diff --git a/.github/workflows/spring-boot-jersey-starter-ci.yml b/.github/workflows/spring-boot-jersey-starter-ci.yml
new file mode 100644
index 00000000..712ad1af
--- /dev/null
+++ b/.github/workflows/spring-boot-jersey-starter-ci.yml
@@ -0,0 +1,51 @@
+name: Spring Boot Jersey Starter CI
+
+on:
+ push:
+ paths:
+ - 'spring/fluentforms-jersey-spring-boot-**'
+ - '.github/workflows/spring-boot-jersey-starter-ci.yml'
+ workflow_dispatch:
+
+jobs:
+ build:
+ name: Java ${{ matrix.java }} build
+ runs-on: ubuntu-latest
+ continue-on-error: ${{ matrix.experimental }}
+ strategy:
+ fail-fast: true
+ matrix:
+ java: [ 21 ]
+ experimental: [false]
+ include:
+ - java: 25
+ experimental: true
+
+ steps:
+ - uses: actions/checkout@v6
+ - name: Set up JDK ${{ matrix.java }}
+ uses: actions/setup-java@v5
+ with:
+ distribution: 'oracle'
+ java-version: ${{ matrix.java }}
+ cache: 'maven'
+ server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
+ settings-path: ${{ github.workspace }} # location for the settings.xml file
+
+ - name: Build AutoConfigure with Maven
+ run: mvn -B install -s $GITHUB_WORKSPACE/settings.xml --file spring/fluentforms-jersey-spring-boot-autoconfigure
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+
+ - name: Build AutoConfigure with Maven
+ if: (github.ref == 'refs/heads/master' || github.ref == 'refs/tags/*') && !matrix.experimental # Only run on main branch or tags and non-experimental
+ run: mvn -B deploy -s $GITHUB_WORKSPACE/settings.xml --file spring/fluentforms-jersey-spring-boot-autoconfigure
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+
+ - name: Publish Starter to GitHub Packages Apache Maven
+ if: (github.ref == 'refs/heads/master' || github.ref == 'refs/tags/*') && !matrix.experimental # Only run on main branch or tags and non-experimental
+ run: mvn -B deploy -s $GITHUB_WORKSPACE/settings.xml --file spring/fluentforms-jersey-spring-boot-starter
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+
\ No newline at end of file
diff --git a/.github/workflows/spring-boot-starter-ci.yml b/.github/workflows/spring-boot-webmvc-starter-ci.yml
similarity index 93%
rename from .github/workflows/spring-boot-starter-ci.yml
rename to .github/workflows/spring-boot-webmvc-starter-ci.yml
index 128c17be..6eef6ee8 100644
--- a/.github/workflows/spring-boot-starter-ci.yml
+++ b/.github/workflows/spring-boot-webmvc-starter-ci.yml
@@ -1,10 +1,10 @@
-name: Spring Boot Starter CI
+name: Spring Boot WebMVC Starter CI
on:
push:
paths:
- 'spring/fluentforms-spring-boot-**'
- - '.github/workflows/spring-boot-starter-ci.yml'
+ - '.github/workflows/spring-boot-webmvc-starter-ci.yml'
workflow_dispatch:
jobs:
@@ -22,7 +22,7 @@ jobs:
experimental: true
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v5
with:
diff --git a/fluentforms/examples/pom.xml b/fluentforms/examples/pom.xml
index b9b34207..623d5372 100644
--- a/fluentforms/examples/pom.xml
+++ b/fluentforms/examples/pom.xml
@@ -11,6 +11,25 @@
FluentForms Examples
Various examples of using the Fluent Forms APIs.
+
+
+
+
+ maven-install-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
+
+
+
org.osgi
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 00000000..a3bd675b
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,36 @@
+
+ 4.0.0
+ com._4point.aem.fluentforms
+ fluentforms
+ pom
+ 0.0.4-SNAPSHOT
+ Fluent Forms Spring Boot Starter Projects
+
+
+
+ fluentforms
+ rest-services
+ spring
+
+
+
+
+
+
+ maven-install-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/rest-services/it.tests/pom.xml b/rest-services/it.tests/pom.xml
index 797bae13..51240d97 100644
--- a/rest-services/it.tests/pom.xml
+++ b/rest-services/it.tests/pom.xml
@@ -38,6 +38,25 @@
17
+
+
+
+
+ maven-install-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
+
+
+
+
+ com._4point.aem.fluentforms
+ fluentforms-jersey-spring-boot-autoconfigure
+ 0.0.4-SNAPSHOT
+ FluentForms Jersey AutoConfigure Project
+
+
+ 17
+ 3.0.5
+ 3.0.5
+ 0.0.4-SNAPSHOT
+ 0.0.4-SNAPSHOT
+
+
+ 0.0.4-SNAPSHOT
+ 4.0.0-beta.16
+ 1.20.2
+ 1.2.3
+
+
+
+
+ github
+ 4Point Solutions FluentFormsAPI Apache Maven Packages
+ https://maven.pkg.github.com/4PointSolutions/FluentFormsAPI
+
+
+
+
+
+ github
+ https://maven.pkg.github.com/4PointSolutions/*
+
+ true
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot
+
+
+ com.github.ulisesbocchio
+ jasypt-spring-boot-starter
+ ${jasypt.spring.boot.version}
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+ compile
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure-processor
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-jersey
+ true
+ provided
+
+
+ com._4point.aem.fluentforms
+ fluentforms-spring-boot-autoconfigure
+ ${fluentforms-autoconfigure.version}
+
+
+ com._4point.aem
+ fluentforms.core
+ ${fluentforms.version}
+
+
+ com._4point.aem.docservices
+ rest-services.client
+ ${fluentforms.version}
+
+
+ com._4point.aem.docservices.rest-services
+ rest-services.jersey-client
+ ${fluentforms.version}
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ com.4point.testing
+ 4point-hamcrest-matchers
+ ${fp.hamcrest.matchers.version}
+ test
+
+
+ org.wiremock
+ wiremock-standalone
+ ${wiremock.version}
+ test
+
+
+ org.pitest
+ pitest-junit5-plugin
+ ${pitest.junit5.maven.plugin.version}
+ test
+
+
+
+
+
+
+
+ com.github.ulisesbocchio
+ jasypt-maven-plugin
+ ${jasypt.maven.plugin.version}
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+
+
+
+
+
+
+
+ org.pitest
+ pitest-maven
+ ${pitest.maven.plugin.version}
+
+
+
+
+
\ No newline at end of file
diff --git a/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyAfSubmission.java b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyAfSubmission.java
new file mode 100644
index 00000000..e8cba253
--- /dev/null
+++ b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyAfSubmission.java
@@ -0,0 +1,379 @@
+package com._4point.aem.fluentforms.spring;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.function.Function;
+
+import org.glassfish.jersey.client.ChunkedInput;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.media.multipart.BodyPartEntity;
+import org.glassfish.jersey.media.multipart.FormDataBodyPart;
+import org.glassfish.jersey.media.multipart.FormDataMultiPart;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ssl.SslBundles;
+import org.springframework.util.MultiValueMapAdapter;
+
+import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmissionHandler;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.InternalServerErrorException;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
+
+/**
+ * Class that handles Adaptive Form Submissions.
+ *
+ * This class sets up an endpoint that receives all Adaptive Forms submissions. The processing of these
+ * submissions can be configured based on the available beans available within the Spring context.
+ *
+ * If a bean is provided that implements the AfSubmitProcessor interface, then that bean will be called
+ * for every Adaptive Form submission.
+ *
+ * In the absence of an AfSubmitProcessor bean, then if one or more AfSubmitHandler beans are available, these will
+ * invoked in order for each Adaptive Form submission.
+ *
+ * If no AfSubmitHandler beans are available, then all Adaptive Form submissions will be forwarded on
+ * to the configured AEM instance.
+ *
+ *
+ *
+ */
+@Path("/aem")
+public class AemProxyJerseyAfSubmission {
+ private final static Logger logger = LoggerFactory.getLogger(AemProxyJerseyAfSubmission.class);
+ private static final String CONTENT_FORMS_AF = "content/forms/af/";
+
+ @Autowired
+ JerseyAfSubmitProcessor submitProcessor;
+
+ @Path(CONTENT_FORMS_AF + "{remainder : .+}")
+ @POST
+ @Consumes(MediaType.MULTIPART_FORM_DATA)
+ @Produces(MediaType.WILDCARD)
+ public Response proxySubmitPost(@PathParam("remainder") String remainder, /* @HeaderParam(CorrelationId.CORRELATION_ID_HDR) final String correlationIdHdr,*/ @Context HttpHeaders headers, final FormDataMultiPart inFormData) {
+ logger.atInfo().addArgument(()->submitProcessor != null ? submitProcessor.getClass().getName() : "null" ).log("Submit proxy called. SubmitProcessor={}");
+// final String correlationId = CorrelationId.generate(correlationIdHdr);
+// ProcessingMetadataBuilder pmBuilder = ProcessingMetadata.start(correlationId);
+ return submitProcessor.processRequest(inFormData, headers, remainder);
+ }
+
+ /**
+ * Transforms a FormDataMultiPart object using a set of provided functions.
+ *
+ * Accepts incoming form data, in the form of a FormDataMultiPart object and a Map collection of functions. It walks through the
+ * parts and if it finds a function in the Map with the same name it executes that function on the the data from the corresponding part.
+ * It accumulates and returns the result in another FormDataMultiPart object.
+ *
+ * @param inFormData incoming form data
+ * @param fieldFunctions set of functions that correspond to specific parts
+ * @param logger logger for logging messages
+ * @return
+ * @throws IOException
+ */
+ private static FormDataMultiPart transformFormData(final FormDataMultiPart inFormData, final Map> fieldFunctions, Logger logger) {
+ try {
+ FormDataMultiPart outFormData = new FormDataMultiPart();
+ var fields = inFormData.getFields();
+ logger.atDebug().log(()->"Found " + fields.size() + " fields");
+
+ for (var fieldEntry : fields.entrySet()) {
+ String fieldName = fieldEntry.getKey();
+ for (FormDataBodyPart fieldData : fieldEntry.getValue()) {
+ logger.atDebug().log(()->"Copying '" + fieldName + "' field");
+ byte[] fieldBytes = ((BodyPartEntity)fieldData.getEntity()).getInputStream().readAllBytes();
+ logger.atTrace().log(()->"Fieldname '" + fieldName + "' is '" + new String(fieldBytes) + "'.");
+ var fieldFn = fieldFunctions.getOrDefault(fieldName, Function.identity()); // Look for an entry in fieldFunctions table for this field. Return the Identity function if we don't find one.
+ byte[] modifiedFieldBytes = fieldFn.apply(fieldBytes);
+ if (modifiedFieldBytes != null) { // If the function returned bytes (if not, then remove that part)
+ outFormData.field(fieldName, new String(modifiedFieldBytes, StandardCharsets.UTF_8)); // Apply the field function to bytes.
+ }
+ }
+ }
+ return outFormData;
+ } catch (IOException e) {
+ throw new InternalServerErrorException("Error while transforming submission data.", e);
+ }
+ }
+
+ /**
+ * Interface that classes that want to perform low-level processing of all Adaptive Forms submissions.
+ *
+ * All Adaptive Form submissions will pass through an AfSubmitProcessor singleton found within the Spring
+ * context. Normally, this will be one of the provided AfSubmitProcessors (like AfSubmitLocalProcessor or
+ * AfSubmitAemProxyProcessor), but can be replaced by a user supplied implementation.
+ *
+ */
+ @FunctionalInterface
+ public interface JerseyAfSubmitProcessor {
+ /**
+ * Processor to process incoming Adaptive Forms submit.
+ *
+ * @param inFormData
+ * incoming form data
+ * @param headers
+ * incoming HTTP headers
+ * @param remainder
+ * Adaptive Forms location path (relative to /content/forms/af/)
+ * @return
+ */
+ Response processRequest(final FormDataMultiPart inFormData, HttpHeaders headers, String remainder);
+ }
+
+ @FunctionalInterface
+ public interface AfFormDataTransformer {
+ /**
+ * If one or more of these are available in the Spring context, they will be run against the incoming
+ * data before it is processed.
+ *
+ * This can be useful when used with the AfSubmitAemProxyProcessor to transform the data before it
+ * is sent to AEM.
+ *
+ * This can be useful when used with the AfSubmitLocalProcessor to capture data from the initial
+ * Adaptive Form submission that may not normally be passed to the AfSubmitHandler.
+ *
+ * @param inFormData
+ * incoming form data object
+ * @return
+ * outgoing form data object
+ */
+ FormDataMultiPart transformFormData(final FormDataMultiPart inFormData);
+ }
+ /**
+ * This processor forwards the Adaptive Form submissions on to AEM for processing by the AEM instance.
+ *
+ * This is typically used if the AEM Forms Data model will be used for processing the submission.
+ *
+ * This is the default submit processor if no other type of submit processing is configured in the
+ * Spring context.
+ *
+ */
+ static class AfSubmitAemProxyProcessor implements JerseyAfSubmitProcessor {
+
+ private final AemConfiguration aemConfig;
+ private final Client httpClient;
+
+ public AfSubmitAemProxyProcessor(AemConfiguration aemConfig, SslBundles sslBundles) {
+ this.aemConfig = aemConfig;
+ this.httpClient = JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle(), aemConfig.user(), aemConfig.password());
+ }
+
+ @Override
+ public Response processRequest(FormDataMultiPart formSubmission, HttpHeaders headers, String remainder) {
+ logger.atTrace().addArgument(()->{ String formData = formSubmission.getField("jcr:data").getEntityAs(String.class);
+ return formData != null ? formData : "null";
+ })
+ .log("AF Submit Proxy: Data = '{}'");
+
+ // Transfer to AEM
+ String contentType = headers.getMediaType().toString();
+ String cookie = headers.getHeaderString("cookie");
+ WebTarget webTarget = httpClient.target(aemConfig.url())
+ .property(ClientProperties.FOLLOW_REDIRECTS, Boolean.FALSE)
+ .path("/" + CONTENT_FORMS_AF + remainder);
+
+ logger.atDebug().log(()->"Proxying Submit POST request for target '" + webTarget.getUri().toString() + "'.");
+ Response result = webTarget.request()
+ .header("cookie", cookie)
+ .post(Entity.entity(formSubmission , contentType));
+
+ logger.atDebug().log(()->"AEM Response = " + result.getStatus());
+ logger.atDebug().log(()->"AEM Response Location = " + result.getLocation());
+
+ String aemResponseEncoding = result.getHeaderString("Transfer-Encoding");
+ if (aemResponseEncoding != null && aemResponseEncoding.equalsIgnoreCase("chunked")) {
+ logger.atDebug().log("Returning chunked response from AEM.");
+ return Response.status(result.getStatus()).entity(new ByteArrayInputStream(transferFromAem(result, logger)))
+ .type(result.getMediaType())
+// .header(CorrelationId.CORRELATION_ID_HDR, correlationId)
+ .build();
+ } else {
+ logger.atDebug().log("Returning response from AEM.");
+ return Response.fromResponse(result)
+// .header(CorrelationId.CORRELATION_ID_HDR, correlationId)
+ .build();
+ }
+ }
+
+ /**
+ * Transfers a response from AEM and returns it in a byte array. It handles chunked responses.
+ *
+ * @param result Response object from AEM
+ * @param logger Logger for logging any errors/warnings/etc.
+ * @return
+ * @throws IOException
+ */
+ private static byte[] transferFromAem(Response result, Logger logger) {
+ try {
+ if (logger.isDebugEnabled()) {
+ logger.debug("AEM Response Mediatype=" + (result.getMediaType() != null ? result.getMediaType().toString(): "null"));
+ MultivaluedMap headers = result.getHeaders();
+ for(Entry> entry : headers.entrySet()) {
+ String msgLine = "For header '" + entry.getKey() + "', ";
+ for (Object value : entry.getValue()) {
+ msgLine += "'" + value.toString() + "' ";
+ }
+ logger.debug(msgLine);
+ }
+ }
+
+ String aemResponseEncoding = result.getHeaderString("Transfer-Encoding");
+ if (aemResponseEncoding != null && aemResponseEncoding.equalsIgnoreCase("chunked")) {
+ // They've sent back chunked response.
+ logger.debug("Found a chunked encoding.");
+ final ChunkedInput chunkedInput = result.readEntity(new GenericType>() {});
+ byte[] chunk;
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ try (buffer) {
+ while ((chunk = chunkedInput.read()) != null) {
+ buffer.writeBytes(chunk);
+ logger.debug("Read chunk from AEM response.");
+ }
+ }
+
+ return buffer.toByteArray();
+ } else {
+ return ((InputStream)result.getEntity()).readAllBytes();
+ }
+ } catch (IllegalStateException | IOException e) {
+ throw new InternalServerErrorException("Error while processing transferring result from AEM.", e);
+ }
+ }
+
+ }
+
+ /**
+ * This processor will process Adaptive Forms submissions locally without sending anything to AEM.
+ *
+ * It will invoke one or more AfSubmitHandlers that have been configured in the Spring context.
+ *
+ * TODO: Add configuration variable that becomes enum value for FIRST and ALL. FIRST = quit after first handler that canHandle
+ * ALL - process all handlers that canHandle a request.
+ *
+ */
+ static class AfSubmitLocalProcessor implements JerseyAfSubmitProcessor {
+ private final static Logger logger = LoggerFactory.getLogger(AfSubmitLocalProcessor.class);
+ private static final String REMAINDER_PATH_SUFFIX = "/jcr:content/guideContainer.af.submit.jsp";
+
+ // Have to implement an internal interface so that Spring does not think there are two available
+ // AfSubmitProcessors. This wraps an internal AfSubmitAemProxyProcessor that the local processor
+ // uses to handle requests it chooses to pass on to AEM.
+ @FunctionalInterface
+ public interface InternalAfSubmitAemProxyProcessor {
+ AfSubmitAemProxyProcessor get();
+ }
+
+ private final List submissionHandlers;
+ private final AfSubmitAemProxyProcessor aemProxyProcessor;
+
+ AfSubmitLocalProcessor(List submissionHandlers, InternalAfSubmitAemProxyProcessor aemProxyProcessor) {
+ this.submissionHandlers = submissionHandlers;
+ this.aemProxyProcessor = aemProxyProcessor.get();
+ logger.atInfo().addArgument(submissionHandlers.size()).log("Found {} available AfSubmissionHandlers.");
+ if(logger.isDebugEnabled()) {
+ submissionHandlers.forEach(sh->logger.atDebug().addArgument(sh.getClass().getName()).log(" Found AfSubmissionHandler named '{}'."));
+ }
+ }
+
+ @Override
+ public Response processRequest(FormDataMultiPart inFormData, HttpHeaders headers, String remainder) {
+ if (!remainder.endsWith(REMAINDER_PATH_SUFFIX)) {
+ // If the submission does not end with the expected submission suffix, then just proxy it AEM.
+ return aemProxyProcessor.processRequest(inFormData, headers, remainder);
+ }
+ String formName = determineFormName(remainder);
+ Optional firstHandler = submissionHandlers.stream()
+ .filter(sh->canHandle(sh, formName))
+ .findFirst();
+
+ return firstHandler.map(h->processSubmission(h, inFormData, headers, formName))
+ .orElseGet(()->errorResponse());
+ }
+
+ private Response processSubmission(AfSubmissionHandler handler, FormDataMultiPart inFormData, HttpHeaders headers, String formName) {
+ logger.atInfo().addArgument(handler.getClass().getName()).log("Calling AfSubmissionHandler={}");
+ return formulateResponse(handler.processSubmission(formulateSubmission(inFormData, headers, formName)));
+ }
+
+ private String determineFormName(String guideContainerPath) {
+ return guideContainerPath.substring(0, guideContainerPath.length() - REMAINDER_PATH_SUFFIX.length());
+ }
+
+ private boolean canHandle(AfSubmissionHandler sh, String formName) {
+ boolean result = sh.canHandle(formName);
+ logger.atDebug().addArgument(formName).addArgument(()->sh.getClass().getName()).log("Submission Handler canHandle returned {}. ({})");
+ return result;
+ }
+
+ // Create a AfSubmissionHandler.Submission object from the JAX-RS Request classes.
+ private AfSubmissionHandler.Submission formulateSubmission(FormDataMultiPart inFormData, HttpHeaders headers, String formName) {
+ class ExtractedData {
+ String formData;
+ String redirectUrl;
+ };
+ final ExtractedData extractedData = new ExtractedData();
+ // Extract data some of the parts.
+ final Map> fieldFunctions = // Create a table of functions that will be called to transform specific fields in the incoming AF submission.
+ Map.of(
+ ":redirect", (redirect)->{ extractedData.redirectUrl = new String(redirect, StandardCharsets.UTF_8); return null; },
+ "jcr:data", (dataBytes)->{ extractedData.formData = new String(dataBytes, StandardCharsets.UTF_8); return null; }
+ );
+ transformFormData(inFormData, fieldFunctions, logger);
+ return new AfSubmissionHandler.Submission(extractedData.formData,
+ formName,
+ extractedData.redirectUrl,
+ transferHeaders(headers)
+ );
+ }
+
+ // Transfer headers from JAX-RS construct to Spring construct (in order to keep JAX-RS encapsulated in this class)
+ private MultiValueMapAdapter transferHeaders(HttpHeaders headers) {
+ if (logger.isDebugEnabled()) {
+ headers.getRequestHeaders().forEach((k,v)->logger.atDebug().addArgument(k).addArgument(v.size()).log("Found Http header {} with {} values."));
+ }
+ return new MultiValueMapAdapter(headers.getRequestHeaders());
+ }
+
+ // Convert the SubmitResponse object into a JAX-RS Response object.
+ private Response formulateResponse(AfSubmissionHandler.SubmitResponse submitResponse) {
+ if (submitResponse instanceof AfSubmissionHandler.SubmitResponse.Response response) {
+ var builder = response.responseBytes().length > 0 ? Response.ok().entity(response.responseBytes()).type(response.mediaType())
+ : Response.noContent();
+ return builder.build();
+ } else if (submitResponse instanceof AfSubmissionHandler.SubmitResponse.SeeOther redirectFound) {
+ return Response.seeOther(redirectFound.redirectUrl()).build();
+ } else if (submitResponse instanceof AfSubmissionHandler.SubmitResponse.Redirect redirect) {
+ return Response.temporaryRedirect(redirect.redirectUrl()).build();
+ } else {
+ // This cannot happen, but we need to supply an else until we can turn this code into a switch
+ // expression in JDK 21.
+ throw new IllegalStateException("Unexpected SubmitResponse class type '%s', this should never happen!".formatted(submitResponse.getClass().getName()));
+ }
+ }
+
+ // Generate an JAX-RS Error response if not AfSubmissionHandler was found.
+ private Response errorResponse() {
+ logger.atWarn().log("No applicable AfSubmissionHandler found.");
+ return Response.status(Response.Status.NOT_FOUND).build();
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyAutoConfiguration.java b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyAutoConfiguration.java
new file mode 100644
index 00000000..c6070e67
--- /dev/null
+++ b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyAutoConfiguration.java
@@ -0,0 +1,156 @@
+package com._4point.aem.fluentforms.spring;
+
+import java.util.List;
+import java.util.Map;
+
+import org.glassfish.jersey.servlet.ServletProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
+import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.ssl.SslBundles;
+import org.springframework.boot.system.JavaVersion;
+import org.springframework.context.annotation.Bean;
+import org.springframework.core.task.SimpleAsyncTaskExecutor;
+import org.springframework.core.task.TaskExecutor;
+
+import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmissionHandler;
+import com._4point.aem.fluentforms.spring.AemProxyJerseyAfSubmission.AfSubmitAemProxyProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyJerseyAfSubmission.AfSubmitLocalProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyJerseyAfSubmission.AfSubmitLocalProcessor.InternalAfSubmitAemProxyProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyJerseyAfSubmission.JerseyAfSubmitProcessor;
+
+/**
+ * AutoConfiguration for the Reverse Proxy Library which reverse proxies secondary
+ * resources (.css, .js, etc.) that the browser will request. These requests are forwarded to AEM.
+ */
+@AutoConfiguration
+@ConditionalOnWebApplication(type=Type.SERVLET)
+@ConditionalOnProperty(prefix="fluentforms.rproxy", name="enabled", havingValue="true", matchIfMissing=true )
+@ConditionalOnProperty(prefix="fluentforms.rproxy", name="type", havingValue="jersey", matchIfMissing=true )
+@EnableConfigurationProperties({AemConfiguration.class, AemProxyConfiguration.class})
+@ConditionalOnMissingBean(AemProxyImplemention.class)
+@AutoConfigureBefore(AemProxyAutoConfiguration.class)
+public class AemProxyJerseyAutoConfiguration {
+
+ /**
+ * Marker bean to indicate that the Jersey-based AEM Proxy implementation is being used.
+ *
+ * @return
+ */
+ @Bean
+ AemProxyImplemention aemProxyImplemention() {
+ return new AemProxyImplemention() {
+ // This is just a marker bean.
+ };
+ }
+
+ /**
+ * Configures the JAX-RS resources associated with reverse proxying resources and submissions from
+ * Adaptive Forms.
+ *
+ * @param aemConfig
+ * AEM configuration typically configured using application.properties files. This is
+ * typically injected by the Spring Framework.
+ * @param aemProxyConfig
+ * AEM proxy-specific configuration typically configured using application.properties files.
+ * This is typically injected by the Spring Framework.
+ * @param aemProxyTaskExecutor
+ * @return
+ * JAX-RS Resource configuration customizer that is used by the spring-jersey starter to configure
+ * JAX-RS Resources (i.e. endpoints)
+ */
+ @Bean
+ public ResourceConfigCustomizer afProxyConfigurer(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, @Autowired(required = false) SslBundles sslBundles, TaskExecutor aemProxyTaskExecutor) {
+ return config->config.register(new AemProxyJerseyEndpoint(aemConfig, aemProxyConfig, sslBundles, aemProxyTaskExecutor))
+ .register(new AemProxyJerseyAfSubmission())
+ .addProperties(Map.of(
+ // Turn off Wadl generation (this was interfering with some CORS functionality
+ "jersey.config.server.wadl.disableWadl", true,
+ // Set properties to allow Jersey to coexist with Spring MVC
+ "jersey.config.server.response.setStatusOverSendError", true,
+ // See https://docs.spring.io/spring-boot/how-to/jersey.html#howto .jersey.alongside-another-web-framework
+ ServletProperties.FILTER_FORWARD_ON_404, true
+ ))
+ ;
+ }
+
+ /**
+ * Supply a TaskExecutor for use by the AemProxyEndpoint. This is used to process csrf token requests because they are Chunked.
+ *
+ * @return the taskeExecutor that will be used to process csrf token requests.
+ */
+ @Bean
+ public TaskExecutor aemProxyTaskExecutor() {
+ var executor = new SimpleAsyncTaskExecutor("AemProxy-");
+ // Use virtual threads if available. This will be the default for Java 21 and later.
+ executor.setVirtualThreads(JavaVersion.getJavaVersion().isEqualOrNewerThan(JavaVersion.TWENTY_ONE));
+ return executor;
+ }
+
+ /**
+ * Supply a AfSubmitLocalProcessor if the user has not already supplied one *and* there is an
+ * available AfSubmissionHandler
+ *
+ * Basically, a user can supply their own AfSubmitProcessor if they want to process things
+ * at the JAX-RS Servlet level. I expect this to be an unusual case, most users will want
+ * to either process things locally using a custom AfSubmissionHandler or the will
+ * want to forward things to AEM by *not* providing a custom AfSubmissionHandler.
+ *
+ * @param submissionHandlers
+ * List of local submission handlers. This is injected by the Spring Framework.
+ * @return
+ * Processor that will call the first submission handler that says that it can
+ * process this request.
+ */
+ @ConditionalOnMissingBean(JerseyAfSubmitProcessor.class)
+ @ConditionalOnBean(AfSubmissionHandler.class)
+ @Bean
+ public JerseyAfSubmitProcessor localSubmitProcessor(List submissionHandlers, InternalAfSubmitAemProxyProcessor aemProxyProcessor) {
+ return new AfSubmitLocalProcessor(submissionHandlers, aemProxyProcessor);
+ }
+
+ /**
+ * Supply a AfSubmitAemProxyProcessor if the user has not supplied any of the AfSubmit beans.
+ *
+ * This is the default processor and it will forward all submissions on to the configured AEM
+ * instance.
+ *
+ * @param aemConfig
+ * AEM configuration typically configured using application.properties files. This is
+ * typically injected by the Spring Framework.
+ * @return
+ * Processor that forwards all submissions on to AEM.
+ */
+ @ConditionalOnMissingBean({JerseyAfSubmitProcessor.class, AfSubmissionHandler.class})
+ @Bean()
+ public JerseyAfSubmitProcessor aemSubmitProcessor(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
+ return new AfSubmitAemProxyProcessor(aemConfig, sslBundles);
+ }
+
+ /**
+ * Supply a AfSubmitAemProxyProcessor for use by the localSubmitProcessor.
+ *
+ * This is the a processor that will forward all submissions on to the configured AEM
+ * instance. It is used by the localSubmitProcessor to proxy any requests that aren't
+ * true submissions (e.g. an internalsubmit).
+ *
+ * @param aemConfig
+ * AEM configuration typically configured using application.properties files. This is
+ * typically injected by the Spring Framework.
+ * @return
+ * Processor that forwards all submissions on to AEM.
+ */
+ @ConditionalOnMissingBean(InternalAfSubmitAemProxyProcessor.class)
+ @ConditionalOnBean(AfSubmissionHandler.class)
+ @Bean
+ public InternalAfSubmitAemProxyProcessor aemProxyProcessor(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
+ return ()->new AfSubmitAemProxyProcessor(aemConfig, sslBundles);
+ }
+}
\ No newline at end of file
diff --git a/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyEndpoint.java b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyEndpoint.java
new file mode 100644
index 00000000..84ef323e
--- /dev/null
+++ b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyEndpoint.java
@@ -0,0 +1,227 @@
+package com._4point.aem.fluentforms.spring;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import javax.naming.ConfigurationException;
+
+import org.glassfish.jersey.client.ChunkedInput;
+import org.glassfish.jersey.server.ChunkedOutput;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.ssl.SslBundles;
+import org.springframework.core.task.TaskExecutor;
+
+import com._4point.aem.docservices.rest_services.client.helpers.ReplacingInputStream;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.HeaderParam;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+
+/**
+ * Reverse Proxy Code which reverse proxies secondary resources (.css, .js, etc.) that the browser will request.
+ * These requests are forwarded to AEM.
+ *
+ * This code relies on Eclipse Jersey and expects that the spring-boo-starter-jersey is included in the project.
+ *
+ * It assumes that the application that generated the Adaptive Form or HTML5 Form inserted /aem in from of any
+ * AEM links in the AF or HTML5 html code. This task is typically performes using the FluentForms
+ * StandardFormsFeederUrlFilters.getStandardInputStreamFilter() method and passing that into the call to
+ * get the AdaptiveForm or HTML5 Form using the FLuentForms libraries.
+ *
+ */
+@Path("/aem")
+public class AemProxyJerseyEndpoint {
+
+ private final static Logger logger = LoggerFactory.getLogger(AemProxyJerseyEndpoint.class);
+
+ private static final String AEM_APP_PREFIX = "/";
+ private Client httpClient;
+
+ private final AemProxyConfiguration aemProxyConfig;
+ private final AemConfiguration aemConfig;
+ private final TaskExecutor taskExecutor;
+
+ /**
+ *
+ */
+ public AemProxyJerseyEndpoint(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, SslBundles sslBundles, TaskExecutor taskExecutor) {
+ this.aemProxyConfig = aemProxyConfig;
+ this.aemConfig = aemConfig;
+ this.httpClient = JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle(), aemConfig.user(), aemConfig.password());
+ this.taskExecutor = taskExecutor;
+ }
+
+ @Path("libs/granite/csrf/token.json")
+ @GET
+ public ChunkedOutput proxyOsgiCsrfToken() throws IOException {
+ final String path = AEM_APP_PREFIX + "libs/granite/csrf/token.json";
+ return getCsrfToken(path);
+ }
+
+ @Path("lc/libs/granite/csrf/token.json")
+ @GET
+ public ChunkedOutput proxyJeeCsrfToken() throws IOException {
+ final String path = "/lc/libs/granite/csrf/token.json";
+ return getCsrfToken(path);
+ }
+
+ private ChunkedOutput getCsrfToken(final String path) {
+ logger.atDebug().log("Proxying GET request. CSRF token");
+ WebTarget webTarget = httpClient.target(aemConfig.url())
+ .path(path);
+ logger.atDebug().log(()->"Proxying GET request for CSRF token '" + webTarget.getUri().toString() + "'.");
+ Response result = webTarget.request()
+ .get();
+
+ logger.atDebug().log(()->"CSRF token GET response status = " + result.getStatus());
+ final ChunkedInput chunkedInput = result.readEntity(new GenericType>() {});
+ final ChunkedOutput output = new ChunkedOutput(byte[].class);
+
+ taskExecutor.execute(() -> {
+ try (result; chunkedInput; output) {
+ byte[] chunk;
+ while ((chunk = chunkedInput.read()) != null) {
+ output.write(chunk);
+ logger.debug("Returning GET chunk for CSRF token.");
+ }
+ logger.debug("Finished GETting chunks for CSRF token.");
+ } catch (IllegalStateException | IOException e) {
+ e.printStackTrace();
+ }
+ logger.debug("Exiting Thread.");
+ });
+
+ logger.atDebug().log("Returning GET response for CSRF token.");
+ return output;
+ }
+
+
+
+ /**
+ * This function acts as a reverse proxy for anything under clientlibs. It just forwards
+ * anything it receives on AEM and then returns the response.
+ *
+ * @param remainder
+ * @return
+ * @throws ConfigurationException
+ */
+ @Path("{remainder : .+}")
+ @GET
+ public Response proxyGet(@PathParam("remainder") String remainder) {
+ logger.atDebug().log(()->"Proxying GET request. remainder=" + remainder);
+ WebTarget webTarget = httpClient.target(aemConfig.url())
+ .path(AEM_APP_PREFIX + remainder);
+ logger.atDebug().log(()->"Proxying GET request for target '" + webTarget.getUri().toString() + "'.");
+ Response result = webTarget.request()
+ .get();
+ if (logger.isDebugEnabled()) {
+ result.getHeaders().forEach((h, l)->logger.atDebug().log("For " + webTarget.getUri().toString() + ", Header:" + h + "=" + l.stream().map(o->(String)o).collect(Collectors.joining("','", "'", "'"))));
+ }
+
+ logger.atDebug().log(()->"Returning GET response from target '" + webTarget.getUri().toString() + "' status code=" + result.getStatus() + ".");
+ Function filter = switch (remainder) {
+ case "etc.clientlibs/clientlibs/granite/utils.js" -> this::substituteAfBaseLocation;
+ case "etc.clientlibs/fd/xfaforms/clientlibs/profile.js" -> this::fixTogglesDotJsonLocation;
+ default -> is -> is; // No filtering needed
+ };
+ return Response.fromResponse(result)
+ .header("Transfer-Encoding", null) // Remove the Transfer-Encoding header
+ .entity(filter.apply(result.readEntity(InputStream.class)))
+ .build();
+ }
+
+ /**
+ * Wraps an InputStream with a wrapper that replaces some code in the Adobe utils.js code.
+ *
+ * The detectContextPath function in utils.js has the following line:
+ * contextPath = result[1];
+ *
+ * This routine replaces it with
+ * contextPath = FORMSFEEDER_AF_BASE_LOCATION_PROP + result[1];
+ * (where FORMSFEEDER_AF_BASE_LOCATION_PROP is whatever value is in the application.properties file)
+ *
+ * @param is
+ * @return
+ */
+ private InputStream substituteAfBaseLocation(InputStream is) {
+ if (aemProxyConfig.afBaseLocation().isBlank()) {
+ return is;
+ } else {
+ String target = "contextPath = result[1];";
+ String replacement = "contextPath = \""+ aemProxyConfig.afBaseLocation() + "\" + result[1];";
+ logger.atDebug().log("Altering granite/utils.js to replace '{}' with '{}'", target, replacement);
+ return new ReplacingInputStream(is, target, replacement);
+ }
+ }
+
+ private InputStream fixTogglesDotJsonLocation(InputStream is) {
+ String target = "\"/etc.clientlibs/toggles.json\"";
+ String replacement = "\"/aem/etc.clientlibs/toggles.json\"";
+ logger.atDebug().log("Altering profile.js to replace '{}' with '{}'", target, replacement);
+ return new ReplacingInputStream(is, target, replacement);
+ }
+
+ @Path("{remainder : .+}")
+ @POST
+ public Response proxyPost(@PathParam("remainder") String remainder, @HeaderParam("Content-Type") String contentType, InputStream in) {
+ logger.atDebug().log("Proxying POST request. remainder={}", remainder);
+ WebTarget webTarget = httpClient.target(aemConfig.url())
+ .path(AEM_APP_PREFIX + remainder);
+ logger.atDebug().addArgument(()->webTarget.getUri().toString())
+ .addArgument(contentType)
+ .log(()->"Proxying POST request for target '{}'. ContentType='{}'.");
+ Response result = webTarget.request()
+ .post(Entity.entity(
+ logger.isDebugEnabled() ? debugInput(in, webTarget.getUri().toString()) : in, // if Debug is on, write out information about input stream
+ contentType != null ? contentType : "application/octet-stream" // supply default content type if it was omitted.
+ ));
+
+ if (remainder.contains("af.submit.jsp")) {
+ logger.atDebug().addArgument(()->Boolean.valueOf(result == null).toString())
+ .log("result == null is {}.");
+ MediaType mediaType = result.getMediaType();
+ logger.atDebug()
+ .addArgument(()->webTarget.getUri().toString())
+ .addArgument(()->mediaType != null ? mediaType.toString() : "")
+ .addArgument(()->result.getHeaderString("Transfer-Encoding"))
+ .log("Returning POST response from target '{}'. contentType='{}'. transfer-encoding='{}'.");
+ } else {
+ logger.atDebug()
+ .addArgument(webTarget.getUri()::toString)
+ .log("Returning POST response from target '{}'.");
+ }
+
+ return Response.fromResponse(result).build();
+ }
+
+ private InputStream debugInput(InputStream in, String target) {
+ try {
+ byte[] inputBytes = in.readAllBytes();
+ logger.atDebug()
+ .log("Proxying POST request for target '{}'. numberOfBytes proxied='{}'.", target, inputBytes.length);
+ logger.atTrace()
+ .addArgument(target)
+ .addArgument(()->new String(inputBytes, StandardCharsets.UTF_8))
+ .log("Proxying POST request for target '{}'. input bytes proxied='{}'.");
+ return new ByteArrayInputStream(inputBytes);
+ } catch (IOException e) {
+ logger.atError()
+ .setCause(e)
+ .log("Error reading input stream.");
+ return new ByteArrayInputStream(new byte[0]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/FluentFormsJerseyAutoConfiguration.java b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/FluentFormsJerseyAutoConfiguration.java
new file mode 100644
index 00000000..92aeb4d2
--- /dev/null
+++ b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/FluentFormsJerseyAutoConfiguration.java
@@ -0,0 +1,44 @@
+package com._4point.aem.fluentforms.spring;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.ssl.SslBundles;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+
+import com._4point.aem.docservices.rest_services.client.helpers.Builder.RestClientFactory;
+import com._4point.aem.docservices.rest_services.client.jersey.JerseyRestClient;
+
+import jakarta.ws.rs.client.Client;
+
+/**
+ * AutoConfiguration for the FluentForms Rest Services Client library using the Jersey Rest Client.
+ *
+ * This class automatically configures a set of beans (one for each AEM service) that can be injected
+ * into any Spring Boot code.
+ *
+ */
+@Lazy
+@AutoConfiguration
+@EnableConfigurationProperties(AemConfiguration.class)
+public class FluentFormsJerseyAutoConfiguration {
+
+ @Configuration(proxyBeanMethods = false)
+ @ConditionalOnClass(org.glassfish.jersey.client.JerseyClient.class)
+ public static class JerseyRestClientConfiguration {
+
+ @ConditionalOnProperty(prefix="fluentforms", name="restclient", havingValue="jersey", matchIfMissing=true )
+ @ConditionalOnMissingBean
+ @Bean
+ public RestClientFactory jerseyRestClientFactory(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
+ Client jerseyClient = JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle()); // Create custom Jersey Client with SSL bundle
+ return JerseyRestClient.factory(jerseyClient); // Create a RestClientFactory using JerseyClient implementation
+ }
+
+ }
+}
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/JerseyClientFactory.java b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/JerseyClientFactory.java
similarity index 99%
rename from spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/JerseyClientFactory.java
rename to spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/JerseyClientFactory.java
index 602e9fe4..53e770a4 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/JerseyClientFactory.java
+++ b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/JerseyClientFactory.java
@@ -41,4 +41,4 @@ public static Client createClient(SslBundles sslBundles, String bundleName) {
logger.info("Creating default client");
return ClientBuilder.newClient();
}
-}
+}
\ No newline at end of file
diff --git a/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 00000000..d489f14e
--- /dev/null
+++ b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1,2 @@
+com._4point.aem.fluentforms.spring.FluentFormsJerseyAutoConfiguration
+com._4point.aem.fluentforms.spring.AemProxyJerseyAutoConfiguration
\ No newline at end of file
diff --git a/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyAfSubmissionTest.java b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyAfSubmissionTest.java
new file mode 100644
index 00000000..90036a46
--- /dev/null
+++ b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyAfSubmissionTest.java
@@ -0,0 +1,489 @@
+package com._4point.aem.fluentforms.spring;
+
+import static com._4point.testing.matchers.javalang.ExceptionMatchers.exceptionMsgContainsAll;
+import static com._4point.testing.matchers.jaxrs.ResponseMatchers.doesNotHaveEntity;
+import static com._4point.testing.matchers.jaxrs.ResponseMatchers.hasEntityMatching;
+import static com._4point.testing.matchers.jaxrs.ResponseMatchers.isStatus;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.anyOf;
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.function.Function;
+
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.media.multipart.FormDataMultiPart;
+import org.glassfish.jersey.media.multipart.MultiPartFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.EnumSource;
+import org.mockito.Mockito;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.web.server.LocalServerPort;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmissionHandler;
+import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmissionHandler.SubmitResponse;
+import com._4point.aem.fluentforms.spring.AemProxyJerseyAfSubmission.AfSubmitAemProxyProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyJerseyAfSubmission.AfSubmitLocalProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyJerseyAfSubmission.AfSubmitLocalProcessor.InternalAfSubmitAemProxyProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyJerseyAfSubmission.JerseyAfSubmitProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyJerseyAfSubmissionTest.AemProxyAfSubmissionTestWithLocalAfSubmitProcessorTest.MockAemProxy;
+import com._4point.aem.fluentforms.spring.AemProxyJerseyAfSubmissionTest.TestApplication.JerseyConfig;
+import com.github.tomakehurst.wiremock.client.WireMock;
+import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
+import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
+
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+
+/**
+ * Tests for AemProxyAfSubmissions classes.
+ *
+ * Includes inner classes that test the different SubmitProcessor implementations.
+ *
+ */
+class AemProxyJerseyAfSubmissionTest {
+ public static final String AF_TEMPLATE_NAME = "sample00002test";
+ private static final String SUBMIT_ADAPTIVE_FORM_SERVICE_PATH = "/aem/content/forms/af/" + AF_TEMPLATE_NAME + "/jcr:content/guideContainer.af.submit.jsp";
+ private static final String AEM_SUBMIT_ADAPTIVE_FORM_SERVICE_PATH = SUBMIT_ADAPTIVE_FORM_SERVICE_PATH.substring(4); // Same as above minus "/aem"
+ public static final MediaType APPLICATION_PDF = new MediaType("application", "pdf");
+ private static final String SAMPLE_RESPONSE_BODY = "body";
+
+ record JakartaRestClient(WebTarget target, URI uri) {};
+
+ public static JakartaRestClient setUpRestClient(int port) {
+ var uri = getBaseUri(port);
+ var target = ClientBuilder.newClient() //newClient(clientConfig)
+ .property(ClientProperties.FOLLOW_REDIRECTS, Boolean.FALSE) // Disable re-directs so that we can test for "thank you page" redirection.
+ .register(MultiPartFeature.class)
+ .target(uri);
+ return new JakartaRestClient(target, uri);
+ }
+
+
+ /* package */ static FormDataMultiPart mockFormData(String redirect, String data) {
+ final FormDataMultiPart getPdfForm = new FormDataMultiPart();
+ getPdfForm.field("guideContainerPath", "/aem/content/forms/af/" + AF_TEMPLATE_NAME + "/jcr:content/guideContainer")
+ .field("aemFormComponentPath", "")
+ .field("_asyncSubmit", "false")
+ .field("_charset_", "UTF-8")
+ .field("runtimeLocale", "en")
+ .field("fileAttachmentMap", "{}")
+ .field("afSubmissionInfo", "{\"computedMetaInfo\":{},\"stateOverrides\":{},\"signers\":{}}")
+ .field("TextField1", "TextField1 Contents")
+ .field("TextField2", "TextField2 Contents")
+ .field("jcr:data", data)
+ .field(":redirect", redirect)
+ .field(":selfUrl", "/aem/content/forms/af/" + AF_TEMPLATE_NAME)
+ .field("_guideValueMap", "yes")
+ .field("_guideValuesMap", "{\"textdraw1555538078737\":\"Sample Form
\\n\",\"TextField1\":\"DFGDFG\",\"TextField2\":\"DFGDG 233\",\"submit\":null}")
+ .field("_guideAttachments", "")
+ .field(":cq_csrf_token", "eyJleHAiOjE1NjU2MzUzNzcsImlhdCI6MTU2NTYzNDc3N30.9KB9yPr_mvIfyiwzn5S8mMh-yUzD0-BF99cJR7vW49M");
+ return getPdfForm;
+ }
+
+ private static URI getBaseUri(int port) {
+ return URI.create("http://localhost:" + port);
+ }
+
+ // Supporting mock application class that limits the amount of classes to be loaded.
+ @SpringBootApplication()
+ @EnableConfigurationProperties({AemConfiguration.class,AemProxyConfiguration.class})
+ public static class TestApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(TestApplication.class, args);
+ }
+
+ @Component
+ public static class JerseyConfig extends ResourceConfig {
+ }
+ }
+
+ /**
+ * Tests the AemAfSubmitProcessor. It utilizes an SSL connection to test the SslBundle code.
+ *
+ */
+ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
+ classes = {TestApplication.class, JerseyConfig.class, AfSubmitAemProxyProcessor.class},
+ properties = {
+// "debug",
+ "fluentforms.aem.servername=" + "localhost",
+ "fluentforms.aem.port=" + "8502",
+ "fluentforms.aem.user=admin",
+ "fluentforms.aem.password=admin",
+ "fluentforms.aem.useSsl=true",
+ "spring.ssl.bundle.jks.aem.truststore.location=file:src/test/resources/aemforms.p12",
+ "spring.ssl.bundle.jks.aem.truststore.password=Pa$$123",
+ "spring.ssl.bundle.jks.aem.truststore.type=PKCS12"
+ }
+ )
+ public static class AemProxyAfSubmissionTestWithAemAfSubmitProcessorTest {
+
+ @RegisterExtension
+ static WireMockExtension wm1 = WireMockExtension.newInstance()
+ .options(WireMockConfiguration.wireMockConfig().httpsPort(8502)
+ .httpDisabled(true)
+ .keystorePath("src/test/resources/aemforms.p12")
+ .keyManagerPassword("Pa$$123")
+ .keystorePassword("Pa$$123")
+ .keystoreType("PKCS12")
+ )
+ .configureStaticDsl(true) // Use with Static DSL
+ .build();
+
+ @LocalServerPort
+ private int port;
+
+ private JakartaRestClient jrc;
+
+ @BeforeEach
+ public void setUp() throws Exception {
+ jrc = setUpRestClient(port);
+ }
+
+ @Test
+ void test() {
+ // given
+ String expectedResponseString = "Dummy Response";
+ WireMock.stubFor(WireMock.post(AEM_SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+ .willReturn(WireMock.okForContentType("text/html", expectedResponseString))
+ );
+ final FormDataMultiPart getPdfForm = mockFormData("foo", "bar");
+
+ // when
+ Response response = jrc.target.path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH).request().accept(APPLICATION_PDF)
+ .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
+
+ // then
+ assertThat(response, allOf(isStatus(Response.Status.OK),hasEntityMatching(equalTo(expectedResponseString.getBytes()))));
+ WireMock.verify(
+ WireMock.postRequestedFor(WireMock.urlEqualTo(AEM_SUBMIT_ADAPTIVE_FORM_SERVICE_PATH))
+ .withAnyRequestBodyPart(WireMock.aMultipart("jcr:data").withBody(WireMock.equalTo("bar")))
+ );
+ }
+
+ }
+
+ /**
+ * Tests the AemLocalSubmitProcessor
+ *
+ */
+ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
+ classes = {TestApplication.class, JerseyConfig.class, AfSubmitLocalProcessor.class, MockAemProxy.class,
+ AemProxyAfSubmissionTestWithLocalAfSubmitProcessorTest.MockSubmissionProcessor.class,
+ AemProxyAfSubmissionTestWithLocalAfSubmitProcessorTest.MockSubmissionProcessor2.class}
+ ,properties={
+// "debug",
+ "logging.level.com._4point.aem.fluentforms.spring=DEBUG"
+ }
+ )
+ public static class AemProxyAfSubmissionTestWithLocalAfSubmitProcessorTest {
+ private static final String AF_SUBMIT_LOCAL_PROCESSOR_RESPONSE = "AfSubmitLocalProcessor Response";
+
+ private final static Logger logger = LoggerFactory.getLogger(AemProxyAfSubmissionTestWithLocalAfSubmitProcessorTest.class);
+
+ @LocalServerPort
+ private int port;
+
+ private JakartaRestClient jrc;
+
+ @BeforeEach
+ public void setUp() throws Exception {
+ jrc = setUpRestClient(port);
+ }
+
+
+ @Test
+ void testResponse() {
+ final FormDataMultiPart getPdfForm = mockFormData("foo1", "bar");
+
+ Response response = jrc.target
+ .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+ .request()
+ .accept(MediaType.TEXT_PLAIN_TYPE)
+ .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
+
+ assertThat(response, allOf(isStatus(Response.Status.OK),hasEntityMatching(equalTo(AF_SUBMIT_LOCAL_PROCESSOR_RESPONSE.getBytes()))));
+ }
+
+ @Test
+ void testRedirect() {
+ final FormDataMultiPart getPdfForm = mockFormData("foo2", "bar");
+
+ Response response = jrc.target
+ .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+ .request()
+ .accept(MediaType.TEXT_PLAIN_TYPE)
+ .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
+
+ assertThat(response, allOf(isStatus(Response.Status.TEMPORARY_REDIRECT), doesNotHaveEntity()));
+ }
+
+ @Test
+ void testSeeOther() {
+ final FormDataMultiPart getPdfForm = mockFormData("foo3", "bar");
+
+ Response response = jrc.target
+ .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+ .request()
+ .accept(MediaType.TEXT_PLAIN_TYPE)
+ .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
+
+ assertThat(response, allOf(isStatus(Response.Status.SEE_OTHER), doesNotHaveEntity()));
+ }
+
+ @Test
+ void testProxy() {
+ final FormDataMultiPart getPdfForm = mockFormData("foo2", "bar");
+
+ Response response = jrc.target
+ .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH+"anythingElse")
+ .request()
+ .accept(MediaType.TEXT_PLAIN_TYPE)
+ .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
+
+ assertThat(response, allOf(isStatus(Response.Status.OK), doesNotHaveEntity()));
+ }
+
+ @Component
+ public static class MockSubmissionProcessor implements AfSubmissionHandler {
+
+ @Override
+ public boolean canHandle(String formName) {
+ logger.atDebug().log(()->"I can handle form name '" + formName + "'!!!!");
+ assertEquals(AF_TEMPLATE_NAME, formName);
+ return true; // Can always handle.
+ }
+
+
+ @Override
+ public SubmitResponse processSubmission(Submission submission) {
+ // Validate the arguments passed in.
+
+ assertAll(
+ ()->assertEquals(AF_TEMPLATE_NAME, submission.formName()),
+ ()->assertEquals("bar", submission.formData()),
+ ()->assertThat(submission.redirectUrl(), anyOf(equalTo("foo1"), equalTo("foo2"), equalTo("foo3"))),
+ ()->assertEquals(MediaType.TEXT_PLAIN, submission.headers().getFirst("accept")),
+ ()->assertTrue(MediaType.MULTIPART_FORM_DATA_TYPE.isCompatible(MediaType.valueOf(submission.headers().getFirst("content-type"))))
+ );
+ try {
+ String redirectUrl = submission.redirectUrl();
+ return switch(redirectUrl) {
+ case "foo1" -> new SubmitResponse.Response(AF_SUBMIT_LOCAL_PROCESSOR_RESPONSE.getBytes(), "text/plain");
+ case "foo2" -> new SubmitResponse.Redirect(new URI("http://localhost/"));
+ case "foo3" -> new SubmitResponse.SeeOther(new URI("http://localhost/"));
+ default -> throw new UnsupportedOperationException("Unexpected value in redirectUrl (%s)".formatted(redirectUrl));
+ };
+ } catch (URISyntaxException e) {
+ throw new IllegalStateException("Bad URI -- ", e);
+ }
+ }
+ }
+
+ @Component
+ public static class MockSubmissionProcessor2 implements AfSubmissionHandler {
+
+ @Override
+ public boolean canHandle(String formName) {
+ return false; // Can never handle.
+ }
+
+
+ @Override
+ public SubmitResponse processSubmission(Submission submission) {
+ fail("MockSubmissionProcessor2.processSubmission should never be called");
+ return null;
+ }
+ }
+
+ @Configuration
+ public static class MockAemProxy {
+ @Bean()
+ public InternalAfSubmitAemProxyProcessor aemProxyProcessor() {
+ AfSubmitAemProxyProcessor mock = Mockito.mock(AfSubmitAemProxyProcessor.class);
+ Mockito.when(mock.processRequest(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Response.ok().build());
+ return ()->mock;
+ }
+ }
+ }
+
+ /**
+ * Tests a custom AfSubmitProcessor
+ *
+ */
+ @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
+ classes = {TestApplication.class, JerseyConfig.class, AemProxyAfSubmissionTestWithCustomAfSubmitProcessorTest.MockSubmitProcessor.class}
+// ,properties="debug"
+ )
+ public static class AemProxyAfSubmissionTestWithCustomAfSubmitProcessorTest {
+
+ @LocalServerPort
+ private int port;
+
+ private JakartaRestClient jrc;
+
+ @BeforeEach
+ public void setUp() throws Exception {
+ jrc = setUpRestClient(port);
+ }
+
+ @Test
+ void test() {
+ final FormDataMultiPart getPdfForm = mockFormData("foo", "bar");
+
+ Response response = jrc.target
+ .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+ .request()
+ .accept(APPLICATION_PDF)
+ .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
+
+ assertThat(response, allOf(isStatus(Response.Status.OK), hasEntityMatching(equalTo(SAMPLE_RESPONSE_BODY.getBytes()))));
+ }
+
+ @Component
+ public static class MockSubmitProcessor implements JerseyAfSubmitProcessor {
+
+ @Override
+ public Response processRequest(FormDataMultiPart inFormData, HttpHeaders headers, String remainder) {
+ return Response.ok().entity(SAMPLE_RESPONSE_BODY).build();
+ }
+ }
+ }
+
+ public static class SubmitResponseResponseTests {
+ private static final String SAMPLE_TEXT = "text";
+ private static final byte[] SAMPLE_TEXT_BYTES = SAMPLE_TEXT.getBytes(StandardCharsets.UTF_8);
+
+ enum TestScenario {
+ TEXT("text/plain", SubmitResponse.Response::text),
+ HTML("text/html", SubmitResponse.Response::html),
+ JSON("application/json", SubmitResponse.Response::json),
+ XML("application/xml", SubmitResponse.Response::xml)
+ ;
+ final String expectedContentType;
+ final Function methodUnderTest;
+
+ private TestScenario(String expectedContentType, Function methodUnderTest) {
+ this.expectedContentType = expectedContentType;
+ this.methodUnderTest = methodUnderTest;
+ }
+ }
+
+ @ParameterizedTest
+ @EnumSource
+ void testResponseCreationMethod(TestScenario scenario) {
+ var result = scenario.methodUnderTest.apply(SAMPLE_TEXT);
+ assertAll(
+ ()->assertArrayEquals(SAMPLE_TEXT_BYTES, result.responseBytes()),
+ ()->assertEquals(scenario.expectedContentType, result.mediaType())
+ );
+ }
+ }
+
+ public static class AfSubmissionHandlerTests {
+ // In this class we test the static convenience methods that generate AfSubmissionHandlers. Since the
+ // processSubmission logic is one line (and trivial) we don't test it, however we do test the canHandle()
+ // method generated by the convenience method.
+
+ @ParameterizedTest
+ @CsvSource({
+ "formName, true",
+ "notFormName, false"
+ })
+ void testcanHandleFormNameEquals(String formNameIn, boolean expectedResult) {
+ var underTest = AfSubmissionHandler.canHandleFormNameEquals("formName", t->null);
+ assertEquals(expectedResult, underTest.canHandle(formNameIn));
+ }
+
+ @DisplayName("Passing in null should produce a null pointer exception")
+ @Test
+ void testcanHandleFormNameEquals_Null() {
+ NullPointerException ex = assertThrows(NullPointerException.class, ()->AfSubmissionHandler.canHandleFormNameEquals(null, t->null));
+ assertThat(ex, exceptionMsgContainsAll("Form Name for submission handler cannot be null"));
+ }
+
+ @ParameterizedTest
+ @CsvSource({
+ "formName1, true",
+ "formName2, true",
+ "notFormName, false"
+ })
+ void testcanHandleFormNameAnyOf(String formNameIn, boolean expectedResult) {
+ var underTest = AfSubmissionHandler.canHandleFormNameAnyOf(t->null, "formName1", "formName2");
+ assertEquals(expectedResult, underTest.canHandle(formNameIn));
+ }
+
+ @ParameterizedTest
+ @CsvSource({
+ "formName1, false",
+ "formName2, false",
+ "notFormName, false"
+ })
+ void testcanHandleFormNameAnyOf_NoNames(String formNameIn, boolean expectedResult) {
+ var underTest = AfSubmissionHandler.canHandleFormNameAnyOf(t->null);
+ assertEquals(expectedResult, underTest.canHandle(formNameIn));
+ }
+
+ @ParameterizedTest
+ @CsvSource({
+ "formName1, true",
+ "formName2, true",
+ "notFormName, false"
+ })
+ void testcanHandleFormNameAnyOf_List(String formNameIn, boolean expectedResult) {
+ var underTest = AfSubmissionHandler.canHandleFormNameAnyOf(List.of("formName1", "formName2"), t->null);
+ assertEquals(expectedResult, underTest.canHandle(formNameIn));
+ }
+
+ @ParameterizedTest
+ @CsvSource({
+ "formName1, false",
+ "formName2, false",
+ "notFormName, false"
+ })
+ void testcanHandleFormNameAnyOf__List_NoNames(String formNameIn, boolean expectedResult) {
+ var underTest = AfSubmissionHandler.canHandleFormNameAnyOf(List.of(), t->null);
+ assertEquals(expectedResult, underTest.canHandle(formNameIn));
+ }
+
+ @ParameterizedTest
+ @CsvSource({
+ "formName1, true",
+ "formName2, true",
+ "notFormName, false"
+ })
+ void testcanHandleFormNameMatchesRegEx(String formNameIn, boolean expectedResult) {
+ var underTest = AfSubmissionHandler.canHandleFormNameMatchesRegex("formName.*", t->null);
+ assertEquals(expectedResult, underTest.canHandle(formNameIn));
+ }
+ }
+}
\ No newline at end of file
diff --git a/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyAutoConfigurationTest.java b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyAutoConfigurationTest.java
new file mode 100644
index 00000000..cfb13982
--- /dev/null
+++ b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyAutoConfigurationTest.java
@@ -0,0 +1,35 @@
+package com._4point.aem.fluentforms.spring;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest(classes = {com._4point.aem.fluentforms.spring.FluentFormsJerseyAutoConfigurationTest.TestApplication.class, FluentFormsAutoConfiguration.class, AemProxyAutoConfiguration.class},
+properties = {
+ "fluentforms.aem.servername=localhost",
+ "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=admin",
+ "fluentforms.aem.password=admin)",
+ })
+class AemProxyJerseyAutoConfigurationTest {
+
+ @Test
+ void testDocumentFactory(@Autowired ResourceConfigCustomizer afProxyConfigurer) {
+ assertNotNull(afProxyConfigurer);
+ }
+
+ @SpringBootApplication
+ @EnableConfigurationProperties({AemConfiguration.class,AemProxyConfiguration.class})
+ public static class TestApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(TestApplication.class, args);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyEndpointTest.java b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyEndpointTest.java
new file mode 100644
index 00000000..ae37cd30
--- /dev/null
+++ b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyJerseyEndpointTest.java
@@ -0,0 +1,172 @@
+package com._4point.aem.fluentforms.spring;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.*;
+import static java.util.Objects.requireNonNullElse;
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.FieldSource;
+import org.junit.jupiter.params.provider.ValueSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.web.server.LocalServerPort;
+import org.springframework.web.client.RestClient;
+
+import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
+import com.github.tomakehurst.wiremock.junit5.WireMockTest;
+
+@WireMockTest(httpPort = AemProxyJerseyEndpointTest.WIREMOCK_PORT)
+@SpringBootTest(classes = {com._4point.aem.fluentforms.spring.AemProxyJerseyEndpointTest.TestApplication.class},
+webEnvironment = WebEnvironment.RANDOM_PORT,
+properties = {
+"fluentforms.aem.servername=localhost",
+"fluentforms.aem.port=" + AemProxyJerseyEndpointTest.WIREMOCK_PORT,
+"fluentforms.aem.user=ENC(7FgD3ZsSExfUGRYlXNc++6C1upPBURNKq6HouzagnNZW4FsBwFs5+crawv+djhw6)",
+"fluentforms.aem.password=ENC(QmQ6iTm/+TOO8U3dDuBzJWH129vReWgYNdgqQwWhjWaQy6j8sMnk2/Auhehmlh3v)",
+//"fluentforms.aem.useSsl=true",
+"fluentforms.rproxy.af-base-location=" + AemProxyJerseyEndpointTest.AF_BASE_LOCATION,
+"jasypt.encryptor.algorithm=PBEWITHHMACSHA512ANDAES_256",
+"jasypt.encryptor.password=4Point",
+"jasypt.encryptor.iv-generator-classname=org.jasypt.iv.RandomIvGenerator",
+"jasypt.encryptor.salt-generator-classname=org.jasypt.salt.RandomSaltGenerator",
+"logging.level.com._4point.aem.fluentforms.spring.AemProxyEndpoint=DEBUG"
+})
+@Timeout(value = 5, unit = TimeUnit.MINUTES) // Fail tests that take longer than this to prevent hanging.
+class AemProxyJerseyEndpointTest {
+ private final static Logger logger = LoggerFactory.getLogger(AemProxyJerseyEndpointTest.class);
+
+ static final int WIREMOCK_PORT = 5504;
+ static final String AF_BASE_LOCATION = "/aem";
+
+ // The following is a string that contains all possible values that may be modified by the AemProxyEndpoint.
+ private static final String MODIFICATION_TARGETS_FORMAT_STR = """
+ 'contextPath = %sresult[1];'
+ '"%s/etc.clientlibs/toggles.json"'
+ """;
+ private static final String MODIFICATION_TARGETS = MODIFICATION_TARGETS_FORMAT_STR.formatted("", "");
+
+ @LocalServerPort
+ private int port;
+
+ private RestClient restClient;
+
+ @BeforeEach
+ void setup(WireMockRuntimeInfo wmRuntimeInfo) {
+ restClient = RestClient.builder()
+ .baseUrl(("http://localhost:%d" + AF_BASE_LOCATION).formatted(port)) // "/aem" added to the front of the base URL we're testing
+ .build();
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "/libs/granite/csrf/token.json",
+ "/lc/libs/granite/csrf/token.json",
+ "/etc.clientlibs/clientlibs/granite/jquery/granite/csrf.js",
+ "/etc.clientlibs/fd/xfaforms/clientlibs/I18N/en.js",
+ "/etc.clientlibs/fd/xfaforms/clientlibs/I18N/en_US.js",
+ "/etc.clientlibs/fd/xfaforms/clientlibs/profile.css",
+ })
+ void testProxyUnmodifiedGet(String endpoint) {
+ // Given
+ String aemResponseText = "Value should be unmodified. " + MODIFICATION_TARGETS;
+ runTest(endpoint, aemResponseText, aemResponseText);
+ }
+
+ final static List MODIFIED_GET_ARGUMENTS = List.of(
+ Arguments.of("/etc.clientlibs/clientlibs/granite/utils.js", "\"" + AF_BASE_LOCATION + "\" + ", ""),
+ Arguments.of("/etc.clientlibs/fd/xfaforms/clientlibs/profile.js", "", "/aem")
+ );
+
+ @ParameterizedTest
+ @FieldSource("MODIFIED_GET_ARGUMENTS")
+ void testProxyModifiedGet(String endpoint, String modValueUtilsJs, String modValueProfileJs) {
+ // Given
+ String aemResponseText = "Value should be modified. " + MODIFICATION_TARGETS;
+ String expectedResult = "Value should be modified. " + MODIFICATION_TARGETS_FORMAT_STR.formatted(requireNonNullElse(modValueUtilsJs, ""), requireNonNullElse(modValueProfileJs, ""));
+ runTest(endpoint, aemResponseText, expectedResult);
+ }
+
+ @Test
+ void testProxyGet_Utils_Js() {
+ // Given
+ String endpoint = "/etc.clientlibs/clientlibs/granite/utils.js";
+ String aemResponseText = "Value to be modified 'contextPath = result[1];'";
+ String expectedResponseText = "Value to be modified 'contextPath = \"" + AF_BASE_LOCATION + "\" + result[1];'";
+ runTest(endpoint, aemResponseText, expectedResponseText);
+ }
+
+ private void runTest(String endpoint, String inputText, String expectedResponseText) {
+ stubFor(get(urlPathEqualTo(endpoint)).willReturn(okForContentType("text/plain", inputText)));
+
+ logger.atInfo()
+ .addArgument(endpoint)
+ .addArgument(inputText)
+ .addArgument(expectedResponseText)
+ .log("Testing proxy endpoint '{}' with input '{}', expecting response '{}'.");
+
+ // When
+ // Make rest call to the proxy endpoint
+ String result;
+ try {
+ result = restClient.get()
+ .uri(endpoint)
+ .retrieve()
+ .body(String.class);
+ } catch (Exception e) {
+ logger.atError()
+ .addArgument(endpoint)
+ .addArgument(inputText)
+ .addArgument(expectedResponseText)
+ .log("Caught exception while testing proxy endpoint '{}' with input '{}', expecting response '{}'.");
+ throw e;
+ }
+
+ assertNotNull(result);
+ assertEquals(expectedResponseText, result);
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "/jcr:content/guideContainer.af.internalsubmit.jsp",
+ "/jcr:content/guideContainer.af.submit.jsp"
+ })
+ void testProxyPost(String endpoint) {
+ String aemResponseText = "Value should be unmodified. " + MODIFICATION_TARGETS;
+ stubFor(post(urlPathEqualTo(endpoint)).willReturn(okForContentType("text/plain", aemResponseText)));
+
+ // When
+ // Make rest call to the proxy endpoint
+ String result = restClient.post()
+ .uri(endpoint)
+ .retrieve()
+ .body(String.class);
+
+ assertNotNull(result);
+ assertEquals(aemResponseText, result);
+ }
+
+ @SpringBootApplication
+ @EnableConfigurationProperties({AemConfiguration.class, AemProxyConfiguration.class})
+ public static class TestApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(TestApplication.class, args);
+ }
+
+// @Bean
+// public ResourceConfigCustomizer afProxyConfigurer(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, @Autowired(required = false) SslBundles sslBundles) {
+// return config->config.register(new AemProxyEndpoint(aemConfig, aemProxyConfig, sslBundles));
+// }
+ }
+}
\ No newline at end of file
diff --git a/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/FluentFormsJerseyAutoConfigurationTest.java b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/FluentFormsJerseyAutoConfigurationTest.java
new file mode 100644
index 00000000..369a2f05
--- /dev/null
+++ b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/FluentFormsJerseyAutoConfigurationTest.java
@@ -0,0 +1,285 @@
+package com._4point.aem.fluentforms.spring;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import com._4point.aem.docservices.rest_services.client.RestClient;
+import com._4point.aem.docservices.rest_services.client.af.AdaptiveFormsService;
+import com._4point.aem.docservices.rest_services.client.helpers.AemConfig;
+import com._4point.aem.docservices.rest_services.client.helpers.Builder.RestClientFactory;
+import com._4point.aem.docservices.rest_services.client.html5.Html5FormsService;
+import com._4point.aem.docservices.rest_services.client.jersey.JerseyRestClient;
+import com._4point.aem.fluentforms.api.DocumentFactory;
+import com._4point.aem.fluentforms.api.assembler.AssemblerService;
+import com._4point.aem.fluentforms.api.convertPdf.ConvertPdfService;
+import com._4point.aem.fluentforms.api.docassurance.DocAssuranceService;
+import com._4point.aem.fluentforms.api.forms.FormsService;
+import com._4point.aem.fluentforms.api.generatePDF.GeneratePDFService;
+import com._4point.aem.fluentforms.api.output.OutputService;
+import com._4point.aem.fluentforms.api.pdfUtility.PdfUtilityService;
+import com._4point.aem.fluentforms.spring.rest_services.client.SpringRestClientRestClient;
+
+@SpringBootTest(classes = {FluentFormsJerseyAutoConfigurationTest.TestApplication.class, FluentFormsJerseyAutoConfiguration.class, FluentFormsAutoConfiguration.class},
+ properties = {
+ "fluentforms.aem.servername=localhost",
+ "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=admin",
+ "fluentforms.aem.password=admin)",
+ })
+class FluentFormsJerseyAutoConfigurationTest {
+
+ @Test
+ void testAdaptiveFormsService(@Autowired AdaptiveFormsService service) {
+ assertNotNull(service);
+ }
+
+ @Test
+ void testAssemblerService(@Autowired AssemblerService service) {
+ assertNotNull(service);
+ }
+
+ @Test
+ void testDocAssuranceService(@Autowired DocAssuranceService service) {
+ assertNotNull(service);
+ }
+
+ @Test
+ void testFormsService(@Autowired FormsService service) {
+ assertNotNull(service);
+ }
+
+ @Test
+ void testGeneratePDFService(@Autowired GeneratePDFService service) {
+ assertNotNull(service);
+ }
+
+ @Test
+ void testHtml5FormsService(@Autowired Html5FormsService service) {
+ assertNotNull(service);
+ }
+
+ @Test
+ void testOutputService(@Autowired OutputService service) {
+ assertNotNull(service);
+ }
+
+ @Test
+ void testPdfUtilityService(@Autowired PdfUtilityService service) {
+ assertNotNull(service);
+ }
+
+ @Test
+ void testConvertPdfService(@Autowired ConvertPdfService service) {
+ assertNotNull(service);
+ }
+
+ @Test
+ void testDocumentFactory(@Autowired DocumentFactory factory) {
+ assertNotNull(factory);
+ assertNotNull(factory.create(new byte[6]));
+ }
+
+ @Test
+ void testRestClientFactory(@Autowired RestClientFactory factory, @Autowired AemConfiguration config) {
+ RestClient client = factory.apply(toAemConfig(config) , "testRestClientFactory", ()->"correlationId");
+ assertTrue(client instanceof JerseyRestClient, "RestClientFactory should return a JerseyRestClient by default");
+ }
+
+ @Test
+ void testAfInputStreamFilterFactory(@Autowired Function afInputStreamFilter) throws Exception {
+ final String INPUT_STRING = "/etc.clientlibs/foobar";
+ final String EXPECTED_RESULT_STRING = "/aem/etc.clientlibs/foobar";
+
+ assertNotNull(afInputStreamFilter);
+ assertEquals(EXPECTED_RESULT_STRING, applyStreamFilter(INPUT_STRING, afInputStreamFilter));
+ }
+
+ @SpringBootApplication
+ @EnableConfigurationProperties({AemConfiguration.class})
+ public static class TestApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(TestApplication.class, args);
+ }
+ }
+
+ @SpringBootTest(classes = {FluentFormsJerseyAutoConfigurationTest.TestApplication.class, FluentFormsJerseyAutoConfiguration.class, FluentFormsAutoConfiguration.class},
+ properties = {
+ "fluentforms.aem.servername=localhost",
+ "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=admin",
+ "fluentforms.aem.password=admin)",
+ "fluentforms.rproxy.aemPrefix=/app_prefix",
+ "fluentforms.rproxy.clientPrefix=/client_prefix",
+ })
+ public static class AfStreamFilterTest {
+
+ @Test
+ void testAfInputStreamFilterFactory(@Autowired Function afInputStreamFilter) throws Exception {
+ final String INPUT_STRING = "/app_prefix/etc.clientlibs/foobar";
+ final String EXPECTED_RESULT_STRING = "/client_prefix/aem/app_prefix/etc.clientlibs/foobar";
+
+ assertNotNull(afInputStreamFilter);
+ assertEquals(EXPECTED_RESULT_STRING, applyStreamFilter(INPUT_STRING, afInputStreamFilter));
+ }
+ }
+
+ private static String applyStreamFilter(String inputString, Function afInputStreamFilter) {
+ try (InputStream is = afInputStreamFilter.apply(stringToInputStream(inputString))) {
+ return inputStreamToString(is);
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private static InputStream stringToInputStream(String inputString) {
+ return new ByteArrayInputStream(inputString.getBytes(StandardCharsets.UTF_8));
+ }
+
+ private static String inputStreamToString(InputStream inputStream) throws IOException {
+ String result = new BufferedReader(
+ new InputStreamReader(inputStream, StandardCharsets.UTF_8))
+ .lines()
+ .collect(Collectors.joining("\n"));
+ return result;
+ }
+
+ @SpringBootTest(classes = {FluentFormsJerseyAutoConfigurationTest.TestApplication.class, FluentFormsAutoConfiguration.class},
+ properties = {
+ "fluentforms.aem.servername=localhost",
+ "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=admin",
+ "fluentforms.aem.password=admin",
+ "fluentforms.restclient=springrestclient" // Configure for Spring RestClient
+ })
+ public static class SpringRestClientTest {
+
+ @Test
+ void testRestClientFactory(@Autowired RestClientFactory factory, @Autowired AemConfiguration config) {
+ RestClient client = factory.apply(toAemConfig(config) , "testRestClientFactory", ()->"correlationId");
+ assertTrue(client instanceof SpringRestClientRestClient, "RestClientFactory should return a SpringRestClientRestClient when configured to do so");
+ }
+ }
+
+ @SpringBootTest(classes = {FluentFormsJerseyAutoConfigurationTest.TestApplication.class, FluentFormsAutoConfiguration.class},
+ properties = {
+ "fluentforms.aem.servername=localhost",
+ "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=admin",
+ "fluentforms.aem.password=admin",
+ "fluentforms.aem.usessl=true",
+ "fluentforms.restclient=springrestclient" // Configure for Spring RestClient
+ })
+ public static class SpringRestClient_SslNoBundleNameTest {
+
+ @Test
+ void testRestClientFactory(@Autowired RestClientFactory factory, @Autowired AemConfiguration config) {
+ RestClient client = factory.apply(toAemConfig(config) , "testRestClientFactory", ()->"correlationId");
+ assertTrue(client instanceof SpringRestClientRestClient, "RestClientFactory should return a SpringRestClientRestClient when configured to do so");
+ }
+ }
+
+ @SpringBootTest(classes = {FluentFormsJerseyAutoConfigurationTest.TestApplication.class, FluentFormsJerseyAutoConfiguration.class, FluentFormsAutoConfiguration.class},
+ properties = {
+ "fluentforms.aem.servername=localhost",
+ "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=admin",
+ "fluentforms.aem.password=admin",
+ "fluentforms.aem.usessl=true",
+ "fluentforms.rproxy.enabled=false",
+ "fluentforms.restclient=jersey" // Configure for Jersey RestClient
+ })
+ public static class JserseyRestClient_SslNoBundleNameTest {
+
+ @Test
+ void testRestClientFactory(@Autowired RestClientFactory factory, @Autowired AemConfiguration config) {
+ RestClient client = factory.apply(toAemConfig(config) , "testRestClientFactory", ()->"correlationId");
+ assertTrue(client instanceof JerseyRestClient, "RestClientFactory should return a JerseyRestClient when configured to do so");
+ }
+ }
+
+ @SpringBootTest(classes = {FluentFormsJerseyAutoConfigurationTest.TestApplication.class, FluentFormsAutoConfiguration.class},
+ properties = {
+ "fluentforms.aem.servername=localhost",
+ "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=admin",
+ "fluentforms.aem.password=admin",
+ "fluentforms.aem.usessl=true",
+ "spring.ssl.bundle.jks.aem.truststore.location=file:src/test/resources/aemforms.p12",
+ "spring.ssl.bundle.jks.aem.truststore.password=Pa$$123",
+ "spring.ssl.bundle.jks.aem.truststore.type=PKCS12",
+ "fluentforms.restclient=springrestclient" // Configure for Spring RestClient
+ })
+ public static class SpringRestClient_SslBundleTest {
+
+ @Test
+ void testRestClientFactory(@Autowired RestClientFactory factory, @Autowired AemConfiguration config) {
+ RestClient client = factory.apply(toAemConfig(config) , "testRestClientFactory", ()->"correlationId");
+ assertTrue(client instanceof SpringRestClientRestClient, "RestClientFactory should return a SpringRestClientRestClient when configured to do so");
+ }
+ }
+
+ @SpringBootTest(classes = {FluentFormsJerseyAutoConfigurationTest.TestApplication.class, FluentFormsAutoConfiguration.class},
+ properties = {
+ "fluentforms.aem.servername=localhost",
+ "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=admin",
+ "fluentforms.aem.password=admin",
+ "fluentforms.aem.usessl=true",
+ "spring.ssl.bundle.jks.aem.truststore.location=file:src/test/resources/aemforms.p12",
+ "spring.ssl.bundle.jks.aem.truststore.password=Pa$$123",
+ "spring.ssl.bundle.jks.aem.truststore.type=PKCS12",
+ "fluentforms.restclient=jersey" // Configure for Jersey RestClient
+ })
+ public static class JserseyRestClient_SslBundleTest {
+
+ @Test
+ void testRestClientFactory(@Autowired RestClientFactory factory, @Autowired AemConfiguration config) {
+ RestClient client = factory.apply(toAemConfig(config) , "testRestClientFactory", ()->"correlationId");
+ assertTrue(client instanceof JerseyRestClient, "RestClientFactory should return a JerseyRestClient when configured to do so");
+ }
+ }
+ private static AemConfig toAemConfig(AemConfiguration config) {
+ return new AemConfig() {
+
+ @Override
+ public String servername() {
+ return config.servername();
+ }
+
+ @Override
+ public Integer port() {
+ return config.port();
+ }
+
+ @Override
+ public String user() {
+ return config.user();
+ }
+
+ @Override
+ public String password() {
+ return config.password();
+ }
+
+ @Override
+ public Boolean useSsl() {
+ return config.useSsl();
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/JerseyAutoConfigurationTest.java b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/JerseyAutoConfigurationTest.java
new file mode 100644
index 00000000..5cf571aa
--- /dev/null
+++ b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/JerseyAutoConfigurationTest.java
@@ -0,0 +1,252 @@
+package com._4point.aem.fluentforms.spring;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.autoconfigure.web.client.RestClientSsl;
+import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
+import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.boot.test.context.runner.ContextConsumer;
+import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.client.RestClient;
+
+import com._4point.aem.fluentforms.api.output.OutputService;
+import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmissionHandler;
+import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.SpringAfSubmitProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyJerseyAfSubmission.AfSubmitAemProxyProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyJerseyAfSubmission.AfSubmitLocalProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyJerseyAfSubmission.JerseyAfSubmitProcessor;
+
+/**
+ * Test that AutoConfiguration happens. The code in this test class is based on the following docs:
+ *
+ * https://spring.io/blog/2018/03/07/testing-auto-configurations-with-spring-boot-2-0
+ *
+ */
+class JerseyAutoConfigurationTest {
+
+ /**
+ * This class provides mock versions of beans that would normally be provided by Spring Boot in a real application. We
+ * only need to mock out the RestClient.Builder and RestClientSsl beans because those are the only Spring Boot provided
+ * beans that our AutoConfigurations depend on.
+ */
+ private static class SpringBootMocks {
+ @Bean RestClient.Builder mockRestClientBuilder() { return Mockito.mock(RestClient.Builder.class, Mockito.RETURNS_DEEP_STUBS); }
+ @Bean private RestClientSsl mockRestClientSsl() { return Mockito.mock(RestClientSsl.class); }
+ }
+
+ private static final AutoConfigurations AUTO_CONFIG = AutoConfigurations.of(FluentFormsJerseyAutoConfiguration.class, AemProxyJerseyAutoConfiguration.class, FluentFormsAutoConfiguration.class, AemProxyAutoConfiguration.class, SpringBootMocks.class);
+
+ private static final AutoConfigurations LOCAL_SUBMIT_CONFIG = AutoConfigurations.of(FluentFormsJerseyAutoConfiguration.class, AemProxyJerseyAutoConfiguration.class, FluentFormsAutoConfiguration.class, AemProxyAutoConfiguration.class, DummyLocalSubmitHandler.class, SpringBootMocks.class);
+
+ private static final AutoConfigurations ALTERNATE_PROXY_CONFIG = AutoConfigurations.of(DummyProxyImplementation.class, FluentFormsJerseyAutoConfiguration.class, AemProxyJerseyAutoConfiguration.class, FluentFormsAutoConfiguration.class, AemProxyAutoConfiguration.class, SpringBootMocks.class);
+
+ // Tests to make sure that only the FluentFormsLibraries are loaded in a non-web application.
+ private static final ContextConsumer super AssertableApplicationContext> FF_LIBRARIES_ONLY = (context) -> {
+ assertAll(
+ ()->assertThat(context).hasSingleBean(FluentFormsAutoConfiguration.class),
+ ()->assertThat(context).getBean(FluentFormsAutoConfiguration.class.getName()).isSameAs(context.getBean(FluentFormsAutoConfiguration.class)),
+ ()->assertThat(context).hasSingleBean(OutputService.class),
+ ()->assertThat(context).getBean("outputService").isNotNull(),
+ ()->assertThat(context).doesNotHaveBean(AemProxyAutoConfiguration.class),
+ ()->assertThat(context).doesNotHaveBean(SpringAfSubmitProcessor.class),
+ ()->assertThat(context).doesNotHaveBean(AfSubmissionHandler.class),
+ ()->assertThat(context).doesNotHaveBean(AemProxyJerseyAutoConfiguration.class),
+ ()->assertThat(context).doesNotHaveBean(JerseyAfSubmitProcessor.class)
+ );
+ };
+
+ // Tests to make sure that only the FluentFormsLibraries are loaded in a web application.
+ private static final ContextConsumer super AssertableWebApplicationContext> WEB_FF_LIBRARIES_ONLY = (context) -> {
+ assertAll(
+ ()->assertThat(context).hasSingleBean(FluentFormsAutoConfiguration.class),
+ ()->assertThat(context).getBean(FluentFormsAutoConfiguration.class.getName()).isSameAs(context.getBean(FluentFormsAutoConfiguration.class)),
+ ()->assertThat(context).hasSingleBean(OutputService.class),
+ ()->assertThat(context).getBean("outputService").isNotNull(),
+ ()->assertThat(context).doesNotHaveBean(AemProxyAutoConfiguration.class),
+ ()->assertThat(context).doesNotHaveBean(SpringAfSubmitProcessor.class),
+ ()->assertThat(context).doesNotHaveBean(AfSubmissionHandler.class),
+ ()->assertThat(context).doesNotHaveBean(AemProxyJerseyAutoConfiguration.class),
+ ()->assertThat(context).doesNotHaveBean(JerseyAfSubmitProcessor.class)
+ );
+ };
+
+ // Tests to make sure that all beans are loaded by default in a web application.
+ private static final ContextConsumer super AssertableWebApplicationContext> WEB_ALL_DEFAULT_SERVICES = (context) -> {
+ assertAll(
+ ()->assertThat(context).hasSingleBean(FluentFormsAutoConfiguration.class),
+ ()->assertThat(context).getBean(FluentFormsAutoConfiguration.class.getName()).isSameAs(context.getBean(FluentFormsAutoConfiguration.class)),
+ ()->assertThat(context).hasSingleBean(OutputService.class),
+ ()->assertThat(context).getBean("outputService").isNotNull(),
+ ()->assertThat(context).hasSingleBean(AemProxyJerseyAutoConfiguration.class),
+ ()->assertThat(context).getBean(AemProxyJerseyAutoConfiguration.class.getName()).isSameAs(context.getBean(AemProxyJerseyAutoConfiguration.class)),
+ ()->assertThat(context).hasSingleBean(JerseyAfSubmitProcessor.class),
+ ()->assertThat(context).getBean(JerseyAfSubmitProcessor.class).isSameAs(context.getBean(AfSubmitAemProxyProcessor.class)),
+ ()->assertThat(context).doesNotHaveBean(AfSubmissionHandler.class)
+ );
+ };
+
+ // Tests to make sure that all beans are loaded by default in a web application.
+ private static final ContextConsumer super AssertableWebApplicationContext> WEB_ALL_SPRINGMVC_SERVICES = (context) -> {
+ assertAll(
+ ()->assertThat(context).hasSingleBean(FluentFormsAutoConfiguration.class),
+ ()->assertThat(context).getBean(FluentFormsAutoConfiguration.class.getName()).isSameAs(context.getBean(FluentFormsAutoConfiguration.class)),
+ ()->assertThat(context).hasSingleBean(OutputService.class),
+ ()->assertThat(context).getBean("outputService").isNotNull(),
+ ()->assertThat(context).hasSingleBean(AemProxyAutoConfiguration.class),
+ ()->assertThat(context).getBean(AemProxyAutoConfiguration.class.getName()).isSameAs(context.getBean(AemProxyAutoConfiguration.class)),
+ ()->assertThat(context).hasSingleBean(SpringAfSubmitProcessor.class),
+ ()->assertThat(context).getBean(SpringAfSubmitProcessor.class).isSameAs(context.getBean(AemProxyAfSubmission.AfSubmitAemProxyProcessor.class)),
+ ()->assertThat(context).doesNotHaveBean(AfSubmissionHandler.class),
+ ()->assertThat(context).doesNotHaveBean(AemProxyJerseyAutoConfiguration.class),
+ ()->assertThat(context).doesNotHaveBean(JerseyAfSubmitProcessor.class)
+ );
+ };
+
+ // Tests to make sure that all beans are loaded in a web application that contains a local submit handler.
+ private static final ContextConsumer super AssertableWebApplicationContext> WEB_LOCAL_SUBMIT_SERVICES = (context) -> {
+ assertAll(
+ ()->assertThat(context).hasSingleBean(FluentFormsAutoConfiguration.class),
+ ()->assertThat(context).getBean(FluentFormsAutoConfiguration.class.getName()).isSameAs(context.getBean(FluentFormsAutoConfiguration.class)),
+ ()->assertThat(context).hasSingleBean(OutputService.class),
+ ()->assertThat(context).getBean("outputService").isNotNull(),
+ ()->assertThat(context).hasSingleBean(AemProxyJerseyAutoConfiguration.class),
+ ()->assertThat(context).getBean(AemProxyJerseyAutoConfiguration.class.getName()).isSameAs(context.getBean(AemProxyJerseyAutoConfiguration.class)),
+ ()->assertThat(context).hasSingleBean(JerseyAfSubmitProcessor.class),
+ ()->assertThat(context).getBean(JerseyAfSubmitProcessor.class).isSameAs(context.getBean(AfSubmitLocalProcessor.class)),
+ ()->assertThat(context).hasSingleBean(AfSubmissionHandler.class),
+ ()->assertThat(context).getBean(DummyLocalSubmitHandler.class).isSameAs(context.getBean(AfSubmissionHandler.class))
+ );
+ };
+
+ private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+ .withConfiguration(AUTO_CONFIG);
+
+ private final WebApplicationContextRunner webContextRunner = new WebApplicationContextRunner()
+ .withConfiguration(AUTO_CONFIG);
+
+ private final WebApplicationContextRunner webLocalSubmitContextRunner = new WebApplicationContextRunner()
+ .withConfiguration(LOCAL_SUBMIT_CONFIG);
+
+ private final WebApplicationContextRunner webAlternateProxyContextRunner = new WebApplicationContextRunner()
+ .withConfiguration(ALTERNATE_PROXY_CONFIG);
+
+ // Only the services that do not require a web server should be started.
+ @Test
+ void nonWebContext_StartNonWebServices() {
+ this.contextRunner
+ .withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=user", "fluentforms.aem.password=password")
+ .run(FF_LIBRARIES_ONLY);
+ }
+
+ // All services should start when a proper web context has been initialized.
+ @Test
+ void webContext_StartAllServices() {
+ this.webContextRunner
+ .withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=user", "fluentforms.aem.password=password")
+ .run(WEB_ALL_DEFAULT_SERVICES);
+ }
+
+ // Only the FluentForms libraries are instantiated when the proxy is explicitly disabled.
+ @Test
+ void webContext_ProxyDisabled_StartNonProxyServices() {
+ this.webContextRunner
+ .withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=user", "fluentforms.aem.password=password",
+ "fluentforms.rproxy.enabled=false")
+ .run(WEB_FF_LIBRARIES_ONLY);
+ }
+
+ // Only the FluentForms libraries are instantiated when the proxy is not properly disabled.
+ @Test
+ void webContext_ProxyNotSpecifiedCorrectly_StartNonProxyServices() {
+ this.webContextRunner
+ .withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=user", "fluentforms.aem.password=password",
+ "fluentforms.rproxy.enabled=foobar")
+ .run(WEB_FF_LIBRARIES_ONLY);
+ }
+
+ // All services should start when the proxy has been explicitly enabled.
+ @Test
+ void webContext_ProxyEnabled_StartNonProxyServices() {
+ this.webContextRunner
+ .withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=user", "fluentforms.aem.password=password",
+ "fluentforms.rproxy.enabled=true")
+ .run(WEB_ALL_DEFAULT_SERVICES);
+ }
+
+ // All services should start when a proper web context has been initialized.
+ @Test
+ void webContext_StartAllServices_LocalSubmit() {
+ this.webLocalSubmitContextRunner
+ .withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=user", "fluentforms.aem.password=password")
+ .run(WEB_LOCAL_SUBMIT_SERVICES);
+ }
+
+ // Only the FluentForms libraries are instantiated by this autoconfiguration when an alternate proxy implementation is supplied.
+ @Test
+ void webContext_StartAllServices_AlternateProxySupplied() {
+ this.webAlternateProxyContextRunner
+ .withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=user", "fluentforms.aem.password=password")
+ .run(WEB_FF_LIBRARIES_ONLY);
+ }
+
+ // Only the FluentForms libraries are instantiated when an alternate proxy tyoe is configured.
+ @Test
+ void webContext_ProxyDisabled_AlternateProxyConfigured() {
+ this.webContextRunner
+ .withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=user", "fluentforms.aem.password=password",
+ "fluentforms.rproxy.type=someothertype")
+ .run(WEB_FF_LIBRARIES_ONLY);
+ }
+
+ // All services should start when the jersey proxy type is configured.
+ @Test
+ void webContext_ProxyEnabled_DefaultProxyConfigured() {
+ this.webContextRunner
+ .withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=user", "fluentforms.aem.password=password",
+ "fluentforms.rproxy.type=jersey")
+ .run(WEB_ALL_DEFAULT_SERVICES);
+ }
+
+ // All services should start when the jersey proxy type is configured.
+ @Test
+ void webContext_ProxyEnabled_SpringMvcProxyConfigured() {
+ this.webContextRunner
+ .withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=user", "fluentforms.aem.password=password",
+ "fluentforms.rproxy.type=springmvc")
+ .run(WEB_ALL_SPRINGMVC_SERVICES);
+ }
+
+
+ public static class DummyLocalSubmitHandler implements AfSubmissionHandler {
+
+ @Override
+ public boolean canHandle(String formName) {
+ return false;
+ }
+
+ @Override
+ public SubmitResponse processSubmission(Submission submission) {
+ return null;
+ }
+ }
+
+ public static class DummyProxyImplementation implements AemProxyImplemention {
+
+ }
+}
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/JerseyClientFactoryTest.java b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/JerseyClientFactoryTest.java
similarity index 99%
rename from spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/JerseyClientFactoryTest.java
rename to spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/JerseyClientFactoryTest.java
index 80cf0470..4f2098cf 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/JerseyClientFactoryTest.java
+++ b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/JerseyClientFactoryTest.java
@@ -70,4 +70,4 @@ void testCreateClient_NullSslBundles_NullString() throws Exception {
assertNotNull(client.getSslContext());
}
-}
+}
\ No newline at end of file
diff --git a/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/resources/aemforms.p12 b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/resources/aemforms.p12
new file mode 100644
index 00000000..2e835490
Binary files /dev/null and b/spring/fluentforms-jersey-spring-boot-autoconfigure/src/test/resources/aemforms.p12 differ
diff --git a/spring/fluentforms-jersey-spring-boot-starter/pom.xml b/spring/fluentforms-jersey-spring-boot-starter/pom.xml
new file mode 100644
index 00000000..f5efb9c4
--- /dev/null
+++ b/spring/fluentforms-jersey-spring-boot-starter/pom.xml
@@ -0,0 +1,78 @@
+
+ 4.0.0
+ com._4point.aem.fluentforms
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.5.7
+
+
+ fluentforms-jersey-spring-boot-starter
+ 0.0.4-SNAPSHOT
+ FluentForms Jersey Spring Boot Starter
+ Spring Boot starter for FluentForms library using Jersey
+
+ 17
+ 3.0.5
+ 3.0.5
+ 0.0.4-SNAPSHOT
+ 0.0.4-SNAPSHOT
+
+
+
+
+ github
+ 4Point Solutions FluentFormsAPI Apache Maven Packages
+ https://maven.pkg.github.com/4PointSolutions/FluentFormsAPI
+
+
+
+
+
+ github
+ https://maven.pkg.github.com/4PointSolutions/*
+
+ true
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ com._4point.aem.fluentforms
+ fluentforms-jersey-spring-boot-autoconfigure
+ ${fluentforms-jersey-autoconfigure.version}
+
+
+
+
+
+
+
+ com.github.ulisesbocchio
+ jasypt-maven-plugin
+ ${jasypt.maven.plugin.version}
+
+
+
+
\ No newline at end of file
diff --git a/spring/fluentforms-jersey-spring-boot-starter/src/main/java/.gitignore b/spring/fluentforms-jersey-spring-boot-starter/src/main/java/.gitignore
new file mode 100644
index 00000000..e69de29b
diff --git a/spring/fluentforms-jersey-spring-boot-starter/src/main/resources/.gitignore b/spring/fluentforms-jersey-spring-boot-starter/src/main/resources/.gitignore
new file mode 100644
index 00000000..e69de29b
diff --git a/spring/fluentforms-jersey-spring-boot-starter/src/test/java/.gitignore b/spring/fluentforms-jersey-spring-boot-starter/src/test/java/.gitignore
new file mode 100644
index 00000000..e69de29b
diff --git a/spring/fluentforms-jersey-spring-boot-starter/src/test/resources/.gitignore b/spring/fluentforms-jersey-spring-boot-starter/src/test/resources/.gitignore
new file mode 100644
index 00000000..e69de29b
diff --git a/spring/fluentforms-sample-cli-app/pom.xml b/spring/fluentforms-sample-cli-app/pom.xml
index dfd9a097..1b4c92ff 100644
--- a/spring/fluentforms-sample-cli-app/pom.xml
+++ b/spring/fluentforms-sample-cli-app/pom.xml
@@ -50,6 +50,20 @@
org.springframework.boot
spring-boot-maven-plugin
+
+
+ maven-install-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
diff --git a/spring/fluentforms-sample-web-jersey-app/pom.xml b/spring/fluentforms-sample-web-jersey-app/pom.xml
index 50c3f6b3..09ba17fa 100644
--- a/spring/fluentforms-sample-web-jersey-app/pom.xml
+++ b/spring/fluentforms-sample-web-jersey-app/pom.xml
@@ -6,6 +6,7 @@
org.springframework.boot
spring-boot-starter-parent
3.5.7
+
com._4point.aem.fluentforms
fluentforms-sample-web-app
@@ -18,7 +19,7 @@
3.13.1
3.10.6
4.16.0
- 0.0.5-SNAPSHOT
+ 0.0.4-SNAPSHOT
0.0.4-SNAPSHOT
@@ -67,8 +68,8 @@
com._4point.aem.fluentforms
- fluentforms-spring-boot-starter
- ${fluentforms.spring.boot.starter.version}
+ fluentforms-jersey-spring-boot-starter
+ ${fluentforms.jersey.spring.boot.starter.version}
@@ -122,6 +123,20 @@
io.github.git-commit-id
git-commit-id-maven-plugin
+
+
+ maven-install-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
diff --git a/spring/fluentforms-sample-webmvc-app/pom.xml b/spring/fluentforms-sample-webmvc-app/pom.xml
index 04dd57de..4dc40985 100644
--- a/spring/fluentforms-sample-webmvc-app/pom.xml
+++ b/spring/fluentforms-sample-webmvc-app/pom.xml
@@ -6,6 +6,7 @@
org.springframework.boot
spring-boot-starter-parent
3.5.7
+
com._4point.aem.fluentforms
fluentforms-sample-webmvc-app
@@ -127,6 +128,20 @@
io.github.git-commit-id
git-commit-id-maven-plugin
+
+
+ maven-install-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
diff --git a/spring/fluentforms-sample-webmvc-app/src/main/java/com/_4point/aem/fluentforms/sampleapp/JerseyConfig.java b/spring/fluentforms-sample-webmvc-app/src/main/java/com/_4point/aem/fluentforms/sampleapp/JerseyConfig.java
deleted file mode 100644
index e788bd0f..00000000
--- a/spring/fluentforms-sample-webmvc-app/src/main/java/com/_4point/aem/fluentforms/sampleapp/JerseyConfig.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com._4point.aem.fluentforms.sampleapp;
-
-import java.util.Map;
-
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.servlet.ServletProperties;
-import org.springframework.stereotype.Component;
-
-@Component
-public class JerseyConfig extends ResourceConfig {
-
- public JerseyConfig() {
- // Add properties that we want set
- addProperties(Map.of(
- // Turn off Wadl generation (this was interfering with some CORS functionality
- "jersey.config.server.wadl.disableWadl", true,
- "jersey.config.server.response.setStatusOverSendError", true,
- // See https://docs.spring.io/spring-boot/how-to/jersey.html#howto .jersey.alongside-another-web-framework
- ServletProperties.FILTER_FORWARD_ON_404, true
- ));
- }
-
-}
\ No newline at end of file
diff --git a/spring/fluentforms-sample-webmvc-app/src/test/java/com/_4point/aem/fluentforms/sampleapp/resources/WireMockAemProxyEndpointTest.java b/spring/fluentforms-sample-webmvc-app/src/test/java/com/_4point/aem/fluentforms/sampleapp/resources/WireMockAemProxyEndpointTest.java
index 3f3b514b..9025e2f2 100644
--- a/spring/fluentforms-sample-webmvc-app/src/test/java/com/_4point/aem/fluentforms/sampleapp/resources/WireMockAemProxyEndpointTest.java
+++ b/spring/fluentforms-sample-webmvc-app/src/test/java/com/_4point/aem/fluentforms/sampleapp/resources/WireMockAemProxyEndpointTest.java
@@ -3,16 +3,11 @@
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.junit.jupiter.api.Assertions.*;
-import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.TimeUnit;
-import org.htmlunit.DefaultCredentialsProvider;
-import org.htmlunit.WebClient;
-import org.htmlunit.html.HtmlPage;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.api.condition.EnabledIf;
@@ -44,11 +39,10 @@
class WireMockAemProxyEndpointTest extends AbstractAemProxyEndpointTest {
private static final boolean WIREMOCK_RECORDING = false;
- private static final Path RESOURCES_DIR = Path.of("src", "test", "resources");
- private static final Path SAMPLE_FILES_DIR = RESOURCES_DIR.resolve("SampleFiles");
+ private static final String CRX_CONTENT_ROOT = "crx:/content/dam/formsanddocuments/sample-forms/";
public WireMockAemProxyEndpointTest() {
- super(SAMPLE_FILES_DIR.resolve(SAMPLE_XDP_FILENAME_PATH).toAbsolutePath().toString());
+ super(CRX_CONTENT_ROOT + SAMPLE_XDP_FILENAME_PATH);
}
@BeforeEach
@@ -86,46 +80,4 @@ protected void verifyProxyTest() {
)
.forEach(url->verify(getRequestedFor(urlPathEqualTo(url))));
}
-
-
- // In order to re-record the AEM interactions for Wiremock emulation, you need to:
- // 1) run a local AEM server
- // 2) set the WIREMOCK_RECORDING variable to true
- // 3) then run this test.
- //
- // It will record the interactions with the AEM server.
- // Don't forget to set the WIREMOCK_RECORDING variable back to false after you are done.
- //
- // Note: THe recordings may require modification. As of AEM 6.5 LTS, the required changes are:
- // * Two calls to /content/xfaforms/profiles/default.html - One returns a 401, the other returns the form.
- // This is because this HTMLUnit emulates a browser. The 401 recording can be deleted since the FluentForms code
- // sends a pre-emptive authentication header.
- // * the /etc.clientlibs/fd/xfaforms/clientlibs/I18N/en_US recording must be modified to make the _US optional.
- // It appears that the FluentForms call does not include the _US suffix.
- @Disabled("This test is not really a test but it is used to record interactions with the AEM server.")
- @Test
- void aemTest(WireMockRuntimeInfo wmRuntimeInfo) throws Exception {
- DefaultCredentialsProvider userCredentials = new DefaultCredentialsProvider();
- userCredentials.addCredentials("admin", "admin".toCharArray());
- try (final WebClient webClient = new WebClient()) {
- webClient.setCredentialsProvider(userCredentials);
- String baseUri = "http://localhost:" + wmRuntimeInfo.getHttpPort() + "/content/xfaforms/profiles/default.html?contentRoot=crx:///content/dam/formsanddocuments/sample-forms&template=SampleForm.xdp";
- final HtmlPage page = webClient.getPage(baseUri);
- assertEquals("LC Forms", page.getTitleText());
-
-// final String pageAsXml = page.asXml();
-// assertTrue(pageAsXml.contains(""), "Does not contain topBarDisabled");
-//
-// final String pageAsText = page.asNormalizedText();
-// assertTrue(pageAsText.contains("Support for the HTTP and HTTPS protocols"));
- }
- List.of("/content/xfaforms/profiles/default.html",
- "/etc.clientlibs/toggles.json",
- "/libs/granite/csrf/token.json",
- "/etc.clientlibs/fd/xfaforms/clientlibs/I18N/en_US.js",
- "/etc.clientlibs/fd/xfaforms/clientlibs/profile.css",
- "/etc.clientlibs/fd/xfaforms/clientlibs/profile.js"
- )
- .forEach(url->verify(getRequestedFor(urlPathEqualTo(url))));
- }
}
diff --git a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_content_xfaforms_profiles_default_html.json b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_content_xfaforms_profiles_default_html.json
deleted file mode 100644
index 25e537b6..00000000
--- a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_content_xfaforms_profiles_default_html.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "id" : "42c7fedf-c9a2-44a8-acbb-9f0cc1260a39",
- "name" : "content_xfaforms_profiles_default.html",
- "request" : {
- "urlPath" : "/content/xfaforms/profiles/default.html",
- "method" : "GET",
- "queryParameters" : {
- "contentRoot" : {
- "hasExactly" : [ {
- "equalTo" : "crx:///content/dam/formsanddocuments/sample-forms"
- } ]
- },
- "template" : {
- "hasExactly" : [ {
- "equalTo" : "SampleForm.xdp"
- } ]
- }
- }
- },
- "response" : {
- "status" : 200,
- "body" : "\n\n\n\n \n \n\n\n\n\n\n\nLC Forms\n\n\n\n\n\n\n\n\n \n \n \n \n \n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n \n \n \n\n\n\n\n \n\n\n\n \n \n\n\n\n\n\n\n\n\n\n\n \n \n\n\n\n\n\n\n \n\n\n \n \n\n\n\n\n\n\n\n\n\n\n\n \n\n",
- "headers" : {
- "X-Content-Type-Options" : "nosniff",
- "Set-Cookie" : "cq-authoring-mode=TOUCH; Path=/; Expires=Sun, 18-May-2025 11:23:43 GMT; Max-Age=604800",
- "Expires" : "Thu, 01 Jan 1970 00:00:00 GMT",
- "Date" : "Sun, 11 May 2025 11:23:43 GMT",
- "Content-Type" : "text/html;charset=utf-8"
- }
- },
- "uuid" : "42c7fedf-c9a2-44a8-acbb-9f0cc1260a39",
- "persistent" : true,
- "scenarioName" : "scenario-1-content-xfaforms-profiles-default.html",
- "requiredScenarioState" : "scenario-1-content-xfaforms-profiles-default.html-2",
- "insertionIndex" : 23
-}
\ No newline at end of file
diff --git a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_clientlibs_granite_jquery_granite_csrf_js.json b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_clientlibs_granite_jquery_granite_csrf_js.json
index e55231a8..b1a21afb 100644
--- a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_clientlibs_granite_jquery_granite_csrf_js.json
+++ b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_clientlibs_granite_jquery_granite_csrf_js.json
@@ -1,21 +1,22 @@
{
- "id" : "00a42460-ec46-4cee-94e6-33ea44869f87",
- "name" : "etc.clientlibs_clientlibs_granite_jquery_granite_csrf.js",
+ "id" : "7a26c766-1d0f-4af8-a2a5-f1d5cd028f5d",
+ "name" : "libs_granite_csrf_token.json",
"request" : {
- "url" : "/etc.clientlibs/clientlibs/granite/jquery/granite/csrf.js",
+ "url" : "/libs/granite/csrf/token.json",
"method" : "GET"
},
"response" : {
"status" : 200,
- "base64Body" : "LyoKICogQURPQkUgQ09ORklERU5USUFMCiAqCiAqIENvcHlyaWdodCAyMDE1IEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqIHN1cHBsaWVycyBhbmQgbWF5IGJlIGNvdmVyZWQgYnkgVS5TLiBhbmQgRm9yZWlnbiBQYXRlbnRzLAogKiBwYXRlbnRzIGluIHByb2Nlc3MsIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IHRyYWRlIHNlY3JldCBvciBjb3B5cmlnaHQgbGF3LgogKiBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoKICovCi8qIGdsb2JhbCBDUVVSTEluZm86ZmFsc2UgKi8KKGZ1bmN0aW9uKHdpbmRvdykgewogICAgInVzZSBzdHJpY3QiOwoKICAgIHdpbmRvdy5HcmFuaXRlID0gd2luZG93LkdyYW5pdGUgfHwge307CiAgICB3aW5kb3cuR3Jhbml0ZS5IVFRQID0gd2luZG93LkdyYW5pdGUuSFRUUCB8fCB7fTsKCiAgICB2YXIgY29udGV4dFBhdGggPSBudWxsOwoKICAgIGZ1bmN0aW9uIGRldGVjdENvbnRleHRQYXRoKCkgewogICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuCiAgICAgICAgdmFyIFNDUklQVF9VUkxfUkVHRVhQID0gL14oPzpodHRwfGh0dHBzKTpcL1wvW14vXSsoXC8uKilcLyg/OmV0Y1wuY2xpZW50bGlic3xldGMoXC8uKikqXC9jbGllbnRsaWJzfGxpYnMoXC8uKikqXC9jbGllbnRsaWJzfGFwcHMoXC8uKikqXC9jbGllbnRsaWJzfGV0Y1wvZGVzaWducykuKlwuanMoXD8uKik/JC87CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKHdpbmRvdy5DUVVSTEluZm8pIHsKICAgICAgICAgICAgICAgIGNvbnRleHRQYXRoID0gQ1FVUkxJbmZvLmNvbnRleHRQYXRoIHx8ICIiOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIHNjcmlwdHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgic2NyaXB0Iik7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNjcmlwdHMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gU0NSSVBUX1VSTF9SRUdFWFAuZXhlYyhzY3JpcHRzW2ldLnNyYyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0UGF0aCA9IHJlc3VsdFsxXTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvbnRleHRQYXRoID0gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIC8vIGlnbm9yZWQKICAgICAgICB9CiAgICB9CgogICAgd2luZG93LkdyYW5pdGUuSFRUUC5leHRlcm5hbGl6ZSA9IHdpbmRvdy5HcmFuaXRlLkhUVFAuZXh0ZXJuYWxpemUgfHwgZnVuY3Rpb24odXJsKSB7CiAgICAgICAgaWYgKGNvbnRleHRQYXRoID09PSBudWxsKSB7CiAgICAgICAgICAgIGRldGVjdENvbnRleHRQYXRoKCk7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAodXJsLmluZGV4T2YoIi8iKSA9PT0gMCAmJiBjb250ZXh0UGF0aCAmJiB1cmwuaW5kZXhPZihjb250ZXh0UGF0aCArICIvIikgIT09IDApIHsKICAgICAgICAgICAgICAgIHVybCA9IGNvbnRleHRQYXRoICsgdXJsOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAvLyBpZ25vcmVkCiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdXJsOwogICAgfTsKfSkodGhpcyk7CgovKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICoKICogQ29weXJpZ2h0IDIwMTUgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogc3VwcGxpZXJzIGFuZCBtYXkgYmUgY292ZXJlZCBieSBVLlMuIGFuZCBGb3JlaWduIFBhdGVudHMsCiAqIHBhdGVudHMgaW4gcHJvY2VzcywgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuCiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKgogKi8KKGZ1bmN0aW9uKGZhY3RvcnkpIHsKICAgICJ1c2Ugc3RyaWN0IjsKCiAgICAvLyBHUkFOSVRFLTIyMjgxIENoZWNrIGZvciBtdWx0aXBsZSBpbml0aWFsaXphdGlvbgogICAgaWYgKHdpbmRvdy5HcmFuaXRlLmNzcmYpIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgd2luZG93LkdyYW5pdGUuY3NyZiA9IGZhY3Rvcnkod2luZG93LkdyYW5pdGUuSFRUUCk7Cn0oZnVuY3Rpb24oaHR0cCkgewogICAgInVzZSBzdHJpY3QiOwoKICAgIC8vIEFkb2JlUGF0ZW50SUQ9IlA1Mjk2IgoKICAgIGZ1bmN0aW9uIFByb21pc2UoKSB7CiAgICAgICAgdGhpcy5faGFuZGxlciA9IFtdOwogICAgfQoKICAgIFByb21pc2UucHJvdG90eXBlID0gewogICAgICAgIHRoZW46IGZ1bmN0aW9uKHJlc29sdmVGbiwgcmVqZWN0Rm4pIHsKICAgICAgICAgICAgdGhpcy5faGFuZGxlci5wdXNoKHsgcmVzb2x2ZTogcmVzb2x2ZUZuLCByZWplY3Q6IHJlamVjdEZuIH0pOwogICAgICAgIH0sCiAgICAgICAgcmVzb2x2ZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHRoaXMuX2V4ZWN1dGUoInJlc29sdmUiLCBhcmd1bWVudHMpOwogICAgICAgIH0sCiAgICAgICAgcmVqZWN0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdGhpcy5fZXhlY3V0ZSgicmVqZWN0IiwgYXJndW1lbnRzKTsKICAgICAgICB9LAogICAgICAgIF9leGVjdXRlOiBmdW5jdGlvbihyZXN1bHQsIGFyZ3MpIHsKICAgICAgICAgICAgaWYgKHRoaXMuX2hhbmRsZXIgPT09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiUHJvbWlzZSBhbHJlYWR5IGNvbXBsZXRlZC4iKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxuID0gdGhpcy5faGFuZGxlci5sZW5ndGg7IGkgPCBsbjsgaSsrKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVyW2ldW3Jlc3VsdF0uYXBwbHkod2luZG93LCBhcmdzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy50aGVuID0gZnVuY3Rpb24ocmVzb2x2ZUZuLCByZWplY3RGbikgewogICAgICAgICAgICAgICAgKHJlc3VsdCA9PT0gInJlc29sdmUiID8gcmVzb2x2ZUZuIDogcmVqZWN0Rm4pLmFwcGx5KHdpbmRvdywgYXJncyk7CiAgICAgICAgICAgIH07CgogICAgICAgICAgICB0aGlzLl9oYW5kbGVyID0gbnVsbDsKICAgICAgICB9CiAgICB9OwoKICAgIGZ1bmN0aW9uIHZlcmlmeVNhbWVPcmlnaW4odXJsKSB7CiAgICAgICAgLy8gdXJsIGNvdWxkIGJlIHJlbGF0aXZlIG9yIHNjaGVtZSByZWxhdGl2ZSBvciBhYnNvbHV0ZQogICAgICAgIC8vIGhvc3QgKyBwb3J0CiAgICAgICAgdmFyIGhvc3QgPSBkb2N1bWVudC5sb2NhdGlvbi5ob3N0OwogICAgICAgIHZhciBwcm90b2NvbCA9IGRvY3VtZW50LmxvY2F0aW9uLnByb3RvY29sOwogICAgICAgIHZhciByZWxhdGl2ZU9yaWdpbiA9ICIvLyIgKyBob3N0OwogICAgICAgIHZhciBvcmlnaW4gPSBwcm90b2NvbCArIHJlbGF0aXZlT3JpZ2luOwoKICAgICAgICAvLyBBbGxvdyBhYnNvbHV0ZSBvciBzY2hlbWUgcmVsYXRpdmUgVVJMcyB0byBzYW1lIG9yaWdpbgogICAgICAgIHJldHVybiAodXJsID09PSBvcmlnaW4gfHwgdXJsLnNsaWNlKDAsIG9yaWdpbi5sZW5ndGggKyAxKSA9PT0gb3JpZ2luICsgIi8iKSB8fAogICAgICAgICAgICAgICAgKHVybCA9PT0gcmVsYXRpdmVPcmlnaW4gfHwgdXJsLnNsaWNlKDAsIHJlbGF0aXZlT3JpZ2luLmxlbmd0aCArIDEpID09PSByZWxhdGl2ZU9yaWdpbiArICIvIikgfHwKICAgICAgICAgICAgICAgIC8vIG9yIGFueSBvdGhlciBVUkwgdGhhdCBpc24ndCBzY2hlbWUgcmVsYXRpdmUgb3IgYWJzb2x1dGUgaS5lIHJlbGF0aXZlLgogICAgICAgICAgICAgICAgISgvXihcL1wvfGh0dHA6fGh0dHBzOikuKi8udGVzdCh1cmwpKTsKICAgIH0KCiAgICB2YXIgRklFTERfTkFNRSA9ICI6Y3FfY3NyZl90b2tlbiI7CiAgICB2YXIgSEVBREVSX05BTUUgPSAiQ1NSRi1Ub2tlbiI7CiAgICB2YXIgVE9LRU5fU0VSVkxFVCA9IGh0dHAuZXh0ZXJuYWxpemUoIi9saWJzL2dyYW5pdGUvY3NyZi90b2tlbi5qc29uIik7CgogICAgdmFyIHByb21pc2U7CiAgICB2YXIgZ2xvYmFsVG9rZW47CgogICAgZnVuY3Rpb24gbG9nRmFpbFJlcXVlc3QoZXJyb3IpIHsKICAgICAgICBpZiAod2luZG93LmNvbnNvbGUpIHsKICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGUKICAgICAgICAgICAgY29uc29sZS53YXJuKCJDU1JGIGRhdGEgbm90IGF2YWlsYWJsZTsiICsKICAgICAgICAgICAgICAgICAgICAiVGhlIGRhdGEgbWF5IGJlIHVuYXZhaWxhYmxlIGJ5IGRlc2lnbiwgc3VjaCBhcyBkdXJpbmcgbm9uLWF1dGhlbnRpY2F0ZWQgcmVxdWVzdHM6ICIgKyBlcnJvcik7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGdldFRva2VuKCkgewogICAgICAgIHZhciBsb2NhbFByb21pc2UgPSBuZXcgUHJvbWlzZSgpOwogICAgICAgIHByb21pc2UgPSBsb2NhbFByb21pc2U7CgogICAgICAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTsKICAgICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PT0gNCkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IEpTT04ucGFyc2UoeGhyLnJlc3BvbnNlVGV4dCk7CiAgICAgICAgICAgICAgICAgICAgZ2xvYmFsVG9rZW4gPSBkYXRhLnRva2VuOwogICAgICAgICAgICAgICAgICAgIGxvY2FsUHJvbWlzZS5yZXNvbHZlKGdsb2JhbFRva2VuKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4KSB7CiAgICAgICAgICAgICAgICAgICAgbG9nRmFpbFJlcXVlc3QoZXgpOwogICAgICAgICAgICAgICAgICAgIGxvY2FsUHJvbWlzZS5yZWplY3QoeGhyLnJlc3BvbnNlVGV4dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIHhoci5vcGVuKCJHRVQiLCBUT0tFTl9TRVJWTEVULCB0cnVlKTsKICAgICAgICB4aHIuc2VuZCgpOwoKICAgICAgICByZXR1cm4gbG9jYWxQcm9taXNlOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldFRva2VuU3luYygpIHsKICAgICAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7CiAgICAgICAgeGhyLm9wZW4oIkdFVCIsIFRPS0VOX1NFUlZMRVQsIGZhbHNlKTsKICAgICAgICB4aHIuc2VuZCgpOwoKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gZ2xvYmFsVG9rZW4gPSBKU09OLnBhcnNlKHhoci5yZXNwb25zZVRleHQpLnRva2VuOwogICAgICAgIH0gY2F0Y2ggKGV4KSB7CiAgICAgICAgICAgIGxvZ0ZhaWxSZXF1ZXN0KGV4KTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY2xlYXJUb2tlbigpIHsKICAgICAgICBnbG9iYWxUb2tlbiA9IHVuZGVmaW5lZDsKICAgICAgICBnZXRUb2tlbigpOwogICAgfQoKICAgIGZ1bmN0aW9uIGFkZEZpZWxkKGZvcm0pIHsKICAgICAgICB2YXIgYWN0aW9uID0gZm9ybS5nZXRBdHRyaWJ1dGUoImFjdGlvbiIpOwogICAgICAgIGlmIChmb3JtLm1ldGhvZC50b1VwcGVyQ2FzZSgpID09PSAiR0VUIiB8fCAoYWN0aW9uICYmICF2ZXJpZnlTYW1lT3JpZ2luKGFjdGlvbikpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICghZ2xvYmFsVG9rZW4pIHsKICAgICAgICAgICAgZ2V0VG9rZW5TeW5jKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWdsb2JhbFRva2VuKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHZhciBpbnB1dCA9IGZvcm0ucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT0iJyArIEZJRUxEX05BTUUgKyAnIl0nKTsKCiAgICAgICAgaWYgKCFpbnB1dCkgewogICAgICAgICAgICBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImlucHV0Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgidHlwZSIsICJoaWRkZW4iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJuYW1lIiwgRklFTERfTkFNRSk7CiAgICAgICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgIH0KCiAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJ2YWx1ZSIsIGdsb2JhbFRva2VuKTsKICAgIH0KCiAgICBmdW5jdGlvbiBoYW5kbGVGb3JtKGRvY3VtZW50KSB7CiAgICAgICAgdmFyIGhhbmRsZXIgPSBmdW5jdGlvbihldikgewogICAgICAgICAgICB2YXIgdCA9IGV2LnRhcmdldDsKCiAgICAgICAgICAgIGlmICh0Lm5vZGVOYW1lID09PSAiRk9STSIpIHsKICAgICAgICAgICAgICAgIGFkZEZpZWxkKHQpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgaWYgKGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIpIHsKICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigic3VibWl0IiwgaGFuZGxlciwgdHJ1ZSk7CiAgICAgICAgfSBlbHNlIGlmIChkb2N1bWVudC5hdHRhY2hFdmVudCkgewogICAgICAgICAgICBkb2N1bWVudC5hdHRhY2hFdmVudCgic3VibWl0IiwgaGFuZGxlcik7CiAgICAgICAgfQogICAgfQoKICAgIGhhbmRsZUZvcm0oZG9jdW1lbnQpOwoKICAgIHZhciBvcGVuID0gWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLm9wZW47CgogICAgWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbihtZXRob2QsIHVybCwgYXN5bmMpIHsKICAgICAgICBpZiAobWV0aG9kLnRvTG93ZXJDYXNlKCkgIT09ICJnZXQiICYmIHZlcmlmeVNhbWVPcmlnaW4odXJsKSkgewogICAgICAgICAgICB0aGlzLl9jc3JmID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5fYXN5bmMgPSBhc3luYzsKICAgICAgICB9CgogICAgICAgIHJldHVybiBvcGVuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICB9OwoKICAgIHZhciBzZW5kID0gWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLnNlbmQ7CgogICAgWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbigpIHsKICAgICAgICBpZiAoIXRoaXMuX2NzcmYpIHsKICAgICAgICAgICAgc2VuZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoZ2xvYmFsVG9rZW4pIHsKICAgICAgICAgICAgdGhpcy5zZXRSZXF1ZXN0SGVhZGVyKEhFQURFUl9OQU1FLCBnbG9iYWxUb2tlbik7CiAgICAgICAgICAgIHNlbmQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKHRoaXMuX2FzeW5jID09PSBmYWxzZSkgewogICAgICAgICAgICBnZXRUb2tlblN5bmMoKTsKCiAgICAgICAgICAgIGlmIChnbG9iYWxUb2tlbikgewogICAgICAgICAgICAgICAgdGhpcy5zZXRSZXF1ZXN0SGVhZGVyKEhFQURFUl9OQU1FLCBnbG9iYWxUb2tlbik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNlbmQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdmFyIHNlbGYgPSB0aGlzOwogICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTsKCiAgICAgICAgcHJvbWlzZS50aGVuKGZ1bmN0aW9uKHRva2VuKSB7CiAgICAgICAgICAgIHNlbGYuc2V0UmVxdWVzdEhlYWRlcihIRUFERVJfTkFNRSwgdG9rZW4pOwogICAgICAgICAgICBzZW5kLmFwcGx5KHNlbGYsIGFyZ3MpOwogICAgICAgIH0sIGZ1bmN0aW9uKCkgewogICAgICAgICAgICBzZW5kLmFwcGx5KHNlbGYsIGFyZ3MpOwogICAgICAgIH0pOwogICAgfTsKCiAgICB2YXIgc3VibWl0ID0gSFRNTEZvcm1FbGVtZW50LnByb3RvdHlwZS5zdWJtaXQ7CgogICAgSFRNTEZvcm1FbGVtZW50LnByb3RvdHlwZS5zdWJtaXQgPSBmdW5jdGlvbigpIHsKICAgICAgICBhZGRGaWVsZCh0aGlzKTsKICAgICAgICByZXR1cm4gc3VibWl0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICB9OwoKICAgIGlmICh3aW5kb3cuTm9kZSkgewogICAgICAgIHZhciBhYyA9IE5vZGUucHJvdG90eXBlLmFwcGVuZENoaWxkOwoKICAgICAgICBOb2RlLnByb3RvdHlwZS5hcHBlbmRDaGlsZCA9IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgcmVzdWx0ID0gYWMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKCiAgICAgICAgICAgIGlmIChyZXN1bHQubm9kZU5hbWUgPT09ICJJRlJBTUUiKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuY29udGVudFdpbmRvdyAmJiAhcmVzdWx0Ll9jc3JmKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5fY3NyZiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUZvcm0ocmVzdWx0LmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zcmMgJiYgcmVzdWx0LnNyYy5sZW5ndGggJiYgdmVyaWZ5U2FtZU9yaWdpbihyZXN1bHQuc3JjKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAod2luZG93LmNvbnNvbGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCJVbmFibGUgdG8gYXR0YWNoIENTUkYgdG9rZW4gdG8gYW4gaWZyYW1lIGVsZW1lbnQgb24gdGhlIHNhbWUgb3JpZ2luIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFBvdGVudGlhbCBlcnJvcjogQWNjZXNzIGlzIERlbmllZAogICAgICAgICAgICAgICAgICAgIC8vIHdlIGNhbiBzYWZlbHkgaWdub3JlIENPUlMgc2VjdXJpdHkgZXJyb3JzIGhlcmUKICAgICAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGUgY3NyZiBhbnl3YXlzIHRvIGFub3RoZXIgZG9tYWluCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfTsKICAgIH0KCiAgICAvLyByZWZyZXNoaW5nIGNzcmYgdG9rZW4gcGVyaW9kaWNhbGx5CiAgICBnZXRUb2tlbigpOwoKICAgIHNldEludGVydmFsKGZ1bmN0aW9uKCkgewogICAgICAgIGdldFRva2VuKCk7CiAgICB9LCAzMDAwMDApOwoKICAgIHJldHVybiB7CiAgICAgICAgaW5pdGlhbGlzZWQ6IGZhbHNlLAogICAgICAgIHJlZnJlc2hUb2tlbjogZ2V0VG9rZW4sCiAgICAgICAgX2NsZWFyVG9rZW46IGNsZWFyVG9rZW4KICAgIH07Cn0pKTsKCg==",
+ "body" : "{\"token\":\"eyJleHAiOjE3NjMzMDM3OTQsImlhdCI6MTc2MzMwMzE5NH0.5v2R_70ZbNN7EUoVwrGql7hk1EBeJ2FepXfNUxQJkg8\"}",
"headers" : {
+ "Cache-Control" : "no-cache",
"X-Content-Type-Options" : "nosniff",
- "Last-Modified" : "Sat, 03 May 2025 13:47:20 GMT",
- "Date" : "Sun, 11 May 2025 11:23:44 GMT",
- "Content-Type" : "application/javascript;charset=utf-8"
+ "Expires" : "-1",
+ "Date" : "Sun, 16 Nov 2025 14:26:34 GMT",
+ "Content-Type" : "application/json"
}
},
- "uuid" : "00a42460-ec46-4cee-94e6-33ea44869f87",
+ "uuid" : "7a26c766-1d0f-4af8-a2a5-f1d5cd028f5d",
"persistent" : true,
- "insertionIndex" : 20
+ "insertionIndex" : 31
}
\ No newline at end of file
diff --git a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_fd_xfaforms_clientlibs_i18n_en_us_js.json b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_fd_xfaforms_clientlibs_i18n_en_us_js.json
index 7751f30c..ccdbf588 100644
--- a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_fd_xfaforms_clientlibs_i18n_en_us_js.json
+++ b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_fd_xfaforms_clientlibs_i18n_en_us_js.json
@@ -1,8 +1,8 @@
{
- "id" : "a1cf3903-7f2b-43f4-bbfe-862e68daaf6e",
- "name" : "etc.clientlibs_fd_xfaforms_clientlibs_i18n_en_us.js",
+ "id" : "8bab67f2-6d86-4b88-85f3-660ae4be80bc",
+ "name" : "etc.clientlibs_fd_xfaforms_clientlibs_i18n_en.js",
"request" : {
- "urlPattern" : "/etc\\.clientlibs/fd/xfaforms/clientlibs/I18N/en(_US)?\\.js",
+ "url" : "/etc.clientlibs/fd/xfaforms/clientlibs/I18N/en.js",
"method" : "GET"
},
"response" : {
@@ -10,12 +10,12 @@
"base64Body" : "LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqIF9fX19fX19fX19fX19fX19fX18KICoKICogIENvcHlyaWdodCAyMDEzIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgo7KGZ1bmN0aW9uKCkgewogICAgeGZhbGliID0gewogICAgICAgIHV0IDoge30sCiAgICAgICAgc2NyaXB0IDogewogICAgICAgICAgICBtaXhpbiA6IHt9LAogICAgICAgICAgICBkb20gOiB7fQogICAgICAgIH0sCiAgICAgICAgdmlldyA6IHsKICAgICAgICAgICAgdXRpbDp7fSwKICAgICAgICAgICAgbGF5b3V0Ont9CiAgICAgICAgfSwKICAgICAgICBydW50aW1lOiB7CiAgICAgICAgICAgIF9wcml2YXRlOiB7fQogICAgICAgIH0sCiAgICAgICAgbG9jYWxlIDoge30sCiAgICAgICAgYWNyb2JhdDoge30sIC8vYWRkZWQgZm9yIGFjcm9iYXQgc3BlY2lmaWMgc2NyaXB0cwogICAgICAgIHRlbXBsYXRlOiB7fSwKICAgICAgICBnbG9iYWxzOiB7CiAgICAgICAgICAgIGhpZ2hsaWdodCA6IGZhbHNlIC8vIGZsYWcgZm9yICJIaWdobGlnaHQgRXhpc3RpbmcgRmllbGRzIgogICAgICAgIH0KICAgIH07CiAgICB3aW5kb3cueGZhbGliID0geGZhbGliOwp9KSgpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTMgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCihmdW5jdGlvbih4ZmFsaWIpewp4ZmFsaWIubG9jYWxlLlN0cmluZ3MgPQp7CiAgICAicGxlYXNlVGFwVGV4dCIgICAgICAgICA6ICAgICAgICJQbGVhc2UgdGFwIGhlcmUgdG8gc2lnbiIsCgkicGxlYXNlQ2xpY2tUZXh0IiAgICAgICA6ICAgICAgICJQbGVhc2UgY2xpY2sgaGVyZSB0byBzaWduIiwKCSJjbGVhclNpZ25hdHVyZSIgICAgICAgIDogICAgICAgIkNsZWFyIFNpZ25hdHVyZSBDb25maXJtYXRpb24iLAoJImNsZWFyU2lnbmF0dXJlQ29uZmlybSIgOiAgICAgICAiQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGNsZWFyIHNpZ25hdHVyZT8iLAoJImZldGNoR2VvTG9jYXRpb24iICAgICAgOiAgICAgICAiRmV0Y2hpbmcgR2VvIExvY2F0aW9uIGluZm8uLi4iLAoJImVycm9yRmV0Y2hHZW9Mb2NhdGlvbiIgOiAgICAgICAiRXJyb3IgZmV0Y2hpbmcgZ2VvbG9jYXRpb24gaW5mbyIsCgkicGxlYXNlU2lnblRleHQiICAgICAgICA6ICAgICAgICJQbGVhc2Ugc2lnbiBoZXJlIiwKCSJsYXRpdHVkZSIgICAgICAgICAgICAgIDogICAgICAgIkxhdGl0dWRlIiwKCSJsb25naXR1ZGUiICAgICAgICAgICAgIDogICAgICAgIkxvbmdpdHVkZSIsCgkidGltZSIgICAgICAgICAgICAgICAgICA6ICAgICAgICJUaW1lIiwKICAgICJjbGVhclRleHQiICAgICAgICAgICAgIDogICAgICAgIkNsZWFyIiwKICAgICJ2YWxpZGF0aW9uSXNzdWUiICAgICAgIDogICAgICAgIlZhbGlkYXRpb24gRXJyb3IgaW4gdGhlIGZpZWxkIiwKICAgICJ3YXJuaW5nIiAgICAgICAgICAgICAgIDogICAgICAgIldhcm5pbmdzIiwKICAgICJlcnJvcnMiICAgICAgICAgICAgICAgIDogICAgICAgIkVycm9ycyIsCiAgICAiZXJyb3JTZXJ2ZXJTY3JpcHQiICAgICA6ICAgICAgICJFcnJvciBpbiBydW5uaW5nIHNlcnZlciBzY3JpcHQiLAogICAgInVuYWJsZVRvQ29ubmVjdFRleHQiICAgOiAgICAgICAiQ291bGRuJ3QgY29ubmVjdCB0byB0aGUgc2VydmVyIiwKICAgICJlcnJvclN1Ym1pdHRpbmdGb3JtIiAgIDogICAgICAgIkVycm9yIHN1Ym1pdHRpbmcgZm9ybSB0byBpbnRlcm5hbCB1cmwiLAogICAgIm9rIiAgICAgICAgICAgICAgICAgICAgOiAgICAgICAiT0siLAogICAgImNhbmNlbCIgICAgICAgICAgICAgICAgOiAgICAgICAiQ2FuY2VsIiwKICAgICJ5ZXMiICAgICAgICAgICAgICAgICAgIDogICAgICAgIlllcyIsCiAgICAibm8iICAgICAgICAgICAgICAgICAgICA6ICAgICAgICJObyIsCiAgICAiY2xlYXIiICAgICAgICAgICAgICAgICA6ICAgICAgICJDbGVhciIsCiAgICAiYnJ1c2hlcyIgICAgICAgICAgICAgICA6ICAgICAgICJCcnVzaGVzIiwKICAgICJnZW9sb2NhdGlvbiIgICAgICAgICAgIDogICAgICAgIkdlb2xvY2F0aW9uIiwKICAgICJGaWxlQ2xvc2VBY2Nlc3NUZXh0IiAgIDogICAgICAgIlByZXNzIEVudGVyIHRvIGRlbGV0ZSB0aGUgZmlsZSAiLAogICAgIkZpbGVTaXplR3JlYXRlciIgICAgICAgOiAgICAgICAiRmlsZShzKSB7MH0gYXJlIGdyZWF0ZXIgdGhhbiB0aGUgZXhwZWN0ZWQgc2l6ZTogezF9TUIuIiwKICAgICJGaWxlTmFtZUludmFsaWQiICAgICAgIDogICAgICAgIkRvIG5vdCBhdHRhY2ggZmlsZXMgd2hlcmUgZmlsZW5hbWUgc3RhcnRzIHdpdGggKC4pLCBjb250YWlucyBcXCAvIDogKiA/IFwiIDwgPiB8IDsgJSAkLCBvciBpcyBhIHJlc2VydmVkIGtleXdvcmQgbGlrZSBudWwsIHBybiwgY29uLCBscHQsIG9yIGNvbS4iLAogICAgIkZpbGVNaW1lVHlwZUludmFsaWQiICAgOiAgICAgICAiRmlsZShzKSB7MH0gYXJlIHVuc3VwcG9ydGVkIGZpbGUgdHlwZXMiLAogICAgIlVuYWJsZVRvU2F2ZSIgICAgICAgICAgOiAgICAgICAiVW5hYmxlIHRvIHNhdmUiLAogICAgIlNhdmVkU3VjY2Vzc2Z1bGx5IiAgICAgOiAgICAgICAiU2F2ZWQgU3VjY2Vzc2Z1bGx5IiwKICAgICJBdHRhY2giICAgICAgICAgICAgICAgIDogICAgICAgIkF0dGFjaCIsCiAgICAiZGF0ZVBpY2tlckFyaWFMYWJlbCIgICA6ICAgICAgICJQbGVhc2UgRW50ZXIgZGF0ZSBpbiB7MH0gZm9ybWF0IG9ubHkiLAogICAgInR5cGVZb3VyU2lnbmF0dXJlSGVyZSIgOiAgICAgICAiVHlwZSBZb3VyIFNpZ25hdHVyZSBIZXJlIiwKICAgICJ0eXBlWW91ck5hbWUiICAgICAgICAgIDogICAgICAgIlR5cGUgWW91ciBOYW1lIgp9Cn0pKHhmYWxpYik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogX19fX19fX19fX19fX19fX19fXwogKgogKiAgQ29weXJpZ2h0IDIwMTMgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCgooZnVuY3Rpb24oeGZhbGliKXsKeGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlcyA9CnsKICAgICJBTEMtRlJNLTkwMS0wMDEiICAgOiAgICJbQUxDLUZSTS05MDEtMDAxXSA6ICIreGZhbGliLmxvY2FsZS5TdHJpbmdzLmVycm9yU2VydmVyU2NyaXB0LAogICAgIkFMQy1GUk0tOTAxLTAwMiIgICA6ICAgIltBTEMtRlJNLTkwMS0wMDJdIDogRXhjZXB0aW9uIG9jY3VycmVkIHdoaWxlIGV4ZWN1dGluZyB7MH0gc2NyaXB0IGZvciB7MX0gOiB7Mn0uIiwKICAgICJBTEMtRlJNLTkwMS0wMDMiICAgOiAgICJbQUxDLUZSTS05MDEtMDAzXSA6IEVycm9yOiB4ZmEgaXMgbm90IGluaXRpYWxpemVkLiIsCiAgICAiQUxDLUZSTS05MDEtMDA0IiAgIDogICAiW0FMQy1GUk0tOTAxLTAwNF0gOiBOdWxsUG9pbnRlciBFeGNlcHRpb246IHswfSBjaGlsZCB7MX0gaXMgbnVsbC4iLAogICAgIkFMQy1GUk0tOTAxLTAwNSIgICA6ICAgIltBTEMtRlJNLTkwMS0wMDVdIDogZXhjZXB0aW9uIHswfSBpbiBwYXJzaW5nIHVzZXIgc2NyaXB0LiBzY3JpcHQ6ezF9LiIsCiAgICAiQUxDLUZSTS05MDEtMDA2IiAgIDogICAiW0FMQy1GUk0tOTAxLTAwNl0gOiBVbnN1cHBvcnRlZCBvcGVyYXRpb24gOiB7MH0uIiwKICAgICJBTEMtRlJNLTkwMS0wMDciICAgOiAgICJbQUxDLUZSTS05MDEtMDA3XSA6IEVycm9yIGluIHJ1bm5pbmcgc2VydmVyIHNjcmlwdHMuIFR5cGUgbWlzbWF0Y2ggb2xkOiB7MH0sIG5ldzogezF9LiIsCiAgICAiQUxDLUZSTS05MDEtMDA4IiAgIDogICAiW0FMQy1GUk0tOTAxLTAwOF0gOiAiK3hmYWxpYi5sb2NhbGUuU3RyaW5ncy51bmFibGVUb0Nvbm5lY3RUZXh0LAogICAgIkFMQy1GUk0tOTAxLTAwOSIgICA6ICAgIltBTEMtRlJNLTkwMS0wMDldIDogTWVzc2FnZSBCb3ggd2l0aCBZZXMvTm8gYXJlIG5vdCBzdXBwb3J0ZWQgYW5kIGNvbnZlcnRlZCB0byBPay9DYW5jZWwgbWVzc2FnZSBib3ggYnV0IHRoZSByZXR1cm4gdmFsdWVzIGFyZSBjb3JyZWN0IGkuZSBmb3IgWWVzL05vIiwKICAgICJBTEMtRlJNLTkwMS0wMTAiICAgOiAgICJbQUxDLUZSTS05MDEtMDEwXSA6IE1lc3NhZ2UgQm94IHdpdGggMyBidXR0b25zIGFyZSBub3Qgc3VwcG9ydGVkIiwKICAgICJBTEMtRlJNLTkwMS0wMTEiICAgOiAgICJbQUxDLUZSTS05MDEtMDExXSA6IEdlbyBMb2NhdGlvbiBub3Qgc3VwcG9ydGVkIiwKICAgICJBTEMtRlJNLTkwMS0wMTIiICAgOiAgICJbQUxDLUZSTS05MDEtMDEyXSA6IE1peGVkIG1vZGUgZGF0YSBiaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQiLAogICAgIkFMQy1GUk0tOTAxLTAxMyIgICA6ICAgIltBTEMtRlJNLTkwMS0wMTNdIDogQ2FsY3VsYXRpb25zIGZhaWxlZCBhZnRlciB7MH0iLAogICAgIkFMQy1GUk0tOTAxLTAxNCIgICA6ICAgIltBTEMtRlJNLTkwMS0wMTRdIDogVmFsaWRhdGlvbiBmYWlsZWQgZm9yIHRoZSBvYmplY3Q6IHswfS4gVmFsaWRhdGUgU2NyaXB0IGlzIHsxfSIsCiAgICAiQUxDLUZSTS05MDEtMDE1IiAgIDogICAiW0FMQy1GUk0tOTAxLTAxNV0gOiBleGNlcHRpb24gezB9IGluIGNyZWF0aW5nIHVzZXIgc2NyaXB0IG9iamVjdC4gdXNlciBzY3JpcHQ6ezF9LCBpbml0aWFsaXplZCBmcm9tIGV2ZW50OiB7Mn0sIG9iamVjdCA6IHszfSIsCiAgICAiQUxDLUZSTS05MDEtMDE2IiAgIDogICAiW0FMQy1GUk0tOTAxLTAxNl0gOiAiK3hmYWxpYi5sb2NhbGUuU3RyaW5ncy5lcnJvclN1Ym1pdHRpbmdGb3JtLAogICAgIkFMQy1GUk0tOTAxLTAxNyIgICA6ICAgIltBTEMtRlJNLTkwMS0wMTddIDogRXhjZXB0aW9uIG9jY3VycmVkIHswfSB3aGlsZSBhY2Nlc3NpbmcgcHJvcGVydHkgezF9IG9mIHsyfSIgLAogICAgIkFMQy1GUk0tOTAxLTAxOCIgICA6ICAgIltBTEMtRlJNLTkwMS0wMThdIDogVGhpcyBmb3JtIG1heSBub3QgcmVuZGVyIGNvcnJlY3RseSBhcyB5b3UgYXJlIHVzaW5nIGFuIHVuc3VwcG9ydGVkIGJyb3dzZXIuIiwKICAgICJBTEMtRlJNLTkwMS0wMTkiICAgOiAgICJbQUxDLUZSTS05MDEtMDE5XSA6IEV4Y2VwdGlvbiBvY2N1cnJlZCB3aGlsZSByZXNvbHZpbmcgZmxvYXRpbmcgZmllbGRzIGZvciA6IHswfS4iLAogICAgIkFMQy1GUk0tOTAxLTAyMCIgICA6ICAgIltBTEMtRlJNLTkwMS0wMjBdIDogRXhjZXB0aW9uIHdoaWxlIEluaXRpYWxpemluZyBMb2dnZXIuIEludmFsaWQgQ29uZmlndXJhdGlvbiB7MH0gaW4gezF9IiwKICAgICJBTEMtRlJNLTkwMS0wMjEiICAgOiAgICJbQUxDLUZSTS05MDEtMDIxXSA6IEZhaWxlZCB0byBwYXJzZSBkYXRhUGF0dGVybiB7MH0gZm9yIHRoZSB2YWx1ZSB7MX06IHsyfSIsCiAgICAiQUxDLUZSTS05MDEtMDIyIiAgIDogICAiW0FMQy1GUk0tOTAxLTAyMl0gOiBTa2lwcGVkIHBhcnNpbmcgTXVsdGlwbGUgZGF0YVBhdHRlcm5zICBwYXR0ZXJuIHswfSB2YWx1ZSB7MX0iLAogICAgIkFMQy1GUk0tOTAxLTAyMyIgICA6ICAgIltBTEMtRlJNLTkwMS0wMjNdIDogTnVtZXJpYyBQYXR0ZXJucyBoYXZpbmcgdGhlIGZvcm1hdCAocGF0dGVybikgYXJlIG5vdCBzdXBwb3J0ZWQuICIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNraXBwaW5nIHBhdHRlcm4gezB9IHZhbHVlIHsxfSIKfQp9KSh4ZmFsaWIpOwoK",
"headers" : {
"X-Content-Type-Options" : "nosniff",
- "Last-Modified" : "Sat, 03 May 2025 13:49:07 GMT",
- "Date" : "Sun, 11 May 2025 11:23:44 GMT",
+ "Last-Modified" : "Thu, 18 Sep 2025 12:47:59 GMT",
+ "Date" : "Sun, 16 Nov 2025 14:26:31 GMT",
"Content-Type" : "application/javascript;charset=utf-8"
}
},
- "uuid" : "a1cf3903-7f2b-43f4-bbfe-862e68daaf6e",
+ "uuid" : "8bab67f2-6d86-4b88-85f3-660ae4be80bc",
"persistent" : true,
- "insertionIndex" : 21
+ "insertionIndex" : 35
}
\ No newline at end of file
diff --git a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_fd_xfaforms_clientlibs_profile_css.json b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_fd_xfaforms_clientlibs_profile_css.json
index 3b0ef386..538e288e 100644
--- a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_fd_xfaforms_clientlibs_profile_css.json
+++ b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_fd_xfaforms_clientlibs_profile_css.json
@@ -1,5 +1,5 @@
{
- "id" : "3e90f2cb-315a-4083-a77d-c94479894815",
+ "id" : "1a4d3741-e8fd-426c-ad01-e05ab57658fd",
"name" : "etc.clientlibs_fd_xfaforms_clientlibs_profile.css",
"request" : {
"url" : "/etc.clientlibs/fd/xfaforms/clientlibs/profile.css",
@@ -10,12 +10,14 @@
"body" : "/*!\n * Portions copyright © 2017 Adobe Systems Incorporated\n * Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome\n * Font Awesome by Dave Gandy - http://fontawesome.io\n * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n\n@font-face {\n font-family: 'fontello';\n src: url('../../rte/gui/components/clientlibs/thirdparty/resources/fontello.eot?66049208');\n src: url('../../rte/gui/components/clientlibs/thirdparty/resources/fontello.eot?66049208#iefix') format('embedded-opentype'),\n url('../../rte/gui/components/clientlibs/thirdparty/resources/fontello.woff2?66049208') format('woff2'),\n url('../../rte/gui/components/clientlibs/thirdparty/resources/fontello.woff?66049208') format('woff'),\n url('../../rte/gui/components/clientlibs/thirdparty/resources/fontello.ttf?66049208') format('truetype'),\n url('../../rte/gui/components/clientlibs/thirdparty/resources/fontello.svg?66049208#fontello') format('svg');\n font-weight: normal;\n font-style: normal;\n}\n/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */\n/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */\n/*\n@media screen and (-webkit-min-device-pixel-ratio:0) {\n @font-face {\n font-family: 'fontello';\n src: url('../../rte/gui/components/clientlibs/thirdparty/font/fontello.svg?66049208#fontello') format('svg');\n }\n}\n*/\n \n [class^=\"icon-\"]:before, [class*=\" icon-\"]:before {\n font-family: \"fontello\";\n font-style: normal;\n font-weight: normal;\n speak: none;\n \n display: inline-block;\n text-decoration: inherit;\n width: 1em;\n margin-right: .2em;\n text-align: center;\n /* opacity: .8; */\n \n /* For safety - reset parent styles, that can break glyph codes*/\n font-variant: normal;\n text-transform: none;\n \n /* fix buttons height, for twitter bootstrap */\n line-height: 1em;\n \n /* Animation center compensation - margins should be symmetric */\n /* remove if not needed */\n margin-left: .2em;\n \n /* you can be more comfortable with increased icons size */\n /* font-size: 120%; */\n \n /* Font smoothing. That was taken from TWBS */\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n \n /* Uncomment for 3D effect */\n /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */\n}\n \n.icon-search:before { content: '\\e800'; } /* '' */\n.icon-heart-empty:before { content: '\\e801'; } /* '' */\n.icon-star:before { content: '\\e802'; } /* '' */\n.icon-star-empty:before { content: '\\e803'; } /* '' */\n.icon-glass:before { content: '\\e804'; } /* '' */\n.icon-star-half:before { content: '\\e805'; } /* '' */\n.icon-user:before { content: '\\e806'; } /* '' */\n.icon-users:before { content: '\\e807'; } /* '' */\n.icon-video:before { content: '\\e808'; } /* '' */\n.icon-videocam:before { content: '\\e809'; } /* '' */\n.icon-picture:before { content: '\\e80a'; } /* '' */\n.icon-th:before { content: '\\e80b'; } /* '' */\n.icon-th-list:before { content: '\\e80c'; } /* '' */\n.icon-ok:before { content: '\\e80d'; } /* '' */\n.icon-ok-circled:before { content: '\\e80e'; } /* '' */\n.icon-ok-circled2:before { content: '\\e80f'; } /* '' */\n.icon-cancel:before { content: '\\e810'; } /* '' */\n.icon-cancel-circled:before { content: '\\e811'; } /* '' */\n.icon-cancel-circled2:before { content: '\\e812'; } /* '' */\n.icon-plus:before { content: '\\e813'; } /* '' */\n.icon-plus-circled:before { content: '\\e814'; } /* '' */\n.icon-help-circled:before { content: '\\e815'; } /* '' */\n.icon-info-circled:before { content: '\\e816'; } /* '' */\n.icon-link:before { content: '\\e817'; } /* '' */\n.icon-mail:before { content: '\\e818'; } /* '' */\n.icon-camera:before { content: '\\e819'; } /* '' */\n.icon-camera-alt:before { content: '\\e81a'; } /* '' */\n.icon-th-large:before { content: '\\e81b'; } /* '' */\n.icon-minus:before { content: '\\e81c'; } /* '' */\n.icon-minus-circled:before { content: '\\e81d'; } /* '' */\n.icon-attach:before { content: '\\e81e'; } /* '' */\n.icon-lock:before { content: '\\e81f'; } /* '' */\n.icon-lock-open:before { content: '\\e820'; } /* '' */\n.icon-pin:before { content: '\\e821'; } /* '' */\n.icon-eye:before { content: '\\e822'; } /* '' */\n.icon-eye-off:before { content: '\\e823'; } /* '' */\n.icon-tag:before { content: '\\e824'; } /* '' */\n.icon-tags:before { content: '\\e825'; } /* '' */\n.icon-bookmark:before { content: '\\e826'; } /* '' */\n.icon-flag:before { content: '\\e827'; } /* '' */\n.icon-thumbs-up:before { content: '\\e828'; } /* '' */\n.icon-download:before { content: '\\e829'; } /* '' */\n.icon-upload:before { content: '\\e82a'; } /* '' */\n.icon-forward:before { content: '\\e82b'; } /* '' */\n.icon-export:before { content: '\\e82c'; } /* '' */\n.icon-pencil:before { content: '\\e82d'; } /* '' */\n.icon-edit:before { content: '\\e82e'; } /* '' */\n.icon-print:before { content: '\\e82f'; } /* '' */\n.icon-retweet:before { content: '\\e830'; } /* '' */\n.icon-comment:before { content: '\\e831'; } /* '' */\n.icon-chat:before { content: '\\e832'; } /* '' */\n.icon-bell:before { content: '\\e833'; } /* '' */\n.icon-attention:before { content: '\\e834'; } /* '' */\n.icon-attention-circled:before { content: '\\e835'; } /* '' */\n.icon-location:before { content: '\\e836'; } /* '' */\n.icon-trash-empty:before { content: '\\e837'; } /* '' */\n.icon-doc:before { content: '\\e838'; } /* '' */\n.icon-phone:before { content: '\\e839'; } /* '' */\n.icon-cog:before { content: '\\e83a'; } /* '' */\n.icon-cog-alt:before { content: '\\e83b'; } /* '' */\n.icon-music:before { content: '\\e83c'; } /* '' */\n.icon-heart:before { content: '\\e83d'; } /* '' */\n.icon-home:before { content: '\\e83e'; } /* '' */\n.icon-thumbs-down:before { content: '\\e83f'; } /* '' */\n.icon-wrench:before { content: '\\e840'; } /* '' */\n.icon-basket:before { content: '\\e841'; } /* '' */\n.icon-calendar:before { content: '\\e842'; } /* '' */\n.icon-volume-off:before { content: '\\e843'; } /* '' */\n.icon-volume-down:before { content: '\\e844'; } /* '' */\n.icon-volume-up:before { content: '\\e845'; } /* '' */\n.icon-headphones:before { content: '\\e846'; } /* '' */\n.icon-clock:before { content: '\\e847'; } /* '' */\n.icon-block:before { content: '\\e848'; } /* '' */\n.icon-resize-vertical:before { content: '\\e849'; } /* '' */\n.icon-resize-horizontal:before { content: '\\e84a'; } /* '' */\n.icon-zoom-in:before { content: '\\e84b'; } /* '' */\n.icon-zoom-out:before { content: '\\e84c'; } /* '' */\n.icon-down-circled2:before { content: '\\e84d'; } /* '' */\n.icon-up-circled2:before { content: '\\e84e'; } /* '' */\n.icon-down-dir:before { content: '\\e84f'; } /* '' */\n.icon-up-dir:before { content: '\\e850'; } /* '' */\n.icon-left-dir:before { content: '\\e851'; } /* '' */\n.icon-right-dir:before { content: '\\e852'; } /* '' */\n.icon-down-open:before { content: '\\e853'; } /* '' */\n.icon-right-open:before { content: '\\e854'; } /* '' */\n.icon-left-open:before { content: '\\e855'; } /* '' */\n.icon-resize-full:before { content: '\\e856'; } /* '' */\n.icon-resize-small:before { content: '\\e857'; } /* '' */\n.icon-login:before { content: '\\e858'; } /* '' */\n.icon-folder:before { content: '\\e859'; } /* '' */\n.icon-folder-open:before { content: '\\e85a'; } /* '' */\n.icon-logout:before { content: '\\e85b'; } /* '' */\n.icon-up-open:before { content: '\\e85c'; } /* '' */\n.icon-down-big:before { content: '\\e85d'; } /* '' */\n.icon-left-big:before { content: '\\e85e'; } /* '' */\n.icon-right-big:before { content: '\\e85f'; } /* '' */\n.icon-up-big:before { content: '\\e860'; } /* '' */\n.icon-right-hand:before { content: '\\e861'; } /* '' */\n.icon-left-hand:before { content: '\\e862'; } /* '' */\n.icon-up-hand:before { content: '\\e863'; } /* '' */\n.icon-down-hand:before { content: '\\e864'; } /* '' */\n.icon-cw:before { content: '\\e865'; } /* '' */\n.icon-ccw:before { content: '\\e866'; } /* '' */\n.icon-arrows-cw:before { content: '\\e867'; } /* '' */\n.icon-shuffle:before { content: '\\e868'; } /* '' */\n.icon-play:before { content: '\\e869'; } /* '' */\n.icon-play-circled2:before { content: '\\e86a'; } /* '' */\n.icon-stop:before { content: '\\e86b'; } /* '' */\n.icon-pause:before { content: '\\e86c'; } /* '' */\n.icon-to-end:before { content: '\\e86d'; } /* '' */\n.icon-to-end-alt:before { content: '\\e86e'; } /* '' */\n.icon-to-start:before { content: '\\e86f'; } /* '' */\n.icon-to-start-alt:before { content: '\\e870'; } /* '' */\n.icon-fast-fw:before { content: '\\e871'; } /* '' */\n.icon-fast-bw:before { content: '\\e872'; } /* '' */\n.icon-eject:before { content: '\\e873'; } /* '' */\n.icon-target:before { content: '\\e874'; } /* '' */\n.icon-signal:before { content: '\\e875'; } /* '' */\n.icon-award:before { content: '\\e876'; } /* '' */\n.icon-inbox:before { content: '\\e877'; } /* '' */\n.icon-globe:before { content: '\\e878'; } /* '' */\n.icon-cloud:before { content: '\\e879'; } /* '' */\n.icon-flash:before { content: '\\e87a'; } /* '' */\n.icon-umbrella:before { content: '\\e87b'; } /* '' */\n.icon-flight:before { content: '\\e87c'; } /* '' */\n.icon-leaf:before { content: '\\e87d'; } /* '' */\n.icon-font:before { content: '\\e87e'; } /* '' */\n.icon-bold:before { content: '\\e87f'; } /* '' */\n.icon-italic:before { content: '\\e880'; } /* '' */\n.icon-text-height:before { content: '\\e881'; } /* '' */\n.icon-text-width:before { content: '\\e882'; } /* '' */\n.icon-align-left:before { content: '\\e883'; } /* '' */\n.icon-align-center:before { content: '\\e884'; } /* '' */\n.icon-align-right:before { content: '\\e885'; } /* '' */\n.icon-align-justify:before { content: '\\e886'; } /* '' */\n.icon-list:before { content: '\\e887'; } /* '' */\n.icon-indent-left:before { content: '\\e888'; } /* '' */\n.icon-indent-right:before { content: '\\e889'; } /* '' */\n.icon-scissors:before { content: '\\e88a'; } /* '' */\n.icon-briefcase:before { content: '\\e88b'; } /* '' */\n.icon-off:before { content: '\\e88c'; } /* '' */\n.icon-road:before { content: '\\e88d'; } /* '' */\n.icon-list-alt:before { content: '\\e88e'; } /* '' */\n.icon-qrcode:before { content: '\\e88f'; } /* '' */\n.icon-barcode:before { content: '\\e890'; } /* '' */\n.icon-book:before { content: '\\e891'; } /* '' */\n.icon-adjust:before { content: '\\e892'; } /* '' */\n.icon-tint:before { content: '\\e893'; } /* '' */\n.icon-check:before { content: '\\e894'; } /* '' */\n.icon-asterisk:before { content: '\\e895'; } /* '' */\n.icon-gift:before { content: '\\e896'; } /* '' */\n.icon-fire:before { content: '\\e897'; } /* '' */\n.icon-magnet:before { content: '\\e898'; } /* '' */\n.icon-chart-bar:before { content: '\\e899'; } /* '' */\n.icon-credit-card:before { content: '\\e89a'; } /* '' */\n.icon-floppy:before { content: '\\e89b'; } /* '' */\n.icon-megaphone:before { content: '\\e89c'; } /* '' */\n.icon-key:before { content: '\\e89d'; } /* '' */\n.icon-truck:before { content: '\\e89e'; } /* '' */\n.icon-hammer:before { content: '\\e89f'; } /* '' */\n.icon-move:before { content: '\\f047'; } /* '' */\n.icon-link-ext:before { content: '\\f08e'; } /* '' */\n.icon-check-empty:before { content: '\\f096'; } /* '' */\n.icon-bookmark-empty:before { content: '\\f097'; } /* '' */\n.icon-phone-squared:before { content: '\\f098'; } /* '' */\n.icon-rss:before { content: '\\f09e'; } /* '' */\n.icon-hdd:before { content: '\\f0a0'; } /* '' */\n.icon-certificate:before { content: '\\f0a3'; } /* '' */\n.icon-left-circled:before { content: '\\f0a8'; } /* '' */\n.icon-right-circled:before { content: '\\f0a9'; } /* '' */\n.icon-up-circled:before { content: '\\f0aa'; } /* '' */\n.icon-down-circled:before { content: '\\f0ab'; } /* '' */\n.icon-tasks:before { content: '\\f0ae'; } /* '' */\n.icon-filter:before { content: '\\f0b0'; } /* '' */\n.icon-resize-full-alt:before { content: '\\f0b2'; } /* '' */\n.icon-beaker:before { content: '\\f0c3'; } /* '' */\n.icon-docs:before { content: '\\f0c5'; } /* '' */\n.icon-menu:before { content: '\\f0c9'; } /* '' */\n.icon-list-bullet:before { content: '\\f0ca'; } /* '' */\n.icon-list-numbered:before { content: '\\f0cb'; } /* '' */\n.icon-strike:before { content: '\\f0cc'; } /* '' */\n.icon-underline:before { content: '\\f0cd'; } /* '' */\n.icon-table:before { content: '\\f0ce'; } /* '' */\n.icon-magic:before { content: '\\f0d0'; } /* '' */\n.icon-money:before { content: '\\f0d6'; } /* '' */\n.icon-columns:before { content: '\\f0db'; } /* '' */\n.icon-sort:before { content: '\\f0dc'; } /* '' */\n.icon-sort-down:before { content: '\\f0dd'; } /* '' */\n.icon-sort-up:before { content: '\\f0de'; } /* '' */\n.icon-mail-alt:before { content: '\\f0e0'; } /* '' */\n.icon-gauge:before { content: '\\f0e4'; } /* '' */\n.icon-comment-empty:before { content: '\\f0e5'; } /* '' */\n.icon-chat-empty:before { content: '\\f0e6'; } /* '' */\n.icon-sitemap:before { content: '\\f0e8'; } /* '' */\n.icon-paste:before { content: '\\f0ea'; } /* '' */\n.icon-lightbulb:before { content: '\\f0eb'; } /* '' */\n.icon-exchange:before { content: '\\f0ec'; } /* '' */\n.icon-download-cloud:before { content: '\\f0ed'; } /* '' */\n.icon-upload-cloud:before { content: '\\f0ee'; } /* '' */\n.icon-user-md:before { content: '\\f0f0'; } /* '' */\n.icon-stethoscope:before { content: '\\f0f1'; } /* '' */\n.icon-suitcase:before { content: '\\f0f2'; } /* '' */\n.icon-bell-alt:before { content: '\\f0f3'; } /* '' */\n.icon-coffee:before { content: '\\f0f4'; } /* '' */\n.icon-food:before { content: '\\f0f5'; } /* '' */\n.icon-doc-text:before { content: '\\f0f6'; } /* '' */\n.icon-building:before { content: '\\f0f7'; } /* '' */\n.icon-hospital:before { content: '\\f0f8'; } /* '' */\n.icon-ambulance:before { content: '\\f0f9'; } /* '' */\n.icon-medkit:before { content: '\\f0fa'; } /* '' */\n.icon-fighter-jet:before { content: '\\f0fb'; } /* '' */\n.icon-beer:before { content: '\\f0fc'; } /* '' */\n.icon-h-sigh:before { content: '\\f0fd'; } /* '' */\n.icon-plus-squared:before { content: '\\f0fe'; } /* '' */\n.icon-angle-double-left:before { content: '\\f100'; } /* '' */\n.icon-angle-double-right:before { content: '\\f101'; } /* '' */\n.icon-angle-double-up:before { content: '\\f102'; } /* '' */\n.icon-angle-double-down:before { content: '\\f103'; } /* '' */\n.icon-angle-left:before { content: '\\f104'; } /* '' */\n.icon-angle-right:before { content: '\\f105'; } /* '' */\n.icon-angle-up:before { content: '\\f106'; } /* '' */\n.icon-angle-down:before { content: '\\f107'; } /* '' */\n.icon-desktop:before { content: '\\f108'; } /* '' */\n.icon-laptop:before { content: '\\f109'; } /* '' */\n.icon-tablet:before { content: '\\f10a'; } /* '' */\n.icon-mobile:before { content: '\\f10b'; } /* '' */\n.icon-circle-empty:before { content: '\\f10c'; } /* '' */\n.icon-quote-left:before { content: '\\f10d'; } /* '' */\n.icon-quote-right:before { content: '\\f10e'; } /* '' */\n.icon-spinner:before { content: '\\f110'; } /* '' */\n.icon-circle:before { content: '\\f111'; } /* '' */\n.icon-reply:before { content: '\\f112'; } /* '' */\n.icon-folder-empty:before { content: '\\f114'; } /* '' */\n.icon-folder-open-empty:before { content: '\\f115'; } /* '' */\n.icon-smile:before { content: '\\f118'; } /* '' */\n.icon-frown:before { content: '\\f119'; } /* '' */\n.icon-meh:before { content: '\\f11a'; } /* '' */\n.icon-gamepad:before { content: '\\f11b'; } /* '' */\n.icon-keyboard:before { content: '\\f11c'; } /* '' */\n.icon-flag-empty:before { content: '\\f11d'; } /* '' */\n.icon-flag-checkered:before { content: '\\f11e'; } /* '' */\n.icon-terminal:before { content: '\\f120'; } /* '' */\n.icon-code:before { content: '\\f121'; } /* '' */\n.icon-reply-all:before { content: '\\f122'; } /* '' */\n.icon-star-half-alt:before { content: '\\f123'; } /* '' */\n.icon-direction:before { content: '\\f124'; } /* '' */\n.icon-crop:before { content: '\\f125'; } /* '' */\n.icon-fork:before { content: '\\f126'; } /* '' */\n.icon-unlink:before { content: '\\f127'; } /* '' */\n.icon-help:before { content: '\\f128'; } /* '' */\n.icon-info:before { content: '\\f129'; } /* '' */\n.icon-attention-alt:before { content: '\\f12a'; } /* '' */\n.icon-superscript:before { content: '\\f12b'; } /* '' */\n.icon-subscript:before { content: '\\f12c'; } /* '' */\n.icon-eraser:before { content: '\\f12d'; } /* '' */\n.icon-puzzle:before { content: '\\f12e'; } /* '' */\n.icon-mic:before { content: '\\f130'; } /* '' */\n.icon-mute:before { content: '\\f131'; } /* '' */\n.icon-shield:before { content: '\\f132'; } /* '' */\n.icon-calendar-empty:before { content: '\\f133'; } /* '' */\n.icon-extinguisher:before { content: '\\f134'; } /* '' */\n.icon-rocket:before { content: '\\f135'; } /* '' */\n.icon-angle-circled-left:before { content: '\\f137'; } /* '' */\n.icon-angle-circled-right:before { content: '\\f138'; } /* '' */\n.icon-angle-circled-up:before { content: '\\f139'; } /* '' */\n.icon-angle-circled-down:before { content: '\\f13a'; } /* '' */\n.icon-anchor:before { content: '\\f13d'; } /* '' */\n.icon-lock-open-alt:before { content: '\\f13e'; } /* '' */\n.icon-bullseye:before { content: '\\f140'; } /* '' */\n.icon-ellipsis:before { content: '\\f141'; } /* '' */\n.icon-ellipsis-vert:before { content: '\\f142'; } /* '' */\n.icon-rss-squared:before { content: '\\f143'; } /* '' */\n.icon-play-circled:before { content: '\\f144'; } /* '' */\n.icon-ticket:before { content: '\\f145'; } /* '' */\n.icon-minus-squared:before { content: '\\f146'; } /* '' */\n.icon-minus-squared-alt:before { content: '\\f147'; } /* '' */\n.icon-level-up:before { content: '\\f148'; } /* '' */\n.icon-level-down:before { content: '\\f149'; } /* '' */\n.icon-ok-squared:before { content: '\\f14a'; } /* '' */\n.icon-pencil-squared:before { content: '\\f14b'; } /* '' */\n.icon-link-ext-alt:before { content: '\\f14c'; } /* '' */\n.icon-export-alt:before { content: '\\f14d'; } /* '' */\n.icon-compass:before { content: '\\f14e'; } /* '' */\n.icon-expand:before { content: '\\f150'; } /* '' */\n.icon-collapse:before { content: '\\f151'; } /* '' */\n.icon-expand-right:before { content: '\\f152'; } /* '' */\n.icon-euro:before { content: '\\f153'; } /* '' */\n.icon-pound:before { content: '\\f154'; } /* '' */\n.icon-dollar:before { content: '\\f155'; } /* '' */\n.icon-rupee:before { content: '\\f156'; } /* '' */\n.icon-yen:before { content: '\\f157'; } /* '' */\n.icon-rouble:before { content: '\\f158'; } /* '' */\n.icon-won:before { content: '\\f159'; } /* '' */\n.icon-doc-inv:before { content: '\\f15b'; } /* '' */\n.icon-doc-text-inv:before { content: '\\f15c'; } /* '' */\n.icon-sort-name-up:before { content: '\\f15d'; } /* '' */\n.icon-sort-name-down:before { content: '\\f15e'; } /* '' */\n.icon-sort-alt-up:before { content: '\\f160'; } /* '' */\n.icon-sort-alt-down:before { content: '\\f161'; } /* '' */\n.icon-sort-number-up:before { content: '\\f162'; } /* '' */\n.icon-sort-number-down:before { content: '\\f163'; } /* '' */\n.icon-thumbs-up-alt:before { content: '\\f164'; } /* '' */\n.icon-thumbs-down-alt:before { content: '\\f165'; } /* '' */\n.icon-down:before { content: '\\f175'; } /* '' */\n.icon-up:before { content: '\\f176'; } /* '' */\n.icon-left:before { content: '\\f177'; } /* '' */\n.icon-right:before { content: '\\f178'; } /* '' */\n.icon-female:before { content: '\\f182'; } /* '' */\n.icon-male:before { content: '\\f183'; } /* '' */\n.icon-sun:before { content: '\\f185'; } /* '' */\n.icon-moon:before { content: '\\f186'; } /* '' */\n.icon-box:before { content: '\\f187'; } /* '' */\n.icon-bug:before { content: '\\f188'; } /* '' */\n.icon-right-circled2:before { content: '\\f18e'; } /* '' */\n.icon-left-circled2:before { content: '\\f190'; } /* '' */\n.icon-collapse-left:before { content: '\\f191'; } /* '' */\n.icon-dot-circled:before { content: '\\f192'; } /* '' */\n.icon-wheelchair:before { content: '\\f193'; } /* '' */\n.icon-try:before { content: '\\f195'; } /* '' */\n.icon-plus-squared-alt:before { content: '\\f196'; } /* '' */\n.icon-space-shuttle:before { content: '\\f197'; } /* '' */\n.icon-mail-squared:before { content: '\\f199'; } /* '' */\n.icon-bank:before { content: '\\f19c'; } /* '' */\n.icon-graduation-cap:before { content: '\\f19d'; } /* '' */\n.icon-language:before { content: '\\f1ab'; } /* '' */\n.icon-fax:before { content: '\\f1ac'; } /* '' */\n.icon-building-filled:before { content: '\\f1ad'; } /* '' */\n.icon-child:before { content: '\\f1ae'; } /* '' */\n.icon-paw:before { content: '\\f1b0'; } /* '' */\n.icon-spoon:before { content: '\\f1b1'; } /* '' */\n.icon-cube:before { content: '\\f1b2'; } /* '' */\n.icon-cubes:before { content: '\\f1b3'; } /* '' */\n.icon-recycle:before { content: '\\f1b8'; } /* '' */\n.icon-cab:before { content: '\\f1b9'; } /* '' */\n.icon-taxi:before { content: '\\f1ba'; } /* '' */\n.icon-tree:before { content: '\\f1bb'; } /* '' */\n.icon-database:before { content: '\\f1c0'; } /* '' */\n.icon-file-pdf:before { content: '\\f1c1'; } /* '' */\n.icon-file-word:before { content: '\\f1c2'; } /* '' */\n.icon-file-excel:before { content: '\\f1c3'; } /* '' */\n.icon-file-powerpoint:before { content: '\\f1c4'; } /* '' */\n.icon-file-image:before { content: '\\f1c5'; } /* '' */\n.icon-file-archive:before { content: '\\f1c6'; } /* '' */\n.icon-file-audio:before { content: '\\f1c7'; } /* '' */\n.icon-file-video:before { content: '\\f1c8'; } /* '' */\n.icon-file-code:before { content: '\\f1c9'; } /* '' */\n.icon-lifebuoy:before { content: '\\f1cd'; } /* '' */\n.icon-circle-notch:before { content: '\\f1ce'; } /* '' */\n.icon-rebel:before { content: '\\f1d0'; } /* '' */\n.icon-empire:before { content: '\\f1d1'; } /* '' */\n.icon-paper-plane:before { content: '\\f1d8'; } /* '' */\n.icon-paper-plane-empty:before { content: '\\f1d9'; } /* '' */\n.icon-history:before { content: '\\f1da'; } /* '' */\n.icon-circle-thin:before { content: '\\f1db'; } /* '' */\n.icon-header:before { content: '\\f1dc'; } /* '' */\n.icon-paragraph:before { content: '\\f1dd'; } /* '' */\n.icon-sliders:before { content: '\\f1de'; } /* '' */\n.icon-share:before { content: '\\f1e0'; } /* '' */\n.icon-share-squared:before { content: '\\f1e1'; } /* '' */\n.icon-bomb:before { content: '\\f1e2'; } /* '' */\n.icon-soccer-ball:before { content: '\\f1e3'; } /* '' */\n.icon-tty:before { content: '\\f1e4'; } /* '' */\n.icon-binoculars:before { content: '\\f1e5'; } /* '' */\n.icon-plug:before { content: '\\f1e6'; } /* '' */\n.icon-newspaper:before { content: '\\f1ea'; } /* '' */\n.icon-wifi:before { content: '\\f1eb'; } /* '' */\n.icon-calc:before { content: '\\f1ec'; } /* '' */\n.icon-bell-off:before { content: '\\f1f6'; } /* '' */\n.icon-bell-off-empty:before { content: '\\f1f7'; } /* '' */\n.icon-trash:before { content: '\\f1f8'; } /* '' */\n.icon-copyright:before { content: '\\f1f9'; } /* '' */\n.icon-at:before { content: '\\f1fa'; } /* '' */\n.icon-eyedropper:before { content: '\\f1fb'; } /* '' */\n.icon-brush:before { content: '\\f1fc'; } /* '' */\n.icon-birthday:before { content: '\\f1fd'; } /* '' */\n.icon-chart-area:before { content: '\\f1fe'; } /* '' */\n.icon-chart-pie:before { content: '\\f200'; } /* '' */\n.icon-chart-line:before { content: '\\f201'; } /* '' */\n.icon-toggle-off:before { content: '\\f204'; } /* '' */\n.icon-toggle-on:before { content: '\\f205'; } /* '' */\n.icon-bicycle:before { content: '\\f206'; } /* '' */\n.icon-bus:before { content: '\\f207'; } /* '' */\n.icon-shekel:before { content: '\\f20b'; } /* '' */\n.icon-cart-plus:before { content: '\\f217'; } /* '' */\n.icon-cart-arrow-down:before { content: '\\f218'; } /* '' */\n.icon-diamond:before { content: '\\f219'; } /* '' */\n.icon-ship:before { content: '\\f21a'; } /* '' */\n.icon-user-secret:before { content: '\\f21b'; } /* '' */\n.icon-motorcycle:before { content: '\\f21c'; } /* '' */\n.icon-street-view:before { content: '\\f21d'; } /* '' */\n.icon-heartbeat:before { content: '\\f21e'; } /* '' */\n.icon-venus:before { content: '\\f221'; } /* '' */\n.icon-mars:before { content: '\\f222'; } /* '' */\n.icon-mercury:before { content: '\\f223'; } /* '' */\n.icon-transgender:before { content: '\\f224'; } /* '' */\n.icon-transgender-alt:before { content: '\\f225'; } /* '' */\n.icon-venus-double:before { content: '\\f226'; } /* '' */\n.icon-mars-double:before { content: '\\f227'; } /* '' */\n.icon-venus-mars:before { content: '\\f228'; } /* '' */\n.icon-mars-stroke:before { content: '\\f229'; } /* '' */\n.icon-mars-stroke-v:before { content: '\\f22a'; } /* '' */\n.icon-mars-stroke-h:before { content: '\\f22b'; } /* '' */\n.icon-neuter:before { content: '\\f22c'; } /* '' */\n.icon-server:before { content: '\\f233'; } /* '' */\n.icon-user-plus:before { content: '\\f234'; } /* '' */\n.icon-user-times:before { content: '\\f235'; } /* '' */\n.icon-bed:before { content: '\\f236'; } /* '' */\n.icon-viacoin:before { content: '\\f237'; } /* '' */\n.icon-train:before { content: '\\f238'; } /* '' */\n.icon-subway:before { content: '\\f239'; } /* '' */\n.icon-medium:before { content: '\\f23a'; } /* '' */\n\n.pick-a-color-markup *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n.pick-a-color-markup .hex-pound{padding-left:8px;padding-right:8px}@media screen and (max-width:991px){.pick-a-color-markup .hex-pound{padding:3px 5px 0px 5px;min-height:30px}}\n.pick-a-color-markup .pick-a-color{padding:5px}@media screen and (max-width:991px){.pick-a-color-markup .pick-a-color{width:100%;font-size:18px;padding:9px;min-width:222px;height:47px}}\n.pick-a-color-markup .input-group-btn .color-dropdown{padding:6px 5px}.pick-a-color-markup .input-group-btn .color-dropdown.no-hex{border-bottom-left-radius:4px;border-top-left-radius:4px}\n.pick-a-color-markup .input-group-btn .color-dropdown:focus{background-color:#fff}\n@media screen and (max-width:991px){.pick-a-color-markup .input-group-btn .color-dropdown{height:47px}}\n.pick-a-color-markup .color-preview{border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 0 2px 2px rgba(0,0,0,0.075);box-shadow:inset 0 0 2px 2px rgba(0,0,0,0.075);height:1.429em;width:1.429em;display:inline-block;cursor:pointer;margin-right:5px}.pick-a-color-markup .color-preview.current-color{margin-bottom:-5px}\n@media screen and (max-width:991px){.pick-a-color-markup .color-preview{height:1.875em;width:1.875em}}\n.pick-a-color-markup .color-menu{text-align:left;padding:5px 0px;width:330px;font-size:14px;left:auto;}.pick-a-color-markup .color-menu.color-menu--inline{left:-285px}@media screen and (max-width:991px){.pick-a-color-markup .color-menu.color-menu--inline{left:-242px}}\n@media screen and (max-width:991px){.pick-a-color-markup .color-menu{left:-242px;width:293px}}.pick-a-color-markup .color-menu.small{width:100px}@media screen and (max-width:991px){.pick-a-color-markup .color-menu.small{left:-105px}}\n.pick-a-color-markup .color-menu.no-hex{left:0px}\n.pick-a-color-markup .color-menu ul{padding:0px;margin:0px}\n.pick-a-color-markup .color-menu li{list-style-type:none;padding:5px 0px;margin:0px}\n.pick-a-color-markup .color-menu .color-preview{vertical-align:middle;margin:0px}@media screen and (max-width:991px){.pick-a-color-markup .color-menu .color-preview{height:35px;width:35px}}.pick-a-color-markup .color-menu .color-preview.current-color,.pick-a-color-markup .color-menu .color-preview.white{background-color:#fff}\n.pick-a-color-markup .color-menu .color-preview.red{background-color:#f00}\n.pick-a-color-markup .color-menu .color-preview.orange{background-color:#f60}\n.pick-a-color-markup .color-menu .color-preview.yellow{background-color:#ff0}\n.pick-a-color-markup .color-menu .color-preview.green{background-color:#008000}\n.pick-a-color-markup .color-menu .color-preview.blue{background-color:#00f}\n.pick-a-color-markup .color-menu .color-preview.indigo{background-color:#4a0080}\n.pick-a-color-markup .color-menu .color-preview.violet{background-color:#ee81ee}\n.pick-a-color-markup .color-menu .color-preview.purple{background-color:#80007f}\n.pick-a-color-markup .color-menu .color-preview.black{background-color:#000}\n.pick-a-color-markup .color-menu .basicColors-content li>a,.pick-a-color-markup .color-menu .savedColors-content li>a{padding:5px 15px 3px 15px;cursor:default;min-height:25px;color:#333}.pick-a-color-markup .color-menu .basicColors-content li>a:hover,.pick-a-color-markup .color-menu .savedColors-content li>a:hover{background-color:#fff}\n@media screen and (max-width:991px){.pick-a-color-markup .color-menu .basicColors-content li>a,.pick-a-color-markup .color-menu .savedColors-content li>a{min-height:40px}}\n.pick-a-color-markup .color-menu .basicColors-content li:hover a,.pick-a-color-markup .color-menu .savedColors-content li:hover a{color:#333;background-image:none;filter:none;text-decoration:none;font-weight:bold}@media screen and (max-width:991px){.pick-a-color-markup .color-menu .basicColors-content li:hover a,.pick-a-color-markup .color-menu .savedColors-content li:hover a{background-color:#fff;font-weight:normal}}\n.pick-a-color-markup .color-menu .btn.color-select{margin:0px 5px;height:20px;padding:0px 5px;margin-top:0px;line-height:1.5px;border-radius:4px}@media screen and (max-width:991px){.pick-a-color-markup .color-menu .btn.color-select{height:35px}}\n.pick-a-color-markup .caret{margin-bottom:3px}\n.pick-a-color-markup .color-menu-instructions,.pick-a-color-markup .advanced-instructions{text-align:center;padding:0px 6px;margin:0px;font-size:14px;font-weight:normal}@media screen and (min-width:992px){.pick-a-color-markup .color-menu-instructions,.pick-a-color-markup .advanced-instructions{display:none}}\n.pick-a-color-markup .color-label{vertical-align:middle;margin:0px;margin-left:10px;cursor:pointer}@media screen and (max-width:991px){.pick-a-color-markup .color-label{margin-left:8px}}\n.pick-a-color-markup .color-box{height:20px;width:200px;position:absolute;left:115px;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 0 2px 2px rgba(0,0,0,0.075);box-shadow:inset 0 0 2px 2px rgba(0,0,0,0.075);cursor:pointer}@media screen and (max-width:991px){.pick-a-color-markup .color-box{width:160px;height:35px}}\n.pick-a-color-markup .black .highlight-band-stripe{background-color:#fff}\n.pick-a-color-markup .spectrum-white{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#fff), to(#808080));background-image:-webkit-linear-gradient(left, color-stop(#fff 0), color-stop(#808080 100%));background-image:-moz-linear-gradient(left, #fff 0, #808080 100%);background-image:linear-gradient(to right, #fff 0, #808080 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ff808080', GradientType=1)}.pick-a-color-markup .spectrum-white .highlight-band{left:0px}\n.pick-a-color-markup .spectrum-red{background-image:-webkit-gradient(linear, left top, right top, color-stop(0, #fff), color-stop(.5, #f00), color-stop(1, #000));background-image:-moz-linear-gradient(left center, #fff 0, #f00 50%, #000 100%);background-image:-webkit-linear-gradient(left, #fff 0, #f00 50%, #000 100%);background-image:-o-linear-gradient(left, #fff 0, #f00 50%, #000 100%);background-image:linear-gradient(to right, #fff 0, #f00 50%, #000 100%);background-repeat:repeat-x}\n.pick-a-color-markup .spectrum-orange{background-image:-webkit-gradient(linear, left top, right top, color-stop(0, #fff), color-stop(.5, #f60), color-stop(1, #000));background-image:-moz-linear-gradient(left center, #fff 0, #f60 50%, #000 100%);background-image:-webkit-linear-gradient(left, #fff 0, #f60 50%, #000 100%);background-image:-o-linear-gradient(left, #fff 0, #f60 50%, #000 100%);background-image:linear-gradient(to right, #fff 0, #f60 50%, #000 100%);background-repeat:repeat-x}\n.pick-a-color-markup .spectrum-yellow{background-image:-webkit-gradient(linear, left top, right top, color-stop(0, #fff), color-stop(.5, #ff0), color-stop(1, #000));background-image:-moz-linear-gradient(left center, #fff 0, #ff0 50%, #000 100%);background-image:-webkit-linear-gradient(left, #fff 0, #ff0 50%, #000 100%);background-image:-o-linear-gradient(left, #fff 0, #ff0 50%, #000 100%);background-image:linear-gradient(to right, #fff 0, #ff0 50%, #000 100%);background-repeat:repeat-x}\n.pick-a-color-markup .spectrum-green{background-image:-webkit-gradient(linear, left top, right top, color-stop(0, #80ff80), color-stop(.5, #008000), color-stop(1, #000));background-image:-moz-linear-gradient(left center, #80ff80 0, #008000 50%, #000 100%);background-image:-webkit-linear-gradient(left, #80ff80 0, #008000 50%, #000 100%);background-image:-o-linear-gradient(left, #80ff80 0, #008000 50%, #000 100%);background-image:linear-gradient(to right, #80ff80 0, #008000 50%, #000 100%);background-repeat:repeat-x}\n.pick-a-color-markup .spectrum-blue{background-image:-webkit-gradient(linear, left top, right top, color-stop(0, #fff), color-stop(.5, #00f), color-stop(1, #000));background-image:-moz-linear-gradient(left center, #fff 0, #00f 50%, #000 100%);background-image:-webkit-linear-gradient(left, #fff 0, #00f 50%, #000 100%);background-image:-o-linear-gradient(left, #fff 0, #00f 50%, #000 100%);background-image:linear-gradient(to right, #fff 0, #00f 50%, #000 100%);background-repeat:repeat-x}\n.pick-a-color-markup .spectrum-purple{background-image:-webkit-gradient(linear, left top, right top, color-stop(0, #ff80ff), color-stop(.5, #80007f), color-stop(1, #000));background-image:-moz-linear-gradient(left center, #ff80ff 0, #80007f 50%, #000 100%);background-image:-webkit-linear-gradient(left, #ff80ff 0, #80007f 50%, #000 100%);background-image:-o-linear-gradient(left, #ff80ff 0, #80007f 50%, #000 100%);background-image:linear-gradient(to right, #ff80ff 0, #80007f 50%, #000 100%);background-repeat:repeat-x}\n.pick-a-color-markup .spectrum-black{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#000), to(#808080));background-image:-webkit-linear-gradient(left, color-stop(#000 0), color-stop(#808080 100%));background-image:-moz-linear-gradient(left, #000 0, #808080 100%);background-image:linear-gradient(to right, #000 0, #808080 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff000000', endColorstr='#ff808080', GradientType=1)}.pick-a-color-markup .spectrum-black .highlight-band{left:0px;border:1px solid #808080}\n.pick-a-color-markup .ie-spectrum{height:20px;width:100px;display:inline-block;top:-1}.pick-a-color-markup .ie-spectrum.hue{width:50.5px}@media screen and (max-width:991px){.pick-a-color-markup .ie-spectrum.hue{width:45.5px}}\n@media screen and (max-width:991px){.pick-a-color-markup .ie-spectrum{width:80px;height:35px}}\n.pick-a-color-markup .red-spectrum-0,.pick-a-color-markup .lightness-spectrum-0{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#fff), to(#f00));background-image:-webkit-linear-gradient(left, color-stop(#fff 0), color-stop(#f00 100%));background-image:-moz-linear-gradient(left, #fff 0, #f00 100%);background-image:linear-gradient(to right, #fff 0, #f00 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffff0000', GradientType=1);border-bottom-left-radius:4px;border-top-left-radius:4px}\n.pick-a-color-markup .red-spectrum-1,.pick-a-color-markup .lightness-spectrum-1{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#f00), to(#000));background-image:-webkit-linear-gradient(left, color-stop(#f00 0), color-stop(#000 100%));background-image:-moz-linear-gradient(left, #f00 0, #000 100%);background-image:linear-gradient(to right, #f00 0, #000 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff0000', endColorstr='#ff000000', GradientType=1);border-bottom-right-radius:4px;border-top-right-radius:4px}\n.pick-a-color-markup .lightness-spectrum-0,.pick-a-color-markup .lightness-spectrum-1{width:150px}@media screen and (max-width:991px){.pick-a-color-markup .lightness-spectrum-0,.pick-a-color-markup .lightness-spectrum-1{width:135px}}\n.pick-a-color-markup .orange-spectrum-0{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#fff), to(#f60));background-image:-webkit-linear-gradient(left, color-stop(#fff 0), color-stop(#f60 100%));background-image:-moz-linear-gradient(left, #fff 0, #f60 100%);background-image:linear-gradient(to right, #fff 0, #f60 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffff6600', GradientType=1);border-bottom-left-radius:4px;border-top-left-radius:4px}\n.pick-a-color-markup .orange-spectrum-1{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#f60), to(#000));background-image:-webkit-linear-gradient(left, color-stop(#f60 0), color-stop(#000 100%));background-image:-moz-linear-gradient(left, #f60 0, #000 100%);background-image:linear-gradient(to right, #f60 0, #000 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff6600', endColorstr='#ff000000', GradientType=1);border-bottom-right-radius:4px;border-top-right-radius:4px}\n.pick-a-color-markup .yellow-spectrum-0{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#fff), to(#ff0));background-image:-webkit-linear-gradient(left, color-stop(#fff 0), color-stop(#ff0 100%));background-image:-moz-linear-gradient(left, #fff 0, #ff0 100%);background-image:linear-gradient(to right, #fff 0, #ff0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffffff00', GradientType=1);border-bottom-left-radius:4px;border-top-left-radius:4px}\n.pick-a-color-markup .yellow-spectrum-1{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#ff0), to(#000));background-image:-webkit-linear-gradient(left, color-stop(#ff0 0), color-stop(#000 100%));background-image:-moz-linear-gradient(left, #ff0 0, #000 100%);background-image:linear-gradient(to right, #ff0 0, #000 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff00', endColorstr='#ff000000', GradientType=1);border-bottom-right-radius:4px;border-top-right-radius:4px}\n.pick-a-color-markup .green-spectrum-0{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#80ff80), to(#008000));background-image:-webkit-linear-gradient(left, color-stop(#80ff80 0), color-stop(#008000 100%));background-image:-moz-linear-gradient(left, #80ff80 0, #008000 100%);background-image:linear-gradient(to right, #80ff80 0, #008000 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff80ff80', endColorstr='#ff008000', GradientType=1);border-bottom-left-radius:4px;border-top-left-radius:4px}\n.pick-a-color-markup .green-spectrum-1{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#008000), to(#000));background-image:-webkit-linear-gradient(left, color-stop(#008000 0), color-stop(#000 100%));background-image:-moz-linear-gradient(left, #008000 0, #000 100%);background-image:linear-gradient(to right, #008000 0, #000 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff008000', endColorstr='#ff000000', GradientType=1);border-bottom-right-radius:4px;border-top-right-radius:4px}\n.pick-a-color-markup .blue-spectrum-0{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#fff), to(#00f));background-image:-webkit-linear-gradient(left, color-stop(#fff 0), color-stop(#00f 100%));background-image:-moz-linear-gradient(left, #fff 0, #00f 100%);background-image:linear-gradient(to right, #fff 0, #00f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ff0000ff', GradientType=1);border-bottom-left-radius:4px;border-top-left-radius:4px}\n.pick-a-color-markup .blue-spectrum-1{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#00f), to(#000));background-image:-webkit-linear-gradient(left, color-stop(#00f 0), color-stop(#000 100%));background-image:-moz-linear-gradient(left, #00f 0, #000 100%);background-image:linear-gradient(to right, #00f 0, #000 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000ff', endColorstr='#ff000000', GradientType=1);border-bottom-right-radius:4px;border-top-right-radius:4px}\n.pick-a-color-markup .purple-spectrum-0{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#ff80ff), to(#80007f));background-image:-webkit-linear-gradient(left, color-stop(#ff80ff 0), color-stop(#80007f 100%));background-image:-moz-linear-gradient(left, #ff80ff 0, #80007f 100%);background-image:linear-gradient(to right, #ff80ff 0, #80007f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff80ff', endColorstr='#ff80007f', GradientType=1);border-bottom-left-radius:4px;border-top-left-radius:4px}\n.pick-a-color-markup .purple-spectrum-1{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#80007f), to(#000));background-image:-webkit-linear-gradient(left, color-stop(#80007f 0), color-stop(#000 100%));background-image:-moz-linear-gradient(left, #80007f 0, #000 100%);background-image:linear-gradient(to right, #80007f 0, #000 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff80007f', endColorstr='#ff000000', GradientType=1);border-bottom-right-radius:4px;border-top-right-radius:4px}\n.pick-a-color-markup .saturation-spectrum-0{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#808080), to(#bf4040));background-image:-webkit-linear-gradient(left, color-stop(#808080 0), color-stop(#bf4040 100%));background-image:-moz-linear-gradient(left, #808080 0, #bf4040 100%);background-image:linear-gradient(to right, #808080 0, #bf4040 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff808080', endColorstr='#ffbf4040', GradientType=1);border-bottom-left-radius:4px;border-top-left-radius:4px;width:150px}@media screen and (max-width:991px){.pick-a-color-markup .saturation-spectrum-0{width:135px}}\n.pick-a-color-markup .saturation-spectrum-1{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#bf4040), to(#f00));background-image:-webkit-linear-gradient(left, color-stop(#bf4040 0), color-stop(#f00 100%));background-image:-moz-linear-gradient(left, #bf4040 0, #f00 100%);background-image:linear-gradient(to right, #bf4040 0, #f00 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffbf4040', endColorstr='#ffff0000', GradientType=1);border-bottom-right-radius:4px;border-top-right-radius:4px;width:150px}@media screen and (max-width:991px){.pick-a-color-markup .saturation-spectrum-1{width:135px}}\n.pick-a-color-markup .hue-spectrum-0{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#f00), to(#ff0));background-image:-webkit-linear-gradient(left, color-stop(#f00 0), color-stop(#ff0 100%));background-image:-moz-linear-gradient(left, #f00 0, #ff0 100%);background-image:linear-gradient(to right, #f00 0, #ff0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff0000', endColorstr='#ffffff00', GradientType=1)}\n.pick-a-color-markup .hue-spectrum-1{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#ff0), to(#0f0));background-image:-webkit-linear-gradient(left, color-stop(#ff0 0), color-stop(#0f0 100%));background-image:-moz-linear-gradient(left, #ff0 0, #0f0 100%);background-image:linear-gradient(to right, #ff0 0, #0f0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff00', endColorstr='#ff00ff00', GradientType=1)}\n.pick-a-color-markup .hue-spectrum-2{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#0f0), to(#0ff));background-image:-webkit-linear-gradient(left, color-stop(#0f0 0), color-stop(#0ff 100%));background-image:-moz-linear-gradient(left, #0f0 0, #0ff 100%);background-image:linear-gradient(to right, #0f0 0, #0ff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff00', endColorstr='#ff00ffff', GradientType=1);left:-1px;position:relative}\n.pick-a-color-markup .hue-spectrum-3{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#0ff), to(#00f));background-image:-webkit-linear-gradient(left, color-stop(#0ff 0), color-stop(#00f 100%));background-image:-moz-linear-gradient(left, #0ff 0, #00f 100%);background-image:linear-gradient(to right, #0ff 0, #00f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ffff', endColorstr='#ff0000ff', GradientType=1);left:-1px;position:relative}\n.pick-a-color-markup .hue-spectrum-4{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#00f), to(#f0f));background-image:-webkit-linear-gradient(left, color-stop(#00f 0), color-stop(#f0f 100%));background-image:-moz-linear-gradient(left, #00f 0, #f0f 100%);background-image:linear-gradient(to right, #00f 0, #f0f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000ff', endColorstr='#ffff00ff', GradientType=1);left:-1px;position:relative}\n.pick-a-color-markup .hue-spectrum-5{background-image:-webkit-gradient(linear, 0 top, 100% top, from(#f0f), to(#f00));background-image:-webkit-linear-gradient(left, color-stop(#f0f 0), color-stop(#f00 100%));background-image:-moz-linear-gradient(left, #f0f 0, #f00 100%);background-image:linear-gradient(to right, #f0f 0, #f00 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00ff', endColorstr='#ffff0000', GradientType=1);left:-2px;position:relative}\n.pick-a-color-markup .highlight-band{border:1px solid #222;border-radius:2px;-webkit-box-shadow:1px 1px 1px #333;box-shadow:1px 1px 1px #333;height:19px;width:11px;display:inline-block;cursor:pointer;cursor:-webkit-grab;cursor:-moz-grab;position:absolute;top:-1px;left:94.5px;text-align:center}@media screen and (max-width:991px){.pick-a-color-markup .highlight-band{width:21px;left:69.5px;height:34px}}\n.pick-a-color-markup .highlight-band-stripe{min-height:80%;min-width:1px;background-color:#000;opacity:0.40;margin:2px 1px;display:inline-block;-webkit-box-shadow:1px 0 2px 0 #fff;box-shadow:1px 0 2px 0 #fff}@media screen and (max-width:991px){.pick-a-color-markup .highlight-band-stripe{margin:4px 2px}}\n.pick-a-color-markup .color-menu-tabs{padding:5px 3px 3px 10px;font-size:12px;color:#333;border-bottom:1px solid #ccc;margin-bottom:5px}.pick-a-color-markup .color-menu-tabs .tab{padding:4px 5px;margin:5px;border-left:1px solid #fff;border-right:1px solid #fff;cursor:pointer;background-color:#fff}.pick-a-color-markup .color-menu-tabs .tab:hover{padding-bottom:6px;border-top:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;border-top-right-radius:4px;border-top-left-radius:4px}\n.pick-a-color-markup .color-menu-tabs a{color:#333;text-decoration:none}\n.pick-a-color-markup .color-menu-tabs .tab-active{border-bottom:3px solid #fff;padding-bottom:5px;border-top:1px solid #ccc;border-right:1px solid #ccc;border-left:1px solid #ccc;border-top-right-radius:4px;border-top-left-radius:4px}\n.pick-a-color-markup .active-content{display:block}\n.pick-a-color-markup .inactive-content{display:none}\n.pick-a-color-markup .savedColors-content{padding:5px 15px;white-space:normal}.pick-a-color-markup .savedColors-content li.color-item>a{margin-left:7px;padding-left:8px;border-radius:4px}\n.pick-a-color-markup .saved-color-col{position:relative;left:-15px;float:left;width:149px}@media screen and (max-width:991px){.pick-a-color-markup .saved-color-col{width:130px}}\n.pick-a-color-markup .advanced-content ul{margin-top:10px}\n.pick-a-color-markup .advanced-content li{padding:5px 15px 3px 15px;cursor:default;min-height:25px;height:50px;position:relative}@media screen and (max-width:991px){.pick-a-color-markup .advanced-content li{min-height:70px}}\n.pick-a-color-markup .advanced-content .color-preview{height:50px;width:300px;float:left;margin:0px 0px 10px 0px;background-color:#f00;text-align:center}.pick-a-color-markup .advanced-content .color-preview .color-select.btn.advanced{margin-top:15px;display:none}@media screen and (max-width:991px){.pick-a-color-markup .advanced-content .color-preview .color-select.btn.advanced{display:inline;margin-top:7px}}\n.pick-a-color-markup .advanced-content .color-preview:hover .color-select.btn.advanced{display:inline}\n@media screen and (max-width:991px){.pick-a-color-markup .advanced-content .color-preview{width:270px;margin-left:-10px}}\n.pick-a-color-markup .advanced-content .spectrum-hue{background-image:-webkit-gradient(linear, left top, right top, color-stop(0, #f00), color-stop(17%, #ff0), color-stop(34%, #0f0), color-stop(51%, #0ff), color-stop(68%, #00f), color-stop(85%, #f0f), color-stop(100%, #f00));background-image:-moz-linear-gradient(left center, #f00 0, #ff0 17%, #0f0 24%, #0ff 51%, #00f 68%, #f0f 85%, #f00 100%);background-image:-webkit-linear-gradient(left, #f00 0, #ff0 17%, #0f0 24%, #0ff 51%, #00f 68%, #f0f 85%, #f00 100%);background-image:-o-linear-gradient(left, #f00 0, #ff0 17%, #0f0 24%, #0ff 51%, #00f 68%, #f0f 85%, #f00 100%);background-image:linear-gradient(to right, #f00 0, #ff0 17%, #0f0 24%, #0ff 51%, #00f 68%, #f0f 85%, #f00 100%);background-repeat:repeat-x}.pick-a-color-markup .advanced-content .spectrum-hue .highlight-band{left:0px}\n.pick-a-color-markup .advanced-content .spectrum-lightness{background-image:-webkit-gradient(linear, left top, right top, color-stop(0, #fff), color-stop(.5, #f00), color-stop(1, #000));background-image:-moz-linear-gradient(left center, #fff 0, #f00 50%, #000 100%);background-image:-webkit-linear-gradient(left, #fff 0, #f00 50%, #000 100%);background-image:-o-linear-gradient(left, #fff 0, #f00 50%, #000 100%);background-image:linear-gradient(to right, #fff 0, #f00 50%, #000 100%);background-repeat:repeat-x}\n.pick-a-color-markup .advanced-content .spectrum-saturation{background-image:-webkit-gradient(linear, left top, right top, color-stop(0, #808080), color-stop(.5, #f00), color-stop(1, #f00));background-image:-moz-linear-gradient(left center, #808080 0, #f00 50%, #f00 100%);background-image:-webkit-linear-gradient(left, #808080 0, #f00 50%, #f00 100%);background-image:-o-linear-gradient(left, #808080 0, #f00 50%, #f00 100%);background-image:linear-gradient(to right, #808080 0, #f00 50%, #f00 100%);background-repeat:repeat-x}.pick-a-color-markup .advanced-content .spectrum-saturation .highlight-band{left:287px}@media screen and (max-width:991px){.pick-a-color-markup .advanced-content .spectrum-saturation .highlight-band{left:247px}}\n.pick-a-color-markup .advanced-content .spectrum-lightness .highlight-band{left:143.5px}@media screen and (max-width:991px){.pick-a-color-markup .advanced-content .spectrum-lightness .highlight-band{left:123.5px}}\n.pick-a-color-markup .advanced-content .lightness-text,.pick-a-color-markup .advanced-content .hue-text,.pick-a-color-markup .advanced-content .saturation-text,.pick-a-color-markup .advanced-content .preview-text{vertical-align:middle;text-align:center;display:block}\n.pick-a-color-markup .advanced-content .color-box{left:15px;top:25px;width:300px}@media screen and (max-width:991px){.pick-a-color-markup .advanced-content .color-box{width:270px;left:10px}}\n.pick-a-color-markup .advanced-content .preview-item{height:80px}\n@-moz-document url-prefix(){@media screen and (max-width:991px){div.pick-a-color-markup .color-menu{left:0px}}}\n\n.rte_toolBar .rte-custom-icon > span,\n.rte_toolBar .rte-custom-icon > span:after {\n height: 19px;\n width: 16px;\n display: inline-block;\n margin-bottom: -4px;\n}\n\n.icon-textNumbered, .icon-textNumbered:after {\n content: url(\"../../rte/gui/components/clientlibs/core/resources/List_ordered.svg\");\n}\n\n.icon-textLetteredUppercase, .icon-textLetteredUppercase:after {\n content: url(\"../../rte/gui/components/clientlibs/core/resources/List_caps_a.svg\");\n}\n\n.icon-textLetteredLowercase, .icon-textLetteredLowercase:after {\n content: url(\"../../rte/gui/components/clientlibs/core/resources/List_a.svg\");\n}\n\n.icon-textRomanUppercase, .icon-textRomanUppercase:after {\n content: url(\"../../rte/gui/components/clientlibs/core/resources/List_caps_i.svg\");\n}\n\n.icon-textRomanLowercase, .icon-textRomanLowercase:after {\n content: url(\"../../rte/gui/components/clientlibs/core/resources/List_i.svg\");\n}\n\n.rte_toolBar{\n all: initial;\n position: absolute;\n display: none;\n -webkit-box-shadow: 0 2px 6px 0 rgba(0,0,0,0.15);\n -moz-box-shadow: 0 2px 6px 0 rgba(0,0,0,0.15);\n box-shadow: 0 2px 6px 0 rgba(0,0,0,0.15);\n background-color: white;\n font-family: Helvetica,Arial,sans-serif;\n}\n\n.forms-richTextEditor.rte-mode-full {\n position: fixed;\n display: flex;\n flex-direction: column;\n top: 10vh;\n left: 10vw;\n background-color: #FFFFFF;\n width: 80vw;\n height: 80vh;\n z-index: 99999;\n border: 1px solid rgba(0,0,0,0.1);\n border-radius: 4px;\n -webkit-box-shadow: 0 4px 20px 0 rgba(0,0,0,0.2);\n -moz-box-shadow: 0 4px 20px 0 rgba(0,0,0,0.2);\n box-shadow: 0 4px 20px 0 rgba(0,0,0,0.2);\n}\n\n.forms-richTextEditor.rte-mode-full .rte_toolBar {\n display: block !important;\n flex: 0 1 auto;\n position: relative;\n top: auto !important;\n left: auto !important;\n background-color: rgb(240,240,240);\n box-shadow: none;\n}\n\n.forms-richTextEditor.rte-mode-basic .rte_toolBar {\n display: inline-block;\n z-index: 10000;\n}\n\n.forms-richTextEditor .wysihtml5-editor {\n overflow: auto;\n}\n.forms-richTextEditor.rte-mode-full .wysihtml5-editor {\n padding: 1rem !important;\n width: calc(100% - 2rem) !important;\n height: calc(100% - 3.3rem) !important;\n border: none !important;\n position: relative !important;\n top: 0 !important;\n left: 0 !important;\n flex: 1 1 auto;\n}\n\n.rte_toolBar .popover {\n margin: 0;\n padding: 0;\n border: 1px solid rgb(200, 200, 200);\n border-radius: 0.25rem;\n background-color: white;\n max-width: none;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1010;\n display: none;\n text-align: left;\n background-clip: padding-box;\n white-space: normal;\n box-shadow: 0 1px 4px 0 rgba(0,0,0,0.2);\n}\n\n.rte_toolBar .popover > .arrow {\n display: none;\n}\n\n.rte_toolBar .popover > .popover-content {\n padding: 0;\n}\n\n.rte_toolBar .dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n list-style: none;\n font-size: 14px;\n background-color: #ffffff;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n background-clip: padding-box;\n}\n\n/****** Button styling **********/\n.rte_toolBar button.rte-button {\n all: initial;\n font-family: Helvetica,Arial,sans-serif;\n display: inline-block;\n padding: 0 1rem;\n margin: 0 1px;\n font-size: 16px;\n font-weight: normal;\n line-height: 2.5rem;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n -ms-touch-action: manipulation;\n touch-action: manipulation;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n background-image: none;\n border: none;\n\n}\n\n.rte_toolBar button.rte-button.rte-button-quiet {\n color: #333;\n background-color: transparent;\n}\n\n.rte_toolBar button.rte-button.rte-button-square {\n background-color: white;\n border: 1px solid rgba(0,0,0,0.2);\n border-radius: 4px;\n padding: 0 0.8rem;\n color: #333;\n}\n\n.rte_toolBar button.rte-button.rte-button-quiet:hover,\n.rte_toolBar button.rte-button.rte-button-quiet:focus,\n.rte_toolBar button.rte-button.rte-button-quiet:active {\n color: #333;\n background-color: #FAFAFA;\n box-shadow: inset 1px 0 0 0 rgba(0,0,0,0.2), inset -1px 0 0 0 rgba(0,0,0,0.2);\n}\n\n\n/************ Popover stylings **************/\n\n.rte_toolBar .rte-popover {\n\tdisplay: inline-block;\n}\n\n.rte_toolBar .rte-popover > button:after {\n content: '';\n display: inline-block;\n width: 0;\n height: 0;\n border-bottom: 8px solid rgba(0,0,0,0.2);\n border-left: 10px solid transparent;\n margin-bottom: -1rem;\n margin-right: -1rem;\n}\n\n\n/*********** Group styles *******************/\n.rte_toolBar .rte-group {\n display: inline;\n}\n\n.rte_toolBar .rte-group:after {\n content: '';\n display: inline;\n width: 1px;\n height: 2rem;\n background-color: rgba(0,0,0,0.2);\n vertical-align: middle;\n}\n\n.rte_toolBar .rte-block-group {\n display: block;\n}\n/*********** Dropdown styles *******************/\n.rte_toolBar .rte-select {\n display: inline;\n}\n.rte_toolBar .rte-select > select {\n margin-right: 5px;\n height: 2.5rem;\n padding: 0.5rem 2rem 0.5rem 0.5rem;;\n color: #555;\n background-color: transparent;\n background-image: none;\n border: none;\n -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n width: auto;\n cursor: pointer;\n position: relative;\n z-index: 1;\n}\n\n.rte_toolBar .rte-select > i {\n margin-left: -2rem;\n font-size: 11px;\n pointer-events : none;\n position: relative;\n}\n\n\n/************* Input styles ***********/\n.rte_toolBar .rte-numberInput {\n display: inline-block;\n max-width: 6rem;\n margin-right: 0.5rem;\n}\n\n.rte_toolBar .rte-input,\n.rte_toolBar .rte-numberInput > input {\n all: initial;\n height: 1.5rem;\n padding: 0.5rem;\n border: 1px solid rgba(0,0,0,0.2);\n font-family: Helvetica,Arial,sans-serif;\n}\n\n.rte_toolBar .rte-numberInput > input {\n width: 85%;\n}\n\n.rte_toolBar input[type=\"checkbox\"] {\n width: auto !important;\n height: auto !important;\n}\n\n/******* Color Picker stylings *********/\n.rte_toolBar .rte-colorInput {\n display: inline-block;\n margin-right: 0.5rem;\n}\n\n.rte_toolBar .rte-colorInput button {\n border-radius: 0 !important;\n}\n\n.rte_toolBar .rte-colorInput .pick-a-color-markup .color-dropdown:focus,\n.rte_toolBar .rte-colorInput .pick-a-color-markup .color-dropdown:active,\n.rte_toolBar .rte-colorInput .pick-a-color-markup .color-dropdown:hover {\n color: #333;\n background-color: #FAFAFA;\n box-shadow: inset 1px 0 0 0 rgba(0,0,0,0.2), inset -1px 0 0 0 rgba(0,0,0,0.2);\n}\n.rte_toolBar .rte-colorInput .pick-a-color-markup .color-preview {\n border: 1px solid rgba(0,0,0,.1);\n box-shadow: none;\n border-radius: 0;\n margin: 0;\n vertical-align: middle;\n}\n\n.rte_toolBar .rte-colorInput .pick-a-color-markup .highlight-band {\n background-color: #fff;\n border-radius: 0;\n border: .0625rem solid #c8c8c8;\n width: .625rem;\n height: 1.5rem;\n top: -0.5rem;\n box-shadow: none;\n}\n\n.rte_toolBar .rte-colorInput .pick-a-color-markup .highlight-band-stripe {\n display: none;\n}\n\n.rte_toolBar .rte-colorInput .pick-a-color-markup .color-box {\n height: 8px;\n border-top: .0625rem solid rgba(0,0,0,.1);\n border-bottom: .0625rem solid rgba(0,0,0,.1);\n zoom: 1;\n margin-top: 0.4rem;\n}\n\n.rte_toolBar .rte-colorInput .pick-a-color-markup .color-menu.no-hex {\n left: auto !important;\n}\n\n.rte_toolBar .rte-colorInput button {\n all: initial;\n border-radius: 0px;\n padding: 6px 5px;\n font-family: Helvetica,Arial,sans-serif;\n line-height: 1.7rem;\n}\n\n\n\n.rte_toolBar .rte_insertLink_dialog,\n.rte_toolBar .rte_findAndReplace_dialog {\n padding: 0.5rem;\n}\n\n.rte_toolBar .rte_insertLink_dialog {\n width: 25.8rem;\n}\n\n.rte_toolBar .rte_insertLink_dialog > span{\n display: inline-block;\n margin-top: 1rem;\n}\n\n.rte_toolBar .rte_insertLink_dialog > button{\n margin: 0.5rem 0.1rem;\n float: right;\n}\n\n.rte_toolBar .rte_lists_command + .popover {\n width: 9rem;\n}\n\n.rte_toolBar .input-group,\n.rte_toolBar .input-group-btn {\n display: inline-block;\n}\n\n.wysihtml5-tempContainer {\n height: 0;\n overflow: hidden;\n}\n/*************************************************************************\n * ADOBE CONFIDENTIAL\n * ___________________\n *\n * Copyright 2013 Adobe Systems Incorporated\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe Systems Incorporated and its suppliers,\n * if any. The intellectual and technical concepts contained\n * herein are proprietary to Adobe Systems Incorporated and its\n * suppliers and are protected by all applicable intellectual property\n * laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe Systems Incorporated.\n **************************************************************************/\n\n/* this works only for MWS app. In IE behavior remains same\n with horizontal scrollbar appearing for content-width greater than device-width */\n@-ms-viewport{\n width: device-width;\n}\n\n.formLoading{\n text-align: center;\n vertical-align: middle;\n background-color: white;\n height:100%;\n width:100%;\n}\n\n.xfaform {\n position: relative;\n}\n\n\ninput:not([type=\"radio\"]),select,textarea {\n border: 0;\n padding: 0;\n margin: 0;\n -webkit-border-radius: 0;\n -moz-border-radius: 0;\n background-color: rgba(255,255,255,0);\n}\n\ninput[type=\"radio\"] {\n padding: 0px;\n margin: 0px;\n}\n\n.widgetError {\n background-color: #D3D3D3 !important;\n}\n\n.widgetMandatoryBorder {\n outline: 1.5px solid red;\n}\n\n.dataInvalid {\n outline: 2px solid orange;\n}\n\n#xfa_ui_freeze {\n position: fixed;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.3); /*dim the background*/\n cursor: wait !important; /* busy cursor */\n z-index: 100000;\n}\n\ninput:focus, textarea:focus{\n outline: none;\n cursor: auto;\n}\n\ninput[readonly=\"readonly\"][type=\"text\"]:focus, textarea[readonly=\"readonly\"]:focus, input[type=\"radio\"]:focus, input[type=\"checkbox\"]:focus, select:focus, .imagefieldwidget > img:focus, .listBoxWidget > ol > li:focus {\n outline: #000000 dashed 1px;\n}\n\ninput[type=\"button\"]:focus {\n outline: #000000 dashed 2px;\n}\n\n.page {\n background-color: rgba(255,255,255,1);\n filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffffff,endColorstr=#ffffffff);\n overflow: hidden;\n}\n\n/*#######################################################################*/\n/*# Html-XFA Layout specific styles */\n/*#######################################################################*/\n\n.page > div, .field > div, .draw > * {\n position: absolute\n}\n\n/* must exclude date picker icons from aligning to top left*/\ntable .field > *, table .draw > *, table .field div > *:not(.datepicker-calendar-icon) {\n top: 0;\n left: 0;\n}\n\n/* LC-5561 : Override the 1em extra line space between paragraphs introduced by browser user agent */\n.draw p {\nmargin-top: 0px;\nmargin-bottom: 0px;\n}\n\n/*####################################### Html-XFA Layout specific styles End ##################### */\n\n.subform {\n overflow: visible;\n}\n\ndiv.widget > textarea , table.widget > textarea\n{\n resize: none;\n overflow: hidden;\n}\n\n\n\nsvg|rect\n{\n fill-opacity: 0.0\n}\n\nsvg|text\n{\n white-space: pre;\n -webkit-text-size-adjust: auto;\n}\n\nsvg|tspan\n{\n white-space: pre;\n -webkit-text-size-adjust: auto;\n}\n\ninput[type=date]::-webkit-outer-spin-button {\n -webkit-appearance: none;\n}\n\ninput[type=date]::-webkit-inner-spin-button {\n -webkit-appearance: none;\n}\n\n.neutral {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n\n#error-msg {\n background-color: #ee0101;\n z-index:990;\n display:none;\n position:absolute;\n opacity:0.85;\n color:#FFFFFF;\n font-size: 21px;\n border: 2px solid #ddd;\n box-shadow: 0 0 6px #000;\n -moz-box-shadow: 0 0 6px #000;\n -webkit-box-shadow: 0 0 6px #000;\n padding: 4px 10px 4px 10px;\n border-radius: 6px;\n -moz-border-radius: 6px;\n -webkit-border-radius: 6px;\n}\n\n#warning-msg {\n background-color: #FFA500;\n z-index:990;\n display:none;\n position:absolute;\n opacity:0.85;\n color:#FFFFFF;\n font-size: 21px;\n border: 2px solid #ddd;\n box-shadow: 0 0 6px #000;\n -moz-box-shadow: 0 0 6px #000;\n -webkit-box-shadow: 0 0 6px #000;\n padding: 4px 10px 4px 10px;\n border-radius: 6px;\n -moz-border-radius: 6px;\n -webkit-border-radius: 6px;\n}\n\ninput[type=\"button\"]:active {\n background-color: rgba(0,0,0,0.21)\n}\n\n.dateTimeEdit input\n{\n width:100%;\n height:100%;\n}\n.hideElement {\n\tvisibility: hidden !important;\n}\n\n/*************************************************************************\n * ADOBE CONFIDENTIAL\n * ___________________\n *\n * Copyright 2013 Adobe Systems Incorporated\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe Systems Incorporated and its suppliers,\n * if any. The intellectual and technical concepts contained\n * herein are proprietary to Adobe Systems Incorporated and its\n * suppliers and are protected by all applicable intellectual property\n * laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe Systems Incorporated.\n **************************************************************************/\n\n\n\n#msgBox_container {\n font-family: Arial, sans-serif;\n font-size: 12px;\n min-width: 300px; /* Dialog will be no smaller than this */\n max-width: 600px; /* Dialog will wrap after this width */\n background: #FFF;\n border: solid 5px #999;\n color: #000;\n -moz-border-radius: 5px;\n -webkit-border-radius: 5px;\n border-radius: 5px;\n}\n\n#msgBox_title {\n font-size: 14px;\n font-weight: bold;\n text-align: center;\n line-height: 1.75em;\n color: #666;\n background: #CCC top repeat-x;\n border: solid 1px #FFF;\n border-bottom: solid 1px #999;\n cursor: default;\n padding: 0em;\n margin: 0em;\n}\n\n#msgBox_content {\n background: 16px 16px no-repeat ;\n padding: 1em 1.75em;\n margin: 0em;\n}\n\n#msgBox_message {\n padding-left: 48px;\n}\n\n#msgBox_panel {\n text-align: center;\n margin: 1em 0em 0em 1em;\n}\n\n#msgBox_prompt {\n margin: .5em 0em;\n}\n\ninput#msgBox_Ok,input#msgBox_Yes,input#msgBox_No,input#msgBox_Cancel{\n background-color: buttonFace;\n padding: 5px 10px;\n -webkit-box-shadow: rgba(0,0,0,1) 0 1px 0;\n -moz-box-shadow: rgba(0,0,0,1) 0 1px 0;\n box-shadow: rgba(0,0,0,1) 0 1px 0;\n text-shadow: rgba(0,0,0,.4) 0 1px 0;\n color: buttonText;\n font-size: 14px;\n font-family: Georgia, serif;\n text-decoration: none;\n vertical-align: middle;\n outline:none;\n border: 2px outset buttonface;\n}\n\ninput#msgBox_Ok:focus,input#msgBox_Yes:focus,input#msgBox_No:focus,input#msgBox_Cancel:focus{\noutline:highlight;\n}\n\ninput#msgBox_Ok:hover,input#msgBox_Yes:hover,input#msgBox_No:hover,input#msgBox_Cancel:hover{\noutline:none;\nborder: 2px outset buttonface;\n}\n.msgBoxType0{\n background-image: url(../../../../etc.clientlibs/fd/xfaforms/clientlibs/xfalib/resources/images/A_Warning_Lg_N.png);\n}\n.msgBoxType1{\n background-image: url(../../../../etc.clientlibs/fd/xfaforms/clientlibs/xfalib/resources/images/A_Alert2_Lg_N.png);\n}\n.msgBoxType2{\n background-image: url(../../../../etc.clientlibs/fd/xfaforms/clientlibs/xfalib/resources/images/C_QuestionBubble_Xl_N.png);\n}\n.msgBoxType3{\n background-image: url(../../../../etc.clientlibs/fd/xfaforms/clientlibs/xfalib/resources/images/A_InfoBlue_32x32_N.png);\n}\n\n/*************************************************************************\n * ADOBE CONFIDENTIAL\n * ___________________\n *\n * Copyright 2013 Adobe Systems Incorporated\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe Systems Incorporated and its suppliers,\n * if any. The intellectual and technical concepts contained\n * herein are proprietary to Adobe Systems Incorporated and its\n * suppliers and are protected by all applicable intellectual property\n * laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe Systems Incorporated.\n **************************************************************************/\n\n.datetimepicker {\n border: none;\n background-color: #FFF;\n display: none;\n position: absolute;\n cursor: default;\n z-index: 100;\n outline: solid #CCCCCC 2px;\n}\n\n.datetimepicker .dp-clear {\n overflow: auto;\n background-color: #F5F5F5;\n text-align: center;\n}\n\n.datetimepicker .dp-clear a {\n cursor: pointer;\n height: 40px;\n line-height: 40px;\n padding: 0px 5px 0px 5px;\n text-align: center;\n display: inline-block;\n font-size: 0.875rem;\n color: #969696;\n}\n\n.datetimepicker-notouch .dp-close a:hover {\n color: #c8bbff;\n}\n\n.datetimepicker .dp-header {\n height: 40px;\n line-height: 40px;\n color: #555555;\n margin-bottom: 5px;\n background-color: #E6E6E6;\n}\n\n.datetimepicker .dp-header .dp-leftnav,\n.datetimepicker .dp-header .dp-rightnav,\n.datetimepicker .dp-header .dp-caption {\n float: left;\n text-align: center;\n cursor: pointer;\n height: 40px;\n}\n\n.datetimepicker-notouch .dp-header .dp-caption:not(.disabled):hover {\n color: #969696;\n}\n\n.datetimepicker .dp-header .dp-rightnav {\n float: right;\n background: url(xfalib/resources/images/rightnav.png) no-repeat center center;\n width: 40px;\n}\n\n.datetimepicker .dp-header .dp-leftnav {\n width: 40px;\n background: url(xfalib/resources/images/leftnav.png) no-repeat center center;\n}\n\n.datetimepicker .dp-header .dp-rightnav:hover {\n background: url(xfalib/resources/images/rightnav_hover.png) no-repeat center center;\n}\n\n.datetimepicker .dp-header .dp-leftnav:hover {\n background: url(xfalib/resources/images/leftnav_hover.png) no-repeat center center;\n}\n\n.datetimepicker .view {\n display: none;\n}\n\n.datetimepicker .view ul {\n display: block;\n list-style: none;\n margin: 0px;\n padding: 0px;\n overflow: hidden;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n}\n\n.datetimepicker .view ul li {\n float: left;\n padding: 0px;\n text-align: center;\n border: none;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n color: #666666;\n}\n\n.datetimepicker .view ul.header li {\n color: #555555;\n}\n\n.datetimepicker .view ul:not(.header) li:not(.disabled) {\n cursor: pointer;\n}\n\n.datetimepicker .view ul.header {\n color: #000;\n background-color: #FFF;\n border-bottom: #E6E6E6 1px solid;\n}\n\n.datetimepicker-notouch .view ul:not(.header) li:not(.disabled):hover {\n color: black;\n background-color: #E6E6E6;\n opacity: 0.5;\n}\n\n.datetimepicker .view ul li.disabled {\n color: #CCCCCC;\n}\n\n.datetimepicker .view ul li.dp-selected {\n outline: none;\n background-color: #666666;\n color: #FFFFFF;\n opacity: 1.0;\n}\n\n.datetimepicker .view ul li.dp-focus {\n border: 1px dashed black;\n}\n\n.datepicker-calendar-icon {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 10;\n height: 100%;\n background: url(xfalib/resources/images/calendar.png) no-repeat center center;\n background-size: contain;\n}\n\n.datefieldwidget.widgetreadonly .datepicker-calendar-icon {\n display: none;\n}\n\n/*******************************************************************************\n * ADOBE CONFIDENTIAL\n * ___________________\n *\n * Copyright 2015 Adobe Systems Incorporated\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe Systems Incorporated and its suppliers,\n * if any. The intellectual and technical concepts contained\n * herein are proprietary to Adobe Systems Incorporated and its\n * suppliers and are protected by all applicable intellectual property\n * laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe Systems Incorporated.\n ******************************************************************************/\n\n/** Default style to show placeholder in dropdownlist **/\n.dropDownList .placeHolder{\n color: gray;\n}\n\n.dropDownList select {\n width: 100%;\n height: 100%;\n}\n\n/*******************************************************************************\n * ADOBE CONFIDENTIAL\n * ___________________\n *\n * Copyright 2013 Adobe Systems Incorporated\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe Systems Incorporated and its suppliers,\n * if any. The intellectual and technical concepts contained\n * herein are proprietary to Adobe Systems Incorporated and its\n * suppliers and are protected by all applicable intellectual property\n * laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe Systems Incorporated.\n ******************************************************************************/\n\n\n\ndiv#iEBox_container {\n font-family: Arial, sans-serif;\n font-size: 12px;\n min-width: 300px; /* Dialog will be no smaller than this */\n /* Dialog will wrap after this width */\n background: #FFF;\n border: solid 2px #999;\n color: #000;\n \n \n -moz-border-radius: 10px;\n -webkit-border-radius: 10px;\n border-radius: 10px;\n \n display:none;\n /* the shadow */\n -moz-box-shadow: 10px 10px 5px #888888;\n -webkit-box-shadow: 10px 10px 5px #888888;\n box-shadow: 0px 0px 15px #888888;\n \n /* make dialog a non-selectatable thing */\n -moz-user-select: none; \n -khtml-user-select: none; \n -webkit-user-select: none; \n -o-user-select: none; \n \n position: absolute;\n z-index: 99998;\n padding: 0;\n margin: 0;\n\t \n\t line-height:0;\n}\n\n#iEBox_title {\n font-size: 14px;\n font-weight: normal;\n text-align: center;\n line-height: 1.75em;\n color: #555555;\n background: #FFFFFF top repeat-x;\n cursor: default;\n padding: 10px;\n margin: 0em;\n display:inline-block;\n /* border-left:2px ridge gray; */\n vertical-align:middle;\n}\n\n#iEBox_content {\n background: 16px 16px no-repeat ;\n padding: 10px 10px;\n margin: 0em;\n\tmin-width:300px;\n}\n\n#iEBox_canvas {\n border:4px #AAAAAA dashed;\n -ms-touch-action:pinch-zoom;\n touch-action:pinch-zoom;\n}\n\n#iEBox_panel {\n text-align: center;\n margin: 0em 0em 0em 0em;\n background-color:black;\n \n -moz-border-top-right-radius: 8px;\n -webkit-border-top-right-radius: 8px;\n border-top-right-radius: 8px;\n -moz-border-top-left-radius: 8px;\n -webkit-border-top-left-radius: 8px;\n border-top-left-radius: 8px;\n \n overflow:hidden;\n \n /* title bar color */\n background: #AFB0B5;\n\t\n -ms-touch-action:pinch-zoom;\n touch-action:pinch-zoom;\n}\n\n#iEBox_prompt {\n margin: .5em 0em;\n}\n\ndiv.iEBox_button {\n background:no-repeat;\n width:40px;\n height:40px;\n background-size:40px 40px;\n display:inline-block;\n margin:10px;\n}\ndiv#iEBox_Geo{\n background-image:url('xfalib/resources/images/iEBox_geo.png');\n width:40px;\n height:40px;\n background-size:40px 40px;\n display:none;\n vertical-align:middle;\n}\ndiv#iEBox_Text{\n background-image:url('xfalib/resources/images/iEBox_keyboard.png');\n width:40px;\n height:40px;\n background-size:40px 40px;\n display:inline-block;\n vertical-align:middle;\n}\n#keyboard_Sign_Box{\n border:4px #AAAAAA dashed;\n display:none;\n margin:0px;\n border-bottom:0px;\n border-radius: 0px 0px 0px 0px;\n outline:none;\n}\n\n#keyboard_Sign_Box::placeholder {\n font: 1rem sans-serif, Georgia;\n vertical-align: middle;\n}\n\ndiv#iEBox_Brush{\n background-image:url('xfalib/resources/images/iEBox_brush.png');\n width:40px;\n height:40px;\n background-size:40px 40px;\n\n vertical-align:middle;\n}\ndiv#iEBox_incBrush{\n background-image:url('xfalib/resources/images/iEBox_geo.png');\n width:40px;\n height:40px;\n background-size:40px 40px;\n \n vertical-align:middle;\n}\ndiv#iEBox_Ok {\n background-image:url('xfalib/resources/images/iEBox_ok.png');\n vertical-align:middle;\n float:right;\n}\ndiv#iEBox_Clear {\n background-image:url('xfalib/resources/images/iEBox_clear.png');\n vertical-align:middle;\n}\ndiv#iEBox_Cancel {\n background: url('xfalib/resources/images/iEBox_close.png') center no-repeat;\n float:right;\n}\ndiv#iEBox_moveframe{\npadding:0px;\nmargin:0px;\n border:0px dotted rgba(0,0,0,0.5);\n -moz-border-radius: 10px;\n -webkit-border-radius: 10px;\n border-radius: 10px;\n \n -moz-box-shadow: 10px 10px 5px #888888;\n -webkit-box-shadow: 10px 10px 5px #888888;\n box-shadow: 0px 0px 15px #888888;\n \n display:none;\n position:absolute;\n}\ndiv.disable_button {\n filter: url(\"data:image/svg+xml;utf8,#grayscale\"); /* Firefox 3.5+ */\n filter: grayscale(100%);\n -webkit-filter: grayscale(100%);\n -moz-filter: grayscale(100%);\n -ms-filter: grayscale(100%);\n -o-filter: grayscale(100%);\n}\ndiv.sc_popUpMenu {\n display:none;\n width:20px;\n height:20px;\n background:no-repeat;\n background-size:20px 20px; \n background-image:url('xfalib/resources/images/iEBox_no.png');\n \n z-index:9999;\n position:absolute;\n left:0px;\n top:0px;\n}\ndiv#iEBox_brushList{\n position:absolute;\n z-index:99999;\n background-color:white;\n -moz-box-shadow: 10px 10px 5px #888888;\n -webkit-box-shadow: 10px 10px 5px #888888;\n box-shadow: 0px 0px 15px #888888;\n display:none;\n}\ndiv#iEBox_brushList div:hover{\n background-color:gray;\n}\nfieldset#iEBox_caption {\n border:4px dashed #AAAAAA;\n border-bottom:0px;\n border-left:0px;\n border-right:0px;\n margin-right:4px;\n margin-left:1px;\n margin-top:0px;\n text-align:center;\n padding:0px;\n}\nfieldset#iEBox_caption > legend {\n width:auto;\n background-color: #FFFFFF;\n padding: 2px;\n}\n.emptyScribble {\n background: url(xfalib/resources/images/signature.png) no-repeat;\n}\n\ndiv#iEBox_canvases {\n white-space:nowrap;\n}\n\n/*******************************************************************************\n * ADOBE CONFIDENTIAL\n * ___________________\n *\n * Copyright 2013 Adobe Systems Incorporated\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe Systems Incorporated and its suppliers,\n * if any. The intellectual and technical concepts contained\n * herein are proprietary to Adobe Systems Incorporated and its\n * suppliers and are protected by all applicable intellectual property\n * laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe Systems Incorporated.\n ******************************************************************************/\n\ndiv .listBoxWidget , table.listBoxWidget{\n overflow: auto;\n}\n\ndiv.listBoxWidget > ol, table.listBoxWidget > ol{\n list-style-type: none;\n padding: 5px;\n margin:0px;\n outline: none;\n}\n\nol > li.item-selectable{\n background-color: rgba(255, 255, 255, 0);\n color: black;\n padding-left: 5px;\n cursor: pointer;\n}\n\nol> li.item-selected{\n background: #99C1DA;\n color: white;\n padding-left: 5px;\n cursor: pointer;\n}\n/*******************************************************************************\n * ADOBE CONFIDENTIAL\n * ___________________\n *\n * Copyright 2017 Adobe Systems Incorporated\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe Systems Incorporated and its suppliers,\n * if any. The intellectual and technical concepts contained\n * herein are proprietary to Adobe Systems Incorporated and its\n * suppliers and are protected by all applicable intellectual property\n * laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe Systems Incorporated.\n ******************************************************************************/\n\n.filePreview {\n position: absolute;\n top: -1000px;\n bottom: -1000px;\n visibility: hidden;\n height: 0;\n}\n\n/*******************************************************************************\n * ADOBE CONFIDENTIAL\n * ___________________\n *\n * Copyright 2019 Adobe Systems Incorporated\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe Systems Incorporated and its suppliers,\n * if any. The intellectual and technical concepts contained\n * herein are proprietary to Adobe Systems Incorporated and its\n * suppliers and are protected by all applicable intellectual property\n * laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe Systems Incorporated.\n ******************************************************************************/\n\n\n.richTextWidget {\n overflow: auto;\n}\n\n/*/*******************************************************************************\n * ADOBE CONFIDENTIAL\n * ___________________\n *\n * Copyright 2023 Adobe Systems Incorporated\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe Systems Incorporated and its suppliers,\n * if any. The intellectual and technical concepts contained\n * herein are proprietary to Adobe Systems Incorporated and its\n * suppliers and are protected by all applicable intellectual property\n * laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe Systems Incorporated.\n ******************************************************************************/\n\ntext {\n forced-color-adjust: auto;\n}\n\n@media (forced-colors: active) {\n\n text {\n fill:CanvasText!important;\n }\n\n a text {\n fill:LinkText!important;\n forced-color-adjust: auto;\n }\n\n input {\n color:CanvasText!important;\n }\n\n input([type=checkbox]) {\n color:Highlight!important;\n }\n\n\n .datetimepicker .dp-header {\n color:CanvasText!important;\n }\n \n .datetimepicker li {\n color:CanvasText!important;\n }\n \n .datetimepicker .dp-clear a {\n color:CanvasText!important;\n }\n \n .datetimepicker {\n background-color:Canvas!important;\n }\n \n .datetimepicker .dp-header{\n background-color:Canvas!important;\n }\n \n .datetimepicker .dp-header{\n background-color:Canvas!important;\n }\n \n .datetimepicker .dp-monthview {\n background-color:Canvas!important;\n }\n \n .datetimepicker .dp-yearview {\n background-color:Canvas!important;\n }\n \n .datetimepicker .dp-yearsetview {\n background-color:Canvas!important;\n }\n\n .datetimepicker .dp-monthview .header{\n background-color:Canvas!important;\n }\n \n .datetimepicker .dp-clear {\n background-color:Canvas!important;\n }\n}\n\n@media (forced-colors: active) and (prefers-color-scheme: dark) {\n\t.datepicker-calendar-icon {\n\t\tfilter: grayscale(100%) brightness(10)!important;\n\t}\n}\n/*******************************************************************************\n * ADOBE CONFIDENTIAL\n * ___________________\n *\n * Copyright 2013 Adobe Systems Incorporated\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe Systems Incorporated and its suppliers,\n * if any. The intellectual and technical concepts contained\n * herein are proprietary to Adobe Systems Incorporated and its\n * suppliers and are protected by all applicable intellectual property\n * laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe Systems Incorporated.\n ******************************************************************************/\n.toolbarheader {\n width: 100%;\n height: 39px;\n background-repeat: repeat-x;\n background-color: #C790F4;\n position: fixed;\n border: 1px solid rgba(0,0,0, 0.5);\n vertical-align: middle;\n z-index: 2;\n margin-bottom: 5px;\n position: relative;\n}\n\n.toolbarformslogo {\n background: url(\"toolbar/resources/images/AX_Form_Lg_N.png\") no-repeat;\n width: 28px;\n height: 28px;\n border: none;\n margin-top:5px;\n vertical-align: middle;\n float: left;\n}\n\n.toolbarfieldhighlight {\n background: url(\"toolbar/resources/images/AX_HighlightFields_Lg_N.png\") no-repeat;\n width: 50px;\n height: 28px;\n margin-top:5px;\n border: none;\n vertical-align: middle;\n float: right;\n /*border: 1px solid #ffffff;*/\n}\n.toolbarfileattachment {\n background: url(\"toolbar/resources/images/Attach.png\") no-repeat;\n width: 35px;\n height: 32px;\n margin-top:5px;\n border: none;\n vertical-align: middle;\n float: right;\n margin-right: 10px;\n /*border: 1px solid #ffffff;*/\n}\n.toolbarlogger {\n background-color: #C790F4 ;\n width: 120px;\n height: 28px;\n margin-top:5px;\n border: none;\n vertical-align: middle;\n float: right;\n text-align:center;\n}\n\n.toolbartext {\n font-family: Arial, Helvetica;\n font-size: 12px;\n}\n\n.widgetBackGroundColorHighlight:not(.widgetreadonly) {\n background-color: #DEE3FF !important;\n}\n\n.widgetBackGroundColorHighlight:not(.widgetreadonly):not(.widgetMandatoryBorder):not(.dataInvalid) {\n outline: none ;\n}\n\n#loadingPage {\n background: url(\"toolbar/resources/images/busy-state.gif\") no-repeat fixed center;\n position: fixed;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n width: 100%;\n height: 100%;\n background-color: rgb(255, 255, 255);\n cursor: wait; /* busy cursor */\n z-index: 100000;\n}\n\n.loadingBody {\n background-color: rgb(255, 255, 255);\n}\n\n#loadText {\n position: fixed;\n left: 50%;\n top: 50%;\n transform: translate(-50%, 35px);\n font-size: 150%;\n z-index: 1000000;\n}\n\ninput[type=\"file\"] {\n visibility: hidden !important;\n top: -2000px !important;\n left: -2000px !important;\n position: absolute !important;\n}\ninput[type=\"file\"] {\n display: block;\n}\n.guideFieldWidget input[type=\"button\"], .guideFieldWidget button, .guideFieldWidget .button {\n /* margin-top: @label-line-height * @label-font-size + @label-margin; */\n box-sizing: border-box;\n cursor: pointer;\n border-style: outset;\n border-width: 0px;\n border-color: #285e8e;\n color: #000000;\n background-color: #DDDDDD;\n padding: 10px 15px 10px 15px;\n font-size: 14px;\n line-height: normal;\n border-radius: 0;\n}\n\n\nul.guide-fu-fileItemList {\n padding-left: 0px;\n margin:0px;\n list-style: none;\n}\n\nli.guide-fu-fileItem{\n display: block;\n padding: 10px;\n background-color: #fff;\n border-top: 1px solid #dddddd;;\n color: #000000;\n}\n\nspan.guide-fu-filePreview{\n margin-right: 10px;\n float: left;\n color: #000000;\n}\n\nspan.guide-fu-fileName {\n text-decoration: underline;\n cursor: pointer;\n}\n\nspan.non-preview-fileName{\n text-decoration: none;\n opacity: 0.4;\n}\n\ndiv.guide-fu-comment[contenteditable=\"true\"] {\n border: 1px solid;\n margin-top:5px;\n}\n\ndiv.guide-fu-comment {\nwidth:100%;\nheight: 25px;\nmargin-top: 5px;\npadding: 2px 30px 2px 5px;\nword-break: break-word;\nborder-style: groove;\n}\n\n.modal-elements-font-size {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n}\ndiv.guideFileUpload div.guideFieldWidget > input[type=\"file\"] {\n visibility:hidden !important;\n top:-2000px !important;\n left:-2000px !important;\n position:absolute !important;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition: height 0.35s ease;\n transition: height 0.35s ease;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000000;\n text-shadow: 0 1px 0 #ffffff;\n opacity: 0.2;\n filter: alpha(opacity=20);\n}\n.close:hover,\n.close:focus {\n color: #000000;\n text-decoration: none;\n cursor: pointer;\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n display: none;\n overflow: auto;\n overflow-y: scroll;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #ffffff;\n border: 1px solid #999999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n background-clip: padding-box;\n outline: none;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000000;\n}\n.modal-backdrop.fade {\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.modal-backdrop.in {\n opacity: 0.5;\n filter: alpha(opacity=50);\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n min-height: 16.42857143px;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 20px;\n}\n.modal-footer {\n margin-top: 15px;\n padding: 19px 20px 20px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n\n/*******************************************************************************\n * ADOBE CONFIDENTIAL\n * ___________________\n *\n * Copyright 2013 Adobe Systems Incorporated\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe Systems Incorporated and its suppliers,\n * if any. The intellectual and technical concepts contained\n * herein are proprietary to Adobe Systems Incorporated and its\n * suppliers and are protected by all applicable intellectual property\n * laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe Systems Incorporated.\n ******************************************************************************/\n\n.pagingfooter {\n width: 100%;\n height: 39px;\n background-repeat: repeat-x;\n background-color: #C790F4;\n border: 1px solid rgba(0,0,0, 0.5);\n vertical-align: middle;\n z-index: 2;\n margin-bottom: 5px;\n position: relative;\n}\n.pageloadinglogo {\n border: none;\n margin-right:5px;\n vertical-align: middle;\n}\n\n.pageloadtext {\n font-family: Arial, Helvetica;\n font-size: 12px;\n font-style: italic;\n}\n\n.pageloadnow {\n width: 200px;\n height: 28px;\n margin-top:5px;\n border: none;\n vertical-align: middle;\n float: right;\n border: none;\n\n}\n/*\n * ADOBE CONFIDENTIAL\n * ___________________\n *\n * Copyright 2012-2013 Adobe Systems Incorporated\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe Systems Incorporated and its suppliers,\n * if any. The intellectual and technical concepts contained\n * herein are proprietary to Adobe Systems Incorporated and its\n * suppliers and may be covered by U.S. and Foreign Patents,\n * patents in process, and are protected by trade secret or copyright law.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe Systems Incorporated.\n *\n */\n.toolbarformsportalbtn{\n width: 45px;\n height: 35px;\n margin-top:5px;\n vertical-align: middle;\n float: right;\n text-align:center;\n padding: 5px;\n background: url('../../fp/components/clientlibs/xfaforms/resources/save.png') no-repeat transparent 0 0;\n border: none;\n}\n.fpsavemessage{\n width: 200px;\n height: 35px;\n margin-top: 45px;\n margin-right: -115px;\n vertical-align: middle;\n float: right;\n text-align: center;\n border: none;\n background: #D4D4D4;\n border-radius: 5px;\n font: 20px/24px Adobe Clean, Arial;\n padding: 10px 5px 5px 5px;\n display:none;\n}\n/*******************************************************************************\n * ADOBE CONFIDENTIAL\n * ___________________\n *\n * Copyright 2013 Adobe Systems Incorporated\n * All Rights Reserved.\n *\n * NOTICE: All information contained herein is, and remains\n * the property of Adobe Systems Incorporated and its suppliers,\n * if any. The intellectual and technical concepts contained\n * herein are proprietary to Adobe Systems Incorporated and its\n * suppliers and are protected by all applicable intellectual property\n * laws, including trade secret and copyright laws.\n * Dissemination of this information or reproduction of this material\n * is strictly forbidden unless prior written permission is obtained\n * from Adobe Systems Incorporated.\n ******************************************************************************/\n\nbody {\n margin: 0;\n padding: 0;\n background-color: #444;\n}\n\n\n",
"headers" : {
"X-Content-Type-Options" : "nosniff",
- "Last-Modified" : "Sat, 03 May 2025 13:59:40 GMT",
- "Date" : "Sun, 11 May 2025 11:23:44 GMT",
+ "Set-Cookie" : "cq-authoring-mode=TOUCH; Path=/; Expires=Sun, 23-Nov-2025 14:26:31 GMT; Max-Age=604800",
+ "Last-Modified" : "Thu, 18 Sep 2025 12:51:32 GMT",
+ "Expires" : "Thu, 01 Jan 1970 00:00:00 GMT",
+ "Date" : "Sun, 16 Nov 2025 14:26:31 GMT",
"Content-Type" : "text/css;charset=utf-8"
}
},
- "uuid" : "3e90f2cb-315a-4083-a77d-c94479894815",
+ "uuid" : "1a4d3741-e8fd-426c-ad01-e05ab57658fd",
"persistent" : true,
- "insertionIndex" : 22
+ "insertionIndex" : 36
}
\ No newline at end of file
diff --git a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_fd_xfaforms_clientlibs_profile_js.json b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_fd_xfaforms_clientlibs_profile_js.json
index cc0fa072..cfbd51c2 100644
--- a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_fd_xfaforms_clientlibs_profile_js.json
+++ b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_fd_xfaforms_clientlibs_profile_js.json
@@ -1,5 +1,5 @@
{
- "id" : "0d679342-fffe-4666-9286-bd35cc64a58e",
+ "id" : "0a024c8e-aa5e-4459-91bf-531695e412fe",
"name" : "etc.clientlibs_fd_xfaforms_clientlibs_profile.js",
"request" : {
"url" : "/etc.clientlibs/fd/xfaforms/clientlibs/profile.js",
@@ -7,15 +7,15 @@
},
"response" : {
"status" : 200,
- "base64Body" : "LyohIGpRdWVyeSB2My42LjAgfCAoYykgT3BlbkpTIEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9ycyB8IGpxdWVyeS5vcmcvbGljZW5zZSAqLwohZnVuY3Rpb24oZSx0KXsidXNlIHN0cmljdCI7Im9iamVjdCI9PXR5cGVvZiBtb2R1bGUmJiJvYmplY3QiPT10eXBlb2YgbW9kdWxlLmV4cG9ydHM/bW9kdWxlLmV4cG9ydHM9ZS5kb2N1bWVudD90KGUsITApOmZ1bmN0aW9uKGUpe2lmKCFlLmRvY3VtZW50KXRocm93IG5ldyBFcnJvcigialF1ZXJ5IHJlcXVpcmVzIGEgd2luZG93IHdpdGggYSBkb2N1bWVudCIpO3JldHVybiB0KGUpfTp0KGUpfSgidW5kZWZpbmVkIiE9dHlwZW9mIHdpbmRvdz93aW5kb3c6dGhpcyxmdW5jdGlvbihDLGUpeyJ1c2Ugc3RyaWN0Ijt2YXIgdD1bXSxyPU9iamVjdC5nZXRQcm90b3R5cGVPZixzPXQuc2xpY2UsZz10LmZsYXQ/ZnVuY3Rpb24oZSl7cmV0dXJuIHQuZmxhdC5jYWxsKGUpfTpmdW5jdGlvbihlKXtyZXR1cm4gdC5jb25jYXQuYXBwbHkoW10sZSl9LHU9dC5wdXNoLGk9dC5pbmRleE9mLG49e30sbz1uLnRvU3RyaW5nLHY9bi5oYXNPd25Qcm9wZXJ0eSxhPXYudG9TdHJpbmcsbD1hLmNhbGwoT2JqZWN0KSx5PXt9LG09ZnVuY3Rpb24oZSl7cmV0dXJuImZ1bmN0aW9uIj09dHlwZW9mIGUmJiJudW1iZXIiIT10eXBlb2YgZS5ub2RlVHlwZSYmImZ1bmN0aW9uIiE9dHlwZW9mIGUuaXRlbX0seD1mdW5jdGlvbihlKXtyZXR1cm4gbnVsbCE9ZSYmZT09PWUud2luZG93fSxFPUMuZG9jdW1lbnQsYz17dHlwZTohMCxzcmM6ITAsbm9uY2U6ITAsbm9Nb2R1bGU6ITB9O2Z1bmN0aW9uIGIoZSx0LG4pe3ZhciByLGksbz0obj1ufHxFKS5jcmVhdGVFbGVtZW50KCJzY3JpcHQiKTtpZihvLnRleHQ9ZSx0KWZvcihyIGluIGMpKGk9dFtyXXx8dC5nZXRBdHRyaWJ1dGUmJnQuZ2V0QXR0cmlidXRlKHIpKSYmby5zZXRBdHRyaWJ1dGUocixpKTtuLmhlYWQuYXBwZW5kQ2hpbGQobykucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChvKX1mdW5jdGlvbiB3KGUpe3JldHVybiBudWxsPT1lP2UrIiI6Im9iamVjdCI9PXR5cGVvZiBlfHwiZnVuY3Rpb24iPT10eXBlb2YgZT9uW28uY2FsbChlKV18fCJvYmplY3QiOnR5cGVvZiBlfXZhciBmPSIzLjYuMCIsUz1mdW5jdGlvbihlLHQpe3JldHVybiBuZXcgUy5mbi5pbml0KGUsdCl9O2Z1bmN0aW9uIHAoZSl7dmFyIHQ9ISFlJiYibGVuZ3RoImluIGUmJmUubGVuZ3RoLG49dyhlKTtyZXR1cm4hbShlKSYmIXgoZSkmJigiYXJyYXkiPT09bnx8MD09PXR8fCJudW1iZXIiPT10eXBlb2YgdCYmMDx0JiZ0LTEgaW4gZSl9Uy5mbj1TLnByb3RvdHlwZT17anF1ZXJ5OmYsY29uc3RydWN0b3I6UyxsZW5ndGg6MCx0b0FycmF5OmZ1bmN0aW9uKCl7cmV0dXJuIHMuY2FsbCh0aGlzKX0sZ2V0OmZ1bmN0aW9uKGUpe3JldHVybiBudWxsPT1lP3MuY2FsbCh0aGlzKTplPDA/dGhpc1tlK3RoaXMubGVuZ3RoXTp0aGlzW2VdfSxwdXNoU3RhY2s6ZnVuY3Rpb24oZSl7dmFyIHQ9Uy5tZXJnZSh0aGlzLmNvbnN0cnVjdG9yKCksZSk7cmV0dXJuIHQucHJldk9iamVjdD10aGlzLHR9LGVhY2g6ZnVuY3Rpb24oZSl7cmV0dXJuIFMuZWFjaCh0aGlzLGUpfSxtYXA6ZnVuY3Rpb24obil7cmV0dXJuIHRoaXMucHVzaFN0YWNrKFMubWFwKHRoaXMsZnVuY3Rpb24oZSx0KXtyZXR1cm4gbi5jYWxsKGUsdCxlKX0pKX0sc2xpY2U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2socy5hcHBseSh0aGlzLGFyZ3VtZW50cykpfSxmaXJzdDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmVxKDApfSxsYXN0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZXEoLTEpfSxldmVuOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucHVzaFN0YWNrKFMuZ3JlcCh0aGlzLGZ1bmN0aW9uKGUsdCl7cmV0dXJuKHQrMSklMn0pKX0sb2RkOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucHVzaFN0YWNrKFMuZ3JlcCh0aGlzLGZ1bmN0aW9uKGUsdCl7cmV0dXJuIHQlMn0pKX0sZXE6ZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5sZW5ndGgsbj0rZSsoZTwwP3Q6MCk7cmV0dXJuIHRoaXMucHVzaFN0YWNrKDA8PW4mJm48dD9bdGhpc1tuXV06W10pfSxlbmQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wcmV2T2JqZWN0fHx0aGlzLmNvbnN0cnVjdG9yKCl9LHB1c2g6dSxzb3J0OnQuc29ydCxzcGxpY2U6dC5zcGxpY2V9LFMuZXh0ZW5kPVMuZm4uZXh0ZW5kPWZ1bmN0aW9uKCl7dmFyIGUsdCxuLHIsaSxvLGE9YXJndW1lbnRzWzBdfHx7fSxzPTEsdT1hcmd1bWVudHMubGVuZ3RoLGw9ITE7Zm9yKCJib29sZWFuIj09dHlwZW9mIGEmJihsPWEsYT1hcmd1bWVudHNbc118fHt9LHMrKyksIm9iamVjdCI9PXR5cGVvZiBhfHxtKGEpfHwoYT17fSkscz09PXUmJihhPXRoaXMscy0tKTtzPHU7cysrKWlmKG51bGwhPShlPWFyZ3VtZW50c1tzXSkpZm9yKHQgaW4gZSlyPWVbdF0sIl9fcHJvdG9fXyIhPT10JiZhIT09ciYmKGwmJnImJihTLmlzUGxhaW5PYmplY3Qocil8fChpPUFycmF5LmlzQXJyYXkocikpKT8obj1hW3RdLG89aSYmIUFycmF5LmlzQXJyYXkobik/W106aXx8Uy5pc1BsYWluT2JqZWN0KG4pP246e30saT0hMSxhW3RdPVMuZXh0ZW5kKGwsbyxyKSk6dm9pZCAwIT09ciYmKGFbdF09cikpO3JldHVybiBhfSxTLmV4dGVuZCh7ZXhwYW5kbzoialF1ZXJ5IisoZitNYXRoLnJhbmRvbSgpKS5yZXBsYWNlKC9cRC9nLCIiKSxpc1JlYWR5OiEwLGVycm9yOmZ1bmN0aW9uKGUpe3Rocm93IG5ldyBFcnJvcihlKX0sbm9vcDpmdW5jdGlvbigpe30saXNQbGFpbk9iamVjdDpmdW5jdGlvbihlKXt2YXIgdCxuO3JldHVybiEoIWV8fCJbb2JqZWN0IE9iamVjdF0iIT09by5jYWxsKGUpKSYmKCEodD1yKGUpKXx8ImZ1bmN0aW9uIj09dHlwZW9mKG49di5jYWxsKHQsImNvbnN0cnVjdG9yIikmJnQuY29uc3RydWN0b3IpJiZhLmNhbGwobik9PT1sKX0saXNFbXB0eU9iamVjdDpmdW5jdGlvbihlKXt2YXIgdDtmb3IodCBpbiBlKXJldHVybiExO3JldHVybiEwfSxnbG9iYWxFdmFsOmZ1bmN0aW9uKGUsdCxuKXtiKGUse25vbmNlOnQmJnQubm9uY2V9LG4pfSxlYWNoOmZ1bmN0aW9uKGUsdCl7dmFyIG4scj0wO2lmKHAoZSkpe2ZvcihuPWUubGVuZ3RoO3I8bjtyKyspaWYoITE9PT10LmNhbGwoZVtyXSxyLGVbcl0pKWJyZWFrfWVsc2UgZm9yKHIgaW4gZSlpZighMT09PXQuY2FsbChlW3JdLHIsZVtyXSkpYnJlYWs7cmV0dXJuIGV9LG1ha2VBcnJheTpmdW5jdGlvbihlLHQpe3ZhciBuPXR8fFtdO3JldHVybiBudWxsIT1lJiYocChPYmplY3QoZSkpP1MubWVyZ2Uobiwic3RyaW5nIj09dHlwZW9mIGU/W2VdOmUpOnUuY2FsbChuLGUpKSxufSxpbkFycmF5OmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gbnVsbD09dD8tMTppLmNhbGwodCxlLG4pfSxtZXJnZTpmdW5jdGlvbihlLHQpe2Zvcih2YXIgbj0rdC5sZW5ndGgscj0wLGk9ZS5sZW5ndGg7cjxuO3IrKyllW2krK109dFtyXTtyZXR1cm4gZS5sZW5ndGg9aSxlfSxncmVwOmZ1bmN0aW9uKGUsdCxuKXtmb3IodmFyIHI9W10saT0wLG89ZS5sZW5ndGgsYT0hbjtpPG87aSsrKSF0KGVbaV0saSkhPT1hJiZyLnB1c2goZVtpXSk7cmV0dXJuIHJ9LG1hcDpmdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvPTAsYT1bXTtpZihwKGUpKWZvcihyPWUubGVuZ3RoO288cjtvKyspbnVsbCE9KGk9dChlW29dLG8sbikpJiZhLnB1c2goaSk7ZWxzZSBmb3IobyBpbiBlKW51bGwhPShpPXQoZVtvXSxvLG4pKSYmYS5wdXNoKGkpO3JldHVybiBnKGEpfSxndWlkOjEsc3VwcG9ydDp5fSksImZ1bmN0aW9uIj09dHlwZW9mIFN5bWJvbCYmKFMuZm5bU3ltYm9sLml0ZXJhdG9yXT10W1N5bWJvbC5pdGVyYXRvcl0pLFMuZWFjaCgiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvciBTeW1ib2wiLnNwbGl0KCIgIiksZnVuY3Rpb24oZSx0KXtuWyJbb2JqZWN0ICIrdCsiXSJdPXQudG9Mb3dlckNhc2UoKX0pO3ZhciBkPWZ1bmN0aW9uKG4pe3ZhciBlLGQsYixvLGksaCxmLGcsdyx1LGwsVCxDLGEsRSx2LHMsYyx5LFM9InNpenpsZSIrMSpuZXcgRGF0ZSxwPW4uZG9jdW1lbnQsaz0wLHI9MCxtPXVlKCkseD11ZSgpLEE9dWUoKSxOPXVlKCksaj1mdW5jdGlvbihlLHQpe3JldHVybiBlPT09dCYmKGw9ITApLDB9LEQ9e30uaGFzT3duUHJvcGVydHksdD1bXSxxPXQucG9wLEw9dC5wdXNoLEg9dC5wdXNoLE89dC5zbGljZSxQPWZ1bmN0aW9uKGUsdCl7Zm9yKHZhciBuPTAscj1lLmxlbmd0aDtuPHI7bisrKWlmKGVbbl09PT10KXJldHVybiBuO3JldHVybi0xfSxSPSJjaGVja2VkfHNlbGVjdGVkfGFzeW5jfGF1dG9mb2N1c3xhdXRvcGxheXxjb250cm9sc3xkZWZlcnxkaXNhYmxlZHxoaWRkZW58aXNtYXB8bG9vcHxtdWx0aXBsZXxvcGVufHJlYWRvbmx5fHJlcXVpcmVkfHNjb3BlZCIsTT0iW1xceDIwXFx0XFxyXFxuXFxmXSIsST0iKD86XFxcXFtcXGRhLWZBLUZdezEsNn0iK00rIj98XFxcXFteXFxyXFxuXFxmXXxbXFx3LV18W15cMC1cXHg3Zl0pKyIsVz0iXFxbIitNKyIqKCIrSSsiKSg/OiIrTSsiKihbKl4kfCF+XT89KSIrTSsiKig/OicoKD86XFxcXC58W15cXFxcJ10pKiknfFwiKCg/OlxcXFwufFteXFxcXFwiXSkqKVwifCgiK0krIikpfCkiK00rIipcXF0iLEY9IjooIitJKyIpKD86XFwoKCgnKCg/OlxcXFwufFteXFxcXCddKSopJ3xcIigoPzpcXFxcLnxbXlxcXFxcIl0pKilcIil8KCg/OlxcXFwufFteXFxcXCgpW1xcXV18IitXKyIpKil8LiopXFwpfCkiLEI9bmV3IFJlZ0V4cChNKyIrIiwiZyIpLCQ9bmV3IFJlZ0V4cCgiXiIrTSsiK3woKD86XnxbXlxcXFxdKSg/OlxcXFwuKSopIitNKyIrJCIsImciKSxfPW5ldyBSZWdFeHAoIl4iK00rIiosIitNKyIqIiksej1uZXcgUmVnRXhwKCJeIitNKyIqKFs+K35dfCIrTSsiKSIrTSsiKiIpLFU9bmV3IFJlZ0V4cChNKyJ8PiIpLFg9bmV3IFJlZ0V4cChGKSxWPW5ldyBSZWdFeHAoIl4iK0krIiQiKSxHPXtJRDpuZXcgUmVnRXhwKCJeIygiK0krIikiKSxDTEFTUzpuZXcgUmVnRXhwKCJeXFwuKCIrSSsiKSIpLFRBRzpuZXcgUmVnRXhwKCJeKCIrSSsifFsqXSkiKSxBVFRSOm5ldyBSZWdFeHAoIl4iK1cpLFBTRVVETzpuZXcgUmVnRXhwKCJeIitGKSxDSElMRDpuZXcgUmVnRXhwKCJeOihvbmx5fGZpcnN0fGxhc3R8bnRofG50aC1sYXN0KS0oY2hpbGR8b2YtdHlwZSkoPzpcXCgiK00rIiooZXZlbnxvZGR8KChbKy1dfCkoXFxkKilufCkiK00rIiooPzooWystXXwpIitNKyIqKFxcZCspfCkpIitNKyIqXFwpfCkiLCJpIiksYm9vbDpuZXcgUmVnRXhwKCJeKD86IitSKyIpJCIsImkiKSxuZWVkc0NvbnRleHQ6bmV3IFJlZ0V4cCgiXiIrTSsiKls+K35dfDooZXZlbnxvZGR8ZXF8Z3R8bHR8bnRofGZpcnN0fGxhc3QpKD86XFwoIitNKyIqKCg/Oi1cXGQpP1xcZCopIitNKyIqXFwpfCkoPz1bXi1dfCQpIiwiaSIpfSxZPS9IVE1MJC9pLFE9L14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxKPS9eaFxkJC9pLEs9L15bXntdK1x7XHMqXFtuYXRpdmUgXHcvLFo9L14oPzojKFtcdy1dKyl8KFx3Kyl8XC4oW1x3LV0rKSkkLyxlZT0vWyt+XS8sdGU9bmV3IFJlZ0V4cCgiXFxcXFtcXGRhLWZBLUZdezEsNn0iK00rIj98XFxcXChbXlxcclxcblxcZl0pIiwiZyIpLG5lPWZ1bmN0aW9uKGUsdCl7dmFyIG49IjB4IitlLnNsaWNlKDEpLTY1NTM2O3JldHVybiB0fHwobjwwP1N0cmluZy5mcm9tQ2hhckNvZGUobis2NTUzNik6U3RyaW5nLmZyb21DaGFyQ29kZShuPj4xMHw1NTI5NiwxMDIzJm58NTYzMjApKX0scmU9LyhbXDAtXHgxZlx4N2ZdfF4tP1xkKXxeLSR8W15cMC1ceDFmXHg3Zi1cdUZGRkZcdy1dL2csaWU9ZnVuY3Rpb24oZSx0KXtyZXR1cm4gdD8iXDAiPT09ZT8iXHVmZmZkIjplLnNsaWNlKDAsLTEpKyJcXCIrZS5jaGFyQ29kZUF0KGUubGVuZ3RoLTEpLnRvU3RyaW5nKDE2KSsiICI6IlxcIitlfSxvZT1mdW5jdGlvbigpe1QoKX0sYWU9YmUoZnVuY3Rpb24oZSl7cmV0dXJuITA9PT1lLmRpc2FibGVkJiYiZmllbGRzZXQiPT09ZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpfSx7ZGlyOiJwYXJlbnROb2RlIixuZXh0OiJsZWdlbmQifSk7dHJ5e0guYXBwbHkodD1PLmNhbGwocC5jaGlsZE5vZGVzKSxwLmNoaWxkTm9kZXMpLHRbcC5jaGlsZE5vZGVzLmxlbmd0aF0ubm9kZVR5cGV9Y2F0Y2goZSl7SD17YXBwbHk6dC5sZW5ndGg/ZnVuY3Rpb24oZSx0KXtMLmFwcGx5KGUsTy5jYWxsKHQpKX06ZnVuY3Rpb24oZSx0KXt2YXIgbj1lLmxlbmd0aCxyPTA7d2hpbGUoZVtuKytdPXRbcisrXSk7ZS5sZW5ndGg9bi0xfX19ZnVuY3Rpb24gc2UodCxlLG4scil7dmFyIGksbyxhLHMsdSxsLGMsZj1lJiZlLm93bmVyRG9jdW1lbnQscD1lP2Uubm9kZVR5cGU6OTtpZihuPW58fFtdLCJzdHJpbmciIT10eXBlb2YgdHx8IXR8fDEhPT1wJiY5IT09cCYmMTEhPT1wKXJldHVybiBuO2lmKCFyJiYoVChlKSxlPWV8fEMsRSkpe2lmKDExIT09cCYmKHU9Wi5leGVjKHQpKSlpZihpPXVbMV0pe2lmKDk9PT1wKXtpZighKGE9ZS5nZXRFbGVtZW50QnlJZChpKSkpcmV0dXJuIG47aWYoYS5pZD09PWkpcmV0dXJuIG4ucHVzaChhKSxufWVsc2UgaWYoZiYmKGE9Zi5nZXRFbGVtZW50QnlJZChpKSkmJnkoZSxhKSYmYS5pZD09PWkpcmV0dXJuIG4ucHVzaChhKSxufWVsc2V7aWYodVsyXSlyZXR1cm4gSC5hcHBseShuLGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUodCkpLG47aWYoKGk9dVszXSkmJmQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSYmZS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKXJldHVybiBILmFwcGx5KG4sZS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKGkpKSxufWlmKGQucXNhJiYhTlt0KyIgIl0mJighdnx8IXYudGVzdCh0KSkmJigxIT09cHx8Im9iamVjdCIhPT1lLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpKXtpZihjPXQsZj1lLDE9PT1wJiYoVS50ZXN0KHQpfHx6LnRlc3QodCkpKXsoZj1lZS50ZXN0KHQpJiZ5ZShlLnBhcmVudE5vZGUpfHxlKT09PWUmJmQuc2NvcGV8fCgocz1lLmdldEF0dHJpYnV0ZSgiaWQiKSk/cz1zLnJlcGxhY2UocmUsaWUpOmUuc2V0QXR0cmlidXRlKCJpZCIscz1TKSksbz0obD1oKHQpKS5sZW5ndGg7d2hpbGUoby0tKWxbb109KHM/IiMiK3M6IjpzY29wZSIpKyIgIit4ZShsW29dKTtjPWwuam9pbigiLCIpfXRyeXtyZXR1cm4gSC5hcHBseShuLGYucXVlcnlTZWxlY3RvckFsbChjKSksbn1jYXRjaChlKXtOKHQsITApfWZpbmFsbHl7cz09PVMmJmUucmVtb3ZlQXR0cmlidXRlKCJpZCIpfX19cmV0dXJuIGcodC5yZXBsYWNlKCQsIiQxIiksZSxuLHIpfWZ1bmN0aW9uIHVlKCl7dmFyIHI9W107cmV0dXJuIGZ1bmN0aW9uIGUodCxuKXtyZXR1cm4gci5wdXNoKHQrIiAiKT5iLmNhY2hlTGVuZ3RoJiZkZWxldGUgZVtyLnNoaWZ0KCldLGVbdCsiICJdPW59fWZ1bmN0aW9uIGxlKGUpe3JldHVybiBlW1NdPSEwLGV9ZnVuY3Rpb24gY2UoZSl7dmFyIHQ9Qy5jcmVhdGVFbGVtZW50KCJmaWVsZHNldCIpO3RyeXtyZXR1cm4hIWUodCl9Y2F0Y2goZSl7cmV0dXJuITF9ZmluYWxseXt0LnBhcmVudE5vZGUmJnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0KSx0PW51bGx9fWZ1bmN0aW9uIGZlKGUsdCl7dmFyIG49ZS5zcGxpdCgifCIpLHI9bi5sZW5ndGg7d2hpbGUoci0tKWIuYXR0ckhhbmRsZVtuW3JdXT10fWZ1bmN0aW9uIHBlKGUsdCl7dmFyIG49dCYmZSxyPW4mJjE9PT1lLm5vZGVUeXBlJiYxPT09dC5ub2RlVHlwZSYmZS5zb3VyY2VJbmRleC10LnNvdXJjZUluZGV4O2lmKHIpcmV0dXJuIHI7aWYobil3aGlsZShuPW4ubmV4dFNpYmxpbmcpaWYobj09PXQpcmV0dXJuLTE7cmV0dXJuIGU/MTotMX1mdW5jdGlvbiBkZSh0KXtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuImlucHV0Ij09PWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSYmZS50eXBlPT09dH19ZnVuY3Rpb24gaGUobil7cmV0dXJuIGZ1bmN0aW9uKGUpe3ZhciB0PWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtyZXR1cm4oImlucHV0Ij09PXR8fCJidXR0b24iPT09dCkmJmUudHlwZT09PW59fWZ1bmN0aW9uIGdlKHQpe3JldHVybiBmdW5jdGlvbihlKXtyZXR1cm4iZm9ybSJpbiBlP2UucGFyZW50Tm9kZSYmITE9PT1lLmRpc2FibGVkPyJsYWJlbCJpbiBlPyJsYWJlbCJpbiBlLnBhcmVudE5vZGU/ZS5wYXJlbnROb2RlLmRpc2FibGVkPT09dDplLmRpc2FibGVkPT09dDplLmlzRGlzYWJsZWQ9PT10fHxlLmlzRGlzYWJsZWQhPT0hdCYmYWUoZSk9PT10OmUuZGlzYWJsZWQ9PT10OiJsYWJlbCJpbiBlJiZlLmRpc2FibGVkPT09dH19ZnVuY3Rpb24gdmUoYSl7cmV0dXJuIGxlKGZ1bmN0aW9uKG8pe3JldHVybiBvPStvLGxlKGZ1bmN0aW9uKGUsdCl7dmFyIG4scj1hKFtdLGUubGVuZ3RoLG8pLGk9ci5sZW5ndGg7d2hpbGUoaS0tKWVbbj1yW2ldXSYmKGVbbl09ISh0W25dPWVbbl0pKX0pfSl9ZnVuY3Rpb24geWUoZSl7cmV0dXJuIGUmJiJ1bmRlZmluZWQiIT10eXBlb2YgZS5nZXRFbGVtZW50c0J5VGFnTmFtZSYmZX1mb3IoZSBpbiBkPXNlLnN1cHBvcnQ9e30saT1zZS5pc1hNTD1mdW5jdGlvbihlKXt2YXIgdD1lJiZlLm5hbWVzcGFjZVVSSSxuPWUmJihlLm93bmVyRG9jdW1lbnR8fGUpLmRvY3VtZW50RWxlbWVudDtyZXR1cm4hWS50ZXN0KHR8fG4mJm4ubm9kZU5hbWV8fCJIVE1MIil9LFQ9c2Uuc2V0RG9jdW1lbnQ9ZnVuY3Rpb24oZSl7dmFyIHQsbixyPWU/ZS5vd25lckRvY3VtZW50fHxlOnA7cmV0dXJuIHIhPUMmJjk9PT1yLm5vZGVUeXBlJiZyLmRvY3VtZW50RWxlbWVudCYmKGE9KEM9cikuZG9jdW1lbnRFbGVtZW50LEU9IWkoQykscCE9QyYmKG49Qy5kZWZhdWx0VmlldykmJm4udG9wIT09biYmKG4uYWRkRXZlbnRMaXN0ZW5lcj9uLmFkZEV2ZW50TGlzdGVuZXIoInVubG9hZCIsb2UsITEpOm4uYXR0YWNoRXZlbnQmJm4uYXR0YWNoRXZlbnQoIm9udW5sb2FkIixvZSkpLGQuc2NvcGU9Y2UoZnVuY3Rpb24oZSl7cmV0dXJuIGEuYXBwZW5kQ2hpbGQoZSkuYXBwZW5kQ2hpbGQoQy5jcmVhdGVFbGVtZW50KCJkaXYiKSksInVuZGVmaW5lZCIhPXR5cGVvZiBlLnF1ZXJ5U2VsZWN0b3JBbGwmJiFlLnF1ZXJ5U2VsZWN0b3JBbGwoIjpzY29wZSBmaWVsZHNldCBkaXYiKS5sZW5ndGh9KSxkLmF0dHJpYnV0ZXM9Y2UoZnVuY3Rpb24oZSl7cmV0dXJuIGUuY2xhc3NOYW1lPSJpIiwhZS5nZXRBdHRyaWJ1dGUoImNsYXNzTmFtZSIpfSksZC5nZXRFbGVtZW50c0J5VGFnTmFtZT1jZShmdW5jdGlvbihlKXtyZXR1cm4gZS5hcHBlbmRDaGlsZChDLmNyZWF0ZUNvbW1lbnQoIiIpKSwhZS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpLmxlbmd0aH0pLGQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZT1LLnRlc3QoQy5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKSxkLmdldEJ5SWQ9Y2UoZnVuY3Rpb24oZSl7cmV0dXJuIGEuYXBwZW5kQ2hpbGQoZSkuaWQ9UywhQy5nZXRFbGVtZW50c0J5TmFtZXx8IUMuZ2V0RWxlbWVudHNCeU5hbWUoUykubGVuZ3RofSksZC5nZXRCeUlkPyhiLmZpbHRlci5JRD1mdW5jdGlvbihlKXt2YXIgdD1lLnJlcGxhY2UodGUsbmUpO3JldHVybiBmdW5jdGlvbihlKXtyZXR1cm4gZS5nZXRBdHRyaWJ1dGUoImlkIik9PT10fX0sYi5maW5kLklEPWZ1bmN0aW9uKGUsdCl7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiB0LmdldEVsZW1lbnRCeUlkJiZFKXt2YXIgbj10LmdldEVsZW1lbnRCeUlkKGUpO3JldHVybiBuP1tuXTpbXX19KTooYi5maWx0ZXIuSUQ9ZnVuY3Rpb24oZSl7dmFyIG49ZS5yZXBsYWNlKHRlLG5lKTtyZXR1cm4gZnVuY3Rpb24oZSl7dmFyIHQ9InVuZGVmaW5lZCIhPXR5cGVvZiBlLmdldEF0dHJpYnV0ZU5vZGUmJmUuZ2V0QXR0cmlidXRlTm9kZSgiaWQiKTtyZXR1cm4gdCYmdC52YWx1ZT09PW59fSxiLmZpbmQuSUQ9ZnVuY3Rpb24oZSx0KXtpZigidW5kZWZpbmVkIiE9dHlwZW9mIHQuZ2V0RWxlbWVudEJ5SWQmJkUpe3ZhciBuLHIsaSxvPXQuZ2V0RWxlbWVudEJ5SWQoZSk7aWYobyl7aWYoKG49by5nZXRBdHRyaWJ1dGVOb2RlKCJpZCIpKSYmbi52YWx1ZT09PWUpcmV0dXJuW29dO2k9dC5nZXRFbGVtZW50c0J5TmFtZShlKSxyPTA7d2hpbGUobz1pW3IrK10paWYoKG49by5nZXRBdHRyaWJ1dGVOb2RlKCJpZCIpKSYmbi52YWx1ZT09PWUpcmV0dXJuW29dfXJldHVybltdfX0pLGIuZmluZC5UQUc9ZC5nZXRFbGVtZW50c0J5VGFnTmFtZT9mdW5jdGlvbihlLHQpe3JldHVybiJ1bmRlZmluZWQiIT10eXBlb2YgdC5nZXRFbGVtZW50c0J5VGFnTmFtZT90LmdldEVsZW1lbnRzQnlUYWdOYW1lKGUpOmQucXNhP3QucXVlcnlTZWxlY3RvckFsbChlKTp2b2lkIDB9OmZ1bmN0aW9uKGUsdCl7dmFyIG4scj1bXSxpPTAsbz10LmdldEVsZW1lbnRzQnlUYWdOYW1lKGUpO2lmKCIqIj09PWUpe3doaWxlKG49b1tpKytdKTE9PT1uLm5vZGVUeXBlJiZyLnB1c2gobik7cmV0dXJuIHJ9cmV0dXJuIG99LGIuZmluZC5DTEFTUz1kLmdldEVsZW1lbnRzQnlDbGFzc05hbWUmJmZ1bmN0aW9uKGUsdCl7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiB0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUmJkUpcmV0dXJuIHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShlKX0scz1bXSx2PVtdLChkLnFzYT1LLnRlc3QoQy5xdWVyeVNlbGVjdG9yQWxsKSkmJihjZShmdW5jdGlvbihlKXt2YXIgdDthLmFwcGVuZENoaWxkKGUpLmlubmVySFRNTD0iPGEgaWQ9JyIrUysiJz48L2E+PHNlbGVjdCBpZD0nIitTKyItXHJcXCcgbXNhbGxvd2NhcHR1cmU9Jyc+PG9wdGlvbiBzZWxlY3RlZD0nJz48L29wdGlvbj48L3NlbGVjdD4iLGUucXVlcnlTZWxlY3RvckFsbCgiW21zYWxsb3djYXB0dXJlXj0nJ10iKS5sZW5ndGgmJnYucHVzaCgiWypeJF09IitNKyIqKD86Jyd8XCJcIikiKSxlLnF1ZXJ5U2VsZWN0b3JBbGwoIltzZWxlY3RlZF0iKS5sZW5ndGh8fHYucHVzaCgiXFxbIitNKyIqKD86dmFsdWV8IitSKyIpIiksZS5xdWVyeVNlbGVjdG9yQWxsKCJbaWR+PSIrUysiLV0iKS5sZW5ndGh8fHYucHVzaCgifj0iKSwodD1DLmNyZWF0ZUVsZW1lbnQoImlucHV0IikpLnNldEF0dHJpYnV0ZSgibmFtZSIsIiIpLGUuYXBwZW5kQ2hpbGQodCksZS5xdWVyeVNlbGVjdG9yQWxsKCJbbmFtZT0nJ10iKS5sZW5ndGh8fHYucHVzaCgiXFxbIitNKyIqbmFtZSIrTSsiKj0iK00rIiooPzonJ3xcIlwiKSIpLGUucXVlcnlTZWxlY3RvckFsbCgiOmNoZWNrZWQiKS5sZW5ndGh8fHYucHVzaCgiOmNoZWNrZWQiKSxlLnF1ZXJ5U2VsZWN0b3JBbGwoImEjIitTKyIrKiIpLmxlbmd0aHx8di5wdXNoKCIuIy4rWyt+XSIpLGUucXVlcnlTZWxlY3RvckFsbCgiXFxcZiIpLHYucHVzaCgiW1xcclxcblxcZl0iKX0pLGNlKGZ1bmN0aW9uKGUpe2UuaW5uZXJIVE1MPSI8YSBocmVmPScnIGRpc2FibGVkPSdkaXNhYmxlZCc+PC9hPjxzZWxlY3QgZGlzYWJsZWQ9J2Rpc2FibGVkJz48b3B0aW9uLz48L3NlbGVjdD4iO3ZhciB0PUMuY3JlYXRlRWxlbWVudCgiaW5wdXQiKTt0LnNldEF0dHJpYnV0ZSgidHlwZSIsImhpZGRlbiIpLGUuYXBwZW5kQ2hpbGQodCkuc2V0QXR0cmlidXRlKCJuYW1lIiwiRCIpLGUucXVlcnlTZWxlY3RvckFsbCgiW25hbWU9ZF0iKS5sZW5ndGgmJnYucHVzaCgibmFtZSIrTSsiKlsqXiR8IX5dPz0iKSwyIT09ZS5xdWVyeVNlbGVjdG9yQWxsKCI6ZW5hYmxlZCIpLmxlbmd0aCYmdi5wdXNoKCI6ZW5hYmxlZCIsIjpkaXNhYmxlZCIpLGEuYXBwZW5kQ2hpbGQoZSkuZGlzYWJsZWQ9ITAsMiE9PWUucXVlcnlTZWxlY3RvckFsbCgiOmRpc2FibGVkIikubGVuZ3RoJiZ2LnB1c2goIjplbmFibGVkIiwiOmRpc2FibGVkIiksZS5xdWVyeVNlbGVjdG9yQWxsKCIqLDp4Iiksdi5wdXNoKCIsLio6Iil9KSksKGQubWF0Y2hlc1NlbGVjdG9yPUsudGVzdChjPWEubWF0Y2hlc3x8YS53ZWJraXRNYXRjaGVzU2VsZWN0b3J8fGEubW96TWF0Y2hlc1NlbGVjdG9yfHxhLm9NYXRjaGVzU2VsZWN0b3J8fGEubXNNYXRjaGVzU2VsZWN0b3IpKSYmY2UoZnVuY3Rpb24oZSl7ZC5kaXNjb25uZWN0ZWRNYXRjaD1jLmNhbGwoZSwiKiIpLGMuY2FsbChlLCJbcyE9JyddOngiKSxzLnB1c2goIiE9IixGKX0pLHY9di5sZW5ndGgmJm5ldyBSZWdFeHAodi5qb2luKCJ8IikpLHM9cy5sZW5ndGgmJm5ldyBSZWdFeHAocy5qb2luKCJ8IikpLHQ9Sy50ZXN0KGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24pLHk9dHx8Sy50ZXN0KGEuY29udGFpbnMpP2Z1bmN0aW9uKGUsdCl7dmFyIG49OT09PWUubm9kZVR5cGU/ZS5kb2N1bWVudEVsZW1lbnQ6ZSxyPXQmJnQucGFyZW50Tm9kZTtyZXR1cm4gZT09PXJ8fCEoIXJ8fDEhPT1yLm5vZGVUeXBlfHwhKG4uY29udGFpbnM/bi5jb250YWlucyhyKTplLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uJiYxNiZlLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKHIpKSl9OmZ1bmN0aW9uKGUsdCl7aWYodCl3aGlsZSh0PXQucGFyZW50Tm9kZSlpZih0PT09ZSlyZXR1cm4hMDtyZXR1cm4hMX0saj10P2Z1bmN0aW9uKGUsdCl7aWYoZT09PXQpcmV0dXJuIGw9ITAsMDt2YXIgbj0hZS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbi0hdC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbjtyZXR1cm4gbnx8KDEmKG49KGUub3duZXJEb2N1bWVudHx8ZSk9PSh0Lm93bmVyRG9jdW1lbnR8fHQpP2UuY29tcGFyZURvY3VtZW50UG9zaXRpb24odCk6MSl8fCFkLnNvcnREZXRhY2hlZCYmdC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihlKT09PW4/ZT09Q3x8ZS5vd25lckRvY3VtZW50PT1wJiZ5KHAsZSk/LTE6dD09Q3x8dC5vd25lckRvY3VtZW50PT1wJiZ5KHAsdCk/MTp1P1AodSxlKS1QKHUsdCk6MDo0Jm4/LTE6MSl9OmZ1bmN0aW9uKGUsdCl7aWYoZT09PXQpcmV0dXJuIGw9ITAsMDt2YXIgbixyPTAsaT1lLnBhcmVudE5vZGUsbz10LnBhcmVudE5vZGUsYT1bZV0scz1bdF07aWYoIWl8fCFvKXJldHVybiBlPT1DPy0xOnQ9PUM/MTppPy0xOm8/MTp1P1AodSxlKS1QKHUsdCk6MDtpZihpPT09bylyZXR1cm4gcGUoZSx0KTtuPWU7d2hpbGUobj1uLnBhcmVudE5vZGUpYS51bnNoaWZ0KG4pO249dDt3aGlsZShuPW4ucGFyZW50Tm9kZSlzLnVuc2hpZnQobik7d2hpbGUoYVtyXT09PXNbcl0pcisrO3JldHVybiByP3BlKGFbcl0sc1tyXSk6YVtyXT09cD8tMTpzW3JdPT1wPzE6MH0pLEN9LHNlLm1hdGNoZXM9ZnVuY3Rpb24oZSx0KXtyZXR1cm4gc2UoZSxudWxsLG51bGwsdCl9LHNlLm1hdGNoZXNTZWxlY3Rvcj1mdW5jdGlvbihlLHQpe2lmKFQoZSksZC5tYXRjaGVzU2VsZWN0b3ImJkUmJiFOW3QrIiAiXSYmKCFzfHwhcy50ZXN0KHQpKSYmKCF2fHwhdi50ZXN0KHQpKSl0cnl7dmFyIG49Yy5jYWxsKGUsdCk7aWYobnx8ZC5kaXNjb25uZWN0ZWRNYXRjaHx8ZS5kb2N1bWVudCYmMTEhPT1lLmRvY3VtZW50Lm5vZGVUeXBlKXJldHVybiBufWNhdGNoKGUpe04odCwhMCl9cmV0dXJuIDA8c2UodCxDLG51bGwsW2VdKS5sZW5ndGh9LHNlLmNvbnRhaW5zPWZ1bmN0aW9uKGUsdCl7cmV0dXJuKGUub3duZXJEb2N1bWVudHx8ZSkhPUMmJlQoZSkseShlLHQpfSxzZS5hdHRyPWZ1bmN0aW9uKGUsdCl7KGUub3duZXJEb2N1bWVudHx8ZSkhPUMmJlQoZSk7dmFyIG49Yi5hdHRySGFuZGxlW3QudG9Mb3dlckNhc2UoKV0scj1uJiZELmNhbGwoYi5hdHRySGFuZGxlLHQudG9Mb3dlckNhc2UoKSk/bihlLHQsIUUpOnZvaWQgMDtyZXR1cm4gdm9pZCAwIT09cj9yOmQuYXR0cmlidXRlc3x8IUU/ZS5nZXRBdHRyaWJ1dGUodCk6KHI9ZS5nZXRBdHRyaWJ1dGVOb2RlKHQpKSYmci5zcGVjaWZpZWQ/ci52YWx1ZTpudWxsfSxzZS5lc2NhcGU9ZnVuY3Rpb24oZSl7cmV0dXJuKGUrIiIpLnJlcGxhY2UocmUsaWUpfSxzZS5lcnJvcj1mdW5jdGlvbihlKXt0aHJvdyBuZXcgRXJyb3IoIlN5bnRheCBlcnJvciwgdW5yZWNvZ25pemVkIGV4cHJlc3Npb246ICIrZSl9LHNlLnVuaXF1ZVNvcnQ9ZnVuY3Rpb24oZSl7dmFyIHQsbj1bXSxyPTAsaT0wO2lmKGw9IWQuZGV0ZWN0RHVwbGljYXRlcyx1PSFkLnNvcnRTdGFibGUmJmUuc2xpY2UoMCksZS5zb3J0KGopLGwpe3doaWxlKHQ9ZVtpKytdKXQ9PT1lW2ldJiYocj1uLnB1c2goaSkpO3doaWxlKHItLSllLnNwbGljZShuW3JdLDEpfXJldHVybiB1PW51bGwsZX0sbz1zZS5nZXRUZXh0PWZ1bmN0aW9uKGUpe3ZhciB0LG49IiIscj0wLGk9ZS5ub2RlVHlwZTtpZihpKXtpZigxPT09aXx8OT09PWl8fDExPT09aSl7aWYoInN0cmluZyI9PXR5cGVvZiBlLnRleHRDb250ZW50KXJldHVybiBlLnRleHRDb250ZW50O2ZvcihlPWUuZmlyc3RDaGlsZDtlO2U9ZS5uZXh0U2libGluZyluKz1vKGUpfWVsc2UgaWYoMz09PWl8fDQ9PT1pKXJldHVybiBlLm5vZGVWYWx1ZX1lbHNlIHdoaWxlKHQ9ZVtyKytdKW4rPW8odCk7cmV0dXJuIG59LChiPXNlLnNlbGVjdG9ycz17Y2FjaGVMZW5ndGg6NTAsY3JlYXRlUHNldWRvOmxlLG1hdGNoOkcsYXR0ckhhbmRsZTp7fSxmaW5kOnt9LHJlbGF0aXZlOnsiPiI6e2RpcjoicGFyZW50Tm9kZSIsZmlyc3Q6ITB9LCIgIjp7ZGlyOiJwYXJlbnROb2RlIn0sIisiOntkaXI6InByZXZpb3VzU2libGluZyIsZmlyc3Q6ITB9LCJ+Ijp7ZGlyOiJwcmV2aW91c1NpYmxpbmcifX0scHJlRmlsdGVyOntBVFRSOmZ1bmN0aW9uKGUpe3JldHVybiBlWzFdPWVbMV0ucmVwbGFjZSh0ZSxuZSksZVszXT0oZVszXXx8ZVs0XXx8ZVs1XXx8IiIpLnJlcGxhY2UodGUsbmUpLCJ+PSI9PT1lWzJdJiYoZVszXT0iICIrZVszXSsiICIpLGUuc2xpY2UoMCw0KX0sQ0hJTEQ6ZnVuY3Rpb24oZSl7cmV0dXJuIGVbMV09ZVsxXS50b0xvd2VyQ2FzZSgpLCJudGgiPT09ZVsxXS5zbGljZSgwLDMpPyhlWzNdfHxzZS5lcnJvcihlWzBdKSxlWzRdPSsoZVs0XT9lWzVdKyhlWzZdfHwxKToyKigiZXZlbiI9PT1lWzNdfHwib2RkIj09PWVbM10pKSxlWzVdPSsoZVs3XStlWzhdfHwib2RkIj09PWVbM10pKTplWzNdJiZzZS5lcnJvcihlWzBdKSxlfSxQU0VVRE86ZnVuY3Rpb24oZSl7dmFyIHQsbj0hZVs2XSYmZVsyXTtyZXR1cm4gRy5DSElMRC50ZXN0KGVbMF0pP251bGw6KGVbM10/ZVsyXT1lWzRdfHxlWzVdfHwiIjpuJiZYLnRlc3QobikmJih0PWgobiwhMCkpJiYodD1uLmluZGV4T2YoIikiLG4ubGVuZ3RoLXQpLW4ubGVuZ3RoKSYmKGVbMF09ZVswXS5zbGljZSgwLHQpLGVbMl09bi5zbGljZSgwLHQpKSxlLnNsaWNlKDAsMykpfX0sZmlsdGVyOntUQUc6ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5yZXBsYWNlKHRlLG5lKS50b0xvd2VyQ2FzZSgpO3JldHVybiIqIj09PWU/ZnVuY3Rpb24oKXtyZXR1cm4hMH06ZnVuY3Rpb24oZSl7cmV0dXJuIGUubm9kZU5hbWUmJmUubm9kZU5hbWUudG9Mb3dlckNhc2UoKT09PXR9fSxDTEFTUzpmdW5jdGlvbihlKXt2YXIgdD1tW2UrIiAiXTtyZXR1cm4gdHx8KHQ9bmV3IFJlZ0V4cCgiKF58IitNKyIpIitlKyIoIitNKyJ8JCkiKSkmJm0oZSxmdW5jdGlvbihlKXtyZXR1cm4gdC50ZXN0KCJzdHJpbmciPT10eXBlb2YgZS5jbGFzc05hbWUmJmUuY2xhc3NOYW1lfHwidW5kZWZpbmVkIiE9dHlwZW9mIGUuZ2V0QXR0cmlidXRlJiZlLmdldEF0dHJpYnV0ZSgiY2xhc3MiKXx8IiIpfSl9LEFUVFI6ZnVuY3Rpb24obixyLGkpe3JldHVybiBmdW5jdGlvbihlKXt2YXIgdD1zZS5hdHRyKGUsbik7cmV0dXJuIG51bGw9PXQ/IiE9Ij09PXI6IXJ8fCh0Kz0iIiwiPSI9PT1yP3Q9PT1pOiIhPSI9PT1yP3QhPT1pOiJePSI9PT1yP2kmJjA9PT10LmluZGV4T2YoaSk6Iio9Ij09PXI/aSYmLTE8dC5pbmRleE9mKGkpOiIkPSI9PT1yP2kmJnQuc2xpY2UoLWkubGVuZ3RoKT09PWk6In49Ij09PXI/LTE8KCIgIit0LnJlcGxhY2UoQiwiICIpKyIgIikuaW5kZXhPZihpKToifD0iPT09ciYmKHQ9PT1pfHx0LnNsaWNlKDAsaS5sZW5ndGgrMSk9PT1pKyItIikpfX0sQ0hJTEQ6ZnVuY3Rpb24oaCxlLHQsZyx2KXt2YXIgeT0ibnRoIiE9PWguc2xpY2UoMCwzKSxtPSJsYXN0IiE9PWguc2xpY2UoLTQpLHg9Im9mLXR5cGUiPT09ZTtyZXR1cm4gMT09PWcmJjA9PT12P2Z1bmN0aW9uKGUpe3JldHVybiEhZS5wYXJlbnROb2RlfTpmdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvLGEscyx1LGw9eSE9PW0/Im5leHRTaWJsaW5nIjoicHJldmlvdXNTaWJsaW5nIixjPWUucGFyZW50Tm9kZSxmPXgmJmUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSxwPSFuJiYheCxkPSExO2lmKGMpe2lmKHkpe3doaWxlKGwpe2E9ZTt3aGlsZShhPWFbbF0paWYoeD9hLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk9PT1mOjE9PT1hLm5vZGVUeXBlKXJldHVybiExO3U9bD0ib25seSI9PT1oJiYhdSYmIm5leHRTaWJsaW5nIn1yZXR1cm4hMH1pZih1PVttP2MuZmlyc3RDaGlsZDpjLmxhc3RDaGlsZF0sbSYmcCl7ZD0ocz0ocj0oaT0obz0oYT1jKVtTXXx8KGFbU109e30pKVthLnVuaXF1ZUlEXXx8KG9bYS51bmlxdWVJRF09e30pKVtoXXx8W10pWzBdPT09ayYmclsxXSkmJnJbMl0sYT1zJiZjLmNoaWxkTm9kZXNbc107d2hpbGUoYT0rK3MmJmEmJmFbbF18fChkPXM9MCl8fHUucG9wKCkpaWYoMT09PWEubm9kZVR5cGUmJisrZCYmYT09PWUpe2lbaF09W2sscyxkXTticmVha319ZWxzZSBpZihwJiYoZD1zPShyPShpPShvPShhPWUpW1NdfHwoYVtTXT17fSkpW2EudW5pcXVlSURdfHwob1thLnVuaXF1ZUlEXT17fSkpW2hdfHxbXSlbMF09PT1rJiZyWzFdKSwhMT09PWQpd2hpbGUoYT0rK3MmJmEmJmFbbF18fChkPXM9MCl8fHUucG9wKCkpaWYoKHg/YS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpPT09ZjoxPT09YS5ub2RlVHlwZSkmJisrZCYmKHAmJigoaT0obz1hW1NdfHwoYVtTXT17fSkpW2EudW5pcXVlSURdfHwob1thLnVuaXF1ZUlEXT17fSkpW2hdPVtrLGRdKSxhPT09ZSkpYnJlYWs7cmV0dXJuKGQtPXYpPT09Z3x8ZCVnPT0wJiYwPD1kL2d9fX0sUFNFVURPOmZ1bmN0aW9uKGUsbyl7dmFyIHQsYT1iLnBzZXVkb3NbZV18fGIuc2V0RmlsdGVyc1tlLnRvTG93ZXJDYXNlKCldfHxzZS5lcnJvcigidW5zdXBwb3J0ZWQgcHNldWRvOiAiK2UpO3JldHVybiBhW1NdP2Eobyk6MTxhLmxlbmd0aD8odD1bZSxlLCIiLG9dLGIuc2V0RmlsdGVycy5oYXNPd25Qcm9wZXJ0eShlLnRvTG93ZXJDYXNlKCkpP2xlKGZ1bmN0aW9uKGUsdCl7dmFyIG4scj1hKGUsbyksaT1yLmxlbmd0aDt3aGlsZShpLS0pZVtuPVAoZSxyW2ldKV09ISh0W25dPXJbaV0pfSk6ZnVuY3Rpb24oZSl7cmV0dXJuIGEoZSwwLHQpfSk6YX19LHBzZXVkb3M6e25vdDpsZShmdW5jdGlvbihlKXt2YXIgcj1bXSxpPVtdLHM9ZihlLnJlcGxhY2UoJCwiJDEiKSk7cmV0dXJuIHNbU10/bGUoZnVuY3Rpb24oZSx0LG4scil7dmFyIGksbz1zKGUsbnVsbCxyLFtdKSxhPWUubGVuZ3RoO3doaWxlKGEtLSkoaT1vW2FdKSYmKGVbYV09ISh0W2FdPWkpKX0pOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gclswXT1lLHMocixudWxsLG4saSksclswXT1udWxsLCFpLnBvcCgpfX0pLGhhczpsZShmdW5jdGlvbih0KXtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIDA8c2UodCxlKS5sZW5ndGh9fSksY29udGFpbnM6bGUoZnVuY3Rpb24odCl7cmV0dXJuIHQ9dC5yZXBsYWNlKHRlLG5lKSxmdW5jdGlvbihlKXtyZXR1cm4tMTwoZS50ZXh0Q29udGVudHx8byhlKSkuaW5kZXhPZih0KX19KSxsYW5nOmxlKGZ1bmN0aW9uKG4pe3JldHVybiBWLnRlc3Qobnx8IiIpfHxzZS5lcnJvcigidW5zdXBwb3J0ZWQgbGFuZzogIituKSxuPW4ucmVwbGFjZSh0ZSxuZSkudG9Mb3dlckNhc2UoKSxmdW5jdGlvbihlKXt2YXIgdDtkb3tpZih0PUU/ZS5sYW5nOmUuZ2V0QXR0cmlidXRlKCJ4bWw6bGFuZyIpfHxlLmdldEF0dHJpYnV0ZSgibGFuZyIpKXJldHVybih0PXQudG9Mb3dlckNhc2UoKSk9PT1ufHwwPT09dC5pbmRleE9mKG4rIi0iKX13aGlsZSgoZT1lLnBhcmVudE5vZGUpJiYxPT09ZS5ub2RlVHlwZSk7cmV0dXJuITF9fSksdGFyZ2V0OmZ1bmN0aW9uKGUpe3ZhciB0PW4ubG9jYXRpb24mJm4ubG9jYXRpb24uaGFzaDtyZXR1cm4gdCYmdC5zbGljZSgxKT09PWUuaWR9LHJvb3Q6ZnVuY3Rpb24oZSl7cmV0dXJuIGU9PT1hfSxmb2N1czpmdW5jdGlvbihlKXtyZXR1cm4gZT09PUMuYWN0aXZlRWxlbWVudCYmKCFDLmhhc0ZvY3VzfHxDLmhhc0ZvY3VzKCkpJiYhIShlLnR5cGV8fGUuaHJlZnx8fmUudGFiSW5kZXgpfSxlbmFibGVkOmdlKCExKSxkaXNhYmxlZDpnZSghMCksY2hlY2tlZDpmdW5jdGlvbihlKXt2YXIgdD1lLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7cmV0dXJuImlucHV0Ij09PXQmJiEhZS5jaGVja2VkfHwib3B0aW9uIj09PXQmJiEhZS5zZWxlY3RlZH0sc2VsZWN0ZWQ6ZnVuY3Rpb24oZSl7cmV0dXJuIGUucGFyZW50Tm9kZSYmZS5wYXJlbnROb2RlLnNlbGVjdGVkSW5kZXgsITA9PT1lLnNlbGVjdGVkfSxlbXB0eTpmdW5jdGlvbihlKXtmb3IoZT1lLmZpcnN0Q2hpbGQ7ZTtlPWUubmV4dFNpYmxpbmcpaWYoZS5ub2RlVHlwZTw2KXJldHVybiExO3JldHVybiEwfSxwYXJlbnQ6ZnVuY3Rpb24oZSl7cmV0dXJuIWIucHNldWRvcy5lbXB0eShlKX0saGVhZGVyOmZ1bmN0aW9uKGUpe3JldHVybiBKLnRlc3QoZS5ub2RlTmFtZSl9LGlucHV0OmZ1bmN0aW9uKGUpe3JldHVybiBRLnRlc3QoZS5ub2RlTmFtZSl9LGJ1dHRvbjpmdW5jdGlvbihlKXt2YXIgdD1lLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7cmV0dXJuImlucHV0Ij09PXQmJiJidXR0b24iPT09ZS50eXBlfHwiYnV0dG9uIj09PXR9LHRleHQ6ZnVuY3Rpb24oZSl7dmFyIHQ7cmV0dXJuImlucHV0Ij09PWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSYmInRleHQiPT09ZS50eXBlJiYobnVsbD09KHQ9ZS5nZXRBdHRyaWJ1dGUoInR5cGUiKSl8fCJ0ZXh0Ij09PXQudG9Mb3dlckNhc2UoKSl9LGZpcnN0OnZlKGZ1bmN0aW9uKCl7cmV0dXJuWzBdfSksbGFzdDp2ZShmdW5jdGlvbihlLHQpe3JldHVyblt0LTFdfSksZXE6dmUoZnVuY3Rpb24oZSx0LG4pe3JldHVybltuPDA/bit0Om5dfSksZXZlbjp2ZShmdW5jdGlvbihlLHQpe2Zvcih2YXIgbj0wO248dDtuKz0yKWUucHVzaChuKTtyZXR1cm4gZX0pLG9kZDp2ZShmdW5jdGlvbihlLHQpe2Zvcih2YXIgbj0xO248dDtuKz0yKWUucHVzaChuKTtyZXR1cm4gZX0pLGx0OnZlKGZ1bmN0aW9uKGUsdCxuKXtmb3IodmFyIHI9bjwwP24rdDp0PG4/dDpuOzA8PS0tcjspZS5wdXNoKHIpO3JldHVybiBlfSksZ3Q6dmUoZnVuY3Rpb24oZSx0LG4pe2Zvcih2YXIgcj1uPDA/bit0Om47KytyPHQ7KWUucHVzaChyKTtyZXR1cm4gZX0pfX0pLnBzZXVkb3MubnRoPWIucHNldWRvcy5lcSx7cmFkaW86ITAsY2hlY2tib3g6ITAsZmlsZTohMCxwYXNzd29yZDohMCxpbWFnZTohMH0pYi5wc2V1ZG9zW2VdPWRlKGUpO2ZvcihlIGlue3N1Ym1pdDohMCxyZXNldDohMH0pYi5wc2V1ZG9zW2VdPWhlKGUpO2Z1bmN0aW9uIG1lKCl7fWZ1bmN0aW9uIHhlKGUpe2Zvcih2YXIgdD0wLG49ZS5sZW5ndGgscj0iIjt0PG47dCsrKXIrPWVbdF0udmFsdWU7cmV0dXJuIHJ9ZnVuY3Rpb24gYmUocyxlLHQpe3ZhciB1PWUuZGlyLGw9ZS5uZXh0LGM9bHx8dSxmPXQmJiJwYXJlbnROb2RlIj09PWMscD1yKys7cmV0dXJuIGUuZmlyc3Q/ZnVuY3Rpb24oZSx0LG4pe3doaWxlKGU9ZVt1XSlpZigxPT09ZS5ub2RlVHlwZXx8ZilyZXR1cm4gcyhlLHQsbik7cmV0dXJuITF9OmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG8sYT1bayxwXTtpZihuKXt3aGlsZShlPWVbdV0paWYoKDE9PT1lLm5vZGVUeXBlfHxmKSYmcyhlLHQsbikpcmV0dXJuITB9ZWxzZSB3aGlsZShlPWVbdV0paWYoMT09PWUubm9kZVR5cGV8fGYpaWYoaT0obz1lW1NdfHwoZVtTXT17fSkpW2UudW5pcXVlSURdfHwob1tlLnVuaXF1ZUlEXT17fSksbCYmbD09PWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSllPWVbdV18fGU7ZWxzZXtpZigocj1pW2NdKSYmclswXT09PWsmJnJbMV09PT1wKXJldHVybiBhWzJdPXJbMl07aWYoKGlbY109YSlbMl09cyhlLHQsbikpcmV0dXJuITB9cmV0dXJuITF9fWZ1bmN0aW9uIHdlKGkpe3JldHVybiAxPGkubGVuZ3RoP2Z1bmN0aW9uKGUsdCxuKXt2YXIgcj1pLmxlbmd0aDt3aGlsZShyLS0paWYoIWlbcl0oZSx0LG4pKXJldHVybiExO3JldHVybiEwfTppWzBdfWZ1bmN0aW9uIFRlKGUsdCxuLHIsaSl7Zm9yKHZhciBvLGE9W10scz0wLHU9ZS5sZW5ndGgsbD1udWxsIT10O3M8dTtzKyspKG89ZVtzXSkmJihuJiYhbihvLHIsaSl8fChhLnB1c2gobyksbCYmdC5wdXNoKHMpKSk7cmV0dXJuIGF9ZnVuY3Rpb24gQ2UoZCxoLGcsdix5LGUpe3JldHVybiB2JiYhdltTXSYmKHY9Q2UodikpLHkmJiF5W1NdJiYoeT1DZSh5LGUpKSxsZShmdW5jdGlvbihlLHQsbixyKXt2YXIgaSxvLGEscz1bXSx1PVtdLGw9dC5sZW5ndGgsYz1lfHxmdW5jdGlvbihlLHQsbil7Zm9yKHZhciByPTAsaT10Lmxlbmd0aDtyPGk7cisrKXNlKGUsdFtyXSxuKTtyZXR1cm4gbn0oaHx8IioiLG4ubm9kZVR5cGU/W25dOm4sW10pLGY9IWR8fCFlJiZoP2M6VGUoYyxzLGQsbixyKSxwPWc/eXx8KGU/ZDpsfHx2KT9bXTp0OmY7aWYoZyYmZyhmLHAsbixyKSx2KXtpPVRlKHAsdSksdihpLFtdLG4sciksbz1pLmxlbmd0aDt3aGlsZShvLS0pKGE9aVtvXSkmJihwW3Vbb11dPSEoZlt1W29dXT1hKSl9aWYoZSl7aWYoeXx8ZCl7aWYoeSl7aT1bXSxvPXAubGVuZ3RoO3doaWxlKG8tLSkoYT1wW29dKSYmaS5wdXNoKGZbb109YSk7eShudWxsLHA9W10saSxyKX1vPXAubGVuZ3RoO3doaWxlKG8tLSkoYT1wW29dKSYmLTE8KGk9eT9QKGUsYSk6c1tvXSkmJihlW2ldPSEodFtpXT1hKSl9fWVsc2UgcD1UZShwPT09dD9wLnNwbGljZShsLHAubGVuZ3RoKTpwKSx5P3kobnVsbCx0LHAscik6SC5hcHBseSh0LHApfSl9ZnVuY3Rpb24gRWUoZSl7Zm9yKHZhciBpLHQsbixyPWUubGVuZ3RoLG89Yi5yZWxhdGl2ZVtlWzBdLnR5cGVdLGE9b3x8Yi5yZWxhdGl2ZVsiICJdLHM9bz8xOjAsdT1iZShmdW5jdGlvbihlKXtyZXR1cm4gZT09PWl9LGEsITApLGw9YmUoZnVuY3Rpb24oZSl7cmV0dXJuLTE8UChpLGUpfSxhLCEwKSxjPVtmdW5jdGlvbihlLHQsbil7dmFyIHI9IW8mJihufHx0IT09dyl8fCgoaT10KS5ub2RlVHlwZT91KGUsdCxuKTpsKGUsdCxuKSk7cmV0dXJuIGk9bnVsbCxyfV07czxyO3MrKylpZih0PWIucmVsYXRpdmVbZVtzXS50eXBlXSljPVtiZSh3ZShjKSx0KV07ZWxzZXtpZigodD1iLmZpbHRlcltlW3NdLnR5cGVdLmFwcGx5KG51bGwsZVtzXS5tYXRjaGVzKSlbU10pe2ZvcihuPSsrcztuPHI7bisrKWlmKGIucmVsYXRpdmVbZVtuXS50eXBlXSlicmVhaztyZXR1cm4gQ2UoMTxzJiZ3ZShjKSwxPHMmJnhlKGUuc2xpY2UoMCxzLTEpLmNvbmNhdCh7dmFsdWU6IiAiPT09ZVtzLTJdLnR5cGU/IioiOiIifSkpLnJlcGxhY2UoJCwiJDEiKSx0LHM8biYmRWUoZS5zbGljZShzLG4pKSxuPHImJkVlKGU9ZS5zbGljZShuKSksbjxyJiZ4ZShlKSl9Yy5wdXNoKHQpfXJldHVybiB3ZShjKX1yZXR1cm4gbWUucHJvdG90eXBlPWIuZmlsdGVycz1iLnBzZXVkb3MsYi5zZXRGaWx0ZXJzPW5ldyBtZSxoPXNlLnRva2VuaXplPWZ1bmN0aW9uKGUsdCl7dmFyIG4scixpLG8sYSxzLHUsbD14W2UrIiAiXTtpZihsKXJldHVybiB0PzA6bC5zbGljZSgwKTthPWUscz1bXSx1PWIucHJlRmlsdGVyO3doaWxlKGEpe2ZvcihvIGluIG4mJiEocj1fLmV4ZWMoYSkpfHwociYmKGE9YS5zbGljZShyWzBdLmxlbmd0aCl8fGEpLHMucHVzaChpPVtdKSksbj0hMSwocj16LmV4ZWMoYSkpJiYobj1yLnNoaWZ0KCksaS5wdXNoKHt2YWx1ZTpuLHR5cGU6clswXS5yZXBsYWNlKCQsIiAiKX0pLGE9YS5zbGljZShuLmxlbmd0aCkpLGIuZmlsdGVyKSEocj1HW29dLmV4ZWMoYSkpfHx1W29dJiYhKHI9dVtvXShyKSl8fChuPXIuc2hpZnQoKSxpLnB1c2goe3ZhbHVlOm4sdHlwZTpvLG1hdGNoZXM6cn0pLGE9YS5zbGljZShuLmxlbmd0aCkpO2lmKCFuKWJyZWFrfXJldHVybiB0P2EubGVuZ3RoOmE/c2UuZXJyb3IoZSk6eChlLHMpLnNsaWNlKDApfSxmPXNlLmNvbXBpbGU9ZnVuY3Rpb24oZSx0KXt2YXIgbix2LHksbSx4LHIsaT1bXSxvPVtdLGE9QVtlKyIgIl07aWYoIWEpe3R8fCh0PWgoZSkpLG49dC5sZW5ndGg7d2hpbGUobi0tKShhPUVlKHRbbl0pKVtTXT9pLnB1c2goYSk6by5wdXNoKGEpOyhhPUEoZSwodj1vLG09MDwoeT1pKS5sZW5ndGgseD0wPHYubGVuZ3RoLHI9ZnVuY3Rpb24oZSx0LG4scixpKXt2YXIgbyxhLHMsdT0wLGw9IjAiLGM9ZSYmW10sZj1bXSxwPXcsZD1lfHx4JiZiLmZpbmQuVEFHKCIqIixpKSxoPWsrPW51bGw9PXA/MTpNYXRoLnJhbmRvbSgpfHwuMSxnPWQubGVuZ3RoO2ZvcihpJiYodz10PT1DfHx0fHxpKTtsIT09ZyYmbnVsbCE9KG89ZFtsXSk7bCsrKXtpZih4JiZvKXthPTAsdHx8by5vd25lckRvY3VtZW50PT1DfHwoVChvKSxuPSFFKTt3aGlsZShzPXZbYSsrXSlpZihzKG8sdHx8QyxuKSl7ci5wdXNoKG8pO2JyZWFrfWkmJihrPWgpfW0mJigobz0hcyYmbykmJnUtLSxlJiZjLnB1c2gobykpfWlmKHUrPWwsbSYmbCE9PXUpe2E9MDt3aGlsZShzPXlbYSsrXSlzKGMsZix0LG4pO2lmKGUpe2lmKDA8dSl3aGlsZShsLS0pY1tsXXx8ZltsXXx8KGZbbF09cS5jYWxsKHIpKTtmPVRlKGYpfUguYXBwbHkocixmKSxpJiYhZSYmMDxmLmxlbmd0aCYmMTx1K3kubGVuZ3RoJiZzZS51bmlxdWVTb3J0KHIpfXJldHVybiBpJiYoaz1oLHc9cCksY30sbT9sZShyKTpyKSkpLnNlbGVjdG9yPWV9cmV0dXJuIGF9LGc9c2Uuc2VsZWN0PWZ1bmN0aW9uKGUsdCxuLHIpe3ZhciBpLG8sYSxzLHUsbD0iZnVuY3Rpb24iPT10eXBlb2YgZSYmZSxjPSFyJiZoKGU9bC5zZWxlY3Rvcnx8ZSk7aWYobj1ufHxbXSwxPT09Yy5sZW5ndGgpe2lmKDI8KG89Y1swXT1jWzBdLnNsaWNlKDApKS5sZW5ndGgmJiJJRCI9PT0oYT1vWzBdKS50eXBlJiY5PT09dC5ub2RlVHlwZSYmRSYmYi5yZWxhdGl2ZVtvWzFdLnR5cGVdKXtpZighKHQ9KGIuZmluZC5JRChhLm1hdGNoZXNbMF0ucmVwbGFjZSh0ZSxuZSksdCl8fFtdKVswXSkpcmV0dXJuIG47bCYmKHQ9dC5wYXJlbnROb2RlKSxlPWUuc2xpY2Uoby5zaGlmdCgpLnZhbHVlLmxlbmd0aCl9aT1HLm5lZWRzQ29udGV4dC50ZXN0KGUpPzA6by5sZW5ndGg7d2hpbGUoaS0tKXtpZihhPW9baV0sYi5yZWxhdGl2ZVtzPWEudHlwZV0pYnJlYWs7aWYoKHU9Yi5maW5kW3NdKSYmKHI9dShhLm1hdGNoZXNbMF0ucmVwbGFjZSh0ZSxuZSksZWUudGVzdChvWzBdLnR5cGUpJiZ5ZSh0LnBhcmVudE5vZGUpfHx0KSkpe2lmKG8uc3BsaWNlKGksMSksIShlPXIubGVuZ3RoJiZ4ZShvKSkpcmV0dXJuIEguYXBwbHkobixyKSxuO2JyZWFrfX19cmV0dXJuKGx8fGYoZSxjKSkocix0LCFFLG4sIXR8fGVlLnRlc3QoZSkmJnllKHQucGFyZW50Tm9kZSl8fHQpLG59LGQuc29ydFN0YWJsZT1TLnNwbGl0KCIiKS5zb3J0KGopLmpvaW4oIiIpPT09UyxkLmRldGVjdER1cGxpY2F0ZXM9ISFsLFQoKSxkLnNvcnREZXRhY2hlZD1jZShmdW5jdGlvbihlKXtyZXR1cm4gMSZlLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKEMuY3JlYXRlRWxlbWVudCgiZmllbGRzZXQiKSl9KSxjZShmdW5jdGlvbihlKXtyZXR1cm4gZS5pbm5lckhUTUw9IjxhIGhyZWY9JyMnPjwvYT4iLCIjIj09PWUuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoImhyZWYiKX0pfHxmZSgidHlwZXxocmVmfGhlaWdodHx3aWR0aCIsZnVuY3Rpb24oZSx0LG4pe2lmKCFuKXJldHVybiBlLmdldEF0dHJpYnV0ZSh0LCJ0eXBlIj09PXQudG9Mb3dlckNhc2UoKT8xOjIpfSksZC5hdHRyaWJ1dGVzJiZjZShmdW5jdGlvbihlKXtyZXR1cm4gZS5pbm5lckhUTUw9IjxpbnB1dC8+IixlLmZpcnN0Q2hpbGQuc2V0QXR0cmlidXRlKCJ2YWx1ZSIsIiIpLCIiPT09ZS5maXJzdENoaWxkLmdldEF0dHJpYnV0ZSgidmFsdWUiKX0pfHxmZSgidmFsdWUiLGZ1bmN0aW9uKGUsdCxuKXtpZighbiYmImlucHV0Ij09PWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSlyZXR1cm4gZS5kZWZhdWx0VmFsdWV9KSxjZShmdW5jdGlvbihlKXtyZXR1cm4gbnVsbD09ZS5nZXRBdHRyaWJ1dGUoImRpc2FibGVkIil9KXx8ZmUoUixmdW5jdGlvbihlLHQsbil7dmFyIHI7aWYoIW4pcmV0dXJuITA9PT1lW3RdP3QudG9Mb3dlckNhc2UoKToocj1lLmdldEF0dHJpYnV0ZU5vZGUodCkpJiZyLnNwZWNpZmllZD9yLnZhbHVlOm51bGx9KSxzZX0oQyk7Uy5maW5kPWQsUy5leHByPWQuc2VsZWN0b3JzLFMuZXhwclsiOiJdPVMuZXhwci5wc2V1ZG9zLFMudW5pcXVlU29ydD1TLnVuaXF1ZT1kLnVuaXF1ZVNvcnQsUy50ZXh0PWQuZ2V0VGV4dCxTLmlzWE1MRG9jPWQuaXNYTUwsUy5jb250YWlucz1kLmNvbnRhaW5zLFMuZXNjYXBlU2VsZWN0b3I9ZC5lc2NhcGU7dmFyIGg9ZnVuY3Rpb24oZSx0LG4pe3ZhciByPVtdLGk9dm9pZCAwIT09bjt3aGlsZSgoZT1lW3RdKSYmOSE9PWUubm9kZVR5cGUpaWYoMT09PWUubm9kZVR5cGUpe2lmKGkmJlMoZSkuaXMobikpYnJlYWs7ci5wdXNoKGUpfXJldHVybiByfSxUPWZ1bmN0aW9uKGUsdCl7Zm9yKHZhciBuPVtdO2U7ZT1lLm5leHRTaWJsaW5nKTE9PT1lLm5vZGVUeXBlJiZlIT09dCYmbi5wdXNoKGUpO3JldHVybiBufSxrPVMuZXhwci5tYXRjaC5uZWVkc0NvbnRleHQ7ZnVuY3Rpb24gQShlLHQpe3JldHVybiBlLm5vZGVOYW1lJiZlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk9PT10LnRvTG93ZXJDYXNlKCl9dmFyIE49L148KFthLXpdW15cL1wwPjpceDIwXHRcclxuXGZdKilbXHgyMFx0XHJcblxmXSpcLz8+KD86PFwvXDE+fCkkL2k7ZnVuY3Rpb24gaihlLG4scil7cmV0dXJuIG0obik/Uy5ncmVwKGUsZnVuY3Rpb24oZSx0KXtyZXR1cm4hIW4uY2FsbChlLHQsZSkhPT1yfSk6bi5ub2RlVHlwZT9TLmdyZXAoZSxmdW5jdGlvbihlKXtyZXR1cm4gZT09PW4hPT1yfSk6InN0cmluZyIhPXR5cGVvZiBuP1MuZ3JlcChlLGZ1bmN0aW9uKGUpe3JldHVybi0xPGkuY2FsbChuLGUpIT09cn0pOlMuZmlsdGVyKG4sZSxyKX1TLmZpbHRlcj1mdW5jdGlvbihlLHQsbil7dmFyIHI9dFswXTtyZXR1cm4gbiYmKGU9Ijpub3QoIitlKyIpIiksMT09PXQubGVuZ3RoJiYxPT09ci5ub2RlVHlwZT9TLmZpbmQubWF0Y2hlc1NlbGVjdG9yKHIsZSk/W3JdOltdOlMuZmluZC5tYXRjaGVzKGUsUy5ncmVwKHQsZnVuY3Rpb24oZSl7cmV0dXJuIDE9PT1lLm5vZGVUeXBlfSkpfSxTLmZuLmV4dGVuZCh7ZmluZDpmdW5jdGlvbihlKXt2YXIgdCxuLHI9dGhpcy5sZW5ndGgsaT10aGlzO2lmKCJzdHJpbmciIT10eXBlb2YgZSlyZXR1cm4gdGhpcy5wdXNoU3RhY2soUyhlKS5maWx0ZXIoZnVuY3Rpb24oKXtmb3IodD0wO3Q8cjt0KyspaWYoUy5jb250YWlucyhpW3RdLHRoaXMpKXJldHVybiEwfSkpO2ZvcihuPXRoaXMucHVzaFN0YWNrKFtdKSx0PTA7dDxyO3QrKylTLmZpbmQoZSxpW3RdLG4pO3JldHVybiAxPHI/Uy51bmlxdWVTb3J0KG4pOm59LGZpbHRlcjpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2soaih0aGlzLGV8fFtdLCExKSl9LG5vdDpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2soaih0aGlzLGV8fFtdLCEwKSl9LGlzOmZ1bmN0aW9uKGUpe3JldHVybiEhaih0aGlzLCJzdHJpbmciPT10eXBlb2YgZSYmay50ZXN0KGUpP1MoZSk6ZXx8W10sITEpLmxlbmd0aH19KTt2YXIgRCxxPS9eKD86XHMqKDxbXHdcV10rPilbXj5dKnwjKFtcdy1dKykpJC87KFMuZm4uaW5pdD1mdW5jdGlvbihlLHQsbil7dmFyIHIsaTtpZighZSlyZXR1cm4gdGhpcztpZihuPW58fEQsInN0cmluZyI9PXR5cGVvZiBlKXtpZighKHI9IjwiPT09ZVswXSYmIj4iPT09ZVtlLmxlbmd0aC0xXSYmMzw9ZS5sZW5ndGg/W251bGwsZSxudWxsXTpxLmV4ZWMoZSkpfHwhclsxXSYmdClyZXR1cm4hdHx8dC5qcXVlcnk/KHR8fG4pLmZpbmQoZSk6dGhpcy5jb25zdHJ1Y3Rvcih0KS5maW5kKGUpO2lmKHJbMV0pe2lmKHQ9dCBpbnN0YW5jZW9mIFM/dFswXTp0LFMubWVyZ2UodGhpcyxTLnBhcnNlSFRNTChyWzFdLHQmJnQubm9kZVR5cGU/dC5vd25lckRvY3VtZW50fHx0OkUsITApKSxOLnRlc3QoclsxXSkmJlMuaXNQbGFpbk9iamVjdCh0KSlmb3IociBpbiB0KW0odGhpc1tyXSk/dGhpc1tyXSh0W3JdKTp0aGlzLmF0dHIocix0W3JdKTtyZXR1cm4gdGhpc31yZXR1cm4oaT1FLmdldEVsZW1lbnRCeUlkKHJbMl0pKSYmKHRoaXNbMF09aSx0aGlzLmxlbmd0aD0xKSx0aGlzfXJldHVybiBlLm5vZGVUeXBlPyh0aGlzWzBdPWUsdGhpcy5sZW5ndGg9MSx0aGlzKTptKGUpP3ZvaWQgMCE9PW4ucmVhZHk/bi5yZWFkeShlKTplKFMpOlMubWFrZUFycmF5KGUsdGhpcyl9KS5wcm90b3R5cGU9Uy5mbixEPVMoRSk7dmFyIEw9L14oPzpwYXJlbnRzfHByZXYoPzpVbnRpbHxBbGwpKS8sSD17Y2hpbGRyZW46ITAsY29udGVudHM6ITAsbmV4dDohMCxwcmV2OiEwfTtmdW5jdGlvbiBPKGUsdCl7d2hpbGUoKGU9ZVt0XSkmJjEhPT1lLm5vZGVUeXBlKTtyZXR1cm4gZX1TLmZuLmV4dGVuZCh7aGFzOmZ1bmN0aW9uKGUpe3ZhciB0PVMoZSx0aGlzKSxuPXQubGVuZ3RoO3JldHVybiB0aGlzLmZpbHRlcihmdW5jdGlvbigpe2Zvcih2YXIgZT0wO2U8bjtlKyspaWYoUy5jb250YWlucyh0aGlzLHRbZV0pKXJldHVybiEwfSl9LGNsb3Nlc3Q6ZnVuY3Rpb24oZSx0KXt2YXIgbixyPTAsaT10aGlzLmxlbmd0aCxvPVtdLGE9InN0cmluZyIhPXR5cGVvZiBlJiZTKGUpO2lmKCFrLnRlc3QoZSkpZm9yKDtyPGk7cisrKWZvcihuPXRoaXNbcl07biYmbiE9PXQ7bj1uLnBhcmVudE5vZGUpaWYobi5ub2RlVHlwZTwxMSYmKGE/LTE8YS5pbmRleChuKToxPT09bi5ub2RlVHlwZSYmUy5maW5kLm1hdGNoZXNTZWxlY3RvcihuLGUpKSl7by5wdXNoKG4pO2JyZWFrfXJldHVybiB0aGlzLnB1c2hTdGFjaygxPG8ubGVuZ3RoP1MudW5pcXVlU29ydChvKTpvKX0saW5kZXg6ZnVuY3Rpb24oZSl7cmV0dXJuIGU/InN0cmluZyI9PXR5cGVvZiBlP2kuY2FsbChTKGUpLHRoaXNbMF0pOmkuY2FsbCh0aGlzLGUuanF1ZXJ5P2VbMF06ZSk6dGhpc1swXSYmdGhpc1swXS5wYXJlbnROb2RlP3RoaXMuZmlyc3QoKS5wcmV2QWxsKCkubGVuZ3RoOi0xfSxhZGQ6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gdGhpcy5wdXNoU3RhY2soUy51bmlxdWVTb3J0KFMubWVyZ2UodGhpcy5nZXQoKSxTKGUsdCkpKSl9LGFkZEJhY2s6ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuYWRkKG51bGw9PWU/dGhpcy5wcmV2T2JqZWN0OnRoaXMucHJldk9iamVjdC5maWx0ZXIoZSkpfX0pLFMuZWFjaCh7cGFyZW50OmZ1bmN0aW9uKGUpe3ZhciB0PWUucGFyZW50Tm9kZTtyZXR1cm4gdCYmMTEhPT10Lm5vZGVUeXBlP3Q6bnVsbH0scGFyZW50czpmdW5jdGlvbihlKXtyZXR1cm4gaChlLCJwYXJlbnROb2RlIil9LHBhcmVudHNVbnRpbDpmdW5jdGlvbihlLHQsbil7cmV0dXJuIGgoZSwicGFyZW50Tm9kZSIsbil9LG5leHQ6ZnVuY3Rpb24oZSl7cmV0dXJuIE8oZSwibmV4dFNpYmxpbmciKX0scHJldjpmdW5jdGlvbihlKXtyZXR1cm4gTyhlLCJwcmV2aW91c1NpYmxpbmciKX0sbmV4dEFsbDpmdW5jdGlvbihlKXtyZXR1cm4gaChlLCJuZXh0U2libGluZyIpfSxwcmV2QWxsOmZ1bmN0aW9uKGUpe3JldHVybiBoKGUsInByZXZpb3VzU2libGluZyIpfSxuZXh0VW50aWw6ZnVuY3Rpb24oZSx0LG4pe3JldHVybiBoKGUsIm5leHRTaWJsaW5nIixuKX0scHJldlVudGlsOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gaChlLCJwcmV2aW91c1NpYmxpbmciLG4pfSxzaWJsaW5nczpmdW5jdGlvbihlKXtyZXR1cm4gVCgoZS5wYXJlbnROb2RlfHx7fSkuZmlyc3RDaGlsZCxlKX0sY2hpbGRyZW46ZnVuY3Rpb24oZSl7cmV0dXJuIFQoZS5maXJzdENoaWxkKX0sY29udGVudHM6ZnVuY3Rpb24oZSl7cmV0dXJuIG51bGwhPWUuY29udGVudERvY3VtZW50JiZyKGUuY29udGVudERvY3VtZW50KT9lLmNvbnRlbnREb2N1bWVudDooQShlLCJ0ZW1wbGF0ZSIpJiYoZT1lLmNvbnRlbnR8fGUpLFMubWVyZ2UoW10sZS5jaGlsZE5vZGVzKSl9fSxmdW5jdGlvbihyLGkpe1MuZm5bcl09ZnVuY3Rpb24oZSx0KXt2YXIgbj1TLm1hcCh0aGlzLGksZSk7cmV0dXJuIlVudGlsIiE9PXIuc2xpY2UoLTUpJiYodD1lKSx0JiYic3RyaW5nIj09dHlwZW9mIHQmJihuPVMuZmlsdGVyKHQsbikpLDE8dGhpcy5sZW5ndGgmJihIW3JdfHxTLnVuaXF1ZVNvcnQobiksTC50ZXN0KHIpJiZuLnJldmVyc2UoKSksdGhpcy5wdXNoU3RhY2sobil9fSk7dmFyIFA9L1teXHgyMFx0XHJcblxmXSsvZztmdW5jdGlvbiBSKGUpe3JldHVybiBlfWZ1bmN0aW9uIE0oZSl7dGhyb3cgZX1mdW5jdGlvbiBJKGUsdCxuLHIpe3ZhciBpO3RyeXtlJiZtKGk9ZS5wcm9taXNlKT9pLmNhbGwoZSkuZG9uZSh0KS5mYWlsKG4pOmUmJm0oaT1lLnRoZW4pP2kuY2FsbChlLHQsbik6dC5hcHBseSh2b2lkIDAsW2VdLnNsaWNlKHIpKX1jYXRjaChlKXtuLmFwcGx5KHZvaWQgMCxbZV0pfX1TLkNhbGxiYWNrcz1mdW5jdGlvbihyKXt2YXIgZSxuO3I9InN0cmluZyI9PXR5cGVvZiByPyhlPXIsbj17fSxTLmVhY2goZS5tYXRjaChQKXx8W10sZnVuY3Rpb24oZSx0KXtuW3RdPSEwfSksbik6Uy5leHRlbmQoe30scik7dmFyIGksdCxvLGEscz1bXSx1PVtdLGw9LTEsYz1mdW5jdGlvbigpe2ZvcihhPWF8fHIub25jZSxvPWk9ITA7dS5sZW5ndGg7bD0tMSl7dD11LnNoaWZ0KCk7d2hpbGUoKytsPHMubGVuZ3RoKSExPT09c1tsXS5hcHBseSh0WzBdLHRbMV0pJiZyLnN0b3BPbkZhbHNlJiYobD1zLmxlbmd0aCx0PSExKX1yLm1lbW9yeXx8KHQ9ITEpLGk9ITEsYSYmKHM9dD9bXToiIil9LGY9e2FkZDpmdW5jdGlvbigpe3JldHVybiBzJiYodCYmIWkmJihsPXMubGVuZ3RoLTEsdS5wdXNoKHQpKSxmdW5jdGlvbiBuKGUpe1MuZWFjaChlLGZ1bmN0aW9uKGUsdCl7bSh0KT9yLnVuaXF1ZSYmZi5oYXModCl8fHMucHVzaCh0KTp0JiZ0Lmxlbmd0aCYmInN0cmluZyIhPT13KHQpJiZuKHQpfSl9KGFyZ3VtZW50cyksdCYmIWkmJmMoKSksdGhpc30scmVtb3ZlOmZ1bmN0aW9uKCl7cmV0dXJuIFMuZWFjaChhcmd1bWVudHMsZnVuY3Rpb24oZSx0KXt2YXIgbjt3aGlsZSgtMTwobj1TLmluQXJyYXkodCxzLG4pKSlzLnNwbGljZShuLDEpLG48PWwmJmwtLX0pLHRoaXN9LGhhczpmdW5jdGlvbihlKXtyZXR1cm4gZT8tMTxTLmluQXJyYXkoZSxzKTowPHMubGVuZ3RofSxlbXB0eTpmdW5jdGlvbigpe3JldHVybiBzJiYocz1bXSksdGhpc30sZGlzYWJsZTpmdW5jdGlvbigpe3JldHVybiBhPXU9W10scz10PSIiLHRoaXN9LGRpc2FibGVkOmZ1bmN0aW9uKCl7cmV0dXJuIXN9LGxvY2s6ZnVuY3Rpb24oKXtyZXR1cm4gYT11PVtdLHR8fGl8fChzPXQ9IiIpLHRoaXN9LGxvY2tlZDpmdW5jdGlvbigpe3JldHVybiEhYX0sZmlyZVdpdGg6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gYXx8KHQ9W2UsKHQ9dHx8W10pLnNsaWNlP3Quc2xpY2UoKTp0XSx1LnB1c2godCksaXx8YygpKSx0aGlzfSxmaXJlOmZ1bmN0aW9uKCl7cmV0dXJuIGYuZmlyZVdpdGgodGhpcyxhcmd1bWVudHMpLHRoaXN9LGZpcmVkOmZ1bmN0aW9uKCl7cmV0dXJuISFvfX07cmV0dXJuIGZ9LFMuZXh0ZW5kKHtEZWZlcnJlZDpmdW5jdGlvbihlKXt2YXIgbz1bWyJub3RpZnkiLCJwcm9ncmVzcyIsUy5DYWxsYmFja3MoIm1lbW9yeSIpLFMuQ2FsbGJhY2tzKCJtZW1vcnkiKSwyXSxbInJlc29sdmUiLCJkb25lIixTLkNhbGxiYWNrcygib25jZSBtZW1vcnkiKSxTLkNhbGxiYWNrcygib25jZSBtZW1vcnkiKSwwLCJyZXNvbHZlZCJdLFsicmVqZWN0IiwiZmFpbCIsUy5DYWxsYmFja3MoIm9uY2UgbWVtb3J5IiksUy5DYWxsYmFja3MoIm9uY2UgbWVtb3J5IiksMSwicmVqZWN0ZWQiXV0saT0icGVuZGluZyIsYT17c3RhdGU6ZnVuY3Rpb24oKXtyZXR1cm4gaX0sYWx3YXlzOmZ1bmN0aW9uKCl7cmV0dXJuIHMuZG9uZShhcmd1bWVudHMpLmZhaWwoYXJndW1lbnRzKSx0aGlzfSwiY2F0Y2giOmZ1bmN0aW9uKGUpe3JldHVybiBhLnRoZW4obnVsbCxlKX0scGlwZTpmdW5jdGlvbigpe3ZhciBpPWFyZ3VtZW50cztyZXR1cm4gUy5EZWZlcnJlZChmdW5jdGlvbihyKXtTLmVhY2gobyxmdW5jdGlvbihlLHQpe3ZhciBuPW0oaVt0WzRdXSkmJmlbdFs0XV07c1t0WzFdXShmdW5jdGlvbigpe3ZhciBlPW4mJm4uYXBwbHkodGhpcyxhcmd1bWVudHMpO2UmJm0oZS5wcm9taXNlKT9lLnByb21pc2UoKS5wcm9ncmVzcyhyLm5vdGlmeSkuZG9uZShyLnJlc29sdmUpLmZhaWwoci5yZWplY3QpOnJbdFswXSsiV2l0aCJdKHRoaXMsbj9bZV06YXJndW1lbnRzKX0pfSksaT1udWxsfSkucHJvbWlzZSgpfSx0aGVuOmZ1bmN0aW9uKHQsbixyKXt2YXIgdT0wO2Z1bmN0aW9uIGwoaSxvLGEscyl7cmV0dXJuIGZ1bmN0aW9uKCl7dmFyIG49dGhpcyxyPWFyZ3VtZW50cyxlPWZ1bmN0aW9uKCl7dmFyIGUsdDtpZighKGk8dSkpe2lmKChlPWEuYXBwbHkobixyKSk9PT1vLnByb21pc2UoKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJUaGVuYWJsZSBzZWxmLXJlc29sdXRpb24iKTt0PWUmJigib2JqZWN0Ij09dHlwZW9mIGV8fCJmdW5jdGlvbiI9PXR5cGVvZiBlKSYmZS50aGVuLG0odCk/cz90LmNhbGwoZSxsKHUsbyxSLHMpLGwodSxvLE0scykpOih1KyssdC5jYWxsKGUsbCh1LG8sUixzKSxsKHUsbyxNLHMpLGwodSxvLFIsby5ub3RpZnlXaXRoKSkpOihhIT09UiYmKG49dm9pZCAwLHI9W2VdKSwoc3x8by5yZXNvbHZlV2l0aCkobixyKSl9fSx0PXM/ZTpmdW5jdGlvbigpe3RyeXtlKCl9Y2F0Y2goZSl7Uy5EZWZlcnJlZC5leGNlcHRpb25Ib29rJiZTLkRlZmVycmVkLmV4Y2VwdGlvbkhvb2soZSx0LnN0YWNrVHJhY2UpLHU8PWkrMSYmKGEhPT1NJiYobj12b2lkIDAscj1bZV0pLG8ucmVqZWN0V2l0aChuLHIpKX19O2k/dCgpOihTLkRlZmVycmVkLmdldFN0YWNrSG9vayYmKHQuc3RhY2tUcmFjZT1TLkRlZmVycmVkLmdldFN0YWNrSG9vaygpKSxDLnNldFRpbWVvdXQodCkpfX1yZXR1cm4gUy5EZWZlcnJlZChmdW5jdGlvbihlKXtvWzBdWzNdLmFkZChsKDAsZSxtKHIpP3I6UixlLm5vdGlmeVdpdGgpKSxvWzFdWzNdLmFkZChsKDAsZSxtKHQpP3Q6UikpLG9bMl1bM10uYWRkKGwoMCxlLG0obik/bjpNKSl9KS5wcm9taXNlKCl9LHByb21pc2U6ZnVuY3Rpb24oZSl7cmV0dXJuIG51bGwhPWU/Uy5leHRlbmQoZSxhKTphfX0scz17fTtyZXR1cm4gUy5lYWNoKG8sZnVuY3Rpb24oZSx0KXt2YXIgbj10WzJdLHI9dFs1XTthW3RbMV1dPW4uYWRkLHImJm4uYWRkKGZ1bmN0aW9uKCl7aT1yfSxvWzMtZV1bMl0uZGlzYWJsZSxvWzMtZV1bM10uZGlzYWJsZSxvWzBdWzJdLmxvY2ssb1swXVszXS5sb2NrKSxuLmFkZCh0WzNdLmZpcmUpLHNbdFswXV09ZnVuY3Rpb24oKXtyZXR1cm4gc1t0WzBdKyJXaXRoIl0odGhpcz09PXM/dm9pZCAwOnRoaXMsYXJndW1lbnRzKSx0aGlzfSxzW3RbMF0rIldpdGgiXT1uLmZpcmVXaXRofSksYS5wcm9taXNlKHMpLGUmJmUuY2FsbChzLHMpLHN9LHdoZW46ZnVuY3Rpb24oZSl7dmFyIG49YXJndW1lbnRzLmxlbmd0aCx0PW4scj1BcnJheSh0KSxpPXMuY2FsbChhcmd1bWVudHMpLG89Uy5EZWZlcnJlZCgpLGE9ZnVuY3Rpb24odCl7cmV0dXJuIGZ1bmN0aW9uKGUpe3JbdF09dGhpcyxpW3RdPTE8YXJndW1lbnRzLmxlbmd0aD9zLmNhbGwoYXJndW1lbnRzKTplLC0tbnx8by5yZXNvbHZlV2l0aChyLGkpfX07aWYobjw9MSYmKEkoZSxvLmRvbmUoYSh0KSkucmVzb2x2ZSxvLnJlamVjdCwhbiksInBlbmRpbmciPT09by5zdGF0ZSgpfHxtKGlbdF0mJmlbdF0udGhlbikpKXJldHVybiBvLnRoZW4oKTt3aGlsZSh0LS0pSShpW3RdLGEodCksby5yZWplY3QpO3JldHVybiBvLnByb21pc2UoKX19KTt2YXIgVz0vXihFdmFsfEludGVybmFsfFJhbmdlfFJlZmVyZW5jZXxTeW50YXh8VHlwZXxVUkkpRXJyb3IkLztTLkRlZmVycmVkLmV4Y2VwdGlvbkhvb2s9ZnVuY3Rpb24oZSx0KXtDLmNvbnNvbGUmJkMuY29uc29sZS53YXJuJiZlJiZXLnRlc3QoZS5uYW1lKSYmQy5jb25zb2xlLndhcm4oImpRdWVyeS5EZWZlcnJlZCBleGNlcHRpb246ICIrZS5tZXNzYWdlLGUuc3RhY2ssdCl9LFMucmVhZHlFeGNlcHRpb249ZnVuY3Rpb24oZSl7Qy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dGhyb3cgZX0pfTt2YXIgRj1TLkRlZmVycmVkKCk7ZnVuY3Rpb24gQigpe0UucmVtb3ZlRXZlbnRMaXN0ZW5lcigiRE9NQ29udGVudExvYWRlZCIsQiksQy5yZW1vdmVFdmVudExpc3RlbmVyKCJsb2FkIixCKSxTLnJlYWR5KCl9Uy5mbi5yZWFkeT1mdW5jdGlvbihlKXtyZXR1cm4gRi50aGVuKGUpWyJjYXRjaCJdKGZ1bmN0aW9uKGUpe1MucmVhZHlFeGNlcHRpb24oZSl9KSx0aGlzfSxTLmV4dGVuZCh7aXNSZWFkeTohMSxyZWFkeVdhaXQ6MSxyZWFkeTpmdW5jdGlvbihlKXsoITA9PT1lPy0tUy5yZWFkeVdhaXQ6Uy5pc1JlYWR5KXx8KFMuaXNSZWFkeT0hMCkhPT1lJiYwPC0tUy5yZWFkeVdhaXR8fEYucmVzb2x2ZVdpdGgoRSxbU10pfX0pLFMucmVhZHkudGhlbj1GLnRoZW4sImNvbXBsZXRlIj09PUUucmVhZHlTdGF0ZXx8ImxvYWRpbmciIT09RS5yZWFkeVN0YXRlJiYhRS5kb2N1bWVudEVsZW1lbnQuZG9TY3JvbGw/Qy5zZXRUaW1lb3V0KFMucmVhZHkpOihFLmFkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLEIpLEMuYWRkRXZlbnRMaXN0ZW5lcigibG9hZCIsQikpO3ZhciAkPWZ1bmN0aW9uKGUsdCxuLHIsaSxvLGEpe3ZhciBzPTAsdT1lLmxlbmd0aCxsPW51bGw9PW47aWYoIm9iamVjdCI9PT13KG4pKWZvcihzIGluIGk9ITAsbikkKGUsdCxzLG5bc10sITAsbyxhKTtlbHNlIGlmKHZvaWQgMCE9PXImJihpPSEwLG0ocil8fChhPSEwKSxsJiYoYT8odC5jYWxsKGUsciksdD1udWxsKToobD10LHQ9ZnVuY3Rpb24oZSx0LG4pe3JldHVybiBsLmNhbGwoUyhlKSxuKX0pKSx0KSlmb3IoO3M8dTtzKyspdChlW3NdLG4sYT9yOnIuY2FsbChlW3NdLHMsdChlW3NdLG4pKSk7cmV0dXJuIGk/ZTpsP3QuY2FsbChlKTp1P3QoZVswXSxuKTpvfSxfPS9eLW1zLS8sej0vLShbYS16XSkvZztmdW5jdGlvbiBVKGUsdCl7cmV0dXJuIHQudG9VcHBlckNhc2UoKX1mdW5jdGlvbiBYKGUpe3JldHVybiBlLnJlcGxhY2UoXywibXMtIikucmVwbGFjZSh6LFUpfXZhciBWPWZ1bmN0aW9uKGUpe3JldHVybiAxPT09ZS5ub2RlVHlwZXx8OT09PWUubm9kZVR5cGV8fCErZS5ub2RlVHlwZX07ZnVuY3Rpb24gRygpe3RoaXMuZXhwYW5kbz1TLmV4cGFuZG8rRy51aWQrK31HLnVpZD0xLEcucHJvdG90eXBlPXtjYWNoZTpmdW5jdGlvbihlKXt2YXIgdD1lW3RoaXMuZXhwYW5kb107cmV0dXJuIHR8fCh0PXt9LFYoZSkmJihlLm5vZGVUeXBlP2VbdGhpcy5leHBhbmRvXT10Ok9iamVjdC5kZWZpbmVQcm9wZXJ0eShlLHRoaXMuZXhwYW5kbyx7dmFsdWU6dCxjb25maWd1cmFibGU6ITB9KSkpLHR9LHNldDpmdW5jdGlvbihlLHQsbil7dmFyIHIsaT10aGlzLmNhY2hlKGUpO2lmKCJzdHJpbmciPT10eXBlb2YgdClpW1godCldPW47ZWxzZSBmb3IociBpbiB0KWlbWChyKV09dFtyXTtyZXR1cm4gaX0sZ2V0OmZ1bmN0aW9uKGUsdCl7cmV0dXJuIHZvaWQgMD09PXQ/dGhpcy5jYWNoZShlKTplW3RoaXMuZXhwYW5kb10mJmVbdGhpcy5leHBhbmRvXVtYKHQpXX0sYWNjZXNzOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gdm9pZCAwPT09dHx8dCYmInN0cmluZyI9PXR5cGVvZiB0JiZ2b2lkIDA9PT1uP3RoaXMuZ2V0KGUsdCk6KHRoaXMuc2V0KGUsdCxuKSx2b2lkIDAhPT1uP246dCl9LHJlbW92ZTpmdW5jdGlvbihlLHQpe3ZhciBuLHI9ZVt0aGlzLmV4cGFuZG9dO2lmKHZvaWQgMCE9PXIpe2lmKHZvaWQgMCE9PXQpe249KHQ9QXJyYXkuaXNBcnJheSh0KT90Lm1hcChYKToodD1YKHQpKWluIHI/W3RdOnQubWF0Y2goUCl8fFtdKS5sZW5ndGg7d2hpbGUobi0tKWRlbGV0ZSByW3Rbbl1dfSh2b2lkIDA9PT10fHxTLmlzRW1wdHlPYmplY3QocikpJiYoZS5ub2RlVHlwZT9lW3RoaXMuZXhwYW5kb109dm9pZCAwOmRlbGV0ZSBlW3RoaXMuZXhwYW5kb10pfX0saGFzRGF0YTpmdW5jdGlvbihlKXt2YXIgdD1lW3RoaXMuZXhwYW5kb107cmV0dXJuIHZvaWQgMCE9PXQmJiFTLmlzRW1wdHlPYmplY3QodCl9fTt2YXIgWT1uZXcgRyxRPW5ldyBHLEo9L14oPzpce1tcd1xXXSpcfXxcW1tcd1xXXSpcXSkkLyxLPS9bQS1aXS9nO2Z1bmN0aW9uIFooZSx0LG4pe3ZhciByLGk7aWYodm9pZCAwPT09biYmMT09PWUubm9kZVR5cGUpaWYocj0iZGF0YS0iK3QucmVwbGFjZShLLCItJCYiKS50b0xvd2VyQ2FzZSgpLCJzdHJpbmciPT10eXBlb2Yobj1lLmdldEF0dHJpYnV0ZShyKSkpe3RyeXtuPSJ0cnVlIj09PShpPW4pfHwiZmFsc2UiIT09aSYmKCJudWxsIj09PWk/bnVsbDppPT09K2krIiI/K2k6Si50ZXN0KGkpP0pTT04ucGFyc2UoaSk6aSl9Y2F0Y2goZSl7fVEuc2V0KGUsdCxuKX1lbHNlIG49dm9pZCAwO3JldHVybiBufVMuZXh0ZW5kKHtoYXNEYXRhOmZ1bmN0aW9uKGUpe3JldHVybiBRLmhhc0RhdGEoZSl8fFkuaGFzRGF0YShlKX0sZGF0YTpmdW5jdGlvbihlLHQsbil7cmV0dXJuIFEuYWNjZXNzKGUsdCxuKX0scmVtb3ZlRGF0YTpmdW5jdGlvbihlLHQpe1EucmVtb3ZlKGUsdCl9LF9kYXRhOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gWS5hY2Nlc3MoZSx0LG4pfSxfcmVtb3ZlRGF0YTpmdW5jdGlvbihlLHQpe1kucmVtb3ZlKGUsdCl9fSksUy5mbi5leHRlbmQoe2RhdGE6ZnVuY3Rpb24obixlKXt2YXIgdCxyLGksbz10aGlzWzBdLGE9byYmby5hdHRyaWJ1dGVzO2lmKHZvaWQgMD09PW4pe2lmKHRoaXMubGVuZ3RoJiYoaT1RLmdldChvKSwxPT09by5ub2RlVHlwZSYmIVkuZ2V0KG8sImhhc0RhdGFBdHRycyIpKSl7dD1hLmxlbmd0aDt3aGlsZSh0LS0pYVt0XSYmMD09PShyPWFbdF0ubmFtZSkuaW5kZXhPZigiZGF0YS0iKSYmKHI9WChyLnNsaWNlKDUpKSxaKG8scixpW3JdKSk7WS5zZXQobywiaGFzRGF0YUF0dHJzIiwhMCl9cmV0dXJuIGl9cmV0dXJuIm9iamVjdCI9PXR5cGVvZiBuP3RoaXMuZWFjaChmdW5jdGlvbigpe1Euc2V0KHRoaXMsbil9KTokKHRoaXMsZnVuY3Rpb24oZSl7dmFyIHQ7aWYobyYmdm9pZCAwPT09ZSlyZXR1cm4gdm9pZCAwIT09KHQ9US5nZXQobyxuKSk/dDp2b2lkIDAhPT0odD1aKG8sbikpP3Q6dm9pZCAwO3RoaXMuZWFjaChmdW5jdGlvbigpe1Euc2V0KHRoaXMsbixlKX0pfSxudWxsLGUsMTxhcmd1bWVudHMubGVuZ3RoLG51bGwsITApfSxyZW1vdmVEYXRhOmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtRLnJlbW92ZSh0aGlzLGUpfSl9fSksUy5leHRlbmQoe3F1ZXVlOmZ1bmN0aW9uKGUsdCxuKXt2YXIgcjtpZihlKXJldHVybiB0PSh0fHwiZngiKSsicXVldWUiLHI9WS5nZXQoZSx0KSxuJiYoIXJ8fEFycmF5LmlzQXJyYXkobik/cj1ZLmFjY2VzcyhlLHQsUy5tYWtlQXJyYXkobikpOnIucHVzaChuKSkscnx8W119LGRlcXVldWU6ZnVuY3Rpb24oZSx0KXt0PXR8fCJmeCI7dmFyIG49Uy5xdWV1ZShlLHQpLHI9bi5sZW5ndGgsaT1uLnNoaWZ0KCksbz1TLl9xdWV1ZUhvb2tzKGUsdCk7ImlucHJvZ3Jlc3MiPT09aSYmKGk9bi5zaGlmdCgpLHItLSksaSYmKCJmeCI9PT10JiZuLnVuc2hpZnQoImlucHJvZ3Jlc3MiKSxkZWxldGUgby5zdG9wLGkuY2FsbChlLGZ1bmN0aW9uKCl7Uy5kZXF1ZXVlKGUsdCl9LG8pKSwhciYmbyYmby5lbXB0eS5maXJlKCl9LF9xdWV1ZUhvb2tzOmZ1bmN0aW9uKGUsdCl7dmFyIG49dCsicXVldWVIb29rcyI7cmV0dXJuIFkuZ2V0KGUsbil8fFkuYWNjZXNzKGUsbix7ZW1wdHk6Uy5DYWxsYmFja3MoIm9uY2UgbWVtb3J5IikuYWRkKGZ1bmN0aW9uKCl7WS5yZW1vdmUoZSxbdCsicXVldWUiLG5dKX0pfSl9fSksUy5mbi5leHRlbmQoe3F1ZXVlOmZ1bmN0aW9uKHQsbil7dmFyIGU9MjtyZXR1cm4ic3RyaW5nIiE9dHlwZW9mIHQmJihuPXQsdD0iZngiLGUtLSksYXJndW1lbnRzLmxlbmd0aDxlP1MucXVldWUodGhpc1swXSx0KTp2b2lkIDA9PT1uP3RoaXM6dGhpcy5lYWNoKGZ1bmN0aW9uKCl7dmFyIGU9Uy5xdWV1ZSh0aGlzLHQsbik7Uy5fcXVldWVIb29rcyh0aGlzLHQpLCJmeCI9PT10JiYiaW5wcm9ncmVzcyIhPT1lWzBdJiZTLmRlcXVldWUodGhpcyx0KX0pfSxkZXF1ZXVlOmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtTLmRlcXVldWUodGhpcyxlKX0pfSxjbGVhclF1ZXVlOmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLnF1ZXVlKGV8fCJmeCIsW10pfSxwcm9taXNlOmZ1bmN0aW9uKGUsdCl7dmFyIG4scj0xLGk9Uy5EZWZlcnJlZCgpLG89dGhpcyxhPXRoaXMubGVuZ3RoLHM9ZnVuY3Rpb24oKXstLXJ8fGkucmVzb2x2ZVdpdGgobyxbb10pfTsic3RyaW5nIiE9dHlwZW9mIGUmJih0PWUsZT12b2lkIDApLGU9ZXx8ImZ4Ijt3aGlsZShhLS0pKG49WS5nZXQob1thXSxlKyJxdWV1ZUhvb2tzIikpJiZuLmVtcHR5JiYocisrLG4uZW1wdHkuYWRkKHMpKTtyZXR1cm4gcygpLGkucHJvbWlzZSh0KX19KTt2YXIgZWU9L1srLV0/KD86XGQqXC58KVxkKyg/OltlRV1bKy1dP1xkK3wpLy5zb3VyY2UsdGU9bmV3IFJlZ0V4cCgiXig/OihbKy1dKT18KSgiK2VlKyIpKFthLXolXSopJCIsImkiKSxuZT1bIlRvcCIsIlJpZ2h0IiwiQm90dG9tIiwiTGVmdCJdLHJlPUUuZG9jdW1lbnRFbGVtZW50LGllPWZ1bmN0aW9uKGUpe3JldHVybiBTLmNvbnRhaW5zKGUub3duZXJEb2N1bWVudCxlKX0sb2U9e2NvbXBvc2VkOiEwfTtyZS5nZXRSb290Tm9kZSYmKGllPWZ1bmN0aW9uKGUpe3JldHVybiBTLmNvbnRhaW5zKGUub3duZXJEb2N1bWVudCxlKXx8ZS5nZXRSb290Tm9kZShvZSk9PT1lLm93bmVyRG9jdW1lbnR9KTt2YXIgYWU9ZnVuY3Rpb24oZSx0KXtyZXR1cm4ibm9uZSI9PT0oZT10fHxlKS5zdHlsZS5kaXNwbGF5fHwiIj09PWUuc3R5bGUuZGlzcGxheSYmaWUoZSkmJiJub25lIj09PVMuY3NzKGUsImRpc3BsYXkiKX07ZnVuY3Rpb24gc2UoZSx0LG4scil7dmFyIGksbyxhPTIwLHM9cj9mdW5jdGlvbigpe3JldHVybiByLmN1cigpfTpmdW5jdGlvbigpe3JldHVybiBTLmNzcyhlLHQsIiIpfSx1PXMoKSxsPW4mJm5bM118fChTLmNzc051bWJlclt0XT8iIjoicHgiKSxjPWUubm9kZVR5cGUmJihTLmNzc051bWJlclt0XXx8InB4IiE9PWwmJit1KSYmdGUuZXhlYyhTLmNzcyhlLHQpKTtpZihjJiZjWzNdIT09bCl7dS89MixsPWx8fGNbM10sYz0rdXx8MTt3aGlsZShhLS0pUy5zdHlsZShlLHQsYytsKSwoMS1vKSooMS0obz1zKCkvdXx8LjUpKTw9MCYmKGE9MCksYy89bztjKj0yLFMuc3R5bGUoZSx0LGMrbCksbj1ufHxbXX1yZXR1cm4gbiYmKGM9K2N8fCt1fHwwLGk9blsxXT9jKyhuWzFdKzEpKm5bMl06K25bMl0sciYmKHIudW5pdD1sLHIuc3RhcnQ9YyxyLmVuZD1pKSksaX12YXIgdWU9e307ZnVuY3Rpb24gbGUoZSx0KXtmb3IodmFyIG4scixpLG8sYSxzLHUsbD1bXSxjPTAsZj1lLmxlbmd0aDtjPGY7YysrKShyPWVbY10pLnN0eWxlJiYobj1yLnN0eWxlLmRpc3BsYXksdD8oIm5vbmUiPT09biYmKGxbY109WS5nZXQociwiZGlzcGxheSIpfHxudWxsLGxbY118fChyLnN0eWxlLmRpc3BsYXk9IiIpKSwiIj09PXIuc3R5bGUuZGlzcGxheSYmYWUocikmJihsW2NdPSh1PWE9bz12b2lkIDAsYT0oaT1yKS5vd25lckRvY3VtZW50LHM9aS5ub2RlTmFtZSwodT11ZVtzXSl8fChvPWEuYm9keS5hcHBlbmRDaGlsZChhLmNyZWF0ZUVsZW1lbnQocykpLHU9Uy5jc3MobywiZGlzcGxheSIpLG8ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChvKSwibm9uZSI9PT11JiYodT0iYmxvY2siKSx1ZVtzXT11KSkpKToibm9uZSIhPT1uJiYobFtjXT0ibm9uZSIsWS5zZXQociwiZGlzcGxheSIsbikpKTtmb3IoYz0wO2M8ZjtjKyspbnVsbCE9bFtjXSYmKGVbY10uc3R5bGUuZGlzcGxheT1sW2NdKTtyZXR1cm4gZX1TLmZuLmV4dGVuZCh7c2hvdzpmdW5jdGlvbigpe3JldHVybiBsZSh0aGlzLCEwKX0saGlkZTpmdW5jdGlvbigpe3JldHVybiBsZSh0aGlzKX0sdG9nZ2xlOmZ1bmN0aW9uKGUpe3JldHVybiJib29sZWFuIj09dHlwZW9mIGU/ZT90aGlzLnNob3coKTp0aGlzLmhpZGUoKTp0aGlzLmVhY2goZnVuY3Rpb24oKXthZSh0aGlzKT9TKHRoaXMpLnNob3coKTpTKHRoaXMpLmhpZGUoKX0pfX0pO3ZhciBjZSxmZSxwZT0vXig/OmNoZWNrYm94fHJhZGlvKSQvaSxkZT0vPChbYS16XVteXC9cMD5ceDIwXHRcclxuXGZdKikvaSxoZT0vXiR8Xm1vZHVsZSR8XC8oPzpqYXZhfGVjbWEpc2NyaXB0L2k7Y2U9RS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkuYXBwZW5kQ2hpbGQoRS5jcmVhdGVFbGVtZW50KCJkaXYiKSksKGZlPUUuY3JlYXRlRWxlbWVudCgiaW5wdXQiKSkuc2V0QXR0cmlidXRlKCJ0eXBlIiwicmFkaW8iKSxmZS5zZXRBdHRyaWJ1dGUoImNoZWNrZWQiLCJjaGVja2VkIiksZmUuc2V0QXR0cmlidXRlKCJuYW1lIiwidCIpLGNlLmFwcGVuZENoaWxkKGZlKSx5LmNoZWNrQ2xvbmU9Y2UuY2xvbmVOb2RlKCEwKS5jbG9uZU5vZGUoITApLmxhc3RDaGlsZC5jaGVja2VkLGNlLmlubmVySFRNTD0iPHRleHRhcmVhPng8L3RleHRhcmVhPiIseS5ub0Nsb25lQ2hlY2tlZD0hIWNlLmNsb25lTm9kZSghMCkubGFzdENoaWxkLmRlZmF1bHRWYWx1ZSxjZS5pbm5lckhUTUw9IjxvcHRpb24+PC9vcHRpb24+Iix5Lm9wdGlvbj0hIWNlLmxhc3RDaGlsZDt2YXIgZ2U9e3RoZWFkOlsxLCI8dGFibGU+IiwiPC90YWJsZT4iXSxjb2w6WzIsIjx0YWJsZT48Y29sZ3JvdXA+IiwiPC9jb2xncm91cD48L3RhYmxlPiJdLHRyOlsyLCI8dGFibGU+PHRib2R5PiIsIjwvdGJvZHk+PC90YWJsZT4iXSx0ZDpbMywiPHRhYmxlPjx0Ym9keT48dHI+IiwiPC90cj48L3Rib2R5PjwvdGFibGU+Il0sX2RlZmF1bHQ6WzAsIiIsIiJdfTtmdW5jdGlvbiB2ZShlLHQpe3ZhciBuO3JldHVybiBuPSJ1bmRlZmluZWQiIT10eXBlb2YgZS5nZXRFbGVtZW50c0J5VGFnTmFtZT9lLmdldEVsZW1lbnRzQnlUYWdOYW1lKHR8fCIqIik6InVuZGVmaW5lZCIhPXR5cGVvZiBlLnF1ZXJ5U2VsZWN0b3JBbGw/ZS5xdWVyeVNlbGVjdG9yQWxsKHR8fCIqIik6W10sdm9pZCAwPT09dHx8dCYmQShlLHQpP1MubWVyZ2UoW2VdLG4pOm59ZnVuY3Rpb24geWUoZSx0KXtmb3IodmFyIG49MCxyPWUubGVuZ3RoO248cjtuKyspWS5zZXQoZVtuXSwiZ2xvYmFsRXZhbCIsIXR8fFkuZ2V0KHRbbl0sImdsb2JhbEV2YWwiKSl9Z2UudGJvZHk9Z2UudGZvb3Q9Z2UuY29sZ3JvdXA9Z2UuY2FwdGlvbj1nZS50aGVhZCxnZS50aD1nZS50ZCx5Lm9wdGlvbnx8KGdlLm9wdGdyb3VwPWdlLm9wdGlvbj1bMSwiPHNlbGVjdCBtdWx0aXBsZT0nbXVsdGlwbGUnPiIsIjwvc2VsZWN0PiJdKTt2YXIgbWU9Lzx8JiM/XHcrOy87ZnVuY3Rpb24geGUoZSx0LG4scixpKXtmb3IodmFyIG8sYSxzLHUsbCxjLGY9dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkscD1bXSxkPTAsaD1lLmxlbmd0aDtkPGg7ZCsrKWlmKChvPWVbZF0pfHwwPT09bylpZigib2JqZWN0Ij09PXcobykpUy5tZXJnZShwLG8ubm9kZVR5cGU/W29dOm8pO2Vsc2UgaWYobWUudGVzdChvKSl7YT1hfHxmLmFwcGVuZENoaWxkKHQuY3JlYXRlRWxlbWVudCgiZGl2IikpLHM9KGRlLmV4ZWMobyl8fFsiIiwiIl0pWzFdLnRvTG93ZXJDYXNlKCksdT1nZVtzXXx8Z2UuX2RlZmF1bHQsYS5pbm5lckhUTUw9dVsxXStTLmh0bWxQcmVmaWx0ZXIobykrdVsyXSxjPXVbMF07d2hpbGUoYy0tKWE9YS5sYXN0Q2hpbGQ7Uy5tZXJnZShwLGEuY2hpbGROb2RlcyksKGE9Zi5maXJzdENoaWxkKS50ZXh0Q29udGVudD0iIn1lbHNlIHAucHVzaCh0LmNyZWF0ZVRleHROb2RlKG8pKTtmLnRleHRDb250ZW50PSIiLGQ9MDt3aGlsZShvPXBbZCsrXSlpZihyJiYtMTxTLmluQXJyYXkobyxyKSlpJiZpLnB1c2gobyk7ZWxzZSBpZihsPWllKG8pLGE9dmUoZi5hcHBlbmRDaGlsZChvKSwic2NyaXB0IiksbCYmeWUoYSksbil7Yz0wO3doaWxlKG89YVtjKytdKWhlLnRlc3Qoby50eXBlfHwiIikmJm4ucHVzaChvKX1yZXR1cm4gZn12YXIgYmU9L14oW14uXSopKD86XC4oLispfCkvO2Z1bmN0aW9uIHdlKCl7cmV0dXJuITB9ZnVuY3Rpb24gVGUoKXtyZXR1cm4hMX1mdW5jdGlvbiBDZShlLHQpe3JldHVybiBlPT09ZnVuY3Rpb24oKXt0cnl7cmV0dXJuIEUuYWN0aXZlRWxlbWVudH1jYXRjaChlKXt9fSgpPT0oImZvY3VzIj09PXQpfWZ1bmN0aW9uIEVlKGUsdCxuLHIsaSxvKXt2YXIgYSxzO2lmKCJvYmplY3QiPT10eXBlb2YgdCl7Zm9yKHMgaW4ic3RyaW5nIiE9dHlwZW9mIG4mJihyPXJ8fG4sbj12b2lkIDApLHQpRWUoZSxzLG4scix0W3NdLG8pO3JldHVybiBlfWlmKG51bGw9PXImJm51bGw9PWk/KGk9bixyPW49dm9pZCAwKTpudWxsPT1pJiYoInN0cmluZyI9PXR5cGVvZiBuPyhpPXIscj12b2lkIDApOihpPXIscj1uLG49dm9pZCAwKSksITE9PT1pKWk9VGU7ZWxzZSBpZighaSlyZXR1cm4gZTtyZXR1cm4gMT09PW8mJihhPWksKGk9ZnVuY3Rpb24oZSl7cmV0dXJuIFMoKS5vZmYoZSksYS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9KS5ndWlkPWEuZ3VpZHx8KGEuZ3VpZD1TLmd1aWQrKykpLGUuZWFjaChmdW5jdGlvbigpe1MuZXZlbnQuYWRkKHRoaXMsdCxpLHIsbil9KX1mdW5jdGlvbiBTZShlLGksbyl7bz8oWS5zZXQoZSxpLCExKSxTLmV2ZW50LmFkZChlLGkse25hbWVzcGFjZTohMSxoYW5kbGVyOmZ1bmN0aW9uKGUpe3ZhciB0LG4scj1ZLmdldCh0aGlzLGkpO2lmKDEmZS5pc1RyaWdnZXImJnRoaXNbaV0pe2lmKHIubGVuZ3RoKShTLmV2ZW50LnNwZWNpYWxbaV18fHt9KS5kZWxlZ2F0ZVR5cGUmJmUuc3RvcFByb3BhZ2F0aW9uKCk7ZWxzZSBpZihyPXMuY2FsbChhcmd1bWVudHMpLFkuc2V0KHRoaXMsaSxyKSx0PW8odGhpcyxpKSx0aGlzW2ldKCksciE9PShuPVkuZ2V0KHRoaXMsaSkpfHx0P1kuc2V0KHRoaXMsaSwhMSk6bj17fSxyIT09bilyZXR1cm4gZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSxlLnByZXZlbnREZWZhdWx0KCksbiYmbi52YWx1ZX1lbHNlIHIubGVuZ3RoJiYoWS5zZXQodGhpcyxpLHt2YWx1ZTpTLmV2ZW50LnRyaWdnZXIoUy5leHRlbmQoclswXSxTLkV2ZW50LnByb3RvdHlwZSksci5zbGljZSgxKSx0aGlzKX0pLGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCkpfX0pKTp2b2lkIDA9PT1ZLmdldChlLGkpJiZTLmV2ZW50LmFkZChlLGksd2UpfVMuZXZlbnQ9e2dsb2JhbDp7fSxhZGQ6ZnVuY3Rpb24odCxlLG4scixpKXt2YXIgbyxhLHMsdSxsLGMsZixwLGQsaCxnLHY9WS5nZXQodCk7aWYoVih0KSl7bi5oYW5kbGVyJiYobj0obz1uKS5oYW5kbGVyLGk9by5zZWxlY3RvciksaSYmUy5maW5kLm1hdGNoZXNTZWxlY3RvcihyZSxpKSxuLmd1aWR8fChuLmd1aWQ9Uy5ndWlkKyspLCh1PXYuZXZlbnRzKXx8KHU9di5ldmVudHM9T2JqZWN0LmNyZWF0ZShudWxsKSksKGE9di5oYW5kbGUpfHwoYT12LmhhbmRsZT1mdW5jdGlvbihlKXtyZXR1cm4idW5kZWZpbmVkIiE9dHlwZW9mIFMmJlMuZXZlbnQudHJpZ2dlcmVkIT09ZS50eXBlP1MuZXZlbnQuZGlzcGF0Y2guYXBwbHkodCxhcmd1bWVudHMpOnZvaWQgMH0pLGw9KGU9KGV8fCIiKS5tYXRjaChQKXx8WyIiXSkubGVuZ3RoO3doaWxlKGwtLSlkPWc9KHM9YmUuZXhlYyhlW2xdKXx8W10pWzFdLGg9KHNbMl18fCIiKS5zcGxpdCgiLiIpLnNvcnQoKSxkJiYoZj1TLmV2ZW50LnNwZWNpYWxbZF18fHt9LGQ9KGk/Zi5kZWxlZ2F0ZVR5cGU6Zi5iaW5kVHlwZSl8fGQsZj1TLmV2ZW50LnNwZWNpYWxbZF18fHt9LGM9Uy5leHRlbmQoe3R5cGU6ZCxvcmlnVHlwZTpnLGRhdGE6cixoYW5kbGVyOm4sZ3VpZDpuLmd1aWQsc2VsZWN0b3I6aSxuZWVkc0NvbnRleHQ6aSYmUy5leHByLm1hdGNoLm5lZWRzQ29udGV4dC50ZXN0KGkpLG5hbWVzcGFjZTpoLmpvaW4oIi4iKX0sbyksKHA9dVtkXSl8fCgocD11W2RdPVtdKS5kZWxlZ2F0ZUNvdW50PTAsZi5zZXR1cCYmITEhPT1mLnNldHVwLmNhbGwodCxyLGgsYSl8fHQuYWRkRXZlbnRMaXN0ZW5lciYmdC5hZGRFdmVudExpc3RlbmVyKGQsYSkpLGYuYWRkJiYoZi5hZGQuY2FsbCh0LGMpLGMuaGFuZGxlci5ndWlkfHwoYy5oYW5kbGVyLmd1aWQ9bi5ndWlkKSksaT9wLnNwbGljZShwLmRlbGVnYXRlQ291bnQrKywwLGMpOnAucHVzaChjKSxTLmV2ZW50Lmdsb2JhbFtkXT0hMCl9fSxyZW1vdmU6ZnVuY3Rpb24oZSx0LG4scixpKXt2YXIgbyxhLHMsdSxsLGMsZixwLGQsaCxnLHY9WS5oYXNEYXRhKGUpJiZZLmdldChlKTtpZih2JiYodT12LmV2ZW50cykpe2w9KHQ9KHR8fCIiKS5tYXRjaChQKXx8WyIiXSkubGVuZ3RoO3doaWxlKGwtLSlpZihkPWc9KHM9YmUuZXhlYyh0W2xdKXx8W10pWzFdLGg9KHNbMl18fCIiKS5zcGxpdCgiLiIpLnNvcnQoKSxkKXtmPVMuZXZlbnQuc3BlY2lhbFtkXXx8e30scD11W2Q9KHI/Zi5kZWxlZ2F0ZVR5cGU6Zi5iaW5kVHlwZSl8fGRdfHxbXSxzPXNbMl0mJm5ldyBSZWdFeHAoIihefFxcLikiK2guam9pbigiXFwuKD86LipcXC58KSIpKyIoXFwufCQpIiksYT1vPXAubGVuZ3RoO3doaWxlKG8tLSljPXBbb10sIWkmJmchPT1jLm9yaWdUeXBlfHxuJiZuLmd1aWQhPT1jLmd1aWR8fHMmJiFzLnRlc3QoYy5uYW1lc3BhY2UpfHxyJiZyIT09Yy5zZWxlY3RvciYmKCIqKiIhPT1yfHwhYy5zZWxlY3Rvcil8fChwLnNwbGljZShvLDEpLGMuc2VsZWN0b3ImJnAuZGVsZWdhdGVDb3VudC0tLGYucmVtb3ZlJiZmLnJlbW92ZS5jYWxsKGUsYykpO2EmJiFwLmxlbmd0aCYmKGYudGVhcmRvd24mJiExIT09Zi50ZWFyZG93bi5jYWxsKGUsaCx2LmhhbmRsZSl8fFMucmVtb3ZlRXZlbnQoZSxkLHYuaGFuZGxlKSxkZWxldGUgdVtkXSl9ZWxzZSBmb3IoZCBpbiB1KVMuZXZlbnQucmVtb3ZlKGUsZCt0W2xdLG4sciwhMCk7Uy5pc0VtcHR5T2JqZWN0KHUpJiZZLnJlbW92ZShlLCJoYW5kbGUgZXZlbnRzIil9fSxkaXNwYXRjaDpmdW5jdGlvbihlKXt2YXIgdCxuLHIsaSxvLGEscz1uZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCksdT1TLmV2ZW50LmZpeChlKSxsPShZLmdldCh0aGlzLCJldmVudHMiKXx8T2JqZWN0LmNyZWF0ZShudWxsKSlbdS50eXBlXXx8W10sYz1TLmV2ZW50LnNwZWNpYWxbdS50eXBlXXx8e307Zm9yKHNbMF09dSx0PTE7dDxhcmd1bWVudHMubGVuZ3RoO3QrKylzW3RdPWFyZ3VtZW50c1t0XTtpZih1LmRlbGVnYXRlVGFyZ2V0PXRoaXMsIWMucHJlRGlzcGF0Y2h8fCExIT09Yy5wcmVEaXNwYXRjaC5jYWxsKHRoaXMsdSkpe2E9Uy5ldmVudC5oYW5kbGVycy5jYWxsKHRoaXMsdSxsKSx0PTA7d2hpbGUoKGk9YVt0KytdKSYmIXUuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSl7dS5jdXJyZW50VGFyZ2V0PWkuZWxlbSxuPTA7d2hpbGUoKG89aS5oYW5kbGVyc1tuKytdKSYmIXUuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQoKSl1LnJuYW1lc3BhY2UmJiExIT09by5uYW1lc3BhY2UmJiF1LnJuYW1lc3BhY2UudGVzdChvLm5hbWVzcGFjZSl8fCh1LmhhbmRsZU9iaj1vLHUuZGF0YT1vLmRhdGEsdm9pZCAwIT09KHI9KChTLmV2ZW50LnNwZWNpYWxbby5vcmlnVHlwZV18fHt9KS5oYW5kbGV8fG8uaGFuZGxlcikuYXBwbHkoaS5lbGVtLHMpKSYmITE9PT0odS5yZXN1bHQ9cikmJih1LnByZXZlbnREZWZhdWx0KCksdS5zdG9wUHJvcGFnYXRpb24oKSkpfXJldHVybiBjLnBvc3REaXNwYXRjaCYmYy5wb3N0RGlzcGF0Y2guY2FsbCh0aGlzLHUpLHUucmVzdWx0fX0saGFuZGxlcnM6ZnVuY3Rpb24oZSx0KXt2YXIgbixyLGksbyxhLHM9W10sdT10LmRlbGVnYXRlQ291bnQsbD1lLnRhcmdldDtpZih1JiZsLm5vZGVUeXBlJiYhKCJjbGljayI9PT1lLnR5cGUmJjE8PWUuYnV0dG9uKSlmb3IoO2whPT10aGlzO2w9bC5wYXJlbnROb2RlfHx0aGlzKWlmKDE9PT1sLm5vZGVUeXBlJiYoImNsaWNrIiE9PWUudHlwZXx8ITAhPT1sLmRpc2FibGVkKSl7Zm9yKG89W10sYT17fSxuPTA7bjx1O24rKyl2b2lkIDA9PT1hW2k9KHI9dFtuXSkuc2VsZWN0b3IrIiAiXSYmKGFbaV09ci5uZWVkc0NvbnRleHQ/LTE8UyhpLHRoaXMpLmluZGV4KGwpOlMuZmluZChpLHRoaXMsbnVsbCxbbF0pLmxlbmd0aCksYVtpXSYmby5wdXNoKHIpO28ubGVuZ3RoJiZzLnB1c2goe2VsZW06bCxoYW5kbGVyczpvfSl9cmV0dXJuIGw9dGhpcyx1PHQubGVuZ3RoJiZzLnB1c2goe2VsZW06bCxoYW5kbGVyczp0LnNsaWNlKHUpfSksc30sYWRkUHJvcDpmdW5jdGlvbih0LGUpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShTLkV2ZW50LnByb3RvdHlwZSx0LHtlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCxnZXQ6bShlKT9mdW5jdGlvbigpe2lmKHRoaXMub3JpZ2luYWxFdmVudClyZXR1cm4gZSh0aGlzLm9yaWdpbmFsRXZlbnQpfTpmdW5jdGlvbigpe2lmKHRoaXMub3JpZ2luYWxFdmVudClyZXR1cm4gdGhpcy5vcmlnaW5hbEV2ZW50W3RdfSxzZXQ6ZnVuY3Rpb24oZSl7T2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsdCx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6ZX0pfX0pfSxmaXg6ZnVuY3Rpb24oZSl7cmV0dXJuIGVbUy5leHBhbmRvXT9lOm5ldyBTLkV2ZW50KGUpfSxzcGVjaWFsOntsb2FkOntub0J1YmJsZTohMH0sY2xpY2s6e3NldHVwOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXN8fGU7cmV0dXJuIHBlLnRlc3QodC50eXBlKSYmdC5jbGljayYmQSh0LCJpbnB1dCIpJiZTZSh0LCJjbGljayIsd2UpLCExfSx0cmlnZ2VyOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXN8fGU7cmV0dXJuIHBlLnRlc3QodC50eXBlKSYmdC5jbGljayYmQSh0LCJpbnB1dCIpJiZTZSh0LCJjbGljayIpLCEwfSxfZGVmYXVsdDpmdW5jdGlvbihlKXt2YXIgdD1lLnRhcmdldDtyZXR1cm4gcGUudGVzdCh0LnR5cGUpJiZ0LmNsaWNrJiZBKHQsImlucHV0IikmJlkuZ2V0KHQsImNsaWNrIil8fEEodCwiYSIpfX0sYmVmb3JldW5sb2FkOntwb3N0RGlzcGF0Y2g6ZnVuY3Rpb24oZSl7dm9pZCAwIT09ZS5yZXN1bHQmJmUub3JpZ2luYWxFdmVudCYmKGUub3JpZ2luYWxFdmVudC5yZXR1cm5WYWx1ZT1lLnJlc3VsdCl9fX19LFMucmVtb3ZlRXZlbnQ9ZnVuY3Rpb24oZSx0LG4pe2UucmVtb3ZlRXZlbnRMaXN0ZW5lciYmZS5yZW1vdmVFdmVudExpc3RlbmVyKHQsbil9LFMuRXZlbnQ9ZnVuY3Rpb24oZSx0KXtpZighKHRoaXMgaW5zdGFuY2VvZiBTLkV2ZW50KSlyZXR1cm4gbmV3IFMuRXZlbnQoZSx0KTtlJiZlLnR5cGU/KHRoaXMub3JpZ2luYWxFdmVudD1lLHRoaXMudHlwZT1lLnR5cGUsdGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQ9ZS5kZWZhdWx0UHJldmVudGVkfHx2b2lkIDA9PT1lLmRlZmF1bHRQcmV2ZW50ZWQmJiExPT09ZS5yZXR1cm5WYWx1ZT93ZTpUZSx0aGlzLnRhcmdldD1lLnRhcmdldCYmMz09PWUudGFyZ2V0Lm5vZGVUeXBlP2UudGFyZ2V0LnBhcmVudE5vZGU6ZS50YXJnZXQsdGhpcy5jdXJyZW50VGFyZ2V0PWUuY3VycmVudFRhcmdldCx0aGlzLnJlbGF0ZWRUYXJnZXQ9ZS5yZWxhdGVkVGFyZ2V0KTp0aGlzLnR5cGU9ZSx0JiZTLmV4dGVuZCh0aGlzLHQpLHRoaXMudGltZVN0YW1wPWUmJmUudGltZVN0YW1wfHxEYXRlLm5vdygpLHRoaXNbUy5leHBhbmRvXT0hMH0sUy5FdmVudC5wcm90b3R5cGU9e2NvbnN0cnVjdG9yOlMuRXZlbnQsaXNEZWZhdWx0UHJldmVudGVkOlRlLGlzUHJvcGFnYXRpb25TdG9wcGVkOlRlLGlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOlRlLGlzU2ltdWxhdGVkOiExLHByZXZlbnREZWZhdWx0OmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5vcmlnaW5hbEV2ZW50O3RoaXMuaXNEZWZhdWx0UHJldmVudGVkPXdlLGUmJiF0aGlzLmlzU2ltdWxhdGVkJiZlLnByZXZlbnREZWZhdWx0KCl9LHN0b3BQcm9wYWdhdGlvbjpmdW5jdGlvbigpe3ZhciBlPXRoaXMub3JpZ2luYWxFdmVudDt0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkPXdlLGUmJiF0aGlzLmlzU2ltdWxhdGVkJiZlLnN0b3BQcm9wYWdhdGlvbigpfSxzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb246ZnVuY3Rpb24oKXt2YXIgZT10aGlzLm9yaWdpbmFsRXZlbnQ7dGhpcy5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZD13ZSxlJiYhdGhpcy5pc1NpbXVsYXRlZCYmZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSx0aGlzLnN0b3BQcm9wYWdhdGlvbigpfX0sUy5lYWNoKHthbHRLZXk6ITAsYnViYmxlczohMCxjYW5jZWxhYmxlOiEwLGNoYW5nZWRUb3VjaGVzOiEwLGN0cmxLZXk6ITAsZGV0YWlsOiEwLGV2ZW50UGhhc2U6ITAsbWV0YUtleTohMCxwYWdlWDohMCxwYWdlWTohMCxzaGlmdEtleTohMCx2aWV3OiEwLCJjaGFyIjohMCxjb2RlOiEwLGNoYXJDb2RlOiEwLGtleTohMCxrZXlDb2RlOiEwLGJ1dHRvbjohMCxidXR0b25zOiEwLGNsaWVudFg6ITAsY2xpZW50WTohMCxvZmZzZXRYOiEwLG9mZnNldFk6ITAscG9pbnRlcklkOiEwLHBvaW50ZXJUeXBlOiEwLHNjcmVlblg6ITAsc2NyZWVuWTohMCx0YXJnZXRUb3VjaGVzOiEwLHRvRWxlbWVudDohMCx0b3VjaGVzOiEwLHdoaWNoOiEwfSxTLmV2ZW50LmFkZFByb3ApLFMuZWFjaCh7Zm9jdXM6ImZvY3VzaW4iLGJsdXI6ImZvY3Vzb3V0In0sZnVuY3Rpb24oZSx0KXtTLmV2ZW50LnNwZWNpYWxbZV09e3NldHVwOmZ1bmN0aW9uKCl7cmV0dXJuIFNlKHRoaXMsZSxDZSksITF9LHRyaWdnZXI6ZnVuY3Rpb24oKXtyZXR1cm4gU2UodGhpcyxlKSwhMH0sX2RlZmF1bHQ6ZnVuY3Rpb24oKXtyZXR1cm4hMH0sZGVsZWdhdGVUeXBlOnR9fSksUy5lYWNoKHttb3VzZWVudGVyOiJtb3VzZW92ZXIiLG1vdXNlbGVhdmU6Im1vdXNlb3V0Iixwb2ludGVyZW50ZXI6InBvaW50ZXJvdmVyIixwb2ludGVybGVhdmU6InBvaW50ZXJvdXQifSxmdW5jdGlvbihlLGkpe1MuZXZlbnQuc3BlY2lhbFtlXT17ZGVsZWdhdGVUeXBlOmksYmluZFR5cGU6aSxoYW5kbGU6ZnVuY3Rpb24oZSl7dmFyIHQsbj1lLnJlbGF0ZWRUYXJnZXQscj1lLmhhbmRsZU9iajtyZXR1cm4gbiYmKG49PT10aGlzfHxTLmNvbnRhaW5zKHRoaXMsbikpfHwoZS50eXBlPXIub3JpZ1R5cGUsdD1yLmhhbmRsZXIuYXBwbHkodGhpcyxhcmd1bWVudHMpLGUudHlwZT1pKSx0fX19KSxTLmZuLmV4dGVuZCh7b246ZnVuY3Rpb24oZSx0LG4scil7cmV0dXJuIEVlKHRoaXMsZSx0LG4scil9LG9uZTpmdW5jdGlvbihlLHQsbixyKXtyZXR1cm4gRWUodGhpcyxlLHQsbixyLDEpfSxvZmY6ZnVuY3Rpb24oZSx0LG4pe3ZhciByLGk7aWYoZSYmZS5wcmV2ZW50RGVmYXVsdCYmZS5oYW5kbGVPYmopcmV0dXJuIHI9ZS5oYW5kbGVPYmosUyhlLmRlbGVnYXRlVGFyZ2V0KS5vZmYoci5uYW1lc3BhY2U/ci5vcmlnVHlwZSsiLiIrci5uYW1lc3BhY2U6ci5vcmlnVHlwZSxyLnNlbGVjdG9yLHIuaGFuZGxlciksdGhpcztpZigib2JqZWN0Ij09dHlwZW9mIGUpe2ZvcihpIGluIGUpdGhpcy5vZmYoaSx0LGVbaV0pO3JldHVybiB0aGlzfXJldHVybiExIT09dCYmImZ1bmN0aW9uIiE9dHlwZW9mIHR8fChuPXQsdD12b2lkIDApLCExPT09biYmKG49VGUpLHRoaXMuZWFjaChmdW5jdGlvbigpe1MuZXZlbnQucmVtb3ZlKHRoaXMsZSxuLHQpfSl9fSk7dmFyIGtlPS88c2NyaXB0fDxzdHlsZXw8bGluay9pLEFlPS9jaGVja2VkXHMqKD86W149XXw9XHMqLmNoZWNrZWQuKS9pLE5lPS9eXHMqPCEoPzpcW0NEQVRBXFt8LS0pfCg/OlxdXF18LS0pPlxzKiQvZztmdW5jdGlvbiBqZShlLHQpe3JldHVybiBBKGUsInRhYmxlIikmJkEoMTEhPT10Lm5vZGVUeXBlP3Q6dC5maXJzdENoaWxkLCJ0ciIpJiZTKGUpLmNoaWxkcmVuKCJ0Ym9keSIpWzBdfHxlfWZ1bmN0aW9uIERlKGUpe3JldHVybiBlLnR5cGU9KG51bGwhPT1lLmdldEF0dHJpYnV0ZSgidHlwZSIpKSsiLyIrZS50eXBlLGV9ZnVuY3Rpb24gcWUoZSl7cmV0dXJuInRydWUvIj09PShlLnR5cGV8fCIiKS5zbGljZSgwLDUpP2UudHlwZT1lLnR5cGUuc2xpY2UoNSk6ZS5yZW1vdmVBdHRyaWJ1dGUoInR5cGUiKSxlfWZ1bmN0aW9uIExlKGUsdCl7dmFyIG4scixpLG8sYSxzO2lmKDE9PT10Lm5vZGVUeXBlKXtpZihZLmhhc0RhdGEoZSkmJihzPVkuZ2V0KGUpLmV2ZW50cykpZm9yKGkgaW4gWS5yZW1vdmUodCwiaGFuZGxlIGV2ZW50cyIpLHMpZm9yKG49MCxyPXNbaV0ubGVuZ3RoO248cjtuKyspUy5ldmVudC5hZGQodCxpLHNbaV1bbl0pO1EuaGFzRGF0YShlKSYmKG89US5hY2Nlc3MoZSksYT1TLmV4dGVuZCh7fSxvKSxRLnNldCh0LGEpKX19ZnVuY3Rpb24gSGUobixyLGksbyl7cj1nKHIpO3ZhciBlLHQsYSxzLHUsbCxjPTAsZj1uLmxlbmd0aCxwPWYtMSxkPXJbMF0saD1tKGQpO2lmKGh8fDE8ZiYmInN0cmluZyI9PXR5cGVvZiBkJiYheS5jaGVja0Nsb25lJiZBZS50ZXN0KGQpKXJldHVybiBuLmVhY2goZnVuY3Rpb24oZSl7dmFyIHQ9bi5lcShlKTtoJiYoclswXT1kLmNhbGwodGhpcyxlLHQuaHRtbCgpKSksSGUodCxyLGksbyl9KTtpZihmJiYodD0oZT14ZShyLG5bMF0ub3duZXJEb2N1bWVudCwhMSxuLG8pKS5maXJzdENoaWxkLDE9PT1lLmNoaWxkTm9kZXMubGVuZ3RoJiYoZT10KSx0fHxvKSl7Zm9yKHM9KGE9Uy5tYXAodmUoZSwic2NyaXB0IiksRGUpKS5sZW5ndGg7YzxmO2MrKyl1PWUsYyE9PXAmJih1PVMuY2xvbmUodSwhMCwhMCkscyYmUy5tZXJnZShhLHZlKHUsInNjcmlwdCIpKSksaS5jYWxsKG5bY10sdSxjKTtpZihzKWZvcihsPWFbYS5sZW5ndGgtMV0ub3duZXJEb2N1bWVudCxTLm1hcChhLHFlKSxjPTA7YzxzO2MrKyl1PWFbY10saGUudGVzdCh1LnR5cGV8fCIiKSYmIVkuYWNjZXNzKHUsImdsb2JhbEV2YWwiKSYmUy5jb250YWlucyhsLHUpJiYodS5zcmMmJiJtb2R1bGUiIT09KHUudHlwZXx8IiIpLnRvTG93ZXJDYXNlKCk/Uy5fZXZhbFVybCYmIXUubm9Nb2R1bGUmJlMuX2V2YWxVcmwodS5zcmMse25vbmNlOnUubm9uY2V8fHUuZ2V0QXR0cmlidXRlKCJub25jZSIpfSxsKTpiKHUudGV4dENvbnRlbnQucmVwbGFjZShOZSwiIiksdSxsKSl9cmV0dXJuIG59ZnVuY3Rpb24gT2UoZSx0LG4pe2Zvcih2YXIgcixpPXQ/Uy5maWx0ZXIodCxlKTplLG89MDtudWxsIT0ocj1pW29dKTtvKyspbnx8MSE9PXIubm9kZVR5cGV8fFMuY2xlYW5EYXRhKHZlKHIpKSxyLnBhcmVudE5vZGUmJihuJiZpZShyKSYmeWUodmUociwic2NyaXB0IikpLHIucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChyKSk7cmV0dXJuIGV9Uy5leHRlbmQoe2h0bWxQcmVmaWx0ZXI6ZnVuY3Rpb24oZSl7cmV0dXJuIGV9LGNsb25lOmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG8sYSxzLHUsbCxjPWUuY2xvbmVOb2RlKCEwKSxmPWllKGUpO2lmKCEoeS5ub0Nsb25lQ2hlY2tlZHx8MSE9PWUubm9kZVR5cGUmJjExIT09ZS5ub2RlVHlwZXx8Uy5pc1hNTERvYyhlKSkpZm9yKGE9dmUoYykscj0wLGk9KG89dmUoZSkpLmxlbmd0aDtyPGk7cisrKXM9b1tyXSx1PWFbcl0sdm9pZCAwLCJpbnB1dCI9PT0obD11Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpJiZwZS50ZXN0KHMudHlwZSk/dS5jaGVja2VkPXMuY2hlY2tlZDoiaW5wdXQiIT09bCYmInRleHRhcmVhIiE9PWx8fCh1LmRlZmF1bHRWYWx1ZT1zLmRlZmF1bHRWYWx1ZSk7aWYodClpZihuKWZvcihvPW98fHZlKGUpLGE9YXx8dmUoYykscj0wLGk9by5sZW5ndGg7cjxpO3IrKylMZShvW3JdLGFbcl0pO2Vsc2UgTGUoZSxjKTtyZXR1cm4gMDwoYT12ZShjLCJzY3JpcHQiKSkubGVuZ3RoJiZ5ZShhLCFmJiZ2ZShlLCJzY3JpcHQiKSksY30sY2xlYW5EYXRhOmZ1bmN0aW9uKGUpe2Zvcih2YXIgdCxuLHIsaT1TLmV2ZW50LnNwZWNpYWwsbz0wO3ZvaWQgMCE9PShuPWVbb10pO28rKylpZihWKG4pKXtpZih0PW5bWS5leHBhbmRvXSl7aWYodC5ldmVudHMpZm9yKHIgaW4gdC5ldmVudHMpaVtyXT9TLmV2ZW50LnJlbW92ZShuLHIpOlMucmVtb3ZlRXZlbnQobixyLHQuaGFuZGxlKTtuW1kuZXhwYW5kb109dm9pZCAwfW5bUS5leHBhbmRvXSYmKG5bUS5leHBhbmRvXT12b2lkIDApfX19KSxTLmZuLmV4dGVuZCh7ZGV0YWNoOmZ1bmN0aW9uKGUpe3JldHVybiBPZSh0aGlzLGUsITApfSxyZW1vdmU6ZnVuY3Rpb24oZSl7cmV0dXJuIE9lKHRoaXMsZSl9LHRleHQ6ZnVuY3Rpb24oZSl7cmV0dXJuICQodGhpcyxmdW5jdGlvbihlKXtyZXR1cm4gdm9pZCAwPT09ZT9TLnRleHQodGhpcyk6dGhpcy5lbXB0eSgpLmVhY2goZnVuY3Rpb24oKXsxIT09dGhpcy5ub2RlVHlwZSYmMTEhPT10aGlzLm5vZGVUeXBlJiY5IT09dGhpcy5ub2RlVHlwZXx8KHRoaXMudGV4dENvbnRlbnQ9ZSl9KX0sbnVsbCxlLGFyZ3VtZW50cy5sZW5ndGgpfSxhcHBlbmQ6ZnVuY3Rpb24oKXtyZXR1cm4gSGUodGhpcyxhcmd1bWVudHMsZnVuY3Rpb24oZSl7MSE9PXRoaXMubm9kZVR5cGUmJjExIT09dGhpcy5ub2RlVHlwZSYmOSE9PXRoaXMubm9kZVR5cGV8fGplKHRoaXMsZSkuYXBwZW5kQ2hpbGQoZSl9KX0scHJlcGVuZDpmdW5jdGlvbigpe3JldHVybiBIZSh0aGlzLGFyZ3VtZW50cyxmdW5jdGlvbihlKXtpZigxPT09dGhpcy5ub2RlVHlwZXx8MTE9PT10aGlzLm5vZGVUeXBlfHw5PT09dGhpcy5ub2RlVHlwZSl7dmFyIHQ9amUodGhpcyxlKTt0Lmluc2VydEJlZm9yZShlLHQuZmlyc3RDaGlsZCl9fSl9LGJlZm9yZTpmdW5jdGlvbigpe3JldHVybiBIZSh0aGlzLGFyZ3VtZW50cyxmdW5jdGlvbihlKXt0aGlzLnBhcmVudE5vZGUmJnRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZSx0aGlzKX0pfSxhZnRlcjpmdW5jdGlvbigpe3JldHVybiBIZSh0aGlzLGFyZ3VtZW50cyxmdW5jdGlvbihlKXt0aGlzLnBhcmVudE5vZGUmJnRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZSx0aGlzLm5leHRTaWJsaW5nKX0pfSxlbXB0eTpmdW5jdGlvbigpe2Zvcih2YXIgZSx0PTA7bnVsbCE9KGU9dGhpc1t0XSk7dCsrKTE9PT1lLm5vZGVUeXBlJiYoUy5jbGVhbkRhdGEodmUoZSwhMSkpLGUudGV4dENvbnRlbnQ9IiIpO3JldHVybiB0aGlzfSxjbG9uZTpmdW5jdGlvbihlLHQpe3JldHVybiBlPW51bGwhPWUmJmUsdD1udWxsPT10P2U6dCx0aGlzLm1hcChmdW5jdGlvbigpe3JldHVybiBTLmNsb25lKHRoaXMsZSx0KX0pfSxodG1sOmZ1bmN0aW9uKGUpe3JldHVybiAkKHRoaXMsZnVuY3Rpb24oZSl7dmFyIHQ9dGhpc1swXXx8e30sbj0wLHI9dGhpcy5sZW5ndGg7aWYodm9pZCAwPT09ZSYmMT09PXQubm9kZVR5cGUpcmV0dXJuIHQuaW5uZXJIVE1MO2lmKCJzdHJpbmciPT10eXBlb2YgZSYmIWtlLnRlc3QoZSkmJiFnZVsoZGUuZXhlYyhlKXx8WyIiLCIiXSlbMV0udG9Mb3dlckNhc2UoKV0pe2U9Uy5odG1sUHJlZmlsdGVyKGUpO3RyeXtmb3IoO248cjtuKyspMT09PSh0PXRoaXNbbl18fHt9KS5ub2RlVHlwZSYmKFMuY2xlYW5EYXRhKHZlKHQsITEpKSx0LmlubmVySFRNTD1lKTt0PTB9Y2F0Y2goZSl7fX10JiZ0aGlzLmVtcHR5KCkuYXBwZW5kKGUpfSxudWxsLGUsYXJndW1lbnRzLmxlbmd0aCl9LHJlcGxhY2VXaXRoOmZ1bmN0aW9uKCl7dmFyIG49W107cmV0dXJuIEhlKHRoaXMsYXJndW1lbnRzLGZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMucGFyZW50Tm9kZTtTLmluQXJyYXkodGhpcyxuKTwwJiYoUy5jbGVhbkRhdGEodmUodGhpcykpLHQmJnQucmVwbGFjZUNoaWxkKGUsdGhpcykpfSxuKX19KSxTLmVhY2goe2FwcGVuZFRvOiJhcHBlbmQiLHByZXBlbmRUbzoicHJlcGVuZCIsaW5zZXJ0QmVmb3JlOiJiZWZvcmUiLGluc2VydEFmdGVyOiJhZnRlciIscmVwbGFjZUFsbDoicmVwbGFjZVdpdGgifSxmdW5jdGlvbihlLGEpe1MuZm5bZV09ZnVuY3Rpb24oZSl7Zm9yKHZhciB0LG49W10scj1TKGUpLGk9ci5sZW5ndGgtMSxvPTA7bzw9aTtvKyspdD1vPT09aT90aGlzOnRoaXMuY2xvbmUoITApLFMocltvXSlbYV0odCksdS5hcHBseShuLHQuZ2V0KCkpO3JldHVybiB0aGlzLnB1c2hTdGFjayhuKX19KTt2YXIgUGU9bmV3IFJlZ0V4cCgiXigiK2VlKyIpKD8hcHgpW2EteiVdKyQiLCJpIiksUmU9ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3O3JldHVybiB0JiZ0Lm9wZW5lcnx8KHQ9QyksdC5nZXRDb21wdXRlZFN0eWxlKGUpfSxNZT1mdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvPXt9O2ZvcihpIGluIHQpb1tpXT1lLnN0eWxlW2ldLGUuc3R5bGVbaV09dFtpXTtmb3IoaSBpbiByPW4uY2FsbChlKSx0KWUuc3R5bGVbaV09b1tpXTtyZXR1cm4gcn0sSWU9bmV3IFJlZ0V4cChuZS5qb2luKCJ8IiksImkiKTtmdW5jdGlvbiBXZShlLHQsbil7dmFyIHIsaSxvLGEscz1lLnN0eWxlO3JldHVybihuPW58fFJlKGUpKSYmKCIiIT09KGE9bi5nZXRQcm9wZXJ0eVZhbHVlKHQpfHxuW3RdKXx8aWUoZSl8fChhPVMuc3R5bGUoZSx0KSksIXkucGl4ZWxCb3hTdHlsZXMoKSYmUGUudGVzdChhKSYmSWUudGVzdCh0KSYmKHI9cy53aWR0aCxpPXMubWluV2lkdGgsbz1zLm1heFdpZHRoLHMubWluV2lkdGg9cy5tYXhXaWR0aD1zLndpZHRoPWEsYT1uLndpZHRoLHMud2lkdGg9cixzLm1pbldpZHRoPWkscy5tYXhXaWR0aD1vKSksdm9pZCAwIT09YT9hKyIiOmF9ZnVuY3Rpb24gRmUoZSx0KXtyZXR1cm57Z2V0OmZ1bmN0aW9uKCl7aWYoIWUoKSlyZXR1cm4odGhpcy5nZXQ9dCkuYXBwbHkodGhpcyxhcmd1bWVudHMpO2RlbGV0ZSB0aGlzLmdldH19fSFmdW5jdGlvbigpe2Z1bmN0aW9uIGUoKXtpZihsKXt1LnN0eWxlLmNzc1RleHQ9InBvc2l0aW9uOmFic29sdXRlO2xlZnQ6LTExMTExcHg7d2lkdGg6NjBweDttYXJnaW4tdG9wOjFweDtwYWRkaW5nOjA7Ym9yZGVyOjAiLGwuc3R5bGUuY3NzVGV4dD0icG9zaXRpb246cmVsYXRpdmU7ZGlzcGxheTpibG9jaztib3gtc2l6aW5nOmJvcmRlci1ib3g7b3ZlcmZsb3c6c2Nyb2xsO21hcmdpbjphdXRvO2JvcmRlcjoxcHg7cGFkZGluZzoxcHg7d2lkdGg6NjAlO3RvcDoxJSIscmUuYXBwZW5kQ2hpbGQodSkuYXBwZW5kQ2hpbGQobCk7dmFyIGU9Qy5nZXRDb21wdXRlZFN0eWxlKGwpO249IjElIiE9PWUudG9wLHM9MTI9PT10KGUubWFyZ2luTGVmdCksbC5zdHlsZS5yaWdodD0iNjAlIixvPTM2PT09dChlLnJpZ2h0KSxyPTM2PT09dChlLndpZHRoKSxsLnN0eWxlLnBvc2l0aW9uPSJhYnNvbHV0ZSIsaT0xMj09PXQobC5vZmZzZXRXaWR0aC8zKSxyZS5yZW1vdmVDaGlsZCh1KSxsPW51bGx9fWZ1bmN0aW9uIHQoZSl7cmV0dXJuIE1hdGgucm91bmQocGFyc2VGbG9hdChlKSl9dmFyIG4scixpLG8sYSxzLHU9RS5jcmVhdGVFbGVtZW50KCJkaXYiKSxsPUUuY3JlYXRlRWxlbWVudCgiZGl2Iik7bC5zdHlsZSYmKGwuc3R5bGUuYmFja2dyb3VuZENsaXA9ImNvbnRlbnQtYm94IixsLmNsb25lTm9kZSghMCkuc3R5bGUuYmFja2dyb3VuZENsaXA9IiIseS5jbGVhckNsb25lU3R5bGU9ImNvbnRlbnQtYm94Ij09PWwuc3R5bGUuYmFja2dyb3VuZENsaXAsUy5leHRlbmQoeSx7Ym94U2l6aW5nUmVsaWFibGU6ZnVuY3Rpb24oKXtyZXR1cm4gZSgpLHJ9LHBpeGVsQm94U3R5bGVzOmZ1bmN0aW9uKCl7cmV0dXJuIGUoKSxvfSxwaXhlbFBvc2l0aW9uOmZ1bmN0aW9uKCl7cmV0dXJuIGUoKSxufSxyZWxpYWJsZU1hcmdpbkxlZnQ6ZnVuY3Rpb24oKXtyZXR1cm4gZSgpLHN9LHNjcm9sbGJveFNpemU6ZnVuY3Rpb24oKXtyZXR1cm4gZSgpLGl9LHJlbGlhYmxlVHJEaW1lbnNpb25zOmZ1bmN0aW9uKCl7dmFyIGUsdCxuLHI7cmV0dXJuIG51bGw9PWEmJihlPUUuY3JlYXRlRWxlbWVudCgidGFibGUiKSx0PUUuY3JlYXRlRWxlbWVudCgidHIiKSxuPUUuY3JlYXRlRWxlbWVudCgiZGl2IiksZS5zdHlsZS5jc3NUZXh0PSJwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0Oi0xMTExMXB4O2JvcmRlci1jb2xsYXBzZTpzZXBhcmF0ZSIsdC5zdHlsZS5jc3NUZXh0PSJib3JkZXI6MXB4IHNvbGlkIix0LnN0eWxlLmhlaWdodD0iMXB4IixuLnN0eWxlLmhlaWdodD0iOXB4IixuLnN0eWxlLmRpc3BsYXk9ImJsb2NrIixyZS5hcHBlbmRDaGlsZChlKS5hcHBlbmRDaGlsZCh0KS5hcHBlbmRDaGlsZChuKSxyPUMuZ2V0Q29tcHV0ZWRTdHlsZSh0KSxhPXBhcnNlSW50KHIuaGVpZ2h0LDEwKStwYXJzZUludChyLmJvcmRlclRvcFdpZHRoLDEwKStwYXJzZUludChyLmJvcmRlckJvdHRvbVdpZHRoLDEwKT09PXQub2Zmc2V0SGVpZ2h0LHJlLnJlbW92ZUNoaWxkKGUpKSxhfX0pKX0oKTt2YXIgQmU9WyJXZWJraXQiLCJNb3oiLCJtcyJdLCRlPUUuY3JlYXRlRWxlbWVudCgiZGl2Iikuc3R5bGUsX2U9e307ZnVuY3Rpb24gemUoZSl7dmFyIHQ9Uy5jc3NQcm9wc1tlXXx8X2VbZV07cmV0dXJuIHR8fChlIGluICRlP2U6X2VbZV09ZnVuY3Rpb24oZSl7dmFyIHQ9ZVswXS50b1VwcGVyQ2FzZSgpK2Uuc2xpY2UoMSksbj1CZS5sZW5ndGg7d2hpbGUobi0tKWlmKChlPUJlW25dK3QpaW4gJGUpcmV0dXJuIGV9KGUpfHxlKX12YXIgVWU9L14obm9uZXx0YWJsZSg/IS1jW2VhXSkuKykvLFhlPS9eLS0vLFZlPXtwb3NpdGlvbjoiYWJzb2x1dGUiLHZpc2liaWxpdHk6ImhpZGRlbiIsZGlzcGxheToiYmxvY2sifSxHZT17bGV0dGVyU3BhY2luZzoiMCIsZm9udFdlaWdodDoiNDAwIn07ZnVuY3Rpb24gWWUoZSx0LG4pe3ZhciByPXRlLmV4ZWModCk7cmV0dXJuIHI/TWF0aC5tYXgoMCxyWzJdLShufHwwKSkrKHJbM118fCJweCIpOnR9ZnVuY3Rpb24gUWUoZSx0LG4scixpLG8pe3ZhciBhPSJ3aWR0aCI9PT10PzE6MCxzPTAsdT0wO2lmKG49PT0ocj8iYm9yZGVyIjoiY29udGVudCIpKXJldHVybiAwO2Zvcig7YTw0O2ErPTIpIm1hcmdpbiI9PT1uJiYodSs9Uy5jc3MoZSxuK25lW2FdLCEwLGkpKSxyPygiY29udGVudCI9PT1uJiYodS09Uy5jc3MoZSwicGFkZGluZyIrbmVbYV0sITAsaSkpLCJtYXJnaW4iIT09biYmKHUtPVMuY3NzKGUsImJvcmRlciIrbmVbYV0rIldpZHRoIiwhMCxpKSkpOih1Kz1TLmNzcyhlLCJwYWRkaW5nIituZVthXSwhMCxpKSwicGFkZGluZyIhPT1uP3UrPVMuY3NzKGUsImJvcmRlciIrbmVbYV0rIldpZHRoIiwhMCxpKTpzKz1TLmNzcyhlLCJib3JkZXIiK25lW2FdKyJXaWR0aCIsITAsaSkpO3JldHVybiFyJiYwPD1vJiYodSs9TWF0aC5tYXgoMCxNYXRoLmNlaWwoZVsib2Zmc2V0Iit0WzBdLnRvVXBwZXJDYXNlKCkrdC5zbGljZSgxKV0tby11LXMtLjUpKXx8MCksdX1mdW5jdGlvbiBKZShlLHQsbil7dmFyIHI9UmUoZSksaT0oIXkuYm94U2l6aW5nUmVsaWFibGUoKXx8bikmJiJib3JkZXItYm94Ij09PVMuY3NzKGUsImJveFNpemluZyIsITEsciksbz1pLGE9V2UoZSx0LHIpLHM9Im9mZnNldCIrdFswXS50b1VwcGVyQ2FzZSgpK3Quc2xpY2UoMSk7aWYoUGUudGVzdChhKSl7aWYoIW4pcmV0dXJuIGE7YT0iYXV0byJ9cmV0dXJuKCF5LmJveFNpemluZ1JlbGlhYmxlKCkmJml8fCF5LnJlbGlhYmxlVHJEaW1lbnNpb25zKCkmJkEoZSwidHIiKXx8ImF1dG8iPT09YXx8IXBhcnNlRmxvYXQoYSkmJiJpbmxpbmUiPT09Uy5jc3MoZSwiZGlzcGxheSIsITEscikpJiZlLmdldENsaWVudFJlY3RzKCkubGVuZ3RoJiYoaT0iYm9yZGVyLWJveCI9PT1TLmNzcyhlLCJib3hTaXppbmciLCExLHIpLChvPXMgaW4gZSkmJihhPWVbc10pKSwoYT1wYXJzZUZsb2F0KGEpfHwwKStRZShlLHQsbnx8KGk/ImJvcmRlciI6ImNvbnRlbnQiKSxvLHIsYSkrInB4In1mdW5jdGlvbiBLZShlLHQsbixyLGkpe3JldHVybiBuZXcgS2UucHJvdG90eXBlLmluaXQoZSx0LG4scixpKX1TLmV4dGVuZCh7Y3NzSG9va3M6e29wYWNpdHk6e2dldDpmdW5jdGlvbihlLHQpe2lmKHQpe3ZhciBuPVdlKGUsIm9wYWNpdHkiKTtyZXR1cm4iIj09PW4/IjEiOm59fX19LGNzc051bWJlcjp7YW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6ITAsY29sdW1uQ291bnQ6ITAsZmlsbE9wYWNpdHk6ITAsZmxleEdyb3c6ITAsZmxleFNocmluazohMCxmb250V2VpZ2h0OiEwLGdyaWRBcmVhOiEwLGdyaWRDb2x1bW46ITAsZ3JpZENvbHVtbkVuZDohMCxncmlkQ29sdW1uU3RhcnQ6ITAsZ3JpZFJvdzohMCxncmlkUm93RW5kOiEwLGdyaWRSb3dTdGFydDohMCxsaW5lSGVpZ2h0OiEwLG9wYWNpdHk6ITAsb3JkZXI6ITAsb3JwaGFuczohMCx3aWRvd3M6ITAsekluZGV4OiEwLHpvb206ITB9LGNzc1Byb3BzOnt9LHN0eWxlOmZ1bmN0aW9uKGUsdCxuLHIpe2lmKGUmJjMhPT1lLm5vZGVUeXBlJiY4IT09ZS5ub2RlVHlwZSYmZS5zdHlsZSl7dmFyIGksbyxhLHM9WCh0KSx1PVhlLnRlc3QodCksbD1lLnN0eWxlO2lmKHV8fCh0PXplKHMpKSxhPVMuY3NzSG9va3NbdF18fFMuY3NzSG9va3Nbc10sdm9pZCAwPT09bilyZXR1cm4gYSYmImdldCJpbiBhJiZ2b2lkIDAhPT0oaT1hLmdldChlLCExLHIpKT9pOmxbdF07InN0cmluZyI9PT0obz10eXBlb2YgbikmJihpPXRlLmV4ZWMobikpJiZpWzFdJiYobj1zZShlLHQsaSksbz0ibnVtYmVyIiksbnVsbCE9biYmbj09biYmKCJudW1iZXIiIT09b3x8dXx8KG4rPWkmJmlbM118fChTLmNzc051bWJlcltzXT8iIjoicHgiKSkseS5jbGVhckNsb25lU3R5bGV8fCIiIT09bnx8MCE9PXQuaW5kZXhPZigiYmFja2dyb3VuZCIpfHwobFt0XT0iaW5oZXJpdCIpLGEmJiJzZXQiaW4gYSYmdm9pZCAwPT09KG49YS5zZXQoZSxuLHIpKXx8KHU/bC5zZXRQcm9wZXJ0eSh0LG4pOmxbdF09bikpfX0sY3NzOmZ1bmN0aW9uKGUsdCxuLHIpe3ZhciBpLG8sYSxzPVgodCk7cmV0dXJuIFhlLnRlc3QodCl8fCh0PXplKHMpKSwoYT1TLmNzc0hvb2tzW3RdfHxTLmNzc0hvb2tzW3NdKSYmImdldCJpbiBhJiYoaT1hLmdldChlLCEwLG4pKSx2b2lkIDA9PT1pJiYoaT1XZShlLHQscikpLCJub3JtYWwiPT09aSYmdCBpbiBHZSYmKGk9R2VbdF0pLCIiPT09bnx8bj8obz1wYXJzZUZsb2F0KGkpLCEwPT09bnx8aXNGaW5pdGUobyk/b3x8MDppKTppfX0pLFMuZWFjaChbImhlaWdodCIsIndpZHRoIl0sZnVuY3Rpb24oZSx1KXtTLmNzc0hvb2tzW3VdPXtnZXQ6ZnVuY3Rpb24oZSx0LG4pe2lmKHQpcmV0dXJuIVVlLnRlc3QoUy5jc3MoZSwiZGlzcGxheSIpKXx8ZS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCYmZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aD9KZShlLHUsbik6TWUoZSxWZSxmdW5jdGlvbigpe3JldHVybiBKZShlLHUsbil9KX0sc2V0OmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpPVJlKGUpLG89IXkuc2Nyb2xsYm94U2l6ZSgpJiYiYWJzb2x1dGUiPT09aS5wb3NpdGlvbixhPShvfHxuKSYmImJvcmRlci1ib3giPT09Uy5jc3MoZSwiYm94U2l6aW5nIiwhMSxpKSxzPW4/UWUoZSx1LG4sYSxpKTowO3JldHVybiBhJiZvJiYocy09TWF0aC5jZWlsKGVbIm9mZnNldCIrdVswXS50b1VwcGVyQ2FzZSgpK3Uuc2xpY2UoMSldLXBhcnNlRmxvYXQoaVt1XSktUWUoZSx1LCJib3JkZXIiLCExLGkpLS41KSkscyYmKHI9dGUuZXhlYyh0KSkmJiJweCIhPT0oclszXXx8InB4IikmJihlLnN0eWxlW3VdPXQsdD1TLmNzcyhlLHUpKSxZZSgwLHQscyl9fX0pLFMuY3NzSG9va3MubWFyZ2luTGVmdD1GZSh5LnJlbGlhYmxlTWFyZ2luTGVmdCxmdW5jdGlvbihlLHQpe2lmKHQpcmV0dXJuKHBhcnNlRmxvYXQoV2UoZSwibWFyZ2luTGVmdCIpKXx8ZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0LU1lKGUse21hcmdpbkxlZnQ6MH0sZnVuY3Rpb24oKXtyZXR1cm4gZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0fSkpKyJweCJ9KSxTLmVhY2goe21hcmdpbjoiIixwYWRkaW5nOiIiLGJvcmRlcjoiV2lkdGgifSxmdW5jdGlvbihpLG8pe1MuY3NzSG9va3NbaStvXT17ZXhwYW5kOmZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0wLG49e30scj0ic3RyaW5nIj09dHlwZW9mIGU/ZS5zcGxpdCgiICIpOltlXTt0PDQ7dCsrKW5baStuZVt0XStvXT1yW3RdfHxyW3QtMl18fHJbMF07cmV0dXJuIG59fSwibWFyZ2luIiE9PWkmJihTLmNzc0hvb2tzW2krb10uc2V0PVllKX0pLFMuZm4uZXh0ZW5kKHtjc3M6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gJCh0aGlzLGZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG89e30sYT0wO2lmKEFycmF5LmlzQXJyYXkodCkpe2ZvcihyPVJlKGUpLGk9dC5sZW5ndGg7YTxpO2ErKylvW3RbYV1dPVMuY3NzKGUsdFthXSwhMSxyKTtyZXR1cm4gb31yZXR1cm4gdm9pZCAwIT09bj9TLnN0eWxlKGUsdCxuKTpTLmNzcyhlLHQpfSxlLHQsMTxhcmd1bWVudHMubGVuZ3RoKX19KSwoKFMuVHdlZW49S2UpLnByb3RvdHlwZT17Y29uc3RydWN0b3I6S2UsaW5pdDpmdW5jdGlvbihlLHQsbixyLGksbyl7dGhpcy5lbGVtPWUsdGhpcy5wcm9wPW4sdGhpcy5lYXNpbmc9aXx8Uy5lYXNpbmcuX2RlZmF1bHQsdGhpcy5vcHRpb25zPXQsdGhpcy5zdGFydD10aGlzLm5vdz10aGlzLmN1cigpLHRoaXMuZW5kPXIsdGhpcy51bml0PW98fChTLmNzc051bWJlcltuXT8iIjoicHgiKX0sY3VyOmZ1bmN0aW9uKCl7dmFyIGU9S2UucHJvcEhvb2tzW3RoaXMucHJvcF07cmV0dXJuIGUmJmUuZ2V0P2UuZ2V0KHRoaXMpOktlLnByb3BIb29rcy5fZGVmYXVsdC5nZXQodGhpcyl9LHJ1bjpmdW5jdGlvbihlKXt2YXIgdCxuPUtlLnByb3BIb29rc1t0aGlzLnByb3BdO3JldHVybiB0aGlzLm9wdGlvbnMuZHVyYXRpb24/dGhpcy5wb3M9dD1TLmVhc2luZ1t0aGlzLmVhc2luZ10oZSx0aGlzLm9wdGlvbnMuZHVyYXRpb24qZSwwLDEsdGhpcy5vcHRpb25zLmR1cmF0aW9uKTp0aGlzLnBvcz10PWUsdGhpcy5ub3c9KHRoaXMuZW5kLXRoaXMuc3RhcnQpKnQrdGhpcy5zdGFydCx0aGlzLm9wdGlvbnMuc3RlcCYmdGhpcy5vcHRpb25zLnN0ZXAuY2FsbCh0aGlzLmVsZW0sdGhpcy5ub3csdGhpcyksbiYmbi5zZXQ/bi5zZXQodGhpcyk6S2UucHJvcEhvb2tzLl9kZWZhdWx0LnNldCh0aGlzKSx0aGlzfX0pLmluaXQucHJvdG90eXBlPUtlLnByb3RvdHlwZSwoS2UucHJvcEhvb2tzPXtfZGVmYXVsdDp7Z2V0OmZ1bmN0aW9uKGUpe3ZhciB0O3JldHVybiAxIT09ZS5lbGVtLm5vZGVUeXBlfHxudWxsIT1lLmVsZW1bZS5wcm9wXSYmbnVsbD09ZS5lbGVtLnN0eWxlW2UucHJvcF0/ZS5lbGVtW2UucHJvcF06KHQ9Uy5jc3MoZS5lbGVtLGUucHJvcCwiIikpJiYiYXV0byIhPT10P3Q6MH0sc2V0OmZ1bmN0aW9uKGUpe1MuZnguc3RlcFtlLnByb3BdP1MuZnguc3RlcFtlLnByb3BdKGUpOjEhPT1lLmVsZW0ubm9kZVR5cGV8fCFTLmNzc0hvb2tzW2UucHJvcF0mJm51bGw9PWUuZWxlbS5zdHlsZVt6ZShlLnByb3ApXT9lLmVsZW1bZS5wcm9wXT1lLm5vdzpTLnN0eWxlKGUuZWxlbSxlLnByb3AsZS5ub3crZS51bml0KX19fSkuc2Nyb2xsVG9wPUtlLnByb3BIb29rcy5zY3JvbGxMZWZ0PXtzZXQ6ZnVuY3Rpb24oZSl7ZS5lbGVtLm5vZGVUeXBlJiZlLmVsZW0ucGFyZW50Tm9kZSYmKGUuZWxlbVtlLnByb3BdPWUubm93KX19LFMuZWFzaW5nPXtsaW5lYXI6ZnVuY3Rpb24oZSl7cmV0dXJuIGV9LHN3aW5nOmZ1bmN0aW9uKGUpe3JldHVybi41LU1hdGguY29zKGUqTWF0aC5QSSkvMn0sX2RlZmF1bHQ6InN3aW5nIn0sUy5meD1LZS5wcm90b3R5cGUuaW5pdCxTLmZ4LnN0ZXA9e307dmFyIFplLGV0LHR0LG50LHJ0PS9eKD86dG9nZ2xlfHNob3d8aGlkZSkkLyxpdD0vcXVldWVIb29rcyQvO2Z1bmN0aW9uIG90KCl7ZXQmJighMT09PUUuaGlkZGVuJiZDLnJlcXVlc3RBbmltYXRpb25GcmFtZT9DLnJlcXVlc3RBbmltYXRpb25GcmFtZShvdCk6Qy5zZXRUaW1lb3V0KG90LFMuZnguaW50ZXJ2YWwpLFMuZngudGljaygpKX1mdW5jdGlvbiBhdCgpe3JldHVybiBDLnNldFRpbWVvdXQoZnVuY3Rpb24oKXtaZT12b2lkIDB9KSxaZT1EYXRlLm5vdygpfWZ1bmN0aW9uIHN0KGUsdCl7dmFyIG4scj0wLGk9e2hlaWdodDplfTtmb3IodD10PzE6MDtyPDQ7cis9Mi10KWlbIm1hcmdpbiIrKG49bmVbcl0pXT1pWyJwYWRkaW5nIituXT1lO3JldHVybiB0JiYoaS5vcGFjaXR5PWkud2lkdGg9ZSksaX1mdW5jdGlvbiB1dChlLHQsbil7Zm9yKHZhciByLGk9KGx0LnR3ZWVuZXJzW3RdfHxbXSkuY29uY2F0KGx0LnR3ZWVuZXJzWyIqIl0pLG89MCxhPWkubGVuZ3RoO288YTtvKyspaWYocj1pW29dLmNhbGwobix0LGUpKXJldHVybiByfWZ1bmN0aW9uIGx0KG8sZSx0KXt2YXIgbixhLHI9MCxpPWx0LnByZWZpbHRlcnMubGVuZ3RoLHM9Uy5EZWZlcnJlZCgpLmFsd2F5cyhmdW5jdGlvbigpe2RlbGV0ZSB1LmVsZW19KSx1PWZ1bmN0aW9uKCl7aWYoYSlyZXR1cm4hMTtmb3IodmFyIGU9WmV8fGF0KCksdD1NYXRoLm1heCgwLGwuc3RhcnRUaW1lK2wuZHVyYXRpb24tZSksbj0xLSh0L2wuZHVyYXRpb258fDApLHI9MCxpPWwudHdlZW5zLmxlbmd0aDtyPGk7cisrKWwudHdlZW5zW3JdLnJ1bihuKTtyZXR1cm4gcy5ub3RpZnlXaXRoKG8sW2wsbix0XSksbjwxJiZpP3Q6KGl8fHMubm90aWZ5V2l0aChvLFtsLDEsMF0pLHMucmVzb2x2ZVdpdGgobyxbbF0pLCExKX0sbD1zLnByb21pc2Uoe2VsZW06byxwcm9wczpTLmV4dGVuZCh7fSxlKSxvcHRzOlMuZXh0ZW5kKCEwLHtzcGVjaWFsRWFzaW5nOnt9LGVhc2luZzpTLmVhc2luZy5fZGVmYXVsdH0sdCksb3JpZ2luYWxQcm9wZXJ0aWVzOmUsb3JpZ2luYWxPcHRpb25zOnQsc3RhcnRUaW1lOlplfHxhdCgpLGR1cmF0aW9uOnQuZHVyYXRpb24sdHdlZW5zOltdLGNyZWF0ZVR3ZWVuOmZ1bmN0aW9uKGUsdCl7dmFyIG49Uy5Ud2VlbihvLGwub3B0cyxlLHQsbC5vcHRzLnNwZWNpYWxFYXNpbmdbZV18fGwub3B0cy5lYXNpbmcpO3JldHVybiBsLnR3ZWVucy5wdXNoKG4pLG59LHN0b3A6ZnVuY3Rpb24oZSl7dmFyIHQ9MCxuPWU/bC50d2VlbnMubGVuZ3RoOjA7aWYoYSlyZXR1cm4gdGhpcztmb3IoYT0hMDt0PG47dCsrKWwudHdlZW5zW3RdLnJ1bigxKTtyZXR1cm4gZT8ocy5ub3RpZnlXaXRoKG8sW2wsMSwwXSkscy5yZXNvbHZlV2l0aChvLFtsLGVdKSk6cy5yZWplY3RXaXRoKG8sW2wsZV0pLHRoaXN9fSksYz1sLnByb3BzO2ZvcighZnVuY3Rpb24oZSx0KXt2YXIgbixyLGksbyxhO2ZvcihuIGluIGUpaWYoaT10W3I9WChuKV0sbz1lW25dLEFycmF5LmlzQXJyYXkobykmJihpPW9bMV0sbz1lW25dPW9bMF0pLG4hPT1yJiYoZVtyXT1vLGRlbGV0ZSBlW25dKSwoYT1TLmNzc0hvb2tzW3JdKSYmImV4cGFuZCJpbiBhKWZvcihuIGluIG89YS5leHBhbmQobyksZGVsZXRlIGVbcl0sbyluIGluIGV8fChlW25dPW9bbl0sdFtuXT1pKTtlbHNlIHRbcl09aX0oYyxsLm9wdHMuc3BlY2lhbEVhc2luZyk7cjxpO3IrKylpZihuPWx0LnByZWZpbHRlcnNbcl0uY2FsbChsLG8sYyxsLm9wdHMpKXJldHVybiBtKG4uc3RvcCkmJihTLl9xdWV1ZUhvb2tzKGwuZWxlbSxsLm9wdHMucXVldWUpLnN0b3A9bi5zdG9wLmJpbmQobikpLG47cmV0dXJuIFMubWFwKGMsdXQsbCksbShsLm9wdHMuc3RhcnQpJiZsLm9wdHMuc3RhcnQuY2FsbChvLGwpLGwucHJvZ3Jlc3MobC5vcHRzLnByb2dyZXNzKS5kb25lKGwub3B0cy5kb25lLGwub3B0cy5jb21wbGV0ZSkuZmFpbChsLm9wdHMuZmFpbCkuYWx3YXlzKGwub3B0cy5hbHdheXMpLFMuZngudGltZXIoUy5leHRlbmQodSx7ZWxlbTpvLGFuaW06bCxxdWV1ZTpsLm9wdHMucXVldWV9KSksbH1TLkFuaW1hdGlvbj1TLmV4dGVuZChsdCx7dHdlZW5lcnM6eyIqIjpbZnVuY3Rpb24oZSx0KXt2YXIgbj10aGlzLmNyZWF0ZVR3ZWVuKGUsdCk7cmV0dXJuIHNlKG4uZWxlbSxlLHRlLmV4ZWModCksbiksbn1dfSx0d2VlbmVyOmZ1bmN0aW9uKGUsdCl7bShlKT8odD1lLGU9WyIqIl0pOmU9ZS5tYXRjaChQKTtmb3IodmFyIG4scj0wLGk9ZS5sZW5ndGg7cjxpO3IrKyluPWVbcl0sbHQudHdlZW5lcnNbbl09bHQudHdlZW5lcnNbbl18fFtdLGx0LnR3ZWVuZXJzW25dLnVuc2hpZnQodCl9LHByZWZpbHRlcnM6W2Z1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG8sYSxzLHUsbCxjLGY9IndpZHRoImluIHR8fCJoZWlnaHQiaW4gdCxwPXRoaXMsZD17fSxoPWUuc3R5bGUsZz1lLm5vZGVUeXBlJiZhZShlKSx2PVkuZ2V0KGUsImZ4c2hvdyIpO2ZvcihyIGluIG4ucXVldWV8fChudWxsPT0oYT1TLl9xdWV1ZUhvb2tzKGUsImZ4IikpLnVucXVldWVkJiYoYS51bnF1ZXVlZD0wLHM9YS5lbXB0eS5maXJlLGEuZW1wdHkuZmlyZT1mdW5jdGlvbigpe2EudW5xdWV1ZWR8fHMoKX0pLGEudW5xdWV1ZWQrKyxwLmFsd2F5cyhmdW5jdGlvbigpe3AuYWx3YXlzKGZ1bmN0aW9uKCl7YS51bnF1ZXVlZC0tLFMucXVldWUoZSwiZngiKS5sZW5ndGh8fGEuZW1wdHkuZmlyZSgpfSl9KSksdClpZihpPXRbcl0scnQudGVzdChpKSl7aWYoZGVsZXRlIHRbcl0sbz1vfHwidG9nZ2xlIj09PWksaT09PShnPyJoaWRlIjoic2hvdyIpKXtpZigic2hvdyIhPT1pfHwhdnx8dm9pZCAwPT09dltyXSljb250aW51ZTtnPSEwfWRbcl09diYmdltyXXx8Uy5zdHlsZShlLHIpfWlmKCh1PSFTLmlzRW1wdHlPYmplY3QodCkpfHwhUy5pc0VtcHR5T2JqZWN0KGQpKWZvcihyIGluIGYmJjE9PT1lLm5vZGVUeXBlJiYobi5vdmVyZmxvdz1baC5vdmVyZmxvdyxoLm92ZXJmbG93WCxoLm92ZXJmbG93WV0sbnVsbD09KGw9diYmdi5kaXNwbGF5KSYmKGw9WS5nZXQoZSwiZGlzcGxheSIpKSwibm9uZSI9PT0oYz1TLmNzcyhlLCJkaXNwbGF5IikpJiYobD9jPWw6KGxlKFtlXSwhMCksbD1lLnN0eWxlLmRpc3BsYXl8fGwsYz1TLmNzcyhlLCJkaXNwbGF5IiksbGUoW2VdKSkpLCgiaW5saW5lIj09PWN8fCJpbmxpbmUtYmxvY2siPT09YyYmbnVsbCE9bCkmJiJub25lIj09PVMuY3NzKGUsImZsb2F0IikmJih1fHwocC5kb25lKGZ1bmN0aW9uKCl7aC5kaXNwbGF5PWx9KSxudWxsPT1sJiYoYz1oLmRpc3BsYXksbD0ibm9uZSI9PT1jPyIiOmMpKSxoLmRpc3BsYXk9ImlubGluZS1ibG9jayIpKSxuLm92ZXJmbG93JiYoaC5vdmVyZmxvdz0iaGlkZGVuIixwLmFsd2F5cyhmdW5jdGlvbigpe2gub3ZlcmZsb3c9bi5vdmVyZmxvd1swXSxoLm92ZXJmbG93WD1uLm92ZXJmbG93WzFdLGgub3ZlcmZsb3dZPW4ub3ZlcmZsb3dbMl19KSksdT0hMSxkKXV8fCh2PyJoaWRkZW4iaW4gdiYmKGc9di5oaWRkZW4pOnY9WS5hY2Nlc3MoZSwiZnhzaG93Iix7ZGlzcGxheTpsfSksbyYmKHYuaGlkZGVuPSFnKSxnJiZsZShbZV0sITApLHAuZG9uZShmdW5jdGlvbigpe2ZvcihyIGluIGd8fGxlKFtlXSksWS5yZW1vdmUoZSwiZnhzaG93IiksZClTLnN0eWxlKGUscixkW3JdKX0pKSx1PXV0KGc/dltyXTowLHIscCksciBpbiB2fHwodltyXT11LnN0YXJ0LGcmJih1LmVuZD11LnN0YXJ0LHUuc3RhcnQ9MCkpfV0scHJlZmlsdGVyOmZ1bmN0aW9uKGUsdCl7dD9sdC5wcmVmaWx0ZXJzLnVuc2hpZnQoZSk6bHQucHJlZmlsdGVycy5wdXNoKGUpfX0pLFMuc3BlZWQ9ZnVuY3Rpb24oZSx0LG4pe3ZhciByPWUmJiJvYmplY3QiPT10eXBlb2YgZT9TLmV4dGVuZCh7fSxlKTp7Y29tcGxldGU6bnx8IW4mJnR8fG0oZSkmJmUsZHVyYXRpb246ZSxlYXNpbmc6biYmdHx8dCYmIW0odCkmJnR9O3JldHVybiBTLmZ4Lm9mZj9yLmR1cmF0aW9uPTA6Im51bWJlciIhPXR5cGVvZiByLmR1cmF0aW9uJiYoci5kdXJhdGlvbiBpbiBTLmZ4LnNwZWVkcz9yLmR1cmF0aW9uPVMuZnguc3BlZWRzW3IuZHVyYXRpb25dOnIuZHVyYXRpb249Uy5meC5zcGVlZHMuX2RlZmF1bHQpLG51bGwhPXIucXVldWUmJiEwIT09ci5xdWV1ZXx8KHIucXVldWU9ImZ4Iiksci5vbGQ9ci5jb21wbGV0ZSxyLmNvbXBsZXRlPWZ1bmN0aW9uKCl7bShyLm9sZCkmJnIub2xkLmNhbGwodGhpcyksci5xdWV1ZSYmUy5kZXF1ZXVlKHRoaXMsci5xdWV1ZSl9LHJ9LFMuZm4uZXh0ZW5kKHtmYWRlVG86ZnVuY3Rpb24oZSx0LG4scil7cmV0dXJuIHRoaXMuZmlsdGVyKGFlKS5jc3MoIm9wYWNpdHkiLDApLnNob3coKS5lbmQoKS5hbmltYXRlKHtvcGFjaXR5OnR9LGUsbixyKX0sYW5pbWF0ZTpmdW5jdGlvbih0LGUsbixyKXt2YXIgaT1TLmlzRW1wdHlPYmplY3QodCksbz1TLnNwZWVkKGUsbixyKSxhPWZ1bmN0aW9uKCl7dmFyIGU9bHQodGhpcyxTLmV4dGVuZCh7fSx0KSxvKTsoaXx8WS5nZXQodGhpcywiZmluaXNoIikpJiZlLnN0b3AoITApfTtyZXR1cm4gYS5maW5pc2g9YSxpfHwhMT09PW8ucXVldWU/dGhpcy5lYWNoKGEpOnRoaXMucXVldWUoby5xdWV1ZSxhKX0sc3RvcDpmdW5jdGlvbihpLGUsbyl7dmFyIGE9ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5zdG9wO2RlbGV0ZSBlLnN0b3AsdChvKX07cmV0dXJuInN0cmluZyIhPXR5cGVvZiBpJiYobz1lLGU9aSxpPXZvaWQgMCksZSYmdGhpcy5xdWV1ZShpfHwiZngiLFtdKSx0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgZT0hMCx0PW51bGwhPWkmJmkrInF1ZXVlSG9va3MiLG49Uy50aW1lcnMscj1ZLmdldCh0aGlzKTtpZih0KXJbdF0mJnJbdF0uc3RvcCYmYShyW3RdKTtlbHNlIGZvcih0IGluIHIpclt0XSYmclt0XS5zdG9wJiZpdC50ZXN0KHQpJiZhKHJbdF0pO2Zvcih0PW4ubGVuZ3RoO3QtLTspblt0XS5lbGVtIT09dGhpc3x8bnVsbCE9aSYmblt0XS5xdWV1ZSE9PWl8fChuW3RdLmFuaW0uc3RvcChvKSxlPSExLG4uc3BsaWNlKHQsMSkpOyFlJiZvfHxTLmRlcXVldWUodGhpcyxpKX0pfSxmaW5pc2g6ZnVuY3Rpb24oYSl7cmV0dXJuITEhPT1hJiYoYT1hfHwiZngiKSx0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgZSx0PVkuZ2V0KHRoaXMpLG49dFthKyJxdWV1ZSJdLHI9dFthKyJxdWV1ZUhvb2tzIl0saT1TLnRpbWVycyxvPW4/bi5sZW5ndGg6MDtmb3IodC5maW5pc2g9ITAsUy5xdWV1ZSh0aGlzLGEsW10pLHImJnIuc3RvcCYmci5zdG9wLmNhbGwodGhpcywhMCksZT1pLmxlbmd0aDtlLS07KWlbZV0uZWxlbT09PXRoaXMmJmlbZV0ucXVldWU9PT1hJiYoaVtlXS5hbmltLnN0b3AoITApLGkuc3BsaWNlKGUsMSkpO2ZvcihlPTA7ZTxvO2UrKyluW2VdJiZuW2VdLmZpbmlzaCYmbltlXS5maW5pc2guY2FsbCh0aGlzKTtkZWxldGUgdC5maW5pc2h9KX19KSxTLmVhY2goWyJ0b2dnbGUiLCJzaG93IiwiaGlkZSJdLGZ1bmN0aW9uKGUscil7dmFyIGk9Uy5mbltyXTtTLmZuW3JdPWZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gbnVsbD09ZXx8ImJvb2xlYW4iPT10eXBlb2YgZT9pLmFwcGx5KHRoaXMsYXJndW1lbnRzKTp0aGlzLmFuaW1hdGUoc3QociwhMCksZSx0LG4pfX0pLFMuZWFjaCh7c2xpZGVEb3duOnN0KCJzaG93Iiksc2xpZGVVcDpzdCgiaGlkZSIpLHNsaWRlVG9nZ2xlOnN0KCJ0b2dnbGUiKSxmYWRlSW46e29wYWNpdHk6InNob3cifSxmYWRlT3V0OntvcGFjaXR5OiJoaWRlIn0sZmFkZVRvZ2dsZTp7b3BhY2l0eToidG9nZ2xlIn19LGZ1bmN0aW9uKGUscil7Uy5mbltlXT1mdW5jdGlvbihlLHQsbil7cmV0dXJuIHRoaXMuYW5pbWF0ZShyLGUsdCxuKX19KSxTLnRpbWVycz1bXSxTLmZ4LnRpY2s9ZnVuY3Rpb24oKXt2YXIgZSx0PTAsbj1TLnRpbWVycztmb3IoWmU9RGF0ZS5ub3coKTt0PG4ubGVuZ3RoO3QrKykoZT1uW3RdKSgpfHxuW3RdIT09ZXx8bi5zcGxpY2UodC0tLDEpO24ubGVuZ3RofHxTLmZ4LnN0b3AoKSxaZT12b2lkIDB9LFMuZngudGltZXI9ZnVuY3Rpb24oZSl7Uy50aW1lcnMucHVzaChlKSxTLmZ4LnN0YXJ0KCl9LFMuZnguaW50ZXJ2YWw9MTMsUy5meC5zdGFydD1mdW5jdGlvbigpe2V0fHwoZXQ9ITAsb3QoKSl9LFMuZnguc3RvcD1mdW5jdGlvbigpe2V0PW51bGx9LFMuZnguc3BlZWRzPXtzbG93OjYwMCxmYXN0OjIwMCxfZGVmYXVsdDo0MDB9LFMuZm4uZGVsYXk9ZnVuY3Rpb24ocixlKXtyZXR1cm4gcj1TLmZ4JiZTLmZ4LnNwZWVkc1tyXXx8cixlPWV8fCJmeCIsdGhpcy5xdWV1ZShlLGZ1bmN0aW9uKGUsdCl7dmFyIG49Qy5zZXRUaW1lb3V0KGUscik7dC5zdG9wPWZ1bmN0aW9uKCl7Qy5jbGVhclRpbWVvdXQobil9fSl9LHR0PUUuY3JlYXRlRWxlbWVudCgiaW5wdXQiKSxudD1FLmNyZWF0ZUVsZW1lbnQoInNlbGVjdCIpLmFwcGVuZENoaWxkKEUuY3JlYXRlRWxlbWVudCgib3B0aW9uIikpLHR0LnR5cGU9ImNoZWNrYm94Iix5LmNoZWNrT249IiIhPT10dC52YWx1ZSx5Lm9wdFNlbGVjdGVkPW50LnNlbGVjdGVkLCh0dD1FLmNyZWF0ZUVsZW1lbnQoImlucHV0IikpLnZhbHVlPSJ0Iix0dC50eXBlPSJyYWRpbyIseS5yYWRpb1ZhbHVlPSJ0Ij09PXR0LnZhbHVlO3ZhciBjdCxmdD1TLmV4cHIuYXR0ckhhbmRsZTtTLmZuLmV4dGVuZCh7YXR0cjpmdW5jdGlvbihlLHQpe3JldHVybiAkKHRoaXMsUy5hdHRyLGUsdCwxPGFyZ3VtZW50cy5sZW5ndGgpfSxyZW1vdmVBdHRyOmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtTLnJlbW92ZUF0dHIodGhpcyxlKX0pfX0pLFMuZXh0ZW5kKHthdHRyOmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG89ZS5ub2RlVHlwZTtpZigzIT09byYmOCE9PW8mJjIhPT1vKXJldHVybiJ1bmRlZmluZWQiPT10eXBlb2YgZS5nZXRBdHRyaWJ1dGU/Uy5wcm9wKGUsdCxuKTooMT09PW8mJlMuaXNYTUxEb2MoZSl8fChpPVMuYXR0ckhvb2tzW3QudG9Mb3dlckNhc2UoKV18fChTLmV4cHIubWF0Y2guYm9vbC50ZXN0KHQpP2N0OnZvaWQgMCkpLHZvaWQgMCE9PW4/bnVsbD09PW4/dm9pZCBTLnJlbW92ZUF0dHIoZSx0KTppJiYic2V0ImluIGkmJnZvaWQgMCE9PShyPWkuc2V0KGUsbix0KSk/cjooZS5zZXRBdHRyaWJ1dGUodCxuKyIiKSxuKTppJiYiZ2V0ImluIGkmJm51bGwhPT0ocj1pLmdldChlLHQpKT9yOm51bGw9PShyPVMuZmluZC5hdHRyKGUsdCkpP3ZvaWQgMDpyKX0sYXR0ckhvb2tzOnt0eXBlOntzZXQ6ZnVuY3Rpb24oZSx0KXtpZigheS5yYWRpb1ZhbHVlJiYicmFkaW8iPT09dCYmQShlLCJpbnB1dCIpKXt2YXIgbj1lLnZhbHVlO3JldHVybiBlLnNldEF0dHJpYnV0ZSgidHlwZSIsdCksbiYmKGUudmFsdWU9biksdH19fX0scmVtb3ZlQXR0cjpmdW5jdGlvbihlLHQpe3ZhciBuLHI9MCxpPXQmJnQubWF0Y2goUCk7aWYoaSYmMT09PWUubm9kZVR5cGUpd2hpbGUobj1pW3IrK10pZS5yZW1vdmVBdHRyaWJ1dGUobil9fSksY3Q9e3NldDpmdW5jdGlvbihlLHQsbil7cmV0dXJuITE9PT10P1MucmVtb3ZlQXR0cihlLG4pOmUuc2V0QXR0cmlidXRlKG4sbiksbn19LFMuZWFjaChTLmV4cHIubWF0Y2guYm9vbC5zb3VyY2UubWF0Y2goL1x3Ky9nKSxmdW5jdGlvbihlLHQpe3ZhciBhPWZ0W3RdfHxTLmZpbmQuYXR0cjtmdFt0XT1mdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvPXQudG9Mb3dlckNhc2UoKTtyZXR1cm4gbnx8KGk9ZnRbb10sZnRbb109cixyPW51bGwhPWEoZSx0LG4pP286bnVsbCxmdFtvXT1pKSxyfX0pO3ZhciBwdD0vXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxidXR0b24pJC9pLGR0PS9eKD86YXxhcmVhKSQvaTtmdW5jdGlvbiBodChlKXtyZXR1cm4oZS5tYXRjaChQKXx8W10pLmpvaW4oIiAiKX1mdW5jdGlvbiBndChlKXtyZXR1cm4gZS5nZXRBdHRyaWJ1dGUmJmUuZ2V0QXR0cmlidXRlKCJjbGFzcyIpfHwiIn1mdW5jdGlvbiB2dChlKXtyZXR1cm4gQXJyYXkuaXNBcnJheShlKT9lOiJzdHJpbmciPT10eXBlb2YgZSYmZS5tYXRjaChQKXx8W119Uy5mbi5leHRlbmQoe3Byb3A6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gJCh0aGlzLFMucHJvcCxlLHQsMTxhcmd1bWVudHMubGVuZ3RoKX0scmVtb3ZlUHJvcDpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7ZGVsZXRlIHRoaXNbUy5wcm9wRml4W2VdfHxlXX0pfX0pLFMuZXh0ZW5kKHtwcm9wOmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG89ZS5ub2RlVHlwZTtpZigzIT09byYmOCE9PW8mJjIhPT1vKXJldHVybiAxPT09byYmUy5pc1hNTERvYyhlKXx8KHQ9Uy5wcm9wRml4W3RdfHx0LGk9Uy5wcm9wSG9va3NbdF0pLHZvaWQgMCE9PW4/aSYmInNldCJpbiBpJiZ2b2lkIDAhPT0ocj1pLnNldChlLG4sdCkpP3I6ZVt0XT1uOmkmJiJnZXQiaW4gaSYmbnVsbCE9PShyPWkuZ2V0KGUsdCkpP3I6ZVt0XX0scHJvcEhvb2tzOnt0YWJJbmRleDp7Z2V0OmZ1bmN0aW9uKGUpe3ZhciB0PVMuZmluZC5hdHRyKGUsInRhYmluZGV4Iik7cmV0dXJuIHQ/cGFyc2VJbnQodCwxMCk6cHQudGVzdChlLm5vZGVOYW1lKXx8ZHQudGVzdChlLm5vZGVOYW1lKSYmZS5ocmVmPzA6LTF9fX0scHJvcEZpeDp7ImZvciI6Imh0bWxGb3IiLCJjbGFzcyI6ImNsYXNzTmFtZSJ9fSkseS5vcHRTZWxlY3RlZHx8KFMucHJvcEhvb2tzLnNlbGVjdGVkPXtnZXQ6ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5wYXJlbnROb2RlO3JldHVybiB0JiZ0LnBhcmVudE5vZGUmJnQucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4LG51bGx9LHNldDpmdW5jdGlvbihlKXt2YXIgdD1lLnBhcmVudE5vZGU7dCYmKHQuc2VsZWN0ZWRJbmRleCx0LnBhcmVudE5vZGUmJnQucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4KX19KSxTLmVhY2goWyJ0YWJJbmRleCIsInJlYWRPbmx5IiwibWF4TGVuZ3RoIiwiY2VsbFNwYWNpbmciLCJjZWxsUGFkZGluZyIsInJvd1NwYW4iLCJjb2xTcGFuIiwidXNlTWFwIiwiZnJhbWVCb3JkZXIiLCJjb250ZW50RWRpdGFibGUiXSxmdW5jdGlvbigpe1MucHJvcEZpeFt0aGlzLnRvTG93ZXJDYXNlKCldPXRoaXN9KSxTLmZuLmV4dGVuZCh7YWRkQ2xhc3M6ZnVuY3Rpb24odCl7dmFyIGUsbixyLGksbyxhLHMsdT0wO2lmKG0odCkpcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihlKXtTKHRoaXMpLmFkZENsYXNzKHQuY2FsbCh0aGlzLGUsZ3QodGhpcykpKX0pO2lmKChlPXZ0KHQpKS5sZW5ndGgpd2hpbGUobj10aGlzW3UrK10paWYoaT1ndChuKSxyPTE9PT1uLm5vZGVUeXBlJiYiICIraHQoaSkrIiAiKXthPTA7d2hpbGUobz1lW2ErK10pci5pbmRleE9mKCIgIitvKyIgIik8MCYmKHIrPW8rIiAiKTtpIT09KHM9aHQocikpJiZuLnNldEF0dHJpYnV0ZSgiY2xhc3MiLHMpfXJldHVybiB0aGlzfSxyZW1vdmVDbGFzczpmdW5jdGlvbih0KXt2YXIgZSxuLHIsaSxvLGEscyx1PTA7aWYobSh0KSlyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKGUpe1ModGhpcykucmVtb3ZlQ2xhc3ModC5jYWxsKHRoaXMsZSxndCh0aGlzKSkpfSk7aWYoIWFyZ3VtZW50cy5sZW5ndGgpcmV0dXJuIHRoaXMuYXR0cigiY2xhc3MiLCIiKTtpZigoZT12dCh0KSkubGVuZ3RoKXdoaWxlKG49dGhpc1t1KytdKWlmKGk9Z3Qobikscj0xPT09bi5ub2RlVHlwZSYmIiAiK2h0KGkpKyIgIil7YT0wO3doaWxlKG89ZVthKytdKXdoaWxlKC0xPHIuaW5kZXhPZigiICIrbysiICIpKXI9ci5yZXBsYWNlKCIgIitvKyIgIiwiICIpO2khPT0ocz1odChyKSkmJm4uc2V0QXR0cmlidXRlKCJjbGFzcyIscyl9cmV0dXJuIHRoaXN9LHRvZ2dsZUNsYXNzOmZ1bmN0aW9uKGksdCl7dmFyIG89dHlwZW9mIGksYT0ic3RyaW5nIj09PW98fEFycmF5LmlzQXJyYXkoaSk7cmV0dXJuImJvb2xlYW4iPT10eXBlb2YgdCYmYT90P3RoaXMuYWRkQ2xhc3MoaSk6dGhpcy5yZW1vdmVDbGFzcyhpKTptKGkpP3RoaXMuZWFjaChmdW5jdGlvbihlKXtTKHRoaXMpLnRvZ2dsZUNsYXNzKGkuY2FsbCh0aGlzLGUsZ3QodGhpcyksdCksdCl9KTp0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgZSx0LG4scjtpZihhKXt0PTAsbj1TKHRoaXMpLHI9dnQoaSk7d2hpbGUoZT1yW3QrK10pbi5oYXNDbGFzcyhlKT9uLnJlbW92ZUNsYXNzKGUpOm4uYWRkQ2xhc3MoZSl9ZWxzZSB2b2lkIDAhPT1pJiYiYm9vbGVhbiIhPT1vfHwoKGU9Z3QodGhpcykpJiZZLnNldCh0aGlzLCJfX2NsYXNzTmFtZV9fIixlKSx0aGlzLnNldEF0dHJpYnV0ZSYmdGhpcy5zZXRBdHRyaWJ1dGUoImNsYXNzIixlfHwhMT09PWk/IiI6WS5nZXQodGhpcywiX19jbGFzc05hbWVfXyIpfHwiIikpfSl9LGhhc0NsYXNzOmZ1bmN0aW9uKGUpe3ZhciB0LG4scj0wO3Q9IiAiK2UrIiAiO3doaWxlKG49dGhpc1tyKytdKWlmKDE9PT1uLm5vZGVUeXBlJiYtMTwoIiAiK2h0KGd0KG4pKSsiICIpLmluZGV4T2YodCkpcmV0dXJuITA7cmV0dXJuITF9fSk7dmFyIHl0PS9cci9nO1MuZm4uZXh0ZW5kKHt2YWw6ZnVuY3Rpb24obil7dmFyIHIsZSxpLHQ9dGhpc1swXTtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oaT1tKG4pLHRoaXMuZWFjaChmdW5jdGlvbihlKXt2YXIgdDsxPT09dGhpcy5ub2RlVHlwZSYmKG51bGw9PSh0PWk/bi5jYWxsKHRoaXMsZSxTKHRoaXMpLnZhbCgpKTpuKT90PSIiOiJudW1iZXIiPT10eXBlb2YgdD90Kz0iIjpBcnJheS5pc0FycmF5KHQpJiYodD1TLm1hcCh0LGZ1bmN0aW9uKGUpe3JldHVybiBudWxsPT1lPyIiOmUrIiJ9KSksKHI9Uy52YWxIb29rc1t0aGlzLnR5cGVdfHxTLnZhbEhvb2tzW3RoaXMubm9kZU5hbWUudG9Mb3dlckNhc2UoKV0pJiYic2V0ImluIHImJnZvaWQgMCE9PXIuc2V0KHRoaXMsdCwidmFsdWUiKXx8KHRoaXMudmFsdWU9dCkpfSkpOnQ/KHI9Uy52YWxIb29rc1t0LnR5cGVdfHxTLnZhbEhvb2tzW3Qubm9kZU5hbWUudG9Mb3dlckNhc2UoKV0pJiYiZ2V0ImluIHImJnZvaWQgMCE9PShlPXIuZ2V0KHQsInZhbHVlIikpP2U6InN0cmluZyI9PXR5cGVvZihlPXQudmFsdWUpP2UucmVwbGFjZSh5dCwiIik6bnVsbD09ZT8iIjplOnZvaWQgMH19KSxTLmV4dGVuZCh7dmFsSG9va3M6e29wdGlvbjp7Z2V0OmZ1bmN0aW9uKGUpe3ZhciB0PVMuZmluZC5hdHRyKGUsInZhbHVlIik7cmV0dXJuIG51bGwhPXQ/dDpodChTLnRleHQoZSkpfX0sc2VsZWN0OntnZXQ6ZnVuY3Rpb24oZSl7dmFyIHQsbixyLGk9ZS5vcHRpb25zLG89ZS5zZWxlY3RlZEluZGV4LGE9InNlbGVjdC1vbmUiPT09ZS50eXBlLHM9YT9udWxsOltdLHU9YT9vKzE6aS5sZW5ndGg7Zm9yKHI9bzwwP3U6YT9vOjA7cjx1O3IrKylpZigoKG49aVtyXSkuc2VsZWN0ZWR8fHI9PT1vKSYmIW4uZGlzYWJsZWQmJighbi5wYXJlbnROb2RlLmRpc2FibGVkfHwhQShuLnBhcmVudE5vZGUsIm9wdGdyb3VwIikpKXtpZih0PVMobikudmFsKCksYSlyZXR1cm4gdDtzLnB1c2godCl9cmV0dXJuIHN9LHNldDpmdW5jdGlvbihlLHQpe3ZhciBuLHIsaT1lLm9wdGlvbnMsbz1TLm1ha2VBcnJheSh0KSxhPWkubGVuZ3RoO3doaWxlKGEtLSkoKHI9aVthXSkuc2VsZWN0ZWQ9LTE8Uy5pbkFycmF5KFMudmFsSG9va3Mub3B0aW9uLmdldChyKSxvKSkmJihuPSEwKTtyZXR1cm4gbnx8KGUuc2VsZWN0ZWRJbmRleD0tMSksb319fX0pLFMuZWFjaChbInJhZGlvIiwiY2hlY2tib3giXSxmdW5jdGlvbigpe1MudmFsSG9va3NbdGhpc109e3NldDpmdW5jdGlvbihlLHQpe2lmKEFycmF5LmlzQXJyYXkodCkpcmV0dXJuIGUuY2hlY2tlZD0tMTxTLmluQXJyYXkoUyhlKS52YWwoKSx0KX19LHkuY2hlY2tPbnx8KFMudmFsSG9va3NbdGhpc10uZ2V0PWZ1bmN0aW9uKGUpe3JldHVybiBudWxsPT09ZS5nZXRBdHRyaWJ1dGUoInZhbHVlIik/Im9uIjplLnZhbHVlfSl9KSx5LmZvY3VzaW49Im9uZm9jdXNpbiJpbiBDO3ZhciBtdD0vXig/OmZvY3VzaW5mb2N1c3xmb2N1c291dGJsdXIpJC8seHQ9ZnVuY3Rpb24oZSl7ZS5zdG9wUHJvcGFnYXRpb24oKX07Uy5leHRlbmQoUy5ldmVudCx7dHJpZ2dlcjpmdW5jdGlvbihlLHQsbixyKXt2YXIgaSxvLGEscyx1LGwsYyxmLHA9W258fEVdLGQ9di5jYWxsKGUsInR5cGUiKT9lLnR5cGU6ZSxoPXYuY2FsbChlLCJuYW1lc3BhY2UiKT9lLm5hbWVzcGFjZS5zcGxpdCgiLiIpOltdO2lmKG89Zj1hPW49bnx8RSwzIT09bi5ub2RlVHlwZSYmOCE9PW4ubm9kZVR5cGUmJiFtdC50ZXN0KGQrUy5ldmVudC50cmlnZ2VyZWQpJiYoLTE8ZC5pbmRleE9mKCIuIikmJihkPShoPWQuc3BsaXQoIi4iKSkuc2hpZnQoKSxoLnNvcnQoKSksdT1kLmluZGV4T2YoIjoiKTwwJiYib24iK2QsKGU9ZVtTLmV4cGFuZG9dP2U6bmV3IFMuRXZlbnQoZCwib2JqZWN0Ij09dHlwZW9mIGUmJmUpKS5pc1RyaWdnZXI9cj8yOjMsZS5uYW1lc3BhY2U9aC5qb2luKCIuIiksZS5ybmFtZXNwYWNlPWUubmFtZXNwYWNlP25ldyBSZWdFeHAoIihefFxcLikiK2guam9pbigiXFwuKD86LipcXC58KSIpKyIoXFwufCQpIik6bnVsbCxlLnJlc3VsdD12b2lkIDAsZS50YXJnZXR8fChlLnRhcmdldD1uKSx0PW51bGw9PXQ/W2VdOlMubWFrZUFycmF5KHQsW2VdKSxjPVMuZXZlbnQuc3BlY2lhbFtkXXx8e30scnx8IWMudHJpZ2dlcnx8ITEhPT1jLnRyaWdnZXIuYXBwbHkobix0KSkpe2lmKCFyJiYhYy5ub0J1YmJsZSYmIXgobikpe2ZvcihzPWMuZGVsZWdhdGVUeXBlfHxkLG10LnRlc3QocytkKXx8KG89by5wYXJlbnROb2RlKTtvO289by5wYXJlbnROb2RlKXAucHVzaChvKSxhPW87YT09PShuLm93bmVyRG9jdW1lbnR8fEUpJiZwLnB1c2goYS5kZWZhdWx0Vmlld3x8YS5wYXJlbnRXaW5kb3d8fEMpfWk9MDt3aGlsZSgobz1wW2krK10pJiYhZS5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpKWY9byxlLnR5cGU9MTxpP3M6Yy5iaW5kVHlwZXx8ZCwobD0oWS5nZXQobywiZXZlbnRzIil8fE9iamVjdC5jcmVhdGUobnVsbCkpW2UudHlwZV0mJlkuZ2V0KG8sImhhbmRsZSIpKSYmbC5hcHBseShvLHQpLChsPXUmJm9bdV0pJiZsLmFwcGx5JiZWKG8pJiYoZS5yZXN1bHQ9bC5hcHBseShvLHQpLCExPT09ZS5yZXN1bHQmJmUucHJldmVudERlZmF1bHQoKSk7cmV0dXJuIGUudHlwZT1kLHJ8fGUuaXNEZWZhdWx0UHJldmVudGVkKCl8fGMuX2RlZmF1bHQmJiExIT09Yy5fZGVmYXVsdC5hcHBseShwLnBvcCgpLHQpfHwhVihuKXx8dSYmbShuW2RdKSYmIXgobikmJigoYT1uW3VdKSYmKG5bdV09bnVsbCksUy5ldmVudC50cmlnZ2VyZWQ9ZCxlLmlzUHJvcGFnYXRpb25TdG9wcGVkKCkmJmYuYWRkRXZlbnRMaXN0ZW5lcihkLHh0KSxuW2RdKCksZS5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpJiZmLnJlbW92ZUV2ZW50TGlzdGVuZXIoZCx4dCksUy5ldmVudC50cmlnZ2VyZWQ9dm9pZCAwLGEmJihuW3VdPWEpKSxlLnJlc3VsdH19LHNpbXVsYXRlOmZ1bmN0aW9uKGUsdCxuKXt2YXIgcj1TLmV4dGVuZChuZXcgUy5FdmVudCxuLHt0eXBlOmUsaXNTaW11bGF0ZWQ6ITB9KTtTLmV2ZW50LnRyaWdnZXIocixudWxsLHQpfX0pLFMuZm4uZXh0ZW5kKHt0cmlnZ2VyOmZ1bmN0aW9uKGUsdCl7cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe1MuZXZlbnQudHJpZ2dlcihlLHQsdGhpcyl9KX0sdHJpZ2dlckhhbmRsZXI6ZnVuY3Rpb24oZSx0KXt2YXIgbj10aGlzWzBdO2lmKG4pcmV0dXJuIFMuZXZlbnQudHJpZ2dlcihlLHQsbiwhMCl9fSkseS5mb2N1c2lufHxTLmVhY2goe2ZvY3VzOiJmb2N1c2luIixibHVyOiJmb2N1c291dCJ9LGZ1bmN0aW9uKG4scil7dmFyIGk9ZnVuY3Rpb24oZSl7Uy5ldmVudC5zaW11bGF0ZShyLGUudGFyZ2V0LFMuZXZlbnQuZml4KGUpKX07Uy5ldmVudC5zcGVjaWFsW3JdPXtzZXR1cDpmdW5jdGlvbigpe3ZhciBlPXRoaXMub3duZXJEb2N1bWVudHx8dGhpcy5kb2N1bWVudHx8dGhpcyx0PVkuYWNjZXNzKGUscik7dHx8ZS5hZGRFdmVudExpc3RlbmVyKG4saSwhMCksWS5hY2Nlc3MoZSxyLCh0fHwwKSsxKX0sdGVhcmRvd246ZnVuY3Rpb24oKXt2YXIgZT10aGlzLm93bmVyRG9jdW1lbnR8fHRoaXMuZG9jdW1lbnR8fHRoaXMsdD1ZLmFjY2VzcyhlLHIpLTE7dD9ZLmFjY2VzcyhlLHIsdCk6KGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihuLGksITApLFkucmVtb3ZlKGUscikpfX19KTt2YXIgYnQ9Qy5sb2NhdGlvbix3dD17Z3VpZDpEYXRlLm5vdygpfSxUdD0vXD8vO1MucGFyc2VYTUw9ZnVuY3Rpb24oZSl7dmFyIHQsbjtpZighZXx8InN0cmluZyIhPXR5cGVvZiBlKXJldHVybiBudWxsO3RyeXt0PShuZXcgQy5ET01QYXJzZXIpLnBhcnNlRnJvbVN0cmluZyhlLCJ0ZXh0L3htbCIpfWNhdGNoKGUpe31yZXR1cm4gbj10JiZ0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwYXJzZXJlcnJvciIpWzBdLHQmJiFufHxTLmVycm9yKCJJbnZhbGlkIFhNTDogIisobj9TLm1hcChuLmNoaWxkTm9kZXMsZnVuY3Rpb24oZSl7cmV0dXJuIGUudGV4dENvbnRlbnR9KS5qb2luKCJcbiIpOmUpKSx0fTt2YXIgQ3Q9L1xbXF0kLyxFdD0vXHI/XG4vZyxTdD0vXig/OnN1Ym1pdHxidXR0b258aW1hZ2V8cmVzZXR8ZmlsZSkkL2ksa3Q9L14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8a2V5Z2VuKS9pO2Z1bmN0aW9uIEF0KG4sZSxyLGkpe3ZhciB0O2lmKEFycmF5LmlzQXJyYXkoZSkpUy5lYWNoKGUsZnVuY3Rpb24oZSx0KXtyfHxDdC50ZXN0KG4pP2kobix0KTpBdChuKyJbIisoIm9iamVjdCI9PXR5cGVvZiB0JiZudWxsIT10P2U6IiIpKyJdIix0LHIsaSl9KTtlbHNlIGlmKHJ8fCJvYmplY3QiIT09dyhlKSlpKG4sZSk7ZWxzZSBmb3IodCBpbiBlKUF0KG4rIlsiK3QrIl0iLGVbdF0scixpKX1TLnBhcmFtPWZ1bmN0aW9uKGUsdCl7dmFyIG4scj1bXSxpPWZ1bmN0aW9uKGUsdCl7dmFyIG49bSh0KT90KCk6dDtyW3IubGVuZ3RoXT1lbmNvZGVVUklDb21wb25lbnQoZSkrIj0iK2VuY29kZVVSSUNvbXBvbmVudChudWxsPT1uPyIiOm4pfTtpZihudWxsPT1lKXJldHVybiIiO2lmKEFycmF5LmlzQXJyYXkoZSl8fGUuanF1ZXJ5JiYhUy5pc1BsYWluT2JqZWN0KGUpKVMuZWFjaChlLGZ1bmN0aW9uKCl7aSh0aGlzLm5hbWUsdGhpcy52YWx1ZSl9KTtlbHNlIGZvcihuIGluIGUpQXQobixlW25dLHQsaSk7cmV0dXJuIHIuam9pbigiJiIpfSxTLmZuLmV4dGVuZCh7c2VyaWFsaXplOmZ1bmN0aW9uKCl7cmV0dXJuIFMucGFyYW0odGhpcy5zZXJpYWxpemVBcnJheSgpKX0sc2VyaWFsaXplQXJyYXk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24oKXt2YXIgZT1TLnByb3AodGhpcywiZWxlbWVudHMiKTtyZXR1cm4gZT9TLm1ha2VBcnJheShlKTp0aGlzfSkuZmlsdGVyKGZ1bmN0aW9uKCl7dmFyIGU9dGhpcy50eXBlO3JldHVybiB0aGlzLm5hbWUmJiFTKHRoaXMpLmlzKCI6ZGlzYWJsZWQiKSYma3QudGVzdCh0aGlzLm5vZGVOYW1lKSYmIVN0LnRlc3QoZSkmJih0aGlzLmNoZWNrZWR8fCFwZS50ZXN0KGUpKX0pLm1hcChmdW5jdGlvbihlLHQpe3ZhciBuPVModGhpcykudmFsKCk7cmV0dXJuIG51bGw9PW4/bnVsbDpBcnJheS5pc0FycmF5KG4pP1MubWFwKG4sZnVuY3Rpb24oZSl7cmV0dXJue25hbWU6dC5uYW1lLHZhbHVlOmUucmVwbGFjZShFdCwiXHJcbiIpfX0pOntuYW1lOnQubmFtZSx2YWx1ZTpuLnJlcGxhY2UoRXQsIlxyXG4iKX19KS5nZXQoKX19KTt2YXIgTnQ9LyUyMC9nLGp0PS8jLiokLyxEdD0vKFs/Jl0pXz1bXiZdKi8scXQ9L14oLio/KTpbIFx0XSooW15cclxuXSopJC9nbSxMdD0vXig/OkdFVHxIRUFEKSQvLEh0PS9eXC9cLy8sT3Q9e30sUHQ9e30sUnQ9IiovIi5jb25jYXQoIioiKSxNdD1FLmNyZWF0ZUVsZW1lbnQoImEiKTtmdW5jdGlvbiBJdChvKXtyZXR1cm4gZnVuY3Rpb24oZSx0KXsic3RyaW5nIiE9dHlwZW9mIGUmJih0PWUsZT0iKiIpO3ZhciBuLHI9MCxpPWUudG9Mb3dlckNhc2UoKS5tYXRjaChQKXx8W107aWYobSh0KSl3aGlsZShuPWlbcisrXSkiKyI9PT1uWzBdPyhuPW4uc2xpY2UoMSl8fCIqIiwob1tuXT1vW25dfHxbXSkudW5zaGlmdCh0KSk6KG9bbl09b1tuXXx8W10pLnB1c2godCl9fWZ1bmN0aW9uIFd0KHQsaSxvLGEpe3ZhciBzPXt9LHU9dD09PVB0O2Z1bmN0aW9uIGwoZSl7dmFyIHI7cmV0dXJuIHNbZV09ITAsUy5lYWNoKHRbZV18fFtdLGZ1bmN0aW9uKGUsdCl7dmFyIG49dChpLG8sYSk7cmV0dXJuInN0cmluZyIhPXR5cGVvZiBufHx1fHxzW25dP3U/IShyPW4pOnZvaWQgMDooaS5kYXRhVHlwZXMudW5zaGlmdChuKSxsKG4pLCExKX0pLHJ9cmV0dXJuIGwoaS5kYXRhVHlwZXNbMF0pfHwhc1siKiJdJiZsKCIqIil9ZnVuY3Rpb24gRnQoZSx0KXt2YXIgbixyLGk9Uy5hamF4U2V0dGluZ3MuZmxhdE9wdGlvbnN8fHt9O2ZvcihuIGluIHQpdm9pZCAwIT09dFtuXSYmKChpW25dP2U6cnx8KHI9e30pKVtuXT10W25dKTtyZXR1cm4gciYmUy5leHRlbmQoITAsZSxyKSxlfU10LmhyZWY9YnQuaHJlZixTLmV4dGVuZCh7YWN0aXZlOjAsbGFzdE1vZGlmaWVkOnt9LGV0YWc6e30sYWpheFNldHRpbmdzOnt1cmw6YnQuaHJlZix0eXBlOiJHRVQiLGlzTG9jYWw6L14oPzphYm91dHxhcHB8YXBwLXN0b3JhZ2V8ListZXh0ZW5zaW9ufGZpbGV8cmVzfHdpZGdldCk6JC8udGVzdChidC5wcm90b2NvbCksZ2xvYmFsOiEwLHByb2Nlc3NEYXRhOiEwLGFzeW5jOiEwLGNvbnRlbnRUeXBlOiJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7IGNoYXJzZXQ9VVRGLTgiLGFjY2VwdHM6eyIqIjpSdCx0ZXh0OiJ0ZXh0L3BsYWluIixodG1sOiJ0ZXh0L2h0bWwiLHhtbDoiYXBwbGljYXRpb24veG1sLCB0ZXh0L3htbCIsanNvbjoiYXBwbGljYXRpb24vanNvbiwgdGV4dC9qYXZhc2NyaXB0In0sY29udGVudHM6e3htbDovXGJ4bWxcYi8saHRtbDovXGJodG1sLyxqc29uOi9cYmpzb25cYi99LHJlc3BvbnNlRmllbGRzOnt4bWw6InJlc3BvbnNlWE1MIix0ZXh0OiJyZXNwb25zZVRleHQiLGpzb246InJlc3BvbnNlSlNPTiJ9LGNvbnZlcnRlcnM6eyIqIHRleHQiOlN0cmluZywidGV4dCBodG1sIjohMCwidGV4dCBqc29uIjpKU09OLnBhcnNlLCJ0ZXh0IHhtbCI6Uy5wYXJzZVhNTH0sZmxhdE9wdGlvbnM6e3VybDohMCxjb250ZXh0OiEwfX0sYWpheFNldHVwOmZ1bmN0aW9uKGUsdCl7cmV0dXJuIHQ/RnQoRnQoZSxTLmFqYXhTZXR0aW5ncyksdCk6RnQoUy5hamF4U2V0dGluZ3MsZSl9LGFqYXhQcmVmaWx0ZXI6SXQoT3QpLGFqYXhUcmFuc3BvcnQ6SXQoUHQpLGFqYXg6ZnVuY3Rpb24oZSx0KXsib2JqZWN0Ij09dHlwZW9mIGUmJih0PWUsZT12b2lkIDApLHQ9dHx8e307dmFyIGMsZixwLG4sZCxyLGgsZyxpLG8sdj1TLmFqYXhTZXR1cCh7fSx0KSx5PXYuY29udGV4dHx8dixtPXYuY29udGV4dCYmKHkubm9kZVR5cGV8fHkuanF1ZXJ5KT9TKHkpOlMuZXZlbnQseD1TLkRlZmVycmVkKCksYj1TLkNhbGxiYWNrcygib25jZSBtZW1vcnkiKSx3PXYuc3RhdHVzQ29kZXx8e30sYT17fSxzPXt9LHU9ImNhbmNlbGVkIixUPXtyZWFkeVN0YXRlOjAsZ2V0UmVzcG9uc2VIZWFkZXI6ZnVuY3Rpb24oZSl7dmFyIHQ7aWYoaCl7aWYoIW4pe249e307d2hpbGUodD1xdC5leGVjKHApKW5bdFsxXS50b0xvd2VyQ2FzZSgpKyIgIl09KG5bdFsxXS50b0xvd2VyQ2FzZSgpKyIgIl18fFtdKS5jb25jYXQodFsyXSl9dD1uW2UudG9Mb3dlckNhc2UoKSsiICJdfXJldHVybiBudWxsPT10P251bGw6dC5qb2luKCIsICIpfSxnZXRBbGxSZXNwb25zZUhlYWRlcnM6ZnVuY3Rpb24oKXtyZXR1cm4gaD9wOm51bGx9LHNldFJlcXVlc3RIZWFkZXI6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gbnVsbD09aCYmKGU9c1tlLnRvTG93ZXJDYXNlKCldPXNbZS50b0xvd2VyQ2FzZSgpXXx8ZSxhW2VdPXQpLHRoaXN9LG92ZXJyaWRlTWltZVR5cGU6ZnVuY3Rpb24oZSl7cmV0dXJuIG51bGw9PWgmJih2Lm1pbWVUeXBlPWUpLHRoaXN9LHN0YXR1c0NvZGU6ZnVuY3Rpb24oZSl7dmFyIHQ7aWYoZSlpZihoKVQuYWx3YXlzKGVbVC5zdGF0dXNdKTtlbHNlIGZvcih0IGluIGUpd1t0XT1bd1t0XSxlW3RdXTtyZXR1cm4gdGhpc30sYWJvcnQ6ZnVuY3Rpb24oZSl7dmFyIHQ9ZXx8dTtyZXR1cm4gYyYmYy5hYm9ydCh0KSxsKDAsdCksdGhpc319O2lmKHgucHJvbWlzZShUKSx2LnVybD0oKGV8fHYudXJsfHxidC5ocmVmKSsiIikucmVwbGFjZShIdCxidC5wcm90b2NvbCsiLy8iKSx2LnR5cGU9dC5tZXRob2R8fHQudHlwZXx8di5tZXRob2R8fHYudHlwZSx2LmRhdGFUeXBlcz0odi5kYXRhVHlwZXx8IioiKS50b0xvd2VyQ2FzZSgpLm1hdGNoKFApfHxbIiJdLG51bGw9PXYuY3Jvc3NEb21haW4pe3I9RS5jcmVhdGVFbGVtZW50KCJhIik7dHJ5e3IuaHJlZj12LnVybCxyLmhyZWY9ci5ocmVmLHYuY3Jvc3NEb21haW49TXQucHJvdG9jb2wrIi8vIitNdC5ob3N0IT1yLnByb3RvY29sKyIvLyIrci5ob3N0fWNhdGNoKGUpe3YuY3Jvc3NEb21haW49ITB9fWlmKHYuZGF0YSYmdi5wcm9jZXNzRGF0YSYmInN0cmluZyIhPXR5cGVvZiB2LmRhdGEmJih2LmRhdGE9Uy5wYXJhbSh2LmRhdGEsdi50cmFkaXRpb25hbCkpLFd0KE90LHYsdCxUKSxoKXJldHVybiBUO2ZvcihpIGluKGc9Uy5ldmVudCYmdi5nbG9iYWwpJiYwPT1TLmFjdGl2ZSsrJiZTLmV2ZW50LnRyaWdnZXIoImFqYXhTdGFydCIpLHYudHlwZT12LnR5cGUudG9VcHBlckNhc2UoKSx2Lmhhc0NvbnRlbnQ9IUx0LnRlc3Qodi50eXBlKSxmPXYudXJsLnJlcGxhY2UoanQsIiIpLHYuaGFzQ29udGVudD92LmRhdGEmJnYucHJvY2Vzc0RhdGEmJjA9PT0odi5jb250ZW50VHlwZXx8IiIpLmluZGV4T2YoImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIpJiYodi5kYXRhPXYuZGF0YS5yZXBsYWNlKE50LCIrIikpOihvPXYudXJsLnNsaWNlKGYubGVuZ3RoKSx2LmRhdGEmJih2LnByb2Nlc3NEYXRhfHwic3RyaW5nIj09dHlwZW9mIHYuZGF0YSkmJihmKz0oVHQudGVzdChmKT8iJiI6Ij8iKSt2LmRhdGEsZGVsZXRlIHYuZGF0YSksITE9PT12LmNhY2hlJiYoZj1mLnJlcGxhY2UoRHQsIiQxIiksbz0oVHQudGVzdChmKT8iJiI6Ij8iKSsiXz0iK3d0Lmd1aWQrKytvKSx2LnVybD1mK28pLHYuaWZNb2RpZmllZCYmKFMubGFzdE1vZGlmaWVkW2ZdJiZULnNldFJlcXVlc3RIZWFkZXIoIklmLU1vZGlmaWVkLVNpbmNlIixTLmxhc3RNb2RpZmllZFtmXSksUy5ldGFnW2ZdJiZULnNldFJlcXVlc3RIZWFkZXIoIklmLU5vbmUtTWF0Y2giLFMuZXRhZ1tmXSkpLCh2LmRhdGEmJnYuaGFzQ29udGVudCYmITEhPT12LmNvbnRlbnRUeXBlfHx0LmNvbnRlbnRUeXBlKSYmVC5zZXRSZXF1ZXN0SGVhZGVyKCJDb250ZW50LVR5cGUiLHYuY29udGVudFR5cGUpLFQuc2V0UmVxdWVzdEhlYWRlcigiQWNjZXB0Iix2LmRhdGFUeXBlc1swXSYmdi5hY2NlcHRzW3YuZGF0YVR5cGVzWzBdXT92LmFjY2VwdHNbdi5kYXRhVHlwZXNbMF1dKygiKiIhPT12LmRhdGFUeXBlc1swXT8iLCAiK1J0KyI7IHE9MC4wMSI6IiIpOnYuYWNjZXB0c1siKiJdKSx2LmhlYWRlcnMpVC5zZXRSZXF1ZXN0SGVhZGVyKGksdi5oZWFkZXJzW2ldKTtpZih2LmJlZm9yZVNlbmQmJighMT09PXYuYmVmb3JlU2VuZC5jYWxsKHksVCx2KXx8aCkpcmV0dXJuIFQuYWJvcnQoKTtpZih1PSJhYm9ydCIsYi5hZGQodi5jb21wbGV0ZSksVC5kb25lKHYuc3VjY2VzcyksVC5mYWlsKHYuZXJyb3IpLGM9V3QoUHQsdix0LFQpKXtpZihULnJlYWR5U3RhdGU9MSxnJiZtLnRyaWdnZXIoImFqYXhTZW5kIixbVCx2XSksaClyZXR1cm4gVDt2LmFzeW5jJiYwPHYudGltZW91dCYmKGQ9Qy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7VC5hYm9ydCgidGltZW91dCIpfSx2LnRpbWVvdXQpKTt0cnl7aD0hMSxjLnNlbmQoYSxsKX1jYXRjaChlKXtpZihoKXRocm93IGU7bCgtMSxlKX19ZWxzZSBsKC0xLCJObyBUcmFuc3BvcnQiKTtmdW5jdGlvbiBsKGUsdCxuLHIpe3ZhciBpLG8sYSxzLHUsbD10O2h8fChoPSEwLGQmJkMuY2xlYXJUaW1lb3V0KGQpLGM9dm9pZCAwLHA9cnx8IiIsVC5yZWFkeVN0YXRlPTA8ZT80OjAsaT0yMDA8PWUmJmU8MzAwfHwzMDQ9PT1lLG4mJihzPWZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG8sYSxzPWUuY29udGVudHMsdT1lLmRhdGFUeXBlczt3aGlsZSgiKiI9PT11WzBdKXUuc2hpZnQoKSx2b2lkIDA9PT1yJiYocj1lLm1pbWVUeXBlfHx0LmdldFJlc3BvbnNlSGVhZGVyKCJDb250ZW50LVR5cGUiKSk7aWYocilmb3IoaSBpbiBzKWlmKHNbaV0mJnNbaV0udGVzdChyKSl7dS51bnNoaWZ0KGkpO2JyZWFrfWlmKHVbMF1pbiBuKW89dVswXTtlbHNle2ZvcihpIGluIG4pe2lmKCF1WzBdfHxlLmNvbnZlcnRlcnNbaSsiICIrdVswXV0pe289aTticmVha31hfHwoYT1pKX1vPW98fGF9aWYobylyZXR1cm4gbyE9PXVbMF0mJnUudW5zaGlmdChvKSxuW29dfSh2LFQsbikpLCFpJiYtMTxTLmluQXJyYXkoInNjcmlwdCIsdi5kYXRhVHlwZXMpJiZTLmluQXJyYXkoImpzb24iLHYuZGF0YVR5cGVzKTwwJiYodi5jb252ZXJ0ZXJzWyJ0ZXh0IHNjcmlwdCJdPWZ1bmN0aW9uKCl7fSkscz1mdW5jdGlvbihlLHQsbixyKXt2YXIgaSxvLGEscyx1LGw9e30sYz1lLmRhdGFUeXBlcy5zbGljZSgpO2lmKGNbMV0pZm9yKGEgaW4gZS5jb252ZXJ0ZXJzKWxbYS50b0xvd2VyQ2FzZSgpXT1lLmNvbnZlcnRlcnNbYV07bz1jLnNoaWZ0KCk7d2hpbGUobylpZihlLnJlc3BvbnNlRmllbGRzW29dJiYobltlLnJlc3BvbnNlRmllbGRzW29dXT10KSwhdSYmciYmZS5kYXRhRmlsdGVyJiYodD1lLmRhdGFGaWx0ZXIodCxlLmRhdGFUeXBlKSksdT1vLG89Yy5zaGlmdCgpKWlmKCIqIj09PW8pbz11O2Vsc2UgaWYoIioiIT09dSYmdSE9PW8pe2lmKCEoYT1sW3UrIiAiK29dfHxsWyIqICIrb10pKWZvcihpIGluIGwpaWYoKHM9aS5zcGxpdCgiICIpKVsxXT09PW8mJihhPWxbdSsiICIrc1swXV18fGxbIiogIitzWzBdXSkpeyEwPT09YT9hPWxbaV06ITAhPT1sW2ldJiYobz1zWzBdLGMudW5zaGlmdChzWzFdKSk7YnJlYWt9aWYoITAhPT1hKWlmKGEmJmVbInRocm93cyJdKXQ9YSh0KTtlbHNlIHRyeXt0PWEodCl9Y2F0Y2goZSl7cmV0dXJue3N0YXRlOiJwYXJzZXJlcnJvciIsZXJyb3I6YT9lOiJObyBjb252ZXJzaW9uIGZyb20gIit1KyIgdG8gIitvfX19cmV0dXJue3N0YXRlOiJzdWNjZXNzIixkYXRhOnR9fSh2LHMsVCxpKSxpPyh2LmlmTW9kaWZpZWQmJigodT1ULmdldFJlc3BvbnNlSGVhZGVyKCJMYXN0LU1vZGlmaWVkIikpJiYoUy5sYXN0TW9kaWZpZWRbZl09dSksKHU9VC5nZXRSZXNwb25zZUhlYWRlcigiZXRhZyIpKSYmKFMuZXRhZ1tmXT11KSksMjA0PT09ZXx8IkhFQUQiPT09di50eXBlP2w9Im5vY29udGVudCI6MzA0PT09ZT9sPSJub3Rtb2RpZmllZCI6KGw9cy5zdGF0ZSxvPXMuZGF0YSxpPSEoYT1zLmVycm9yKSkpOihhPWwsIWUmJmx8fChsPSJlcnJvciIsZTwwJiYoZT0wKSkpLFQuc3RhdHVzPWUsVC5zdGF0dXNUZXh0PSh0fHxsKSsiIixpP3gucmVzb2x2ZVdpdGgoeSxbbyxsLFRdKTp4LnJlamVjdFdpdGgoeSxbVCxsLGFdKSxULnN0YXR1c0NvZGUodyksdz12b2lkIDAsZyYmbS50cmlnZ2VyKGk/ImFqYXhTdWNjZXNzIjoiYWpheEVycm9yIixbVCx2LGk/bzphXSksYi5maXJlV2l0aCh5LFtULGxdKSxnJiYobS50cmlnZ2VyKCJhamF4Q29tcGxldGUiLFtULHZdKSwtLVMuYWN0aXZlfHxTLmV2ZW50LnRyaWdnZXIoImFqYXhTdG9wIikpKX1yZXR1cm4gVH0sZ2V0SlNPTjpmdW5jdGlvbihlLHQsbil7cmV0dXJuIFMuZ2V0KGUsdCxuLCJqc29uIil9LGdldFNjcmlwdDpmdW5jdGlvbihlLHQpe3JldHVybiBTLmdldChlLHZvaWQgMCx0LCJzY3JpcHQiKX19KSxTLmVhY2goWyJnZXQiLCJwb3N0Il0sZnVuY3Rpb24oZSxpKXtTW2ldPWZ1bmN0aW9uKGUsdCxuLHIpe3JldHVybiBtKHQpJiYocj1yfHxuLG49dCx0PXZvaWQgMCksUy5hamF4KFMuZXh0ZW5kKHt1cmw6ZSx0eXBlOmksZGF0YVR5cGU6cixkYXRhOnQsc3VjY2VzczpufSxTLmlzUGxhaW5PYmplY3QoZSkmJmUpKX19KSxTLmFqYXhQcmVmaWx0ZXIoZnVuY3Rpb24oZSl7dmFyIHQ7Zm9yKHQgaW4gZS5oZWFkZXJzKSJjb250ZW50LXR5cGUiPT09dC50b0xvd2VyQ2FzZSgpJiYoZS5jb250ZW50VHlwZT1lLmhlYWRlcnNbdF18fCIiKX0pLFMuX2V2YWxVcmw9ZnVuY3Rpb24oZSx0LG4pe3JldHVybiBTLmFqYXgoe3VybDplLHR5cGU6IkdFVCIsZGF0YVR5cGU6InNjcmlwdCIsY2FjaGU6ITAsYXN5bmM6ITEsZ2xvYmFsOiExLGNvbnZlcnRlcnM6eyJ0ZXh0IHNjcmlwdCI6ZnVuY3Rpb24oKXt9fSxkYXRhRmlsdGVyOmZ1bmN0aW9uKGUpe1MuZ2xvYmFsRXZhbChlLHQsbil9fSl9LFMuZm4uZXh0ZW5kKHt3cmFwQWxsOmZ1bmN0aW9uKGUpe3ZhciB0O3JldHVybiB0aGlzWzBdJiYobShlKSYmKGU9ZS5jYWxsKHRoaXNbMF0pKSx0PVMoZSx0aGlzWzBdLm93bmVyRG9jdW1lbnQpLmVxKDApLmNsb25lKCEwKSx0aGlzWzBdLnBhcmVudE5vZGUmJnQuaW5zZXJ0QmVmb3JlKHRoaXNbMF0pLHQubWFwKGZ1bmN0aW9uKCl7dmFyIGU9dGhpczt3aGlsZShlLmZpcnN0RWxlbWVudENoaWxkKWU9ZS5maXJzdEVsZW1lbnRDaGlsZDtyZXR1cm4gZX0pLmFwcGVuZCh0aGlzKSksdGhpc30sd3JhcElubmVyOmZ1bmN0aW9uKG4pe3JldHVybiBtKG4pP3RoaXMuZWFjaChmdW5jdGlvbihlKXtTKHRoaXMpLndyYXBJbm5lcihuLmNhbGwodGhpcyxlKSl9KTp0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgZT1TKHRoaXMpLHQ9ZS5jb250ZW50cygpO3QubGVuZ3RoP3Qud3JhcEFsbChuKTplLmFwcGVuZChuKX0pfSx3cmFwOmZ1bmN0aW9uKHQpe3ZhciBuPW0odCk7cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihlKXtTKHRoaXMpLndyYXBBbGwobj90LmNhbGwodGhpcyxlKTp0KX0pfSx1bndyYXA6ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMucGFyZW50KGUpLm5vdCgiYm9keSIpLmVhY2goZnVuY3Rpb24oKXtTKHRoaXMpLnJlcGxhY2VXaXRoKHRoaXMuY2hpbGROb2Rlcyl9KSx0aGlzfX0pLFMuZXhwci5wc2V1ZG9zLmhpZGRlbj1mdW5jdGlvbihlKXtyZXR1cm4hUy5leHByLnBzZXVkb3MudmlzaWJsZShlKX0sUy5leHByLnBzZXVkb3MudmlzaWJsZT1mdW5jdGlvbihlKXtyZXR1cm4hIShlLm9mZnNldFdpZHRofHxlLm9mZnNldEhlaWdodHx8ZS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCl9LFMuYWpheFNldHRpbmdzLnhocj1mdW5jdGlvbigpe3RyeXtyZXR1cm4gbmV3IEMuWE1MSHR0cFJlcXVlc3R9Y2F0Y2goZSl7fX07dmFyIEJ0PXswOjIwMCwxMjIzOjIwNH0sJHQ9Uy5hamF4U2V0dGluZ3MueGhyKCk7eS5jb3JzPSEhJHQmJiJ3aXRoQ3JlZGVudGlhbHMiaW4gJHQseS5hamF4PSR0PSEhJHQsUy5hamF4VHJhbnNwb3J0KGZ1bmN0aW9uKGkpe3ZhciBvLGE7aWYoeS5jb3JzfHwkdCYmIWkuY3Jvc3NEb21haW4pcmV0dXJue3NlbmQ6ZnVuY3Rpb24oZSx0KXt2YXIgbixyPWkueGhyKCk7aWYoci5vcGVuKGkudHlwZSxpLnVybCxpLmFzeW5jLGkudXNlcm5hbWUsaS5wYXNzd29yZCksaS54aHJGaWVsZHMpZm9yKG4gaW4gaS54aHJGaWVsZHMpcltuXT1pLnhockZpZWxkc1tuXTtmb3IobiBpbiBpLm1pbWVUeXBlJiZyLm92ZXJyaWRlTWltZVR5cGUmJnIub3ZlcnJpZGVNaW1lVHlwZShpLm1pbWVUeXBlKSxpLmNyb3NzRG9tYWlufHxlWyJYLVJlcXVlc3RlZC1XaXRoIl18fChlWyJYLVJlcXVlc3RlZC1XaXRoIl09IlhNTEh0dHBSZXF1ZXN0IiksZSlyLnNldFJlcXVlc3RIZWFkZXIobixlW25dKTtvPWZ1bmN0aW9uKGUpe3JldHVybiBmdW5jdGlvbigpe28mJihvPWE9ci5vbmxvYWQ9ci5vbmVycm9yPXIub25hYm9ydD1yLm9udGltZW91dD1yLm9ucmVhZHlzdGF0ZWNoYW5nZT1udWxsLCJhYm9ydCI9PT1lP3IuYWJvcnQoKToiZXJyb3IiPT09ZT8ibnVtYmVyIiE9dHlwZW9mIHIuc3RhdHVzP3QoMCwiZXJyb3IiKTp0KHIuc3RhdHVzLHIuc3RhdHVzVGV4dCk6dChCdFtyLnN0YXR1c118fHIuc3RhdHVzLHIuc3RhdHVzVGV4dCwidGV4dCIhPT0oci5yZXNwb25zZVR5cGV8fCJ0ZXh0Iil8fCJzdHJpbmciIT10eXBlb2Ygci5yZXNwb25zZVRleHQ/e2JpbmFyeTpyLnJlc3BvbnNlfTp7dGV4dDpyLnJlc3BvbnNlVGV4dH0sci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSkpfX0sci5vbmxvYWQ9bygpLGE9ci5vbmVycm9yPXIub250aW1lb3V0PW8oImVycm9yIiksdm9pZCAwIT09ci5vbmFib3J0P3Iub25hYm9ydD1hOnIub25yZWFkeXN0YXRlY2hhbmdlPWZ1bmN0aW9uKCl7ND09PXIucmVhZHlTdGF0ZSYmQy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7byYmYSgpfSl9LG89bygiYWJvcnQiKTt0cnl7ci5zZW5kKGkuaGFzQ29udGVudCYmaS5kYXRhfHxudWxsKX1jYXRjaChlKXtpZihvKXRocm93IGV9fSxhYm9ydDpmdW5jdGlvbigpe28mJm8oKX19fSksUy5hamF4UHJlZmlsdGVyKGZ1bmN0aW9uKGUpe2UuY3Jvc3NEb21haW4mJihlLmNvbnRlbnRzLnNjcmlwdD0hMSl9KSxTLmFqYXhTZXR1cCh7YWNjZXB0czp7c2NyaXB0OiJ0ZXh0L2phdmFzY3JpcHQsIGFwcGxpY2F0aW9uL2phdmFzY3JpcHQsIGFwcGxpY2F0aW9uL2VjbWFzY3JpcHQsIGFwcGxpY2F0aW9uL3gtZWNtYXNjcmlwdCJ9LGNvbnRlbnRzOntzY3JpcHQ6L1xiKD86amF2YXxlY21hKXNjcmlwdFxiL30sY29udmVydGVyczp7InRleHQgc2NyaXB0IjpmdW5jdGlvbihlKXtyZXR1cm4gUy5nbG9iYWxFdmFsKGUpLGV9fX0pLFMuYWpheFByZWZpbHRlcigic2NyaXB0IixmdW5jdGlvbihlKXt2b2lkIDA9PT1lLmNhY2hlJiYoZS5jYWNoZT0hMSksZS5jcm9zc0RvbWFpbiYmKGUudHlwZT0iR0VUIil9KSxTLmFqYXhUcmFuc3BvcnQoInNjcmlwdCIsZnVuY3Rpb24obil7dmFyIHIsaTtpZihuLmNyb3NzRG9tYWlufHxuLnNjcmlwdEF0dHJzKXJldHVybntzZW5kOmZ1bmN0aW9uKGUsdCl7cj1TKCI8c2NyaXB0PiIpLmF0dHIobi5zY3JpcHRBdHRyc3x8e30pLnByb3Aoe2NoYXJzZXQ6bi5zY3JpcHRDaGFyc2V0LHNyYzpuLnVybH0pLm9uKCJsb2FkIGVycm9yIixpPWZ1bmN0aW9uKGUpe3IucmVtb3ZlKCksaT1udWxsLGUmJnQoImVycm9yIj09PWUudHlwZT80MDQ6MjAwLGUudHlwZSl9KSxFLmhlYWQuYXBwZW5kQ2hpbGQoclswXSl9LGFib3J0OmZ1bmN0aW9uKCl7aSYmaSgpfX19KTt2YXIgX3QsenQ9W10sVXQ9Lyg9KVw/KD89JnwkKXxcP1w/LztTLmFqYXhTZXR1cCh7anNvbnA6ImNhbGxiYWNrIixqc29ucENhbGxiYWNrOmZ1bmN0aW9uKCl7dmFyIGU9enQucG9wKCl8fFMuZXhwYW5kbysiXyIrd3QuZ3VpZCsrO3JldHVybiB0aGlzW2VdPSEwLGV9fSksUy5hamF4UHJlZmlsdGVyKCJqc29uIGpzb25wIixmdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvLGE9ITEhPT1lLmpzb25wJiYoVXQudGVzdChlLnVybCk/InVybCI6InN0cmluZyI9PXR5cGVvZiBlLmRhdGEmJjA9PT0oZS5jb250ZW50VHlwZXx8IiIpLmluZGV4T2YoImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIpJiZVdC50ZXN0KGUuZGF0YSkmJiJkYXRhIik7aWYoYXx8Impzb25wIj09PWUuZGF0YVR5cGVzWzBdKXJldHVybiByPWUuanNvbnBDYWxsYmFjaz1tKGUuanNvbnBDYWxsYmFjayk/ZS5qc29ucENhbGxiYWNrKCk6ZS5qc29ucENhbGxiYWNrLGE/ZVthXT1lW2FdLnJlcGxhY2UoVXQsIiQxIityKTohMSE9PWUuanNvbnAmJihlLnVybCs9KFR0LnRlc3QoZS51cmwpPyImIjoiPyIpK2UuanNvbnArIj0iK3IpLGUuY29udmVydGVyc1sic2NyaXB0IGpzb24iXT1mdW5jdGlvbigpe3JldHVybiBvfHxTLmVycm9yKHIrIiB3YXMgbm90IGNhbGxlZCIpLG9bMF19LGUuZGF0YVR5cGVzWzBdPSJqc29uIixpPUNbcl0sQ1tyXT1mdW5jdGlvbigpe289YXJndW1lbnRzfSxuLmFsd2F5cyhmdW5jdGlvbigpe3ZvaWQgMD09PWk/UyhDKS5yZW1vdmVQcm9wKHIpOkNbcl09aSxlW3JdJiYoZS5qc29ucENhbGxiYWNrPXQuanNvbnBDYWxsYmFjayx6dC5wdXNoKHIpKSxvJiZtKGkpJiZpKG9bMF0pLG89aT12b2lkIDB9KSwic2NyaXB0In0pLHkuY3JlYXRlSFRNTERvY3VtZW50PSgoX3Q9RS5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoIiIpLmJvZHkpLmlubmVySFRNTD0iPGZvcm0+PC9mb3JtPjxmb3JtPjwvZm9ybT4iLDI9PT1fdC5jaGlsZE5vZGVzLmxlbmd0aCksUy5wYXJzZUhUTUw9ZnVuY3Rpb24oZSx0LG4pe3JldHVybiJzdHJpbmciIT10eXBlb2YgZT9bXTooImJvb2xlYW4iPT10eXBlb2YgdCYmKG49dCx0PSExKSx0fHwoeS5jcmVhdGVIVE1MRG9jdW1lbnQ/KChyPSh0PUUuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50KCIiKSkuY3JlYXRlRWxlbWVudCgiYmFzZSIpKS5ocmVmPUUubG9jYXRpb24uaHJlZix0LmhlYWQuYXBwZW5kQ2hpbGQocikpOnQ9RSksbz0hbiYmW10sKGk9Ti5leGVjKGUpKT9bdC5jcmVhdGVFbGVtZW50KGlbMV0pXTooaT14ZShbZV0sdCxvKSxvJiZvLmxlbmd0aCYmUyhvKS5yZW1vdmUoKSxTLm1lcmdlKFtdLGkuY2hpbGROb2RlcykpKTt2YXIgcixpLG99LFMuZm4ubG9hZD1mdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvLGE9dGhpcyxzPWUuaW5kZXhPZigiICIpO3JldHVybi0xPHMmJihyPWh0KGUuc2xpY2UocykpLGU9ZS5zbGljZSgwLHMpKSxtKHQpPyhuPXQsdD12b2lkIDApOnQmJiJvYmplY3QiPT10eXBlb2YgdCYmKGk9IlBPU1QiKSwwPGEubGVuZ3RoJiZTLmFqYXgoe3VybDplLHR5cGU6aXx8IkdFVCIsZGF0YVR5cGU6Imh0bWwiLGRhdGE6dH0pLmRvbmUoZnVuY3Rpb24oZSl7bz1hcmd1bWVudHMsYS5odG1sKHI/UygiPGRpdj4iKS5hcHBlbmQoUy5wYXJzZUhUTUwoZSkpLmZpbmQocik6ZSl9KS5hbHdheXMobiYmZnVuY3Rpb24oZSx0KXthLmVhY2goZnVuY3Rpb24oKXtuLmFwcGx5KHRoaXMsb3x8W2UucmVzcG9uc2VUZXh0LHQsZV0pfSl9KSx0aGlzfSxTLmV4cHIucHNldWRvcy5hbmltYXRlZD1mdW5jdGlvbih0KXtyZXR1cm4gUy5ncmVwKFMudGltZXJzLGZ1bmN0aW9uKGUpe3JldHVybiB0PT09ZS5lbGVtfSkubGVuZ3RofSxTLm9mZnNldD17c2V0T2Zmc2V0OmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG8sYSxzLHUsbD1TLmNzcyhlLCJwb3NpdGlvbiIpLGM9UyhlKSxmPXt9OyJzdGF0aWMiPT09bCYmKGUuc3R5bGUucG9zaXRpb249InJlbGF0aXZlIikscz1jLm9mZnNldCgpLG89Uy5jc3MoZSwidG9wIiksdT1TLmNzcyhlLCJsZWZ0IiksKCJhYnNvbHV0ZSI9PT1sfHwiZml4ZWQiPT09bCkmJi0xPChvK3UpLmluZGV4T2YoImF1dG8iKT8oYT0ocj1jLnBvc2l0aW9uKCkpLnRvcCxpPXIubGVmdCk6KGE9cGFyc2VGbG9hdChvKXx8MCxpPXBhcnNlRmxvYXQodSl8fDApLG0odCkmJih0PXQuY2FsbChlLG4sUy5leHRlbmQoe30scykpKSxudWxsIT10LnRvcCYmKGYudG9wPXQudG9wLXMudG9wK2EpLG51bGwhPXQubGVmdCYmKGYubGVmdD10LmxlZnQtcy5sZWZ0K2kpLCJ1c2luZyJpbiB0P3QudXNpbmcuY2FsbChlLGYpOmMuY3NzKGYpfX0sUy5mbi5leHRlbmQoe29mZnNldDpmdW5jdGlvbih0KXtpZihhcmd1bWVudHMubGVuZ3RoKXJldHVybiB2b2lkIDA9PT10P3RoaXM6dGhpcy5lYWNoKGZ1bmN0aW9uKGUpe1Mub2Zmc2V0LnNldE9mZnNldCh0aGlzLHQsZSl9KTt2YXIgZSxuLHI9dGhpc1swXTtyZXR1cm4gcj9yLmdldENsaWVudFJlY3RzKCkubGVuZ3RoPyhlPXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksbj1yLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcse3RvcDplLnRvcCtuLnBhZ2VZT2Zmc2V0LGxlZnQ6ZS5sZWZ0K24ucGFnZVhPZmZzZXR9KTp7dG9wOjAsbGVmdDowfTp2b2lkIDB9LHBvc2l0aW9uOmZ1bmN0aW9uKCl7aWYodGhpc1swXSl7dmFyIGUsdCxuLHI9dGhpc1swXSxpPXt0b3A6MCxsZWZ0OjB9O2lmKCJmaXhlZCI9PT1TLmNzcyhyLCJwb3NpdGlvbiIpKXQ9ci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtlbHNle3Q9dGhpcy5vZmZzZXQoKSxuPXIub3duZXJEb2N1bWVudCxlPXIub2Zmc2V0UGFyZW50fHxuLmRvY3VtZW50RWxlbWVudDt3aGlsZShlJiYoZT09PW4uYm9keXx8ZT09PW4uZG9jdW1lbnRFbGVtZW50KSYmInN0YXRpYyI9PT1TLmNzcyhlLCJwb3NpdGlvbiIpKWU9ZS5wYXJlbnROb2RlO2UmJmUhPT1yJiYxPT09ZS5ub2RlVHlwZSYmKChpPVMoZSkub2Zmc2V0KCkpLnRvcCs9Uy5jc3MoZSwiYm9yZGVyVG9wV2lkdGgiLCEwKSxpLmxlZnQrPVMuY3NzKGUsImJvcmRlckxlZnRXaWR0aCIsITApKX1yZXR1cm57dG9wOnQudG9wLWkudG9wLVMuY3NzKHIsIm1hcmdpblRvcCIsITApLGxlZnQ6dC5sZWZ0LWkubGVmdC1TLmNzcyhyLCJtYXJnaW5MZWZ0IiwhMCl9fX0sb2Zmc2V0UGFyZW50OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5vZmZzZXRQYXJlbnQ7d2hpbGUoZSYmInN0YXRpYyI9PT1TLmNzcyhlLCJwb3NpdGlvbiIpKWU9ZS5vZmZzZXRQYXJlbnQ7cmV0dXJuIGV8fHJlfSl9fSksUy5lYWNoKHtzY3JvbGxMZWZ0OiJwYWdlWE9mZnNldCIsc2Nyb2xsVG9wOiJwYWdlWU9mZnNldCJ9LGZ1bmN0aW9uKHQsaSl7dmFyIG89InBhZ2VZT2Zmc2V0Ij09PWk7Uy5mblt0XT1mdW5jdGlvbihlKXtyZXR1cm4gJCh0aGlzLGZ1bmN0aW9uKGUsdCxuKXt2YXIgcjtpZih4KGUpP3I9ZTo5PT09ZS5ub2RlVHlwZSYmKHI9ZS5kZWZhdWx0Vmlldyksdm9pZCAwPT09bilyZXR1cm4gcj9yW2ldOmVbdF07cj9yLnNjcm9sbFRvKG8/ci5wYWdlWE9mZnNldDpuLG8/bjpyLnBhZ2VZT2Zmc2V0KTplW3RdPW59LHQsZSxhcmd1bWVudHMubGVuZ3RoKX19KSxTLmVhY2goWyJ0b3AiLCJsZWZ0Il0sZnVuY3Rpb24oZSxuKXtTLmNzc0hvb2tzW25dPUZlKHkucGl4ZWxQb3NpdGlvbixmdW5jdGlvbihlLHQpe2lmKHQpcmV0dXJuIHQ9V2UoZSxuKSxQZS50ZXN0KHQpP1MoZSkucG9zaXRpb24oKVtuXSsicHgiOnR9KX0pLFMuZWFjaCh7SGVpZ2h0OiJoZWlnaHQiLFdpZHRoOiJ3aWR0aCJ9LGZ1bmN0aW9uKGEscyl7Uy5lYWNoKHtwYWRkaW5nOiJpbm5lciIrYSxjb250ZW50OnMsIiI6Im91dGVyIithfSxmdW5jdGlvbihyLG8pe1MuZm5bb109ZnVuY3Rpb24oZSx0KXt2YXIgbj1hcmd1bWVudHMubGVuZ3RoJiYocnx8ImJvb2xlYW4iIT10eXBlb2YgZSksaT1yfHwoITA9PT1lfHwhMD09PXQ/Im1hcmdpbiI6ImJvcmRlciIpO3JldHVybiAkKHRoaXMsZnVuY3Rpb24oZSx0LG4pe3ZhciByO3JldHVybiB4KGUpPzA9PT1vLmluZGV4T2YoIm91dGVyIik/ZVsiaW5uZXIiK2FdOmUuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50WyJjbGllbnQiK2FdOjk9PT1lLm5vZGVUeXBlPyhyPWUuZG9jdW1lbnRFbGVtZW50LE1hdGgubWF4KGUuYm9keVsic2Nyb2xsIithXSxyWyJzY3JvbGwiK2FdLGUuYm9keVsib2Zmc2V0IithXSxyWyJvZmZzZXQiK2FdLHJbImNsaWVudCIrYV0pKTp2b2lkIDA9PT1uP1MuY3NzKGUsdCxpKTpTLnN0eWxlKGUsdCxuLGkpfSxzLG4/ZTp2b2lkIDAsbil9fSl9KSxTLmVhY2goWyJhamF4U3RhcnQiLCJhamF4U3RvcCIsImFqYXhDb21wbGV0ZSIsImFqYXhFcnJvciIsImFqYXhTdWNjZXNzIiwiYWpheFNlbmQiXSxmdW5jdGlvbihlLHQpe1MuZm5bdF09ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMub24odCxlKX19KSxTLmZuLmV4dGVuZCh7YmluZDpmdW5jdGlvbihlLHQsbil7cmV0dXJuIHRoaXMub24oZSxudWxsLHQsbil9LHVuYmluZDpmdW5jdGlvbihlLHQpe3JldHVybiB0aGlzLm9mZihlLG51bGwsdCl9LGRlbGVnYXRlOmZ1bmN0aW9uKGUsdCxuLHIpe3JldHVybiB0aGlzLm9uKHQsZSxuLHIpfSx1bmRlbGVnYXRlOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gMT09PWFyZ3VtZW50cy5sZW5ndGg/dGhpcy5vZmYoZSwiKioiKTp0aGlzLm9mZih0LGV8fCIqKiIsbil9LGhvdmVyOmZ1bmN0aW9uKGUsdCl7cmV0dXJuIHRoaXMubW91c2VlbnRlcihlKS5tb3VzZWxlYXZlKHR8fGUpfX0pLFMuZWFjaCgiYmx1ciBmb2N1cyBmb2N1c2luIGZvY3Vzb3V0IHJlc2l6ZSBzY3JvbGwgY2xpY2sgZGJsY2xpY2sgbW91c2Vkb3duIG1vdXNldXAgbW91c2Vtb3ZlIG1vdXNlb3ZlciBtb3VzZW91dCBtb3VzZWVudGVyIG1vdXNlbGVhdmUgY2hhbmdlIHNlbGVjdCBzdWJtaXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBjb250ZXh0bWVudSIuc3BsaXQoIiAiKSxmdW5jdGlvbihlLG4pe1MuZm5bbl09ZnVuY3Rpb24oZSx0KXtyZXR1cm4gMDxhcmd1bWVudHMubGVuZ3RoP3RoaXMub24obixudWxsLGUsdCk6dGhpcy50cmlnZ2VyKG4pfX0pO3ZhciBYdD0vXltcc1x1RkVGRlx4QTBdK3xbXHNcdUZFRkZceEEwXSskL2c7Uy5wcm94eT1mdW5jdGlvbihlLHQpe3ZhciBuLHIsaTtpZigic3RyaW5nIj09dHlwZW9mIHQmJihuPWVbdF0sdD1lLGU9biksbShlKSlyZXR1cm4gcj1zLmNhbGwoYXJndW1lbnRzLDIpLChpPWZ1bmN0aW9uKCl7cmV0dXJuIGUuYXBwbHkodHx8dGhpcyxyLmNvbmNhdChzLmNhbGwoYXJndW1lbnRzKSkpfSkuZ3VpZD1lLmd1aWQ9ZS5ndWlkfHxTLmd1aWQrKyxpfSxTLmhvbGRSZWFkeT1mdW5jdGlvbihlKXtlP1MucmVhZHlXYWl0Kys6Uy5yZWFkeSghMCl9LFMuaXNBcnJheT1BcnJheS5pc0FycmF5LFMucGFyc2VKU09OPUpTT04ucGFyc2UsUy5ub2RlTmFtZT1BLFMuaXNGdW5jdGlvbj1tLFMuaXNXaW5kb3c9eCxTLmNhbWVsQ2FzZT1YLFMudHlwZT13LFMubm93PURhdGUubm93LFMuaXNOdW1lcmljPWZ1bmN0aW9uKGUpe3ZhciB0PVMudHlwZShlKTtyZXR1cm4oIm51bWJlciI9PT10fHwic3RyaW5nIj09PXQpJiYhaXNOYU4oZS1wYXJzZUZsb2F0KGUpKX0sUy50cmltPWZ1bmN0aW9uKGUpe3JldHVybiBudWxsPT1lPyIiOihlKyIiKS5yZXBsYWNlKFh0LCIiKX0sImZ1bmN0aW9uIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZCYmZGVmaW5lKCJqcXVlcnkiLFtdLGZ1bmN0aW9uKCl7cmV0dXJuIFN9KTt2YXIgVnQ9Qy5qUXVlcnksR3Q9Qy4kO3JldHVybiBTLm5vQ29uZmxpY3Q9ZnVuY3Rpb24oZSl7cmV0dXJuIEMuJD09PVMmJihDLiQ9R3QpLGUmJkMualF1ZXJ5PT09UyYmKEMualF1ZXJ5PVZ0KSxTfSwidW5kZWZpbmVkIj09dHlwZW9mIGUmJihDLmpRdWVyeT1DLiQ9UyksU30pOwovKiEKICogalF1ZXJ5IFVJIFdpZGdldCAxLjEzLjIKICogaHR0cDovL2pxdWVyeXVpLmNvbQogKgogKiBDb3B5cmlnaHQgalF1ZXJ5IEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9ycwogKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuCiAqIGh0dHA6Ly9qcXVlcnkub3JnL2xpY2Vuc2UKICovCgovLz4+bGFiZWw6IFdpZGdldAovLz4+Z3JvdXA6IENvcmUKLy8+PmRlc2NyaXB0aW9uOiBQcm92aWRlcyBhIGZhY3RvcnkgZm9yIGNyZWF0aW5nIHN0YXRlZnVsIHdpZGdldHMgd2l0aCBhIGNvbW1vbiBBUEkuCi8vPj5kb2NzOiBodHRwOi8vYXBpLmpxdWVyeXVpLmNvbS9qUXVlcnkud2lkZ2V0LwovLz4+ZGVtb3M6IGh0dHA6Ly9qcXVlcnl1aS5jb20vd2lkZ2V0LwoKKCBmdW5jdGlvbiggZmFjdG9yeSApIHsKICAgIGlmICggdHlwZW9mIGRlZmluZSA9PT0gImZ1bmN0aW9uIiAmJiBkZWZpbmUuYW1kICkgewoKICAgICAgICAvLyBBTUQuIFJlZ2lzdGVyIGFzIGFuIGFub255bW91cyBtb2R1bGUuCiAgICAgICAgZGVmaW5lKCBbICJqcXVlcnkiIF0sIGZhY3RvcnkgKTsKICAgIH0gZWxzZSB7CgogICAgICAgIC8vIEJyb3dzZXIgZ2xvYmFscwogICAgICAgIGZhY3RvcnkoIGpRdWVyeSApOwogICAgfQp9KCBmdW5jdGlvbiggJCApIHsKICAgICJ1c2Ugc3RyaWN0IjsKCiAgICAkLnVpID0gJC51aSB8fCB7fTsKCiAgICB2YXIgdmVyc2lvbiA9ICQudWkudmVyc2lvbiA9ICIxLjEzLjIiOwoKICAgIHZhciB3aWRnZXRVdWlkID0gMDsKICAgIHZhciB3aWRnZXRIYXNPd25Qcm9wZXJ0eSA9IEFycmF5LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTsKICAgIHZhciB3aWRnZXRTbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTsKCiAgICAkLmNsZWFuRGF0YSA9ICggZnVuY3Rpb24oIG9yaWcgKSB7CiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCBlbGVtcyApIHsKICAgICAgICAgICAgdmFyIGV2ZW50cywgZWxlbSwgaTsKICAgICAgICAgICAgZm9yICggaSA9IDA7ICggZWxlbSA9IGVsZW1zWyBpIF0gKSAhPSBudWxsOyBpKysgKSB7CgogICAgICAgICAgICAgICAgLy8gT25seSB0cmlnZ2VyIHJlbW92ZSB3aGVuIG5lY2Vzc2FyeSB0byBzYXZlIHRpbWUKICAgICAgICAgICAgICAgIGV2ZW50cyA9ICQuX2RhdGEoIGVsZW0sICJldmVudHMiICk7CiAgICAgICAgICAgICAgICBpZiAoIGV2ZW50cyAmJiBldmVudHMucmVtb3ZlICkgewogICAgICAgICAgICAgICAgICAgICQoIGVsZW0gKS50cmlnZ2VySGFuZGxlciggInJlbW92ZSIgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBvcmlnKCBlbGVtcyApOwogICAgICAgIH07CiAgICB9ICkoICQuY2xlYW5EYXRhICk7CgogICAgJC53aWRnZXQgPSBmdW5jdGlvbiggbmFtZSwgYmFzZSwgcHJvdG90eXBlICkgewogICAgICAgIHZhciBleGlzdGluZ0NvbnN0cnVjdG9yLCBjb25zdHJ1Y3RvciwgYmFzZVByb3RvdHlwZTsKCiAgICAgICAgLy8gUHJveGllZFByb3RvdHlwZSBhbGxvd3MgdGhlIHByb3ZpZGVkIHByb3RvdHlwZSB0byByZW1haW4gdW5tb2RpZmllZAogICAgICAgIC8vIHNvIHRoYXQgaXQgY2FuIGJlIHVzZWQgYXMgYSBtaXhpbiBmb3IgbXVsdGlwbGUgd2lkZ2V0cyAoIzg4NzYpCiAgICAgICAgdmFyIHByb3hpZWRQcm90b3R5cGUgPSB7fTsKCiAgICAgICAgdmFyIG5hbWVzcGFjZSA9IG5hbWUuc3BsaXQoICIuIiApWyAwIF07CiAgICAgICAgbmFtZSA9IG5hbWUuc3BsaXQoICIuIiApWyAxIF07CiAgICAgICAgdmFyIGZ1bGxOYW1lID0gbmFtZXNwYWNlICsgIi0iICsgbmFtZTsKCiAgICAgICAgaWYgKCAhcHJvdG90eXBlICkgewogICAgICAgICAgICBwcm90b3R5cGUgPSBiYXNlOwogICAgICAgICAgICBiYXNlID0gJC5XaWRnZXQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoIEFycmF5LmlzQXJyYXkoIHByb3RvdHlwZSApICkgewogICAgICAgICAgICBwcm90b3R5cGUgPSAkLmV4dGVuZC5hcHBseSggbnVsbCwgWyB7fSBdLmNvbmNhdCggcHJvdG90eXBlICkgKTsKICAgICAgICB9CgogICAgICAgIC8vIENyZWF0ZSBzZWxlY3RvciBmb3IgcGx1Z2luCiAgICAgICAgJC5leHByLnBzZXVkb3NbIGZ1bGxOYW1lLnRvTG93ZXJDYXNlKCkgXSA9IGZ1bmN0aW9uKCBlbGVtICkgewogICAgICAgICAgICByZXR1cm4gISEkLmRhdGEoIGVsZW0sIGZ1bGxOYW1lICk7CiAgICAgICAgfTsKCiAgICAgICAgJFsgbmFtZXNwYWNlIF0gPSAkWyBuYW1lc3BhY2UgXSB8fCB7fTsKICAgICAgICBleGlzdGluZ0NvbnN0cnVjdG9yID0gJFsgbmFtZXNwYWNlIF1bIG5hbWUgXTsKICAgICAgICBjb25zdHJ1Y3RvciA9ICRbIG5hbWVzcGFjZSBdWyBuYW1lIF0gPSBmdW5jdGlvbiggb3B0aW9ucywgZWxlbWVudCApIHsKCiAgICAgICAgICAgIC8vIEFsbG93IGluc3RhbnRpYXRpb24gd2l0aG91dCAibmV3IiBrZXl3b3JkCiAgICAgICAgICAgIGlmICggIXRoaXMgfHwgIXRoaXMuX2NyZWF0ZVdpZGdldCApIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgY29uc3RydWN0b3IoIG9wdGlvbnMsIGVsZW1lbnQgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQWxsb3cgaW5zdGFudGlhdGlvbiB3aXRob3V0IGluaXRpYWxpemluZyBmb3Igc2ltcGxlIGluaGVyaXRhbmNlCiAgICAgICAgICAgIC8vIG11c3QgdXNlICJuZXciIGtleXdvcmQgKHRoZSBjb2RlIGFib3ZlIGFsd2F5cyBwYXNzZXMgYXJncykKICAgICAgICAgICAgaWYgKCBhcmd1bWVudHMubGVuZ3RoICkgewogICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlV2lkZ2V0KCBvcHRpb25zLCBlbGVtZW50ICk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICAvLyBFeHRlbmQgd2l0aCB0aGUgZXhpc3RpbmcgY29uc3RydWN0b3IgdG8gY2Fycnkgb3ZlciBhbnkgc3RhdGljIHByb3BlcnRpZXMKICAgICAgICAkLmV4dGVuZCggY29uc3RydWN0b3IsIGV4aXN0aW5nQ29uc3RydWN0b3IsIHsKICAgICAgICAgICAgdmVyc2lvbjogcHJvdG90eXBlLnZlcnNpb24sCgogICAgICAgICAgICAvLyBDb3B5IHRoZSBvYmplY3QgdXNlZCB0byBjcmVhdGUgdGhlIHByb3RvdHlwZSBpbiBjYXNlIHdlIG5lZWQgdG8KICAgICAgICAgICAgLy8gcmVkZWZpbmUgdGhlIHdpZGdldCBsYXRlcgogICAgICAgICAgICBfcHJvdG86ICQuZXh0ZW5kKCB7fSwgcHJvdG90eXBlICksCgogICAgICAgICAgICAvLyBUcmFjayB3aWRnZXRzIHRoYXQgaW5oZXJpdCBmcm9tIHRoaXMgd2lkZ2V0IGluIGNhc2UgdGhpcyB3aWRnZXQgaXMKICAgICAgICAgICAgLy8gcmVkZWZpbmVkIGFmdGVyIGEgd2lkZ2V0IGluaGVyaXRzIGZyb20gaXQKICAgICAgICAgICAgX2NoaWxkQ29uc3RydWN0b3JzOiBbXQogICAgICAgIH0gKTsKCiAgICAgICAgYmFzZVByb3RvdHlwZSA9IG5ldyBiYXNlKCk7CgogICAgICAgIC8vIFdlIG5lZWQgdG8gbWFrZSB0aGUgb3B0aW9ucyBoYXNoIGEgcHJvcGVydHkgZGlyZWN0bHkgb24gdGhlIG5ldyBpbnN0YW5jZQogICAgICAgIC8vIG90aGVyd2lzZSB3ZSdsbCBtb2RpZnkgdGhlIG9wdGlvbnMgaGFzaCBvbiB0aGUgcHJvdG90eXBlIHRoYXQgd2UncmUKICAgICAgICAvLyBpbmhlcml0aW5nIGZyb20KICAgICAgICBiYXNlUHJvdG90eXBlLm9wdGlvbnMgPSAkLndpZGdldC5leHRlbmQoIHt9LCBiYXNlUHJvdG90eXBlLm9wdGlvbnMgKTsKICAgICAgICAkLmVhY2goIHByb3RvdHlwZSwgZnVuY3Rpb24oIHByb3AsIHZhbHVlICkgewogICAgICAgICAgICBpZiAoIHR5cGVvZiB2YWx1ZSAhPT0gImZ1bmN0aW9uIiApIHsKICAgICAgICAgICAgICAgIHByb3hpZWRQcm90b3R5cGVbIHByb3AgXSA9IHZhbHVlOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHByb3hpZWRQcm90b3R5cGVbIHByb3AgXSA9ICggZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICBmdW5jdGlvbiBfc3VwZXIoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJhc2UucHJvdG90eXBlWyBwcm9wIF0uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZ1bmN0aW9uIF9zdXBlckFwcGx5KCBhcmdzICkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBiYXNlLnByb3RvdHlwZVsgcHJvcCBdLmFwcGx5KCB0aGlzLCBhcmdzICk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHZhciBfX3N1cGVyID0gdGhpcy5fc3VwZXI7CiAgICAgICAgICAgICAgICAgICAgdmFyIF9fc3VwZXJBcHBseSA9IHRoaXMuX3N1cGVyQXBwbHk7CiAgICAgICAgICAgICAgICAgICAgdmFyIHJldHVyblZhbHVlOwoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdXBlciA9IF9zdXBlcjsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdXBlckFwcGx5ID0gX3N1cGVyQXBwbHk7CgogICAgICAgICAgICAgICAgICAgIHJldHVyblZhbHVlID0gdmFsdWUuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApOwoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdXBlciA9IF9fc3VwZXI7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3VwZXJBcHBseSA9IF9fc3VwZXJBcHBseTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldHVyblZhbHVlOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfSApKCk7CiAgICAgICAgfSApOwogICAgICAgIGNvbnN0cnVjdG9yLnByb3RvdHlwZSA9ICQud2lkZ2V0LmV4dGVuZCggYmFzZVByb3RvdHlwZSwgewoKICAgICAgICAgICAgLy8gVE9ETzogcmVtb3ZlIHN1cHBvcnQgZm9yIHdpZGdldEV2ZW50UHJlZml4CiAgICAgICAgICAgIC8vIGFsd2F5cyB1c2UgdGhlIG5hbWUgKyBhIGNvbG9uIGFzIHRoZSBwcmVmaXgsIGUuZy4sIGRyYWdnYWJsZTpzdGFydAogICAgICAgICAgICAvLyBkb24ndCBwcmVmaXggZm9yIHdpZGdldHMgdGhhdCBhcmVuJ3QgRE9NLWJhc2VkCiAgICAgICAgICAgIHdpZGdldEV2ZW50UHJlZml4OiBleGlzdGluZ0NvbnN0cnVjdG9yID8gKCBiYXNlUHJvdG90eXBlLndpZGdldEV2ZW50UHJlZml4IHx8IG5hbWUgKSA6IG5hbWUKICAgICAgICB9LCBwcm94aWVkUHJvdG90eXBlLCB7CiAgICAgICAgICAgIGNvbnN0cnVjdG9yOiBjb25zdHJ1Y3RvciwKICAgICAgICAgICAgbmFtZXNwYWNlOiBuYW1lc3BhY2UsCiAgICAgICAgICAgIHdpZGdldE5hbWU6IG5hbWUsCiAgICAgICAgICAgIHdpZGdldEZ1bGxOYW1lOiBmdWxsTmFtZQogICAgICAgIH0gKTsKCiAgICAgICAgLy8gSWYgdGhpcyB3aWRnZXQgaXMgYmVpbmcgcmVkZWZpbmVkIHRoZW4gd2UgbmVlZCB0byBmaW5kIGFsbCB3aWRnZXRzIHRoYXQKICAgICAgICAvLyBhcmUgaW5oZXJpdGluZyBmcm9tIGl0IGFuZCByZWRlZmluZSBhbGwgb2YgdGhlbSBzbyB0aGF0IHRoZXkgaW5oZXJpdCBmcm9tCiAgICAgICAgLy8gdGhlIG5ldyB2ZXJzaW9uIG9mIHRoaXMgd2lkZ2V0LiBXZSdyZSBlc3NlbnRpYWxseSB0cnlpbmcgdG8gcmVwbGFjZSBvbmUKICAgICAgICAvLyBsZXZlbCBpbiB0aGUgcHJvdG90eXBlIGNoYWluLgogICAgICAgIGlmICggZXhpc3RpbmdDb25zdHJ1Y3RvciApIHsKICAgICAgICAgICAgJC5lYWNoKCBleGlzdGluZ0NvbnN0cnVjdG9yLl9jaGlsZENvbnN0cnVjdG9ycywgZnVuY3Rpb24oIGksIGNoaWxkICkgewogICAgICAgICAgICAgICAgdmFyIGNoaWxkUHJvdG90eXBlID0gY2hpbGQucHJvdG90eXBlOwoKICAgICAgICAgICAgICAgIC8vIFJlZGVmaW5lIHRoZSBjaGlsZCB3aWRnZXQgdXNpbmcgdGhlIHNhbWUgcHJvdG90eXBlIHRoYXQgd2FzCiAgICAgICAgICAgICAgICAvLyBvcmlnaW5hbGx5IHVzZWQsIGJ1dCBpbmhlcml0IGZyb20gdGhlIG5ldyB2ZXJzaW9uIG9mIHRoZSBiYXNlCiAgICAgICAgICAgICAgICAkLndpZGdldCggY2hpbGRQcm90b3R5cGUubmFtZXNwYWNlICsgIi4iICsgY2hpbGRQcm90b3R5cGUud2lkZ2V0TmFtZSwgY29uc3RydWN0b3IsCiAgICAgICAgICAgICAgICAgICAgY2hpbGQuX3Byb3RvICk7CiAgICAgICAgICAgIH0gKTsKCiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgbGlzdCBvZiBleGlzdGluZyBjaGlsZCBjb25zdHJ1Y3RvcnMgZnJvbSB0aGUgb2xkIGNvbnN0cnVjdG9yCiAgICAgICAgICAgIC8vIHNvIHRoZSBvbGQgY2hpbGQgY29uc3RydWN0b3JzIGNhbiBiZSBnYXJiYWdlIGNvbGxlY3RlZAogICAgICAgICAgICBkZWxldGUgZXhpc3RpbmdDb25zdHJ1Y3Rvci5fY2hpbGRDb25zdHJ1Y3RvcnM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYmFzZS5fY2hpbGRDb25zdHJ1Y3RvcnMucHVzaCggY29uc3RydWN0b3IgKTsKICAgICAgICB9CgogICAgICAgICQud2lkZ2V0LmJyaWRnZSggbmFtZSwgY29uc3RydWN0b3IgKTsKCiAgICAgICAgcmV0dXJuIGNvbnN0cnVjdG9yOwogICAgfTsKCiAgICAkLndpZGdldC5leHRlbmQgPSBmdW5jdGlvbiggdGFyZ2V0ICkgewogICAgICAgIHZhciBpbnB1dCA9IHdpZGdldFNsaWNlLmNhbGwoIGFyZ3VtZW50cywgMSApOwogICAgICAgIHZhciBpbnB1dEluZGV4ID0gMDsKICAgICAgICB2YXIgaW5wdXRMZW5ndGggPSBpbnB1dC5sZW5ndGg7CiAgICAgICAgdmFyIGtleTsKICAgICAgICB2YXIgdmFsdWU7CgogICAgICAgIGZvciAoIDsgaW5wdXRJbmRleCA8IGlucHV0TGVuZ3RoOyBpbnB1dEluZGV4KysgKSB7CiAgICAgICAgICAgIGZvciAoIGtleSBpbiBpbnB1dFsgaW5wdXRJbmRleCBdICkgewogICAgICAgICAgICAgICAgdmFsdWUgPSBpbnB1dFsgaW5wdXRJbmRleCBdWyBrZXkgXTsKICAgICAgICAgICAgICAgIGlmICggd2lkZ2V0SGFzT3duUHJvcGVydHkuY2FsbCggaW5wdXRbIGlucHV0SW5kZXggXSwga2V5ICkgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCApIHsKCiAgICAgICAgICAgICAgICAgICAgLy8gQ2xvbmUgb2JqZWN0cwogICAgICAgICAgICAgICAgICAgIGlmICggJC5pc1BsYWluT2JqZWN0KCB2YWx1ZSApICkgewogICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRbIGtleSBdID0gJC5pc1BsYWluT2JqZWN0KCB0YXJnZXRbIGtleSBdICkgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJC53aWRnZXQuZXh0ZW5kKCB7fSwgdGFyZ2V0WyBrZXkgXSwgdmFsdWUgKSA6CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG9uJ3QgZXh0ZW5kIHN0cmluZ3MsIGFycmF5cywgZXRjLiB3aXRoIG9iamVjdHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQud2lkZ2V0LmV4dGVuZCgge30sIHZhbHVlICk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBDb3B5IGV2ZXJ5dGhpbmcgZWxzZSBieSByZWZlcmVuY2UKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRbIGtleSBdID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0YXJnZXQ7CiAgICB9OwoKICAgICQud2lkZ2V0LmJyaWRnZSA9IGZ1bmN0aW9uKCBuYW1lLCBvYmplY3QgKSB7CiAgICAgICAgdmFyIGZ1bGxOYW1lID0gb2JqZWN0LnByb3RvdHlwZS53aWRnZXRGdWxsTmFtZSB8fCBuYW1lOwogICAgICAgICQuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBvcHRpb25zICkgewogICAgICAgICAgICB2YXIgaXNNZXRob2RDYWxsID0gdHlwZW9mIG9wdGlvbnMgPT09ICJzdHJpbmciOwogICAgICAgICAgICB2YXIgYXJncyA9IHdpZGdldFNsaWNlLmNhbGwoIGFyZ3VtZW50cywgMSApOwogICAgICAgICAgICB2YXIgcmV0dXJuVmFsdWUgPSB0aGlzOwoKICAgICAgICAgICAgaWYgKCBpc01ldGhvZENhbGwgKSB7CgogICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhbiBlbXB0eSBjb2xsZWN0aW9uLCB3ZSBuZWVkIHRvIGhhdmUgdGhlIGluc3RhbmNlIG1ldGhvZAogICAgICAgICAgICAgICAgLy8gcmV0dXJuIHVuZGVmaW5lZCBpbnN0ZWFkIG9mIHRoZSBqUXVlcnkgaW5zdGFuY2UKICAgICAgICAgICAgICAgIGlmICggIXRoaXMubGVuZ3RoICYmIG9wdGlvbnMgPT09ICJpbnN0YW5jZSIgKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtZXRob2RWYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gJC5kYXRhKCB0aGlzLCBmdWxsTmFtZSApOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBvcHRpb25zID09PSAiaW5zdGFuY2UiICkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSBpbnN0YW5jZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAhaW5zdGFuY2UgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJC5lcnJvciggImNhbm5vdCBjYWxsIG1ldGhvZHMgb24gIiArIG5hbWUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgcHJpb3IgdG8gaW5pdGlhbGl6YXRpb247ICIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhdHRlbXB0ZWQgdG8gY2FsbCBtZXRob2QgJyIgKyBvcHRpb25zICsgIiciICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggdHlwZW9mIGluc3RhbmNlWyBvcHRpb25zIF0gIT09ICJmdW5jdGlvbiIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuY2hhckF0KCAwICkgPT09ICJfIiApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkLmVycm9yKCAibm8gc3VjaCBtZXRob2QgJyIgKyBvcHRpb25zICsgIicgZm9yICIgKyBuYW1lICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIHdpZGdldCBpbnN0YW5jZSIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kVmFsdWUgPSBpbnN0YW5jZVsgb3B0aW9ucyBdLmFwcGx5KCBpbnN0YW5jZSwgYXJncyApOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBtZXRob2RWYWx1ZSAhPT0gaW5zdGFuY2UgJiYgbWV0aG9kVmFsdWUgIT09IHVuZGVmaW5lZCApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVyblZhbHVlID0gbWV0aG9kVmFsdWUgJiYgbWV0aG9kVmFsdWUuanF1ZXJ5ID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5WYWx1ZS5wdXNoU3RhY2soIG1ldGhvZFZhbHVlLmdldCgpICkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZFZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgICAgIC8vIEFsbG93IG11bHRpcGxlIGhhc2hlcyB0byBiZSBwYXNzZWQgb24gaW5pdAogICAgICAgICAgICAgICAgaWYgKCBhcmdzLmxlbmd0aCApIHsKICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0gJC53aWRnZXQuZXh0ZW5kLmFwcGx5KCBudWxsLCBbIG9wdGlvbnMgXS5jb25jYXQoIGFyZ3MgKSApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gJC5kYXRhKCB0aGlzLCBmdWxsTmFtZSApOwogICAgICAgICAgICAgICAgICAgIGlmICggaW5zdGFuY2UgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLm9wdGlvbiggb3B0aW9ucyB8fCB7fSApOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGluc3RhbmNlLl9pbml0ICkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UuX2luaXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICQuZGF0YSggdGhpcywgZnVsbE5hbWUsIG5ldyBvYmplY3QoIG9wdGlvbnMsIHRoaXMgKSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHJldHVyblZhbHVlOwogICAgICAgIH07CiAgICB9OwoKICAgICQuV2lkZ2V0ID0gZnVuY3Rpb24oIC8qIG9wdGlvbnMsIGVsZW1lbnQgKi8gKSB7fTsKICAgICQuV2lkZ2V0Ll9jaGlsZENvbnN0cnVjdG9ycyA9IFtdOwoKICAgICQuV2lkZ2V0LnByb3RvdHlwZSA9IHsKICAgICAgICB3aWRnZXROYW1lOiAid2lkZ2V0IiwKICAgICAgICB3aWRnZXRFdmVudFByZWZpeDogIiIsCiAgICAgICAgZGVmYXVsdEVsZW1lbnQ6ICI8ZGl2PiIsCgogICAgICAgIG9wdGlvbnM6IHsKICAgICAgICAgICAgY2xhc3Nlczoge30sCiAgICAgICAgICAgIGRpc2FibGVkOiBmYWxzZSwKCiAgICAgICAgICAgIC8vIENhbGxiYWNrcwogICAgICAgICAgICBjcmVhdGU6IG51bGwKICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlV2lkZ2V0OiBmdW5jdGlvbiggb3B0aW9ucywgZWxlbWVudCApIHsKICAgICAgICAgICAgZWxlbWVudCA9ICQoIGVsZW1lbnQgfHwgdGhpcy5kZWZhdWx0RWxlbWVudCB8fCB0aGlzIClbIDAgXTsKICAgICAgICAgICAgdGhpcy5lbGVtZW50ID0gJCggZWxlbWVudCApOwogICAgICAgICAgICB0aGlzLnV1aWQgPSB3aWRnZXRVdWlkKys7CiAgICAgICAgICAgIHRoaXMuZXZlbnROYW1lc3BhY2UgPSAiLiIgKyB0aGlzLndpZGdldE5hbWUgKyB0aGlzLnV1aWQ7CgogICAgICAgICAgICB0aGlzLmJpbmRpbmdzID0gJCgpOwogICAgICAgICAgICB0aGlzLmhvdmVyYWJsZSA9ICQoKTsKICAgICAgICAgICAgdGhpcy5mb2N1c2FibGUgPSAkKCk7CiAgICAgICAgICAgIHRoaXMuY2xhc3Nlc0VsZW1lbnRMb29rdXAgPSB7fTsKCiAgICAgICAgICAgIGlmICggZWxlbWVudCAhPT0gdGhpcyApIHsKICAgICAgICAgICAgICAgICQuZGF0YSggZWxlbWVudCwgdGhpcy53aWRnZXRGdWxsTmFtZSwgdGhpcyApOwogICAgICAgICAgICAgICAgdGhpcy5fb24oIHRydWUsIHRoaXMuZWxlbWVudCwgewogICAgICAgICAgICAgICAgICAgIHJlbW92ZTogZnVuY3Rpb24oIGV2ZW50ICkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGV2ZW50LnRhcmdldCA9PT0gZWxlbWVudCApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGVzdHJveSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSApOwogICAgICAgICAgICAgICAgdGhpcy5kb2N1bWVudCA9ICQoIGVsZW1lbnQuc3R5bGUgPwoKICAgICAgICAgICAgICAgICAgICAvLyBFbGVtZW50IHdpdGhpbiB0aGUgZG9jdW1lbnQKICAgICAgICAgICAgICAgICAgICBlbGVtZW50Lm93bmVyRG9jdW1lbnQgOgoKICAgICAgICAgICAgICAgICAgICAvLyBFbGVtZW50IGlzIHdpbmRvdyBvciBkb2N1bWVudAogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuZG9jdW1lbnQgfHwgZWxlbWVudCApOwogICAgICAgICAgICAgICAgdGhpcy53aW5kb3cgPSAkKCB0aGlzLmRvY3VtZW50WyAwIF0uZGVmYXVsdFZpZXcgfHwgdGhpcy5kb2N1bWVudFsgMCBdLnBhcmVudFdpbmRvdyApOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLm9wdGlvbnMgPSAkLndpZGdldC5leHRlbmQoIHt9LAogICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLAogICAgICAgICAgICAgICAgdGhpcy5fZ2V0Q3JlYXRlT3B0aW9ucygpLAogICAgICAgICAgICAgICAgb3B0aW9ucyApOwoKICAgICAgICAgICAgdGhpcy5fY3JlYXRlKCk7CgogICAgICAgICAgICBpZiAoIHRoaXMub3B0aW9ucy5kaXNhYmxlZCApIHsKICAgICAgICAgICAgICAgIHRoaXMuX3NldE9wdGlvbkRpc2FibGVkKCB0aGlzLm9wdGlvbnMuZGlzYWJsZWQgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fdHJpZ2dlciggImNyZWF0ZSIsIG51bGwsIHRoaXMuX2dldENyZWF0ZUV2ZW50RGF0YSgpICk7CiAgICAgICAgICAgIHRoaXMuX2luaXQoKTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0Q3JlYXRlT3B0aW9uczogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB7fTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0Q3JlYXRlRXZlbnREYXRhOiAkLm5vb3AsCgogICAgICAgIF9jcmVhdGU6ICQubm9vcCwKCiAgICAgICAgX2luaXQ6ICQubm9vcCwKCiAgICAgICAgZGVzdHJveTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKCiAgICAgICAgICAgIHRoaXMuX2Rlc3Ryb3koKTsKICAgICAgICAgICAgJC5lYWNoKCB0aGlzLmNsYXNzZXNFbGVtZW50TG9va3VwLCBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHsKICAgICAgICAgICAgICAgIHRoYXQuX3JlbW92ZUNsYXNzKCB2YWx1ZSwga2V5ICk7CiAgICAgICAgICAgIH0gKTsKCiAgICAgICAgICAgIC8vIFdlIGNhbiBwcm9iYWJseSByZW1vdmUgdGhlIHVuYmluZCBjYWxscyBpbiAyLjAKICAgICAgICAgICAgLy8gYWxsIGV2ZW50IGJpbmRpbmdzIHNob3VsZCBnbyB0aHJvdWdoIHRoaXMuX29uKCkKICAgICAgICAgICAgdGhpcy5lbGVtZW50CiAgICAgICAgICAgICAgICAub2ZmKCB0aGlzLmV2ZW50TmFtZXNwYWNlICkKICAgICAgICAgICAgICAgIC5yZW1vdmVEYXRhKCB0aGlzLndpZGdldEZ1bGxOYW1lICk7CiAgICAgICAgICAgIHRoaXMud2lkZ2V0KCkKICAgICAgICAgICAgICAgIC5vZmYoIHRoaXMuZXZlbnROYW1lc3BhY2UgKQogICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoICJhcmlhLWRpc2FibGVkIiApOwoKICAgICAgICAgICAgLy8gQ2xlYW4gdXAgZXZlbnRzIGFuZCBzdGF0ZXMKICAgICAgICAgICAgdGhpcy5iaW5kaW5ncy5vZmYoIHRoaXMuZXZlbnROYW1lc3BhY2UgKTsKICAgICAgICB9LAoKICAgICAgICBfZGVzdHJveTogJC5ub29wLAoKICAgICAgICB3aWRnZXQ6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50OwogICAgICAgIH0sCgogICAgICAgIG9wdGlvbjogZnVuY3Rpb24oIGtleSwgdmFsdWUgKSB7CiAgICAgICAgICAgIHZhciBvcHRpb25zID0ga2V5OwogICAgICAgICAgICB2YXIgcGFydHM7CiAgICAgICAgICAgIHZhciBjdXJPcHRpb247CiAgICAgICAgICAgIHZhciBpOwoKICAgICAgICAgICAgaWYgKCBhcmd1bWVudHMubGVuZ3RoID09PSAwICkgewoKICAgICAgICAgICAgICAgIC8vIERvbid0IHJldHVybiBhIHJlZmVyZW5jZSB0byB0aGUgaW50ZXJuYWwgaGFzaAogICAgICAgICAgICAgICAgcmV0dXJuICQud2lkZ2V0LmV4dGVuZCgge30sIHRoaXMub3B0aW9ucyApOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIHR5cGVvZiBrZXkgPT09ICJzdHJpbmciICkgewoKICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBuZXN0ZWQga2V5cywgZS5nLiwgImZvby5iYXIiID0+IHsgZm9vOiB7IGJhcjogX19fIH0gfQogICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9OwogICAgICAgICAgICAgICAgcGFydHMgPSBrZXkuc3BsaXQoICIuIiApOwogICAgICAgICAgICAgICAga2V5ID0gcGFydHMuc2hpZnQoKTsKICAgICAgICAgICAgICAgIGlmICggcGFydHMubGVuZ3RoICkgewogICAgICAgICAgICAgICAgICAgIGN1ck9wdGlvbiA9IG9wdGlvbnNbIGtleSBdID0gJC53aWRnZXQuZXh0ZW5kKCB7fSwgdGhpcy5vcHRpb25zWyBrZXkgXSApOwogICAgICAgICAgICAgICAgICAgIGZvciAoIGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoIC0gMTsgaSsrICkgewogICAgICAgICAgICAgICAgICAgICAgICBjdXJPcHRpb25bIHBhcnRzWyBpIF0gXSA9IGN1ck9wdGlvblsgcGFydHNbIGkgXSBdIHx8IHt9OwogICAgICAgICAgICAgICAgICAgICAgICBjdXJPcHRpb24gPSBjdXJPcHRpb25bIHBhcnRzWyBpIF0gXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAga2V5ID0gcGFydHMucG9wKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCBhcmd1bWVudHMubGVuZ3RoID09PSAxICkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VyT3B0aW9uWyBrZXkgXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGN1ck9wdGlvblsga2V5IF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGN1ck9wdGlvblsga2V5IF0gPSB2YWx1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCBhcmd1bWVudHMubGVuZ3RoID09PSAxICkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zWyBrZXkgXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IHRoaXMub3B0aW9uc1sga2V5IF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG9wdGlvbnNbIGtleSBdID0gdmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX3NldE9wdGlvbnMoIG9wdGlvbnMgKTsKCiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCgogICAgICAgIF9zZXRPcHRpb25zOiBmdW5jdGlvbiggb3B0aW9ucyApIHsKICAgICAgICAgICAgdmFyIGtleTsKCiAgICAgICAgICAgIGZvciAoIGtleSBpbiBvcHRpb25zICkgewogICAgICAgICAgICAgICAgdGhpcy5fc2V0T3B0aW9uKCBrZXksIG9wdGlvbnNbIGtleSBdICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCgogICAgICAgIF9zZXRPcHRpb246IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkgewogICAgICAgICAgICBpZiAoIGtleSA9PT0gImNsYXNzZXMiICkgewogICAgICAgICAgICAgICAgdGhpcy5fc2V0T3B0aW9uQ2xhc3NlcyggdmFsdWUgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5vcHRpb25zWyBrZXkgXSA9IHZhbHVlOwoKICAgICAgICAgICAgaWYgKCBrZXkgPT09ICJkaXNhYmxlZCIgKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9zZXRPcHRpb25EaXNhYmxlZCggdmFsdWUgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgX3NldE9wdGlvbkNsYXNzZXM6IGZ1bmN0aW9uKCB2YWx1ZSApIHsKICAgICAgICAgICAgdmFyIGNsYXNzS2V5LCBlbGVtZW50cywgY3VycmVudEVsZW1lbnRzOwoKICAgICAgICAgICAgZm9yICggY2xhc3NLZXkgaW4gdmFsdWUgKSB7CiAgICAgICAgICAgICAgICBjdXJyZW50RWxlbWVudHMgPSB0aGlzLmNsYXNzZXNFbGVtZW50TG9va3VwWyBjbGFzc0tleSBdOwogICAgICAgICAgICAgICAgaWYgKCB2YWx1ZVsgY2xhc3NLZXkgXSA9PT0gdGhpcy5vcHRpb25zLmNsYXNzZXNbIGNsYXNzS2V5IF0gfHwKICAgICAgICAgICAgICAgICAgICAhY3VycmVudEVsZW1lbnRzIHx8CiAgICAgICAgICAgICAgICAgICAgIWN1cnJlbnRFbGVtZW50cy5sZW5ndGggKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gV2UgYXJlIGRvaW5nIHRoaXMgdG8gY3JlYXRlIGEgbmV3IGpRdWVyeSBvYmplY3QgYmVjYXVzZSB0aGUgX3JlbW92ZUNsYXNzKCkgY2FsbAogICAgICAgICAgICAgICAgLy8gb24gdGhlIG5leHQgbGluZSBpcyBnb2luZyB0byBkZXN0cm95IHRoZSByZWZlcmVuY2UgdG8gdGhlIGN1cnJlbnQgZWxlbWVudHMgYmVpbmcKICAgICAgICAgICAgICAgIC8vIHRyYWNrZWQuIFdlIG5lZWQgdG8gc2F2ZSBhIGNvcHkgb2YgdGhpcyBjb2xsZWN0aW9uIHNvIHRoYXQgd2UgY2FuIGFkZCB0aGUgbmV3IGNsYXNzZXMKICAgICAgICAgICAgICAgIC8vIGJlbG93LgogICAgICAgICAgICAgICAgZWxlbWVudHMgPSAkKCBjdXJyZW50RWxlbWVudHMuZ2V0KCkgKTsKICAgICAgICAgICAgICAgIHRoaXMuX3JlbW92ZUNsYXNzKCBjdXJyZW50RWxlbWVudHMsIGNsYXNzS2V5ICk7CgogICAgICAgICAgICAgICAgLy8gV2UgZG9uJ3QgdXNlIF9hZGRDbGFzcygpIGhlcmUsIGJlY2F1c2UgdGhhdCB1c2VzIHRoaXMub3B0aW9ucy5jbGFzc2VzCiAgICAgICAgICAgICAgICAvLyBmb3IgZ2VuZXJhdGluZyB0aGUgc3RyaW5nIG9mIGNsYXNzZXMuIFdlIHdhbnQgdG8gdXNlIHRoZSB2YWx1ZSBwYXNzZWQgaW4gZnJvbQogICAgICAgICAgICAgICAgLy8gX3NldE9wdGlvbigpLCB0aGlzIGlzIHRoZSBuZXcgdmFsdWUgb2YgdGhlIGNsYXNzZXMgb3B0aW9uIHdoaWNoIHdhcyBwYXNzZWQgdG8KICAgICAgICAgICAgICAgIC8vIF9zZXRPcHRpb24oKS4gV2UgcGFzcyB0aGlzIHZhbHVlIGRpcmVjdGx5IHRvIF9jbGFzc2VzKCkuCiAgICAgICAgICAgICAgICBlbGVtZW50cy5hZGRDbGFzcyggdGhpcy5fY2xhc3NlcyggewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IGVsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgIGtleXM6IGNsYXNzS2V5LAogICAgICAgICAgICAgICAgICAgIGNsYXNzZXM6IHZhbHVlLAogICAgICAgICAgICAgICAgICAgIGFkZDogdHJ1ZQogICAgICAgICAgICAgICAgfSApICk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfc2V0T3B0aW9uRGlzYWJsZWQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHsKICAgICAgICAgICAgdGhpcy5fdG9nZ2xlQ2xhc3MoIHRoaXMud2lkZ2V0KCksIHRoaXMud2lkZ2V0RnVsbE5hbWUgKyAiLWRpc2FibGVkIiwgbnVsbCwgISF2YWx1ZSApOwoKICAgICAgICAgICAgLy8gSWYgdGhlIHdpZGdldCBpcyBiZWNvbWluZyBkaXNhYmxlZCwgdGhlbiBub3RoaW5nIGlzIGludGVyYWN0aXZlCiAgICAgICAgICAgIGlmICggdmFsdWUgKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVDbGFzcyggdGhpcy5ob3ZlcmFibGUsIG51bGwsICJ1aS1zdGF0ZS1ob3ZlciIgKTsKICAgICAgICAgICAgICAgIHRoaXMuX3JlbW92ZUNsYXNzKCB0aGlzLmZvY3VzYWJsZSwgbnVsbCwgInVpLXN0YXRlLWZvY3VzIiApOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgZW5hYmxlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NldE9wdGlvbnMoIHsgZGlzYWJsZWQ6IGZhbHNlIH0gKTsKICAgICAgICB9LAoKICAgICAgICBkaXNhYmxlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NldE9wdGlvbnMoIHsgZGlzYWJsZWQ6IHRydWUgfSApOwogICAgICAgIH0sCgogICAgICAgIF9jbGFzc2VzOiBmdW5jdGlvbiggb3B0aW9ucyApIHsKICAgICAgICAgICAgdmFyIGZ1bGwgPSBbXTsKICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwoKICAgICAgICAgICAgb3B0aW9ucyA9ICQuZXh0ZW5kKCB7CiAgICAgICAgICAgICAgICBlbGVtZW50OiB0aGlzLmVsZW1lbnQsCiAgICAgICAgICAgICAgICBjbGFzc2VzOiB0aGlzLm9wdGlvbnMuY2xhc3NlcyB8fCB7fQogICAgICAgICAgICB9LCBvcHRpb25zICk7CgogICAgICAgICAgICBmdW5jdGlvbiBiaW5kUmVtb3ZlRXZlbnQoKSB7CiAgICAgICAgICAgICAgICB2YXIgbm9kZXNUb0JpbmQgPSBbXTsKCiAgICAgICAgICAgICAgICBvcHRpb25zLmVsZW1lbnQuZWFjaCggZnVuY3Rpb24oIF8sIGVsZW1lbnQgKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGlzVHJhY2tlZCA9ICQubWFwKCB0aGF0LmNsYXNzZXNFbGVtZW50TG9va3VwLCBmdW5jdGlvbiggZWxlbWVudHMgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50czsKICAgICAgICAgICAgICAgICAgICB9ICkKICAgICAgICAgICAgICAgICAgICAgICAgLnNvbWUoIGZ1bmN0aW9uKCBlbGVtZW50cyApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50cy5pcyggZWxlbWVudCApOwogICAgICAgICAgICAgICAgICAgICAgICB9ICk7CgogICAgICAgICAgICAgICAgICAgIGlmICggIWlzVHJhY2tlZCApIHsKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXNUb0JpbmQucHVzaCggZWxlbWVudCApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gKTsKCiAgICAgICAgICAgICAgICB0aGF0Ll9vbiggJCggbm9kZXNUb0JpbmQgKSwgewogICAgICAgICAgICAgICAgICAgIHJlbW92ZTogIl91bnRyYWNrQ2xhc3Nlc0VsZW1lbnQiCiAgICAgICAgICAgICAgICB9ICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NDbGFzc1N0cmluZyggY2xhc3NlcywgY2hlY2tPcHRpb24gKSB7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudCwgaTsKICAgICAgICAgICAgICAgIGZvciAoIGkgPSAwOyBpIDwgY2xhc3Nlcy5sZW5ndGg7IGkrKyApIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gdGhhdC5jbGFzc2VzRWxlbWVudExvb2t1cFsgY2xhc3Nlc1sgaSBdIF0gfHwgJCgpOwogICAgICAgICAgICAgICAgICAgIGlmICggb3B0aW9ucy5hZGQgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRSZW1vdmVFdmVudCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gJCggJC51bmlxdWVTb3J0KCBjdXJyZW50LmdldCgpLmNvbmNhdCggb3B0aW9ucy5lbGVtZW50LmdldCgpICkgKSApOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgPSAkKCBjdXJyZW50Lm5vdCggb3B0aW9ucy5lbGVtZW50ICkuZ2V0KCkgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhhdC5jbGFzc2VzRWxlbWVudExvb2t1cFsgY2xhc3Nlc1sgaSBdIF0gPSBjdXJyZW50OwogICAgICAgICAgICAgICAgICAgIGZ1bGwucHVzaCggY2xhc3Nlc1sgaSBdICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCBjaGVja09wdGlvbiAmJiBvcHRpb25zLmNsYXNzZXNbIGNsYXNzZXNbIGkgXSBdICkgewogICAgICAgICAgICAgICAgICAgICAgICBmdWxsLnB1c2goIG9wdGlvbnMuY2xhc3Nlc1sgY2xhc3Nlc1sgaSBdIF0gKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICggb3B0aW9ucy5rZXlzICkgewogICAgICAgICAgICAgICAgcHJvY2Vzc0NsYXNzU3RyaW5nKCBvcHRpb25zLmtleXMubWF0Y2goIC9cUysvZyApIHx8IFtdLCB0cnVlICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCBvcHRpb25zLmV4dHJhICkgewogICAgICAgICAgICAgICAgcHJvY2Vzc0NsYXNzU3RyaW5nKCBvcHRpb25zLmV4dHJhLm1hdGNoKCAvXFMrL2cgKSB8fCBbXSApOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZnVsbC5qb2luKCAiICIgKTsKICAgICAgICB9LAoKICAgICAgICBfdW50cmFja0NsYXNzZXNFbGVtZW50OiBmdW5jdGlvbiggZXZlbnQgKSB7CiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgJC5lYWNoKCB0aGF0LmNsYXNzZXNFbGVtZW50TG9va3VwLCBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHsKICAgICAgICAgICAgICAgIGlmICggJC5pbkFycmF5KCBldmVudC50YXJnZXQsIHZhbHVlICkgIT09IC0xICkgewogICAgICAgICAgICAgICAgICAgIHRoYXQuY2xhc3Nlc0VsZW1lbnRMb29rdXBbIGtleSBdID0gJCggdmFsdWUubm90KCBldmVudC50YXJnZXQgKS5nZXQoKSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9ICk7CgogICAgICAgICAgICB0aGlzLl9vZmYoICQoIGV2ZW50LnRhcmdldCApICk7CiAgICAgICAgfSwKCiAgICAgICAgX3JlbW92ZUNsYXNzOiBmdW5jdGlvbiggZWxlbWVudCwga2V5cywgZXh0cmEgKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl90b2dnbGVDbGFzcyggZWxlbWVudCwga2V5cywgZXh0cmEsIGZhbHNlICk7CiAgICAgICAgfSwKCiAgICAgICAgX2FkZENsYXNzOiBmdW5jdGlvbiggZWxlbWVudCwga2V5cywgZXh0cmEgKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl90b2dnbGVDbGFzcyggZWxlbWVudCwga2V5cywgZXh0cmEsIHRydWUgKTsKICAgICAgICB9LAoKICAgICAgICBfdG9nZ2xlQ2xhc3M6IGZ1bmN0aW9uKCBlbGVtZW50LCBrZXlzLCBleHRyYSwgYWRkICkgewogICAgICAgICAgICBhZGQgPSAoIHR5cGVvZiBhZGQgPT09ICJib29sZWFuIiApID8gYWRkIDogZXh0cmE7CiAgICAgICAgICAgIHZhciBzaGlmdCA9ICggdHlwZW9mIGVsZW1lbnQgPT09ICJzdHJpbmciIHx8IGVsZW1lbnQgPT09IG51bGwgKSwKICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7CiAgICAgICAgICAgICAgICAgICAgZXh0cmE6IHNoaWZ0ID8ga2V5cyA6IGV4dHJhLAogICAgICAgICAgICAgICAgICAgIGtleXM6IHNoaWZ0ID8gZWxlbWVudCA6IGtleXMsCiAgICAgICAgICAgICAgICAgICAgZWxlbWVudDogc2hpZnQgPyB0aGlzLmVsZW1lbnQgOiBlbGVtZW50LAogICAgICAgICAgICAgICAgICAgIGFkZDogYWRkCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICBvcHRpb25zLmVsZW1lbnQudG9nZ2xlQ2xhc3MoIHRoaXMuX2NsYXNzZXMoIG9wdGlvbnMgKSwgYWRkICk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCgogICAgICAgIF9vbjogZnVuY3Rpb24oIHN1cHByZXNzRGlzYWJsZWRDaGVjaywgZWxlbWVudCwgaGFuZGxlcnMgKSB7CiAgICAgICAgICAgIHZhciBkZWxlZ2F0ZUVsZW1lbnQ7CiAgICAgICAgICAgIHZhciBpbnN0YW5jZSA9IHRoaXM7CgogICAgICAgICAgICAvLyBObyBzdXBwcmVzc0Rpc2FibGVkQ2hlY2sgZmxhZywgc2h1ZmZsZSBhcmd1bWVudHMKICAgICAgICAgICAgaWYgKCB0eXBlb2Ygc3VwcHJlc3NEaXNhYmxlZENoZWNrICE9PSAiYm9vbGVhbiIgKSB7CiAgICAgICAgICAgICAgICBoYW5kbGVycyA9IGVsZW1lbnQ7CiAgICAgICAgICAgICAgICBlbGVtZW50ID0gc3VwcHJlc3NEaXNhYmxlZENoZWNrOwogICAgICAgICAgICAgICAgc3VwcHJlc3NEaXNhYmxlZENoZWNrID0gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIE5vIGVsZW1lbnQgYXJndW1lbnQsIHNodWZmbGUgYW5kIHVzZSB0aGlzLmVsZW1lbnQKICAgICAgICAgICAgaWYgKCAhaGFuZGxlcnMgKSB7CiAgICAgICAgICAgICAgICBoYW5kbGVycyA9IGVsZW1lbnQ7CiAgICAgICAgICAgICAgICBlbGVtZW50ID0gdGhpcy5lbGVtZW50OwogICAgICAgICAgICAgICAgZGVsZWdhdGVFbGVtZW50ID0gdGhpcy53aWRnZXQoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBkZWxlZ2F0ZUVsZW1lbnQgPSAkKCBlbGVtZW50ICk7CiAgICAgICAgICAgICAgICB0aGlzLmJpbmRpbmdzID0gdGhpcy5iaW5kaW5ncy5hZGQoIGVsZW1lbnQgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJC5lYWNoKCBoYW5kbGVycywgZnVuY3Rpb24oIGV2ZW50LCBoYW5kbGVyICkgewogICAgICAgICAgICAgICAgZnVuY3Rpb24gaGFuZGxlclByb3h5KCkgewoKICAgICAgICAgICAgICAgICAgICAvLyBBbGxvdyB3aWRnZXRzIHRvIGN1c3RvbWl6ZSB0aGUgZGlzYWJsZWQgaGFuZGxpbmcKICAgICAgICAgICAgICAgICAgICAvLyAtIGRpc2FibGVkIGFzIGFuIGFycmF5IGluc3RlYWQgb2YgYm9vbGVhbgogICAgICAgICAgICAgICAgICAgIC8vIC0gZGlzYWJsZWQgY2xhc3MgYXMgbWV0aG9kIGZvciBkaXNhYmxpbmcgaW5kaXZpZHVhbCBwYXJ0cwogICAgICAgICAgICAgICAgICAgIGlmICggIXN1cHByZXNzRGlzYWJsZWRDaGVjayAmJgogICAgICAgICAgICAgICAgICAgICAgICAoIGluc3RhbmNlLm9wdGlvbnMuZGlzYWJsZWQgPT09IHRydWUgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoIHRoaXMgKS5oYXNDbGFzcyggInVpLXN0YXRlLWRpc2FibGVkIiApICkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICggdHlwZW9mIGhhbmRsZXIgPT09ICJzdHJpbmciID8gaW5zdGFuY2VbIGhhbmRsZXIgXSA6IGhhbmRsZXIgKQogICAgICAgICAgICAgICAgICAgICAgICAuYXBwbHkoIGluc3RhbmNlLCBhcmd1bWVudHMgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBDb3B5IHRoZSBndWlkIHNvIGRpcmVjdCB1bmJpbmRpbmcgd29ya3MKICAgICAgICAgICAgICAgIGlmICggdHlwZW9mIGhhbmRsZXIgIT09ICJzdHJpbmciICkgewogICAgICAgICAgICAgICAgICAgIGhhbmRsZXJQcm94eS5ndWlkID0gaGFuZGxlci5ndWlkID0KICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5ndWlkIHx8IGhhbmRsZXJQcm94eS5ndWlkIHx8ICQuZ3VpZCsrOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IGV2ZW50Lm1hdGNoKCAvXihbXHc6LV0qKVxzKiguKikkLyApOwogICAgICAgICAgICAgICAgdmFyIGV2ZW50TmFtZSA9IG1hdGNoWyAxIF0gKyBpbnN0YW5jZS5ldmVudE5hbWVzcGFjZTsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3RvciA9IG1hdGNoWyAyIF07CgogICAgICAgICAgICAgICAgaWYgKCBzZWxlY3RvciApIHsKICAgICAgICAgICAgICAgICAgICBkZWxlZ2F0ZUVsZW1lbnQub24oIGV2ZW50TmFtZSwgc2VsZWN0b3IsIGhhbmRsZXJQcm94eSApOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50Lm9uKCBldmVudE5hbWUsIGhhbmRsZXJQcm94eSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9ICk7CiAgICAgICAgfSwKCiAgICAgICAgX29mZjogZnVuY3Rpb24oIGVsZW1lbnQsIGV2ZW50TmFtZSApIHsKICAgICAgICAgICAgZXZlbnROYW1lID0gKCBldmVudE5hbWUgfHwgIiIgKS5zcGxpdCggIiAiICkuam9pbiggdGhpcy5ldmVudE5hbWVzcGFjZSArICIgIiApICsKICAgICAgICAgICAgICAgIHRoaXMuZXZlbnROYW1lc3BhY2U7CiAgICAgICAgICAgIGVsZW1lbnQub2ZmKCBldmVudE5hbWUgKTsKCiAgICAgICAgICAgIC8vIENsZWFyIHRoZSBzdGFjayB0byBhdm9pZCBtZW1vcnkgbGVha3MgKCMxMDA1NikKICAgICAgICAgICAgdGhpcy5iaW5kaW5ncyA9ICQoIHRoaXMuYmluZGluZ3Mubm90KCBlbGVtZW50ICkuZ2V0KCkgKTsKICAgICAgICAgICAgdGhpcy5mb2N1c2FibGUgPSAkKCB0aGlzLmZvY3VzYWJsZS5ub3QoIGVsZW1lbnQgKS5nZXQoKSApOwogICAgICAgICAgICB0aGlzLmhvdmVyYWJsZSA9ICQoIHRoaXMuaG92ZXJhYmxlLm5vdCggZWxlbWVudCApLmdldCgpICk7CiAgICAgICAgfSwKCiAgICAgICAgX2RlbGF5OiBmdW5jdGlvbiggaGFuZGxlciwgZGVsYXkgKSB7CiAgICAgICAgICAgIGZ1bmN0aW9uIGhhbmRsZXJQcm94eSgpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoIHR5cGVvZiBoYW5kbGVyID09PSAic3RyaW5nIiA/IGluc3RhbmNlWyBoYW5kbGVyIF0gOiBoYW5kbGVyICkKICAgICAgICAgICAgICAgICAgICAuYXBwbHkoIGluc3RhbmNlLCBhcmd1bWVudHMgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgaW5zdGFuY2UgPSB0aGlzOwogICAgICAgICAgICByZXR1cm4gc2V0VGltZW91dCggaGFuZGxlclByb3h5LCBkZWxheSB8fCAwICk7CiAgICAgICAgfSwKCiAgICAgICAgX2hvdmVyYWJsZTogZnVuY3Rpb24oIGVsZW1lbnQgKSB7CiAgICAgICAgICAgIHRoaXMuaG92ZXJhYmxlID0gdGhpcy5ob3ZlcmFibGUuYWRkKCBlbGVtZW50ICk7CiAgICAgICAgICAgIHRoaXMuX29uKCBlbGVtZW50LCB7CiAgICAgICAgICAgICAgICBtb3VzZWVudGVyOiBmdW5jdGlvbiggZXZlbnQgKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYWRkQ2xhc3MoICQoIGV2ZW50LmN1cnJlbnRUYXJnZXQgKSwgbnVsbCwgInVpLXN0YXRlLWhvdmVyIiApOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIG1vdXNlbGVhdmU6IGZ1bmN0aW9uKCBldmVudCApIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVDbGFzcyggJCggZXZlbnQuY3VycmVudFRhcmdldCApLCBudWxsLCAidWktc3RhdGUtaG92ZXIiICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gKTsKICAgICAgICB9LAoKICAgICAgICBfZm9jdXNhYmxlOiBmdW5jdGlvbiggZWxlbWVudCApIHsKICAgICAgICAgICAgdGhpcy5mb2N1c2FibGUgPSB0aGlzLmZvY3VzYWJsZS5hZGQoIGVsZW1lbnQgKTsKICAgICAgICAgICAgdGhpcy5fb24oIGVsZW1lbnQsIHsKICAgICAgICAgICAgICAgIGZvY3VzaW46IGZ1bmN0aW9uKCBldmVudCApIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9hZGRDbGFzcyggJCggZXZlbnQuY3VycmVudFRhcmdldCApLCBudWxsLCAidWktc3RhdGUtZm9jdXMiICk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZm9jdXNvdXQ6IGZ1bmN0aW9uKCBldmVudCApIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVDbGFzcyggJCggZXZlbnQuY3VycmVudFRhcmdldCApLCBudWxsLCAidWktc3RhdGUtZm9jdXMiICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gKTsKICAgICAgICB9LAoKICAgICAgICBfdHJpZ2dlcjogZnVuY3Rpb24oIHR5cGUsIGV2ZW50LCBkYXRhICkgewogICAgICAgICAgICB2YXIgcHJvcCwgb3JpZzsKICAgICAgICAgICAgdmFyIGNhbGxiYWNrID0gdGhpcy5vcHRpb25zWyB0eXBlIF07CgogICAgICAgICAgICBkYXRhID0gZGF0YSB8fCB7fTsKICAgICAgICAgICAgZXZlbnQgPSAkLkV2ZW50KCBldmVudCApOwogICAgICAgICAgICBldmVudC50eXBlID0gKCB0eXBlID09PSB0aGlzLndpZGdldEV2ZW50UHJlZml4ID8KICAgICAgICAgICAgICAgIHR5cGUgOgogICAgICAgICAgICAgICAgdGhpcy53aWRnZXRFdmVudFByZWZpeCArIHR5cGUgKS50b0xvd2VyQ2FzZSgpOwoKICAgICAgICAgICAgLy8gVGhlIG9yaWdpbmFsIGV2ZW50IG1heSBjb21lIGZyb20gYW55IGVsZW1lbnQKICAgICAgICAgICAgLy8gc28gd2UgbmVlZCB0byByZXNldCB0aGUgdGFyZ2V0IG9uIHRoZSBuZXcgZXZlbnQKICAgICAgICAgICAgZXZlbnQudGFyZ2V0ID0gdGhpcy5lbGVtZW50WyAwIF07CgogICAgICAgICAgICAvLyBDb3B5IG9yaWdpbmFsIGV2ZW50IHByb3BlcnRpZXMgb3ZlciB0byB0aGUgbmV3IGV2ZW50CiAgICAgICAgICAgIG9yaWcgPSBldmVudC5vcmlnaW5hbEV2ZW50OwogICAgICAgICAgICBpZiAoIG9yaWcgKSB7CiAgICAgICAgICAgICAgICBmb3IgKCBwcm9wIGluIG9yaWcgKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCAhKCBwcm9wIGluIGV2ZW50ICkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50WyBwcm9wIF0gPSBvcmlnWyBwcm9wIF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLmVsZW1lbnQudHJpZ2dlciggZXZlbnQsIGRhdGEgKTsKICAgICAgICAgICAgcmV0dXJuICEoIHR5cGVvZiBjYWxsYmFjayA9PT0gImZ1bmN0aW9uIiAmJgogICAgICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkoIHRoaXMuZWxlbWVudFsgMCBdLCBbIGV2ZW50IF0uY29uY2F0KCBkYXRhICkgKSA9PT0gZmFsc2UgfHwKICAgICAgICAgICAgICAgIGV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpICk7CiAgICAgICAgfQogICAgfTsKCiAgICAkLmVhY2goIHsgc2hvdzogImZhZGVJbiIsIGhpZGU6ICJmYWRlT3V0IiB9LCBmdW5jdGlvbiggbWV0aG9kLCBkZWZhdWx0RWZmZWN0ICkgewogICAgICAgICQuV2lkZ2V0LnByb3RvdHlwZVsgIl8iICsgbWV0aG9kIF0gPSBmdW5jdGlvbiggZWxlbWVudCwgb3B0aW9ucywgY2FsbGJhY2sgKSB7CiAgICAgICAgICAgIGlmICggdHlwZW9mIG9wdGlvbnMgPT09ICJzdHJpbmciICkgewogICAgICAgICAgICAgICAgb3B0aW9ucyA9IHsgZWZmZWN0OiBvcHRpb25zIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBoYXNPcHRpb25zOwogICAgICAgICAgICB2YXIgZWZmZWN0TmFtZSA9ICFvcHRpb25zID8KICAgICAgICAgICAgICAgIG1ldGhvZCA6CiAgICAgICAgICAgICAgICBvcHRpb25zID09PSB0cnVlIHx8IHR5cGVvZiBvcHRpb25zID09PSAibnVtYmVyIiA/CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdEVmZmVjdCA6CiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5lZmZlY3QgfHwgZGVmYXVsdEVmZmVjdDsKCiAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogICAgICAgICAgICBpZiAoIHR5cGVvZiBvcHRpb25zID09PSAibnVtYmVyIiApIHsKICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IGR1cmF0aW9uOiBvcHRpb25zIH07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoIG9wdGlvbnMgPT09IHRydWUgKSB7CiAgICAgICAgICAgICAgICBvcHRpb25zID0ge307CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGhhc09wdGlvbnMgPSAhJC5pc0VtcHR5T2JqZWN0KCBvcHRpb25zICk7CiAgICAgICAgICAgIG9wdGlvbnMuY29tcGxldGUgPSBjYWxsYmFjazsKCiAgICAgICAgICAgIGlmICggb3B0aW9ucy5kZWxheSApIHsKICAgICAgICAgICAgICAgIGVsZW1lbnQuZGVsYXkoIG9wdGlvbnMuZGVsYXkgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCBoYXNPcHRpb25zICYmICQuZWZmZWN0cyAmJiAkLmVmZmVjdHMuZWZmZWN0WyBlZmZlY3ROYW1lIF0gKSB7CiAgICAgICAgICAgICAgICBlbGVtZW50WyBtZXRob2QgXSggb3B0aW9ucyApOwogICAgICAgICAgICB9IGVsc2UgaWYgKCBlZmZlY3ROYW1lICE9PSBtZXRob2QgJiYgZWxlbWVudFsgZWZmZWN0TmFtZSBdICkgewogICAgICAgICAgICAgICAgZWxlbWVudFsgZWZmZWN0TmFtZSBdKCBvcHRpb25zLmR1cmF0aW9uLCBvcHRpb25zLmVhc2luZywgY2FsbGJhY2sgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGVsZW1lbnQucXVldWUoIGZ1bmN0aW9uKCBuZXh0ICkgewogICAgICAgICAgICAgICAgICAgICQoIHRoaXMgKVsgbWV0aG9kIF0oKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIGNhbGxiYWNrICkgewogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKCBlbGVtZW50WyAwIF0gKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbmV4dCgpOwogICAgICAgICAgICAgICAgfSApOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIH0gKTsKCiAgICB2YXIgd2lkZ2V0ID0gJC53aWRnZXQ7Cn0pKTsKIWZ1bmN0aW9uKG4scil7Im9iamVjdCI9PXR5cGVvZiBleHBvcnRzJiYidW5kZWZpbmVkIiE9dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz1yKCk6ImZ1bmN0aW9uIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUoInVuZGVyc2NvcmUiLHIpOihuPSJ1bmRlZmluZWQiIT10eXBlb2YgZ2xvYmFsVGhpcz9nbG9iYWxUaGlzOm58fHNlbGYsZnVuY3Rpb24oKXt2YXIgdD1uLl8sZT1uLl89cigpO2Uubm9Db25mbGljdD1mdW5jdGlvbigpe3JldHVybiBuLl89dCxlfX0oKSl9KHRoaXMsKGZ1bmN0aW9uKCl7Ci8vICAgICBVbmRlcnNjb3JlLmpzIDEuMTMuNgovLyAgICAgaHR0cHM6Ly91bmRlcnNjb3JlanMub3JnCi8vICAgICAoYykgMjAwOS0yMDIyIEplcmVteSBBc2hrZW5hcywgSnVsaWFuIEdvbmdncmlqcCwgYW5kIERvY3VtZW50Q2xvdWQgYW5kIEludmVzdGlnYXRpdmUgUmVwb3J0ZXJzICYgRWRpdG9ycwovLyAgICAgVW5kZXJzY29yZSBtYXkgYmUgZnJlZWx5IGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS4KdmFyIG49IjEuMTMuNiIscj0ib2JqZWN0Ij09dHlwZW9mIHNlbGYmJnNlbGYuc2VsZj09PXNlbGYmJnNlbGZ8fCJvYmplY3QiPT10eXBlb2YgZ2xvYmFsJiZnbG9iYWwuZ2xvYmFsPT09Z2xvYmFsJiZnbG9iYWx8fEZ1bmN0aW9uKCJyZXR1cm4gdGhpcyIpKCl8fHt9LHQ9QXJyYXkucHJvdG90eXBlLGU9T2JqZWN0LnByb3RvdHlwZSx1PSJ1bmRlZmluZWQiIT10eXBlb2YgU3ltYm9sP1N5bWJvbC5wcm90b3R5cGU6bnVsbCxvPXQucHVzaCxpPXQuc2xpY2UsYT1lLnRvU3RyaW5nLGY9ZS5oYXNPd25Qcm9wZXJ0eSxjPSJ1bmRlZmluZWQiIT10eXBlb2YgQXJyYXlCdWZmZXIsbD0idW5kZWZpbmVkIiE9dHlwZW9mIERhdGFWaWV3LHM9QXJyYXkuaXNBcnJheSxwPU9iamVjdC5rZXlzLHY9T2JqZWN0LmNyZWF0ZSxoPWMmJkFycmF5QnVmZmVyLmlzVmlldyx5PWlzTmFOLGQ9aXNGaW5pdGUsZz0he3RvU3RyaW5nOm51bGx9LnByb3BlcnR5SXNFbnVtZXJhYmxlKCJ0b1N0cmluZyIpLGI9WyJ2YWx1ZU9mIiwiaXNQcm90b3R5cGVPZiIsInRvU3RyaW5nIiwicHJvcGVydHlJc0VudW1lcmFibGUiLCJoYXNPd25Qcm9wZXJ0eSIsInRvTG9jYWxlU3RyaW5nIl0sbT1NYXRoLnBvdygyLDUzKS0xO2Z1bmN0aW9uIGoobixyKXtyZXR1cm4gcj1udWxsPT1yP24ubGVuZ3RoLTE6K3IsZnVuY3Rpb24oKXtmb3IodmFyIHQ9TWF0aC5tYXgoYXJndW1lbnRzLmxlbmd0aC1yLDApLGU9QXJyYXkodCksdT0wO3U8dDt1KyspZVt1XT1hcmd1bWVudHNbdStyXTtzd2l0Y2gocil7Y2FzZSAwOnJldHVybiBuLmNhbGwodGhpcyxlKTtjYXNlIDE6cmV0dXJuIG4uY2FsbCh0aGlzLGFyZ3VtZW50c1swXSxlKTtjYXNlIDI6cmV0dXJuIG4uY2FsbCh0aGlzLGFyZ3VtZW50c1swXSxhcmd1bWVudHNbMV0sZSl9dmFyIG89QXJyYXkocisxKTtmb3IodT0wO3U8cjt1Kyspb1t1XT1hcmd1bWVudHNbdV07cmV0dXJuIG9bcl09ZSxuLmFwcGx5KHRoaXMsbyl9fWZ1bmN0aW9uIF8obil7dmFyIHI9dHlwZW9mIG47cmV0dXJuImZ1bmN0aW9uIj09PXJ8fCJvYmplY3QiPT09ciYmISFufWZ1bmN0aW9uIHcobil7cmV0dXJuIHZvaWQgMD09PW59ZnVuY3Rpb24gQShuKXtyZXR1cm4hMD09PW58fCExPT09bnx8IltvYmplY3QgQm9vbGVhbl0iPT09YS5jYWxsKG4pfWZ1bmN0aW9uIHgobil7dmFyIHI9IltvYmplY3QgIituKyJdIjtyZXR1cm4gZnVuY3Rpb24obil7cmV0dXJuIGEuY2FsbChuKT09PXJ9fXZhciBTPXgoIlN0cmluZyIpLE89eCgiTnVtYmVyIiksTT14KCJEYXRlIiksRT14KCJSZWdFeHAiKSxCPXgoIkVycm9yIiksTj14KCJTeW1ib2wiKSxJPXgoIkFycmF5QnVmZmVyIiksVD14KCJGdW5jdGlvbiIpLGs9ci5kb2N1bWVudCYmci5kb2N1bWVudC5jaGlsZE5vZGVzOyJmdW5jdGlvbiIhPXR5cGVvZi8uLyYmIm9iamVjdCIhPXR5cGVvZiBJbnQ4QXJyYXkmJiJmdW5jdGlvbiIhPXR5cGVvZiBrJiYoVD1mdW5jdGlvbihuKXtyZXR1cm4iZnVuY3Rpb24iPT10eXBlb2Ygbnx8ITF9KTt2YXIgRD1ULFI9eCgiT2JqZWN0IiksRj1sJiZSKG5ldyBEYXRhVmlldyhuZXcgQXJyYXlCdWZmZXIoOCkpKSxWPSJ1bmRlZmluZWQiIT10eXBlb2YgTWFwJiZSKG5ldyBNYXApLFA9eCgiRGF0YVZpZXciKTt2YXIgcT1GP2Z1bmN0aW9uKG4pe3JldHVybiBudWxsIT1uJiZEKG4uZ2V0SW50OCkmJkkobi5idWZmZXIpfTpQLFU9c3x8eCgiQXJyYXkiKTtmdW5jdGlvbiBXKG4scil7cmV0dXJuIG51bGwhPW4mJmYuY2FsbChuLHIpfXZhciB6PXgoIkFyZ3VtZW50cyIpOyFmdW5jdGlvbigpe3ooYXJndW1lbnRzKXx8KHo9ZnVuY3Rpb24obil7cmV0dXJuIFcobiwiY2FsbGVlIil9KX0oKTt2YXIgTD16O2Z1bmN0aW9uICQobil7cmV0dXJuIE8obikmJnkobil9ZnVuY3Rpb24gQyhuKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gbn19ZnVuY3Rpb24gSyhuKXtyZXR1cm4gZnVuY3Rpb24ocil7dmFyIHQ9bihyKTtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQmJnQ+PTAmJnQ8PW19fWZ1bmN0aW9uIEoobil7cmV0dXJuIGZ1bmN0aW9uKHIpe3JldHVybiBudWxsPT1yP3ZvaWQgMDpyW25dfX12YXIgRz1KKCJieXRlTGVuZ3RoIiksSD1LKEcpLFE9L1xbb2JqZWN0ICgoSXxVaSludCg4fDE2fDMyKXxGbG9hdCgzMnw2NCl8VWludDhDbGFtcGVkfEJpZyhJfFVpKW50NjQpQXJyYXlcXS87dmFyIFg9Yz9mdW5jdGlvbihuKXtyZXR1cm4gaD9oKG4pJiYhcShuKTpIKG4pJiZRLnRlc3QoYS5jYWxsKG4pKX06QyghMSksWT1KKCJsZW5ndGgiKTtmdW5jdGlvbiBaKG4scil7cj1mdW5jdGlvbihuKXtmb3IodmFyIHI9e30sdD1uLmxlbmd0aCxlPTA7ZTx0OysrZSlyW25bZV1dPSEwO3JldHVybntjb250YWluczpmdW5jdGlvbihuKXtyZXR1cm4hMD09PXJbbl19LHB1c2g6ZnVuY3Rpb24odCl7cmV0dXJuIHJbdF09ITAsbi5wdXNoKHQpfX19KHIpO3ZhciB0PWIubGVuZ3RoLHU9bi5jb25zdHJ1Y3RvcixvPUQodSkmJnUucHJvdG90eXBlfHxlLGk9ImNvbnN0cnVjdG9yIjtmb3IoVyhuLGkpJiYhci5jb250YWlucyhpKSYmci5wdXNoKGkpO3QtLTspKGk9Ylt0XSlpbiBuJiZuW2ldIT09b1tpXSYmIXIuY29udGFpbnMoaSkmJnIucHVzaChpKX1mdW5jdGlvbiBubihuKXtpZighXyhuKSlyZXR1cm5bXTtpZihwKXJldHVybiBwKG4pO3ZhciByPVtdO2Zvcih2YXIgdCBpbiBuKVcobix0KSYmci5wdXNoKHQpO3JldHVybiBnJiZaKG4scikscn1mdW5jdGlvbiBybihuLHIpe3ZhciB0PW5uKHIpLGU9dC5sZW5ndGg7aWYobnVsbD09bilyZXR1cm4hZTtmb3IodmFyIHU9T2JqZWN0KG4pLG89MDtvPGU7bysrKXt2YXIgaT10W29dO2lmKHJbaV0hPT11W2ldfHwhKGkgaW4gdSkpcmV0dXJuITF9cmV0dXJuITB9ZnVuY3Rpb24gdG4obil7cmV0dXJuIG4gaW5zdGFuY2VvZiB0bj9uOnRoaXMgaW5zdGFuY2VvZiB0bj92b2lkKHRoaXMuX3dyYXBwZWQ9bik6bmV3IHRuKG4pfWZ1bmN0aW9uIGVuKG4pe3JldHVybiBuZXcgVWludDhBcnJheShuLmJ1ZmZlcnx8bixuLmJ5dGVPZmZzZXR8fDAsRyhuKSl9dG4uVkVSU0lPTj1uLHRuLnByb3RvdHlwZS52YWx1ZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLl93cmFwcGVkfSx0bi5wcm90b3R5cGUudmFsdWVPZj10bi5wcm90b3R5cGUudG9KU09OPXRuLnByb3RvdHlwZS52YWx1ZSx0bi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gU3RyaW5nKHRoaXMuX3dyYXBwZWQpfTt2YXIgdW49IltvYmplY3QgRGF0YVZpZXddIjtmdW5jdGlvbiBvbihuLHIsdCxlKXtpZihuPT09cilyZXR1cm4gMCE9PW58fDEvbj09MS9yO2lmKG51bGw9PW58fG51bGw9PXIpcmV0dXJuITE7aWYobiE9bilyZXR1cm4gciE9cjt2YXIgbz10eXBlb2YgbjtyZXR1cm4oImZ1bmN0aW9uIj09PW98fCJvYmplY3QiPT09b3x8Im9iamVjdCI9PXR5cGVvZiByKSYmZnVuY3Rpb24gbihyLHQsZSxvKXtyIGluc3RhbmNlb2YgdG4mJihyPXIuX3dyYXBwZWQpO3QgaW5zdGFuY2VvZiB0biYmKHQ9dC5fd3JhcHBlZCk7dmFyIGk9YS5jYWxsKHIpO2lmKGkhPT1hLmNhbGwodCkpcmV0dXJuITE7aWYoRiYmIltvYmplY3QgT2JqZWN0XSI9PWkmJnEocikpe2lmKCFxKHQpKXJldHVybiExO2k9dW59c3dpdGNoKGkpe2Nhc2UiW29iamVjdCBSZWdFeHBdIjpjYXNlIltvYmplY3QgU3RyaW5nXSI6cmV0dXJuIiIrcj09IiIrdDtjYXNlIltvYmplY3QgTnVtYmVyXSI6cmV0dXJuK3IhPStyPyt0IT0rdDowPT0rcj8xLytyPT0xL3Q6K3I9PSt0O2Nhc2UiW29iamVjdCBEYXRlXSI6Y2FzZSJbb2JqZWN0IEJvb2xlYW5dIjpyZXR1cm4rcj09K3Q7Y2FzZSJbb2JqZWN0IFN5bWJvbF0iOnJldHVybiB1LnZhbHVlT2YuY2FsbChyKT09PXUudmFsdWVPZi5jYWxsKHQpO2Nhc2UiW29iamVjdCBBcnJheUJ1ZmZlcl0iOmNhc2UgdW46cmV0dXJuIG4oZW4ociksZW4odCksZSxvKX12YXIgZj0iW29iamVjdCBBcnJheV0iPT09aTtpZighZiYmWChyKSl7aWYoRyhyKSE9PUcodCkpcmV0dXJuITE7aWYoci5idWZmZXI9PT10LmJ1ZmZlciYmci5ieXRlT2Zmc2V0PT09dC5ieXRlT2Zmc2V0KXJldHVybiEwO2Y9ITB9aWYoIWYpe2lmKCJvYmplY3QiIT10eXBlb2Ygcnx8Im9iamVjdCIhPXR5cGVvZiB0KXJldHVybiExO3ZhciBjPXIuY29uc3RydWN0b3IsbD10LmNvbnN0cnVjdG9yO2lmKGMhPT1sJiYhKEQoYykmJmMgaW5zdGFuY2VvZiBjJiZEKGwpJiZsIGluc3RhbmNlb2YgbCkmJiJjb25zdHJ1Y3RvciJpbiByJiYiY29uc3RydWN0b3IiaW4gdClyZXR1cm4hMX1vPW98fFtdO3ZhciBzPShlPWV8fFtdKS5sZW5ndGg7Zm9yKDtzLS07KWlmKGVbc109PT1yKXJldHVybiBvW3NdPT09dDtpZihlLnB1c2gociksby5wdXNoKHQpLGYpe2lmKChzPXIubGVuZ3RoKSE9PXQubGVuZ3RoKXJldHVybiExO2Zvcig7cy0tOylpZighb24ocltzXSx0W3NdLGUsbykpcmV0dXJuITF9ZWxzZXt2YXIgcCx2PW5uKHIpO2lmKHM9di5sZW5ndGgsbm4odCkubGVuZ3RoIT09cylyZXR1cm4hMTtmb3IoO3MtLTspaWYocD12W3NdLCFXKHQscCl8fCFvbihyW3BdLHRbcF0sZSxvKSlyZXR1cm4hMX1yZXR1cm4gZS5wb3AoKSxvLnBvcCgpLCEwfShuLHIsdCxlKX1mdW5jdGlvbiBhbihuKXtpZighXyhuKSlyZXR1cm5bXTt2YXIgcj1bXTtmb3IodmFyIHQgaW4gbilyLnB1c2godCk7cmV0dXJuIGcmJloobixyKSxyfWZ1bmN0aW9uIGZuKG4pe3ZhciByPVkobik7cmV0dXJuIGZ1bmN0aW9uKHQpe2lmKG51bGw9PXQpcmV0dXJuITE7dmFyIGU9YW4odCk7aWYoWShlKSlyZXR1cm4hMTtmb3IodmFyIHU9MDt1PHI7dSsrKWlmKCFEKHRbblt1XV0pKXJldHVybiExO3JldHVybiBuIT09aG58fCFEKHRbY25dKX19dmFyIGNuPSJmb3JFYWNoIixsbj0iaGFzIixzbj1bImNsZWFyIiwiZGVsZXRlIl0scG49WyJnZXQiLGxuLCJzZXQiXSx2bj1zbi5jb25jYXQoY24scG4pLGhuPXNuLmNvbmNhdChwbikseW49WyJhZGQiXS5jb25jYXQoc24sY24sbG4pLGRuPVY/Zm4odm4pOngoIk1hcCIpLGduPVY/Zm4oaG4pOngoIldlYWtNYXAiKSxibj1WP2ZuKHluKTp4KCJTZXQiKSxtbj14KCJXZWFrU2V0Iik7ZnVuY3Rpb24gam4obil7Zm9yKHZhciByPW5uKG4pLHQ9ci5sZW5ndGgsZT1BcnJheSh0KSx1PTA7dTx0O3UrKyllW3VdPW5bclt1XV07cmV0dXJuIGV9ZnVuY3Rpb24gX24obil7Zm9yKHZhciByPXt9LHQ9bm4obiksZT0wLHU9dC5sZW5ndGg7ZTx1O2UrKylyW25bdFtlXV1dPXRbZV07cmV0dXJuIHJ9ZnVuY3Rpb24gd24obil7dmFyIHI9W107Zm9yKHZhciB0IGluIG4pRChuW3RdKSYmci5wdXNoKHQpO3JldHVybiByLnNvcnQoKX1mdW5jdGlvbiBBbihuLHIpe3JldHVybiBmdW5jdGlvbih0KXt2YXIgZT1hcmd1bWVudHMubGVuZ3RoO2lmKHImJih0PU9iamVjdCh0KSksZTwyfHxudWxsPT10KXJldHVybiB0O2Zvcih2YXIgdT0xO3U8ZTt1KyspZm9yKHZhciBvPWFyZ3VtZW50c1t1XSxpPW4obyksYT1pLmxlbmd0aCxmPTA7ZjxhO2YrKyl7dmFyIGM9aVtmXTtyJiZ2b2lkIDAhPT10W2NdfHwodFtjXT1vW2NdKX1yZXR1cm4gdH19dmFyIHhuPUFuKGFuKSxTbj1BbihubiksT249QW4oYW4sITApO2Z1bmN0aW9uIE1uKG4pe2lmKCFfKG4pKXJldHVybnt9O2lmKHYpcmV0dXJuIHYobik7dmFyIHI9ZnVuY3Rpb24oKXt9O3IucHJvdG90eXBlPW47dmFyIHQ9bmV3IHI7cmV0dXJuIHIucHJvdG90eXBlPW51bGwsdH1mdW5jdGlvbiBFbihuKXtyZXR1cm4gVShuKT9uOltuXX1mdW5jdGlvbiBCbihuKXtyZXR1cm4gdG4udG9QYXRoKG4pfWZ1bmN0aW9uIE5uKG4scil7Zm9yKHZhciB0PXIubGVuZ3RoLGU9MDtlPHQ7ZSsrKXtpZihudWxsPT1uKXJldHVybjtuPW5bcltlXV19cmV0dXJuIHQ/bjp2b2lkIDB9ZnVuY3Rpb24gSW4obixyLHQpe3ZhciBlPU5uKG4sQm4ocikpO3JldHVybiB3KGUpP3Q6ZX1mdW5jdGlvbiBUbihuKXtyZXR1cm4gbn1mdW5jdGlvbiBrbihuKXtyZXR1cm4gbj1Tbih7fSxuKSxmdW5jdGlvbihyKXtyZXR1cm4gcm4ocixuKX19ZnVuY3Rpb24gRG4obil7cmV0dXJuIG49Qm4obiksZnVuY3Rpb24ocil7cmV0dXJuIE5uKHIsbil9fWZ1bmN0aW9uIFJuKG4scix0KXtpZih2b2lkIDA9PT1yKXJldHVybiBuO3N3aXRjaChudWxsPT10PzM6dCl7Y2FzZSAxOnJldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gbi5jYWxsKHIsdCl9O2Nhc2UgMzpyZXR1cm4gZnVuY3Rpb24odCxlLHUpe3JldHVybiBuLmNhbGwocix0LGUsdSl9O2Nhc2UgNDpyZXR1cm4gZnVuY3Rpb24odCxlLHUsbyl7cmV0dXJuIG4uY2FsbChyLHQsZSx1LG8pfX1yZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gbi5hcHBseShyLGFyZ3VtZW50cyl9fWZ1bmN0aW9uIEZuKG4scix0KXtyZXR1cm4gbnVsbD09bj9UbjpEKG4pP1JuKG4scix0KTpfKG4pJiYhVShuKT9rbihuKTpEbihuKX1mdW5jdGlvbiBWbihuLHIpe3JldHVybiBGbihuLHIsMS8wKX1mdW5jdGlvbiBQbihuLHIsdCl7cmV0dXJuIHRuLml0ZXJhdGVlIT09Vm4/dG4uaXRlcmF0ZWUobixyKTpGbihuLHIsdCl9ZnVuY3Rpb24gcW4oKXt9ZnVuY3Rpb24gVW4obixyKXtyZXR1cm4gbnVsbD09ciYmKHI9bixuPTApLG4rTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpKihyLW4rMSkpfXRuLnRvUGF0aD1Fbix0bi5pdGVyYXRlZT1Wbjt2YXIgV249RGF0ZS5ub3d8fGZ1bmN0aW9uKCl7cmV0dXJuKG5ldyBEYXRlKS5nZXRUaW1lKCl9O2Z1bmN0aW9uIHpuKG4pe3ZhciByPWZ1bmN0aW9uKHIpe3JldHVybiBuW3JdfSx0PSIoPzoiK25uKG4pLmpvaW4oInwiKSsiKSIsZT1SZWdFeHAodCksdT1SZWdFeHAodCwiZyIpO3JldHVybiBmdW5jdGlvbihuKXtyZXR1cm4gbj1udWxsPT1uPyIiOiIiK24sZS50ZXN0KG4pP24ucmVwbGFjZSh1LHIpOm59fXZhciBMbj17IiYiOiImYW1wOyIsIjwiOiImbHQ7IiwiPiI6IiZndDsiLCciJzoiJnF1b3Q7IiwiJyI6IiYjeDI3OyIsImAiOiImI3g2MDsifSwkbj16bihMbiksQ249em4oX24oTG4pKSxLbj10bi50ZW1wbGF0ZVNldHRpbmdzPXtldmFsdWF0ZTovPCUoW1xzXFNdKz8pJT4vZyxpbnRlcnBvbGF0ZTovPCU9KFtcc1xTXSs/KSU+L2csZXNjYXBlOi88JS0oW1xzXFNdKz8pJT4vZ30sSm49LyguKV4vLEduPXsiJyI6IiciLCJcXCI6IlxcIiwiXHIiOiJyIiwiXG4iOiJuIiwiXHUyMDI4IjoidTIwMjgiLCJcdTIwMjkiOiJ1MjAyOSJ9LEhuPS9cXHwnfFxyfFxufFx1MjAyOHxcdTIwMjkvZztmdW5jdGlvbiBRbihuKXtyZXR1cm4iXFwiK0duW25dfXZhciBYbj0vXlxzKihcd3xcJCkrXHMqJC87dmFyIFluPTA7ZnVuY3Rpb24gWm4obixyLHQsZSx1KXtpZighKGUgaW5zdGFuY2VvZiByKSlyZXR1cm4gbi5hcHBseSh0LHUpO3ZhciBvPU1uKG4ucHJvdG90eXBlKSxpPW4uYXBwbHkobyx1KTtyZXR1cm4gXyhpKT9pOm99dmFyIG5yPWooKGZ1bmN0aW9uKG4scil7dmFyIHQ9bnIucGxhY2Vob2xkZXIsZT1mdW5jdGlvbigpe2Zvcih2YXIgdT0wLG89ci5sZW5ndGgsaT1BcnJheShvKSxhPTA7YTxvO2ErKylpW2FdPXJbYV09PT10P2FyZ3VtZW50c1t1KytdOnJbYV07Zm9yKDt1PGFyZ3VtZW50cy5sZW5ndGg7KWkucHVzaChhcmd1bWVudHNbdSsrXSk7cmV0dXJuIFpuKG4sZSx0aGlzLHRoaXMsaSl9O3JldHVybiBlfSkpO25yLnBsYWNlaG9sZGVyPXRuO3ZhciBycj1qKChmdW5jdGlvbihuLHIsdCl7aWYoIUQobikpdGhyb3cgbmV3IFR5cGVFcnJvcigiQmluZCBtdXN0IGJlIGNhbGxlZCBvbiBhIGZ1bmN0aW9uIik7dmFyIGU9aigoZnVuY3Rpb24odSl7cmV0dXJuIFpuKG4sZSxyLHRoaXMsdC5jb25jYXQodSkpfSkpO3JldHVybiBlfSkpLHRyPUsoWSk7ZnVuY3Rpb24gZXIobixyLHQsZSl7aWYoZT1lfHxbXSxyfHwwPT09cil7aWYocjw9MClyZXR1cm4gZS5jb25jYXQobil9ZWxzZSByPTEvMDtmb3IodmFyIHU9ZS5sZW5ndGgsbz0wLGk9WShuKTtvPGk7bysrKXt2YXIgYT1uW29dO2lmKHRyKGEpJiYoVShhKXx8TChhKSkpaWYocj4xKWVyKGEsci0xLHQsZSksdT1lLmxlbmd0aDtlbHNlIGZvcih2YXIgZj0wLGM9YS5sZW5ndGg7ZjxjOyllW3UrK109YVtmKytdO2Vsc2UgdHx8KGVbdSsrXT1hKX1yZXR1cm4gZX12YXIgdXI9aigoZnVuY3Rpb24obixyKXt2YXIgdD0ocj1lcihyLCExLCExKSkubGVuZ3RoO2lmKHQ8MSl0aHJvdyBuZXcgRXJyb3IoImJpbmRBbGwgbXVzdCBiZSBwYXNzZWQgZnVuY3Rpb24gbmFtZXMiKTtmb3IoO3QtLTspe3ZhciBlPXJbdF07bltlXT1ycihuW2VdLG4pfXJldHVybiBufSkpO3ZhciBvcj1qKChmdW5jdGlvbihuLHIsdCl7cmV0dXJuIHNldFRpbWVvdXQoKGZ1bmN0aW9uKCl7cmV0dXJuIG4uYXBwbHkobnVsbCx0KX0pLHIpfSkpLGlyPW5yKG9yLHRuLDEpO2Z1bmN0aW9uIGFyKG4pe3JldHVybiBmdW5jdGlvbigpe3JldHVybiFuLmFwcGx5KHRoaXMsYXJndW1lbnRzKX19ZnVuY3Rpb24gZnIobixyKXt2YXIgdDtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4tLW4+MCYmKHQ9ci5hcHBseSh0aGlzLGFyZ3VtZW50cykpLG48PTEmJihyPW51bGwpLHR9fXZhciBjcj1ucihmciwyKTtmdW5jdGlvbiBscihuLHIsdCl7cj1QbihyLHQpO2Zvcih2YXIgZSx1PW5uKG4pLG89MCxpPXUubGVuZ3RoO288aTtvKyspaWYocihuW2U9dVtvXV0sZSxuKSlyZXR1cm4gZX1mdW5jdGlvbiBzcihuKXtyZXR1cm4gZnVuY3Rpb24ocix0LGUpe3Q9UG4odCxlKTtmb3IodmFyIHU9WShyKSxvPW4+MD8wOnUtMTtvPj0wJiZvPHU7bys9bilpZih0KHJbb10sbyxyKSlyZXR1cm4gbztyZXR1cm4tMX19dmFyIHByPXNyKDEpLHZyPXNyKC0xKTtmdW5jdGlvbiBocihuLHIsdCxlKXtmb3IodmFyIHU9KHQ9UG4odCxlLDEpKShyKSxvPTAsaT1ZKG4pO288aTspe3ZhciBhPU1hdGguZmxvb3IoKG8raSkvMik7dChuW2FdKTx1P289YSsxOmk9YX1yZXR1cm4gb31mdW5jdGlvbiB5cihuLHIsdCl7cmV0dXJuIGZ1bmN0aW9uKGUsdSxvKXt2YXIgYT0wLGY9WShlKTtpZigibnVtYmVyIj09dHlwZW9mIG8pbj4wP2E9bz49MD9vOk1hdGgubWF4KG8rZixhKTpmPW8+PTA/TWF0aC5taW4obysxLGYpOm8rZisxO2Vsc2UgaWYodCYmbyYmZilyZXR1cm4gZVtvPXQoZSx1KV09PT11P286LTE7aWYodSE9dSlyZXR1cm4obz1yKGkuY2FsbChlLGEsZiksJCkpPj0wP28rYTotMTtmb3Iobz1uPjA/YTpmLTE7bz49MCYmbzxmO28rPW4paWYoZVtvXT09PXUpcmV0dXJuIG87cmV0dXJuLTF9fXZhciBkcj15cigxLHByLGhyKSxncj15cigtMSx2cik7ZnVuY3Rpb24gYnIobixyLHQpe3ZhciBlPSh0cihuKT9wcjpscikobixyLHQpO2lmKHZvaWQgMCE9PWUmJi0xIT09ZSlyZXR1cm4gbltlXX1mdW5jdGlvbiBtcihuLHIsdCl7dmFyIGUsdTtpZihyPVJuKHIsdCksdHIobikpZm9yKGU9MCx1PW4ubGVuZ3RoO2U8dTtlKyspcihuW2VdLGUsbik7ZWxzZXt2YXIgbz1ubihuKTtmb3IoZT0wLHU9by5sZW5ndGg7ZTx1O2UrKylyKG5bb1tlXV0sb1tlXSxuKX1yZXR1cm4gbn1mdW5jdGlvbiBqcihuLHIsdCl7cj1QbihyLHQpO2Zvcih2YXIgZT0hdHIobikmJm5uKG4pLHU9KGV8fG4pLmxlbmd0aCxvPUFycmF5KHUpLGk9MDtpPHU7aSsrKXt2YXIgYT1lP2VbaV06aTtvW2ldPXIoblthXSxhLG4pfXJldHVybiBvfWZ1bmN0aW9uIF9yKG4pe3ZhciByPWZ1bmN0aW9uKHIsdCxlLHUpe3ZhciBvPSF0cihyKSYmbm4ociksaT0ob3x8cikubGVuZ3RoLGE9bj4wPzA6aS0xO2Zvcih1fHwoZT1yW28/b1thXTphXSxhKz1uKTthPj0wJiZhPGk7YSs9bil7dmFyIGY9bz9vW2FdOmE7ZT10KGUscltmXSxmLHIpfXJldHVybiBlfTtyZXR1cm4gZnVuY3Rpb24obix0LGUsdSl7dmFyIG89YXJndW1lbnRzLmxlbmd0aD49MztyZXR1cm4gcihuLFJuKHQsdSw0KSxlLG8pfX12YXIgd3I9X3IoMSksQXI9X3IoLTEpO2Z1bmN0aW9uIHhyKG4scix0KXt2YXIgZT1bXTtyZXR1cm4gcj1QbihyLHQpLG1yKG4sKGZ1bmN0aW9uKG4sdCx1KXtyKG4sdCx1KSYmZS5wdXNoKG4pfSkpLGV9ZnVuY3Rpb24gU3IobixyLHQpe3I9UG4ocix0KTtmb3IodmFyIGU9IXRyKG4pJiZubihuKSx1PShlfHxuKS5sZW5ndGgsbz0wO288dTtvKyspe3ZhciBpPWU/ZVtvXTpvO2lmKCFyKG5baV0saSxuKSlyZXR1cm4hMX1yZXR1cm4hMH1mdW5jdGlvbiBPcihuLHIsdCl7cj1QbihyLHQpO2Zvcih2YXIgZT0hdHIobikmJm5uKG4pLHU9KGV8fG4pLmxlbmd0aCxvPTA7bzx1O28rKyl7dmFyIGk9ZT9lW29dOm87aWYocihuW2ldLGksbikpcmV0dXJuITB9cmV0dXJuITF9ZnVuY3Rpb24gTXIobixyLHQsZSl7cmV0dXJuIHRyKG4pfHwobj1qbihuKSksKCJudW1iZXIiIT10eXBlb2YgdHx8ZSkmJih0PTApLGRyKG4scix0KT49MH12YXIgRXI9aigoZnVuY3Rpb24obixyLHQpe3ZhciBlLHU7cmV0dXJuIEQocik/dT1yOihyPUJuKHIpLGU9ci5zbGljZSgwLC0xKSxyPXJbci5sZW5ndGgtMV0pLGpyKG4sKGZ1bmN0aW9uKG4pe3ZhciBvPXU7aWYoIW8pe2lmKGUmJmUubGVuZ3RoJiYobj1ObihuLGUpKSxudWxsPT1uKXJldHVybjtvPW5bcl19cmV0dXJuIG51bGw9PW8/bzpvLmFwcGx5KG4sdCl9KSl9KSk7ZnVuY3Rpb24gQnIobixyKXtyZXR1cm4ganIobixEbihyKSl9ZnVuY3Rpb24gTnIobixyLHQpe3ZhciBlLHUsbz0tMS8wLGk9LTEvMDtpZihudWxsPT1yfHwibnVtYmVyIj09dHlwZW9mIHImJiJvYmplY3QiIT10eXBlb2YgblswXSYmbnVsbCE9bilmb3IodmFyIGE9MCxmPShuPXRyKG4pP246am4obikpLmxlbmd0aDthPGY7YSsrKW51bGwhPShlPW5bYV0pJiZlPm8mJihvPWUpO2Vsc2Ugcj1QbihyLHQpLG1yKG4sKGZ1bmN0aW9uKG4sdCxlKXsoKHU9cihuLHQsZSkpPml8fHU9PT0tMS8wJiZvPT09LTEvMCkmJihvPW4saT11KX0pKTtyZXR1cm4gb312YXIgSXI9L1teXHVkODAwLVx1ZGZmZl18W1x1ZDgwMC1cdWRiZmZdW1x1ZGMwMC1cdWRmZmZdfFtcdWQ4MDAtXHVkZmZmXS9nO2Z1bmN0aW9uIFRyKG4pe3JldHVybiBuP1Uobik/aS5jYWxsKG4pOlMobik/bi5tYXRjaChJcik6dHIobik/anIobixUbik6am4obik6W119ZnVuY3Rpb24ga3IobixyLHQpe2lmKG51bGw9PXJ8fHQpcmV0dXJuIHRyKG4pfHwobj1qbihuKSksbltVbihuLmxlbmd0aC0xKV07dmFyIGU9VHIobiksdT1ZKGUpO3I9TWF0aC5tYXgoTWF0aC5taW4ocix1KSwwKTtmb3IodmFyIG89dS0xLGk9MDtpPHI7aSsrKXt2YXIgYT1VbihpLG8pLGY9ZVtpXTtlW2ldPWVbYV0sZVthXT1mfXJldHVybiBlLnNsaWNlKDAscil9ZnVuY3Rpb24gRHIobixyKXtyZXR1cm4gZnVuY3Rpb24odCxlLHUpe3ZhciBvPXI/W1tdLFtdXTp7fTtyZXR1cm4gZT1QbihlLHUpLG1yKHQsKGZ1bmN0aW9uKHIsdSl7dmFyIGk9ZShyLHUsdCk7bihvLHIsaSl9KSksb319dmFyIFJyPURyKChmdW5jdGlvbihuLHIsdCl7VyhuLHQpP25bdF0ucHVzaChyKTpuW3RdPVtyXX0pKSxGcj1EcigoZnVuY3Rpb24obixyLHQpe25bdF09cn0pKSxWcj1EcigoZnVuY3Rpb24obixyLHQpe1cobix0KT9uW3RdKys6blt0XT0xfSkpLFByPURyKChmdW5jdGlvbihuLHIsdCl7blt0PzA6MV0ucHVzaChyKX0pLCEwKTtmdW5jdGlvbiBxcihuLHIsdCl7cmV0dXJuIHIgaW4gdH12YXIgVXI9aigoZnVuY3Rpb24obixyKXt2YXIgdD17fSxlPXJbMF07aWYobnVsbD09bilyZXR1cm4gdDtEKGUpPyhyLmxlbmd0aD4xJiYoZT1SbihlLHJbMV0pKSxyPWFuKG4pKTooZT1xcixyPWVyKHIsITEsITEpLG49T2JqZWN0KG4pKTtmb3IodmFyIHU9MCxvPXIubGVuZ3RoO3U8bzt1Kyspe3ZhciBpPXJbdV0sYT1uW2ldO2UoYSxpLG4pJiYodFtpXT1hKX1yZXR1cm4gdH0pKSxXcj1qKChmdW5jdGlvbihuLHIpe3ZhciB0LGU9clswXTtyZXR1cm4gRChlKT8oZT1hcihlKSxyLmxlbmd0aD4xJiYodD1yWzFdKSk6KHI9anIoZXIociwhMSwhMSksU3RyaW5nKSxlPWZ1bmN0aW9uKG4sdCl7cmV0dXJuIU1yKHIsdCl9KSxVcihuLGUsdCl9KSk7ZnVuY3Rpb24genIobixyLHQpe3JldHVybiBpLmNhbGwobiwwLE1hdGgubWF4KDAsbi5sZW5ndGgtKG51bGw9PXJ8fHQ/MTpyKSkpfWZ1bmN0aW9uIExyKG4scix0KXtyZXR1cm4gbnVsbD09bnx8bi5sZW5ndGg8MT9udWxsPT1yfHx0P3ZvaWQgMDpbXTpudWxsPT1yfHx0P25bMF06enIobixuLmxlbmd0aC1yKX1mdW5jdGlvbiAkcihuLHIsdCl7cmV0dXJuIGkuY2FsbChuLG51bGw9PXJ8fHQ/MTpyKX12YXIgQ3I9aigoZnVuY3Rpb24obixyKXtyZXR1cm4gcj1lcihyLCEwLCEwKSx4cihuLChmdW5jdGlvbihuKXtyZXR1cm4hTXIocixuKX0pKX0pKSxLcj1qKChmdW5jdGlvbihuLHIpe3JldHVybiBDcihuLHIpfSkpO2Z1bmN0aW9uIEpyKG4scix0LGUpe0Eocil8fChlPXQsdD1yLHI9ITEpLG51bGwhPXQmJih0PVBuKHQsZSkpO2Zvcih2YXIgdT1bXSxvPVtdLGk9MCxhPVkobik7aTxhO2krKyl7dmFyIGY9bltpXSxjPXQ/dChmLGksbik6ZjtyJiYhdD8oaSYmbz09PWN8fHUucHVzaChmKSxvPWMpOnQ/TXIobyxjKXx8KG8ucHVzaChjKSx1LnB1c2goZikpOk1yKHUsZil8fHUucHVzaChmKX1yZXR1cm4gdX12YXIgR3I9aigoZnVuY3Rpb24obil7cmV0dXJuIEpyKGVyKG4sITAsITApKX0pKTtmdW5jdGlvbiBIcihuKXtmb3IodmFyIHI9biYmTnIobixZKS5sZW5ndGh8fDAsdD1BcnJheShyKSxlPTA7ZTxyO2UrKyl0W2VdPUJyKG4sZSk7cmV0dXJuIHR9dmFyIFFyPWooSHIpO2Z1bmN0aW9uIFhyKG4scil7cmV0dXJuIG4uX2NoYWluP3RuKHIpLmNoYWluKCk6cn1mdW5jdGlvbiBZcihuKXtyZXR1cm4gbXIod24obiksKGZ1bmN0aW9uKHIpe3ZhciB0PXRuW3JdPW5bcl07dG4ucHJvdG90eXBlW3JdPWZ1bmN0aW9uKCl7dmFyIG49W3RoaXMuX3dyYXBwZWRdO3JldHVybiBvLmFwcGx5KG4sYXJndW1lbnRzKSxYcih0aGlzLHQuYXBwbHkodG4sbikpfX0pKSx0bn1tcihbInBvcCIsInB1c2giLCJyZXZlcnNlIiwic2hpZnQiLCJzb3J0Iiwic3BsaWNlIiwidW5zaGlmdCJdLChmdW5jdGlvbihuKXt2YXIgcj10W25dO3RuLnByb3RvdHlwZVtuXT1mdW5jdGlvbigpe3ZhciB0PXRoaXMuX3dyYXBwZWQ7cmV0dXJuIG51bGwhPXQmJihyLmFwcGx5KHQsYXJndW1lbnRzKSwic2hpZnQiIT09biYmInNwbGljZSIhPT1ufHwwIT09dC5sZW5ndGh8fGRlbGV0ZSB0WzBdKSxYcih0aGlzLHQpfX0pKSxtcihbImNvbmNhdCIsImpvaW4iLCJzbGljZSJdLChmdW5jdGlvbihuKXt2YXIgcj10W25dO3RuLnByb3RvdHlwZVtuXT1mdW5jdGlvbigpe3ZhciBuPXRoaXMuX3dyYXBwZWQ7cmV0dXJuIG51bGwhPW4mJihuPXIuYXBwbHkobixhcmd1bWVudHMpKSxYcih0aGlzLG4pfX0pKTt2YXIgWnI9WXIoe19fcHJvdG9fXzpudWxsLFZFUlNJT046bixyZXN0QXJndW1lbnRzOmosaXNPYmplY3Q6Xyxpc051bGw6ZnVuY3Rpb24obil7cmV0dXJuIG51bGw9PT1ufSxpc1VuZGVmaW5lZDp3LGlzQm9vbGVhbjpBLGlzRWxlbWVudDpmdW5jdGlvbihuKXtyZXR1cm4hKCFufHwxIT09bi5ub2RlVHlwZSl9LGlzU3RyaW5nOlMsaXNOdW1iZXI6Tyxpc0RhdGU6TSxpc1JlZ0V4cDpFLGlzRXJyb3I6Qixpc1N5bWJvbDpOLGlzQXJyYXlCdWZmZXI6SSxpc0RhdGFWaWV3OnEsaXNBcnJheTpVLGlzRnVuY3Rpb246RCxpc0FyZ3VtZW50czpMLGlzRmluaXRlOmZ1bmN0aW9uKG4pe3JldHVybiFOKG4pJiZkKG4pJiYhaXNOYU4ocGFyc2VGbG9hdChuKSl9LGlzTmFOOiQsaXNUeXBlZEFycmF5OlgsaXNFbXB0eTpmdW5jdGlvbihuKXtpZihudWxsPT1uKXJldHVybiEwO3ZhciByPVkobik7cmV0dXJuIm51bWJlciI9PXR5cGVvZiByJiYoVShuKXx8UyhuKXx8TChuKSk/MD09PXI6MD09PVkobm4obikpfSxpc01hdGNoOnJuLGlzRXF1YWw6ZnVuY3Rpb24obixyKXtyZXR1cm4gb24obixyKX0saXNNYXA6ZG4saXNXZWFrTWFwOmduLGlzU2V0OmJuLGlzV2Vha1NldDptbixrZXlzOm5uLGFsbEtleXM6YW4sdmFsdWVzOmpuLHBhaXJzOmZ1bmN0aW9uKG4pe2Zvcih2YXIgcj1ubihuKSx0PXIubGVuZ3RoLGU9QXJyYXkodCksdT0wO3U8dDt1KyspZVt1XT1bclt1XSxuW3JbdV1dXTtyZXR1cm4gZX0saW52ZXJ0Ol9uLGZ1bmN0aW9uczp3bixtZXRob2RzOnduLGV4dGVuZDp4bixleHRlbmRPd246U24sYXNzaWduOlNuLGRlZmF1bHRzOk9uLGNyZWF0ZTpmdW5jdGlvbihuLHIpe3ZhciB0PU1uKG4pO3JldHVybiByJiZTbih0LHIpLHR9LGNsb25lOmZ1bmN0aW9uKG4pe3JldHVybiBfKG4pP1Uobik/bi5zbGljZSgpOnhuKHt9LG4pOm59LHRhcDpmdW5jdGlvbihuLHIpe3JldHVybiByKG4pLG59LGdldDpJbixoYXM6ZnVuY3Rpb24obixyKXtmb3IodmFyIHQ9KHI9Qm4ocikpLmxlbmd0aCxlPTA7ZTx0O2UrKyl7dmFyIHU9cltlXTtpZighVyhuLHUpKXJldHVybiExO249blt1XX1yZXR1cm4hIXR9LG1hcE9iamVjdDpmdW5jdGlvbihuLHIsdCl7cj1QbihyLHQpO2Zvcih2YXIgZT1ubihuKSx1PWUubGVuZ3RoLG89e30saT0wO2k8dTtpKyspe3ZhciBhPWVbaV07b1thXT1yKG5bYV0sYSxuKX1yZXR1cm4gb30saWRlbnRpdHk6VG4sY29uc3RhbnQ6Qyxub29wOnFuLHRvUGF0aDpFbixwcm9wZXJ0eTpEbixwcm9wZXJ0eU9mOmZ1bmN0aW9uKG4pe3JldHVybiBudWxsPT1uP3FuOmZ1bmN0aW9uKHIpe3JldHVybiBJbihuLHIpfX0sbWF0Y2hlcjprbixtYXRjaGVzOmtuLHRpbWVzOmZ1bmN0aW9uKG4scix0KXt2YXIgZT1BcnJheShNYXRoLm1heCgwLG4pKTtyPVJuKHIsdCwxKTtmb3IodmFyIHU9MDt1PG47dSsrKWVbdV09cih1KTtyZXR1cm4gZX0scmFuZG9tOlVuLG5vdzpXbixlc2NhcGU6JG4sdW5lc2NhcGU6Q24sdGVtcGxhdGVTZXR0aW5nczpLbix0ZW1wbGF0ZTpmdW5jdGlvbihuLHIsdCl7IXImJnQmJihyPXQpLHI9T24oe30scix0bi50ZW1wbGF0ZVNldHRpbmdzKTt2YXIgZT1SZWdFeHAoWyhyLmVzY2FwZXx8Sm4pLnNvdXJjZSwoci5pbnRlcnBvbGF0ZXx8Sm4pLnNvdXJjZSwoci5ldmFsdWF0ZXx8Sm4pLnNvdXJjZV0uam9pbigifCIpKyJ8JCIsImciKSx1PTAsbz0iX19wKz0nIjtuLnJlcGxhY2UoZSwoZnVuY3Rpb24ocix0LGUsaSxhKXtyZXR1cm4gbys9bi5zbGljZSh1LGEpLnJlcGxhY2UoSG4sUW4pLHU9YStyLmxlbmd0aCx0P28rPSInK1xuKChfX3Q9KCIrdCsiKSk9PW51bGw/Jyc6Xy5lc2NhcGUoX190KSkrXG4nIjplP28rPSInK1xuKChfX3Q9KCIrZSsiKSk9PW51bGw/Jyc6X190KStcbiciOmkmJihvKz0iJztcbiIraSsiXG5fX3ArPSciKSxyfSkpLG8rPSInO1xuIjt2YXIgaSxhPXIudmFyaWFibGU7aWYoYSl7aWYoIVhuLnRlc3QoYSkpdGhyb3cgbmV3IEVycm9yKCJ2YXJpYWJsZSBpcyBub3QgYSBiYXJlIGlkZW50aWZpZXI6ICIrYSl9ZWxzZSBvPSJ3aXRoKG9ianx8e30pe1xuIitvKyJ9XG4iLGE9Im9iaiI7bz0idmFyIF9fdCxfX3A9JycsX19qPUFycmF5LnByb3RvdHlwZS5qb2luLCIrInByaW50PWZ1bmN0aW9uKCl7X19wKz1fX2ouY2FsbChhcmd1bWVudHMsJycpO307XG4iK28rInJldHVybiBfX3A7XG4iO3RyeXtpPW5ldyBGdW5jdGlvbihhLCJfIixvKX1jYXRjaChuKXt0aHJvdyBuLnNvdXJjZT1vLG59dmFyIGY9ZnVuY3Rpb24obil7cmV0dXJuIGkuY2FsbCh0aGlzLG4sdG4pfTtyZXR1cm4gZi5zb3VyY2U9ImZ1bmN0aW9uKCIrYSsiKXtcbiIrbysifSIsZn0scmVzdWx0OmZ1bmN0aW9uKG4scix0KXt2YXIgZT0ocj1CbihyKSkubGVuZ3RoO2lmKCFlKXJldHVybiBEKHQpP3QuY2FsbChuKTp0O2Zvcih2YXIgdT0wO3U8ZTt1Kyspe3ZhciBvPW51bGw9PW4/dm9pZCAwOm5bclt1XV07dm9pZCAwPT09byYmKG89dCx1PWUpLG49RChvKT9vLmNhbGwobik6b31yZXR1cm4gbn0sdW5pcXVlSWQ6ZnVuY3Rpb24obil7dmFyIHI9KytZbisiIjtyZXR1cm4gbj9uK3I6cn0sY2hhaW46ZnVuY3Rpb24obil7dmFyIHI9dG4obik7cmV0dXJuIHIuX2NoYWluPSEwLHJ9LGl0ZXJhdGVlOlZuLHBhcnRpYWw6bnIsYmluZDpycixiaW5kQWxsOnVyLG1lbW9pemU6ZnVuY3Rpb24obixyKXt2YXIgdD1mdW5jdGlvbihlKXt2YXIgdT10LmNhY2hlLG89IiIrKHI/ci5hcHBseSh0aGlzLGFyZ3VtZW50cyk6ZSk7cmV0dXJuIFcodSxvKXx8KHVbb109bi5hcHBseSh0aGlzLGFyZ3VtZW50cykpLHVbb119O3JldHVybiB0LmNhY2hlPXt9LHR9LGRlbGF5Om9yLGRlZmVyOmlyLHRocm90dGxlOmZ1bmN0aW9uKG4scix0KXt2YXIgZSx1LG8saSxhPTA7dHx8KHQ9e30pO3ZhciBmPWZ1bmN0aW9uKCl7YT0hMT09PXQubGVhZGluZz8wOlduKCksZT1udWxsLGk9bi5hcHBseSh1LG8pLGV8fCh1PW89bnVsbCl9LGM9ZnVuY3Rpb24oKXt2YXIgYz1XbigpO2F8fCExIT09dC5sZWFkaW5nfHwoYT1jKTt2YXIgbD1yLShjLWEpO3JldHVybiB1PXRoaXMsbz1hcmd1bWVudHMsbDw9MHx8bD5yPyhlJiYoY2xlYXJUaW1lb3V0KGUpLGU9bnVsbCksYT1jLGk9bi5hcHBseSh1LG8pLGV8fCh1PW89bnVsbCkpOmV8fCExPT09dC50cmFpbGluZ3x8KGU9c2V0VGltZW91dChmLGwpKSxpfTtyZXR1cm4gYy5jYW5jZWw9ZnVuY3Rpb24oKXtjbGVhclRpbWVvdXQoZSksYT0wLGU9dT1vPW51bGx9LGN9LGRlYm91bmNlOmZ1bmN0aW9uKG4scix0KXt2YXIgZSx1LG8saSxhLGY9ZnVuY3Rpb24oKXt2YXIgYz1XbigpLXU7cj5jP2U9c2V0VGltZW91dChmLHItYyk6KGU9bnVsbCx0fHwoaT1uLmFwcGx5KGEsbykpLGV8fChvPWE9bnVsbCkpfSxjPWooKGZ1bmN0aW9uKGMpe3JldHVybiBhPXRoaXMsbz1jLHU9V24oKSxlfHwoZT1zZXRUaW1lb3V0KGYsciksdCYmKGk9bi5hcHBseShhLG8pKSksaX0pKTtyZXR1cm4gYy5jYW5jZWw9ZnVuY3Rpb24oKXtjbGVhclRpbWVvdXQoZSksZT1vPWE9bnVsbH0sY30sd3JhcDpmdW5jdGlvbihuLHIpe3JldHVybiBucihyLG4pfSxuZWdhdGU6YXIsY29tcG9zZTpmdW5jdGlvbigpe3ZhciBuPWFyZ3VtZW50cyxyPW4ubGVuZ3RoLTE7cmV0dXJuIGZ1bmN0aW9uKCl7Zm9yKHZhciB0PXIsZT1uW3JdLmFwcGx5KHRoaXMsYXJndW1lbnRzKTt0LS07KWU9blt0XS5jYWxsKHRoaXMsZSk7cmV0dXJuIGV9fSxhZnRlcjpmdW5jdGlvbihuLHIpe3JldHVybiBmdW5jdGlvbigpe2lmKC0tbjwxKXJldHVybiByLmFwcGx5KHRoaXMsYXJndW1lbnRzKX19LGJlZm9yZTpmcixvbmNlOmNyLGZpbmRLZXk6bHIsZmluZEluZGV4OnByLGZpbmRMYXN0SW5kZXg6dnIsc29ydGVkSW5kZXg6aHIsaW5kZXhPZjpkcixsYXN0SW5kZXhPZjpncixmaW5kOmJyLGRldGVjdDpicixmaW5kV2hlcmU6ZnVuY3Rpb24obixyKXtyZXR1cm4gYnIobixrbihyKSl9LGVhY2g6bXIsZm9yRWFjaDptcixtYXA6anIsY29sbGVjdDpqcixyZWR1Y2U6d3IsZm9sZGw6d3IsaW5qZWN0OndyLHJlZHVjZVJpZ2h0OkFyLGZvbGRyOkFyLGZpbHRlcjp4cixzZWxlY3Q6eHIscmVqZWN0OmZ1bmN0aW9uKG4scix0KXtyZXR1cm4geHIobixhcihQbihyKSksdCl9LGV2ZXJ5OlNyLGFsbDpTcixzb21lOk9yLGFueTpPcixjb250YWluczpNcixpbmNsdWRlczpNcixpbmNsdWRlOk1yLGludm9rZTpFcixwbHVjazpCcix3aGVyZTpmdW5jdGlvbihuLHIpe3JldHVybiB4cihuLGtuKHIpKX0sbWF4Ok5yLG1pbjpmdW5jdGlvbihuLHIsdCl7dmFyIGUsdSxvPTEvMCxpPTEvMDtpZihudWxsPT1yfHwibnVtYmVyIj09dHlwZW9mIHImJiJvYmplY3QiIT10eXBlb2YgblswXSYmbnVsbCE9bilmb3IodmFyIGE9MCxmPShuPXRyKG4pP246am4obikpLmxlbmd0aDthPGY7YSsrKW51bGwhPShlPW5bYV0pJiZlPG8mJihvPWUpO2Vsc2Ugcj1QbihyLHQpLG1yKG4sKGZ1bmN0aW9uKG4sdCxlKXsoKHU9cihuLHQsZSkpPGl8fHU9PT0xLzAmJm89PT0xLzApJiYobz1uLGk9dSl9KSk7cmV0dXJuIG99LHNodWZmbGU6ZnVuY3Rpb24obil7cmV0dXJuIGtyKG4sMS8wKX0sc2FtcGxlOmtyLHNvcnRCeTpmdW5jdGlvbihuLHIsdCl7dmFyIGU9MDtyZXR1cm4gcj1QbihyLHQpLEJyKGpyKG4sKGZ1bmN0aW9uKG4sdCx1KXtyZXR1cm57dmFsdWU6bixpbmRleDplKyssY3JpdGVyaWE6cihuLHQsdSl9fSkpLnNvcnQoKGZ1bmN0aW9uKG4scil7dmFyIHQ9bi5jcml0ZXJpYSxlPXIuY3JpdGVyaWE7aWYodCE9PWUpe2lmKHQ+ZXx8dm9pZCAwPT09dClyZXR1cm4gMTtpZih0PGV8fHZvaWQgMD09PWUpcmV0dXJuLTF9cmV0dXJuIG4uaW5kZXgtci5pbmRleH0pKSwidmFsdWUiKX0sZ3JvdXBCeTpScixpbmRleEJ5OkZyLGNvdW50Qnk6VnIscGFydGl0aW9uOlByLHRvQXJyYXk6VHIsc2l6ZTpmdW5jdGlvbihuKXtyZXR1cm4gbnVsbD09bj8wOnRyKG4pP24ubGVuZ3RoOm5uKG4pLmxlbmd0aH0scGljazpVcixvbWl0OldyLGZpcnN0OkxyLGhlYWQ6THIsdGFrZTpMcixpbml0aWFsOnpyLGxhc3Q6ZnVuY3Rpb24obixyLHQpe3JldHVybiBudWxsPT1ufHxuLmxlbmd0aDwxP251bGw9PXJ8fHQ/dm9pZCAwOltdOm51bGw9PXJ8fHQ/bltuLmxlbmd0aC0xXTokcihuLE1hdGgubWF4KDAsbi5sZW5ndGgtcikpfSxyZXN0OiRyLHRhaWw6JHIsZHJvcDokcixjb21wYWN0OmZ1bmN0aW9uKG4pe3JldHVybiB4cihuLEJvb2xlYW4pfSxmbGF0dGVuOmZ1bmN0aW9uKG4scil7cmV0dXJuIGVyKG4sciwhMSl9LHdpdGhvdXQ6S3IsdW5pcTpKcix1bmlxdWU6SnIsdW5pb246R3IsaW50ZXJzZWN0aW9uOmZ1bmN0aW9uKG4pe2Zvcih2YXIgcj1bXSx0PWFyZ3VtZW50cy5sZW5ndGgsZT0wLHU9WShuKTtlPHU7ZSsrKXt2YXIgbz1uW2VdO2lmKCFNcihyLG8pKXt2YXIgaTtmb3IoaT0xO2k8dCYmTXIoYXJndW1lbnRzW2ldLG8pO2krKyk7aT09PXQmJnIucHVzaChvKX19cmV0dXJuIHJ9LGRpZmZlcmVuY2U6Q3IsdW56aXA6SHIsdHJhbnNwb3NlOkhyLHppcDpRcixvYmplY3Q6ZnVuY3Rpb24obixyKXtmb3IodmFyIHQ9e30sZT0wLHU9WShuKTtlPHU7ZSsrKXI/dFtuW2VdXT1yW2VdOnRbbltlXVswXV09bltlXVsxXTtyZXR1cm4gdH0scmFuZ2U6ZnVuY3Rpb24obixyLHQpe251bGw9PXImJihyPW58fDAsbj0wKSx0fHwodD1yPG4/LTE6MSk7Zm9yKHZhciBlPU1hdGgubWF4KE1hdGguY2VpbCgoci1uKS90KSwwKSx1PUFycmF5KGUpLG89MDtvPGU7bysrLG4rPXQpdVtvXT1uO3JldHVybiB1fSxjaHVuazpmdW5jdGlvbihuLHIpe2lmKG51bGw9PXJ8fHI8MSlyZXR1cm5bXTtmb3IodmFyIHQ9W10sZT0wLHU9bi5sZW5ndGg7ZTx1Oyl0LnB1c2goaS5jYWxsKG4sZSxlKz1yKSk7cmV0dXJuIHR9LG1peGluOllyLGRlZmF1bHQ6dG59KTtyZXR1cm4gWnIuXz1acixacn0pKTsKLyoqCiAqICAgIHhiZTR4IGlzIGphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIG9yaWdpbmFsIEVDTUFTY3JpcHQgZm9yIFhNTCAoRTRYKQogKiAgICBTcGVjaWZpY2F0aW9uIChFQ01BLTM1NykgRGVjZW1iZXIgMjAwNS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBkZXNpZ25lZCB0byBlbXVsYXRlCiAqICAgIHRoZSBpbXBsZW1lbnRhdGlvbiB0aGF0IGlzIHVzZWQgaW4gU3BpZGVyTW9ua2V5IChNb3ppbGxhJ3MgSmF2YVNjcmlwdChUTSkgRW5naW5lKQogKiAgICBhbmQgdGhlcmVmb3JlIEZpcmVmb3gsIFRodW5kZXJiaXJkLCBhbmQgbW9zdCBvdGhlciBHZWNrbyBiYXNlZCBhcHBsaWNhdGlvbnMuCiAqICAgIEJlY2F1c2UgdGhlIE1vemlsbGEgaW1wbGVtZW50YXRpb24gbGVhdmVzIG91dCBjZXJ0YWluIGZlYXR1cmVzIG9mIHRoZQogKiAgICBzcGVjaWZpY2F0aW9uLCBzbyBkb2VzIHhiZTR4LiBQbGVhc2UgcmVhZCB0aGUgUkVBRE1FIGZpbGUgZm9yIGEgZnVydGhlcgogKiAgICBleHBsYW5hdGlvbiBvZiB0aGVzZSBpc3N1ZXMuCiAqCiAqCiAqICAgIEBhdXRob3IgU2FtIFNodWxsIDxodHRwOi8vc2Ftc2h1bGwuYmxvZ3Nwb3QuY29tLz4KICogICAgQHZlcnNpb24gMC4xCiAqCiAqICAgIEBjb3B5cmlnaHQgQ29weXJpZ2h0IChjKSAyMDA5IFNhbSBTaHVsbCA8aHR0cDovL3NhbXNodWxsLmJsb2dzcG90LmNvbS8+CiAqICAgIEBsaWNlbnNlIDxodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLmh0bWw+CiAqCiAqICAgIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKICogICAgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKICogICAgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwogKiAgICB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiAqICAgIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwogKiAgICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiAgICBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgogKiAgICBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogICAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKICogICAgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiAqICAgIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQogKiAgICBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiAqICAgIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiAqICAgIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KICogICAgVEhFIFNPRlRXQVJFLgogKgogKgogKiAgICBDSEFOR0VTOgogKi8KCi8vdGhpcyBkb2Vzbid0IGxvYWQgaWYgd2luZG93LlhNTCBpcyBhbHJlYWR5IGRlZmluZWQKaWYgKCF0aGlzLlhNTCkKewogICAgKGZ1bmN0aW9uICgpCiAgICB7CiAgICAgICAgLyoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgdmFyIHVuZGVmaW5lZCwgcCwKICAgICAgICAgICAgd2luZG93ICAgICAgICAgICAgICAgICAgICAgICA9IHRoaXMsCiAgICAgICAgICAgIGRucyAgICAgICAgICAgICAgICAgICAgICAgICAgPSBbXSwKICAgICAgICAgICAgZGVmYXVsdE5hbWVzcGFjZSAgICAgICAgICAgICA9ICIiLAogICAgICAgICAgICBFTEVNRU5UX05PREUgICAgICAgICAgICAgICAgID0gMSwKICAgICAgICAgICAgQVRUUklCVVRFX05PREUgICAgICAgICAgICAgICA9IDIsCiAgICAgICAgICAgIFRFWFRfTk9ERSAgICAgICAgICAgICAgICAgICAgPSAzLAogICAgICAgICAgICBDREFUQV9TRUNUSU9OX05PREUgICAgICAgICAgID0gNCwKICAgICAgICAgICAgRU5USVRZX1JFRkVSRU5DRV9OT0RFICAgICAgICA9IDUsCiAgICAgICAgICAgIEVOVElUWV9OT0RFICAgICAgICAgICAgICAgICAgPSA2LAogICAgICAgICAgICBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgID0gNywKICAgICAgICAgICAgQ09NTUVOVF9OT0RFICAgICAgICAgICAgICAgICA9IDgsCiAgICAgICAgICAgIERPQ1VNRU5UX05PREUgICAgICAgICAgICAgICAgPSA5LAogICAgICAgICAgICBET0NVTUVOVF9UWVBFX05PREUgICAgICAgICAgID0gMTAsCiAgICAgICAgICAgIERPQ1VNRU5UX0ZSQUdNRU5UX05PREUgICAgICAgPSAxMSwKICAgICAgICAgICAgTk9UQVRJT05fTk9ERSAgICAgICAgICAgICAgICA9IDEyLAogICAgICAgICAgICBpc05TRGVmICAgICAgICAgICAgICAgICAgICAgID0gL154bWxuczooW1x3XC1dKykvaSwKICAgICAgICAgICAgdG9TdHJpbmcgICAgICAgICAgICAgICAgICAgICA9ICh7fSkudG9TdHJpbmcsCiAgICAgICAgICAgIHByb3BlcnR5SXNFbnVtZXJhYmxlICAgICAgICAgPSAoe30pLnByb3BlcnR5SXNFbnVtZXJhYmxlLAogICAgICAgICAgICBoYXNPd25Qcm9wZXJ0eSAgICAgICAgICAgICAgID0gKHt9KS5oYXNPd25Qcm9wZXJ0eSwKICAgICAgICAgICAgZGVmYXVsdFhNTFByb3BlcnRpZXMgICAgICAgICA9ICIscHJvdG90eXBlLGlnbm9yZUNvbW1lbnRzLGlnbm9yZVByb2Nlc3NpbmdJbnN0cnVjdGlvbnMsaWdub3JlV2hpdGVzcGFjZSwiICsKICAgICAgICAgICAgICAgICJwcmV0dHlQcmludGluZyxwcmV0dHlJbmRlbnQsc2V0dGluZ3MsZGVmYXVsdFNldHRpbmdzLHNldFNldHRpbmdzLHNldHRpbmdzLCIgKwogICAgICAgICAgICAgICAgInByb3BlcnR5SXNFbnVtZXJhYmxlLGhhc093blByb3BlcnR5LF9zZXREZWZhdWx0TmFtZXNwYWNlLCIsCiAgICAgICAgICAgIGRlZmF1bHRYTUxQcm90b3R5cGUgICAgICAgICAgPSAiLF9DbGFzcyxfTmFtZSxfUGFyZW50LF9WYWx1ZSxfSW5TY29wZU5hbWVzcGFjZXMsX0F0dHJpYnV0ZXMsX0NoaWxkcmVuLF9Ob2RlIiwKICAgICAgICAgICAgZGVmYXVsdFhNTExpc3RQcm90b3R5cGUgICAgICA9ICIsX0NsYXNzLF9WYWx1ZSxfQ2hpbGRyZW4sX1RhcmdldE9iamVjdCxfVGFyZ2V0UHJvcGVydHkiLAogICAgICAgICAgICB4bWxEb2MgICAgICAgICAgICAgICAgICAgICAgID0gcGFyc2UoIjx4Lz4iKSwKICAgICAgICAgICAgcGlOYW1lICAgICAgICAgICAgICAgICAgICAgICA9IC9eW1x3XC1dK1xzKi8sCiAgICAgICAgICAgIFhTTFRfTlMgICAgICAgICAgICAgICAgICAgICAgPSAiaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIjsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBYTUwgJHN0cmluZwogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqICAgIEB0aHJvd3MgU3ludGF4RXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBYTUwgKCRzdHJpbmcpCiAgICAgICAgewogICAgICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgWE1MKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIFRvWE1MKCRzdHJpbmcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgeCwgaSwgbDsKCiAgICAgICAgICAgIHRoaXMuX0NsYXNzID0gInRleHQiOwoKICAgICAgICAgICAgdGhpcy5fTmFtZSA9IG51bGw7CgogICAgICAgICAgICB0aGlzLl9WYWx1ZSA9IG51bGw7CgogICAgICAgICAgICB0aGlzLl9QYXJlbnQgPSBudWxsOwoKICAgICAgICAgICAgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMgPSB7fTsKCiAgICAgICAgICAgIHRoaXMuX0RlZmF1bHROYW1lc3BhY2UgPSBudWxsOwoKICAgICAgICAgICAgdGhpcy5fQXR0cmlidXRlcyA9IHt9OwoKICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW4gPSBbXTsKCiAgICAgICAgICAgIHRoaXNbMF0gPSB0aGlzOwoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzd2l0Y2ggKHR5cGVvZigkc3RyaW5nKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSAidW5kZWZpbmVkIjoKICAgICAgICAgICAgICAgIGNhc2UgIm51bGwiOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAibnVtYmVyIjoKICAgICAgICAgICAgICAgIGNhc2UgImJvb2xlYW4iOiAgICAkc3RyaW5nID0gVG9TdHJpbmcoJHN0cmluZyk7CiAgICAgICAgICAgICAgICBjYXNlICJzdHJpbmciOgoKICAgICAgICAgICAgICAgICAgICB4ID0gVG9YTUwodHJpbSgkc3RyaW5nKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHgpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoeC5sZW5ndGgoKSA9PT0xKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DbGFzcyA9IHguX0NsYXNzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fTmFtZSA9IHguX05hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9WYWx1ZSA9IHguX1ZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMgPSB4Ll9JblNjb3BlTmFtZXNwYWNlczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0RlZmF1bHROYW1lc3BhY2UgPSB4Ll9EZWZhdWx0TmFtZXNwYWNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQXR0cmlidXRlcyA9IHguX0F0dHJpYnV0ZXM7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMCwgbCA9IHguX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXSA9IHguX0NoaWxkcmVuW2ldOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldLl9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKCRzdHJpbmcgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHN0cmluZy5sZW5ndGgoKSA9PT0xKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gJHN0cmluZzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NsYXNzID0geC5fQ2xhc3M7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9OYW1lID0geC5fTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX1ZhbHVlID0geC5fVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcyA9IHguX0luU2NvcGVOYW1lc3BhY2VzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSA9IHguX0RlZmF1bHROYW1lc3BhY2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzID0geC5fQXR0cmlidXRlczsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0geC5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldID0geC5fQ2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0uX1BhcmVudCA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqICAgIElnbm9yZSBYTUwgY29tbWVudHMuIChEZWZhdWx0OiB0cnVlLikKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAcGFyYW0gTmFtZXNwYWNlIG5zCiAgICAgICAgICogICAgQHJldHVybnMgdm9pZAogICAgICAgICAqLwogICAgICAgIFhNTC5zZXREZWZhdWx0TmFtZXNwYWNlID0gZnVuY3Rpb24gKG5zKQogICAgICAgIHsKICAgICAgICAgICAgZG5zLnVuc2hpZnQoZGVmYXVsdE5hbWVzcGFjZSB8fCAiIik7CiAgICAgICAgICAgIGRlZmF1bHROYW1lc3BhY2UgPSBOYW1lc3BhY2UobnMpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKiAgVXNlIHRoaXMgZnVuY3Rpb24gdG8gcmVzdG9yZSB0aGUgZGVmYXVsdCBuYW1lc3BhY2UKICAgICAgICAgKiAgdG8gdGhlIHByZXZpb3VzIG5hbWVzcGFjZQogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgWE1MLnJlc3RvcmVEZWZhdWx0TmFtZXNwYWNlID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGRlZmF1bHROYW1lc3BhY2UgPSBkbnMuc2hpZnQoKSB8fCAiIjsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgWE1MLmxvYWQgPSBmdW5jdGlvbiAocGF0aFRvRmlsZSwgb25sb2FkKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHhociA9IGlzQWN0aXZlWFN1cHBvcnRlZCgiTWljcm9zb2Z0LlhNTEhUVFAiKSAmJiBuZXcgQWN0aXZlWE9iamVjdCgiTWljcm9zb2Z0LlhNTEhUVFAiKSB8fCBuZXcgWE1MSHR0cFJlcXVlc3QoKSwKICAgICAgICAgICAgICAgIGFzeW5jID0gKHt9KS50b1N0cmluZy5jYWxsKG9ubG9hZCB8fCB7fSkgPT0gIltvYmplY3QgRnVuY3Rpb25dIjsKCiAgICAgICAgICAgIHhoci5vcGVuKCJHRVQiLCBwYXRoVG9GaWxlLCBhc3luYyk7CgogICAgICAgICAgICBpZiAoYXN5bmMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghIXhoci5hZGRFdmVudExpc3RlbmVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHhoci5hZGRFdmVudExpc3RlbmVyKCJsb2FkIiwgbG9hZGVkLCBmYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uICgpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoeGhyLnJlYWR5U3RhdGUgPT0gNCAmJiB4aHIuc3RhdHVzID09IDIwMCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB4aHIuc2VuZChudWxsKTsKCiAgICAgICAgICAgIHJldHVybiBhc3luYyA/IHhociA6IGxvYWRlZCgxKTsKCiAgICAgICAgICAgIGZ1bmN0aW9uIGxvYWRlZCAocmV0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgeCA9IG5ldyBYTUwoKHhoci5yZXNwb25zZVRleHR8fCIiKS5yZXBsYWNlKC9ccyo8XD94bWwuKj9cPz4vLCIiKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmV0ID8geCA6IG9ubG9hZCh4KTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqICAgIElnbm9yZSBYTUwgY29tbWVudHMuIChEZWZhdWx0OiB0cnVlLikKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAdmFyIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUwuaWdub3JlQ29tbWVudHMgPSB0cnVlOwoKICAgICAgICAvKioKICAgICAgICAgKiAgICBJZ25vcmUgWE1MIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zLiAoRGVmYXVsdDogdHJ1ZS4pCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHZhciBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLmlnbm9yZVByb2Nlc3NpbmdJbnN0cnVjdGlvbnMgPSB0cnVlOwoKICAgICAgICAvKioKICAgICAgICAgKiAgICBJZ25vcmUgd2hpdGVzcGFjZS4gKERlZmF1bHQ6IHRydWUuKQogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEB2YXIgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5pZ25vcmVXaGl0ZXNwYWNlID0gdHJ1ZTsKCiAgICAgICAgLyoqCiAgICAgICAgICogICAgUHJldHR5LXByaW50IFhNTCBvdXRwdXQgd2l0aCB0b1hNTFN0cmluZygpIGV0Yy4gKERlZmF1bHQ6IHRydWUuKQogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEB2YXIgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5wcmV0dHlQcmludGluZyA9IHRydWU7CgogICAgICAgIC8qKgogICAgICAgICAqICAgIFByZXR0eSBpbmRlbnQgbGV2ZWwgZm9yIGNoaWxkIG5vZGVzLiAoRGVmYXVsdDogMi4pCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHZhciBOdW1iZXIKICAgICAgICAgKi8KICAgICAgICBYTUwucHJldHR5SW5kZW50ID0gMjsKCiAgICAgICAgLy9UaGVyZSBhcmUgYWxzbyB0aHJlZSBtZXRob2RzIHRvIG1vcmUgZWFzaWx5IGFwcGx5IGFuZCByZXN0b3JlIHNldHRpbmdzIGZvciB1c2UsIHNheSwgd2l0aGluIGEgZnVuY3Rpb24uCgogICAgICAgIC8qKgogICAgICAgICAqICAgIEdldCBhbiBPYmplY3QgY29udGFpbmluZyB0aGUgYWJvdmUgc2V0dGluZ3MuCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHJldHVybnMgT2JqZWN0CiAgICAgICAgICovCiAgICAgICAgWE1MLnNldHRpbmdzID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICBpZ25vcmVDb21tZW50czogICAgICAgICAgICAgICAgIFhNTC5pZ25vcmVDb21tZW50cywKICAgICAgICAgICAgICAgIGlnbm9yZVByb2Nlc3NpbmdJbnN0cnVjdGlvbnM6ICAgWE1MLmlnbm9yZVByb2Nlc3NpbmdJbnN0cnVjdGlvbnMsCiAgICAgICAgICAgICAgICBpZ25vcmVXaGl0ZXNwYWNlOiAgICAgICAgICAgICAgIFhNTC5pZ25vcmVXaGl0ZXNwYWNlLAogICAgICAgICAgICAgICAgcHJldHR5UHJpbnRpbmc6ICAgICAgICAgICAgICAgICBYTUwucHJldHR5UHJpbnRpbmcsCiAgICAgICAgICAgICAgICBwcmV0dHlJbmRlbnQ6ICAgICAgICAgICAgICAgICAgIFhNTC5wcmV0dHlJbmRlbnQKICAgICAgICAgICAgfTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKiAgICBHZXQgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGRlZmF1bHQgc2V0dGluZ3MuCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHJldHVybnMgT2JqZWN0CiAgICAgICAgICovCiAgICAgICAgWE1MLmRlZmF1bHRTZXR0aW5ncyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgaWdub3JlQ29tbWVudHM6ICAgICAgICAgICAgICAgICB0cnVlLAogICAgICAgICAgICAgICAgaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9uczogICB0cnVlLAogICAgICAgICAgICAgICAgaWdub3JlV2hpdGVzcGFjZTogICAgICAgICAgICAgICB0cnVlLAogICAgICAgICAgICAgICAgcHJldHR5UHJpbnRpbmc6ICAgICAgICAgICAgICAgICB0cnVlLAogICAgICAgICAgICAgICAgcHJldHR5SW5kZW50OiAgICAgICAgICAgICAgICAgICAyCiAgICAgICAgICAgIH07CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICogICAgU2V0IFhNTCBzZXR0aW5ncyBmcm9tLCBlLmcuLCBhbiBvYmplY3QgcmV0dXJuZWQgYnkgWE1MLnNldHRpbmdzKCkuCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAcGFyYW0gT2JqZWN0IHNldHRpbmdzCiAgICAgICAgICogICAgQHJldHVybnMgdm9pZAogICAgICAgICAqLwogICAgICAgIFhNTC5zZXRTZXR0aW5ncyA9IGZ1bmN0aW9uIChzZXR0aW5ncykKICAgICAgICB7CiAgICAgICAgICAgIHZhciBwOwogICAgICAgICAgICBzZXR0aW5ncyA9IHNldHRpbmdzIHx8IFhNTC5zZXR0aW5ncygpOwogICAgICAgICAgICBmb3IgKHAgaW4gc2V0dGluZ3MpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAocCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJpZ25vcmVDb21tZW50cyI6ICAgICAgICAgICAgICAgICAgIFhNTC5pZ25vcmVDb21tZW50cyA9ICEhc2V0dGluZ3NbcF07CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucyI6ICAgICBYTUwuaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucyA9ICEhc2V0dGluZ3NbcF07CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiaWdub3JlV2hpdGVzcGFjZSI6ICAgICAgICAgICAgICAgICBYTUwuaWdub3JlV2hpdGVzcGFjZSA9ICEhc2V0dGluZ3NbcF07CiAgICAgICAgICAgICAgICAgICAgY2FzZSAicHJldHR5UHJpbnRpbmciOiAgICAgICAgICAgICAgICAgICBYTUwucHJldHR5UHJpbnRpbmcgPSAhIXNldHRpbmdzW3BdOwogICAgICAgICAgICAgICAgICAgIGNhc2UgInByZXR0eUluZGVudCI6ICAgICAgICAgICAgICAgICAgICAgWE1MLnByZXR0eUluZGVudCA9IHBhcnNlSW50KHNldHRpbmdzW3BdKSB8fCAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5oYXNPd25Qcm9wZXJ0eSA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRYTUxQcm9wZXJ0aWVzLmluZGV4T2YoIiwiICsgbmFtZSArICIsIikgPT09LTEKICAgICAgICAgICAgICAgICYmIGhhc093blByb3BlcnR5LmNhbGwoWE1MLCBuYW1lKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUwucHJvcGVydHlJc0VudW1lcmFibGUgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuYW1lICE9PSAicHJvdG90eXBlIgogICAgICAgICAgICAgICAgJiYgbmFtZSBpbiBYTUwKICAgICAgICAgICAgICAgICYmIHRvU3RyaW5nLmNhbGwoWE1MW25hbWVdKSAhPSAiW29iamVjdCBGdW5jdGlvbl0iCiAgICAgICAgICAgICAgICAmJiBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKFhNTCwgbmFtZSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBYTUwudG9TdHJpbmcgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICJmdW5jdGlvbiBYTUwoKSB7XG4gW25hdGl2ZSBjb2RlXSBcbn0iOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTmFtZXNwYWNlIG5hbWVzcGFjZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuYWRkTmFtZXNwYWNlID0gZnVuY3Rpb24gKG5hbWVzcGFjZSkKICAgICAgICB7CiAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbCh0aGlzLCBOYW1lc3BhY2UobmFtZXNwYWNlKSk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIGNoaWxkCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5hcHBlbmRDaGlsZCA9IGZ1bmN0aW9uIChjaGlsZCxpc0NoaWxkRWxlbWVudCkKICAgICAgICB7CiAgICAgICAgICAgIGlzQ2hpbGRFbGVtZW50ID0gaXNDaGlsZEVsZW1lbnQgIT09IHVuZGVmaW5lZCA/IGlzQ2hpbGRFbGVtZW50IDogZmFsc2U7CiAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IEdldC5jYWxsKHRoaXMsICIqIik7CiAgICAgICAgICAgIGNoaWxkcmVuLlB1dChjaGlsZHJlbi5sZW5ndGgoKSwgY2hpbGQsaXNDaGlsZEVsZW1lbnQpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IEF0dHJpYnV0ZU5hbWUgfCBRTmFtZSBhdHRyaWJ1dGVOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5hdHRyaWJ1dGUgPSBmdW5jdGlvbiAoYXR0cmlidXRlTmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBHZXQuY2FsbCh0aGlzLCBUb0F0dHJpYnV0ZU5hbWUoYXR0cmlidXRlTmFtZSksIHRydWUpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5hdHRyaWJ1dGVzID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBHZXQuY2FsbCh0aGlzLCBUb0F0dHJpYnV0ZU5hbWUoIioiKSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgcHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuY2hpbGQgPSBmdW5jdGlvbiAocHJvcGVydHlOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHRlbXBvcmFyeTsKCiAgICAgICAgICAgIGlmIChwYXJzZUludChwcm9wZXJ0eU5hbWUpKyIiID09IHByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGVtcG9yYXJ5ID0gR2V0LmNhbGwodGhpcywgIioiKTsKICAgICAgICAgICAgICAgIHRlbXBvcmFyeSA9IEdldExpc3QuY2FsbCh0ZW1wb3JhcnksIHByb3BlcnR5TmFtZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gdGVtcG9yYXJ5IHx8IG5ldyBYTUxMaXN0KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRlbXBvcmFyeSA9IFRvWE1MTGlzdCggR2V0LmNhbGwodGhpcywgcHJvcGVydHlOYW1lKSApOwoKICAgICAgICAgICAgcmV0dXJuIHRlbXBvcmFyeTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgTnVtYmVyCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5jaGlsZEluZGV4ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBwYXJlbnQgPSB0aGlzLl9QYXJlbnQsIHEsIGw7CgogICAgICAgICAgICBpZiAoIXBhcmVudCB8fCB0aGlzLl9DbGFzcyA9PT0gImF0dHJpYnV0ZSIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChxID0gMCwgbCA9IHBhcmVudC5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocGFyZW50Ll9DaGlsZHJlbltxXSA9PT0gdGhpcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5jaGlsZHJlbiA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gR2V0LmNhbGwodGhpcywgIioiKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuY29tbWVudHMgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgWE1MTGlzdCgpLCBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gdGhpczsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0UHJvcGVydHkgPSBudWxsOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJjb21tZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZCh0aGlzLl9DaGlsZHJlbltpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIHZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuY29udGFpbnMgPSBmdW5jdGlvbiAodmFsdWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdGhpcyA9PSB2YWx1ZTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBEZWVwQ29weS5jYWxsKHRoaXMpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmRlc2NlbmRhbnRzID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRGVzY2VuZGFudHMuY2FsbCh0aGlzLCBuYW1lIHx8ICIqIik7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSB8IEF0dHJpYnV0ZU5hbWUgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmVsZW1lbnRzID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICBuYW1lID0gVG9YTUxOYW1lKG5hbWUgfHwgIioiKTsKICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgWE1MTGlzdCgpLCBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gdGhpczsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0UHJvcGVydHkgPSBuYW1lOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJlbGVtZW50IgogICAgICAgICAgICAgICAgICAgICAgICAmJiAobmFtZS5sb2NhbE5hbWUgPT09ICIqIiB8fCBuYW1lLmxvY2FsTmFtZSA9PT0gdGhpcy5fQ2hpbGRyZW5baV0uX05hbWUubG9jYWxOYW1lKQogICAgICAgICAgICAgICAgICAgICAgICAmJiAobmFtZS51cmkgPT0gbnVsbCB8fCBuYW1lLnVyaSA9PT0gdGhpcy5fQ2hpbGRyZW5baV0uX05hbWUudXJpKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZCh0aGlzLl9DaGlsZHJlbltpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIEhhc1Byb3BlcnR5LmNhbGwodGhpcywgbmFtZSkgfHwgKGRlZmF1bHRYTUxQcm90b3R5cGUuaW5kZXhPZigiLCIgKyBuYW1lICsiLCIpID09PSAtMSAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMsIG5hbWUpKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuaGFzQ29tcGxleENvbnRlbnQgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgiLGF0dHJpYnV0ZSxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sdGV4dCwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5baV0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuaGFzU2ltcGxlQ29udGVudCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBBcnJheQogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuaW5TY29wZU5hbWVzcGFjZXMgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHkgPSB0aGlzLCBpblNjb3BlTlMgPSB7fSwgcCwgYSA9IFtdOwoKICAgICAgICAgICAgd2hpbGUgKHkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAocCBpbiB5Ll9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWluU2NvcGVOU1twXSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGluU2NvcGVOU1twXSA9IHkuX0luU2NvcGVOYW1lc3BhY2VzW3BdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB5ID0geS5wYXJlbnQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRoaXMuX0RlZmF1bHROYW1lc3BhY2UpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGluU2NvcGVOU1siIl0gPSB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHAgaW4gaW5TY29wZU5TKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhW2EubGVuZ3RoXSA9IGluU2NvcGVOU1twXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGE7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBYTUwgY2hpbGQxCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBjaGlsZDIKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwgfCBudWxsCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5pbnNlcnRDaGlsZEFmdGVyID0gZnVuY3Rpb24gKGNoaWxkMSwgY2hpbGQyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgiLGF0dHJpYnV0ZSxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sdGV4dCwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgIC8vdGhpcyBpcyBkaXNhYmxlZCwgYmVjYXVzZSBpdCBkb2Vzbid0IHdvcmsgaW4KICAgICAgICAgICAgIC8vRmlyZWZveCBhY2NvcmRpbmcgdG8gdGhlIHNwZWMKICAgICAgICAgICAgIGlmICghY2hpbGQyKQogICAgICAgICAgICAgewogICAgICAgICAgICAgSW5zZXJ0LmNhbGwodGhpcywgMCwgY2hpbGQxKTsKICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgZWxzZSBpZiAoIWNoaWxkMSkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIDAsIGNoaWxkMik7CiAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICovCgogICAgICAgICAgICBpZiAoIWNoaWxkMSl7CiAgICAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCAwLCBjaGlsZDIpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFjaGlsZDIpewogICAgICAgICAgICAgICAgSW5zZXJ0LmNhbGwodGhpcywgMCwgY2hpbGQxKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY2hpbGQxIGluc3RhbmNlb2YgWE1MKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCBjaGlsZDEuY2hpbGRJbmRleCgpICsgMSwgY2hpbGQyKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIGNoaWxkMQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgY2hpbGQyCiAgICAgICAgICogICAgQHJldHVybnMgWE1MIHwgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuaW5zZXJ0Q2hpbGRCZWZvcmUgPSBmdW5jdGlvbiAoY2hpbGQxLCBjaGlsZDIpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsYXR0cmlidXRlLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgLy90aGlzIGlzIGRpc2FibGVkLCBiZWNhdXNlIGl0IGRvZXNuJ3Qgd29yayBpbgogICAgICAgICAgICAgLy9GaXJlZm94IGFjY29yZGluZyB0byB0aGUgc3BlYwogICAgICAgICAgICAgaWYgKCFjaGlsZDEpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIGNoaWxkMik7CiAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIGVsc2UgaWYgKCFjaGlsZDIpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIGNoaWxkMSk7CiAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICovCgogICAgICAgICAgICBpZiAoY2hpbGQxIGluc3RhbmNlb2YgWE1MKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCBjaGlsZDEuY2hpbGRJbmRleCgpLCBjaGlsZDIpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBOdW1iZXIKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmxlbmd0aCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nIHwgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUubG9jYWxOYW1lID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9OYW1lID09PSBudWxsID8gbnVsbCA6IHRoaXMuX05hbWUubG9jYWxOYW1lOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICByZXR1cm4gUU5hbWUKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLm5hbWUgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX05hbWU7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgcHJlZml4CiAgICAgICAgICogICAgQHJldHVybnMgTmFtZXNwYWNlCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5uYW1lc3BhY2UgPSBmdW5jdGlvbiAocHJlZml4KQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHkgPSB0aGlzLCBpblNjb3BlTlMgPSB7fSwgcDsKCiAgICAgICAgICAgIHdoaWxlICh5KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKHAgaW4geS5fSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpblNjb3BlTlNbcF0pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpblNjb3BlTlNbcF0gPSB5Ll9JblNjb3BlTmFtZXNwYWNlc1twXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgeSA9IHkucGFyZW50KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChwcmVmaXggPT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCgiLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIEdldE5hbWVzcGFjZSh0aGlzLl9OYW1lLCBpblNjb3BlTlMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcmVmaXggPSBUb1N0cmluZyhwcmVmaXgpOwoKICAgICAgICAgICAgZm9yIChwIGluIGluU2NvcGVOUykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGluU2NvcGVOU1twXS5wcmVmaXggPT09IHByZWZpeCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5TY29wZU5TW3BdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgQXJyYXkKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLm5hbWVzcGFjZURlY2xhcmF0aW9ucyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsYXR0cmlidXRlLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBbXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGEgPSBbXSwgeSA9IHRoaXMuX1BhcmVudCwgYW5jZXN0b3JOUyA9IHt9LCBwOwoKICAgICAgICAgICAgd2hpbGUgKHkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAocCBpbiB5Ll9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWFuY2VzdG9yTlNbcF0pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhbmNlc3Rvck5TW3BdID0geS5fSW5TY29wZU5hbWVzcGFjZXNbcF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHkgPSB5Ll9QYXJlbnQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAocCBpbiB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHAgIT0gIiIgJiYgKCFhbmNlc3Rvck5TW3BdIHx8IGFuY2VzdG9yTlNbcF0udXJpICE9IHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBhW2EubGVuZ3RoXSA9IHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZihwID09PSAiIiAmJiAhdGhpcy5fUGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFbYS5sZW5ndGhdID0gdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbcF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBhOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLm5vZGVLaW5kID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9DbGFzczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5ub3JtYWxpemUgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldLm5vcm1hbGl6ZSgpOwogICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gInRleHQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHdoaWxlIChpKzEgPCB0aGlzLl9DaGlsZHJlbi5sZW5ndGggJiYgdGhpcy5fQ2hpbGRyZW5baSsxXS5fQ2xhc3MgPT09ICJ0ZXh0IikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldLl9WYWx1ZSA9ICh0aGlzLl9DaGlsZHJlbltpXS5fVmFsdWUgfHwgIiIpICsgKHRoaXMuX0NoaWxkcmVuW2krMV0uX1ZhbHVlIHx8ICIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgRGVsZXRlQnlJbmRleC5jYWxsKHRoaXMsIGkrMSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5baV0uX1ZhbHVlLmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZUJ5SW5kZXguY2FsbCh0aGlzLCBpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgKytpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICArK2k7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwgfCBudWxsCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5wYXJlbnQgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX1BhcmVudDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUucHJvY2Vzc2luZ0luc3RydWN0aW9ucyA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgbmFtZSA9IFRvWE1MTmFtZShuYW1lIHx8ICIqIik7CgogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRQcm9wZXJ0eSA9IG51bGw7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iCiAgICAgICAgICAgICAgICAgICAgJiYgKG5hbWUubG9jYWxOYW1lID09PSAiKiIgfHwgbmFtZS5sb2NhbE5hbWUgPT09IHRoaXMuX0NoaWxkcmVuW2ldLl9OYW1lLmxvY2FsTmFtZSkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQodGhpcy5fQ2hpbGRyZW5baV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFhNTCB2YWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUucHJlcGVuZENoaWxkID0gZnVuY3Rpb24gKHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgSW5zZXJ0LmNhbGwodGhpcywgMCwgdmFsdWUpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKCiAgICAgICAgWE1MLnByb3RvdHlwZS5maW5kRmlyc3RFbGVtZW50ID0gZnVuY3Rpb24gKHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGxpc3QgPSBbXTsKICAgICAgICAgICAgbGlzdCA9IHRoaXMuZWxlbWVudHModmFsdWUpLl9DaGlsZHJlbjsKICAgICAgICAgICAgaWYobGlzdC5sZW5ndGggPT0gMCl7CiAgICAgICAgICAgICAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuKCk7CiAgICAgICAgICAgICAgICB2YXIgeG1sOwogICAgICAgICAgICAgICAgZm9yKHZhciBpPTA7aTxjaGlsZHJlbi5sZW5ndGgoKTtpKyspewogICAgICAgICAgICAgICAgICAgIHhtbCA9IGNoaWxkcmVuW2ldOwogICAgICAgICAgICAgICAgICAgIHZhciBzdWJsaXN0ID0geG1sLmZpbmRGaXJzdEVsZW1lbnQodmFsdWUpOwogICAgICAgICAgICAgICAgICAgIGlmKHN1Ymxpc3QubGVuZ3RoPjApCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWJsaXN0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuYW1lID09ICIwIjsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIE5hbWVzcGFjZSB8IFN0cmluZyBuYW1lc3BhY2UKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnJlbW92ZU5hbWVzcGFjZSA9IGZ1bmN0aW9uIChuYW1lc3BhY2UpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsYXR0cmlidXRlLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbnMgPSBOYW1lc3BhY2UobmFtZXNwYWNlKSwgdGhpc05TID0gR2V0TmFtZXNwYWNlKHRoaXMuX05hbWUsIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzKSwgcCwgbDsKCiAgICAgICAgICAgIGlmICh0aGlzTlMgPT0gbnMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgLy9maXJlZm94IGRvZXMgbm90IHJlbW92ZSB0aGUgcmVmZXJlbmNlcyB0byB0aGUKICAgICAgICAgICAgIC8vbmFtZXNwYWNlcyBpbiBhdHRyaWJ1dGVzIC0tIHNvIHdlIHdvbnQgZWl0aGVyCiAgICAgICAgICAgICBmb3IgKHAgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIGlmIChHZXROYW1lc3BhY2UodGhpcy5fQXR0cmlidXRlc1twXS5fTmFtZSwgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMpLnVyaSA9PSBucy51cmkpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzW3BdLl9OYW1lID0gbmV3IFFOYW1lKG5zLCB0aGlzLl9BdHRyaWJ1dGVzW3BdLmxvY2FsTmFtZSgpKTsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIH0KICAgICAgICAgICAgIC8vKi8KCiAgICAgICAgICAgIGlmIChucy5wcmVmaXggPT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKHAgaW4gdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdLnVyaSA9PT0gbnMudXJpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5ewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbcF0gPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdOwogICAgICAgICAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1tucy5wcmVmaXhdICYmIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW25zLnByZWZpeF0udXJpID09PSBucy51cmkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1tucy5wcmVmaXhdID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbbnMucHJlZml4XTsKICAgICAgICAgICAgICAgIH1jYXRjaChlKXt9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAocCA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IHAgPCBsOyArK3ApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltwXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltwXS5yZW1vdmVOYW1lc3BhY2UobnMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBwcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIHZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5yZXBsYWNlID0gZnVuY3Rpb24gKHByb3BlcnR5TmFtZSwgdmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsYXR0cmlidXRlLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgYyA9IHZhbHVlIGluc3RhbmNlb2YgWE1MID8gRGVlcENvcHkuY2FsbCh2YWx1ZSkgOiBUb1N0cmluZyh2YWx1ZSksIG4sIGksIGs7CgogICAgICAgICAgICBpZiAocGFyc2VJbnQocHJvcGVydHlOYW1lKSsiIiA9PSBwcm9wZXJ0eU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbCh0aGlzLCBwcm9wZXJ0eU5hbWUsIGMpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICBCYXNpY2FsbHkgRmlyZWZveCBkb2VzIG5vdCBhcHBlYXIgdG8gZm9sbG93IHRoZSBydWxlcyBzZXQgZm9ydGggaW4gdGhlIHNwZWMKICAgICAgICAgICAgIHNvLCB3ZSBhcmUganVzdCBnb2luZyB0byBmaXggdGhpcyBzbyB0aGF0IHdlIGRvIHdoYXQgZmlyZWZveCBkb2VzCiAgICAgICAgICAgICBpZiB0aGUgcHJvcGVydHlOYW1lIGlzIG5vdCBhbiBpbnRlZ2VyOgogICAgICAgICAgICAgaWYgdmFsdWUgaXMgYSBYTUxMaXN0IHNldENoaWxkcmVuCiAgICAgICAgICAgICBvdGhlcndpc2UgZG8gbm90aGluZwogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGlmIChjIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhpcy5zZXRDaGlsZHJlbihjKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgTGVhdmUgdGhlIHJlc3Qgb2YgdGhlc2UgcnVsZXMgaW4gcGxhY2UsIGp1c3QgaW4gY2FzZQogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIG4gPSBRTmFtZShwcm9wZXJ0eU5hbWUpOwogICAgICAgICAgICBrID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwoKICAgICAgICAgICAgd2hpbGUgKC0tayA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKG4ubG9jYWxOYW1lID09PSAiKiIgfHwgKHRoaXMuX0NoaWxkcmVuW2tdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLmxvY2FsTmFtZT09PW4ubG9jYWxOYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKG4udXJpID09IG51bGwgfHwgKHRoaXMuX0NoaWxkcmVuW2tdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIG4udXJpID09PSB0aGlzLl9DaGlsZHJlbltrXS5fTmFtZS51cmkgKSkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGkgIT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZUJ5SW5kZXguY2FsbCh0aGlzLCBpKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGkgPSBrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaSAhPT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZXBsYWNlLmNhbGwodGhpcywgaSwgYyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIHZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5zZXRDaGlsZHJlbiA9IGZ1bmN0aW9uICh2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIHRoaXMuUHV0KCIqIiwgdmFsdWUpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgdm9pZAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuc2V0TG9jYWxOYW1lID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsY29tbWVudCx0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLl9OYW1lLmxvY2FsTmFtZSA9IG5hbWUgaW5zdGFuY2VvZiBRTmFtZSA/IG5hbWUubG9jYWxOYW1lIDogVG9TdHJpbmcobmFtZSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBRTmFtZSB8IFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuc2V0TmFtZSA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgiLGNvbW1lbnQsdGV4dCwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG5hbWUgaW5zdGFuY2VvZiBRTmFtZSAmJiBuYW1lLnVyaSA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBuYW1lID0gbmFtZS5sb2NhbE5hbWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBuID0gUU5hbWUobmFtZSk7CgogICAgICAgICAgICBpZiAodGhpcy5fQ2xhc3MgPT09ICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbi51cmkgPSAiIjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSA9IG5ldyBOYW1lc3BhY2Uobi5wcmVmaXgsIG4udXJpKTsKCiAgICAgICAgICAgIHRoaXMuX05hbWUgPSBuOwoKICAgICAgICAgICAgaWYgKHRoaXMuX0NsYXNzID09PSAiYXR0cmlidXRlIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX1BhcmVudCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBBZGRJblNjb3BlTmFtZXNwYWNlLmNhbGwodGhpcy5fUGFyZW50LCB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBBZGRJblNjb3BlTmFtZXNwYWNlLmNhbGwodGhpcywgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoKCIsY29tbWVudCx0ZXh0LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX05hbWUgPSBuZXcgUU5hbWUodGhpcy5fRGVmYXVsdE5hbWVzcGFjZSwgdGhpcy5fTmFtZS5sb2NhbE5hbWUpOwoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBOYW1lc3BhY2UgfCBTdHJpbmcgbnMKICAgICAgICAgKiAgICBAcmV0dXJucyBudWxsCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5zZXROYW1lc3BhY2UgPSBmdW5jdGlvbiAobnMpCiAgICAgICAgewogICAgICAgICAgICAvL3Byb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sCiAgICAgICAgICAgIGlmICgoIixjb21tZW50LHRleHQsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX0RlZmF1bHROYW1lc3BhY2UgPSBOYW1lc3BhY2UobnMpOwoKICAgICAgICAgICAgdGhpcy5fTmFtZSA9IG5ldyBRTmFtZSh0aGlzLl9EZWZhdWx0TmFtZXNwYWNlLCB0aGlzLl9OYW1lLmxvY2FsTmFtZSk7CgogICAgICAgICAgICBpZiAodGhpcy5fQ2xhc3MgPT09ICJhdHRyaWJ1dGUiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fUGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbCh0aGlzLl9QYXJlbnQsIHRoaXMuX0RlZmF1bHROYW1lc3BhY2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbCh0aGlzLCB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnRleHQgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgWE1MTGlzdCgpLCBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gdGhpczsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0UHJvcGVydHkgPSBudWxsOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJ0ZXh0IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZCh0aGlzLl9DaGlsZHJlbltpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUb1N0cmluZyh0aGlzKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS50b1hNTFN0cmluZyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVG9YTUxTdHJpbmcodGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUudmFsdWVPZiA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHBhcmFtIFhNTCB8IFN0cmluZyBWYWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuUHV0ID0gZnVuY3Rpb24gKFByb3BlcnR5TmFtZSwgVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAocGFyc2VJbnQoUHJvcGVydHlOYW1lKSsiIiA9PSBQcm9wZXJ0eU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCgiLHRleHQsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLGF0dHJpYnV0ZSwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGMgPSAoIShWYWx1ZSBpbnN0YW5jZW9mIFhNTCkgfHwgKCIsdGV4dCxhdHRyaWJ1dGUsIikuaW5kZXhPZigiLCIgKyBWYWx1ZS5fQ2xhc3MrIiwiKSA+IC0xKQogICAgICAgICAgICAgICAgICAgID8gVG9TdHJpbmcoVmFsdWUpCiAgICAgICAgICAgICAgICAgICAgOiBEZWVwQ29weS5jYWxsKFZhbHVlKSwKICAgICAgICAgICAgICAgIG4gPSBUb1hNTE5hbWUoUHJvcGVydHlOYW1lKSwKICAgICAgICAgICAgICAgIHMsIGksIGwsIGEgPSBudWxsLCBwcmltaXRpdmVBc3NpZ24sIGs7CgogICAgICAgICAgICBpZiAobiBpbnN0YW5jZW9mIEF0dHJpYnV0ZU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghaXNYTUxOYW1lKG4uX05hbWUpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoYyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGMgPSAiIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcyA9IFRvU3RyaW5nKGNbMF0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMSwgbCA9IGMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiICIgKyBUb1N0cmluZyhjW2ldKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgYyA9IHM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGMgPSBUb1N0cmluZyhjKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmb3IgKGkgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgIChuLl9OYW1lLmxvY2FsTmFtZSA9PT0gdGhpcy5fQXR0cmlidXRlc1tpXS5fTmFtZS5sb2NhbE5hbWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAobi5fTmFtZS51cmkgPT09IG51bGwgfHwgbi5fTmFtZS51cmkgPT09IHRoaXMuX0F0dHJpYnV0ZXNbaV0uX05hbWUudXJpKQogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhID0gdGhpcy5fQXR0cmlidXRlc1tpXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuRGVsZXRlKHRoaXMuX0F0dHJpYnV0ZXNbaV0uX05hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChhID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYSA9IG5ldyBYTUwoKTsKICAgICAgICAgICAgICAgICAgICBhLl9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgIGEuX0NsYXNzID0gImF0dHJpYnV0ZSI7CiAgICAgICAgICAgICAgICAgICAgYS5fTmFtZSA9IG4uX05hbWUudXJpID09IG51bGwKICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgUU5hbWUobmV3IE5hbWVzcGFjZSgpLCBuLl9OYW1lKQogICAgICAgICAgICAgICAgICAgICAgICA6IG5ldyBRTmFtZShuZXcgTmFtZXNwYWNlKG4uX05hbWUudXJpKSwgbi5fTmFtZS5sb2NhbE5hbWUpOwoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzWyhhLl9OYW1lLl9QcmVmaXggPyBhLl9OYW1lLl9QcmVmaXggKyAiOiIgOiAiIikgKyBhLl9OYW1lLmxvY2FsTmFtZV0gPSBhOwoKICAgICAgICAgICAgICAgICAgICBBZGRJblNjb3BlTmFtZXNwYWNlLmNhbGwodGhpcywgR2V0TmFtZXNwYWNlKGEuX05hbWUpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBhLl9WYWx1ZSA9IGM7CgogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNYTUxOYW1lKG4pICYmIG4ubG9jYWxOYW1lICE9ICIqIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGkgPSB1bmRlZmluZWQ7CgogICAgICAgICAgICBwcmltaXRpdmVBc3NpZ24gPSAhKGMgaW5zdGFuY2VvZiBYTUwpICYmIG4ubG9jYWxOYW1lICE9ICIqIjsKCiAgICAgICAgICAgIGZvciAoayA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGsgPCBsOyArK2spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAobi5sb2NhbE5hbWUgPT09ICIqIiB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgdGhpcy5fQ2hpbGRyZW5ba10uX05hbWUubG9jYWxOYW1lPT09bi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgICAgICAgICAobi51cmkgPT0gbnVsbCB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgbi51cmkgPT09IHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLnVyaSkpCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChpICE9IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZUJ5SW5kZXguY2FsbCh0aGlzLCBUb1N0cmluZyhpKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGkgPSBrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGkgPT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwoKICAgICAgICAgICAgICAgIGlmIChwcmltaXRpdmVBc3NpZ24pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYSA9IG5ldyBYTUwoKTsKICAgICAgICAgICAgICAgICAgICBhLl9DbGFzcyA9ICJlbGVtZW50IjsKICAgICAgICAgICAgICAgICAgICBhLl9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgIGEuX05hbWUgPSBuLnVyaSA9PSBudWxsCiAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IFFOYW1lKEdldERlZmF1bHROYW1lc3BhY2UoKSwgbikKICAgICAgICAgICAgICAgICAgICAgICAgOiBuZXcgUU5hbWUobik7CgogICAgICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbCh0aGlzLCBUb1N0cmluZyhpKSwgYSk7CgogICAgICAgICAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbChhLCBHZXROYW1lc3BhY2UoYS5fTmFtZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocHJpbWl0aXZlQXNzaWduKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzID0gVG9TdHJpbmcoYyk7CgogICAgICAgICAgICAgICAgaWYgKHMgIT0gIiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgUmVwbGFjZS5jYWxsKHRoaXMuX0NoaWxkcmVuW2ldLCAiMCIsIHMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVwbGFjZS5jYWxsKHRoaXMsIFRvU3RyaW5nKGkpLCBjKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuRGVsZXRlID0gZnVuY3Rpb24gKFByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwYXJzZUludChQcm9wZXJ0eU5hbWUpKyIiID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbiA9IFRvWE1MTmFtZShQcm9wZXJ0eU5hbWUpLCBrLCBkcCA9IDAsIHEgPSAwLCBsOwoKICAgICAgICAgICAgaWYgKG4gaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGsgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgIChuLl9OYW1lLmxvY2FsTmFtZSA9PT0gIioiIHx8IG4uX05hbWUubG9jYWxOYW1lID09PSB0aGlzLl9BdHRyaWJ1dGVzW2tdLl9OYW1lLmxvY2FsTmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobi5fTmFtZS51cmkgPT0gbnVsbCB8fCBuLl9OYW1lLnVyaSA9PT0gdGhpcy5fQXR0cmlidXRlc1trXS5fTmFtZS51cmkpCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0F0dHJpYnV0ZXNba10uX1BhcmVudCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9BdHRyaWJ1dGVzW2tdOwogICAgICAgICAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKG4ubG9jYWxOYW1lID09PSAiKiIgfHwgKHRoaXMuX0NoaWxkcmVuW3FdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXMuX0NoaWxkcmVuW3FdLl9OYW1lLmxvY2FsTmFtZSA9PT0gbi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgICAgICAgICAobi51cmkgPT0gbnVsbCB8fCAodGhpcy5fQ2hpbGRyZW5bcV0uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgbi51cmkgPT09IHRoaXMuX0NoaWxkcmVuW3FdLl9OYW1lLnVyaSkpCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIERlbGV0ZUJ5SW5kZXguY2FsbCh0aGlzLCBxKTsKICAgICAgICAgICAgICAgICAgICArK2RwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoZHAgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW3EgLSBkcF0gPSB0aGlzLl9DaGlsZHJlbltxXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgVmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5FcXVhbHMgPSBmdW5jdGlvbiAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIShWYWx1ZSBpbnN0YW5jZW9mIFhNTCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhpcy5fQ2xhc3MgIT09IFZhbHVlLl9DbGFzcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggIT09IFZhbHVlLl9DaGlsZHJlbi5sZW5ndGgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhpcy5fVmFsdWUgIT09IFZhbHVlLl9WYWx1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLl9OYW1lICE9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoVmFsdWUuX05hbWUgPT09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKFZhbHVlLl9OYW1lLmxvY2FsTmFtZSAhPT0gdGhpcy5fTmFtZS5sb2NhbE5hbWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKFZhbHVlLl9OYW1lLnVyaSAhPT0gdGhpcy5fTmFtZS51cmkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKFZhbHVlLl9OYW1lICE9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb3VudCh0aGlzLl9BdHRyaWJ1dGVzKSAhPT0gY291bnQoVmFsdWUuX0F0dHJpYnV0ZXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBhLCBiLCBrLCBsOwoKICAgICAgICAgICAgZm9yIChrIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGEgPSB0aGlzLl9BdHRyaWJ1dGVzW2tdOwoKICAgICAgICAgICAgICAgIGIgPSBWYWx1ZS5fQXR0cmlidXRlc1trXTsKCiAgICAgICAgICAgICAgICBpZiAoIWIgfHwgYi5fTmFtZS5sb2NhbE5hbWUgIT09IGEuX05hbWUubG9jYWxOYW1lIHx8IGIuX05hbWUudXJpICE9PSBhLl9OYW1lLnVyaSB8fCBiLl9WYWx1ZSAhPT0gYS5fVmFsdWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGsgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBrIDwgbDsgKytrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhID0gdGhpcy5fQ2hpbGRyZW5ba107CgogICAgICAgICAgICAgICAgYiA9IFZhbHVlLl9DaGlsZHJlbltrXTsKCiAgICAgICAgICAgICAgICBpZiAoIWFyZ3VtZW50cy5jYWxsZWUuY2FsbChhLCBiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8vZXh0ZW5zaW9ucwoKICAgICAgICAvKgogICAgICAgICAqIGU0eC5qcwogICAgICAgICAqCiAgICAgICAgICogQSBKYXZhU2NyaXB0IGxpYnJhcnkgdGhhdCBpbXBsZW1lbnRzIHRoZSBvcHRpb25hbCBFNFggZmVhdHVyZXMgZGVzY3JpYmVkIGluCiAgICAgICAgICogRUNNQS0zNTcgMm5kIEVkaXRpb24gQW5uZXggQSBpZiB0aGV5IGFyZSBub3QgYWxyZWFkeSBpbXBsZW1lbnRlZC4KICAgICAgICAgKgogICAgICAgICAqIDIwMTAtMDMtMTMKICAgICAgICAgKgogICAgICAgICAqIEJ5IEVsaWphaCBHcmV5LCBodHRwOi8vZWxpZ3JleS5jb20KICAgICAgICAgKiBMaWNlbnNlOiBUaGUgWDExL01JVCBsaWNlbnNlIChzZWUgQ09QWUlORy5tZCkKICAgICAgICAgKgogICAgICAgICAqIENoYW5nZXM6CiAgICAgICAgICogICAgQnkgU2FtIFNodWxsLCBodHRwOi8vc2Ftc2h1bGwuYmxvZ3Nwb3QuY29tCiAgICAgICAgICogICAgSnVzdCBhIGxpdGxsZSBzaW1wbGlmeWluZyBmb3IgaW1wbGVtZW50YXRpb24KICAgICAgICAgKi8KCiAgICAgICAgLypnbG9iYWwgZG9jdW1lbnQsIFhNTCwgWE1MTGlzdCwgRE9NUGFyc2VyLCBYTUxTZXJpYWxpemVyLCBYUGF0aFJlc3VsdCAqLwoKICAgICAgICAvKmpzbGludCB1bmRlZjogdHJ1ZSwgbm9tZW46IHRydWUsIGVxZXFlcTogdHJ1ZSwgYml0d2lzZTogdHJ1ZSwgcmVnZXhwOiB0cnVlLAogICAgICAgICBuZXdjYXA6IHRydWUsIGltbWVkOiB0cnVlLCBtYXhlcnI6IDEwMDAsIG1heGxlbjogOTAgKi8KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5kb21Ob2RlID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBhZG9wdE5vZGUoZG9jdW1lbnQsIHhtbFRvRG9tTm9kZSh0aGlzKSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5kb21Ob2RlTGlzdCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcy5sZW5ndGgoKSA8IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gYWRvcHROb2RlKGRvY3VtZW50LCBjcmVhdGVEb2N1bWVudEZyb20odGhpcykuZG9jdW1lbnRFbGVtZW50KS5jaGlsZE5vZGVzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUueHBhdGggPSBmdW5jdGlvbiAoeHBhdGhFeHApCiAgICAgICAgewogICAgICAgICAgICB2YXIgcmVzID0gbmV3IFhNTExpc3QsCiAgICAgICAgICAgICAgICBpID0gMCwgbCA9IHRoaXMubGVuZ3RoKCksCiAgICAgICAgICAgICAgICB4cHI7CgogICAgICAgICAgICBpZiAobCAhPT0gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzLkFwcGVuZCh0aGlzW2ldLnhwYXRoKHhwYXRoRXhwKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgeHByID0gZXZhbHVhdGUoY3JlYXRlRG9jdW1lbnRGcm9tKHRoaXMpLCB4cGF0aEV4cCwgdGhpcyk7CgogICAgICAgICAgICBmb3IgKGw9eHByLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzLkFwcGVuZChUb1hNTCh4cHJbaV0pKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnRyYW5zZm9ybSA9IGZ1bmN0aW9uICh4c2x0LCBwYXJhbXMpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIXhzbHQgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGRvYywgcmVzLCBpLCBsID0gdGhpcy5sZW5ndGgoKSwgYzsKCiAgICAgICAgICAgIGlmIChsID4gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzID0gbmV3IFhNTExpc3QoKTsKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzLkFwcGVuZCh0aGlzW2ldLnRyYW5zZm9ybSh4c2x0LCBwYXJhbXMpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm0odGhpcywgeHNsdCwgcGFyYW1zKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFhNTExpc3QgKCRzdHJpbmcpCiAgICAgICAgewogICAgICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgWE1MTGlzdCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBUb1hNTExpc3QoJHN0cmluZyB8fCAiIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX0NsYXNzID0gIlhNTExpc3QiOwoKICAgICAgICAgICAgdGhpcy5fVmFsdWUgPSB1bmRlZmluZWQ7CgoKICAgICAgICAgICAgdGhpcy5fVGFyZ2V0T2JqZWN0ID0gbnVsbDsKCiAgICAgICAgICAgIHRoaXMuX1RhcmdldFByb3BlcnR5ID0gbnVsbDsKCiAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuID0gW107CgogICAgICAgICAgICB0aGlzWzBdID0gbnVsbDsKCiAgICAgICAgICAgIGlmICgkc3RyaW5nKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgbGlzdCA9IFRvWE1MTGlzdCgkc3RyaW5nKSwgaSA9IDAsIGwgPSBsaXN0Ll9DaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgICAgICB0aGlzLl9WYWx1ZSA9IGxpc3QuX1ZhbHVlOwoKICAgICAgICAgICAgICAgIGZvciAoO2kgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0gPSB0aGlzW2ldID0gbGlzdC5fQ2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnRvU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAiZnVuY3Rpb24gWE1MTGlzdCgpIHtcbiBbbmF0aXZlIGNvZGVdIFxufSI7CiAgICAgICAgfTsKCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUgPSBuZXcgWE1MKCk7CgogICAgICAgIHZhciBpZ25vcmUgPSB7eHBhdGg6MSxkb21Ob2RlTGlzdDoxLHRyYW5zZm9ybToxfTsKCiAgICAgICAgZm9yIChwIGluIFhNTExpc3QucHJvdG90eXBlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGlnbm9yZVtwXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFhNTExpc3QucHJvdG90eXBlW3BdID0gKGZ1bmN0aW9uKHApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggIT0gMSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoImNhbm5vdCBjYWxsICIgKyBwICsgIiBtZXRob2Qgb24gYW4gWE1MIGxpc3Qgd2l0aCAiICsgdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoICsgIiBlbGVtZW50cyIpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTC5wcm90b3R5cGVbcF0uYXBwbHkodGhpc1swXSwgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0pKHApOwogICAgICAgIH0KCiAgICAgICAgdHJ5ewogICAgICAgICAgICBkZWxldGUgWE1MTGlzdC5wcm90b3R5cGUuX0F0dHJpYnV0ZXM7CiAgICAgICAgICAgIGRlbGV0ZSBYTUxMaXN0LnByb3RvdHlwZS5fSW5TY29wZU5hbWVzcGFjZXM7CiAgICAgICAgfWNhdGNoKGUpe30KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBBdHRyaWJ1dGVOYW1lIGF0dHJpYnV0ZU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuYXR0cmlidXRlID0gZnVuY3Rpb24gKGF0dHJpYnV0ZU5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gR2V0TGlzdC5jYWxsKHRoaXMsIFRvQXR0cmlidXRlTmFtZShhdHRyaWJ1dGVOYW1lKSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5hdHRyaWJ1dGVzID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBHZXRMaXN0LmNhbGwodGhpcywgVG9BdHRyaWJ1dGVOYW1lKCIqIikpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgcHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLmNoaWxkID0gZnVuY3Rpb24gKHByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIHI7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHRoaXM7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgciA9IHRoaXNbaV0uY2hpbGQocHJvcGVydHlOYW1lKTsKCiAgICAgICAgICAgICAgICBpZiAoci5fQ2hpbGRyZW4ubGVuZ3RoID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5jaGlsZHJlbiA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gR2V0TGlzdC5jYWxsKHRoaXMsICIqIik7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5jb21tZW50cyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCByOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHIgPSB0aGlzW2ldLmNvbW1lbnRzKCk7CgogICAgICAgICAgICAgICAgICAgIGlmIChyLl9DaGlsZHJlbi5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQocik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFhNTCB2YWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uICh2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXSA9PSB2YWx1ZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRGVlcENvcHlMaXN0LmNhbGwodGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLmRlc2NlbmRhbnRzID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRGVzY2VuZGFudHNMaXN0LmNhbGwodGhpcywgbmFtZSB8fCAiKiIpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5lbGVtZW50cyA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgbmFtZSA9IFRvWE1MTmFtZShuYW1lIHx8ICIqIik7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIHI7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHRoaXM7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldFByb3BlcnR5ID0gbmFtZTsKCiAgICAgICAgICAgIGZvciAoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByID0gdGhpc1tpXS5lbGVtZW50cyhuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHIuX0NoaWxkcmVuLmxlbmd0aCA+IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBIYXNQcm9wZXJ0eS5jYWxsKHRoaXMsIG5hbWUpCiAgICAgICAgICAgICAgICB8fCAoZGVmYXVsdFhNTExpc3RQcm9wZXJ0aWVzLmluZGV4T2YoIiwiICsgbmFtZSArICIsIikgPT09IC0xICYmIGhhc093blByb3BlcnR5LmNhbGwodGhpcywgbmFtZSkpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuaGFzQ29tcGxleENvbnRlbnQgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW4ubGVuZ3RoID09PSAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpc1swXS5oYXNDb21wbGV4Q29udGVudCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5oYXNTaW1wbGVDb250ZW50ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggPT09IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzWzBdLmhhc1NpbXBsZUNvbnRlbnQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBOdW1iZXIKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzW2ldLm5vcm1hbGl6ZSgpOwogICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXNbaV0uX0NsYXNzID09PSAidGV4dCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGkrMSA8IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCAmJiB0aGlzW2krMV0uX0NsYXNzID09PSAidGV4dCIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2ldLl9WYWx1ZSA9ICh0aGlzW2ldLl9WYWx1ZSB8fCAiIikgKyAodGhpc1tpKzFdLl9WYWx1ZSB8fCAiIik7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuRGVsZXRlKGkrMSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fVmFsdWUubGVuZ3RoID09PSAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5EZWxldGUoaSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgKytpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MIHwgdW5kZWZpbmVkCiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUucGFyZW50ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggPT09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIHBhcmVudCA9IHRoaXNbMF0uX1BhcmVudCwgaSA9IDEsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9QYXJlbnQgIT0gcGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBwYXJlbnQ7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnByb2Nlc3NpbmdJbnN0cnVjdGlvbnMgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIG5hbWUgPSBUb1hNTE5hbWUobmFtZSB8fCAiKiIpOwogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCByOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHIgPSB0aGlzW2ldLnByb2Nlc3NpbmdJbnN0cnVjdGlvbnMobmFtZSk7CgogICAgICAgICAgICAgICAgICAgIGlmIChyLl9DaGlsZHJlbi5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQocik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IE51bWJlciBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQobmFtZSkgPiAwICYmIHBhcnNlSW50KG5hbWUpIDwgdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUudGV4dCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCByOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHIgPSB0aGlzW2ldLnRleHQoKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHIuX0NoaWxkcmVuLmxlbmd0aCA+IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVG9TdHJpbmcodGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnRvWE1MU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUb1hNTFN0cmluZyh0aGlzKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnZhbHVlT2YgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IE51bWJlciB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgVmFsdWUKICAgICAgICAgKiAgICBAcGFyYW0gaXNFbGVtZW50CiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLlB1dCA9IGZ1bmN0aW9uIChQcm9wZXJ0eU5hbWUsIFZhbHVlLGlzQ2hpbGRFbGVtZW50KQogICAgICAgIHsKICAgICAgICAgICAgaXNDaGlsZEVsZW1lbnQgPSBpc0NoaWxkRWxlbWVudCAhPT0gdW5kZWZpbmVkID8gaXNDaGlsZEVsZW1lbnQgOiBmYWxzZTsKICAgICAgICAgICAgdmFyIGkgPSBwYXJzZUludChQcm9wZXJ0eU5hbWUpLCByLCB5LCBsLCB6LCBwYXJlbnQsIGMsIGogPSAwLCBxLCB0OwoKICAgICAgICAgICAgaWYgKGkrIiIgPT0gUHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByID0gUmVzb2x2ZVZhbHVlLmNhbGwodGhpcy5fVGFyZ2V0T2JqZWN0KTsKICAgICAgICAgICAgICAgIC8qIEZpcmVmb3ggZG9lc24ndCBkbyB0aGlzCiAgICAgICAgICAgICAgICAgaWYgKHIgPT0gbnVsbCkKICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoaSA+PSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHIubGVuZ3RoKCkgIT0gMSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHIgPSByWzBdOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLyogRmlyZWZveCBkb2Vzbid0IGRvIHRoaXMKICAgICAgICAgICAgICAgICAgICAgaWYgKHIuX0NsYXNzICE9ICJlbGVtZW50IikKICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHkgPSBuZXcgWE1MKCk7CiAgICAgICAgICAgICAgICAgICAgeS5fUGFyZW50ID0gcjsKICAgICAgICAgICAgICAgICAgICB5Ll9OYW1lID0gdGhpcy5fVGFyZ2V0UHJvcGVydHk7CiAgICAgICAgICAgICAgICAgICAgeS5fQXR0cmlidXRlcyA9IHt9OwoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fVGFyZ2V0UHJvcGVydHkgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhciAmJiBHZXQuY2FsbChyLCB5Ll9OYW1lKS5sZW5ndGgoKSA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB5Ll9DbGFzcyA9ICJhdHRyaWJ1dGUiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghaXNDaGlsZEVsZW1lbnQgJiYgKHRoaXMuX1RhcmdldFByb3BlcnR5ID09IG51bGwgfHwgdGhpcy5fVGFyZ2V0UHJvcGVydHkubG9jYWxOYW1lID09PSAiKiIpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgeS5fTmFtZSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIHkuX0NsYXNzID0gInRleHQiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB5Ll9DbGFzcyA9ICJlbGVtZW50IjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh5Ll9DbGFzcyAhPSAiYXR0cmlidXRlIikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqID0gMDsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGogPCByLl9DaGlsZHJlbi5sZW5ndGgtMSAmJiByW2pdICE9PSB0aGlzW2ktMV0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArK2o7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGogPSByLl9DaGlsZHJlbi5sZW5ndGggLSAxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc2VydC5jYWxsKHIsIGorMSwgeSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChWYWx1ZSBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkuX05hbWUgPSBWYWx1ZS5fVGFyZ2V0UHJvcGVydHk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkuX05hbWUgPSBWYWx1ZS5fTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhpcy5BcHBlbmQoeSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCEoVmFsdWUgaW5zdGFuY2VvZiBYTUwpIHx8IFZhbHVlLl9DbGFzcyA9PT0gInRleHQiIHx8IFZhbHVlLl9DbGFzcyA9PT0gImF0dHJpYnV0ZSIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVmFsdWUgPSBUb1N0cmluZyhWYWx1ZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHRoaXNbaV0uX0NsYXNzID09PSAiYXR0cmlidXRlIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB6ID0gVG9BdHRyaWJ1dGVOYW1lKHRoaXNbaV0uX05hbWUpOwogICAgICAgICAgICAgICAgICAgIHRoaXNbaV0uX1BhcmVudC5QdXQoeiwgVmFsdWUpOwogICAgICAgICAgICAgICAgICAgIHRoaXNbaV0gPSB0aGlzW2ldLl9QYXJlbnQuYXR0cmlidXRlKHopWzBdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vc2hhbGxvdyBjb3B5PwogICAgICAgICAgICAgICAgICAgIGMgPSBWYWx1ZTsKICAgICAgICAgICAgICAgICAgICBwYXJlbnQgPSB0aGlzW2ldLl9QYXJlbnQ7CgogICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBxID0gdGhpc1tpXS5jaGlsZEluZGV4KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbChwYXJlbnQsIHEsIGMpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gYy5fQ2hpbGRyZW4ubGVuZ3RoOyBqIDwgbDsgKytqKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLl9DaGlsZHJlbltqXSA9IGNbal0gPSBwYXJlbnQuX0NoaWxkcmVuW3Eral07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChjLl9DaGlsZHJlbi5sZW5ndGggPT09IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSBpICsgMSwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaiA8IGw7ICsraikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bai0xXSA9IHRoaXNbai0xXSA9IHRoaXNbal0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGogPiBpOyAtLWopCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHogPSBUb1N0cmluZyhqICsgYy5fQ2hpbGRyZW4ubGVuZ3RoIC0gMSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlblt6XSA9IHRoaXNbel0gPSB0aGlzW2pdOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gYy5fQ2hpbGRyZW4ubGVuZ3RoOyBqIDwgbDsgKytqKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baStqXSA9IHRoaXNbaStqXSA9IGNbal07CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MIHx8ICgiLHRleHQsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uIikuaW5kZXhPZigiLCIgKyB0aGlzW2ldLl9DbGFzcysiLCIpID4gLTEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gISF0aGlzW2ldICYmIHRoaXNbaV0uX1BhcmVudDsKCiAgICAgICAgICAgICAgICAgICAgaWYocGFyZW50KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcSA9IHRoaXNbaV0uY2hpbGRJbmRleCgpOwogICAgICAgICAgICAgICAgICAgICAgICBSZXBsYWNlLmNhbGwocGFyZW50LCBxLCBWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlID0gcGFyZW50Ll9DaGlsZHJlbltxXTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh0b1N0cmluZy5jYWxsKFZhbHVlKSA9PT0gIltvYmplY3QgU3RyaW5nXSIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0ID0gVG9YTUwoVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0Ll9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXSA9IHRoaXNbaV0gPSB0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5BcHBlbmQoWE1MTGlzdChWYWx1ZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIEZpcmVmb3ggZG9lc24ndCBkbyB0aGlzCiAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLmxlbmd0aCgpIDw9IDEpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICBpZiAodGhpcy5sZW5ndGgoKSA9PT0gMCkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIHIgPSBSZXNvbHZlVmFsdWVMaXN0LmNhbGwodGhpcyk7CgogICAgICAgICAgICAgaWYgKHIgPT0gbnVsbCB8fCByLmxlbmd0aCgpICE9IDEpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICB0aGlzLkFwcGVuZChyKTsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIHRoaXNbMF0uUHV0KFByb3BlcnR5TmFtZSwgVmFsdWUpOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgfSovCgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTnVtYmVyIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLkRlbGV0ZSA9IGZ1bmN0aW9uIChQcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICB2YXIgaSA9IHBhcnNlSW50KFByb3BlcnR5TmFtZSksIHBhcmVudCwgcSwgbDsKCiAgICAgICAgICAgIGlmIChpKyIiID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGkgPj0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHBhcmVudCA9IHRoaXNbaV0uX1BhcmVudDsKCiAgICAgICAgICAgICAgICBpZiAocGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9ICJhdHRyaWJ1dGUiKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LkRlbGV0ZShUb0F0dHJpYnV0ZU5hbWUodGhpc1tpXS5fTmFtZSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBEZWxldGVCeUluZGV4LmNhbGwocGFyZW50LCB0aGlzW2ldLmNoaWxkSW5kZXgoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbi5zcGxpY2UoUHJvcGVydHlOYW1lLDEpOwogICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzW1Byb3BlcnR5TmFtZV07CiAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQoKICAgICAgICAgICAgICAgIGZvciAocSA9IGkgKyAxLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW3EtMV0gPSB0aGlzW3EtMV0gPSB0aGlzW3FdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogRmlyZWZveCB3b24ndCBkbyB0aGlzCiAgICAgICAgICAgICBmb3IgKHEgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICAgewogICAgICAgICAgICAgaWYgKHRoaXNbcV0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICB0aGlzW3FdLkRlbGV0ZShQcm9wZXJ0eU5hbWUpOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBWYWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5BcHBlbmQgPSBmdW5jdGlvbiAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIShWYWx1ZSBpbnN0YW5jZW9mIFhNTCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgaSA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCwgbiA9IDEsIGogPSAwOwoKICAgICAgICAgICAgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbiA9IFZhbHVlLl9DaGlsZHJlbi5sZW5ndGg7CgogICAgICAgICAgICAgICAgaWYgKG4gPT0gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLl9UYXJnZXRPYmplY3QgPSBWYWx1ZS5fVGFyZ2V0T2JqZWN0OwogICAgICAgICAgICAgICAgdGhpcy5fVGFyZ2V0UHJvcGVydHkgPSBWYWx1ZS5fVGFyZ2V0UHJvcGVydHk7CgogICAgICAgICAgICAgICAgZm9yICg7aiA8IG47ICsraikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpK2pdID0gdGhpc1tpK2pdID0gVmFsdWVbal07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXSA9IHRoaXNbaV0gPSBWYWx1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBWYWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5FcXVhbHMgPSBmdW5jdGlvbiAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoVmFsdWUgPT0gdW5kZWZpbmVkICYmIHRoaXMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUxMaXN0ICYmIFZhbHVlLl9DaGlsZHJlbi5sZW5ndGggPT09IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzW2ldLkVxdWFscyhWYWx1ZVtpXSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXNbMF0uRXF1YWxzKFZhbHVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBSZXNvbHZlVmFsdWVMaXN0ICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW4ubGVuZ3RoID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh0aGlzLl9UYXJnZXRPYmplY3QgPT0gbnVsbAogICAgICAgICAgICAgICAgfHwgdGhpcy5fVGFyZ2V0UHJvcGVydHkgPT0gbnVsbAogICAgICAgICAgICAgICAgfHwgdGhpcy5fVGFyZ2V0UHJvcGVydHkgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lCiAgICAgICAgICAgICAgICB8fCB0aGlzLl9UYXJnZXRQcm9wZXJ0eS5sb2NhbE5hbWUgPT09ICIqIgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGJhc2UgPSBSZXNvbHZlVmFsdWUuY2FsbCh0aGlzLl9UYXJnZXRPYmplY3QpLCB0YXJnZXQ7CgogICAgICAgICAgICBpZiAoYmFzZSA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGFyZ2V0ID0gR2V0LmNhbGwoYmFzZSwgdGhpcy5fVGFyZ2V0UHJvcGVydHkpOwoKICAgICAgICAgICAgaWYgKHRhcmdldC5fQ2hpbGRyZW4ubGVuZ3RoID09PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoYmFzZSBpbnN0YW5jZW9mIFhNTExpc3QgJiYgYmFzZS5fQ2hpbGRyZW4ubGVuZ3RoID4gMSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBiYXNlLlB1dCh0aGlzLl9UYXJnZXRQcm9wZXJ0eSwgIiIpOwoKICAgICAgICAgICAgICAgIHRhcmdldCA9IEdldC5jYWxsKGJhc2UsIHRoaXMuX1RhcmdldFByb3BlcnR5KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRhcmdldDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IE5hbWVzcGFjZSB8IFFOYW1lIHByZWZpeAogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgdXJpCiAgICAgICAgICogICAgQHJldHVybnMgTmFtZXNwYWNlCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBOYW1lc3BhY2UgKHByZWZpeCwgdXJpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIE5hbWVzcGFjZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBwcmVmaXggJiYgcHJlZml4IGluc3RhbmNlb2YgTmFtZXNwYWNlCiAgICAgICAgICAgICAgICAgICAgPyBwcmVmaXgKICAgICAgICAgICAgICAgICAgICA6IG5ldyBOYW1lc3BhY2UocHJlZml4LCB1cmkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodXJpID09PSB1bmRlZmluZWQgJiYgcHJlZml4ID09PSB1bmRlZmluZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRoaXMucHJlZml4ID0gIiI7CiAgICAgICAgICAgICAgICB0aGlzLnVyaSA9ICIiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHVyaSA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB1cmkgPSBwcmVmaXg7CiAgICAgICAgICAgICAgICBwcmVmaXggPSB1bmRlZmluZWQ7CgogICAgICAgICAgICAgICAgaWYgKHVyaSBpbnN0YW5jZW9mIE5hbWVzcGFjZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnByZWZpeCA9IHVyaS5wcmVmaXg7CiAgICAgICAgICAgICAgICAgICAgdGhpcy51cmkgPSB1cmkudXJpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAodXJpIGluc3RhbmNlb2YgUU5hbWUgJiYgdXJpLnVyaSAhPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVyaSA9IHVyaS51cmk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy51cmkgPSBUb1N0cmluZyh1cmkpOwoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy51cmkgPT0gIiIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZWZpeCA9ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh1cmkgaW5zdGFuY2VvZiBRTmFtZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVyaSA9IHVyaS51cmk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy51cmkgPSBUb1N0cmluZyh1cmkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICh0aGlzLnVyaSA9PT0gIiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHByZWZpeCA9PT0gdW5kZWZpbmVkIHx8IFRvU3RyaW5nKHByZWZpeCkgPT09ICIiKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmVmaXggPSAiIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigiY2Fubm90IGRlZmluZSB0aGUgcHJlZml4IGZvciBhbiBlbXB0eSB1cmkiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChwcmVmaXggPT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnByZWZpeCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnByZWZpeCA9IFRvU3RyaW5nKHByZWZpeCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAdmFyIFN0cmluZwogICAgICAgICAqLwogICAgICAgIE5hbWVzcGFjZS5wcm90b3R5cGUucHJlZml4ID0gdW5kZWZpbmVkOwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHZhciBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBOYW1lc3BhY2UucHJvdG90eXBlLnVyaSA9IHVuZGVmaW5lZDsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIE5hbWVzcGFjZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMudXJpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gTmFtZXNwYWNlIHwgU3RyaW5nIHwgUU5hbWUgTmFtZVNwYWNlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZwogICAgICAgICAqICAgIEByZXR1cm5zIFFOYW1lCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gUU5hbWUgKE5hbWVTcGFjZSwgTmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBRTmFtZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBOYW1lU3BhY2UgaW5zdGFuY2VvZiBRTmFtZQogICAgICAgICAgICAgICAgICAgID8gTmFtZVNwYWNlCiAgICAgICAgICAgICAgICAgICAgOiBuZXcgUU5hbWUoTmFtZVNwYWNlLCBOYW1lKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKE5hbWUgPT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTmFtZSA9IE5hbWVTcGFjZTsKICAgICAgICAgICAgICAgIE5hbWVTcGFjZSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKE5hbWVzcGFjZSBpbnN0YW5jZW9mIFFOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoTmFtZSA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE5hbWUgPSBOYW1lLmxvY2FsTmFtZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgTmFtZSA9IE5hbWUgPT09IHVuZGVmaW5lZCB8fCBOYW1lID09PSBudWxsCiAgICAgICAgICAgICAgICA/ICIiCiAgICAgICAgICAgICAgICA6IFRvU3RyaW5nKE5hbWUpOwoKICAgICAgICAgICAgaWYgKE5hbWVTcGFjZSA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBOYW1lU3BhY2UgPSBOYW1lID09PSAiKiIgPyBudWxsIDogR2V0RGVmYXVsdE5hbWVzcGFjZSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLmxvY2FsTmFtZSA9IE5hbWU7CgogICAgICAgICAgICBpZiAoTmFtZVNwYWNlID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRoaXMudXJpID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE5hbWVTcGFjZSA9IE5hbWVzcGFjZShOYW1lU3BhY2UpOwogICAgICAgICAgICAgICAgdGhpcy51cmkgPSBOYW1lU3BhY2UudXJpOwogICAgICAgICAgICAgICAgdGhpcy5fUHJlZml4ID0gTmFtZVNwYWNlLnByZWZpeDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEB2YXIgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgUU5hbWUucHJvdG90eXBlLmxvY2FsTmFtZSA9IHVuZGVmaW5lZDsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEB2YXIgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgUU5hbWUucHJvdG90eXBlLnVyaSA9IHVuZGVmaW5lZDsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBPYmplY3QgSW5TY29wZU5hbWVzcGFjZXMKICAgICAgICAgKiAgICBAcmV0dXJucyBOYW1lc3BhY2UKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEdldE5hbWVzcGFjZSAocSwgSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgewogICAgICAgICAgICBpZighcSkKICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE5hbWVzcGFjZSgpOwogICAgICAgICAgICBpZiAocS51cmkgPT09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSW5TY29wZU5hbWVzcGFjZXMgPSBJblNjb3BlTmFtZXNwYWNlcyB8fCB7fTsKCiAgICAgICAgICAgIHZhciBucywgcDsKCiAgICAgICAgICAgIGZvciAocCBpbiBJblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHEudXJpID09PSBJblNjb3BlTmFtZXNwYWNlc1twXS51cmkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbnMgPSBJblNjb3BlTmFtZXNwYWNlc1twXTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCEhcS5fUHJlZml4ICYmIHEuX1ByZWZpeCA9PT0gbnMucHJlZml4KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5zOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFucykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbnMgPSAhIXEuX1ByZWZpeAogICAgICAgICAgICAgICAgICAgID8gbmV3IE5hbWVzcGFjZShxLl9QcmVmaXgsIHEudXJpKQogICAgICAgICAgICAgICAgICAgIDogbmV3IE5hbWVzcGFjZShxLnVyaSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBuczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgUU5hbWUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMudXJpCiAgICAgICAgICAgICAgICA/IHRoaXMudXJpICsgIjo6IiArIHRoaXMubG9jYWxOYW1lCiAgICAgICAgICAgICAgICA6IHRoaXMubG9jYWxOYW1lOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gQXR0cmlidXRlTmFtZSB8IFFOYW1lIHwgU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBBdHRyaWJ1dGVOYW1lCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gQXR0cmlidXRlTmFtZSAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5hbWUgJiYgKG5hbWUgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lIHx8IG5hbWUgaW5zdGFuY2VvZiBRTmFtZSkKICAgICAgICAgICAgICAgICAgICA/IG5hbWUKICAgICAgICAgICAgICAgICAgICA6IG5ldyBBdHRyaWJ1dGVOYW1lKG5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLl9OYW1lID0gbmFtZSBpbnN0YW5jZW9mIFFOYW1lCiAgICAgICAgICAgICAgICA/IG5hbWUKICAgICAgICAgICAgICAgIDogbmV3IFFOYW1lKG5ldyBOYW1lc3BhY2UoR2V0RGVmYXVsdE5hbWVzcGFjZSgpfHx1bmRlZmluZWQpLCBuYW1lKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAdmFyIFN0cmluZwogICAgICAgICAqLwogICAgICAgIEF0dHJpYnV0ZU5hbWUucHJvdG90eXBlLmxvY2FsTmFtZSA9IHVuZGVmaW5lZDsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEB2YXIgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgQXR0cmlidXRlTmFtZS5wcm90b3R5cGUudXJpID0gdW5kZWZpbmVkOwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgQXR0cmlidXRlTmFtZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICJAIiArICghIXRoaXMuX05hbWUudXJpCiAgICAgICAgICAgICAgICA/IHRoaXMuX05hbWUudXJpICsgIjo6IiArIHRoaXMuX05hbWUubG9jYWxOYW1lCiAgICAgICAgICAgICAgICA6IHRoaXMuX05hbWUubG9jYWxOYW1lCiAgICAgICAgICAgICAgICApOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEFueU5hbWUgKCkKICAgICAgICB7CgogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBtaXhlZCB2YWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBpc1hNTE5hbWUgKHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgIHZhciBxID0gUU5hbWUodmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhdGNoIChlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAhIXEubG9jYWxOYW1lICYmICghIXEubG9jYWxOYW1lLm1hdGNoKC9eW1x3XC1dKyQvaSkgfHwgISFxLmxvY2FsTmFtZS5tYXRjaCgvXltcd1wtXDpdKyQvaSkpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBtaXhlZCB2YWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gVG9TdHJpbmcgKHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGkgPSAwLCBsLCBzOwoKICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHZhbHVlLmhhc1NpbXBsZUNvbnRlbnQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzID0gIiI7CgogICAgICAgICAgICAgICAgICAgIGZvciAobCA9IHZhbHVlLmxlbmd0aCgpOyBpIDwgbDsgKytpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlW2ldLl9DbGFzcyAhPSAiY29tbWVudCIgJiYgdmFsdWVbaV0uX0NsYXNzICE9ICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSBUb1N0cmluZyh2YWx1ZVtpXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBUb1hNTFN0cmluZyh2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5fQ2xhc3MgPT09ICJhdHRyaWJ1dGUiIHx8IHZhbHVlLl9DbGFzcyA9PT0gInRleHQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5fVmFsdWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHZhbHVlLmhhc1NpbXBsZUNvbnRlbnQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzID0gIiI7CgogICAgICAgICAgICAgICAgICAgIGZvciAobCA9IHZhbHVlLmxlbmd0aCgpOyBpIDwgbDsgKytpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmNoaWxkKGkpLl9DbGFzcyAhPSAiY29tbWVudCIgJiYgdmFsdWUuY2hpbGQoaSkuX0NsYXNzICE9ICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSBUb1N0cmluZyh2YWx1ZS5jaGlsZChpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBUb1hNTFN0cmluZyh2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIkAiICsgVG9TdHJpbmcodmFsdWUuX05hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZAogICAgICAgICAgICAgICAgPyAiIgogICAgICAgICAgICAgICAgOiAiIiArIHZhbHVlOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBYTUwgaW5wdXQKICAgICAgICAgKiAgICBAcGFyYW0gT2JqZWN0IEFuY2VzdG9yTmFtZXNwYWNlcwogICAgICAgICAqICAgIEBwYXJhbSBOdW1iZXIgSW5kZW50TGV2ZWwKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBUb1hNTFN0cmluZyAoaW5wdXQsIEFuY2VzdG9yTmFtZXNwYWNlcywgSW5kZW50TGV2ZWwpCiAgICAgICAgewogICAgICAgICAgICB2YXIgcyA9ICIiLCBwID0gMCwgdGVtcCwgdGVtcDIsIG5hbWVzcGFjZSwgbmFtZXNwYWNlVW5pb24sCiAgICAgICAgICAgICAgICBuYW1lc3BhY2VEZWNsYXJhdGlvbnMgPSB7fSwgYXR0ckFuZE5hbWVzcGFjZXMsIHByZWZpeGVzLCBkZWZhdWx0U2V0OwoKICAgICAgICAgICAgQW5jZXN0b3JOYW1lc3BhY2VzID0gQW5jZXN0b3JOYW1lc3BhY2VzIHx8IHt9OwoKICAgICAgICAgICAgSW5kZW50TGV2ZWwgPSBOdW1iZXIoSW5kZW50TGV2ZWwgfHwgMCk7CgogICAgICAgICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0ZW1wID0gaW5wdXQuaGFzU2ltcGxlQ29udGVudCgpOwoKICAgICAgICAgICAgICAgIHRlbXAyID0gaW5wdXQubGVuZ3RoKCk7CgogICAgICAgICAgICAgICAgZm9yICg7IHAgPCB0ZW1wMjsgKytwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChwID4gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gIlxyXG4iOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcyArPSBUb1hNTFN0cmluZyhpbnB1dFtwXSwgQW5jZXN0b3JOYW1lc3BhY2VzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChpbnB1dCBpbnN0YW5jZW9mIFhNTCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKFhNTC5wcmV0dHlQcmludGluZykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvL3MgKz0gbmV3IEFycmF5KEluZGVudExldmVsKzEpLmpvaW4oIiAiKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKDsgcCA8IEluZGVudExldmVsOyArK3ApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzICs9ICIgIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgc3dpdGNoIChpbnB1dC5fQ2xhc3MpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAidGV4dCI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzICsgRXNjYXBlRWxlbWVudFZhbHVlKFhNTC5wcmV0dHlQcmludGluZyA/IHRyaW0oaW5wdXQuX1ZhbHVlKSA6IGlucHV0Ll9WYWx1ZSk7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgImF0dHJpYnV0ZSI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzICsgRXNjYXBlQXR0cmlidXRlVmFsdWUoaW5wdXQuX1ZhbHVlKTsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAiY29tbWVudCI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzICsgIjwhLS0iICsgaW5wdXQuX1ZhbHVlICsgIi0tPiI7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcyArICI8PyIgKyBpbnB1dC5fTmFtZS5sb2NhbE5hbWUgKyAiICIgKyBpbnB1dC5fVmFsdWUgKyAiPz4iOwoKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VVbmlvbiA9IGV4dGVuZCh7fSwgQW5jZXN0b3JOYW1lc3BhY2VzKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAocCBpbiBpbnB1dC5fSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAgPSBpbnB1dC5fSW5TY29wZU5hbWVzcGFjZXNbcF07CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFBbmNlc3Rvck5hbWVzcGFjZXNbKHRlbXAucHJlZml4fHwiIildIHx8IEFuY2VzdG9yTmFtZXNwYWNlc1sodGVtcC5wcmVmaXh8fCIiKV0udXJpICE9IHRlbXAudXJpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVuaW9uWyh0ZW1wLnByZWZpeHx8IiIpXSA9IG5hbWVzcGFjZURlY2xhcmF0aW9uc1sodGVtcC5wcmVmaXh8fCIiKV0gPSBuZXcgTmFtZXNwYWNlKHRlbXApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlucHV0Ll9QYXJlbnQpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVuaW9uWyhpbnB1dC5fRGVmYXVsdE5hbWVzcGFjZS5wcmVmaXh8fCIiKV0gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZURlY2xhcmF0aW9uc1soaW5wdXQuX0RlZmF1bHROYW1lc3BhY2UucHJlZml4fHwiIildID0gbmV3IE5hbWVzcGFjZShpbnB1dC5fRGVmYXVsdE5hbWVzcGFjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmlyZWZveCBkb2Vzbid0IGRvIHRoaXMKICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAocCBpbiBpbnB1dC5fQXR0cmlidXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSA9IEdldE5hbWVzcGFjZShpbnB1dC5fQXR0cmlidXRlc1twXS5fTmFtZSwgbmFtZXNwYWNlVW5pb24pOwoKICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2UucHJlZml4ID09PSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UucHJlZml4ID0gIW5hbWVzcGFjZVVuaW9uWyIiXSA/ICIiIDogbmV3UHJlZml4KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSghIW5hbWVzcGFjZVVuaW9uW25hbWVzcGFjZS5wcmVmaXhdKTsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VVbmlvbltuYW1lc3BhY2UucHJlZml4XSA9IG5hbWVzcGFjZURlY2xhcmF0aW9uc1tuYW1lc3BhY2UucHJlZml4XSA9IG5hbWVzcGFjZTsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgICAgICAgICBzICs9ICI8IjsKCiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSA9IEdldE5hbWVzcGFjZShpbnB1dC5fTmFtZSwgbmFtZXNwYWNlRGVjbGFyYXRpb25zKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2UucHJlZml4KQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9IG5hbWVzcGFjZS5wcmVmaXggKyAiOiI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gaW5wdXQuX05hbWUgPyBpbnB1dC5fTmFtZS5sb2NhbE5hbWUgOiAiIjsKCiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJBbmROYW1lc3BhY2VzID0gZXh0ZW5kKHt9LCBpbnB1dC5fQXR0cmlidXRlcywgbmFtZXNwYWNlRGVjbGFyYXRpb25zKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRTZXQgPSBmYWxzZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAocCBpbiBhdHRyQW5kTmFtZXNwYWNlcykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiICI7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJBbmROYW1lc3BhY2VzW3BdIGluc3RhbmNlb2YgWE1MKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAgPSBHZXROYW1lc3BhY2UoYXR0ckFuZE5hbWVzcGFjZXNbcF0uX05hbWUsIEFuY2VzdG9yTmFtZXNwYWNlcyk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wLnByZWZpeCA9PT0gdW5kZWZpbmVkICYmICFuYW1lc3BhY2VVbmlvblsiIl0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3sKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAucHJlZml4ID0gIW5hbWVzcGFjZVVuaW9uWyIiXSA/ICIiIDogbmV3UHJlZml4KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUobmFtZXNwYWNlVW5pb25bdGVtcC5wcmVmaXhdKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVuaW9uW3RlbXAucHJlZml4XSA9IG5hbWVzcGFjZURlY2xhcmF0aW9uc1t0ZW1wLnByZWZpeF0gPSBuZXcgTmFtZXNwYWNlKHRlbXApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAucHJlZml4KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSB0ZW1wLnByZWZpeCArICI6IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gYXR0ckFuZE5hbWVzcGFjZXNbcF0ubG9jYWxOYW1lKCkgKyAnPSInICsgRXNjYXBlQXR0cmlidXRlVmFsdWUoYXR0ckFuZE5hbWVzcGFjZXNbcF0uX1ZhbHVlKSArICciJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICJ4bWxucyI7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4ICYmIGRlZmF1bHRTZXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3sKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJBbmROYW1lc3BhY2VzW3BdLnByZWZpeCA9IG5ld1ByZWZpeCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlKCEhbmFtZXNwYWNlVW5pb25bYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4XSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VVbmlvblthdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXhdID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZURlY2xhcmF0aW9uc1thdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXhdID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTmFtZXNwYWNlKGF0dHJBbmROYW1lc3BhY2VzW3BdKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gIjoiICsgYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4ICYmICFkZWZhdWx0U2V0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFNldCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGF0dHJBbmROYW1lc3BhY2VzW3BdLnByZWZpeCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gIjoiICsgYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAnPSInICsgRXNjYXBlQXR0cmlidXRlVmFsdWUoYXR0ckFuZE5hbWVzcGFjZXNbcF0udXJpKSArICciJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGlucHV0Ll9DaGlsZHJlbi5sZW5ndGg7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRlbXApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzICsgIi8+IjsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiPiI7CgogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHRlbXAgPiAxIHx8ICh0ZW1wID09IDEgJiYgaW5wdXQuX0NsYXNzICE9PSAidGV4dCIpOwoKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMgPSAoISFYTUwucHJldHR5UHJpbnRpbmcgJiYgISF0ZW1wMikgPyBJbmRlbnRMZXZlbCArIE51bWJlcihYTUwucHJldHR5SW5kZW50KSA6IDA7CgogICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXhlcyA9ICEhWE1MLnByZXR0eVByaW50aW5nICYmICEhdGVtcDI7CgogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHAgPSAwOyBwIDwgdGVtcDsgKytwKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJlZml4ZXMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiXHJcbiI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlucHV0Ll9DaGlsZHJlbltwXSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9IFRvWE1MU3RyaW5nKGlucHV0Ll9DaGlsZHJlbltwXSwgbmFtZXNwYWNlRGVjbGFyYXRpb25zLCBuYW1lcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVmaXhlcykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiXHJcbiI7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChwID0gMDsgcCA8IEluZGVudExldmVsOyArK3ApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiICI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzICsgIjwvIiArIChuYW1lc3BhY2UucHJlZml4ID8gbmFtZXNwYWNlLnByZWZpeCArICI6IiA6ICIiKSArIGlucHV0Ll9OYW1lLmxvY2FsTmFtZSArICI+IjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoaW5wdXQgPT09IHVuZGVmaW5lZCB8fCBpbnB1dCA9PT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHRvU3RyaW5nLmNhbGwoaW5wdXQpID09PSAiW29iamVjdCBPYmplY3RdIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIEVzY2FwZUVsZW1lbnRWYWx1ZSggaW5wdXQudmFsdWVPZigpLnRvU3RyaW5nKCkgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIFRvU3RyaW5nKGlucHV0KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gbWl4ZWQgcwogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqICAgIEB0aHJvd3MgU3ludGF4RXJyb3IgfCBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBUb1hNTCAocykKICAgICAgICB7CiAgICAgICAgICAgIHZhciB4LCBkaXY7CgogICAgICAgICAgICBpZiAocyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChzLmxlbmd0aCgpID09IDEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNbMF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocyBpbnN0YW5jZW9mIFhNTCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoKCIsc3RyaW5nLG51bWJlcixib29sZWFuLCIpLmluZGV4T2YoIiwiICsgdHlwZW9mKHMpKyIsIikgPiAtMSkKICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgIGRpdiA9IHBhcnNlKCc8cGFyZW50IHhtbG5zPSInICsgR2V0RGVmYXVsdE5hbWVzcGFjZSgpICsgJyI+JyArIHMgKyAnPC9wYXJlbnQ+Jyk7CgogICAgICAgICAgICAgICAgeCA9IFRvWE1MKGRpdi5kb2N1bWVudEVsZW1lbnQpCgogICAgICAgICAgICAgICAgaWYgKHgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHgubGVuZ3RoKCkgPT0gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgWE1MKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHgubGVuZ3RoKCkgPT0gMSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHguY2hpbGQoMCkuX1BhcmVudCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB4LmNoaWxkKDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCJGYWlsZWQgdG8gY29udmVydCBET00gb2JqZWN0IHRvIFhNTCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHMubm9kZVR5cGUgJiYgIWlzTmFOKHMubm9kZVR5cGUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gTWFwSW5mb0l0ZW1Ub1hNTChzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBET01Ob2RlIGkKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIE1hcEluZm9JdGVtVG9YTUwgKGksbikKICAgICAgICB7CiAgICAgICAgICAgIHZhciB4ID0gbmV3IFhNTCgpLCB0ZW1wLCB0ZW1wMiwgdGVtcDMsIGlzTlNjaGVjayA9IGlzTlNEZWYsIGosIGwsIHhtbENoaWxkOwoKICAgICAgICAgICAgeC5fUGFyZW50ID0gbnVsbDsKCiAgICAgICAgICAgIHN3aXRjaCAoaS5ub2RlVHlwZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSBURVhUX05PREU6CiAgICAgICAgICAgICAgICBjYXNlIENEQVRBX1NFQ1RJT05fTk9ERToKICAgICAgICAgICAgICAgICAgICB4Ll9DbGFzcyA9ICJ0ZXh0IjsKICAgICAgICAgICAgICAgICAgICB4Ll9WYWx1ZSA9ICIiOwogICAgICAgICAgICAgICAgICAgIHRlbXAgPSBpOwoKICAgICAgICAgICAgICAgICAgICB3aGlsZSAodGVtcCAmJiAodGVtcC5ub2RlVHlwZSA9PT0gVEVYVF9OT0RFIHx8IHRlbXAubm9kZVR5cGUgPT09IENEQVRBX1NFQ1RJT05fTk9ERSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB4Ll9WYWx1ZSArPSB0ZW1wLnRleHRDb250ZW50IHx8IHRlbXAudGV4dCB8fCB0ZW1wLmRhdGE7CiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAgPSB0ZW1wLm5leHRTaWJsaW5nOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobiAmJiAobi5uIHx8IG4ubiA9PSAwKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgKytuLm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgoKICAgICAgICAgICAgICAgICAgICBpZiAoWE1MLmlnbm9yZVdoaXRlc3BhY2UgJiYgIXguX1ZhbHVlLm1hdGNoKC9cUysvKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHg7CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBDT01NRU5UX05PREU6CiAgICAgICAgICAgICAgICAgICAgaWYgKFhNTC5pZ25vcmVDb21tZW50cykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeC5fQ2xhc3MgPSAiY29tbWVudCI7CiAgICAgICAgICAgICAgICAgICAgeC5fVmFsdWUgPSBpLmRhdGEgfHwgaS50ZXh0Q29udGVudCB8fCBpLnRleHQgfHwgIiI7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB4OwoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFOgogICAgICAgICAgICAgICAgICAgIGlmIChYTUwuaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeC5fQ2xhc3MgPSAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiI7CiAgICAgICAgICAgICAgICAgICAgeC5fTmFtZSA9IG5ldyBRTmFtZSgiIiwgaS50YXJnZXQpOwogICAgICAgICAgICAgICAgICAgIHguX1ZhbHVlID0gaS5kYXRhIHx8IGkudGV4dENvbnRlbnQgfHwgaS50ZXh0IHx8ICIiOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4geDsKCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEFUVFJJQlVURV9OT0RFOgogICAgICAgICAgICAgICAgICAgIHguX0NsYXNzID0gImF0dHJpYnV0ZSI7CgogICAgICAgICAgICAgICAgICAgIHRlbXAgPSBpLm5vZGVOYW1lLm1hdGNoKC8oKFtcd1wtXSspOik/KFtcd1wtXSspLyk7CgogICAgICAgICAgICAgICAgICAgIGlmICggdGVtcFsxXSApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWkubG9va3VwTmFtZXNwYWNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IGkubG9va3VwTmFtZXNwYWNlKHRlbXBbMl0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDMgPSBuOy8vaGFjayBmb3IgaWUgLS0gc3R1cGlkIGllCgogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCF0ZW1wMiAmJiAhIXRlbXAzICYmICEhdGVtcDMuYXR0cmlidXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gdGVtcDMuYXR0cmlidXRlcy5sZW5ndGg7IGogPCBsOyArK2opCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlTmFtZSA9PSAoInhtbG5zOiIgKyB0ZW1wWzJdKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDIgPSB0ZW1wMy5hdHRyaWJ1dGVzW2pdLnZhbHVlIHx8IHRlbXAzLmF0dHJpYnV0ZXNbal0ubm9kZVZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAzID0gdGVtcDMucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB4Ll9EZWZhdWx0TmFtZXNwYWNlID0gbmV3IE5hbWVzcGFjZSggdGVtcFsyXSwgdGVtcDIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgeC5fTmFtZSA9IG5ldyBRTmFtZSggeC5fRGVmYXVsdE5hbWVzcGFjZSwgdGVtcFszXSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWkubG9va3VwTmFtZXNwYWNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IGkubG9va3VwTmFtZXNwYWNlKCIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAzID0gaS5wYXJlbnROb2RlOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICghdGVtcDIgJiYgISF0ZW1wMyAmJiAhIXRlbXAzLmF0dHJpYnV0ZXMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChqID0gMCwgbCA9IHRlbXAzLmF0dHJpYnV0ZXMubGVuZ3RoOyBqIDwgbDsgKytqKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAzLmF0dHJpYnV0ZXNbal0ubm9kZU5hbWUgPT0gInhtbG5zIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDIgPSB0ZW1wMy5hdHRyaWJ1dGVzW2pdLnZhbHVlIHx8IHRlbXAzLmF0dHJpYnV0ZXNbal0ubm9kZVZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAzID0gdGVtcDMucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgeC5fRGVmYXVsdE5hbWVzcGFjZSA9IG5ldyBOYW1lc3BhY2UoIiIsIHRlbXAyKTsKICAgICAgICAgICAgICAgICAgICAgICAgeC5fTmFtZSA9IG5ldyBRTmFtZSggeC5fRGVmYXVsdE5hbWVzcGFjZSwgdGVtcFszXSApOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeC5fVmFsdWUgPSBpLnZhbHVlIHx8IG51bGw7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB4OwoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRUxFTUVOVF9OT0RFOgogICAgICAgICAgICAgICAgICAgIHguX0NsYXNzID0gImVsZW1lbnQiOwogICAgICAgICAgICAgICAgICAgIHRlbXAgPSBpLm5vZGVOYW1lLm1hdGNoKC8oKFtcd1wtXSspOik/KFtcd1wtXSspLyk7CgogICAgICAgICAgICAgICAgICAgIGlmICggdGVtcFsxXSApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWkubG9va3VwTmFtZXNwYWNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IGkubG9va3VwTmFtZXNwYWNlKHRlbXBbMl0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDMgPSBpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICghdGVtcDIgJiYgISF0ZW1wMyAmJiAhIXRlbXAzLmF0dHJpYnV0ZXMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChqID0gMCwgbCA9IHRlbXAzLmF0dHJpYnV0ZXMubGVuZ3RoOyBqIDwgbDsgKytqKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAzLmF0dHJpYnV0ZXNbal0ubm9kZU5hbWUgPT0gKCJ4bWxuczoiICsgdGVtcFsyXSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gdGVtcDMuYXR0cmlidXRlc1tqXS52YWx1ZSB8fCB0ZW1wMy5hdHRyaWJ1dGVzW2pdLm5vZGVWYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMyA9IHRlbXAzLnBhcmVudE5vZGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgeC5fRGVmYXVsdE5hbWVzcGFjZSA9IG5ldyBOYW1lc3BhY2UoIHRlbXBbMl0sIHRlbXAyICk7CiAgICAgICAgICAgICAgICAgICAgICAgIHguX05hbWUgPSBuZXcgUU5hbWUoIHguX0RlZmF1bHROYW1lc3BhY2UsIHRlbXBbM10gKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDIgPSB1bmRlZmluZWQ7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFpLmxvb2t1cE5hbWVzcGFjZSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDIgPSBpLmxvb2t1cE5hbWVzcGFjZSgiIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMyA9IGk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCF0ZW1wMiAmJiAhIXRlbXAzICYmICEhdGVtcDMuYXR0cmlidXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gdGVtcDMuYXR0cmlidXRlcy5sZW5ndGg7IGogPCBsOyArK2opCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlTmFtZSA9PSAieG1sbnMiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHRlbXAzLmF0dHJpYnV0ZXNbal0udmFsdWUgfHwgdGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDMgPSB0ZW1wMy5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB4Ll9EZWZhdWx0TmFtZXNwYWNlID0gbmV3IE5hbWVzcGFjZSgiIiwgdGVtcDIpOwoKICAgICAgICAgICAgICAgICAgICAgICAgeC5fTmFtZSA9IG5ldyBRTmFtZSggeC5fRGVmYXVsdE5hbWVzcGFjZSwgdGVtcFszXSApOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgZm9yICh0ZW1wID0gMCwgdGVtcDIgPSBpLmF0dHJpYnV0ZXMubGVuZ3RoOyB0ZW1wIDwgdGVtcDI7ICsrdGVtcCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wMyA9IGlzTlNjaGVjay5leGVjKGkuYXR0cmlidXRlc1t0ZW1wXS5ub2RlTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHguX0luU2NvcGVOYW1lc3BhY2VzW3RlbXAzWzFdXSA9IG5ldyBOYW1lc3BhY2UodGVtcDNbMV0sIGkuYXR0cmlidXRlc1t0ZW1wXS52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoaS5hdHRyaWJ1dGVzW3RlbXBdLm5vZGVOYW1lID09PSAieG1sbnMiKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4Ll9JblNjb3BlTmFtZXNwYWNlc1siIl0gPSBuZXcgTmFtZXNwYWNlKGkuYXR0cmlidXRlc1t0ZW1wXS52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4Ll9BdHRyaWJ1dGVzW2kuYXR0cmlidXRlc1t0ZW1wXS5ub2RlTmFtZV0gPSBNYXBJbmZvSXRlbVRvWE1MKGkuYXR0cmlidXRlc1t0ZW1wXSwgaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGogPSAwOwogICAgICAgICAgICAgICAgICAgIHhtbENoaWxkID0gMDsKICAgICAgICAgICAgICAgICAgICB0ZW1wID0gaS5jaGlsZE5vZGVzLmxlbmd0aDsKCiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGogPCB0ZW1wKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbiA9IHtuOi0xfTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAzID0gTWFwSW5mb0l0ZW1Ub1hNTChpLmNoaWxkTm9kZXNbal0sIG4pKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2V2ZW4gdGhvdWdoIGl0IGlzIG5vdCB3cml0dGVuIHRoaXMgd2F5IGluIHRoZSBzcGVjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RoaXMgaXMgaG93IGl0IHdvcmtzIGluIEZpcmVmb3gKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHguX0NoaWxkcmVuW3htbENoaWxkXSA9IHRlbXAzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgeC5fQ2hpbGRyZW5beG1sQ2hpbGRdLl9QYXJlbnQgPSB4OwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wMy5fQ2xhc3MgPT09ICJ0ZXh0IiAmJiBuLm4gPiAwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGogPSBqICsgbi5uOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsreG1sQ2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICsrajsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHguX1ZhbHVlID0gaS50ZXh0Q29udGVudCB8fCBpLnRleHQgfHwgaS5kYXRhIHx8ICIiOwoKICAgICAgICAgICAgICAgICAgICB4Ll9MZW5ndGggPSB4bWxDaGlsZDsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHg7CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBET0NVTUVOVF9OT0RFOgogICAgICAgICAgICAgICAgLy9maXJlZm94IHdvbid0IGRvIHRoaXMKICAgICAgICAgICAgICAgIC8vcmV0dXJuIE1hcEluZm9JdGVtVG9YTUwoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KTsKICAgICAgICAgICAgICAgIC8vYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEVOVElUWV9SRUZFUkVOQ0VfTk9ERToKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIG1peGVkIHMKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFRvWE1MTGlzdCAocykKICAgICAgICB7CiAgICAgICAgICAgIHZhciBlLHgsbGlzdCxpLGw7CgogICAgICAgICAgICBpZiAocyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHMgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxpc3QgPSBuZXcgWE1MTGlzdCgpOwogICAgICAgICAgICAgICAgbGlzdC5fQ2hpbGRyZW5bMF0gPSBsaXN0WzBdID0gczsKICAgICAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHguX1BhcmVudDsKICAgICAgICAgICAgICAgIGxpc3QuX1RhcmdldFByb3BlcnR5ID0geC5fTmFtZTsKCiAgICAgICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICgoIixzdHJpbmcsYm9vbGVhbixudW1iZXIsIikuaW5kZXhPZigiLCIgKyB0eXBlb2YocykrIiwiKSA9PT0gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZSA9IHBhcnNlKCc8cGFyZW50IHhtbG5zPSInICsgR2V0RGVmYXVsdE5hbWVzcGFjZSgpICsgJyI+JyArIHMgKyAnPC9wYXJlbnQ+Jyk7CiAgICAgICAgICAgIHggPSBUb1hNTChlLmRvY3VtZW50RWxlbWVudCk7CiAgICAgICAgICAgIGxpc3QgPSBuZXcgWE1MTGlzdCgpOwogICAgICAgICAgICBpID0gMDsKICAgICAgICAgICAgbCA9IHguX0NoaWxkcmVuLmxlbmd0aDsKCiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IG51bGw7CgogICAgICAgICAgICBmb3IgKDtpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB4Ll9DaGlsZHJlbltpXS5fUGFyZW50ID0gbnVsbDsKICAgICAgICAgICAgICAgIGxpc3QuX0NoaWxkcmVuW2ldID0gbGlzdFtpXSA9IHguX0NoaWxkcmVuW2ldOwogICAgICAgICAgICB9CgoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIG1peGVkIHMKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBUb0F0dHJpYnV0ZU5hbWUgKHMpCiAgICAgICAgewogICAgICAgICAgICBpZiAocyA9PT0gIioiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZU5hbWUobmV3IFFOYW1lKG51bGwsICIqIikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHMgaW5zdGFuY2VvZiBRTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGVOYW1lKHMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHMgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3dpdGNoICh0eXBlb2YocykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgInVuZGVmaW5lZCI6CiAgICAgICAgICAgICAgICBjYXNlICJudWxsIjoKICAgICAgICAgICAgICAgIGNhc2UgImJvb2xlYW4iOgogICAgICAgICAgICAgICAgY2FzZSAibnVtYmVyIjoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJzdHJpbmciOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlTmFtZShuZXcgUU5hbWUobnVsbCwgKHMgKyAiIikucmVwbGFjZSgvXkAvLCIiKSkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAib2JqZWN0IjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZU5hbWUobmV3IFFOYW1lKG51bGwsIFRvU3RyaW5nKHMpKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gbWl4ZWQgcwogICAgICAgICAqICAgIEByZXR1cm5zIFFOYW1lIHwgQXR0cmlidXRlTmFtZQogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gVG9YTUxOYW1lIChzKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHMgaW5zdGFuY2VvZiBRTmFtZSB8fCBzIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocyA9PT0gIioiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFFOYW1lKCIqIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN3aXRjaCAodHlwZW9mKHMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlICJ1bmRlZmluZWQiOgogICAgICAgICAgICAgICAgY2FzZSAibnVsbCI6CiAgICAgICAgICAgICAgICBjYXNlICJib29sZWFuIjoKICAgICAgICAgICAgICAgIGNhc2UgIm51bWJlciI6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAic3RyaW5nIjoKICAgICAgICAgICAgICAgICAgICBpZiAocy5jaGFyQXQoMCkgPT09ICJAIikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBUb0F0dHJpYnV0ZU5hbWUoIHMuc3Vic3RyKDApICk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFFOYW1lKHMpOwoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIm9iamVjdCI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRvWE1MTmFtZSggVG9TdHJpbmcocykgKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEdldERlZmF1bHROYW1lc3BhY2UgKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAhIWRlZmF1bHROYW1lc3BhY2UgJiYgZGVmYXVsdE5hbWVzcGFjZS51cmkgfHwgIiI7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBzCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gRXNjYXBlRWxlbWVudFZhbHVlIChzKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICgoc3x8IiIpKyIiKS5yZXBsYWNlKC8uL2csIGZ1bmN0aW9uIChjKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiPCI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiJmx0OyI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiPiI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiJmd0OyI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiJiI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiJmFtcDsiOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgcwogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEVzY2FwZUF0dHJpYnV0ZVZhbHVlIChzKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICgoc3x8IiIpKyIiKS5yZXBsYWNlKC8uL2csIGZ1bmN0aW9uIChjKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnIic6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiJnF1b3Q7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICI8IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImbHQ7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICI+IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImZ3Q7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICImIjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImYW1wOyI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiXHIiOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiYjeEE7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICJcbiI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiJiN4RDsiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIlx0IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImI3g5OyI7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gR2V0IChQcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBHZXRMaXN0LmNhbGwodGhpcywgUHJvcGVydHlOYW1lKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHBhcnNlSW50KFByb3BlcnR5TmFtZSkrIiIgPT0gUHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gR2V0TGlzdC5jYWxsKFRvWE1MTGlzdCh0aGlzKSwgUHJvcGVydHlOYW1lICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBuID0gVG9YTUxOYW1lKFByb3BlcnR5TmFtZSksCiAgICAgICAgICAgICAgICBsaXN0ID0gbmV3IFhNTExpc3QoKSwgcCwgbDsKCiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHRoaXM7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldFByb3BlcnR5ID0gbjsKCiAgICAgICAgICAgIGlmIChuIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChwIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAobi5fTmFtZS5sb2NhbE5hbWUgPT09ICIqIiB8fCBuLl9OYW1lLmxvY2FsTmFtZSA9PT0gdGhpcy5fQXR0cmlidXRlc1twXS5fTmFtZS5sb2NhbE5hbWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKG4uX05hbWUudXJpID09IG51bGwgfHwgbi5fTmFtZS51cmkgPT09IHRoaXMuX0F0dHJpYnV0ZXNbcF0uX05hbWUudXJpKQogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZCh0aGlzLl9BdHRyaWJ1dGVzW3BdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKHAgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBwIDwgbDsgKytwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgKG4ubG9jYWxOYW1lID09PSAiKiIgfHwgKHRoaXMuX0NoaWxkcmVuW3BdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXMuX0NoaWxkcmVuW3BdLl9OYW1lLmxvY2FsTmFtZSA9PT0gbi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuLnVyaSA9PSBudWxsIHx8ICh0aGlzLl9DaGlsZHJlbltwXS5fQ2xhc3MgPT09ICJlbGVtZW50IiAmJiBuLnVyaSA9PT0gdGhpcy5fQ2hpbGRyZW5bcF0uX05hbWUudXJpKSkKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQodGhpcy5fQ2hpbGRyZW5bcF0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgUAogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBIYXNQcm9wZXJ0eSAoUCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIEhhc1Byb3BlcnR5TGlzdC5jYWxsKHRoaXMsIFApOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocGFyc2VJbnQoUCkgPT0gUCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIFAgPT0gIjAiOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbiA9IFRvWE1MTmFtZShQKSwgaywgbDsKCiAgICAgICAgICAgIGlmIChuIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChrIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuLl9OYW1lLmxvY2FsTmFtZSA9PT0gIioiIHx8IG4uX05hbWUubG9jYWxOYW1lID09PSB0aGlzLl9BdHRyaWJ1dGVzW2tdLl9OYW1lLmxvY2FsTmFtZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4uX05hbWUudXJpID09IG51bGwgfHwgbi5fTmFtZS51cmkgPT09IHRoaXMuX0F0dHJpYnV0ZXNba10uX05hbWUudXJpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGsgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBrIDwgbDsgKytrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKG4ubG9jYWxOYW1lID09PSAiKiIgfHwgKHRoaXMuX0NoaWxkcmVuW2tdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLmxvY2FsTmFtZSA9PT0gbi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgICAgICAgICAobi51cmkgPT0gbnVsbCB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgbi51cmkgPT09IHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLnVyaSkpCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gRGVsZXRlQnlJbmRleCAoUHJvcGVydHlOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGkgPSBwYXJzZUludChQcm9wZXJ0eU5hbWUpOy8vLCBxID0gaSArIDEsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7CgogICAgICAgICAgICBpZiAoaSA9PSBQcm9wZXJ0eU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghIXRoaXMuX0NoaWxkcmVuW2ldKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldLl9QYXJlbnQgPSBudWxsOwoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXSA9IG51bGw7CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuLnNwbGljZShpLCAxKTsKCiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgZm9yICg7cSA8IGw7KytxKQogICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW3EtMV0gPSB0aGlzLl9DaGlsZHJlbltxXTsKICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBEZWVwQ29weSAoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gRGVlcENvcHlMaXN0LmNhbGwodGhpcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciB5ID0gbmV3IFhNTCgpLCBpLCBsOy8vLCBjLCB0OwoKICAgICAgICAgICAgeS5fQ2xhc3MgPSB0aGlzLl9DbGFzczsKICAgICAgICAgICAgeS5fTmFtZSA9IHRoaXMuX05hbWU7CiAgICAgICAgICAgIHkuX0RlZmF1bHROYW1lc3BhY2UgPSB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlID8gbmV3IE5hbWVzcGFjZSh0aGlzLl9EZWZhdWx0TmFtZXNwYWNlKSA6IG51bGw7CiAgICAgICAgICAgIHkuX1ZhbHVlID0gdGhpcy5fVmFsdWU7CiAgICAgICAgICAgIHkuX1BhcmVudCA9IG51bGw7CgogICAgICAgICAgICBmb3IgKGkgaW4gdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHkuX0luU2NvcGVOYW1lc3BhY2VzW2ldID0gbmV3IE5hbWVzcGFjZSh0aGlzLl9JblNjb3BlTmFtZXNwYWNlcy5wcmVmaXgsIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzLnVyaSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAobCBpbiB0aGlzLl9BdHRyaWJ1dGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvL3kuX0F0dHJpYnV0ZXNbaV0gPSBhcmd1bWVudHMuY2FsbGVlLmNhbGwodGhpcy5fQXR0cmlidXRlc1tpXSk7CiAgICAgICAgICAgICAgICAvL25vdCBwYXJ0IG9mIHRoZSBzcGVjCiAgICAgICAgICAgICAgICB5Ll9BdHRyaWJ1dGVzW2ldID0gdGhpcy5fQXR0cmlidXRlc1tsXS5jb3B5KCk7CiAgICAgICAgICAgICAgICB5Ll9BdHRyaWJ1dGVzW2ldLl9QYXJlbnQgPSB5OwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB5Ll9DaGlsZHJlbltpXSA9IHRoaXMuX0NoaWxkcmVuW2ldLmNvcHkoKTsKICAgICAgICAgICAgICAgIHkuX0NoaWxkcmVuW2ldLl9QYXJlbnQgPSB5OwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4geTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFJlc29sdmVWYWx1ZSAoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gUmVzb2x2ZVZhbHVlTGlzdC5jYWxsKHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgWE1MID8gdGhpcyA6IG51bGw7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIERlc2NlbmRhbnRzIChQcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBEZXNjZW5kYW50c0xpc3QuY2FsbCh0aGlzLCBQcm9wZXJ0eU5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbiA9IFRvWE1MTmFtZShQcm9wZXJ0eU5hbWUpLAogICAgICAgICAgICAgICAgbGlzdCA9IG5ldyBYTUxMaXN0KCksCiAgICAgICAgICAgICAgICBrLCBsLCBkcTsKCiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IG51bGw7CgogICAgICAgICAgICBpZiAobiBpbnN0YW5jZW9mIEF0dHJpYnV0ZU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoayBpbiB0aGlzLl9BdHRyaWJ1dGVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgKG4uX05hbWUubG9jYWxOYW1lID09PSAiKiIgfHwgbi5fTmFtZS5sb2NhbE5hbWUgPT09IHRoaXMuX0F0dHJpYnV0ZXNba10uX05hbWUubG9jYWxOYW1lKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuLl9OYW1lLnVyaSA9PSBudWxsIHx8IG4uX05hbWUudXJpID09PSB0aGlzLl9BdHRyaWJ1dGVzW2tdLl9OYW1lLnVyaSkKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQodGhpcy5fQXR0cmlidXRlc1trXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGsgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBrIDwgbDsgKytrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKG4ubG9jYWxOYW1lID09PSAiKiIgfHwgKHRoaXMuX0NoaWxkcmVuW2tdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLmxvY2FsTmFtZSA9PT0gbi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgICAgICAgICAobi51cmkgPT0gbnVsbCB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgbi51cmkgPT09IHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLnVyaSkpCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRoaXMuX0NoaWxkcmVuW2tdKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBkcSA9IHRoaXMuX0NoaWxkcmVuW2tdLmRlc2NlbmRhbnRzKG4pOwoKICAgICAgICAgICAgICAgIGlmIChkcS5sZW5ndGgoKSA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQoZHEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIFZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yIHwgRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBJbnNlcnQgKFByb3BlcnR5TmFtZSwgVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsdGV4dCxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sYXR0cmlidXRlLCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGkgPSBwYXJzZUludChQcm9wZXJ0eU5hbWUpLCBuLCBqOwoKICAgICAgICAgICAgaWYgKGkrIiIgIT0gUHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCInIiArIGkgKyAiJyAhPSAnIiArIFByb3BlcnR5TmFtZSArICInIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChWYWx1ZSA9PT0gdGhpcyB8fCBpbmRleE9mKCIsIiArIHRoaXMsIFZhbHVlLmRlc2NlbmRhbnRzKCIqIikpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBuID0gVmFsdWUubGVuZ3RoKCk7CgogICAgICAgICAgICBmb3IgKGogPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGggLSAxOyBqID49IGk7IC0taikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bIGogKyBuIF0gPSB0aGlzLl9DaGlsZHJlbltqXTsKICAgICAgICAgICAgfQoKCiAgICAgICAgICAgIGlmIChWYWx1ZSBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBuOyArK2opCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVmFsdWVbal0uX1BhcmVudCA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baSArIGpdID0gVmFsdWVbal07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZXBsYWNlLmNhbGwodGhpcywgaSwgVmFsdWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIFZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gUmVwbGFjZSAoUHJvcGVydHlOYW1lLCBWYWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIix0ZXh0LGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbixhdHRyaWJ1dGUsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBpID0gcGFyc2VJbnQoUHJvcGVydHlOYW1lKSwgdDsKCiAgICAgICAgICAgIGlmIChpKyIiICE9IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigiJyIgKyBpICsgIicgIT0gJyIgKyBQcm9wZXJ0eU5hbWUgKyAiJyIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaSA+PSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFByb3BlcnR5TmFtZSA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRGVsZXRlQnlJbmRleC5jYWxsKHRoaXMsIFByb3BlcnR5TmFtZSk7CiAgICAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCBQcm9wZXJ0eU5hbWUsIFZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChWYWx1ZSBpbnN0YW5jZW9mIFhNTAogICAgICAgICAgICAgICAgJiYgVmFsdWUuX0NsYXNzID09PSAiZWxlbWVudCIKICAgICAgICAgICAgICAgICYmICgiLGVsZW1lbnQsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLHRleHQiKS5pbmRleE9mKCIsIiArIFZhbHVlLl9DbGFzcyArICIsIikgPiAtMQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBWYWx1ZS5fUGFyZW50ID0gdGhpczsKCiAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5bUHJvcGVydHlOYW1lXSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltQcm9wZXJ0eU5hbWVdLl9QYXJlbnQgPSBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW1Byb3BlcnR5TmFtZV0gPSBWYWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHQgPSBuZXcgWE1MKCk7CiAgICAgICAgICAgICAgICB0Ll9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgdC5fVmFsdWUgPSBUb1N0cmluZyhWYWx1ZSk7CgogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW1Byb3BlcnR5TmFtZV0pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bUHJvcGVydHlOYW1lXS5fUGFyZW50ID0gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltQcm9wZXJ0eU5hbWVdID0gdDsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBOYW1lc3BhY2UgTmFtZVNwYWNlCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEFkZEluU2NvcGVOYW1lc3BhY2UgKE5hbWVTcGFjZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIix0ZXh0LGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbixhdHRyaWJ1dGUsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBtYXRjaCA9IG51bGwsIHA7CgogICAgICAgICAgICBpZiAoTmFtZVNwYWNlLnByZWZpeCA9PSAiIiAmJiB0aGlzLl9OYW1lLnVyaSA9PSAiIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAocCBpbiB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKE5hbWVTcGFjZS5wcmVmaXggPT09IHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdLnByZWZpeCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAobWF0Y2ggJiYgbWF0Y2gudXJpICE9IE5hbWVTcGFjZS51cmkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW21hdGNoLnByZWZpeF0gPSBudWxsOwogICAgICAgICAgICAgICAgdHJ5ewogICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1ttYXRjaC5wcmVmaXhdOwogICAgICAgICAgICAgICAgfWNhdGNoKGUpe30KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbTmFtZVNwYWNlLnByZWZpeF0gPSBOYW1lU3BhY2U7CgogICAgICAgICAgICBpZiAodGhpcy5fTmFtZS5wcmVmaXggPT09IE5hbWVTcGFjZS5wcmVmaXgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRoaXMuX05hbWUucHJlZml4ID0gdW5kZWZpbmVkOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHAgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0F0dHJpYnV0ZXNbcF0uX05hbWUucHJlZml4ID0gTmFtZVNwYWNlLnByZWZpeCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzW3BdLl9OYW1lLnByZWZpeCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9kbyB0aGlzIGluIG9yZGVyIHRvIGVuc3VyZSBuYW1lc3BhY2UgaW50ZWdyaXR5CiAgICAgICAgICAgIC8qbWF0Y2ggPSBwYXJzZSh0aGlzLnRvWE1MU3RyaW5nKCkpOwogICAgICAgICAgICAgdGhpcy5fTm9kZSA9ICEhdGhpcy5fTm9kZS5wYXJlbnROb2RlCiAgICAgICAgICAgICA/IHRoaXMuX05vZGUucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQobWF0Y2guZG9jdW1lbnRFbGVtZW50LCB0aGlzLl9Ob2RlKQogICAgICAgICAgICAgOiBtYXRjaDsqLwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBOdW1iZXIgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBIYXNQcm9wZXJ0eUxpc3QgKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoVG9TdHJpbmcoIHBhcnNlSW50KG5hbWUpICkgPT09IG5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludChuYW1lKSA8IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXNbaV0uaGFzT3duUHJvcGVydHkobmFtZSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBOdW1iZXIgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gR2V0TGlzdCAoUHJvcGVydHlOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHBhcnNlSW50KFByb3BlcnR5TmFtZSkrIiIgPT0gUHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpc1tQcm9wZXJ0eU5hbWVdOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCB0ZW1wOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRQcm9wZXJ0eSA9IFByb3BlcnR5TmFtZTsKCiAgICAgICAgICAgIGZvciAoO2kgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0ZW1wID0gR2V0LmNhbGwodGhpcy5fQ2hpbGRyZW5baV0sIFByb3BlcnR5TmFtZSk7CgogICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wLl9DaGlsZHJlbi5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQodGVtcCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBEZWVwQ29weUxpc3QgKCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7CgogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzLl9UYXJnZXRPYmplY3Q7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldFByb3BlcnR5ID0gdGhpcy5fVGFyZ2V0UHJvcGVydHk7CiAgICAgICAgICAgIGxpc3QuX0NsYXNzID0gdGhpcy5fQ2xhc3M7CiAgICAgICAgICAgIGxpc3QuX1ZhbHVlID0gdGhpcy5fVmFsdWU7CgogICAgICAgICAgICBmb3IgKDtpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChEZWVwQ29weS5jYWxsKHRoaXNbaV0pKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIERlc2NlbmRhbnRzTGlzdCAoUHJvcGVydHlOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgWE1MTGlzdCgpLCBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCwgdGVtcDsKCiAgICAgICAgICAgIGZvciAoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKHRlbXAgPSBEZXNjZW5kYW50cy5jYWxsKHRoaXNbaV0sICIqIikpICYmIHRlbXAubGVuZ3RoKCkgPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQodGVtcCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqICAgIGh0dHA6Ly9ibG9nLnN0ZXZlbmxldml0aGFuLmNvbS9hcmNoaXZlcy9mYXN0ZXItdHJpbS1qYXZhc2NyaXB0CiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgcwogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIHRyaW0gKHN0cikKICAgICAgICB7CiAgICAgICAgICAgIGlmKCFzdHIpCiAgICAgICAgICAgICAgICByZXR1cm4gc3RyOwogICAgICAgICAgICB2YXIgICAgc3RyID0gc3RyLnJlcGxhY2UoL15cc1xzKi8sICIiKSwKICAgICAgICAgICAgICAgIHdzID0gL1xzLywKICAgICAgICAgICAgICAgIGkgPSBzdHIubGVuZ3RoOwogICAgICAgICAgICB3aGlsZSAod3MudGVzdChzdHIuY2hhckF0KC0taSkpKTsKICAgICAgICAgICAgcmV0dXJuIHN0ci5zbGljZSgwLCBpICsgMSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiAgICBHZW5lcmF0ZXMgYSBwcmVmaXggZm9yIGEgUU5hbWUgdGhhdCBpcyBub3QgYWxyZWFkeQogICAgICAgICAqICAgIGEgcHJvcGVydHkgb2YgdGhlIG9wdGlvbmFsIGFyZ3VtZW50CiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gT2JqZWN0IHByZWZpeGVzCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gbmV3UHJlZml4IChwcmVmaXhlcykKICAgICAgICB7CiAgICAgICAgICAgIHByZWZpeGVzID0gcHJlZml4ZXMgfHwge307CgogICAgICAgICAgICB2YXIgbnVtID0gTWF0aC5yYW5kb20oKQogICAgICAgICAgICAgICAgLnRvU3RyaW5nKCkKICAgICAgICAgICAgICAgIC5zdWJzdHIoMikKICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8uezJ9L2csIGZ1bmN0aW9uIChhKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGEgPSBOdW1iZXIoYSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChhID4gOTAgPyA5MCA6IChhIDwgNjUgPyA2NSA6IGEpKSArICIiOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICBudW0gPSBTdHJpbmcuZnJvbUNoYXJDb2RlKAogICAgICAgICAgICAgICAgTnVtYmVyKG51bS5zdWJzdHIoMCwgMikpICYgMHhGRiwKICAgICAgICAgICAgICAgIE51bWJlcihudW0uc3Vic3RyKDIsIDIpKSAmIDB4RkYsCiAgICAgICAgICAgICAgICBOdW1iZXIobnVtLnN1YnN0cig0LCAyKSkgJiAweEZGLAogICAgICAgICAgICAgICAgTnVtYmVyKG51bS5zdWJzdHIoNiwgMikpICYgMHhGRiwKICAgICAgICAgICAgICAgIE51bWJlcihudW0uc3Vic3RyKDgsIDIpKSAmIDB4RkYsCiAgICAgICAgICAgICAgICBOdW1iZXIobnVtLnN1YnN0cigxMCwgMikpICYgMHhGRgogICAgICAgICAgICApLnRvTG93ZXJDYXNlKCk7CgogICAgICAgICAgICB3aGlsZSAobnVtIGluIHByZWZpeGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBudW0gPSBhcmd1bWVudHMuY2FsbGVlKHByZWZpeGVzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHN0cgogICAgICAgICAqICAgIEByZXR1cm5zIERPTU5vZGUKICAgICAgICAgKiAgICBAdGhyb3dzIFN5bnRheEVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gcGFyc2UgKHN0cikKICAgICAgICB7CiAgICAgICAgICAgIHZhciB4bWxEb2MsIHN1Y2Nlc3MgPSB0cnVlOwoKICAgICAgICAgICAgaWYgKGlzQWN0aXZlWFN1cHBvcnRlZCgiTWljcm9zb2Z0LlhNTERPTSIpKSAvL0ludGVybmV0IEV4cGxvcmVyCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MgICAgICAgICAgICAgICAgICAgICAgPSBuZXcgQWN0aXZlWE9iamVjdCgiTWljcm9zb2Z0LlhNTERPTSIpOwogICAgICAgICAgICAgICAgICAgIHhtbERvYy5hc3luYyAgICAgICAgICAgICAgICA9ICdmYWxzZSc7CiAgICAgICAgICAgICAgICAgICAgeG1sRG9jLnByZXNlcnZlV2hpdGVTcGFjZSAgID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MucmVzb2x2ZUV4dGVybmFscyAgICAgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MudmFsaWRhdGVPblBhcnNlICAgICAgICAgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB4bWxEb2Muc2V0UHJvcGVydHkoJ1Byb2hpYml0RFREJywgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB4bWxEb2MubG9hZFhNTChzdHIpOwogICAgICAgICAgICAgICAgfWNhdGNoKGUpe30KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRyeXsvL0ZpcmVmb3gsIE1vemlsbGEsIE9wZXJhLCBldGMuCiAgICAgICAgICAgICAgICAgICAgeG1sRG9jID0gbmV3IERPTVBhcnNlcigpOwogICAgICAgICAgICAgICAgICAgIHhtbERvYyA9IHhtbERvYy5wYXJzZUZyb21TdHJpbmcoc3RyLCAidGV4dC94bWwiKTsKICAgICAgICAgICAgICAgIH1jYXRjaChlKXt9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghc3VjY2VzcyB8fCAheG1sRG9jIHx8IHhtbERvYy5kb2N1bWVudEVsZW1lbnQubm9kZU5hbWUgPT0gInBhcnNlcmVycm9yIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCEheG1sRG9jICYmIHhtbERvYy5kb2N1bWVudEVsZW1lbnQuY2hpbGROb2Rlc1swXS5ub2RlVmFsdWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4geG1sRG9jOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBPYmplY3Qgb2JqCiAgICAgICAgICogICAgQHJldHVybnMgTnVtYmVyCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gY291bnQgKG9iaikKICAgICAgICB7CiAgICAgICAgICAgIGlmICgiX19jb3VudF9fIiBpbiBvYmopCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBvYmouX19jb3VudF9fOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgaSA9IDAsIGs7CgogICAgICAgICAgICBmb3IgKGsgaW4gb2JqKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGspKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIE9iamVjdCBvYmoKICAgICAgICAgKiAgICBAcGFyYW0gWE1MTGlzdCBsaXN0CiAgICAgICAgICogICAgQHJldHVybnMgTnVtYmVyCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gaW5kZXhPZiAob2JqLCBsaXN0KQogICAgICAgIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBsaXN0Lmxlbmd0aCgpOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAobGlzdFtpXS5FcXVhbHMob2JqKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBtaXhlZCBvYmoKICAgICAgICAgKiAgICBAcGFyYW0gbWl4ZWQgLi4uCiAgICAgICAgICogICAgQHJldHVybnMgbWl4ZWQKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBleHRlbmQgKG9iaikKICAgICAgICB7CiAgICAgICAgICAgIGZvciAodmFyIHAsIGkgPSAxLCBsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChwIGluIGFyZ3VtZW50c1tpXSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBvYmpbcF0gPSBhcmd1bWVudHNbaV1bcF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBvYmo7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBjcmVhdGVEb2N1bWVudEZyb20gKHhtbCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBwYXJzZSh4bWwubGVuZ3RoKCkgPT0gMSA/IHhtbC50b1hNTFN0cmluZygpIDogIjx4PiIgKyB4bWwudG9YTUxTdHJpbmcoKSArICI8L3g+Iik7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiB4bWxUb0RvbU5vZGUgKHhtbCkKICAgICAgICB7CiAgICAgICAgICAgIHN3aXRjaCAoeG1sLm5vZGVLaW5kKCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgImVsZW1lbnQiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVEb2N1bWVudEZyb20oeG1sKS5kb2N1bWVudEVsZW1lbnQ7CgogICAgICAgICAgICAgICAgY2FzZSAidGV4dCI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHhtbERvYy5jcmVhdGVUZXh0Tm9kZSh4bWwudG9TdHJpbmcoKSk7CgogICAgICAgICAgICAgICAgY2FzZSAiY29tbWVudCI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHhtbERvYy5jcmVhdGVDb21tZW50KHhtbC50b1N0cmluZygpLnNsaWNlKDQsIC0zKSk7CgogICAgICAgICAgICAgICAgY2FzZSAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHhtbERvYy5jcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbC5sb2NhbE5hbWUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sLnRvU3RyaW5nKCkuc2xpY2UoMiwgLTIpLnJlcGxhY2UocGlOYW1lLCAiIikKICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgIGNhc2UgImF0dHJpYnV0ZSI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZU5TKHhtbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBhZG9wdE5vZGUgKGRvYywgbm9kZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghIWRvYy5hZG9wdE5vZGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBkb2MuYWRvcHROb2RlKG5vZGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgYiA9IGRvYy5kb2N1bWVudEVsZW1lbnQgfHwgZG9jLmJvZHk7CiAgICAgICAgICAgIHJldHVybiBiLnJlbW92ZUNoaWxkKGIuYXBwZW5kQ2hpbGQobm9kZSkpOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gZXZhbHVhdGUgKGRvYywgZXhwciwgeG1sKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHJlcywgbCwgbiA9ICIiOwoKICAgICAgICAgICAgaWYgKCEhZG9jLmV2YWx1YXRlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXMgPSBkb2MuZXZhbHVhdGUoCiAgICAgICAgICAgICAgICAgICAgZXhwciwKICAgICAgICAgICAgICAgICAgICBkb2MsCiAgICAgICAgICAgICAgICAgICAgZG9jLmNyZWF0ZU5TUmVzb2x2ZXIoZG9jKSwKICAgICAgICAgICAgICAgICAgICBYUGF0aFJlc3VsdC5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSwKICAgICAgICAgICAgICAgICAgICBudWxsCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgIGwgPSBbXTsKCiAgICAgICAgICAgICAgICB3aGlsZShuID0gcmVzLml0ZXJhdGVOZXh0KCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbFtsLmxlbmd0aF0gPSBuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoInNldFByb3BlcnR5IiBpbiBkb2MpewoKICAgICAgICAgICAgICAgIHJlcyA9IGFsbE5hbWVzcGFjZXMoeG1sKTsKCiAgICAgICAgICAgICAgICBpZiAoY291bnQocmVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKGwgaW4gcmVzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbiArPSAiIHhtbG5zOiIgKyBsICsgJz0iJyArIEVzY2FwZUF0dHJpYnV0ZVZhbHVlKHJlc1tsXSkgKyAnIic7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBkb2Muc2V0UHJvcGVydHkoJ1NlbGVjdGlvbk5hbWVzcGFjZXMnLCBuLnN1YnN0cigxKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZG9jLnNldFByb3BlcnR5KCJTZWxlY3Rpb25MYW5ndWFnZSIsICJYUGF0aCIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gaXNBY3RpdmVYU3VwcG9ydGVkKCJNaWNyb3NvZnQuWE1MRE9NIikgJiYgZG9jLnNlbGVjdE5vZGVzKGV4cHIpOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gaXNBY3RpdmVYU3VwcG9ydGVkKHR5cGUpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIG5ldyBBY3RpdmVYT2JqZWN0KHR5cGUpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gYWxsTmFtZXNwYWNlcyAoeG1sLCB1bikKICAgICAgICB7CiAgICAgICAgICAgIHZhciBucyA9IHVuIHx8IHt9LAogICAgICAgICAgICAgICAgaSA9IDAsCiAgICAgICAgICAgICAgICBjID0geG1sLmNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBsID0gYy5sZW5ndGgoKSwKICAgICAgICAgICAgICAgIG4gPSB1biA9PSB1bmRlZmluZWQKICAgICAgICAgICAgICAgICAgICA/IGluc2NvcGUoeG1sKQogICAgICAgICAgICAgICAgICAgIDogeG1sLl9JblNjb3BlTmFtZXNwYWNlcywKICAgICAgICAgICAgICAgIHA7CgogICAgICAgICAgICBmb3IgKDtpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBucyA9IGFyZ3VtZW50cy5jYWxsZWUoY1tpXSwgbnMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHAgaW4gbikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKG5bcF0ucHJlZml4KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG5zW25bcF0ucHJlZml4XSA9IG5bcF0udXJpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnM7CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBpbnNjb3BlICh4bWwpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbnMgPSB7fSwKICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgbiA9IHhtbC5pblNjb3BlTmFtZXNwYWNlcygpLAogICAgICAgICAgICAgICAgbCA9IG4ubGVuZ3RoOwoKICAgICAgICAgICAgZm9yICg7aSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKG5baV0ucHJlZml4KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG5zW25baV0ucHJlZml4XSA9IG5baV0udXJpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnM7CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBjcmVhdGVBdHRyaWJ1dGVOUyAoeG1sKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIG5zID0geG1sLm5hbWVzcGFjZSgpLAogICAgICAgICAgICAgICAgbm9kZSA9ICEheG1sRG9jLmNyZWF0ZUF0dHJpYnV0ZU5TCiAgICAgICAgICAgICAgICAgICAgPyB4bWxEb2MuY3JlYXRlQXR0cmlidXRlTlMobnMudXJpLCB4bWwubG9jYWxOYW1lKCkpCiAgICAgICAgICAgICAgICAgICAgOiB4bWxEb2MuY3JlYXRlQXR0cmlidXRlKChucy5wcmVmaXggPyBucy5wcmVmaXggKyAiOiIgOiAiIiApICsgeG1sLmxvY2FsTmFtZSgpKTsKCiAgICAgICAgICAgIG5vZGUubm9kZVZhbHVlID0geG1sLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gdHJhbnNmb3JtICh4bWwsIHN0eWxlLCBwYXJhbXMpCiAgICAgICAgewogICAgICAgICAgICB2YXIgeHNsLCByZXMsIGkgPSAwLCBsID0gKHBhcmFtc3x8W10pLmxlbmd0aDsKCiAgICAgICAgICAgIGlmICghd2luZG93LlhTTFRQcm9jZXNzb3IpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vVE9ETzogTmVlZCB0byBjcmVhdGUgYSB3YXkgdG8gc2V0IHBhcmFtZXRlcnMgb24gYW4gSUUgc3R5bGVzaGVldAogICAgICAgICAgICAgICAgLy9YU0xQcm9jZXNzb3IKICAgICAgICAgICAgICAgIC8vaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21zNzU3MDE1JTI4dj1WUy44NSUyOS5hc3B4CiAgICAgICAgICAgICAgICAvL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczc2MzY3OSUyOFZTLjg1JTI5LmFzcHgKICAgICAgICAgICAgICAgIC8vaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21zNzU0NTk0JTI4dj1WUy44NSUyOS5hc3B4CgogICAgICAgICAgICAgICAgcmVzID0gY3JlYXRlRG9jdW1lbnRGcm9tKHhtbCkudHJhbnNmb3JtTm9kZShjcmVhdGVEb2N1bWVudEZyb20oc3R5bGUpKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gISFyZXMgJiYgVG9YTUwocmVzKSB8fCBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB4c2wgPSBuZXcgWFNMVFByb2Nlc3NvcigpOwoKICAgICAgICAgICAgeHNsLmltcG9ydFN0eWxlU2hlZXQoY3JlYXRlRG9jdW1lbnRGcm9tKHN0eWxlKSk7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzID0gcGFyYW1zW2ldOwogICAgICAgICAgICAgICAgeHNsLnNldFBhcmFtZXRlcihyZXMubmFtZXNwYWNlVVJJLCByZXMubG9jYWxOYW1lLCByZXMudmFsdWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXMgPSB4c2wudHJhbnNmb3JtVG9Eb2N1bWVudChjcmVhdGVEb2N1bWVudEZyb20oZG9jKSkKCiAgICAgICAgICAgIHJldHVybiAhIXJlcyAmJiBUb1hNTChyZXMpIHx8IG51bGw7CiAgICAgICAgfQoKICAgICAgICBmb3IgKHAgaW4gWE1MLnByb3RvdHlwZSkKICAgICAgICB7CiAgICAgICAgICAgIGRlZmF1bHRYTUxQcm90b3R5cGUgKz0gcCArICIsIjsKICAgICAgICB9CgogICAgICAgIGZvciAocCBpbiBYTUxMaXN0LnByb3RvdHlwZSkKICAgICAgICB7CiAgICAgICAgICAgIGRlZmF1bHRYTUxMaXN0UHJvdG90eXBlICs9IHAgKyAiLCI7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICB3aW5kb3cuWE1MICAgICAgICAgICAgICA9IFhNTDsKICAgICAgICB3aW5kb3cuWE1MTGlzdCAgICAgICAgICA9IFhNTExpc3Q7CiAgICAgICAgd2luZG93LlFOYW1lICAgICAgICAgICAgPSBRTmFtZTsKICAgICAgICB3aW5kb3cuTmFtZXNwYWNlICAgICAgICA9IE5hbWVzcGFjZTsKICAgICAgICB3aW5kb3cuaXNYTUxOYW1lICAgICAgICA9IGlzWE1MTmFtZTsKICAgICAgICB3aW5kb3cuQXR0cmlidXRlTmFtZSAgICA9IEF0dHJpYnV0ZU5hbWU7CgogICAgfSkoKTsKfQooZnVuY3Rpb24oKXt2YXIgaD10aGlzOwpmdW5jdGlvbiBhYShhKXt2YXIgYj10eXBlb2YgYTtpZigib2JqZWN0Ij09YilpZihhKXtpZihhIGluc3RhbmNlb2YgQXJyYXkpcmV0dXJuImFycmF5IjtpZihhIGluc3RhbmNlb2YgT2JqZWN0KXJldHVybiBiO3ZhciBjPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhKTtpZigiW29iamVjdCBXaW5kb3ddIj09YylyZXR1cm4ib2JqZWN0IjtpZigiW29iamVjdCBBcnJheV0iPT1jfHwibnVtYmVyIj09dHlwZW9mIGEubGVuZ3RoJiYidW5kZWZpbmVkIiE9dHlwZW9mIGEuc3BsaWNlJiYidW5kZWZpbmVkIiE9dHlwZW9mIGEucHJvcGVydHlJc0VudW1lcmFibGUmJiFhLnByb3BlcnR5SXNFbnVtZXJhYmxlKCJzcGxpY2UiKSlyZXR1cm4iYXJyYXkiO2lmKCJbb2JqZWN0IEZ1bmN0aW9uXSI9PWN8fCJ1bmRlZmluZWQiIT10eXBlb2YgYS5jYWxsJiYidW5kZWZpbmVkIiE9dHlwZW9mIGEucHJvcGVydHlJc0VudW1lcmFibGUmJiFhLnByb3BlcnR5SXNFbnVtZXJhYmxlKCJjYWxsIikpcmV0dXJuImZ1bmN0aW9uIn1lbHNlIHJldHVybiJudWxsIjtlbHNlIGlmKCJmdW5jdGlvbiI9PQpiJiYidW5kZWZpbmVkIj09dHlwZW9mIGEuY2FsbClyZXR1cm4ib2JqZWN0IjtyZXR1cm4gYn1mdW5jdGlvbiBrKGEpe3JldHVybiJzdHJpbmciPT10eXBlb2YgYX1mdW5jdGlvbiBiYShhLGIsYyl7cmV0dXJuIGEuY2FsbC5hcHBseShhLmJpbmQsYXJndW1lbnRzKX1mdW5jdGlvbiBjYShhLGIsYyl7aWYoIWEpdGhyb3cgRXJyb3IoKTtpZigyPGFyZ3VtZW50cy5sZW5ndGgpe3ZhciBkPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywyKTtyZXR1cm4gZnVuY3Rpb24oKXt2YXIgYz1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO0FycmF5LnByb3RvdHlwZS51bnNoaWZ0LmFwcGx5KGMsZCk7cmV0dXJuIGEuYXBwbHkoYixjKX19cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGEuYXBwbHkoYixhcmd1bWVudHMpfX0KZnVuY3Rpb24gZGEoYSxiLGMpe2RhPUZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kJiYtMSE9RnVuY3Rpb24ucHJvdG90eXBlLmJpbmQudG9TdHJpbmcoKS5pbmRleE9mKCJuYXRpdmUgY29kZSIpP2JhOmNhO3JldHVybiBkYS5hcHBseShudWxsLGFyZ3VtZW50cyl9ZnVuY3Rpb24gZWEoYSxiKXt2YXIgYz1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMSk7cmV0dXJuIGZ1bmN0aW9uKCl7dmFyIGI9Yy5zbGljZSgpO2IucHVzaC5hcHBseShiLGFyZ3VtZW50cyk7cmV0dXJuIGEuYXBwbHkodGhpcyxiKX19CmZ1bmN0aW9uIG0oYSl7dmFyIGI9bjtmdW5jdGlvbiBjKCl7fWMucHJvdG90eXBlPWIucHJvdG90eXBlO2EudT1iLnByb3RvdHlwZTthLnByb3RvdHlwZT1uZXcgYzthLnByb3RvdHlwZS5jb25zdHJ1Y3Rvcj1hO2EudD1mdW5jdGlvbihhLGMsZil7cmV0dXJuIGIucHJvdG90eXBlW2NdLmFwcGx5KGEsQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDIpKX19O3ZhciBmYT1TdHJpbmcucHJvdG90eXBlLnRyaW0/ZnVuY3Rpb24oYSl7cmV0dXJuIGEudHJpbSgpfTpmdW5jdGlvbihhKXtyZXR1cm4gYS5yZXBsYWNlKC9eW1xzXHhhMF0rfFtcc1x4YTBdKyQvZywiIil9O2Z1bmN0aW9uIGdhKGEsYil7cmV0dXJuIGE8Yj8tMTphPmI/MTowfTt2YXIgcTthOnt2YXIgaGE9aC5uYXZpZ2F0b3I7aWYoaGEpe3ZhciBpYT1oYS51c2VyQWdlbnQ7aWYoaWEpe3E9aWE7YnJlYWsgYX19cT0iIn1mdW5jdGlvbiByKGEpe3JldHVybi0xIT1xLmluZGV4T2YoYSl9O3ZhciBzPUFycmF5LnByb3RvdHlwZSxqYT1zLmluZGV4T2Y/ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBzLmluZGV4T2YuY2FsbChhLGIsYyl9OmZ1bmN0aW9uKGEsYixjKXtjPW51bGw9PWM/MDowPmM/TWF0aC5tYXgoMCxhLmxlbmd0aCtjKTpjO2lmKGsoYSkpcmV0dXJuIGsoYikmJjE9PWIubGVuZ3RoP2EuaW5kZXhPZihiLGMpOi0xO2Zvcig7YzxhLmxlbmd0aDtjKyspaWYoYyBpbiBhJiZhW2NdPT09YilyZXR1cm4gYztyZXR1cm4tMX0sdD1zLmZvckVhY2g/ZnVuY3Rpb24oYSxiLGMpe3MuZm9yRWFjaC5jYWxsKGEsYixjKX06ZnVuY3Rpb24oYSxiLGMpe2Zvcih2YXIgZD1hLmxlbmd0aCxlPWsoYSk/YS5zcGxpdCgiIik6YSxmPTA7ZjxkO2YrKylmIGluIGUmJmIuY2FsbChjLGVbZl0sZixhKX0sa2E9cy5maWx0ZXI/ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBzLmZpbHRlci5jYWxsKGEsYixjKX06ZnVuY3Rpb24oYSxiLGMpe2Zvcih2YXIgZD1hLmxlbmd0aCxlPVtdLGY9MCxnPWsoYSk/CmEuc3BsaXQoIiIpOmEsbD0wO2w8ZDtsKyspaWYobCBpbiBnKXt2YXIgcD1nW2xdO2IuY2FsbChjLHAsbCxhKSYmKGVbZisrXT1wKX1yZXR1cm4gZX0sdT1zLnJlZHVjZT9mdW5jdGlvbihhLGIsYyxkKXtkJiYoYj1kYShiLGQpKTtyZXR1cm4gcy5yZWR1Y2UuY2FsbChhLGIsYyl9OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlPWM7dChhLGZ1bmN0aW9uKGMsZyl7ZT1iLmNhbGwoZCxlLGMsZyxhKX0pO3JldHVybiBlfSxsYT1zLnNvbWU/ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBzLnNvbWUuY2FsbChhLGIsYyl9OmZ1bmN0aW9uKGEsYixjKXtmb3IodmFyIGQ9YS5sZW5ndGgsZT1rKGEpP2Euc3BsaXQoIiIpOmEsZj0wO2Y8ZDtmKyspaWYoZiBpbiBlJiZiLmNhbGwoYyxlW2ZdLGYsYSkpcmV0dXJuITA7cmV0dXJuITF9OwpmdW5jdGlvbiBtYShhLGIpe3ZhciBjO2E6e2M9YS5sZW5ndGg7Zm9yKHZhciBkPWsoYSk/YS5zcGxpdCgiIik6YSxlPTA7ZTxjO2UrKylpZihlIGluIGQmJmIuY2FsbCh2b2lkIDAsZFtlXSxlLGEpKXtjPWU7YnJlYWsgYX1jPS0xfXJldHVybiAwPmM/bnVsbDprKGEpP2EuY2hhckF0KGMpOmFbY119ZnVuY3Rpb24gbmEoYSl7cmV0dXJuIHMuY29uY2F0LmFwcGx5KHMsYXJndW1lbnRzKX1mdW5jdGlvbiBvYShhLGIsYyl7cmV0dXJuIDI+PWFyZ3VtZW50cy5sZW5ndGg/cy5zbGljZS5jYWxsKGEsYik6cy5zbGljZS5jYWxsKGEsYixjKX07dmFyIHBhPXIoIk9wZXJhIil8fHIoIk9QUiIpLHY9cigiVHJpZGVudCIpfHxyKCJNU0lFIikscWE9cigiR2Vja28iKSYmLTE9PXEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCJ3ZWJraXQiKSYmIShyKCJUcmlkZW50Iil8fHIoIk1TSUUiKSkscmE9LTEhPXEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCJ3ZWJraXQiKTtmdW5jdGlvbiBzYSgpe3ZhciBhPWguZG9jdW1lbnQ7cmV0dXJuIGE/YS5kb2N1bWVudE1vZGU6dm9pZCAwfQp2YXIgdGE9ZnVuY3Rpb24oKXt2YXIgYT0iIixiO2lmKHBhJiZoLm9wZXJhKXJldHVybiBhPWgub3BlcmEudmVyc2lvbiwiZnVuY3Rpb24iPT1hYShhKT9hKCk6YTtxYT9iPS9ydlw6KFteXCk7XSspKFwpfDspLzp2P2I9L1xiKD86TVNJRXxydilbOiBdKFteXCk7XSspKFwpfDspLzpyYSYmKGI9L1dlYktpdFwvKFxTKykvKTtiJiYoYT0oYT1iLmV4ZWMocSkpP2FbMV06IiIpO3JldHVybiB2JiYoYj1zYSgpLGI+cGFyc2VGbG9hdChhKSk/U3RyaW5nKGIpOmF9KCksdWE9e307CmZ1bmN0aW9uIHZhKGEpe2lmKCF1YVthXSl7Zm9yKHZhciBiPTAsYz1mYShTdHJpbmcodGEpKS5zcGxpdCgiLiIpLGQ9ZmEoU3RyaW5nKGEpKS5zcGxpdCgiLiIpLGU9TWF0aC5tYXgoYy5sZW5ndGgsZC5sZW5ndGgpLGY9MDswPT1iJiZmPGU7ZisrKXt2YXIgZz1jW2ZdfHwiIixsPWRbZl18fCIiLHA9UmVnRXhwKCIoXFxkKikoXFxEKikiLCJnIikseD1SZWdFeHAoIihcXGQqKShcXEQqKSIsImciKTtkb3t2YXIgQz1wLmV4ZWMoZyl8fFsiIiwiIiwiIl0sWD14LmV4ZWMobCl8fFsiIiwiIiwiIl07aWYoMD09Q1swXS5sZW5ndGgmJjA9PVhbMF0ubGVuZ3RoKWJyZWFrO2I9Z2EoMD09Q1sxXS5sZW5ndGg/MDpwYXJzZUludChDWzFdLDEwKSwwPT1YWzFdLmxlbmd0aD8wOnBhcnNlSW50KFhbMV0sMTApKXx8Z2EoMD09Q1syXS5sZW5ndGgsMD09WFsyXS5sZW5ndGgpfHxnYShDWzJdLFhbMl0pfXdoaWxlKDA9PWIpfXVhW2FdPTA8PWJ9fQp2YXIgd2E9aC5kb2N1bWVudCx4YT13YSYmdj9zYSgpfHwoIkNTUzFDb21wYXQiPT13YS5jb21wYXRNb2RlP3BhcnNlSW50KHRhLDEwKTo1KTp2b2lkIDA7IXFhJiYhdnx8diYmdiYmOTw9eGF8fHFhJiZ2YSgiMS45LjEiKTt2JiZ2YSgiOSIpO2Z1bmN0aW9uIHlhKGEsYil7aWYoYS5jb250YWlucyYmMT09Yi5ub2RlVHlwZSlyZXR1cm4gYT09Ynx8YS5jb250YWlucyhiKTtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24pcmV0dXJuIGE9PWJ8fEJvb2xlYW4oYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihiKSYxNik7Zm9yKDtiJiZhIT1iOyliPWIucGFyZW50Tm9kZTtyZXR1cm4gYj09YX0KZnVuY3Rpb24gemEoYSxiKXtpZihhPT1iKXJldHVybiAwO2lmKGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24pcmV0dXJuIGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oYikmMj8xOi0xO2lmKHYmJiEodiYmOTw9eGEpKXtpZig5PT1hLm5vZGVUeXBlKXJldHVybi0xO2lmKDk9PWIubm9kZVR5cGUpcmV0dXJuIDF9aWYoInNvdXJjZUluZGV4ImluIGF8fGEucGFyZW50Tm9kZSYmInNvdXJjZUluZGV4ImluIGEucGFyZW50Tm9kZSl7dmFyIGM9MT09YS5ub2RlVHlwZSxkPTE9PWIubm9kZVR5cGU7aWYoYyYmZClyZXR1cm4gYS5zb3VyY2VJbmRleC1iLnNvdXJjZUluZGV4O3ZhciBlPWEucGFyZW50Tm9kZSxmPWIucGFyZW50Tm9kZTtyZXR1cm4gZT09Zj9BYShhLGIpOiFjJiZ5YShlLGIpPy0xKkJhKGEsYik6IWQmJnlhKGYsYSk/QmEoYixhKTooYz9hLnNvdXJjZUluZGV4OmUuc291cmNlSW5kZXgpLShkP2Iuc291cmNlSW5kZXg6Zi5zb3VyY2VJbmRleCl9ZD05PT1hLm5vZGVUeXBlP2E6CmEub3duZXJEb2N1bWVudHx8YS5kb2N1bWVudDtjPWQuY3JlYXRlUmFuZ2UoKTtjLnNlbGVjdE5vZGUoYSk7Yy5jb2xsYXBzZSghMCk7ZD1kLmNyZWF0ZVJhbmdlKCk7ZC5zZWxlY3ROb2RlKGIpO2QuY29sbGFwc2UoITApO3JldHVybiBjLmNvbXBhcmVCb3VuZGFyeVBvaW50cyhoLlJhbmdlLlNUQVJUX1RPX0VORCxkKX1mdW5jdGlvbiBCYShhLGIpe3ZhciBjPWEucGFyZW50Tm9kZTtpZihjPT1iKXJldHVybi0xO2Zvcih2YXIgZD1iO2QucGFyZW50Tm9kZSE9YzspZD1kLnBhcmVudE5vZGU7cmV0dXJuIEFhKGQsYSl9ZnVuY3Rpb24gQWEoYSxiKXtmb3IodmFyIGM9YjtjPWMucHJldmlvdXNTaWJsaW5nOylpZihjPT1hKXJldHVybi0xO3JldHVybiAxfTtmdW5jdGlvbiB3KGEsYixjKXt0aGlzLmE9YTt0aGlzLmI9Ynx8MTt0aGlzLmQ9Y3x8MX07ZnVuY3Rpb24gQ2EoYSl7dGhpcy5iPWE7dGhpcy5hPTB9ZnVuY3Rpb24gRGEoYSl7YT1hLm1hdGNoKEVhKTtmb3IodmFyIGI9MDtiPGEubGVuZ3RoO2IrKylGYS50ZXN0KGFbYl0pJiZhLnNwbGljZShiLDEpO3JldHVybiBuZXcgQ2EoYSl9dmFyIEVhPVJlZ0V4cCgiXFwkPyg/Oig/IVswLTktXSlbXFx3LV0rOik/KD8hWzAtOS1dKVtcXHctXSt8XFwvXFwvfFxcLlxcLnw6OnxcXGQrKD86XFwuXFxkKik/fFxcLlxcZCt8XCJbXlwiXSpcInwnW14nXSonfFshPD5dPXxcXHMrfC4iLCJnIiksRmE9L15ccy87ZnVuY3Rpb24geShhLGIpe3JldHVybiBhLmJbYS5hKyhifHwwKV19ZnVuY3Rpb24geihhKXtyZXR1cm4gYS5iW2EuYSsrXX1mdW5jdGlvbiBHYShhKXtyZXR1cm4gYS5iLmxlbmd0aDw9YS5hfTtmdW5jdGlvbiBBKGEsYil7dGhpcy5oPWEudG9Mb3dlckNhc2UoKTt0aGlzLmM9Yj9iLnRvTG93ZXJDYXNlKCk6Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwifUEucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7dmFyIGI9YS5ub2RlVHlwZTtyZXR1cm4gMSE9YiYmMiE9Yj8hMToiKiIhPXRoaXMuaCYmdGhpcy5oIT1hLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk/ITE6dGhpcy5jPT0oYS5uYW1lc3BhY2VVUkk/YS5uYW1lc3BhY2VVUkkudG9Mb3dlckNhc2UoKToiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIpfTtBLnByb3RvdHlwZS5kPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaH07QS5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4iTmFtZSBUZXN0OiAiKygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI9PXRoaXMuYz8iIjp0aGlzLmMrIjoiKSt0aGlzLmh9O2Z1bmN0aW9uIEIoYSxiKXt0aGlzLmY9YTt0aGlzLmM9dm9pZCAwIT09Yj9iOm51bGw7dGhpcy5iPW51bGw7c3dpdGNoKGEpe2Nhc2UgImNvbW1lbnQiOnRoaXMuYj04O2JyZWFrO2Nhc2UgInRleHQiOnRoaXMuYj0zO2JyZWFrO2Nhc2UgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iOnRoaXMuYj03O2JyZWFrO2Nhc2UgIm5vZGUiOmJyZWFrO2RlZmF1bHQ6dGhyb3cgRXJyb3IoIlVuZXhwZWN0ZWQgYXJndW1lbnQiKTt9fWZ1bmN0aW9uIEhhKGEpe3JldHVybiJjb21tZW50Ij09YXx8InRleHQiPT1hfHwicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiI9PWF8fCJub2RlIj09YX1CLnByb3RvdHlwZS5hPWZ1bmN0aW9uKGEpe3JldHVybiBudWxsPT09dGhpcy5ifHx0aGlzLmI9PWEubm9kZVR5cGV9O0IucHJvdG90eXBlLmQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5mfTsKQi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXt2YXIgYT0iS2luZCBUZXN0OiAiK3RoaXMuZjtudWxsPT09dGhpcy5jfHwoYSs9RCh0aGlzLmMpKTtyZXR1cm4gYX07ZnVuY3Rpb24gSWEoYSl7c3dpdGNoKGEubm9kZVR5cGUpe2Nhc2UgMTpyZXR1cm4gZWEoSmEsYSk7Y2FzZSA5OnJldHVybiBJYShhLmRvY3VtZW50RWxlbWVudCk7Y2FzZSAxMTpjYXNlIDEwOmNhc2UgNjpjYXNlIDEyOnJldHVybiBLYTtkZWZhdWx0OnJldHVybiBhLnBhcmVudE5vZGU/SWEoYS5wYXJlbnROb2RlKTpLYX19ZnVuY3Rpb24gS2EoKXtyZXR1cm4gbnVsbH1mdW5jdGlvbiBKYShhLGIpe2lmKGEucHJlZml4PT1iKXJldHVybiBhLm5hbWVzcGFjZVVSSXx8Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiO3ZhciBjPWEuZ2V0QXR0cmlidXRlTm9kZSgieG1sbnM6IitiKTtyZXR1cm4gYyYmYy5zcGVjaWZpZWQ/Yy52YWx1ZXx8bnVsbDphLnBhcmVudE5vZGUmJjkhPWEucGFyZW50Tm9kZS5ub2RlVHlwZT9KYShhLnBhcmVudE5vZGUsYik6bnVsbH07dmFyIEU9diYmISh2JiY5PD14YSksTGE9diYmISh2JiY4PD14YSk7ZnVuY3Rpb24gRihhLGIsYyxkKXt0aGlzLmE9YTt0aGlzLm5vZGVOYW1lPWM7dGhpcy5ub2RlVmFsdWU9ZDt0aGlzLm5vZGVUeXBlPTI7dGhpcy5wYXJlbnROb2RlPXRoaXMub3duZXJFbGVtZW50PWJ9ZnVuY3Rpb24gTWEoYSxiKXt2YXIgYz1MYSYmImhyZWYiPT1iLm5vZGVOYW1lP2EuZ2V0QXR0cmlidXRlKGIubm9kZU5hbWUsMik6Yi5ub2RlVmFsdWU7cmV0dXJuIG5ldyBGKGIsYSxiLm5vZGVOYW1lLGMpfTtmdW5jdGlvbiBHKGEpe3ZhciBiPW51bGwsYz1hLm5vZGVUeXBlOzE9PWMmJihiPWEudGV4dENvbnRlbnQsYj12b2lkIDA9PWJ8fG51bGw9PWI/YS5pbm5lclRleHQ6YixiPXZvaWQgMD09Ynx8bnVsbD09Yj8iIjpiKTtpZigic3RyaW5nIiE9dHlwZW9mIGIpaWYoRSYmInRpdGxlIj09YS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpJiYxPT1jKWI9YS50ZXh0O2Vsc2UgaWYoOT09Y3x8MT09Yyl7YT05PT1jP2EuZG9jdW1lbnRFbGVtZW50OmEuZmlyc3RDaGlsZDtmb3IodmFyIGM9MCxkPVtdLGI9IiI7YTspe2RvIDEhPWEubm9kZVR5cGUmJihiKz1hLm5vZGVWYWx1ZSksRSYmInRpdGxlIj09YS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpJiYoYis9YS50ZXh0KSxkW2MrK109YTt3aGlsZShhPWEuZmlyc3RDaGlsZCk7Zm9yKDtjJiYhKGE9ZFstLWNdLm5leHRTaWJsaW5nKTspO319ZWxzZSBiPWEubm9kZVZhbHVlO3JldHVybiIiK2J9CmZ1bmN0aW9uIEgoYSxiLGMpe2lmKG51bGw9PT1iKXJldHVybiEwO3RyeXtpZighYS5nZXRBdHRyaWJ1dGUpcmV0dXJuITF9Y2F0Y2goZCl7cmV0dXJuITF9TGEmJiJjbGFzcyI9PWImJihiPSJjbGFzc05hbWUiKTtyZXR1cm4gbnVsbD09Yz8hIWEuZ2V0QXR0cmlidXRlKGIpOmEuZ2V0QXR0cmlidXRlKGIsMik9PWN9ZnVuY3Rpb24gSShhLGIsYyxkLGUpe3JldHVybihFP05hOk9hKS5jYWxsKG51bGwsYSxiLGsoYyk/YzpudWxsLGsoZCk/ZDpudWxsLGV8fG5ldyBKKX0KZnVuY3Rpb24gTmEoYSxiLGMsZCxlKXtpZihhIGluc3RhbmNlb2YgQXx8OD09YS5ifHxjJiZudWxsPT09YS5iKXt2YXIgZj1iLmFsbDtpZighZilyZXR1cm4gZTthPVBhKGEpO2lmKCIqIiE9YSYmKGY9Yi5nZXRFbGVtZW50c0J5VGFnTmFtZShhKSwhZikpcmV0dXJuIGU7aWYoYyl7Zm9yKHZhciBnPVtdLGw9MDtiPWZbbCsrXTspSChiLGMsZCkmJmcucHVzaChiKTtmPWd9Zm9yKGw9MDtiPWZbbCsrXTspIioiPT1hJiYiISI9PWIudGFnTmFtZXx8SyhlLGIpO3JldHVybiBlfVFhKGEsYixjLGQsZSk7cmV0dXJuIGV9CmZ1bmN0aW9uIE9hKGEsYixjLGQsZSl7Yi5nZXRFbGVtZW50c0J5TmFtZSYmZCYmIm5hbWUiPT1jJiYhdj8oYj1iLmdldEVsZW1lbnRzQnlOYW1lKGQpLHQoYixmdW5jdGlvbihiKXthLmEoYikmJksoZSxiKX0pKTpiLmdldEVsZW1lbnRzQnlDbGFzc05hbWUmJmQmJiJjbGFzcyI9PWM/KGI9Yi5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKGQpLHQoYixmdW5jdGlvbihiKXtiLmNsYXNzTmFtZT09ZCYmYS5hKGIpJiZLKGUsYil9KSk6YSBpbnN0YW5jZW9mIEI/UWEoYSxiLGMsZCxlKTpiLmdldEVsZW1lbnRzQnlUYWdOYW1lJiYoYj1iLmdldEVsZW1lbnRzQnlUYWdOYW1lKGEuZCgpKSx0KGIsZnVuY3Rpb24oYSl7SChhLGMsZCkmJksoZSxhKX0pKTtyZXR1cm4gZX0KZnVuY3Rpb24gUmEoYSxiLGMsZCxlKXt2YXIgZjtpZigoYSBpbnN0YW5jZW9mIEF8fDg9PWEuYnx8YyYmbnVsbD09PWEuYikmJihmPWIuY2hpbGROb2Rlcykpe3ZhciBnPVBhKGEpO2lmKCIqIiE9ZyYmKGY9a2EoZixmdW5jdGlvbihhKXtyZXR1cm4gYS50YWdOYW1lJiZhLnRhZ05hbWUudG9Mb3dlckNhc2UoKT09Z30pLCFmKSlyZXR1cm4gZTtjJiYoZj1rYShmLGZ1bmN0aW9uKGEpe3JldHVybiBIKGEsYyxkKX0pKTt0KGYsZnVuY3Rpb24oYSl7IioiPT1nJiYoIiEiPT1hLnRhZ05hbWV8fCIqIj09ZyYmMSE9YS5ub2RlVHlwZSl8fEsoZSxhKX0pO3JldHVybiBlfXJldHVybiBTYShhLGIsYyxkLGUpfWZ1bmN0aW9uIFNhKGEsYixjLGQsZSl7Zm9yKGI9Yi5maXJzdENoaWxkO2I7Yj1iLm5leHRTaWJsaW5nKUgoYixjLGQpJiZhLmEoYikmJksoZSxiKTtyZXR1cm4gZX0KZnVuY3Rpb24gUWEoYSxiLGMsZCxlKXtmb3IoYj1iLmZpcnN0Q2hpbGQ7YjtiPWIubmV4dFNpYmxpbmcpSChiLGMsZCkmJmEuYShiKSYmSyhlLGIpLFFhKGEsYixjLGQsZSl9ZnVuY3Rpb24gUGEoYSl7aWYoYSBpbnN0YW5jZW9mIEIpe2lmKDg9PWEuYilyZXR1cm4iISI7aWYobnVsbD09PWEuYilyZXR1cm4iKiJ9cmV0dXJuIGEuZCgpfTtmdW5jdGlvbiBKKCl7dGhpcy5iPXRoaXMuYT1udWxsO3RoaXMuaT0wfWZ1bmN0aW9uIFRhKGEpe3RoaXMuZD1hO3RoaXMuYT10aGlzLmI9bnVsbH1mdW5jdGlvbiBVYShhLGIpe2lmKCFhLmEpcmV0dXJuIGI7aWYoIWIuYSlyZXR1cm4gYTtmb3IodmFyIGM9YS5hLGQ9Yi5hLGU9bnVsbCxmPW51bGwsZz0wO2MmJmQ7KXt2YXIgZj1jLmQsbD1kLmQ7Zj09bHx8ZiBpbnN0YW5jZW9mIEYmJmwgaW5zdGFuY2VvZiBGJiZmLmE9PWwuYT8oZj1jLGM9Yy5hLGQ9ZC5hKTowPHphKGMuZCxkLmQpPyhmPWQsZD1kLmEpOihmPWMsYz1jLmEpOyhmLmI9ZSk/ZS5hPWY6YS5hPWY7ZT1mO2crK31mb3IoZj1jfHxkO2Y7KWYuYj1lLGU9ZS5hPWYsZysrLGY9Zi5hO2EuYj1lO2EuaT1nO3JldHVybiBhfWZ1bmN0aW9uIFZhKGEsYil7dmFyIGM9bmV3IFRhKGIpO2MuYT1hLmE7YS5iP2EuYS5iPWM6YS5hPWEuYj1jO2EuYT1jO2EuaSsrfQpmdW5jdGlvbiBLKGEsYil7dmFyIGM9bmV3IFRhKGIpO2MuYj1hLmI7YS5hP2EuYi5hPWM6YS5hPWEuYj1jO2EuYj1jO2EuaSsrfWZ1bmN0aW9uIFdhKGEpe3JldHVybihhPWEuYSk/YS5kOm51bGx9ZnVuY3Rpb24gWGEoYSl7cmV0dXJuKGE9V2EoYSkpP0coYSk6IiJ9ZnVuY3Rpb24gTChhLGIpe3JldHVybiBuZXcgWWEoYSwhIWIpfWZ1bmN0aW9uIFlhKGEsYil7dGhpcy5kPWE7dGhpcy5iPSh0aGlzLmM9Yik/YS5iOmEuYTt0aGlzLmE9bnVsbH1mdW5jdGlvbiBNKGEpe3ZhciBiPWEuYjtpZihudWxsPT1iKXJldHVybiBudWxsO3ZhciBjPWEuYT1iO2EuYj1hLmM/Yi5iOmIuYTtyZXR1cm4gYy5kfTtmdW5jdGlvbiBuKGEpe3RoaXMuZz1hO3RoaXMuYj10aGlzLmU9ITE7dGhpcy5kPW51bGx9ZnVuY3Rpb24gRChhKXtyZXR1cm4iXG4gICIrYS50b1N0cmluZygpLnNwbGl0KCJcbiIpLmpvaW4oIlxuICAiKX1mdW5jdGlvbiBaYShhLGIpe2EuZT1ifWZ1bmN0aW9uICRhKGEsYil7YS5iPWJ9ZnVuY3Rpb24gTihhLGIpe3ZhciBjPWEuYShiKTtyZXR1cm4gYyBpbnN0YW5jZW9mIEo/K1hhKGMpOitjfWZ1bmN0aW9uIE8oYSxiKXt2YXIgYz1hLmEoYik7cmV0dXJuIGMgaW5zdGFuY2VvZiBKP1hhKGMpOiIiK2N9ZnVuY3Rpb24gUChhLGIpe3ZhciBjPWEuYShiKTtyZXR1cm4gYyBpbnN0YW5jZW9mIEo/ISFjLmk6ISFjfTtmdW5jdGlvbiBRKGEsYixjKXtuLmNhbGwodGhpcyxhLmcpO3RoaXMuYz1hO3RoaXMuZj1iO3RoaXMuaz1jO3RoaXMuZT1iLmV8fGMuZTt0aGlzLmI9Yi5ifHxjLmI7dGhpcy5jPT1hYiYmKGMuYnx8Yy5lfHw0PT1jLmd8fDA9PWMuZ3x8IWIuZD9iLmJ8fGIuZXx8ND09Yi5nfHwwPT1iLmd8fCFjLmR8fCh0aGlzLmQ9e25hbWU6Yy5kLm5hbWUsbDpifSk6dGhpcy5kPXtuYW1lOmIuZC5uYW1lLGw6Y30pfW0oUSk7CmZ1bmN0aW9uIFIoYSxiLGMsZCxlKXtiPWIuYShkKTtjPWMuYShkKTt2YXIgZjtpZihiIGluc3RhbmNlb2YgSiYmYyBpbnN0YW5jZW9mIEope2U9TChiKTtmb3IoZD1NKGUpO2Q7ZD1NKGUpKWZvcihiPUwoYyksZj1NKGIpO2Y7Zj1NKGIpKWlmKGEoRyhkKSxHKGYpKSlyZXR1cm4hMDtyZXR1cm4hMX1pZihiIGluc3RhbmNlb2YgSnx8YyBpbnN0YW5jZW9mIEope2IgaW5zdGFuY2VvZiBKP2U9YjooZT1jLGM9Yik7ZT1MKGUpO2I9dHlwZW9mIGM7Zm9yKGQ9TShlKTtkO2Q9TShlKSl7c3dpdGNoKGIpe2Nhc2UgIm51bWJlciI6ZD0rRyhkKTticmVhaztjYXNlICJib29sZWFuIjpkPSEhRyhkKTticmVhaztjYXNlICJzdHJpbmciOmQ9RyhkKTticmVhaztkZWZhdWx0OnRocm93IEVycm9yKCJJbGxlZ2FsIHByaW1pdGl2ZSB0eXBlIGZvciBjb21wYXJpc29uLiIpO31pZihhKGQsYykpcmV0dXJuITB9cmV0dXJuITF9cmV0dXJuIGU/ImJvb2xlYW4iPT10eXBlb2YgYnx8ImJvb2xlYW4iPT10eXBlb2YgYz8KYSghIWIsISFjKToibnVtYmVyIj09dHlwZW9mIGJ8fCJudW1iZXIiPT10eXBlb2YgYz9hKCtiLCtjKTphKGIsYyk6YSgrYiwrYyl9US5wcm90b3R5cGUuYT1mdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5jLmoodGhpcy5mLHRoaXMuayxhKX07US5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXt2YXIgYT0iQmluYXJ5IEV4cHJlc3Npb246ICIrdGhpcy5jLGE9YStEKHRoaXMuZik7cmV0dXJuIGErPUQodGhpcy5rKX07ZnVuY3Rpb24gYmIoYSxiLGMsZCl7dGhpcy5hPWE7dGhpcy5wPWI7dGhpcy5nPWM7dGhpcy5qPWR9YmIucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYX07dmFyIGNiPXt9O2Z1bmN0aW9uIFMoYSxiLGMsZCl7aWYoY2IuaGFzT3duUHJvcGVydHkoYSkpdGhyb3cgRXJyb3IoIkJpbmFyeSBvcGVyYXRvciBhbHJlYWR5IGNyZWF0ZWQ6ICIrYSk7YT1uZXcgYmIoYSxiLGMsZCk7cmV0dXJuIGNiW2EudG9TdHJpbmcoKV09YX0KUygiZGl2Iiw2LDEsZnVuY3Rpb24oYSxiLGMpe3JldHVybiBOKGEsYykvTihiLGMpfSk7UygibW9kIiw2LDEsZnVuY3Rpb24oYSxiLGMpe3JldHVybiBOKGEsYyklTihiLGMpfSk7UygiKiIsNiwxLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gTihhLGMpKk4oYixjKX0pO1MoIisiLDUsMSxmdW5jdGlvbihhLGIsYyl7cmV0dXJuIE4oYSxjKStOKGIsYyl9KTtTKCItIiw1LDEsZnVuY3Rpb24oYSxiLGMpe3JldHVybiBOKGEsYyktTihiLGMpfSk7UygiPCIsNCwyLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gUihmdW5jdGlvbihhLGIpe3JldHVybiBhPGJ9LGEsYixjKX0pO1MoIj4iLDQsMixmdW5jdGlvbihhLGIsYyl7cmV0dXJuIFIoZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT5ifSxhLGIsYyl9KTtTKCI8PSIsNCwyLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gUihmdW5jdGlvbihhLGIpe3JldHVybiBhPD1ifSxhLGIsYyl9KTsKUygiPj0iLDQsMixmdW5jdGlvbihhLGIsYyl7cmV0dXJuIFIoZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT49Yn0sYSxiLGMpfSk7dmFyIGFiPVMoIj0iLDMsMixmdW5jdGlvbihhLGIsYyl7cmV0dXJuIFIoZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT09Yn0sYSxiLGMsITApfSk7UygiIT0iLDMsMixmdW5jdGlvbihhLGIsYyl7cmV0dXJuIFIoZnVuY3Rpb24oYSxiKXtyZXR1cm4gYSE9Yn0sYSxiLGMsITApfSk7UygiYW5kIiwyLDIsZnVuY3Rpb24oYSxiLGMpe3JldHVybiBQKGEsYykmJlAoYixjKX0pO1MoIm9yIiwxLDIsZnVuY3Rpb24oYSxiLGMpe3JldHVybiBQKGEsYyl8fFAoYixjKX0pO2Z1bmN0aW9uIGRiKGEsYil7aWYoYi5hLmxlbmd0aCYmNCE9YS5nKXRocm93IEVycm9yKCJQcmltYXJ5IGV4cHJlc3Npb24gbXVzdCBldmFsdWF0ZSB0byBub2Rlc2V0IGlmIGZpbHRlciBoYXMgcHJlZGljYXRlKHMpLiIpO24uY2FsbCh0aGlzLGEuZyk7dGhpcy5jPWE7dGhpcy5mPWI7dGhpcy5lPWEuZTt0aGlzLmI9YS5ifW0oZGIpO2RiLnByb3RvdHlwZS5hPWZ1bmN0aW9uKGEpe2E9dGhpcy5jLmEoYSk7cmV0dXJuIGViKHRoaXMuZixhKX07ZGIucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7dmFyIGE7YT0iRmlsdGVyOiIrRCh0aGlzLmMpO3JldHVybiBhKz1EKHRoaXMuZil9O2Z1bmN0aW9uIGZiKGEsYil7aWYoYi5sZW5ndGg8YS5vKXRocm93IEVycm9yKCJGdW5jdGlvbiAiK2EuaCsiIGV4cGVjdHMgYXQgbGVhc3QiK2EubysiIGFyZ3VtZW50cywgIitiLmxlbmd0aCsiIGdpdmVuIik7aWYobnVsbCE9PWEubiYmYi5sZW5ndGg+YS5uKXRocm93IEVycm9yKCJGdW5jdGlvbiAiK2EuaCsiIGV4cGVjdHMgYXQgbW9zdCAiK2EubisiIGFyZ3VtZW50cywgIitiLmxlbmd0aCsiIGdpdmVuIik7YS5zJiZ0KGIsZnVuY3Rpb24oYixkKXtpZig0IT1iLmcpdGhyb3cgRXJyb3IoIkFyZ3VtZW50ICIrZCsiIHRvIGZ1bmN0aW9uICIrYS5oKyIgaXMgbm90IG9mIHR5cGUgTm9kZXNldDogIitiKTt9KTtuLmNhbGwodGhpcyxhLmcpO3RoaXMuZj1hO3RoaXMuYz1iO1phKHRoaXMsYS5lfHxsYShiLGZ1bmN0aW9uKGEpe3JldHVybiBhLmV9KSk7JGEodGhpcyxhLnImJiFiLmxlbmd0aHx8YS5xJiYhIWIubGVuZ3RofHxsYShiLGZ1bmN0aW9uKGEpe3JldHVybiBhLmJ9KSl9bShmYik7CmZiLnByb3RvdHlwZS5hPWZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmYuai5hcHBseShudWxsLG5hKGEsdGhpcy5jKSl9O2ZiLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3ZhciBhPSJGdW5jdGlvbjogIit0aGlzLmY7aWYodGhpcy5jLmxlbmd0aCl2YXIgYj11KHRoaXMuYyxmdW5jdGlvbihhLGIpe3JldHVybiBhK0QoYil9LCJBcmd1bWVudHM6IiksYT1hK0QoYik7cmV0dXJuIGF9O2Z1bmN0aW9uIGdiKGEsYixjLGQsZSxmLGcsbCxwKXt0aGlzLmg9YTt0aGlzLmc9Yjt0aGlzLmU9Yzt0aGlzLnI9ZDt0aGlzLnE9ZTt0aGlzLmo9Zjt0aGlzLm89Zzt0aGlzLm49dm9pZCAwIT09bD9sOmc7dGhpcy5zPSEhcH1nYi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ofTt2YXIgaGI9e307CmZ1bmN0aW9uIFQoYSxiLGMsZCxlLGYsZyxsKXtpZihoYi5oYXNPd25Qcm9wZXJ0eShhKSl0aHJvdyBFcnJvcigiRnVuY3Rpb24gYWxyZWFkeSBjcmVhdGVkOiAiK2ErIi4iKTtoYlthXT1uZXcgZ2IoYSxiLGMsZCwhMSxlLGYsZyxsKX1UKCJib29sZWFuIiwyLCExLCExLGZ1bmN0aW9uKGEsYil7cmV0dXJuIFAoYixhKX0sMSk7VCgiY2VpbGluZyIsMSwhMSwhMSxmdW5jdGlvbihhLGIpe3JldHVybiBNYXRoLmNlaWwoTihiLGEpKX0sMSk7VCgiY29uY2F0IiwzLCExLCExLGZ1bmN0aW9uKGEsYil7cmV0dXJuIHUob2EoYXJndW1lbnRzLDEpLGZ1bmN0aW9uKGIsZCl7cmV0dXJuIGIrTyhkLGEpfSwiIil9LDIsbnVsbCk7VCgiY29udGFpbnMiLDIsITEsITEsZnVuY3Rpb24oYSxiLGMpe2I9TyhiLGEpO2E9TyhjLGEpO3JldHVybi0xIT1iLmluZGV4T2YoYSl9LDIpO1QoImNvdW50IiwxLCExLCExLGZ1bmN0aW9uKGEsYil7cmV0dXJuIGIuYShhKS5pfSwxLDEsITApOwpUKCJmYWxzZSIsMiwhMSwhMSxmdW5jdGlvbigpe3JldHVybiExfSwwKTtUKCJmbG9vciIsMSwhMSwhMSxmdW5jdGlvbihhLGIpe3JldHVybiBNYXRoLmZsb29yKE4oYixhKSl9LDEpO1QoImlkIiw0LCExLCExLGZ1bmN0aW9uKGEsYil7ZnVuY3Rpb24gYyhhKXtpZihFKXt2YXIgYj1lLmFsbFthXTtpZihiKXtpZihiLm5vZGVUeXBlJiZhPT1iLmlkKXJldHVybiBiO2lmKGIubGVuZ3RoKXJldHVybiBtYShiLGZ1bmN0aW9uKGIpe3JldHVybiBhPT1iLmlkfSl9cmV0dXJuIG51bGx9cmV0dXJuIGUuZ2V0RWxlbWVudEJ5SWQoYSl9dmFyIGQ9YS5hLGU9OT09ZC5ub2RlVHlwZT9kOmQub3duZXJEb2N1bWVudCxkPU8oYixhKS5zcGxpdCgvXHMrLyksZj1bXTt0KGQsZnVuY3Rpb24oYSl7YT1jKGEpOyFhfHwwPD1qYShmLGEpfHxmLnB1c2goYSl9KTtmLnNvcnQoemEpO3ZhciBnPW5ldyBKO3QoZixmdW5jdGlvbihhKXtLKGcsYSl9KTtyZXR1cm4gZ30sMSk7ClQoImxhbmciLDIsITEsITEsZnVuY3Rpb24oKXtyZXR1cm4hMX0sMSk7VCgibGFzdCIsMSwhMCwhMSxmdW5jdGlvbihhKXtpZigxIT1hcmd1bWVudHMubGVuZ3RoKXRocm93IEVycm9yKCJGdW5jdGlvbiBsYXN0IGV4cGVjdHMgKCkiKTtyZXR1cm4gYS5kfSwwKTtUKCJsb2NhbC1uYW1lIiwzLCExLCEwLGZ1bmN0aW9uKGEsYil7dmFyIGM9Yj9XYShiLmEoYSkpOmEuYTtyZXR1cm4gYz9jLmxvY2FsTmFtZXx8Yy5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpOiIifSwwLDEsITApO1QoIm5hbWUiLDMsITEsITAsZnVuY3Rpb24oYSxiKXt2YXIgYz1iP1dhKGIuYShhKSk6YS5hO3JldHVybiBjP2Mubm9kZU5hbWUudG9Mb3dlckNhc2UoKToiIn0sMCwxLCEwKTtUKCJuYW1lc3BhY2UtdXJpIiwzLCEwLCExLGZ1bmN0aW9uKCl7cmV0dXJuIiJ9LDAsMSwhMCk7ClQoIm5vcm1hbGl6ZS1zcGFjZSIsMywhMSwhMCxmdW5jdGlvbihhLGIpe3JldHVybihiP08oYixhKTpHKGEuYSkpLnJlcGxhY2UoL1tcc1x4YTBdKy9nLCIgIikucmVwbGFjZSgvXlxzK3xccyskL2csIiIpfSwwLDEpO1QoIm5vdCIsMiwhMSwhMSxmdW5jdGlvbihhLGIpe3JldHVybiFQKGIsYSl9LDEpO1QoIm51bWJlciIsMSwhMSwhMCxmdW5jdGlvbihhLGIpe3JldHVybiBiP04oYixhKTorRyhhLmEpfSwwLDEpO1QoInBvc2l0aW9uIiwxLCEwLCExLGZ1bmN0aW9uKGEpe3JldHVybiBhLmJ9LDApO1QoInJvdW5kIiwxLCExLCExLGZ1bmN0aW9uKGEsYil7cmV0dXJuIE1hdGgucm91bmQoTihiLGEpKX0sMSk7VCgic3RhcnRzLXdpdGgiLDIsITEsITEsZnVuY3Rpb24oYSxiLGMpe2I9TyhiLGEpO2E9TyhjLGEpO3JldHVybiAwPT1iLmxhc3RJbmRleE9mKGEsMCl9LDIpO1QoInN0cmluZyIsMywhMSwhMCxmdW5jdGlvbihhLGIpe3JldHVybiBiP08oYixhKTpHKGEuYSl9LDAsMSk7ClQoInN0cmluZy1sZW5ndGgiLDEsITEsITAsZnVuY3Rpb24oYSxiKXtyZXR1cm4oYj9PKGIsYSk6RyhhLmEpKS5sZW5ndGh9LDAsMSk7VCgic3Vic3RyaW5nIiwzLCExLCExLGZ1bmN0aW9uKGEsYixjLGQpe2M9TihjLGEpO2lmKGlzTmFOKGMpfHxJbmZpbml0eT09Y3x8LUluZmluaXR5PT1jKXJldHVybiIiO2Q9ZD9OKGQsYSk6SW5maW5pdHk7aWYoaXNOYU4oZCl8fC1JbmZpbml0eT09PWQpcmV0dXJuIiI7Yz1NYXRoLnJvdW5kKGMpLTE7dmFyIGU9TWF0aC5tYXgoYywwKTthPU8oYixhKTtpZihJbmZpbml0eT09ZClyZXR1cm4gYS5zdWJzdHJpbmcoZSk7Yj1NYXRoLnJvdW5kKGQpO3JldHVybiBhLnN1YnN0cmluZyhlLGMrYil9LDIsMyk7VCgic3Vic3RyaW5nLWFmdGVyIiwzLCExLCExLGZ1bmN0aW9uKGEsYixjKXtiPU8oYixhKTthPU8oYyxhKTtjPWIuaW5kZXhPZihhKTtyZXR1cm4tMT09Yz8iIjpiLnN1YnN0cmluZyhjK2EubGVuZ3RoKX0sMik7ClQoInN1YnN0cmluZy1iZWZvcmUiLDMsITEsITEsZnVuY3Rpb24oYSxiLGMpe2I9TyhiLGEpO2E9TyhjLGEpO2E9Yi5pbmRleE9mKGEpO3JldHVybi0xPT1hPyIiOmIuc3Vic3RyaW5nKDAsYSl9LDIpO1QoInN1bSIsMSwhMSwhMSxmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz1MKGIuYShhKSksZD0wLGU9TShjKTtlO2U9TShjKSlkKz0rRyhlKTtyZXR1cm4gZH0sMSwxLCEwKTtUKCJ0cmFuc2xhdGUiLDMsITEsITEsZnVuY3Rpb24oYSxiLGMsZCl7Yj1PKGIsYSk7Yz1PKGMsYSk7dmFyIGU9TyhkLGEpO2E9W107Zm9yKGQ9MDtkPGMubGVuZ3RoO2QrKyl7dmFyIGY9Yy5jaGFyQXQoZCk7ZiBpbiBhfHwoYVtmXT1lLmNoYXJBdChkKSl9Yz0iIjtmb3IoZD0wO2Q8Yi5sZW5ndGg7ZCsrKWY9Yi5jaGFyQXQoZCksYys9ZiBpbiBhP2FbZl06ZjtyZXR1cm4gY30sMyk7VCgidHJ1ZSIsMiwhMSwhMSxmdW5jdGlvbigpe3JldHVybiEwfSwwKTtmdW5jdGlvbiBpYihhKXtuLmNhbGwodGhpcywzKTt0aGlzLmM9YS5zdWJzdHJpbmcoMSxhLmxlbmd0aC0xKX1tKGliKTtpYi5wcm90b3R5cGUuYT1mdW5jdGlvbigpe3JldHVybiB0aGlzLmN9O2liLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiJMaXRlcmFsOiAiK3RoaXMuY307ZnVuY3Rpb24gamIoYSl7bi5jYWxsKHRoaXMsMSk7dGhpcy5jPWF9bShqYik7amIucHJvdG90eXBlLmE9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jfTtqYi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4iTnVtYmVyOiAiK3RoaXMuY307ZnVuY3Rpb24ga2IoYSxiKXtuLmNhbGwodGhpcyxhLmcpO3RoaXMuZj1hO3RoaXMuYz1iO3RoaXMuZT1hLmU7dGhpcy5iPWEuYjtpZigxPT10aGlzLmMubGVuZ3RoKXt2YXIgYz10aGlzLmNbMF07Yy5tfHxjLmMhPWxifHwoYz1jLmssIioiIT1jLmQoKSYmKHRoaXMuZD17bmFtZTpjLmQoKSxsOm51bGx9KSl9fW0oa2IpO2Z1bmN0aW9uIFUoKXtuLmNhbGwodGhpcyw0KX1tKFUpO1UucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IEo7YT1hLmE7OT09YS5ub2RlVHlwZT9LKGIsYSk6SyhiLGEub3duZXJEb2N1bWVudCk7cmV0dXJuIGJ9O1UucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIlJvb3QgSGVscGVyIEV4cHJlc3Npb24ifTtmdW5jdGlvbiBtYigpe24uY2FsbCh0aGlzLDQpfW0obWIpO21iLnByb3RvdHlwZS5hPWZ1bmN0aW9uKGEpe3ZhciBiPW5ldyBKO0soYixhLmEpO3JldHVybiBifTttYi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4iQ29udGV4dCBIZWxwZXIgRXhwcmVzc2lvbiJ9OwpmdW5jdGlvbiBuYihhKXtyZXR1cm4iLyI9PWF8fCIvLyI9PWF9a2IucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcy5mLmEoYSk7aWYoIShiIGluc3RhbmNlb2YgSikpdGhyb3cgRXJyb3IoIkZpbHRlciBleHByZXNzaW9uIG11c3QgZXZhbHVhdGUgdG8gbm9kZXNldC4iKTthPXRoaXMuYztmb3IodmFyIGM9MCxkPWEubGVuZ3RoO2M8ZCYmYi5pO2MrKyl7dmFyIGU9YVtjXSxmPUwoYixlLmMuYSksZztpZihlLmV8fGUuYyE9b2IpaWYoZS5lfHxlLmMhPXBiKWZvcihnPU0oZiksYj1lLmEobmV3IHcoZykpO251bGwhPShnPU0oZikpOylnPWUuYShuZXcgdyhnKSksYj1VYShiLGcpO2Vsc2UgZz1NKGYpLGI9ZS5hKG5ldyB3KGcpKTtlbHNle2ZvcihnPU0oZik7KGI9TShmKSkmJighZy5jb250YWluc3x8Zy5jb250YWlucyhiKSkmJmIuY29tcGFyZURvY3VtZW50UG9zaXRpb24oZykmODtnPWIpO2I9ZS5hKG5ldyB3KGcpKX19cmV0dXJuIGJ9OwprYi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXt2YXIgYTthPSJQYXRoIEV4cHJlc3Npb246IitEKHRoaXMuZik7aWYodGhpcy5jLmxlbmd0aCl7dmFyIGI9dSh0aGlzLmMsZnVuY3Rpb24oYSxiKXtyZXR1cm4gYStEKGIpfSwiU3RlcHM6Iik7YSs9RChiKX1yZXR1cm4gYX07ZnVuY3Rpb24gcWIoYSxiKXt0aGlzLmE9YTt0aGlzLmI9ISFifQpmdW5jdGlvbiBlYihhLGIsYyl7Zm9yKGM9Y3x8MDtjPGEuYS5sZW5ndGg7YysrKWZvcih2YXIgZD1hLmFbY10sZT1MKGIpLGY9Yi5pLGcsbD0wO2c9TShlKTtsKyspe3ZhciBwPWEuYj9mLWw6bCsxO2c9ZC5hKG5ldyB3KGcscCxmKSk7aWYoIm51bWJlciI9PXR5cGVvZiBnKXA9cD09ZztlbHNlIGlmKCJzdHJpbmciPT10eXBlb2YgZ3x8ImJvb2xlYW4iPT10eXBlb2YgZylwPSEhZztlbHNlIGlmKGcgaW5zdGFuY2VvZiBKKXA9MDxnLmk7ZWxzZSB0aHJvdyBFcnJvcigiUHJlZGljYXRlLmV2YWx1YXRlIHJldHVybmVkIGFuIHVuZXhwZWN0ZWQgdHlwZS4iKTtpZighcCl7cD1lO2c9cC5kO3ZhciB4PXAuYTtpZigheCl0aHJvdyBFcnJvcigiTmV4dCBtdXN0IGJlIGNhbGxlZCBhdCBsZWFzdCBvbmNlIGJlZm9yZSByZW1vdmUuIik7dmFyIEM9eC5iLHg9eC5hO0M/Qy5hPXg6Zy5hPXg7eD94LmI9QzpnLmI9QztnLmktLTtwLmE9bnVsbH19cmV0dXJuIGJ9CnFiLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB1KHRoaXMuYSxmdW5jdGlvbihhLGIpe3JldHVybiBhK0QoYil9LCJQcmVkaWNhdGVzOiIpfTtmdW5jdGlvbiBWKGEsYixjLGQpe24uY2FsbCh0aGlzLDQpO3RoaXMuYz1hO3RoaXMuaz1iO3RoaXMuZj1jfHxuZXcgcWIoW10pO3RoaXMubT0hIWQ7Yj10aGlzLmY7Yj0wPGIuYS5sZW5ndGg/Yi5hWzBdLmQ6bnVsbDthLmImJmImJihhPWIubmFtZSxhPUU/YS50b0xvd2VyQ2FzZSgpOmEsdGhpcy5kPXtuYW1lOmEsbDpiLmx9KTthOnthPXRoaXMuZjtmb3IoYj0wO2I8YS5hLmxlbmd0aDtiKyspaWYoYz1hLmFbYl0sYy5lfHwxPT1jLmd8fDA9PWMuZyl7YT0hMDticmVhayBhfWE9ITF9dGhpcy5lPWF9bShWKTsKVi5wcm90b3R5cGUuYT1mdW5jdGlvbihhKXt2YXIgYj1hLmEsYz1udWxsLGM9dGhpcy5kLGQ9bnVsbCxlPW51bGwsZj0wO2MmJihkPWMubmFtZSxlPWMubD9PKGMubCxhKTpudWxsLGY9MSk7aWYodGhpcy5tKWlmKHRoaXMuZXx8dGhpcy5jIT1yYilpZihhPUwoKG5ldyBWKHNiLG5ldyBCKCJub2RlIikpKS5hKGEpKSxiPU0oYSkpZm9yKGM9dGhpcy5qKGIsZCxlLGYpO251bGwhPShiPU0oYSkpOyljPVVhKGMsdGhpcy5qKGIsZCxlLGYpKTtlbHNlIGM9bmV3IEo7ZWxzZSBjPUkodGhpcy5rLGIsZCxlKSxjPWViKHRoaXMuZixjLGYpO2Vsc2UgYz10aGlzLmooYS5hLGQsZSxmKTtyZXR1cm4gY307Vi5wcm90b3R5cGUuaj1mdW5jdGlvbihhLGIsYyxkKXthPXRoaXMuYy5kKHRoaXMuayxhLGIsYyk7cmV0dXJuIGE9ZWIodGhpcy5mLGEsZCl9OwpWLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3ZhciBhO2E9IlN0ZXA6IitEKCJPcGVyYXRvcjogIisodGhpcy5tPyIvLyI6Ii8iKSk7dGhpcy5jLmgmJihhKz1EKCJBeGlzOiAiK3RoaXMuYykpO2ErPUQodGhpcy5rKTtpZih0aGlzLmYuYS5sZW5ndGgpe3ZhciBiPXUodGhpcy5mLmEsZnVuY3Rpb24oYSxiKXtyZXR1cm4gYStEKGIpfSwiUHJlZGljYXRlczoiKTthKz1EKGIpfXJldHVybiBhfTtmdW5jdGlvbiB0YihhLGIsYyxkKXt0aGlzLmg9YTt0aGlzLmQ9Yjt0aGlzLmE9Yzt0aGlzLmI9ZH10Yi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ofTt2YXIgdWI9e307ZnVuY3Rpb24gVyhhLGIsYyxkKXtpZih1Yi5oYXNPd25Qcm9wZXJ0eShhKSl0aHJvdyBFcnJvcigiQXhpcyBhbHJlYWR5IGNyZWF0ZWQ6ICIrYSk7Yj1uZXcgdGIoYSxiLGMsISFkKTtyZXR1cm4gdWJbYV09Yn0KVygiYW5jZXN0b3IiLGZ1bmN0aW9uKGEsYil7Zm9yKHZhciBjPW5ldyBKLGQ9YjtkPWQucGFyZW50Tm9kZTspYS5hKGQpJiZWYShjLGQpO3JldHVybiBjfSwhMCk7VygiYW5jZXN0b3Itb3Itc2VsZiIsZnVuY3Rpb24oYSxiKXt2YXIgYz1uZXcgSixkPWI7ZG8gYS5hKGQpJiZWYShjLGQpO3doaWxlKGQ9ZC5wYXJlbnROb2RlKTtyZXR1cm4gY30sITApOwp2YXIgbGI9VygiYXR0cmlidXRlIixmdW5jdGlvbihhLGIpe3ZhciBjPW5ldyBKLGQ9YS5kKCk7aWYoInN0eWxlIj09ZCYmYi5zdHlsZSYmRSlyZXR1cm4gSyhjLG5ldyBGKGIuc3R5bGUsYiwic3R5bGUiLGIuc3R5bGUuY3NzVGV4dCkpLGM7dmFyIGU9Yi5hdHRyaWJ1dGVzO2lmKGUpaWYoYSBpbnN0YW5jZW9mIEImJm51bGw9PT1hLmJ8fCIqIj09ZClmb3IodmFyIGQ9MCxmO2Y9ZVtkXTtkKyspRT9mLm5vZGVWYWx1ZSYmSyhjLE1hKGIsZikpOksoYyxmKTtlbHNlKGY9ZS5nZXROYW1lZEl0ZW0oZCkpJiYoRT9mLm5vZGVWYWx1ZSYmSyhjLE1hKGIsZikpOksoYyxmKSk7cmV0dXJuIGN9LCExKSxyYj1XKCJjaGlsZCIsZnVuY3Rpb24oYSxiLGMsZCxlKXtyZXR1cm4oRT9SYTpTYSkuY2FsbChudWxsLGEsYixrKGMpP2M6bnVsbCxrKGQpP2Q6bnVsbCxlfHxuZXcgSil9LCExLCEwKTtXKCJkZXNjZW5kYW50IixJLCExLCEwKTsKdmFyIHNiPVcoImRlc2NlbmRhbnQtb3Itc2VsZiIsZnVuY3Rpb24oYSxiLGMsZCl7dmFyIGU9bmV3IEo7SChiLGMsZCkmJmEuYShiKSYmSyhlLGIpO3JldHVybiBJKGEsYixjLGQsZSl9LCExLCEwKSxvYj1XKCJmb2xsb3dpbmciLGZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlPW5ldyBKO2RvIGZvcih2YXIgZj1iO2Y9Zi5uZXh0U2libGluZzspSChmLGMsZCkmJmEuYShmKSYmSyhlLGYpLGU9SShhLGYsYyxkLGUpO3doaWxlKGI9Yi5wYXJlbnROb2RlKTtyZXR1cm4gZX0sITEsITApO1coImZvbGxvd2luZy1zaWJsaW5nIixmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz1uZXcgSixkPWI7ZD1kLm5leHRTaWJsaW5nOylhLmEoZCkmJksoYyxkKTtyZXR1cm4gY30sITEpO1coIm5hbWVzcGFjZSIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEp9LCExKTsKdmFyIHZiPVcoInBhcmVudCIsZnVuY3Rpb24oYSxiKXt2YXIgYz1uZXcgSjtpZig5PT1iLm5vZGVUeXBlKXJldHVybiBjO2lmKDI9PWIubm9kZVR5cGUpcmV0dXJuIEsoYyxiLm93bmVyRWxlbWVudCksYzt2YXIgZD1iLnBhcmVudE5vZGU7YS5hKGQpJiZLKGMsZCk7cmV0dXJuIGN9LCExKSxwYj1XKCJwcmVjZWRpbmciLGZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlPW5ldyBKLGY9W107ZG8gZi51bnNoaWZ0KGIpO3doaWxlKGI9Yi5wYXJlbnROb2RlKTtmb3IodmFyIGc9MSxsPWYubGVuZ3RoO2c8bDtnKyspe3ZhciBwPVtdO2ZvcihiPWZbZ107Yj1iLnByZXZpb3VzU2libGluZzspcC51bnNoaWZ0KGIpO2Zvcih2YXIgeD0wLEM9cC5sZW5ndGg7eDxDO3grKyliPXBbeF0sSChiLGMsZCkmJmEuYShiKSYmSyhlLGIpLGU9SShhLGIsYyxkLGUpfXJldHVybiBlfSwhMCwhMCk7ClcoInByZWNlZGluZy1zaWJsaW5nIixmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz1uZXcgSixkPWI7ZD1kLnByZXZpb3VzU2libGluZzspYS5hKGQpJiZWYShjLGQpO3JldHVybiBjfSwhMCk7dmFyIHdiPVcoInNlbGYiLGZ1bmN0aW9uKGEsYil7dmFyIGM9bmV3IEo7YS5hKGIpJiZLKGMsYik7cmV0dXJuIGN9LCExKTtmdW5jdGlvbiB4YihhKXtuLmNhbGwodGhpcywxKTt0aGlzLmM9YTt0aGlzLmU9YS5lO3RoaXMuYj1hLmJ9bSh4Yik7eGIucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7cmV0dXJuLU4odGhpcy5jLGEpfTt4Yi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4iVW5hcnkgRXhwcmVzc2lvbjogLSIrRCh0aGlzLmMpfTtmdW5jdGlvbiB5YihhKXtuLmNhbGwodGhpcyw0KTt0aGlzLmM9YTtaYSh0aGlzLGxhKHRoaXMuYyxmdW5jdGlvbihhKXtyZXR1cm4gYS5lfSkpOyRhKHRoaXMsbGEodGhpcy5jLGZ1bmN0aW9uKGEpe3JldHVybiBhLmJ9KSl9bSh5Yik7eWIucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IEo7dCh0aGlzLmMsZnVuY3Rpb24oYyl7Yz1jLmEoYSk7aWYoIShjIGluc3RhbmNlb2YgSikpdGhyb3cgRXJyb3IoIlBhdGggZXhwcmVzc2lvbiBtdXN0IGV2YWx1YXRlIHRvIE5vZGVTZXQuIik7Yj1VYShiLGMpfSk7cmV0dXJuIGJ9O3liLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB1KHRoaXMuYyxmdW5jdGlvbihhLGIpe3JldHVybiBhK0QoYil9LCJVbmlvbiBFeHByZXNzaW9uOiIpfTtmdW5jdGlvbiB6YihhLGIpe3RoaXMuYT1hO3RoaXMuYj1ifWZ1bmN0aW9uIEFiKGEpe2Zvcih2YXIgYixjPVtdOzspe1koYSwiTWlzc2luZyByaWdodCBoYW5kIHNpZGUgb2YgYmluYXJ5IGV4cHJlc3Npb24uIik7Yj1CYihhKTt2YXIgZD16KGEuYSk7aWYoIWQpYnJlYWs7dmFyIGU9KGQ9Y2JbZF18fG51bGwpJiZkLnA7aWYoIWUpe2EuYS5hLS07YnJlYWt9Zm9yKDtjLmxlbmd0aCYmZTw9Y1tjLmxlbmd0aC0xXS5wOyliPW5ldyBRKGMucG9wKCksYy5wb3AoKSxiKTtjLnB1c2goYixkKX1mb3IoO2MubGVuZ3RoOyliPW5ldyBRKGMucG9wKCksYy5wb3AoKSxiKTtyZXR1cm4gYn1mdW5jdGlvbiBZKGEsYil7aWYoR2EoYS5hKSl0aHJvdyBFcnJvcihiKTt9ZnVuY3Rpb24gQ2IoYSxiKXt2YXIgYz16KGEuYSk7aWYoYyE9Yil0aHJvdyBFcnJvcigiQmFkIHRva2VuLCBleHBlY3RlZDogIitiKyIgZ290OiAiK2MpO30KZnVuY3Rpb24gRGIoYSl7YT16KGEuYSk7aWYoIikiIT1hKXRocm93IEVycm9yKCJCYWQgdG9rZW46ICIrYSk7fWZ1bmN0aW9uIEViKGEpe2E9eihhLmEpO2lmKDI+YS5sZW5ndGgpdGhyb3cgRXJyb3IoIlVuY2xvc2VkIGxpdGVyYWwgc3RyaW5nIik7cmV0dXJuIG5ldyBpYihhKX1mdW5jdGlvbiBGYihhKXt2YXIgYj16KGEuYSksYz1iLmluZGV4T2YoIjoiKTtpZigtMT09YylyZXR1cm4gbmV3IEEoYik7dmFyIGQ9Yi5zdWJzdHJpbmcoMCxjKTthPWEuYihkKTtpZighYSl0aHJvdyBFcnJvcigiTmFtZXNwYWNlIHByZWZpeCBub3QgZGVjbGFyZWQ6ICIrZCk7Yj1iLnN1YnN0cihjKzEpO3JldHVybiBuZXcgQShiLGEpfQpmdW5jdGlvbiBHYihhKXt2YXIgYixjPVtdLGQ7aWYobmIoeShhLmEpKSl7Yj16KGEuYSk7ZD15KGEuYSk7aWYoIi8iPT1iJiYoR2EoYS5hKXx8Ii4iIT1kJiYiLi4iIT1kJiYiQCIhPWQmJiIqIiE9ZCYmIS8oPyFbMC05XSlbXHddLy50ZXN0KGQpKSlyZXR1cm4gbmV3IFU7ZD1uZXcgVTtZKGEsIk1pc3NpbmcgbmV4dCBsb2NhdGlvbiBzdGVwLiIpO2I9SGIoYSxiKTtjLnB1c2goYil9ZWxzZXthOntiPXkoYS5hKTtkPWIuY2hhckF0KDApO3N3aXRjaChkKXtjYXNlICIkIjp0aHJvdyBFcnJvcigiVmFyaWFibGUgcmVmZXJlbmNlIG5vdCBhbGxvd2VkIGluIEhUTUwgWFBhdGgiKTtjYXNlICIoIjp6KGEuYSk7Yj1BYihhKTtZKGEsJ3VuY2xvc2VkICIoIicpO0NiKGEsIikiKTticmVhaztjYXNlICciJzpjYXNlICInIjpiPUViKGEpO2JyZWFrO2RlZmF1bHQ6aWYoaXNOYU4oK2IpKWlmKCFIYShiKSYmLyg/IVswLTldKVtcd10vLnRlc3QoZCkmJiIoIj09eShhLmEsMSkpe2I9eihhLmEpO2I9CmhiW2JdfHxudWxsO3ooYS5hKTtmb3IoZD1bXTsiKSIhPXkoYS5hKTspe1koYSwiTWlzc2luZyBmdW5jdGlvbiBhcmd1bWVudCBsaXN0LiIpO2QucHVzaChBYihhKSk7aWYoIiwiIT15KGEuYSkpYnJlYWs7eihhLmEpfVkoYSwiVW5jbG9zZWQgZnVuY3Rpb24gYXJndW1lbnQgbGlzdC4iKTtEYihhKTtiPW5ldyBmYihiLGQpfWVsc2V7Yj1udWxsO2JyZWFrIGF9ZWxzZSBiPW5ldyBqYigreihhLmEpKX0iWyI9PXkoYS5hKSYmKGQ9bmV3IHFiKEliKGEpKSxiPW5ldyBkYihiLGQpKX1pZihiKWlmKG5iKHkoYS5hKSkpZD1iO2Vsc2UgcmV0dXJuIGI7ZWxzZSBiPUhiKGEsIi8iKSxkPW5ldyBtYixjLnB1c2goYil9Zm9yKDtuYih5KGEuYSkpOyliPXooYS5hKSxZKGEsIk1pc3NpbmcgbmV4dCBsb2NhdGlvbiBzdGVwLiIpLGI9SGIoYSxiKSxjLnB1c2goYik7cmV0dXJuIG5ldyBrYihkLGMpfQpmdW5jdGlvbiBIYihhLGIpe3ZhciBjLGQsZTtpZigiLyIhPWImJiIvLyIhPWIpdGhyb3cgRXJyb3IoJ1N0ZXAgb3Agc2hvdWxkIGJlICIvIiBvciAiLy8iJyk7aWYoIi4iPT15KGEuYSkpcmV0dXJuIGQ9bmV3IFYod2IsbmV3IEIoIm5vZGUiKSkseihhLmEpLGQ7aWYoIi4uIj09eShhLmEpKXJldHVybiBkPW5ldyBWKHZiLG5ldyBCKCJub2RlIikpLHooYS5hKSxkO3ZhciBmO2lmKCJAIj09eShhLmEpKWY9bGIseihhLmEpLFkoYSwiTWlzc2luZyBhdHRyaWJ1dGUgbmFtZSIpO2Vsc2UgaWYoIjo6Ij09eShhLmEsMSkpe2lmKCEvKD8hWzAtOV0pW1x3XS8udGVzdCh5KGEuYSkuY2hhckF0KDApKSl0aHJvdyBFcnJvcigiQmFkIHRva2VuOiAiK3ooYS5hKSk7Yz16KGEuYSk7Zj11YltjXXx8bnVsbDtpZighZil0aHJvdyBFcnJvcigiTm8gYXhpcyB3aXRoIG5hbWU6ICIrYyk7eihhLmEpO1koYSwiTWlzc2luZyBub2RlIG5hbWUiKX1lbHNlIGY9cmI7Yz15KGEuYSk7aWYoLyg/IVswLTldKVtcd10vLnRlc3QoYy5jaGFyQXQoMCkpKWlmKCIoIj09CnkoYS5hLDEpKXtpZighSGEoYykpdGhyb3cgRXJyb3IoIkludmFsaWQgbm9kZSB0eXBlOiAiK2MpO2M9eihhLmEpO2lmKCFIYShjKSl0aHJvdyBFcnJvcigiSW52YWxpZCB0eXBlIG5hbWU6ICIrYyk7Q2IoYSwiKCIpO1koYSwiQmFkIG5vZGV0eXBlIik7ZT15KGEuYSkuY2hhckF0KDApO3ZhciBnPW51bGw7aWYoJyInPT1lfHwiJyI9PWUpZz1FYihhKTtZKGEsIkJhZCBub2RldHlwZSIpO0RiKGEpO2M9bmV3IEIoYyxnKX1lbHNlIGM9RmIoYSk7ZWxzZSBpZigiKiI9PWMpYz1GYihhKTtlbHNlIHRocm93IEVycm9yKCJCYWQgdG9rZW46ICIreihhLmEpKTtlPW5ldyBxYihJYihhKSxmLmEpO3JldHVybiBkfHxuZXcgVihmLGMsZSwiLy8iPT1iKX0KZnVuY3Rpb24gSWIoYSl7Zm9yKHZhciBiPVtdOyJbIj09eShhLmEpOyl7eihhLmEpO1koYSwiTWlzc2luZyBwcmVkaWNhdGUgZXhwcmVzc2lvbi4iKTt2YXIgYz1BYihhKTtiLnB1c2goYyk7WShhLCJVbmNsb3NlZCBwcmVkaWNhdGUgZXhwcmVzc2lvbi4iKTtDYihhLCJdIil9cmV0dXJuIGJ9ZnVuY3Rpb24gQmIoYSl7aWYoIi0iPT15KGEuYSkpcmV0dXJuIHooYS5hKSxuZXcgeGIoQmIoYSkpO3ZhciBiPUdiKGEpO2lmKCJ8IiE9eShhLmEpKWE9YjtlbHNle2ZvcihiPVtiXTsifCI9PXooYS5hKTspWShhLCJNaXNzaW5nIG5leHQgdW5pb24gbG9jYXRpb24gcGF0aC4iKSxiLnB1c2goR2IoYSkpO2EuYS5hLS07YT1uZXcgeWIoYil9cmV0dXJuIGF9O2Z1bmN0aW9uIEpiKGEsYil7aWYoIWEubGVuZ3RoKXRocm93IEVycm9yKCJFbXB0eSBYUGF0aCBleHByZXNzaW9uLiIpO3ZhciBjPURhKGEpO2lmKEdhKGMpKXRocm93IEVycm9yKCJJbnZhbGlkIFhQYXRoIGV4cHJlc3Npb24uIik7Yj8iZnVuY3Rpb24iPT1hYShiKXx8KGI9ZGEoYi5sb29rdXBOYW1lc3BhY2VVUkksYikpOmI9ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH07dmFyIGQ9QWIobmV3IHpiKGMsYikpO2lmKCFHYShjKSl0aHJvdyBFcnJvcigiQmFkIHRva2VuOiAiK3ooYykpO3RoaXMuZXZhbHVhdGU9ZnVuY3Rpb24oYSxiKXt2YXIgYz1kLmEobmV3IHcoYSkpO3JldHVybiBuZXcgWihjLGIpfX0KZnVuY3Rpb24gWihhLGIpe2lmKDA9PWIpaWYoYSBpbnN0YW5jZW9mIEopYj00O2Vsc2UgaWYoInN0cmluZyI9PXR5cGVvZiBhKWI9MjtlbHNlIGlmKCJudW1iZXIiPT10eXBlb2YgYSliPTE7ZWxzZSBpZigiYm9vbGVhbiI9PXR5cGVvZiBhKWI9MztlbHNlIHRocm93IEVycm9yKCJVbmV4cGVjdGVkIGV2YWx1YXRpb24gcmVzdWx0LiIpO2lmKDIhPWImJjEhPWImJjMhPWImJiEoYSBpbnN0YW5jZW9mIEopKXRocm93IEVycm9yKCJ2YWx1ZSBjb3VsZCBub3QgYmUgY29udmVydGVkIHRvIHRoZSBzcGVjaWZpZWQgdHlwZSIpO3RoaXMucmVzdWx0VHlwZT1iO3ZhciBjO3N3aXRjaChiKXtjYXNlIDI6dGhpcy5zdHJpbmdWYWx1ZT1hIGluc3RhbmNlb2YgSj9YYShhKToiIithO2JyZWFrO2Nhc2UgMTp0aGlzLm51bWJlclZhbHVlPWEgaW5zdGFuY2VvZiBKPytYYShhKTorYTticmVhaztjYXNlIDM6dGhpcy5ib29sZWFuVmFsdWU9YSBpbnN0YW5jZW9mIEo/MDxhLmk6ISFhO2JyZWFrO2Nhc2UgNDpjYXNlIDU6Y2FzZSA2OmNhc2UgNzp2YXIgZD0KTChhKTtjPVtdO2Zvcih2YXIgZT1NKGQpO2U7ZT1NKGQpKWMucHVzaChlIGluc3RhbmNlb2YgRj9lLmE6ZSk7dGhpcy5zbmFwc2hvdExlbmd0aD1hLmk7dGhpcy5pbnZhbGlkSXRlcmF0b3JTdGF0ZT0hMTticmVhaztjYXNlIDg6Y2FzZSA5OmQ9V2EoYSk7dGhpcy5zaW5nbGVOb2RlVmFsdWU9ZCBpbnN0YW5jZW9mIEY/ZC5hOmQ7YnJlYWs7ZGVmYXVsdDp0aHJvdyBFcnJvcigiVW5rbm93biBYUGF0aFJlc3VsdCB0eXBlLiIpO312YXIgZj0wO3RoaXMuaXRlcmF0ZU5leHQ9ZnVuY3Rpb24oKXtpZig0IT1iJiY1IT1iKXRocm93IEVycm9yKCJpdGVyYXRlTmV4dCBjYWxsZWQgd2l0aCB3cm9uZyByZXN1bHQgdHlwZSIpO3JldHVybiBmPj1jLmxlbmd0aD9udWxsOmNbZisrXX07dGhpcy5zbmFwc2hvdEl0ZW09ZnVuY3Rpb24oYSl7aWYoNiE9YiYmNyE9Yil0aHJvdyBFcnJvcigic25hcHNob3RJdGVtIGNhbGxlZCB3aXRoIHdyb25nIHJlc3VsdCB0eXBlIik7cmV0dXJuIGE+PWMubGVuZ3RofHwKMD5hP251bGw6Y1thXX19Wi5BTllfVFlQRT0wO1ouTlVNQkVSX1RZUEU9MTtaLlNUUklOR19UWVBFPTI7Wi5CT09MRUFOX1RZUEU9MztaLlVOT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEU9NDtaLk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFPTU7Wi5VTk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFPTY7Wi5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRT03O1ouQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEU9ODtaLkZJUlNUX09SREVSRURfTk9ERV9UWVBFPTk7ZnVuY3Rpb24gS2IoYSl7dGhpcy5sb29rdXBOYW1lc3BhY2VVUkk9SWEoYSl9CmZ1bmN0aW9uIExiKGEpe2E9YXx8aDt2YXIgYj1hLmRvY3VtZW50O2IuZXZhbHVhdGV8fChhLlhQYXRoUmVzdWx0PVosYi5ldmFsdWF0ZT1mdW5jdGlvbihhLGIsZSxmKXtyZXR1cm4obmV3IEpiKGEsZSkpLmV2YWx1YXRlKGIsZil9LGIuY3JlYXRlRXhwcmVzc2lvbj1mdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSmIoYSxiKX0sYi5jcmVhdGVOU1Jlc29sdmVyPWZ1bmN0aW9uKGEpe3JldHVybiBuZXcgS2IoYSl9KX12YXIgTWI9WyJ3Z3hwYXRoIiwiaW5zdGFsbCJdLCQ9aDtNYlswXWluICR8fCEkLmV4ZWNTY3JpcHR8fCQuZXhlY1NjcmlwdCgidmFyICIrTWJbMF0pO2Zvcih2YXIgTmI7TWIubGVuZ3RoJiYoTmI9TWIuc2hpZnQoKSk7KU1iLmxlbmd0aHx8dm9pZCAwPT09TGI/JFtOYl0/JD0kW05iXTokPSRbTmJdPXt9OiRbTmJdPUxiO30pKCkKCi8qKgogKiBAbGljZW5zZSB3eXNpaHRtbDUgdjAuNC4wcHJlCiAqIGh0dHBzOi8vZ2l0aHViLmNvbS94aW5nL3d5c2lodG1sNQogKgogKiBBdXRob3I6IENocmlzdG9waGVyIEJsdW0gKGh0dHBzOi8vZ2l0aHViLmNvbS90aWZmKQogKgogKiBDb3B5cmlnaHQgKEMpIDIwMTIgWElORyBBRwogKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgKE1JVCkKICoKICovCnZhciB3eXNpaHRtbDUgPSB7CiAgICB2ZXJzaW9uIDogIjAuNC4wcHJlIiwKCiAgICAvLyBuYW1lc3BhY2VzCiAgICBjb21tYW5kcyA6IHt9LAogICAgZG9tIDoge30sCiAgICBxdWlya3MgOiB7fSwKICAgIHRvb2xiYXIgOiB7fSwKICAgIGxhbmcgOiB7fSwKICAgIHNlbGVjdGlvbiA6IHt9LAogICAgdmlld3MgOiB7fSwKCiAgICBJTlZJU0lCTEVfU1BBQ0UgOiAiXHVGRUZGIiwKCiAgICBFTVBUWV9GVU5DVElPTiA6IGZ1bmN0aW9uICgpIHsKICAgIH0sCgogICAgRUxFTUVOVF9OT0RFIDogMSwKICAgIFRFWFRfTk9ERSA6IDMsCgogICAgQkFDS1NQQUNFX0tFWSA6IDgsCiAgICBFTlRFUl9LRVkgOiAxMywKICAgIEVTQ0FQRV9LRVkgOiAyNywKICAgIFNQQUNFX0tFWSA6IDMyLAogICAgREVMRVRFX0tFWSA6IDQ2LAogICAgVEFCX0tFWSA6IDksCiAgICBCTE9DS19FTEVNRU5UU19HUk9VUCA6IFsiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiLCAiUCJdCn07Ci8qKgogKiBAbGljZW5zZSBSYW5neSwgYSBjcm9zcy1icm93c2VyIEphdmFTY3JpcHQgcmFuZ2UgYW5kIHNlbGVjdGlvbiBsaWJyYXJ5CiAqIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9yYW5neS8KICoKICogQ29weXJpZ2h0IDIwMTEsIFRpbSBEb3duCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS4KICogVmVyc2lvbjogMS4yLjIKICogQnVpbGQgZGF0ZTogMTMgTm92ZW1iZXIgMjAxMQogKi8Kd2luZG93LnJhbmd5ID0gKGZ1bmN0aW9uICgpIHsKCiAgICB2YXIgT0JKRUNUID0gIm9iamVjdCIsIEZVTkNUSU9OID0gImZ1bmN0aW9uIiwgVU5ERUZJTkVEID0gInVuZGVmaW5lZCI7CgogICAgdmFyIGRvbVJhbmdlUHJvcGVydGllcyA9IFsic3RhcnRDb250YWluZXIiLCAic3RhcnRPZmZzZXQiLCAiZW5kQ29udGFpbmVyIiwgImVuZE9mZnNldCIsICJjb2xsYXBzZWQiLAogICAgICAgICJjb21tb25BbmNlc3RvckNvbnRhaW5lciIsICJTVEFSVF9UT19TVEFSVCIsICJTVEFSVF9UT19FTkQiLCAiRU5EX1RPX1NUQVJUIiwgIkVORF9UT19FTkQiXTsKCiAgICB2YXIgZG9tUmFuZ2VNZXRob2RzID0gWyJzZXRTdGFydCIsICJzZXRTdGFydEJlZm9yZSIsICJzZXRTdGFydEFmdGVyIiwgInNldEVuZCIsICJzZXRFbmRCZWZvcmUiLAogICAgICAgICJzZXRFbmRBZnRlciIsICJjb2xsYXBzZSIsICJzZWxlY3ROb2RlIiwgInNlbGVjdE5vZGVDb250ZW50cyIsICJjb21wYXJlQm91bmRhcnlQb2ludHMiLCAiZGVsZXRlQ29udGVudHMiLAogICAgICAgICJleHRyYWN0Q29udGVudHMiLCAiY2xvbmVDb250ZW50cyIsICJpbnNlcnROb2RlIiwgInN1cnJvdW5kQ29udGVudHMiLCAiY2xvbmVSYW5nZSIsICJ0b1N0cmluZyIsICJkZXRhY2giXTsKCiAgICB2YXIgdGV4dFJhbmdlUHJvcGVydGllcyA9IFsiYm91bmRpbmdIZWlnaHQiLCAiYm91bmRpbmdMZWZ0IiwgImJvdW5kaW5nVG9wIiwgImJvdW5kaW5nV2lkdGgiLCAiaHRtbFRleHQiLCAidGV4dCJdOwoKICAgIC8vIFN1YnNldCBvZiBUZXh0UmFuZ2UncyBmdWxsIHNldCBvZiBtZXRob2RzIHRoYXQgd2UncmUgaW50ZXJlc3RlZCBpbgogICAgdmFyIHRleHRSYW5nZU1ldGhvZHMgPSBbImNvbGxhcHNlIiwgImNvbXBhcmVFbmRQb2ludHMiLCAiZHVwbGljYXRlIiwgImdldEJvb2ttYXJrIiwgIm1vdmVUb0Jvb2ttYXJrIiwKICAgICAgICAibW92ZVRvRWxlbWVudFRleHQiLCAicGFyZW50RWxlbWVudCIsICJwYXN0ZUhUTUwiLCAic2VsZWN0IiwgInNldEVuZFBvaW50IiwgImdldEJvdW5kaW5nQ2xpZW50UmVjdCJdOwoKICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgogICAgLy8gVHJpbyBvZiBmdW5jdGlvbnMgdGFrZW4gZnJvbSBQZXRlciBNaWNoYXV4J3MgYXJ0aWNsZToKICAgIC8vIGh0dHA6Ly9wZXRlci5taWNoYXV4LmNhL2FydGljbGVzL2ZlYXR1cmUtZGV0ZWN0aW9uLXN0YXRlLW9mLXRoZS1hcnQtYnJvd3Nlci1zY3JpcHRpbmcKICAgIGZ1bmN0aW9uIGlzSG9zdE1ldGhvZChvLCBwKSB7CiAgICAgICAgdmFyIHQgPSB0eXBlb2Ygb1twXTsKICAgICAgICByZXR1cm4gdCA9PSBGVU5DVElPTiB8fCAoISEodCA9PSBPQkpFQ1QgJiYgb1twXSkpIHx8IHQgPT0gInVua25vd24iOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzSG9zdE9iamVjdChvLCBwKSB7CiAgICAgICAgcmV0dXJuICEhKHR5cGVvZiBvW3BdID09IE9CSkVDVCAmJiBvW3BdKTsKICAgIH0KCiAgICBmdW5jdGlvbiBpc0hvc3RQcm9wZXJ0eShvLCBwKSB7CiAgICAgICAgcmV0dXJuIHR5cGVvZiBvW3BdICE9IFVOREVGSU5FRDsKICAgIH0KCiAgICAvLyBDcmVhdGVzIGEgY29udmVuaWVuY2UgZnVuY3Rpb24gdG8gc2F2ZSB2ZXJib3NlIHJlcGVhdGVkIGNhbGxzIHRvIHRlc3RzIGZ1bmN0aW9ucwogICAgZnVuY3Rpb24gY3JlYXRlTXVsdGlwbGVQcm9wZXJ0eVRlc3QodGVzdEZ1bmMpIHsKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG8sIHByb3BzKSB7CiAgICAgICAgICAgIHZhciBpID0gcHJvcHMubGVuZ3RoOwogICAgICAgICAgICB3aGlsZSAoaS0tKSB7CiAgICAgICAgICAgICAgICBpZiAoIXRlc3RGdW5jKG8sIHByb3BzW2ldKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9OwogICAgfQoKICAgIC8vIE5leHQgdHJpbyBvZiBmdW5jdGlvbnMgYXJlIGEgY29udmVuaWVuY2UgdG8gc2F2ZSB2ZXJib3NlIHJlcGVhdGVkIGNhbGxzIHRvIHByZXZpb3VzIHR3byBmdW5jdGlvbnMKICAgIHZhciBhcmVIb3N0TWV0aG9kcyA9IGNyZWF0ZU11bHRpcGxlUHJvcGVydHlUZXN0KGlzSG9zdE1ldGhvZCk7CiAgICB2YXIgYXJlSG9zdE9iamVjdHMgPSBjcmVhdGVNdWx0aXBsZVByb3BlcnR5VGVzdChpc0hvc3RPYmplY3QpOwogICAgdmFyIGFyZUhvc3RQcm9wZXJ0aWVzID0gY3JlYXRlTXVsdGlwbGVQcm9wZXJ0eVRlc3QoaXNIb3N0UHJvcGVydHkpOwoKICAgIGZ1bmN0aW9uIGlzVGV4dFJhbmdlKHJhbmdlKSB7CiAgICAgICAgcmV0dXJuIHJhbmdlICYmIGFyZUhvc3RNZXRob2RzKHJhbmdlLCB0ZXh0UmFuZ2VNZXRob2RzKSAmJiBhcmVIb3N0UHJvcGVydGllcyhyYW5nZSwgdGV4dFJhbmdlUHJvcGVydGllcyk7CiAgICB9CgogICAgdmFyIGFwaSA9IHsKICAgICAgICB2ZXJzaW9uIDogIjEuMi4yIiwKICAgICAgICBpbml0aWFsaXplZCA6IGZhbHNlLAogICAgICAgIHN1cHBvcnRlZCA6IHRydWUsCgogICAgICAgIHV0aWwgOiB7CiAgICAgICAgICAgIGlzSG9zdE1ldGhvZCA6IGlzSG9zdE1ldGhvZCwKICAgICAgICAgICAgaXNIb3N0T2JqZWN0IDogaXNIb3N0T2JqZWN0LAogICAgICAgICAgICBpc0hvc3RQcm9wZXJ0eSA6IGlzSG9zdFByb3BlcnR5LAogICAgICAgICAgICBhcmVIb3N0TWV0aG9kcyA6IGFyZUhvc3RNZXRob2RzLAogICAgICAgICAgICBhcmVIb3N0T2JqZWN0cyA6IGFyZUhvc3RPYmplY3RzLAogICAgICAgICAgICBhcmVIb3N0UHJvcGVydGllcyA6IGFyZUhvc3RQcm9wZXJ0aWVzLAogICAgICAgICAgICBpc1RleHRSYW5nZSA6IGlzVGV4dFJhbmdlCiAgICAgICAgfSwKCiAgICAgICAgZmVhdHVyZXMgOiB7fSwKCiAgICAgICAgbW9kdWxlcyA6IHt9LAogICAgICAgIGNvbmZpZyA6IHsKICAgICAgICAgICAgYWxlcnRPbldhcm4gOiBmYWxzZSwKICAgICAgICAgICAgcHJlZmVyVGV4dFJhbmdlIDogZmFsc2UKICAgICAgICB9CiAgICB9OwoKICAgIGZ1bmN0aW9uIGZhaWwocmVhc29uKSB7CiAgICAgICAgd2luZG93LmFsZXJ0KCJSYW5neSBub3Qgc3VwcG9ydGVkIGluIHlvdXIgYnJvd3Nlci4gUmVhc29uOiAiICsgcmVhc29uKTsKICAgICAgICBhcGkuaW5pdGlhbGl6ZWQgPSB0cnVlOwogICAgICAgIGFwaS5zdXBwb3J0ZWQgPSBmYWxzZTsKICAgIH0KCiAgICBhcGkuZmFpbCA9IGZhaWw7CgogICAgZnVuY3Rpb24gd2Fybihtc2cpIHsKICAgICAgICB2YXIgd2FybmluZ01lc3NhZ2UgPSAiUmFuZ3kgd2FybmluZzogIiArIG1zZzsKICAgICAgICBpZiAoYXBpLmNvbmZpZy5hbGVydE9uV2FybikgewogICAgICAgICAgICB3aW5kb3cuYWxlcnQod2FybmluZ01lc3NhZ2UpOwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdy5jb25zb2xlICE9IFVOREVGSU5FRCAmJiB0eXBlb2Ygd2luZG93LmNvbnNvbGUubG9nICE9IFVOREVGSU5FRCkgewogICAgICAgICAgICB3aW5kb3cuY29uc29sZS5sb2cod2FybmluZ01lc3NhZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICBhcGkud2FybiA9IHdhcm47CgogICAgaWYgKHt9Lmhhc093blByb3BlcnR5KSB7CiAgICAgICAgYXBpLnV0aWwuZXh0ZW5kID0gZnVuY3Rpb24gKG8sIHByb3BzKSB7CiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gcHJvcHMpIHsKICAgICAgICAgICAgICAgIGlmIChwcm9wcy5oYXNPd25Qcm9wZXJ0eShpKSkgewogICAgICAgICAgICAgICAgICAgIG9baV0gPSBwcm9wc1tpXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIGZhaWwoImhhc093blByb3BlcnR5IG5vdCBzdXBwb3J0ZWQiKTsKICAgIH0KCiAgICB2YXIgaW5pdExpc3RlbmVycyA9IFtdOwogICAgdmFyIG1vZHVsZUluaXRpYWxpemVycyA9IFtdOwoKICAgIC8vIEluaXRpYWxpemF0aW9uCiAgICBmdW5jdGlvbiBpbml0KCkgewogICAgICAgIGlmIChhcGkuaW5pdGlhbGl6ZWQpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICB2YXIgdGVzdFJhbmdlOwogICAgICAgIHZhciBpbXBsZW1lbnRzRG9tUmFuZ2UgPSBmYWxzZSwgaW1wbGVtZW50c1RleHRSYW5nZSA9IGZhbHNlOwoKICAgICAgICAvLyBGaXJzdCwgcGVyZm9ybSBiYXNpYyBmZWF0dXJlIHRlc3RzCgogICAgICAgIGlmIChpc0hvc3RNZXRob2QoZG9jdW1lbnQsICJjcmVhdGVSYW5nZSIpKSB7CiAgICAgICAgICAgIHRlc3RSYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgICAgIGlmIChhcmVIb3N0TWV0aG9kcyh0ZXN0UmFuZ2UsIGRvbVJhbmdlTWV0aG9kcykgJiYgYXJlSG9zdFByb3BlcnRpZXModGVzdFJhbmdlLCBkb21SYW5nZVByb3BlcnRpZXMpKSB7CiAgICAgICAgICAgICAgICBpbXBsZW1lbnRzRG9tUmFuZ2UgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRlc3RSYW5nZS5kZXRhY2goKTsKICAgICAgICB9CgogICAgICAgIHZhciBib2R5ID0gaXNIb3N0T2JqZWN0KGRvY3VtZW50LCAiYm9keSIpID8gZG9jdW1lbnQuYm9keSA6IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJib2R5IilbMF07CgogICAgICAgIC8qIEluIGNhc2UgY3JlYXRlUmFuZ2UgaXMgc3VwcG9ydGVkIHNraXBwaW5nIHZhbGlkYXRpb24gZm9yIGNyZWF0ZVRleHRSYW5nZSBBUEkKICAgICAgICAgKiBhcyBpdHMgbm90IHVzZWQgaW4gc3VjaCBzY2VuYXJpbyBhcyB3ZWxsIGFzIHJlZHVjZXMgcGVyZm9ybWFuY2UoQ1EtNDIyODE2NikgICovCiAgICAgICAgaWYgKCFpbXBsZW1lbnRzRG9tUmFuZ2UgJiYgYm9keSAmJiBpc0hvc3RNZXRob2QoYm9keSwgImNyZWF0ZVRleHRSYW5nZSIpKSB7CiAgICAgICAgICAgIHRlc3RSYW5nZSA9IGJvZHkuY3JlYXRlVGV4dFJhbmdlKCk7CiAgICAgICAgICAgIGlmIChpc1RleHRSYW5nZSh0ZXN0UmFuZ2UpKSB7CiAgICAgICAgICAgICAgICBpbXBsZW1lbnRzVGV4dFJhbmdlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFpbXBsZW1lbnRzRG9tUmFuZ2UgJiYgIWltcGxlbWVudHNUZXh0UmFuZ2UpIHsKICAgICAgICAgICAgZmFpbCgiTmVpdGhlciBSYW5nZSBub3IgVGV4dFJhbmdlIGFyZSBpbXBsZW1lbnRlZCIpOwogICAgICAgIH0KCiAgICAgICAgYXBpLmluaXRpYWxpemVkID0gdHJ1ZTsKICAgICAgICBhcGkuZmVhdHVyZXMgPSB7CiAgICAgICAgICAgIGltcGxlbWVudHNEb21SYW5nZSA6IGltcGxlbWVudHNEb21SYW5nZSwKICAgICAgICAgICAgaW1wbGVtZW50c1RleHRSYW5nZSA6IGltcGxlbWVudHNUZXh0UmFuZ2UKICAgICAgICB9OwoKICAgICAgICAvLyBJbml0aWFsaXplIG1vZHVsZXMgYW5kIGNhbGwgaW5pdCBsaXN0ZW5lcnMKICAgICAgICB2YXIgYWxsTGlzdGVuZXJzID0gbW9kdWxlSW5pdGlhbGl6ZXJzLmNvbmNhdChpbml0TGlzdGVuZXJzKTsKICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gYWxsTGlzdGVuZXJzLmxlbmd0aDsKICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGFsbExpc3RlbmVyc1tpXShhcGkpOwogICAgICAgICAgICB9IGNhdGNoIChleCkgewogICAgICAgICAgICAgICAgaWYgKGlzSG9zdE9iamVjdCh3aW5kb3csICJjb25zb2xlIikgJiYgaXNIb3N0TWV0aG9kKHdpbmRvdy5jb25zb2xlLCAibG9nIikpIHsKICAgICAgICAgICAgICAgICAgICB3aW5kb3cuY29uc29sZS5sb2coIkluaXQgbGlzdGVuZXIgdGhyZXcgYW4gZXhjZXB0aW9uLiBDb250aW51aW5nLiIsIGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvLyBBbGxvdyBleHRlcm5hbCBzY3JpcHRzIHRvIGluaXRpYWxpemUgdGhpcyBsaWJyYXJ5IGluIGNhc2UgaXQncyBsb2FkZWQgYWZ0ZXIgdGhlIGRvY3VtZW50IGhhcyBsb2FkZWQKICAgIGFwaS5pbml0ID0gaW5pdDsKCiAgICAvLyBFeGVjdXRlIGxpc3RlbmVyIGltbWVkaWF0ZWx5IGlmIGFscmVhZHkgaW5pdGlhbGl6ZWQKICAgIGFwaS5hZGRJbml0TGlzdGVuZXIgPSBmdW5jdGlvbiAobGlzdGVuZXIpIHsKICAgICAgICBpZiAoYXBpLmluaXRpYWxpemVkKSB7CiAgICAgICAgICAgIGxpc3RlbmVyKGFwaSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW5pdExpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTsKICAgICAgICB9CiAgICB9OwoKICAgIHZhciBjcmVhdGVNaXNzaW5nTmF0aXZlQXBpTGlzdGVuZXJzID0gW107CgogICAgYXBpLmFkZENyZWF0ZU1pc3NpbmdOYXRpdmVBcGlMaXN0ZW5lciA9IGZ1bmN0aW9uIChsaXN0ZW5lcikgewogICAgICAgIGNyZWF0ZU1pc3NpbmdOYXRpdmVBcGlMaXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7CiAgICB9OwoKICAgIGZ1bmN0aW9uIGNyZWF0ZU1pc3NpbmdOYXRpdmVBcGkod2luKSB7CiAgICAgICAgd2luID0gd2luIHx8IHdpbmRvdzsKICAgICAgICBpbml0KCk7CgogICAgICAgIC8vIE5vdGlmeSBsaXN0ZW5lcnMKICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gY3JlYXRlTWlzc2luZ05hdGl2ZUFwaUxpc3RlbmVycy5sZW5ndGg7CiAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgIGNyZWF0ZU1pc3NpbmdOYXRpdmVBcGlMaXN0ZW5lcnNbaV0od2luKTsKICAgICAgICB9CiAgICB9CgogICAgYXBpLmNyZWF0ZU1pc3NpbmdOYXRpdmVBcGkgPSBjcmVhdGVNaXNzaW5nTmF0aXZlQXBpOwoKICAgIC8qKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKi8KICAgIGZ1bmN0aW9uIE1vZHVsZShuYW1lKSB7CiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICB0aGlzLmluaXRpYWxpemVkID0gZmFsc2U7CiAgICAgICAgdGhpcy5zdXBwb3J0ZWQgPSBmYWxzZTsKICAgIH0KCiAgICBNb2R1bGUucHJvdG90eXBlLmZhaWwgPSBmdW5jdGlvbiAocmVhc29uKSB7CiAgICAgICAgdGhpcy5pbml0aWFsaXplZCA9IHRydWU7CiAgICAgICAgdGhpcy5zdXBwb3J0ZWQgPSBmYWxzZTsKCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJNb2R1bGUgJyIgKyB0aGlzLm5hbWUgKyAiJyBmYWlsZWQgdG8gbG9hZDogIiArIHJlYXNvbik7CiAgICB9OwoKICAgIE1vZHVsZS5wcm90b3R5cGUud2FybiA9IGZ1bmN0aW9uIChtc2cpIHsKICAgICAgICBhcGkud2FybigiTW9kdWxlICIgKyB0aGlzLm5hbWUgKyAiOiAiICsgbXNnKTsKICAgIH07CgogICAgTW9kdWxlLnByb3RvdHlwZS5jcmVhdGVFcnJvciA9IGZ1bmN0aW9uIChtc2cpIHsKICAgICAgICByZXR1cm4gbmV3IEVycm9yKCJFcnJvciBpbiBSYW5neSAiICsgdGhpcy5uYW1lICsgIiBtb2R1bGU6ICIgKyBtc2cpOwogICAgfTsKCiAgICBhcGkuY3JlYXRlTW9kdWxlID0gZnVuY3Rpb24gKG5hbWUsIGluaXRGdW5jKSB7CiAgICAgICAgdmFyIG1vZHVsZSA9IG5ldyBNb2R1bGUobmFtZSk7CiAgICAgICAgYXBpLm1vZHVsZXNbbmFtZV0gPSBtb2R1bGU7CgogICAgICAgIG1vZHVsZUluaXRpYWxpemVycy5wdXNoKGZ1bmN0aW9uIChhcGkpIHsKICAgICAgICAgICAgaW5pdEZ1bmMoYXBpLCBtb2R1bGUpOwogICAgICAgICAgICBtb2R1bGUuaW5pdGlhbGl6ZWQgPSB0cnVlOwogICAgICAgICAgICBtb2R1bGUuc3VwcG9ydGVkID0gdHJ1ZTsKICAgICAgICB9KTsKICAgIH07CgogICAgYXBpLnJlcXVpcmVNb2R1bGVzID0gZnVuY3Rpb24gKG1vZHVsZXMpIHsKICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gbW9kdWxlcy5sZW5ndGgsIG1vZHVsZSwgbW9kdWxlTmFtZTsKICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgbW9kdWxlTmFtZSA9IG1vZHVsZXNbaV07CiAgICAgICAgICAgIG1vZHVsZSA9IGFwaS5tb2R1bGVzW21vZHVsZU5hbWVdOwogICAgICAgICAgICBpZiAoIW1vZHVsZSB8fCAhKG1vZHVsZSBpbnN0YW5jZW9mIE1vZHVsZSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiTW9kdWxlICciICsgbW9kdWxlTmFtZSArICInIG5vdCBmb3VuZCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghbW9kdWxlLnN1cHBvcnRlZCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJNb2R1bGUgJyIgKyBtb2R1bGVOYW1lICsgIicgbm90IHN1cHBvcnRlZCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8vIFdhaXQgZm9yIGRvY3VtZW50IHRvIGxvYWQgYmVmb3JlIHJ1bm5pbmcgdGVzdHMKCiAgICB2YXIgZG9jUmVhZHkgPSBmYWxzZTsKCiAgICB2YXIgbG9hZEhhbmRsZXIgPSBmdW5jdGlvbiAoZSkgewoKICAgICAgICBpZiAoIWRvY1JlYWR5KSB7CiAgICAgICAgICAgIGRvY1JlYWR5ID0gdHJ1ZTsKICAgICAgICAgICAgaWYgKCFhcGkuaW5pdGlhbGl6ZWQpIHsKICAgICAgICAgICAgICAgIGluaXQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgLy8gVGVzdCB3aGV0aGVyIHdlIGhhdmUgd2luZG93IGFuZCBkb2N1bWVudCBvYmplY3RzIHRoYXQgd2Ugd2lsbCBuZWVkCiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PSBVTkRFRklORUQpIHsKICAgICAgICBmYWlsKCJObyB3aW5kb3cgZm91bmQiKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09IFVOREVGSU5FRCkgewogICAgICAgIGZhaWwoIk5vIGRvY3VtZW50IGZvdW5kIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChpc0hvc3RNZXRob2QoZG9jdW1lbnQsICJhZGRFdmVudExpc3RlbmVyIikpIHsKICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIiwgbG9hZEhhbmRsZXIsIGZhbHNlKTsKICAgIH0KCiAgICAvLyBBZGQgYSBmYWxsYmFjayBpbiBjYXNlIHRoZSBET01Db250ZW50TG9hZGVkIGV2ZW50IGlzbid0IHN1cHBvcnRlZAogICAgaWYgKGlzSG9zdE1ldGhvZCh3aW5kb3csICJhZGRFdmVudExpc3RlbmVyIikpIHsKICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigibG9hZCIsIGxvYWRIYW5kbGVyLCBmYWxzZSk7CiAgICB9IGVsc2UgaWYgKGlzSG9zdE1ldGhvZCh3aW5kb3csICJhdHRhY2hFdmVudCIpKSB7CiAgICAgICAgd2luZG93LmF0dGFjaEV2ZW50KCJvbmxvYWQiLCBsb2FkSGFuZGxlcik7CiAgICB9IGVsc2UgewogICAgICAgIGZhaWwoIldpbmRvdyBkb2VzIG5vdCBoYXZlIHJlcXVpcmVkIGFkZEV2ZW50TGlzdGVuZXIgb3IgYXR0YWNoRXZlbnQgbWV0aG9kIik7CiAgICB9CgogICAgcmV0dXJuIGFwaTsKfSkoKTsKcmFuZ3kuY3JlYXRlTW9kdWxlKCJEb21VdGlsIiwgZnVuY3Rpb24gKGFwaSwgbW9kdWxlKSB7CgogICAgdmFyIFVOREVGID0gInVuZGVmaW5lZCI7CiAgICB2YXIgdXRpbCA9IGFwaS51dGlsOwoKICAgIC8vIFBlcmZvcm0gZmVhdHVyZSB0ZXN0cwogICAgaWYgKCF1dGlsLmFyZUhvc3RNZXRob2RzKGRvY3VtZW50LCBbImNyZWF0ZURvY3VtZW50RnJhZ21lbnQiLCAiY3JlYXRlRWxlbWVudCIsICJjcmVhdGVUZXh0Tm9kZSJdKSkgewogICAgICAgIG1vZHVsZS5mYWlsKCJkb2N1bWVudCBtaXNzaW5nIGEgTm9kZSBjcmVhdGlvbiBtZXRob2QiKTsKICAgIH0KCiAgICBpZiAoIXV0aWwuaXNIb3N0TWV0aG9kKGRvY3VtZW50LCAiZ2V0RWxlbWVudHNCeVRhZ05hbWUiKSkgewogICAgICAgIG1vZHVsZS5mYWlsKCJkb2N1bWVudCBtaXNzaW5nIGdldEVsZW1lbnRzQnlUYWdOYW1lIG1ldGhvZCIpOwogICAgfQoKICAgIHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpOwogICAgaWYgKCF1dGlsLmFyZUhvc3RNZXRob2RzKGVsLCBbImluc2VydEJlZm9yZSIsICJhcHBlbmRDaGlsZCIsICJjbG9uZU5vZGUiXSB8fCAhdXRpbC5hcmVIb3N0T2JqZWN0cyhlbCwgWyJwcmV2aW91c1NpYmxpbmciLCAibmV4dFNpYmxpbmciLCAiY2hpbGROb2RlcyIsICJwYXJlbnROb2RlIl0pKSkgewogICAgICAgIG1vZHVsZS5mYWlsKCJJbmNvbXBsZXRlIEVsZW1lbnQgaW1wbGVtZW50YXRpb24iKTsKICAgIH0KCiAgICAvLyBpbm5lckhUTUwgaXMgcmVxdWlyZWQgZm9yIFJhbmdlJ3MgY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IG1ldGhvZAogICAgaWYgKCF1dGlsLmlzSG9zdFByb3BlcnR5KGVsLCAiaW5uZXJIVE1MIikpIHsKICAgICAgICBtb2R1bGUuZmFpbCgiRWxlbWVudCBpcyBtaXNzaW5nIGlubmVySFRNTCBwcm9wZXJ0eSIpOwogICAgfQoKICAgIHZhciB0ZXh0Tm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCJ0ZXN0Iik7CiAgICBpZiAoIXV0aWwuYXJlSG9zdE1ldGhvZHModGV4dE5vZGUsIFsic3BsaXRUZXh0IiwgImRlbGV0ZURhdGEiLCAiaW5zZXJ0RGF0YSIsICJhcHBlbmREYXRhIiwgImNsb25lTm9kZSJdIHx8ICF1dGlsLmFyZUhvc3RPYmplY3RzKGVsLCBbInByZXZpb3VzU2libGluZyIsICJuZXh0U2libGluZyIsICJjaGlsZE5vZGVzIiwgInBhcmVudE5vZGUiXSkgfHwgIXV0aWwuYXJlSG9zdFByb3BlcnRpZXModGV4dE5vZGUsIFsiZGF0YSJdKSkpIHsKICAgICAgICBtb2R1bGUuZmFpbCgiSW5jb21wbGV0ZSBUZXh0IE5vZGUgaW1wbGVtZW50YXRpb24iKTsKICAgIH0KCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8vIFJlbW92ZWQgdXNlIG9mIGluZGV4T2YgYmVjYXVzZSBvZiBhIGJpemFycmUgYnVnIGluIE9wZXJhIHRoYXQgaXMgdGhyb3duIGluIG9uZSBvZiB0aGUgQWNpZDMgdGVzdHMuIEkgaGF2ZW4ndCBiZWVuCiAgICAvLyBhYmxlIHRvIHJlcGxpY2F0ZSBpdCBvdXRzaWRlIG9mIHRoZSB0ZXN0LiBUaGUgYnVnIGlzIHRoYXQgaW5kZXhPZiByZXR1cm5zIC0xIHdoZW4gY2FsbGVkIG9uIGFuIEFycmF5IHRoYXQKICAgIC8vIGNvbnRhaW5zIGp1c3QgdGhlIGRvY3VtZW50IGFzIGEgc2luZ2xlIGVsZW1lbnQgYW5kIHRoZSB2YWx1ZSBzZWFyY2hlZCBmb3IgaXMgdGhlIGRvY3VtZW50LgogICAgdmFyIGFycmF5Q29udGFpbnMgPSAvKkFycmF5LnByb3RvdHlwZS5pbmRleE9mID8KICAgICBmdW5jdGlvbihhcnIsIHZhbCkgewogICAgIHJldHVybiBhcnIuaW5kZXhPZih2YWwpID4gLTE7CiAgICAgfToqLwoKICAgICAgICBmdW5jdGlvbiAoYXJyLCB2YWwpIHsKICAgICAgICAgICAgdmFyIGkgPSBhcnIubGVuZ3RoOwogICAgICAgICAgICB3aGlsZSAoaS0tKSB7CiAgICAgICAgICAgICAgICBpZiAoYXJyW2ldID09PSB2YWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfTsKCiAgICAvLyBPcGVyYSAxMSBwdXRzIEhUTUwgZWxlbWVudHMgaW4gdGhlIG51bGwgbmFtZXNwYWNlLCBpdCBzZWVtcywgYW5kIElFIDcgaGFzIHVuZGVmaW5lZCBuYW1lc3BhY2VVUkkKICAgIGZ1bmN0aW9uIGlzSHRtbE5hbWVzcGFjZShub2RlKSB7CiAgICAgICAgdmFyIG5zOwogICAgICAgIHJldHVybiB0eXBlb2Ygbm9kZS5uYW1lc3BhY2VVUkkgPT0gVU5ERUYgfHwgKChucyA9IG5vZGUubmFtZXNwYWNlVVJJKSA9PT0gbnVsbCB8fCBucyA9PSAiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIpOwogICAgfQoKICAgIGZ1bmN0aW9uIHBhcmVudEVsZW1lbnQobm9kZSkgewogICAgICAgIHZhciBwYXJlbnQgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgcmV0dXJuIChwYXJlbnQubm9kZVR5cGUgPT0gMSkgPyBwYXJlbnQgOiBudWxsOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldE5vZGVJbmRleChub2RlKSB7CiAgICAgICAgdmFyIGkgPSAwOwogICAgICAgIHdoaWxlICgobm9kZSA9IG5vZGUucHJldmlvdXNTaWJsaW5nKSkgewogICAgICAgICAgICBpKys7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldE5vZGVMZW5ndGgobm9kZSkgewogICAgICAgIHZhciBjaGlsZE5vZGVzOwogICAgICAgIHJldHVybiBpc0NoYXJhY3RlckRhdGFOb2RlKG5vZGUpID8gbm9kZS5sZW5ndGggOiAoKGNoaWxkTm9kZXMgPSBub2RlLmNoaWxkTm9kZXMpID8gY2hpbGROb2Rlcy5sZW5ndGggOiAwKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRDb21tb25BbmNlc3Rvcihub2RlMSwgbm9kZTIpIHsKICAgICAgICB2YXIgYW5jZXN0b3JzID0gW10sIG47CiAgICAgICAgZm9yIChuID0gbm9kZTE7CiAgICAgICAgICAgICBuOwogICAgICAgICAgICAgbiA9IG4ucGFyZW50Tm9kZSkgewogICAgICAgICAgICBhbmNlc3RvcnMucHVzaChuKTsKICAgICAgICB9CgogICAgICAgIGZvciAobiA9IG5vZGUyOwogICAgICAgICAgICAgbjsKICAgICAgICAgICAgIG4gPSBuLnBhcmVudE5vZGUpIHsKICAgICAgICAgICAgaWYgKGFycmF5Q29udGFpbnMoYW5jZXN0b3JzLCBuKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzQW5jZXN0b3JPZihhbmNlc3RvciwgZGVzY2VuZGFudCwgc2VsZklzQW5jZXN0b3IpIHsKICAgICAgICB2YXIgbiA9IHNlbGZJc0FuY2VzdG9yID8gZGVzY2VuZGFudCA6IGRlc2NlbmRhbnQucGFyZW50Tm9kZTsKICAgICAgICB3aGlsZSAobikgewogICAgICAgICAgICBpZiAobiA9PT0gYW5jZXN0b3IpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbiA9IG4ucGFyZW50Tm9kZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0Q2xvc2VzdEFuY2VzdG9ySW4obm9kZSwgYW5jZXN0b3IsIHNlbGZJc0FuY2VzdG9yKSB7CiAgICAgICAgdmFyIHAsIG4gPSBzZWxmSXNBbmNlc3RvciA/IG5vZGUgOiBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgd2hpbGUgKG4pIHsKICAgICAgICAgICAgcCA9IG4ucGFyZW50Tm9kZTsKICAgICAgICAgICAgaWYgKHAgPT09IGFuY2VzdG9yKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbjsKICAgICAgICAgICAgfQogICAgICAgICAgICBuID0gcDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgZnVuY3Rpb24gaXNDaGFyYWN0ZXJEYXRhTm9kZShub2RlKSB7CiAgICAgICAgdmFyIHQgPSBub2RlLm5vZGVUeXBlOwogICAgICAgIHJldHVybiB0ID09IDMgfHwgdCA9PSA0IHx8IHQgPT0gODsgLy8gVGV4dCwgQ0RhdGFTZWN0aW9uIG9yIENvbW1lbnQKICAgIH0KCiAgICBmdW5jdGlvbiBpbnNlcnRBZnRlcihub2RlLCBwcmVjZWRpbmdOb2RlKSB7CiAgICAgICAgdmFyIG5leHROb2RlID0gcHJlY2VkaW5nTm9kZS5uZXh0U2libGluZywgcGFyZW50ID0gcHJlY2VkaW5nTm9kZS5wYXJlbnROb2RlOwogICAgICAgIGlmIChuZXh0Tm9kZSkgewogICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKG5vZGUsIG5leHROb2RlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQobm9kZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBub2RlOwogICAgfQoKICAgIC8vIE5vdGUgdGhhdCB3ZSBjYW5ub3QgdXNlIHNwbGl0VGV4dCgpIGJlY2F1c2UgaXQgaXMgYnVncmlkZGVuIGluIElFIDkuCiAgICBmdW5jdGlvbiBzcGxpdERhdGFOb2RlKG5vZGUsIGluZGV4KSB7CiAgICAgICAgdmFyIG5ld05vZGUgPSBub2RlLmNsb25lTm9kZShmYWxzZSk7CiAgICAgICAgbmV3Tm9kZS5kZWxldGVEYXRhKDAsIGluZGV4KTsKICAgICAgICBub2RlLmRlbGV0ZURhdGEoaW5kZXgsIG5vZGUubGVuZ3RoIC0gaW5kZXgpOwogICAgICAgIGluc2VydEFmdGVyKG5ld05vZGUsIG5vZGUpOwogICAgICAgIHJldHVybiBuZXdOb2RlOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldERvY3VtZW50KG5vZGUpIHsKICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSA5KSB7CiAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG5vZGUub3duZXJEb2N1bWVudCAhPSBVTkRFRikgewogICAgICAgICAgICByZXR1cm4gbm9kZS5vd25lckRvY3VtZW50OwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG5vZGUuZG9jdW1lbnQgIT0gVU5ERUYpIHsKICAgICAgICAgICAgcmV0dXJuIG5vZGUuZG9jdW1lbnQ7CiAgICAgICAgfSBlbHNlIGlmIChub2RlLnBhcmVudE5vZGUpIHsKICAgICAgICAgICAgcmV0dXJuIGdldERvY3VtZW50KG5vZGUucGFyZW50Tm9kZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJnZXREb2N1bWVudDogbm8gZG9jdW1lbnQgZm91bmQgZm9yIG5vZGUiKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0V2luZG93KG5vZGUpIHsKICAgICAgICB2YXIgZG9jID0gZ2V0RG9jdW1lbnQobm9kZSk7CiAgICAgICAgaWYgKHR5cGVvZiBkb2MuZGVmYXVsdFZpZXcgIT0gVU5ERUYpIHsKICAgICAgICAgICAgcmV0dXJuIGRvYy5kZWZhdWx0VmlldzsKICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkb2MucGFyZW50V2luZG93ICE9IFVOREVGKSB7CiAgICAgICAgICAgIHJldHVybiBkb2MucGFyZW50V2luZG93OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiQ2Fubm90IGdldCBhIHdpbmRvdyBvYmplY3QgZm9yIG5vZGUiKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0SWZyYW1lRG9jdW1lbnQoaWZyYW1lRWwpIHsKICAgICAgICBpZiAodHlwZW9mIGlmcmFtZUVsLmNvbnRlbnREb2N1bWVudCAhPSBVTkRFRikgewogICAgICAgICAgICByZXR1cm4gaWZyYW1lRWwuY29udGVudERvY3VtZW50OwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGlmcmFtZUVsLmNvbnRlbnRXaW5kb3cgIT0gVU5ERUYpIHsKICAgICAgICAgICAgcmV0dXJuIGlmcmFtZUVsLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJnZXRJZnJhbWVXaW5kb3c6IE5vIERvY3VtZW50IG9iamVjdCBmb3VuZCBmb3IgaWZyYW1lIGVsZW1lbnQiKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0SWZyYW1lV2luZG93KGlmcmFtZUVsKSB7CiAgICAgICAgaWYgKHR5cGVvZiBpZnJhbWVFbC5jb250ZW50V2luZG93ICE9IFVOREVGKSB7CiAgICAgICAgICAgIHJldHVybiBpZnJhbWVFbC5jb250ZW50V2luZG93OwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGlmcmFtZUVsLmNvbnRlbnREb2N1bWVudCAhPSBVTkRFRikgewogICAgICAgICAgICByZXR1cm4gaWZyYW1lRWwuY29udGVudERvY3VtZW50LmRlZmF1bHRWaWV3OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiZ2V0SWZyYW1lV2luZG93OiBObyBXaW5kb3cgb2JqZWN0IGZvdW5kIGZvciBpZnJhbWUgZWxlbWVudCIpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBnZXRCb2R5KGRvYykgewogICAgICAgIHJldHVybiB1dGlsLmlzSG9zdE9iamVjdChkb2MsICJib2R5IikgPyBkb2MuYm9keSA6IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYm9keSIpWzBdOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldFJvb3RDb250YWluZXIobm9kZSkgewogICAgICAgIHZhciBwYXJlbnQ7CiAgICAgICAgd2hpbGUgKChwYXJlbnQgPSBub2RlLnBhcmVudE5vZGUpKSB7CiAgICAgICAgICAgIG5vZGUgPSBwYXJlbnQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBub2RlOwogICAgfQoKICAgIGZ1bmN0aW9uIGNvbXBhcmVQb2ludHMobm9kZUEsIG9mZnNldEEsIG5vZGVCLCBvZmZzZXRCKSB7CiAgICAgICAgLy8gU2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLVRyYXZlcnNhbC1SYW5nZS9yYW5nZXMuaHRtbCNMZXZlbC0yLVJhbmdlLUNvbXBhcmluZwogICAgICAgIHZhciBub2RlQywgcm9vdCwgY2hpbGRBLCBjaGlsZEIsIG47CiAgICAgICAgaWYgKG5vZGVBID09IG5vZGVCKSB7CgogICAgICAgICAgICAvLyBDYXNlIDE6IG5vZGVzIGFyZSB0aGUgc2FtZQogICAgICAgICAgICByZXR1cm4gb2Zmc2V0QSA9PT0gb2Zmc2V0QiA/IDAgOiAob2Zmc2V0QSA8IG9mZnNldEIpID8gLTEgOiAxOwogICAgICAgIH0gZWxzZSBpZiAoKG5vZGVDID0gZ2V0Q2xvc2VzdEFuY2VzdG9ySW4obm9kZUIsIG5vZGVBLCB0cnVlKSkpIHsKCiAgICAgICAgICAgIC8vIENhc2UgMjogbm9kZSBDIChjb250YWluZXIgQiBvciBhbiBhbmNlc3RvcikgaXMgYSBjaGlsZCBub2RlIG9mIEEKICAgICAgICAgICAgcmV0dXJuIG9mZnNldEEgPD0gZ2V0Tm9kZUluZGV4KG5vZGVDKSA/IC0xIDogMTsKICAgICAgICB9IGVsc2UgaWYgKChub2RlQyA9IGdldENsb3Nlc3RBbmNlc3RvckluKG5vZGVBLCBub2RlQiwgdHJ1ZSkpKSB7CgogICAgICAgICAgICAvLyBDYXNlIDM6IG5vZGUgQyAoY29udGFpbmVyIEEgb3IgYW4gYW5jZXN0b3IpIGlzIGEgY2hpbGQgbm9kZSBvZiBCCiAgICAgICAgICAgIHJldHVybiBnZXROb2RlSW5kZXgobm9kZUMpIDwgb2Zmc2V0QiA/IC0xIDogMTsKICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgLy8gQ2FzZSA0OiBjb250YWluZXJzIGFyZSBzaWJsaW5ncyBvciBkZXNjZW5kYW50cyBvZiBzaWJsaW5ncwogICAgICAgICAgICByb290ID0gZ2V0Q29tbW9uQW5jZXN0b3Iobm9kZUEsIG5vZGVCKTsKICAgICAgICAgICAgY2hpbGRBID0gKG5vZGVBID09PSByb290KSA/IHJvb3QgOiBnZXRDbG9zZXN0QW5jZXN0b3JJbihub2RlQSwgcm9vdCwgdHJ1ZSk7CiAgICAgICAgICAgIGNoaWxkQiA9IChub2RlQiA9PT0gcm9vdCkgPyByb290IDogZ2V0Q2xvc2VzdEFuY2VzdG9ySW4obm9kZUIsIHJvb3QsIHRydWUpOwoKICAgICAgICAgICAgaWYgKGNoaWxkQSA9PT0gY2hpbGRCKSB7CiAgICAgICAgICAgICAgICAvLyBUaGlzIHNob3VsZG4ndCBiZSBwb3NzaWJsZQoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiY29tcGFyZVBvaW50cyBnb3QgdG8gY2FzZSA0IGFuZCBjaGlsZEEgYW5kIGNoaWxkQiBhcmUgdGhlIHNhbWUhIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBuID0gcm9vdC5maXJzdENoaWxkOwogICAgICAgICAgICAgICAgd2hpbGUgKG4pIHsKICAgICAgICAgICAgICAgICAgICBpZiAobiA9PT0gY2hpbGRBKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG4gPT09IGNoaWxkQikgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbiA9IG4ubmV4dFNpYmxpbmc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlNob3VsZCBub3QgYmUgaGVyZSEiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBmcmFnbWVudEZyb21Ob2RlQ2hpbGRyZW4obm9kZSkgewogICAgICAgIHZhciBmcmFnbWVudCA9IGdldERvY3VtZW50KG5vZGUpLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSwgY2hpbGQ7CiAgICAgICAgd2hpbGUgKChjaGlsZCA9IG5vZGUuZmlyc3RDaGlsZCkpIHsKICAgICAgICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoY2hpbGQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZnJhZ21lbnQ7CiAgICB9CgogICAgZnVuY3Rpb24gaW5zcGVjdE5vZGUobm9kZSkgewogICAgICAgIGlmICghbm9kZSkgewogICAgICAgICAgICByZXR1cm4gIltObyBub2RlXSI7CiAgICAgICAgfQogICAgICAgIGlmIChpc0NoYXJhY3RlckRhdGFOb2RlKG5vZGUpKSB7CiAgICAgICAgICAgIHJldHVybiAnIicgKyBub2RlLmRhdGEgKyAnIic7CiAgICAgICAgfSBlbHNlIGlmIChub2RlLm5vZGVUeXBlID09IDEpIHsKICAgICAgICAgICAgdmFyIGlkQXR0ciA9IG5vZGUuaWQgPyAnIGlkPSInICsgbm9kZS5pZCArICciJyA6ICIiOwogICAgICAgICAgICByZXR1cm4gIjwiICsgbm9kZS5ub2RlTmFtZSArIGlkQXR0ciArICI+WyIgKyBub2RlLmNoaWxkTm9kZXMubGVuZ3RoICsgIl0iOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBub2RlLm5vZGVOYW1lOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBjb25zdHJ1Y3RvcgogICAgICovCiAgICBmdW5jdGlvbiBOb2RlSXRlcmF0b3Iocm9vdCkgewogICAgICAgIHRoaXMucm9vdCA9IHJvb3Q7CiAgICAgICAgdGhpcy5fbmV4dCA9IHJvb3Q7CiAgICB9CgogICAgTm9kZUl0ZXJhdG9yLnByb3RvdHlwZSA9IHsKICAgICAgICBfY3VycmVudCA6IG51bGwsCgogICAgICAgIGhhc05leHQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMuX25leHQ7CiAgICAgICAgfSwKCiAgICAgICAgbmV4dCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIG4gPSB0aGlzLl9jdXJyZW50ID0gdGhpcy5fbmV4dDsKICAgICAgICAgICAgdmFyIGNoaWxkLCBuZXh0OwogICAgICAgICAgICBpZiAodGhpcy5fY3VycmVudCkgewogICAgICAgICAgICAgICAgY2hpbGQgPSBuLmZpcnN0Q2hpbGQ7CiAgICAgICAgICAgICAgICBpZiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9uZXh0ID0gY2hpbGQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIG5leHQgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIHdoaWxlICgobiAhPT0gdGhpcy5yb290KSAmJiAhKG5leHQgPSBuLm5leHRTaWJsaW5nKSkgewogICAgICAgICAgICAgICAgICAgICAgICBuID0gbi5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aGlzLl9uZXh0ID0gbmV4dDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdGhpcy5fY3VycmVudDsKICAgICAgICB9LAoKICAgICAgICBkZXRhY2ggOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnQgPSB0aGlzLl9uZXh0ID0gdGhpcy5yb290ID0gbnVsbDsKICAgICAgICB9CiAgICB9OwoKICAgIGZ1bmN0aW9uIGNyZWF0ZUl0ZXJhdG9yKHJvb3QpIHsKICAgICAgICByZXR1cm4gbmV3IE5vZGVJdGVyYXRvcihyb290KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBjb25zdHJ1Y3RvcgogICAgICovCiAgICBmdW5jdGlvbiBEb21Qb3NpdGlvbihub2RlLCBvZmZzZXQpIHsKICAgICAgICB0aGlzLm5vZGUgPSBub2RlOwogICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0OwogICAgfQoKICAgIERvbVBvc2l0aW9uLnByb3RvdHlwZSA9IHsKICAgICAgICBlcXVhbHMgOiBmdW5jdGlvbiAocG9zKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLm5vZGUgPT09IHBvcy5ub2RlICYgdGhpcy5vZmZzZXQgPT0gcG9zLm9mZnNldDsKICAgICAgICB9LAoKICAgICAgICBpbnNwZWN0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gIltEb21Qb3NpdGlvbigiICsgaW5zcGVjdE5vZGUodGhpcy5ub2RlKSArICI6IiArIHRoaXMub2Zmc2V0ICsgIildIjsKICAgICAgICB9CiAgICB9OwoKICAgIC8qKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKi8KICAgIGZ1bmN0aW9uIERPTUV4Y2VwdGlvbihjb2RlTmFtZSkgewogICAgICAgIHRoaXMuY29kZSA9IHRoaXNbY29kZU5hbWVdOwogICAgICAgIHRoaXMuY29kZU5hbWUgPSBjb2RlTmFtZTsKICAgICAgICB0aGlzLm1lc3NhZ2UgPSAiRE9NRXhjZXB0aW9uOiAiICsgdGhpcy5jb2RlTmFtZTsKICAgIH0KCiAgICBET01FeGNlcHRpb24ucHJvdG90eXBlID0gewogICAgICAgIElOREVYX1NJWkVfRVJSIDogMSwKICAgICAgICBISUVSQVJDSFlfUkVRVUVTVF9FUlIgOiAzLAogICAgICAgIFdST05HX0RPQ1VNRU5UX0VSUiA6IDQsCiAgICAgICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIDogNywKICAgICAgICBOT1RfRk9VTkRfRVJSIDogOCwKICAgICAgICBOT1RfU1VQUE9SVEVEX0VSUiA6IDksCiAgICAgICAgSU5WQUxJRF9TVEFURV9FUlIgOiAxMQogICAgfTsKCiAgICBET01FeGNlcHRpb24ucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiB0aGlzLm1lc3NhZ2U7CiAgICB9OwoKICAgIGFwaS5kb20gPSB7CiAgICAgICAgYXJyYXlDb250YWlucyA6IGFycmF5Q29udGFpbnMsCiAgICAgICAgaXNIdG1sTmFtZXNwYWNlIDogaXNIdG1sTmFtZXNwYWNlLAogICAgICAgIHBhcmVudEVsZW1lbnQgOiBwYXJlbnRFbGVtZW50LAogICAgICAgIGdldE5vZGVJbmRleCA6IGdldE5vZGVJbmRleCwKICAgICAgICBnZXROb2RlTGVuZ3RoIDogZ2V0Tm9kZUxlbmd0aCwKICAgICAgICBnZXRDb21tb25BbmNlc3RvciA6IGdldENvbW1vbkFuY2VzdG9yLAogICAgICAgIGlzQW5jZXN0b3JPZiA6IGlzQW5jZXN0b3JPZiwKICAgICAgICBnZXRDbG9zZXN0QW5jZXN0b3JJbiA6IGdldENsb3Nlc3RBbmNlc3RvckluLAogICAgICAgIGlzQ2hhcmFjdGVyRGF0YU5vZGUgOiBpc0NoYXJhY3RlckRhdGFOb2RlLAogICAgICAgIGluc2VydEFmdGVyIDogaW5zZXJ0QWZ0ZXIsCiAgICAgICAgc3BsaXREYXRhTm9kZSA6IHNwbGl0RGF0YU5vZGUsCiAgICAgICAgZ2V0RG9jdW1lbnQgOiBnZXREb2N1bWVudCwKICAgICAgICBnZXRXaW5kb3cgOiBnZXRXaW5kb3csCiAgICAgICAgZ2V0SWZyYW1lV2luZG93IDogZ2V0SWZyYW1lV2luZG93LAogICAgICAgIGdldElmcmFtZURvY3VtZW50IDogZ2V0SWZyYW1lRG9jdW1lbnQsCiAgICAgICAgZ2V0Qm9keSA6IGdldEJvZHksCiAgICAgICAgZ2V0Um9vdENvbnRhaW5lciA6IGdldFJvb3RDb250YWluZXIsCiAgICAgICAgY29tcGFyZVBvaW50cyA6IGNvbXBhcmVQb2ludHMsCiAgICAgICAgaW5zcGVjdE5vZGUgOiBpbnNwZWN0Tm9kZSwKICAgICAgICBmcmFnbWVudEZyb21Ob2RlQ2hpbGRyZW4gOiBmcmFnbWVudEZyb21Ob2RlQ2hpbGRyZW4sCiAgICAgICAgY3JlYXRlSXRlcmF0b3IgOiBjcmVhdGVJdGVyYXRvciwKICAgICAgICBEb21Qb3NpdGlvbiA6IERvbVBvc2l0aW9uCiAgICB9OwoKICAgIGFwaS5ET01FeGNlcHRpb24gPSBET01FeGNlcHRpb247Cn0pOwpyYW5neS5jcmVhdGVNb2R1bGUoIkRvbVJhbmdlIiwgZnVuY3Rpb24gKGFwaSwgbW9kdWxlKSB7CiAgICBhcGkucmVxdWlyZU1vZHVsZXMoWyJEb21VdGlsIl0pOwoKICAgIHZhciBkb20gPSBhcGkuZG9tOwogICAgdmFyIERvbVBvc2l0aW9uID0gZG9tLkRvbVBvc2l0aW9uOwogICAgdmFyIERPTUV4Y2VwdGlvbiA9IGFwaS5ET01FeGNlcHRpb247CgogICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCiAgICAvLyBVdGlsaXR5IGZ1bmN0aW9ucwoKICAgIGZ1bmN0aW9uIGlzTm9uVGV4dFBhcnRpYWxseVNlbGVjdGVkKG5vZGUsIHJhbmdlKSB7CiAgICAgICAgcmV0dXJuIChub2RlLm5vZGVUeXBlICE9IDMpICYmIChkb20uaXNBbmNlc3Rvck9mKG5vZGUsIHJhbmdlLnN0YXJ0Q29udGFpbmVyLCB0cnVlKSB8fCBkb20uaXNBbmNlc3Rvck9mKG5vZGUsIHJhbmdlLmVuZENvbnRhaW5lciwgdHJ1ZSkpOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldFJhbmdlRG9jdW1lbnQocmFuZ2UpIHsKICAgICAgICByZXR1cm4gZG9tLmdldERvY3VtZW50KHJhbmdlLnN0YXJ0Q29udGFpbmVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBkaXNwYXRjaEV2ZW50KHJhbmdlLCB0eXBlLCBhcmdzKSB7CiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHJhbmdlLl9saXN0ZW5lcnNbdHlwZV07CiAgICAgICAgaWYgKGxpc3RlbmVycykgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsKICAgICAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgICAgICsraSkgewogICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmNhbGwocmFuZ2UsIHt0YXJnZXQgOiByYW5nZSwgYXJncyA6IGFyZ3N9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBnZXRCb3VuZGFyeUJlZm9yZU5vZGUobm9kZSkgewogICAgICAgIHJldHVybiBuZXcgRG9tUG9zaXRpb24obm9kZS5wYXJlbnROb2RlLCBkb20uZ2V0Tm9kZUluZGV4KG5vZGUpKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRCb3VuZGFyeUFmdGVyTm9kZShub2RlKSB7CiAgICAgICAgcmV0dXJuIG5ldyBEb21Qb3NpdGlvbihub2RlLnBhcmVudE5vZGUsIGRvbS5nZXROb2RlSW5kZXgobm9kZSkgKyAxKTsKICAgIH0KCiAgICBmdW5jdGlvbiBpbnNlcnROb2RlQXRQb3NpdGlvbihub2RlLCBuLCBvKSB7CiAgICAgICAgdmFyIGZpcnN0Tm9kZUluc2VydGVkID0gbm9kZS5ub2RlVHlwZSA9PSAxMSA/IG5vZGUuZmlyc3RDaGlsZCA6IG5vZGU7CiAgICAgICAgaWYgKGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKG4pKSB7CiAgICAgICAgICAgIGlmIChvID09IG4ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBkb20uaW5zZXJ0QWZ0ZXIobm9kZSwgbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBuLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5vZGUsIG8gPT0gMCA/IG4gOiBkb20uc3BsaXREYXRhTm9kZShuLCBvKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKG8gPj0gbi5jaGlsZE5vZGVzLmxlbmd0aCkgewogICAgICAgICAgICBuLmFwcGVuZENoaWxkKG5vZGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG4uaW5zZXJ0QmVmb3JlKG5vZGUsIG4uY2hpbGROb2Rlc1tvXSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaXJzdE5vZGVJbnNlcnRlZDsKICAgIH0KCiAgICBmdW5jdGlvbiBjbG9uZVN1YnRyZWUoaXRlcmF0b3IpIHsKICAgICAgICB2YXIgcGFydGlhbGx5U2VsZWN0ZWQ7CiAgICAgICAgZm9yICh2YXIgbm9kZSwgZnJhZyA9IGdldFJhbmdlRG9jdW1lbnQoaXRlcmF0b3IucmFuZ2UpLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSwgc3ViSXRlcmF0b3I7CiAgICAgICAgICAgICBub2RlID0gaXRlcmF0b3IubmV4dCgpOykgewogICAgICAgICAgICBwYXJ0aWFsbHlTZWxlY3RlZCA9IGl0ZXJhdG9yLmlzUGFydGlhbGx5U2VsZWN0ZWRTdWJ0cmVlKCk7CgogICAgICAgICAgICBub2RlID0gbm9kZS5jbG9uZU5vZGUoIXBhcnRpYWxseVNlbGVjdGVkKTsKICAgICAgICAgICAgaWYgKHBhcnRpYWxseVNlbGVjdGVkKSB7CiAgICAgICAgICAgICAgICBzdWJJdGVyYXRvciA9IGl0ZXJhdG9yLmdldFN1YnRyZWVJdGVyYXRvcigpOwogICAgICAgICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChjbG9uZVN1YnRyZWUoc3ViSXRlcmF0b3IpKTsKICAgICAgICAgICAgICAgIHN1Ykl0ZXJhdG9yLmRldGFjaCh0cnVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMTApIHsvLyBEb2N1bWVudFR5cGUKICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIkhJRVJBUkNIWV9SRVFVRVNUX0VSUiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZyYWcuYXBwZW5kQ2hpbGQobm9kZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmcmFnOwogICAgfQoKICAgIGZ1bmN0aW9uIGl0ZXJhdGVTdWJ0cmVlKHJhbmdlSXRlcmF0b3IsIGZ1bmMsIGl0ZXJhdG9yU3RhdGUpIHsKICAgICAgICB2YXIgaXQsIG47CiAgICAgICAgaXRlcmF0b3JTdGF0ZSA9IGl0ZXJhdG9yU3RhdGUgfHwge3N0b3AgOiBmYWxzZX07CiAgICAgICAgZm9yICh2YXIgbm9kZSwgc3ViUmFuZ2VJdGVyYXRvcjsKICAgICAgICAgICAgIG5vZGUgPSByYW5nZUl0ZXJhdG9yLm5leHQoKTspIHsKICAgICAgICAgICAgLy9sb2cuZGVidWcoIml0ZXJhdGVTdWJ0cmVlLCBwYXJ0aWFsbHkgc2VsZWN0ZWQ6ICIgKyByYW5nZUl0ZXJhdG9yLmlzUGFydGlhbGx5U2VsZWN0ZWRTdWJ0cmVlKCksIG5vZGVUb1N0cmluZyhub2RlKSk7CiAgICAgICAgICAgIGlmIChyYW5nZUl0ZXJhdG9yLmlzUGFydGlhbGx5U2VsZWN0ZWRTdWJ0cmVlKCkpIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBub2RlIGlzIHBhcnRpYWxseSBzZWxlY3RlZCBieSB0aGUgUmFuZ2UsIHNvIHdlIGNhbiB1c2UgYSBuZXcgUmFuZ2VJdGVyYXRvciBvbiB0aGUgcG9ydGlvbiBvZiB0aGUKICAgICAgICAgICAgICAgIC8vIG5vZGUgc2VsZWN0ZWQgYnkgdGhlIFJhbmdlLgogICAgICAgICAgICAgICAgaWYgKGZ1bmMobm9kZSkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgaXRlcmF0b3JTdGF0ZS5zdG9wID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHN1YlJhbmdlSXRlcmF0b3IgPSByYW5nZUl0ZXJhdG9yLmdldFN1YnRyZWVJdGVyYXRvcigpOwogICAgICAgICAgICAgICAgICAgIGl0ZXJhdGVTdWJ0cmVlKHN1YlJhbmdlSXRlcmF0b3IsIGZ1bmMsIGl0ZXJhdG9yU3RhdGUpOwogICAgICAgICAgICAgICAgICAgIHN1YlJhbmdlSXRlcmF0b3IuZGV0YWNoKHRydWUpOwogICAgICAgICAgICAgICAgICAgIGlmIChpdGVyYXRvclN0YXRlLnN0b3ApIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIFRoZSB3aG9sZSBub2RlIGlzIHNlbGVjdGVkLCBzbyB3ZSBjYW4gdXNlIGVmZmljaWVudCBET00gaXRlcmF0aW9uIHRvIGl0ZXJhdGUgb3ZlciB0aGUgbm9kZSBhbmQgaXRzCiAgICAgICAgICAgICAgICAvLyBkZXNjZW5kYW50CiAgICAgICAgICAgICAgICBpdCA9IGRvbS5jcmVhdGVJdGVyYXRvcihub2RlKTsKICAgICAgICAgICAgICAgIHdoaWxlICgobiA9IGl0Lm5leHQoKSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZnVuYyhuKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXRlcmF0b3JTdGF0ZS5zdG9wID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBkZWxldGVTdWJ0cmVlKGl0ZXJhdG9yKSB7CiAgICAgICAgdmFyIHN1Ykl0ZXJhdG9yOwogICAgICAgIHdoaWxlIChpdGVyYXRvci5uZXh0KCkpIHsKICAgICAgICAgICAgaWYgKGl0ZXJhdG9yLmlzUGFydGlhbGx5U2VsZWN0ZWRTdWJ0cmVlKCkpIHsKICAgICAgICAgICAgICAgIHN1Ykl0ZXJhdG9yID0gaXRlcmF0b3IuZ2V0U3VidHJlZUl0ZXJhdG9yKCk7CiAgICAgICAgICAgICAgICBkZWxldGVTdWJ0cmVlKHN1Ykl0ZXJhdG9yKTsKICAgICAgICAgICAgICAgIHN1Ykl0ZXJhdG9yLmRldGFjaCh0cnVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGl0ZXJhdG9yLnJlbW92ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGV4dHJhY3RTdWJ0cmVlKGl0ZXJhdG9yKSB7CgogICAgICAgIGZvciAodmFyIG5vZGUsIGZyYWcgPSBnZXRSYW5nZURvY3VtZW50KGl0ZXJhdG9yLnJhbmdlKS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksIHN1Ykl0ZXJhdG9yOwogICAgICAgICAgICAgbm9kZSA9IGl0ZXJhdG9yLm5leHQoKTspIHsKCiAgICAgICAgICAgIGlmIChpdGVyYXRvci5pc1BhcnRpYWxseVNlbGVjdGVkU3VidHJlZSgpKSB7CiAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5jbG9uZU5vZGUoZmFsc2UpOwogICAgICAgICAgICAgICAgc3ViSXRlcmF0b3IgPSBpdGVyYXRvci5nZXRTdWJ0cmVlSXRlcmF0b3IoKTsKICAgICAgICAgICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQoZXh0cmFjdFN1YnRyZWUoc3ViSXRlcmF0b3IpKTsKICAgICAgICAgICAgICAgIHN1Ykl0ZXJhdG9yLmRldGFjaCh0cnVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGl0ZXJhdG9yLnJlbW92ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDEwKSB7Ly8gRG9jdW1lbnRUeXBlCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKCJISUVSQVJDSFlfUkVRVUVTVF9FUlIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmcmFnLmFwcGVuZENoaWxkKG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZnJhZzsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXROb2Rlc0luUmFuZ2UocmFuZ2UsIG5vZGVUeXBlcywgZmlsdGVyKSB7CiAgICAgICAgLy9sb2cuaW5mbygiZ2V0Tm9kZXNJblJhbmdlLCAiICsgbm9kZVR5cGVzLmpvaW4oIiwiKSk7CiAgICAgICAgdmFyIGZpbHRlck5vZGVUeXBlcyA9ICEhKG5vZGVUeXBlcyAmJiBub2RlVHlwZXMubGVuZ3RoKSwgcmVnZXg7CiAgICAgICAgdmFyIGZpbHRlckV4aXN0cyA9ICEhZmlsdGVyOwogICAgICAgIGlmIChmaWx0ZXJOb2RlVHlwZXMpIHsKICAgICAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKCJeKCIgKyBub2RlVHlwZXMuam9pbigifCIpICsgIikkIik7CiAgICAgICAgfQoKICAgICAgICB2YXIgbm9kZXMgPSBbXTsKICAgICAgICBpdGVyYXRlU3VidHJlZShuZXcgUmFuZ2VJdGVyYXRvcihyYW5nZSwgZmFsc2UpLCBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICBpZiAoKCFmaWx0ZXJOb2RlVHlwZXMgfHwgcmVnZXgudGVzdChub2RlLm5vZGVUeXBlKSkgJiYgKCFmaWx0ZXJFeGlzdHMgfHwgZmlsdGVyKG5vZGUpKSkgewogICAgICAgICAgICAgICAgbm9kZXMucHVzaChub2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBub2RlczsKICAgIH0KCiAgICBmdW5jdGlvbiBpbnNwZWN0KHJhbmdlKSB7CiAgICAgICAgdmFyIG5hbWUgPSAodHlwZW9mIHJhbmdlLmdldE5hbWUgPT0gInVuZGVmaW5lZCIpID8gIlJhbmdlIiA6IHJhbmdlLmdldE5hbWUoKTsKICAgICAgICByZXR1cm4gIlsiICsgbmFtZSArICIoIiArIGRvbS5pbnNwZWN0Tm9kZShyYW5nZS5zdGFydENvbnRhaW5lcikgKyAiOiIgKyByYW5nZS5zdGFydE9mZnNldCArICIsICIgKwogICAgICAgICAgICBkb20uaW5zcGVjdE5vZGUocmFuZ2UuZW5kQ29udGFpbmVyKSArICI6IiArIHJhbmdlLmVuZE9mZnNldCArICIpXSI7CiAgICB9CgogICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCiAgICAvLyBSYW5nZUl0ZXJhdG9yIGNvZGUgcGFydGlhbGx5IGJvcnJvd3MgZnJvbSBJRVJhbmdlIGJ5IFRpbSBSeWFuIChodHRwOi8vZ2l0aHViLmNvbS90aW1jYW1lcm9ucnlhbi9JRVJhbmdlKQoKICAgIC8qKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKi8KICAgIGZ1bmN0aW9uIFJhbmdlSXRlcmF0b3IocmFuZ2UsIGNsb25lUGFydGlhbGx5U2VsZWN0ZWRUZXh0Tm9kZXMpIHsKICAgICAgICB0aGlzLnJhbmdlID0gcmFuZ2U7CiAgICAgICAgdGhpcy5jbG9uZVBhcnRpYWxseVNlbGVjdGVkVGV4dE5vZGVzID0gY2xvbmVQYXJ0aWFsbHlTZWxlY3RlZFRleHROb2RlczsKCiAgICAgICAgaWYgKCFyYW5nZS5jb2xsYXBzZWQpIHsKICAgICAgICAgICAgdGhpcy5zYyA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyOwogICAgICAgICAgICB0aGlzLnNvID0gcmFuZ2Uuc3RhcnRPZmZzZXQ7CiAgICAgICAgICAgIHRoaXMuZWMgPSByYW5nZS5lbmRDb250YWluZXI7CiAgICAgICAgICAgIHRoaXMuZW8gPSByYW5nZS5lbmRPZmZzZXQ7CiAgICAgICAgICAgIHZhciByb290ID0gcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXI7CgogICAgICAgICAgICBpZiAodGhpcy5zYyA9PT0gdGhpcy5lYyAmJiBkb20uaXNDaGFyYWN0ZXJEYXRhTm9kZSh0aGlzLnNjKSkgewogICAgICAgICAgICAgICAgdGhpcy5pc1NpbmdsZUNoYXJhY3RlckRhdGFOb2RlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHRoaXMuX2ZpcnN0ID0gdGhpcy5fbGFzdCA9IHRoaXMuX25leHQgPSB0aGlzLnNjOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5fZmlyc3QgPSB0aGlzLl9uZXh0ID0gKHRoaXMuc2MgPT09IHJvb3QgJiYgIWRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKHRoaXMuc2MpKSA/CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zYy5jaGlsZE5vZGVzW3RoaXMuc29dIDogZG9tLmdldENsb3Nlc3RBbmNlc3RvckluKHRoaXMuc2MsIHJvb3QsIHRydWUpOwogICAgICAgICAgICAgICAgdGhpcy5fbGFzdCA9ICh0aGlzLmVjID09PSByb290ICYmICFkb20uaXNDaGFyYWN0ZXJEYXRhTm9kZSh0aGlzLmVjKSkgPwogICAgICAgICAgICAgICAgICAgIHRoaXMuZWMuY2hpbGROb2Rlc1t0aGlzLmVvIC0gMV0gOiBkb20uZ2V0Q2xvc2VzdEFuY2VzdG9ySW4odGhpcy5lYywgcm9vdCwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgUmFuZ2VJdGVyYXRvci5wcm90b3R5cGUgPSB7CiAgICAgICAgX2N1cnJlbnQgOiBudWxsLAogICAgICAgIF9uZXh0IDogbnVsbCwKICAgICAgICBfZmlyc3QgOiBudWxsLAogICAgICAgIF9sYXN0IDogbnVsbCwKICAgICAgICBpc1NpbmdsZUNoYXJhY3RlckRhdGFOb2RlIDogZmFsc2UsCgogICAgICAgIHJlc2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLl9jdXJyZW50ID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5fbmV4dCA9IHRoaXMuX2ZpcnN0OwogICAgICAgIH0sCgogICAgICAgIGhhc05leHQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMuX25leHQ7CiAgICAgICAgfSwKCiAgICAgICAgbmV4dCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgLy8gTW92ZSB0byBuZXh0IG5vZGUKICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSB0aGlzLl9jdXJyZW50ID0gdGhpcy5fbmV4dDsKICAgICAgICAgICAgaWYgKGN1cnJlbnQpIHsKICAgICAgICAgICAgICAgIHRoaXMuX25leHQgPSAoY3VycmVudCAhPT0gdGhpcy5fbGFzdCkgPyBjdXJyZW50Lm5leHRTaWJsaW5nIDogbnVsbDsKCiAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgcGFydGlhbGx5IHNlbGVjdGVkIHRleHQgbm9kZXMKICAgICAgICAgICAgICAgIGlmIChkb20uaXNDaGFyYWN0ZXJEYXRhTm9kZShjdXJyZW50KSAmJiB0aGlzLmNsb25lUGFydGlhbGx5U2VsZWN0ZWRUZXh0Tm9kZXMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudCA9PT0gdGhpcy5lYykgewoKICAgICAgICAgICAgICAgICAgICAgICAgKGN1cnJlbnQgPSBjdXJyZW50LmNsb25lTm9kZSh0cnVlKSkuZGVsZXRlRGF0YSh0aGlzLmVvLCBjdXJyZW50Lmxlbmd0aCAtIHRoaXMuZW8pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fY3VycmVudCA9PT0gdGhpcy5zYykgewoKICAgICAgICAgICAgICAgICAgICAgICAgKGN1cnJlbnQgPSBjdXJyZW50LmNsb25lTm9kZSh0cnVlKSkuZGVsZXRlRGF0YSgwLCB0aGlzLnNvKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBjdXJyZW50OwogICAgICAgIH0sCgogICAgICAgIHJlbW92ZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSB0aGlzLl9jdXJyZW50LCBzdGFydCwgZW5kOwoKICAgICAgICAgICAgaWYgKGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKGN1cnJlbnQpICYmIChjdXJyZW50ID09PSB0aGlzLnNjIHx8IGN1cnJlbnQgPT09IHRoaXMuZWMpKSB7CiAgICAgICAgICAgICAgICBzdGFydCA9IChjdXJyZW50ID09PSB0aGlzLnNjKSA/IHRoaXMuc28gOiAwOwogICAgICAgICAgICAgICAgZW5kID0gKGN1cnJlbnQgPT09IHRoaXMuZWMpID8gdGhpcy5lbyA6IGN1cnJlbnQubGVuZ3RoOwogICAgICAgICAgICAgICAgaWYgKHN0YXJ0ICE9IGVuZCkgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnQuZGVsZXRlRGF0YShzdGFydCwgZW5kIC0gc3RhcnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGN1cnJlbnQucGFyZW50Tm9kZSkgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChjdXJyZW50KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvLyBDaGVja3MgaWYgdGhlIGN1cnJlbnQgbm9kZSBpcyBwYXJ0aWFsbHkgc2VsZWN0ZWQKICAgICAgICBpc1BhcnRpYWxseVNlbGVjdGVkU3VidHJlZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSB0aGlzLl9jdXJyZW50OwogICAgICAgICAgICByZXR1cm4gaXNOb25UZXh0UGFydGlhbGx5U2VsZWN0ZWQoY3VycmVudCwgdGhpcy5yYW5nZSk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0U3VidHJlZUl0ZXJhdG9yIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgc3ViUmFuZ2U7CiAgICAgICAgICAgIGlmICh0aGlzLmlzU2luZ2xlQ2hhcmFjdGVyRGF0YU5vZGUpIHsKICAgICAgICAgICAgICAgIHN1YlJhbmdlID0gdGhpcy5yYW5nZS5jbG9uZVJhbmdlKCk7CiAgICAgICAgICAgICAgICBzdWJSYW5nZS5jb2xsYXBzZSgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc3ViUmFuZ2UgPSBuZXcgUmFuZ2UoZ2V0UmFuZ2VEb2N1bWVudCh0aGlzLnJhbmdlKSk7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudCA9IHRoaXMuX2N1cnJlbnQ7CiAgICAgICAgICAgICAgICB2YXIgc3RhcnRDb250YWluZXIgPSBjdXJyZW50LCBzdGFydE9mZnNldCA9IDAsIGVuZENvbnRhaW5lciA9IGN1cnJlbnQsCiAgICAgICAgICAgICAgICAgICAgZW5kT2Zmc2V0ID0gZG9tLmdldE5vZGVMZW5ndGgoY3VycmVudCk7CgogICAgICAgICAgICAgICAgaWYgKGRvbS5pc0FuY2VzdG9yT2YoY3VycmVudCwgdGhpcy5zYywgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICBzdGFydENvbnRhaW5lciA9IHRoaXMuc2M7CiAgICAgICAgICAgICAgICAgICAgc3RhcnRPZmZzZXQgPSB0aGlzLnNvOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGRvbS5pc0FuY2VzdG9yT2YoY3VycmVudCwgdGhpcy5lYywgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICBlbmRDb250YWluZXIgPSB0aGlzLmVjOwogICAgICAgICAgICAgICAgICAgIGVuZE9mZnNldCA9IHRoaXMuZW87CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdXBkYXRlQm91bmRhcmllcyhzdWJSYW5nZSwgc3RhcnRDb250YWluZXIsIHN0YXJ0T2Zmc2V0LCBlbmRDb250YWluZXIsIGVuZE9mZnNldCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ldyBSYW5nZUl0ZXJhdG9yKHN1YlJhbmdlLCB0aGlzLmNsb25lUGFydGlhbGx5U2VsZWN0ZWRUZXh0Tm9kZXMpOwogICAgICAgIH0sCgogICAgICAgIGRldGFjaCA6IGZ1bmN0aW9uIChkZXRhY2hSYW5nZSkgewogICAgICAgICAgICBpZiAoZGV0YWNoUmFuZ2UpIHsKICAgICAgICAgICAgICAgIHRoaXMucmFuZ2UuZGV0YWNoKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5yYW5nZSA9IHRoaXMuX2N1cnJlbnQgPSB0aGlzLl9uZXh0ID0gdGhpcy5fZmlyc3QgPSB0aGlzLl9sYXN0ID0gdGhpcy5zYyA9IHRoaXMuc28gPSB0aGlzLmVjID0gdGhpcy5lbyA9IG51bGw7CiAgICAgICAgfQogICAgfTsKCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8vIEV4Y2VwdGlvbnMKCiAgICAvKioKICAgICAqIEBjb25zdHJ1Y3RvcgogICAgICovCiAgICBmdW5jdGlvbiBSYW5nZUV4Y2VwdGlvbihjb2RlTmFtZSkgewogICAgICAgIHRoaXMuY29kZSA9IHRoaXNbY29kZU5hbWVdOwogICAgICAgIHRoaXMuY29kZU5hbWUgPSBjb2RlTmFtZTsKICAgICAgICB0aGlzLm1lc3NhZ2UgPSAiUmFuZ2VFeGNlcHRpb246ICIgKyB0aGlzLmNvZGVOYW1lOwogICAgfQoKICAgIFJhbmdlRXhjZXB0aW9uLnByb3RvdHlwZSA9IHsKICAgICAgICBCQURfQk9VTkRBUllQT0lOVFNfRVJSIDogMSwKICAgICAgICBJTlZBTElEX05PREVfVFlQRV9FUlIgOiAyCiAgICB9OwoKICAgIFJhbmdlRXhjZXB0aW9uLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gdGhpcy5tZXNzYWdlOwogICAgfTsKCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8qKgogICAgICogQ3VycmVudGx5IGl0ZXJhdGVzIHRocm91Z2ggYWxsIG5vZGVzIGluIHRoZSByYW5nZSBvbiBjcmVhdGlvbiB1bnRpbCBJIHRoaW5rIG9mIGEgZGVjZW50IHdheSB0byBkbyBpdAogICAgICogVE9ETzogTG9vayBpbnRvIG1ha2luZyB0aGlzIGEgcHJvcGVyIGl0ZXJhdG9yLCBub3QgcmVxdWlyaW5nIHByZWxvYWRpbmcgZXZlcnl0aGluZyBmaXJzdAogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKi8KICAgIGZ1bmN0aW9uIFJhbmdlTm9kZUl0ZXJhdG9yKHJhbmdlLCBub2RlVHlwZXMsIGZpbHRlcikgewogICAgICAgIHRoaXMubm9kZXMgPSBnZXROb2Rlc0luUmFuZ2UocmFuZ2UsIG5vZGVUeXBlcywgZmlsdGVyKTsKICAgICAgICB0aGlzLl9uZXh0ID0gdGhpcy5ub2Rlc1swXTsKICAgICAgICB0aGlzLl9wb3NpdGlvbiA9IDA7CiAgICB9CgogICAgUmFuZ2VOb2RlSXRlcmF0b3IucHJvdG90eXBlID0gewogICAgICAgIF9jdXJyZW50IDogbnVsbCwKCiAgICAgICAgaGFzTmV4dCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICEhdGhpcy5fbmV4dDsKICAgICAgICB9LAoKICAgICAgICBuZXh0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLl9jdXJyZW50ID0gdGhpcy5fbmV4dDsKICAgICAgICAgICAgdGhpcy5fbmV4dCA9IHRoaXMubm9kZXNbKyt0aGlzLl9wb3NpdGlvbl07CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jdXJyZW50OwogICAgICAgIH0sCgogICAgICAgIGRldGFjaCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdGhpcy5fY3VycmVudCA9IHRoaXMuX25leHQgPSB0aGlzLm5vZGVzID0gbnVsbDsKICAgICAgICB9CiAgICB9OwoKICAgIHZhciBiZWZvcmVBZnRlck5vZGVUeXBlcyA9IFsxLCAzLCA0LCA1LCA3LCA4LCAxMF07CiAgICB2YXIgcm9vdENvbnRhaW5lck5vZGVUeXBlcyA9IFsyLCA5LCAxMV07CiAgICB2YXIgcmVhZG9ubHlOb2RlVHlwZXMgPSBbNSwgNiwgMTAsIDEyXTsKICAgIHZhciBpbnNlcnRhYmxlTm9kZVR5cGVzID0gWzEsIDMsIDQsIDUsIDcsIDgsIDEwLCAxMV07CiAgICB2YXIgc3Vycm91bmROb2RlVHlwZXMgPSBbMSwgMywgNCwgNSwgNywgOF07CgogICAgZnVuY3Rpb24gY3JlYXRlQW5jZXN0b3JGaW5kZXIobm9kZVR5cGVzKSB7CiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChub2RlLCBzZWxmSXNBbmNlc3RvcikgewogICAgICAgICAgICB2YXIgdCwgbiA9IHNlbGZJc0FuY2VzdG9yID8gbm9kZSA6IG5vZGUucGFyZW50Tm9kZTsKICAgICAgICAgICAgd2hpbGUgKG4pIHsKICAgICAgICAgICAgICAgIHQgPSBuLm5vZGVUeXBlOwogICAgICAgICAgICAgICAgaWYgKGRvbS5hcnJheUNvbnRhaW5zKG5vZGVUeXBlcywgdCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG4gPSBuLnBhcmVudE5vZGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKICAgIH0KCiAgICB2YXIgZ2V0Um9vdENvbnRhaW5lciA9IGRvbS5nZXRSb290Q29udGFpbmVyOwogICAgdmFyIGdldERvY3VtZW50T3JGcmFnbWVudENvbnRhaW5lciA9IGNyZWF0ZUFuY2VzdG9yRmluZGVyKFs5LCAxMV0pOwogICAgdmFyIGdldFJlYWRvbmx5QW5jZXN0b3IgPSBjcmVhdGVBbmNlc3RvckZpbmRlcihyZWFkb25seU5vZGVUeXBlcyk7CiAgICB2YXIgZ2V0RG9jVHlwZU5vdGF0aW9uRW50aXR5QW5jZXN0b3IgPSBjcmVhdGVBbmNlc3RvckZpbmRlcihbNiwgMTAsIDEyXSk7CgogICAgZnVuY3Rpb24gYXNzZXJ0Tm9Eb2NUeXBlTm90YXRpb25FbnRpdHlBbmNlc3Rvcihub2RlLCBhbGxvd1NlbGYpIHsKICAgICAgICBpZiAoZ2V0RG9jVHlwZU5vdGF0aW9uRW50aXR5QW5jZXN0b3Iobm9kZSwgYWxsb3dTZWxmKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFeGNlcHRpb24oIklOVkFMSURfTk9ERV9UWVBFX0VSUiIpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBhc3NlcnROb3REZXRhY2hlZChyYW5nZSkgewogICAgICAgIGlmICghcmFuZ2Uuc3RhcnRDb250YWluZXIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigiSU5WQUxJRF9TVEFURV9FUlIiKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gYXNzZXJ0VmFsaWROb2RlVHlwZShub2RlLCBpbnZhbGlkVHlwZXMpIHsKICAgICAgICBpZiAoIWRvbS5hcnJheUNvbnRhaW5zKGludmFsaWRUeXBlcywgbm9kZS5ub2RlVHlwZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXhjZXB0aW9uKCJJTlZBTElEX05PREVfVFlQRV9FUlIiKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gYXNzZXJ0VmFsaWRPZmZzZXQobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gKGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKG5vZGUpID8gbm9kZS5sZW5ndGggOiBub2RlLmNoaWxkTm9kZXMubGVuZ3RoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKCJJTkRFWF9TSVpFX0VSUiIpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBhc3NlcnRTYW1lRG9jdW1lbnRPckZyYWdtZW50KG5vZGUxLCBub2RlMikgewogICAgICAgIGlmIChnZXREb2N1bWVudE9yRnJhZ21lbnRDb250YWluZXIobm9kZTEsIHRydWUpICE9PSBnZXREb2N1bWVudE9yRnJhZ21lbnRDb250YWluZXIobm9kZTIsIHRydWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIldST05HX0RPQ1VNRU5UX0VSUiIpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBhc3NlcnROb2RlTm90UmVhZE9ubHkobm9kZSkgewogICAgICAgIGlmIChnZXRSZWFkb25seUFuY2VzdG9yKG5vZGUsIHRydWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBhc3NlcnROb2RlKG5vZGUsIGNvZGVOYW1lKSB7CiAgICAgICAgaWYgKCFub2RlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oY29kZU5hbWUpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBpc09ycGhhbihub2RlKSB7CiAgICAgICAgcmV0dXJuICFkb20uYXJyYXlDb250YWlucyhyb290Q29udGFpbmVyTm9kZVR5cGVzLCBub2RlLm5vZGVUeXBlKSAmJiAhZ2V0RG9jdW1lbnRPckZyYWdtZW50Q29udGFpbmVyKG5vZGUsIHRydWUpOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzVmFsaWRPZmZzZXQobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgcmV0dXJuIG9mZnNldCA8PSAoZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUobm9kZSkgPyBub2RlLmxlbmd0aCA6IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGgpOwogICAgfQoKICAgIGZ1bmN0aW9uIGFzc2VydFJhbmdlVmFsaWQocmFuZ2UpIHsKICAgICAgICBhc3NlcnROb3REZXRhY2hlZChyYW5nZSk7CiAgICAgICAgaWYgKGlzT3JwaGFuKHJhbmdlLnN0YXJ0Q29udGFpbmVyKSB8fCBpc09ycGhhbihyYW5nZS5lbmRDb250YWluZXIpIHx8ICFpc1ZhbGlkT2Zmc2V0KHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydE9mZnNldCkgfHwgIWlzVmFsaWRPZmZzZXQocmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiUmFuZ2UgZXJyb3I6IFJhbmdlIGlzIG5vIGxvbmdlciB2YWxpZCBhZnRlciBET00gbXV0YXRpb24gKCIgKyByYW5nZS5pbnNwZWN0KCkgKyAiKSIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8vIFRlc3QgdGhlIGJyb3dzZXIncyBpbm5lckhUTUwgc3VwcG9ydCB0byBkZWNpZGUgaG93IHRvIGltcGxlbWVudCBjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQKICAgIHZhciBzdHlsZUVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3R5bGUiKTsKICAgIHZhciBodG1sUGFyc2luZ0NvbmZvcm1zID0gZmFsc2U7CiAgICB0cnkgewogICAgICAgIHN0eWxlRWwuaW5uZXJIVE1MID0gIjxiPng8L2I+IjsKICAgICAgICBodG1sUGFyc2luZ0NvbmZvcm1zID0gKHN0eWxlRWwuZmlyc3RDaGlsZC5ub2RlVHlwZSA9PSAzKTsgLy8gT3BlcmEgaW5jb3JyZWN0bHkgY3JlYXRlcyBhbiBlbGVtZW50IG5vZGUKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAvLyBJRSA2IGFuZCA3IHRocm93CiAgICB9CgogICAgYXBpLmZlYXR1cmVzLmh0bWxQYXJzaW5nQ29uZm9ybXMgPSBodG1sUGFyc2luZ0NvbmZvcm1zOwoKICAgIHZhciBjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQgPSBodG1sUGFyc2luZ0NvbmZvcm1zID8KCiAgICAgICAgLy8gSW1wbGVtZW50YXRpb24gYXMgcGVyIEhUTUwgcGFyc2luZyBzcGVjLCB0cnVzdGluZyBpbiB0aGUgYnJvd3NlcidzIGltcGxlbWVudGF0aW9uIG9mIGlubmVySFRNTC4gU2VlCiAgICAgICAgLy8gZGlzY3Vzc2lvbiBhbmQgYmFzZSBjb2RlIGZvciB0aGlzIGltcGxlbWVudGF0aW9uIGF0IGlzc3VlIDY3LgogICAgICAgIC8vIFNwZWM6IGh0dHA6Ly9odG1sNS5vcmcvc3BlY3MvZG9tLXBhcnNpbmcuaHRtbCNleHRlbnNpb25zLXRvLXRoZS1yYW5nZS1pbnRlcmZhY2UKICAgICAgICAvLyBUaGFua3MgdG8gQWxla3MgV2lsbGlhbXMuCiAgICAgICAgZnVuY3Rpb24gKGZyYWdtZW50U3RyKSB7CiAgICAgICAgICAgIC8vICJMZXQgbm9kZSB0aGUgY29udGV4dCBvYmplY3QncyBzdGFydCdzIG5vZGUuIgogICAgICAgICAgICB2YXIgbm9kZSA9IHRoaXMuc3RhcnRDb250YWluZXI7CiAgICAgICAgICAgIHZhciBkb2MgPSBkb20uZ2V0RG9jdW1lbnQobm9kZSk7CgogICAgICAgICAgICAvLyAiSWYgdGhlIGNvbnRleHQgb2JqZWN0J3Mgc3RhcnQncyBub2RlIGlzIG51bGwsIHJhaXNlIGFuIElOVkFMSURfU1RBVEVfRVJSCiAgICAgICAgICAgIC8vIGV4Y2VwdGlvbiBhbmQgYWJvcnQgdGhlc2Ugc3RlcHMuIgogICAgICAgICAgICBpZiAoIW5vZGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIklOVkFMSURfU1RBVEVfRVJSIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vICJMZXQgZWxlbWVudCBiZSBhcyBmb2xsb3dzLCBkZXBlbmRpbmcgb24gbm9kZSdzIGludGVyZmFjZToiCiAgICAgICAgICAgIC8vIERvY3VtZW50LCBEb2N1bWVudCBGcmFnbWVudDogbnVsbAogICAgICAgICAgICB2YXIgZWwgPSBudWxsOwoKICAgICAgICAgICAgLy8gIkVsZW1lbnQ6IG5vZGUiCiAgICAgICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDEpIHsKICAgICAgICAgICAgICAgIGVsID0gbm9kZTsKCiAgICAgICAgICAgICAgICAvLyAiVGV4dCwgQ29tbWVudDogbm9kZSdzIHBhcmVudEVsZW1lbnQiCiAgICAgICAgICAgIH0gZWxzZSBpZiAoZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUobm9kZSkpIHsKICAgICAgICAgICAgICAgIGVsID0gZG9tLnBhcmVudEVsZW1lbnQobm9kZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vICJJZiBlaXRoZXIgZWxlbWVudCBpcyBudWxsIG9yIGVsZW1lbnQncyBvd25lckRvY3VtZW50IGlzIGFuIEhUTUwgZG9jdW1lbnQKICAgICAgICAgICAgLy8gYW5kIGVsZW1lbnQncyBsb2NhbCBuYW1lIGlzICJodG1sIiBhbmQgZWxlbWVudCdzIG5hbWVzcGFjZSBpcyB0aGUgSFRNTAogICAgICAgICAgICAvLyBuYW1lc3BhY2UiCiAgICAgICAgICAgIGlmIChlbCA9PT0gbnVsbCB8fCAoCiAgICAgICAgICAgICAgICAgICAgZWwubm9kZU5hbWUgPT0gIkhUTUwiICYmIGRvbS5pc0h0bWxOYW1lc3BhY2UoZG9tLmdldERvY3VtZW50KGVsKS5kb2N1bWVudEVsZW1lbnQpICYmIGRvbS5pc0h0bWxOYW1lc3BhY2UoZWwpCiAgICAgICAgICAgICAgICApKSB7CgogICAgICAgICAgICAgICAgLy8gImxldCBlbGVtZW50IGJlIGEgbmV3IEVsZW1lbnQgd2l0aCAiYm9keSIgYXMgaXRzIGxvY2FsIG5hbWUgYW5kIHRoZSBIVE1MCiAgICAgICAgICAgICAgICAvLyBuYW1lc3BhY2UgYXMgaXRzIG5hbWVzcGFjZS4iIgogICAgICAgICAgICAgICAgZWwgPSBkb2MuY3JlYXRlRWxlbWVudCgiYm9keSIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZWwgPSBlbC5jbG9uZU5vZGUoZmFsc2UpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyAiSWYgdGhlIG5vZGUncyBkb2N1bWVudCBpcyBhbiBIVE1MIGRvY3VtZW50OiBJbnZva2UgdGhlIEhUTUwgZnJhZ21lbnQgcGFyc2luZyBhbGdvcml0aG0uIgogICAgICAgICAgICAvLyAiSWYgdGhlIG5vZGUncyBkb2N1bWVudCBpcyBhbiBYTUwgZG9jdW1lbnQ6IEludm9rZSB0aGUgWE1MIGZyYWdtZW50IHBhcnNpbmcgYWxnb3JpdGhtLiIKICAgICAgICAgICAgLy8gIkluIGVpdGhlciBjYXNlLCB0aGUgYWxnb3JpdGhtIG11c3QgYmUgaW52b2tlZCB3aXRoIGZyYWdtZW50IGFzIHRoZSBpbnB1dAogICAgICAgICAgICAvLyBhbmQgZWxlbWVudCBhcyB0aGUgY29udGV4dCBlbGVtZW50LiIKICAgICAgICAgICAgZWwuaW5uZXJIVE1MID0gZnJhZ21lbnRTdHI7CgogICAgICAgICAgICAvLyAiSWYgdGhpcyByYWlzZXMgYW4gZXhjZXB0aW9uLCB0aGVuIGFib3J0IHRoZXNlIHN0ZXBzLiBPdGhlcndpc2UsIGxldCBuZXcKICAgICAgICAgICAgLy8gY2hpbGRyZW4gYmUgdGhlIG5vZGVzIHJldHVybmVkLiIKCiAgICAgICAgICAgIC8vICJMZXQgZnJhZ21lbnQgYmUgYSBuZXcgRG9jdW1lbnRGcmFnbWVudC4iCiAgICAgICAgICAgIC8vICJBcHBlbmQgYWxsIG5ldyBjaGlsZHJlbiB0byBmcmFnbWVudC4iCiAgICAgICAgICAgIC8vICJSZXR1cm4gZnJhZ21lbnQuIgogICAgICAgICAgICByZXR1cm4gZG9tLmZyYWdtZW50RnJvbU5vZGVDaGlsZHJlbihlbCk7CiAgICAgICAgfSA6CgogICAgICAgIC8vIEluIHRoaXMgY2FzZSwgaW5uZXJIVE1MIGNhbm5vdCBiZSB0cnVzdGVkLCBzbyBmYWxsIGJhY2sgdG8gYSBzaW1wbGVyLCBub24tY29uZm9ybWFudCBpbXBsZW1lbnRhdGlvbiB0aGF0CiAgICAgICAgLy8gcHJldmlvdXMgdmVyc2lvbnMgb2YgUmFuZ3kgdXNlZCAod2l0aCB0aGUgZXhjZXB0aW9uIG9mIHVzaW5nIGEgYm9keSBlbGVtZW50IHJhdGhlciB0aGFuIGEgZGl2KQogICAgICAgIGZ1bmN0aW9uIChmcmFnbWVudFN0cikgewogICAgICAgICAgICBhc3NlcnROb3REZXRhY2hlZCh0aGlzKTsKICAgICAgICAgICAgdmFyIGRvYyA9IGdldFJhbmdlRG9jdW1lbnQodGhpcyk7CiAgICAgICAgICAgIHZhciBlbCA9IGRvYy5jcmVhdGVFbGVtZW50KCJib2R5Iik7CiAgICAgICAgICAgIGVsLmlubmVySFRNTCA9IGZyYWdtZW50U3RyOwoKICAgICAgICAgICAgcmV0dXJuIGRvbS5mcmFnbWVudEZyb21Ob2RlQ2hpbGRyZW4oZWwpOwogICAgICAgIH07CgogICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCiAgICB2YXIgcmFuZ2VQcm9wZXJ0aWVzID0gWyJzdGFydENvbnRhaW5lciIsICJzdGFydE9mZnNldCIsICJlbmRDb250YWluZXIiLCAiZW5kT2Zmc2V0IiwgImNvbGxhcHNlZCIsCiAgICAgICAgImNvbW1vbkFuY2VzdG9yQ29udGFpbmVyIl07CgogICAgdmFyIHMycyA9IDAsIHMyZSA9IDEsIGUyZSA9IDIsIGUycyA9IDM7CiAgICB2YXIgbl9iID0gMCwgbl9hID0gMSwgbl9iX2EgPSAyLCBuX2kgPSAzOwoKICAgIGZ1bmN0aW9uIFJhbmdlUHJvdG90eXBlKCkgewogICAgfQoKICAgIFJhbmdlUHJvdG90eXBlLnByb3RvdHlwZSA9IHsKICAgICAgICBhdHRhY2hMaXN0ZW5lciA6IGZ1bmN0aW9uICh0eXBlLCBsaXN0ZW5lcikgewogICAgICAgICAgICB0aGlzLl9saXN0ZW5lcnNbdHlwZV0ucHVzaChsaXN0ZW5lcik7CiAgICAgICAgfSwKCiAgICAgICAgY29tcGFyZUJvdW5kYXJ5UG9pbnRzIDogZnVuY3Rpb24gKGhvdywgcmFuZ2UpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgYXNzZXJ0U2FtZURvY3VtZW50T3JGcmFnbWVudCh0aGlzLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydENvbnRhaW5lcik7CgogICAgICAgICAgICB2YXIgbm9kZUEsIG9mZnNldEEsIG5vZGVCLCBvZmZzZXRCOwogICAgICAgICAgICB2YXIgcHJlZml4QSA9IChob3cgPT0gZTJzIHx8IGhvdyA9PSBzMnMpID8gInN0YXJ0IiA6ICJlbmQiOwogICAgICAgICAgICB2YXIgcHJlZml4QiA9IChob3cgPT0gczJlIHx8IGhvdyA9PSBzMnMpID8gInN0YXJ0IiA6ICJlbmQiOwogICAgICAgICAgICBub2RlQSA9IHRoaXNbcHJlZml4QSArICJDb250YWluZXIiXTsKICAgICAgICAgICAgb2Zmc2V0QSA9IHRoaXNbcHJlZml4QSArICJPZmZzZXQiXTsKICAgICAgICAgICAgbm9kZUIgPSByYW5nZVtwcmVmaXhCICsgIkNvbnRhaW5lciJdOwogICAgICAgICAgICBvZmZzZXRCID0gcmFuZ2VbcHJlZml4QiArICJPZmZzZXQiXTsKICAgICAgICAgICAgcmV0dXJuIGRvbS5jb21wYXJlUG9pbnRzKG5vZGVBLCBvZmZzZXRBLCBub2RlQiwgb2Zmc2V0Qik7CiAgICAgICAgfSwKCiAgICAgICAgaW5zZXJ0Tm9kZSA6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgIGFzc2VydFJhbmdlVmFsaWQodGhpcyk7CiAgICAgICAgICAgIGFzc2VydFZhbGlkTm9kZVR5cGUobm9kZSwgaW5zZXJ0YWJsZU5vZGVUeXBlcyk7CiAgICAgICAgICAgIGFzc2VydE5vZGVOb3RSZWFkT25seSh0aGlzLnN0YXJ0Q29udGFpbmVyKTsKCiAgICAgICAgICAgIGlmIChkb20uaXNBbmNlc3Rvck9mKG5vZGUsIHRoaXMuc3RhcnRDb250YWluZXIsIHRydWUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKCJISUVSQVJDSFlfUkVRVUVTVF9FUlIiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gTm8gY2hlY2sgZm9yIHdoZXRoZXIgdGhlIGNvbnRhaW5lciBvZiB0aGUgc3RhcnQgb2YgdGhlIFJhbmdlIGlzIG9mIGEgdHlwZSB0aGF0IGRvZXMgbm90IGFsbG93CiAgICAgICAgICAgIC8vIGNoaWxkcmVuIG9mIHRoZSB0eXBlIG9mIG5vZGU6IHRoZSBicm93c2VyJ3MgRE9NIGltcGxlbWVudGF0aW9uIHNob3VsZCBkbyB0aGlzIGZvciB1cyB3aGVuIHdlIGF0dGVtcHQKICAgICAgICAgICAgLy8gdG8gYWRkIHRoZSBub2RlCgogICAgICAgICAgICB2YXIgZmlyc3ROb2RlSW5zZXJ0ZWQgPSBpbnNlcnROb2RlQXRQb3NpdGlvbihub2RlLCB0aGlzLnN0YXJ0Q29udGFpbmVyLCB0aGlzLnN0YXJ0T2Zmc2V0KTsKICAgICAgICAgICAgdGhpcy5zZXRTdGFydEJlZm9yZShmaXJzdE5vZGVJbnNlcnRlZCk7CiAgICAgICAgfSwKCiAgICAgICAgY2xvbmVDb250ZW50cyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKCiAgICAgICAgICAgIHZhciBjbG9uZSwgZnJhZzsKICAgICAgICAgICAgaWYgKHRoaXMuY29sbGFwc2VkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0UmFuZ2VEb2N1bWVudCh0aGlzKS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGFydENvbnRhaW5lciA9PT0gdGhpcy5lbmRDb250YWluZXIgJiYgZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUodGhpcy5zdGFydENvbnRhaW5lcikpIHsKICAgICAgICAgICAgICAgICAgICBjbG9uZSA9IHRoaXMuc3RhcnRDb250YWluZXIuY2xvbmVOb2RlKHRydWUpOwogICAgICAgICAgICAgICAgICAgIGNsb25lLmRhdGEgPSBjbG9uZS5kYXRhLnNsaWNlKHRoaXMuc3RhcnRPZmZzZXQsIHRoaXMuZW5kT2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICBmcmFnID0gZ2V0UmFuZ2VEb2N1bWVudCh0aGlzKS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CiAgICAgICAgICAgICAgICAgICAgZnJhZy5hcHBlbmRDaGlsZChjbG9uZSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZyYWc7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHZhciBpdGVyYXRvciA9IG5ldyBSYW5nZUl0ZXJhdG9yKHRoaXMsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIGNsb25lID0gY2xvbmVTdWJ0cmVlKGl0ZXJhdG9yKTsKICAgICAgICAgICAgICAgICAgICBpdGVyYXRvci5kZXRhY2goKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBjbG9uZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNhblN1cnJvdW5kQ29udGVudHMgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGFzc2VydFJhbmdlVmFsaWQodGhpcyk7CiAgICAgICAgICAgIGFzc2VydE5vZGVOb3RSZWFkT25seSh0aGlzLnN0YXJ0Q29udGFpbmVyKTsKICAgICAgICAgICAgYXNzZXJ0Tm9kZU5vdFJlYWRPbmx5KHRoaXMuZW5kQ29udGFpbmVyKTsKCiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBjb250ZW50cyBjYW4gYmUgc3Vycm91bmRlZC4gU3BlY2lmaWNhbGx5LCB0aGlzIG1lYW5zIHdoZXRoZXIgdGhlIHJhbmdlIHBhcnRpYWxseSBzZWxlY3RzCiAgICAgICAgICAgIC8vIG5vIG5vbi10ZXh0IG5vZGVzLgogICAgICAgICAgICB2YXIgaXRlcmF0b3IgPSBuZXcgUmFuZ2VJdGVyYXRvcih0aGlzLCB0cnVlKTsKICAgICAgICAgICAgdmFyIGJvdW5kYXJpZXNJbnZhbGlkID0gKGl0ZXJhdG9yLl9maXJzdCAmJiAoaXNOb25UZXh0UGFydGlhbGx5U2VsZWN0ZWQoaXRlcmF0b3IuX2ZpcnN0LCB0aGlzKSkgfHwKICAgICAgICAgICAgKGl0ZXJhdG9yLl9sYXN0ICYmIGlzTm9uVGV4dFBhcnRpYWxseVNlbGVjdGVkKGl0ZXJhdG9yLl9sYXN0LCB0aGlzKSkpOwogICAgICAgICAgICBpdGVyYXRvci5kZXRhY2goKTsKICAgICAgICAgICAgcmV0dXJuICFib3VuZGFyaWVzSW52YWxpZDsKICAgICAgICB9LAoKICAgICAgICBzdXJyb3VuZENvbnRlbnRzIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgYXNzZXJ0VmFsaWROb2RlVHlwZShub2RlLCBzdXJyb3VuZE5vZGVUeXBlcyk7CgogICAgICAgICAgICBpZiAoIXRoaXMuY2FuU3Vycm91bmRDb250ZW50cygpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFeGNlcHRpb24oIkJBRF9CT1VOREFSWVBPSU5UU19FUlIiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gRXh0cmFjdCB0aGUgY29udGVudHMKICAgICAgICAgICAgdmFyIGNvbnRlbnQgPSB0aGlzLmV4dHJhY3RDb250ZW50cygpOwoKICAgICAgICAgICAgLy8gQ2xlYXIgdGhlIGNoaWxkcmVuIG9mIHRoZSBub2RlCiAgICAgICAgICAgIGlmIChub2RlLmhhc0NoaWxkTm9kZXMoKSkgewogICAgICAgICAgICAgICAgd2hpbGUgKG5vZGUubGFzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgbm9kZS5yZW1vdmVDaGlsZChub2RlLmxhc3RDaGlsZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEluc2VydCB0aGUgbmV3IG5vZGUgYW5kIGFkZCB0aGUgZXh0cmFjdGVkIGNvbnRlbnRzCiAgICAgICAgICAgIGluc2VydE5vZGVBdFBvc2l0aW9uKG5vZGUsIHRoaXMuc3RhcnRDb250YWluZXIsIHRoaXMuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICBub2RlLmFwcGVuZENoaWxkKGNvbnRlbnQpOwoKICAgICAgICAgICAgdGhpcy5zZWxlY3ROb2RlKG5vZGUpOwogICAgICAgIH0sCgogICAgICAgIGNsb25lUmFuZ2UgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGFzc2VydFJhbmdlVmFsaWQodGhpcyk7CiAgICAgICAgICAgIHZhciByYW5nZSA9IG5ldyBSYW5nZShnZXRSYW5nZURvY3VtZW50KHRoaXMpKTsKICAgICAgICAgICAgdmFyIGkgPSByYW5nZVByb3BlcnRpZXMubGVuZ3RoLCBwcm9wOwogICAgICAgICAgICB3aGlsZSAoaS0tKSB7CiAgICAgICAgICAgICAgICBwcm9wID0gcmFuZ2VQcm9wZXJ0aWVzW2ldOwogICAgICAgICAgICAgICAgcmFuZ2VbcHJvcF0gPSB0aGlzW3Byb3BdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByYW5nZTsKICAgICAgICB9LAoKICAgICAgICB0b1N0cmluZyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgdmFyIHNjID0gdGhpcy5zdGFydENvbnRhaW5lcjsKICAgICAgICAgICAgaWYgKHNjID09PSB0aGlzLmVuZENvbnRhaW5lciAmJiBkb20uaXNDaGFyYWN0ZXJEYXRhTm9kZShzYykpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoc2Mubm9kZVR5cGUgPT0gMyB8fCBzYy5ub2RlVHlwZSA9PSA0KSA/IHNjLmRhdGEuc2xpY2UodGhpcy5zdGFydE9mZnNldCwgdGhpcy5lbmRPZmZzZXQpIDogIiI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgdGV4dEJpdHMgPSBbXSwgaXRlcmF0b3IgPSBuZXcgUmFuZ2VJdGVyYXRvcih0aGlzLCB0cnVlKTsKCiAgICAgICAgICAgICAgICBpdGVyYXRlU3VidHJlZShpdGVyYXRvciwgZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBBY2NlcHQgb25seSB0ZXh0IG9yIENEQVRBIG5vZGVzLCBub3QgY29tbWVudHMKCiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMyB8fCBub2RlLm5vZGVUeXBlID09IDQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEJpdHMucHVzaChub2RlLmRhdGEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgaXRlcmF0b3IuZGV0YWNoKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gdGV4dEJpdHMuam9pbigiIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvLyBUaGUgbWV0aG9kcyBiZWxvdyBhcmUgYWxsIG5vbi1zdGFuZGFyZC4gVGhlIGZvbGxvd2luZyBiYXRjaCB3ZXJlIGludHJvZHVjZWQgYnkgTW96aWxsYSBidXQgaGF2ZSBzaW5jZQogICAgICAgIC8vIGJlZW4gcmVtb3ZlZCBmcm9tIE1vemlsbGEuCgogICAgICAgIGNvbXBhcmVOb2RlIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKCiAgICAgICAgICAgIHZhciBwYXJlbnQgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgICAgIHZhciBub2RlSW5kZXggPSBkb20uZ2V0Tm9kZUluZGV4KG5vZGUpOwoKICAgICAgICAgICAgaWYgKCFwYXJlbnQpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIk5PVF9GT1VORF9FUlIiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHN0YXJ0Q29tcGFyaXNvbiA9IHRoaXMuY29tcGFyZVBvaW50KHBhcmVudCwgbm9kZUluZGV4KSwKICAgICAgICAgICAgICAgIGVuZENvbXBhcmlzb24gPSB0aGlzLmNvbXBhcmVQb2ludChwYXJlbnQsIG5vZGVJbmRleCArIDEpOwoKICAgICAgICAgICAgaWYgKHN0YXJ0Q29tcGFyaXNvbiA8IDApIHsvLyBOb2RlIHN0YXJ0cyBiZWZvcmUKICAgICAgICAgICAgICAgIHJldHVybiAoZW5kQ29tcGFyaXNvbiA+IDApID8gbl9iX2EgOiBuX2I7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKGVuZENvbXBhcmlzb24gPiAwKSA/IG5fYSA6IG5faTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNvbXBhcmVQb2ludCA6IGZ1bmN0aW9uIChub2RlLCBvZmZzZXQpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgYXNzZXJ0Tm9kZShub2RlLCAiSElFUkFSQ0hZX1JFUVVFU1RfRVJSIik7CiAgICAgICAgICAgIGFzc2VydFNhbWVEb2N1bWVudE9yRnJhZ21lbnQobm9kZSwgdGhpcy5zdGFydENvbnRhaW5lcik7CgogICAgICAgICAgICBpZiAoZG9tLmNvbXBhcmVQb2ludHMobm9kZSwgb2Zmc2V0LCB0aGlzLnN0YXJ0Q29udGFpbmVyLCB0aGlzLnN0YXJ0T2Zmc2V0KSA8IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfSBlbHNlIGlmIChkb20uY29tcGFyZVBvaW50cyhub2RlLCBvZmZzZXQsIHRoaXMuZW5kQ29udGFpbmVyLCB0aGlzLmVuZE9mZnNldCkgPiAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQgOiBjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQsCgogICAgICAgIHRvSHRtbCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgdmFyIGNvbnRhaW5lciA9IGdldFJhbmdlRG9jdW1lbnQodGhpcykuY3JlYXRlRWxlbWVudCgiZGl2Iik7CiAgICAgICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLmNsb25lQ29udGVudHMoKSk7CiAgICAgICAgICAgIHJldHVybiBjb250YWluZXIuaW5uZXJIVE1MOwogICAgICAgIH0sCgogICAgICAgIC8vIHRvdWNoaW5nSXNJbnRlcnNlY3RpbmcgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoaXMgbWV0aG9kIGNvbnNpZGVycyBhIG5vZGUgdGhhdCBib3JkZXJzIGEgcmFuZ2UgaW50ZXJzZWN0cwogICAgICAgIC8vIHdpdGggaXQgKGFzIGluIFdlYktpdCkgb3Igbm90IChhcyBpbiBHZWNrbyBwcmUtMS45LCBhbmQgdGhlIGRlZmF1bHQpCiAgICAgICAgaW50ZXJzZWN0c05vZGUgOiBmdW5jdGlvbiAobm9kZSwgdG91Y2hpbmdJc0ludGVyc2VjdGluZykgewogICAgICAgICAgICBhc3NlcnRSYW5nZVZhbGlkKHRoaXMpOwogICAgICAgICAgICBhc3NlcnROb2RlKG5vZGUsICJOT1RfRk9VTkRfRVJSIik7CiAgICAgICAgICAgIGlmIChkb20uZ2V0RG9jdW1lbnQobm9kZSkgIT09IGdldFJhbmdlRG9jdW1lbnQodGhpcykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHBhcmVudCA9IG5vZGUucGFyZW50Tm9kZSwgb2Zmc2V0ID0gZG9tLmdldE5vZGVJbmRleChub2RlKTsKICAgICAgICAgICAgYXNzZXJ0Tm9kZShwYXJlbnQsICJOT1RfRk9VTkRfRVJSIik7CgogICAgICAgICAgICB2YXIgc3RhcnRDb21wYXJpc29uID0gZG9tLmNvbXBhcmVQb2ludHMocGFyZW50LCBvZmZzZXQsIHRoaXMuZW5kQ29udGFpbmVyLCB0aGlzLmVuZE9mZnNldCksCiAgICAgICAgICAgICAgICBlbmRDb21wYXJpc29uID0gZG9tLmNvbXBhcmVQb2ludHMocGFyZW50LCBvZmZzZXQgKyAxLCB0aGlzLnN0YXJ0Q29udGFpbmVyLCB0aGlzLnN0YXJ0T2Zmc2V0KTsKCiAgICAgICAgICAgIHJldHVybiB0b3VjaGluZ0lzSW50ZXJzZWN0aW5nID8gc3RhcnRDb21wYXJpc29uIDw9IDAgJiYgZW5kQ29tcGFyaXNvbiA+PSAwIDogc3RhcnRDb21wYXJpc29uIDwgMCAmJiBlbmRDb21wYXJpc29uID4gMDsKICAgICAgICB9LAoKICAgICAgICBpc1BvaW50SW5SYW5nZSA6IGZ1bmN0aW9uIChub2RlLCBvZmZzZXQpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgYXNzZXJ0Tm9kZShub2RlLCAiSElFUkFSQ0hZX1JFUVVFU1RfRVJSIik7CiAgICAgICAgICAgIGFzc2VydFNhbWVEb2N1bWVudE9yRnJhZ21lbnQobm9kZSwgdGhpcy5zdGFydENvbnRhaW5lcik7CgogICAgICAgICAgICByZXR1cm4gKGRvbS5jb21wYXJlUG9pbnRzKG5vZGUsIG9mZnNldCwgdGhpcy5zdGFydENvbnRhaW5lciwgdGhpcy5zdGFydE9mZnNldCkgPj0gMCkgJiYgKGRvbS5jb21wYXJlUG9pbnRzKG5vZGUsIG9mZnNldCwgdGhpcy5lbmRDb250YWluZXIsIHRoaXMuZW5kT2Zmc2V0KSA8PSAwKTsKICAgICAgICB9LAoKICAgICAgICAvLyBUaGUgbWV0aG9kcyBiZWxvdyBhcmUgbm9uLXN0YW5kYXJkIGFuZCBpbnZlbnRlZCBieSBtZS4KCiAgICAgICAgLy8gU2hhcmluZyBhIGJvdW5kYXJ5IHN0YXJ0LXRvLWVuZCBvciBlbmQtdG8tc3RhcnQgZG9lcyBub3QgY291bnQgYXMgaW50ZXJzZWN0aW9uLgogICAgICAgIGludGVyc2VjdHNSYW5nZSA6IGZ1bmN0aW9uIChyYW5nZSwgdG91Y2hpbmdJc0ludGVyc2VjdGluZykgewogICAgICAgICAgICBhc3NlcnRSYW5nZVZhbGlkKHRoaXMpOwoKICAgICAgICAgICAgaWYgKGdldFJhbmdlRG9jdW1lbnQocmFuZ2UpICE9IGdldFJhbmdlRG9jdW1lbnQodGhpcykpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIldST05HX0RPQ1VNRU5UX0VSUiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgc3RhcnRDb21wYXJpc29uID0gZG9tLmNvbXBhcmVQb2ludHModGhpcy5zdGFydENvbnRhaW5lciwgdGhpcy5zdGFydE9mZnNldCwgcmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpLAogICAgICAgICAgICAgICAgZW5kQ29tcGFyaXNvbiA9IGRvbS5jb21wYXJlUG9pbnRzKHRoaXMuZW5kQ29udGFpbmVyLCB0aGlzLmVuZE9mZnNldCwgcmFuZ2Uuc3RhcnRDb250YWluZXIsIHJhbmdlLnN0YXJ0T2Zmc2V0KTsKCiAgICAgICAgICAgIHJldHVybiB0b3VjaGluZ0lzSW50ZXJzZWN0aW5nID8gc3RhcnRDb21wYXJpc29uIDw9IDAgJiYgZW5kQ29tcGFyaXNvbiA+PSAwIDogc3RhcnRDb21wYXJpc29uIDwgMCAmJiBlbmRDb21wYXJpc29uID4gMDsKICAgICAgICB9LAoKICAgICAgICBpbnRlcnNlY3Rpb24gOiBmdW5jdGlvbiAocmFuZ2UpIHsKICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJzZWN0c1JhbmdlKHJhbmdlKSkgewogICAgICAgICAgICAgICAgdmFyIHN0YXJ0Q29tcGFyaXNvbiA9IGRvbS5jb21wYXJlUG9pbnRzKHRoaXMuc3RhcnRDb250YWluZXIsIHRoaXMuc3RhcnRPZmZzZXQsIHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydE9mZnNldCksCiAgICAgICAgICAgICAgICAgICAgZW5kQ29tcGFyaXNvbiA9IGRvbS5jb21wYXJlUG9pbnRzKHRoaXMuZW5kQ29udGFpbmVyLCB0aGlzLmVuZE9mZnNldCwgcmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpOwoKICAgICAgICAgICAgICAgIHZhciBpbnRlcnNlY3Rpb25SYW5nZSA9IHRoaXMuY2xvbmVSYW5nZSgpOwoKICAgICAgICAgICAgICAgIGlmIChzdGFydENvbXBhcmlzb24gPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICBpbnRlcnNlY3Rpb25SYW5nZS5zZXRTdGFydChyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGVuZENvbXBhcmlzb24gPT0gMSkgewogICAgICAgICAgICAgICAgICAgIGludGVyc2VjdGlvblJhbmdlLnNldEVuZChyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gaW50ZXJzZWN0aW9uUmFuZ2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgdW5pb24gOiBmdW5jdGlvbiAocmFuZ2UpIHsKICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJzZWN0c1JhbmdlKHJhbmdlLCB0cnVlKSkgewogICAgICAgICAgICAgICAgdmFyIHVuaW9uUmFuZ2UgPSB0aGlzLmNsb25lUmFuZ2UoKTsKICAgICAgICAgICAgICAgIGlmIChkb20uY29tcGFyZVBvaW50cyhyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQsIHRoaXMuc3RhcnRDb250YWluZXIsIHRoaXMuc3RhcnRPZmZzZXQpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgdW5pb25SYW5nZS5zZXRTdGFydChyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGRvbS5jb21wYXJlUG9pbnRzKHJhbmdlLmVuZENvbnRhaW5lciwgcmFuZ2UuZW5kT2Zmc2V0LCB0aGlzLmVuZENvbnRhaW5lciwgdGhpcy5lbmRPZmZzZXQpID09IDEpIHsKICAgICAgICAgICAgICAgICAgICB1bmlvblJhbmdlLnNldEVuZChyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gdW5pb25SYW5nZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUV4Y2VwdGlvbigiUmFuZ2VzIGRvIG5vdCBpbnRlcnNlY3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNvbnRhaW5zTm9kZSA6IGZ1bmN0aW9uIChub2RlLCBhbGxvd1BhcnRpYWwpIHsKICAgICAgICAgICAgaWYgKGFsbG93UGFydGlhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJzZWN0c05vZGUobm9kZSwgZmFsc2UpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZU5vZGUobm9kZSkgPT0gbl9pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgY29udGFpbnNOb2RlQ29udGVudHMgOiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5jb21wYXJlUG9pbnQobm9kZSwgMCkgPj0gMCAmJiB0aGlzLmNvbXBhcmVQb2ludChub2RlLCBkb20uZ2V0Tm9kZUxlbmd0aChub2RlKSkgPD0gMDsKICAgICAgICB9LAoKICAgICAgICBjb250YWluc1JhbmdlIDogZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmludGVyc2VjdGlvbihyYW5nZSkuZXF1YWxzKHJhbmdlKTsKICAgICAgICB9LAoKICAgICAgICBjb250YWluc05vZGVUZXh0IDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgdmFyIG5vZGVSYW5nZSA9IHRoaXMuY2xvbmVSYW5nZSgpOwogICAgICAgICAgICBub2RlUmFuZ2Uuc2VsZWN0Tm9kZShub2RlKTsKICAgICAgICAgICAgdmFyIHRleHROb2RlcyA9IG5vZGVSYW5nZS5nZXROb2RlcyhbM10pOwogICAgICAgICAgICBpZiAodGV4dE5vZGVzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIG5vZGVSYW5nZS5zZXRTdGFydCh0ZXh0Tm9kZXNbMF0sIDApOwogICAgICAgICAgICAgICAgdmFyIGxhc3RUZXh0Tm9kZSA9IHRleHROb2Rlcy5wb3AoKTsKICAgICAgICAgICAgICAgIG5vZGVSYW5nZS5zZXRFbmQobGFzdFRleHROb2RlLCBsYXN0VGV4dE5vZGUubGVuZ3RoKTsKICAgICAgICAgICAgICAgIHZhciBjb250YWlucyA9IHRoaXMuY29udGFpbnNSYW5nZShub2RlUmFuZ2UpOwogICAgICAgICAgICAgICAgbm9kZVJhbmdlLmRldGFjaCgpOwogICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRhaW5zOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGFpbnNOb2RlQ29udGVudHMobm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBjcmVhdGVOb2RlSXRlcmF0b3IgOiBmdW5jdGlvbiAobm9kZVR5cGVzLCBmaWx0ZXIpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSYW5nZU5vZGVJdGVyYXRvcih0aGlzLCBub2RlVHlwZXMsIGZpbHRlcik7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0Tm9kZXMgOiBmdW5jdGlvbiAobm9kZVR5cGVzLCBmaWx0ZXIpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgcmV0dXJuIGdldE5vZGVzSW5SYW5nZSh0aGlzLCBub2RlVHlwZXMsIGZpbHRlcik7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RG9jdW1lbnQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBnZXRSYW5nZURvY3VtZW50KHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIGNvbGxhcHNlQmVmb3JlIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgYXNzZXJ0Tm90RGV0YWNoZWQodGhpcyk7CgogICAgICAgICAgICB0aGlzLnNldEVuZEJlZm9yZShub2RlKTsKICAgICAgICAgICAgdGhpcy5jb2xsYXBzZShmYWxzZSk7CiAgICAgICAgfSwKCiAgICAgICAgY29sbGFwc2VBZnRlciA6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgIGFzc2VydE5vdERldGFjaGVkKHRoaXMpOwoKICAgICAgICAgICAgdGhpcy5zZXRTdGFydEFmdGVyKG5vZGUpOwogICAgICAgICAgICB0aGlzLmNvbGxhcHNlKHRydWUpOwogICAgICAgIH0sCgogICAgICAgIGdldE5hbWUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAiRG9tUmFuZ2UiOwogICAgICAgIH0sCgogICAgICAgIGVxdWFscyA6IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgICAgICByZXR1cm4gUmFuZ2UucmFuZ2VzRXF1YWwodGhpcywgcmFuZ2UpOwogICAgICAgIH0sCgogICAgICAgIGluc3BlY3QgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0KHRoaXMpOwogICAgICAgIH0KICAgIH07CgogICAgZnVuY3Rpb24gY29weUNvbXBhcmlzb25Db25zdGFudHNUb09iamVjdChvYmopIHsKICAgICAgICBvYmouU1RBUlRfVE9fU1RBUlQgPSBzMnM7CiAgICAgICAgb2JqLlNUQVJUX1RPX0VORCA9IHMyZTsKICAgICAgICBvYmouRU5EX1RPX0VORCA9IGUyZTsKICAgICAgICBvYmouRU5EX1RPX1NUQVJUID0gZTJzOwoKICAgICAgICBvYmouTk9ERV9CRUZPUkUgPSBuX2I7CiAgICAgICAgb2JqLk5PREVfQUZURVIgPSBuX2E7CiAgICAgICAgb2JqLk5PREVfQkVGT1JFX0FORF9BRlRFUiA9IG5fYl9hOwogICAgICAgIG9iai5OT0RFX0lOU0lERSA9IG5faTsKICAgIH0KCiAgICBmdW5jdGlvbiBjb3B5Q29tcGFyaXNvbkNvbnN0YW50cyhjb25zdHJ1Y3RvcikgewogICAgICAgIGNvcHlDb21wYXJpc29uQ29uc3RhbnRzVG9PYmplY3QoY29uc3RydWN0b3IpOwogICAgICAgIGNvcHlDb21wYXJpc29uQ29uc3RhbnRzVG9PYmplY3QoY29uc3RydWN0b3IucHJvdG90eXBlKTsKICAgIH0KCiAgICBmdW5jdGlvbiBjcmVhdGVSYW5nZUNvbnRlbnRSZW1vdmVyKHJlbW92ZXIsIGJvdW5kYXJ5VXBkYXRlcikgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGFzc2VydFJhbmdlVmFsaWQodGhpcyk7CgogICAgICAgICAgICB2YXIgc2MgPSB0aGlzLnN0YXJ0Q29udGFpbmVyLCBzbyA9IHRoaXMuc3RhcnRPZmZzZXQsIHJvb3QgPSB0aGlzLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyOwoKICAgICAgICAgICAgdmFyIGl0ZXJhdG9yID0gbmV3IFJhbmdlSXRlcmF0b3IodGhpcywgdHJ1ZSk7CgogICAgICAgICAgICAvLyBXb3JrIG91dCB3aGVyZSB0byBwb3NpdGlvbiB0aGUgcmFuZ2UgYWZ0ZXIgY29udGVudCByZW1vdmFsCiAgICAgICAgICAgIHZhciBub2RlLCBib3VuZGFyeTsKICAgICAgICAgICAgaWYgKHNjICE9PSByb290KSB7CiAgICAgICAgICAgICAgICBub2RlID0gZG9tLmdldENsb3Nlc3RBbmNlc3RvckluKHNjLCByb290LCB0cnVlKTsKICAgICAgICAgICAgICAgIGJvdW5kYXJ5ID0gZ2V0Qm91bmRhcnlBZnRlck5vZGUobm9kZSk7CiAgICAgICAgICAgICAgICBzYyA9IGJvdW5kYXJ5Lm5vZGU7CiAgICAgICAgICAgICAgICBzbyA9IGJvdW5kYXJ5Lm9mZnNldDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2hlY2sgbm9uZSBvZiB0aGUgcmFuZ2UgaXMgcmVhZC1vbmx5CiAgICAgICAgICAgIGl0ZXJhdGVTdWJ0cmVlKGl0ZXJhdG9yLCBhc3NlcnROb2RlTm90UmVhZE9ubHkpOwoKICAgICAgICAgICAgaXRlcmF0b3IucmVzZXQoKTsKCiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgY29udGVudAogICAgICAgICAgICB2YXIgcmV0dXJuVmFsdWUgPSByZW1vdmVyKGl0ZXJhdG9yKTsKICAgICAgICAgICAgaXRlcmF0b3IuZGV0YWNoKCk7CgogICAgICAgICAgICAvLyBNb3ZlIHRvIHRoZSBuZXcgcG9zaXRpb24KICAgICAgICAgICAgYm91bmRhcnlVcGRhdGVyKHRoaXMsIHNjLCBzbywgc2MsIHNvKTsKCiAgICAgICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTsKICAgICAgICB9OwogICAgfQoKICAgIGZ1bmN0aW9uIGNyZWF0ZVByb3RvdHlwZVJhbmdlKGNvbnN0cnVjdG9yLCBib3VuZGFyeVVwZGF0ZXIsIGRldGFjaGVyKSB7CiAgICAgICAgZnVuY3Rpb24gY3JlYXRlQmVmb3JlQWZ0ZXJOb2RlU2V0dGVyKGlzQmVmb3JlLCBpc1N0YXJ0KSB7CiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICAgICAgYXNzZXJ0Tm90RGV0YWNoZWQodGhpcyk7CiAgICAgICAgICAgICAgICBhc3NlcnRWYWxpZE5vZGVUeXBlKG5vZGUsIGJlZm9yZUFmdGVyTm9kZVR5cGVzKTsKICAgICAgICAgICAgICAgIGFzc2VydFZhbGlkTm9kZVR5cGUoZ2V0Um9vdENvbnRhaW5lcihub2RlKSwgcm9vdENvbnRhaW5lck5vZGVUeXBlcyk7CgogICAgICAgICAgICAgICAgdmFyIGJvdW5kYXJ5ID0gKGlzQmVmb3JlID8gZ2V0Qm91bmRhcnlCZWZvcmVOb2RlIDogZ2V0Qm91bmRhcnlBZnRlck5vZGUpKG5vZGUpOwogICAgICAgICAgICAgICAgKGlzU3RhcnQgPyBzZXRSYW5nZVN0YXJ0IDogc2V0UmFuZ2VFbmQpKHRoaXMsIGJvdW5kYXJ5Lm5vZGUsIGJvdW5kYXJ5Lm9mZnNldCk7CiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBzZXRSYW5nZVN0YXJ0KHJhbmdlLCBub2RlLCBvZmZzZXQpIHsKICAgICAgICAgICAgdmFyIGVjID0gcmFuZ2UuZW5kQ29udGFpbmVyLCBlbyA9IHJhbmdlLmVuZE9mZnNldDsKICAgICAgICAgICAgaWYgKG5vZGUgIT09IHJhbmdlLnN0YXJ0Q29udGFpbmVyIHx8IG9mZnNldCAhPT0gcmFuZ2Uuc3RhcnRPZmZzZXQpIHsKICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoZSByb290IGNvbnRhaW5lcnMgb2YgdGhlIHJhbmdlIGFuZCB0aGUgbmV3IGJvdW5kYXJ5LCBhbmQgYWxzbyBjaGVjayB3aGV0aGVyIHRoZSBuZXcgYm91bmRhcnkKICAgICAgICAgICAgICAgIC8vIGlzIGFmdGVyIHRoZSBjdXJyZW50IGVuZC4gSW4gZWl0aGVyIGNhc2UsIGNvbGxhcHNlIHRoZSByYW5nZSB0byB0aGUgbmV3IHBvc2l0aW9uCiAgICAgICAgICAgICAgICBpZiAoZ2V0Um9vdENvbnRhaW5lcihub2RlKSAhPSBnZXRSb290Q29udGFpbmVyKGVjKSB8fCBkb20uY29tcGFyZVBvaW50cyhub2RlLCBvZmZzZXQsIGVjLCBlbykgPT0gMSkgewogICAgICAgICAgICAgICAgICAgIGVjID0gbm9kZTsKICAgICAgICAgICAgICAgICAgICBlbyA9IG9mZnNldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJvdW5kYXJ5VXBkYXRlcihyYW5nZSwgbm9kZSwgb2Zmc2V0LCBlYywgZW8pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBzZXRSYW5nZUVuZChyYW5nZSwgbm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgICAgIHZhciBzYyA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyLCBzbyA9IHJhbmdlLnN0YXJ0T2Zmc2V0OwogICAgICAgICAgICBpZiAobm9kZSAhPT0gcmFuZ2UuZW5kQ29udGFpbmVyIHx8IG9mZnNldCAhPT0gcmFuZ2UuZW5kT2Zmc2V0KSB7CiAgICAgICAgICAgICAgICAvLyBDaGVjayB0aGUgcm9vdCBjb250YWluZXJzIG9mIHRoZSByYW5nZSBhbmQgdGhlIG5ldyBib3VuZGFyeSwgYW5kIGFsc28gY2hlY2sgd2hldGhlciB0aGUgbmV3IGJvdW5kYXJ5CiAgICAgICAgICAgICAgICAvLyBpcyBhZnRlciB0aGUgY3VycmVudCBlbmQuIEluIGVpdGhlciBjYXNlLCBjb2xsYXBzZSB0aGUgcmFuZ2UgdG8gdGhlIG5ldyBwb3NpdGlvbgogICAgICAgICAgICAgICAgaWYgKGdldFJvb3RDb250YWluZXIobm9kZSkgIT0gZ2V0Um9vdENvbnRhaW5lcihzYykgfHwgZG9tLmNvbXBhcmVQb2ludHMobm9kZSwgb2Zmc2V0LCBzYywgc28pID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgc2MgPSBub2RlOwogICAgICAgICAgICAgICAgICAgIHNvID0gb2Zmc2V0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYm91bmRhcnlVcGRhdGVyKHJhbmdlLCBzYywgc28sIG5vZGUsIG9mZnNldCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIHNldFJhbmdlU3RhcnRBbmRFbmQocmFuZ2UsIG5vZGUsIG9mZnNldCkgewogICAgICAgICAgICBpZiAobm9kZSAhPT0gcmFuZ2Uuc3RhcnRDb250YWluZXIgfHwgb2Zmc2V0ICE9PSByYW5nZS5zdGFydE9mZnNldCB8fCBub2RlICE9PSByYW5nZS5lbmRDb250YWluZXIgfHwgb2Zmc2V0ICE9PSByYW5nZS5lbmRPZmZzZXQpIHsKICAgICAgICAgICAgICAgIGJvdW5kYXJ5VXBkYXRlcihyYW5nZSwgbm9kZSwgb2Zmc2V0LCBub2RlLCBvZmZzZXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBuZXcgUmFuZ2VQcm90b3R5cGUoKTsKCiAgICAgICAgYXBpLnV0aWwuZXh0ZW5kKGNvbnN0cnVjdG9yLnByb3RvdHlwZSwgewogICAgICAgICAgICBzZXRTdGFydCA6IGZ1bmN0aW9uIChub2RlLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAgIGFzc2VydE5vdERldGFjaGVkKHRoaXMpOwogICAgICAgICAgICAgICAgYXNzZXJ0Tm9Eb2NUeXBlTm90YXRpb25FbnRpdHlBbmNlc3Rvcihub2RlLCB0cnVlKTsKICAgICAgICAgICAgICAgIGFzc2VydFZhbGlkT2Zmc2V0KG5vZGUsIG9mZnNldCk7CgogICAgICAgICAgICAgICAgc2V0UmFuZ2VTdGFydCh0aGlzLCBub2RlLCBvZmZzZXQpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2V0RW5kIDogZnVuY3Rpb24gKG5vZGUsIG9mZnNldCkgewogICAgICAgICAgICAgICAgYXNzZXJ0Tm90RGV0YWNoZWQodGhpcyk7CiAgICAgICAgICAgICAgICBhc3NlcnROb0RvY1R5cGVOb3RhdGlvbkVudGl0eUFuY2VzdG9yKG5vZGUsIHRydWUpOwogICAgICAgICAgICAgICAgYXNzZXJ0VmFsaWRPZmZzZXQobm9kZSwgb2Zmc2V0KTsKCiAgICAgICAgICAgICAgICBzZXRSYW5nZUVuZCh0aGlzLCBub2RlLCBvZmZzZXQpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2V0U3RhcnRCZWZvcmUgOiBjcmVhdGVCZWZvcmVBZnRlck5vZGVTZXR0ZXIodHJ1ZSwgdHJ1ZSksCiAgICAgICAgICAgIHNldFN0YXJ0QWZ0ZXIgOiBjcmVhdGVCZWZvcmVBZnRlck5vZGVTZXR0ZXIoZmFsc2UsIHRydWUpLAogICAgICAgICAgICBzZXRFbmRCZWZvcmUgOiBjcmVhdGVCZWZvcmVBZnRlck5vZGVTZXR0ZXIodHJ1ZSwgZmFsc2UpLAogICAgICAgICAgICBzZXRFbmRBZnRlciA6IGNyZWF0ZUJlZm9yZUFmdGVyTm9kZVNldHRlcihmYWxzZSwgZmFsc2UpLAoKICAgICAgICAgICAgY29sbGFwc2UgOiBmdW5jdGlvbiAoaXNTdGFydCkgewogICAgICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgICAgIGlmIChpc1N0YXJ0KSB7CiAgICAgICAgICAgICAgICAgICAgYm91bmRhcnlVcGRhdGVyKHRoaXMsIHRoaXMuc3RhcnRDb250YWluZXIsIHRoaXMuc3RhcnRPZmZzZXQsIHRoaXMuc3RhcnRDb250YWluZXIsIHRoaXMuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBib3VuZGFyeVVwZGF0ZXIodGhpcywgdGhpcy5lbmRDb250YWluZXIsIHRoaXMuZW5kT2Zmc2V0LCB0aGlzLmVuZENvbnRhaW5lciwgdGhpcy5lbmRPZmZzZXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2VsZWN0Tm9kZUNvbnRlbnRzIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgICAgIC8vIFRoaXMgZG9lc24ndCBzZWVtIHdlbGwgc3BlY2lmaWVkOiB0aGUgc3BlYyB0YWxrcyBvbmx5IGFib3V0IHNlbGVjdGluZyB0aGUgbm9kZSdzIGNvbnRlbnRzLCB3aGljaAogICAgICAgICAgICAgICAgLy8gY291bGQgYmUgdGFrZW4gdG8gbWVhbiBvbmx5IGl0cyBjaGlsZHJlbi4gSG93ZXZlciwgYnJvd3NlcnMgaW1wbGVtZW50IHRoaXMgdGhlIHNhbWUgYXMgc2VsZWN0Tm9kZSBmb3IKICAgICAgICAgICAgICAgIC8vIHRleHQgbm9kZXMsIHNvIEkgc2hhbGwgZG8gbGlrZXdpc2UKICAgICAgICAgICAgICAgIGFzc2VydE5vdERldGFjaGVkKHRoaXMpOwogICAgICAgICAgICAgICAgYXNzZXJ0Tm9Eb2NUeXBlTm90YXRpb25FbnRpdHlBbmNlc3Rvcihub2RlLCB0cnVlKTsKCiAgICAgICAgICAgICAgICBib3VuZGFyeVVwZGF0ZXIodGhpcywgbm9kZSwgMCwgbm9kZSwgZG9tLmdldE5vZGVMZW5ndGgobm9kZSkpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2VsZWN0Tm9kZSA6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICBhc3NlcnROb3REZXRhY2hlZCh0aGlzKTsKICAgICAgICAgICAgICAgIGFzc2VydE5vRG9jVHlwZU5vdGF0aW9uRW50aXR5QW5jZXN0b3Iobm9kZSwgZmFsc2UpOwogICAgICAgICAgICAgICAgYXNzZXJ0VmFsaWROb2RlVHlwZShub2RlLCBiZWZvcmVBZnRlck5vZGVUeXBlcyk7CgogICAgICAgICAgICAgICAgdmFyIHN0YXJ0ID0gZ2V0Qm91bmRhcnlCZWZvcmVOb2RlKG5vZGUpLCBlbmQgPSBnZXRCb3VuZGFyeUFmdGVyTm9kZShub2RlKTsKICAgICAgICAgICAgICAgIGJvdW5kYXJ5VXBkYXRlcih0aGlzLCBzdGFydC5ub2RlLCBzdGFydC5vZmZzZXQsIGVuZC5ub2RlLCBlbmQub2Zmc2V0KTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGV4dHJhY3RDb250ZW50cyA6IGNyZWF0ZVJhbmdlQ29udGVudFJlbW92ZXIoZXh0cmFjdFN1YnRyZWUsIGJvdW5kYXJ5VXBkYXRlciksCgogICAgICAgICAgICBkZWxldGVDb250ZW50cyA6IGNyZWF0ZVJhbmdlQ29udGVudFJlbW92ZXIoZGVsZXRlU3VidHJlZSwgYm91bmRhcnlVcGRhdGVyKSwKCiAgICAgICAgICAgIGNhblN1cnJvdW5kQ29udGVudHMgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBhc3NlcnRSYW5nZVZhbGlkKHRoaXMpOwogICAgICAgICAgICAgICAgYXNzZXJ0Tm9kZU5vdFJlYWRPbmx5KHRoaXMuc3RhcnRDb250YWluZXIpOwogICAgICAgICAgICAgICAgYXNzZXJ0Tm9kZU5vdFJlYWRPbmx5KHRoaXMuZW5kQ29udGFpbmVyKTsKCiAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgY29udGVudHMgY2FuIGJlIHN1cnJvdW5kZWQuIFNwZWNpZmljYWxseSwgdGhpcyBtZWFucyB3aGV0aGVyIHRoZSByYW5nZSBwYXJ0aWFsbHkgc2VsZWN0cwogICAgICAgICAgICAgICAgLy8gbm8gbm9uLXRleHQgbm9kZXMuCiAgICAgICAgICAgICAgICB2YXIgaXRlcmF0b3IgPSBuZXcgUmFuZ2VJdGVyYXRvcih0aGlzLCB0cnVlKTsKICAgICAgICAgICAgICAgIHZhciBib3VuZGFyaWVzSW52YWxpZCA9IChpdGVyYXRvci5fZmlyc3QgJiYgKGlzTm9uVGV4dFBhcnRpYWxseVNlbGVjdGVkKGl0ZXJhdG9yLl9maXJzdCwgdGhpcykpIHx8CiAgICAgICAgICAgICAgICAoaXRlcmF0b3IuX2xhc3QgJiYgaXNOb25UZXh0UGFydGlhbGx5U2VsZWN0ZWQoaXRlcmF0b3IuX2xhc3QsIHRoaXMpKSk7CiAgICAgICAgICAgICAgICBpdGVyYXRvci5kZXRhY2goKTsKICAgICAgICAgICAgICAgIHJldHVybiAhYm91bmRhcmllc0ludmFsaWQ7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBkZXRhY2ggOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBkZXRhY2hlcih0aGlzKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHNwbGl0Qm91bmRhcmllcyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGFzc2VydFJhbmdlVmFsaWQodGhpcyk7CgogICAgICAgICAgICAgICAgdmFyIHNjID0gdGhpcy5zdGFydENvbnRhaW5lciwgc28gPSB0aGlzLnN0YXJ0T2Zmc2V0LCBlYyA9IHRoaXMuZW5kQ29udGFpbmVyLCBlbyA9IHRoaXMuZW5kT2Zmc2V0OwogICAgICAgICAgICAgICAgdmFyIHN0YXJ0RW5kU2FtZSA9IChzYyA9PT0gZWMpOwoKICAgICAgICAgICAgICAgIGlmIChkb20uaXNDaGFyYWN0ZXJEYXRhTm9kZShlYykgJiYgZW8gPCBlYy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBkb20uc3BsaXREYXRhTm9kZShlYywgZW8pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChkb20uaXNDaGFyYWN0ZXJEYXRhTm9kZShzYykgJiYgc28gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgc2MgPSBkb20uc3BsaXREYXRhTm9kZShzYywgc28pOwogICAgICAgICAgICAgICAgICAgIGlmIChzdGFydEVuZFNhbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZW8gLT0gc287CiAgICAgICAgICAgICAgICAgICAgICAgIGVjID0gc2M7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlYyA9PSBzYy5wYXJlbnROb2RlICYmIGVvID49IGRvbS5nZXROb2RlSW5kZXgoc2MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVvKys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHNvID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJvdW5kYXJ5VXBkYXRlcih0aGlzLCBzYywgc28sIGVjLCBlbyk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBub3JtYWxpemVCb3VuZGFyaWVzIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKCiAgICAgICAgICAgICAgICB2YXIgc2MgPSB0aGlzLnN0YXJ0Q29udGFpbmVyLCBzbyA9IHRoaXMuc3RhcnRPZmZzZXQsIGVjID0gdGhpcy5lbmRDb250YWluZXIsIGVvID0gdGhpcy5lbmRPZmZzZXQ7CgogICAgICAgICAgICAgICAgdmFyIG1lcmdlRm9yd2FyZCA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHNpYmxpbmcgPSBub2RlLm5leHRTaWJsaW5nOwogICAgICAgICAgICAgICAgICAgIGlmIChzaWJsaW5nICYmIHNpYmxpbmcubm9kZVR5cGUgPT0gbm9kZS5ub2RlVHlwZSkgewogICAgICAgICAgICAgICAgICAgICAgICBlYyA9IG5vZGU7CiAgICAgICAgICAgICAgICAgICAgICAgIGVvID0gbm9kZS5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuYXBwZW5kRGF0YShzaWJsaW5nLmRhdGEpOwogICAgICAgICAgICAgICAgICAgICAgICBzaWJsaW5nLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc2libGluZyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICB2YXIgbWVyZ2VCYWNrd2FyZCA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHNpYmxpbmcgPSBub2RlLnByZXZpb3VzU2libGluZzsKICAgICAgICAgICAgICAgICAgICBpZiAoc2libGluZyAmJiBzaWJsaW5nLm5vZGVUeXBlID09IG5vZGUubm9kZVR5cGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2MgPSBub2RlOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZUxlbmd0aCA9IG5vZGUubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICBzbyA9IHNpYmxpbmcubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICBub2RlLmluc2VydERhdGEoMCwgc2libGluZy5kYXRhKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2libGluZy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHNpYmxpbmcpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2MgPT0gZWMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVvICs9IHNvOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWMgPSBzYzsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlYyA9PSBub2RlLnBhcmVudE5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlSW5kZXggPSBkb20uZ2V0Tm9kZUluZGV4KG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVvID09IG5vZGVJbmRleCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVjID0gbm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbyA9IG5vZGVMZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVvID4gbm9kZUluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW8tLTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgdmFyIG5vcm1hbGl6ZVN0YXJ0ID0gdHJ1ZTsKCiAgICAgICAgICAgICAgICBpZiAoZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUoZWMpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVjLmxlbmd0aCA9PSBlbykgewogICAgICAgICAgICAgICAgICAgICAgICBtZXJnZUZvcndhcmQoZWMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVvID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZW5kTm9kZSA9IGVjLmNoaWxkTm9kZXNbZW8gLSAxXTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVuZE5vZGUgJiYgZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUoZW5kTm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lcmdlRm9yd2FyZChlbmROb2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVTdGFydCA9ICF0aGlzLmNvbGxhcHNlZDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAobm9ybWFsaXplU3RhcnQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUoc2MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzbyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXJnZUJhY2t3YXJkKHNjKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzbyA8IHNjLmNoaWxkTm9kZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RhcnROb2RlID0gc2MuY2hpbGROb2Rlc1tzb107CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhcnROb2RlICYmIGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKHN0YXJ0Tm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXJnZUJhY2t3YXJkKHN0YXJ0Tm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHNjID0gZWM7CiAgICAgICAgICAgICAgICAgICAgc28gPSBlbzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBib3VuZGFyeVVwZGF0ZXIodGhpcywgc2MsIHNvLCBlYywgZW8pOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgY29sbGFwc2VUb1BvaW50IDogZnVuY3Rpb24gKG5vZGUsIG9mZnNldCkgewogICAgICAgICAgICAgICAgYXNzZXJ0Tm90RGV0YWNoZWQodGhpcyk7CgogICAgICAgICAgICAgICAgYXNzZXJ0Tm9Eb2NUeXBlTm90YXRpb25FbnRpdHlBbmNlc3Rvcihub2RlLCB0cnVlKTsKICAgICAgICAgICAgICAgIGFzc2VydFZhbGlkT2Zmc2V0KG5vZGUsIG9mZnNldCk7CgogICAgICAgICAgICAgICAgc2V0UmFuZ2VTdGFydEFuZEVuZCh0aGlzLCBub2RlLCBvZmZzZXQpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIGNvcHlDb21wYXJpc29uQ29uc3RhbnRzKGNvbnN0cnVjdG9yKTsKICAgIH0KCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8vIFVwZGF0ZXMgY29tbW9uQW5jZXN0b3JDb250YWluZXIgYW5kIGNvbGxhcHNlZCBhZnRlciBib3VuZGFyeSBjaGFuZ2UKICAgIGZ1bmN0aW9uIHVwZGF0ZUNvbGxhcHNlZEFuZENvbW1vbkFuY2VzdG9yKHJhbmdlKSB7CiAgICAgICAgcmFuZ2UuY29sbGFwc2VkID0gKHJhbmdlLnN0YXJ0Q29udGFpbmVyID09PSByYW5nZS5lbmRDb250YWluZXIgJiYgcmFuZ2Uuc3RhcnRPZmZzZXQgPT09IHJhbmdlLmVuZE9mZnNldCk7CiAgICAgICAgcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIgPSByYW5nZS5jb2xsYXBzZWQgPwogICAgICAgICAgICByYW5nZS5zdGFydENvbnRhaW5lciA6IGRvbS5nZXRDb21tb25BbmNlc3RvcihyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2UuZW5kQ29udGFpbmVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiB1cGRhdGVCb3VuZGFyaWVzKHJhbmdlLCBzdGFydENvbnRhaW5lciwgc3RhcnRPZmZzZXQsIGVuZENvbnRhaW5lciwgZW5kT2Zmc2V0KSB7CiAgICAgICAgdmFyIHN0YXJ0TW92ZWQgPSAocmFuZ2Uuc3RhcnRDb250YWluZXIgIT09IHN0YXJ0Q29udGFpbmVyIHx8IHJhbmdlLnN0YXJ0T2Zmc2V0ICE9PSBzdGFydE9mZnNldCk7CiAgICAgICAgdmFyIGVuZE1vdmVkID0gKHJhbmdlLmVuZENvbnRhaW5lciAhPT0gZW5kQ29udGFpbmVyIHx8IHJhbmdlLmVuZE9mZnNldCAhPT0gZW5kT2Zmc2V0KTsKCiAgICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXIgPSBzdGFydENvbnRhaW5lcjsKICAgICAgICByYW5nZS5zdGFydE9mZnNldCA9IHN0YXJ0T2Zmc2V0OwogICAgICAgIHJhbmdlLmVuZENvbnRhaW5lciA9IGVuZENvbnRhaW5lcjsKICAgICAgICByYW5nZS5lbmRPZmZzZXQgPSBlbmRPZmZzZXQ7CgogICAgICAgIHVwZGF0ZUNvbGxhcHNlZEFuZENvbW1vbkFuY2VzdG9yKHJhbmdlKTsKICAgICAgICBkaXNwYXRjaEV2ZW50KHJhbmdlLCAiYm91bmRhcnljaGFuZ2UiLCB7c3RhcnRNb3ZlZCA6IHN0YXJ0TW92ZWQsIGVuZE1vdmVkIDogZW5kTW92ZWR9KTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZXRhY2gocmFuZ2UpIHsKICAgICAgICBhc3NlcnROb3REZXRhY2hlZChyYW5nZSk7CiAgICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXIgPSByYW5nZS5zdGFydE9mZnNldCA9IHJhbmdlLmVuZENvbnRhaW5lciA9IHJhbmdlLmVuZE9mZnNldCA9IG51bGw7CiAgICAgICAgcmFuZ2UuY29sbGFwc2VkID0gcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIgPSBudWxsOwogICAgICAgIGRpc3BhdGNoRXZlbnQocmFuZ2UsICJkZXRhY2giLCBudWxsKTsKICAgICAgICByYW5nZS5fbGlzdGVuZXJzID0gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBjb25zdHJ1Y3RvcgogICAgICovCiAgICBmdW5jdGlvbiBSYW5nZShkb2MpIHsKICAgICAgICB0aGlzLnN0YXJ0Q29udGFpbmVyID0gZG9jOwogICAgICAgIHRoaXMuc3RhcnRPZmZzZXQgPSAwOwogICAgICAgIHRoaXMuZW5kQ29udGFpbmVyID0gZG9jOwogICAgICAgIHRoaXMuZW5kT2Zmc2V0ID0gMDsKICAgICAgICB0aGlzLl9saXN0ZW5lcnMgPSB7CiAgICAgICAgICAgIGJvdW5kYXJ5Y2hhbmdlIDogW10sCiAgICAgICAgICAgIGRldGFjaCA6IFtdCiAgICAgICAgfTsKICAgICAgICB1cGRhdGVDb2xsYXBzZWRBbmRDb21tb25BbmNlc3Rvcih0aGlzKTsKICAgIH0KCiAgICBjcmVhdGVQcm90b3R5cGVSYW5nZShSYW5nZSwgdXBkYXRlQm91bmRhcmllcywgZGV0YWNoKTsKCiAgICBhcGkucmFuZ2VQcm90b3R5cGUgPSBSYW5nZVByb3RvdHlwZS5wcm90b3R5cGU7CgogICAgUmFuZ2UucmFuZ2VQcm9wZXJ0aWVzID0gcmFuZ2VQcm9wZXJ0aWVzOwogICAgUmFuZ2UuUmFuZ2VJdGVyYXRvciA9IFJhbmdlSXRlcmF0b3I7CiAgICBSYW5nZS5jb3B5Q29tcGFyaXNvbkNvbnN0YW50cyA9IGNvcHlDb21wYXJpc29uQ29uc3RhbnRzOwogICAgUmFuZ2UuY3JlYXRlUHJvdG90eXBlUmFuZ2UgPSBjcmVhdGVQcm90b3R5cGVSYW5nZTsKICAgIFJhbmdlLmluc3BlY3QgPSBpbnNwZWN0OwogICAgUmFuZ2UuZ2V0UmFuZ2VEb2N1bWVudCA9IGdldFJhbmdlRG9jdW1lbnQ7CiAgICBSYW5nZS5yYW5nZXNFcXVhbCA9IGZ1bmN0aW9uIChyMSwgcjIpIHsKICAgICAgICByZXR1cm4gcjEuc3RhcnRDb250YWluZXIgPT09IHIyLnN0YXJ0Q29udGFpbmVyICYmIHIxLnN0YXJ0T2Zmc2V0ID09PSByMi5zdGFydE9mZnNldCAmJiByMS5lbmRDb250YWluZXIgPT09IHIyLmVuZENvbnRhaW5lciAmJiByMS5lbmRPZmZzZXQgPT09IHIyLmVuZE9mZnNldDsKICAgIH07CgogICAgYXBpLkRvbVJhbmdlID0gUmFuZ2U7CiAgICBhcGkuUmFuZ2VFeGNlcHRpb24gPSBSYW5nZUV4Y2VwdGlvbjsKfSk7CnJhbmd5LmNyZWF0ZU1vZHVsZSgiV3JhcHBlZFJhbmdlIiwgZnVuY3Rpb24gKGFwaSwgbW9kdWxlKSB7CiAgICBhcGkucmVxdWlyZU1vZHVsZXMoWyJEb21VdGlsIiwgIkRvbVJhbmdlIl0pOwoKICAgIC8qKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKi8KICAgIHZhciBXcmFwcGVkUmFuZ2U7CiAgICB2YXIgZG9tID0gYXBpLmRvbTsKICAgIHZhciBEb21Qb3NpdGlvbiA9IGRvbS5Eb21Qb3NpdGlvbjsKICAgIHZhciBEb21SYW5nZSA9IGFwaS5Eb21SYW5nZTsKCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8qCiAgICAgVGhpcyBpcyBhIHdvcmthcm91bmQgZm9yIGEgYnVnIHdoZXJlIElFIHJldHVybnMgdGhlIHdyb25nIGNvbnRhaW5lciBlbGVtZW50IGZyb20gdGhlIFRleHRSYW5nZSdzIHBhcmVudEVsZW1lbnQoKQogICAgIG1ldGhvZC4gRm9yIGV4YW1wbGUsIGluIHRoZSBmb2xsb3dpbmcgKHdoZXJlIHBpcGVzIGRlbm90ZSB0aGUgc2VsZWN0aW9uIGJvdW5kYXJpZXMpOgoKICAgICA8dWwgaWQ9InVsIj48bGkgaWQ9ImEiPnwgYSA8L2xpPjxsaSBpZD0iYiI+IGIgfDwvbGk+PC91bD4KCiAgICAgdmFyIHJhbmdlID0gZG9jdW1lbnQuc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCk7CiAgICAgYWxlcnQocmFuZ2UucGFyZW50RWxlbWVudCgpLmlkKTsgLy8gU2hvdWxkIGFsZXJ0ICJ1bCIgYnV0IGFsZXJ0cyAiYiIKCiAgICAgVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgY29tbW9uIGFuY2VzdG9yIG5vZGUgb2YgdGhlIGZvbGxvd2luZzoKICAgICAtIHRoZSBwYXJlbnRFbGVtZW50KCkgb2YgdGhlIHRleHRSYW5nZQogICAgIC0gdGhlIHBhcmVudEVsZW1lbnQoKSBvZiB0aGUgdGV4dFJhbmdlIGFmdGVyIGNhbGxpbmcgY29sbGFwc2UodHJ1ZSkKICAgICAtIHRoZSBwYXJlbnRFbGVtZW50KCkgb2YgdGhlIHRleHRSYW5nZSBhZnRlciBjYWxsaW5nIGNvbGxhcHNlKGZhbHNlKQogICAgICovCiAgICBmdW5jdGlvbiBnZXRUZXh0UmFuZ2VDb250YWluZXJFbGVtZW50KHRleHRSYW5nZSkgewogICAgICAgIHZhciBwYXJlbnRFbCA9IHRleHRSYW5nZS5wYXJlbnRFbGVtZW50KCk7CgogICAgICAgIHZhciByYW5nZSA9IHRleHRSYW5nZS5kdXBsaWNhdGUoKTsKICAgICAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTsKICAgICAgICB2YXIgc3RhcnRFbCA9IHJhbmdlLnBhcmVudEVsZW1lbnQoKTsKICAgICAgICByYW5nZSA9IHRleHRSYW5nZS5kdXBsaWNhdGUoKTsKICAgICAgICByYW5nZS5jb2xsYXBzZShmYWxzZSk7CiAgICAgICAgdmFyIGVuZEVsID0gcmFuZ2UucGFyZW50RWxlbWVudCgpOwogICAgICAgIHZhciBzdGFydEVuZENvbnRhaW5lciA9IChzdGFydEVsID09IGVuZEVsKSA/IHN0YXJ0RWwgOiBkb20uZ2V0Q29tbW9uQW5jZXN0b3Ioc3RhcnRFbCwgZW5kRWwpOwoKICAgICAgICByZXR1cm4gc3RhcnRFbmRDb250YWluZXIgPT0gcGFyZW50RWwgPyBzdGFydEVuZENvbnRhaW5lciA6IGRvbS5nZXRDb21tb25BbmNlc3RvcihwYXJlbnRFbCwgc3RhcnRFbmRDb250YWluZXIpOwogICAgfQoKICAgIGZ1bmN0aW9uIHRleHRSYW5nZUlzQ29sbGFwc2VkKHRleHRSYW5nZSkgewogICAgICAgIHJldHVybiB0ZXh0UmFuZ2UuY29tcGFyZUVuZFBvaW50cygiU3RhcnRUb0VuZCIsIHRleHRSYW5nZSkgPT0gMDsKICAgIH0KCiAgICAvLyBHZXRzIHRoZSBib3VuZGFyeSBvZiBhIFRleHRSYW5nZSBleHByZXNzZWQgYXMgYSBub2RlIGFuZCBhbiBvZmZzZXQgd2l0aGluIHRoYXQgbm9kZS4gVGhpcyBmdW5jdGlvbiBzdGFydGVkIG91dCBhcwogICAgLy8gYW4gaW1wcm92ZWQgdmVyc2lvbiBvZiBjb2RlIGZvdW5kIGluIFRpbSBDYW1lcm9uIFJ5YW4ncyBJRVJhbmdlIChodHRwOi8vY29kZS5nb29nbGUuY29tL3AvaWVyYW5nZS8pIGJ1dCBoYXMKICAgIC8vIGdyb3duLCBmaXhpbmcgcHJvYmxlbXMgd2l0aCBsaW5lIGJyZWFrcyBpbiBwcmVmb3JtYXR0ZWQgdGV4dCwgYWRkaW5nIHdvcmthcm91bmQgZm9yIElFIFRleHRSYW5nZSBidWdzLCBoYW5kbGluZwogICAgLy8gZm9yIGlucHV0cyBhbmQgaW1hZ2VzLCBwbHVzIG9wdGltaXphdGlvbnMuCiAgICBmdW5jdGlvbiBnZXRUZXh0UmFuZ2VCb3VuZGFyeVBvc2l0aW9uKHRleHRSYW5nZSwgd2hvbGVSYW5nZUNvbnRhaW5lckVsZW1lbnQsIGlzU3RhcnQsIGlzQ29sbGFwc2VkKSB7CiAgICAgICAgdmFyIHdvcmtpbmdSYW5nZSA9IHRleHRSYW5nZS5kdXBsaWNhdGUoKTsKCiAgICAgICAgd29ya2luZ1JhbmdlLmNvbGxhcHNlKGlzU3RhcnQpOwogICAgICAgIHZhciBjb250YWluZXJFbGVtZW50ID0gd29ya2luZ1JhbmdlLnBhcmVudEVsZW1lbnQoKTsKCiAgICAgICAgLy8gU29tZXRpbWVzIGNvbGxhcHNpbmcgYSBUZXh0UmFuZ2UgdGhhdCdzIGF0IHRoZSBzdGFydCBvZiBhIHRleHQgbm9kZSBjYW4gbW92ZSBpdCBpbnRvIHRoZSBwcmV2aW91cyBub2RlLCBzbwogICAgICAgIC8vIGNoZWNrIGZvciB0aGF0CiAgICAgICAgLy8gVE9ETzogRmluZCBvdXQgd2hlbi4gV29ya2Fyb3VuZCBmb3Igd2hvbGVSYW5nZUNvbnRhaW5lckVsZW1lbnQgbWF5IGJyZWFrIHRoaXMKICAgICAgICBpZiAoIWRvbS5pc0FuY2VzdG9yT2Yod2hvbGVSYW5nZUNvbnRhaW5lckVsZW1lbnQsIGNvbnRhaW5lckVsZW1lbnQsIHRydWUpKSB7CiAgICAgICAgICAgIGNvbnRhaW5lckVsZW1lbnQgPSB3aG9sZVJhbmdlQ29udGFpbmVyRWxlbWVudDsKICAgICAgICB9CgogICAgICAgIC8vIERlYWwgd2l0aCBub2RlcyB0aGF0IGNhbm5vdCAiY29udGFpbiByaWNoIEhUTUwgbWFya3VwIi4gSW4gcHJhY3RpY2UsIHRoaXMgbWVhbnMgZm9ybSBpbnB1dHMsIGltYWdlcyBhbmQKICAgICAgICAvLyBzaW1pbGFyLiBTZWUgaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2FhNzAzOTUwJTI4VlMuODUlMjkuYXNweAogICAgICAgIGlmICghY29udGFpbmVyRWxlbWVudC5jYW5IYXZlSFRNTCkgewogICAgICAgICAgICByZXR1cm4gbmV3IERvbVBvc2l0aW9uKGNvbnRhaW5lckVsZW1lbnQucGFyZW50Tm9kZSwgZG9tLmdldE5vZGVJbmRleChjb250YWluZXJFbGVtZW50KSk7CiAgICAgICAgfQoKICAgICAgICB2YXIgd29ya2luZ05vZGUgPSBkb20uZ2V0RG9jdW1lbnQoY29udGFpbmVyRWxlbWVudCkuY3JlYXRlRWxlbWVudCgic3BhbiIpOwogICAgICAgIHZhciBjb21wYXJpc29uLCB3b3JraW5nQ29tcGFyaXNvblR5cGUgPSBpc1N0YXJ0ID8gIlN0YXJ0VG9TdGFydCIgOiAiU3RhcnRUb0VuZCI7CiAgICAgICAgdmFyIHByZXZpb3VzTm9kZSwgbmV4dE5vZGUsIGJvdW5kYXJ5UG9zaXRpb24sIGJvdW5kYXJ5Tm9kZTsKCiAgICAgICAgLy8gTW92ZSB0aGUgd29ya2luZyByYW5nZSB0aHJvdWdoIHRoZSBjb250YWluZXIncyBjaGlsZHJlbiwgc3RhcnRpbmcgYXQgdGhlIGVuZCBhbmQgd29ya2luZyBiYWNrd2FyZHMsIHVudGlsIHRoZQogICAgICAgIC8vIHdvcmtpbmcgcmFuZ2UgcmVhY2hlcyBvciBnb2VzIHBhc3QgdGhlIGJvdW5kYXJ5IHdlJ3JlIGludGVyZXN0ZWQgaW4KICAgICAgICBkbyB7CiAgICAgICAgICAgIGNvbnRhaW5lckVsZW1lbnQuaW5zZXJ0QmVmb3JlKHdvcmtpbmdOb2RlLCB3b3JraW5nTm9kZS5wcmV2aW91c1NpYmxpbmcpOwogICAgICAgICAgICB3b3JraW5nUmFuZ2UubW92ZVRvRWxlbWVudFRleHQod29ya2luZ05vZGUpOwogICAgICAgIH0gd2hpbGUgKChjb21wYXJpc29uID0gd29ya2luZ1JhbmdlLmNvbXBhcmVFbmRQb2ludHMod29ya2luZ0NvbXBhcmlzb25UeXBlLCB0ZXh0UmFuZ2UpKSA+IDAgJiYgd29ya2luZ05vZGUucHJldmlvdXNTaWJsaW5nKTsKCiAgICAgICAgLy8gV2UndmUgbm93IHJlYWNoZWQgb3IgZ29uZSBwYXN0IHRoZSBib3VuZGFyeSBvZiB0aGUgdGV4dCByYW5nZSB3ZSdyZSBpbnRlcmVzdGVkIGluCiAgICAgICAgLy8gc28gaGF2ZSBpZGVudGlmaWVkIHRoZSBub2RlIHdlIHdhbnQKICAgICAgICBib3VuZGFyeU5vZGUgPSB3b3JraW5nTm9kZS5uZXh0U2libGluZzsKCiAgICAgICAgaWYgKGNvbXBhcmlzb24gPT0gLTEgJiYgYm91bmRhcnlOb2RlICYmIGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKGJvdW5kYXJ5Tm9kZSkpIHsKICAgICAgICAgICAgLy8gVGhpcyBpcyBhIGNoYXJhY3RlciBkYXRhIG5vZGUgKHRleHQsIGNvbW1lbnQsIGNkYXRhKS4gVGhlIHdvcmtpbmcgcmFuZ2UgaXMgY29sbGFwc2VkIGF0IHRoZSBzdGFydCBvZiB0aGUKICAgICAgICAgICAgLy8gbm9kZSBjb250YWluaW5nIHRoZSB0ZXh0IHJhbmdlJ3MgYm91bmRhcnksIHNvIHdlIG1vdmUgdGhlIGVuZCBvZiB0aGUgd29ya2luZyByYW5nZSB0byB0aGUgYm91bmRhcnkgcG9pbnQKICAgICAgICAgICAgLy8gYW5kIG1lYXN1cmUgdGhlIGxlbmd0aCBvZiBpdHMgdGV4dCB0byBnZXQgdGhlIGJvdW5kYXJ5J3Mgb2Zmc2V0IHdpdGhpbiB0aGUgbm9kZS4KICAgICAgICAgICAgd29ya2luZ1JhbmdlLnNldEVuZFBvaW50KGlzU3RhcnQgPyAiRW5kVG9TdGFydCIgOiAiRW5kVG9FbmQiLCB0ZXh0UmFuZ2UpOwoKICAgICAgICAgICAgdmFyIG9mZnNldDsKCiAgICAgICAgICAgIGlmICgvW1xyXG5dLy50ZXN0KGJvdW5kYXJ5Tm9kZS5kYXRhKSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICBGb3IgdGhlIHBhcnRpY3VsYXIgY2FzZSBvZiBhIGJvdW5kYXJ5IHdpdGhpbiBhIHRleHQgbm9kZSBjb250YWluaW5nIGxpbmUgYnJlYWtzICh3aXRoaW4gYSA8cHJlPiBlbGVtZW50LAogICAgICAgICAgICAgICAgIGZvciBleGFtcGxlKSwgd2UgbmVlZCBhIHNsaWdodGx5IGNvbXBsaWNhdGVkIGFwcHJvYWNoIHRvIGdldCB0aGUgYm91bmRhcnkncyBvZmZzZXQgaW4gSUUuIFRoZSBmYWN0czoKCiAgICAgICAgICAgICAgICAgLSBFYWNoIGxpbmUgYnJlYWsgaXMgcmVwcmVzZW50ZWQgYXMgXHIgaW4gdGhlIHRleHQgbm9kZSdzIGRhdGEvbm9kZVZhbHVlIHByb3BlcnRpZXMKICAgICAgICAgICAgICAgICAtIEVhY2ggbGluZSBicmVhayBpcyByZXByZXNlbnRlZCBhcyBcclxuIGluIHRoZSBUZXh0UmFuZ2UncyAndGV4dCcgcHJvcGVydHkKICAgICAgICAgICAgICAgICAtIFRoZSAndGV4dCcgcHJvcGVydHkgb2YgdGhlIFRleHRSYW5nZSBkb2VzIG5vdCBjb250YWluIHRyYWlsaW5nIGxpbmUgYnJlYWtzCgogICAgICAgICAgICAgICAgIFRvIGdldCByb3VuZCB0aGUgcHJvYmxlbSBwcmVzZW50ZWQgYnkgdGhlIGZpbmFsIGZhY3QgYWJvdmUsIHdlIGNhbiB1c2UgdGhlIGZhY3QgdGhhdCBUZXh0UmFuZ2UncwogICAgICAgICAgICAgICAgIG1vdmVTdGFydCgpIGFuZCBtb3ZlRW5kKCkgbWV0aG9kcyByZXR1cm4gdGhlIGFjdHVhbCBudW1iZXIgb2YgY2hhcmFjdGVycyBtb3ZlZCwgd2hpY2ggaXMgbm90IG5lY2Vzc2FyaWx5CiAgICAgICAgICAgICAgICAgdGhlIHNhbWUgYXMgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGl0IHdhcyBpbnN0cnVjdGVkIHRvIG1vdmUuIFRoZSBzaW1wbGVzdCBhcHByb2FjaCBpcyB0byB1c2UgdGhpcyB0bwogICAgICAgICAgICAgICAgIHN0b3JlIHRoZSBjaGFyYWN0ZXJzIG1vdmVkIHdoZW4gbW92aW5nIGJvdGggdGhlIHN0YXJ0IGFuZCBlbmQgb2YgdGhlIHJhbmdlIHRvIHRoZSBzdGFydCBvZiB0aGUgZG9jdW1lbnQKICAgICAgICAgICAgICAgICBib2R5IGFuZCBzdWJ0cmFjdGluZyB0aGUgc3RhcnQgb2Zmc2V0IGZyb20gdGhlIGVuZCBvZmZzZXQgKHRoZSAibW92ZS1uZWdhdGl2ZS1nYXppbGxpb24iIG1ldGhvZCkuCiAgICAgICAgICAgICAgICAgSG93ZXZlciwgdGhpcyBpcyBleHRyZW1lbHkgc2xvdyB3aGVuIHRoZSBkb2N1bWVudCBpcyBsYXJnZSBhbmQgdGhlIHJhbmdlIGlzIG5lYXIgdGhlIGVuZCBvZiBpdC4gQ2xlYXJseQogICAgICAgICAgICAgICAgIGRvaW5nIHRoZSBtaXJyb3IgaW1hZ2UgKGkuZS4gbW92aW5nIHRoZSByYW5nZSBib3VuZGFyaWVzIHRvIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50KSBoYXMgdGhlIHNhbWUKICAgICAgICAgICAgICAgICBwcm9ibGVtLgoKICAgICAgICAgICAgICAgICBBbm90aGVyIGFwcHJvYWNoIHRoYXQgd29ya3MgaXMgdG8gdXNlIG1vdmVTdGFydCgpIHRvIG1vdmUgdGhlIHN0YXJ0IGJvdW5kYXJ5IG9mIHRoZSByYW5nZSB1cCB0byB0aGUgZW5kCiAgICAgICAgICAgICAgICAgYm91bmRhcnkgb25lIGNoYXJhY3RlciBhdCBhIHRpbWUgYW5kIGluY3JlbWVudGluZyBhIGNvdW50ZXIgd2l0aCB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIG1vdmVTdGFydCgpCiAgICAgICAgICAgICAgICAgY2FsbC4gSG93ZXZlciwgdGhlIGNoZWNrIGZvciB3aGV0aGVyIHRoZSBzdGFydCBib3VuZGFyeSBoYXMgcmVhY2hlZCB0aGUgZW5kIGJvdW5kYXJ5IGlzIGV4cGVuc2l2ZSwgc28KICAgICAgICAgICAgICAgICB0aGlzIG1ldGhvZCBpcyBzbG93IChhbHRob3VnaCB1bmxpa2UgIm1vdmUtbmVnYXRpdmUtZ2F6aWxsaW9uIiBpcyBsYXJnZWx5IHVuYWZmZWN0ZWQgYnkgdGhlIGxvY2F0aW9uIG9mCiAgICAgICAgICAgICAgICAgdGhlIHJhbmdlIHdpdGhpbiB0aGUgZG9jdW1lbnQpLgoKICAgICAgICAgICAgICAgICBUaGUgbWV0aG9kIGJlbG93IGlzIGEgaHlicmlkIG9mIHRoZSB0d28gbWV0aG9kcyBhYm92ZS4gSXQgdXNlcyB0aGUgZmFjdCB0aGF0IGEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlCiAgICAgICAgICAgICAgICAgVGV4dFJhbmdlJ3MgJ3RleHQnIHByb3BlcnR5IHdpdGggZWFjaCBcclxuIGNvbnZlcnRlZCB0byBhIHNpbmdsZSBcciBjaGFyYWN0ZXIgY2Fubm90IGJlIGxvbmdlciB0aGFuIHRoZQogICAgICAgICAgICAgICAgIHRleHQgb2YgdGhlIFRleHRSYW5nZSwgc28gdGhlIHN0YXJ0IG9mIHRoZSByYW5nZSBpcyBtb3ZlZCB0aGF0IGxlbmd0aCBpbml0aWFsbHkgYW5kIHRoZW4gYSBjaGFyYWN0ZXIgYXQKICAgICAgICAgICAgICAgICBhIHRpbWUgdG8gbWFrZSB1cCBmb3IgYW55IHRyYWlsaW5nIGxpbmUgYnJlYWtzIG5vdCBjb250YWluZWQgaW4gdGhlICd0ZXh0JyBwcm9wZXJ0eS4gVGhpcyBoYXMgZ29vZAogICAgICAgICAgICAgICAgIHBlcmZvcm1hbmNlIGluIG1vc3Qgc2l0dWF0aW9ucyBjb21wYXJlZCB0byB0aGUgcHJldmlvdXMgdHdvIG1ldGhvZHMuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHZhciB0ZW1wUmFuZ2UgPSB3b3JraW5nUmFuZ2UuZHVwbGljYXRlKCk7CiAgICAgICAgICAgICAgICB2YXIgcmFuZ2VMZW5ndGggPSB0ZW1wUmFuZ2UudGV4dC5yZXBsYWNlKC9cclxuL2csICJcciIpLmxlbmd0aDsKCiAgICAgICAgICAgICAgICBvZmZzZXQgPSB0ZW1wUmFuZ2UubW92ZVN0YXJ0KCJjaGFyYWN0ZXIiLCByYW5nZUxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoKGNvbXBhcmlzb24gPSB0ZW1wUmFuZ2UuY29tcGFyZUVuZFBvaW50cygiU3RhcnRUb0VuZCIsIHRlbXBSYW5nZSkpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0Kys7CiAgICAgICAgICAgICAgICAgICAgdGVtcFJhbmdlLm1vdmVTdGFydCgiY2hhcmFjdGVyIiwgMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBvZmZzZXQgPSB3b3JraW5nUmFuZ2UudGV4dC5sZW5ndGg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYm91bmRhcnlQb3NpdGlvbiA9IG5ldyBEb21Qb3NpdGlvbihib3VuZGFyeU5vZGUsIG9mZnNldCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gSWYgdGhlIGJvdW5kYXJ5IGltbWVkaWF0ZWx5IGZvbGxvd3MgYSBjaGFyYWN0ZXIgZGF0YSBub2RlIGFuZCB0aGlzIGlzIHRoZSBlbmQgYm91bmRhcnksIHdlIHNob3VsZCBmYXZvdXIKICAgICAgICAgICAgLy8gYSBwb3NpdGlvbiB3aXRoaW4gdGhhdCwgYW5kIGxpa2V3aXNlIGZvciBhIHN0YXJ0IGJvdW5kYXJ5IHByZWNlZGluZyBhIGNoYXJhY3RlciBkYXRhIG5vZGUKICAgICAgICAgICAgcHJldmlvdXNOb2RlID0gKGlzQ29sbGFwc2VkIHx8ICFpc1N0YXJ0KSAmJiB3b3JraW5nTm9kZS5wcmV2aW91c1NpYmxpbmc7CiAgICAgICAgICAgIG5leHROb2RlID0gKGlzQ29sbGFwc2VkIHx8IGlzU3RhcnQpICYmIHdvcmtpbmdOb2RlLm5leHRTaWJsaW5nOwoKICAgICAgICAgICAgaWYgKG5leHROb2RlICYmIGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKG5leHROb2RlKSkgewogICAgICAgICAgICAgICAgYm91bmRhcnlQb3NpdGlvbiA9IG5ldyBEb21Qb3NpdGlvbihuZXh0Tm9kZSwgMCk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAocHJldmlvdXNOb2RlICYmIGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKHByZXZpb3VzTm9kZSkpIHsKICAgICAgICAgICAgICAgIGJvdW5kYXJ5UG9zaXRpb24gPSBuZXcgRG9tUG9zaXRpb24ocHJldmlvdXNOb2RlLCBwcmV2aW91c05vZGUubGVuZ3RoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJvdW5kYXJ5UG9zaXRpb24gPSBuZXcgRG9tUG9zaXRpb24oY29udGFpbmVyRWxlbWVudCwgZG9tLmdldE5vZGVJbmRleCh3b3JraW5nTm9kZSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBDbGVhbiB1cAogICAgICAgIHdvcmtpbmdOb2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQod29ya2luZ05vZGUpOwoKICAgICAgICByZXR1cm4gYm91bmRhcnlQb3NpdGlvbjsKICAgIH0KCiAgICAvLyBSZXR1cm5zIGEgVGV4dFJhbmdlIHJlcHJlc2VudGluZyB0aGUgYm91bmRhcnkgb2YgYSBUZXh0UmFuZ2UgZXhwcmVzc2VkIGFzIGEgbm9kZSBhbmQgYW4gb2Zmc2V0IHdpdGhpbiB0aGF0IG5vZGUuCiAgICAvLyBUaGlzIGZ1bmN0aW9uIHN0YXJ0ZWQgb3V0IGFzIGFuIG9wdGltaXplZCB2ZXJzaW9uIG9mIGNvZGUgZm91bmQgaW4gVGltIENhbWVyb24gUnlhbidzIElFUmFuZ2UKICAgIC8vIChodHRwOi8vY29kZS5nb29nbGUuY29tL3AvaWVyYW5nZS8pCiAgICBmdW5jdGlvbiBjcmVhdGVCb3VuZGFyeVRleHRSYW5nZShib3VuZGFyeVBvc2l0aW9uLCBpc1N0YXJ0KSB7CiAgICAgICAgdmFyIGJvdW5kYXJ5Tm9kZSwgYm91bmRhcnlQYXJlbnQsIGJvdW5kYXJ5T2Zmc2V0ID0gYm91bmRhcnlQb3NpdGlvbi5vZmZzZXQ7CiAgICAgICAgdmFyIGRvYyA9IGRvbS5nZXREb2N1bWVudChib3VuZGFyeVBvc2l0aW9uLm5vZGUpOwogICAgICAgIHZhciB3b3JraW5nTm9kZSwgY2hpbGROb2Rlcywgd29ya2luZ1JhbmdlID0gZG9jLmJvZHkuY3JlYXRlVGV4dFJhbmdlKCk7CiAgICAgICAgdmFyIG5vZGVJc0RhdGFOb2RlID0gZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUoYm91bmRhcnlQb3NpdGlvbi5ub2RlKTsKCiAgICAgICAgaWYgKG5vZGVJc0RhdGFOb2RlKSB7CiAgICAgICAgICAgIGJvdW5kYXJ5Tm9kZSA9IGJvdW5kYXJ5UG9zaXRpb24ubm9kZTsKICAgICAgICAgICAgYm91bmRhcnlQYXJlbnQgPSBib3VuZGFyeU5vZGUucGFyZW50Tm9kZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjaGlsZE5vZGVzID0gYm91bmRhcnlQb3NpdGlvbi5ub2RlLmNoaWxkTm9kZXM7CiAgICAgICAgICAgIGJvdW5kYXJ5Tm9kZSA9IChib3VuZGFyeU9mZnNldCA8IGNoaWxkTm9kZXMubGVuZ3RoKSA/IGNoaWxkTm9kZXNbYm91bmRhcnlPZmZzZXRdIDogbnVsbDsKICAgICAgICAgICAgYm91bmRhcnlQYXJlbnQgPSBib3VuZGFyeVBvc2l0aW9uLm5vZGU7CiAgICAgICAgfQoKICAgICAgICAvLyBQb3NpdGlvbiB0aGUgcmFuZ2UgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBub2RlIGNvbnRhaW5pbmcgdGhlIGJvdW5kYXJ5CiAgICAgICAgd29ya2luZ05vZGUgPSBkb2MuY3JlYXRlRWxlbWVudCgic3BhbiIpOwoKICAgICAgICAvLyBNYWtpbmcgdGhlIHdvcmtpbmcgZWxlbWVudCBub24tZW1wdHkgZWxlbWVudCBwZXJzdWFkZXMgSUUgdG8gY29uc2lkZXIgdGhlIFRleHRSYW5nZSBib3VuZGFyeSB0byBiZSB3aXRoaW4gdGhlCiAgICAgICAgLy8gZWxlbWVudCByYXRoZXIgdGhhbiBpbW1lZGlhdGVseSBiZWZvcmUgb3IgYWZ0ZXIgaXQsIHdoaWNoIGlzIHdoYXQgd2Ugd2FudAogICAgICAgIHdvcmtpbmdOb2RlLmlubmVySFRNTCA9ICImI2ZlZmY7IjsKCiAgICAgICAgLy8gaW5zZXJ0QmVmb3JlIGlzIHN1cHBvc2VkIHRvIHdvcmsgbGlrZSBhcHBlbmRDaGlsZCBpZiB0aGUgc2Vjb25kIHBhcmFtZXRlciBpcyBudWxsLiBIb3dldmVyLCBhIGJ1ZyByZXBvcnQKICAgICAgICAvLyBmb3IgSUVSYW5nZSBzdWdnZXN0cyB0aGF0IGl0IGNhbiBjcmFzaCB0aGUgYnJvd3NlcjogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2llcmFuZ2UvaXNzdWVzL2RldGFpbD9pZD0xMgogICAgICAgIGlmIChib3VuZGFyeU5vZGUpIHsKICAgICAgICAgICAgYm91bmRhcnlQYXJlbnQuaW5zZXJ0QmVmb3JlKHdvcmtpbmdOb2RlLCBib3VuZGFyeU5vZGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGJvdW5kYXJ5UGFyZW50LmFwcGVuZENoaWxkKHdvcmtpbmdOb2RlKTsKICAgICAgICB9CgogICAgICAgIHdvcmtpbmdSYW5nZS5tb3ZlVG9FbGVtZW50VGV4dCh3b3JraW5nTm9kZSk7CiAgICAgICAgd29ya2luZ1JhbmdlLmNvbGxhcHNlKCFpc1N0YXJ0KTsKCiAgICAgICAgLy8gQ2xlYW4gdXAKICAgICAgICBib3VuZGFyeVBhcmVudC5yZW1vdmVDaGlsZCh3b3JraW5nTm9kZSk7CgogICAgICAgIC8vIE1vdmUgdGhlIHdvcmtpbmcgcmFuZ2UgdG8gdGhlIHRleHQgb2Zmc2V0LCBpZiByZXF1aXJlZAogICAgICAgIGlmIChub2RlSXNEYXRhTm9kZSkgewogICAgICAgICAgICB3b3JraW5nUmFuZ2VbaXNTdGFydCA/ICJtb3ZlU3RhcnQiIDogIm1vdmVFbmQiXSgiY2hhcmFjdGVyIiwgYm91bmRhcnlPZmZzZXQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHdvcmtpbmdSYW5nZTsKICAgIH0KCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIGlmIChhcGkuZmVhdHVyZXMuaW1wbGVtZW50c0RvbVJhbmdlICYmICghYXBpLmZlYXR1cmVzLmltcGxlbWVudHNUZXh0UmFuZ2UgfHwgIWFwaS5jb25maWcucHJlZmVyVGV4dFJhbmdlKSkgewogICAgICAgIC8vIFRoaXMgaXMgYSB3cmFwcGVyIGFyb3VuZCB0aGUgYnJvd3NlcidzIG5hdGl2ZSBET00gUmFuZ2UuIEl0IGhhcyB0d28gYWltczoKICAgICAgICAvLyAtIFByb3ZpZGUgd29ya2Fyb3VuZHMgZm9yIHNwZWNpZmljIGJyb3dzZXIgYnVncwogICAgICAgIC8vIC0gcHJvdmlkZSBjb252ZW5pZW50IGV4dGVuc2lvbnMsIHdoaWNoIGFyZSBpbmhlcml0ZWQgZnJvbSBSYW5neSdzIERvbVJhbmdlCgogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciByYW5nZVByb3RvOwogICAgICAgICAgICB2YXIgcmFuZ2VQcm9wZXJ0aWVzID0gRG9tUmFuZ2UucmFuZ2VQcm9wZXJ0aWVzOwogICAgICAgICAgICB2YXIgY2FuU2V0UmFuZ2VTdGFydEFmdGVyRW5kOwoKICAgICAgICAgICAgZnVuY3Rpb24gdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHJhbmdlKSB7CiAgICAgICAgICAgICAgICB2YXIgaSA9IHJhbmdlUHJvcGVydGllcy5sZW5ndGgsIHByb3A7CiAgICAgICAgICAgICAgICB3aGlsZSAoaS0tKSB7CiAgICAgICAgICAgICAgICAgICAgcHJvcCA9IHJhbmdlUHJvcGVydGllc1tpXTsKICAgICAgICAgICAgICAgICAgICByYW5nZVtwcm9wXSA9IHJhbmdlLm5hdGl2ZVJhbmdlW3Byb3BdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBmdW5jdGlvbiB1cGRhdGVOYXRpdmVSYW5nZShyYW5nZSwgc3RhcnRDb250YWluZXIsIHN0YXJ0T2Zmc2V0LCBlbmRDb250YWluZXIsIGVuZE9mZnNldCkgewogICAgICAgICAgICAgICAgdmFyIHN0YXJ0TW92ZWQgPSAocmFuZ2Uuc3RhcnRDb250YWluZXIgIT09IHN0YXJ0Q29udGFpbmVyIHx8IHJhbmdlLnN0YXJ0T2Zmc2V0ICE9IHN0YXJ0T2Zmc2V0KTsKICAgICAgICAgICAgICAgIHZhciBlbmRNb3ZlZCA9IChyYW5nZS5lbmRDb250YWluZXIgIT09IGVuZENvbnRhaW5lciB8fCByYW5nZS5lbmRPZmZzZXQgIT0gZW5kT2Zmc2V0KTsKCiAgICAgICAgICAgICAgICAvLyBBbHdheXMgc2V0IGJvdGggYm91bmRhcmllcyBmb3IgdGhlIGJlbmVmaXQgb2YgSUU5IChzZWUgaXNzdWUgMzUpCiAgICAgICAgICAgICAgICBpZiAoc3RhcnRNb3ZlZCB8fCBlbmRNb3ZlZCkgewogICAgICAgICAgICAgICAgICAgIHJhbmdlLnNldEVuZChlbmRDb250YWluZXIsIGVuZE9mZnNldCk7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2Uuc2V0U3RhcnQoc3RhcnRDb250YWluZXIsIHN0YXJ0T2Zmc2V0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgZnVuY3Rpb24gZGV0YWNoKHJhbmdlKSB7CiAgICAgICAgICAgICAgICByYW5nZS5uYXRpdmVSYW5nZS5kZXRhY2goKTsKICAgICAgICAgICAgICAgIHJhbmdlLmRldGFjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHZhciBpID0gcmFuZ2VQcm9wZXJ0aWVzLmxlbmd0aCwgcHJvcDsKICAgICAgICAgICAgICAgIHdoaWxlIChpLS0pIHsKICAgICAgICAgICAgICAgICAgICBwcm9wID0gcmFuZ2VQcm9wZXJ0aWVzW2ldOwogICAgICAgICAgICAgICAgICAgIHJhbmdlW3Byb3BdID0gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGNyZWF0ZUJlZm9yZUFmdGVyTm9kZVNldHRlcjsKCiAgICAgICAgICAgIFdyYXBwZWRSYW5nZSA9IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgICAgICAgICAgaWYgKCFyYW5nZSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiUmFuZ2UgbXVzdCBiZSBzcGVjaWZpZWQiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlUmFuZ2UgPSByYW5nZTsKICAgICAgICAgICAgICAgIHVwZGF0ZVJhbmdlUHJvcGVydGllcyh0aGlzKTsKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIERvbVJhbmdlLmNyZWF0ZVByb3RvdHlwZVJhbmdlKFdyYXBwZWRSYW5nZSwgdXBkYXRlTmF0aXZlUmFuZ2UsIGRldGFjaCk7CgogICAgICAgICAgICByYW5nZVByb3RvID0gV3JhcHBlZFJhbmdlLnByb3RvdHlwZTsKCiAgICAgICAgICAgIHJhbmdlUHJvdG8uc2VsZWN0Tm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZVJhbmdlLnNlbGVjdE5vZGUobm9kZSk7CiAgICAgICAgICAgICAgICB1cGRhdGVSYW5nZVByb3BlcnRpZXModGhpcyk7CiAgICAgICAgICAgIH07CgogICAgICAgICAgICByYW5nZVByb3RvLmRlbGV0ZUNvbnRlbnRzID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZS5kZWxldGVDb250ZW50cygpOwogICAgICAgICAgICAgICAgdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHRoaXMpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgcmFuZ2VQcm90by5leHRyYWN0Q29udGVudHMgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgZnJhZyA9IHRoaXMubmF0aXZlUmFuZ2UuZXh0cmFjdENvbnRlbnRzKCk7CiAgICAgICAgICAgICAgICB1cGRhdGVSYW5nZVByb3BlcnRpZXModGhpcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gZnJhZzsKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHJhbmdlUHJvdG8uY2xvbmVDb250ZW50cyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5hdGl2ZVJhbmdlLmNsb25lQ29udGVudHMoKTsKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIC8vIFRPRE86IFVudGlsIEkgY2FuIGZpbmQgYSB3YXkgdG8gcHJvZ3JhbW1hdGljYWxseSB0cmlnZ2VyIHRoZSBGaXJlZm94IGJ1ZyAoYXBwYXJlbnRseSBsb25nLXN0YW5kaW5nLCBzdGlsbAogICAgICAgICAgICAvLyBwcmVzZW50IGluIDMuNi44KSB0aGF0IHRocm93cyAiSW5kZXggb3Igc2l6ZSBpcyBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIGFsbG93ZWQgYW1vdW50IiBmb3IKICAgICAgICAgICAgLy8gaW5zZXJ0Tm9kZSBpbiBzb21lIGNpcmN1bXN0YW5jZXMsIGFsbCBicm93c2VycyB3aWxsIGhhdmUgdG8gdXNlIHRoZSBSYW5neSdzIG93biBpbXBsZW1lbnRhdGlvbiBvZgogICAgICAgICAgICAvLyBpbnNlcnROb2RlLCB3aGljaCB3b3JrcyBidXQgaXMgYWxtb3N0IGNlcnRhaW5seSBzbG93ZXIgdGhhbiB0aGUgbmF0aXZlIGltcGxlbWVudGF0aW9uLgogICAgICAgICAgICAvKgogICAgICAgICAgICAgcmFuZ2VQcm90by5pbnNlcnROb2RlID0gZnVuY3Rpb24obm9kZSkgewogICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZS5pbnNlcnROb2RlKG5vZGUpOwogICAgICAgICAgICAgdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHRoaXMpOwogICAgICAgICAgICAgfTsKICAgICAgICAgICAgICovCgogICAgICAgICAgICByYW5nZVByb3RvLnN1cnJvdW5kQ29udGVudHMgPSBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZS5zdXJyb3VuZENvbnRlbnRzKG5vZGUpOwogICAgICAgICAgICAgICAgdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHRoaXMpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgcmFuZ2VQcm90by5jb2xsYXBzZSA9IGZ1bmN0aW9uIChpc1N0YXJ0KSB7CiAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZVJhbmdlLmNvbGxhcHNlKGlzU3RhcnQpOwogICAgICAgICAgICAgICAgdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHRoaXMpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgcmFuZ2VQcm90by5jbG9uZVJhbmdlID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBXcmFwcGVkUmFuZ2UodGhpcy5uYXRpdmVSYW5nZS5jbG9uZVJhbmdlKCkpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgcmFuZ2VQcm90by5yZWZyZXNoID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHRoaXMpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgcmFuZ2VQcm90by50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5hdGl2ZVJhbmdlLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIH07CgogICAgICAgICAgICAvLyBDcmVhdGUgdGVzdCByYW5nZSBhbmQgbm9kZSBmb3IgZmVhdHVyZSBkZXRlY3Rpb24KCiAgICAgICAgICAgIHZhciB0ZXN0VGV4dE5vZGUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgidGVzdCIpOwogICAgICAgICAgICBkb20uZ2V0Qm9keShkb2N1bWVudCkuYXBwZW5kQ2hpbGQodGVzdFRleHROb2RlKTsKICAgICAgICAgICAgdmFyIHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTsKCiAgICAgICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgICAgICAgICAgLy8gVGVzdCBmb3IgRmlyZWZveCAyIGJ1ZyB0aGF0IHByZXZlbnRzIG1vdmluZyB0aGUgc3RhcnQgb2YgYSBSYW5nZSB0byBhIHBvaW50IGFmdGVyIGl0cyBjdXJyZW50IGVuZCBhbmQKICAgICAgICAgICAgLy8gY29ycmVjdCBmb3IgaXQKCiAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0KHRlc3RUZXh0Tm9kZSwgMCk7CiAgICAgICAgICAgIHJhbmdlLnNldEVuZCh0ZXN0VGV4dE5vZGUsIDApOwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0KHRlc3RUZXh0Tm9kZSwgMSk7CiAgICAgICAgICAgICAgICBjYW5TZXRSYW5nZVN0YXJ0QWZ0ZXJFbmQgPSB0cnVlOwoKICAgICAgICAgICAgICAgIHJhbmdlUHJvdG8uc2V0U3RhcnQgPSBmdW5jdGlvbiAobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZS5zZXRTdGFydChub2RlLCBvZmZzZXQpOwogICAgICAgICAgICAgICAgICAgIHVwZGF0ZVJhbmdlUHJvcGVydGllcyh0aGlzKTsKICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgcmFuZ2VQcm90by5zZXRFbmQgPSBmdW5jdGlvbiAobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZS5zZXRFbmQobm9kZSwgb2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICB1cGRhdGVSYW5nZVByb3BlcnRpZXModGhpcyk7CiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIGNyZWF0ZUJlZm9yZUFmdGVyTm9kZVNldHRlciA9IGZ1bmN0aW9uIChuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlUmFuZ2VbbmFtZV0obm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZVJhbmdlUHJvcGVydGllcyh0aGlzKTsKICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsKCiAgICAgICAgICAgICAgICBjYW5TZXRSYW5nZVN0YXJ0QWZ0ZXJFbmQgPSBmYWxzZTsKCiAgICAgICAgICAgICAgICByYW5nZVByb3RvLnNldFN0YXJ0ID0gZnVuY3Rpb24gKG5vZGUsIG9mZnNldCkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlUmFuZ2Uuc2V0U3RhcnQobm9kZSwgb2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZVJhbmdlLnNldEVuZChub2RlLCBvZmZzZXQpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZVJhbmdlLnNldFN0YXJ0KG5vZGUsIG9mZnNldCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHVwZGF0ZVJhbmdlUHJvcGVydGllcyh0aGlzKTsKICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgcmFuZ2VQcm90by5zZXRFbmQgPSBmdW5jdGlvbiAobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZS5zZXRFbmQobm9kZSwgb2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZVJhbmdlLnNldFN0YXJ0KG5vZGUsIG9mZnNldCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlUmFuZ2Uuc2V0RW5kKG5vZGUsIG9mZnNldCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHVwZGF0ZVJhbmdlUHJvcGVydGllcyh0aGlzKTsKICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgY3JlYXRlQmVmb3JlQWZ0ZXJOb2RlU2V0dGVyID0gZnVuY3Rpb24gKG5hbWUsIG9wcG9zaXRlTmFtZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZVtuYW1lXShub2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlUmFuZ2Vbb3Bwb3NpdGVOYW1lXShub2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlUmFuZ2VbbmFtZV0obm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHRoaXMpOwogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgICAgICByYW5nZVByb3RvLnNldFN0YXJ0QmVmb3JlID0gY3JlYXRlQmVmb3JlQWZ0ZXJOb2RlU2V0dGVyKCJzZXRTdGFydEJlZm9yZSIsICJzZXRFbmRCZWZvcmUiKTsKICAgICAgICAgICAgcmFuZ2VQcm90by5zZXRTdGFydEFmdGVyID0gY3JlYXRlQmVmb3JlQWZ0ZXJOb2RlU2V0dGVyKCJzZXRTdGFydEFmdGVyIiwgInNldEVuZEFmdGVyIik7CiAgICAgICAgICAgIHJhbmdlUHJvdG8uc2V0RW5kQmVmb3JlID0gY3JlYXRlQmVmb3JlQWZ0ZXJOb2RlU2V0dGVyKCJzZXRFbmRCZWZvcmUiLCAic2V0U3RhcnRCZWZvcmUiKTsKICAgICAgICAgICAgcmFuZ2VQcm90by5zZXRFbmRBZnRlciA9IGNyZWF0ZUJlZm9yZUFmdGVyTm9kZVNldHRlcigic2V0RW5kQWZ0ZXIiLCAic2V0U3RhcnRBZnRlciIpOwoKICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgogICAgICAgICAgICAvLyBUZXN0IGZvciBhbmQgY29ycmVjdCBGaXJlZm94IDIgYmVoYXZpb3VyIHdpdGggc2VsZWN0Tm9kZUNvbnRlbnRzIG9uIHRleHQgbm9kZXM6IGl0IGNvbGxhcHNlcyB0aGUgcmFuZ2UgdG8KICAgICAgICAgICAgLy8gdGhlIDB0aCBjaGFyYWN0ZXIgb2YgdGhlIHRleHQgbm9kZQogICAgICAgICAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHModGVzdFRleHROb2RlKTsKICAgICAgICAgICAgaWYgKHJhbmdlLnN0YXJ0Q29udGFpbmVyID09IHRlc3RUZXh0Tm9kZSAmJiByYW5nZS5lbmRDb250YWluZXIgPT0gdGVzdFRleHROb2RlICYmIHJhbmdlLnN0YXJ0T2Zmc2V0ID09IDAgJiYgcmFuZ2UuZW5kT2Zmc2V0ID09IHRlc3RUZXh0Tm9kZS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHJhbmdlUHJvdG8uc2VsZWN0Tm9kZUNvbnRlbnRzID0gZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZVJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhub2RlKTsKICAgICAgICAgICAgICAgICAgICB1cGRhdGVSYW5nZVByb3BlcnRpZXModGhpcyk7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmFuZ2VQcm90by5zZWxlY3ROb2RlQ29udGVudHMgPSBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhcnQobm9kZSwgMCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRFbmQobm9kZSwgRG9tUmFuZ2UuZ2V0RW5kT2Zmc2V0KG5vZGUpKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgICAgICAgICAgLy8gVGVzdCBmb3IgV2ViS2l0IGJ1ZyB0aGF0IGhhcyB0aGUgYmVhaHZpb3VyIG9mIGNvbXBhcmVCb3VuZGFyeVBvaW50cyByb3VuZCB0aGUgd3Jvbmcgd2F5IGZvciBjb25zdGFudHMKICAgICAgICAgICAgLy8gU1RBUlRfVE9fRU5EIGFuZCBFTkRfVE9fU1RBUlQ6IGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0yMDczOAoKICAgICAgICAgICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKHRlc3RUZXh0Tm9kZSk7CiAgICAgICAgICAgIHJhbmdlLnNldEVuZCh0ZXN0VGV4dE5vZGUsIDMpOwoKICAgICAgICAgICAgdmFyIHJhbmdlMiA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgICAgIHJhbmdlMi5zZWxlY3ROb2RlQ29udGVudHModGVzdFRleHROb2RlKTsKICAgICAgICAgICAgcmFuZ2UyLnNldEVuZCh0ZXN0VGV4dE5vZGUsIDQpOwogICAgICAgICAgICByYW5nZTIuc2V0U3RhcnQodGVzdFRleHROb2RlLCAyKTsKCiAgICAgICAgICAgIGlmIChyYW5nZS5jb21wYXJlQm91bmRhcnlQb2ludHMocmFuZ2UuU1RBUlRfVE9fRU5ELCByYW5nZTIpID09IC0xICYKICAgICAgICAgICAgICAgIHJhbmdlLmNvbXBhcmVCb3VuZGFyeVBvaW50cyhyYW5nZS5FTkRfVE9fU1RBUlQsIHJhbmdlMikgPT0gMSkgewogICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgd3Jvbmcgd2F5IHJvdW5kLCBzbyBjb3JyZWN0IGZvciBpdAoKICAgICAgICAgICAgICAgIHJhbmdlUHJvdG8uY29tcGFyZUJvdW5kYXJ5UG9pbnRzID0gZnVuY3Rpb24gKHR5cGUsIHJhbmdlKSB7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2UgPSByYW5nZS5uYXRpdmVSYW5nZSB8fCByYW5nZTsKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSByYW5nZS5TVEFSVF9UT19FTkQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IHJhbmdlLkVORF9UT19TVEFSVDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gcmFuZ2UuRU5EX1RPX1NUQVJUKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSByYW5nZS5TVEFSVF9UT19FTkQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5hdGl2ZVJhbmdlLmNvbXBhcmVCb3VuZGFyeVBvaW50cyh0eXBlLCByYW5nZSk7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmFuZ2VQcm90by5jb21wYXJlQm91bmRhcnlQb2ludHMgPSBmdW5jdGlvbiAodHlwZSwgcmFuZ2UpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uYXRpdmVSYW5nZS5jb21wYXJlQm91bmRhcnlQb2ludHModHlwZSwgcmFuZ2UubmF0aXZlUmFuZ2UgfHwgcmFuZ2UpOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgogICAgICAgICAgICAvLyBUZXN0IGZvciBleGlzdGVuY2Ugb2YgY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IGFuZCBkZWxlZ2F0ZSB0byBpdCBpZiBpdCBleGlzdHMKICAgICAgICAgICAgaWYgKGFwaS51dGlsLmlzSG9zdE1ldGhvZChyYW5nZSwgImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIpKSB7CiAgICAgICAgICAgICAgICByYW5nZVByb3RvLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCA9IGZ1bmN0aW9uIChmcmFnbWVudFN0cikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5hdGl2ZVJhbmdlLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChmcmFnbWVudFN0cik7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCiAgICAgICAgICAgIC8vIENsZWFuIHVwCiAgICAgICAgICAgIGRvbS5nZXRCb2R5KGRvY3VtZW50KS5yZW1vdmVDaGlsZCh0ZXN0VGV4dE5vZGUpOwogICAgICAgICAgICByYW5nZS5kZXRhY2goKTsKICAgICAgICAgICAgcmFuZ2UyLmRldGFjaCgpOwogICAgICAgIH0pKCk7CgogICAgICAgIGFwaS5jcmVhdGVOYXRpdmVSYW5nZSA9IGZ1bmN0aW9uIChkb2MpIHsKICAgICAgICAgICAgZG9jID0gZG9jIHx8IGRvY3VtZW50OwogICAgICAgICAgICByZXR1cm4gZG9jLmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgfTsKICAgIH0gZWxzZSBpZiAoYXBpLmZlYXR1cmVzLmltcGxlbWVudHNUZXh0UmFuZ2UpIHsKICAgICAgICAvLyBUaGlzIGlzIGEgd3JhcHBlciBhcm91bmQgYSBUZXh0UmFuZ2UsIHByb3ZpZGluZyBmdWxsIERPTSBSYW5nZSBmdW5jdGlvbmFsaXR5IHVzaW5nIHJhbmd5J3MgRG9tUmFuZ2UgYXMgYQogICAgICAgIC8vIHByb3RvdHlwZQoKICAgICAgICBXcmFwcGVkUmFuZ2UgPSBmdW5jdGlvbiAodGV4dFJhbmdlKSB7CiAgICAgICAgICAgIHRoaXMudGV4dFJhbmdlID0gdGV4dFJhbmdlOwogICAgICAgICAgICB0aGlzLnJlZnJlc2goKTsKICAgICAgICB9OwoKICAgICAgICBXcmFwcGVkUmFuZ2UucHJvdG90eXBlID0gbmV3IERvbVJhbmdlKGRvY3VtZW50KTsKCiAgICAgICAgV3JhcHBlZFJhbmdlLnByb3RvdHlwZS5yZWZyZXNoID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgc3RhcnQsIGVuZDsKCiAgICAgICAgICAgIC8vIFRleHRSYW5nZSdzIHBhcmVudEVsZW1lbnQoKSBtZXRob2QgY2Fubm90IGJlIHRydXN0ZWQuIGdldFRleHRSYW5nZUNvbnRhaW5lckVsZW1lbnQoKSB3b3JrcyBhcm91bmQgdGhhdC4KICAgICAgICAgICAgdmFyIHJhbmdlQ29udGFpbmVyRWxlbWVudCA9IGdldFRleHRSYW5nZUNvbnRhaW5lckVsZW1lbnQodGhpcy50ZXh0UmFuZ2UpOwoKICAgICAgICAgICAgaWYgKHRleHRSYW5nZUlzQ29sbGFwc2VkKHRoaXMudGV4dFJhbmdlKSkgewogICAgICAgICAgICAgICAgZW5kID0gc3RhcnQgPSBnZXRUZXh0UmFuZ2VCb3VuZGFyeVBvc2l0aW9uKHRoaXMudGV4dFJhbmdlLCByYW5nZUNvbnRhaW5lckVsZW1lbnQsIHRydWUsIHRydWUpOwogICAgICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgICAgIHN0YXJ0ID0gZ2V0VGV4dFJhbmdlQm91bmRhcnlQb3NpdGlvbih0aGlzLnRleHRSYW5nZSwgcmFuZ2VDb250YWluZXJFbGVtZW50LCB0cnVlLCBmYWxzZSk7CiAgICAgICAgICAgICAgICBlbmQgPSBnZXRUZXh0UmFuZ2VCb3VuZGFyeVBvc2l0aW9uKHRoaXMudGV4dFJhbmdlLCByYW5nZUNvbnRhaW5lckVsZW1lbnQsIGZhbHNlLCBmYWxzZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuc2V0U3RhcnQoc3RhcnQubm9kZSwgc3RhcnQub2Zmc2V0KTsKICAgICAgICAgICAgdGhpcy5zZXRFbmQoZW5kLm5vZGUsIGVuZC5vZmZzZXQpOwogICAgICAgIH07CgogICAgICAgIERvbVJhbmdlLmNvcHlDb21wYXJpc29uQ29uc3RhbnRzKFdyYXBwZWRSYW5nZSk7CgogICAgICAgIC8vIEFkZCBXcmFwcGVkUmFuZ2UgYXMgdGhlIFJhbmdlIHByb3BlcnR5IG9mIHRoZSBnbG9iYWwgb2JqZWN0IHRvIGFsbG93IGV4cHJlc3Npb24gbGlrZSBSYW5nZS5FTkRfVE9fRU5EIHRvIHdvcmsKICAgICAgICB2YXIgZ2xvYmFsT2JqID0gKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSkoKTsKICAgICAgICBpZiAodHlwZW9mIGdsb2JhbE9iai5SYW5nZSA9PSAidW5kZWZpbmVkIikgewogICAgICAgICAgICBnbG9iYWxPYmouUmFuZ2UgPSBXcmFwcGVkUmFuZ2U7CiAgICAgICAgfQoKICAgICAgICBhcGkuY3JlYXRlTmF0aXZlUmFuZ2UgPSBmdW5jdGlvbiAoZG9jKSB7CiAgICAgICAgICAgIGRvYyA9IGRvYyB8fCBkb2N1bWVudDsKICAgICAgICAgICAgcmV0dXJuIGRvYy5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpOwogICAgICAgIH07CiAgICB9CgogICAgaWYgKGFwaS5mZWF0dXJlcy5pbXBsZW1lbnRzVGV4dFJhbmdlKSB7CiAgICAgICAgV3JhcHBlZFJhbmdlLnJhbmdlVG9UZXh0UmFuZ2UgPSBmdW5jdGlvbiAocmFuZ2UpIHsKICAgICAgICAgICAgaWYgKHJhbmdlLmNvbGxhcHNlZCkgewogICAgICAgICAgICAgICAgdmFyIHRyID0gY3JlYXRlQm91bmRhcnlUZXh0UmFuZ2UobmV3IERvbVBvc2l0aW9uKHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydE9mZnNldCksIHRydWUpOwoKICAgICAgICAgICAgICAgIHJldHVybiB0cjsKCiAgICAgICAgICAgICAgICAvL3JldHVybiBjcmVhdGVCb3VuZGFyeVRleHRSYW5nZShuZXcgRG9tUG9zaXRpb24ocmFuZ2Uuc3RhcnRDb250YWluZXIsIHJhbmdlLnN0YXJ0T2Zmc2V0KSwgdHJ1ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgc3RhcnRSYW5nZSA9IGNyZWF0ZUJvdW5kYXJ5VGV4dFJhbmdlKG5ldyBEb21Qb3NpdGlvbihyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpLCB0cnVlKTsKICAgICAgICAgICAgICAgIHZhciBlbmRSYW5nZSA9IGNyZWF0ZUJvdW5kYXJ5VGV4dFJhbmdlKG5ldyBEb21Qb3NpdGlvbihyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCksIGZhbHNlKTsKICAgICAgICAgICAgICAgIHZhciB0ZXh0UmFuZ2UgPSBkb20uZ2V0RG9jdW1lbnQocmFuZ2Uuc3RhcnRDb250YWluZXIpLmJvZHkuY3JlYXRlVGV4dFJhbmdlKCk7CiAgICAgICAgICAgICAgICB0ZXh0UmFuZ2Uuc2V0RW5kUG9pbnQoIlN0YXJ0VG9TdGFydCIsIHN0YXJ0UmFuZ2UpOwogICAgICAgICAgICAgICAgdGV4dFJhbmdlLnNldEVuZFBvaW50KCJFbmRUb0VuZCIsIGVuZFJhbmdlKTsKICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0UmFuZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfQoKICAgIFdyYXBwZWRSYW5nZS5wcm90b3R5cGUuZ2V0TmFtZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gIldyYXBwZWRSYW5nZSI7CiAgICB9OwoKICAgIGFwaS5XcmFwcGVkUmFuZ2UgPSBXcmFwcGVkUmFuZ2U7CgogICAgYXBpLmNyZWF0ZVJhbmdlID0gZnVuY3Rpb24gKGRvYykgewogICAgICAgIGRvYyA9IGRvYyB8fCBkb2N1bWVudDsKICAgICAgICByZXR1cm4gbmV3IFdyYXBwZWRSYW5nZShhcGkuY3JlYXRlTmF0aXZlUmFuZ2UoZG9jKSk7CiAgICB9OwoKICAgIGFwaS5jcmVhdGVSYW5neVJhbmdlID0gZnVuY3Rpb24gKGRvYykgewogICAgICAgIGRvYyA9IGRvYyB8fCBkb2N1bWVudDsKICAgICAgICByZXR1cm4gbmV3IERvbVJhbmdlKGRvYyk7CiAgICB9OwoKICAgIGFwaS5jcmVhdGVJZnJhbWVSYW5nZSA9IGZ1bmN0aW9uIChpZnJhbWVFbCkgewogICAgICAgIHJldHVybiBhcGkuY3JlYXRlUmFuZ2UoZG9tLmdldElmcmFtZURvY3VtZW50KGlmcmFtZUVsKSk7CiAgICB9OwoKICAgIGFwaS5jcmVhdGVJZnJhbWVSYW5neVJhbmdlID0gZnVuY3Rpb24gKGlmcmFtZUVsKSB7CiAgICAgICAgcmV0dXJuIGFwaS5jcmVhdGVSYW5neVJhbmdlKGRvbS5nZXRJZnJhbWVEb2N1bWVudChpZnJhbWVFbCkpOwogICAgfTsKCiAgICBhcGkuYWRkQ3JlYXRlTWlzc2luZ05hdGl2ZUFwaUxpc3RlbmVyKGZ1bmN0aW9uICh3aW4pIHsKICAgICAgICB2YXIgZG9jID0gd2luLmRvY3VtZW50OwogICAgICAgIGlmICh0eXBlb2YgZG9jLmNyZWF0ZVJhbmdlID09ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgIGRvYy5jcmVhdGVSYW5nZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhcGkuY3JlYXRlUmFuZ2UodGhpcyk7CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGRvYyA9IHdpbiA9IG51bGw7CiAgICB9KTsKfSk7CnJhbmd5LmNyZWF0ZU1vZHVsZSgiV3JhcHBlZFNlbGVjdGlvbiIsIGZ1bmN0aW9uIChhcGksIG1vZHVsZSkgewogICAgLy8gVGhpcyB3aWxsIGNyZWF0ZSBhIHNlbGVjdGlvbiBvYmplY3Qgd3JhcHBlciB0aGF0IGZvbGxvd3MgdGhlIFNlbGVjdGlvbiBvYmplY3QgZm91bmQgaW4gdGhlIFdIQVRXRyBkcmFmdCBET00gUmFuZ2UKICAgIC8vIHNwZWMgKGh0dHA6Ly9odG1sNS5vcmcvc3BlY3MvZG9tLXJhbmdlLmh0bWwpCgogICAgYXBpLnJlcXVpcmVNb2R1bGVzKFsiRG9tVXRpbCIsICJEb21SYW5nZSIsICJXcmFwcGVkUmFuZ2UiXSk7CgogICAgYXBpLmNvbmZpZy5jaGVja1NlbGVjdGlvblJhbmdlcyA9IHRydWU7CgogICAgdmFyIEJPT0xFQU4gPSAiYm9vbGVhbiIsCiAgICAgICAgd2luZG93UHJvcGVydHlOYW1lID0gIl9yYW5neVNlbGVjdGlvbiIsCiAgICAgICAgZG9tID0gYXBpLmRvbSwKICAgICAgICB1dGlsID0gYXBpLnV0aWwsCiAgICAgICAgRG9tUmFuZ2UgPSBhcGkuRG9tUmFuZ2UsCiAgICAgICAgV3JhcHBlZFJhbmdlID0gYXBpLldyYXBwZWRSYW5nZSwKICAgICAgICBET01FeGNlcHRpb24gPSBhcGkuRE9NRXhjZXB0aW9uLAogICAgICAgIERvbVBvc2l0aW9uID0gZG9tLkRvbVBvc2l0aW9uLAogICAgICAgIGdldFNlbGVjdGlvbiwKICAgICAgICBzZWxlY3Rpb25Jc0NvbGxhcHNlZCwKICAgICAgICBDT05UUk9MID0gIkNvbnRyb2wiOwoKICAgIGZ1bmN0aW9uIGdldFdpblNlbGVjdGlvbih3aW5QYXJhbSkgewogICAgICAgIHJldHVybiAod2luUGFyYW0gfHwgd2luZG93KS5nZXRTZWxlY3Rpb24oKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXREb2NTZWxlY3Rpb24od2luUGFyYW0pIHsKICAgICAgICByZXR1cm4gKHdpblBhcmFtIHx8IHdpbmRvdykuZG9jdW1lbnQuc2VsZWN0aW9uOwogICAgfQoKICAgIC8vIFRlc3QgZm9yIHRoZSBSYW5nZS9UZXh0UmFuZ2UgYW5kIFNlbGVjdGlvbiBmZWF0dXJlcyByZXF1aXJlZAogICAgLy8gVGVzdCBmb3IgYWJpbGl0eSB0byByZXRyaWV2ZSBzZWxlY3Rpb24KICAgIHZhciBpbXBsZW1lbnRzV2luR2V0U2VsZWN0aW9uID0gYXBpLnV0aWwuaXNIb3N0TWV0aG9kKHdpbmRvdywgImdldFNlbGVjdGlvbiIpLAogICAgICAgIGltcGxlbWVudHNEb2NTZWxlY3Rpb24gPSBhcGkudXRpbC5pc0hvc3RPYmplY3QoZG9jdW1lbnQsICJzZWxlY3Rpb24iKTsKCiAgICB2YXIgdXNlRG9jdW1lbnRTZWxlY3Rpb24gPSBpbXBsZW1lbnRzRG9jU2VsZWN0aW9uICYmICghaW1wbGVtZW50c1dpbkdldFNlbGVjdGlvbiB8fCBhcGkuY29uZmlnLnByZWZlclRleHRSYW5nZSk7CgogICAgaWYgKHVzZURvY3VtZW50U2VsZWN0aW9uKSB7CiAgICAgICAgZ2V0U2VsZWN0aW9uID0gZ2V0RG9jU2VsZWN0aW9uOwogICAgICAgIGFwaS5pc1NlbGVjdGlvblZhbGlkID0gZnVuY3Rpb24gKHdpblBhcmFtKSB7CiAgICAgICAgICAgIHZhciBkb2MgPSAod2luUGFyYW0gfHwgd2luZG93KS5kb2N1bWVudCwgbmF0aXZlU2VsID0gZG9jLnNlbGVjdGlvbjsKCiAgICAgICAgICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIHNlbGVjdGlvbiBUZXh0UmFuZ2UgaXMgYWN0dWFsbHkgY29udGFpbmVkIHdpdGhpbiB0aGUgY29ycmVjdCBkb2N1bWVudAogICAgICAgICAgICByZXR1cm4gKG5hdGl2ZVNlbC50eXBlICE9ICJOb25lIiB8fCBkb20uZ2V0RG9jdW1lbnQobmF0aXZlU2VsLmNyZWF0ZVJhbmdlKCkucGFyZW50RWxlbWVudCgpKSA9PSBkb2MpOwogICAgICAgIH07CiAgICB9IGVsc2UgaWYgKGltcGxlbWVudHNXaW5HZXRTZWxlY3Rpb24pIHsKICAgICAgICBnZXRTZWxlY3Rpb24gPSBnZXRXaW5TZWxlY3Rpb247CiAgICAgICAgYXBpLmlzU2VsZWN0aW9uVmFsaWQgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIG1vZHVsZS5mYWlsKCJOZWl0aGVyIGRvY3VtZW50LnNlbGVjdGlvbiBvciB3aW5kb3cuZ2V0U2VsZWN0aW9uKCkgZGV0ZWN0ZWQuIik7CiAgICB9CgogICAgYXBpLmdldE5hdGl2ZVNlbGVjdGlvbiA9IGdldFNlbGVjdGlvbjsKCiAgICB2YXIgdGVzdFNlbGVjdGlvbiA9IGdldFNlbGVjdGlvbigpOwogICAgdmFyIHRlc3RSYW5nZSA9IGFwaS5jcmVhdGVOYXRpdmVSYW5nZShkb2N1bWVudCk7CiAgICB2YXIgYm9keSA9IGRvbS5nZXRCb2R5KGRvY3VtZW50KTsKCiAgICAvLyBPYnRhaW5pbmcgYSByYW5nZSBmcm9tIGEgc2VsZWN0aW9uCiAgICB2YXIgc2VsZWN0aW9uSGFzQW5jaG9yQW5kRm9jdXMgPSB1dGlsLmFyZUhvc3RPYmplY3RzKHRlc3RTZWxlY3Rpb24sIFsiYW5jaG9yTm9kZSIsICJmb2N1c05vZGUiXSAmJiB1dGlsLmFyZUhvc3RQcm9wZXJ0aWVzKHRlc3RTZWxlY3Rpb24sIFsiYW5jaG9yT2Zmc2V0IiwgImZvY3VzT2Zmc2V0Il0pKTsKICAgIGFwaS5mZWF0dXJlcy5zZWxlY3Rpb25IYXNBbmNob3JBbmRGb2N1cyA9IHNlbGVjdGlvbkhhc0FuY2hvckFuZEZvY3VzOwoKICAgIC8vIFRlc3QgZm9yIGV4aXN0ZW5jZSBvZiBuYXRpdmUgc2VsZWN0aW9uIGV4dGVuZCgpIG1ldGhvZAogICAgdmFyIHNlbGVjdGlvbkhhc0V4dGVuZCA9IHV0aWwuaXNIb3N0TWV0aG9kKHRlc3RTZWxlY3Rpb24sICJleHRlbmQiKTsKICAgIGFwaS5mZWF0dXJlcy5zZWxlY3Rpb25IYXNFeHRlbmQgPSBzZWxlY3Rpb25IYXNFeHRlbmQ7CgogICAgLy8gVGVzdCBpZiByYW5nZUNvdW50IGV4aXN0cwogICAgdmFyIHNlbGVjdGlvbkhhc1JhbmdlQ291bnQgPSAodHlwZW9mIHRlc3RTZWxlY3Rpb24ucmFuZ2VDb3VudCA9PSAibnVtYmVyIik7CiAgICBhcGkuZmVhdHVyZXMuc2VsZWN0aW9uSGFzUmFuZ2VDb3VudCA9IHNlbGVjdGlvbkhhc1JhbmdlQ291bnQ7CgogICAgdmFyIHNlbGVjdGlvblN1cHBvcnRzTXVsdGlwbGVSYW5nZXMgPSBmYWxzZTsKICAgIHZhciBjb2xsYXBzZWROb25FZGl0YWJsZVNlbGVjdGlvbnNTdXBwb3J0ZWQgPSB0cnVlOwoKICAgIGlmICh1dGlsLmFyZUhvc3RNZXRob2RzKHRlc3RTZWxlY3Rpb24sIFsiYWRkUmFuZ2UiLCAiZ2V0UmFuZ2VBdCIsICJyZW1vdmVBbGxSYW5nZXMiXSkgJiYgdHlwZW9mIHRlc3RTZWxlY3Rpb24ucmFuZ2VDb3VudCA9PSAibnVtYmVyIiAmJiBhcGkuZmVhdHVyZXMuaW1wbGVtZW50c0RvbVJhbmdlKSB7CgogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJpZnJhbWUiKTsKICAgICAgICAgICAgYm9keS5hcHBlbmRDaGlsZChpZnJhbWUpOwoKICAgICAgICAgICAgdmFyIGlmcmFtZURvYyA9IGRvbS5nZXRJZnJhbWVEb2N1bWVudChpZnJhbWUpOwogICAgICAgICAgICBpZnJhbWVEb2Mub3BlbigpOwogICAgICAgICAgICBpZnJhbWVEb2Mud3JpdGUoIjxodG1sPjxoZWFkPjwvaGVhZD48Ym9keT4xMjwvYm9keT48L2h0bWw+Iik7CiAgICAgICAgICAgIGlmcmFtZURvYy5jbG9zZSgpOwoKICAgICAgICAgICAgdmFyIHNlbCA9IGRvbS5nZXRJZnJhbWVXaW5kb3coaWZyYW1lKS5nZXRTZWxlY3Rpb24oKTsKICAgICAgICAgICAgdmFyIGRvY0VsID0gaWZyYW1lRG9jLmRvY3VtZW50RWxlbWVudDsKICAgICAgICAgICAgdmFyIGlmcmFtZUJvZHkgPSBkb2NFbC5sYXN0Q2hpbGQsIHRleHROb2RlID0gaWZyYW1lQm9keS5maXJzdENoaWxkOwoKICAgICAgICAgICAgLy8gVGVzdCB3aGV0aGVyIHRoZSBuYXRpdmUgc2VsZWN0aW9uIHdpbGwgYWxsb3cgYSBjb2xsYXBzZWQgc2VsZWN0aW9uIHdpdGhpbiBhIG5vbi1lZGl0YWJsZSBlbGVtZW50CiAgICAgICAgICAgIHZhciByMSA9IGlmcmFtZURvYy5jcmVhdGVSYW5nZSgpOwogICAgICAgICAgICByMS5zZXRTdGFydCh0ZXh0Tm9kZSwgMSk7CiAgICAgICAgICAgIHIxLmNvbGxhcHNlKHRydWUpOwogICAgICAgICAgICBzZWwuYWRkUmFuZ2UocjEpOwogICAgICAgICAgICBjb2xsYXBzZWROb25FZGl0YWJsZVNlbGVjdGlvbnNTdXBwb3J0ZWQgPSAoc2VsLnJhbmdlQ291bnQgPT0gMSk7CiAgICAgICAgICAgIHNlbC5yZW1vdmVBbGxSYW5nZXMoKTsKCiAgICAgICAgICAgIC8vIFRlc3Qgd2hldGhlciB0aGUgbmF0aXZlIHNlbGVjdGlvbiBpcyBjYXBhYmxlIG9mIHN1cHBvcnRpbmcgbXVsdGlwbGUgcmFuZ2VzCiAgICAgICAgICAgIHZhciByMiA9IHIxLmNsb25lUmFuZ2UoKTsKICAgICAgICAgICAgcjEuc2V0U3RhcnQodGV4dE5vZGUsIDApOwogICAgICAgICAgICByMi5zZXRFbmQodGV4dE5vZGUsIDIpOwogICAgICAgICAgICBzZWwuYWRkUmFuZ2UocjEpOwogICAgICAgICAgICBzZWwuYWRkUmFuZ2UocjIpOwoKICAgICAgICAgICAgc2VsZWN0aW9uU3VwcG9ydHNNdWx0aXBsZVJhbmdlcyA9IChzZWwucmFuZ2VDb3VudCA9PSAyKTsKCiAgICAgICAgICAgIC8vIENsZWFuIHVwCiAgICAgICAgICAgIHIxLmRldGFjaCgpOwogICAgICAgICAgICByMi5kZXRhY2goKTsKCiAgICAgICAgICAgIGJvZHkucmVtb3ZlQ2hpbGQoaWZyYW1lKTsKICAgICAgICB9KSgpOwogICAgfQoKICAgIGFwaS5mZWF0dXJlcy5zZWxlY3Rpb25TdXBwb3J0c011bHRpcGxlUmFuZ2VzID0gc2VsZWN0aW9uU3VwcG9ydHNNdWx0aXBsZVJhbmdlczsKICAgIGFwaS5mZWF0dXJlcy5jb2xsYXBzZWROb25FZGl0YWJsZVNlbGVjdGlvbnNTdXBwb3J0ZWQgPSBjb2xsYXBzZWROb25FZGl0YWJsZVNlbGVjdGlvbnNTdXBwb3J0ZWQ7CgogICAgLy8gQ29udHJvbFJhbmdlcwogICAgdmFyIGltcGxlbWVudHNDb250cm9sUmFuZ2UgPSBmYWxzZSwgdGVzdENvbnRyb2xSYW5nZTsKCiAgICBpZiAoYm9keSAmJiB1dGlsLmlzSG9zdE1ldGhvZChib2R5LCAiY3JlYXRlQ29udHJvbFJhbmdlIikpIHsKICAgICAgICB0ZXN0Q29udHJvbFJhbmdlID0gYm9keS5jcmVhdGVDb250cm9sUmFuZ2UoKTsKICAgICAgICBpZiAodXRpbC5hcmVIb3N0UHJvcGVydGllcyh0ZXN0Q29udHJvbFJhbmdlLCBbIml0ZW0iLCAiYWRkIl0pKSB7CiAgICAgICAgICAgIGltcGxlbWVudHNDb250cm9sUmFuZ2UgPSB0cnVlOwogICAgICAgIH0KICAgIH0KICAgIGFwaS5mZWF0dXJlcy5pbXBsZW1lbnRzQ29udHJvbFJhbmdlID0gaW1wbGVtZW50c0NvbnRyb2xSYW5nZTsKCiAgICAvLyBTZWxlY3Rpb24gY29sbGFwc2VkbmVzcwogICAgaWYgKHNlbGVjdGlvbkhhc0FuY2hvckFuZEZvY3VzKSB7CiAgICAgICAgc2VsZWN0aW9uSXNDb2xsYXBzZWQgPSBmdW5jdGlvbiAoc2VsKSB7CiAgICAgICAgICAgIHJldHVybiBzZWwuYW5jaG9yTm9kZSA9PT0gc2VsLmZvY3VzTm9kZSAmJiBzZWwuYW5jaG9yT2Zmc2V0ID09PSBzZWwuZm9jdXNPZmZzZXQ7CiAgICAgICAgfTsKICAgIH0gZWxzZSB7CiAgICAgICAgc2VsZWN0aW9uSXNDb2xsYXBzZWQgPSBmdW5jdGlvbiAoc2VsKSB7CiAgICAgICAgICAgIHJldHVybiBzZWwucmFuZ2VDb3VudCA/IHNlbC5nZXRSYW5nZUF0KHNlbC5yYW5nZUNvdW50IC0gMSkuY29sbGFwc2VkIDogZmFsc2U7CiAgICAgICAgfTsKICAgIH0KCiAgICBmdW5jdGlvbiB1cGRhdGVBbmNob3JBbmRGb2N1c0Zyb21SYW5nZShzZWwsIHJhbmdlLCBiYWNrd2FyZHMpIHsKICAgICAgICB2YXIgYW5jaG9yUHJlZml4ID0gYmFja3dhcmRzID8gImVuZCIgOiAic3RhcnQiLCBmb2N1c1ByZWZpeCA9IGJhY2t3YXJkcyA/ICJzdGFydCIgOiAiZW5kIjsKICAgICAgICBzZWwuYW5jaG9yTm9kZSA9IHJhbmdlW2FuY2hvclByZWZpeCArICJDb250YWluZXIiXTsKICAgICAgICBzZWwuYW5jaG9yT2Zmc2V0ID0gcmFuZ2VbYW5jaG9yUHJlZml4ICsgIk9mZnNldCJdOwogICAgICAgIHNlbC5mb2N1c05vZGUgPSByYW5nZVtmb2N1c1ByZWZpeCArICJDb250YWluZXIiXTsKICAgICAgICBzZWwuZm9jdXNPZmZzZXQgPSByYW5nZVtmb2N1c1ByZWZpeCArICJPZmZzZXQiXTsKICAgIH0KCiAgICBmdW5jdGlvbiB1cGRhdGVBbmNob3JBbmRGb2N1c0Zyb21OYXRpdmVTZWxlY3Rpb24oc2VsKSB7CiAgICAgICAgdmFyIG5hdGl2ZVNlbCA9IHNlbC5uYXRpdmVTZWxlY3Rpb247CiAgICAgICAgc2VsLmFuY2hvck5vZGUgPSBuYXRpdmVTZWwuYW5jaG9yTm9kZTsKICAgICAgICBzZWwuYW5jaG9yT2Zmc2V0ID0gbmF0aXZlU2VsLmFuY2hvck9mZnNldDsKICAgICAgICBzZWwuZm9jdXNOb2RlID0gbmF0aXZlU2VsLmZvY3VzTm9kZTsKICAgICAgICBzZWwuZm9jdXNPZmZzZXQgPSBuYXRpdmVTZWwuZm9jdXNPZmZzZXQ7CiAgICB9CgogICAgZnVuY3Rpb24gdXBkYXRlRW1wdHlTZWxlY3Rpb24oc2VsKSB7CiAgICAgICAgc2VsLmFuY2hvck5vZGUgPSBzZWwuZm9jdXNOb2RlID0gbnVsbDsKICAgICAgICBzZWwuYW5jaG9yT2Zmc2V0ID0gc2VsLmZvY3VzT2Zmc2V0ID0gMDsKICAgICAgICBzZWwucmFuZ2VDb3VudCA9IDA7CiAgICAgICAgc2VsLmlzQ29sbGFwc2VkID0gdHJ1ZTsKICAgICAgICBzZWwuX3Jhbmdlcy5sZW5ndGggPSAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldE5hdGl2ZVJhbmdlKHJhbmdlKSB7CiAgICAgICAgdmFyIG5hdGl2ZVJhbmdlOwogICAgICAgIGlmIChyYW5nZSBpbnN0YW5jZW9mIERvbVJhbmdlKSB7CiAgICAgICAgICAgIG5hdGl2ZVJhbmdlID0gcmFuZ2UuX3NlbGVjdGlvbk5hdGl2ZVJhbmdlOwogICAgICAgICAgICBpZiAoIW5hdGl2ZVJhbmdlKSB7CiAgICAgICAgICAgICAgICBuYXRpdmVSYW5nZSA9IGFwaS5jcmVhdGVOYXRpdmVSYW5nZShkb20uZ2V0RG9jdW1lbnQocmFuZ2Uuc3RhcnRDb250YWluZXIpKTsKICAgICAgICAgICAgICAgIG5hdGl2ZVJhbmdlLnNldEVuZChyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCk7CiAgICAgICAgICAgICAgICBuYXRpdmVSYW5nZS5zZXRTdGFydChyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICAgICAgcmFuZ2UuX3NlbGVjdGlvbk5hdGl2ZVJhbmdlID0gbmF0aXZlUmFuZ2U7CiAgICAgICAgICAgICAgICByYW5nZS5hdHRhY2hMaXN0ZW5lcigiZGV0YWNoIiwgZnVuY3Rpb24gKCkgewoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZWxlY3Rpb25OYXRpdmVSYW5nZSA9IG51bGw7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAocmFuZ2UgaW5zdGFuY2VvZiBXcmFwcGVkUmFuZ2UpIHsKICAgICAgICAgICAgbmF0aXZlUmFuZ2UgPSByYW5nZS5uYXRpdmVSYW5nZTsKICAgICAgICB9IGVsc2UgaWYgKGFwaS5mZWF0dXJlcy5pbXBsZW1lbnRzRG9tUmFuZ2UgJiYgKHJhbmdlIGluc3RhbmNlb2YgZG9tLmdldFdpbmRvdyhyYW5nZS5zdGFydENvbnRhaW5lcikuUmFuZ2UpKSB7CiAgICAgICAgICAgIG5hdGl2ZVJhbmdlID0gcmFuZ2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuYXRpdmVSYW5nZTsKICAgIH0KCiAgICBmdW5jdGlvbiByYW5nZUNvbnRhaW5zU2luZ2xlRWxlbWVudChyYW5nZU5vZGVzKSB7CiAgICAgICAgaWYgKCFyYW5nZU5vZGVzLmxlbmd0aCB8fCByYW5nZU5vZGVzWzBdLm5vZGVUeXBlICE9IDEpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmb3IgKHZhciBpID0gMSwgbGVuID0gcmFuZ2VOb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgIGlmICghZG9tLmlzQW5jZXN0b3JPZihyYW5nZU5vZGVzWzBdLCByYW5nZU5vZGVzW2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldFNpbmdsZUVsZW1lbnRGcm9tUmFuZ2UocmFuZ2UpIHsKICAgICAgICB2YXIgbm9kZXMgPSByYW5nZS5nZXROb2RlcygpOwogICAgICAgIGlmICghcmFuZ2VDb250YWluc1NpbmdsZUVsZW1lbnQobm9kZXMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiZ2V0U2luZ2xlRWxlbWVudEZyb21SYW5nZTogcmFuZ2UgIiArIHJhbmdlLmluc3BlY3QoKSArICIgZGlkIG5vdCBjb25zaXN0IG9mIGEgc2luZ2xlIGVsZW1lbnQiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5vZGVzWzBdOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzVGV4dFJhbmdlKHJhbmdlKSB7CiAgICAgICAgcmV0dXJuICEhcmFuZ2UgJiYgdHlwZW9mIHJhbmdlLnRleHQgIT0gInVuZGVmaW5lZCI7CiAgICB9CgogICAgZnVuY3Rpb24gdXBkYXRlRnJvbVRleHRSYW5nZShzZWwsIHJhbmdlKSB7CiAgICAgICAgLy8gQ3JlYXRlIGEgUmFuZ2UgZnJvbSB0aGUgc2VsZWN0ZWQgVGV4dFJhbmdlCiAgICAgICAgdmFyIHdyYXBwZWRSYW5nZSA9IG5ldyBXcmFwcGVkUmFuZ2UocmFuZ2UpOwogICAgICAgIHNlbC5fcmFuZ2VzID0gW3dyYXBwZWRSYW5nZV07CgogICAgICAgIHVwZGF0ZUFuY2hvckFuZEZvY3VzRnJvbVJhbmdlKHNlbCwgd3JhcHBlZFJhbmdlLCBmYWxzZSk7CiAgICAgICAgc2VsLnJhbmdlQ291bnQgPSAxOwogICAgICAgIHNlbC5pc0NvbGxhcHNlZCA9IHdyYXBwZWRSYW5nZS5jb2xsYXBzZWQ7CiAgICB9CgogICAgZnVuY3Rpb24gdXBkYXRlQ29udHJvbFNlbGVjdGlvbihzZWwpIHsKICAgICAgICAvLyBVcGRhdGUgdGhlIHdyYXBwZWQgc2VsZWN0aW9uIGJhc2VkIG9uIHdoYXQncyBub3cgaW4gdGhlIG5hdGl2ZSBzZWxlY3Rpb24KICAgICAgICBzZWwuX3Jhbmdlcy5sZW5ndGggPSAwOwogICAgICAgIGlmIChzZWwuZG9jU2VsZWN0aW9uLnR5cGUgPT0gIk5vbmUiKSB7CiAgICAgICAgICAgIHVwZGF0ZUVtcHR5U2VsZWN0aW9uKHNlbCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdmFyIGNvbnRyb2xSYW5nZSA9IHNlbC5kb2NTZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTsKICAgICAgICAgICAgaWYgKGlzVGV4dFJhbmdlKGNvbnRyb2xSYW5nZSkpIHsKICAgICAgICAgICAgICAgIC8vIFRoaXMgY2FzZSAod2hlcmUgdGhlIHNlbGVjdGlvbiB0eXBlIGlzICJDb250cm9sIiBhbmQgY2FsbGluZyBjcmVhdGVSYW5nZSgpIG9uIHRoZSBzZWxlY3Rpb24gcmV0dXJucwogICAgICAgICAgICAgICAgLy8gYSBUZXh0UmFuZ2UpIGNhbiBoYXBwZW4gaW4gSUUgOS4gSXQgaGFwcGVucywgZm9yIGV4YW1wbGUsIHdoZW4gYWxsIGVsZW1lbnRzIGluIHRoZSBzZWxlY3RlZAogICAgICAgICAgICAgICAgLy8gQ29udHJvbFJhbmdlIGhhdmUgYmVlbiByZW1vdmVkIGZyb20gdGhlIENvbnRyb2xSYW5nZSBhbmQgcmVtb3ZlZCBmcm9tIHRoZSBkb2N1bWVudC4KICAgICAgICAgICAgICAgIHVwZGF0ZUZyb21UZXh0UmFuZ2Uoc2VsLCBjb250cm9sUmFuZ2UpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2VsLnJhbmdlQ291bnQgPSBjb250cm9sUmFuZ2UubGVuZ3RoOwogICAgICAgICAgICAgICAgdmFyIHJhbmdlLCBkb2MgPSBkb20uZ2V0RG9jdW1lbnQoY29udHJvbFJhbmdlLml0ZW0oMCkpOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7CiAgICAgICAgICAgICAgICAgICAgIGkgPCBzZWwucmFuZ2VDb3VudDsKICAgICAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2UgPSBhcGkuY3JlYXRlUmFuZ2UoZG9jKTsKICAgICAgICAgICAgICAgICAgICByYW5nZS5zZWxlY3ROb2RlKGNvbnRyb2xSYW5nZS5pdGVtKGkpKTsKICAgICAgICAgICAgICAgICAgICBzZWwuX3Jhbmdlcy5wdXNoKHJhbmdlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNlbC5pc0NvbGxhcHNlZCA9IHNlbC5yYW5nZUNvdW50ID09IDEgJiYgc2VsLl9yYW5nZXNbMF0uY29sbGFwc2VkOwogICAgICAgICAgICAgICAgdXBkYXRlQW5jaG9yQW5kRm9jdXNGcm9tUmFuZ2Uoc2VsLCBzZWwuX3Jhbmdlc1tzZWwucmFuZ2VDb3VudCAtIDFdLCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gYWRkUmFuZ2VUb0NvbnRyb2xTZWxlY3Rpb24oc2VsLCByYW5nZSkgewogICAgICAgIHZhciBjb250cm9sUmFuZ2UgPSBzZWwuZG9jU2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgdmFyIHJhbmdlRWxlbWVudCA9IGdldFNpbmdsZUVsZW1lbnRGcm9tUmFuZ2UocmFuZ2UpOwoKICAgICAgICAvLyBDcmVhdGUgYSBuZXcgQ29udHJvbFJhbmdlIGNvbnRhaW5pbmcgYWxsIHRoZSBlbGVtZW50cyBpbiB0aGUgc2VsZWN0ZWQgQ29udHJvbFJhbmdlIHBsdXMgdGhlIGVsZW1lbnQKICAgICAgICAvLyBjb250YWluZWQgYnkgdGhlIHN1cHBsaWVkIHJhbmdlCiAgICAgICAgdmFyIGRvYyA9IGRvbS5nZXREb2N1bWVudChjb250cm9sUmFuZ2UuaXRlbSgwKSk7CiAgICAgICAgdmFyIG5ld0NvbnRyb2xSYW5nZSA9IGRvbS5nZXRCb2R5KGRvYykuY3JlYXRlQ29udHJvbFJhbmdlKCk7CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNvbnRyb2xSYW5nZS5sZW5ndGg7CiAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgIG5ld0NvbnRyb2xSYW5nZS5hZGQoY29udHJvbFJhbmdlLml0ZW0oaSkpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgICBuZXdDb250cm9sUmFuZ2UuYWRkKHJhbmdlRWxlbWVudCk7CiAgICAgICAgfSBjYXRjaCAoZXgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJhZGRSYW5nZSgpOiBFbGVtZW50IHdpdGhpbiB0aGUgc3BlY2lmaWVkIFJhbmdlIGNvdWxkIG5vdCBiZSBhZGRlZCB0byBjb250cm9sIHNlbGVjdGlvbiAoZG9lcyBpdCBoYXZlIGxheW91dD8pIik7CiAgICAgICAgfQogICAgICAgIG5ld0NvbnRyb2xSYW5nZS5zZWxlY3QoKTsKCiAgICAgICAgLy8gVXBkYXRlIHRoZSB3cmFwcGVkIHNlbGVjdGlvbiBiYXNlZCBvbiB3aGF0J3Mgbm93IGluIHRoZSBuYXRpdmUgc2VsZWN0aW9uCiAgICAgICAgdXBkYXRlQ29udHJvbFNlbGVjdGlvbihzZWwpOwogICAgfQoKICAgIHZhciBnZXRTZWxlY3Rpb25SYW5nZUF0OwoKICAgIGlmICh1dGlsLmlzSG9zdE1ldGhvZCh0ZXN0U2VsZWN0aW9uLCAiZ2V0UmFuZ2VBdCIpKSB7CiAgICAgICAgZ2V0U2VsZWN0aW9uUmFuZ2VBdCA9IGZ1bmN0aW9uIChzZWwsIGluZGV4KSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsLmdldFJhbmdlQXQoaW5kZXgpOwogICAgICAgICAgICB9IGNhdGNoIChleCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfSBlbHNlIGlmIChzZWxlY3Rpb25IYXNBbmNob3JBbmRGb2N1cykgewogICAgICAgIGdldFNlbGVjdGlvblJhbmdlQXQgPSBmdW5jdGlvbiAoc2VsKSB7CiAgICAgICAgICAgIHZhciBkb2MgPSBkb20uZ2V0RG9jdW1lbnQoc2VsLmFuY2hvck5vZGUpOwogICAgICAgICAgICB2YXIgcmFuZ2UgPSBhcGkuY3JlYXRlUmFuZ2UoZG9jKTsKICAgICAgICAgICAgcmFuZ2Uuc2V0U3RhcnQoc2VsLmFuY2hvck5vZGUsIHNlbC5hbmNob3JPZmZzZXQpOwogICAgICAgICAgICByYW5nZS5zZXRFbmQoc2VsLmZvY3VzTm9kZSwgc2VsLmZvY3VzT2Zmc2V0KTsKCiAgICAgICAgICAgIC8vIEhhbmRsZSB0aGUgY2FzZSB3aGVuIHRoZSBzZWxlY3Rpb24gd2FzIHNlbGVjdGVkIGJhY2t3YXJkcyAoZnJvbSB0aGUgZW5kIHRvIHRoZSBzdGFydCBpbiB0aGUKICAgICAgICAgICAgLy8gZG9jdW1lbnQpCiAgICAgICAgICAgIGlmIChyYW5nZS5jb2xsYXBzZWQgIT09IHRoaXMuaXNDb2xsYXBzZWQpIHsKICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0KHNlbC5mb2N1c05vZGUsIHNlbC5mb2N1c09mZnNldCk7CiAgICAgICAgICAgICAgICByYW5nZS5zZXRFbmQoc2VsLmFuY2hvck5vZGUsIHNlbC5hbmNob3JPZmZzZXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gcmFuZ2U7CiAgICAgICAgfTsKICAgIH0KCiAgICAvKioKICAgICAqIEBjb25zdHJ1Y3RvcgogICAgICovCiAgICBmdW5jdGlvbiBXcmFwcGVkU2VsZWN0aW9uKHNlbGVjdGlvbiwgZG9jU2VsZWN0aW9uLCB3aW4pIHsKICAgICAgICB0aGlzLm5hdGl2ZVNlbGVjdGlvbiA9IHNlbGVjdGlvbjsKICAgICAgICB0aGlzLmRvY1NlbGVjdGlvbiA9IGRvY1NlbGVjdGlvbjsKICAgICAgICB0aGlzLl9yYW5nZXMgPSBbXTsKICAgICAgICB0aGlzLndpbiA9IHdpbjsKICAgICAgICB0aGlzLnJlZnJlc2goKTsKICAgIH0KCiAgICBhcGkuZ2V0U2VsZWN0aW9uID0gZnVuY3Rpb24gKHdpbikgewogICAgICAgIHdpbiA9IHdpbiB8fCB3aW5kb3c7CiAgICAgICAgdmFyIHNlbCA9IHdpblt3aW5kb3dQcm9wZXJ0eU5hbWVdOwogICAgICAgIHZhciBuYXRpdmVTZWwgPSBnZXRTZWxlY3Rpb24od2luKSwgZG9jU2VsID0gaW1wbGVtZW50c0RvY1NlbGVjdGlvbiA/IGdldERvY1NlbGVjdGlvbih3aW4pIDogbnVsbDsKICAgICAgICBpZiAoc2VsKSB7CiAgICAgICAgICAgIHNlbC5uYXRpdmVTZWxlY3Rpb24gPSBuYXRpdmVTZWw7CiAgICAgICAgICAgIHNlbC5kb2NTZWxlY3Rpb24gPSBkb2NTZWw7CiAgICAgICAgICAgIHNlbC5yZWZyZXNoKHdpbik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2VsID0gbmV3IFdyYXBwZWRTZWxlY3Rpb24obmF0aXZlU2VsLCBkb2NTZWwsIHdpbik7CiAgICAgICAgICAgIHdpblt3aW5kb3dQcm9wZXJ0eU5hbWVdID0gc2VsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsOwogICAgfTsKCiAgICBhcGkuZ2V0U2VsZWN0aW9uV2l0aG91dFJlZmVyc2ggPSBmdW5jdGlvbiAod2luKSB7CiAgICAgICAgd2luID0gd2luIHx8IHdpbmRvdzsKICAgICAgICB2YXIgc2VsID0gd2luW3dpbmRvd1Byb3BlcnR5TmFtZV07CiAgICAgICAgdmFyIG5hdGl2ZVNlbCA9IGdldFNlbGVjdGlvbih3aW4pLCBkb2NTZWwgPSBpbXBsZW1lbnRzRG9jU2VsZWN0aW9uID8gZ2V0RG9jU2VsZWN0aW9uKHdpbikgOiBudWxsOwogICAgICAgIGlmIChzZWwpIHsKICAgICAgICAgICAgc2VsLm5hdGl2ZVNlbGVjdGlvbiA9IG5hdGl2ZVNlbDsKICAgICAgICAgICAgc2VsLmRvY1NlbGVjdGlvbiA9IGRvY1NlbDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzZWwgPSBuZXcgV3JhcHBlZFNlbGVjdGlvbihuYXRpdmVTZWwsIGRvY1NlbCwgd2luKTsKICAgICAgICAgICAgd2luW3dpbmRvd1Byb3BlcnR5TmFtZV0gPSBzZWw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWw7CiAgICB9OwoKICAgIGFwaS5nZXRJZnJhbWVTZWxlY3Rpb24gPSBmdW5jdGlvbiAoaWZyYW1lRWwpIHsKICAgICAgICByZXR1cm4gYXBpLmdldFNlbGVjdGlvbihkb20uZ2V0SWZyYW1lV2luZG93KGlmcmFtZUVsKSk7CiAgICB9OwoKICAgIHZhciBzZWxQcm90byA9IFdyYXBwZWRTZWxlY3Rpb24ucHJvdG90eXBlOwoKICAgIGZ1bmN0aW9uIGNyZWF0ZUNvbnRyb2xTZWxlY3Rpb24oc2VsLCByYW5nZXMpIHsKICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGUgc2VsZWN0aW9uIGJlY29tZXMgb2YgdHlwZSAiQ29udHJvbCIKICAgICAgICB2YXIgZG9jID0gZG9tLmdldERvY3VtZW50KHJhbmdlc1swXS5zdGFydENvbnRhaW5lcik7CiAgICAgICAgdmFyIGNvbnRyb2xSYW5nZSA9IGRvbS5nZXRCb2R5KGRvYykuY3JlYXRlQ29udHJvbFJhbmdlKCk7CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGVsOwogICAgICAgICAgICAgaSA8IHJhbmdlQ291bnQ7CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgZWwgPSBnZXRTaW5nbGVFbGVtZW50RnJvbVJhbmdlKHJhbmdlc1tpXSk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBjb250cm9sUmFuZ2UuYWRkKGVsKTsKICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigic2V0UmFuZ2VzKCk6IEVsZW1lbnQgd2l0aGluIHRoZSBvbmUgb2YgdGhlIHNwZWNpZmllZCBSYW5nZXMgY291bGQgbm90IGJlIGFkZGVkIHRvIGNvbnRyb2wgc2VsZWN0aW9uIChkb2VzIGl0IGhhdmUgbGF5b3V0PykiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb250cm9sUmFuZ2Uuc2VsZWN0KCk7CgogICAgICAgIC8vIFVwZGF0ZSB0aGUgd3JhcHBlZCBzZWxlY3Rpb24gYmFzZWQgb24gd2hhdCdzIG5vdyBpbiB0aGUgbmF0aXZlIHNlbGVjdGlvbgogICAgICAgIHVwZGF0ZUNvbnRyb2xTZWxlY3Rpb24oc2VsKTsKICAgIH0KCiAgICAvLyBTZWxlY3RpbmcgYSByYW5nZQogICAgaWYgKCF1c2VEb2N1bWVudFNlbGVjdGlvbiAmJiBzZWxlY3Rpb25IYXNBbmNob3JBbmRGb2N1cyAmJiB1dGlsLmFyZUhvc3RNZXRob2RzKHRlc3RTZWxlY3Rpb24sIFsicmVtb3ZlQWxsUmFuZ2VzIiwgImFkZFJhbmdlIl0pKSB7CiAgICAgICAgc2VsUHJvdG8ucmVtb3ZlQWxsUmFuZ2VzID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLm5hdGl2ZVNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTsKICAgICAgICAgICAgdXBkYXRlRW1wdHlTZWxlY3Rpb24odGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgdmFyIGFkZFJhbmdlQmFja3dhcmRzID0gZnVuY3Rpb24gKHNlbCwgcmFuZ2UpIHsKICAgICAgICAgICAgdmFyIGRvYyA9IERvbVJhbmdlLmdldFJhbmdlRG9jdW1lbnQocmFuZ2UpOwogICAgICAgICAgICB2YXIgZW5kUmFuZ2UgPSBhcGkuY3JlYXRlUmFuZ2UoZG9jKTsKICAgICAgICAgICAgZW5kUmFuZ2UuY29sbGFwc2VUb1BvaW50KHJhbmdlLmVuZENvbnRhaW5lciwgcmFuZ2UuZW5kT2Zmc2V0KTsKICAgICAgICAgICAgc2VsLm5hdGl2ZVNlbGVjdGlvbi5hZGRSYW5nZShnZXROYXRpdmVSYW5nZShlbmRSYW5nZSkpOwogICAgICAgICAgICBzZWwubmF0aXZlU2VsZWN0aW9uLmV4dGVuZChyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICBzZWwucmVmcmVzaCgpOwogICAgICAgIH07CgogICAgICAgIGlmIChzZWxlY3Rpb25IYXNSYW5nZUNvdW50KSB7CiAgICAgICAgICAgIHNlbFByb3RvLmFkZFJhbmdlID0gZnVuY3Rpb24gKHJhbmdlLCBiYWNrd2FyZHMpIHsKICAgICAgICAgICAgICAgIGlmIChpbXBsZW1lbnRzQ29udHJvbFJhbmdlICYmIGltcGxlbWVudHNEb2NTZWxlY3Rpb24gJiYgdGhpcy5kb2NTZWxlY3Rpb24udHlwZSA9PSBDT05UUk9MKSB7CiAgICAgICAgICAgICAgICAgICAgYWRkUmFuZ2VUb0NvbnRyb2xTZWxlY3Rpb24odGhpcywgcmFuZ2UpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYmFja3dhcmRzICYmIHNlbGVjdGlvbkhhc0V4dGVuZCkgewogICAgICAgICAgICAgICAgICAgICAgICBhZGRSYW5nZUJhY2t3YXJkcyh0aGlzLCByYW5nZSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHByZXZpb3VzUmFuZ2VDb3VudDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvblN1cHBvcnRzTXVsdGlwbGVSYW5nZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzUmFuZ2VDb3VudCA9IHRoaXMucmFuZ2VDb3VudDsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlQWxsUmFuZ2VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c1JhbmdlQ291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlU2VsZWN0aW9uLmFkZFJhbmdlKGdldE5hdGl2ZVJhbmdlKHJhbmdlKSk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayB3aGV0aGVyIGFkZGluZyB0aGUgcmFuZ2Ugd2FzIHN1Y2Nlc3NmdWwKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yYW5nZUNvdW50ID0gdGhpcy5uYXRpdmVTZWxlY3Rpb24ucmFuZ2VDb3VudDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJhbmdlQ291bnQgPT0gcHJldmlvdXNSYW5nZUNvdW50ICsgMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHJhbmdlIHdhcyBhZGRlZCBzdWNjZXNzZnVsbHkKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSByYW5nZSB0aGF0IHdlIGFkZGVkIHRvIHRoZSBzZWxlY3Rpb24gaXMgcmVmbGVjdGVkIGluIHRoZSBsYXN0IHJhbmdlIGV4dHJhY3RlZCBmcm9tCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgc2VsZWN0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXBpLmNvbmZpZy5jaGVja1NlbGVjdGlvblJhbmdlcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuYXRpdmVSYW5nZSA9IGdldFNlbGVjdGlvblJhbmdlQXQodGhpcy5uYXRpdmVTZWxlY3Rpb24sIHRoaXMucmFuZ2VDb3VudCAtIDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVSYW5nZSAmJiAhRG9tUmFuZ2UucmFuZ2VzRXF1YWwobmF0aXZlUmFuZ2UsIHJhbmdlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIYXBwZW5zIGluIFdlYktpdCB3aXRoLCBmb3IgZXhhbXBsZSwgYSBzZWxlY3Rpb24gcGxhY2VkIGF0IHRoZSBzdGFydCBvZiBhIHRleHQgbm9kZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZSA9IG5ldyBXcmFwcGVkUmFuZ2UobmF0aXZlUmFuZ2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Jhbmdlc1t0aGlzLnJhbmdlQ291bnQgLSAxXSA9IHJhbmdlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlQW5jaG9yQW5kRm9jdXNGcm9tUmFuZ2UodGhpcywgcmFuZ2UsIHNlbGVjdGlvbklzQmFja3dhcmRzKHRoaXMubmF0aXZlU2VsZWN0aW9uKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzQ29sbGFwc2VkID0gc2VsZWN0aW9uSXNDb2xsYXBzZWQodGhpcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgcmFuZ2Ugd2FzIG5vdCBhZGRlZCBzdWNjZXNzZnVsbHkuIFRoZSBzaW1wbGVzdCB0aGluZyBpcyB0byByZWZyZXNoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlZnJlc2goKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzZWxQcm90by5hZGRSYW5nZSA9IGZ1bmN0aW9uIChyYW5nZSwgYmFja3dhcmRzKSB7CiAgICAgICAgICAgICAgICBpZiAoYmFja3dhcmRzICYmIHNlbGVjdGlvbkhhc0V4dGVuZCkgewogICAgICAgICAgICAgICAgICAgIGFkZFJhbmdlQmFja3dhcmRzKHRoaXMsIHJhbmdlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVTZWxlY3Rpb24uYWRkUmFuZ2UoZ2V0TmF0aXZlUmFuZ2UocmFuZ2UpKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnJlZnJlc2goKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIHNlbFByb3RvLnNldFJhbmdlcyA9IGZ1bmN0aW9uIChyYW5nZXMpIHsKICAgICAgICAgICAgaWYgKGltcGxlbWVudHNDb250cm9sUmFuZ2UgJiYgcmFuZ2VzLmxlbmd0aCA+IDEpIHsKICAgICAgICAgICAgICAgIGNyZWF0ZUNvbnRyb2xTZWxlY3Rpb24odGhpcywgcmFuZ2VzKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlQWxsUmFuZ2VzKCk7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gcmFuZ2VzLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRSYW5nZShyYW5nZXNbaV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIH0gZWxzZSBpZiAodXRpbC5pc0hvc3RNZXRob2QodGVzdFNlbGVjdGlvbiwgImVtcHR5IikgJiYgdXRpbC5pc0hvc3RNZXRob2QodGVzdFJhbmdlLCAic2VsZWN0IikgJiYgaW1wbGVtZW50c0NvbnRyb2xSYW5nZSAmJiB1c2VEb2N1bWVudFNlbGVjdGlvbikgewoKICAgICAgICBzZWxQcm90by5yZW1vdmVBbGxSYW5nZXMgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vIEFkZGVkIHRyeS9jYXRjaCBhcyBmaXggZm9yIGlzc3VlICMyMQogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5kb2NTZWxlY3Rpb24uZW1wdHkoKTsKCiAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgZW1wdHkoKSBub3Qgd29ya2luZyAoaXNzdWUgIzI0KQogICAgICAgICAgICAgICAgaWYgKHRoaXMuZG9jU2VsZWN0aW9uLnR5cGUgIT0gIk5vbmUiKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gV29yayBhcm91bmQgZmFpbHVyZSB0byBlbXB0eSBhIGNvbnRyb2wgc2VsZWN0aW9uIGJ5IGluc3RlYWQgc2VsZWN0aW5nIGEgVGV4dFJhbmdlIGFuZCB0aGVuCiAgICAgICAgICAgICAgICAgICAgLy8gY2FsbGluZyBlbXB0eSgpCiAgICAgICAgICAgICAgICAgICAgdmFyIGRvYzsKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5hbmNob3JOb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvYyA9IGRvbS5nZXREb2N1bWVudCh0aGlzLmFuY2hvck5vZGUpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5kb2NTZWxlY3Rpb24udHlwZSA9PSBDT05UUk9MKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250cm9sUmFuZ2UgPSB0aGlzLmRvY1NlbGVjdGlvbi5jcmVhdGVSYW5nZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29udHJvbFJhbmdlLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jID0gZG9tLmdldERvY3VtZW50KGNvbnRyb2xSYW5nZS5pdGVtKDApKS5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChkb2MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRSYW5nZSA9IGRvYy5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB0ZXh0UmFuZ2Uuc2VsZWN0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZG9jU2VsZWN0aW9uLmVtcHR5KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChleCkgewogICAgICAgICAgICB9CiAgICAgICAgICAgIHVwZGF0ZUVtcHR5U2VsZWN0aW9uKHRoaXMpOwogICAgICAgIH07CgogICAgICAgIHNlbFByb3RvLmFkZFJhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgICAgIGlmICh0aGlzLmRvY1NlbGVjdGlvbi50eXBlID09IENPTlRST0wpIHsKICAgICAgICAgICAgICAgIGFkZFJhbmdlVG9Db250cm9sU2VsZWN0aW9uKHRoaXMsIHJhbmdlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFdyYXBwZWRSYW5nZS5yYW5nZVRvVGV4dFJhbmdlKHJhbmdlKS5zZWxlY3QoKTsKICAgICAgICAgICAgICAgIHRoaXMuX3Jhbmdlc1swXSA9IHJhbmdlOwogICAgICAgICAgICAgICAgdGhpcy5yYW5nZUNvdW50ID0gMTsKICAgICAgICAgICAgICAgIHRoaXMuaXNDb2xsYXBzZWQgPSB0aGlzLl9yYW5nZXNbMF0uY29sbGFwc2VkOwogICAgICAgICAgICAgICAgdXBkYXRlQW5jaG9yQW5kRm9jdXNGcm9tUmFuZ2UodGhpcywgcmFuZ2UsIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIHNlbFByb3RvLnNldFJhbmdlcyA9IGZ1bmN0aW9uIChyYW5nZXMpIHsKICAgICAgICAgICAgdGhpcy5yZW1vdmVBbGxSYW5nZXMoKTsKICAgICAgICAgICAgdmFyIHJhbmdlQ291bnQgPSByYW5nZXMubGVuZ3RoOwogICAgICAgICAgICBpZiAocmFuZ2VDb3VudCA+IDEpIHsKICAgICAgICAgICAgICAgIGNyZWF0ZUNvbnRyb2xTZWxlY3Rpb24odGhpcywgcmFuZ2VzKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChyYW5nZUNvdW50KSB7CiAgICAgICAgICAgICAgICB0aGlzLmFkZFJhbmdlKHJhbmdlc1swXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfSBlbHNlIHsKICAgICAgICBtb2R1bGUuZmFpbCgiTm8gbWVhbnMgb2Ygc2VsZWN0aW5nIGEgUmFuZ2Ugb3IgVGV4dFJhbmdlIHdhcyBmb3VuZCIpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBzZWxQcm90by5nZXRSYW5nZUF0ID0gZnVuY3Rpb24gKGluZGV4KSB7CiAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSB0aGlzLnJhbmdlQ291bnQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigiSU5ERVhfU0laRV9FUlIiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gdGhpcy5fcmFuZ2VzW2luZGV4XTsKICAgICAgICB9CiAgICB9OwoKICAgIHZhciByZWZyZXNoU2VsZWN0aW9uOwoKICAgIGlmICh1c2VEb2N1bWVudFNlbGVjdGlvbikgewogICAgICAgIHJlZnJlc2hTZWxlY3Rpb24gPSBmdW5jdGlvbiAoc2VsKSB7CiAgICAgICAgICAgIHZhciByYW5nZTsKICAgICAgICAgICAgaWYgKGFwaS5pc1NlbGVjdGlvblZhbGlkKHNlbC53aW4pKSB7CiAgICAgICAgICAgICAgICByYW5nZSA9IHNlbC5kb2NTZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJhbmdlID0gZG9tLmdldEJvZHkoc2VsLndpbi5kb2N1bWVudCkuY3JlYXRlVGV4dFJhbmdlKCk7CiAgICAgICAgICAgICAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHNlbC5kb2NTZWxlY3Rpb24udHlwZSA9PSBDT05UUk9MKSB7CiAgICAgICAgICAgICAgICB1cGRhdGVDb250cm9sU2VsZWN0aW9uKHNlbCk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNUZXh0UmFuZ2UocmFuZ2UpKSB7CiAgICAgICAgICAgICAgICB1cGRhdGVGcm9tVGV4dFJhbmdlKHNlbCwgcmFuZ2UpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdXBkYXRlRW1wdHlTZWxlY3Rpb24oc2VsKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9IGVsc2UgaWYgKHV0aWwuaXNIb3N0TWV0aG9kKHRlc3RTZWxlY3Rpb24sICJnZXRSYW5nZUF0IikgJiYgdHlwZW9mIHRlc3RTZWxlY3Rpb24ucmFuZ2VDb3VudCA9PSAibnVtYmVyIikgewogICAgICAgIHJlZnJlc2hTZWxlY3Rpb24gPSBmdW5jdGlvbiAoc2VsKSB7CiAgICAgICAgICAgIGlmIChpbXBsZW1lbnRzQ29udHJvbFJhbmdlICYmIGltcGxlbWVudHNEb2NTZWxlY3Rpb24gJiYgc2VsLmRvY1NlbGVjdGlvbi50eXBlID09IENPTlRST0wpIHsKICAgICAgICAgICAgICAgIHVwZGF0ZUNvbnRyb2xTZWxlY3Rpb24oc2VsKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNlbC5fcmFuZ2VzLmxlbmd0aCA9IHNlbC5yYW5nZUNvdW50ID0gc2VsLm5hdGl2ZVNlbGVjdGlvbiA/IHNlbC5uYXRpdmVTZWxlY3Rpb24ucmFuZ2VDb3VudCA6IG51bGw7CiAgICAgICAgICAgICAgICBpZiAoc2VsLnJhbmdlQ291bnQpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gc2VsLnJhbmdlQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbC5fcmFuZ2VzW2ldID0gbmV3IGFwaS5XcmFwcGVkUmFuZ2Uoc2VsLm5hdGl2ZVNlbGVjdGlvbi5nZXRSYW5nZUF0KGkpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdXBkYXRlQW5jaG9yQW5kRm9jdXNGcm9tUmFuZ2Uoc2VsLCBzZWwuX3Jhbmdlc1tzZWwucmFuZ2VDb3VudCAtIDFdLCBzZWxlY3Rpb25Jc0JhY2t3YXJkcyhzZWwubmF0aXZlU2VsZWN0aW9uKSk7CiAgICAgICAgICAgICAgICAgICAgc2VsLmlzQ29sbGFwc2VkID0gc2VsZWN0aW9uSXNDb2xsYXBzZWQoc2VsKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdXBkYXRlRW1wdHlTZWxlY3Rpb24oc2VsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9IGVsc2UgaWYgKHNlbGVjdGlvbkhhc0FuY2hvckFuZEZvY3VzICYmIHR5cGVvZiB0ZXN0U2VsZWN0aW9uLmlzQ29sbGFwc2VkID09IEJPT0xFQU4gJiYgdHlwZW9mIHRlc3RSYW5nZS5jb2xsYXBzZWQgPT0gQk9PTEVBTiAmJiBhcGkuZmVhdHVyZXMuaW1wbGVtZW50c0RvbVJhbmdlKSB7CiAgICAgICAgcmVmcmVzaFNlbGVjdGlvbiA9IGZ1bmN0aW9uIChzZWwpIHsKICAgICAgICAgICAgdmFyIHJhbmdlLCBuYXRpdmVTZWwgPSBzZWwubmF0aXZlU2VsZWN0aW9uOwogICAgICAgICAgICBpZiAobmF0aXZlU2VsLmFuY2hvck5vZGUpIHsKICAgICAgICAgICAgICAgIHJhbmdlID0gZ2V0U2VsZWN0aW9uUmFuZ2VBdChuYXRpdmVTZWwsIDApOwogICAgICAgICAgICAgICAgc2VsLl9yYW5nZXMgPSBbcmFuZ2VdOwogICAgICAgICAgICAgICAgc2VsLnJhbmdlQ291bnQgPSAxOwogICAgICAgICAgICAgICAgdXBkYXRlQW5jaG9yQW5kRm9jdXNGcm9tTmF0aXZlU2VsZWN0aW9uKHNlbCk7CiAgICAgICAgICAgICAgICBzZWwuaXNDb2xsYXBzZWQgPSBzZWxlY3Rpb25Jc0NvbGxhcHNlZChzZWwpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdXBkYXRlRW1wdHlTZWxlY3Rpb24oc2VsKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIG1vZHVsZS5mYWlsKCJObyBtZWFucyBvZiBvYnRhaW5pbmcgYSBSYW5nZSBvciBUZXh0UmFuZ2UgZnJvbSB0aGUgdXNlcidzIHNlbGVjdGlvbiB3YXMgZm91bmQiKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgc2VsUHJvdG8ucmVmcmVzaCA9IGZ1bmN0aW9uIChjaGVja0ZvckNoYW5nZXMpIHsKICAgICAgICB2YXIgb2xkUmFuZ2VzID0gY2hlY2tGb3JDaGFuZ2VzID8gdGhpcy5fcmFuZ2VzLnNsaWNlKDApIDogbnVsbDsKICAgICAgICByZWZyZXNoU2VsZWN0aW9uKHRoaXMpOwogICAgICAgIGlmIChjaGVja0ZvckNoYW5nZXMpIHsKICAgICAgICAgICAgdmFyIGkgPSBvbGRSYW5nZXMubGVuZ3RoOwogICAgICAgICAgICBpZiAoaSAhPSB0aGlzLl9yYW5nZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgd2hpbGUgKGktLSkgewogICAgICAgICAgICAgICAgaWYgKCFEb21SYW5nZS5yYW5nZXNFcXVhbChvbGRSYW5nZXNbaV0sIHRoaXMuX3Jhbmdlc1tpXSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfTsKCiAgICAvLyBSZW1vdmFsIG9mIGEgc2luZ2xlIHJhbmdlCiAgICB2YXIgcmVtb3ZlUmFuZ2VNYW51YWxseSA9IGZ1bmN0aW9uIChzZWwsIHJhbmdlKSB7CiAgICAgICAgdmFyIHJhbmdlcyA9IHNlbC5nZXRBbGxSYW5nZXMoKSwgcmVtb3ZlZCA9IGZhbHNlOwogICAgICAgIHNlbC5yZW1vdmVBbGxSYW5nZXMoKTsKICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gcmFuZ2VzLmxlbmd0aDsKICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgaWYgKHJlbW92ZWQgfHwgcmFuZ2UgIT09IHJhbmdlc1tpXSkgewogICAgICAgICAgICAgICAgc2VsLmFkZFJhbmdlKHJhbmdlc1tpXSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBBY2NvcmRpbmcgdG8gdGhlIGRyYWZ0IFdIQVRXRyBSYW5nZSBzcGVjLCB0aGUgc2FtZSByYW5nZSBtYXkgYmUgYWRkZWQgdG8gdGhlIHNlbGVjdGlvbiBtdWx0aXBsZQogICAgICAgICAgICAgICAgLy8gdGltZXMuIHJlbW92ZVJhbmdlIHNob3VsZCBvbmx5IHJlbW92ZSB0aGUgZmlyc3QgaW5zdGFuY2UsIHNvIHRoZSBmb2xsb3dpbmcgZW5zdXJlcyBvbmx5IHRoZSBmaXJzdAogICAgICAgICAgICAgICAgLy8gaW5zdGFuY2UgaXMgcmVtb3ZlZAogICAgICAgICAgICAgICAgcmVtb3ZlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCFzZWwucmFuZ2VDb3VudCkgewogICAgICAgICAgICB1cGRhdGVFbXB0eVNlbGVjdGlvbihzZWwpOwogICAgICAgIH0KICAgIH07CgogICAgaWYgKGltcGxlbWVudHNDb250cm9sUmFuZ2UpIHsKICAgICAgICBzZWxQcm90by5yZW1vdmVSYW5nZSA9IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgICAgICBpZiAodGhpcy5kb2NTZWxlY3Rpb24udHlwZSA9PSBDT05UUk9MKSB7CiAgICAgICAgICAgICAgICB2YXIgY29udHJvbFJhbmdlID0gdGhpcy5kb2NTZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTsKICAgICAgICAgICAgICAgIHZhciByYW5nZUVsZW1lbnQgPSBnZXRTaW5nbGVFbGVtZW50RnJvbVJhbmdlKHJhbmdlKTsKCiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgQ29udHJvbFJhbmdlIGNvbnRhaW5pbmcgYWxsIHRoZSBlbGVtZW50cyBpbiB0aGUgc2VsZWN0ZWQgQ29udHJvbFJhbmdlIG1pbnVzIHRoZQogICAgICAgICAgICAgICAgLy8gZWxlbWVudCBjb250YWluZWQgYnkgdGhlIHN1cHBsaWVkIHJhbmdlCiAgICAgICAgICAgICAgICB2YXIgZG9jID0gZG9tLmdldERvY3VtZW50KGNvbnRyb2xSYW5nZS5pdGVtKDApKTsKICAgICAgICAgICAgICAgIHZhciBuZXdDb250cm9sUmFuZ2UgPSBkb20uZ2V0Qm9keShkb2MpLmNyZWF0ZUNvbnRyb2xSYW5nZSgpOwogICAgICAgICAgICAgICAgdmFyIGVsLCByZW1vdmVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gY29udHJvbFJhbmdlLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgZWwgPSBjb250cm9sUmFuZ2UuaXRlbShpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZWwgIT09IHJhbmdlRWxlbWVudCB8fCByZW1vdmVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0NvbnRyb2xSYW5nZS5hZGQoY29udHJvbFJhbmdlLml0ZW0oaSkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5ld0NvbnRyb2xSYW5nZS5zZWxlY3QoKTsKCiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgdGhlIHdyYXBwZWQgc2VsZWN0aW9uIGJhc2VkIG9uIHdoYXQncyBub3cgaW4gdGhlIG5hdGl2ZSBzZWxlY3Rpb24KICAgICAgICAgICAgICAgIHVwZGF0ZUNvbnRyb2xTZWxlY3Rpb24odGhpcyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZW1vdmVSYW5nZU1hbnVhbGx5KHRoaXMsIHJhbmdlKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIHNlbFByb3RvLnJlbW92ZVJhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgICAgIHJlbW92ZVJhbmdlTWFudWFsbHkodGhpcywgcmFuZ2UpOwogICAgICAgIH07CiAgICB9CgogICAgLy8gRGV0ZWN0aW5nIGlmIGEgc2VsZWN0aW9uIGlzIGJhY2t3YXJkcwogICAgdmFyIHNlbGVjdGlvbklzQmFja3dhcmRzOwogICAgaWYgKCF1c2VEb2N1bWVudFNlbGVjdGlvbiAmJiBzZWxlY3Rpb25IYXNBbmNob3JBbmRGb2N1cyAmJiBhcGkuZmVhdHVyZXMuaW1wbGVtZW50c0RvbVJhbmdlKSB7CiAgICAgICAgc2VsZWN0aW9uSXNCYWNrd2FyZHMgPSBmdW5jdGlvbiAoc2VsKSB7CiAgICAgICAgICAgIHZhciBiYWNrd2FyZHMgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKHNlbC5hbmNob3JOb2RlKSB7CiAgICAgICAgICAgICAgICBiYWNrd2FyZHMgPSAoZG9tLmNvbXBhcmVQb2ludHMoc2VsLmFuY2hvck5vZGUsIHNlbC5hbmNob3JPZmZzZXQsIHNlbC5mb2N1c05vZGUsIHNlbC5mb2N1c09mZnNldCkgPT0gMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGJhY2t3YXJkczsKICAgICAgICB9OwoKICAgICAgICBzZWxQcm90by5pc0JhY2t3YXJkcyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGlvbklzQmFja3dhcmRzKHRoaXMpOwogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIHNlbGVjdGlvbklzQmFja3dhcmRzID0gc2VsUHJvdG8uaXNCYWNrd2FyZHMgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9OwogICAgfQoKICAgIC8vIFNlbGVjdGlvbiB0ZXh0CiAgICAvLyBUaGlzIGlzIGNvbmZvcm1hbnQgdG8gdGhlIG5ldyBXSEFUV0cgRE9NIFJhbmdlIGRyYWZ0IHNwZWMgYnV0IGRpZmZlcnMgZnJvbSBXZWJLaXQgYW5kIE1vemlsbGEncyBpbXBsZW1lbnRhdGlvbgogICAgc2VsUHJvdG8udG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7CgogICAgICAgIHZhciByYW5nZVRleHRzID0gW107CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRoaXMucmFuZ2VDb3VudDsKICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgcmFuZ2VUZXh0c1tpXSA9ICIiICsgdGhpcy5fcmFuZ2VzW2ldOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmFuZ2VUZXh0cy5qb2luKCIiKTsKICAgIH07CgogICAgZnVuY3Rpb24gYXNzZXJ0Tm9kZUluU2FtZURvY3VtZW50KHNlbCwgbm9kZSkgewogICAgICAgIGlmIChzZWwuYW5jaG9yTm9kZSAmJiAoZG9tLmdldERvY3VtZW50KHNlbC5hbmNob3JOb2RlKSAhPT0gZG9tLmdldERvY3VtZW50KG5vZGUpKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKCJXUk9OR19ET0NVTUVOVF9FUlIiKTsKICAgICAgICB9CiAgICB9CgogICAgLy8gTm8gY3VycmVudCBicm93c2VycyBjb25mb3JtIGZ1bGx5IHRvIHRoZSBIVE1MIDUgZHJhZnQgc3BlYyBmb3IgdGhpcyBtZXRob2QsIHNvIFJhbmd5J3Mgb3duIG1ldGhvZCBpcyBhbHdheXMgdXNlZAogICAgc2VsUHJvdG8uY29sbGFwc2UgPSBmdW5jdGlvbiAobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgYXNzZXJ0Tm9kZUluU2FtZURvY3VtZW50KHRoaXMsIG5vZGUpOwogICAgICAgIHZhciByYW5nZSA9IGFwaS5jcmVhdGVSYW5nZShkb20uZ2V0RG9jdW1lbnQobm9kZSkpOwogICAgICAgIHJhbmdlLmNvbGxhcHNlVG9Qb2ludChub2RlLCBvZmZzZXQpOwogICAgICAgIHRoaXMucmVtb3ZlQWxsUmFuZ2VzKCk7CiAgICAgICAgdGhpcy5hZGRSYW5nZShyYW5nZSk7CiAgICAgICAgdGhpcy5pc0NvbGxhcHNlZCA9IHRydWU7CiAgICB9OwoKICAgIHNlbFByb3RvLmNvbGxhcHNlVG9TdGFydCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAodGhpcy5yYW5nZUNvdW50KSB7CiAgICAgICAgICAgIHZhciByYW5nZSA9IHRoaXMuX3Jhbmdlc1swXTsKICAgICAgICAgICAgdGhpcy5jb2xsYXBzZShyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIklOVkFMSURfU1RBVEVfRVJSIik7CiAgICAgICAgfQogICAgfTsKCiAgICBzZWxQcm90by5jb2xsYXBzZVRvRW5kID0gZnVuY3Rpb24gKCkgewogICAgICAgIGlmICh0aGlzLnJhbmdlQ291bnQpIHsKICAgICAgICAgICAgdmFyIHJhbmdlID0gdGhpcy5fcmFuZ2VzW3RoaXMucmFuZ2VDb3VudCAtIDFdOwogICAgICAgICAgICB0aGlzLmNvbGxhcHNlKHJhbmdlLmVuZENvbnRhaW5lciwgcmFuZ2UuZW5kT2Zmc2V0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKCJJTlZBTElEX1NUQVRFX0VSUiIpOwogICAgICAgIH0KICAgIH07CgogICAgLy8gVGhlIEhUTUwgNSBzcGVjIGlzIHZlcnkgc3BlY2lmaWMgb24gaG93IHNlbGVjdEFsbENoaWxkcmVuIHNob3VsZCBiZSBpbXBsZW1lbnRlZCBzbyB0aGUgbmF0aXZlIGltcGxlbWVudGF0aW9uIGlzCiAgICAvLyBuZXZlciB1c2VkIGJ5IFJhbmd5LgogICAgc2VsUHJvdG8uc2VsZWN0QWxsQ2hpbGRyZW4gPSBmdW5jdGlvbiAobm9kZSkgewogICAgICAgIGFzc2VydE5vZGVJblNhbWVEb2N1bWVudCh0aGlzLCBub2RlKTsKICAgICAgICB2YXIgcmFuZ2UgPSBhcGkuY3JlYXRlUmFuZ2UoZG9tLmdldERvY3VtZW50KG5vZGUpKTsKICAgICAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHMobm9kZSk7CiAgICAgICAgdGhpcy5yZW1vdmVBbGxSYW5nZXMoKTsKICAgICAgICB0aGlzLmFkZFJhbmdlKHJhbmdlKTsKICAgIH07CgogICAgc2VsUHJvdG8uZGVsZXRlRnJvbURvY3VtZW50ID0gZnVuY3Rpb24gKCkgewogICAgICAgIC8vIFNlcGNpYWwgYmVoYXZpb3VyIHJlcXVpcmVkIGZvciBDb250cm9sIHNlbGVjdGlvbnMKICAgICAgICBpZiAoaW1wbGVtZW50c0NvbnRyb2xSYW5nZSAmJiBpbXBsZW1lbnRzRG9jU2VsZWN0aW9uICYmIHRoaXMuZG9jU2VsZWN0aW9uLnR5cGUgPT0gQ09OVFJPTCkgewogICAgICAgICAgICB2YXIgY29udHJvbFJhbmdlID0gdGhpcy5kb2NTZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTsKICAgICAgICAgICAgdmFyIGVsZW1lbnQ7CiAgICAgICAgICAgIHdoaWxlIChjb250cm9sUmFuZ2UubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBlbGVtZW50ID0gY29udHJvbFJhbmdlLml0ZW0oMCk7CiAgICAgICAgICAgICAgICBjb250cm9sUmFuZ2UucmVtb3ZlKGVsZW1lbnQpOwogICAgICAgICAgICAgICAgZWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGVsZW1lbnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMucmVmcmVzaCgpOwogICAgICAgIH0gZWxzZSBpZiAodGhpcy5yYW5nZUNvdW50KSB7CiAgICAgICAgICAgIHZhciByYW5nZXMgPSB0aGlzLmdldEFsbFJhbmdlcygpOwogICAgICAgICAgICB0aGlzLnJlbW92ZUFsbFJhbmdlcygpOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gcmFuZ2VzLmxlbmd0aDsKICAgICAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgICAgICsraSkgewogICAgICAgICAgICAgICAgcmFuZ2VzW2ldLmRlbGV0ZUNvbnRlbnRzKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gVGhlIEhUTUw1IHNwZWMgc2F5cyBub3RoaW5nIGFib3V0IHdoYXQgdGhlIHNlbGVjdGlvbiBzaG91bGQgY29udGFpbiBhZnRlciBjYWxsaW5nIGRlbGV0ZUNvbnRlbnRzIG9uIGVhY2gKICAgICAgICAgICAgLy8gcmFuZ2UuIEZpcmVmb3ggbW92ZXMgdGhlIHNlbGVjdGlvbiB0byB3aGVyZSB0aGUgZmluYWwgc2VsZWN0ZWQgcmFuZ2Ugd2FzLCBzbyB3ZSBlbXVsYXRlIHRoYXQKICAgICAgICAgICAgdGhpcy5hZGRSYW5nZShyYW5nZXNbbGVuIC0gMV0pOwogICAgICAgIH0KICAgIH07CgogICAgLy8gVGhlIGZvbGxvd2luZyBhcmUgbm9uLXN0YW5kYXJkIGV4dGVuc2lvbnMKICAgIHNlbFByb3RvLmdldEFsbFJhbmdlcyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gdGhpcy5fcmFuZ2VzLnNsaWNlKDApOwogICAgfTsKCiAgICBzZWxQcm90by5zZXRTaW5nbGVSYW5nZSA9IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgIHRoaXMuc2V0UmFuZ2VzKFtyYW5nZV0pOwogICAgfTsKCiAgICBzZWxQcm90by5jb250YWluc05vZGUgPSBmdW5jdGlvbiAobm9kZSwgYWxsb3dQYXJ0aWFsKSB7CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRoaXMuX3Jhbmdlcy5sZW5ndGg7CiAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgIGlmICh0aGlzLl9yYW5nZXNbaV0uY29udGFpbnNOb2RlKG5vZGUsIGFsbG93UGFydGlhbCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CgogICAgc2VsUHJvdG8udG9IdG1sID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBodG1sID0gIiI7CiAgICAgICAgaWYgKHRoaXMucmFuZ2VDb3VudCkgewogICAgICAgICAgICB2YXIgY29udGFpbmVyID0gRG9tUmFuZ2UuZ2V0UmFuZ2VEb2N1bWVudCh0aGlzLl9yYW5nZXNbMF0pLmNyZWF0ZUVsZW1lbnQoImRpdiIpOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gdGhpcy5fcmFuZ2VzLmxlbmd0aDsKICAgICAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgICAgICsraSkgewogICAgICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMuX3Jhbmdlc1tpXS5jbG9uZUNvbnRlbnRzKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGh0bWwgPSBjb250YWluZXIuaW5uZXJIVE1MOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaHRtbDsKICAgIH07CgogICAgZnVuY3Rpb24gaW5zcGVjdChzZWwpIHsKICAgICAgICB2YXIgcmFuZ2VJbnNwZWN0cyA9IFtdOwogICAgICAgIHZhciBhbmNob3IgPSBuZXcgRG9tUG9zaXRpb24oc2VsLmFuY2hvck5vZGUsIHNlbC5hbmNob3JPZmZzZXQpOwogICAgICAgIHZhciBmb2N1cyA9IG5ldyBEb21Qb3NpdGlvbihzZWwuZm9jdXNOb2RlLCBzZWwuZm9jdXNPZmZzZXQpOwogICAgICAgIHZhciBuYW1lID0gKHR5cGVvZiBzZWwuZ2V0TmFtZSA9PSAiZnVuY3Rpb24iKSA/IHNlbC5nZXROYW1lKCkgOiAiU2VsZWN0aW9uIjsKCiAgICAgICAgaWYgKHR5cGVvZiBzZWwucmFuZ2VDb3VudCAhPSAidW5kZWZpbmVkIikgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gc2VsLnJhbmdlQ291bnQ7CiAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgIHJhbmdlSW5zcGVjdHNbaV0gPSBEb21SYW5nZS5pbnNwZWN0KHNlbC5nZXRSYW5nZUF0KGkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gIlsiICsgbmFtZSArICIoUmFuZ2VzOiAiICsgcmFuZ2VJbnNwZWN0cy5qb2luKCIsICIpICsKICAgICAgICAgICAgIikoYW5jaG9yOiAiICsgYW5jaG9yLmluc3BlY3QoKSArICIsIGZvY3VzOiAiICsgZm9jdXMuaW5zcGVjdCgpICsgIl0iOwogICAgfQoKICAgIHNlbFByb3RvLmdldE5hbWUgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuICJXcmFwcGVkU2VsZWN0aW9uIjsKICAgIH07CgogICAgc2VsUHJvdG8uaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gaW5zcGVjdCh0aGlzKTsKICAgIH07CgogICAgc2VsUHJvdG8uZGV0YWNoID0gZnVuY3Rpb24gKCkgewogICAgICAgIHRoaXMud2luW3dpbmRvd1Byb3BlcnR5TmFtZV0gPSBudWxsOwogICAgICAgIHRoaXMud2luID0gdGhpcy5hbmNob3JOb2RlID0gdGhpcy5mb2N1c05vZGUgPSBudWxsOwogICAgfTsKCiAgICBXcmFwcGVkU2VsZWN0aW9uLmluc3BlY3QgPSBpbnNwZWN0OwoKICAgIGFwaS5TZWxlY3Rpb24gPSBXcmFwcGVkU2VsZWN0aW9uOwoKICAgIGFwaS5zZWxlY3Rpb25Qcm90b3R5cGUgPSBzZWxQcm90bzsKCiAgICBhcGkuYWRkQ3JlYXRlTWlzc2luZ05hdGl2ZUFwaUxpc3RlbmVyKGZ1bmN0aW9uICh3aW4pIHsKICAgICAgICBpZiAodHlwZW9mIHdpbi5nZXRTZWxlY3Rpb24gPT0gInVuZGVmaW5lZCIpIHsKICAgICAgICAgICAgd2luLmdldFNlbGVjdGlvbiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhcGkuZ2V0U2VsZWN0aW9uKHRoaXMpOwogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICB3aW4gPSBudWxsOwogICAgfSk7Cn0pOwovKgogQmFzZS5qcywgdmVyc2lvbiAxLjFhCiBDb3B5cmlnaHQgMjAwNi0yMDEwLCBEZWFuIEVkd2FyZHMKIExpY2Vuc2U6IGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwCiAqLwoKdmFyIEJhc2UgPSBmdW5jdGlvbiAoKSB7CiAgICAvLyBkdW1teQp9OwoKQmFzZS5leHRlbmQgPSBmdW5jdGlvbiAoX2luc3RhbmNlLCBfc3RhdGljKSB7Ly8gc3ViY2xhc3MKICAgIHZhciBleHRlbmQgPSBCYXNlLnByb3RvdHlwZS5leHRlbmQ7CgogICAgLy8gYnVpbGQgdGhlIHByb3RvdHlwZQogICAgQmFzZS5fcHJvdG90eXBpbmcgPSB0cnVlOwogICAgdmFyIHByb3RvID0gbmV3IHRoaXM7CiAgICBleHRlbmQuY2FsbChwcm90bywgX2luc3RhbmNlKTsKICAgIHByb3RvLmJhc2UgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgLy8gY2FsbCB0aGlzIG1ldGhvZCBmcm9tIGFueSBvdGhlciBtZXRob2QgdG8gaW52b2tlIHRoYXQgbWV0aG9kJ3MgYW5jZXN0b3IKICAgIH07CiAgICBkZWxldGUgQmFzZS5fcHJvdG90eXBpbmc7CgogICAgLy8gY3JlYXRlIHRoZSB3cmFwcGVyIGZvciB0aGUgY29uc3RydWN0b3IgZnVuY3Rpb24KICAgIC8vdmFyIGNvbnN0cnVjdG9yID0gcHJvdG8uY29uc3RydWN0b3IudmFsdWVPZigpOyAvLy1kZWFuCiAgICB2YXIgY29uc3RydWN0b3IgPSBwcm90by5jb25zdHJ1Y3RvcjsKICAgIHZhciBrbGFzcyA9IHByb3RvLmNvbnN0cnVjdG9yID0gZnVuY3Rpb24gKCkgewogICAgICAgIGlmICghQmFzZS5fcHJvdG90eXBpbmcpIHsKICAgICAgICAgICAgaWYgKHRoaXMuX2NvbnN0cnVjdGluZyB8fCB0aGlzLmNvbnN0cnVjdG9yID09IGtsYXNzKSB7Ly8gaW5zdGFudGlhdGlvbgogICAgICAgICAgICAgICAgdGhpcy5fY29uc3RydWN0aW5nID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5fY29uc3RydWN0aW5nOwogICAgICAgICAgICB9IGVsc2UgaWYgKGFyZ3VtZW50c1swXSAhPSBudWxsKSB7Ly8gY2FzdGluZwogICAgICAgICAgICAgICAgcmV0dXJuIChhcmd1bWVudHNbMF0uZXh0ZW5kIHx8IGV4dGVuZCkuY2FsbChhcmd1bWVudHNbMF0sIHByb3RvKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgLy8gYnVpbGQgdGhlIGNsYXNzIGludGVyZmFjZQogICAga2xhc3MuYW5jZXN0b3IgPSB0aGlzOwogICAga2xhc3MuZXh0ZW5kID0gdGhpcy5leHRlbmQ7CiAgICBrbGFzcy5mb3JFYWNoID0gdGhpcy5mb3JFYWNoOwogICAga2xhc3MuaW1wbGVtZW50ID0gdGhpcy5pbXBsZW1lbnQ7CiAgICBrbGFzcy5wcm90b3R5cGUgPSBwcm90bzsKICAgIGtsYXNzLnRvU3RyaW5nID0gdGhpcy50b1N0cmluZzsKICAgIGtsYXNzLnZhbHVlT2YgPSBmdW5jdGlvbiAodHlwZSkgewogICAgICAgIC8vcmV0dXJuICh0eXBlID09ICJvYmplY3QiKSA/IGtsYXNzIDogY29uc3RydWN0b3I7IC8vLWRlYW4KICAgICAgICByZXR1cm4gKHR5cGUgPT0gIm9iamVjdCIpID8ga2xhc3MgOiBjb25zdHJ1Y3Rvci52YWx1ZU9mKCk7CiAgICB9OwogICAgZXh0ZW5kLmNhbGwoa2xhc3MsIF9zdGF0aWMpOwogICAgLy8gY2xhc3MgaW5pdGlhbGlzYXRpb24KICAgIGlmICh0eXBlb2Yga2xhc3MuaW5pdCA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAga2xhc3MuaW5pdCgpOwogICAgfQogICAgcmV0dXJuIGtsYXNzOwp9OwoKQmFzZS5wcm90b3R5cGUgPSB7CiAgICBleHRlbmQgOiBmdW5jdGlvbiAoc291cmNlLCB2YWx1ZSkgewogICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkgey8vIGV4dGVuZGluZyB3aXRoIGEgbmFtZS92YWx1ZSBwYWlyCiAgICAgICAgICAgIHZhciBhbmNlc3RvciA9IHRoaXNbc291cmNlXTsKICAgICAgICAgICAgaWYgKGFuY2VzdG9yICYmICh0eXBlb2YgdmFsdWUgPT0gImZ1bmN0aW9uIikgJiYgLy8gb3ZlcnJpZGluZyBhIG1ldGhvZD8KICAgICAgICAgICAgICAgIC8vIHRoZSB2YWx1ZU9mKCkgY29tcGFyaXNvbiBpcyB0byBhdm9pZCBjaXJjdWxhciByZWZlcmVuY2VzCiAgICAgICAgICAgICAgICAoIWFuY2VzdG9yLnZhbHVlT2YgfHwgYW5jZXN0b3IudmFsdWVPZigpICE9IHZhbHVlLnZhbHVlT2YoKSkgJiYgL1xiYmFzZVxiLy50ZXN0KHZhbHVlKSkgewogICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSB1bmRlcmx5aW5nIG1ldGhvZAogICAgICAgICAgICAgICAgdmFyIG1ldGhvZCA9IHZhbHVlLnZhbHVlT2YoKTsKICAgICAgICAgICAgICAgIC8vIG92ZXJyaWRlCiAgICAgICAgICAgICAgICB2YWx1ZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcHJldmlvdXMgPSB0aGlzLmJhc2UgfHwgQmFzZS5wcm90b3R5cGUuYmFzZTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmJhc2UgPSBhbmNlc3RvcjsKICAgICAgICAgICAgICAgICAgICB2YXIgcmV0dXJuVmFsdWUgPSBtZXRob2QuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmJhc2UgPSBwcmV2aW91czsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0dXJuVmFsdWU7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgLy8gcG9pbnQgdG8gdGhlIHVuZGVybHlpbmcgbWV0aG9kCiAgICAgICAgICAgICAgICB2YWx1ZS52YWx1ZU9mID0gZnVuY3Rpb24gKHR5cGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHR5cGUgPT0gIm9iamVjdCIpID8gdmFsdWUgOiBtZXRob2Q7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgdmFsdWUudG9TdHJpbmcgPSBCYXNlLnRvU3RyaW5nOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXNbc291cmNlXSA9IHZhbHVlOwogICAgICAgIH0gZWxzZSBpZiAoc291cmNlKSB7Ly8gZXh0ZW5kaW5nIHdpdGggYW4gb2JqZWN0IGxpdGVyYWwKICAgICAgICAgICAgdmFyIGV4dGVuZCA9IEJhc2UucHJvdG90eXBlLmV4dGVuZDsKICAgICAgICAgICAgLy8gaWYgdGhpcyBvYmplY3QgaGFzIGEgY3VzdG9taXNlZCBleHRlbmQgbWV0aG9kIHRoZW4gdXNlIGl0CiAgICAgICAgICAgIGlmICghQmFzZS5fcHJvdG90eXBpbmcgJiYgdHlwZW9mIHRoaXMgIT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICAgICAgZXh0ZW5kID0gdGhpcy5leHRlbmQgfHwgZXh0ZW5kOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBwcm90byA9IHt0b1NvdXJjZSA6IG51bGx9OwogICAgICAgICAgICAvLyBkbyB0aGUgInRvU3RyaW5nIiBhbmQgb3RoZXIgbWV0aG9kcyBtYW51YWxseQogICAgICAgICAgICB2YXIgaGlkZGVuID0gWyJjb25zdHJ1Y3RvciIsICJ0b1N0cmluZyIsICJ2YWx1ZU9mIl07CiAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBwcm90b3R5cGluZyB0aGVuIGluY2x1ZGUgdGhlIGNvbnN0cnVjdG9yCiAgICAgICAgICAgIHZhciBpID0gQmFzZS5fcHJvdG90eXBpbmcgPyAwIDogMTsKICAgICAgICAgICAgd2hpbGUgKGtleSA9IGhpZGRlbltpKytdKSB7CiAgICAgICAgICAgICAgICBpZiAoc291cmNlW2tleV0gIT0gcHJvdG9ba2V5XSkgewogICAgICAgICAgICAgICAgICAgIGV4dGVuZC5jYWxsKHRoaXMsIGtleSwgc291cmNlW2tleV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGNvcHkgZWFjaCBvZiB0aGUgc291cmNlIG9iamVjdCdzIHByb3BlcnRpZXMgdG8gdGhpcyBvYmplY3QKICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgewogICAgICAgICAgICAgICAgaWYgKCFwcm90b1trZXldKSB7CiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kLmNhbGwodGhpcywga2V5LCBzb3VyY2Vba2V5XSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICB9Cn07CgovLyBpbml0aWFsaXNlCkJhc2UgPSBCYXNlLmV4dGVuZCh7CiAgICBjb25zdHJ1Y3RvciA6IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLmV4dGVuZChhcmd1bWVudHNbMF0pOwogICAgfQp9LCB7CiAgICBhbmNlc3RvciA6IE9iamVjdCwKICAgIHZlcnNpb24gOiAiMS4xIiwKCiAgICBmb3JFYWNoIDogZnVuY3Rpb24gKG9iamVjdCwgYmxvY2ssIGNvbnRleHQpIHsKICAgICAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7CiAgICAgICAgICAgIGlmICh0aGlzLnByb3RvdHlwZVtrZXldID09PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgIGJsb2NrLmNhbGwoY29udGV4dCwgb2JqZWN0W2tleV0sIGtleSwgb2JqZWN0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sCgogICAgaW1wbGVtZW50IDogZnVuY3Rpb24gKCkgewogICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgaSA8IGFyZ3VtZW50cy5sZW5ndGg7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgaWYgKHR5cGVvZiBhcmd1bWVudHNbaV0gPT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICAgICAgLy8gaWYgaXQncyBhIGZ1bmN0aW9uLCBjYWxsIGl0CiAgICAgICAgICAgICAgICBhcmd1bWVudHNbaV0odGhpcy5wcm90b3R5cGUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gYWRkIHRoZSBpbnRlcmZhY2UgdXNpbmcgdGhlIGV4dGVuZCBtZXRob2QKICAgICAgICAgICAgICAgIHRoaXMucHJvdG90eXBlLmV4dGVuZChhcmd1bWVudHNbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgfSwKCiAgICB0b1N0cmluZyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gU3RyaW5nKHRoaXMudmFsdWVPZigpKTsKICAgIH0KfSk7Ci8qKgogKiBEZXRlY3QgYnJvd3NlciBzdXBwb3J0IGZvciBzcGVjaWZpYyBmZWF0dXJlcwogKi8Kd3lzaWh0bWw1LmJyb3dzZXIgPSAoZnVuY3Rpb24gKCkgewogICAgdmFyIHVzZXJBZ2VudCA9IG5hdmlnYXRvci51c2VyQWdlbnQsCiAgICAgICAgdGVzdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKSwKICAgICAgICAvLyBCcm93c2VyIHNuaWZmaW5nIGlzIHVuZm9ydHVuYXRlbHkgbmVlZGVkIHNpbmNlIHNvbWUgYmVoYXZpb3JzIGFyZSBpbXBvc3NpYmxlIHRvIGZlYXR1cmUgZGV0ZWN0CiAgICAgICAgaXNHZWNrbyA9IHVzZXJBZ2VudC5pbmRleE9mKCJHZWNrbyIpICE9PSAtMSAmJiB1c2VyQWdlbnQuaW5kZXhPZigiS0hUTUwiKSA9PT0gLTEsCiAgICAgICAgaXNXZWJLaXQgPSB1c2VyQWdlbnQuaW5kZXhPZigiQXBwbGVXZWJLaXQvIikgIT09IC0xLAogICAgICAgIGlzQ2hyb21lID0gdXNlckFnZW50LmluZGV4T2YoIkNocm9tZS8iKSAhPT0gLTEsCiAgICAgICAgaXNPcGVyYSA9IHVzZXJBZ2VudC5pbmRleE9mKCJPcGVyYS8iKSAhPT0gLTE7CgogICAgZnVuY3Rpb24gZGV0ZWN0SUUoKSB7CiAgICAgICAgdmFyIHVhID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7CgogICAgICAgIHZhciBtc2llID0gdWEuaW5kZXhPZignTVNJRSAnKTsKICAgICAgICBpZiAobXNpZSA+IDApIHsKICAgICAgICAgICAgLy8gSUUgMTAgb3Igb2xkZXIgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyCiAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh1YS5zdWJzdHJpbmcobXNpZSArIDUsIHVhLmluZGV4T2YoJy4nLCBtc2llKSksIDEwKTsKICAgICAgICB9CgogICAgICAgIHZhciB0cmlkZW50ID0gdWEuaW5kZXhPZignVHJpZGVudC8nKTsKICAgICAgICBpZiAodHJpZGVudCA+IDApIHsKICAgICAgICAgICAgLy8gSUUgMTEgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyCiAgICAgICAgICAgIHZhciBydiA9IHVhLmluZGV4T2YoJ3J2OicpOwogICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodWEuc3Vic3RyaW5nKHJ2ICsgMywgdWEuaW5kZXhPZignLicsIHJ2KSksIDEwKTsKICAgICAgICB9CgogICAgICAgIHZhciBlZGdlID0gdWEuaW5kZXhPZignRWRnZS8nKTsKICAgICAgICBpZiAoZWRnZSA+IDApIHsKICAgICAgICAgICAgLy8gSUUgMTIgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyCiAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh1YS5zdWJzdHJpbmcoZWRnZSArIDUsIHVhLmluZGV4T2YoJy4nLCBlZGdlKSksIDEwKTsKICAgICAgICB9CgogICAgICAgIC8vIG90aGVyIGJyb3dzZXIKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgdmFyIGlzSUUgPSBkZXRlY3RJRSgpOwogICAgdmFyIGlzRmlyZUZveCA9IHVzZXJBZ2VudCA/ICh1c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA6IDA7CgogICAgZnVuY3Rpb24gaW9zVmVyc2lvbih1c2VyQWdlbnQpIHsKICAgICAgICByZXR1cm4gKygoL2lwYWR8aXBob25lfGlwb2QvLnRlc3QodXNlckFnZW50KSAmJiB1c2VyQWdlbnQubWF0Y2goLyBvcyAoXGQrKS4rPyBsaWtlIG1hYyBvcyB4LykpIHx8IFssIDBdKVsxXTsKICAgIH0KCiAgICBmdW5jdGlvbiBhbmRyb2lkVmVyc2lvbih1c2VyQWdlbnQpIHsKICAgICAgICByZXR1cm4gKyh1c2VyQWdlbnQubWF0Y2goL2FuZHJvaWQgKFxkKykvKSB8fCBbLCAwXSlbMV07CiAgICB9CgogICAgcmV0dXJuIHsKICAgICAgICAvLyBTdGF0aWMgdmFyaWFibGUgbmVlZGVkLCBwdWJsaWNseSBhY2Nlc3NpYmxlLCB0byBiZSBhYmxlIG92ZXJyaWRlIGl0IGluIHVuaXQgdGVzdHMKICAgICAgICBVU0VSX0FHRU5UIDogdXNlckFnZW50LAoKICAgICAgICAvLyByZXR1cm4gdHJ1ZSBpZiBicm93c2VyIGlzIGZpcmVmb3gKICAgICAgICBpc0ZpcmVGb3ggOiBpc0ZpcmVGb3gsCgogICAgICAgIC8vIHJldHVybiB0cnVlIGlmIGJyb3dzZXIgaXMgSUUKICAgICAgICBpc0lFIDogaXNJRSwKICAgICAgICAvKioKICAgICAgICAgKiBFeGNsdWRlIGJyb3dzZXJzIHRoYXQgYXJlIG5vdCBjYXBhYmxlIG9mIGRpc3BsYXlpbmcgYW5kIGhhbmRsaW5nCiAgICAgICAgICogY29udGVudEVkaXRhYmxlIGFzIGRlc2lyZWQ6CiAgICAgICAgICogICAgLSBpUGhvbmUsIGlQYWQgKHRlc3RlZCBpT1MgNC4yLjIpIGFuZCBBbmRyb2lkICh0ZXN0ZWQgMi4yKSByZWZ1c2UgdG8gbWFrZSBjb250ZW50RWRpdGFibGVzIGZvY3VzYWJsZQogICAgICAgICAqICAgIC0gSUUgPCA4IGNyZWF0ZSBpbnZhbGlkIG1hcmt1cCBhbmQgY3Jhc2ggcmFuZG9tbHkgZnJvbSB0aW1lIHRvIHRpbWUKICAgICAgICAgKgogICAgICAgICAqIEByZXR1cm4ge0Jvb2xlYW59CiAgICAgICAgICovCiAgICAgICAgc3VwcG9ydGVkIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgdXNlckFnZW50ID0gdGhpcy5VU0VSX0FHRU5ULnRvTG93ZXJDYXNlKCksCiAgICAgICAgICAgICAgICAvLyBFc3NlbnRpYWwgZm9yIG1ha2luZyBodG1sIGVsZW1lbnRzIGVkaXRhYmxlCiAgICAgICAgICAgICAgICBoYXNDb250ZW50RWRpdGFibGVTdXBwb3J0ID0gImNvbnRlbnRFZGl0YWJsZSIgaW4gdGVzdEVsZW1lbnQsCiAgICAgICAgICAgICAgICAvLyBGb2xsb3dpbmcgbWV0aG9kcyBhcmUgbmVlZGVkIGluIG9yZGVyIHRvIGludGVyYWN0IHdpdGggdGhlIGNvbnRlbnRFZGl0YWJsZSBhcmVhCiAgICAgICAgICAgICAgICBoYXNFZGl0aW5nQXBpU3VwcG9ydCA9IGRvY3VtZW50LmV4ZWNDb21tYW5kICYmIGRvY3VtZW50LnF1ZXJ5Q29tbWFuZFN1cHBvcnRlZCAmJiBkb2N1bWVudC5xdWVyeUNvbW1hbmRTdGF0ZSwKICAgICAgICAgICAgICAgIC8vIGRvY3VtZW50IHNlbGVjdG9yIGFwaXMgYXJlIG9ubHkgc3VwcG9ydGVkIGJ5IElFIDgrLCBTYWZhcmkgNCssIENocm9tZSBhbmQgRmlyZWZveCAzLjUrCiAgICAgICAgICAgICAgICBoYXNRdWVyeVNlbGVjdG9yU3VwcG9ydCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IgJiYgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCwKICAgICAgICAgICAgICAgIC8vIGNvbnRlbnRFZGl0YWJsZSBpcyB1bnVzYWJsZSBpbiBtb2JpbGUgYnJvd3NlcnMgKHRlc3RlZCBpT1MgNC4yLjIsIEFuZHJvaWQgMi4yLCBPcGVyYSBNb2JpbGUsIFdlYk9TIDMuMDUpCiAgICAgICAgICAgICAgICBpc0luY29tcGF0aWJsZU1vYmlsZUJyb3dzZXIgPSAodGhpcy5pc0lvcygpICYmIGlvc1ZlcnNpb24odXNlckFnZW50KSA8IDUpIHx8ICh0aGlzLmlzQW5kcm9pZCgpICYmIGFuZHJvaWRWZXJzaW9uKHVzZXJBZ2VudCkgPCA0KSB8fCB1c2VyQWdlbnQuaW5kZXhPZigib3BlcmEgbW9iaSIpICE9PSAtMSB8fCB1c2VyQWdlbnQuaW5kZXhPZigiaHB3b3MvIikgIT09IC0xOwogICAgICAgICAgICByZXR1cm4gaGFzQ29udGVudEVkaXRhYmxlU3VwcG9ydCAmJiBoYXNFZGl0aW5nQXBpU3VwcG9ydCAmJiBoYXNRdWVyeVNlbGVjdG9yU3VwcG9ydCAmJiAhaXNJbmNvbXBhdGlibGVNb2JpbGVCcm93c2VyOwogICAgICAgIH0sCgogICAgICAgIGlzVG91Y2hEZXZpY2UgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnN1cHBvcnRzRXZlbnQoInRvdWNobW92ZSIpOwogICAgICAgIH0sCgogICAgICAgIGlzSW9zIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gKC9pcGFkfGlwaG9uZXxpcG9kL2kpLnRlc3QodGhpcy5VU0VSX0FHRU5UKTsKICAgICAgICB9LAoKICAgICAgICBpc0FuZHJvaWQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLlVTRVJfQUdFTlQuaW5kZXhPZigiQW5kcm9pZCIpICE9PSAtMTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBXaGV0aGVyIHRoZSBicm93c2VyIHN1cHBvcnRzIHNhbmRib3hlZCBpZnJhbWVzCiAgICAgICAgICogQ3VycmVudGx5IG9ubHkgSUUgNisgb2ZmZXJzIHN1Y2ggZmVhdHVyZSA8aWZyYW1lIHNlY3VyaXR5PSJyZXN0cmljdGVkIj4KICAgICAgICAgKgogICAgICAgICAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNDYyMih2PXZzLjg1KS5hc3B4CiAgICAgICAgICogaHR0cDovL2Jsb2dzLm1zZG4uY29tL2IvaWUvYXJjaGl2ZS8yMDA4LzAxLzE4L3VzaW5nLWZyYW1lcy1tb3JlLXNlY3VyZWx5LmFzcHgKICAgICAgICAgKgogICAgICAgICAqIEhUTUw1IHNhbmRib3hlZCBpZnJhbWVzIGFyZSBzdGlsbCBidWdneSBhbmQgdGhlaXIgRE9NIGlzIG5vdCByZWFjaGFibGUgZnJvbSB0aGUgb3V0c2lkZSAoZXhjZXB0IHdoZW4gdXNpbmcgcG9zdE1lc3NhZ2UpCiAgICAgICAgICovCiAgICAgICAgc3VwcG9ydHNTYW5kYm94ZWRJZnJhbWVzIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNJRTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBJRTYrNyB0aHJvdyBhIG1peGVkIGNvbnRlbnQgd2FybmluZyB3aGVuIHRoZSBzcmMgb2YgYW4gaWZyYW1lCiAgICAgICAgICogaXMgZW1wdHkvdW5zZXQgb3IgYWJvdXQ6YmxhbmsKICAgICAgICAgKiB3aW5kb3cucXVlcnlTZWxlY3RvciBpcyBpbXBsZW1lbnRlZCBhcyBvZiBJRTgKICAgICAgICAgKi8KICAgICAgICB0aHJvd3NNaXhlZENvbnRlbnRXYXJuaW5nV2hlbklmcmFtZVNyY0lzRW1wdHkgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAhKCJxdWVyeVNlbGVjdG9yIiBpbiBkb2N1bWVudCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV2hldGhlciB0aGUgY2FyZXQgaXMgY29ycmVjdGx5IGRpc3BsYXllZCBpbiBjb250ZW50RWRpdGFibGUgZWxlbWVudHMKICAgICAgICAgKiBGaXJlZm94IHNvbWV0aW1lcyBzaG93cyBhIGh1Z2UgY2FyZXQgaW4gdGhlIGJlZ2lubmluZyBhZnRlciBmb2N1c2luZwogICAgICAgICAqLwogICAgICAgIGRpc3BsYXlzQ2FyZXRJbkVtcHR5Q29udGVudEVkaXRhYmxlQ29ycmVjdGx5IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNJRTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBPcGVyYSBhbmQgSUUgYXJlIHRoZSBvbmx5IGJyb3dzZXJzIHdobyBvZmZlciB0aGUgY3NzIHZhbHVlCiAgICAgICAgICogaW4gdGhlIG9yaWdpbmFsIHVuaXQsIHRoeCB0byB0aGUgY3VycmVudFN0eWxlIG9iamVjdAogICAgICAgICAqIEFsbCBvdGhlciBicm93c2VycyBwcm92aWRlIHRoZSBjb21wdXRlZCBzdHlsZSBpbiBweCB2aWEgd2luZG93LmdldENvbXB1dGVkU3R5bGUKICAgICAgICAgKi8KICAgICAgICBoYXNDdXJyZW50U3R5bGVQcm9wZXJ0eSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICJjdXJyZW50U3R5bGUiIGluIHRlc3RFbGVtZW50OwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEZpcmVmb3ggb24gT1NYIG5hdmlnYXRlcyB0aHJvdWdoIGhpc3Rvcnkgd2hlbiBoaXR0aW5nIENNRCArIEFycm93IHJpZ2h0L2xlZnQKICAgICAgICAgKi8KICAgICAgICBoYXNIaXN0b3J5SXNzdWUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBpc0dlY2tvOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFdoZXRoZXIgdGhlIGJyb3dzZXIgaW5zZXJ0cyBhIDxicj4gd2hlbiBwcmVzc2luZyBlbnRlciBpbiBhIGNvbnRlbnRFZGl0YWJsZSBlbGVtZW50CiAgICAgICAgICovCiAgICAgICAgaW5zZXJ0c0xpbmVCcmVha3NPblJldHVybiA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIGlzR2Vja287CiAgICAgICAgfSwKCiAgICAgICAgc3VwcG9ydHNQbGFjZWhvbGRlckF0dHJpYnV0ZU9uIDogZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuICJwbGFjZWhvbGRlciIgaW4gZWxlbWVudDsKICAgICAgICB9LAoKICAgICAgICBzdXBwb3J0c0V2ZW50IDogZnVuY3Rpb24gKGV2ZW50TmFtZSkgewogICAgICAgICAgICByZXR1cm4gIm9uIiArIGV2ZW50TmFtZSBpbiB0ZXN0RWxlbWVudCB8fCAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHRlc3RFbGVtZW50LnNldEF0dHJpYnV0ZSgib24iICsgZXZlbnROYW1lLCAicmV0dXJuOyIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlb2YodGVzdEVsZW1lbnRbIm9uIiArIGV2ZW50TmFtZV0pID09PSAiZnVuY3Rpb24iOwogICAgICAgICAgICAgICAgfSkoKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBPcGVyYSBkb2Vzbid0IGNvcnJlY3RseSBmaXJlIGZvY3VzL2JsdXIgZXZlbnRzIHdoZW4gY2xpY2tpbmcgaW4tIGFuZCBvdXRzaWRlIG9mIGlmcmFtZQogICAgICAgICAqLwogICAgICAgIHN1cHBvcnRzRXZlbnRzSW5JZnJhbWVDb3JyZWN0bHkgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAhaXNPcGVyYTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBFdmVyeXRoaW5nIGJlbG93IElFOSBkb2Vzbid0IGtub3cgaG93IHRvIHRyZWF0IEhUTUw1IHRhZ3MKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0IFRoZSBkb2N1bWVudCBvYmplY3Qgb24gd2hpY2ggdG8gY2hlY2sgSFRNTDUgc3VwcG9ydAogICAgICAgICAqCiAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgKiAgICB3eXNpaHRtbDUuYnJvd3Nlci5zdXBwb3J0c0hUTUw1VGFncyhkb2N1bWVudCk7CiAgICAgICAgICovCiAgICAgICAgc3VwcG9ydHNIVE1MNVRhZ3MgOiBmdW5jdGlvbiAoY29udGV4dCkgewogICAgICAgICAgICB2YXIgZWxlbWVudCA9IGNvbnRleHQuY3JlYXRlRWxlbWVudCgiZGl2IiksCiAgICAgICAgICAgICAgICBodG1sNSA9ICI8YXJ0aWNsZT5mb288L2FydGljbGU+IjsKICAgICAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBodG1sNTsKICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQuaW5uZXJIVE1MLnRvTG93ZXJDYXNlKCkgPT09IGh0bWw1OwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrcyB3aGV0aGVyIGEgZG9jdW1lbnQgc3VwcG9ydHMgYSBjZXJ0YWluIHF1ZXJ5Q29tbWFuZAogICAgICAgICAqIEluIHBhcnRpY3VsYXIsIE9wZXJhIG5lZWRzIGEgcmVmZXJlbmNlIHRvIGEgZG9jdW1lbnQgdGhhdCBoYXMgYSBjb250ZW50RWRpdGFibGUgaW4gaXQncyBkb20gdHJlZQogICAgICAgICAqIGluIG9kZXIgdG8gcmVwb3J0IGNvcnJlY3QgcmVzdWx0cwogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGRvYyBEb2N1bWVudCBvYmplY3Qgb24gd2hpY2ggdG8gY2hlY2sgZm9yIGEgcXVlcnkgY29tbWFuZAogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjb21tYW5kIFRoZSBxdWVyeSBjb21tYW5kIHRvIGNoZWNrIGZvcgogICAgICAgICAqIEByZXR1cm4ge0Jvb2xlYW59CiAgICAgICAgICoKICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAqICAgIHd5c2lodG1sNS5icm93c2VyLnN1cHBvcnRzQ29tbWFuZChkb2N1bWVudCwgImJvbGQiKTsKICAgICAgICAgKi8KICAgICAgICBzdXBwb3J0c0NvbW1hbmQgOiAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAvLyBGb2xsb3dpbmcgY29tbWFuZHMgYXJlIHN1cHBvcnRlZCBidXQgY29udGFpbiBidWdzIGluIHNvbWUgYnJvd3NlcnMKICAgICAgICAgICAgdmFyIGJ1Z2d5Q29tbWFuZHMgPSB7CiAgICAgICAgICAgICAgICAvLyBmb3JtYXRCbG9jayBmYWlscyB3aXRoIHNvbWUgdGFncyAoZWcuIDxibG9ja3F1b3RlPikKICAgICAgICAgICAgICAgICJmb3JtYXRCbG9jayIgOiBpc0lFLAogICAgICAgICAgICAgICAgLy8gV2hlbiBpbnNlcnRpbmcgdW5vcmRlcmVkIG9yIG9yZGVyZWQgbGlzdHMgaW4gRmlyZWZveCwgQ2hyb21lIG9yIFNhZmFyaSwgdGhlIGN1cnJlbnQgc2VsZWN0aW9uIG9yIGxpbmUgZ2V0cwogICAgICAgICAgICAgICAgLy8gY29udmVydGVkIGludG8gYSBsaXN0ICg8dWw+PGxpPi4uLjwvbGk+PC91bD4sIDxvbD48bGk+Li4uPC9saT48L29sPikKICAgICAgICAgICAgICAgIC8vIElFIGFuZCBPcGVyYSBhY3QgYSBiaXQgZGlmZmVyZW50IGhlcmUgYXMgdGhleSBjb252ZXJ0IHRoZSBlbnRpcmUgY29udGVudCBvZiB0aGUgY3VycmVudCBibG9jayBlbGVtZW50IGludG8gYSBsaXN0CiAgICAgICAgICAgICAgICAiaW5zZXJ0VW5vcmRlcmVkTGlzdCIgOiBpc0lFIHx8IGlzV2ViS2l0IHx8IGlzRmlyZUZveCwKICAgICAgICAgICAgICAgICJpbnNlcnRPcmRlcmVkTGlzdCIgOiBpc0lFIHx8IGlzV2ViS2l0CiAgICAgICAgICAgIH07CgogICAgICAgICAgICAvLyBGaXJlZm94IHRocm93cyBlcnJvcnMgZm9yIHF1ZXJ5Q29tbWFuZFN1cHBvcnRlZCwgc28gd2UgaGF2ZSB0byBidWlsZCB1cCBvdXIgb3duIG9iamVjdCBvZiBzdXBwb3J0ZWQgY29tbWFuZHMKICAgICAgICAgICAgdmFyIHN1cHBvcnRlZCA9IHsKICAgICAgICAgICAgICAgICJpbnNlcnRIVE1MIiA6IGlzR2Vja28KICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZG9jLCBjb21tYW5kKSB7CiAgICAgICAgICAgICAgICB2YXIgaXNCdWdneSA9IGJ1Z2d5Q29tbWFuZHNbY29tbWFuZF07CiAgICAgICAgICAgICAgICBpZiAoIWlzQnVnZ3kpIHsKICAgICAgICAgICAgICAgICAgICAvLyBGaXJlZm94IHRocm93cyBlcnJvcnMgd2hlbiBpbnZva2luZyBxdWVyeUNvbW1hbmRTdXBwb3J0ZWQgb3IgcXVlcnlDb21tYW5kRW5hYmxlZAogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkb2MucXVlcnlDb21tYW5kU3VwcG9ydGVkKGNvbW1hbmQpOwogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUxKSB7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9jLnF1ZXJ5Q29tbWFuZEVuYWJsZWQoY29tbWFuZCk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZTIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICEhc3VwcG9ydGVkW2NvbW1hbmRdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfTsKICAgICAgICB9KSgpLAoKICAgICAgICAvKioKICAgICAgICAgKiBJRTogVVJMcyBzdGFydGluZyB3aXRoOgogICAgICAgICAqICAgIHd3dy4sIGh0dHA6Ly8sIGh0dHBzOi8vLCBmdHA6Ly8sIGdvcGhlcjovLywgbWFpbHRvOiwgbmV3Oiwgc25ld3M6LCB0ZWxuZXQ6LCB3YXNpczosIGZpbGU6Ly8sCiAgICAgICAgICogICAgbm50cDovLywgbmV3c3JjOiwgbGRhcDovLywgbGRhcHM6Ly8sIG91dGxvb2s6LCBtaWM6Ly8gYW5kIHVybDoKICAgICAgICAgKiB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgYXV0by1saW5rZWQgd2hlbiBlaXRoZXIgdGhlIHVzZXIgaW5zZXJ0cyB0aGVtIHZpYSBjb3B5JnBhc3RlIG9yIHByZXNzZXMgdGhlCiAgICAgICAgICogc3BhY2UgYmFyIHdoZW4gdGhlIGNhcmV0IGlzIGRpcmVjdGx5IGFmdGVyIHN1Y2ggYW4gdXJsLgogICAgICAgICAqIFRoaXMgYmVoYXZpb3IgY2Fubm90IGVhc2lseSBiZSBhdm9pZGVkIGluIElFIDwgOSBzaW5jZSB0aGUgbG9naWMgaXMgaGFyZGNvZGVkIGluIHRoZSBtc2h0bWwuZGxsCiAgICAgICAgICogKHJlbGF0ZWQgYmxvZyBwb3N0IG9uIG1zZG4KICAgICAgICAgKiBodHRwOi8vYmxvZ3MubXNkbi5jb20vYi9pZWludGVybmFscy9hcmNoaXZlLzIwMDkvMDkvMTcvcHJldmVudC1hdXRvbWF0aWMtaHlwZXJsaW5raW5nLWluLWNvbnRlbnRlZGl0YWJsZS1odG1sLmFzcHgpLgogICAgICAgICAqLwogICAgICAgIGRvZXNBdXRvTGlua2luZ0luQ29udGVudEVkaXRhYmxlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNJRTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBBcyBzdGF0ZWQgYWJvdmUsIElFIGF1dG8gbGlua3MgdXJscyB0eXBlZCBpbnRvIGNvbnRlbnRFZGl0YWJsZSBlbGVtZW50cwogICAgICAgICAqIFNpbmNlIElFOSBpdCdzIHBvc3NpYmxlIHRvIHByZXZlbnQgdGhpcyBiZWhhdmlvcgogICAgICAgICAqLwogICAgICAgIGNhbkRpc2FibGVBdXRvTGlua2luZyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3VwcG9ydHNDb21tYW5kKGRvY3VtZW50LCAiQXV0b1VybERldGVjdCIpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIElFIGxlYXZlcyBhbiBlbXB0eSBwYXJhZ3JhcGggaW4gdGhlIGNvbnRlbnRFZGl0YWJsZSBlbGVtZW50IGFmdGVyIGNsZWFyaW5nIGl0CiAgICAgICAgICogQ2hyb21lL1NhZmFyaSBzb21ldGltZXMgYW4gZW1wdHkgPGRpdj4KICAgICAgICAgKi8KICAgICAgICBjbGVhcnNDb250ZW50RWRpdGFibGVDb3JyZWN0bHkgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBpc0dlY2tvIHx8IGlzT3BlcmEgfHwgaXNXZWJLaXQ7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogSUUgZ2l2ZXMgd3JvbmcgcmVzdWx0cyBmb3IgZ2V0QXR0cmlidXRlCiAgICAgICAgICovCiAgICAgICAgc3VwcG9ydHNHZXRBdHRyaWJ1dGVDb3JyZWN0bHkgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciB0ZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRkIik7CiAgICAgICAgICAgIHJldHVybiB0ZC5nZXRBdHRyaWJ1dGUoInJvd3NwYW4iKSAhPSAiMSI7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV2hlbiBjbGlja2luZyBvbiBpbWFnZXMgaW4gSUUsIE9wZXJhIGFuZCBGaXJlZm94LCB0aGV5IGFyZSBzZWxlY3RlZCwgd2hpY2ggbWFrZXMgaXQgZWFzeSB0byBpbnRlcmFjdCB3aXRoIHRoZW0uCiAgICAgICAgICogQ2hyb21lIGFuZCBTYWZhcmkgYm90aCBkb24ndCBzdXBwb3J0IHRoaXMKICAgICAgICAgKi8KICAgICAgICBjYW5TZWxlY3RJbWFnZXNJbkNvbnRlbnRFZGl0YWJsZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIGlzR2Vja28gfHwgaXNJRSB8fCBpc09wZXJhOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEFsbCBicm93c2VycyBleGNlcHQgU2FmYXJpIGFuZCBDaHJvbWUgYXV0b21hdGljYWxseSBzY3JvbGwgdGhlIHJhbmdlL2NhcmV0IHBvc2l0aW9uIGludG8gdmlldwogICAgICAgICAqLwogICAgICAgIGF1dG9TY3JvbGxzVG9DYXJldCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICFpc1dlYktpdDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBicm93c2VyIGF1dG9tYXRpY2FsbHkgY2xvc2VzIHRhZ3MgdGhhdCBkb24ndCBuZWVkIHRvIGJlIG9wZW5lZAogICAgICAgICAqLwogICAgICAgIGF1dG9DbG9zZXNVbmNsb3NlZFRhZ3MgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBjbG9uZWRUZXN0RWxlbWVudCA9IHRlc3RFbGVtZW50LmNsb25lTm9kZShmYWxzZSksCiAgICAgICAgICAgICAgICByZXR1cm5WYWx1ZSwKICAgICAgICAgICAgICAgIGlubmVySFRNTDsKCiAgICAgICAgICAgIGNsb25lZFRlc3RFbGVtZW50LmlubmVySFRNTCA9ICI8cD48ZGl2PjwvZGl2PiI7CiAgICAgICAgICAgIGlubmVySFRNTCA9IGNsb25lZFRlc3RFbGVtZW50LmlubmVySFRNTC50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICByZXR1cm5WYWx1ZSA9IGlubmVySFRNTCA9PT0gIjxwPjwvcD48ZGl2PjwvZGl2PiIgfHwgaW5uZXJIVE1MID09PSAiPHA+PGRpdj48L2Rpdj48L3A+IjsKCiAgICAgICAgICAgIC8vIENhY2hlIHJlc3VsdCBieSBvdmVyd3JpdGluZyBjdXJyZW50IGZ1bmN0aW9uCiAgICAgICAgICAgIHRoaXMuYXV0b0Nsb3Nlc1VuY2xvc2VkVGFncyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTsKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBXaGV0aGVyIHRoZSBicm93c2VyIHN1cHBvcnRzIHRoZSBuYXRpdmUgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSB3aGljaCByZXR1cm5zIGxpdmUgTm9kZUxpc3RzCiAgICAgICAgICovCiAgICAgICAgc3VwcG9ydHNOYXRpdmVHZXRFbGVtZW50c0J5Q2xhc3NOYW1lIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gU3RyaW5nKGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUpLmluZGV4T2YoIltuYXRpdmUgY29kZV0iKSAhPT0gLTE7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQXMgb2Ygbm93ICgxOS4wNC4yMDExKSBvbmx5IHN1cHBvcnRlZCBieSBGaXJlZm94IDQgYW5kIENocm9tZQogICAgICAgICAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9ET00vU2VsZWN0aW9uL21vZGlmeQogICAgICAgICAqLwogICAgICAgIHN1cHBvcnRzU2VsZWN0aW9uTW9kaWZ5IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gImdldFNlbGVjdGlvbiIgaW4gd2luZG93ICYmICJtb2RpZnkiIGluIHdpbmRvdy5nZXRTZWxlY3Rpb24oKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBPcGVyYSBuZWVkcyBhIHdoaXRlIHNwYWNlIGFmdGVyIGEgPGJyPiBpbiBvcmRlciB0byBwb3NpdGlvbiB0aGUgY2FyZXQgY29ycmVjdGx5CiAgICAgICAgICovCiAgICAgICAgbmVlZHNTcGFjZUFmdGVyTGluZUJyZWFrIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNPcGVyYTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBXaGV0aGVyIHRoZSBicm93c2VyIHN1cHBvcnRzIHRoZSBzcGVlY2ggYXBpIG9uIHRoZSBnaXZlbiBlbGVtZW50CiAgICAgICAgICogU2VlIGh0dHA6Ly9taWtlcHVsdHouY29tLzIwMTEvMDMvYWNjZXNzaW5nLWdvb2dsZS1zcGVlY2gtYXBpLWNocm9tZS0xMS8KICAgICAgICAgKgogICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICogICAgdmFyIGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiaW5wdXQiKTsKICAgICAgICAgKiAgICBpZiAod3lzaWh0bWw1LmJyb3dzZXIuc3VwcG9ydHNTcGVlY2hBcGlPbihpbnB1dCkpIHsKICAgICAqICAgICAgLy8gLi4uCiAgICAgKiAgICB9CiAgICAgICAgICovCiAgICAgICAgc3VwcG9ydHNTcGVlY2hBcGlPbiA6IGZ1bmN0aW9uIChpbnB1dCkgewogICAgICAgICAgICB2YXIgY2hyb21lVmVyc2lvbiA9IHVzZXJBZ2VudC5tYXRjaCgvQ2hyb21lXC8oXGQrKS8pIHx8IFssIDBdOwogICAgICAgICAgICByZXR1cm4gY2hyb21lVmVyc2lvblsxXSA+PSAxMSAmJiAoIm9ud2Via2l0c3BlZWNoY2hhbmdlIiBpbiBpbnB1dCB8fCAic3BlZWNoIiBpbiBpbnB1dCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogSUU5IGNyYXNoZXMgd2hlbiBzZXR0aW5nIGEgZ2V0dGVyIHZpYSBPYmplY3QuZGVmaW5lUHJvcGVydHkgb24gWE1MSHR0cFJlcXVlc3Qgb3IgWERvbWFpblJlcXVlc3QKICAgICAgICAgKiBTZWUgaHR0cHM6Ly9jb25uZWN0Lm1pY3Jvc29mdC5jb20vaWUvZmVlZGJhY2svZGV0YWlscy82NTAxMTIKICAgICAgICAgKiBvciB0cnkgdGhlIFBPQyBodHRwOi8vdGlmZnRpZmYuZGUvaWU5X2NyYXNoLwogICAgICAgICAqLwogICAgICAgIGNyYXNoZXNXaGVuRGVmaW5lUHJvcGVydHkgOiBmdW5jdGlvbiAocHJvcGVydHkpIHsKICAgICAgICAgICAgcmV0dXJuIGlzSUUgJiYgKHByb3BlcnR5ID09PSAiWE1MSHR0cFJlcXVlc3QiIHx8IHByb3BlcnR5ID09PSAiWERvbWFpblJlcXVlc3QiKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBJRSBpcyB0aGUgb25seSBicm93c2VyIHdobyBmaXJlcyB0aGUgImZvY3VzIiBldmVudCBub3QgaW1tZWRpYXRlbHkgd2hlbiAuZm9jdXMoKSBpcyBjYWxsZWQgb24gYW4gZWxlbWVudAogICAgICAgICAqLwogICAgICAgIGRvZXNBc3luY0ZvY3VzIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNJRTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBJbiBJRSBpdCdzIGltcHNzaWJsZSBmb3IgdGhlIHVzZXIgYW5kIGZvciB0aGUgc2VsZWN0aW9uIGxpYnJhcnkgdG8gc2V0IHRoZSBjYXJldCBhZnRlciBhbiA8aW1nPiB3aGVuIGl0J3MgdGhlIGxhc3RDaGlsZCBpbiB0aGUgZG9jdW1lbnQKICAgICAgICAgKi8KICAgICAgICBoYXNQcm9ibGVtc1NldHRpbmdDYXJldEFmdGVySW1nIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNJRTsKICAgICAgICB9LAoKICAgICAgICBoYXNVbmRvSW5Db250ZXh0TWVudSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIGlzR2Vja28gfHwgaXNDaHJvbWUgfHwgaXNPcGVyYTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBPcGVyYSBzb21ldGltZXMgZG9lc24ndCBpbnNlcnQgdGhlIG5vZGUgYXQgdGhlIHJpZ2h0IHBvc2l0aW9uIHdoZW4gcmFuZ2UuaW5zZXJ0Tm9kZShzb21lTm9kZSkKICAgICAgICAgKiBpcyB1c2VkIChyZWdhcmRsZXNzIGlmIHJhbmd5IG9yIG5hdGl2ZSkKICAgICAgICAgKiBUaGlzIGVzcGVjaWFsbHkgaGFwcGVucyB3aGVuIHRoZSBjYXJldCBpcyBwb3NpdGlvbmVkIHJpZ2h0IGFmdGVyIGEgPGJyPiBiZWNhdXNlIHRoZW4KICAgICAgICAgKiBpbnNlcnROb2RlKCkgd2lsbCBpbnNlcnQgdGhlIG5vZGUgcmlnaHQgYmVmb3JlIHRoZSA8YnI+CiAgICAgICAgICovCiAgICAgICAgaGFzSW5zZXJ0Tm9kZUlzc3VlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNPcGVyYTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBJRSA4KzkgZG9uJ3QgZmlyZSB0aGUgZm9jdXMgZXZlbnQgb2YgdGhlIDxib2R5PiB3aGVuIHRoZSBpZnJhbWUgZ2V0cyBmb2N1c2VkIChldmVuIHRob3VnaCB0aGUgY2FyZXQgZ2V0cyBzZXQgaW50byB0aGUgPGJvZHk+KQogICAgICAgICAqLwogICAgICAgIGhhc0lmcmFtZUZvY3VzSXNzdWUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBpc0lFOwogICAgICAgIH0KICAgIH07Cn0pKCk7Cnd5c2lodG1sNS5sYW5nLmFycmF5ID0gZnVuY3Rpb24gKGFycikgewogICAgcmV0dXJuIHsKICAgICAgICAvKioKICAgICAgICAgKiBDaGVjayB3aGV0aGVyIGEgZ2l2ZW4gb2JqZWN0IGV4aXN0cyBpbiBhbiBhcnJheQogICAgICAgICAqCiAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgKiAgICB3eXNpaHRtbDUubGFuZy5hcnJheShbMSwgMl0pLmNvbnRhaW5zKDEpOwogICAgICAgICAqICAgIC8vID0+IHRydWUKICAgICAgICAgKi8KICAgICAgICBjb250YWlucyA6IGZ1bmN0aW9uIChuZWVkbGUpIHsKICAgICAgICAgICAgaWYgKGFyci5pbmRleE9mKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyLmluZGV4T2YobmVlZGxlKSAhPT0gLTE7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gYXJyLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGFycltpXSA9PT0gbmVlZGxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFN1YnN0cmFjdCBvbmUgYXJyYXkgZnJvbSBhbm90aGVyCiAgICAgICAgICoKICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAqICAgIHd5c2lodG1sNS5sYW5nLmFycmF5KFsxLCAyLCAzLCA0XSkud2l0aG91dChbMywgNF0pOwogICAgICAgICAqICAgIC8vID0+IFsxLCAyXQogICAgICAgICAqLwogICAgICAgIHdpdGhvdXQgOiBmdW5jdGlvbiAoYXJyYXlUb1N1YnN0cmFjdCkgewogICAgICAgICAgICBhcnJheVRvU3Vic3RyYWN0ID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoYXJyYXlUb1N1YnN0cmFjdCk7CiAgICAgICAgICAgIHZhciBuZXdBcnIgPSBbXSwKICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgbGVuZ3RoID0gYXJyLmxlbmd0aDsKICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICBpZiAoIWFycmF5VG9TdWJzdHJhY3QuY29udGFpbnMoYXJyW2ldKSkgewogICAgICAgICAgICAgICAgICAgIG5ld0Fyci5wdXNoKGFycltpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ld0FycjsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm4gYSBjbGVhbiBuYXRpdmUgYXJyYXkKICAgICAgICAgKgogICAgICAgICAqIEZvbGxvd2luZyB3aWxsIGNvbnZlcnQgYSBMaXZlIE5vZGVMaXN0IHRvIGEgcHJvcGVyIEFycmF5CiAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgKiAgICB2YXIgY2hpbGROb2RlcyA9IHd5c2lodG1sNS5sYW5nLmFycmF5KGRvY3VtZW50LmJvZHkuY2hpbGROb2RlcykuZ2V0KCk7CiAgICAgICAgICovCiAgICAgICAgZ2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgaSA9IDAsCiAgICAgICAgICAgICAgICBsZW5ndGggPSBhcnIubGVuZ3RoLAogICAgICAgICAgICAgICAgbmV3QXJyYXkgPSBbXTsKICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICBuZXdBcnJheS5wdXNoKGFycltpXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ld0FycmF5OwogICAgICAgIH0KICAgIH07Cn07Cnd5c2lodG1sNS5sYW5nLkRpc3BhdGNoZXIgPSBCYXNlLmV4dGVuZCgKICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LmxhbmcuRGlhbG9nLnByb3RvdHlwZSAqLyB7CiAgICAgICAgb24gOiBmdW5jdGlvbiAoZXZlbnROYW1lLCBoYW5kbGVyKSB7CiAgICAgICAgICAgIHRoaXMuZXZlbnRzID0gdGhpcy5ldmVudHMgfHwge307CiAgICAgICAgICAgIHRoaXMuZXZlbnRzW2V2ZW50TmFtZV0gPSB0aGlzLmV2ZW50c1tldmVudE5hbWVdIHx8IFtdOwogICAgICAgICAgICB0aGlzLmV2ZW50c1tldmVudE5hbWVdLnB1c2goaGFuZGxlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCgogICAgICAgIG9mZiA6IGZ1bmN0aW9uIChldmVudE5hbWUsIGhhbmRsZXIpIHsKICAgICAgICAgICAgdGhpcy5ldmVudHMgPSB0aGlzLmV2ZW50cyB8fCB7fTsKICAgICAgICAgICAgdmFyIGkgPSAwLAogICAgICAgICAgICAgICAgaGFuZGxlcnMsCiAgICAgICAgICAgICAgICBuZXdIYW5kbGVyczsKICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSkgewogICAgICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmV2ZW50c1tldmVudE5hbWVdIHx8IFtdLAogICAgICAgICAgICAgICAgICAgIG5ld0hhbmRsZXJzID0gW107CiAgICAgICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgICAgICBpIDwgaGFuZGxlcnMubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyc1tpXSAhPT0gaGFuZGxlciAmJiBoYW5kbGVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0hhbmRsZXJzLnB1c2goaGFuZGxlcnNbaV0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzW2V2ZW50TmFtZV0gPSBuZXdIYW5kbGVyczsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIENsZWFuIHVwIGFsbCBldmVudHMKICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzID0ge307CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgZmlyZSA6IGZ1bmN0aW9uIChldmVudE5hbWUsIHBheWxvYWQpIHsKICAgICAgICAgICAgdGhpcy5ldmVudHMgPSB0aGlzLmV2ZW50cyB8fCB7fTsKICAgICAgICAgICAgdmFyIGhhbmRsZXJzID0gdGhpcy5ldmVudHNbZXZlbnROYW1lXSB8fCBbXSwKICAgICAgICAgICAgICAgIGkgPSAwOwogICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgIGkgPCBoYW5kbGVycy5sZW5ndGg7CiAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgIGhhbmRsZXJzW2ldLmNhbGwodGhpcywgcGF5bG9hZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgLy8gZGVwcmVjYXRlZCwgdXNlIC5vbigpCiAgICAgICAgb2JzZXJ2ZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMub24uYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICAvLyBkZXByZWNhdGVkLCB1c2UgLm9mZigpCiAgICAgICAgc3RvcE9ic2VydmluZyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMub2ZmLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfQogICAgfSk7Cnd5c2lodG1sNS5sYW5nLm9iamVjdCA9IGZ1bmN0aW9uIChvYmopIHsKICAgIHJldHVybiB7CiAgICAgICAgLyoqCiAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgKiAgICB3eXNpaHRtbDUubGFuZy5vYmplY3QoeyBmb286IDEsIGJhcjogMSB9KS5tZXJnZSh7IGJhcjogMiwgYmF6OiAzIH0pLmdldCgpOwogICAgICAgICAqICAgIC8vID0+IHsgZm9vOiAxLCBiYXI6IDIsIGJhejogMyB9CiAgICAgICAgICovCiAgICAgICAgbWVyZ2UgOiBmdW5jdGlvbiAob3RoZXJPYmopIHsKICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBvdGhlck9iaikgewogICAgICAgICAgICAgICAgb2JqW2ldID0gb3RoZXJPYmpbaV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gb2JqOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICogICAgd3lzaWh0bWw1Lmxhbmcub2JqZWN0KHsgZm9vOiAxIH0pLmNsb25lKCk7CiAgICAgICAgICogICAgLy8gPT4geyBmb286IDEgfQogICAgICAgICAqLwogICAgICAgIGNsb25lIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgbmV3T2JqID0ge30sCiAgICAgICAgICAgICAgICBpOwogICAgICAgICAgICBmb3IgKGkgaW4gb2JqKSB7CiAgICAgICAgICAgICAgICBuZXdPYmpbaV0gPSBvYmpbaV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ld09iajsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAqICAgIHd5c2lodG1sNS5sYW5nLm9iamVjdChbXSkuaXNBcnJheSgpOwogICAgICAgICAqICAgIC8vID0+IHRydWUKICAgICAgICAgKi8KICAgICAgICBpc0FycmF5IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgPT09ICJbb2JqZWN0IEFycmF5XSI7CiAgICAgICAgfQogICAgfTsKfTsKKGZ1bmN0aW9uICgpIHsKICAgIHZhciBXSElURV9TUEFDRV9TVEFSVCA9IC9eXHMrLywKICAgICAgICBXSElURV9TUEFDRV9FTkQgPSAvXHMrJC87CiAgICB3eXNpaHRtbDUubGFuZy5zdHJpbmcgPSBmdW5jdGlvbiAoc3RyKSB7CiAgICAgICAgc3RyID0gU3RyaW5nKHN0cik7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHd5c2lodG1sNS5sYW5nLnN0cmluZygiICAgZm9vICAgIikudHJpbSgpOwogICAgICAgICAgICAgKiAgICAvLyA9PiAiZm9vIgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdHJpbSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzdHIucmVwbGFjZShXSElURV9TUEFDRV9TVEFSVCwgIiIpLnJlcGxhY2UoV0hJVEVfU1BBQ0VfRU5ELCAiIik7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICogICAgd3lzaWh0bWw1Lmxhbmcuc3RyaW5nKCJIZWxsbyAje25hbWV9IikuaW50ZXJwb2xhdGUoeyBuYW1lOiAiQ2hyaXN0b3BoZXIiIH0pOwogICAgICAgICAgICAgKiAgICAvLyA9PiAiSGVsbG8gQ2hyaXN0b3BoZXIiCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbnRlcnBvbGF0ZSA6IGZ1bmN0aW9uICh2YXJzKSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHZhcnMpIHsKICAgICAgICAgICAgICAgICAgICBzdHIgPSB0aGlzLnJlcGxhY2UoIiN7IiArIGkgKyAifSIpLmJ5KHZhcnNbaV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHN0cjsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKiAgICB3eXNpaHRtbDUubGFuZy5zdHJpbmcoIkhlbGxvIFRvbSIpLnJlcGxhY2UoIlRvbSIpLndpdGgoIkhhbnMiKTsKICAgICAgICAgICAgICogICAgLy8gPT4gIkhlbGxvIEhhbnMiCiAgICAgICAgICAgICAqLwogICAgICAgICAgICByZXBsYWNlIDogZnVuY3Rpb24gKHNlYXJjaCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICBieSA6IGZ1bmN0aW9uIChyZXBsYWNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHIuc3BsaXQoc2VhcmNoKS5qb2luKHJlcGxhY2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfTsKfSkoKTsKLyoqCiAqIEZpbmQgdXJscyBpbiBkZXNjZW5kYW50IHRleHQgbm9kZXMgb2YgYW4gZWxlbWVudCBhbmQgYXV0by1saW5rcyB0aGVtCiAqIEluc3BpcmVkIGJ5IGh0dHA6Ly9qYW1lcy5wYWRvbHNleS5jb20vamF2YXNjcmlwdC9maW5kLWFuZC1yZXBsYWNlLXRleHQtd2l0aC1qYXZhc2NyaXB0LwogKgogKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgQ29udGFpbmVyIGVsZW1lbnQgaW4gd2hpY2ggdG8gc2VhcmNoIGZvciB1cmxzCiAqCiAqIEBleGFtcGxlCiAqICAgIDxkaXYgaWQ9InRleHQtY29udGFpbmVyIj5QbGVhc2UgY2xpY2sgaGVyZTogd3d3Lmdvb2dsZS5jb208L2Rpdj4KICogICAgPHNjcmlwdD53eXNpaHRtbDUuZG9tLmF1dG9MaW5rKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0ZXh0LWNvbnRhaW5lciIpKTs8L3NjcmlwdD4KICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgLyoqCiAgICAgICAgICogRG9uJ3QgYXV0by1saW5rIHVybHMgdGhhdCBhcmUgY29udGFpbmVkIGluIHRoZSBmb2xsb3dpbmcgZWxlbWVudHM6CiAgICAgICAgICovCiAgICAgICAgSUdOT1JFX1VSTFNfSU4gPSB3eXNpaHRtbDUubGFuZy5hcnJheShbIkNPREUiLCAiUFJFIiwgIkEiLCAiU0NSSVBUIiwgIkhFQUQiLCAiVElUTEUiLCAiU1RZTEUiXSksCiAgICAgICAgLyoqCiAgICAgICAgICogcmV2aXNpb24gMToKICAgICAgICAgKiAgICAvKFxTK1wuezF9W15cc1wsXC5cIV0rKS9nCiAgICAgICAgICoKICAgICAgICAgKiByZXZpc2lvbiAyOgogICAgICAgICAqICAgIC8oXGIoKChodHRwcz98ZnRwKTpcL1wvKXwod3d3XC4pKVstQS1aMC05KyZAI1wvJT89fl98ITosLjtcW1xdXSpbLUEtWjAtOSsmQCNcLyU9fl98XSkvZ2ltCiAgICAgICAgICoKICAgICAgICAgKiBwdXQgdGhpcyBpbiB0aGUgYmVnaW5uaW5nIGlmIHlvdSBkb24ndCB3YW4ndCB0byBtYXRjaCB3aXRoaW4gYSB3b3JkCiAgICAgICAgICogICAgKF58W1w+XChce1xbXHNcPl0pCiAgICAgICAqLwogICAgICAgIFVSTF9SRUdfRVhQID0gLygoaHR0cHM/OlwvXC98d3d3XC4pW15cczxdezMsfSkvZ2ksCiAgICAgICAgVFJBSUxJTkdfQ0hBUl9SRUdfRVhQID0gLyhbXlx3XC9cLV0oLD8pKSQvaSwKICAgICAgICBNQVhfRElTUExBWV9MRU5HVEggPSAxMDAsCiAgICAgICAgQlJBQ0tFVFMgPSB7IikiIDogIigiLCAiXSIgOiAiWyIsICJ9IiA6ICJ7In07CgogICAgZnVuY3Rpb24gYXV0b0xpbmsoZWxlbWVudCkgewogICAgICAgIGlmIChfaGFzUGFyZW50VGhhdFNob3VsZEJlSWdub3JlZChlbGVtZW50KSkgewogICAgICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgICAgICB9CgogICAgICAgIGlmIChlbGVtZW50ID09PSBlbGVtZW50Lm93bmVyRG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSB7CiAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50Lm93bmVyRG9jdW1lbnQuYm9keTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBfcGFyc2VOb2RlKGVsZW1lbnQpOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBpcyBiYXNpY2FsbHkgYSByZWJ1aWxkIG9mCiAgICAgKiB0aGUgcmFpbHMgYXV0b19saW5rX3VybHMgdGV4dCBoZWxwZXIKICAgICAqLwogICAgZnVuY3Rpb24gX2NvbnZlcnRVcmxzVG9MaW5rcyhzdHIpIHsKICAgICAgICByZXR1cm4gc3RyLnJlcGxhY2UoVVJMX1JFR19FWFAsIGZ1bmN0aW9uIChtYXRjaCwgdXJsKSB7CiAgICAgICAgICAgIHZhciBwdW5jdHVhdGlvbiA9ICh1cmwubWF0Y2goVFJBSUxJTkdfQ0hBUl9SRUdfRVhQKSB8fCBbXSlbMV0gfHwgIiIsCiAgICAgICAgICAgICAgICBvcGVuaW5nID0gQlJBQ0tFVFNbcHVuY3R1YXRpb25dOwogICAgICAgICAgICB1cmwgPSB1cmwucmVwbGFjZShUUkFJTElOR19DSEFSX1JFR19FWFAsICIiKTsKCiAgICAgICAgICAgIGlmICh1cmwuc3BsaXQob3BlbmluZykubGVuZ3RoID4gdXJsLnNwbGl0KHB1bmN0dWF0aW9uKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHVybCA9IHVybCArIHB1bmN0dWF0aW9uOwogICAgICAgICAgICAgICAgcHVuY3R1YXRpb24gPSAiIjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgcmVhbFVybCA9IHVybCwKICAgICAgICAgICAgICAgIGRpc3BsYXlVcmwgPSB1cmw7CiAgICAgICAgICAgIGlmICh1cmwubGVuZ3RoID4gTUFYX0RJU1BMQVlfTEVOR1RIKSB7CiAgICAgICAgICAgICAgICBkaXNwbGF5VXJsID0gZGlzcGxheVVybC5zdWJzdHIoMCwgTUFYX0RJU1BMQVlfTEVOR1RIKSArICIuLi4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEFkZCBodHRwIHByZWZpeCBpZiBuZWNlc3NhcnkKICAgICAgICAgICAgaWYgKHJlYWxVcmwuc3Vic3RyKDAsIDQpID09PSAid3d3LiIpIHsKICAgICAgICAgICAgICAgIHJlYWxVcmwgPSAiaHR0cDovLyIgKyByZWFsVXJsOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9IicgKyByZWFsVXJsICsgJyI+JyArIGRpc3BsYXlVcmwgKyAnPC9hPicgKyBwdW5jdHVhdGlvbjsKICAgICAgICB9KTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgb3IgKGlmIGFscmVhZHkgY2FjaGVkKSByZXR1cm5zIGEgdGVtcCBlbGVtZW50CiAgICAgKiBmb3IgdGhlIGdpdmVuIGRvY3VtZW50IG9iamVjdAogICAgICovCiAgICBmdW5jdGlvbiBfZ2V0VGVtcEVsZW1lbnQoY29udGV4dCkgewogICAgICAgIHZhciB0ZW1wRWxlbWVudCA9IGNvbnRleHQuX3d5c2lodG1sNV90ZW1wRWxlbWVudDsKICAgICAgICBpZiAoIXRlbXBFbGVtZW50KSB7CiAgICAgICAgICAgIHRlbXBFbGVtZW50ID0gY29udGV4dC5fd3lzaWh0bWw1X3RlbXBFbGVtZW50ID0gY29udGV4dC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRlbXBFbGVtZW50OwogICAgfQoKICAgIC8qKgogICAgICogUmVwbGFjZXMgdGhlIG9yaWdpbmFsIHRleHQgbm9kZXMgd2l0aCB0aGUgbmV3bHkgYXV0by1saW5rZWQgZG9tIHRyZWUKICAgICAqLwogICAgZnVuY3Rpb24gX3dyYXBNYXRjaGVzSW5Ob2RlKHRleHROb2RlKSB7CiAgICAgICAgdmFyIHBhcmVudE5vZGUgPSB0ZXh0Tm9kZS5wYXJlbnROb2RlLAogICAgICAgICAgICB0ZW1wRWxlbWVudCA9IF9nZXRUZW1wRWxlbWVudChwYXJlbnROb2RlLm93bmVyRG9jdW1lbnQpOwoKICAgICAgICAvLyBXZSBuZWVkIHRvIGluc2VydCBhbiBlbXB0eS90ZW1wb3JhcnkgPHNwYW4gLz4gdG8gZml4IElFIHF1aXJrcwogICAgICAgIC8vIEVsc2V3aXNlIElFIHdvdWxkIHN0cmlwIHdoaXRlIHNwYWNlIGluIHRoZSBiZWdpbm5pbmcKICAgICAgICB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPSAiPHNwYW4+PC9zcGFuPiIgKyBfY29udmVydFVybHNUb0xpbmtzKHRleHROb2RlLmRhdGEpOwogICAgICAgIHRlbXBFbGVtZW50LnJlbW92ZUNoaWxkKHRlbXBFbGVtZW50LmZpcnN0Q2hpbGQpOwoKICAgICAgICB3aGlsZSAodGVtcEVsZW1lbnQuZmlyc3RDaGlsZCkgewogICAgICAgICAgICAvLyBpbnNlcnRzIHRlbXBFbGVtZW50LmZpcnN0Q2hpbGQgYmVmb3JlIHRleHROb2RlCiAgICAgICAgICAgIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRlbXBFbGVtZW50LmZpcnN0Q2hpbGQsIHRleHROb2RlKTsKICAgICAgICB9CiAgICAgICAgcGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0ZXh0Tm9kZSk7CiAgICB9CgogICAgZnVuY3Rpb24gX2hhc1BhcmVudFRoYXRTaG91bGRCZUlnbm9yZWQobm9kZSkgewogICAgICAgIHZhciBub2RlTmFtZTsKICAgICAgICB3aGlsZSAobm9kZS5wYXJlbnROb2RlKSB7CiAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgICAgIG5vZGVOYW1lID0gbm9kZS5ub2RlTmFtZTsKICAgICAgICAgICAgaWYgKElHTk9SRV9VUkxTX0lOLmNvbnRhaW5zKG5vZGVOYW1lKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXd5c2lodG1sNS51dGlsLmlzRWRpdG9yTm9kZShub2RlKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcGFyc2VOb2RlKGVsZW1lbnQpIHsKICAgICAgICBpZiAoSUdOT1JFX1VSTFNfSU4uY29udGFpbnMoZWxlbWVudC5ub2RlTmFtZSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKGVsZW1lbnQubm9kZVR5cGUgPT09IHd5c2lodG1sNS5URVhUX05PREUgJiYgZWxlbWVudC5kYXRhLm1hdGNoKFVSTF9SRUdfRVhQKSkgewogICAgICAgICAgICBfd3JhcE1hdGNoZXNJbk5vZGUoZWxlbWVudCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHZhciBjaGlsZE5vZGVzID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoZWxlbWVudC5jaGlsZE5vZGVzKS5nZXQoKSwKICAgICAgICAgICAgY2hpbGROb2Rlc0xlbmd0aCA9IGNoaWxkTm9kZXMubGVuZ3RoLAogICAgICAgICAgICBpID0gMDsKCiAgICAgICAgZm9yICg7CiAgICAgICAgICAgIGkgPCBjaGlsZE5vZGVzTGVuZ3RoOwogICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgX3BhcnNlTm9kZShjaGlsZE5vZGVzW2ldKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBlbGVtZW50OwogICAgfQoKICAgIHd5c2lodG1sNS5kb20uYXV0b0xpbmsgPSBhdXRvTGluazsKCiAgICAvLyBSZXZlYWwgdXJsIHJlZyBleHAgdG8gdGhlIG91dHNpZGUKICAgIHd5c2lodG1sNS5kb20uYXV0b0xpbmsuVVJMX1JFR19FWFAgPSBVUkxfUkVHX0VYUDsKfSkod3lzaWh0bWw1KTsKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBhcGkgPSB3eXNpaHRtbDUuZG9tOwoKICAgIGFwaS5hZGRDbGFzcyA9IGZ1bmN0aW9uIChlbGVtZW50LCBjbGFzc05hbWUpIHsKICAgICAgICB2YXIgY2xhc3NMaXN0ID0gZWxlbWVudC5jbGFzc0xpc3Q7CiAgICAgICAgaWYgKGNsYXNzTGlzdCkgewogICAgICAgICAgICByZXR1cm4gY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpOwogICAgICAgIH0KICAgICAgICBpZiAoYXBpLmhhc0NsYXNzKGVsZW1lbnQsIGNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBlbGVtZW50LmNsYXNzTmFtZSArPSAiICIgKyBjbGFzc05hbWU7CiAgICB9OwoKICAgIGFwaS5yZW1vdmVDbGFzcyA9IGZ1bmN0aW9uIChlbGVtZW50LCBjbGFzc05hbWUpIHsKICAgICAgICB2YXIgY2xhc3NMaXN0ID0gZWxlbWVudC5jbGFzc0xpc3Q7CiAgICAgICAgaWYgKGNsYXNzTGlzdCkgewogICAgICAgICAgICByZXR1cm4gY2xhc3NMaXN0LnJlbW92ZShjbGFzc05hbWUpOwogICAgICAgIH0KCiAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50LmNsYXNzTmFtZS5yZXBsYWNlKG5ldyBSZWdFeHAoIihefFxccyspIiArIGNsYXNzTmFtZSArICIoXFxzK3wkKSIpLCAiICIpOwogICAgfTsKCiAgICBhcGkuaGFzQ2xhc3MgPSBmdW5jdGlvbiAoZWxlbWVudCwgY2xhc3NOYW1lKSB7CiAgICAgICAgdmFyIGNsYXNzTGlzdCA9IGVsZW1lbnQuY2xhc3NMaXN0OwogICAgICAgIGlmIChjbGFzc0xpc3QpIHsKICAgICAgICAgICAgcmV0dXJuIGNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpOwogICAgICAgIH0KCiAgICAgICAgdmFyIGVsZW1lbnRDbGFzc05hbWUgPSBlbGVtZW50LmNsYXNzTmFtZTsKICAgICAgICByZXR1cm4gKGVsZW1lbnRDbGFzc05hbWUubGVuZ3RoID4gMCAmJiAoZWxlbWVudENsYXNzTmFtZSA9PSBjbGFzc05hbWUgfHwgbmV3IFJlZ0V4cCgiKF58XFxzKSIgKyBjbGFzc05hbWUgKyAiKFxcc3wkKSIpLnRlc3QoZWxlbWVudENsYXNzTmFtZSkpKTsKICAgIH07Cn0pKHd5c2lodG1sNSk7Cnd5c2lodG1sNS5kb20uY29udGFpbnMgPSAoZnVuY3Rpb24gKCkgewogICAgdmFyIGRvY3VtZW50RWxlbWVudCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDsKICAgIGlmIChkb2N1bWVudEVsZW1lbnQuY29udGFpbnMpIHsKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGNvbnRhaW5lciwgZWxlbWVudCkgewogICAgICAgICAgICBpZiAoZWxlbWVudC5ub2RlVHlwZSAhPT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERSkgewogICAgICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY29udGFpbmVyICE9PSBlbGVtZW50ICYmIGNvbnRhaW5lci5jb250YWlucyhlbGVtZW50KTsKICAgICAgICB9OwogICAgfSBlbHNlIGlmIChkb2N1bWVudEVsZW1lbnQuY29tcGFyZURvY3VtZW50UG9zaXRpb24pIHsKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGNvbnRhaW5lciwgZWxlbWVudCkgewogICAgICAgICAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9ET00vTm9kZS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbgogICAgICAgICAgICByZXR1cm4gISEoY29udGFpbmVyLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGVsZW1lbnQpICYgMTYpOwogICAgICAgIH07CiAgICB9Cn0pKCk7Ci8qKgogKiBDb252ZXJ0cyBhbiBIVE1MIGZyYWdtZW50L2VsZW1lbnQgaW50byBhIHVub3JkZXJlZC9vcmRlcmVkIGxpc3QKICoKICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHdoaWNoIHNob3VsZCBiZSB0dXJuZWQgaW50byBhIGxpc3QKICogQHBhcmFtIHtTdHJpbmd9IGxpc3RUeXBlIFRoZSBsaXN0IHR5cGUgaW4gd2hpY2ggdG8gY29udmVydCB0aGUgdHJlZSAoZWl0aGVyICJ1bCIgb3IgIm9sIikKICogQHJldHVybiB7RWxlbWVudH0gVGhlIGNyZWF0ZWQgbGlzdAogKgogKiBAZXhhbXBsZQogKiAgICA8IS0tIEFzc3VtZSB0aGUgZm9sbG93aW5nIGRvbTogLS0+CiAqICAgIDxzcGFuIGlkPSJwc2V1ZG8tbGlzdCI+CiAqICAgICAgZW1pbmVtPGJyPgogKiAgICAgIGRyLiBkcmUKICogICAgICA8ZGl2PjUwIENlbnQ8L2Rpdj4KICogICAgPC9zcGFuPgogKgogKiAgICA8c2NyaXB0PgogKiAgICAgIHd5c2lodG1sNS5kb20uY29udmVydFRvTGlzdChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicHNldWRvLWxpc3QiKSwgInVsIik7CiAqICAgIDwvc2NyaXB0PgogKgogKiAgICA8IS0tIFdpbGwgcmVzdWx0IGluOiAtLT4KICogICAgPHVsPgogKiAgICAgIDxsaT5lbWluZW08L2xpPgogKiAgICAgIDxsaT5kci4gZHJlPC9saT4KICogICAgICA8bGk+NTAgQ2VudDwvbGk+CiAqICAgIDwvdWw+CiAqLwp3eXNpaHRtbDUuZG9tLmNvbnZlcnRUb0xpc3QgPSAoZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gX2NyZWF0ZUxpc3RJdGVtKGRvYywgbGlzdCwgaXNCbG9ja0VsZW1lbnQpIHsKICAgICAgICB2YXIgbGlzdEl0ZW0gPSBkb2MuY3JlYXRlRWxlbWVudCgibGkiKTsKICAgICAgICBsaXN0LmFwcGVuZENoaWxkKGxpc3RJdGVtKTsKICAgICAgICBpZiAoaXNCbG9ja0VsZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGxpc3RJdGVtOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZhciBwYXJhID0gZG9jLmNyZWF0ZUVsZW1lbnQoInAiKTsKICAgICAgICAgICAgbGlzdEl0ZW0uYXBwZW5kQ2hpbGQocGFyYSk7CiAgICAgICAgICAgIHJldHVybiBwYXJhOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfY3JlYXRlTGlzdChkb2MsIHR5cGUsIGxpc3RUeXBlKSB7CiAgICAgICAgdmFyIGUgPSBkb2MuY3JlYXRlRWxlbWVudCh0eXBlKTsKICAgICAgICBpZiAobGlzdFR5cGUgJiYgbGlzdFR5cGUgIT0gIk9yZGVyZWQiKSB7CiAgICAgICAgICAgIGUuc2V0QXR0cmlidXRlKCJ0eXBlIiwgbGlzdFR5cGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZTsKICAgIH0KCiAgICBmdW5jdGlvbiBjb252ZXJ0VG9MaXN0KGVsZW1lbnQsIGxpc3RUeXBlLCB0eXBlKSB7CiAgICAgICAgaWYgKGVsZW1lbnQubm9kZU5hbWUgPT09ICJVTCIgfHwgZWxlbWVudC5ub2RlTmFtZSA9PT0gIk9MIiB8fCBlbGVtZW50Lm5vZGVOYW1lID09PSAiTUVOVSIpIHsKICAgICAgICAgICAgLy8gQWxyZWFkeSBhIGxpc3QKICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICAgICAgfQogICAgICAgIHZhciBkb2MgPSBlbGVtZW50Lm93bmVyRG9jdW1lbnQsCiAgICAgICAgICAgIGxpc3QgPSBfY3JlYXRlTGlzdChkb2MsIGxpc3RUeXBlLCB0eXBlKSwKICAgICAgICAgICAgbGluZUJyZWFrcyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgiYnIiKSwKICAgICAgICAgICAgbGluZUJyZWFrc0xlbmd0aCA9IGxpbmVCcmVha3MubGVuZ3RoLAogICAgICAgICAgICBjaGlsZE5vZGVzLAogICAgICAgICAgICBjaGlsZE5vZGVzTGVuZ3RoLAogICAgICAgICAgICBjaGlsZE5vZGUsCiAgICAgICAgICAgIGxpbmVCcmVhaywKICAgICAgICAgICAgcGFyZW50Tm9kZSwKICAgICAgICAgICAgaXNCbG9ja0VsZW1lbnQsCiAgICAgICAgICAgIGlzTGluZUJyZWFrLAogICAgICAgICAgICBjdXJyZW50TGlzdEl0ZW0sCiAgICAgICAgICAgIGk7CgogICAgICAgIC8vIEZpcnN0IGZpbmQgPGJyPiBhdCB0aGUgZW5kIG9mIGlubGluZSBlbGVtZW50cyBhbmQgbW92ZSB0aGVtIGJlaGluZCB0aGVtCiAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgIGkgPCBsaW5lQnJlYWtzTGVuZ3RoOwogICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgIGxpbmVCcmVhayA9IGxpbmVCcmVha3NbaV07CiAgICAgICAgICAgIHdoaWxlICgocGFyZW50Tm9kZSA9IGxpbmVCcmVhay5wYXJlbnROb2RlKSAmJiBwYXJlbnROb2RlICE9PSBlbGVtZW50ICYmIHBhcmVudE5vZGUubGFzdENoaWxkID09PSBsaW5lQnJlYWspIHsKICAgICAgICAgICAgICAgIGlmICh3eXNpaHRtbDUuZG9tLmdldFN0eWxlKCJkaXNwbGF5IikuZnJvbShwYXJlbnROb2RlKSA9PT0gImJsb2NrIikgewogICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobGluZUJyZWFrKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHd5c2lodG1sNS5kb20uaW5zZXJ0KGxpbmVCcmVhaykuYWZ0ZXIobGluZUJyZWFrLnBhcmVudE5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBjaGlsZE5vZGVzID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoZWxlbWVudC5jaGlsZE5vZGVzKS5nZXQoKTsKICAgICAgICBjaGlsZE5vZGVzTGVuZ3RoID0gY2hpbGROb2Rlcy5sZW5ndGg7CiAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgIGkgPCBjaGlsZE5vZGVzTGVuZ3RoOwogICAgICAgICAgICAgaSsrKSB7CgogICAgICAgICAgICBjaGlsZE5vZGUgPSBjaGlsZE5vZGVzW2ldOwogICAgICAgICAgICBpc0Jsb2NrRWxlbWVudCA9IHd5c2lodG1sNS5kb20uZ2V0U3R5bGUoImRpc3BsYXkiKS5mcm9tKGNoaWxkTm9kZSkgPT09ICJibG9jayIgfHwgKGNoaWxkTm9kZSAmJiBjaGlsZE5vZGUucXVlcnlTZWxlY3RvciAmJiBjaGlsZE5vZGUucXVlcnlTZWxlY3Rvcih3eXNpaHRtbDUuQkxPQ0tfRUxFTUVOVFNfR1JPVVAuam9pbigiLCIpKSk7CiAgICAgICAgICAgIGlzTGluZUJyZWFrID0gY2hpbGROb2RlLm5vZGVOYW1lID09PSAiQlIiOwoKICAgICAgICAgICAgaWYgKGNoaWxkTm9kZSAmJiBjaGlsZE5vZGUuY2xhc3NOYW1lID09ICJfd3lzaWh0bWw1LXRlbXAtcGxhY2Vob2xkZXIiKSB7Ly8gaWdub3JlIGNoaWxkTm9kZSBjcmV0ZWQgYnkgZXhlY3V0ZUFuZFJlc3RvcmUKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNCbG9ja0VsZW1lbnQpIHsKICAgICAgICAgICAgICAgIGN1cnJlbnRMaXN0SXRlbSA9IF9jcmVhdGVMaXN0SXRlbShkb2MsIGxpc3QsIGlzQmxvY2tFbGVtZW50KTsKICAgICAgICAgICAgICAgIGN1cnJlbnRMaXN0SXRlbS5hcHBlbmRDaGlsZChjaGlsZE5vZGUpOwogICAgICAgICAgICAgICAgY3VycmVudExpc3RJdGVtID0gbnVsbDsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNMaW5lQnJlYWspIHsKICAgICAgICAgICAgICAgIC8vIE9ubHkgY3JlYXRlIGEgbmV3IGxpc3QgaXRlbSBpbiB0aGUgbmV4dCBpdGVyYXRpb24gd2hlbiB0aGUgY3VycmVudCBvbmUgaGFzIGFscmVhZHkgY29udGVudCwKICAgICAgICAgICAgICAgIGlmIChpICE9IGNoaWxkTm9kZXNMZW5ndGggLSAxKSB7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudExpc3RJdGVtID0gKGN1cnJlbnRMaXN0SXRlbSAmJiBjdXJyZW50TGlzdEl0ZW0uZmlyc3RDaGlsZCkgPyBudWxsIDogY3VycmVudExpc3RJdGVtOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJlbnRMaXN0SXRlbSA9IGN1cnJlbnRMaXN0SXRlbSB8fCBfY3JlYXRlTGlzdEl0ZW0oZG9jLCBsaXN0LCBpc0Jsb2NrRWxlbWVudCk7CiAgICAgICAgICAgIGN1cnJlbnRMaXN0SXRlbS5hcHBlbmRDaGlsZChjaGlsZE5vZGUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGNoaWxkTm9kZXMubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgIF9jcmVhdGVMaXN0SXRlbShkb2MsIGxpc3QpOwogICAgICAgIH0KCiAgICAgICAgZWxlbWVudC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChsaXN0LCBlbGVtZW50KTsKICAgICAgICByZXR1cm4gbGlzdDsKICAgIH0KCiAgICByZXR1cm4gY29udmVydFRvTGlzdDsKfSkoKTsKLyoqCiAqIENvcHkgYSBzZXQgb2YgYXR0cmlidXRlcyBmcm9tIG9uZSBlbGVtZW50IHRvIGFub3RoZXIKICoKICogQHBhcmFtIHtBcnJheX0gYXR0cmlidXRlc1RvQ29weSBMaXN0IG9mIGF0dHJpYnV0ZXMgd2hpY2ggc2hvdWxkIGJlIGNvcGllZAogKiBAcmV0dXJuIHtPYmplY3R9IFJldHVybnMgYW4gb2JqZWN0IHdoaWNoIG9mZmVycyB0aGUgImZyb20iIG1ldGhvZCB3aGljaCBjYW4gYmUgaW52b2tlZCB3aXRoIHRoZSBlbGVtZW50IHdoZXJlIHRvCiAqICAgIGNvcHkgdGhlIGF0dHJpYnV0ZXMgZnJvbS4sIHRoaXMgYWdhaW4gcmV0dXJucyBhbiBvYmplY3Qgd2hpY2ggcHJvdmlkZXMgYSBtZXRob2QgbmFtZWQgInRvIiB3aGljaCBjYW4gYmUgaW52b2tlZAogKiAgICB3aXRoIHRoZSBlbGVtZW50IHdoZXJlIHRvIGNvcHkgdGhlIGF0dHJpYnV0ZXMgdG8gKHNlZSBleGFtcGxlKQogKgogKiBAZXhhbXBsZQogKiAgICB2YXIgdGV4dGFyZWEgICAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJ0ZXh0YXJlYSIpLAogKiAgICAgICAgZGl2ICAgICAgICAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJkaXZbY29udGVudGVkaXRhYmxlPXRydWVdIiksCiAqICAgICAgICBhbm90aGVyRGl2ICA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImRpdi5wcmV2aWV3Iik7CiAqICAgIHd5c2lodG1sNS5kb20uY29weUF0dHJpYnV0ZXMoWyJzcGVsbGNoZWNrIiwgInZhbHVlIiwgInBsYWNlaG9sZGVyIl0pLmZyb20odGV4dGFyZWEpLnRvKGRpdikuYW5kVG8oYW5vdGhlckRpdik7CiAqCiAqLwp3eXNpaHRtbDUuZG9tLmNvcHlBdHRyaWJ1dGVzID0gZnVuY3Rpb24gKGF0dHJpYnV0ZXNUb0NvcHkpIHsKICAgIHJldHVybiB7CiAgICAgICAgZnJvbSA6IGZ1bmN0aW9uIChlbGVtZW50VG9Db3B5RnJvbSkgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgdG8gOiBmdW5jdGlvbiAoZWxlbWVudFRvQ29weVRvKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgaSA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IGF0dHJpYnV0ZXNUb0NvcHkubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgIGZvciAoOwogICAgICAgICAgICAgICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlID0gYXR0cmlidXRlc1RvQ29weVtpXTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZihlbGVtZW50VG9Db3B5RnJvbVthdHRyaWJ1dGVdKSAhPT0gInVuZGVmaW5lZCIgJiYgZWxlbWVudFRvQ29weUZyb21bYXR0cmlidXRlXSAhPT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRUb0NvcHlUb1thdHRyaWJ1dGVdID0gZWxlbWVudFRvQ29weUZyb21bYXR0cmlidXRlXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4ge2FuZFRvIDogYXJndW1lbnRzLmNhbGxlZX07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfTsKfTsKLyoqCiAqIENvcHkgYSBzZXQgb2Ygc3R5bGVzIGZyb20gb25lIGVsZW1lbnQgdG8gYW5vdGhlcgogKiBQbGVhc2Ugbm90ZSB0aGF0IHRoaXMgb25seSB3b3JrcyBwcm9wZXJseSBhY3Jvc3MgYnJvd3NlcnMgd2hlbiB0aGUgZWxlbWVudCBmcm9tIHdoaWNoIHRvIGNvcHkgdGhlIHN0eWxlcwogKiBpcyBpbiB0aGUgZG9tCiAqCiAqIEludGVyZXN0aW5nIGFydGljbGUgb24gaG93IHRvIGNvcHkgc3R5bGVzCiAqCiAqIEBwYXJhbSB7QXJyYXl9IHN0eWxlc1RvQ29weSBMaXN0IG9mIHN0eWxlcyB3aGljaCBzaG91bGQgYmUgY29waWVkCiAqIEByZXR1cm4ge09iamVjdH0gUmV0dXJucyBhbiBvYmplY3Qgd2hpY2ggb2ZmZXJzIHRoZSAiZnJvbSIgbWV0aG9kIHdoaWNoIGNhbiBiZSBpbnZva2VkIHdpdGggdGhlIGVsZW1lbnQgd2hlcmUgdG8KICogICAgY29weSB0aGUgc3R5bGVzIGZyb20uLCB0aGlzIGFnYWluIHJldHVybnMgYW4gb2JqZWN0IHdoaWNoIHByb3ZpZGVzIGEgbWV0aG9kIG5hbWVkICJ0byIgd2hpY2ggY2FuIGJlIGludm9rZWQKICogICAgd2l0aCB0aGUgZWxlbWVudCB3aGVyZSB0byBjb3B5IHRoZSBzdHlsZXMgdG8gKHNlZSBleGFtcGxlKQogKgogKiBAZXhhbXBsZQogKiAgICB2YXIgdGV4dGFyZWEgICAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJ0ZXh0YXJlYSIpLAogKiAgICAgICAgZGl2ICAgICAgICAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJkaXZbY29udGVudGVkaXRhYmxlPXRydWVdIiksCiAqICAgICAgICBhbm90aGVyRGl2ICA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImRpdi5wcmV2aWV3Iik7CiAqICAgIHd5c2lodG1sNS5kb20uY29weVN0eWxlcyhbIm92ZXJmbG93LXkiLCAid2lkdGgiLCAiaGVpZ2h0Il0pLmZyb20odGV4dGFyZWEpLnRvKGRpdikuYW5kVG8oYW5vdGhlckRpdik7CiAqCiAqLwooZnVuY3Rpb24gKGRvbSkgewoKICAgIC8qKgogICAgICogTW96aWxsYSwgV2ViS2l0IGFuZCBPcGVyYSByZWNhbGN1bGF0ZSB0aGUgY29tcHV0ZWQgd2lkdGggd2hlbiBib3gtc2l6aW5nOiBib2Rlci1ib3g7IGlzIHNldAogICAgICogU28gaWYgYW4gZWxlbWVudCBoYXMgIndpZHRoOiAyMDBweDsgLW1vei1ib3gtc2l6aW5nOiBib3JkZXItYm94OyBib3JkZXI6IDFweDsiIHRoZW4KICAgICAqIGl0cyBjb21wdXRlZCBjc3Mgd2lkdGggd2lsbCBiZSAxOThweAogICAgICoKICAgICAqIFNlZSBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD01MjA5OTIKICAgICAqLwogICAgdmFyIEJPWF9TSVpJTkdfUFJPUEVSVElFUyA9IFsiLXdlYmtpdC1ib3gtc2l6aW5nIiwgIi1tb3otYm94LXNpemluZyIsICItbXMtYm94LXNpemluZyIsICJib3gtc2l6aW5nIl07CgogICAgdmFyIHNob3VsZElnbm9yZUJveFNpemluZ0JvcmRlckJveCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgICAgaWYgKGhhc0JveFNpemluZ0JvcmRlckJveChlbGVtZW50KSkgewogICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQoZG9tLmdldFN0eWxlKCJ3aWR0aCIpLmZyb20oZWxlbWVudCksIDEwKSA8IGVsZW1lbnQub2Zmc2V0V2lkdGg7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CgogICAgdmFyIGhhc0JveFNpemluZ0JvcmRlckJveCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgICAgdmFyIGkgPSAwLAogICAgICAgICAgICBsZW5ndGggPSBCT1hfU0laSU5HX1BST1BFUlRJRVMubGVuZ3RoOwogICAgICAgIGZvciAoOwogICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgaWYgKGRvbS5nZXRTdHlsZShCT1hfU0laSU5HX1BST1BFUlRJRVNbaV0pLmZyb20oZWxlbWVudCkgPT09ICJib3JkZXItYm94IikgewogICAgICAgICAgICAgICAgcmV0dXJuIEJPWF9TSVpJTkdfUFJPUEVSVElFU1tpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgZG9tLmNvcHlTdHlsZXMgPSBmdW5jdGlvbiAoc3R5bGVzVG9Db3B5KSB7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgZnJvbSA6IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgICAgICAgICAgICBpZiAoc2hvdWxkSWdub3JlQm94U2l6aW5nQm9yZGVyQm94KGVsZW1lbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgc3R5bGVzVG9Db3B5ID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoc3R5bGVzVG9Db3B5KS53aXRob3V0KEJPWF9TSVpJTkdfUFJPUEVSVElFUyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyIGNzc1RleHQgPSAiIiwKICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSBzdHlsZXNUb0NvcHkubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OwogICAgICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eSA9IHN0eWxlc1RvQ29weVtpXTsKICAgICAgICAgICAgICAgICAgICBjc3NUZXh0ICs9IHByb3BlcnR5ICsgIjoiICsgZG9tLmdldFN0eWxlKHByb3BlcnR5KS5mcm9tKGVsZW1lbnQpICsgIjsiOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAgICAgdG8gOiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBkb20uc2V0U3R5bGVzKGNzc1RleHQpLm9uKGVsZW1lbnQpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge2FuZFRvIDogYXJndW1lbnRzLmNhbGxlZX07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9Owp9KSh3eXNpaHRtbDUuZG9tKTsKLyoqCiAqIEV2ZW50IERlbGVnYXRpb24KICoKICogQGV4YW1wbGUKICogICAgd3lzaWh0bWw1LmRvbS5kZWxlZ2F0ZShkb2N1bWVudC5ib2R5LCAiYSIsICJjbGljayIsIGZ1bmN0aW9uKCkgewogKiAgICAgIC8vIGZvbwogKiAgICB9KTsKICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CgogICAgd3lzaWh0bWw1LmRvbS5kZWxlZ2F0ZSA9IGZ1bmN0aW9uIChjb250YWluZXIsIHNlbGVjdG9yLCBldmVudE5hbWUsIGhhbmRsZXIpIHsKICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmRvbS5vYnNlcnZlKGNvbnRhaW5lciwgZXZlbnROYW1lLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgdmFyIHRhcmdldCA9IGV2ZW50LnRhcmdldCwKICAgICAgICAgICAgICAgIG1hdGNoID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpKTsKCiAgICAgICAgICAgIHdoaWxlICh0YXJnZXQgJiYgdGFyZ2V0ICE9PSBjb250YWluZXIpIHsKICAgICAgICAgICAgICAgIGlmIChtYXRjaC5jb250YWlucyh0YXJnZXQpKSB7CiAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5jYWxsKHRhcmdldCwgZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBSZXR1cm5zIHRoZSBnaXZlbiBodG1sIHdyYXBwZWQgaW4gYSBkaXYgZWxlbWVudAogKgogKiBGaXhpbmcgSUUncyBpbmFiaWxpdHkgdG8gdHJlYXQgdW5rbm93biBlbGVtZW50cyAoSFRNTDUgc2VjdGlvbiwgYXJ0aWNsZSwgLi4uKSBjb3JyZWN0bHkKICogd2hlbiBpbnNlcnRlZCB2aWEgaW5uZXJIVE1MCiAqCiAqIEBwYXJhbSB7U3RyaW5nfSBodG1sIFRoZSBodG1sIHdoaWNoIHNob3VsZCBiZSB3cmFwcGVkIGluIGEgZG9tIGVsZW1lbnQKICogQHBhcmFtIHtPYmVqY3R9IFtjb250ZXh0XSBEb2N1bWVudCBvYmplY3Qgb2YgdGhlIGNvbnRleHQgdGhlIGh0bWwgYmVsb25ncyB0bwogKgogKiBAZXhhbXBsZQogKiAgICB3eXNpaHRtbDUuZG9tLmdldEFzRG9tKCI8YXJ0aWNsZT5mb288L2FydGljbGU+Iik7CiAqLwp3eXNpaHRtbDUuZG9tLmdldEFzRG9tID0gKGZ1bmN0aW9uICgpIHsKCiAgICB2YXIgX2lubmVySFRNTFNoaXYgPSBmdW5jdGlvbiAoaHRtbCwgY29udGV4dCkgewogICAgICAgIHZhciB0ZW1wRWxlbWVudCA9IGNvbnRleHQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CiAgICAgICAgdGVtcEVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICJub25lIjsKICAgICAgICBjb250ZXh0LmJvZHkuYXBwZW5kQ2hpbGQodGVtcEVsZW1lbnQpOwogICAgICAgIC8vIElFIHRocm93cyBhbiBleGNlcHRpb24gd2hlbiB0cnlpbmcgdG8gaW5zZXJ0IDxmcmFtZXNldD48L2ZyYW1lc2V0PiB2aWEgaW5uZXJIVE1MCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdGVtcEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgfQogICAgICAgIGNvbnRleHQuYm9keS5yZW1vdmVDaGlsZCh0ZW1wRWxlbWVudCk7CiAgICAgICAgcmV0dXJuIHRlbXBFbGVtZW50OwogICAgfTsKCiAgICAvKioKICAgICAqIE1ha2Ugc3VyZSBJRSBzdXBwb3J0cyBIVE1MNSB0YWdzLCB3aGljaCBpcyBhY2NvbXBsaXNoZWQgYnkgc2ltcGx5IGNyZWF0aW5nIG9uZSBpbnN0YW5jZSBvZiBlYWNoIGVsZW1lbnQKICAgICAqLwogICAgdmFyIF9lbnN1cmVIVE1MNUNvbXBhdGliaWxpdHkgPSBmdW5jdGlvbiAoY29udGV4dCkgewogICAgICAgIGlmIChjb250ZXh0Ll93eXNpaHRtbDVfc3VwcG9ydHNIVE1MNVRhZ3MpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gSFRNTDVfRUxFTUVOVFMubGVuZ3RoOwogICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoSFRNTDVfRUxFTUVOVFNbaV0pOwogICAgICAgIH0KICAgICAgICBjb250ZXh0Ll93eXNpaHRtbDVfc3VwcG9ydHNIVE1MNVRhZ3MgPSB0cnVlOwogICAgfTsKCiAgICAvKioKICAgICAqIExpc3Qgb2YgaHRtbDUgdGFncwogICAgICogdGFrZW4gZnJvbSBodHRwOi8vc2ltb24uaHRtbDUub3JnL2h0bWw1LWVsZW1lbnRzCiAgICAgKi8KICAgIHZhciBIVE1MNV9FTEVNRU5UUyA9IFsKICAgICAgICAiYWJiciIsICJhcnRpY2xlIiwgImFzaWRlIiwgImF1ZGlvIiwgImJkaSIsICJjYW52YXMiLCAiY29tbWFuZCIsICJkYXRhbGlzdCIsICJkZXRhaWxzIiwgImZpZ2NhcHRpb24iLAogICAgICAgICJmaWd1cmUiLCAiZm9vdGVyIiwgImhlYWRlciIsICJoZ3JvdXAiLCAia2V5Z2VuIiwgIm1hcmsiLCAibWV0ZXIiLCAibmF2IiwgIm91dHB1dCIsICJwcm9ncmVzcyIsCiAgICAgICAgInJwIiwgInJ0IiwgInJ1YnkiLCAic3ZnIiwgInNlY3Rpb24iLCAic291cmNlIiwgInN1bW1hcnkiLCAidGltZSIsICJ0cmFjayIsICJ2aWRlbyIsICJ3YnIiCiAgICBdOwoKICAgIHJldHVybiBmdW5jdGlvbiAoaHRtbCwgY29udGV4dCkgewogICAgICAgIGNvbnRleHQgPSBjb250ZXh0IHx8IGRvY3VtZW50OwogICAgICAgIHZhciB0ZW1wRWxlbWVudDsKICAgICAgICBpZiAodHlwZW9mKGh0bWwpID09PSAib2JqZWN0IiAmJiBodG1sLm5vZGVUeXBlKSB7CiAgICAgICAgICAgIHRlbXBFbGVtZW50ID0gY29udGV4dC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKICAgICAgICAgICAgdGVtcEVsZW1lbnQuYXBwZW5kQ2hpbGQoaHRtbCk7CiAgICAgICAgfSBlbHNlIGlmICh3eXNpaHRtbDUuYnJvd3Nlci5zdXBwb3J0c0hUTUw1VGFncyhjb250ZXh0KSkgewogICAgICAgICAgICB0ZW1wRWxlbWVudCA9IGNvbnRleHQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CiAgICAgICAgICAgIHRlbXBFbGVtZW50LmlubmVySFRNTCA9IGh0bWw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX2Vuc3VyZUhUTUw1Q29tcGF0aWJpbGl0eShjb250ZXh0KTsKICAgICAgICAgICAgdGVtcEVsZW1lbnQgPSBfaW5uZXJIVE1MU2hpdihodG1sLCBjb250ZXh0KTsKICAgICAgICB9CiAgICAgICAgdGVtcEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgid3lzaWh0bWw1LWVkaXRvciIpOwogICAgICAgIHJldHVybiB0ZW1wRWxlbWVudDsKICAgIH07Cn0pKCk7Ci8qKgogKiBXYWxrcyB0aGUgZG9tIHRyZWUgZnJvbSB0aGUgZ2l2ZW4gbm9kZSB1cCB1bnRpbCBpdCBmaW5kcyBhIG1hdGNoCiAqIERlc2lnbmVkIGZvciBvcHRpbWFsIHBlcmZvcm1hbmNlLgogKgogKiBAcGFyYW0ge0VsZW1lbnR9IG5vZGUgVGhlIGZyb20gd2hpY2ggdG8gY2hlY2sgdGhlIHBhcmVudCBub2RlcwogKiBAcGFyYW0ge09iamVjdH0gbWF0Y2hpbmdTZXQgT2JqZWN0IHRvIG1hdGNoIGFnYWluc3QgKHBvc3NpYmxlIHByb3BlcnRpZXM6IG5vZGVOYW1lLCBjbGFzc05hbWUsIGNsYXNzUmVnRXhwKQogKiBAcGFyYW0ge051bWJlcn0gW2xldmVsc10gSG93IG1hbnkgcGFyZW50cyBzaG91bGQgdGhlIGZ1bmN0aW9uIGNoZWNrIHVwIGZyb20gdGhlIGN1cnJlbnQgbm9kZSAoZGVmYXVsdHMgdG8gNTApCiAqIEByZXR1cm4ge251bGx8RWxlbWVudH0gUmV0dXJucyB0aGUgZmlyc3QgZWxlbWVudCB0aGF0IG1hdGNoZWQgdGhlIGRlc2lyZWROb2RlTmFtZShzKQogKiBAZXhhbXBsZQogKiAgICB2YXIgbGlzdEVsZW1lbnQgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQoZG9jdW1lbnQucXVlcnlTZWxlY3RvcigibGkiKSwgeyBub2RlTmFtZTogWyJNRU5VIiwgIlVMIiwgIk9MIl0gfSk7CiAqICAgIC8vIC4uLiBvciAuLi4KICogICAgdmFyIHVub3JkZXJlZExpc3RFbGVtZW50ID0gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImxpIiksIHsgbm9kZU5hbWU6ICJVTCIgfSk7CiAqICAgIC8vIC4uLiBvciAuLi4KICogICAgdmFyIGNvbG9yZWRFbGVtZW50ID0gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KG15VGV4dE5vZGUsIHsgbm9kZU5hbWU6ICJTUEFOIiwgY2xhc3NOYW1lOiAid3lzaXd5Zy1jb2xvci1yZWQiLCBjbGFzc1JlZ0V4cDogL3d5c2l3eWctY29sb3ItW2Etel0vZyB9KTsKICovCnd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudCA9IChmdW5jdGlvbiAoKSB7CgogICAgZnVuY3Rpb24gX2lzU2FtZU5vZGVOYW1lKG5vZGVOYW1lLCBkZXNpcmVkTm9kZU5hbWVzKSB7CiAgICAgICAgaWYgKCFkZXNpcmVkTm9kZU5hbWVzIHx8ICFkZXNpcmVkTm9kZU5hbWVzLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmICh0eXBlb2YoZGVzaXJlZE5vZGVOYW1lcykgPT09ICJzdHJpbmciKSB7CiAgICAgICAgICAgIHJldHVybiBub2RlTmFtZSA9PT0gZGVzaXJlZE5vZGVOYW1lczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmxhbmcuYXJyYXkoZGVzaXJlZE5vZGVOYW1lcykuY29udGFpbnMobm9kZU5hbWUpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfaXNFbGVtZW50KG5vZGUpIHsKICAgICAgICByZXR1cm4gbm9kZS5ub2RlVHlwZSA9PT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERTsKICAgIH0KCiAgICBmdW5jdGlvbiBfaGFzQ2xhc3NOYW1lKGVsZW1lbnQsIGNsYXNzTmFtZSwgY2xhc3NSZWdFeHApIHsKICAgICAgICB2YXIgY2xhc3NOYW1lcyA9IChlbGVtZW50LmNsYXNzTmFtZSB8fCAiIikubWF0Y2goY2xhc3NSZWdFeHApIHx8IFtdOwogICAgICAgIGlmICghY2xhc3NOYW1lKSB7CiAgICAgICAgICAgIHJldHVybiAhIWNsYXNzTmFtZXMubGVuZ3RoOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY2xhc3NOYW1lc1tjbGFzc05hbWVzLmxlbmd0aCAtIDFdID09PSBjbGFzc05hbWU7CiAgICB9CgogICAgZnVuY3Rpb24gX2hhc0F0dHJpYnV0ZXMoZWwsIGF0dHJpYnV0ZXMpIHsKICAgICAgICBpZiAoZWwubm9kZVR5cGUgPT0gd3lzaWh0bWw1LlRFWFRfTk9ERSB8fCBlbC5ub2RlVHlwZSA9PSA5KSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgdmFyIHN0ID0gZWwuZ2V0QXR0cmlidXRlKCJzdHlsZSIpOwogICAgICAgIGlmICghc3QpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmb3IgKHZhciBhdHRyaWJ1dGUgaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICBpZiAoZWwuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShhdHRyaWJ1dGUpKSB7CiAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlc1thdHRyaWJ1dGVdICE9IG51bGwgJiYgYXR0cmlidXRlc1thdHRyaWJ1dGVdID09IGVsLnN0eWxlLmdldFByb3BlcnR5VmFsdWUoYXR0cmlidXRlKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhdHRyaWJ1dGVzW2F0dHJpYnV0ZV0gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBmdW5jdGlvbiBfZ2V0UGFyZW50RWxlbWVudFdpdGhOb2RlTmFtZShub2RlLCBub2RlTmFtZSwgbGV2ZWxzKSB7CiAgICAgICAgd2hpbGUgKGxldmVscy0tICYmIG5vZGUpIHsKICAgICAgICAgICAgaWYgKF9pc1NhbWVOb2RlTmFtZShub2RlLm5vZGVOYW1lLCBub2RlTmFtZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKG5vZGUucGFyZW50Tm9kZSkpIHsKICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBmdW5jdGlvbiBfZ2V0UGFyZW50RWxlbWVudFdpdGhOb2RlTmFtZUFuZENsYXNzTmFtZShub2RlLCBub2RlTmFtZSwgY2xhc3NOYW1lLCBjbGFzc1JlZ0V4cCwgbGV2ZWxzKSB7CiAgICAgICAgd2hpbGUgKGxldmVscy0tICYmIG5vZGUpIHsKICAgICAgICAgICAgaWYgKF9pc0VsZW1lbnQobm9kZSkgJiYgX2lzU2FtZU5vZGVOYW1lKG5vZGUubm9kZU5hbWUsIG5vZGVOYW1lKSAmJiBfaGFzQ2xhc3NOYW1lKG5vZGUsIGNsYXNzTmFtZSwgY2xhc3NSZWdFeHApKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIXd5c2lodG1sNS51dGlsLmlzRWRpdG9yTm9kZShub2RlLnBhcmVudE5vZGUpKSB7CiAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgZnVuY3Rpb24gX2dldFBhcmVudEVsZW1lbnRXaXRoTm9kZU5hbWVBbmRBdHRyaWJ1dGUobm9kZSwgbm9kZU5hbWUsIGF0dHJpYnV0ZXMsIGxldmVscykgewogICAgICAgIHdoaWxlIChsZXZlbHMtLSAmJiBub2RlKSB7CiAgICAgICAgICAgIGlmIChfaXNFbGVtZW50KG5vZGUpICYmIF9pc1NhbWVOb2RlTmFtZShub2RlLm5vZGVOYW1lLCBub2RlTmFtZSkgJiYgX2hhc0F0dHJpYnV0ZXMobm9kZSwgYXR0cmlidXRlcykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKG5vZGUucGFyZW50Tm9kZSkpIHsKICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICByZXR1cm4gZnVuY3Rpb24gKG5vZGUsIG1hdGNoaW5nU2V0LCBsZXZlbHMpIHsKICAgICAgICBsZXZlbHMgPSBsZXZlbHMgfHwgNTA7IC8vIEdvIG1heCA1MCBub2RlcyB1cHdhcmRzIGZyb20gY3VycmVudCBub2RlCiAgICAgICAgaWYgKG1hdGNoaW5nU2V0LmF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgcmV0dXJuIF9nZXRQYXJlbnRFbGVtZW50V2l0aE5vZGVOYW1lQW5kQXR0cmlidXRlKAogICAgICAgICAgICAgICAgbm9kZSwgbWF0Y2hpbmdTZXQubm9kZU5hbWUsIG1hdGNoaW5nU2V0LmF0dHJpYnV0ZXMsIGxldmVscwogICAgICAgICAgICApOwogICAgICAgIH0gZWxzZSBpZiAobWF0Y2hpbmdTZXQuY2xhc3NOYW1lIHx8IG1hdGNoaW5nU2V0LmNsYXNzUmVnRXhwKSB7CiAgICAgICAgICAgIHJldHVybiBfZ2V0UGFyZW50RWxlbWVudFdpdGhOb2RlTmFtZUFuZENsYXNzTmFtZSgKICAgICAgICAgICAgICAgIG5vZGUsIG1hdGNoaW5nU2V0Lm5vZGVOYW1lLCBtYXRjaGluZ1NldC5jbGFzc05hbWUsIG1hdGNoaW5nU2V0LmNsYXNzUmVnRXhwLCBsZXZlbHMKICAgICAgICAgICAgKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gX2dldFBhcmVudEVsZW1lbnRXaXRoTm9kZU5hbWUoCiAgICAgICAgICAgICAgICBub2RlLCBtYXRjaGluZ1NldC5ub2RlTmFtZSwgbGV2ZWxzCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfTsKfSkoKTsKLyoqCiAqIEdldCBlbGVtZW50J3Mgc3R5bGUgZm9yIGEgc3BlY2lmaWMgY3NzIHByb3BlcnR5CiAqCiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCBvbiB3aGljaCB0byByZXRyaWV2ZSB0aGUgc3R5bGUKICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IFRoZSBDU1MgcHJvcGVydHkgdG8gcmV0cmlldmUgKCJmbG9hdCIsICJkaXNwbGF5IiwgInRleHQtYWxpZ24iLCAuLi4pCiAqCiAqIEBleGFtcGxlCiAqICAgIHd5c2lodG1sNS5kb20uZ2V0U3R5bGUoImRpc3BsYXkiKS5mcm9tKGRvY3VtZW50LmJvZHkpOwogKiAgICAvLyA9PiAiYmxvY2siCiAqLwp3eXNpaHRtbDUuZG9tLmdldFN0eWxlID0gKGZ1bmN0aW9uICgpIHsKICAgIHZhciBzdHlsZVByb3BlcnR5TWFwcGluZyA9IHsKICAgICAgICAgICAgImZsb2F0IiA6ICgic3R5bGVGbG9hdCIgaW4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iikuc3R5bGUpID8gInN0eWxlRmxvYXQiIDogImNzc0Zsb2F0IgogICAgICAgIH0sCiAgICAgICAgUkVHX0VYUF9DQU1FTElaRSA9IC9cLVthLXpdL2c7CgogICAgZnVuY3Rpb24gY2FtZWxpemUoc3RyKSB7CiAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKFJFR19FWFBfQ0FNRUxJWkUsIGZ1bmN0aW9uIChtYXRjaCkgewogICAgICAgICAgICByZXR1cm4gbWF0Y2guY2hhckF0KDEpLnRvVXBwZXJDYXNlKCk7CiAgICAgICAgfSk7CiAgICB9CgogICAgcmV0dXJuIGZ1bmN0aW9uIChwcm9wZXJ0eSkgewogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIGZyb20gOiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQubm9kZVR5cGUgIT09IHd5c2lodG1sNS5FTEVNRU5UX05PREUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyIGRvYyA9IGVsZW1lbnQub3duZXJEb2N1bWVudCwKICAgICAgICAgICAgICAgICAgICBjYW1lbGl6ZWRQcm9wZXJ0eSA9IHN0eWxlUHJvcGVydHlNYXBwaW5nW3Byb3BlcnR5XSB8fCBjYW1lbGl6ZShwcm9wZXJ0eSksCiAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBlbGVtZW50LnN0eWxlLAogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTdHlsZSA9IGVsZW1lbnQuY3VycmVudFN0eWxlLAogICAgICAgICAgICAgICAgICAgIHN0eWxlVmFsdWUgPSBzdHlsZVtjYW1lbGl6ZWRQcm9wZXJ0eV07CiAgICAgICAgICAgICAgICBpZiAoc3R5bGVWYWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHlsZVZhbHVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGN1cnJlbnRTdHlsZSBpcyBubyBzdGFuZGFyZCBhbmQgb25seSBzdXBwb3J0ZWQgYnkgT3BlcmEgYW5kIElFIGJ1dCBpdCBoYXMgb25lIGltcG9ydGFudCBhZHZhbnRhZ2Ugb3ZlciB0aGUgc3RhbmRhcmQtY29tcGxpYW50CiAgICAgICAgICAgICAgICAvLyB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSwgc2luY2UgaXQgcmV0dXJucyBjc3MgcHJvcGVydHkgdmFsdWVzIGluIHRoZWlyIG9yaWdpbmFsIHVuaXQ6CiAgICAgICAgICAgICAgICAvLyBJZiB5b3Ugc2V0IGFuIGVsZW1lbnRzIHdpZHRoIHRvICI1MCUiLCB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSB3aWxsIGdpdmUgeW91IGl0J3MgY3VycmVudCB3aWR0aCBpbiBweCB3aGlsZSBjdXJyZW50U3R5bGUKICAgICAgICAgICAgICAgIC8vIGdpdmVzIHlvdSB0aGUgb3JpZ2luYWwgIjUwJSIuCiAgICAgICAgICAgICAgICAvLyBPcGVyYSBzdXBwb3J0cyBib3RoLCBjdXJyZW50U3R5bGUgYW5kIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlLCB0aGF0J3Mgd2h5IGNoZWNraW5nIGZvciBjdXJyZW50U3R5bGUgc2hvdWxkIGhhdmUgaGlnaGVyIHByaW8KICAgICAgICAgICAgICAgIGlmIChjdXJyZW50U3R5bGUpIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudFN0eWxlW2NhbWVsaXplZFByb3BlcnR5XTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWUgd2lsbCBvY2Nhc2lvbmFsbHkgZmFpbCBmb3IgdW5rbm93biByZWFzb25zLiBzd2FsbG93aW5nIGV4Y2VwdGlvbgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgd2luID0gZG9jLmRlZmF1bHRWaWV3IHx8IGRvYy5wYXJlbnRXaW5kb3csCiAgICAgICAgICAgICAgICAgICAgbmVlZHNPdmVyZmxvd1Jlc2V0ID0gKHByb3BlcnR5ID09PSAiaGVpZ2h0IiB8fCBwcm9wZXJ0eSA9PT0gIndpZHRoIikgJiYgZWxlbWVudC5ub2RlTmFtZSA9PT0gIlRFWFRBUkVBIiwKICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbE92ZXJmbG93LAogICAgICAgICAgICAgICAgICAgIHJldHVyblZhbHVlOwoKICAgICAgICAgICAgICAgIGlmICh3aW4uZ2V0Q29tcHV0ZWRTdHlsZSkgewogICAgICAgICAgICAgICAgICAgIC8vIENocm9tZSBhbmQgU2FmYXJpIGJvdGggY2FsY3VsYXRlIGEgd3Jvbmcgd2lkdGggYW5kIGhlaWdodCBmb3IgdGV4dGFyZWFzIHdoZW4gdGhleSBoYXZlIHNjcm9sbCBiYXJzCiAgICAgICAgICAgICAgICAgICAgLy8gdGhlcmZvcmUgd2UgcmVtb3ZlIGFuZCByZXN0b3JlIHRoZSBzY3JvbGxiYXIgYW5kIGNhbGN1bGF0ZSB0aGUgdmFsdWUgaW4gYmV0d2VlbgogICAgICAgICAgICAgICAgICAgIGlmIChuZWVkc092ZXJmbG93UmVzZXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxPdmVyZmxvdyA9IHN0eWxlLm92ZXJmbG93OwogICAgICAgICAgICAgICAgICAgICAgICBzdHlsZS5vdmVyZmxvdyA9ICJoaWRkZW4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHdpbi5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQsIG51bGwpLmdldFByb3BlcnR5VmFsdWUocHJvcGVydHkpOwogICAgICAgICAgICAgICAgICAgIGlmIChuZWVkc092ZXJmbG93UmVzZXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUub3ZlcmZsb3cgPSBvcmlnaW5hbE92ZXJmbG93IHx8ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0dXJuVmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfTsKfSkoKTsKLyoqCiAqIEhpZ2ggcGVyZm9ybWFudCB3YXkgdG8gY2hlY2sgd2hldGhlciBhbiBlbGVtZW50IHdpdGggYSBzcGVjaWZpYyB0YWcgbmFtZSBpcyBpbiB0aGUgZ2l2ZW4gZG9jdW1lbnQKICogT3B0aW1pemVkIGZvciBiZWluZyBoZWF2aWx5IGV4ZWN1dGVkCiAqIFVubGVhc2hlcyB0aGUgcG93ZXIgb2YgbGl2ZSBub2RlIGxpc3RzCiAqCiAqIEBwYXJhbSB7T2JqZWN0fSBkb2MgVGhlIGRvY3VtZW50IG9iamVjdCBvZiB0aGUgY29udGV4dCB3aGVyZSB0byBjaGVjawogKiBAcGFyYW0ge1N0cmluZ30gdGFnTmFtZSBVcHBlciBjYXNlZCB0YWcgbmFtZQogKiBAZXhhbXBsZQogKiAgICB3eXNpaHRtbDUuZG9tLmhhc0VsZW1lbnRXaXRoVGFnTmFtZShkb2N1bWVudCwgIklNRyIpOwogKi8Kd3lzaWh0bWw1LmRvbS5oYXNFbGVtZW50V2l0aFRhZ05hbWUgPSAoZnVuY3Rpb24gKCkgewogICAgdmFyIExJVkVfQ0FDSEUgPSB7fSwKICAgICAgICBET0NVTUVOVF9JREVOVElGSUVSID0gMTsKCiAgICBmdW5jdGlvbiBfZ2V0RG9jdW1lbnRJZGVudGlmaWVyKGRvYykgewogICAgICAgIHJldHVybiBkb2MuX3d5c2lodG1sNV9pZGVudGlmaWVyIHx8IChkb2MuX3d5c2lodG1sNV9pZGVudGlmaWVyID0gRE9DVU1FTlRfSURFTlRJRklFUisrKTsKICAgIH0KCiAgICByZXR1cm4gZnVuY3Rpb24gKGRvYywgdGFnTmFtZSkgewogICAgICAgIHZhciBrZXkgPSBfZ2V0RG9jdW1lbnRJZGVudGlmaWVyKGRvYykgKyAiOiIgKyB0YWdOYW1lLAogICAgICAgICAgICBjYWNoZUVudHJ5ID0gTElWRV9DQUNIRVtrZXldOwogICAgICAgIGlmICghY2FjaGVFbnRyeSkgewogICAgICAgICAgICBjYWNoZUVudHJ5ID0gTElWRV9DQUNIRVtrZXldID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKHRhZ05hbWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGNhY2hlRW50cnkubGVuZ3RoID4gMDsKICAgIH07Cn0pKCk7Ci8qKgogKiBIaWdoIHBlcmZvcm1hbnQgd2F5IHRvIGNoZWNrIHdoZXRoZXIgYW4gZWxlbWVudCB3aXRoIGEgc3BlY2lmaWMgY2xhc3MgbmFtZSBpcyBpbiB0aGUgZ2l2ZW4gZG9jdW1lbnQKICogT3B0aW1pemVkIGZvciBiZWluZyBoZWF2aWx5IGV4ZWN1dGVkCiAqIFVubGVhc2hlcyB0aGUgcG93ZXIgb2YgbGl2ZSBub2RlIGxpc3RzCiAqCiAqIEBwYXJhbSB7T2JqZWN0fSBkb2MgVGhlIGRvY3VtZW50IG9iamVjdCBvZiB0aGUgY29udGV4dCB3aGVyZSB0byBjaGVjawogKiBAcGFyYW0ge1N0cmluZ30gdGFnTmFtZSBVcHBlciBjYXNlZCB0YWcgbmFtZQogKiBAZXhhbXBsZQogKiAgICB3eXNpaHRtbDUuZG9tLmhhc0VsZW1lbnRXaXRoQ2xhc3NOYW1lKGRvY3VtZW50LCAiZm9vYmFyIik7CiAqLwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgdmFyIExJVkVfQ0FDSEUgPSB7fSwKICAgICAgICBET0NVTUVOVF9JREVOVElGSUVSID0gMTsKCiAgICBmdW5jdGlvbiBfZ2V0RG9jdW1lbnRJZGVudGlmaWVyKGRvYykgewogICAgICAgIHJldHVybiBkb2MuX3d5c2lodG1sNV9pZGVudGlmaWVyIHx8IChkb2MuX3d5c2lodG1sNV9pZGVudGlmaWVyID0gRE9DVU1FTlRfSURFTlRJRklFUisrKTsKICAgIH0KCiAgICB3eXNpaHRtbDUuZG9tLmhhc0VsZW1lbnRXaXRoQ2xhc3NOYW1lID0gZnVuY3Rpb24gKGRvYywgY2xhc3NOYW1lKSB7CiAgICAgICAgLy8gZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSBpcyBub3Qgc3VwcG9ydGVkIGJ5IElFPDkKICAgICAgICAvLyBidXQgaXMgc29tZXRpbWVzIG1vY2tlZCB2aWEgbGlicmFyeSBjb2RlICh3aGljaCB0aGVuIGRvZXNuJ3QgcmV0dXJuIGxpdmUgbm9kZSBsaXN0cykKICAgICAgICBpZiAoIXd5c2lodG1sNS5icm93c2VyLnN1cHBvcnRzTmF0aXZlR2V0RWxlbWVudHNCeUNsYXNzTmFtZSgpKSB7CiAgICAgICAgICAgIHJldHVybiAhIWRvYy5xdWVyeVNlbGVjdG9yKCIuIiArIGNsYXNzTmFtZSk7CiAgICAgICAgfQoKICAgICAgICB2YXIga2V5ID0gX2dldERvY3VtZW50SWRlbnRpZmllcihkb2MpICsgIjoiICsgY2xhc3NOYW1lLAogICAgICAgICAgICBjYWNoZUVudHJ5ID0gTElWRV9DQUNIRVtrZXldOwogICAgICAgIGlmICghY2FjaGVFbnRyeSkgewogICAgICAgICAgICBjYWNoZUVudHJ5ID0gTElWRV9DQUNIRVtrZXldID0gZG9jLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoY2xhc3NOYW1lKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBjYWNoZUVudHJ5Lmxlbmd0aCA+IDA7CiAgICB9Owp9KSh3eXNpaHRtbDUpOwp3eXNpaHRtbDUuZG9tLmluc2VydCA9IGZ1bmN0aW9uIChlbGVtZW50VG9JbnNlcnQpIHsKICAgIHJldHVybiB7CiAgICAgICAgYWZ0ZXIgOiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICBlbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVsZW1lbnRUb0luc2VydCwgZWxlbWVudC5uZXh0U2libGluZyA/IGVsZW1lbnQubmV4dFNpYmxpbmcgOiBudWxsKTsKICAgICAgICB9LAoKICAgICAgICBiZWZvcmUgOiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICBlbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVsZW1lbnRUb0luc2VydCwgZWxlbWVudCk7CiAgICAgICAgfSwKCiAgICAgICAgaW50byA6IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoZWxlbWVudFRvSW5zZXJ0KTsKICAgICAgICB9CiAgICB9Owp9Owp3eXNpaHRtbDUuZG9tLmluc2VydENTUyA9IGZ1bmN0aW9uIChydWxlcykgewogICAgcnVsZXMgPSBydWxlcy5qb2luKCJcbiIpOwoKICAgIHJldHVybiB7CiAgICAgICAgaW50byA6IGZ1bmN0aW9uIChkb2MpIHsKICAgICAgICAgICAgdmFyIHN0eWxlRWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJzdHlsZSIpOwogICAgICAgICAgICBzdHlsZUVsZW1lbnQudHlwZSA9ICJ0ZXh0L2NzcyI7CgogICAgICAgICAgICBpZiAoc3R5bGVFbGVtZW50LnN0eWxlU2hlZXQpIHsKICAgICAgICAgICAgICAgIHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0LmNzc1RleHQgPSBydWxlczsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHN0eWxlRWxlbWVudC5hcHBlbmRDaGlsZChkb2MuY3JlYXRlVGV4dE5vZGUocnVsZXMpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGxpbmsgPSBkb2MucXVlcnlTZWxlY3RvcigiaGVhZCBsaW5rIik7CiAgICAgICAgICAgIGlmIChsaW5rKSB7CiAgICAgICAgICAgICAgICBsaW5rLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHN0eWxlRWxlbWVudCwgbGluayk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgaGVhZCA9IGRvYy5xdWVyeVNlbGVjdG9yKCJoZWFkIik7CiAgICAgICAgICAgICAgICBpZiAoaGVhZCkgewogICAgICAgICAgICAgICAgICAgIGhlYWQuYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07Cn07Ci8qKgogKiBNZXRob2QgdG8gc2V0IGRvbSBldmVudHMKICoKICogQGV4YW1wbGUKICogICAgd3lzaWh0bWw1LmRvbS5vYnNlcnZlKGlmcmFtZS5jb250ZW50V2luZG93LmRvY3VtZW50LmJvZHksIFsiZm9jdXMiLCAiYmx1ciJdLCBmdW5jdGlvbigpIHsgLi4uIH0pOwogKi8Kd3lzaWh0bWw1LmRvbS5vYnNlcnZlID0gZnVuY3Rpb24gKGVsZW1lbnQsIGV2ZW50TmFtZXMsIGhhbmRsZXIpIHsKICAgIGV2ZW50TmFtZXMgPSB0eXBlb2YoZXZlbnROYW1lcykgPT09ICJzdHJpbmciID8gW2V2ZW50TmFtZXNdIDogZXZlbnROYW1lczsKCiAgICB2YXIgaGFuZGxlcldyYXBwZXIsCiAgICAgICAgZXZlbnROYW1lLAogICAgICAgIGkgPSAwLAogICAgICAgIGxlbmd0aCA9IGV2ZW50TmFtZXMubGVuZ3RoOwoKICAgIGZvciAoOwogICAgICAgIGkgPCBsZW5ndGg7CiAgICAgICAgaSsrKSB7CiAgICAgICAgZXZlbnROYW1lID0gZXZlbnROYW1lc1tpXTsKICAgICAgICBpZiAoZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKSB7CiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGhhbmRsZXIsIGZhbHNlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBoYW5kbGVyV3JhcHBlciA9IGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgaWYgKCEoInRhcmdldCIgaW4gZXZlbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgZXZlbnQudGFyZ2V0ID0gZXZlbnQuc3JjRWxlbWVudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0ID0gZXZlbnQucHJldmVudERlZmF1bHQgfHwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJldHVyblZhbHVlID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbiA9IGV2ZW50LnN0b3BQcm9wYWdhdGlvbiB8fCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2FuY2VsQnViYmxlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgaGFuZGxlci5jYWxsKGVsZW1lbnQsIGV2ZW50KTsKICAgICAgICAgICAgfTsKICAgICAgICAgICAgZWxlbWVudC5hdHRhY2hFdmVudCgib24iICsgZXZlbnROYW1lLCBoYW5kbGVyV3JhcHBlcik7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiB7CiAgICAgICAgc3RvcCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGV2ZW50TmFtZSwKICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgbGVuZ3RoID0gZXZlbnROYW1lcy5sZW5ndGg7CiAgICAgICAgICAgIGZvciAoOwogICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgZXZlbnROYW1lID0gZXZlbnROYW1lc1tpXTsKICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIpIHsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBoYW5kbGVyLCBmYWxzZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuZGV0YWNoRXZlbnQoIm9uIiArIGV2ZW50TmFtZSwgaGFuZGxlcldyYXBwZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKfTsKLyoqCiAqIEhUTUwgU2FuaXRpemVyCiAqIFJld3JpdGVzIHRoZSBIVE1MIGJhc2VkIG9uIGdpdmVuIHJ1bGVzCiAqCiAqIEBwYXJhbSB7RWxlbWVudHxTdHJpbmd9IGVsZW1lbnRPckh0bWwgSFRNTCBTdHJpbmcgdG8gYmUgc2FuaXRpemVkIE9SIGVsZW1lbnQgd2hvc2UgY29udGVudCBzaG91bGQgYmUgc2FuaXRpemVkCiAqIEBwYXJhbSB7T2JqZWN0fSBbcnVsZXNdIExpc3Qgb2YgcnVsZXMgZm9yIHJld3JpdGluZyB0aGUgSFRNTCwgaWYgdGhlcmUncyBubyBydWxlIGZvciBhbiBlbGVtZW50IGl0IHdpbGwKICogICAgYmUgY29udmVydGVkIHRvIGEgInNwYW4iLiBFYWNoIHJ1bGUgaXMgYSBrZXkvdmFsdWUgcGFpciB3aGVyZSBrZXkgaXMgdGhlIHRhZyB0byBjb252ZXJ0LCBhbmQgdmFsdWUgdGhlCiAqICAgIGRlc2lyZWQgc3Vic3RpdHV0aW9uLgogKiBAcGFyYW0ge09iamVjdH0gY29udGV4dCBEb2N1bWVudCBvYmplY3QgaW4gd2hpY2ggdG8gcGFyc2UgdGhlIGh0bWwsIG5lZWRlZCB0byBzYW5kYm94IHRoZSBwYXJzaW5nCiAqCiAqIEByZXR1cm4ge0VsZW1lbnR8U3RyaW5nfSBEZXBlbmRzIG9uIHRoZSBlbGVtZW50T3JIdG1sIHBhcmFtZXRlci4gV2hlbiBodG1sIHRoZW4gdGhlIHNhbml0aXplZCBodG1sIGFzIHN0cmluZyBlbHNld2lzZSB0aGUgZWxlbWVudC4KICoKICogQGV4YW1wbGUKICogICAgdmFyIHVzZXJIVE1MID0gJzxkaXYgaWQ9ImZvbyIgb25jbGljaz0iYWxlcnQoMSk7Ij48cD48Zm9udCBjb2xvcj0icmVkIj5mb288L2ZvbnQ+PHNjcmlwdD5hbGVydCgxKTs8L3NjcmlwdD48L3A+PC9kaXY+JzsKICogICAgd3lzaWh0bWw1LmRvbS5wYXJzZSh1c2VySFRNTCwgewogKiAgICAgIHRhZ3MgewogKiAgICAgICAgcDogICAgICAiZGl2IiwgICAgICAvLyBSZW5hbWUgcCB0YWdzIHRvIGRpdiB0YWdzCiAqICAgICAgICBmb250OiAgICJzcGFuIiAgICAgIC8vIFJlbmFtZSBmb250IHRhZ3MgdG8gc3BhbiB0YWdzCiAqICAgICAgICBkaXY6ICAgIHRydWUsICAgICAgIC8vIEtlZXAgdGhlbSwgYWxzbyBwb3NzaWJsZSAoc2FtZSByZXN1bHQgd2hlbiBwYXNzaW5nOiAiZGl2IiBvciB0cnVlKQogKiAgICAgICAgc2NyaXB0OiB1bmRlZmluZWQgICAvLyBSZW1vdmUgc2NyaXB0IGVsZW1lbnRzCiAqICAgICAgfQogKiAgICB9KTsKICogICAgLy8gPT4gPGRpdj48ZGl2PjxzcGFuPmZvbyBiYXI8L3NwYW4+PC9kaXY+PC9kaXY+CiAqCiAqICAgIHZhciB1c2VySFRNTCA9ICc8dGFibGU+PHRib2R5Pjx0cj48dGQ+SSdtIGEgdGFibGUhPC90ZD48L3RyPjwvdGJvZHk+PC90YWJsZT4nOwogKiAgICB3eXNpaHRtbDUuZG9tLnBhcnNlKHVzZXJIVE1MKTsKICogICAgLy8gPT4gJzxzcGFuPjxzcGFuPjxzcGFuPjxzcGFuPkknbSBhIHRhYmxlITwvc3Bhbj48L3NwYW4+PC9zcGFuPjwvc3Bhbj4nCiAqCiAqICAgIHZhciB1c2VySFRNTCA9ICc8ZGl2PmZvb2Jhcjxicj5mb29iYXI8L2Rpdj4nOwogKiAgICB3eXNpaHRtbDUuZG9tLnBhcnNlKHVzZXJIVE1MLCB7CiAqICAgICAgdGFnczogewogKiAgICAgICAgZGl2OiB1bmRlZmluZWQsCiAqICAgICAgICBicjogIHRydWUKICogICAgICB9CiAqICAgIH0pOwogKiAgICAvLyA9PiAnJwogKgogKiAgICB2YXIgdXNlckhUTUwgPSAnPGRpdiBjbGFzcz0icmVkIj5mb288L2Rpdj48ZGl2IGNsYXNzPSJwaW5rIj5iYXI8L2Rpdj4nOwogKiAgICB3eXNpaHRtbDUuZG9tLnBhcnNlKHVzZXJIVE1MLCB7CiAqICAgICAgY2xhc3NlczogewogKiAgICAgICAgcmVkOiAgICAxLAogKiAgICAgICAgZ3JlZW46ICAxCiAqICAgICAgfSwKICogICAgICB0YWdzOiB7CiAqICAgICAgICBkaXY6IHsKICogICAgICAgICAgcmVuYW1lX3RhZzogICAgICJwIgogKiAgICAgICAgfQogKiAgICAgIH0KICogICAgfSk7CiAqICAgIC8vID0+ICc8cCBjbGFzcz0icmVkIj5mb288L3A+PHA+YmFyPC9wPicKICovCnd5c2lodG1sNS5kb20ucGFyc2UgPSAoZnVuY3Rpb24gKCkgewoKICAgIC8qKgogICAgICogSXQncyBub3QgcG9zc2libGUgdG8gdXNlIGEgWE1MUGFyc2VyL0RPTVBhcnNlciBhcyBIVE1MNSBpcyBub3QgYWx3YXlzIHdlbGwtZm9ybWVkIFhNTAogICAgICogbmV3IERPTVBhcnNlcigpLnBhcnNlRnJvbVN0cmluZygnPGltZyBzcmM9ImZvby5naWYiPicpIHdpbGwgY2F1c2UgYSBwYXJzZUVycm9yIHNpbmNlIHRoZQogICAgICogbm9kZSBpc24ndCBjbG9zZWQKICAgICAqCiAgICAgKiBUaGVyZWZvcmUgd2UndmUgdG8gdXNlIHRoZSBicm93c2VyJ3Mgb3JkaW5hcnkgSFRNTCBwYXJzZXIgaW52b2tlZCBieSBzZXR0aW5nIGlubmVySFRNTC4KICAgICAqLwogICAgdmFyIE5PREVfVFlQRV9NQVBQSU5HID0gewogICAgICAgICAgICAiMSIgOiBfaGFuZGxlRWxlbWVudCwKICAgICAgICAgICAgIjMiIDogX2hhbmRsZVRleHQKICAgICAgICB9LAogICAgICAgIC8vIFJlbmFtZSB1bmtub3duIHRhZ3MgdG8gdGhpcwogICAgICAgIERFRkFVTFRfTk9ERV9OQU1FID0gInNwYW4iLAogICAgICAgIFdISVRFX1NQQUNFX1JFR19FWFAgPSAvXHMrLywKICAgICAgICBkZWZhdWx0UnVsZXMgPSB7dGFncyA6IHt9LCBjbGFzc2VzIDoge319LAogICAgICAgIGN1cnJlbnRSdWxlcyA9IHt9LAogICAgICAgIHByZVByb2Nlc3NpbmdDb250ZW50ID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBJdGVyYXRlcyBvdmVyIGFsbCBjaGlsZHMgb2YgdGhlIGVsZW1lbnQsIHJlY3JlYXRlcyB0aGVtLCBhcHBlbmRzIHRoZW0gaW50byBhIGRvY3VtZW50IGZyYWdtZW50CiAgICAgKiB3aGljaCBsYXRlciByZXBsYWNlcyB0aGUgZW50aXJlIGJvZHkgY29udGVudAogICAgICovCiAgICBmdW5jdGlvbiBwYXJzZShlbGVtZW50T3JIdG1sLCBydWxlcywgY29udGV4dCwgY2xlYW5VcCwgcHJlUHJvY2VzcykgewogICAgICAgIHd5c2lodG1sNS5sYW5nLm9iamVjdChjdXJyZW50UnVsZXMpLm1lcmdlKGRlZmF1bHRSdWxlcykubWVyZ2UocnVsZXMpLmdldCgpOwoKICAgICAgICBjb250ZXh0ID0gY29udGV4dCB8fCBlbGVtZW50T3JIdG1sLm93bmVyRG9jdW1lbnQgfHwgZG9jdW1lbnQ7CiAgICAgICAgcHJlUHJvY2Vzc2luZ0NvbnRlbnQgPSAhIXByZVByb2Nlc3M7CiAgICAgICAgdmFyIGZyYWdtZW50ID0gY29udGV4dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksCiAgICAgICAgICAgIGlzU3RyaW5nID0gdHlwZW9mKGVsZW1lbnRPckh0bWwpID09PSAic3RyaW5nIiwKICAgICAgICAgICAgZWxlbWVudCwKICAgICAgICAgICAgbmV3Tm9kZSwKICAgICAgICAgICAgZmlyc3RDaGlsZDsKCiAgICAgICAgaWYgKGlzU3RyaW5nKSB7CiAgICAgICAgICAgIGVsZW1lbnQgPSB3eXNpaHRtbDUuZG9tLmdldEFzRG9tKGVsZW1lbnRPckh0bWwsIGNvbnRleHQpOwogICAgICAgICAgICBpZiAocHJlUHJvY2VzcykgewogICAgICAgICAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBlbGVtZW50LmlubmVySFRNTC5yZXBsYWNlKC9cci9nLCAiIik7CiAgICAgICAgICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IGVsZW1lbnQuaW5uZXJIVE1MLnJlcGxhY2UoL1xuL2csICIgIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgICAgICBjb250ZXh0LmJvZHkuYXBwZW5kQ2hpbGQoZWxlbWVudCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdmFyIGlubmVySFRNTCA9IGVsZW1lbnRPckh0bWwuaW5uZXJIVE1MOwogICAgICAgICAgICBlbGVtZW50ID0gZWxlbWVudE9ySHRtbDsKICAgICAgICAgICAgaWYgKHByZVByb2Nlc3MpIHsKICAgICAgICAgICAgICAgIGlubmVySFRNTCA9IGlubmVySFRNTC5yZXBsYWNlKC9cci9nLCAiIik7CiAgICAgICAgICAgICAgICBpbm5lckhUTUwgPSBpbm5lckhUTUwucmVwbGFjZSgvXG4vZywgIiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gaW5uZXJIVE1MOwogICAgICAgIH0KICAgICAgICB3aGlsZSAoZWxlbWVudC5maXJzdENoaWxkKSB7CiAgICAgICAgICAgIGZpcnN0Q2hpbGQgPSBlbGVtZW50LmZpcnN0Q2hpbGQ7CiAgICAgICAgICAgIG5ld05vZGUgPSBfY29udmVydChmaXJzdENoaWxkLCBjbGVhblVwLCAiYm9keSIpOwogICAgICAgICAgICBlbGVtZW50LnJlbW92ZUNoaWxkKGZpcnN0Q2hpbGQpOwogICAgICAgICAgICBpZiAobmV3Tm9kZSkgewogICAgICAgICAgICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQobmV3Tm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIENsZWFyIGVsZW1lbnQgY29udGVudHMKICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9ICIiOwoKICAgICAgICAvLyBJbnNlcnQgbmV3IERPTSB0cmVlCiAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChmcmFnbWVudCk7CgogICAgICAgIC8vIENsZWFudXAgdGhlIFdvcmQgVG8gSFRNTCBDYWNoZQogICAgICAgIF9jbGVhblVwV29yZFRvSFRNTENhY2hlKCk7CgogICAgICAgIGlmIChpc1N0cmluZykgewogICAgICAgICAgICBjb250ZXh0LmJvZHkucmVtb3ZlQ2hpbGQoZWxlbWVudCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpc1N0cmluZyA/IHd5c2lodG1sNS5xdWlya3MuZ2V0Q29ycmVjdElubmVySFRNTChlbGVtZW50KSA6IGVsZW1lbnQ7CiAgICB9CgogICAgZnVuY3Rpb24gX2NvbnZlcnQob2xkTm9kZSwgY2xlYW5VcCwgbmV3UGFyZW50Tm9kZU5hbWUpIHsKICAgICAgICB2YXIgb2xkTm9kZVR5cGUgPSBvbGROb2RlLm5vZGVUeXBlLAogICAgICAgICAgICBvbGRDaGlsZHMgPSBvbGROb2RlLmNoaWxkTm9kZXMsCiAgICAgICAgICAgIG1ldGhvZCA9IE5PREVfVFlQRV9NQVBQSU5HW29sZE5vZGVUeXBlXSwKICAgICAgICAgICAgaSA9IDAsCiAgICAgICAgICAgIG5ld05vZGUsCiAgICAgICAgICAgIG5ld0NoaWxkOwoKICAgICAgICAvLyBSZXR1cm4gbnVsbCBmb3IgI3RleHQgbm9kZXMgd2hpY2ggaGFzIG9ubHkgd2hpdGVzcGFjZXMKICAgICAgICBpZiAob2xkTm9kZVR5cGUgPT0gMyAmJiAhb2xkTm9kZS5kYXRhLnRyaW0oKS5sZW5ndGggJiYgb2xkTm9kZS5wYXJlbnROb2RlLmhhc0F0dHJpYnV0ZSgnY2xhc3MnLCAnd3lzaWh0bWw1LWVkaXRvcicpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgbmV3Tm9kZSA9IG1ldGhvZCAmJiBtZXRob2Qob2xkTm9kZSwgbmV3UGFyZW50Tm9kZU5hbWUpOwoKICAgICAgICBpZiAoIW5ld05vZGUpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICB2YXIgb2xkQ2hpbGRzTGVuZ3RoID0gb2xkQ2hpbGRzLmxlbmd0aDsKICAgICAgICBmb3IgKGkgPSAwOwogICAgICAgICAgICAgaSA8IG9sZENoaWxkc0xlbmd0aDsKICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICBuZXdDaGlsZCA9IF9jb252ZXJ0KG9sZENoaWxkc1tpXSwgY2xlYW5VcCwgbmV3Tm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKTsKICAgICAgICAgICAgaWYgKG5ld0NoaWxkKSB7CiAgICAgICAgICAgICAgICBuZXdOb2RlLmFwcGVuZENoaWxkKG5ld0NoaWxkKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gQ2xlYW51cCBzZW5zZWxlc3MgPHNwYW4+IGVsZW1lbnRzCiAgICAgICAgaWYgKGNsZWFuVXAgJiYgbmV3Tm9kZS5jaGlsZE5vZGVzLmxlbmd0aCA8PSAxICYmIG5ld05vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gREVGQVVMVF9OT0RFX05BTUUgJiYgIW5ld05vZGUuYXR0cmlidXRlcy5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIG5ld05vZGUuZmlyc3RDaGlsZDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXdOb2RlOwogICAgfQoKICAgIGZ1bmN0aW9uIF9oYW5kbGVFbGVtZW50KG9sZE5vZGUsIG5ld1BhcmVudE5vZGVOYW1lKSB7CiAgICAgICAgdmFyIHJ1bGUsCiAgICAgICAgICAgIG5ld05vZGUsCiAgICAgICAgICAgIHRhZ1J1bGVzID0gY3VycmVudFJ1bGVzLnRhZ3MsCiAgICAgICAgICAgIHBzZXVkb1RhZ3MgPSBjdXJyZW50UnVsZXMucHNldWRvVGFncyB8fCBbXSwKICAgICAgICAgICAgbm9kZU5hbWUgPSBvbGROb2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCksCiAgICAgICAgICAgIHNjb3BlTmFtZSA9IG9sZE5vZGUuc2NvcGVOYW1lLAogICAgICAgICAgICB0YWJsZUVsZW1lbnRzID0gWyJ0YWJsZSIsICJ0aGVhZCIsICJ0Zm9vdCIsICJ0aCIsICJjb2xncm91cCIsICJjb2wiLCAidGJvZHkiLCAidHIiLCAidGQiXTsKCiAgICAgICAgLyoqCiAgICAgICAgICogV2UgYWxyZWFkeSBwYXJzZWQgdGhhdCBlbGVtZW50CiAgICAgICAgICogaWdub3JlIGl0ISAoeWVzLCB0aGlzIHNvbWV0aW1lcyBoYXBwZW5zIGluIElFOCB3aGVuIHRoZSBodG1sIGlzIGludmFsaWQpCiAgICAgICAgICovCiAgICAgICAgaWYgKG9sZE5vZGUuX3d5c2lodG1sNSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgb2xkTm9kZS5fd3lzaWh0bWw1ID0gMTsKCiAgICAgICAgaWYgKG9sZE5vZGUuY2xhc3NOYW1lID09PSAid3lzaWh0bWw1LXRlbXAiKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICB2YXIgaXNUYWJsZUVsZW1lbnQgPSB0YWJsZUVsZW1lbnRzLmluZGV4T2Yobm9kZU5hbWUpID4gLTE7CiAgICAgICAgaWYgKCFpc1RhYmxlRWxlbWVudCAmJiAoIW9sZE5vZGUudGV4dENvbnRlbnQgfHwgIW9sZE5vZGUudGV4dENvbnRlbnQucmVwbGFjZSgvXG4vZywgIiIpKSAmJiBvbGROb2RlLm91dGVySFRNTC5zZWFyY2goIjxicj4iKSA9PSAtMSkgeyAvL0lmIGZpcnN0RWxlbWVudENoaWxkIGlzIG5vdCBmb3VuZCBhbmQgZmlyc3RFbGVtZW50IGlzIG5vdCBhIGJsYW5rIGxpbmUuCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKG9sZE5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PSAibGkiICYmICFvbGROb2RlLnRleHRDb250ZW50LnRyaW0oKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIElFIGlzIHRoZSBvbmx5IGJyb3dzZXIgd2hvIGRvZXNuJ3QgaW5jbHVkZSB0aGUgbmFtZXNwYWNlIGluIHRoZQogICAgICAgICAqIG5vZGVOYW1lLCB0aGF0J3Mgd2h5IHdlIGhhdmUgdG8gcHJlcGVuZCBpdCBieSBvdXJzZWx2ZXMKICAgICAgICAgKiBzY29wZU5hbWUgaXMgYSBwcm9wcmlldGFyeSBJRSBmZWF0dXJlCiAgICAgICAgICogcmVhZCBtb3JlIGhlcmUgaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21zNTM0Mzg4KHY9dnMuODUpLmFzcHgKICAgICAgICAgKi8KICAgICAgICBpZiAoc2NvcGVOYW1lICYmIHNjb3BlTmFtZSAhPSAiSFRNTCIpIHsKICAgICAgICAgICAgbm9kZU5hbWUgPSBzY29wZU5hbWUgKyAiOiIgKyBub2RlTmFtZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJlcGFpciBub2RlCiAgICAgICAgICogSUUgaXMgYSBiaXQgYml0Y2h5IHdoZW4gaXQgY29tZXMgdG8gaW52YWxpZCBuZXN0ZWQgbWFya3VwIHdoaWNoIGluY2x1ZGVzIHVuY2xvc2VkIHRhZ3MKICAgICAgICAgKiBBIDxwPiBkb2Vzbid0IG5lZWQgdG8gYmUgY2xvc2VkIGFjY29yZGluZyBIVE1MNC01IHNwZWMsIHdlIHNpbXBseSByZXBsYWNlIGl0IHdpdGggYSA8ZGl2PiB0byBwcmVzZXJ2ZSBpdHMgY29udGVudCBhbmQgbGF5b3V0CiAgICAgICAgICovCiAgICAgICAgaWYgKCJvdXRlckhUTUwiIGluIG9sZE5vZGUpIHsKICAgICAgICAgICAgaWYgKCF3eXNpaHRtbDUuYnJvd3Nlci5hdXRvQ2xvc2VzVW5jbG9zZWRUYWdzKCkgJiYgb2xkTm9kZS5ub2RlTmFtZSA9PT0gIlAiICYmIG9sZE5vZGUub3V0ZXJIVE1MLnNsaWNlKC00KS50b0xvd2VyQ2FzZSgpICE9PSAiPC9wPiIpIHsKICAgICAgICAgICAgICAgIG5vZGVOYW1lID0gImRpdiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrIGlmIGN1cnJlbnROb2RlJ3MgY2hpbGQgaXMgdG8gYmUgcmVtb3ZlZCBhcyBwZXIgdGhlIHRhZ1J1bGVzCiAgICAgICAgICogYW5kIGlmIGN1cnJlbnROb2RlJ3MgY2hpbGQgY29udGFpbnMgaW5uZXJIVE1MIGRhdGEsCiAgICAgICAgICogdGhlbiBhc3NpZ24gY2hpbGQncyBIVE1MIGludG8gY3VycmVudE5vZGUncyBIVE1MLCB0byByZW1vdmUgdGhlIGNoaWxkIHRhZwogICAgICAgICAqLwogICAgICAgIGlmIChvbGROb2RlLmhhc0NoaWxkTm9kZXMoKSkgewogICAgICAgICAgICB2YXIgY2hpbGROb2RlTmFtZSA9IG9sZE5vZGUuZmlyc3RDaGlsZC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICBpZiAoY2hpbGROb2RlTmFtZSBpbiB0YWdSdWxlcykgewogICAgICAgICAgICAgICAgcnVsZSA9IHRhZ1J1bGVzW2NoaWxkTm9kZU5hbWVdOwogICAgICAgICAgICAgICAgaWYgKCghcnVsZSB8fCBydWxlLnJlbW92ZSkgJiYgb2xkTm9kZS5maXJzdENoaWxkLmlubmVySFRNTCkgewogICAgICAgICAgICAgICAgICAgIG9sZE5vZGUuaW5uZXJIVE1MID0gb2xkTm9kZS5maXJzdENoaWxkLmlubmVySFRNTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG5vZGVOYW1lIGluIHRhZ1J1bGVzKSB7CiAgICAgICAgICAgIHJ1bGUgPSB0YWdSdWxlc1tub2RlTmFtZV07CiAgICAgICAgICAgIGlmICghcnVsZSB8fCBydWxlLnJlbW92ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJ1bGUgPSB0eXBlb2YocnVsZSkgPT09ICJzdHJpbmciID8ge3JlbmFtZV90YWcgOiBydWxlfSA6IHJ1bGU7CiAgICAgICAgfSBlbHNlIGlmIChvbGROb2RlLmZpcnN0Q2hpbGQpIHsKICAgICAgICAgICAgcnVsZSA9IHtyZW5hbWVfdGFnIDogREVGQVVMVF9OT0RFX05BTUV9OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIFJlbW92ZSBlbXB0eSB1bmtub3duIGVsZW1lbnRzCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgdmFyIGxpc3RUeXBlcyA9IFsib2wiLCAidWwiLCAiZGlyIiwgIm1lbnUiXTsKICAgICAgICBpZiAobGlzdFR5cGVzLmluZGV4T2Yobm9kZU5hbWUpID49IDApIHsKICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gb2xkTm9kZS5jaGlsZE5vZGVzOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB2YXIgY2hpbGROb2RlTmFtZSA9IGNoaWxkcmVuW2ldICYmIGNoaWxkcmVuW2ldLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICBpZiAoY2hpbGROb2RlTmFtZSAmJiAoY2hpbGRyZW5baV0ubm9kZVR5cGUgPT0gMSB8fCBjaGlsZHJlbltpXS5ub2RlVHlwZSA9PSAzKSAmJiBjaGlsZHJlbltpXS50ZXh0Q29udGVudCAmJiBsaXN0VHlwZXMuaW5kZXhPZihjaGlsZE5vZGVOYW1lKSA9PSAtMSAmJiBjaGlsZE5vZGVOYW1lICE9ICJsaSIpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbGlOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiTEkiKTsKICAgICAgICAgICAgICAgICAgICBvbGROb2RlLmluc2VydEJlZm9yZShsaU5vZGUsIGNoaWxkcmVuW2ldKTsKICAgICAgICAgICAgICAgICAgICBsaU5vZGUuYXBwZW5kQ2hpbGQoY2hpbGRyZW5baSArIDFdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdmFyIGxpc3RUeXBlID0gX2lzTVNvTGlzdFBhcmFncmFwaENoaWxkKG9sZE5vZGUpOwogICAgICAgIHZhciB2YWxpZENoaWxkQ291bnQgPSBfdmFsaWRDaGlsZE5vZGVDb3VudChvbGROb2RlKTsKICAgICAgICBpZiAobGlzdFR5cGUgJiYgdmFsaWRDaGlsZENvdW50KSB7IC8vQ2hpbGQgRWxlbWVudCBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIHR3by4KICAgICAgICAgICAgbmV3Tm9kZSA9IF9jb252ZXJ0V29yZFRvSFRNTE5vZGUob2xkTm9kZSwgdGFnUnVsZXMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICgvTXNvTm9ybWFsL2kudGVzdChvbGROb2RlLmNsYXNzTmFtZSkgfHwgKGxpc3RUeXBlICYmICF2YWxpZENoaWxkQ291bnQpKSB7IC8vY2xlYW4gbGlzdCBjYWNoZSBpZiBhIHBhcmEgYXBwZWFycyBhZnRlciBsaXN0LgogICAgICAgICAgICAgICAgX2NsZWFuVXBXb3JkVG9IVE1MQ2FjaGUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgcmVuYW1lVGFnID0gcnVsZS5yZW5hbWVfdGFnIHx8IG5vZGVOYW1lOwogICAgICAgICAgICBpZiAocHJlUHJvY2Vzc2luZ0NvbnRlbnQpIHsKICAgICAgICAgICAgICAgIG5ld05vZGUgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudChyZW5hbWVUYWcpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIGJsb2NrRWxlbWVudHMgPSBbInAiLCAiaDEiLCAiaDIiLCAiaDMiLCAiaDQiLCAiaDUiLCAiaDYiLCAib2wiLCAidWwiXTsKICAgICAgICAgICAgICAgIHZhciBwYXJlbnROb2RlID0gb2xkTm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgd2hpbGUgKG5ld1BhcmVudE5vZGVOYW1lICYmIG5ld1BhcmVudE5vZGVOYW1lICE9ICJib2R5IiAmJiBwc2V1ZG9UYWdzLmluZGV4T2YobmV3UGFyZW50Tm9kZU5hbWUpID4gLTEpIHsKICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gcGFyZW50Tm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIGlmICh3eXNpaHRtbDUudXRpbC5pc0VkaXRvck5vZGUocGFyZW50Tm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3UGFyZW50Tm9kZU5hbWUgPSAiYm9keSI7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3UGFyZW50Tm9kZU5hbWUgPSAocGFyZW50Tm9kZSAmJiBwYXJlbnROb2RlLm5vZGVOYW1lKSA/IHBhcmVudE5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA6ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChwc2V1ZG9UYWdzLmluZGV4T2YocmVuYW1lVGFnKSA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIC8vRm9yIFRhYmxlIGVsZW1lbnRzIGNyZWF0ZSB0aGUgc2FtZSBuZXcgbm9kZQogICAgICAgICAgICAgICAgICAgIGlmIChpc1RhYmxlRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdOb2RlID0gb2xkTm9kZS5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQocmVuYW1lVGFnKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5ld1BhcmVudE5vZGVOYW1lID09ICJib2R5IiAmJiBibG9ja0VsZW1lbnRzLmluZGV4T2YocmVuYW1lVGFnKSA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdOb2RlID0gb2xkTm9kZS5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInAiKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChuZXdQYXJlbnROb2RlTmFtZSA9PSAidWwiIHx8IG5ld1BhcmVudE5vZGVOYW1lID09ICJvbCIpICYmIHJlbmFtZVRhZyAhPSAibGkiICYmIHJlbmFtZVRhZyAhPSAib2wiICYmIHJlbmFtZVRhZyAhPSAidWwiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgibGkiKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5ld1BhcmVudE5vZGVOYW1lICE9ICJib2R5IiAmJiBuZXdQYXJlbnROb2RlTmFtZSAhPSAibGkiICYmIFsicCIsICJoMSIsICJoMiIsICJoMyIsICJoNCIsICJoNSIsICJoNiJdLmluZGV4T2YocmVuYW1lVGFnKSA+IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKG5ld1BhcmVudE5vZGVOYW1lICE9ICJib2R5IiAmJiBuZXdQYXJlbnROb2RlTmFtZSAhPSAib2wiICYmIG5ld1BhcmVudE5vZGVOYW1lICE9ICJ1bCIgJiYgbmV3UGFyZW50Tm9kZU5hbWUgIT0gImxpIikgJiYgWyJvbCIsICJ1bCIsICJsaSJdLmluZGV4T2YocmVuYW1lVGFnKSA+IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudChyZW5hbWVUYWcpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSA9IG9sZE5vZGUub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KHJlbmFtZVRhZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX2hhbmRsZUF0dHJpYnV0ZXMob2xkTm9kZSwgbmV3Tm9kZSwgcnVsZSk7CiAgICAgICAgfQoKICAgICAgICBvbGROb2RlID0gbnVsbDsKICAgICAgICByZXR1cm4gbmV3Tm9kZTsKICAgIH0KCiAgICBmdW5jdGlvbiBfaGFuZGxlQXR0cmlidXRlcyhvbGROb2RlLCBuZXdOb2RlLCBydWxlKSB7CiAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7fSwgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZnJlc2ggbmV3IHNldCBvZiBhdHRyaWJ1dGVzIHRvIHNldCBvbiBuZXdOb2RlCiAgICAgICAgICAgIHNldENsYXNzID0gcnVsZS5zZXRfY2xhc3MsICAgICAgICAgICAgIC8vIGNsYXNzZXMgdG8gc2V0CiAgICAgICAgICAgIGFkZENsYXNzID0gcnVsZS5hZGRfY2xhc3MsICAgICAgICAgICAgIC8vIGFkZCBjbGFzc2VzIGJhc2VkIG9uIGV4aXN0aW5nIGF0dHJpYnV0ZXMKICAgICAgICAgICAgc2V0QXR0cmlidXRlcyA9IHJ1bGUuc2V0X2F0dHJpYnV0ZXMsICAgICAgICAvLyBhdHRyaWJ1dGVzIHRvIHNldCBvbiB0aGUgY3VycmVudCBub2RlCiAgICAgICAgICAgIGNoZWNrQXR0cmlidXRlcyA9IHJ1bGUuY2hlY2tfYXR0cmlidXRlcywgICAgICAvLyBjaGVjay9jb252ZXJ0IHZhbHVlcyBvZiBhdHRyaWJ1dGVzCiAgICAgICAgICAgIGFsbG93ZWRDbGFzc2VzID0gY3VycmVudFJ1bGVzLmNsYXNzZXMsCiAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICBjbGFzc2VzID0gW10sCiAgICAgICAgICAgIG5ld0NsYXNzZXMgPSBbXSwKICAgICAgICAgICAgbmV3VW5pcXVlQ2xhc3NlcyA9IFtdLAogICAgICAgICAgICBvbGRDbGFzc2VzID0gW10sCiAgICAgICAgICAgIGNsYXNzZXNMZW5ndGgsCiAgICAgICAgICAgIG5ld0NsYXNzZXNMZW5ndGgsCiAgICAgICAgICAgIGN1cnJlbnRDbGFzcywKICAgICAgICAgICAgbmV3Q2xhc3MsCiAgICAgICAgICAgIGF0dHJpYnV0ZU5hbWUsCiAgICAgICAgICAgIG5ld0F0dHJpYnV0ZVZhbHVlLAogICAgICAgICAgICBtZXRob2Q7CgogICAgICAgIHZhciBuZXdOb2RldGFnUnVsZXMgPSBjdXJyZW50UnVsZXMudGFnczsKICAgICAgICB2YXIgbmV3Tm9kZU5hbWUgPSBuZXdOb2RlID8gbmV3Tm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpIDogbnVsbDsKICAgICAgICB2YXIgbmV3Tm9kZVJ1bGVzOwogICAgICAgIGlmIChuZXdOb2RlTmFtZSAmJiAobmV3Tm9kZU5hbWUgaW4gbmV3Tm9kZXRhZ1J1bGVzKSkgewogICAgICAgICAgICBuZXdOb2RlUnVsZXMgPSBuZXdOb2RldGFnUnVsZXNbbmV3Tm9kZU5hbWVdOwogICAgICAgIH0KICAgICAgICB2YXIgcmVtb3ZlQXR0cmlidXRlcyA9IG5ld05vZGVSdWxlcyA/IG5ld05vZGVSdWxlcy5yZW1vdmVfYXR0cmlidXRlcyA6IG51bGw7IC8vIFJlbW92ZSBhdHRyaWJ1dGVzIGZyb20gb2xkIG5vZGUuCgogICAgICAgIGlmIChyZW1vdmVBdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVtb3ZlQXR0cmlidXRlcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIGF0dHIgPSByZW1vdmVBdHRyaWJ1dGVzW2ldOwogICAgICAgICAgICAgICAgaWYgKGF0dHIpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgYXR0ckFycmF5ID0gYXR0ci5zcGxpdCgiLCIpOwogICAgICAgICAgICAgICAgICAgIGlmIChhdHRyQXJyYXkubGVuZ3RoID09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb2xkTm9kZS5yZW1vdmVBdHRyaWJ1dGUocmVtb3ZlQXR0cmlidXRlc1tpXSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHIgPSBvbGROb2RlW2F0dHJBcnJheVswXV07CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZEF0dHIgPSBhdHRyW2F0dHJBcnJheVsxXV07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZEF0dHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyQXJyYXkubGVuZ3RoID4gMiAmJiAoY2hpbGRBdHRyLmluZGV4T2YoYXR0ckFycmF5WzJdKSAhPSAtMSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyLnJlbW92ZVByb3BlcnR5KGF0dHJBcnJheVsxXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGF0dHJBcnJheS5sZW5ndGggPD0gMikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIucmVtb3ZlUHJvcGVydHkoYXR0ckFycmF5WzFdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHNldEF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgYXR0cmlidXRlcyA9IHd5c2lodG1sNS5sYW5nLm9iamVjdChzZXRBdHRyaWJ1dGVzKS5jbG9uZSgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGNoZWNrQXR0cmlidXRlcykgewogICAgICAgICAgICBmb3IgKGF0dHJpYnV0ZU5hbWUgaW4gY2hlY2tBdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICBtZXRob2QgPSBhdHRyaWJ1dGVDaGVja01ldGhvZHNbY2hlY2tBdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdXTsKICAgICAgICAgICAgICAgIGlmICghbWV0aG9kKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBuZXdBdHRyaWJ1dGVWYWx1ZSA9IG1ldGhvZChfZ2V0QXR0cmlidXRlKG9sZE5vZGUsIGF0dHJpYnV0ZU5hbWUpKTsKICAgICAgICAgICAgICAgIGlmICh0eXBlb2YobmV3QXR0cmlidXRlVmFsdWUpID09PSAic3RyaW5nIikgewogICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNbYXR0cmlidXRlTmFtZV0gPSBuZXdBdHRyaWJ1dGVWYWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHNldENsYXNzKSB7CiAgICAgICAgICAgIGNsYXNzZXMucHVzaChzZXRDbGFzcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoYWRkQ2xhc3MpIHsKICAgICAgICAgICAgZm9yIChhdHRyaWJ1dGVOYW1lIGluIGFkZENsYXNzKSB7CiAgICAgICAgICAgICAgICBtZXRob2QgPSBhZGRDbGFzc01ldGhvZHNbYWRkQ2xhc3NbYXR0cmlidXRlTmFtZV1dOwogICAgICAgICAgICAgICAgaWYgKCFtZXRob2QpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5ld0NsYXNzID0gbWV0aG9kKF9nZXRBdHRyaWJ1dGUob2xkTm9kZSwgYXR0cmlidXRlTmFtZSkpOwogICAgICAgICAgICAgICAgaWYgKHR5cGVvZihuZXdDbGFzcykgPT09ICJzdHJpbmciKSB7CiAgICAgICAgICAgICAgICAgICAgY2xhc3Nlcy5wdXNoKG5ld0NsYXNzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgd3lzaWh0bWw1IHRlbXAgY2xhc3MgZG9lc24ndCBnZXQgc3RyaXBwZWQgb3V0CiAgICAgICAgYWxsb3dlZENsYXNzZXNbIl93eXNpaHRtbDUtdGVtcC1wbGFjZWhvbGRlciJdID0gMTsKICAgICAgICBhbGxvd2VkQ2xhc3Nlc1siQXBwbGUtdGFiLXNwYW4iXSA9IDI7CgogICAgICAgIC8vIGFkZCBvbGQgY2xhc3NlcyBsYXN0CiAgICAgICAgb2xkQ2xhc3NlcyA9IG9sZE5vZGUuZ2V0QXR0cmlidXRlKCJjbGFzcyIpOwogICAgICAgIGlmIChvbGRDbGFzc2VzKSB7CiAgICAgICAgICAgIGNsYXNzZXMgPSBjbGFzc2VzLmNvbmNhdChvbGRDbGFzc2VzLnNwbGl0KFdISVRFX1NQQUNFX1JFR19FWFApKTsKICAgICAgICB9CiAgICAgICAgY2xhc3Nlc0xlbmd0aCA9IGNsYXNzZXMubGVuZ3RoOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBjbGFzc2VzTGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgY3VycmVudENsYXNzID0gY2xhc3Nlc1tpXTsKICAgICAgICAgICAgaWYgKGFsbG93ZWRDbGFzc2VzW2N1cnJlbnRDbGFzc10pIHsKICAgICAgICAgICAgICAgIG5ld0NsYXNzZXMucHVzaChjdXJyZW50Q2xhc3MpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyByZW1vdmUgZHVwbGljYXRlIGVudHJpZXMgYW5kIHByZXNlcnZlIGNsYXNzIHNwZWNpZmljaXR5CiAgICAgICAgbmV3Q2xhc3Nlc0xlbmd0aCA9IG5ld0NsYXNzZXMubGVuZ3RoOwogICAgICAgIHdoaWxlIChuZXdDbGFzc2VzTGVuZ3RoLS0pIHsKICAgICAgICAgICAgY3VycmVudENsYXNzID0gbmV3Q2xhc3Nlc1tuZXdDbGFzc2VzTGVuZ3RoXTsKICAgICAgICAgICAgaWYgKCF3eXNpaHRtbDUubGFuZy5hcnJheShuZXdVbmlxdWVDbGFzc2VzKS5jb250YWlucyhjdXJyZW50Q2xhc3MpKSB7CiAgICAgICAgICAgICAgICBuZXdVbmlxdWVDbGFzc2VzLnVuc2hpZnQoY3VycmVudENsYXNzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG5ld1VuaXF1ZUNsYXNzZXMubGVuZ3RoKSB7CiAgICAgICAgICAgIGF0dHJpYnV0ZXNbImNsYXNzIl0gPSBuZXdVbmlxdWVDbGFzc2VzLmpvaW4oIiAiKTsKICAgICAgICB9CgogICAgICAgIC8vIHNldCBhdHRyaWJ1dGVzIG9uIG5ld05vZGUKICAgICAgICBmb3IgKGF0dHJpYnV0ZU5hbWUgaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICAvLyBTZXR0aW5nIGF0dHJpYnV0ZXMgY2FuIGNhdXNlIGEganMgZXJyb3IgaW4gSUUgdW5kZXIgY2VydGFpbiBjaXJjdW1zdGFuY2VzCiAgICAgICAgICAgIC8vIGVnLiBvbiBhIDxpbWc+IHVuZGVyIGh0dHBzIHdoZW4gaXQncyBuZXcgYXR0cmlidXRlIHZhbHVlIGlzIG5vbi1odHRwcwogICAgICAgICAgICAvLyBUT0RPOiBJbnZlc3RpZ2F0ZSB0aGlzIGZ1cnRoZXIgYW5kIGNoZWNrIGZvciBzbWFydGVyIGhhbmRsaW5nCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBuZXdOb2RlLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCBhdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdKTsKICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBJRTggc29tZXRpbWVzIGxvc2VzIHRoZSB3aWR0aC9oZWlnaHQgYXR0cmlidXRlcyB3aGVuIHRob3NlIGFyZSBzZXQgYmVmb3JlIHRoZSAic3JjIgogICAgICAgIC8vIHNvIHdlIG1ha2Ugc3VyZSB0byBzZXQgdGhlbSBhZ2FpbgogICAgICAgIGlmIChhdHRyaWJ1dGVzLnNyYykgewogICAgICAgICAgICBpZiAodHlwZW9mKGF0dHJpYnV0ZXMud2lkdGgpICE9PSAidW5kZWZpbmVkIikgewogICAgICAgICAgICAgICAgbmV3Tm9kZS5zZXRBdHRyaWJ1dGUoIndpZHRoIiwgYXR0cmlidXRlcy53aWR0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHR5cGVvZihhdHRyaWJ1dGVzLmhlaWdodCkgIT09ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgICAgICBuZXdOb2RlLnNldEF0dHJpYnV0ZSgiaGVpZ2h0IiwgYXR0cmlidXRlcy5oZWlnaHQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBfY29weVN0eWxlVG9OZXdOb2RlKG9sZE5vZGUsIG5ld05vZGUpOwogICAgICAgIF9jb3B5TGlzdFR5cGVUb05ld05vZGUob2xkTm9kZSwgbmV3Tm9kZSk7CiAgICAgICAgX2NvcHlEYXRhQXR0cmlidXRlVG9OZXdOb2RlKG9sZE5vZGUsIG5ld05vZGUpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9jb3B5RGF0YUF0dHJpYnV0ZVRvTmV3Tm9kZShvbGROb2RlLCBuZXdOb2RlKSB7CiAgICAgICAgaWYgKG9sZE5vZGUgJiYgbmV3Tm9kZSkgewogICAgICAgICAgICB2YXIgZGF0YXNldCA9IG9sZE5vZGUuZGF0YXNldDsKICAgICAgICAgICAgZm9yICh2YXIgYXR0cmlidXRlIGluIGRhdGFzZXQpIHsKICAgICAgICAgICAgICAgICQobmV3Tm9kZSkuZGF0YShhdHRyaWJ1dGUsIGRhdGFzZXRbYXR0cmlidXRlXSk7CiAgICAgICAgICAgICAgICAkKG5ld05vZGUpLmF0dHIoJ2RhdGEtJyArIGF0dHJpYnV0ZSwgZGF0YXNldFthdHRyaWJ1dGVdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfY29weUxpc3RUeXBlVG9OZXdOb2RlKG9sZE5vZGUsIG5ld05vZGUpIHsKICAgICAgICBpZiAob2xkTm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09ICdvbCcpIHsKICAgICAgICAgICAgdmFyIGxpc3RUeXBlID0gb2xkTm9kZS5nZXRBdHRyaWJ1dGUoJ3R5cGUnKTsKICAgICAgICAgICAgaWYgKGxpc3RUeXBlKSB7CiAgICAgICAgICAgICAgICBuZXdOb2RlLnNldEF0dHJpYnV0ZSgndHlwZScsIGxpc3RUeXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfY29weVN0eWxlVG9OZXdOb2RlKG9sZE5vZGUsIG5ld05vZGUpIHsKICAgICAgICB2YXIgc3VwcG9ydGVkU3R5bGVzID0gY3VycmVudFJ1bGVzLnN0eWxlczsKICAgICAgICB2YXIgY29tcHV0ZWRTdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShvbGROb2RlKSwKICAgICAgICAgICAgYXBwbGllZFN0eWxlcyA9IG9sZE5vZGUuc3R5bGU7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcHBsaWVkU3R5bGVzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHZhciBzdHlsZUF0dHIgPSBhcHBsaWVkU3R5bGVzW2ldOwogICAgICAgICAgICB2YXIgdmFsdWUgPSBhcHBsaWVkU3R5bGVzLmdldFByb3BlcnR5VmFsdWUoc3R5bGVBdHRyKTsKICAgICAgICAgICAgaWYgKHN1cHBvcnRlZFN0eWxlcy5pbmRleE9mKHN0eWxlQXR0cikgPj0gMCkgewogICAgICAgICAgICAgICAgaWYgKHByZVByb2Nlc3NpbmdDb250ZW50ICYmIHN0eWxlQXR0ciA9PT0gImJhY2tncm91bmQtY29sb3IiICYmIHZhbHVlID09PSAicmdiKDI1NSwgMjU1LCAyNTUpIikgewogICAgICAgICAgICAgICAgICAgIC8qIFJlbW92ZSBiYWNrZ3JvdW5kIGNvbG9yIGlmIHdoaXRlIHNpbmNlIGl0cyByZWR1bmRhbnQgYXMgaXQgaXMgc2FtZSBhcyBkZWZhdWx0CiAgICAgICAgICAgICAgICAgICAgKiBGaXhlcyBidWcgQ1EtNDIwOTA0NyAqLwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIXZhbHVlIHx8ICF2YWx1ZS5tYXRjaCgvXlsuXGRdK3B0JC8pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IGNvbXB1dGVkU3R5bGVzLmdldFByb3BlcnR5VmFsdWUoc3R5bGVBdHRyKSB8fCAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgLyogUmVwbGFjZSBhbGwgcHggdmFsdWVzIHRvIHB0Ki8KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlZ0V4cCA9IG5ldyBSZWdFeHAoIl4oWy5cXGRdKylweCQiLCAiZyIpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gcmVnRXhwLmV4ZWModmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWVJblB4ID0gcGFyc2VGbG9hdChyZXN1bHRbMV0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlSW5QdCA9ICIiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc05hTih2YWx1ZUluUHgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVJblB0ID0gKHZhbHVlSW5QeCAqIDAuNzUpICsgInB0IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZShyZWdFeHAsIHZhbHVlSW5QdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBuZXdOb2RlLnN0eWxlLnNldFByb3BlcnR5KHN0eWxlQXR0ciwgdmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vSW4gZmlyZWZveCwgbm9kZS5jaGlsZEVsZW1lbnRDb3VudCBpcyBjaGlsZG5vZGVzIGNvdW50IHdoZXJlIGNoaWxkbm9kZXMgYXJlIG9mIGVsZW1lbnQgdHlwZSAoTm9kZS5FTEVNRU5UX05PREUgPT0gMSksIGl0IGRvZXMgbm90IGNvbnNpZGVyIHRleHQgdHlwZSBub2RlIGFzIGVsZW1lbnQgbm9kZS4KICAgIGZ1bmN0aW9uIF92YWxpZENoaWxkTm9kZUNvdW50KG9sZE5vZGUpIHsKICAgICAgICBpZiAob2xkTm9kZSkgewogICAgICAgICAgICB2YXIgY2hpbGROb2RlcyA9IG9sZE5vZGUuY2hpbGROb2RlczsKICAgICAgICAgICAgdmFyIGNoaWxkTm9kZSwgY291bnQgPSAwOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIGNoaWxkTm9kZSA9IGNoaWxkTm9kZXNbaV07CiAgICAgICAgICAgICAgICBpZiAoKGNoaWxkTm9kZS5ub2RlVHlwZSA9PSAxIHx8IGNoaWxkTm9kZS5ub2RlVHlwZSA9PSAzKSAmJiBjaGlsZE5vZGUudGV4dENvbnRlbnQgJiYgY2hpbGROb2RlLnRleHRDb250ZW50LnRyaW0oKSkgewogICAgICAgICAgICAgICAgICAgIGNvdW50Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNvdW50ID49IDIpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvLyBCdWcgRml4IC0gQ1EtOTUxMzAuIEluIGxpc3RpbmcgZXh0cmEgc3BhY2UgaXMgYWRkZWQuIFJlbW92aW5nIGFsbCBleHRyYSBzcGFjZSBmcm9tIGp1c3QgYmVmb3JlIGFuZCBhZnRlciBub2RlIG9mIHR5cGUgZGV0ZXJtaW5pbmcKICAgIC8vIG5vZGUgb2YgTXNvIGxpc3QuCiAgICBmdW5jdGlvbiBfcmVtb3ZlRXh0cmFTcGFjZShvbGROb2RlLCB0eXBlRGV0ZXJtaW5pZ05vZGUpIHsKICAgICAgICB2YXIgY2hpbGROb2RlcyA9IG9sZE5vZGUuY2hpbGROb2RlczsKICAgICAgICB2YXIgY2hpbGROb2RlLCBpOwogICAgICAgIGlmICghd3lzaWh0bWw1LmJyb3dzZXIuaXNGaXJlRm94KSB7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGNoaWxkTm9kZXNbaV0gIT0gdHlwZURldGVybWluaWdOb2RlOyBpKyspIHsKICAgICAgICAgICAgICAgIGNoaWxkTm9kZSA9IGNoaWxkTm9kZXNbaV07CiAgICAgICAgICAgICAgICBpZiAoY2hpbGROb2RlICYmIGNoaWxkTm9kZS50ZXh0Q29udGVudCkgewogICAgICAgICAgICAgICAgICAgIGNoaWxkTm9kZS50ZXh0Q29udGVudCA9IGNoaWxkTm9kZS50ZXh0Q29udGVudC50cmltKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaSsrOyAvLyBKdXN0IG5leHQgbm9kZSB0byBMaXN0IHR5cGUgZGV0ZXJtaW5pbmcgbm9kZQogICAgICAgICAgICBjaGlsZE5vZGUgPSBjaGlsZE5vZGVzW2ldOwogICAgICAgICAgICBpZiAoY2hpbGROb2RlICYmIGNoaWxkTm9kZS50ZXh0Q29udGVudCkgewogICAgICAgICAgICAgICAgY2hpbGROb2RlLnRleHRDb250ZW50ID0gY2hpbGROb2RlLnRleHRDb250ZW50LnRyaW0oKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gb2xkTm9kZTsKICAgIH0KCiAgICBmdW5jdGlvbiBfY29udmVydFdvcmRUb0hUTUxOb2RlKG9sZE5vZGUsIHRhZ1J1bGVzKSB7CiAgICAgICAgaWYgKG9sZE5vZGUpIHsKICAgICAgICAgICAgLyogY2hlY2sgaWYgaXRzIE1zb0xpc3RQYXJhZ3JhcGggdGhlbiBjcmVhdGUgbGkgYW5kIGlmIGl0cyBNc29MaXN0UGFyYWdyYXBoQ3hTcEZpcnN0IHRoZW4gY29udmVydCB0byBPTCBvciBVTAogICAgICAgICAgICAgKiBPTCBvciBVTCBpcyBkZWNpZGVkIGJhc2VkIG9uIGZpcnN0IFNwYW4gY29udGVudAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKC9Nc29MaXN0UGFyYWdyYXBoL2kudGVzdChvbGROb2RlLmNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgICAgIHZhciBpc05ld0NvbnRhaW5lciA9IF9zZXRDdXJyZW50TGlzdEVsZW1lbnQob2xkTm9kZSk7CiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgTEkgYW5kIGNvcHkgdGhlIGNoaWxkIG9mIG9sZCBub2RlIHRvIG5ldyBMSSBub2RlIHVzaW5nIHJ1bGUgd3JpdHRlbiBmb3IgcGFyc2luZwogICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgibGkiKSwKICAgICAgICAgICAgICAgICAgICBvbGRGb250RmFtaWx5ID0gb2xkTm9kZS5maXJzdEVsZW1lbnRDaGlsZC5zdHlsZS5mb250RmFtaWx5LAogICAgICAgICAgICAgICAgICAgIGZvbnRGYW1pbHlMaXN0ID0gQXJyYXkuZnJvbSgkKCIjdGV4dEVkaXRvcl9mb250RmFtaWx5X2NvbnRhaW5lciBjb3JhbC1zZWxlY3QtaXRlbSIpKS5tYXAoZnVuY3Rpb24gKGl0ZW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0udmFsdWU7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBjb3BpZWQgZm9udC1mYW1pbHkgaXMgcHJlc2V0IGluIHJ0ZS1lZGl0b3IgZm9udCBsaXN0LCBhZGQgZm9udC1mYW1pbHkgdG8gbGkgZWxlbWVudAogICAgICAgICAgICAgICAgaWYgKG9sZEZvbnRGYW1pbHkgIT0gbnVsbCAmJiBmb250RmFtaWx5TGlzdC5pbmNsdWRlcyhvbGRGb250RmFtaWx5LnNwbGl0KCIsIilbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5mb250RmFtaWx5ID0gb2xkRm9udEZhbWlseTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciBwYXJhRWxlbWVudCA9IG9sZE5vZGUub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KCJwIik7CiAgICAgICAgICAgICAgICBpZiAob2xkTm9kZS5maXJzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5ld05vZGUgPSBudWxsLCBmaXJzdENoaWxkID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBmaXJzdENoaWxkID0gX2dldFRleHRDaGlsZE5vZGUob2xkTm9kZSk7CiAgICAgICAgICAgICAgICAgICAgb2xkTm9kZSA9IF9yZW1vdmVFeHRyYVNwYWNlKG9sZE5vZGUsIGZpcnN0Q2hpbGQpOyAvLyBSZW1vdmUgZXh0cmEgc3BhY2UgZnJvbSBsaXN0LgogICAgICAgICAgICAgICAgICAgIGZpcnN0Q2hpbGQgPSBfZ2V0VGV4dENoaWxkTm9kZShvbGROb2RlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3RDaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICBvbGROb2RlLnJlbW92ZUNoaWxkKGZpcnN0Q2hpbGQpOwogICAgICAgICAgICAgICAgICAgIH0gLy8gUmVtb3ZlIHRoZSBmaXJzdENoaWxkIHdoaWNoIGhvbGQgdGhlIEJ1bGxldCBvciBudW1iZXIgdHlwZQogICAgICAgICAgICAgICAgICAgIHdoaWxlIChvbGROb2RlLmZpcnN0Q2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RDaGlsZCA9IG9sZE5vZGUuZmlyc3RDaGlsZDsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSA9IF9jb252ZXJ0KGZpcnN0Q2hpbGQsIHRydWUsICJwIik7CiAgICAgICAgICAgICAgICAgICAgICAgIG9sZE5vZGUucmVtb3ZlQ2hpbGQoZmlyc3RDaGlsZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdOb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhRWxlbWVudC5hcHBlbmRDaGlsZChuZXdOb2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKHBhcmFFbGVtZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChjdXJyZW50TGlzdEVsZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGlzdEVsZW1lbnQuYXBwZW5kQ2hpbGQoZWxlbWVudCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGlzTmV3Q29udGFpbmVyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRMaXN0RWxlbWVudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICB2YXIgY3VycmVudExpc3RFbGVtZW50ID0gbnVsbDsKICAgIHZhciBsZXZlbExpc3RNYXAgPSB7fTsgLy8gVGhpcyBtYXAgd2lsbCBob2xkIHRoZSBDb250YWluZXIgKCBPTCBvciBVTCApIGZvciBlYWNoIGxldmVsICggbXVsdGktbGV2ZWwgbGlzdGluZykKICAgIHZhciBNU19MRVZFTDEgPSAibGV2ZWwxIjsKCiAgICBmdW5jdGlvbiBfc2V0Q3VycmVudExpc3RFbGVtZW50KG9sZE5vZGUpIHsKICAgICAgICBpZiAob2xkTm9kZSkgewogICAgICAgICAgICB2YXIgY29udGFpbmVyID0gX2NyZWF0ZUxpc3RDb250YWluZXIob2xkTm9kZSk7CiAgICAgICAgICAgIHZhciBsaXN0UHJvcGVydHkgPSBfZ2V0Q3VzdG9tQ3NzUHJvcGVydHkob2xkTm9kZSwgIm1zby1saXN0Iik7CiAgICAgICAgICAgIGxpc3RQcm9wZXJ0eSA9IGxpc3RQcm9wZXJ0eSA/IGxpc3RQcm9wZXJ0eS5zcGxpdCgiICIpIDogW107CiAgICAgICAgICAgIHZhciBsaXN0TGV2ZWwgPSBsaXN0UHJvcGVydHkgJiYgbGlzdFByb3BlcnR5Lmxlbmd0aCA+PSAyID8gbGlzdFByb3BlcnR5WzFdIDogTVNfTEVWRUwxOwogICAgICAgICAgICAvKiBDcmVhdGUgYSBPTCBvciBVTCBpbiBmb2xsb3dpbmcgY2FzZQogICAgICAgICAgICAgKiBhICAgIGlmIGN1cnJlbnRMaXN0RWxlbWVudCBpcyBub3QgZm91bmQgaW4gdGhlIG1hcCAoIGZpcnN0IExJKQogICAgICAgICAgICAgKiBiICAgIGVsc2UgaWYgYnVsbGV0IG9yIG51bWJlciB0eXBlIGlzIGNoYW5nZWQgaW4gbWlkZGxlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAobGV2ZWxMaXN0TWFwLmhhc093blByb3BlcnR5KGxpc3RMZXZlbCkpIHsvLyBjb250YWluZXIgaXMgYXZhaWxhYmxlIGluIGxldmVsTGlzdE1hcAogICAgICAgICAgICAgICAgY3VycmVudExpc3RFbGVtZW50ID0gbGV2ZWxMaXN0TWFwW2xpc3RMZXZlbF07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFjdXJyZW50TGlzdEVsZW1lbnQgfHwgKGNvbnRhaW5lciAmJiAoY3VycmVudExpc3RFbGVtZW50LnR5cGUgIT0gY29udGFpbmVyLnR5cGUgfHwgIWxldmVsTGlzdE1hcC5oYXNPd25Qcm9wZXJ0eShsaXN0TGV2ZWwpKSkpIHsgLy8gMm5kIGNvbmRpdGlvbiBpcyBpZiBsaXN0IHR5cGUgY2hhbmdlIG9yIGNvbXBvdW5kIGxpc3QgdGhlbiBjcmVhdGUgbmV3IGNvbnRhaW5lcgogICAgICAgICAgICAgICAgaWYgKE1TX0xFVkVMMSA9PSBsaXN0TGV2ZWwpIHsKICAgICAgICAgICAgICAgICAgICBsZXZlbExpc3RNYXAgPSB7fTsKICAgICAgICAgICAgICAgIH0gLy8gSWYgaXRzIGxldmVsIDEgdGhlbiByZXN0IHRoZSBNYXAKICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJlbnRMaXN0RWxlbWVudCAmJiBjdXJyZW50TGlzdEVsZW1lbnQubGFzdEVsZW1lbnRDaGlsZCkgey8vIGlmIG5leHQgbGV2ZWwgaXMgc3RhcnRpbmcgdGhlbiBhZGQgbmV3IGNvbnRhaW5lciB0byBwYXJlbnQgTGlzdCBjb250YWluZXIKICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGlzdEVsZW1lbnQubGFzdEVsZW1lbnRDaGlsZC5hcHBlbmRDaGlsZChjb250YWluZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGV2ZWxMaXN0TWFwW2xpc3RMZXZlbF0gPSBjb250YWluZXI7CiAgICAgICAgICAgICAgICBjdXJyZW50TGlzdEVsZW1lbnQgPSBjb250YWluZXI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKE1TX0xFVkVMMSA9PSBsaXN0TGV2ZWwpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9IC8vIHNlbmQgdHJ1ZSBpZiBmaXJzdCBsZXZlbCBjb250YWluZXIgaXMgYWRkZWQgYXMgaXQgbmVlZCB0byBiZSBhZGRlZCBpbiBET00gb3RoZXIgbGV2ZWwgY29udGFpbmVyIHdpbGwgYmUgZGlyZWN0bHkgYWRkZWQgdG8gcGFyZW50IGxpc3QgY29udGFpbmVyCiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBmdW5jdGlvbiBfY2xlYW5VcFdvcmRUb0hUTUxDYWNoZSgpIHsKICAgICAgICBsZXZlbExpc3RNYXAgPSB7fTsKICAgICAgICBjdXJyZW50TGlzdEVsZW1lbnQgPSBudWxsOwogICAgfQoKICAgIGZ1bmN0aW9uIF9jcmVhdGVMaXN0Q29udGFpbmVyKG9sZE5vZGUpIHsKICAgICAgICB2YXIgZWxlbWVudCA9IG51bGw7CiAgICAgICAgaWYgKG9sZE5vZGUpIHsKICAgICAgICAgICAgaWYgKC9Nc29MaXN0UGFyYWdyYXBoL2kudGVzdChvbGROb2RlLmNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgICAgIHZhciB0ZXh0Tm9kZSA9IF9nZXRUZXh0Q2hpbGROb2RlKG9sZE5vZGUpOwogICAgICAgICAgICAgICAgaWYgKHRleHROb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRDb250ZW50ID0gdGV4dE5vZGUudGV4dENvbnRlbnQgPyB0ZXh0Tm9kZS50ZXh0Q29udGVudC50cmltKCkgOiAiIjsKICAgICAgICAgICAgICAgICAgICB2YXIgc3BsaXRBcnJheSA9IHRleHRDb250ZW50LnNwbGl0KCIuIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKChzcGxpdEFycmF5Lmxlbmd0aCAtIDIpID49IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dENvbnRlbnQgPSBzcGxpdEFycmF5W3NwbGl0QXJyYXkubGVuZ3RoIC0gMl07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciB0eXBlID0gdGV4dENvbnRlbnQgPyBfZ2V0TGlzdENvbnRhaW5lclR5cGUodGV4dENvbnRlbnQpIDogbnVsbDsKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSkgey8vIENoZWNrIHR5cGUgb2YgY29udGVudCBpbiBmaXJzdFNwYW4gKCB3aGljaCBjb250YWlucyBidWxsZXQgb3IgbnVtYmVyIHR5cGUpCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50TmFtZSA9IC9kaXNjfGNpcmNsZXxzcXVhcmUvLnRlc3QodHlwZSkgPyAidWwiIDogIm9sIjsKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IG9sZE5vZGUub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KGVsZW1lbnROYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC50eXBlID0gdHlwZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugey8vIGlmIHR5cGUgaXMgbm90IHJlY29nbml6ZWQgdGhlbiBjcmVhdGVkIFVMIHdpdGggdHlwZSBkaXNjCiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidWwiKTsKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC50eXBlID0gImRpc2MiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH0KCiAgICBmdW5jdGlvbiBjaGVja0ZvckFscGhhYmV0TGlzdCh0ZXh0Q29udGVudCwgY3VycmVudExpc3RFbGVtZW50KSB7CiAgICAgICAgaWYgKGN1cnJlbnRMaXN0RWxlbWVudCAmJiAoY3VycmVudExpc3RFbGVtZW50LnR5cGUgPT0gImEiIHx8IGN1cnJlbnRMaXN0RWxlbWVudC50eXBlID09ICJBIikpIHsKICAgICAgICAgICAgdmFyIGFscGhhYmV0ID0gImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6IjsKICAgICAgICAgICAgdmFyIGNoYXJhY3RlckluQWxwaGFiZXRTZXQgPSBhbHBoYWJldC5jaGFyQXQoY3VycmVudExpc3RFbGVtZW50LmNoaWxkRWxlbWVudENvdW50KTsKICAgICAgICAgICAgaWYgKGN1cnJlbnRMaXN0RWxlbWVudC50eXBlID09ICJBIikgewogICAgICAgICAgICAgICAgY2hhcmFjdGVySW5BbHBoYWJldFNldCA9IGFscGhhYmV0LnRvVXBwZXJDYXNlKCkuY2hhckF0KGN1cnJlbnRMaXN0RWxlbWVudC5jaGlsZEVsZW1lbnRDb3VudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRleHRDb250ZW50ID09IGNoYXJhY3RlckluQWxwaGFiZXRTZXQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50TGlzdEVsZW1lbnQudHlwZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoY3VycmVudExpc3RFbGVtZW50ICYmIGN1cnJlbnRMaXN0RWxlbWVudC5wYXJlbnRFbGVtZW50ICYmIGN1cnJlbnRMaXN0RWxlbWVudC5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGNoZWNrRm9yQWxwaGFiZXRMaXN0KHRleHRDb250ZW50LCBjdXJyZW50TGlzdEVsZW1lbnQucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50KTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY2hlY2tGb3JOdW1lcmljTGlzdCh0ZXh0Q29udGVudCwgY3VycmVudExpc3RFbGVtZW50KSB7CiAgICAgICAgaWYgKGN1cnJlbnRMaXN0RWxlbWVudCAmJiAoY3VycmVudExpc3RFbGVtZW50LnR5cGUgPT0gIjEiKSkgewogICAgICAgICAgICB2YXIgY2hpbGRFbGVtZW50cyA9IGN1cnJlbnRMaXN0RWxlbWVudC5jaGlsZEVsZW1lbnRDb3VudDsKICAgICAgICAgICAgdmFyIGRlY2ltYWxWYWx1ZSA9IHBhcnNlSW50KHRleHRDb250ZW50KTsKICAgICAgICAgICAgaWYgKGNoaWxkRWxlbWVudHMgKyAxID09IGRlY2ltYWxWYWx1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRMaXN0RWxlbWVudC50eXBlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChjdXJyZW50TGlzdEVsZW1lbnQgJiYgY3VycmVudExpc3RFbGVtZW50LnBhcmVudEVsZW1lbnQgJiYgY3VycmVudExpc3RFbGVtZW50LnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudCkgewogICAgICAgICAgICByZXR1cm4gY2hlY2tGb3JOdW1lcmljTGlzdCh0ZXh0Q29udGVudCwgY3VycmVudExpc3RFbGVtZW50LnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudCk7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGNoZWNrRm9yUm9tYW5MaXN0KHRleHRDb250ZW50LCBjdXJyZW50TGlzdEVsZW1lbnQpIHsKICAgICAgICBpZiAoY3VycmVudExpc3RFbGVtZW50ICYmIChjdXJyZW50TGlzdEVsZW1lbnQudHlwZSA9PSAiaSIgfHwgY3VycmVudExpc3RFbGVtZW50LnR5cGUgPT0gIkkiKSkgewogICAgICAgICAgICB2YXIgY2hpbGRFbGVtZW50cyA9IGN1cnJlbnRMaXN0RWxlbWVudC5jaGlsZEVsZW1lbnRDb3VudDsKICAgICAgICAgICAgdmFyIHJvbWFuVmFsdWUgPSBfZ2V0Um9tYW5Ub0RlY2ltYWwodGV4dENvbnRlbnQpOwoKICAgICAgICAgICAgaWYgKGNoaWxkRWxlbWVudHMgKyAxID09IHJvbWFuVmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmICgodGV4dENvbnRlbnRbMF0udG9VcHBlckNhc2UoKSA9PSB0ZXh0Q29udGVudFswXSkgJiYgKGN1cnJlbnRMaXN0RWxlbWVudC50eXBlID09ICJJIikpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudExpc3RFbGVtZW50LnR5cGU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCh0ZXh0Q29udGVudFswXS50b0xvd2VyQ2FzZSgpID09IHRleHRDb250ZW50WzBdKSAmJiAoY3VycmVudExpc3RFbGVtZW50LnR5cGUgPT0gImkiKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50TGlzdEVsZW1lbnQudHlwZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoY3VycmVudExpc3RFbGVtZW50ICYmIGN1cnJlbnRMaXN0RWxlbWVudC5wYXJlbnRFbGVtZW50ICYmIGN1cnJlbnRMaXN0RWxlbWVudC5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGNoZWNrRm9yUm9tYW5MaXN0KHRleHRDb250ZW50LCBjdXJyZW50TGlzdEVsZW1lbnQucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50KTsKICAgICAgICB9CgogICAgfQoKICAgIGZ1bmN0aW9uIF9nZXRJbnRlZ2VyVmFsdWUocm9tYW5DaGFyKSB7CiAgICAgICAgdmFyIHJvbUFyciA9IFsiaSIsICJ2IiwgIngiLCAibCIsICJjIiwgImQiLCAibSJdOwogICAgICAgIHZhciBpbnRBcnIgPSBbMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMF07CiAgICAgICAgcmV0dXJuIGludEFycltyb21BcnIuaW5kZXhPZihyb21hbkNoYXIpXTsKICAgIH0KCiAgICBmdW5jdGlvbiBfZ2V0Um9tYW5Ub0RlY2ltYWwoc3RyKSB7CiAgICAgICAgdmFyIHJlcyA9IDAsIHJvbWFuRmlyc3RWYWwsIHJvbWFuU2Vjb25kVmFsOwogICAgICAgIHZhciBsb3dlclJvbWFuVHlwZVJlZyA9IC9ebXswLDR9KGNtfGNkfGQ/Y3swLDN9KSh4Y3x4bHxsP3h7MCwzfSkoaXh8aXZ8dj9pezAsM30pJC87CiAgICAgICAgaWYgKHN0ci50b0xvd2VyQ2FzZSgpLm1hdGNoKGxvd2VyUm9tYW5UeXBlUmVnKSkgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgcm9tYW5GaXJzdFZhbCA9IF9nZXRJbnRlZ2VyVmFsdWUoc3RyW2ldLnRvTG93ZXJDYXNlKCkpOwogICAgICAgICAgICAgICAgaWYgKGkgKyAxIDwgc3RyLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIHJvbWFuU2Vjb25kVmFsID0gX2dldEludGVnZXJWYWx1ZShzdHJbaSArIDFdLnRvTG93ZXJDYXNlKCkpOwogICAgICAgICAgICAgICAgICAgIGlmIChyb21hbkZpcnN0VmFsID49IHJvbWFuU2Vjb25kVmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcyA9IHJlcyArIHJvbWFuRmlyc3RWYWw7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzID0gcmVzICsgcm9tYW5TZWNvbmRWYWwgLSByb21hbkZpcnN0VmFsOwogICAgICAgICAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXMgPSByZXMgKyByb21hbkZpcnN0VmFsOwogICAgICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfZ2V0TGlzdENvbnRhaW5lclR5cGUodGV4dENvbnRlbnRTdHIpIHsKICAgICAgICB2YXIgZGVjaW1hbFR5cGVSZWcgPSAvXGQrLywKICAgICAgICAgICAgbG93ZXJSb21hblR5cGVSZWcgPSAvXm17MCw0fShjbXxjZHxkP2N7MCwzfSkoeGN8eGx8bD94ezAsM30pKGl4fGl2fHY/aXswLDN9KSQvLAogICAgICAgICAgICB1cHBlclJvbWFuVHlwZVJlZyA9IC9eTXswLDR9KENNfENEfEQ/Q3swLDN9KShYQ3xYTHxMP1h7MCwzfSkoSVh8SVZ8Vj9JezAsM30pJC8sCiAgICAgICAgICAgIGxvd2VyQWxwaGFUeXBlUmVnID0gL15bYS16XSskLywKICAgICAgICAgICAgdXBwZXJBbHBoYVR5cGVSZWcgPSAvXltBLVpdKyQvOwogICAgICAgIHZhciBkaXNjVHlwZVJlZyA9IC9bbFx1MDBCN1x1MjAwMl0vLAogICAgICAgICAgICBjaXJjbGVUeXBlUmVnID0gL1tcdTAwNkZcdTAwRDhdLywKICAgICAgICAgICAgc3F1YXJlVHlwZVJlZyA9IC9bXHUwMDZFXHUyNUM2XHUwMEE3XS87CgogICAgICAgIHZhciB2YWxpZEFscGhhYmV0ID0gZmFsc2UsIHZhbGlkUm9tYW4gPSBmYWxzZSwgdmFsaWRJbnRlZ2VyID0gZmFsc2U7CiAgICAgICAgaWYgKHRleHRDb250ZW50U3RyKSB7CiAgICAgICAgICAgIGlmICh0ZXh0Q29udGVudFN0ci50b0xvd2VyQ2FzZSgpLm1hdGNoKGxvd2VyUm9tYW5UeXBlUmVnKSkgewogICAgICAgICAgICAgICAgdmFsaWRSb21hbiA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRleHRDb250ZW50U3RyLnRvTG93ZXJDYXNlKCkubWF0Y2gobG93ZXJBbHBoYVR5cGVSZWcpKSB7CiAgICAgICAgICAgICAgICB2YWxpZEFscGhhYmV0ID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGV4dENvbnRlbnRTdHIubWF0Y2goZGVjaW1hbFR5cGVSZWcpKSB7CiAgICAgICAgICAgICAgICB2YWxpZEludGVnZXIgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB2YXIgcm9tYW5MaXN0ID0gdmFsaWRSb21hbiA/IGNoZWNrRm9yUm9tYW5MaXN0KHRleHRDb250ZW50U3RyLCBjdXJyZW50TGlzdEVsZW1lbnQpIDogbnVsbDsKICAgICAgICBpZiAocm9tYW5MaXN0KSB7CiAgICAgICAgICAgIHJldHVybiByb21hbkxpc3Q7CiAgICAgICAgfQoKICAgICAgICB2YXIgdGV4dENvbnRlbnQgPSB0ZXh0Q29udGVudFN0ci5zdWJzdHIoMCwgMSk7CiAgICAgICAgdmFyIGFscGhhTGlzdCA9IHZhbGlkQWxwaGFiZXQgPyBjaGVja0ZvckFscGhhYmV0TGlzdCh0ZXh0Q29udGVudCwgY3VycmVudExpc3RFbGVtZW50KSA6IG51bGw7CiAgICAgICAgaWYgKGFscGhhTGlzdCkgewogICAgICAgICAgICByZXR1cm4gYWxwaGFMaXN0OwogICAgICAgIH0KCiAgICAgICAgdmFyIG51bWVyaWNMaXN0ID0gdmFsaWRJbnRlZ2VyID8gY2hlY2tGb3JOdW1lcmljTGlzdCh0ZXh0Q29udGVudFN0ciwgY3VycmVudExpc3RFbGVtZW50KSA6IG51bGw7CiAgICAgICAgaWYgKG51bWVyaWNMaXN0KSB7CiAgICAgICAgICAgIHJldHVybiBudW1lcmljTGlzdDsKICAgICAgICB9CgogICAgICAgIGlmICh0ZXh0Q29udGVudFN0ciAmJiAodGV4dENvbnRlbnRTdHIgPT0gImEiIHx8IHRleHRDb250ZW50U3RyID09ICJBIiB8fCB0ZXh0Q29udGVudFN0ciA9PSAiaSIgfHwgdGV4dENvbnRlbnRTdHIgPT0gIkkiIHx8IHRleHRDb250ZW50U3RyID09ICIxIikpIHsKICAgICAgICAgICAgcmV0dXJuIHRleHRDb250ZW50U3RyOwogICAgICAgIH0gZWxzZSBpZiAodGV4dENvbnRlbnQubWF0Y2goZGlzY1R5cGVSZWcpKSB7CiAgICAgICAgICAgIHJldHVybiAiZGlzYyI7CiAgICAgICAgfSBlbHNlIGlmICh0ZXh0Q29udGVudC5tYXRjaChjaXJjbGVUeXBlUmVnKSkgewogICAgICAgICAgICByZXR1cm4gImNpcmNsZSI7CiAgICAgICAgfSBlbHNlIGlmICh0ZXh0Q29udGVudC5tYXRjaChzcXVhcmVUeXBlUmVnKSkgewogICAgICAgICAgICByZXR1cm4gInNxdWFyZSI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8vIEFjdGlvbiBvbiAgTVNPIExpc3Qgbm9kZSB3aGljaCBmaXJzdCB0ZXh0IG5vZGUgaGFzIGxpc3QgdHlwZSBpbmZvcm1hdGlvbi4KICAgIGZ1bmN0aW9uIF9nZXRUZXh0Q2hpbGROb2RlKG9sZE5vZGUpIHsKICAgICAgICBpZiAob2xkTm9kZSkgewogICAgICAgICAgICB2YXIgY2hpbGROb2RlcyA9IG9sZE5vZGUuY2hpbGROb2RlczsKICAgICAgICAgICAgdmFyIHRleHRDb250ZW50LCBjaGlsZE5vZGU7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgY2hpbGROb2RlID0gY2hpbGROb2Rlc1tpXTsKICAgICAgICAgICAgICAgIHRleHRDb250ZW50ID0gY2hpbGROb2RlLnRleHRDb250ZW50ID8gY2hpbGROb2RlLnRleHRDb250ZW50LnRyaW0oKSA6ICIiOwogICAgICAgICAgICAgICAgaWYgKGNoaWxkTm9kZSAmJiAoY2hpbGROb2RlLm5vZGVUeXBlID09IDMgfHwgY2hpbGROb2RlLm5vZGVUeXBlID09IDEpICYmIHRleHRDb250ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkTm9kZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfaXNNU29MaXN0UGFyYWdyYXBoQ2hpbGQob2xkTm9kZSkgewogICAgICAgIC8vIFNpbmNlIGVhY2ggYW5kIHZlcnkgZWxlbWVudCBpcyBwYXNzZWQgd2h5IHBhcnNlciBjaGVjayBpZiBhbnkgZWxlbWVudCBpcyBwYXJ0IG9mIE1zb0xpc3RQYXJhZ3JhcGggaWYgc28gaWdub3JlIGl0IGFzIGl0cyBhbHJlYWR5IGhhbmRsZSB2aWEgY3JlYXRpbmcgTEkKICAgICAgICBpZiAob2xkTm9kZSkgewogICAgICAgICAgICBpZiAoL01zb0xpc3RQYXJhZ3JhcGgvaS50ZXN0KG9sZE5vZGUuY2xhc3NOYW1lKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIGZ1bmN0aW9uIF9nZXRDdXN0b21Dc3NQcm9wZXJ0eShlbGVtZW50LCBwcm9wZXJ0eU5hbWUpIHsKICAgICAgICBpZiAoZWxlbWVudCkgewogICAgICAgICAgICB2YXIgc3R5bGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgic3R5bGUiKTsKICAgICAgICAgICAgdmFyIGVudHJpZXMgPSBzdHlsZS5zcGxpdCgiOyIpOwoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7CiAgICAgICAgICAgICAgICAgaSA8IGVudHJpZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgdmFyIGVudHJ5ID0gZW50cmllc1tpXS5zcGxpdCgiOiIpOwogICAgICAgICAgICAgICAgaWYgKGVudHJ5WzBdID09IHByb3BlcnR5TmFtZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBlbnRyeVsxXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIElFIGdpdmVzIHdyb25nIHJlc3VsdHMgZm9yIGhhc0F0dHJpYnV0ZS9nZXRBdHRyaWJ1dGUsIGZvciBleGFtcGxlOgogICAgICogICAgdmFyIHRkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGQiKTsKICAgICAqICAgIHRkLmdldEF0dHJpYnV0ZSgicm93c3BhbiIpOyAvLyA9PiAiMSIgaW4gSUUKICAgICAqCiAgICAgKiBUaGVyZWZvcmUgd2UgaGF2ZSB0byBjaGVjayB0aGUgZWxlbWVudCdzIG91dGVySFRNTCBmb3IgdGhlIGF0dHJpYnV0ZQogICAgICovCiAgICB2YXIgSEFTX0dFVF9BVFRSSUJVVEVfQlVHID0gIXd5c2lodG1sNS5icm93c2VyLnN1cHBvcnRzR2V0QXR0cmlidXRlQ29ycmVjdGx5KCk7CgogICAgZnVuY3Rpb24gX2dldEF0dHJpYnV0ZShub2RlLCBhdHRyaWJ1dGVOYW1lKSB7CiAgICAgICAgYXR0cmlidXRlTmFtZSA9IGF0dHJpYnV0ZU5hbWUudG9Mb3dlckNhc2UoKTsKICAgICAgICB2YXIgbm9kZU5hbWUgPSBub2RlLm5vZGVOYW1lOwogICAgICAgIGlmIChub2RlTmFtZSA9PSAiSU1HIiAmJiBhdHRyaWJ1dGVOYW1lID09ICJzcmMiICYmIF9pc0xvYWRlZEltYWdlKG5vZGUpID09PSB0cnVlKSB7CiAgICAgICAgICAgIC8vIEdldCAnc3JjJyBhdHRyaWJ1dGUgdmFsdWUgdmlhIG9iamVjdCBwcm9wZXJ0eSBzaW5jZSB0aGlzIHdpbGwgYWx3YXlzIGNvbnRhaW4gdGhlCiAgICAgICAgICAgIC8vIGZ1bGwgYWJzb2x1dGUgdXJsIChodHRwOi8vLi4uKQogICAgICAgICAgICAvLyB0aGlzIGZpeGVzIGEgdmVyeSBhbm5veWluZyBidWcgaW4gZmlyZWZveCAodmVyIDMuNiAmIDQpIGFuZCBJRSA4IHdoZXJlIGltYWdlcyBjb3BpZWQgZnJvbSB0aGUgc2FtZSBob3N0CiAgICAgICAgICAgIC8vIHdpbGwgaGF2ZSByZWxhdGl2ZSBwYXRocywgd2hpY2ggdGhlIHNhbml0aXplciBzdHJpcHMgb3V0IChzZWUgYXR0cmlidXRlQ2hlY2tNZXRob2RzLnVybCkKICAgICAgICAgICAgcmV0dXJuIG5vZGUuc3JjOwogICAgICAgIH0gZWxzZSBpZiAoSEFTX0dFVF9BVFRSSUJVVEVfQlVHICYmICJvdXRlckhUTUwiIGluIG5vZGUpIHsKICAgICAgICAgICAgLy8gRG9uJ3QgdHJ1c3QgZ2V0QXR0cmlidXRlL2hhc0F0dHJpYnV0ZSBpbiBJRSA2LTgsIGluc3RlYWQgY2hlY2sgdGhlIGVsZW1lbnQncyBvdXRlckhUTUwKICAgICAgICAgICAgdmFyIG91dGVySFRNTCA9IG5vZGUub3V0ZXJIVE1MLnRvTG93ZXJDYXNlKCksCiAgICAgICAgICAgICAgICAvLyBUT0RPOiBUaGlzIG1pZ2h0IG5vdCB3b3JrIGZvciBhdHRyaWJ1dGVzIHdpdGhvdXQgdmFsdWU6IDxpbnB1dCBkaXNhYmxlZD4KICAgICAgICAgICAgICAgIGhhc0F0dHJpYnV0ZSA9IG91dGVySFRNTC5pbmRleE9mKCIgIiArIGF0dHJpYnV0ZU5hbWUgKyAiPSIpICE9IC0xOwoKICAgICAgICAgICAgcmV0dXJuIGhhc0F0dHJpYnV0ZSA/IG5vZGUuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUpIDogbnVsbDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbm9kZS5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgd2hldGhlciB0aGUgZ2l2ZW4gbm9kZSBpcyBhIHByb3BlciBsb2FkZWQgaW1hZ2UKICAgICAqIEZJWE1FOiBSZXR1cm5zIHVuZGVmaW5lZCB3aGVuIHVua25vd24gKENocm9tZSwgU2FmYXJpKQogICAgICovCiAgICBmdW5jdGlvbiBfaXNMb2FkZWRJbWFnZShub2RlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIG5vZGUuY29tcGxldGUgJiYgIW5vZGUubW96TWF0Y2hlc1NlbGVjdG9yKCI6LW1vei1icm9rZW4iKTsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIGlmIChub2RlLmNvbXBsZXRlICYmIG5vZGUucmVhZHlTdGF0ZSA9PT0gImNvbXBsZXRlIikgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gX2hhbmRsZVRleHQob2xkTm9kZSkgewogICAgICAgIHJldHVybiBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUob2xkTm9kZS5kYXRhKTsKICAgIH0KCiAgICAvLyAtLS0tLS0tLS0tLS0gYXR0cmlidXRlIGNoZWNrcyAtLS0tLS0tLS0tLS0gXFwKICAgIHZhciBhdHRyaWJ1dGVDaGVja01ldGhvZHMgPSB7CiAgICAgICAgYW55IDogKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChhdHRyaWJ1dGVWYWx1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZVZhbHVlOwogICAgICAgICAgICB9OwogICAgICAgIH0pKCksCgogICAgICAgIHVybCA6IChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBSRUdfRVhQID0gL15odHRwcz86XC9cLy9pOwogICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZVZhbHVlIHx8ICFhdHRyaWJ1dGVWYWx1ZS5tYXRjaChSRUdfRVhQKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoUkVHX0VYUCwgZnVuY3Rpb24gKG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfTsKICAgICAgICB9KSgpLAoKICAgICAgICBzcmMgOiAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgUkVHX0VYUCA9IC9eKFwvfGh0dHBzPzpcL1wvKS9pOwogICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZVZhbHVlIHx8ICFhdHRyaWJ1dGVWYWx1ZS5tYXRjaChSRUdfRVhQKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoUkVHX0VYUCwgZnVuY3Rpb24gKG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfTsKICAgICAgICB9KSgpLAoKICAgICAgICBocmVmIDogKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIFJFR19FWFAgPSAvXihcL3xodHRwcz86XC9cL3xtYWlsdG86KS9pOwogICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZVZhbHVlIHx8ICFhdHRyaWJ1dGVWYWx1ZS5tYXRjaChSRUdfRVhQKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoUkVHX0VYUCwgZnVuY3Rpb24gKG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfTsKICAgICAgICB9KSgpLAoKICAgICAgICBhbHQgOiAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgUkVHX0VYUCA9IC9bXiBhLXowLTlfXC1dL2dpOwogICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoUkVHX0VYUCwgIiIpOwogICAgICAgICAgICB9OwogICAgICAgIH0pKCksCgogICAgICAgIG51bWJlcnMgOiAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgUkVHX0VYUCA9IC9cRC9nOwogICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVWYWx1ZSA9IChhdHRyaWJ1dGVWYWx1ZSB8fCAiIikucmVwbGFjZShSRUdfRVhQLCAiIik7CiAgICAgICAgICAgICAgICByZXR1cm4gYXR0cmlidXRlVmFsdWUgfHwgbnVsbDsKICAgICAgICAgICAgfTsKICAgICAgICB9KSgpCiAgICB9OwoKICAgIC8vIC0tLS0tLS0tLS0tLSBjbGFzcyBjb252ZXJ0ZXIgKGNvbnZlcnRzIGFuIGh0bWwgYXR0cmlidXRlIHRvIGEgY2xhc3MgbmFtZSkgLS0tLS0tLS0tLS0tIFxcCiAgICB2YXIgYWRkQ2xhc3NNZXRob2RzID0gewogICAgICAgIGFsaWduX2ltZyA6IChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBtYXBwaW5nID0gewogICAgICAgICAgICAgICAgbGVmdCA6ICJ3eXNpd3lnLWZsb2F0LWxlZnQiLAogICAgICAgICAgICAgICAgcmlnaHQgOiAid3lzaXd5Zy1mbG9hdC1yaWdodCIKICAgICAgICAgICAgfTsKICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChhdHRyaWJ1dGVWYWx1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG1hcHBpbmdbU3RyaW5nKGF0dHJpYnV0ZVZhbHVlKS50b0xvd2VyQ2FzZSgpXTsKICAgICAgICAgICAgfTsKICAgICAgICB9KSgpLAoKICAgICAgICBhbGlnbl90ZXh0IDogKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIG1hcHBpbmcgPSB7CiAgICAgICAgICAgICAgICBsZWZ0IDogInd5c2l3eWctdGV4dC1hbGlnbi1sZWZ0IiwKICAgICAgICAgICAgICAgIHJpZ2h0IDogInd5c2l3eWctdGV4dC1hbGlnbi1yaWdodCIsCiAgICAgICAgICAgICAgICBjZW50ZXIgOiAid3lzaXd5Zy10ZXh0LWFsaWduLWNlbnRlciIsCiAgICAgICAgICAgICAgICBqdXN0aWZ5IDogInd5c2l3eWctdGV4dC1hbGlnbi1qdXN0aWZ5IgogICAgICAgICAgICB9OwogICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbWFwcGluZ1tTdHJpbmcoYXR0cmlidXRlVmFsdWUpLnRvTG93ZXJDYXNlKCldOwogICAgICAgICAgICB9OwogICAgICAgIH0pKCksCgogICAgICAgIGNsZWFyX2JyIDogKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIG1hcHBpbmcgPSB7CiAgICAgICAgICAgICAgICBsZWZ0IDogInd5c2l3eWctY2xlYXItbGVmdCIsCiAgICAgICAgICAgICAgICByaWdodCA6ICJ3eXNpd3lnLWNsZWFyLXJpZ2h0IiwKICAgICAgICAgICAgICAgIGJvdGggOiAid3lzaXd5Zy1jbGVhci1ib3RoIiwKICAgICAgICAgICAgICAgIGFsbCA6ICJ3eXNpd3lnLWNsZWFyLWJvdGgiCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoYXR0cmlidXRlVmFsdWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBtYXBwaW5nW1N0cmluZyhhdHRyaWJ1dGVWYWx1ZSkudG9Mb3dlckNhc2UoKV07CiAgICAgICAgICAgIH07CiAgICAgICAgfSkoKSwKCiAgICAgICAgc2l6ZV9mb250IDogKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIG1hcHBpbmcgPSB7CiAgICAgICAgICAgICAgICAiMSIgOiAid3lzaXd5Zy1mb250LXNpemUteHgtc21hbGwiLAogICAgICAgICAgICAgICAgIjIiIDogInd5c2l3eWctZm9udC1zaXplLXNtYWxsIiwKICAgICAgICAgICAgICAgICIzIiA6ICJ3eXNpd3lnLWZvbnQtc2l6ZS1tZWRpdW0iLAogICAgICAgICAgICAgICAgIjQiIDogInd5c2l3eWctZm9udC1zaXplLWxhcmdlIiwKICAgICAgICAgICAgICAgICI1IiA6ICJ3eXNpd3lnLWZvbnQtc2l6ZS14LWxhcmdlIiwKICAgICAgICAgICAgICAgICI2IiA6ICJ3eXNpd3lnLWZvbnQtc2l6ZS14eC1sYXJnZSIsCiAgICAgICAgICAgICAgICAiNyIgOiAid3lzaXd5Zy1mb250LXNpemUteHgtbGFyZ2UiLAogICAgICAgICAgICAgICAgIi0iIDogInd5c2l3eWctZm9udC1zaXplLXNtYWxsZXIiLAogICAgICAgICAgICAgICAgIisiIDogInd5c2l3eWctZm9udC1zaXplLWxhcmdlciIKICAgICAgICAgICAgfTsKICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChhdHRyaWJ1dGVWYWx1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG1hcHBpbmdbU3RyaW5nKGF0dHJpYnV0ZVZhbHVlKS5jaGFyQXQoMCldOwogICAgICAgICAgICB9OwogICAgICAgIH0pKCkKICAgIH07CgogICAgcmV0dXJuIHBhcnNlOwp9KSgpOwovKioKICogQ2hlY2tzIGZvciBlbXB0eSB0ZXh0IG5vZGUgY2hpbGRzIGFuZCByZW1vdmVzIHRoZW0KICoKICogQHBhcmFtIHtFbGVtZW50fSBub2RlIFRoZSBlbGVtZW50IGluIHdoaWNoIHRvIGNsZWFudXAKICogQGV4YW1wbGUKICogICAgd3lzaWh0bWw1LmRvbS5yZW1vdmVFbXB0eVRleHROb2RlcyhlbGVtZW50KTsKICovCnd5c2lodG1sNS5kb20ucmVtb3ZlRW1wdHlUZXh0Tm9kZXMgPSBmdW5jdGlvbiAobm9kZSkgewogICAgdmFyIGNoaWxkTm9kZSwKICAgICAgICBjaGlsZE5vZGVzID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkobm9kZS5jaGlsZE5vZGVzKS5nZXQoKSwKICAgICAgICBjaGlsZE5vZGVzTGVuZ3RoID0gY2hpbGROb2Rlcy5sZW5ndGgsCiAgICAgICAgaSA9IDA7CiAgICBmb3IgKDsKICAgICAgICBpIDwgY2hpbGROb2Rlc0xlbmd0aDsKICAgICAgICBpKyspIHsKICAgICAgICBjaGlsZE5vZGUgPSBjaGlsZE5vZGVzW2ldOwogICAgICAgIGlmIChjaGlsZE5vZGUubm9kZVR5cGUgPT09IHd5c2lodG1sNS5URVhUX05PREUgJiYgY2hpbGROb2RlLmRhdGEgPT09ICIiKSB7CiAgICAgICAgICAgIGNoaWxkTm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGNoaWxkTm9kZSk7CiAgICAgICAgfQogICAgfQp9OwovKioKICogUmVuYW1lcyBhbiBlbGVtZW50IChlZy4gYSA8ZGl2PiB0byBhIDxwPikgYW5kIGtlZXBzIGl0cyBjaGlsZHMKICoKICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IFRoZSBsaXN0IGVsZW1lbnQgd2hpY2ggc2hvdWxkIGJlIHJlbmFtZWQKICogQHBhcmFtIHtFbGVtZW50fSBuZXdOb2RlTmFtZSBUaGUgZGVzaXJlZCB0YWcgbmFtZQogKgogKiBAZXhhbXBsZQogKiAgICA8IS0tIEFzc3VtZSB0aGUgZm9sbG93aW5nIGRvbTogLS0+CiAqICAgIDx1bCBpZD0ibGlzdCI+CiAqICAgICAgPGxpPmVtaW5lbTwvbGk+CiAqICAgICAgPGxpPmRyLiBkcmU8L2xpPgogKiAgICAgIDxsaT41MCBDZW50PC9saT4KICogICAgPC91bD4KICoKICogICAgPHNjcmlwdD4KICogICAgICB3eXNpaHRtbDUuZG9tLnJlbmFtZUVsZW1lbnQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImxpc3QiKSwgIm9sIik7CiAqICAgIDwvc2NyaXB0PgogKgogKiAgICA8IS0tIFdpbGwgcmVzdWx0IGluOiAtLT4KICogICAgPG9sPgogKiAgICAgIDxsaT5lbWluZW08L2xpPgogKiAgICAgIDxsaT5kci4gZHJlPC9saT4KICogICAgICA8bGk+NTAgQ2VudDwvbGk+CiAqICAgIDwvb2w+CiAqLwp3eXNpaHRtbDUuZG9tLnJlbmFtZUVsZW1lbnQgPSBmdW5jdGlvbiAoZWxlbWVudCwgbmV3Tm9kZU5hbWUpIHsKICAgIHZhciBuZXdFbGVtZW50ID0gZWxlbWVudC5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQobmV3Tm9kZU5hbWUpLAogICAgICAgIGZpcnN0Q2hpbGQ7CiAgICB3aGlsZSAoZmlyc3RDaGlsZCA9IGVsZW1lbnQuZmlyc3RDaGlsZCkgewogICAgICAgIG5ld0VsZW1lbnQuYXBwZW5kQ2hpbGQoZmlyc3RDaGlsZCk7CiAgICB9CiAgICB3eXNpaHRtbDUuZG9tLmNvcHlBdHRyaWJ1dGVzKFsiYWxpZ24iLCAiY2xhc3NOYW1lIl0pLmZyb20oZWxlbWVudCkudG8obmV3RWxlbWVudCk7CiAgICAvL3d5c2lodG1sNS5kb20uY29weVN0eWxlcyhbImxpbmUtaGVpZ2h0Il0pLmZyb20oZWxlbWVudCkudG8obmV3RWxlbWVudCk7CiAgICBlbGVtZW50LnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG5ld0VsZW1lbnQsIGVsZW1lbnQpOwogICAgcmV0dXJuIG5ld0VsZW1lbnQ7Cn07Ci8qKgogKiBUYWtlcyBhbiBlbGVtZW50LCByZW1vdmVzIGl0IGFuZCByZXBsYWNlcyBpdCB3aXRoIGl0J3MgY2hpbGRzCiAqCiAqIEBwYXJhbSB7T2JqZWN0fSBub2RlIFRoZSBub2RlIHdoaWNoIHRvIHJlcGxhY2Ugd2l0aCBpdCdzIGNoaWxkIG5vZGVzCiAqIEBleGFtcGxlCiAqICAgIDxkaXYgaWQ9ImZvbyI+CiAqICAgICAgPHNwYW4+aGVsbG88L3NwYW4+CiAqICAgIDwvZGl2PgogKiAgICA8c2NyaXB0PgogKiAgICAgIC8vIFJlbW92ZSAjZm9vIGFuZCByZXBsYWNlIHdpdGggaXQncyBjaGlsZHJlbgogKiAgICAgIHd5c2lodG1sNS5kb20ucmVwbGFjZVdpdGhDaGlsZE5vZGVzKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJmb28iKSk7CiAqICAgIDwvc2NyaXB0PgogKi8Kd3lzaWh0bWw1LmRvbS5yZXBsYWNlV2l0aENoaWxkTm9kZXMgPSBmdW5jdGlvbiAobm9kZSkgewogICAgaWYgKCFub2RlLnBhcmVudE5vZGUpIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCFub2RlLmZpcnN0Q2hpbGQpIHsKICAgICAgICBub2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIHZhciBmcmFnbWVudCA9IG5vZGUub3duZXJEb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CiAgICB3aGlsZSAobm9kZS5maXJzdENoaWxkKSB7CiAgICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQobm9kZS5maXJzdENoaWxkKTsKICAgIH0KICAgIG5vZGUucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoZnJhZ21lbnQsIG5vZGUpOwogICAgbm9kZSA9IGZyYWdtZW50ID0gbnVsbDsKfTsKLyoqCiAqIFVud3JhcHMgYW4gdW5vcmRlcmVkL29yZGVyZWQgbGlzdAogKgogKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgVGhlIGxpc3QgZWxlbWVudCB3aGljaCBzaG91bGQgYmUgdW53cmFwcGVkCiAqCiAqIEBleGFtcGxlCiAqICAgIDwhLS0gQXNzdW1lIHRoZSBmb2xsb3dpbmcgZG9tOiAtLT4KICogICAgPHVsIGlkPSJsaXN0Ij4KICogICAgICA8bGk+ZW1pbmVtPC9saT4KICogICAgICA8bGk+ZHIuIGRyZTwvbGk+CiAqICAgICAgPGxpPjUwIENlbnQ8L2xpPgogKiAgICA8L3VsPgogKgogKiAgICA8c2NyaXB0PgogKiAgICAgIHd5c2lodG1sNS5kb20ucmVzb2x2ZUxpc3QoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImxpc3QiKSk7CiAqICAgIDwvc2NyaXB0PgogKgogKiAgICA8IS0tIFdpbGwgcmVzdWx0IGluOiAtLT4KICogICAgZW1pbmVtPGJyPgogKiAgICBkci4gZHJlPGJyPgogKiAgICA1MCBDZW50PGJyPgogKi8KKGZ1bmN0aW9uIChkb20pIHsKICAgIGZ1bmN0aW9uIF9pc0Jsb2NrRWxlbWVudChub2RlKSB7CiAgICAgICAgcmV0dXJuIGRvbS5nZXRTdHlsZSgiZGlzcGxheSIpLmZyb20obm9kZSkgPT09ICJibG9jayI7CiAgICB9CgogICAgZnVuY3Rpb24gX2lzTGluZUJyZWFrKG5vZGUpIHsKICAgICAgICByZXR1cm4gbm9kZS5ub2RlTmFtZSA9PT0gIkJSIjsKICAgIH0KCiAgICBmdW5jdGlvbiBfYXBwZW5kTGluZUJyZWFrKGVsZW1lbnQpIHsKICAgICAgICB2YXIgbGluZUJyZWFrID0gZWxlbWVudC5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImJyIik7CiAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChsaW5lQnJlYWspOwogICAgfQoKICAgIGZ1bmN0aW9uIHJlc29sdmVMaXN0KGxpc3QsIHVzZUxpbmVCcmVha3MpIHsKICAgICAgICBpZiAoIWxpc3Qubm9kZU5hbWUubWF0Y2goL14oTUVOVXxVTHxPTCkkLykpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdmFyIGRvYyA9IGxpc3Qub3duZXJEb2N1bWVudCwKICAgICAgICAgICAgZnJhZ21lbnQgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLAogICAgICAgICAgICBwcmV2aW91c1NpYmxpbmcgPSBsaXN0LnByZXZpb3VzRWxlbWVudFNpYmxpbmcgfHwgbGlzdC5wcmV2aW91c1NpYmxpbmcsCiAgICAgICAgICAgIGZpcnN0Q2hpbGQsCiAgICAgICAgICAgIGxhc3RDaGlsZCwKICAgICAgICAgICAgaXNMYXN0Q2hpbGQsCiAgICAgICAgICAgIHNob3VsZEFwcGVuZExpbmVCcmVhaywKICAgICAgICAgICAgcGFyYWdyYXBoLAogICAgICAgICAgICBsaXN0SXRlbTsKCiAgICAgICAgaWYgKHVzZUxpbmVCcmVha3MpIHsKICAgICAgICAgICAgLy8gSW5zZXJ0IGxpbmUgYnJlYWsgaWYgbGlzdCBpcyBhZnRlciBhIG5vbi1ibG9jayBlbGVtZW50CiAgICAgICAgICAgIGlmIChwcmV2aW91c1NpYmxpbmcgJiYgIV9pc0Jsb2NrRWxlbWVudChwcmV2aW91c1NpYmxpbmcpKSB7CiAgICAgICAgICAgICAgICBfYXBwZW5kTGluZUJyZWFrKGZyYWdtZW50KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgd2hpbGUgKGxpc3RJdGVtID0gKGxpc3QuZmlyc3RFbGVtZW50Q2hpbGQgfHwgbGlzdC5maXJzdENoaWxkKSkgewogICAgICAgICAgICAgICAgbGFzdENoaWxkID0gbGlzdEl0ZW0ubGFzdENoaWxkOwogICAgICAgICAgICAgICAgd2hpbGUgKGZpcnN0Q2hpbGQgPSBsaXN0SXRlbS5maXJzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgaXNMYXN0Q2hpbGQgPSBmaXJzdENoaWxkID09PSBsYXN0Q2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBuZWVkcyB0byBiZSBkb25lIGJlZm9yZSBhcHBlbmRpbmcgaXQgdG8gdGhlIGZyYWdtZW50LCBhcyBpdCBvdGhlcndpc2Ugd2lsbCBsb3NlIHN0eWxlIGluZm9ybWF0aW9uCiAgICAgICAgICAgICAgICAgICAgc2hvdWxkQXBwZW5kTGluZUJyZWFrID0gaXNMYXN0Q2hpbGQgJiYgIV9pc0Jsb2NrRWxlbWVudChmaXJzdENoaWxkKSAmJiAhX2lzTGluZUJyZWFrKGZpcnN0Q2hpbGQpOwogICAgICAgICAgICAgICAgICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKGZpcnN0Q2hpbGQpOwogICAgICAgICAgICAgICAgICAgIGlmIChzaG91bGRBcHBlbmRMaW5lQnJlYWspIHsKICAgICAgICAgICAgICAgICAgICAgICAgX2FwcGVuZExpbmVCcmVhayhmcmFnbWVudCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGxpc3RJdGVtLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobGlzdEl0ZW0pOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgd2hpbGUgKGxpc3RJdGVtID0gKGxpc3QuZmlyc3RFbGVtZW50Q2hpbGQgfHwgbGlzdC5maXJzdENoaWxkKSkgewogICAgICAgICAgICAgICAgaWYgKGxpc3RJdGVtLnF1ZXJ5U2VsZWN0b3IgJiYgbGlzdEl0ZW0ucXVlcnlTZWxlY3RvcigiZGl2LCBwLCB1bCwgb2wsIG1lbnUsIGJsb2NrcXVvdGUsIGgxLCBoMiwgaDMsIGg0LCBoNSwgaDYiKSkgewogICAgICAgICAgICAgICAgICAgIHdoaWxlIChmaXJzdENoaWxkID0gbGlzdEl0ZW0uZmlyc3RDaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChmaXJzdENoaWxkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHBhcmFncmFwaCA9IGRvYy5jcmVhdGVFbGVtZW50KCJwIik7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGZpcnN0Q2hpbGQgPSBsaXN0SXRlbS5maXJzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFncmFwaC5hcHBlbmRDaGlsZChmaXJzdENoaWxkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQocGFyYWdyYXBoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxpc3RJdGVtLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobGlzdEl0ZW0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBsaXN0LnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGZyYWdtZW50LCBsaXN0KTsKICAgIH0KCiAgICBkb20ucmVzb2x2ZUxpc3QgPSByZXNvbHZlTGlzdDsKfSkod3lzaWh0bWw1LmRvbSk7Ci8qKgogKiBTYW5kYm94IGZvciBleGVjdXRpbmcgamF2YXNjcmlwdCwgcGFyc2luZyBjc3Mgc3R5bGVzIGFuZCBkb2luZyBkb20gb3BlcmF0aW9ucyBpbiBhIHNlY3VyZSB3YXkKICoKICogQnJvd3NlciBDb21wYXRpYmlsaXR5OgogKiAgLSBTZWN1cmUgaW4gTVNJRSA2KywgYnV0IG9ubHkgd2hlbiB0aGUgdXNlciBoYXNuJ3QgbWFkZSBjaGFuZ2VzIHRvIGhpcyBzZWN1cml0eSBsZXZlbCAicmVzdHJpY3RlZCIKICogIC0gUGFydGlhbGx5IHNlY3VyZSBpbiBvdGhlciBicm93c2VycyAoRmlyZWZveCwgT3BlcmEsIFNhZmFyaSwgQ2hyb21lLCAuLi4pCiAqCiAqIFBsZWFzZSBub3RlIHRoYXQgdGhpcyBjbGFzcyBjYW4ndCBiZW5lZml0IGZyb20gdGhlIEhUTUw1IHNhbmRib3ggYXR0cmlidXRlIGZvciB0aGUgZm9sbG93aW5nIHJlYXNvbnM6CiAqICAgIC0gc2FuZGJveGluZyBkb2Vzbid0IHdvcmsgY29ycmVjdGx5IHdpdGggaW5saW5lZCBjb250ZW50IChzcmM9ImphdmFzY3JpcHQ6JzxodG1sPi4uLjwvaHRtbD4nIikKICogICAgLSBzYW5kYm94aW5nIG9mIHBoeXNpY2FsIGRvY3VtZW50cyBjYXVzZXMgdGhhdCB0aGUgZG9tIGlzbid0IGFjY2Vzc2libGUgYW55bW9yZSBmcm9tIHRoZSBvdXRzaWRlIChpZnJhbWUuY29udGVudFdpbmRvdywgLi4uKQogKiAgICAtIHNldHRpbmcgdGhlICJhbGxvdy1zYW1lLW9yaWdpbiIgZmxhZyB3b3VsZCBmaXggdGhhdCwgYnV0IHRoZW4gc3RpbGwgamF2YXNjcmlwdCBhbmQgZG9tIGV2ZW50cyByZWZ1c2UgdG8gZmlyZQogKiAgICAtIHRoZXJlZm9yZSB0aGUgImFsbG93LXNjcmlwdHMiIGZsYWcgaXMgbmVlZGVkLCB3aGljaCB0aGVuIHdvdWxkIGRlYWN0aXZhdGUgYW55IHNlY3VyaXR5LCBhcyB0aGUganMgZXhlY3V0ZWQgaW5zaWRlIHRoZSBpZnJhbWUKICogICAgICBjYW4gZG8gYW55dGhpbmcgYXMgaWYgdGhlIHNhbmRib3ggYXR0cmlidXRlIHdhc24ndCBzZXQKICoKICogQHBhcmFtIHtGdW5jdGlvbn0gW3JlYWR5Q2FsbGJhY2tdIE1ldGhvZCB0aGF0IGdldHMgaW52b2tlZCB3aGVuIHRoZSBzYW5kYm94IGlzIHJlYWR5CiAqIEBwYXJhbSB7T2JqZWN0fSBbY29uZmlnXSBPcHRpb25hbCBwYXJhbWV0ZXJzCiAqCiAqIEBleGFtcGxlCiAqICAgIG5ldyB3eXNpaHRtbDUuZG9tLlNhbmRib3goZnVuY3Rpb24oc2FuZGJveCkgewogKiAgICAgIHNhbmRib3guZ2V0V2luZG93KCkuZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPSAnPGltZyBzcmM9Zm9vLmdpZiBvbmVycm9yPSJhbGVydChkb2N1bWVudC5jb29raWUpIj4nOwogKiAgICB9KTsKICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgLyoqCiAgICAgICAgICogRGVmYXVsdCBjb25maWd1cmF0aW9uCiAgICAgICAgICovCiAgICAgICAgZG9jID0gZG9jdW1lbnQsCiAgICAgICAgLyoqCiAgICAgICAgICogUHJvcGVydGllcyB0byB1bnNldC9wcm90ZWN0IG9uIHRoZSB3aW5kb3cgb2JqZWN0CiAgICAgICAgICovCiAgICAgICAgd2luZG93UHJvcGVydGllcyA9IFsKICAgICAgICAgICAgInBhcmVudCIsICJ0b3AiLCAib3BlbmVyIiwgImZyYW1lRWxlbWVudCIsICJmcmFtZXMiLAogICAgICAgICAgICAibG9jYWxTdG9yYWdlIiwgImdsb2JhbFN0b3JhZ2UiLCAic2Vzc2lvblN0b3JhZ2UiLCAiaW5kZXhlZERCIgogICAgICAgIF0sCiAgICAgICAgLyoqCiAgICAgICAgICogUHJvcGVydGllcyBvbiB0aGUgd2luZG93IG9iamVjdCB3aGljaCBhcmUgc2V0IHRvIGFuIGVtcHR5IGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgd2luZG93UHJvcGVydGllczIgPSBbCiAgICAgICAgICAgICJvcGVuIiwgImNsb3NlIiwgIm9wZW5EaWFsb2ciLCAic2hvd01vZGFsRGlhbG9nIiwKICAgICAgICAgICAgImFsZXJ0IiwgImNvbmZpcm0iLCAicHJvbXB0IiwKICAgICAgICAgICAgIm9wZW5EYXRhYmFzZSIsICJwb3N0TWVzc2FnZSIsCiAgICAgICAgICAgICJYTUxIdHRwUmVxdWVzdCIsICJYRG9tYWluUmVxdWVzdCIKICAgICAgICBdLAogICAgICAgIC8qKgogICAgICAgICAqIFByb3BlcnRpZXMgdG8gdW5zZXQvcHJvdGVjdCBvbiB0aGUgZG9jdW1lbnQgb2JqZWN0CiAgICAgICAgICovCiAgICAgICAgZG9jdW1lbnRQcm9wZXJ0aWVzID0gWwogICAgICAgICAgICAicmVmZXJyZXIiLAogICAgICAgICAgICAid3JpdGUiLCAib3BlbiIsICJjbG9zZSIKICAgICAgICBdOwoKICAgIHd5c2lodG1sNS5kb20uU2FuZGJveCA9IEJhc2UuZXh0ZW5kKAogICAgICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LmRvbS5TYW5kYm94LnByb3RvdHlwZSAqLyB7CgogICAgICAgICAgICBjb25zdHJ1Y3RvciA6IGZ1bmN0aW9uIChjb25maWcpIHsKICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnID0gd3lzaWh0bWw1Lmxhbmcub2JqZWN0KHt9KS5tZXJnZShjb25maWcpLmdldCgpOwogICAgICAgICAgICAgICAgdGhpcy5jb250YWluZXIgPSB0aGlzLl9jcmVhdGVDb250YWluZXIoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGluc2VydEludG8gOiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICAgICAgaWYgKHR5cGVvZihlbGVtZW50KSA9PT0gInN0cmluZyIpIHsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gZG9jLmdldEVsZW1lbnRCeUlkKGVsZW1lbnQpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5jb250YWluZXIpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZ2V0Q29udGFpbmVyIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGFpbmVyOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZ2V0V2luZG93IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhpcy5fcmVhZHlFcnJvcigpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZ2V0RG9jdW1lbnQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9yZWFkeUVycm9yKCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBkZXN0cm95IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuZ2V0Q29udGFpbmVyKCk7CiAgICAgICAgICAgICAgICBpZiAoY29udGFpbmVyICYmIGNvbnRhaW5lci5wYXJlbnROb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY29udGFpbmVyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9yZWFkeUVycm9yIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJ3eXNpaHRtbDUuU2FuZGJveDogU2FuZGJveCBjb250YWluZXIgaXNuJ3QgbG9hZGVkIHlldCIpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENyZWF0ZXMgdGhlIHNhbmRib3ggY29udGFpbmVyCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFNvbWUgaW1wb3J0YW50IG5vdGVzOgogICAgICAgICAgICAgKiAgLSBXZSBjYW4ndCB1c2UgSFRNTDUgc2FuZGJveCBmb3Igbm93OgogICAgICAgICAgICAgKiAgICBzZXR0aW5nIGl0IGNhdXNlcyB0aGF0IHRoZSBpZnJhbWUncyBkb20gY2FuJ3QgYmUgYWNjZXNzZWQgZnJvbSB0aGUgb3V0c2lkZQogICAgICAgICAgICAgKiAgICBUaGVyZWZvcmUgd2UgbmVlZCB0byBzZXQgdGhlICJhbGxvdy1zYW1lLW9yaWdpbiIgZmxhZyB3aGljaCBlbmFibGVzIGFjY2Vzc2luZyB0aGUgaWZyYW1lJ3MgZG9tCiAgICAgICAgICAgICAqICAgIEJ1dCB0aGVuIHRoZXJlJ3MgYW5vdGhlciBwcm9ibGVtLCBET00gZXZlbnRzIChmb2N1cywgYmx1ciwgY2hhbmdlLCBrZXlwcmVzcywgLi4uKSBhcmVuJ3QgZmlyZWQuCiAgICAgICAgICAgICAqICAgIEluIG9yZGVyIHRvIG1ha2UgdGhpcyBoYXBwZW4gd2UgbmVlZCB0byBzZXQgdGhlICJhbGxvdy1zY3JpcHRzIiBmbGFnLgogICAgICAgICAgICAgKiAgICBBIGNvbWJpbmF0aW9uIG9mIGFsbG93LXNjcmlwdHMgYW5kIGFsbG93LXNhbWUtb3JpZ2luIGlzIGFsbW9zdCB0aGUgc2FtZSBhcyBzZXR0aW5nIG5vIHNhbmRib3ggYXR0cmlidXRlIGF0IGFsbC4KICAgICAgICAgICAgICogIC0gQ2hyb21lICYgU2FmYXJpLCBkb2Vzbid0IHNlZW0gdG8gc3VwcG9ydCBzYW5kYm94aW5nIGNvcnJlY3RseSB3aGVuIHRoZSBpZnJhbWUncyBodG1sIGlzIGlubGluZWQgKG5vIHBoeXNpY2FsIGRvY3VtZW50KQogICAgICAgICAgICAgKiAgLSBJRSBuZWVkcyB0byBoYXZlIHRoZSBzZWN1cml0eT0icmVzdHJpY3RlZCIgYXR0cmlidXRlIHNldCBiZWZvcmUgdGhlIGlmcmFtZSBpcwogICAgICAgICAgICAgKiAgICBpbnNlcnRlZCBpbnRvIHRoZSBkb20gdHJlZQogICAgICAgICAgICAgKiAgLSBCZWxpZXZlIGl0IG9yIG5vdCBidXQgaW4gSUUgInNlY3VyaXR5IiBpbiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJpZnJhbWUiKSBpcyBmYWxzZSwgZXZlbgogICAgICAgICAgICAgKiAgICB0aG91Z2ggaXQgc3VwcG9ydHMgaXQKICAgICAgICAgICAgICogIC0gV2hlbiBhbiBpZnJhbWUgaGFzIHNlY3VyaXR5PSJyZXN0cmljdGVkIiwgaW4gSUUgZXZhbCgpICYgZXhlY1NjcmlwdCgpIGRvbid0IHdvcmsgYW55bW9yZQogICAgICAgICAgICAgKiAgLSBJRSBkb2Vzbid0IGZpcmUgdGhlIG9ubG9hZCBldmVudCB3aGVuIHRoZSBjb250ZW50IGlzIGlubGluZWQgaW4gdGhlIHNyYyBhdHRyaWJ1dGUsIHRoZXJlZm9yZSB3ZSByZWx5CiAgICAgICAgICAgICAqICAgIG9uIHRoZSBvbnJlYWR5c3RhdGVjaGFuZ2UgZXZlbnQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIF9jcmVhdGVDb250YWluZXIgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgY29udGFpbmVyID0gZG9jLmNyZWF0ZUVsZW1lbnQoImRpdiIpOwogICAgICAgICAgICAgICAgdGhpcy5nZXRXaW5kb3cgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGRvYyA9IHRoaXMuZ2V0RG9jdW1lbnQoKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9jLmRlZmF1bHRWaWV3IHx8IGRvYy5wYXJlbnRXaW5kb3c7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgdGhpcy5nZXREb2N1bWVudCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udGFpbmVyLm93bmVyRG9jdW1lbnQ7CiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIHJldHVybiBjb250YWluZXI7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfZ2V0SHRtbCA6IGZ1bmN0aW9uICh0ZW1wbGF0ZVZhcnMpIHsKICAgICAgICAgICAgICAgIHZhciBzdHlsZXNoZWV0cyA9IHRlbXBsYXRlVmFycy5zdHlsZXNoZWV0cywKICAgICAgICAgICAgICAgICAgICBodG1sID0gIiIsCiAgICAgICAgICAgICAgICAgICAgaSA9IDAsCiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoOwogICAgICAgICAgICAgICAgc3R5bGVzaGVldHMgPSB0eXBlb2Yoc3R5bGVzaGVldHMpID09PSAic3RyaW5nIiA/IFtzdHlsZXNoZWV0c10gOiBzdHlsZXNoZWV0czsKICAgICAgICAgICAgICAgIGlmIChzdHlsZXNoZWV0cykgewogICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IHN0eWxlc2hlZXRzLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGh0bWwgKz0gJzxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iJyArIHN0eWxlc2hlZXRzW2ldICsgJyI+JzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0ZW1wbGF0ZVZhcnMuc3R5bGVzaGVldHMgPSBodG1sOwoKICAgICAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUubGFuZy5zdHJpbmcoCiAgICAgICAgICAgICAgICAgICAgJzwhRE9DVFlQRSBodG1sPjxodG1sPjxoZWFkPicgKwogICAgICAgICAgICAgICAgICAgICc8bWV0YSBjaGFyc2V0PSIje2NoYXJzZXR9Ij4je3N0eWxlc2hlZXRzfTwvaGVhZD4nICsKICAgICAgICAgICAgICAgICAgICAnPGJvZHk+PC9ib2R5PjwvaHRtbD4nCiAgICAgICAgICAgICAgICApLmludGVycG9sYXRlKHRlbXBsYXRlVmFycyk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogTWV0aG9kIHRvIHVuc2V0L292ZXJyaWRlIGV4aXN0aW5nIHZhcmlhYmxlcwogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKiAgICAvLyBNYWtlIGNvb2tpZSB1bnJlYWRhYmxlIGFuZCB1bndyaXRhYmxlCiAgICAgICAgICAgICAqICAgIHRoaXMuX3Vuc2V0KGRvY3VtZW50LCAiY29va2llIiwgIiIsIHRydWUpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgX3Vuc2V0IDogZnVuY3Rpb24gKG9iamVjdCwgcHJvcGVydHksIHZhbHVlLCBzZXR0ZXIpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgb2JqZWN0W3Byb3BlcnR5XSA9IHZhbHVlOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgb2JqZWN0Ll9fZGVmaW5lR2V0dGVyX18ocHJvcGVydHksIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHNldHRlcikgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5fX2RlZmluZVNldHRlcl9fKHByb3BlcnR5LCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCF3eXNpaHRtbDUuYnJvd3Nlci5jcmFzaGVzV2hlbkRlZmluZVByb3BlcnR5KHByb3BlcnR5KSkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb25maWcgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2V0dGVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcuc2V0ID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wZXJ0eSwgY29uZmlnKTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAoKSB7CiAgICB2YXIgbWFwcGluZyA9IHsKICAgICAgICAiY2xhc3NOYW1lIiA6ICJjbGFzcyIKICAgIH07CiAgICB3eXNpaHRtbDUuZG9tLnNldEF0dHJpYnV0ZXMgPSBmdW5jdGlvbiAoYXR0cmlidXRlcykgewogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIG9uIDogZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKG1hcHBpbmdbaV0gfHwgaSwgYXR0cmlidXRlc1tpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfTsKfSkoKTsKd3lzaWh0bWw1LmRvbS5zZXRTdHlsZXMgPSBmdW5jdGlvbiAoc3R5bGVzKSB7CiAgICByZXR1cm4gewogICAgICAgIG9uIDogZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgICAgICAgICAgdmFyIHN0eWxlID0gZWxlbWVudC5zdHlsZTsKICAgICAgICAgICAgaWYgKHR5cGVvZihzdHlsZXMpID09PSAic3RyaW5nIikgewogICAgICAgICAgICAgICAgc3R5bGUuY3NzVGV4dCArPSAiOyIgKyBzdHlsZXM7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBzdHlsZXMpIHsKICAgICAgICAgICAgICAgIGlmIChpID09PSAiZmxvYXQiKSB7CiAgICAgICAgICAgICAgICAgICAgc3R5bGUuY3NzRmxvYXQgPSBzdHlsZXNbaV07CiAgICAgICAgICAgICAgICAgICAgc3R5bGUuc3R5bGVGbG9hdCA9IHN0eWxlc1tpXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc3R5bGVbaV0gPSBzdHlsZXNbaV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Owp9OwovKioKICogU2ltdWxhdGUgSFRNTDUgcGxhY2Vob2xkZXIgYXR0cmlidXRlCiAqCiAqIE5lZWRlZCBzaW5jZQogKiAgICAtIGRpdltjb250ZW50RWRpdGFibGVdIGVsZW1lbnRzIGRvbid0IHN1cHBvcnQgaXQKICogICAgLSBvbGRlciBicm93c2VycyAoc3VjaCBhcyBJRTggYW5kIEZpcmVmb3ggMy42KSBkb24ndCBzdXBwb3J0IGl0IGF0IGFsbAogKgogKiBAcGFyYW0ge09iamVjdH0gcGFyZW50IEluc3RhbmNlIG9mIG1haW4gd3lzaWh0bWw1LkVkaXRvciBjbGFzcwogKiBAcGFyYW0ge0VsZW1lbnR9IHZpZXcgSW5zdGFuY2Ugb2Ygd3lzaWh0bWw1LnZpZXdzLiogY2xhc3MKICogQHBhcmFtIHtTdHJpbmd9IHBsYWNlaG9sZGVyVGV4dAogKgogKiBAZXhhbXBsZQogKiAgICB3eXNpaHRtbC5kb20uc2ltdWxhdGVQbGFjZWhvbGRlcih0aGlzLCBjb21wb3NlciwgIkZvb2JhciIpOwogKi8KKGZ1bmN0aW9uIChkb20pIHsKICAgIGRvbS5zaW11bGF0ZVBsYWNlaG9sZGVyID0gZnVuY3Rpb24gKGVkaXRvciwgdmlldywgcGxhY2Vob2xkZXJUZXh0KSB7CiAgICAgICAgdmFyIENMQVNTX05BTUUgPSAicGxhY2Vob2xkZXIiLAogICAgICAgICAgICB1bnNldCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGlmICh2aWV3Lmhhc1BsYWNlaG9sZGVyU2V0KCkpIHsKICAgICAgICAgICAgICAgICAgICB2aWV3LmNsZWFyKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2aWV3LnBsYWNlaG9sZGVyU2V0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICBkb20ucmVtb3ZlQ2xhc3Modmlldy5lbGVtZW50LCBDTEFTU19OQU1FKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0ID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgaWYgKHZpZXcuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgdmlldy5wbGFjZWhvbGRlclNldCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgdmlldy5zZXRWYWx1ZShwbGFjZWhvbGRlclRleHQpOwogICAgICAgICAgICAgICAgICAgIGRvbS5hZGRDbGFzcyh2aWV3LmVsZW1lbnQsIENMQVNTX05BTUUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgICBlZGl0b3IKICAgICAgICAgICAgLm9uKCJzZXRfcGxhY2Vob2xkZXIiLCBzZXQpCiAgICAgICAgICAgIC5vbigidW5zZXRfcGxhY2Vob2xkZXIiLCB1bnNldCkKICAgICAgICAgICAgLm9uKCJmb2N1czpjb21wb3NlciIsIHVuc2V0KQogICAgICAgICAgICAub24oImNsaWNrOmNvbXBvc2VyIiwgdW5zZXQpCiAgICAgICAgICAgIC5vbigicGFzdGU6Y29tcG9zZXIiLCB1bnNldCkKICAgICAgICAgICAgLm9uKCJibHVyOmNvbXBvc2VyIiwgc2V0KTsKCiAgICAgICAgc2V0KCk7CiAgICB9Owp9KSh3eXNpaHRtbDUuZG9tKTsKKGZ1bmN0aW9uIChkb20pIHsKICAgIHZhciBkb2N1bWVudEVsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7CiAgICBpZiAoInRleHRDb250ZW50IiBpbiBkb2N1bWVudEVsZW1lbnQpIHsKICAgICAgICBkb20uc2V0VGV4dENvbnRlbnQgPSBmdW5jdGlvbiAoZWxlbWVudCwgdGV4dCkgewogICAgICAgICAgICBlbGVtZW50LnRleHRDb250ZW50ID0gdGV4dDsKICAgICAgICB9OwoKICAgICAgICBkb20uZ2V0VGV4dENvbnRlbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICByZXR1cm4gZWxlbWVudC50ZXh0Q29udGVudDsKICAgICAgICB9OwogICAgfSBlbHNlIGlmICgiaW5uZXJUZXh0IiBpbiBkb2N1bWVudEVsZW1lbnQpIHsKICAgICAgICBkb20uc2V0VGV4dENvbnRlbnQgPSBmdW5jdGlvbiAoZWxlbWVudCwgdGV4dCkgewogICAgICAgICAgICBlbGVtZW50LmlubmVyVGV4dCA9IHRleHQ7CiAgICAgICAgfTsKCiAgICAgICAgZG9tLmdldFRleHRDb250ZW50ID0gZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQuaW5uZXJUZXh0OwogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIGRvbS5zZXRUZXh0Q29udGVudCA9IGZ1bmN0aW9uIChlbGVtZW50LCB0ZXh0KSB7CiAgICAgICAgICAgIGVsZW1lbnQubm9kZVZhbHVlID0gdGV4dDsKICAgICAgICB9OwoKICAgICAgICBkb20uZ2V0VGV4dENvbnRlbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICByZXR1cm4gZWxlbWVudC5ub2RlVmFsdWU7CiAgICAgICAgfTsKICAgIH0KfSkod3lzaWh0bWw1LmRvbSk7CgovKioKICogRml4IG1vc3QgY29tbW9uIGh0bWwgZm9ybWF0dGluZyBtaXNiZWhhdmlvcnMgb2YgYnJvd3NlcnMgaW1wbGVtZW50YXRpb24gd2hlbiBpbnNlcnRpbmcKICogY29udGVudCB2aWEgY29weSAmIHBhc3RlIGNvbnRlbnRFZGl0YWJsZQogKgogKiBAYXV0aG9yIENocmlzdG9waGVyIEJsdW0KICovCnd5c2lodG1sNS5xdWlya3MuY2xlYW5QYXN0ZWRIVE1MID0gKGZ1bmN0aW9uICgpIHsKICAgIC8vIFRPRE86IFdlIHByb2JhYmx5IG5lZWQgbW9yZSBydWxlcyBoZXJlCiAgICB2YXIgZGVmYXVsdFJ1bGVzID0gewogICAgICAgIC8vIFdoZW4gcGFzdGluZyB1bmRlcmxpbmVkIGxpbmtzIDxhPiBpbnRvIGEgY29udGVudEVkaXRhYmxlLCBJRSB0aGlua3MsIGl0IGhhcyB0byBpbnNlcnQgPHU+IHRvIGtlZXAgdGhlIHN0eWxpbmcKICAgICAgICAiYSB1IiA6IHd5c2lodG1sNS5kb20ucmVwbGFjZVdpdGhDaGlsZE5vZGVzCiAgICB9OwoKICAgIGZ1bmN0aW9uIGNsZWFuUGFzdGVkSFRNTChlbGVtZW50T3JIdG1sLCBydWxlcywgY29udGV4dCkgewogICAgICAgIHJ1bGVzID0gcnVsZXMgfHwgZGVmYXVsdFJ1bGVzOwogICAgICAgIGNvbnRleHQgPSBjb250ZXh0IHx8IGVsZW1lbnRPckh0bWwub3duZXJEb2N1bWVudCB8fCBkb2N1bWVudDsKCiAgICAgICAgdmFyIGVsZW1lbnQsCiAgICAgICAgICAgIGlzU3RyaW5nID0gdHlwZW9mKGVsZW1lbnRPckh0bWwpID09PSAic3RyaW5nIiwKICAgICAgICAgICAgbWV0aG9kLAogICAgICAgICAgICBtYXRjaGVzLAogICAgICAgICAgICBtYXRjaGVzTGVuZ3RoLAogICAgICAgICAgICBpLAogICAgICAgICAgICBqID0gMDsKICAgICAgICBpZiAoaXNTdHJpbmcpIHsKICAgICAgICAgICAgZWxlbWVudCA9IHd5c2lodG1sNS5kb20uZ2V0QXNEb20oZWxlbWVudE9ySHRtbCwgY29udGV4dCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnRPckh0bWw7CiAgICAgICAgfQoKICAgICAgICBmb3IgKGkgaW4gcnVsZXMpIHsKICAgICAgICAgICAgbWF0Y2hlcyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChpKTsKICAgICAgICAgICAgbWV0aG9kID0gcnVsZXNbaV07CiAgICAgICAgICAgIG1hdGNoZXNMZW5ndGggPSBtYXRjaGVzLmxlbmd0aDsKICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICBqIDwgbWF0Y2hlc0xlbmd0aDsKICAgICAgICAgICAgICAgIGorKykgewogICAgICAgICAgICAgICAgbWV0aG9kKG1hdGNoZXNbal0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBtYXRjaGVzID0gZWxlbWVudE9ySHRtbCA9IHJ1bGVzID0gbnVsbDsKCiAgICAgICAgcmV0dXJuIGlzU3RyaW5nID8gZWxlbWVudC5pbm5lckhUTUwgOiBlbGVtZW50OwogICAgfQoKICAgIHJldHVybiBjbGVhblBhc3RlZEhUTUw7Cn0pKCk7Ci8qKgogKiBJRSBhbmQgT3BlcmEgbGVhdmUgYW4gZW1wdHkgcGFyYWdyYXBoIGluIHRoZSBjb250ZW50RWRpdGFibGUgZWxlbWVudCBhZnRlciBjbGVhcmluZyBpdAogKgogKiBAcGFyYW0ge09iamVjdH0gY29udGVudEVkaXRhYmxlRWxlbWVudCBUaGUgY29udGVudEVkaXRhYmxlIGVsZW1lbnQgdG8gb2JzZXJ2ZSBmb3IgY2xlYXJpbmcgZXZlbnRzCiAqIEBleGFwbGUKICogICAgd3lzaWh0bWw1LnF1aXJrcy5lbnN1cmVQcm9wZXJDbGVhcmluZyhteUNvbnRlbnRFZGl0YWJsZUVsZW1lbnQpOwogKi8Kd3lzaWh0bWw1LnF1aXJrcy5lbnN1cmVQcm9wZXJDbGVhcmluZyA9IChmdW5jdGlvbiAoKSB7CiAgICB2YXIgY2xlYXJJZk5lY2Vzc2FyeSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgZWxlbWVudCA9IHRoaXM7CiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBpbm5lckhUTUwgPSBlbGVtZW50LmlubmVySFRNTC50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICBpZiAoaW5uZXJIVE1MID09ICI8cD4mbmJzcDs8L3A+IiB8fAogICAgICAgICAgICAgICAgaW5uZXJIVE1MID09ICI8cD4mbmJzcDs8L3A+PHA+Jm5ic3A7PC9wPiIpIHsKICAgICAgICAgICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9LCAwKTsKICAgIH07CgogICAgcmV0dXJuIGZ1bmN0aW9uIChjb21wb3NlcikgewogICAgICAgIHd5c2lodG1sNS5kb20ub2JzZXJ2ZShjb21wb3Nlci5lbGVtZW50LCBbImN1dCIsICJrZXlkb3duIl0sIGNsZWFySWZOZWNlc3NhcnkpOwogICAgfTsKfSkoKTsKLy8gU2VlIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY2NDM5OAovLwovLyBJbiBGaXJlZm94IHRoaXM6Ci8vICAgICAgdmFyIGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKLy8gICAgICBkLmlubmVySFRNTCA9JzxhIGhyZWY9In4iPjwvYT4nOwovLyAgICAgIGQuaW5uZXJIVE1MOwovLyB3aWxsIHJlc3VsdCBpbjoKLy8gICAgICA8YSBocmVmPSIlN0UiPjwvYT4KLy8gd2hpY2ggaXMgd3JvbmcKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBUSUxERV9FU0NBUEVEID0gIiU3RSI7CiAgICB3eXNpaHRtbDUucXVpcmtzLmdldENvcnJlY3RJbm5lckhUTUwgPSBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgIHZhciBpbm5lckhUTUwgPSBlbGVtZW50LmlubmVySFRNTDsKICAgICAgICBpZiAoaW5uZXJIVE1MLmluZGV4T2YoVElMREVfRVNDQVBFRCkgPT09IC0xKSB7CiAgICAgICAgICAgIHJldHVybiBpbm5lckhUTUwudHJpbSgpOwogICAgICAgIH0KCiAgICAgICAgdmFyIGVsZW1lbnRzV2l0aFRpbGRlID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCJbaHJlZio9J34nXSwgW3NyYyo9J34nXSIpLAogICAgICAgICAgICB1cmwsCiAgICAgICAgICAgIHVybFRvU2VhcmNoLAogICAgICAgICAgICBsZW5ndGgsCiAgICAgICAgICAgIGk7CiAgICAgICAgZm9yIChpID0gMCwgbGVuZ3RoID0gZWxlbWVudHNXaXRoVGlsZGUubGVuZ3RoOwogICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICB1cmwgPSBlbGVtZW50c1dpdGhUaWxkZVtpXS5ocmVmIHx8IGVsZW1lbnRzV2l0aFRpbGRlW2ldLnNyYzsKICAgICAgICAgICAgdXJsVG9TZWFyY2ggPSB3eXNpaHRtbDUubGFuZy5zdHJpbmcodXJsKS5yZXBsYWNlKCJ+IikuYnkoVElMREVfRVNDQVBFRCk7CiAgICAgICAgICAgIGlubmVySFRNTCA9IHd5c2lodG1sNS5sYW5nLnN0cmluZyhpbm5lckhUTUwpLnJlcGxhY2UodXJsVG9TZWFyY2gpLmJ5KHVybCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbm5lckhUTUw7CiAgICB9Owp9KSh3eXNpaHRtbDUpOwovKioKICogRm9yY2UgcmVyZW5kZXJpbmcgb2YgYSBnaXZlbiBlbGVtZW50CiAqIE5lZWRlZCB0byBmaXggZGlzcGxheSBtaXNiZWhhdmlvcnMgb2YgSUUKICoKICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IG9iamVjdCB3aGljaCBuZWVkcyB0byBiZSByZXJlbmRlcmVkCiAqIEBleGFtcGxlCiAqICAgIHd5c2lodG1sNS5xdWlya3MucmVkcmF3KGRvY3VtZW50LmJvZHkpOwogKi8KKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBDTEFTU19OQU1FID0gInd5c2lodG1sNS1xdWlya3MtcmVkcmF3IjsKCiAgICB3eXNpaHRtbDUucXVpcmtzLnJlZHJhdyA9IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgICAgd3lzaWh0bWw1LmRvbS5hZGRDbGFzcyhlbGVtZW50LCBDTEFTU19OQU1FKTsKICAgICAgICB3eXNpaHRtbDUuZG9tLnJlbW92ZUNsYXNzKGVsZW1lbnQsIENMQVNTX05BTUUpOwoKICAgICAgICAvLyBGb2xsb3dpbmcgaGFjayBpcyBuZWVkZWQgZm9yIGZpcmVmb3ggdG8gbWFrZSBzdXJlIHRoYXQgaW1hZ2UgcmVzaXplIGhhbmRsZXMgYXJlIHByb3Blcmx5IHJlbW92ZWQKICAgICAgICB0cnkgewogICAgICAgICAgICB2YXIgZG9jID0gZWxlbWVudC5vd25lckRvY3VtZW50OwogICAgICAgICAgICBkb2MuZXhlY0NvbW1hbmQoIml0YWxpYyIsIGZhbHNlLCBudWxsKTsKICAgICAgICAgICAgZG9jLmV4ZWNDb21tYW5kKCJpdGFsaWMiLCBmYWxzZSwgbnVsbCk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBTZWxlY3Rpb24gQVBJCiAqCiAqIEBleGFtcGxlCiAqICAgIHZhciBzZWxlY3Rpb24gPSBuZXcgd3lzaWh0bWw1LlNlbGVjdGlvbihlZGl0b3IpOwogKi8KKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBkb20gPSB3eXNpaHRtbDUuZG9tOwoKICAgIGZ1bmN0aW9uIF9nZXRDdW11bGF0aXZlT2Zmc2V0VG9wKGVsZW1lbnQpIHsKICAgICAgICB2YXIgdG9wID0gMDsKICAgICAgICBpZiAoZWxlbWVudC5wYXJlbnROb2RlKSB7CiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIHRvcCArPSBlbGVtZW50Lm9mZnNldFRvcCB8fCAwOwogICAgICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQub2Zmc2V0UGFyZW50OwogICAgICAgICAgICB9IHdoaWxlIChlbGVtZW50KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRvcDsKICAgIH0KCiAgICB3eXNpaHRtbDUuU2VsZWN0aW9uID0gQmFzZS5leHRlbmQoCiAgICAgICAgLyoqIEBzY29wZSB3eXNpaHRtbDUuU2VsZWN0aW9uLnByb3RvdHlwZSAqLyB7CiAgICAgICAgICAgIGNvbnN0cnVjdG9yIDogZnVuY3Rpb24gKGVkaXRvcikgewogICAgICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgb3VyIGV4dGVybmFsIHJhbmdlIGxpYnJhcnkgaXMgaW5pdGlhbGl6ZWQKICAgICAgICAgICAgICAgIHdpbmRvdy5yYW5neS5pbml0KCk7CgogICAgICAgICAgICAgICAgdGhpcy5lZGl0b3IgPSBlZGl0b3I7CiAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyID0gZWRpdG9yLmNvbXBvc2VyOwogICAgICAgICAgICAgICAgdGhpcy5kb2MgPSB0aGlzLmNvbXBvc2VyLmRvYzsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBHZXQgdGhlIGN1cnJlbnQgc2VsZWN0aW9uIGFzIGEgYm9va21hcmsgdG8gYmUgYWJsZSB0byBsYXRlciByZXN0b3JlIGl0CiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gQW4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBzZWxlY3Rpb24KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGdldEJvb2ttYXJrIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gdGhpcy5nZXRSYW5nZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIHJhbmdlICYmIHJhbmdlLmNsb25lUmFuZ2UoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBSZXN0b3JlIGEgc2VsZWN0aW9uIHJldHJpZXZlZCB2aWEgd3lzaWh0bWw1LlNlbGVjdGlvbi5wcm90b3R5cGUuZ2V0Qm9va21hcmsKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGJvb2ttYXJrIEFuIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgc2VsZWN0aW9uCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzZXRCb29rbWFyayA6IGZ1bmN0aW9uIChib29rbWFyaykgewogICAgICAgICAgICAgICAgaWYgKCFib29rbWFyaykgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLnNldFNlbGVjdGlvbihib29rbWFyayk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU2V0IHRoZSBjYXJldCBpbiBmcm9udCBvZiB0aGUgZ2l2ZW4gbm9kZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gbm9kZSBUaGUgZWxlbWVudCBvciB0ZXh0IG5vZGUgd2hlcmUgdG8gcG9zaXRpb24gdGhlIGNhcmV0IGluIGZyb250IG9mCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHNlbGVjdGlvbi5zZXRCZWZvcmUobXlFbGVtZW50KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNldEJlZm9yZSA6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICB2YXIgcmFuZ2UgPSByYW5neS5jcmVhdGVSYW5nZSh0aGlzLmRvYyk7CiAgICAgICAgICAgICAgICByYW5nZS5zZXRTdGFydEJlZm9yZShub2RlKTsKICAgICAgICAgICAgICAgIHJhbmdlLnNldEVuZEJlZm9yZShub2RlKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNldFNlbGVjdGlvbihyYW5nZSk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU2V0IHRoZSBjYXJldCBhZnRlciB0aGUgZ2l2ZW4gbm9kZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gbm9kZSBUaGUgZWxlbWVudCBvciB0ZXh0IG5vZGUgd2hlcmUgdG8gcG9zaXRpb24gdGhlIGNhcmV0IGluIGZyb250IG9mCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHNlbGVjdGlvbi5zZXRCZWZvcmUobXlFbGVtZW50KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNldEFmdGVyIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgICAgIHZhciByYW5nZSA9IHJhbmd5LmNyZWF0ZVJhbmdlKHRoaXMuZG9jKTsKICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobm9kZSk7CiAgICAgICAgICAgICAgICByYW5nZS5zZXRFbmRBZnRlcihub2RlKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNldFNlbGVjdGlvbihyYW5nZSk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQWJpbGl0eSB0byBzZWxlY3QvbWFyayBub2RlcwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IG5vZGUgVGhlIG5vZGUvZWxlbWVudCB0byBzZWxlY3QKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICogICAgc2VsZWN0aW9uLnNlbGVjdE5vZGUoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm15LWltYWdlIikpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2VsZWN0Tm9kZSA6IGZ1bmN0aW9uIChub2RlLCBhdm9pZEludmlzaWJsZVNwYWNlKSB7CiAgICAgICAgICAgICAgICB2YXIgcmFuZ2UgPSByYW5neS5jcmVhdGVSYW5nZSh0aGlzLmRvYyksCiAgICAgICAgICAgICAgICAgICAgaXNFbGVtZW50ID0gbm9kZS5ub2RlVHlwZSA9PT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERSwKICAgICAgICAgICAgICAgICAgICBjYW5IYXZlSFRNTCA9ICJjYW5IYXZlSFRNTCIgaW4gbm9kZSA/IG5vZGUuY2FuSGF2ZUhUTUwgOiAobm9kZS5ub2RlTmFtZSAhPT0gIklNRyIpLAogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBpc0VsZW1lbnQgPyBub2RlLmlubmVySFRNTCA6IG5vZGUuZGF0YSwKICAgICAgICAgICAgICAgICAgICBpc0VtcHR5ID0gKGNvbnRlbnQgPT09ICIiIHx8IGNvbnRlbnQgPT09IHd5c2lodG1sNS5JTlZJU0lCTEVfU1BBQ0UpLAogICAgICAgICAgICAgICAgICAgIGRpc3BsYXlTdHlsZSA9IGRvbS5nZXRTdHlsZSgiZGlzcGxheSIpLmZyb20obm9kZSksCiAgICAgICAgICAgICAgICAgICAgaXNCbG9ja0VsZW1lbnQgPSAoZGlzcGxheVN0eWxlID09PSAiYmxvY2siIHx8IGRpc3BsYXlTdHlsZSA9PT0gImxpc3QtaXRlbSIpOwoKICAgICAgICAgICAgICAgIGlmIChpc0VtcHR5ICYmIGlzRWxlbWVudCAmJiBjYW5IYXZlSFRNTCAmJiAhYXZvaWRJbnZpc2libGVTcGFjZSkgewogICAgICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IGNhcmV0IGlzIHZpc2libGUgaW4gbm9kZSBieSBpbnNlcnRpbmcgYSB6ZXJvIHdpZHRoIG5vIGJyZWFraW5nIHNwYWNlCiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5pbm5lckhUTUwgPSB3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFOwogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGNhbkhhdmVIVE1MKSB7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKG5vZGUpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByYW5nZS5zZWxlY3ROb2RlKG5vZGUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChjYW5IYXZlSFRNTCAmJiBpc0VtcHR5ICYmIGlzRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgIHJhbmdlLmNvbGxhcHNlKGlzQmxvY2tFbGVtZW50KTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2FuSGF2ZUhUTUwgJiYgaXNFbXB0eSkgewogICAgICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2Uuc2V0RW5kQWZ0ZXIobm9kZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5zZXRTZWxlY3Rpb24ocmFuZ2UpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEdldCB0aGUgbm9kZSB3aGljaCBjb250YWlucyB0aGUgc2VsZWN0aW9uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gW2NvbnRyb2xSYW5nZV0gKG9ubHkgSUUpIFdoZXRoZXIgaXQgc2hvdWxkIHJldHVybiB0aGUgc2VsZWN0ZWQgQ29udHJvbFJhbmdlIGVsZW1lbnQgd2hlbiB0aGUgc2VsZWN0aW9uIHR5cGUgaXMgYSAiQ29udHJvbFJhbmdlIgogICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBub2RlIHRoYXQgY29udGFpbnMgdGhlIGNhcmV0CiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHZhciBub2RlVGhhdENvbnRhaW5zQ2FyZXQgPSBzZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKCk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBnZXRTZWxlY3RlZE5vZGUgOiBmdW5jdGlvbiAoY29udHJvbFJhbmdlLCBleGNsdWRlRWRpdG9yQ29udGFpbmVyKSB7CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0aW9uLAogICAgICAgICAgICAgICAgICAgIHJhbmdlLAogICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IG51bGw7CgogICAgICAgICAgICAgICAgaWYgKGNvbnRyb2xSYW5nZSAmJiB0aGlzLmRvYy5zZWxlY3Rpb24gJiYgdGhpcy5kb2Muc2VsZWN0aW9uLnR5cGUgPT09ICJDb250cm9sIikgewogICAgICAgICAgICAgICAgICAgIHJhbmdlID0gdGhpcy5kb2Muc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJhbmdlICYmIHJhbmdlLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZE5vZGUgPSByYW5nZS5pdGVtKDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBzZWxlY3Rpb24gPSB0aGlzLmdldFNlbGVjdGlvbih0aGlzLmRvYyk7CiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uLmZvY3VzTm9kZSA9PT0gc2VsZWN0aW9uLmFuY2hvck5vZGUpIHsKICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZE5vZGUgPSBzZWxlY3Rpb24uZm9jdXNOb2RlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByYW5nZSA9IHRoaXMuZ2V0UmFuZ2UodGhpcy5kb2MpOwogICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IHJhbmdlID8gcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIgOiB0aGlzLmVkaXRvci5jb21wb3Nlci5zYW5kYm94LmdldENvbnRhaW5lcigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGV4Y2x1ZGVFZGl0b3JDb250YWluZXIgJiYgd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKHNlbGVjdGVkTm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZE5vZGUgPSBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGVkTm9kZTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGV4ZWN1dGVBbmRSZXN0b3JlIDogZnVuY3Rpb24gKG1ldGhvZCwgcmVzdG9yZVNjcm9sbFBvc2l0aW9uKSB7CiAgICAgICAgICAgICAgICB2YXIgYm9keSA9IHRoaXMuZG9jLmJvZHksCiAgICAgICAgICAgICAgICAgICAgb2xkU2Nyb2xsVG9wID0gcmVzdG9yZVNjcm9sbFBvc2l0aW9uICYmIGJvZHkuc2Nyb2xsVG9wLAogICAgICAgICAgICAgICAgICAgIG9sZFNjcm9sbExlZnQgPSByZXN0b3JlU2Nyb2xsUG9zaXRpb24gJiYgYm9keS5zY3JvbGxMZWZ0LAogICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSA9ICJfd3lzaWh0bWw1LXRlbXAtcGxhY2Vob2xkZXIiLAogICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVySHRtbCA9ICc8c3BhbiBjbGFzcz0iJyArIGNsYXNzTmFtZSArICciPicgKyB3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFICsgJzwvc3Bhbj4nLAogICAgICAgICAgICAgICAgICAgIHJhbmdlID0gdGhpcy5nZXRSYW5nZSh0aGlzLmRvYyksCiAgICAgICAgICAgICAgICAgICAgY2FyZXRQbGFjZWhvbGRlciwKICAgICAgICAgICAgICAgICAgICBuZXdDYXJldFBsYWNlaG9sZGVyLAogICAgICAgICAgICAgICAgICAgIG5leHRTaWJsaW5nLAogICAgICAgICAgICAgICAgICAgIG5vZGUsCiAgICAgICAgICAgICAgICAgICAgbmV3UmFuZ2U7CgogICAgICAgICAgICAgICAgLy8gTm90aGluZyBzZWxlY3RlZCwgZXhlY3V0ZSBhbmQgc2F5IGdvb2RieWUKICAgICAgICAgICAgICAgIGlmICghcmFuZ2UpIHsKICAgICAgICAgICAgICAgICAgICBtZXRob2QoYm9keSwgYm9keSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICh3eXNpaHRtbDUuYnJvd3Nlci5oYXNJbnNlcnROb2RlSXNzdWUoKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZG9jLmV4ZWNDb21tYW5kKCJpbnNlcnRIVE1MIiwgZmFsc2UsIHBsYWNlaG9sZGVySHRtbCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIG5vZGUgPSByYW5nZS5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQocGxhY2Vob2xkZXJIdG1sKTsKICAgICAgICAgICAgICAgICAgICByYW5nZS5pbnNlcnROb2RlKG5vZGUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IGEgcG90ZW50aWFsIGVycm9yIGRvZXNuJ3QgY2F1c2Ugb3VyIHBsYWNlaG9sZGVyIGVsZW1lbnQgdG8gYmUgbGVmdCBhcyBhIHBsYWNlaG9sZGVyCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIG1ldGhvZChyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2UuZW5kQ29udGFpbmVyKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgICAgICAgICB9LCAwKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjYXJldFBsYWNlaG9sZGVyID0gdGhpcy5kb2MucXVlcnlTZWxlY3RvcigiLiIgKyBjbGFzc05hbWUpOwogICAgICAgICAgICAgICAgaWYgKGNhcmV0UGxhY2Vob2xkZXIpIHsKICAgICAgICAgICAgICAgICAgICBuZXdSYW5nZSA9IHJhbmd5LmNyZWF0ZVJhbmdlKHRoaXMuZG9jKTsKICAgICAgICAgICAgICAgICAgICBuZXh0U2libGluZyA9IGNhcmV0UGxhY2Vob2xkZXIubmV4dFNpYmxpbmc7CiAgICAgICAgICAgICAgICAgICAgLy8gT3BlcmEgaXMgc28gZnVja2VkIHVwIHdoZW4geW91IHdhbm5hIHNldCBmb2N1cyBiZWZvcmUgYSA8YnI+CiAgICAgICAgICAgICAgICAgICAgaWYgKHd5c2lodG1sNS5icm93c2VyLmhhc0luc2VydE5vZGVJc3N1ZSgpICYmIG5leHRTaWJsaW5nICYmIG5leHRTaWJsaW5nLm5vZGVOYW1lID09PSAiQlIiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0NhcmV0UGxhY2Vob2xkZXIgPSB0aGlzLmRvYy5jcmVhdGVUZXh0Tm9kZSh3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFKTsKICAgICAgICAgICAgICAgICAgICAgICAgZG9tLmluc2VydChuZXdDYXJldFBsYWNlaG9sZGVyKS5hZnRlcihjYXJldFBsYWNlaG9sZGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3UmFuZ2Uuc2V0U3RhcnRCZWZvcmUobmV3Q2FyZXRQbGFjZWhvbGRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1JhbmdlLnNldEVuZEJlZm9yZShuZXdDYXJldFBsYWNlaG9sZGVyKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdSYW5nZS5zZWxlY3ROb2RlKGNhcmV0UGxhY2Vob2xkZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBuZXdSYW5nZS5kZWxldGVDb250ZW50cygpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFNlbGVjdGlvbihuZXdSYW5nZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIGZhbGxiYWNrIGZvciB3aGVuIGFsbCBoZWxsIGJyZWFrcyBsb29zZQogICAgICAgICAgICAgICAgICAgIGJvZHkuZm9jdXMoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAocmVzdG9yZVNjcm9sbFBvc2l0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgYm9keS5zY3JvbGxUb3AgPSBvbGRTY3JvbGxUb3A7CiAgICAgICAgICAgICAgICAgICAgYm9keS5zY3JvbGxMZWZ0ID0gb2xkU2Nyb2xsTGVmdDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgaXQgYWdhaW4sIGp1c3QgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIHBsYWNlaG9sZGVyIGlzIGRlZmluaXRlbHkgb3V0IG9mIHRoZSBkb20gdHJlZQogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBjYXJldFBsYWNlaG9sZGVyLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY2FyZXRQbGFjZWhvbGRlcik7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChlMikgewogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIERpZmZlcmVudCBhcHByb2FjaCBvZiBwcmVzZXJ2aW5nIHRoZSBzZWxlY3Rpb24gKGRvZXNuJ3QgbW9kaWZ5IHRoZSBkb20pCiAgICAgICAgICAgICAqIFRha2VzIGFsbCB0ZXh0IG5vZGVzIGluIHRoZSBzZWxlY3Rpb24gYW5kIHNhdmVzIHRoZSBzZWxlY3Rpb24gcG9zaXRpb24gaW4gdGhlIGZpcnN0IGFuZCBsYXN0IG9uZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZXhlY3V0ZUFuZFJlc3RvcmVTaW1wbGUgOiBmdW5jdGlvbiAobWV0aG9kKSB7CiAgICAgICAgICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLmdldFJhbmdlKCksCiAgICAgICAgICAgICAgICAgICAgYm9keSA9IHRoaXMuZG9jLmJvZHksCiAgICAgICAgICAgICAgICAgICAgbmV3UmFuZ2UsCiAgICAgICAgICAgICAgICAgICAgZmlyc3ROb2RlLAogICAgICAgICAgICAgICAgICAgIGxhc3ROb2RlLAogICAgICAgICAgICAgICAgICAgIHRleHROb2RlcywKICAgICAgICAgICAgICAgICAgICByYW5nZUJhY2t1cDsKCiAgICAgICAgICAgICAgICAvLyBOb3RoaW5nIHNlbGVjdGVkLCBleGVjdXRlIGFuZCBzYXkgZ29vZGJ5ZQogICAgICAgICAgICAgICAgaWYgKCFyYW5nZSkgewogICAgICAgICAgICAgICAgICAgIG1ldGhvZChib2R5LCBib2R5KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGV4dE5vZGVzID0gcmFuZ2UuZ2V0Tm9kZXMoWzNdKTsKICAgICAgICAgICAgICAgIGZpcnN0Tm9kZSA9IHRleHROb2Rlc1swXSB8fCByYW5nZS5zdGFydENvbnRhaW5lcjsKICAgICAgICAgICAgICAgIGxhc3ROb2RlID0gdGV4dE5vZGVzW3RleHROb2Rlcy5sZW5ndGggLSAxXSB8fCByYW5nZS5lbmRDb250YWluZXI7CgogICAgICAgICAgICAgICAgcmFuZ2VCYWNrdXAgPSB7CiAgICAgICAgICAgICAgICAgICAgY29sbGFwc2VkIDogcmFuZ2UuY29sbGFwc2VkLAogICAgICAgICAgICAgICAgICAgIHN0YXJ0Q29udGFpbmVyIDogZmlyc3ROb2RlLAogICAgICAgICAgICAgICAgICAgIHN0YXJ0T2Zmc2V0IDogZmlyc3ROb2RlID09PSByYW5nZS5zdGFydENvbnRhaW5lciA/IHJhbmdlLnN0YXJ0T2Zmc2V0IDogMCwKICAgICAgICAgICAgICAgICAgICBlbmRDb250YWluZXIgOiBsYXN0Tm9kZSwKICAgICAgICAgICAgICAgICAgICBlbmRPZmZzZXQgOiBsYXN0Tm9kZSA9PT0gcmFuZ2UuZW5kQ29udGFpbmVyID8gcmFuZ2UuZW5kT2Zmc2V0IDogbGFzdE5vZGUubGVuZ3RoCiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgbWV0aG9kKHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5lbmRDb250YWluZXIpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICAgICAgICAgIH0sIDApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIG5ld1JhbmdlID0gcmFuZ3kuY3JlYXRlUmFuZ2UodGhpcy5kb2MpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBuZXdSYW5nZS5zZXRTdGFydChyYW5nZUJhY2t1cC5zdGFydENvbnRhaW5lciwgcmFuZ2VCYWNrdXAuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZTEpIHsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgbmV3UmFuZ2Uuc2V0RW5kKHJhbmdlQmFja3VwLmVuZENvbnRhaW5lciwgcmFuZ2VCYWNrdXAuZW5kT2Zmc2V0KTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUyKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U2VsZWN0aW9uKG5ld1JhbmdlKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUzKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbiAobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgICB2YXIgbmV3UmFuZ2UgPSByYW5neS5jcmVhdGVSYW5nZSh0aGlzLmRvYyk7CiAgICAgICAgICAgICAgICBuZXdSYW5nZS5zZXRTdGFydChub2RlLCBvZmZzZXQgfHwgMCk7CiAgICAgICAgICAgICAgICB0aGlzLnNldFNlbGVjdGlvbihuZXdSYW5nZSk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogSW5zZXJ0IGh0bWwgYXQgdGhlIGNhcmV0IHBvc2l0aW9uIGFuZCBtb3ZlIHRoZSBjdXJzb3IgYWZ0ZXIgdGhlIGluc2VydGVkIGh0bWwKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGh0bWwgSFRNTCBzdHJpbmcgdG8gaW5zZXJ0CiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHNlbGVjdGlvbi5pbnNlcnRIVE1MKCI8cD5mb29iYXI8L3A+Iik7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbnNlcnRIVE1MIDogZnVuY3Rpb24gKGh0bWwpIHsKICAgICAgICAgICAgICAgIHZhciByYW5nZSA9IHJhbmd5LmNyZWF0ZVJhbmdlKHRoaXMuZG9jKSwKICAgICAgICAgICAgICAgICAgICBub2RlID0gcmFuZ2UuY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KGh0bWwpLAogICAgICAgICAgICAgICAgICAgIGxhc3RDaGlsZCA9IG5vZGUubGFzdENoaWxkOwogICAgICAgICAgICAgICAgdGhpcy5pbnNlcnROb2RlKG5vZGUpOwogICAgICAgICAgICAgICAgaWYgKGxhc3RDaGlsZCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0QWZ0ZXIobGFzdENoaWxkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBJbnNlcnQgYSBub2RlIGF0IHRoZSBjYXJldCBwb3NpdGlvbiBhbmQgbW92ZSB0aGUgY3Vyc29yIGJlaGluZCBpdAogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gbm9kZSBIVE1MIHN0cmluZyB0byBpbnNlcnQKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICogICAgc2VsZWN0aW9uLmluc2VydE5vZGUoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoImZvb2JhciIpKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGluc2VydE5vZGUgOiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gdGhpcy5nZXRSYW5nZSgpOwogICAgICAgICAgICAgICAgaWYgKHJhbmdlKSB7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZShub2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBXcmFwcyBjdXJyZW50IHNlbGVjdGlvbiB3aXRoIHRoZSBnaXZlbiBub2RlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBub2RlIFRoZSBub2RlIHRvIHN1cnJvdW5kIHRoZSBzZWxlY3RlZCBlbGVtZW50cyB3aXRoCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzdXJyb3VuZCA6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLmdldFJhbmdlKCk7CiAgICAgICAgICAgICAgICBpZiAoIXJhbmdlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBvbmx5IHdvcmtzIHdoZW4gdGhlIHJhbmdlIGJvdW5kYXJpZXMgYXJlIG5vdCBvdmVybGFwcGluZyBvdGhlciBlbGVtZW50cwogICAgICAgICAgICAgICAgICAgIHJhbmdlLnN1cnJvdW5kQ29udGVudHMobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3ROb2RlKG5vZGUpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgIC8vIGZhbGxiYWNrCiAgICAgICAgICAgICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChyYW5nZS5leHRyYWN0Q29udGVudHMoKSk7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZShub2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBTY3JvbGwgdGhlIGN1cnJlbnQgY2FyZXQgcG9zaXRpb24gaW50byB0aGUgdmlldwogICAgICAgICAgICAgKiBGSVhNRTogVGhpcyBpcyBhIGJpdCBoYWNreSwgdGhlcmUgbWlnaHQgYmUgYSBzbWFydGVyIHdheSBvZiBkb2luZyB0aGlzCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHNlbGVjdGlvbi5zY3JvbGxJbnRvVmlldygpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2Nyb2xsSW50b1ZpZXcgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWROb2RlcyA9IHRoaXMuY29tcG9zZXIuc2VsZWN0aW9uLmdldE5vZGVzKDMpOwogICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZXMgJiYgc2VsZWN0ZWROb2Rlcy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGZpcnN0Tm9kZSA9IHNlbGVjdGVkTm9kZXNbMF07CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGZpcnN0Tm9kZS5ub2RlVHlwZSA9PT0gMykgewogICAgICAgICAgICAgICAgICAgICAgICBmaXJzdE5vZGUgPSBmaXJzdE5vZGUucGFyZW50RWxlbWVudDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLyogVXNpbmcgc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZCBmb3IgQ2hyb21lIGFuZAogICAgICAgICAgICAgICAgICAgICAqIHNjcm9sbEludG9WaWV3IGZvciBvdGhlciBicm93c2VycyAqLwogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZmlyc3ROb2RlLnNjcm9sbEludG9WaWV3SWZOZWVkZWQgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3ROb2RlLnNjcm9sbEludG9WaWV3SWZOZWVkZWQoKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaXJzdE5vZGUuc2Nyb2xsSW50b1ZpZXcgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3ROb2RlLnNjcm9sbEludG9WaWV3KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFNlbGVjdCBsaW5lIHdoZXJlIHRoZSBjYXJldCBpcyBpbgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2VsZWN0TGluZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGlmICh3eXNpaHRtbDUuYnJvd3Nlci5zdXBwb3J0c1NlbGVjdGlvbk1vZGlmeSgpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2VsZWN0TGluZV9XM0MoKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5kb2Muc2VsZWN0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2VsZWN0TGluZV9NU0lFKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0RPTS9TZWxlY3Rpb24vbW9kaWZ5CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBfc2VsZWN0TGluZV9XM0MgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgd2luID0gdGhpcy5kb2MuZGVmYXVsdFZpZXcsCiAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uID0gd2luLmdldFNlbGVjdGlvbigpOwogICAgICAgICAgICAgICAgc2VsZWN0aW9uLm1vZGlmeSgiZXh0ZW5kIiwgImxlZnQiLCAibGluZWJvdW5kYXJ5Iik7CiAgICAgICAgICAgICAgICBzZWxlY3Rpb24ubW9kaWZ5KCJleHRlbmQiLCAicmlnaHQiLCAibGluZWJvdW5kYXJ5Iik7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfc2VsZWN0TGluZV9NU0lFIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gdGhpcy5kb2Muc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCksCiAgICAgICAgICAgICAgICAgICAgcmFuZ2VUb3AgPSByYW5nZS5ib3VuZGluZ1RvcCwKICAgICAgICAgICAgICAgICAgICByYW5nZUhlaWdodCA9IHJhbmdlLmJvdW5kaW5nSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgIHNjcm9sbFdpZHRoID0gdGhpcy5kb2MuYm9keS5zY3JvbGxXaWR0aCwKICAgICAgICAgICAgICAgICAgICByYW5nZUJvdHRvbSwKICAgICAgICAgICAgICAgICAgICByYW5nZUVuZCwKICAgICAgICAgICAgICAgICAgICBtZWFzdXJlTm9kZSwKICAgICAgICAgICAgICAgICAgICBpLAogICAgICAgICAgICAgICAgICAgIGo7CgogICAgICAgICAgICAgICAgaWYgKCFyYW5nZS5tb3ZlVG9Qb2ludCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAocmFuZ2VUb3AgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAvLyBEb24ndCBrbm93IHdoeSwgYnV0IHdoZW4gdGhlIHNlbGVjdGlvbiBlbmRzIGF0IHRoZSBlbmQgb2YgYSBsaW5lCiAgICAgICAgICAgICAgICAgICAgLy8gcmFuZ2UuYm91bmRpbmdUb3AgaXMgMAogICAgICAgICAgICAgICAgICAgIG1lYXN1cmVOb2RlID0gdGhpcy5kb2MuY3JlYXRlRWxlbWVudCgic3BhbiIpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0Tm9kZShtZWFzdXJlTm9kZSk7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2VUb3AgPSBtZWFzdXJlTm9kZS5vZmZzZXRUb3A7CiAgICAgICAgICAgICAgICAgICAgbWVhc3VyZU5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChtZWFzdXJlTm9kZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmFuZ2VUb3AgKz0gMTsKCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAtMTA7CiAgICAgICAgICAgICAgICAgICAgIGkgPCBzY3JvbGxXaWR0aDsKICAgICAgICAgICAgICAgICAgICAgaSArPSAyKSB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UubW92ZVRvUG9pbnQoaSwgcmFuZ2VUb3ApOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlMSkgewogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBJbnZlc3RpZ2F0ZSB0aGUgZm9sbG93aW5nIGluIG9yZGVyIHRvIGhhbmRsZSBtdWx0aSBsaW5lIHNlbGVjdGlvbnMKICAgICAgICAgICAgICAgIHJhbmdlQm90dG9tID0gcmFuZ2VUb3AgKyAocmFuZ2VIZWlnaHQgPyAocmFuZ2VIZWlnaHQgLSAxKSA6IDApOwogICAgICAgICAgICAgICAgLy9yYW5nZUJvdHRvbSA9IHJhbmdlVG9wOwogICAgICAgICAgICAgICAgcmFuZ2VFbmQgPSB0aGlzLmRvYy5zZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTsKICAgICAgICAgICAgICAgIGZvciAoaiA9IHNjcm9sbFdpZHRoOwogICAgICAgICAgICAgICAgICAgICBqID49IDA7CiAgICAgICAgICAgICAgICAgICAgIGotLSkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlRW5kLm1vdmVUb1BvaW50KGosIHJhbmdlQm90dG9tKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZTIpIHsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmFuZ2Uuc2V0RW5kUG9pbnQoIkVuZFRvRW5kIiwgcmFuZ2VFbmQpOwogICAgICAgICAgICAgICAgcmFuZ2Uuc2VsZWN0KCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRUZXh0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGlvbiA9IHRoaXMuZ2V0U2VsZWN0aW9uKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0aW9uID8gc2VsZWN0aW9uLnRvU3RyaW5nKCkgOiAiIjsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGdldE5vZGVzIDogZnVuY3Rpb24gKG5vZGVUeXBlLCBmaWx0ZXIpIHsKICAgICAgICAgICAgICAgIHZhciByYW5nZSA9IHRoaXMuZ2V0UmFuZ2UoKTsKICAgICAgICAgICAgICAgIGlmIChyYW5nZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiByYW5nZS5nZXROb2Rlcyhbbm9kZVR5cGVdLCBmaWx0ZXIpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gW107CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRSYW5nZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3Rpb24gPSB0aGlzLmdldFNlbGVjdGlvbigpOwogICAgICAgICAgICAgICAgLyogQ2hlY2sgaWYgdGhlIGZvY3VzTm9kZSBpcyBlZGl0b3IgZGl2IGVsZW1lbnQgb3IgaXRzIGNoaWxkCiAgICAgICAgICAgICAgICAqICBGb3IgSUUsIG9uIHNlbGVjdGluZyB0ZXh0IHdpdGggQ3RybCtBIHRoZSBmb2N1cyBub2RlIGlzIGVkaXRvciBub2RlICovCiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0aW9uICYmIHNlbGVjdGlvbi5yYW5nZUNvdW50ICYmICh0aGlzLmNvbXBvc2VyLmNvbnRhaW5lciA9PT0gc2VsZWN0aW9uLmZvY3VzTm9kZSB8fCAkKHRoaXMuY29tcG9zZXIuY29udGFpbmVyKS5oYXMoc2VsZWN0aW9uLmZvY3VzTm9kZSkubGVuZ3RoID4gMCkgJiYgc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRTZWxlY3Rpb24gOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcmFuZ3kuZ2V0U2VsZWN0aW9uKHRoaXMuZG9jLmRlZmF1bHRWaWV3IHx8IHRoaXMuZG9jLnBhcmVudFdpbmRvdyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGdldEN1cnJlbnRSYW5nZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3Rpb24gPSByYW5neS5nZXRTZWxlY3Rpb25XaXRob3V0UmVmZXJzaCh0aGlzLmRvYy5kZWZhdWx0VmlldyB8fCB0aGlzLmRvYy5wYXJlbnRXaW5kb3cpOwogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGlvbiAmJiBzZWxlY3Rpb24ucmFuZ2VDb3VudCAmJiBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHNldFNlbGVjdGlvbiA6IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgICAgICAgICAgdmFyIHdpbiA9IHRoaXMuZG9jLmRlZmF1bHRWaWV3IHx8IHRoaXMuZG9jLnBhcmVudFdpbmRvdywKICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb24gPSByYW5neS5nZXRTZWxlY3Rpb24od2luKTsKICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3Rpb24uc2V0U2luZ2xlUmFuZ2UocmFuZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBJbnNwaXJlZCBieSB0aGUgcmFuZ3kgQ1NTIEFwcGxpZXIgbW9kdWxlIHdyaXR0ZW4gYnkgVGltIERvd24gYW5kIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS4KICogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Jhbmd5LwogKgogKiBjaGFuZ2VkIGluIG9yZGVyIHRvIGJlIGFibGUgLi4uCiAqICAgIC0gdG8gdXNlIGN1c3RvbSB0YWdzCiAqICAgIC0gdG8gZGV0ZWN0IGFuZCByZXBsYWNlIHNpbWlsYXIgY3NzIGNsYXNzZXMgdmlhIHJlZyBleHAKICovCihmdW5jdGlvbiAod3lzaWh0bWw1LCByYW5neSkgewogICAgdmFyIGRlZmF1bHRUYWdOYW1lID0gInNwYW4iOwoKICAgIHZhciBSRUdfRVhQX1dISVRFX1NQQUNFID0gL1xzKy9nOwoKICAgIGZ1bmN0aW9uIGhhc0NsYXNzKGVsLCBjc3NDbGFzcywgcmVnRXhwKSB7CiAgICAgICAgaWYgKCFlbC5jbGFzc05hbWUpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgdmFyIG1hdGNoaW5nQ2xhc3NOYW1lcyA9IGVsLmNsYXNzTmFtZS5tYXRjaChyZWdFeHApIHx8IFtdOwogICAgICAgIHJldHVybiBtYXRjaGluZ0NsYXNzTmFtZXNbbWF0Y2hpbmdDbGFzc05hbWVzLmxlbmd0aCAtIDFdID09PSBjc3NDbGFzczsKICAgIH0KCiAgICBmdW5jdGlvbiBoYXNBdHRyaWJ1dGUoZWwsIGF0dHJpYnV0ZXMpIHsKICAgICAgICBpZiAoZWwubm9kZVR5cGUgPT0gd3lzaWh0bWw1LlRFWFRfTk9ERSB8fCBlbC5ub2RlVHlwZSA9PSA5KSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgdmFyIHN0ID0gZWwuZ2V0QXR0cmlidXRlKCJzdHlsZSIpOwogICAgICAgIGlmICghc3QpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmb3IgKHZhciBhdHRyaWJ1dGUgaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICBpZiAoZWwuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShhdHRyaWJ1dGUpKSB7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudEF0dHJpYnV0ZVZhbHVlID0gZWwuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShhdHRyaWJ1dGUpLnJlcGxhY2UoL3B4LywgIiIpOwogICAgICAgICAgICAgICAgY3VycmVudEF0dHJpYnV0ZVZhbHVlID0gY3VycmVudEF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoL3B0LywgIiIpOwogICAgICAgICAgICAgICAgY3VycmVudEF0dHJpYnV0ZVZhbHVlID0gY3VycmVudEF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoL1siJ10vZywgIiIpOwogICAgICAgICAgICAgICAgdmFyIG5ld0F0dHJpYnV0ZVZhbHVlID0gYXR0cmlidXRlc1thdHRyaWJ1dGVdID8gYXR0cmlidXRlc1thdHRyaWJ1dGVdLnJlcGxhY2UoL3B4LywgIiIpIDogbnVsbDsKICAgICAgICAgICAgICAgIG5ld0F0dHJpYnV0ZVZhbHVlID0gbmV3QXR0cmlidXRlVmFsdWUgPyBuZXdBdHRyaWJ1dGVWYWx1ZS5yZXBsYWNlKC9wdC8sICIiKSA6IG51bGw7CiAgICAgICAgICAgICAgICBpZiAobmV3QXR0cmlidXRlVmFsdWUgIT0gbnVsbCAmJiBjdXJyZW50QXR0cmlidXRlVmFsdWUgPT0gbmV3QXR0cmlidXRlVmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWF0dHJpYnV0ZXNbYXR0cmlidXRlXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRDbGFzcyhlbCwgY3NzQ2xhc3MsIHJlZ0V4cCkgewogICAgICAgIGlmIChlbC5jbGFzc05hbWUpIHsKICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoZWwsIHJlZ0V4cCk7CiAgICAgICAgICAgIGVsLmNsYXNzTmFtZSArPSAiICIgKyBjc3NDbGFzczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbC5jbGFzc05hbWUgPSBjc3NDbGFzczsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gYWRkQXR0cmlidXRlKGVsLCBhdHRyaWJ1dGVzLCBjbGVhclByZVN0eWxlKSB7CiAgICAgICAgaWYgKGNsZWFyUHJlU3R5bGUgJiYgZWwpIHsKICAgICAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCJzdHlsZSIpOwogICAgICAgIH0KICAgICAgICBpZiAoYXR0cmlidXRlcyAhPSBudWxsKSB7CiAgICAgICAgICAgIGZvciAoYXR0cmlidXRlIGluIGF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICAgIGlmIChlbC5zdHlsZSkgewogICAgICAgICAgICAgICAgICAgIGVsLnN0eWxlLnJlbW92ZVByb3BlcnR5KGF0dHJpYnV0ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgc3QgPSBlbC5nZXRBdHRyaWJ1dGUoJ3N0eWxlJyk7CiAgICAgICAgICAgICAgICBpZiAoc3QgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IHN0LmluZGV4T2YoYXR0cmlidXRlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlID09ICJjb2xvciIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogSWYgc3BhbiBoYWQgImJhY2tncm91bmQtY29sb3IiIGluIHN0eWxlIGFuZCB3ZSBzZWFyY2ggZm9yICJjb2xvciIgdGhlbiBpdCByZXR1cm5zIHRoZSBpbmRleCBvZiBjb2xvcgogICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2ggaXMgcHJlc2VudCBpbiAiYmFja2dyb3VuZC1jb2xvciIgc3RyaW5nLiBCZWNhdXNlIG9mIHRoaXMgYmFja2dyb3VuZC1jb2xvciB3aGljaCB3YXMgYXBwbGllZCBlYXJsaWVyIHdhcyBsb3N0LgogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgc3QgPSBzdC5yZXBsYWNlKCJiYWNrZ3JvdW5kLWNvbG9yIiwgImJhY2tncm91bmQtY3VzdG9tY2xyIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gc3QuaW5kZXhPZihhdHRyaWJ1dGUpOwogICAgICAgICAgICAgICAgICAgICAgICBzdCA9IHN0LnJlcGxhY2UoImJhY2tncm91bmQtY3VzdG9tY2xyIiwgImJhY2tncm91bmQtY29sb3IiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID49IDApIHsvLyBDb250YWlucyBjdXN0b20gU3R5bGUgYXR0cmlidXRlIHRyeSByZW1vdmUgaWYgYWxyZWFkeSBleGlzdHMgYW5kIGV4ZWNwZXRpbmcgY3VzdG9tIGF0dHJpYnV0ZSB0byBjb250YWluIHZhbHVlIHRydWUKICAgICAgICAgICAgICAgICAgICAgICAgc3QgPSBzdC5zdWJzdHIoMCwgaW5kZXgpICsgc3Quc3Vic3RyKGluZGV4ICsgYXR0cmlidXRlLmxlbmd0aCArIDYpOyAvLyBhZGRpbmcgKzYgY2hhcmN0ZXIgYXMgd2UgZXhlY3BldGluZyBjdXN0b20gYXR0cmlidXRlIHZhbHVlIHRvIHRydWUgb3IgZmFsc2UgZW5kIHdpdGggOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgYXR0cmlidXRlICsgIjoiICsgYXR0cmlidXRlc1thdHRyaWJ1dGVdICsgIjsiICsgc3QpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgYXR0cmlidXRlICsgIjoiICsgYXR0cmlidXRlc1thdHRyaWJ1dGVdICsgIjsiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBhZGREYXRhQXR0cmlidXRlKGVsLCBhdHRyaWJ1dGVzLCBjbGVhclByZURhdGFBdHRyKSB7CiAgICAgICAgaWYgKGVsKSB7CiAgICAgICAgICAgIGlmIChjbGVhclByZURhdGFBdHRyICYmICQoZWwpLmRhdGEoKSkgewogICAgICAgICAgICAgICAgdmFyIGRhdGEgPSAkKGVsKS5kYXRhKCk7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gZGF0YSkgewogICAgICAgICAgICAgICAgICAgICQoZWwpLnJlbW92ZURhdGEoa2V5KTsKICAgICAgICAgICAgICAgICAgICAkKGVsKS5yZW1vdmVBdHRyKCJkYXRhLSIgKyBrZXkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAodmFyIGF0dHJpYnV0ZSBpbiBhdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICAkKGVsKS5kYXRhKGF0dHJpYnV0ZSwgYXR0cmlidXRlc1thdHRyaWJ1dGVdKTsKICAgICAgICAgICAgICAgICQoZWwpLmF0dHIoJ2RhdGEtJyArIGF0dHJpYnV0ZSwgYXR0cmlidXRlc1thdHRyaWJ1dGVdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiByZW1vdmVDbGFzcyhlbCwgcmVnRXhwKSB7CiAgICAgICAgaWYgKGVsLmNsYXNzTmFtZSkgewogICAgICAgICAgICBlbC5jbGFzc05hbWUgPSBlbC5jbGFzc05hbWUucmVwbGFjZShyZWdFeHAsICIiKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gaGFzU2FtZUNsYXNzZXMoZWwxLCBlbDIpIHsKICAgICAgICByZXR1cm4gZWwxLmNsYXNzTmFtZS5yZXBsYWNlKFJFR19FWFBfV0hJVEVfU1BBQ0UsICIgIikgPT0gZWwyLmNsYXNzTmFtZS5yZXBsYWNlKFJFR19FWFBfV0hJVEVfU1BBQ0UsICIgIik7CiAgICB9CgogICAgZnVuY3Rpb24gcmVwbGFjZVdpdGhPd25DaGlsZHJlbihlbCkgewogICAgICAgIHZhciBwYXJlbnQgPSBlbC5wYXJlbnROb2RlOwogICAgICAgIHdoaWxlIChlbC5maXJzdENoaWxkKSB7CiAgICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoZWwuZmlyc3RDaGlsZCwgZWwpOwogICAgICAgIH0KICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoZWwpOwogICAgfQoKICAgIGZ1bmN0aW9uIGVsZW1lbnRzSGF2ZVNhbWVOb25DbGFzc0F0dHJpYnV0ZXMoZWwxLCBlbDIpIHsKICAgICAgICBpZiAoZWwxLmF0dHJpYnV0ZXMubGVuZ3RoICE9IGVsMi5hdHRyaWJ1dGVzLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBlbDEuYXR0cmlidXRlcy5sZW5ndGgsIGF0dHIxLCBhdHRyMiwgbmFtZTsKICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgYXR0cjEgPSBlbDEuYXR0cmlidXRlc1tpXTsKICAgICAgICAgICAgbmFtZSA9IGF0dHIxLm5hbWU7CiAgICAgICAgICAgIGlmIChuYW1lICE9ICJjbGFzcyIpIHsKICAgICAgICAgICAgICAgIGF0dHIyID0gZWwyLmF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKG5hbWUpOwogICAgICAgICAgICAgICAgaWYgKGF0dHIxLnNwZWNpZmllZCAhPSBhdHRyMi5zcGVjaWZpZWQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoYXR0cjEuc3BlY2lmaWVkICYmIGF0dHIxLm5vZGVWYWx1ZSAhPT0gYXR0cjIubm9kZVZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzU3BsaXRQb2ludChub2RlLCBvZmZzZXQpIHsKICAgICAgICBpZiAocmFuZ3kuZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUobm9kZSkpIHsKICAgICAgICAgICAgaWYgKG9mZnNldCA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gISFub2RlLnByZXZpb3VzU2libGluZzsKICAgICAgICAgICAgfSBlbHNlIGlmIChvZmZzZXQgPT0gbm9kZS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHJldHVybiAhIW5vZGUubmV4dFNpYmxpbmc7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG9mZnNldCA+IDAgJiYgb2Zmc2V0IDwgbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDsKICAgIH0KCiAgICBmdW5jdGlvbiBzcGxpdE5vZGVBdChub2RlLCBkZXNjZW5kYW50Tm9kZSwgZGVzY2VuZGFudE9mZnNldCkgewogICAgICAgIHZhciBuZXdOb2RlOwogICAgICAgIGlmIChyYW5neS5kb20uaXNDaGFyYWN0ZXJEYXRhTm9kZShkZXNjZW5kYW50Tm9kZSkpIHsKICAgICAgICAgICAgaWYgKGRlc2NlbmRhbnRPZmZzZXQgPT0gMCkgewogICAgICAgICAgICAgICAgZGVzY2VuZGFudE9mZnNldCA9IHJhbmd5LmRvbS5nZXROb2RlSW5kZXgoZGVzY2VuZGFudE5vZGUpOwogICAgICAgICAgICAgICAgZGVzY2VuZGFudE5vZGUgPSBkZXNjZW5kYW50Tm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICB9IGVsc2UgaWYgKGRlc2NlbmRhbnRPZmZzZXQgPT0gZGVzY2VuZGFudE5vZGUubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBkZXNjZW5kYW50T2Zmc2V0ID0gcmFuZ3kuZG9tLmdldE5vZGVJbmRleChkZXNjZW5kYW50Tm9kZSkgKyAxOwogICAgICAgICAgICAgICAgZGVzY2VuZGFudE5vZGUgPSBkZXNjZW5kYW50Tm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbmV3Tm9kZSA9IHJhbmd5LmRvbS5zcGxpdERhdGFOb2RlKGRlc2NlbmRhbnROb2RlLCBkZXNjZW5kYW50T2Zmc2V0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIW5ld05vZGUpIHsKICAgICAgICAgICAgbmV3Tm9kZSA9IGRlc2NlbmRhbnROb2RlLmNsb25lTm9kZShmYWxzZSk7CiAgICAgICAgICAgIGlmIChuZXdOb2RlLmlkKSB7CiAgICAgICAgICAgICAgICBuZXdOb2RlLnJlbW92ZUF0dHJpYnV0ZSgiaWQiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgY2hpbGQ7CiAgICAgICAgICAgIHdoaWxlICgoY2hpbGQgPSBkZXNjZW5kYW50Tm9kZS5jaGlsZE5vZGVzW2Rlc2NlbmRhbnRPZmZzZXRdKSkgewogICAgICAgICAgICAgICAgbmV3Tm9kZS5hcHBlbmRDaGlsZChjaGlsZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmFuZ3kuZG9tLmluc2VydEFmdGVyKG5ld05vZGUsIGRlc2NlbmRhbnROb2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChkZXNjZW5kYW50Tm9kZSA9PSBub2RlKSA/IG5ld05vZGUgOiBzcGxpdE5vZGVBdChub2RlLCBuZXdOb2RlLnBhcmVudE5vZGUsIHJhbmd5LmRvbS5nZXROb2RlSW5kZXgobmV3Tm9kZSkpOwogICAgfQoKICAgIGZ1bmN0aW9uIE1lcmdlKGZpcnN0Tm9kZSkgewogICAgICAgIHRoaXMuaXNFbGVtZW50TWVyZ2UgPSAoZmlyc3ROb2RlLm5vZGVUeXBlID09IHd5c2lodG1sNS5FTEVNRU5UX05PREUpOwogICAgICAgIHRoaXMuZmlyc3RUZXh0Tm9kZSA9IHRoaXMuaXNFbGVtZW50TWVyZ2UgPyBmaXJzdE5vZGUubGFzdENoaWxkIDogZmlyc3ROb2RlOwogICAgICAgIHRoaXMudGV4dE5vZGVzID0gW3RoaXMuZmlyc3RUZXh0Tm9kZV07CiAgICB9CgogICAgTWVyZ2UucHJvdG90eXBlID0gewogICAgICAgIGRvTWVyZ2UgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciB0ZXh0Qml0cyA9IFtdLCB0ZXh0Tm9kZSwgcGFyZW50LCB0ZXh0OwogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gdGhpcy50ZXh0Tm9kZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZSA9IHRoaXMudGV4dE5vZGVzW2ldOwogICAgICAgICAgICAgICAgcGFyZW50ID0gdGV4dE5vZGUucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgIHRleHRCaXRzW2ldID0gdGV4dE5vZGUuZGF0YTsKICAgICAgICAgICAgICAgIGlmIChpKSB7CiAgICAgICAgICAgICAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKHRleHROb2RlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXBhcmVudC5oYXNDaGlsZE5vZGVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQocGFyZW50KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5maXJzdFRleHROb2RlLmRhdGEgPSB0ZXh0ID0gdGV4dEJpdHMuam9pbigiIik7CiAgICAgICAgICAgIHJldHVybiB0ZXh0OwogICAgICAgIH0sCgogICAgICAgIGdldExlbmd0aCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGkgPSB0aGlzLnRleHROb2Rlcy5sZW5ndGgsIGxlbiA9IDA7CiAgICAgICAgICAgIHdoaWxlIChpLS0pIHsKICAgICAgICAgICAgICAgIGxlbiArPSB0aGlzLnRleHROb2Rlc1tpXS5sZW5ndGg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGxlbjsKICAgICAgICB9LAoKICAgICAgICB0b1N0cmluZyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHRleHRCaXRzID0gW107CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB0aGlzLnRleHROb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgIHRleHRCaXRzW2ldID0gIiciICsgdGhpcy50ZXh0Tm9kZXNbaV0uZGF0YSArICInIjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gIltNZXJnZSgiICsgdGV4dEJpdHMuam9pbigiLCIpICsgIildIjsKICAgICAgICB9CiAgICB9OwoKICAgIGZ1bmN0aW9uIEhUTUxBcHBsaWVyKHRhZ05hbWVzLCBjc3NDbGFzcywgc2ltaWxhckNsYXNzUmVnRXhwLCBub3JtYWxpemUsIGF0dHJpYnV0ZXMsIGNsZWFyUHJlU3R5bGUsIGRhdGFBdHRyaWJ1dGVzLCBjbGVhclByZURhdGFBdHRyKSB7CiAgICAgICAgdGhpcy50YWdOYW1lcyA9IHRhZ05hbWVzIHx8IFtkZWZhdWx0VGFnTmFtZV07CiAgICAgICAgdGhpcy5jc3NDbGFzcyA9IGNzc0NsYXNzIHx8ICIiOwogICAgICAgIHRoaXMuc2ltaWxhckNsYXNzUmVnRXhwID0gc2ltaWxhckNsYXNzUmVnRXhwOwogICAgICAgIHRoaXMubm9ybWFsaXplID0gbm9ybWFsaXplOwogICAgICAgIHRoaXMuYXBwbHlUb0FueVRhZ05hbWUgPSBmYWxzZTsKICAgICAgICB0aGlzLmF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzOwogICAgICAgIHRoaXMuY2xlYXJQcmVTdHlsZSA9IGNsZWFyUHJlU3R5bGU7CiAgICAgICAgdGhpcy5kYXRhQXR0cmlidXRlcyA9IGRhdGFBdHRyaWJ1dGVzOwogICAgICAgIHRoaXMuY2xlYXJQcmVEYXRhQXR0ciA9IGNsZWFyUHJlRGF0YUF0dHI7CiAgICB9CgogICAgSFRNTEFwcGxpZXIucHJvdG90eXBlID0gewogICAgICAgIGdldEFuY2VzdG9yV2l0aENsYXNzQW5kQXR0cmlidXRlIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgdmFyIGNzc0NsYXNzTWF0Y2g7CgogICAgICAgICAgICB3aGlsZSAobm9kZSkgewogICAgICAgICAgICAgICAgY3NzQ2xhc3NNYXRjaCA9IHRoaXMuY3NzQ2xhc3MgPyBoYXNDbGFzcyhub2RlLCB0aGlzLmNzc0NsYXNzLCB0aGlzLnNpbWlsYXJDbGFzc1JlZ0V4cCkgOiB0cnVlOwogICAgICAgICAgICAgICAgdmFyIHRleHROb2RlID0gbm9kZTsKICAgICAgICAgICAgICAgIGlmICgodGV4dE5vZGUubm9kZVR5cGUgPT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERSkgJiYgdGhpcy5hdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB0aGlzLmF0dHJpYnV0ZXM7CiAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZU1hdGNoID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBhdHRyaWJ1dGUgaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cmlidXRlVmFsdWUgPSB0ZXh0Tm9kZS5zdHlsZVthdHRyaWJ1dGVdOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlVmFsdWUgIT0gYXR0cmlidXRlc1thdHRyaWJ1dGVdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVNYXRjaCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVNYXRjaCA9IHRoaXMuYXR0cmlidXRlcyA/IGF0dHJpYnV0ZU1hdGNoIDogdHJ1ZTsKCiAgICAgICAgICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSB3eXNpaHRtbDUuRUxFTUVOVF9OT0RFICYmIHJhbmd5LmRvbS5hcnJheUNvbnRhaW5zKHRoaXMudGFnTmFtZXMsIG5vZGUudGFnTmFtZS50b0xvd2VyQ2FzZSgpKSAmJiBjc3NDbGFzc01hdGNoICYmIGF0dHJpYnV0ZU1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAogICAgICAgIGdldEFuY2VzdG9yIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgaWYgKHRoaXMuYXR0cmlidXRlcyB8fCB0aGlzLmRhdGFBdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBbmNlc3RvcldpdGhBdHRyaWJ1dGVzKG5vZGUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QW5jZXN0b3JXaXRoQ2xhc3Mobm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGdldEFuY2VzdG9yV2l0aEF0dHJpYnV0ZXMgOiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlc01hdGNoOwogICAgICAgICAgICBpZiAoIXRoaXMuYXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHdoaWxlIChub2RlKSB7CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzTWF0Y2ggPSB0aGlzLmF0dHJpYnV0ZXMgPyBoYXNBdHRyaWJ1dGUobm9kZSwgdGhpcy5hdHRyaWJ1dGVzKSA6IHRydWU7CiAgICAgICAgICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSB3eXNpaHRtbDUuRUxFTUVOVF9OT0RFICYmIChyYW5neS5kb20uYXJyYXlDb250YWlucyh0aGlzLnRhZ05hbWVzLCBub2RlLnRhZ05hbWUudG9Mb3dlckNhc2UoKSkgfHwgd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKG5vZGUpKSAmJiBhdHRyaWJ1dGVzTWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChub2RlICYmIG5vZGUuc3R5bGUgJiYgdGhpcy5hdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJFeGlzdHMgPSBub2RlLnN0eWxlLmdldFByb3BlcnR5VmFsdWUoKE9iamVjdC5rZXlzKHRoaXMuYXR0cmlidXRlcykpWzBdKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ckV4aXN0cykgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKICAgICAgICBnZXRBbmNlc3RvcldpdGhDbGFzcyA6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgIHZhciBjc3NDbGFzc01hdGNoOwoKICAgICAgICAgICAgd2hpbGUgKG5vZGUpIHsKICAgICAgICAgICAgICAgIGNzc0NsYXNzTWF0Y2ggPSB0aGlzLmNzc0NsYXNzID8gaGFzQ2xhc3Mobm9kZSwgdGhpcy5jc3NDbGFzcywgdGhpcy5zaW1pbGFyQ2xhc3NSZWdFeHApIDogdHJ1ZTsKICAgICAgICAgICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IHd5c2lodG1sNS5FTEVNRU5UX05PREUgJiYgcmFuZ3kuZG9tLmFycmF5Q29udGFpbnModGhpcy50YWdOYW1lcywgbm9kZS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpICYmIGNzc0NsYXNzTWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIC8vIE5vcm1hbGl6ZXMgbm9kZXMgYWZ0ZXIgYXBwbHlpbmcgYSBDU1MgY2xhc3MgdG8gYSBSYW5nZS4KICAgICAgICBwb3N0QXBwbHkgOiBmdW5jdGlvbiAodGV4dE5vZGVzLCByYW5nZSwgdGV4dE5vZGVOYW1lcykgewogICAgICAgICAgICB2YXIgZmlyc3ROb2RlID0gdGV4dE5vZGVzWzBdLCBsYXN0Tm9kZSA9IHRleHROb2Rlc1t0ZXh0Tm9kZXMubGVuZ3RoIC0gMV07CgogICAgICAgICAgICB2YXIgbWVyZ2VzID0gW10sIGN1cnJlbnRNZXJnZTsKCiAgICAgICAgICAgIHZhciByYW5nZVN0YXJ0Tm9kZSA9IGZpcnN0Tm9kZSwgcmFuZ2VFbmROb2RlID0gbGFzdE5vZGU7CiAgICAgICAgICAgIHZhciByYW5nZVN0YXJ0T2Zmc2V0ID0gMCwgcmFuZ2VFbmRPZmZzZXQgPSBsYXN0Tm9kZS5sZW5ndGg7CgogICAgICAgICAgICB2YXIgdGV4dE5vZGUsIHByZWNlZGluZ1RleHROb2RlOwoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRleHROb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgIHRleHROb2RlID0gdGV4dE5vZGVzW2ldOwogICAgICAgICAgICAgICAgcHJlY2VkaW5nVGV4dE5vZGUgPSB0aGlzLmdldEFkamFjZW50TWVyZ2VhYmxlVGV4dE5vZGUodGV4dE5vZGUucGFyZW50Tm9kZSwgZmFsc2UsIHRleHROb2RlTmFtZXMpOwogICAgICAgICAgICAgICAgaWYgKHByZWNlZGluZ1RleHROb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFjdXJyZW50TWVyZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE1lcmdlID0gbmV3IE1lcmdlKHByZWNlZGluZ1RleHROb2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgbWVyZ2VzLnB1c2goY3VycmVudE1lcmdlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY3VycmVudE1lcmdlLnRleHROb2Rlcy5wdXNoKHRleHROb2RlKTsKICAgICAgICAgICAgICAgICAgICBpZiAodGV4dE5vZGUgPT09IGZpcnN0Tm9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICByYW5nZVN0YXJ0Tm9kZSA9IGN1cnJlbnRNZXJnZS5maXJzdFRleHROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICByYW5nZVN0YXJ0T2Zmc2V0ID0gcmFuZ2VTdGFydE5vZGUubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAodGV4dE5vZGUgPT09IGxhc3ROb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlRW5kTm9kZSA9IGN1cnJlbnRNZXJnZS5maXJzdFRleHROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICByYW5nZUVuZE9mZnNldCA9IGN1cnJlbnRNZXJnZS5nZXRMZW5ndGgoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNZXJnZSA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFRlc3Qgd2hldGhlciB0aGUgZmlyc3Qgbm9kZSBhZnRlciB0aGUgcmFuZ2UgbmVlZHMgbWVyZ2luZwogICAgICAgICAgICB2YXIgbmV4dFRleHROb2RlID0gdGhpcy5nZXRBZGphY2VudE1lcmdlYWJsZVRleHROb2RlKGxhc3ROb2RlLnBhcmVudE5vZGUsIHRydWUpOwogICAgICAgICAgICBpZiAobmV4dFRleHROb2RlKSB7CiAgICAgICAgICAgICAgICBpZiAoIWN1cnJlbnRNZXJnZSkgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNZXJnZSA9IG5ldyBNZXJnZShsYXN0Tm9kZSk7CiAgICAgICAgICAgICAgICAgICAgbWVyZ2VzLnB1c2goY3VycmVudE1lcmdlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJlbnRNZXJnZS50ZXh0Tm9kZXMucHVzaChuZXh0VGV4dE5vZGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBEbyB0aGUgbWVyZ2VzCiAgICAgICAgICAgIGlmIChtZXJnZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBtZXJnZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZXNbaV0uZG9NZXJnZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gU2V0IHRoZSByYW5nZSBib3VuZGFyaWVzCiAgICAgICAgICAgICAgICByYW5nZS5zZXRTdGFydChyYW5nZVN0YXJ0Tm9kZSwgcmFuZ2VTdGFydE9mZnNldCk7CiAgICAgICAgICAgICAgICByYW5nZS5zZXRFbmQocmFuZ2VFbmROb2RlLCByYW5nZUVuZE9mZnNldCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBnZXRBZGphY2VudE1lcmdlYWJsZVRleHROb2RlIDogZnVuY3Rpb24gKG5vZGUsIGZvcndhcmQsIHRleHROb2RlTmFtZXMpIHsKICAgICAgICAgICAgdmFyIGlzVGV4dE5vZGUgPSAobm9kZS5ub2RlVHlwZSA9PSB3eXNpaHRtbDUuVEVYVF9OT0RFKTsKICAgICAgICAgICAgdmFyIGVsID0gaXNUZXh0Tm9kZSA/IG5vZGUucGFyZW50Tm9kZSA6IG5vZGU7CiAgICAgICAgICAgIHZhciBhZGphY2VudE5vZGU7CiAgICAgICAgICAgIHZhciBwcm9wTmFtZSA9IGZvcndhcmQgPyAibmV4dFNpYmxpbmciIDogInByZXZpb3VzU2libGluZyI7CiAgICAgICAgICAgIGlmIChpc1RleHROb2RlKSB7CiAgICAgICAgICAgICAgICAvLyBDYW4gbWVyZ2UgaWYgdGhlIG5vZGUncyBwcmV2aW91cy9uZXh0IHNpYmxpbmcgaXMgYSB0ZXh0IG5vZGUKICAgICAgICAgICAgICAgIGFkamFjZW50Tm9kZSA9IG5vZGVbcHJvcE5hbWVdOwogICAgICAgICAgICAgICAgaWYgKGFkamFjZW50Tm9kZSAmJiBhZGphY2VudE5vZGUubm9kZVR5cGUgPT0gd3lzaWh0bWw1LlRFWFRfTk9ERSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhZGphY2VudE5vZGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBDb21wYXJlIGVsZW1lbnQgd2l0aCBpdHMgc2libGluZwogICAgICAgICAgICAgICAgYWRqYWNlbnROb2RlID0gZWxbcHJvcE5hbWVdOwogICAgICAgICAgICAgICAgaWYgKGFkamFjZW50Tm9kZSAmJiB0aGlzLmFyZUVsZW1lbnRzTWVyZ2VhYmxlKG5vZGUsIGFkamFjZW50Tm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZSA9IGFkamFjZW50Tm9kZVtmb3J3YXJkID8gImZpcnN0Q2hpbGQiIDogImxhc3RDaGlsZCJdOwogICAgICAgICAgICAgICAgICAgIGlmICghdGV4dE5vZGVOYW1lcyB8fCB0ZXh0Tm9kZU5hbWVzLmluZGV4T2Yobm9kZS5ub2RlTmFtZSkgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICBhcmVFbGVtZW50c01lcmdlYWJsZSA6IGZ1bmN0aW9uIChlbDEsIGVsMikgewogICAgICAgICAgICByZXR1cm4gcmFuZ3kuZG9tLmFycmF5Q29udGFpbnModGhpcy50YWdOYW1lcywgKGVsMS50YWdOYW1lIHx8ICIiKS50b0xvd2VyQ2FzZSgpKSAmJiByYW5neS5kb20uYXJyYXlDb250YWlucyh0aGlzLnRhZ05hbWVzLCAoZWwyLnRhZ05hbWUgfHwgIiIpLnRvTG93ZXJDYXNlKCkpICYmIGhhc1NhbWVDbGFzc2VzKGVsMSwgZWwyKSAmJiBlbGVtZW50c0hhdmVTYW1lTm9uQ2xhc3NBdHRyaWJ1dGVzKGVsMSwgZWwyKTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVDb250YWluZXIgOiBmdW5jdGlvbiAoZG9jKSB7CiAgICAgICAgICAgIHZhciBlbCA9IGRvYy5jcmVhdGVFbGVtZW50KHRoaXMudGFnTmFtZXNbMF0pOwogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHRoaXMuYXR0cmlidXRlczsKICAgICAgICAgICAgdmFyIGRhdGFBdHRyaWJ1dGVzID0gdGhpcy5kYXRhQXR0cmlidXRlczsKICAgICAgICAgICAgaWYgKHRoaXMuY3NzQ2xhc3MpIHsKICAgICAgICAgICAgICAgIGVsLmNsYXNzTmFtZSA9IHRoaXMuY3NzQ2xhc3M7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIGF0dHJpYnV0ZSBpbiBhdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICBlbC5zdHlsZS5yZW1vdmVQcm9wZXJ0eShhdHRyaWJ1dGUpOwogICAgICAgICAgICAgICAgdmFyIHN0ID0gZWwuZ2V0QXR0cmlidXRlKCdzdHlsZScpOwogICAgICAgICAgICAgICAgaWYgKHN0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgYXR0cmlidXRlICsgIjoiICsgYXR0cmlidXRlc1thdHRyaWJ1dGVdICsgIjsiICsgc3QpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgYXR0cmlidXRlICsgIjoiICsgYXR0cmlidXRlc1thdHRyaWJ1dGVdICsgIjsiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGF0dHJpYnV0ZSBpbiBkYXRhQXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgJChlbCkuZGF0YShhdHRyaWJ1dGUsIGRhdGFBdHRyaWJ1dGVzW2F0dHJpYnV0ZV0pOwogICAgICAgICAgICAgICAgJChlbCkuYXR0cignZGF0YS0nICsgYXR0cmlidXRlLCBkYXRhQXR0cmlidXRlc1thdHRyaWJ1dGVdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZWw7CiAgICAgICAgfSwKCiAgICAgICAgYXBwbHlUb1RleHROb2RlIDogZnVuY3Rpb24gKHRleHROb2RlKSB7CiAgICAgICAgICAgIHZhciBwYXJlbnQgPSB0ZXh0Tm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICBpZiAocGFyZW50LmNoaWxkTm9kZXMubGVuZ3RoID09IDEgJiYgcmFuZ3kuZG9tLmFycmF5Q29udGFpbnModGhpcy50YWdOYW1lcywgcGFyZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSkpIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmNzc0NsYXNzKSB7CiAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MocGFyZW50LCB0aGlzLmNzc0NsYXNzLCB0aGlzLnNpbWlsYXJDbGFzc1JlZ0V4cCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhZGRBdHRyaWJ1dGUocGFyZW50LCB0aGlzLmF0dHJpYnV0ZXMsIHRoaXMuY2xlYXJQcmVTdHlsZSk7CiAgICAgICAgICAgICAgICBhZGREYXRhQXR0cmlidXRlKHBhcmVudCwgdGhpcy5kYXRhQXR0cmlidXRlcywgdGhpcy5jbGVhclByZURhdGFBdHRyKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBlbCA9IHRoaXMuY3JlYXRlQ29udGFpbmVyKHJhbmd5LmRvbS5nZXREb2N1bWVudCh0ZXh0Tm9kZSkpOwogICAgICAgICAgICAgICAgdGV4dE5vZGUucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZWwsIHRleHROb2RlKTsKICAgICAgICAgICAgICAgIGVsLmFwcGVuZENoaWxkKHRleHROb2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGlzUmVtb3ZhYmxlIDogZnVuY3Rpb24gKGVsKSB7CiAgICAgICAgICAgIHJldHVybiByYW5neS5kb20uYXJyYXlDb250YWlucyh0aGlzLnRhZ05hbWVzLCBlbC50YWdOYW1lLnRvTG93ZXJDYXNlKCkpICYmIHd5c2lodG1sNS5sYW5nLnN0cmluZyhlbC5jbGFzc05hbWUpLnRyaW0oKSA9PSB0aGlzLmNzc0NsYXNzOwogICAgICAgIH0sCgogICAgICAgIHVuZG9Ub1RleHROb2RlIDogZnVuY3Rpb24gKHRleHROb2RlLCByYW5nZSwgYW5jZXN0b3JXaXRoQ2xhc3MpIHsKICAgICAgICAgICAgaWYgKCFyYW5nZS5jb250YWluc05vZGUoYW5jZXN0b3JXaXRoQ2xhc3MpKSB7CiAgICAgICAgICAgICAgICAvLyBTcGxpdCBvdXQgdGhlIHBvcnRpb24gb2YgdGhlIGFuY2VzdG9yIGZyb20gd2hpY2ggd2UgY2FuIHJlbW92ZSB0aGUgQ1NTIGNsYXNzCiAgICAgICAgICAgICAgICB2YXIgYW5jZXN0b3JSYW5nZSA9IHJhbmdlLmNsb25lUmFuZ2UoKTsKICAgICAgICAgICAgICAgIGFuY2VzdG9yUmFuZ2Uuc2VsZWN0Tm9kZShhbmNlc3RvcldpdGhDbGFzcyk7CgogICAgICAgICAgICAgICAgaWYgKGFuY2VzdG9yUmFuZ2UuaXNQb2ludEluUmFuZ2UocmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpICYmIGlzU3BsaXRQb2ludChyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCkpIHsKICAgICAgICAgICAgICAgICAgICBzcGxpdE5vZGVBdChhbmNlc3RvcldpdGhDbGFzcywgcmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpOwogICAgICAgICAgICAgICAgICAgIHJhbmdlLnNldEVuZEFmdGVyKGFuY2VzdG9yV2l0aENsYXNzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChhbmNlc3RvclJhbmdlLmlzUG9pbnRJblJhbmdlKHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydE9mZnNldCkgJiYgaXNTcGxpdFBvaW50KHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydE9mZnNldCkpIHsKICAgICAgICAgICAgICAgICAgICBhbmNlc3RvcldpdGhDbGFzcyA9IHNwbGl0Tm9kZUF0KGFuY2VzdG9yV2l0aENsYXNzLCByYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5zaW1pbGFyQ2xhc3NSZWdFeHApIHsKICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKGFuY2VzdG9yV2l0aENsYXNzLCB0aGlzLnNpbWlsYXJDbGFzc1JlZ0V4cCk7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBhdHRyaWJ1dGUgaW4gdGhpcy5hdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3JXaXRoQ2xhc3Muc3R5bGUucmVtb3ZlUHJvcGVydHkoYXR0cmlidXRlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhpcy5pc1JlbW92YWJsZShhbmNlc3RvcldpdGhDbGFzcykpIHsKICAgICAgICAgICAgICAgIHJlcGxhY2VXaXRoT3duQ2hpbGRyZW4oYW5jZXN0b3JXaXRoQ2xhc3MpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgYXBwbHlUb1JhbmdlIDogZnVuY3Rpb24gKHJhbmdlLCBjb21wb3NlcikgewogICAgICAgICAgICB2YXIgYXBwbGllZCA9IHRoaXMuaGFuZGxlTGlzdFNlbGVjdGlvbihyYW5nZSwgY29tcG9zZXIpOwogICAgICAgICAgICB2YXIgdGV4dE5vZGVzID0gcmFuZ2UuZ2V0Tm9kZXMoW3d5c2lodG1sNS5URVhUX05PREVdKTsKICAgICAgICAgICAgaWYgKCF0ZXh0Tm9kZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHZhciBub2RlID0gdGhpcy5jcmVhdGVDb250YWluZXIocmFuZ2UuZW5kQ29udGFpbmVyLm93bmVyRG9jdW1lbnQpOwogICAgICAgICAgICAgICAgICAgIHJhbmdlLnN1cnJvdW5kQ29udGVudHMobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3ROb2RlKHJhbmdlLCBub2RlKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJhbmdlLnNwbGl0Qm91bmRhcmllcygpOwogICAgICAgICAgICB0ZXh0Tm9kZXMgPSByYW5nZS5nZXROb2Rlcyhbd3lzaWh0bWw1LlRFWFRfTk9ERV0pOwoKICAgICAgICAgICAgaWYgKHRleHROb2Rlcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHZhciB0ZXh0Tm9kZU5hbWVzID0gW107CiAgICAgICAgICAgICAgICBpZiAoY29tcG9zZXIuY29uZmlnLnBhcnNlclJ1bGVzICYmIGNvbXBvc2VyLmNvbmZpZy5wYXJzZXJSdWxlcy50ZXh0Tm9kZXMpIHsKICAgICAgICAgICAgICAgICAgICB0ZXh0Tm9kZU5hbWVzID0gY29tcG9zZXIuY29uZmlnLnBhcnNlclJ1bGVzLnRleHROb2RlczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciB0ZXh0Tm9kZTsKCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gdGV4dE5vZGVzLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgdGV4dE5vZGUgPSB0ZXh0Tm9kZXNbaV07CiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudEVsID0gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KHRleHROb2RlLCB7bm9kZU5hbWUgOiB0ZXh0Tm9kZU5hbWVzfSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudEVsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRleHROb2RlID0gcGFyZW50RWw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5nZXRBbmNlc3Rvcih0ZXh0Tm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBseVRvVGV4dE5vZGUodGV4dE5vZGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0KHRleHROb2Rlc1swXSwgMCk7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZSA9IHRleHROb2Rlc1t0ZXh0Tm9kZXMubGVuZ3RoIC0gMV07CiAgICAgICAgICAgICAgICByYW5nZS5zZXRFbmQodGV4dE5vZGUsIHRleHROb2RlLmxlbmd0aCk7CgogICAgICAgICAgICAgICAgaWYgKHRoaXMubm9ybWFsaXplKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3N0QXBwbHkodGV4dE5vZGVzLCByYW5nZSwgdGV4dE5vZGVOYW1lcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYW5kbGVMaXN0U2VsZWN0aW9uIDogZnVuY3Rpb24gKHJhbmdlLCBjb21wb3NlcikgewogICAgICAgICAgICBub2RlTGlzdCA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXROb2RlcygzKTsKICAgICAgICAgICAgdmFyIGhhbmRsZWRMaXN0U2VsZWN0aW9uID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChub2RlTGlzdC5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOwogICAgICAgICAgICAgICAgICAgICBpIDwgbm9kZUxpc3QubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZUxpc3RbaV07CiAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICBpZiAoKG5vZGUubm9kZU5hbWUgPT0gIkxJIikgJiYgKGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRUZXh0KCkudHJpbSgpID09IG5vZGUudGV4dENvbnRlbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlLmNoaWxkTm9kZXMubGVuZ3RoID09IDEgJiYgcmFuZ3kuZG9tLmFycmF5Q29udGFpbnModGhpcy50YWdOYW1lcywgbm9kZS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jc3NDbGFzcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKG5vZGUsIHRoaXMuY3NzQ2xhc3MsIHRoaXMuc2ltaWxhckNsYXNzUmVnRXhwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZEF0dHJpYnV0ZShub2RlLCB0aGlzLmF0dHJpYnV0ZXMsIHRoaXMuY2xlYXJQcmVTdHlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGREYXRhQXR0cmlidXRlKHBhcmVudCwgdGhpcy5kYXRhQXR0cmlidXRlcywgdGhpcy5jbGVhclByZURhdGFBdHRyKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCF3eXNpaHRtbDUudXRpbC5pc0VkaXRvck5vZGUobm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCEobm9kZS5ub2RlTmFtZSA9PSAiTEkiKSAmJiAhd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKG5vZGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5wYXJlbnRFbGVtZW50OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobm9kZS50ZXh0Q29udGVudCAmJiBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0VGV4dCgpLnRyaW0oKS5pbmRleE9mKG5vZGUudGV4dENvbnRlbnQudHJpbSgpKSA+IC0xKSAmJiAhd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKG5vZGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jc3NDbGFzcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKG5vZGUsIHRoaXMuY3NzQ2xhc3MsIHRoaXMuc2ltaWxhckNsYXNzUmVnRXhwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZEF0dHJpYnV0ZShub2RlLCB0aGlzLmF0dHJpYnV0ZXMsIHRoaXMuY2xlYXJQcmVTdHlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGREYXRhQXR0cmlidXRlKHBhcmVudCwgdGhpcy5kYXRhQXR0cmlidXRlcywgdGhpcy5jbGVhclByZURhdGFBdHRyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZWRMaXN0U2VsZWN0aW9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3RlZE5vZGUgPSBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKCk7CiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWROb2RlICYmIHNlbGVjdGVkTm9kZSAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoIShzZWxlY3RlZE5vZGUubm9kZU5hbWUgPT0gIkxJIikgJiYgIXd5c2lodG1sNS51dGlsLmlzRWRpdG9yTm9kZShzZWxlY3RlZE5vZGUpICYmIHNlbGVjdGVkTm9kZS5ub2RlTmFtZSAhPSAiI3RleHQiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IHNlbGVjdGVkTm9kZS5wYXJlbnRFbGVtZW50OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvL0NRLTQyMjU2MTQKICAgICAgICAgICAgICAgICAgICBpZiAoY29tcG9zZXIuc2VsZWN0aW9uLmdldFRleHQoKS50cmltKCkuaW5kZXhPZihzZWxlY3RlZE5vZGUudGV4dENvbnRlbnQpID4gLTEgJiYgIXd5c2lodG1sNS51dGlsLmlzRWRpdG9yTm9kZShzZWxlY3RlZE5vZGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNzc0NsYXNzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhzZWxlY3RlZE5vZGUsIHRoaXMuY3NzQ2xhc3MsIHRoaXMuc2ltaWxhckNsYXNzUmVnRXhwKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBhZGRBdHRyaWJ1dGUoc2VsZWN0ZWROb2RlLCB0aGlzLmF0dHJpYnV0ZXMsIHRoaXMuY2xlYXJQcmVTdHlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkZERhdGFBdHRyaWJ1dGUocGFyZW50LCB0aGlzLmRhdGFBdHRyaWJ1dGVzLCB0aGlzLmNsZWFyUHJlRGF0YUF0dHIpOwogICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVkTGlzdFNlbGVjdGlvbiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBoYW5kbGVkTGlzdFNlbGVjdGlvbjsKICAgICAgICB9LAoKICAgICAgICB1bmRvVG9SYW5nZSA6IGZ1bmN0aW9uIChyYW5nZSwgY29tcG9zZXIpIHsKICAgICAgICAgICAgdmFyIHRleHROb2RlcyA9IHJhbmdlLmdldE5vZGVzKFt3eXNpaHRtbDUuVEVYVF9OT0RFXSksIHRleHROb2RlLCBhbmNlc3RvcldpdGhDbGFzczsKICAgICAgICAgICAgaWYgKHRleHROb2Rlcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHJhbmdlLnNwbGl0Qm91bmRhcmllcygpOwogICAgICAgICAgICAgICAgdGV4dE5vZGVzID0gcmFuZ2UuZ2V0Tm9kZXMoW3d5c2lodG1sNS5URVhUX05PREVdKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBkb2MgPSByYW5nZS5lbmRDb250YWluZXIub3duZXJEb2N1bWVudCwKICAgICAgICAgICAgICAgICAgICBub2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKHd5c2lodG1sNS5JTlZJU0lCTEVfU1BBQ0UpOwogICAgICAgICAgICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZShub2RlKTsKICAgICAgICAgICAgICAgIHJhbmdlLnNlbGVjdE5vZGUobm9kZSk7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZXMgPSBbbm9kZV07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB0ZXh0Tm9kZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZSA9IHRleHROb2Rlc1tpXTsKICAgICAgICAgICAgICAgIGFuY2VzdG9yV2l0aENsYXNzID0gdGhpcy5nZXRBbmNlc3Rvcih0ZXh0Tm9kZSk7CiAgICAgICAgICAgICAgICBpZiAoYW5jZXN0b3JXaXRoQ2xhc3MpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVuZG9Ub1RleHROb2RlKHRleHROb2RlLCByYW5nZSwgYW5jZXN0b3JXaXRoQ2xhc3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAobGVuID09IDEpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0Tm9kZShyYW5nZSwgdGV4dE5vZGVzWzBdKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0KHRleHROb2Rlc1swXSwgMCk7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZSA9IHRleHROb2Rlc1t0ZXh0Tm9kZXMubGVuZ3RoIC0gMV07CiAgICAgICAgICAgICAgICByYW5nZS5zZXRFbmQodGV4dE5vZGUsIHRleHROb2RlLmxlbmd0aCk7CgogICAgICAgICAgICAgICAgaWYgKHRoaXMubm9ybWFsaXplKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3N0QXBwbHkodGV4dE5vZGVzLCByYW5nZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBzZWxlY3ROb2RlIDogZnVuY3Rpb24gKHJhbmdlLCBub2RlKSB7CiAgICAgICAgICAgIHZhciBpc0VsZW1lbnQgPSBub2RlLm5vZGVUeXBlID09PSB3eXNpaHRtbDUuRUxFTUVOVF9OT0RFLAogICAgICAgICAgICAgICAgY2FuSGF2ZUhUTUwgPSAiY2FuSGF2ZUhUTUwiIGluIG5vZGUgPyBub2RlLmNhbkhhdmVIVE1MIDogdHJ1ZSwKICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBpc0VsZW1lbnQgPyBub2RlLmlubmVySFRNTCA6IG5vZGUuZGF0YSwKICAgICAgICAgICAgICAgIGlzRW1wdHkgPSAoY29udGVudCA9PT0gIiIgfHwgY29udGVudCA9PT0gd3lzaWh0bWw1LklOVklTSUJMRV9TUEFDRSk7CgogICAgICAgICAgICBpZiAoaXNFbXB0eSAmJiBpc0VsZW1lbnQgJiYgY2FuSGF2ZUhUTUwpIHsKICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IGNhcmV0IGlzIHZpc2libGUgaW4gbm9kZSBieSBpbnNlcnRpbmcgYSB6ZXJvIHdpZHRoIG5vIGJyZWFraW5nIHNwYWNlCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIG5vZGUuaW5uZXJIVE1MID0gd3lzaWh0bWw1LklOVklTSUJMRV9TUEFDRTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHMobm9kZSk7CiAgICAgICAgICAgIGlmIChpc0VtcHR5ICYmIGlzRWxlbWVudCkgewogICAgICAgICAgICAgICAgcmFuZ2UuY29sbGFwc2UoZmFsc2UpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGlzRW1wdHkpIHsKICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobm9kZSk7CiAgICAgICAgICAgICAgICByYW5nZS5zZXRFbmRBZnRlcihub2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGdldFRleHRTZWxlY3RlZEJ5UmFuZ2UgOiBmdW5jdGlvbiAodGV4dE5vZGUsIHJhbmdlKSB7CiAgICAgICAgICAgIHZhciB0ZXh0UmFuZ2UgPSByYW5nZS5jbG9uZVJhbmdlKCk7CiAgICAgICAgICAgIHRleHRSYW5nZS5zZWxlY3ROb2RlQ29udGVudHModGV4dE5vZGUpOwoKICAgICAgICAgICAgdmFyIGludGVyc2VjdGlvblJhbmdlID0gdGV4dFJhbmdlLmludGVyc2VjdGlvbihyYW5nZSk7CiAgICAgICAgICAgIHZhciB0ZXh0ID0gaW50ZXJzZWN0aW9uUmFuZ2UgPyBpbnRlcnNlY3Rpb25SYW5nZS50b1N0cmluZygpIDogIiI7CiAgICAgICAgICAgIHRleHRSYW5nZS5kZXRhY2goKTsKCiAgICAgICAgICAgIHJldHVybiB0ZXh0OwogICAgICAgIH0sCgogICAgICAgIGlzQXBwbGllZFRvUmFuZ2VCeUNsYXNzQW5kQXR0cmlidXRlIDogZnVuY3Rpb24gKHJhbmdlKSB7CgogICAgICAgICAgICB2YXIgdGV4dE5vZGVzID0gcmFuZ2UuZ2V0Tm9kZXMoW3d5c2lodG1sNS5URVhUX05PREVdKTsKICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB0aGlzLmF0dHJpYnV0ZXM7CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVWYWx1ZSA9IG5ldyBBcnJheSgpOwogICAgICAgICAgICBpZiAodGV4dE5vZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgdmFyIHRleHROb2RlOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRleHROb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgICAgIHRleHROb2RlID0gdGV4dE5vZGVzW2ldOwogICAgICAgICAgICAgICAgICAgIHdoaWxlICghd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKHRleHROb2RlKSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dE5vZGUgPSB0ZXh0Tm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgaiA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGF0dHJpYnV0ZSBpbiBhdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZVZhbHVlW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRleHROb2RlLnN0eWxlLmdldFByb3BlcnR5VmFsdWUoYXR0cmlidXRlKSA9PSBhdHRyaWJ1dGVzW2F0dHJpYnV0ZV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlVmFsdWVbaisrXSA9ICJ0cnVlIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGF0YUF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoYXR0cmlidXRlIGluIHRoaXMuZGF0YUF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZVZhbHVlW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkKHRleHROb2RlKS5kYXRhKGF0dHJpYnV0ZSkgPT0gdGhpcy5kYXRhQXR0cmlidXRlc1thdHRyaWJ1dGVdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVWYWx1ZVtqKytdID0gInRydWUiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBpID0gMDsKICAgICAgICAgICAgZm9yIChhdHRyaWJ1dGUgaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgaWYgKCFhdHRyaWJ1dGVWYWx1ZVtpKytdKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBhbmNlc3RvcnMgPSBbXSwKICAgICAgICAgICAgICAgIGFuY2VzdG9yLAogICAgICAgICAgICAgICAgdGV4dE5vZGVzID0gcmFuZ2UuZ2V0Tm9kZXMoW3d5c2lodG1sNS5URVhUX05PREVdKTsKICAgICAgICAgICAgaWYgKCF0ZXh0Tm9kZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBhbmNlc3RvciA9IHRoaXMuZ2V0QW5jZXN0b3JXaXRoQXR0cmlidXRlcyhyYW5nZS5zdGFydENvbnRhaW5lcik7CiAgICAgICAgICAgICAgICByZXR1cm4gYW5jZXN0b3IgPyBbYW5jZXN0b3JdIDogZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB0ZXh0Tm9kZXMubGVuZ3RoLCBzZWxlY3RlZFRleHQ7CiAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgIHNlbGVjdGVkVGV4dCA9IHRoaXMuZ2V0VGV4dFNlbGVjdGVkQnlSYW5nZSh0ZXh0Tm9kZXNbaV0sIHJhbmdlKTsKICAgICAgICAgICAgICAgIGFuY2VzdG9yID0gdGhpcy5nZXRBbmNlc3RvcldpdGhBdHRyaWJ1dGVzKHRleHROb2Rlc1tpXSk7CiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWRUZXh0ICE9ICIiICYmICFhbmNlc3RvcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3JzLnB1c2goYW5jZXN0b3IpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBhbmNlc3RvcnM7CiAgICAgICAgfSwKCiAgICAgICAgaXNBcHBsaWVkVG9SYW5nZSA6IGZ1bmN0aW9uIChyYW5nZSkgewoKICAgICAgICAgICAgdmFyIGFuY2VzdG9ycyA9IFtdLAogICAgICAgICAgICAgICAgYW5jZXN0b3IsCiAgICAgICAgICAgICAgICB0ZXh0Tm9kZXMgPSByYW5nZS5nZXROb2Rlcyhbd3lzaWh0bWw1LlRFWFRfTk9ERV0pOwogICAgICAgICAgICBpZiAoIXRleHROb2Rlcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIGFuY2VzdG9yID0gdGhpcy5nZXRBbmNlc3RvcihyYW5nZS5zdGFydENvbnRhaW5lcik7CiAgICAgICAgICAgICAgICByZXR1cm4gYW5jZXN0b3IgPyBbYW5jZXN0b3JdIDogZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB0ZXh0Tm9kZXMubGVuZ3RoLCBzZWxlY3RlZFRleHQ7CiAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgIHNlbGVjdGVkVGV4dCA9IHRoaXMuZ2V0VGV4dFNlbGVjdGVkQnlSYW5nZSh0ZXh0Tm9kZXNbaV0sIHJhbmdlKTsKICAgICAgICAgICAgICAgIGFuY2VzdG9yID0gdGhpcy5nZXRBbmNlc3Rvcih0ZXh0Tm9kZXNbaV0pOwogICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkVGV4dCAhPSAiIiAmJiAhYW5jZXN0b3IpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGFuY2VzdG9ycy5wdXNoKGFuY2VzdG9yKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYW5jZXN0b3JzOwogICAgICAgIH0sCgogICAgICAgIHRvZ2dsZVJhbmdlIDogZnVuY3Rpb24gKHJhbmdlLCBjb21wb3NlcikgewogICAgICAgICAgICB2YXIgaXNBcHBseSA9IGZhbHNlOwogICAgICAgICAgICBpZiAodGhpcy5hdHRyaWJ1dGVzIHx8IHRoaXMuZGF0YUF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICAgIGlzQXBwbHkgPSB0aGlzLmlzQXBwbGllZFRvUmFuZ2VCeUNsYXNzQW5kQXR0cmlidXRlKHJhbmdlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlzQXBwbHkgPSB0aGlzLmlzQXBwbGllZFRvUmFuZ2UocmFuZ2UpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNBcHBseSkgewogICAgICAgICAgICAgICAgdGhpcy51bmRvVG9SYW5nZShyYW5nZSwgY29tcG9zZXIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5hcHBseVRvUmFuZ2UocmFuZ2UsIGNvbXBvc2VyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgd3lzaWh0bWw1LnNlbGVjdGlvbi5IVE1MQXBwbGllciA9IEhUTUxBcHBsaWVyOwp9KSh3eXNpaHRtbDUsIHJhbmd5KTsKLyoqCiAqIFJpY2ggVGV4dCBRdWVyeS9Gb3JtYXR0aW5nIENvbW1hbmRzCiAqCiAqIEBleGFtcGxlCiAqICAgIHZhciBjb21tYW5kcyA9IG5ldyB3eXNpaHRtbDUuQ29tbWFuZHMoZWRpdG9yKTsKICovCnd5c2lodG1sNS5Db21tYW5kcyA9IEJhc2UuZXh0ZW5kKAogICAgLyoqIEBzY29wZSB3eXNpaHRtbDUuQ29tbWFuZHMucHJvdG90eXBlICovIHsKICAgICAgICBjb25zdHJ1Y3RvciA6IGZ1bmN0aW9uIChlZGl0b3IpIHsKICAgICAgICAgICAgdGhpcy5lZGl0b3IgPSBlZGl0b3I7CiAgICAgICAgICAgIHRoaXMuY29tcG9zZXIgPSBlZGl0b3IuY29tcG9zZXI7CiAgICAgICAgICAgIHRoaXMuZG9jID0gdGhpcy5jb21wb3Nlci5kb2M7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2sgd2hldGhlciB0aGUgYnJvd3NlciBzdXBwb3J0cyB0aGUgZ2l2ZW4gY29tbWFuZAogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGNvbW1hbmQgVGhlIGNvbW1hbmQgc3RyaW5nIHdoaWNoIHRvIGNoZWNrIChlZy4gImJvbGQiLCAiaXRhbGljIiwgImluc2VydFVub3JkZXJlZExpc3QiKQogICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICogICAgY29tbWFuZHMuc3VwcG9ydHMoImNyZWF0ZUxpbmsiKTsKICAgICAgICAgKi8KICAgICAgICBzdXBwb3J0IDogZnVuY3Rpb24gKGNvbW1hbmQpIHsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5icm93c2VyLnN1cHBvcnRzQ29tbWFuZCh0aGlzLmRvYywgY29tbWFuZCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2sgd2hldGhlciB0aGUgYnJvd3NlciBzdXBwb3J0cyB0aGUgZ2l2ZW4gY29tbWFuZAogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGNvbW1hbmQgVGhlIGNvbW1hbmQgc3RyaW5nIHdoaWNoIHRvIGV4ZWN1dGUgKGVnLiAiYm9sZCIsICJpdGFsaWMiLCAiaW5zZXJ0VW5vcmRlcmVkTGlzdCIpCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IFt2YWx1ZV0gVGhlIGNvbW1hbmQgdmFsdWUgcGFyYW1ldGVyLCBuZWVkZWQgZm9yIHNvbWUgY29tbWFuZHMgKCJjcmVhdGVMaW5rIiwgImluc2VydEltYWdlIiwgLi4uKSwgb3B0aW9uYWwgZm9yIGNvbW1hbmRzIHRoYXQgZG9uJ3QgcmVxdWlyZSBvbmUgKCJib2xkIiwgInVuZGVybGluZSIsIC4uLikKICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAqICAgIGNvbW1hbmRzLmV4ZWMoImluc2VydEltYWdlIiwgImh0dHA6Ly9hMS50d2ltZy5jb20vcHJvZmlsZV9pbWFnZXMvMTEzODY4NjU1L3NjaHJlaV90d2l0dGVyX3JlYXNvbmFibHlfc21hbGwuanBnIik7CiAgICAgICAgICovCiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21tYW5kLCB2YWx1ZSwgYWxsb3dVbmRvKSB7CiAgICAgICAgICAgIHZhciBvYmogPSB3eXNpaHRtbDUuY29tbWFuZHNbY29tbWFuZF0sCiAgICAgICAgICAgICAgICBhcmdzID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoYXJndW1lbnRzKS5nZXQoKSwKICAgICAgICAgICAgICAgIG1ldGhvZCA9IG9iaiAmJiBvYmouZXhlYywKICAgICAgICAgICAgICAgIGZvY3VzID0gb2JqICYmIG9iai5mb2N1cywKICAgICAgICAgICAgICAgIHJlc3VsdCA9IG51bGw7CgogICAgICAgICAgICBpZiAoYWxsb3dVbmRvID09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgYWxsb3dVbmRvID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZm9jdXMgPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICBmb2N1cyA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChhbGxvd1VuZG8pIHsKICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yLmZpcmUoImJlZm9yZWNvbW1hbmQ6Y29tcG9zZXIiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG1ldGhvZCkgewogICAgICAgICAgICAgICAgYXJncy51bnNoaWZ0KHRoaXMuY29tcG9zZXIpOwogICAgICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgY29tcG9zZXIgaXMgZm9jdXNzZWQgKGZhbHNlID0+IGRvbid0IG1vdmUgY2FyZXQgdG8gdGhlIGVuZCkKICAgICAgICAgICAgICAgIHZhciByYW5nZSA9IHRoaXMuY29tcG9zZXIuc2VsZWN0aW9uLmdldFJhbmdlKCk7CiAgICAgICAgICAgICAgICBpZiAoZm9jdXMpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmVkaXRvci5mb2N1cyhmYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZm9jdXMgJiYgdGhpcy5lZGl0b3Iuc2F2ZWRTZWxlY3Rpb24gJiYgIXJhbmdlKSB7Ly8gRml4aW5nIExDLTM5MTE5OTQKICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyLnNlbGVjdGlvbi5zZXRTZWxlY3Rpb24odGhpcy5lZGl0b3Iuc2F2ZWRTZWxlY3Rpb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmVzdWx0ID0gbWV0aG9kLmFwcGx5KG9iaiwgYXJncyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIC8vIHRyeS9jYXRjaCBmb3IgYnVnZ3kgZmlyZWZveAogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRoaXMuZG9jLmV4ZWNDb21tYW5kKGNvbW1hbmQsIGZhbHNlLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuZWRpdG9yLmZpcmUoImFmdGVyY29tbWFuZDpjb21wb3NlciIpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrIHdoZXRoZXIgdGhlIGN1cnJlbnQgY29tbWFuZCBpcyBhY3RpdmUKICAgICAgICAgKiBJZiB0aGUgY2FyZXQgaXMgd2l0aGluIGEgYm9sZCB0ZXh0LCB0aGVuIGNhbGxpbmcgdGhpcyB3aXRoIGNvbW1hbmQgImJvbGQiIHNob3VsZCByZXR1cm4gdHJ1ZQogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGNvbW1hbmQgVGhlIGNvbW1hbmQgc3RyaW5nIHdoaWNoIHRvIGNoZWNrIChlZy4gImJvbGQiLCAiaXRhbGljIiwgImluc2VydFVub3JkZXJlZExpc3QiKQogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBbY29tbWFuZFZhbHVlXSBUaGUgY29tbWFuZCB2YWx1ZSBwYXJhbWV0ZXIgKGVnLiBmb3IgImluc2VydEltYWdlIiB0aGUgaW1hZ2Ugc3JjKQogICAgICAgICAqIEByZXR1cm4ge0Jvb2xlYW59IFdoZXRoZXIgdGhlIGNvbW1hbmQgaXMgYWN0aXZlCiAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgKiAgICB2YXIgaXNDdXJyZW50U2VsZWN0aW9uQm9sZCA9IGNvbW1hbmRzLnN0YXRlKCJib2xkIik7CiAgICAgICAgICovCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tbWFuZCwgY29tbWFuZFZhbHVlKSB7CiAgICAgICAgICAgIHZhciBvYmogPSB3eXNpaHRtbDUuY29tbWFuZHNbY29tbWFuZF0sCiAgICAgICAgICAgICAgICBhcmdzID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoYXJndW1lbnRzKS5nZXQoKSwKICAgICAgICAgICAgICAgIG1ldGhvZCA9IG9iaiAmJiBvYmouc3RhdGU7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmNhbGxTdGF0ZUZ1bmN0aW9uKG1ldGhvZCwgb2JqLCBhcmdzLCBjb21tYW5kKTsKICAgICAgICB9LAoKICAgICAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbW1hbmQsIGNvbW1hbmRWYWx1ZSwgaXNEZWZhdWx0KSB7CiAgICAgICAgICAgIHZhciBvYmogPSB3eXNpaHRtbDUuY29tbWFuZHNbY29tbWFuZF0sCiAgICAgICAgICAgICAgICBhcmdzID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoYXJndW1lbnRzKS5nZXQoKSwgbWV0aG9kOwogICAgICAgICAgICBpZiAob2JqICYmIG9iai5jYWxsYmFja1N0YXRlKSB7CiAgICAgICAgICAgICAgICBtZXRob2QgPSBvYmogJiYgb2JqLmNhbGxiYWNrU3RhdGU7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jYWxsU3RhdGVGdW5jdGlvbihtZXRob2QsIG9iaiwgYXJncywgY29tbWFuZCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZShjb21tYW5kLCBjb21tYW5kVmFsdWUsIGlzRGVmYXVsdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBjYWxsU3RhdGVGdW5jdGlvbiA6IGZ1bmN0aW9uIChtZXRob2QsIG9iaiwgYXJncywgY29tbWFuZCkgewogICAgICAgICAgICBpZiAobWV0aG9kKSB7CiAgICAgICAgICAgICAgICBhcmdzLnVuc2hpZnQodGhpcy5jb21wb3Nlcik7CiAgICAgICAgICAgICAgICByZXR1cm4gbWV0aG9kLmFwcGx5KG9iaiwgYXJncyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIC8vIHRyeS9jYXRjaCBmb3IgYnVnZ3kgZmlyZWZveAogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRvYy5xdWVyeUNvbW1hbmRTdGF0ZShjb21tYW5kKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKd3lzaWh0bWw1LmNvbW1hbmRzLmJvbGQgPSB7CiAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgImIiKTsKICAgIH0sCgogICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICAvLyBlbGVtZW50Lm93bmVyRG9jdW1lbnQucXVlcnlDb21tYW5kU3RhdGUoImJvbGQiKSByZXN1bHRzOgogICAgICAgIC8vIGZpcmVmb3g6IG9ubHkgPGI+CiAgICAgICAgLy8gY2hyb21lOiAgPGI+LCA8c3Ryb25nPiwgPGgxPiwgPGgyPiwgLi4uCiAgICAgICAgLy8gaWU6ICAgICAgPGI+LCA8c3Ryb25nPgogICAgICAgIC8vIG9wZXJhOiAgIDxiPiwgPHN0cm9uZz4KICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgImIiKTsKICAgIH0KfTsKCnd5c2lodG1sNS5jb21tYW5kcy5zdXBlclNjcmlwdCA9IHsKICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICB2YXIgZG9jID0gY29tcG9zZXIuZG9jLAogICAgICAgICAgICBzZWxlY3RlZE5vZGUgPSBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKCksCiAgICAgICAgICAgIHN1YnNjcmlwdCA9IHNlbGVjdGVkTm9kZS5wYXJlbnROb2RlLm5vZGVOYW1lOwogICAgICAgIGlmIChjb21wb3Nlci5jb21tYW5kcy5zdXBwb3J0KGNvbW1hbmQpKSB7CiAgICAgICAgICAgIGNvbXBvc2VyLmRvYy5leGVjQ29tbWFuZChjb21tYW5kLCBmYWxzZSwgbnVsbCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKHN1YnNjcmlwdCAmJiBzdWJzY3JpcHQgPT0gIlNVQiIpIHsKICAgICAgICAgICAgICAgIHZhciBlbCA9IGNvbXBvc2VyLnNlbGVjdGlvbi5leGVjdXRlQW5kUmVzdG9yZShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5yZW5hbWVFbGVtZW50KHNlbGVjdGVkTm9kZS5wYXJlbnROb2RlLCAic3VwIik7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgInN1cCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwKCiAgICBzdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAic3VwIik7CiAgICB9Cn07Cgp3eXNpaHRtbDUuY29tbWFuZHMuc3ViU2NyaXB0ID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgIHZhciBkb2MgPSBjb21wb3Nlci5kb2MsCiAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKSwKICAgICAgICAgICAgc3VwZXJzY3JpcHQgPSBzZWxlY3RlZE5vZGUucGFyZW50Tm9kZS5ub2RlTmFtZTsKICAgICAgICBpZiAoY29tcG9zZXIuY29tbWFuZHMuc3VwcG9ydChjb21tYW5kKSkgewogICAgICAgICAgICBjb21wb3Nlci5kb2MuZXhlY0NvbW1hbmQoY29tbWFuZCwgZmFsc2UsIG51bGwpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChzdXBlcnNjcmlwdCAmJiBzdXBlcnNjcmlwdCA9PSAiU1VQIikgewogICAgICAgICAgICAgICAgdmFyIGVsID0gY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUuZG9tLnJlbmFtZUVsZW1lbnQoc2VsZWN0ZWROb2RlLnBhcmVudE5vZGUsICJzdWIiKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5leGVjKGNvbXBvc2VyLCBjb21tYW5kLCAic3ViIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsICJzdWIiKTsKICAgIH0KfTsKCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgdW5kZWYsCiAgICAgICAgTk9ERV9OQU1FID0gIkEiLAogICAgICAgIGRvbSA9IHd5c2lodG1sNS5kb207CgogICAgZnVuY3Rpb24gX3JlbW92ZUZvcm1hdChjb21wb3NlciwgYW5jaG9ycykgewogICAgICAgIHZhciBsZW5ndGggPSBhbmNob3JzLmxlbmd0aCwKICAgICAgICAgICAgaSA9IDAsCiAgICAgICAgICAgIGFuY2hvciwKICAgICAgICAgICAgY29kZUVsZW1lbnQsCiAgICAgICAgICAgIHRleHRDb250ZW50OwogICAgICAgIGZvciAoOwogICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgYW5jaG9yID0gYW5jaG9yc1tpXTsKICAgICAgICAgICAgY29kZUVsZW1lbnQgPSBkb20uZ2V0UGFyZW50RWxlbWVudChhbmNob3IsIHtub2RlTmFtZSA6ICJjb2RlIn0pOwogICAgICAgICAgICB0ZXh0Q29udGVudCA9IGRvbS5nZXRUZXh0Q29udGVudChhbmNob3IpOwoKICAgICAgICAgICAgLy8gaWYgPGE+IGNvbnRhaW5zIHVybC1saWtlIHRleHQgY29udGVudCwgcmVuYW1lIGl0IHRvIDxjb2RlPiB0byBwcmV2ZW50IHJlLWF1dG9saW5raW5nCiAgICAgICAgICAgIC8vIGVsc2UgcmVwbGFjZSA8YT4gd2l0aCBpdHMgY2hpbGROb2RlcwogICAgICAgICAgICBpZiAodGV4dENvbnRlbnQubWF0Y2goZG9tLmF1dG9MaW5rLlVSTF9SRUdfRVhQKSAmJiAhY29kZUVsZW1lbnQpIHsKICAgICAgICAgICAgICAgIC8vIDxjb2RlPiBlbGVtZW50IGlzIHVzZWQgdG8gcHJldmVudCBsYXRlciBhdXRvLWxpbmtpbmcgb2YgdGhlIGNvbnRlbnQKICAgICAgICAgICAgICAgIGNvZGVFbGVtZW50ID0gZG9tLnJlbmFtZUVsZW1lbnQoYW5jaG9yLCAiY29kZSIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZG9tLnJlcGxhY2VXaXRoQ2hpbGROb2RlcyhhbmNob3IpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIF9mb3JtYXQoY29tcG9zZXIsIGF0dHJpYnV0ZXMpIHsKICAgICAgICB2YXIgZG9jID0gY29tcG9zZXIuZG9jLAogICAgICAgICAgICB0ZW1wQ2xhc3MgPSAiX3d5c2lodG1sNS10ZW1wLSIgKyAoK25ldyBEYXRlKCkpLAogICAgICAgICAgICB0ZW1wQ2xhc3NSZWdFeHAgPSAvbm9uLW1hdGNoaW5nLWNsYXNzL2csCiAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICBsZW5ndGgsCiAgICAgICAgICAgIGFuY2hvcnMsCiAgICAgICAgICAgIGFuY2hvciwKICAgICAgICAgICAgaGFzRWxlbWVudENoaWxkLAogICAgICAgICAgICBpc0VtcHR5LAogICAgICAgICAgICBlbGVtZW50VG9TZXRDYXJldEFmdGVyLAogICAgICAgICAgICB0ZXh0Q29udGVudCwKICAgICAgICAgICAgd2hpdGVTcGFjZSwKICAgICAgICAgICAgajsKICAgICAgICB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLmV4ZWMoY29tcG9zZXIsIHVuZGVmLCBOT0RFX05BTUUsIHRlbXBDbGFzcywgdGVtcENsYXNzUmVnRXhwKTsKCiAgICAgICAgdmFyIG5ld1RleHQgPSBudWxsOwogICAgICAgIGlmIChhdHRyaWJ1dGVzICYmIGF0dHJpYnV0ZXMuYWx0KSB7CiAgICAgICAgICAgIG5ld1RleHQgPSBhdHRyaWJ1dGVzLmFsdDsKICAgICAgICAgICAgZGVsZXRlIGF0dHJpYnV0ZXMuYWx0OwogICAgICAgIH0KCiAgICAgICAgYW5jaG9ycyA9IGRvYy5xdWVyeVNlbGVjdG9yQWxsKE5PREVfTkFNRSArICIuIiArIHRlbXBDbGFzcyk7CiAgICAgICAgbGVuZ3RoID0gYW5jaG9ycy5sZW5ndGg7CiAgICAgICAgZm9yICg7CiAgICAgICAgICAgIGkgPCBsZW5ndGg7CiAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICBhbmNob3IgPSBhbmNob3JzW2ldOwogICAgICAgICAgICBhbmNob3IucmVtb3ZlQXR0cmlidXRlKCJjbGFzcyIpOwogICAgICAgICAgICBmb3IgKGogaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgYW5jaG9yLnNldEF0dHJpYnV0ZShqLCBhdHRyaWJ1dGVzW2pdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobmV3VGV4dCkgewogICAgICAgICAgICAgICAgYW5jaG9yLnRleHQgPSBuZXdUZXh0OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBlbGVtZW50VG9TZXRDYXJldEFmdGVyID0gYW5jaG9yOwogICAgICAgIGlmIChsZW5ndGggPT09IDEpIHsKICAgICAgICAgICAgdGV4dENvbnRlbnQgPSBkb20uZ2V0VGV4dENvbnRlbnQoYW5jaG9yKTsKICAgICAgICAgICAgaGFzRWxlbWVudENoaWxkID0gISFhbmNob3IucXVlcnlTZWxlY3RvcigiKiIpOwogICAgICAgICAgICBpc0VtcHR5ID0gdGV4dENvbnRlbnQgPT09ICIiIHx8IHRleHRDb250ZW50ID09PSB3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFOwogICAgICAgICAgICBpZiAoIWhhc0VsZW1lbnRDaGlsZCAmJiBpc0VtcHR5KSB7CiAgICAgICAgICAgICAgICBkb20uc2V0VGV4dENvbnRlbnQoYW5jaG9yLCBhdHRyaWJ1dGVzLnRleHQgfHwgYW5jaG9yLmhyZWYpOwogICAgICAgICAgICAgICAgd2hpdGVTcGFjZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSgiICIpOwogICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLnNldEFmdGVyKGFuY2hvcik7CiAgICAgICAgICAgICAgICBkb20uaW5zZXJ0KHdoaXRlU3BhY2UpLmFmdGVyKGFuY2hvcik7CiAgICAgICAgICAgICAgICBlbGVtZW50VG9TZXRDYXJldEFmdGVyID0gd2hpdGVTcGFjZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2V0QWZ0ZXIoZWxlbWVudFRvU2V0Q2FyZXRBZnRlcik7CiAgICB9CgogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmNyZWF0ZUxpbmsgPSB7CiAgICAgICAgLyoqCiAgICAgICAgICogVE9ETzogVXNlIEhUTUxBcHBsaWVyIG9yIGZvcm1hdElubGluZSBoZXJlCiAgICAgICAgICoKICAgICAgICAgKiBUdXJucyBzZWxlY3Rpb24gaW50byBhIGxpbmsKICAgICAgICAgKiBJZiBzZWxlY3Rpb24gaXMgYWxyZWFkeSBhIGxpbmssIGl0IHJlbW92ZXMgdGhlIGxpbmsgYW5kIHdyYXBzIGl0IHdpdGggYSA8Y29kZT4gZWxlbWVudAogICAgICAgICAqIFRoZSA8Y29kZT4gZWxlbWVudCBpcyBuZWVkZWQgdG8gYXZvaWQgYXV0byBsaW5raW5nCiAgICAgICAgICoKICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAqICAgIC8vIGVpdGhlciAuLi4KICAgICAgICAgKiAgICB3eXNpaHRtbDUuY29tbWFuZHMuY3JlYXRlTGluay5leGVjKGNvbXBvc2VyLCAiY3JlYXRlTGluayIsICJodHRwOi8vd3d3Lmdvb2dsZS5kZSIpOwogICAgICAgICAqICAgIC8vIC4uLiBvciAuLi4KICAgICAgICAgKiAgICB3eXNpaHRtbDUuY29tbWFuZHMuY3JlYXRlTGluay5leGVjKGNvbXBvc2VyLCAiY3JlYXRlTGluayIsIHsgaHJlZjogImh0dHA6Ly93d3cuZ29vZ2xlLmRlIiwgdGFyZ2V0OiAiX2JsYW5rIiB9KTsKICAgICAgICAgKi8KICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCB2YWx1ZSwgYWx0LCB0YXJnZXQpIHsKICAgICAgICAgICAgdmFyIGFuY2hvcnMgPSB0aGlzLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kKTsKICAgICAgICAgICAgLy8gaWYgKGFuY2hvcnMpIHsKICAgICAgICAgICAgLy8gU2VsZWN0aW9uIGNvbnRhaW5zIGxpbmtzCiAgICAgICAgICAgIC8vICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uKCkgewogICAgICAgICAgICAvLyAgICAgX3JlbW92ZUZvcm1hdChjb21wb3NlciwgYW5jaG9ycyk7CiAgICAgICAgICAgIC8vICAgfSk7CiAgICAgICAgICAgIC8vIH0KICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gIm9iamVjdCIpIHsKICAgICAgICAgICAgICAgIGFsdCA9IHZhbHVlLmFsdDsKICAgICAgICAgICAgICAgIHRhcmdldCA9IHZhbHVlLnRhcmdldCA/ICJfdGFyZ2V0IiA6ICIiOwogICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS51cmw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgICAgICAoYW5jaG9ycyAmJiAoaSA8IGFuY2hvcnMubGVuZ3RoKSk7CiAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICB2YXIgYW5jaG9yID0gYW5jaG9yc1tpXTsKICAgICAgICAgICAgICAgIGFuY2hvci5ocmVmID0gdmFsdWU7CiAgICAgICAgICAgICAgICBhbmNob3IudGl0bGUgPSAiTGluazogIiArIHZhbHVlOwogICAgICAgICAgICAgICAgYW5jaG9yLmFsdCA9IGFsdDsKICAgICAgICAgICAgICAgIGFuY2hvci50YXJnZXQgPSB0YXJnZXQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFhbmNob3JzKSB7CiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgbGlua3MKICAgICAgICAgICAgICAgIHZhbHVlID0gdHlwZW9mKHZhbHVlKSA9PT0gIm9iamVjdCIgPyB2YWx1ZSA6IHtocmVmIDogdmFsdWUsIGFsdCA6IGFsdCwgdGFyZ2V0IDogdGFyZ2V0fTsKICAgICAgICAgICAgICAgIF9mb3JtYXQoY29tcG9zZXIsIHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAiQSIpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBkb2N1bWVudC5leGVjQ29tbWFuZCgiZm9udFNpemUiKSB3aWxsIGNyZWF0ZSBlaXRoZXIgaW5saW5lIHN0eWxlcyAoZmlyZWZveCwgY2hyb21lKSBvciB1c2UgZm9udCB0YWdzCiAqIHdoaWNoIHdlIGRvbid0IHdhbnQKICogSW5zdGVhZCB3ZSBzZXQgYSBjc3MgY2xhc3MKICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgdW5kZWYsCiAgICAgICAgUkVHX0VYUCA9IC9mb250LXNpemUvZzsKCiAgICB3eXNpaHRtbDUuY29tbWFuZHMuZm9udFNpemUgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgc2l6ZSkgewogICAgICAgICAgICBzaXplID0gc2l6ZSArICJwdCI7CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJmb250LXNpemUiIDogc2l6ZX07CiAgICAgICAgICAgIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAiZm9udC1zaXplIiwgUkVHX0VYUCwgYXR0cmlidXRlcyk7CiAgICAgICAgICAgIHZhciBkb21FbGVtID0gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdEJsb2NrLnN0YXRlKGNvbXBvc2VyLCAnbGluZUhlaWdodCcsIGF0dHJpYnV0ZXMpOwogICAgICAgICAgICB2YXIgbGVhZGluZzsKICAgICAgICAgICAgaWYgKGRvbUVsZW0gJiYgZG9tRWxlbS5nZXRBdHRyaWJ1dGUpIHsKICAgICAgICAgICAgICAgIGxlYWRpbmcgPSAoZG9tRWxlbSkuZ2V0QXR0cmlidXRlKCJsZWFkaW5nIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgd3lzaWh0bWw1LnV0aWwuY2hhbmdlTGluZUhlaWdodChsZWFkaW5nLCBmYWxzZSwgJ1AnLCBjb21wb3Nlcik7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIHNpemUpIHsKICAgICAgICAgICAgaWYgKHNpemUpIHsKICAgICAgICAgICAgICAgIHNpemUgPSBzaXplICsgInB0IjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiZm9udC1zaXplIiA6IHNpemV9OwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAiZm9udC1zaXplIiwgUkVHX0VYUCwgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKICAgICAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBzaXplKSB7CiAgICAgICAgICAgIHZhciBkb21FbGVtID0gdGhpcy5zdGF0ZShjb21wb3NlciwgY29tbWFuZCk7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IFtdOwogICAgICAgICAgICAvLyBkb21FbGVtZW50IGkuZSBTZWxlY3RlZCB0ZXh0IG5vZGVzIGV4aXN0CiAgICAgICAgICAgIGlmIChkb21FbGVtICYmIGRvbUVsZW0ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRvbUVsZW0ubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAvLyBnZXR0aW5nIGRpZmZlcmVudCBmb250IHNpemVzIGFwcGxpZWQgdG8gc2VsZWN0ZWQgdGV4dHMKICAgICAgICAgICAgICAgICAgICB2YXIgZm9udFNpemUgPSAgd3lzaWh0bWw1LmhlbHBlckZuLmdldFByb3BlcnR5VmFsdWUoZG9tRWxlbVtpXSwgImZvbnQtc2l6ZSIpOwogICAgICAgICAgICAgICAgICAgIC8vIGZvbnQgc2l6ZSBpcyBub3QgYWxyZWFkeSByZXRyaWV2ZWQgZnJvbSBzZWxlY3RlZCB0ZXh0cywgYWRkIGZvbnQgc2l6ZQogICAgICAgICAgICAgICAgICAgIGlmICghdmFsdWUuaW5jbHVkZXMoZm9udFNpemUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLnB1c2goZm9udFNpemUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgfSwKICAgICAgICB2YWx1ZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHVuZGVmOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBkb2N1bWVudC5leGVjQ29tbWFuZCgiICAgICIpIHdpbGwgY3JlYXRlIGVpdGhlciBpbmxpbmUgc3R5bGVzIChmaXJlZm94LCBjaHJvbWUpIG9yIHVzZSBmb250IHRhZ3MKICogd2hpY2ggd2UgZG9uJ3Qgd2FudAogKiBJbnN0ZWFkIHdlIHNldCBhIGNzcyBjbGFzcwogKi8KKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBSRUdfRVhQID0gL3d5c2l3eWctY29sb3ItWzAtOWEtel0rL2c7CgogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmZvcmVDb2xvciA9IHsKICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBjb2xvcikgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiY29sb3IiIDogY29sb3J9OwoKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAid3lzaXd5Zy1jb2xvci0iICsgY29sb3IsIFJFR19FWFAsIGF0dHJpYnV0ZXMpOwogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBjb2xvcikgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiY29sb3IiIDogY29sb3J9OwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAid3lzaXd5Zy1jb2xvci0iICsgY29sb3IsIFJFR19FWFAsIGF0dHJpYnV0ZXMpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgZG9tID0gd3lzaWh0bWw1LmRvbSwKICAgICAgICAvLyBGb2xsb3dpbmcgZWxlbWVudHMgYXJlIGdyb3VwZWQKICAgICAgICAvLyB3aGVuIHRoZSBjYXJldCBpcyB3aXRoaW4gYSBIMSBhbmQgdGhlIEg0IGlzIGludm9rZWQsIHRoZSBIMSBzaG91bGQgdHVybiBpbnRvIEg0CiAgICAgICAgLy8gaW5zdGVhZCBvZiBjcmVhdGluZyBhIEg0IHdpdGhpbiBhIEgxIHdoaWNoIHdvdWxkIHJlc3VsdCBpbiBzZW1hbnRpY2FsbHkgaW52YWxpZCBodG1sCiAgICAgICAgQkxPQ0tfRUxFTUVOVFNfR1JPVVAgPSBbIkgxIiwgIkgyIiwgIkgzIiwgIkg0IiwgIkg1IiwgIkg2IiwgIlAiLCAiQkxPQ0tRVU9URSIsICJESVYiXTsKCiAgICAvKioKICAgICAqIFJlbW92ZSBzaW1pbGlhciBjbGFzc2VzIChiYXNlZCBvbiBjbGFzc1JlZ0V4cCkKICAgICAqIGFuZCBhZGQgdGhlIGRlc2lyZWQgY2xhc3MgbmFtZQogICAgICovCiAgICBmdW5jdGlvbiBfYWRkQ2xhc3MoZWxlbWVudCwgY2xhc3NOYW1lLCBjbGFzc1JlZ0V4cCkgewogICAgICAgIGlmIChlbGVtZW50LmNsYXNzTmFtZSkgewogICAgICAgICAgICBfcmVtb3ZlQ2xhc3MoZWxlbWVudCwgY2xhc3NSZWdFeHApOwogICAgICAgICAgICBlbGVtZW50LmNsYXNzTmFtZSArPSAiICIgKyBjbGFzc05hbWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSBjbGFzc05hbWU7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIF9hZGRBdHRyaWJ1dGUoZWxlbWVudCkgewogICAgICAgIHZhciBhdHRyaWJ1dGVzID0gdGhpcy5hdHRyaWJ1dGVzOwogICAgICAgIGlmIChlbGVtZW50KSB7CiAgICAgICAgICAgIGlmICh0aGlzLmNsZWFyUHJlU3R5bGUpIHsKICAgICAgICAgICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCJzdHlsZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAodmFyIGF0dHJpYnV0ZSBpbiBhdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5zdHlsZSkgewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUucmVtb3ZlUHJvcGVydHkoYXR0cmlidXRlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciBzdCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdzdHlsZScpOwogICAgICAgICAgICAgICAgaWYgKHN0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnc3R5bGUnLCBhdHRyaWJ1dGUgKyAiOiIgKyBhdHRyaWJ1dGVzW2F0dHJpYnV0ZV0gKyAiOyIgKyBzdCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdzdHlsZScsIGF0dHJpYnV0ZSArICI6IiArIGF0dHJpYnV0ZXNbYXR0cmlidXRlXSArICI7Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZERhdGFBdHRyaWJ1dGUoZWxlbWVudCkgewogICAgICAgIGlmIChlbGVtZW50KSB7CiAgICAgICAgICAgIHZhciBkYXRhQXR0cmlidXRlcyA9IHRoaXMuZGF0YUF0dHJpYnV0ZXM7CiAgICAgICAgICAgIGlmICh0aGlzLmNsZWFyUHJlRGF0YUF0dHIgJiYgJChlbGVtZW50KS5kYXRhKCkpIHsKICAgICAgICAgICAgICAgIHZhciBkYXRhID0gJChlbGVtZW50KS5kYXRhKCk7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gZGF0YSkgewogICAgICAgICAgICAgICAgICAgICQoZWxlbWVudCkucmVtb3ZlRGF0YShrZXkpOwogICAgICAgICAgICAgICAgICAgICQoZWwpLnJlbW92ZUF0dHIoImRhdGEtIiArIGtleSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yICh2YXIgYXR0cmlidXRlIGluIGRhdGFBdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICAkKGVsZW1lbnQpLmRhdGEoYXR0cmlidXRlLCBhdHRyaWJ1dGVzW2F0dHJpYnV0ZV0pOwogICAgICAgICAgICAgICAgJChlbGVtZW50KS5hdHRyKCdkYXRhLScgKyBhdHRyaWJ1dGUsIGF0dHJpYnV0ZXNbYXR0cmlidXRlXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gX3JlbW92ZUNsYXNzKGVsZW1lbnQsIGNsYXNzUmVnRXhwKSB7CiAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50LmNsYXNzTmFtZS5yZXBsYWNlKGNsYXNzUmVnRXhwLCAiIik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayB3aGV0aGVyIGdpdmVuIG5vZGUgaXMgYSB0ZXh0IG5vZGUgYW5kIHdoZXRoZXIgaXQncyBlbXB0eQogICAgICovCiAgICBmdW5jdGlvbiBfaXNCbGFua1RleHROb2RlKG5vZGUpIHsKICAgICAgICByZXR1cm4gbm9kZS5ub2RlVHlwZSA9PT0gd3lzaWh0bWw1LlRFWFRfTk9ERSAmJiAhd3lzaWh0bWw1Lmxhbmcuc3RyaW5nKG5vZGUuZGF0YSkudHJpbSgpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBwcmV2aW91cyBzaWJsaW5nIG5vZGUgdGhhdCBpcyBub3QgYSBibGFuayB0ZXh0IG5vZGUKICAgICAqLwogICAgZnVuY3Rpb24gX2dldFByZXZpb3VzU2libGluZ1RoYXRJc05vdEJsYW5rKG5vZGUpIHsKICAgICAgICB2YXIgcHJldmlvdXNTaWJsaW5nID0gbm9kZS5wcmV2aW91c1NpYmxpbmc7CiAgICAgICAgd2hpbGUgKHByZXZpb3VzU2libGluZyAmJiBfaXNCbGFua1RleHROb2RlKHByZXZpb3VzU2libGluZykpIHsKICAgICAgICAgICAgcHJldmlvdXNTaWJsaW5nID0gcHJldmlvdXNTaWJsaW5nLnByZXZpb3VzU2libGluZzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHByZXZpb3VzU2libGluZzsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgbmV4dCBzaWJsaW5nIG5vZGUgdGhhdCBpcyBub3QgYSBibGFuayB0ZXh0IG5vZGUKICAgICAqLwogICAgZnVuY3Rpb24gX2dldE5leHRTaWJsaW5nVGhhdElzTm90Qmxhbmsobm9kZSkgewogICAgICAgIHZhciBuZXh0U2libGluZyA9IG5vZGUubmV4dFNpYmxpbmc7CiAgICAgICAgd2hpbGUgKG5leHRTaWJsaW5nICYmIF9pc0JsYW5rVGV4dE5vZGUobmV4dFNpYmxpbmcpKSB7CiAgICAgICAgICAgIG5leHRTaWJsaW5nID0gbmV4dFNpYmxpbmcubmV4dFNpYmxpbmc7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXh0U2libGluZzsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgbGluZSBicmVha3MgYmVmb3JlIGFuZCBhZnRlciB0aGUgZ2l2ZW4gbm9kZSBpZiB0aGUgcHJldmlvdXMgYW5kIG5leHQgc2libGluZ3MKICAgICAqIGFyZW4ndCBhbHJlYWR5IGNhdXNpbmcgYSB2aXN1YWwgbGluZSBicmVhayAoYmxvY2sgZWxlbWVudCBvciA8YnI+KQogICAgICovCiAgICBmdW5jdGlvbiBfYWRkTGluZUJyZWFrQmVmb3JlQW5kQWZ0ZXIobm9kZSkgewogICAgICAgIHZhciBkb2MgPSBub2RlLm93bmVyRG9jdW1lbnQsCiAgICAgICAgICAgIG5leHRTaWJsaW5nID0gX2dldE5leHRTaWJsaW5nVGhhdElzTm90Qmxhbmsobm9kZSksCiAgICAgICAgICAgIHByZXZpb3VzU2libGluZyA9IF9nZXRQcmV2aW91c1NpYmxpbmdUaGF0SXNOb3RCbGFuayhub2RlKTsKCiAgICAgICAgaWYgKG5leHRTaWJsaW5nICYmICFfaXNMaW5lQnJlYWtPckJsb2NrRWxlbWVudChuZXh0U2libGluZykpIHsKICAgICAgICAgICAgbm9kZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShkb2MuY3JlYXRlRWxlbWVudCgiYnIiKSwgbmV4dFNpYmxpbmcpOwogICAgICAgIH0KICAgICAgICBpZiAocHJldmlvdXNTaWJsaW5nICYmICFfaXNMaW5lQnJlYWtPckJsb2NrRWxlbWVudChwcmV2aW91c1NpYmxpbmcpKSB7CiAgICAgICAgICAgIG5vZGUucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZG9jLmNyZWF0ZUVsZW1lbnQoImJyIiksIG5vZGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgbGluZSBicmVha3MgYmVmb3JlIGFuZCBhZnRlciB0aGUgZ2l2ZW4gbm9kZQogICAgICovCiAgICBmdW5jdGlvbiBfcmVtb3ZlTGluZUJyZWFrQmVmb3JlQW5kQWZ0ZXIobm9kZSkgewogICAgICAgIHZhciBuZXh0U2libGluZyA9IF9nZXROZXh0U2libGluZ1RoYXRJc05vdEJsYW5rKG5vZGUpLAogICAgICAgICAgICBwcmV2aW91c1NpYmxpbmcgPSBfZ2V0UHJldmlvdXNTaWJsaW5nVGhhdElzTm90Qmxhbmsobm9kZSk7CgogICAgICAgIGlmIChuZXh0U2libGluZyAmJiBfaXNMaW5lQnJlYWsobmV4dFNpYmxpbmcpKSB7CiAgICAgICAgICAgIG5leHRTaWJsaW5nLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobmV4dFNpYmxpbmcpOwogICAgICAgIH0KICAgICAgICBpZiAocHJldmlvdXNTaWJsaW5nICYmIF9pc0xpbmVCcmVhayhwcmV2aW91c1NpYmxpbmcpKSB7CiAgICAgICAgICAgIHByZXZpb3VzU2libGluZy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHByZXZpb3VzU2libGluZyk7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIF9yZW1vdmVMYXN0Q2hpbGRJZkxpbmVCcmVhayhub2RlKSB7CiAgICAgICAgdmFyIGxhc3RDaGlsZCA9IG5vZGUubGFzdENoaWxkOwogICAgICAgIGlmIChsYXN0Q2hpbGQgJiYgX2lzTGluZUJyZWFrKGxhc3RDaGlsZCkpIHsKICAgICAgICAgICAgbGFzdENoaWxkLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobGFzdENoaWxkKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gX2lzTGluZUJyZWFrKG5vZGUpIHsKICAgICAgICByZXR1cm4gbm9kZS5ub2RlTmFtZSA9PT0gIkJSIjsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBlbG1lbnQgY2F1c2VzIGEgdmlzdWFsIGxpbmUgYnJlYWsKICAgICAqICg8YnI+IG9yIGJsb2NrIGVsZW1lbnRzKQogICAgICovCiAgICBmdW5jdGlvbiBfaXNMaW5lQnJlYWtPckJsb2NrRWxlbWVudChlbGVtZW50KSB7CiAgICAgICAgaWYgKF9pc0xpbmVCcmVhayhlbGVtZW50KSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmIChkb20uZ2V0U3R5bGUoImRpc3BsYXkiKS5mcm9tKGVsZW1lbnQpID09PSAiYmxvY2siKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZSBuYXRpdmUgcXVlcnkgY29tbWFuZAogICAgICogYW5kIGlmIG5lY2Vzc2FyeSBtb2RpZnkgdGhlIGluc2VydGVkIG5vZGUncyBjbGFzc05hbWUKICAgICAqLwogICAgZnVuY3Rpb24gX2V4ZWNDb21tYW5kKGRvYywgY29tbWFuZCwgbm9kZU5hbWUsIGNsYXNzTmFtZSkgewogICAgICAgIGlmIChjbGFzc05hbWUpIHsKICAgICAgICAgICAgdmFyIGV2ZW50TGlzdGVuZXIgPSBkb20ub2JzZXJ2ZShkb2MsICJET01Ob2RlSW5zZXJ0ZWQiLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSBldmVudC50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgZGlzcGxheVN0eWxlOwogICAgICAgICAgICAgICAgaWYgKHRhcmdldC5ub2RlVHlwZSAhPT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRpc3BsYXlTdHlsZSA9IGRvbS5nZXRTdHlsZSgiZGlzcGxheSIpLmZyb20odGFyZ2V0KTsKICAgICAgICAgICAgICAgIGlmIChkaXNwbGF5U3R5bGUuc3Vic3RyKDAsIDYpICE9PSAiaW5saW5lIikgewogICAgICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IG9ubHkgYmxvY2sgZWxlbWVudHMgcmVjZWl2ZSB0aGUgZ2l2ZW4gY2xhc3MKICAgICAgICAgICAgICAgICAgICB0YXJnZXQuY2xhc3NOYW1lICs9ICIgIiArIGNsYXNzTmFtZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGRvYy5leGVjQ29tbWFuZChjb21tYW5kLCBmYWxzZSwgbm9kZU5hbWUpOwogICAgICAgIGlmIChldmVudExpc3RlbmVyKSB7CiAgICAgICAgICAgIGV2ZW50TGlzdGVuZXIuc3RvcCgpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfc2VsZWN0TGluZUFuZFdyYXAoY29tcG9zZXIsIGVsZW1lbnQpIHsKICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2VsZWN0TGluZSgpOwogICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zdXJyb3VuZChlbGVtZW50KTsKICAgICAgICBfcmVtb3ZlTGluZUJyZWFrQmVmb3JlQW5kQWZ0ZXIoZWxlbWVudCk7CiAgICAgICAgX3JlbW92ZUxhc3RDaGlsZElmTGluZUJyZWFrKGVsZW1lbnQpOwogICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZWxlY3ROb2RlKGVsZW1lbnQsIHd5c2lodG1sNS5icm93c2VyLmRpc3BsYXlzQ2FyZXRJbkVtcHR5Q29udGVudEVkaXRhYmxlQ29ycmVjdGx5KCkpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9oYXNDbGFzc2VzKGVsZW1lbnQpIHsKICAgICAgICByZXR1cm4gISF3eXNpaHRtbDUubGFuZy5zdHJpbmcoZWxlbWVudC5jbGFzc05hbWUpLnRyaW0oKTsKICAgIH0KCiAgICB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0QmxvY2sgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgbm9kZU5hbWUsIGNsYXNzTmFtZSwgY2xhc3NSZWdFeHApIHsKICAgICAgICAgICAgdmFyIGRvYyA9IGNvbXBvc2VyLmRvYywKICAgICAgICAgICAgICAgIGJsb2NrRWxlbWVudCA9IHRoaXMuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsIG5vZGVOYW1lLCBjbGFzc05hbWUsIGNsYXNzUmVnRXhwKSwKICAgICAgICAgICAgICAgIHVzZUxpbmVCcmVha3MgPSBjb21wb3Nlci5jb25maWcudXNlTGluZUJyZWFrcywKICAgICAgICAgICAgICAgIGRlZmF1bHROb2RlTmFtZSA9IHVzZUxpbmVCcmVha3MgPyAiRElWIiA6ICJQIiwKICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZTsKCiAgICAgICAgICAgIG5vZGVOYW1lID0gdHlwZW9mKG5vZGVOYW1lKSA9PT0gInN0cmluZyIgPyBub2RlTmFtZS50b1VwcGVyQ2FzZSgpIDogbm9kZU5hbWU7CgogICAgICAgICAgICBpZiAoYmxvY2tFbGVtZW50KSB7CiAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmVTaW1wbGUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc1JlZ0V4cCkgewogICAgICAgICAgICAgICAgICAgICAgICBfcmVtb3ZlQ2xhc3MoYmxvY2tFbGVtZW50LCBjbGFzc1JlZ0V4cCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBoYXNDbGFzc2VzID0gX2hhc0NsYXNzZXMoYmxvY2tFbGVtZW50KTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWhhc0NsYXNzZXMgJiYgKHVzZUxpbmVCcmVha3MgfHwgbm9kZU5hbWUgPT09ICJQIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5zZXJ0IGEgbGluZSBicmVhayBhZnRlcndhcmRzIGFuZCBiZWZvcmV3YXJkcyB3aGVuIHRoZXJlIGFyZSBzaWJsaW5ncwogICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGF0IGFyZSBub3Qgb2YgdHlwZSBsaW5lIGJyZWFrIG9yIGJsb2NrIGVsZW1lbnQKICAgICAgICAgICAgICAgICAgICAgICAgX2FkZExpbmVCcmVha0JlZm9yZUFuZEFmdGVyKGJsb2NrRWxlbWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5yZXBsYWNlV2l0aENoaWxkTm9kZXMoYmxvY2tFbGVtZW50KTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCBzdHlsaW5nIGlzIGtlcHQgYnkgcmVuYW1pbmcgdGhlIGVsZW1lbnQgdG8gYSA8ZGl2PiBvciA8cD4gYW5kIGNvcHlpbmcgb3ZlciB0aGUgY2xhc3MgbmFtZQogICAgICAgICAgICAgICAgICAgICAgICBkb20ucmVuYW1lRWxlbWVudChibG9ja0VsZW1lbnQsIG5vZGVOYW1lID09PSAiUCIgPyAiRElWIiA6IGRlZmF1bHROb2RlTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEZpbmQgc2ltaWxpYXIgYmxvY2sgZWxlbWVudCBhbmQgcmVuYW1lIGl0ICg8aDIgY2xhc3M9ImZvbyI+PC9oMj4gID0+ICA8aDEgY2xhc3M9ImZvbyI+PC9oMT4pCiAgICAgICAgICAgIGlmIChub2RlTmFtZSA9PT0gbnVsbCB8fCB3eXNpaHRtbDUubGFuZy5hcnJheShCTE9DS19FTEVNRU5UU19HUk9VUCkuY29udGFpbnMobm9kZU5hbWUpKSB7CiAgICAgICAgICAgICAgICBzZWxlY3RlZE5vZGUgPSBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKHVuZGVmaW5lZCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICBibG9ja0VsZW1lbnQgPSBkb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHsKICAgICAgICAgICAgICAgICAgICBub2RlTmFtZSA6IEJMT0NLX0VMRU1FTlRTX0dST1VQCiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICBpZiAoYmxvY2tFbGVtZW50KSB7CiAgICAgICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVuYW1lIGN1cnJlbnQgYmxvY2sgZWxlbWVudCB0byBuZXcgYmxvY2sgZWxlbWVudCBhbmQgYWRkIGNsYXNzCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlTmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tFbGVtZW50ID0gZG9tLnJlbmFtZUVsZW1lbnQoYmxvY2tFbGVtZW50LCBub2RlTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX2FkZENsYXNzKGJsb2NrRWxlbWVudCwgY2xhc3NOYW1lLCBjbGFzc1JlZ0V4cCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYWRkQXR0cmlidXRlKGJsb2NrRWxlbWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYWRkRGF0YUF0dHJpYnV0ZShibG9ja0VsZW1lbnQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29tcG9zZXIuY29tbWFuZHMuc3VwcG9ydChjb21tYW5kKSkgewogICAgICAgICAgICAgICAgX2V4ZWNDb21tYW5kKGRvYywgY29tbWFuZCwgbm9kZU5hbWUgfHwgZGVmYXVsdE5vZGVOYW1lLCBjbGFzc05hbWUpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBibG9ja0VsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudChub2RlTmFtZSB8fCBkZWZhdWx0Tm9kZU5hbWUpOwogICAgICAgICAgICBpZiAoY2xhc3NOYW1lKSB7CiAgICAgICAgICAgICAgICBibG9ja0VsZW1lbnQuY2xhc3NOYW1lID0gY2xhc3NOYW1lOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF9zZWxlY3RMaW5lQW5kV3JhcChjb21wb3NlciwgYmxvY2tFbGVtZW50KTsKICAgICAgICB9LAoKICAgICAgICBzdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgbm9kZU5hbWUsIGNsYXNzTmFtZSwgY2xhc3NSZWdFeHAsIGF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgbm9kZU5hbWUgPSB0eXBlb2Yobm9kZU5hbWUpID09PSAic3RyaW5nIiA/IG5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgOiBub2RlTmFtZTsKICAgICAgICAgICAgdmFyIG5vZGVMaXN0ID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldE5vZGVzKDMpOwogICAgICAgICAgICBpZiAobm9kZUxpc3QubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgICAgICAgICAgaSA8IG5vZGVMaXN0Lmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSBub2RlTGlzdFtpXTsKICAgICAgICAgICAgICAgICAgICBpZiAobm9kZS50ZXh0Q29udGVudC50cmltKCkgIT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBkb20uZ2V0UGFyZW50RWxlbWVudChub2RlLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlTmFtZSA6IG5vZGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lIDogY2xhc3NOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NSZWdFeHAgOiBjbGFzc1JlZ0V4cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgOiBhdHRyaWJ1dGVzCiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiBkb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHsKICAgICAgICAgICAgICAgICAgICBub2RlTmFtZSA6IG5vZGVOYW1lLAogICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSA6IGNsYXNzTmFtZSwKICAgICAgICAgICAgICAgICAgICBjbGFzc1JlZ0V4cCA6IGNsYXNzUmVnRXhwLAogICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgOiBhdHRyaWJ1dGVzCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGVtcHR5IHRhZ3MgYmVmb3JlIGFuZCBhZnRlciB0aGUgZ2l2ZW4gbm9kZQogICAgICovCiAgICBmdW5jdGlvbiBfcmVtb3ZlRW1wdHlUYWdzQmVmb3JlQW5kQWZ0ZXIobm9kZSkgewogICAgICAgIHZhciBuZXh0U2libGluZyA9IF9nZXROZXh0U2libGluZ1RoYXRJc05vdEJsYW5rKG5vZGUpLAogICAgICAgICAgICBwcmV2aW91c1NpYmxpbmcgPSBfZ2V0UHJldmlvdXNTaWJsaW5nVGhhdElzTm90Qmxhbmsobm9kZSk7CgogICAgICAgIGlmIChuZXh0U2libGluZyAmJiAhbmV4dFNpYmxpbmcudGV4dENvbnRlbnQpIHsKICAgICAgICAgICAgbmV4dFNpYmxpbmcucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChuZXh0U2libGluZyk7CiAgICAgICAgfQogICAgICAgIGlmIChwcmV2aW91c1NpYmxpbmcgJiYgIXByZXZpb3VzU2libGluZy50ZXh0Q29udGVudCkgewogICAgICAgICAgICBwcmV2aW91c1NpYmxpbmcucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChwcmV2aW91c1NpYmxpbmcpOwogICAgICAgIH0KICAgIH0KCiAgICB3eXNpaHRtbDUuY29tbWFuZHMuc3Vycm91bmRDb250ZW50ID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGVsZW1lbnQsIGVtcHR5VGV4dCkgewogICAgICAgICAgICB2YXIgc2VsZWN0ZWROb2RlID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFNlbGVjdGVkTm9kZSgpLAogICAgICAgICAgICAgICAgaXNFbXB0eSA9ICFjb21wb3Nlci5zZWxlY3Rpb24uZ2V0VGV4dCgpLAogICAgICAgICAgICAgICAgdGV4dE5vZGVOYW1lcyA9IFtdOwogICAgICAgICAgICBpZiAoY29tcG9zZXIuY29uZmlnLnBhcnNlclJ1bGVzICYmIGNvbXBvc2VyLmNvbmZpZy5wYXJzZXJSdWxlcy50ZXh0Tm9kZXMpIHsKICAgICAgICAgICAgICAgIHRleHROb2RlTmFtZXMgPSBjb21wb3Nlci5jb25maWcucGFyc2VyUnVsZXMudGV4dE5vZGVzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciB0ZXh0Tm9kZSA9IHd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHtub2RlTmFtZSA6IHRleHROb2RlTmFtZXN9KTsKICAgICAgICAgICAgaWYgKHRleHROb2RlKSB7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZS5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZShlbGVtZW50LCB0ZXh0Tm9kZSk7CiAgICAgICAgICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKHRleHROb2RlKTsKICAgICAgICAgICAgfSBlbHNlIGlmICghd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKHNlbGVjdGVkTm9kZSkgJiYgc2VsZWN0ZWROb2RlLnRleHRDb250ZW50ID09IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRUZXh0KCkpIHsKICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZS5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZShlbGVtZW50LCBzZWxlY3RlZE5vZGUpOwogICAgICAgICAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChzZWxlY3RlZE5vZGUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLnN1cnJvdW5kKGVsZW1lbnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF9yZW1vdmVFbXB0eVRhZ3NCZWZvcmVBbmRBZnRlcihlbGVtZW50KTsKICAgICAgICAgICAgaWYgKGlzRW1wdHkpIHsKICAgICAgICAgICAgICAgIC8qIElmIHRoZSBhZGRlZCBlbGVtZW50IGlzIGVtcHR5IGFkZCBhIHBsYWNlaG9sZGVyIHRleHQqLwogICAgICAgICAgICAgICAgdmFyIGZpcnN0Q2hpbGQgPSBlbGVtZW50OwogICAgICAgICAgICAgICAgd2hpbGUgKGZpcnN0Q2hpbGQuZmlyc3RDaGlsZCAmJiBmaXJzdENoaWxkLmZpcnN0Q2hpbGQubm9kZVR5cGUgPT0gMSAmJiBmaXJzdENoaWxkLmZpcnN0Q2hpbGQubm9kZU5hbWUgIT0gIkJSIikgewogICAgICAgICAgICAgICAgICAgIGZpcnN0Q2hpbGQgPSBmaXJzdENoaWxkLmZpcnN0Q2hpbGQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmaXJzdENoaWxkLnRleHRDb250ZW50ID0gZW1wdHlUZXh0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBjaGlsZDsKICAgICAgICAgICAgaWYgKCFlbGVtZW50Lm5leHRTaWJsaW5nIHx8ICFlbGVtZW50Lm5leHRTaWJsaW5nLnRleHRDb250ZW50KSB7CiAgICAgICAgICAgICAgICAvKiBJZiB0aGUgZWxlbWVudCBoYXMgbm8gbmV4dCBzaWJsaW5nIGFkZCBhbiBlbGVtZW50CiAgICAgICAgICAgICAgICAgKiB3aXRoIHNhbWUgc3R5bGUgYXMgbGFzdCBjaGlsZCBvZiB0aGUgZWxlbWVudCBhbmQgJm5ic3AKICAgICAgICAgICAgICAgICAqIHRvIGVuYWJsZSBjdXJzb3IgdG8gZW50ZXIgdGhlIGVsZW1lbnQgKi8KICAgICAgICAgICAgICAgIGlmIChlbGVtZW50Lm5leHRTaWJsaW5nICYmIGVsZW1lbnQubmV4dFNpYmxpbmcubm9kZVR5cGUgPT0gMSkgewogICAgICAgICAgICAgICAgICAgIGNoaWxkID0gZWxlbWVudC5uZXh0U2libGluZzsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hpbGQuZmlyc3RDaGlsZCAmJiBjaGlsZC5maXJzdENoaWxkLm5vZGVUeXBlID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZmlyc3RDaGlsZDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHZhciBsYXN0Q2hpbGQgPSBlbGVtZW50Lmxhc3RDaGlsZDsKICAgICAgICAgICAgICAgICAgICB2YXIgc3VwcG9ydGVkVGFncyA9IFsiUCIsICJIMSIsICJIMiIsICJIMyIsICJINCIsICJINSIsICJINiIsICJTUEFOIiwgIkIiLCAiVSIsICJJIiwgIlNVUCIsICJTVUIiLCAiQSJdOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChsYXN0Q2hpbGQubm9kZVR5cGUgPT09IDEgJiYgc3VwcG9ydGVkVGFncy5pbmRleE9mKGxhc3RDaGlsZC5ub2RlTmFtZSkgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RDaGlsZCA9IGxhc3RDaGlsZC5sYXN0Q2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8qIElmIGxhc3QgY2hpbGQgdHlwZSBpcyBub3QgdGV4dCwgY2xvbmUgYWxsIHRoZSBjaGlsZCBub2RlcwogICAgICAgICAgICAgICAgICAgICAqIGVsc2UgYXBwZW5kIGEgc3BhbiB0YWcqLwogICAgICAgICAgICAgICAgICAgIGlmIChsYXN0Q2hpbGQubm9kZVR5cGUgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNsb25lTm9kZSA9IGxhc3RDaGlsZC5jbG9uZU5vZGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQubmV4dFNpYmxpbmcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUoY2xvbmVOb2RlLCBlbGVtZW50Lm5leHRTaWJsaW5nKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQucGFyZW50RWxlbWVudC5hcHBlbmRDaGlsZChjbG9uZU5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChsYXN0Q2hpbGQubGFzdENoaWxkICYmIGxhc3RDaGlsZC5sYXN0Q2hpbGQubm9kZVR5cGUgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RDaGlsZCA9IGxhc3RDaGlsZC5sYXN0Q2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBTa2lwIGFsbCBjb25kaXRpb24vcmVwZWF0IGFuZCBsaXN0IHRhZ3MqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1cHBvcnRlZFRhZ3MuaW5kZXhPZihsYXN0Q2hpbGQubm9kZU5hbWUpIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQgPSBsYXN0Q2hpbGQuY2xvbmVOb2RlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9uZU5vZGUuYXBwZW5kQ2hpbGQoY2hpbGQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvbmVOb2RlID0gY2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5wYXJlbnRFbGVtZW50LmFwcGVuZENoaWxkKGNoaWxkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICBjaGlsZC5pbm5lckhUTUwgPSAiJm5ic3AiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciByYW5nZSA9IHJhbmd5LmNyZWF0ZVJhbmdlKGNvbXBvc2VyLmRvYyk7CiAgICAgICAgICAgIHJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhlbGVtZW50KTsKICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLnNldFNlbGVjdGlvbihyYW5nZSk7CiAgICAgICAgfQogICAgfTsKfSkod3lzaWh0bWw1KTsKLyoqCiAqIGZvcm1hdElubGluZSBzY2VuYXJpb3MgZm9yIHRhZyAiQiIgKHwgPSBjYXJldCwgfGZvb3wgPSBzZWxlY3RlZCB0ZXh0KQogKgogKiAgICMxIGNhcmV0IGluIHVuZm9ybWF0dGVkIHRleHQ6CiAqICAgICAgYWJjZGVmZ3wKICogICBvdXRwdXQ6CiAqICAgICAgYWJjZGVmZzxiPnw8L2I+CiAqCiAqICAgIzIgdW5mb3JtYXR0ZWQgdGV4dCBzZWxlY3RlZDoKICogICAgICBhYmN8ZGVnfGgKICogICBvdXRwdXQ6CiAqICAgICAgYWJjPGI+fGRlZ3w8L2I+aAogKgogKiAgICMzIHVuZm9ybWF0dGVkIHRleHQgc2VsZWN0ZWQgYWNyb3NzIGJvdW5kYXJpZXM6CiAqICAgICAgYWJ8YyA8c3Bhbj5kZWZnfGg8L3NwYW4+CiAqICAgb3V0cHV0OgogKiAgICAgIGFiPGI+fGMgPC9iPjxzcGFuPjxiPmRlZmc8L2I+fGg8L3NwYW4+CiAqCiAqICAgIzQgZm9ybWF0dGVkIHRleHQgZW50aXJlbHkgc2VsZWN0ZWQKICogICAgICA8Yj58YWJjfDwvYj4KICogICBvdXRwdXQ6CiAqICAgICAgfGFiY3wKICoKICogICAjNSBmb3JtYXR0ZWQgdGV4dCBwYXJ0aWFsbHkgc2VsZWN0ZWQKICogICAgICA8Yj5hYnxjfDwvYj4KICogICBvdXRwdXQ6CiAqICAgICAgPGI+YWI8L2I+fGN8CiAqCiAqICAgIzYgZm9ybWF0dGVkIHRleHQgc2VsZWN0ZWQgYWNyb3NzIGJvdW5kYXJpZXMKICogICAgICA8c3Bhbj5hYnxjPC9zcGFuPiA8Yj5kZXxmZ2g8L2I+CiAqICAgb3V0cHV0OgogKiAgICAgIDxzcGFuPmFifGM8L3NwYW4+IGRlfDxiPmZnaDwvYj4KICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgLy8gVHJlYXQgPGI+IGFzIDxzdHJvbmc+IGFuZCB2aWNlIHZlcnNhCiAgICAgICAgQUxJQVNfTUFQUElORyA9IHsKICAgICAgICAgICAgInN0cm9uZyIgOiAiYiIsCiAgICAgICAgICAgICJlbSIgOiAiaSIsCiAgICAgICAgICAgICJiIiA6ICJzdHJvbmciLAogICAgICAgICAgICAiaSIgOiAiZW0iCiAgICAgICAgfSwKICAgICAgICBodG1sQXBwbGllciA9IHt9OwoKICAgIGZ1bmN0aW9uIF9nZXRUYWdOYW1lcyh0YWdOYW1lKSB7CiAgICAgICAgdmFyIGFsaWFzID0gQUxJQVNfTUFQUElOR1t0YWdOYW1lXTsKICAgICAgICBpZiAodGFnTmFtZS50b0xvd2VyQ2FzZSgpID09ICdzcGFuJykgewogICAgICAgICAgICByZXR1cm4gYWxpYXMgPyBbdGFnTmFtZS50b0xvd2VyQ2FzZSgpLCBhbGlhcy50b0xvd2VyQ2FzZSgpLCAibGkiLCAicCJdIDogW3RhZ05hbWUudG9Mb3dlckNhc2UoKSwgImxpIiwgInAiXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gYWxpYXMgPyBbdGFnTmFtZS50b0xvd2VyQ2FzZSgpLCBhbGlhcy50b0xvd2VyQ2FzZSgpXSA6IFt0YWdOYW1lLnRvTG93ZXJDYXNlKCldOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfZ2V0QXBwbGllcih0YWdOYW1lLCBjbGFzc05hbWUsIGNsYXNzUmVnRXhwLCBhdHRyaWJ1dGVzLCBjbGVhclByZVN0eWxlLCBkYXRhQXR0cmlidXRlLCBjbGVhclByZURhdGFBdHRyaWJ1dGUpIHsKICAgICAgICB2YXIgaWRlbnRpZmllciA9ICIiOwogICAgICAgIGlmIChhdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgIGZvciAoYXR0cmlidXRlIGluIGF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICAgIGlkZW50aWZpZXIgPSB0YWdOYW1lICsgIjoiICsgY2xhc3NOYW1lICsgIjoiICsgYXR0cmlidXRlc1thdHRyaWJ1dGVdOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGRhdGFBdHRyaWJ1dGUpIHsKICAgICAgICAgICAgZm9yIChhdHRyaWJ1dGUgaW4gZGF0YUF0dHJpYnV0ZSkgewogICAgICAgICAgICAgICAgaWRlbnRpZmllciArPSB0YWdOYW1lICsgIjoiICsgY2xhc3NOYW1lICsgIjoiICsgZGF0YUF0dHJpYnV0ZVthdHRyaWJ1dGVdOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChpZGVudGlmaWVyID09ICIiKSB7CiAgICAgICAgICAgIGlkZW50aWZpZXIgPSB0YWdOYW1lICsgIjoiICsgY2xhc3NOYW1lOwogICAgICAgIH0KICAgICAgICBpZiAoIWh0bWxBcHBsaWVyW2lkZW50aWZpZXJdKSB7CiAgICAgICAgICAgIGh0bWxBcHBsaWVyW2lkZW50aWZpZXJdID0gbmV3IHd5c2lodG1sNS5zZWxlY3Rpb24uSFRNTEFwcGxpZXIoX2dldFRhZ05hbWVzKHRhZ05hbWUpLCBjbGFzc05hbWUsIGNsYXNzUmVnRXhwLCB0cnVlLCBhdHRyaWJ1dGVzLCBjbGVhclByZVN0eWxlLCBkYXRhQXR0cmlidXRlLCBjbGVhclByZURhdGFBdHRyaWJ1dGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaHRtbEFwcGxpZXJbaWRlbnRpZmllcl07CiAgICB9CgogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZSA9IHsKICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCB0YWdOYW1lLCBjbGFzc05hbWUsIGNsYXNzUmVnRXhwLCBhdHRyaWJ1dGVzLCBjbGVhclByZVN0eWxlLCBkYXRhQXR0cmlidXRlLCBjbGVhclByZURhdGFBdHRyaWJ1dGUpIHsKICAgICAgICAgICAgdmFyIHJhbmdlID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFJhbmdlKCk7CiAgICAgICAgICAgIGlmICghcmFuZ2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBfZ2V0QXBwbGllcih0YWdOYW1lLCBjbGFzc05hbWUsIGNsYXNzUmVnRXhwLCBhdHRyaWJ1dGVzLCBjbGVhclByZVN0eWxlLCBkYXRhQXR0cmlidXRlLCBjbGVhclByZURhdGFBdHRyaWJ1dGUpLnRvZ2dsZVJhbmdlKHJhbmdlLCBjb21wb3Nlcik7CiAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZXRTZWxlY3Rpb24ocmFuZ2UpOwogICAgICAgIH0sCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIHRhZ05hbWUsIGNsYXNzTmFtZSwgY2xhc3NSZWdFeHAsIGF0dHJpYnV0ZXMsIGNsZWFyUHJlU3R5bGUsIGRhdGFBdHRyaWJ1dGUsIGNsZWFyUHJlRGF0YUF0dHJpYnV0ZSkgewogICAgICAgICAgICB2YXIgZG9jID0gY29tcG9zZXIuZG9jLAogICAgICAgICAgICAgICAgYWxpYXNUYWdOYW1lID0gQUxJQVNfTUFQUElOR1t0YWdOYW1lXSB8fCB0YWdOYW1lLAogICAgICAgICAgICAgICAgcmFuZ2U7CgogICAgICAgICAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSBkb2N1bWVudCBjb250YWlucyBhIG5vZGUgd2l0aCB0aGUgZGVzaXJlZCB0YWdOYW1lCiAgICAgICAgICAgIGlmICghd3lzaWh0bWw1LmRvbS5oYXNFbGVtZW50V2l0aFRhZ05hbWUoZG9jLCB0YWdOYW1lKSAmJiAhd3lzaWh0bWw1LmRvbS5oYXNFbGVtZW50V2l0aFRhZ05hbWUoZG9jLCBhbGlhc1RhZ05hbWUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIGRvY3VtZW50IGNvbnRhaW5zIGEgbm9kZSB3aXRoIHRoZSBkZXNpcmVkIGNsYXNzTmFtZQogICAgICAgICAgICAvL2lmIChjbGFzc05hbWUgJiYgIXd5c2lodG1sNS5kb20uaGFzRWxlbWVudFdpdGhDbGFzc05hbWUoZG9jLCBjbGFzc05hbWUpKSB7CiAgICAgICAgICAgIC8vICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAvL30KCiAgICAgICAgICAgIHJhbmdlID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFJhbmdlKCk7CiAgICAgICAgICAgIGlmICghcmFuZ2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gX2dldEFwcGxpZXIodGFnTmFtZSwgY2xhc3NOYW1lLCBjbGFzc1JlZ0V4cCwgYXR0cmlidXRlcywgY2xlYXJQcmVTdHlsZSwgZGF0YUF0dHJpYnV0ZSwgY2xlYXJQcmVEYXRhQXR0cmlidXRlKS5pc0FwcGxpZWRUb1JhbmdlKHJhbmdlKTsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwp3eXNpaHRtbDUuY29tbWFuZHMuaW5zZXJ0SFRNTCA9IHsKICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGh0bWwpIHsKICAgICAgICBpZiAoY29tcG9zZXIuY29tbWFuZHMuc3VwcG9ydChjb21tYW5kKSkgewogICAgICAgICAgICBjb21wb3Nlci5kb2MuZXhlY0NvbW1hbmQoY29tbWFuZCwgZmFsc2UsIGh0bWwpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5pbnNlcnRIVE1MKGh0bWwpOwogICAgICAgIH0KICAgIH0sCgogICAgc3RhdGUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9Owood3lzaWh0bWw1KTsKd3lzaWh0bWw1LmNvbW1hbmRzLmluc2VydFRleHQgPSB7CiAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCB0ZXh0KSB7CiAgICAgICAgaWYgKGNvbXBvc2VyLmNvbW1hbmRzLnN1cHBvcnQoY29tbWFuZCkpIHsKICAgICAgICAgICAgY29tcG9zZXIuZG9jLmV4ZWNDb21tYW5kKGNvbW1hbmQsIGZhbHNlLCB0ZXh0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoY29tcG9zZXIuc2VsZWN0aW9uICYmIGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRUZXh0KCkgIT0gIiIpIHsKICAgICAgICAgICAgICAgIGNvbXBvc2VyLmRvYy5leGVjQ29tbWFuZCgiZGVsZXRlIiwgZmFsc2UsIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEltcGxlbWVudGluZyBtdWx0aSBsaW5lIGluc2VydFRleHQgKCBpbmNhc2Ugb2YgcGFzdGUpCiAgICAgICAgICAgIGlmICh0ZXh0KSB7CiAgICAgICAgICAgICAgICB2YXIgbXVsdGlMaW5lcyA9IHRleHQuc3BsaXQoIlxyXG4iKTsgLy8gc3BsaXQgYnkgQ1IgKyBMRgogICAgICAgICAgICAgICAgdmFyIHRleHROb2RlOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOwogICAgICAgICAgICAgICAgICAgICBpbmRleCA8IG11bHRpTGluZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICBpbmRleCsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGV4dE5vZGUgPSBjb21wb3Nlci5zZWxlY3Rpb24uZG9jLmNyZWF0ZVRleHROb2RlKG11bHRpTGluZXNbaW5kZXhdKTsKICAgICAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uaW5zZXJ0Tm9kZSh0ZXh0Tm9kZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKG11bHRpTGluZXMubGVuZ3RoID4gMSAmJiBpbmRleCA8IG11bHRpTGluZXMubGVuZ3RoIC0gMSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uaW5zZXJ0Tm9kZShjb21wb3Nlci5zZWxlY3Rpb24uZG9jLmNyZWF0ZUVsZW1lbnQoImJyIikpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZXQodGV4dE5vZGUsIHRleHROb2RlLmxlbmd0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfTsKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBOT0RFX05BTUUgPSAiSU1HIjsKCiAgICB3eXNpaHRtbDUuY29tbWFuZHMuaW5zZXJ0SW1hZ2UgPSB7CiAgICAgICAgLyoqCiAgICAgICAgICogSW5zZXJ0cyBhbiA8aW1nPgogICAgICAgICAqIElmIHNlbGVjdGlvbiBpcyBhbHJlYWR5IGFuIGltYWdlIGxpbmssIGl0IHJlbW92ZXMgaXQKICAgICAgICAgKgogICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICogICAgLy8gZWl0aGVyIC4uLgogICAgICAgICAqICAgIHd5c2lodG1sNS5jb21tYW5kcy5pbnNlcnRJbWFnZS5leGVjKGNvbXBvc2VyLCAiaW5zZXJ0SW1hZ2UiLCAiaHR0cDovL3d3dy5nb29nbGUuZGUvbG9nby5qcGciKTsKICAgICAgICAgKiAgICAvLyAuLi4gb3IgLi4uCiAgICAgICAgICogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmluc2VydEltYWdlLmV4ZWMoY29tcG9zZXIsICJpbnNlcnRJbWFnZSIsIHsgc3JjOiAiaHR0cDovL3d3dy5nb29nbGUuZGUvbG9nby5qcGciLCB0aXRsZTogImZvbyIgfSk7CiAgICAgICAgICovCiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgdmFsdWUpIHsKICAgICAgICAgICAgdmFsdWUgPSB0eXBlb2YodmFsdWUpID09PSAib2JqZWN0IiA/IHZhbHVlIDoge3NyYyA6IHZhbHVlfTsKCiAgICAgICAgICAgIHZhciBkb2MgPSBjb21wb3Nlci5kb2MsCiAgICAgICAgICAgICAgICBpbWFnZSA9IHRoaXMuc3RhdGUoY29tcG9zZXIpLAogICAgICAgICAgICAgICAgdGV4dE5vZGUsCiAgICAgICAgICAgICAgICBpLAogICAgICAgICAgICAgICAgcGFyZW50OwoKICAgICAgICAgICAgaWYgKGltYWdlKSB7CiAgICAgICAgICAgICAgICAvLyBJbWFnZSBhbHJlYWR5IHNlbGVjdGVkLCBzZXQgdGhlIGNhcmV0IGJlZm9yZSBpdCBhbmQgZGVsZXRlIGl0CiAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2V0QmVmb3JlKGltYWdlKTsKICAgICAgICAgICAgICAgIHBhcmVudCA9IGltYWdlLnBhcmVudE5vZGU7CiAgICAgICAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoaW1hZ2UpOwoKICAgICAgICAgICAgICAgIC8vIGFuZCBpdCdzIHBhcmVudCA8YT4gdG9vIGlmIGl0IGhhc24ndCBnb3QgYW55IG90aGVyIHJlbGV2YW50IGNoaWxkIG5vZGVzCiAgICAgICAgICAgICAgICB3eXNpaHRtbDUuZG9tLnJlbW92ZUVtcHR5VGV4dE5vZGVzKHBhcmVudCk7CiAgICAgICAgICAgICAgICBpZiAocGFyZW50Lm5vZGVOYW1lID09PSAiQSIgJiYgIXBhcmVudC5maXJzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLnNldEFmdGVyKHBhcmVudCk7CiAgICAgICAgICAgICAgICAgICAgcGFyZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQocGFyZW50KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBmaXJlZm94IGFuZCBpZSBzb21ldGltZXMgZG9uJ3QgcmVtb3ZlIHRoZSBpbWFnZSBoYW5kbGVzLCBldmVuIHRob3VnaCB0aGUgaW1hZ2UgZ290IHJlbW92ZWQKICAgICAgICAgICAgICAgIHd5c2lodG1sNS5xdWlya3MucmVkcmF3KGNvbXBvc2VyLmVsZW1lbnQpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpbWFnZSA9IGRvYy5jcmVhdGVFbGVtZW50KE5PREVfTkFNRSk7CgogICAgICAgICAgICBmb3IgKGkgaW4gdmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmIChpID09PSAiY2xhc3NOYW1lIikgewogICAgICAgICAgICAgICAgICAgIGkgPSAiY2xhc3MiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW1hZ2Uuc2V0QXR0cmlidXRlKGksIHZhbHVlW2ldKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmluc2VydE5vZGUoaW1hZ2UpOwogICAgICAgICAgICBpZiAod3lzaWh0bWw1LmJyb3dzZXIuaGFzUHJvYmxlbXNTZXR0aW5nQ2FyZXRBZnRlckltZygpKSB7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSh3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFKTsKICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5pbnNlcnROb2RlKHRleHROb2RlKTsKICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZXRBZnRlcih0ZXh0Tm9kZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2V0QWZ0ZXIoaW1hZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIpIHsKICAgICAgICAgICAgdmFyIGRvYyA9IGNvbXBvc2VyLmRvYywKICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZSwKICAgICAgICAgICAgICAgIHRleHQsCiAgICAgICAgICAgICAgICBpbWFnZXNJblNlbGVjdGlvbjsKCiAgICAgICAgICAgIGlmICghd3lzaWh0bWw1LmRvbS5oYXNFbGVtZW50V2l0aFRhZ05hbWUoZG9jLCBOT0RFX05BTUUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKTsKICAgICAgICAgICAgaWYgKCFzZWxlY3RlZE5vZGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZS5ub2RlTmFtZSA9PT0gTk9ERV9OQU1FKSB7CiAgICAgICAgICAgICAgICAvLyBUaGlzIHdvcmtzIHBlcmZlY3RseSBpbiBJRQogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGVkTm9kZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZS5ub2RlVHlwZSAhPT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0ZXh0ID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFRleHQoKTsKICAgICAgICAgICAgdGV4dCA9IHd5c2lodG1sNS5sYW5nLnN0cmluZyh0ZXh0KS50cmltKCk7CiAgICAgICAgICAgIGlmICh0ZXh0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGltYWdlc0luU2VsZWN0aW9uID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldE5vZGVzKHd5c2lodG1sNS5FTEVNRU5UX05PREUsIGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5ub2RlTmFtZSA9PT0gIklNRyI7CiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgaWYgKGltYWdlc0luU2VsZWN0aW9uLmxlbmd0aCAhPT0gMSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gaW1hZ2VzSW5TZWxlY3Rpb25bMF07CiAgICAgICAgfQogICAgfTsKfSkod3lzaWh0bWw1KTsKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBMSU5FX0JSRUFLID0gIjxicj4iICsgKHd5c2lodG1sNS5icm93c2VyLm5lZWRzU3BhY2VBZnRlckxpbmVCcmVhaygpID8gIiAiIDogIiIpOwoKICAgIHd5c2lodG1sNS5jb21tYW5kcy5pbnNlcnRMaW5lQnJlYWsgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgICAgICBpZiAoY29tcG9zZXIuY29tbWFuZHMuc3VwcG9ydChjb21tYW5kKSkgewogICAgICAgICAgICAgICAgY29tcG9zZXIuZG9jLmV4ZWNDb21tYW5kKGNvbW1hbmQsIGZhbHNlLCBudWxsKTsKICAgICAgICAgICAgICAgIGlmICghd3lzaWh0bWw1LmJyb3dzZXIuYXV0b1Njcm9sbHNUb0NhcmV0KCkpIHsKICAgICAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2Nyb2xsSW50b1ZpZXcoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvbXBvc2VyLmNvbW1hbmRzLmV4ZWMoImluc2VydEhUTUwiLCBMSU5FX0JSRUFLKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfTsKfSkod3lzaWh0bWw1KTsKd3lzaWh0bWw1LmNvbW1hbmRzLmluc2VydE9yZGVyZWRMaXN0ID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgbGlzdFR5cGUpIHsKICAgICAgICB2YXIgZG9jID0gY29tcG9zZXIuZG9jLAogICAgICAgICAgICBzZWxlY3RlZE5vZGUgPSBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKHVuZGVmaW5lZCwgdHJ1ZSksCiAgICAgICAgICAgIGxpc3QgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQoc2VsZWN0ZWROb2RlLCB7bm9kZU5hbWUgOiAiT0wifSksCiAgICAgICAgICAgIG90aGVyTGlzdCA9IHd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHtub2RlTmFtZSA6ICJVTCJ9KSwKICAgICAgICAgICAgdGVtcENsYXNzTmFtZSA9ICJfd3lzaWh0bWw1LXRlbXAtIiArIG5ldyBEYXRlKCkuZ2V0VGltZSgpLAogICAgICAgICAgICBpc0VtcHR5LAogICAgICAgICAgICB0ZW1wRWxlbWVudDsKICAgICAgICB2YXIgdXBwZXJSb21hbkxpc3Q7CiAgICAgICAgdmFyIGxvd2VyUm9tYW5MaXN0OwogICAgICAgIHZhciB1cHBlckFscGhhTGlzdDsKICAgICAgICB2YXIgbG93ZXJBbHBoYUxpc3Q7CgogICAgICAgIC8vaWYgKCFsaXN0ICYmICFvdGhlckxpc3QgJiYgY29tcG9zZXIuY29tbWFuZHMuc3VwcG9ydChjb21tYW5kKSkgewogICAgICAgIC8vICAgICAgZG9jLmV4ZWNDb21tYW5kKGNvbW1hbmQsIGZhbHNlLCBudWxsKTsKICAgICAgICAvLyAgICAgIHJldHVybjsKICAgICAgICAvL30KCiAgICAgICAgaWYgKGxpc3QgJiYgKGxpc3RUeXBlID09ICJOb25lIikpIHsKICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS5kb20ucmVzb2x2ZUxpc3QobGlzdCwgY29tcG9zZXIuY29uZmlnLnVzZUxpbmVCcmVha3MpOwogICAgICAgICAgICB9KTsKICAgICAgICB9IGVsc2UgaWYgKG90aGVyTGlzdCAmJiAobGlzdFR5cGUgPT0gIk5vbmUiKSkgewogICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5yZXNvbHZlTGlzdChvdGhlckxpc3QsIGNvbXBvc2VyLmNvbmZpZy51c2VMaW5lQnJlYWtzKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICBpZiAobGlzdCAhPSBudWxsICYmIGxpc3QuZ2V0QXR0cmlidXRlKCJ0eXBlIikgPT0gIkkiKSB7CiAgICAgICAgICAgIHVwcGVyUm9tYW5MaXN0ID0gbGlzdDsKICAgICAgICAgICAgbGlzdCA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChsaXN0ICE9IG51bGwgJiYgbGlzdC5nZXRBdHRyaWJ1dGUoInR5cGUiKSA9PSAiaSIpIHsKICAgICAgICAgICAgbG93ZXJSb21hbkxpc3QgPSBsaXN0OwogICAgICAgICAgICBsaXN0ID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKGxpc3QgIT0gbnVsbCAmJiBsaXN0LmdldEF0dHJpYnV0ZSgidHlwZSIpID09ICJBIikgewogICAgICAgICAgICB1cHBlckFscGhhTGlzdCA9IGxpc3Q7CiAgICAgICAgICAgIGxpc3QgPSBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAobGlzdCAhPSBudWxsICYmIGxpc3QuZ2V0QXR0cmlidXRlKCJ0eXBlIikgPT0gImEiKSB7CiAgICAgICAgICAgIGxvd2VyQWxwaGFMaXN0ID0gbGlzdDsKICAgICAgICAgICAgbGlzdCA9IG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZiAobGlzdCAmJiAobGlzdFR5cGUgPT0gIk9yZGVyZWQiKSkgewogICAgICAgICAgICAvLyBVbndyYXAgbGlzdAogICAgICAgICAgICAvLyA8b2w+PGxpPmZvbzwvbGk+PGxpPmJhcjwvbGk+PC9vbD4KICAgICAgICAgICAgLy8gYmVjb21lczoKICAgICAgICAgICAgLy8gZm9vPGJyPmJhcjxicj4KICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS5kb20ucmVzb2x2ZUxpc3QobGlzdCwgY29tcG9zZXIuY29uZmlnLnVzZUxpbmVCcmVha3MpOwogICAgICAgICAgICB9KTsKICAgICAgICB9IGVsc2UgaWYgKHVwcGVyUm9tYW5MaXN0ICYmIChsaXN0VHlwZSA9PSAiSSIpKSB7CiAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5leGVjdXRlQW5kUmVzdG9yZShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB3eXNpaHRtbDUuZG9tLnJlc29sdmVMaXN0KHVwcGVyUm9tYW5MaXN0LCBjb21wb3Nlci5jb25maWcudXNlTGluZUJyZWFrcyk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSBpZiAobG93ZXJSb21hbkxpc3QgJiYgKGxpc3RUeXBlID09ICJpIikpIHsKICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS5kb20ucmVzb2x2ZUxpc3QobG93ZXJSb21hbkxpc3QsIGNvbXBvc2VyLmNvbmZpZy51c2VMaW5lQnJlYWtzKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSBlbHNlIGlmICh1cHBlckFscGhhTGlzdCAmJiAobGlzdFR5cGUgPT0gIkEiKSkgewogICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5yZXNvbHZlTGlzdCh1cHBlckFscGhhTGlzdCwgY29tcG9zZXIuY29uZmlnLnVzZUxpbmVCcmVha3MpOwogICAgICAgICAgICB9KTsKICAgICAgICB9IGVsc2UgaWYgKGxvd2VyQWxwaGFMaXN0ICYmIChsaXN0VHlwZSA9PSAiYSIpKSB7CiAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5leGVjdXRlQW5kUmVzdG9yZShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB3eXNpaHRtbDUuZG9tLnJlc29sdmVMaXN0KGxvd2VyQWxwaGFMaXN0LCBjb21wb3Nlci5jb25maWcudXNlTGluZUJyZWFrcyk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSBpZiAob3RoZXJMaXN0KSB7CiAgICAgICAgICAgIC8vIFR1cm4gYW4gdW5vcmRlcmVkIGxpc3QgaW50byBhbiBvcmRlcmVkIGxpc3QKICAgICAgICAgICAgLy8gPHVsPjxsaT5mb288L2xpPjxsaT5iYXI8L2xpPjwvdWw+CiAgICAgICAgICAgIC8vIGJlY29tZXM6CiAgICAgICAgICAgIC8vIDxvbD48bGk+Zm9vPC9saT48bGk+YmFyPC9saT48L29sPgogICAgICAgICAgICB2YXIgZWwgPSBjb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSB3eXNpaHRtbDUuZG9tLnJlbmFtZUVsZW1lbnQob3RoZXJMaXN0LCAib2wiKTsKICAgICAgICAgICAgICAgIHZhciBhdHRyaWJ1dGUgPSB7fTsKICAgICAgICAgICAgICAgIGF0dHJpYnV0ZS50eXBlID0gbGlzdFR5cGU7CiAgICAgICAgICAgICAgICB3eXNpaHRtbDUuZG9tLnNldEF0dHJpYnV0ZXMoYXR0cmlidXRlKS5vbihlbGVtZW50KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlmIChlbCAhPSBudWxsICYmIGxpc3RUeXBlICE9ICJPcmRlcmVkIikgewogICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKCJ0eXBlIiwgbGlzdFR5cGUpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChsb3dlclJvbWFuTGlzdCB8fCB1cHBlclJvbWFuTGlzdCB8fCBsb3dlckFscGhhTGlzdCB8fCB1cHBlckFscGhhTGlzdCkgewogICAgICAgICAgICB2YXIgZWwgPSB3eXNpaHRtbDUuY29tbWFuZHMuaW5zZXJ0T3JkZXJlZExpc3Quc3RhdGUoY29tcG9zZXIpOwogICAgICAgICAgICBpZiAoZWwgIT0gbnVsbCAmJiAobGlzdFR5cGUgPT0gIk9yZGVyZWQiKSkgewogICAgICAgICAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoInR5cGUiLCBsaXN0VHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGxpc3QpIHsKICAgICAgICAgICAgdmFyIGVsID0gd3lzaWh0bWw1LmNvbW1hbmRzLmluc2VydE9yZGVyZWRMaXN0LnN0YXRlKGNvbXBvc2VyKTsKICAgICAgICAgICAgaWYgKGVsICE9IG51bGwgJiYgKGxpc3RUeXBlICE9ICJPcmRlcmVkIikpIHsKICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgidHlwZSIsIGxpc3RUeXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAobGlzdFR5cGUgIT0gIk5vbmUiKSB7CiAgICAgICAgICAgIC8vIENyZWF0ZSBsaXN0CiAgICAgICAgICAgIGNvbXBvc2VyLmNvbW1hbmRzLmV4ZWMoImZvcm1hdEJsb2NrIiwgImRpdiIsIHRlbXBDbGFzc05hbWUpOwogICAgICAgICAgICAvLyBDaGVjayBpZiBtdWx0aXBsZSBlbGVtZW50IGFyZSBmb3VuZAogICAgICAgICAgICB2YXIgdGVtcEVsZW1lbnRzID0gZG9jLnF1ZXJ5U2VsZWN0b3JBbGwoIi4iICsgdGVtcENsYXNzTmFtZSk7CiAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudHMpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsKICAgICAgICAgICAgICAgICAgICAgaW5kZXggPCB0ZW1wRWxlbWVudHMubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICBpbmRleCsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGVtcEVsZW1lbnQgPSB0ZW1wRWxlbWVudHNbaW5kZXhdOwogICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ID0gd3lzaWh0bWw1LmRvbS5jb252ZXJ0VG9MaXN0KHRlbXBFbGVtZW50LCAib2wiLCBsaXN0VHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudC5ub2RlTmFtZSAhPSAiTEkiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcEVsZW1lbnQgPSB3eXNpaHRtbDUuZG9tLnJlbmFtZUVsZW1lbnQodGVtcEVsZW1lbnQsICJsaSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5yZW1vdmVDbGFzcyh0ZW1wRWxlbWVudCwgdGVtcENsYXNzTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRlbXBFbGVtZW50LnF1ZXJ5U2VsZWN0b3Iod3lzaWh0bWw1LkJMT0NLX0VMRU1FTlRTX0dST1VQLmpvaW4oIiwiKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPSAiPHA+IiArIHRlbXBFbGVtZW50LmlubmVySFRNTCArICI8L3A+IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuYXBwZW5kQ2hpbGQodGVtcEVsZW1lbnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlzRW1wdHkgPSB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPT09ICIiIHx8IHRlbXBFbGVtZW50LmlubmVySFRNTCA9PT0gd3lzaWh0bWw1LklOVklTSUJMRV9TUEFDRSB8fCB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPT09ICI8YnI+IjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRW1wdHkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZWxlY3ROb2RlKGxpc3QucXVlcnlTZWxlY3RvcigibGkiKSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyKSB7CiAgICAgICAgdmFyIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKTsKICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkTm9kZSwge25vZGVOYW1lIDogIk9MIn0pOwogICAgfSwKCiAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCB2YWx1ZSwgaXNEZWZhdWx0KSB7CiAgICAgICAgdmFyIGRvbUVsZW0gPSB0aGlzLnN0YXRlKGNvbXBvc2VyKTsKICAgICAgICBpZiAoZG9tRWxlbSkgewogICAgICAgICAgICB2YXIgYXR0clZhbCA9IGRvbUVsZW0uZ2V0QXR0cmlidXRlKCd0eXBlJyk7CiAgICAgICAgICAgIGlmIChhdHRyVmFsID09IG51bGwgJiYgdmFsdWUgPT0gJ09yZGVyZWQnKSB7Ly93aGVuIHZhbHVlIGlzICdPcmRlcmVkJywgZGVmYXVsdCBvcmRlcmVkIGxpc3QgbnVtYmVyaW5nIGlzIHVzZWQsIG5vIHR5cGUgYXR0cmlidXRlLgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGF0dHJWYWwgPT0gdmFsdWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9IGVsc2UgaWYgKGlzRGVmYXVsdCkgeyAgICAgICAgIC8vbm8gZG9tRWxlbSB3aXRoICJPTCIgd291bGQgYmUgZm91bmQgaWYgd2UgaGF2ZSBub25lIHR5cGUKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfTsKCnd5c2lodG1sNS5jb21tYW5kcy5pbnNlcnRVbm9yZGVyZWRMaXN0ID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgIHZhciBkb2MgPSBjb21wb3Nlci5kb2MsCiAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUodW5kZWZpbmVkLCB0cnVlKSwKICAgICAgICAgICAgbGlzdCA9IHd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHtub2RlTmFtZSA6ICJVTCJ9KSwKICAgICAgICAgICAgb3RoZXJMaXN0ID0gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkTm9kZSwge25vZGVOYW1lIDogIk9MIn0pLAogICAgICAgICAgICB0ZW1wQ2xhc3NOYW1lID0gIl93eXNpaHRtbDUtdGVtcC0iICsgbmV3IERhdGUoKS5nZXRUaW1lKCksCiAgICAgICAgICAgIGlzRW1wdHksCiAgICAgICAgICAgIHRlbXBFbGVtZW50OwoKICAgICAgICBpZiAoIWxpc3QgJiYgIW90aGVyTGlzdCAmJiBjb21wb3Nlci5jb21tYW5kcy5zdXBwb3J0KGNvbW1hbmQpKSB7CiAgICAgICAgICAgIGRvYy5leGVjQ29tbWFuZChjb21tYW5kLCBmYWxzZSwgbnVsbCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmIChsaXN0KSB7CiAgICAgICAgICAgIC8vIFVud3JhcCBsaXN0CiAgICAgICAgICAgIC8vIDx1bD48bGk+Zm9vPC9saT48bGk+YmFyPC9saT48L3VsPgogICAgICAgICAgICAvLyBiZWNvbWVzOgogICAgICAgICAgICAvLyBmb288YnI+YmFyPGJyPgogICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5yZXNvbHZlTGlzdChsaXN0LCBjb21wb3Nlci5jb25maWcudXNlTGluZUJyZWFrcyk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSBpZiAob3RoZXJMaXN0KSB7CiAgICAgICAgICAgIC8vIFR1cm4gYW4gb3JkZXJlZCBsaXN0IGludG8gYW4gdW5vcmRlcmVkIGxpc3QKICAgICAgICAgICAgLy8gPG9sPjxsaT5mb288L2xpPjxsaT5iYXI8L2xpPjwvb2w+CiAgICAgICAgICAgIC8vIGJlY29tZXM6CiAgICAgICAgICAgIC8vIDx1bD48bGk+Zm9vPC9saT48bGk+YmFyPC9saT48L3VsPgogICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5yZW5hbWVFbGVtZW50KG90aGVyTGlzdCwgInVsIik7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIENyZWF0ZSBsaXN0CiAgICAgICAgICAgIGNvbXBvc2VyLmNvbW1hbmRzLmV4ZWMoImZvcm1hdEJsb2NrIiwgImRpdiIsIHRlbXBDbGFzc05hbWUpOwogICAgICAgICAgICB2YXIgdGVtcEVsZW1lbnRzID0gZG9jLnF1ZXJ5U2VsZWN0b3JBbGwoIi4iICsgdGVtcENsYXNzTmFtZSk7CiAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudHMpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggPCB0ZW1wRWxlbWVudHMubGVuZ3RoOyBpbmRleCsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGVtcEVsZW1lbnQgPSB0ZW1wRWxlbWVudHNbaW5kZXhdOwogICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ID0gd3lzaWh0bWw1LmRvbS5jb252ZXJ0VG9MaXN0KHRlbXBFbGVtZW50LCAidWwiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXBFbGVtZW50Lm5vZGVOYW1lICE9ICJMSSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wRWxlbWVudCA9IHd5c2lodG1sNS5kb20ucmVuYW1lRWxlbWVudCh0ZW1wRWxlbWVudCwgImxpIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUuZG9tLnJlbW92ZUNsYXNzKHRlbXBFbGVtZW50LCB0ZW1wQ2xhc3NOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFdyYXAgd2l0aGluIHBhcmEgdGFnIGlmIG5vIGJsb2NrIGVsZW1lbnQgcHJlc2VudCovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRlbXBFbGVtZW50LnF1ZXJ5U2VsZWN0b3Iod3lzaWh0bWw1LkJMT0NLX0VMRU1FTlRTX0dST1VQLmpvaW4oIiwiKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPSAiPHA+IiArIHRlbXBFbGVtZW50LmlubmVySFRNTCArICI8L3A+IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuYXBwZW5kQ2hpbGQodGVtcEVsZW1lbnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlzRW1wdHkgPSB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPT09ICIiIHx8IHRlbXBFbGVtZW50LmlubmVySFRNTCA9PT0gd3lzaWh0bWw1LklOVklTSUJMRV9TUEFDRSB8fCB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPT09ICI8YnI+IjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRW1wdHkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZWxlY3ROb2RlKGxpc3QucXVlcnlTZWxlY3RvcigibGkiKSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyKSB7CiAgICAgICAgdmFyIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKTsKICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkTm9kZSwge25vZGVOYW1lIDogIlVMIn0pOwogICAgfSwKCiAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyKSB7CiAgICAgICAgdmFyIGRvbUVsZW0gPSB0aGlzLnN0YXRlKGNvbXBvc2VyKTsKICAgICAgICBpZiAoZG9tRWxlbSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9Owp3eXNpaHRtbDUuY29tbWFuZHMuaXRhbGljID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLmV4ZWMoY29tcG9zZXIsIGNvbW1hbmQsICJpIik7CiAgICAgICAgLy9yZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5leGVjKGNvbXBvc2VyLCBjb21tYW5kLCAiaSIpOwogICAgfSwKCiAgICBzdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgIC8vIGVsZW1lbnQub3duZXJEb2N1bWVudC5xdWVyeUNvbW1hbmRTdGF0ZSgiaXRhbGljIikgcmVzdWx0czoKICAgICAgICAvLyBmaXJlZm94OiBvbmx5IDxpPgogICAgICAgIC8vIGNocm9tZTogIDxpPiwgPGVtPiwgPGJsb2NrcXVvdGU+LCAuLi4KICAgICAgICAvLyBpZTogICAgICA8aT4sIDxlbT4KICAgICAgICAvLyBvcGVyYTogICBvbmx5IDxpPgogICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAiaSIpOwogICAgfQp9OwoKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHd5c2lodG1sNS5jb21tYW5kcy5pbmNyZWFzZUluZGVudCA9IHsKICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciByYW5nZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRSYW5nZSgpOwogICAgICAgICAgICB2YXIgdGV4dE5vZGVzID0gcmFuZ2UuZ2V0Tm9kZXMoW3d5c2lodG1sNS5URVhUX05PREVdKTsKICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZVZhbHVlOwogICAgICAgICAgICBpZiAodGV4dE5vZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgdmFyIHRleHROb2RlOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRleHROb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICAgICAgICAgICsraSkgewogICAgICAgICAgICAgICAgICAgIHRleHROb2RlID0gdGV4dE5vZGVzW2ldOwogICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnQgPSB0ZXh0Tm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZVZhbHVlID0gcGFyZW50LnN0eWxlWyJwYWRkaW5nLWxlZnQiXTsKICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVWYWx1ZSA9IGF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoL3B4LywgIiIpOwogICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZVZhbHVlID0gYXR0cmlidXRlVmFsdWUucmVwbGFjZSgvcHQvLCAiIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSBwYXJzZUludCg0MCkgKyBwYXJzZUludChhdHRyaWJ1dGVWYWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZSArICJwdCI7CgogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsidGV4dC1pbmRlbnQiIDogdmFsdWV9OwoKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAicGFkZGluZy1sZWZ0IiwgL3BhZGRpbmctbGVmdC9nLCBhdHRyaWJ1dGVzKTsKICAgICAgICB9LAoKICAgICAgICBzdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgdmFsdWUpIHsKICAgICAgICAgICAgLy8gZWxlbWVudC5vd25lckRvY3VtZW50LnF1ZXJ5Q29tbWFuZFN0YXRlKCJpdGFsaWMiKSByZXN1bHRzOgogICAgICAgICAgICAvLyBmaXJlZm94OiBvbmx5IDxpPgogICAgICAgICAgICAvLyBjaHJvbWU6ICA8aT4sIDxlbT4sIDxibG9ja3F1b3RlPiwgLi4uCiAgICAgICAgICAgIC8vIGllOiAgICAgIDxpPiwgPGVtPgogICAgICAgICAgICAvLyBvcGVyYTogICBvbmx5IDxpPgogICAgICAgICAgICAvL3JldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAic3BhbiIsImZvbnQtZmFtaWx5LSIrZm9udGZhbWlseSwnL2ZvbnQtZmFtaWx5LVswLTlhLXpdKy9nJywiZm9udC1mYW1pbHkiLGZvbnRmYW1pbHkpOwogICAgICAgICAgICB2YWx1ZSA9IHZhbHVlICsgInB0IjsKICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7InRleHQtaW5kZW50IiA6IHZhbHVlfTsKCiAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAic3BhbiIsICJwYWRkaW5nLWxlZnQiLCAvcGFkZGluZy1sZWZ0L2csIGF0dHJpYnV0ZXMpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CgooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmZvbnRGYW1pbHkgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgZm9udGZhbWlseSkgewoKICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7ImZvbnQtZmFtaWx5IiA6IGZvbnRmYW1pbHl9OwoKICAgICAgICAgICAgLy9yZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5leGVjKGNvbXBvc2VyLCBjb21tYW5kLCAicCIsImZvbnQtZmFtaWx5LSIrZm9udGZhbWlseSwvZm9udC1mYW1pbHktWzAtOWEtel0rL2csImZvbnQtZmFtaWx5Iixmb250ZmFtaWx5KTsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAiZm9udC1mYW1pbHkiLCAvZm9udC1mYW1pbHkvZywgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGZvbnRmYW1pbHkpIHsKICAgICAgICAgICAgLy8gZWxlbWVudC5vd25lckRvY3VtZW50LnF1ZXJ5Q29tbWFuZFN0YXRlKCJpdGFsaWMiKSByZXN1bHRzOgogICAgICAgICAgICAvLyBmaXJlZm94OiBvbmx5IDxpPgogICAgICAgICAgICAvLyBjaHJvbWU6ICA8aT4sIDxlbT4sIDxibG9ja3F1b3RlPiwgLi4uCiAgICAgICAgICAgIC8vIGllOiAgICAgIDxpPiwgPGVtPgogICAgICAgICAgICAvLyBvcGVyYTogICBvbmx5IDxpPgogICAgICAgICAgICAvL3JldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAic3BhbiIsImZvbnQtZmFtaWx5LSIrZm9udGZhbWlseSwnL2ZvbnQtZmFtaWx5LVswLTlhLXpdKy9nJywiZm9udC1mYW1pbHkiLGZvbnRmYW1pbHkpOwogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiZm9udC1mYW1pbHkiIDogZm9udGZhbWlseX07CgogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAiZm9udC1mYW1pbHkiLCAvZm9udC1mYW1pbHkvZywgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKICAgICAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciBkb21FbGVtID0gdGhpcy5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgbnVsbCk7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IFtdOwogICAgICAgICAgICAvLyBkb21FbGVtZW50IGkuZSBTZWxlY3RlZCB0ZXh0IG5vZGVzIGV4aXN0CiAgICAgICAgICAgIGlmIChkb21FbGVtICYmIGRvbUVsZW0ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB2YXIgZm9udEZhbWlseTsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZG9tRWxlbS5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIC8vIGRvbUVsZW1lbnQgaGFzIHN0eWxlIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgIGlmIChkb21FbGVtW2ldLnN0eWxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldHRpbmcgZGlmZmVyZW50IGZvbnQgZmFtaWxpZXMgYXBwbGllZCB0byBzZWxlY3RlZCB0ZXh0cwogICAgICAgICAgICAgICAgICAgICAgICBmb250RmFtaWx5ID0gZG9tRWxlbVtpXS5zdHlsZS5mb250RmFtaWx5OwogICAgICAgICAgICAgICAgICAgICAgICBmb250RmFtaWx5ID0gZm9udEZhbWlseS5zcGxpdCgiLCIpWzBdOwogICAgICAgICAgICAgICAgICAgICAgICBmb250RmFtaWx5ID0gZm9udEZhbWlseS5yZXBsYWNlKC9cIi9nLCAiIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRGYW1pbHkgPSBmb250RmFtaWx5LnJlcGxhY2UoLycvZywgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBmb250IGZhbWlseSBpcyBub3QgYWxyZWFkeSByZXRyaWV2ZWQgZnJvbSBzZWxlY3RlZCB0ZXh0cywgYWRkIGZvbnQgZmFtaWx5CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmFsdWUuaW5jbHVkZXMoZm9udEZhbWlseSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLnB1c2goZm9udEZhbWlseSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMuY3VzdG9tU3R5bGUgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgY2xhc3NlcykgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiY3VzdG9tU3R5bGVBdHRyaWJ1dGUiIDogdHJ1ZX07CiAgICAgICAgICAgIHZhciBjbGFzc05hbWUgPSAiIHRleHRFZGl0b3ItY3VzdG9tU3R5bGUgIjsKICAgICAgICAgICAgdmFyIFJFR19FWFAgPSBuZXcgUmVnRXhwKGNsYXNzTmFtZSArICJjbS10ZXh0ZWRpdG9yLWN1c3RvbXN0eWxlLVthLXpdKyIsICJnIik7CiAgICAgICAgICAgIGlmIChjbGFzc2VzKSB7CiAgICAgICAgICAgICAgICBjbGFzc05hbWUgKz0gY2xhc3NlczsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5leGVjKGNvbXBvc2VyLCBjb21tYW5kLCAic3BhbiIsIGNsYXNzTmFtZSwgUkVHX0VYUCwgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGRhdGFBdHRyaWJ1dGUsIGNsZWFyUHJlRGF0YUF0dHJpYnV0ZSwgY2xhc3NlcykgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiY3VzdG9tU3R5bGVBdHRyaWJ1dGUiIDogdHJ1ZX07CiAgICAgICAgICAgIHZhciBjbGFzc05hbWUgPSAiIHRleHRFZGl0b3ItY3VzdG9tU3R5bGUgIjsKICAgICAgICAgICAgdmFyIFJFR19FWFAgPSBuZXcgUmVnRXhwKGNsYXNzTmFtZSArICJjbS10ZXh0ZWRpdG9yLWN1c3RvbXN0eWxlLVthLXpdKyIsICJnIik7CiAgICAgICAgICAgIGlmIChjbGFzc2VzKSB7CiAgICAgICAgICAgICAgICBjbGFzc05hbWUgKz0gY2xhc3NlczsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCBjbGFzc05hbWUsIFJFR19FWFAsIGF0dHJpYnV0ZXMpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMuZGF0YUF0dHJpYnV0ZSA9IHsKICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBkYXRhQXR0ciwgY2xlYXJQcmVEYXRhQXR0cmlidXRlKSB7CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJkYXRhQXR0cmlidXRlIiA6IHRydWV9OwogICAgICAgICAgICB2YXIgY2xhc3NOYW1lID0gInRleHRFZGl0b3ItY3VzdG9tRGF0YUF0dHIiOwogICAgICAgICAgICB2YXIgUkVHX0VYUCA9IG5ldyBSZWdFeHAoY2xhc3NOYW1lLCAiZyIpOwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5leGVjKGNvbXBvc2VyLCBjb21tYW5kLCAic3BhbiIsIGNsYXNzTmFtZSwgUkVHX0VYUCwgYXR0cmlidXRlcywgbnVsbCwgZGF0YUF0dHIsIGNsZWFyUHJlRGF0YUF0dHJpYnV0ZSk7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGRhdGFBdHRyaWJ1dGUsIGNsZWFyUHJlRGF0YUF0dHJpYnV0ZSkgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiZGF0YUF0dHJpYnV0ZSIgOiB0cnVlfTsKICAgICAgICAgICAgdmFyIGNsYXNzTmFtZSA9ICJ0ZXh0RWRpdG9yLWN1c3RvbURhdGFBdHRyIjsKICAgICAgICAgICAgdmFyIFJFR19FWFAgPSBuZXcgUmVnRXhwKGNsYXNzTmFtZSwgImciKTsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsICJzcGFuIiwgY2xhc3NOYW1lLCBSRUdfRVhQLCBhdHRyaWJ1dGVzLCBudWxsLCBkYXRhQXR0cmlidXRlLCBjbGVhclByZURhdGFBdHRyaWJ1dGUpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMuaGVhZGVyID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGhlYWRlclR5cGUpIHsKICAgICAgICAgICAgdmFyIGNsYXNzTmFtZSA9ICJ0ZXh0RWRpdG9yLWhlYWRlci0iOwogICAgICAgICAgICB2YXIgUkVHX0VYUCA9IG5ldyBSZWdFeHAoY2xhc3NOYW1lICsgIlteXHNdKiIsICJnIik7CiAgICAgICAgICAgIGNsYXNzTmFtZSArPSBoZWFkZXJUeXBlOwogICAgICAgICAgICB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0QmxvY2suZXhlYyhjb21wb3NlciwgY29tbWFuZCwgaGVhZGVyVHlwZSwgY2xhc3NOYW1lLCBSRUdfRVhQKTsKICAgICAgICAgICAgdmFyIGRvbUVsZW0gPSB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0QmxvY2suc3RhdGUoY29tcG9zZXIsICdsaW5lSGVpZ2h0JywgaGVhZGVyVHlwZSk7CiAgICAgICAgICAgIHd5c2lodG1sNS51dGlsLmNsZWFyRm9udFNpemUoZG9tRWxlbSk7CiAgICAgICAgICAgIHZhciBsZWFkaW5nOwogICAgICAgICAgICBpZiAoZG9tRWxlbSAmJiBkb21FbGVtLnN0eWxlICYmIGRvbUVsZW0uc3R5bGUubGluZUhlaWdodCkgewogICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLnNlbGVjdE5vZGUoZG9tRWxlbSk7CiAgICAgICAgICAgICAgICB2YXIgY29tcHV0ZWRTdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShkb21FbGVtKTsKICAgICAgICAgICAgICAgIHZhciBtYXhGb250U2l6ZSA9IDA7CiAgICAgICAgICAgICAgICBpZiAoY29tcHV0ZWRTdHlsZXMpIHsKICAgICAgICAgICAgICAgICAgICBtYXhGb250U2l6ZSA9IGNvbXB1dGVkU3R5bGVzLmZvbnRTaXplOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFtYXhGb250U2l6ZSkgewogICAgICAgICAgICAgICAgICAgIG1heEZvbnRTaXplID0gY29tcG9zZXIuY29uZmlnLmRlZmF1bHRGb250U2l6ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChkb21FbGVtLmdldEF0dHJpYnV0ZSkgewogICAgICAgICAgICAgICAgICAgIGxlYWRpbmcgPSAoZG9tRWxlbSkuZ2V0QXR0cmlidXRlKCJsZWFkaW5nIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWxlYWRpbmcpIHsKICAgICAgICAgICAgICAgICAgICBsZWFkaW5nID0gY29tcG9zZXIuY29uZmlnLmRlZmF1bHRMaW5lSGVpZ2h0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGxpbmVIZWlnaHRWYWx1ZSA9IHBhcnNlSW50KGxlYWRpbmcpICsgcGFyc2VJbnQobWF4Rm9udFNpemUpOwogICAgICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7bGluZUhlaWdodCA6IGxpbmVIZWlnaHRWYWx1ZSwgbGVhZGluZyA6IGxlYWRpbmd9OwogICAgICAgICAgICAgICAgLy8gYWRqdXN0aW5nIGxlYWRpbmcgYW5kIGxpbmVoZWlnaHQgZGVwZW5kaW5nIHVwb24gY2hhbmdlIGluIGZvbnRzaXplLCB0aGlzIGlzIHBhcnQgb2YgZm9udHNpemUgdHJhbnNhY3Rpb24sIHdlIHdvbid0IGFsbG93IHVuZG8gZm9yIHRoaXMuCiAgICAgICAgICAgICAgICBkb21FbGVtLnN0eWxlLnNldFByb3BlcnR5KCJsaW5lLWhlaWdodCIsIGxpbmVIZWlnaHRWYWx1ZSArICJwdCIpOwogICAgICAgICAgICAgICAgZG9tRWxlbS5zZXRBdHRyaWJ1dGUoImxlYWRpbmciLCBsZWFkaW5nKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBoZWFkZXJUeXBlKSB7CiAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0QmxvY2suc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsIGhlYWRlclR5cGUpOwogICAgICAgIH0sCiAgICAgICAgY2FsbGJhY2tTdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgICAgICB2YXIgZG9tRWxlbSA9IHRoaXMuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsIFsiUCIsICJIMSIsICJIMiIsICJIMyIsICJINCIsICJINSIsICJINiJdKTsKICAgICAgICAgICAgdmFyIHZhbHVlID0gIiI7CiAgICAgICAgICAgIGlmIChkb21FbGVtICYmIGRvbUVsZW0ubm9kZU5hbWUpIHsKICAgICAgICAgICAgICAgIHZhbHVlID0gZG9tRWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgaWYgKCF3eXNpaHRtbDUuaGVscGVyRm4pIHsKICAgICAgICB3eXNpaHRtbDUuaGVscGVyRm4gPSB7fTsKICAgIH0KCiAgICB3eXNpaHRtbDUuaGVscGVyRm4uZ2V0UHJvcGVydHlWYWx1ZSA9IGZ1bmN0aW9uIChkb21FbGVtLCBwcm9wZXJ0eU5hbWUpIHsKICAgICAgICBpZiAoZG9tRWxlbSAmJiBkb21FbGVtLnN0eWxlKSB7CiAgICAgICAgICAgIHJldHVybiBkb21FbGVtLnN0eWxlLmdldFByb3BlcnR5VmFsdWUocHJvcGVydHlOYW1lKS5yZXBsYWNlKCdwdCcsICcnKS5yZXBsYWNlKCdweCcsICcnKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwoKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHd5c2lodG1sNS5jb21tYW5kcy5tYXJnaW5MZWZ0ID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIHZhbHVlKSB7CiAgICAgICAgICAgIHZhciBtYXJnaW5WYWx1ZSA9IHZhbHVlICsgInB0IjsKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJtYXJnaW4tbGVmdCIgOiBtYXJnaW5WYWx1ZX0pOwogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBtYXJnaW5WYWx1ZSkgewogICAgICAgICAgICBpZiAobWFyZ2luVmFsdWUpIHsKICAgICAgICAgICAgICAgIG1hcmdpblZhbHVlID0gbWFyZ2luVmFsdWUgKyAicHQiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJtYXJnaW4tbGVmdCIgOiBtYXJnaW5WYWx1ZX07CiAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0QmxvY2suc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsIFsiUCIsICJMSSIsICJIMSIsICJIMiIsICJIMyIsICJINCIsICJINSIsICJINiJdLCAibWFyZ2luLWxlZnQiLCAvbWFyZ2luLWxlZnQvZywgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKCiAgICAgICAgY2FsbGJhY2tTdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgbWFyZ2luVmFsdWUpIHsKICAgICAgICAgICAgdmFyIGRvbUVsZW0gPSB0aGlzLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kKTsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5oZWxwZXJGbi5nZXRQcm9wZXJ0eVZhbHVlKGRvbUVsZW0sICJtYXJnaW4tbGVmdCIpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMubWFyZ2luUmlnaHQgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgdmFsdWUpIHsKICAgICAgICAgICAgdmFyIG1hcmdpblZhbHVlID0gdmFsdWUgKyAicHQiOwogICAgICAgICAgICBjb21wb3Nlci5hcHBseVN0eWxlKGNvbXBvc2VyLCB7Im1hcmdpbi1yaWdodCIgOiBtYXJnaW5WYWx1ZX0pOwogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBtYXJnaW5WYWx1ZSkgewogICAgICAgICAgICBpZiAobWFyZ2luVmFsdWUpIHsKICAgICAgICAgICAgICAgIG1hcmdpblZhbHVlID0gbWFyZ2luVmFsdWUgKyAicHQiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJtYXJnaW4tcmlnaHQiIDogbWFyZ2luVmFsdWV9OwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdEJsb2NrLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCBbIlAiLCAiTEkiLCAiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiXSwgIm1hcmdpbi1yaWdodCIsIC9tYXJnaW4tcmlnaHQvZywgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKCiAgICAgICAgY2FsbGJhY2tTdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgICAgICB2YXIgZG9tRWxlbSA9IHRoaXMuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQpOwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmhlbHBlckZuLmdldFByb3BlcnR5VmFsdWUoZG9tRWxlbSwgIm1hcmdpbi1yaWdodCIpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMubWFyZ2luVG9wID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIHZhbHVlKSB7CiAgICAgICAgICAgIHZhciBtYXJnaW5WYWx1ZSA9IHZhbHVlICsgInB0IjsKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJtYXJnaW4tdG9wIiA6IG1hcmdpblZhbHVlfSk7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIG1hcmdpblZhbHVlKSB7CiAgICAgICAgICAgIGlmIChtYXJnaW5WYWx1ZSkgewogICAgICAgICAgICAgICAgbWFyZ2luVmFsdWUgPSBtYXJnaW5WYWx1ZSArICJwdCI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7Im1hcmdpbi10b3AiIDogbWFyZ2luVmFsdWV9OwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdEJsb2NrLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCBbIlAiLCAiTEkiLCAiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiXSwgIm1hcmdpbi10b3AiLCAvbWFyZ2luLXRvcC9nLCBhdHRyaWJ1dGVzKTsKICAgICAgICB9LAoKICAgICAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciBkb21FbGVtID0gdGhpcy5zdGF0ZShjb21wb3NlciwgY29tbWFuZCk7CiAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUuaGVscGVyRm4uZ2V0UHJvcGVydHlWYWx1ZShkb21FbGVtLCAibWFyZ2luLXRvcCIpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMubWFyZ2luQm90dG9tID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIHZhbHVlKSB7CiAgICAgICAgICAgIHZhciBtYXJnaW5WYWx1ZSA9IHZhbHVlICsgInB0IjsKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJtYXJnaW4tYm90dG9tIiA6IG1hcmdpblZhbHVlfSk7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIG1hcmdpblZhbHVlKSB7CiAgICAgICAgICAgIGlmIChtYXJnaW5WYWx1ZSkgewogICAgICAgICAgICAgICAgbWFyZ2luVmFsdWUgPSBtYXJnaW5WYWx1ZSArICJwdCI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7Im1hcmdpbi1ib3R0b20iIDogbWFyZ2luVmFsdWV9OwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdEJsb2NrLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCBbIlAiLCAiTEkiLCAiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiXSwgIm1hcmdpbi1ib3R0b20iLCAvbWFyZ2luLWJvdHRvbS9nLCBhdHRyaWJ1dGVzKTsKICAgICAgICB9LAoKICAgICAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBtYXJnaW5WYWx1ZSkgewogICAgICAgICAgICB2YXIgZG9tRWxlbSA9IHRoaXMuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsIG51bGwpOwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmhlbHBlckZuLmdldFByb3BlcnR5VmFsdWUoZG9tRWxlbSwgIm1hcmdpbi1ib3R0b20iKTsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwoKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHd5c2lodG1sNS5jb21tYW5kcy5sZXR0ZXJTcGFjaW5nID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIHZhbCkgewogICAgICAgICAgICB2YWwgPSB2YWwgKyAicHQiOwogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsibGV0dGVyLXNwYWNpbmciIDogdmFsfTsKCiAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLmV4ZWMoY29tcG9zZXIsIGNvbW1hbmQsICJzcGFuIiwgImxldHRlci1zcGFjaW5nIiwgL2xldHRlci1zcGFjaW5nL2csIGF0dHJpYnV0ZXMpOwogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCB2YWwpIHsKICAgICAgICAgICAgaWYgKHZhbCkgewogICAgICAgICAgICAgICAgdmFsID0gdmFsICsgInB0IjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsibGV0dGVyLXNwYWNpbmciIDogdmFsfTsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsICJzcGFuIiwgImxldHRlci1zcGFjaW5nIiwgL2xldHRlci1zcGFjaW5nL2csIGF0dHJpYnV0ZXMpOwogICAgICAgIH0sCgogICAgICAgIGNhbGxiYWNrU3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICAgICAgdmFyIGRvbUVsZW0gPSB0aGlzLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCBudWxsKTsKICAgICAgICAgICAgdmFyIHZhbHVlID0gIiI7CiAgICAgICAgICAgIGlmIChkb21FbGVtKSB7CiAgICAgICAgICAgICAgICB2YWx1ZSA9IHd5c2lodG1sNS5oZWxwZXJGbi5nZXRQcm9wZXJ0eVZhbHVlKGRvbUVsZW1bMF0sICJsZXR0ZXItc3BhY2luZyIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmxpbmVIZWlnaHQgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgYXR0cmlidXRlcykgewogICAgICAgICAgICB2YXIgbGluZUhlaWdodFZhbHVlID0gYXR0cmlidXRlcy5saW5lSGVpZ2h0OwogICAgICAgICAgICBsaW5lSGVpZ2h0VmFsdWUgPSBsaW5lSGVpZ2h0VmFsdWUgKyAicHQiOwogICAgICAgICAgICB2YXIgbGVhZGluZ1ZhbHVlID0gYXR0cmlidXRlcy5sZWFkaW5nOwogICAgICAgICAgICBjb21wb3Nlci5hcHBseVN0eWxlKGNvbXBvc2VyLCB7ImxpbmUtaGVpZ2h0IiA6IGxpbmVIZWlnaHRWYWx1ZX0sIHsibGVhZGluZyIgOiBsZWFkaW5nVmFsdWV9KTsKICAgICAgICB9LAogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCB2YWwpIHsKICAgICAgICAgICAgaWYgKHZhbCkgewogICAgICAgICAgICAgICAgdmFsID0gdmFsICsgInB0IjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsibGluZS1oZWlnaHQiIDogdmFsfTsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRCbG9jay5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInAiLCAibGluZS1oZWlnaHQiLCAvbGluZS1oZWlnaHQvZywgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKICAgICAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciBkb21FbGVtID0gdGhpcy5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgbnVsbCk7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9ICIiOwogICAgICAgICAgICBpZiAoZG9tRWxlbSkgewogICAgICAgICAgICAgICAgdmFsdWUgPSAoZG9tRWxlbSkuZ2V0QXR0cmlidXRlKCJsZWFkaW5nIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMub3V0ZGVudCA9IHsKICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBhbGlnblZhbHVlKSB7CiAgICAgICAgICAgIGlmIChjb21wb3Nlci5jb21tYW5kcy5zdXBwb3J0KGNvbW1hbmQpKSB7CiAgICAgICAgICAgICAgICBjb21wb3Nlci5kb2MuZXhlY0NvbW1hbmQoY29tbWFuZCwgZmFsc2UsICcwcHQgNXB0IDBwdCAwcHQnKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBhbGlnblZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmp1c3RpZnlMZWZ0ID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJ0ZXh0LWFsaWduIiA6ICJsZWZ0In0pOwogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJ0ZXh0LWFsaWduIiA6ICJsZWZ0In07CgogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdEJsb2NrLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAicCIsICJ0ZXh0LWFsaWduIiwgL3RleHQtYWxpZ24vZywgYXR0cmlidXRlcyk7CiAgICAgICAgfQogICAgfTsKfSkod3lzaWh0bWw1KTsKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHd5c2lodG1sNS5jb21tYW5kcy5qdXN0aWZ5Q2VudGVyID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJ0ZXh0LWFsaWduIiA6ICJjZW50ZXIifSk7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7InRleHQtYWxpZ24iIDogImNlbnRlciJ9OwoKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRCbG9jay5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInAiLCAidGV4dC1hbGlnbiIsIC90ZXh0LWFsaWduL2csIGF0dHJpYnV0ZXMpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMuanVzdGlmeUZ1bGwgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewoKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJ0ZXh0LWFsaWduIiA6ICJqdXN0aWZ5In0pOwogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJ0ZXh0LWFsaWduIiA6ICJqdXN0aWZ5In07CgogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdEJsb2NrLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAicCIsICJ0ZXh0LWFsaWduIiwgL3RleHQtYWxpZ24vZywgYXR0cmlidXRlcyk7CiAgICAgICAgfQogICAgfTsKfSkod3lzaWh0bWw1KTsKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHd5c2lodG1sNS5jb21tYW5kcy5qdXN0aWZ5UmlnaHQgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewoKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJ0ZXh0LWFsaWduIiA6ICJyaWdodCJ9KTsKICAgICAgICB9LAoKICAgICAgICBzdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsidGV4dC1hbGlnbiIgOiAicmlnaHQifTsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRCbG9jay5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInAiLCAidGV4dC1hbGlnbiIsIC90ZXh0LWFsaWduL2csIGF0dHJpYnV0ZXMpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7Cgp3eXNpaHRtbDUudXRpbCA9IHt9OwovL0ZvciBmaXhpbmcgTEMtMzkxMTk1NQp3eXNpaHRtbDUudXRpbC5jbGVhckZvbnRTaXplID0gZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgIGlmIChlbGVtZW50ICYmIGVsZW1lbnQuY2hpbGRFbGVtZW50Q291bnQgPiAwKSB7CiAgICAgICAgZm9yICh2YXIgZWxlLCBpbmRleCA9IDA7CiAgICAgICAgICAgICBpbmRleCA8IGVsZW1lbnQuY2hpbGRFbGVtZW50Q291bnQ7CiAgICAgICAgICAgICBpbmRleCsrKSB7CiAgICAgICAgICAgIGVsZSA9IGVsZW1lbnQuY2hpbGRyZW5baW5kZXhdOwogICAgICAgICAgICBpZiAoZWxlICYmIGVsZS5zdHlsZSkgewogICAgICAgICAgICAgICAgZWxlLnN0eWxlLnNldFByb3BlcnR5KCJmb250LXNpemUiLCAiIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGVsZS5jaGlsZEVsZW1lbnRDb3VudCA+IDApIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS51dGlsLmNsZWFyRm9udFNpemUoZWxlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfTsKCnd5c2lodG1sNS51dGlsLmlzRWRpdG9yTm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICByZXR1cm4gbm9kZSAmJiBub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT0gImRpdiIgJiYgbm9kZS5jbGFzc0xpc3QuY29udGFpbnMoInd5c2lodG1sNS1lZGl0b3IiKTsKfTsKCnd5c2lodG1sNS51dGlsLmNoYW5nZUxpbmVIZWlnaHQgPSBmdW5jdGlvbiAobGVhZGluZywgYWxsb3dVbmRvLCBub2RlTmFtZSwgY29tcG9zZXIsIGZvcmNlQXBwbHkpIHsKICAgIGlmIChsZWFkaW5nID09IHVuZGVmaW5lZCkgewogICAgICAgIGxlYWRpbmcgPSBjb21wb3Nlci5jb25maWcuZGVmYXVsdExpbmVIZWlnaHQ7CiAgICB9CiAgICBpZiAoYWxsb3dVbmRvID09IHVuZGVmaW5lZCkgewogICAgICAgIGFsbG93VW5kbyA9IHRydWU7CiAgICB9CiAgICBpZiAobm9kZU5hbWUgPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgbm9kZU5hbWUgPSAiUCI7CiAgICB9CiAgICB2YXIgc2VsZWN0aW9uID0gY29tcG9zZXIuc2VsZWN0aW9uOwogICAgdmFyIGN1cnJlbnRTZWxlY3Rpb24gPSBzZWxlY3Rpb24uZ2V0UmFuZ2UoKTsKICAgIGlmICghY3VycmVudFNlbGVjdGlvbiAmJiBmb3JjZUFwcGx5KSB7Ly8gRml4aW5nIExDLTM5MTE5OTQKICAgICAgICBzZWxlY3Rpb24uc2V0U2VsZWN0aW9uKHNlbGVjdGlvbi5lZGl0b3Iuc2F2ZWRTZWxlY3Rpb24pOwogICAgICAgIGN1cnJlbnRTZWxlY3Rpb24gPSBzZWxlY3Rpb24uZ2V0UmFuZ2UoKTsKICAgIH0KICAgIGlmICghY3VycmVudFNlbGVjdGlvbikgewogICAgICAgIHdpbmRvdy5jb25zb2xlLmxvZygiVGhpcyBlcnJvciBpcyBkdWUgdG8gY2hhbmdlTGluZUhlaWdodCBmdW5jdGlvbi4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICAvKiBmaW5kIHRoZSBtYXhtaW11bSBmb250U2l6ZSBpbiBhIHBhcmFncmFwaCwgYXMgbGluZWhlaWdodCBpcyBhIGJsb2NrIGxldmVsIGF0dHJpYnV0ZSwgbmVlZCB0byBmaW5kIHRoZSBtYXhpbXVtIGZvbnQtc2l6ZSBiZWZvcmUgY2FsY3VsYXRpbmcgbmV3IGxpbmUgaGVpZ2h0Ki8KICAgIHZhciBtYXRjaGluZ1NldCA9IHtub2RlTmFtZSA6IG5vZGVOYW1lfTsKICAgIHZhciBzZWxlY3RlZFRleHRBcnIgPSBzZWxlY3Rpb24uZ2V0Tm9kZXMoMyk7CiAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICBzZWxlY3RlZFRleHRBcnIuZm9yRWFjaChmdW5jdGlvbiAodGV4dCkgewogICAgICAgIHZhciBwYXJlbnRQYXJhZ3JhcGggPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQodGV4dCwgbWF0Y2hpbmdTZXQpOwogICAgICAgIGlmICghcGFyZW50UGFyYWdyYXBoKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYgKChwYXJlbnRQYXJhZ3JhcGggJiYgcGFyZW50UGFyYWdyYXBoLnN0eWxlICYmIHBhcmVudFBhcmFncmFwaC5zdHlsZS5saW5lSGVpZ2h0KSB8fCBmb3JjZUFwcGx5KSB7CiAgICAgICAgICAgIHNlbGVjdGlvbi5zZWxlY3ROb2RlKHBhcmVudFBhcmFncmFwaCk7CiAgICAgICAgICAgIHZhciBmb250U2l6ZVNwYW5BcnIgPSB3eXNpaHRtbDUuY29tbWFuZHMuZm9udFNpemUuc3RhdGUoY29tcG9zZXIsICJmb250U2l6ZSIpOwogICAgICAgICAgICBmb250U2l6ZVNwYW5BcnIgPSBbXS5jb25jYXQoZm9udFNpemVTcGFuQXJyKTsgICAvLyBnZXRDb21tYW5kU3RhdGUgc29tZXRpbWVzIGNhbiByZXR1cm4gYSBzaW5nbGUgc3BhbiBvciBhbiBhcnJheSwgZm9yY2VmdWxseSBjb252ZXJ0aW5nIGludG8gYW4gYXJyYXkKICAgICAgICAgICAgdmFyIG1heEZvbnRTaXplID0gMDsKICAgICAgICAgICAgZm9udFNpemVTcGFuQXJyLmZvckVhY2goZnVuY3Rpb24gKHNwYW4pIHsKICAgICAgICAgICAgICAgIGlmIChzcGFuICYmIHNwYW4uc3R5bGUgJiYgc3Bhbi5zdHlsZS5mb250U2l6ZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBmb250U2l6ZSA9IHNwYW4uc3R5bGUuZm9udFNpemUucmVwbGFjZSgiL3B4LyIsICIiKTsKICAgICAgICAgICAgICAgICAgICBmb250U2l6ZSA9IGZvbnRTaXplLnJlcGxhY2UoIi9wdC8iLCAiIik7CiAgICAgICAgICAgICAgICAgICAgZm9udFNpemUgPSBwYXJzZUludChmb250U2l6ZSk7CiAgICAgICAgICAgICAgICAgICAgbWF4Rm9udFNpemUgPSBNYXRoLm1heChmb250U2l6ZSwgbWF4Rm9udFNpemUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIGlmIChtYXhGb250U2l6ZSA9PSAwKSB7CiAgICAgICAgICAgICAgICBtYXhGb250U2l6ZSA9IGNvbXBvc2VyLmNvbmZpZy5kZWZhdWx0Rm9udFNpemU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGxpbmVIZWlnaHRWYWx1ZSA9IHBhcnNlSW50KGxlYWRpbmcpICsgcGFyc2VJbnQobWF4Rm9udFNpemUpOwogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHtsaW5lSGVpZ2h0IDogbGluZUhlaWdodFZhbHVlLCBsZWFkaW5nIDogbGVhZGluZ307CiAgICAgICAgICAgIC8vIGFkanVzdGluZyBsZWFkaW5nIGFuZCBsaW5laGVpZ2h0IGRlcGVuZGluZyB1cG9uIGNoYW5nZSBpbiBmb250c2l6ZSwgdGhpcyBpcyBwYXJ0IG9mIGZvbnRzaXplIHRyYW5zYWN0aW9uLCB3ZSB3b24ndCBhbGxvdyB1bmRvIGZvciB0aGlzLgogICAgICAgICAgICB3eXNpaHRtbDUuY29tbWFuZHMubGluZUhlaWdodC5leGVjKGNvbXBvc2VyLCAibGluZUhlaWdodCIsIGF0dHJpYnV0ZXMsIGFsbG93VW5kbyk7CiAgICAgICAgfQogICAgfSk7CiAgICBzZWxlY3Rpb24uc2V0U2VsZWN0aW9uKGN1cnJlbnRTZWxlY3Rpb24pOwp9Owp3eXNpaHRtbDUudXRpbC5nZXRUZXh0Tm9kZXMgPSBmdW5jdGlvbiAoc2VsZWN0aW9uKSB7CiAgICB2YXIgdGV4dE5vZGVzID0gc2VsZWN0aW9uLmdldE5vZGVzKHd5c2lodG1sNS5URVhUX05PREUpOwogICAgaWYgKHRleHROb2Rlcy5sZW5ndGggPT0gMCkgewogICAgICAgIHZhciBub2RlID0gc2VsZWN0aW9uLmdldFNlbGVjdGVkTm9kZSgpOwogICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IHd5c2lodG1sNS5URVhUX05PREUpIHsKICAgICAgICAgICAgdGV4dE5vZGVzLnB1c2gobm9kZSk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHRleHROb2RlczsKfTsKCnd5c2lodG1sNS51dGlsLmdldExJTm9kZXNGcm9tVGV4dE5vZGVzID0gZnVuY3Rpb24gKHRleHROb2RlcykgewogICAgdmFyIGxpTm9kZXMgPSBbXTsKICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICBpIDwgdGV4dE5vZGVzLmxlbmd0aDsKICAgICAgICAgKytpKSB7CiAgICAgICAgdmFyIGxpUGFyZW50ID0gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KHRleHROb2Rlc1tpXSwge25vZGVOYW1lIDogIkxJIn0pOwogICAgICAgIGlmIChsaVBhcmVudCkgewogICAgICAgICAgICBsaU5vZGVzLnB1c2gobGlQYXJlbnQpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBsaU5vZGVzOwp9OwoKd3lzaWh0bWw1LnV0aWwuc2V0SW5kZW50ID0gZnVuY3Rpb24gKG5vZGUpIHsKICAgIHZhciBtYXJnaW4gPSBub2RlLnN0eWxlLm1hcmdpbkxlZnQ7CiAgICBtYXJnaW4gPSBtYXJnaW4ucmVwbGFjZSgncHgnLCAnJykucmVwbGFjZSgncHQnLCAnJyk7CiAgICB2YXIgbmV3TWFyZ2luID0gKHBhcnNlSW50KG1hcmdpbikgKyA0MCkgKyAncHQnOwogICAgaWYgKG1hcmdpbiA9PSAiIikgewogICAgICAgIG5ld01hcmdpbiA9ICc0MHB0JzsKICAgIH0KICAgIG5vZGUuc3R5bGUubWFyZ2luTGVmdCA9IG5ld01hcmdpbjsKfTsKd3lzaWh0bWw1LnV0aWwuZGVjcmVhc2VJbmRlbnQgPSBmdW5jdGlvbiAobm9kZSkgewogICAgdmFyIG1hcmdpbiA9IG5vZGUuc3R5bGUubWFyZ2luTGVmdDsKICAgIG1hcmdpbiA9IG1hcmdpbi5yZXBsYWNlKCdweCcsICcnKS5yZXBsYWNlKCdwdCcsICcnKTsKICAgIHZhciBuZXdNYXJnaW4gPSAocGFyc2VJbnQobWFyZ2luKSAtIDQwKSArICdwdCc7CiAgICBub2RlLnN0eWxlLm1hcmdpbkxlZnQgPSBuZXdNYXJnaW47Cn07Cgp3eXNpaHRtbDUudXRpbC5nZXRJbW1lZGlhdGVDaGlsZHNCeVRhZ05hbWUgPSBmdW5jdGlvbiAobm9kZSwgdGFnTmFtZXMpIHsKICAgIHZhciBsaXN0Q2hpbGRzID0gW107CiAgICBpZiAobm9kZSAmJiBub2RlLmNoaWxkcmVuKSB7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7CiAgICAgICAgICAgICBpIDwgbm9kZS5jaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgaWYgKHRhZ05hbWVzLmluZGV4T2Yobm9kZS5jaGlsZHJlbltpXS5ub2RlTmFtZSkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIGxpc3RDaGlsZHMucHVzaChub2RlLmNoaWxkcmVuW2ldKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBsaXN0Q2hpbGRzOwp9OwoKd3lzaWh0bWw1LnV0aWwuZ2V0T2JqZWN0UHJvcGVydHkgPSBmdW5jdGlvbiAob2JqZWN0LCBwYXRoLCBkZWZhdWx0VmFsdWUpIHsKICAgIHZhciBjdXJyT2JqZWN0ID0gb2JqZWN0OwogICAgaWYgKHBhdGgpIHsKICAgICAgICB2YXIgcHJvcHMgPSBwYXRoLnNwbGl0KCIuIik7CiAgICAgICAgcHJvcHMuZm9yRWFjaChmdW5jdGlvbiAocHJvcCkgewogICAgICAgICAgICBpZiAoY3Vyck9iamVjdCAmJiBjdXJyT2JqZWN0Lmhhc093blByb3BlcnR5KHByb3ApKSB7CiAgICAgICAgICAgICAgICBjdXJyT2JqZWN0ID0gY3Vyck9iamVjdFtwcm9wXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGN1cnJPYmplY3QgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0gZWxzZSB7CiAgICAgICAgY3Vyck9iamVjdCA9IHVuZGVmaW5lZDsKICAgIH0KICAgIGlmIChjdXJyT2JqZWN0KSB7CiAgICAgICAgcmV0dXJuIGN1cnJPYmplY3Q7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CiAgICB9Cn07CgooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgd3lzaWh0bWw1LmNvbW1hbmRzLm91dGRlbnQgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgYWxpZ25WYWx1ZSkgewoKICAgICAgICAgICAgdmFyIHJhbmdlID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFJhbmdlKCk7CgogICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCBzZWxlY3Rpb24gY29udGFpbnMgbGlzdCBvZiBvbmx5IG9uZSBsZXZlbCwgZG9uJ3QgZG8gYW55dGhpbmcgaW4gY2FzZSBvZiBtdWx0aSBsZXZlbCovCiAgICAgICAgICAgIHZhciBzdGFydENvbnRhaW5lclBhcmVudExpc3QgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQocmFuZ2Uuc3RhcnRDb250YWluZXIsIHtub2RlTmFtZSA6IFsiT0wiLCAiVUwiXX0pOwogICAgICAgICAgICB2YXIgZW5kQ29udGFpbmVyUGFyZW50TGlzdCA9IHd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudChyYW5nZS5lbmRDb250YWluZXIsIHtub2RlTmFtZSA6IFsiT0wiLCAiVUwiXX0pOwogICAgICAgICAgICBpZiAoc3RhcnRDb250YWluZXJQYXJlbnRMaXN0ICYmIHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCAhPSBlbmRDb250YWluZXJQYXJlbnRMaXN0KSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChzdGFydENvbnRhaW5lclBhcmVudExpc3QgJiYgc3RhcnRDb250YWluZXJQYXJlbnRMaXN0LnN0eWxlICYmIChzdGFydENvbnRhaW5lclBhcmVudExpc3Quc3R5bGUubWFyZ2luTGVmdCAmJiBzdGFydENvbnRhaW5lclBhcmVudExpc3Quc3R5bGUubWFyZ2luTGVmdCAhPSAiMHB4IiAmJiBzdGFydENvbnRhaW5lclBhcmVudExpc3Quc3R5bGUubWFyZ2luTGVmdCAhPSAiMHB0IikpIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS51dGlsLmRlY3JlYXNlSW5kZW50KHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCk7CiAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2VsZWN0Tm9kZShzdGFydENvbnRhaW5lclBhcmVudExpc3QpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9IGVsc2UgaWYgKCFzdGFydENvbnRhaW5lclBhcmVudExpc3QpIHsKICAgICAgICAgICAgICAgIHZhciBub2RlcyA9IGNvbXBvc2VyLnNlbGVjdGlvbiA/IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXROb2RlcygxKSA6IFtdOwogICAgICAgICAgICAgICAgaWYgKCFub2RlcyB8fCBub2Rlcy5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgICAgIG5vZGVzID0gd3lzaWh0bWw1LnV0aWwuZ2V0VGV4dE5vZGVzKGNvbXBvc2VyLnNlbGVjdGlvbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAobm9kZXMpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgIGkgPCBub2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVzW2ldICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnROb2RlID0gbm9kZXNbaV0ucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2Rlcy5pbmRleE9mKHBhcmVudE5vZGUpIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJhID0gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KG5vZGVzW2ldLCB7bm9kZU5hbWUgOiBbIlAiLCAiT0wiLCAiVUwiLCAiRElWIiwgIkgxIiwgIkgyIiwgIkgzIiwgIkg0IiwgIkg1IiwgIkg2Il19KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyYSAmJiBwYXJhLnN0eWxlICYmIHBhcmEuc3R5bGUubWFyZ2luTGVmdCAhPSB1bmRlZmluZWQgJiYgKHBhcmEuc3R5bGUubWFyZ2luTGVmdCAhPSAwICYmIHBhcmEuc3R5bGUubWFyZ2luTGVmdCAhPSAiMHB4IiAmJiBwYXJhLnN0eWxlLm1hcmdpbkxlZnQgIT0gIjBwdCIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHd5c2lodG1sNS51dGlsLmRlY3JlYXNlSW5kZW50KHBhcmEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNvbXBvc2VyLmNvbW1hbmRzLnN1cHBvcnQoY29tbWFuZCkpIHsKICAgICAgICAgICAgICAgIGNvbXBvc2VyLmRvYy5leGVjQ29tbWFuZChjb21tYW5kLCBmYWxzZSwgJzBwdCA1cHQgMHB0IDBwdCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbGlOb2RlcyA9IHd5c2lodG1sNS51dGlsLmdldExJTm9kZXNGcm9tVGV4dE5vZGVzKHd5c2lodG1sNS51dGlsLmdldFRleHROb2Rlcyhjb21wb3Nlci5zZWxlY3Rpb24pKTsKCiAgICAgICAgICAgIGZvciAodmFyIGkgPSBsaU5vZGVzLmxlbmd0aCAtIDE7CiAgICAgICAgICAgICAgICAgaSA+PSAwOwogICAgICAgICAgICAgICAgIC0taSkgewogICAgICAgICAgICAgICAgdmFyIHBhcmVudExpc3QgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQobGlOb2Rlc1tpXSwge25vZGVOYW1lIDogWyJPTCIsICJVTCJdfSk7CiAgICAgICAgICAgICAgICBpZiAocGFyZW50TGlzdCAmJiBsaU5vZGVzW2ldLnBhcmVudEVsZW1lbnQgJiYgbGlOb2Rlc1tpXS5wYXJlbnRFbGVtZW50Lm5vZGVOYW1lID09ICdMSScpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobGlOb2Rlc1tpXS5wYXJlbnRFbGVtZW50Lm5leHRTaWJsaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudExpc3QuaW5zZXJ0QmVmb3JlKGxpTm9kZXNbaV0sIGxpTm9kZXNbaV0ucGFyZW50RWxlbWVudC5uZXh0U2libGluZyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50TGlzdC5hcHBlbmRDaGlsZChsaU5vZGVzW2ldKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2VsZWN0Tm9kZShwYXJlbnRMaXN0KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBhbGlnblZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwoKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHd5c2lodG1sNS5jb21tYW5kcy5pbmRlbnQgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgYWxpZ25WYWx1ZSkgewoKICAgICAgICAgICAgdmFyIHJhbmdlID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFJhbmdlKCk7CiAgICAgICAgICAgIHZhciBzdGFydENvbnRhaW5lclBhcmVudExpc3QgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQocmFuZ2Uuc3RhcnRDb250YWluZXIsIHtub2RlTmFtZSA6IFsiT0wiLCAiVUwiXX0pOwogICAgICAgICAgICBpZiAoc3RhcnRDb250YWluZXJQYXJlbnRMaXN0KSB7CiAgICAgICAgICAgICAgICB2YXIgc3RhcnRDb250YWluZXJQYXJlbnRMaXN0RWxlbWVudCA9IHd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudChyYW5nZS5zdGFydENvbnRhaW5lciwge25vZGVOYW1lIDogIkxJIn0pOwogICAgICAgICAgICAgICAgLyogd2Ugd2FudCB0byBpbnNlcnQgdGhlIG5ldyBPTC9VTCBlbGVtZW50cyBhZnRlciBpbmRlbnQgaW50byB0aGUgc2libGluZyBiZWZvcmUsCiAgICAgICAgICAgICAgICAgaW4gY2FzZSBmaXJzdCBlbGVtZW50IGlzIHNlbGVjdGVkIHRvbywgd2Ugd29uJ3QgaGF2ZSBhbnkgc2libGluZyB0byBpbnNlcnQgbmV3IE9ML1VMIGVsZW1lbnRzIGludG8uCiAgICAgICAgICAgICAgICAgaWYgc2VsZWN0aW9uIGNvbnRhaW5zIGZpcnN0IGVsZW1lbnQgb2YgdGhlIGxpc3Qsc2VsZWN0IHdob2xlIGxpc3QgYW5kIGluZGVudCovCiAgICAgICAgICAgICAgICBpZiAoKHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdEVsZW1lbnQgJiYgc3RhcnRDb250YWluZXJQYXJlbnRMaXN0LmZpcnN0Q2hpbGQgPT0gc3RhcnRDb250YWluZXJQYXJlbnRMaXN0RWxlbWVudCkgfHwgcmFuZ2Uuc3RhcnRDb250YWluZXIubm9kZU5hbWUgPT0gIk9MIikgewogICAgICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZWxlY3ROb2RlKHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCk7CiAgICAgICAgICAgICAgICAgICAgLy8gYXBwbHkgc3R5bGUgb24gdGhpcywgbWFyZ2luLWxlZnQgOiA0MHB4IGFuZCByZXR1cm4KICAgICAgICAgICAgICAgICAgICBpZiAoc3RhcnRDb250YWluZXJQYXJlbnRMaXN0LnN0eWxlICYmIHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdC5zdHlsZS5tYXJnaW5MZWZ0ICE9IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUudXRpbC5zZXRJbmRlbnQoc3RhcnRDb250YWluZXJQYXJlbnRMaXN0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCBzZWxlY3Rpb24gY29udGFpbnMgbGlzdCBvZiBvbmx5IG9uZSBsZXZlbCwgZG9uJ3QgZG8gYW55dGhpbmcgaW4gY2FzZSBvZiBtdWx0aSBsZXZlbCovCiAgICAgICAgICAgIHZhciBzdGFydENvbnRhaW5lclBhcmVudExpc3QgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQocmFuZ2Uuc3RhcnRDb250YWluZXIsIHtub2RlTmFtZSA6IFsiT0wiLCAiVUwiXX0pLAogICAgICAgICAgICAgICAgaW5kZW50VHlwZTsKICAgICAgICAgICAgaWYgKHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCkgewogICAgICAgICAgICAgICAgaW5kZW50VHlwZSA9IHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdC5nZXRBdHRyaWJ1dGUoInR5cGUiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgZW5kQ29udGFpbmVyUGFyZW50TGlzdCA9IHd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudChyYW5nZS5lbmRDb250YWluZXIsIHtub2RlTmFtZSA6IFsiT0wiLCAiVUwiXX0pOwogICAgICAgICAgICBpZiAoc3RhcnRDb250YWluZXJQYXJlbnRMaXN0ICYmIHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCA9PSBlbmRDb250YWluZXJQYXJlbnRMaXN0KSB7CiAgICAgICAgICAgICAgICB2YXIgbGlOb2RlcyA9IHd5c2lodG1sNS51dGlsLmdldExJTm9kZXNGcm9tVGV4dE5vZGVzKHd5c2lodG1sNS51dGlsLmdldFRleHROb2Rlcyhjb21wb3Nlci5zZWxlY3Rpb24pKTsKICAgICAgICAgICAgICAgIGlmIChsaU5vZGVzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0TGlzdE5vZGUgPSBsaU5vZGVzWzBdLnByZXZpb3VzU2libGluZzsKICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0TGlzdE5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxpc3RDaGlsZHMgPSB3eXNpaHRtbDUudXRpbC5nZXRJbW1lZGlhdGVDaGlsZHNCeVRhZ05hbWUodGFyZ2V0TGlzdE5vZGUsIFsiT0wiLCAiVUwiXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPCBsaU5vZGVzLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsaXN0Q2hpbGRzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0Q2hpbGRzWzBdLmFwcGVuZENoaWxkKGxpTm9kZXNbaV0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3TGlzdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoc3RhcnRDb250YWluZXJQYXJlbnRMaXN0Lm5vZGVOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdMaXN0LnNldEF0dHJpYnV0ZSgidHlwZSIsIGluZGVudFR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0xpc3QuYXBwZW5kQ2hpbGQobGlOb2Rlc1tpXSk7ICAgICAgICAvLyBpIG11c3QgYmUgMCBoZXJlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldExpc3ROb2RlLmFwcGVuZENoaWxkKG5ld0xpc3QpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RDaGlsZHNbMF0gPSBuZXdMaXN0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgd3lzaWh0bWw1LnV0aWwuc2V0SW5kZW50KHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZWxlY3ROb2RlKHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCkgewogICAgICAgICAgICAgICAgdmFyIG5vZGVzID0gY29tcG9zZXIuc2VsZWN0aW9uID8gY29tcG9zZXIuc2VsZWN0aW9uLmdldE5vZGVzKDEpIDogW107CiAgICAgICAgICAgICAgICBpZiAoIW5vZGVzIHx8IG5vZGVzLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgbm9kZXMgPSB3eXNpaHRtbDUudXRpbC5nZXRUZXh0Tm9kZXMoY29tcG9zZXIuc2VsZWN0aW9uKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChub2RlcykgewogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgaSA8IG5vZGVzLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgICAgICsraSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZXNbaV0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudE5vZGUgPSBub2Rlc1tpXS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVzLmluZGV4T2YocGFyZW50Tm9kZSkgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmEgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQobm9kZXNbaV0sIHtub2RlTmFtZSA6IFsiUCIsICJPTCIsICJVTCIsICJESVYiLCAiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiXX0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJhICYmIHBhcmEuc3R5bGUgJiYgcGFyYS5zdHlsZS5tYXJnaW5MZWZ0ICE9IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUudXRpbC5zZXRJbmRlbnQocGFyYSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGFsaWduVmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CgooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgd3lzaWh0bWw1LmNvbW1hbmRzLnBhZ2VCcmVhayA9IHsKICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciByYW5nZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRSYW5nZSgpOwogICAgICAgICAgICB2YXIgdGV4dE5vZGVzOwogICAgICAgICAgICBpZiAocmFuZ2UpIHsKICAgICAgICAgICAgICAgIHRleHROb2RlcyA9IHJhbmdlLmdldE5vZGVzKFt3eXNpaHRtbDUuVEVYVF9OT0RFXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogRmFsbGJhY2sgaW4gY2FzZSB0aGUgdGV4dCBpcyBub3Qgc2VsZWN0ZWQgYnV0IGN1cnNvciBpcyBmb2N1c2VkIG9uIHRoZSB0ZXh0Ki8KICAgICAgICAgICAgaWYgKHRleHROb2RlcyA9PSBudWxsIHx8IHRleHROb2Rlcy5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKTsKICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZE5vZGUpIHsKICAgICAgICAgICAgICAgICAgICB0ZXh0Tm9kZXMgPSBbc2VsZWN0ZWROb2RlXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGV4dE5vZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgdmFyIHRleHROb2RlOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRleHROb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICAgICAgICAgICsraSkgewogICAgICAgICAgICAgICAgICAgIHRleHROb2RlID0gdGV4dE5vZGVzW2ldOwogICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnQgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQodGV4dE5vZGUsIHtub2RlTmFtZSA6IFsiUCIsICJIMSIsICJIMiIsICJIMyIsICJINCIsICJINSIsICJINiJdfSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3R5bGVBdHRyaWJ1dGUgPSBwYXJlbnQuZ2V0QXR0cmlidXRlKCJzdHlsZSIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGVBdHRyaWJ1dGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWdFeHAxID0gL3BhZ2UtYnJlYWstaW5zaWRlXHMqOlxzKmF2b2lkOy9nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ0V4cDIgPSAvcGFnZS1icmVhay1pbnNpZGVccyo6XHMqYXZvaWQvZzsgLy9DaGVjayBmb3IgYm90aCB3aXRoL3dpdGhvdXQgc2VtaS1jb2xvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlZ0V4cDEuZXhlYyhzdHlsZUF0dHJpYnV0ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZUF0dHJpYnV0ZSA9IHN0eWxlQXR0cmlidXRlLnJlcGxhY2UocmVnRXhwMSwgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZWdFeHAyLmV4ZWMoc3R5bGVBdHRyaWJ1dGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGVBdHRyaWJ1dGUgPSBzdHlsZUF0dHJpYnV0ZS5yZXBsYWNlKHJlZ0V4cDIsICIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzdHlsZUF0dHJpYnV0ZS5lbmRzV2l0aCgiOyIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlQXR0cmlidXRlICs9ICI7IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGVBdHRyaWJ1dGUgKz0gInBhZ2UtYnJlYWstaW5zaWRlOiBhdm9pZDsiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGVBdHRyaWJ1dGUgPSAicGFnZS1icmVhay1pbnNpZGU6IGF2b2lkOyI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LnNldEF0dHJpYnV0ZSgic3R5bGUiLCBzdHlsZUF0dHJpYnV0ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7InBhZ2UtYnJlYWstaW5zaWRlIiA6ICJhdm9pZCIsCiAgICAgICAgICAgICAgICAiYnJlYWstaW5zaWRlIiA6ICJhdm9pZCJ9OwogICAgICAgICAgICByZXR1cm4gIXd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRCbG9jay5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgWyJQIiwgIkxJIiwgIkgxIiwgIkgyIiwgIkgzIiwgIkg0IiwgIkg1IiwgIkg2Il0sIG51bGwsIG51bGwsIGF0dHJpYnV0ZXMpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7Cnd5c2lodG1sNS5jb21tYW5kcy5oaWxpdGVDb2xvciA9IHsKICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGNvbG9yKSB7CiAgICAgICAgLyogQWZ0ZXIgc3RhdGUgaW1wbGVtZW50YXRpb24gY2hhbmdlcywgdXNlIGZvbGxvd2luZyBicm93c2VyIGNvbW1hbmQuCiAgICAgICAgIGlmIChjb21wb3Nlci5jb21tYW5kcy5zdXBwb3J0KGNvbW1hbmQpKSB7CiAgICAgICAgIGNvbXBvc2VyLmRvYy5leGVjQ29tbWFuZChjb21tYW5kLCBmYWxzZSwgY29sb3IpOwogICAgICAgICB9Ki8KICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiYmFja2dyb3VuZC1jb2xvciIgOiBjb2xvcn07CiAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAid3lzaXd5Zy1iZ2NvbG9yLSIgKyBjb2xvciwgL3d5c2l3eWctYmdjb2xvci1bMC05YS16XSsvZywgYXR0cmlidXRlcyk7CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBjb2xvcikgewogICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJiYWNrZ3JvdW5kLWNvbG9yIiA6IGNvbG9yfTsKICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAid3lzaXd5Zy1iZ2NvbG9yLSIgKyBjb2xvciwgL3d5c2l3eWctYmdjb2xvci1bMC05YS16XSsvZywgYXR0cmlidXRlcyk7CiAgICB9Cn07Cnd5c2lodG1sNS5jb21tYW5kcy5yZWRvID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlcikgewogICAgICAgIHJldHVybiBjb21wb3Nlci51bmRvTWFuYWdlci5yZWRvKCk7CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9Owp3eXNpaHRtbDUuY29tbWFuZHMudW5kZXJsaW5lID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLmV4ZWMoY29tcG9zZXIsIGNvbW1hbmQsICJ1Iik7CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsICJ1Iik7CiAgICB9Cn07Cnd5c2lodG1sNS5jb21tYW5kcy51bmRvID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlcikgewogICAgICAgIHJldHVybiBjb21wb3Nlci51bmRvTWFuYWdlci51bmRvKCk7CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9OwovKioKICogVW5kbyBNYW5hZ2VyIGZvciB3eXNpaHRtbDUKICogc2xpZ2h0bHkgaW5zcGlyZWQgYnkgaHR0cDovL3JuaXdhLmNvbS9lZGl0aW5nL3VuZG9tYW5hZ2VyLmh0bWwjdGhlLXVuZG9tYW5hZ2VyLWludGVyZmFjZQogKi8KKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBaX0tFWSA9IDkwLAogICAgICAgIFlfS0VZID0gODksCiAgICAgICAgQkFDS1NQQUNFX0tFWSA9IDgsCiAgICAgICAgREVMRVRFX0tFWSA9IDQ2LAogICAgICAgIE1BWF9ISVNUT1JZX0VOVFJJRVMgPSAyNSwKICAgICAgICBEQVRBX0FUVFJfTk9ERSA9ICJkYXRhLXd5c2lodG1sNS1zZWxlY3Rpb24tbm9kZSIsCiAgICAgICAgREFUQV9BVFRSX09GRlNFVCA9ICJkYXRhLXd5c2lodG1sNS1zZWxlY3Rpb24tb2Zmc2V0IiwKICAgICAgICBVTkRPX0hUTUwgPSAnPHNwYW4gaWQ9Il93eXNpaHRtbDUtdW5kbyIgY2xhc3M9Il93eXNpaHRtbDUtdGVtcCI+JyArIHd5c2lodG1sNS5JTlZJU0lCTEVfU1BBQ0UgKyAnPC9zcGFuPicsCiAgICAgICAgUkVET19IVE1MID0gJzxzcGFuIGlkPSJfd3lzaWh0bWw1LXJlZG8iIGNsYXNzPSJfd3lzaWh0bWw1LXRlbXAiPicgKyB3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFICsgJzwvc3Bhbj4nLAogICAgICAgIGRvbSA9IHd5c2lodG1sNS5kb207CgogICAgZnVuY3Rpb24gY2xlYW5UZW1wRWxlbWVudHMoZG9jKSB7CiAgICAgICAgdmFyIHRlbXBFbGVtZW50OwogICAgICAgIHdoaWxlICh0ZW1wRWxlbWVudCA9IGRvYy5xdWVyeVNlbGVjdG9yKCIuX3d5c2lodG1sNS10ZW1wIikpIHsKICAgICAgICAgICAgdGVtcEVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0ZW1wRWxlbWVudCk7CiAgICAgICAgfQogICAgfQoKICAgIHd5c2lodG1sNS5VbmRvTWFuYWdlciA9IHd5c2lodG1sNS5sYW5nLkRpc3BhdGNoZXIuZXh0ZW5kKAogICAgICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LlVuZG9NYW5hZ2VyLnByb3RvdHlwZSAqLyB7CiAgICAgICAgICAgIGNvbnN0cnVjdG9yIDogZnVuY3Rpb24gKGVkaXRvcikgewogICAgICAgICAgICAgICAgdGhpcy5lZGl0b3IgPSBlZGl0b3I7CiAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyID0gZWRpdG9yLmNvbXBvc2VyOwogICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy5jb21wb3Nlci5lbGVtZW50OwoKICAgICAgICAgICAgICAgIHRoaXMucG9zaXRpb24gPSAwOwogICAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5U3RyID0gW107CiAgICAgICAgICAgICAgICB0aGlzLmhpc3RvcnlEb20gPSBbXTsKCiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zYWN0KCk7CgogICAgICAgICAgICAgICAgdGhpcy5fb2JzZXJ2ZSgpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBjbGVhckhpc3RvcnkgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLnBvc2l0aW9uID0gMDsKICAgICAgICAgICAgICAgIHRoaXMuaGlzdG9yeVN0ciA9IFtdOwogICAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5RG9tID0gW107CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfb2JzZXJ2ZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcywKICAgICAgICAgICAgICAgICAgICBkb2MgPSB0aGlzLmNvbXBvc2VyLnNhbmRib3guZ2V0RG9jdW1lbnQoKSwKICAgICAgICAgICAgICAgICAgICBsYXN0S2V5OwoKICAgICAgICAgICAgICAgIC8vIENhdGNoIENUUkwrWiBhbmQgQ1RSTCtZCiAgICAgICAgICAgICAgICBkb20ub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsICJrZXlkb3duIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50LmFsdEtleSB8fCAoIWV2ZW50LmN0cmxLZXkgJiYgIWV2ZW50Lm1ldGFLZXkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHZhciBrZXlDb2RlID0gZXZlbnQua2V5Q29kZSwKICAgICAgICAgICAgICAgICAgICAgICAgaXNVbmRvID0ga2V5Q29kZSA9PT0gWl9LRVkgJiYgIWV2ZW50LnNoaWZ0S2V5LAogICAgICAgICAgICAgICAgICAgICAgICBpc1JlZG8gPSAoa2V5Q29kZSA9PT0gWl9LRVkgJiYgZXZlbnQuc2hpZnRLZXkpIHx8IChrZXlDb2RlID09PSBZX0tFWSk7CgogICAgICAgICAgICAgICAgICAgIGlmIChpc1VuZG8pIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC51bmRvKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc1JlZG8pIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5yZWRvKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgLy8gQ2F0Y2ggZGVsZXRlIGFuZCBiYWNrc3BhY2UKICAgICAgICAgICAgICAgIGRvbS5vYnNlcnZlKHRoaXMuZWxlbWVudCwgImtleWRvd24iLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIga2V5Q29kZSA9IGV2ZW50LmtleUNvZGU7CiAgICAgICAgICAgICAgICAgICAgaWYgKGtleUNvZGUgPT09IGxhc3RLZXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgbGFzdEtleSA9IGtleUNvZGU7CgogICAgICAgICAgICAgICAgICAgIGlmIChrZXlDb2RlID09PSBCQUNLU1BBQ0VfS0VZIHx8IGtleUNvZGUgPT09IERFTEVURV9LRVkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC50cmFuc2FjdCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIC8vIE5vdyB0aGlzIGlzIHZlcnkgaGFja3k6CiAgICAgICAgICAgICAgICAvLyBUaGVzZSBkYXlzIGJyb3dzZXJzIGRvbid0IG9mZmVyIGEgdW5kby9yZWRvIGV2ZW50IHdoaWNoIHdlIGNvdWxkIGhvb2sgaW50bwogICAgICAgICAgICAgICAgLy8gdG8gYmUgbm90aWZpZWQgd2hlbiB0aGUgdXNlciBoaXRzIHVuZG8vcmVkbyBpbiB0aGUgY29udGV4dG1lbnUuCiAgICAgICAgICAgICAgICAvLyBUaGVyZWZvcmUgd2Ugc2ltcGx5IGluc2VydCB0d28gZWxlbWVudHMgYXMgc29vbiBhcyB0aGUgY29udGV4dG1lbnUgZ2V0cyBvcGVuZWQuCiAgICAgICAgICAgICAgICAvLyBUaGUgbGFzdCBlbGVtZW50IGJlaW5nIGluc2VydGVkIHdpbGwgYmUgaW1tZWRpYXRlbHkgYmUgcmVtb3ZlZCBhZ2FpbiBieSBhIGV4ZXhDb21tYW5kKCJ1bmRvIikKICAgICAgICAgICAgICAgIC8vICA9PiBXaGVuIHRoZSBzZWNvbmQgZWxlbWVudCBhcHBlYXJzIGluIHRoZSBkb20gdHJlZSB0aGVuIHdlIGtub3cgdGhlIHVzZXIgY2xpY2tlZCAicmVkbyIgaW4gdGhlIGNvbnRleHQgbWVudQogICAgICAgICAgICAgICAgLy8gID0+IFdoZW4gdGhlIGZpcnN0IGVsZW1lbnQgZGlzYXBwZWFycyBmcm9tIHRoZSBkb20gdHJlZSB0aGVuIHdlIGtub3cgdGhlIHVzZXIgY2xpY2tlZCAidW5kbyIgaW4gdGhlIGNvbnRleHQgbWVudQogICAgICAgICAgICAgICAgaWYgKHd5c2lodG1sNS5icm93c2VyLmhhc1VuZG9JbkNvbnRleHRNZW51KCkpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaW50ZXJ2YWwsIG9ic2VydmVkLCBjbGVhblVwID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICBjbGVhblRlbXBFbGVtZW50cyhkb2MpOwogICAgICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKGludGVydmFsKTsKICAgICAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgICAgICBkb20ub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsICJjb250ZXh0bWVudSIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2xlYW5VcCgpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmNvbXBvc2VyLnNlbGVjdGlvbi5leGVjdXRlQW5kUmVzdG9yZVNpbXBsZShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5lbGVtZW50Lmxhc3RDaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuY29tcG9zZXIuc2VsZWN0aW9uLnNldEFmdGVyKHRoYXQuZWxlbWVudC5sYXN0Q2hpbGQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVuYWJsZSB1bmRvIGJ1dHRvbiBpbiBjb250ZXh0IG1lbnUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvYy5leGVjQ29tbWFuZCgiaW5zZXJ0SFRNTCIsIGZhbHNlLCBVTkRPX0hUTUwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZW5hYmxlIHJlZG8gYnV0dG9uIGluIGNvbnRleHQgbWVudQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jLmV4ZWNDb21tYW5kKCJpbnNlcnRIVE1MIiwgZmFsc2UsIFJFRE9fSFRNTCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2MuZXhlY0NvbW1hbmQoInVuZG8iLCBmYWxzZSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9jLmdldEVsZW1lbnRCeUlkKCJfd3lzaWh0bWw1LXJlZG8iKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFuVXAoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnJlZG8oKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWRvYy5nZXRFbGVtZW50QnlJZCgiX3d5c2lodG1sNS11bmRvIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhblVwKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC51bmRvKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0sIDQwMCk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9ic2VydmVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb20ub2JzZXJ2ZShkb2N1bWVudCwgIm1vdXNlZG93biIsIGNsZWFuVXApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tLm9ic2VydmUoZG9jLCBbIm1vdXNlZG93biIsICJwYXN0ZSIsICJjdXQiLCAiY29weSJdLCBjbGVhblVwKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yCiAgICAgICAgICAgICAgICAgICAgLm9uKCJuZXd3b3JkOmNvbXBvc2VyIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnRyYW5zYWN0KCk7CiAgICAgICAgICAgICAgICAgICAgfSkKCiAgICAgICAgICAgICAgICAgICAgLm9uKCJiZWZvcmVjb21tYW5kOmNvbXBvc2VyIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnRyYW5zYWN0KCk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICB0cmFuc2FjdCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBwcmV2aW91c0h0bWwgPSB0aGlzLmhpc3RvcnlTdHJbdGhpcy5wb3NpdGlvbiAtIDFdLAogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRIdG1sID0gdGhpcy5jb21wb3Nlci5nZXRWYWx1ZSgpOwoKICAgICAgICAgICAgICAgIGlmIChjdXJyZW50SHRtbCA9PT0gcHJldmlvdXNIdG1sKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBsZW5ndGggPSB0aGlzLmhpc3RvcnlTdHIubGVuZ3RoID0gdGhpcy5oaXN0b3J5RG9tLmxlbmd0aCA9IHRoaXMucG9zaXRpb247CiAgICAgICAgICAgICAgICBpZiAobGVuZ3RoID4gTUFYX0hJU1RPUllfRU5UUklFUykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaGlzdG9yeVN0ci5zaGlmdCgpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaGlzdG9yeURvbS5zaGlmdCgpOwogICAgICAgICAgICAgICAgICAgIHRoaXMucG9zaXRpb24tLTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLnBvc2l0aW9uKys7CgogICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gdGhpcy5jb21wb3Nlci5zZWxlY3Rpb24uZ2V0UmFuZ2UoKSwKICAgICAgICAgICAgICAgICAgICBub2RlID0gcmFuZ2Uuc3RhcnRDb250YWluZXIgfHwgdGhpcy5lbGVtZW50LAogICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IHJhbmdlLnN0YXJ0T2Zmc2V0IHx8IDAsCiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCwKICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjsKCiAgICAgICAgICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERSkgewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBub2RlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gbm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gdGhpcy5nZXRDaGlsZE5vZGVJbmRleChlbGVtZW50LCBub2RlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShEQVRBX0FUVFJfT0ZGU0VULCBvZmZzZXQpOwogICAgICAgICAgICAgICAgaWYgKHR5cGVvZihwb3NpdGlvbikgIT09ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoREFUQV9BVFRSX05PREUsIHBvc2l0aW9uKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgY2xvbmUgPSB0aGlzLmVsZW1lbnQuY2xvbmVOb2RlKCEhY3VycmVudEh0bWwpOwogICAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5RG9tLnB1c2goY2xvbmUpOwogICAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5U3RyLnB1c2goY3VycmVudEh0bWwpOwoKICAgICAgICAgICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKERBVEFfQVRUUl9PRkZTRVQpOwogICAgICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoREFUQV9BVFRSX05PREUpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgdW5kbyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHRoaXMudHJhbnNhY3QoKTsKCiAgICAgICAgICAgICAgICBpZiAoIXRoaXMudW5kb1Bvc3NpYmxlKCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5zZXQodGhpcy5oaXN0b3J5RG9tWy0tdGhpcy5wb3NpdGlvbiAtIDFdKTsKICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yLmZpcmUoInVuZG86Y29tcG9zZXIiKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHJlZG8gOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBpZiAoIXRoaXMucmVkb1Bvc3NpYmxlKCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5zZXQodGhpcy5oaXN0b3J5RG9tWysrdGhpcy5wb3NpdGlvbiAtIDFdKTsKICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yLmZpcmUoInJlZG86Y29tcG9zZXIiKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHVuZG9Qb3NzaWJsZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uID4gMTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHJlZG9Qb3NzaWJsZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uIDwgdGhpcy5oaXN0b3J5U3RyLmxlbmd0aDsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uIChoaXN0b3J5RW50cnkpIHsKICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5pbm5lckhUTUwgPSAiIjsKCiAgICAgICAgICAgICAgICB2YXIgaSA9IDAsCiAgICAgICAgICAgICAgICAgICAgY2hpbGROb2RlcyA9IGhpc3RvcnlFbnRyeS5jaGlsZE5vZGVzLAogICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IGhpc3RvcnlFbnRyeS5jaGlsZE5vZGVzLmxlbmd0aDsKCiAgICAgICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZChjaGlsZE5vZGVzW2ldLmNsb25lTm9kZSh0cnVlKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gUmVzdG9yZSBzZWxlY3Rpb24KICAgICAgICAgICAgICAgIHZhciBvZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgbm9kZSwKICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjsKCiAgICAgICAgICAgICAgICBpZiAoaGlzdG9yeUVudHJ5Lmhhc0F0dHJpYnV0ZShEQVRBX0FUVFJfT0ZGU0VUKSkgewogICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IGhpc3RvcnlFbnRyeS5nZXRBdHRyaWJ1dGUoREFUQV9BVFRSX09GRlNFVCk7CiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBoaXN0b3J5RW50cnkuZ2V0QXR0cmlidXRlKERBVEFfQVRUUl9OT0RFKTsKICAgICAgICAgICAgICAgICAgICBub2RlID0gdGhpcy5lbGVtZW50OwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBub2RlID0gdGhpcy5lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoIlsiICsgREFUQV9BVFRSX09GRlNFVCArICJdIikgfHwgdGhpcy5lbGVtZW50OwogICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IG5vZGUuZ2V0QXR0cmlidXRlKERBVEFfQVRUUl9PRkZTRVQpOwogICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gbm9kZS5nZXRBdHRyaWJ1dGUoREFUQV9BVFRSX05PREUpOwogICAgICAgICAgICAgICAgICAgIG5vZGUucmVtb3ZlQXR0cmlidXRlKERBVEFfQVRUUl9PRkZTRVQpOwogICAgICAgICAgICAgICAgICAgIG5vZGUucmVtb3ZlQXR0cmlidXRlKERBVEFfQVRUUl9OT0RFKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBub2RlID0gdGhpcy5nZXRDaGlsZE5vZGVCeUluZGV4KG5vZGUsICtwb3NpdGlvbik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5jb21wb3Nlci5zZWxlY3Rpb24uc2V0KG5vZGUsIG9mZnNldCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRDaGlsZE5vZGVJbmRleCA6IGZ1bmN0aW9uIChwYXJlbnQsIGNoaWxkKSB7CiAgICAgICAgICAgICAgICB2YXIgaSA9IDAsCiAgICAgICAgICAgICAgICAgICAgY2hpbGROb2RlcyA9IHBhcmVudC5jaGlsZE5vZGVzLAogICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IGNoaWxkTm9kZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGROb2Rlc1tpXSA9PT0gY2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZ2V0Q2hpbGROb2RlQnlJbmRleCA6IGZ1bmN0aW9uIChwYXJlbnQsIGluZGV4KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50LmNoaWxkTm9kZXNbaW5kZXhdOwogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBUT0RPOiB0aGUgZm9sbG93aW5nIG1ldGhvZHMgc3RpbGwgbmVlZCB1bml0IHRlc3QgY292ZXJhZ2UKICovCnd5c2lodG1sNS52aWV3cy5WaWV3ID0gQmFzZS5leHRlbmQoCiAgICAvKiogQHNjb3BlIHd5c2lodG1sNS52aWV3cy5WaWV3LnByb3RvdHlwZSAqLyB7CiAgICAgICAgY29uc3RydWN0b3IgOiBmdW5jdGlvbiAocGFyZW50LCB0ZXh0YXJlYUVsZW1lbnQsIGNvbmZpZykgewogICAgICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDsKICAgICAgICAgICAgdGhpcy5lbGVtZW50ID0gdGV4dGFyZWFFbGVtZW50OwogICAgICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZzsKCiAgICAgICAgICAgIHRoaXMuX29ic2VydmVWaWV3Q2hhbmdlKCk7CiAgICAgICAgfSwKCiAgICAgICAgX29ic2VydmVWaWV3Q2hhbmdlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgIHRoaXMucGFyZW50Lm9uKCJiZWZvcmVsb2FkIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhhdC5wYXJlbnQub24oImNoYW5nZV92aWV3IiwgZnVuY3Rpb24gKHZpZXcpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodmlldyA9PT0gdGhhdC5uYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQucGFyZW50LmN1cnJlbnRWaWV3ID0gdGhhdDsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5zaG93KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVzaW5nIHRpbnkgZGVsYXkgaGVyZSB0byBtYWtlIHN1cmUgdGhhdCB0aGUgcGxhY2Vob2xkZXIgaXMgc2V0IGJlZm9yZSBmb2N1c2luZwogICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZm9jdXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5oaWRlKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIGZvY3VzIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBpZiAodGhpcy5lbGVtZW50Lm93bmVyRG9jdW1lbnQucXVlcnlTZWxlY3RvcigiOmZvY3VzIikgPT09IHRoaXMuZWxlbWVudCkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50LmZvY3VzKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGhpZGUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgIH0sCgogICAgICAgIHNob3cgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gIiI7CiAgICAgICAgfSwKCiAgICAgICAgZGlzYWJsZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgiZGlzYWJsZWQiLCAiZGlzYWJsZWQiKTsKICAgICAgICB9LAoKICAgICAgICBlbmFibGUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgICAgfQogICAgfSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgZG9tID0gd3lzaWh0bWw1LmRvbSwKICAgICAgICBicm93c2VyID0gd3lzaWh0bWw1LmJyb3dzZXI7CgogICAgd3lzaWh0bWw1LnZpZXdzLkNvbXBvc2VyID0gd3lzaWh0bWw1LnZpZXdzLlZpZXcuZXh0ZW5kKAogICAgICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LnZpZXdzLkNvbXBvc2VyLnByb3RvdHlwZSAqLyB7CiAgICAgICAgICAgIG5hbWUgOiAiY29tcG9zZXIiLAoKICAgICAgICAgICAgLy8gTmVlZGVkIGZvciBmaXJlZm94IGluIG9yZGVyIHRvIGRpc3BsYXkgYSBwcm9wZXIgY2FyZXQgaW4gYW4gZW1wdHkgY29udGVudEVkaXRhYmxlCiAgICAgICAgICAgIENBUkVUX0hBQ0sgOiAiPGJyPiIsCgogICAgICAgICAgICBjb25zdHJ1Y3RvciA6IGZ1bmN0aW9uIChwYXJlbnQsIHRleHRhcmVhRWxlbWVudCwgY29uZmlnKSB7CiAgICAgICAgICAgICAgICB0aGlzLmJhc2UocGFyZW50LCB0ZXh0YXJlYUVsZW1lbnQsIGNvbmZpZyk7CiAgICAgICAgICAgICAgICB0aGlzLnRleHRhcmVhID0gdGhpcy5wYXJlbnQudGV4dGFyZWE7CiAgICAgICAgICAgICAgICB0aGlzLl9pbml0U2FuZGJveChjb25maWcuaW5zZXJ0QWZ0ZXIpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgY2xlYXIgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQuaW5uZXJIVE1MID0gYnJvd3Nlci5kaXNwbGF5c0NhcmV0SW5FbXB0eUNvbnRlbnRFZGl0YWJsZUNvcnJlY3RseSgpID8gIiIgOiB0aGlzLkNBUkVUX0hBQ0s7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRWYWx1ZSA6IGZ1bmN0aW9uIChwYXJzZSkgewogICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5pc0VtcHR5KCkgPyAiIiA6IHd5c2lodG1sNS5xdWlya3MuZ2V0Q29ycmVjdElubmVySFRNTCh0aGlzLmVsZW1lbnQpOwoKICAgICAgICAgICAgICAgIGlmIChwYXJzZSkgewogICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5wYXJlbnQucGFyc2UodmFsdWUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFJlcGxhY2UgYWxsICJ6ZXJvIHdpZHRoIG5vIGJyZWFraW5nIHNwYWNlIiBjaGFycwogICAgICAgICAgICAgICAgLy8gd2hpY2ggYXJlIHVzZWQgYXMgaGFja3MgdG8gZW5hYmxlIHNvbWUgZnVuY3Rpb25hbGl0aWVzCiAgICAgICAgICAgICAgICAvLyBBbHNvIHJlbW92ZSBhbGwgQ0FSRVQgaGFja3MgdGhhdCBzb21laG93IGdvdCBsZWZ0CiAgICAgICAgICAgICAgICB2YWx1ZSA9IHd5c2lodG1sNS5sYW5nLnN0cmluZyh2YWx1ZSkucmVwbGFjZSh3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFKS5ieSgiIik7CgogICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2V0VmFsdWUgOiBmdW5jdGlvbiAoaHRtbCwgcGFyc2UpIHsKICAgICAgICAgICAgICAgIGlmIChwYXJzZSkgewogICAgICAgICAgICAgICAgICAgIGh0bWwgPSB0aGlzLnBhcmVudC5wYXJzZShodG1sKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5pbm5lckhUTUwgPSBodG1sOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5pbm5lclRleHQgPSBodG1sOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2hvdyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSB0aGlzLl9kaXNwbGF5U3R5bGUgfHwgIiI7CgogICAgICAgICAgICAgICAgaWYgKCF0aGlzLnRleHRhcmVhLmVsZW1lbnQuZGlzYWJsZWQpIHsKICAgICAgICAgICAgICAgICAgICAvLyBGaXJlZm94IG5lZWRzIHRoaXMsIG90aGVyd2lzZSBjb250ZW50RWRpdGFibGUgYmVjb21lcyB1bmVkaXRhYmxlCiAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbmFibGUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGhpZGUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9kaXNwbGF5U3R5bGUgPSBkb20uZ2V0U3R5bGUoImRpc3BsYXkiKS5mcm9tKHRoaXMuY29udGFpbmVyKTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9kaXNwbGF5U3R5bGUgPT09ICJub25lIikgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Rpc3BsYXlTdHlsZSA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZGlzYWJsZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHRoaXMucGFyZW50LmZpcmUoImRpc2FibGU6Y29tcG9zZXIiKTsKICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoImNvbnRlbnRFZGl0YWJsZSIpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZW5hYmxlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhpcy5wYXJlbnQuZmlyZSgiZW5hYmxlOmNvbXBvc2VyIik7CiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCJjb250ZW50RWRpdGFibGUiLCAidHJ1ZSIpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZm9jdXMgOiBmdW5jdGlvbiAoc2V0VG9FbmQpIHsKICAgICAgICAgICAgICAgIC8vIElFIDggZmlyZXMgdGhlIGZvY3VzIGV2ZW50IGFmdGVyIC5mb2N1cygpCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIG5lZWRlZCBieSBvdXIgc2ltdWxhdGVfcGxhY2Vob2xkZXIuanMgdG8gd29yawogICAgICAgICAgICAgICAgLy8gdGhlcmVmb3JlIHdlIGNsZWFyIGl0IG91cnNlbHZlcyB0aGlzIHRpbWUKICAgICAgICAgICAgICAgIGlmICh3eXNpaHRtbDUuYnJvd3Nlci5kb2VzQXN5bmNGb2N1cygpICYmIHRoaXMuaGFzUGxhY2Vob2xkZXJTZXQoKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYXIoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLmJhc2UoKTsKCiAgICAgICAgICAgICAgICB2YXIgbGFzdENoaWxkID0gdGhpcy5lbGVtZW50Lmxhc3RDaGlsZDsKICAgICAgICAgICAgICAgIGlmIChzZXRUb0VuZCAmJiBsYXN0Q2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobGFzdENoaWxkLm5vZGVOYW1lID09PSAiQlIiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uLnNldEJlZm9yZSh0aGlzLmVsZW1lbnQubGFzdENoaWxkKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGlvbi5zZXRBZnRlcih0aGlzLmVsZW1lbnQubGFzdENoaWxkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRUZXh0Q29udGVudCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBkb20uZ2V0VGV4dENvbnRlbnQodGhpcy5lbGVtZW50KTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGFwcGx5U3R5bGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIHN0eWxlUHJvcGVydGllcywgYXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkTm9kZXMgPSBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0Tm9kZXMoMSk7CiAgICAgICAgICAgICAgICB2YXIgYXBwbHlTdHlsZVRvTm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50Tm9kZSA9IGRvbS5nZXRQYXJlbnRFbGVtZW50KG5vZGUsIHtub2RlTmFtZSA6IFsiTEkiXX0pOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50Tm9kZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBQcmV2ZW50IGFwcGx5aW5nIHN0eWxlIHRvIGlubmVyIGxpc3RzKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsaXN0Tm9kZSA9IGRvbS5nZXRQYXJlbnRFbGVtZW50KG5vZGUsIHtub2RlTmFtZSA6IFsiT0wiLCAiVUwiXX0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3ROb2RlICE9IG51bGwgJiYgc2VsZWN0ZWROb2Rlcy5pbmRleE9mKGxpc3ROb2RlKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50TGlzdEl0ZW0gPSBkb20uZ2V0UGFyZW50RWxlbWVudChsaXN0Tm9kZSwge25vZGVOYW1lIDogWyJMSSJdfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudExpc3RJdGVtICE9IG51bGwgJiYgc2VsZWN0ZWROb2Rlcy5pbmRleE9mKHBhcmVudExpc3RJdGVtKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBwYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIHByb3BlcnR5IGluIHN0eWxlUHJvcGVydGllcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5zdHlsZS5zZXRQcm9wZXJ0eShwcm9wZXJ0eSwgc3R5bGVQcm9wZXJ0aWVzW3Byb3BlcnR5XSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgYXR0cmlidXRlIGluIGF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKGF0dHJpYnV0ZSwgYXR0cmlidXRlc1thdHRyaWJ1dGVdKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB2YXIgbm9kZUxpc3QgPSBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0Tm9kZXMoMyk7CiAgICAgICAgICAgICAgICBpZiAobm9kZUxpc3QubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICBpIDwgbm9kZUxpc3QubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlID0gbm9kZUxpc3RbaV07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSAhPSBudWxsICYmIChub2RlLm5vZGVOYW1lID09ICJQIiB8fCBub2RlLm5vZGVOYW1lID09ICJMSSIgfHwgbm9kZS5ub2RlTmFtZS5tYXRjaCgvXkhbMS02XSQvKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBseVN0eWxlVG9Ob2RlKG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChub2RlICE9IG51bGwgJiYgIXd5c2lodG1sNS51dGlsLmlzRWRpdG9yTm9kZShub2RlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChub2RlICE9IG51bGwgJiYgbm9kZS5ub2RlTmFtZSAhPSAiUCIgJiYgbm9kZS5ub2RlTmFtZSAhPSAiTEkiICYmIG5vZGUubm9kZU5hbWUubWF0Y2goL15IWzEtNl0kLykgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5wYXJlbnRFbGVtZW50OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBseVN0eWxlVG9Ob2RlKG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWROb2RlID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFNlbGVjdGVkTm9kZSgpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChzZWxlY3RlZE5vZGUgIT0gbnVsbCAmJiBzZWxlY3RlZE5vZGUubm9kZU5hbWUgIT0gIlAiICYmIHNlbGVjdGVkTm9kZS5ub2RlTmFtZSAhPSBzZWxlY3RlZE5vZGUubm9kZU5hbWUubWF0Y2goL15IWzEtNl0kLykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWROb2RlID0gc2VsZWN0ZWROb2RlLnBhcmVudEVsZW1lbnQgPyBzZWxlY3RlZE5vZGUucGFyZW50RWxlbWVudCA6IHNlbGVjdGVkTm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBhcHBseVN0eWxlVG9Ob2RlKHNlbGVjdGVkTm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGhhc1BsYWNlaG9sZGVyU2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VGV4dENvbnRlbnQoKSA9PSB0aGlzLnRleHRhcmVhLmVsZW1lbnQuZ2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIpICYmIHRoaXMucGxhY2Vob2xkZXJTZXQ7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBpc0VtcHR5IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIGlubmVySFRNTCA9IHRoaXMuZWxlbWVudC5pbm5lckhUTUwudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgICAgIHJldHVybiBpbm5lckhUTUwgPT09ICIiIHx8CiAgICAgICAgICAgICAgICAgICAgaW5uZXJIVE1MID09PSAiPGJyPiIgfHwKICAgICAgICAgICAgICAgICAgICBpbm5lckhUTUwgPT09ICI8cD48L3A+IiB8fAogICAgICAgICAgICAgICAgICAgIGlubmVySFRNTCA9PT0gIjxwPjxicj48L3A+IiB8fAogICAgICAgICAgICAgICAgICAgIHRoaXMuaGFzUGxhY2Vob2xkZXJTZXQoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9pbml0U2FuZGJveCA6IGZ1bmN0aW9uIChpbnNlcnRBZnRlcikgewoKICAgICAgICAgICAgICAgIHRoaXMuc2FuZGJveCA9IG5ldyBkb20uU2FuZGJveCh7CiAgICAgICAgICAgICAgICAgICAgc3R5bGVzaGVldHMgOiB0aGlzLmNvbmZpZy5zdHlsZXNoZWV0cwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMuc2FuZGJveC5nZXRDb250YWluZXIoKTsKCiAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFFbGVtZW50ID0gdGhpcy50ZXh0YXJlYS5lbGVtZW50OwogICAgICAgICAgICAgICAgaW5zZXJ0QWZ0ZXIgPSBpbnNlcnRBZnRlciB8fCB0ZXh0YXJlYUVsZW1lbnQ7CiAgICAgICAgICAgICAgICBkb20uaW5zZXJ0KHRoaXMuY29udGFpbmVyKS5hZnRlcihpbnNlcnRBZnRlcik7CgogICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGhpZGRlbiBmaWVsZCB3aGljaCB0ZWxscyB0aGUgc2VydmVyIGFmdGVyIHN1Ym1pdCwgdGhhdCB0aGUgdXNlciB1c2VkIGFuIHd5c2l3eWcgZWRpdG9yCiAgICAgICAgICAgICAgICBpZiAodGV4dGFyZWFFbGVtZW50LmZvcm0pIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaGlkZGVuRmllbGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJpbnB1dCIpOwogICAgICAgICAgICAgICAgICAgIGhpZGRlbkZpZWxkLnR5cGUgPSAiaGlkZGVuIjsKICAgICAgICAgICAgICAgICAgICBoaWRkZW5GaWVsZC5uYW1lID0gIl93eXNpaHRtbDVfbW9kZSI7CiAgICAgICAgICAgICAgICAgICAgaGlkZGVuRmllbGQudmFsdWUgPSAxOwogICAgICAgICAgICAgICAgICAgIGRvbS5pbnNlcnQoaGlkZGVuRmllbGQpLmFmdGVyKHRleHRhcmVhRWxlbWVudCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfY3JlYXRlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwoKICAgICAgICAgICAgICAgIHRoaXMuZG9jID0gdGhpcy5zYW5kYm94LmdldERvY3VtZW50KCk7CiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNvbnRhaW5lcjsKICAgICAgICAgICAgICAgIHRoaXMudGV4dGFyZWEgPSB0aGlzLnBhcmVudC50ZXh0YXJlYTsKICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLnRleHRhcmVhLmdldFZhbHVlKHRydWUpOwoKICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSBvdXIgc2VsZWN0aW9uIGhhbmRsZXIgaXMgcmVhZHkKICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uID0gbmV3IHd5c2lodG1sNS5TZWxlY3Rpb24odGhpcy5wYXJlbnQpOwoKICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSBjb21tYW5kcyBkaXNwYXRjaGVyIGlzIHJlYWR5CiAgICAgICAgICAgICAgICB0aGlzLmNvbW1hbmRzID0gbmV3IHd5c2lodG1sNS5Db21tYW5kcyh0aGlzLnBhcmVudCk7CgogICAgICAgICAgICAgICAgZG9tLmNvcHlBdHRyaWJ1dGVzKFsKICAgICAgICAgICAgICAgICAgICAiY2xhc3NOYW1lIiwgInNwZWxsY2hlY2siLCAidGl0bGUiLCAibGFuZyIsICJhY2Nlc3NLZXkiCiAgICAgICAgICAgICAgICBdKS5mcm9tKHRoaXMudGV4dGFyZWEuZWxlbWVudCkudG8odGhpcy5lbGVtZW50KTsKCiAgICAgICAgICAgICAgICBkb20uYWRkQ2xhc3ModGhpcy5lbGVtZW50LCB0aGlzLmNvbmZpZy5jb21wb3NlckNsYXNzTmFtZSk7CiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgLy8gLy8gTWFrZSB0aGUgZWRpdG9yIGxvb2sgbGlrZSB0aGUgb3JpZ2luYWwgdGV4dGFyZWEsIGJ5IHN5bmNpbmcgc3R5bGVzCiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25maWcuc3R5bGUpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnN0eWxlKCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5vYnNlcnZlKCk7CgogICAgICAgICAgICAgICAgdmFyIG5hbWUgPSB0aGlzLmNvbmZpZy5uYW1lOwogICAgICAgICAgICAgICAgaWYgKG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICBkb20uYWRkQ2xhc3ModGhpcy5lbGVtZW50LCBuYW1lKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLmVuYWJsZSgpOwoKICAgICAgICAgICAgICAgIGlmICh0aGlzLnRleHRhcmVhLmVsZW1lbnQuZGlzYWJsZWQpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGUoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBTaW11bGF0ZSBodG1sNSBwbGFjZWhvbGRlciBhdHRyaWJ1dGUgb24gY29udGVudEVkaXRhYmxlIGVsZW1lbnQKICAgICAgICAgICAgICAgIHZhciBwbGFjZWhvbGRlclRleHQgPSB0eXBlb2YodGhpcy5jb25maWcucGxhY2Vob2xkZXIpID09PSAic3RyaW5nIiA/IHRoaXMuY29uZmlnLnBsYWNlaG9sZGVyIDogdGhpcy50ZXh0YXJlYS5lbGVtZW50LmdldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiKTsKICAgICAgICAgICAgICAgIGlmIChwbGFjZWhvbGRlclRleHQpIHsKICAgICAgICAgICAgICAgICAgICBkb20uc2ltdWxhdGVQbGFjZWhvbGRlcih0aGlzLnBhcmVudCwgdGhpcywgcGxhY2Vob2xkZXJUZXh0KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgYnJvd3NlciBhdm9pZHMgdXNpbmcgaW5saW5lIHN0eWxlcyB3aGVuZXZlciBwb3NzaWJsZQogICAgICAgICAgICAgICAgdGhpcy5jb21tYW5kcy5leGVjKCJzdHlsZVdpdGhDU1MiLCBmYWxzZSk7CgogICAgICAgICAgICAgICAgdGhpcy5faW5pdEF1dG9MaW5raW5nKCk7CiAgICAgICAgICAgICAgICB0aGlzLl9pbml0T2JqZWN0UmVzaXppbmcoKTsKICAgICAgICAgICAgICAgIHRoaXMuX2luaXRVbmRvTWFuYWdlcigpOwogICAgICAgICAgICAgICAgdGhpcy5faW5pdExpbmVCcmVha2luZygpOwoKICAgICAgICAgICAgICAgIC8vIFNpbXVsYXRlIGh0bWw1IGF1dG9mb2N1cyBvbiBjb250ZW50RWRpdGFibGUgZWxlbWVudAogICAgICAgICAgICAgICAgLy8gVGhpcyBkb2Vzbid0IHdvcmsgb24gSU9TICg1LjEuMSkKICAgICAgICAgICAgICAgIGlmICgodGhpcy50ZXh0YXJlYS5lbGVtZW50Lmhhc0F0dHJpYnV0ZSgiYXV0b2ZvY3VzIikgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiOmZvY3VzIikgPT0gdGhpcy50ZXh0YXJlYS5lbGVtZW50KSAmJiAhYnJvd3Nlci5pc0lvcygpKSB7CiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZm9jdXModHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBJRSBzb21ldGltZXMgbGVhdmVzIGEgc2luZ2xlIHBhcmFncmFwaCwgd2hpY2ggY2FuJ3QgYmUgcmVtb3ZlZCBieSB0aGUgdXNlcgogICAgICAgICAgICAgICAgaWYgKCFicm93c2VyLmNsZWFyc0NvbnRlbnRFZGl0YWJsZUNvcnJlY3RseSgpKSB7CiAgICAgICAgICAgICAgICAgICAgd3lzaWh0bWw1LnF1aXJrcy5lbnN1cmVQcm9wZXJDbGVhcmluZyh0aGlzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBTZXQgdXAgYSBzeW5jIHRoYXQgbWFrZXMgc3VyZSB0aGF0IHRleHRhcmVhIGFuZCBlZGl0b3IgaGF2ZSB0aGUgc2FtZSBjb250ZW50CiAgICAgICAgICAgICAgICBpZiAodGhpcy5pbml0U3luYyAmJiB0aGlzLmNvbmZpZy5zeW5jKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0U3luYygpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIE9rYXkgaGlkZSB0aGUgdGV4dGFyZWEsIHdlIGFyZSByZWFkeSB0byBnbwogICAgICAgICAgICAgICAgdGhpcy50ZXh0YXJlYS5oaWRlKCk7CgogICAgICAgICAgICAgICAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50OwogICAgICAgICAgICAgICAgLy8gRmlyZSBnbG9iYWwgKGJlZm9yZS0pbG9hZCBldmVudAogICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgcGFyZW50LmZpcmUoImJlZm9yZWxvYWQiKS5maXJlKCJsb2FkIik7CiAgICAgICAgICAgICAgICB9LCAwKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9pbml0QXV0b0xpbmtpbmcgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsCiAgICAgICAgICAgICAgICAgICAgc3VwcG9ydHNEaXNhYmxpbmdPZkF1dG9MaW5raW5nID0gYnJvd3Nlci5jYW5EaXNhYmxlQXV0b0xpbmtpbmcoKSwKICAgICAgICAgICAgICAgICAgICBzdXBwb3J0c0F1dG9MaW5raW5nID0gYnJvd3Nlci5kb2VzQXV0b0xpbmtpbmdJbkNvbnRlbnRFZGl0YWJsZSgpOwogICAgICAgICAgICAgICAgaWYgKHN1cHBvcnRzRGlzYWJsaW5nT2ZBdXRvTGlua2luZykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuY29tbWFuZHMuZXhlYygiYXV0b1VybERldGVjdCIsIGZhbHNlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlnLmF1dG9MaW5rKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIE9ubHkgZG8gdGhlIGF1dG8gbGlua2luZyBieSBvdXJzZWx2ZXMgd2hlbiB0aGUgYnJvd3NlciBkb2Vzbid0IHN1cHBvcnQgYXV0byBsaW5raW5nCiAgICAgICAgICAgICAgICAvLyBPUiB3aGVuIGhlIHN1cHBvcnRzIGF1dG8gbGlua2luZyBidXQgd2Ugd2VyZSBhYmxlIHRvIHR1cm4gaXQgb2ZmIChJRTkrKQogICAgICAgICAgICAgICAgaWYgKCFzdXBwb3J0c0F1dG9MaW5raW5nIHx8IChzdXBwb3J0c0F1dG9MaW5raW5nICYmIHN1cHBvcnRzRGlzYWJsaW5nT2ZBdXRvTGlua2luZykpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnBhcmVudC5vbigibmV3d29yZDpjb21wb3NlciIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvbS5nZXRUZXh0Q29udGVudCh0aGF0LmVsZW1lbnQpLm1hdGNoKGRvbS5hdXRvTGluay5VUkxfUkVHX0VYUCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uIChzdGFydENvbnRhaW5lciwgZW5kQ29udGFpbmVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tLmF1dG9MaW5rKGVuZENvbnRhaW5lci5wYXJlbnROb2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgIGRvbS5vYnNlcnZlKHRoaXMuZWxlbWVudCwgImJsdXIiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5hdXRvTGluayh0aGF0LmVsZW1lbnQpOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIEFzc3VtaW5nIHdlIGhhdmUgdGhlIGZvbGxvd2luZzoKICAgICAgICAgICAgICAgIC8vICA8YSBocmVmPSJodHRwOi8vd3d3Lmdvb2dsZS5kZSI+aHR0cDovL3d3dy5nb29nbGUuZGU8L2E+CiAgICAgICAgICAgICAgICAvLyBJZiBhIHVzZXIgbm93IGNoYW5nZXMgdGhlIHVybCBpbiB0aGUgaW5uZXJIVE1MIHdlIHdhbnQgdG8gbWFrZSBzdXJlIHRoYXQKICAgICAgICAgICAgICAgIC8vIGl0J3Mgc3luY2hyb25pemVkIHdpdGggdGhlIGhyZWYgYXR0cmlidXRlIChhcyBsb25nIGFzIHRoZSBpbm5lckhUTUwgaXMgc3RpbGwgYSB1cmwpCiAgICAgICAgICAgICAgICB2YXIgLy8gVXNlIGEgbGl2ZSBOb2RlTGlzdCB0byBjaGVjayB3aGV0aGVyIHRoZXJlIGFyZSBhbnkgbGlua3MgaW4gdGhlIGRvY3VtZW50CiAgICAgICAgICAgICAgICAgICAgbGlua3MgPSB0aGlzLnNhbmRib3guZ2V0RG9jdW1lbnQoKS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYSIpLAogICAgICAgICAgICAgICAgICAgIC8vIFRoZSBhdXRvTGluayBoZWxwZXIgbWV0aG9kIHJldmVhbHMgYSByZWcgZXhwIHRvIGRldGVjdCBjb3JyZWN0IHVybHMKICAgICAgICAgICAgICAgICAgICB1cmxSZWdFeHAgPSBkb20uYXV0b0xpbmsuVVJMX1JFR19FWFAsCiAgICAgICAgICAgICAgICAgICAgZ2V0VGV4dENvbnRlbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dENvbnRlbnQgPSB3eXNpaHRtbDUubGFuZy5zdHJpbmcoZG9tLmdldFRleHRDb250ZW50KGVsZW1lbnQpKS50cmltKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0Q29udGVudC5zdWJzdHIoMCwgNCkgPT09ICJ3d3cuIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dENvbnRlbnQgPSAiaHR0cDovLyIgKyB0ZXh0Q29udGVudDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dENvbnRlbnQ7CiAgICAgICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICBkb20ub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsICJrZXlkb3duIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFsaW5rcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkTm9kZSA9IHRoYXQuc2VsZWN0aW9uLmdldFNlbGVjdGVkTm9kZShldmVudC50YXJnZXQub3duZXJEb2N1bWVudCksCiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmsgPSBkb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHtub2RlTmFtZSA6ICJBIn0sIDQpLAogICAgICAgICAgICAgICAgICAgICAgICB0ZXh0Q29udGVudDsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCFsaW5rKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRleHRDb250ZW50ID0gZ2V0VGV4dENvbnRlbnQobGluayk7CiAgICAgICAgICAgICAgICAgICAgLy8ga2V5ZG93biBpcyBmaXJlZCBiZWZvcmUgdGhlIGFjdHVhbCBjb250ZW50IGlzIGNoYW5nZWQKICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZWZvcmUgd2Ugc2V0IGEgdGltZW91dCB0byBjaGFuZ2UgdGhlIGhyZWYKICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld1RleHRDb250ZW50ID0gZ2V0VGV4dENvbnRlbnQobGluayk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdUZXh0Q29udGVudCA9PT0gdGV4dENvbnRlbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBzZXQgaHJlZiB3aGVuIG5ldyBocmVmIGxvb2tzIGxpa2UgYSB2YWxpZCB1cmwKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld1RleHRDb250ZW50Lm1hdGNoKHVybFJlZ0V4cCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmsuc2V0QXR0cmlidXRlKCJocmVmIiwgbmV3VGV4dENvbnRlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9pbml0T2JqZWN0UmVzaXppbmcgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLmNvbW1hbmRzLmV4ZWMoImVuYWJsZU9iamVjdFJlc2l6aW5nIiwgdHJ1ZSk7CgogICAgICAgICAgICAgICAgLy8gSUUgc2V0cyBpbmxpbmUgc3R5bGVzIGFmdGVyIHJlc2l6aW5nIG9iamVjdHMKICAgICAgICAgICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgbGluZXMgbWFrZSBzdXJlIHRoYXQgdGhlIHdpZHRoL2hlaWdodCBjc3MgcHJvcGVydGllcwogICAgICAgICAgICAgICAgLy8gYXJlIGNvcGllZCBvdmVyIHRvIHRoZSB3aWR0aC9oZWlnaHQgYXR0cmlidXRlcwogICAgICAgICAgICAgICAgaWYgKGJyb3dzZXIuc3VwcG9ydHNFdmVudCgicmVzaXplZW5kIikpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcHJvcGVydGllcyA9IFsid2lkdGgiLCAiaGVpZ2h0Il0sCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnRpZXNMZW5ndGggPSBwcm9wZXJ0aWVzLmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IHRoaXMuZWxlbWVudDsKCiAgICAgICAgICAgICAgICAgICAgZG9tLm9ic2VydmUoZWxlbWVudCwgInJlc2l6ZWVuZCIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IHx8IGV2ZW50LnNyY0VsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZSA9IHRhcmdldC5zdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0Lm5vZGVOYW1lICE9PSAiSU1HIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPCBwcm9wZXJ0aWVzTGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eSA9IHByb3BlcnRpZXNbaV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGVbcHJvcGVydHldKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LnNldEF0dHJpYnV0ZShwcm9wZXJ0eSwgcGFyc2VJbnQoc3R5bGVbcHJvcGVydHldLCAxMCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlW3Byb3BlcnR5XSA9ICIiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBBZnRlciByZXNpemluZyBJRSBzb21ldGltZXMgZm9yZ2V0cyB0byByZW1vdmUgdGhlIG9sZCByZXNpemUgaGFuZGxlcwogICAgICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUucXVpcmtzLnJlZHJhdyhlbGVtZW50KTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9pbml0VW5kb01hbmFnZXIgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLnVuZG9NYW5hZ2VyID0gbmV3IHd5c2lodG1sNS5VbmRvTWFuYWdlcih0aGlzLnBhcmVudCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfaW5pdExpbmVCcmVha2luZyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcywKICAgICAgICAgICAgICAgICAgICBVU0VfTkFUSVZFX0xJTkVfQlJFQUtfSU5TSURFX1RBR1MgPSBbIkxJIiwgIlAiLCAiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiXSwKICAgICAgICAgICAgICAgICAgICBMSVNUX1RBR1MgPSBbIlVMIiwgIk9MIiwgIk1FTlUiXTsKCiAgICAgICAgICAgICAgICBmdW5jdGlvbiBhZGp1c3Qoc2VsZWN0ZWROb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudEVsZW1lbnQgPSBkb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHtub2RlTmFtZSA6IFsiUCIsICJESVYiLCAiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiXX0sIDIpOwogICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnRFbGVtZW50ICYmIChwYXJlbnRFbGVtZW50Lm5vZGVOYW1lID09ICJESVYiIHx8ICFwYXJlbnRFbGVtZW50LnRleHRDb250ZW50IHx8IHBhcmVudEVsZW1lbnQudGV4dENvbnRlbnQudHJpbSgpID09ICIiKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnNlbGVjdGlvbi5leGVjdXRlQW5kUmVzdG9yZShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5jb25maWcudXNlTGluZUJyZWFrcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5yZXBsYWNlV2l0aENoaWxkTm9kZXMocGFyZW50RWxlbWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmVudEVsZW1lbnQubm9kZU5hbWUgIT09ICJQIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5yZW5hbWVFbGVtZW50KHBhcmVudEVsZW1lbnQsICJwIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlnLnVzZUxpbmVCcmVha3MpIHsKICAgICAgICAgICAgICAgICAgICBkb20ub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsIFsiZm9jdXMiLCAia2V5ZG93biJdLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGF0LmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmFncmFwaCA9IHRoYXQuZG9jLmNyZWF0ZUVsZW1lbnQoIlAiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZWxlbWVudC5pbm5lckhUTUwgPSAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZWxlbWVudC5hcHBlbmRDaGlsZChwYXJhZ3JhcGgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNwYW4gPSB0aGF0LmRvYy5jcmVhdGVFbGVtZW50KCJzcGFuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhZ3JhcGguYXBwZW5kQ2hpbGQoc3Bhbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWJyb3dzZXIuZGlzcGxheXNDYXJldEluRW1wdHlDb250ZW50RWRpdGFibGVDb3JyZWN0bHkoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYW4uaW5uZXJIVE1MID0gIjxicj4iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5zZWxlY3Rpb24uc2VsZWN0Tm9kZShzcGFuLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGRvbS5vYnNlcnZlKHRoaXMuZWxlbWVudCwgImtleWRvd24iLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIga2V5Q29kZSA9IGV2ZW50LmtleUNvZGU7CgogICAgICAgICAgICAgICAgICAgIGlmIChldmVudC5zaGlmdEtleSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoa2V5Q29kZSAhPT0gd3lzaWh0bWw1LkVOVEVSX0tFWSAmJiBrZXlDb2RlICE9PSB3eXNpaHRtbDUuQkFDS1NQQUNFX0tFWSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB2YXIgYmxvY2tFbGVtZW50ID0gZG9tLmdldFBhcmVudEVsZW1lbnQodGhhdC5zZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKCksIHtub2RlTmFtZSA6IFVTRV9OQVRJVkVfTElORV9CUkVBS19JTlNJREVfVEFHU30pOwoKICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tFbGVtZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVW53cmFwIHBhcmFncmFwaCBhZnRlciBsZWF2aW5nIGEgbGlzdCBvciBhIEgxLTYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzZWxlY3RlZE5vZGUgPSB0aGF0LnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9GaXhpbmcgZm9yIExDLTM5MTA2ODIgOiBbVGV4dCBFZGl0b3JdIC0gTmV3ICdoZWxwIGNvbnRlbnQnIHN5bWJvbCBnZXRzIGFkZGVkIHdoZW4gdXNlciBwcmVzcyBlbnRlciBhZnRlciBhICdoZWxwIGNvbnRlbnQnIHN5bWJvbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXRzIGhhY2t5IG1ldGhvZCBidXQgZGlkbnQgZmluZCB3aG8gaXMgY29weWluZyB0aGUgc3R5bGUgJiBjbGFzcyBuYW1lIG9uIGNyZWF0aW5nIG5ldyBub2RlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lID0gInRleHRFZGl0b3ItY3VzdG9tRGF0YUF0dHIiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZSAmJiBzZWxlY3RlZE5vZGUuY2xhc3NOYW1lICYmIHNlbGVjdGVkTm9kZS5jbGFzc05hbWUuaW5kZXhPZihjbGFzc05hbWUpICE9IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWROb2RlLmNsYXNzTmFtZSA9IHNlbGVjdGVkTm9kZS5jbGFzc05hbWUucmVwbGFjZShjbGFzc05hbWUsICIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YSA9ICQoc2VsZWN0ZWROb2RlKS5kYXRhKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIGRhdGEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJChzZWxlY3RlZE5vZGUpLnJlbW92ZURhdGEoa2V5KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJChzZWxlY3RlZE5vZGUpLnJlbW92ZUF0dHIoImRhdGEtIiArIGtleSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoYXQuY29uZmlnICYmIHRoYXQuY29uZmlnLnBhcnNlclJ1bGVzICYmIHRoYXQuY29uZmlnLnBhcnNlclJ1bGVzLnBzZXVkb1RhZ3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZU5hbWVzID0gdGhhdC5jb25maWcucGFyc2VyUnVsZXMucHNldWRvVGFncy5tYXAoZnVuY3Rpb24gKHRhZykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFnLnRvVXBwZXJDYXNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcHNldWRvTm9kZSA9IGRvbS5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkTm9kZSwge25vZGVOYW1lIDogbm9kZU5hbWVzfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBzZXVkb05vZGUgJiYgIXBzZXVkb05vZGUudGV4dENvbnRlbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHNldWRvTm9kZS5vdXRlckhUTUwgPSAiPHNwYW4+IiArIHBzZXVkb05vZGUuaW5uZXJIVE1MICsgIjwvc3Bhbj4iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tFbGVtZW50Lm5vZGVOYW1lID09PSAiTEkiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzZWxlY3RlZE5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCA9IGRvbS5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkTm9kZSwge25vZGVOYW1lIDogTElTVF9UQUdTfSwgMik7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbGlzdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGp1c3Qoc2VsZWN0ZWROb2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleUNvZGUgPT09IHd5c2lodG1sNS5FTlRFUl9LRVkgJiYgYmxvY2tFbGVtZW50Lm5vZGVOYW1lLm1hdGNoKC9eSFsxLTZdJC8pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRqdXN0KHNlbGVjdGVkTm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVmZXRjaGluZyB0aGUgc2VsZWN0ZWQgbm9kZSBhcyBpdCBtYXkgYmUgbW9kaWZlZCBieSBhZGp1c3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IHRoYXQuc2VsZWN0aW9uLmdldFNlbGVjdGVkTm9kZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgZXZlcnkgcGFyYWdyYXBoICYgTEkgaGF2ZSBzcGFuIGVsZW1lbnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtYXRjaGluZ05vZGVzID0gWyJQIiwgIkxJIiwgIkRJViJdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbXB0TGlzdCA9IFtdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4IDwgbWF0Y2hpbmdOb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlTmFtZSA9IG1hdGNoaW5nTm9kZXNbaW5kZXhdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGFnTmFtZSA9IG5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZE5vZGUubm9kZU5hbWUgPT09IG5vZGVOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXB0TGlzdCA9IFtdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1wdExpc3QucHVzaCgiPCIgKyB0YWdOYW1lICsgIj48LyIgKyB0YWdOYW1lICsgIj4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcHRMaXN0LnB1c2goIjwiICsgdGFnTmFtZSArICI+PGJyPjwvIiArIHRhZ05hbWUgKyAiPiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1wdExpc3QucHVzaCgiPCIgKyB0YWdOYW1lICsgIj48YnI+PC9icj48LyIgKyB0YWdOYW1lICsgIj4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIG5vZGUgaXMgZW1wdHkgKCBlbXB0eSBpbmNsdWRlIDxicj4gY2FzZSBhbHNvKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVtcHRMaXN0LmluZGV4T2Yoc2VsZWN0ZWROb2RlLm91dGVySFRNTCkgPiAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzcGFuID0gdGhhdC5kb2MuY3JlYXRlRWxlbWVudCgic3BhbiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYnJvd3Nlci5kaXNwbGF5c0NhcmV0SW5FbXB0eUNvbnRlbnRFZGl0YWJsZUNvcnJlY3RseSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYW4uaW5uZXJIVE1MID0gIjxicj4iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmUgPEJSPiBpZiBhbnkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc2VsZWN0ZWROb2RlLmZpcnN0Q2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWROb2RlLnJlbW92ZUNoaWxkKHNlbGVjdGVkTm9kZS5maXJzdENoaWxkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWROb2RlLmFwcGVuZENoaWxkKHNwYW4pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZE5vZGUubm9kZU5hbWUgPT09ICJESVYiKSB7Ly8gTWFrZSBzdXJlIHdlIGhhdmUgb25seSBQIG9yIExJIHRhZ3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tLnJlbmFtZUVsZW1lbnQoc2VsZWN0ZWROb2RlLCAicCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnNlbGVjdGlvbi5zZWxlY3ROb2RlKHNwYW4pOy8vIEZvcmNpbmcgdG8gZm9jdXMgb24gc3BhbiBvdGhlciB0ZXh0IHdpbGwgYmUgaW5zZXJ0IGF0IHAgb3IgbGkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCBldmVyeSBMSSBoYXZlIHBhcmFncmFwaCtzcGFuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50TEkgPSBkb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHtub2RlTmFtZSA6ICJMSSJ9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudERJViA9IGRvbS5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkTm9kZSwge25vZGVOYW1lIDogIkRJViJ9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudExJKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmEgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgZmlzdCBjaGlsZCBub2RlIGlzIHBhcmFncmFwaCA6IGlmIHRydWUgc2ltcGxlIHJldHVybiBvciBlbHNlIG1vdmUgdGhlIExJIGNvbnRlbnQgdG8gcGFyYWdyYXBoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBhcmUgbm90IGNoZWNrIGFsbCB0aGUgY2hpbGQgYXMgc2hpZnQgZW50ZXIgaXMgdXNlZCBmb3IgbmV3IExpbmUgYW5kIGl0IHdpbGwgY3JlYXRlIHNwYW4gaW4gcGFyYWdyYXBoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50TEkuY2hpbGRFbGVtZW50Q291bnQgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGROb2RlID0gcGFyZW50TEkuY2hpbGROb2Rlc1swXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGROb2RlICYmIGNoaWxkTm9kZS5ub2RlTmFtZSA9PSAiUCIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmEgPSB0aGF0LmRvYy5jcmVhdGVFbGVtZW50KCJwIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudExJLmFwcGVuZENoaWxkKHBhcmEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGNoaWxkSW5kZXggPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZEluZGV4IDwgcGFyZW50TEkuY2hpbGRFbGVtZW50Q291bnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkSW5kZXgrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkTm9kZSA9IHBhcmVudExJLmNoaWxkTm9kZXNbY2hpbGRJbmRleF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYS5hcHBlbmRDaGlsZChjaGlsZE5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuc2VsZWN0aW9uLnNlbGVjdE5vZGUoY2hpbGROb2RlKTsvLyBGb3JjaW5nIHRvIGZvY3VzIG9uIHNwYW4gb3RoZXIgdGV4dCB3aWxsIGJlIGluc2VydCBhdCBwIG9yIGxpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudERJViAmJiAhd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKHBhcmVudERJVikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJzZWRFbGVtID0gdGhhdC5wYXJlbnQucGFyc2UocGFyZW50RElWKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZWRFbGVtLmlubmVySFRNTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudERJVi5vdXRlckhUTUwgPSBwYXJzZWRFbGVtLmlubmVySFRNTDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh0aGF0LmNvbmZpZy51c2VMaW5lQnJlYWtzICYmIGtleUNvZGUgPT09IHd5c2lodG1sNS5FTlRFUl9LRVkgJiYgIXd5c2lodG1sNS5icm93c2VyLmluc2VydHNMaW5lQnJlYWtzT25SZXR1cm4oKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmNvbW1hbmRzLmV4ZWMoImluc2VydExpbmVCcmVhayIpOwogICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgZG9tID0gd3lzaWh0bWw1LmRvbSwKICAgICAgICBkb2MgPSBkb2N1bWVudCwKICAgICAgICB3aW4gPSB3aW5kb3csCiAgICAgICAgSE9TVF9URU1QTEFURSA9IGRvYy5jcmVhdGVFbGVtZW50KCJkaXYiKSwKICAgICAgICAvKioKICAgICAgICAgKiBTdHlsZXMgdG8gY29weSBmcm9tIHRleHRhcmVhIHRvIHRoZSBjb21wb3NlciBlbGVtZW50CiAgICAgICAgICovCiAgICAgICAgVEVYVF9GT1JNQVRUSU5HID0gWwogICAgICAgICAgICAiYmFja2dyb3VuZC1jb2xvciIsCiAgICAgICAgICAgICJjb2xvciIsICJjdXJzb3IiLAogICAgICAgICAgICAiZm9udC1mYW1pbHkiLCAiZm9udC1zaXplIiwgImZvbnQtc3R5bGUiLCAiZm9udC12YXJpYW50IiwgImZvbnQtd2VpZ2h0IiwKICAgICAgICAgICAgImxpbmUtaGVpZ2h0IiwgImxldHRlci1zcGFjaW5nIiwKICAgICAgICAgICAgInRleHQtYWxpZ24iLCAidGV4dC1kZWNvcmF0aW9uIiwgInRleHQtaW5kZW50IiwgInRleHQtcmVuZGVyaW5nIiwKICAgICAgICAgICAgIndvcmQtYnJlYWsiLCAid29yZC13cmFwIiwgIndvcmQtc3BhY2luZyIKICAgICAgICBdLAogICAgICAgIC8qKgogICAgICAgICAqIFN0eWxlcyB0byBjb3B5IGZyb20gdGV4dGFyZWEgdG8gdGhlIGlmcmFtZQogICAgICAgICAqLwogICAgICAgIEJPWF9GT1JNQVRUSU5HID0gWwogICAgICAgICAgICAiYmFja2dyb3VuZC1jb2xvciIsCiAgICAgICAgICAgICJib3JkZXItY29sbGFwc2UiLAogICAgICAgICAgICAiYm9yZGVyLWJvdHRvbS1jb2xvciIsICJib3JkZXItYm90dG9tLXN0eWxlIiwgImJvcmRlci1ib3R0b20td2lkdGgiLAogICAgICAgICAgICAiYm9yZGVyLWxlZnQtY29sb3IiLCAiYm9yZGVyLWxlZnQtc3R5bGUiLCAiYm9yZGVyLWxlZnQtd2lkdGgiLAogICAgICAgICAgICAiYm9yZGVyLXJpZ2h0LWNvbG9yIiwgImJvcmRlci1yaWdodC1zdHlsZSIsICJib3JkZXItcmlnaHQtd2lkdGgiLAogICAgICAgICAgICAiYm9yZGVyLXRvcC1jb2xvciIsICJib3JkZXItdG9wLXN0eWxlIiwgImJvcmRlci10b3Atd2lkdGgiLAogICAgICAgICAgICAiY2xlYXIiLCAiZGlzcGxheSIsICJmbG9hdCIsCiAgICAgICAgICAgICJtYXJnaW4tYm90dG9tIiwgIm1hcmdpbi1sZWZ0IiwgIm1hcmdpbi1yaWdodCIsICJtYXJnaW4tdG9wIiwKICAgICAgICAgICAgIm91dGxpbmUtY29sb3IiLCAib3V0bGluZS1vZmZzZXQiLCAib3V0bGluZS13aWR0aCIsICJvdXRsaW5lLXN0eWxlIiwKICAgICAgICAgICAgInBhZGRpbmctbGVmdCIsICJwYWRkaW5nLXJpZ2h0IiwgInBhZGRpbmctdG9wIiwgInBhZGRpbmctYm90dG9tIiwKICAgICAgICAgICAgInBvc2l0aW9uIiwgInRvcCIsICJsZWZ0IiwgInJpZ2h0IiwgImJvdHRvbSIsICJ6LWluZGV4IiwKICAgICAgICAgICAgInZlcnRpY2FsLWFsaWduIiwgInRleHQtYWxpZ24iLAogICAgICAgICAgICAiLXdlYmtpdC1ib3gtc2l6aW5nIiwgIi1tb3otYm94LXNpemluZyIsICItbXMtYm94LXNpemluZyIsICJib3gtc2l6aW5nIiwKICAgICAgICAgICAgIi13ZWJraXQtYm94LXNoYWRvdyIsICItbW96LWJveC1zaGFkb3ciLCAiLW1zLWJveC1zaGFkb3ciLCAiYm94LXNoYWRvdyIsCiAgICAgICAgICAgICItd2Via2l0LWJvcmRlci10b3AtcmlnaHQtcmFkaXVzIiwgIi1tb3otYm9yZGVyLXJhZGl1cy10b3ByaWdodCIsICJib3JkZXItdG9wLXJpZ2h0LXJhZGl1cyIsCiAgICAgICAgICAgICItd2Via2l0LWJvcmRlci1ib3R0b20tcmlnaHQtcmFkaXVzIiwgIi1tb3otYm9yZGVyLXJhZGl1cy1ib3R0b21yaWdodCIsICJib3JkZXItYm90dG9tLXJpZ2h0LXJhZGl1cyIsCiAgICAgICAgICAgICItd2Via2l0LWJvcmRlci1ib3R0b20tbGVmdC1yYWRpdXMiLCAiLW1vei1ib3JkZXItcmFkaXVzLWJvdHRvbWxlZnQiLCAiYm9yZGVyLWJvdHRvbS1sZWZ0LXJhZGl1cyIsCiAgICAgICAgICAgICItd2Via2l0LWJvcmRlci10b3AtbGVmdC1yYWRpdXMiLCAiLW1vei1ib3JkZXItcmFkaXVzLXRvcGxlZnQiLCAiYm9yZGVyLXRvcC1sZWZ0LXJhZGl1cyIsCiAgICAgICAgICAgICJ3aWR0aCIsICJoZWlnaHQiLCAid2hpdGUtc3BhY2UiCiAgICAgICAgXSwKICAgICAgICBBRERJVElPTkFMX0NTU19SVUxFUyA9IFsKICAgICAgICAgICAgImh0bWwgICAgICAgICAgICAgICAgIHsgaGVpZ2h0OiAxMDAlOyB9IiwKICAgICAgICAgICAgImJvZHkgICAgICAgICAgICAgICAgIHsgaGVpZ2h0OiAxMDAlOyBwYWRkaW5nOiAxcHggMCAwIDA7IG1hcmdpbjogLTFweCAwIDAgMDsgfSIsCiAgICAgICAgICAgICJib2R5ID4gcDpmaXJzdC1jaGlsZCB7IG1hcmdpbi10b3A6IDA7IH0iLAogICAgICAgICAgICAiLl93eXNpaHRtbDUtdGVtcCAgICAgeyBkaXNwbGF5OiBub25lOyB9IiwKICAgICAgICAgICAgd3lzaWh0bWw1LmJyb3dzZXIuaXNHZWNrbyA/CiAgICAgICAgICAgICAgICAiYm9keS5wbGFjZWhvbGRlciB7IGNvbG9yOiBncmF5dGV4dCAhaW1wb3J0YW50OyB9IiA6CiAgICAgICAgICAgICAgICAiYm9keS5wbGFjZWhvbGRlciB7IGNvbG9yOiAjYTlhOWE5ICFpbXBvcnRhbnQ7IH0iLAogICAgICAgICAgICAvLyBFbnN1cmUgdGhhdCB1c2VyIHNlZSdzIGJyb2tlbiBpbWFnZXMgYW5kIGNhbiBkZWxldGUgdGhlbQogICAgICAgICAgICAiaW1nOi1tb3otYnJva2VuICAgICAgeyAtbW96LWZvcmNlLWJyb2tlbi1pbWFnZS1pY29uOiAxOyBoZWlnaHQ6IDI0cHg7IHdpZHRoOiAyNHB4OyB9IgogICAgICAgIF07CgogICAgLyoqCiAgICAgKiBXaXRoICJzZXRBY3RpdmUiIElFIG9mZmVycyBhIHNtYXJ0IHdheSBvZiBmb2N1c2luZyBlbGVtZW50cyB3aXRob3V0IHNjcm9sbGluZyB0aGVtIGludG8gdmlldzoKICAgICAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNjczOCh2PXZzLjg1KS5hc3B4CiAgICAgKgogICAgICogT3RoZXIgYnJvd3NlcnMgbmVlZCBhIG1vcmUgaGFja3kgd2F5OiAocHNzc3QgZG9uJ3QgdGVsbCBteSBtYW1hKQogICAgICogSW4gb3JkZXIgdG8gcHJldmVudCB0aGUgZWxlbWVudCBiZWluZyBzY3JvbGxlZCBpbnRvIHZpZXcgd2hlbiBmb2N1c2luZyBpdCwgd2Ugc2ltcGx5CiAgICAgKiBtb3ZlIGl0IG91dCBvZiB0aGUgc2Nyb2xsYWJsZSBhcmVhLCBmb2N1cyBpdCwgYW5kIHJlc2V0IGl0J3MgcG9zaXRpb24KICAgICAqLwogICAgdmFyIGZvY3VzV2l0aG91dFNjcm9sbGluZyA9IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgICAgaWYgKGVsZW1lbnQuc2V0QWN0aXZlKSB7CiAgICAgICAgICAgIC8vIEZvbGxvd2luZyBsaW5lIGNvdWxkIGNhdXNlIGEganMgZXJyb3Igd2hlbiB0aGUgdGV4dGFyZWEgaXMgaW52aXNpYmxlCiAgICAgICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20veGluZy93eXNpaHRtbDUvaXNzdWVzLzkKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QWN0aXZlKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZhciBlbGVtZW50U3R5bGUgPSBlbGVtZW50LnN0eWxlLAogICAgICAgICAgICAgICAgb3JpZ2luYWxTY3JvbGxUb3AgPSBkb2MuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBkb2MuYm9keS5zY3JvbGxUb3AsCiAgICAgICAgICAgICAgICBvcmlnaW5hbFNjcm9sbExlZnQgPSBkb2MuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQgfHwgZG9jLmJvZHkuc2Nyb2xsTGVmdCwKICAgICAgICAgICAgICAgIG9yaWdpbmFsU3R5bGVzID0gewogICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uIDogZWxlbWVudFN0eWxlLnBvc2l0aW9uLAogICAgICAgICAgICAgICAgICAgIHRvcCA6IGVsZW1lbnRTdHlsZS50b3AsCiAgICAgICAgICAgICAgICAgICAgbGVmdCA6IGVsZW1lbnRTdHlsZS5sZWZ0LAogICAgICAgICAgICAgICAgICAgIFdlYmtpdFVzZXJTZWxlY3QgOiBlbGVtZW50U3R5bGUuV2Via2l0VXNlclNlbGVjdAogICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIGRvbS5zZXRTdHlsZXMoewogICAgICAgICAgICAgICAgcG9zaXRpb24gOiAiYWJzb2x1dGUiLAogICAgICAgICAgICAgICAgdG9wIDogIi05OTk5OXB4IiwKICAgICAgICAgICAgICAgIGxlZnQgOiAiLTk5OTk5cHgiLAogICAgICAgICAgICAgICAgLy8gRG9uJ3QgYXNrIHdoeSBidXQgdGVtcG9yYXJpbHkgc2V0dGluZyAtd2Via2l0LXVzZXItc2VsZWN0IHRvIG5vbmUgbWFrZXMgdGhlIHdob2xlIHRoaW5nIHBlcmZvcm1pbmcgc21vb3RoZXIKICAgICAgICAgICAgICAgIFdlYmtpdFVzZXJTZWxlY3QgOiAibm9uZSIKICAgICAgICAgICAgfSkub24oZWxlbWVudCk7CgogICAgICAgICAgICBlbGVtZW50LmZvY3VzKCk7CgogICAgICAgICAgICBkb20uc2V0U3R5bGVzKG9yaWdpbmFsU3R5bGVzKS5vbihlbGVtZW50KTsKCiAgICAgICAgICAgIGlmICh3aW4uc2Nyb2xsVG8pIHsKICAgICAgICAgICAgICAgIC8vIFNvbWUgYnJvd3NlciBleHRlbnNpb25zIHVuc2V0IHRoaXMgbWV0aG9kIHRvIHByZXZlbnQgYW5ub3lhbmNlcwogICAgICAgICAgICAgICAgLy8gIkJldHRlciBQb3BVcCBCbG9ja2VyIiBmb3IgQ2hyb21lIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9iZXR0ZXJwb3B1cGJsb2NrZXIvc291cmNlL2Jyb3dzZS90cnVuay9ibG9ja1N0YXJ0LmpzIzEwMAogICAgICAgICAgICAgICAgLy8gSXNzdWU6IGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9iZXR0ZXJwb3B1cGJsb2NrZXIvaXNzdWVzL2RldGFpbD9pZD0xCiAgICAgICAgICAgICAgICB3aW4uc2Nyb2xsVG8ob3JpZ2luYWxTY3JvbGxMZWZ0LCBvcmlnaW5hbFNjcm9sbFRvcCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwoKICAgIHd5c2lodG1sNS52aWV3cy5Db21wb3Nlci5wcm90b3R5cGUuc3R5bGUgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHRoYXQgPSB0aGlzLAogICAgICAgICAgICBvcmlnaW5hbEFjdGl2ZUVsZW1lbnQgPSBkb2MucXVlcnlTZWxlY3RvcigiOmZvY3VzIiksCiAgICAgICAgICAgIHRleHRhcmVhRWxlbWVudCA9IHRoaXMudGV4dGFyZWEuZWxlbWVudCwKICAgICAgICAgICAgaGFzUGxhY2Vob2xkZXIgPSB0ZXh0YXJlYUVsZW1lbnQuaGFzQXR0cmlidXRlKCJwbGFjZWhvbGRlciIpLAogICAgICAgICAgICBvcmlnaW5hbFBsYWNlaG9sZGVyID0gaGFzUGxhY2Vob2xkZXIgJiYgdGV4dGFyZWFFbGVtZW50LmdldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiKSwKICAgICAgICAgICAgb3JpZ2luYWxEaXNwbGF5VmFsdWUgPSB0ZXh0YXJlYUVsZW1lbnQuc3R5bGUuZGlzcGxheSwKICAgICAgICAgICAgb3JpZ2luYWxEaXNhYmxlZCA9IHRleHRhcmVhRWxlbWVudC5kaXNhYmxlZCwKICAgICAgICAgICAgZGlzcGxheVZhbHVlRm9yQ29weWluZzsKCiAgICAgICAgdGhpcy5mb2N1c1N0eWxlc0hvc3QgPSBIT1NUX1RFTVBMQVRFLmNsb25lTm9kZShmYWxzZSk7CiAgICAgICAgdGhpcy5ibHVyU3R5bGVzSG9zdCA9IEhPU1RfVEVNUExBVEUuY2xvbmVOb2RlKGZhbHNlKTsKICAgICAgICB0aGlzLmRpc2FibGVkU3R5bGVzSG9zdCA9IEhPU1RfVEVNUExBVEUuY2xvbmVOb2RlKGZhbHNlKTsKCiAgICAgICAgLy8gUmVtb3ZlIHBsYWNlaG9sZGVyIGJlZm9yZSBjb3B5aW5nIChhcyB0aGUgcGxhY2Vob2xkZXIgaGFzIGFuIGFmZmVjdCBvbiB0aGUgY29tcHV0ZWQgc3R5bGUpCiAgICAgICAgaWYgKGhhc1BsYWNlaG9sZGVyKSB7CiAgICAgICAgICAgIHRleHRhcmVhRWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIik7CiAgICAgICAgfQoKICAgICAgICBpZiAodGV4dGFyZWFFbGVtZW50ID09PSBvcmlnaW5hbEFjdGl2ZUVsZW1lbnQpIHsKICAgICAgICAgICAgdGV4dGFyZWFFbGVtZW50LmJsdXIoKTsKICAgICAgICB9CgogICAgICAgIC8vIGVuYWJsZSBmb3IgY29weWluZyBzdHlsZXMKICAgICAgICB0ZXh0YXJlYUVsZW1lbnQuZGlzYWJsZWQgPSBmYWxzZTsKCiAgICAgICAgLy8gc2V0IHRleHRhcmVhIHRvIGRpc3BsYXk9Im5vbmUiIHRvIGdldCBjYXNjYWRlZCBzdHlsZXMgdmlhIGdldENvbXB1dGVkU3R5bGUKICAgICAgICB0ZXh0YXJlYUVsZW1lbnQuc3R5bGUuZGlzcGxheSA9IGRpc3BsYXlWYWx1ZUZvckNvcHlpbmcgPSAibm9uZSI7CiAgICAgICAgdGV4dGFyZWFFbGVtZW50LnN0eWxlLnZpc2liaWxpdHkgPSAiaGlkZGVuIjsKCiAgICAgICAgaWYgKCh0ZXh0YXJlYUVsZW1lbnQuZ2V0QXR0cmlidXRlKCJyb3dzIikgJiYgZG9tLmdldFN0eWxlKCJoZWlnaHQiKS5mcm9tKHRleHRhcmVhRWxlbWVudCkgPT09ICJhdXRvIikgfHwKICAgICAgICAgICAgKHRleHRhcmVhRWxlbWVudC5nZXRBdHRyaWJ1dGUoImNvbHMiKSAmJiBkb20uZ2V0U3R5bGUoIndpZHRoIikuZnJvbSh0ZXh0YXJlYUVsZW1lbnQpID09PSAiYXV0byIpKSB7CiAgICAgICAgICAgIHRleHRhcmVhRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gZGlzcGxheVZhbHVlRm9yQ29weWluZyA9IG9yaWdpbmFsRGlzcGxheVZhbHVlOwogICAgICAgIH0KCiAgICAgICAgLy8gLS0tLS0tLS0tIGNvbnRhaW5lciBzdHlsZXMgKGhhcyB0byBiZSBzZXQgYmVmb3JlIGVkaXRvciBzdHlsZXMsIG90aGVyd2lzZSBJRTkgc2V0cyB3cm9uZyBmb250RmFtaWx5IG9uIGJsdXJTdHlsZXNIb3N0KSAtLS0tLS0tLS0KICAgICAgICBkb20uY29weVN0eWxlcyhCT1hfRk9STUFUVElORykuZnJvbSh0ZXh0YXJlYUVsZW1lbnQpLnRvKHRoaXMuY29udGFpbmVyKS5hbmRUbyh0aGlzLmJsdXJTdHlsZXNIb3N0KTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIGVkaXRvciBzdHlsZXMgLS0tLS0tLS0tCiAgICAgICAgZG9tLmNvcHlTdHlsZXMoVEVYVF9GT1JNQVRUSU5HKS5mcm9tKHRleHRhcmVhRWxlbWVudCkudG8odGhpcy5lbGVtZW50KS5hbmRUbyh0aGlzLmJsdXJTdHlsZXNIb3N0KTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIGFwcGx5IHN0YW5kYXJkIHJ1bGVzIC0tLS0tLS0tLQogICAgICAgIGRvbS5pbnNlcnRDU1MoQURESVRJT05BTF9DU1NfUlVMRVMpLmludG8odGhpcy5lbGVtZW50Lm93bmVyRG9jdW1lbnQpOwoKICAgICAgICAvLyAtLS0tLS0tLS0gOmRpc2FibGVkIHN0eWxlcyAtLS0tLS0tLS0KICAgICAgICB0ZXh0YXJlYUVsZW1lbnQuZGlzYWJsZWQgPSB0cnVlOwogICAgICAgIGRvbS5jb3B5U3R5bGVzKEJPWF9GT1JNQVRUSU5HKS5mcm9tKHRleHRhcmVhRWxlbWVudCkudG8odGhpcy5kaXNhYmxlZFN0eWxlc0hvc3QpOwogICAgICAgIGRvbS5jb3B5U3R5bGVzKFRFWFRfRk9STUFUVElORykuZnJvbSh0ZXh0YXJlYUVsZW1lbnQpLnRvKHRoaXMuZGlzYWJsZWRTdHlsZXNIb3N0KTsKICAgICAgICB0ZXh0YXJlYUVsZW1lbnQuZGlzYWJsZWQgPSBvcmlnaW5hbERpc2FibGVkOwoKICAgICAgICAvLyAtLS0tLS0tLS0gOmZvY3VzIHN0eWxlcyAtLS0tLS0tLS0KICAgICAgICB0ZXh0YXJlYUVsZW1lbnQuc3R5bGUuZGlzcGxheSA9IG9yaWdpbmFsRGlzcGxheVZhbHVlOwogICAgICAgIGZvY3VzV2l0aG91dFNjcm9sbGluZyh0ZXh0YXJlYUVsZW1lbnQpOwogICAgICAgIHRleHRhcmVhRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gZGlzcGxheVZhbHVlRm9yQ29weWluZzsKCiAgICAgICAgZG9tLmNvcHlTdHlsZXMoQk9YX0ZPUk1BVFRJTkcpLmZyb20odGV4dGFyZWFFbGVtZW50KS50byh0aGlzLmZvY3VzU3R5bGVzSG9zdCk7CiAgICAgICAgZG9tLmNvcHlTdHlsZXMoVEVYVF9GT1JNQVRUSU5HKS5mcm9tKHRleHRhcmVhRWxlbWVudCkudG8odGhpcy5mb2N1c1N0eWxlc0hvc3QpOwoKICAgICAgICAvLyByZXNldCB0ZXh0YXJlYQogICAgICAgIHRleHRhcmVhRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gb3JpZ2luYWxEaXNwbGF5VmFsdWU7CgogICAgICAgIGRvbS5jb3B5U3R5bGVzKFsiZGlzcGxheSJdKS5mcm9tKHRleHRhcmVhRWxlbWVudCkudG8odGhpcy5jb250YWluZXIpOwoKICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCB3ZSBkb24ndCBjaGFuZ2UgdGhlIGRpc3BsYXkgc3R5bGUgb2YgdGhlIGNvbnRhaW5lciB3aGVuIGNvcHlpbmcgc3R5bGVzIG9ibHVyL29uZm9jdXMKICAgICAgICAvLyB0aGlzIGlzIG5lZWRlZCBmb3Igd2hlbiB0aGUgY2hhbmdlX3ZpZXcgZXZlbnQgaXMgZmlyZWQgd2hlcmUgdGhlIGNvbnRhaW5lciBpcyBoaWRkZW4gYW5kIHRoZW4KICAgICAgICAvLyB0aGUgYmx1ciBldmVudCBmaXJlcyBhbmQgcmUtZGlzcGxheXMgaXQKICAgICAgICB2YXIgYm94Rm9ybWF0dGluZ1N0eWxlcyA9IHd5c2lodG1sNS5sYW5nLmFycmF5KEJPWF9GT1JNQVRUSU5HKS53aXRob3V0KFsiZGlzcGxheSJdKTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIHJlc3RvcmUgZm9jdXMgLS0tLS0tLS0tCiAgICAgICAgaWYgKG9yaWdpbmFsQWN0aXZlRWxlbWVudCkgewogICAgICAgICAgICBvcmlnaW5hbEFjdGl2ZUVsZW1lbnQuZm9jdXMoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0ZXh0YXJlYUVsZW1lbnQuYmx1cigpOwogICAgICAgIH0KCiAgICAgICAgLy8gLS0tLS0tLS0tIHJlc3RvcmUgcGxhY2Vob2xkZXIgLS0tLS0tLS0tCiAgICAgICAgaWYgKGhhc1BsYWNlaG9sZGVyKSB7CiAgICAgICAgICAgIHRleHRhcmVhRWxlbWVudC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgb3JpZ2luYWxQbGFjZWhvbGRlcik7CiAgICAgICAgfQoKICAgICAgICAvLyAtLS0tLS0tLS0gU3luYyBmb2N1cy9ibHVyIHN0eWxlcyAtLS0tLS0tLS0KCiAgICAgICAgdGhpcy5wYXJlbnQub24oImJsdXI6Y29tcG9zZXIiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vIEZpeGluZyBMQy0zOTExOTk0CiAgICAgICAgICAgIHRoaXMuc2F2ZWRTZWxlY3Rpb24gPSB0aGlzLmNvbXBvc2VyLnNlbGVjdGlvbi5nZXRDdXJyZW50UmFuZ2UoKTsKICAgICAgICB9KTsKCiAgICAgICAgdGhpcy5wYXJlbnQub2JzZXJ2ZSgiZGlzYWJsZTpjb21wb3NlciIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgZG9tLmNvcHlTdHlsZXMoYm94Rm9ybWF0dGluZ1N0eWxlcykuZnJvbSh0aGF0LmRpc2FibGVkU3R5bGVzSG9zdCkudG8odGhhdC5jb250YWluZXIpOwogICAgICAgICAgICBkb20uY29weVN0eWxlcyhURVhUX0ZPUk1BVFRJTkcpLmZyb20odGhhdC5kaXNhYmxlZFN0eWxlc0hvc3QpLnRvKHRoYXQuZWxlbWVudCk7CiAgICAgICAgfSk7CgogICAgICAgIHRoaXMucGFyZW50Lm9ic2VydmUoImVuYWJsZTpjb21wb3NlciIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgZG9tLmNvcHlTdHlsZXMoYm94Rm9ybWF0dGluZ1N0eWxlcykuZnJvbSh0aGF0LmJsdXJTdHlsZXNIb3N0KS50byh0aGF0LmNvbnRhaW5lcik7CiAgICAgICAgICAgIGRvbS5jb3B5U3R5bGVzKFRFWFRfRk9STUFUVElORykuZnJvbSh0aGF0LmJsdXJTdHlsZXNIb3N0KS50byh0aGF0LmVsZW1lbnQpOwogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gdGhpczsKICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBUYWtpbmcgY2FyZSBvZiBldmVudHMKICogIC0gU2ltdWxhdGluZyAnY2hhbmdlJyBldmVudCBvbiBjb250ZW50RWRpdGFibGUgZWxlbWVudAogKiAgLSBIYW5kbGluZyBkcmFnICYgZHJvcCBsb2dpYwogKiAgLSBDYXRjaCBwYXN0ZSBldmVudHMKICogIC0gRGlzcGF0Y2ggcHJvcHJpZXRhcnkgbmV3d29yZDpjb21wb3NlciBldmVudAogKiAgLSBLZXlib2FyZCBzaG9ydGN1dHMKICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgZG9tID0gd3lzaWh0bWw1LmRvbSwKICAgICAgICBicm93c2VyID0gd3lzaWh0bWw1LmJyb3dzZXIsCiAgICAgICAgLyoqCiAgICAgICAgICogTWFwIGtleUNvZGVzIHRvIHF1ZXJ5IGNvbW1hbmRzCiAgICAgICAgICovCiAgICAgICAgc2hvcnRjdXRzID0gewogICAgICAgICAgICAiNjYiIDogImJvbGQiLCAgICAgLy8gQgogICAgICAgICAgICAiNzMiIDogIml0YWxpYyIsICAgLy8gSQogICAgICAgICAgICAiODUiIDogInVuZGVybGluZSIgLy8gVQogICAgICAgIH07CgogICAgd3lzaWh0bWw1LnZpZXdzLkNvbXBvc2VyLnByb3RvdHlwZS5vYnNlcnZlID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciB0aGF0ID0gdGhpcywKICAgICAgICAgICAgc3RhdGUgPSB0aGlzLmdldFZhbHVlKCksCiAgICAgICAgICAgIGNvbnRhaW5lciA9IHRoaXMuc2FuZGJveC5nZXRDb250YWluZXIoKSwKICAgICAgICAgICAgZWxlbWVudCA9IHRoaXMuZWxlbWVudCwKICAgICAgICAgICAgZm9jdXNCbHVyRWxlbWVudCA9IGJyb3dzZXIuc3VwcG9ydHNFdmVudHNJbklmcmFtZUNvcnJlY3RseSgpID8gZWxlbWVudCA6IHRoaXMuc2FuZGJveC5nZXRXaW5kb3coKSwKICAgICAgICAgICAgcGFzdGVFdmVudHMgPSBbImRyb3AiLCAicGFzdGUiXTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIGRlc3Ryb3k6Y29tcG9zZXIgZXZlbnQgLS0tLS0tLS0tCiAgICAgICAgZG9tLm9ic2VydmUoY29udGFpbmVyLCAiRE9NTm9kZVJlbW92ZWQiLCBmdW5jdGlvbiAoZSkgewogICAgICAgICAgICBpZiAoZS50YXJnZXQgPT0gdGhpcykgeyAvL0Rlc3Ryb3kgY29tcG9zZXIgb25seSBpZiB0aGUgZW50aXJlIFJURSBjb250YWluZXIgaXMgcmVtb3ZlZAogICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChkb21Ob2RlUmVtb3ZlZEludGVydmFsKTsKICAgICAgICAgICAgICAgIHRoYXQucGFyZW50LmZpcmUoImRlc3Ryb3k6Y29tcG9zZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwoKICAgICAgICAvLyBET01Ob2RlUmVtb3ZlZCBldmVudCBpcyBub3Qgc3VwcG9ydGVkIGluIElFIDgKICAgICAgICB2YXIgZG9tTm9kZVJlbW92ZWRJbnRlcnZhbCA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKCFkb20uY29udGFpbnMoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCBjb250YWluZXIpKSB7CiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKGRvbU5vZGVSZW1vdmVkSW50ZXJ2YWwpOwogICAgICAgICAgICAgICAgdGhhdC5wYXJlbnQuZmlyZSgiZGVzdHJveTpjb21wb3NlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwgMjUwKTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIEZvY3VzICYgYmx1ciBsb2dpYyAtLS0tLS0tLS0KICAgICAgICBkb20ub2JzZXJ2ZShmb2N1c0JsdXJFbGVtZW50LCAiZm9jdXMiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoYXQucGFyZW50LmZpcmUoImZvY3VzIikuZmlyZSgiZm9jdXM6Y29tcG9zZXIiKTsKCiAgICAgICAgICAgIC8vIERlbGF5IHN0b3Jpbmcgb2Ygc3RhdGUgdW50aWwgYWxsIGZvY3VzIGhhbmRsZXIgYXJlIGZpcmVkCiAgICAgICAgICAgIC8vIGVzcGVjaWFsbHkgdGhlIG9uZSB3aGljaCByZXNldHMgdGhlIHBsYWNlaG9sZGVyCiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgc3RhdGUgPSB0aGF0LmdldFZhbHVlKCk7CiAgICAgICAgICAgIH0sIDApOwogICAgICAgIH0pOwoKICAgICAgICBkb20ub2JzZXJ2ZShmb2N1c0JsdXJFbGVtZW50LCAiY2xpY2siLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoYXQucGFyZW50LmZpcmUoImNsaWNrOmNvbXBvc2VyIik7CiAgICAgICAgfSk7CgogICAgICAgIGRvbS5vYnNlcnZlKGZvY3VzQmx1ckVsZW1lbnQsICJibHVyIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICBpZiAoc3RhdGUgIT09IHRoYXQuZ2V0VmFsdWUoKSkgewogICAgICAgICAgICAgICAgdGhhdC5wYXJlbnQuZmlyZSgiY2hhbmdlIikuZmlyZSgiY2hhbmdlOmNvbXBvc2VyIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhhdC5wYXJlbnQuZmlyZSgiYmx1ciIpLmZpcmUoImJsdXI6Y29tcG9zZXIiKTsKICAgICAgICB9KTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIERyYWcgJiBEcm9wIGxvZ2ljIC0tLS0tLS0tLQogICAgICAgIGRvbS5vYnNlcnZlKGVsZW1lbnQsICJkcmFnZW50ZXIiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoYXQucGFyZW50LmZpcmUoInVuc2V0X3BsYWNlaG9sZGVyIik7CiAgICAgICAgfSk7CgogICAgICAgIGlmICh3eXNpaHRtbDUuYnJvd3Nlci5pc0lFKSB7CiAgICAgICAgICAgIGRvbS5vYnNlcnZlKGVsZW1lbnQsICJiZWZvcmVwYXN0ZSIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGlvbiA9IHRoYXQucGFyZW50LmNvbXBvc2VyLnNlbGVjdGlvbi5nZXRDdXJyZW50UmFuZ2UoKTsKICAgICAgICAgICAgICAgIHZhciB0ZW1wQ29udGFpbmVyID0gJCgiPGRpdiBjbGFzcz0nd3lzaWh0bWw1LXRlbXBDb250YWluZXInIGNvbnRlbnRlZGl0YWJsZT0ndHJ1ZSc+PC9kaXY+IilbMF07CiAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRlbXBDb250YWluZXIpOwogICAgICAgICAgICAgICAgJCh0ZW1wQ29udGFpbmVyKS5vbmUoInBhc3RlIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnQgPSAiIjsKICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGF0LmNvbmZpZy5wYXN0ZUFzUGxhaW5UZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gc2VsZi50ZXh0Q29udGVudDsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBzZWxmLmlubmVySFRNTDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gdGhhdC5wYXJlbnQucGFyc2UoY29udGVudCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQucGFyZW50LmZvY3VzKGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5wYXJlbnQuY29tcG9zZXIuc2VsZWN0aW9uLnNldFNlbGVjdGlvbihzZWxlY3Rpb24pOwogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmNvbW1hbmRzLmV4ZWMoImRlbGV0ZSIpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnBhcmVudC5jb21wb3Nlci5zZWxlY3Rpb24uaW5zZXJ0SFRNTChjb250ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgJChzZWxmKS5yZW1vdmUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnBhcmVudC5maXJlKCJwYXN0ZSIpLmZpcmUoInBhc3RlOmNvbXBvc2VyIiwgZXZlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICB9LCAwKTsKICAgICAgICAgICAgICAgICAgICB9LCAwKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgdGVtcENvbnRhaW5lci5mb2N1cygpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICQodGhhdC5wYXJlbnQuY29tcG9zZXIuZG9jLmRlZmF1bHRWaWV3KS5vbignZm9jdXMnLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0aW9uID0gdGhhdC5wYXJlbnQuY29tcG9zZXIuZG9jLmdldFNlbGVjdGlvbigpOwogICAgICAgICAgICAgICAgaWYgKCFzZWxlY3Rpb24gfHwgIXNlbGVjdGlvbi5mb2N1c05vZGUpIHsKICAgICAgICAgICAgICAgICAgICB0aGF0LnBhcmVudC5jb21wb3Nlci5mb2N1cyhmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoYXQucGFyZW50LnNhdmVkU2VsZWN0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQucGFyZW50LmNvbXBvc2VyLnNlbGVjdGlvbi5zZXRTZWxlY3Rpb24odGhhdC5wYXJlbnQuc2F2ZWRTZWxlY3Rpb24pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICBkb20ub2JzZXJ2ZShlbGVtZW50LCBwYXN0ZUV2ZW50cywgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgIGlmICh0aGF0LmNvbmZpZy5wYXN0ZUFzUGxhaW5UZXh0KSB7CiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgdmFyIGNvbnRlbnQgPSAiIjsKICAgICAgICAgICAgICAgIGlmIChldmVudCAmJiBldmVudC5jbGlwYm9hcmREYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IChldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50KS5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQvcGxhaW4nKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAod2luZG93LmNsaXBib2FyZERhdGEpIHsKICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gd2luZG93LmNsaXBib2FyZERhdGEuZ2V0RGF0YSgnVGV4dCcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGNvbnRlbnQpIHsKICAgICAgICAgICAgICAgICAgICB0aGF0LmNvbW1hbmRzLmV4ZWMuY2FsbCh0aGF0LmNvbW1hbmRzLCAiaW5zZXJ0VGV4dCIsIGNvbnRlbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIGh0bWwgPSAiIjsKICAgICAgICAgICAgICAgIGlmIChldmVudCAmJiBldmVudC5jbGlwYm9hcmREYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgaHRtbCA9IChldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50KS5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQvaHRtbCcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGh0bWwpIHsKICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgICAgIGlmICh0aGF0LnNlbGVjdGlvbi5nZXRUZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5jb21tYW5kcy5leGVjKCJkZWxldGUiKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8qIEV4dHJhY3QgYm9keSBjb250ZW50IGlmIGJvZHkgcHJlc2VudCwgdG8gcmVtb3ZlIHVud2FudGVkIGRhdGEqLwogICAgICAgICAgICAgICAgICAgIHZhciByZSA9IFhSZWdFeHAoIjxib2R5W14+XSo+XFxzKiguKilcXHMqPFwvYm9keT4iLCAiZ3MiKTsKICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gcmUuZXhlYyhodG1sKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQubGVuZ3RoID4gMSkgewogICAgICAgICAgICAgICAgICAgICAgICBodG1sID0gcmVzdWx0WzFdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBodG1sID0gdGhhdC5wYXJlbnQucGFyc2UoaHRtbCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgdGhhdC5wYXJlbnQuY29tcG9zZXIuc2VsZWN0aW9uLmluc2VydEhUTUwoaHRtbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB0aGF0LnBhcmVudC5maXJlKCJwYXN0ZSIpLmZpcmUoInBhc3RlOmNvbXBvc2VyIiwgZXZlbnQpOwogICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIG5ld29yZCBldmVudCAtLS0tLS0tLS0KICAgICAgICBkb20ub2JzZXJ2ZShlbGVtZW50LCAia2V5dXAiLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgdmFyIGtleUNvZGUgPSBldmVudC5rZXlDb2RlOwogICAgICAgICAgICBpZiAoa2V5Q29kZSA9PT0gd3lzaWh0bWw1LlNQQUNFX0tFWSB8fCBrZXlDb2RlID09PSB3eXNpaHRtbDUuRU5URVJfS0VZKSB7CiAgICAgICAgICAgICAgICB0aGF0LnBhcmVudC5maXJlKCJuZXd3b3JkOmNvbXBvc2VyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKCiAgICAgICAgdGhpcy5wYXJlbnQub24oInBhc3RlOmNvbXBvc2VyIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHRoYXQucGFyZW50LmZpcmUoIm5ld3dvcmQ6Y29tcG9zZXIiKTsKICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgfSk7CgogICAgICAgIC8vIC0tLS0tLS0tLSBNYWtlIHN1cmUgdGhhdCBpbWFnZXMgYXJlIHNlbGVjdGVkIHdoZW4gY2xpY2tpbmcgb24gdGhlbSAtLS0tLS0tLS0KICAgICAgICBpZiAoIWJyb3dzZXIuY2FuU2VsZWN0SW1hZ2VzSW5Db250ZW50RWRpdGFibGUoKSkgewogICAgICAgICAgICBkb20ub2JzZXJ2ZShlbGVtZW50LCAibW91c2Vkb3duIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0OwogICAgICAgICAgICAgICAgaWYgKHRhcmdldC5ub2RlTmFtZSA9PT0gIklNRyIpIHsKICAgICAgICAgICAgICAgICAgICB0aGF0LnNlbGVjdGlvbi5zZWxlY3ROb2RlKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoYnJvd3Nlci5oYXNIaXN0b3J5SXNzdWUoKSAmJiBicm93c2VyLnN1cHBvcnRzU2VsZWN0aW9uTW9kaWZ5KCkpIHsKICAgICAgICAgICAgZG9tLm9ic2VydmUoZWxlbWVudCwgImtleWRvd24iLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgIGlmICghZXZlbnQubWV0YUtleSAmJiAhZXZlbnQuY3RybEtleSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIga2V5Q29kZSA9IGV2ZW50LmtleUNvZGUsCiAgICAgICAgICAgICAgICAgICAgd2luID0gZWxlbWVudC5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3LAogICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbiA9IHdpbi5nZXRTZWxlY3Rpb24oKTsKCiAgICAgICAgICAgICAgICBpZiAoa2V5Q29kZSA9PT0gMzcgfHwga2V5Q29kZSA9PT0gMzkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoa2V5Q29kZSA9PT0gMzcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uLm1vZGlmeSgiZXh0ZW5kIiwgImxlZnQiLCAibGluZWJvdW5kYXJ5Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZXZlbnQuc2hpZnRLZXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbi5jb2xsYXBzZVRvU3RhcnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoa2V5Q29kZSA9PT0gMzkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uLm1vZGlmeSgiZXh0ZW5kIiwgInJpZ2h0IiwgImxpbmVib3VuZGFyeSIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWV2ZW50LnNoaWZ0S2V5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb24uY29sbGFwc2VUb0VuZCgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLy8gLS0tLS0tLS0tIFNob3J0Y3V0IGxvZ2ljIC0tLS0tLS0tLQogICAgICAgIGRvbS5vYnNlcnZlKGVsZW1lbnQsICJrZXlkb3duIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciBrZXlDb2RlID0gZXZlbnQua2V5Q29kZSwKICAgICAgICAgICAgICAgIGNvbW1hbmQgPSBzaG9ydGN1dHNba2V5Q29kZV07CiAgICAgICAgICAgIGlmICgoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5KSAmJiAhZXZlbnQuYWx0S2V5ICYmIGNvbW1hbmQpIHsKICAgICAgICAgICAgICAgIHRoYXQuY29tbWFuZHMuZXhlYyhjb21tYW5kKTsKICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKCiAgICAgICAgLyogSGFuZGluZyBUYWIga2V5IDogSW5zZXJ0IHRhYiBpbnRvIHRleHQgYW5kIHByZXZlbnQgbG9zaW5nIHRoZSBmb2N1cyBmcm9tIHRleHRhcmVhLiAqLwogICAgICAgIGRvbS5vYnNlcnZlKGVsZW1lbnQsICJrZXlkb3duIiwgZnVuY3Rpb24gKGV2ZW50KSB7CgogICAgICAgICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PSB3eXNpaHRtbDUuVEFCX0tFWSkgewogICAgICAgICAgICAgICAgdGhhdC5jb21tYW5kcy5leGVjLmNhbGwodGhhdC5jb21tYW5kcywgImluc2VydFRleHQiLCAnXHQnKTsKICAgICAgICAgICAgICAgIC8qIEZvciBoYW5kbGluZyBJRSAqLwogICAgICAgICAgICAgICAgaWYgKHd5c2lodG1sNS5icm93c2VyLmhhc0lmcmFtZUZvY3VzSXNzdWUoKSkgewogICAgICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSB0aGF0LnNlbGVjdGlvbiA/IHRoYXQuc2VsZWN0aW9uLmdldFNlbGVjdGVkTm9kZSgpIDogbnVsbDsKICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnQgPSB0YXJnZXQucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudCAmJiBwYXJlbnQuc3R5bGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5zdHlsZS53aGl0ZVNwYWNlID0gInByZSI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQuc2V0QXR0cmlidXRlKCJzdHlsZSIsICJ3aGl0ZS1zcGFjZTogcHJlIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIC8vIC0tLS0tLS0tLSBNYWtlIHN1cmUgdGhhdCB3aGVuIHByZXNzaW5nIGJhY2tzcGFjZS9kZWxldGUgb24gc2VsZWN0ZWQgaW1hZ2VzIGRlbGV0ZXMgdGhlIGltYWdlIGFuZCBpdCdzIGFuY2hvciAtLS0tLS0tLS0KICAgICAgICBkb20ub2JzZXJ2ZShlbGVtZW50LCAia2V5ZG93biIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICB2YXIgdGFyZ2V0ID0gdGhhdC5zZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKHRydWUpLAogICAgICAgICAgICAgICAga2V5Q29kZSA9IGV2ZW50LmtleUNvZGUsCiAgICAgICAgICAgICAgICBwYXJlbnQ7CiAgICAgICAgICAgIGlmICh0YXJnZXQgJiYgKGtleUNvZGUgPT09IHd5c2lodG1sNS5CQUNLU1BBQ0VfS0VZIHx8IGtleUNvZGUgPT09IHd5c2lodG1sNS5ERUxFVEVfS0VZKSkgey8vIDggPT4gYmFja3NwYWNlLCA0NiA9PiBkZWxldGUKICAgICAgICAgICAgICAgIHZhciBub2RlTmFtZXMgPSBbXTsKICAgICAgICAgICAgICAgIC8qIERlbGV0ZSBjb25maWd1cmVkIHRleHQgbm9kZXMgYXMgdGhleSBhcmUgbm90IGVkaXRhYmxlIGFuZCB3b24ndCBiZSBkZWxldGVkICovCiAgICAgICAgICAgICAgICBpZiAodGhhdC5jb25maWcucGFyc2VyUnVsZXMgJiYgdGhhdC5jb25maWcucGFyc2VyUnVsZXMudGV4dE5vZGVzKSB7CiAgICAgICAgICAgICAgICAgICAgbm9kZU5hbWVzID0gdGhhdC5jb25maWcucGFyc2VyUnVsZXMudGV4dE5vZGVzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbm9kZU5hbWVzLnB1c2goIklNRyIpOwogICAgICAgICAgICAgICAgaWYgKG5vZGVOYW1lcy5pbmRleE9mKHRhcmdldC5ub2RlTmFtZSkgPiAtMSkgewogICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IHRhcmdldC5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZCh0YXJnZXQpOwogICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQubm9kZU5hbWUgPT09ICJJTUciKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBpdCdzIHBhcmVudCA8YT4gdG9vIGlmIGl0IGhhc24ndCBnb3QgYW55IG90aGVyIGNoaWxkIG5vZGVzCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnQubm9kZU5hbWUgPT09ICJBIiAmJiAhcGFyZW50LmZpcnN0Q2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHBhcmVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3lzaWh0bWw1LnF1aXJrcy5yZWRyYXcoZWxlbWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0sIDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIC8vIC0tLS0tLS0tLSBJRSA4KzkgZm9jdXMgdGhlIGVkaXRvciB3aGVuIHRoZSBpZnJhbWUgaXMgY2xpY2tlZCAod2l0aG91dCBhY3R1YWxseSBmaXJpbmcgdGhlICdmb2N1cycgZXZlbnQgb24gdGhlIDxib2R5PikgLS0tLS0tLS0tCiAgICAgICAgaWYgKGJyb3dzZXIuaGFzSWZyYW1lRm9jdXNJc3N1ZSgpKSB7CiAgICAgICAgICAgIGRvbS5vYnNlcnZlKHRoaXMuY29udGFpbmVyLCAiZm9jdXMiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5kb2MucXVlcnlTZWxlY3RvcigiOmZvY3VzIikgIT09IHRoYXQuZWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmZvY3VzKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgZG9tLm9ic2VydmUodGhpcy5lbGVtZW50LCAiYmx1ciIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHRoYXQuc2VsZWN0aW9uLmdldFNlbGVjdGlvbigpLnJlbW92ZUFsbFJhbmdlcygpOwogICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLy8gLS0tLS0tLS0tIFNob3cgdXJsIGluIHRvb2x0aXAgd2hlbiBob3ZlcmluZyBsaW5rcyBvciBpbWFnZXMgLS0tLS0tLS0tCiAgICAgICAgdmFyIHRpdGxlUHJlZml4ZXMgPSB7CiAgICAgICAgICAgIElNRyA6ICJJbWFnZTogIiwKICAgICAgICAgICAgQSA6ICJMaW5rOiAiCiAgICAgICAgfTsKCiAgICAgICAgZG9tLm9ic2VydmUoZWxlbWVudCwgIm1vdXNlb3ZlciIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICB2YXIgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0LAogICAgICAgICAgICAgICAgbm9kZU5hbWUgPSB0YXJnZXQubm9kZU5hbWUsCiAgICAgICAgICAgICAgICB0aXRsZTsKICAgICAgICAgICAgaWYgKG5vZGVOYW1lICE9PSAiQSIgJiYgbm9kZU5hbWUgIT09ICJJTUciKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGhhc1RpdGxlID0gdGFyZ2V0Lmhhc0F0dHJpYnV0ZSgidGl0bGUiKTsKICAgICAgICAgICAgaWYgKCFoYXNUaXRsZSkgewogICAgICAgICAgICAgICAgdGl0bGUgPSB0aXRsZVByZWZpeGVzW25vZGVOYW1lXSArICh0YXJnZXQuZ2V0QXR0cmlidXRlKCJocmVmIikgfHwgdGFyZ2V0LmdldEF0dHJpYnV0ZSgic3JjIikpOwogICAgICAgICAgICAgICAgdGFyZ2V0LnNldEF0dHJpYnV0ZSgidGl0bGUiLCB0aXRsZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBDbGFzcyB0aGF0IHRha2VzIGNhcmUgdGhhdCB0aGUgdmFsdWUgb2YgdGhlIGNvbXBvc2VyIGFuZCB0aGUgdGV4dGFyZWEgaXMgYWx3YXlzIGluIHN5bmMKICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgSU5URVJWQUwgPSA0MDA7CgogICAgd3lzaWh0bWw1LnZpZXdzLlN5bmNocm9uaXplciA9IEJhc2UuZXh0ZW5kKAogICAgICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LnZpZXdzLlN5bmNocm9uaXplci5wcm90b3R5cGUgKi8gewoKICAgICAgICAgICAgY29uc3RydWN0b3IgOiBmdW5jdGlvbiAoZWRpdG9yLCB0ZXh0YXJlYSwgY29tcG9zZXIpIHsKICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yID0gZWRpdG9yOwogICAgICAgICAgICAgICAgdGhpcy50ZXh0YXJlYSA9IHRleHRhcmVhOwogICAgICAgICAgICAgICAgdGhpcy5jb21wb3NlciA9IGNvbXBvc2VyOwoKICAgICAgICAgICAgICAgIHRoaXMuX29ic2VydmUoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBTeW5jIGh0bWwgZnJvbSBjb21wb3NlciB0byB0ZXh0YXJlYQogICAgICAgICAgICAgKiBUYWtlcyBjYXJlIG9mIHBsYWNlaG9sZGVycwogICAgICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHNob3VsZFBhcnNlSHRtbCBXaGV0aGVyIHRoZSBodG1sIHNob3VsZCBiZSBzYW5pdGl6ZWQgYmVmb3JlIGluc2VydGluZyBpdCBpbnRvIHRoZSB0ZXh0YXJlYQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZnJvbUNvbXBvc2VyVG9UZXh0YXJlYSA6IGZ1bmN0aW9uIChzaG91bGRQYXJzZUh0bWwpIHsKICAgICAgICAgICAgICAgIHRoaXMudGV4dGFyZWEuc2V0VmFsdWUod3lzaWh0bWw1Lmxhbmcuc3RyaW5nKHRoaXMuY29tcG9zZXIuZ2V0VmFsdWUoKSkudHJpbSgpLCBzaG91bGRQYXJzZUh0bWwpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFN5bmMgdmFsdWUgb2YgdGV4dGFyZWEgdG8gY29tcG9zZXIKICAgICAgICAgICAgICogVGFrZXMgY2FyZSBvZiBwbGFjZWhvbGRlcnMKICAgICAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSBzaG91bGRQYXJzZUh0bWwgV2hldGhlciB0aGUgaHRtbCBzaG91bGQgYmUgc2FuaXRpemVkIGJlZm9yZSBpbnNlcnRpbmcgaXQgaW50byB0aGUgY29tcG9zZXIKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZyb21UZXh0YXJlYVRvQ29tcG9zZXIgOiBmdW5jdGlvbiAoc2hvdWxkUGFyc2VIdG1sKSB7CiAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFWYWx1ZSA9IHRoaXMudGV4dGFyZWEuZ2V0VmFsdWUoKTsKICAgICAgICAgICAgICAgIGlmICh0ZXh0YXJlYVZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wb3Nlci5zZXRWYWx1ZSh0ZXh0YXJlYVZhbHVlLCBzaG91bGRQYXJzZUh0bWwpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyLmNsZWFyKCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZGl0b3IuZmlyZSgic2V0X3BsYWNlaG9sZGVyIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogSW52b2tlIHN5bmNpbmcgYmFzZWQgb24gdmlldyBzdGF0ZQogICAgICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHNob3VsZFBhcnNlSHRtbCBXaGV0aGVyIHRoZSBodG1sIHNob3VsZCBiZSBzYW5pdGl6ZWQgYmVmb3JlIGluc2VydGluZyBpdCBpbnRvIHRoZSBjb21wb3Nlci90ZXh0YXJlYQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3luYyA6IGZ1bmN0aW9uIChzaG91bGRQYXJzZUh0bWwpIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmVkaXRvci5jdXJyZW50Vmlldy5uYW1lID09PSAidGV4dGFyZWEiKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mcm9tVGV4dGFyZWFUb0NvbXBvc2VyKHNob3VsZFBhcnNlSHRtbCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZnJvbUNvbXBvc2VyVG9UZXh0YXJlYShzaG91bGRQYXJzZUh0bWwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGludGVydmFsLWJhc2VkIHN5bmNpbmcKICAgICAgICAgICAgICogYWxzbyBtYWtlcyBzdXJlIHRoYXQgb24tc3VibWl0IHRoZSBjb21wb3NlcidzIGNvbnRlbnQgaXMgc3luY2VkIHdpdGggdGhlIHRleHRhcmVhCiAgICAgICAgICAgICAqIGltbWVkaWF0ZWx5IHdoZW4gdGhlIGZvcm0gZ2V0cyBzdWJtaXR0ZWQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIF9vYnNlcnZlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIGludGVydmFsLAogICAgICAgICAgICAgICAgICAgIHRoYXQgPSB0aGlzLAogICAgICAgICAgICAgICAgICAgIGZvcm0gPSB0aGlzLnRleHRhcmVhLmVsZW1lbnQuZm9ybSwKICAgICAgICAgICAgICAgICAgICBzdGFydEludGVydmFsID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZnJvbUNvbXBvc2VyVG9UZXh0YXJlYSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9LCBJTlRFUlZBTCk7CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBzdG9wSW50ZXJ2YWwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpOwogICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICBzdGFydEludGVydmFsKCk7CgogICAgICAgICAgICAgICAgaWYgKGZvcm0pIHsKICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdGV4dGFyZWEgaXMgaW4gYSBmb3JtIG1ha2Ugc3VyZSB0aGF0IGFmdGVyIG9ucmVzZXQgYW5kIG9uc3VibWl0IHRoZSBjb21wb3NlcgogICAgICAgICAgICAgICAgICAgIC8vIGhhcyB0aGUgY29ycmVjdCBzdGF0ZQogICAgICAgICAgICAgICAgICAgIHd5c2lodG1sNS5kb20ub2JzZXJ2ZShmb3JtLCAic3VibWl0IiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnN5bmModHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5vYnNlcnZlKGZvcm0sICJyZXNldCIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmZyb21UZXh0YXJlYVRvQ29tcG9zZXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5lZGl0b3Iub24oImNoYW5nZV92aWV3IiwgZnVuY3Rpb24gKHZpZXcpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodmlldyA9PT0gImNvbXBvc2VyIiAmJiAhaW50ZXJ2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5mcm9tVGV4dGFyZWFUb0NvbXBvc2VyKHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICBzdGFydEludGVydmFsKCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh2aWV3ID09PSAidGV4dGFyZWEiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZnJvbUNvbXBvc2VyVG9UZXh0YXJlYSh0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3RvcEludGVydmFsKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgdGhpcy5lZGl0b3Iub24oImRlc3Ryb3k6Y29tcG9zZXIiLCBzdG9wSW50ZXJ2YWwpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7Cnd5c2lodG1sNS52aWV3cy5UZXh0YXJlYSA9IHd5c2lodG1sNS52aWV3cy5WaWV3LmV4dGVuZCgKICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LnZpZXdzLlRleHRhcmVhLnByb3RvdHlwZSAqLyB7CiAgICAgICAgbmFtZSA6ICJ0ZXh0YXJlYSIsCgogICAgICAgIGNvbnN0cnVjdG9yIDogZnVuY3Rpb24gKHBhcmVudCwgdGV4dGFyZWFFbGVtZW50LCBjb25maWcpIHsKICAgICAgICAgICAgdGhpcy5iYXNlKHBhcmVudCwgdGV4dGFyZWFFbGVtZW50LCBjb25maWcpOwoKICAgICAgICAgICAgdGhpcy5fb2JzZXJ2ZSgpOwogICAgICAgIH0sCgogICAgICAgIGNsZWFyIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLmVsZW1lbnQudmFsdWUgPSAiIjsKICAgICAgICB9LAoKICAgICAgICBnZXRWYWx1ZSA6IGZ1bmN0aW9uIChwYXJzZSkgewogICAgICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLmlzRW1wdHkoKSA/ICIiIDogdGhpcy5lbGVtZW50LnZhbHVlOwogICAgICAgICAgICBpZiAocGFyc2UgJiYgdmFsdWUpIHsKICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5wYXJlbnQucGFyc2UodmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9LAoKICAgICAgICBzZXRWYWx1ZSA6IGZ1bmN0aW9uIChodG1sLCBwYXJzZSkgewogICAgICAgICAgICBpZiAocGFyc2UpIHsKICAgICAgICAgICAgICAgIGh0bWwgPSB0aGlzLnBhcmVudC5wYXJzZShodG1sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLmVsZW1lbnQudmFsdWUgPSBodG1sOwogICAgICAgIH0sCgogICAgICAgIGhhc1BsYWNlaG9sZGVyU2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgc3VwcG9ydHNQbGFjZWhvbGRlciA9IHd5c2lodG1sNS5icm93c2VyLnN1cHBvcnRzUGxhY2Vob2xkZXJBdHRyaWJ1dGVPbih0aGlzLmVsZW1lbnQpLAogICAgICAgICAgICAgICAgcGxhY2Vob2xkZXJUZXh0ID0gdGhpcy5lbGVtZW50LmdldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiKSB8fCBudWxsLAogICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmVsZW1lbnQudmFsdWUsCiAgICAgICAgICAgICAgICBpc0VtcHR5ID0gIXZhbHVlOwogICAgICAgICAgICByZXR1cm4gKHN1cHBvcnRzUGxhY2Vob2xkZXIgJiYgaXNFbXB0eSkgfHwgKHZhbHVlID09PSBwbGFjZWhvbGRlclRleHQpOwogICAgICAgIH0sCgogICAgICAgIGlzRW1wdHkgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAhdGhpcy5lbGVtZW50LnZhbHVlIHx8ICF3eXNpaHRtbDUubGFuZy5zdHJpbmcodGhpcy5lbGVtZW50LnZhbHVlKS50cmltKCkgfHwgdGhpcy5oYXNQbGFjZWhvbGRlclNldCgpOwogICAgICAgIH0sCgogICAgICAgIF9vYnNlcnZlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgZWxlbWVudCA9IHRoaXMuZWxlbWVudCwKICAgICAgICAgICAgICAgIHBhcmVudCA9IHRoaXMucGFyZW50LAogICAgICAgICAgICAgICAgZXZlbnRNYXBwaW5nID0gewogICAgICAgICAgICAgICAgICAgIGZvY3VzaW4gOiAiZm9jdXMiLAogICAgICAgICAgICAgICAgICAgIGZvY3Vzb3V0IDogImJsdXIiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAgICAgKiBDYWxsaW5nIGZvY3VzKCkgb3IgYmx1cigpIG9uIGFuIGVsZW1lbnQgZG9lc24ndCBzeW5jaHJvbm91c2x5IHRyaWdnZXIgdGhlIGF0dGFjaGVkIGZvY3VzL2JsdXIgZXZlbnRzCiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIHRoZSBjYXNlIGZvciBmb2N1c2luIGFuZCBmb2N1c291dCwgc28gbGV0J3MgdXNlIHRoZW0gd2hlbmV2ZXIgcG9zc2libGUsIGtrdGh4YmFpCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGV2ZW50cyA9IHd5c2lodG1sNS5icm93c2VyLnN1cHBvcnRzRXZlbnQoImZvY3VzaW4iKSA/IFsiZm9jdXNpbiIsICJmb2N1c291dCIsICJjaGFuZ2UiXSA6IFsiZm9jdXMiLCAiYmx1ciIsICJjaGFuZ2UiXTsKCiAgICAgICAgICAgIHBhcmVudC5vbigiYmVmb3JlbG9hZCIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS5kb20ub2JzZXJ2ZShlbGVtZW50LCBldmVudHMsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgIHZhciBldmVudE5hbWUgPSBldmVudE1hcHBpbmdbZXZlbnQudHlwZV0gfHwgZXZlbnQudHlwZTsKICAgICAgICAgICAgICAgICAgICBwYXJlbnQuZmlyZShldmVudE5hbWUpLmZpcmUoZXZlbnROYW1lICsgIjp0ZXh0YXJlYSIpOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5vYnNlcnZlKGVsZW1lbnQsIFsicGFzdGUiLCAiZHJvcCJdLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5maXJlKCJwYXN0ZSIpLmZpcmUoInBhc3RlOnRleHRhcmVhIik7CiAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfSk7Ci8qKgogKiBUb29sYmFyIERpYWxvZwogKgogKiBAcGFyYW0ge0VsZW1lbnR9IGxpbmsgVGhlIHRvb2xiYXIgbGluayB3aGljaCBjYXVzZXMgdGhlIGRpYWxvZyB0byBzaG93IHVwCiAqIEBwYXJhbSB7RWxlbWVudH0gY29udGFpbmVyIFRoZSBkaWFsb2cgY29udGFpbmVyCiAqCiAqIEBleGFtcGxlCiAqICAgIDwhLS0gVG9vbGJhciBsaW5rIC0tPgogKiAgICA8YSBkYXRhLXd5c2lodG1sNS1jb21tYW5kPSJpbnNlcnRJbWFnZSI+aW5zZXJ0IGFuIGltYWdlPC9hPgogKgogKiAgICA8IS0tIERpYWxvZyAtLT4KICogICAgPGRpdiBkYXRhLXd5c2lodG1sNS1kaWFsb2c9Imluc2VydEltYWdlIiBzdHlsZT0iZGlzcGxheTogbm9uZTsiPgogKiAgICAgIDxsYWJlbD4KICogICAgICAgIFVSTDogPGlucHV0IGRhdGEtd3lzaWh0bWw1LWRpYWxvZy1maWVsZD0ic3JjIiB2YWx1ZT0iaHR0cDovLyI+CiAqICAgICAgPC9sYWJlbD4KICogICAgICA8bGFiZWw+CiAqICAgICAgICBBbHRlcm5hdGl2ZSB0ZXh0OiA8aW5wdXQgZGF0YS13eXNpaHRtbDUtZGlhbG9nLWZpZWxkPSJhbHQiIHZhbHVlPSIiPgogKiAgICAgIDwvbGFiZWw+CiAqICAgIDwvZGl2PgogKgogKiAgICA8c2NyaXB0PgogKiAgICAgIHZhciBkaWFsb2cgPSBuZXcgd3lzaWh0bWw1LnRvb2xiYXIuRGlhbG9nKAogKiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiW2RhdGEtd3lzaWh0bWw1LWNvbW1hbmQ9J2luc2VydEltYWdlJ10iKSwKICogICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLXd5c2lodG1sNS1kaWFsb2c9J2luc2VydEltYWdlJ10iKQogKiAgICAgICk7CiAqICAgICAgZGlhbG9nLm9ic2VydmUoInNhdmUiLCBmdW5jdGlvbihhdHRyaWJ1dGVzKSB7CiAqICAgICAgICAvLyBkbyBzb21ldGhpbmcKICogICAgICB9KTsKICogICAgPC9zY3JpcHQ+CiAqLwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgdmFyIGRvbSA9IHd5c2lodG1sNS5kb20sCiAgICAgICAgQ0xBU1NfTkFNRV9PUEVORUQgPSAid3lzaWh0bWw1LWNvbW1hbmQtZGlhbG9nLW9wZW5lZCIsCiAgICAgICAgU0VMRUNUT1JfRk9STV9FTEVNRU5UUyA9ICJpbnB1dCwgc2VsZWN0LCB0ZXh0YXJlYSIsCiAgICAgICAgU0VMRUNUT1JfRklFTERTID0gIltkYXRhLXd5c2lodG1sNS1kaWFsb2ctZmllbGRdIiwKICAgICAgICBBVFRSSUJVVEVfRklFTERTID0gImRhdGEtd3lzaWh0bWw1LWRpYWxvZy1maWVsZCI7CgogICAgd3lzaWh0bWw1LnRvb2xiYXIuRGlhbG9nID0gd3lzaWh0bWw1LmxhbmcuRGlzcGF0Y2hlci5leHRlbmQoCiAgICAgICAgLyoqIEBzY29wZSB3eXNpaHRtbDUudG9vbGJhci5EaWFsb2cucHJvdG90eXBlICovIHsKICAgICAgICAgICAgY29uc3RydWN0b3IgOiBmdW5jdGlvbiAobGluaywgY29udGFpbmVyKSB7CiAgICAgICAgICAgICAgICB0aGlzLmxpbmsgPSBsaW5rOwogICAgICAgICAgICAgICAgdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfb2JzZXJ2ZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9vYnNlcnZlZCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsCiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tXcmFwcGVyID0gZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0gdGhhdC5fc2VyaWFsaXplKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzID09IHRoYXQuZWxlbWVudFRvQ2hhbmdlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmZpcmUoImVkaXQiLCBhdHRyaWJ1dGVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZmlyZSgic2F2ZSIsIGF0dHJpYnV0ZXMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuaGlkZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIGRvbS5vYnNlcnZlKHRoYXQubGluaywgImNsaWNrIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIGlmIChkb20uaGFzQ2xhc3ModGhhdC5saW5rLCBDTEFTU19OQU1FX09QRU5FRCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmhpZGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgZG9tLm9ic2VydmUodGhpcy5jb250YWluZXIsICJrZXlkb3duIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGtleUNvZGUgPSBldmVudC5rZXlDb2RlOwogICAgICAgICAgICAgICAgICAgIGlmIChrZXlDb2RlID09PSB3eXNpaHRtbDUuRU5URVJfS0VZKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrV3JhcHBlcihldmVudCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChrZXlDb2RlID09PSB3eXNpaHRtbDUuRVNDQVBFX0tFWSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmhpZGUoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICBkb20uZGVsZWdhdGUodGhpcy5jb250YWluZXIsICJbZGF0YS13eXNpaHRtbDUtZGlhbG9nLWFjdGlvbj1zYXZlXSIsICJjbGljayIsIGNhbGxiYWNrV3JhcHBlcik7CgogICAgICAgICAgICAgICAgZG9tLmRlbGVnYXRlKHRoaXMuY29udGFpbmVyLCAiW2RhdGEtd3lzaWh0bWw1LWRpYWxvZy1hY3Rpb249Y2FuY2VsXSIsICJjbGljayIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgIHRoYXQuZmlyZSgiY2FuY2VsIik7CiAgICAgICAgICAgICAgICAgICAgdGhhdC5oaWRlKCk7CiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIHZhciBmb3JtRWxlbWVudHMgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFNFTEVDVE9SX0ZPUk1fRUxFTUVOVFMpLAogICAgICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IGZvcm1FbGVtZW50cy5sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgX2NsZWFySW50ZXJ2YWwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhhdC5pbnRlcnZhbCk7CiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIGZvciAoOwogICAgICAgICAgICAgICAgICAgIGkgPCBsZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgZG9tLm9ic2VydmUoZm9ybUVsZW1lbnRzW2ldLCAiY2hhbmdlIiwgX2NsZWFySW50ZXJ2YWwpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRoaXMuX29ic2VydmVkID0gdHJ1ZTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBHcmFicyBhbGwgZmllbGRzIGluIHRoZSBkaWFsb2cgYW5kIHB1dHMgdGhlbSBpbiBrZXk9PnZhbHVlIHN0eWxlIGluIGFuIG9iamVjdCB3aGljaAogICAgICAgICAgICAgKiB0aGVuIGdldHMgcmV0dXJuZWQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIF9zZXJpYWxpemUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuZWxlbWVudFRvQ2hhbmdlIHx8IHt9LAogICAgICAgICAgICAgICAgICAgIGZpZWxkcyA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoU0VMRUNUT1JfRklFTERTKSwKICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSBmaWVsZHMubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgIGkgPSAwOwogICAgICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgICAgICBkYXRhW2ZpZWxkc1tpXS5nZXRBdHRyaWJ1dGUoQVRUUklCVVRFX0ZJRUxEUyldID0gZmllbGRzW2ldLnZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGRhdGE7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogVGFrZXMgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlICJlbGVtZW50VG9DaGFuZ2UiCiAgICAgICAgICAgICAqIGFuZCBpbnNlcnRzIHRoZW0gaW4gdGhlaXIgY29ycmVzcG9uZGluZyBkaWFsb2cgaW5wdXQgZmllbGRzCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEFzc3VtZSB0aGUgImVsZW1lbnRUb0NoYW5nZSIgbG9va3MgbGlrZSB0aGlzOgogICAgICAgICAgICAgKiAgICA8YSBocmVmPSJodHRwOi8vd3d3Lmdvb2dsZS5jb20iIHRhcmdldD0iX2JsYW5rIj5mb288L2E+CiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIGFuZCB3ZSBoYXZlIHRoZSBmb2xsb3dpbmcgZGlhbG9nOgogICAgICAgICAgICAgKiAgICA8aW5wdXQgdHlwZT0idGV4dCIgZGF0YS13eXNpaHRtbDUtZGlhbG9nLWZpZWxkPSJocmVmIiB2YWx1ZT0iIj4KICAgICAgICAgICAgICogICAgPGlucHV0IHR5cGU9InRleHQiIGRhdGEtd3lzaWh0bWw1LWRpYWxvZy1maWVsZD0idGFyZ2V0IiB2YWx1ZT0iIj4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogYWZ0ZXIgY2FsbGluZyBfaW50ZXJwb2xhdGUoKSB0aGUgZGlhbG9nIHdpbGwgbG9vayBsaWtlIHRoaXMKICAgICAgICAgICAgICogICAgPGlucHV0IHR5cGU9InRleHQiIGRhdGEtd3lzaWh0bWw1LWRpYWxvZy1maWVsZD0iaHJlZiIgdmFsdWU9Imh0dHA6Ly93d3cuZ29vZ2xlLmNvbSI+CiAgICAgICAgICAgICAqICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBkYXRhLXd5c2lodG1sNS1kaWFsb2ctZmllbGQ9InRhcmdldCIgdmFsdWU9Il9ibGFuayI+CiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEJhc2ljYWxseSBpdCBhZG9wdGVkIHRoZSBhdHRyaWJ1dGUgdmFsdWVzIGludG8gdGhlIGNvcnJlc3BvbmRpbmcgaW5wdXQgZmllbGRzCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBfaW50ZXJwb2xhdGUgOiBmdW5jdGlvbiAoYXZvaWRIaWRkZW5GaWVsZHMpIHsKICAgICAgICAgICAgICAgIHZhciBmaWVsZCwKICAgICAgICAgICAgICAgICAgICBmaWVsZE5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgZm9jdXNlZEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCI6Zm9jdXMiKSwKICAgICAgICAgICAgICAgICAgICBmaWVsZHMgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFNFTEVDVE9SX0ZJRUxEUyksCiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID0gZmllbGRzLmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICBpID0gMDsKICAgICAgICAgICAgICAgIGZvciAoOwogICAgICAgICAgICAgICAgICAgIGkgPCBsZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgZmllbGQgPSBmaWVsZHNbaV07CgogICAgICAgICAgICAgICAgICAgIC8vIE5ldmVyIGNoYW5nZSBlbGVtZW50cyB3aGVyZSB0aGUgdXNlciBpcyBjdXJyZW50bHkgdHlwaW5nIGluCiAgICAgICAgICAgICAgICAgICAgaWYgKGZpZWxkID09PSBmb2N1c2VkRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIERvbid0IHVwZGF0ZSBoaWRkZW4gZmllbGRzCiAgICAgICAgICAgICAgICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS94aW5nL3d5c2lodG1sNS9wdWxsLzE0CiAgICAgICAgICAgICAgICAgICAgaWYgKGF2b2lkSGlkZGVuRmllbGRzICYmIGZpZWxkLnR5cGUgPT09ICJoaWRkZW4iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgZmllbGROYW1lID0gZmllbGQuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9GSUVMRFMpOwogICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlID0gdGhpcy5lbGVtZW50VG9DaGFuZ2UgPyAodGhpcy5lbGVtZW50VG9DaGFuZ2VbZmllbGROYW1lXSB8fCAiIikgOiBmaWVsZC5kZWZhdWx0VmFsdWU7CiAgICAgICAgICAgICAgICAgICAgZmllbGQudmFsdWUgPSBuZXdWYWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBTaG93IHRoZSBkaWFsb2cgZWxlbWVudAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2hvdyA6IGZ1bmN0aW9uIChlbGVtZW50VG9DaGFuZ2UpIHsKICAgICAgICAgICAgICAgIGlmIChkb20uaGFzQ2xhc3ModGhpcy5saW5rLCBDTEFTU19OQU1FX09QRU5FRCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzLAogICAgICAgICAgICAgICAgICAgIGZpcnN0RmllbGQgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKFNFTEVDVE9SX0ZPUk1fRUxFTUVOVFMpOwogICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50VG9DaGFuZ2UgPSBlbGVtZW50VG9DaGFuZ2U7CiAgICAgICAgICAgICAgICB0aGlzLl9vYnNlcnZlKCk7CiAgICAgICAgICAgICAgICB0aGlzLl9pbnRlcnBvbGF0ZSgpOwogICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRUb0NoYW5nZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX2ludGVycG9sYXRlKHRydWUpOwogICAgICAgICAgICAgICAgICAgIH0sIDUwMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkb20uYWRkQ2xhc3ModGhpcy5saW5rLCBDTEFTU19OQU1FX09QRU5FRCk7CiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gIiI7CiAgICAgICAgICAgICAgICB0aGlzLmZpcmUoInNob3ciKTsKICAgICAgICAgICAgICAgIGlmIChmaXJzdEZpZWxkICYmICFlbGVtZW50VG9DaGFuZ2UpIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICBmaXJzdEZpZWxkLmZvY3VzKCk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBIaWRlIHRoZSBkaWFsb2cgZWxlbWVudAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaGlkZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5pbnRlcnZhbCk7CiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnRUb0NoYW5nZSA9IG51bGw7CiAgICAgICAgICAgICAgICBkb20ucmVtb3ZlQ2xhc3ModGhpcy5saW5rLCBDTEFTU19OQU1FX09QRU5FRCk7CiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgICAgICAgICAgdGhpcy5maXJlKCJoaWRlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKfSkod3lzaWh0bWw1KTsKLyoqCiAqIENvbnZlcnRzIHNwZWVjaC10by10ZXh0IGFuZCBpbnNlcnRzIHRoaXMgaW50byB0aGUgZWRpdG9yCiAqIEFzIG9mIG5vdyAoMjAxMS8wMy8yNSkgdGhpcyBvbmx5IGlzIHN1cHBvcnRlZCBpbiBDaHJvbWUgPj0gMTEKICoKICogTm90ZSB0aGF0IGl0IHNlbmRzIHRoZSByZWNvcmRlZCBhdWRpbyB0byB0aGUgZ29vZ2xlIHNwZWVjaCByZWNvZ25pdGlvbiBhcGk6CiAqIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDM2MTgyNi9kb2VzLWNocm9tZS1oYXZlLWJ1aWwtaW4tc3BlZWNoLXJlY29nbml0aW9uLWZvci1pbnB1dC10eXBlLXRleHQteC13ZWJraXQtc3BlZWMKICoKICogQ3VycmVudCBIVE1MNSBkcmFmdCBjYW4gYmUgZm91bmQgaGVyZQogKiBodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy9wdWJsaWMteGctaHRtbHNwZWVjaC8yMDExRmViL2F0dC0wMDIwL2FwaS1kcmFmdC5odG1sCiAqCiAqICJBY2Nlc3NpbmcgR29vZ2xlIFNwZWVjaCBBUEkgQ2hyb21lIDExIgogKiBodHRwOi8vbWlrZXB1bHR6LmNvbS8yMDExLzAzL2FjY2Vzc2luZy1nb29nbGUtc3BlZWNoLWFwaS1jaHJvbWUtMTEvCiAqLwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgdmFyIGRvbSA9IHd5c2lodG1sNS5kb207CgogICAgdmFyIGxpbmtTdHlsZXMgPSB7CiAgICAgICAgcG9zaXRpb24gOiAicmVsYXRpdmUiCiAgICB9OwoKICAgIHZhciB3cmFwcGVyU3R5bGVzID0gewogICAgICAgIGxlZnQgOiAwLAogICAgICAgIG1hcmdpbiA6IDAsCiAgICAgICAgb3BhY2l0eSA6IDAsCiAgICAgICAgb3ZlcmZsb3cgOiAiaGlkZGVuIiwKICAgICAgICBwYWRkaW5nIDogMCwKICAgICAgICBwb3NpdGlvbiA6ICJhYnNvbHV0ZSIsCiAgICAgICAgdG9wIDogMCwKICAgICAgICB6SW5kZXggOiAxCiAgICB9OwoKICAgIHZhciBpbnB1dFN0eWxlcyA9IHsKICAgICAgICBjdXJzb3IgOiAiaW5oZXJpdCIsCiAgICAgICAgZm9udFNpemUgOiAiNTBweCIsCiAgICAgICAgaGVpZ2h0IDogIjUwcHgiLAogICAgICAgIG1hcmdpblRvcCA6ICItMjVweCIsCiAgICAgICAgb3V0bGluZSA6IDAsCiAgICAgICAgcGFkZGluZyA6IDAsCiAgICAgICAgcG9zaXRpb24gOiAiYWJzb2x1dGUiLAogICAgICAgIHJpZ2h0IDogIi00cHgiLAogICAgICAgIHRvcCA6ICI1MCUiCiAgICB9OwoKICAgIHZhciBpbnB1dEF0dHJpYnV0ZXMgPSB7CiAgICAgICAgIngtd2Via2l0LXNwZWVjaCIgOiAiIiwKICAgICAgICAic3BlZWNoIiA6ICIiCiAgICB9OwoKICAgIHd5c2lodG1sNS50b29sYmFyLlNwZWVjaCA9IGZ1bmN0aW9uIChwYXJlbnQsIGxpbmspIHsKICAgICAgICB2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJpbnB1dCIpOwogICAgICAgIGlmICghd3lzaWh0bWw1LmJyb3dzZXIuc3VwcG9ydHNTcGVlY2hBcGlPbihpbnB1dCkpIHsKICAgICAgICAgICAgbGluay5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIHZhciBsYW5nID0gcGFyZW50LmVkaXRvci50ZXh0YXJlYS5lbGVtZW50LmdldEF0dHJpYnV0ZSgibGFuZyIpOwogICAgICAgIGlmIChsYW5nKSB7CiAgICAgICAgICAgIGlucHV0QXR0cmlidXRlcy5sYW5nID0gbGFuZzsKICAgICAgICB9CgogICAgICAgIHZhciB3cmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CgogICAgICAgIHd5c2lodG1sNS5sYW5nLm9iamVjdCh3cmFwcGVyU3R5bGVzKS5tZXJnZSh7CiAgICAgICAgICAgIHdpZHRoIDogbGluay5vZmZzZXRXaWR0aCArICJweCIsCiAgICAgICAgICAgIGhlaWdodCA6IGxpbmsub2Zmc2V0SGVpZ2h0ICsgInB4IgogICAgICAgIH0pOwoKICAgICAgICBkb20uaW5zZXJ0KGlucHV0KS5pbnRvKHdyYXBwZXIpOwogICAgICAgIGRvbS5pbnNlcnQod3JhcHBlcikuaW50byhsaW5rKTsKCiAgICAgICAgZG9tLnNldFN0eWxlcyhpbnB1dFN0eWxlcykub24oaW5wdXQpOwogICAgICAgIGRvbS5zZXRBdHRyaWJ1dGVzKGlucHV0QXR0cmlidXRlcykub24oaW5wdXQpOwoKICAgICAgICBkb20uc2V0U3R5bGVzKHdyYXBwZXJTdHlsZXMpLm9uKHdyYXBwZXIpOwogICAgICAgIGRvbS5zZXRTdHlsZXMobGlua1N0eWxlcykub24obGluayk7CgogICAgICAgIHZhciBldmVudE5hbWUgPSAib253ZWJraXRzcGVlY2hjaGFuZ2UiIGluIGlucHV0ID8gIndlYmtpdHNwZWVjaGNoYW5nZSIgOiAic3BlZWNoY2hhbmdlIjsKICAgICAgICBkb20ub2JzZXJ2ZShpbnB1dCwgZXZlbnROYW1lLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHBhcmVudC5leGVjQ29tbWFuZCgiaW5zZXJ0VGV4dCIsIGlucHV0LnZhbHVlKTsKICAgICAgICAgICAgaW5wdXQudmFsdWUgPSAiIjsKICAgICAgICB9KTsKCiAgICAgICAgZG9tLm9ic2VydmUoaW5wdXQsICJjbGljayIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICBpZiAoZG9tLmhhc0NsYXNzKGxpbmssICJ3eXNpaHRtbDUtY29tbWFuZC1kaXNhYmxlZCIpKSB7CiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgICB9KTsKICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBUb29sYmFyCiAqCiAqIEBwYXJhbSB7T2JqZWN0fSBwYXJlbnQgUmVmZXJlbmNlIHRvIGluc3RhbmNlIG9mIEVkaXRvciBpbnN0YW5jZQogKiBAcGFyYW0ge0VsZW1lbnR9IGNvbnRhaW5lciBSZWZlcmVuY2UgdG8gdGhlIHRvb2xiYXIgY29udGFpbmVyIGVsZW1lbnQKICoKICogQGV4YW1wbGUKICogICAgPGRpdiBpZD0idG9vbGJhciI+CiAqICAgICAgPGEgZGF0YS13eXNpaHRtbDUtY29tbWFuZD0iY3JlYXRlTGluayI+aW5zZXJ0IGxpbms8L2E+CiAqICAgICAgPGEgZGF0YS13eXNpaHRtbDUtY29tbWFuZD0iZm9ybWF0QmxvY2siIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQtdmFsdWU9ImgxIj5pbnNlcnQgaDE8L2E+CiAqICAgIDwvZGl2PgogKgogKiAgICA8c2NyaXB0PgogKiAgICAgIHZhciB0b29sYmFyID0gbmV3IHd5c2lodG1sNS50b29sYmFyLlRvb2xiYXIoZWRpdG9yLCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgidG9vbGJhciIpKTsKICogICAgPC9zY3JpcHQ+CiAqLwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgdmFyIENMQVNTX05BTUVfQ09NTUFORF9ESVNBQkxFRCA9ICJ3eXNpaHRtbDUtY29tbWFuZC1kaXNhYmxlZCIsCiAgICAgICAgQ0xBU1NfTkFNRV9DT01NQU5EU19ESVNBQkxFRCA9ICJ3eXNpaHRtbDUtY29tbWFuZHMtZGlzYWJsZWQiLAogICAgICAgIENMQVNTX05BTUVfQ09NTUFORF9BQ1RJVkUgPSAid3lzaWh0bWw1LWNvbW1hbmQtYWN0aXZlIiwKICAgICAgICBDTEFTU19OQU1FX0FDVElPTl9BQ1RJVkUgPSAid3lzaWh0bWw1LWFjdGlvbi1hY3RpdmUiLAogICAgICAgIGRvbSA9IHd5c2lodG1sNS5kb207CgogICAgd3lzaWh0bWw1LnRvb2xiYXIuVG9vbGJhciA9IEJhc2UuZXh0ZW5kKAogICAgICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LnRvb2xiYXIuVG9vbGJhci5wcm90b3R5cGUgKi8gewogICAgICAgICAgICBjb25zdHJ1Y3RvciA6IGZ1bmN0aW9uIChlZGl0b3IsIGNvbnRhaW5lcikgewogICAgICAgICAgICAgICAgdGhpcy5lZGl0b3IgPSBlZGl0b3I7CiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHR5cGVvZihjb250YWluZXIpID09PSAic3RyaW5nIiA/IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGNvbnRhaW5lcikgOiBjb250YWluZXI7CiAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyID0gZWRpdG9yLmNvbXBvc2VyOwoKICAgICAgICAgICAgICAgIGlmICghdGhpcy5jb250YWluZXIuY2xhc3NMaXN0LmNvbnRhaW5zKCJ3eXNpaHRtbDUtdG9vbGJhciIpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZ2V0TGlua3MoImNvbW1hbmQiKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9nZXRMaW5rcygiYWN0aW9uIik7CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX29ic2VydmUoKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3coKTsKCiAgICAgICAgICAgICAgICAgICAgdmFyIHNwZWVjaElucHV0TGlua3MgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCJbZGF0YS13eXNpaHRtbDUtY29tbWFuZD1pbnNlcnRTcGVlY2hdIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IHNwZWVjaElucHV0TGlua3MubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICBpID0gMDsKICAgICAgICAgICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyB3eXNpaHRtbDUudG9vbGJhci5TcGVlY2godGhpcywgc3BlZWNoSW5wdXRMaW5rc1tpXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5jb250YWluZXIuY2xhc3NMaXN0LmFkZCgid3lzaWh0bWw1LXRvb2xiYXIiKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9nZXRMaW5rcyA6IGZ1bmN0aW9uICh0eXBlKSB7CiAgICAgICAgICAgICAgICB2YXIgbGlua3MgPSB0aGlzW3R5cGUgKyAiTGlua3MiXSA9IHd5c2lodG1sNS5sYW5nLmFycmF5KHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoIltkYXRhLXd5c2lodG1sNS0iICsgdHlwZSArICJdIikpLmdldCgpLAogICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IGxpbmtzLmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICBpID0gMCwKICAgICAgICAgICAgICAgICAgICBtYXBwaW5nID0gdGhpc1t0eXBlICsgIk1hcHBpbmciXSA9IHt9LAogICAgICAgICAgICAgICAgICAgIGxpbmssCiAgICAgICAgICAgICAgICAgICAgZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgbmFtZSwKICAgICAgICAgICAgICAgICAgICB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICBkaWFsb2c7CiAgICAgICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgICAgIGxpbmsgPSBsaW5rc1tpXTsKICAgICAgICAgICAgICAgICAgICBuYW1lID0gbGluay5nZXRBdHRyaWJ1dGUoImRhdGEtd3lzaWh0bWw1LSIgKyB0eXBlKTsKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxpbmsuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS0iICsgdHlwZSArICItdmFsdWUiKTsKICAgICAgICAgICAgICAgICAgICBmdW5jID0gbGluay5nZXRBdHRyaWJ1dGUoImRhdGEtd3lzaWh0bWw1LSIgKyB0eXBlICsgIi1zdGF0ZUNhbGxiYWNrRm4iKTsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50TmFtZSA9IGxpbmsuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS0iICsgdHlwZSArICItZWxlbWVudCIpOwogICAgICAgICAgICAgICAgICAgIGlzRGVmYXVsdCA9IGxpbmsuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS0iICsgdHlwZSArICItZGVmYXVsdCIpOwogICAgICAgICAgICAgICAgICAgIGdyb3VwID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvcigiW2RhdGEtd3lzaWh0bWw1LSIgKyB0eXBlICsgIi1ncm91cD0nIiArIG5hbWUgKyAiJ10iKTsKICAgICAgICAgICAgICAgICAgICBkaWFsb2cgPSB0aGlzLl9nZXREaWFsb2cobGluaywgbmFtZSk7CgogICAgICAgICAgICAgICAgICAgIG1hcHBpbmdbbmFtZSArICI6IiArIHZhbHVlXSA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgbGluayA6IGxpbmssCiAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwIDogZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgOiBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICBmdW5jIDogZnVuYywKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudE5hbWUgOiBlbGVtZW50TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgaXNEZWZhdWx0IDogaXNEZWZhdWx0ID09ICIiID8gdHJ1ZSA6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA6IHZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICBkaWFsb2cgOiBkaWFsb2csCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlIDogZmFsc2UKICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgX2dldERpYWxvZyA6IGZ1bmN0aW9uIChsaW5rLCBjb21tYW5kKSB7CiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsCiAgICAgICAgICAgICAgICAgICAgZGlhbG9nRWxlbWVudCA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoIltkYXRhLXd5c2lodG1sNS1kaWFsb2c9JyIgKyBjb21tYW5kICsgIiddIiksCiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLAogICAgICAgICAgICAgICAgICAgIGNhcmV0Qm9va21hcms7CgogICAgICAgICAgICAgICAgaWYgKGRpYWxvZ0VsZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICBkaWFsb2cgPSBuZXcgd3lzaWh0bWw1LnRvb2xiYXIuRGlhbG9nKGxpbmssIGRpYWxvZ0VsZW1lbnQpOwoKICAgICAgICAgICAgICAgICAgICBkaWFsb2cub24oInNob3ciLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhcmV0Qm9va21hcmsgPSB0aGF0LmNvbXBvc2VyLnNlbGVjdGlvbi5nZXRCb29rbWFyaygpOwoKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5lZGl0b3IuZmlyZSgic2hvdzpkaWFsb2ciLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kIDogY29tbWFuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWxvZ0NvbnRhaW5lciA6IGRpYWxvZ0VsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kTGluayA6IGxpbmsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgIGRpYWxvZy5vbigic2F2ZSIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNhcmV0Qm9va21hcmspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuY29tcG9zZXIuc2VsZWN0aW9uLnNldEJvb2ttYXJrKGNhcmV0Qm9va21hcmspOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX2V4ZWNDb21tYW5kKGNvbW1hbmQsIGF0dHJpYnV0ZXMpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmVkaXRvci5maXJlKCJzYXZlOmRpYWxvZyIsIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgOiBjb21tYW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nQ29udGFpbmVyIDogZGlhbG9nRWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmRMaW5rIDogbGluawogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLm9uKCJzYXZlT25seSIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNhcmV0Qm9va21hcmspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuY29tcG9zZXIuc2VsZWN0aW9uLnNldEJvb2ttYXJrKGNhcmV0Qm9va21hcmspOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgIGRpYWxvZy5vbigiY2FuY2VsIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmVkaXRvci5mb2N1cyhmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZWRpdG9yLmZpcmUoImNhbmNlbDpkaWFsb2ciLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kIDogY29tbWFuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWxvZ0NvbnRhaW5lciA6IGRpYWxvZ0VsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kTGluayA6IGxpbmsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZGlhbG9nOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHZhciB0b29sYmFyID0gbmV3IHd5c2lodG1sNS5Ub29sYmFyKCk7CiAgICAgICAgICAgICAqICAgIC8vIEluc2VydCBhIDxibG9ja3F1b3RlPiBlbGVtZW50IG9yIHdyYXAgY3VycmVudCBzZWxlY3Rpb24gaW4gPGJsb2NrcXVvdGU+CiAgICAgICAgICAgICAqICAgIHRvb2xiYXIuZXhlY0NvbW1hbmQoImZvcm1hdEJsb2NrIiwgImJsb2NrcXVvdGUiKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGV4ZWNDb21tYW5kIDogZnVuY3Rpb24gKGNvbW1hbmQsIGNvbW1hbmRWYWx1ZSkgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuY29tbWFuZHNEaXNhYmxlZCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgY29tbWFuZE9iaiA9IHRoaXMuY29tbWFuZE1hcHBpbmdbY29tbWFuZCArICI6IiArIGNvbW1hbmRWYWx1ZV07CgogICAgICAgICAgICAgICAgLy8gU2hvdyBkaWFsb2cgd2hlbiBhdmFpbGFibGUKICAgICAgICAgICAgICAgIGlmIChjb21tYW5kT2JqICYmIGNvbW1hbmRPYmouZGlhbG9nICYmICFjb21tYW5kT2JqLnN0YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgY29tbWFuZE9iai5kaWFsb2cuc2hvdygpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9leGVjQ29tbWFuZChjb21tYW5kLCBjb21tYW5kVmFsdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgX2V4ZWNDb21tYW5kIDogZnVuY3Rpb24gKGNvbW1hbmQsIGNvbW1hbmRWYWx1ZSkgewoKICAgICAgICAgICAgICAgIHRoaXMuY29tcG9zZXIuY29tbWFuZHMuZXhlYyhjb21tYW5kLCBjb21tYW5kVmFsdWUpOwogICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlTGlua1N0YXRlcygpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZXhlY0FjdGlvbiA6IGZ1bmN0aW9uIChhY3Rpb24pIHsKICAgICAgICAgICAgICAgIHZhciBlZGl0b3IgPSB0aGlzLmVkaXRvcjsKICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gPT09ICJjaGFuZ2VfdmlldyIpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZWRpdG9yLmN1cnJlbnRWaWV3ID09PSBlZGl0b3IudGV4dGFyZWEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZWRpdG9yLmZpcmUoImNoYW5nZV92aWV3IiwgImNvbXBvc2VyIik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgZWRpdG9yLmZpcmUoImNoYW5nZV92aWV3IiwgInRleHRhcmVhIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgX29ic2VydmUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsCiAgICAgICAgICAgICAgICAgICAgZWRpdG9yID0gdGhpcy5lZGl0b3IsCiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyID0gdGhpcy5jb250YWluZXIsCiAgICAgICAgICAgICAgICAgICAgbGlua3MgPSB0aGlzLmNvbW1hbmRMaW5rcy5jb25jYXQodGhpcy5hY3Rpb25MaW5rcyksCiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID0gbGlua3MubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgIGkgPSAwOwoKICAgICAgICAgICAgICAgIGZvciAoOwogICAgICAgICAgICAgICAgICAgIGkgPCBsZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gJ2phdmFzY3JpcHQ6OycgYW5kIHVuc2VsZWN0YWJsZT1vbiBOZWVkZWQgZm9yIElFLCBidXQgZG9uZSBpbiBhbGwgYnJvd3NlcnMgdG8gbWFrZSBzdXJlIHRoYXQgYWxsIGdldCB0aGUgc2FtZSBjc3MgYXBwbGllZAogICAgICAgICAgICAgICAgICAgIC8vICh5b3Uga25vdywgYTpsaW5rIHsuLi4gfSBkb2Vzbid0IG1hdGNoIGFuY2hvcnMgd2l0aCBtaXNzaW5nIGhyZWYgYXR0cmlidXRlKQogICAgICAgICAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0ge307CiAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5ocmVmID0gImphdmFzY3JpcHQ6OyI7CiAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmtzW2ldICYmICFsaW5rc1tpXS5oYXNBdHRyaWJ1dGUoInVuc2VsZWN0YWJsZSIpICYmIGxpbmtzW2ldLnRhZ05hbWUudG9Mb3dlckNhc2UoKSAhPSAiaW5wdXQiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMudW5zZWxlY3RhYmxlID0gIm9uIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZG9tLnNldEF0dHJpYnV0ZXMoYXR0cmlidXRlcykub24obGlua3NbaV0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIE5lZWRlZCBmb3Igb3BlcmEgYW5kIGNocm9tZQogICAgICAgICAgICAgICAgZG9tLmRlbGVnYXRlKGNvbnRhaW5lciwgIltkYXRhLXd5c2lodG1sNS1hY3Rpb25dIiwgIm1vdXNlZG93biIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICBkb20uZGVsZWdhdGUoY29udGFpbmVyLCAiW2RhdGEtd3lzaWh0bWw1LWNvbW1hbmRdIiwgIm1vdXNlZG93biIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgIHZhciBsaW5rID0gdGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZCA9IGxpbmsuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS1jb21tYW5kIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmRWYWx1ZSA9IGxpbmsuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS1jb21tYW5kLXZhbHVlIik7CgogICAgICAgICAgICAgICAgICAgIC8vVG8gYWxsb3cgZGVmYXVsdCBhY3Rpb24gaW4gY2FzZSBvZiBtYXJnaW4gZmllbGRzLgogICAgICAgICAgICAgICAgICAgIGlmICghbGluay5oYXNBdHRyaWJ1dGUoImRhdGEtd3lzaWh0bWw1LXNraXAiKSkgewogICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIGRvbS5kZWxlZ2F0ZShjb250YWluZXIsICJbZGF0YS13eXNpaHRtbDUtY29tbWFuZF0iLCAiY2xpY2siLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbGluayA9IHRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSBsaW5rLmdldEF0dHJpYnV0ZSgiZGF0YS13eXNpaHRtbDUtY29tbWFuZCIpLAogICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kVmFsdWUgPSBsaW5rLmdldEF0dHJpYnV0ZSgiZGF0YS13eXNpaHRtbDUtY29tbWFuZC12YWx1ZSIpLAogICAgICAgICAgICAgICAgICAgICAgICBmb3JtID0gbGluay5mb3JtOwogICAgICAgICAgICAgICAgICAgIGlmIChjb21tYW5kVmFsdWUgPT09IG51bGwgJiYgZm9ybSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kVmFsdWUgPSB7fTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvcm1JbnB1dHMgPSBmb3JtLnF1ZXJ5U2VsZWN0b3JBbGwoImlucHV0W25hbWVdLCB0ZXh0YXJlYVtuYW1lXSIpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZvcm1JbnB1dHMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gZm9ybUlucHV0c1tpXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IGVsZW1lbnQudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC50eXBlID09PSAiY2hlY2tib3giKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBlbGVtZW50LmNoZWNrZWQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kVmFsdWVbZWxlbWVudC5uYW1lXSA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoIWxpbmsuaGFzQXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS1za2lwIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5leGVjQ29tbWFuZChjb21tYW5kLCBjb21tYW5kVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIGRvbS5kZWxlZ2F0ZShjb250YWluZXIsICJzZWxlY3RbZGF0YS13eXNpaHRtbDUtY29tbWFuZF0iLCAiY2hhbmdlIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGxpbmsgPSB0aGlzLAogICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kID0gbGluay5nZXRBdHRyaWJ1dGUoImRhdGEtd3lzaWh0bWw1LWNvbW1hbmQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZFZhbHVlID0gbGluay52YWx1ZTsKICAgICAgICAgICAgICAgICAgICB0aGF0LmV4ZWNDb21tYW5kKGNvbW1hbmQsIGNvbW1hbmRWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIGRvbS5kZWxlZ2F0ZShjb250YWluZXIsICJpbnB1dFtkYXRhLXd5c2lodG1sNS1jb21tYW5kXSIsICJjaGFuZ2UiLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbGluayA9IHRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSBsaW5rLmdldEF0dHJpYnV0ZSgiZGF0YS13eXNpaHRtbDUtY29tbWFuZCIpLAogICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kVmFsdWUgPSBsaW5rLnR5cGUgPT09ICJjaGVja2JveCIgPyBsaW5rLmNoZWNrZWQgOiBsaW5rLnZhbHVlOwogICAgICAgICAgICAgICAgICAgIHRoYXQuZXhlY0NvbW1hbmQoY29tbWFuZCwgY29tbWFuZFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgZG9tLmRlbGVnYXRlKGNvbnRhaW5lciwgIltkYXRhLXd5c2lodG1sNS1hY3Rpb25dIiwgImNsaWNrIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGFjdGlvbiA9IHRoaXMuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS1hY3Rpb24iKTsKICAgICAgICAgICAgICAgICAgICB0aGF0LmV4ZWNBY3Rpb24oYWN0aW9uKTsKICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgZWRpdG9yLm9uKCJmb2N1czpjb21wb3NlciIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB0aGF0LmJvb2ttYXJrID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKHRoYXQuaW50ZXJ2YWwpOwogICAgICAgICAgICAgICAgICAgIHRoYXQuaW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX3VwZGF0ZUxpbmtTdGF0ZXMoKTsKICAgICAgICAgICAgICAgICAgICB9LCA1MDApOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgZWRpdG9yLm9uKCJibHVyOmNvbXBvc2VyIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhhdC5pbnRlcnZhbCk7CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICBlZGl0b3Iub24oImRlc3Ryb3k6Y29tcG9zZXIiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGF0LmludGVydmFsKTsKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIGVkaXRvci5vbigiY2hhbmdlX3ZpZXciLCBmdW5jdGlvbiAoY3VycmVudFZpZXcpIHsKICAgICAgICAgICAgICAgICAgICAvLyBTZXQgdGltZW91dCBuZWVkZWQgaW4gb3JkZXIgdG8gbGV0IHRoZSBibHVyIGV2ZW50IGZpcmUgZmlyc3QKICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5jb21tYW5kc0Rpc2FibGVkID0gKGN1cnJlbnRWaWV3ICE9PSAiY29tcG9zZXIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fdXBkYXRlTGlua1N0YXRlcygpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5jb21tYW5kc0Rpc2FibGVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb20uYWRkQ2xhc3MoY29udGFpbmVyLCBDTEFTU19OQU1FX0NPTU1BTkRTX0RJU0FCTEVEKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5yZW1vdmVDbGFzcyhjb250YWluZXIsIENMQVNTX05BTUVfQ09NTUFORFNfRElTQUJMRUQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF91cGRhdGVMaW5rU3RhdGVzIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIGNvbW1hbmRNYXBwaW5nID0gdGhpcy5jb21tYW5kTWFwcGluZywKICAgICAgICAgICAgICAgICAgICBhY3Rpb25NYXBwaW5nID0gdGhpcy5hY3Rpb25NYXBwaW5nLAogICAgICAgICAgICAgICAgICAgIGksCiAgICAgICAgICAgICAgICAgICAgc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgYWN0aW9uLAogICAgICAgICAgICAgICAgICAgIGNvbW1hbmQ7CiAgICAgICAgICAgICAgICAvLyBldmVyeSBtaWxsaXNlY29uZCBjb3VudHMuLi4gdGhpcyBpcyBleGVjdXRlZCBxdWl0ZSBvZnRlbgoKICAgICAgICAgICAgICAgIGZvciAoaSBpbiBjb21tYW5kTWFwcGluZykgewogICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSBjb21tYW5kTWFwcGluZ1tpXTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29tbWFuZHNEaXNhYmxlZCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZnVuYyA9IHd5c2lodG1sNS51dGlsLmdldE9iamVjdFByb3BlcnR5KHdpbmRvdywgY29tbWFuZC5mdW5jKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZ1bmMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gdGhpcy5jb21wb3Nlci5jb21tYW5kcy5jYWxsYmFja1N0YXRlKGNvbW1hbmQubmFtZSwgY29tbWFuZC52YWx1ZSwgY29tbWFuZC5pc0RlZmF1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHd5c2lodG1sNS5sYW5nLm9iamVjdChzdGF0ZSkuaXNBcnJheSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR3JhYiBmaXJzdCBhbmQgb25seSBvYmplY3QvZWxlbWVudCBpbiBzdGF0ZSBhcnJheSwgb3RoZXJ3aXNlIGNvbnZlcnQgc3RhdGUgaW50byBib29sZWFuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG8gYXZvaWQgc2hvd2luZyBhIGRpYWxvZyBmb3IgbXVsdGlwbGUgc2VsZWN0ZWQgZWxlbWVudHMgd2hpY2ggbWF5IGhhdmUgZGlmZmVyZW50IGF0dHJpYnV0ZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlZy4gd2hlbiB0d28gbGlua3Mgd2l0aCBkaWZmZXJlbnQgaHJlZiBhcmUgc2VsZWN0ZWQsIHRoZSBzdGF0ZSB3aWxsIGJlIGFuIGFycmF5IGNvbnNpc3Rpbmcgb2YgYm90aCBsaW5rIGVsZW1lbnRzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IHRoZSBkaWFsb2cgaW50ZXJmYWNlIGNhbiBvbmx5IHVwZGF0ZSBvbmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IHN0YXRlLmxlbmd0aCA9PT0gMSA/IHN0YXRlWzBdIDogdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5yZW1vdmVDbGFzcyhjb21tYW5kLmxpbmssIENMQVNTX05BTUVfQ09NTUFORF9ESVNBQkxFRCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWFuZC5ncm91cCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5yZW1vdmVDbGFzcyhjb21tYW5kLmdyb3VwLCBDTEFTU19OQU1FX0NPTU1BTkRfRElTQUJMRUQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuYyhjb21tYW5kLmxpbmssIHN0YXRlLCBjb21tYW5kLmVsZW1lbnROYW1lLCBjb21tYW5kLm5hbWUsIGNvbW1hbmQudmFsdWUsIGNvbW1hbmQuaXNEZWZhdWx0KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmb3IgKGkgaW4gYWN0aW9uTWFwcGluZykgewogICAgICAgICAgICAgICAgICAgIGFjdGlvbiA9IGFjdGlvbk1hcHBpbmdbaV07CiAgICAgICAgICAgICAgICAgICAgaWYgKGFjdGlvbi5uYW1lID09PSAiY2hhbmdlX3ZpZXciKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbi5zdGF0ZSA9IHRoaXMuZWRpdG9yLmN1cnJlbnRWaWV3ID09PSB0aGlzLmVkaXRvci50ZXh0YXJlYTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFjdGlvbi5zdGF0ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tLmFkZENsYXNzKGFjdGlvbi5saW5rLCBDTEFTU19OQU1FX0FDVElPTl9BQ1RJVkUpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tLnJlbW92ZUNsYXNzKGFjdGlvbi5saW5rLCBDTEFTU19OQU1FX0FDVElPTl9BQ1RJVkUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2hvdyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAiIjsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGhpZGUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBXWVNJSFRNTDUgRWRpdG9yCiAqCiAqIEBwYXJhbSB7RWxlbWVudH0gdGV4dGFyZWFFbGVtZW50IFJlZmVyZW5jZSB0byB0aGUgdGV4dGFyZWEgd2hpY2ggc2hvdWxkIGJlIHR1cm5lZCBpbnRvIGEgcmljaCB0ZXh0IGludGVyZmFjZQogKiBAcGFyYW0ge09iamVjdH0gW2NvbmZpZ10gU2VlIGRlZmF1bHRDb25maWcgb2JqZWN0IGJlbG93IGZvciBleHBsYW5hdGlvbiBvZiBlYWNoIGluZGl2aWR1YWwgY29uZmlnIG9wdGlvbgogKgogKiBAZXZlbnRzCiAqICAgIGxvYWQKICogICAgYmVmb3JlbG9hZCAoZm9yIGludGVybmFsIHVzZSBvbmx5KQogKiAgICBmb2N1cwogKiAgICBmb2N1czpjb21wb3NlcgogKiAgICBjbGljazpjb21wb3NlcgogKiAgICBmb2N1czp0ZXh0YXJlYQogKiAgICBibHVyCiAqICAgIGJsdXI6Y29tcG9zZXIKICogICAgYmx1cjp0ZXh0YXJlYQogKiAgICBjaGFuZ2UKICogICAgY2hhbmdlOmNvbXBvc2VyCiAqICAgIGNoYW5nZTp0ZXh0YXJlYQogKiAgICBwYXN0ZQogKiAgICBwYXN0ZTpjb21wb3NlcgogKiAgICBwYXN0ZTp0ZXh0YXJlYQogKiAgICBuZXd3b3JkOmNvbXBvc2VyCiAqICAgIGRlc3Ryb3k6Y29tcG9zZXIKICogICAgdW5kbzpjb21wb3NlcgogKiAgICByZWRvOmNvbXBvc2VyCiAqICAgIGJlZm9yZWNvbW1hbmQ6Y29tcG9zZXIKICogICAgYWZ0ZXJjb21tYW5kOmNvbXBvc2VyCiAqICAgIGVuYWJsZTpjb21wb3NlcgogKiAgICBkaXNhYmxlOmNvbXBvc2VyCiAqICAgIGNoYW5nZV92aWV3CiAqLwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgdmFyIHVuZGVmOwoKICAgIHZhciBkZWZhdWx0Q29uZmlnID0gewogICAgICAgIC8vIEdpdmUgdGhlIGVkaXRvciBhIG5hbWUsIHRoZSBuYW1lIHdpbGwgYWxzbyBiZSBzZXQgYXMgY2xhc3MgbmFtZSBvbiB0aGUgaWZyYW1lIGFuZCBvbiB0aGUgaWZyYW1lJ3MgYm9keQogICAgICAgIG5hbWUgOiB1bmRlZiwKICAgICAgICAvLyBXaGV0aGVyIHRoZSBlZGl0b3Igc2hvdWxkIGxvb2sgbGlrZSB0aGUgdGV4dGFyZWEgKGJ5IGFkb3B0aW5nIHN0eWxlcykKICAgICAgICBzdHlsZSA6IHRydWUsCiAgICAgICAgLy8gSWQgb2YgdGhlIHRvb2xiYXIgZWxlbWVudCwgcGFzcyBmYWxzZXkgdmFsdWUgaWYgeW91IGRvbid0IHdhbnQgYW55IHRvb2xiYXIgbG9naWMKICAgICAgICB0b29sYmFyIDogdW5kZWYsCiAgICAgICAgLy8gV2hldGhlciB1cmxzLCBlbnRlcmVkIGJ5IHRoZSB1c2VyIHNob3VsZCBhdXRvbWF0aWNhbGx5IGJlY29tZSBjbGlja2FibGUtbGlua3MKICAgICAgICBhdXRvTGluayA6IHRydWUsCiAgICAgICAgLy8gT2JqZWN0IHdoaWNoIGluY2x1ZGVzIHBhcnNlciBydWxlcyB0byBhcHBseSB3aGVuIGh0bWwgZ2V0cyBpbnNlcnRlZCB2aWEgY29weSAmIHBhc3RlCiAgICAgICAgLy8gU2VlIHBhcnNlcl9ydWxlcy8qLmpzIGZvciBleGFtcGxlcwogICAgICAgIHBhcnNlclJ1bGVzIDoge3RhZ3MgOiB7YnIgOiB7fSwgc3BhbiA6IHt9LCBkaXYgOiB7fSwgcCA6IHt9fSwgY2xhc3NlcyA6IHt9fSwKICAgICAgICAvLyBQYXJzZXIgbWV0aG9kIHRvIHVzZSB3aGVuIHRoZSB1c2VyIGluc2VydHMgY29udGVudCB2aWEgY29weSAmIHBhc3RlCiAgICAgICAgcGFyc2VyIDogd3lzaWh0bWw1LmRvbS5wYXJzZSwKICAgICAgICAvLyBDbGFzcyBuYW1lIHdoaWNoIHNob3VsZCBiZSBzZXQgb24gdGhlIGNvbnRlbnRFZGl0YWJsZSBlbGVtZW50IGluIHRoZSBjcmVhdGVkIHNhbmRib3ggaWZyYW1lLCBjYW4gYmUgc3R5bGVkIHZpYSB0aGUgJ3N0eWxlc2hlZXRzJyBvcHRpb24KICAgICAgICBjb21wb3NlckNsYXNzTmFtZSA6ICJ3eXNpaHRtbDUtZWRpdG9yIiwKICAgICAgICAvLyBDbGFzcyBuYW1lIHRvIGFkZCB0byB0aGUgYm9keSB3aGVuIHRoZSB3eXNpaHRtbDUgZWRpdG9yIGlzIHN1cHBvcnRlZAogICAgICAgIGJvZHlDbGFzc05hbWUgOiAid3lzaWh0bWw1LXN1cHBvcnRlZCIsCiAgICAgICAgLy8gQnkgZGVmYXVsdCB3eXNpaHRtbDUgd2lsbCBpbnNlcnQgYSA8YnI+IGZvciBsaW5lIGJyZWFrcywgc2V0IHRoaXMgdG8gZmFsc2UgdG8gdXNlIDxwPgogICAgICAgIHVzZUxpbmVCcmVha3MgOiB0cnVlLAogICAgICAgIHBhc3RlQXNQbGFpblRleHQgOiBmYWxzZSwKICAgICAgICAvLyBBcnJheSAob3Igc2luZ2xlIHN0cmluZykgb2Ygc3R5bGVzaGVldCB1cmxzIHRvIGJlIGxvYWRlZCBpbiB0aGUgZWRpdG9yJ3MgaWZyYW1lCiAgICAgICAgc3R5bGVzaGVldHMgOiBbXSwKICAgICAgICAvLyBQbGFjZWhvbGRlciB0ZXh0IHRvIHVzZSwgZGVmYXVsdHMgdG8gdGhlIHBsYWNlaG9sZGVyIGF0dHJpYnV0ZSBvbiB0aGUgdGV4dGFyZWEgZWxlbWVudAogICAgICAgIHBsYWNlaG9sZGVyVGV4dCA6IHVuZGVmLAogICAgICAgIC8vIFdoZXRoZXIgdGhlIHJpY2ggdGV4dCBlZGl0b3Igc2hvdWxkIGJlIHJlbmRlcmVkIG9uIHRvdWNoIGRldmljZXMgKHd5c2lodG1sNSA+PSAwLjMuMCBjb21lcyB3aXRoIGJhc2ljIHN1cHBvcnQgZm9yIGlPUyA1KQogICAgICAgIHN1cHBvcnRUb3VjaERldmljZXMgOiB0cnVlCiAgICB9OwoKICAgIHd5c2lodG1sNS5FZGl0b3IgPSB3eXNpaHRtbDUubGFuZy5EaXNwYXRjaGVyLmV4dGVuZCgKICAgICAgICAvKiogQHNjb3BlIHd5c2lodG1sNS5FZGl0b3IucHJvdG90eXBlICovIHsKICAgICAgICAgICAgY29uc3RydWN0b3IgOiBmdW5jdGlvbiAodGV4dGFyZWFFbGVtZW50LCBjb25maWcpIHsKICAgICAgICAgICAgICAgIHRoaXMudGV4dGFyZWFFbGVtZW50ID0gdHlwZW9mKHRleHRhcmVhRWxlbWVudCkgPT09ICJzdHJpbmciID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGV4dGFyZWFFbGVtZW50KSA6IHRleHRhcmVhRWxlbWVudDsKICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnID0gd3lzaWh0bWw1Lmxhbmcub2JqZWN0KHt9KS5tZXJnZShkZWZhdWx0Q29uZmlnKS5tZXJnZShjb25maWcpLmdldCgpOwogICAgICAgICAgICAgICAgdGhpcy50ZXh0YXJlYSA9IG5ldyB3eXNpaHRtbDUudmlld3MuVGV4dGFyZWEodGhpcywgdGhpcy50ZXh0YXJlYUVsZW1lbnQsIHRoaXMuY29uZmlnKTsKICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFZpZXcgPSB0aGlzLnRleHRhcmVhOwogICAgICAgICAgICAgICAgdGhpcy5faXNDb21wYXRpYmxlID0gd3lzaWh0bWw1LmJyb3dzZXIuc3VwcG9ydGVkKCk7CgogICAgICAgICAgICAgICAgLy8gU29ydCBvdXQgdW5zdXBwb3J0ZWQvdW53YW50ZWQgYnJvd3NlcnMgaGVyZQogICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9pc0NvbXBhdGlibGUgfHwgKCF0aGlzLmNvbmZpZy5zdXBwb3J0VG91Y2hEZXZpY2VzICYmIHd5c2lodG1sNS5icm93c2VyLmlzVG91Y2hEZXZpY2UoKSkpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZmlyZSgiYmVmb3JlbG9hZCIpLmZpcmUoImxvYWQiKTsKICAgICAgICAgICAgICAgICAgICB9LCAwKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gQWRkIGNsYXNzIG5hbWUgdG8gYm9keSwgdG8gaW5kaWNhdGUgdGhhdCB0aGUgZWRpdG9yIGlzIHN1cHBvcnRlZAogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5hZGRDbGFzcyhkb2N1bWVudC5ib2R5LCB0aGlzLmNvbmZpZy5ib2R5Q2xhc3NOYW1lKTsKCiAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyID0gbmV3IHd5c2lodG1sNS52aWV3cy5Db21wb3Nlcih0aGlzLCB0aGlzLnRleHRhcmVhRWxlbWVudCwgdGhpcy5jb25maWcpOwogICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50VmlldyA9IHRoaXMuY29tcG9zZXI7CgogICAgICAgICAgICAgICAgaWYgKHR5cGVvZih0aGlzLmNvbmZpZy5wYXJzZXIpID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5pdFBhcnNlcigpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5wYXJzZXJSdWxlcykgewogICAgICAgICAgICAgICAgICAgIHRoaXMucGFyc2VyUnVsZXMgPSB0aGlzLmNvbmZpZy5wYXJzZXJSdWxlczsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLm9uKCJiZWZvcmVsb2FkIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc3luY2hyb25pemVyID0gbmV3IHd5c2lodG1sNS52aWV3cy5TeW5jaHJvbml6ZXIodGhpcywgdGhpcy50ZXh0YXJlYSwgdGhpcy5jb21wb3Nlcik7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLnRvb2xiYXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b29sYmFyID0gbmV3IHd5c2lodG1sNS50b29sYmFyLlRvb2xiYXIodGhpcywgdGhpcy5jb25maWcudG9vbGJhcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyLl9jcmVhdGUoKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coIkhleWEhIFRoaXMgcGFnZSBpcyB1c2luZyB3eXNpaHRtbDUgZm9yIHJpY2ggdGV4dCBlZGl0aW5nLiBDaGVjayBvdXQgaHR0cHM6Ly9naXRodWIuY29tL3hpbmcvd3lzaWh0bWw1Iik7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBzZXRUb29sYmFyIDogZnVuY3Rpb24gKHRvb2xiYXIpIHsKICAgICAgICAgICAgICAgIHRoaXMudG9vbGJhciA9IG5ldyB3eXNpaHRtbDUudG9vbGJhci5Ub29sYmFyKHRoaXMsIHRvb2xiYXIpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgaXNDb21wYXRpYmxlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2lzQ29tcGF0aWJsZTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGNsZWFyIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50Vmlldy5jbGVhcigpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRWYWx1ZSA6IGZ1bmN0aW9uIChwYXJzZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFZpZXcuZ2V0VmFsdWUocGFyc2UpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2V0VmFsdWUgOiBmdW5jdGlvbiAoaHRtbCwgcGFyc2UpIHsKICAgICAgICAgICAgICAgIHRoaXMuZmlyZSgidW5zZXRfcGxhY2Vob2xkZXIiKTsKCiAgICAgICAgICAgICAgICBpZiAoIWh0bWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGVhcigpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFZpZXcuc2V0VmFsdWUoaHRtbCwgcGFyc2UpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBmb2N1cyA6IGZ1bmN0aW9uIChzZXRUb0VuZCkgewogICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50Vmlldy5mb2N1cyhzZXRUb0VuZCk7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBEZWFjdGl2YXRlIGVkaXRvciAobWFrZSBpdCByZWFkb25seSkKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGRpc2FibGUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRWaWV3LmRpc2FibGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEFjdGl2YXRlIGVkaXRvcgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZW5hYmxlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50Vmlldy5lbmFibGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgaXNFbXB0eSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRWaWV3LmlzRW1wdHkoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGhhc1BsYWNlaG9sZGVyU2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFZpZXcuaGFzUGxhY2Vob2xkZXJTZXQoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHBhcnNlIDogZnVuY3Rpb24gKGh0bWxPckVsZW1lbnQsIHByZVByb2Nlc3MpIHsKICAgICAgICAgICAgICAgIHZhciByZXR1cm5WYWx1ZSA9IHRoaXMuY29uZmlnLnBhcnNlcihodG1sT3JFbGVtZW50LCB0aGlzLmNvbmZpZy5wYXJzZXJSdWxlcywgdGhpcy5jb21wb3Nlci5zYW5kYm94LmdldERvY3VtZW50KCksIHRydWUsIHByZVByb2Nlc3MpOwogICAgICAgICAgICAgICAgaWYgKHR5cGVvZihodG1sT3JFbGVtZW50KSA9PT0gIm9iamVjdCIpIHsKICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUucXVpcmtzLnJlZHJhdyhodG1sT3JFbGVtZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBQcmVwYXJlIGh0bWwgcGFyc2VyIGxvZ2ljCiAgICAgICAgICAgICAqICAtIE9ic2VydmVzIGZvciBwYXN0ZSBhbmQgZHJvcAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgX2luaXRQYXJzZXIgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLm9uKCJwYXN0ZTpjb21wb3NlciIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIga2VlcFNjcm9sbFBvc2l0aW9uID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgdGhhdC5jb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUucXVpcmtzLmNsZWFuUGFzdGVkSFRNTCh0aGF0LmNvbXBvc2VyLmVsZW1lbnQpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnBhcnNlKHRoYXQuY29tcG9zZXIuZWxlbWVudCk7CiAgICAgICAgICAgICAgICAgICAgfSwga2VlcFNjcm9sbFBvc2l0aW9uKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7CgovKioKICogVGhlc2UgcnVsZXMgZGVmaW5lIHdoaWNoIHRhZ3MgYW5kIGNzcyBjbGFzc2VzIGFyZSBzdXBwb3J0ZWQgYW5kIHdoaWNoIHRhZ3Mgc2hvdWxkIGJlIHNwZWNpYWxseSB0cmVhdGVkLgogKgogKiBFeGFtcGxlcyBiYXNlZCBvbiB0aGlzIHJ1bGUgc2V0OgogKgogKiAgICA8YSBocmVmPSJodHRwOi8vZm9vYmFyLmNvbSI+Zm9vPC9hPgogKiAgICAuLi4gYmVjb21lcyAuLi4KICogICAgPGEgaHJlZj0iaHR0cDovL2Zvb2Jhci5jb20iIHRhcmdldD0iX2JsYW5rIiByZWw9Im5vZm9sbG93Ij5mb288L2E+CiAqCiAqICAgIDxpbWcgYWxpZ249ImxlZnQiIHNyYz0iaHR0cDovL2Zvb2Jhci5jb20vaW1hZ2UucG5nIj4KICogICAgLi4uIGJlY29tZXMgLi4uCiAqICAgIDxpbWcgY2xhc3M9Ind5c2l3eWctZmxvYXQtbGVmdCIgc3JjPSJodHRwOi8vZm9vYmFyLmNvbS9pbWFnZS5wbmciIGFsdD0iIj4KICoKICogICAgPGRpdj5mb288c2NyaXB0PmFsZXJ0KGRvY3VtZW50LmNvb2tpZSk8L3NjcmlwdD48L2Rpdj4KICogICAgLi4uIGJlY29tZXMgLi4uCiAqICAgIDxkaXY+Zm9vPC9kaXY+CiAqCiAqICAgIDxtYXJxdWVlPmZvbzwvbWFycXVlZT4KICogICAgLi4uIGJlY29tZXMgLi4uCiAqICAgIDxzcGFuPmZvbzwvbWFycXVlZT4KICoKICogICAgZm9vIDxiciBjbGVhcj0iYm90aCI+IGJhcgogKiAgICAuLi4gYmVjb21lcyAuLi4KICogICAgZm9vIDxiciBjbGFzcz0id3lzaXd5Zy1jbGVhci1ib3RoIj4gYmFyCiAqCiAqICAgIDxkaXY+aGVsbG8gPGlmcmFtZSBzcmM9Imh0dHA6Ly9nb29nbGUuY29tIj48L2lmcmFtZT48L2Rpdj4KICogICAgLi4uIGJlY29tZXMgLi4uCiAqICAgIDxkaXY+aGVsbG8gPC9kaXY+CiAqCiAqICAgIDxjZW50ZXI+aGVsbG88L2NlbnRlcj4KICogICAgLi4uIGJlY29tZXMgLi4uCiAqICAgIDxkaXYgY2xhc3M9Ind5c2l3eWctdGV4dC1hbGlnbi1jZW50ZXIiPmhlbGxvPC9kaXY+CiAqLwp2YXIgd3lzaWh0bWw1U3VwcG9ydGVkUGFyc2VyUnVsZXMgPSB7CiAgICAvKioKICAgICAqIENTUyBDbGFzcyB3aGl0ZS1saXN0CiAgICAgKiBGb2xsb3dpbmcgY3NzIGNsYXNzZXMgd29uJ3QgYmUgcmVtb3ZlZCB3aGVuIHBhcnNlZCBieSB0aGUgd3lzaWh0bWw1IGh0bWwgcGFyc2VyCiAgICAgKi8KICAgICJjbGFzc2VzIiA6IHsKICAgICAgICAidGV4dEVkaXRvci1jdXN0b21EYXRhQXR0ciIgOiAxCiAgICB9LAogICAgLyoqCiAgICAgKiBUYWcgbGlzdAogICAgICoKICAgICAqIEZvbGxvd2luZyBvcHRpb25zIGFyZSBhdmFpbGFibGU6CiAgICAgKgogICAgICogICAgLSBhZGRfY2xhc3M6ICAgICAgICBjb252ZXJ0cyBhbmQgZGVsZXRlcyB0aGUgZ2l2ZW4gSFRNTDQgYXR0cmlidXRlIChhbGlnbiwgY2xlYXIsIC4uLikgdmlhIHRoZSBnaXZlbiBtZXRob2QgdG8gYSBjc3MgY2xhc3MKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgVGhlIGZvbGxvd2luZyBtZXRob2RzIGFyZSBpbXBsZW1lbnRlZCBpbiB3eXNpaHRtbDUuZG9tLnBhcnNlOgogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIC0gYWxpZ25fdGV4dDogIGNvbnZlcnRzIGFsaWduIGF0dHJpYnV0ZSB2YWx1ZXMgKHJpZ2h0L2xlZnQvY2VudGVyL2p1c3RpZnkpIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgY3NzIGNsYXNzICJ3eXNpd3lnLXRleHQtYWxpZ24tKiIpCiAgICAgPHAgYWxpZ249ImNlbnRlciI+Zm9vPC9wPiAuLi4gYmVjb21lcyAuLi4gPHA+IGNsYXNzPSJ3eXNpd3lnLXRleHQtYWxpZ24tY2VudGVyIj5mb288L3A+CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgLSBjbGVhcl9icjogICAgY29udmVydHMgY2xlYXIgYXR0cmlidXRlIHZhbHVlcyBsZWZ0L3JpZ2h0L2FsbC9ib3RoIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgY3NzIGNsYXNzICJ3eXNpd3lnLWNsZWFyLSoiCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnIgY2xlYXI9ImFsbCI+IC4uLiBiZWNvbWVzIC4uLiA8YnIgY2xhc3M9Ind5c2l3eWctY2xlYXItYm90aCI+CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgLSBhbGlnbl9pbWc6ICAgIGNvbnZlcnRzIGFsaWduIGF0dHJpYnV0ZSB2YWx1ZXMgKHJpZ2h0L2xlZnQpIG9uIDxpbWc+IHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgY3NzIGNsYXNzICJ3eXNpd3lnLWZsb2F0LSoiCiAgICAgKgogICAgICogICAgLSByZW1vdmU6ICAgICAgICAgICAgIHJlbW92ZXMgdGhlIGVsZW1lbnQgYW5kIGl0J3MgY29udGVudAogICAgICoKICAgICAqICAgIC0gcmVuYW1lX3RhZzogICAgICAgICByZW5hbWVzIHRoZSBlbGVtZW50IHRvIHRoZSBnaXZlbiB0YWcKICAgICAqCiAgICAgKiAgICAtIHNldF9jbGFzczogICAgICAgICAgYWRkcyB0aGUgZ2l2ZW4gY2xhc3MgdG8gdGhlIGVsZW1lbnQgKG5vdGU6IG1ha2Ugc3VyZSB0aGF0IHRoZSBjbGFzcyBpcyBpbiB0aGUgImNsYXNzZXMiIHdoaXRlIGxpc3QgYWJvdmUpCiAgICAgKgogICAgICogICAgLSBzZXRfYXR0cmlidXRlczogICAgIHNldHMvb3ZlcnJpZGVzIHRoZSBnaXZlbiBhdHRyaWJ1dGVzCiAgICAgKgogICAgICogICAgLSByZW1vdmVfYXR0cmlidXRlczogIHJlbW92ZV9hdHRyaWJ1dGVzOiAgcmVtb3ZlIGdpdmVuIGF0dHJpYnV0ZXMuIFthdHRyLCBwcm9wZXJ0eSwgZW5kU3RyaW5nXSAtPiByZW1vdmUgYXR0cmlidXRlIHByb3BlcnR5IGlmIGl0IGVuZHMgd2l0aCBlbmRTdHJpbmcuCiAgICAgKgogICAgICogICAgLSBjaGVja19hdHRyaWJ1dGVzOiAgIGNoZWNrcyB0aGUgZ2l2ZW4gSFRNTCBhdHRyaWJ1dGUgdmlhIHRoZSBnaXZlbiBtZXRob2QKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gdXJsOiAgICAgIGNoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBzdHJpbmcgaXMgYW4gdXJsLCBkZWxldGVzIHRoZSBhdHRyaWJ1dGUgaWYgbm90CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIGFsdDogICAgICBzdHJpcHMgdW53YW50ZWQgY2hhcmFjdGVycy4gaWYgdGhlIGF0dHJpYnV0ZSBpcyBub3Qgc2V0LCB0aGVuIGl0IGdldHMgc2V0ICh0byBlbnN1cmUgdmFsaWQgYW5kIGNvbXBhdGlibGUgSFRNTCkKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gbnVtYmVyczogIGVuc3VyZXMgdGhhdCB0aGUgYXR0cmlidXRlIG9ubHkgY29udGFpbnMgbnVtZXJpYyBjaGFyYWN0ZXJzCiAgICAgKi8KICAgICJ0YWdzIiA6IHsKICAgICAgICAidWwiIDoge30sCiAgICAgICAgIm9sIiA6IHt9LAogICAgICAgICJsaSIgOiB7fSwKICAgICAgICAiYiIgOiB7fSwKICAgICAgICAiaSIgOiB7fSwKICAgICAgICAidSIgOiB7fSwKICAgICAgICAic3VwIiA6IHt9LAogICAgICAgICJzdWIiIDoge30sCiAgICAgICAgImJyIiA6IHsKICAgICAgICAgICAgInJlbW92ZV9hdHRyaWJ1dGVzIiA6IFsic3R5bGUiXQogICAgICAgIH0sCiAgICAgICAgImgxIiA6IHt9LAogICAgICAgICJoMiIgOiB7fSwKICAgICAgICAiaDMiIDoge30sCiAgICAgICAgImg0IiA6IHt9LAogICAgICAgICJoNSIgOiB7fSwKICAgICAgICAiaDYiIDoge30sCiAgICAgICAgImEiIDogewogICAgICAgICAgICAiY2hlY2tfYXR0cmlidXRlcyIgOiB7CiAgICAgICAgICAgICAgICAiaHJlZiIgOiAidXJsIgogICAgICAgICAgICB9LAogICAgICAgICAgICAic2V0X2F0dHJpYnV0ZXMiIDogewogICAgICAgICAgICAgICAgInJlbCIgOiAibm9mb2xsb3ciLAogICAgICAgICAgICAgICAgInRhcmdldCIgOiAiX2JsYW5rIgogICAgICAgICAgICB9LAogICAgICAgICAgICAicmVtb3ZlX2F0dHJpYnV0ZXMiIDogWyJzdHlsZSxiYWNrZ3JvdW5kLWNvbG9yIl0KICAgICAgICB9LAogICAgICAgICJxIiA6IHsKICAgICAgICAgICAgImNoZWNrX2F0dHJpYnV0ZXMiIDogewogICAgICAgICAgICAgICAgImNpdGUiIDogInVybCIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImhyIiA6IHt9LAogICAgICAgICJwcmUiIDoge30sCiAgICAgICAgInNwYW4iIDogewogICAgICAgICAgICAicmVtb3ZlX2F0dHJpYnV0ZXMiIDogWyJzdHlsZSxsaW5lLWhlaWdodCIsICJzdHlsZSx0ZXh0LWFsaWduIiwgInN0eWxlLG1hcmdpbi1sZWZ0IiwgInN0eWxlLG1hcmdpbi1yaWdodCIsICJzdHlsZSxtYXJnaW4tdG9wIiwgInN0eWxlLG1hcmdpbi1ib3R0b20iLCAic3R5bGUsbWFyZ2luIl0KICAgICAgICB9LAogICAgICAgICJwIiA6IHt9LAogICAgICAgICJ0YWJsZSIgOiB7CiAgICAgICAgICAgICJjaGVja19hdHRyaWJ1dGVzIiA6IHsKICAgICAgICAgICAgICAgICJjZWxscGFkZGluZyIgOiAiYW55IiwKICAgICAgICAgICAgICAgICJjZWxsc3BhY2luZyIgOiAiYW55IiwKICAgICAgICAgICAgICAgICJib3JkZXIiIDogImFueSIsCiAgICAgICAgICAgICAgICAid2lkdGgiIDogImFueSIsCiAgICAgICAgICAgICAgICAiaGVpZ2h0IiA6ICJhbnkiCiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJ0aGVhZCIgOiB7fSwKICAgICAgICAidGZvb3QiIDoge30sCiAgICAgICAgInRoIiA6IHt9LAogICAgICAgICJjb2wiIDogewogICAgICAgICAgICAiY2hlY2tfYXR0cmlidXRlcyIgOiB7CiAgICAgICAgICAgICAgICAic3BhbiIgOiAibnVtYmVycyIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInRib2R5IiA6IHt9LAogICAgICAgICJ0ciIgOiB7fSwKICAgICAgICAidGQiIDoge30sCiAgICAgICAgImZvcm0iIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJjb2RlIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAidGl0bGUiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJhcmVhIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiY29tbWFuZCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImlmcmFtZSIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImltZyIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgIm5vZnJhbWVzIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiYmdzb3VuZCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImJhc2Vmb250IiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiYmFzZSIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgInZpZGVvIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiY2FudmFzIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiYXBwbGV0IiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAic3BhY2VyIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAic291cmNlIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiZnJhbWUiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJzdHlsZSIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImRldmljZSIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImVtYmVkIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAibm9lbWJlZCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgInhtbCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgInBhcmFtIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiYXVkaW8iIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJuZXh0aWQiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJsaW5rIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAic2NyaXB0IiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiY29sZ3JvdXAiIDoge30sCiAgICAgICAgIm86cCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImNvbW1lbnQiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJmcmFtZXNldCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImhlYWQiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJvYmplY3QiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJ0cmFjayIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgIndiciIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImJ1dHRvbiIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgIm5vc2NyaXB0IiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAic3ZnIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiaW5wdXQiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJrZXlnZW4iIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJtZXRhIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiaXNpbmRleCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImRlbCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgIm1hcCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImFkZHJlc3MiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAicCIKICAgICAgICB9LAogICAgICAgICJuYXYiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAicCIKICAgICAgICB9LAogICAgICAgICJtdWx0aWNvbCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJwIgogICAgICAgIH0sCiAgICAgICAgImZpZ3VyZSIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJwIgogICAgICAgIH0sCiAgICAgICAgImZpZ2NhcHRpb24iIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAicCIKICAgICAgICB9LAogICAgICAgICJmb290ZXIiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAicCIKICAgICAgICB9LAogICAgICAgICJmaWVsZHNldCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJwIgogICAgICAgIH0sCiAgICAgICAgImRpdiIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgImFzaWRlIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInAiCiAgICAgICAgfSwKICAgICAgICAic2VjdGlvbiIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJwIgogICAgICAgIH0sCiAgICAgICAgImJvZHkiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAicCIKICAgICAgICB9LAogICAgICAgICJodG1sIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInAiCiAgICAgICAgfSwKICAgICAgICAiaGdyb3VwIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInAiCiAgICAgICAgfSwKICAgICAgICAiY2VudGVyIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInAiCiAgICAgICAgfSwKICAgICAgICAiYXJ0aWNsZSIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJwIgogICAgICAgIH0sCiAgICAgICAgImhlYWRlciIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJwIgogICAgICAgIH0sCiAgICAgICAgImRsIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInAiCiAgICAgICAgfSwKICAgICAgICAiZGQiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJkdCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgInhtcCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgInNtYWxsIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAidGltZSIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgInJ1YnkiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJydCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgInJwIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAicmIiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJhY3JvbnltIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAiZGV0YWlscyIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgInN1bW1hcnkiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJiZGkiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJwcm9ncmVzcyIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgImRmbiIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgImFiYnIiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJzIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAic3RyaWtlIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAib3B0aW9uIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAib3B0Z3JvdXAiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJzZWxlY3QiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJiaWciIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJtYXJrIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAiY2FwdGlvbiIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgIm91dHB1dCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgIm1hcnF1ZWUiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJub2JyIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAidmFyIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAibWV0ZXIiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJibG9ja3F1b3RlIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAidGV4dGFyZWEiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJmb250IiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAidHQiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJibGluayIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgInBsYWludGV4dCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgImxlZ2VuZCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgImxhYmVsIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAia2JkIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAiZGF0YWxpc3QiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJzYW1wIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAiYmRvIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAiaW5zIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAic3Ryb25nIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogImIiCiAgICAgICAgfSwKICAgICAgICAiZW0iIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAiaSIKICAgICAgICB9LAogICAgICAgICJjaXRlIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogImkiCiAgICAgICAgfSwKICAgICAgICAiZGlyIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInVsIgogICAgICAgIH0sCiAgICAgICAgIm1lbnUiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAidWwiCiAgICAgICAgfSwKICAgICAgICAibWVudWl0ZW0iIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAibGkiCiAgICAgICAgfQogICAgfSwKICAgIC8qKgogICAgICogQ1NTIHN0eWxlcyB3aGl0ZS1saXN0CiAgICAgKiBGb2xsb3dpbmcgY3NzIHN0eWxlcyB3b24ndCBiZSByZW1vdmVkIHdoZW4gcGFyc2VkIGJ5IHRoZSB3eXNpaHRtbDUgaHRtbCBwYXJzZXIKICAgICAqLwogICAgInN0eWxlcyIgOiBbCiAgICAgICAgICAgICAgICAiZm9udC1mYW1pbHkiLAogICAgICAgICAgICAgICAgImZvbnQtc2l6ZSIsCiAgICAgICAgICAgICAgICAiY29sb3IiLAogICAgICAgICAgICAgICAgImJhY2tncm91bmQtY29sb3IiLAogICAgICAgICAgICAgICAgImxldHRlci1zcGFjaW5nIiwKICAgICAgICAgICAgICAgICJsaW5lLWhlaWdodCIsCiAgICAgICAgICAgICAgICAidGV4dC1hbGlnbiIsCiAgICAgICAgICAgICAgICAibWFyZ2luLWxlZnQiLAogICAgICAgICAgICAgICAgIm1hcmdpbi1yaWdodCIsCiAgICAgICAgICAgICAgICAibWFyZ2luLXRvcCIsCiAgICAgICAgICAgICAgICAibWFyZ2luLWJvdHRvbSIsCiAgICAgICAgICAgICAgICAibGlzdC1zdHlsZS10eXBlIiwKICAgICAgICAgICAgICAgICJ3aGl0ZS1zcGFjZSIsCiAgICAgICAgICAgICAgICAiYm9yZGVyLWNvbGxhcHNlIgogICAgICAgICAgICAgICAgXQp9OwoKLyohCgogaGFuZGxlYmFycyB2NC4wLjUKCiBDb3B5cmlnaHQgKEMpIDIwMTEtMjAxNSBieSBZZWh1ZGEgS2F0egoKIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgoKIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KIFRIRSBTT0ZUV0FSRS4KCiBAbGljZW5zZQogKi8KKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHsKCWlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JykKCQltb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTsKCWVsc2UgaWYodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKQoJCWRlZmluZShbXSwgZmFjdG9yeSk7CgllbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JykKCQlleHBvcnRzWyJIYW5kbGViYXJzIl0gPSBmYWN0b3J5KCk7CgllbHNlCgkJcm9vdFsiSGFuZGxlYmFycyJdID0gZmFjdG9yeSgpOwp9KSh0aGlzLCBmdW5jdGlvbigpIHsKCXJldHVybiAvKioqKioqLyAoZnVuY3Rpb24obW9kdWxlcykgeyAvLyB3ZWJwYWNrQm9vdHN0cmFwCgkJLyoqKioqKi8gCS8vIFRoZSBtb2R1bGUgY2FjaGUKCQkvKioqKioqLyAJdmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTsKCgkJLyoqKioqKi8gCS8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uCgkJLyoqKioqKi8gCWZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHsKCgkJCS8qKioqKiovIAkJLy8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlCgkJCS8qKioqKiovIAkJaWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pCgkJCS8qKioqKiovIAkJCXJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzOwoKCQkJLyoqKioqKi8gCQkvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKQoJCQkvKioqKioqLyAJCXZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHsKCQkJCS8qKioqKiovIAkJCWV4cG9ydHM6IHt9LAoJCQkJLyoqKioqKi8gCQkJaWQ6IG1vZHVsZUlkLAoJCQkJLyoqKioqKi8gCQkJbG9hZGVkOiBmYWxzZQoJCQkJLyoqKioqKi8gCQl9OwoKCQkJLyoqKioqKi8gCQkvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb24KCQkJLyoqKioqKi8gCQltb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTsKCgkJCS8qKioqKiovIAkJLy8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZAoJCQkvKioqKioqLyAJCW1vZHVsZS5sb2FkZWQgPSB0cnVlOwoKCQkJLyoqKioqKi8gCQkvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZQoJCQkvKioqKioqLyAJCXJldHVybiBtb2R1bGUuZXhwb3J0czsKCQkJLyoqKioqKi8gCX0KCgoJCS8qKioqKiovIAkvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKQoJCS8qKioqKiovIAlfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzOwoKCQkvKioqKioqLyAJLy8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGUKCQkvKioqKioqLyAJX193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlczsKCgkJLyoqKioqKi8gCS8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fCgkJLyoqKioqKi8gCV9fd2VicGFja19yZXF1aXJlX18ucCA9ICIiOwoKCQkvKioqKioqLyAJLy8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzCgkJLyoqKioqKi8gCXJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKDApOwoJCS8qKioqKiovIH0pCgkJLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCQkvKioqKioqLyAoWwoJCS8qIDAgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHsKCgkJCSd1c2Ugc3RyaWN0JzsKCgkJCXZhciBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCA9IF9fd2VicGFja19yZXF1aXJlX18oMSlbJ2RlZmF1bHQnXTsKCgkJCXZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKVsnZGVmYXVsdCddOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCgkJCXZhciBfaGFuZGxlYmFyc0Jhc2UgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDMpOwoKCQkJdmFyIGJhc2UgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfaGFuZGxlYmFyc0Jhc2UpOwoKCQkJLy8gRWFjaCBvZiB0aGVzZSBhdWdtZW50IHRoZSBIYW5kbGViYXJzIG9iamVjdC4gTm8gbmVlZCB0byBzZXR1cCBoZXJlLgoJCQkvLyAoVGhpcyBpcyBkb25lIHRvIGVhc2lseSBzaGFyZSBjb2RlIGJldHdlZW4gY29tbW9uanMgYW5kIGJyb3dzZSBlbnZzKQoKCQkJdmFyIF9oYW5kbGViYXJzU2FmZVN0cmluZyA9IF9fd2VicGFja19yZXF1aXJlX18oMTcpOwoKCQkJdmFyIF9oYW5kbGViYXJzU2FmZVN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9oYW5kbGViYXJzU2FmZVN0cmluZyk7CgoJCQl2YXIgX2hhbmRsZWJhcnNFeGNlcHRpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpOwoKCQkJdmFyIF9oYW5kbGViYXJzRXhjZXB0aW9uMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2hhbmRsZWJhcnNFeGNlcHRpb24pOwoKCQkJdmFyIF9oYW5kbGViYXJzVXRpbHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpOwoKCQkJdmFyIFV0aWxzID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoX2hhbmRsZWJhcnNVdGlscyk7CgoJCQl2YXIgX2hhbmRsZWJhcnNSdW50aW1lID0gX193ZWJwYWNrX3JlcXVpcmVfXygxOCk7CgoJCQl2YXIgcnVudGltZSA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF9oYW5kbGViYXJzUnVudGltZSk7CgoJCQl2YXIgX2hhbmRsZWJhcnNOb0NvbmZsaWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxOSk7CgoJCQl2YXIgX2hhbmRsZWJhcnNOb0NvbmZsaWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2hhbmRsZWJhcnNOb0NvbmZsaWN0KTsKCgkJCS8vIEZvciBjb21wYXRpYmlsaXR5IGFuZCB1c2FnZSBvdXRzaWRlIG9mIG1vZHVsZSBzeXN0ZW1zLCBtYWtlIHRoZSBIYW5kbGViYXJzIG9iamVjdCBhIG5hbWVzcGFjZQoJCQlmdW5jdGlvbiBjcmVhdGUoKSB7CgkJCQl2YXIgaGIgPSBuZXcgYmFzZS5IYW5kbGViYXJzRW52aXJvbm1lbnQoKTsKCgkJCQlVdGlscy5leHRlbmQoaGIsIGJhc2UpOwoJCQkJaGIuU2FmZVN0cmluZyA9IF9oYW5kbGViYXJzU2FmZVN0cmluZzJbJ2RlZmF1bHQnXTsKCQkJCWhiLkV4Y2VwdGlvbiA9IF9oYW5kbGViYXJzRXhjZXB0aW9uMlsnZGVmYXVsdCddOwoJCQkJaGIuVXRpbHMgPSBVdGlsczsKCQkJCWhiLmVzY2FwZUV4cHJlc3Npb24gPSBVdGlscy5lc2NhcGVFeHByZXNzaW9uOwoKCQkJCWhiLlZNID0gcnVudGltZTsKCQkJCWhiLnRlbXBsYXRlID0gZnVuY3Rpb24gKHNwZWMpIHsKCQkJCQlyZXR1cm4gcnVudGltZS50ZW1wbGF0ZShzcGVjLCBoYik7CgkJCQl9OwoKCQkJCXJldHVybiBoYjsKCQkJfQoKCQkJdmFyIGluc3QgPSBjcmVhdGUoKTsKCQkJaW5zdC5jcmVhdGUgPSBjcmVhdGU7CgoJCQlfaGFuZGxlYmFyc05vQ29uZmxpY3QyWydkZWZhdWx0J10oaW5zdCk7CgoJCQlpbnN0WydkZWZhdWx0J10gPSBpbnN0OwoKCQkJZXhwb3J0c1snZGVmYXVsdCddID0gaW5zdDsKCQkJbW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107CgoJCQkvKioqLyB9LAoJCS8qIDEgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHsKCgkJCSJ1c2Ugc3RyaWN0IjsKCgkJCWV4cG9ydHNbImRlZmF1bHQiXSA9IGZ1bmN0aW9uIChvYmopIHsKCQkJCWlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsKCQkJCQlyZXR1cm4gb2JqOwoJCQkJfSBlbHNlIHsKCQkJCQl2YXIgbmV3T2JqID0ge307CgoJCQkJCWlmIChvYmogIT0gbnVsbCkgewoJCQkJCQlmb3IgKHZhciBrZXkgaW4gb2JqKSB7CgkJCQkJCQlpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgbmV3T2JqW2tleV0gPSBvYmpba2V5XTsKCQkJCQkJfQoJCQkJCX0KCgkJCQkJbmV3T2JqWyJkZWZhdWx0Il0gPSBvYmo7CgkJCQkJcmV0dXJuIG5ld09iajsKCQkJCX0KCQkJfTsKCgkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgoJCQkvKioqLyB9LAoJCS8qIDIgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHsKCgkJCSJ1c2Ugc3RyaWN0IjsKCgkJCWV4cG9ydHNbImRlZmF1bHQiXSA9IGZ1bmN0aW9uIChvYmopIHsKCQkJCXJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7CgkJCQkJImRlZmF1bHQiOiBvYmoKCQkJCX07CgkJCX07CgoJCQlleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOwoKCQkJLyoqKi8gfSwKCQkvKiAzICovCgkJLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7CgoJCQkndXNlIHN0cmljdCc7CgoJCQl2YXIgX2ludGVyb3BSZXF1aXJlRGVmYXVsdCA9IF9fd2VicGFja19yZXF1aXJlX18oMilbJ2RlZmF1bHQnXTsKCgkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgkJCWV4cG9ydHMuSGFuZGxlYmFyc0Vudmlyb25tZW50ID0gSGFuZGxlYmFyc0Vudmlyb25tZW50OwoKCQkJdmFyIF91dGlscyA9IF9fd2VicGFja19yZXF1aXJlX18oNCk7CgoJCQl2YXIgX2V4Y2VwdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oNSk7CgoJCQl2YXIgX2V4Y2VwdGlvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9leGNlcHRpb24pOwoKCQkJdmFyIF9oZWxwZXJzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2KTsKCgkJCXZhciBfZGVjb3JhdG9ycyA9IF9fd2VicGFja19yZXF1aXJlX18oMTQpOwoKCQkJdmFyIF9sb2dnZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE2KTsKCgkJCXZhciBfbG9nZ2VyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2xvZ2dlcik7CgoJCQl2YXIgVkVSU0lPTiA9ICc0LjAuNSc7CgkJCWV4cG9ydHMuVkVSU0lPTiA9IFZFUlNJT047CgkJCXZhciBDT01QSUxFUl9SRVZJU0lPTiA9IDc7CgoJCQlleHBvcnRzLkNPTVBJTEVSX1JFVklTSU9OID0gQ09NUElMRVJfUkVWSVNJT047CgkJCXZhciBSRVZJU0lPTl9DSEFOR0VTID0gewoJCQkJMTogJzw9IDEuMC5yYy4yJywgLy8gMS4wLnJjLjIgaXMgYWN0dWFsbHkgcmV2MiBidXQgZG9lc24ndCByZXBvcnQgaXQKCQkJCTI6ICc9PSAxLjAuMC1yYy4zJywKCQkJCTM6ICc9PSAxLjAuMC1yYy40JywKCQkJCTQ6ICc9PSAxLngueCcsCgkJCQk1OiAnPT0gMi4wLjAtYWxwaGEueCcsCgkJCQk2OiAnPj0gMi4wLjAtYmV0YS4xJywKCQkJCTc6ICc+PSA0LjAuMCcKCQkJfTsKCgkJCWV4cG9ydHMuUkVWSVNJT05fQ0hBTkdFUyA9IFJFVklTSU9OX0NIQU5HRVM7CgkJCXZhciBvYmplY3RUeXBlID0gJ1tvYmplY3QgT2JqZWN0XSc7CgoJCQlmdW5jdGlvbiBIYW5kbGViYXJzRW52aXJvbm1lbnQoaGVscGVycywgcGFydGlhbHMsIGRlY29yYXRvcnMpIHsKCQkJCXRoaXMuaGVscGVycyA9IGhlbHBlcnMgfHwge307CgkJCQl0aGlzLnBhcnRpYWxzID0gcGFydGlhbHMgfHwge307CgkJCQl0aGlzLmRlY29yYXRvcnMgPSBkZWNvcmF0b3JzIHx8IHt9OwoKCQkJCV9oZWxwZXJzLnJlZ2lzdGVyRGVmYXVsdEhlbHBlcnModGhpcyk7CgkJCQlfZGVjb3JhdG9ycy5yZWdpc3RlckRlZmF1bHREZWNvcmF0b3JzKHRoaXMpOwoJCQl9CgoJCQlIYW5kbGViYXJzRW52aXJvbm1lbnQucHJvdG90eXBlID0gewoJCQkJY29uc3RydWN0b3I6IEhhbmRsZWJhcnNFbnZpcm9ubWVudCwKCgkJCQlsb2dnZXI6IF9sb2dnZXIyWydkZWZhdWx0J10sCgkJCQlsb2c6IF9sb2dnZXIyWydkZWZhdWx0J10ubG9nLAoKCQkJCXJlZ2lzdGVySGVscGVyOiBmdW5jdGlvbiByZWdpc3RlckhlbHBlcihuYW1lLCBmbikgewoJCQkJCWlmIChfdXRpbHMudG9TdHJpbmcuY2FsbChuYW1lKSA9PT0gb2JqZWN0VHlwZSkgewoJCQkJCQlpZiAoZm4pIHsKCQkJCQkJCXRocm93IG5ldyBfZXhjZXB0aW9uMlsnZGVmYXVsdCddKCdBcmcgbm90IHN1cHBvcnRlZCB3aXRoIG11bHRpcGxlIGhlbHBlcnMnKTsKCQkJCQkJfQoJCQkJCQlfdXRpbHMuZXh0ZW5kKHRoaXMuaGVscGVycywgbmFtZSk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJdGhpcy5oZWxwZXJzW25hbWVdID0gZm47CgkJCQkJfQoJCQkJfSwKCQkJCXVucmVnaXN0ZXJIZWxwZXI6IGZ1bmN0aW9uIHVucmVnaXN0ZXJIZWxwZXIobmFtZSkgewoJCQkJCWRlbGV0ZSB0aGlzLmhlbHBlcnNbbmFtZV07CgkJCQl9LAoKCQkJCXJlZ2lzdGVyUGFydGlhbDogZnVuY3Rpb24gcmVnaXN0ZXJQYXJ0aWFsKG5hbWUsIHBhcnRpYWwpIHsKCQkJCQlpZiAoX3V0aWxzLnRvU3RyaW5nLmNhbGwobmFtZSkgPT09IG9iamVjdFR5cGUpIHsKCQkJCQkJX3V0aWxzLmV4dGVuZCh0aGlzLnBhcnRpYWxzLCBuYW1lKTsKCQkJCQl9IGVsc2UgewoJCQkJCQlpZiAodHlwZW9mIHBhcnRpYWwgPT09ICd1bmRlZmluZWQnKSB7CgkJCQkJCQl0aHJvdyBuZXcgX2V4Y2VwdGlvbjJbJ2RlZmF1bHQnXSgnQXR0ZW1wdGluZyB0byByZWdpc3RlciBhIHBhcnRpYWwgY2FsbGVkICInICsgbmFtZSArICciIGFzIHVuZGVmaW5lZCcpOwoJCQkJCQl9CgkJCQkJCXRoaXMucGFydGlhbHNbbmFtZV0gPSBwYXJ0aWFsOwoJCQkJCX0KCQkJCX0sCgkJCQl1bnJlZ2lzdGVyUGFydGlhbDogZnVuY3Rpb24gdW5yZWdpc3RlclBhcnRpYWwobmFtZSkgewoJCQkJCWRlbGV0ZSB0aGlzLnBhcnRpYWxzW25hbWVdOwoJCQkJfSwKCgkJCQlyZWdpc3RlckRlY29yYXRvcjogZnVuY3Rpb24gcmVnaXN0ZXJEZWNvcmF0b3IobmFtZSwgZm4pIHsKCQkJCQlpZiAoX3V0aWxzLnRvU3RyaW5nLmNhbGwobmFtZSkgPT09IG9iamVjdFR5cGUpIHsKCQkJCQkJaWYgKGZuKSB7CgkJCQkJCQl0aHJvdyBuZXcgX2V4Y2VwdGlvbjJbJ2RlZmF1bHQnXSgnQXJnIG5vdCBzdXBwb3J0ZWQgd2l0aCBtdWx0aXBsZSBkZWNvcmF0b3JzJyk7CgkJCQkJCX0KCQkJCQkJX3V0aWxzLmV4dGVuZCh0aGlzLmRlY29yYXRvcnMsIG5hbWUpOwoJCQkJCX0gZWxzZSB7CgkJCQkJCXRoaXMuZGVjb3JhdG9yc1tuYW1lXSA9IGZuOwoJCQkJCX0KCQkJCX0sCgkJCQl1bnJlZ2lzdGVyRGVjb3JhdG9yOiBmdW5jdGlvbiB1bnJlZ2lzdGVyRGVjb3JhdG9yKG5hbWUpIHsKCQkJCQlkZWxldGUgdGhpcy5kZWNvcmF0b3JzW25hbWVdOwoJCQkJfQoJCQl9OwoKCQkJdmFyIGxvZyA9IF9sb2dnZXIyWydkZWZhdWx0J10ubG9nOwoKCQkJZXhwb3J0cy5sb2cgPSBsb2c7CgkJCWV4cG9ydHMuY3JlYXRlRnJhbWUgPSBfdXRpbHMuY3JlYXRlRnJhbWU7CgkJCWV4cG9ydHMubG9nZ2VyID0gX2xvZ2dlcjJbJ2RlZmF1bHQnXTsKCgkJCS8qKiovIH0sCgkJLyogNCAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCQkJZXhwb3J0cy5leHRlbmQgPSBleHRlbmQ7CgkJCWV4cG9ydHMuaW5kZXhPZiA9IGluZGV4T2Y7CgkJCWV4cG9ydHMuZXNjYXBlRXhwcmVzc2lvbiA9IGVzY2FwZUV4cHJlc3Npb247CgkJCWV4cG9ydHMuaXNFbXB0eSA9IGlzRW1wdHk7CgkJCWV4cG9ydHMuY3JlYXRlRnJhbWUgPSBjcmVhdGVGcmFtZTsKCQkJZXhwb3J0cy5ibG9ja1BhcmFtcyA9IGJsb2NrUGFyYW1zOwoJCQlleHBvcnRzLmFwcGVuZENvbnRleHRQYXRoID0gYXBwZW5kQ29udGV4dFBhdGg7CgkJCXZhciBlc2NhcGUgPSB7CgkJCQknJic6ICcmYW1wOycsCgkJCQknPCc6ICcmbHQ7JywKCQkJCSc+JzogJyZndDsnLAoJCQkJJyInOiAnJnF1b3Q7JywKCQkJCSInIjogJyYjeDI3OycsCgkJCQknYCc6ICcmI3g2MDsnLAoJCQkJJz0nOiAnJiN4M0Q7JwoJCQl9OwoKCQkJdmFyIGJhZENoYXJzID0gL1smPD4iJ2A9XS9nLAoJCQkJcG9zc2libGUgPSAvWyY8PiInYD1dLzsKCgkJCWZ1bmN0aW9uIGVzY2FwZUNoYXIoY2hyKSB7CgkJCQlyZXR1cm4gZXNjYXBlW2Nocl07CgkJCX0KCgkJCWZ1bmN0aW9uIGV4dGVuZChvYmogLyogLCAuLi5zb3VyY2UgKi8pIHsKCQkJCWZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7CgkJCQkJZm9yICh2YXIga2V5IGluIGFyZ3VtZW50c1tpXSkgewoJCQkJCQlpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGFyZ3VtZW50c1tpXSwga2V5KSkgewoJCQkJCQkJb2JqW2tleV0gPSBhcmd1bWVudHNbaV1ba2V5XTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCgkJCQlyZXR1cm4gb2JqOwoJCQl9CgoJCQl2YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nOwoKCQkJZXhwb3J0cy50b1N0cmluZyA9IHRvU3RyaW5nOwoJCQkvLyBTb3VyY2VkIGZyb20gbG9kYXNoCgkJCS8vIGh0dHBzOi8vZ2l0aHViLmNvbS9iZXN0aWVqcy9sb2Rhc2gvYmxvYi9tYXN0ZXIvTElDRU5TRS50eHQKCQkJLyogZXNsaW50LWRpc2FibGUgZnVuYy1zdHlsZSAqLwoJCQl2YXIgaXNGdW5jdGlvbiA9IGZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWUpIHsKCQkJCXJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbic7CgkJCX07CgkJCS8vIGZhbGxiYWNrIGZvciBvbGRlciB2ZXJzaW9ucyBvZiBDaHJvbWUgYW5kIFNhZmFyaQoJCQkvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLwoJCQlpZiAoaXNGdW5jdGlvbigveC8pKSB7CgkJCQlleHBvcnRzLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gKHZhbHVlKSB7CgkJCQkJcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0b1N0cmluZy5jYWxsKHZhbHVlKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJzsKCQkJCX07CgkJCX0KCQkJZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjsKCgkJCS8qIGVzbGludC1lbmFibGUgZnVuYy1zdHlsZSAqLwoKCQkJLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8KCQkJdmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uICh2YWx1ZSkgewoJCQkJcmV0dXJuIHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgPyB0b1N0cmluZy5jYWxsKHZhbHVlKSA9PT0gJ1tvYmplY3QgQXJyYXldJyA6IGZhbHNlOwoJCQl9OwoKCQkJZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTsKCQkJLy8gT2xkZXIgSUUgdmVyc2lvbnMgZG8gbm90IGRpcmVjdGx5IHN1cHBvcnQgaW5kZXhPZiBzbyB3ZSBtdXN0IGltcGxlbWVudCBvdXIgb3duLCBzYWRseS4KCgkJCWZ1bmN0aW9uIGluZGV4T2YoYXJyYXksIHZhbHVlKSB7CgkJCQlmb3IgKHZhciBpID0gMCwgbGVuID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHsKCQkJCQlpZiAoYXJyYXlbaV0gPT09IHZhbHVlKSB7CgkJCQkJCXJldHVybiBpOwoJCQkJCX0KCQkJCX0KCQkJCXJldHVybiAtMTsKCQkJfQoKCQkJZnVuY3Rpb24gZXNjYXBlRXhwcmVzc2lvbihzdHJpbmcpIHsKCQkJCWlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykgewoJCQkJCS8vIGRvbid0IGVzY2FwZSBTYWZlU3RyaW5ncywgc2luY2UgdGhleSdyZSBhbHJlYWR5IHNhZmUKCQkJCQlpZiAoc3RyaW5nICYmIHN0cmluZy50b0hUTUwpIHsKCQkJCQkJcmV0dXJuIHN0cmluZy50b0hUTUwoKTsKCQkJCQl9IGVsc2UgaWYgKHN0cmluZyA9PSBudWxsKSB7CgkJCQkJCXJldHVybiAnJzsKCQkJCQl9IGVsc2UgaWYgKCFzdHJpbmcpIHsKCQkJCQkJcmV0dXJuIHN0cmluZyArICcnOwoJCQkJCX0KCgkJCQkJLy8gRm9yY2UgYSBzdHJpbmcgY29udmVyc2lvbiBhcyB0aGlzIHdpbGwgYmUgZG9uZSBieSB0aGUgYXBwZW5kIHJlZ2FyZGxlc3MgYW5kCgkJCQkJLy8gdGhlIHJlZ2V4IHRlc3Qgd2lsbCBkbyB0aGlzIHRyYW5zcGFyZW50bHkgYmVoaW5kIHRoZSBzY2VuZXMsIGNhdXNpbmcgaXNzdWVzIGlmCgkJCQkJLy8gYW4gb2JqZWN0J3MgdG8gc3RyaW5nIGhhcyBlc2NhcGVkIGNoYXJhY3RlcnMgaW4gaXQuCgkJCQkJc3RyaW5nID0gJycgKyBzdHJpbmc7CgkJCQl9CgoJCQkJaWYgKCFwb3NzaWJsZS50ZXN0KHN0cmluZykpIHsKCQkJCQlyZXR1cm4gc3RyaW5nOwoJCQkJfQoJCQkJcmV0dXJuIHN0cmluZy5yZXBsYWNlKGJhZENoYXJzLCBlc2NhcGVDaGFyKTsKCQkJfQoKCQkJZnVuY3Rpb24gaXNFbXB0eSh2YWx1ZSkgewoJCQkJaWYgKCF2YWx1ZSAmJiB2YWx1ZSAhPT0gMCkgewoJCQkJCXJldHVybiB0cnVlOwoJCQkJfSBlbHNlIGlmIChpc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5sZW5ndGggPT09IDApIHsKCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCX0gZWxzZSB7CgkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoJCQl9CgoJCQlmdW5jdGlvbiBjcmVhdGVGcmFtZShvYmplY3QpIHsKCQkJCXZhciBmcmFtZSA9IGV4dGVuZCh7fSwgb2JqZWN0KTsKCQkJCWZyYW1lLl9wYXJlbnQgPSBvYmplY3Q7CgkJCQlyZXR1cm4gZnJhbWU7CgkJCX0KCgkJCWZ1bmN0aW9uIGJsb2NrUGFyYW1zKHBhcmFtcywgaWRzKSB7CgkJCQlwYXJhbXMucGF0aCA9IGlkczsKCQkJCXJldHVybiBwYXJhbXM7CgkJCX0KCgkJCWZ1bmN0aW9uIGFwcGVuZENvbnRleHRQYXRoKGNvbnRleHRQYXRoLCBpZCkgewoJCQkJcmV0dXJuIChjb250ZXh0UGF0aCA/IGNvbnRleHRQYXRoICsgJy4nIDogJycpICsgaWQ7CgkJCX0KCgkJCS8qKiovIH0sCgkJLyogNSAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCgkJCXZhciBlcnJvclByb3BzID0gWydkZXNjcmlwdGlvbicsICdmaWxlTmFtZScsICdsaW5lTnVtYmVyJywgJ21lc3NhZ2UnLCAnbmFtZScsICdudW1iZXInLCAnc3RhY2snXTsKCgkJCWZ1bmN0aW9uIEV4Y2VwdGlvbihtZXNzYWdlLCBub2RlKSB7CgkJCQl2YXIgbG9jID0gbm9kZSAmJiBub2RlLmxvYywKCQkJCQlsaW5lID0gdW5kZWZpbmVkLAoJCQkJCWNvbHVtbiA9IHVuZGVmaW5lZDsKCQkJCWlmIChsb2MpIHsKCQkJCQlsaW5lID0gbG9jLnN0YXJ0LmxpbmU7CgkJCQkJY29sdW1uID0gbG9jLnN0YXJ0LmNvbHVtbjsKCgkJCQkJbWVzc2FnZSArPSAnIC0gJyArIGxpbmUgKyAnOicgKyBjb2x1bW47CgkJCQl9CgoJCQkJdmFyIHRtcCA9IEVycm9yLnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsIG1lc3NhZ2UpOwoKCQkJCS8vIFVuZm9ydHVuYXRlbHkgZXJyb3JzIGFyZSBub3QgZW51bWVyYWJsZSBpbiBDaHJvbWUgKGF0IGxlYXN0KSwgc28gYGZvciBwcm9wIGluIHRtcGAgZG9lc24ndCB3b3JrLgoJCQkJZm9yICh2YXIgaWR4ID0gMDsgaWR4IDwgZXJyb3JQcm9wcy5sZW5ndGg7IGlkeCsrKSB7CgkJCQkJdGhpc1tlcnJvclByb3BzW2lkeF1dID0gdG1wW2Vycm9yUHJvcHNbaWR4XV07CgkJCQl9CgoJCQkJLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi8KCQkJCWlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkgewoJCQkJCUVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIEV4Y2VwdGlvbik7CgkJCQl9CgoJCQkJaWYgKGxvYykgewoJCQkJCXRoaXMubGluZU51bWJlciA9IGxpbmU7CgkJCQkJdGhpcy5jb2x1bW4gPSBjb2x1bW47CgkJCQl9CgkJCX0KCgkJCUV4Y2VwdGlvbi5wcm90b3R5cGUgPSBuZXcgRXJyb3IoKTsKCgkJCWV4cG9ydHNbJ2RlZmF1bHQnXSA9IEV4Y2VwdGlvbjsKCQkJbW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107CgoJCQkvKioqLyB9LAoJCS8qIDYgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHsKCgkJCSd1c2Ugc3RyaWN0JzsKCgkJCXZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKVsnZGVmYXVsdCddOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCQkJZXhwb3J0cy5yZWdpc3RlckRlZmF1bHRIZWxwZXJzID0gcmVnaXN0ZXJEZWZhdWx0SGVscGVyczsKCgkJCXZhciBfaGVscGVyc0Jsb2NrSGVscGVyTWlzc2luZyA9IF9fd2VicGFja19yZXF1aXJlX18oNyk7CgoJCQl2YXIgX2hlbHBlcnNCbG9ja0hlbHBlck1pc3NpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaGVscGVyc0Jsb2NrSGVscGVyTWlzc2luZyk7CgoJCQl2YXIgX2hlbHBlcnNFYWNoID0gX193ZWJwYWNrX3JlcXVpcmVfXyg4KTsKCgkJCXZhciBfaGVscGVyc0VhY2gyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaGVscGVyc0VhY2gpOwoKCQkJdmFyIF9oZWxwZXJzSGVscGVyTWlzc2luZyA9IF9fd2VicGFja19yZXF1aXJlX18oOSk7CgoJCQl2YXIgX2hlbHBlcnNIZWxwZXJNaXNzaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2hlbHBlcnNIZWxwZXJNaXNzaW5nKTsKCgkJCXZhciBfaGVscGVyc0lmID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMCk7CgoJCQl2YXIgX2hlbHBlcnNJZjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9oZWxwZXJzSWYpOwoKCQkJdmFyIF9oZWxwZXJzTG9nID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMSk7CgoJCQl2YXIgX2hlbHBlcnNMb2cyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaGVscGVyc0xvZyk7CgoJCQl2YXIgX2hlbHBlcnNMb29rdXAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEyKTsKCgkJCXZhciBfaGVscGVyc0xvb2t1cDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9oZWxwZXJzTG9va3VwKTsKCgkJCXZhciBfaGVscGVyc1dpdGggPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEzKTsKCgkJCXZhciBfaGVscGVyc1dpdGgyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaGVscGVyc1dpdGgpOwoKCQkJZnVuY3Rpb24gcmVnaXN0ZXJEZWZhdWx0SGVscGVycyhpbnN0YW5jZSkgewoJCQkJX2hlbHBlcnNCbG9ja0hlbHBlck1pc3NpbmcyWydkZWZhdWx0J10oaW5zdGFuY2UpOwoJCQkJX2hlbHBlcnNFYWNoMlsnZGVmYXVsdCddKGluc3RhbmNlKTsKCQkJCV9oZWxwZXJzSGVscGVyTWlzc2luZzJbJ2RlZmF1bHQnXShpbnN0YW5jZSk7CgkJCQlfaGVscGVyc0lmMlsnZGVmYXVsdCddKGluc3RhbmNlKTsKCQkJCV9oZWxwZXJzTG9nMlsnZGVmYXVsdCddKGluc3RhbmNlKTsKCQkJCV9oZWxwZXJzTG9va3VwMlsnZGVmYXVsdCddKGluc3RhbmNlKTsKCQkJCV9oZWxwZXJzV2l0aDJbJ2RlZmF1bHQnXShpbnN0YW5jZSk7CgkJCX0KCgkJCS8qKiovIH0sCgkJLyogNyAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCgkJCXZhciBfdXRpbHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpOwoKCQkJZXhwb3J0c1snZGVmYXVsdCddID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7CgkJCQlpbnN0YW5jZS5yZWdpc3RlckhlbHBlcignYmxvY2tIZWxwZXJNaXNzaW5nJywgZnVuY3Rpb24gKGNvbnRleHQsIG9wdGlvbnMpIHsKCQkJCQl2YXIgaW52ZXJzZSA9IG9wdGlvbnMuaW52ZXJzZSwKCQkJCQkJZm4gPSBvcHRpb25zLmZuOwoKCQkJCQlpZiAoY29udGV4dCA9PT0gdHJ1ZSkgewoJCQkJCQlyZXR1cm4gZm4odGhpcyk7CgkJCQkJfSBlbHNlIGlmIChjb250ZXh0ID09PSBmYWxzZSB8fCBjb250ZXh0ID09IG51bGwpIHsKCQkJCQkJcmV0dXJuIGludmVyc2UodGhpcyk7CgkJCQkJfSBlbHNlIGlmIChfdXRpbHMuaXNBcnJheShjb250ZXh0KSkgewoJCQkJCQlpZiAoY29udGV4dC5sZW5ndGggPiAwKSB7CgkJCQkJCQlpZiAob3B0aW9ucy5pZHMpIHsKCQkJCQkJCQlvcHRpb25zLmlkcyA9IFtvcHRpb25zLm5hbWVdOwoJCQkJCQkJfQoKCQkJCQkJCXJldHVybiBpbnN0YW5jZS5oZWxwZXJzLmVhY2goY29udGV4dCwgb3B0aW9ucyk7CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQlyZXR1cm4gaW52ZXJzZSh0aGlzKTsKCQkJCQkJfQoJCQkJCX0gZWxzZSB7CgkJCQkJCWlmIChvcHRpb25zLmRhdGEgJiYgb3B0aW9ucy5pZHMpIHsKCQkJCQkJCXZhciBkYXRhID0gX3V0aWxzLmNyZWF0ZUZyYW1lKG9wdGlvbnMuZGF0YSk7CgkJCQkJCQlkYXRhLmNvbnRleHRQYXRoID0gX3V0aWxzLmFwcGVuZENvbnRleHRQYXRoKG9wdGlvbnMuZGF0YS5jb250ZXh0UGF0aCwgb3B0aW9ucy5uYW1lKTsKCQkJCQkJCW9wdGlvbnMgPSB7IGRhdGE6IGRhdGEgfTsKCQkJCQkJfQoKCQkJCQkJcmV0dXJuIGZuKGNvbnRleHQsIG9wdGlvbnMpOwoJCQkJCX0KCQkJCX0pOwoJCQl9OwoKCQkJbW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107CgoJCQkvKioqLyB9LAoJCS8qIDggKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHsKCgkJCSd1c2Ugc3RyaWN0JzsKCgkJCXZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKVsnZGVmYXVsdCddOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCgkJCXZhciBfdXRpbHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpOwoKCQkJdmFyIF9leGNlcHRpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpOwoKCQkJdmFyIF9leGNlcHRpb24yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZXhjZXB0aW9uKTsKCgkJCWV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZ1bmN0aW9uIChpbnN0YW5jZSkgewoJCQkJaW5zdGFuY2UucmVnaXN0ZXJIZWxwZXIoJ2VhY2gnLCBmdW5jdGlvbiAoY29udGV4dCwgb3B0aW9ucykgewoJCQkJCWlmICghb3B0aW9ucykgewoJCQkJCQl0aHJvdyBuZXcgX2V4Y2VwdGlvbjJbJ2RlZmF1bHQnXSgnTXVzdCBwYXNzIGl0ZXJhdG9yIHRvICNlYWNoJyk7CgkJCQkJfQoKCQkJCQl2YXIgZm4gPSBvcHRpb25zLmZuLAoJCQkJCQlpbnZlcnNlID0gb3B0aW9ucy5pbnZlcnNlLAoJCQkJCQlpID0gMCwKCQkJCQkJcmV0ID0gJycsCgkJCQkJCWRhdGEgPSB1bmRlZmluZWQsCgkJCQkJCWNvbnRleHRQYXRoID0gdW5kZWZpbmVkOwoKCQkJCQlpZiAob3B0aW9ucy5kYXRhICYmIG9wdGlvbnMuaWRzKSB7CgkJCQkJCWNvbnRleHRQYXRoID0gX3V0aWxzLmFwcGVuZENvbnRleHRQYXRoKG9wdGlvbnMuZGF0YS5jb250ZXh0UGF0aCwgb3B0aW9ucy5pZHNbMF0pICsgJy4nOwoJCQkJCX0KCgkJCQkJaWYgKF91dGlscy5pc0Z1bmN0aW9uKGNvbnRleHQpKSB7CgkJCQkJCWNvbnRleHQgPSBjb250ZXh0LmNhbGwodGhpcyk7CgkJCQkJfQoKCQkJCQlpZiAob3B0aW9ucy5kYXRhKSB7CgkJCQkJCWRhdGEgPSBfdXRpbHMuY3JlYXRlRnJhbWUob3B0aW9ucy5kYXRhKTsKCQkJCQl9CgoJCQkJCWZ1bmN0aW9uIGV4ZWNJdGVyYXRpb24oZmllbGQsIGluZGV4LCBsYXN0KSB7CgkJCQkJCWlmIChkYXRhKSB7CgkJCQkJCQlkYXRhLmtleSA9IGZpZWxkOwoJCQkJCQkJZGF0YS5pbmRleCA9IGluZGV4OwoJCQkJCQkJZGF0YS5maXJzdCA9IGluZGV4ID09PSAwOwoJCQkJCQkJZGF0YS5sYXN0ID0gISFsYXN0OwoKCQkJCQkJCWlmIChjb250ZXh0UGF0aCkgewoJCQkJCQkJCWRhdGEuY29udGV4dFBhdGggPSBjb250ZXh0UGF0aCArIGZpZWxkOwoJCQkJCQkJfQoJCQkJCQl9CgoJCQkJCQlyZXQgPSByZXQgKyBmbihjb250ZXh0W2ZpZWxkXSwgewoJCQkJCQkJZGF0YTogZGF0YSwKCQkJCQkJCWJsb2NrUGFyYW1zOiBfdXRpbHMuYmxvY2tQYXJhbXMoW2NvbnRleHRbZmllbGRdLCBmaWVsZF0sIFtjb250ZXh0UGF0aCArIGZpZWxkLCBudWxsXSkKCQkJCQkJfSk7CgkJCQkJfQoKCQkJCQlpZiAoY29udGV4dCAmJiB0eXBlb2YgY29udGV4dCA9PT0gJ29iamVjdCcpIHsKCQkJCQkJaWYgKF91dGlscy5pc0FycmF5KGNvbnRleHQpKSB7CgkJCQkJCQlmb3IgKHZhciBqID0gY29udGV4dC5sZW5ndGg7IGkgPCBqOyBpKyspIHsKCQkJCQkJCQlpZiAoaSBpbiBjb250ZXh0KSB7CgkJCQkJCQkJCWV4ZWNJdGVyYXRpb24oaSwgaSwgaSA9PT0gY29udGV4dC5sZW5ndGggLSAxKTsKCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQl2YXIgcHJpb3JLZXkgPSB1bmRlZmluZWQ7CgoJCQkJCQkJZm9yICh2YXIga2V5IGluIGNvbnRleHQpIHsKCQkJCQkJCQlpZiAoY29udGV4dC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7CgkJCQkJCQkJCS8vIFdlJ3JlIHJ1bm5pbmcgdGhlIGl0ZXJhdGlvbnMgb25lIHN0ZXAgb3V0IG9mIHN5bmMgc28gd2UgY2FuIGRldGVjdAoJCQkJCQkJCQkvLyB0aGUgbGFzdCBpdGVyYXRpb24gd2l0aG91dCBoYXZlIHRvIHNjYW4gdGhlIG9iamVjdCB0d2ljZSBhbmQgY3JlYXRlCgkJCQkJCQkJCS8vIGFuIGl0ZXJtZWRpYXRlIGtleXMgYXJyYXkuCgkJCQkJCQkJCWlmIChwcmlvcktleSAhPT0gdW5kZWZpbmVkKSB7CgkJCQkJCQkJCQlleGVjSXRlcmF0aW9uKHByaW9yS2V5LCBpIC0gMSk7CgkJCQkJCQkJCX0KCQkJCQkJCQkJcHJpb3JLZXkgPSBrZXk7CgkJCQkJCQkJCWkrKzsKCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCQlpZiAocHJpb3JLZXkgIT09IHVuZGVmaW5lZCkgewoJCQkJCQkJCWV4ZWNJdGVyYXRpb24ocHJpb3JLZXksIGkgLSAxLCB0cnVlKTsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCgkJCQkJaWYgKGkgPT09IDApIHsKCQkJCQkJcmV0ID0gaW52ZXJzZSh0aGlzKTsKCQkJCQl9CgoJCQkJCXJldHVybiByZXQ7CgkJCQl9KTsKCQkJfTsKCgkJCW1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOwoKCQkJLyoqKi8gfSwKCQkvKiA5ICovCgkJLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7CgoJCQkndXNlIHN0cmljdCc7CgoJCQl2YXIgX2ludGVyb3BSZXF1aXJlRGVmYXVsdCA9IF9fd2VicGFja19yZXF1aXJlX18oMilbJ2RlZmF1bHQnXTsKCgkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgoJCQl2YXIgX2V4Y2VwdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oNSk7CgoJCQl2YXIgX2V4Y2VwdGlvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9leGNlcHRpb24pOwoKCQkJZXhwb3J0c1snZGVmYXVsdCddID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7CgkJCQlpbnN0YW5jZS5yZWdpc3RlckhlbHBlcignaGVscGVyTWlzc2luZycsIGZ1bmN0aW9uICgpIC8qIFthcmdzLCBdb3B0aW9ucyAqL3sKCQkJCQlpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkgewoJCQkJCQkvLyBBIG1pc3NpbmcgZmllbGQgaW4gYSB7e2Zvb319IGNvbnN0cnVjdC4KCQkJCQkJcmV0dXJuIHVuZGVmaW5lZDsKCQkJCQl9IGVsc2UgewoJCQkJCQkvLyBTb21lb25lIGlzIGFjdHVhbGx5IHRyeWluZyB0byBjYWxsIHNvbWV0aGluZywgYmxvdyB1cC4KCQkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJ01pc3NpbmcgaGVscGVyOiAiJyArIGFyZ3VtZW50c1thcmd1bWVudHMubGVuZ3RoIC0gMV0ubmFtZSArICciJyk7CgkJCQkJfQoJCQkJfSk7CgkJCX07CgoJCQltb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsKCgkJCS8qKiovIH0sCgkJLyogMTAgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHsKCgkJCSd1c2Ugc3RyaWN0JzsKCgkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgoJCQl2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTsKCgkJCWV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZ1bmN0aW9uIChpbnN0YW5jZSkgewoJCQkJaW5zdGFuY2UucmVnaXN0ZXJIZWxwZXIoJ2lmJywgZnVuY3Rpb24gKGNvbmRpdGlvbmFsLCBvcHRpb25zKSB7CgkJCQkJaWYgKF91dGlscy5pc0Z1bmN0aW9uKGNvbmRpdGlvbmFsKSkgewoJCQkJCQljb25kaXRpb25hbCA9IGNvbmRpdGlvbmFsLmNhbGwodGhpcyk7CgkJCQkJfQoKCQkJCQkvLyBEZWZhdWx0IGJlaGF2aW9yIGlzIHRvIHJlbmRlciB0aGUgcG9zaXRpdmUgcGF0aCBpZiB0aGUgdmFsdWUgaXMgdHJ1dGh5IGFuZCBub3QgZW1wdHkuCgkJCQkJLy8gVGhlIGBpbmNsdWRlWmVyb2Agb3B0aW9uIG1heSBiZSBzZXQgdG8gdHJlYXQgdGhlIGNvbmR0aW9uYWwgYXMgcHVyZWx5IG5vdCBlbXB0eSBiYXNlZCBvbiB0aGUKCQkJCQkvLyBiZWhhdmlvciBvZiBpc0VtcHR5LiBFZmZlY3RpdmVseSB0aGlzIGRldGVybWluZXMgaWYgMCBpcyBoYW5kbGVkIGJ5IHRoZSBwb3NpdGl2ZSBwYXRoIG9yIG5lZ2F0aXZlLgoJCQkJCWlmICghb3B0aW9ucy5oYXNoLmluY2x1ZGVaZXJvICYmICFjb25kaXRpb25hbCB8fCBfdXRpbHMuaXNFbXB0eShjb25kaXRpb25hbCkpIHsKCQkJCQkJcmV0dXJuIG9wdGlvbnMuaW52ZXJzZSh0aGlzKTsKCQkJCQl9IGVsc2UgewoJCQkJCQlyZXR1cm4gb3B0aW9ucy5mbih0aGlzKTsKCQkJCQl9CgkJCQl9KTsKCgkJCQlpbnN0YW5jZS5yZWdpc3RlckhlbHBlcigndW5sZXNzJywgZnVuY3Rpb24gKGNvbmRpdGlvbmFsLCBvcHRpb25zKSB7CgkJCQkJcmV0dXJuIGluc3RhbmNlLmhlbHBlcnNbJ2lmJ10uY2FsbCh0aGlzLCBjb25kaXRpb25hbCwgeyBmbjogb3B0aW9ucy5pbnZlcnNlLCBpbnZlcnNlOiBvcHRpb25zLmZuLCBoYXNoOiBvcHRpb25zLmhhc2ggfSk7CgkJCQl9KTsKCQkJfTsKCgkJCW1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOwoKCQkJLyoqKi8gfSwKCQkvKiAxMSAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCgkJCWV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZ1bmN0aW9uIChpbnN0YW5jZSkgewoJCQkJaW5zdGFuY2UucmVnaXN0ZXJIZWxwZXIoJ2xvZycsIGZ1bmN0aW9uICgpIC8qIG1lc3NhZ2UsIG9wdGlvbnMgKi97CgkJCQkJdmFyIGFyZ3MgPSBbdW5kZWZpbmVkXSwKCQkJCQkJb3B0aW9ucyA9IGFyZ3VtZW50c1thcmd1bWVudHMubGVuZ3RoIC0gMV07CgkJCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoIC0gMTsgaSsrKSB7CgkJCQkJCWFyZ3MucHVzaChhcmd1bWVudHNbaV0pOwoJCQkJCX0KCgkJCQkJdmFyIGxldmVsID0gMTsKCQkJCQlpZiAob3B0aW9ucy5oYXNoLmxldmVsICE9IG51bGwpIHsKCQkJCQkJbGV2ZWwgPSBvcHRpb25zLmhhc2gubGV2ZWw7CgkJCQkJfSBlbHNlIGlmIChvcHRpb25zLmRhdGEgJiYgb3B0aW9ucy5kYXRhLmxldmVsICE9IG51bGwpIHsKCQkJCQkJbGV2ZWwgPSBvcHRpb25zLmRhdGEubGV2ZWw7CgkJCQkJfQoJCQkJCWFyZ3NbMF0gPSBsZXZlbDsKCgkJCQkJaW5zdGFuY2UubG9nLmFwcGx5KGluc3RhbmNlLCBhcmdzKTsKCQkJCX0pOwoJCQl9OwoKCQkJbW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107CgoJCQkvKioqLyB9LAoJCS8qIDEyICovCgkJLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7CgoJCQkndXNlIHN0cmljdCc7CgoJCQlleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOwoKCQkJZXhwb3J0c1snZGVmYXVsdCddID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7CgkJCQlpbnN0YW5jZS5yZWdpc3RlckhlbHBlcignbG9va3VwJywgZnVuY3Rpb24gKG9iaiwgZmllbGQpIHsKCQkJCQlyZXR1cm4gb2JqICYmIG9ialtmaWVsZF07CgkJCQl9KTsKCQkJfTsKCgkJCW1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOwoKCQkJLyoqKi8gfSwKCQkvKiAxMyAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCgkJCXZhciBfdXRpbHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpOwoKCQkJZXhwb3J0c1snZGVmYXVsdCddID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7CgkJCQlpbnN0YW5jZS5yZWdpc3RlckhlbHBlcignd2l0aCcsIGZ1bmN0aW9uIChjb250ZXh0LCBvcHRpb25zKSB7CgkJCQkJaWYgKF91dGlscy5pc0Z1bmN0aW9uKGNvbnRleHQpKSB7CgkJCQkJCWNvbnRleHQgPSBjb250ZXh0LmNhbGwodGhpcyk7CgkJCQkJfQoKCQkJCQl2YXIgZm4gPSBvcHRpb25zLmZuOwoKCQkJCQlpZiAoIV91dGlscy5pc0VtcHR5KGNvbnRleHQpKSB7CgkJCQkJCXZhciBkYXRhID0gb3B0aW9ucy5kYXRhOwoJCQkJCQlpZiAob3B0aW9ucy5kYXRhICYmIG9wdGlvbnMuaWRzKSB7CgkJCQkJCQlkYXRhID0gX3V0aWxzLmNyZWF0ZUZyYW1lKG9wdGlvbnMuZGF0YSk7CgkJCQkJCQlkYXRhLmNvbnRleHRQYXRoID0gX3V0aWxzLmFwcGVuZENvbnRleHRQYXRoKG9wdGlvbnMuZGF0YS5jb250ZXh0UGF0aCwgb3B0aW9ucy5pZHNbMF0pOwoJCQkJCQl9CgoJCQkJCQlyZXR1cm4gZm4oY29udGV4dCwgewoJCQkJCQkJZGF0YTogZGF0YSwKCQkJCQkJCWJsb2NrUGFyYW1zOiBfdXRpbHMuYmxvY2tQYXJhbXMoW2NvbnRleHRdLCBbZGF0YSAmJiBkYXRhLmNvbnRleHRQYXRoXSkKCQkJCQkJfSk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJcmV0dXJuIG9wdGlvbnMuaW52ZXJzZSh0aGlzKTsKCQkJCQl9CgkJCQl9KTsKCQkJfTsKCgkJCW1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOwoKCQkJLyoqKi8gfSwKCQkvKiAxNCAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJdmFyIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDIpWydkZWZhdWx0J107CgoJCQlleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOwoJCQlleHBvcnRzLnJlZ2lzdGVyRGVmYXVsdERlY29yYXRvcnMgPSByZWdpc3RlckRlZmF1bHREZWNvcmF0b3JzOwoKCQkJdmFyIF9kZWNvcmF0b3JzSW5saW5lID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNSk7CgoJCQl2YXIgX2RlY29yYXRvcnNJbmxpbmUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZGVjb3JhdG9yc0lubGluZSk7CgoJCQlmdW5jdGlvbiByZWdpc3RlckRlZmF1bHREZWNvcmF0b3JzKGluc3RhbmNlKSB7CgkJCQlfZGVjb3JhdG9yc0lubGluZTJbJ2RlZmF1bHQnXShpbnN0YW5jZSk7CgkJCX0KCgkJCS8qKiovIH0sCgkJLyogMTUgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHsKCgkJCSd1c2Ugc3RyaWN0JzsKCgkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgoJCQl2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTsKCgkJCWV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZ1bmN0aW9uIChpbnN0YW5jZSkgewoJCQkJaW5zdGFuY2UucmVnaXN0ZXJEZWNvcmF0b3IoJ2lubGluZScsIGZ1bmN0aW9uIChmbiwgcHJvcHMsIGNvbnRhaW5lciwgb3B0aW9ucykgewoJCQkJCXZhciByZXQgPSBmbjsKCQkJCQlpZiAoIXByb3BzLnBhcnRpYWxzKSB7CgkJCQkJCXByb3BzLnBhcnRpYWxzID0ge307CgkJCQkJCXJldCA9IGZ1bmN0aW9uIChjb250ZXh0LCBvcHRpb25zKSB7CgkJCQkJCQkvLyBDcmVhdGUgYSBuZXcgcGFydGlhbHMgc3RhY2sgZnJhbWUgcHJpb3IgdG8gZXhlYy4KCQkJCQkJCXZhciBvcmlnaW5hbCA9IGNvbnRhaW5lci5wYXJ0aWFsczsKCQkJCQkJCWNvbnRhaW5lci5wYXJ0aWFscyA9IF91dGlscy5leHRlbmQoe30sIG9yaWdpbmFsLCBwcm9wcy5wYXJ0aWFscyk7CgkJCQkJCQl2YXIgcmV0ID0gZm4oY29udGV4dCwgb3B0aW9ucyk7CgkJCQkJCQljb250YWluZXIucGFydGlhbHMgPSBvcmlnaW5hbDsKCQkJCQkJCXJldHVybiByZXQ7CgkJCQkJCX07CgkJCQkJfQoKCQkJCQlwcm9wcy5wYXJ0aWFsc1tvcHRpb25zLmFyZ3NbMF1dID0gb3B0aW9ucy5mbjsKCgkJCQkJcmV0dXJuIHJldDsKCQkJCX0pOwoJCQl9OwoKCQkJbW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107CgoJCQkvKioqLyB9LAoJCS8qIDE2ICovCgkJLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7CgoJCQkndXNlIHN0cmljdCc7CgoJCQlleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOwoKCQkJdmFyIF91dGlscyA9IF9fd2VicGFja19yZXF1aXJlX18oNCk7CgoJCQl2YXIgbG9nZ2VyID0gewoJCQkJbWV0aG9kTWFwOiBbJ2RlYnVnJywgJ2luZm8nLCAnd2FybicsICdlcnJvciddLAoJCQkJbGV2ZWw6ICdpbmZvJywKCgkJCQkvLyBNYXBzIGEgZ2l2ZW4gbGV2ZWwgdmFsdWUgdG8gdGhlIGBtZXRob2RNYXBgIGluZGV4ZXMgYWJvdmUuCgkJCQlsb29rdXBMZXZlbDogZnVuY3Rpb24gbG9va3VwTGV2ZWwobGV2ZWwpIHsKCQkJCQlpZiAodHlwZW9mIGxldmVsID09PSAnc3RyaW5nJykgewoJCQkJCQl2YXIgbGV2ZWxNYXAgPSBfdXRpbHMuaW5kZXhPZihsb2dnZXIubWV0aG9kTWFwLCBsZXZlbC50b0xvd2VyQ2FzZSgpKTsKCQkJCQkJaWYgKGxldmVsTWFwID49IDApIHsKCQkJCQkJCWxldmVsID0gbGV2ZWxNYXA7CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQlsZXZlbCA9IHBhcnNlSW50KGxldmVsLCAxMCk7CgkJCQkJCX0KCQkJCQl9CgoJCQkJCXJldHVybiBsZXZlbDsKCQkJCX0sCgoJCQkJLy8gQ2FuIGJlIG92ZXJyaWRkZW4gaW4gdGhlIGhvc3QgZW52aXJvbm1lbnQKCQkJCWxvZzogZnVuY3Rpb24gbG9nKGxldmVsKSB7CgkJCQkJbGV2ZWwgPSBsb2dnZXIubG9va3VwTGV2ZWwobGV2ZWwpOwoKCQkJCQlpZiAodHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnICYmIGxvZ2dlci5sb29rdXBMZXZlbChsb2dnZXIubGV2ZWwpIDw9IGxldmVsKSB7CgkJCQkJCXZhciBtZXRob2QgPSBsb2dnZXIubWV0aG9kTWFwW2xldmVsXTsKCQkJCQkJaWYgKCFjb25zb2xlW21ldGhvZF0pIHsKCQkJCQkJCS8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tY29uc29sZQoJCQkJCQkJbWV0aG9kID0gJ2xvZyc7CgkJCQkJCX0KCgkJCQkJCWZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBtZXNzYWdlID0gQXJyYXkoX2xlbiA+IDEgPyBfbGVuIC0gMSA6IDApLCBfa2V5ID0gMTsgX2tleSA8IF9sZW47IF9rZXkrKykgewoJCQkJCQkJbWVzc2FnZVtfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07CgkJCQkJCX0KCgkJCQkJCWNvbnNvbGVbbWV0aG9kXS5hcHBseShjb25zb2xlLCBtZXNzYWdlKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1jb25zb2xlCgkJCQkJfQoJCQkJfQoJCQl9OwoKCQkJZXhwb3J0c1snZGVmYXVsdCddID0gbG9nZ2VyOwoJCQltb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsKCgkJCS8qKiovIH0sCgkJLyogMTcgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHsKCgkJCS8vIEJ1aWxkIG91dCBvdXIgYmFzaWMgU2FmZVN0cmluZyB0eXBlCgkJCSd1c2Ugc3RyaWN0JzsKCgkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgkJCWZ1bmN0aW9uIFNhZmVTdHJpbmcoc3RyaW5nKSB7CgkJCQl0aGlzLnN0cmluZyA9IHN0cmluZzsKCQkJfQoKCQkJU2FmZVN0cmluZy5wcm90b3R5cGUudG9TdHJpbmcgPSBTYWZlU3RyaW5nLnByb3RvdHlwZS50b0hUTUwgPSBmdW5jdGlvbiAoKSB7CgkJCQlyZXR1cm4gJycgKyB0aGlzLnN0cmluZzsKCQkJfTsKCgkJCWV4cG9ydHNbJ2RlZmF1bHQnXSA9IFNhZmVTdHJpbmc7CgkJCW1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOwoKCQkJLyoqKi8gfSwKCQkvKiAxOCAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJdmFyIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKVsnZGVmYXVsdCddOwoKCQkJdmFyIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDIpWydkZWZhdWx0J107CgoJCQlleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOwoJCQlleHBvcnRzLmNoZWNrUmV2aXNpb24gPSBjaGVja1JldmlzaW9uOwoJCQlleHBvcnRzLnRlbXBsYXRlID0gdGVtcGxhdGU7CgkJCWV4cG9ydHMud3JhcFByb2dyYW0gPSB3cmFwUHJvZ3JhbTsKCQkJZXhwb3J0cy5yZXNvbHZlUGFydGlhbCA9IHJlc29sdmVQYXJ0aWFsOwoJCQlleHBvcnRzLmludm9rZVBhcnRpYWwgPSBpbnZva2VQYXJ0aWFsOwoJCQlleHBvcnRzLm5vb3AgPSBub29wOwoKCQkJdmFyIF91dGlscyA9IF9fd2VicGFja19yZXF1aXJlX18oNCk7CgoJCQl2YXIgVXRpbHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfdXRpbHMpOwoKCQkJdmFyIF9leGNlcHRpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpOwoKCQkJdmFyIF9leGNlcHRpb24yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZXhjZXB0aW9uKTsKCgkJCXZhciBfYmFzZSA9IF9fd2VicGFja19yZXF1aXJlX18oMyk7CgoJCQlmdW5jdGlvbiBjaGVja1JldmlzaW9uKGNvbXBpbGVySW5mbykgewoJCQkJdmFyIGNvbXBpbGVyUmV2aXNpb24gPSBjb21waWxlckluZm8gJiYgY29tcGlsZXJJbmZvWzBdIHx8IDEsCgkJCQkJY3VycmVudFJldmlzaW9uID0gX2Jhc2UuQ09NUElMRVJfUkVWSVNJT047CgoJCQkJaWYgKGNvbXBpbGVyUmV2aXNpb24gIT09IGN1cnJlbnRSZXZpc2lvbikgewoJCQkJCWlmIChjb21waWxlclJldmlzaW9uIDwgY3VycmVudFJldmlzaW9uKSB7CgkJCQkJCXZhciBydW50aW1lVmVyc2lvbnMgPSBfYmFzZS5SRVZJU0lPTl9DSEFOR0VTW2N1cnJlbnRSZXZpc2lvbl0sCgkJCQkJCQljb21waWxlclZlcnNpb25zID0gX2Jhc2UuUkVWSVNJT05fQ0hBTkdFU1tjb21waWxlclJldmlzaW9uXTsKCQkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJ1RlbXBsYXRlIHdhcyBwcmVjb21waWxlZCB3aXRoIGFuIG9sZGVyIHZlcnNpb24gb2YgSGFuZGxlYmFycyB0aGFuIHRoZSBjdXJyZW50IHJ1bnRpbWUuICcgKyAnUGxlYXNlIHVwZGF0ZSB5b3VyIHByZWNvbXBpbGVyIHRvIGEgbmV3ZXIgdmVyc2lvbiAoJyArIHJ1bnRpbWVWZXJzaW9ucyArICcpIG9yIGRvd25ncmFkZSB5b3VyIHJ1bnRpbWUgdG8gYW4gb2xkZXIgdmVyc2lvbiAoJyArIGNvbXBpbGVyVmVyc2lvbnMgKyAnKS4nKTsKCQkJCQl9IGVsc2UgewoJCQkJCQkvLyBVc2UgdGhlIGVtYmVkZGVkIHZlcnNpb24gaW5mbyBzaW5jZSB0aGUgcnVudGltZSBkb2Vzbid0IGtub3cgYWJvdXQgdGhpcyByZXZpc2lvbiB5ZXQKCQkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJ1RlbXBsYXRlIHdhcyBwcmVjb21waWxlZCB3aXRoIGEgbmV3ZXIgdmVyc2lvbiBvZiBIYW5kbGViYXJzIHRoYW4gdGhlIGN1cnJlbnQgcnVudGltZS4gJyArICdQbGVhc2UgdXBkYXRlIHlvdXIgcnVudGltZSB0byBhIG5ld2VyIHZlcnNpb24gKCcgKyBjb21waWxlckluZm9bMV0gKyAnKS4nKTsKCQkJCQl9CgkJCQl9CgkJCX0KCgkJCWZ1bmN0aW9uIHRlbXBsYXRlKHRlbXBsYXRlU3BlYywgZW52KSB7CgkJCQkvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLwoJCQkJaWYgKCFlbnYpIHsKCQkJCQl0aHJvdyBuZXcgX2V4Y2VwdGlvbjJbJ2RlZmF1bHQnXSgnTm8gZW52aXJvbm1lbnQgcGFzc2VkIHRvIHRlbXBsYXRlJyk7CgkJCQl9CgkJCQlpZiAoIXRlbXBsYXRlU3BlYyB8fCAhdGVtcGxhdGVTcGVjLm1haW4pIHsKCQkJCQl0aHJvdyBuZXcgX2V4Y2VwdGlvbjJbJ2RlZmF1bHQnXSgnVW5rbm93biB0ZW1wbGF0ZSBvYmplY3Q6ICcgKyB0eXBlb2YgdGVtcGxhdGVTcGVjKTsKCQkJCX0KCgkJCQl0ZW1wbGF0ZVNwZWMubWFpbi5kZWNvcmF0b3IgPSB0ZW1wbGF0ZVNwZWMubWFpbl9kOwoKCQkJCS8vIE5vdGU6IFVzaW5nIGVudi5WTSByZWZlcmVuY2VzIHJhdGhlciB0aGFuIGxvY2FsIHZhciByZWZlcmVuY2VzIHRocm91Z2hvdXQgdGhpcyBzZWN0aW9uIHRvIGFsbG93CgkJCQkvLyBmb3IgZXh0ZXJuYWwgdXNlcnMgdG8gb3ZlcnJpZGUgdGhlc2UgYXMgcHN1ZWRvLXN1cHBvcnRlZCBBUElzLgoJCQkJZW52LlZNLmNoZWNrUmV2aXNpb24odGVtcGxhdGVTcGVjLmNvbXBpbGVyKTsKCgkJCQlmdW5jdGlvbiBpbnZva2VQYXJ0aWFsV3JhcHBlcihwYXJ0aWFsLCBjb250ZXh0LCBvcHRpb25zKSB7CgkJCQkJaWYgKG9wdGlvbnMuaGFzaCkgewoJCQkJCQljb250ZXh0ID0gVXRpbHMuZXh0ZW5kKHt9LCBjb250ZXh0LCBvcHRpb25zLmhhc2gpOwoJCQkJCQlpZiAob3B0aW9ucy5pZHMpIHsKCQkJCQkJCW9wdGlvbnMuaWRzWzBdID0gdHJ1ZTsKCQkJCQkJfQoJCQkJCX0KCgkJCQkJcGFydGlhbCA9IGVudi5WTS5yZXNvbHZlUGFydGlhbC5jYWxsKHRoaXMsIHBhcnRpYWwsIGNvbnRleHQsIG9wdGlvbnMpOwoJCQkJCXZhciByZXN1bHQgPSBlbnYuVk0uaW52b2tlUGFydGlhbC5jYWxsKHRoaXMsIHBhcnRpYWwsIGNvbnRleHQsIG9wdGlvbnMpOwoKCQkJCQlpZiAocmVzdWx0ID09IG51bGwgJiYgZW52LmNvbXBpbGUpIHsKCQkJCQkJb3B0aW9ucy5wYXJ0aWFsc1tvcHRpb25zLm5hbWVdID0gZW52LmNvbXBpbGUocGFydGlhbCwgdGVtcGxhdGVTcGVjLmNvbXBpbGVyT3B0aW9ucywgZW52KTsKCQkJCQkJcmVzdWx0ID0gb3B0aW9ucy5wYXJ0aWFsc1tvcHRpb25zLm5hbWVdKGNvbnRleHQsIG9wdGlvbnMpOwoJCQkJCX0KCQkJCQlpZiAocmVzdWx0ICE9IG51bGwpIHsKCQkJCQkJaWYgKG9wdGlvbnMuaW5kZW50KSB7CgkJCQkJCQl2YXIgbGluZXMgPSByZXN1bHQuc3BsaXQoJ1xuJyk7CgkJCQkJCQlmb3IgKHZhciBpID0gMCwgbCA9IGxpbmVzLmxlbmd0aDsgaSA8IGw7IGkrKykgewoJCQkJCQkJCWlmICghbGluZXNbaV0gJiYgaSArIDEgPT09IGwpIHsKCQkJCQkJCQkJYnJlYWs7CgkJCQkJCQkJfQoKCQkJCQkJCQlsaW5lc1tpXSA9IG9wdGlvbnMuaW5kZW50ICsgbGluZXNbaV07CgkJCQkJCQl9CgkJCQkJCQlyZXN1bHQgPSBsaW5lcy5qb2luKCdcbicpOwoJCQkJCQl9CgkJCQkJCXJldHVybiByZXN1bHQ7CgkJCQkJfSBlbHNlIHsKCQkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJ1RoZSBwYXJ0aWFsICcgKyBvcHRpb25zLm5hbWUgKyAnIGNvdWxkIG5vdCBiZSBjb21waWxlZCB3aGVuIHJ1bm5pbmcgaW4gcnVudGltZS1vbmx5IG1vZGUnKTsKCQkJCQl9CgkJCQl9CgoJCQkJLy8gSnVzdCBhZGQgd2F0ZXIKCQkJCXZhciBjb250YWluZXIgPSB7CgkJCQkJc3RyaWN0OiBmdW5jdGlvbiBzdHJpY3Qob2JqLCBuYW1lKSB7CgkJCQkJCWlmICghKG5hbWUgaW4gb2JqKSkgewoJCQkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJyInICsgbmFtZSArICciIG5vdCBkZWZpbmVkIGluICcgKyBvYmopOwoJCQkJCQl9CgkJCQkJCXJldHVybiBvYmpbbmFtZV07CgkJCQkJfSwKCQkJCQlsb29rdXA6IGZ1bmN0aW9uIGxvb2t1cChkZXB0aHMsIG5hbWUpIHsKCQkJCQkJdmFyIGxlbiA9IGRlcHRocy5sZW5ndGg7CgkJCQkJCWZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKCQkJCQkJCWlmIChkZXB0aHNbaV0gJiYgZGVwdGhzW2ldW25hbWVdICE9IG51bGwpIHsKCQkJCQkJCQlyZXR1cm4gZGVwdGhzW2ldW25hbWVdOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfSwKCQkJCQlsYW1iZGE6IGZ1bmN0aW9uIGxhbWJkYShjdXJyZW50LCBjb250ZXh0KSB7CgkJCQkJCXJldHVybiB0eXBlb2YgY3VycmVudCA9PT0gJ2Z1bmN0aW9uJyA/IGN1cnJlbnQuY2FsbChjb250ZXh0KSA6IGN1cnJlbnQ7CgkJCQkJfSwKCgkJCQkJZXNjYXBlRXhwcmVzc2lvbjogVXRpbHMuZXNjYXBlRXhwcmVzc2lvbiwKCQkJCQlpbnZva2VQYXJ0aWFsOiBpbnZva2VQYXJ0aWFsV3JhcHBlciwKCgkJCQkJZm46IGZ1bmN0aW9uIGZuKGkpIHsKCQkJCQkJdmFyIHJldCA9IHRlbXBsYXRlU3BlY1tpXTsKCQkJCQkJcmV0LmRlY29yYXRvciA9IHRlbXBsYXRlU3BlY1tpICsgJ19kJ107CgkJCQkJCXJldHVybiByZXQ7CgkJCQkJfSwKCgkJCQkJcHJvZ3JhbXM6IFtdLAoJCQkJCXByb2dyYW06IGZ1bmN0aW9uIHByb2dyYW0oaSwgZGF0YSwgZGVjbGFyZWRCbG9ja1BhcmFtcywgYmxvY2tQYXJhbXMsIGRlcHRocykgewoJCQkJCQl2YXIgcHJvZ3JhbVdyYXBwZXIgPSB0aGlzLnByb2dyYW1zW2ldLAoJCQkJCQkJZm4gPSB0aGlzLmZuKGkpOwoJCQkJCQlpZiAoZGF0YSB8fCBkZXB0aHMgfHwgYmxvY2tQYXJhbXMgfHwgZGVjbGFyZWRCbG9ja1BhcmFtcykgewoJCQkJCQkJcHJvZ3JhbVdyYXBwZXIgPSB3cmFwUHJvZ3JhbSh0aGlzLCBpLCBmbiwgZGF0YSwgZGVjbGFyZWRCbG9ja1BhcmFtcywgYmxvY2tQYXJhbXMsIGRlcHRocyk7CgkJCQkJCX0gZWxzZSBpZiAoIXByb2dyYW1XcmFwcGVyKSB7CgkJCQkJCQlwcm9ncmFtV3JhcHBlciA9IHRoaXMucHJvZ3JhbXNbaV0gPSB3cmFwUHJvZ3JhbSh0aGlzLCBpLCBmbik7CgkJCQkJCX0KCQkJCQkJcmV0dXJuIHByb2dyYW1XcmFwcGVyOwoJCQkJCX0sCgoJCQkJCWRhdGE6IGZ1bmN0aW9uIGRhdGEodmFsdWUsIGRlcHRoKSB7CgkJCQkJCXdoaWxlICh2YWx1ZSAmJiBkZXB0aC0tKSB7CgkJCQkJCQl2YWx1ZSA9IHZhbHVlLl9wYXJlbnQ7CgkJCQkJCX0KCQkJCQkJcmV0dXJuIHZhbHVlOwoJCQkJCX0sCgkJCQkJbWVyZ2U6IGZ1bmN0aW9uIG1lcmdlKHBhcmFtLCBjb21tb24pIHsKCQkJCQkJdmFyIG9iaiA9IHBhcmFtIHx8IGNvbW1vbjsKCgkJCQkJCWlmIChwYXJhbSAmJiBjb21tb24gJiYgcGFyYW0gIT09IGNvbW1vbikgewoJCQkJCQkJb2JqID0gVXRpbHMuZXh0ZW5kKHt9LCBjb21tb24sIHBhcmFtKTsKCQkJCQkJfQoKCQkJCQkJcmV0dXJuIG9iajsKCQkJCQl9LAoKCQkJCQlub29wOiBlbnYuVk0ubm9vcCwKCQkJCQljb21waWxlckluZm86IHRlbXBsYXRlU3BlYy5jb21waWxlcgoJCQkJfTsKCgkJCQlmdW5jdGlvbiByZXQoY29udGV4dCkgewoJCQkJCXZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8ge30gOiBhcmd1bWVudHNbMV07CgoJCQkJCXZhciBkYXRhID0gb3B0aW9ucy5kYXRhOwoKCQkJCQlyZXQuX3NldHVwKG9wdGlvbnMpOwoJCQkJCWlmICghb3B0aW9ucy5wYXJ0aWFsICYmIHRlbXBsYXRlU3BlYy51c2VEYXRhKSB7CgkJCQkJCWRhdGEgPSBpbml0RGF0YShjb250ZXh0LCBkYXRhKTsKCQkJCQl9CgkJCQkJdmFyIGRlcHRocyA9IHVuZGVmaW5lZCwKCQkJCQkJYmxvY2tQYXJhbXMgPSB0ZW1wbGF0ZVNwZWMudXNlQmxvY2tQYXJhbXMgPyBbXSA6IHVuZGVmaW5lZDsKCQkJCQlpZiAodGVtcGxhdGVTcGVjLnVzZURlcHRocykgewoJCQkJCQlpZiAob3B0aW9ucy5kZXB0aHMpIHsKCQkJCQkJCWRlcHRocyA9IGNvbnRleHQgIT09IG9wdGlvbnMuZGVwdGhzWzBdID8gW2NvbnRleHRdLmNvbmNhdChvcHRpb25zLmRlcHRocykgOiBvcHRpb25zLmRlcHRoczsKCQkJCQkJfSBlbHNlIHsKCQkJCQkJCWRlcHRocyA9IFtjb250ZXh0XTsKCQkJCQkJfQoJCQkJCX0KCgkJCQkJZnVuY3Rpb24gbWFpbihjb250ZXh0IC8qLCBvcHRpb25zKi8pIHsKCQkJCQkJcmV0dXJuICcnICsgdGVtcGxhdGVTcGVjLm1haW4oY29udGFpbmVyLCBjb250ZXh0LCBjb250YWluZXIuaGVscGVycywgY29udGFpbmVyLnBhcnRpYWxzLCBkYXRhLCBibG9ja1BhcmFtcywgZGVwdGhzKTsKCQkJCQl9CgkJCQkJbWFpbiA9IGV4ZWN1dGVEZWNvcmF0b3JzKHRlbXBsYXRlU3BlYy5tYWluLCBtYWluLCBjb250YWluZXIsIG9wdGlvbnMuZGVwdGhzIHx8IFtdLCBkYXRhLCBibG9ja1BhcmFtcyk7CgkJCQkJcmV0dXJuIG1haW4oY29udGV4dCwgb3B0aW9ucyk7CgkJCQl9CgkJCQlyZXQuaXNUb3AgPSB0cnVlOwoKCQkJCXJldC5fc2V0dXAgPSBmdW5jdGlvbiAob3B0aW9ucykgewoJCQkJCWlmICghb3B0aW9ucy5wYXJ0aWFsKSB7CgkJCQkJCWNvbnRhaW5lci5oZWxwZXJzID0gY29udGFpbmVyLm1lcmdlKG9wdGlvbnMuaGVscGVycywgZW52LmhlbHBlcnMpOwoKCQkJCQkJaWYgKHRlbXBsYXRlU3BlYy51c2VQYXJ0aWFsKSB7CgkJCQkJCQljb250YWluZXIucGFydGlhbHMgPSBjb250YWluZXIubWVyZ2Uob3B0aW9ucy5wYXJ0aWFscywgZW52LnBhcnRpYWxzKTsKCQkJCQkJfQoJCQkJCQlpZiAodGVtcGxhdGVTcGVjLnVzZVBhcnRpYWwgfHwgdGVtcGxhdGVTcGVjLnVzZURlY29yYXRvcnMpIHsKCQkJCQkJCWNvbnRhaW5lci5kZWNvcmF0b3JzID0gY29udGFpbmVyLm1lcmdlKG9wdGlvbnMuZGVjb3JhdG9ycywgZW52LmRlY29yYXRvcnMpOwoJCQkJCQl9CgkJCQkJfSBlbHNlIHsKCQkJCQkJY29udGFpbmVyLmhlbHBlcnMgPSBvcHRpb25zLmhlbHBlcnM7CgkJCQkJCWNvbnRhaW5lci5wYXJ0aWFscyA9IG9wdGlvbnMucGFydGlhbHM7CgkJCQkJCWNvbnRhaW5lci5kZWNvcmF0b3JzID0gb3B0aW9ucy5kZWNvcmF0b3JzOwoJCQkJCX0KCQkJCX07CgoJCQkJcmV0Ll9jaGlsZCA9IGZ1bmN0aW9uIChpLCBkYXRhLCBibG9ja1BhcmFtcywgZGVwdGhzKSB7CgkJCQkJaWYgKHRlbXBsYXRlU3BlYy51c2VCbG9ja1BhcmFtcyAmJiAhYmxvY2tQYXJhbXMpIHsKCQkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJ211c3QgcGFzcyBibG9jayBwYXJhbXMnKTsKCQkJCQl9CgkJCQkJaWYgKHRlbXBsYXRlU3BlYy51c2VEZXB0aHMgJiYgIWRlcHRocykgewoJCQkJCQl0aHJvdyBuZXcgX2V4Y2VwdGlvbjJbJ2RlZmF1bHQnXSgnbXVzdCBwYXNzIHBhcmVudCBkZXB0aHMnKTsKCQkJCQl9CgoJCQkJCXJldHVybiB3cmFwUHJvZ3JhbShjb250YWluZXIsIGksIHRlbXBsYXRlU3BlY1tpXSwgZGF0YSwgMCwgYmxvY2tQYXJhbXMsIGRlcHRocyk7CgkJCQl9OwoJCQkJcmV0dXJuIHJldDsKCQkJfQoKCQkJZnVuY3Rpb24gd3JhcFByb2dyYW0oY29udGFpbmVyLCBpLCBmbiwgZGF0YSwgZGVjbGFyZWRCbG9ja1BhcmFtcywgYmxvY2tQYXJhbXMsIGRlcHRocykgewoJCQkJZnVuY3Rpb24gcHJvZyhjb250ZXh0KSB7CgkJCQkJdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyB7fSA6IGFyZ3VtZW50c1sxXTsKCgkJCQkJdmFyIGN1cnJlbnREZXB0aHMgPSBkZXB0aHM7CgkJCQkJaWYgKGRlcHRocyAmJiBjb250ZXh0ICE9PSBkZXB0aHNbMF0pIHsKCQkJCQkJY3VycmVudERlcHRocyA9IFtjb250ZXh0XS5jb25jYXQoZGVwdGhzKTsKCQkJCQl9CgoJCQkJCXJldHVybiBmbihjb250YWluZXIsIGNvbnRleHQsIGNvbnRhaW5lci5oZWxwZXJzLCBjb250YWluZXIucGFydGlhbHMsIG9wdGlvbnMuZGF0YSB8fCBkYXRhLCBibG9ja1BhcmFtcyAmJiBbb3B0aW9ucy5ibG9ja1BhcmFtc10uY29uY2F0KGJsb2NrUGFyYW1zKSwgY3VycmVudERlcHRocyk7CgkJCQl9CgoJCQkJcHJvZyA9IGV4ZWN1dGVEZWNvcmF0b3JzKGZuLCBwcm9nLCBjb250YWluZXIsIGRlcHRocywgZGF0YSwgYmxvY2tQYXJhbXMpOwoKCQkJCXByb2cucHJvZ3JhbSA9IGk7CgkJCQlwcm9nLmRlcHRoID0gZGVwdGhzID8gZGVwdGhzLmxlbmd0aCA6IDA7CgkJCQlwcm9nLmJsb2NrUGFyYW1zID0gZGVjbGFyZWRCbG9ja1BhcmFtcyB8fCAwOwoJCQkJcmV0dXJuIHByb2c7CgkJCX0KCgkJCWZ1bmN0aW9uIHJlc29sdmVQYXJ0aWFsKHBhcnRpYWwsIGNvbnRleHQsIG9wdGlvbnMpIHsKCQkJCWlmICghcGFydGlhbCkgewoJCQkJCWlmIChvcHRpb25zLm5hbWUgPT09ICdAcGFydGlhbC1ibG9jaycpIHsKCQkJCQkJcGFydGlhbCA9IG9wdGlvbnMuZGF0YVsncGFydGlhbC1ibG9jayddOwoJCQkJCX0gZWxzZSB7CgkJCQkJCXBhcnRpYWwgPSBvcHRpb25zLnBhcnRpYWxzW29wdGlvbnMubmFtZV07CgkJCQkJfQoJCQkJfSBlbHNlIGlmICghcGFydGlhbC5jYWxsICYmICFvcHRpb25zLm5hbWUpIHsKCQkJCQkvLyBUaGlzIGlzIGEgZHluYW1pYyBwYXJ0aWFsIHRoYXQgcmV0dXJuZWQgYSBzdHJpbmcKCQkJCQlvcHRpb25zLm5hbWUgPSBwYXJ0aWFsOwoJCQkJCXBhcnRpYWwgPSBvcHRpb25zLnBhcnRpYWxzW3BhcnRpYWxdOwoJCQkJfQoJCQkJcmV0dXJuIHBhcnRpYWw7CgkJCX0KCgkJCWZ1bmN0aW9uIGludm9rZVBhcnRpYWwocGFydGlhbCwgY29udGV4dCwgb3B0aW9ucykgewoJCQkJb3B0aW9ucy5wYXJ0aWFsID0gdHJ1ZTsKCQkJCWlmIChvcHRpb25zLmlkcykgewoJCQkJCW9wdGlvbnMuZGF0YS5jb250ZXh0UGF0aCA9IG9wdGlvbnMuaWRzWzBdIHx8IG9wdGlvbnMuZGF0YS5jb250ZXh0UGF0aDsKCQkJCX0KCgkJCQl2YXIgcGFydGlhbEJsb2NrID0gdW5kZWZpbmVkOwoJCQkJaWYgKG9wdGlvbnMuZm4gJiYgb3B0aW9ucy5mbiAhPT0gbm9vcCkgewoJCQkJCW9wdGlvbnMuZGF0YSA9IF9iYXNlLmNyZWF0ZUZyYW1lKG9wdGlvbnMuZGF0YSk7CgkJCQkJcGFydGlhbEJsb2NrID0gb3B0aW9ucy5kYXRhWydwYXJ0aWFsLWJsb2NrJ10gPSBvcHRpb25zLmZuOwoKCQkJCQlpZiAocGFydGlhbEJsb2NrLnBhcnRpYWxzKSB7CgkJCQkJCW9wdGlvbnMucGFydGlhbHMgPSBVdGlscy5leHRlbmQoe30sIG9wdGlvbnMucGFydGlhbHMsIHBhcnRpYWxCbG9jay5wYXJ0aWFscyk7CgkJCQkJfQoJCQkJfQoKCQkJCWlmIChwYXJ0aWFsID09PSB1bmRlZmluZWQgJiYgcGFydGlhbEJsb2NrKSB7CgkJCQkJcGFydGlhbCA9IHBhcnRpYWxCbG9jazsKCQkJCX0KCgkJCQlpZiAocGFydGlhbCA9PT0gdW5kZWZpbmVkKSB7CgkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJ1RoZSBwYXJ0aWFsICcgKyBvcHRpb25zLm5hbWUgKyAnIGNvdWxkIG5vdCBiZSBmb3VuZCcpOwoJCQkJfSBlbHNlIGlmIChwYXJ0aWFsIGluc3RhbmNlb2YgRnVuY3Rpb24pIHsKCQkJCQlyZXR1cm4gcGFydGlhbChjb250ZXh0LCBvcHRpb25zKTsKCQkJCX0KCQkJfQoKCQkJZnVuY3Rpb24gbm9vcCgpIHsKCQkJCXJldHVybiAnJzsKCQkJfQoKCQkJZnVuY3Rpb24gaW5pdERhdGEoY29udGV4dCwgZGF0YSkgewoJCQkJaWYgKCFkYXRhIHx8ICEoJ3Jvb3QnIGluIGRhdGEpKSB7CgkJCQkJZGF0YSA9IGRhdGEgPyBfYmFzZS5jcmVhdGVGcmFtZShkYXRhKSA6IHt9OwoJCQkJCWRhdGEucm9vdCA9IGNvbnRleHQ7CgkJCQl9CgkJCQlyZXR1cm4gZGF0YTsKCQkJfQoKCQkJZnVuY3Rpb24gZXhlY3V0ZURlY29yYXRvcnMoZm4sIHByb2csIGNvbnRhaW5lciwgZGVwdGhzLCBkYXRhLCBibG9ja1BhcmFtcykgewoJCQkJaWYgKGZuLmRlY29yYXRvcikgewoJCQkJCXZhciBwcm9wcyA9IHt9OwoJCQkJCXByb2cgPSBmbi5kZWNvcmF0b3IocHJvZywgcHJvcHMsIGNvbnRhaW5lciwgZGVwdGhzICYmIGRlcHRoc1swXSwgZGF0YSwgYmxvY2tQYXJhbXMsIGRlcHRocyk7CgkJCQkJVXRpbHMuZXh0ZW5kKHByb2csIHByb3BzKTsKCQkJCX0KCQkJCXJldHVybiBwcm9nOwoJCQl9CgoJCQkvKioqLyB9LAoJCS8qIDE5ICovCgkJLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7CgoJCQkvKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi8oZnVuY3Rpb24oZ2xvYmFsKSB7LyogZ2xvYmFsIHdpbmRvdyAqLwoJCQkJJ3VzZSBzdHJpY3QnOwoKCQkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgoJCQkJZXhwb3J0c1snZGVmYXVsdCddID0gZnVuY3Rpb24gKEhhbmRsZWJhcnMpIHsKCQkJCQkvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLwoJCQkJCXZhciByb290ID0gdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWwgOiB3aW5kb3csCgkJCQkJCSRIYW5kbGViYXJzID0gcm9vdC5IYW5kbGViYXJzOwoJCQkJCS8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovCgkJCQkJSGFuZGxlYmFycy5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkgewoJCQkJCQlpZiAocm9vdC5IYW5kbGViYXJzID09PSBIYW5kbGViYXJzKSB7CgkJCQkJCQlyb290LkhhbmRsZWJhcnMgPSAkSGFuZGxlYmFyczsKCQkJCQkJfQoJCQkJCQlyZXR1cm4gSGFuZGxlYmFyczsKCQkJCQl9OwoJCQkJfTsKCgkJCQltb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsKCQkJCS8qIFdFQlBBQ0sgVkFSIElOSkVDVElPTiAqL30uY2FsbChleHBvcnRzLCAoZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KCkpKSkKCgkJCS8qKiovIH0KCQkvKioqKioqLyBdKQp9KTsKOwovKioKICogICAgeGJlNHggaXMgamF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgb3JpZ2luYWwgRUNNQVNjcmlwdCBmb3IgWE1MIChFNFgpCiAqICAgIFNwZWNpZmljYXRpb24gKEVDTUEtMzU3KSBEZWNlbWJlciAyMDA1LiBUaGlzIGltcGxlbWVudGF0aW9uIGlzIGRlc2lnbmVkIHRvIGVtdWxhdGUKICogICAgdGhlIGltcGxlbWVudGF0aW9uIHRoYXQgaXMgdXNlZCBpbiBTcGlkZXJNb25rZXkgKE1vemlsbGEncyBKYXZhU2NyaXB0KFRNKSBFbmdpbmUpCiAqICAgIGFuZCB0aGVyZWZvcmUgRmlyZWZveCwgVGh1bmRlcmJpcmQsIGFuZCBtb3N0IG90aGVyIEdlY2tvIGJhc2VkIGFwcGxpY2F0aW9ucy4KICogICAgQmVjYXVzZSB0aGUgTW96aWxsYSBpbXBsZW1lbnRhdGlvbiBsZWF2ZXMgb3V0IGNlcnRhaW4gZmVhdHVyZXMgb2YgdGhlCiAqICAgIHNwZWNpZmljYXRpb24sIHNvIGRvZXMgeGJlNHguIFBsZWFzZSByZWFkIHRoZSBSRUFETUUgZmlsZSBmb3IgYSBmdXJ0aGVyCiAqICAgIGV4cGxhbmF0aW9uIG9mIHRoZXNlIGlzc3Vlcy4KICoKICoKICogICAgQGF1dGhvciBTYW0gU2h1bGwgPGh0dHA6Ly9zYW1zaHVsbC5ibG9nc3BvdC5jb20vPgogKiAgICBAdmVyc2lvbiAwLjEKICoKICogICAgQGNvcHlyaWdodCBDb3B5cmlnaHQgKGMpIDIwMDkgU2FtIFNodWxsIDxodHRwOi8vc2Ftc2h1bGwuYmxvZ3Nwb3QuY29tLz4KICogICAgQGxpY2Vuc2UgPGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UuaHRtbD4KICoKICogICAgUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQogKiAgICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAogKiAgICBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCiAqICAgIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKICogICAgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCiAqICAgIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiAqCiAqICAgIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCiAqICAgIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgogKgogKiAgICBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgogKiAgICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogICAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiAqICAgIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKICogICAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKICogICAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgogKiAgICBUSEUgU09GVFdBUkUuCiAqCiAqCiAqICAgIENIQU5HRVM6CiAqLwoKLy90aGlzIGRvZXNuJ3QgbG9hZCBpZiB3aW5kb3cuWE1MIGlzIGFscmVhZHkgZGVmaW5lZAppZiAoIXRoaXMuWE1MKQp7CiAgICAoZnVuY3Rpb24gKCkKICAgIHsKICAgICAgICAvKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICB2YXIgdW5kZWZpbmVkLCBwLAogICAgICAgICAgICB3aW5kb3cgICAgICAgICAgICAgICAgICAgICAgID0gdGhpcywKICAgICAgICAgICAgZG5zICAgICAgICAgICAgICAgICAgICAgICAgICA9IFtdLAogICAgICAgICAgICBkZWZhdWx0TmFtZXNwYWNlICAgICAgICAgICAgID0gIiIsCiAgICAgICAgICAgIEVMRU1FTlRfTk9ERSAgICAgICAgICAgICAgICAgPSAxLAogICAgICAgICAgICBBVFRSSUJVVEVfTk9ERSAgICAgICAgICAgICAgID0gMiwKICAgICAgICAgICAgVEVYVF9OT0RFICAgICAgICAgICAgICAgICAgICA9IDMsCiAgICAgICAgICAgIENEQVRBX1NFQ1RJT05fTk9ERSAgICAgICAgICAgPSA0LAogICAgICAgICAgICBFTlRJVFlfUkVGRVJFTkNFX05PREUgICAgICAgID0gNSwKICAgICAgICAgICAgRU5USVRZX05PREUgICAgICAgICAgICAgICAgICA9IDYsCiAgICAgICAgICAgIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSAgPSA3LAogICAgICAgICAgICBDT01NRU5UX05PREUgICAgICAgICAgICAgICAgID0gOCwKICAgICAgICAgICAgRE9DVU1FTlRfTk9ERSAgICAgICAgICAgICAgICA9IDksCiAgICAgICAgICAgIERPQ1VNRU5UX1RZUEVfTk9ERSAgICAgICAgICAgPSAxMCwKICAgICAgICAgICAgRE9DVU1FTlRfRlJBR01FTlRfTk9ERSAgICAgICA9IDExLAogICAgICAgICAgICBOT1RBVElPTl9OT0RFICAgICAgICAgICAgICAgID0gMTIsCiAgICAgICAgICAgIGlzTlNEZWYgICAgICAgICAgICAgICAgICAgICAgPSAvXnhtbG5zOihbXHdcLV0rKS9pLAogICAgICAgICAgICB0b1N0cmluZyAgICAgICAgICAgICAgICAgICAgID0gKHt9KS50b1N0cmluZywKICAgICAgICAgICAgcHJvcGVydHlJc0VudW1lcmFibGUgICAgICAgICA9ICh7fSkucHJvcGVydHlJc0VudW1lcmFibGUsCiAgICAgICAgICAgIGhhc093blByb3BlcnR5ICAgICAgICAgICAgICAgPSAoe30pLmhhc093blByb3BlcnR5LAogICAgICAgICAgICBkZWZhdWx0WE1MUHJvcGVydGllcyAgICAgICAgID0gIixwcm90b3R5cGUsaWdub3JlQ29tbWVudHMsaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucyxpZ25vcmVXaGl0ZXNwYWNlLCIgKwogICAgICAgICAgICAgICAgInByZXR0eVByaW50aW5nLHByZXR0eUluZGVudCxzZXR0aW5ncyxkZWZhdWx0U2V0dGluZ3Msc2V0U2V0dGluZ3Msc2V0dGluZ3MsIiArCiAgICAgICAgICAgICAgICAicHJvcGVydHlJc0VudW1lcmFibGUsaGFzT3duUHJvcGVydHksX3NldERlZmF1bHROYW1lc3BhY2UsIiwKICAgICAgICAgICAgZGVmYXVsdFhNTFByb3RvdHlwZSAgICAgICAgICA9ICIsX0NsYXNzLF9OYW1lLF9QYXJlbnQsX1ZhbHVlLF9JblNjb3BlTmFtZXNwYWNlcyxfQXR0cmlidXRlcyxfQ2hpbGRyZW4sX05vZGUiLAogICAgICAgICAgICBkZWZhdWx0WE1MTGlzdFByb3RvdHlwZSAgICAgID0gIixfQ2xhc3MsX1ZhbHVlLF9DaGlsZHJlbixfVGFyZ2V0T2JqZWN0LF9UYXJnZXRQcm9wZXJ0eSIsCiAgICAgICAgICAgIHhtbERvYyAgICAgICAgICAgICAgICAgICAgICAgPSBwYXJzZSgiPHgvPiIpLAogICAgICAgICAgICBwaU5hbWUgICAgICAgICAgICAgICAgICAgICAgID0gL15bXHdcLV0rXHMqLywKICAgICAgICAgICAgWFNMVF9OUyAgICAgICAgICAgICAgICAgICAgICA9ICJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iOwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFhNTCAkc3RyaW5nCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICogICAgQHRocm93cyBTeW50YXhFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFhNTCAoJHN0cmluZykKICAgICAgICB7CiAgICAgICAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBYTUwpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gVG9YTUwoJHN0cmluZyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciB4LCBpLCBsOwoKICAgICAgICAgICAgdGhpcy5fQ2xhc3MgPSAidGV4dCI7CgogICAgICAgICAgICB0aGlzLl9OYW1lID0gbnVsbDsKCiAgICAgICAgICAgIHRoaXMuX1ZhbHVlID0gbnVsbDsKCiAgICAgICAgICAgIHRoaXMuX1BhcmVudCA9IG51bGw7CgogICAgICAgICAgICB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcyA9IHt9OwoKICAgICAgICAgICAgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSA9IG51bGw7CgogICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzID0ge307CgogICAgICAgICAgICB0aGlzLl9DaGlsZHJlbiA9IFtdOwoKICAgICAgICAgICAgdGhpc1swXSA9IHRoaXM7CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICoKICAgICAgICAgICAgICoKICAgICAgICAgICAgICoKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHN3aXRjaCAodHlwZW9mKCRzdHJpbmcpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlICJ1bmRlZmluZWQiOgogICAgICAgICAgICAgICAgY2FzZSAibnVsbCI6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJudW1iZXIiOgogICAgICAgICAgICAgICAgY2FzZSAiYm9vbGVhbiI6ICAgICRzdHJpbmcgPSBUb1N0cmluZygkc3RyaW5nKTsKICAgICAgICAgICAgICAgIGNhc2UgInN0cmluZyI6CgogICAgICAgICAgICAgICAgICAgIHggPSBUb1hNTCh0cmltKCRzdHJpbmcpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoeCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4Lmxlbmd0aCgpID09PTEpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NsYXNzID0geC5fQ2xhc3M7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9OYW1lID0geC5fTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX1ZhbHVlID0geC5fVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcyA9IHguX0luU2NvcGVOYW1lc3BhY2VzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSA9IHguX0RlZmF1bHROYW1lc3BhY2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzID0geC5fQXR0cmlidXRlczsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0geC5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldID0geC5fQ2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0uX1BhcmVudCA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcigpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBpZiAoJHN0cmluZyBpbnN0YW5jZW9mIFhNTCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkc3RyaW5nLmxlbmd0aCgpID09PTEpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAkc3RyaW5nOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2xhc3MgPSB4Ll9DbGFzczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX05hbWUgPSB4Ll9OYW1lOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fVmFsdWUgPSB4Ll9WYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzID0geC5fSW5TY29wZU5hbWVzcGFjZXM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlID0geC5fRGVmYXVsdE5hbWVzcGFjZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0F0dHJpYnV0ZXMgPSB4Ll9BdHRyaWJ1dGVzOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSB4Ll9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0gPSB4Ll9DaGlsZHJlbltpXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXS5fUGFyZW50ID0gdGhpczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogICAgSWdub3JlIFhNTCBjb21tZW50cy4gKERlZmF1bHQ6IHRydWUuKQogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEBwYXJhbSBOYW1lc3BhY2UgbnMKICAgICAgICAgKiAgICBAcmV0dXJucyB2b2lkCiAgICAgICAgICovCiAgICAgICAgWE1MLnNldERlZmF1bHROYW1lc3BhY2UgPSBmdW5jdGlvbiAobnMpCiAgICAgICAgewogICAgICAgICAgICBkbnMudW5zaGlmdChkZWZhdWx0TmFtZXNwYWNlIHx8ICIiKTsKICAgICAgICAgICAgZGVmYXVsdE5hbWVzcGFjZSA9IE5hbWVzcGFjZShucyk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqICBVc2UgdGhpcyBmdW5jdGlvbiB0byByZXN0b3JlIHRoZSBkZWZhdWx0IG5hbWVzcGFjZQogICAgICAgICAqICB0byB0aGUgcHJldmlvdXMgbmFtZXNwYWNlCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICBYTUwucmVzdG9yZURlZmF1bHROYW1lc3BhY2UgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgZGVmYXVsdE5hbWVzcGFjZSA9IGRucy5zaGlmdCgpIHx8ICIiOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICBYTUwubG9hZCA9IGZ1bmN0aW9uIChwYXRoVG9GaWxlLCBvbmxvYWQpCiAgICAgICAgewogICAgICAgICAgICB2YXIgeGhyID0gaXNBY3RpdmVYU3VwcG9ydGVkKCJNaWNyb3NvZnQuWE1MSFRUUCIpICYmIG5ldyBBY3RpdmVYT2JqZWN0KCJNaWNyb3NvZnQuWE1MSFRUUCIpIHx8IG5ldyBYTUxIdHRwUmVxdWVzdCgpLAogICAgICAgICAgICAgICAgYXN5bmMgPSAoe30pLnRvU3RyaW5nLmNhbGwob25sb2FkIHx8IHt9KSA9PSAiW29iamVjdCBGdW5jdGlvbl0iOwoKICAgICAgICAgICAgeGhyLm9wZW4oIkdFVCIsIHBhdGhUb0ZpbGUsIGFzeW5jKTsKCiAgICAgICAgICAgIGlmIChhc3luYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCEheGhyLmFkZEV2ZW50TGlzdGVuZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeGhyLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLCBsb2FkZWQsIGZhbHNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PSA0ICYmIHhoci5zdGF0dXMgPT0gMjAwKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2FkZWQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHhoci5zZW5kKG51bGwpOwoKICAgICAgICAgICAgcmV0dXJuIGFzeW5jID8geGhyIDogbG9hZGVkKDEpOwoKICAgICAgICAgICAgZnVuY3Rpb24gbG9hZGVkIChyZXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciB4ID0gbmV3IFhNTCgoeGhyLnJlc3BvbnNlVGV4dHx8IiIpLnJlcGxhY2UoL1xzKjxcP3htbC4qP1w/Pi8sIiIpKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXQgPyB4IDogb25sb2FkKHgpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICogICAgSWdub3JlIFhNTCBjb21tZW50cy4gKERlZmF1bHQ6IHRydWUuKQogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEB2YXIgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5pZ25vcmVDb21tZW50cyA9IHRydWU7CgogICAgICAgIC8qKgogICAgICAgICAqICAgIElnbm9yZSBYTUwgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMuIChEZWZhdWx0OiB0cnVlLikKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAdmFyIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUwuaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucyA9IHRydWU7CgogICAgICAgIC8qKgogICAgICAgICAqICAgIElnbm9yZSB3aGl0ZXNwYWNlLiAoRGVmYXVsdDogdHJ1ZS4pCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHZhciBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLmlnbm9yZVdoaXRlc3BhY2UgPSB0cnVlOwoKICAgICAgICAvKioKICAgICAgICAgKiAgICBQcmV0dHktcHJpbnQgWE1MIG91dHB1dCB3aXRoIHRvWE1MU3RyaW5nKCkgZXRjLiAoRGVmYXVsdDogdHJ1ZS4pCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHZhciBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByZXR0eVByaW50aW5nID0gdHJ1ZTsKCiAgICAgICAgLyoqCiAgICAgICAgICogICAgUHJldHR5IGluZGVudCBsZXZlbCBmb3IgY2hpbGQgbm9kZXMuIChEZWZhdWx0OiAyLikKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAdmFyIE51bWJlcgogICAgICAgICAqLwogICAgICAgIFhNTC5wcmV0dHlJbmRlbnQgPSAyOwoKICAgICAgICAvL1RoZXJlIGFyZSBhbHNvIHRocmVlIG1ldGhvZHMgdG8gbW9yZSBlYXNpbHkgYXBwbHkgYW5kIHJlc3RvcmUgc2V0dGluZ3MgZm9yIHVzZSwgc2F5LCB3aXRoaW4gYSBmdW5jdGlvbi4KCiAgICAgICAgLyoqCiAgICAgICAgICogICAgR2V0IGFuIE9iamVjdCBjb250YWluaW5nIHRoZSBhYm92ZSBzZXR0aW5ncy4KICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAcmV0dXJucyBPYmplY3QKICAgICAgICAgKi8KICAgICAgICBYTUwuc2V0dGluZ3MgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgIGlnbm9yZUNvbW1lbnRzOiAgICAgICAgICAgICAgICAgWE1MLmlnbm9yZUNvbW1lbnRzLAogICAgICAgICAgICAgICAgaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9uczogICBYTUwuaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucywKICAgICAgICAgICAgICAgIGlnbm9yZVdoaXRlc3BhY2U6ICAgICAgICAgICAgICAgWE1MLmlnbm9yZVdoaXRlc3BhY2UsCiAgICAgICAgICAgICAgICBwcmV0dHlQcmludGluZzogICAgICAgICAgICAgICAgIFhNTC5wcmV0dHlQcmludGluZywKICAgICAgICAgICAgICAgIHByZXR0eUluZGVudDogICAgICAgICAgICAgICAgICAgWE1MLnByZXR0eUluZGVudAogICAgICAgICAgICB9OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqICAgIEdldCBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgZGVmYXVsdCBzZXR0aW5ncy4KICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAcmV0dXJucyBPYmplY3QKICAgICAgICAgKi8KICAgICAgICBYTUwuZGVmYXVsdFNldHRpbmdzID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICBpZ25vcmVDb21tZW50czogICAgICAgICAgICAgICAgIHRydWUsCiAgICAgICAgICAgICAgICBpZ25vcmVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25zOiAgIHRydWUsCiAgICAgICAgICAgICAgICBpZ25vcmVXaGl0ZXNwYWNlOiAgICAgICAgICAgICAgIHRydWUsCiAgICAgICAgICAgICAgICBwcmV0dHlQcmludGluZzogICAgICAgICAgICAgICAgIHRydWUsCiAgICAgICAgICAgICAgICBwcmV0dHlJbmRlbnQ6ICAgICAgICAgICAgICAgICAgIDIKICAgICAgICAgICAgfTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKiAgICBTZXQgWE1MIHNldHRpbmdzIGZyb20sIGUuZy4sIGFuIG9iamVjdCByZXR1cm5lZCBieSBYTUwuc2V0dGluZ3MoKS4KICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEBwYXJhbSBPYmplY3Qgc2V0dGluZ3MKICAgICAgICAgKiAgICBAcmV0dXJucyB2b2lkCiAgICAgICAgICovCiAgICAgICAgWE1MLnNldFNldHRpbmdzID0gZnVuY3Rpb24gKHNldHRpbmdzKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHA7CiAgICAgICAgICAgIHNldHRpbmdzID0gc2V0dGluZ3MgfHwgWE1MLnNldHRpbmdzKCk7CiAgICAgICAgICAgIGZvciAocCBpbiBzZXR0aW5ncykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3dpdGNoIChwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhc2UgImlnbm9yZUNvbW1lbnRzIjogICAgICAgICAgICAgICAgICAgWE1MLmlnbm9yZUNvbW1lbnRzID0gISFzZXR0aW5nc1twXTsKICAgICAgICAgICAgICAgICAgICBjYXNlICJpZ25vcmVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25zIjogICAgIFhNTC5pZ25vcmVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25zID0gISFzZXR0aW5nc1twXTsKICAgICAgICAgICAgICAgICAgICBjYXNlICJpZ25vcmVXaGl0ZXNwYWNlIjogICAgICAgICAgICAgICAgIFhNTC5pZ25vcmVXaGl0ZXNwYWNlID0gISFzZXR0aW5nc1twXTsKICAgICAgICAgICAgICAgICAgICBjYXNlICJwcmV0dHlQcmludGluZyI6ICAgICAgICAgICAgICAgICAgIFhNTC5wcmV0dHlQcmludGluZyA9ICEhc2V0dGluZ3NbcF07CiAgICAgICAgICAgICAgICAgICAgY2FzZSAicHJldHR5SW5kZW50IjogICAgICAgICAgICAgICAgICAgICBYTUwucHJldHR5SW5kZW50ID0gcGFyc2VJbnQoc2V0dGluZ3NbcF0pIHx8IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLmhhc093blByb3BlcnR5ID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZGVmYXVsdFhNTFByb3BlcnRpZXMuaW5kZXhPZigiLCIgKyBuYW1lICsgIiwiKSA9PT0tMQogICAgICAgICAgICAgICAgJiYgaGFzT3duUHJvcGVydHkuY2FsbChYTUwsIG5hbWUpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm9wZXJ0eUlzRW51bWVyYWJsZSA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5hbWUgIT09ICJwcm90b3R5cGUiCiAgICAgICAgICAgICAgICAmJiBuYW1lIGluIFhNTAogICAgICAgICAgICAgICAgJiYgdG9TdHJpbmcuY2FsbChYTUxbbmFtZV0pICE9ICJbb2JqZWN0IEZ1bmN0aW9uXSIKICAgICAgICAgICAgICAgICYmIHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwoWE1MLCBuYW1lKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIFhNTC50b1N0cmluZyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gImZ1bmN0aW9uIFhNTCgpIHtcbiBbbmF0aXZlIGNvZGVdIFxufSI7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBOYW1lc3BhY2UgbmFtZXNwYWNlCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5hZGROYW1lc3BhY2UgPSBmdW5jdGlvbiAobmFtZXNwYWNlKQogICAgICAgIHsKICAgICAgICAgICAgQWRkSW5TY29wZU5hbWVzcGFjZS5jYWxsKHRoaXMsIE5hbWVzcGFjZShuYW1lc3BhY2UpKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgY2hpbGQKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmFwcGVuZENoaWxkID0gZnVuY3Rpb24gKGNoaWxkLGlzQ2hpbGRFbGVtZW50KQogICAgICAgIHsKICAgICAgICAgICAgaXNDaGlsZEVsZW1lbnQgPSBpc0NoaWxkRWxlbWVudCAhPT0gdW5kZWZpbmVkID8gaXNDaGlsZEVsZW1lbnQgOiBmYWxzZTsKICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gR2V0LmNhbGwodGhpcywgIioiKTsKICAgICAgICAgICAgY2hpbGRyZW4uUHV0KGNoaWxkcmVuLmxlbmd0aCgpLCBjaGlsZCxpc0NoaWxkRWxlbWVudCk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgQXR0cmlidXRlTmFtZSB8IFFOYW1lIGF0dHJpYnV0ZU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmF0dHJpYnV0ZSA9IGZ1bmN0aW9uIChhdHRyaWJ1dGVOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIEdldC5jYWxsKHRoaXMsIFRvQXR0cmlidXRlTmFtZShhdHRyaWJ1dGVOYW1lKSwgdHJ1ZSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmF0dHJpYnV0ZXMgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIEdldC5jYWxsKHRoaXMsIFRvQXR0cmlidXRlTmFtZSgiKiIpKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBwcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5jaGlsZCA9IGZ1bmN0aW9uIChwcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICB2YXIgdGVtcG9yYXJ5OwoKICAgICAgICAgICAgaWYgKHBhcnNlSW50KHByb3BlcnR5TmFtZSkrIiIgPT0gcHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0ZW1wb3JhcnkgPSBHZXQuY2FsbCh0aGlzLCAiKiIpOwogICAgICAgICAgICAgICAgdGVtcG9yYXJ5ID0gR2V0TGlzdC5jYWxsKHRlbXBvcmFyeSwgcHJvcGVydHlOYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiB0ZW1wb3JhcnkgfHwgbmV3IFhNTExpc3QoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGVtcG9yYXJ5ID0gVG9YTUxMaXN0KCBHZXQuY2FsbCh0aGlzLCBwcm9wZXJ0eU5hbWUpICk7CgogICAgICAgICAgICByZXR1cm4gdGVtcG9yYXJ5OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBOdW1iZXIKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmNoaWxkSW5kZXggPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHBhcmVudCA9IHRoaXMuX1BhcmVudCwgcSwgbDsKCiAgICAgICAgICAgIGlmICghcGFyZW50IHx8IHRoaXMuX0NsYXNzID09PSAiYXR0cmlidXRlIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHEgPSAwLCBsID0gcGFyZW50Ll9DaGlsZHJlbi5sZW5ndGg7IHEgPCBsOyArK3EpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwYXJlbnQuX0NoaWxkcmVuW3FdID09PSB0aGlzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmNoaWxkcmVuID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBHZXQuY2FsbCh0aGlzLCAiKiIpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5jb21tZW50cyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRQcm9wZXJ0eSA9IG51bGw7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gImNvbW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRoaXMuX0NoaWxkcmVuW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBYTUwgdmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uICh2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0aGlzID09IHZhbHVlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIERlZXBDb3B5LmNhbGwodGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuZGVzY2VuZGFudHMgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBEZXNjZW5kYW50cy5jYWxsKHRoaXMsIG5hbWUgfHwgIioiKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIHwgQXR0cmlidXRlTmFtZSBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuZWxlbWVudHMgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIG5hbWUgPSBUb1hNTE5hbWUobmFtZSB8fCAiKiIpOwogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRQcm9wZXJ0eSA9IG5hbWU7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiCiAgICAgICAgICAgICAgICAgICAgJiYgKG5hbWUubG9jYWxOYW1lID09PSAiKiIgfHwgbmFtZS5sb2NhbE5hbWUgPT09IHRoaXMuX0NoaWxkcmVuW2ldLl9OYW1lLmxvY2FsTmFtZSkKICAgICAgICAgICAgICAgICAgICAmJiAobmFtZS51cmkgPT0gbnVsbCB8fCBuYW1lLnVyaSA9PT0gdGhpcy5fQ2hpbGRyZW5baV0uX05hbWUudXJpKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRoaXMuX0NoaWxkcmVuW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmhhc093blByb3BlcnR5ID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gSGFzUHJvcGVydHkuY2FsbCh0aGlzLCBuYW1lKSB8fCAoZGVmYXVsdFhNTFByb3RvdHlwZS5pbmRleE9mKCIsIiArIG5hbWUgKyIsIikgPT09IC0xICYmIGhhc093blByb3BlcnR5LmNhbGwodGhpcywgbmFtZSkpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5oYXNDb21wbGV4Q29udGVudCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsYXR0cmlidXRlLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5oYXNTaW1wbGVDb250ZW50ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIixjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIEFycmF5CiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5pblNjb3BlTmFtZXNwYWNlcyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgeSA9IHRoaXMsIGluU2NvcGVOUyA9IHt9LCBwLCBhID0gW107CgogICAgICAgICAgICB3aGlsZSAoeSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChwIGluIHkuX0luU2NvcGVOYW1lc3BhY2VzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICghaW5TY29wZU5TW3BdKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW5TY29wZU5TW3BdID0geS5fSW5TY29wZU5hbWVzcGFjZXNbcF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHkgPSB5LnBhcmVudCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5fRGVmYXVsdE5hbWVzcGFjZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW5TY29wZU5TWyIiXSA9IHRoaXMuX0RlZmF1bHROYW1lc3BhY2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAocCBpbiBpblNjb3BlTlMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGFbYS5sZW5ndGhdID0gaW5TY29wZU5TW3BdOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gYTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBjaGlsZDEKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIGNoaWxkMgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTCB8IG51bGwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmluc2VydENoaWxkQWZ0ZXIgPSBmdW5jdGlvbiAoY2hpbGQxLCBjaGlsZDIpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsYXR0cmlidXRlLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgLy90aGlzIGlzIGRpc2FibGVkLCBiZWNhdXNlIGl0IGRvZXNuJ3Qgd29yayBpbgogICAgICAgICAgICAgLy9GaXJlZm94IGFjY29yZGluZyB0byB0aGUgc3BlYwogICAgICAgICAgICAgaWYgKCFjaGlsZDIpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCAwLCBjaGlsZDEpOwogICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICBlbHNlIGlmICghY2hpbGQxKQogICAgICAgICAgICAgewogICAgICAgICAgICAgSW5zZXJ0LmNhbGwodGhpcywgMCwgY2hpbGQyKTsKICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGlmICghY2hpbGQxKXsKICAgICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIDAsIGNoaWxkMik7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWNoaWxkMil7CiAgICAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCAwLCBjaGlsZDEpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjaGlsZDEgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIGNoaWxkMS5jaGlsZEluZGV4KCkgKyAxLCBjaGlsZDIpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBYTUwgY2hpbGQxCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBjaGlsZDIKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwgfCBudWxsCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5pbnNlcnRDaGlsZEJlZm9yZSA9IGZ1bmN0aW9uIChjaGlsZDEsIGNoaWxkMikKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIixhdHRyaWJ1dGUsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLHRleHQsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAvL3RoaXMgaXMgZGlzYWJsZWQsIGJlY2F1c2UgaXQgZG9lc24ndCB3b3JrIGluCiAgICAgICAgICAgICAvL0ZpcmVmb3ggYWNjb3JkaW5nIHRvIHRoZSBzcGVjCiAgICAgICAgICAgICBpZiAoIWNoaWxkMSkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIHRoaXMuX0NoaWxkcmVuLmxlbmd0aCwgY2hpbGQyKTsKICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgZWxzZSBpZiAoIWNoaWxkMikKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIHRoaXMuX0NoaWxkcmVuLmxlbmd0aCwgY2hpbGQxKTsKICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGlmIChjaGlsZDEgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIGNoaWxkMS5jaGlsZEluZGV4KCksIGNoaWxkMik7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIE51bWJlcgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUubGVuZ3RoID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcgfCBudWxsCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5sb2NhbE5hbWUgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX05hbWUgPT09IG51bGwgPyBudWxsIDogdGhpcy5fTmFtZS5sb2NhbE5hbWU7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIHJldHVybiBRTmFtZQogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUubmFtZSA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdGhpcy5fTmFtZTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBwcmVmaXgKICAgICAgICAgKiAgICBAcmV0dXJucyBOYW1lc3BhY2UKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLm5hbWVzcGFjZSA9IGZ1bmN0aW9uIChwcmVmaXgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgeSA9IHRoaXMsIGluU2NvcGVOUyA9IHt9LCBwOwoKICAgICAgICAgICAgd2hpbGUgKHkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAocCBpbiB5Ll9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWluU2NvcGVOU1twXSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGluU2NvcGVOU1twXSA9IHkuX0luU2NvcGVOYW1lc3BhY2VzW3BdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB5ID0geS5wYXJlbnQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHByZWZpeCA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoKCIsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLHRleHQsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gR2V0TmFtZXNwYWNlKHRoaXMuX05hbWUsIGluU2NvcGVOUyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByZWZpeCA9IFRvU3RyaW5nKHByZWZpeCk7CgogICAgICAgICAgICBmb3IgKHAgaW4gaW5TY29wZU5TKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoaW5TY29wZU5TW3BdLnByZWZpeCA9PT0gcHJlZml4KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpblNjb3BlTlNbcF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBBcnJheQogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUubmFtZXNwYWNlRGVjbGFyYXRpb25zID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIixhdHRyaWJ1dGUsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLHRleHQsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIFtdOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgYSA9IFtdLCB5ID0gdGhpcy5fUGFyZW50LCBhbmNlc3Rvck5TID0ge30sIHA7CgogICAgICAgICAgICB3aGlsZSAoeSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChwIGluIHkuX0luU2NvcGVOYW1lc3BhY2VzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICghYW5jZXN0b3JOU1twXSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yTlNbcF0gPSB5Ll9JblNjb3BlTmFtZXNwYWNlc1twXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgeSA9IHkuX1BhcmVudDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChwIGluIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocCAhPSAiIiAmJiAoIWFuY2VzdG9yTlNbcF0gfHwgYW5jZXN0b3JOU1twXS51cmkgIT0gdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbcF0pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFbYS5sZW5ndGhdID0gdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbcF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKHAgPT09ICIiICYmICF0aGlzLl9QYXJlbnQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYVthLmxlbmd0aF0gPSB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1twXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGE7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUubm9kZUtpbmQgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX0NsYXNzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5baV0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0ubm9ybWFsaXplKCk7CiAgICAgICAgICAgICAgICAgICAgKytpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fQ2hpbGRyZW5baV0uX0NsYXNzID09PSAidGV4dCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGkrMSA8IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCAmJiB0aGlzLl9DaGlsZHJlbltpKzFdLl9DbGFzcyA9PT0gInRleHQiKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0uX1ZhbHVlID0gKHRoaXMuX0NoaWxkcmVuW2ldLl9WYWx1ZSB8fCAiIikgKyAodGhpcy5fQ2hpbGRyZW5baSsxXS5fVmFsdWUgfHwgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICBEZWxldGVCeUluZGV4LmNhbGwodGhpcywgaSsxKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fVmFsdWUubGVuZ3RoID09PSAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgRGVsZXRlQnlJbmRleC5jYWxsKHRoaXMsIGkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICArK2k7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTCB8IG51bGwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnBhcmVudCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdGhpcy5fUGFyZW50OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb25zID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICBuYW1lID0gVG9YTUxOYW1lKG5hbWUgfHwgIioiKTsKCiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHRoaXM7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldFByb3BlcnR5ID0gbnVsbDsKCiAgICAgICAgICAgIGZvciAoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5baV0uX0NsYXNzID09PSAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiIKICAgICAgICAgICAgICAgICAgICAmJiAobmFtZS5sb2NhbE5hbWUgPT09ICIqIiB8fCBuYW1lLmxvY2FsTmFtZSA9PT0gdGhpcy5fQ2hpbGRyZW5baV0uX05hbWUubG9jYWxOYW1lKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRoaXMuX0NoaWxkcmVuW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBYTUwgdmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnByZXBlbmRDaGlsZCA9IGZ1bmN0aW9uICh2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIDAsIHZhbHVlKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCgogICAgICAgIFhNTC5wcm90b3R5cGUuZmluZEZpcnN0RWxlbWVudCA9IGZ1bmN0aW9uICh2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gW107CiAgICAgICAgICAgIGxpc3QgPSB0aGlzLmVsZW1lbnRzKHZhbHVlKS5fQ2hpbGRyZW47CiAgICAgICAgICAgIGlmKGxpc3QubGVuZ3RoID09IDApewogICAgICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlbigpOwogICAgICAgICAgICAgICAgdmFyIHhtbDsKICAgICAgICAgICAgICAgIGZvcih2YXIgaT0wO2k8Y2hpbGRyZW4ubGVuZ3RoKCk7aSsrKXsKICAgICAgICAgICAgICAgICAgICB4bWwgPSBjaGlsZHJlbltpXTsKICAgICAgICAgICAgICAgICAgICB2YXIgc3VibGlzdCA9IHhtbC5maW5kRmlyc3RFbGVtZW50KHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICBpZihzdWJsaXN0Lmxlbmd0aD4wKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VibGlzdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9OwoKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmFtZSA9PSAiMCI7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBOYW1lc3BhY2UgfCBTdHJpbmcgbmFtZXNwYWNlCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5yZW1vdmVOYW1lc3BhY2UgPSBmdW5jdGlvbiAobmFtZXNwYWNlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgiLGF0dHJpYnV0ZSxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sdGV4dCwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIG5zID0gTmFtZXNwYWNlKG5hbWVzcGFjZSksIHRoaXNOUyA9IEdldE5hbWVzcGFjZSh0aGlzLl9OYW1lLCB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcyksIHAsIGw7CgogICAgICAgICAgICBpZiAodGhpc05TID09IG5zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgIC8vZmlyZWZveCBkb2VzIG5vdCByZW1vdmUgdGhlIHJlZmVyZW5jZXMgdG8gdGhlCiAgICAgICAgICAgICAvL25hbWVzcGFjZXMgaW4gYXR0cmlidXRlcyAtLSBzbyB3ZSB3b250IGVpdGhlcgogICAgICAgICAgICAgZm9yIChwIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICBpZiAoR2V0TmFtZXNwYWNlKHRoaXMuX0F0dHJpYnV0ZXNbcF0uX05hbWUsIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzKS51cmkgPT0gbnMudXJpKQogICAgICAgICAgICAgewogICAgICAgICAgICAgdGhpcy5fQXR0cmlidXRlc1twXS5fTmFtZSA9IG5ldyBRTmFtZShucywgdGhpcy5fQXR0cmlidXRlc1twXS5sb2NhbE5hbWUoKSk7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICAvLyovCgogICAgICAgICAgICBpZiAobnMucHJlZml4ID09IHVuZGVmaW5lZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChwIGluIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1twXS51cmkgPT09IG5zLnVyaSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1twXTsKICAgICAgICAgICAgICAgICAgICAgICAgfWNhdGNoKGUpe30KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbbnMucHJlZml4XSAmJiB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1tucy5wcmVmaXhdLnVyaSA9PT0gbnMudXJpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0cnl7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbbnMucHJlZml4XSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW25zLnByZWZpeF07CiAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHAgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBwIDwgbDsgKytwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5bcF0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bcF0ucmVtb3ZlTmFtZXNwYWNlKG5zKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgcHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHBhcmFtIFhNTCB2YWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUucmVwbGFjZSA9IGZ1bmN0aW9uIChwcm9wZXJ0eU5hbWUsIHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgiLGF0dHJpYnV0ZSxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sdGV4dCwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGMgPSB2YWx1ZSBpbnN0YW5jZW9mIFhNTCA/IERlZXBDb3B5LmNhbGwodmFsdWUpIDogVG9TdHJpbmcodmFsdWUpLCBuLCBpLCBrOwoKICAgICAgICAgICAgaWYgKHBhcnNlSW50KHByb3BlcnR5TmFtZSkrIiIgPT0gcHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZXBsYWNlLmNhbGwodGhpcywgcHJvcGVydHlOYW1lLCBjKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgQmFzaWNhbGx5IEZpcmVmb3ggZG9lcyBub3QgYXBwZWFyIHRvIGZvbGxvdyB0aGUgcnVsZXMgc2V0IGZvcnRoIGluIHRoZSBzcGVjCiAgICAgICAgICAgICBzbywgd2UgYXJlIGp1c3QgZ29pbmcgdG8gZml4IHRoaXMgc28gdGhhdCB3ZSBkbyB3aGF0IGZpcmVmb3ggZG9lcwogICAgICAgICAgICAgaWYgdGhlIHByb3BlcnR5TmFtZSBpcyBub3QgYW4gaW50ZWdlcjoKICAgICAgICAgICAgIGlmIHZhbHVlIGlzIGEgWE1MTGlzdCBzZXRDaGlsZHJlbgogICAgICAgICAgICAgb3RoZXJ3aXNlIGRvIG5vdGhpbmcKICAgICAgICAgICAgICovCgogICAgICAgICAgICBpZiAoYyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0Q2hpbGRyZW4oYyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0aGlzOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgIExlYXZlIHRoZSByZXN0IG9mIHRoZXNlIHJ1bGVzIGluIHBsYWNlLCBqdXN0IGluIGNhc2UKICAgICAgICAgICAgICovCgogICAgICAgICAgICBuID0gUU5hbWUocHJvcGVydHlOYW1lKTsKICAgICAgICAgICAgayA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKCiAgICAgICAgICAgIHdoaWxlICgtLWsgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgIChuLmxvY2FsTmFtZSA9PT0gIioiIHx8ICh0aGlzLl9DaGlsZHJlbltrXS5fQ2xhc3MgPT09ICJlbGVtZW50IiAmJiB0aGlzLl9DaGlsZHJlbltrXS5fTmFtZS5sb2NhbE5hbWU9PT1uLmxvY2FsTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgJiYgKG4udXJpID09IG51bGwgfHwgKHRoaXMuX0NoaWxkcmVuW2tdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIG4udXJpID09PSB0aGlzLl9DaGlsZHJlbltrXS5fTmFtZS51cmkgKSkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaSAhPT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgRGVsZXRlQnlJbmRleC5jYWxsKHRoaXMsIGkpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaSA9IGs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpICE9PSB1bmRlZmluZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbCh0aGlzLCBpLCBjKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBYTUwgdmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnNldENoaWxkcmVuID0gZnVuY3Rpb24gKHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgdGhpcy5QdXQoIioiLCB2YWx1ZSk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyB2b2lkCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5zZXRMb2NhbE5hbWUgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIixjb21tZW50LHRleHQsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX05hbWUubG9jYWxOYW1lID0gbmFtZSBpbnN0YW5jZW9mIFFOYW1lID8gbmFtZS5sb2NhbE5hbWUgOiBUb1N0cmluZyhuYW1lKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFFOYW1lIHwgU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBudWxsCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5zZXROYW1lID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsY29tbWVudCx0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAobmFtZSBpbnN0YW5jZW9mIFFOYW1lICYmIG5hbWUudXJpID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lLmxvY2FsTmFtZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIG4gPSBRTmFtZShuYW1lKTsKCiAgICAgICAgICAgIGlmICh0aGlzLl9DbGFzcyA9PT0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBuLnVyaSA9ICIiOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlID0gbmV3IE5hbWVzcGFjZShuLnByZWZpeCwgbi51cmkpOwoKICAgICAgICAgICAgdGhpcy5fTmFtZSA9IG47CgogICAgICAgICAgICBpZiAodGhpcy5fQ2xhc3MgPT09ICJhdHRyaWJ1dGUiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fUGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbCh0aGlzLl9QYXJlbnQsIHRoaXMuX0RlZmF1bHROYW1lc3BhY2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbCh0aGlzLCB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICgoIixjb21tZW50LHRleHQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbiwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fTmFtZSA9IG5ldyBRTmFtZSh0aGlzLl9EZWZhdWx0TmFtZXNwYWNlLCB0aGlzLl9OYW1lLmxvY2FsTmFtZSk7CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIE5hbWVzcGFjZSB8IFN0cmluZyBucwogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnNldE5hbWVzcGFjZSA9IGZ1bmN0aW9uIChucykKICAgICAgICB7CiAgICAgICAgICAgIC8vcHJvY2Vzc2luZy1pbnN0cnVjdGlvbiwKICAgICAgICAgICAgaWYgKCgiLGNvbW1lbnQsdGV4dCwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSA9IE5hbWVzcGFjZShucyk7CgogICAgICAgICAgICB0aGlzLl9OYW1lID0gbmV3IFFOYW1lKHRoaXMuX0RlZmF1bHROYW1lc3BhY2UsIHRoaXMuX05hbWUubG9jYWxOYW1lKTsKCiAgICAgICAgICAgIGlmICh0aGlzLl9DbGFzcyA9PT0gImF0dHJpYnV0ZSIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9QYXJlbnQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgQWRkSW5TY29wZU5hbWVzcGFjZS5jYWxsKHRoaXMuX1BhcmVudCwgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQWRkSW5TY29wZU5hbWVzcGFjZS5jYWxsKHRoaXMsIHRoaXMuX0RlZmF1bHROYW1lc3BhY2UpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUudGV4dCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRQcm9wZXJ0eSA9IG51bGw7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gInRleHQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRoaXMuX0NoaWxkcmVuW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRvU3RyaW5nKHRoaXMpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnRvWE1MU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUb1hNTFN0cmluZyh0aGlzKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS52YWx1ZU9mID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIHwgU3RyaW5nIFZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5QdXQgPSBmdW5jdGlvbiAoUHJvcGVydHlOYW1lLCBWYWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwYXJzZUludChQcm9wZXJ0eU5hbWUpKyIiID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoKCIsdGV4dCxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sYXR0cmlidXRlLCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgYyA9ICghKFZhbHVlIGluc3RhbmNlb2YgWE1MKSB8fCAoIix0ZXh0LGF0dHJpYnV0ZSwiKS5pbmRleE9mKCIsIiArIFZhbHVlLl9DbGFzcysiLCIpID4gLTEpCiAgICAgICAgICAgICAgICAgICAgPyBUb1N0cmluZyhWYWx1ZSkKICAgICAgICAgICAgICAgICAgICA6IERlZXBDb3B5LmNhbGwoVmFsdWUpLAogICAgICAgICAgICAgICAgbiA9IFRvWE1MTmFtZShQcm9wZXJ0eU5hbWUpLAogICAgICAgICAgICAgICAgcywgaSwgbCwgYSA9IG51bGwsIHByaW1pdGl2ZUFzc2lnbiwgazsKCiAgICAgICAgICAgIGlmIChuIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFpc1hNTE5hbWUobi5fTmFtZSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChjIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYy5fQ2hpbGRyZW4ubGVuZ3RoID09PSAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYyA9ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzID0gVG9TdHJpbmcoY1swXSk7CgogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAxLCBsID0gYy5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICIgIiArIFRvU3RyaW5nKGNbaV0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBjID0gczsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYyA9IFRvU3RyaW5nKGMpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZvciAoaSBpbiB0aGlzLl9BdHRyaWJ1dGVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgKG4uX05hbWUubG9jYWxOYW1lID09PSB0aGlzLl9BdHRyaWJ1dGVzW2ldLl9OYW1lLmxvY2FsTmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKG4uX05hbWUudXJpID09PSBudWxsIHx8IG4uX05hbWUudXJpID09PSB0aGlzLl9BdHRyaWJ1dGVzW2ldLl9OYW1lLnVyaSkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhID0gdGhpcy5fQXR0cmlidXRlc1tpXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuRGVsZXRlKHRoaXMuX0F0dHJpYnV0ZXNbaV0uX05hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChhID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYSA9IG5ldyBYTUwoKTsKICAgICAgICAgICAgICAgICAgICBhLl9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgIGEuX0NsYXNzID0gImF0dHJpYnV0ZSI7CiAgICAgICAgICAgICAgICAgICAgYS5fTmFtZSA9IG4uX05hbWUudXJpID09IG51bGwKICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgUU5hbWUobmV3IE5hbWVzcGFjZSgpLCBuLl9OYW1lKQogICAgICAgICAgICAgICAgICAgICAgICA6IG5ldyBRTmFtZShuZXcgTmFtZXNwYWNlKG4uX05hbWUudXJpKSwgbi5fTmFtZS5sb2NhbE5hbWUpOwoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzWyhhLl9OYW1lLl9QcmVmaXggPyBhLl9OYW1lLl9QcmVmaXggKyAiOiIgOiAiIikgKyBhLl9OYW1lLmxvY2FsTmFtZV0gPSBhOwoKICAgICAgICAgICAgICAgICAgICBBZGRJblNjb3BlTmFtZXNwYWNlLmNhbGwodGhpcywgR2V0TmFtZXNwYWNlKGEuX05hbWUpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBhLl9WYWx1ZSA9IGM7CgogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNYTUxOYW1lKG4pICYmIG4ubG9jYWxOYW1lICE9ICIqIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGkgPSB1bmRlZmluZWQ7CgogICAgICAgICAgICBwcmltaXRpdmVBc3NpZ24gPSAhKGMgaW5zdGFuY2VvZiBYTUwpICYmIG4ubG9jYWxOYW1lICE9ICIqIjsKCiAgICAgICAgICAgIGZvciAoayA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGsgPCBsOyArK2spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAobi5sb2NhbE5hbWUgPT09ICIqIiB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgdGhpcy5fQ2hpbGRyZW5ba10uX05hbWUubG9jYWxOYW1lPT09bi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICAgICAgKG4udXJpID09IG51bGwgfHwgKHRoaXMuX0NoaWxkcmVuW2tdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIG4udXJpID09PSB0aGlzLl9DaGlsZHJlbltrXS5fTmFtZS51cmkpKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChpICE9IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZUJ5SW5kZXguY2FsbCh0aGlzLCBUb1N0cmluZyhpKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGkgPSBrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGkgPT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwoKICAgICAgICAgICAgICAgIGlmIChwcmltaXRpdmVBc3NpZ24pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYSA9IG5ldyBYTUwoKTsKICAgICAgICAgICAgICAgICAgICBhLl9DbGFzcyA9ICJlbGVtZW50IjsKICAgICAgICAgICAgICAgICAgICBhLl9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgIGEuX05hbWUgPSBuLnVyaSA9PSBudWxsCiAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IFFOYW1lKEdldERlZmF1bHROYW1lc3BhY2UoKSwgbikKICAgICAgICAgICAgICAgICAgICAgICAgOiBuZXcgUU5hbWUobik7CgogICAgICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbCh0aGlzLCBUb1N0cmluZyhpKSwgYSk7CgogICAgICAgICAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbChhLCBHZXROYW1lc3BhY2UoYS5fTmFtZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocHJpbWl0aXZlQXNzaWduKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzID0gVG9TdHJpbmcoYyk7CgogICAgICAgICAgICAgICAgaWYgKHMgIT0gIiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgUmVwbGFjZS5jYWxsKHRoaXMuX0NoaWxkcmVuW2ldLCAiMCIsIHMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVwbGFjZS5jYWxsKHRoaXMsIFRvU3RyaW5nKGkpLCBjKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuRGVsZXRlID0gZnVuY3Rpb24gKFByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwYXJzZUludChQcm9wZXJ0eU5hbWUpKyIiID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbiA9IFRvWE1MTmFtZShQcm9wZXJ0eU5hbWUpLCBrLCBkcCA9IDAsIHEgPSAwLCBsOwoKICAgICAgICAgICAgaWYgKG4gaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGsgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgIChuLl9OYW1lLmxvY2FsTmFtZSA9PT0gIioiIHx8IG4uX05hbWUubG9jYWxOYW1lID09PSB0aGlzLl9BdHRyaWJ1dGVzW2tdLl9OYW1lLmxvY2FsTmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKG4uX05hbWUudXJpID09IG51bGwgfHwgbi5fTmFtZS51cmkgPT09IHRoaXMuX0F0dHJpYnV0ZXNba10uX05hbWUudXJpKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0F0dHJpYnV0ZXNba10uX1BhcmVudCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9BdHRyaWJ1dGVzW2tdOwogICAgICAgICAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKG4ubG9jYWxOYW1lID09PSAiKiIgfHwgKHRoaXMuX0NoaWxkcmVuW3FdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXMuX0NoaWxkcmVuW3FdLl9OYW1lLmxvY2FsTmFtZSA9PT0gbi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICAgICAgKG4udXJpID09IG51bGwgfHwgKHRoaXMuX0NoaWxkcmVuW3FdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIG4udXJpID09PSB0aGlzLl9DaGlsZHJlbltxXS5fTmFtZS51cmkpKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIERlbGV0ZUJ5SW5kZXguY2FsbCh0aGlzLCBxKTsKICAgICAgICAgICAgICAgICAgICArK2RwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoZHAgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW3EgLSBkcF0gPSB0aGlzLl9DaGlsZHJlbltxXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgVmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5FcXVhbHMgPSBmdW5jdGlvbiAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIShWYWx1ZSBpbnN0YW5jZW9mIFhNTCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhpcy5fQ2xhc3MgIT09IFZhbHVlLl9DbGFzcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggIT09IFZhbHVlLl9DaGlsZHJlbi5sZW5ndGgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhpcy5fVmFsdWUgIT09IFZhbHVlLl9WYWx1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLl9OYW1lICE9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoVmFsdWUuX05hbWUgPT09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKFZhbHVlLl9OYW1lLmxvY2FsTmFtZSAhPT0gdGhpcy5fTmFtZS5sb2NhbE5hbWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKFZhbHVlLl9OYW1lLnVyaSAhPT0gdGhpcy5fTmFtZS51cmkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKFZhbHVlLl9OYW1lICE9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb3VudCh0aGlzLl9BdHRyaWJ1dGVzKSAhPT0gY291bnQoVmFsdWUuX0F0dHJpYnV0ZXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBhLCBiLCBrLCBsOwoKICAgICAgICAgICAgZm9yIChrIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGEgPSB0aGlzLl9BdHRyaWJ1dGVzW2tdOwoKICAgICAgICAgICAgICAgIGIgPSBWYWx1ZS5fQXR0cmlidXRlc1trXTsKCiAgICAgICAgICAgICAgICBpZiAoIWIgfHwgYi5fTmFtZS5sb2NhbE5hbWUgIT09IGEuX05hbWUubG9jYWxOYW1lIHx8IGIuX05hbWUudXJpICE9PSBhLl9OYW1lLnVyaSB8fCBiLl9WYWx1ZSAhPT0gYS5fVmFsdWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGsgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBrIDwgbDsgKytrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhID0gdGhpcy5fQ2hpbGRyZW5ba107CgogICAgICAgICAgICAgICAgYiA9IFZhbHVlLl9DaGlsZHJlbltrXTsKCiAgICAgICAgICAgICAgICBpZiAoIWFyZ3VtZW50cy5jYWxsZWUuY2FsbChhLCBiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8vZXh0ZW5zaW9ucwoKICAgICAgICAvKgogICAgICAgICAqIGU0eC5qcwogICAgICAgICAqCiAgICAgICAgICogQSBKYXZhU2NyaXB0IGxpYnJhcnkgdGhhdCBpbXBsZW1lbnRzIHRoZSBvcHRpb25hbCBFNFggZmVhdHVyZXMgZGVzY3JpYmVkIGluCiAgICAgICAgICogRUNNQS0zNTcgMm5kIEVkaXRpb24gQW5uZXggQSBpZiB0aGV5IGFyZSBub3QgYWxyZWFkeSBpbXBsZW1lbnRlZC4KICAgICAgICAgKgogICAgICAgICAqIDIwMTAtMDMtMTMKICAgICAgICAgKgogICAgICAgICAqIEJ5IEVsaWphaCBHcmV5LCBodHRwOi8vZWxpZ3JleS5jb20KICAgICAgICAgKiBMaWNlbnNlOiBUaGUgWDExL01JVCBsaWNlbnNlIChzZWUgQ09QWUlORy5tZCkKICAgICAgICAgKgogICAgICAgICAqIENoYW5nZXM6CiAgICAgICAgICogICAgQnkgU2FtIFNodWxsLCBodHRwOi8vc2Ftc2h1bGwuYmxvZ3Nwb3QuY29tCiAgICAgICAgICogICAgSnVzdCBhIGxpdGxsZSBzaW1wbGlmeWluZyBmb3IgaW1wbGVtZW50YXRpb24KICAgICAgICAgKi8KCiAgICAgICAgLypnbG9iYWwgZG9jdW1lbnQsIFhNTCwgWE1MTGlzdCwgRE9NUGFyc2VyLCBYTUxTZXJpYWxpemVyLCBYUGF0aFJlc3VsdCAqLwoKICAgICAgICAvKmpzbGludCB1bmRlZjogdHJ1ZSwgbm9tZW46IHRydWUsIGVxZXFlcTogdHJ1ZSwgYml0d2lzZTogdHJ1ZSwgcmVnZXhwOiB0cnVlLAogICAgICAgICBuZXdjYXA6IHRydWUsIGltbWVkOiB0cnVlLCBtYXhlcnI6IDEwMDAsIG1heGxlbjogOTAgKi8KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5kb21Ob2RlID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBhZG9wdE5vZGUoZG9jdW1lbnQsIHhtbFRvRG9tTm9kZSh0aGlzKSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5kb21Ob2RlTGlzdCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcy5sZW5ndGgoKSA8IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gYWRvcHROb2RlKGRvY3VtZW50LCBjcmVhdGVEb2N1bWVudEZyb20odGhpcykuZG9jdW1lbnRFbGVtZW50KS5jaGlsZE5vZGVzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUueHBhdGggPSBmdW5jdGlvbiAoeHBhdGhFeHApCiAgICAgICAgewogICAgICAgICAgICB2YXIgcmVzID0gbmV3IFhNTExpc3QsCiAgICAgICAgICAgICAgICBpID0gMCwgbCA9IHRoaXMubGVuZ3RoKCksCiAgICAgICAgICAgICAgICB4cHI7CgogICAgICAgICAgICBpZiAobCAhPT0gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzLkFwcGVuZCh0aGlzW2ldLnhwYXRoKHhwYXRoRXhwKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgeHByID0gZXZhbHVhdGUoY3JlYXRlRG9jdW1lbnRGcm9tKHRoaXMpLCB4cGF0aEV4cCwgdGhpcyk7CgogICAgICAgICAgICBmb3IgKGw9eHByLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzLkFwcGVuZChUb1hNTCh4cHJbaV0pKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnRyYW5zZm9ybSA9IGZ1bmN0aW9uICh4c2x0LCBwYXJhbXMpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIXhzbHQgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGRvYywgcmVzLCBpLCBsID0gdGhpcy5sZW5ndGgoKSwgYzsKCiAgICAgICAgICAgIGlmIChsID4gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzID0gbmV3IFhNTExpc3QoKTsKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzLkFwcGVuZCh0aGlzW2ldLnRyYW5zZm9ybSh4c2x0LCBwYXJhbXMpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm0odGhpcywgeHNsdCwgcGFyYW1zKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFhNTExpc3QgKCRzdHJpbmcpCiAgICAgICAgewogICAgICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgWE1MTGlzdCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBUb1hNTExpc3QoJHN0cmluZyB8fCAiIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX0NsYXNzID0gIlhNTExpc3QiOwoKICAgICAgICAgICAgdGhpcy5fVmFsdWUgPSB1bmRlZmluZWQ7CgoKICAgICAgICAgICAgdGhpcy5fVGFyZ2V0T2JqZWN0ID0gbnVsbDsKCiAgICAgICAgICAgIHRoaXMuX1RhcmdldFByb3BlcnR5ID0gbnVsbDsKCiAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuID0gW107CgogICAgICAgICAgICB0aGlzWzBdID0gbnVsbDsKCiAgICAgICAgICAgIGlmICgkc3RyaW5nKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgbGlzdCA9IFRvWE1MTGlzdCgkc3RyaW5nKSwgaSA9IDAsIGwgPSBsaXN0Ll9DaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgICAgICB0aGlzLl9WYWx1ZSA9IGxpc3QuX1ZhbHVlOwoKICAgICAgICAgICAgICAgIGZvciAoO2kgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0gPSB0aGlzW2ldID0gbGlzdC5fQ2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnRvU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAiZnVuY3Rpb24gWE1MTGlzdCgpIHtcbiBbbmF0aXZlIGNvZGVdIFxufSI7CiAgICAgICAgfTsKCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUgPSBuZXcgWE1MKCk7CgogICAgICAgIHZhciBpZ25vcmUgPSB7eHBhdGg6MSxkb21Ob2RlTGlzdDoxLHRyYW5zZm9ybToxfTsKCiAgICAgICAgZm9yIChwIGluIFhNTExpc3QucHJvdG90eXBlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGlnbm9yZVtwXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFhNTExpc3QucHJvdG90eXBlW3BdID0gKGZ1bmN0aW9uKHApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggIT0gMSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoImNhbm5vdCBjYWxsICIgKyBwICsgIiBtZXRob2Qgb24gYW4gWE1MIGxpc3Qgd2l0aCAiICsgdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoICsgIiBlbGVtZW50cyIpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTC5wcm90b3R5cGVbcF0uYXBwbHkodGhpc1swXSwgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0pKHApOwogICAgICAgIH0KCiAgICAgICAgdHJ5ewogICAgICAgICAgICBkZWxldGUgWE1MTGlzdC5wcm90b3R5cGUuX0F0dHJpYnV0ZXM7CiAgICAgICAgICAgIGRlbGV0ZSBYTUxMaXN0LnByb3RvdHlwZS5fSW5TY29wZU5hbWVzcGFjZXM7CiAgICAgICAgfWNhdGNoKGUpe30KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBBdHRyaWJ1dGVOYW1lIGF0dHJpYnV0ZU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuYXR0cmlidXRlID0gZnVuY3Rpb24gKGF0dHJpYnV0ZU5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gR2V0TGlzdC5jYWxsKHRoaXMsIFRvQXR0cmlidXRlTmFtZShhdHRyaWJ1dGVOYW1lKSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5hdHRyaWJ1dGVzID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBHZXRMaXN0LmNhbGwodGhpcywgVG9BdHRyaWJ1dGVOYW1lKCIqIikpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgcHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLmNoaWxkID0gZnVuY3Rpb24gKHByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIHI7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHRoaXM7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgciA9IHRoaXNbaV0uY2hpbGQocHJvcGVydHlOYW1lKTsKCiAgICAgICAgICAgICAgICBpZiAoci5fQ2hpbGRyZW4ubGVuZ3RoID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5jaGlsZHJlbiA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gR2V0TGlzdC5jYWxsKHRoaXMsICIqIik7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5jb21tZW50cyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCByOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHIgPSB0aGlzW2ldLmNvbW1lbnRzKCk7CgogICAgICAgICAgICAgICAgICAgIGlmIChyLl9DaGlsZHJlbi5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQocik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFhNTCB2YWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uICh2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXSA9PSB2YWx1ZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRGVlcENvcHlMaXN0LmNhbGwodGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLmRlc2NlbmRhbnRzID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRGVzY2VuZGFudHNMaXN0LmNhbGwodGhpcywgbmFtZSB8fCAiKiIpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5lbGVtZW50cyA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgbmFtZSA9IFRvWE1MTmFtZShuYW1lIHx8ICIqIik7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIHI7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHRoaXM7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldFByb3BlcnR5ID0gbmFtZTsKCiAgICAgICAgICAgIGZvciAoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByID0gdGhpc1tpXS5lbGVtZW50cyhuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHIuX0NoaWxkcmVuLmxlbmd0aCA+IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBIYXNQcm9wZXJ0eS5jYWxsKHRoaXMsIG5hbWUpCiAgICAgICAgICAgICAgICB8fCAoZGVmYXVsdFhNTExpc3RQcm9wZXJ0aWVzLmluZGV4T2YoIiwiICsgbmFtZSArICIsIikgPT09IC0xICYmIGhhc093blByb3BlcnR5LmNhbGwodGhpcywgbmFtZSkpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuaGFzQ29tcGxleENvbnRlbnQgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW4ubGVuZ3RoID09PSAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpc1swXS5oYXNDb21wbGV4Q29udGVudCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5oYXNTaW1wbGVDb250ZW50ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggPT09IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzWzBdLmhhc1NpbXBsZUNvbnRlbnQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBOdW1iZXIKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzW2ldLm5vcm1hbGl6ZSgpOwogICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXNbaV0uX0NsYXNzID09PSAidGV4dCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGkrMSA8IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCAmJiB0aGlzW2krMV0uX0NsYXNzID09PSAidGV4dCIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2ldLl9WYWx1ZSA9ICh0aGlzW2ldLl9WYWx1ZSB8fCAiIikgKyAodGhpc1tpKzFdLl9WYWx1ZSB8fCAiIik7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuRGVsZXRlKGkrMSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fVmFsdWUubGVuZ3RoID09PSAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5EZWxldGUoaSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgKytpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MIHwgdW5kZWZpbmVkCiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUucGFyZW50ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggPT09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIHBhcmVudCA9IHRoaXNbMF0uX1BhcmVudCwgaSA9IDEsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9QYXJlbnQgIT0gcGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBwYXJlbnQ7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnByb2Nlc3NpbmdJbnN0cnVjdGlvbnMgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIG5hbWUgPSBUb1hNTE5hbWUobmFtZSB8fCAiKiIpOwogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCByOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHIgPSB0aGlzW2ldLnByb2Nlc3NpbmdJbnN0cnVjdGlvbnMobmFtZSk7CgogICAgICAgICAgICAgICAgICAgIGlmIChyLl9DaGlsZHJlbi5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQocik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IE51bWJlciBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQobmFtZSkgPiAwICYmIHBhcnNlSW50KG5hbWUpIDwgdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUudGV4dCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCByOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHIgPSB0aGlzW2ldLnRleHQoKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHIuX0NoaWxkcmVuLmxlbmd0aCA+IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVG9TdHJpbmcodGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnRvWE1MU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUb1hNTFN0cmluZyh0aGlzKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnZhbHVlT2YgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IE51bWJlciB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgVmFsdWUKICAgICAgICAgKiAgICBAcGFyYW0gaXNFbGVtZW50CiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLlB1dCA9IGZ1bmN0aW9uIChQcm9wZXJ0eU5hbWUsIFZhbHVlLGlzQ2hpbGRFbGVtZW50KQogICAgICAgIHsKICAgICAgICAgICAgaXNDaGlsZEVsZW1lbnQgPSBpc0NoaWxkRWxlbWVudCAhPT0gdW5kZWZpbmVkID8gaXNDaGlsZEVsZW1lbnQgOiBmYWxzZTsKICAgICAgICAgICAgdmFyIGkgPSBwYXJzZUludChQcm9wZXJ0eU5hbWUpLCByLCB5LCBsLCB6LCBwYXJlbnQsIGMsIGogPSAwLCBxLCB0OwoKICAgICAgICAgICAgaWYgKGkrIiIgPT0gUHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByID0gUmVzb2x2ZVZhbHVlLmNhbGwodGhpcy5fVGFyZ2V0T2JqZWN0KTsKICAgICAgICAgICAgICAgIC8qIEZpcmVmb3ggZG9lc24ndCBkbyB0aGlzCiAgICAgICAgICAgICAgICAgaWYgKHIgPT0gbnVsbCkKICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoaSA+PSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHIubGVuZ3RoKCkgIT0gMSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHIgPSByWzBdOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLyogRmlyZWZveCBkb2Vzbid0IGRvIHRoaXMKICAgICAgICAgICAgICAgICAgICAgaWYgKHIuX0NsYXNzICE9ICJlbGVtZW50IikKICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHkgPSBuZXcgWE1MKCk7CiAgICAgICAgICAgICAgICAgICAgeS5fUGFyZW50ID0gcjsKICAgICAgICAgICAgICAgICAgICB5Ll9OYW1lID0gdGhpcy5fVGFyZ2V0UHJvcGVydHk7CiAgICAgICAgICAgICAgICAgICAgeS5fQXR0cmlidXRlcyA9IHt9OwoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fVGFyZ2V0UHJvcGVydHkgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhciAmJiBHZXQuY2FsbChyLCB5Ll9OYW1lKS5sZW5ndGgoKSA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB5Ll9DbGFzcyA9ICJhdHRyaWJ1dGUiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghaXNDaGlsZEVsZW1lbnQgJiYgKHRoaXMuX1RhcmdldFByb3BlcnR5ID09IG51bGwgfHwgdGhpcy5fVGFyZ2V0UHJvcGVydHkubG9jYWxOYW1lID09PSAiKiIpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgeS5fTmFtZSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIHkuX0NsYXNzID0gInRleHQiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB5Ll9DbGFzcyA9ICJlbGVtZW50IjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh5Ll9DbGFzcyAhPSAiYXR0cmlidXRlIikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqID0gMDsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGogPCByLl9DaGlsZHJlbi5sZW5ndGgtMSAmJiByW2pdICE9PSB0aGlzW2ktMV0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArK2o7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGogPSByLl9DaGlsZHJlbi5sZW5ndGggLSAxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc2VydC5jYWxsKHIsIGorMSwgeSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChWYWx1ZSBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkuX05hbWUgPSBWYWx1ZS5fVGFyZ2V0UHJvcGVydHk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkuX05hbWUgPSBWYWx1ZS5fTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhpcy5BcHBlbmQoeSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCEoVmFsdWUgaW5zdGFuY2VvZiBYTUwpIHx8IFZhbHVlLl9DbGFzcyA9PT0gInRleHQiIHx8IFZhbHVlLl9DbGFzcyA9PT0gImF0dHJpYnV0ZSIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVmFsdWUgPSBUb1N0cmluZyhWYWx1ZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHRoaXNbaV0uX0NsYXNzID09PSAiYXR0cmlidXRlIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB6ID0gVG9BdHRyaWJ1dGVOYW1lKHRoaXNbaV0uX05hbWUpOwogICAgICAgICAgICAgICAgICAgIHRoaXNbaV0uX1BhcmVudC5QdXQoeiwgVmFsdWUpOwogICAgICAgICAgICAgICAgICAgIHRoaXNbaV0gPSB0aGlzW2ldLl9QYXJlbnQuYXR0cmlidXRlKHopWzBdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vc2hhbGxvdyBjb3B5PwogICAgICAgICAgICAgICAgICAgIGMgPSBWYWx1ZTsKICAgICAgICAgICAgICAgICAgICBwYXJlbnQgPSB0aGlzW2ldLl9QYXJlbnQ7CgogICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBxID0gdGhpc1tpXS5jaGlsZEluZGV4KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbChwYXJlbnQsIHEsIGMpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gYy5fQ2hpbGRyZW4ubGVuZ3RoOyBqIDwgbDsgKytqKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLl9DaGlsZHJlbltqXSA9IGNbal0gPSBwYXJlbnQuX0NoaWxkcmVuW3Eral07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChjLl9DaGlsZHJlbi5sZW5ndGggPT09IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSBpICsgMSwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaiA8IGw7ICsraikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bai0xXSA9IHRoaXNbai0xXSA9IHRoaXNbal0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGogPiBpOyAtLWopCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHogPSBUb1N0cmluZyhqICsgYy5fQ2hpbGRyZW4ubGVuZ3RoIC0gMSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlblt6XSA9IHRoaXNbel0gPSB0aGlzW2pdOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gYy5fQ2hpbGRyZW4ubGVuZ3RoOyBqIDwgbDsgKytqKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baStqXSA9IHRoaXNbaStqXSA9IGNbal07CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MIHx8ICgiLHRleHQsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uIikuaW5kZXhPZigiLCIgKyB0aGlzW2ldLl9DbGFzcysiLCIpID4gLTEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gISF0aGlzW2ldICYmIHRoaXNbaV0uX1BhcmVudDsKCiAgICAgICAgICAgICAgICAgICAgaWYocGFyZW50KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcSA9IHRoaXNbaV0uY2hpbGRJbmRleCgpOwogICAgICAgICAgICAgICAgICAgICAgICBSZXBsYWNlLmNhbGwocGFyZW50LCBxLCBWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlID0gcGFyZW50Ll9DaGlsZHJlbltxXTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh0b1N0cmluZy5jYWxsKFZhbHVlKSA9PT0gIltvYmplY3QgU3RyaW5nXSIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0ID0gVG9YTUwoVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0Ll9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXSA9IHRoaXNbaV0gPSB0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5BcHBlbmQoWE1MTGlzdChWYWx1ZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIEZpcmVmb3ggZG9lc24ndCBkbyB0aGlzCiAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLmxlbmd0aCgpIDw9IDEpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICBpZiAodGhpcy5sZW5ndGgoKSA9PT0gMCkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIHIgPSBSZXNvbHZlVmFsdWVMaXN0LmNhbGwodGhpcyk7CgogICAgICAgICAgICAgaWYgKHIgPT0gbnVsbCB8fCByLmxlbmd0aCgpICE9IDEpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICB0aGlzLkFwcGVuZChyKTsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIHRoaXNbMF0uUHV0KFByb3BlcnR5TmFtZSwgVmFsdWUpOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgfSovCgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTnVtYmVyIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLkRlbGV0ZSA9IGZ1bmN0aW9uIChQcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICB2YXIgaSA9IHBhcnNlSW50KFByb3BlcnR5TmFtZSksIHBhcmVudCwgcSwgbDsKCiAgICAgICAgICAgIGlmIChpKyIiID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGkgPj0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHBhcmVudCA9IHRoaXNbaV0uX1BhcmVudDsKCiAgICAgICAgICAgICAgICBpZiAocGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9ICJhdHRyaWJ1dGUiKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LkRlbGV0ZShUb0F0dHJpYnV0ZU5hbWUodGhpc1tpXS5fTmFtZSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBEZWxldGVCeUluZGV4LmNhbGwocGFyZW50LCB0aGlzW2ldLmNoaWxkSW5kZXgoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbi5zcGxpY2UoUHJvcGVydHlOYW1lLDEpOwogICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzW1Byb3BlcnR5TmFtZV07CiAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQoKICAgICAgICAgICAgICAgIGZvciAocSA9IGkgKyAxLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW3EtMV0gPSB0aGlzW3EtMV0gPSB0aGlzW3FdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogRmlyZWZveCB3b24ndCBkbyB0aGlzCiAgICAgICAgICAgICBmb3IgKHEgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICAgewogICAgICAgICAgICAgaWYgKHRoaXNbcV0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICB0aGlzW3FdLkRlbGV0ZShQcm9wZXJ0eU5hbWUpOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBWYWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5BcHBlbmQgPSBmdW5jdGlvbiAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIShWYWx1ZSBpbnN0YW5jZW9mIFhNTCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgaSA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCwgbiA9IDEsIGogPSAwOwoKICAgICAgICAgICAgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbiA9IFZhbHVlLl9DaGlsZHJlbi5sZW5ndGg7CgogICAgICAgICAgICAgICAgaWYgKG4gPT0gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLl9UYXJnZXRPYmplY3QgPSBWYWx1ZS5fVGFyZ2V0T2JqZWN0OwogICAgICAgICAgICAgICAgdGhpcy5fVGFyZ2V0UHJvcGVydHkgPSBWYWx1ZS5fVGFyZ2V0UHJvcGVydHk7CgogICAgICAgICAgICAgICAgZm9yICg7aiA8IG47ICsraikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpK2pdID0gdGhpc1tpK2pdID0gVmFsdWVbal07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXSA9IHRoaXNbaV0gPSBWYWx1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBWYWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5FcXVhbHMgPSBmdW5jdGlvbiAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoVmFsdWUgPT0gdW5kZWZpbmVkICYmIHRoaXMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUxMaXN0ICYmIFZhbHVlLl9DaGlsZHJlbi5sZW5ndGggPT09IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzW2ldLkVxdWFscyhWYWx1ZVtpXSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXNbMF0uRXF1YWxzKFZhbHVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBSZXNvbHZlVmFsdWVMaXN0ICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW4ubGVuZ3RoID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh0aGlzLl9UYXJnZXRPYmplY3QgPT0gbnVsbAogICAgICAgICAgICAgICAgfHwgdGhpcy5fVGFyZ2V0UHJvcGVydHkgPT0gbnVsbAogICAgICAgICAgICAgICAgfHwgdGhpcy5fVGFyZ2V0UHJvcGVydHkgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lCiAgICAgICAgICAgICAgICB8fCB0aGlzLl9UYXJnZXRQcm9wZXJ0eS5sb2NhbE5hbWUgPT09ICIqIgogICAgICAgICAgICApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgYmFzZSA9IFJlc29sdmVWYWx1ZS5jYWxsKHRoaXMuX1RhcmdldE9iamVjdCksIHRhcmdldDsKCiAgICAgICAgICAgIGlmIChiYXNlID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0YXJnZXQgPSBHZXQuY2FsbChiYXNlLCB0aGlzLl9UYXJnZXRQcm9wZXJ0eSk7CgogICAgICAgICAgICBpZiAodGFyZ2V0Ll9DaGlsZHJlbi5sZW5ndGggPT09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChiYXNlIGluc3RhbmNlb2YgWE1MTGlzdCAmJiBiYXNlLl9DaGlsZHJlbi5sZW5ndGggPiAxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGJhc2UuUHV0KHRoaXMuX1RhcmdldFByb3BlcnR5LCAiIik7CgogICAgICAgICAgICAgICAgdGFyZ2V0ID0gR2V0LmNhbGwoYmFzZSwgdGhpcy5fVGFyZ2V0UHJvcGVydHkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdGFyZ2V0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTmFtZXNwYWNlIHwgUU5hbWUgcHJlZml4CiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB1cmkKICAgICAgICAgKiAgICBAcmV0dXJucyBOYW1lc3BhY2UKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIE5hbWVzcGFjZSAocHJlZml4LCB1cmkpCiAgICAgICAgewogICAgICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTmFtZXNwYWNlKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHByZWZpeCAmJiBwcmVmaXggaW5zdGFuY2VvZiBOYW1lc3BhY2UKICAgICAgICAgICAgICAgICAgICA/IHByZWZpeAogICAgICAgICAgICAgICAgICAgIDogbmV3IE5hbWVzcGFjZShwcmVmaXgsIHVyaSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh1cmkgPT09IHVuZGVmaW5lZCAmJiBwcmVmaXggPT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhpcy5wcmVmaXggPSAiIjsKICAgICAgICAgICAgICAgIHRoaXMudXJpID0gIiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodXJpID09PSB1bmRlZmluZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHVyaSA9IHByZWZpeDsKICAgICAgICAgICAgICAgIHByZWZpeCA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgICAgICBpZiAodXJpIGluc3RhbmNlb2YgTmFtZXNwYWNlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMucHJlZml4ID0gdXJpLnByZWZpeDsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVyaSA9IHVyaS51cmk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICh1cmkgaW5zdGFuY2VvZiBRTmFtZSAmJiB1cmkudXJpICE9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMudXJpID0gdXJpLnVyaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVyaSA9IFRvU3RyaW5nKHVyaSk7CgogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnVyaSA9PSAiIikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJlZml4ID0gIiI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHVyaSBpbnN0YW5jZW9mIFFOYW1lKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMudXJpID0gdXJpLnVyaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVyaSA9IFRvU3RyaW5nKHVyaSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHRoaXMudXJpID09PSAiIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZml4ID09PSB1bmRlZmluZWQgfHwgVG9TdHJpbmcocHJlZml4KSA9PT0gIiIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZWZpeCA9ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCJjYW5ub3QgZGVmaW5lIHRoZSBwcmVmaXggZm9yIGFuIGVtcHR5IHVyaSIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHByZWZpeCA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMucHJlZml4ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMucHJlZml4ID0gVG9TdHJpbmcocHJlZml4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEB2YXIgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgTmFtZXNwYWNlLnByb3RvdHlwZS5wcmVmaXggPSB1bmRlZmluZWQ7CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAdmFyIFN0cmluZwogICAgICAgICAqLwogICAgICAgIE5hbWVzcGFjZS5wcm90b3R5cGUudXJpID0gdW5kZWZpbmVkOwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgTmFtZXNwYWNlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdGhpcy51cmk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBOYW1lc3BhY2UgfCBTdHJpbmcgfCBRTmFtZSBOYW1lU3BhY2UKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nCiAgICAgICAgICogICAgQHJldHVybnMgUU5hbWUKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBRTmFtZSAoTmFtZVNwYWNlLCBOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFFOYW1lKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIE5hbWVTcGFjZSBpbnN0YW5jZW9mIFFOYW1lCiAgICAgICAgICAgICAgICAgICAgPyBOYW1lU3BhY2UKICAgICAgICAgICAgICAgICAgICA6IG5ldyBRTmFtZShOYW1lU3BhY2UsIE5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoTmFtZSA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBOYW1lID0gTmFtZVNwYWNlOwogICAgICAgICAgICAgICAgTmFtZVNwYWNlID0gdW5kZWZpbmVkOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoTmFtZXNwYWNlIGluc3RhbmNlb2YgUU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChOYW1lID09PSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTmFtZSA9IE5hbWUubG9jYWxOYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBOYW1lID0gTmFtZSA9PT0gdW5kZWZpbmVkIHx8IE5hbWUgPT09IG51bGwKICAgICAgICAgICAgICAgID8gIiIKICAgICAgICAgICAgICAgIDogVG9TdHJpbmcoTmFtZSk7CgogICAgICAgICAgICBpZiAoTmFtZVNwYWNlID09PSB1bmRlZmluZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE5hbWVTcGFjZSA9IE5hbWUgPT09ICIqIiA/IG51bGwgOiBHZXREZWZhdWx0TmFtZXNwYWNlKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMubG9jYWxOYW1lID0gTmFtZTsKCiAgICAgICAgICAgIGlmIChOYW1lU3BhY2UgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhpcy51cmkgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTmFtZVNwYWNlID0gTmFtZXNwYWNlKE5hbWVTcGFjZSk7CiAgICAgICAgICAgICAgICB0aGlzLnVyaSA9IE5hbWVTcGFjZS51cmk7CiAgICAgICAgICAgICAgICB0aGlzLl9QcmVmaXggPSBOYW1lU3BhY2UucHJlZml4OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHZhciBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBRTmFtZS5wcm90b3R5cGUubG9jYWxOYW1lID0gdW5kZWZpbmVkOwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHZhciBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBRTmFtZS5wcm90b3R5cGUudXJpID0gdW5kZWZpbmVkOwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIE9iamVjdCBJblNjb3BlTmFtZXNwYWNlcwogICAgICAgICAqICAgIEByZXR1cm5zIE5hbWVzcGFjZQogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gR2V0TmFtZXNwYWNlIChxLCBJblNjb3BlTmFtZXNwYWNlcykKICAgICAgICB7CiAgICAgICAgICAgIGlmKCFxKQogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBOYW1lc3BhY2UoKTsKICAgICAgICAgICAgaWYgKHEudXJpID09PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEluU2NvcGVOYW1lc3BhY2VzID0gSW5TY29wZU5hbWVzcGFjZXMgfHwge307CgogICAgICAgICAgICB2YXIgbnMsIHA7CgogICAgICAgICAgICBmb3IgKHAgaW4gSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChxLnVyaSA9PT0gSW5TY29wZU5hbWVzcGFjZXNbcF0udXJpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG5zID0gSW5TY29wZU5hbWVzcGFjZXNbcF07CgogICAgICAgICAgICAgICAgICAgIGlmICghIXEuX1ByZWZpeCAmJiBxLl9QcmVmaXggPT09IG5zLnByZWZpeCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuczsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghbnMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG5zID0gISFxLl9QcmVmaXgKICAgICAgICAgICAgICAgICAgICA/IG5ldyBOYW1lc3BhY2UocS5fUHJlZml4LCBxLnVyaSkKICAgICAgICAgICAgICAgICAgICA6IG5ldyBOYW1lc3BhY2UocS51cmkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIFFOYW1lLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gISF0aGlzLnVyaQogICAgICAgICAgICAgICAgPyB0aGlzLnVyaSArICI6OiIgKyB0aGlzLmxvY2FsTmFtZQogICAgICAgICAgICAgICAgOiB0aGlzLmxvY2FsTmFtZTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIEF0dHJpYnV0ZU5hbWUgfCBRTmFtZSB8IFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQXR0cmlidXRlTmFtZQogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEF0dHJpYnV0ZU5hbWUgKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBuYW1lICYmIChuYW1lIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSB8fCBuYW1lIGluc3RhbmNlb2YgUU5hbWUpCiAgICAgICAgICAgICAgICAgICAgPyBuYW1lCiAgICAgICAgICAgICAgICAgICAgOiBuZXcgQXR0cmlidXRlTmFtZShuYW1lKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fTmFtZSA9IG5hbWUgaW5zdGFuY2VvZiBRTmFtZQogICAgICAgICAgICAgICAgPyBuYW1lCiAgICAgICAgICAgICAgICA6IG5ldyBRTmFtZShuZXcgTmFtZXNwYWNlKEdldERlZmF1bHROYW1lc3BhY2UoKXx8dW5kZWZpbmVkKSwgbmFtZSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHZhciBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBBdHRyaWJ1dGVOYW1lLnByb3RvdHlwZS5sb2NhbE5hbWUgPSB1bmRlZmluZWQ7CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAdmFyIFN0cmluZwogICAgICAgICAqLwogICAgICAgIEF0dHJpYnV0ZU5hbWUucHJvdG90eXBlLnVyaSA9IHVuZGVmaW5lZDsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIEF0dHJpYnV0ZU5hbWUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAiQCIgKyAoISF0aGlzLl9OYW1lLnVyaQogICAgICAgICAgICAgICAgICAgICAgICA/IHRoaXMuX05hbWUudXJpICsgIjo6IiArIHRoaXMuX05hbWUubG9jYWxOYW1lCiAgICAgICAgICAgICAgICAgICAgICAgIDogdGhpcy5fTmFtZS5sb2NhbE5hbWUKICAgICAgICAgICAgICAgICk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gQW55TmFtZSAoKQogICAgICAgIHsKCiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIG1peGVkIHZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIGlzWE1MTmFtZSAodmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdHJ5ewogICAgICAgICAgICAgICAgdmFyIHEgPSBRTmFtZSh2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2ggKGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICEhcS5sb2NhbE5hbWUgJiYgKCEhcS5sb2NhbE5hbWUubWF0Y2goL15bXHdcLV0rJC9pKSB8fCAhIXEubG9jYWxOYW1lLm1hdGNoKC9eW1x3XC1cOl0rJC9pKSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIG1peGVkIHZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBUb1N0cmluZyAodmFsdWUpCiAgICAgICAgewogICAgICAgICAgICB2YXIgaSA9IDAsIGwsIHM7CgogICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodmFsdWUuaGFzU2ltcGxlQ29udGVudCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHMgPSAiIjsKCiAgICAgICAgICAgICAgICAgICAgZm9yIChsID0gdmFsdWUubGVuZ3RoKCk7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWVbaV0uX0NsYXNzICE9ICJjb21tZW50IiAmJiB2YWx1ZVtpXS5fQ2xhc3MgIT0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9IFRvU3RyaW5nKHZhbHVlW2ldKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIFRvWE1MU3RyaW5nKHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFhNTCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHZhbHVlLl9DbGFzcyA9PT0gImF0dHJpYnV0ZSIgfHwgdmFsdWUuX0NsYXNzID09PSAidGV4dCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLl9WYWx1ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAodmFsdWUuaGFzU2ltcGxlQ29udGVudCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHMgPSAiIjsKCiAgICAgICAgICAgICAgICAgICAgZm9yIChsID0gdmFsdWUubGVuZ3RoKCk7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUuY2hpbGQoaSkuX0NsYXNzICE9ICJjb21tZW50IiAmJiB2YWx1ZS5jaGlsZChpKS5fQ2xhc3MgIT0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9IFRvU3RyaW5nKHZhbHVlLmNoaWxkKGkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIFRvWE1MU3RyaW5nKHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEF0dHJpYnV0ZU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiQCIgKyBUb1N0cmluZyh2YWx1ZS5fTmFtZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkCiAgICAgICAgICAgICAgICA/ICIiCiAgICAgICAgICAgICAgICA6ICIiICsgdmFsdWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBpbnB1dAogICAgICAgICAqICAgIEBwYXJhbSBPYmplY3QgQW5jZXN0b3JOYW1lc3BhY2VzCiAgICAgICAgICogICAgQHBhcmFtIE51bWJlciBJbmRlbnRMZXZlbAogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFRvWE1MU3RyaW5nIChpbnB1dCwgQW5jZXN0b3JOYW1lc3BhY2VzLCBJbmRlbnRMZXZlbCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBzID0gIiIsIHAgPSAwLCB0ZW1wLCB0ZW1wMiwgbmFtZXNwYWNlLCBuYW1lc3BhY2VVbmlvbiwKICAgICAgICAgICAgICAgIG5hbWVzcGFjZURlY2xhcmF0aW9ucyA9IHt9LCBhdHRyQW5kTmFtZXNwYWNlcywgcHJlZml4ZXMsIGRlZmF1bHRTZXQ7CgogICAgICAgICAgICBBbmNlc3Rvck5hbWVzcGFjZXMgPSBBbmNlc3Rvck5hbWVzcGFjZXMgfHwge307CgogICAgICAgICAgICBJbmRlbnRMZXZlbCA9IE51bWJlcihJbmRlbnRMZXZlbCB8fCAwKTsKCiAgICAgICAgICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRlbXAgPSBpbnB1dC5oYXNTaW1wbGVDb250ZW50KCk7CgogICAgICAgICAgICAgICAgdGVtcDIgPSBpbnB1dC5sZW5ndGgoKTsKCiAgICAgICAgICAgICAgICBmb3IgKDsgcCA8IHRlbXAyOyArK3ApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHAgPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiXHJcbiI7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBzICs9IFRvWE1MU3RyaW5nKGlucHV0W3BdLCBBbmNlc3Rvck5hbWVzcGFjZXMpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGlucHV0IGluc3RhbmNlb2YgWE1MKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoWE1MLnByZXR0eVByaW50aW5nKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vcyArPSBuZXcgQXJyYXkoSW5kZW50TGV2ZWwrMSkuam9pbigiICIpOwogICAgICAgICAgICAgICAgICAgIGZvciAoOyBwIDwgSW5kZW50TGV2ZWw7ICsrcCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gIiAiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBzd2l0Y2ggKGlucHV0Ll9DbGFzcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJ0ZXh0IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMgKyBFc2NhcGVFbGVtZW50VmFsdWUoWE1MLnByZXR0eVByaW50aW5nID8gdHJpbShpbnB1dC5fVmFsdWUpIDogaW5wdXQuX1ZhbHVlKTsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAiYXR0cmlidXRlIjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMgKyBFc2NhcGVBdHRyaWJ1dGVWYWx1ZShpbnB1dC5fVmFsdWUpOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICJjb21tZW50IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMgKyAiPCEtLSIgKyBpbnB1dC5fVmFsdWUgKyAiLS0+IjsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzICsgIjw/IiArIGlucHV0Ll9OYW1lLmxvY2FsTmFtZSArICIgIiArIGlucHV0Ll9WYWx1ZSArICI/PiI7CgogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVuaW9uID0gZXh0ZW5kKHt9LCBBbmNlc3Rvck5hbWVzcGFjZXMpOwoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChwIGluIGlucHV0Ll9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGlucHV0Ll9JblNjb3BlTmFtZXNwYWNlc1twXTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUFuY2VzdG9yTmFtZXNwYWNlc1sodGVtcC5wcmVmaXh8fCIiKV0gfHwgQW5jZXN0b3JOYW1lc3BhY2VzWyh0ZW1wLnByZWZpeHx8IiIpXS51cmkgIT0gdGVtcC51cmkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlVW5pb25bKHRlbXAucHJlZml4fHwiIildID0gbmFtZXNwYWNlRGVjbGFyYXRpb25zWyh0ZW1wLnByZWZpeHx8IiIpXSA9IG5ldyBOYW1lc3BhY2UodGVtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaW5wdXQuX1BhcmVudCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlVW5pb25bKGlucHV0Ll9EZWZhdWx0TmFtZXNwYWNlLnByZWZpeHx8IiIpXSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlRGVjbGFyYXRpb25zWyhpbnB1dC5fRGVmYXVsdE5hbWVzcGFjZS5wcmVmaXh8fCIiKV0gPSBuZXcgTmFtZXNwYWNlKGlucHV0Ll9EZWZhdWx0TmFtZXNwYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgLy9maXJlZm94IGRvZXNuJ3QgZG8gdGhpcwogICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChwIGluIGlucHV0Ll9BdHRyaWJ1dGVzKQogICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlID0gR2V0TmFtZXNwYWNlKGlucHV0Ll9BdHRyaWJ1dGVzW3BdLl9OYW1lLCBuYW1lc3BhY2VVbmlvbik7CgogICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZS5wcmVmaXggPT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZS5wcmVmaXggPSAhbmFtZXNwYWNlVW5pb25bIiJdID8gIiIgOiBuZXdQcmVmaXgoKTsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlKCEhbmFtZXNwYWNlVW5pb25bbmFtZXNwYWNlLnByZWZpeF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVuaW9uW25hbWVzcGFjZS5wcmVmaXhdID0gbmFtZXNwYWNlRGVjbGFyYXRpb25zW25hbWVzcGFjZS5wcmVmaXhdID0gbmFtZXNwYWNlOwogICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgKi8KCiAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gIjwiOwoKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlID0gR2V0TmFtZXNwYWNlKGlucHV0Ll9OYW1lLCBuYW1lc3BhY2VEZWNsYXJhdGlvbnMpOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZS5wcmVmaXgpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gbmFtZXNwYWNlLnByZWZpeCArICI6IjsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgcyArPSBpbnB1dC5fTmFtZSA/IGlucHV0Ll9OYW1lLmxvY2FsTmFtZSA6ICIiOwoKICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckFuZE5hbWVzcGFjZXMgPSBleHRlbmQoe30sIGlucHV0Ll9BdHRyaWJ1dGVzLCBuYW1lc3BhY2VEZWNsYXJhdGlvbnMpOwoKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFNldCA9IGZhbHNlOwoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChwIGluIGF0dHJBbmROYW1lc3BhY2VzKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICIgIjsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ckFuZE5hbWVzcGFjZXNbcF0gaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IEdldE5hbWVzcGFjZShhdHRyQW5kTmFtZXNwYWNlc1twXS5fTmFtZSwgQW5jZXN0b3JOYW1lc3BhY2VzKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAucHJlZml4ID09PSB1bmRlZmluZWQgJiYgIW5hbWVzcGFjZVVuaW9uWyIiXSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcC5wcmVmaXggPSAhbmFtZXNwYWNlVW5pb25bIiJdID8gIiIgOiBuZXdQcmVmaXgoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZShuYW1lc3BhY2VVbmlvblt0ZW1wLnByZWZpeF0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlVW5pb25bdGVtcC5wcmVmaXhdID0gbmFtZXNwYWNlRGVjbGFyYXRpb25zW3RlbXAucHJlZml4XSA9IG5ldyBOYW1lc3BhY2UodGVtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcC5wcmVmaXgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9IHRlbXAucHJlZml4ICsgIjoiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSBhdHRyQW5kTmFtZXNwYWNlc1twXS5sb2NhbE5hbWUoKSArICc9IicgKyBFc2NhcGVBdHRyaWJ1dGVWYWx1ZShhdHRyQW5kTmFtZXNwYWNlc1twXS5fVmFsdWUpICsgJyInOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gInhtbG5zIjsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXggJiYgZGVmYXVsdFNldCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4ID0gbmV3UHJlZml4KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUoISFuYW1lc3BhY2VVbmlvblthdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXhdKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVuaW9uW2F0dHJBbmROYW1lc3BhY2VzW3BdLnByZWZpeF0gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlRGVjbGFyYXRpb25zW2F0dHJBbmROYW1lc3BhY2VzW3BdLnByZWZpeF0gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBOYW1lc3BhY2UoYXR0ckFuZE5hbWVzcGFjZXNbcF0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiOiIgKyBhdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFhdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXggJiYgIWRlZmF1bHRTZXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0U2V0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiOiIgKyBhdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICc9IicgKyBFc2NhcGVBdHRyaWJ1dGVWYWx1ZShhdHRyQW5kTmFtZXNwYWNlc1twXS51cmkpICsgJyInOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wID0gaW5wdXQuX0NoaWxkcmVuLmxlbmd0aDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGVtcCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMgKyAiLz4iOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBzICs9ICI+IjsKCiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gdGVtcCA+IDEgfHwgKHRlbXAgPT0gMSAmJiBpbnB1dC5fQ2xhc3MgIT09ICJ0ZXh0Iik7CgogICAgICAgICAgICAgICAgICAgICAgICBuYW1lcyA9ICghIVhNTC5wcmV0dHlQcmludGluZyAmJiAhIXRlbXAyKSA/IEluZGVudExldmVsICsgTnVtYmVyKFhNTC5wcmV0dHlJbmRlbnQpIDogMDsKCiAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeGVzID0gISFYTUwucHJldHR5UHJpbnRpbmcgJiYgISF0ZW1wMjsKCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAocCA9IDA7IHAgPCB0ZW1wOyArK3ApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVmaXhlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICJcclxuIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXQuX0NoaWxkcmVuW3BdKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gVG9YTUxTdHJpbmcoaW5wdXQuX0NoaWxkcmVuW3BdLCBuYW1lc3BhY2VEZWNsYXJhdGlvbnMsIG5hbWVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZWZpeGVzKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICJcclxuIjsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHAgPSAwOyBwIDwgSW5kZW50TGV2ZWw7ICsrcCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICIgIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMgKyAiPC8iICsgKG5hbWVzcGFjZS5wcmVmaXggPyBuYW1lc3BhY2UucHJlZml4ICsgIjoiIDogIiIpICsgaW5wdXQuX05hbWUubG9jYWxOYW1lICsgIj4iOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChpbnB1dCA9PT0gdW5kZWZpbmVkIHx8IGlucHV0ID09PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICJbb2JqZWN0IE9iamVjdF0iKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gRXNjYXBlRWxlbWVudFZhbHVlKCBpbnB1dC52YWx1ZU9mKCkudG9TdHJpbmcoKSApOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gVG9TdHJpbmcoaW5wdXQpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBtaXhlZCBzCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICogICAgQHRocm93cyBTeW50YXhFcnJvciB8IFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFRvWE1MIChzKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHgsIGRpdjsKCiAgICAgICAgICAgIGlmIChzIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHMubGVuZ3RoKCkgPT0gMSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc1swXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChzIGluc3RhbmNlb2YgWE1MKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICgoIixzdHJpbmcsbnVtYmVyLGJvb2xlYW4sIikuaW5kZXhPZigiLCIgKyB0eXBlb2YocykrIiwiKSA+IC0xKQogICAgICAgICAgICB7CgogICAgICAgICAgICAgICAgZGl2ID0gcGFyc2UoJzxwYXJlbnQgeG1sbnM9IicgKyBHZXREZWZhdWx0TmFtZXNwYWNlKCkgKyAnIj4nICsgcyArICc8L3BhcmVudD4nKTsKCiAgICAgICAgICAgICAgICB4ID0gVG9YTUwoZGl2LmRvY3VtZW50RWxlbWVudCkKCiAgICAgICAgICAgICAgICBpZiAoeCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoeC5sZW5ndGgoKSA9PSAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBYTUwoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoeC5sZW5ndGgoKSA9PSAxKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgeC5jaGlsZCgwKS5fUGFyZW50ID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHguY2hpbGQoMCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoIkZhaWxlZCB0byBjb252ZXJ0IERPTSBvYmplY3QgdG8gWE1MIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocy5ub2RlVHlwZSAmJiAhaXNOYU4ocy5ub2RlVHlwZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBNYXBJbmZvSXRlbVRvWE1MKHMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIERPTU5vZGUgaQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gTWFwSW5mb0l0ZW1Ub1hNTCAoaSxuKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHggPSBuZXcgWE1MKCksIHRlbXAsIHRlbXAyLCB0ZW1wMywgaXNOU2NoZWNrID0gaXNOU0RlZiwgaiwgbCwgeG1sQ2hpbGQ7CgogICAgICAgICAgICB4Ll9QYXJlbnQgPSBudWxsOwoKICAgICAgICAgICAgc3dpdGNoIChpLm5vZGVUeXBlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIFRFWFRfTk9ERToKICAgICAgICAgICAgICAgIGNhc2UgQ0RBVEFfU0VDVElPTl9OT0RFOgogICAgICAgICAgICAgICAgICAgIHguX0NsYXNzID0gInRleHQiOwogICAgICAgICAgICAgICAgICAgIHguX1ZhbHVlID0gIiI7CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGk7CgogICAgICAgICAgICAgICAgICAgIHdoaWxlICh0ZW1wICYmICh0ZW1wLm5vZGVUeXBlID09PSBURVhUX05PREUgfHwgdGVtcC5ub2RlVHlwZSA9PT0gQ0RBVEFfU0VDVElPTl9OT0RFKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHguX1ZhbHVlICs9IHRlbXAudGV4dENvbnRlbnQgfHwgdGVtcC50ZXh0IHx8IHRlbXAuZGF0YTsKICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IHRlbXAubmV4dFNpYmxpbmc7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuICYmIChuLm4gfHwgbi5uID09IDApKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICArK24ubjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCgogICAgICAgICAgICAgICAgICAgIGlmIChYTUwuaWdub3JlV2hpdGVzcGFjZSAmJiAheC5fVmFsdWUubWF0Y2goL1xTKy8pKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4geDsKCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIENPTU1FTlRfTk9ERToKICAgICAgICAgICAgICAgICAgICBpZiAoWE1MLmlnbm9yZUNvbW1lbnRzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB4Ll9DbGFzcyA9ICJjb21tZW50IjsKICAgICAgICAgICAgICAgICAgICB4Ll9WYWx1ZSA9IGkuZGF0YSB8fCBpLnRleHRDb250ZW50IHx8IGkudGV4dCB8fCAiIjsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHg7CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU6CiAgICAgICAgICAgICAgICAgICAgaWYgKFhNTC5pZ25vcmVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25zKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB4Ll9DbGFzcyA9ICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIjsKICAgICAgICAgICAgICAgICAgICB4Ll9OYW1lID0gbmV3IFFOYW1lKCIiLCBpLnRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgeC5fVmFsdWUgPSBpLmRhdGEgfHwgaS50ZXh0Q29udGVudCB8fCBpLnRleHQgfHwgIiI7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB4OwoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgQVRUUklCVVRFX05PREU6CiAgICAgICAgICAgICAgICAgICAgeC5fQ2xhc3MgPSAiYXR0cmlidXRlIjsKCiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGkubm9kZU5hbWUubWF0Y2goLygoW1x3XC1dKyk6KT8oW1x3XC1dKykvKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCB0ZW1wWzFdICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhaS5sb29rdXBOYW1lc3BhY2UpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gaS5sb29rdXBOYW1lc3BhY2UodGVtcFsyXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMyA9IG47Ly9oYWNrIGZvciBpZSAtLSBzdHVwaWQgaWUKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoIXRlbXAyICYmICEhdGVtcDMgJiYgISF0ZW1wMy5hdHRyaWJ1dGVzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDAsIGwgPSB0ZW1wMy5hdHRyaWJ1dGVzLmxlbmd0aDsgaiA8IGw7ICsraikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wMy5hdHRyaWJ1dGVzW2pdLm5vZGVOYW1lID09ICgieG1sbnM6IiArIHRlbXBbMl0pKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHRlbXAzLmF0dHJpYnV0ZXNbal0udmFsdWUgfHwgdGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDMgPSB0ZW1wMy5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHguX0RlZmF1bHROYW1lc3BhY2UgPSBuZXcgTmFtZXNwYWNlKCB0ZW1wWzJdLCB0ZW1wMiApOwogICAgICAgICAgICAgICAgICAgICAgICB4Ll9OYW1lID0gbmV3IFFOYW1lKCB4Ll9EZWZhdWx0TmFtZXNwYWNlLCB0ZW1wWzNdICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhaS5sb29rdXBOYW1lc3BhY2UpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gaS5sb29rdXBOYW1lc3BhY2UoIiIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDMgPSBpLnBhcmVudE5vZGU7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCF0ZW1wMiAmJiAhIXRlbXAzICYmICEhdGVtcDMuYXR0cmlidXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gdGVtcDMuYXR0cmlidXRlcy5sZW5ndGg7IGogPCBsOyArK2opCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlTmFtZSA9PSAieG1sbnMiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHRlbXAzLmF0dHJpYnV0ZXNbal0udmFsdWUgfHwgdGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDMgPSB0ZW1wMy5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB4Ll9EZWZhdWx0TmFtZXNwYWNlID0gbmV3IE5hbWVzcGFjZSgiIiwgdGVtcDIpOwogICAgICAgICAgICAgICAgICAgICAgICB4Ll9OYW1lID0gbmV3IFFOYW1lKCB4Ll9EZWZhdWx0TmFtZXNwYWNlLCB0ZW1wWzNdICk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB4Ll9WYWx1ZSA9IGkudmFsdWUgfHwgbnVsbDsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHg7CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBFTEVNRU5UX05PREU6CiAgICAgICAgICAgICAgICAgICAgeC5fQ2xhc3MgPSAiZWxlbWVudCI7CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGkubm9kZU5hbWUubWF0Y2goLygoW1x3XC1dKyk6KT8oW1x3XC1dKykvKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCB0ZW1wWzFdICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhaS5sb29rdXBOYW1lc3BhY2UpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gaS5sb29rdXBOYW1lc3BhY2UodGVtcFsyXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMyA9IGk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCF0ZW1wMiAmJiAhIXRlbXAzICYmICEhdGVtcDMuYXR0cmlidXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gdGVtcDMuYXR0cmlidXRlcy5sZW5ndGg7IGogPCBsOyArK2opCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlTmFtZSA9PSAoInhtbG5zOiIgKyB0ZW1wWzJdKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDIgPSB0ZW1wMy5hdHRyaWJ1dGVzW2pdLnZhbHVlIHx8IHRlbXAzLmF0dHJpYnV0ZXNbal0ubm9kZVZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAzID0gdGVtcDMucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB4Ll9EZWZhdWx0TmFtZXNwYWNlID0gbmV3IE5hbWVzcGFjZSggdGVtcFsyXSwgdGVtcDIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgeC5fTmFtZSA9IG5ldyBRTmFtZSggeC5fRGVmYXVsdE5hbWVzcGFjZSwgdGVtcFszXSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWkubG9va3VwTmFtZXNwYWNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IGkubG9va3VwTmFtZXNwYWNlKCIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAzID0gaTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoIXRlbXAyICYmICEhdGVtcDMgJiYgISF0ZW1wMy5hdHRyaWJ1dGVzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDAsIGwgPSB0ZW1wMy5hdHRyaWJ1dGVzLmxlbmd0aDsgaiA8IGw7ICsraikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wMy5hdHRyaWJ1dGVzW2pdLm5vZGVOYW1lID09ICJ4bWxucyIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gdGVtcDMuYXR0cmlidXRlc1tqXS52YWx1ZSB8fCB0ZW1wMy5hdHRyaWJ1dGVzW2pdLm5vZGVWYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMyA9IHRlbXAzLnBhcmVudE5vZGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHguX0RlZmF1bHROYW1lc3BhY2UgPSBuZXcgTmFtZXNwYWNlKCIiLCB0ZW1wMik7CgogICAgICAgICAgICAgICAgICAgICAgICB4Ll9OYW1lID0gbmV3IFFOYW1lKCB4Ll9EZWZhdWx0TmFtZXNwYWNlLCB0ZW1wWzNdICk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBmb3IgKHRlbXAgPSAwLCB0ZW1wMiA9IGkuYXR0cmlidXRlcy5sZW5ndGg7IHRlbXAgPCB0ZW1wMjsgKyt0ZW1wKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAzID0gaXNOU2NoZWNrLmV4ZWMoaS5hdHRyaWJ1dGVzW3RlbXBdLm5vZGVOYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeC5fSW5TY29wZU5hbWVzcGFjZXNbdGVtcDNbMV1dID0gbmV3IE5hbWVzcGFjZSh0ZW1wM1sxXSwgaS5hdHRyaWJ1dGVzW3RlbXBdLnZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChpLmF0dHJpYnV0ZXNbdGVtcF0ubm9kZU5hbWUgPT09ICJ4bWxucyIpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHguX0luU2NvcGVOYW1lc3BhY2VzWyIiXSA9IG5ldyBOYW1lc3BhY2UoaS5hdHRyaWJ1dGVzW3RlbXBdLnZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHguX0F0dHJpYnV0ZXNbaS5hdHRyaWJ1dGVzW3RlbXBdLm5vZGVOYW1lXSA9IE1hcEluZm9JdGVtVG9YTUwoaS5hdHRyaWJ1dGVzW3RlbXBdLCBpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaiA9IDA7CiAgICAgICAgICAgICAgICAgICAgeG1sQ2hpbGQgPSAwOwogICAgICAgICAgICAgICAgICAgIHRlbXAgPSBpLmNoaWxkTm9kZXMubGVuZ3RoOwoKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaiA8IHRlbXApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuID0ge246LTF9OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcDMgPSBNYXBJbmZvSXRlbVRvWE1MKGkuY2hpbGROb2Rlc1tqXSwgbikpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZXZlbiB0aG91Z2ggaXQgaXMgbm90IHdyaXR0ZW4gdGhpcyB3YXkgaW4gdGhlIHNwZWMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcyBpcyBob3cgaXQgd29ya3MgaW4gRmlyZWZveAogICAgICAgICAgICAgICAgICAgICAgICAgICAgeC5fQ2hpbGRyZW5beG1sQ2hpbGRdID0gdGVtcDM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4Ll9DaGlsZHJlblt4bWxDaGlsZF0uX1BhcmVudCA9IHg7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAzLl9DbGFzcyA9PT0gInRleHQiICYmIG4ubiA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaiA9IGogKyBuLm47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKyt4bWxDaGlsZDsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgKytqOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeC5fVmFsdWUgPSBpLnRleHRDb250ZW50IHx8IGkudGV4dCB8fCBpLmRhdGEgfHwgIiI7CgogICAgICAgICAgICAgICAgICAgIHguX0xlbmd0aCA9IHhtbENoaWxkOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4geDsKCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIERPQ1VNRU5UX05PREU6CiAgICAgICAgICAgICAgICAvL2ZpcmVmb3ggd29uJ3QgZG8gdGhpcwogICAgICAgICAgICAgICAgLy9yZXR1cm4gTWFwSW5mb0l0ZW1Ub1hNTChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpOwogICAgICAgICAgICAgICAgLy9icmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRU5USVRZX1JFRkVSRU5DRV9OT0RFOgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gbWl4ZWQgcwogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gVG9YTUxMaXN0IChzKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGUseCxsaXN0LGksbDsKCiAgICAgICAgICAgIGlmIChzIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocyBpbnN0YW5jZW9mIFhNTCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbGlzdCA9IG5ldyBYTUxMaXN0KCk7CiAgICAgICAgICAgICAgICBsaXN0Ll9DaGlsZHJlblswXSA9IGxpc3RbMF0gPSBzOwogICAgICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0geC5fUGFyZW50OwogICAgICAgICAgICAgICAgbGlzdC5fVGFyZ2V0UHJvcGVydHkgPSB4Ll9OYW1lOwoKICAgICAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKCgiLHN0cmluZyxib29sZWFuLG51bWJlciwiKS5pbmRleE9mKCIsIiArIHR5cGVvZihzKSsiLCIpID09PSAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBlID0gcGFyc2UoJzxwYXJlbnQgeG1sbnM9IicgKyBHZXREZWZhdWx0TmFtZXNwYWNlKCkgKyAnIj4nICsgcyArICc8L3BhcmVudD4nKTsKICAgICAgICAgICAgeCA9IFRvWE1MKGUuZG9jdW1lbnRFbGVtZW50KTsKICAgICAgICAgICAgbGlzdCA9IG5ldyBYTUxMaXN0KCk7CiAgICAgICAgICAgIGkgPSAwOwogICAgICAgICAgICBsID0geC5fQ2hpbGRyZW4ubGVuZ3RoOwoKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gbnVsbDsKCiAgICAgICAgICAgIGZvciAoO2kgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHguX0NoaWxkcmVuW2ldLl9QYXJlbnQgPSBudWxsOwogICAgICAgICAgICAgICAgbGlzdC5fQ2hpbGRyZW5baV0gPSBsaXN0W2ldID0geC5fQ2hpbGRyZW5baV07CiAgICAgICAgICAgIH0KCgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gbWl4ZWQgcwogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFRvQXR0cmlidXRlTmFtZSAocykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChzID09PSAiKiIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlTmFtZShuZXcgUU5hbWUobnVsbCwgIioiKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocyBpbnN0YW5jZW9mIFFOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZU5hbWUocyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocyBpbnN0YW5jZW9mIEF0dHJpYnV0ZU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzd2l0Y2ggKHR5cGVvZihzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSAidW5kZWZpbmVkIjoKICAgICAgICAgICAgICAgIGNhc2UgIm51bGwiOgogICAgICAgICAgICAgICAgY2FzZSAiYm9vbGVhbiI6CiAgICAgICAgICAgICAgICBjYXNlICJudW1iZXIiOgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInN0cmluZyI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGVOYW1lKG5ldyBRTmFtZShudWxsLCAocyArICIiKS5yZXBsYWNlKC9eQC8sIiIpKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJvYmplY3QiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlTmFtZShuZXcgUU5hbWUobnVsbCwgVG9TdHJpbmcocykpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBtaXhlZCBzCiAgICAgICAgICogICAgQHJldHVybnMgUU5hbWUgfCBBdHRyaWJ1dGVOYW1lCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBUb1hNTE5hbWUgKHMpCiAgICAgICAgewogICAgICAgICAgICBpZiAocyBpbnN0YW5jZW9mIFFOYW1lIHx8IHMgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChzID09PSAiKiIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUU5hbWUoIioiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3dpdGNoICh0eXBlb2YocykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgInVuZGVmaW5lZCI6CiAgICAgICAgICAgICAgICBjYXNlICJudWxsIjoKICAgICAgICAgICAgICAgIGNhc2UgImJvb2xlYW4iOgogICAgICAgICAgICAgICAgY2FzZSAibnVtYmVyIjoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJzdHJpbmciOgogICAgICAgICAgICAgICAgICAgIGlmIChzLmNoYXJBdCgwKSA9PT0gIkAiKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRvQXR0cmlidXRlTmFtZSggcy5zdWJzdHIoMCkgKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUU5hbWUocyk7CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAib2JqZWN0IjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVG9YTUxOYW1lKCBUb1N0cmluZyhzKSApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gR2V0RGVmYXVsdE5hbWVzcGFjZSAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICEhZGVmYXVsdE5hbWVzcGFjZSAmJiBkZWZhdWx0TmFtZXNwYWNlLnVyaSB8fCAiIjsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHMKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBFc2NhcGVFbGVtZW50VmFsdWUgKHMpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gKChzfHwiIikrIiIpLnJlcGxhY2UoLy4vZywgZnVuY3Rpb24gKGMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICI8IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImbHQ7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICI+IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImZ3Q7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICImIjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImYW1wOyI7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBzCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gRXNjYXBlQXR0cmlidXRlVmFsdWUgKHMpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gKChzfHwiIikrIiIpLnJlcGxhY2UoLy4vZywgZnVuY3Rpb24gKGMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICciJzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImcXVvdDsiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIjwiOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiZsdDsiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIj4iOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiZndDsiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIiYiOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiZhbXA7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICJcciI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiJiN4QTsiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIlxuIjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImI3hEOyI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiXHQiOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiYjeDk7IjsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBHZXQgKFByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIEdldExpc3QuY2FsbCh0aGlzLCBQcm9wZXJ0eU5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocGFyc2VJbnQoUHJvcGVydHlOYW1lKSsiIiA9PSBQcm9wZXJ0eU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBHZXRMaXN0LmNhbGwoVG9YTUxMaXN0KHRoaXMpLCBQcm9wZXJ0eU5hbWUgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIG4gPSBUb1hNTE5hbWUoUHJvcGVydHlOYW1lKSwKICAgICAgICAgICAgICAgIGxpc3QgPSBuZXcgWE1MTGlzdCgpLCBwLCBsOwoKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gdGhpczsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0UHJvcGVydHkgPSBuOwoKICAgICAgICAgICAgaWYgKG4gaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKHAgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgIChuLl9OYW1lLmxvY2FsTmFtZSA9PT0gIioiIHx8IG4uX05hbWUubG9jYWxOYW1lID09PSB0aGlzLl9BdHRyaWJ1dGVzW3BdLl9OYW1lLmxvY2FsTmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKG4uX05hbWUudXJpID09IG51bGwgfHwgbi5fTmFtZS51cmkgPT09IHRoaXMuX0F0dHJpYnV0ZXNbcF0uX05hbWUudXJpKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRoaXMuX0F0dHJpYnV0ZXNbcF0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAocCA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IHAgPCBsOyArK3ApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAobi5sb2NhbE5hbWUgPT09ICIqIiB8fCAodGhpcy5fQ2hpbGRyZW5bcF0uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgdGhpcy5fQ2hpbGRyZW5bcF0uX05hbWUubG9jYWxOYW1lID09PSBuLmxvY2FsTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChuLnVyaSA9PSBudWxsIHx8ICh0aGlzLl9DaGlsZHJlbltwXS5fQ2xhc3MgPT09ICJlbGVtZW50IiAmJiBuLnVyaSA9PT0gdGhpcy5fQ2hpbGRyZW5bcF0uX05hbWUudXJpKSkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZCh0aGlzLl9DaGlsZHJlbltwXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEhhc1Byb3BlcnR5IChQKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gSGFzUHJvcGVydHlMaXN0LmNhbGwodGhpcywgUCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChwYXJzZUludChQKSA9PSBQKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gUCA9PSAiMCI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBuID0gVG9YTUxOYW1lKFApLCBrLCBsOwoKICAgICAgICAgICAgaWYgKG4gaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGsgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4uX05hbWUubG9jYWxOYW1lID09PSAiKiIgfHwgbi5fTmFtZS5sb2NhbE5hbWUgPT09IHRoaXMuX0F0dHJpYnV0ZXNba10uX05hbWUubG9jYWxOYW1lCiAgICAgICAgICAgICAgICAgICAgICAgICkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbi5fTmFtZS51cmkgPT0gbnVsbCB8fCBuLl9OYW1lLnVyaSA9PT0gdGhpcy5fQXR0cmlidXRlc1trXS5fTmFtZS51cmkKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoayA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGsgPCBsOyArK2spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAobi5sb2NhbE5hbWUgPT09ICIqIiB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgdGhpcy5fQ2hpbGRyZW5ba10uX05hbWUubG9jYWxOYW1lID09PSBuLmxvY2FsTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICAgICAobi51cmkgPT0gbnVsbCB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgbi51cmkgPT09IHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLnVyaSkpCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBEZWxldGVCeUluZGV4IChQcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICB2YXIgaSA9IHBhcnNlSW50KFByb3BlcnR5TmFtZSk7Ly8sIHEgPSBpICsgMSwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKCiAgICAgICAgICAgIGlmIChpID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5fQ2hpbGRyZW5baV0pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0uX1BhcmVudCA9IG51bGw7CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldID0gbnVsbDsKCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW4uc3BsaWNlKGksIDEpOwoKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICBmb3IgKDtxIDwgbDsrK3EpCiAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bcS0xXSA9IHRoaXMuX0NoaWxkcmVuW3FdOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIERlZXBDb3B5ICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBEZWVwQ29weUxpc3QuY2FsbCh0aGlzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHkgPSBuZXcgWE1MKCksIGksIGw7Ly8sIGMsIHQ7CgogICAgICAgICAgICB5Ll9DbGFzcyA9IHRoaXMuX0NsYXNzOwogICAgICAgICAgICB5Ll9OYW1lID0gdGhpcy5fTmFtZTsKICAgICAgICAgICAgeS5fRGVmYXVsdE5hbWVzcGFjZSA9IHRoaXMuX0RlZmF1bHROYW1lc3BhY2UgPyBuZXcgTmFtZXNwYWNlKHRoaXMuX0RlZmF1bHROYW1lc3BhY2UpIDogbnVsbDsKICAgICAgICAgICAgeS5fVmFsdWUgPSB0aGlzLl9WYWx1ZTsKICAgICAgICAgICAgeS5fUGFyZW50ID0gbnVsbDsKCiAgICAgICAgICAgIGZvciAoaSBpbiB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgeS5fSW5TY29wZU5hbWVzcGFjZXNbaV0gPSBuZXcgTmFtZXNwYWNlKHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzLnByZWZpeCwgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMudXJpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChsIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8veS5fQXR0cmlidXRlc1tpXSA9IGFyZ3VtZW50cy5jYWxsZWUuY2FsbCh0aGlzLl9BdHRyaWJ1dGVzW2ldKTsKICAgICAgICAgICAgICAgIC8vbm90IHBhcnQgb2YgdGhlIHNwZWMKICAgICAgICAgICAgICAgIHkuX0F0dHJpYnV0ZXNbaV0gPSB0aGlzLl9BdHRyaWJ1dGVzW2xdLmNvcHkoKTsKICAgICAgICAgICAgICAgIHkuX0F0dHJpYnV0ZXNbaV0uX1BhcmVudCA9IHk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHkuX0NoaWxkcmVuW2ldID0gdGhpcy5fQ2hpbGRyZW5baV0uY29weSgpOwogICAgICAgICAgICAgICAgeS5fQ2hpbGRyZW5baV0uX1BhcmVudCA9IHk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB5OwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gUmVzb2x2ZVZhbHVlICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBSZXNvbHZlVmFsdWVMaXN0LmNhbGwodGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBYTUwgPyB0aGlzIDogbnVsbDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gRGVzY2VuZGFudHMgKFByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIERlc2NlbmRhbnRzTGlzdC5jYWxsKHRoaXMsIFByb3BlcnR5TmFtZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBuID0gVG9YTUxOYW1lKFByb3BlcnR5TmFtZSksCiAgICAgICAgICAgICAgICBsaXN0ID0gbmV3IFhNTExpc3QoKSwKICAgICAgICAgICAgICAgIGssIGwsIGRxOwoKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gbnVsbDsKCiAgICAgICAgICAgIGlmIChuIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChrIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAobi5fTmFtZS5sb2NhbE5hbWUgPT09ICIqIiB8fCBuLl9OYW1lLmxvY2FsTmFtZSA9PT0gdGhpcy5fQXR0cmlidXRlc1trXS5fTmFtZS5sb2NhbE5hbWUpCiAgICAgICAgICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChuLl9OYW1lLnVyaSA9PSBudWxsIHx8IG4uX05hbWUudXJpID09PSB0aGlzLl9BdHRyaWJ1dGVzW2tdLl9OYW1lLnVyaSkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZCh0aGlzLl9BdHRyaWJ1dGVzW2tdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoayA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGsgPCBsOyArK2spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAobi5sb2NhbE5hbWUgPT09ICIqIiB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgdGhpcy5fQ2hpbGRyZW5ba10uX05hbWUubG9jYWxOYW1lID09PSBuLmxvY2FsTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICAgICAobi51cmkgPT0gbnVsbCB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgbi51cmkgPT09IHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLnVyaSkpCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQodGhpcy5fQ2hpbGRyZW5ba10pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGRxID0gdGhpcy5fQ2hpbGRyZW5ba10uZGVzY2VuZGFudHMobik7CgogICAgICAgICAgICAgICAgaWYgKGRxLmxlbmd0aCgpID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChkcSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgVmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBudWxsCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IgfCBFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEluc2VydCAoUHJvcGVydHlOYW1lLCBWYWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIix0ZXh0LGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbixhdHRyaWJ1dGUsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgaSA9IHBhcnNlSW50KFByb3BlcnR5TmFtZSksIG4sIGo7CgogICAgICAgICAgICBpZiAoaSsiIiAhPSBQcm9wZXJ0eU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoIiciICsgaSArICInICE9ICciICsgUHJvcGVydHlOYW1lICsgIiciKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKFZhbHVlID09PSB0aGlzIHx8IGluZGV4T2YoIiwiICsgdGhpcywgVmFsdWUuZGVzY2VuZGFudHMoIioiKSkgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG4gPSBWYWx1ZS5sZW5ndGgoKTsKCiAgICAgICAgICAgIGZvciAoaiA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCAtIDE7IGogPj0gaTsgLS1qKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlblsgaiArIG4gXSA9IHRoaXMuX0NoaWxkcmVuW2pdOwogICAgICAgICAgICB9CgoKICAgICAgICAgICAgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IG47ICsraikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBWYWx1ZVtqXS5fUGFyZW50ID0gdGhpczsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpICsgal0gPSBWYWx1ZVtqXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbCh0aGlzLCBpLCBWYWx1ZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgVmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBudWxsCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBSZXBsYWNlIChQcm9wZXJ0eU5hbWUsIFZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgiLHRleHQsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLGF0dHJpYnV0ZSwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGkgPSBwYXJzZUludChQcm9wZXJ0eU5hbWUpLCB0OwoKICAgICAgICAgICAgaWYgKGkrIiIgIT0gUHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCInIiArIGkgKyAiJyAhPSAnIiArIFByb3BlcnR5TmFtZSArICInIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpID49IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUHJvcGVydHlOYW1lID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBEZWxldGVCeUluZGV4LmNhbGwodGhpcywgUHJvcGVydHlOYW1lKTsKICAgICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIFByb3BlcnR5TmFtZSwgVmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MCiAgICAgICAgICAgICAgICAmJiBWYWx1ZS5fQ2xhc3MgPT09ICJlbGVtZW50IgogICAgICAgICAgICAgICAgJiYgKCIsZWxlbWVudCxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sdGV4dCIpLmluZGV4T2YoIiwiICsgVmFsdWUuX0NsYXNzICsgIiwiKSA+IC0xCiAgICAgICAgICAgICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVmFsdWUuX1BhcmVudCA9IHRoaXM7CgogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW1Byb3BlcnR5TmFtZV0pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bUHJvcGVydHlOYW1lXS5fUGFyZW50ID0gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltQcm9wZXJ0eU5hbWVdID0gVmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0ID0gbmV3IFhNTCgpOwogICAgICAgICAgICAgICAgdC5fUGFyZW50ID0gdGhpczsKICAgICAgICAgICAgICAgIHQuX1ZhbHVlID0gVG9TdHJpbmcoVmFsdWUpOwoKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltQcm9wZXJ0eU5hbWVdKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW1Byb3BlcnR5TmFtZV0uX1BhcmVudCA9IG51bGw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bUHJvcGVydHlOYW1lXSA9IHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTmFtZXNwYWNlIE5hbWVTcGFjZQogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBBZGRJblNjb3BlTmFtZXNwYWNlIChOYW1lU3BhY2UpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsdGV4dCxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sYXR0cmlidXRlLCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbWF0Y2ggPSBudWxsLCBwOwoKICAgICAgICAgICAgaWYgKE5hbWVTcGFjZS5wcmVmaXggPT0gIiIgJiYgdGhpcy5fTmFtZS51cmkgPT0gIiIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHAgaW4gdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChOYW1lU3BhY2UucHJlZml4ID09PSB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1twXS5wcmVmaXgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggPSB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1twXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG1hdGNoICYmIG1hdGNoLnVyaSAhPSBOYW1lU3BhY2UudXJpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1ttYXRjaC5wcmVmaXhdID0gbnVsbDsKICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbbWF0Y2gucHJlZml4XTsKICAgICAgICAgICAgICAgIH1jYXRjaChlKXt9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW05hbWVTcGFjZS5wcmVmaXhdID0gTmFtZVNwYWNlOwoKICAgICAgICAgICAgaWYgKHRoaXMuX05hbWUucHJlZml4ID09PSBOYW1lU3BhY2UucHJlZml4KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aGlzLl9OYW1lLnByZWZpeCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChwIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9BdHRyaWJ1dGVzW3BdLl9OYW1lLnByZWZpeCA9IE5hbWVTcGFjZS5wcmVmaXgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQXR0cmlidXRlc1twXS5fTmFtZS5wcmVmaXggPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vZG8gdGhpcyBpbiBvcmRlciB0byBlbnN1cmUgbmFtZXNwYWNlIGludGVncml0eQogICAgICAgICAgICAvKm1hdGNoID0gcGFyc2UodGhpcy50b1hNTFN0cmluZygpKTsKICAgICAgICAgICAgIHRoaXMuX05vZGUgPSAhIXRoaXMuX05vZGUucGFyZW50Tm9kZQogICAgICAgICAgICAgPyB0aGlzLl9Ob2RlLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG1hdGNoLmRvY3VtZW50RWxlbWVudCwgdGhpcy5fTm9kZSkKICAgICAgICAgICAgIDogbWF0Y2g7Ki8KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTnVtYmVyIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gSGFzUHJvcGVydHlMaXN0IChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKFRvU3RyaW5nKCBwYXJzZUludChuYW1lKSApID09PSBuYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQobmFtZSkgPCB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fQ2xhc3MgPT09ICJlbGVtZW50IiAmJiB0aGlzW2ldLmhhc093blByb3BlcnR5KG5hbWUpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTnVtYmVyIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEdldExpc3QgKFByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwYXJzZUludChQcm9wZXJ0eU5hbWUpKyIiID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXNbUHJvcGVydHlOYW1lXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgWE1MTGlzdCgpLCBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCwgdGVtcDsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gdGhpczsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0UHJvcGVydHkgPSBQcm9wZXJ0eU5hbWU7CgogICAgICAgICAgICBmb3IgKDtpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5baV0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IEdldC5jYWxsKHRoaXMuX0NoaWxkcmVuW2ldLCBQcm9wZXJ0eU5hbWUpOwoKICAgICAgICAgICAgICAgICAgICBpZiAodGVtcC5fQ2hpbGRyZW4ubGVuZ3RoID4gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRlbXApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gRGVlcENvcHlMaXN0ICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwoKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gdGhpcy5fVGFyZ2V0T2JqZWN0OwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRQcm9wZXJ0eSA9IHRoaXMuX1RhcmdldFByb3BlcnR5OwogICAgICAgICAgICBsaXN0Ll9DbGFzcyA9IHRoaXMuX0NsYXNzOwogICAgICAgICAgICBsaXN0Ll9WYWx1ZSA9IHRoaXMuX1ZhbHVlOwoKICAgICAgICAgICAgZm9yICg7aSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQoRGVlcENvcHkuY2FsbCh0aGlzW2ldKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBEZXNjZW5kYW50c0xpc3QgKFByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIHRlbXA7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXNbaV0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCh0ZW1wID0gRGVzY2VuZGFudHMuY2FsbCh0aGlzW2ldLCAiKiIpKSAmJiB0ZW1wLmxlbmd0aCgpID4gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRlbXApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiAgICBodHRwOi8vYmxvZy5zdGV2ZW5sZXZpdGhhbi5jb20vYXJjaGl2ZXMvZmFzdGVyLXRyaW0tamF2YXNjcmlwdAogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHMKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiB0cmltIChzdHIpCiAgICAgICAgewogICAgICAgICAgICBpZighc3RyKQogICAgICAgICAgICAgICAgcmV0dXJuIHN0cjsKICAgICAgICAgICAgdmFyICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9eXHNccyovLCAiIiksCiAgICAgICAgICAgICAgICB3cyA9IC9ccy8sCiAgICAgICAgICAgICAgICBpID0gc3RyLmxlbmd0aDsKICAgICAgICAgICAgd2hpbGUgKHdzLnRlc3Qoc3RyLmNoYXJBdCgtLWkpKSk7CiAgICAgICAgICAgIHJldHVybiBzdHIuc2xpY2UoMCwgaSArIDEpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogICAgR2VuZXJhdGVzIGEgcHJlZml4IGZvciBhIFFOYW1lIHRoYXQgaXMgbm90IGFscmVhZHkKICAgICAgICAgKiAgICBhIHByb3BlcnR5IG9mIHRoZSBvcHRpb25hbCBhcmd1bWVudAogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIE9iamVjdCBwcmVmaXhlcwogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIG5ld1ByZWZpeCAocHJlZml4ZXMpCiAgICAgICAgewogICAgICAgICAgICBwcmVmaXhlcyA9IHByZWZpeGVzIHx8IHt9OwoKICAgICAgICAgICAgdmFyIG51bSA9IE1hdGgucmFuZG9tKCkKICAgICAgICAgICAgICAgIC50b1N0cmluZygpCiAgICAgICAgICAgICAgICAuc3Vic3RyKDIpCiAgICAgICAgICAgICAgICAucmVwbGFjZSgvLnsyfS9nLCBmdW5jdGlvbiAoYSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBhID0gTnVtYmVyKGEpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAoYSA+IDkwID8gOTAgOiAoYSA8IDY1ID8gNjUgOiBhKSkgKyAiIjsKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgbnVtID0gU3RyaW5nLmZyb21DaGFyQ29kZSgKICAgICAgICAgICAgICAgIE51bWJlcihudW0uc3Vic3RyKDAsIDIpKSAmIDB4RkYsCiAgICAgICAgICAgICAgICBOdW1iZXIobnVtLnN1YnN0cigyLCAyKSkgJiAweEZGLAogICAgICAgICAgICAgICAgTnVtYmVyKG51bS5zdWJzdHIoNCwgMikpICYgMHhGRiwKICAgICAgICAgICAgICAgIE51bWJlcihudW0uc3Vic3RyKDYsIDIpKSAmIDB4RkYsCiAgICAgICAgICAgICAgICBOdW1iZXIobnVtLnN1YnN0cig4LCAyKSkgJiAweEZGLAogICAgICAgICAgICAgICAgTnVtYmVyKG51bS5zdWJzdHIoMTAsIDIpKSAmIDB4RkYKICAgICAgICAgICAgKS50b0xvd2VyQ2FzZSgpOwoKICAgICAgICAgICAgd2hpbGUgKG51bSBpbiBwcmVmaXhlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbnVtID0gYXJndW1lbnRzLmNhbGxlZShwcmVmaXhlcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudW07CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBzdHIKICAgICAgICAgKiAgICBAcmV0dXJucyBET01Ob2RlCiAgICAgICAgICogICAgQHRocm93cyBTeW50YXhFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIHBhcnNlIChzdHIpCiAgICAgICAgewogICAgICAgICAgICB2YXIgeG1sRG9jLCBzdWNjZXNzID0gdHJ1ZTsKCiAgICAgICAgICAgIGlmIChpc0FjdGl2ZVhTdXBwb3J0ZWQoIk1pY3Jvc29mdC5YTUxET00iKSkgLy9JbnRlcm5ldCBFeHBsb3JlcgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0cnl7CiAgICAgICAgICAgICAgICAgICAgeG1sRG9jICAgICAgICAgICAgICAgICAgICAgID0gbmV3IEFjdGl2ZVhPYmplY3QoIk1pY3Jvc29mdC5YTUxET00iKTsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MuYXN5bmMgICAgICAgICAgICAgICAgPSAnZmFsc2UnOwogICAgICAgICAgICAgICAgICAgIHhtbERvYy5wcmVzZXJ2ZVdoaXRlU3BhY2UgICA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgeG1sRG9jLnJlc29sdmVFeHRlcm5hbHMgICAgID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgeG1sRG9jLnZhbGlkYXRlT25QYXJzZSAgICAgICAgID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgeG1sRG9jLnNldFByb3BlcnR5KCdQcm9oaWJpdERURCcsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0geG1sRG9jLmxvYWRYTUwoc3RyKTsKICAgICAgICAgICAgICAgIH1jYXRjaChlKXt9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0cnl7Ly9GaXJlZm94LCBNb3ppbGxhLCBPcGVyYSwgZXRjLgogICAgICAgICAgICAgICAgICAgIHhtbERvYyA9IG5ldyBET01QYXJzZXIoKTsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MgPSB4bWxEb2MucGFyc2VGcm9tU3RyaW5nKHN0ciwgInRleHQveG1sIik7CiAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIXN1Y2Nlc3MgfHwgIXhtbERvYyB8fCB4bWxEb2MuZG9jdW1lbnRFbGVtZW50Lm5vZGVOYW1lID09ICJwYXJzZXJlcnJvciIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcighIXhtbERvYyAmJiB4bWxEb2MuZG9jdW1lbnRFbGVtZW50LmNoaWxkTm9kZXNbMF0ubm9kZVZhbHVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHhtbERvYzsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gT2JqZWN0IG9iagogICAgICAgICAqICAgIEByZXR1cm5zIE51bWJlcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIGNvdW50IChvYmopCiAgICAgICAgewogICAgICAgICAgICBpZiAoIl9fY291bnRfXyIgaW4gb2JqKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gb2JqLl9fY291bnRfXzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGkgPSAwLCBrOwoKICAgICAgICAgICAgZm9yIChrIGluIG9iaikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICArK2k7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBPYmplY3Qgb2JqCiAgICAgICAgICogICAgQHBhcmFtIFhNTExpc3QgbGlzdAogICAgICAgICAqICAgIEByZXR1cm5zIE51bWJlcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIGluZGV4T2YgKG9iaiwgbGlzdCkKICAgICAgICB7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gbGlzdC5sZW5ndGgoKTsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGxpc3RbaV0uRXF1YWxzKG9iaikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gbWl4ZWQgb2JqCiAgICAgICAgICogICAgQHBhcmFtIG1peGVkIC4uLgogICAgICAgICAqICAgIEByZXR1cm5zIG1peGVkCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gZXh0ZW5kIChvYmopCiAgICAgICAgewogICAgICAgICAgICBmb3IgKHZhciBwLCBpID0gMSwgbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAocCBpbiBhcmd1bWVudHNbaV0pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgb2JqW3BdID0gYXJndW1lbnRzW2ldW3BdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gb2JqOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gY3JlYXRlRG9jdW1lbnRGcm9tICh4bWwpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gcGFyc2UoeG1sLmxlbmd0aCgpID09IDEgPyB4bWwudG9YTUxTdHJpbmcoKSA6ICI8eD4iICsgeG1sLnRvWE1MU3RyaW5nKCkgKyAiPC94PiIpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24geG1sVG9Eb21Ob2RlICh4bWwpCiAgICAgICAgewogICAgICAgICAgICBzd2l0Y2ggKHhtbC5ub2RlS2luZCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlICJlbGVtZW50IjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlRG9jdW1lbnRGcm9tKHhtbCkuZG9jdW1lbnRFbGVtZW50OwoKICAgICAgICAgICAgICAgIGNhc2UgInRleHQiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiB4bWxEb2MuY3JlYXRlVGV4dE5vZGUoeG1sLnRvU3RyaW5nKCkpOwoKICAgICAgICAgICAgICAgIGNhc2UgImNvbW1lbnQiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiB4bWxEb2MuY3JlYXRlQ29tbWVudCh4bWwudG9TdHJpbmcoKS5zbGljZSg0LCAtMykpOwoKICAgICAgICAgICAgICAgIGNhc2UgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iOgogICAgICAgICAgICAgICAgICAgIHJldHVybiB4bWxEb2MuY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICB4bWwubG9jYWxOYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbC50b1N0cmluZygpLnNsaWNlKDIsIC0yKS5yZXBsYWNlKHBpTmFtZSwgIiIpCiAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBjYXNlICJhdHRyaWJ1dGUiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVOUyh4bWwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gYWRvcHROb2RlIChkb2MsIG5vZGUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoISFkb2MuYWRvcHROb2RlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZG9jLmFkb3B0Tm9kZShub2RlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGIgPSBkb2MuZG9jdW1lbnRFbGVtZW50IHx8IGRvYy5ib2R5OwogICAgICAgICAgICByZXR1cm4gYi5yZW1vdmVDaGlsZChiLmFwcGVuZENoaWxkKG5vZGUpKTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIGV2YWx1YXRlIChkb2MsIGV4cHIsIHhtbCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciByZXMsIGwsIG4gPSAiIjsKCiAgICAgICAgICAgIGlmICghIWRvYy5ldmFsdWF0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzID0gZG9jLmV2YWx1YXRlKAogICAgICAgICAgICAgICAgICAgIGV4cHIsCiAgICAgICAgICAgICAgICAgICAgZG9jLAogICAgICAgICAgICAgICAgICAgIGRvYy5jcmVhdGVOU1Jlc29sdmVyKGRvYyksCiAgICAgICAgICAgICAgICAgICAgWFBhdGhSZXN1bHQuT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUsCiAgICAgICAgICAgICAgICAgICAgbnVsbAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBsID0gW107CgogICAgICAgICAgICAgICAgd2hpbGUobiA9IHJlcy5pdGVyYXRlTmV4dCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxbbC5sZW5ndGhdID0gbjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCJzZXRQcm9wZXJ0eSIgaW4gZG9jKXsKCiAgICAgICAgICAgICAgICByZXMgPSBhbGxOYW1lc3BhY2VzKHhtbCk7CgogICAgICAgICAgICAgICAgaWYgKGNvdW50KHJlcykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChsIGluIHJlcykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG4gKz0gIiB4bWxuczoiICsgbCArICc9IicgKyBFc2NhcGVBdHRyaWJ1dGVWYWx1ZShyZXNbbF0pICsgJyInOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgZG9jLnNldFByb3BlcnR5KCdTZWxlY3Rpb25OYW1lc3BhY2VzJywgbi5zdWJzdHIoMSkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGRvYy5zZXRQcm9wZXJ0eSgiU2VsZWN0aW9uTGFuZ3VhZ2UiLCAiWFBhdGgiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGlzQWN0aXZlWFN1cHBvcnRlZCgiTWljcm9zb2Z0LlhNTERPTSIpICYmIGRvYy5zZWxlY3ROb2RlcyhleHByKTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIGlzQWN0aXZlWFN1cHBvcnRlZCh0eXBlKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBuZXcgQWN0aXZlWE9iamVjdCh0eXBlKTsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIGFsbE5hbWVzcGFjZXMgKHhtbCwgdW4pCiAgICAgICAgewogICAgICAgICAgICB2YXIgbnMgPSB1biB8fCB7fSwKICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgYyA9IHhtbC5jaGlsZHJlbigpLAogICAgICAgICAgICAgICAgbCA9IGMubGVuZ3RoKCksCiAgICAgICAgICAgICAgICBuID0gdW4gPT0gdW5kZWZpbmVkCiAgICAgICAgICAgICAgICAgICAgPyBpbnNjb3BlKHhtbCkKICAgICAgICAgICAgICAgICAgICA6IHhtbC5fSW5TY29wZU5hbWVzcGFjZXMsCiAgICAgICAgICAgICAgICBwOwoKICAgICAgICAgICAgZm9yICg7aSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbnMgPSBhcmd1bWVudHMuY2FsbGVlKGNbaV0sIG5zKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChwIGluIG4pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChuW3BdLnByZWZpeCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBuc1tuW3BdLnByZWZpeF0gPSBuW3BdLnVyaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG5zOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gaW5zY29wZSAoeG1sKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIG5zID0ge30sCiAgICAgICAgICAgICAgICBpID0gMCwKICAgICAgICAgICAgICAgIG4gPSB4bWwuaW5TY29wZU5hbWVzcGFjZXMoKSwKICAgICAgICAgICAgICAgIGwgPSBuLmxlbmd0aDsKCiAgICAgICAgICAgIGZvciAoO2kgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChuW2ldLnByZWZpeCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBuc1tuW2ldLnByZWZpeF0gPSBuW2ldLnVyaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG5zOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gY3JlYXRlQXR0cmlidXRlTlMgKHhtbCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBucyA9IHhtbC5uYW1lc3BhY2UoKSwKICAgICAgICAgICAgICAgIG5vZGUgPSAhIXhtbERvYy5jcmVhdGVBdHRyaWJ1dGVOUwogICAgICAgICAgICAgICAgICAgID8geG1sRG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5zLnVyaSwgeG1sLmxvY2FsTmFtZSgpKQogICAgICAgICAgICAgICAgICAgIDogeG1sRG9jLmNyZWF0ZUF0dHJpYnV0ZSgobnMucHJlZml4ID8gbnMucHJlZml4ICsgIjoiIDogIiIgKSArIHhtbC5sb2NhbE5hbWUoKSk7CgogICAgICAgICAgICBub2RlLm5vZGVWYWx1ZSA9IHhtbC50b1N0cmluZygpOwogICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIHRyYW5zZm9ybSAoeG1sLCBzdHlsZSwgcGFyYW1zKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHhzbCwgcmVzLCBpID0gMCwgbCA9IChwYXJhbXN8fFtdKS5sZW5ndGg7CgogICAgICAgICAgICBpZiAoIXdpbmRvdy5YU0xUUHJvY2Vzc29yKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvL1RPRE86IE5lZWQgdG8gY3JlYXRlIGEgd2F5IHRvIHNldCBwYXJhbWV0ZXJzIG9uIGFuIElFIHN0eWxlc2hlZXQKICAgICAgICAgICAgICAgIC8vWFNMUHJvY2Vzc29yCiAgICAgICAgICAgICAgICAvL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczc1NzAxNSUyOHY9VlMuODUlMjkuYXNweAogICAgICAgICAgICAgICAgLy9odHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM3NjM2NzklMjhWUy44NSUyOS5hc3B4CiAgICAgICAgICAgICAgICAvL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczc1NDU5NCUyOHY9VlMuODUlMjkuYXNweAoKICAgICAgICAgICAgICAgIHJlcyA9IGNyZWF0ZURvY3VtZW50RnJvbSh4bWwpLnRyYW5zZm9ybU5vZGUoY3JlYXRlRG9jdW1lbnRGcm9tKHN0eWxlKSk7CgogICAgICAgICAgICAgICAgcmV0dXJuICEhcmVzICYmIFRvWE1MKHJlcykgfHwgbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgeHNsID0gbmV3IFhTTFRQcm9jZXNzb3IoKTsKCiAgICAgICAgICAgIHhzbC5pbXBvcnRTdHlsZVNoZWV0KGNyZWF0ZURvY3VtZW50RnJvbShzdHlsZSkpOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJlcyA9IHBhcmFtc1tpXTsKICAgICAgICAgICAgICAgIHhzbC5zZXRQYXJhbWV0ZXIocmVzLm5hbWVzcGFjZVVSSSwgcmVzLmxvY2FsTmFtZSwgcmVzLnZhbHVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmVzID0geHNsLnRyYW5zZm9ybVRvRG9jdW1lbnQoY3JlYXRlRG9jdW1lbnRGcm9tKGRvYykpCgogICAgICAgICAgICByZXR1cm4gISFyZXMgJiYgVG9YTUwocmVzKSB8fCBudWxsOwogICAgICAgIH0KCiAgICAgICAgZm9yIChwIGluIFhNTC5wcm90b3R5cGUpCiAgICAgICAgewogICAgICAgICAgICBkZWZhdWx0WE1MUHJvdG90eXBlICs9IHAgKyAiLCI7CiAgICAgICAgfQoKICAgICAgICBmb3IgKHAgaW4gWE1MTGlzdC5wcm90b3R5cGUpCiAgICAgICAgewogICAgICAgICAgICBkZWZhdWx0WE1MTGlzdFByb3RvdHlwZSArPSBwICsgIiwiOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgd2luZG93LlhNTCAgICAgICAgICAgICAgPSBYTUw7CiAgICAgICAgd2luZG93LlhNTExpc3QgICAgICAgICAgPSBYTUxMaXN0OwogICAgICAgIHdpbmRvdy5RTmFtZSAgICAgICAgICAgID0gUU5hbWU7CiAgICAgICAgd2luZG93Lk5hbWVzcGFjZSAgICAgICAgPSBOYW1lc3BhY2U7CiAgICAgICAgd2luZG93LmlzWE1MTmFtZSAgICAgICAgPSBpc1hNTE5hbWU7CiAgICAgICAgd2luZG93LkF0dHJpYnV0ZU5hbWUgICAgPSBBdHRyaWJ1dGVOYW1lOwoKICAgIH0pKCk7Cn0KCi8qKioqKiB4cmVnZXhwLmpzICoqKioqLwoKLyohCiAqIFhSZWdFeHAgdjIuMC4wCiAqIChjKSAyMDA3LTIwMTIgU3RldmVuIExldml0aGFuIDxodHRwOi8veHJlZ2V4cC5jb20vPgogKiBNSVQgTGljZW5zZQogKi8KCi8qKgogKiBYUmVnRXhwIHByb3ZpZGVzIGF1Z21lbnRlZCwgZXh0ZW5zaWJsZSBKYXZhU2NyaXB0IHJlZ3VsYXIgZXhwcmVzc2lvbnMuIFlvdSBnZXQgbmV3IHN5bnRheCwKICogZmxhZ3MsIGFuZCBtZXRob2RzIGJleW9uZCB3aGF0IGJyb3dzZXJzIHN1cHBvcnQgbmF0aXZlbHkuIFhSZWdFeHAgaXMgYWxzbyBhIHJlZ2V4IHV0aWxpdHkgYmVsdAogKiB3aXRoIHRvb2xzIHRvIG1ha2UgeW91ciBjbGllbnQtc2lkZSBncmVwcGluZyBzaW1wbGVyIGFuZCBtb3JlIHBvd2VyZnVsLCB3aGlsZSBmcmVlaW5nIHlvdSBmcm9tCiAqIHdvcnJ5aW5nIGFib3V0IHBlc2t5IGNyb3NzLWJyb3dzZXIgaW5jb25zaXN0ZW5jaWVzIGFuZCB0aGUgZHViaW91cyBgbGFzdEluZGV4YCBwcm9wZXJ0eS4gU2VlCiAqIFhSZWdFeHAncyBkb2N1bWVudGF0aW9uIChodHRwOi8veHJlZ2V4cC5jb20vKSBmb3IgbW9yZSBkZXRhaWxzLgogKiBAbW9kdWxlIHhyZWdleHAKICogQHJlcXVpcmVzIE4vQQogKi8KdmFyIFhSZWdFeHA7CgovLyBBdm9pZCBydW5uaW5nIHR3aWNlOyB0aGF0IHdvdWxkIHJlc2V0IHRva2VucyBhbmQgY291bGQgYnJlYWsgcmVmZXJlbmNlcyB0byBuYXRpdmUgZ2xvYmFscwpYUmVnRXhwID0gWFJlZ0V4cCB8fCAoZnVuY3Rpb24gKHVuZGVmKSB7CiAgICAidXNlIHN0cmljdCI7CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqICBQcml2YXRlIHZhcmlhYmxlcwogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgogICAgdmFyIHNlbGYsCiAgICAgICAgYWRkVG9rZW4sCiAgICAgICAgYWRkLAoKLy8gT3B0aW9uYWwgZmVhdHVyZXM7IGNhbiBiZSBpbnN0YWxsZWQgYW5kIHVuaW5zdGFsbGVkCiAgICAgICAgZmVhdHVyZXMgPSB7CiAgICAgICAgICAgIG5hdGl2ZXM6IGZhbHNlLAogICAgICAgICAgICBleHRlbnNpYmlsaXR5OiBmYWxzZQogICAgICAgIH0sCgovLyBTdG9yZSBuYXRpdmUgbWV0aG9kcyB0byB1c2UgYW5kIHJlc3RvcmUgKCJuYXRpdmUiIGlzIGFuIEVTMyByZXNlcnZlZCBrZXl3b3JkKQogICAgICAgIG5hdGl2ID0gewogICAgICAgICAgICBleGVjOiBSZWdFeHAucHJvdG90eXBlLmV4ZWMsCiAgICAgICAgICAgIHRlc3Q6IFJlZ0V4cC5wcm90b3R5cGUudGVzdCwKICAgICAgICAgICAgbWF0Y2g6IFN0cmluZy5wcm90b3R5cGUubWF0Y2gsCiAgICAgICAgICAgIHJlcGxhY2U6IFN0cmluZy5wcm90b3R5cGUucmVwbGFjZSwKICAgICAgICAgICAgc3BsaXQ6IFN0cmluZy5wcm90b3R5cGUuc3BsaXQKICAgICAgICB9LAoKLy8gU3RvcmFnZSBmb3IgZml4ZWQvZXh0ZW5kZWQgbmF0aXZlIG1ldGhvZHMKICAgICAgICBmaXhlZCA9IHt9LAoKLy8gU3RvcmFnZSBmb3IgY2FjaGVkIHJlZ2V4ZXMKICAgICAgICBjYWNoZSA9IHt9LAoKLy8gU3RvcmFnZSBmb3IgYWRkb24gdG9rZW5zCiAgICAgICAgdG9rZW5zID0gW10sCgovLyBUb2tlbiBzY29wZXMKICAgICAgICBkZWZhdWx0U2NvcGUgPSAiZGVmYXVsdCIsCiAgICAgICAgY2xhc3NTY29wZSA9ICJjbGFzcyIsCgovLyBSZWdleGVzIHRoYXQgbWF0Y2ggbmF0aXZlIHJlZ2V4IHN5bnRheAogICAgICAgIG5hdGl2ZVRva2VucyA9IHsKICAgICAgICAgICAgLy8gQW55IG5hdGl2ZSBtdWx0aWNoYXJhY3RlciB0b2tlbiBpbiBkZWZhdWx0IHNjb3BlIChpbmNsdWRlcyBvY3RhbHMsIGV4Y2x1ZGVzIGNoYXJhY3RlciBjbGFzc2VzKQogICAgICAgICAgICAiZGVmYXVsdCI6IC9eKD86XFwoPzowKD86WzAtM11bMC03XXswLDJ9fFs0LTddWzAtN10/KT98WzEtOV1cZCp8eFtcZEEtRmEtZl17Mn18dVtcZEEtRmEtZl17NH18Y1tBLVphLXpdfFtcc1xTXSl8XChcP1s6PSFdfFs/KitdXD98e1xkKyg/OixcZCopP31cPz8pLywKICAgICAgICAgICAgLy8gQW55IG5hdGl2ZSBtdWx0aWNoYXJhY3RlciB0b2tlbiBpbiBjaGFyYWN0ZXIgY2xhc3Mgc2NvcGUgKGluY2x1ZGVzIG9jdGFscykKICAgICAgICAgICAgImNsYXNzIjogL14oPzpcXCg/OlswLTNdWzAtN117MCwyfXxbNC03XVswLTddP3x4W1xkQS1GYS1mXXsyfXx1W1xkQS1GYS1mXXs0fXxjW0EtWmEtel18W1xzXFNdKSkvCiAgICAgICAgfSwKCi8vIEFueSBiYWNrcmVmZXJlbmNlIGluIHJlcGxhY2VtZW50IHN0cmluZ3MKICAgICAgICByZXBsYWNlbWVudFRva2VuID0gL1wkKD86eyhbXHckXSspfXwoXGRcZD98W1xzXFNdKSkvZywKCi8vIEFueSBjaGFyYWN0ZXIgd2l0aCBhIGxhdGVyIGluc3RhbmNlIGluIHRoZSBzdHJpbmcKICAgICAgICBkdXBsaWNhdGVGbGFncyA9IC8oW1xzXFNdKSg/PVtcc1xTXSpcMSkvZywKCi8vIEFueSBncmVlZHkvbGF6eSBxdWFudGlmaWVyCiAgICAgICAgcXVhbnRpZmllciA9IC9eKD86Wz8qK118e1xkKyg/OixcZCopP30pXD8/LywKCi8vIENoZWNrIGZvciBjb3JyZWN0IGBleGVjYCBoYW5kbGluZyBvZiBub25wYXJ0aWNpcGF0aW5nIGNhcHR1cmluZyBncm91cHMKICAgICAgICBjb21wbGlhbnRFeGVjTnBjZyA9IG5hdGl2LmV4ZWMuY2FsbCgvKCk/Py8sICIiKVsxXSA9PT0gdW5kZWYsCgovLyBDaGVjayBmb3IgZmxhZyB5IHN1cHBvcnQgKEZpcmVmb3ggMyspCiAgICAgICAgaGFzTmF0aXZlWSA9IFJlZ0V4cC5wcm90b3R5cGUuc3RpY2t5ICE9PSB1bmRlZiwKCi8vIFVzZWQgdG8ga2lsbCBpbmZpbml0ZSByZWN1cnNpb24gZHVyaW5nIFhSZWdFeHAgY29uc3RydWN0aW9uCiAgICAgICAgaXNJbnNpZGVDb25zdHJ1Y3RvciA9IGZhbHNlLAoKLy8gU3RvcmFnZSBmb3Iga25vd24gZmxhZ3MsIGluY2x1ZGluZyBhZGRvbiBmbGFncwogICAgICAgIHJlZ2lzdGVyZWRGbGFncyA9ICJnaW0iICsgKGhhc05hdGl2ZVkgPyAieSIgOiAiIik7CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqICBQcml2YXRlIGhlbHBlciBmdW5jdGlvbnMKICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKLyoqCiAqIEF0dGFjaGVzIFhSZWdFeHAucHJvdG90eXBlIHByb3BlcnRpZXMgYW5kIG5hbWVkIGNhcHR1cmUgc3VwcG9ydGluZyBkYXRhIHRvIGEgcmVnZXggb2JqZWN0LgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge1JlZ0V4cH0gcmVnZXggUmVnZXggdG8gYXVnbWVudC4KICogQHBhcmFtIHtBcnJheX0gY2FwdHVyZU5hbWVzIEFycmF5IHdpdGggY2FwdHVyZSBuYW1lcywgb3IgbnVsbC4KICogQHBhcmFtIHtCb29sZWFufSBbaXNOYXRpdmVdIFdoZXRoZXIgdGhlIHJlZ2V4IHdhcyBjcmVhdGVkIGJ5IGBSZWdFeHBgIHJhdGhlciB0aGFuIGBYUmVnRXhwYC4KICogQHJldHVybnMge1JlZ0V4cH0gQXVnbWVudGVkIHJlZ2V4LgogKi8KICAgIGZ1bmN0aW9uIGF1Z21lbnQocmVnZXgsIGNhcHR1cmVOYW1lcywgaXNOYXRpdmUpIHsKICAgICAgICB2YXIgcDsKICAgICAgICAvLyBDYW4ndCBhdXRvLWluaGVyaXQgdGhlc2Ugc2luY2UgdGhlIFhSZWdFeHAgY29uc3RydWN0b3IgcmV0dXJucyBhIG5vbnByaW1pdGl2ZSB2YWx1ZQogICAgICAgIGZvciAocCBpbiBzZWxmLnByb3RvdHlwZSkgewogICAgICAgICAgICBpZiAoc2VsZi5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkocCkpIHsKICAgICAgICAgICAgICAgIHJlZ2V4W3BdID0gc2VsZi5wcm90b3R5cGVbcF07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVnZXgueHJlZ2V4cCA9IHtjYXB0dXJlTmFtZXM6IGNhcHR1cmVOYW1lcywgaXNOYXRpdmU6ICEhaXNOYXRpdmV9OwogICAgICAgIHJldHVybiByZWdleDsKICAgIH0KCi8qKgogKiBSZXR1cm5zIG5hdGl2ZSBgUmVnRXhwYCBmbGFncyB1c2VkIGJ5IGEgcmVnZXggb2JqZWN0LgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge1JlZ0V4cH0gcmVnZXggUmVnZXggdG8gY2hlY2suCiAqIEByZXR1cm5zIHtTdHJpbmd9IE5hdGl2ZSBmbGFncyBpbiB1c2UuCiAqLwogICAgZnVuY3Rpb24gZ2V0TmF0aXZlRmxhZ3MocmVnZXgpIHsKICAgICAgICAvL3JldHVybiBuYXRpdi5leGVjLmNhbGwoL1wvKFthLXpdKikkL2ksIFN0cmluZyhyZWdleCkpWzFdOwogICAgICAgIHJldHVybiAocmVnZXguZ2xvYmFsICAgICA/ICJnIiA6ICIiKSArCiAgICAgICAgICAgICAgIChyZWdleC5pZ25vcmVDYXNlID8gImkiIDogIiIpICsKICAgICAgICAgICAgICAgKHJlZ2V4Lm11bHRpbGluZSAgPyAibSIgOiAiIikgKwogICAgICAgICAgICAgICAocmVnZXguZXh0ZW5kZWQgICA/ICJ4IiA6ICIiKSArIC8vIFByb3Bvc2VkIGZvciBFUzYsIGluY2x1ZGVkIGluIEFTMwogICAgICAgICAgICAgICAocmVnZXguc3RpY2t5ICAgICA/ICJ5IiA6ICIiKTsgLy8gUHJvcG9zZWQgZm9yIEVTNiwgaW5jbHVkZWQgaW4gRmlyZWZveCAzKwogICAgfQoKLyoqCiAqIENvcGllcyBhIHJlZ2V4IG9iamVjdCB3aGlsZSBwcmVzZXJ2aW5nIHNwZWNpYWwgcHJvcGVydGllcyBmb3IgbmFtZWQgY2FwdHVyZSBhbmQgYXVnbWVudGluZyB3aXRoCiAqIGBYUmVnRXhwLnByb3RvdHlwZWAgbWV0aG9kcy4gVGhlIGNvcHkgaGFzIGEgZnJlc2ggYGxhc3RJbmRleGAgcHJvcGVydHkgKHNldCB0byB6ZXJvKS4gQWxsb3dzCiAqIGFkZGluZyBhbmQgcmVtb3ZpbmcgZmxhZ3Mgd2hpbGUgY29weWluZyB0aGUgcmVnZXguCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7UmVnRXhwfSByZWdleCBSZWdleCB0byBjb3B5LgogKiBAcGFyYW0ge1N0cmluZ30gW2FkZEZsYWdzXSBGbGFncyB0byBiZSBhZGRlZCB3aGlsZSBjb3B5aW5nIHRoZSByZWdleC4KICogQHBhcmFtIHtTdHJpbmd9IFtyZW1vdmVGbGFnc10gRmxhZ3MgdG8gYmUgcmVtb3ZlZCB3aGlsZSBjb3B5aW5nIHRoZSByZWdleC4KICogQHJldHVybnMge1JlZ0V4cH0gQ29weSBvZiB0aGUgcHJvdmlkZWQgcmVnZXgsIHBvc3NpYmx5IHdpdGggbW9kaWZpZWQgZmxhZ3MuCiAqLwogICAgZnVuY3Rpb24gY29weShyZWdleCwgYWRkRmxhZ3MsIHJlbW92ZUZsYWdzKSB7CiAgICAgICAgaWYgKCFzZWxmLmlzUmVnRXhwKHJlZ2V4KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCJ0eXBlIFJlZ0V4cCBleHBlY3RlZCIpOwogICAgICAgIH0KICAgICAgICB2YXIgZmxhZ3MgPSBuYXRpdi5yZXBsYWNlLmNhbGwoZ2V0TmF0aXZlRmxhZ3MocmVnZXgpICsgKGFkZEZsYWdzIHx8ICIiKSwgZHVwbGljYXRlRmxhZ3MsICIiKTsKICAgICAgICBpZiAocmVtb3ZlRmxhZ3MpIHsKICAgICAgICAgICAgLy8gV291bGQgbmVlZCB0byBlc2NhcGUgYHJlbW92ZUZsYWdzYCBpZiB0aGlzIHdhcyBwdWJsaWMKICAgICAgICAgICAgZmxhZ3MgPSBuYXRpdi5yZXBsYWNlLmNhbGwoZmxhZ3MsIG5ldyBSZWdFeHAoIlsiICsgcmVtb3ZlRmxhZ3MgKyAiXSsiLCAiZyIpLCAiIik7CiAgICAgICAgfQogICAgICAgIGlmIChyZWdleC54cmVnZXhwICYmICFyZWdleC54cmVnZXhwLmlzTmF0aXZlKSB7CiAgICAgICAgICAgIC8vIENvbXBpbGluZyB0aGUgY3VycmVudCAocmF0aGVyIHRoYW4gcHJlY29tcGlsYXRpb24pIHNvdXJjZSBwcmVzZXJ2ZXMgdGhlIGVmZmVjdHMgb2Ygbm9ubmF0aXZlIHNvdXJjZSBmbGFncwogICAgICAgICAgICByZWdleCA9IGF1Z21lbnQoc2VsZihyZWdleC5zb3VyY2UsIGZsYWdzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2V4LnhyZWdleHAuY2FwdHVyZU5hbWVzID8gcmVnZXgueHJlZ2V4cC5jYXB0dXJlTmFtZXMuc2xpY2UoMCkgOiBudWxsKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBBdWdtZW50IHdpdGggYFhSZWdFeHAucHJvdG90eXBlYCBtZXRob2RzLCBidXQgdXNlIG5hdGl2ZSBgUmVnRXhwYCAoYXZvaWQgc2VhcmNoaW5nIGZvciBzcGVjaWFsIHRva2VucykKICAgICAgICAgICAgcmVnZXggPSBhdWdtZW50KG5ldyBSZWdFeHAocmVnZXguc291cmNlLCBmbGFncyksIG51bGwsIHRydWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVnZXg7CiAgICB9CgovKgogKiBSZXR1cm5zIHRoZSBsYXN0IGluZGV4IGF0IHdoaWNoIGEgZ2l2ZW4gdmFsdWUgY2FuIGJlIGZvdW5kIGluIGFuIGFycmF5LCBvciBgLTFgIGlmIGl0J3Mgbm90CiAqIHByZXNlbnQuIFRoZSBhcnJheSBpcyBzZWFyY2hlZCBiYWNrd2FyZHMuCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IEFycmF5IHRvIHNlYXJjaC4KICogQHBhcmFtIHsqfSB2YWx1ZSBWYWx1ZSB0byBsb2NhdGUgaW4gdGhlIGFycmF5LgogKiBAcmV0dXJucyB7TnVtYmVyfSBMYXN0IHplcm8tYmFzZWQgaW5kZXggYXQgd2hpY2ggdGhlIGl0ZW0gaXMgZm91bmQsIG9yIC0xLgogKi8KICAgIGZ1bmN0aW9uIGxhc3RJbmRleE9mKGFycmF5LCB2YWx1ZSkgewogICAgICAgIHZhciBpID0gYXJyYXkubGVuZ3RoOwogICAgICAgIGlmIChBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YpIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5Lmxhc3RJbmRleE9mKHZhbHVlKTsgLy8gVXNlIHRoZSBuYXRpdmUgbWV0aG9kIGlmIGF2YWlsYWJsZQogICAgICAgIH0KICAgICAgICB3aGlsZSAoaS0tKSB7CiAgICAgICAgICAgIGlmIChhcnJheVtpXSA9PT0gdmFsdWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAtMTsKICAgIH0KCi8qKgogKiBEZXRlcm1pbmVzIHdoZXRoZXIgYW4gb2JqZWN0IGlzIG9mIHRoZSBzcGVjaWZpZWQgdHlwZS4KICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBPYmplY3QgdG8gY2hlY2suCiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIFR5cGUgdG8gY2hlY2sgZm9yLCBpbiBsb3dlcmNhc2UuCiAqIEByZXR1cm5zIHtCb29sZWFufSBXaGV0aGVyIHRoZSBvYmplY3QgbWF0Y2hlcyB0aGUgdHlwZS4KICovCiAgICBmdW5jdGlvbiBpc1R5cGUodmFsdWUsIHR5cGUpIHsKICAgICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKS50b0xvd2VyQ2FzZSgpID09PSAiW29iamVjdCAiICsgdHlwZSArICJdIjsKICAgIH0KCi8qKgogKiBQcmVwYXJlcyBhbiBvcHRpb25zIG9iamVjdCBmcm9tIHRoZSBnaXZlbiB2YWx1ZS4KICogQHByaXZhdGUKICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSB2YWx1ZSBWYWx1ZSB0byBjb252ZXJ0IHRvIGFuIG9wdGlvbnMgb2JqZWN0LgogKiBAcmV0dXJucyB7T2JqZWN0fSBPcHRpb25zIG9iamVjdC4KICovCiAgICBmdW5jdGlvbiBwcmVwYXJlT3B0aW9ucyh2YWx1ZSkgewogICAgICAgIHZhbHVlID0gdmFsdWUgfHwge307CiAgICAgICAgaWYgKHZhbHVlID09PSAiYWxsIiB8fCB2YWx1ZS5hbGwpIHsKICAgICAgICAgICAgdmFsdWUgPSB7bmF0aXZlczogdHJ1ZSwgZXh0ZW5zaWJpbGl0eTogdHJ1ZX07CiAgICAgICAgfSBlbHNlIGlmIChpc1R5cGUodmFsdWUsICJzdHJpbmciKSkgewogICAgICAgICAgICB2YWx1ZSA9IHNlbGYuZm9yRWFjaCh2YWx1ZSwgL1teXHMsXSsvLCBmdW5jdGlvbiAobSkgewogICAgICAgICAgICAgICAgdGhpc1ttXSA9IHRydWU7CiAgICAgICAgICAgIH0sIHt9KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgfQoKLyoqCiAqIFJ1bnMgYnVpbHQtaW4vY3VzdG9tIHRva2VucyBpbiByZXZlcnNlIGluc2VydGlvbiBvcmRlciwgdW50aWwgYSBtYXRjaCBpcyBmb3VuZC4KICogQHByaXZhdGUKICogQHBhcmFtIHtTdHJpbmd9IHBhdHRlcm4gT3JpZ2luYWwgcGF0dGVybiBmcm9tIHdoaWNoIGFuIFhSZWdFeHAgb2JqZWN0IGlzIGJlaW5nIGJ1aWx0LgogKiBAcGFyYW0ge051bWJlcn0gcG9zIFBvc2l0aW9uIHRvIHNlYXJjaCBmb3IgdG9rZW5zIHdpdGhpbiBgcGF0dGVybmAuCiAqIEBwYXJhbSB7TnVtYmVyfSBzY29wZSBDdXJyZW50IHJlZ2V4IHNjb3BlLgogKiBAcGFyYW0ge09iamVjdH0gY29udGV4dCBDb250ZXh0IG9iamVjdCBhc3NpZ25lZCB0byB0b2tlbiBoYW5kbGVyIGZ1bmN0aW9ucy4KICogQHJldHVybnMge09iamVjdH0gT2JqZWN0IHdpdGggcHJvcGVydGllcyBgb3V0cHV0YCAodGhlIHN1YnN0aXR1dGlvbiBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlCiAqICAgc3VjY2Vzc2Z1bCB0b2tlbiBoYW5kbGVyKSBhbmQgYG1hdGNoYCAodGhlIHRva2VuJ3MgbWF0Y2ggYXJyYXkpLCBvciBudWxsLgogKi8KICAgIGZ1bmN0aW9uIHJ1blRva2VucyhwYXR0ZXJuLCBwb3MsIHNjb3BlLCBjb250ZXh0KSB7CiAgICAgICAgdmFyIGkgPSB0b2tlbnMubGVuZ3RoLAogICAgICAgICAgICByZXN1bHQgPSBudWxsLAogICAgICAgICAgICBtYXRjaCwKICAgICAgICAgICAgdDsKICAgICAgICAvLyBQcm90ZWN0IGFnYWluc3QgY29uc3RydWN0aW5nIFhSZWdFeHBzIHdpdGhpbiB0b2tlbiBoYW5kbGVyIGFuZCB0cmlnZ2VyIGZ1bmN0aW9ucwogICAgICAgIGlzSW5zaWRlQ29uc3RydWN0b3IgPSB0cnVlOwogICAgICAgIC8vIE11c3QgcmVzZXQgYGlzSW5zaWRlQ29uc3RydWN0b3JgLCBldmVuIGlmIGEgYHRyaWdnZXJgIG9yIGBoYW5kbGVyYCB0aHJvd3MKICAgICAgICB0cnkgewogICAgICAgICAgICB3aGlsZSAoaS0tKSB7IC8vIFJ1biBpbiByZXZlcnNlIG9yZGVyCiAgICAgICAgICAgICAgICB0ID0gdG9rZW5zW2ldOwogICAgICAgICAgICAgICAgaWYgKCh0LnNjb3BlID09PSAiYWxsIiB8fCB0LnNjb3BlID09PSBzY29wZSkgJiYgKCF0LnRyaWdnZXIgfHwgdC50cmlnZ2VyLmNhbGwoY29udGV4dCkpKSB7CiAgICAgICAgICAgICAgICAgICAgdC5wYXR0ZXJuLmxhc3RJbmRleCA9IHBvczsKICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGZpeGVkLmV4ZWMuY2FsbCh0LnBhdHRlcm4sIHBhdHRlcm4pOyAvLyBGaXhlZCBgZXhlY2AgaGVyZSBhbGxvd3MgdXNlIG9mIG5hbWVkIGJhY2tyZWZlcmVuY2VzLCBldGMuCiAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoICYmIG1hdGNoLmluZGV4ID09PSBwb3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiB0LmhhbmRsZXIuY2FsbChjb250ZXh0LCBtYXRjaCwgc2NvcGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2g6IG1hdGNoCiAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICB0aHJvdyBlcnI7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgaXNJbnNpZGVDb25zdHJ1Y3RvciA9IGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKLyoqCiAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgWFJlZ0V4cCBzeW50YXggYW5kIGZsYWcgZXh0ZW5zaWJpbGl0eS4KICogQHByaXZhdGUKICogQHBhcmFtIHtCb29sZWFufSBvbiBgdHJ1ZWAgdG8gZW5hYmxlOyBgZmFsc2VgIHRvIGRpc2FibGUuCiAqLwogICAgZnVuY3Rpb24gc2V0RXh0ZW5zaWJpbGl0eShvbikgewogICAgICAgIHNlbGYuYWRkVG9rZW4gPSBhZGRUb2tlbltvbiA/ICJvbiIgOiAib2ZmIl07CiAgICAgICAgZmVhdHVyZXMuZXh0ZW5zaWJpbGl0eSA9IG9uOwogICAgfQoKLyoqCiAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgbmF0aXZlIG1ldGhvZCBvdmVycmlkZXMuCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Qm9vbGVhbn0gb24gYHRydWVgIHRvIGVuYWJsZTsgYGZhbHNlYCB0byBkaXNhYmxlLgogKi8KICAgIGZ1bmN0aW9uIHNldE5hdGl2ZXMob24pIHsKICAgICAgICBSZWdFeHAucHJvdG90eXBlLmV4ZWMgPSAob24gPyBmaXhlZCA6IG5hdGl2KS5leGVjOwogICAgICAgIFJlZ0V4cC5wcm90b3R5cGUudGVzdCA9IChvbiA/IGZpeGVkIDogbmF0aXYpLnRlc3Q7CiAgICAgICAgU3RyaW5nLnByb3RvdHlwZS5tYXRjaCA9IChvbiA/IGZpeGVkIDogbmF0aXYpLm1hdGNoOwogICAgICAgIFN0cmluZy5wcm90b3R5cGUucmVwbGFjZSA9IChvbiA/IGZpeGVkIDogbmF0aXYpLnJlcGxhY2U7CiAgICAgICAgU3RyaW5nLnByb3RvdHlwZS5zcGxpdCA9IChvbiA/IGZpeGVkIDogbmF0aXYpLnNwbGl0OwogICAgICAgIGZlYXR1cmVzLm5hdGl2ZXMgPSBvbjsKICAgIH0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogIENvbnN0cnVjdG9yCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCi8qKgogKiBDcmVhdGVzIGFuIGV4dGVuZGVkIHJlZ3VsYXIgZXhwcmVzc2lvbiBvYmplY3QgZm9yIG1hdGNoaW5nIHRleHQgd2l0aCBhIHBhdHRlcm4uIERpZmZlcnMgZnJvbSBhCiAqIG5hdGl2ZSByZWd1bGFyIGV4cHJlc3Npb24gaW4gdGhhdCBhZGRpdGlvbmFsIHN5bnRheCBhbmQgZmxhZ3MgYXJlIHN1cHBvcnRlZC4gVGhlIHJldHVybmVkIG9iamVjdAogKiBpcyBpbiBmYWN0IGEgbmF0aXZlIGBSZWdFeHBgIGFuZCB3b3JrcyB3aXRoIGFsbCBuYXRpdmUgbWV0aG9kcy4KICogQGNsYXNzIFhSZWdFeHAKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gcGF0dGVybiBSZWdleCBwYXR0ZXJuIHN0cmluZywgb3IgYW4gZXhpc3RpbmcgYFJlZ0V4cGAgb2JqZWN0IHRvIGNvcHkuCiAqIEBwYXJhbSB7U3RyaW5nfSBbZmxhZ3NdIEFueSBjb21iaW5hdGlvbiBvZiBmbGFnczoKICogICA8bGk+YGdgIC0gZ2xvYmFsCiAqICAgPGxpPmBpYCAtIGlnbm9yZSBjYXNlCiAqICAgPGxpPmBtYCAtIG11bHRpbGluZSBhbmNob3JzCiAqICAgPGxpPmBuYCAtIGV4cGxpY2l0IGNhcHR1cmUKICogICA8bGk+YHNgIC0gZG90IG1hdGNoZXMgYWxsIChha2Egc2luZ2xlbGluZSkKICogICA8bGk+YHhgIC0gZnJlZS1zcGFjaW5nIGFuZCBsaW5lIGNvbW1lbnRzIChha2EgZXh0ZW5kZWQpCiAqICAgPGxpPmB5YCAtIHN0aWNreSAoRmlyZWZveCAzKyBvbmx5KQogKiAgIEZsYWdzIGNhbm5vdCBiZSBwcm92aWRlZCB3aGVuIGNvbnN0cnVjdGluZyBvbmUgYFJlZ0V4cGAgZnJvbSBhbm90aGVyLgogKiBAcmV0dXJucyB7UmVnRXhwfSBFeHRlbmRlZCByZWd1bGFyIGV4cHJlc3Npb24gb2JqZWN0LgogKiBAZXhhbXBsZQogKgogKiAvLyBXaXRoIG5hbWVkIGNhcHR1cmUgYW5kIGZsYWcgeAogKiBkYXRlID0gWFJlZ0V4cCgnKD88eWVhcj4gIFswLTldezR9KSAtPyAgIyB5ZWFyICBcblwKICogICAgICAgICAgICAgICAgICg/PG1vbnRoPiBbMC05XXsyfSkgLT8gICMgbW9udGggXG5cCiAqICAgICAgICAgICAgICAgICAoPzxkYXk+ICAgWzAtOV17Mn0pICAgICAjIGRheSAgICcsICd4Jyk7CiAqCiAqIC8vIFBhc3NpbmcgYSByZWdleCBvYmplY3QgdG8gY29weSBpdC4gVGhlIGNvcHkgbWFpbnRhaW5zIHNwZWNpYWwgcHJvcGVydGllcyBmb3IgbmFtZWQgY2FwdHVyZSwKICogLy8gaXMgYXVnbWVudGVkIHdpdGggYFhSZWdFeHAucHJvdG90eXBlYCBtZXRob2RzLCBhbmQgaGFzIGEgZnJlc2ggYGxhc3RJbmRleGAgcHJvcGVydHkgKHNldCB0bwogKiAvLyB6ZXJvKS4gTmF0aXZlIHJlZ2V4ZXMgYXJlIG5vdCByZWNvbXBpbGVkIHVzaW5nIFhSZWdFeHAgc3ludGF4LgogKiBYUmVnRXhwKC9yZWdleC8pOwogKi8KICAgIHNlbGYgPSBmdW5jdGlvbiAocGF0dGVybiwgZmxhZ3MpIHsKICAgICAgICBpZiAoc2VsZi5pc1JlZ0V4cChwYXR0ZXJuKSkgewogICAgICAgICAgICBpZiAoZmxhZ3MgIT09IHVuZGVmKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCJjYW4ndCBzdXBwbHkgZmxhZ3Mgd2hlbiBjb25zdHJ1Y3Rpbmcgb25lIFJlZ0V4cCBmcm9tIGFub3RoZXIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY29weShwYXR0ZXJuKTsKICAgICAgICB9CiAgICAgICAgLy8gVG9rZW5zIGJlY29tZSBwYXJ0IG9mIHRoZSByZWdleCBjb25zdHJ1Y3Rpb24gcHJvY2Vzcywgc28gcHJvdGVjdCBhZ2FpbnN0IGluZmluaXRlIHJlY3Vyc2lvbgogICAgICAgIC8vIHdoZW4gYW4gWFJlZ0V4cCBpcyBjb25zdHJ1Y3RlZCB3aXRoaW4gYSB0b2tlbiBoYW5kbGVyIGZ1bmN0aW9uCiAgICAgICAgaWYgKGlzSW5zaWRlQ29uc3RydWN0b3IpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJjYW4ndCBjYWxsIHRoZSBYUmVnRXhwIGNvbnN0cnVjdG9yIHdpdGhpbiB0b2tlbiBkZWZpbml0aW9uIGZ1bmN0aW9ucyIpOwogICAgICAgIH0KCiAgICAgICAgdmFyIG91dHB1dCA9IFtdLAogICAgICAgICAgICBzY29wZSA9IGRlZmF1bHRTY29wZSwKICAgICAgICAgICAgdG9rZW5Db250ZXh0ID0gewogICAgICAgICAgICAgICAgaGFzTmFtZWRDYXB0dXJlOiBmYWxzZSwKICAgICAgICAgICAgICAgIGNhcHR1cmVOYW1lczogW10sCiAgICAgICAgICAgICAgICBoYXNGbGFnOiBmdW5jdGlvbiAoZmxhZykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmbGFncy5pbmRleE9mKGZsYWcpID4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHBvcyA9IDAsCiAgICAgICAgICAgIHRva2VuUmVzdWx0LAogICAgICAgICAgICBtYXRjaCwKICAgICAgICAgICAgY2hyOwogICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuID09PSB1bmRlZiA/ICIiIDogU3RyaW5nKHBhdHRlcm4pOwogICAgICAgIGZsYWdzID0gZmxhZ3MgPT09IHVuZGVmID8gIiIgOiBTdHJpbmcoZmxhZ3MpOwoKICAgICAgICBpZiAobmF0aXYubWF0Y2guY2FsbChmbGFncywgZHVwbGljYXRlRmxhZ3MpKSB7IC8vIERvbid0IHVzZSB0ZXN0L2V4ZWMgYmVjYXVzZSB0aGV5IHdvdWxkIHVwZGF0ZSBsYXN0SW5kZXgKICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCJpbnZhbGlkIGR1cGxpY2F0ZSByZWd1bGFyIGV4cHJlc3Npb24gZmxhZyIpOwogICAgICAgIH0KICAgICAgICAvLyBTdHJpcC9hcHBseSBsZWFkaW5nIG1vZGUgbW9kaWZpZXIgd2l0aCBhbnkgY29tYmluYXRpb24gb2YgZmxhZ3MgZXhjZXB0IGcgb3IgeTogKD9pbW5zeCkKICAgICAgICBwYXR0ZXJuID0gbmF0aXYucmVwbGFjZS5jYWxsKHBhdHRlcm4sIC9eXChcPyhbXHckXSspXCkvLCBmdW5jdGlvbiAoJDAsICQxKSB7CiAgICAgICAgICAgIGlmIChuYXRpdi50ZXN0LmNhbGwoL1tneV0vLCAkMSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcigiY2FuJ3QgdXNlIGZsYWcgZyBvciB5IGluIG1vZGUgbW9kaWZpZXIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmbGFncyA9IG5hdGl2LnJlcGxhY2UuY2FsbChmbGFncyArICQxLCBkdXBsaWNhdGVGbGFncywgIiIpOwogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfSk7CiAgICAgICAgc2VsZi5mb3JFYWNoKGZsYWdzLCAvW1xzXFNdLywgZnVuY3Rpb24gKG0pIHsKICAgICAgICAgICAgaWYgKHJlZ2lzdGVyZWRGbGFncy5pbmRleE9mKG1bMF0pIDwgMCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCJpbnZhbGlkIHJlZ3VsYXIgZXhwcmVzc2lvbiBmbGFnICIgKyBtWzBdKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwoKICAgICAgICB3aGlsZSAocG9zIDwgcGF0dGVybi5sZW5ndGgpIHsKICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGN1c3RvbSB0b2tlbnMgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24KICAgICAgICAgICAgdG9rZW5SZXN1bHQgPSBydW5Ub2tlbnMocGF0dGVybiwgcG9zLCBzY29wZSwgdG9rZW5Db250ZXh0KTsKICAgICAgICAgICAgaWYgKHRva2VuUmVzdWx0KSB7CiAgICAgICAgICAgICAgICBvdXRwdXQucHVzaCh0b2tlblJlc3VsdC5vdXRwdXQpOwogICAgICAgICAgICAgICAgcG9zICs9ICh0b2tlblJlc3VsdC5tYXRjaFswXS5sZW5ndGggfHwgMSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgbmF0aXZlIHRva2VucyAoZXhjZXB0IGNoYXJhY3RlciBjbGFzc2VzKSBhdCB0aGUgY3VycmVudCBwb3NpdGlvbgogICAgICAgICAgICAgICAgbWF0Y2ggPSBuYXRpdi5leGVjLmNhbGwobmF0aXZlVG9rZW5zW3Njb3BlXSwgcGF0dGVybi5zbGljZShwb3MpKTsKICAgICAgICAgICAgICAgIGlmIChtYXRjaCkgewogICAgICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKG1hdGNoWzBdKTsKICAgICAgICAgICAgICAgICAgICBwb3MgKz0gbWF0Y2hbMF0ubGVuZ3RoOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjaHIgPSBwYXR0ZXJuLmNoYXJBdChwb3MpOwogICAgICAgICAgICAgICAgICAgIGlmIChjaHIgPT09ICJbIikgewogICAgICAgICAgICAgICAgICAgICAgICBzY29wZSA9IGNsYXNzU2NvcGU7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaHIgPT09ICJdIikgewogICAgICAgICAgICAgICAgICAgICAgICBzY29wZSA9IGRlZmF1bHRTY29wZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gQWR2YW5jZSBwb3NpdGlvbiBieSBvbmUgY2hhcmFjdGVyCiAgICAgICAgICAgICAgICAgICAgb3V0cHV0LnB1c2goY2hyKTsKICAgICAgICAgICAgICAgICAgICArK3BvczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGF1Z21lbnQobmV3IFJlZ0V4cChvdXRwdXQuam9pbigiIiksIG5hdGl2LnJlcGxhY2UuY2FsbChmbGFncywgL1teZ2lteV0rL2csICIiKSksCiAgICAgICAgICAgICAgICAgICAgICAgdG9rZW5Db250ZXh0Lmhhc05hbWVkQ2FwdHVyZSA/IHRva2VuQ29udGV4dC5jYXB0dXJlTmFtZXMgOiBudWxsKTsKICAgIH07CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqICBQdWJsaWMgbWV0aG9kcy9wcm9wZXJ0aWVzCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCi8vIEluc3RhbGxlZCBhbmQgdW5pbnN0YWxsZWQgc3RhdGVzIGZvciBgWFJlZ0V4cC5hZGRUb2tlbmAKICAgIGFkZFRva2VuID0gewogICAgICAgIG9uOiBmdW5jdGlvbiAocmVnZXgsIGhhbmRsZXIsIG9wdGlvbnMpIHsKICAgICAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgICAgICAgICAgIGlmIChyZWdleCkgewogICAgICAgICAgICAgICAgdG9rZW5zLnB1c2goewogICAgICAgICAgICAgICAgICAgIHBhdHRlcm46IGNvcHkocmVnZXgsICJnIiArIChoYXNOYXRpdmVZID8gInkiIDogIiIpKSwKICAgICAgICAgICAgICAgICAgICBoYW5kbGVyOiBoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgIHNjb3BlOiBvcHRpb25zLnNjb3BlIHx8IGRlZmF1bHRTY29wZSwKICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyOiBvcHRpb25zLnRyaWdnZXIgfHwgbnVsbAogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gUHJvdmlkaW5nIGBjdXN0b21GbGFnc2Agd2l0aCBudWxsIGByZWdleGAgYW5kIGBoYW5kbGVyYCBhbGxvd3MgYWRkaW5nIGZsYWdzIHRoYXQgZG8KICAgICAgICAgICAgLy8gbm90aGluZywgYnV0IGRvbid0IHRocm93IGFuIGVycm9yCiAgICAgICAgICAgIGlmIChvcHRpb25zLmN1c3RvbUZsYWdzKSB7CiAgICAgICAgICAgICAgICByZWdpc3RlcmVkRmxhZ3MgPSBuYXRpdi5yZXBsYWNlLmNhbGwocmVnaXN0ZXJlZEZsYWdzICsgb3B0aW9ucy5jdXN0b21GbGFncywgZHVwbGljYXRlRmxhZ3MsICIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgb2ZmOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiZXh0ZW5zaWJpbGl0eSBtdXN0IGJlIGluc3RhbGxlZCBiZWZvcmUgdXNpbmcgYWRkVG9rZW4iKTsKICAgICAgICB9CiAgICB9OwoKLyoqCiAqIEV4dGVuZHMgb3IgY2hhbmdlcyBYUmVnRXhwIHN5bnRheCBhbmQgYWxsb3dzIGN1c3RvbSBmbGFncy4gVGhpcyBpcyB1c2VkIGludGVybmFsbHkgYW5kIGNhbiBiZQogKiB1c2VkIHRvIGNyZWF0ZSBYUmVnRXhwIGFkZG9ucy4gYFhSZWdFeHAuaW5zdGFsbCgnZXh0ZW5zaWJpbGl0eScpYCBtdXN0IGJlIHJ1biBiZWZvcmUgY2FsbGluZwogKiB0aGlzIGZ1bmN0aW9uLCBvciBhbiBlcnJvciBpcyB0aHJvd24uIElmIG1vcmUgdGhhbiBvbmUgdG9rZW4gY2FuIG1hdGNoIHRoZSBzYW1lIHN0cmluZywgdGhlIGxhc3QKICogYWRkZWQgd2lucy4KICogQG1lbWJlck9mIFhSZWdFeHAKICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4IFJlZ2V4IG9iamVjdCB0aGF0IG1hdGNoZXMgdGhlIG5ldyB0b2tlbi4KICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlciBGdW5jdGlvbiB0aGF0IHJldHVybnMgYSBuZXcgcGF0dGVybiBzdHJpbmcgKHVzaW5nIG5hdGl2ZSByZWdleCBzeW50YXgpCiAqICAgdG8gcmVwbGFjZSB0aGUgbWF0Y2hlZCB0b2tlbiB3aXRoaW4gYWxsIGZ1dHVyZSBYUmVnRXhwIHJlZ2V4ZXMuIEhhcyBhY2Nlc3MgdG8gcGVyc2lzdGVudAogKiAgIHByb3BlcnRpZXMgb2YgdGhlIHJlZ2V4IGJlaW5nIGJ1aWx0LCB0aHJvdWdoIGB0aGlzYC4gSW52b2tlZCB3aXRoIHR3byBhcmd1bWVudHM6CiAqICAgPGxpPlRoZSBtYXRjaCBhcnJheSwgd2l0aCBuYW1lZCBiYWNrcmVmZXJlbmNlIHByb3BlcnRpZXMuCiAqICAgPGxpPlRoZSByZWdleCBzY29wZSB3aGVyZSB0aGUgbWF0Y2ggd2FzIGZvdW5kLgogKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIE9wdGlvbnMgb2JqZWN0IHdpdGggb3B0aW9uYWwgcHJvcGVydGllczoKICogICA8bGk+YHNjb3BlYCB7U3RyaW5nfSBTY29wZXMgd2hlcmUgdGhlIHRva2VuIGFwcGxpZXM6ICdkZWZhdWx0JywgJ2NsYXNzJywgb3IgJ2FsbCcuCiAqICAgPGxpPmB0cmlnZ2VyYCB7RnVuY3Rpb259IEZ1bmN0aW9uIHRoYXQgcmV0dXJucyBgdHJ1ZWAgd2hlbiB0aGUgdG9rZW4gc2hvdWxkIGJlIGFwcGxpZWQ7IGUuZy4sCiAqICAgICBpZiBhIGZsYWcgaXMgc2V0LiBJZiBgZmFsc2VgIGlzIHJldHVybmVkLCB0aGUgbWF0Y2hlZCBzdHJpbmcgY2FuIGJlIG1hdGNoZWQgYnkgb3RoZXIgdG9rZW5zLgogKiAgICAgSGFzIGFjY2VzcyB0byBwZXJzaXN0ZW50IHByb3BlcnRpZXMgb2YgdGhlIHJlZ2V4IGJlaW5nIGJ1aWx0LCB0aHJvdWdoIGB0aGlzYCAoaW5jbHVkaW5nCiAqICAgICBmdW5jdGlvbiBgdGhpcy5oYXNGbGFnYCkuCiAqICAgPGxpPmBjdXN0b21GbGFnc2Age1N0cmluZ30gTm9ubmF0aXZlIGZsYWdzIHVzZWQgYnkgdGhlIHRva2VuJ3MgaGFuZGxlciBvciB0cmlnZ2VyIGZ1bmN0aW9ucy4KICogICAgIFByZXZlbnRzIFhSZWdFeHAgZnJvbSB0aHJvd2luZyBhbiBpbnZhbGlkIGZsYWcgZXJyb3Igd2hlbiB0aGUgc3BlY2lmaWVkIGZsYWdzIGFyZSB1c2VkLgogKiBAZXhhbXBsZQogKgogKiAvLyBCYXNpYyB1c2FnZTogQWRkcyBcYSBmb3IgQUxFUlQgY2hhcmFjdGVyCiAqIFhSZWdFeHAuYWRkVG9rZW4oCiAqICAgL1xcYS8sCiAqICAgZnVuY3Rpb24gKCkge3JldHVybiAnXFx4MDcnO30sCiAqICAge3Njb3BlOiAnYWxsJ30KICogKTsKICogWFJlZ0V4cCgnXFxhW1xcYS1cXG5dKycpLnRlc3QoJ1x4MDdcblx4MDcnKTsgLy8gLT4gdHJ1ZQogKi8KICAgIHNlbGYuYWRkVG9rZW4gPSBhZGRUb2tlbi5vZmY7CgovKioKICogQ2FjaGVzIGFuZCByZXR1cm5zIHRoZSByZXN1bHQgb2YgY2FsbGluZyBgWFJlZ0V4cChwYXR0ZXJuLCBmbGFncylgLiBPbiBhbnkgc3Vic2VxdWVudCBjYWxsIHdpdGgKICogdGhlIHNhbWUgcGF0dGVybiBhbmQgZmxhZyBjb21iaW5hdGlvbiwgdGhlIGNhY2hlZCBjb3B5IGlzIHJldHVybmVkLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gcGF0dGVybiBSZWdleCBwYXR0ZXJuIHN0cmluZy4KICogQHBhcmFtIHtTdHJpbmd9IFtmbGFnc10gQW55IGNvbWJpbmF0aW9uIG9mIFhSZWdFeHAgZmxhZ3MuCiAqIEByZXR1cm5zIHtSZWdFeHB9IENhY2hlZCBYUmVnRXhwIG9iamVjdC4KICogQGV4YW1wbGUKICoKICogd2hpbGUgKG1hdGNoID0gWFJlZ0V4cC5jYWNoZSgnLicsICdncycpLmV4ZWMoc3RyKSkgewogKiAgIC8vIFRoZSByZWdleCBpcyBjb21waWxlZCBvbmNlIG9ubHkKICogfQogKi8KICAgIHNlbGYuY2FjaGUgPSBmdW5jdGlvbiAocGF0dGVybiwgZmxhZ3MpIHsKICAgICAgICB2YXIga2V5ID0gcGF0dGVybiArICIvIiArIChmbGFncyB8fCAiIik7CiAgICAgICAgcmV0dXJuIGNhY2hlW2tleV0gfHwgKGNhY2hlW2tleV0gPSBzZWxmKHBhdHRlcm4sIGZsYWdzKSk7CiAgICB9OwoKLyoqCiAqIEVzY2FwZXMgYW55IHJlZ3VsYXIgZXhwcmVzc2lvbiBtZXRhY2hhcmFjdGVycywgZm9yIHVzZSB3aGVuIG1hdGNoaW5nIGxpdGVyYWwgc3RyaW5ncy4gVGhlIHJlc3VsdAogKiBjYW4gc2FmZWx5IGJlIHVzZWQgYXQgYW55IHBvaW50IHdpdGhpbiBhIHJlZ2V4IHRoYXQgdXNlcyBhbnkgZmxhZ3MuCiAqIEBtZW1iZXJPZiBYUmVnRXhwCiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGVzY2FwZS4KICogQHJldHVybnMge1N0cmluZ30gU3RyaW5nIHdpdGggcmVnZXggbWV0YWNoYXJhY3RlcnMgZXNjYXBlZC4KICogQGV4YW1wbGUKICoKICogWFJlZ0V4cC5lc2NhcGUoJ0VzY2FwZWQ/IDwuPicpOwogKiAvLyAtPiAnRXNjYXBlZFw/XCA8XC4+JwogKi8KICAgIHNlbGYuZXNjYXBlID0gZnVuY3Rpb24gKHN0cikgewogICAgICAgIHJldHVybiBuYXRpdi5yZXBsYWNlLmNhbGwoc3RyLCAvWy1bXF17fSgpKis/LixcXF4kfCNcc10vZywgIlxcJCYiKTsKICAgIH07CgovKioKICogRXhlY3V0ZXMgYSByZWdleCBzZWFyY2ggaW4gYSBzcGVjaWZpZWQgc3RyaW5nLiBSZXR1cm5zIGEgbWF0Y2ggYXJyYXkgb3IgYG51bGxgLiBJZiB0aGUgcHJvdmlkZWQKICogcmVnZXggdXNlcyBuYW1lZCBjYXB0dXJlLCBuYW1lZCBiYWNrcmVmZXJlbmNlIHByb3BlcnRpZXMgYXJlIGluY2x1ZGVkIG9uIHRoZSBtYXRjaCBhcnJheS4KICogT3B0aW9uYWwgYHBvc2AgYW5kIGBzdGlja3lgIGFyZ3VtZW50cyBzcGVjaWZ5IHRoZSBzZWFyY2ggc3RhcnQgcG9zaXRpb24sIGFuZCB3aGV0aGVyIHRoZSBtYXRjaAogKiBtdXN0IHN0YXJ0IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gb25seS4gVGhlIGBsYXN0SW5kZXhgIHByb3BlcnR5IG9mIHRoZSBwcm92aWRlZCByZWdleCBpcyBub3QKICogdXNlZCwgYnV0IGlzIHVwZGF0ZWQgZm9yIGNvbXBhdGliaWxpdHkuIEFsc28gZml4ZXMgYnJvd3NlciBidWdzIGNvbXBhcmVkIHRvIHRoZSBuYXRpdmUKICogYFJlZ0V4cC5wcm90b3R5cGUuZXhlY2AgYW5kIGNhbiBiZSB1c2VkIHJlbGlhYmx5IGNyb3NzLWJyb3dzZXIuCiAqIEBtZW1iZXJPZiBYUmVnRXhwCiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIHNlYXJjaC4KICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4IFJlZ2V4IHRvIHNlYXJjaCB3aXRoLgogKiBAcGFyYW0ge051bWJlcn0gW3Bvcz0wXSBaZXJvLWJhc2VkIGluZGV4IGF0IHdoaWNoIHRvIHN0YXJ0IHRoZSBzZWFyY2guCiAqIEBwYXJhbSB7Qm9vbGVhbnxTdHJpbmd9IFtzdGlja3k9ZmFsc2VdIFdoZXRoZXIgdGhlIG1hdGNoIG11c3Qgc3RhcnQgYXQgdGhlIHNwZWNpZmllZCBwb3NpdGlvbgogKiAgIG9ubHkuIFRoZSBzdHJpbmcgYCdzdGlja3knYCBpcyBhY2NlcHRlZCBhcyBhbiBhbHRlcm5hdGl2ZSB0byBgdHJ1ZWAuCiAqIEByZXR1cm5zIHtBcnJheX0gTWF0Y2ggYXJyYXkgd2l0aCBuYW1lZCBiYWNrcmVmZXJlbmNlIHByb3BlcnRpZXMsIG9yIG51bGwuCiAqIEBleGFtcGxlCiAqCiAqIC8vIEJhc2ljIHVzZSwgd2l0aCBuYW1lZCBiYWNrcmVmZXJlbmNlCiAqIHZhciBtYXRjaCA9IFhSZWdFeHAuZXhlYygnVSsyNjIwJywgWFJlZ0V4cCgnVVxcKyg/PGhleD5bMC05QS1GXXs0fSknKSk7CiAqIG1hdGNoLmhleDsgLy8gLT4gJzI2MjAnCiAqCiAqIC8vIFdpdGggcG9zIGFuZCBzdGlja3ksIGluIGEgbG9vcAogKiB2YXIgcG9zID0gMiwgcmVzdWx0ID0gW10sIG1hdGNoOwogKiB3aGlsZSAobWF0Y2ggPSBYUmVnRXhwLmV4ZWMoJzwxPjwyPjwzPjw0PjU8Nj4nLCAvPChcZCk+LywgcG9zLCAnc3RpY2t5JykpIHsKICogICByZXN1bHQucHVzaChtYXRjaFsxXSk7CiAqICAgcG9zID0gbWF0Y2guaW5kZXggKyBtYXRjaFswXS5sZW5ndGg7CiAqIH0KICogLy8gcmVzdWx0IC0+IFsnMicsICczJywgJzQnXQogKi8KICAgIHNlbGYuZXhlYyA9IGZ1bmN0aW9uIChzdHIsIHJlZ2V4LCBwb3MsIHN0aWNreSkgewogICAgICAgIHZhciByMiA9IGNvcHkocmVnZXgsICJnIiArIChzdGlja3kgJiYgaGFzTmF0aXZlWSA/ICJ5IiA6ICIiKSwgKHN0aWNreSA9PT0gZmFsc2UgPyAieSIgOiAiIikpLAogICAgICAgICAgICBtYXRjaDsKICAgICAgICByMi5sYXN0SW5kZXggPSBwb3MgPSBwb3MgfHwgMDsKICAgICAgICBtYXRjaCA9IGZpeGVkLmV4ZWMuY2FsbChyMiwgc3RyKTsgLy8gRml4ZWQgYGV4ZWNgIHJlcXVpcmVkIGZvciBgbGFzdEluZGV4YCBmaXgsIGV0Yy4KICAgICAgICBpZiAoc3RpY2t5ICYmIG1hdGNoICYmIG1hdGNoLmluZGV4ICE9PSBwb3MpIHsKICAgICAgICAgICAgbWF0Y2ggPSBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAocmVnZXguZ2xvYmFsKSB7CiAgICAgICAgICAgIHJlZ2V4Lmxhc3RJbmRleCA9IG1hdGNoID8gcjIubGFzdEluZGV4IDogMDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hdGNoOwogICAgfTsKCi8qKgogKiBFeGVjdXRlcyBhIHByb3ZpZGVkIGZ1bmN0aW9uIG9uY2UgcGVyIHJlZ2V4IG1hdGNoLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBzZWFyY2guCiAqIEBwYXJhbSB7UmVnRXhwfSByZWdleCBSZWdleCB0byBzZWFyY2ggd2l0aC4KICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgRnVuY3Rpb24gdG8gZXhlY3V0ZSBmb3IgZWFjaCBtYXRjaC4gSW52b2tlZCB3aXRoIGZvdXIgYXJndW1lbnRzOgogKiAgIDxsaT5UaGUgbWF0Y2ggYXJyYXksIHdpdGggbmFtZWQgYmFja3JlZmVyZW5jZSBwcm9wZXJ0aWVzLgogKiAgIDxsaT5UaGUgemVyby1iYXNlZCBtYXRjaCBpbmRleC4KICogICA8bGk+VGhlIHN0cmluZyBiZWluZyB0cmF2ZXJzZWQuCiAqICAgPGxpPlRoZSByZWdleCBvYmplY3QgYmVpbmcgdXNlZCB0byB0cmF2ZXJzZSB0aGUgc3RyaW5nLgogKiBAcGFyYW0geyp9IFtjb250ZXh0XSBPYmplY3QgdG8gdXNlIGFzIGB0aGlzYCB3aGVuIGV4ZWN1dGluZyBgY2FsbGJhY2tgLgogKiBAcmV0dXJucyB7Kn0gUHJvdmlkZWQgYGNvbnRleHRgIG9iamVjdC4KICogQGV4YW1wbGUKICoKICogLy8gRXh0cmFjdHMgZXZlcnkgb3RoZXIgZGlnaXQgZnJvbSBhIHN0cmluZwogKiBYUmVnRXhwLmZvckVhY2goJzFhMjM0NScsIC9cZC8sIGZ1bmN0aW9uIChtYXRjaCwgaSkgewogKiAgIGlmIChpICUgMikgdGhpcy5wdXNoKCttYXRjaFswXSk7CiAqIH0sIFtdKTsKICogLy8gLT4gWzIsIDRdCiAqLwogICAgc2VsZi5mb3JFYWNoID0gZnVuY3Rpb24gKHN0ciwgcmVnZXgsIGNhbGxiYWNrLCBjb250ZXh0KSB7CiAgICAgICAgdmFyIHBvcyA9IDAsCiAgICAgICAgICAgIGkgPSAtMSwKICAgICAgICAgICAgbWF0Y2g7CiAgICAgICAgd2hpbGUgKChtYXRjaCA9IHNlbGYuZXhlYyhzdHIsIHJlZ2V4LCBwb3MpKSkgewogICAgICAgICAgICBjYWxsYmFjay5jYWxsKGNvbnRleHQsIG1hdGNoLCArK2ksIHN0ciwgcmVnZXgpOwogICAgICAgICAgICBwb3MgPSBtYXRjaC5pbmRleCArIChtYXRjaFswXS5sZW5ndGggfHwgMSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb250ZXh0OwogICAgfTsKCi8qKgogKiBDb3BpZXMgYSByZWdleCBvYmplY3QgYW5kIGFkZHMgZmxhZyBgZ2AuIFRoZSBjb3B5IG1haW50YWlucyBzcGVjaWFsIHByb3BlcnRpZXMgZm9yIG5hbWVkCiAqIGNhcHR1cmUsIGlzIGF1Z21lbnRlZCB3aXRoIGBYUmVnRXhwLnByb3RvdHlwZWAgbWV0aG9kcywgYW5kIGhhcyBhIGZyZXNoIGBsYXN0SW5kZXhgIHByb3BlcnR5CiAqIChzZXQgdG8gemVybykuIE5hdGl2ZSByZWdleGVzIGFyZSBub3QgcmVjb21waWxlZCB1c2luZyBYUmVnRXhwIHN5bnRheC4KICogQG1lbWJlck9mIFhSZWdFeHAKICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4IFJlZ2V4IHRvIGdsb2JhbGl6ZS4KICogQHJldHVybnMge1JlZ0V4cH0gQ29weSBvZiB0aGUgcHJvdmlkZWQgcmVnZXggd2l0aCBmbGFnIGBnYCBhZGRlZC4KICogQGV4YW1wbGUKICoKICogdmFyIGdsb2JhbENvcHkgPSBYUmVnRXhwLmdsb2JhbGl6ZSgvcmVnZXgvKTsKICogZ2xvYmFsQ29weS5nbG9iYWw7IC8vIC0+IHRydWUKICovCiAgICBzZWxmLmdsb2JhbGl6ZSA9IGZ1bmN0aW9uIChyZWdleCkgewogICAgICAgIHJldHVybiBjb3B5KHJlZ2V4LCAiZyIpOwogICAgfTsKCi8qKgogKiBJbnN0YWxscyBvcHRpb25hbCBmZWF0dXJlcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBvcHRpb25zLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IG9wdGlvbnMgT3B0aW9ucyBvYmplY3Qgb3Igc3RyaW5nLgogKiBAZXhhbXBsZQogKgogKiAvLyBXaXRoIGFuIG9wdGlvbnMgb2JqZWN0CiAqIFhSZWdFeHAuaW5zdGFsbCh7CiAqICAgLy8gT3ZlcnJpZGVzIG5hdGl2ZSByZWdleCBtZXRob2RzIHdpdGggZml4ZWQvZXh0ZW5kZWQgdmVyc2lvbnMgdGhhdCBzdXBwb3J0IG5hbWVkCiAqICAgLy8gYmFja3JlZmVyZW5jZXMgYW5kIGZpeCBudW1lcm91cyBjcm9zcy1icm93c2VyIGJ1Z3MKICogICBuYXRpdmVzOiB0cnVlLAogKgogKiAgIC8vIEVuYWJsZXMgZXh0ZW5zaWJpbGl0eSBvZiBYUmVnRXhwIHN5bnRheCBhbmQgZmxhZ3MKICogICBleHRlbnNpYmlsaXR5OiB0cnVlCiAqIH0pOwogKgogKiAvLyBXaXRoIGFuIG9wdGlvbnMgc3RyaW5nCiAqIFhSZWdFeHAuaW5zdGFsbCgnbmF0aXZlcyBleHRlbnNpYmlsaXR5Jyk7CiAqCiAqIC8vIFVzaW5nIGEgc2hvcnRjdXQgdG8gaW5zdGFsbCBhbGwgb3B0aW9uYWwgZmVhdHVyZXMKICogWFJlZ0V4cC5pbnN0YWxsKCdhbGwnKTsKICovCiAgICBzZWxmLmluc3RhbGwgPSBmdW5jdGlvbiAob3B0aW9ucykgewogICAgICAgIG9wdGlvbnMgPSBwcmVwYXJlT3B0aW9ucyhvcHRpb25zKTsKICAgICAgICBpZiAoIWZlYXR1cmVzLm5hdGl2ZXMgJiYgb3B0aW9ucy5uYXRpdmVzKSB7CiAgICAgICAgICAgIHNldE5hdGl2ZXModHJ1ZSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmVhdHVyZXMuZXh0ZW5zaWJpbGl0eSAmJiBvcHRpb25zLmV4dGVuc2liaWxpdHkpIHsKICAgICAgICAgICAgc2V0RXh0ZW5zaWJpbGl0eSh0cnVlKTsKICAgICAgICB9CiAgICB9OwoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGFuIGluZGl2aWR1YWwgb3B0aW9uYWwgZmVhdHVyZSBpcyBpbnN0YWxsZWQuCiAqIEBtZW1iZXJPZiBYUmVnRXhwCiAqIEBwYXJhbSB7U3RyaW5nfSBmZWF0dXJlIE5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gY2hlY2suIE9uZSBvZjoKICogICA8bGk+YG5hdGl2ZXNgCiAqICAgPGxpPmBleHRlbnNpYmlsaXR5YAogKiBAcmV0dXJucyB7Qm9vbGVhbn0gV2hldGhlciB0aGUgZmVhdHVyZSBpcyBpbnN0YWxsZWQuCiAqIEBleGFtcGxlCiAqCiAqIFhSZWdFeHAuaXNJbnN0YWxsZWQoJ25hdGl2ZXMnKTsKICovCiAgICBzZWxmLmlzSW5zdGFsbGVkID0gZnVuY3Rpb24gKGZlYXR1cmUpIHsKICAgICAgICByZXR1cm4gISEoZmVhdHVyZXNbZmVhdHVyZV0pOwogICAgfTsKCi8qKgogKiBSZXR1cm5zIGB0cnVlYCBpZiBhbiBvYmplY3QgaXMgYSByZWdleDsgYGZhbHNlYCBpZiBpdCBpc24ndC4gVGhpcyB3b3JrcyBjb3JyZWN0bHkgZm9yIHJlZ2V4ZXMKICogY3JlYXRlZCBpbiBhbm90aGVyIGZyYW1lLCB3aGVuIGBpbnN0YW5jZW9mYCBhbmQgYGNvbnN0cnVjdG9yYCBjaGVja3Mgd291bGQgZmFpbC4KICogQG1lbWJlck9mIFhSZWdFeHAKICogQHBhcmFtIHsqfSB2YWx1ZSBPYmplY3QgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtCb29sZWFufSBXaGV0aGVyIHRoZSBvYmplY3QgaXMgYSBgUmVnRXhwYCBvYmplY3QuCiAqIEBleGFtcGxlCiAqCiAqIFhSZWdFeHAuaXNSZWdFeHAoJ3N0cmluZycpOyAvLyAtPiBmYWxzZQogKiBYUmVnRXhwLmlzUmVnRXhwKC9yZWdleC9pKTsgLy8gLT4gdHJ1ZQogKiBYUmVnRXhwLmlzUmVnRXhwKFJlZ0V4cCgnXicsICdtJykpOyAvLyAtPiB0cnVlCiAqIFhSZWdFeHAuaXNSZWdFeHAoWFJlZ0V4cCgnKD9zKS4nKSk7IC8vIC0+IHRydWUKICovCiAgICBzZWxmLmlzUmVnRXhwID0gZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGlzVHlwZSh2YWx1ZSwgInJlZ2V4cCIpOwogICAgfTsKCi8qKgogKiBSZXRyaWV2ZXMgdGhlIG1hdGNoZXMgZnJvbSBzZWFyY2hpbmcgYSBzdHJpbmcgdXNpbmcgYSBjaGFpbiBvZiByZWdleGVzIHRoYXQgc3VjY2Vzc2l2ZWx5IHNlYXJjaAogKiB3aXRoaW4gcHJldmlvdXMgbWF0Y2hlcy4gVGhlIHByb3ZpZGVkIGBjaGFpbmAgYXJyYXkgY2FuIGNvbnRhaW4gcmVnZXhlcyBhbmQgb2JqZWN0cyB3aXRoIGByZWdleGAKICogYW5kIGBiYWNrcmVmYCBwcm9wZXJ0aWVzLiBXaGVuIGEgYmFja3JlZmVyZW5jZSBpcyBzcGVjaWZpZWQsIHRoZSBuYW1lZCBvciBudW1iZXJlZCBiYWNrcmVmZXJlbmNlCiAqIGlzIHBhc3NlZCBmb3J3YXJkIHRvIHRoZSBuZXh0IHJlZ2V4IG9yIHJldHVybmVkLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBzZWFyY2guCiAqIEBwYXJhbSB7QXJyYXl9IGNoYWluIFJlZ2V4ZXMgdGhhdCBlYWNoIHNlYXJjaCBmb3IgbWF0Y2hlcyB3aXRoaW4gcHJlY2VkaW5nIHJlc3VsdHMuCiAqIEByZXR1cm5zIHtBcnJheX0gTWF0Y2hlcyBieSB0aGUgbGFzdCByZWdleCBpbiB0aGUgY2hhaW4sIG9yIGFuIGVtcHR5IGFycmF5LgogKiBAZXhhbXBsZQogKgogKiAvLyBCYXNpYyB1c2FnZTsgbWF0Y2hlcyBudW1iZXJzIHdpdGhpbiA8Yj4gdGFncwogKiBYUmVnRXhwLm1hdGNoQ2hhaW4oJzEgPGI+MjwvYj4gMyA8Yj40IGEgNTY8L2I+JywgWwogKiAgIFhSZWdFeHAoJyg/aXMpPGI+Lio/PC9iPicpLAogKiAgIC9cZCsvCiAqIF0pOwogKiAvLyAtPiBbJzInLCAnNCcsICc1NiddCiAqCiAqIC8vIFBhc3NpbmcgZm9yd2FyZCBhbmQgcmV0dXJuaW5nIHNwZWNpZmljIGJhY2tyZWZlcmVuY2VzCiAqIGh0bWwgPSAnPGEgaHJlZj0iaHR0cDovL3hyZWdleHAuY29tL2FwaS8iPlhSZWdFeHA8L2E+XAogKiAgICAgICAgIDxhIGhyZWY9Imh0dHA6Ly93d3cuZ29vZ2xlLmNvbS8iPkdvb2dsZTwvYT4nOwogKiBYUmVnRXhwLm1hdGNoQ2hhaW4oaHRtbCwgWwogKiAgIHtyZWdleDogLzxhIGhyZWY9IihbXiJdKykiPi9pLCBiYWNrcmVmOiAxfSwKICogICB7cmVnZXg6IFhSZWdFeHAoJyg/aSleaHR0cHM/Oi8vKD88ZG9tYWluPlteLz8jXSspJyksIGJhY2tyZWY6ICdkb21haW4nfQogKiBdKTsKICogLy8gLT4gWyd4cmVnZXhwLmNvbScsICd3d3cuZ29vZ2xlLmNvbSddCiAqLwogICAgc2VsZi5tYXRjaENoYWluID0gZnVuY3Rpb24gKHN0ciwgY2hhaW4pIHsKICAgICAgICByZXR1cm4gKGZ1bmN0aW9uIHJlY3Vyc2VDaGFpbih2YWx1ZXMsIGxldmVsKSB7CiAgICAgICAgICAgIHZhciBpdGVtID0gY2hhaW5bbGV2ZWxdLnJlZ2V4ID8gY2hhaW5bbGV2ZWxdIDoge3JlZ2V4OiBjaGFpbltsZXZlbF19LAogICAgICAgICAgICAgICAgbWF0Y2hlcyA9IFtdLAogICAgICAgICAgICAgICAgYWRkTWF0Y2ggPSBmdW5jdGlvbiAobWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaGVzLnB1c2goaXRlbS5iYWNrcmVmID8gKG1hdGNoW2l0ZW0uYmFja3JlZl0gfHwgIiIpIDogbWF0Y2hbMF0pOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGk7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIHNlbGYuZm9yRWFjaCh2YWx1ZXNbaV0sIGl0ZW0ucmVnZXgsIGFkZE1hdGNoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gKChsZXZlbCA9PT0gY2hhaW4ubGVuZ3RoIC0gMSkgfHwgIW1hdGNoZXMubGVuZ3RoKSA/CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlcyA6CiAgICAgICAgICAgICAgICAgICAgcmVjdXJzZUNoYWluKG1hdGNoZXMsIGxldmVsICsgMSk7CiAgICAgICAgfShbc3RyXSwgMCkpOwogICAgfTsKCi8qKgogKiBSZXR1cm5zIGEgbmV3IHN0cmluZyB3aXRoIG9uZSBvciBhbGwgbWF0Y2hlcyBvZiBhIHBhdHRlcm4gcmVwbGFjZWQuIFRoZSBwYXR0ZXJuIGNhbiBiZSBhIHN0cmluZwogKiBvciByZWdleCwgYW5kIHRoZSByZXBsYWNlbWVudCBjYW4gYmUgYSBzdHJpbmcgb3IgYSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgZm9yIGVhY2ggbWF0Y2guIFRvCiAqIHBlcmZvcm0gYSBnbG9iYWwgc2VhcmNoIGFuZCByZXBsYWNlLCB1c2UgdGhlIG9wdGlvbmFsIGBzY29wZWAgYXJndW1lbnQgb3IgaW5jbHVkZSBmbGFnIGBnYCBpZgogKiB1c2luZyBhIHJlZ2V4LiBSZXBsYWNlbWVudCBzdHJpbmdzIGNhbiB1c2UgYCR7bn1gIGZvciBuYW1lZCBhbmQgbnVtYmVyZWQgYmFja3JlZmVyZW5jZXMuCiAqIFJlcGxhY2VtZW50IGZ1bmN0aW9ucyBjYW4gdXNlIG5hbWVkIGJhY2tyZWZlcmVuY2VzIHZpYSBgYXJndW1lbnRzWzBdLm5hbWVgLiBBbHNvIGZpeGVzIGJyb3dzZXIKICogYnVncyBjb21wYXJlZCB0byB0aGUgbmF0aXZlIGBTdHJpbmcucHJvdG90eXBlLnJlcGxhY2VgIGFuZCBjYW4gYmUgdXNlZCByZWxpYWJseSBjcm9zcy1icm93c2VyLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBzZWFyY2guCiAqIEBwYXJhbSB7UmVnRXhwfFN0cmluZ30gc2VhcmNoIFNlYXJjaCBwYXR0ZXJuIHRvIGJlIHJlcGxhY2VkLgogKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gcmVwbGFjZW1lbnQgUmVwbGFjZW1lbnQgc3RyaW5nIG9yIGEgZnVuY3Rpb24gaW52b2tlZCB0byBjcmVhdGUgaXQuCiAqICAgUmVwbGFjZW1lbnQgc3RyaW5ncyBjYW4gaW5jbHVkZSBzcGVjaWFsIHJlcGxhY2VtZW50IHN5bnRheDoKICogICAgIDxsaT4kJCAtIEluc2VydHMgYSBsaXRlcmFsICckJy4KICogICAgIDxsaT4kJiwgJDAgLSBJbnNlcnRzIHRoZSBtYXRjaGVkIHN1YnN0cmluZy4KICogICAgIDxsaT4kYCAtIEluc2VydHMgdGhlIHN0cmluZyB0aGF0IHByZWNlZGVzIHRoZSBtYXRjaGVkIHN1YnN0cmluZyAobGVmdCBjb250ZXh0KS4KICogICAgIDxsaT4kJyAtIEluc2VydHMgdGhlIHN0cmluZyB0aGF0IGZvbGxvd3MgdGhlIG1hdGNoZWQgc3Vic3RyaW5nIChyaWdodCBjb250ZXh0KS4KICogICAgIDxsaT4kbiwgJG5uIC0gV2hlcmUgbi9ubiBhcmUgZGlnaXRzIHJlZmVyZW5jaW5nIGFuIGV4aXN0ZW50IGNhcHR1cmluZyBncm91cCwgaW5zZXJ0cwogKiAgICAgICBiYWNrcmVmZXJlbmNlIG4vbm4uCiAqICAgICA8bGk+JHtufSAtIFdoZXJlIG4gaXMgYSBuYW1lIG9yIGFueSBudW1iZXIgb2YgZGlnaXRzIHRoYXQgcmVmZXJlbmNlIGFuIGV4aXN0ZW50IGNhcHR1cmluZwogKiAgICAgICBncm91cCwgaW5zZXJ0cyBiYWNrcmVmZXJlbmNlIG4uCiAqICAgUmVwbGFjZW1lbnQgZnVuY3Rpb25zIGFyZSBpbnZva2VkIHdpdGggdGhyZWUgb3IgbW9yZSBhcmd1bWVudHM6CiAqICAgICA8bGk+VGhlIG1hdGNoZWQgc3Vic3RyaW5nIChjb3JyZXNwb25kcyB0byAkJiBhYm92ZSkuIE5hbWVkIGJhY2tyZWZlcmVuY2VzIGFyZSBhY2Nlc3NpYmxlIGFzCiAqICAgICAgIHByb3BlcnRpZXMgb2YgdGhpcyBmaXJzdCBhcmd1bWVudC4KICogICAgIDxsaT4wLi5uIGFyZ3VtZW50cywgb25lIGZvciBlYWNoIGJhY2tyZWZlcmVuY2UgKGNvcnJlc3BvbmRpbmcgdG8gJDEsICQyLCBldGMuIGFib3ZlKS4KICogICAgIDxsaT5UaGUgemVyby1iYXNlZCBpbmRleCBvZiB0aGUgbWF0Y2ggd2l0aGluIHRoZSB0b3RhbCBzZWFyY2ggc3RyaW5nLgogKiAgICAgPGxpPlRoZSB0b3RhbCBzdHJpbmcgYmVpbmcgc2VhcmNoZWQuCiAqIEBwYXJhbSB7U3RyaW5nfSBbc2NvcGU9J29uZSddIFVzZSAnb25lJyB0byByZXBsYWNlIHRoZSBmaXJzdCBtYXRjaCBvbmx5LCBvciAnYWxsJy4gSWYgbm90CiAqICAgZXhwbGljaXRseSBzcGVjaWZpZWQgYW5kIHVzaW5nIGEgcmVnZXggd2l0aCBmbGFnIGBnYCwgYHNjb3BlYCBpcyAnYWxsJy4KICogQHJldHVybnMge1N0cmluZ30gTmV3IHN0cmluZyB3aXRoIG9uZSBvciBhbGwgbWF0Y2hlcyByZXBsYWNlZC4KICogQGV4YW1wbGUKICoKICogLy8gUmVnZXggc2VhcmNoLCB1c2luZyBuYW1lZCBiYWNrcmVmZXJlbmNlcyBpbiByZXBsYWNlbWVudCBzdHJpbmcKICogdmFyIG5hbWUgPSBYUmVnRXhwKCcoPzxmaXJzdD5cXHcrKSAoPzxsYXN0PlxcdyspJyk7CiAqIFhSZWdFeHAucmVwbGFjZSgnSm9obiBTbWl0aCcsIG5hbWUsICcke2xhc3R9LCAke2ZpcnN0fScpOwogKiAvLyAtPiAnU21pdGgsIEpvaG4nCiAqCiAqIC8vIFJlZ2V4IHNlYXJjaCwgdXNpbmcgbmFtZWQgYmFja3JlZmVyZW5jZXMgaW4gcmVwbGFjZW1lbnQgZnVuY3Rpb24KICogWFJlZ0V4cC5yZXBsYWNlKCdKb2huIFNtaXRoJywgbmFtZSwgZnVuY3Rpb24gKG1hdGNoKSB7CiAqICAgcmV0dXJuIG1hdGNoLmxhc3QgKyAnLCAnICsgbWF0Y2guZmlyc3Q7CiAqIH0pOwogKiAvLyAtPiAnU21pdGgsIEpvaG4nCiAqCiAqIC8vIEdsb2JhbCBzdHJpbmcgc2VhcmNoL3JlcGxhY2VtZW50CiAqIFhSZWdFeHAucmVwbGFjZSgnUmVnRXhwIGJ1aWxkcyBSZWdFeHBzJywgJ1JlZ0V4cCcsICdYUmVnRXhwJywgJ2FsbCcpOwogKiAvLyAtPiAnWFJlZ0V4cCBidWlsZHMgWFJlZ0V4cHMnCiAqLwogICAgc2VsZi5yZXBsYWNlID0gZnVuY3Rpb24gKHN0ciwgc2VhcmNoLCByZXBsYWNlbWVudCwgc2NvcGUpIHsKICAgICAgICB2YXIgaXNSZWdleCA9IHNlbGYuaXNSZWdFeHAoc2VhcmNoKSwKICAgICAgICAgICAgc2VhcmNoMiA9IHNlYXJjaCwKICAgICAgICAgICAgcmVzdWx0OwogICAgICAgIGlmIChpc1JlZ2V4KSB7CiAgICAgICAgICAgIGlmIChzY29wZSA9PT0gdW5kZWYgJiYgc2VhcmNoLmdsb2JhbCkgewogICAgICAgICAgICAgICAgc2NvcGUgPSAiYWxsIjsgLy8gRm9sbG93IGZsYWcgZyB3aGVuIGBzY29wZWAgaXNuJ3QgZXhwbGljaXQKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBOb3RlIHRoYXQgc2luY2UgYSBjb3B5IGlzIHVzZWQsIGBzZWFyY2hgJ3MgYGxhc3RJbmRleGAgaXNuJ3QgdXBkYXRlZCAqZHVyaW5nKiByZXBsYWNlbWVudCBpdGVyYXRpb25zCiAgICAgICAgICAgIHNlYXJjaDIgPSBjb3B5KHNlYXJjaCwgc2NvcGUgPT09ICJhbGwiID8gImciIDogIiIsIHNjb3BlID09PSAiYWxsIiA/ICIiIDogImciKTsKICAgICAgICB9IGVsc2UgaWYgKHNjb3BlID09PSAiYWxsIikgewogICAgICAgICAgICBzZWFyY2gyID0gbmV3IFJlZ0V4cChzZWxmLmVzY2FwZShTdHJpbmcoc2VhcmNoKSksICJnIik7CiAgICAgICAgfQogICAgICAgIHJlc3VsdCA9IGZpeGVkLnJlcGxhY2UuY2FsbChTdHJpbmcoc3RyKSwgc2VhcmNoMiwgcmVwbGFjZW1lbnQpOyAvLyBGaXhlZCBgcmVwbGFjZWAgcmVxdWlyZWQgZm9yIG5hbWVkIGJhY2tyZWZlcmVuY2VzLCBldGMuCiAgICAgICAgaWYgKGlzUmVnZXggJiYgc2VhcmNoLmdsb2JhbCkgewogICAgICAgICAgICBzZWFyY2gubGFzdEluZGV4ID0gMDsgLy8gRml4ZXMgSUUsIFNhZmFyaSBidWcgKGxhc3QgdGVzdGVkIElFIDksIFNhZmFyaSA1LjEpCiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9OwoKLyoqCiAqIFNwbGl0cyBhIHN0cmluZyBpbnRvIGFuIGFycmF5IG9mIHN0cmluZ3MgdXNpbmcgYSByZWdleCBvciBzdHJpbmcgc2VwYXJhdG9yLiBNYXRjaGVzIG9mIHRoZQogKiBzZXBhcmF0b3IgYXJlIG5vdCBpbmNsdWRlZCBpbiB0aGUgcmVzdWx0IGFycmF5LiBIb3dldmVyLCBpZiBgc2VwYXJhdG9yYCBpcyBhIHJlZ2V4IHRoYXQgY29udGFpbnMKICogY2FwdHVyaW5nIGdyb3VwcywgYmFja3JlZmVyZW5jZXMgYXJlIHNwbGljZWQgaW50byB0aGUgcmVzdWx0IGVhY2ggdGltZSBgc2VwYXJhdG9yYCBpcyBtYXRjaGVkLgogKiBGaXhlcyBicm93c2VyIGJ1Z3MgY29tcGFyZWQgdG8gdGhlIG5hdGl2ZSBgU3RyaW5nLnByb3RvdHlwZS5zcGxpdGAgYW5kIGNhbiBiZSB1c2VkIHJlbGlhYmx5CiAqIGNyb3NzLWJyb3dzZXIuCiAqIEBtZW1iZXJPZiBYUmVnRXhwCiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIHNwbGl0LgogKiBAcGFyYW0ge1JlZ0V4cHxTdHJpbmd9IHNlcGFyYXRvciBSZWdleCBvciBzdHJpbmcgdG8gdXNlIGZvciBzZXBhcmF0aW5nIHRoZSBzdHJpbmcuCiAqIEBwYXJhbSB7TnVtYmVyfSBbbGltaXRdIE1heGltdW0gbnVtYmVyIG9mIGl0ZW1zIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3VsdCBhcnJheS4KICogQHJldHVybnMge0FycmF5fSBBcnJheSBvZiBzdWJzdHJpbmdzLgogKiBAZXhhbXBsZQogKgogKiAvLyBCYXNpYyB1c2UKICogWFJlZ0V4cC5zcGxpdCgnYSBiIGMnLCAnICcpOwogKiAvLyAtPiBbJ2EnLCAnYicsICdjJ10KICoKICogLy8gV2l0aCBsaW1pdAogKiBYUmVnRXhwLnNwbGl0KCdhIGIgYycsICcgJywgMik7CiAqIC8vIC0+IFsnYScsICdiJ10KICoKICogLy8gQmFja3JlZmVyZW5jZXMgaW4gcmVzdWx0IGFycmF5CiAqIFhSZWdFeHAuc3BsaXQoJy4ud29yZDEuLicsIC8oW2Etel0rKShcZCspL2kpOwogKiAvLyAtPiBbJy4uJywgJ3dvcmQnLCAnMScsICcuLiddCiAqLwogICAgc2VsZi5zcGxpdCA9IGZ1bmN0aW9uIChzdHIsIHNlcGFyYXRvciwgbGltaXQpIHsKICAgICAgICByZXR1cm4gZml4ZWQuc3BsaXQuY2FsbChzdHIsIHNlcGFyYXRvciwgbGltaXQpOwogICAgfTsKCi8qKgogKiBFeGVjdXRlcyBhIHJlZ2V4IHNlYXJjaCBpbiBhIHNwZWNpZmllZCBzdHJpbmcuIFJldHVybnMgYHRydWVgIG9yIGBmYWxzZWAuIE9wdGlvbmFsIGBwb3NgIGFuZAogKiBgc3RpY2t5YCBhcmd1bWVudHMgc3BlY2lmeSB0aGUgc2VhcmNoIHN0YXJ0IHBvc2l0aW9uLCBhbmQgd2hldGhlciB0aGUgbWF0Y2ggbXVzdCBzdGFydCBhdCB0aGUKICogc3BlY2lmaWVkIHBvc2l0aW9uIG9ubHkuIFRoZSBgbGFzdEluZGV4YCBwcm9wZXJ0eSBvZiB0aGUgcHJvdmlkZWQgcmVnZXggaXMgbm90IHVzZWQsIGJ1dCBpcwogKiB1cGRhdGVkIGZvciBjb21wYXRpYmlsaXR5LiBBbHNvIGZpeGVzIGJyb3dzZXIgYnVncyBjb21wYXJlZCB0byB0aGUgbmF0aXZlCiAqIGBSZWdFeHAucHJvdG90eXBlLnRlc3RgIGFuZCBjYW4gYmUgdXNlZCByZWxpYWJseSBjcm9zcy1icm93c2VyLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBzZWFyY2guCiAqIEBwYXJhbSB7UmVnRXhwfSByZWdleCBSZWdleCB0byBzZWFyY2ggd2l0aC4KICogQHBhcmFtIHtOdW1iZXJ9IFtwb3M9MF0gWmVyby1iYXNlZCBpbmRleCBhdCB3aGljaCB0byBzdGFydCB0aGUgc2VhcmNoLgogKiBAcGFyYW0ge0Jvb2xlYW58U3RyaW5nfSBbc3RpY2t5PWZhbHNlXSBXaGV0aGVyIHRoZSBtYXRjaCBtdXN0IHN0YXJ0IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24KICogICBvbmx5LiBUaGUgc3RyaW5nIGAnc3RpY2t5J2AgaXMgYWNjZXB0ZWQgYXMgYW4gYWx0ZXJuYXRpdmUgdG8gYHRydWVgLgogKiBAcmV0dXJucyB7Qm9vbGVhbn0gV2hldGhlciB0aGUgcmVnZXggbWF0Y2hlZCB0aGUgcHJvdmlkZWQgdmFsdWUuCiAqIEBleGFtcGxlCiAqCiAqIC8vIEJhc2ljIHVzZQogKiBYUmVnRXhwLnRlc3QoJ2FiYycsIC9jLyk7IC8vIC0+IHRydWUKICoKICogLy8gV2l0aCBwb3MgYW5kIHN0aWNreQogKiBYUmVnRXhwLnRlc3QoJ2FiYycsIC9jLywgMCwgJ3N0aWNreScpOyAvLyAtPiBmYWxzZQogKi8KICAgIHNlbGYudGVzdCA9IGZ1bmN0aW9uIChzdHIsIHJlZ2V4LCBwb3MsIHN0aWNreSkgewogICAgICAgIC8vIERvIHRoaXMgdGhlIGVhc3kgd2F5IDotKQogICAgICAgIHJldHVybiAhIXNlbGYuZXhlYyhzdHIsIHJlZ2V4LCBwb3MsIHN0aWNreSk7CiAgICB9OwoKLyoqCiAqIFVuaW5zdGFsbHMgb3B0aW9uYWwgZmVhdHVyZXMgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgb3B0aW9ucy4KICogQG1lbWJlck9mIFhSZWdFeHAKICogQHBhcmFtIHtPYmplY3R8U3RyaW5nfSBvcHRpb25zIE9wdGlvbnMgb2JqZWN0IG9yIHN0cmluZy4KICogQGV4YW1wbGUKICoKICogLy8gV2l0aCBhbiBvcHRpb25zIG9iamVjdAogKiBYUmVnRXhwLnVuaW5zdGFsbCh7CiAqICAgLy8gUmVzdG9yZXMgbmF0aXZlIHJlZ2V4IG1ldGhvZHMKICogICBuYXRpdmVzOiB0cnVlLAogKgogKiAgIC8vIERpc2FibGVzIGFkZGl0aW9uYWwgc3ludGF4IGFuZCBmbGFnIGV4dGVuc2lvbnMKICogICBleHRlbnNpYmlsaXR5OiB0cnVlCiAqIH0pOwogKgogKiAvLyBXaXRoIGFuIG9wdGlvbnMgc3RyaW5nCiAqIFhSZWdFeHAudW5pbnN0YWxsKCduYXRpdmVzIGV4dGVuc2liaWxpdHknKTsKICoKICogLy8gVXNpbmcgYSBzaG9ydGN1dCB0byB1bmluc3RhbGwgYWxsIG9wdGlvbmFsIGZlYXR1cmVzCiAqIFhSZWdFeHAudW5pbnN0YWxsKCdhbGwnKTsKICovCiAgICBzZWxmLnVuaW5zdGFsbCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7CiAgICAgICAgb3B0aW9ucyA9IHByZXBhcmVPcHRpb25zKG9wdGlvbnMpOwogICAgICAgIGlmIChmZWF0dXJlcy5uYXRpdmVzICYmIG9wdGlvbnMubmF0aXZlcykgewogICAgICAgICAgICBzZXROYXRpdmVzKGZhbHNlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZlYXR1cmVzLmV4dGVuc2liaWxpdHkgJiYgb3B0aW9ucy5leHRlbnNpYmlsaXR5KSB7CiAgICAgICAgICAgIHNldEV4dGVuc2liaWxpdHkoZmFsc2UpOwogICAgICAgIH0KICAgIH07CgovKioKICogUmV0dXJucyBhbiBYUmVnRXhwIG9iamVjdCB0aGF0IGlzIHRoZSB1bmlvbiBvZiB0aGUgZ2l2ZW4gcGF0dGVybnMuIFBhdHRlcm5zIGNhbiBiZSBwcm92aWRlZCBhcwogKiByZWdleCBvYmplY3RzIG9yIHN0cmluZ3MuIE1ldGFjaGFyYWN0ZXJzIGFyZSBlc2NhcGVkIGluIHBhdHRlcm5zIHByb3ZpZGVkIGFzIHN0cmluZ3MuCiAqIEJhY2tyZWZlcmVuY2VzIGluIHByb3ZpZGVkIHJlZ2V4IG9iamVjdHMgYXJlIGF1dG9tYXRpY2FsbHkgcmVudW1iZXJlZCB0byB3b3JrIGNvcnJlY3RseS4gTmF0aXZlCiAqIGZsYWdzIHVzZWQgYnkgcHJvdmlkZWQgcmVnZXhlcyBhcmUgaWdub3JlZCBpbiBmYXZvciBvZiB0aGUgYGZsYWdzYCBhcmd1bWVudC4KICogQG1lbWJlck9mIFhSZWdFeHAKICogQHBhcmFtIHtBcnJheX0gcGF0dGVybnMgUmVnZXhlcyBhbmQgc3RyaW5ncyB0byBjb21iaW5lLgogKiBAcGFyYW0ge1N0cmluZ30gW2ZsYWdzXSBBbnkgY29tYmluYXRpb24gb2YgWFJlZ0V4cCBmbGFncy4KICogQHJldHVybnMge1JlZ0V4cH0gVW5pb24gb2YgdGhlIHByb3ZpZGVkIHJlZ2V4ZXMgYW5kIHN0cmluZ3MuCiAqIEBleGFtcGxlCiAqCiAqIFhSZWdFeHAudW5pb24oWydhK2IqYycsIC8oZG9ncylcMS8sIC8oY2F0cylcMS9dLCAnaScpOwogKiAvLyAtPiAvYVwrYlwqY3woZG9ncylcMXwoY2F0cylcMi9pCiAqCiAqIFhSZWdFeHAudW5pb24oW1hSZWdFeHAoJyg/PHBldD5kb2dzKVxcazxwZXQ+JyksIFhSZWdFeHAoJyg/PHBldD5jYXRzKVxcazxwZXQ+JyldKTsKICogLy8gLT4gWFJlZ0V4cCgnKD88cGV0PmRvZ3MpXFxrPHBldD58KD88cGV0PmNhdHMpXFxrPHBldD4nKQogKi8KICAgIHNlbGYudW5pb24gPSBmdW5jdGlvbiAocGF0dGVybnMsIGZsYWdzKSB7CiAgICAgICAgdmFyIHBhcnRzID0gLyhcKCkoPyFcPyl8XFwoWzEtOV1cZCopfFxcW1xzXFNdfFxbKD86W15cXFxdXXxcXFtcc1xTXSkqXS9nLAogICAgICAgICAgICBudW1DYXB0dXJlcyA9IDAsCiAgICAgICAgICAgIG51bVByaW9yQ2FwdHVyZXMsCiAgICAgICAgICAgIGNhcHR1cmVOYW1lcywKICAgICAgICAgICAgcmV3cml0ZSA9IGZ1bmN0aW9uIChtYXRjaCwgcGFyZW4sIGJhY2tyZWYpIHsKICAgICAgICAgICAgICAgIHZhciBuYW1lID0gY2FwdHVyZU5hbWVzW251bUNhcHR1cmVzIC0gbnVtUHJpb3JDYXB0dXJlc107CiAgICAgICAgICAgICAgICBpZiAocGFyZW4pIHsgLy8gQ2FwdHVyaW5nIGdyb3VwCiAgICAgICAgICAgICAgICAgICAgKytudW1DYXB0dXJlczsKICAgICAgICAgICAgICAgICAgICBpZiAobmFtZSkgeyAvLyBJZiB0aGUgY3VycmVudCBjYXB0dXJlIGhhcyBhIG5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICIoPzwiICsgbmFtZSArICI+IjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJhY2tyZWYpIHsgLy8gQmFja3JlZmVyZW5jZQogICAgICAgICAgICAgICAgICAgIHJldHVybiAiXFwiICsgKCtiYWNrcmVmICsgbnVtUHJpb3JDYXB0dXJlcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2g7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIG91dHB1dCA9IFtdLAogICAgICAgICAgICBwYXR0ZXJuLAogICAgICAgICAgICBpOwogICAgICAgIGlmICghKGlzVHlwZShwYXR0ZXJucywgImFycmF5IikgJiYgcGF0dGVybnMubGVuZ3RoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCJwYXR0ZXJucyBtdXN0IGJlIGEgbm9uZW1wdHkgYXJyYXkiKTsKICAgICAgICB9CiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBhdHRlcm5zLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuc1tpXTsKICAgICAgICAgICAgaWYgKHNlbGYuaXNSZWdFeHAocGF0dGVybikpIHsKICAgICAgICAgICAgICAgIG51bVByaW9yQ2FwdHVyZXMgPSBudW1DYXB0dXJlczsKICAgICAgICAgICAgICAgIGNhcHR1cmVOYW1lcyA9IChwYXR0ZXJuLnhyZWdleHAgJiYgcGF0dGVybi54cmVnZXhwLmNhcHR1cmVOYW1lcykgfHwgW107CiAgICAgICAgICAgICAgICAvLyBSZXdyaXRlIGJhY2tyZWZlcmVuY2VzLiBQYXNzaW5nIHRvIFhSZWdFeHAgZGllcyBvbiBvY3RhbHMgYW5kIGVuc3VyZXMgcGF0dGVybnMKICAgICAgICAgICAgICAgIC8vIGFyZSBpbmRlcGVuZGVudGx5IHZhbGlkOyBoZWxwcyBrZWVwIHRoaXMgc2ltcGxlLiBOYW1lZCBjYXB0dXJlcyBhcmUgcHV0IGJhY2sKICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKHNlbGYocGF0dGVybi5zb3VyY2UpLnNvdXJjZS5yZXBsYWNlKHBhcnRzLCByZXdyaXRlKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBvdXRwdXQucHVzaChzZWxmLmVzY2FwZShwYXR0ZXJuKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNlbGYob3V0cHV0LmpvaW4oInwiKSwgZmxhZ3MpOwogICAgfTsKCi8qKgogKiBUaGUgWFJlZ0V4cCB2ZXJzaW9uIG51bWJlci4KICogQHN0YXRpYwogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAdHlwZSBTdHJpbmcKICovCiAgICBzZWxmLnZlcnNpb24gPSAiMi4wLjAiOwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiAgRml4ZWQvZXh0ZW5kZWQgbmF0aXZlIG1ldGhvZHMKICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKLyoqCiAqIEFkZHMgbmFtZWQgY2FwdHVyZSBzdXBwb3J0ICh3aXRoIGJhY2tyZWZlcmVuY2VzIHJldHVybmVkIGFzIGByZXN1bHQubmFtZWApLCBhbmQgZml4ZXMgYnJvd3NlcgogKiBidWdzIGluIHRoZSBuYXRpdmUgYFJlZ0V4cC5wcm90b3R5cGUuZXhlY2AuIENhbGxpbmcgYFhSZWdFeHAuaW5zdGFsbCgnbmF0aXZlcycpYCB1c2VzIHRoaXMgdG8KICogb3ZlcnJpZGUgdGhlIG5hdGl2ZSBtZXRob2QuIFVzZSB2aWEgYFhSZWdFeHAuZXhlY2Agd2l0aG91dCBvdmVycmlkaW5nIG5hdGl2ZXMuCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIHNlYXJjaC4KICogQHJldHVybnMge0FycmF5fSBNYXRjaCBhcnJheSB3aXRoIG5hbWVkIGJhY2tyZWZlcmVuY2UgcHJvcGVydGllcywgb3IgbnVsbC4KICovCiAgICBmaXhlZC5leGVjID0gZnVuY3Rpb24gKHN0cikgewogICAgICAgIHZhciBtYXRjaCwgbmFtZSwgcjIsIG9yaWdMYXN0SW5kZXgsIGk7CiAgICAgICAgaWYgKCF0aGlzLmdsb2JhbCkgewogICAgICAgICAgICBvcmlnTGFzdEluZGV4ID0gdGhpcy5sYXN0SW5kZXg7CiAgICAgICAgfQogICAgICAgIG1hdGNoID0gbmF0aXYuZXhlYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIGlmIChtYXRjaCkgewogICAgICAgICAgICAvLyBGaXggYnJvd3NlcnMgd2hvc2UgYGV4ZWNgIG1ldGhvZHMgZG9uJ3QgY29uc2lzdGVudGx5IHJldHVybiBgdW5kZWZpbmVkYCBmb3IKICAgICAgICAgICAgLy8gbm9ucGFydGljaXBhdGluZyBjYXB0dXJpbmcgZ3JvdXBzCiAgICAgICAgICAgIGlmICghY29tcGxpYW50RXhlY05wY2cgJiYgbWF0Y2gubGVuZ3RoID4gMSAmJiBsYXN0SW5kZXhPZihtYXRjaCwgIiIpID4gLTEpIHsKICAgICAgICAgICAgICAgIHIyID0gbmV3IFJlZ0V4cCh0aGlzLnNvdXJjZSwgbmF0aXYucmVwbGFjZS5jYWxsKGdldE5hdGl2ZUZsYWdzKHRoaXMpLCAiZyIsICIiKSk7CiAgICAgICAgICAgICAgICAvLyBVc2luZyBgc3RyLnNsaWNlKG1hdGNoLmluZGV4KWAgcmF0aGVyIHRoYW4gYG1hdGNoWzBdYCBpbiBjYXNlIGxvb2thaGVhZCBhbGxvd2VkCiAgICAgICAgICAgICAgICAvLyBtYXRjaGluZyBkdWUgdG8gY2hhcmFjdGVycyBvdXRzaWRlIHRoZSBtYXRjaAogICAgICAgICAgICAgICAgbmF0aXYucmVwbGFjZS5jYWxsKFN0cmluZyhzdHIpLnNsaWNlKG1hdGNoLmluZGV4KSwgcjIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaTsKICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aCAtIDI7ICsraSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzW2ldID09PSB1bmRlZikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hbaV0gPSB1bmRlZjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEF0dGFjaCBuYW1lZCBjYXB0dXJlIHByb3BlcnRpZXMKICAgICAgICAgICAgaWYgKHRoaXMueHJlZ2V4cCAmJiB0aGlzLnhyZWdleHAuY2FwdHVyZU5hbWVzKSB7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgbWF0Y2gubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICBuYW1lID0gdGhpcy54cmVnZXhwLmNhcHR1cmVOYW1lc1tpIC0gMV07CiAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hbbmFtZV0gPSBtYXRjaFtpXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gRml4IGJyb3dzZXJzIHRoYXQgaW5jcmVtZW50IGBsYXN0SW5kZXhgIGFmdGVyIHplcm8tbGVuZ3RoIG1hdGNoZXMKICAgICAgICAgICAgaWYgKHRoaXMuZ2xvYmFsICYmICFtYXRjaFswXS5sZW5ndGggJiYgKHRoaXMubGFzdEluZGV4ID4gbWF0Y2guaW5kZXgpKSB7CiAgICAgICAgICAgICAgICB0aGlzLmxhc3RJbmRleCA9IG1hdGNoLmluZGV4OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICghdGhpcy5nbG9iYWwpIHsKICAgICAgICAgICAgdGhpcy5sYXN0SW5kZXggPSBvcmlnTGFzdEluZGV4OyAvLyBGaXhlcyBJRSwgT3BlcmEgYnVnIChsYXN0IHRlc3RlZCBJRSA5LCBPcGVyYSAxMS42KQogICAgICAgIH0KICAgICAgICByZXR1cm4gbWF0Y2g7CiAgICB9OwoKLyoqCiAqIEZpeGVzIGJyb3dzZXIgYnVncyBpbiB0aGUgbmF0aXZlIGBSZWdFeHAucHJvdG90eXBlLnRlc3RgLiBDYWxsaW5nIGBYUmVnRXhwLmluc3RhbGwoJ25hdGl2ZXMnKWAKICogdXNlcyB0aGlzIHRvIG92ZXJyaWRlIHRoZSBuYXRpdmUgbWV0aG9kLgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBzZWFyY2guCiAqIEByZXR1cm5zIHtCb29sZWFufSBXaGV0aGVyIHRoZSByZWdleCBtYXRjaGVkIHRoZSBwcm92aWRlZCB2YWx1ZS4KICovCiAgICBmaXhlZC50ZXN0ID0gZnVuY3Rpb24gKHN0cikgewogICAgICAgIC8vIERvIHRoaXMgdGhlIGVhc3kgd2F5IDotKQogICAgICAgIHJldHVybiAhIWZpeGVkLmV4ZWMuY2FsbCh0aGlzLCBzdHIpOwogICAgfTsKCi8qKgogKiBBZGRzIG5hbWVkIGNhcHR1cmUgc3VwcG9ydCAod2l0aCBiYWNrcmVmZXJlbmNlcyByZXR1cm5lZCBhcyBgcmVzdWx0Lm5hbWVgKSwgYW5kIGZpeGVzIGJyb3dzZXIKICogYnVncyBpbiB0aGUgbmF0aXZlIGBTdHJpbmcucHJvdG90eXBlLm1hdGNoYC4gQ2FsbGluZyBgWFJlZ0V4cC5pbnN0YWxsKCduYXRpdmVzJylgIHVzZXMgdGhpcyB0bwogKiBvdmVycmlkZSB0aGUgbmF0aXZlIG1ldGhvZC4KICogQHByaXZhdGUKICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4IFJlZ2V4IHRvIHNlYXJjaCB3aXRoLgogKiBAcmV0dXJucyB7QXJyYXl9IElmIGByZWdleGAgdXNlcyBmbGFnIGcsIGFuIGFycmF5IG9mIG1hdGNoIHN0cmluZ3Mgb3IgbnVsbC4gV2l0aG91dCBmbGFnIGcsIHRoZQogKiAgIHJlc3VsdCBvZiBjYWxsaW5nIGByZWdleC5leGVjKHRoaXMpYC4KICovCiAgICBmaXhlZC5tYXRjaCA9IGZ1bmN0aW9uIChyZWdleCkgewogICAgICAgIGlmICghc2VsZi5pc1JlZ0V4cChyZWdleCkpIHsKICAgICAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKHJlZ2V4KTsgLy8gVXNlIG5hdGl2ZSBgUmVnRXhwYAogICAgICAgIH0gZWxzZSBpZiAocmVnZXguZ2xvYmFsKSB7CiAgICAgICAgICAgIHZhciByZXN1bHQgPSBuYXRpdi5tYXRjaC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICByZWdleC5sYXN0SW5kZXggPSAwOyAvLyBGaXhlcyBJRSBidWcKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpeGVkLmV4ZWMuY2FsbChyZWdleCwgdGhpcyk7CiAgICB9OwoKLyoqCiAqIEFkZHMgc3VwcG9ydCBmb3IgYCR7bn1gIHRva2VucyBmb3IgbmFtZWQgYW5kIG51bWJlcmVkIGJhY2tyZWZlcmVuY2VzIGluIHJlcGxhY2VtZW50IHRleHQsIGFuZAogKiBwcm92aWRlcyBuYW1lZCBiYWNrcmVmZXJlbmNlcyB0byByZXBsYWNlbWVudCBmdW5jdGlvbnMgYXMgYGFyZ3VtZW50c1swXS5uYW1lYC4gQWxzbyBmaXhlcwogKiBicm93c2VyIGJ1Z3MgaW4gcmVwbGFjZW1lbnQgdGV4dCBzeW50YXggd2hlbiBwZXJmb3JtaW5nIGEgcmVwbGFjZW1lbnQgdXNpbmcgYSBub25yZWdleCBzZWFyY2gKICogdmFsdWUsIGFuZCB0aGUgdmFsdWUgb2YgYSByZXBsYWNlbWVudCByZWdleCdzIGBsYXN0SW5kZXhgIHByb3BlcnR5IGR1cmluZyByZXBsYWNlbWVudCBpdGVyYXRpb25zCiAqIGFuZCB1cG9uIGNvbXBsZXRpb24uIE5vdGUgdGhhdCB0aGlzIGRvZXNuJ3Qgc3VwcG9ydCBTcGlkZXJNb25rZXkncyBwcm9wcmlldGFyeSB0aGlyZCAoYGZsYWdzYCkKICogYXJndW1lbnQuIENhbGxpbmcgYFhSZWdFeHAuaW5zdGFsbCgnbmF0aXZlcycpYCB1c2VzIHRoaXMgdG8gb3ZlcnJpZGUgdGhlIG5hdGl2ZSBtZXRob2QuIFVzZSB2aWEKICogYFhSZWdFeHAucmVwbGFjZWAgd2l0aG91dCBvdmVycmlkaW5nIG5hdGl2ZXMuCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7UmVnRXhwfFN0cmluZ30gc2VhcmNoIFNlYXJjaCBwYXR0ZXJuIHRvIGJlIHJlcGxhY2VkLgogKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gcmVwbGFjZW1lbnQgUmVwbGFjZW1lbnQgc3RyaW5nIG9yIGEgZnVuY3Rpb24gaW52b2tlZCB0byBjcmVhdGUgaXQuCiAqIEByZXR1cm5zIHtTdHJpbmd9IE5ldyBzdHJpbmcgd2l0aCBvbmUgb3IgYWxsIG1hdGNoZXMgcmVwbGFjZWQuCiAqLwogICAgZml4ZWQucmVwbGFjZSA9IGZ1bmN0aW9uIChzZWFyY2gsIHJlcGxhY2VtZW50KSB7CiAgICAgICAgdmFyIGlzUmVnZXggPSBzZWxmLmlzUmVnRXhwKHNlYXJjaCksIGNhcHR1cmVOYW1lcywgcmVzdWx0LCBzdHIsIG9yaWdMYXN0SW5kZXg7CiAgICAgICAgaWYgKGlzUmVnZXgpIHsKICAgICAgICAgICAgaWYgKHNlYXJjaC54cmVnZXhwKSB7CiAgICAgICAgICAgICAgICBjYXB0dXJlTmFtZXMgPSBzZWFyY2gueHJlZ2V4cC5jYXB0dXJlTmFtZXM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFzZWFyY2guZ2xvYmFsKSB7CiAgICAgICAgICAgICAgICBvcmlnTGFzdEluZGV4ID0gc2VhcmNoLmxhc3RJbmRleDsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNlYXJjaCArPSAiIjsKICAgICAgICB9CiAgICAgICAgaWYgKGlzVHlwZShyZXBsYWNlbWVudCwgImZ1bmN0aW9uIikpIHsKICAgICAgICAgICAgcmVzdWx0ID0gbmF0aXYucmVwbGFjZS5jYWxsKFN0cmluZyh0aGlzKSwgc2VhcmNoLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cywgaTsKICAgICAgICAgICAgICAgIGlmIChjYXB0dXJlTmFtZXMpIHsKICAgICAgICAgICAgICAgICAgICAvLyBDaGFuZ2UgdGhlIGBhcmd1bWVudHNbMF1gIHN0cmluZyBwcmltaXRpdmUgdG8gYSBgU3RyaW5nYCBvYmplY3QgdGhhdCBjYW4gc3RvcmUgcHJvcGVydGllcwogICAgICAgICAgICAgICAgICAgIGFyZ3NbMF0gPSBuZXcgU3RyaW5nKGFyZ3NbMF0pOwogICAgICAgICAgICAgICAgICAgIC8vIFN0b3JlIG5hbWVkIGJhY2tyZWZlcmVuY2VzIG9uIHRoZSBmaXJzdCBhcmd1bWVudAogICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjYXB0dXJlTmFtZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNhcHR1cmVOYW1lc1tpXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1swXVtjYXB0dXJlTmFtZXNbaV1dID0gYXJnc1tpICsgMV07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgYGxhc3RJbmRleGAgYmVmb3JlIGNhbGxpbmcgYHJlcGxhY2VtZW50YC4KICAgICAgICAgICAgICAgIC8vIEZpeGVzIElFLCBDaHJvbWUsIEZpcmVmb3gsIFNhZmFyaSBidWcgKGxhc3QgdGVzdGVkIElFIDksIENocm9tZSAxNywgRmlyZWZveCAxMSwgU2FmYXJpIDUuMSkKICAgICAgICAgICAgICAgIGlmIChpc1JlZ2V4ICYmIHNlYXJjaC5nbG9iYWwpIHsKICAgICAgICAgICAgICAgICAgICBzZWFyY2gubGFzdEluZGV4ID0gYXJnc1thcmdzLmxlbmd0aCAtIDJdICsgYXJnc1swXS5sZW5ndGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gcmVwbGFjZW1lbnQuYXBwbHkobnVsbCwgYXJncyk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN0ciA9IFN0cmluZyh0aGlzKTsgLy8gRW5zdXJlIGBhcmdzW2FyZ3MubGVuZ3RoIC0gMV1gIHdpbGwgYmUgYSBzdHJpbmcgd2hlbiBnaXZlbiBub25zdHJpbmcgYHRoaXNgCiAgICAgICAgICAgIHJlc3VsdCA9IG5hdGl2LnJlcGxhY2UuY2FsbChzdHIsIHNlYXJjaCwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7IC8vIEtlZXAgdGhpcyBmdW5jdGlvbidzIGBhcmd1bWVudHNgIGF2YWlsYWJsZSB0aHJvdWdoIGNsb3N1cmUKICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdi5yZXBsYWNlLmNhbGwoU3RyaW5nKHJlcGxhY2VtZW50KSwgcmVwbGFjZW1lbnRUb2tlbiwgZnVuY3Rpb24gKCQwLCAkMSwgJDIpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbjsKICAgICAgICAgICAgICAgICAgICAvLyBOYW1lZCBvciBudW1iZXJlZCBiYWNrcmVmZXJlbmNlIHdpdGggY3VybHkgYnJhY2tldHMKICAgICAgICAgICAgICAgICAgICBpZiAoJDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogWFJlZ0V4cCBiZWhhdmlvciBmb3IgYCR7bn1gOgogICAgICAgICAgICAgICAgICAgICAgICAgKiAxLiBCYWNrcmVmZXJlbmNlIHRvIG51bWJlcmVkIGNhcHR1cmUsIHdoZXJlIGBuYCBpcyAxKyBkaWdpdHMuIGAwYCwgYDAwYCwgZXRjLiBpcyB0aGUgZW50aXJlIG1hdGNoLgogICAgICAgICAgICAgICAgICAgICAgICAgKiAyLiBCYWNrcmVmZXJlbmNlIHRvIG5hbWVkIGNhcHR1cmUgYG5gLCBpZiBpdCBleGlzdHMgYW5kIGlzIG5vdCBhIG51bWJlciBvdmVycmlkZGVuIGJ5IG51bWJlcmVkIGNhcHR1cmUuCiAgICAgICAgICAgICAgICAgICAgICAgICAqIDMuIE90aGVyd2lzZSwgaXQncyBhbiBlcnJvci4KICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgIG4gPSArJDE7IC8vIFR5cGUtY29udmVydDsgZHJvcCBsZWFkaW5nIHplcm9zCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuIDw9IGFyZ3MubGVuZ3RoIC0gMykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFyZ3Nbbl0gfHwgIiI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgbiA9IGNhcHR1cmVOYW1lcyA/IGxhc3RJbmRleE9mKGNhcHR1cmVOYW1lcywgJDEpIDogLTE7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCJiYWNrcmVmZXJlbmNlIHRvIHVuZGVmaW5lZCBncm91cCAiICsgJDApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhcmdzW24gKyAxXSB8fCAiIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gRWxzZSwgc3BlY2lhbCB2YXJpYWJsZSBvciBudW1iZXJlZCBiYWNrcmVmZXJlbmNlICh3aXRob3V0IGN1cmx5IGJyYWNrZXRzKQogICAgICAgICAgICAgICAgICAgIGlmICgkMiA9PT0gIiQiKSByZXR1cm4gIiQiOwogICAgICAgICAgICAgICAgICAgIGlmICgkMiA9PT0gIiYiIHx8ICskMiA9PT0gMCkgcmV0dXJuIGFyZ3NbMF07IC8vICQmLCAkMCAobm90IGZvbGxvd2VkIGJ5IDEtOSksICQwMAogICAgICAgICAgICAgICAgICAgIGlmICgkMiA9PT0gImAiKSByZXR1cm4gYXJnc1thcmdzLmxlbmd0aCAtIDFdLnNsaWNlKDAsIGFyZ3NbYXJncy5sZW5ndGggLSAyXSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCQyID09PSAiJyIpIHJldHVybiBhcmdzW2FyZ3MubGVuZ3RoIC0gMV0uc2xpY2UoYXJnc1thcmdzLmxlbmd0aCAtIDJdICsgYXJnc1swXS5sZW5ndGgpOwogICAgICAgICAgICAgICAgICAgIC8vIEVsc2UsIG51bWJlcmVkIGJhY2tyZWZlcmVuY2UgKHdpdGhvdXQgY3VybHkgYnJhY2tldHMpCiAgICAgICAgICAgICAgICAgICAgJDIgPSArJDI7IC8vIFR5cGUtY29udmVydDsgZHJvcCBsZWFkaW5nIHplcm8KICAgICAgICAgICAgICAgICAgICAvKiBYUmVnRXhwIGJlaGF2aW9yOgogICAgICAgICAgICAgICAgICAgICAqIC0gQmFja3JlZmVyZW5jZXMgd2l0aG91dCBjdXJseSBicmFja2V0cyBlbmQgYWZ0ZXIgMSBvciAyIGRpZ2l0cy4gVXNlIGAkey4ufWAgZm9yIG1vcmUgZGlnaXRzLgogICAgICAgICAgICAgICAgICAgICAqIC0gYCQxYCBpcyBhbiBlcnJvciBpZiB0aGVyZSBhcmUgbm8gY2FwdHVyaW5nIGdyb3Vwcy4KICAgICAgICAgICAgICAgICAgICAgKiAtIGAkMTBgIGlzIGFuIGVycm9yIGlmIHRoZXJlIGFyZSBsZXNzIHRoYW4gMTAgY2FwdHVyaW5nIGdyb3Vwcy4gVXNlIGAkezF9MGAgaW5zdGVhZC4KICAgICAgICAgICAgICAgICAgICAgKiAtIGAkMDFgIGlzIGVxdWl2YWxlbnQgdG8gYCQxYCBpZiBhIGNhcHR1cmluZyBncm91cCBleGlzdHMsIG90aGVyd2lzZSBpdCdzIGFuIGVycm9yLgogICAgICAgICAgICAgICAgICAgICAqIC0gYCQwYCAobm90IGZvbGxvd2VkIGJ5IDEtOSksIGAkMDBgLCBhbmQgYCQmYCBhcmUgdGhlIGVudGlyZSBtYXRjaC4KICAgICAgICAgICAgICAgICAgICAgKiBOYXRpdmUgYmVoYXZpb3IsIGZvciBjb21wYXJpc29uOgogICAgICAgICAgICAgICAgICAgICAqIC0gQmFja3JlZmVyZW5jZXMgZW5kIGFmdGVyIDEgb3IgMiBkaWdpdHMuIENhbm5vdCB1c2UgYmFja3JlZmVyZW5jZSB0byBjYXB0dXJpbmcgZ3JvdXAgMTAwKy4KICAgICAgICAgICAgICAgICAgICAgKiAtIGAkMWAgaXMgYSBsaXRlcmFsIGAkMWAgaWYgdGhlcmUgYXJlIG5vIGNhcHR1cmluZyBncm91cHMuCiAgICAgICAgICAgICAgICAgICAgICogLSBgJDEwYCBpcyBgJDFgIGZvbGxvd2VkIGJ5IGEgbGl0ZXJhbCBgMGAgaWYgdGhlcmUgYXJlIGxlc3MgdGhhbiAxMCBjYXB0dXJpbmcgZ3JvdXBzLgogICAgICAgICAgICAgICAgICAgICAqIC0gYCQwMWAgaXMgZXF1aXZhbGVudCB0byBgJDFgIGlmIGEgY2FwdHVyaW5nIGdyb3VwIGV4aXN0cywgb3RoZXJ3aXNlIGl0J3MgYSBsaXRlcmFsIGAkMDFgLgogICAgICAgICAgICAgICAgICAgICAqIC0gYCQwYCBpcyBhIGxpdGVyYWwgYCQwYC4gYCQmYCBpcyB0aGUgZW50aXJlIG1hdGNoLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGlmICghaXNOYU4oJDIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkMiA+IGFyZ3MubGVuZ3RoIC0gMykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCJiYWNrcmVmZXJlbmNlIHRvIHVuZGVmaW5lZCBncm91cCAiICsgJDApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhcmdzWyQyXSB8fCAiIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCJpbnZhbGlkIHRva2VuICIgKyAkMCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGlmIChpc1JlZ2V4KSB7CiAgICAgICAgICAgIGlmIChzZWFyY2guZ2xvYmFsKSB7CiAgICAgICAgICAgICAgICBzZWFyY2gubGFzdEluZGV4ID0gMDsgLy8gRml4ZXMgSUUsIFNhZmFyaSBidWcgKGxhc3QgdGVzdGVkIElFIDksIFNhZmFyaSA1LjEpCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2gubGFzdEluZGV4ID0gb3JpZ0xhc3RJbmRleDsgLy8gRml4ZXMgSUUsIE9wZXJhIGJ1ZyAobGFzdCB0ZXN0ZWQgSUUgOSwgT3BlcmEgMTEuNikKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfTsKCi8qKgogKiBGaXhlcyBicm93c2VyIGJ1Z3MgaW4gdGhlIG5hdGl2ZSBgU3RyaW5nLnByb3RvdHlwZS5zcGxpdGAuIENhbGxpbmcgYFhSZWdFeHAuaW5zdGFsbCgnbmF0aXZlcycpYAogKiB1c2VzIHRoaXMgdG8gb3ZlcnJpZGUgdGhlIG5hdGl2ZSBtZXRob2QuIFVzZSB2aWEgYFhSZWdFeHAuc3BsaXRgIHdpdGhvdXQgb3ZlcnJpZGluZyBuYXRpdmVzLgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge1JlZ0V4cHxTdHJpbmd9IHNlcGFyYXRvciBSZWdleCBvciBzdHJpbmcgdG8gdXNlIGZvciBzZXBhcmF0aW5nIHRoZSBzdHJpbmcuCiAqIEBwYXJhbSB7TnVtYmVyfSBbbGltaXRdIE1heGltdW0gbnVtYmVyIG9mIGl0ZW1zIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3VsdCBhcnJheS4KICogQHJldHVybnMge0FycmF5fSBBcnJheSBvZiBzdWJzdHJpbmdzLgogKi8KICAgIGZpeGVkLnNwbGl0ID0gZnVuY3Rpb24gKHNlcGFyYXRvciwgbGltaXQpIHsKICAgICAgICBpZiAoIXNlbGYuaXNSZWdFeHAoc2VwYXJhdG9yKSkgewogICAgICAgICAgICByZXR1cm4gbmF0aXYuc3BsaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gdXNlIGZhc3RlciBuYXRpdmUgbWV0aG9kCiAgICAgICAgfQogICAgICAgIHZhciBzdHIgPSBTdHJpbmcodGhpcyksCiAgICAgICAgICAgIG9yaWdMYXN0SW5kZXggPSBzZXBhcmF0b3IubGFzdEluZGV4LAogICAgICAgICAgICBvdXRwdXQgPSBbXSwKICAgICAgICAgICAgbGFzdExhc3RJbmRleCA9IDAsCiAgICAgICAgICAgIGxhc3RMZW5ndGg7CiAgICAgICAgLyogVmFsdWVzIGZvciBgbGltaXRgLCBwZXIgdGhlIHNwZWM6CiAgICAgICAgICogSWYgdW5kZWZpbmVkOiBwb3coMiwzMikgLSAxCiAgICAgICAgICogSWYgMCwgSW5maW5pdHksIG9yIE5hTjogMAogICAgICAgICAqIElmIHBvc2l0aXZlIG51bWJlcjogbGltaXQgPSBmbG9vcihsaW1pdCk7IGlmIChsaW1pdCA+PSBwb3coMiwzMikpIGxpbWl0IC09IHBvdygyLDMyKTsKICAgICAgICAgKiBJZiBuZWdhdGl2ZSBudW1iZXI6IHBvdygyLDMyKSAtIGZsb29yKGFicyhsaW1pdCkpCiAgICAgICAgICogSWYgb3RoZXI6IFR5cGUtY29udmVydCwgdGhlbiB1c2UgdGhlIGFib3ZlIHJ1bGVzCiAgICAgICAgICovCiAgICAgICAgbGltaXQgPSAobGltaXQgPT09IHVuZGVmID8gLTEgOiBsaW1pdCkgPj4+IDA7CiAgICAgICAgc2VsZi5mb3JFYWNoKHN0ciwgc2VwYXJhdG9yLCBmdW5jdGlvbiAobWF0Y2gpIHsKICAgICAgICAgICAgaWYgKChtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aCkgPiBsYXN0TGFzdEluZGV4KSB7IC8vICE9IGBpZiAobWF0Y2hbMF0ubGVuZ3RoKWAKICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKHN0ci5zbGljZShsYXN0TGFzdEluZGV4LCBtYXRjaC5pbmRleCkpOwogICAgICAgICAgICAgICAgaWYgKG1hdGNoLmxlbmd0aCA+IDEgJiYgbWF0Y2guaW5kZXggPCBzdHIubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkob3V0cHV0LCBtYXRjaC5zbGljZSgxKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsYXN0TGVuZ3RoID0gbWF0Y2hbMF0ubGVuZ3RoOwogICAgICAgICAgICAgICAgbGFzdExhc3RJbmRleCA9IG1hdGNoLmluZGV4ICsgbGFzdExlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIGlmIChsYXN0TGFzdEluZGV4ID09PSBzdHIubGVuZ3RoKSB7CiAgICAgICAgICAgIGlmICghbmF0aXYudGVzdC5jYWxsKHNlcGFyYXRvciwgIiIpIHx8IGxhc3RMZW5ndGgpIHsKICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKCIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG91dHB1dC5wdXNoKHN0ci5zbGljZShsYXN0TGFzdEluZGV4KSk7CiAgICAgICAgfQogICAgICAgIHNlcGFyYXRvci5sYXN0SW5kZXggPSBvcmlnTGFzdEluZGV4OwogICAgICAgIHJldHVybiBvdXRwdXQubGVuZ3RoID4gbGltaXQgPyBvdXRwdXQuc2xpY2UoMCwgbGltaXQpIDogb3V0cHV0OwogICAgfTsKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogIEJ1aWx0LWluIHRva2VucwogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgovLyBTaG9ydGN1dAogICAgYWRkID0gYWRkVG9rZW4ub247CgovKiBMZXR0ZXIgaWRlbnRpdHkgZXNjYXBlcyB0aGF0IG5hdGl2ZWx5IG1hdGNoIGxpdGVyYWwgY2hhcmFjdGVyczogXHAsIFxQLCBldGMuCiAqIFNob3VsZCBiZSBTeW50YXhFcnJvcnMgYnV0IGFyZSBhbGxvd2VkIGluIHdlYiByZWFsaXR5LiBYUmVnRXhwIG1ha2VzIHRoZW0gZXJyb3JzIGZvciBjcm9zcy0KICogYnJvd3NlciBjb25zaXN0ZW5jeSBhbmQgdG8gcmVzZXJ2ZSB0aGVpciBzeW50YXgsIGJ1dCBsZXRzIHRoZW0gYmUgc3VwZXJzZWRlZCBieSBYUmVnRXhwIGFkZG9ucy4KICovCiAgICBhZGQoL1xcKFtBQkNFLVJUVVZYWVphZWctbW9wcXl6XXxjKD8hW0EtWmEtel0pfHUoPyFbXGRBLUZhLWZdezR9KXx4KD8hW1xkQS1GYS1mXXsyfSkpLywKICAgICAgICBmdW5jdGlvbiAobWF0Y2gsIHNjb3BlKSB7CiAgICAgICAgICAgIC8vIFxCIGlzIGFsbG93ZWQgaW4gZGVmYXVsdCBzY29wZSBvbmx5CiAgICAgICAgICAgIGlmIChtYXRjaFsxXSA9PT0gIkIiICYmIHNjb3BlID09PSBkZWZhdWx0U2NvcGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaFswXTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImludmFsaWQgZXNjYXBlICIgKyBtYXRjaFswXSk7CiAgICAgICAgfSwKICAgICAgICB7c2NvcGU6ICJhbGwifSk7CgovKiBFbXB0eSBjaGFyYWN0ZXIgY2xhc3M6IFtdIG9yIFteXQogKiBGaXhlcyBhIGNyaXRpY2FsIGNyb3NzLWJyb3dzZXIgc3ludGF4IGluY29uc2lzdGVuY3kuIFVubGVzcyB0aGlzIGlzIHN0YW5kYXJkaXplZCAocGVyIHRoZSBzcGVjKSwKICogcmVnZXggc3ludGF4IGNhbid0IGJlIGFjY3VyYXRlbHkgcGFyc2VkIGJlY2F1c2UgY2hhcmFjdGVyIGNsYXNzIGVuZGluZ3MgY2FuJ3QgYmUgZGV0ZXJtaW5lZC4KICovCiAgICBhZGQoL1xbKFxePyldLywKICAgICAgICBmdW5jdGlvbiAobWF0Y2gpIHsKICAgICAgICAgICAgLy8gRm9yIGNyb3NzLWJyb3dzZXIgY29tcGF0aWJpbGl0eSB3aXRoIEVTMywgY29udmVydCBbXSB0byBcYlxCIGFuZCBbXl0gdG8gW1xzXFNdLgogICAgICAgICAgICAvLyAoPyEpIHNob3VsZCB3b3JrIGxpa2UgXGJcQiwgYnV0IGlzIHVucmVsaWFibGUgaW4gRmlyZWZveAogICAgICAgICAgICByZXR1cm4gbWF0Y2hbMV0gPyAiW1xcc1xcU10iIDogIlxcYlxcQiI7CiAgICAgICAgfSk7CgovKiBDb21tZW50IHBhdHRlcm46ICg/IyApCiAqIElubGluZSBjb21tZW50cyBhcmUgYW4gYWx0ZXJuYXRpdmUgdG8gdGhlIGxpbmUgY29tbWVudHMgYWxsb3dlZCBpbiBmcmVlLXNwYWNpbmcgbW9kZSAoZmxhZyB4KS4KICovCiAgICBhZGQoLyg/OlwoXD8jW14pXSpcKSkrLywKICAgICAgICBmdW5jdGlvbiAobWF0Y2gpIHsKICAgICAgICAgICAgLy8gS2VlcCB0b2tlbnMgc2VwYXJhdGVkIHVubGVzcyB0aGUgZm9sbG93aW5nIHRva2VuIGlzIGEgcXVhbnRpZmllcgogICAgICAgICAgICByZXR1cm4gbmF0aXYudGVzdC5jYWxsKHF1YW50aWZpZXIsIG1hdGNoLmlucHV0LnNsaWNlKG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoKSkgPyAiIiA6ICIoPzopIjsKICAgICAgICB9KTsKCi8qIE5hbWVkIGJhY2tyZWZlcmVuY2U6IFxrPG5hbWU+CiAqIEJhY2tyZWZlcmVuY2UgbmFtZXMgY2FuIHVzZSB0aGUgY2hhcmFjdGVycyBBLVosIGEteiwgMC05LCBfLCBhbmQgJCBvbmx5LgogKi8KICAgIGFkZCgvXFxrPChbXHckXSspPi8sCiAgICAgICAgZnVuY3Rpb24gKG1hdGNoKSB7CiAgICAgICAgICAgIHZhciBpbmRleCA9IGlzTmFOKG1hdGNoWzFdKSA/IChsYXN0SW5kZXhPZih0aGlzLmNhcHR1cmVOYW1lcywgbWF0Y2hbMV0pICsgMSkgOiArbWF0Y2hbMV0sCiAgICAgICAgICAgICAgICBlbmRJbmRleCA9IG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoOwogICAgICAgICAgICBpZiAoIWluZGV4IHx8IGluZGV4ID4gdGhpcy5jYXB0dXJlTmFtZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImJhY2tyZWZlcmVuY2UgdG8gdW5kZWZpbmVkIGdyb3VwICIgKyBtYXRjaFswXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gS2VlcCBiYWNrcmVmZXJlbmNlcyBzZXBhcmF0ZSBmcm9tIHN1YnNlcXVlbnQgbGl0ZXJhbCBudW1iZXJzCiAgICAgICAgICAgIHJldHVybiAiXFwiICsgaW5kZXggKyAoCiAgICAgICAgICAgICAgICBlbmRJbmRleCA9PT0gbWF0Y2guaW5wdXQubGVuZ3RoIHx8IGlzTmFOKG1hdGNoLmlucHV0LmNoYXJBdChlbmRJbmRleCkpID8gIiIgOiAiKD86KSIKICAgICAgICAgICAgKTsKICAgICAgICB9KTsKCi8qIFdoaXRlc3BhY2UgYW5kIGxpbmUgY29tbWVudHMsIGluIGZyZWUtc3BhY2luZyBtb2RlIChha2EgZXh0ZW5kZWQgbW9kZSwgZmxhZyB4KSBvbmx5LgogKi8KICAgIGFkZCgvKD86XHMrfCMuKikrLywKICAgICAgICBmdW5jdGlvbiAobWF0Y2gpIHsKICAgICAgICAgICAgLy8gS2VlcCB0b2tlbnMgc2VwYXJhdGVkIHVubGVzcyB0aGUgZm9sbG93aW5nIHRva2VuIGlzIGEgcXVhbnRpZmllcgogICAgICAgICAgICByZXR1cm4gbmF0aXYudGVzdC5jYWxsKHF1YW50aWZpZXIsIG1hdGNoLmlucHV0LnNsaWNlKG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoKSkgPyAiIiA6ICIoPzopIjsKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgdHJpZ2dlcjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaGFzRmxhZygieCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBjdXN0b21GbGFnczogIngiCiAgICAgICAgfSk7CgovKiBEb3QsIGluIGRvdGFsbCBtb2RlIChha2Egc2luZ2xlbGluZSBtb2RlLCBmbGFnIHMpIG9ubHkuCiAqLwogICAgYWRkKC9cLi8sCiAgICAgICAgZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gIltcXHNcXFNdIjsKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgdHJpZ2dlcjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaGFzRmxhZygicyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBjdXN0b21GbGFnczogInMiCiAgICAgICAgfSk7CgovKiBOYW1lZCBjYXB0dXJpbmcgZ3JvdXA7IG1hdGNoIHRoZSBvcGVuaW5nIGRlbGltaXRlciBvbmx5OiAoPzxuYW1lPgogKiBDYXB0dXJlIG5hbWVzIGNhbiB1c2UgdGhlIGNoYXJhY3RlcnMgQS1aLCBhLXosIDAtOSwgXywgYW5kICQgb25seS4gTmFtZXMgY2FuJ3QgYmUgaW50ZWdlcnMuCiAqIFN1cHBvcnRzIFB5dGhvbi1zdHlsZSAoP1A8bmFtZT4gYXMgYW4gYWx0ZXJuYXRlIHN5bnRheCB0byBhdm9pZCBpc3N1ZXMgaW4gcmVjZW50IE9wZXJhICh3aGljaAogKiBuYXRpdmVseSBzdXBwb3J0cyB0aGUgUHl0aG9uLXN0eWxlIHN5bnRheCkuIE90aGVyd2lzZSwgWFJlZ0V4cCBtaWdodCB0cmVhdCBudW1iZXJlZAogKiBiYWNrcmVmZXJlbmNlcyB0byBQeXRob24tc3R5bGUgbmFtZWQgY2FwdHVyZSBhcyBvY3RhbHMuCiAqLwogICAgYWRkKC9cKFw/UD88KFtcdyRdKyk+LywKICAgICAgICBmdW5jdGlvbiAobWF0Y2gpIHsKICAgICAgICAgICAgaWYgKCFpc05hTihtYXRjaFsxXSkpIHsKICAgICAgICAgICAgICAgIC8vIEF2b2lkIGluY29ycmVjdCBsb29rdXBzLCBzaW5jZSBuYW1lZCBiYWNrcmVmZXJlbmNlcyBhcmUgYWRkZWQgdG8gbWF0Y2ggYXJyYXlzCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImNhbid0IHVzZSBpbnRlZ2VyIGFzIGNhcHR1cmUgbmFtZSAiICsgbWF0Y2hbMF0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuY2FwdHVyZU5hbWVzLnB1c2gobWF0Y2hbMV0pOwogICAgICAgICAgICB0aGlzLmhhc05hbWVkQ2FwdHVyZSA9IHRydWU7CiAgICAgICAgICAgIHJldHVybiAiKCI7CiAgICAgICAgfSk7CgovKiBOdW1iZXJlZCBiYWNrcmVmZXJlbmNlIG9yIG9jdGFsLCBwbHVzIGFueSBmb2xsb3dpbmcgZGlnaXRzOiBcMCwgXDExLCBldGMuCiAqIE9jdGFscyBleGNlcHQgXDAgbm90IGZvbGxvd2VkIGJ5IDAtOSBhbmQgYmFja3JlZmVyZW5jZXMgdG8gdW5vcGVuZWQgY2FwdHVyZSBncm91cHMgdGhyb3cgYW4KICogZXJyb3IuIE90aGVyIG1hdGNoZXMgYXJlIHJldHVybmVkIHVuYWx0ZXJlZC4gSUUgPD0gOCBkb2Vzbid0IHN1cHBvcnQgYmFja3JlZmVyZW5jZXMgZ3JlYXRlciB0aGFuCiAqIFw5OSBpbiByZWdleCBzeW50YXguCiAqLwogICAgYWRkKC9cXChcZCspLywKICAgICAgICBmdW5jdGlvbiAobWF0Y2gsIHNjb3BlKSB7CiAgICAgICAgICAgIGlmICghKHNjb3BlID09PSBkZWZhdWx0U2NvcGUgJiYgL15bMS05XS8udGVzdChtYXRjaFsxXSkgJiYgK21hdGNoWzFdIDw9IHRoaXMuY2FwdHVyZU5hbWVzLmxlbmd0aCkgJiYKICAgICAgICAgICAgICAgICAgICBtYXRjaFsxXSAhPT0gIjAiKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImNhbid0IHVzZSBvY3RhbCBlc2NhcGUgb3IgYmFja3JlZmVyZW5jZSB0byB1bmRlZmluZWQgZ3JvdXAgIiArIG1hdGNoWzBdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbWF0Y2hbMF07CiAgICAgICAgfSwKICAgICAgICB7c2NvcGU6ICJhbGwifSk7CgovKiBDYXB0dXJpbmcgZ3JvdXA7IG1hdGNoIHRoZSBvcGVuaW5nIHBhcmVudGhlc2lzIG9ubHkuCiAqIFJlcXVpcmVkIGZvciBzdXBwb3J0IG9mIG5hbWVkIGNhcHR1cmluZyBncm91cHMuIEFsc28gYWRkcyBleHBsaWNpdCBjYXB0dXJlIG1vZGUgKGZsYWcgbikuCiAqLwogICAgYWRkKC9cKCg/IVw/KS8sCiAgICAgICAgZnVuY3Rpb24gKCkgewogICAgICAgICAgICBpZiAodGhpcy5oYXNGbGFnKCJuIikpIHsKICAgICAgICAgICAgICAgIHJldHVybiAiKD86IjsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLmNhcHR1cmVOYW1lcy5wdXNoKG51bGwpOwogICAgICAgICAgICByZXR1cm4gIigiOwogICAgICAgIH0sCiAgICAgICAge2N1c3RvbUZsYWdzOiAibiJ9KTsKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogIEV4cG9zZSBYUmVnRXhwCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCi8vIEZvciBDb21tb25KUyBlbnZpcm9tZW50cwogICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAidW5kZWZpbmVkIikgewogICAgICAgIGV4cG9ydHMuWFJlZ0V4cCA9IHNlbGY7CiAgICB9CgogICAgcmV0dXJuIHNlbGY7Cgp9KCkpOwoKCi8qKioqKiB1bmljb2RlLWJhc2UuanMgKioqKiovCgovKiEKICogWFJlZ0V4cCBVbmljb2RlIEJhc2UgdjEuMC4wCiAqIChjKSAyMDA4LTIwMTIgU3RldmVuIExldml0aGFuIDxodHRwOi8veHJlZ2V4cC5jb20vPgogKiBNSVQgTGljZW5zZQogKiBVc2VzIFVuaWNvZGUgNi4xIDxodHRwOi8vdW5pY29kZS5vcmcvPgogKi8KCi8qKgogKiBBZGRzIHN1cHBvcnQgZm9yIHRoZSBgXHB7TH1gIG9yIGBccHtMZXR0ZXJ9YCBVbmljb2RlIGNhdGVnb3J5LiBBZGRvbiBwYWNrYWdlcyBmb3Igb3RoZXIgVW5pY29kZQogKiBjYXRlZ29yaWVzLCBzY3JpcHRzLCBibG9ja3MsIGFuZCBwcm9wZXJ0aWVzIGFyZSBhdmFpbGFibGUgc2VwYXJhdGVseS4gQWxsIFVuaWNvZGUgdG9rZW5zIGNhbiBiZQogKiBpbnZlcnRlZCB1c2luZyBgXFB7Li59YCBvciBgXHB7Xi4ufWAuIFRva2VuIG5hbWVzIGFyZSBjYXNlIGluc2Vuc2l0aXZlLCBhbmQgYW55IHNwYWNlcywgaHlwaGVucywKICogYW5kIHVuZGVyc2NvcmVzIGFyZSBpZ25vcmVkLgogKiBAcmVxdWlyZXMgWFJlZ0V4cAogKi8KKGZ1bmN0aW9uIChYUmVnRXhwKSB7CiAgICAidXNlIHN0cmljdCI7CgogICAgdmFyIHVuaWNvZGUgPSB7fTsKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogIFByaXZhdGUgaGVscGVyIGZ1bmN0aW9ucwogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgovLyBHZW5lcmF0ZXMgYSBzdGFuZGFyZGl6ZWQgdG9rZW4gbmFtZSAobG93ZXJjYXNlLCB3aXRoIGh5cGhlbnMsIHNwYWNlcywgYW5kIHVuZGVyc2NvcmVzIHJlbW92ZWQpCiAgICBmdW5jdGlvbiBzbHVnKG5hbWUpIHsKICAgICAgICByZXR1cm4gbmFtZS5yZXBsYWNlKC9bLSBfXSsvZywgIiIpLnRvTG93ZXJDYXNlKCk7CiAgICB9CgovLyBFeHBhbmRzIGEgbGlzdCBvZiBVbmljb2RlIGNvZGUgcG9pbnRzIGFuZCByYW5nZXMgdG8gYmUgdXNhYmxlIGluIGEgcmVnZXggY2hhcmFjdGVyIGNsYXNzCiAgICBmdW5jdGlvbiBleHBhbmQoc3RyKSB7CiAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKC9cd3s0fS9nLCAiXFx1JCYiKTsKICAgIH0KCi8vIEFkZHMgbGVhZGluZyB6ZXJvcyBpZiBzaG9ydGVyIHRoYW4gZm91ciBjaGFyYWN0ZXJzCiAgICBmdW5jdGlvbiBwYWQ0KHN0cikgewogICAgICAgIHdoaWxlIChzdHIubGVuZ3RoIDwgNCkgewogICAgICAgICAgICBzdHIgPSAiMCIgKyBzdHI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHI7CiAgICB9CgovLyBDb252ZXJ0cyBhIGhleGFkZWNpbWFsIG51bWJlciB0byBkZWNpbWFsCiAgICBmdW5jdGlvbiBkZWMoaGV4KSB7CiAgICAgICAgcmV0dXJuIHBhcnNlSW50KGhleCwgMTYpOwogICAgfQoKLy8gQ29udmVydHMgYSBkZWNpbWFsIG51bWJlciB0byBoZXhhZGVjaW1hbAogICAgZnVuY3Rpb24gaGV4KGRlYykgewogICAgICAgIHJldHVybiBwYXJzZUludChkZWMsIDEwKS50b1N0cmluZygxNik7CiAgICB9CgovLyBJbnZlcnRzIGEgbGlzdCBvZiBVbmljb2RlIGNvZGUgcG9pbnRzIGFuZCByYW5nZXMKICAgIGZ1bmN0aW9uIGludmVydChyYW5nZSkgewogICAgICAgIHZhciBvdXRwdXQgPSBbXSwKICAgICAgICAgICAgbGFzdEVuZCA9IC0xLAogICAgICAgICAgICBzdGFydDsKICAgICAgICBYUmVnRXhwLmZvckVhY2gocmFuZ2UsIC9cXHUoXHd7NH0pKD86LVxcdShcd3s0fSkpPy8sIGZ1bmN0aW9uIChtKSB7CiAgICAgICAgICAgIHN0YXJ0ID0gZGVjKG1bMV0pOwogICAgICAgICAgICBpZiAoc3RhcnQgPiAobGFzdEVuZCArIDEpKSB7CiAgICAgICAgICAgICAgICBvdXRwdXQucHVzaCgiXFx1IiArIHBhZDQoaGV4KGxhc3RFbmQgKyAxKSkpOwogICAgICAgICAgICAgICAgaWYgKHN0YXJ0ID4gKGxhc3RFbmQgKyAyKSkgewogICAgICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKCItXFx1IiArIHBhZDQoaGV4KHN0YXJ0IC0gMSkpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBsYXN0RW5kID0gZGVjKG1bMl0gfHwgbVsxXSk7CiAgICAgICAgfSk7CiAgICAgICAgaWYgKGxhc3RFbmQgPCAweEZGRkYpIHsKICAgICAgICAgICAgb3V0cHV0LnB1c2goIlxcdSIgKyBwYWQ0KGhleChsYXN0RW5kICsgMSkpKTsKICAgICAgICAgICAgaWYgKGxhc3RFbmQgPCAweEZGRkUpIHsKICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKCItXFx1RkZGRiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBvdXRwdXQuam9pbigiIik7CiAgICB9CgovLyBHZW5lcmF0ZXMgYW4gaW52ZXJ0ZWQgdG9rZW4gb24gZmlyc3QgdXNlCiAgICBmdW5jdGlvbiBjYWNoZUludmVyc2lvbihpdGVtKSB7CiAgICAgICAgcmV0dXJuIHVuaWNvZGVbIl4iICsgaXRlbV0gfHwgKHVuaWNvZGVbIl4iICsgaXRlbV0gPSBpbnZlcnQodW5pY29kZVtpdGVtXSkpOwogICAgfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiAgQ29yZSBmdW5jdGlvbmFsaXR5CiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCiAgICBYUmVnRXhwLmluc3RhbGwoImV4dGVuc2liaWxpdHkiKTsKCi8qKgogKiBBZGRzIHRvIHRoZSBsaXN0IG9mIFVuaWNvZGUgcHJvcGVydGllcyB0aGF0IFhSZWdFeHAgcmVnZXhlcyBjYW4gbWF0Y2ggdmlhIFxwey4ufSBvciBcUHsuLn0uCiAqIEBtZW1iZXJPZiBYUmVnRXhwCiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrIE5hbWVkIHNldHMgb2YgVW5pY29kZSBjb2RlIHBvaW50cyBhbmQgcmFuZ2VzLgogKiBAcGFyYW0ge09iamVjdH0gW2FsaWFzZXNdIEFsaWFzZXMgZm9yIHRoZSBwcmltYXJ5IHRva2VuIG5hbWVzLgogKiBAZXhhbXBsZQogKgogKiBYUmVnRXhwLmFkZFVuaWNvZGVQYWNrYWdlKHsKICogICBYRGlnaXQ6ICcwMDMwLTAwMzkwMDQxLTAwNDYwMDYxLTAwNjYnIC8vIDAtOUEtRmEtZgogKiB9LCB7CiAqICAgWERpZ2l0OiAnSGV4YWRlY2ltYWwnCiAqIH0pOwogKi8KICAgIFhSZWdFeHAuYWRkVW5pY29kZVBhY2thZ2UgPSBmdW5jdGlvbiAocGFjaywgYWxpYXNlcykgewogICAgICAgIHZhciBwOwogICAgICAgIGlmICghWFJlZ0V4cC5pc0luc3RhbGxlZCgiZXh0ZW5zaWJpbGl0eSIpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiZXh0ZW5zaWJpbGl0eSBtdXN0IGJlIGluc3RhbGxlZCBiZWZvcmUgYWRkaW5nIFVuaWNvZGUgcGFja2FnZXMiKTsKICAgICAgICB9CiAgICAgICAgaWYgKHBhY2spIHsKICAgICAgICAgICAgZm9yIChwIGluIHBhY2spIHsKICAgICAgICAgICAgICAgIGlmIChwYWNrLmhhc093blByb3BlcnR5KHApKSB7CiAgICAgICAgICAgICAgICAgICAgdW5pY29kZVtzbHVnKHApXSA9IGV4cGFuZChwYWNrW3BdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoYWxpYXNlcykgewogICAgICAgICAgICBmb3IgKHAgaW4gYWxpYXNlcykgewogICAgICAgICAgICAgICAgaWYgKGFsaWFzZXMuaGFzT3duUHJvcGVydHkocCkpIHsKICAgICAgICAgICAgICAgICAgICB1bmljb2RlW3NsdWcoYWxpYXNlc1twXSldID0gdW5pY29kZVtzbHVnKHApXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgovKiBBZGRzIGRhdGEgZm9yIHRoZSBVbmljb2RlIGBMZXR0ZXJgIGNhdGVnb3J5LiBBZGRvbiBwYWNrYWdlcyBpbmNsdWRlIG90aGVyIGNhdGVnb3JpZXMsIHNjcmlwdHMsCiAqIGJsb2NrcywgYW5kIHByb3BlcnRpZXMuCiAqLwogICAgWFJlZ0V4cC5hZGRVbmljb2RlUGFja2FnZSh7CiAgICAgICAgTDogIjAwNDEtMDA1QTAwNjEtMDA3QTAwQUEwMEI1MDBCQTAwQzAtMDBENjAwRDgtMDBGNjAwRjgtMDJDMTAyQzYtMDJEMTAyRTAtMDJFNDAyRUMwMkVFMDM3MC0wMzc0MDM3NjAzNzcwMzdBLTAzN0QwMzg2MDM4OC0wMzhBMDM4QzAzOEUtMDNBMTAzQTMtMDNGNTAzRjctMDQ4MTA0OEEtMDUyNzA1MzEtMDU1NjA1NTkwNTYxLTA1ODcwNUQwLTA1RUEwNUYwLTA1RjIwNjIwLTA2NEEwNjZFMDY2RjA2NzEtMDZEMzA2RDUwNkU1MDZFNjA2RUUwNkVGMDZGQS0wNkZDMDZGRjA3MTAwNzEyLTA3MkYwNzRELTA3QTUwN0IxMDdDQS0wN0VBMDdGNDA3RjUwN0ZBMDgwMC0wODE1MDgxQTA4MjQwODI4MDg0MC0wODU4MDhBMDA4QTItMDhBQzA5MDQtMDkzOTA5M0QwOTUwMDk1OC0wOTYxMDk3MS0wOTc3MDk3OS0wOTdGMDk4NS0wOThDMDk4RjA5OTAwOTkzLTA5QTgwOUFBLTA5QjAwOUIyMDlCNi0wOUI5MDlCRDA5Q0UwOURDMDlERDA5REYtMDlFMTA5RjAwOUYxMEEwNS0wQTBBMEEwRjBBMTAwQTEzLTBBMjgwQTJBLTBBMzAwQTMyMEEzMzBBMzUwQTM2MEEzODBBMzkwQTU5LTBBNUMwQTVFMEE3Mi0wQTc0MEE4NS0wQThEMEE4Ri0wQTkxMEE5My0wQUE4MEFBQS0wQUIwMEFCMjBBQjMwQUI1LTBBQjkwQUJEMEFEMDBBRTAwQUUxMEIwNS0wQjBDMEIwRjBCMTAwQjEzLTBCMjgwQjJBLTBCMzAwQjMyMEIzMzBCMzUtMEIzOTBCM0QwQjVDMEI1RDBCNUYtMEI2MTBCNzEwQjgzMEI4NS0wQjhBMEI4RS0wQjkwMEI5Mi0wQjk1MEI5OTBCOUEwQjlDMEI5RTBCOUYwQkEzMEJBNDBCQTgtMEJBQTBCQUUtMEJCOTBCRDAwQzA1LTBDMEMwQzBFLTBDMTAwQzEyLTBDMjgwQzJBLTBDMzMwQzM1LTBDMzkwQzNEMEM1ODBDNTkwQzYwMEM2MTBDODUtMEM4QzBDOEUtMEM5MDBDOTItMENBODBDQUEtMENCMzBDQjUtMENCOTBDQkQwQ0RFMENFMDBDRTEwQ0YxMENGMjBEMDUtMEQwQzBEMEUtMEQxMDBEMTItMEQzQTBEM0QwRDRFMEQ2MDBENjEwRDdBLTBEN0YwRDg1LTBEOTYwRDlBLTBEQjEwREIzLTBEQkIwREJEMERDMC0wREM2MEUwMS0wRTMwMEUzMjBFMzMwRTQwLTBFNDYwRTgxMEU4MjBFODQwRTg3MEU4ODBFOEEwRThEMEU5NC0wRTk3MEU5OS0wRTlGMEVBMS0wRUEzMEVBNTBFQTcwRUFBMEVBQjBFQUQtMEVCMDBFQjIwRUIzMEVCRDBFQzAtMEVDNDBFQzYwRURDLTBFREYwRjAwMEY0MC0wRjQ3MEY0OS0wRjZDMEY4OC0wRjhDMTAwMC0xMDJBMTAzRjEwNTAtMTA1NTEwNUEtMTA1RDEwNjExMDY1MTA2NjEwNkUtMTA3MDEwNzUtMTA4MTEwOEUxMEEwLTEwQzUxMEM3MTBDRDEwRDAtMTBGQTEwRkMtMTI0ODEyNEEtMTI0RDEyNTAtMTI1NjEyNTgxMjVBLTEyNUQxMjYwLTEyODgxMjhBLTEyOEQxMjkwLTEyQjAxMkIyLTEyQjUxMkI4LTEyQkUxMkMwMTJDMi0xMkM1MTJDOC0xMkQ2MTJEOC0xMzEwMTMxMi0xMzE1MTMxOC0xMzVBMTM4MC0xMzhGMTNBMC0xM0Y0MTQwMS0xNjZDMTY2Ri0xNjdGMTY4MS0xNjlBMTZBMC0xNkVBMTcwMC0xNzBDMTcwRS0xNzExMTcyMC0xNzMxMTc0MC0xNzUxMTc2MC0xNzZDMTc2RS0xNzcwMTc4MC0xN0IzMTdENzE3REMxODIwLTE4NzcxODgwLTE4QTgxOEFBMThCMC0xOEY1MTkwMC0xOTFDMTk1MC0xOTZEMTk3MC0xOTc0MTk4MC0xOUFCMTlDMS0xOUM3MUEwMC0xQTE2MUEyMC0xQTU0MUFBNzFCMDUtMUIzMzFCNDUtMUI0QjFCODMtMUJBMDFCQUUxQkFGMUJCQS0xQkU1MUMwMC0xQzIzMUM0RC0xQzRGMUM1QS0xQzdEMUNFOS0xQ0VDMUNFRS0xQ0YxMUNGNTFDRjYxRDAwLTFEQkYxRTAwLTFGMTUxRjE4LTFGMUQxRjIwLTFGNDUxRjQ4LTFGNEQxRjUwLTFGNTcxRjU5MUY1QjFGNUQxRjVGLTFGN0QxRjgwLTFGQjQxRkI2LTFGQkMxRkJFMUZDMi0xRkM0MUZDNi0xRkNDMUZEMC0xRkQzMUZENi0xRkRCMUZFMC0xRkVDMUZGMi0xRkY0MUZGNi0xRkZDMjA3MTIwN0YyMDkwLTIwOUMyMTAyMjEwNzIxMEEtMjExMzIxMTUyMTE5LTIxMUQyMTI0MjEyNjIxMjgyMTJBLTIxMkQyMTJGLTIxMzkyMTNDLTIxM0YyMTQ1LTIxNDkyMTRFMjE4MzIxODQyQzAwLTJDMkUyQzMwLTJDNUUyQzYwLTJDRTQyQ0VCLTJDRUUyQ0YyMkNGMzJEMDAtMkQyNTJEMjcyRDJEMkQzMC0yRDY3MkQ2RjJEODAtMkQ5NjJEQTAtMkRBNjJEQTgtMkRBRTJEQjAtMkRCNjJEQjgtMkRCRTJEQzAtMkRDNjJEQzgtMkRDRTJERDAtMkRENjJERDgtMkRERTJFMkYzMDA1MzAwNjMwMzEtMzAzNTMwM0IzMDNDMzA0MS0zMDk2MzA5RC0zMDlGMzBBMS0zMEZBMzBGQy0zMEZGMzEwNS0zMTJEMzEzMS0zMThFMzFBMC0zMUJBMzFGMC0zMUZGMzQwMC00REI1NEUwMC05RkNDQTAwMC1BNDhDQTREMC1BNEZEQTUwMC1BNjBDQTYxMC1BNjFGQTYyQUE2MkJBNjQwLUE2NkVBNjdGLUE2OTdBNkEwLUE2RTVBNzE3LUE3MUZBNzIyLUE3ODhBNzhCLUE3OEVBNzkwLUE3OTNBN0EwLUE3QUFBN0Y4LUE4MDFBODAzLUE4MDVBODA3LUE4MEFBODBDLUE4MjJBODQwLUE4NzNBODgyLUE4QjNBOEYyLUE4RjdBOEZCQTkwQS1BOTI1QTkzMC1BOTQ2QTk2MC1BOTdDQTk4NC1BOUIyQTlDRkFBMDAtQUEyOEFBNDAtQUE0MkFBNDQtQUE0QkFBNjAtQUE3NkFBN0FBQTgwLUFBQUZBQUIxQUFCNUFBQjZBQUI5LUFBQkRBQUMwQUFDMkFBREItQUFEREFBRTAtQUFFQUFBRjItQUFGNEFCMDEtQUIwNkFCMDktQUIwRUFCMTEtQUIxNkFCMjAtQUIyNkFCMjgtQUIyRUFCQzAtQUJFMkFDMDAtRDdBM0Q3QjAtRDdDNkQ3Q0ItRDdGQkY5MDAtRkE2REZBNzAtRkFEOUZCMDAtRkIwNkZCMTMtRkIxN0ZCMURGQjFGLUZCMjhGQjJBLUZCMzZGQjM4LUZCM0NGQjNFRkI0MEZCNDFGQjQzRkI0NEZCNDYtRkJCMUZCRDMtRkQzREZENTAtRkQ4RkZEOTItRkRDN0ZERjAtRkRGQkZFNzAtRkU3NEZFNzYtRkVGQ0ZGMjEtRkYzQUZGNDEtRkY1QUZGNjYtRkZCRUZGQzItRkZDN0ZGQ0EtRkZDRkZGRDItRkZEN0ZGREEtRkZEQyIKICAgIH0sIHsKICAgICAgICBMOiAiTGV0dGVyIgogICAgfSk7CgovKiBBZGRzIFVuaWNvZGUgcHJvcGVydHkgc3ludGF4IHRvIFhSZWdFeHA6IFxwey4ufSwgXFB7Li59LCBccHteLi59CiAqLwogICAgWFJlZ0V4cC5hZGRUb2tlbigKICAgICAgICAvXFwoW3BQXSl7KFxePykoW159XSopfS8sCiAgICAgICAgZnVuY3Rpb24gKG1hdGNoLCBzY29wZSkgewogICAgICAgICAgICB2YXIgaW52ID0gKG1hdGNoWzFdID09PSAiUCIgfHwgbWF0Y2hbMl0pID8gIl4iIDogIiIsCiAgICAgICAgICAgICAgICBpdGVtID0gc2x1ZyhtYXRjaFszXSk7CiAgICAgICAgICAgIC8vIFRoZSBkb3VibGUgbmVnYXRpdmUgXFB7Xi4ufSBpcyBpbnZhbGlkCiAgICAgICAgICAgIGlmIChtYXRjaFsxXSA9PT0gIlAiICYmIG1hdGNoWzJdKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImludmFsaWQgZG91YmxlIG5lZ2F0aW9uIFxcUHteIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCF1bmljb2RlLmhhc093blByb3BlcnR5KGl0ZW0pKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImludmFsaWQgb3IgdW5rbm93biBVbmljb2RlIHByb3BlcnR5ICIgKyBtYXRjaFswXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHNjb3BlID09PSAiY2xhc3MiID8KICAgICAgICAgICAgICAgICAgICAoaW52ID8gY2FjaGVJbnZlcnNpb24oaXRlbSkgOiB1bmljb2RlW2l0ZW1dKSA6CiAgICAgICAgICAgICAgICAgICAgIlsiICsgaW52ICsgdW5pY29kZVtpdGVtXSArICJdIjsKICAgICAgICB9LAogICAgICAgIHtzY29wZTogImFsbCJ9CiAgICApOwoKfShYUmVnRXhwKSk7CgoKLyoqKioqIHVuaWNvZGUtY2F0ZWdvcmllcy5qcyAqKioqKi8KCi8qIQogKiBYUmVnRXhwIFVuaWNvZGUgQ2F0ZWdvcmllcyB2MS4yLjAKICogKGMpIDIwMTAtMjAxMiBTdGV2ZW4gTGV2aXRoYW4gPGh0dHA6Ly94cmVnZXhwLmNvbS8+CiAqIE1JVCBMaWNlbnNlCiAqIFVzZXMgVW5pY29kZSA2LjEgPGh0dHA6Ly91bmljb2RlLm9yZy8+CiAqLwoKLyoqCiAqIEFkZHMgc3VwcG9ydCBmb3IgYWxsIFVuaWNvZGUgY2F0ZWdvcmllcyAoYWthIHByb3BlcnRpZXMpIEUuZy4sIGBccHtMdX1gIG9yCiAqIGBccHtVcHBlcmNhc2UgTGV0dGVyfWAuIFRva2VuIG5hbWVzIGFyZSBjYXNlIGluc2Vuc2l0aXZlLCBhbmQgYW55IHNwYWNlcywgaHlwaGVucywgYW5kCiAqIHVuZGVyc2NvcmVzIGFyZSBpZ25vcmVkLgogKiBAcmVxdWlyZXMgWFJlZ0V4cCwgWFJlZ0V4cCBVbmljb2RlIEJhc2UKICovCihmdW5jdGlvbiAoWFJlZ0V4cCkgewogICAgInVzZSBzdHJpY3QiOwoKICAgIGlmICghWFJlZ0V4cC5hZGRVbmljb2RlUGFja2FnZSkgewogICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigiVW5pY29kZSBCYXNlIG11c3QgYmUgbG9hZGVkIGJlZm9yZSBVbmljb2RlIENhdGVnb3JpZXMiKTsKICAgIH0KCiAgICBYUmVnRXhwLmluc3RhbGwoImV4dGVuc2liaWxpdHkiKTsKCiAgICBYUmVnRXhwLmFkZFVuaWNvZGVQYWNrYWdlKHsKICAgICAgICAvL0w6ICIiLCAvLyBJbmNsdWRlZCBpbiB0aGUgVW5pY29kZSBCYXNlIGFkZG9uCiAgICAgICAgTGw6ICIwMDYxLTAwN0EwMEI1MDBERi0wMEY2MDBGOC0wMEZGMDEwMTAxMDMwMTA1MDEwNzAxMDkwMTBCMDEwRDAxMEYwMTExMDExMzAxMTUwMTE3MDExOTAxMUIwMTFEMDExRjAxMjEwMTIzMDEyNTAxMjcwMTI5MDEyQjAxMkQwMTJGMDEzMTAxMzMwMTM1MDEzNzAxMzgwMTNBMDEzQzAxM0UwMTQwMDE0MjAxNDQwMTQ2MDE0ODAxNDkwMTRCMDE0RDAxNEYwMTUxMDE1MzAxNTUwMTU3MDE1OTAxNUIwMTVEMDE1RjAxNjEwMTYzMDE2NTAxNjcwMTY5MDE2QjAxNkQwMTZGMDE3MTAxNzMwMTc1MDE3NzAxN0EwMTdDMDE3RS0wMTgwMDE4MzAxODUwMTg4MDE4QzAxOEQwMTkyMDE5NTAxOTktMDE5QjAxOUUwMUExMDFBMzAxQTUwMUE4MDFBQTAxQUIwMUFEMDFCMDAxQjQwMUI2MDFCOTAxQkEwMUJELTAxQkYwMUM2MDFDOTAxQ0MwMUNFMDFEMDAxRDIwMUQ0MDFENjAxRDgwMURBMDFEQzAxREQwMURGMDFFMTAxRTMwMUU1MDFFNzAxRTkwMUVCMDFFRDAxRUYwMUYwMDFGMzAxRjUwMUY5MDFGQjAxRkQwMUZGMDIwMTAyMDMwMjA1MDIwNzAyMDkwMjBCMDIwRDAyMEYwMjExMDIxMzAyMTUwMjE3MDIxOTAyMUIwMjFEMDIxRjAyMjEwMjIzMDIyNTAyMjcwMjI5MDIyQjAyMkQwMjJGMDIzMTAyMzMtMDIzOTAyM0MwMjNGMDI0MDAyNDIwMjQ3MDI0OTAyNEIwMjREMDI0Ri0wMjkzMDI5NS0wMkFGMDM3MTAzNzMwMzc3MDM3Qi0wMzdEMDM5MDAzQUMtMDNDRTAzRDAwM0QxMDNENS0wM0Q3MDNEOTAzREIwM0REMDNERjAzRTEwM0UzMDNFNTAzRTcwM0U5MDNFQjAzRUQwM0VGLTAzRjMwM0Y1MDNGODAzRkIwM0ZDMDQzMC0wNDVGMDQ2MTA0NjMwNDY1MDQ2NzA0NjkwNDZCMDQ2RDA0NkYwNDcxMDQ3MzA0NzUwNDc3MDQ3OTA0N0IwNDdEMDQ3RjA0ODEwNDhCMDQ4RDA0OEYwNDkxMDQ5MzA0OTUwNDk3MDQ5OTA0OUIwNDlEMDQ5RjA0QTEwNEEzMDRBNTA0QTcwNEE5MDRBQjA0QUQwNEFGMDRCMTA0QjMwNEI1MDRCNzA0QjkwNEJCMDRCRDA0QkYwNEMyMDRDNDA0QzYwNEM4MDRDQTA0Q0MwNENFMDRDRjA0RDEwNEQzMDRENTA0RDcwNEQ5MDREQjA0REQwNERGMDRFMTA0RTMwNEU1MDRFNzA0RTkwNEVCMDRFRDA0RUYwNEYxMDRGMzA0RjUwNEY3MDRGOTA0RkIwNEZEMDRGRjA1MDEwNTAzMDUwNTA1MDcwNTA5MDUwQjA1MEQwNTBGMDUxMTA1MTMwNTE1MDUxNzA1MTkwNTFCMDUxRDA1MUYwNTIxMDUyMzA1MjUwNTI3MDU2MS0wNTg3MUQwMC0xRDJCMUQ2Qi0xRDc3MUQ3OS0xRDlBMUUwMTFFMDMxRTA1MUUwNzFFMDkxRTBCMUUwRDFFMEYxRTExMUUxMzFFMTUxRTE3MUUxOTFFMUIxRTFEMUUxRjFFMjExRTIzMUUyNTFFMjcxRTI5MUUyQjFFMkQxRTJGMUUzMTFFMzMxRTM1MUUzNzFFMzkxRTNCMUUzRDFFM0YxRTQxMUU0MzFFNDUxRTQ3MUU0OTFFNEIxRTREMUU0RjFFNTExRTUzMUU1NTFFNTcxRTU5MUU1QjFFNUQxRTVGMUU2MTFFNjMxRTY1MUU2NzFFNjkxRTZCMUU2RDFFNkYxRTcxMUU3MzFFNzUxRTc3MUU3OTFFN0IxRTdEMUU3RjFFODExRTgzMUU4NTFFODcxRTg5MUU4QjFFOEQxRThGMUU5MTFFOTMxRTk1LTFFOUQxRTlGMUVBMTFFQTMxRUE1MUVBNzFFQTkxRUFCMUVBRDFFQUYxRUIxMUVCMzFFQjUxRUI3MUVCOTFFQkIxRUJEMUVCRjFFQzExRUMzMUVDNTFFQzcxRUM5MUVDQjFFQ0QxRUNGMUVEMTFFRDMxRUQ1MUVENzFFRDkxRURCMUVERDFFREYxRUUxMUVFMzFFRTUxRUU3MUVFOTFFRUIxRUVEMUVFRjFFRjExRUYzMUVGNTFFRjcxRUY5MUVGQjFFRkQxRUZGLTFGMDcxRjEwLTFGMTUxRjIwLTFGMjcxRjMwLTFGMzcxRjQwLTFGNDUxRjUwLTFGNTcxRjYwLTFGNjcxRjcwLTFGN0QxRjgwLTFGODcxRjkwLTFGOTcxRkEwLTFGQTcxRkIwLTFGQjQxRkI2MUZCNzFGQkUxRkMyLTFGQzQxRkM2MUZDNzFGRDAtMUZEMzFGRDYxRkQ3MUZFMC0xRkU3MUZGMi0xRkY0MUZGNjFGRjcyMTBBMjEwRTIxMEYyMTEzMjEyRjIxMzQyMTM5MjEzQzIxM0QyMTQ2LTIxNDkyMTRFMjE4NDJDMzAtMkM1RTJDNjEyQzY1MkM2NjJDNjgyQzZBMkM2QzJDNzEyQzczMkM3NDJDNzYtMkM3QjJDODEyQzgzMkM4NTJDODcyQzg5MkM4QjJDOEQyQzhGMkM5MTJDOTMyQzk1MkM5NzJDOTkyQzlCMkM5RDJDOUYyQ0ExMkNBMzJDQTUyQ0E3MkNBOTJDQUIyQ0FEMkNBRjJDQjEyQ0IzMkNCNTJDQjcyQ0I5MkNCQjJDQkQyQ0JGMkNDMTJDQzMyQ0M1MkNDNzJDQzkyQ0NCMkNDRDJDQ0YyQ0QxMkNEMzJDRDUyQ0Q3MkNEOTJDREIyQ0REMkNERjJDRTEyQ0UzMkNFNDJDRUMyQ0VFMkNGMzJEMDAtMkQyNTJEMjcyRDJEQTY0MUE2NDNBNjQ1QTY0N0E2NDlBNjRCQTY0REE2NEZBNjUxQTY1M0E2NTVBNjU3QTY1OUE2NUJBNjVEQTY1RkE2NjFBNjYzQTY2NUE2NjdBNjY5QTY2QkE2NkRBNjgxQTY4M0E2ODVBNjg3QTY4OUE2OEJBNjhEQTY4RkE2OTFBNjkzQTY5NUE2OTdBNzIzQTcyNUE3MjdBNzI5QTcyQkE3MkRBNzJGLUE3MzFBNzMzQTczNUE3MzdBNzM5QTczQkE3M0RBNzNGQTc0MUE3NDNBNzQ1QTc0N0E3NDlBNzRCQTc0REE3NEZBNzUxQTc1M0E3NTVBNzU3QTc1OUE3NUJBNzVEQTc1RkE3NjFBNzYzQTc2NUE3NjdBNzY5QTc2QkE3NkRBNzZGQTc3MS1BNzc4QTc3QUE3N0NBNzdGQTc4MUE3ODNBNzg1QTc4N0E3OENBNzhFQTc5MUE3OTNBN0ExQTdBM0E3QTVBN0E3QTdBOUE3RkFGQjAwLUZCMDZGQjEzLUZCMTdGRjQxLUZGNUEiLAogICAgICAgIEx1OiAiMDA0MS0wMDVBMDBDMC0wMEQ2MDBEOC0wMERFMDEwMDAxMDIwMTA0MDEwNjAxMDgwMTBBMDEwQzAxMEUwMTEwMDExMjAxMTQwMTE2MDExODAxMUEwMTFDMDExRTAxMjAwMTIyMDEyNDAxMjYwMTI4MDEyQTAxMkMwMTJFMDEzMDAxMzIwMTM0MDEzNjAxMzkwMTNCMDEzRDAxM0YwMTQxMDE0MzAxNDUwMTQ3MDE0QTAxNEMwMTRFMDE1MDAxNTIwMTU0MDE1NjAxNTgwMTVBMDE1QzAxNUUwMTYwMDE2MjAxNjQwMTY2MDE2ODAxNkEwMTZDMDE2RTAxNzAwMTcyMDE3NDAxNzYwMTc4MDE3OTAxN0IwMTdEMDE4MTAxODIwMTg0MDE4NjAxODcwMTg5LTAxOEIwMThFLTAxOTEwMTkzMDE5NDAxOTYtMDE5ODAxOUMwMTlEMDE5RjAxQTAwMUEyMDFBNDAxQTYwMUE3MDFBOTAxQUMwMUFFMDFBRjAxQjEtMDFCMzAxQjUwMUI3MDFCODAxQkMwMUM0MDFDNzAxQ0EwMUNEMDFDRjAxRDEwMUQzMDFENTAxRDcwMUQ5MDFEQjAxREUwMUUwMDFFMjAxRTQwMUU2MDFFODAxRUEwMUVDMDFFRTAxRjEwMUY0MDFGNi0wMUY4MDFGQTAxRkMwMUZFMDIwMDAyMDIwMjA0MDIwNjAyMDgwMjBBMDIwQzAyMEUwMjEwMDIxMjAyMTQwMjE2MDIxODAyMUEwMjFDMDIxRTAyMjAwMjIyMDIyNDAyMjYwMjI4MDIyQTAyMkMwMjJFMDIzMDAyMzIwMjNBMDIzQjAyM0QwMjNFMDI0MTAyNDMtMDI0NjAyNDgwMjRBMDI0QzAyNEUwMzcwMDM3MjAzNzYwMzg2MDM4OC0wMzhBMDM4QzAzOEUwMzhGMDM5MS0wM0ExMDNBMy0wM0FCMDNDRjAzRDItMDNENDAzRDgwM0RBMDNEQzAzREUwM0UwMDNFMjAzRTQwM0U2MDNFODAzRUEwM0VDMDNFRTAzRjQwM0Y3MDNGOTAzRkEwM0ZELTA0MkYwNDYwMDQ2MjA0NjQwNDY2MDQ2ODA0NkEwNDZDMDQ2RTA0NzAwNDcyMDQ3NDA0NzYwNDc4MDQ3QTA0N0MwNDdFMDQ4MDA0OEEwNDhDMDQ4RTA0OTAwNDkyMDQ5NDA0OTYwNDk4MDQ5QTA0OUMwNDlFMDRBMDA0QTIwNEE0MDRBNjA0QTgwNEFBMDRBQzA0QUUwNEIwMDRCMjA0QjQwNEI2MDRCODA0QkEwNEJDMDRCRTA0QzAwNEMxMDRDMzA0QzUwNEM3MDRDOTA0Q0IwNENEMDREMDA0RDIwNEQ0MDRENjA0RDgwNERBMDREQzA0REUwNEUwMDRFMjA0RTQwNEU2MDRFODA0RUEwNEVDMDRFRTA0RjAwNEYyMDRGNDA0RjYwNEY4MDRGQTA0RkMwNEZFMDUwMDA1MDIwNTA0MDUwNjA1MDgwNTBBMDUwQzA1MEUwNTEwMDUxMjA1MTQwNTE2MDUxODA1MUEwNTFDMDUxRTA1MjAwNTIyMDUyNDA1MjYwNTMxLTA1NTYxMEEwLTEwQzUxMEM3MTBDRDFFMDAxRTAyMUUwNDFFMDYxRTA4MUUwQTFFMEMxRTBFMUUxMDFFMTIxRTE0MUUxNjFFMTgxRTFBMUUxQzFFMUUxRTIwMUUyMjFFMjQxRTI2MUUyODFFMkExRTJDMUUyRTFFMzAxRTMyMUUzNDFFMzYxRTM4MUUzQTFFM0MxRTNFMUU0MDFFNDIxRTQ0MUU0NjFFNDgxRTRBMUU0QzFFNEUxRTUwMUU1MjFFNTQxRTU2MUU1ODFFNUExRTVDMUU1RTFFNjAxRTYyMUU2NDFFNjYxRTY4MUU2QTFFNkMxRTZFMUU3MDFFNzIxRTc0MUU3NjFFNzgxRTdBMUU3QzFFN0UxRTgwMUU4MjFFODQxRTg2MUU4ODFFOEExRThDMUU4RTFFOTAxRTkyMUU5NDFFOUUxRUEwMUVBMjFFQTQxRUE2MUVBODFFQUExRUFDMUVBRTFFQjAxRUIyMUVCNDFFQjYxRUI4MUVCQTFFQkMxRUJFMUVDMDFFQzIxRUM0MUVDNjFFQzgxRUNBMUVDQzFFQ0UxRUQwMUVEMjFFRDQxRUQ2MUVEODFFREExRURDMUVERTFFRTAxRUUyMUVFNDFFRTYxRUU4MUVFQTFFRUMxRUVFMUVGMDFFRjIxRUY0MUVGNjFFRjgxRUZBMUVGQzFFRkUxRjA4LTFGMEYxRjE4LTFGMUQxRjI4LTFGMkYxRjM4LTFGM0YxRjQ4LTFGNEQxRjU5MUY1QjFGNUQxRjVGMUY2OC0xRjZGMUZCOC0xRkJCMUZDOC0xRkNCMUZEOC0xRkRCMUZFOC0xRkVDMUZGOC0xRkZCMjEwMjIxMDcyMTBCLTIxMEQyMTEwLTIxMTIyMTE1MjExOS0yMTFEMjEyNDIxMjYyMTI4MjEyQS0yMTJEMjEzMC0yMTMzMjEzRTIxM0YyMTQ1MjE4MzJDMDAtMkMyRTJDNjAyQzYyLTJDNjQyQzY3MkM2OTJDNkIyQzZELTJDNzAyQzcyMkM3NTJDN0UtMkM4MDJDODIyQzg0MkM4NjJDODgyQzhBMkM4QzJDOEUyQzkwMkM5MjJDOTQyQzk2MkM5ODJDOUEyQzlDMkM5RTJDQTAyQ0EyMkNBNDJDQTYyQ0E4MkNBQTJDQUMyQ0FFMkNCMDJDQjIyQ0I0MkNCNjJDQjgyQ0JBMkNCQzJDQkUyQ0MwMkNDMjJDQzQyQ0M2MkNDODJDQ0EyQ0NDMkNDRTJDRDAyQ0QyMkNENDJDRDYyQ0Q4MkNEQTJDREMyQ0RFMkNFMDJDRTIyQ0VCMkNFRDJDRjJBNjQwQTY0MkE2NDRBNjQ2QTY0OEE2NEFBNjRDQTY0RUE2NTBBNjUyQTY1NEE2NTZBNjU4QTY1QUE2NUNBNjVFQTY2MEE2NjJBNjY0QTY2NkE2NjhBNjZBQTY2Q0E2ODBBNjgyQTY4NEE2ODZBNjg4QTY4QUE2OENBNjhFQTY5MEE2OTJBNjk0QTY5NkE3MjJBNzI0QTcyNkE3MjhBNzJBQTcyQ0E3MkVBNzMyQTczNEE3MzZBNzM4QTczQUE3M0NBNzNFQTc0MEE3NDJBNzQ0QTc0NkE3NDhBNzRBQTc0Q0E3NEVBNzUwQTc1MkE3NTRBNzU2QTc1OEE3NUFBNzVDQTc1RUE3NjBBNzYyQTc2NEE3NjZBNzY4QTc2QUE3NkNBNzZFQTc3OUE3N0JBNzdEQTc3RUE3ODBBNzgyQTc4NEE3ODZBNzhCQTc4REE3OTBBNzkyQTdBMEE3QTJBN0E0QTdBNkE3QThBN0FBRkYyMS1GRjNBIiwKICAgICAgICBMdDogIjAxQzUwMUM4MDFDQjAxRjIxRjg4LTFGOEYxRjk4LTFGOUYxRkE4LTFGQUYxRkJDMUZDQzFGRkMiLAogICAgICAgIExtOiAiMDJCMC0wMkMxMDJDNi0wMkQxMDJFMC0wMkU0MDJFQzAyRUUwMzc0MDM3QTA1NTkwNjQwMDZFNTA2RTYwN0Y0MDdGNTA3RkEwODFBMDgyNDA4MjgwOTcxMEU0NjBFQzYxMEZDMTdENzE4NDMxQUE3MUM3OC0xQzdEMUQyQy0xRDZBMUQ3ODFEOUItMURCRjIwNzEyMDdGMjA5MC0yMDlDMkM3QzJDN0QyRDZGMkUyRjMwMDUzMDMxLTMwMzUzMDNCMzA5RDMwOUUzMEZDLTMwRkVBMDE1QTRGOC1BNEZEQTYwQ0E2N0ZBNzE3LUE3MUZBNzcwQTc4OEE3RjhBN0Y5QTlDRkFBNzBBQUREQUFGM0FBRjRGRjcwRkY5RUZGOUYiLAogICAgICAgIExvOiAiMDBBQTAwQkEwMUJCMDFDMC0wMUMzMDI5NDA1RDAtMDVFQTA1RjAtMDVGMjA2MjAtMDYzRjA2NDEtMDY0QTA2NkUwNjZGMDY3MS0wNkQzMDZENTA2RUUwNkVGMDZGQS0wNkZDMDZGRjA3MTAwNzEyLTA3MkYwNzRELTA3QTUwN0IxMDdDQS0wN0VBMDgwMC0wODE1MDg0MC0wODU4MDhBMDA4QTItMDhBQzA5MDQtMDkzOTA5M0QwOTUwMDk1OC0wOTYxMDk3Mi0wOTc3MDk3OS0wOTdGMDk4NS0wOThDMDk4RjA5OTAwOTkzLTA5QTgwOUFBLTA5QjAwOUIyMDlCNi0wOUI5MDlCRDA5Q0UwOURDMDlERDA5REYtMDlFMTA5RjAwOUYxMEEwNS0wQTBBMEEwRjBBMTAwQTEzLTBBMjgwQTJBLTBBMzAwQTMyMEEzMzBBMzUwQTM2MEEzODBBMzkwQTU5LTBBNUMwQTVFMEE3Mi0wQTc0MEE4NS0wQThEMEE4Ri0wQTkxMEE5My0wQUE4MEFBQS0wQUIwMEFCMjBBQjMwQUI1LTBBQjkwQUJEMEFEMDBBRTAwQUUxMEIwNS0wQjBDMEIwRjBCMTAwQjEzLTBCMjgwQjJBLTBCMzAwQjMyMEIzMzBCMzUtMEIzOTBCM0QwQjVDMEI1RDBCNUYtMEI2MTBCNzEwQjgzMEI4NS0wQjhBMEI4RS0wQjkwMEI5Mi0wQjk1MEI5OTBCOUEwQjlDMEI5RTBCOUYwQkEzMEJBNDBCQTgtMEJBQTBCQUUtMEJCOTBCRDAwQzA1LTBDMEMwQzBFLTBDMTAwQzEyLTBDMjgwQzJBLTBDMzMwQzM1LTBDMzkwQzNEMEM1ODBDNTkwQzYwMEM2MTBDODUtMEM4QzBDOEUtMEM5MDBDOTItMENBODBDQUEtMENCMzBDQjUtMENCOTBDQkQwQ0RFMENFMDBDRTEwQ0YxMENGMjBEMDUtMEQwQzBEMEUtMEQxMDBEMTItMEQzQTBEM0QwRDRFMEQ2MDBENjEwRDdBLTBEN0YwRDg1LTBEOTYwRDlBLTBEQjEwREIzLTBEQkIwREJEMERDMC0wREM2MEUwMS0wRTMwMEUzMjBFMzMwRTQwLTBFNDUwRTgxMEU4MjBFODQwRTg3MEU4ODBFOEEwRThEMEU5NC0wRTk3MEU5OS0wRTlGMEVBMS0wRUEzMEVBNTBFQTcwRUFBMEVBQjBFQUQtMEVCMDBFQjIwRUIzMEVCRDBFQzAtMEVDNDBFREMtMEVERjBGMDAwRjQwLTBGNDcwRjQ5LTBGNkMwRjg4LTBGOEMxMDAwLTEwMkExMDNGMTA1MC0xMDU1MTA1QS0xMDVEMTA2MTEwNjUxMDY2MTA2RS0xMDcwMTA3NS0xMDgxMTA4RTEwRDAtMTBGQTEwRkQtMTI0ODEyNEEtMTI0RDEyNTAtMTI1NjEyNTgxMjVBLTEyNUQxMjYwLTEyODgxMjhBLTEyOEQxMjkwLTEyQjAxMkIyLTEyQjUxMkI4LTEyQkUxMkMwMTJDMi0xMkM1MTJDOC0xMkQ2MTJEOC0xMzEwMTMxMi0xMzE1MTMxOC0xMzVBMTM4MC0xMzhGMTNBMC0xM0Y0MTQwMS0xNjZDMTY2Ri0xNjdGMTY4MS0xNjlBMTZBMC0xNkVBMTcwMC0xNzBDMTcwRS0xNzExMTcyMC0xNzMxMTc0MC0xNzUxMTc2MC0xNzZDMTc2RS0xNzcwMTc4MC0xN0IzMTdEQzE4MjAtMTg0MjE4NDQtMTg3NzE4ODAtMThBODE4QUExOEIwLTE4RjUxOTAwLTE5MUMxOTUwLTE5NkQxOTcwLTE5NzQxOTgwLTE5QUIxOUMxLTE5QzcxQTAwLTFBMTYxQTIwLTFBNTQxQjA1LTFCMzMxQjQ1LTFCNEIxQjgzLTFCQTAxQkFFMUJBRjFCQkEtMUJFNTFDMDAtMUMyMzFDNEQtMUM0RjFDNUEtMUM3NzFDRTktMUNFQzFDRUUtMUNGMTFDRjUxQ0Y2MjEzNS0yMTM4MkQzMC0yRDY3MkQ4MC0yRDk2MkRBMC0yREE2MkRBOC0yREFFMkRCMC0yREI2MkRCOC0yREJFMkRDMC0yREM2MkRDOC0yRENFMkREMC0yREQ2MkREOC0yRERFMzAwNjMwM0MzMDQxLTMwOTYzMDlGMzBBMS0zMEZBMzBGRjMxMDUtMzEyRDMxMzEtMzE4RTMxQTAtMzFCQTMxRjAtMzFGRjM0MDAtNERCNTRFMDAtOUZDQ0EwMDAtQTAxNEEwMTYtQTQ4Q0E0RDAtQTRGN0E1MDAtQTYwQkE2MTAtQTYxRkE2MkFBNjJCQTY2RUE2QTAtQTZFNUE3RkItQTgwMUE4MDMtQTgwNUE4MDctQTgwQUE4MEMtQTgyMkE4NDAtQTg3M0E4ODItQThCM0E4RjItQThGN0E4RkJBOTBBLUE5MjVBOTMwLUE5NDZBOTYwLUE5N0NBOTg0LUE5QjJBQTAwLUFBMjhBQTQwLUFBNDJBQTQ0LUFBNEJBQTYwLUFBNkZBQTcxLUFBNzZBQTdBQUE4MC1BQUFGQUFCMUFBQjVBQUI2QUFCOS1BQUJEQUFDMEFBQzJBQURCQUFEQ0FBRTAtQUFFQUFBRjJBQjAxLUFCMDZBQjA5LUFCMEVBQjExLUFCMTZBQjIwLUFCMjZBQjI4LUFCMkVBQkMwLUFCRTJBQzAwLUQ3QTNEN0IwLUQ3QzZEN0NCLUQ3RkJGOTAwLUZBNkRGQTcwLUZBRDlGQjFERkIxRi1GQjI4RkIyQS1GQjM2RkIzOC1GQjNDRkIzRUZCNDBGQjQxRkI0M0ZCNDRGQjQ2LUZCQjFGQkQzLUZEM0RGRDUwLUZEOEZGRDkyLUZEQzdGREYwLUZERkJGRTcwLUZFNzRGRTc2LUZFRkNGRjY2LUZGNkZGRjcxLUZGOURGRkEwLUZGQkVGRkMyLUZGQzdGRkNBLUZGQ0ZGRkQyLUZGRDdGRkRBLUZGREMiLAogICAgICAgIE06ICIwMzAwLTAzNkYwNDgzLTA0ODkwNTkxLTA1QkQwNUJGMDVDMTA1QzIwNUM0MDVDNTA1QzcwNjEwLTA2MUEwNjRCLTA2NUYwNjcwMDZENi0wNkRDMDZERi0wNkU0MDZFNzA2RTgwNkVBLTA2RUQwNzExMDczMC0wNzRBMDdBNi0wN0IwMDdFQi0wN0YzMDgxNi0wODE5MDgxQi0wODIzMDgyNS0wODI3MDgyOS0wODJEMDg1OS0wODVCMDhFNC0wOEZFMDkwMC0wOTAzMDkzQS0wOTNDMDkzRS0wOTRGMDk1MS0wOTU3MDk2MjA5NjMwOTgxLTA5ODMwOUJDMDlCRS0wOUM0MDlDNzA5QzgwOUNCLTA5Q0QwOUQ3MDlFMjA5RTMwQTAxLTBBMDMwQTNDMEEzRS0wQTQyMEE0NzBBNDgwQTRCLTBBNEQwQTUxMEE3MDBBNzEwQTc1MEE4MS0wQTgzMEFCQzBBQkUtMEFDNTBBQzctMEFDOTBBQ0ItMEFDRDBBRTIwQUUzMEIwMS0wQjAzMEIzQzBCM0UtMEI0NDBCNDcwQjQ4MEI0Qi0wQjREMEI1NjBCNTcwQjYyMEI2MzBCODIwQkJFLTBCQzIwQkM2LTBCQzgwQkNBLTBCQ0QwQkQ3MEMwMS0wQzAzMEMzRS0wQzQ0MEM0Ni0wQzQ4MEM0QS0wQzREMEM1NTBDNTYwQzYyMEM2MzBDODIwQzgzMENCQzBDQkUtMENDNDBDQzYtMENDODBDQ0EtMENDRDBDRDUwQ0Q2MENFMjBDRTMwRDAyMEQwMzBEM0UtMEQ0NDBENDYtMEQ0ODBENEEtMEQ0RDBENTcwRDYyMEQ2MzBEODIwRDgzMERDQTBEQ0YtMERENDBERDYwREQ4LTBEREYwREYyMERGMzBFMzEwRTM0LTBFM0EwRTQ3LTBFNEUwRUIxMEVCNC0wRUI5MEVCQjBFQkMwRUM4LTBFQ0QwRjE4MEYxOTBGMzUwRjM3MEYzOTBGM0UwRjNGMEY3MS0wRjg0MEY4NjBGODcwRjhELTBGOTcwRjk5LTBGQkMwRkM2MTAyQi0xMDNFMTA1Ni0xMDU5MTA1RS0xMDYwMTA2Mi0xMDY0MTA2Ny0xMDZEMTA3MS0xMDc0MTA4Mi0xMDhEMTA4RjEwOUEtMTA5RDEzNUQtMTM1RjE3MTItMTcxNDE3MzItMTczNDE3NTIxNzUzMTc3MjE3NzMxN0I0LTE3RDMxN0REMTgwQi0xODBEMThBOTE5MjAtMTkyQjE5MzAtMTkzQjE5QjAtMTlDMDE5QzgxOUM5MUExNy0xQTFCMUE1NS0xQTVFMUE2MC0xQTdDMUE3RjFCMDAtMUIwNDFCMzQtMUI0NDFCNkItMUI3MzFCODAtMUI4MjFCQTEtMUJBRDFCRTYtMUJGMzFDMjQtMUMzNzFDRDAtMUNEMjFDRDQtMUNFODFDRUQxQ0YyLTFDRjQxREMwLTFERTYxREZDLTFERkYyMEQwLTIwRjAyQ0VGLTJDRjEyRDdGMkRFMC0yREZGMzAyQS0zMDJGMzA5OTMwOUFBNjZGLUE2NzJBNjc0LUE2N0RBNjlGQTZGMEE2RjFBODAyQTgwNkE4MEJBODIzLUE4MjdBODgwQTg4MUE4QjQtQThDNEE4RTAtQThGMUE5MjYtQTkyREE5NDctQTk1M0E5ODAtQTk4M0E5QjMtQTlDMEFBMjktQUEzNkFBNDNBQTRDQUE0REFBN0JBQUIwQUFCMi1BQUI0QUFCN0FBQjhBQUJFQUFCRkFBQzFBQUVCLUFBRUZBQUY1QUFGNkFCRTMtQUJFQUFCRUNBQkVERkIxRUZFMDAtRkUwRkZFMjAtRkUyNiIsCiAgICAgICAgTW46ICIwMzAwLTAzNkYwNDgzLTA0ODcwNTkxLTA1QkQwNUJGMDVDMTA1QzIwNUM0MDVDNTA1QzcwNjEwLTA2MUEwNjRCLTA2NUYwNjcwMDZENi0wNkRDMDZERi0wNkU0MDZFNzA2RTgwNkVBLTA2RUQwNzExMDczMC0wNzRBMDdBNi0wN0IwMDdFQi0wN0YzMDgxNi0wODE5MDgxQi0wODIzMDgyNS0wODI3MDgyOS0wODJEMDg1OS0wODVCMDhFNC0wOEZFMDkwMC0wOTAyMDkzQTA5M0MwOTQxLTA5NDgwOTREMDk1MS0wOTU3MDk2MjA5NjMwOTgxMDlCQzA5QzEtMDlDNDA5Q0QwOUUyMDlFMzBBMDEwQTAyMEEzQzBBNDEwQTQyMEE0NzBBNDgwQTRCLTBBNEQwQTUxMEE3MDBBNzEwQTc1MEE4MTBBODIwQUJDMEFDMS0wQUM1MEFDNzBBQzgwQUNEMEFFMjBBRTMwQjAxMEIzQzBCM0YwQjQxLTBCNDQwQjREMEI1NjBCNjIwQjYzMEI4MjBCQzAwQkNEMEMzRS0wQzQwMEM0Ni0wQzQ4MEM0QS0wQzREMEM1NTBDNTYwQzYyMEM2MzBDQkMwQ0JGMENDNjBDQ0MwQ0NEMENFMjBDRTMwRDQxLTBENDQwRDREMEQ2MjBENjMwRENBMEREMi0wREQ0MERENjBFMzEwRTM0LTBFM0EwRTQ3LTBFNEUwRUIxMEVCNC0wRUI5MEVCQjBFQkMwRUM4LTBFQ0QwRjE4MEYxOTBGMzUwRjM3MEYzOTBGNzEtMEY3RTBGODAtMEY4NDBGODYwRjg3MEY4RC0wRjk3MEY5OS0wRkJDMEZDNjEwMkQtMTAzMDEwMzItMTAzNzEwMzkxMDNBMTAzRDEwM0UxMDU4MTA1OTEwNUUtMTA2MDEwNzEtMTA3NDEwODIxMDg1MTA4NjEwOEQxMDlEMTM1RC0xMzVGMTcxMi0xNzE0MTczMi0xNzM0MTc1MjE3NTMxNzcyMTc3MzE3QjQxN0I1MTdCNy0xN0JEMTdDNjE3QzktMTdEMzE3REQxODBCLTE4MEQxOEE5MTkyMC0xOTIyMTkyNzE5MjgxOTMyMTkzOS0xOTNCMUExNzFBMTgxQTU2MUE1OC0xQTVFMUE2MDFBNjIxQTY1LTFBNkMxQTczLTFBN0MxQTdGMUIwMC0xQjAzMUIzNDFCMzYtMUIzQTFCM0MxQjQyMUI2Qi0xQjczMUI4MDFCODExQkEyLTFCQTUxQkE4MUJBOTFCQUIxQkU2MUJFODFCRTkxQkVEMUJFRi0xQkYxMUMyQy0xQzMzMUMzNjFDMzcxQ0QwLTFDRDIxQ0Q0LTFDRTAxQ0UyLTFDRTgxQ0VEMUNGNDFEQzAtMURFNjFERkMtMURGRjIwRDAtMjBEQzIwRTEyMEU1LTIwRjAyQ0VGLTJDRjEyRDdGMkRFMC0yREZGMzAyQS0zMDJEMzA5OTMwOUFBNjZGQTY3NC1BNjdEQTY5RkE2RjBBNkYxQTgwMkE4MDZBODBCQTgyNUE4MjZBOEM0QThFMC1BOEYxQTkyNi1BOTJEQTk0Ny1BOTUxQTk4MC1BOTgyQTlCM0E5QjYtQTlCOUE5QkNBQTI5LUFBMkVBQTMxQUEzMkFBMzVBQTM2QUE0M0FBNENBQUIwQUFCMi1BQUI0QUFCN0FBQjhBQUJFQUFCRkFBQzFBQUVDQUFFREFBRjZBQkU1QUJFOEFCRURGQjFFRkUwMC1GRTBGRkUyMC1GRTI2IiwKICAgICAgICBNYzogIjA5MDMwOTNCMDkzRS0wOTQwMDk0OS0wOTRDMDk0RTA5NEYwOTgyMDk4MzA5QkUtMDlDMDA5QzcwOUM4MDlDQjA5Q0MwOUQ3MEEwMzBBM0UtMEE0MDBBODMwQUJFLTBBQzAwQUM5MEFDQjBBQ0MwQjAyMEIwMzBCM0UwQjQwMEI0NzBCNDgwQjRCMEI0QzBCNTcwQkJFMEJCRjBCQzEwQkMyMEJDNi0wQkM4MEJDQS0wQkNDMEJENzBDMDEtMEMwMzBDNDEtMEM0NDBDODIwQzgzMENCRTBDQzAtMENDNDBDQzcwQ0M4MENDQTBDQ0IwQ0Q1MENENjBEMDIwRDAzMEQzRS0wRDQwMEQ0Ni0wRDQ4MEQ0QS0wRDRDMEQ1NzBEODIwRDgzMERDRi0wREQxMEREOC0wRERGMERGMjBERjMwRjNFMEYzRjBGN0YxMDJCMTAyQzEwMzExMDM4MTAzQjEwM0MxMDU2MTA1NzEwNjItMTA2NDEwNjctMTA2RDEwODMxMDg0MTA4Ny0xMDhDMTA4RjEwOUEtMTA5QzE3QjYxN0JFLTE3QzUxN0M3MTdDODE5MjMtMTkyNjE5MjktMTkyQjE5MzAxOTMxMTkzMy0xOTM4MTlCMC0xOUMwMTlDODE5QzkxQTE5LTFBMUIxQTU1MUE1NzFBNjExQTYzMUE2NDFBNkQtMUE3MjFCMDQxQjM1MUIzQjFCM0QtMUI0MTFCNDMxQjQ0MUI4MjFCQTExQkE2MUJBNzFCQUExQkFDMUJBRDFCRTcxQkVBLTFCRUMxQkVFMUJGMjFCRjMxQzI0LTFDMkIxQzM0MUMzNTFDRTExQ0YyMUNGMzMwMkUzMDJGQTgyM0E4MjRBODI3QTg4MEE4ODFBOEI0LUE4QzNBOTUyQTk1M0E5ODNBOUI0QTlCNUE5QkFBOUJCQTlCRC1BOUMwQUEyRkFBMzBBQTMzQUEzNEFBNERBQTdCQUFFQkFBRUVBQUVGQUFGNUFCRTNBQkU0QUJFNkFCRTdBQkU5QUJFQUFCRUMiLAogICAgICAgIE1lOiAiMDQ4ODA0ODkyMERELTIwRTAyMEUyLTIwRTRBNjcwLUE2NzIiLAogICAgICAgIE46ICIwMDMwLTAwMzkwMEIyMDBCMzAwQjkwMEJDLTAwQkUwNjYwLTA2NjkwNkYwLTA2RjkwN0MwLTA3QzkwOTY2LTA5NkYwOUU2LTA5RUYwOUY0LTA5RjkwQTY2LTBBNkYwQUU2LTBBRUYwQjY2LTBCNkYwQjcyLTBCNzcwQkU2LTBCRjIwQzY2LTBDNkYwQzc4LTBDN0UwQ0U2LTBDRUYwRDY2LTBENzUwRTUwLTBFNTkwRUQwLTBFRDkwRjIwLTBGMzMxMDQwLTEwNDkxMDkwLTEwOTkxMzY5LTEzN0MxNkVFLTE2RjAxN0UwLTE3RTkxN0YwLTE3RjkxODEwLTE4MTkxOTQ2LTE5NEYxOUQwLTE5REExQTgwLTFBODkxQTkwLTFBOTkxQjUwLTFCNTkxQkIwLTFCQjkxQzQwLTFDNDkxQzUwLTFDNTkyMDcwMjA3NC0yMDc5MjA4MC0yMDg5MjE1MC0yMTgyMjE4NS0yMTg5MjQ2MC0yNDlCMjRFQS0yNEZGMjc3Ni0yNzkzMkNGRDMwMDczMDIxLTMwMjkzMDM4LTMwM0EzMTkyLTMxOTUzMjIwLTMyMjkzMjQ4LTMyNEYzMjUxLTMyNUYzMjgwLTMyODkzMkIxLTMyQkZBNjIwLUE2MjlBNkU2LUE2RUZBODMwLUE4MzVBOEQwLUE4RDlBOTAwLUE5MDlBOUQwLUE5RDlBQTUwLUFBNTlBQkYwLUFCRjlGRjEwLUZGMTkiLAogICAgICAgIE5kOiAiMDAzMC0wMDM5MDY2MC0wNjY5MDZGMC0wNkY5MDdDMC0wN0M5MDk2Ni0wOTZGMDlFNi0wOUVGMEE2Ni0wQTZGMEFFNi0wQUVGMEI2Ni0wQjZGMEJFNi0wQkVGMEM2Ni0wQzZGMENFNi0wQ0VGMEQ2Ni0wRDZGMEU1MC0wRTU5MEVEMC0wRUQ5MEYyMC0wRjI5MTA0MC0xMDQ5MTA5MC0xMDk5MTdFMC0xN0U5MTgxMC0xODE5MTk0Ni0xOTRGMTlEMC0xOUQ5MUE4MC0xQTg5MUE5MC0xQTk5MUI1MC0xQjU5MUJCMC0xQkI5MUM0MC0xQzQ5MUM1MC0xQzU5QTYyMC1BNjI5QThEMC1BOEQ5QTkwMC1BOTA5QTlEMC1BOUQ5QUE1MC1BQTU5QUJGMC1BQkY5RkYxMC1GRjE5IiwKICAgICAgICBObDogIjE2RUUtMTZGMDIxNjAtMjE4MjIxODUtMjE4ODMwMDczMDIxLTMwMjkzMDM4LTMwM0FBNkU2LUE2RUYiLAogICAgICAgIE5vOiAiMDBCMjAwQjMwMEI5MDBCQy0wMEJFMDlGNC0wOUY5MEI3Mi0wQjc3MEJGMC0wQkYyMEM3OC0wQzdFMEQ3MC0wRDc1MEYyQS0wRjMzMTM2OS0xMzdDMTdGMC0xN0Y5MTlEQTIwNzAyMDc0LTIwNzkyMDgwLTIwODkyMTUwLTIxNUYyMTg5MjQ2MC0yNDlCMjRFQS0yNEZGMjc3Ni0yNzkzMkNGRDMxOTItMzE5NTMyMjAtMzIyOTMyNDgtMzI0RjMyNTEtMzI1RjMyODAtMzI4OTMyQjEtMzJCRkE4MzAtQTgzNSIsCiAgICAgICAgUDogIjAwMjEtMDAyMzAwMjUtMDAyQTAwMkMtMDAyRjAwM0EwMDNCMDAzRjAwNDAwMDVCLTAwNUQwMDVGMDA3QjAwN0QwMEExMDBBNzAwQUIwMEI2MDBCNzAwQkIwMEJGMDM3RTAzODcwNTVBLTA1NUYwNTg5MDU4QTA1QkUwNUMwMDVDMzA1QzYwNUYzMDVGNDA2MDkwNjBBMDYwQzA2MEQwNjFCMDYxRTA2MUYwNjZBLTA2NkQwNkQ0MDcwMC0wNzBEMDdGNy0wN0Y5MDgzMC0wODNFMDg1RTA5NjQwOTY1MDk3MDBBRjAwREY0MEU0RjBFNUEwRTVCMEYwNC0wRjEyMEYxNDBGM0EtMEYzRDBGODUwRkQwLTBGRDQwRkQ5MEZEQTEwNEEtMTA0RjEwRkIxMzYwLTEzNjgxNDAwMTY2RDE2NkUxNjlCMTY5QzE2RUItMTZFRDE3MzUxNzM2MTdENC0xN0Q2MTdEOC0xN0RBMTgwMC0xODBBMTk0NDE5NDUxQTFFMUExRjFBQTAtMUFBNjFBQTgtMUFBRDFCNUEtMUI2MDFCRkMtMUJGRjFDM0ItMUMzRjFDN0UxQzdGMUNDMC0xQ0M3MUNEMzIwMTAtMjAyNzIwMzAtMjA0MzIwNDUtMjA1MTIwNTMtMjA1RTIwN0QyMDdFMjA4RDIwOEUyMzI5MjMyQTI3NjgtMjc3NTI3QzUyN0M2MjdFNi0yN0VGMjk4My0yOTk4MjlEOC0yOURCMjlGQzI5RkQyQ0Y5LTJDRkMyQ0ZFMkNGRjJENzAyRTAwLTJFMkUyRTMwLTJFM0IzMDAxLTMwMDMzMDA4LTMwMTEzMDE0LTMwMUYzMDMwMzAzRDMwQTAzMEZCQTRGRUE0RkZBNjBELUE2MEZBNjczQTY3RUE2RjItQTZGN0E4NzQtQTg3N0E4Q0VBOENGQThGOC1BOEZBQTkyRUE5MkZBOTVGQTlDMS1BOUNEQTlERUE5REZBQTVDLUFBNUZBQURFQUFERkFBRjBBQUYxQUJFQkZEM0VGRDNGRkUxMC1GRTE5RkUzMC1GRTUyRkU1NC1GRTYxRkU2M0ZFNjhGRTZBRkU2QkZGMDEtRkYwM0ZGMDUtRkYwQUZGMEMtRkYwRkZGMUFGRjFCRkYxRkZGMjBGRjNCLUZGM0RGRjNGRkY1QkZGNURGRjVGLUZGNjUiLAogICAgICAgIFBkOiAiMDAyRDA1OEEwNUJFMTQwMDE4MDYyMDEwLTIwMTUyRTE3MkUxQTJFM0EyRTNCMzAxQzMwMzAzMEEwRkUzMUZFMzJGRTU4RkU2M0ZGMEQiLAogICAgICAgIFBzOiAiMDAyODAwNUIwMDdCMEYzQTBGM0MxNjlCMjAxQTIwMUUyMDQ1MjA3RDIwOEQyMzI5Mjc2ODI3NkEyNzZDMjc2RTI3NzAyNzcyMjc3NDI3QzUyN0U2MjdFODI3RUEyN0VDMjdFRTI5ODMyOTg1Mjk4NzI5ODkyOThCMjk4RDI5OEYyOTkxMjk5MzI5OTUyOTk3MjlEODI5REEyOUZDMkUyMjJFMjQyRTI2MkUyODMwMDgzMDBBMzAwQzMwMEUzMDEwMzAxNDMwMTYzMDE4MzAxQTMwMURGRDNFRkUxN0ZFMzVGRTM3RkUzOUZFM0JGRTNERkUzRkZFNDFGRTQzRkU0N0ZFNTlGRTVCRkU1REZGMDhGRjNCRkY1QkZGNUZGRjYyIiwKICAgICAgICBQZTogIjAwMjkwMDVEMDA3RDBGM0IwRjNEMTY5QzIwNDYyMDdFMjA4RTIzMkEyNzY5Mjc2QjI3NkQyNzZGMjc3MTI3NzMyNzc1MjdDNjI3RTcyN0U5MjdFQjI3RUQyN0VGMjk4NDI5ODYyOTg4Mjk4QTI5OEMyOThFMjk5MDI5OTIyOTk0Mjk5NjI5OTgyOUQ5MjlEQjI5RkQyRTIzMkUyNTJFMjcyRTI5MzAwOTMwMEIzMDBEMzAwRjMwMTEzMDE1MzAxNzMwMTkzMDFCMzAxRTMwMUZGRDNGRkUxOEZFMzZGRTM4RkUzQUZFM0NGRTNFRkU0MEZFNDJGRTQ0RkU0OEZFNUFGRTVDRkU1RUZGMDlGRjNERkY1REZGNjBGRjYzIiwKICAgICAgICBQaTogIjAwQUIyMDE4MjAxQjIwMUMyMDFGMjAzOTJFMDIyRTA0MkUwOTJFMEMyRTFDMkUyMCIsCiAgICAgICAgUGY6ICIwMEJCMjAxOTIwMUQyMDNBMkUwMzJFMDUyRTBBMkUwRDJFMUQyRTIxIiwKICAgICAgICBQYzogIjAwNUYyMDNGMjA0MDIwNTRGRTMzRkUzNEZFNEQtRkU0RkZGM0YiLAogICAgICAgIFBvOiAiMDAyMS0wMDIzMDAyNS0wMDI3MDAyQTAwMkMwMDJFMDAyRjAwM0EwMDNCMDAzRjAwNDAwMDVDMDBBMTAwQTcwMEI2MDBCNzAwQkYwMzdFMDM4NzA1NUEtMDU1RjA1ODkwNUMwMDVDMzA1QzYwNUYzMDVGNDA2MDkwNjBBMDYwQzA2MEQwNjFCMDYxRTA2MUYwNjZBLTA2NkQwNkQ0MDcwMC0wNzBEMDdGNy0wN0Y5MDgzMC0wODNFMDg1RTA5NjQwOTY1MDk3MDBBRjAwREY0MEU0RjBFNUEwRTVCMEYwNC0wRjEyMEYxNDBGODUwRkQwLTBGRDQwRkQ5MEZEQTEwNEEtMTA0RjEwRkIxMzYwLTEzNjgxNjZEMTY2RTE2RUItMTZFRDE3MzUxNzM2MTdENC0xN0Q2MTdEOC0xN0RBMTgwMC0xODA1MTgwNy0xODBBMTk0NDE5NDUxQTFFMUExRjFBQTAtMUFBNjFBQTgtMUFBRDFCNUEtMUI2MDFCRkMtMUJGRjFDM0ItMUMzRjFDN0UxQzdGMUNDMC0xQ0M3MUNEMzIwMTYyMDE3MjAyMC0yMDI3MjAzMC0yMDM4MjAzQi0yMDNFMjA0MS0yMDQzMjA0Ny0yMDUxMjA1MzIwNTUtMjA1RTJDRjktMkNGQzJDRkUyQ0ZGMkQ3MDJFMDAyRTAxMkUwNi0yRTA4MkUwQjJFMEUtMkUxNjJFMTgyRTE5MkUxQjJFMUUyRTFGMkUyQS0yRTJFMkUzMC0yRTM5MzAwMS0zMDAzMzAzRDMwRkJBNEZFQTRGRkE2MEQtQTYwRkE2NzNBNjdFQTZGMi1BNkY3QTg3NC1BODc3QThDRUE4Q0ZBOEY4LUE4RkFBOTJFQTkyRkE5NUZBOUMxLUE5Q0RBOURFQTlERkFBNUMtQUE1RkFBREVBQURGQUFGMEFBRjFBQkVCRkUxMC1GRTE2RkUxOUZFMzBGRTQ1RkU0NkZFNDktRkU0Q0ZFNTAtRkU1MkZFNTQtRkU1N0ZFNUYtRkU2MUZFNjhGRTZBRkU2QkZGMDEtRkYwM0ZGMDUtRkYwN0ZGMEFGRjBDRkYwRUZGMEZGRjFBRkYxQkZGMUZGRjIwRkYzQ0ZGNjFGRjY0RkY2NSIsCiAgICAgICAgUzogIjAwMjQwMDJCMDAzQy0wMDNFMDA1RTAwNjAwMDdDMDA3RTAwQTItMDBBNjAwQTgwMEE5MDBBQzAwQUUtMDBCMTAwQjQwMEI4MDBENzAwRjcwMkMyLTAyQzUwMkQyLTAyREYwMkU1LTAyRUIwMkVEMDJFRi0wMkZGMDM3NTAzODQwMzg1MDNGNjA0ODIwNThGMDYwNi0wNjA4MDYwQjA2MEUwNjBGMDZERTA2RTkwNkZEMDZGRTA3RjYwOUYyMDlGMzA5RkEwOUZCMEFGMTBCNzAwQkYzLTBCRkEwQzdGMEQ3OTBFM0YwRjAxLTBGMDMwRjEzMEYxNS0wRjE3MEYxQS0wRjFGMEYzNDBGMzYwRjM4MEZCRS0wRkM1MEZDNy0wRkNDMEZDRTBGQ0YwRkQ1LTBGRDgxMDlFMTA5RjEzOTAtMTM5OTE3REIxOTQwMTlERS0xOUZGMUI2MS0xQjZBMUI3NC0xQjdDMUZCRDFGQkYtMUZDMTFGQ0QtMUZDRjFGREQtMUZERjFGRUQtMUZFRjFGRkQxRkZFMjA0NDIwNTIyMDdBLTIwN0MyMDhBLTIwOEMyMEEwLTIwQjkyMTAwMjEwMTIxMDMtMjEwNjIxMDgyMTA5MjExNDIxMTYtMjExODIxMUUtMjEyMzIxMjUyMTI3MjEyOTIxMkUyMTNBMjEzQjIxNDAtMjE0NDIxNEEtMjE0RDIxNEYyMTkwLTIzMjgyMzJCLTIzRjMyNDAwLTI0MjYyNDQwLTI0NEEyNDlDLTI0RTkyNTAwLTI2RkYyNzAxLTI3NjcyNzk0LTI3QzQyN0M3LTI3RTUyN0YwLTI5ODIyOTk5LTI5RDcyOURDLTI5RkIyOUZFLTJCNEMyQjUwLTJCNTkyQ0U1LTJDRUEyRTgwLTJFOTkyRTlCLTJFRjMyRjAwLTJGRDUyRkYwLTJGRkIzMDA0MzAxMjMwMTMzMDIwMzAzNjMwMzczMDNFMzAzRjMwOUIzMDlDMzE5MDMxOTEzMTk2LTMxOUYzMUMwLTMxRTMzMjAwLTMyMUUzMjJBLTMyNDczMjUwMzI2MC0zMjdGMzI4QS0zMkIwMzJDMC0zMkZFMzMwMC0zM0ZGNERDMC00REZGQTQ5MC1BNEM2QTcwMC1BNzE2QTcyMEE3MjFBNzg5QTc4QUE4MjgtQTgyQkE4MzYtQTgzOUFBNzctQUE3OUZCMjlGQkIyLUZCQzFGREZDRkRGREZFNjJGRTY0LUZFNjZGRTY5RkYwNEZGMEJGRjFDLUZGMUVGRjNFRkY0MEZGNUNGRjVFRkZFMC1GRkU2RkZFOC1GRkVFRkZGQ0ZGRkQiLAogICAgICAgIFNtOiAiMDAyQjAwM0MtMDAzRTAwN0MwMDdFMDBBQzAwQjEwMEQ3MDBGNzAzRjYwNjA2LTA2MDgyMDQ0MjA1MjIwN0EtMjA3QzIwOEEtMjA4QzIxMTgyMTQwLTIxNDQyMTRCMjE5MC0yMTk0MjE5QTIxOUIyMUEwMjFBMzIxQTYyMUFFMjFDRTIxQ0YyMUQyMjFENDIxRjQtMjJGRjIzMDgtMjMwQjIzMjAyMzIxMjM3QzIzOUItMjNCMzIzREMtMjNFMTI1QjcyNUMxMjVGOC0yNUZGMjY2RjI3QzAtMjdDNDI3QzctMjdFNTI3RjAtMjdGRjI5MDAtMjk4MjI5OTktMjlENzI5REMtMjlGQjI5RkUtMkFGRjJCMzAtMkI0NDJCNDctMkI0Q0ZCMjlGRTYyRkU2NC1GRTY2RkYwQkZGMUMtRkYxRUZGNUNGRjVFRkZFMkZGRTktRkZFQyIsCiAgICAgICAgU2M6ICIwMDI0MDBBMi0wMEE1MDU4RjA2MEIwOUYyMDlGMzA5RkIwQUYxMEJGOTBFM0YxN0RCMjBBMC0yMEI5QTgzOEZERkNGRTY5RkYwNEZGRTBGRkUxRkZFNUZGRTYiLAogICAgICAgIFNrOiAiMDA1RTAwNjAwMEE4MDBBRjAwQjQwMEI4MDJDMi0wMkM1MDJEMi0wMkRGMDJFNS0wMkVCMDJFRDAyRUYtMDJGRjAzNzUwMzg0MDM4NTFGQkQxRkJGLTFGQzExRkNELTFGQ0YxRkRELTFGREYxRkVELTFGRUYxRkZEMUZGRTMwOUIzMDlDQTcwMC1BNzE2QTcyMEE3MjFBNzg5QTc4QUZCQjItRkJDMUZGM0VGRjQwRkZFMyIsCiAgICAgICAgU286ICIwMEE2MDBBOTAwQUUwMEIwMDQ4MjA2MEUwNjBGMDZERTA2RTkwNkZEMDZGRTA3RjYwOUZBMEI3MDBCRjMtMEJGODBCRkEwQzdGMEQ3OTBGMDEtMEYwMzBGMTMwRjE1LTBGMTcwRjFBLTBGMUYwRjM0MEYzNjBGMzgwRkJFLTBGQzUwRkM3LTBGQ0MwRkNFMEZDRjBGRDUtMEZEODEwOUUxMDlGMTM5MC0xMzk5MTk0MDE5REUtMTlGRjFCNjEtMUI2QTFCNzQtMUI3QzIxMDAyMTAxMjEwMy0yMTA2MjEwODIxMDkyMTE0MjExNjIxMTcyMTFFLTIxMjMyMTI1MjEyNzIxMjkyMTJFMjEzQTIxM0IyMTRBMjE0QzIxNEQyMTRGMjE5NS0yMTk5MjE5Qy0yMTlGMjFBMTIxQTIyMUE0MjFBNTIxQTctMjFBRDIxQUYtMjFDRDIxRDAyMUQxMjFEMzIxRDUtMjFGMzIzMDAtMjMwNzIzMEMtMjMxRjIzMjItMjMyODIzMkItMjM3QjIzN0QtMjM5QTIzQjQtMjNEQjIzRTItMjNGMzI0MDAtMjQyNjI0NDAtMjQ0QTI0OUMtMjRFOTI1MDAtMjVCNjI1QjgtMjVDMDI1QzItMjVGNzI2MDAtMjY2RTI2NzAtMjZGRjI3MDEtMjc2NzI3OTQtMjdCRjI4MDAtMjhGRjJCMDAtMkIyRjJCNDUyQjQ2MkI1MC0yQjU5MkNFNS0yQ0VBMkU4MC0yRTk5MkU5Qi0yRUYzMkYwMC0yRkQ1MkZGMC0yRkZCMzAwNDMwMTIzMDEzMzAyMDMwMzYzMDM3MzAzRTMwM0YzMTkwMzE5MTMxOTYtMzE5RjMxQzAtMzFFMzMyMDAtMzIxRTMyMkEtMzI0NzMyNTAzMjYwLTMyN0YzMjhBLTMyQjAzMkMwLTMyRkUzMzAwLTMzRkY0REMwLTRERkZBNDkwLUE0QzZBODI4LUE4MkJBODM2QTgzN0E4MzlBQTc3LUFBNzlGREZERkZFNEZGRThGRkVERkZFRUZGRkNGRkZEIiwKICAgICAgICBaOiAiMDAyMDAwQTAxNjgwMTgwRTIwMDAtMjAwQTIwMjgyMDI5MjAyRjIwNUYzMDAwIiwKICAgICAgICBaczogIjAwMjAwMEEwMTY4MDE4MEUyMDAwLTIwMEEyMDJGMjA1RjMwMDAiLAogICAgICAgIFpsOiAiMjAyOCIsCiAgICAgICAgWnA6ICIyMDI5IiwKICAgICAgICBDOiAiMDAwMC0wMDFGMDA3Ri0wMDlGMDBBRDAzNzgwMzc5MDM3Ri0wMzgzMDM4QjAzOEQwM0EyMDUyOC0wNTMwMDU1NzA1NTgwNTYwMDU4ODA1OEItMDU4RTA1OTAwNUM4LTA1Q0YwNUVCLTA1RUYwNUY1LTA2MDUwNjFDMDYxRDA2REQwNzBFMDcwRjA3NEIwNzRDMDdCMi0wN0JGMDdGQi0wN0ZGMDgyRTA4MkYwODNGMDg1QzA4NUQwODVGLTA4OUYwOEExMDhBRC0wOEUzMDhGRjA5NzgwOTgwMDk4NDA5OEQwOThFMDk5MTA5OTIwOUE5MDlCMTA5QjMtMDlCNTA5QkEwOUJCMDlDNTA5QzYwOUM5MDlDQTA5Q0YtMDlENjA5RDgtMDlEQjA5REUwOUU0MDlFNTA5RkMtMEEwMDBBMDQwQTBCLTBBMEUwQTExMEExMjBBMjkwQTMxMEEzNDBBMzcwQTNBMEEzQjBBM0QwQTQzLTBBNDYwQTQ5MEE0QTBBNEUtMEE1MDBBNTItMEE1ODBBNUQwQTVGLTBBNjUwQTc2LTBBODAwQTg0MEE4RTBBOTIwQUE5MEFCMTBBQjQwQUJBMEFCQjBBQzYwQUNBMEFDRTBBQ0YwQUQxLTBBREYwQUU0MEFFNTBBRjItMEIwMDBCMDQwQjBEMEIwRTBCMTEwQjEyMEIyOTBCMzEwQjM0MEIzQTBCM0IwQjQ1MEI0NjBCNDkwQjRBMEI0RS0wQjU1MEI1OC0wQjVCMEI1RTBCNjQwQjY1MEI3OC0wQjgxMEI4NDBCOEItMEI4RDBCOTEwQjk2LTBCOTgwQjlCMEI5RDBCQTAtMEJBMjBCQTUtMEJBNzBCQUItMEJBRDBCQkEtMEJCRDBCQzMtMEJDNTBCQzkwQkNFMEJDRjBCRDEtMEJENjBCRDgtMEJFNTBCRkItMEMwMDBDMDQwQzBEMEMxMTBDMjkwQzM0MEMzQS0wQzNDMEM0NTBDNDkwQzRFLTBDNTQwQzU3MEM1QS0wQzVGMEM2NDBDNjUwQzcwLTBDNzcwQzgwMEM4MTBDODQwQzhEMEM5MTBDQTkwQ0I0MENCQTBDQkIwQ0M1MENDOTBDQ0UtMENENDBDRDctMENERDBDREYwQ0U0MENFNTBDRjAwQ0YzLTBEMDEwRDA0MEQwRDBEMTEwRDNCMEQzQzBENDUwRDQ5MEQ0Ri0wRDU2MEQ1OC0wRDVGMEQ2NDBENjUwRDc2LTBENzgwRDgwMEQ4MTBEODQwRDk3LTBEOTkwREIyMERCQzBEQkUwREJGMERDNy0wREM5MERDQi0wRENFMERENTBERDcwREUwLTBERjEwREY1LTBFMDAwRTNCLTBFM0UwRTVDLTBFODAwRTgzMEU4NTBFODYwRTg5MEU4QjBFOEMwRThFLTBFOTMwRTk4MEVBMDBFQTQwRUE2MEVBODBFQTkwRUFDMEVCQTBFQkUwRUJGMEVDNTBFQzcwRUNFMEVDRjBFREEwRURCMEVFMC0wRUZGMEY0ODBGNkQtMEY3MDBGOTgwRkJEMEZDRDBGREItMEZGRjEwQzYxMEM4LTEwQ0MxMENFMTBDRjEyNDkxMjRFMTI0RjEyNTcxMjU5MTI1RTEyNUYxMjg5MTI4RTEyOEYxMkIxMTJCNjEyQjcxMkJGMTJDMTEyQzYxMkM3MTJENzEzMTExMzE2MTMxNzEzNUIxMzVDMTM3RC0xMzdGMTM5QS0xMzlGMTNGNS0xM0ZGMTY5RC0xNjlGMTZGMS0xNkZGMTcwRDE3MTUtMTcxRjE3MzctMTczRjE3NTQtMTc1RjE3NkQxNzcxMTc3NC0xNzdGMTdERTE3REYxN0VBLTE3RUYxN0ZBLTE3RkYxODBGMTgxQS0xODFGMTg3OC0xODdGMThBQi0xOEFGMThGNi0xOEZGMTkxRC0xOTFGMTkyQy0xOTJGMTkzQy0xOTNGMTk0MS0xOTQzMTk2RTE5NkYxOTc1LTE5N0YxOUFDLTE5QUYxOUNBLTE5Q0YxOURCLTE5REQxQTFDMUExRDFBNUYxQTdEMUE3RTFBOEEtMUE4RjFBOUEtMUE5RjFBQUUtMUFGRjFCNEMtMUI0RjFCN0QtMUI3RjFCRjQtMUJGQjFDMzgtMUMzQTFDNEEtMUM0QzFDODAtMUNCRjFDQzgtMUNDRjFDRjctMUNGRjFERTctMURGQjFGMTYxRjE3MUYxRTFGMUYxRjQ2MUY0NzFGNEUxRjRGMUY1ODFGNUExRjVDMUY1RTFGN0UxRjdGMUZCNTFGQzUxRkQ0MUZENTFGREMxRkYwMUZGMTFGRjUxRkZGMjAwQi0yMDBGMjAyQS0yMDJFMjA2MC0yMDZGMjA3MjIwNzMyMDhGMjA5RC0yMDlGMjBCQS0yMENGMjBGMS0yMEZGMjE4QS0yMThGMjNGNC0yM0ZGMjQyNy0yNDNGMjQ0Qi0yNDVGMjcwMDJCNEQtMkI0RjJCNUEtMkJGRjJDMkYyQzVGMkNGNC0yQ0Y4MkQyNjJEMjgtMkQyQzJEMkUyRDJGMkQ2OC0yRDZFMkQ3MS0yRDdFMkQ5Ny0yRDlGMkRBNzJEQUYyREI3MkRCRjJEQzcyRENGMkRENzJEREYyRTNDLTJFN0YyRTlBMkVGNC0yRUZGMkZENi0yRkVGMkZGQy0yRkZGMzA0MDMwOTczMDk4MzEwMC0zMTA0MzEyRS0zMTMwMzE4RjMxQkItMzFCRjMxRTQtMzFFRjMyMUYzMkZGNERCNi00REJGOUZDRC05RkZGQTQ4RC1BNDhGQTRDNy1BNENGQTYyQy1BNjNGQTY5OC1BNjlFQTZGOC1BNkZGQTc4RkE3OTQtQTc5RkE3QUItQTdGN0E4MkMtQTgyRkE4M0EtQTgzRkE4NzgtQTg3RkE4QzUtQThDREE4REEtQThERkE4RkMtQThGRkE5NTQtQTk1RUE5N0QtQTk3RkE5Q0VBOURBLUE5RERBOUUwLUE5RkZBQTM3LUFBM0ZBQTRFQUE0RkFBNUFBQTVCQUE3Qy1BQTdGQUFDMy1BQURBQUFGNy1BQjAwQUIwN0FCMDhBQjBGQUIxMEFCMTctQUIxRkFCMjdBQjJGLUFCQkZBQkVFQUJFRkFCRkEtQUJGRkQ3QTQtRDdBRkQ3QzctRDdDQUQ3RkMtRjhGRkZBNkVGQTZGRkFEQS1GQUZGRkIwNy1GQjEyRkIxOC1GQjFDRkIzN0ZCM0RGQjNGRkI0MkZCNDVGQkMyLUZCRDJGRDQwLUZENEZGRDkwRkQ5MUZEQzgtRkRFRkZERkVGREZGRkUxQS1GRTFGRkUyNy1GRTJGRkU1M0ZFNjdGRTZDLUZFNkZGRTc1RkVGRC1GRjAwRkZCRi1GRkMxRkZDOEZGQzlGRkQwRkZEMUZGRDhGRkQ5RkZERC1GRkRGRkZFN0ZGRUYtRkZGQkZGRkVGRkZGIiwKICAgICAgICBDYzogIjAwMDAtMDAxRjAwN0YtMDA5RiIsCiAgICAgICAgQ2Y6ICIwMEFEMDYwMC0wNjA0MDZERDA3MEYyMDBCLTIwMEYyMDJBLTIwMkUyMDYwLTIwNjQyMDZBLTIwNkZGRUZGRkZGOS1GRkZCIiwKICAgICAgICBDbzogIkUwMDAtRjhGRiIsCiAgICAgICAgQ3M6ICJEODAwLURGRkYiLAogICAgICAgIENuOiAiMDM3ODAzNzkwMzdGLTAzODMwMzhCMDM4RDAzQTIwNTI4LTA1MzAwNTU3MDU1ODA1NjAwNTg4MDU4Qi0wNThFMDU5MDA1QzgtMDVDRjA1RUItMDVFRjA1RjUtMDVGRjA2MDUwNjFDMDYxRDA3MEUwNzRCMDc0QzA3QjItMDdCRjA3RkItMDdGRjA4MkUwODJGMDgzRjA4NUMwODVEMDg1Ri0wODlGMDhBMTA4QUQtMDhFMzA4RkYwOTc4MDk4MDA5ODQwOThEMDk4RTA5OTEwOTkyMDlBOTA5QjEwOUIzLTA5QjUwOUJBMDlCQjA5QzUwOUM2MDlDOTA5Q0EwOUNGLTA5RDYwOUQ4LTA5REIwOURFMDlFNDA5RTUwOUZDLTBBMDAwQTA0MEEwQi0wQTBFMEExMTBBMTIwQTI5MEEzMTBBMzQwQTM3MEEzQTBBM0IwQTNEMEE0My0wQTQ2MEE0OTBBNEEwQTRFLTBBNTAwQTUyLTBBNTgwQTVEMEE1Ri0wQTY1MEE3Ni0wQTgwMEE4NDBBOEUwQTkyMEFBOTBBQjEwQUI0MEFCQTBBQkIwQUM2MEFDQTBBQ0UwQUNGMEFEMS0wQURGMEFFNDBBRTUwQUYyLTBCMDAwQjA0MEIwRDBCMEUwQjExMEIxMjBCMjkwQjMxMEIzNDBCM0EwQjNCMEI0NTBCNDYwQjQ5MEI0QTBCNEUtMEI1NTBCNTgtMEI1QjBCNUUwQjY0MEI2NTBCNzgtMEI4MTBCODQwQjhCLTBCOEQwQjkxMEI5Ni0wQjk4MEI5QjBCOUQwQkEwLTBCQTIwQkE1LTBCQTcwQkFCLTBCQUQwQkJBLTBCQkQwQkMzLTBCQzUwQkM5MEJDRTBCQ0YwQkQxLTBCRDYwQkQ4LTBCRTUwQkZCLTBDMDAwQzA0MEMwRDBDMTEwQzI5MEMzNDBDM0EtMEMzQzBDNDUwQzQ5MEM0RS0wQzU0MEM1NzBDNUEtMEM1RjBDNjQwQzY1MEM3MC0wQzc3MEM4MDBDODEwQzg0MEM4RDBDOTEwQ0E5MENCNDBDQkEwQ0JCMENDNTBDQzkwQ0NFLTBDRDQwQ0Q3LTBDREQwQ0RGMENFNDBDRTUwQ0YwMENGMy0wRDAxMEQwNDBEMEQwRDExMEQzQjBEM0MwRDQ1MEQ0OTBENEYtMEQ1NjBENTgtMEQ1RjBENjQwRDY1MEQ3Ni0wRDc4MEQ4MDBEODEwRDg0MEQ5Ny0wRDk5MERCMjBEQkMwREJFMERCRjBEQzctMERDOTBEQ0ItMERDRTBERDUwREQ3MERFMC0wREYxMERGNS0wRTAwMEUzQi0wRTNFMEU1Qy0wRTgwMEU4MzBFODUwRTg2MEU4OTBFOEIwRThDMEU4RS0wRTkzMEU5ODBFQTAwRUE0MEVBNjBFQTgwRUE5MEVBQzBFQkEwRUJFMEVCRjBFQzUwRUM3MEVDRTBFQ0YwRURBMEVEQjBFRTAtMEVGRjBGNDgwRjZELTBGNzAwRjk4MEZCRDBGQ0QwRkRCLTBGRkYxMEM2MTBDOC0xMENDMTBDRTEwQ0YxMjQ5MTI0RTEyNEYxMjU3MTI1OTEyNUUxMjVGMTI4OTEyOEUxMjhGMTJCMTEyQjYxMkI3MTJCRjEyQzExMkM2MTJDNzEyRDcxMzExMTMxNjEzMTcxMzVCMTM1QzEzN0QtMTM3RjEzOUEtMTM5RjEzRjUtMTNGRjE2OUQtMTY5RjE2RjEtMTZGRjE3MEQxNzE1LTE3MUYxNzM3LTE3M0YxNzU0LTE3NUYxNzZEMTc3MTE3NzQtMTc3RjE3REUxN0RGMTdFQS0xN0VGMTdGQS0xN0ZGMTgwRjE4MUEtMTgxRjE4NzgtMTg3RjE4QUItMThBRjE4RjYtMThGRjE5MUQtMTkxRjE5MkMtMTkyRjE5M0MtMTkzRjE5NDEtMTk0MzE5NkUxOTZGMTk3NS0xOTdGMTlBQy0xOUFGMTlDQS0xOUNGMTlEQi0xOUREMUExQzFBMUQxQTVGMUE3RDFBN0UxQThBLTFBOEYxQTlBLTFBOUYxQUFFLTFBRkYxQjRDLTFCNEYxQjdELTFCN0YxQkY0LTFCRkIxQzM4LTFDM0ExQzRBLTFDNEMxQzgwLTFDQkYxQ0M4LTFDQ0YxQ0Y3LTFDRkYxREU3LTFERkIxRjE2MUYxNzFGMUUxRjFGMUY0NjFGNDcxRjRFMUY0RjFGNTgxRjVBMUY1QzFGNUUxRjdFMUY3RjFGQjUxRkM1MUZENDFGRDUxRkRDMUZGMDFGRjExRkY1MUZGRjIwNjUtMjA2OTIwNzIyMDczMjA4RjIwOUQtMjA5RjIwQkEtMjBDRjIwRjEtMjBGRjIxOEEtMjE4RjIzRjQtMjNGRjI0MjctMjQzRjI0NEItMjQ1RjI3MDAyQjRELTJCNEYyQjVBLTJCRkYyQzJGMkM1RjJDRjQtMkNGODJEMjYyRDI4LTJEMkMyRDJFMkQyRjJENjgtMkQ2RTJENzEtMkQ3RTJEOTctMkQ5RjJEQTcyREFGMkRCNzJEQkYyREM3MkRDRjJERDcyRERGMkUzQy0yRTdGMkU5QTJFRjQtMkVGRjJGRDYtMkZFRjJGRkMtMkZGRjMwNDAzMDk3MzA5ODMxMDAtMzEwNDMxMkUtMzEzMDMxOEYzMUJCLTMxQkYzMUU0LTMxRUYzMjFGMzJGRjREQjYtNERCRjlGQ0QtOUZGRkE0OEQtQTQ4RkE0QzctQTRDRkE2MkMtQTYzRkE2OTgtQTY5RUE2RjgtQTZGRkE3OEZBNzk0LUE3OUZBN0FCLUE3RjdBODJDLUE4MkZBODNBLUE4M0ZBODc4LUE4N0ZBOEM1LUE4Q0RBOERBLUE4REZBOEZDLUE4RkZBOTU0LUE5NUVBOTdELUE5N0ZBOUNFQTlEQS1BOUREQTlFMC1BOUZGQUEzNy1BQTNGQUE0RUFBNEZBQTVBQUE1QkFBN0MtQUE3RkFBQzMtQUFEQUFBRjctQUIwMEFCMDdBQjA4QUIwRkFCMTBBQjE3LUFCMUZBQjI3QUIyRi1BQkJGQUJFRUFCRUZBQkZBLUFCRkZEN0E0LUQ3QUZEN0M3LUQ3Q0FEN0ZDLUQ3RkZGQTZFRkE2RkZBREEtRkFGRkZCMDctRkIxMkZCMTgtRkIxQ0ZCMzdGQjNERkIzRkZCNDJGQjQ1RkJDMi1GQkQyRkQ0MC1GRDRGRkQ5MEZEOTFGREM4LUZERUZGREZFRkRGRkZFMUEtRkUxRkZFMjctRkUyRkZFNTNGRTY3RkU2Qy1GRTZGRkU3NUZFRkRGRUZFRkYwMEZGQkYtRkZDMUZGQzhGRkM5RkZEMEZGRDFGRkQ4RkZEOUZGREQtRkZERkZGRTdGRkVGLUZGRjhGRkZFRkZGRiIKICAgIH0sIHsKICAgICAgICAvL0w6ICJMZXR0ZXIiLCAvLyBJbmNsdWRlZCBpbiB0aGUgVW5pY29kZSBCYXNlIGFkZG9uCiAgICAgICAgTGw6ICJMb3dlcmNhc2VfTGV0dGVyIiwKICAgICAgICBMdTogIlVwcGVyY2FzZV9MZXR0ZXIiLAogICAgICAgIEx0OiAiVGl0bGVjYXNlX0xldHRlciIsCiAgICAgICAgTG06ICJNb2RpZmllcl9MZXR0ZXIiLAogICAgICAgIExvOiAiT3RoZXJfTGV0dGVyIiwKICAgICAgICBNOiAiTWFyayIsCiAgICAgICAgTW46ICJOb25zcGFjaW5nX01hcmsiLAogICAgICAgIE1jOiAiU3BhY2luZ19NYXJrIiwKICAgICAgICBNZTogIkVuY2xvc2luZ19NYXJrIiwKICAgICAgICBOOiAiTnVtYmVyIiwKICAgICAgICBOZDogIkRlY2ltYWxfTnVtYmVyIiwKICAgICAgICBObDogIkxldHRlcl9OdW1iZXIiLAogICAgICAgIE5vOiAiT3RoZXJfTnVtYmVyIiwKICAgICAgICBQOiAiUHVuY3R1YXRpb24iLAogICAgICAgIFBkOiAiRGFzaF9QdW5jdHVhdGlvbiIsCiAgICAgICAgUHM6ICJPcGVuX1B1bmN0dWF0aW9uIiwKICAgICAgICBQZTogIkNsb3NlX1B1bmN0dWF0aW9uIiwKICAgICAgICBQaTogIkluaXRpYWxfUHVuY3R1YXRpb24iLAogICAgICAgIFBmOiAiRmluYWxfUHVuY3R1YXRpb24iLAogICAgICAgIFBjOiAiQ29ubmVjdG9yX1B1bmN0dWF0aW9uIiwKICAgICAgICBQbzogIk90aGVyX1B1bmN0dWF0aW9uIiwKICAgICAgICBTOiAiU3ltYm9sIiwKICAgICAgICBTbTogIk1hdGhfU3ltYm9sIiwKICAgICAgICBTYzogIkN1cnJlbmN5X1N5bWJvbCIsCiAgICAgICAgU2s6ICJNb2RpZmllcl9TeW1ib2wiLAogICAgICAgIFNvOiAiT3RoZXJfU3ltYm9sIiwKICAgICAgICBaOiAiU2VwYXJhdG9yIiwKICAgICAgICBaczogIlNwYWNlX1NlcGFyYXRvciIsCiAgICAgICAgWmw6ICJMaW5lX1NlcGFyYXRvciIsCiAgICAgICAgWnA6ICJQYXJhZ3JhcGhfU2VwYXJhdG9yIiwKICAgICAgICBDOiAiT3RoZXIiLAogICAgICAgIENjOiAiQ29udHJvbCIsCiAgICAgICAgQ2Y6ICJGb3JtYXQiLAogICAgICAgIENvOiAiUHJpdmF0ZV9Vc2UiLAogICAgICAgIENzOiAiU3Vycm9nYXRlIiwKICAgICAgICBDbjogIlVuYXNzaWduZWQiCiAgICB9KTsKCn0oWFJlZ0V4cCkpOwoKCi8qKioqKiB1bmljb2RlLXNjcmlwdHMuanMgKioqKiovCgovKiEKICogWFJlZ0V4cCBVbmljb2RlIFNjcmlwdHMgdjEuMi4wCiAqIChjKSAyMDEwLTIwMTIgU3RldmVuIExldml0aGFuIDxodHRwOi8veHJlZ2V4cC5jb20vPgogKiBNSVQgTGljZW5zZQogKiBVc2VzIFVuaWNvZGUgNi4xIDxodHRwOi8vdW5pY29kZS5vcmcvPgogKi8KCi8qKgogKiBBZGRzIHN1cHBvcnQgZm9yIGFsbCBVbmljb2RlIHNjcmlwdHMgaW4gdGhlIEJhc2ljIE11bHRpbGluZ3VhbCBQbGFuZSAoVSswMDAwLVUrRkZGRikuCiAqIEUuZy4sIGBccHtMYXRpbn1gLiBUb2tlbiBuYW1lcyBhcmUgY2FzZSBpbnNlbnNpdGl2ZSwgYW5kIGFueSBzcGFjZXMsIGh5cGhlbnMsIGFuZCB1bmRlcnNjb3JlcwogKiBhcmUgaWdub3JlZC4KICogQHJlcXVpcmVzIFhSZWdFeHAsIFhSZWdFeHAgVW5pY29kZSBCYXNlCiAqLwooZnVuY3Rpb24gKFhSZWdFeHApIHsKICAgICJ1c2Ugc3RyaWN0IjsKCiAgICBpZiAoIVhSZWdFeHAuYWRkVW5pY29kZVBhY2thZ2UpIHsKICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoIlVuaWNvZGUgQmFzZSBtdXN0IGJlIGxvYWRlZCBiZWZvcmUgVW5pY29kZSBTY3JpcHRzIik7CiAgICB9CgogICAgWFJlZ0V4cC5pbnN0YWxsKCJleHRlbnNpYmlsaXR5Iik7CgogICAgWFJlZ0V4cC5hZGRVbmljb2RlUGFja2FnZSh7CiAgICAgICAgQXJhYmljOiAiMDYwMC0wNjA0MDYwNi0wNjBCMDYwRC0wNjFBMDYxRTA2MjAtMDYzRjA2NDEtMDY0QTA2NTYtMDY1RTA2NkEtMDY2RjA2NzEtMDZEQzA2REUtMDZGRjA3NTAtMDc3RjA4QTAwOEEyLTA4QUMwOEU0LTA4RkVGQjUwLUZCQzFGQkQzLUZEM0RGRDUwLUZEOEZGRDkyLUZEQzdGREYwLUZERkNGRTcwLUZFNzRGRTc2LUZFRkMiLAogICAgICAgIEFybWVuaWFuOiAiMDUzMS0wNTU2MDU1OS0wNTVGMDU2MS0wNTg3MDU4QTA1OEZGQjEzLUZCMTciLAogICAgICAgIEJhbGluZXNlOiAiMUIwMC0xQjRCMUI1MC0xQjdDIiwKICAgICAgICBCYW11bTogIkE2QTAtQTZGNyIsCiAgICAgICAgQmF0YWs6ICIxQkMwLTFCRjMxQkZDLTFCRkYiLAogICAgICAgIEJlbmdhbGk6ICIwOTgxLTA5ODMwOTg1LTA5OEMwOThGMDk5MDA5OTMtMDlBODA5QUEtMDlCMDA5QjIwOUI2LTA5QjkwOUJDLTA5QzQwOUM3MDlDODA5Q0ItMDlDRTA5RDcwOURDMDlERDA5REYtMDlFMzA5RTYtMDlGQiIsCiAgICAgICAgQm9wb21vZm86ICIwMkVBMDJFQjMxMDUtMzEyRDMxQTAtMzFCQSIsCiAgICAgICAgQnJhaWxsZTogIjI4MDAtMjhGRiIsCiAgICAgICAgQnVnaW5lc2U6ICIxQTAwLTFBMUIxQTFFMUExRiIsCiAgICAgICAgQnVoaWQ6ICIxNzQwLTE3NTMiLAogICAgICAgIENhbmFkaWFuX0Fib3JpZ2luYWw6ICIxNDAwLTE2N0YxOEIwLTE4RjUiLAogICAgICAgIENoYW06ICJBQTAwLUFBMzZBQTQwLUFBNERBQTUwLUFBNTlBQTVDLUFBNUYiLAogICAgICAgIENoZXJva2VlOiAiMTNBMC0xM0Y0IiwKICAgICAgICBDb21tb246ICIwMDAwLTAwNDAwMDVCLTAwNjAwMDdCLTAwQTkwMEFCLTAwQjkwMEJCLTAwQkYwMEQ3MDBGNzAyQjktMDJERjAyRTUtMDJFOTAyRUMtMDJGRjAzNzQwMzdFMDM4NTAzODcwNTg5MDYwQzA2MUIwNjFGMDY0MDA2NjAtMDY2OTA2REQwOTY0MDk2NTBFM0YwRkQ1LTBGRDgxMEZCMTZFQi0xNkVEMTczNTE3MzYxODAyMTgwMzE4MDUxQ0QzMUNFMTFDRTktMUNFQzFDRUUtMUNGMzFDRjUxQ0Y2MjAwMC0yMDBCMjAwRS0yMDY0MjA2QS0yMDcwMjA3NC0yMDdFMjA4MC0yMDhFMjBBMC0yMEI5MjEwMC0yMTI1MjEyNy0yMTI5MjEyQy0yMTMxMjEzMy0yMTREMjE0Ri0yMTVGMjE4OTIxOTAtMjNGMzI0MDAtMjQyNjI0NDAtMjQ0QTI0NjAtMjZGRjI3MDEtMjdGRjI5MDAtMkI0QzJCNTAtMkI1OTJFMDAtMkUzQjJGRjAtMkZGQjMwMDAtMzAwNDMwMDYzMDA4LTMwMjAzMDMwLTMwMzczMDNDLTMwM0YzMDlCMzA5QzMwQTAzMEZCMzBGQzMxOTAtMzE5RjMxQzAtMzFFMzMyMjAtMzI1RjMyN0YtMzJDRjMzNTgtMzNGRjREQzAtNERGRkE3MDAtQTcyMUE3ODgtQTc4QUE4MzAtQTgzOUZEM0VGRDNGRkRGREZFMTAtRkUxOUZFMzAtRkU1MkZFNTQtRkU2NkZFNjgtRkU2QkZFRkZGRjAxLUZGMjBGRjNCLUZGNDBGRjVCLUZGNjVGRjcwRkY5RUZGOUZGRkUwLUZGRTZGRkU4LUZGRUVGRkY5LUZGRkQiLAogICAgICAgIENvcHRpYzogIjAzRTItMDNFRjJDODAtMkNGMzJDRjktMkNGRiIsCiAgICAgICAgQ3lyaWxsaWM6ICIwNDAwLTA0ODQwNDg3LTA1MjcxRDJCMUQ3ODJERTAtMkRGRkE2NDAtQTY5N0E2OUYiLAogICAgICAgIERldmFuYWdhcmk6ICIwOTAwLTA5NTAwOTUzLTA5NjMwOTY2LTA5NzcwOTc5LTA5N0ZBOEUwLUE4RkIiLAogICAgICAgIEV0aGlvcGljOiAiMTIwMC0xMjQ4MTI0QS0xMjREMTI1MC0xMjU2MTI1ODEyNUEtMTI1RDEyNjAtMTI4ODEyOEEtMTI4RDEyOTAtMTJCMDEyQjItMTJCNTEyQjgtMTJCRTEyQzAxMkMyLTEyQzUxMkM4LTEyRDYxMkQ4LTEzMTAxMzEyLTEzMTUxMzE4LTEzNUExMzVELTEzN0MxMzgwLTEzOTkyRDgwLTJEOTYyREEwLTJEQTYyREE4LTJEQUUyREIwLTJEQjYyREI4LTJEQkUyREMwLTJEQzYyREM4LTJEQ0UyREQwLTJERDYyREQ4LTJEREVBQjAxLUFCMDZBQjA5LUFCMEVBQjExLUFCMTZBQjIwLUFCMjZBQjI4LUFCMkUiLAogICAgICAgIEdlb3JnaWFuOiAiMTBBMC0xMEM1MTBDNzEwQ0QxMEQwLTEwRkExMEZDLTEwRkYyRDAwLTJEMjUyRDI3MkQyRCIsCiAgICAgICAgR2xhZ29saXRpYzogIjJDMDAtMkMyRTJDMzAtMkM1RSIsCiAgICAgICAgR3JlZWs6ICIwMzcwLTAzNzMwMzc1LTAzNzcwMzdBLTAzN0QwMzg0MDM4NjAzODgtMDM4QTAzOEMwMzhFLTAzQTEwM0EzLTAzRTEwM0YwLTAzRkYxRDI2LTFEMkExRDVELTFENjExRDY2LTFENkExREJGMUYwMC0xRjE1MUYxOC0xRjFEMUYyMC0xRjQ1MUY0OC0xRjREMUY1MC0xRjU3MUY1OTFGNUIxRjVEMUY1Ri0xRjdEMUY4MC0xRkI0MUZCNi0xRkM0MUZDNi0xRkQzMUZENi0xRkRCMUZERC0xRkVGMUZGMi0xRkY0MUZGNi0xRkZFMjEyNiIsCiAgICAgICAgR3VqYXJhdGk6ICIwQTgxLTBBODMwQTg1LTBBOEQwQThGLTBBOTEwQTkzLTBBQTgwQUFBLTBBQjAwQUIyMEFCMzBBQjUtMEFCOTBBQkMtMEFDNTBBQzctMEFDOTBBQ0ItMEFDRDBBRDAwQUUwLTBBRTMwQUU2LTBBRjEiLAogICAgICAgIEd1cm11a2hpOiAiMEEwMS0wQTAzMEEwNS0wQTBBMEEwRjBBMTAwQTEzLTBBMjgwQTJBLTBBMzAwQTMyMEEzMzBBMzUwQTM2MEEzODBBMzkwQTNDMEEzRS0wQTQyMEE0NzBBNDgwQTRCLTBBNEQwQTUxMEE1OS0wQTVDMEE1RTBBNjYtMEE3NSIsCiAgICAgICAgSGFuOiAiMkU4MC0yRTk5MkU5Qi0yRUYzMkYwMC0yRkQ1MzAwNTMwMDczMDIxLTMwMjkzMDM4LTMwM0IzNDAwLTREQjU0RTAwLTlGQ0NGOTAwLUZBNkRGQTcwLUZBRDkiLAogICAgICAgIEhhbmd1bDogIjExMDAtMTFGRjMwMkUzMDJGMzEzMS0zMThFMzIwMC0zMjFFMzI2MC0zMjdFQTk2MC1BOTdDQUMwMC1EN0EzRDdCMC1EN0M2RDdDQi1EN0ZCRkZBMC1GRkJFRkZDMi1GRkM3RkZDQS1GRkNGRkZEMi1GRkQ3RkZEQS1GRkRDIiwKICAgICAgICBIYW51bm9vOiAiMTcyMC0xNzM0IiwKICAgICAgICBIZWJyZXc6ICIwNTkxLTA1QzcwNUQwLTA1RUEwNUYwLTA1RjRGQjFELUZCMzZGQjM4LUZCM0NGQjNFRkI0MEZCNDFGQjQzRkI0NEZCNDYtRkI0RiIsCiAgICAgICAgSGlyYWdhbmE6ICIzMDQxLTMwOTYzMDlELTMwOUYiLAogICAgICAgIEluaGVyaXRlZDogIjAzMDAtMDM2RjA0ODUwNDg2MDY0Qi0wNjU1MDY1RjA2NzAwOTUxMDk1MjFDRDAtMUNEMjFDRDQtMUNFMDFDRTItMUNFODFDRUQxQ0Y0MURDMC0xREU2MURGQy0xREZGMjAwQzIwMEQyMEQwLTIwRjAzMDJBLTMwMkQzMDk5MzA5QUZFMDAtRkUwRkZFMjAtRkUyNiIsCiAgICAgICAgSmF2YW5lc2U6ICJBOTgwLUE5Q0RBOUNGLUE5RDlBOURFQTlERiIsCiAgICAgICAgS2FubmFkYTogIjBDODIwQzgzMEM4NS0wQzhDMEM4RS0wQzkwMEM5Mi0wQ0E4MENBQS0wQ0IzMENCNS0wQ0I5MENCQy0wQ0M0MENDNi0wQ0M4MENDQS0wQ0NEMENENTBDRDYwQ0RFMENFMC0wQ0UzMENFNi0wQ0VGMENGMTBDRjIiLAogICAgICAgIEthdGFrYW5hOiAiMzBBMS0zMEZBMzBGRC0zMEZGMzFGMC0zMUZGMzJEMC0zMkZFMzMwMC0zMzU3RkY2Ni1GRjZGRkY3MS1GRjlEIiwKICAgICAgICBLYXlhaF9MaTogIkE5MDAtQTkyRiIsCiAgICAgICAgS2htZXI6ICIxNzgwLTE3REQxN0UwLTE3RTkxN0YwLTE3RjkxOUUwLTE5RkYiLAogICAgICAgIExhbzogIjBFODEwRTgyMEU4NDBFODcwRTg4MEU4QTBFOEQwRTk0LTBFOTcwRTk5LTBFOUYwRUExLTBFQTMwRUE1MEVBNzBFQUEwRUFCMEVBRC0wRUI5MEVCQi0wRUJEMEVDMC0wRUM0MEVDNjBFQzgtMEVDRDBFRDAtMEVEOTBFREMtMEVERiIsCiAgICAgICAgTGF0aW46ICIwMDQxLTAwNUEwMDYxLTAwN0EwMEFBMDBCQTAwQzAtMDBENjAwRDgtMDBGNjAwRjgtMDJCODAyRTAtMDJFNDFEMDAtMUQyNTFEMkMtMUQ1QzFENjItMUQ2NTFENkItMUQ3NzFENzktMURCRTFFMDAtMUVGRjIwNzEyMDdGMjA5MC0yMDlDMjEyQTIxMkIyMTMyMjE0RTIxNjAtMjE4ODJDNjAtMkM3RkE3MjItQTc4N0E3OEItQTc4RUE3OTAtQTc5M0E3QTAtQTdBQUE3RjgtQTdGRkZCMDAtRkIwNkZGMjEtRkYzQUZGNDEtRkY1QSIsCiAgICAgICAgTGVwY2hhOiAiMUMwMC0xQzM3MUMzQi0xQzQ5MUM0RC0xQzRGIiwKICAgICAgICBMaW1idTogIjE5MDAtMTkxQzE5MjAtMTkyQjE5MzAtMTkzQjE5NDAxOTQ0LTE5NEYiLAogICAgICAgIExpc3U6ICJBNEQwLUE0RkYiLAogICAgICAgIE1hbGF5YWxhbTogIjBEMDIwRDAzMEQwNS0wRDBDMEQwRS0wRDEwMEQxMi0wRDNBMEQzRC0wRDQ0MEQ0Ni0wRDQ4MEQ0QS0wRDRFMEQ1NzBENjAtMEQ2MzBENjYtMEQ3NTBENzktMEQ3RiIsCiAgICAgICAgTWFuZGFpYzogIjA4NDAtMDg1QjA4NUUiLAogICAgICAgIE1lZXRlaV9NYXllazogIkFBRTAtQUFGNkFCQzAtQUJFREFCRjAtQUJGOSIsCiAgICAgICAgTW9uZ29saWFuOiAiMTgwMDE4MDExODA0MTgwNi0xODBFMTgxMC0xODE5MTgyMC0xODc3MTg4MC0xOEFBIiwKICAgICAgICBNeWFubWFyOiAiMTAwMC0xMDlGQUE2MC1BQTdCIiwKICAgICAgICBOZXdfVGFpX0x1ZTogIjE5ODAtMTlBQjE5QjAtMTlDOTE5RDAtMTlEQTE5REUxOURGIiwKICAgICAgICBOa286ICIwN0MwLTA3RkEiLAogICAgICAgIE9naGFtOiAiMTY4MC0xNjlDIiwKICAgICAgICBPbF9DaGlraTogIjFDNTAtMUM3RiIsCiAgICAgICAgT3JpeWE6ICIwQjAxLTBCMDMwQjA1LTBCMEMwQjBGMEIxMDBCMTMtMEIyODBCMkEtMEIzMDBCMzIwQjMzMEIzNS0wQjM5MEIzQy0wQjQ0MEI0NzBCNDgwQjRCLTBCNEQwQjU2MEI1NzBCNUMwQjVEMEI1Ri0wQjYzMEI2Ni0wQjc3IiwKICAgICAgICBQaGFnc19QYTogIkE4NDAtQTg3NyIsCiAgICAgICAgUmVqYW5nOiAiQTkzMC1BOTUzQTk1RiIsCiAgICAgICAgUnVuaWM6ICIxNkEwLTE2RUExNkVFLTE2RjAiLAogICAgICAgIFNhbWFyaXRhbjogIjA4MDAtMDgyRDA4MzAtMDgzRSIsCiAgICAgICAgU2F1cmFzaHRyYTogIkE4ODAtQThDNEE4Q0UtQThEOSIsCiAgICAgICAgU2luaGFsYTogIjBEODIwRDgzMEQ4NS0wRDk2MEQ5QS0wREIxMERCMy0wREJCMERCRDBEQzAtMERDNjBEQ0EwRENGLTBERDQwREQ2MEREOC0wRERGMERGMi0wREY0IiwKICAgICAgICBTdW5kYW5lc2U6ICIxQjgwLTFCQkYxQ0MwLTFDQzciLAogICAgICAgIFN5bG90aV9OYWdyaTogIkE4MDAtQTgyQiIsCiAgICAgICAgU3lyaWFjOiAiMDcwMC0wNzBEMDcwRi0wNzRBMDc0RC0wNzRGIiwKICAgICAgICBUYWdhbG9nOiAiMTcwMC0xNzBDMTcwRS0xNzE0IiwKICAgICAgICBUYWdiYW53YTogIjE3NjAtMTc2QzE3NkUtMTc3MDE3NzIxNzczIiwKICAgICAgICBUYWlfTGU6ICIxOTUwLTE5NkQxOTcwLTE5NzQiLAogICAgICAgIFRhaV9UaGFtOiAiMUEyMC0xQTVFMUE2MC0xQTdDMUE3Ri0xQTg5MUE5MC0xQTk5MUFBMC0xQUFEIiwKICAgICAgICBUYWlfVmlldDogIkFBODAtQUFDMkFBREItQUFERiIsCiAgICAgICAgVGFtaWw6ICIwQjgyMEI4MzBCODUtMEI4QTBCOEUtMEI5MDBCOTItMEI5NTBCOTkwQjlBMEI5QzBCOUUwQjlGMEJBMzBCQTQwQkE4LTBCQUEwQkFFLTBCQjkwQkJFLTBCQzIwQkM2LTBCQzgwQkNBLTBCQ0QwQkQwMEJENzBCRTYtMEJGQSIsCiAgICAgICAgVGVsdWd1OiAiMEMwMS0wQzAzMEMwNS0wQzBDMEMwRS0wQzEwMEMxMi0wQzI4MEMyQS0wQzMzMEMzNS0wQzM5MEMzRC0wQzQ0MEM0Ni0wQzQ4MEM0QS0wQzREMEM1NTBDNTYwQzU4MEM1OTBDNjAtMEM2MzBDNjYtMEM2RjBDNzgtMEM3RiIsCiAgICAgICAgVGhhYW5hOiAiMDc4MC0wN0IxIiwKICAgICAgICBUaGFpOiAiMEUwMS0wRTNBMEU0MC0wRTVCIiwKICAgICAgICBUaWJldGFuOiAiMEYwMC0wRjQ3MEY0OS0wRjZDMEY3MS0wRjk3MEY5OS0wRkJDMEZCRS0wRkNDMEZDRS0wRkQ0MEZEOTBGREEiLAogICAgICAgIFRpZmluYWdoOiAiMkQzMC0yRDY3MkQ2RjJENzAyRDdGIiwKICAgICAgICBWYWk6ICJBNTAwLUE2MkIiLAogICAgICAgIFlpOiAiQTAwMC1BNDhDQTQ5MC1BNEM2IgogICAgfSk7Cgp9KFhSZWdFeHApKTsKCgovKioqKiogdW5pY29kZS1ibG9ja3MuanMgKioqKiovCgovKiEKICogWFJlZ0V4cCBVbmljb2RlIEJsb2NrcyB2MS4yLjAKICogKGMpIDIwMTAtMjAxMiBTdGV2ZW4gTGV2aXRoYW4gPGh0dHA6Ly94cmVnZXhwLmNvbS8+CiAqIE1JVCBMaWNlbnNlCiAqIFVzZXMgVW5pY29kZSA2LjEgPGh0dHA6Ly91bmljb2RlLm9yZy8+CiAqLwoKLyoqCiAqIEFkZHMgc3VwcG9ydCBmb3IgYWxsIFVuaWNvZGUgYmxvY2tzIGluIHRoZSBCYXNpYyBNdWx0aWxpbmd1YWwgUGxhbmUgKFUrMDAwMC1VK0ZGRkYpLiBVbmljb2RlCiAqIGJsb2NrcyB1c2UgdGhlIHByZWZpeCAiSW4iLiBFLmcuLCBgXHB7SW5CYXNpY0xhdGlufWAuIFRva2VuIG5hbWVzIGFyZSBjYXNlIGluc2Vuc2l0aXZlLCBhbmQgYW55CiAqIHNwYWNlcywgaHlwaGVucywgYW5kIHVuZGVyc2NvcmVzIGFyZSBpZ25vcmVkLgogKiBAcmVxdWlyZXMgWFJlZ0V4cCwgWFJlZ0V4cCBVbmljb2RlIEJhc2UKICovCihmdW5jdGlvbiAoWFJlZ0V4cCkgewogICAgInVzZSBzdHJpY3QiOwoKICAgIGlmICghWFJlZ0V4cC5hZGRVbmljb2RlUGFja2FnZSkgewogICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigiVW5pY29kZSBCYXNlIG11c3QgYmUgbG9hZGVkIGJlZm9yZSBVbmljb2RlIEJsb2NrcyIpOwogICAgfQoKICAgIFhSZWdFeHAuaW5zdGFsbCgiZXh0ZW5zaWJpbGl0eSIpOwoKICAgIFhSZWdFeHAuYWRkVW5pY29kZVBhY2thZ2UoewogICAgICAgIEluQmFzaWNfTGF0aW46ICIwMDAwLTAwN0YiLAogICAgICAgIEluTGF0aW5fMV9TdXBwbGVtZW50OiAiMDA4MC0wMEZGIiwKICAgICAgICBJbkxhdGluX0V4dGVuZGVkX0E6ICIwMTAwLTAxN0YiLAogICAgICAgIEluTGF0aW5fRXh0ZW5kZWRfQjogIjAxODAtMDI0RiIsCiAgICAgICAgSW5JUEFfRXh0ZW5zaW9uczogIjAyNTAtMDJBRiIsCiAgICAgICAgSW5TcGFjaW5nX01vZGlmaWVyX0xldHRlcnM6ICIwMkIwLTAyRkYiLAogICAgICAgIEluQ29tYmluaW5nX0RpYWNyaXRpY2FsX01hcmtzOiAiMDMwMC0wMzZGIiwKICAgICAgICBJbkdyZWVrX2FuZF9Db3B0aWM6ICIwMzcwLTAzRkYiLAogICAgICAgIEluQ3lyaWxsaWM6ICIwNDAwLTA0RkYiLAogICAgICAgIEluQ3lyaWxsaWNfU3VwcGxlbWVudDogIjA1MDAtMDUyRiIsCiAgICAgICAgSW5Bcm1lbmlhbjogIjA1MzAtMDU4RiIsCiAgICAgICAgSW5IZWJyZXc6ICIwNTkwLTA1RkYiLAogICAgICAgIEluQXJhYmljOiAiMDYwMC0wNkZGIiwKICAgICAgICBJblN5cmlhYzogIjA3MDAtMDc0RiIsCiAgICAgICAgSW5BcmFiaWNfU3VwcGxlbWVudDogIjA3NTAtMDc3RiIsCiAgICAgICAgSW5UaGFhbmE6ICIwNzgwLTA3QkYiLAogICAgICAgIEluTktvOiAiMDdDMC0wN0ZGIiwKICAgICAgICBJblNhbWFyaXRhbjogIjA4MDAtMDgzRiIsCiAgICAgICAgSW5NYW5kYWljOiAiMDg0MC0wODVGIiwKICAgICAgICBJbkFyYWJpY19FeHRlbmRlZF9BOiAiMDhBMC0wOEZGIiwKICAgICAgICBJbkRldmFuYWdhcmk6ICIwOTAwLTA5N0YiLAogICAgICAgIEluQmVuZ2FsaTogIjA5ODAtMDlGRiIsCiAgICAgICAgSW5HdXJtdWtoaTogIjBBMDAtMEE3RiIsCiAgICAgICAgSW5HdWphcmF0aTogIjBBODAtMEFGRiIsCiAgICAgICAgSW5Pcml5YTogIjBCMDAtMEI3RiIsCiAgICAgICAgSW5UYW1pbDogIjBCODAtMEJGRiIsCiAgICAgICAgSW5UZWx1Z3U6ICIwQzAwLTBDN0YiLAogICAgICAgIEluS2FubmFkYTogIjBDODAtMENGRiIsCiAgICAgICAgSW5NYWxheWFsYW06ICIwRDAwLTBEN0YiLAogICAgICAgIEluU2luaGFsYTogIjBEODAtMERGRiIsCiAgICAgICAgSW5UaGFpOiAiMEUwMC0wRTdGIiwKICAgICAgICBJbkxhbzogIjBFODAtMEVGRiIsCiAgICAgICAgSW5UaWJldGFuOiAiMEYwMC0wRkZGIiwKICAgICAgICBJbk15YW5tYXI6ICIxMDAwLTEwOUYiLAogICAgICAgIEluR2VvcmdpYW46ICIxMEEwLTEwRkYiLAogICAgICAgIEluSGFuZ3VsX0phbW86ICIxMTAwLTExRkYiLAogICAgICAgIEluRXRoaW9waWM6ICIxMjAwLTEzN0YiLAogICAgICAgIEluRXRoaW9waWNfU3VwcGxlbWVudDogIjEzODAtMTM5RiIsCiAgICAgICAgSW5DaGVyb2tlZTogIjEzQTAtMTNGRiIsCiAgICAgICAgSW5VbmlmaWVkX0NhbmFkaWFuX0Fib3JpZ2luYWxfU3lsbGFiaWNzOiAiMTQwMC0xNjdGIiwKICAgICAgICBJbk9naGFtOiAiMTY4MC0xNjlGIiwKICAgICAgICBJblJ1bmljOiAiMTZBMC0xNkZGIiwKICAgICAgICBJblRhZ2Fsb2c6ICIxNzAwLTE3MUYiLAogICAgICAgIEluSGFudW5vbzogIjE3MjAtMTczRiIsCiAgICAgICAgSW5CdWhpZDogIjE3NDAtMTc1RiIsCiAgICAgICAgSW5UYWdiYW53YTogIjE3NjAtMTc3RiIsCiAgICAgICAgSW5LaG1lcjogIjE3ODAtMTdGRiIsCiAgICAgICAgSW5Nb25nb2xpYW46ICIxODAwLTE4QUYiLAogICAgICAgIEluVW5pZmllZF9DYW5hZGlhbl9BYm9yaWdpbmFsX1N5bGxhYmljc19FeHRlbmRlZDogIjE4QjAtMThGRiIsCiAgICAgICAgSW5MaW1idTogIjE5MDAtMTk0RiIsCiAgICAgICAgSW5UYWlfTGU6ICIxOTUwLTE5N0YiLAogICAgICAgIEluTmV3X1RhaV9MdWU6ICIxOTgwLTE5REYiLAogICAgICAgIEluS2htZXJfU3ltYm9sczogIjE5RTAtMTlGRiIsCiAgICAgICAgSW5CdWdpbmVzZTogIjFBMDAtMUExRiIsCiAgICAgICAgSW5UYWlfVGhhbTogIjFBMjAtMUFBRiIsCiAgICAgICAgSW5CYWxpbmVzZTogIjFCMDAtMUI3RiIsCiAgICAgICAgSW5TdW5kYW5lc2U6ICIxQjgwLTFCQkYiLAogICAgICAgIEluQmF0YWs6ICIxQkMwLTFCRkYiLAogICAgICAgIEluTGVwY2hhOiAiMUMwMC0xQzRGIiwKICAgICAgICBJbk9sX0NoaWtpOiAiMUM1MC0xQzdGIiwKICAgICAgICBJblN1bmRhbmVzZV9TdXBwbGVtZW50OiAiMUNDMC0xQ0NGIiwKICAgICAgICBJblZlZGljX0V4dGVuc2lvbnM6ICIxQ0QwLTFDRkYiLAogICAgICAgIEluUGhvbmV0aWNfRXh0ZW5zaW9uczogIjFEMDAtMUQ3RiIsCiAgICAgICAgSW5QaG9uZXRpY19FeHRlbnNpb25zX1N1cHBsZW1lbnQ6ICIxRDgwLTFEQkYiLAogICAgICAgIEluQ29tYmluaW5nX0RpYWNyaXRpY2FsX01hcmtzX1N1cHBsZW1lbnQ6ICIxREMwLTFERkYiLAogICAgICAgIEluTGF0aW5fRXh0ZW5kZWRfQWRkaXRpb25hbDogIjFFMDAtMUVGRiIsCiAgICAgICAgSW5HcmVla19FeHRlbmRlZDogIjFGMDAtMUZGRiIsCiAgICAgICAgSW5HZW5lcmFsX1B1bmN0dWF0aW9uOiAiMjAwMC0yMDZGIiwKICAgICAgICBJblN1cGVyc2NyaXB0c19hbmRfU3Vic2NyaXB0czogIjIwNzAtMjA5RiIsCiAgICAgICAgSW5DdXJyZW5jeV9TeW1ib2xzOiAiMjBBMC0yMENGIiwKICAgICAgICBJbkNvbWJpbmluZ19EaWFjcml0aWNhbF9NYXJrc19mb3JfU3ltYm9sczogIjIwRDAtMjBGRiIsCiAgICAgICAgSW5MZXR0ZXJsaWtlX1N5bWJvbHM6ICIyMTAwLTIxNEYiLAogICAgICAgIEluTnVtYmVyX0Zvcm1zOiAiMjE1MC0yMThGIiwKICAgICAgICBJbkFycm93czogIjIxOTAtMjFGRiIsCiAgICAgICAgSW5NYXRoZW1hdGljYWxfT3BlcmF0b3JzOiAiMjIwMC0yMkZGIiwKICAgICAgICBJbk1pc2NlbGxhbmVvdXNfVGVjaG5pY2FsOiAiMjMwMC0yM0ZGIiwKICAgICAgICBJbkNvbnRyb2xfUGljdHVyZXM6ICIyNDAwLTI0M0YiLAogICAgICAgIEluT3B0aWNhbF9DaGFyYWN0ZXJfUmVjb2duaXRpb246ICIyNDQwLTI0NUYiLAogICAgICAgIEluRW5jbG9zZWRfQWxwaGFudW1lcmljczogIjI0NjAtMjRGRiIsCiAgICAgICAgSW5Cb3hfRHJhd2luZzogIjI1MDAtMjU3RiIsCiAgICAgICAgSW5CbG9ja19FbGVtZW50czogIjI1ODAtMjU5RiIsCiAgICAgICAgSW5HZW9tZXRyaWNfU2hhcGVzOiAiMjVBMC0yNUZGIiwKICAgICAgICBJbk1pc2NlbGxhbmVvdXNfU3ltYm9sczogIjI2MDAtMjZGRiIsCiAgICAgICAgSW5EaW5nYmF0czogIjI3MDAtMjdCRiIsCiAgICAgICAgSW5NaXNjZWxsYW5lb3VzX01hdGhlbWF0aWNhbF9TeW1ib2xzX0E6ICIyN0MwLTI3RUYiLAogICAgICAgIEluU3VwcGxlbWVudGFsX0Fycm93c19BOiAiMjdGMC0yN0ZGIiwKICAgICAgICBJbkJyYWlsbGVfUGF0dGVybnM6ICIyODAwLTI4RkYiLAogICAgICAgIEluU3VwcGxlbWVudGFsX0Fycm93c19COiAiMjkwMC0yOTdGIiwKICAgICAgICBJbk1pc2NlbGxhbmVvdXNfTWF0aGVtYXRpY2FsX1N5bWJvbHNfQjogIjI5ODAtMjlGRiIsCiAgICAgICAgSW5TdXBwbGVtZW50YWxfTWF0aGVtYXRpY2FsX09wZXJhdG9yczogIjJBMDAtMkFGRiIsCiAgICAgICAgSW5NaXNjZWxsYW5lb3VzX1N5bWJvbHNfYW5kX0Fycm93czogIjJCMDAtMkJGRiIsCiAgICAgICAgSW5HbGFnb2xpdGljOiAiMkMwMC0yQzVGIiwKICAgICAgICBJbkxhdGluX0V4dGVuZGVkX0M6ICIyQzYwLTJDN0YiLAogICAgICAgIEluQ29wdGljOiAiMkM4MC0yQ0ZGIiwKICAgICAgICBJbkdlb3JnaWFuX1N1cHBsZW1lbnQ6ICIyRDAwLTJEMkYiLAogICAgICAgIEluVGlmaW5hZ2g6ICIyRDMwLTJEN0YiLAogICAgICAgIEluRXRoaW9waWNfRXh0ZW5kZWQ6ICIyRDgwLTJEREYiLAogICAgICAgIEluQ3lyaWxsaWNfRXh0ZW5kZWRfQTogIjJERTAtMkRGRiIsCiAgICAgICAgSW5TdXBwbGVtZW50YWxfUHVuY3R1YXRpb246ICIyRTAwLTJFN0YiLAogICAgICAgIEluQ0pLX1JhZGljYWxzX1N1cHBsZW1lbnQ6ICIyRTgwLTJFRkYiLAogICAgICAgIEluS2FuZ3hpX1JhZGljYWxzOiAiMkYwMC0yRkRGIiwKICAgICAgICBJbklkZW9ncmFwaGljX0Rlc2NyaXB0aW9uX0NoYXJhY3RlcnM6ICIyRkYwLTJGRkYiLAogICAgICAgIEluQ0pLX1N5bWJvbHNfYW5kX1B1bmN0dWF0aW9uOiAiMzAwMC0zMDNGIiwKICAgICAgICBJbkhpcmFnYW5hOiAiMzA0MC0zMDlGIiwKICAgICAgICBJbkthdGFrYW5hOiAiMzBBMC0zMEZGIiwKICAgICAgICBJbkJvcG9tb2ZvOiAiMzEwMC0zMTJGIiwKICAgICAgICBJbkhhbmd1bF9Db21wYXRpYmlsaXR5X0phbW86ICIzMTMwLTMxOEYiLAogICAgICAgIEluS2FuYnVuOiAiMzE5MC0zMTlGIiwKICAgICAgICBJbkJvcG9tb2ZvX0V4dGVuZGVkOiAiMzFBMC0zMUJGIiwKICAgICAgICBJbkNKS19TdHJva2VzOiAiMzFDMC0zMUVGIiwKICAgICAgICBJbkthdGFrYW5hX1Bob25ldGljX0V4dGVuc2lvbnM6ICIzMUYwLTMxRkYiLAogICAgICAgIEluRW5jbG9zZWRfQ0pLX0xldHRlcnNfYW5kX01vbnRoczogIjMyMDAtMzJGRiIsCiAgICAgICAgSW5DSktfQ29tcGF0aWJpbGl0eTogIjMzMDAtMzNGRiIsCiAgICAgICAgSW5DSktfVW5pZmllZF9JZGVvZ3JhcGhzX0V4dGVuc2lvbl9BOiAiMzQwMC00REJGIiwKICAgICAgICBJbllpamluZ19IZXhhZ3JhbV9TeW1ib2xzOiAiNERDMC00REZGIiwKICAgICAgICBJbkNKS19VbmlmaWVkX0lkZW9ncmFwaHM6ICI0RTAwLTlGRkYiLAogICAgICAgIEluWWlfU3lsbGFibGVzOiAiQTAwMC1BNDhGIiwKICAgICAgICBJbllpX1JhZGljYWxzOiAiQTQ5MC1BNENGIiwKICAgICAgICBJbkxpc3U6ICJBNEQwLUE0RkYiLAogICAgICAgIEluVmFpOiAiQTUwMC1BNjNGIiwKICAgICAgICBJbkN5cmlsbGljX0V4dGVuZGVkX0I6ICJBNjQwLUE2OUYiLAogICAgICAgIEluQmFtdW06ICJBNkEwLUE2RkYiLAogICAgICAgIEluTW9kaWZpZXJfVG9uZV9MZXR0ZXJzOiAiQTcwMC1BNzFGIiwKICAgICAgICBJbkxhdGluX0V4dGVuZGVkX0Q6ICJBNzIwLUE3RkYiLAogICAgICAgIEluU3lsb3RpX05hZ3JpOiAiQTgwMC1BODJGIiwKICAgICAgICBJbkNvbW1vbl9JbmRpY19OdW1iZXJfRm9ybXM6ICJBODMwLUE4M0YiLAogICAgICAgIEluUGhhZ3NfcGE6ICJBODQwLUE4N0YiLAogICAgICAgIEluU2F1cmFzaHRyYTogIkE4ODAtQThERiIsCiAgICAgICAgSW5EZXZhbmFnYXJpX0V4dGVuZGVkOiAiQThFMC1BOEZGIiwKICAgICAgICBJbktheWFoX0xpOiAiQTkwMC1BOTJGIiwKICAgICAgICBJblJlamFuZzogIkE5MzAtQTk1RiIsCiAgICAgICAgSW5IYW5ndWxfSmFtb19FeHRlbmRlZF9BOiAiQTk2MC1BOTdGIiwKICAgICAgICBJbkphdmFuZXNlOiAiQTk4MC1BOURGIiwKICAgICAgICBJbkNoYW06ICJBQTAwLUFBNUYiLAogICAgICAgIEluTXlhbm1hcl9FeHRlbmRlZF9BOiAiQUE2MC1BQTdGIiwKICAgICAgICBJblRhaV9WaWV0OiAiQUE4MC1BQURGIiwKICAgICAgICBJbk1lZXRlaV9NYXlla19FeHRlbnNpb25zOiAiQUFFMC1BQUZGIiwKICAgICAgICBJbkV0aGlvcGljX0V4dGVuZGVkX0E6ICJBQjAwLUFCMkYiLAogICAgICAgIEluTWVldGVpX01heWVrOiAiQUJDMC1BQkZGIiwKICAgICAgICBJbkhhbmd1bF9TeWxsYWJsZXM6ICJBQzAwLUQ3QUYiLAogICAgICAgIEluSGFuZ3VsX0phbW9fRXh0ZW5kZWRfQjogIkQ3QjAtRDdGRiIsCiAgICAgICAgSW5IaWdoX1N1cnJvZ2F0ZXM6ICJEODAwLURCN0YiLAogICAgICAgIEluSGlnaF9Qcml2YXRlX1VzZV9TdXJyb2dhdGVzOiAiREI4MC1EQkZGIiwKICAgICAgICBJbkxvd19TdXJyb2dhdGVzOiAiREMwMC1ERkZGIiwKICAgICAgICBJblByaXZhdGVfVXNlX0FyZWE6ICJFMDAwLUY4RkYiLAogICAgICAgIEluQ0pLX0NvbXBhdGliaWxpdHlfSWRlb2dyYXBoczogIkY5MDAtRkFGRiIsCiAgICAgICAgSW5BbHBoYWJldGljX1ByZXNlbnRhdGlvbl9Gb3JtczogIkZCMDAtRkI0RiIsCiAgICAgICAgSW5BcmFiaWNfUHJlc2VudGF0aW9uX0Zvcm1zX0E6ICJGQjUwLUZERkYiLAogICAgICAgIEluVmFyaWF0aW9uX1NlbGVjdG9yczogIkZFMDAtRkUwRiIsCiAgICAgICAgSW5WZXJ0aWNhbF9Gb3JtczogIkZFMTAtRkUxRiIsCiAgICAgICAgSW5Db21iaW5pbmdfSGFsZl9NYXJrczogIkZFMjAtRkUyRiIsCiAgICAgICAgSW5DSktfQ29tcGF0aWJpbGl0eV9Gb3JtczogIkZFMzAtRkU0RiIsCiAgICAgICAgSW5TbWFsbF9Gb3JtX1ZhcmlhbnRzOiAiRkU1MC1GRTZGIiwKICAgICAgICBJbkFyYWJpY19QcmVzZW50YXRpb25fRm9ybXNfQjogIkZFNzAtRkVGRiIsCiAgICAgICAgSW5IYWxmd2lkdGhfYW5kX0Z1bGx3aWR0aF9Gb3JtczogIkZGMDAtRkZFRiIsCiAgICAgICAgSW5TcGVjaWFsczogIkZGRjAtRkZGRiIKICAgIH0pOwoKfShYUmVnRXhwKSk7CgoKLyoqKioqIHVuaWNvZGUtcHJvcGVydGllcy5qcyAqKioqKi8KCi8qIQogKiBYUmVnRXhwIFVuaWNvZGUgUHJvcGVydGllcyB2MS4wLjAKICogKGMpIDIwMTIgU3RldmVuIExldml0aGFuIDxodHRwOi8veHJlZ2V4cC5jb20vPgogKiBNSVQgTGljZW5zZQogKiBVc2VzIFVuaWNvZGUgNi4xIDxodHRwOi8vdW5pY29kZS5vcmcvPgogKi8KCi8qKgogKiBBZGRzIFVuaWNvZGUgcHJvcGVydGllcyBuZWNlc3NhcnkgdG8gbWVldCBMZXZlbCAxIFVuaWNvZGUgc3VwcG9ydCAoZGV0YWlsZWQgaW4gVVRTIzE4IFJMMS4yKS4KICogSW5jbHVkZXMgY29kZSBwb2ludHMgZnJvbSB0aGUgQmFzaWMgTXVsdGlsaW5ndWFsIFBsYW5lIChVKzAwMDAtVStGRkZGKSBvbmx5LiBUb2tlbiBuYW1lcyBhcmUKICogY2FzZSBpbnNlbnNpdGl2ZSwgYW5kIGFueSBzcGFjZXMsIGh5cGhlbnMsIGFuZCB1bmRlcnNjb3JlcyBhcmUgaWdub3JlZC4KICogQHJlcXVpcmVzIFhSZWdFeHAsIFhSZWdFeHAgVW5pY29kZSBCYXNlCiAqLwooZnVuY3Rpb24gKFhSZWdFeHApIHsKICAgICJ1c2Ugc3RyaWN0IjsKCiAgICBpZiAoIVhSZWdFeHAuYWRkVW5pY29kZVBhY2thZ2UpIHsKICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoIlVuaWNvZGUgQmFzZSBtdXN0IGJlIGxvYWRlZCBiZWZvcmUgVW5pY29kZSBQcm9wZXJ0aWVzIik7CiAgICB9CgogICAgWFJlZ0V4cC5pbnN0YWxsKCJleHRlbnNpYmlsaXR5Iik7CgogICAgWFJlZ0V4cC5hZGRVbmljb2RlUGFja2FnZSh7CiAgICAgICAgQWxwaGFiZXRpYzogIjAwNDEtMDA1QTAwNjEtMDA3QTAwQUEwMEI1MDBCQTAwQzAtMDBENjAwRDgtMDBGNjAwRjgtMDJDMTAyQzYtMDJEMTAyRTAtMDJFNDAyRUMwMkVFMDM0NTAzNzAtMDM3NDAzNzYwMzc3MDM3QS0wMzdEMDM4NjAzODgtMDM4QTAzOEMwMzhFLTAzQTEwM0EzLTAzRjUwM0Y3LTA0ODEwNDhBLTA1MjcwNTMxLTA1NTYwNTU5MDU2MS0wNTg3MDVCMC0wNUJEMDVCRjA1QzEwNUMyMDVDNDA1QzUwNUM3MDVEMC0wNUVBMDVGMC0wNUYyMDYxMC0wNjFBMDYyMC0wNjU3MDY1OS0wNjVGMDY2RS0wNkQzMDZENS0wNkRDMDZFMS0wNkU4MDZFRC0wNkVGMDZGQS0wNkZDMDZGRjA3MTAtMDczRjA3NEQtMDdCMTA3Q0EtMDdFQTA3RjQwN0Y1MDdGQTA4MDAtMDgxNzA4MUEtMDgyQzA4NDAtMDg1ODA4QTAwOEEyLTA4QUMwOEU0LTA4RTkwOEYwLTA4RkUwOTAwLTA5M0IwOTNELTA5NEMwOTRFLTA5NTAwOTU1LTA5NjMwOTcxLTA5NzcwOTc5LTA5N0YwOTgxLTA5ODMwOTg1LTA5OEMwOThGMDk5MDA5OTMtMDlBODA5QUEtMDlCMDA5QjIwOUI2LTA5QjkwOUJELTA5QzQwOUM3MDlDODA5Q0IwOUNDMDlDRTA5RDcwOURDMDlERDA5REYtMDlFMzA5RjAwOUYxMEEwMS0wQTAzMEEwNS0wQTBBMEEwRjBBMTAwQTEzLTBBMjgwQTJBLTBBMzAwQTMyMEEzMzBBMzUwQTM2MEEzODBBMzkwQTNFLTBBNDIwQTQ3MEE0ODBBNEIwQTRDMEE1MTBBNTktMEE1QzBBNUUwQTcwLTBBNzUwQTgxLTBBODMwQTg1LTBBOEQwQThGLTBBOTEwQTkzLTBBQTgwQUFBLTBBQjAwQUIyMEFCMzBBQjUtMEFCOTBBQkQtMEFDNTBBQzctMEFDOTBBQ0IwQUNDMEFEMDBBRTAtMEFFMzBCMDEtMEIwMzBCMDUtMEIwQzBCMEYwQjEwMEIxMy0wQjI4MEIyQS0wQjMwMEIzMjBCMzMwQjM1LTBCMzkwQjNELTBCNDQwQjQ3MEI0ODBCNEIwQjRDMEI1NjBCNTcwQjVDMEI1RDBCNUYtMEI2MzBCNzEwQjgyMEI4MzBCODUtMEI4QTBCOEUtMEI5MDBCOTItMEI5NTBCOTkwQjlBMEI5QzBCOUUwQjlGMEJBMzBCQTQwQkE4LTBCQUEwQkFFLTBCQjkwQkJFLTBCQzIwQkM2LTBCQzgwQkNBLTBCQ0MwQkQwMEJENzBDMDEtMEMwMzBDMDUtMEMwQzBDMEUtMEMxMDBDMTItMEMyODBDMkEtMEMzMzBDMzUtMEMzOTBDM0QtMEM0NDBDNDYtMEM0ODBDNEEtMEM0QzBDNTUwQzU2MEM1ODBDNTkwQzYwLTBDNjMwQzgyMEM4MzBDODUtMEM4QzBDOEUtMEM5MDBDOTItMENBODBDQUEtMENCMzBDQjUtMENCOTBDQkQtMENDNDBDQzYtMENDODBDQ0EtMENDQzBDRDUwQ0Q2MENERTBDRTAtMENFMzBDRjEwQ0YyMEQwMjBEMDMwRDA1LTBEMEMwRDBFLTBEMTAwRDEyLTBEM0EwRDNELTBENDQwRDQ2LTBENDgwRDRBLTBENEMwRDRFMEQ1NzBENjAtMEQ2MzBEN0EtMEQ3RjBEODIwRDgzMEQ4NS0wRDk2MEQ5QS0wREIxMERCMy0wREJCMERCRDBEQzAtMERDNjBEQ0YtMERENDBERDYwREQ4LTBEREYwREYyMERGMzBFMDEtMEUzQTBFNDAtMEU0NjBFNEQwRTgxMEU4MjBFODQwRTg3MEU4ODBFOEEwRThEMEU5NC0wRTk3MEU5OS0wRTlGMEVBMS0wRUEzMEVBNTBFQTcwRUFBMEVBQjBFQUQtMEVCOTBFQkItMEVCRDBFQzAtMEVDNDBFQzYwRUNEMEVEQy0wRURGMEYwMDBGNDAtMEY0NzBGNDktMEY2QzBGNzEtMEY4MTBGODgtMEY5NzBGOTktMEZCQzEwMDAtMTAzNjEwMzgxMDNCLTEwM0YxMDUwLTEwNjIxMDY1LTEwNjgxMDZFLTEwODYxMDhFMTA5QzEwOUQxMEEwLTEwQzUxMEM3MTBDRDEwRDAtMTBGQTEwRkMtMTI0ODEyNEEtMTI0RDEyNTAtMTI1NjEyNTgxMjVBLTEyNUQxMjYwLTEyODgxMjhBLTEyOEQxMjkwLTEyQjAxMkIyLTEyQjUxMkI4LTEyQkUxMkMwMTJDMi0xMkM1MTJDOC0xMkQ2MTJEOC0xMzEwMTMxMi0xMzE1MTMxOC0xMzVBMTM1RjEzODAtMTM4RjEzQTAtMTNGNDE0MDEtMTY2QzE2NkYtMTY3RjE2ODEtMTY5QTE2QTAtMTZFQTE2RUUtMTZGMDE3MDAtMTcwQzE3MEUtMTcxMzE3MjAtMTczMzE3NDAtMTc1MzE3NjAtMTc2QzE3NkUtMTc3MDE3NzIxNzczMTc4MC0xN0IzMTdCNi0xN0M4MTdENzE3REMxODIwLTE4NzcxODgwLTE4QUExOEIwLTE4RjUxOTAwLTE5MUMxOTIwLTE5MkIxOTMwLTE5MzgxOTUwLTE5NkQxOTcwLTE5NzQxOTgwLTE5QUIxOUIwLTE5QzkxQTAwLTFBMUIxQTIwLTFBNUUxQTYxLTFBNzQxQUE3MUIwMC0xQjMzMUIzNS0xQjQzMUI0NS0xQjRCMUI4MC0xQkE5MUJBQy0xQkFGMUJCQS0xQkU1MUJFNy0xQkYxMUMwMC0xQzM1MUM0RC0xQzRGMUM1QS0xQzdEMUNFOS0xQ0VDMUNFRS0xQ0YzMUNGNTFDRjYxRDAwLTFEQkYxRTAwLTFGMTUxRjE4LTFGMUQxRjIwLTFGNDUxRjQ4LTFGNEQxRjUwLTFGNTcxRjU5MUY1QjFGNUQxRjVGLTFGN0QxRjgwLTFGQjQxRkI2LTFGQkMxRkJFMUZDMi0xRkM0MUZDNi0xRkNDMUZEMC0xRkQzMUZENi0xRkRCMUZFMC0xRkVDMUZGMi0xRkY0MUZGNi0xRkZDMjA3MTIwN0YyMDkwLTIwOUMyMTAyMjEwNzIxMEEtMjExMzIxMTUyMTE5LTIxMUQyMTI0MjEyNjIxMjgyMTJBLTIxMkQyMTJGLTIxMzkyMTNDLTIxM0YyMTQ1LTIxNDkyMTRFMjE2MC0yMTg4MjRCNi0yNEU5MkMwMC0yQzJFMkMzMC0yQzVFMkM2MC0yQ0U0MkNFQi0yQ0VFMkNGMjJDRjMyRDAwLTJEMjUyRDI3MkQyRDJEMzAtMkQ2NzJENkYyRDgwLTJEOTYyREEwLTJEQTYyREE4LTJEQUUyREIwLTJEQjYyREI4LTJEQkUyREMwLTJEQzYyREM4LTJEQ0UyREQwLTJERDYyREQ4LTJEREUyREUwLTJERkYyRTJGMzAwNS0zMDA3MzAyMS0zMDI5MzAzMS0zMDM1MzAzOC0zMDNDMzA0MS0zMDk2MzA5RC0zMDlGMzBBMS0zMEZBMzBGQy0zMEZGMzEwNS0zMTJEMzEzMS0zMThFMzFBMC0zMUJBMzFGMC0zMUZGMzQwMC00REI1NEUwMC05RkNDQTAwMC1BNDhDQTREMC1BNEZEQTUwMC1BNjBDQTYxMC1BNjFGQTYyQUE2MkJBNjQwLUE2NkVBNjc0LUE2N0JBNjdGLUE2OTdBNjlGLUE2RUZBNzE3LUE3MUZBNzIyLUE3ODhBNzhCLUE3OEVBNzkwLUE3OTNBN0EwLUE3QUFBN0Y4LUE4MDFBODAzLUE4MDVBODA3LUE4MEFBODBDLUE4MjdBODQwLUE4NzNBODgwLUE4QzNBOEYyLUE4RjdBOEZCQTkwQS1BOTJBQTkzMC1BOTUyQTk2MC1BOTdDQTk4MC1BOUIyQTlCNC1BOUJGQTlDRkFBMDAtQUEzNkFBNDAtQUE0REFBNjAtQUE3NkFBN0FBQTgwLUFBQkVBQUMwQUFDMkFBREItQUFEREFBRTAtQUFFRkFBRjItQUFGNUFCMDEtQUIwNkFCMDktQUIwRUFCMTEtQUIxNkFCMjAtQUIyNkFCMjgtQUIyRUFCQzAtQUJFQUFDMDAtRDdBM0Q3QjAtRDdDNkQ3Q0ItRDdGQkY5MDAtRkE2REZBNzAtRkFEOUZCMDAtRkIwNkZCMTMtRkIxN0ZCMUQtRkIyOEZCMkEtRkIzNkZCMzgtRkIzQ0ZCM0VGQjQwRkI0MUZCNDNGQjQ0RkI0Ni1GQkIxRkJEMy1GRDNERkQ1MC1GRDhGRkQ5Mi1GREM3RkRGMC1GREZCRkU3MC1GRTc0RkU3Ni1GRUZDRkYyMS1GRjNBRkY0MS1GRjVBRkY2Ni1GRkJFRkZDMi1GRkM3RkZDQS1GRkNGRkZEMi1GRkQ3RkZEQS1GRkRDIiwKICAgICAgICBVcHBlcmNhc2U6ICIwMDQxLTAwNUEwMEMwLTAwRDYwMEQ4LTAwREUwMTAwMDEwMjAxMDQwMTA2MDEwODAxMEEwMTBDMDEwRTAxMTAwMTEyMDExNDAxMTYwMTE4MDExQTAxMUMwMTFFMDEyMDAxMjIwMTI0MDEyNjAxMjgwMTJBMDEyQzAxMkUwMTMwMDEzMjAxMzQwMTM2MDEzOTAxM0IwMTNEMDEzRjAxNDEwMTQzMDE0NTAxNDcwMTRBMDE0QzAxNEUwMTUwMDE1MjAxNTQwMTU2MDE1ODAxNUEwMTVDMDE1RTAxNjAwMTYyMDE2NDAxNjYwMTY4MDE2QTAxNkMwMTZFMDE3MDAxNzIwMTc0MDE3NjAxNzgwMTc5MDE3QjAxN0QwMTgxMDE4MjAxODQwMTg2MDE4NzAxODktMDE4QjAxOEUtMDE5MTAxOTMwMTk0MDE5Ni0wMTk4MDE5QzAxOUQwMTlGMDFBMDAxQTIwMUE0MDFBNjAxQTcwMUE5MDFBQzAxQUUwMUFGMDFCMS0wMUIzMDFCNTAxQjcwMUI4MDFCQzAxQzQwMUM3MDFDQTAxQ0QwMUNGMDFEMTAxRDMwMUQ1MDFENzAxRDkwMURCMDFERTAxRTAwMUUyMDFFNDAxRTYwMUU4MDFFQTAxRUMwMUVFMDFGMTAxRjQwMUY2LTAxRjgwMUZBMDFGQzAxRkUwMjAwMDIwMjAyMDQwMjA2MDIwODAyMEEwMjBDMDIwRTAyMTAwMjEyMDIxNDAyMTYwMjE4MDIxQTAyMUMwMjFFMDIyMDAyMjIwMjI0MDIyNjAyMjgwMjJBMDIyQzAyMkUwMjMwMDIzMjAyM0EwMjNCMDIzRDAyM0UwMjQxMDI0My0wMjQ2MDI0ODAyNEEwMjRDMDI0RTAzNzAwMzcyMDM3NjAzODYwMzg4LTAzOEEwMzhDMDM4RTAzOEYwMzkxLTAzQTEwM0EzLTAzQUIwM0NGMDNEMi0wM0Q0MDNEODAzREEwM0RDMDNERTAzRTAwM0UyMDNFNDAzRTYwM0U4MDNFQTAzRUMwM0VFMDNGNDAzRjcwM0Y5MDNGQTAzRkQtMDQyRjA0NjAwNDYyMDQ2NDA0NjYwNDY4MDQ2QTA0NkMwNDZFMDQ3MDA0NzIwNDc0MDQ3NjA0NzgwNDdBMDQ3QzA0N0UwNDgwMDQ4QTA0OEMwNDhFMDQ5MDA0OTIwNDk0MDQ5NjA0OTgwNDlBMDQ5QzA0OUUwNEEwMDRBMjA0QTQwNEE2MDRBODA0QUEwNEFDMDRBRTA0QjAwNEIyMDRCNDA0QjYwNEI4MDRCQTA0QkMwNEJFMDRDMDA0QzEwNEMzMDRDNTA0QzcwNEM5MDRDQjA0Q0QwNEQwMDREMjA0RDQwNEQ2MDREODA0REEwNERDMDRERTA0RTAwNEUyMDRFNDA0RTYwNEU4MDRFQTA0RUMwNEVFMDRGMDA0RjIwNEY0MDRGNjA0RjgwNEZBMDRGQzA0RkUwNTAwMDUwMjA1MDQwNTA2MDUwODA1MEEwNTBDMDUwRTA1MTAwNTEyMDUxNDA1MTYwNTE4MDUxQTA1MUMwNTFFMDUyMDA1MjIwNTI0MDUyNjA1MzEtMDU1NjEwQTAtMTBDNTEwQzcxMENEMUUwMDFFMDIxRTA0MUUwNjFFMDgxRTBBMUUwQzFFMEUxRTEwMUUxMjFFMTQxRTE2MUUxODFFMUExRTFDMUUxRTFFMjAxRTIyMUUyNDFFMjYxRTI4MUUyQTFFMkMxRTJFMUUzMDFFMzIxRTM0MUUzNjFFMzgxRTNBMUUzQzFFM0UxRTQwMUU0MjFFNDQxRTQ2MUU0ODFFNEExRTRDMUU0RTFFNTAxRTUyMUU1NDFFNTYxRTU4MUU1QTFFNUMxRTVFMUU2MDFFNjIxRTY0MUU2NjFFNjgxRTZBMUU2QzFFNkUxRTcwMUU3MjFFNzQxRTc2MUU3ODFFN0ExRTdDMUU3RTFFODAxRTgyMUU4NDFFODYxRTg4MUU4QTFFOEMxRThFMUU5MDFFOTIxRTk0MUU5RTFFQTAxRUEyMUVBNDFFQTYxRUE4MUVBQTFFQUMxRUFFMUVCMDFFQjIxRUI0MUVCNjFFQjgxRUJBMUVCQzFFQkUxRUMwMUVDMjFFQzQxRUM2MUVDODFFQ0ExRUNDMUVDRTFFRDAxRUQyMUVENDFFRDYxRUQ4MUVEQTFFREMxRURFMUVFMDFFRTIxRUU0MUVFNjFFRTgxRUVBMUVFQzFFRUUxRUYwMUVGMjFFRjQxRUY2MUVGODFFRkExRUZDMUVGRTFGMDgtMUYwRjFGMTgtMUYxRDFGMjgtMUYyRjFGMzgtMUYzRjFGNDgtMUY0RDFGNTkxRjVCMUY1RDFGNUYxRjY4LTFGNkYxRkI4LTFGQkIxRkM4LTFGQ0IxRkQ4LTFGREIxRkU4LTFGRUMxRkY4LTFGRkIyMTAyMjEwNzIxMEItMjEwRDIxMTAtMjExMjIxMTUyMTE5LTIxMUQyMTI0MjEyNjIxMjgyMTJBLTIxMkQyMTMwLTIxMzMyMTNFMjEzRjIxNDUyMTYwLTIxNkYyMTgzMjRCNi0yNENGMkMwMC0yQzJFMkM2MDJDNjItMkM2NDJDNjcyQzY5MkM2QjJDNkQtMkM3MDJDNzIyQzc1MkM3RS0yQzgwMkM4MjJDODQyQzg2MkM4ODJDOEEyQzhDMkM4RTJDOTAyQzkyMkM5NDJDOTYyQzk4MkM5QTJDOUMyQzlFMkNBMDJDQTIyQ0E0MkNBNjJDQTgyQ0FBMkNBQzJDQUUyQ0IwMkNCMjJDQjQyQ0I2MkNCODJDQkEyQ0JDMkNCRTJDQzAyQ0MyMkNDNDJDQzYyQ0M4MkNDQTJDQ0MyQ0NFMkNEMDJDRDIyQ0Q0MkNENjJDRDgyQ0RBMkNEQzJDREUyQ0UwMkNFMjJDRUIyQ0VEMkNGMkE2NDBBNjQyQTY0NEE2NDZBNjQ4QTY0QUE2NENBNjRFQTY1MEE2NTJBNjU0QTY1NkE2NThBNjVBQTY1Q0E2NUVBNjYwQTY2MkE2NjRBNjY2QTY2OEE2NkFBNjZDQTY4MEE2ODJBNjg0QTY4NkE2ODhBNjhBQTY4Q0E2OEVBNjkwQTY5MkE2OTRBNjk2QTcyMkE3MjRBNzI2QTcyOEE3MkFBNzJDQTcyRUE3MzJBNzM0QTczNkE3MzhBNzNBQTczQ0E3M0VBNzQwQTc0MkE3NDRBNzQ2QTc0OEE3NEFBNzRDQTc0RUE3NTBBNzUyQTc1NEE3NTZBNzU4QTc1QUE3NUNBNzVFQTc2MEE3NjJBNzY0QTc2NkE3NjhBNzZBQTc2Q0E3NkVBNzc5QTc3QkE3N0RBNzdFQTc4MEE3ODJBNzg0QTc4NkE3OEJBNzhEQTc5MEE3OTJBN0EwQTdBMkE3QTRBN0E2QTdBOEE3QUFGRjIxLUZGM0EiLAogICAgICAgIExvd2VyY2FzZTogIjAwNjEtMDA3QTAwQUEwMEI1MDBCQTAwREYtMDBGNjAwRjgtMDBGRjAxMDEwMTAzMDEwNTAxMDcwMTA5MDEwQjAxMEQwMTBGMDExMTAxMTMwMTE1MDExNzAxMTkwMTFCMDExRDAxMUYwMTIxMDEyMzAxMjUwMTI3MDEyOTAxMkIwMTJEMDEyRjAxMzEwMTMzMDEzNTAxMzcwMTM4MDEzQTAxM0MwMTNFMDE0MDAxNDIwMTQ0MDE0NjAxNDgwMTQ5MDE0QjAxNEQwMTRGMDE1MTAxNTMwMTU1MDE1NzAxNTkwMTVCMDE1RDAxNUYwMTYxMDE2MzAxNjUwMTY3MDE2OTAxNkIwMTZEMDE2RjAxNzEwMTczMDE3NTAxNzcwMTdBMDE3QzAxN0UtMDE4MDAxODMwMTg1MDE4ODAxOEMwMThEMDE5MjAxOTUwMTk5LTAxOUIwMTlFMDFBMTAxQTMwMUE1MDFBODAxQUEwMUFCMDFBRDAxQjAwMUI0MDFCNjAxQjkwMUJBMDFCRC0wMUJGMDFDNjAxQzkwMUNDMDFDRTAxRDAwMUQyMDFENDAxRDYwMUQ4MDFEQTAxREMwMUREMDFERjAxRTEwMUUzMDFFNTAxRTcwMUU5MDFFQjAxRUQwMUVGMDFGMDAxRjMwMUY1MDFGOTAxRkIwMUZEMDFGRjAyMDEwMjAzMDIwNTAyMDcwMjA5MDIwQjAyMEQwMjBGMDIxMTAyMTMwMjE1MDIxNzAyMTkwMjFCMDIxRDAyMUYwMjIxMDIyMzAyMjUwMjI3MDIyOTAyMkIwMjJEMDIyRjAyMzEwMjMzLTAyMzkwMjNDMDIzRjAyNDAwMjQyMDI0NzAyNDkwMjRCMDI0RDAyNEYtMDI5MzAyOTUtMDJCODAyQzAwMkMxMDJFMC0wMkU0MDM0NTAzNzEwMzczMDM3NzAzN0EtMDM3RDAzOTAwM0FDLTAzQ0UwM0QwMDNEMTAzRDUtMDNENzAzRDkwM0RCMDNERDAzREYwM0UxMDNFMzAzRTUwM0U3MDNFOTAzRUIwM0VEMDNFRi0wM0YzMDNGNTAzRjgwM0ZCMDNGQzA0MzAtMDQ1RjA0NjEwNDYzMDQ2NTA0NjcwNDY5MDQ2QjA0NkQwNDZGMDQ3MTA0NzMwNDc1MDQ3NzA0NzkwNDdCMDQ3RDA0N0YwNDgxMDQ4QjA0OEQwNDhGMDQ5MTA0OTMwNDk1MDQ5NzA0OTkwNDlCMDQ5RDA0OUYwNEExMDRBMzA0QTUwNEE3MDRBOTA0QUIwNEFEMDRBRjA0QjEwNEIzMDRCNTA0QjcwNEI5MDRCQjA0QkQwNEJGMDRDMjA0QzQwNEM2MDRDODA0Q0EwNENDMDRDRTA0Q0YwNEQxMDREMzA0RDUwNEQ3MDREOTA0REIwNEREMDRERjA0RTEwNEUzMDRFNTA0RTcwNEU5MDRFQjA0RUQwNEVGMDRGMTA0RjMwNEY1MDRGNzA0RjkwNEZCMDRGRDA0RkYwNTAxMDUwMzA1MDUwNTA3MDUwOTA1MEIwNTBEMDUwRjA1MTEwNTEzMDUxNTA1MTcwNTE5MDUxQjA1MUQwNTFGMDUyMTA1MjMwNTI1MDUyNzA1NjEtMDU4NzFEMDAtMURCRjFFMDExRTAzMUUwNTFFMDcxRTA5MUUwQjFFMEQxRTBGMUUxMTFFMTMxRTE1MUUxNzFFMTkxRTFCMUUxRDFFMUYxRTIxMUUyMzFFMjUxRTI3MUUyOTFFMkIxRTJEMUUyRjFFMzExRTMzMUUzNTFFMzcxRTM5MUUzQjFFM0QxRTNGMUU0MTFFNDMxRTQ1MUU0NzFFNDkxRTRCMUU0RDFFNEYxRTUxMUU1MzFFNTUxRTU3MUU1OTFFNUIxRTVEMUU1RjFFNjExRTYzMUU2NTFFNjcxRTY5MUU2QjFFNkQxRTZGMUU3MTFFNzMxRTc1MUU3NzFFNzkxRTdCMUU3RDFFN0YxRTgxMUU4MzFFODUxRTg3MUU4OTFFOEIxRThEMUU4RjFFOTExRTkzMUU5NS0xRTlEMUU5RjFFQTExRUEzMUVBNTFFQTcxRUE5MUVBQjFFQUQxRUFGMUVCMTFFQjMxRUI1MUVCNzFFQjkxRUJCMUVCRDFFQkYxRUMxMUVDMzFFQzUxRUM3MUVDOTFFQ0IxRUNEMUVDRjFFRDExRUQzMUVENTFFRDcxRUQ5MUVEQjFFREQxRURGMUVFMTFFRTMxRUU1MUVFNzFFRTkxRUVCMUVFRDFFRUYxRUYxMUVGMzFFRjUxRUY3MUVGOTFFRkIxRUZEMUVGRi0xRjA3MUYxMC0xRjE1MUYyMC0xRjI3MUYzMC0xRjM3MUY0MC0xRjQ1MUY1MC0xRjU3MUY2MC0xRjY3MUY3MC0xRjdEMUY4MC0xRjg3MUY5MC0xRjk3MUZBMC0xRkE3MUZCMC0xRkI0MUZCNjFGQjcxRkJFMUZDMi0xRkM0MUZDNjFGQzcxRkQwLTFGRDMxRkQ2MUZENzFGRTAtMUZFNzFGRjItMUZGNDFGRjYxRkY3MjA3MTIwN0YyMDkwLTIwOUMyMTBBMjEwRTIxMEYyMTEzMjEyRjIxMzQyMTM5MjEzQzIxM0QyMTQ2LTIxNDkyMTRFMjE3MC0yMTdGMjE4NDI0RDAtMjRFOTJDMzAtMkM1RTJDNjEyQzY1MkM2NjJDNjgyQzZBMkM2QzJDNzEyQzczMkM3NDJDNzYtMkM3RDJDODEyQzgzMkM4NTJDODcyQzg5MkM4QjJDOEQyQzhGMkM5MTJDOTMyQzk1MkM5NzJDOTkyQzlCMkM5RDJDOUYyQ0ExMkNBMzJDQTUyQ0E3MkNBOTJDQUIyQ0FEMkNBRjJDQjEyQ0IzMkNCNTJDQjcyQ0I5MkNCQjJDQkQyQ0JGMkNDMTJDQzMyQ0M1MkNDNzJDQzkyQ0NCMkNDRDJDQ0YyQ0QxMkNEMzJDRDUyQ0Q3MkNEOTJDREIyQ0REMkNERjJDRTEyQ0UzMkNFNDJDRUMyQ0VFMkNGMzJEMDAtMkQyNTJEMjcyRDJEQTY0MUE2NDNBNjQ1QTY0N0E2NDlBNjRCQTY0REE2NEZBNjUxQTY1M0E2NTVBNjU3QTY1OUE2NUJBNjVEQTY1RkE2NjFBNjYzQTY2NUE2NjdBNjY5QTY2QkE2NkRBNjgxQTY4M0E2ODVBNjg3QTY4OUE2OEJBNjhEQTY4RkE2OTFBNjkzQTY5NUE2OTdBNzIzQTcyNUE3MjdBNzI5QTcyQkE3MkRBNzJGLUE3MzFBNzMzQTczNUE3MzdBNzM5QTczQkE3M0RBNzNGQTc0MUE3NDNBNzQ1QTc0N0E3NDlBNzRCQTc0REE3NEZBNzUxQTc1M0E3NTVBNzU3QTc1OUE3NUJBNzVEQTc1RkE3NjFBNzYzQTc2NUE3NjdBNzY5QTc2QkE3NkRBNzZGLUE3NzhBNzdBQTc3Q0E3N0ZBNzgxQTc4M0E3ODVBNzg3QTc4Q0E3OEVBNzkxQTc5M0E3QTFBN0EzQTdBNUE3QTdBN0E5QTdGOC1BN0ZBRkIwMC1GQjA2RkIxMy1GQjE3RkY0MS1GRjVBIiwKICAgICAgICBXaGl0ZV9TcGFjZTogIjAwMDktMDAwRDAwMjAwMDg1MDBBMDE2ODAxODBFMjAwMC0yMDBBMjAyODIwMjkyMDJGMjA1RjMwMDAiLAogICAgICAgIE5vbmNoYXJhY3Rlcl9Db2RlX1BvaW50OiAiRkREMC1GREVGRkZGRUZGRkYiLAogICAgICAgIERlZmF1bHRfSWdub3JhYmxlX0NvZGVfUG9pbnQ6ICIwMEFEMDM0RjExNUYxMTYwMTdCNDE3QjUxODBCLTE4MEQyMDBCLTIwMEYyMDJBLTIwMkUyMDYwLTIwNkYzMTY0RkUwMC1GRTBGRkVGRkZGQTBGRkYwLUZGRjgiLAogICAgICAgIC8vIFxwe0FueX0gbWF0Y2hlcyBhIGNvZGUgdW5pdC4gVG8gbWF0Y2ggYW55IGNvZGUgcG9pbnQgdmlhIHN1cnJvZ2F0ZSBwYWlycywgdXNlICg/OltcMC1cdUQ3RkZcdURDMDAtXHVGRkZGXXxbXHVEODAwLVx1REJGRl1bXHVEQzAwLVx1REZGRl18W1x1RDgwMC1cdURCRkZdKQogICAgICAgIEFueTogIjAwMDAtRkZGRiIsIC8vIFxwe15Bbnl9IGNvbXBpbGVzIHRvIFteXHUwMDAwLVx1RkZGRl07IFtccHteQW55fV0gdG8gW10KICAgICAgICBBc2NpaTogIjAwMDAtMDA3RiIsCiAgICAgICAgLy8gXHB7QXNzaWduZWR9IGlzIGVxdWl2YWxlbnQgdG8gXHB7XkNufQogICAgICAgIC8vQXNzaWduZWQ6IFhSZWdFeHAoIltcXHB7XkNufV0iKS5zb3VyY2UucmVwbGFjZSgvW1tcXV18XFx1L2csICIiKSAvLyBOZWdhdGlvbiBpbnNpZGUgYSBjaGFyYWN0ZXIgY2xhc3MgdHJpZ2dlcnMgaW52ZXJzaW9uCiAgICAgICAgQXNzaWduZWQ6ICIwMDAwLTAzNzcwMzdBLTAzN0UwMzg0LTAzOEEwMzhDMDM4RS0wM0ExMDNBMy0wNTI3MDUzMS0wNTU2MDU1OS0wNTVGMDU2MS0wNTg3MDU4OTA1OEEwNThGMDU5MS0wNUM3MDVEMC0wNUVBMDVGMC0wNUY0MDYwMC0wNjA0MDYwNi0wNjFCMDYxRS0wNzBEMDcwRi0wNzRBMDc0RC0wN0IxMDdDMC0wN0ZBMDgwMC0wODJEMDgzMC0wODNFMDg0MC0wODVCMDg1RTA4QTAwOEEyLTA4QUMwOEU0LTA4RkUwOTAwLTA5NzcwOTc5LTA5N0YwOTgxLTA5ODMwOTg1LTA5OEMwOThGMDk5MDA5OTMtMDlBODA5QUEtMDlCMDA5QjIwOUI2LTA5QjkwOUJDLTA5QzQwOUM3MDlDODA5Q0ItMDlDRTA5RDcwOURDMDlERDA5REYtMDlFMzA5RTYtMDlGQjBBMDEtMEEwMzBBMDUtMEEwQTBBMEYwQTEwMEExMy0wQTI4MEEyQS0wQTMwMEEzMjBBMzMwQTM1MEEzNjBBMzgwQTM5MEEzQzBBM0UtMEE0MjBBNDcwQTQ4MEE0Qi0wQTREMEE1MTBBNTktMEE1QzBBNUUwQTY2LTBBNzUwQTgxLTBBODMwQTg1LTBBOEQwQThGLTBBOTEwQTkzLTBBQTgwQUFBLTBBQjAwQUIyMEFCMzBBQjUtMEFCOTBBQkMtMEFDNTBBQzctMEFDOTBBQ0ItMEFDRDBBRDAwQUUwLTBBRTMwQUU2LTBBRjEwQjAxLTBCMDMwQjA1LTBCMEMwQjBGMEIxMDBCMTMtMEIyODBCMkEtMEIzMDBCMzIwQjMzMEIzNS0wQjM5MEIzQy0wQjQ0MEI0NzBCNDgwQjRCLTBCNEQwQjU2MEI1NzBCNUMwQjVEMEI1Ri0wQjYzMEI2Ni0wQjc3MEI4MjBCODMwQjg1LTBCOEEwQjhFLTBCOTAwQjkyLTBCOTUwQjk5MEI5QTBCOUMwQjlFMEI5RjBCQTMwQkE0MEJBOC0wQkFBMEJBRS0wQkI5MEJCRS0wQkMyMEJDNi0wQkM4MEJDQS0wQkNEMEJEMDBCRDcwQkU2LTBCRkEwQzAxLTBDMDMwQzA1LTBDMEMwQzBFLTBDMTAwQzEyLTBDMjgwQzJBLTBDMzMwQzM1LTBDMzkwQzNELTBDNDQwQzQ2LTBDNDgwQzRBLTBDNEQwQzU1MEM1NjBDNTgwQzU5MEM2MC0wQzYzMEM2Ni0wQzZGMEM3OC0wQzdGMEM4MjBDODMwQzg1LTBDOEMwQzhFLTBDOTAwQzkyLTBDQTgwQ0FBLTBDQjMwQ0I1LTBDQjkwQ0JDLTBDQzQwQ0M2LTBDQzgwQ0NBLTBDQ0QwQ0Q1MENENjBDREUwQ0UwLTBDRTMwQ0U2LTBDRUYwQ0YxMENGMjBEMDIwRDAzMEQwNS0wRDBDMEQwRS0wRDEwMEQxMi0wRDNBMEQzRC0wRDQ0MEQ0Ni0wRDQ4MEQ0QS0wRDRFMEQ1NzBENjAtMEQ2MzBENjYtMEQ3NTBENzktMEQ3RjBEODIwRDgzMEQ4NS0wRDk2MEQ5QS0wREIxMERCMy0wREJCMERCRDBEQzAtMERDNjBEQ0EwRENGLTBERDQwREQ2MEREOC0wRERGMERGMi0wREY0MEUwMS0wRTNBMEUzRi0wRTVCMEU4MTBFODIwRTg0MEU4NzBFODgwRThBMEU4RDBFOTQtMEU5NzBFOTktMEU5RjBFQTEtMEVBMzBFQTUwRUE3MEVBQTBFQUIwRUFELTBFQjkwRUJCLTBFQkQwRUMwLTBFQzQwRUM2MEVDOC0wRUNEMEVEMC0wRUQ5MEVEQy0wRURGMEYwMC0wRjQ3MEY0OS0wRjZDMEY3MS0wRjk3MEY5OS0wRkJDMEZCRS0wRkNDMEZDRS0wRkRBMTAwMC0xMEM1MTBDNzEwQ0QxMEQwLTEyNDgxMjRBLTEyNEQxMjUwLTEyNTYxMjU4MTI1QS0xMjVEMTI2MC0xMjg4MTI4QS0xMjhEMTI5MC0xMkIwMTJCMi0xMkI1MTJCOC0xMkJFMTJDMDEyQzItMTJDNTEyQzgtMTJENjEyRDgtMTMxMDEzMTItMTMxNTEzMTgtMTM1QTEzNUQtMTM3QzEzODAtMTM5OTEzQTAtMTNGNDE0MDAtMTY5QzE2QTAtMTZGMDE3MDAtMTcwQzE3MEUtMTcxNDE3MjAtMTczNjE3NDAtMTc1MzE3NjAtMTc2QzE3NkUtMTc3MDE3NzIxNzczMTc4MC0xN0REMTdFMC0xN0U5MTdGMC0xN0Y5MTgwMC0xODBFMTgxMC0xODE5MTgyMC0xODc3MTg4MC0xOEFBMThCMC0xOEY1MTkwMC0xOTFDMTkyMC0xOTJCMTkzMC0xOTNCMTk0MDE5NDQtMTk2RDE5NzAtMTk3NDE5ODAtMTlBQjE5QjAtMTlDOTE5RDAtMTlEQTE5REUtMUExQjFBMUUtMUE1RTFBNjAtMUE3QzFBN0YtMUE4OTFBOTAtMUE5OTFBQTAtMUFBRDFCMDAtMUI0QjFCNTAtMUI3QzFCODAtMUJGMzFCRkMtMUMzNzFDM0ItMUM0OTFDNEQtMUM3RjFDQzAtMUNDNzFDRDAtMUNGNjFEMDAtMURFNjFERkMtMUYxNTFGMTgtMUYxRDFGMjAtMUY0NTFGNDgtMUY0RDFGNTAtMUY1NzFGNTkxRjVCMUY1RDFGNUYtMUY3RDFGODAtMUZCNDFGQjYtMUZDNDFGQzYtMUZEMzFGRDYtMUZEQjFGREQtMUZFRjFGRjItMUZGNDFGRjYtMUZGRTIwMDAtMjA2NDIwNkEtMjA3MTIwNzQtMjA4RTIwOTAtMjA5QzIwQTAtMjBCOTIwRDAtMjBGMDIxMDAtMjE4OTIxOTAtMjNGMzI0MDAtMjQyNjI0NDAtMjQ0QTI0NjAtMjZGRjI3MDEtMkI0QzJCNTAtMkI1OTJDMDAtMkMyRTJDMzAtMkM1RTJDNjAtMkNGMzJDRjktMkQyNTJEMjcyRDJEMkQzMC0yRDY3MkQ2RjJENzAyRDdGLTJEOTYyREEwLTJEQTYyREE4LTJEQUUyREIwLTJEQjYyREI4LTJEQkUyREMwLTJEQzYyREM4LTJEQ0UyREQwLTJERDYyREQ4LTJEREUyREUwLTJFM0IyRTgwLTJFOTkyRTlCLTJFRjMyRjAwLTJGRDUyRkYwLTJGRkIzMDAwLTMwM0YzMDQxLTMwOTYzMDk5LTMwRkYzMTA1LTMxMkQzMTMxLTMxOEUzMTkwLTMxQkEzMUMwLTMxRTMzMUYwLTMyMUUzMjIwLTMyRkUzMzAwLTREQjU0REMwLTlGQ0NBMDAwLUE0OENBNDkwLUE0QzZBNEQwLUE2MkJBNjQwLUE2OTdBNjlGLUE2RjdBNzAwLUE3OEVBNzkwLUE3OTNBN0EwLUE3QUFBN0Y4LUE4MkJBODMwLUE4MzlBODQwLUE4NzdBODgwLUE4QzRBOENFLUE4RDlBOEUwLUE4RkJBOTAwLUE5NTNBOTVGLUE5N0NBOTgwLUE5Q0RBOUNGLUE5RDlBOURFQTlERkFBMDAtQUEzNkFBNDAtQUE0REFBNTAtQUE1OUFBNUMtQUE3QkFBODAtQUFDMkFBREItQUFGNkFCMDEtQUIwNkFCMDktQUIwRUFCMTEtQUIxNkFCMjAtQUIyNkFCMjgtQUIyRUFCQzAtQUJFREFCRjAtQUJGOUFDMDAtRDdBM0Q3QjAtRDdDNkQ3Q0ItRDdGQkQ4MDAtRkE2REZBNzAtRkFEOUZCMDAtRkIwNkZCMTMtRkIxN0ZCMUQtRkIzNkZCMzgtRkIzQ0ZCM0VGQjQwRkI0MUZCNDNGQjQ0RkI0Ni1GQkMxRkJEMy1GRDNGRkQ1MC1GRDhGRkQ5Mi1GREM3RkRGMC1GREZERkUwMC1GRTE5RkUyMC1GRTI2RkUzMC1GRTUyRkU1NC1GRTY2RkU2OC1GRTZCRkU3MC1GRTc0RkU3Ni1GRUZDRkVGRkZGMDEtRkZCRUZGQzItRkZDN0ZGQ0EtRkZDRkZGRDItRkZEN0ZGREEtRkZEQ0ZGRTAtRkZFNkZGRTgtRkZFRUZGRjktRkZGRCIKICAgIH0pOwoKfShYUmVnRXhwKSk7CgoKLyoqKioqIG1hdGNocmVjdXJzaXZlLmpzICoqKioqLwoKLyohCiAqIFhSZWdFeHAubWF0Y2hSZWN1cnNpdmUgdjAuMi4wCiAqIChjKSAyMDA5LTIwMTIgU3RldmVuIExldml0aGFuIDxodHRwOi8veHJlZ2V4cC5jb20vPgogKiBNSVQgTGljZW5zZQogKi8KCihmdW5jdGlvbiAoWFJlZ0V4cCkgewogICAgInVzZSBzdHJpY3QiOwoKLyoqCiAqIFJldHVybnMgYSBtYXRjaCBkZXRhaWwgb2JqZWN0IGNvbXBvc2VkIG9mIHRoZSBwcm92aWRlZCB2YWx1ZXMuCiAqIEBwcml2YXRlCiAqLwogICAgZnVuY3Rpb24gcm93KHZhbHVlLCBuYW1lLCBzdGFydCwgZW5kKSB7CiAgICAgICAgcmV0dXJuIHt2YWx1ZTp2YWx1ZSwgbmFtZTpuYW1lLCBzdGFydDpzdGFydCwgZW5kOmVuZH07CiAgICB9CgovKioKICogUmV0dXJucyBhbiBhcnJheSBvZiBtYXRjaCBzdHJpbmdzIGJldHdlZW4gb3V0ZXJtb3N0IGxlZnQgYW5kIHJpZ2h0IGRlbGltaXRlcnMsIG9yIGFuIGFycmF5IG9mCiAqIG9iamVjdHMgd2l0aCBkZXRhaWxlZCBtYXRjaCBwYXJ0cyBhbmQgcG9zaXRpb24gZGF0YS4gQW4gZXJyb3IgaXMgdGhyb3duIGlmIGRlbGltaXRlcnMgYXJlCiAqIHVuYmFsYW5jZWQgd2l0aGluIHRoZSBkYXRhLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBzZWFyY2guCiAqIEBwYXJhbSB7U3RyaW5nfSBsZWZ0IExlZnQgZGVsaW1pdGVyIGFzIGFuIFhSZWdFeHAgcGF0dGVybi4KICogQHBhcmFtIHtTdHJpbmd9IHJpZ2h0IFJpZ2h0IGRlbGltaXRlciBhcyBhbiBYUmVnRXhwIHBhdHRlcm4uCiAqIEBwYXJhbSB7U3RyaW5nfSBbZmxhZ3NdIEZsYWdzIGZvciB0aGUgbGVmdCBhbmQgcmlnaHQgZGVsaW1pdGVycy4gVXNlIGFueSBvZjogYGdpbW5zeHlgLgogKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIExldHMgeW91IHNwZWNpZnkgYHZhbHVlTmFtZXNgIGFuZCBgZXNjYXBlQ2hhcmAgb3B0aW9ucy4KICogQHJldHVybnMge0FycmF5fSBBcnJheSBvZiBtYXRjaGVzLCBvciBhbiBlbXB0eSBhcnJheS4KICogQGV4YW1wbGUKICoKICogLy8gQmFzaWMgdXNhZ2UKICogdmFyIHN0ciA9ICcodCgoZSkpcyl0KCkoaW5nKSc7CiAqIFhSZWdFeHAubWF0Y2hSZWN1cnNpdmUoc3RyLCAnXFwoJywgJ1xcKScsICdnJyk7CiAqIC8vIC0+IFsndCgoZSkpcycsICcnLCAnaW5nJ10KICoKICogLy8gRXh0ZW5kZWQgaW5mb3JtYXRpb24gbW9kZSB3aXRoIHZhbHVlTmFtZXMKICogc3RyID0gJ0hlcmUgaXMgPGRpdj4gPGRpdj5hbjwvZGl2PjwvZGl2PiBleGFtcGxlJzsKICogWFJlZ0V4cC5tYXRjaFJlY3Vyc2l2ZShzdHIsICc8ZGl2XFxzKj4nLCAnPC9kaXY+JywgJ2dpJywgewogKiAgIHZhbHVlTmFtZXM6IFsnYmV0d2VlbicsICdsZWZ0JywgJ21hdGNoJywgJ3JpZ2h0J10KICogfSk7CiAqIC8vIC0+IFsKICogLy8ge25hbWU6ICdiZXR3ZWVuJywgdmFsdWU6ICdIZXJlIGlzICcsICAgICAgIHN0YXJ0OiAwLCAgZW5kOiA4fSwKICogLy8ge25hbWU6ICdsZWZ0JywgICAgdmFsdWU6ICc8ZGl2PicsICAgICAgICAgIHN0YXJ0OiA4LCAgZW5kOiAxM30sCiAqIC8vIHtuYW1lOiAnbWF0Y2gnLCAgIHZhbHVlOiAnIDxkaXY+YW48L2Rpdj4nLCBzdGFydDogMTMsIGVuZDogMjd9LAogKiAvLyB7bmFtZTogJ3JpZ2h0JywgICB2YWx1ZTogJzwvZGl2PicsICAgICAgICAgc3RhcnQ6IDI3LCBlbmQ6IDMzfSwKICogLy8ge25hbWU6ICdiZXR3ZWVuJywgdmFsdWU6ICcgZXhhbXBsZScsICAgICAgIHN0YXJ0OiAzMywgZW5kOiA0MX0KICogLy8gXQogKgogKiAvLyBPbWl0dGluZyB1bm5lZWRlZCBwYXJ0cyB3aXRoIG51bGwgdmFsdWVOYW1lcywgYW5kIHVzaW5nIGVzY2FwZUNoYXIKICogc3RyID0gJy4uLnsxfVxce3tmdW5jdGlvbih4LHkpe3JldHVybiB5K3g7fX0nOwogKiBYUmVnRXhwLm1hdGNoUmVjdXJzaXZlKHN0ciwgJ3snLCAnfScsICdnJywgewogKiAgIHZhbHVlTmFtZXM6IFsnbGl0ZXJhbCcsIG51bGwsICd2YWx1ZScsIG51bGxdLAogKiAgIGVzY2FwZUNoYXI6ICdcXCcKICogfSk7CiAqIC8vIC0+IFsKICogLy8ge25hbWU6ICdsaXRlcmFsJywgdmFsdWU6ICcuLi4nLCBzdGFydDogMCwgZW5kOiAzfSwKICogLy8ge25hbWU6ICd2YWx1ZScsICAgdmFsdWU6ICcxJywgICBzdGFydDogNCwgZW5kOiA1fSwKICogLy8ge25hbWU6ICdsaXRlcmFsJywgdmFsdWU6ICdcXHsnLCBzdGFydDogNiwgZW5kOiA4fSwKICogLy8ge25hbWU6ICd2YWx1ZScsICAgdmFsdWU6ICdmdW5jdGlvbih4LHkpe3JldHVybiB5K3g7fScsIHN0YXJ0OiA5LCBlbmQ6IDM1fQogKiAvLyBdCiAqCiAqIC8vIFN0aWNreSBtb2RlIHZpYSBmbGFnIHkKICogc3RyID0gJzwxPjw8PDI+Pj48Mz40PDU+JzsKICogWFJlZ0V4cC5tYXRjaFJlY3Vyc2l2ZShzdHIsICc8JywgJz4nLCAnZ3knKTsKICogLy8gLT4gWycxJywgJzw8Mj4+JywgJzMnXQogKi8KICAgIFhSZWdFeHAubWF0Y2hSZWN1cnNpdmUgPSBmdW5jdGlvbiAoc3RyLCBsZWZ0LCByaWdodCwgZmxhZ3MsIG9wdGlvbnMpIHsKICAgICAgICBmbGFncyA9IGZsYWdzIHx8ICIiOwogICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogICAgICAgIHZhciBnbG9iYWwgPSBmbGFncy5pbmRleE9mKCJnIikgPiAtMSwKICAgICAgICAgICAgc3RpY2t5ID0gZmxhZ3MuaW5kZXhPZigieSIpID4gLTEsCiAgICAgICAgICAgIGJhc2ljRmxhZ3MgPSBmbGFncy5yZXBsYWNlKC95L2csICIiKSwgLy8gRmxhZyB5IGNvbnRyb2xsZWQgaW50ZXJuYWxseQogICAgICAgICAgICBlc2NhcGVDaGFyID0gb3B0aW9ucy5lc2NhcGVDaGFyLAogICAgICAgICAgICB2TiA9IG9wdGlvbnMudmFsdWVOYW1lcywKICAgICAgICAgICAgb3V0cHV0ID0gW10sCiAgICAgICAgICAgIG9wZW5Ub2tlbnMgPSAwLAogICAgICAgICAgICBkZWxpbVN0YXJ0ID0gMCwKICAgICAgICAgICAgZGVsaW1FbmQgPSAwLAogICAgICAgICAgICBsYXN0T3V0ZXJFbmQgPSAwLAogICAgICAgICAgICBvdXRlclN0YXJ0LAogICAgICAgICAgICBpbm5lclN0YXJ0LAogICAgICAgICAgICBsZWZ0TWF0Y2gsCiAgICAgICAgICAgIHJpZ2h0TWF0Y2gsCiAgICAgICAgICAgIGVzYzsKICAgICAgICBsZWZ0ID0gWFJlZ0V4cChsZWZ0LCBiYXNpY0ZsYWdzKTsKICAgICAgICByaWdodCA9IFhSZWdFeHAocmlnaHQsIGJhc2ljRmxhZ3MpOwoKICAgICAgICBpZiAoZXNjYXBlQ2hhcikgewogICAgICAgICAgICBpZiAoZXNjYXBlQ2hhci5sZW5ndGggPiAxKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImNhbid0IHVzZSBtb3JlIHRoYW4gb25lIGVzY2FwZSBjaGFyYWN0ZXIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlc2NhcGVDaGFyID0gWFJlZ0V4cC5lc2NhcGUoZXNjYXBlQ2hhcik7CiAgICAgICAgICAgIC8vIFVzaW5nIFhSZWdFeHAudW5pb24gc2FmZWx5IHJld3JpdGVzIGJhY2tyZWZlcmVuY2VzIGluIGBsZWZ0YCBhbmQgYHJpZ2h0YAogICAgICAgICAgICBlc2MgPSBuZXcgUmVnRXhwKAogICAgICAgICAgICAgICAgIig/OiIgKyBlc2NhcGVDaGFyICsgIltcXFNcXHNdfCg/Oig/ISIgKyBYUmVnRXhwLnVuaW9uKFtsZWZ0LCByaWdodF0pLnNvdXJjZSArICIpW14iICsgZXNjYXBlQ2hhciArICJdKSspKyIsCiAgICAgICAgICAgICAgICBmbGFncy5yZXBsYWNlKC9bXmltXSsvZywgIiIpIC8vIEZsYWdzIGd5IG5vdCBuZWVkZWQgaGVyZTsgZmxhZ3MgbnN4IGhhbmRsZWQgYnkgWFJlZ0V4cAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgLy8gSWYgdXNpbmcgYW4gZXNjYXBlIGNoYXJhY3RlciwgYWR2YW5jZSB0byB0aGUgZGVsaW1pdGVyJ3MgbmV4dCBzdGFydGluZyBwb3NpdGlvbiwKICAgICAgICAgICAgLy8gc2tpcHBpbmcgYW55IGVzY2FwZWQgY2hhcmFjdGVycyBpbiBiZXR3ZWVuCiAgICAgICAgICAgIGlmIChlc2NhcGVDaGFyKSB7CiAgICAgICAgICAgICAgICBkZWxpbUVuZCArPSAoWFJlZ0V4cC5leGVjKHN0ciwgZXNjLCBkZWxpbUVuZCwgInN0aWNreSIpIHx8IFsiIl0pWzBdLmxlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgICAgICBsZWZ0TWF0Y2ggPSBYUmVnRXhwLmV4ZWMoc3RyLCBsZWZ0LCBkZWxpbUVuZCk7CiAgICAgICAgICAgIHJpZ2h0TWF0Y2ggPSBYUmVnRXhwLmV4ZWMoc3RyLCByaWdodCwgZGVsaW1FbmQpOwogICAgICAgICAgICAvLyBLZWVwIHRoZSBsZWZ0bW9zdCBtYXRjaCBvbmx5CiAgICAgICAgICAgIGlmIChsZWZ0TWF0Y2ggJiYgcmlnaHRNYXRjaCkgewogICAgICAgICAgICAgICAgaWYgKGxlZnRNYXRjaC5pbmRleCA8PSByaWdodE1hdGNoLmluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgcmlnaHRNYXRjaCA9IG51bGw7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGxlZnRNYXRjaCA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogUGF0aHMgKExNOmxlZnRNYXRjaCwgUk06cmlnaHRNYXRjaCwgT1Q6b3BlblRva2Vucyk6CiAgICAgICAgICAgIExNIHwgUk0gfCBPVCB8IFJlc3VsdAogICAgICAgICAgICAxICB8IDAgIHwgMSAgfCBsb29wCiAgICAgICAgICAgIDEgIHwgMCAgfCAwICB8IGxvb3AKICAgICAgICAgICAgMCAgfCAxICB8IDEgIHwgbG9vcAogICAgICAgICAgICAwICB8IDEgIHwgMCAgfCB0aHJvdwogICAgICAgICAgICAwICB8IDAgIHwgMSAgfCB0aHJvdwogICAgICAgICAgICAwICB8IDAgIHwgMCAgfCBicmVhawogICAgICAgICAgICAqIERvZXNuJ3QgaW5jbHVkZSB0aGUgc3RpY2t5IG1vZGUgc3BlY2lhbCBjYXNlCiAgICAgICAgICAgICogTG9vcCBlbmRzIGFmdGVyIHRoZSBmaXJzdCBjb21wbGV0ZWQgbWF0Y2ggaWYgYCFnbG9iYWxgICovCiAgICAgICAgICAgIGlmIChsZWZ0TWF0Y2ggfHwgcmlnaHRNYXRjaCkgewogICAgICAgICAgICAgICAgZGVsaW1TdGFydCA9IChsZWZ0TWF0Y2ggfHwgcmlnaHRNYXRjaCkuaW5kZXg7CiAgICAgICAgICAgICAgICBkZWxpbUVuZCA9IGRlbGltU3RhcnQgKyAobGVmdE1hdGNoIHx8IHJpZ2h0TWF0Y2gpWzBdLmxlbmd0aDsKICAgICAgICAgICAgfSBlbHNlIGlmICghb3BlblRva2VucykgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHN0aWNreSAmJiAhb3BlblRva2VucyAmJiBkZWxpbVN0YXJ0ID4gbGFzdE91dGVyRW5kKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobGVmdE1hdGNoKSB7CiAgICAgICAgICAgICAgICBpZiAoIW9wZW5Ub2tlbnMpIHsKICAgICAgICAgICAgICAgICAgICBvdXRlclN0YXJ0ID0gZGVsaW1TdGFydDsKICAgICAgICAgICAgICAgICAgICBpbm5lclN0YXJ0ID0gZGVsaW1FbmQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICArK29wZW5Ub2tlbnM7CiAgICAgICAgICAgIH0gZWxzZSBpZiAocmlnaHRNYXRjaCAmJiBvcGVuVG9rZW5zKSB7CiAgICAgICAgICAgICAgICBpZiAoIS0tb3BlblRva2VucykgewogICAgICAgICAgICAgICAgICAgIGlmICh2TikgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAodk5bMF0gJiYgb3V0ZXJTdGFydCA+IGxhc3RPdXRlckVuZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0LnB1c2gocm93KHZOWzBdLCBzdHIuc2xpY2UobGFzdE91dGVyRW5kLCBvdXRlclN0YXJ0KSwgbGFzdE91dGVyRW5kLCBvdXRlclN0YXJ0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZOWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQucHVzaChyb3codk5bMV0sIHN0ci5zbGljZShvdXRlclN0YXJ0LCBpbm5lclN0YXJ0KSwgb3V0ZXJTdGFydCwgaW5uZXJTdGFydCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2TlsyXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0LnB1c2gocm93KHZOWzJdLCBzdHIuc2xpY2UoaW5uZXJTdGFydCwgZGVsaW1TdGFydCksIGlubmVyU3RhcnQsIGRlbGltU3RhcnQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAodk5bM10pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKHJvdyh2TlszXSwgc3RyLnNsaWNlKGRlbGltU3RhcnQsIGRlbGltRW5kKSwgZGVsaW1TdGFydCwgZGVsaW1FbmQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKHN0ci5zbGljZShpbm5lclN0YXJ0LCBkZWxpbVN0YXJ0KSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGxhc3RPdXRlckVuZCA9IGRlbGltRW5kOwogICAgICAgICAgICAgICAgICAgIGlmICghZ2xvYmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigic3RyaW5nIGNvbnRhaW5zIHVuYmFsYW5jZWQgZGVsaW1pdGVycyIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIElmIHRoZSBkZWxpbWl0ZXIgbWF0Y2hlZCBhbiBlbXB0eSBzdHJpbmcsIGF2b2lkIGFuIGluZmluaXRlIGxvb3AKICAgICAgICAgICAgaWYgKGRlbGltU3RhcnQgPT09IGRlbGltRW5kKSB7CiAgICAgICAgICAgICAgICArK2RlbGltRW5kOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoZ2xvYmFsICYmICFzdGlja3kgJiYgdk4gJiYgdk5bMF0gJiYgc3RyLmxlbmd0aCA+IGxhc3RPdXRlckVuZCkgewogICAgICAgICAgICBvdXRwdXQucHVzaChyb3codk5bMF0sIHN0ci5zbGljZShsYXN0T3V0ZXJFbmQpLCBsYXN0T3V0ZXJFbmQsIHN0ci5sZW5ndGgpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBvdXRwdXQ7CiAgICB9OwoKfShYUmVnRXhwKSk7CgoKLyoqKioqIGJ1aWxkLmpzICoqKioqLwoKLyohCiAqIFhSZWdFeHAuYnVpbGQgdjAuMS4wCiAqIChjKSAyMDEyIFN0ZXZlbiBMZXZpdGhhbiA8aHR0cDovL3hyZWdleHAuY29tLz4KICogTUlUIExpY2Vuc2UKICogSW5zcGlyZWQgYnkgUmVnRXhwLmNyZWF0ZSBieSBMZWEgVmVyb3UgPGh0dHA6Ly9sZWEudmVyb3UubWUvPgogKi8KCihmdW5jdGlvbiAoWFJlZ0V4cCkgewogICAgInVzZSBzdHJpY3QiOwoKICAgIHZhciBzdWJwYXJ0cyA9IC8oXCgpKD8hXD8pfFxcKFsxLTldXGQqKXxcXFtcc1xTXXxcWyg/OlteXFxcXV18XFxbXHNcU10pKl0vZywKICAgICAgICBwYXJ0cyA9IFhSZWdFeHAudW5pb24oWy9cKHt7KFtcdyRdKyl9fVwpfHt7KFtcdyRdKyl9fS8sIHN1YnBhcnRzXSwgImciKTsKCi8qKgogKiBTdHJpcHMgYSBsZWFkaW5nIGBeYCBhbmQgdHJhaWxpbmcgdW5lc2NhcGVkIGAkYCwgaWYgYm90aCBhcmUgcHJlc2VudC4KICogQHByaXZhdGUKICogQHBhcmFtIHtTdHJpbmd9IHBhdHRlcm4gUGF0dGVybiB0byBwcm9jZXNzLgogKiBAcmV0dXJucyB7U3RyaW5nfSBQYXR0ZXJuIHdpdGggZWRnZSBhbmNob3JzIHJlbW92ZWQuCiAqLwogICAgZnVuY3Rpb24gZGVhbmNob3IocGF0dGVybikgewogICAgICAgIHZhciBzdGFydEFuY2hvciA9IC9eKD86XChcPzpcKSk/XF4vLCAvLyBMZWFkaW5nIGBeYCBvciBgKD86KV5gIChoYW5kbGVzIC94IGNydWZ0KQogICAgICAgICAgICBlbmRBbmNob3IgPSAvXCQoPzpcKFw/OlwpKT8kLzsgLy8gVHJhaWxpbmcgYCRgIG9yIGAkKD86KWAgKGhhbmRsZXMgL3ggY3J1ZnQpCiAgICAgICAgaWYgKGVuZEFuY2hvci50ZXN0KHBhdHRlcm4ucmVwbGFjZSgvXFxbXHNcU10vZywgIiIpKSkgeyAvLyBFbnN1cmUgdHJhaWxpbmcgYCRgIGlzbid0IGVzY2FwZWQKICAgICAgICAgICAgcmV0dXJuIHBhdHRlcm4ucmVwbGFjZShzdGFydEFuY2hvciwgIiIpLnJlcGxhY2UoZW5kQW5jaG9yLCAiIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwYXR0ZXJuOwogICAgfQoKLyoqCiAqIENvbnZlcnRzIHRoZSBwcm92aWRlZCB2YWx1ZSB0byBhbiBYUmVnRXhwLgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IHZhbHVlIFZhbHVlIHRvIGNvbnZlcnQuCiAqIEByZXR1cm5zIHtSZWdFeHB9IFhSZWdFeHAgb2JqZWN0IHdpdGggWFJlZ0V4cCBzeW50YXggYXBwbGllZC4KICovCiAgICBmdW5jdGlvbiBhc1hSZWdFeHAodmFsdWUpIHsKICAgICAgICByZXR1cm4gWFJlZ0V4cC5pc1JlZ0V4cCh2YWx1ZSkgPwogICAgICAgICAgICAgICAgKHZhbHVlLnhyZWdleHAgJiYgIXZhbHVlLnhyZWdleHAuaXNOYXRpdmUgPyB2YWx1ZSA6IFhSZWdFeHAodmFsdWUuc291cmNlKSkgOgogICAgICAgICAgICAgICAgWFJlZ0V4cCh2YWx1ZSk7CiAgICB9CgovKioKICogQnVpbGRzIHJlZ2V4ZXMgdXNpbmcgbmFtZWQgc3VicGF0dGVybnMsIGZvciByZWFkYWJpbGl0eSBhbmQgcGF0dGVybiByZXVzZS4gQmFja3JlZmVyZW5jZXMgaW4gdGhlCiAqIG91dGVyIHBhdHRlcm4gYW5kIHByb3ZpZGVkIHN1YnBhdHRlcm5zIGFyZSBhdXRvbWF0aWNhbGx5IHJlbnVtYmVyZWQgdG8gd29yayBjb3JyZWN0bHkuIE5hdGl2ZQogKiBmbGFncyB1c2VkIGJ5IHByb3ZpZGVkIHN1YnBhdHRlcm5zIGFyZSBpZ25vcmVkIGluIGZhdm9yIG9mIHRoZSBgZmxhZ3NgIGFyZ3VtZW50LgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gcGF0dGVybiBYUmVnRXhwIHBhdHRlcm4gdXNpbmcgYHt7bmFtZX19YCBmb3IgZW1iZWRkZWQgc3VicGF0dGVybnMuIEFsbG93cwogKiAgIGAoe3tuYW1lfX0pYCBhcyBzaG9ydGhhbmQgZm9yIGAoPzxuYW1lPnt7bmFtZX19KWAuIFBhdHRlcm5zIGNhbm5vdCBiZSBlbWJlZGRlZCB3aXRoaW4KICogICBjaGFyYWN0ZXIgY2xhc3Nlcy4KICogQHBhcmFtIHtPYmplY3R9IHN1YnMgTG9va3VwIG9iamVjdCBmb3IgbmFtZWQgc3VicGF0dGVybnMuIFZhbHVlcyBjYW4gYmUgc3RyaW5ncyBvciByZWdleGVzLiBBCiAqICAgbGVhZGluZyBgXmAgYW5kIHRyYWlsaW5nIHVuZXNjYXBlZCBgJGAgYXJlIHN0cmlwcGVkIGZyb20gc3VicGF0dGVybnMsIGlmIGJvdGggYXJlIHByZXNlbnQuCiAqIEBwYXJhbSB7U3RyaW5nfSBbZmxhZ3NdIEFueSBjb21iaW5hdGlvbiBvZiBYUmVnRXhwIGZsYWdzLgogKiBAcmV0dXJucyB7UmVnRXhwfSBSZWdleCB3aXRoIGludGVycG9sYXRlZCBzdWJwYXR0ZXJucy4KICogQGV4YW1wbGUKICoKICogdmFyIHRpbWUgPSBYUmVnRXhwLmJ1aWxkKCcoP3gpXiB7e2hvdXJzfX0gKHt7bWludXRlc319KSAkJywgewogKiAgIGhvdXJzOiBYUmVnRXhwLmJ1aWxkKCd7e2gxMn19IDogfCB7e2gyNH19JywgewogKiAgICAgaDEyOiAvMVswLTJdfDA/WzEtOV0vLAogKiAgICAgaDI0OiAvMlswLTNdfFswMV1bMC05XS8KICogICB9LCAneCcpLAogKiAgIG1pbnV0ZXM6IC9eWzAtNV1bMC05XSQvCiAqIH0pOwogKiB0aW1lLnRlc3QoJzEwOjU5Jyk7IC8vIC0+IHRydWUKICogWFJlZ0V4cC5leGVjKCcxMDo1OScsIHRpbWUpLm1pbnV0ZXM7IC8vIC0+ICc1OScKICovCiAgICBYUmVnRXhwLmJ1aWxkID0gZnVuY3Rpb24gKHBhdHRlcm4sIHN1YnMsIGZsYWdzKSB7CiAgICAgICAgdmFyIGlubGluZUZsYWdzID0gL15cKFw/KFtcdyRdKylcKS8uZXhlYyhwYXR0ZXJuKSwKICAgICAgICAgICAgZGF0YSA9IHt9LAogICAgICAgICAgICBudW1DYXBzID0gMCwgLy8gQ2FwcyBpcyBzaG9ydCBmb3IgY2FwdHVyZXMKICAgICAgICAgICAgbnVtUHJpb3JDYXBzLAogICAgICAgICAgICBudW1PdXRlckNhcHMgPSAwLAogICAgICAgICAgICBvdXRlckNhcHNNYXAgPSBbMF0sCiAgICAgICAgICAgIG91dGVyQ2FwTmFtZXMsCiAgICAgICAgICAgIHN1YiwKICAgICAgICAgICAgcDsKCiAgICAgICAgLy8gQWRkIGZsYWdzIHdpdGhpbiBhIGxlYWRpbmcgbW9kZSBtb2RpZmllciB0byB0aGUgb3ZlcmFsbCBwYXR0ZXJuJ3MgZmxhZ3MKICAgICAgICBpZiAoaW5saW5lRmxhZ3MpIHsKICAgICAgICAgICAgZmxhZ3MgPSBmbGFncyB8fCAiIjsKICAgICAgICAgICAgaW5saW5lRmxhZ3NbMV0ucmVwbGFjZSgvLi9nLCBmdW5jdGlvbiAoZmxhZykgewogICAgICAgICAgICAgICAgZmxhZ3MgKz0gKGZsYWdzLmluZGV4T2YoZmxhZykgPiAtMSA/ICIiIDogZmxhZyk7IC8vIERvbid0IGFkZCBkdXBsaWNhdGVzCiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgZm9yIChwIGluIHN1YnMpIHsKICAgICAgICAgICAgaWYgKHN1YnMuaGFzT3duUHJvcGVydHkocCkpIHsKICAgICAgICAgICAgICAgIC8vIFBhc3NpbmcgdG8gWFJlZ0V4cCBlbmFibGVzIGVudGVuZGVkIHN5bnRheCBmb3Igc3VicGF0dGVybnMgcHJvdmlkZWQgYXMgc3RyaW5ncwogICAgICAgICAgICAgICAgLy8gYW5kIGVuc3VyZXMgaW5kZXBlbmRlbnQgdmFsaWRpdHksIGxlc3QgYW4gdW5lc2NhcGVkIGAoYCwgYClgLCBgW2AsIG9yIHRyYWlsaW5nCiAgICAgICAgICAgICAgICAvLyBgXGAgYnJlYWtzIHRoZSBgKD86KWAgd3JhcHBlci4gRm9yIHN1YnBhdHRlcm5zIHByb3ZpZGVkIGFzIHJlZ2V4ZXMsIGl0IGRpZXMgb24KICAgICAgICAgICAgICAgIC8vIG9jdGFscyBhbmQgYWRkcyB0aGUgYHhyZWdleHBgIHByb3BlcnR5LCBmb3Igc2ltcGxpY2l0eQogICAgICAgICAgICAgICAgc3ViID0gYXNYUmVnRXhwKHN1YnNbcF0pOwogICAgICAgICAgICAgICAgLy8gRGVhbmNob3JpbmcgYWxsb3dzIGVtYmVkZGluZyBpbmRlcGVuZGVudGx5IHVzZWZ1bCBhbmNob3JlZCByZWdleGVzLiBJZiB5b3UKICAgICAgICAgICAgICAgIC8vIHJlYWxseSBuZWVkIHRvIGtlZXAgeW91ciBhbmNob3JzLCBkb3VibGUgdGhlbSAoaS5lLiwgYF5eLi4uJCRgKQogICAgICAgICAgICAgICAgZGF0YVtwXSA9IHtwYXR0ZXJuOiBkZWFuY2hvcihzdWIuc291cmNlKSwgbmFtZXM6IHN1Yi54cmVnZXhwLmNhcHR1cmVOYW1lcyB8fCBbXX07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFBhc3NpbmcgdG8gWFJlZ0V4cCBkaWVzIG9uIG9jdGFscyBhbmQgZW5zdXJlcyB0aGUgb3V0ZXIgcGF0dGVybiBpcyBpbmRlcGVuZGVudGx5IHZhbGlkOwogICAgICAgIC8vIGhlbHBzIGtlZXAgdGhpcyBzaW1wbGUuIE5hbWVkIGNhcHR1cmVzIHdpbGwgYmUgcHV0IGJhY2sKICAgICAgICBwYXR0ZXJuID0gYXNYUmVnRXhwKHBhdHRlcm4pOwogICAgICAgIG91dGVyQ2FwTmFtZXMgPSBwYXR0ZXJuLnhyZWdleHAuY2FwdHVyZU5hbWVzIHx8IFtdOwogICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuLnNvdXJjZS5yZXBsYWNlKHBhcnRzLCBmdW5jdGlvbiAoJDAsICQxLCAkMiwgJDMsICQ0KSB7CiAgICAgICAgICAgIHZhciBzdWJOYW1lID0gJDEgfHwgJDIsIGNhcE5hbWUsIGludHJvOwogICAgICAgICAgICBpZiAoc3ViTmFtZSkgeyAvLyBOYW1lZCBzdWJwYXR0ZXJuCiAgICAgICAgICAgICAgICBpZiAoIWRhdGEuaGFzT3duUHJvcGVydHkoc3ViTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInVuZGVmaW5lZCBwcm9wZXJ0eSAiICsgJDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCQxKSB7IC8vIE5hbWVkIHN1YnBhdHRlcm4gd2FzIHdyYXBwZWQgaW4gYSBjYXB0dXJpbmcgZ3JvdXAKICAgICAgICAgICAgICAgICAgICBjYXBOYW1lID0gb3V0ZXJDYXBOYW1lc1tudW1PdXRlckNhcHNdOwogICAgICAgICAgICAgICAgICAgIG91dGVyQ2Fwc01hcFsrK251bU91dGVyQ2Fwc10gPSArK251bUNhcHM7CiAgICAgICAgICAgICAgICAgICAgLy8gSWYgaXQncyBhIG5hbWVkIGdyb3VwLCBwcmVzZXJ2ZSB0aGUgbmFtZS4gT3RoZXJ3aXNlLCB1c2UgdGhlIHN1YnBhdHRlcm4gbmFtZQogICAgICAgICAgICAgICAgICAgIC8vIGFzIHRoZSBjYXB0dXJlIG5hbWUKICAgICAgICAgICAgICAgICAgICBpbnRybyA9ICIoPzwiICsgKGNhcE5hbWUgfHwgc3ViTmFtZSkgKyAiPiI7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGludHJvID0gIig/OiI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBudW1QcmlvckNhcHMgPSBudW1DYXBzOwogICAgICAgICAgICAgICAgcmV0dXJuIGludHJvICsgZGF0YVtzdWJOYW1lXS5wYXR0ZXJuLnJlcGxhY2Uoc3VicGFydHMsIGZ1bmN0aW9uIChtYXRjaCwgcGFyZW4sIGJhY2tyZWYpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW4pIHsgLy8gQ2FwdHVyaW5nIGdyb3VwCiAgICAgICAgICAgICAgICAgICAgICAgIGNhcE5hbWUgPSBkYXRhW3N1Yk5hbWVdLm5hbWVzW251bUNhcHMgLSBudW1QcmlvckNhcHNdOwogICAgICAgICAgICAgICAgICAgICAgICArK251bUNhcHM7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYXBOYW1lKSB7IC8vIElmIHRoZSBjdXJyZW50IGNhcHR1cmUgaGFzIGEgbmFtZSwgcHJlc2VydmUgdGhlIG5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiKD88IiArIGNhcE5hbWUgKyAiPiI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJhY2tyZWYpIHsgLy8gQmFja3JlZmVyZW5jZQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlxcIiArICgrYmFja3JlZiArIG51bVByaW9yQ2Fwcyk7IC8vIFJld3JpdGUgdGhlIGJhY2tyZWZlcmVuY2UKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoOwogICAgICAgICAgICAgICAgfSkgKyAiKSI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCQzKSB7IC8vIENhcHR1cmluZyBncm91cAogICAgICAgICAgICAgICAgY2FwTmFtZSA9IG91dGVyQ2FwTmFtZXNbbnVtT3V0ZXJDYXBzXTsKICAgICAgICAgICAgICAgIG91dGVyQ2Fwc01hcFsrK251bU91dGVyQ2Fwc10gPSArK251bUNhcHM7CiAgICAgICAgICAgICAgICBpZiAoY2FwTmFtZSkgeyAvLyBJZiB0aGUgY3VycmVudCBjYXB0dXJlIGhhcyBhIG5hbWUsIHByZXNlcnZlIHRoZSBuYW1lCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICIoPzwiICsgY2FwTmFtZSArICI+IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmICgkNCkgeyAvLyBCYWNrcmVmZXJlbmNlCiAgICAgICAgICAgICAgICByZXR1cm4gIlxcIiArIG91dGVyQ2Fwc01hcFsrJDRdOyAvLyBSZXdyaXRlIHRoZSBiYWNrcmVmZXJlbmNlCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICQwOwogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gWFJlZ0V4cChwYXR0ZXJuLCBmbGFncyk7CiAgICB9OwoKfShYUmVnRXhwKSk7CgoKLyoqKioqIHByb3RvdHlwZXMuanMgKioqKiovCgovKiEKICogWFJlZ0V4cCBQcm90b3R5cGUgTWV0aG9kcyB2MS4wLjAKICogKGMpIDIwMTIgU3RldmVuIExldml0aGFuIDxodHRwOi8veHJlZ2V4cC5jb20vPgogKiBNSVQgTGljZW5zZQogKi8KCi8qKgogKiBBZGRzIGEgY29sbGVjdGlvbiBvZiBtZXRob2RzIHRvIGBYUmVnRXhwLnByb3RvdHlwZWAuIFJlZ0V4cCBvYmplY3RzIGNvcGllZCBieSBYUmVnRXhwIGFyZSBhbHNvCiAqIGF1Z21lbnRlZCB3aXRoIGFueSBgWFJlZ0V4cC5wcm90b3R5cGVgIG1ldGhvZHMuIEhlbmNlLCB0aGUgZm9sbG93aW5nIHdvcmsgZXF1aXZhbGVudGx5OgogKgogKiBYUmVnRXhwKCdbYS16XScsICdpZycpLnhleGVjKCdhYmMnKTsKICogWFJlZ0V4cCgvW2Etel0vaWcpLnhleGVjKCdhYmMnKTsKICogWFJlZ0V4cC5nbG9iYWxpemUoL1thLXpdL2kpLnhleGVjKCdhYmMnKTsKICovCihmdW5jdGlvbiAoWFJlZ0V4cCkgewogICAgInVzZSBzdHJpY3QiOwoKLyoqCiAqIENvcHkgcHJvcGVydGllcyBvZiBgYmAgdG8gYGFgLgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gYSBPYmplY3QgdGhhdCB3aWxsIHJlY2VpdmUgbmV3IHByb3BlcnRpZXMuCiAqIEBwYXJhbSB7T2JqZWN0fSBiIE9iamVjdCB3aG9zZSBwcm9wZXJ0aWVzIHdpbGwgYmUgY29waWVkLgogKi8KICAgIGZ1bmN0aW9uIGV4dGVuZChhLCBiKSB7CiAgICAgICAgZm9yICh2YXIgcCBpbiBiKSB7CiAgICAgICAgICAgIGlmIChiLmhhc093blByb3BlcnR5KHApKSB7CiAgICAgICAgICAgICAgICBhW3BdID0gYltwXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvL3JldHVybiBhOwogICAgfQoKICAgIGV4dGVuZChYUmVnRXhwLnByb3RvdHlwZSwgewoKLyoqCiAqIEltcGxpY2l0bHkgY2FsbHMgdGhlIHJlZ2V4J3MgYHRlc3RgIG1ldGhvZCB3aXRoIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgcHJvdmlkZWQgYXJndW1lbnRzIGFycmF5LgogKiBAbWVtYmVyT2YgWFJlZ0V4cC5wcm90b3R5cGUKICogQHBhcmFtIHsqfSBjb250ZXh0IElnbm9yZWQuIEFjY2VwdGVkIG9ubHkgZm9yIGNvbmdydWl0eSB3aXRoIGBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHlgLgogKiBAcGFyYW0ge0FycmF5fSBhcmdzIEFycmF5IHdpdGggdGhlIHN0cmluZyB0byBzZWFyY2ggYXMgaXRzIGZpcnN0IHZhbHVlLgogKiBAcmV0dXJucyB7Qm9vbGVhbn0gV2hldGhlciB0aGUgcmVnZXggbWF0Y2hlZCB0aGUgcHJvdmlkZWQgdmFsdWUuCiAqIEBleGFtcGxlCiAqCiAqIFhSZWdFeHAoJ1thLXpdJykuYXBwbHkobnVsbCwgWydhYmMnXSk7IC8vIC0+IHRydWUKICovCiAgICAgICAgYXBwbHk6IGZ1bmN0aW9uIChjb250ZXh0LCBhcmdzKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnRlc3QoYXJnc1swXSk7CiAgICAgICAgfSwKCi8qKgogKiBJbXBsaWNpdGx5IGNhbGxzIHRoZSByZWdleCdzIGB0ZXN0YCBtZXRob2Qgd2l0aCB0aGUgcHJvdmlkZWQgc3RyaW5nLgogKiBAbWVtYmVyT2YgWFJlZ0V4cC5wcm90b3R5cGUKICogQHBhcmFtIHsqfSBjb250ZXh0IElnbm9yZWQuIEFjY2VwdGVkIG9ubHkgZm9yIGNvbmdydWl0eSB3aXRoIGBGdW5jdGlvbi5wcm90b3R5cGUuY2FsbGAuCiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIHNlYXJjaC4KICogQHJldHVybnMge0Jvb2xlYW59IFdoZXRoZXIgdGhlIHJlZ2V4IG1hdGNoZWQgdGhlIHByb3ZpZGVkIHZhbHVlLgogKiBAZXhhbXBsZQogKgogKiBYUmVnRXhwKCdbYS16XScpLmNhbGwobnVsbCwgJ2FiYycpOyAvLyAtPiB0cnVlCiAqLwogICAgICAgIGNhbGw6IGZ1bmN0aW9uIChjb250ZXh0LCBzdHIpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMudGVzdChzdHIpOwogICAgICAgIH0sCgovKioKICogSW1wbGljaXRseSBjYWxscyB7QGxpbmsgI1hSZWdFeHAuZm9yRWFjaH0uCiAqIEBtZW1iZXJPZiBYUmVnRXhwLnByb3RvdHlwZQogKiBAZXhhbXBsZQogKgogKiBYUmVnRXhwKCdcXGQnKS5mb3JFYWNoKCcxYTIzNDUnLCBmdW5jdGlvbiAobWF0Y2gsIGkpIHsKICogICBpZiAoaSAlIDIpIHRoaXMucHVzaCgrbWF0Y2hbMF0pOwogKiB9LCBbXSk7CiAqIC8vIC0+IFsyLCA0XQogKi8KICAgICAgICBmb3JFYWNoOiBmdW5jdGlvbiAoc3RyLCBjYWxsYmFjaywgY29udGV4dCkgewogICAgICAgICAgICByZXR1cm4gWFJlZ0V4cC5mb3JFYWNoKHN0ciwgdGhpcywgY2FsbGJhY2ssIGNvbnRleHQpOwogICAgICAgIH0sCgovKioKICogSW1wbGljaXRseSBjYWxscyB7QGxpbmsgI1hSZWdFeHAuZ2xvYmFsaXplfS4KICogQG1lbWJlck9mIFhSZWdFeHAucHJvdG90eXBlCiAqIEBleGFtcGxlCiAqCiAqIHZhciBnbG9iYWxDb3B5ID0gWFJlZ0V4cCgncmVnZXgnKS5nbG9iYWxpemUoKTsKICogZ2xvYmFsQ29weS5nbG9iYWw7IC8vIC0+IHRydWUKICovCiAgICAgICAgZ2xvYmFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBYUmVnRXhwLmdsb2JhbGl6ZSh0aGlzKTsKICAgICAgICB9LAoKLyoqCiAqIEltcGxpY2l0bHkgY2FsbHMge0BsaW5rICNYUmVnRXhwLmV4ZWN9LgogKiBAbWVtYmVyT2YgWFJlZ0V4cC5wcm90b3R5cGUKICogQGV4YW1wbGUKICoKICogdmFyIG1hdGNoID0gWFJlZ0V4cCgnVVxcKyg/PGhleD5bMC05QS1GXXs0fSknKS54ZXhlYygnVSsyNjIwJyk7CiAqIG1hdGNoLmhleDsgLy8gLT4gJzI2MjAnCiAqLwogICAgICAgIHhleGVjOiBmdW5jdGlvbiAoc3RyLCBwb3MsIHN0aWNreSkgewogICAgICAgICAgICByZXR1cm4gWFJlZ0V4cC5leGVjKHN0ciwgdGhpcywgcG9zLCBzdGlja3kpOwogICAgICAgIH0sCgovKioKICogSW1wbGljaXRseSBjYWxscyB7QGxpbmsgI1hSZWdFeHAudGVzdH0uCiAqIEBtZW1iZXJPZiBYUmVnRXhwLnByb3RvdHlwZQogKiBAZXhhbXBsZQogKgogKiBYUmVnRXhwKCdjJykueHRlc3QoJ2FiYycpOyAvLyAtPiB0cnVlCiAqLwogICAgICAgIHh0ZXN0OiBmdW5jdGlvbiAoc3RyLCBwb3MsIHN0aWNreSkgewogICAgICAgICAgICByZXR1cm4gWFJlZ0V4cC50ZXN0KHN0ciwgdGhpcywgcG9zLCBzdGlja3kpOwogICAgICAgIH0KCiAgICB9KTsKCn0oWFJlZ0V4cCkpOwoKLy8gVGlueUNvbG9yIHYwLjkuMTUKLy8gaHR0cHM6Ly9naXRodWIuY29tL2Jncmlucy9UaW55Q29sb3IKLy8gMjAxMy0wNy0wNCwgQnJpYW4gR3JpbnN0ZWFkLCBNSVQgTGljZW5zZQooZnVuY3Rpb24ocm9vdCl7ZnVuY3Rpb24gdGlueWNvbG9yKGNvbG9yLG9wdHMpe2lmKGNvbG9yPWNvbG9yP2NvbG9yOiIiLG9wdHM9b3B0c3x8e30sIm9iamVjdCI9PXR5cGVvZiBjb2xvciYmY29sb3IuaGFzT3duUHJvcGVydHkoIl90Y19pZCIpKXJldHVybiBjb2xvcjt2YXIgcmdiPWlucHV0VG9SR0IoY29sb3IpLHI9cmdiLnIsZz1yZ2IuZyxiPXJnYi5iLGE9cmdiLmEscm91bmRBPW1hdGhSb3VuZCgxMDAqYSkvMTAwLGZvcm1hdD1vcHRzLmZvcm1hdHx8cmdiLmZvcm1hdDtyZXR1cm4gMT5yJiYocj1tYXRoUm91bmQocikpLDE+ZyYmKGc9bWF0aFJvdW5kKGcpKSwxPmImJihiPW1hdGhSb3VuZChiKSkse29rOnJnYi5vayxmb3JtYXQ6Zm9ybWF0LF90Y19pZDp0aW55Q291bnRlcisrLGFscGhhOmEsdG9Ic3Y6ZnVuY3Rpb24oKXt2YXIgaHN2PXJnYlRvSHN2KHIsZyxiKTtyZXR1cm57aDozNjAqaHN2Lmgsczpoc3Yucyx2Omhzdi52LGE6YX19LHRvSHN2U3RyaW5nOmZ1bmN0aW9uKCl7dmFyIGhzdj1yZ2JUb0hzdihyLGcsYiksaD1tYXRoUm91bmQoMzYwKmhzdi5oKSxzPW1hdGhSb3VuZCgxMDAqaHN2LnMpLHY9bWF0aFJvdW5kKDEwMCpoc3Yudik7cmV0dXJuIDE9PWE/ImhzdigiK2grIiwgIitzKyIlLCAiK3YrIiUpIjoiaHN2YSgiK2grIiwgIitzKyIlLCAiK3YrIiUsICIrcm91bmRBKyIpIn0sdG9Ic2w6ZnVuY3Rpb24oKXt2YXIgaHNsPXJnYlRvSHNsKHIsZyxiKTtyZXR1cm57aDozNjAqaHNsLmgsczpoc2wucyxsOmhzbC5sLGE6YX19LHRvSHNsU3RyaW5nOmZ1bmN0aW9uKCl7dmFyIGhzbD1yZ2JUb0hzbChyLGcsYiksaD1tYXRoUm91bmQoMzYwKmhzbC5oKSxzPW1hdGhSb3VuZCgxMDAqaHNsLnMpLGw9bWF0aFJvdW5kKDEwMCpoc2wubCk7cmV0dXJuIDE9PWE/ImhzbCgiK2grIiwgIitzKyIlLCAiK2wrIiUpIjoiaHNsYSgiK2grIiwgIitzKyIlLCAiK2wrIiUsICIrcm91bmRBKyIpIn0sdG9IZXg6ZnVuY3Rpb24oYWxsb3czQ2hhcil7cmV0dXJuIHJnYlRvSGV4KHIsZyxiLGFsbG93M0NoYXIpfSx0b0hleFN0cmluZzpmdW5jdGlvbihhbGxvdzNDaGFyKXtyZXR1cm4iIyIrcmdiVG9IZXgocixnLGIsYWxsb3czQ2hhcil9LHRvUmdiOmZ1bmN0aW9uKCl7cmV0dXJue3I6bWF0aFJvdW5kKHIpLGc6bWF0aFJvdW5kKGcpLGI6bWF0aFJvdW5kKGIpLGE6YX19LHRvUmdiU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIDE9PWE/InJnYigiK21hdGhSb3VuZChyKSsiLCAiK21hdGhSb3VuZChnKSsiLCAiK21hdGhSb3VuZChiKSsiKSI6InJnYmEoIittYXRoUm91bmQocikrIiwgIittYXRoUm91bmQoZykrIiwgIittYXRoUm91bmQoYikrIiwgIityb3VuZEErIikifSx0b1BlcmNlbnRhZ2VSZ2I6ZnVuY3Rpb24oKXtyZXR1cm57cjptYXRoUm91bmQoMTAwKmJvdW5kMDEociwyNTUpKSsiJSIsZzptYXRoUm91bmQoMTAwKmJvdW5kMDEoZywyNTUpKSsiJSIsYjptYXRoUm91bmQoMTAwKmJvdW5kMDEoYiwyNTUpKSsiJSIsYTphfX0sdG9QZXJjZW50YWdlUmdiU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIDE9PWE/InJnYigiK21hdGhSb3VuZCgxMDAqYm91bmQwMShyLDI1NSkpKyIlLCAiK21hdGhSb3VuZCgxMDAqYm91bmQwMShnLDI1NSkpKyIlLCAiK21hdGhSb3VuZCgxMDAqYm91bmQwMShiLDI1NSkpKyIlKSI6InJnYmEoIittYXRoUm91bmQoMTAwKmJvdW5kMDEociwyNTUpKSsiJSwgIittYXRoUm91bmQoMTAwKmJvdW5kMDEoZywyNTUpKSsiJSwgIittYXRoUm91bmQoMTAwKmJvdW5kMDEoYiwyNTUpKSsiJSwgIityb3VuZEErIikifSx0b05hbWU6ZnVuY3Rpb24oKXtyZXR1cm4gMD09PWE/InRyYW5zcGFyZW50IjpoZXhOYW1lc1tyZ2JUb0hleChyLGcsYiwhMCldfHwhMX0sdG9GaWx0ZXI6ZnVuY3Rpb24oc2Vjb25kQ29sb3Ipe3ZhciBoZXg9cmdiVG9IZXgocixnLGIpLHNlY29uZEhleD1oZXgsYWxwaGFIZXg9TWF0aC5yb3VuZCgyNTUqcGFyc2VGbG9hdChhKSkudG9TdHJpbmcoMTYpLHNlY29uZEFscGhhSGV4PWFscGhhSGV4LGdyYWRpZW50VHlwZT1vcHRzJiZvcHRzLmdyYWRpZW50VHlwZT8iR3JhZGllbnRUeXBlID0gMSwgIjoiIjtpZihzZWNvbmRDb2xvcil7dmFyIHM9dGlueWNvbG9yKHNlY29uZENvbG9yKTtzZWNvbmRIZXg9cy50b0hleCgpLHNlY29uZEFscGhhSGV4PU1hdGgucm91bmQoMjU1KnBhcnNlRmxvYXQocy5hbHBoYSkpLnRvU3RyaW5nKDE2KX1yZXR1cm4icHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0LmdyYWRpZW50KCIrZ3JhZGllbnRUeXBlKyJzdGFydENvbG9yc3RyPSMiK3BhZDIoYWxwaGFIZXgpK2hleCsiLGVuZENvbG9yc3RyPSMiK3BhZDIoc2Vjb25kQWxwaGFIZXgpK3NlY29uZEhleCsiKSJ9LHRvU3RyaW5nOmZ1bmN0aW9uKGZvcm1hdCl7dmFyIGZvcm1hdFNldD0hIWZvcm1hdDtmb3JtYXQ9Zm9ybWF0fHx0aGlzLmZvcm1hdDt2YXIgZm9ybWF0dGVkU3RyaW5nPSExLGhhc0FscGhhQW5kRm9ybWF0Tm90U2V0PSFmb3JtYXRTZXQmJjE+YSYmYT4wLGZvcm1hdFdpdGhBbHBoYT1oYXNBbHBoYUFuZEZvcm1hdE5vdFNldCYmKCJoZXgiPT09Zm9ybWF0fHwiaGV4NiI9PT1mb3JtYXR8fCJoZXgzIj09PWZvcm1hdHx8Im5hbWUiPT09Zm9ybWF0KTtyZXR1cm4icmdiIj09PWZvcm1hdCYmKGZvcm1hdHRlZFN0cmluZz10aGlzLnRvUmdiU3RyaW5nKCkpLCJwcmdiIj09PWZvcm1hdCYmKGZvcm1hdHRlZFN0cmluZz10aGlzLnRvUGVyY2VudGFnZVJnYlN0cmluZygpKSwoImhleCI9PT1mb3JtYXR8fCJoZXg2Ij09PWZvcm1hdCkmJihmb3JtYXR0ZWRTdHJpbmc9dGhpcy50b0hleFN0cmluZygpKSwiaGV4MyI9PT1mb3JtYXQmJihmb3JtYXR0ZWRTdHJpbmc9dGhpcy50b0hleFN0cmluZyghMCkpLCJuYW1lIj09PWZvcm1hdCYmKGZvcm1hdHRlZFN0cmluZz10aGlzLnRvTmFtZSgpKSwiaHNsIj09PWZvcm1hdCYmKGZvcm1hdHRlZFN0cmluZz10aGlzLnRvSHNsU3RyaW5nKCkpLCJoc3YiPT09Zm9ybWF0JiYoZm9ybWF0dGVkU3RyaW5nPXRoaXMudG9Ic3ZTdHJpbmcoKSksZm9ybWF0V2l0aEFscGhhP3RoaXMudG9SZ2JTdHJpbmcoKTpmb3JtYXR0ZWRTdHJpbmd8fHRoaXMudG9IZXhTdHJpbmcoKX19fWZ1bmN0aW9uIGlucHV0VG9SR0IoY29sb3Ipe3ZhciByZ2I9e3I6MCxnOjAsYjowfSxhPTEsb2s9ITEsZm9ybWF0PSExO3JldHVybiJzdHJpbmciPT10eXBlb2YgY29sb3ImJihjb2xvcj1zdHJpbmdJbnB1dFRvT2JqZWN0KGNvbG9yKSksIm9iamVjdCI9PXR5cGVvZiBjb2xvciYmKGNvbG9yLmhhc093blByb3BlcnR5KCJyIikmJmNvbG9yLmhhc093blByb3BlcnR5KCJnIikmJmNvbG9yLmhhc093blByb3BlcnR5KCJiIik/KHJnYj1yZ2JUb1JnYihjb2xvci5yLGNvbG9yLmcsY29sb3IuYiksb2s9ITAsZm9ybWF0PSIlIj09PShjb2xvci5yKyIiKS5zdWJzdHIoLTEpPyJwcmdiIjoicmdiIik6Y29sb3IuaGFzT3duUHJvcGVydHkoImgiKSYmY29sb3IuaGFzT3duUHJvcGVydHkoInMiKSYmY29sb3IuaGFzT3duUHJvcGVydHkoInYiKT8oY29sb3Iucz1jb252ZXJ0VG9QZXJjZW50YWdlKGNvbG9yLnMpLGNvbG9yLnY9Y29udmVydFRvUGVyY2VudGFnZShjb2xvci52KSxyZ2I9aHN2VG9SZ2IoY29sb3IuaCxjb2xvci5zLGNvbG9yLnYpLG9rPSEwLGZvcm1hdD0iaHN2Iik6Y29sb3IuaGFzT3duUHJvcGVydHkoImgiKSYmY29sb3IuaGFzT3duUHJvcGVydHkoInMiKSYmY29sb3IuaGFzT3duUHJvcGVydHkoImwiKSYmKGNvbG9yLnM9Y29udmVydFRvUGVyY2VudGFnZShjb2xvci5zKSxjb2xvci5sPWNvbnZlcnRUb1BlcmNlbnRhZ2UoY29sb3IubCkscmdiPWhzbFRvUmdiKGNvbG9yLmgsY29sb3Iucyxjb2xvci5sKSxvaz0hMCxmb3JtYXQ9ImhzbCIpLGNvbG9yLmhhc093blByb3BlcnR5KCJhIikmJihhPWNvbG9yLmEpKSxhPXBhcnNlRmxvYXQoYSksKGlzTmFOKGEpfHwwPmF8fGE+MSkmJihhPTEpLHtvazpvayxmb3JtYXQ6Y29sb3IuZm9ybWF0fHxmb3JtYXQscjptYXRoTWluKDI1NSxtYXRoTWF4KHJnYi5yLDApKSxnOm1hdGhNaW4oMjU1LG1hdGhNYXgocmdiLmcsMCkpLGI6bWF0aE1pbigyNTUsbWF0aE1heChyZ2IuYiwwKSksYTphfX1mdW5jdGlvbiByZ2JUb1JnYihyLGcsYil7cmV0dXJue3I6MjU1KmJvdW5kMDEociwyNTUpLGc6MjU1KmJvdW5kMDEoZywyNTUpLGI6MjU1KmJvdW5kMDEoYiwyNTUpfX1mdW5jdGlvbiByZ2JUb0hzbChyLGcsYil7cj1ib3VuZDAxKHIsMjU1KSxnPWJvdW5kMDEoZywyNTUpLGI9Ym91bmQwMShiLDI1NSk7dmFyIGgscyxtYXg9bWF0aE1heChyLGcsYiksbWluPW1hdGhNaW4ocixnLGIpLGw9KG1heCttaW4pLzI7aWYobWF4PT1taW4paD1zPTA7ZWxzZXt2YXIgZD1tYXgtbWluO3N3aXRjaChzPWw+LjU/ZC8oMi1tYXgtbWluKTpkLyhtYXgrbWluKSxtYXgpe2Nhc2UgcjpoPShnLWIpL2QrKGI+Zz82OjApO2JyZWFrO2Nhc2UgZzpoPShiLXIpL2QrMjticmVhaztjYXNlIGI6aD0oci1nKS9kKzR9aC89Nn1yZXR1cm57aDpoLHM6cyxsOmx9fWZ1bmN0aW9uIGhzbFRvUmdiKGgscyxsKXtmdW5jdGlvbiBodWUycmdiKHAscSx0KXtyZXR1cm4gMD50JiYodCs9MSksdD4xJiYodC09MSksMS82PnQ/cCs2KihxLXApKnQ6LjU+dD9xOjIvMz50P3ArNioocS1wKSooMi8zLXQpOnB9dmFyIHIsZyxiO2lmKGg9Ym91bmQwMShoLDM2MCkscz1ib3VuZDAxKHMsMTAwKSxsPWJvdW5kMDEobCwxMDApLDA9PT1zKXI9Zz1iPWw7ZWxzZXt2YXIgcT0uNT5sP2wqKDErcyk6bCtzLWwqcyxwPTIqbC1xO3I9aHVlMnJnYihwLHEsaCsxLzMpLGc9aHVlMnJnYihwLHEsaCksYj1odWUycmdiKHAscSxoLTEvMyl9cmV0dXJue3I6MjU1KnIsZzoyNTUqZyxiOjI1NSpifX1mdW5jdGlvbiByZ2JUb0hzdihyLGcsYil7cj1ib3VuZDAxKHIsMjU1KSxnPWJvdW5kMDEoZywyNTUpLGI9Ym91bmQwMShiLDI1NSk7dmFyIGgscyxtYXg9bWF0aE1heChyLGcsYiksbWluPW1hdGhNaW4ocixnLGIpLHY9bWF4LGQ9bWF4LW1pbjtpZihzPTA9PT1tYXg/MDpkL21heCxtYXg9PW1pbiloPTA7ZWxzZXtzd2l0Y2gobWF4KXtjYXNlIHI6aD0oZy1iKS9kKyhiPmc/NjowKTticmVhaztjYXNlIGc6aD0oYi1yKS9kKzI7YnJlYWs7Y2FzZSBiOmg9KHItZykvZCs0fWgvPTZ9cmV0dXJue2g6aCxzOnMsdjp2fX1mdW5jdGlvbiBoc3ZUb1JnYihoLHMsdil7aD02KmJvdW5kMDEoaCwzNjApLHM9Ym91bmQwMShzLDEwMCksdj1ib3VuZDAxKHYsMTAwKTt2YXIgaT1tYXRoLmZsb29yKGgpLGY9aC1pLHA9diooMS1zKSxxPXYqKDEtZipzKSx0PXYqKDEtKDEtZikqcyksbW9kPWklNixyPVt2LHEscCxwLHQsdl1bbW9kXSxnPVt0LHYsdixxLHAscF1bbW9kXSxiPVtwLHAsdCx2LHYscV1bbW9kXTtyZXR1cm57cjoyNTUqcixnOjI1NSpnLGI6MjU1KmJ9fWZ1bmN0aW9uIHJnYlRvSGV4KHIsZyxiLGFsbG93M0NoYXIpe3ZhciBoZXg9W3BhZDIobWF0aFJvdW5kKHIpLnRvU3RyaW5nKDE2KSkscGFkMihtYXRoUm91bmQoZykudG9TdHJpbmcoMTYpKSxwYWQyKG1hdGhSb3VuZChiKS50b1N0cmluZygxNikpXTtyZXR1cm4gYWxsb3czQ2hhciYmaGV4WzBdLmNoYXJBdCgwKT09aGV4WzBdLmNoYXJBdCgxKSYmaGV4WzFdLmNoYXJBdCgwKT09aGV4WzFdLmNoYXJBdCgxKSYmaGV4WzJdLmNoYXJBdCgwKT09aGV4WzJdLmNoYXJBdCgxKT9oZXhbMF0uY2hhckF0KDApK2hleFsxXS5jaGFyQXQoMCkraGV4WzJdLmNoYXJBdCgwKTpoZXguam9pbigiIil9ZnVuY3Rpb24gZmxpcChvKXt2YXIgZmxpcHBlZD17fTtmb3IodmFyIGkgaW4gbylvLmhhc093blByb3BlcnR5KGkpJiYoZmxpcHBlZFtvW2ldXT1pKTtyZXR1cm4gZmxpcHBlZH1mdW5jdGlvbiBib3VuZDAxKG4sbWF4KXtpc09uZVBvaW50WmVybyhuKSYmKG49IjEwMCUiKTt2YXIgcHJvY2Vzc1BlcmNlbnQ9aXNQZXJjZW50YWdlKG4pO3JldHVybiBuPW1hdGhNaW4obWF4LG1hdGhNYXgoMCxwYXJzZUZsb2F0KG4pKSkscHJvY2Vzc1BlcmNlbnQmJihuPXBhcnNlSW50KG4qbWF4LDEwKS8xMDApLDFlLTY+bWF0aC5hYnMobi1tYXgpPzE6biVtYXgvcGFyc2VGbG9hdChtYXgpfWZ1bmN0aW9uIGNsYW1wMDEodmFsKXtyZXR1cm4gbWF0aE1pbigxLG1hdGhNYXgoMCx2YWwpKX1mdW5jdGlvbiBwYXJzZUhleCh2YWwpe3JldHVybiBwYXJzZUludCh2YWwsMTYpfWZ1bmN0aW9uIGlzT25lUG9pbnRaZXJvKG4pe3JldHVybiJzdHJpbmciPT10eXBlb2YgbiYmLTEhPW4uaW5kZXhPZigiLiIpJiYxPT09cGFyc2VGbG9hdChuKX1mdW5jdGlvbiBpc1BlcmNlbnRhZ2Uobil7cmV0dXJuInN0cmluZyI9PXR5cGVvZiBuJiYtMSE9bi5pbmRleE9mKCIlIil9ZnVuY3Rpb24gcGFkMihjKXtyZXR1cm4gMT09Yy5sZW5ndGg/IjAiK2M6IiIrY31mdW5jdGlvbiBjb252ZXJ0VG9QZXJjZW50YWdlKG4pe3JldHVybiAxPj1uJiYobj0xMDAqbisiJSIpLG59ZnVuY3Rpb24gc3RyaW5nSW5wdXRUb09iamVjdChjb2xvcil7Y29sb3I9Y29sb3IucmVwbGFjZSh0cmltTGVmdCwiIikucmVwbGFjZSh0cmltUmlnaHQsIiIpLnRvTG93ZXJDYXNlKCk7dmFyIG5hbWVkPSExO2lmKG5hbWVzW2NvbG9yXSljb2xvcj1uYW1lc1tjb2xvcl0sbmFtZWQ9ITA7ZWxzZSBpZigidHJhbnNwYXJlbnQiPT1jb2xvcilyZXR1cm57cjowLGc6MCxiOjAsYTowLGZvcm1hdDoibmFtZSJ9O3ZhciBtYXRjaDtyZXR1cm4obWF0Y2g9bWF0Y2hlcnMucmdiLmV4ZWMoY29sb3IpKT97cjptYXRjaFsxXSxnOm1hdGNoWzJdLGI6bWF0Y2hbM119OihtYXRjaD1tYXRjaGVycy5yZ2JhLmV4ZWMoY29sb3IpKT97cjptYXRjaFsxXSxnOm1hdGNoWzJdLGI6bWF0Y2hbM10sYTptYXRjaFs0XX06KG1hdGNoPW1hdGNoZXJzLmhzbC5leGVjKGNvbG9yKSk/e2g6bWF0Y2hbMV0sczptYXRjaFsyXSxsOm1hdGNoWzNdfToobWF0Y2g9bWF0Y2hlcnMuaHNsYS5leGVjKGNvbG9yKSk/e2g6bWF0Y2hbMV0sczptYXRjaFsyXSxsOm1hdGNoWzNdLGE6bWF0Y2hbNF19OihtYXRjaD1tYXRjaGVycy5oc3YuZXhlYyhjb2xvcikpP3toOm1hdGNoWzFdLHM6bWF0Y2hbMl0sdjptYXRjaFszXX06KG1hdGNoPW1hdGNoZXJzLmhleDYuZXhlYyhjb2xvcikpP3tyOnBhcnNlSGV4KG1hdGNoWzFdKSxnOnBhcnNlSGV4KG1hdGNoWzJdKSxiOnBhcnNlSGV4KG1hdGNoWzNdKSxmb3JtYXQ6bmFtZWQ/Im5hbWUiOiJoZXgifToobWF0Y2g9bWF0Y2hlcnMuaGV4My5leGVjKGNvbG9yKSk/e3I6cGFyc2VIZXgobWF0Y2hbMV0rIiIrbWF0Y2hbMV0pLGc6cGFyc2VIZXgobWF0Y2hbMl0rIiIrbWF0Y2hbMl0pLGI6cGFyc2VIZXgobWF0Y2hbM10rIiIrbWF0Y2hbM10pLGZvcm1hdDpuYW1lZD8ibmFtZSI6ImhleCJ9OiExfXZhciB0cmltTGVmdD0vXltccywjXSsvLHRyaW1SaWdodD0vXHMrJC8sdGlueUNvdW50ZXI9MCxtYXRoPU1hdGgsbWF0aFJvdW5kPW1hdGgucm91bmQsbWF0aE1pbj1tYXRoLm1pbixtYXRoTWF4PW1hdGgubWF4LG1hdGhSYW5kb209bWF0aC5yYW5kb207dGlueWNvbG9yLmZyb21SYXRpbz1mdW5jdGlvbihjb2xvcixvcHRzKXtpZigib2JqZWN0Ij09dHlwZW9mIGNvbG9yKXt2YXIgbmV3Q29sb3I9e307Zm9yKHZhciBpIGluIGNvbG9yKWNvbG9yLmhhc093blByb3BlcnR5KGkpJiYobmV3Q29sb3JbaV09ImEiPT09aT9jb2xvcltpXTpjb252ZXJ0VG9QZXJjZW50YWdlKGNvbG9yW2ldKSk7Y29sb3I9bmV3Q29sb3J9cmV0dXJuIHRpbnljb2xvcihjb2xvcixvcHRzKX0sdGlueWNvbG9yLmVxdWFscz1mdW5jdGlvbihjb2xvcjEsY29sb3IyKXtyZXR1cm4gY29sb3IxJiZjb2xvcjI/dGlueWNvbG9yKGNvbG9yMSkudG9SZ2JTdHJpbmcoKT09dGlueWNvbG9yKGNvbG9yMikudG9SZ2JTdHJpbmcoKTohMX0sdGlueWNvbG9yLnJhbmRvbT1mdW5jdGlvbigpe3JldHVybiB0aW55Y29sb3IuZnJvbVJhdGlvKHtyOm1hdGhSYW5kb20oKSxnOm1hdGhSYW5kb20oKSxiOm1hdGhSYW5kb20oKX0pfSx0aW55Y29sb3IuZGVzYXR1cmF0ZT1mdW5jdGlvbihjb2xvcixhbW91bnQpe2Ftb3VudD0wPT09YW1vdW50PzA6YW1vdW50fHwxMDt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKTtyZXR1cm4gaHNsLnMtPWFtb3VudC8xMDAsaHNsLnM9Y2xhbXAwMShoc2wucyksdGlueWNvbG9yKGhzbCl9LHRpbnljb2xvci5zYXR1cmF0ZT1mdW5jdGlvbihjb2xvcixhbW91bnQpe2Ftb3VudD0wPT09YW1vdW50PzA6YW1vdW50fHwxMDt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKTtyZXR1cm4gaHNsLnMrPWFtb3VudC8xMDAsaHNsLnM9Y2xhbXAwMShoc2wucyksdGlueWNvbG9yKGhzbCl9LHRpbnljb2xvci5ncmV5c2NhbGU9ZnVuY3Rpb24oY29sb3Ipe3JldHVybiB0aW55Y29sb3IuZGVzYXR1cmF0ZShjb2xvciwxMDApfSx0aW55Y29sb3IubGlnaHRlbj1mdW5jdGlvbihjb2xvcixhbW91bnQpe2Ftb3VudD0wPT09YW1vdW50PzA6YW1vdW50fHwxMDt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKTtyZXR1cm4gaHNsLmwrPWFtb3VudC8xMDAsaHNsLmw9Y2xhbXAwMShoc2wubCksdGlueWNvbG9yKGhzbCl9LHRpbnljb2xvci5kYXJrZW49ZnVuY3Rpb24oY29sb3IsYW1vdW50KXthbW91bnQ9MD09PWFtb3VudD8wOmFtb3VudHx8MTA7dmFyIGhzbD10aW55Y29sb3IoY29sb3IpLnRvSHNsKCk7cmV0dXJuIGhzbC5sLT1hbW91bnQvMTAwLGhzbC5sPWNsYW1wMDEoaHNsLmwpLHRpbnljb2xvcihoc2wpfSx0aW55Y29sb3IuY29tcGxlbWVudD1mdW5jdGlvbihjb2xvcil7dmFyIGhzbD10aW55Y29sb3IoY29sb3IpLnRvSHNsKCk7cmV0dXJuIGhzbC5oPShoc2wuaCsxODApJTM2MCx0aW55Y29sb3IoaHNsKX0sdGlueWNvbG9yLnRyaWFkPWZ1bmN0aW9uKGNvbG9yKXt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKSxoPWhzbC5oO3JldHVyblt0aW55Y29sb3IoY29sb3IpLHRpbnljb2xvcih7aDooaCsxMjApJTM2MCxzOmhzbC5zLGw6aHNsLmx9KSx0aW55Y29sb3Ioe2g6KGgrMjQwKSUzNjAsczpoc2wucyxsOmhzbC5sfSldfSx0aW55Y29sb3IudGV0cmFkPWZ1bmN0aW9uKGNvbG9yKXt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKSxoPWhzbC5oO3JldHVyblt0aW55Y29sb3IoY29sb3IpLHRpbnljb2xvcih7aDooaCs5MCklMzYwLHM6aHNsLnMsbDpoc2wubH0pLHRpbnljb2xvcih7aDooaCsxODApJTM2MCxzOmhzbC5zLGw6aHNsLmx9KSx0aW55Y29sb3Ioe2g6KGgrMjcwKSUzNjAsczpoc2wucyxsOmhzbC5sfSldfSx0aW55Y29sb3Iuc3BsaXRjb21wbGVtZW50PWZ1bmN0aW9uKGNvbG9yKXt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKSxoPWhzbC5oO3JldHVyblt0aW55Y29sb3IoY29sb3IpLHRpbnljb2xvcih7aDooaCs3MiklMzYwLHM6aHNsLnMsbDpoc2wubH0pLHRpbnljb2xvcih7aDooaCsyMTYpJTM2MCxzOmhzbC5zLGw6aHNsLmx9KV19LHRpbnljb2xvci5hbmFsb2dvdXM9ZnVuY3Rpb24oY29sb3IscmVzdWx0cyxzbGljZXMpe3Jlc3VsdHM9cmVzdWx0c3x8NixzbGljZXM9c2xpY2VzfHwzMDt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKSxwYXJ0PTM2MC9zbGljZXMscmV0PVt0aW55Y29sb3IoY29sb3IpXTtmb3IoaHNsLmg9KGhzbC5oLShwYXJ0KnJlc3VsdHM+PjEpKzcyMCklMzYwOy0tcmVzdWx0czspaHNsLmg9KGhzbC5oK3BhcnQpJTM2MCxyZXQucHVzaCh0aW55Y29sb3IoaHNsKSk7cmV0dXJuIHJldH0sdGlueWNvbG9yLm1vbm9jaHJvbWF0aWM9ZnVuY3Rpb24oY29sb3IscmVzdWx0cyl7cmVzdWx0cz1yZXN1bHRzfHw2O2Zvcih2YXIgaHN2PXRpbnljb2xvcihjb2xvcikudG9Ic3YoKSxoPWhzdi5oLHM9aHN2LnMsdj1oc3YudixyZXQ9W10sbW9kaWZpY2F0aW9uPTEvcmVzdWx0cztyZXN1bHRzLS07KXJldC5wdXNoKHRpbnljb2xvcih7aDpoLHM6cyx2OnZ9KSksdj0odittb2RpZmljYXRpb24pJTE7cmV0dXJuIHJldH0sdGlueWNvbG9yLnJlYWRhYmlsaXR5PWZ1bmN0aW9uKGNvbG9yMSxjb2xvcjIpe3ZhciBhPXRpbnljb2xvcihjb2xvcjEpLnRvUmdiKCksYj10aW55Y29sb3IoY29sb3IyKS50b1JnYigpLGJyaWdodG5lc3NBPSgyOTkqYS5yKzU4NyphLmcrMTE0KmEuYikvMWUzLGJyaWdodG5lc3NCPSgyOTkqYi5yKzU4NypiLmcrMTE0KmIuYikvMWUzLGNvbG9yRGlmZj1NYXRoLm1heChhLnIsYi5yKS1NYXRoLm1pbihhLnIsYi5yKStNYXRoLm1heChhLmcsYi5nKS1NYXRoLm1pbihhLmcsYi5nKStNYXRoLm1heChhLmIsYi5iKS1NYXRoLm1pbihhLmIsYi5iKTtyZXR1cm57YnJpZ2h0bmVzczpNYXRoLmFicyhicmlnaHRuZXNzQS1icmlnaHRuZXNzQiksY29sb3I6Y29sb3JEaWZmfX0sdGlueWNvbG9yLnJlYWRhYmxlPWZ1bmN0aW9uKGNvbG9yMSxjb2xvcjIpe3ZhciByZWFkYWJpbGl0eT10aW55Y29sb3IucmVhZGFiaWxpdHkoY29sb3IxLGNvbG9yMik7cmV0dXJuIHJlYWRhYmlsaXR5LmJyaWdodG5lc3M+MTI1JiZyZWFkYWJpbGl0eS5jb2xvcj41MDB9LHRpbnljb2xvci5tb3N0UmVhZGFibGU9ZnVuY3Rpb24oYmFzZUNvbG9yLGNvbG9yTGlzdCl7Zm9yKHZhciBiZXN0Q29sb3I9bnVsbCxiZXN0U2NvcmU9MCxiZXN0SXNSZWFkYWJsZT0hMSxpPTA7Y29sb3JMaXN0Lmxlbmd0aD5pO2krKyl7dmFyIHJlYWRhYmlsaXR5PXRpbnljb2xvci5yZWFkYWJpbGl0eShiYXNlQ29sb3IsY29sb3JMaXN0W2ldKSxyZWFkYWJsZT1yZWFkYWJpbGl0eS5icmlnaHRuZXNzPjEyNSYmcmVhZGFiaWxpdHkuY29sb3I+NTAwLHNjb3JlPTMqKHJlYWRhYmlsaXR5LmJyaWdodG5lc3MvMTI1KStyZWFkYWJpbGl0eS5jb2xvci81MDA7KHJlYWRhYmxlJiYhYmVzdElzUmVhZGFibGV8fHJlYWRhYmxlJiZiZXN0SXNSZWFkYWJsZSYmc2NvcmU+YmVzdFNjb3JlfHwhcmVhZGFibGUmJiFiZXN0SXNSZWFkYWJsZSYmc2NvcmU+YmVzdFNjb3JlKSYmKGJlc3RJc1JlYWRhYmxlPXJlYWRhYmxlLGJlc3RTY29yZT1zY29yZSxiZXN0Q29sb3I9dGlueWNvbG9yKGNvbG9yTGlzdFtpXSkpfXJldHVybiBiZXN0Q29sb3J9O3ZhciBuYW1lcz10aW55Y29sb3IubmFtZXM9e2FsaWNlYmx1ZToiZjBmOGZmIixhbnRpcXVld2hpdGU6ImZhZWJkNyIsYXF1YToiMGZmIixhcXVhbWFyaW5lOiI3ZmZmZDQiLGF6dXJlOiJmMGZmZmYiLGJlaWdlOiJmNWY1ZGMiLGJpc3F1ZToiZmZlNGM0IixibGFjazoiMDAwIixibGFuY2hlZGFsbW9uZDoiZmZlYmNkIixibHVlOiIwMGYiLGJsdWV2aW9sZXQ6IjhhMmJlMiIsYnJvd246ImE1MmEyYSIsYnVybHl3b29kOiJkZWI4ODciLGJ1cm50c2llbm5hOiJlYTdlNWQiLGNhZGV0Ymx1ZToiNWY5ZWEwIixjaGFydHJldXNlOiI3ZmZmMDAiLGNob2NvbGF0ZToiZDI2OTFlIixjb3JhbDoiZmY3ZjUwIixjb3JuZmxvd2VyYmx1ZToiNjQ5NWVkIixjb3Juc2lsazoiZmZmOGRjIixjcmltc29uOiJkYzE0M2MiLGN5YW46IjBmZiIsZGFya2JsdWU6IjAwMDA4YiIsZGFya2N5YW46IjAwOGI4YiIsZGFya2dvbGRlbnJvZDoiYjg4NjBiIixkYXJrZ3JheToiYTlhOWE5IixkYXJrZ3JlZW46IjAwNjQwMCIsZGFya2dyZXk6ImE5YTlhOSIsZGFya2toYWtpOiJiZGI3NmIiLGRhcmttYWdlbnRhOiI4YjAwOGIiLGRhcmtvbGl2ZWdyZWVuOiI1NTZiMmYiLGRhcmtvcmFuZ2U6ImZmOGMwMCIsZGFya29yY2hpZDoiOTkzMmNjIixkYXJrcmVkOiI4YjAwMDAiLGRhcmtzYWxtb246ImU5OTY3YSIsZGFya3NlYWdyZWVuOiI4ZmJjOGYiLGRhcmtzbGF0ZWJsdWU6IjQ4M2Q4YiIsZGFya3NsYXRlZ3JheToiMmY0ZjRmIixkYXJrc2xhdGVncmV5OiIyZjRmNGYiLGRhcmt0dXJxdW9pc2U6IjAwY2VkMSIsZGFya3Zpb2xldDoiOTQwMGQzIixkZWVwcGluazoiZmYxNDkzIixkZWVwc2t5Ymx1ZToiMDBiZmZmIixkaW1ncmF5OiI2OTY5NjkiLGRpbWdyZXk6IjY5Njk2OSIsZG9kZ2VyYmx1ZToiMWU5MGZmIixmaXJlYnJpY2s6ImIyMjIyMiIsZmxvcmFsd2hpdGU6ImZmZmFmMCIsZm9yZXN0Z3JlZW46IjIyOGIyMiIsZnVjaHNpYToiZjBmIixnYWluc2Jvcm86ImRjZGNkYyIsZ2hvc3R3aGl0ZToiZjhmOGZmIixnb2xkOiJmZmQ3MDAiLGdvbGRlbnJvZDoiZGFhNTIwIixncmF5OiI4MDgwODAiLGdyZWVuOiIwMDgwMDAiLGdyZWVueWVsbG93OiJhZGZmMmYiLGdyZXk6IjgwODA4MCIsaG9uZXlkZXc6ImYwZmZmMCIsaG90cGluazoiZmY2OWI0IixpbmRpYW5yZWQ6ImNkNWM1YyIsaW5kaWdvOiI0YjAwODIiLGl2b3J5OiJmZmZmZjAiLGtoYWtpOiJmMGU2OGMiLGxhdmVuZGVyOiJlNmU2ZmEiLGxhdmVuZGVyYmx1c2g6ImZmZjBmNSIsbGF3bmdyZWVuOiI3Y2ZjMDAiLGxlbW9uY2hpZmZvbjoiZmZmYWNkIixsaWdodGJsdWU6ImFkZDhlNiIsbGlnaHRjb3JhbDoiZjA4MDgwIixsaWdodGN5YW46ImUwZmZmZiIsbGlnaHRnb2xkZW5yb2R5ZWxsb3c6ImZhZmFkMiIsbGlnaHRncmF5OiJkM2QzZDMiLGxpZ2h0Z3JlZW46IjkwZWU5MCIsbGlnaHRncmV5OiJkM2QzZDMiLGxpZ2h0cGluazoiZmZiNmMxIixsaWdodHNhbG1vbjoiZmZhMDdhIixsaWdodHNlYWdyZWVuOiIyMGIyYWEiLGxpZ2h0c2t5Ymx1ZToiODdjZWZhIixsaWdodHNsYXRlZ3JheToiNzg5IixsaWdodHNsYXRlZ3JleToiNzg5IixsaWdodHN0ZWVsYmx1ZToiYjBjNGRlIixsaWdodHllbGxvdzoiZmZmZmUwIixsaW1lOiIwZjAiLGxpbWVncmVlbjoiMzJjZDMyIixsaW5lbjoiZmFmMGU2IixtYWdlbnRhOiJmMGYiLG1hcm9vbjoiODAwMDAwIixtZWRpdW1hcXVhbWFyaW5lOiI2NmNkYWEiLG1lZGl1bWJsdWU6IjAwMDBjZCIsbWVkaXVtb3JjaGlkOiJiYTU1ZDMiLG1lZGl1bXB1cnBsZToiOTM3MGRiIixtZWRpdW1zZWFncmVlbjoiM2NiMzcxIixtZWRpdW1zbGF0ZWJsdWU6IjdiNjhlZSIsbWVkaXVtc3ByaW5nZ3JlZW46IjAwZmE5YSIsbWVkaXVtdHVycXVvaXNlOiI0OGQxY2MiLG1lZGl1bXZpb2xldHJlZDoiYzcxNTg1IixtaWRuaWdodGJsdWU6IjE5MTk3MCIsbWludGNyZWFtOiJmNWZmZmEiLG1pc3R5cm9zZToiZmZlNGUxIixtb2NjYXNpbjoiZmZlNGI1IixuYXZham93aGl0ZToiZmZkZWFkIixuYXZ5OiIwMDAwODAiLG9sZGxhY2U6ImZkZjVlNiIsb2xpdmU6IjgwODAwMCIsb2xpdmVkcmFiOiI2YjhlMjMiLG9yYW5nZToiZmZhNTAwIixvcmFuZ2VyZWQ6ImZmNDUwMCIsb3JjaGlkOiJkYTcwZDYiLHBhbGVnb2xkZW5yb2Q6ImVlZThhYSIscGFsZWdyZWVuOiI5OGZiOTgiLHBhbGV0dXJxdW9pc2U6ImFmZWVlZSIscGFsZXZpb2xldHJlZDoiZGI3MDkzIixwYXBheWF3aGlwOiJmZmVmZDUiLHBlYWNocHVmZjoiZmZkYWI5IixwZXJ1OiJjZDg1M2YiLHBpbms6ImZmYzBjYiIscGx1bToiZGRhMGRkIixwb3dkZXJibHVlOiJiMGUwZTYiLHB1cnBsZToiODAwMDgwIixyZWQ6ImYwMCIscm9zeWJyb3duOiJiYzhmOGYiLHJveWFsYmx1ZToiNDE2OWUxIixzYWRkbGVicm93bjoiOGI0NTEzIixzYWxtb246ImZhODA3MiIsc2FuZHlicm93bjoiZjRhNDYwIixzZWFncmVlbjoiMmU4YjU3IixzZWFzaGVsbDoiZmZmNWVlIixzaWVubmE6ImEwNTIyZCIsc2lsdmVyOiJjMGMwYzAiLHNreWJsdWU6Ijg3Y2VlYiIsc2xhdGVibHVlOiI2YTVhY2QiLHNsYXRlZ3JheToiNzA4MDkwIixzbGF0ZWdyZXk6IjcwODA5MCIsc25vdzoiZmZmYWZhIixzcHJpbmdncmVlbjoiMDBmZjdmIixzdGVlbGJsdWU6IjQ2ODJiNCIsdGFuOiJkMmI0OGMiLHRlYWw6IjAwODA4MCIsdGhpc3RsZToiZDhiZmQ4Iix0b21hdG86ImZmNjM0NyIsdHVycXVvaXNlOiI0MGUwZDAiLHZpb2xldDoiZWU4MmVlIix3aGVhdDoiZjVkZWIzIix3aGl0ZToiZmZmIix3aGl0ZXNtb2tlOiJmNWY1ZjUiLHllbGxvdzoiZmYwIix5ZWxsb3dncmVlbjoiOWFjZDMyIn0saGV4TmFtZXM9dGlueWNvbG9yLmhleE5hbWVzPWZsaXAobmFtZXMpLG1hdGNoZXJzPWZ1bmN0aW9uKCl7dmFyIENTU19JTlRFR0VSPSJbLVxcK10/XFxkKyU/IixDU1NfTlVNQkVSPSJbLVxcK10/XFxkKlxcLlxcZCslPyIsQ1NTX1VOSVQ9Iig/OiIrQ1NTX05VTUJFUisiKXwoPzoiK0NTU19JTlRFR0VSKyIpIixQRVJNSVNTSVZFX01BVENIMz0iW1xcc3xcXChdKygiK0NTU19VTklUKyIpWyx8XFxzXSsoIitDU1NfVU5JVCsiKVssfFxcc10rKCIrQ1NTX1VOSVQrIilcXHMqXFwpPyIsUEVSTUlTU0lWRV9NQVRDSDQ9IltcXHN8XFwoXSsoIitDU1NfVU5JVCsiKVssfFxcc10rKCIrQ1NTX1VOSVQrIilbLHxcXHNdKygiK0NTU19VTklUKyIpWyx8XFxzXSsoIitDU1NfVU5JVCsiKVxccypcXCk/IjtyZXR1cm57cmdiOlJlZ0V4cCgicmdiIitQRVJNSVNTSVZFX01BVENIMykscmdiYTpSZWdFeHAoInJnYmEiK1BFUk1JU1NJVkVfTUFUQ0g0KSxoc2w6UmVnRXhwKCJoc2wiK1BFUk1JU1NJVkVfTUFUQ0gzKSxoc2xhOlJlZ0V4cCgiaHNsYSIrUEVSTUlTU0lWRV9NQVRDSDQpLGhzdjpSZWdFeHAoImhzdiIrUEVSTUlTU0lWRV9NQVRDSDMpLGhleDM6L14oWzAtOWEtZkEtRl17MX0pKFswLTlhLWZBLUZdezF9KShbMC05YS1mQS1GXXsxfSkkLyxoZXg2Oi9eKFswLTlhLWZBLUZdezJ9KShbMC05YS1mQS1GXXsyfSkoWzAtOWEtZkEtRl17Mn0pJC99fSgpOyJ1bmRlZmluZWQiIT10eXBlb2YgbW9kdWxlJiZtb2R1bGUuZXhwb3J0cz9tb2R1bGUuZXhwb3J0cz10aW55Y29sb3I6InVuZGVmaW5lZCIhPXR5cGVvZiBkZWZpbmU/ZGVmaW5lKGZ1bmN0aW9uKCl7cmV0dXJuIHRpbnljb2xvcn0pOnJvb3QudGlueWNvbG9yPXRpbnljb2xvcn0pKHRoaXMpOwovKgogICAgKiBQaWNrLWEtQ29sb3IgSlMgdjEuMi4zCiAgICAqIENvcHlyaWdodCAyMDEzIExhdXJlbiBTcGVyYmVyIGFuZCBCcm9hZHN0cmVldCBBZHMKICAgICogaHR0cHM6Ly9naXRodWIuY29tL2xhdXJlbi9waWNrLWEtY29sb3IvYmxvYi9tYXN0ZXIvTElDRU5TRQoqLwohZnVuY3Rpb24obyl7InVzZSBzdHJpY3QiO28uZm4ucGlja0FDb2xvcj1mdW5jdGlvbih0KXt2b2lkIDA9PT10LnRvdWNoT25seU1vZGUmJih0LnRvdWNoT25seU1vZGU9ITEpO3ZhciBlPSJvbnRvdWNoc3RhcnQiaW4gd2luZG93JiZ0LnRvdWNoT25seU1vZGUsYT0ocGFyc2VJbnQobyh3aW5kb3cpLndpZHRoKCksMTApPDc2Nz8hMDohMSwibG9jYWxTdG9yYWdlImluIHdpbmRvdyYmbnVsbCE9PXdpbmRvdy5sb2NhbFN0b3JhZ2UmJiJvYmplY3QiPT10eXBlb2YgSlNPTiksbj1kb2N1bWVudC5hbGwmJiF3aW5kb3cuYXRvYixyPWU/InRvdWNoc3RhcnQucGlja0FDb2xvciI6Im1vdXNlZG93bi5waWNrQUNvbG9yIixzPWU/InRvdWNobW92ZS5waWNrQUNvbG9yIjoibW91c2Vtb3ZlLnBpY2tBQ29sb3IiLGk9ZT8idG91Y2hlbmQucGlja0FDb2xvciI6Im1vdXNldXAucGlja0FDb2xvciIsbD1lPyJ0b3VjaGVuZC5waWNrQUNvbG9yIjoiY2xpY2sucGlja0FDb2xvciIsZD0iZHJhZ2dpbmcucGlja0FDb2xvciIsYz0iZW5kRHJhZy5waWNrQUNvbG9yIixwPW8uZXh0ZW5kKHtzaG93U3BlY3RydW06ITAsc2hvd1NhdmVkQ29sb3JzOiEwLHNhdmVDb2xvcnNQZXJFbGVtZW50OiExLGZhZGVNZW51VG9nZ2xlOiEwLHNob3dBZHZhbmNlZDohMCxzaG93QmFzaWNDb2xvcnM6ITAsc2hvd0hleElucHV0OiEwLGFsbG93Qmxhbms6ITEsaW5saW5lRHJvcGRvd246ITEsYmFzaWNDb2xvcnM6e3doaXRlOiJmZmYiLHJlZDoiZjAwIixvcmFuZ2U6ImY2MCIseWVsbG93OiJmZjAiLGdyZWVuOiIwMDgwMDAiLGJsdWU6IjAwZiIscHVycGxlOiI4MDAwODAiLGJsYWNrOiIwMDAifX0sdCk7cC5zaG93QWR2YW5jZWR8fHAuc2hvd0Jhc2ljQ29sb3JzfHwocC5zaG93QmFzaWNDb2xvcnM9ITApO3ZhciB1PXAuc2hvd1NhdmVkQ29sb3JzJiZwLnNob3dBZHZhbmNlZHx8cC5zaG93QmFzaWNDb2xvcnMmJnAuc2hvd1NhdmVkQ29sb3JzfHxwLnNob3dCYXNpY0NvbG9ycyYmcC5zaG93QWR2YW5jZWQsaD1mdW5jdGlvbigpe3ZhciB0PW8oIjxkaXY+IikuYWRkQ2xhc3MoImlucHV0LWdyb3VwLWJ0biIpLGU9bygiPGJ1dHRvbiB0eXBlPSdidXR0b24nPiIpLmFkZENsYXNzKCJidG4gYnRuLWRlZmF1bHQgY29sb3ItZHJvcGRvd24gZHJvcGRvd24tdG9nZ2xlIiksYT1vKCI8c3Bhbj4iKS5hZGRDbGFzcygiY29sb3ItcHJldmlldyBjdXJyZW50LWNvbG9yIikscj1vKCI8c3Bhbj4iKS5hZGRDbGFzcygiY2FyZXQiKSxzPW8oIjxkaXY+IikuYWRkQ2xhc3MoImNvbG9yLW1lbnUgZHJvcGRvd24tbWVudSIpO2lmKHAuaW5saW5lRHJvcGRvd24mJnMuYWRkQ2xhc3MoImNvbG9yLW1lbnUtLWlubGluZSIpLHAuc2hvd0hleElucHV0fHwoZS5hZGRDbGFzcygibm8taGV4Iikscy5hZGRDbGFzcygibm8taGV4IikpLHQuYXBwZW5kKGUuYXBwZW5kKGEpLmFwcGVuZChyKSksdXx8cC5zaG93U3BlY3RydW18fHMuYWRkQ2xhc3MoInNtYWxsIiksdSl7dmFyIGk9bygiPGRpdj4iKS5hZGRDbGFzcygiY29sb3ItbWVudS10YWJzIiksbD1wLnNob3dCYXNpY0NvbG9ycz8ic2F2ZWRDb2xvcnMtdGFiIHRhYiI6InNhdmVkQ29sb3JzLXRhYiB0YWIgdGFiLWFjdGl2ZSI7cC5zaG93QmFzaWNDb2xvcnMmJmkuYXBwZW5kKG8oIjxzcGFuPiIpLmFkZENsYXNzKCJiYXNpY0NvbG9ycy10YWIgdGFiIHRhYi1hY3RpdmUiKS5hcHBlbmQobygiPGE+IikudGV4dCgiQmFzaWMgQ29sb3JzIikpKSxwLnNob3dTYXZlZENvbG9ycyYmaS5hcHBlbmQobygiPHNwYW4+IikuYWRkQ2xhc3MobCkuYXBwZW5kKG8oIjxhPiIpLnRleHQoIlNhdmVkIENvbG9ycyIpKSkscC5zaG93QWR2YW5jZWQmJmkuYXBwZW5kKG8oIjxzcGFuPiIpLmFkZENsYXNzKCJhZHZhbmNlZC10YWIgdGFiIikuYXBwZW5kKG8oIjxhPiIpLnRleHQoIkFkdmFuY2VkIikpKSxzLmFwcGVuZChpKX1pZihwLnNob3dCYXNpY0NvbG9ycyl7dmFyIGQ9bygiPGRpdj4iKS5hZGRDbGFzcygiYmFzaWNDb2xvcnMtY29udGVudCBhY3RpdmUtY29udGVudCIpO3Auc2hvd1NwZWN0cnVtJiZkLmFwcGVuZChvKCI8aDY+IikuYWRkQ2xhc3MoImNvbG9yLW1lbnUtaW5zdHJ1Y3Rpb25zIikudGV4dCgiVGFwIHNwZWN0cnVtIG9yIGRyYWcgYmFuZCB0byBjaGFuZ2UgY29sb3IiKSk7dmFyIGM9bygiPHVsPiIpLmFkZENsYXNzKCJiYXNpYy1jb2xvcnMtbGlzdCIpO28uZWFjaChwLmJhc2ljQ29sb3JzLGZ1bmN0aW9uKHQsZSl7dmFyIGE9bygiPGxpPiIpLmFkZENsYXNzKCJjb2xvci1pdGVtIikscj1vKCI8YT4iKS5hZGRDbGFzcyh0KyIgY29sb3ItbGluayIpLHM9bygiPHNwYW4+IikuYWRkQ2xhc3MoImNvbG9yLXByZXZpZXcgIit0KSxpPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJjb2xvci1sYWJlbCIpLnRleHQodCk7aWYoci5hcHBlbmQocyxpKSxzLmFwcGVuZCgpLCIjIiE9PWVbMF0mJihlPSIjIitlKSxzLmNzcygiYmFja2dyb3VuZC1jb2xvciIsZSkscC5zaG93U3BlY3RydW0pe3ZhciBsPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJjb2xvci1ib3ggc3BlY3RydW0tIit0KTtuJiZvLmVhY2goWzAsMV0sZnVuY3Rpb24oYSl7ImZmZiIhPT1lJiYiMDAwIiE9PXQmJmwuYXBwZW5kKG8oIjxzcGFuPiIpLmFkZENsYXNzKHQrIi1zcGVjdHJ1bS0iK2ErIiBpZS1zcGVjdHJ1bSIpKX0pO3ZhciBkPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJoaWdobGlnaHQtYmFuZCIpO28uZWFjaChbMCwxLDJdLGZ1bmN0aW9uKCl7ZC5hcHBlbmQobygiPHNwYW4+IikuYWRkQ2xhc3MoImhpZ2hsaWdodC1iYW5kLXN0cmlwZSIpKX0pLHIuYXBwZW5kKGwuYXBwZW5kKGQpKX1jLmFwcGVuZChhLmFwcGVuZChyKSl9KSxzLmFwcGVuZChkLmFwcGVuZChjKSl9aWYocC5zaG93U2F2ZWRDb2xvcnMpe3ZhciBoPXAuc2hvd0Jhc2ljQ29sb3JzPyJpbmFjdGl2ZS1jb250ZW50IjoiYWN0aXZlLWNvbnRlbnQiLGc9bygiPGRpdj4iKS5hZGRDbGFzcygic2F2ZWRDb2xvcnMtY29udGVudCIpLmFkZENsYXNzKGgpO2cuYXBwZW5kKG8oIjxwPiIpLmFkZENsYXNzKCJzYXZlZC1jb2xvcnMtaW5zdHJ1Y3Rpb25zIikudGV4dCgiVHlwZSBpbiBhIGNvbG9yIG9yIHVzZSB0aGUgc3BlY3RydW1zIHRvIGxpZ2h0ZW4gb3IgZGFya2VuIGFuIGV4aXN0aW5nIGNvbG9yLiIpKSxzLmFwcGVuZChnKX1pZihwLnNob3dBZHZhbmNlZCl7dmFyIHY9cC5zaG93QmFzaWNDb2xvcnN8fHAuc2hvd1NhdmVkQ29sb3JzPyJpbmFjdGl2ZS1jb250ZW50IjoiYWN0aXZlLWNvbnRlbnQiLGY9bygiPGRpdj4iKS5hZGRDbGFzcygiYWR2YW5jZWQtY29udGVudCIpLmFkZENsYXNzKHYpLmFwcGVuZChvKCI8aDY+IikuYWRkQ2xhc3MoImFkdmFuY2VkLWluc3RydWN0aW9ucyIpLnRleHQoIlRhcCBzcGVjdHJ1bSBvciBkcmFnIGJhbmQgdG8gY2hhbmdlIGNvbG9yIikpLEM9bygiPHVsPiIpLmFkZENsYXNzKCJhZHZhbmNlZC1saXN0IiksbT1vKCI8bGk+IikuYWRkQ2xhc3MoImh1ZS1pdGVtIiksYj1vKCI8c3Bhbj4iKS5hZGRDbGFzcygiaHVlLXRleHQiKS50ZXh0KCJIdWU6ICIpLmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygiaHVlLXZhbHVlIikudGV4dCgiMCIpKSx3PW8oIjxzcGFuPiIpLmFkZENsYXNzKCJjb2xvci1ib3ggc3BlY3RydW0taHVlIik7biYmby5lYWNoKFswLDEsMiwzLDQsNSw2XSxmdW5jdGlvbih0KXt3LmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygiaHVlLXNwZWN0cnVtLSIrdCsiIGllLXNwZWN0cnVtIGh1ZSIpKX0pO3ZhciBTPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJoaWdobGlnaHQtYmFuZCIpO28uZWFjaChbMCwxLDJdLGZ1bmN0aW9uKCl7Uy5hcHBlbmQobygiPHNwYW4+IikuYWRkQ2xhc3MoImhpZ2hsaWdodC1iYW5kLXN0cmlwZSIpKX0pLEMuYXBwZW5kKG0uYXBwZW5kKGIpLmFwcGVuZCh3LmFwcGVuZChTKSkpO3ZhciB5PW8oIjxsaT4iKS5hZGRDbGFzcygibGlnaHRuZXNzLWl0ZW0iKSxrPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJjb2xvci1ib3ggc3BlY3RydW0tbGlnaHRuZXNzIikseD1vKCI8c3Bhbj4iKS5hZGRDbGFzcygibGlnaHRuZXNzLXRleHQiKS50ZXh0KCJMaWdodG5lc3M6ICIpLmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygibGlnaHRuZXNzLXZhbHVlIikudGV4dCgiNTAlIikpO24mJm8uZWFjaChbMCwxXSxmdW5jdGlvbih0KXtrLmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygibGlnaHRuZXNzLXNwZWN0cnVtLSIrdCsiIGllLXNwZWN0cnVtIikpfSk7dmFyIEg9bygiPHNwYW4+IikuYWRkQ2xhc3MoImhpZ2hsaWdodC1iYW5kIik7by5lYWNoKFswLDEsMl0sZnVuY3Rpb24oKXtILmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygiaGlnaGxpZ2h0LWJhbmQtc3RyaXBlIikpfSksQy5hcHBlbmQoeS5hcHBlbmQoeCkuYXBwZW5kKGsuYXBwZW5kKEgpKSk7dmFyIEE9bygiPGxpPiIpLmFkZENsYXNzKCJzYXR1cmF0aW9uLWl0ZW0iKSxCPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJjb2xvci1ib3ggc3BlY3RydW0tc2F0dXJhdGlvbiIpO24mJm8uZWFjaChbMCwxXSxmdW5jdGlvbih0KXtCLmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygic2F0dXJhdGlvbi1zcGVjdHJ1bS0iK3QrIiBpZS1zcGVjdHJ1bSIpKX0pO3ZhciBNPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJoaWdobGlnaHQtYmFuZCIpO28uZWFjaChbMCwxLDJdLGZ1bmN0aW9uKCl7TS5hcHBlbmQobygiPHNwYW4+IikuYWRkQ2xhc3MoImhpZ2hsaWdodC1iYW5kLXN0cmlwZSIpKX0pO3ZhciBJPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJzYXR1cmF0aW9uLXRleHQiKS50ZXh0KCJTYXR1cmF0aW9uOiAiKS5hcHBlbmQobygiPHNwYW4+IikuYWRkQ2xhc3MoInNhdHVyYXRpb24tdmFsdWUiKS50ZXh0KCIxMDAlIikpO0MuYXBwZW5kKEEuYXBwZW5kKEkpLmFwcGVuZChCLmFwcGVuZChNKSkpO3ZhciBUPW8oIjxsaT4iKS5hZGRDbGFzcygicHJldmlldy1pdGVtIikuYXBwZW5kKG8oIjxzcGFuPiIpLmFkZENsYXNzKCJwcmV2aWV3LXRleHQiKS50ZXh0KCJQcmV2aWV3IikpLFA9bygiPHNwYW4+IikuYWRkQ2xhc3MoImNvbG9yLXByZXZpZXcgYWR2YW5jZWQiKS5hcHBlbmQoIjxidXR0b24gY2xhc3M9J2NvbG9yLXNlbGVjdCBidG4gYnRuLW1pbmkgYWR2YW5jZWQnIHR5cGU9J2J1dHRvbic+U2VsZWN0PC9idXR0b24+Iik7Qy5hcHBlbmQoVC5hcHBlbmQoUCkpLHMuYXBwZW5kKGYuYXBwZW5kKEMpKX1yZXR1cm4gdC5hcHBlbmQocyksdH0sZz17fSx2PXtyb3dzSW5Ecm9wZG93bjo4LG1heENvbHNJbkRyb3Bkb3duOjJ9O2lmKHAuc2hvd1NhdmVkQ29sb3JzKXt2YXIgZj1bXTtpZihhJiZsb2NhbFN0b3JhZ2UuYWxsU2F2ZWRDb2xvcnMpZj1KU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5hbGxTYXZlZENvbG9ycyk7ZWxzZSBpZihkb2N1bWVudC5jb29raWUubWF0Y2goInBpY2tBQ29sb3JTYXZlZENvbG9ycy1hbGxTYXZlZENvbG9ycz0iKSl7dmFyIEM9ZG9jdW1lbnQuY29va2llLnNwbGl0KCI7Iik7by5lYWNoKEMsZnVuY3Rpb24obyl7Q1tvXS5tYXRjaCgicGlja0FDb2xvclNhdmVkQ29sb3JzLWFsbFNhdmVkQ29sb3JzPSIpJiYoZj1DW29dLnNwbGl0KCI9IilbMV0uc3BsaXQoIiwiKSl9KX19dmFyIG09e2luaXRpYWxpemU6ZnVuY3Rpb24odCl7dmFyIGUsYSxuPW8odGhpcyk7bi5hdHRyKCJuYW1lIil8fG4uYXR0cigibmFtZSIsInBpY2stYS1jb2xvci0iK3QpLGE9bi5hdHRyKCJuYW1lIiksbi5hZGRDbGFzcygicGljay1hLWNvbG9yIikscC5hbGxvd0JsYW5rP24udmFsKCkubWF0Y2goL15ccyskfF4kLyl8fChnLmRlZmF1bHRDb2xvcj10aW55Y29sb3Iobi52YWwoKSkudG9IZXgoKSxnLnR5cGVkQ29sb3I9Zy5kZWZhdWx0Q29sb3Isbi52YWwoZy5kZWZhdWx0Q29sb3IpKTooZy5kZWZhdWx0Q29sb3I9dGlueWNvbG9yKG4udmFsKCkpLnRvSGV4KCksZy50eXBlZENvbG9yPWcuZGVmYXVsdENvbG9yLG4udmFsKGcuZGVmYXVsdENvbG9yKSksbyhuKS53cmFwKCc8ZGl2IGNsYXNzPSJpbnB1dC1ncm91cCBwaWNrLWEtY29sb3ItbWFya3VwIiBpZD0iJythKyciPicpLGU9byhuLnBhcmVudCgpKSxwLnNob3dIZXhJbnB1dD9lLnByZXBlbmQoJzxzcGFuIGNsYXNzPSJoZXgtcG91bmQgaW5wdXQtZ3JvdXAtYWRkb24iPiM8L3NwYW4+JykuYXBwZW5kKGgoKSk6ZS5hcHBlbmQoaCgpKSxwLnNob3dIZXhJbnB1dHx8bi5hdHRyKCJ0eXBlIiwiaGlkZGVuIil9LHVwZGF0ZVByZXZpZXc6ZnVuY3Rpb24obyl7cC5hbGxvd0JsYW5rPyhnLnR5cGVkQ29sb3I9by52YWwoKS5tYXRjaCgvXlxzKyR8XiQvKT8iIjp0aW55Y29sb3Ioby52YWwoKSkudG9IZXgoKSwiIj09PWcudHlwZWRDb2xvcj9vLnNpYmxpbmdzKCIuaW5wdXQtZ3JvdXAtYnRuIikuZmluZCgiLmN1cnJlbnQtY29sb3IiKS5jc3MoImJhY2tncm91bmQiLCJub25lIik6by5zaWJsaW5ncygiLmlucHV0LWdyb3VwLWJ0biIpLmZpbmQoIi5jdXJyZW50LWNvbG9yIikuY3NzKCJiYWNrZ3JvdW5kLWNvbG9yIiwiIyIrZy50eXBlZENvbG9yKSk6KGcudHlwZWRDb2xvcj10aW55Y29sb3Ioby52YWwoKSkudG9IZXgoKSxvLnNpYmxpbmdzKCIuaW5wdXQtZ3JvdXAtYnRuIikuZmluZCgiLmN1cnJlbnQtY29sb3IiKS5jc3MoImJhY2tncm91bmQtY29sb3IiLCIjIitnLnR5cGVkQ29sb3IpKX0scHJlc3NQcmV2aWV3QnV0dG9uOmZ1bmN0aW9uKCl7dmFyIG89YXJndW1lbnRzWzBdLnRoaXNFdmVudDtvLnN0b3BQcm9wYWdhdGlvbigpLG0udG9nZ2xlRHJvcGRvd24oby50YXJnZXQpfSxvcGVuRHJvcGRvd246ZnVuY3Rpb24odCxhKXtvKCIuY29sb3ItbWVudSIpLmVhY2goZnVuY3Rpb24oKXt2YXIgdD1vKHRoaXMpO2lmKCJibG9jayI9PT10LmNzcygiZGlzcGxheSIpKXt2YXIgZT10LnBhcmVudHMoIi5pbnB1dC1ncm91cC1idG4iKTttLmNsb3NlRHJvcGRvd24oZSx0KX19KSxwLmZhZGVNZW51VG9nZ2xlJiYhZT9vKGEpLmZhZGVJbigiZmFzdCIpOm8oYSkuc2hvdygpLG8odCkuYWRkQ2xhc3MoIm9wZW4iKX0sY2xvc2VEcm9wZG93bjpmdW5jdGlvbih0LGEpe3AuZmFkZU1lbnVUb2dnbGUmJiFlP28oYSkuZmFkZU91dCgiZmFzdCIpOm8oYSkuY3NzKCJkaXNwbGF5Iiwibm9uZSIpLG8odCkucmVtb3ZlQ2xhc3MoIm9wZW4iKX0sY2xvc2VEcm9wZG93bklmT3BlbjpmdW5jdGlvbigpe3ZhciBvPWFyZ3VtZW50c1swXS5idXR0b24sdD1hcmd1bWVudHNbMF0ubWVudTsiYmxvY2siPT09dC5jc3MoImRpc3BsYXkiKSYmbS5jbG9zZURyb3Bkb3duKG8sdCl9LHRvZ2dsZURyb3Bkb3duOmZ1bmN0aW9uKHQpe3ZhciBlPW8odCkucGFyZW50cygiLnBpY2stYS1jb2xvci1tYXJrdXAiKSxhPWUuZmluZCgiaW5wdXQiKSxuPWUuZmluZCgiLmlucHV0LWdyb3VwLWJ0biIpLHI9ZS5maW5kKCIuY29sb3ItbWVudSIpO2EuaXMoIjpkaXNhYmxlZCIpfHwibm9uZSIhPT1yLmNzcygiZGlzcGxheSIpP20uY2xvc2VEcm9wZG93bihuLHIpOm0ub3BlbkRyb3Bkb3duKG4scil9LHRhYmJhYmxlOmZ1bmN0aW9uKCl7dmFyIHQ9byh0aGlzKSxlPXQucGFyZW50cygiLnBpY2stYS1jb2xvci1tYXJrdXAiKTt0LmNsaWNrKGZ1bmN0aW9uKCl7dmFyIHQ9byh0aGlzKSxhPXQuYXR0cigiY2xhc3MiKS5zcGxpdCgiICIpWzBdLnNwbGl0KCItIilbMF0rIi1jb250ZW50IixuPXQucGFyZW50cygiLmRyb3Bkb3duLW1lbnUiKS5maW5kKCIuIithKTt0Lmhhc0NsYXNzKCJ0YWItYWN0aXZlIil8fChlLmZpbmQoIi50YWItYWN0aXZlIikucmVtb3ZlQ2xhc3MoInRhYi1hY3RpdmUiKSxlLmZpbmQoIi5hY3RpdmUtY29udGVudCIpLnJlbW92ZUNsYXNzKCJhY3RpdmUtY29udGVudCIpLmFkZENsYXNzKCJpbmFjdGl2ZS1jb250ZW50IiksdC5hZGRDbGFzcygidGFiLWFjdGl2ZSIpLG8obikuYWRkQ2xhc3MoImFjdGl2ZS1jb250ZW50IikucmVtb3ZlQ2xhc3MoImluYWN0aXZlLWNvbnRlbnQiKSl9KX0sZ2V0Q29sb3JNdWx0aXBsaWVyOmZ1bmN0aW9uKHQsYSxuKXt2YXIgcj0iYmFzaWMiPT09bj9wYXJzZUludChvKCIuY29sb3ItYm94IikuZmlyc3QoKS53aWR0aCgpLDEwKTpwYXJzZUludChvKCIuYWR2YW5jZWQtbGlzdCIpLmZpbmQoIi5jb2xvci1ib3giKS5maXJzdCgpLndpZHRoKCksMTApOzA9PT1yJiYocj0iYmFzaWMiPT09bj9lPzE2MDoyMDA6ZT8xNjA6MzAwKTt2YXIgcz1yLzIsaT1hL3I7cmV0dXJuImJpZGlyZWN0aW9uYWwiPT09dD8uNT49aT8oMS1hL3MpLzI6LSgoYS1zKS9zKS8yOiJkYXJrZW5SaWdodCI9PT10Py0oaS8yKTppLzJ9LG1vZGlmeUhTTExpZ2h0bmVzczpmdW5jdGlvbihvLHQpe3ZhciBlPW87cmV0dXJuIGUubCs9dCxlLmw9TWF0aC5taW4oTWF0aC5tYXgoMCxlLmwpLDEpLHRpbnljb2xvcihlKS50b0hzbFN0cmluZygpfSxnZXRNb3ZlYWJsZUFyZWE6ZnVuY3Rpb24obyl7dmFyIHQ9e30sZT1vLnBhcmVudCgpLGE9by5vdXRlcldpZHRoKCksbj1lLndpZHRoKCkscj1lLm9mZnNldCgpO3JldHVybiB0Lm1pblg9ci5sZWZ0LHQubWF4WD1uLWEsdH0sbW92ZUhpZ2hsaWdodEJhbmQ6ZnVuY3Rpb24odCxhLG4pe3ZhciByPW8oIi5oaWdobGlnaHQtYmFuZCIpLmZpcnN0KCkub3V0ZXJXaWR0aCgpLHM9Ljc1KnIsaT1lP24ub3JpZ2luYWxFdmVudC5wYWdlWDpuLnBhZ2VYLGw9aS1hLm1pblgtcztsPU1hdGgubWF4KDAsTWF0aC5taW4obCxhLm1heFgpKSx0LmNzcygicG9zaXRpb24iLCJhYnNvbHV0ZSIpLHQuY3NzKCJsZWZ0IixsKX0saG9yaXpvbnRhbGx5RHJhZ2dhYmxlOmZ1bmN0aW9uKCl7byh0aGlzKS5vbihyLGZ1bmN0aW9uKHQpe3QucHJldmVudERlZmF1bHQoKTt2YXIgZT1vKHQuZGVsZWdhdGVUYXJnZXQpO2UuY3NzKCJjdXJzb3IiLCItd2Via2l0LWdyYWJiaW5nIiksZS5jc3MoImN1cnNvciIsIi1tb3otZ3JhYmJpbmciKTt2YXIgYT1tLmdldE1vdmVhYmxlQXJlYShlKTtvKGRvY3VtZW50KS5vbihzLGZ1bmN0aW9uKG8pe2UudHJpZ2dlcihkKSxtLm1vdmVIaWdobGlnaHRCYW5kKGUsYSxvKX0pLm9uKGksZnVuY3Rpb24odCl7byhkb2N1bWVudCkub2ZmKHMpLG8oZG9jdW1lbnQpLm9mZihkKSxlLmNzcygiY3Vyc29yIiwiLXdlYmtpdC1ncmFiIiksZS5jc3MoImN1cnNvciIsIi1tb3otZ3JhYiIpLGUudHJpZ2dlcihjKSxvKGRvY3VtZW50KS5vZmYoaSl9KX0pLm9uKGksZnVuY3Rpb24odCl7dC5zdG9wUHJvcGFnYXRpb24oKSxvKGRvY3VtZW50KS5vZmYocyksbyhkb2N1bWVudCkub2ZmKGQpfSl9LG1vZGlmeUhpZ2hsaWdodEJhbmQ6ZnVuY3Rpb24obyx0LGUpe3ZhciBhPXtoOjAsczowLGw6LjA1fSxuPXtoOjAsczowLGw6LjV9LHI9LXQscz1vLmZpbmQoIi5oaWdobGlnaHQtYmFuZC1zdHJpcGUiKSxpPSJsaWdodGVuUmlnaHQiPT09ZT9tLm1vZGlmeUhTTExpZ2h0bmVzcyhuLHIpOm0ubW9kaWZ5SFNMTGlnaHRuZXNzKGEscik7by5jc3MoImJvcmRlci1jb2xvciIsaSkscy5jc3MoImJhY2tncm91bmQtY29sb3IiLGkpfSxjYWxjdWxhdGVIaWdobGlnaHRlZENvbG9yOmZ1bmN0aW9uKCl7dmFyIHQsZSxhLG4scixzLGksbCxkPW8odGhpcyksYz1kLnBhcmVudCgpLHU9bygiLmhpZ2hsaWdodC1iYW5kIikuZmlyc3QoKS5vdXRlcldpZHRoKCksaD11LzIsZz1hcmd1bWVudHNbMF0udHlwZTtpZigiYmFzaWMiPT09Zyl7dmFyIHY9Yy5hdHRyKCJjbGFzcyIpLnNwbGl0KCItIilbMl0sZj1wLmJhc2ljQ29sb3JzW3ZdO3N3aXRjaChlPXRpbnljb2xvcihmKS50b0hzbCgpLGYpe2Nhc2UiZmZmIjp0PSJkYXJrZW5SaWdodCI7YnJlYWs7Y2FzZSIwMDAiOnQ9ImxpZ2h0ZW5SaWdodCI7YnJlYWs7ZGVmYXVsdDp0PSJiaWRpcmVjdGlvbmFsIn19ZWxzZXt2YXIgQz1kLnBhcmVudHMoIi5hZHZhbmNlZC1saXN0Iik7bj1hcmd1bWVudHNbMF0uaHNsLnMsaT1DLmZpbmQoIi5zcGVjdHJ1bS1odWUiKSxhPWFyZ3VtZW50c1swXS5oc2wuaCxzPUMuZmluZCgiLnNwZWN0cnVtLXNhdHVyYXRpb24iKSxsPUMuZmluZCgiLmxpZ2h0bmVzcy12YWx1ZSIpLHI9Qy5maW5kKCIuY29sb3ItcHJldmlldyIpLGU9e2g6YXJndW1lbnRzWzBdLmhzbC5oLGw6LjUsczphcmd1bWVudHNbMF0uaHNsLnN9LHQ9ImJpZGlyZWN0aW9uYWwifXZhciBiPXBhcnNlSW50KGQuY3NzKCJsZWZ0IiksMTApK2gsdz1tLmdldENvbG9yTXVsdGlwbGllcih0LGIsZyksUz1tLm1vZGlmeUhTTExpZ2h0bmVzcyhlLHcpLHk9IiMiK3Rpbnljb2xvcihTKS50b0hleCgpLGs9Uy5zcGxpdCgiKCIpWzFdLnNwbGl0KCIpIilbMF0uc3BsaXQoIiwiKVsyXSx4PXBhcnNlSW50KGsuc3BsaXQoIiUiKVswXSwxMCkvMTAwO3JldHVybiJiYXNpYyI9PT1nPyhjLnNpYmxpbmdzKCIuY29sb3ItcHJldmlldyIpLmNzcygiYmFja2dyb3VuZC1jb2xvciIseSksYy5wcmV2KCIuY29sb3ItbGFiZWwiKS5yZXBsYWNlV2l0aCgnPGJ1dHRvbiBjbGFzcz0iY29sb3Itc2VsZWN0IGJ0biBidG4tbWluaSIgdHlwZT0iYnV0dG9uIj5TZWxlY3Q8L2J1dHRvbj4nKSwiZGFya2VuUmlnaHQiIT09dCYmbS5tb2RpZnlIaWdobGlnaHRCYW5kKGQsdyx0KSk6KHIuY3NzKCJiYWNrZ3JvdW5kLWNvbG9yIix5KSxsLnRleHQoayksbS51cGRhdGVTYXR1cmF0aW9uU3R5bGVzKHMsYSx4KSxtLnVwZGF0ZUh1ZVN0eWxlcyhpLG4seCksbS5tb2RpZnlIaWdobGlnaHRCYW5kKG8oIi5hZHZhbmNlZC1jb250ZW50IC5oaWdobGlnaHQtYmFuZCIpLHcsdCkpLCJiYXNpYyI9PT1nP3Rpbnljb2xvcihTKS50b0hleCgpOnh9LHVwZGF0ZVNhdmVkQ29sb3JQcmV2aWV3OmZ1bmN0aW9uKHQpe28uZWFjaCh0LGZ1bmN0aW9uKGUpe3ZhciBhPW8odFtlXSksbj1hLmF0dHIoImNsYXNzIik7YS5maW5kKCIuY29sb3ItcHJldmlldyIpLmNzcygiYmFja2dyb3VuZC1jb2xvciIsbil9KX0sdXBkYXRlU2F2ZWRDb2xvck1hcmt1cDpmdW5jdGlvbih0LGUpe2lmKGU9ZT9lOmYscC5zaG93U2F2ZWRDb2xvcnMmJmUubGVuZ3RoPjApe3Auc2F2ZUNvbG9yc1BlckVsZW1lbnR8fCh0PW8oIi5zYXZlZENvbG9ycy1jb250ZW50IiksZT1mKTt2YXIgYT12LnJvd3NJbkRyb3Bkb3duKnYubWF4Q29sc0luRHJvcGRvd247ZT1lLnNsaWNlKDAsYSk7dmFyIG49bygiPHVsPiIpLmFkZENsYXNzKCJzYXZlZC1jb2xvci1jb2wgMCIpLHI9bygiPHVsPiIpLmFkZENsYXNzKCJzYXZlZC1jb2xvci1jb2wgMSIpO28uZWFjaChlLGZ1bmN0aW9uKHQsZSl7dmFyIGE9bygiPGxpPiIpLmFkZENsYXNzKCJjb2xvci1pdGVtIikscz1vKCI8YT4iKS5hZGRDbGFzcyhlKTtzLmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygiY29sb3ItcHJldmlldyIpKSxzLmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygiY29sb3ItbGFiZWwiKS50ZXh0KGUpKSxhLmFwcGVuZChzKSx0JTI9PT0wP24uYXBwZW5kKGEpOnIuYXBwZW5kKGEpfSksdC5odG1sKG4pLHQuYXBwZW5kKHIpO3ZhciBzPW8odCkuZmluZCgiYSIpO20udXBkYXRlU2F2ZWRDb2xvclByZXZpZXcocyl9fSxzZXRTYXZlZENvbG9yc0Nvb2tpZTpmdW5jdGlvbihvLHQpe3ZhciBlPW5ldyBEYXRlLGE9MzE1MzZlNyxuPW5ldyBEYXRlKGUuZ2V0VGltZSgpK2EpO249bi50b0dNVFN0cmluZygpLCJ1bmRlZmluZWQiPT10eXBlb2YgdD9kb2N1bWVudC5jb29raWU9InBpY2tBQ29sb3JTYXZlZENvbG9ycy1hbGxTYXZlZENvbG9ycz0iK28rIjtleHBpcmVzPSIrbjpkb2N1bWVudC5jb29raWU9InBpY2tBQ29sb3JTYXZlZENvbG9ycy0iK3QrIj0iK28rIjsgZXhwaXJlcz0iK259LHNhdmVDb2xvcnNUb0xvY2FsU3RvcmFnZTpmdW5jdGlvbihvLHQpe2lmKGEpaWYoInVuZGVmaW5lZCI9PXR5cGVvZiB0KXRyeXtsb2NhbFN0b3JhZ2UuYWxsU2F2ZWRDb2xvcnM9SlNPTi5zdHJpbmdpZnkobyl9Y2F0Y2goZSl7bG9jYWxTdG9yYWdlLmNsZWFyKCl9ZWxzZSB0cnl7bG9jYWxTdG9yYWdlWyJwaWNrQUNvbG9yU2F2ZWRDb2xvcnMtIit0XT1KU09OLnN0cmluZ2lmeShvKX1jYXRjaChlKXtsb2NhbFN0b3JhZ2UuY2xlYXIoKX1lbHNlIG0uc2V0U2F2ZWRDb2xvcnNDb29raWUobyx0KX0scmVtb3ZlRnJvbUFycmF5OmZ1bmN0aW9uKHQsZSl7LTEhPT1vLmluQXJyYXkoZSx0KSYmdC5zcGxpY2Uoby5pbkFycmF5KGUsdCksMSl9LHVwZGF0ZVNhdmVkQ29sb3JzOmZ1bmN0aW9uKG8sdCxlKXttLnJlbW92ZUZyb21BcnJheSh0LG8pLHQudW5zaGlmdChvKSxtLnNhdmVDb2xvcnNUb0xvY2FsU3RvcmFnZSh0LGUpfSxhZGRUb1NhdmVkQ29sb3JzOmZ1bmN0aW9uKG8sdCxlKXtpZihwLnNob3dTYXZlZENvbG9ycyYmdm9pZCAwIT09bylpZigiIyIhPW9bMF0mJihvPSIjIitvKSxtLnVwZGF0ZVNhdmVkQ29sb3JzKG8sZikscC5zYXZlQ29sb3JzUGVyRWxlbWVudCl7dmFyIGE9dC5jb2xvcnMsbj10LmRhdGFBdHRyO20udXBkYXRlU2F2ZWRDb2xvcnMobyxhLG4pLG0udXBkYXRlU2F2ZWRDb2xvck1hcmt1cChlLGEpfWVsc2UgbS51cGRhdGVTYXZlZENvbG9yTWFya3VwKGUsZil9LHNlbGVjdEZyb21CYXNpY0NvbG9yczpmdW5jdGlvbigpe3ZhciB0PW8odGhpcykuZmluZCgic3BhbjpmaXJzdCIpLmNzcygiYmFja2dyb3VuZC1jb2xvciIpLGU9YXJndW1lbnRzWzBdLmVscyxhPWFyZ3VtZW50c1swXS5zYXZlZENvbG9yc0luZm87dD10aW55Y29sb3IodCkudG9IZXgoKSxvKGUudGhpc0VsKS52YWwodCksbyhlLnRoaXNFbCkudHJpZ2dlcigiY2hhbmdlIiksbS51cGRhdGVQcmV2aWV3KGUudGhpc0VsKSxtLmFkZFRvU2F2ZWRDb2xvcnModCxhLGUuc2F2ZWRDb2xvcnNDb250ZW50KSxtLmNsb3NlRHJvcGRvd24oZS5jb2xvclByZXZpZXdCdXR0b24sZS5jb2xvck1lbnUpfSx0YXBTcGVjdHJ1bTpmdW5jdGlvbigpe3ZhciB0PWFyZ3VtZW50c1swXS50aGlzRXZlbnQsYT1hcmd1bWVudHNbMF0uc2F2ZWRDb2xvcnNJbmZvLG49YXJndW1lbnRzWzBdLmVscyxyPWFyZ3VtZW50c1swXS5tb3N0UmVjZW50Q2xpY2s7dC5zdG9wUHJvcGFnYXRpb24oKTt2YXIgcz1vKHRoaXMpLmZpbmQoIi5oaWdobGlnaHQtYmFuZCIpLGk9bS5nZXRNb3ZlYWJsZUFyZWEocyk7ZT9tLm1vdmVIaWdobGlnaHRCYW5kKHMsaSxyKTptLm1vdmVIaWdobGlnaHRCYW5kKHMsaSx0KTt2YXIgbD1tLmNhbGN1bGF0ZUhpZ2hsaWdodGVkQ29sb3IuYXBwbHkocyxbe3R5cGU6ImJhc2ljIn1dKTttLmFkZFRvU2F2ZWRDb2xvcnMobCxhLG4uc2F2ZWRDb2xvcnNDb250ZW50KSxuLnRvdWNoSW5zdHJ1Y3Rpb25zLmh0bWwoIlByZXNzICdzZWxlY3QnIHRvIGNob29zZSB0aGlzIGNvbG9yIil9LGV4ZWN1dGVVbmxlc3NTY3JvbGxlZDpmdW5jdGlvbigpe3ZhciB0LGEsbj1hcmd1bWVudHNbMF0udGhpc0Z1bmN0aW9uLHM9YXJndW1lbnRzWzBdLnRoZXNlQXJndW1lbnRzO28odGhpcykub24ocixmdW5jdGlvbihlKXt0PW8od2luZG93KS5zY3JvbGxUb3AoKSxhPWV9KS5vbihsLGZ1bmN0aW9uKHIpe3ZhciBpPXQtbyh3aW5kb3cpLnNjcm9sbFRvcCgpO3JldHVybiBlJiZNYXRoLmFicyhpKT4wPyExOihzLnRoaXNFdmVudD1yLHMubW9zdFJlY2VudENsaWNrPWEsbi5hcHBseShvKHRoaXMpLFtzXSksdm9pZCAwKX0pfSx1cGRhdGVTYXR1cmF0aW9uU3R5bGVzOmZ1bmN0aW9uKHQsZSxhKXt2YXIgcj0oMTAwKmEpLnRvU3RyaW5nKCkrIiUiLHM9IiMiK3Rpbnljb2xvcigiaHNsKCIrZSsiLDAlLCIrcikudG9IZXgoKSxpPSIjIit0aW55Y29sb3IoImhzbCgiK2UrIiw1MCUsIityKS50b0hleCgpLGw9IiMiK3Rpbnljb2xvcigiaHNsKCIrZSsiLDEwMCUsIityKS50b0hleCgpLGQ9IiIsYz0oby5lYWNoKFsiLXdlYmtpdC1saW5lYXItZ3JhZGllbnQiLCItby1saW5lYXItZ3JhZGllbnQiXSxmdW5jdGlvbihvLHQpe2QrPSJiYWNrZ3JvdW5kLWltYWdlOiAiK3QrIihsZWZ0LCAiK3MrIiAwJSwgIitpKyIgNTAlLCAiK2wrIiAxMDAlKTsifSksInByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5ncmFkaWVudChzdGFydENvbG9yc3RyPSciK3MrIicsIGVuZENvbG9yc3RyPSciK2krIicsIEdyYWRpZW50VHlwZT0xKSIpLHA9InByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5ncmFkaWVudChzdGFydENvbG9yc3RyPSciK2krIicsIGVuZENvbG9yc3RyPSciK2wrIicsIEdyYWRpZW50VHlwZT0xKSI7aWYoZD0iYmFja2dyb3VuZC1pbWFnZTogLW1vei1saW5lYXItZ3JhZGllbnQobGVmdCBjZW50ZXIsICIrcysiIDAlLCAiK2krIiA1MCUsICIrbCsiIDEwMCUpO2JhY2tncm91bmQtaW1hZ2U6IGxpbmVhci1ncmFkaWVudCh0byByaWdodCwgIitzKyIgMCUsICIraSsiIDUwJSwgIitsKyIgMTAwJSk7IGJhY2tncm91bmQtaW1hZ2U6IC13ZWJraXQtZ3JhZGllbnQobGluZWFyLCBsZWZ0IHRvcCwgcmlnaHQgdG9wLGNvbG9yLXN0b3AoMCwgIitzKyIpLGNvbG9yLXN0b3AoMC41LCAiK2krIiksY29sb3Itc3RvcCgxLCAiK2wrIikpOyIrZCxuKXt2YXIgdT1vKHQpLmZpbmQoIi5zYXR1cmF0aW9uLXNwZWN0cnVtLTAiKSxoPW8odCkuZmluZCgiLnNhdHVyYXRpb24tc3BlY3RydW0tMSIpO3UuY3NzKCJmaWx0ZXIiLGMpLGguY3NzKCJmaWx0ZXIiLHApfWVsc2UgdC5hdHRyKCJzdHlsZSIsZCl9LHVwZGF0ZUxpZ2h0bmVzc1N0eWxlczpmdW5jdGlvbih0LGUsYSl7dmFyIHI9KDEwMCphKS50b1N0cmluZygpKyIlIixzPSIjIit0aW55Y29sb3IoImhzbCgiK2UrIiwiK3IrIiwxMDAlKSIpLnRvSGV4KCksaT0iIyIrdGlueWNvbG9yKCJoc2woIitlKyIsIityKyIsNTAlKSIpLnRvSGV4KCksbD0iIyIrdGlueWNvbG9yKCJoc2woIitlKyIsIityKyIsMCUpIikudG9IZXgoKSxkPSIiLGM9KG8uZWFjaChbIi13ZWJraXQtbGluZWFyLWdyYWRpZW50IiwiLW8tbGluZWFyLWdyYWRpZW50Il0sZnVuY3Rpb24obyx0KXtkKz0iYmFja2dyb3VuZC1pbWFnZTogIit0KyIobGVmdCwgIitzKyIgMCUsICIraSsiIDUwJSwgIitsKyIgMTAwJSk7In0pLCJwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuZ3JhZGllbnQoc3RhcnRDb2xvcnN0cj0nIitzKyInLCBlbmRDb2xvcnN0cj0nIitpKyInLCBHcmFkaWVudFR5cGU9MSkiKSxwPSJwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuZ3JhZGllbnQoc3RhcnRDb2xvcnN0cj0nIitpKyInLCBlbmRDb2xvcnN0cj0nIitsKyInLCBHcmFkaWVudFR5cGU9MSkiO2lmKGQ9ImJhY2tncm91bmQtaW1hZ2U6IC1tb3otbGluZWFyLWdyYWRpZW50KGxlZnQgY2VudGVyLCAiK3MrIiAwJSwgIitpKyIgNTAlLCAiK2wrIiAxMDAlKTsgYmFja2dyb3VuZC1pbWFnZTogbGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCAiK3MrIiAwJSwgIitpKyIgNTAlLCAiK2wrIiAxMDAlKTsgYmFja2dyb3VuZC1pbWFnZTogLXdlYmtpdC1ncmFkaWVudChsaW5lYXIsIGxlZnQgdG9wLCByaWdodCB0b3AsIGNvbG9yLXN0b3AoMCwgIitzKyIpLCBjb2xvci1zdG9wKDAuNSwgIitpKyIpLCBjb2xvci1zdG9wKDEsICIrbCsiKSk7ICIrZCxuKXt2YXIgdT1vKHQpLmZpbmQoIi5saWdodG5lc3Mtc3BlY3RydW0tMCIpLGg9byh0KS5maW5kKCIubGlnaHRuZXNzLXNwZWN0cnVtLTEiKTt1LmNzcygiZmlsdGVyIixjKSxoLmNzcygiZmlsdGVyIixwKX1lbHNlIHQuYXR0cigic3R5bGUiLGQpfSx1cGRhdGVIdWVTdHlsZXM6ZnVuY3Rpb24odCxlLGEpe3ZhciByPSgxMDAqZSkudG9TdHJpbmcoKSsiJSIscz0oMTAwKmEpLnRvU3RyaW5nKCkrIiUiLGk9IiMiK3Rpbnljb2xvcigiaHNsKDAsIityKyIsIitzKyIpIikudG9IZXgoKSxsPSIjIit0aW55Y29sb3IoImhzbCg2MCwiK3IrIiwiK3MrIikiKS50b0hleCgpLGQ9IiMiK3Rpbnljb2xvcigiaHNsKDEyMCwiK3IrIiwiK3MrIikiKS50b0hleCgpLGM9IiMiK3Rpbnljb2xvcigiaHNsKDE4MCwiK3IrIiwiK3MrIikiKS50b0hleCgpLHA9IiMiK3Rpbnljb2xvcigiaHNsKDI0MCwiK3IrIiwiK3MrIikiKS50b0hleCgpLHU9IiMiK3Rpbnljb2xvcigiaHNsKDMwMCwiK3IrIiwiK3MrIikiKS50b0hleCgpLGg9IiMiK3Rpbnljb2xvcigiaHNsKDAsIityKyIsIitzKyIpIikudG9IZXgoKSxnPSJwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuZ3JhZGllbnQoc3RhcnRDb2xvcnN0cj0nIitpKyInLCBlbmRDb2xvcnN0cj0nIitsKyInLCBHcmFkaWVudFR5cGU9MSkiLHY9InByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5ncmFkaWVudChzdGFydENvbG9yc3RyPSciK2wrIicsIGVuZENvbG9yc3RyPSciK2QrIicsIEdyYWRpZW50VHlwZT0xKSIsZj0icHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0LmdyYWRpZW50KHN0YXJ0Q29sb3JzdHI9JyIrZCsiJywgZW5kQ29sb3JzdHI9JyIrYysiJywgR3JhZGllbnRUeXBlPTEpIixDPSJwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuZ3JhZGllbnQoc3RhcnRDb2xvcnN0cj0nIitjKyInLCBlbmRDb2xvcnN0cj0nIitwKyInLCBHcmFkaWVudFR5cGU9MSkiLG09InByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5ncmFkaWVudChzdGFydENvbG9yc3RyPSciK3ArIicsIGVuZENvbG9yc3RyPSciK3UrIicsIEdyYWRpZW50VHlwZT0xKSIsYj0icHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0LmdyYWRpZW50KHN0YXJ0Q29sb3JzdHI9JyIrdSsiJywgZW5kQ29sb3JzdHI9JyIraCsiJywgR3JhZGllbnRUeXBlPTEpIix3PSIiO28uZWFjaChbIi13ZWJraXQtbGluZWFyLWdyYWRpZW50IiwiLW8tbGluZWFyLWdyYWRpZW50Il0sZnVuY3Rpb24obyx0KXt3Kz0iYmFja2dyb3VuZC1pbWFnZTogIit0KyIobGVmdCwgIitpKyIgMCUsICIrbCsiIDE3JSwgIitkKyIgMjQlLCAiK2MrIiA1MSUsICIrcCsiIDY4JSwgIit1KyIgODUlLCAiK2grIiAxMDAlKTsifSk7aWYodys9ImJhY2tncm91bmQtaW1hZ2U6IC13ZWJraXQtZ3JhZGllbnQobGluZWFyLCBsZWZ0IHRvcCwgcmlnaHQgdG9wLGNvbG9yLXN0b3AoMCUsICIraSsiKSxjb2xvci1zdG9wKDE3JSwgIitsKyIpLGNvbG9yLXN0b3AoMzQlLCAiK2QrIiksY29sb3Itc3RvcCg1MSUsICIrYysiKSxjb2xvci1zdG9wKDY4JSwgIitwKyIpLGNvbG9yLXN0b3AoODUlLCAiK3UrIiksY29sb3Itc3RvcCgxMDAlLCAiK2grIikpO2JhY2tncm91bmQtaW1hZ2U6IGxpbmVhci1ncmFkaWVudCh0byByaWdodCwgIitpKyIgMCUsICIrbCsiIDE3JSwgIitkKyIgMjQlLCIrYysiIDUxJSwiK3ArIiA2OCUsIit1KyIgODUlLCIraCsiIDEwMCUpOyBiYWNrZ3JvdW5kLWltYWdlOiAtbW96LWxpbmVhci1ncmFkaWVudChsZWZ0IGNlbnRlciwgIitpKyIgMCUsICIrbCsiIDE3JSwgIitkKyIgMjQlLCAiK2MrIiA1MSUsICIrcCsiIDY4JSwgIit1KyIgODUlLCAiK2grIiAxMDAlKTsiLG4pe3ZhciBTPW8odCkuZmluZCgiLmh1ZS1zcGVjdHJ1bS0wIikseT1vKHQpLmZpbmQoIi5odWUtc3BlY3RydW0tMSIpLGs9byh0KS5maW5kKCIuaHVlLXNwZWN0cnVtLTIiKSx4PW8odCkuZmluZCgiLmh1ZS1zcGVjdHJ1bS0zIiksSD1vKHQpLmZpbmQoIi5odWUtc3BlY3RydW0tNCIpLEE9byh0KS5maW5kKCIuaHVlLXNwZWN0cnVtLTUiKTtTLmNzcygiZmlsdGVyIixnKSx5LmNzcygiZmlsdGVyIix2KSxrLmNzcygiZmlsdGVyIixmKSx4LmNzcygiZmlsdGVyIixDKSxILmNzcygiZmlsdGVyIixtKSxBLmNzcygiZmlsdGVyIixiKX1lbHNlIHQuYXR0cigic3R5bGUiLHcpfSxnZXRIaWdobGlnaHRlZEh1ZTpmdW5jdGlvbigpe3ZhciB0PW8odGhpcyksYT10Lm91dGVyV2lkdGgoKSxuPWEvMixyPXBhcnNlSW50KHQuY3NzKCJsZWZ0IiksMTApK24scz10LnBhcmVudHMoIi5hZHZhbmNlZC1saXN0IiksaT1zLmZpbmQoIi5jb2xvci1wcmV2aWV3IiksbD1zLmZpbmQoIi5zcGVjdHJ1bS1saWdodG5lc3MiKSxkPXMuZmluZCgiLnNwZWN0cnVtLXNhdHVyYXRpb24iKSxjPXBhcnNlSW50KHMuZmluZCgiLmNvbG9yLWJveCIpLmZpcnN0KCkud2lkdGgoKSwxMCkscD1zLmZpbmQoIi5odWUtdmFsdWUiKSx1PWFyZ3VtZW50c1swXS5sLGg9YXJndW1lbnRzWzBdLnMsZz0oMTAwKmgpLnRvU3RyaW5nKCkrIiUiLHY9KDEwMCp1KS50b1N0cmluZygpKyIlIjswPT09YyYmKGM9ZT8xNjA6MzAwKTt2YXIgZj1NYXRoLmZsb29yKHIvYyozNjApLEM9ImhzbCgiK2YrIiwiK2crIiwiK3YrIikiO3JldHVybiBDPSIjIit0aW55Y29sb3IoQykudG9IZXgoKSxpLmNzcygiYmFja2dyb3VuZC1jb2xvciIsQykscC50ZXh0KGYpLG0udXBkYXRlTGlnaHRuZXNzU3R5bGVzKGwsZixoKSxtLnVwZGF0ZVNhdHVyYXRpb25TdHlsZXMoZCxmLHUpLGZ9LGdldEhpZ2hsaWdodGVkU2F0dXJhdGlvbjpmdW5jdGlvbigpe3ZhciB0PW8odGhpcyksYT10Lm91dGVyV2lkdGgoKSxuPWEvMixyPXBhcnNlSW50KHQuY3NzKCJsZWZ0IiksMTApK24scz10LnBhcmVudHMoIi5hZHZhbmNlZC1saXN0IiksaT1zLmZpbmQoIi5jb2xvci1wcmV2aWV3IiksbD1zLmZpbmQoIi5zcGVjdHJ1bS1saWdodG5lc3MiKSxkPXMuZmluZCgiLnNwZWN0cnVtLWh1ZSIpLGM9cy5maW5kKCIuc2F0dXJhdGlvbi12YWx1ZSIpLHA9cGFyc2VJbnQocy5maW5kKCIuY29sb3ItYm94IikuZmlyc3QoKS53aWR0aCgpLDEwKSx1PWFyZ3VtZW50c1swXS5sLGg9KDEwMCp1KS50b1N0cmluZygpKyIlIixnPWFyZ3VtZW50c1swXS5oOzA9PT1wJiYocD1lPzE2MDozMDApO3ZhciB2PXIvcCxmPU1hdGgucm91bmQoMTAwKnYpLnRvU3RyaW5nKCkrIiUiLEM9ImhzbCgiK2crIiwiK2YrIiwiK2grIikiO3JldHVybiBDPSIjIit0aW55Y29sb3IoQykudG9IZXgoKSxpLmNzcygiYmFja2dyb3VuZC1jb2xvciIsQyksYy50ZXh0KGYpLG0udXBkYXRlTGlnaHRuZXNzU3R5bGVzKGwsZyx2KSxtLnVwZGF0ZUh1ZVN0eWxlcyhkLHYsdSksdn0sdXBkYXRlQWR2YW5jZWRJbnN0cnVjdGlvbnM6ZnVuY3Rpb24obyl7by5odG1sKCJQcmVzcyB0aGUgY29sb3IgcHJldmlldyB0byBjaG9vc2UgdGhpcyBjb2xvciIpfX07cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbih0KXttLmluaXRpYWxpemUuYXBwbHkodGhpcyxbdF0pO3ZhciBlLG4scj17dGhpc0VsOm8odGhpcyksdGhpc1dyYXBwZXI6byh0aGlzKS5wYXJlbnQoKSxjb2xvclRleHRJbnB1dDpvKHRoaXMpLmZpbmQoImlucHV0IiksY29sb3JNZW51TGlua3M6byh0aGlzKS5wYXJlbnQoKS5maW5kKCIuY29sb3ItbWVudSBsaSBhIiksY29sb3JQcmV2aWV3QnV0dG9uOm8odGhpcykucGFyZW50KCkuZmluZCgiLmlucHV0LWdyb3VwLWJ0biIpLGNvbG9yTWVudTpvKHRoaXMpLnBhcmVudCgpLmZpbmQoIi5jb2xvci1tZW51IiksY29sb3JTcGVjdHJ1bXM6byh0aGlzKS5wYXJlbnQoKS5maW5kKCIuY29sb3ItYm94IiksYmFzaWNTcGVjdHJ1bXM6byh0aGlzKS5wYXJlbnQoKS5maW5kKCIuYmFzaWNDb2xvcnMtY29udGVudCAuY29sb3ItYm94IiksdG91Y2hJbnN0cnVjdGlvbnM6byh0aGlzKS5wYXJlbnQoKS5maW5kKCIuY29sb3ItbWVudS1pbnN0cnVjdGlvbnMiKSxhZHZhbmNlZEluc3RydWN0aW9uczpvKHRoaXMpLnBhcmVudCgpLmZpbmQoIi5hZHZhbmNlZC1pbnN0cnVjdGlvbnMiKSxoaWdobGlnaHRCYW5kczpvKHRoaXMpLnBhcmVudCgpLmZpbmQoIi5oaWdobGlnaHQtYmFuZCIpLGJhc2ljSGlnaGxpZ2h0QmFuZHM6byh0aGlzKS5wYXJlbnQoKS5maW5kKCIuYmFzaWNDb2xvcnMtY29udGVudCAuaGlnaGxpZ2h0LWJhbmQiKX07aWYodSYmKHIudGFicz1yLnRoaXNXcmFwcGVyLmZpbmQoIi50YWIiKSkscC5zaG93U2F2ZWRDb2xvcnMmJihyLnNhdmVkQ29sb3JzQ29udGVudD1yLnRoaXNXcmFwcGVyLmZpbmQoIi5zYXZlZENvbG9ycy1jb250ZW50IikscC5zYXZlQ29sb3JzUGVyRWxlbWVudCkpaWYobj17Y29sb3JzOltdLGRhdGFPYmo6byh0aGlzKS5kYXRhKCl9LG8uZWFjaChuLmRhdGFPYmosZnVuY3Rpb24obyl7bi5kYXRhQXR0cj1vfSksYSYmbG9jYWxTdG9yYWdlWyJwaWNrQUNvbG9yU2F2ZWRDb2xvcnMtIituLmRhdGFBdHRyXSluLmNvbG9ycz1KU09OLnBhcnNlKGxvY2FsU3RvcmFnZVsicGlja0FDb2xvclNhdmVkQ29sb3JzLSIrbi5kYXRhQXR0cl0pO2Vsc2UgaWYoZG9jdW1lbnQuY29va2llLm1hdGNoKCJwaWNrQUNvbG9yU2F2ZWRDb2xvcnMtIituLmRhdGFBdHRyKSlmb3IodmFyIHM9ZG9jdW1lbnQuY29va2llLnNwbGl0KCI7IiksaD0wO2g8cy5sZW5ndGg7aCsrKXNbaF0ubWF0Y2gobi5kYXRhQXR0cikmJihuLmNvbG9ycz1zW2hdLnNwbGl0KCI9IilbMV0uc3BsaXQoIiwiKSk7ZWxzZSBuLmNvbG9ycz1mO3Auc2hvd0FkdmFuY2VkJiYoZT17aDowLHM6MSxsOi41fSxyLmFkdmFuY2VkU3BlY3RydW1zPXIudGhpc1dyYXBwZXIuZmluZCgiLmFkdmFuY2VkLWxpc3QiKS5maW5kKCIuY29sb3ItYm94Iiksci5hZHZhbmNlZEhpZ2hsaWdodEJhbmRzPXIudGhpc1dyYXBwZXIuZmluZCgiLmFkdmFuY2VkLWxpc3QiKS5maW5kKCIuaGlnaGxpZ2h0LWJhbmQiKSxyLmh1ZVNwZWN0cnVtPXIudGhpc1dyYXBwZXIuZmluZCgiLnNwZWN0cnVtLWh1ZSIpLHIubGlnaHRuZXNzU3BlY3RydW09ci50aGlzV3JhcHBlci5maW5kKCIuc3BlY3RydW0tbGlnaHRuZXNzIiksci5zYXR1cmF0aW9uU3BlY3RydW09ci50aGlzV3JhcHBlci5maW5kKCIuc3BlY3RydW0tc2F0dXJhdGlvbiIpLHIuaHVlSGlnaGxpZ2h0QmFuZD1yLnRoaXNXcmFwcGVyLmZpbmQoIi5zcGVjdHJ1bS1odWUgLmhpZ2hsaWdodC1iYW5kIiksci5saWdodG5lc3NIaWdobGlnaHRCYW5kPXIudGhpc1dyYXBwZXIuZmluZCgiLnNwZWN0cnVtLWxpZ2h0bmVzcyAuaGlnaGxpZ2h0LWJhbmQiKSxyLnNhdHVyYXRpb25IaWdobGlnaHRCYW5kPXIudGhpc1dyYXBwZXIuZmluZCgiLnNwZWN0cnVtLXNhdHVyYXRpb24gLmhpZ2hsaWdodC1iYW5kIiksci5hZHZhbmNlZFByZXZpZXc9ci50aGlzV3JhcHBlci5maW5kKCIuYWR2YW5jZWQtY29udGVudCAuY29sb3ItcHJldmlldyIpKSxtLmFkZFRvU2F2ZWRDb2xvcnMoZy5kZWZhdWx0Q29sb3IsbixyLnNhdmVkQ29sb3JzQ29udGVudCksbS51cGRhdGVQcmV2aWV3KHIudGhpc0VsKSxyLnRoaXNFbC5mb2N1cyhmdW5jdGlvbigpe3ZhciB0PW8odGhpcyk7Zy50eXBlZENvbG9yPXQudmFsKCkscC5hbGxvd0JsYW5rfHx0LnZhbCgiIiksbS50b2dnbGVEcm9wZG93bihyLmNvbG9yUHJldmlld0J1dHRvbixyLkNvbG9yTWVudSl9KS5ibHVyKGZ1bmN0aW9uKCl7dmFyIHQ9byh0aGlzKTtnLm5ld1ZhbHVlPXQudmFsKCksZy5uZXdWYWx1ZS5tYXRjaCgvXlxzKyR8XiQvKT9wLmFsbG93Qmxhbmt8fHQudmFsKGcudHlwZWRDb2xvcik6KGcubmV3VmFsdWU9dGlueWNvbG9yKGcubmV3VmFsdWUpLnRvSGV4KCksdC52YWwoZy5uZXdWYWx1ZSksbS5hZGRUb1NhdmVkQ29sb3JzKGcubmV3VmFsdWUsbixyLnNhdmVkQ29sb3JzQ29udGVudCkpLG0udG9nZ2xlRHJvcGRvd24oci5jb2xvclByZXZpZXdCdXR0b24sci5Db2xvck1lbnUpLG0udXBkYXRlUHJldmlldyh0KX0pLG0uZXhlY3V0ZVVubGVzc1Njcm9sbGVkLmFwcGx5KHIuY29sb3JQcmV2aWV3QnV0dG9uLFt7dGhpc0Z1bmN0aW9uOm0ucHJlc3NQcmV2aWV3QnV0dG9uLHRoZXNlQXJndW1lbnRzOnt9fV0pLG0uZXhlY3V0ZVVubGVzc1Njcm9sbGVkLmFwcGx5KG8oZG9jdW1lbnQpLFt7dGhpc0Z1bmN0aW9uOm0uY2xvc2VEcm9wZG93bklmT3Blbix0aGVzZUFyZ3VtZW50czp7YnV0dG9uOnIuY29sb3JQcmV2aWV3QnV0dG9uLG1lbnU6ci5jb2xvck1lbnV9fV0pLHIuY29sb3JNZW51Lm9uKGwsZnVuY3Rpb24obyl7by5zdG9wUHJvcGFnYXRpb24oKX0pLHIudGhpc0VsLm9uKGwsZnVuY3Rpb24obyl7by5zdG9wUHJvcGFnYXRpb24oKX0pLG0uZXhlY3V0ZVVubGVzc1Njcm9sbGVkLmFwcGx5KHIuY29sb3JNZW51TGlua3MsW3t0aGlzRnVuY3Rpb246bS5zZWxlY3RGcm9tQmFzaWNDb2xvcnMsdGhlc2VBcmd1bWVudHM6e2VsczpyLHNhdmVkQ29sb3JzSW5mbzpufX1dKSx1JiZtLnRhYmJhYmxlLmFwcGx5KHIudGFicyksKHAuc2hvd1NwZWN0cnVtfHxwLnNob3dBZHZhbmNlZCkmJm0uaG9yaXpvbnRhbGx5RHJhZ2dhYmxlLmFwcGx5KHIuaGlnaGxpZ2h0QmFuZHMpLHAuc2hvd1NwZWN0cnVtJiYobS5leGVjdXRlVW5sZXNzU2Nyb2xsZWQuYXBwbHkoci5iYXNpY1NwZWN0cnVtcyxbe3RoaXNGdW5jdGlvbjptLnRhcFNwZWN0cnVtLHRoZXNlQXJndW1lbnRzOntzYXZlZENvbG9yc0luZm86bixlbHM6cn19XSksbyhyLmJhc2ljSGlnaGxpZ2h0QmFuZHMpLm9uKGQsZnVuY3Rpb24obyl7by50YXJnZXQ7bS5jYWxjdWxhdGVIaWdobGlnaHRlZENvbG9yLmFwcGx5KHRoaXMsW3t0eXBlOiJiYXNpYyJ9XSl9KS5vbihjLGZ1bmN0aW9uKG8pe3ZhciB0PW8uZGVsZWdhdGVUYXJnZXQsZT1tLmNhbGN1bGF0ZUhpZ2hsaWdodGVkQ29sb3IuYXBwbHkodCxbe3R5cGU6ImJhc2ljIn1dKTttLmFkZFRvU2F2ZWRDb2xvcnMoZSxuLHIuc2F2ZWRDb2xvcnNDb250ZW50KX0pKSxwLnNob3dBZHZhbmNlZCYmKG8oci5odWVIaWdobGlnaHRCYW5kKS5vbihkLGZ1bmN0aW9uKG8pe2UuaD1tLmdldEhpZ2hsaWdodGVkSHVlLmFwcGx5KHRoaXMsW2VdKX0pLG8oci5saWdodG5lc3NIaWdobGlnaHRCYW5kKS5vbihkLGZ1bmN0aW9uKCl7bS5jYWxjdWxhdGVIaWdobGlnaHRlZENvbG9yLmFwcGx5KHRoaXMsW3t0eXBlOiJhZHZhbmNlZCIsaHNsOmV9XSl9KS5vbihpLGZ1bmN0aW9uKCl7ZS5sPW0uY2FsY3VsYXRlSGlnaGxpZ2h0ZWRDb2xvci5hcHBseSh0aGlzLFt7dHlwZToiYWR2YW5jZWQiLGhzbDplfV0pfSksbyhyLnNhdHVyYXRpb25IaWdobGlnaHRCYW5kKS5vbihkLGZ1bmN0aW9uKCl7bS5nZXRIaWdobGlnaHRlZFNhdHVyYXRpb24uYXBwbHkodGhpcyxbZV0pfSkub24oYyxmdW5jdGlvbigpe2Uucz1tLmdldEhpZ2hsaWdodGVkU2F0dXJhdGlvbi5hcHBseSh0aGlzLFtlXSl9KSxvKHIuYWR2YW5jZWRIaWdobGlnaHRCYW5kKS5vbihjLGZ1bmN0aW9uKCl7bS51cGRhdGVBZHZhbmNlZEluc3RydWN0aW9ucyhyLmFkdmFuY2VkSW5zdHJ1Y3Rpb25zKX0pLG8oci5saWdodG5lc3NTcGVjdHJ1bSkuY2xpY2soZnVuY3Rpb24odCl7dC5zdG9wUHJvcGFnYXRpb24oKTt2YXIgYT1vKHRoaXMpLmZpbmQoIi5oaWdobGlnaHQtYmFuZCIpLG49bS5nZXRNb3ZlYWJsZUFyZWEoYSk7bS5tb3ZlSGlnaGxpZ2h0QmFuZChhLG4sdCksZS5sPW0uY2FsY3VsYXRlSGlnaGxpZ2h0ZWRDb2xvci5hcHBseShhLFt7dHlwZToiYWR2YW5jZWQiLGhzbDplfV0pfSksbyhyLmh1ZVNwZWN0cnVtKS5jbGljayhmdW5jdGlvbih0KXt0LnN0b3BQcm9wYWdhdGlvbigpO3ZhciBhPW8odGhpcykuZmluZCgiLmhpZ2hsaWdodC1iYW5kIiksbj1tLmdldE1vdmVhYmxlQXJlYShhKTttLm1vdmVIaWdobGlnaHRCYW5kKGEsbix0KSxlLmg9bS5nZXRIaWdobGlnaHRlZEh1ZS5hcHBseShhLFtlXSl9KSxvKHIuc2F0dXJhdGlvblNwZWN0cnVtKS5jbGljayhmdW5jdGlvbih0KXt0LnN0b3BQcm9wYWdhdGlvbigpO3ZhciBhPW8odGhpcykuZmluZCgiLmhpZ2hsaWdodC1iYW5kIiksbj1tLmdldE1vdmVhYmxlQXJlYShhKTttLm1vdmVIaWdobGlnaHRCYW5kKGEsbix0KSxlLnM9bS5nZXRIaWdobGlnaHRlZFNhdHVyYXRpb24uYXBwbHkoYSxbZV0pfSksbyhyLmFkdmFuY2VkU3BlY3RydW1zKS5jbGljayhmdW5jdGlvbigpe20udXBkYXRlQWR2YW5jZWRJbnN0cnVjdGlvbnMoci5hZHZhbmNlZEluc3RydWN0aW9ucyl9KSxvKHIuYWR2YW5jZWRQcmV2aWV3KS5jbGljayhmdW5jdGlvbigpe3ZhciB0PXRpbnljb2xvcihvKHRoaXMpLmNzcygiYmFja2dyb3VuZC1jb2xvciIpKS50b0hleCgpO28oci50aGlzRWwpLnZhbCh0KSxvKHIudGhpc0VsKS50cmlnZ2VyKCJjaGFuZ2UiKSxtLnVwZGF0ZVByZXZpZXcoci50aGlzRWwpLG0uYWRkVG9TYXZlZENvbG9ycyh0LG4sci5zYXZlZENvbG9yc0NvbnRlbnQpLG0uY2xvc2VEcm9wZG93bihyLmNvbG9yUHJldmlld0J1dHRvbixyLmNvbG9yTWVudSl9KSkscC5zaG93U2F2ZWRDb2xvcnMmJihvKHIuc2F2ZWRDb2xvcnNDb250ZW50KS5jbGljayhmdW5jdGlvbih0KXt2YXIgZT1vKHQudGFyZ2V0KTtpZihlLmlzKCJTUEFOIil8fGUuaXMoIkEiKSl7dmFyIGE9ZS5pcygiU1BBTiIpP2UucGFyZW50KCkuYXR0cigiY2xhc3MiKS5zcGxpdCgiIyIpWzFdOmUuYXR0cigiY2xhc3MiKS5zcGxpdCgiIyIpWzFdO28oci50aGlzRWwpLnZhbChhKSxvKHIudGhpc0VsKS50cmlnZ2VyKCJjaGFuZ2UiKSxtLnVwZGF0ZVByZXZpZXcoci50aGlzRWwpLG0uY2xvc2VEcm9wZG93bihyLmNvbG9yUHJldmlld0J1dHRvbixyLmNvbG9yTWVudSksbS5hZGRUb1NhdmVkQ29sb3JzKGEsbixyLnNhdmVkQ29sb3JzQ29udGVudCl9fSkscC5zYXZlQ29sb3JzUGVyRWxlbWVudD9wLnNhdmVDb2xvcnNQZXJFbGVtZW50JiZtLnVwZGF0ZVNhdmVkQ29sb3JNYXJrdXAoci5zYXZlZENvbG9yc0NvbnRlbnQsbi5jb2xvcnMpOm0udXBkYXRlU2F2ZWRDb2xvck1hcmt1cChyLnNhdmVkQ29sb3JzQ29udGVudCxmKSl9KX19KGpRdWVyeSk7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDI0LzEwLzIwMTYuCiAqLwoKd2luZG93LkZvcm0gPSB3aW5kb3cuRm9ybSB8fCB7fTsKCkZvcm0ucnRlID0gRm9ybS5ydGUgfHwge307CgooZnVuY3Rpb24gKG5zKSB7CgogICAgdmFyIGxvY2FsZSA9ICJlbiI7CgogICAgdmFyIEkxOG4gPSBucy5JMThuID0ge307CgogICAgSTE4bi5zZXRMb2NhbGUgPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUpIHsKICAgICAgICAgICAgaWYgKHZhbHVlLmluZGV4T2YoIi0iKSA+IC0xKSB7CiAgICAgICAgICAgICAgICB2YXIgc3BsaXRMb2NhbGUgPSB2YWx1ZS5zcGxpdCgiLSIpOwogICAgICAgICAgICAgICAgdmFsdWUgPSBzcGxpdExvY2FsZVswXS50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICAgICAgaWYgKHNwbGl0TG9jYWxlLmxlbmd0aCA+IDEpIHsKICAgICAgICAgICAgICAgICAgICB2YWx1ZSArPSBzcGxpdExvY2FsZVsxXS50b1VwcGVyQ2FzZSgpOyAgLy8gaWYgbG9jYWxlIGhhcyBjb3VudHJ5IGluY2x1ZGUgdGhhdAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGxvY2FsZSA9IHZhbHVlOwogICAgICAgIH0KICAgIH07CgogICAgSTE4bi5nZXQgPSBmdW5jdGlvbiAoc3RyLCBzbmlwcGV0cykgewogICAgICAgIGlmICghc3RyKSB7CiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9CiAgICAgICAgdmFyIGxvY2FsZUZpbGUgPSBJMThuW2xvY2FsZV0gfHwgSTE4bi5lbjsKICAgICAgICB2YXIgc3RyaW5ncyA9IGxvY2FsZUZpbGUuc3RyaW5ncyB8fCB7fTsKICAgICAgICBpZiAoc3RyaW5ncy5oYXNPd25Qcm9wZXJ0eShzdHIpKSB7CiAgICAgICAgICAgIHN0ciA9IHN0cmluZ3Nbc3RyXTsKICAgICAgICB9CiAgICAgICAgaWYgKHNuaXBwZXRzICYmIHNuaXBwZXRzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgdmFyIHBhdHRlcm4gPSAveyhcZCspfS9nOwogICAgICAgICAgICB2YXIgcmVzdWx0ID0gcGF0dGVybi5leGVjKHN0cik7CiAgICAgICAgICAgIHdoaWxlIChyZXN1bHQpIHsKICAgICAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHJlc3VsdFswXSwgc25pcHBldHNbcmVzdWx0WzFdXSk7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBwYXR0ZXJuLmV4ZWMoc3RyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RyOwogICAgfTsKfSkoRm9ybS5ydGUpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTYuIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKgogKiBDcmVhdGVkIGJ5IHJhbW5hbmkgb24gMjQvMTAvMjAxNi4KICovCgooZnVuY3Rpb24gKEkxOG4pIHsKCiAgICB2YXIgZW4gPSBJMThuLmVuID0ge307CgogICAgZW4uc3RyaW5ncyA9IHsKICAgICAgICAiVW5kbyIgOiAiVW5kbyIsCiAgICAgICAgIlJlZG8iIDogIlJlZG8iLAogICAgICAgICJCb2xkIiA6ICJCb2xkIiwKICAgICAgICAiSXRhbGljIiA6ICJJdGFsaWMiLAogICAgICAgICJVbmRlcmxpbmUiIDogIlVuZGVybGluZSIsCiAgICAgICAgIlN1cGVyLXNjcmlwdCIgOiAiU3VwZXItc2NyaXB0IiwKICAgICAgICAiU3ViLXNjcmlwdCIgOiAiU3ViLXNjcmlwdCIsCiAgICAgICAgIlRleHQgQ29sb3IiIDogIlRleHQgQ29sb3IiLAogICAgICAgICJIaWdobGlnaHQgQ29sb3IiIDogIkhpZ2hsaWdodCBDb2xvciIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICJGb250IEZhbWlseSIsCiAgICAgICAgIkZvbnQgU2l6ZSIgOiAiRm9udCBTaXplIiwKICAgICAgICAiTGluZSBIZWlnaHQiIDogIkxpbmUgSGVpZ2h0IiwKICAgICAgICAiTGV0dGVyIFNwYWNpbmciIDogIkxldHRlciBTcGFjaW5nIiwKICAgICAgICAiUGFyYWdyYXBoIEZvcm1hdCIgOiAiUGFyYWdyYXBoIEZvcm1hdCIsCiAgICAgICAgIkp1c3RpZnkgTGVmdCIgOiAiSnVzdGlmeSBMZWZ0IiwKICAgICAgICAiSnVzdGlmeSBDZW50ZXIiIDogIkp1c3RpZnkgQ2VudGVyIiwKICAgICAgICAiSnVzdGlmeSBGdWxsIiA6ICJKdXN0aWZ5IEZ1bGwiLAogICAgICAgICJKdXN0aWZ5IFJpZ2h0IiA6ICJKdXN0aWZ5IFJpZ2h0IiwKICAgICAgICAiTWFyZ2luIExlZnQiIDogIk1hcmdpbiBMZWZ0IiwKICAgICAgICAiTWFyZ2luIFJpZ2h0IiA6ICJNYXJnaW4gUmlnaHQiLAogICAgICAgICJNYXJnaW4gVG9wIiA6ICJNYXJnaW4gVG9wIiwKICAgICAgICAiTWFyZ2luIEJvdHRvbSIgOiAiTWFyZ2luIEJvdHRvbSIsCiAgICAgICAgIkJ1bGxldGVkIExpc3QiIDogIkJ1bGxldGVkIExpc3QiLAogICAgICAgICJOdW1iZXJlZCBMaXN0IiA6ICJOdW1iZXJlZCBMaXN0IiwKICAgICAgICAiVXBwZXItY2FzZSBBbHBoYWJldCBMaXN0IiA6ICJVcHBlci1jYXNlIEFscGhhYmV0IExpc3QiLAogICAgICAgICJMb3dlci1jYXNlIEFscGhhYmV0IExpc3QiIDogIkxvd2VyLWNhc2UgQWxwaGFiZXQgTGlzdCIsCiAgICAgICAgIlVwcGVyLWNhc2UgUm9tYW4gTGlzdCIgOiAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiwKICAgICAgICAiTG93ZXItY2FzZSBSb21hbiBMaXN0IiA6ICJMb3dlci1jYXNlIFJvbWFuIExpc3QiLAogICAgICAgICJJbmRlbnQiIDogIkluZGVudCIsCiAgICAgICAgIk91dGRlbnQiIDogIk91dGRlbnQiLAogICAgICAgICJGaW5kICYgUmVwbGFjZSIgOiAiRmluZCAmIFJlcGxhY2UiLAogICAgICAgICJJbnNlcnQgTGluayIgOiAiSW5zZXJ0IExpbmsiLAogICAgICAgICJGaW5kIiA6ICJGaW5kIiwKICAgICAgICAiUmVwbGFjZSIgOiAiUmVwbGFjZSIsCiAgICAgICAgIlJlcGxhY2UgYWxsIiA6ICJSZXBsYWNlIGFsbCIsCiAgICAgICAgIk1hdGNoIGNhc2UiIDogIk1hdGNoIGNhc2UiLAogICAgICAgICJXaG9sZSB3b3JkIiA6ICJXaG9sZSB3b3JkIiwKICAgICAgICAiUmVnIEV4IiA6ICJSZWcgRXgiLAogICAgICAgICJJbmZvIiA6ICJJbmZvIiwKICAgICAgICAiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIgOiAiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIsCiAgICAgICAgIk1hdGNoIE5vdCBGb3VuZCIgOiAiTWF0Y2ggTm90IEZvdW5kIiwKICAgICAgICAiezB9IG1hdGNoZXMgcmVwbGFjZWQiIDogInswfSBtYXRjaGVzIHJlcGxhY2VkIiwKICAgICAgICAiVGltZXMgTmV3IFJvbWFuIiA6ICJUaW1lcyBOZXcgUm9tYW4iLAogICAgICAgICJBcmlhbCIgOiAiQXJpYWwiLAogICAgICAgICJDb3VyaWVyIiA6ICJDb3VyaWVyIiwKICAgICAgICAiQ291cmllciBOZXciIDogIkNvdXJpZXIgTmV3IiwKICAgICAgICAiR2VuZXZhIiA6ICJHZW5ldmEiLAogICAgICAgICJHZW9yZ2lhIiA6ICJHZW9yZ2lhIiwKICAgICAgICAiSGVsdmV0aWNhIiA6ICJIZWx2ZXRpY2EiLAogICAgICAgICJUYWhvbWEiIDogIlRhaG9tYSIsCiAgICAgICAgIlRpbWVzIiA6ICJUaW1lcyIsCiAgICAgICAgIlZlcmRhbmEiIDogIlZlcmRhbmEiLAogICAgICAgICJOb25lIiA6ICJOb25lIiwKICAgICAgICAiSGVhZGVyIDEiIDogIkhlYWRlciAxIiwKICAgICAgICAiSGVhZGVyIDIiIDogIkhlYWRlciAyIiwKICAgICAgICAiSGVhZGVyIDMiIDogIkhlYWRlciAzIiwKICAgICAgICAiSGVhZGVyIDQiIDogIkhlYWRlciA0IiwKICAgICAgICAiSGVhZGVyIDUiIDogIkhlYWRlciA1IiwKICAgICAgICAiSGVhZGVyIDYiIDogIkhlYWRlciA2IiwKICAgICAgICAiU2VsZWN0IiA6ICJTZWxlY3QiLAogICAgICAgICJCYXNpYyBWaWV3IiA6ICJCYXNpYyBWaWV3IiwKICAgICAgICAiRnVsbFNjcmVlbiIgOiAiRnVsbFNjcmVlbiIsCiAgICAgICAgIkV4cGFuZCIgOiAiRXhwYW5kIiwKICAgICAgICAiQ29sbGFwc2UiIDogIkNvbGxhcHNlIiwKICAgICAgICAiTGlzdCBUeXBlIiA6ICJMaXN0IFR5cGUiLAogICAgICAgICJVUkwiIDogIlVSTCIsCiAgICAgICAgIkFsdCBUZXh0IiA6ICJBbHQgVGV4dCIsCiAgICAgICAgIk9wZW4gaW4gbmV3IHBhZ2UiIDogIk9wZW4gaW4gbmV3IHBhZ2UiCiAgICB9Owp9KShGb3JtLnJ0ZS5JMThuKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDI0LzEwLzIwMTYuCiAqLwoKKGZ1bmN0aW9uIChJMThuKSB7CgogICAgdmFyIGRlID0gSTE4bi5kZSA9IHt9OwoKICAgIGRlLnN0cmluZ3MgPSB7CiAgICAgICAgIlVuZG8iIDogIlLDvGNrZ8OkbmdpZyIsCiAgICAgICAgIlJlZG8iIDogIldpZWRlcmhvbGVuIiwKICAgICAgICAiQm9sZCIgOiAiRmV0dCIsCiAgICAgICAgIkl0YWxpYyIgOiAiS3Vyc2l2IiwKICAgICAgICAiVW5kZXJsaW5lIiA6ICJVbnRlcnN0cmljaGVuIiwKICAgICAgICAiU3VwZXItc2NyaXB0IiA6ICJIb2NoZ2VzdGVsbHQiLAogICAgICAgICJTdWItc2NyaXB0IiA6ICJUaWVmZ2VzdGVsbHQiLAogICAgICAgICJUZXh0IENvbG9yIiA6ICJUZXh0ZmFyYmUiLAogICAgICAgICJIaWdobGlnaHQgQ29sb3IiIDogIkhlcnZvcmhlYnVuZ3NmYXJiZSIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICJTY2hyaWZ0ZmFtaWxpZSIsCiAgICAgICAgIkZvbnQgU2l6ZSIgOiAiU2NocmlmdGdyYWQiLAogICAgICAgICJMaW5lIEhlaWdodCIgOiAiWmVpbGVuaMO2aGUiLAogICAgICAgICJMZXR0ZXIgU3BhY2luZyIgOiAiQnVjaHN0YWJlbmFic3RhbmQiLAogICAgICAgICJQYXJhZ3JhcGggRm9ybWF0IiA6ICJBYnNhdHpmb3JtYXQiLAogICAgICAgICJKdXN0aWZ5IExlZnQiIDogIkxpbmtzIGF1c3JpY2h0ZW4iLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAiWmVudHJpZXJ0IGF1c3JpY2h0ZW4iLAogICAgICAgICJKdXN0aWZ5IEZ1bGwiIDogIkJsb2Nrc2F0eiIsCiAgICAgICAgIkp1c3RpZnkgUmlnaHQiIDogIlJlY2h0cyBhdXNyaWNodGVuIiwKICAgICAgICAiTWFyZ2luIExlZnQiIDogIlJhbmQgbGlua3MiLAogICAgICAgICJNYXJnaW4gUmlnaHQiIDogIlJhbmQgcmVjaHRzIiwKICAgICAgICAiTWFyZ2luIFRvcCIgOiAiUmFuZCBvYmVuIiwKICAgICAgICAiTWFyZ2luIEJvdHRvbSIgOiAiUmFuZCB1bnRlbiIsCiAgICAgICAgIkJ1bGxldGVkIExpc3QiIDogIkxpc3RlIG1pdCBBdWZ6w6RobHVuZ3N6ZWljaGVuIiwKICAgICAgICAiTnVtYmVyZWQgTGlzdCIgOiAiTnVtbWVyaWVydGUgTGlzdGUiLAogICAgICAgICJVcHBlci1jYXNlIEFscGhhYmV0IExpc3QiIDogIkFscGhhYmV0bGlzdGUgbWl0IEdyb8OfYnVjaHN0YWJlbiIsCiAgICAgICAgIkxvd2VyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAiQWxwaGFiZXRsaXN0ZSBtaXQgS2xlaW5idWNoc3RhYmVuIiwKICAgICAgICAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiA6ICJMaXN0ZSBtaXQgZ3Jvw59nZXNjaHJpZWJlbmVuIHLDtm1pc2NoZW4gWmVpY2hlbiIsCiAgICAgICAgIkxvd2VyLWNhc2UgUm9tYW4gTGlzdCIgOiAiS2xlaW5nZXNjaHJpZWJlbmUgcsO2bWlzY2hlIExpc3RlIiwKICAgICAgICAiSW5kZW50IiA6ICJFaW56dWciLAogICAgICAgICJPdXRkZW50IiA6ICJBdXNyw7xja2VuIiwKICAgICAgICAiRmluZCAmIFJlcGxhY2UiIDogIlN1Y2hlbiB1bmQgRXJzZXR6ZW4iLAogICAgICAgICJJbnNlcnQgTGluayIgOiAiTGluayBlaW5mw7xnZW4iLAogICAgICAgICJGaW5kIiA6ICJTdWNoZW4iLAogICAgICAgICJSZXBsYWNlIiA6ICJFcnNldHplbiIsCiAgICAgICAgIlJlcGxhY2UgYWxsIiA6ICJBbGxlIGVyc2V0emVuIiwKICAgICAgICAiTWF0Y2ggY2FzZSIgOiAiR3Jvw58tL0tsZWluc2NocmVpYnVuZyBiZWFjaHRlbiIsCiAgICAgICAgIldob2xlIHdvcmQiIDogIkdhbnplcyBXb3J0IiwKICAgICAgICAiUmVnIEV4IiA6ICJSZWd1bMOkcmVyIEF1c2RydWNrIiwKICAgICAgICAiSW5mbyIgOiAiSW5mb3JtYXRpb24iLAogICAgICAgICJSZWFjaGVkIGVuZCBvZiBtb2R1bGUuIiA6ICJFbmRlIGRlcyBNb2R1bHMgd3VyZGUgZXJyZWljaHQuIiwKICAgICAgICAiTWF0Y2ggTm90IEZvdW5kIiA6ICJLZWluZSDDnGJlcmVpbnN0aW1tdW5nIGdlZnVuZGVuIiwKICAgICAgICAiezB9IG1hdGNoZXMgcmVwbGFjZWQiIDogInswfSDDnGJlcmVpbnN0aW1tdW5nZW4gZXJzZXR6dCIsCiAgICAgICAgIlRpbWVzIE5ldyBSb21hbiIgOiAiVGltZXMgTmV3IFJvbWFuIiwKICAgICAgICAiQXJpYWwiIDogIkFyaWFsIiwKICAgICAgICAiQ291cmllciIgOiAiQ291cmllciIsCiAgICAgICAgIkNvdXJpZXIgTmV3IiA6ICJDb3VyaWVyIE5ldyIsCiAgICAgICAgIkdlbmV2YSIgOiAiR2VuZXZhIiwKICAgICAgICAiR2VvcmdpYSIgOiAiR2VvcmdpYSIsCiAgICAgICAgIkhlbHZldGljYSIgOiAiSGVsdmV0aWNhIiwKICAgICAgICAiVGFob21hIiA6ICJUYWhvbWEiLAogICAgICAgICJUaW1lcyIgOiAiVGltZXMiLAogICAgICAgICJWZXJkYW5hIiA6ICJWZXJkYW5hIiwKICAgICAgICAiTm9uZSIgOiAiS2VpbmUiLAogICAgICAgICJIZWFkZXIgMSIgOiAiw5xiZXJzY2hyaWZ0IDEiLAogICAgICAgICJIZWFkZXIgMiIgOiAiw5xiZXJzY2hyaWZ0IDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAiw5xiZXJzY2hyaWZ0IDMiLAogICAgICAgICJIZWFkZXIgNCIgOiAiw5xiZXJzY2hyaWZ0IDQiLAogICAgICAgICJIZWFkZXIgNSIgOiAiw5xiZXJzY2hyaWZ0IDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAiw5xiZXJzY2hyaWZ0IDYiLAogICAgICAgICJTZWxlY3QiIDogIkF1c3fDpGhsZW4iLAogICAgICAgICJCYXNpYyBWaWV3IiA6ICJFaW5mYWNoZSBBbnNpY2h0IiwKICAgICAgICAiRnVsbFNjcmVlbiIgOiAiVm9sbGJpbGQiLAogICAgICAgICJFeHBhbmQiIDogIkVyd2VpdGVybiIsCiAgICAgICAgIkNvbGxhcHNlIiA6ICJSZWR1emllcmVuIiwKICAgICAgICAiTGlzdCBUeXBlIiA6ICJMaXN0ZW50eXAiLAogICAgICAgICJVUkwiIDogIlVSTCIsCiAgICAgICAgIkFsdCBUZXh0IiA6ICJBbHQtVGV4dCIsCiAgICAgICAgIk9wZW4gaW4gbmV3IHBhZ2UiIDogIkF1ZiBuZXVlciBTZWl0ZSDDtmZmbmVuIgogICAgfTsKfSkoRm9ybS5ydGUuSTE4bik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiAyNC8xMC8yMDE2LgogKi8KCihmdW5jdGlvbiAoSTE4bikgewoKICAgIHZhciBlcyA9IEkxOG4uZXMgPSB7fTsKCiAgICBlcy5zdHJpbmdzID0gewogICAgICAgICJVbmRvIiA6ICJEZXNoYWNlciIsCiAgICAgICAgIlJlZG8iIDogIlJlaGFjZXIiLAogICAgICAgICJCb2xkIiA6ICJOZWdyaXRhIiwKICAgICAgICAiSXRhbGljIiA6ICJDdXJzaXZhIiwKICAgICAgICAiVW5kZXJsaW5lIiA6ICJTdWJyYXlhZG8iLAogICAgICAgICJTdXBlci1zY3JpcHQiIDogIlN1cGVyw61uZGljZSIsCiAgICAgICAgIlN1Yi1zY3JpcHQiIDogIlN1YsOtbmRpY2UiLAogICAgICAgICJUZXh0IENvbG9yIiA6ICJDb2xvciBkZWwgdGV4dG8iLAogICAgICAgICJIaWdobGlnaHQgQ29sb3IiIDogIkNvbG9yIGRlIHJlc2FsdGFkbyIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICJGYW1pbGlhIGRlIGZ1ZW50ZXMiLAogICAgICAgICJGb250IFNpemUiIDogIlRhbWHDsW8gZGUgZnVlbnRlIiwKICAgICAgICAiTGluZSBIZWlnaHQiIDogIkFsdHVyYSBkZSBsYSBsw61uZWEiLAogICAgICAgICJMZXR0ZXIgU3BhY2luZyIgOiAiRXNwYWNpYWRvIGVudHJlIGxldHJhcyIsCiAgICAgICAgIlBhcmFncmFwaCBGb3JtYXQiIDogIkZvcm1hdG8gZGUgcMOhcnJhZm8iLAogICAgICAgICJKdXN0aWZ5IExlZnQiIDogIkp1c3RpZmljYXIgYSBsYSBpenF1aWVyZGEiLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAiSnVzdGlmaWNhciBhbCBjZW50cm8iLAogICAgICAgICJKdXN0aWZ5IEZ1bGwiIDogIkp1c3RpZmljYXIgdG9kbyIsCiAgICAgICAgIkp1c3RpZnkgUmlnaHQiIDogIkp1c3RpZmljYXIgYSBsYSBkZXJlY2hhIiwKICAgICAgICAiTWFyZ2luIExlZnQiIDogIk1hcmdlbiBpenF1aWVyZG8iLAogICAgICAgICJNYXJnaW4gUmlnaHQiIDogIk1hcmdlbiBkZXJlY2hvIiwKICAgICAgICAiTWFyZ2luIFRvcCIgOiAiTWFyZ2VuIHN1cGVyaW9yIiwKICAgICAgICAiTWFyZ2luIEJvdHRvbSIgOiAiTWFyZ2VuIGluZmVyaW9yIiwKICAgICAgICAiQnVsbGV0ZWQgTGlzdCIgOiAiTGlzdGEgY29uIHZpw7FldGFzIiwKICAgICAgICAiTnVtYmVyZWQgTGlzdCIgOiAiTGlzdGEgbnVtZXJhZGEiLAogICAgICAgICJVcHBlci1jYXNlIEFscGhhYmV0IExpc3QiIDogIkxpc3RhIGRlIGxldHJhcyBkZWwgYWxmYWJldG8gZW4gbWF5w7pzY3VsYSIsCiAgICAgICAgIkxvd2VyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAiTGlzdGEgZGUgbGV0cmFzIGRlbCBhbGZhYmV0byBlbiBtaW7DunNjdWxhIiwKICAgICAgICAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiA6ICJMaXN0YSBkZSBjYXJhY3RlcmVzIHJvbWFub3MgZW4gbWluw7pzY3VsYSIsCiAgICAgICAgIkxvd2VyLWNhc2UgUm9tYW4gTGlzdCIgOiAiTGlzdGEgZGUgY2FyYWN0ZXJlcyByb21hbm9zIGVuIG1pbsO6c2N1bGEiLAogICAgICAgICJJbmRlbnQiIDogIlNhbmdyw61hIiwKICAgICAgICAiT3V0ZGVudCIgOiAiQW51bGFyIHNhbmdyw61hIiwKICAgICAgICAiRmluZCAmIFJlcGxhY2UiIDogIkJ1c2NhciB5IHJlZW1wbGF6YXIiLAogICAgICAgICJJbnNlcnQgTGluayIgOiAiSW5zZXJ0YXIgdsOtbmN1bG8iLAogICAgICAgICJGaW5kIiA6ICJCdXNjYXIiLAogICAgICAgICJSZXBsYWNlIiA6ICJSZWVtcGxhemFyIiwKICAgICAgICAiUmVwbGFjZSBhbGwiIDogIlJlZW1wbGF6YXIgdG9kbyIsCiAgICAgICAgIk1hdGNoIGNhc2UiIDogIkNvaW5jaWRpciBtYXnDunNjdWxhcyB5IG1pbsO6c2N1bGFzIiwKICAgICAgICAiV2hvbGUgd29yZCIgOiAiUGFsYWJyYSBjb21wbGV0YSIsCiAgICAgICAgIlJlZyBFeCIgOiAiUmVnIGV4IiwKICAgICAgICAiSW5mbyIgOiAiSW5mb3JtYWNpw7NuIiwKICAgICAgICAiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIgOiAiRmluIGRlbCBtw7NkdWxvIGFsY2FuemFkby4iLAogICAgICAgICJNYXRjaCBOb3QgRm91bmQiIDogIkNvaW5jaWRlbmNpYSBubyBlbmNvbnRyYWRhIiwKICAgICAgICAiezB9IG1hdGNoZXMgcmVwbGFjZWQiIDogInswfSBjb2luY2lkZW5jaWFzIHJlZW1wbGF6YWRhcyIsCiAgICAgICAgIlRpbWVzIE5ldyBSb21hbiIgOiAiVGltZXMgTmV3IFJvbWFuIiwKICAgICAgICAiQXJpYWwiIDogIkFyaWFsIiwKICAgICAgICAiQ291cmllciIgOiAiQ291cmllciIsCiAgICAgICAgIkNvdXJpZXIgTmV3IiA6ICJDb3VyaWVyIE5ldyIsCiAgICAgICAgIkdlbmV2YSIgOiAiR2VuZXZhIiwKICAgICAgICAiR2VvcmdpYSIgOiAiR2VvcmdpYSIsCiAgICAgICAgIkhlbHZldGljYSIgOiAiSGVsdmV0aWNhIiwKICAgICAgICAiVGFob21hIiA6ICJUYWhvbWEiLAogICAgICAgICJUaW1lcyIgOiAiVGltZXMiLAogICAgICAgICJWZXJkYW5hIiA6ICJWZXJkYW5hIiwKICAgICAgICAiTm9uZSIgOiAiTmluZ3VubyIsCiAgICAgICAgIkhlYWRlciAxIiA6ICJDYWJlY2VyYSAxIiwKICAgICAgICAiSGVhZGVyIDIiIDogIkNhYmVjZXJhIDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAiQ2FiZWNlcmEgMyIsCiAgICAgICAgIkhlYWRlciA0IiA6ICJDYWJlY2VyYSA0IiwKICAgICAgICAiSGVhZGVyIDUiIDogIkNhYmVjZXJhIDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAiQ2FiZWNlcmEgNiIsCiAgICAgICAgIlNlbGVjdCIgOiAiU2VsZWNjaW9uYXIiLAogICAgICAgICJCYXNpYyBWaWV3IiA6ICJWaXN0YSBiw6FzaWNhIiwKICAgICAgICAiRnVsbFNjcmVlbiIgOiAiUGFudGFsbGEgY29tcGxldGEiLAogICAgICAgICJFeHBhbmQiIDogIkV4cGFuZGlyIiwKICAgICAgICAiQ29sbGFwc2UiIDogIkNvbnRyYWVyIiwKICAgICAgICAiTGlzdCBUeXBlIiA6ICJUaXBvIGRlIGxpc3RhIiwKICAgICAgICAiVVJMIiA6ICJVUkwiLAogICAgICAgICJBbHQgVGV4dCIgOiAiVGV4dG8gYWx0ZXJuYXRpdm8iLAogICAgICAgICJPcGVuIGluIG5ldyBwYWdlIiA6ICJBYnJpciBlbiBudWV2YSBww6FnaW5hIgogICAgfTsKfSkoRm9ybS5ydGUuSTE4bik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiAyNC8xMC8yMDE2LgogKi8KCihmdW5jdGlvbiAoSTE4bikgewoKICAgIHZhciBmciA9IEkxOG4uZnIgPSB7fTsKCiAgICBmci5zdHJpbmdzID0gewogICAgICAgICJVbmRvIiA6ICJBbm51bGVyIiwKICAgICAgICAiUmVkbyIgOiAiUsOpdGFibGlyIiwKICAgICAgICAiQm9sZCIgOiAiR3JhcyIsCiAgICAgICAgIkl0YWxpYyIgOiAiSXRhbGlxdWUiLAogICAgICAgICJVbmRlcmxpbmUiIDogIlNvdWxpZ27DqSIsCiAgICAgICAgIlN1cGVyLXNjcmlwdCIgOiAiRXhwb3NhbnQiLAogICAgICAgICJTdWItc2NyaXB0IiA6ICJJbmRpY2UiLAogICAgICAgICJUZXh0IENvbG9yIiA6ICJDb3VsZXVyIGR1IHRleHRlIiwKICAgICAgICAiSGlnaGxpZ2h0IENvbG9yIiA6ICJDb3VsZXVyIGRlIHN1cmJyaWxsYW5jZSIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICJGYW1pbGxlIGRlIHBvbGljZXMiLAogICAgICAgICJGb250IFNpemUiIDogIlRhaWxsZSBkZSBsYSBwb2xpY2UiLAogICAgICAgICJMaW5lIEhlaWdodCIgOiAiSGF1dGV1ciBkZSBsaWduZSIsCiAgICAgICAgIkxldHRlciBTcGFjaW5nIiA6ICJJbnRlcmxldHRyYWdlIiwKICAgICAgICAiUGFyYWdyYXBoIEZvcm1hdCIgOiAiRm9ybWF0IGRlIHBhcmFncmFwaGUiLAogICAgICAgICJKdXN0aWZ5IExlZnQiIDogIkp1c3RpZmllciDDoCBnYXVjaGUiLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAiSnVzdGlmaWVyIGF1IGNlbnRyZSIsCiAgICAgICAgIkp1c3RpZnkgRnVsbCIgOiAiSnVzdGlmaWVyIGVudGnDqHJlbWVudCIsCiAgICAgICAgIkp1c3RpZnkgUmlnaHQiIDogIkp1c3RpZmllciDDoCBkcm9pdGUiLAogICAgICAgICJNYXJnaW4gTGVmdCIgOiAiTWFyZ2UgZ2F1Y2hlIiwKICAgICAgICAiTWFyZ2luIFJpZ2h0IiA6ICJNYXJnZSBkcm9pdGUiLAogICAgICAgICJNYXJnaW4gVG9wIiA6ICJNYXJnZSBzdXDDqXJpZXVyZSIsCiAgICAgICAgIk1hcmdpbiBCb3R0b20iIDogIk1hcmdlIGluZsOpcmlldXJlIiwKICAgICAgICAiQnVsbGV0ZWQgTGlzdCIgOiAiTGlzdGUgw6AgcHVjZXMiLAogICAgICAgICJOdW1iZXJlZCBMaXN0IiA6ICJMaXN0ZSBudW3DqXJvdMOpZSIsCiAgICAgICAgIlVwcGVyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAiTGlzdGUgYWxwaGFiw6l0aXF1ZSBlbiBtYWp1c2N1bGVzIiwKICAgICAgICAiTG93ZXItY2FzZSBBbHBoYWJldCBMaXN0IiA6ICJMaXN0ZSBhbHBoYWLDqXRpcXVlIGVuIG1pbnVzY3VsZXMiLAogICAgICAgICJVcHBlci1jYXNlIFJvbWFuIExpc3QiIDogIkxpc3RlIGVuIG1hanVzY3VsZXMgcm9tYWluZXMiLAogICAgICAgICJMb3dlci1jYXNlIFJvbWFuIExpc3QiIDogIkxpc3RlIGVuIGNhcmFjdMOocmVzIHJvbWFpbnMgbWludXNjdWxlcyIsCiAgICAgICAgIkluZGVudCIgOiAiUmV0cmFpdCIsCiAgICAgICAgIk91dGRlbnQiIDogIlJldHJhaXQgbsOpZ2F0aWYiLAogICAgICAgICJGaW5kICYgUmVwbGFjZSIgOiAiUmVjaGVyY2hlciBldCByZW1wbGFjZXIiLAogICAgICAgICJJbnNlcnQgTGluayIgOiAiSW5zw6lyZXIgdW4gbGllbiIsCiAgICAgICAgIkZpbmQiIDogIlJlY2hlcmNoZSIsCiAgICAgICAgIlJlcGxhY2UiIDogIlJlbXBsYWNlciIsCiAgICAgICAgIlJlcGxhY2UgYWxsIiA6ICJSZW1wbGFjZXIgdG91dCIsCiAgICAgICAgIk1hdGNoIGNhc2UiIDogIlJlc3BlY3RlciBsYSBjYXNzZSIsCiAgICAgICAgIldob2xlIHdvcmQiIDogIk1vdCBlbnRpZXIiLAogICAgICAgICJSZWcgRXgiIDogIkV4cC4gcsOpZy4iLAogICAgICAgICJJbmZvIiA6ICJJbmZvcyIsCiAgICAgICAgIlJlYWNoZWQgZW5kIG9mIG1vZHVsZS4iIDogIkF0dGVpbmRyZSBsYSBmaW4gZHUgbW9kdWxlLiIsCiAgICAgICAgIk1hdGNoIE5vdCBGb3VuZCIgOiAiQXVjdW5lIGNvcnJlc3BvbmRhbmNlIHRyb3V2w6llIiwKICAgICAgICAiezB9IG1hdGNoZXMgcmVwbGFjZWQiIDogInswfcKgY29ycmVzcG9uZGFuY2VzIHJlbXBsYWPDqWVzIiwKICAgICAgICAiVGltZXMgTmV3IFJvbWFuIiA6ICJUaW1lcyBOZXcgUm9tYW4iLAogICAgICAgICJBcmlhbCIgOiAiQXJpYWwiLAogICAgICAgICJDb3VyaWVyIiA6ICJDb3VyaWVyIiwKICAgICAgICAiQ291cmllciBOZXciIDogIkNvdXJpZXIgTmV3IiwKICAgICAgICAiR2VuZXZhIiA6ICJHZW5ldmEiLAogICAgICAgICJHZW9yZ2lhIiA6ICJHZW9yZ2lhIiwKICAgICAgICAiSGVsdmV0aWNhIiA6ICJIZWx2ZXRpY2EiLAogICAgICAgICJUYWhvbWEiIDogIlRhaG9tYSIsCiAgICAgICAgIlRpbWVzIiA6ICJUaW1lcyIsCiAgICAgICAgIlZlcmRhbmEiIDogIlZlcmRhbmEiLAogICAgICAgICJOb25lIiA6ICJBdWN1bmUiLAogICAgICAgICJIZWFkZXIgMSIgOiAiRW4tdMOqdGXCoDEiLAogICAgICAgICJIZWFkZXIgMiIgOiAiRW4tdMOqdGXCoDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAiRW4tdMOqdGXCoDMiLAogICAgICAgICJIZWFkZXIgNCIgOiAiRW4tdMOqdGXCoDQiLAogICAgICAgICJIZWFkZXIgNSIgOiAiRW4tdMOqdGXCoDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAiRW4tdMOqdGXCoDYiLAogICAgICAgICJTZWxlY3QiIDogIlPDqWxlY3Rpb25uZXIiLAogICAgICAgICJCYXNpYyBWaWV3IiA6ICJWdWUgZGUgYmFzZSIsCiAgICAgICAgIkZ1bGxTY3JlZW4iIDogIlBsZWluIMOpY3JhbiIsCiAgICAgICAgIkV4cGFuZCIgOiAiRMOpdmVsb3BwZXIiLAogICAgICAgICJDb2xsYXBzZSIgOiAiUsOpZHVpcmUiLAogICAgICAgICJMaXN0IFR5cGUiIDogIlR5cGUgZGUgbGlzdGUiLAogICAgICAgICJVUkwiIDogIlVSTCIsCiAgICAgICAgIkFsdCBUZXh0IiA6ICJBdXRyZSB0ZXh0ZSIsCiAgICAgICAgIk9wZW4gaW4gbmV3IHBhZ2UiIDogIk91dnJpciBkYW5zIHVuZSBub3V2ZWxsZSBwYWdlIgogICAgfTsKfSkoRm9ybS5ydGUuSTE4bik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiAyNC8xMC8yMDE2LgogKi8KCihmdW5jdGlvbiAoSTE4bikgewoKICAgIHZhciBpdCA9IEkxOG4uaXQgPSB7fTsKCiAgICBpdC5zdHJpbmdzID0gewogICAgICAgICJVbmRvIiA6ICJBbm51bGxhIiwKICAgICAgICAiUmVkbyIgOiAiUmlwZXRpIiwKICAgICAgICAiQm9sZCIgOiAiR3Jhc3NldHRvIiwKICAgICAgICAiSXRhbGljIiA6ICJDb3JzaXZvIiwKICAgICAgICAiVW5kZXJsaW5lIiA6ICJTb3R0b2xpbmVhIiwKICAgICAgICAiU3VwZXItc2NyaXB0IiA6ICJBcGljZSIsCiAgICAgICAgIlN1Yi1zY3JpcHQiIDogIlBlZGljZSIsCiAgICAgICAgIlRleHQgQ29sb3IiIDogIkNvbG9yZSB0ZXN0byIsCiAgICAgICAgIkhpZ2hsaWdodCBDb2xvciIgOiAiQ29sb3JlIGV2aWRlbnppYXppb25lIiwKICAgICAgICAiRm9udCBGYW1pbHkiIDogIkZhbWlnbGlhIGRpIGZvbnQiLAogICAgICAgICJGb250IFNpemUiIDogIkRpbWVuc2lvbmUgZm9udCIsCiAgICAgICAgIkxpbmUgSGVpZ2h0IiA6ICJBbHRlenphIHJpZ2EiLAogICAgICAgICJMZXR0ZXIgU3BhY2luZyIgOiAiU3BhemlhdHVyYSB0cmEgbGV0dGVyZSIsCiAgICAgICAgIlBhcmFncmFwaCBGb3JtYXQiIDogIkZvcm1hdG8gcGFyYWdyYWZvIiwKICAgICAgICAiSnVzdGlmeSBMZWZ0IiA6ICJHaXVzdGlmaWNhIGEgc2luaXN0cmEiLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAiR2l1c3RpZmljYSBhbCBjZW50cm8iLAogICAgICAgICJKdXN0aWZ5IEZ1bGwiIDogIkdpdXN0aWZpY2EiLAogICAgICAgICJKdXN0aWZ5IFJpZ2h0IiA6ICJHaXVzdGlmaWNhIGEgZGVzdHJhIiwKICAgICAgICAiTWFyZ2luIExlZnQiIDogIk1hcmdpbmUgc2luaXN0cm8iLAogICAgICAgICJNYXJnaW4gUmlnaHQiIDogIk1hcmdpbmUgZGVzdHJvIiwKICAgICAgICAiTWFyZ2luIFRvcCIgOiAiTWFyZ2luZSBzdXBlcmlvcmUiLAogICAgICAgICJNYXJnaW4gQm90dG9tIiA6ICJNYXJnaW5lIGluZmVyaW9yZSIsCiAgICAgICAgIkJ1bGxldGVkIExpc3QiIDogIkVsZW5jbyBwdW50YXRvIiwKICAgICAgICAiTnVtYmVyZWQgTGlzdCIgOiAiRWxlbmNvIG51bWVyYXRvIiwKICAgICAgICAiVXBwZXItY2FzZSBBbHBoYWJldCBMaXN0IiA6ICJFbGVuY28gYWxmYWJldG8gbWFpdXNjb2xvIiwKICAgICAgICAiTG93ZXItY2FzZSBBbHBoYWJldCBMaXN0IiA6ICJFbGVuY28gYWxmYWJldG8gbWludXNjb2xvIiwKICAgICAgICAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiA6ICJFbGVuY28gUm9tYW4gbWFpdXNjb2xvIiwKICAgICAgICAiTG93ZXItY2FzZSBSb21hbiBMaXN0IiA6ICJFbGVuY28gUm9tYW4gbWludXNjb2xvIiwKICAgICAgICAiSW5kZW50IiA6ICJSaWVudHJvIiwKICAgICAgICAiT3V0ZGVudCIgOiAiUmllbnRybyBuZWdhdGl2byIsCiAgICAgICAgIkZpbmQgJiBSZXBsYWNlIiA6ICJUcm92YSBlIHNvc3RpdHVpc2NpIiwKICAgICAgICAiSW5zZXJ0IExpbmsiIDogIkluc2VyaXNjaSBjb2xsZWdhbWVudG8iLAogICAgICAgICJGaW5kIiA6ICJUcm92YSIsCiAgICAgICAgIlJlcGxhY2UiIDogIlNvc3RpdHVpc2NpIiwKICAgICAgICAiUmVwbGFjZSBhbGwiIDogIlNvc3RpdHVpc2NpIHR1dHRvIiwKICAgICAgICAiTWF0Y2ggY2FzZSIgOiAiTWFpdXNjb2xlL21pbnVzY29sZSIsCiAgICAgICAgIldob2xlIHdvcmQiIDogIlBhcm9sYSBpbnRlcmEiLAogICAgICAgICJSZWcgRXgiIDogIlJlZyBlc2VnIiwKICAgICAgICAiSW5mbyIgOiAiSW5mb3JtYXppb25pIiwKICAgICAgICAiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIgOiAiRmluZSBkZWwgbW9kdWxvLiIsCiAgICAgICAgIk1hdGNoIE5vdCBGb3VuZCIgOiAiQ29ycmlzcG9uZGVuemEgbm9uIHRyb3ZhdGEiLAogICAgICAgICJ7MH0gbWF0Y2hlcyByZXBsYWNlZCIgOiAiezB9IGNvcnJpc3BvbmRlbnplIHNvc3RpdHVpdGUiLAogICAgICAgICJUaW1lcyBOZXcgUm9tYW4iIDogIlRpbWVzIE5ldyBSb21hbiIsCiAgICAgICAgIkFyaWFsIiA6ICJBcmlhbCIsCiAgICAgICAgIkNvdXJpZXIiIDogIkNvdXJpZXIiLAogICAgICAgICJDb3VyaWVyIE5ldyIgOiAiQ291cmllciBOZXciLAogICAgICAgICJHZW5ldmEiIDogIkdlbmV2YSIsCiAgICAgICAgIkdlb3JnaWEiIDogIkdlb3JnaWEiLAogICAgICAgICJIZWx2ZXRpY2EiIDogIkhlbHZldGljYSIsCiAgICAgICAgIlRhaG9tYSIgOiAiVGFob21hIiwKICAgICAgICAiVGltZXMiIDogIlRpbWVzIiwKICAgICAgICAiVmVyZGFuYSIgOiAiVmVyZGFuYSIsCiAgICAgICAgIk5vbmUiIDogIk5lc3N1bm8iLAogICAgICAgICJIZWFkZXIgMSIgOiAiSW50ZXN0YXppb25lIDEiLAogICAgICAgICJIZWFkZXIgMiIgOiAiSW50ZXN0YXppb25lIDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAiSW50ZXN0YXppb25lIDMiLAogICAgICAgICJIZWFkZXIgNCIgOiAiSW50ZXN0YXppb25lIDQiLAogICAgICAgICJIZWFkZXIgNSIgOiAiSW50ZXN0YXppb25lIDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAiSW50ZXN0YXppb25lIDYiLAogICAgICAgICJTZWxlY3QiIDogIlNlbGV6aW9uYSIsCiAgICAgICAgIkJhc2ljIFZpZXciIDogIlZpc3RhIGRpIGJhc2UiLAogICAgICAgICJGdWxsU2NyZWVuIiA6ICJTY2hlcm1vIGludGVybyIsCiAgICAgICAgIkV4cGFuZCIgOiAiRXNwYW5kaSIsCiAgICAgICAgIkNvbGxhcHNlIiA6ICJDb21wcmltaSIsCiAgICAgICAgIkxpc3QgVHlwZSIgOiAiVGlwbyBkaSBsaXN0YSIsCiAgICAgICAgIlVSTCIgOiAiVVJMIiwKICAgICAgICAiQWx0IFRleHQiIDogIlRlc3RvIGFsdGVybmF0aXZvIiwKICAgICAgICAiT3BlbiBpbiBuZXcgcGFnZSIgOiAiQXByaSBpbiBudW92YSBwYWdpbmEiCiAgICB9Owp9KShGb3JtLnJ0ZS5JMThuKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDI0LzEwLzIwMTYuCiAqLwoKKGZ1bmN0aW9uIChJMThuKSB7CgogICAgdmFyIGphID0gSTE4bi5qYSA9IHt9OwoKICAgIGphLnN0cmluZ3MgPSB7CiAgICAgICAgIlVuZG8iIDogIuWPluOCiua2iOOBlyIsCiAgICAgICAgIlJlZG8iIDogIuOChOOCiuebtOOBlyIsCiAgICAgICAgIkJvbGQiIDogIuWkquWtlyIsCiAgICAgICAgIkl0YWxpYyIgOiAi44Kk44K/44Oq44OD44KvIiwKICAgICAgICAiVW5kZXJsaW5lIiA6ICLkuIvnt5oiLAogICAgICAgICJTdXBlci1zY3JpcHQiIDogIuS4iuS7mOOBjeaWh+WtlyIsCiAgICAgICAgIlN1Yi1zY3JpcHQiIDogIuS4i+S7mOOBjeaWh+WtlyIsCiAgICAgICAgIlRleHQgQ29sb3IiIDogIuODhuOCreOCueODiOOCq+ODqeODvCIsCiAgICAgICAgIkhpZ2hsaWdodCBDb2xvciIgOiAi44OP44Kk44Op44Kk44OI6KGo56S644Gu6ImyIiwKICAgICAgICAiRm9udCBGYW1pbHkiIDogIuODleOCqeODs+ODiOODleOCoeODn+ODquODvCIsCiAgICAgICAgIkZvbnQgU2l6ZSIgOiAi44OV44Kp44Oz44OI44K144Kk44K6IiwKICAgICAgICAiTGluZSBIZWlnaHQiIDogIuihjOOBrumrmOOBlSIsCiAgICAgICAgIkxldHRlciBTcGFjaW5nIiA6ICLmloflrZfplpPpmpQiLAogICAgICAgICJQYXJhZ3JhcGggRm9ybWF0IiA6ICLmrrXokL3mm7jlvI8iLAogICAgICAgICJKdXN0aWZ5IExlZnQiIDogIuW3puaPg+OBiCIsCiAgICAgICAgIkp1c3RpZnkgQ2VudGVyIiA6ICLkuK3lpK7mj4PjgYgiLAogICAgICAgICJKdXN0aWZ5IEZ1bGwiIDogIuS4oeerr+aPg+OBiCIsCiAgICAgICAgIkp1c3RpZnkgUmlnaHQiIDogIuWPs+aPg+OBiCIsCiAgICAgICAgIk1hcmdpbiBMZWZ0IiA6ICLlt6bjg57jg7zjgrjjg7MiLAogICAgICAgICJNYXJnaW4gUmlnaHQiIDogIuWPs+ODnuODvOOCuOODsyIsCiAgICAgICAgIk1hcmdpbiBUb3AiIDogIuS4iuODnuODvOOCuOODsyIsCiAgICAgICAgIk1hcmdpbiBCb3R0b20iIDogIuS4i+ODnuODvOOCuOODsyIsCiAgICAgICAgIkJ1bGxldGVkIExpc3QiIDogIuODkOODrOODg+ODiOODquOCueODiCIsCiAgICAgICAgIk51bWJlcmVkIExpc3QiIDogIueVquWPt+S7mOOBjeODquOCueODiCIsCiAgICAgICAgIlVwcGVyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAi5aSn5paH5a2X44Ki44Or44OV44Kh44OZ44OD44OI44Oq44K544OIIiwKICAgICAgICAiTG93ZXItY2FzZSBBbHBoYWJldCBMaXN0IiA6ICLlsI/mloflrZfjgqLjg6vjg5XjgqHjg5njg4Pjg4jjg6rjgrnjg4giLAogICAgICAgICJVcHBlci1jYXNlIFJvbWFuIExpc3QiIDogIuWkp+aWh+Wtl+ODreODvOODnuODs+ODquOCueODiCIsCiAgICAgICAgIkxvd2VyLWNhc2UgUm9tYW4gTGlzdCIgOiAi5bCP5paH5a2X44Ot44O844Oe44Oz44Oq44K544OIIiwKICAgICAgICAiSW5kZW50IiA6ICLjgqTjg7Pjg4fjg7Pjg4giLAogICAgICAgICJPdXRkZW50IiA6ICLjgqLjgqbjg4jjg4fjg7Pjg4giLAogICAgICAgICJGaW5kICYgUmVwbGFjZSIgOiAi5qSc57Si44Go572u5o+bIiwKICAgICAgICAiSW5zZXJ0IExpbmsiIDogIuODquODs+OCr+OCkuaMv+WFpSIsCiAgICAgICAgIkZpbmQiIDogIuaknOe0oiIsCiAgICAgICAgIlJlcGxhY2UiIDogIue9ruaPmyIsCiAgICAgICAgIlJlcGxhY2UgYWxsIiA6ICLjgZnjgbnjgabnva7mj5siLAogICAgICAgICJNYXRjaCBjYXNlIiA6ICLlpKfmloflrZcgLyDlsI/mloflrZfjgpLkuIDoh7QiLAogICAgICAgICJXaG9sZSB3b3JkIiA6ICLljZjoqp7lhajkvZMiLAogICAgICAgICJSZWcgRXgiIDogIuato+imj+ihqOePviIsCiAgICAgICAgIkluZm8iIDogIuaDheWgsSIsCiAgICAgICAgIlJlYWNoZWQgZW5kIG9mIG1vZHVsZS4iIDogIuODouOCuOODpeODvOODq+OBruacgOW+jOOBq+mBlOOBl+OBvuOBl+OBn+OAgiIsCiAgICAgICAgIk1hdGNoIE5vdCBGb3VuZCIgOiAi5LiA6Ie044GM6KaL44Gk44GL44KK44G+44Gb44KT44Gn44GX44GfIiwKICAgICAgICAiezB9IG1hdGNoZXMgcmVwbGFjZWQiIDogInswfSDlgIvjga7kuIDoh7TjgYznva7mj5vjgZXjgozjgb7jgZfjgZ8iLAogICAgICAgICJUaW1lcyBOZXcgUm9tYW4iIDogIlRpbWVzIE5ldyBSb21hbiIsCiAgICAgICAgIkFyaWFsIiA6ICJBcmlhbCIsCiAgICAgICAgIkNvdXJpZXIiIDogIkNvdXJpZXIiLAogICAgICAgICJDb3VyaWVyIE5ldyIgOiAiQ291cmllciBOZXciLAogICAgICAgICJHZW5ldmEiIDogIkdlbmV2YSIsCiAgICAgICAgIkdlb3JnaWEiIDogIkdlb3JnaWEiLAogICAgICAgICJIZWx2ZXRpY2EiIDogIkhlbHZldGljYSIsCiAgICAgICAgIlRhaG9tYSIgOiAiVGFob21hIiwKICAgICAgICAiVGltZXMiIDogIlRpbWVzIiwKICAgICAgICAiVmVyZGFuYSIgOiAiVmVyZGFuYSIsCiAgICAgICAgIk5vbmUiIDogIumBqeeUqOOBquOBlyIsCiAgICAgICAgIkhlYWRlciAxIiA6ICLjg5jjg4Pjg4Djg7wgMSIsCiAgICAgICAgIkhlYWRlciAyIiA6ICLjg5jjg4Pjg4Djg7wgMiIsCiAgICAgICAgIkhlYWRlciAzIiA6ICLjg5jjg4Pjg4Djg7wgMyIsCiAgICAgICAgIkhlYWRlciA0IiA6ICLjg5jjg4Pjg4Djg7wgNCIsCiAgICAgICAgIkhlYWRlciA1IiA6ICLjg5jjg4Pjg4Djg7wgNSIsCiAgICAgICAgIkhlYWRlciA2IiA6ICLjg5jjg4Pjg4Djg7wgNiIsCiAgICAgICAgIlNlbGVjdCIgOiAi6YG45oqeIiwKICAgICAgICAiQmFzaWMgVmlldyIgOiAi5Z+65pys6KGo56S6IiwKICAgICAgICAiRnVsbFNjcmVlbiIgOiAi44OV44Or44K544Kv44Oq44O844OzIiwKICAgICAgICAiRXhwYW5kIiA6ICLlsZXplosiLAogICAgICAgICJDb2xsYXBzZSIgOiAi6Zqg44GZIiwKICAgICAgICAiTGlzdCBUeXBlIiA6ICLjg6rjgrnjg4jjgr/jgqTjg5ciLAogICAgICAgICJVUkwiIDogIlVSTCIsCiAgICAgICAgIkFsdCBUZXh0IiA6ICLku6Pmm7/jg4bjgq3jgrnjg4giLAogICAgICAgICJPcGVuIGluIG5ldyBwYWdlIiA6ICLmlrDjgZfjgYTjg5rjg7zjgrjjgafplovjgY8iCiAgICB9Owp9KShGb3JtLnJ0ZS5JMThuKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDI0LzEwLzIwMTYuCiAqLwoKKGZ1bmN0aW9uIChJMThuKSB7CgogICAgdmFyIGtvS1IgPSBJMThuLmtvS1IgPSB7fTsKCiAgICBrb0tSLnN0cmluZ3MgPSB7CiAgICAgICAgIlVuZG8iIDogIuyLpO2WiSDst6jshowiLAogICAgICAgICJSZWRvIiA6ICLri6Tsi5wg7Iuk7ZaJIiwKICAgICAgICAiQm9sZCIgOiAi67O865Oc7LK0IiwKICAgICAgICAiSXRhbGljIiA6ICLsnbTtg6Trpq3ssrQiLAogICAgICAgICJVbmRlcmxpbmUiIDogIuuwkeykhCIsCiAgICAgICAgIlN1cGVyLXNjcmlwdCIgOiAi7JyEIOyyqOyekCIsCiAgICAgICAgIlN1Yi1zY3JpcHQiIDogIuyVhOuemCDssqjsnpAiLAogICAgICAgICJUZXh0IENvbG9yIiA6ICLthY3siqTtirgg7IOJ7IOBIiwKICAgICAgICAiSGlnaGxpZ2h0IENvbG9yIiA6ICLqsJXsobAg7IOJ7IOBIiwKICAgICAgICAiRm9udCBGYW1pbHkiIDogIuq4gOq8tCDrqqjsnYwiLAogICAgICAgICJGb250IFNpemUiIDogIuq4gOq8tCDtgazquLAiLAogICAgICAgICJMaW5lIEhlaWdodCIgOiAi7ISgIOuGkuydtCIsCiAgICAgICAgIkxldHRlciBTcGFjaW5nIiA6ICLrrLjsnpAg6rCE6rKpIiwKICAgICAgICAiUGFyYWdyYXBoIEZvcm1hdCIgOiAi64uo6529IO2YleyLnSIsCiAgICAgICAgIkp1c3RpZnkgTGVmdCIgOiAi7Jm87Kq9IOunnuy2pCIsCiAgICAgICAgIkp1c3RpZnkgQ2VudGVyIiA6ICLqsIDsmrTrjbAg66ee7LakIiwKICAgICAgICAiSnVzdGlmeSBGdWxsIiA6ICLsoITssrQg66ee7LakIiwKICAgICAgICAiSnVzdGlmeSBSaWdodCIgOiAi7Jik66W47Kq9IOunnuy2pCIsCiAgICAgICAgIk1hcmdpbiBMZWZ0IiA6ICLsmbzsqr0g7Jes67CxIiwKICAgICAgICAiTWFyZ2luIFJpZ2h0IiA6ICLsmKTrpbjsqr0g7Jes67CxIiwKICAgICAgICAiTWFyZ2luIFRvcCIgOiAi7IOB64uoIOyXrOuwsSIsCiAgICAgICAgIk1hcmdpbiBCb3R0b20iIDogIu2VmOuLqCDsl6zrsLEiLAogICAgICAgICJCdWxsZXRlZCBMaXN0IiA6ICLquIDrqLjrpqwg6riw7Zi4IOuqqeuhnSIsCiAgICAgICAgIk51bWJlcmVkIExpc3QiIDogIuuyiO2YuCDrp6TquLDquLAg66qp66GdIiwKICAgICAgICAiVXBwZXItY2FzZSBBbHBoYWJldCBMaXN0IiA6ICLrjIDrrLjsnpAg7JWM7YyM67KzIOuqqeuhnSIsCiAgICAgICAgIkxvd2VyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAi7IaM66y47J6QIOyVjO2MjOuysyDrqqnroZ0iLAogICAgICAgICJVcHBlci1jYXNlIFJvbWFuIExpc3QiIDogIuuMgOusuOyekCDroZzrp4jsnpAg66qp66GdIiwKICAgICAgICAiTG93ZXItY2FzZSBSb21hbiBMaXN0IiA6ICLshozrrLjsnpAg66Gc66eI7J6QIOuqqeuhnSIsCiAgICAgICAgIkluZGVudCIgOiAi65Ok7Jes7JOw6riwIiwKICAgICAgICAiT3V0ZGVudCIgOiAi64K07Ja07JOw6riwIiwKICAgICAgICAiRmluZCAmIFJlcGxhY2UiIDogIuywvuq4sCDrsI8g67CU6r646riwIiwKICAgICAgICAiSW5zZXJ0IExpbmsiIDogIuunge2BrCDsgr3snoUiLAogICAgICAgICJGaW5kIiA6ICLssL7quLAiLAogICAgICAgICJSZXBsYWNlIiA6ICLrsJTqvrjquLAiLAogICAgICAgICJSZXBsYWNlIGFsbCIgOiAi66qo65GQIOuwlOq+uOq4sCIsCiAgICAgICAgIk1hdGNoIGNhc2UiIDogIuuMgOyGjOusuOyekCDsnbzsuZgiLAogICAgICAgICJXaG9sZSB3b3JkIiA6ICLri6jslrQg64uo7JyE66Gc66eMIiwKICAgICAgICAiUmVnIEV4IiA6ICLsnbzrsJgg7ZGc7ZiE7IudIiwKICAgICAgICAiSW5mbyIgOiAi7KCV67O0IiwKICAgICAgICAiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIgOiAi66qo65OIIOuBneyXkCDrj4Tri6ztlojsirXri4jri6QuIiwKICAgICAgICAiTWF0Y2ggTm90IEZvdW5kIiA6ICLsnbzsuZjtlZjripQg7ZWt66qp7J2EIOywvuydhCDsiJgg7JeG7Iq164uI64ukLiIsCiAgICAgICAgInswfSBtYXRjaGVzIHJlcGxhY2VkIiA6ICJ7MH3qsJzsnZgg7J287LmYIO2VreuqqeydtCDrjIDssrTrkJjsl4jsirXri4jri6QuIiwKICAgICAgICAiVGltZXMgTmV3IFJvbWFuIiA6ICJUaW1lcyBOZXcgUm9tYW4iLAogICAgICAgICJBcmlhbCIgOiAiQXJpYWwiLAogICAgICAgICJDb3VyaWVyIiA6ICJDb3VyaWVyIiwKICAgICAgICAiQ291cmllciBOZXciIDogIkNvdXJpZXIgTmV3IiwKICAgICAgICAiR2VuZXZhIiA6ICJHZW5ldmEiLAogICAgICAgICJHZW9yZ2lhIiA6ICJHZW9yZ2lhIiwKICAgICAgICAiSGVsdmV0aWNhIiA6ICJIZWx2ZXRpY2EiLAogICAgICAgICJUYWhvbWEiIDogIlRhaG9tYSIsCiAgICAgICAgIlRpbWVzIiA6ICJUaW1lcyIsCiAgICAgICAgIlZlcmRhbmEiIDogIlZlcmRhbmEiLAogICAgICAgICJOb25lIiA6ICLsl4bsnYwiLAogICAgICAgICJIZWFkZXIgMSIgOiAi66i466as6riAIDEiLAogICAgICAgICJIZWFkZXIgMiIgOiAi66i466as6riAIDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAi66i466as6riAIDMiLAogICAgICAgICJIZWFkZXIgNCIgOiAi66i466as6riAIDQiLAogICAgICAgICJIZWFkZXIgNSIgOiAi66i466as6riAIDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAi66i466as6riAIDYiLAogICAgICAgICJTZWxlY3QiIDogIuyEoO2DnSIsCiAgICAgICAgIkJhc2ljIFZpZXciIDogIuq4sOuzuCDrt7AiLAogICAgICAgICJGdWxsU2NyZWVuIiA6ICLsoITssrTtmZTrqbQiLAogICAgICAgICJFeHBhbmQiIDogIu2ZleyepSIsCiAgICAgICAgIkNvbGxhcHNlIiA6ICLstpXshowiLAogICAgICAgICJMaXN0IFR5cGUiIDogIuuqqeuhnSDsnKDtmJUiLAogICAgICAgICJVUkwiIDogIlVSTCIsCiAgICAgICAgIkFsdCBUZXh0IiA6ICJBbHQg7IaN7ISxIiwKICAgICAgICAiT3BlbiBpbiBuZXcgcGFnZSIgOiAi7IOIIO2OmOydtOyngOyXkOyEnCDsl7TquLAiCiAgICB9Owp9KShGb3JtLnJ0ZS5JMThuKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDI0LzEwLzIwMTYuCiAqLwoKKGZ1bmN0aW9uIChJMThuKSB7CgogICAgdmFyIHB0QlIgPSBJMThuLnB0QlIgPSB7fTsKCiAgICBwdEJSLnN0cmluZ3MgPSB7CiAgICAgICAgIlVuZG8iIDogIkRlc2ZhemVyIiwKICAgICAgICAiUmVkbyIgOiAiUmVmYXplciIsCiAgICAgICAgIkJvbGQiIDogIk5lZ3JpdG8iLAogICAgICAgICJJdGFsaWMiIDogIkl0w6FsaWNvIiwKICAgICAgICAiVW5kZXJsaW5lIiA6ICJTdWJsaW5oYWRvIiwKICAgICAgICAiU3VwZXItc2NyaXB0IiA6ICJTb2JyZXNjcml0byIsCiAgICAgICAgIlN1Yi1zY3JpcHQiIDogIlN1YnNjcml0byIsCiAgICAgICAgIlRleHQgQ29sb3IiIDogIkNvciBkbyB0ZXh0byIsCiAgICAgICAgIkhpZ2hsaWdodCBDb2xvciIgOiAiQ29yIGRlIHJlYWxjZSIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICJGYW3DrWxpYSBkZSBmb250ZXMiLAogICAgICAgICJGb250IFNpemUiIDogIlRhbWFuaG8gZGEgZm9udGUiLAogICAgICAgICJMaW5lIEhlaWdodCIgOiAiQWx0dXJhIGRhIGxpbmhhIiwKICAgICAgICAiTGV0dGVyIFNwYWNpbmciIDogIkVzcGHDp2FtZW50byBlbnRyZSBMZXRyYXMiLAogICAgICAgICJQYXJhZ3JhcGggRm9ybWF0IiA6ICJGb3JtYXRvIGRlIHBhcsOhZ3JhZm8iLAogICAgICAgICJKdXN0aWZ5IExlZnQiIDogIkp1c3RpZmljYXIgw6AgZXNxdWVyZGEiLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAiSnVzdGlmaWNhciBubyBjZW50cm8iLAogICAgICAgICJKdXN0aWZ5IEZ1bGwiIDogIkp1c3RpZmljYXIgdHVkbyIsCiAgICAgICAgIkp1c3RpZnkgUmlnaHQiIDogIkp1c3RpZmljYXIgw6AgZGlyZWl0YSIsCiAgICAgICAgIk1hcmdpbiBMZWZ0IiA6ICJNYXJnZW0gZXNxdWVyZGEiLAogICAgICAgICJNYXJnaW4gUmlnaHQiIDogIk1hcmdlbSBkaXJlaXRhIiwKICAgICAgICAiTWFyZ2luIFRvcCIgOiAiTWFyZ2VtIHN1cGVyaW9yIiwKICAgICAgICAiTWFyZ2luIEJvdHRvbSIgOiAiTWFyZ2VtIGluZmVyaW9yIiwKICAgICAgICAiQnVsbGV0ZWQgTGlzdCIgOiAiTGlzdGEgY29tIG1hcmNhZG9yZXMiLAogICAgICAgICJOdW1iZXJlZCBMaXN0IiA6ICJMaXN0YSBudW1lcmFkYSIsCiAgICAgICAgIlVwcGVyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAiTGlzdGEgYWxmYWLDqXRpY2EgZW0gbWFpw7pzY3VsYXMiLAogICAgICAgICJMb3dlci1jYXNlIEFscGhhYmV0IExpc3QiIDogIkxpc3RhIGFsZmFiw6l0aWNhIGVtIG1pbsO6c2N1bGFzIiwKICAgICAgICAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiA6ICJMaXN0YSBkZSBhbGdhcmlzbW9zIHJvbWFub3MgbWFpw7pzY3Vsb3MiLAogICAgICAgICJMb3dlci1jYXNlIFJvbWFuIExpc3QiIDogIkFsZ2FyaXNtb3MgUm9tYW5vcyBNaW7DunNjdWxvcyIsCiAgICAgICAgIkluZGVudCIgOiAiUmVjdW8iLAogICAgICAgICJPdXRkZW50IiA6ICJSZWN1byBwYXJhIGEgZXNxdWVyZGEiLAogICAgICAgICJGaW5kICYgUmVwbGFjZSIgOiAiTG9jYWxpemFyIGUgc3Vic3RpdHVpciIsCiAgICAgICAgIkluc2VydCBMaW5rIiA6ICJJbnNlcmlyIGxpbmsiLAogICAgICAgICJGaW5kIiA6ICJMb2NhbGl6YXIiLAogICAgICAgICJSZXBsYWNlIiA6ICJTdWJzdGl0dWlyIiwKICAgICAgICAiUmVwbGFjZSBhbGwiIDogIlN1YnN0aXR1aXIgdHVkbyIsCiAgICAgICAgIk1hdGNoIGNhc2UiIDogIkRpZmVyZW5jaWFyIG1hacO6c2N1bGFzIGRlIG1pbsO6c2N1bGFzIiwKICAgICAgICAiV2hvbGUgd29yZCIgOiAiUGFsYXZyYSBpbnRlaXJhIiwKICAgICAgICAiUmVnIEV4IiA6ICJSZWcgRXgiLAogICAgICAgICJJbmZvIiA6ICJJbmZvcm1hw6fDtWVzIiwKICAgICAgICAiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIgOiAiQXRpbmdpdSBvIGZpbSBkbyBtw7NkdWxvLiIsCiAgICAgICAgIk1hdGNoIE5vdCBGb3VuZCIgOiAiQ29ycmVzcG9uZMOqbmNpYSBuw6NvIGVuY29udHJhZGEiLAogICAgICAgICJ7MH0gbWF0Y2hlcyByZXBsYWNlZCIgOiAiezB9IGNvcnJlc3BvbmTDqm5jaWFzIHN1YnN0aXR1w61kYXMiLAogICAgICAgICJUaW1lcyBOZXcgUm9tYW4iIDogIlRpbWVzIE5ldyBSb21hbiIsCiAgICAgICAgIkFyaWFsIiA6ICJBcmlhbCIsCiAgICAgICAgIkNvdXJpZXIiIDogIkNvdXJpZXIiLAogICAgICAgICJDb3VyaWVyIE5ldyIgOiAiQ291cmllciBOZXciLAogICAgICAgICJHZW5ldmEiIDogIkdlbmVicmEiLAogICAgICAgICJHZW9yZ2lhIiA6ICJHZcOzcmdpYSIsCiAgICAgICAgIkhlbHZldGljYSIgOiAiSGVsdmV0aWNhIiwKICAgICAgICAiVGFob21hIiA6ICJUYWhvbWEiLAogICAgICAgICJUaW1lcyIgOiAiVGltZXMiLAogICAgICAgICJWZXJkYW5hIiA6ICJWZXJkYW5hIiwKICAgICAgICAiTm9uZSIgOiAiTmVuaHVtIiwKICAgICAgICAiSGVhZGVyIDEiIDogIkNhYmXDp2FsaG8gMSIsCiAgICAgICAgIkhlYWRlciAyIiA6ICJDYWJlw6dhbGhvIDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAiQ2FiZcOnYWxobyAzIiwKICAgICAgICAiSGVhZGVyIDQiIDogIkNhYmXDp2FsaG8gNCIsCiAgICAgICAgIkhlYWRlciA1IiA6ICJDYWJlw6dhbGhvIDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAiQ2FiZcOnYWxobyA2IiwKICAgICAgICAiU2VsZWN0IiA6ICJTZWxlY2lvbmFyIiwKICAgICAgICAiQmFzaWMgVmlldyIgOiAiRXhpYmnDp8OjbyBiw6FzaWNhIiwKICAgICAgICAiRnVsbFNjcmVlbiIgOiAiVGVsYSBpbnRlaXJhIiwKICAgICAgICAiRXhwYW5kIiA6ICJFeHBhbmRpciIsCiAgICAgICAgIkNvbGxhcHNlIiA6ICJDb250cmFpciIsCiAgICAgICAgIkxpc3QgVHlwZSIgOiAiVGlwbyBkZSBsaXN0YSIsCiAgICAgICAgIlVSTCIgOiAiVVJMIiwKICAgICAgICAiQWx0IFRleHQiIDogIlRleHRvIGFsdGVybmF0aXZvIiwKICAgICAgICAiT3BlbiBpbiBuZXcgcGFnZSIgOiAiQWJyaXIgZW0gbm92YSBww6FnaW5hIgogICAgfTsKfSkoRm9ybS5ydGUuSTE4bik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiAyNC8xMC8yMDE2LgogKi8KCihmdW5jdGlvbiAoSTE4bikgewoKICAgIHZhciB6aENOID0gSTE4bi56aENOID0ge307CgogICAgemhDTi5zdHJpbmdzID0gewogICAgICAgICJVbmRvIiA6ICLmkqTmtogiLAogICAgICAgICJSZWRvIiA6ICLmgaLlpI0iLAogICAgICAgICJCb2xkIiA6ICLnspfkvZMiLAogICAgICAgICJJdGFsaWMiIDogIuaWnOS9kyIsCiAgICAgICAgIlVuZGVybGluZSIgOiAi5LiL5YiS57q/IiwKICAgICAgICAiU3VwZXItc2NyaXB0IiA6ICLkuIrmoIciLAogICAgICAgICJTdWItc2NyaXB0IiA6ICLkuIvmoIciLAogICAgICAgICJUZXh0IENvbG9yIiA6ICLmlofmnKzpopzoibIiLAogICAgICAgICJIaWdobGlnaHQgQ29sb3IiIDogIueqgeWHuuaYvuekuuminOiJsiIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICLlrZfkvZPns7vliJciLAogICAgICAgICJGb250IFNpemUiIDogIuWtl+S9k+Wkp+WwjyIsCiAgICAgICAgIkxpbmUgSGVpZ2h0IiA6ICLooYzpq5giLAogICAgICAgICJMZXR0ZXIgU3BhY2luZyIgOiAi5a2X5q+N6Ze06LedIiwKICAgICAgICAiUGFyYWdyYXBoIEZvcm1hdCIgOiAi5q616JC95qC85byPIiwKICAgICAgICAiSnVzdGlmeSBMZWZ0IiA6ICLlt6blr7npvZAiLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAi5bGF5Lit5a+56b2QIiwKICAgICAgICAiSnVzdGlmeSBGdWxsIiA6ICLlhajpg6jkuKTnq6/lr7npvZAiLAogICAgICAgICJKdXN0aWZ5IFJpZ2h0IiA6ICLlj7Plr7npvZAiLAogICAgICAgICJNYXJnaW4gTGVmdCIgOiAi5bem6L656LedIiwKICAgICAgICAiTWFyZ2luIFJpZ2h0IiA6ICLlj7Povrnot50iLAogICAgICAgICJNYXJnaW4gVG9wIiA6ICLkuIrovrnot50iLAogICAgICAgICJNYXJnaW4gQm90dG9tIiA6ICLkuIvovrnot50iLAogICAgICAgICJCdWxsZXRlZCBMaXN0IiA6ICLpobnnm67nrKblj7fliJfooagiLAogICAgICAgICJOdW1iZXJlZCBMaXN0IiA6ICLnvJblj7fliJfooagiLAogICAgICAgICJVcHBlci1jYXNlIEFscGhhYmV0IExpc3QiIDogIuWkp+WGmeWtl+avjeWIl+ihqCIsCiAgICAgICAgIkxvd2VyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAi5bCP5YaZ5a2X5q+N5YiX6KGoIiwKICAgICAgICAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiA6ICLlpKflhpnnvZfpqazlrZfmr43liJfooagiLAogICAgICAgICJMb3dlci1jYXNlIFJvbWFuIExpc3QiIDogIuWwj+WGmee9l+mprOWtl+avjeWIl+ihqCIsCiAgICAgICAgIkluZGVudCIgOiAi57yp6L+bIiwKICAgICAgICAiT3V0ZGVudCIgOiAi5Y2H57qnIiwKICAgICAgICAiRmluZCAmIFJlcGxhY2UiIDogIuafpeaJvuWSjOabv+aNoiIsCiAgICAgICAgIkluc2VydCBMaW5rIiA6ICLmj5LlhaXpk77mjqUiLAogICAgICAgICJGaW5kIiA6ICLmn6Xmib4iLAogICAgICAgICJSZXBsYWNlIiA6ICLmm7/mjaIiLAogICAgICAgICJSZXBsYWNlIGFsbCIgOiAi5YWo6YOo5pu/5o2iIiwKICAgICAgICAiTWF0Y2ggY2FzZSIgOiAi5Yy65YiG5aSn5bCP5YaZIiwKICAgICAgICAiV2hvbGUgd29yZCIgOiAi5YWo5a2XIiwKICAgICAgICAiUmVnIEV4IiA6ICLmraPliJnooajovr7lvI8iLAogICAgICAgICJJbmZvIiA6ICLkv6Hmga8iLAogICAgICAgICJSZWFjaGVkIGVuZCBvZiBtb2R1bGUuIiA6ICLlt7LliLDmqKHlnZfmnKvlsL7jgIIiLAogICAgICAgICJNYXRjaCBOb3QgRm91bmQiIDogIuacquaJvuWIsOWMuemFjemhuSIsCiAgICAgICAgInswfSBtYXRjaGVzIHJlcGxhY2VkIiA6ICJ7MH0g5Liq5Yy56YWN6aG55bey5pu/5o2iIiwKICAgICAgICAiVGltZXMgTmV3IFJvbWFuIiA6ICJUaW1lcyBOZXcgUm9tYW4iLAogICAgICAgICJBcmlhbCIgOiAiQXJpYWwiLAogICAgICAgICJDb3VyaWVyIiA6ICJDb3VyaWVyIiwKICAgICAgICAiQ291cmllciBOZXciIDogIkNvdXJpZXIgTmV3IiwKICAgICAgICAiR2VuZXZhIiA6ICJHZW5ldmEiLAogICAgICAgICJHZW9yZ2lhIiA6ICJHZW9yZ2lhIiwKICAgICAgICAiSGVsdmV0aWNhIiA6ICJIZWx2ZXRpY2EiLAogICAgICAgICJUYWhvbWEiIDogIlRhaG9tYSIsCiAgICAgICAgIlRpbWVzIiA6ICJUaW1lcyIsCiAgICAgICAgIlZlcmRhbmEiIDogIlZlcmRhbmEiLAogICAgICAgICJOb25lIiA6ICLml6AiLAogICAgICAgICJIZWFkZXIgMSIgOiAi5qCH6aKYIDEiLAogICAgICAgICJIZWFkZXIgMiIgOiAi5qCH6aKYIDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAi5qCH6aKYIDMiLAogICAgICAgICJIZWFkZXIgNCIgOiAi5qCH6aKYIDQiLAogICAgICAgICJIZWFkZXIgNSIgOiAi5qCH6aKYIDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAi5qCH6aKYIDYiLAogICAgICAgICJTZWxlY3QiIDogIumAieaLqSIsCiAgICAgICAgIkJhc2ljIFZpZXciIDogIuWfuuacrOinhuWbviIsCiAgICAgICAgIkZ1bGxTY3JlZW4iIDogIuWFqOWxjyIsCiAgICAgICAgIkV4cGFuZCIgOiAi5bGV5byAIiwKICAgICAgICAiQ29sbGFwc2UiIDogIuaKmOWPoCIsCiAgICAgICAgIkxpc3QgVHlwZSIgOiAi5YiX6KGo57G75Z6LIiwKICAgICAgICAiVVJMIiA6ICJVUkwiLAogICAgICAgICJBbHQgVGV4dCIgOiAi5YiH5o2i5paH5pysIiwKICAgICAgICAiT3BlbiBpbiBuZXcgcGFnZSIgOiAi5Zyo5paw6aG16Z2i5Lit5omT5byAIgogICAgfTsKfSkoRm9ybS5ydGUuSTE4bik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiAyNC8xMC8yMDE2LgogKi8KCihmdW5jdGlvbiAoSTE4bikgewoKICAgIHZhciB6aFRXID0gSTE4bi56aFRXID0ge307CgogICAgemhUVy5zdHJpbmdzID0gewogICAgICAgICJVbmRvIiA6ICLlvqnljp8iLAogICAgICAgICJSZWRvIiA6ICLph43lgZoiLAogICAgICAgICJCb2xkIiA6ICLnspfpq5QiLAogICAgICAgICJJdGFsaWMiIDogIuaWnOmrlCIsCiAgICAgICAgIlVuZGVybGluZSIgOiAi5bqV57eaIiwKICAgICAgICAiU3VwZXItc2NyaXB0IiA6ICLkuIrmqJkiLAogICAgICAgICJTdWItc2NyaXB0IiA6ICLkuIvmqJkiLAogICAgICAgICJUZXh0IENvbG9yIiA6ICLmloflrZfoibLlvakiLAogICAgICAgICJIaWdobGlnaHQgQ29sb3IiIDogIuS6rumhr+mhj+iJsiIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICLlrZflnovns7vliJciLAogICAgICAgICJGb250IFNpemUiIDogIuWtl+Wei+Wkp+WwjyIsCiAgICAgICAgIkxpbmUgSGVpZ2h0IiA6ICLooYzpq5giLAogICAgICAgICJMZXR0ZXIgU3BhY2luZyIgOiAi5a2X5q+N6ZaT6ZqUIiwKICAgICAgICAiUGFyYWdyYXBoIEZvcm1hdCIgOiAi5q616JC95qC85byPIiwKICAgICAgICAiSnVzdGlmeSBMZWZ0IiA6ICLlkJHlt6blsI3pvYoiLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAi572u5Lit5bCN6b2KIiwKICAgICAgICAiSnVzdGlmeSBGdWxsIiA6ICLlt6blj7PlsI3pvYoiLAogICAgICAgICJKdXN0aWZ5IFJpZ2h0IiA6ICLlkJHlj7PlsI3pvYoiLAogICAgICAgICJNYXJnaW4gTGVmdCIgOiAi5bem6YKK6LedIiwKICAgICAgICAiTWFyZ2luIFJpZ2h0IiA6ICLlj7Ppgorot50iLAogICAgICAgICJNYXJnaW4gVG9wIiA6ICLkuIrpgorot50iLAogICAgICAgICJNYXJnaW4gQm90dG9tIiA6ICLkuIvpgorot50iLAogICAgICAgICJCdWxsZXRlZCBMaXN0IiA6ICLpoIXnm67nrKbomZ/muIXllq4iLAogICAgICAgICJOdW1iZXJlZCBMaXN0IiA6ICLnt6jomZ/muIXllq4iLAogICAgICAgICJVcHBlci1jYXNlIEFscGhhYmV0IExpc3QiIDogIuWkp+Wvq+Wtl+avjea4heWWriIsCiAgICAgICAgIkxvd2VyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAi5bCP5a+r5a2X5q+N5riF5ZauIiwKICAgICAgICAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiA6ICLlpKflr6sgUm9tYW4g5a2X5riF5ZauIiwKICAgICAgICAiTG93ZXItY2FzZSBSb21hbiBMaXN0IiA6ICLlsI/lr6sgUm9tYW4g5riF5ZauIiwKICAgICAgICAiSW5kZW50IiA6ICLnuK7mjpIiLAogICAgICAgICJPdXRkZW50IiA6ICLlh7jmjpIiLAogICAgICAgICJGaW5kICYgUmVwbGFjZSIgOiAi5bCL5om+5ZKM5Y+W5LujIiwKICAgICAgICAiSW5zZXJ0IExpbmsiIDogIuaPkuWFpemAo+e1kCIsCiAgICAgICAgIkZpbmQiIDogIuWwi+aJviIsCiAgICAgICAgIlJlcGxhY2UiIDogIuabv+aPmyIsCiAgICAgICAgIlJlcGxhY2UgYWxsIiA6ICLlhajpg6jlj5bku6MiLAogICAgICAgICJNYXRjaCBjYXNlIiA6ICLnrKblkIjlpKflsI/lr6siLAogICAgICAgICJXaG9sZSB3b3JkIiA6ICLlhajlrZciLAogICAgICAgICJSZWcgRXgiIDogIuimj+WJh+mBi+eul+W8jyIsCiAgICAgICAgIkluZm8iIDogIuizh+ioiiIsCiAgICAgICAgIlJlYWNoZWQgZW5kIG9mIG1vZHVsZS4iIDogIuWIsOmBlOaooee1hOe1gum7nuOAgiIsCiAgICAgICAgIk1hdGNoIE5vdCBGb3VuZCIgOiAi5om+5LiN5Yiw55u456ym55qEIiwKICAgICAgICAiezB9IG1hdGNoZXMgcmVwbGFjZWQiIDogIuWPluS7o3swfeespuWQiOeahOmgheebriIsCiAgICAgICAgIlRpbWVzIE5ldyBSb21hbiIgOiAiVGltZXMgTmV3IFJvbWFuIiwKICAgICAgICAiQXJpYWwiIDogIkFyaWFsIiwKICAgICAgICAiQ291cmllciIgOiAiQ291cmllciIsCiAgICAgICAgIkNvdXJpZXIgTmV3IiA6ICJDb3VyaWVyIE5ldyIsCiAgICAgICAgIkdlbmV2YSIgOiAiR2VuZXZhIiwKICAgICAgICAiR2VvcmdpYSIgOiAiR2VvcmdpYSIsCiAgICAgICAgIkhlbHZldGljYSIgOiAiSGVsdmV0aWNhIiwKICAgICAgICAiVGFob21hIiA6ICJUYWhvbWEiLAogICAgICAgICJUaW1lcyIgOiAiVGltZXMiLAogICAgICAgICJWZXJkYW5hIiA6ICJWZXJkYW5hIiwKICAgICAgICAiTm9uZSIgOiAi54ShIiwKICAgICAgICAiSGVhZGVyIDEiIDogIumggemmliAxIiwKICAgICAgICAiSGVhZGVyIDIiIDogIumggemmliAyIiwKICAgICAgICAiSGVhZGVyIDMiIDogIumggemmliAzIiwKICAgICAgICAiSGVhZGVyIDQiIDogIumggemmliA0IiwKICAgICAgICAiSGVhZGVyIDUiIDogIumggemmliA1IiwKICAgICAgICAiSGVhZGVyIDYiIDogIumggemmliA2IiwKICAgICAgICAiU2VsZWN0IiA6ICLpgbjlj5YiLAogICAgICAgICJCYXNpYyBWaWV3IiA6ICLln7rmnKzmqqLoppYiLAogICAgICAgICJGdWxsU2NyZWVuIiA6ICLlhajonqLluZUiLAogICAgICAgICJFeHBhbmQiIDogIuWxlemWiyIsCiAgICAgICAgIkNvbGxhcHNlIiA6ICLmlLbnuK4iLAogICAgICAgICJMaXN0IFR5cGUiIDogIuWIl+ihqOmhnuWeiyIsCiAgICAgICAgIlVSTCIgOiAi57ay5Z2AIiwKICAgICAgICAiQWx0IFRleHQiIDogIuabv+S7o+aWh+WtlyIsCiAgICAgICAgIk9wZW4gaW4gbmV3IHBhZ2UiIDogIuWcqOaWsOeahOmggemdouS4remWi+WVnyIKICAgIH07Cn0pKEZvcm0ucnRlLkkxOG4pOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTYuIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKgogKiBDcmVhdGVkIGJ5IHJhbW5hbmkgb24gNy8yOC8yMDE2LgogKi8KCndpbmRvdy5Gb3JtID0gd2luZG93LkZvcm0gfHwge307CgpGb3JtLnJ0ZSA9IEZvcm0ucnRlIHx8IHt9OwoKRm9ybS5ydGUudXRpbCA9IEZvcm0ucnRlLnV0aWwgfHwge307CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiA4LzEvMjAxNi4KICovCihmdW5jdGlvbiAobnMpIHsKCiAgICB2YXIgUlRFVXRpbHMgPSBucy5SVEVVdGlscyA9IHt9OwoKICAgIFJURVV0aWxzLmlzSUUgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHVhID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7CiAgICAgICAgdmFyIG1zaWUgPSB1YS5pbmRleE9mKCdNU0lFICcpOwogICAgICAgIGlmIChtc2llID4gMCkgewogICAgICAgICAgICAvLyBJRSAxMCBvciBvbGRlciA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXIKICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KHVhLnN1YnN0cmluZyhtc2llICsgNSwgdWEuaW5kZXhPZignLicsIG1zaWUpKSwgMTApOwogICAgICAgIH0KICAgICAgICB2YXIgdHJpZGVudCA9IHVhLmluZGV4T2YoJ1RyaWRlbnQvJyk7CiAgICAgICAgaWYgKHRyaWRlbnQgPiAwKSB7CiAgICAgICAgICAgIC8vIElFIDExID0+IHJldHVybiB2ZXJzaW9uIG51bWJlcgogICAgICAgICAgICB2YXIgcnYgPSB1YS5pbmRleE9mKCdydjonKTsKICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KHVhLnN1YnN0cmluZyhydiArIDMsIHVhLmluZGV4T2YoJy4nLCBydikpLCAxMCk7CiAgICAgICAgfQogICAgICAgIHZhciBlZGdlID0gdWEuaW5kZXhPZignRWRnZS8nKTsKICAgICAgICBpZiAoZWRnZSA+IDApIHsKICAgICAgICAgICAgLy8gSUUgMTIgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyCiAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh1YS5zdWJzdHJpbmcoZWRnZSArIDUsIHVhLmluZGV4T2YoJy4nLCBlZGdlKSksIDEwKTsKICAgICAgICB9CiAgICAgICAgLy8gb3RoZXIgYnJvd3NlcgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CiAgICBSVEVVdGlscy5hZGRTcGVjdHJ1bUdyYWRpZW50ID0gZnVuY3Rpb24gKHNlbGVjdG9yLCBjb2xvclZhbHVlKSB7CiAgICAgICAgaWYgKHNlbGVjdG9yKSB7CiAgICAgICAgICAgICQoc2VsZWN0b3IpLmNzcyh7ImJhY2tncm91bmQtaW1hZ2UiIDogIi13ZWJraXQtZ3JhZGllbnQobGluZWFyLCBsZWZ0IHRvcCwgcmlnaHQgdG9wLCBjb2xvci1zdG9wKDAsICNmZmYpLCBjb2xvci1zdG9wKC41LCAjIiArIGNvbG9yVmFsdWUgKyAiKSwgY29sb3Itc3RvcCgxLCAjMDAwKSkifSk7CiAgICAgICAgICAgICQoc2VsZWN0b3IpLmNzcyh7ImJhY2tncm91bmQtaW1hZ2UiIDogIi1tb3otbGluZWFyLWdyYWRpZW50KGxlZnQgY2VudGVyLCAjZmZmIDAsICMiICsgY29sb3JWYWx1ZSArICIgNTAlLCAjMDAwIDEwMCUpIn0pOwogICAgICAgICAgICAkKHNlbGVjdG9yKS5jc3MoeyJiYWNrZ3JvdW5kLWltYWdlIiA6ICItd2Via2l0LWxpbmVhci1ncmFkaWVudChsZWZ0LCAjZmZmIDAsICMiICsgY29sb3JWYWx1ZSArICIgNTAlLCAjMDAwIDEwMCUpIn0pOwogICAgICAgICAgICAkKHNlbGVjdG9yKS5jc3MoeyJiYWNrZ3JvdW5kLWltYWdlIiA6ICItby1saW5lYXItZ3JhZGllbnQobGVmdCwgI2ZmZiAwLCAjIiArIGNvbG9yVmFsdWUgKyAiIDUwJSwgIzAwMCAxMDAlKSJ9KTsKICAgICAgICAgICAgJChzZWxlY3RvcikuY3NzKHsiYmFja2dyb3VuZC1pbWFnZSIgOiAibGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCAjZmZmIDAsICMiICsgY29sb3JWYWx1ZSArICIgNTAlLCAjMDAwIDEwMCUpIn0pOwogICAgICAgICAgICAkKHNlbGVjdG9yKS5jc3MoeyJiYWNrZ3JvdW5kLXJlcGVhdCIgOiAicmVwZWF0LXgifSk7CiAgICAgICAgfQogICAgfTsKCn0pKEZvcm0ucnRlLnV0aWwpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTYuIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgooZnVuY3Rpb24gKG5zKSB7CiAgICB2YXIgU3RyaW5nSGVscGVyID0gbnMuU3RyaW5nSGVscGVyID0ge307CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGFueSBsZWFkaW5nIGFuZCB0cmFpbGluZyBzbGFzaGVzLCBlaXRoZXIgJy8nIG9yICdcJywgb24gdGhlIHNwZWNpZmllZCBzdHJpbmcuCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cmluZyBmcm9tIHdoaWNoIHNsYXNoZXMgYXJlIHRvIGJlIHRyaW1tZWQuCiAgICAgKiBAcmV0dXJuIFRoZSBvcmlnaW5hbCBzdHJpbmcgbGVzcyBhbnkgdHJhaWxpbmcgc2xhc2hlcy4KICAgICAqLwogICAgU3RyaW5nSGVscGVyLnRyaW1TbGFzaGVzID0gZnVuY3Rpb24gKHZhbHVlKSB7CgogICAgICAgIGlmICghdmFsdWUpIHsvLyBpZiBudWxsIG9yIGVtcHR5CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9CgogICAgICAgIHZhciBsZW4gPSB2YWx1ZS5sZW5ndGg7CgogICAgICAgIC8vIHJlbW92ZSBsZWFkaW5nIHNsYXNoZXMKICAgICAgICB2YXIgc3RhcnQgPSAwOyAvLyBtdXN0IGJlIGluZGV4IG9mIGZpcnN0IGNoYXJhY3RlciB0byBpbmNsdWRlCiAgICAgICAgdmFyIGMgPSB2YWx1ZS5jaGFyQXQoc3RhcnQpOwogICAgICAgIHdoaWxlIChjID09ICcvJyB8fCBjID09ICdcXCcpIHsKICAgICAgICAgICAgc3RhcnQrKzsKICAgICAgICAgICAgaWYgKHN0YXJ0ID49IGxlbikgewogICAgICAgICAgICAgICAgc3RhcnQgPSBsZW47CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjID0gdmFsdWUuY2hhckF0KHN0YXJ0KTsKICAgICAgICB9CiAgICAgICAgaWYgKHN0YXJ0ID49IGxlbikgey8vIGFsbCBzbGFzaGVzCiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9CgogICAgICAgIC8vIGF0IHRoaXMgcG9pbnQsIHRoZXJlJ3MgYXQgbGVhc3Qgb25lIGNoYXJhY3RlciB3ZSB3YW50IHRvIHJldGFpbgoKICAgICAgICAvLyByZW1vdmUgdHJhaWxpbmcgc2xhc2hlcwogICAgICAgIHZhciBlbmQgPSBsZW47IC8vIG11c3QgYmUgMSBtb3JlIHRoYW4gdGhlIGxhc3QgY2hhcmFjdGVyIHdlIHdhbnQgdG8gaW5jbHVkZQogICAgICAgIGMgPSB2YWx1ZS5jaGFyQXQoZW5kIC0gMSk7CiAgICAgICAgd2hpbGUgKGMgPT0gJy8nIHx8IGMgPT0gJ1xcJykgewogICAgICAgICAgICBlbmQtLTsKICAgICAgICAgICAgaWYgKGVuZCA8IDApIHsKICAgICAgICAgICAgICAgIGVuZCA9IDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYyA9IHZhbHVlLmNoYXJBdChlbmQgLSAxKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlLnN1YnN0cmluZyhzdGFydCwgZW5kKTsKICAgIH07CiAgICBTdHJpbmdIZWxwZXIucmVwZWF0ID0gZnVuY3Rpb24gKGMsIGNvdW50KSB7CiAgICAgICAgdmFyIHMgPSAiIjsKICAgICAgICBpZiAoYyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0KCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CiAgICAgICAgICAgIHMgKz0gYzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICB9OwogICAgLyoqCiAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGhhcyB0aGUgc3BlY2lmaWVkIHBvc3RmaXguCiAgICAgKiBAcGFyYW0gc3RyIFRoZSBzdHJpbmcgdG8gYmUgdmVyaWZpZWQuCiAgICAgKiBAcGFyYW0gcG9zdEZpeCBUaGUgcG9zdGZpeCB0byBzZWFyY2ggZm9yLgogICAgICogQHJldHVybiBUcnVlIGlmIHN0ciBoYXMgdGhlIHBvc3RmaXggc3BlY2lmaWVkOyB0cnVlIGlmIHBvc3RmaXggaXMgbnVsbC9lbXB0eSBzaW5jZSBhbnkgbm9uLW51bGwgc3RyaW5nIGNhbiBoYXZlIGFuIGVtcHR5IHBvc3RmaXg7CiAgICAgKiAgZmFsc2UgaWYgc3RyIGlzIG51bGwgb3IgZG9lcyBub3QgaGF2ZSB0aGUgc3BlY2lmaWVkIHBvc3RmaXguCiAgICAgKi8KICAgIFN0cmluZ0hlbHBlci5oYXNQb3N0Rml4ID0gZnVuY3Rpb24gKHN0ciwgcG9zdEZpeCkgewogICAgICAgIGlmIChzdHIgPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoIXBvc3RGaXgpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSAvLyBhbnkgc3RyaW5nIGhhcyBhbiBlbXB0eSBwb3N0Zml4IQogICAgICAgIHJldHVybiAoc3RyLmluZGV4T2YocG9zdEZpeCkgPT0gKHN0ci5sZW5ndGggLSBwb3N0Rml4Lmxlbmd0aCkpOwogICAgfTsKCiAgICAvKioKICAgICAqIFRlc3RzIHRoZSBzdHJpbmcgdG8gc2VlIGlmIGl0IG9ubHkgY29udGFpbnMgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzLiBUaGlzIGlzIHNsaWdodGx5IGRpZmZlcmVudCBmcm9tCiAgICAgKiAgPGNvZGU+U3RyaW5nVXRpbC5pc1doaXRlc3BhY2UoKTwvY29kZT4gaW4gdGhhdCBpdCB0ZXN0cyBhbGwgY2hhcmFjdGVycywgbm90IGp1c3Qgb25lLgogICAgICogQHBhcmFtIHN0ciBUaGUgc3RyaW5nIHRvIHRlc3QuCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHN0ciBpcyBtYWRlLXVwIGVudGlyZWx5IG9mIHdoaXRlc3BhY2U7IGZhbHNlIGlmIG5vdC4gTnVsbCBzdHJpbmdzIHdpbGwgcmVzdWx0IGluIHRydWUuCiAgICAgKi8KICAgIFN0cmluZ0hlbHBlci5pc1doaXRlc3BhY2UgPSBmdW5jdGlvbiAoc3RyKSB7CiAgICAgICAgaWYgKHN0ciA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RyLm1hdGNoKC9bXlxzXSsvZykgPT0gbnVsbDsgLy8gbWF0Y2hlcyBhdCBsZWFzdCBvbmUgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyIHNvIGlmIHRoZXJlJ3Mgbm8gbWF0Y2gsIGl0J3MgZW50aXJlbHkgd2hpdGVzcGFjZQogICAgfTsKCiAgICAvKioKICAgICAqIFN0cmV0Y2hlcyB0aGUgc3BlY2lmaWVkIHN0cmluZyB0byB0aGUgc3BlY2lmaWVkIGxlbmd0aCB1c2luZyB0aGUgc3BlY2lmaWVkIHBhZCBjaGFyYWN0ZXIuCiAgICAgKiBAcGFyYW0gc3RyIFRoZSBzdHJpbmcgdG8gc3RyZXRjaC4KICAgICAqIEBwYXJhbSBwYWQgVGhlIChzaW5nbGUpIGNoYXJhY3RlciB0byB1c2Ugd2hlbiBzdHJldGNoaW5nLgogICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbGVuZ3RoIHRvIHN0cmV0Y2ggdG8uCiAgICAgKiBAcGFyYW0gcHJlZml4IFRydWUgaWYgdGhlIHBhZCBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIGxlZnQgKGJlZm9yZSB0aGUgY29udGVudHMgb2YgdGhlIHN0cmluZyk7IGZhbHNlIGlmIGl0IHNob3VsZCBiZSBhcHBlbmRlZAogICAgICogIHRvIHRoZSBlbmQgb2YgdGhlIGNvbnRlbnRzIG9mIHRoZSBzdHJpbmcuCiAgICAgKiBAcmV0dXJuIFRoZSBzdHJldGNoZWQgc3RyaW5nLiBJZiA8Y29kZT5zdHI8L2NvZGU+IGlzIG51bGwgb3IgZW1wdHksIGl0IHNpbXBseSBiZWNvbWVzIGEgc3RyaW5nIG9mIDxjb2RlPnBhZDwvY29kZT4gY2hhcmFjdGVycwogICAgICogIG9mIHRoZSBzcGVjaWZpZWQgPGNvZGU+bGVuZ3RoPC9jb2RlPi4KICAgICAqIEB0aHJvd3MgRXJyb3IgUGFkIG11c3QgYmUgYSBzaW5nbGUgY2hhcmFjdGVyLgogICAgICovCiAgICBTdHJpbmdIZWxwZXIuc3RyZXRjaCA9IGZ1bmN0aW9uIChzdHIsIHBhZCwgbGVuZ3RoLCBwcmVmaXgpIHsKICAgICAgICBpZiAoIXBhZCB8fCBsZW5ndGggPD0gMCkgewogICAgICAgICAgICByZXR1cm4gc3RyOwogICAgICAgIH0KCiAgICAgICAgaWYgKHBhZC5sZW5ndGggIT0gMSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoInBhZCBtdXN0IGJlIGEgc2luZ2xlIGNoYXJhY3RlcjogIiArIHBhZCk7CiAgICAgICAgfSAvLyBhc3NlcnQKICAgICAgICB2YXIgaSA9IDA7CiAgICAgICAgaWYgKHN0ciA9PSBudWxsKSB7CiAgICAgICAgICAgIHN0ciA9ICIiOwogICAgICAgICAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICBzdHIgKz0gcGFkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzdHI7CiAgICAgICAgfQogICAgICAgIGlmIChzdHIubGVuZ3RoID49IGxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gc3RyOwogICAgICAgIH0KICAgICAgICB2YXIgY291bnQgPSBsZW5ndGggLSBzdHIubGVuZ3RoOwogICAgICAgIGZvciAoOyBpIDwgY291bnQ7IGkrKykgewogICAgICAgICAgICBpZiAocHJlZml4KSB7CiAgICAgICAgICAgICAgICBzdHIgPSBwYWQgKyBzdHI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzdHIgPSBzdHIgKyBwYWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cjsKICAgIH07CgogICAgLyoqCiAgICAgKiBSZXBsYWNlcyB0aGUgYWxsIHRoZSBvY2N1cmFuY2Ugb2YgdGFyZ2V0IHN0cmluZyB3aXRoIHJlcGxhY2VtZW50IHN0cmluZyBmb3IgYSBnaXZlbiBpbnB1dCBzdHJpbmcKICAgICAqIEBwYXJhbSBpbnB1dFN0cmluZyBUaGUgSW5wdXQgU3RyaW5nCiAgICAgKiBAcGFyYW0gdGFyZ2V0CiAgICAgKiBAcGFyYW0gcmVwbGFjZW1lbnQKICAgICAqIEByZXR1cm4KICAgICAqCiAgICAgKi8KICAgIFN0cmluZ0hlbHBlci5yZXBsYWNlQWxsID0gZnVuY3Rpb24gKGlucHV0U3RyaW5nLCB0YXJnZXQsIHJlcGxhY2VtZW50KSB7CiAgICAgICAgaWYgKGlucHV0U3RyaW5nID09IG51bGwgfHwgdGFyZ2V0ID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGlucHV0U3RyaW5nOwogICAgICAgIH0KICAgICAgICB2YXIgZXNjYXBlZFRhcmdldCA9IFN0cmluZ0hlbHBlci5lc2NhcGVSZWdleENoYXJzKHRhcmdldCk7CiAgICAgICAgdmFyIHBhdHRlcm4gPSBuZXcgUmVnRXhwKGVzY2FwZWRUYXJnZXQsICJnIik7CiAgICAgICAgdmFyIG5ld1N0cmluZyA9IGlucHV0U3RyaW5nLnJlcGxhY2UocGF0dGVybiwgcmVwbGFjZW1lbnQpOwogICAgICAgIHJldHVybiBuZXdTdHJpbmc7CiAgICB9OwoKICAgIFN0cmluZ0hlbHBlci5lc2NhcGVSZWdleENoYXJzID0gZnVuY3Rpb24gKHMpIHsKICAgICAgICB2YXIgbmV3U3RyaW5nID0gcy5yZXBsYWNlKG5ldyBSZWdFeHAoIihbe31cKFwpXF4kJi5cKlw/XC9cK1x8XFtcXFxcXXxcXXxcLSkiLCAiZyIpLCAiXFwkMSIpOwogICAgICAgIHJldHVybiBuZXdTdHJpbmc7CiAgICB9OwoKICAgIFN0cmluZ0hlbHBlci5yZXN0cmljdCA9IGZ1bmN0aW9uIChzdHIsIHJlc3RyaWN0KSB7CiAgICAgICAgLy8gQSBudWxsICdyZXN0cmljdCcgc3RyaW5nIG1lYW5zIGFsbCBjaGFyYWN0ZXJzIGFyZSBhbGxvd2VkLgogICAgICAgIGlmIChyZXN0cmljdCA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBzdHI7CiAgICAgICAgfQoKICAgICAgICAvLyBBbiBlbXB0eSAncmVzdHJpY3QnIHN0cmluZyBtZWFucyBubyBjaGFyYWN0ZXJzIGFyZSBhbGxvd2VkLgogICAgICAgIGlmIChyZXN0cmljdCA9PSAiIikgewogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQogICAgICAgIC8vIE90aGVyd2lzZSwgd2UgbmVlZCB0byB0ZXN0IGVhY2ggY2hhcmFjdGVyIGluICdzdHInCiAgICAgICAgLy8gdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlICdyZXN0cmljdCcgc3RyaW5nIGFsbG93cyBpdC4KICAgICAgICB2YXIgY2hhckNvZGVzID0gW107CgogICAgICAgIHZhciBuID0gc3RyLmxlbmd0aDsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG47IGkrKykgewogICAgICAgICAgICB2YXIgY2hhckNvZGUgPSBzdHIuY2hhckNvZGVBdChpKTsKICAgICAgICAgICAgaWYgKFN0cmluZ0hlbHBlci50ZXN0Q2hhcmFjdGVyKGNoYXJDb2RlLCByZXN0cmljdCkpIHsKICAgICAgICAgICAgICAgIGNoYXJDb2Rlcy5wdXNoKGNoYXJDb2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBjaGFyQ29kZXMpOwogICAgfTsKCiAgICBTdHJpbmdIZWxwZXIudGVzdENoYXJhY3RlciA9IGZ1bmN0aW9uIChjaGFyQ29kZSwgcmVzdHJpY3QpIHsKICAgICAgICB2YXIgYWxsb3dJdCA9IGZhbHNlOwogICAgICAgIHZhciBpbkJhY2tTbGFzaCA9IGZhbHNlOwogICAgICAgIHZhciBpblJhbmdlID0gZmFsc2U7CiAgICAgICAgdmFyIHNldEZsYWcgPSB0cnVlOwogICAgICAgIHZhciBsYXN0Q29kZSA9IDA7CiAgICAgICAgdmFyIG4gPSByZXN0cmljdC5sZW5ndGg7CiAgICAgICAgdmFyIGNvZGU7CgogICAgICAgIGlmIChuID4gMCkgewogICAgICAgICAgICBjb2RlID0gcmVzdHJpY3QuY2hhckNvZGVBdCgwKTsKICAgICAgICAgICAgaWYgKGNvZGUgPT0gOTQpIHsvLyBjYXJldAogICAgICAgICAgICAgICAgYWxsb3dJdCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICAgICAgY29kZSA9IHJlc3RyaWN0LmNoYXJDb2RlQXQoaSk7CiAgICAgICAgICAgIHZhciBhY2NlcHRDb2RlID0gZmFsc2U7CiAgICAgICAgICAgIGlmICghaW5CYWNrU2xhc2gpIHsKICAgICAgICAgICAgICAgIGlmIChjb2RlID09IDQ1KSB7Ly8gaHlwaGVuCiAgICAgICAgICAgICAgICAgICAgaW5SYW5nZSA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvZGUgPT0gOTQpIHsvLyBjYXJldAogICAgICAgICAgICAgICAgICAgIHNldEZsYWcgPSAhc2V0RmxhZzsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY29kZSA9PSA5Mikgey8vIGJhY2tzbGFzaAogICAgICAgICAgICAgICAgICAgIGluQmFja1NsYXNoID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYWNjZXB0Q29kZSA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhY2NlcHRDb2RlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGluQmFja1NsYXNoID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGFjY2VwdENvZGUpIHsKICAgICAgICAgICAgICAgIGlmIChpblJhbmdlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RDb2RlIDw9IGNoYXJDb2RlICYmIGNoYXJDb2RlIDw9IGNvZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWxsb3dJdCA9IHNldEZsYWc7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGluUmFuZ2UgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBsYXN0Q29kZSA9IDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSBjb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93SXQgPSBzZXRGbGFnOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBsYXN0Q29kZSA9IGNvZGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFsbG93SXQ7CiAgICB9OwoKICAgIFN0cmluZ0hlbHBlci5lbmRzV2l0aCA9IGZ1bmN0aW9uIChzdHIsIHN1ZmZpeCkgewogICAgICAgIGlmIChzdHIgJiYgc3VmZml4ICYmIHN0ci5pbmRleE9mKHN1ZmZpeCwgc3RyLmxlbmd0aCAtIHN1ZmZpeC5sZW5ndGgpICE9PSAtMSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfTsKCiAgICBTdHJpbmdIZWxwZXIuc3RhcnRzV2l0aCA9IGZ1bmN0aW9uIChzdHIsIHByZWZpeCkgewogICAgICAgIGlmIChzdHIgJiYgcHJlZml4ICYmIHN0ci5pbmRleE9mKHByZWZpeCkgPT09IDApIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH07Cgp9KShGb3JtLnJ0ZS51dGlsKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdmFyIFhmYUVsZW0sIFhmYVhodG1sLCBYZmFTY2hlbWEsIFhmYUF0dCwgWGZhVmFsOwoKdmFyIFhmYURhdGE7Cgp2YXIgWGZhTWltZVR5cGU7Cgp2YXIgWGZhRGF0YUVsZW07CgpYZmFEYXRhRWxlbSA9IEZvcm0ucnRlLnV0aWwuWGZhRGF0YUVsZW0gPSB7fTsKWGZhRGF0YUVsZW0uREFUQVNFVFMgPSAiZGF0YXNldHMiOwpYZmFEYXRhRWxlbS5EQVRBID0gImRhdGEiOwpYZmFEYXRhRWxlbS5fZWxlbVRhZ01hcCA9IG51bGw7ClhmYURhdGFFbGVtLmlzRWxlbWVudCA9IGZ1bmN0aW9uIChlbGVtVGFnKSB7CiAgICAvLyBjcmVhdGUgb24gZmlyc3QgdXNlCiAgICBpZiAoIVhmYURhdGFFbGVtLl9lbGVtVGFnTWFwKSB7CgogICAgICAgIFhmYURhdGFFbGVtLl9lbGVtVGFnTWFwID0ge307CiAgICAgICAgdmFyIGVsZW1lbnQsIHN0YXRpY0NvbnN0TGlzdCA9IE9iamVjdC5rZXlzKFhmYURhdGFFbGVtKTsKCiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IHN0YXRpY0NvbnN0TGlzdC5sZW5ndGg7IGluZGV4KyspIHsKICAgICAgICAgICAgZWxlbWVudCA9IHN0YXRpY0NvbnN0TGlzdFtpbmRleF07CiAgICAgICAgICAgIC8vIGVsZW1lbnQgbWVtYmVycyBhcmUgZXhwZWN0ZWQgbm90IHRvIGhhdmUgYW55IHVuZGVyc2NvcmVzIGluIHRoZWlyIG5hbWVzCiAgICAgICAgICAgIGlmIChlbGVtZW50LmluZGV4T2YoIl8iKSA8IDAgJiYgdHlwZW9mIFhmYURhdGFFbGVtW2VsZW1lbnRdID09ICJzdHJpbmciKSB7CiAgICAgICAgICAgICAgICBYZmFEYXRhRWxlbS5fZWxlbVRhZ01hcFtYZmFEYXRhRWxlbVtlbGVtZW50XV0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIChlbGVtVGFnIGluIFhmYURhdGFFbGVtLl9lbGVtVGFnTWFwKTsKfTsKClhmYURhdGEgPSBGb3JtLnJ0ZS51dGlsLlhmYURhdGEgPSB7fTsKWGZhRGF0YS5YRkFEQVRBTlNVUkkgPSAiaHR0cDovL3d3dy54ZmEub3JnL3NjaGVtYS94ZmEtZGF0YS8xLjAvIjsKClhmYU1pbWVUeXBlID0gRm9ybS5ydGUudXRpbC5YZmFNaW1lVHlwZSA9IHt9OwpYZmFNaW1lVHlwZS5KUEVHID0gImltYWdlL2pwZyI7Ci8qKiBNSU1FIHR5cGUgZm9yIFRJRkYgaW1hZ2VzLiAqLwpYZmFNaW1lVHlwZS5USUZGID0gImltYWdlL3RpZiI7Ci8qKiBNSU1FIHR5cGUgZm9yIEdJRiBpbWFnZXMuICovClhmYU1pbWVUeXBlLkdJRiA9ICJpbWFnZS9naWYiOwovKiogTUlNRSB0eXBlIGZvciBiaXRtYXAgaW1hZ2VzLiAqLwpYZmFNaW1lVHlwZS5CTVAgPSAiaW1hZ2UvYm1wIjsKLyoqIE1JTUUgdHlwZSBmb3IgUE5HIGltYWdlcyAob25seSBpbmRleGVkIFBOR3Mgd2l0aCBvbmUgdHJhbnNwYXJlbnQgY29sb3IgYXJlIHN1cHBvcnRlZCBpbiBYRkEgZm9ybXMpLiAqLwpYZmFNaW1lVHlwZS5QTkcgPSAiaW1hZ2UvcG5nIjsKLyoqIE1JTUUgdHlwZSBmb3IgcGxhaW4gdGV4dC4gKi8KWGZhTWltZVR5cGUuUExBSU5URVhUID0gInRleHQvcGxhaW4iOwovKiogTUlNRSB0eXBlIGZvciByaWNoIHRleHQuICovClhmYU1pbWVUeXBlLlJJQ0hURVhUID0gInRleHQvaHRtbCI7Ci8qKiBNSU1FIHR5cGUgZm9yIHhtbCB0ZXh0LiAqLwpYZmFNaW1lVHlwZS5YTUxURVhUID0gInRleHQveG1sIjsKClhmYVhodG1sID0gRm9ybS5ydGUudXRpbC5YZmFYaHRtbCA9IHt9OwpYZmFYaHRtbC5YSFRNTE5TVVJJID0gImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiOwovKiogQVhURSBBUEkgVmVyc2lvbiB1c2VkIGluIFhGQSBYSFRNTCAmbHQ7Ym9keSZndDsgdGFnIChjdXJyZW50bHkgc2V0IHRvIHRoYXQgd2hpY2ggaXMgdXNlZCB3aXRoIExpdmVDeWNsZSBFUyBVcGRhdGUgMSAoRGVzaWduZXIgOC4yKSkuICovClhmYVhodG1sLkFYVEVBUElWRVJTSU9OID0gIjIuNy4wLjAiOwoKLyoqIFRoZSByb290IG5vZGUgb2YgWEZBIHJpY2ggdGV4dCAoWEhUTUwpIGFzIHNldCBpbiByaWNoIHRleHQgZHJhd3MgYW5kIGZpZWxkcy4gVGhlIGVudGlyZSByaWNoIHRleHQgdmFsdWUgaXMgY29udGFpbmVkIHdpdGhpbiBhICZsdDtib2R5Jmd0OyBlbGVtZW50LiAqLwpYZmFYaHRtbC5CT0RZID0gImJvZHkiOwoKLyoqIFNwYWNlcnVuIHN0eWxlIG5hbWUuICovClhmYVhodG1sLlNQQUNFUlVOU1RZTEVOQU1FID0gInhmYS1zcGFjZXJ1biI7Ci8qKiBTcGFjZXJ1biBzdHlsZSB2YWx1ZS4gKi8KWGZhWGh0bWwuU1BBQ0VSVU5TVFlMRVZBTFVFID0gInllcyI7Ci8qKiBTcGFjZXJ1biBzdHlsZSAobmFtZTp2YWx1ZSkuICovClhmYVhodG1sLlNQQUNFUlVOU1RZTEUgPSBYZmFYaHRtbC5TUEFDRVJVTlNUWUxFTkFNRSArICc6JyArIFhmYVhodG1sLlNQQUNFUlVOU1RZTEVWQUxVRTsKLyoqIFNwYWNlcnVuIG9wZW5pbmcgdGFnLiAqLwpYZmFYaHRtbC5TUEFDRVJVTk9QRU4gPSAnPHNwYW4gc3R5bGU9IicgKyBYZmFYaHRtbC5TUEFDRVJVTlNUWUxFICsgJyI+JzsKLyoqIFNwYWNlcnVuIGNsb3NpbmcgdGFnLiAqLwpYZmFYaHRtbC5TUEFDRVJVTkNMT1NFID0gJzwvc3Bhbj4nOwpYZmFFbGVtID0gRm9ybS5ydGUudXRpbC5YZmFFbGVtID0ge307ClhmYUVsZW0uQVBQRUFSQU5DRUZJTFRFUiA9ICJhcHBlYXJhbmNlRmlsdGVyIjsKWGZhRWxlbS5BUkMgPSAiYXJjIjsKWGZhRWxlbS5BUkVBID0gImFyZWEiOwpYZmFFbGVtLkJBUkNPREUgPSAiYmFyY29kZSI7ClhmYUVsZW0uQklORCA9ICJiaW5kIjsKWGZhRWxlbS5CT09MRUFOID0gImJvb2xlYW4iOwpYZmFFbGVtLkJPUkRFUiA9ICJib3JkZXIiOwpYZmFFbGVtLkJVVFRPTiA9ICJidXR0b24iOwpYZmFFbGVtLkNBUFRJT04gPSAiY2FwdGlvbiI7ClhmYUVsZW0uQ0VSVElGSUNBVEUgPSAiY2VydGlmaWNhdGUiOwpYZmFFbGVtLkNIRUNLQlVUVE9OID0gImNoZWNrQnV0dG9uIjsKWGZhRWxlbS5DSE9JQ0VMSVNUID0gImNob2ljZUxpc3QiOwpYZmFFbGVtLkNPTE9SID0gImNvbG9yIjsKWGZhRWxlbS5DT05URU5UQVJFQSA9ICJjb250ZW50QXJlYSI7ClhmYUVsZW0uREFURSA9ICJkYXRlIjsKWGZhRWxlbS5EQVRFVElNRSA9ICJkYXRlVGltZSI7ClhmYUVsZW0uREFURVRJTUVFRElUID0gImRhdGVUaW1lRWRpdCI7ClhmYUVsZW0uREVDSU1BTCA9ICJkZWNpbWFsIjsKWGZhRWxlbS5ERUZBVUxUVUkgPSAiZGVmYXVsdFVpIjsKWGZhRWxlbS5ESUdFU1RNRVRIT0QgPSAiZGlnZXN0TWV0aG9kIjsKWGZhRWxlbS5EUkFXID0gImRyYXciOwpYZmFFbGVtLkVER0UgPSAiZWRnZSI7ClhmYUVsZW0uRU5DT0RJTkcgPSAiZW5jb2RpbmciOwpYZmFFbGVtLkVYQ0xHUk9VUCA9ICJleGNsR3JvdXAiOwpYZmFFbGVtLkVYREFUQSA9ICJleERhdGEiOwpYZmFFbGVtLkVYT0JKRUNUID0gImV4T2JqZWN0IjsKWGZhRWxlbS5FVkVOVCA9ICJldmVudCI7ClhmYUVsZW0uRVhFQ1VURSA9ICJleGVjdXRlIjsKWGZhRWxlbS5GSUVMRCA9ICJmaWVsZCI7ClhmYUVsZW0uRklMTCA9ICJmaWxsIjsKWGZhRWxlbS5GTE9BVCA9ICJmbG9hdCI7ClhmYUVsZW0uRk9OVCA9ICJmb250IjsKWGZhRWxlbS5IQU5ETEVSID0gImhhbmRsZXIiOwpYZmFFbGVtLklNQUdFID0gImltYWdlIjsKWGZhRWxlbS5JTUFHRUVESVQgPSAiaW1hZ2VFZGl0IjsKWGZhRWxlbS5JTlRFR0VSID0gImludGVnZXIiOwpYZmFFbGVtLklURU1TID0gIml0ZW1zIjsKWGZhRWxlbS5LRUVQID0gImtlZXAiOwpYZmFFbGVtLkxJTkUgPSAibGluZSI7ClhmYUVsZW0uTElORUFSID0gImxpbmVhciI7ClhmYUVsZW0uTE9DS0RPQ1VNRU5UID0gImxvY2tEb2N1bWVudCI7ClhmYUVsZW0uTUFSR0lOID0gIm1hcmdpbiI7ClhmYUVsZW0uTUVESVVNID0gIm1lZGl1bSI7ClhmYUVsZW0uTlVNRVJJQ0VESVQgPSAibnVtZXJpY0VkaXQiOwpYZmFFbGVtLk9JRCA9ICJvaWQiOwpYZmFFbGVtLlBBR0VBUkVBID0gInBhZ2VBcmVhIjsKWGZhRWxlbS5QQUdFU0VUID0gInBhZ2VTZXQiOwpYZmFFbGVtLlBBUkEgPSAicGFyYSI7ClhmYUVsZW0uUEFTU1dPUkRFRElUID0gInBhc3N3b3JkRWRpdCI7ClhmYUVsZW0uUEFUVEVSTiA9ICJwYXR0ZXJuIjsKWGZhRWxlbS5QSUNUVVJFID0gInBpY3R1cmUiOwpYZmFFbGVtLlJBRElBTCA9ICJyYWRpYWwiOwpYZmFFbGVtLlJFQ1RBTkdMRSA9ICJyZWN0YW5nbGUiOwpYZmFFbGVtLlJFQVNPTiA9ICJyZWFzb24iOwpYZmFFbGVtLlJFRiA9ICJyZWYiOwpYZmFFbGVtLlNDUklQVCA9ICJzY3JpcHQiOwpYZmFFbGVtLlNJR05BVFVSRSA9ICJzaWduYXR1cmUiOwpYZmFFbGVtLlNJR05EQVRBID0gInNpZ25EYXRhIjsKWGZhRWxlbS5TT0xJRCA9ICJzb2xpZCI7ClhmYUVsZW0uU1BFQUsgPSAic3BlYWsiOwpYZmFFbGVtLlNUSVBQTEUgPSAic3RpcHBsZSI7ClhmYUVsZW0uU1VCRk9STSA9ICJzdWJmb3JtIjsKWGZhRWxlbS5TVUJGT1JNU0VUID0gInN1YmZvcm1TZXQiOwpYZmFFbGVtLlNVQkpFQ1RETiA9ICJzdWJqZWN0RE4iOwpYZmFFbGVtLlNVQk1JVCA9ICJzdWJtaXQiOwpYZmFFbGVtLlRFTVBMQVRFID0gInRlbXBsYXRlIjsKWGZhRWxlbS5URVhUID0gInRleHQiOwpYZmFFbGVtLlRFWFRFRElUID0gInRleHRFZGl0IjsKWGZhRWxlbS5USU1FID0gInRpbWUiOwpYZmFFbGVtLlRPT0xUSVAgPSAidG9vbFRpcCI7ClhmYUVsZW0uVUkgPSAidWkiOwpYZmFFbGVtLlZBTFVFID0gInZhbHVlIjsKWGZhRWxlbS5WQVJJQUJMRVMgPSAidmFyaWFibGVzIjsKWGZhRWxlbS5fZWxlbVRhZ01hcCA9IG51bGw7CgovKioKICogRGV0ZXJtaW5lcyBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgbmFtZSBpcyBhIHZhbGlkIFhGQSBUZW1wbGF0ZSBlbGVtZW50IG5hbWUuCiAqIEBwYXJhbSBlbGVtVGFnIFRoZSBuYW1lIHRvIHRlc3QuCiAqIEByZXR1cm4gVHJ1ZSBpZiBpdCdzIGFuIFhGQSBUZW1wbGF0ZSBlbGVtZW50IG5hbWU7IGZhbHNlIGlmIG5vdC4KICovClhmYUVsZW0uaXNFbGVtZW50ID0gZnVuY3Rpb24gKGVsZW1UYWcpIHsKICAgIC8vIGNyZWF0ZSBvbiBmaXJzdCB1c2UKICAgIGlmICghWGZhRWxlbS5fZWxlbVRhZ01hcCkgewogICAgICAgIFhmYUVsZW0uX2VsZW1UYWdNYXAgPSB7fTsKICAgICAgICB2YXIgZWxlbWVudCwgc3RhdGljQ29uc3RMaXN0ID0gT2JqZWN0LmtleXMoWGZhRWxlbSk7CiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IHN0YXRpY0NvbnN0TGlzdC5sZW5ndGg7IGluZGV4KyspIHsKICAgICAgICAgICAgZWxlbWVudCA9IHN0YXRpY0NvbnN0TGlzdFtpbmRleF07CiAgICAgICAgICAgIC8vIGVsZW1lbnQgbWVtYmVycyBhcmUgZXhwZWN0ZWQgbm90IHRvIGhhdmUgYW55IHVuZGVyc2NvcmVzIGluIHRoZWlyIG5hbWVzCiAgICAgICAgICAgIGlmIChlbGVtZW50LmluZGV4T2YoIl8iKSA8IDAgJiYgdHlwZW9mIFhmYUVsZW1bZWxlbWVudF0gPT0gInN0cmluZyIpIHsKICAgICAgICAgICAgICAgIFhmYUVsZW0uX2VsZW1UYWdNYXBbWGZhRWxlbVtlbGVtZW50XV0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIChlbGVtVGFnIGluIFhmYUVsZW0uX2VsZW1UYWdNYXApOwp9OwoKWGZhQXR0ID0gRm9ybS5ydGUudXRpbC5YZmFBdHQgPSB7fTsKClhmYUF0dC5BQ1RJVklUWSA9ICJhY3Rpdml0eSI7ClhmYUF0dC5BU1BFQ1QgPSAiYXNwZWN0IjsKWGZhQXR0LkFMTE9XUklDSFRFWFQgPSAiYWxsb3dSaWNoVGV4dCI7ClhmYUF0dC5CT1RUT01JTlNFVCA9ICJib3R0b21JbnNldCI7ClhmYUF0dC5DT01NSVRPTiA9ICJjb21taXRPbiI7ClhmYUF0dC5DT05URU5UVFlQRSA9ICJjb250ZW50VHlwZSI7ClhmYUF0dC5IID0gImgiOwpYZmFBdHQuSFJFRiA9ICJocmVmIjsKWGZhQXR0LklEID0gImlkIjsKWGZhQXR0LklOVEFDVCA9ICJpbnRhY3QiOwpYZmFBdHQuTEFZT1VUID0gImxheW91dCI7ClhmYUF0dC5MRUZUSU5TRVQgPSAibGVmdEluc2V0IjsKWGZhQXR0LkxPTkcgPSAibG9uZyI7ClhmYUF0dC5NQVJHSU5MRUZUID0gIm1hcmdpbkxlZnQiOwpYZmFBdHQuTUFSR0lOUklHSFQgPSAibWFyZ2luUmlnaHQiOwpYZmFBdHQuTUFUQ0ggPSAibWF0Y2giOwpYZmFBdHQuTUFYQ0hBUlMgPSAibWF4Q2hhcnMiOwpYZmFBdHQuTUFYSCA9ICJtYXhIIjsKWGZhQXR0Lk1BWExFTkdUSCA9ICJtYXhMZW5ndGgiOwpYZmFBdHQuTUFYVyA9ICJtYXhXIjsKWGZhQXR0Lk1JTkggPSAibWluSCI7ClhmYUF0dC5NSU5XID0gIm1pblciOwpYZmFBdHQuTVVMVElMSU5FID0gIm11bHRpTGluZSI7ClhmYUF0dC5OQU1FID0gIm5hbWUiOwpYZmFBdHQuT1BFTiA9ICJvcGVuIjsKWGZhQXR0Lk9SSUVOVEFUSU9OID0gIm9yaWVudGF0aW9uIjsKWGZhQXR0LlBBR0VQT1NJVElPTiA9ICJwYWdlUG9zaXRpb24iOwpYZmFBdHQuUExBQ0VNRU5UID0gInBsYWNlbWVudCI7ClhmYUF0dC5QUkVTRU5DRSA9ICJwcmVzZW5jZSI7ClhmYUF0dC5SRUYgPSAicmVmIjsKWGZhQXR0LlJFTEFUSU9OID0gInJlbGF0aW9uIjsKWGZhQXR0LlJFU0VSVkUgPSAicmVzZXJ2ZSI7ClhmYUF0dC5SSUdIVElOU0VUID0gInJpZ2h0SW5zZXQiOwpYZmFBdHQuUlVOQVQgPSAicnVuQXQiOwpYZmFBdHQuU0FWRSA9ICJzYXZlIjsKWGZhQXR0LlNIT1JUID0gInNob3J0IjsKWGZhQXR0LlNJWkUgPSAic2l6ZSI7ClhmYUF0dC5TUEFDRUFCT1ZFID0gInNwYWNlQWJvdmUiOwpYZmFBdHQuU1BBQ0VCRUxPVyA9ICJzcGFjZUJlbG93IjsKWGZhQXR0LlNUT0NLID0gInN0b2NrIjsKWGZhQXR0LlNUUk9LRSA9ICJzdHJva2UiOwpYZmFBdHQuVEVYVEVOVFJZID0gInRleHRFbnRyeSI7ClhmYUF0dC5UT1BJTlNFVCA9ICJ0b3BJbnNldCI7ClhmYUF0dC5UWVBFRkFDRSA9ICJ0eXBlZmFjZSI7ClhmYUF0dC5VU0UgPSAidXNlIjsKWGZhQXR0LlVTRUhSRUYgPSAidXNlaHJlZiI7ClhmYUF0dC5WQUxJR04gPSAidkFsaWduIjsKWGZhQXR0LlZBTFVFID0gInZhbHVlIjsKWGZhQXR0LldFSUdIVCA9ICJ3ZWlnaHQiOwpYZmFBdHQuVyA9ICJ3IjsKWGZhQXR0LlggPSAieCI7ClhmYUF0dC5ZID0gInkiOwovKiogTWFwIG9mIGF0dHJpYnV0ZSBuYW1lcyAoc3RyaW5nIHZhbHVlcyBvZiBzdGF0aWMgYXR0cmlidXRlIGNvbnN0YW50IG1lbWJlcnMgb2YgWGZhQXR0KSB0byBhbiBhcy15ZXQgdW51c2VkIHZhbHVlLiAqLwpYZmFBdHQuX2F0dFRhZ01hcCA9IG51bGw7ClhmYUF0dC5pc0F0dHJpYnV0ZSA9IGZ1bmN0aW9uIChhdHRUYWcpIHsKICAgIC8vIGNyZWF0ZSBvbiBmaXJzdCB1c2UKICAgIGlmICghWGZhQXR0Ll9hdHRUYWdNYXApIHsKICAgICAgICBYZmFBdHQuX2F0dFRhZ01hcCA9IHt9OwogICAgICAgIHZhciBlbGVtZW50LCBzdGF0aWNDb25zdExpc3QgPSBPYmplY3Qua2V5cyhYZmFBdHQpOwogICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggPCBzdGF0aWNDb25zdExpc3QubGVuZ3RoOyBpbmRleCsrKSB7CiAgICAgICAgICAgIGVsZW1lbnQgPSBzdGF0aWNDb25zdExpc3RbaW5kZXhdOwogICAgICAgICAgICAvLyBlbGVtZW50IG1lbWJlcnMgYXJlIGV4cGVjdGVkIG5vdCB0byBoYXZlIGFueSB1bmRlcnNjb3JlcyBpbiB0aGVpciBuYW1lcwogICAgICAgICAgICBpZiAoZWxlbWVudC5pbmRleE9mKCJfIikgPCAwICYmIHR5cGVvZiBYZmFBdHRbZWxlbWVudF0gPT0gInN0cmluZyIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2F0dFRhZ01hcFtYZmFBdHRbZWxlbWVudF1dID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAoYXR0VGFnIGluIHRoaXMuX2F0dFRhZ01hcCk7Cn07CgpYZmFWYWwgPSBGb3JtLnJ0ZS51dGlsLlhmYVZhbCA9IHt9OwoKWGZhVmFsLkFDVFVBTCA9ICJhY3R1YWwiOwpYZmFWYWwuQUxXQVlTID0gImFsd2F5cyI7ClhmYVZhbC5BTlkgPSAiYW55IjsKWGZhVmFsLkFQUFhGT1JNQ0FMQyA9ICJhcHBsaWNhdGlvbi94LWZvcm1jYWxjIjsKWGZhVmFsLkFQUFhKQVZBU0NSSVBUID0gImFwcGxpY2F0aW9uL3gtamF2YXNjcmlwdCI7ClhmYVZhbC5CT0xEID0gImJvbGQiOwpYZmFWYWwuQk9USCA9ICJib3RoIjsKWGZhVmFsLkJPVFRPTSA9ICJib3R0b20iOwpYZmFWYWwuQ0hBTkdFID0gImNoYW5nZSI7ClhmYVZhbC5DTElDSyA9ICJjbGljayI7ClhmYVZhbC5DTElFTlQgPSAiY2xpZW50IjsKWGZhVmFsLkNPTlRFTlRBUkVBID0gImNvbnRlbnRBcmVhIjsKWGZhVmFsLkRBU0hET1QgPSAiZGFzaERvdCI7ClhmYVZhbC5EQVNIRE9URE9UID0gImRhc2hEb3REb3QiOwpYZmFWYWwuREFTSEVEID0gImRhc2hlZCI7ClhmYVZhbC5EQVRBUkVGID0gImRhdGFSZWYiOwpYZmFWYWwuRE9DQ0xPU0UgPSAiZG9jQ2xvc2UiOwpYZmFWYWwuRE9DUkVBRFkgPSAiZG9jUmVhZHkiOwpYZmFWYWwuRE9UVEVEID0gImRvdHRlZCI7ClhmYVZhbC5FTUJPU1NFRCA9ICJlbWJvc3NlZCI7ClhmYVZhbC5FTlRFUiA9ICJlbnRlciI7ClhmYVZhbC5FVENIRUQgPSAiZXRjaGVkIjsKWGZhVmFsLkVYSVQgPSAiZXhpdCI7ClhmYVZhbC5GSVJTVCA9ICJmaXJzdCI7ClhmYVZhbC5GSVQgPSAiZml0IjsKWGZhVmFsLkZVTEwgPSAiZnVsbCI7ClhmYVZhbC5HTE9CQUwgPSAiZ2xvYmFsIjsKWGZhVmFsLkhFSUdIVCA9ICJoZWlnaHQiOwpYZmFWYWwuSElEREVOID0gImhpZGRlbiI7ClhmYVZhbC5JTkRFWENIQU5HRSA9ICJpbmRleENoYW5nZSI7ClhmYVZhbC5JTklUSUFMSVpFID0gImluaXRpYWxpemUiOwpYZmFWYWwuSU5MSU5FID0gImlubGluZSI7ClhmYVZhbC5JTlZJU0lCTEUgPSAiaW52aXNpYmxlIjsKWGZhVmFsLkxBTkRTQ0FQRSA9ICJsYW5kc2NhcGUiOwpYZmFWYWwuTEFTVCA9ICJsYXN0IjsKWGZhVmFsLkxFRlQgPSAibGVmdCI7ClhmYVZhbC5MRVRURVIgPSAibGV0dGVyIjsKWGZhVmFsLkxPV0VSRUQgPSAibG93ZXJlZCI7ClhmYVZhbC5MUlRCID0gImxyLXRiIjsKWGZhVmFsLk1JRERMRSA9ICJtaWRkbGUiOwpYZmFWYWwuTU9VU0VET1dOID0gIm1vdXNlRG93biI7ClhmYVZhbC5NT1VTRUVOVEVSID0gIm1vdXNlRW50ZXIiOwpYZmFWYWwuTU9VU0VFWElUID0gIm1vdXNlRXhpdCI7ClhmYVZhbC5NT1VTRVVQID0gIm1vdXNlVXAiOwpYZmFWYWwuTVVMVElTRUxFQ1QgPSAibXVsdGlTZWxlY3QiOwpYZmFWYWwuTk9ORSA9ICJub25lIjsKWGZhVmFsLk5PUk1BTCA9ICJub3JtYWwiOwpYZmFWYWwuT05DRSA9ICJvbmNlIjsKWGZhVmFsLk9ORU5UUlkgPSAib25FbnRyeSI7ClhmYVZhbC5PTkxZID0gIm9ubHkiOwpYZmFWYWwuT1JERVJFRE9DQ1VSUkVOQ0UgPSAib3JkZXJlZE9jY3VycmVuY2UiOwpYZmFWYWwuUEFHRUFSRUEgPSAicGFnZUFyZWEiOwpYZmFWYWwuUE9SVFJBSVQgPSAicG9ydHJhaXQiOwpYZmFWYWwuUE9TSVRJT04gPSAicG9zaXRpb24iOwpYZmFWYWwuUE9TVEVYRUNVVEUgPSAicG9zdEV4ZWN1dGUiOwpYZmFWYWwuUE9TVE9QRU4gPSAicG9zdE9wZW4iOwpYZmFWYWwuUE9TVFBSSU5UID0gInBvc3RQcmludCI7ClhmYVZhbC5QT1NUU0FWRSA9ICJwb3N0U2F2ZSI7ClhmYVZhbC5QT1NUU0lHTiA9ICJwb3N0U2lnbiI7ClhmYVZhbC5QT1NUU1VCTUlUID0gInBvc3RTdWJtaXQiOwpYZmFWYWwuUFJFRVhFQ1VURSA9ICJwcmVFeGVjdXRlIjsKWGZhVmFsLlBSRU9QRU4gPSAicHJlT3BlbiI7ClhmYVZhbC5QUkVQUklOVCA9ICJwcmVQcmludCI7ClhmYVZhbC5QUkVTQVZFID0gInByZVNhdmUiOwpYZmFWYWwuUFJFU0lHTiA9ICJwcmVTaWduIjsKWGZhVmFsLlBSRVNVQk1JVCA9ICJwcmVTdWJtaXQiOwpYZmFWYWwuUkFJU0VEID0gInJhaXNlZCI7ClhmYVZhbC5SRUFEWSA9ICJyZWFkeSI7ClhmYVZhbC5SRVNUID0gInJlc3QiOwpYZmFWYWwuUklHSFQgPSAicmlnaHQiOwpYZmFWYWwuUkxUQiA9ICJybC10YiI7ClhmYVZhbC5ST1cgPSAicm93IjsKWGZhVmFsLlNFTEVDVCA9ICJzZWxlY3QiOwpYZmFWYWwuU0VSVkVSID0gInNlcnZlciI7ClhmYVZhbC5TT0xJRCA9ICJzb2xpZCI7ClhmYVZhbC5UQUJMRSA9ICJ0YWJsZSI7ClhmYVZhbC5UQiA9ICJ0YiI7ClhmYVZhbC5UT1AgPSAidG9wIjsKWGZhVmFsLlVTRVJDT05UUk9MID0gInVzZXJDb250cm9sIjsKWGZhVmFsLlZJU0lCTEUgPSAidmlzaWJsZSI7ClhmYVZhbC5XSURUSCA9ICJ3aWR0aCI7CgpYZmFTY2hlbWEgPSBGb3JtLnJ0ZS51dGlsLlhmYVNjaGVtYSA9IHt9OwovKiogWEZBIG5hbWVzcGFjZSBwcmVmaXguICovClhmYVNjaGVtYS5YRkFOUyA9ICJ4ZmEiOwoKLyoqIFhGQSAyLjggbmFtZXNwYWNlIFVSSS4gKi8KWGZhU2NoZW1hLlhGQVZFUlNJT04yOCA9ICJodHRwOi8vd3d3LnhmYS5vcmcvc2NoZW1hL3hmYS10ZW1wbGF0ZS8yLjgvIjsKLyoqIFhGQSB2ZXJzaW9uIGZvciBhbGwgbmV3IHRlbXBsYXRlcy4gKi8KWGZhU2NoZW1hLlRFTVBMQVRFVkVSU0lPTiA9IFhmYVNjaGVtYS5YRkFWRVJTSU9OMjg7CgovKiogRGVmYXVsdCBmb3Igc2NoZW1hIHZhbHVlcyB0aGF0IGFyZSB0aGUgbnVtYmVyIHplcm8uICovClhmYVNjaGVtYS5aRVJPID0gIjAiOwovKiogRGVmYXVsdCBmb3Igc2NoZW1hIHZhbHVlcyB0aGF0IGFyZSB0aGUgbnVtYmVyIG9uZS4gKi8KWGZhU2NoZW1hLk9ORSA9ICIxIjsKLyoqIERlZmF1bHQgZm9yIHNjaGVtYSB2YWx1ZXMgdGhhdCBhcmUgdGhlIG51bWJlciBtaW51cyBvbmUuICovClhmYVNjaGVtYS5NSU5VU09ORSA9ICItMSI7Ci8qKiBQb2ludCB1bml0cy4gKi8KWGZhU2NoZW1hLlVOSVRQT0lOVCA9ICJwdCI7Ci8qKiBNaWxsaW1ldGVyIHVuaXRzLiAqLwpYZmFTY2hlbWEuVU5JVE1JTExJID0gIm1tIjsKLyoqIENlbnRpbWV0ZXIgdW5pdHMuICovClhmYVNjaGVtYS5VTklUQ0VOVEkgPSAiY20iOwovKiogSW5jaCB1bml0cy4gKi8KWGZhU2NoZW1hLlVOSVRJTkNIID0gImluIjsKLyoqIERlZmF1bHQgdW5pdHMgZm9yIHNjaGVtYSB2YWx1ZXMgdGhhdCBhcmUgbWVhc3VyZW1lbnRzLiAqLwpYZmFTY2hlbWEuREVGQVVMVFVOSVRTID0gWGZhU2NoZW1hLlVOSVRJTkNIOwovKiogRGVmYXVsdCBvdXRwdXQgdW5pdHMgd2hlbSBlZGl0aW5nIG1lYXN1cmVtZW50IHZhbHVlcy4gTWlsbGltZXRlcnMgYXJlIG1vcmUgcHJlY2lzZS4gKi8KWGZhU2NoZW1hLldSSVRFVU5JVFMgPSBYZmFTY2hlbWEuVU5JVE1JTExJOwovKiogRGVmYXVsdCBmb3Igc2NoZW1hIHZhbHVlcyB0aGF0IGFyZSAiY2RhdGEiLiAqLwpYZmFTY2hlbWEuQ0RBVEEgPSAiIjsKLyoqIERlZmF1bHQgZm9yIHNjaGVtYSB2YWx1ZXMgdGhhdCBhcmUgInhtbC1pZCIuICovClhmYVNjaGVtYS5YTUxJRCA9ICIiOwovKiogRGVmYXVsdCBmb250IGZvciB0eXBlZmFjZSBwcm9wZXJ0aWVzLiBBY3R1YWwgZGVmYXVsdCBpcyAiQ291cmllciBTdGQiIGhvd2V2ZXIgIk15cmlhZCBQcm8iIGlzIHRoZSBBZG9iZSBzdGFuZGFyZCBmb250LiAqLwpYZmFTY2hlbWEuREVGQVVMVEZPTlQgPSAiTXlyaWFkIFBybyI7Ci8qKiBCbGFjayBjb2xvci4gKi8KWGZhU2NoZW1hLkJMQUNLID0gIjAsMCwwIjsKCi8vIFRPRE86IENvbnNpZGVyIG1vdmluZyBYZmFTY2hlbWEuWEZBRk9STURPTSBpbnRvIG5ldyBYZmFTY3JpcHRpbmcgb3Igc2NyaXAuWGZhRm9ybURvbSBvciBzb21ldGhpbmcgYWxvbmcgdGhvc2UgbGluZXMuCi8qIFhGQSBGb3JtIERPTSBzY3JpcHRpbmcgcHJlZml4LiAqLwovL1hmYVNjaGVtYS5YRkFGT1JNRE9NID0gInhmYS5mb3JtIjsKCi8vIFRPRE86IFdvcmthcm91bmQgZm9yIGh0dHBzOi8vYnVncy5hZG9iZS5jb20vamlyYS9icm93c2UvQVNDLTIyMzEgKG5vdCB0ZWNobmljYWxseSBwYXJ0IG9mIHRoZSBYRkEgU2NoZW1hIGJ1dAovLyAgc29tZWhvdyB1c2luZyB0aGUgY29uc3QgZnJvbSBYZmFTY2hlbWEgcmF0aGVyIHRoYW4gWGZhRnJhZ1V0aWxzIHdvcmtzIGJldHRlciB3aGVuIHNldHRpbmcgaXQgYXMgdGhlCi8vICBkZWZhdWx0IHZhbHVlIGZvciBhIGZ1bmN0aW9uIHBhcmFtZXRlcikuCi8qKiBEZWZhdWx0IG5hbWUgZm9yIGEgbmV3IGZyYWdtZW50LiAqLwpYZmFTY2hlbWEuREVGQVVMVEZSQUdOQU1FID0gIkZyYWdtZW50MSI7Ci8qKiBEZWZhdWx0IG5hbWUgZm9yIGEgbmV3IGZvcm0gb2JqZWN0IChmaWVsZCwgZHJhdywgc3ViZm9ybSwgZXRjLikuICovClhmYVNjaGVtYS5ERUZBVUxUT0JKTkFNRSA9ICJGb3JtT2JqZWN0IjsKLyoqIERlZmF1bHQgbmFtZSBmb3IgYSByb290IHN1YmZvcm0uICovClhmYVNjaGVtYS5ERUZBVUxUUk9PVE5BTUUgPSAiZm9ybTEiOwoKLyoqIERlZmF1bHQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkb21haW4gZm9yIFBJcyBnZW5lcmF0ZWQgYW5kIHJlYWQgYnkgTEMgRGVzaWduZXIuICovClhmYVNjaGVtYS5QSURFU0RPTUFJTiA9ICJ0ZW1wbGF0ZURlc2lnbmVyIjsKCi8qKiBQcm9jZXNzaW5nIGluc3RydWN0aW9uIHRoYXQgaWRlbnRpZmllcyBhIGZvcm0gb2JqZWN0IGFzIGEgZnJhZ21lbnQuIFRoaXMgUEkgb2JqZWN0IGFsc28gZGVmaW5lcyBhICJ2YWx1ZSIgcHJvcGVydHkgdGhhdCBob2xkcyB0aGUgUEkncyBleHBlY3RlZCAoYW5kIG9ubHkpIHZhbHVlLiAqLwpYZmFTY2hlbWEuUElGUkFHSVNGUkFHID0ge2RvbWFpbiA6IFhmYVNjaGVtYS5QSURFU0RPTUFJTiwga2V5IDogImlzRnJhZ21lbnQiLCB2YWx1ZSA6ICJ5ZXMifTsKLyoqIFByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGhhdCBjb250YWlucyB0aGUgdGl0bGUgbWV0YWRhdGEgZm9yIGEgZnJhZ21lbnQuICovClhmYVNjaGVtYS5QSUZSQUdUSVRMRSA9IHtkb21haW4gOiBYZmFTY2hlbWEuUElERVNET01BSU4sIGtleSA6ICJmcmFnbWVudFRpdGxlIn07Ci8qKiBQcm9jZXNzaW5nIGluc3RydWN0aW9uIHRoYXQgY29udGFpbnMgdGhlIGRlc2NyaXB0aW9uIG1ldGFkYXRhIGZvciBhIGZyYWdtZW50LiAqLwpYZmFTY2hlbWEuUElGUkFHREVTQyA9IHtkb21haW4gOiBYZmFTY2hlbWEuUElERVNET01BSU4sIGtleSA6ICJmcmFnbWVudERlc2NyaXB0aW9uIn07CgovKioKICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgWEZBIGVsZW1lbnQgdGFnIGlzIGEgY29udGFpbmVyIG5vZGUgKG1heSBjb250YWluIG90aGVyIGNvbnRhaW5lcnMgb3IgZmllbGRzL2RyYXdzKS4gUHJvdG9zIGFyZSBleGNsdWRlZC4KICogQHBhcmFtIGVsZW1UYWcgVGhlIFhGQSBlbGVtZW50IHRhZyB0byBjaGVjayBhcyBiZWluZyBhIGNvbnRhaW5lci4KICogQHBhcmFtIGluY2x1ZGVFeEdycCBJZiB0cnVlLCB0aGUgJmx0O2V4Y2xHcm91cCZndDsgbm9kZSBpcyBjb25zaWRlcmVkIGEgY29udGFpbmVyLiBPdGhlcndpc2UsIGl0IGlzIG5vdC4gTm90ZSB0aGF0IGluIHRlcm1zIG9mCiAqICAiY29udGVudCIsIGV4Y2x1c2lvbiBncm91cCBub2RlcyBtYXkgb25seSBjb250YWluICZsdDtmaWVsZCZndDsgbm9kZXMgd2hpY2ggaXMgbW9yZSByZXN0cmljdGl2ZSB0aGFuIG90aGVyIGNvbnRhaW5lciB0eXBlcy4KICovClhmYVNjaGVtYS5pc0NvbnRhaW5lckVsZW0gPSBmdW5jdGlvbiAoZWxlbVRhZywgaW5jbHVkZUV4R3JwKSB7CiAgICBpbmNsdWRlRXhHcnAgPSBpbmNsdWRlRXhHcnAgIT09IHVuZGVmaW5lZCA/IGluY2x1ZGVFeEdycCA6IHRydWU7CgogICAgc3dpdGNoIChlbGVtVGFnKSB7CiAgICAgICAgY2FzZSBYZmFFbGVtLlNVQkZPUk06CiAgICAgICAgY2FzZSBYZmFFbGVtLlNVQkZPUk1TRVQ6CiAgICAgICAgY2FzZSBYZmFFbGVtLkFSRUE6CiAgICAgICAgY2FzZSBYZmFFbGVtLlBBR0VBUkVBOgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgWGZhRWxlbS5FWENMR1JPVVA6CiAgICAgICAgICAgIHJldHVybiBpbmNsdWRlRXhHcnA7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICByZXR1cm4gZmFsc2U7Cn07CgovKiogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgWEZBIGVsZW1lbnQgdGFnIGRlZmluZXMgZm9ybSBjb250ZW50IChjb3VsZCBiZSBhIGZpZWxkLCBkcmF3IG9yIHNvbWUgdHlwZSBvZiBjb250YWluZXIgbm9kZSkuIFByb3RvcyBhcmUgZXhjbHVkZWQuICovClhmYVNjaGVtYS5pc0NvbnRlbnRFbGVtID0gZnVuY3Rpb24gKGVsZW1UYWcpIHsKICAgIHN3aXRjaCAoZWxlbVRhZykgewogICAgICAgIGNhc2UgWGZhRWxlbS5EUkFXOgogICAgICAgIGNhc2UgWGZhRWxlbS5GSUVMRDoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIFhmYVNjaGVtYS5pc0NvbnRhaW5lckVsZW0oZWxlbVRhZyk7Cn07CgovKioKICogUmV0dXJucyB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgYSBnaXZlbiBhdHRyaWJ1dGUgdGFnLiBJZiB0aGUgYXR0cmlidXRlIGlzIGludmFsaWQgb3IgdW5rbm93biwgbnVsbCBpcyByZXR1cm5lZC4gSWYgdGhlcmUgaXNuJ3QgZW5vdWdoIGNvbnRleHQgdG8gZGV0ZXJtaW5lCiAqICB0aGUgZGVmYXVsdCwgbnVsbCBpcyByZXR1cm5lZCAoZS5nLiB0aGUgbm9kZSBtYXkgYmUgb3JwaGFuZWQgYW5kIGEgcGFydGljdWxhciBwYXJlbnQgdHlwZSBpcyByZXF1aXJlZCwgbGlrZSB0aGUgZGVmYXVsdCBmb3IgdGhlICJhbGxvd1JpY2hUZXh0IiBjYW4ndCBiZQogKiAgZGV0ZXJtaW5lZCBpZiB0aGUgPGNvZGU+dGV4dEVkaXQ8L2NvZGU+IG5vZGUgaXMgb3JwaGFuZWQgYmVjYXVzZSBhIDxjb2RlPmZpZWxkPC9jb2RlPiBvciA8Y29kZT5kcmF3PC9jb2RlPiBwYXJlbnQgY29udGFpbmluZyBhIDxjb2RlPnZhbHVlPC9jb2RlPiBpcyByZXF1aXJlZCkuCiAqIEBwYXJhbSBhdHRUYWcgVGhlIGF0dHJpYnV0ZSBuYW1lIGZvciB3aGljaCB0byByZXRyaWV2ZSB0aGUgZGVmYXVsdC4KICogQHBhcmFtIGNvbnRleHROb2RlIFhGQSBub2RlIHRoYXQgcHJvdmlkZXMgbmVjZXNzYXJ5IGNvbnRleHQgZm9yIHRoZSBkZWZhdWx0IHZhbHVlLiBGb3IgZXhhbXBsZSwgdGhlICJhbGxvd1JpY2hUZXh0IiBhdHRyaWJ1dGUgaGFzIGRpZmZlcmVudCBkZWZhdWx0IHZhbHVlcwogKiAgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIHRleHQgZmllbGQvZHJhdyBoYXMgJmx0O2V4RGF0YSZndDsgYXMgaXRzIHZhbHVlIHR5cGUgb3Igbm90LiBUaGlzIGlzIGV4cGVjdGVkIHRvIGJlIHRoZSBub2RlIG9uIHdoaWNoIHRoZSBhdHRyaWJ1dGUgd291bGQgYmUgc2V0IChpLmUuCiAqICB3aGVuIGF0dFRhZyBpcyAiYWxsb3dSaWNoVGV4dCIsIGNvbnRleHROb2RlIGlzIGV4cGVjdGVkIHRvIGJlIGEgJmx0O3RleHRFZGl0Jmd0OyBub2RlKS4KICogQHJldHVybiBUaGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIGF0dHJpYnV0ZSBvciBudWxsIGlmIHRoZSBhdHRyaWJ1dGUgaXMgdW5rbm93bi4gV2lsbCBhbHNvIHJldHVybiBudWxsIGlmIGNvbnRleHROb2RlIGlzIHNwZWNpZmllZCBidXQgY291bGQgbm90IGJlIHVzZWQKICogIHRvIGRldGVybWluZSB0aGUgYXBwcm9wcmlhdGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUuCiAqIEB0aHJvd3MgY29tLmFkb2JlLnhmYS54ZmF1dGlsLkVycm9yIEF0dHJpYnV0ZSBkZWZhdWx0IGNhbm5vdCBiZSBjb3JyZWN0bHkgZGV0ZXJtaW5lZCB3aXRob3V0IGJvdGggdGhlIGF0dHJpYnV0ZSB0YWcgYW5kIHRoZSBjb250ZXh0IG5vZGUuCiAqLwpYZmFTY2hlbWEuYXR0RGVmYXVsdCA9IGZ1bmN0aW9uIChhdHRUYWcsIGNvbnRleHROb2RlKSB7CiAgICBpZiAoIWF0dFRhZyB8fCAhY29udGV4dE5vZGUpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkF0dHJpYnV0ZSBkZWZhdWx0IGNhbm5vdCBiZSBjb3JyZWN0bHkgZGV0ZXJtaW5lZCB3aXRob3V0IGJvdGggdGhlIGF0dHJpYnV0ZSB0YWcgYW5kIHRoZSBjb250ZXh0IG5vZGUuIik7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLy8gVE9ETzogU0NIRU1BIFZBTElEQVRJT046IEV2ZW50dWFsbHksIHdlJ2xsIG5lZWQgdG8gdmFsaWRhdGUgdGhhdCB0aGUgYXR0cmlidXRlIHNvdWdodCBpcyB2YWxpZCBvbiB0aGUgZ2l2ZW4gY29udGV4dCBub2RlLgogICAgdmFyIGRlZiA9IG51bGw7CiAgICBzd2l0Y2ggKGF0dFRhZykgewogICAgICAgIC8vIE5PVEU6IEFuIGF1dG8tZ2VuZXJhdGVkIChmcm9tIFhURydzIG1haW4gY29kZSBiYXNlKSBYRkEgc3BlYyBzaG91bGQgYmUgYXZhaWxhYmxlIGhlcmUgZm9yIHJlZmVyZW5jZToKICAgICAgICAvLyBodHRwOi8veHRnd2luMS5jYW4uYWRvYmUuY29tL21haW5fYnVpbGQveHRnL2RvY3Mvc2NoZW1hL3RlbXBsYXRlLXN5bnRheC5odG1sCgogICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgICAgICAvLyBpbiBhbHBoYWJldGljYWwgb3JkZXIKICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAgICAgY2FzZSBYZmFBdHQuQUNUSVZJVFk6CiAgICAgICAgICAgIGRlZiA9IFhmYVZhbC5DTElDSzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuQVNQRUNUOgogICAgICAgICAgICBkZWYgPSBYZmFWYWwuRklUOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5BTExPV1JJQ0hURVhUOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuX2dldEFsbG93UmljaFRleHREZWZhdWx0KGNvbnRleHROb2RlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuQk9UVE9NSU5TRVQ6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPICsgWGZhU2NoZW1hLkRFRkFVTFRVTklUUzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuQ09NTUlUT046CiAgICAgICAgICAgIGRlZiA9IFhmYVZhbC5TRUxFQ1Q7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LkNPTlRFTlRUWVBFOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuX2dldENvbnRlbnRUeXBlRGVmYXVsdChjb250ZXh0Tm9kZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Lkg6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPICsgWGZhU2NoZW1hLkRFRkFVTFRVTklUUzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuSFJFRjoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLkNEQVRBOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5JRDoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlhNTElEOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5JTlRBQ1Q6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5fZ2V0SW50YWN0RGVmYXVsdChjb250ZXh0Tm9kZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LkxBWU9VVDoKICAgICAgICAgICAgZGVmID0gWGZhVmFsLlBPU0lUSU9OOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5MRUZUSU5TRVQ6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPICsgWGZhU2NoZW1hLkRFRkFVTFRVTklUUzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuTE9ORzoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlpFUk8gKyBYZmFTY2hlbWEuREVGQVVMVFVOSVRTOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5NQVJHSU5MRUZUOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Lk1BUkdJTlJJR0hUOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Lk1BVENIOgogICAgICAgICAgICBkZWYgPSBYZmFWYWwuT05DRTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuTUFYQ0hBUlM6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5NQVhIOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Lk1BWExFTkdUSDoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLk1JTlVTT05FOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5NQVhXOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Lk1JTkg6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPICsgWGZhU2NoZW1hLkRFRkFVTFRVTklUUzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuTUlOVzoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlpFUk8gKyBYZmFTY2hlbWEuREVGQVVMVFVOSVRTOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5NVUxUSUxJTkU6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5fZ2V0TXVsdGlMaW5lRGVmYXVsdChjb250ZXh0Tm9kZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Lk5BTUU6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5YTUxJRDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuT1BFTjoKICAgICAgICAgICAgZGVmID0gWGZhVmFsLlVTRVJDT05UUk9MOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5PUklFTlRBVElPTjoKICAgICAgICAgICAgZGVmID0gWGZhVmFsLlBPUlRSQUlUOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5QQUdFUE9TSVRJT046CiAgICAgICAgICAgIGRlZiA9IFhmYVZhbC5BTlk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlBMQUNFTUVOVDoKICAgICAgICAgICAgZGVmID0gWGZhVmFsLkxFRlQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlBSRVNFTkNFOgogICAgICAgICAgICBkZWYgPSBYZmFWYWwuVklTSUJMRTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuUkVGOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuQ0RBVEE7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlJFTEFUSU9OOgogICAgICAgICAgICBkZWYgPSBYZmFWYWwuT1JERVJFRE9DQ1VSUkVOQ0U7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlJFU0VSVkU6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5NSU5VU09ORTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuUklHSFRJTlNFVDoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlpFUk8gKyBYZmFTY2hlbWEuREVGQVVMVFVOSVRTOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5SVU5BVDoKICAgICAgICAgICAgZGVmID0gWGZhVmFsLkNMSUVOVDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuU0FWRToKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlpFUk87CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlNIT1JUOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlNJWkU6CiAgICAgICAgICAgIGRlZiA9ICIxMCIgKyBYZmFTY2hlbWEuVU5JVFBPSU5UOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5TUEFDRUFCT1ZFOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlNQQUNFQkVMT1c6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPICsgWGZhU2NoZW1hLkRFRkFVTFRVTklUUzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuU1RPQ0s6CiAgICAgICAgICAgIGRlZiA9IFhmYVZhbC5MRVRURVI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlNUUk9LRToKICAgICAgICAgICAgZGVmID0gWGZhVmFsLlNPTElEOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5URVhURU5UUlk6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5UT1BJTlNFVDoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlpFUk8gKyBYZmFTY2hlbWEuREVGQVVMVFVOSVRTOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5UWVBFRkFDRToKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLkRFRkFVTFRGT05UOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5VU0U6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5DREFUQTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuVVNFSFJFRjoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLkNEQVRBOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5WQUxJR046CiAgICAgICAgICAgIGRlZiA9IFhmYVZhbC5UT1A7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlZBTFVFOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuQkxBQ0s7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LldFSUdIVDoKICAgICAgICAgICAgZGVmID0gWGZhVmFsLk5PUk1BTDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuVzoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlpFUk8gKyBYZmFTY2hlbWEuREVGQVVMVFVOSVRTOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5YOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Llk6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPICsgWGZhU2NoZW1hLkRFRkFVTFRVTklUUzsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFdpbmRvdy5jb25zb2xlLmVycm9yKCJubyBkZWZhdWx0IGF0dHJpYnV0ZSB2YWx1ZSBmb3IgJyIgKyBhdHRUYWcgKyAiJyB0YWciKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gZGVmOwp9OwoKLyoqCiAqIFJldHVybnMgdGhlIGRlZmF1bHQgY2hpbGQgZWxlbWVudCBjbGFzcyBuYW1lIGdpdmVuIGEgdGFnIHRoYXQgY29udGFpbnMgYSBvbmUtb2YgZWxlbWVudCBwcm9wZXJ0eS4KICogPHA+Rm9yIGV4YW1wbGUsIHRoZSA8Y29kZT4vL2ZpZWxkL3VpPC9jb2RlPiBlbGVtZW50IGNvbnRhaW5zIGEgb25lLW9mIHByb3BlcnR5IHdoaWNoIHNwZWNpZmllcyB0aGUgZmllbGQncyBVSSB0eXBlIGZvciB3aGljaCB0aGUgZGVmYXVsdCBpcyA8Y29kZT50ZXh0RmllbGQ8L2NvZGU+LgogKiAgVGhlcmVmb3JlLCBjYWxsaW5nIDxjb2RlPm9uZU9mRGVmYXVsdCgmbHQ7ZmllbGQmZ3Q7Jmx0O3VpLyZndDsmbHQ7L2ZpZWxkJmd0Oyk8L2NvZGU+IHdvdWxkIHJldHVybiBYZmFFbGVtLlRFWFRGSUVMRC48L3A+CiAqIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB3aG9zZSBvbmUtb2YgcHJvcGVydHkgZGVmYXVsdCBpcyBzb3VnaHQuCiAqIEByZXR1cm4gQW4gWEZBIGVsZW1lbnQgbmFtZSwgZnJvbSBYZmFFbGVtLCB3aGljaCBpZGVudGlmaWVzIHRoZSBjbGFzcyBuYW1lIG9mIHRoZSBkZWZhdWx0IG9uZS1vZiBwcm9wZXJ0eSBvZiB0aGUgY29udGV4dCBub2RlLiBSZXR1cm5zIG51bGwgaWYgbm8gZGVmYXVsdCBpcyBkZWZpbmVkLgogKiAgVG8gZGV0ZXJtaW5lIGlmIHRoZSBhbiBlbGVtZW50IGhhcyBhIG9uZS1vZiBwcm9wZXJ0eSwgeW91IHNob3VsZCB1c2UgWGZhU2NoZW1hLmhhc09uZU9mUHJvcCgpLgogKiBAc2VlIGNvbS5hZG9iZS54ZmEuWGZhRWxlbQogKiBAc2VlICNoYXNPbmVPZlByb3AoKQogKiBAdGhyb3dzIGNvbS5hZG9iZS54ZmEueGZhdXRpbC5FcnJvciBPbmUtb2YgZGVmYXVsdCBjYW5ub3QgYmUgY29ycmVjdGx5IGRldGVybWluZWQgd2l0aG91dCB0aGUgY29udGV4dCBub2RlLgogKi8KWGZhU2NoZW1hLm9uZU9mRGVmYXVsdCA9IGZ1bmN0aW9uIChjb250ZXh0Tm9kZSkgewogICAgaWYgKCFjb250ZXh0Tm9kZSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiT25lLW9mIGRlZmF1bHQgY2Fubm90IGJlIGNvcnJlY3RseSBkZXRlcm1pbmVkIHdpdGhvdXQgdGhlIGNvbnRleHQgbm9kZS4iKTsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIHZhciBkZWYgPSBudWxsOwogICAgc3dpdGNoIChjb250ZXh0Tm9kZS5jbGFzc05hbWUpIHsKICAgICAgICAvLyBOT1RFOiBBbiBhdXRvLWdlbmVyYXRlZCAoZnJvbSBYVEcncyBtYWluIGNvZGUgYmFzZSkgWEZBIHNwZWMgc2hvdWxkIGJlIGF2YWlsYWJsZSBoZXJlIGZvciByZWZlcmVuY2U6CiAgICAgICAgLy8gaHR0cDovL3h0Z3dpbjEuY2FuLmFkb2JlLmNvbS9tYWluX2J1aWxkL3h0Zy9kb2NzL3NjaGVtYS90ZW1wbGF0ZS1zeW50YXguaHRtbAoKICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAgICAgLy8gaW4gYWxwaGFiZXRpY2FsIG9yZGVyCiAgICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogICAgICAgIGNhc2UgWGZhRWxlbS5FVkVOVDoKICAgICAgICAgICAgZGVmID0gWGZhRWxlbS5TQ1JJUFQ7CiAgICAgICAgICAgIGJyZWFrOyAvLyBubyBhY3R1YWwgZGVmYXVsdCAtLSBvdXIgZGVmYXVsdCwgYXMgdGhlICJYRkEgYXBwbGljYXRpb24iIGlzIDxzY3JpcHQ+IChtYXRjaGVzIFhURyBkZWZhdWx0KQogICAgICAgIGNhc2UgWGZhRWxlbS5GSUxMOgogICAgICAgICAgICBkZWYgPSBYZmFFbGVtLlNPTElEOwogICAgICAgICAgICBicmVhazsgLy8gbm8gYWN0dWFsIGRlZmF1bHQgLS0gb3VyIGRlZmF1bHQsIGFzIHRoZSAiWEZBIGFwcGxpY2F0aW9uIiBpcyA8c29saWQ+IChtYXRjaGVzIFhURyBkZWZhdWx0KQogICAgICAgIGNhc2UgWGZhRWxlbS5VSToKICAgICAgICAgICAgZGVmID0gWGZhRWxlbS5URVhURURJVDsKICAgICAgICAgICAgYnJlYWs7IC8vIG5vIGFjdHVhbCBkZWZhdWx0IC0tIG91ciBkZWZhdWx0LCBhcyB0aGUgIlhGQSBhcHBsaWNhdGlvbiIgaXMgPHRleHRFZGl0PiAobWF0Y2hlcyBYVEcgZGVmYXVsdCkKICAgICAgICBjYXNlIFhmYUVsZW0uVkFMVUU6CiAgICAgICAgICAgIGRlZiA9IFhmYUVsZW0uVEVYVDsKICAgICAgICAgICAgYnJlYWs7IC8vIG5vIGFjdHVhbCBkZWZhdWx0IC0tIG91ciBkZWZhdWx0LCBhcyB0aGUgIlhGQSBhcHBsaWNhdGlvbiIgaXMgPHRleHQ+IChtYXRjaGVzIFhURyBkZWZhdWx0KQoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB3aW5kb3cuY29uc29sZS5lcnJvcigibm8gZGVmYXVsdCBvbmUtb2YgZWxlbWVudCBwcm9wZXJ0eSBmb3IgJyIgKyBjb250ZXh0Tm9kZS5jbGFzc05hbWUgKyAiJyB0YWciKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gZGVmOwp9OwoKLyoqCiAqIERldGVybWluZXMgaWYgdGhlIHNwZWNpZmllZCBYRkEgZWxlbWVudCBoYXMgYSBvbmUtb2YgcHJvcGVydHkuCiAqIEBwYXJhbSBlbGVtVGFnIFRoZSBYRkEgZWxlbWVudCB0byBjaGVjayBmb3IgYSBvbmUtb2YgcHJvcGVydHkuCiAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgWEZBIGVsZW1lbnQgaGFzIGEgb25lLW9mIHByb3BlcnR5OyBmYWxzZSBpZiBub3QuCiAqLwpYZmFTY2hlbWEuaGFzT25lT2ZQcm9wID0gZnVuY3Rpb24gKGVsZW1UYWcpIHsKICAgIHZhciBoYXNPbmVPZiA9IGZhbHNlOwoKICAgIHN3aXRjaCAoZWxlbVRhZykgewogICAgICAgIC8vIE5PVEU6IEFuIGF1dG8tZ2VuZXJhdGVkIChmcm9tIFhURydzIG1haW4gY29kZSBiYXNlKSBYRkEgc3BlYyBzaG91bGQgYmUgYXZhaWxhYmxlIGhlcmUgZm9yIHJlZmVyZW5jZToKICAgICAgICAvLyBodHRwOi8veHRnd2luMS5jYW4uYWRvYmUuY29tL21haW5fYnVpbGQveHRnL2RvY3Mvc2NoZW1hL3RlbXBsYXRlLXN5bnRheC5odG1sCgogICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgICAgICAvLyBpbiBhbHBoYWJldGljYWwgb3JkZXIKICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAgICAgY2FzZSBYZmFFbGVtLkVWRU5UOgogICAgICAgIGNhc2UgWGZhRWxlbS5GSUxMOgogICAgICAgIGNhc2UgWGZhRWxlbS5VSToKICAgICAgICBjYXNlIFhmYUVsZW0uVkFMVUU6CiAgICAgICAgICAgIGhhc09uZU9mID0gdHJ1ZTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gaGFzT25lT2Y7Cn07CgovKioKICogRGV0ZXJtaW5lcyBpZiB0aGUgc3BlY2lmaWVkIFhGQSBlbGVtZW50IGNsYXNzIG5hbWUgaXMgYSBvbmUtb2YgcHJvcGVydHkgb2YgdGhlIHNwZWNpZmllZCBjb250ZXh0IG5vZGUuCiAqIDxwPkZvciBleGFtcGxlLCBjYWxsaW5nIDxjb2RlPmlzT25lT2ZQcm9wKFhmYUVsZW0uVEVYVEVESVQsICZsdDtmaWVsZCZndDsmbHQ7dWkvJmd0OyZsdDsvZmllbGQmZ3Q7KTwvY29kZT4gd291bGQgcmV0dXJuIHRydWUuPC9wPgogKiBAcGFyYW0gZWxlbVRhZyBUaGUgWEZBIGVsZW1lbnQgY2xhc3MgbmFtZSwgZnJvbSBYZmFFbGVtLCB3aGljaCBpcyB0aGUgdGFnIHRvIHRlc3QgYXMgYSBvbmUtb2YgcHJvcGVydHkgb2YgdGhlIGNvbnRleHQgbm9kZS4KICogQHBhcmFtIGNvbnRleHROb2RlIFRoZSBYRkEgbm9kZSB0aGF0IHByb3ZpZGVzIGNvbnRleHQgdG8gdGhlIHRlc3Qgc2luY2Ugc29tZSBlbGVtZW50cyBtYXkgYmUgb25lLW9mIHByb3BlcnRpZXMgb2Ygc29tZSBvdGhlciBlbGVtZW50cyB3aGlsZQogKiAgdGhleSBtYXkgbm90IGJlIG9mIG90aGVycy4gRm9yIGV4YW1wbGUsIHRoZSAmbHQ7dGV4dCZndDsgZWxlbWVudCBpcyBhIG9uZS1vZiBwcm9wZXJ0eSBvZiAmbHQ7dmFsdWUmZ3Q7IGJ1dCBhIDEvbiBwcm9wZXJ0eSBvZiAmbHQ7dmFyaWFibGVzJmd0Oy4KICogQHRocm93cyBjb20uYWRvYmUueGZhLnhmYXV0aWwuRXJyb3IgT25lLW9mIHByb3BlcnR5IGNhbm5vdCBiZSBjb3JyZWN0bHkgaWRlbnRpZmllZCB3aXRob3V0IHRoZSBlbGVtZW50IHRhZyBhbmQgdGhlIGNvbnRleHQgbm9kZS4KICovClhmYVNjaGVtYS5pc09uZU9mUHJvcCA9IGZ1bmN0aW9uIChlbGVtVGFnLCBjb250ZXh0Tm9kZSkgewogICAgaWYgKCFlbGVtVGFnIHx8ICFjb250ZXh0Tm9kZSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiT25lLW9mIHByb3BlcnR5IGNhbm5vdCBiZSBjb3JyZWN0bHkgaWRlbnRpZmllZCB3aXRob3V0IHRoZSBlbGVtZW50IHRhZyBhbmQgdGhlIGNvbnRleHQgbm9kZS4iKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgdmFyIGlzT25lT2YgPSBmYWxzZTsKCiAgICBzd2l0Y2ggKGNvbnRleHROb2RlLmNsYXNzTmFtZSkgewogICAgICAgIC8vIE5PVEU6IEFuIGF1dG8tZ2VuZXJhdGVkIChmcm9tIFhURydzIG1haW4gY29kZSBiYXNlKSBYRkEgc3BlYyBzaG91bGQgYmUgYXZhaWxhYmxlIGhlcmUgZm9yIHJlZmVyZW5jZToKICAgICAgICAvLyBodHRwOi8veHRnd2luMS5jYW4uYWRvYmUuY29tL21haW5fYnVpbGQveHRnL2RvY3Mvc2NoZW1hL3RlbXBsYXRlLXN5bnRheC5odG1sCgogICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgICAgICAvLyBpbiBhbHBoYWJldGljYWwgb3JkZXIKICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAgICAgY2FzZSBYZmFFbGVtLkVWRU5UOiB7CiAgICAgICAgICAgIHN3aXRjaCAoZWxlbVRhZykgewogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkVYRUNVVEU6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uU0NSSVBUOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLlNJR05EQVRBOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLlNVQk1JVDoKICAgICAgICAgICAgICAgICAgICBpc09uZU9mID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgWGZhRWxlbS5GSUxMOiB7CiAgICAgICAgICAgIHN3aXRjaCAoZWxlbVRhZykgewogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkxJTkVBUjoKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5QQVRURVJOOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLlJBRElBTDoKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5TT0xJRDoKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5TVElQUExFOgogICAgICAgICAgICAgICAgICAgIGlzT25lT2YgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBYZmFFbGVtLlVJOiB7CiAgICAgICAgICAgIHN3aXRjaCAoZWxlbVRhZykgewogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkJBUkNPREU6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uQlVUVE9OOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkNIRUNLQlVUVE9OOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkNIT0lDRUxJU1Q6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uREFURVRJTUVFRElUOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkRFRkFVTFRVSToKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5FWE9CSkVDVDoKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5JTUFHRUVESVQ6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uTlVNRVJJQ0VESVQ6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uUEFTU1dPUkRFRElUOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLlNJR05BVFVSRToKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5URVhURURJVDoKICAgICAgICAgICAgICAgICAgICBpc09uZU9mID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgWGZhRWxlbS5WQUxVRTogewogICAgICAgICAgICBzd2l0Y2ggKGVsZW1UYWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5BUkM6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uQk9PTEVBTjoKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5EQVRFOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkRBVEVUSU1FOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkRFQ0lNQUw6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uRVhEQVRBOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkZMT0FUOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLklNQUdFOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkxJTkU6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uUkVDVEFOR0xFOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLlRFWFQ6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uVElNRToKICAgICAgICAgICAgICAgICAgICBpc09uZU9mID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gaXNPbmVPZjsKfTsKCi8qKgogKiBEZXRlcm1pbmVzIGlmIHRoZSBzcGVjaWZpZWQgWEZBIGVsZW1lbnQgY29udGFpbnMgQ0RBVEEgb3IgUENEQVRBIGNvbnRlbnQuIElmIGl0IGRvZXMsIGl0IG1lYW5zIHRoZSBub2RlIGRvZXMgbm90IGNvbnRhaW4gYW55IFhGQSBlbGVtZW50cy4KICogQHBhcmFtIGVsZW1UYWcgVGhlIFhGQSBlbGVtZW50IHRvIGNoZWNrIGZvciBDREFUQSBjb250ZW50LgogKiBAcmV0dXJuIFRydWUgaWYgdGhlIFhGQSBlbGVtZW50IGhhcyBDREFUQSBjb250ZW50OyBmYWxzZSBpZiBub3QuCiAqLwpYZmFTY2hlbWEuY29udGFpbnNDRGF0YSA9IGZ1bmN0aW9uIChlbGVtVGFnKSB7CiAgICB2YXIgaGFzQ0RhdGEgPSBmYWxzZTsKICAgIHN3aXRjaCAoZWxlbVRhZykgewogICAgICAgIGNhc2UgWGZhRWxlbS5BUFBFQVJBTkNFRklMVEVSOgogICAgICAgIGNhc2UgWGZhRWxlbS5CT09MRUFOOgogICAgICAgIGNhc2UgWGZhRWxlbS5DRVJUSUZJQ0FURToKICAgICAgICBjYXNlIFhmYUVsZW0uREFURToKICAgICAgICBjYXNlIFhmYUVsZW0uREFURVRJTUU6CiAgICAgICAgY2FzZSBYZmFFbGVtLkRFQ0lNQUw6CiAgICAgICAgY2FzZSBYZmFFbGVtLkRJR0VTVE1FVEhPRDoKICAgICAgICBjYXNlIFhmYUVsZW0uRU5DT0RJTkc6CiAgICAgICAgY2FzZSBYZmFFbGVtLkVYREFUQToKICAgICAgICBjYXNlIFhmYUVsZW0uRkxPQVQ6CiAgICAgICAgY2FzZSBYZmFFbGVtLkhBTkRMRVI6CiAgICAgICAgY2FzZSBYZmFFbGVtLklNQUdFOgogICAgICAgIGNhc2UgWGZhRWxlbS5JTlRFR0VSOgogICAgICAgIGNhc2UgWGZhRWxlbS5MT0NLRE9DVU1FTlQ6CiAgICAgICAgY2FzZSBYZmFFbGVtLk9JRDoKICAgICAgICBjYXNlIFhmYUVsZW0uUElDVFVSRToKICAgICAgICBjYXNlIFhmYUVsZW0uUkVBU09OOgogICAgICAgIGNhc2UgWGZhRWxlbS5SRUY6CiAgICAgICAgY2FzZSBYZmFFbGVtLlNDUklQVDoKICAgICAgICBjYXNlIFhmYUVsZW0uU1BFQUs6CiAgICAgICAgY2FzZSBYZmFFbGVtLlNVQkpFQ1RETjoKICAgICAgICBjYXNlIFhmYUVsZW0uVEVYVDoKICAgICAgICBjYXNlIFhmYUVsZW0uVElNRToKICAgICAgICBjYXNlIFhmYUVsZW0uVE9PTFRJUDoKICAgICAgICAgICAgaGFzQ0RhdGEgPSB0cnVlOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICByZXR1cm4gaGFzQ0RhdGE7Cn07CgovKioKICogUmV0dXJucyB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgWGZhQXR0LkFMTE9XUklDSFRFWFQuIFJldHVybnMgbnVsbCBpZiB0aGVyZSBpc24ndCBlbm91Z2ggY29udGV4dC4KICogQHRocm93cyBjb20uYWRvYmUueGZhLnhmYXV0aWwuRXJyb3IgQ29udGV4dCBub2RlIG11c3QgYmUgc3BlY2lmaWVkLgogKiBAdGhyb3dzIGNvbS5hZG9iZS54ZmEueGZhdXRpbC5FcnJvciBBdHRyaWJ1dGUgaXMgbm90IHZhbGlkIG9uIHRoZSBzcGVjaWZpZWQgY29udGV4dCBub2RlLgogKi8KWGZhU2NoZW1hLl9nZXRBbGxvd1JpY2hUZXh0RGVmYXVsdCA9IGZ1bmN0aW9uIChjb250ZXh0Tm9kZSkgewogICAgaWYgKCFjb250ZXh0Tm9kZSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiQ29udGV4dCBub2RlIG11c3QgYmUgc3BlY2lmaWVkIGluIG9yZGVyIHRvIGRldGVybWluZSAiICsgWGZhQXR0LkFMTE9XUklDSFRFWFQgKyAiIGRlZmF1bHQuIik7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgaWYgKGNvbnRleHROb2RlLmNsYXNzTmFtZSAhPSBYZmFFbGVtLlRFWFRFRElUKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFhmYUF0dC5BTExPV1JJQ0hURVhUICsgIiBpcyBub3QgYSB2YWxpZCBhdHRyaWJ1dGUgb24gY29udGV4dCBub2RlIDwiICsgY29udGV4dE5vZGUuY2xhc3NOYW1lICsgIj4uIik7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLy8gQWN0dWFsIGRlZmF1bHQgZGVwZW5kcyBvbiAvL3ZhbHVlL3t0ZXh0fGV4RGF0YX0KCiAgICAvLyBnZXQgPHVpPiBub2RlCiAgICB2YXIgcGFyZW50ID0gY29udGV4dE5vZGUucGFyZW50OwogICAgaWYgKCFwYXJlbnQpIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvLyBnZXQgZmllbGQvZHJhdyBub2RlCiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50OwogICAgaWYgKCFwYXJlbnQgfHwgKCEocGFyZW50IGluc3RhbmNlb2YgWGZhRmllbGQpICYmICEocGFyZW50IGluc3RhbmNlb2YgWGZhRHJhdykpKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgaWYgKChwYXJlbnQgaW5zdGFuY2VvZiBYZmFGaWVsZCAmJiBwYXJlbnQudmFsdWVUeXBlID09IFhmYUVsZW0uRVhEQVRBKSB8fAogICAgICAgIChwYXJlbnQgaW5zdGFuY2VvZiBYZmFEcmF3ICYmIHBhcmVudC52YWx1ZVR5cGUgPT0gWGZhRWxlbS5FWERBVEEpKSB7CiAgICAgICAgcmV0dXJuIFhmYVNjaGVtYS5PTkU7CiAgICB9CiAgICByZXR1cm4gWGZhU2NoZW1hLlpFUk87Cn07CgovKioKICogUmV0dXJucyB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgWGZhQXR0LkNPTlRFTlRUWVBFLgogKiBAdGhyb3dzIGNvbS5hZG9iZS54ZmEueGZhdXRpbC5FcnJvciBDb250ZXh0IG5vZGUgbXVzdCBiZSBzcGVjaWZpZWQuCiAqIEB0aHJvd3MgY29tLmFkb2JlLnhmYS54ZmF1dGlsLkVycm9yIEF0dHJpYnV0ZSBpcyBub3QgdmFsaWQgb24gdGhlIHNwZWNpZmllZCBjb250ZXh0IG5vZGUuCiAqLwpYZmFTY2hlbWEuX2dldENvbnRlbnRUeXBlRGVmYXVsdCA9IGZ1bmN0aW9uIChjb250ZXh0Tm9kZSkgewogICAgaWYgKCFjb250ZXh0Tm9kZSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiQ29udGV4dCBub2RlIG11c3QgYmUgc3BlY2lmaWVkIGluIG9yZGVyIHRvIGRldGVybWluZSAiICsgWGZhQXR0LkNPTlRFTlRUWVBFICsgIiBkZWZhdWx0LiIpOwogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHN3aXRjaCAoY29udGV4dE5vZGUuY2xhc3NOYW1lKSB7CiAgICAgICAgY2FzZSBYZmFFbGVtLkVYREFUQToKICAgICAgICAgICAgcmV0dXJuIFhmYU1pbWVUeXBlLlBMQUlOVEVYVDsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgWGZhRWxlbS5JTUFHRToKICAgICAgICAgICAgcmV0dXJuIFhmYVNjaGVtYS5DREFUQTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgWGZhRWxlbS5TQ1JJUFQ6CiAgICAgICAgICAgIHJldHVybiBYZmFWYWwuQVBQWEZPUk1DQUxDOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICB0aHJvdyBuZXcgRXJyb3IoWGZhQXR0LkNPTlRFTlRUWVBFICsgIiBpcyBub3QgYSB2YWxpZCBhdHRyaWJ1dGUgb24gY29udGV4dCBub2RlIDwiICsgY29udGV4dE5vZGUuY2xhc3NOYW1lICsgIj4uIik7CiAgICByZXR1cm4gbnVsbDsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHZhbHVlIGZvciBYZmFBdHQuSU5UQUNULgogKiBAdGhyb3dzIGNvbS5hZG9iZS54ZmEueGZhdXRpbC5FcnJvciBDb250ZXh0IG5vZGUgbXVzdCBiZSBzcGVjaWZpZWQuCiAqIEB0aHJvd3MgY29tLmFkb2JlLnhmYS54ZmF1dGlsLkVycm9yIEF0dHJpYnV0ZSBpcyBub3QgdmFsaWQgb24gdGhlIHNwZWNpZmllZCBjb250ZXh0IG5vZGUuCiAqLwpYZmFTY2hlbWEuX2dldEludGFjdERlZmF1bHQgPSBmdW5jdGlvbiAoY29udGV4dE5vZGUpIHsKICAgIGlmICghY29udGV4dE5vZGUpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkNvbnRleHQgbm9kZSBtdXN0IGJlIHNwZWNpZmllZCBpbiBvcmRlciB0byBkZXRlcm1pbmUgIiArIFhmYUF0dC5JTlRBQ1QgKyAiIGRlZmF1bHQuIik7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgaWYgKGNvbnRleHROb2RlLmNsYXNzTmFtZSAhPSBYZmFFbGVtLktFRVApIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoWGZhQXR0LklOVEFDVCArICIgaXMgbm90IGEgdmFsaWQgYXR0cmlidXRlIG9uIGNvbnRleHQgbm9kZSA8IiArIGNvbnRleHROb2RlLmNsYXNzTmFtZSArICI+LiIpOwogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8vIEZyb20gdGhlIFhGQSBTY2hlbWE6IFdoZW4gdGhlIHBhcmVudCBjb250YWluZXIgaXMgYSBzdWJmb3JtIGFuZCB0aGUgc3ViZm9ybSdzIGxheW91dCBpcyBmbG93aW5nIG9yIHRhYmxlIHRoZSBkZWZhdWx0IHZhbHVlIGlzIG5vbmUuCiAgICAvLyAgV2hlbiB0aGUgcGFyZW50IHN1YmZvcm0ncyBsYXlvdXQgaXMgcG9zaXRpb25lZCBvciByb3cgdGhlIGRlZmF1bHQgdmFsdWUgaXMgY29udGVudEFyZWEuIEhvd2V2ZXIgd2hlbiB0aGUgcGFyZW50IGNvbnRhaW5lciBpcyBhIGRyYXcKICAgIC8vICB0aGUgZGVmYXVsdCBpcyBhbHdheXMgY29udGVudEFyZWEgYW5kIHdoZW4gdGhlIHBhcmVudCBpcyBhIGZpZWxkIHRoZSBkZWZhdWx0IGlzIGFsd2F5cyBub25lLgoKICAgIHZhciBwYXJlbnQgPSBjb250ZXh0Tm9kZS5wYXJlbnQ7CgogICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFhmYVN1YmZvcm0pIHsKICAgICAgICB2YXIgbGF5b3V0ID0gcGFyZW50LmdldFByb3BlcnR5KG51bGwsICJAIiArIFhmYUF0dC5MQVlPVVQpOwogICAgICAgIHN3aXRjaCAobGF5b3V0KSB7CiAgICAgICAgICAgIGNhc2UgWGZhVmFsLlRCOgogICAgICAgICAgICBjYXNlIFhmYVZhbC5MUlRCOgogICAgICAgICAgICBjYXNlIFhmYVZhbC5STFRCOgogICAgICAgICAgICBjYXNlIFhmYVZhbC5UQUJMRToKICAgICAgICAgICAgICAgIHJldHVybiBYZmFWYWwuTk9ORTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBYZmFWYWwuUE9TSVRJT046CiAgICAgICAgICAgIGNhc2UgWGZhVmFsLlJPVzoKICAgICAgICAgICAgICAgIHJldHVybiBYZmFWYWwuQ09OVEVOVEFSRUE7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvLyBpbnZhbGlkIGxheW91dCBhdHRyaWJ1dGUgdmFsdWUKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAocGFyZW50IGluc3RhbmNlb2YgWGZhRmllbGQpIHsKICAgICAgICByZXR1cm4gWGZhVmFsLk5PTkU7CiAgICB9IGVsc2UgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFhmYURyYXcpIHsKICAgICAgICByZXR1cm4gWGZhVmFsLkNPTlRFTlRBUkVBOwogICAgfQoKICAgIC8vIHVuYWJsZSB0byBkZXRlcm1pbmUgZGVmYXVsdCBmcm9tIGNvbnRleHQgbm9kZQogICAgcmV0dXJuIG51bGw7Cn07CgovKioKICogUmV0dXJucyB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgWGZhQXR0Lk1VTFRJTElORS4KICogQHRocm93cyBjb20uYWRvYmUueGZhLnhmYXV0aWwuRXJyb3IgQ29udGV4dCBub2RlIG11c3QgYmUgc3BlY2lmaWVkLgogKiBAdGhyb3dzIGNvbS5hZG9iZS54ZmEueGZhdXRpbC5FcnJvciBBdHRyaWJ1dGUgaXMgbm90IHZhbGlkIG9uIHRoZSBzcGVjaWZpZWQgY29udGV4dCBub2RlLgogKi8KWGZhU2NoZW1hLl9nZXRNdWx0aUxpbmVEZWZhdWx0ID0gZnVuY3Rpb24gKGNvbnRleHROb2RlKSB7CiAgICBpZiAoIWNvbnRleHROb2RlKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJDb250ZXh0IG5vZGUgbXVzdCBiZSBzcGVjaWZpZWQgaW4gb3JkZXIgdG8gZGV0ZXJtaW5lICIgKyBYZmFBdHQuQUxMT1dSSUNIVEVYVCArICIgZGVmYXVsdC4iKTsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBpZiAoY29udGV4dE5vZGUuY2xhc3NOYW1lICE9IFhmYUVsZW0uVEVYVEVESVQpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoWGZhQXR0Lk1VTFRJTElORSArICIgaXMgbm90IGEgdmFsaWQgYXR0cmlidXRlIG9uIGNvbnRleHQgbm9kZSA8IiArIGNvbnRleHROb2RlLmNsYXNzTmFtZSArICI+LiIpOwogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8vIE9uZSBpcyB0aGUgdHJ1ZSBkZWZhdWx0IGJ1dCBhY3R1YWwgZGVmYXVsdCBkZXBlbmRzIG9uIC8vZmllbGQgdnMgLy9kcmF3IGNvbnRhaW5lciBlbGVtZW50IChzZWUgdGhlIHNwZWMpLgoKICAgIC8vIGdldCA8dWk+IG5vZGUKICAgIHZhciBwYXJlbnQgPSBjb250ZXh0Tm9kZS5wYXJlbnQ7CiAgICBpZiAoIXBhcmVudCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8vIGdldCA8ZmllbGQ+IG9yIDxkcmF3PiBub2RlCiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50OwoKICAgIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBYZmFGaWVsZCkgewogICAgICAgIHJldHVybiBYZmFTY2hlbWEuWkVSTzsKICAgIH0gZWxzZSBpZiAocGFyZW50IGluc3RhbmNlb2YgWGZhRHJhdykgewogICAgICAgIHJldHVybiBYZmFTY2hlbWEuT05FOwogICAgfQogICAgLy8gdW5hYmxlIHRvIGRldGVybWluZSBkZWZhdWx0IGZyb20gY29udGV4dCBub2RlCiAgICByZXR1cm4gbnVsbDsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKKGZ1bmN0aW9uIChucykgewogICAgdmFyIFhtbFV0aWwgPSBucy5YbWxVdGlsID0ge307CgogICAgWG1sVXRpbC5zZWxlY3RTaW5nbGVOb2RlID0gZnVuY3Rpb24gKHBhcmVudCwgbG9jYWxOYW1lLCBkZWVwLCBvY2N1cnJlbmNlKSB7CiAgICAgICAgZGVlcCA9IGRlZXAgIT09IHVuZGVmaW5lZCA/IGRlZXAgOiBmYWxzZTsKICAgICAgICBvY2N1cnJlbmNlID0gaXNOYU4ob2NjdXJyZW5jZSkgPyAwIDogb2NjdXJyZW5jZTsKICAgICAgICAvLyBSZXR1cm5zIHRoZSBmaXJzdCBjaGlsZCBub2RlIGZvdW5kIHdpdGggdGhlIGdpdmVuIGxvY2FsIG5hbWUuCiAgICAgICAgdmFyIGxpc3QgPSBYbWxVdGlsLnNlbGVjdE5vZGVzKHBhcmVudCwgbG9jYWxOYW1lLCBkZWVwKTsKICAgICAgICBpZiAobGlzdCAmJiBsaXN0Lmxlbmd0aCgpID4gb2NjdXJyZW5jZSkgewogICAgICAgICAgICByZXR1cm4gbGlzdFtvY2N1cnJlbmNlXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICB9OwogICAgWG1sVXRpbC5zZWxlY3ROb2RlcyA9IGZ1bmN0aW9uIChwYXJlbnQsIGxvY2FsTmFtZSwgZGVlcCwgYXR0cmlidXRlVmFsdWUsIGF0dHJpYnV0ZU5hbWUsIGJFeGFjdE1hdGNoKSB7CiAgICAgICAgZGVlcCA9IGRlZXAgIT09IHVuZGVmaW5lZCA/IGRlZXAgOiBmYWxzZTsKICAgICAgICBhdHRyaWJ1dGVWYWx1ZSA9IGF0dHJpYnV0ZVZhbHVlIHx8IG51bGw7CiAgICAgICAgYXR0cmlidXRlTmFtZSA9IGF0dHJpYnV0ZU5hbWUgfHwgIm5hbWUiOwogICAgICAgIGJFeGFjdE1hdGNoID0gYkV4YWN0TWF0Y2ggIT09IHVuZGVmaW5lZCA/IGJFeGFjdE1hdGNoIDogdHJ1ZTsKICAgICAgICBpZiAocGFyZW50ID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBYTUxMaXN0KCk7CiAgICAgICAgfQogICAgICAgIHZhciBmdWxsTGlzdDsKICAgICAgICBpZiAoZGVlcCkgewogICAgICAgICAgICBmdWxsTGlzdCA9IHBhcmVudC5kZXNjZW5kYW50cygpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZ1bGxMaXN0ID0gcGFyZW50LmVsZW1lbnRzKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdGhpcy5maWx0ZXJMaXN0KGZ1bGxMaXN0LCBsb2NhbE5hbWUsIGF0dHJpYnV0ZVZhbHVlLCBhdHRyaWJ1dGVOYW1lLCBiRXhhY3RNYXRjaCk7CiAgICB9OwogICAgWG1sVXRpbC5maWx0ZXJMaXN0ID0gZnVuY3Rpb24gKGZ1bGxMaXN0LCBsb2NhbE5hbWUsIGF0dHJpYnV0ZVZhbHVlLCBhdHRyaWJ1dGVOYW1lLCBiRXhhY3RNYXRjaCkgewogICAgICAgIGF0dHJpYnV0ZVZhbHVlID0gYXR0cmlidXRlVmFsdWUgfHwgbnVsbDsKICAgICAgICBhdHRyaWJ1dGVOYW1lID0gYXR0cmlidXRlTmFtZSB8fCAibmFtZSI7CiAgICAgICAgYkV4YWN0TWF0Y2ggPSBiRXhhY3RNYXRjaCAhPT0gdW5kZWZpbmVkID8gYkV4YWN0TWF0Y2ggOiB0cnVlOwogICAgICAgIHZhciBvTGlzdCA9IG5ldyBYTUxMaXN0KCk7CgogICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgaSA8IGZ1bGxMaXN0Lmxlbmd0aCgpOwogICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgIHZhciBlbGVtID0gZnVsbExpc3RbaV07CiAgICAgICAgICAgIGlmIChsb2NhbE5hbWUgPT0gbnVsbCB8fCAoZWxlbS5sb2NhbE5hbWUoKSAhPSBudWxsICYmIFN0cmluZyhlbGVtLmxvY2FsTmFtZSgpKSA9PSBsb2NhbE5hbWUpKSB7CiAgICAgICAgICAgICAgICAvLyBFbGVtZW50IG5hbWUgbWF0Y2hlcyAtIG5vdyBjaGVjayB0byBzZWUgaWYgYW4gYXR0cmlidXRlIG5lZWRzIHRvIGJlIG1hdGNoZWQgYXMgd2VsbC4KICAgICAgICAgICAgICAgIHZhciBiQWRkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVWYWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBhdHRyTWF0Y2ggPSBYbWxVdGlsLmdldEF0dHJpYnV0ZShlbGVtLCBhdHRyaWJ1dGVOYW1lKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWF0dHJNYXRjaCkgewogICAgICAgICAgICAgICAgICAgICAgICBiQWRkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJFeGFjdE1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ck1hdGNoICE9IGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9hdHRyaWJ1dGUgdmFsdWVzIGRvIG5vdCBtYXRjaAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJBZGQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyTWF0Y2guaW5kZXhPZihhdHRyaWJ1dGVWYWx1ZSkgPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2F0dHJpYnV0ZSB2YWx1ZSBub3QgZm91bmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiQWRkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoYkFkZCkgewogICAgICAgICAgICAgICAgICAgIC8vYWRkIHRvIGxpc3QKICAgICAgICAgICAgICAgICAgICBvTGlzdC5BcHBlbmQoZWxlbSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9MaXN0OwogICAgfTsKICAgIFhtbFV0aWwuZ2V0WG1sT2JqZWN0ID0gZnVuY3Rpb24gKHhtbG9iaiwgaWdub3JlV2hpdGUsIGlnbm9yZUNvbW1lbnRzLCBpZ25vcmVQSXMpIHsKICAgICAgICBpZ25vcmVXaGl0ZSA9IGlnbm9yZVdoaXRlICE9PSB1bmRlZmluZWQgPyBpZ25vcmVXaGl0ZSA6IGZhbHNlOwogICAgICAgIGlnbm9yZUNvbW1lbnRzID0gaWdub3JlQ29tbWVudHMgIT09IHVuZGVmaW5lZCA/IGlnbm9yZUNvbW1lbnRzIDogZmFsc2U7CiAgICAgICAgaWdub3JlUElzID0gaWdub3JlUElzICE9PSB1bmRlZmluZWQgPyBpZ25vcmVQSXMgOiBmYWxzZTsKICAgICAgICB2YXIgZWxlbSA9IG51bGw7CgogICAgICAgIGlmICgheG1sb2JqKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKHhtbG9iaiBpbnN0YW5jZW9mIFhNTExpc3QpIHsKICAgICAgICAgICAgaWYgKFhNTExpc3QoeG1sb2JqKS5sZW5ndGgoKSA+IDApIHsKICAgICAgICAgICAgICAgIGVsZW0gPSB4bWxvYmpbMF07CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKHhtbG9iaiBpbnN0YW5jZW9mIFhNTCkgewogICAgICAgICAgICBlbGVtID0geG1sb2JqOwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHhtbG9iaiA9PSAic3RyaW5nIikgewogICAgICAgICAgICAvLyBzYXZlIHNldHRpbmdzCiAgICAgICAgICAgIHZhciB4bWxTZXR0aW5ncyA9IFhNTC5zZXR0aW5ncygpOwoKICAgICAgICAgICAgLy8gYXBwbHkgb3VyIG93bgogICAgICAgICAgICBYTUwuaWdub3JlV2hpdGVzcGFjZSA9IGlnbm9yZVdoaXRlOwogICAgICAgICAgICBYTUwuaWdub3JlQ29tbWVudHMgPSBpZ25vcmVDb21tZW50czsKICAgICAgICAgICAgWE1MLmlnbm9yZVByb2Nlc3NpbmdJbnN0cnVjdGlvbnMgPSBpZ25vcmVQSXM7CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgZWxlbSA9IG5ldyBYTUwoeG1sb2JqKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgLy90cnkgd3JhcHBpbmcgd2l0aCBzb21lIHJvb3QgWE1MIG5vZGVzCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGVsZW0gPSBuZXcgWE1MKCI8cm9vdD4iICsgeG1sb2JqICsgIjwvcm9vdD4iKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICAvL3RoZSBzdHJpbmcgbXVzdCBjb250YWluIGluY29tcGxldGUgWE1MIHNvIHRoZXJlCiAgICAgICAgICAgICAgICAgICAgLy9pcyBubyB3YXkgdG8gY29udmVydCBpdCB0byBhbiBYTUwgb2JqZWN0CiAgICAgICAgICAgICAgICAgICAgZWxlbSA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHJlc3RvcmUgb3JpZ2luYWwgc2V0dGluZ3MKICAgICAgICAgICAgWE1MLnNldFNldHRpbmdzKHhtbFNldHRpbmdzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBlbGVtOwogICAgfTsKICAgIC8qKgogICAgICogQnVpbGRzIGEgcGF0aCBmcm9tIGEgc2VyaWVzIG9mIHN0cmluZyBhcmd1bWVudHMgYW5kIGNhbGxzIHNlbGVjdE5lc3RlZE5vZGUoKSB3aXRoIHRoZSByZXN1bHRpbmcgcGF0aC4KICAgICAqIDxwPlRoaXMgaXMgZXNwZWNpYWxseSB1c2VmdWwgd2hlbiB5b3UgaGF2ZSBzdHJpbmcgY29uc3RhbnRzIHRoYXQgeW91IG5lZWQgdG8gdXNlIGluc3RlYWQgb2YgaGFyZGNvZGVkCiAgICAgKiAgc3RyaW5ncy4gVHlwaW5nIDxjb2RlPmEsYixjPC9jb2RlPiBpcyBtdWNoIGVhc2llciB0aGFuIHR5cGluZyA8Y29kZT4iLyIgKyBDT05TVF9BICsgIi8iICsgQ09OU1RfQiArICIvIiArIENPTlNUX0M8L2NvZGU+LgogICAgICogIFdpdGggdGhpcyBmdW5jdGlvbiwgeW91IHNpbXBseSBjYWxsIDxjb2RlPnNlbGVjdEZyb21QYXRoKHBhcmVudFhtbCwgQ09OU1RfQSwgQ09OU1RfQiwgQ09OU1RfQyk7PC9jb2RlPjwvcD4KICAgICAqIEBwYXJhbSBwYXJlbnRYbWwgVGhlIGVsZW1lbnQgd2hvc2UgY2hpbGRyZW4gYW5kIGJleW9uZCB3aWxsIGJlIHNlYXJjaGVkLgogICAgICogIHBhcmFtIGFyZ3VtZW50cyBUaGUgc3RyaW5nIGFyZ3VtZW50cyB0aGF0IG1ha2UtdXAgdGhlIHBhdGguIFRoZSByZXN1bHQgaXMgaW4gdGhlIGZvcm0gb2YgPGNvZGU+Ii9hcmcxL2FyZzIvLi4uL2FyZ04iPC9jb2RlPi4gQXJncwogICAgICogIG5hbWVzIG1heSBiZSBxdWFsaWZpZWQgd2l0aCBhIG5hbWVzcGFjZSBwcmVmaXggYXMgaW4gPGNvZGU+InByZWZpeDE6bm9kZTEiLCAicHJlZml4Mjpub2RlMiIsICJub2RlMyI8L2NvZGU+LgogICAgICogQHJldHVybiBBbiBYTUwgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgbm9kZSByZWZlcmVuY2VkIGJ5IHRoZSBwYXRoIG9yIG51bGwgaWYgYSBtYXRjaCB3YXNuJ3QgbWFkZS4KICAgICAqIEBzZWUgI3NlbGVjdE5lc3RlZE5vZGUoKQogICAgICovCiAgICBYbWxVdGlsLnNlbGVjdEZyb21QYXRoID0gZnVuY3Rpb24gKHBhcmVudFhtbCkgewogICAgICAgIHBhcmVudFhtbCA9IGFyZ3VtZW50c1swXTsKICAgICAgICBpZiAoIXBhcmVudFhtbCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHZhciBwYXRoID0gIiI7CgogICAgICAgIGZvciAodmFyIGkgPSAxOwogICAgICAgICAgICAgaSA8IGFyZ3VtZW50cy5sZW5ndGg7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgcGF0aCArPSAiLyIgKyBhcmd1bWVudHNbaV0udG9TdHJpbmcoKTsKICAgICAgICB9CgogICAgICAgIGlmIChwYXRoKSB7CiAgICAgICAgICAgIHJldHVybiBYbWxVdGlsLnNlbGVjdE5lc3RlZE5vZGUocGFyZW50WG1sLCBwYXRoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfTsKICAgIFhtbFV0aWwuc2VsZWN0TmVzdGVkTm9kZSA9IGZ1bmN0aW9uIChvUGFyZW50RWxlbWVudCwgc1BhdGgpIHsKICAgICAgICBpZiAob1BhcmVudEVsZW1lbnQgPT0gbnVsbCB8fCBzUGF0aCA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNQYXRoLnN1YnN0cigwLCAxKSA9PSAiLyIpIHsgLy8gc3VwcG9ydCBvcHRpb25hbCBsZWFkaW5nICIvIgogICAgICAgICAgICBzUGF0aCA9IHNQYXRoLnN1YnN0cigxKTsKICAgICAgICB9CgogICAgICAgIHZhciB0b2tzID0gc1BhdGguc3BsaXQoIi8iKTsKCiAgICAgICAgaWYgKHRva3MubGVuZ3RoID4gMCkgewogICAgICAgICAgICB2YXIgdG9rID0gdG9rc1swXTsgLy8gaXMgZWl0aGVyICJuYW1lIiBvciAicHJlZml4Om5hbWUiCgogICAgICAgICAgICB2YXIgdG9rUGFydHMgPSB0b2suc3BsaXQoIjoiKTsgLy8gaGFuZGxlIG5hbWVzcGFjZSBwcmVmaXggaWYgc3BlY2lmaWVkCiAgICAgICAgICAgIHZhciB0b2tOc1ByZWZpeCA9ICh0b2tQYXJ0cy5sZW5ndGggPT0gMiA/IHRva1BhcnRzWzBdIDogbnVsbCk7CiAgICAgICAgICAgIHZhciB0b2tOYW1lID0gKHRva1BhcnRzLmxlbmd0aCA9PSAxID8gdG9rUGFydHNbMF0gOiAodG9rUGFydHMubGVuZ3RoID09IDIgPyB0b2tQYXJ0c1sxXSA6IG51bGwpKTsKICAgICAgICAgICAgaWYgKG51bGwgPT0gdG9rTmFtZSkgewogICAgICAgICAgICAgICAgRGVidWcuZXJyb3IoImludmFsaWQgdG9rZW46ICIgKyB0b2spOwogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBlbGVtTGlzdCA9IG9QYXJlbnRFbGVtZW50LmVsZW1lbnRzKCk7CiAgICAgICAgICAgIHZhciBpdGVtLCBpID0gMDsKICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICBpIDwgZWxlbUxpc3QubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgIGl0ZW0gPSBlbGVtTGlzdFtpXTsKICAgICAgICAgICAgICAgIGlmIChpdGVtLmxvY2FsTmFtZSgpID09IHRva05hbWUgJiYgKCF0b2tOc1ByZWZpeCB8fCBpdGVtLm5hbWVzcGFjZSh0b2tOc1ByZWZpeCkpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRva3MubGVuZ3RoID09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9Ob2RlID0gWG1sVXRpbC5zZWxlY3ROZXN0ZWROb2RlKGl0ZW0sIHNQYXRoLnN1YnN0cmluZyhzUGF0aC5pbmRleE9mKHRvaykgKyB0b2subGVuZ3RoICsgMSkpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAob05vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9Ob2RlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH07CiAgICBYbWxVdGlsLmRlY29kZVhtbENoYXJzID0gZnVuY3Rpb24gKHN0ciwgc3RyaWN0KSB7CiAgICAgICAgc3RyaWN0ID0gc3RyaWN0ICE9PSB1bmRlZmluZWQgPyBzdHJpY3QgOiBmYWxzZTsKICAgICAgICBpZiAoc3RyID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RyLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9CgogICAgICAgIHZhciBkZWMgPSBzdHI7IC8vIHRoZSBkZWNvZGVkIHN0cmluZwoKICAgICAgICBkZWMgPSBkZWMucmVwbGFjZShuZXcgUmVnRXhwKCImbHQ7IiwgImciKSwgIjwiKTsKICAgICAgICBkZWMgPSBkZWMucmVwbGFjZShuZXcgUmVnRXhwKCImZ3Q7IiwgImciKSwgIj4iKTsKCiAgICAgICAgaWYgKHN0cmljdCkgewogICAgICAgICAgICBkZWMgPSBkZWMucmVwbGFjZShuZXcgUmVnRXhwKCImYXBvczsiLCAiZyIpLCAiJyIpOwogICAgICAgICAgICBkZWMgPSBkZWMucmVwbGFjZShuZXcgUmVnRXhwKCImcXVvdDsiLCAiZyIpLCAiXCIiKTsKICAgICAgICB9CgogICAgICAgIGRlYyA9IGRlYy5yZXBsYWNlKG5ldyBSZWdFeHAoIiZhbXA7IiwgImciKSwgIiYiKTsgLy8gZG8gdGhpcyAqbGFzdCogc28gdGhhdCB0aGUgYW1wZXJzYW5kcyBpbiB0aGUgcHJldmlvdXMgY29kZXMgZG9uJ3QgZ2V0IGNvbnZlcnRlZC4uLgogICAgICAgIHJldHVybiBkZWM7CiAgICB9OwogICAgWG1sVXRpbC5lbmNvZGVYbWxDaGFycyA9IGZ1bmN0aW9uIChzdHIsIHN0cmljdCkgewogICAgICAgIHN0cmljdCA9IHN0cmljdCAhPT0gdW5kZWZpbmVkID8gc3RyaWN0IDogZmFsc2U7CiAgICAgICAgaWYgKHN0ciA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKHN0ci5sZW5ndGggPT0gMCkgewogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQoKICAgICAgICB2YXIgZW5jID0gc3RyOyAvLyBlbmNvZGVkIHN0cmluZwoKICAgICAgICBlbmMgPSBlbmMucmVwbGFjZShuZXcgUmVnRXhwKCImIiwgImciKSwgIiZhbXA7Iik7IC8vIGRvIHRoaXMgKmZpcnN0KiBzbyB0aGF0IHRoZSBhbXBlcnNhbmRzIGluIHRoZSBmb2xsb3dpbmcgaW5zZXJ0ZWQgY29kZXMgZG9uJ3QgZ2V0IGNvbnZlcnRlZC4uLgogICAgICAgIGVuYyA9IGVuYy5yZXBsYWNlKG5ldyBSZWdFeHAoIjwiLCAiZyIpLCAiJmx0OyIpOwogICAgICAgIGVuYyA9IGVuYy5yZXBsYWNlKG5ldyBSZWdFeHAoIj4iLCAiZyIpLCAiJmd0OyIpOwoKICAgICAgICBpZiAoc3RyaWN0KSB7CiAgICAgICAgICAgIGVuYyA9IGVuYy5yZXBsYWNlKG5ldyBSZWdFeHAoIiciLCAiZyIpLCAiJmFwb3M7Iik7CiAgICAgICAgICAgIGVuYyA9IGVuYy5yZXBsYWNlKG5ldyBSZWdFeHAoJyInLCAiZyIpLCAiJnF1b3Q7Iik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZW5jOwogICAgfTsKICAgIFhtbFV0aWwuZ2V0Tm9kZVRleHQgPSBmdW5jdGlvbiAoeG1sb2JqLCBkZWVwLCBkZWNvZGUpIHsKICAgICAgICBkZWVwID0gZGVlcCAhPT0gdW5kZWZpbmVkID8gZGVlcCA6IHRydWU7CiAgICAgICAgZGVjb2RlID0gZGVjb2RlICE9PSB1bmRlZmluZWQgPyBkZWNvZGUgOiB0cnVlOwogICAgICAgIHZhciBub2RlID0gWG1sVXRpbC5nZXRYbWxPYmplY3QoeG1sb2JqKTsKCiAgICAgICAgaWYgKCFub2RlKSB7CiAgICAgICAgICAgIGlmICh0eXBlb2YgeG1sb2JqID09ICJzdHJpbmciKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZGVjb2RlID8gWG1sVXRpbC5kZWNvZGVYbWxDaGFycyhTdHJpbmcoeG1sb2JqKSkgOiBTdHJpbmcoeG1sb2JqKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG5vZGUuaGFzU2ltcGxlQ29udGVudCgpKSB7CiAgICAgICAgICAgIC8vIGFsd2F5cyB1c2UgWE1MLnRvU3RyaW5nKCksIGV2ZW4gaWYgaXQgZGVjb2RlcyB3aGVuIHdlIG1pZ2h0IG5vdCB3YW50IGl0IHRvLCBiZWNhdXNlIGl0J2xsIGVuc3VyZSB0aGF0IHdlIGdldCBldmVyeXRoaW5nLCBpbmNsdWRpbmcgc3BhY2VzLAogICAgICAgICAgICAvLyAgZXZlbiBpZiB0aGUgY29udGVudCBvZiB0aGUgbm9kZSBpcyBvbmx5IHdoaXRlc3BhY2UKICAgICAgICAgICAgdmFyIHNpbXBsZUNvbnRlbnQgPSBub2RlLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIGlmICghZGVjb2RlKSB7CiAgICAgICAgICAgICAgICBzaW1wbGVDb250ZW50ID0gWG1sVXRpbC5lbmNvZGVYbWxDaGFycyhzaW1wbGVDb250ZW50KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHNpbXBsZUNvbnRlbnQ7CiAgICAgICAgfQoKICAgICAgICAvL2dldCBhbGwgdGhlIG5vZGUncyBjaGlsZHJlbgogICAgICAgIHZhciBjaGlsZE5vZGUsIHNUZXh0ID0gIiI7CiAgICAgICAgdmFyIGxpc3QgPSBub2RlLmNoaWxkcmVuKCk7CgogICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgaSA8IGxpc3QubGVuZ3RoKCk7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgY2hpbGROb2RlID0gbGlzdFtpXTsKICAgICAgICAgICAgc3dpdGNoIChjaGlsZE5vZGUubm9kZUtpbmQoKSkgewogICAgICAgICAgICAgICAgY2FzZSBYbWxVdGlsLk5PREVLSU5EX1RFWFQgOgogICAgICAgICAgICAgICAgICAgIHNUZXh0ICs9IChkZWNvZGUgPyBjaGlsZE5vZGUudG9TdHJpbmcoKSA6IGNoaWxkTm9kZS50b1hNTFN0cmluZygpKTsgLy8gWE1MLnRvU3RyaW5nKCkgZGVjb2RlcyBlbmNvZGVkIFhNTCBjaGFyYWN0ZXJzCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBYbWxVdGlsLk5PREVLSU5EX0VMRU1FTlQgOgogICAgICAgICAgICAgICAgICAgIGlmIChkZWVwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNUZXh0ICs9IFhtbFV0aWwuZ2V0Tm9kZVRleHQoY2hpbGROb2RlLCBkZWVwLCBkZWNvZGUpOyAvLyByZWN1cnNpdmUgY2FsbAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNUZXh0OwogICAgfTsKCiAgICBYbWxVdGlsLnNldE5vZGVUZXh0ID0gZnVuY3Rpb24gKG5vZGUsIHRleHQsIGtlZXBUZXh0LCBrZWVwRWxlbWVudHMsIGtlZXBDb21tZW50cywga2VlcFBJcykgewoKICAgICAgICBrZWVwVGV4dCA9IGtlZXBUZXh0ICE9PSB1bmRlZmluZWQgPyBrZWVwVGV4dCA6IGZhbHNlOwogICAgICAgIGtlZXBFbGVtZW50cyA9IGtlZXBFbGVtZW50cyAhPT0gdW5kZWZpbmVkID8ga2VlcEVsZW1lbnRzIDogZmFsc2U7CiAgICAgICAga2VlcENvbW1lbnRzID0ga2VlcENvbW1lbnRzICE9PSB1bmRlZmluZWQgPyBrZWVwQ29tbWVudHMgOiBmYWxzZTsKICAgICAgICBrZWVwUElzID0ga2VlcFBJcyAhPT0gdW5kZWZpbmVkID8ga2VlcFBJcyA6IGZhbHNlOwogICAgICAgIGlmICghbm9kZSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBCZWZvcmUgYXNzaWduaW5nIHRoZSBuZXcgY29kZSwgd2UgaGF2ZSB0byBleHRyYWN0IGFsbCBjaGlsZCBlbGVtZW50cyB3ZSB3YW50IHRvIHByZXNlcnZlCiAgICAgICAgLy8gIG90aGVyd2lzZSB0aGV5IHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBub2RlJ3MgY29udGVudC4gV2hpbGUgdGhleSBnZXQgcmVtb3ZlZCBmcm9tIHRoZQogICAgICAgIC8vICBjb250ZW50IGFmdGVyIHNldHRpbmcgdGhlIHRleHQsIHRoZSBub2RlcyB0aGVtc2VsdmVzIGRvbid0IGdldCBkZWxldGVkICh0aGV5IGp1c3QgZ2V0CiAgICAgICAgLy8gIGRlLXJlZmVyZW5jZWQsIEkgc3VwcG9zZSkgc28gdGhleSBjYW4gZWFzaWx5IGJlIHJlLWFkZGVkIGFzIGNoaWxkcmVuLgoKICAgICAgICB2YXIgY29udGVudCA9IGtlZXBUZXh0ID8gWG1sVXRpbC5nZXROb2RlVGV4dChub2RlLCBmYWxzZSkgOiAiIjsKICAgICAgICB2YXIgZWxlbWVudHMgPSBrZWVwRWxlbWVudHMgPyBub2RlLmVsZW1lbnRzKCkgOiBuZXcgWE1MTGlzdCgpOwogICAgICAgIHZhciBjb21tZW50cyA9IGtlZXBDb21tZW50cyA/IG5vZGUuY29tbWVudHMoKSA6IG5ldyBYTUxMaXN0KCk7CiAgICAgICAgdmFyIHBpcyA9IGtlZXBQSXMgPyBub2RlLnByb2Nlc3NpbmdJbnN0cnVjdGlvbnMoKSA6IG5ldyBYTUxMaXN0KCk7CgogICAgICAgIC8vIHJlbW92ZSBldmVyeXRoaW5nIChzYW1lIHRoaW5nIHlvdSB3b3VsZCBnZXQgaWYgeW91IHVzZWQgRTRYIHRvIGFzc2lnbiB0aGUgdGV4dCB2YWx1ZSB0byB0aGUgbm9kZSdzIGNvbnRlbnQpCiAgICAgICAgWG1sVXRpbC5yZW1vdmVDaGlsZHJlbihub2RlKTsKCiAgICAgICAgdmFyIHhtbFNldHRpbmdzID0gWE1MLnNldHRpbmdzKCk7CgogICAgICAgIFhNTC5pZ25vcmVXaGl0ZXNwYWNlID0gZmFsc2U7CiAgICAgICAgWE1MLmlnbm9yZUNvbW1lbnRzID0gZmFsc2U7CiAgICAgICAgWE1MLmlnbm9yZVByb2Nlc3NpbmdJbnN0cnVjdGlvbnMgPSBmYWxzZTsKCiAgICAgICAgLy8gc2V0IHRoZSB0ZXh0IGNvbnRlbnQgKGluIEU0WCwgZXZlbiB0aG91Z2ggdGhlcmUgYXJlIG5vIGNoaWxkcmVuLCB5b3UgY2FuIHN0aWxsIGFjY2VzcyB0aGUgZmlyc3QgY2hpbGQpCiAgICAgICAgaWYgKG51bGwgIT0gdGV4dCkgewogICAgICAgICAgICBub2RlLnNldENoaWxkcmVuKGNvbnRlbnQgKyB0ZXh0KTsKICAgICAgICB9CiAgICAgICAgLy9ub2RlLmNoaWxkcmVuKClbMF0gPSBjb250ZW50ICsgdGV4dDsgLy8gdGhlIFhNTCBjbGFzcyB3aWxsIGF1dG9tYXRpY2FsbHkgZW5jb2RlIGFueSBYTUwgY2hhcmFjdGVycyBpbiB0aGUgdGV4dCAoZXhjZXB0IGZvciBhcG9zdHJvcGhlcyBhbmQgcXVvdGF0aW9uIG1hcmtzKQoKICAgICAgICB2YXIgaSwgZSwgYywgcDsKICAgICAgICBmb3IgKGkgPSAwOwogICAgICAgICAgICAgaSA8IGVsZW1lbnRzLmxlbmd0aCgpOwogICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgIGUgPSBlbGVtZW50c1tpXTsKICAgICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChlLCB0cnVlKTsKICAgICAgICB9CiAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgIGkgPCBjb21tZW50cy5sZW5ndGg7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgYyA9IGNvbW1lbnRzW2ldOwogICAgICAgICAgICBub2RlLmFwcGVuZENoaWxkKGMsIHRydWUpOwogICAgICAgIH0KICAgICAgICBmb3IgKGkgPSAwOwogICAgICAgICAgICAgaSA8IHBpcy5sZW5ndGg7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgcCA9IHBpc1tpXTsKICAgICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChwLCB0cnVlKTsKICAgICAgICB9CgogICAgICAgIFhNTC5zZXRTZXR0aW5ncyh4bWxTZXR0aW5ncyk7CiAgICB9OwogICAgWG1sVXRpbC5yZW1vdmVDaGlsZHJlbiA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgWG1sVXRpbC5yZW1vdmVJdGVtcyhub2RlLmNoaWxkcmVuKCkpOwogICAgfTsKICAgIFhtbFV0aWwucmVtb3ZlTm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgaWYgKCFub2RlKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgdmFyIG5vZGVMaXN0ID0gbmV3IFhNTExpc3Qobm9kZSk7CiAgICAgICAgWG1sVXRpbC5yZW1vdmVJdGVtcyhub2RlTGlzdCk7CiAgICB9OwogICAgWG1sVXRpbC5yZW1vdmVJdGVtcyA9IGZ1bmN0aW9uIChpdGVtcykgewogICAgICAgIHZhciB4bWxMaXN0OwogICAgICAgIGlmIChpdGVtcyBpbnN0YW5jZW9mIFhNTCB8fCBpdGVtcyBpbnN0YW5jZW9mIFhNTExpc3QpIHsKICAgICAgICAgICAgeG1sTGlzdCA9IGl0ZW1zOwogICAgICAgIH0KICAgICAgICBpZiAodHlwZW9mIGl0ZW1zID09ICJzdHJpbmciKSB7CiAgICAgICAgICAgIHhtbExpc3QgPSBuZXcgWE1MKGl0ZW1zKTsKICAgICAgICB9CiAgICAgICAgaWYgKHhtbExpc3QpIHsKICAgICAgICAgICAgZm9yICh2YXIgaiA9IGl0ZW1zLmxlbmd0aCgpIC0gMTsKICAgICAgICAgICAgICAgICBqID49IDA7CiAgICAgICAgICAgICAgICAgai0tKSB7CiAgICAgICAgICAgICAgICBpdGVtcy5EZWxldGUoaik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwogICAgWG1sVXRpbC5nZXRQYXJlbnQgPSBmdW5jdGlvbiAobm9kZVhtbCkgewogICAgICAgIHJldHVybiAobm9kZVhtbCA/IFhtbFV0aWwuZ2V0WG1sT2JqZWN0KG5vZGVYbWwucGFyZW50KCkpIDogbnVsbCk7CiAgICB9OwogICAgLyoqCiAgICAgKiBTZXQgYW4gWE1MIG9iamVjdCdzIGF0dHJpYnV0ZSB2YWx1ZS4gVGhlIGF0dHJpYnV0ZSB3aWxsIGJlIHJlbW92ZWQKICAgICAqIHdoZW4gdGhlIHZhbHVlIGlzIG51bGwuCiAgICAgKi8KICAgIFhtbFV0aWwuc2V0QXR0cmlidXRlID0gZnVuY3Rpb24gKHhtbG9iaiwgbmFtZSwgdmFsdWUpIHsKICAgICAgICBpZiAoIXhtbG9iaiB8fCAhbmFtZSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICB2YXIgZWxlbSA9IFhtbFV0aWwuZ2V0WG1sT2JqZWN0KHhtbG9iaik7CiAgICAgICAgaWYgKGVsZW0gIT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgZWxlbS5QdXQoJ0AnICsgbmFtZSwgdmFsdWUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIGxpc3QgPSBlbGVtLmF0dHJpYnV0ZShuYW1lKTsKICAgICAgICAgICAgICAgIGlmIChsaXN0ICYmIGxpc3QubGVuZ3RoKCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGxpc3RbMF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBYTUwgb2JqZWN0J3MgYXR0cmlidXRlIHZhbHVlLiBBbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQgaWYgdGhlIGF0dHJpYnV0ZSBpcyBub3QgZm91bmQgdW5sZXNzIGFuIGV4aXN0ZW5jZSBjaGVjayBpcyBwZXJmb3JtZWQuCiAgICAgKiBAcGFyYW0geG1sb2JqCiAgICAgKiBAcGFyYW0gYXR0ck5hbWUgQ2FuIGJlIHRoZSBsb2NhbCBuYW1lIChubyBuYW1lc3BhY2UpIG9ubHkgb3IgYSBuYW1lc3BhY2UgcXVhbGlmaWVyIG1heSBiZSBzcGVjaWZpZWQgKGUuZy4gZWl0aGVyICJuYW1lIiBvciAibnM6bmFtZSIpLgogICAgICogQHBhcmFtIGV4aXN0ZW5jZUNoZWNrIElmIHRydWUsIG51bGwgaXMgcmV0dXJuZWQgd2hlbiB0aGUgYXR0cmlidXRlIGlzbid0IHNwZWNpZmllZCAocmF0aGVyIHRoYW4gYW4gZW1wdHkgc3RyaW5nKS4KICAgICAqLwogICAgWG1sVXRpbC5nZXRBdHRyaWJ1dGUgPSBmdW5jdGlvbiAoeG1sb2JqLCBhdHRyTmFtZSwgZXhpc3RlbmNlQ2hlY2spIHsKICAgICAgICBleGlzdGVuY2VDaGVjayA9IGV4aXN0ZW5jZUNoZWNrICE9PSB1bmRlZmluZWQgPyBleGlzdGVuY2VDaGVjayA6IGZhbHNlOwogICAgICAgIHZhciBlbGVtID0gWG1sVXRpbC5nZXRYbWxPYmplY3QoeG1sb2JqKTsKCiAgICAgICAgaWYgKGVsZW0gJiYgYXR0ck5hbWUpIHsKICAgICAgICAgICAgdmFyIHBhcnRzID0gYXR0ck5hbWUuc3BsaXQoIjoiKTsKICAgICAgICAgICAgdmFyIG5zUHJlZml4ID0gKHBhcnRzLmxlbmd0aCA9PSAyID8gcGFydHNbMF0gOiBudWxsKTsKICAgICAgICAgICAgdmFyIGxvY2FsTmFtZSA9IChwYXJ0cy5sZW5ndGggPT0gMSA/IHBhcnRzWzBdIDogKHBhcnRzLmxlbmd0aCA9PSAyID8gcGFydHNbMV0gOiBudWxsKSk7CiAgICAgICAgICAgIHZhciBhdHRyLCBlbGVtZW50QXR0cmlidXRlcyA9IGVsZW0uYXR0cmlidXRlcygpOwoKICAgICAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOwogICAgICAgICAgICAgICAgIGluZGV4IDwgZWxlbWVudEF0dHJpYnV0ZXMubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICAgaW5kZXgrKykgewogICAgICAgICAgICAgICAgYXR0ciA9IGVsZW1lbnRBdHRyaWJ1dGVzW2luZGV4XTsKICAgICAgICAgICAgICAgIGlmIChhdHRyLmxvY2FsTmFtZSgpID09IGxvY2FsTmFtZSAmJiAoIW5zUHJlZml4IHx8IGF0dHIuaW5TY29wZU5hbWVzcGFjZXMobnNQcmVmaXgpKSkgewogICAgICAgICAgICAgICAgICAgIC8vIEF0dHJpYnV0ZSBmb3VuZAogICAgICAgICAgICAgICAgICAgIHJldHVybiBhdHRyLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8gQXR0cmlidXRlIG5vdCBmb3VuZAogICAgICAgIHJldHVybiBleGlzdGVuY2VDaGVjayA/IG51bGwgOiAiIjsKICAgIH07CiAgICBYbWxVdGlsLmdldFBJWG1sID0gZnVuY3Rpb24gKHBhcmVudCwgZG9tYWluLCBrZXksIHZhbHVlKSB7CiAgICAgICAgdmFsdWUgPSB2YWx1ZSB8fCBudWxsOwogICAgICAgIGlmICghcGFyZW50IHx8ICFrZXkgfHwgIWRvbWFpbikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHZhciBwaUxpc3QgPSBwYXJlbnQucHJvY2Vzc2luZ0luc3RydWN0aW9ucygpOwogICAgICAgIHZhciBwaSA9IG51bGw7CgogICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgaSA8IHBpTGlzdC5sZW5ndGg7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgdmFyIHBpU3RyID0gcGlMaXN0W2ldLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIHZhciByZSA9IG5ldyBSZWdFeHAoWG1sVXRpbC5QSV9SRUdFWFAsIFhtbFV0aWwuUElfUkVHRVhQX0ZMQUdTKTsKICAgICAgICAgICAgdmFyIG1hdGNoZXMgPSByZS5leGVjKHBpU3RyKTsKCiAgICAgICAgICAgIC8vdG9kbwogICAgICAgICAgICBpZiAobWF0Y2hlcyAmJiBtYXRjaGVzLnBpRG9tYWluID09IGRvbWFpbiAmJiBtYXRjaGVzLnBpS2V5ID09IGtleSkgewogICAgICAgICAgICAgICAgaWYgKCF2YWx1ZSB8fCBtYXRjaGVzLnBpVmFsdWUgPT0gdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICBwaSA9IHBpTGlzdFtpXTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcGk7CiAgICB9OwoKICAgIFhtbFV0aWwuZ2V0UElYbWxQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKHBpKSB7CiAgICAgICAgaWYgKCFwaSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHZhciBwaVN0ciA9IHBpLnRvU3RyaW5nKCk7CiAgICAgICAgdmFyIHJlID0gbmV3IFJlZ0V4cChYbWxVdGlsLlBJX1JFR0VYUCwgWG1sVXRpbC5QSV9SRUdFWFBfRkxBR1MpOwogICAgICAgIHZhciBtYXRjaGVzID0gcmUuZXhlYyhwaVN0cik7CgogICAgICAgIGlmIChtYXRjaGVzKSB7CiAgICAgICAgICAgIHZhciBwcm9wcyA9IHt9OwogICAgICAgICAgICBwcm9wcy5kb21haW4gPSBtYXRjaGVzLnBpRG9tYWluOwogICAgICAgICAgICBwcm9wcy5rZXkgPSBtYXRjaGVzLnBpS2V5OwogICAgICAgICAgICBpZiAobWF0Y2hlcy5waVZhbHVlKSB7CiAgICAgICAgICAgICAgICBwcm9wcy52YWx1ZSA9IG1hdGNoZXMucGlWYWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcHJvcHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfTsKCiAgICAvKioKICAgICAqIFNlYXJjaGVzIHRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBvbiB0aGUgc3BlY2lmaWVkIG5vZGUgZm9yIGEgUEkgdGhhdCBoYXMgYSBtYXRjaGluZyBkb21haW4gYW5kIGtleS4gSWYgYSB2YWx1ZSBpcyBwcm92aWRlZCwgdGhlIHZhbHVlIHdpbGwgYmUgbWF0Y2hlZCBhcyB3ZWxsLgogICAgICogIFRoZSBzZWFyY2ggaXMgY2FzZS1zZW5zaXRpdmUuCiAgICAgKiBAcGFyYW0gcGFyZW50IFhNTCBub2RlIHRoYXQgY29udGFpbnMgdGhlIFBJcyB0byBiZSBzZWFyY2hlZC4KICAgICAqIEBwYXJhbSBwaSBEeW5hbWljIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczogImRvbWFpbiIgKFJlcXVpcmVkL1N0cmluZywgdGhlIFBJJ3MgZG9tYWluKSwgImtleSIgKFJlcXVpcmVkL1N0cmluZywgdGhlIFBJJ3Mga2V5KS4KICAgICAqIEBwYXJhbSB2YWx1ZU1hdGNoIE9wdGlvbmFsIHZhbHVlIHRvIG1hdGNoIGFzIHdlbGwuIElmIHNwZWNpZmllZCwgYSAmbHQ7P2RvbWFpbiBrZXkgdmFsdWVNYXRjaD8mZ3Q7IFBJIG11c3QgZXhpc3QgZm9yIHRoZSBzZWFyY2ggdG8gc3VjY2VlZC4gU3BlY2lmeWluZwogICAgICogIGFuIGVtcHR5IHN0cmluZyBmb3IgdGhpcyBwYXJhbWV0ZXIgd2lsbCB5aWVsZCB0aGUgc2FtZSByZXN1bHRzIGFzIHNwZWNpZnlpbmcgbnVsbC4KICAgICAqIEByZXR1cm4gVGhlIFBJJ3MgdmFsdWUgKGNvdWxkIGJlIGFuIGVtcHR5IHN0cmluZykgaWYgYSBtYXRjaGluZyBQSSB3YXMgbG9jYXRlZCwgbnVsbCBvdGhlcndpc2UuCiAgICAgKi8KICAgIFhtbFV0aWwuZmluZFBJT2JqID0gZnVuY3Rpb24gKHBhcmVudCwgcGksIHZhbHVlTWF0Y2gpIHsKICAgICAgICB2YWx1ZU1hdGNoID0gdmFsdWVNYXRjaCB8fCBudWxsOwogICAgICAgIGlmICghcGFyZW50KSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFwaS5oYXNPd25Qcm9wZXJ0eSgiZG9tYWluIikgfHwgIXBpLmhhc093blByb3BlcnR5KCJrZXkiKSkgewogICAgICAgICAgICBEZWJ1Zy5lcnJvcigibWlzc2luZyByZXF1aXJlZCBwcm9wZXJ0aWVzIGluIHBpIG9iamVjdDogJ2RvbWFpbicgYW5kICdrZXknIik7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgdmFyIHBpWG1sID0gWG1sVXRpbC5nZXRQSVhtbChwYXJlbnQsIHBpLmRvbWFpbiwgcGkua2V5LCB2YWx1ZU1hdGNoKTsKICAgICAgICBpZiAocGlYbWwpIHsKICAgICAgICAgICAgcmV0dXJuIFhtbFV0aWwuZ2V0UElYbWxWYWx1ZShwaVhtbCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH07CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgJmx0Oz9kb21haW4ga2V5IHZhbHVlPyZndDsgUEkuIFRoZSB2YWx1ZSBtYXkgY29udGFpbiAob3IgYmUpIHdoaXRlc3BhY2UgYnV0IHRoZSBkb21haW4gYW5kIGtleSBtdXN0IG5vdC4KICAgICAqIEBwYXJhbSBwaSBYTUwgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgUEkgd2hvc2UgdmFsdWUgaXMgdG8gYmUgcmV0dXJuZWQuCiAgICAgKiBAcmV0dXJuIFRoZSBQSSdzIHZhbHVlIGFzIGEgc3RyaW5nLiBJZiB0aGUgUEkgZG9lc24ndCBoYXZlIGEgdmFsdWUsIGFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZC4gSWYgdGhlIFBJIGRvZXNuJ3QgaGF2ZSBhIGRvbWFpbiBhbmQga2V5LCBudWxsIGlzIHJldHVybmVkLgogICAgICovCiAgICBYbWxVdGlsLmdldFBJWG1sVmFsdWUgPSBmdW5jdGlvbiAocGkpIHsKICAgICAgICBpZiAoIXBpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICB2YXIgcHJvcHMgPSBYbWxVdGlsLmdldFBJWG1sUHJvcGVydGllcyhwaSk7CiAgICAgICAgaWYgKHByb3BzKSB7CiAgICAgICAgICAgIHJldHVybiBwcm9wcy5oYXNPd25Qcm9wZXJ0eSgidmFsdWUiKSA/IHByb3BzLnZhbHVlIDogIiI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH07CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhICZsdDs/ZG9tYWluIGtleSB2YWx1ZT8mZ3Q7IFBJLiBUaGUgdmFsdWUgbWF5IGNvbnRhaW4gKG9yIGJlKSB3aGl0ZXNwYWNlIGJ1dCB0aGUgZG9tYWluIGFuZCBrZXkgbXVzdCBub3QuCiAgICAgKiBAcGFyYW0gcGkgWE1MIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIFBJIHdob3NlIHZhbHVlIGlzIHRvIGJlIHJldHVybmVkLgogICAgICogQHJldHVybiBUaGUgUEkncyB2YWx1ZSBhcyBhIHN0cmluZy4gSWYgdGhlIFBJIGRvZXNuJ3QgaGF2ZSBhIHZhbHVlLCBhbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQuIElmIHRoZSBQSSBkb2Vzbid0IGhhdmUgYSBkb21haW4gYW5kIGtleSwgbnVsbCBpcyByZXR1cm5lZC4KICAgICAqLwogICAgWG1sVXRpbC5nZXRQSVhtbFZhbHVlZnVuY3Rpb24gPSBmdW5jdGlvbiAocGkpIHsKICAgICAgICBpZiAoIXBpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICB2YXIgcHJvcHMgPSBYbWxVdGlsLmdldFBJWG1sUHJvcGVydGllcyhwaSk7CiAgICAgICAgaWYgKHByb3BzKSB7CiAgICAgICAgICAgIHJldHVybiBwcm9wcy5oYXNPd25Qcm9wZXJ0eSgidmFsdWUiKSA/IHByb3BzLnZhbHVlIDogIiI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH07CgogICAgLyoqCiAgICAgKiBEZXRlcm1pbmVzIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgbm9kZSAobmFtZXNwYWNlIDxiPnByZWZpeDwvYj4gYWRkZWQgaWYgdGhlIG5vZGUgaGFzIGEgbmFtZXNwYWNlKS4gVGhpcyBkaWZmZXJzIGZyb20gdGhlIFFOYW1lIG9iamVjdAogICAgICogIHdoaWNoIHByaW50cyBVUkk6OmxvY2FsTmFtZSAocHJpbnRzIHRoZSBVUkkgcmF0aGVyIHRoYW4gdGhlIHByZWZpeCBhbmQgdXNlcyBkb3VibGUgY29sb25zIHJhdGhlciB0aGFuIGEgc2luZ2xlKS4KICAgICAqIEBwYXJhbSBub2RlWG1sIFRoZSBub2RlIHdob3NlIHF1YWxpZmllZCBuYW1lIGlzIHRvIGJlIHByaW50ZWQuCiAgICAgKiBAcmV0dXJuIFRoZSBxdWFsaWZpZWQgbmFtZSAoaW5jbHVkZXMgbmFtZXNwYWNlIHByZWZpeCBpZiBub2RlIGhhcyBuYW1lc3BhY2UpIG9yIGVtcHR5IHN0cmluZyBpZiBub2RlIGlzIG51bGwgb3IgaXNuJ3QgYW4gZWxlbWVudCBvciBhdHRyaWJ1dGUuCiAgICAgKi8KICAgIFhtbFV0aWwucXVhbGlmaWVkTmFtZSA9IGZ1bmN0aW9uIChub2RlWG1sKSB7CiAgICAgICAgaWYgKCFub2RlWG1sIHx8IChub2RlWG1sLm5vZGVLaW5kKCkgIT0gWG1sVXRpbC5OT0RFS0lORF9FTEVNRU5UICYmIG5vZGVYbWwubm9kZUtpbmQoKSAhPSBYbWxVdGlsLk5PREVLSU5EX0FUVFJJQlVURSkpIHsKICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0KCiAgICAgICAgdmFyIG5hbWUgPSAiIjsKICAgICAgICB2YXIgbnMgPSBub2RlWG1sLm5hbWVzcGFjZSgpOwoKICAgICAgICBpZiAobnMpIHsKICAgICAgICAgICAgaWYgKHR5cGVvZiBucy5wcmVmaXggPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICAgICAgICAgIC8vIEl0IHNlZW1zIHRoYXQgdGhlcmUgYXJlIGNhc2VzIHdoZW4gYW4gZWxlbWVudCBvciBhdHRyaWJ1dGUgbWF5IGhhdmUgYSBuYW1lc3BhY2UgcHJlZml4IGJ1dCB0aGUgbmFtZXNwYWNlIGlzbid0IGRlZmluZWQgYW55d2hlcmUgaW4gdGhlIFhNTCBkb2N1bWVudC4KICAgICAgICAgICAgICAgIC8vICBTdHJhbmdlIGJ1dCB0cnVlLiBQZXJoYXBzIGl0J3MgT0sgd2hlbiB0aGUgbmFtZXNwYWNlIHByZWZpeCBpcyBhIHdlbGwta25vdyBwcmVmaXggbGlrZSAieG1sIiB3aGljaCBpcyB3aHkgdGhlIE5hbWVzcGFjZSBvYmplY3QsIGluIHRoYXQgY2FzZSwKICAgICAgICAgICAgICAgIC8vICBjb250YWlucyBhbiB1bmRlZmluZWQgcHJlZml4IGJ1dCBtYW5hZ2VzIHRvIHByb2R1Y2UgYSB1cmkgb2YgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIuCiAgICAgICAgICAgICAgICAvLyBFeGFtcGxlOiBJbiBhbiBYTVAgcGFja2V0IGluc2lkZSBhbiBYRFAsIHlvdSdsbCBmaW5kIDxyZGY6bGkgeG1sOmxhbmc9IngtZGVmYXVsdCI+e3RpdGxlfTwvcmRmOmxpPiB3aGVyZSAieG1sIiBpcyBub3QgZGVmaW5lZCBpbiB0aGUgWERQIGRvYy4KICAgICAgICAgICAgICAgIGlmIChucy51cmkgPT0gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIpIHsKICAgICAgICAgICAgICAgICAgICBuYW1lICs9ICJ4bWw6IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmIChucy5wcmVmaXggIT0gIiIpIHsKICAgICAgICAgICAgICAgIG5hbWUgKz0gbnMucHJlZml4ICsgIjoiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIG5hbWUgKz0gbm9kZVhtbC5sb2NhbE5hbWUoKTsKICAgICAgICByZXR1cm4gbmFtZTsKICAgIH07CgogICAgLyoqCiAgICAgKiBQcmludHMgdGhlIGF0dHJpYnV0ZXMgc3BlY2lmaWVkIG9uIHRoZSBYTUwgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlWG1sIFRoZSBlbGVtZW50IHdob3NlIGF0dHJpYnV0ZXMgYXJlIHRvIGJlIHByaW50ZWQuCiAgICAgKiBAcmV0dXJuIFRoZSBwcmludGVkIHZlcnNpb24gb2YgdGhlIFhNTCBub2RlJ3MgYXR0cmlidXRlcywgYWxsIG9uIGEgc2luZ2xlIGxpbmUuIElmIHRoZSBub2RlIGhhcyBubyBhdHRyaWJ1dGVzLCBhbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQuCiAgICAgKi8KICAgIFhtbFV0aWwuX3ByaW50WG1sQXR0cmlidXRlcyA9IGZ1bmN0aW9uIChub2RlWG1sKSB7CiAgICAgICAgaWYgKCFub2RlWG1sIHx8IG5vZGVYbWwubm9kZUtpbmQoKSAhPSBYbWxVdGlsLk5PREVLSU5EX0VMRU1FTlQpIHsKICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0KCiAgICAgICAgdmFyIHByaW50ID0gIiI7CiAgICAgICAgdmFyIGF0dExpc3QgPSBub2RlWG1sLmF0dHJpYnV0ZXMoKTsKCiAgICAgICAgZm9yICh2YXIgaSA9IDA7CiAgICAgICAgICAgICBpIDwgYXR0TGlzdC5sZW5ndGgoKTsKICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICB2YXIgYXR0WG1sID0gYXR0TGlzdFtpXTsKICAgICAgICAgICAgaWYgKHByaW50Lmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIHByaW50ICs9ICIgIjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpbnQgKz0gWG1sVXRpbC5xdWFsaWZpZWROYW1lKGF0dFhtbCk7CiAgICAgICAgICAgIC8vIHN0cmljdD10cnVlIGluIHRoZSBmb2xsb3dpbmcgZW5jb2RpbmcgZnVuY3Rpb24gc28gdGhhdCBpdCBlbmNvZGVzIGZvciBhbGwgZml2ZSBjaGFyYWN0ZXJzICgmLCcsIiw8LD4pCiAgICAgICAgICAgIC8vIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdG9TdHJpbmcoKSBmdW5jdGlvbiBkZWNvZGVzIGFsbCBmaXZlIGNoYXJhY3RlcnMuCiAgICAgICAgICAgIHZhciB2YWx1ZSA9IG51bGw7CiAgICAgICAgICAgIGlmIChhdHRYbWwpIHsKICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYXR0WG1sLnRvWE1MU3RyaW5nID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBhdHRYbWwudG9YTUxTdHJpbmcoKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBhdHRYbWwudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCArPSAnPSInICsgWG1sVXRpbC5lbmNvZGVYbWxDaGFycyhYbWxVdGlsLmRlY29kZVhtbENoYXJzKHZhbHVlLCB0cnVlKSwgdHJ1ZSkgKyAnIic7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwcmludDsKICAgIH07CgogICAgLyoqCiAgICAgKiBQcmludHMgYW4gWE1MIGVsZW1lbnQuCiAgICAgKiBAcGFyYW0gbm9kZVhtbCBUaGUgZWxlbWVudCB0byBwcmludC4KICAgICAqIEBwYXJhbSBpbmRlbnRTdHIgVGhlIGluZGVudGF0aW9uIHN0cmluZyB0byBwcmVwZW5kIHRvIHRoZSBwcmludGVkIG91dHB1dC4KICAgICAqIEBwYXJhbSBwcmludE9wZW4gVHJ1ZSBpZiB0aGUgb3BlbmluZyBvZiB0aGUgZWxlbWVudCBzaG91bGQgYmUgcHJpbnRlZDsgZmFsc2UgaWYgdGhlIGNsb3Npbmcgc2hvdWxkIGJlIHByaW50ZWQuIElmIHRydWUgYW5kIHRoZSBub2RlCiAgICAgKiAgaGFzIG5vIGNoaWxkcmVuLCB0aGUgbm9kZSBpcyBwcmludGVkIGFzIGEgY2xvc2VkIGVsZW1lbnQgKGUuZy4gJmx0O2VsZW0vJmd0OykuCiAgICAgKiBAcmV0dXJuIFRoZSBwcmludGVkIHZlcnNpb24gb2YgdGhlIFhNTCBlbGVtZW50LiBJZiB0aGUgbm9kZSBpcyBudWxsLCBhbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQuCiAgICAgKi8KICAgIFhtbFV0aWwuX3ByaW50WG1sRWxlbWVudCA9IGZ1bmN0aW9uIChub2RlWG1sLCBpbmRlbnRTdHIsIHByaW50T3BlbikgewogICAgICAgIGlmICghbm9kZVhtbCB8fCBub2RlWG1sLm5vZGVLaW5kKCkgIT0gWG1sVXRpbC5OT0RFS0lORF9FTEVNRU5UKSB7CiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9CiAgICAgICAgdmFyIHByaW50ID0gIjwiOwogICAgICAgIGlmICghcHJpbnRPcGVuKSB7CiAgICAgICAgICAgIHByaW50ICs9ICIvIjsKICAgICAgICB9CiAgICAgICAgLy8gLS0gcHJpbnQgdGhlIHF1YWxpZmllZCBuYW1lCiAgICAgICAgcHJpbnQgKz0gWG1sVXRpbC5xdWFsaWZpZWROYW1lKG5vZGVYbWwpOwoKICAgICAgICBpZiAocHJpbnRPcGVuKSB7CgogICAgICAgICAgICAvL0FkZGluZyBkZWZhdWx0IG5hbWVzcGFjZQogICAgICAgICAgICB2YXIgbnMgPSBub2RlWG1sLl9EZWZhdWx0TmFtZXNwYWNlOwogICAgICAgICAgICBpZiAobnMgJiYgbnMudXJpICYmIFhtbFV0aWwucXVhbGlmaWVkTmFtZShub2RlWG1sKSA9PSAiYm9keSIpIHsKICAgICAgICAgICAgICAgIHByaW50ICs9ICIgeG1sbnM9XCIiICsgbnMudXJpICsgIlwiICI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHByaW50IHRoZSBvcGVuaW5nIG9mIHRoZSBlbGVtZW50CiAgICAgICAgICAgIC8vIC0tIHByaW50IHRoZSBuYW1lc3BhY2VzCiAgICAgICAgICAgIC8vIHRoaXMgd2lsbCBsaXN0IG9ubHkgbmV3IG5hbWVzcGFjZXM7IGluLXNjb3BlIG5hbWVzcGFjZXMgd2lsbCBub3QgYmUgaW4gdGhpcyBsaXN0CiAgICAgICAgICAgIHZhciBuc0xpc3QgPSBub2RlWG1sLm5hbWVzcGFjZURlY2xhcmF0aW9ucygpOwogICAgICAgICAgICB2YXIgbnNTY29wZUxpc3QgPSBub2RlWG1sLmluU2NvcGVOYW1lc3BhY2VzKCk7CgogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsKICAgICAgICAgICAgICAgICBpIDwgbnNMaXN0Lmxlbmd0aDsKICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBucyA9IG5zTGlzdFtpXTsKICAgICAgICAgICAgICAgIC8vIGFkZCBuYW1lc3BhY2UgZGVjbGFyYXRpb24KICAgICAgICAgICAgICAgIHByaW50ICs9ICIgeG1sbnMiOwogICAgICAgICAgICAgICAgLy8gY2hlY2sgZm9yIGRlZmF1bHQgbmFtZXNwYWNlCiAgICAgICAgICAgICAgICBpZiAobnMucHJlZml4ICE9ICIiKSB7CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgKz0gIjoiICsgbnMucHJlZml4OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcHJpbnQgKz0gJz0iJyArIG5zLnVyaSArICciJzsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyAtLSBwcmludCB0aGUgYXR0cmlidXRlcwogICAgICAgICAgICB2YXIgYXR0cyA9IFhtbFV0aWwuX3ByaW50WG1sQXR0cmlidXRlcyhub2RlWG1sKTsKICAgICAgICAgICAgaWYgKGF0dHMubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgcHJpbnQgKz0gIiAiICsgYXR0czsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyAtLSBwb3N0Zml4CiAgICAgICAgICAgIC8vIGlmIG5vIGNoaWxkcmVuLCBjbG9zZSB0aGUgbm9kZQogICAgICAgICAgICBpZiAobm9kZVhtbC5jaGlsZHJlbigpLmxlbmd0aCgpID09IDApIHsKICAgICAgICAgICAgICAgIHByaW50ICs9ICIvIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCArPSAiPiI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gcHJpbnQgdGhlIGNsb3Npbmcgb2YgdGhlIGVsZW1lbnQKICAgICAgICAgICAgcHJpbnQgKz0gIj4iOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW5kZW50U3RyICsgcHJpbnQ7CiAgICB9OwoKICAgIC8qKgogICAgICogUmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBYbWxVdGlsLnByaW50KCkuCiAgICAgKiBAcGFyYW0gbm9kZVhtbCBUaGUgWE1MIG5vZGUgdG8gcHJpbnQuCiAgICAgKiBAcGFyYW0gb3B0aW9ucyBQcmludCBvcHRpb25zLiBFeHBlY3RlZCBwcm9wZXJ0aWVzIGFyZSBhcyBmb2xsb3dzOgogICAgICogIDxwPnByZXR0eTogQm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gcHJldHR5LXByaW50IG9yIG5vdC48L3A+CiAgICAgKiAgPHA+aW5kZW50OiBpbnQgc3BlY2lmeWluZyB0aGUgZGVwdGggdG8gaW5kZW50IHdoZW4gcHJldHR5LXByaW50aW5nLjwvcD4KICAgICAqICA8cD5sZXZlbDogaW50IHNwZWNpZnlpbmcgdGhlIGN1cnJlbnQgbGV2ZWwgb2YgcmVjdXJzaW9uLjwvcD4KICAgICAqICA8cD5maWx0ZXI6IEZ1bmN0aW9uIHRvIGNhbGwgdG8gZmlsdGVyIG5vZGVzLiBDYW4gYmUgbnVsbC48L3A+CiAgICAgKiBAcmV0dXJuIFRoZSBwcmludGVkIHZlcnNpb24gb2YgdGhlIFhNTCBub2RlIChjb3VsZCBiZSBhbiBlbXB0eSBzdHJpbmcpLiBOdWxsIGlmIHRoZSBub2RlIHdhcyBmaWx0ZXJlZC1vdXQuIEVtcHR5IHN0cmluZyBpZiBub2RlWG1sIHdhcyBudWxsLgogICAgICogQHNlZSAjcHJpbnQoKQogICAgICovCiAgICBYbWxVdGlsLl9wcmludFhtbE5vZGUgPSBmdW5jdGlvbiAobm9kZVhtbCwgb3B0aW9ucykgewogICAgICAgIGlmICghbm9kZVhtbCkgewogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQoKICAgICAgICB2YXIgcHJpbnQgPSAiIjsKICAgICAgICB2YXIgaW5kZW50U3RyID0gb3B0aW9ucy5wcmV0dHkgPyBYbWxVdGlsLnJlcGVhdChYbWxVdGlsLl9QUkVUVFlQUklOVF9JTkRFTlRfQ0hBUiwgb3B0aW9ucy5pbmRlbnQgKiBvcHRpb25zLmxldmVsKSA6ICIiOwogICAgICAgIHZhciBwcmV0dHlJbnNpZGUgPSBvcHRpb25zLnByZXR0eTsKICAgICAgICB2YXIgZmlsdGVyT3B0aW9ucyA9IG51bGw7CgogICAgICAgIGlmIChvcHRpb25zLmZpbHRlciAhPSBudWxsKSB7CiAgICAgICAgICAgIGZpbHRlck9wdGlvbnMgPSB7cHJldHR5SW5zaWRlIDogcHJldHR5SW5zaWRlLCBrZWVwIDogdHJ1ZX07CgogICAgICAgICAgICBpZiAob3B0aW9ucy5maWx0ZXIuY2FsbChudWxsLCBub2RlWG1sLCBmaWx0ZXJPcHRpb25zKSA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICBpZiAoIWZpbHRlck9wdGlvbnMua2VlcCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcHJldHR5SW5zaWRlID0gZmlsdGVyT3B0aW9ucy5wcmV0dHlJbnNpZGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmaWx0ZXJPcHRpb25zID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc3dpdGNoIChub2RlWG1sLm5vZGVLaW5kKCkpIHsKICAgICAgICAgICAgY2FzZSBYbWxVdGlsLk5PREVLSU5EX0VMRU1FTlQgOgogICAgICAgICAgICAgICAgLy8gdXNlIHRoaXMgbm9kZSdzIHByZXR0eSBzZXR0aW5nCiAgICAgICAgICAgICAgICBwcmludCArPSAoKHByaW50Lmxlbmd0aCA+IDAgJiYgb3B0aW9ucy5wcmV0dHkpID8gIlxuIiA6ICIiKSArIFhtbFV0aWwuX3ByaW50WG1sRWxlbWVudChub2RlWG1sLCBpbmRlbnRTdHIsIHRydWUpOwoKICAgICAgICAgICAgICAgIC8vIHVzZSB0aGUgY2hpbGRyZW4ncyBwcmV0dHkgc2V0dGluZyAocHJldHR5SW5zaWRlKQogICAgICAgICAgICAgICAgaWYgKG5vZGVYbWwuY2hpbGRyZW4oKS5sZW5ndGgoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICBpZiAobm9kZVhtbC5jaGlsZHJlbigpLmxlbmd0aCgpID09IDEgJiYgbm9kZVhtbC5jaGlsZHJlbigpWzBdLm5vZGVLaW5kKCkgPT0gWG1sVXRpbC5OT0RFS0lORF9URVhUICYmIGZpbHRlck9wdGlvbnMgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBPdmVycmlkZSB0aGUgcHJldHR5IHNldHRpbmcgZm9yIGNoaWxkcmVuIGlmIHRoZXJlJ3Mgb25seSBvbmUsIGl0J3MgYSB0ZXh0IG5vZGUgYW5kIHRoZSBmaWx0ZXIgZnVuY3Rpb24gZGlkbid0IGV4cGxpY2l0bHkKICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHJlcXVlc3QgdGhhdCB0aGUgY29udGVudHMgb2YgdGhpcyBub2RlIGJlIHByZXR0eS1wcmludGVkLgogICAgICAgICAgICAgICAgICAgICAgICAvLyBYTUwgcGFyc2VycyB0eXBpY2FsbHkgb3V0cHV0IGVsZW1lbnRzIHdpdGggYSBzaW5nbGUgdGV4dCBub2RlIGFsbCBvbiBhIHNpbmdsZSBsaW5lLiBUaGlzIGVuc3VyZXMgdGhhdCB3aGl0ZXNwYWNlIHdpdGhpbiB0ZXh0IG5vZGVzIHJlbWFpbnMgaW50YWN0LgogICAgICAgICAgICAgICAgICAgICAgICAvLyBXQVJOSU5HOiBEaXNhYmxpbmcgdGhpcyB3aWxsIGxlYWQgdG8gdW5leHBlY3RlZCBiZWhhdmlvdXIuIEZvciBleGFtcGxlLCBEZXNpZ25lciBjcmFzaGVzIHdoZW4gInBhc3RpbmcgdGhlIHByaW50LW91dCBpbnRvIFhNTCBTb3VyY2UsIGdvaW5nIHRvIERlc2lnbgogICAgICAgICAgICAgICAgICAgICAgICAvLyAgVmlldyBhbmQgdGhlbiBiYWNrIHRvIFhNTCBTb3VyY2UiIGlmIHRoaXMgb3ZlcnJpZGUgaXMgbm90IGFwcGxpZWQuCiAgICAgICAgICAgICAgICAgICAgICAgIHByZXR0eUluc2lkZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTWFrZSBhIGNvcHkgYW5kIGFwcGx5IHNldHRpbmdzIGZvciBjaGlsZHJlbiBvbiB0aGUgY29weSBzaW5jZSBvYmplY3RzIGFyZSBwYXNzZWQgYnkgcmVmZXJlbmNlLgogICAgICAgICAgICAgICAgICAgIC8vIFdBUk5JTkc6IERvIG5vdCB1c2UgT2JqZWN0VXRpbC5jb3B5KCkgYmVjYXVzZSBpdCB3b24ndCBjb3B5IHRoZSBmaWx0ZXIgcHJvcGVydHkgZm9yIHNvbWUgcmVhc29uIChwZXJoYXBzIGl0IG9ubHkgY2xvbmVzIHByb3BlcnRpZXMgdGhhdCBhcmUgcHJpbWl0aXZlIHR5cGVzPykuCiAgICAgICAgICAgICAgICAgICAgdmFyIGluc2lkZU9wdGlvbnMgPSB7cHJldHR5IDogcHJldHR5SW5zaWRlLCBpbmRlbnQgOiBvcHRpb25zLmluZGVudCwgbGV2ZWwgOiBvcHRpb25zLmxldmVsICsgMSwgZmlsdGVyIDogb3B0aW9ucy5maWx0ZXJ9OwoKICAgICAgICAgICAgICAgICAgICB2YXIgaW5zaWRlUHJpbnQgPSAiIjsKICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRFbGVtZW50cyA9IG5vZGVYbWwuY2hpbGRyZW4oKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgIGkgPCBjaGlsZEVsZW1lbnRzLmxlbmd0aCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IGNoaWxkRWxlbWVudHNbaV07CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZFByaW50ID0gWG1sVXRpbC5fcHJpbnRYbWxOb2RlKGNoaWxkLCBpbnNpZGVPcHRpb25zKTsgLy8gcmVjdXJzaXZlIGNhbGwKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkUHJpbnQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zaWRlUHJpbnQgKz0gKChpbnNpZGVQcmludC5sZW5ndGggPiAwICYmIHByZXR0eUluc2lkZSkgPyAiXG4iIDogIiIpICsgY2hpbGRQcmludDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gYWRkIHRoZSBpbnNpZGUgcHJpbnRlZCBjb250ZW50IChpZiBhbnkpIHRvIHRoZSBwcmludCBjb250ZW50LCBjbG9zaW5nIG5vZGUgdGhlIGFwcHJvcHJpYXRlIHdheQogICAgICAgICAgICAgICAgICAgIGlmIChpbnNpZGVQcmludC5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFkZCBpbnNpZGUgY29udGVudCBhbmQgY2xvc2Ugd2l0aCA8L25vZGU+IHN5bnRheAogICAgICAgICAgICAgICAgICAgICAgICBwcmludCArPSAoKHByaW50Lmxlbmd0aCA+IDAgJiYgcHJldHR5SW5zaWRlKSA/ICJcbiIgOiAiIikgKyBpbnNpZGVQcmludDsKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQgKz0gKChwcmludC5sZW5ndGggPiAwICYmIHByZXR0eUluc2lkZSkgPyAiXG4iIDogIiIpICsgWG1sVXRpbC5fcHJpbnRYbWxFbGVtZW50KG5vZGVYbWwsIHByZXR0eUluc2lkZSA/IGluZGVudFN0ciA6ICIiLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gY2hpbGRyZW4gd2VyZSBwcmludGVkIC0tIGNsb3NlIHdpdGggPG5vZGUvPiBzeW50YXgKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQgPSBwcmludC5zdWJzdHJpbmcoMCwgcHJpbnQubGVuZ3RoIC0gMSkgKyAiLz4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBYbWxVdGlsLk5PREVLSU5EX0FUVFJJQlVURSA6CiAgICAgICAgICAgICAgICBEZWJ1Zy53YXJuaW5nKCJza2lwcGluZyBhdHRyaWJ1dGUgbm9kZSAnIiArIFhtbFV0aWwucXVhbGlmaWVkTmFtZShub2RlWG1sKSArICInOiB0aGVzZSBzaG91bGQgYmUgaGFuZGxlZCB3aGVuIHByaW50aW5nIGVsZW1lbnRzIiwgbnVsbCk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgWG1sVXRpbC5OT0RFS0lORF9DT01NRU5UIDoKICAgICAgICAgICAgICAgIHByaW50ICs9ICgocHJpbnQubGVuZ3RoID4gMCAmJiBvcHRpb25zLnByZXR0eSkgPyAiXG4iIDogIiIpICsgWG1sVXRpbC5fcHJpbnRYbWxDb21tZW50KG5vZGVYbWwsIGluZGVudFN0cik7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgWG1sVXRpbC5OT0RFS0lORF9QSSA6CiAgICAgICAgICAgICAgICBwcmludCArPSAoKHByaW50Lmxlbmd0aCA+IDAgJiYgb3B0aW9ucy5wcmV0dHkpID8gIlxuIiA6ICIiKSArIFhtbFV0aWwuX3ByaW50WG1sUEkobm9kZVhtbCwgaW5kZW50U3RyKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBYbWxVdGlsLk5PREVLSU5EX1RFWFQgOgogICAgICAgICAgICAgICAgcHJpbnQgKz0gKChwcmludC5sZW5ndGggPiAwICYmIG9wdGlvbnMucHJldHR5KSA/ICJcbiIgOiAiIikgKyBYbWxVdGlsLl9wcmludFhtbFRleHQobm9kZVhtbCwgaW5kZW50U3RyKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIERlYnVnLndhcm5pbmcoInNraXBwaW5nIHVuc3VwcG9ydGVkIG5vZGUga2luZDogIiArIG5vZGVYbWwubm9kZUtpbmQoKSwgbnVsbCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHByaW50OwogICAgfTsKCiAgICAvKioKICAgICAqIFByaW50cyBhbiBYTUwgY29tbWVudC4KICAgICAqIEBwYXJhbSBub2RlWG1sIFRoZSBjb21tZW50IHRvIHByaW50LgogICAgICogQHBhcmFtIGluZGVudFN0ciBUaGUgaW5kZW50YXRpb24gc3RyaW5nIHRvIHByZXBlbmQgdG8gdGhlIHByaW50ZWQgb3V0cHV0LgogICAgICogQHJldHVybiBUaGUgcHJpbnRlZCB2ZXJzaW9uIG9mIHRoZSBYTUwgY29tbWVudC4gSWYgdGhlIG5vZGUgaXMgbnVsbCwgYW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkLgogICAgICovCiAgICBYbWxVdGlsLl9wcmludFhtbENvbW1lbnQgPSBmdW5jdGlvbiAobm9kZVhtbCwgaW5kZW50U3RyKSB7CiAgICAgICAgaWYgKCFub2RlWG1sIHx8IG5vZGVYbWwubm9kZUtpbmQoKSAhPSBYbWxVdGlsLk5PREVLSU5EX0NPTU1FTlQpIHsKICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0KCiAgICAgICAgLy8gdXNlIHRvWE1MU3RyaW5nKCkgdG8gZ2V0IHRoZSBmdWxsIG1hcmstdXAKICAgICAgICB2YXIgcHJpbnQgPSBub2RlWG1sLnRvWE1MU3RyaW5nKCk7CiAgICAgICAgcmV0dXJuIGluZGVudFN0ciArIHByaW50OwogICAgfTsKICAgIC8qKgogICAgICogUHJpbnRzIGFuIFhNTCBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgogICAgICogQHBhcmFtIG5vZGVYbWwgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdG8gcHJpbnQuCiAgICAgKiBAcGFyYW0gaW5kZW50U3RyIFRoZSBpbmRlbnRhdGlvbiBzdHJpbmcgdG8gcHJlcGVuZCB0byB0aGUgcHJpbnRlZCBvdXRwdXQuCiAgICAgKiBAcmV0dXJuIFRoZSBwcmludGVkIHZlcnNpb24gb2YgdGhlIFhNTCBwcm9jZXNzaW5nIGluc3RydWN0aW9uLiBJZiB0aGUgbm9kZSBpcyBudWxsLCBhbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQuCiAgICAgKi8KICAgIFhtbFV0aWwuX3ByaW50WG1sUEkgPSBmdW5jdGlvbiAobm9kZVhtbCwgaW5kZW50U3RyKSB7CiAgICAgICAgaWYgKCFub2RlWG1sIHx8IG5vZGVYbWwubm9kZUtpbmQoKSAhPSBOT0RFS0lORF9QSSkgewogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQoKICAgICAgICAvLyB1c2UgdG9YTUxTdHJpbmcoKSB0byBnZXQgdGhlIGZ1bGwgbWFyay11cAogICAgICAgIHZhciBwcmludCA9IG5vZGVYbWwudG9YTUxTdHJpbmcoKTsKICAgICAgICByZXR1cm4gaW5kZW50U3RyICsgcHJpbnQ7CiAgICB9OwogICAgLyoqCiAgICAgKiBQcmludHMgWE1MIHRleHQuCiAgICAgKiBAcGFyYW0gbm9kZVhtbCBUaGUgdGV4dCB0byBwcmludC4KICAgICAqIEBwYXJhbSBpbmRlbnRTdHIgVGhlIGluZGVudGF0aW9uIHN0cmluZyB0byBwcmVwZW5kIHRvIHRoZSBwcmludGVkIG91dHB1dC4KICAgICAqIEByZXR1cm4gVGhlIHByaW50ZWQgdmVyc2lvbiBvZiB0aGUgWE1MIHRleHQuIElmIHRoZSBub2RlIGlzIG51bGwsIGFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZC4KICAgICAqLwogICAgWG1sVXRpbC5fcHJpbnRYbWxUZXh0ID0gZnVuY3Rpb24gKG5vZGVYbWwsIGluZGVudFN0cikgewogICAgICAgIGlmICghbm9kZVhtbCB8fCAhbm9kZVhtbC50b1N0cmluZygpIHx8IG5vZGVYbWwubm9kZUtpbmQoKSAhPSBYbWxVdGlsLk5PREVLSU5EX1RFWFQpIHsKICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0KCiAgICAgICAgLy8gdXNlIHRvU3RyaW5nKCkgdG8gZ2V0IGp1c3QgdGhlIHRleHQsIGluY2x1ZGluZyBzcGFjZXMsIHRoZW4gcmUtZW5jb2RlIHRoZSB0ZXh0CiAgICAgICAgdmFyIHByaW50ID0gWG1sVXRpbC5lbmNvZGVYbWxDaGFycyhub2RlWG1sLnRvU3RyaW5nKCkpOwogICAgICAgIC8vIGZpeC11cCBjYXNlcyB3aGVyZSB3ZSBoYXZlIENSTEYgc2VxdWVuY2VzIHNpbmNlIG91dHB1dHRpbmcgdGhvc2UgY2F1c2VzIGRvdWJsZS1zcGFjZWQgdGV4dAogICAgICAgIHByaW50ID0gcHJpbnQucmVwbGFjZSgiXHJcbiIsICJcbiIpOwogICAgICAgIHJldHVybiBpbmRlbnRTdHIgKyBwcmludDsKICAgIH07CiAgICAvKioKICAgICAqIEZpbmRzIHRoZSBjaGlsZCBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgb2NjdXJyZW5jZS4KICAgICAqIEBwYXJhbSBwYXJlbnRYbWwgVGhlIHBhcmVudCBYTUwgbm9kZSB3aG9zZSBpbW1lZGlhdGUgY2hpbGRyZW4gKG9ubHkpIHdpbGwgYmUgc2VhcmNoZWQuCiAgICAgKiBAcGFyYW0gZWxlbU5hbWUgQ2xhc3MgbmFtZSBvZiB0aGUgY2hpbGQgZWxlbWVudCBzb3VnaHQuCiAgICAgKiBAcGFyYW0gb2NjdXJyZW5jZSBUaGUgb2NjdXJyZW5jZSBvZiB0aGUgY2hpbGQgZWxlbWVudCBzb3VnaHQuCiAgICAgKiBAcGFyYW0gY3JlYXRlIElmIHRydWUgYW5kIHRoZXJlIGFyZSBsZXNzIGV4aXN0aW5nIG9jY3VycmVuY2VzIG9mIHRoZSBzcGVjaWZpZWQgY2hpbGQgdGhhbiB0aGUgb2NjdXJyZW5jZSBzcGVjaWZpZWQsIHRoZQogICAgICogIG1pc3NpbmcgY2hpbGQgZWxlbWVudHMgd2lsbCBiZSBjcmVhdGVkIGFuZCBhcHBlbmRlZCB0byB0aGUgcGFyZW50IG5vZGUuCiAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZCBlbGVtZW50IHNvdWdodCAobWF5IGJlIGEgbmV3IGNoaWxkIG9mIHRoZSBwYXJlbnQgaWYgPGNvZGU+Y3JlYXRlPC9jb2RlPiB3YXMgdHJ1ZSkuIElmIDxjb2RlPmNyZWF0ZTwvY29kZT4gd2FzIGZhbHNlCiAgICAgKiAgYW5kIHRoZSBvY2N1cnJlbmNlIHdhc24ndCBmb3VuZCwgbnVsbC4KICAgICAqLwogICAgWG1sVXRpbC5nZXRDaGlsZE9jY3VycmVuY2UgPSBmdW5jdGlvbiAocGFyZW50WG1sLCBlbGVtTmFtZSwgb2NjdXJyZW5jZSwgY3JlYXRlKSB7CiAgICAgICAgb2NjdXJyZW5jZSA9IG9jY3VycmVuY2UgIT09IHVuZGVmaW5lZCA/IG9jY3VycmVuY2UgOiAwOwogICAgICAgIGNyZWF0ZSA9IGNyZWF0ZSAhPT0gdW5kZWZpbmVkID8gY3JlYXRlIDogZmFsc2U7CiAgICAgICAgaWYgKG9jY3VycmVuY2UgPCAwKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgdmFyIGVsZW1YbWwgPSBudWxsOwoKICAgICAgICB2YXIgb2NjdXIgPSAtMTsgLy8gY3VycmVudCBvY2N1cnJlbmNlIG9mIGV4aXN0aW5nIGVsZW1lbnRzIHdpdGggY2xhc3MgbmFtZXMgdGhhdCBtYXRjaCBlbGVtTmFtZQogICAgICAgIHZhciBjaGlsZHJlbiA9IHBhcmVudFhtbC5lbGVtZW50cygpOwogICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgaSA8IGNoaWxkcmVuLmxlbmd0aCgpOwogICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgIHZhciBjaGlsZFhtbCA9IGNoaWxkcmVuW2ldOwogICAgICAgICAgICBpZiAoY2hpbGRYbWwubG9jYWxOYW1lKCkgPT0gZWxlbU5hbWUpIHsKICAgICAgICAgICAgICAgIG9jY3VyKys7CiAgICAgICAgICAgICAgICBpZiAob2NjdXIgPT0gb2NjdXJyZW5jZSkgewogICAgICAgICAgICAgICAgICAgIC8vIGZvdW5kIG5vZGUgc291Z2h0CiAgICAgICAgICAgICAgICAgICAgZWxlbVhtbCA9IGNoaWxkWG1sOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVsZW1YbWwgJiYgY3JlYXRlKSB7CiAgICAgICAgICAgIC8vIGFkZCBtaXNzaW5nIG9jY3VycmVuY2VzCiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOwogICAgICAgICAgICAgICAgIGogPCAob2NjdXJyZW5jZSAtIG9jY3VyKTsKICAgICAgICAgICAgICAgICBqKyspIHsKICAgICAgICAgICAgICAgIGVsZW1YbWwgPSBYbWxVdGlsLmFkZENoaWxkRWxlbWVudChwYXJlbnRYbWwsIGVsZW1OYW1lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZWxlbVhtbDsKICAgIH07CiAgICAvKioKICAgICAqIFJldHVybnMgYSBjaGlsZCBlbGVtZW50IGZyb20gaXRzIHBhcmVudCBvcHRpb25hbGx5IGNyZWF0aW5nIGFuZCBwYXJlbnRpbmcgaXQgaWYgaXQgZG9lc24ndCBleGlzdC4KICAgICAqIEBwYXJhbSBsb2NhbG5hbWVPckluZGV4IENhbiBlaXRoZXIgYmUgYSBzdHJpbmcgb3IgYSBudW1iZXIuICBXaGVuIGl0J3MgaXMgYSBudW1iZXIgYW4gaW5kZXhlZCBzZWFyY2ggaXMgcGVyZm9ybWVkIG90aGVyd2lzZSB0aGUgZmlyc3QgZWxlbWVudCB3aG9zZSBsb2NhbAogICAgICogIG5hbWUgbWF0Y2hlcyBsb2NhbG5hbWVPckluZGV4IGlzIHJldHVybmVkLgogICAgICogIEBwYXJhbSBwYXJlbnQKICAgICAqIEBwYXJhbSBjcmVhdGUgSWYgdHJ1ZSBhbmQgdGhlIGVsZW1lbnQgaXMgbm90IGZvdW5kIGFuZCBsb2NhbG5hbWVPckluZGV4IGlzIGEgc3RyaW5nLCBhIG5ldyBlbGVtZW50IHdpdGggbG9jYWxuYW1lT3JJbmRleCBhcyB0aGUgbG9jYWwgbmFtZSBpcyBjcmVhdGVkIGFuZAogICAgICogIGFwcGVuZGVkIHRvIHRoZSBwYXJlbnQgb2JqZWN0LgogICAgICovCiAgICBYbWxVdGlsLmdldENoaWxkRWxlbWVudCA9IGZ1bmN0aW9uIChwYXJlbnQsIGxvY2FsbmFtZU9ySW5kZXgsIGNyZWF0ZSkgewogICAgICAgIGNyZWF0ZSA9IGNyZWF0ZSAhPT0gdW5kZWZpbmVkID8gY3JlYXRlIDogZmFsc2U7CiAgICAgICAgdmFyIHhtbFBhcmVudCA9IFhtbFV0aWwuZ2V0WG1sT2JqZWN0KHBhcmVudCk7CgogICAgICAgIGlmICgheG1sUGFyZW50KSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgdmFyIG9Ob2RlID0gbnVsbDsKCiAgICAgICAgaWYgKHR5cGVvZiBsb2NhbG5hbWVPckluZGV4ID09ICJudW1iZXIiKSB7CiAgICAgICAgICAgIC8vU2VhcmNoIGJ5IGluZGV4CiAgICAgICAgICAgIHZhciBpbmRleCA9IE51bWJlcihsb2NhbG5hbWVPckluZGV4KTsKICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0geG1sUGFyZW50LmVsZW1lbnRzKCk7CiAgICAgICAgICAgIGlmIChpbmRleCA8IGNoaWxkcmVuLmxlbmd0aCgpICYmIGluZGV4ID49IDApIHsKICAgICAgICAgICAgICAgIG9Ob2RlID0gY2hpbGRyZW5baW5kZXhdOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy9TZWFyY2ggYnkgZWxlbWVudCBuYW1lCiAgICAgICAgICAgIG9Ob2RlID0gWG1sVXRpbC5zZWxlY3RTaW5nbGVOb2RlKHhtbFBhcmVudCwgbG9jYWxuYW1lT3JJbmRleCk7CiAgICAgICAgICAgIGlmICghb05vZGUgJiYgY3JlYXRlKSB7CiAgICAgICAgICAgICAgICBvTm9kZSA9IFhtbFV0aWwuYWRkQ2hpbGRFbGVtZW50KHhtbFBhcmVudCwgbG9jYWxuYW1lT3JJbmRleCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9Ob2RlOwogICAgfTsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBYTUwgZWxlbWVudCB3aXRoIGFuIG9wdGlvbmFsIG5hbWUgYXR0cmlidXRlIGFuZAogICAgICogYXBwZW5kcyBpdCB0byB0aGUgcGFyZW50IGVsZW1lbnQuCiAgICAgKi8KICAgIFhtbFV0aWwuYWRkQ2hpbGRFbGVtZW50ID0gZnVuY3Rpb24gKHBhcmVudCwgZWxlbU5hbWUsIG5hbWUpIHsKICAgICAgICBpZiAoIXBhcmVudCB8fCAhZWxlbU5hbWUpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICB2YXIgb05vZGU7CiAgICAgICAgaWYgKG5hbWUpIHsKICAgICAgICAgICAgb05vZGUgPSBYbWxVdGlsLmNyZWF0ZVRhZyhlbGVtTmFtZSwge25hbWUgOiBuYW1lfSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb05vZGUgPSBYbWxVdGlsLmNyZWF0ZVRhZyhlbGVtTmFtZSwgbnVsbCk7CiAgICAgICAgfQogICAgICAgIHBhcmVudC5hcHBlbmRDaGlsZChvTm9kZSwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIG9Ob2RlOwogICAgfTsKICAgIFhtbFV0aWwuY3JlYXRlVGFnID0gZnVuY3Rpb24gKGVsZW1lbnQsIHBhcmFtYXRlcnMpIHsKICAgICAgICB2YXIgbmFtZSwgeG1sLCB4bWxTdHJpbmcgPSAiPCIgKyBlbGVtZW50OwogICAgICAgIGlmIChwYXJhbWF0ZXJzKSB7CiAgICAgICAgICAgIGZvciAobmFtZSBpbgogICAgICAgICAgICAgICAgcGFyYW1hdGVycykgewogICAgICAgICAgICAgICAgeG1sU3RyaW5nICs9ICIgIiArIG5hbWUgKyAiPVwiIiArIHBhcmFtYXRlcnNbbmFtZV0gKyAiXCIiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHhtbFN0cmluZyArPSAiIC8+IjsKICAgICAgICB4bWwgPSBuZXcgWE1MKHhtbFN0cmluZyk7CiAgICAgICAgcmV0dXJuIHhtbDsKICAgIH07CgogICAgLyoqCiAgICAgKiBQcmludHMgdGhlIHNwZWNpZmllZCBYTUwgbm9kZS4gVGhpcyBmdW5jdGlvbiBkaWZmZXJzIGZyb20gQVMzJ3MgPGNvZGU+WE1MLnRvWE1MU3RyaW5nKCk8L2NvZGU+IGZ1bmN0aW9uIGluIHRoYXQgaXQgaGFzIHNwZWNpYWwgaGFuZGxpbmcgZm9yIGNlcnRhaW4KICAgICAqICBjYXNlcyBsaWtlIHVucXVhbGlmaWVkIG5hbWVzcGFjZSBwcmVmaXhlcyAod2hlcmUgYSBuYW1lc3BhY2UgcHJlZml4IGlzIHVzZWQgd2hlbiB0aGVyZSdzIG5vIGRlZmluaXRpb24gZm9yIHRoYXQgcHJlZml4IGluIHRoZSBYTUwgZG9jdW1lbnQpLiBXaGl0ZXNwYWNlLAogICAgICogIGNvbW1lbnRzIGFuZCBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBhcmUgYWx3YXlzIHByZXNlcnZlZC4KICAgICAqIEBwYXJhbSByb290WG1sIFRoZSBYTUwgbm9kZSB0byBwcmludC4KICAgICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbmFsIG9iamVjdCBzcGVjaWZ5aW5nIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczoKICAgICAqICA8cD5wcmV0dHk6IEJvb2xlYW4uIFRydWUgaWYgdGhlIHByaW50aW5nIHNob3VsZCBiZSBwcmV0dHk7IGZhbHNlIGlmIGl0IHNob3VsZCBiZSBvbiBhIHNpbmdsZSBsaW5lLiBEZWZhdWx0OiBmYWxzZS48L3A+CiAgICAgKiAgPHA+aW5kZW50OiBpbnQuIFRoZSBkZXB0aCB0byBpbmRlbnQgbmV3IGNoaWxkIGxpbmVzIHdoZW4gcHJldHR5LXByaW50aW5nLiBEZWZhdWx0OiAyLjwvcD4KICAgICAqICA8cD5maWx0ZXI6IEZ1bmN0aW9uLiBEZWZhdWx0OiBudWxsLiBGdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCBwcmlvciB0byBwcm9jZXNzaW5nIGFueSB0eXBlIG9mIG5vZGUgcHJvdmlkaW5nIHRoZSBhYmlsaXR5IHRvIGRpcmVjdCB0aGUgYWxnb3JpdGhtIG9uCiAgICAgKiAgIHNwZWNpZmljIG5vZGVzLiBUaGUgZnVuY3Rpb24ncyBzaWduYXR1cmUgaXMgZXhwZWN0ZWQgdG8gYmUgPGNvZGU+ZnVuY3Rpb24obm9kZTpYTUwsIG9wdGlvbnM6T2JqZWN0KTwvY29kZT4gd2hlcmUgbm9kZSBpcyB0aGUgWE1MIG5vZGUgYWJvdXQKICAgICAqICAgdG8gYmUgcHJvY2Vzc2VkIGFuZCBvcHRpb25zIGlzIGEgZHluYW1pYyBvYmplY3QgdXNlZCB0byBwYXNzIGluIHRoZSBjdXJyZW50IHN0YXRlIGFuZCB0byBwYXNzIG91dCBhbnkgc3RhdGUgbW9kaWZpY2F0aW9ucy4gSWYgdGhlIGZpbHRlciBmdW5jdGlvbgogICAgICogICByZXR1cm5zIHRydWUsIHRoZSBvcHRpb25zIHdpbGwgYmUgY29uc2lkZXJlZCwgb3RoZXJ3aXNlIHRoZXkgd2lsbCBiZSBpZ25vcmVkIGFuZCB0aGUgYWxnb3JpdGhtIHdpbGwgY29udGludWUgaXRzIGRlZmF1bHQgcHJvY2Vzc2luZy4gVGhlIG9wdGlvbnMKICAgICAqICAgb2JqZWN0IGhhcyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6IDxjb2RlPnByZXR0eUluc2lkZTwvY29kZT4gKEJvb2xlYW4gc2V0IHRvIHRoZSBjdXJyZW50IHN0YXRlIG9mIDxjb2RlPnByZXR0eTwvY29kZT4pLCA8Y29kZT5rZWVwPC9jb2RlPgogICAgICogICAoQm9vbGVhbiB0aGF0IGRlZmF1bHRzIHRvIHRydWUgYW5kIGRldGVybWluZXMgd2hldGhlciB0aGUgbm9kZSBzaG91bGQgYmUgaW5jbHVkZWQgaW4gdGhlIHByaW50LW91dCBvciBub3QpLiBEZWZhdWx0OiBudWxsLjwvcD4KICAgICAqIEByZXR1cm4gVGhlIChwcmV0dHkpIHByaW50ZWQgdmVyc2lvbiBvZiB0aGUgWE1MIG5vZGUuIElmIHJvb3RYbWwgaXMgbnVsbCwgYW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkLgogICAgICovCiAgICBYbWxVdGlsLnByaW50ID0gZnVuY3Rpb24gKHJvb3RYbWwsIG9wdGlvbnMpIHsKICAgICAgICAvLyBUaGVyZSdzIGEgcHJvYmxlbSB3aXRoIHRoZSB3YXkgdGhlIEZsZXggWE1MIGNsYXNzIGhhbmRsZXMgbmFtZXNwYWNlcyB3aGljaCBhcmVuJ3QgcXVhbGlmaWVkLiBUaGUgb3V0cHV0IGlzIHZhbGlkIGJ1dCBEZXNpZ25lciA4LjErIGNyYXNoZXMKICAgICAgICAvLyAgYXMgYSByZXN1bHQgb2YgcGFyc2luZyBpdC4gRGVzaWduZXIgOC4yIHdpbGwgY29udGFpbiBhIGZpeCBmb3IgdGhpcy4KICAgICAgICAvLyBJbiB0aGUgWE1QIE1ldGFkYXRhIHBhY2tldCwgdGhlIGZvbGxvd2luZyBub2RlIGlzIGRlZmluZWQ6CiAgICAgICAgLy8gIDxyZGY6bGkgbGFuZz0ieC1kZWZhdWx0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIj4KICAgICAgICAvLyBEZWZpbmluZyB0aGlzIHdheSByZXN1bHRzIGluIGludmFsaWQgWE1MIChhdCBsZWFzdCBtb3N0IFhNTCBwYXJzZXJzIGRvbid0IGxpa2UgaXQpLiBJdCdzIGV4cGVjdGluZyBpdCB0byBiZSBkZWZpbmVkIGluIHRoaXMgd2F5OgogICAgICAgIC8vICA8cmRmOmxpIHhtbDpsYW5nPSJ4LWRlZmF1bHQiPgogICAgICAgIC8vIChOb3RpY2UgdGhhdCB0aGUgRmxleCBYTUwgY2xhc3MgaXMgYXV0b21hdGljYWxseSBxdWFsaWZ5aW5nIHRoZSAieG1sIiBuYW1lc3BhY2Ugd2l0aCBzb21lIGRlZmF1bHQgd2hpY2ggdGhlIG90aGVyIHBhcnNlciBkb2Vzbid0IGxpa2UuKQogICAgICAgIC8vIFRoaXMgaXMgb25lIGRpZmZlcmVuY2UgaW4gdGhlIHdheSB0aGlzIHByaW50IGZ1bmN0aW9uIG91dHB1dHMgdGhlIFhNTCBhcyBvcHBvc2VkIHRvIGhvdyBBUzMncyBYTUwudG9YTUxTdHJpbmcoKSBkb2VzIGl0LgoKICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCBudWxsOwoKICAgICAgICAvLyBpbml0aWFsaXplIHRvIGRlZmF1bHQgdmFsdWVzCiAgICAgICAgdmFyIHByaW50T3B0aW9ucyA9IHtwcmV0dHkgOiBmYWxzZSwgaW5kZW50IDogMiwgZmlsdGVyIDogbnVsbCwgbGV2ZWwgOiAwfTsKCiAgICAgICAgaWYgKG9wdGlvbnMpIHsKICAgICAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoInByZXR0eSIpKSB7CiAgICAgICAgICAgICAgICBwcmludE9wdGlvbnMucHJldHR5ID0gb3B0aW9ucy5wcmV0dHk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KCJpbmRlbnQiKSkgewogICAgICAgICAgICAgICAgcHJpbnRPcHRpb25zLmluZGVudCA9IG9wdGlvbnMuaW5kZW50OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAob3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgiZmlsdGVyIikpIHsKICAgICAgICAgICAgICAgIHByaW50T3B0aW9ucy5maWx0ZXIgPSBvcHRpb25zLmZpbHRlcjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdmFyIHByaW50ID0gWG1sVXRpbC5fcHJpbnRYbWxOb2RlKHJvb3RYbWwsIHByaW50T3B0aW9ucyk7CgogICAgICAgIC8vIGFsd2F5cyByZXR1cm4gYSBzdHJpbmcKICAgICAgICByZXR1cm4gcHJpbnQgPyBwcmludCA6ICIiOwogICAgfTsKCiAgICAvKiogUmV0dXJucyBhIHN0cmluZyB3aG9zZSBjb250ZW50IGlzIHRoZSBzdHJpbmcgYyByZXBlYXRlZCBjb3VudCB0aW1lcy4gSWYgYyBpcyBudWxsLCB0aGUgcmV0dXJuZWQgc3RyaW5nIGlzIG51bGwuICovCiAgICBYbWxVdGlsLnJlcGVhdCA9IGZ1bmN0aW9uIChjLCBjb3VudCkgewogICAgICAgIHZhciBzID0gIiI7CiAgICAgICAgaWYgKGMgPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9CiAgICAgICAgZm9yICh2YXIgaSA9IDA7CiAgICAgICAgICAgICBpIDwgY291bnQ7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgcyArPSBjOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgIH07CgogICAgWG1sVXRpbC5nZXRBbGxDaGlsZHJlbiA9IGZ1bmN0aW9uIChwYXJlbnRYTUwpIHsKICAgICAgICBpZiAocGFyZW50WE1MICE9IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIHBhcmVudFhNTC5fQ2hpbGRyZW47CiAgICAgICAgfQogICAgfTsKCiAgICBYbWxVdGlsLlhIVE1MTlNVUkkgPSAiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI7CiAgICBYbWxVdGlsLk5PREVLSU5EX1RFWFQgPSAidGV4dCI7CiAgICBYbWxVdGlsLk5PREVLSU5EX0VMRU1FTlQgPSAiZWxlbWVudCI7CiAgICBYbWxVdGlsLk5PREVLSU5EX0NPTU1FTlQgPSAiY29tbWVudCI7CiAgICBYbWxVdGlsLk5PREVLSU5EX1BJID0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iOwogICAgWG1sVXRpbC5OT0RFS0lORF9BVFRSSUJVVEUgPSAiYXR0cmlidXRlIjsKICAgIFhtbFV0aWwuUElfUkVHRVhQID0gIjxcXD8oP1A8cGlEb21haW4+XFxTKylcXHMrKD9QPHBpS2V5PlxcUyspKD86XFxzPykoP1A8cGlWYWx1ZT4uKilcXD8+IjsKICAgIFhtbFV0aWwuUElfUkVHRVhQX0ZMQUdTID0gImdzIjsKICAgIFhtbFV0aWwuX1BSRVRUWVBSSU5UX0lOREVOVF9DSEFSID0gIiAiOwp9KShGb3JtLnJ0ZS51dGlsKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE1LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKKGZ1bmN0aW9uIChucykgewogICAgdmFyIFhmYVV0aWwgPSBucy5YZmFVdGlsID0ge307CgogICAgLyoqCiAgICAgKiBQcmludHMgdGhlIHNwZWNpZmllZCBYRkEgbm9kZSBwcm9kaXZpbmcgc3BlY2lhbCBoYW5kbGluZyBmb3Igc3BlY2lmaWMgWEZBIG5vZGVzIHRvIHByZXNlcnZlIHdoaXRlIHNwYWNlIHdoZXJlIGl0J3MgbmVlZGVkIChlLmcuIFhIVE1MKS4KICAgICAqIEBwYXJhbSByb290WGZhIFRoZSBYRkEgWE1MIG5vZGUgdG8gcHJpbnQuCiAgICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25hbCBvYmplY3Qgc3BlY2lmeWluZyB0aGUgZm9sbG93aW5nIG9wdGlvbmFsIHByb3BlcnRpZXM6CiAgICAgKiAgPHA+cHJldHR5OiBCb29sZWFuLiBUcnVlIGlmIHRoZSBwcmludGluZyBzaG91bGQgYmUgcHJldHR5OyBmYWxzZSBpZiBpdCBzaG91bGQgYmUgb24gYSBzaW5nbGUgbGluZS4gRGVmYXVsdDogZmFsc2UuPC9wPgogICAgICogIDxwPmluZGVudDogaW50LiBUaGUgZGVwdGggdG8gaW5kZW50IG5ldyBjaGlsZCBsaW5lcyB3aGVuIHByZXR0eS1wcmludGluZy4gRGVmYXVsdDogMi48L3A+CiAgICAgKiBAcmV0dXJuIFRoZSAocHJldHR5KSBwcmludGVkIHZlcnNpb24gb2YgdGhlIFhGQSBub2RlLiBJZiByb290WG1sIGlzIG51bGwsIGFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZC4KICAgICAqLwogICAgWGZhVXRpbC5wcmludCA9IGZ1bmN0aW9uIChyb290WGZhLCBvcHRpb25zKSB7CiAgICAgICAgdmFyIHByaW50T3B0aW9ucyA9IHtwcmV0dHkgOiBmYWxzZSwgaW5kZW50IDogMiwgZmlsdGVyIDogdGhpcy5fcHJpbnRYZmFGaWx0ZXJ9OwogICAgICAgIGlmIChvcHRpb25zKSB7CiAgICAgICAgICAgIGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KCJwcmV0dHkiKSkgewogICAgICAgICAgICAgICAgcHJpbnRPcHRpb25zLnByZXR0eSA9IG9wdGlvbnMucHJldHR5OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KCJpbmRlbnQiKSkgewogICAgICAgICAgICAgICAgcHJpbnRPcHRpb25zLmluZGVudCA9IG9wdGlvbnMuaW5kZW50OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBucy5YbWxVdGlsLnByaW50KHJvb3RYZmEsIHByaW50T3B0aW9ucyk7CiAgICB9OwoKICAgIFhmYVV0aWwuX3ByaW50WGZhRmlsdGVyID0gZnVuY3Rpb24gKG5vZGVYbWwsIG9wdGlvbnMpIHsKICAgICAgICB2YXIgYXBwbHlPcHRpb25zID0gZmFsc2U7CgogICAgICAgIGlmIChub2RlWG1sICYmIG5vZGVYbWwubm9kZUtpbmQoKSA9PSBucy5YbWxVdGlsLk5PREVLSU5EX0VMRU1FTlQpIHsKICAgICAgICAgICAgaWYgKG5zLlhtbFV0aWwuZmluZFBJT2JqKG5vZGVYbWwsIHtkb21haW4gOiBYZmFVdGlsLlBJX0RPTUFJTiwga2V5IDogInRyYW5zaWVudE5vZGUifSwgbnVsbCkgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgLy8gbm9kZSBpcyB0cmFuc2llbnQgLS0gZG9uJ3Qga2VlcCBpdAogICAgICAgICAgICAgICAgb3B0aW9ucy5rZWVwID0gZmFsc2U7CiAgICAgICAgICAgICAgICBhcHBseU9wdGlvbnMgPSB0cnVlOwogICAgICAgICAgICB9IGVsc2UgaWYgKG5vZGVYbWwubG9jYWxOYW1lKCkgPT0gJ2JvZHknKSB7CiAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdE5zID0gbm9kZVhtbC5uYW1lc3BhY2UoKTsKCiAgICAgICAgICAgICAgICBpZiAoZGVmYXVsdE5zICYmIGRlZmF1bHROcy5wcmVmaXggPT0gIiIgJiYgZGVmYXVsdE5zLnVyaSA9PSBucy5YbWxVdGlsLlhIVE1MTlNVUkkgJiYgbm9kZVhtbC5uYW1lc3BhY2UoJ3hmYScpICE9ICd1bmRlZmluZWQnKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gbmV2ZXIgcHJldHR5LXByaW50IHRoZSBYSFRNTAogICAgICAgICAgICAgICAgICAgIG9wdGlvbnMucHJldHR5SW5zaWRlID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgYXBwbHlPcHRpb25zID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFwcGx5T3B0aW9uczsKICAgIH07CiAgICAvKioKICAgICAqIFByb3Blcmx5IGhhbmRsZXMgbG9hZGluZyBhbiBYRkEgWE1MIHN0cmluZyBpbnRvIEFTMydzIEU0WCBYTUwgb2JqZWN0LiBYRkEgZG9jdW1lbnRzIGFyZSB1c3VhbGx5IHByZXR0eS1wcmludGVkIHdoaWNoIG1lYW5zIHdoaXRlc3BhY2UgbXVzdCBiZSBpZ25vcmVkIGhvd2V2ZXIKICAgICAqICB0aGV5IG1heSBjb250YWluIHNvbWUgWEhUTUwgaW4gd2hpY2ggc3BhY2VzIG11c3QgYmUgcHJlc2VydmVkLiBBUzMncyBYTUwgb2JqZWN0IHByb3ZpZGVzIGEgd2F5IHRvIGlnbm9yZSB3aGl0ZXNwYWNlIGhvd2V2ZXIgaXQgY2F1c2VzIHRoZSB3aGl0ZXNwYWNlIHdpdGhpbgogICAgICogIHRoZSBYSFRNTCB0byBiZSBpZ25vcmVkIHdoZW4gaXQncyBjcml0aWNhbCB0byBwcmVzZXJ2ZSBpdC4gVGhpcyBmdW5jdGlvbiBoYW5kbGVzIHRoZSB0d28gZGlmZmVyZW50IGtpbmRzIG9mIHdoaXRlc3BhY2UgYXBwcm9wcmlhdGVseSwgbWFraW5nIHN1cmUgdGhhdCB0aGUKICAgICAqICB3aGl0ZXNwYWNlIHdlIGRvbid0IHdhbnQgaXMgZGlzY2FyZGVkIGFuZCB0aGUgd2hpdGVzcGFjZSB3ZSBkbyB3YW50IGlzIHByZXNlcnZlZC4KICAgICAqIEBwYXJhbSBzb3VyY2VTdHIgVGhlIHN0cmluZyBjb250YWluaW5nIHRoZSAoWEZBKSBYTUwgZGVmaW5pdGlvbiAobWF5IGJlIGFuIGVudGlyZSBkb2N1bWVudCAoaS5lLiBhbiBYRFApLCBhIHBpZWNlIG9mIFhGQSwgb3Igc29tZSBhcmJpdHJhcnkgWE1MKS4gTm90ZSB0aGF0CiAgICAgKiAgdGhpcyBldmVuIHdvcmtzIHdpdGggc291cmNlIHN0cmluZ3Mgd2hpY2ggYXJlIG5vdCBYTUwuIElmIGEgbm9uLVhNTCBzb3VyY2Ugc3RyaW5nIGlzIHByb3ZpZGVkLCB0aGUgcmVzdWx0IHdpbGwgYmUgYW4gWE1MIG9iamVjdCB3aXRoIHRoZSBzdHJpbmcgYXMgaXRzIHRleHQKICAgICAqICAoYSB0ZXh0IG5vZGUsIGVzc2VudGlhbGx5LCBhcyBwZXIgdGhlIHRvcC1sZXZlbCBYTUwgb2JqZWN0J3MgY29uc3RydWN0b3Igb3V0cHV0KS4KICAgICAqIEByZXR1cm4gVGhlIFhNTCBvYmplY3QgYmFzZWQgb24gdGhlIHNwZWNpZmllZCBzdHJpbmcgb3IgbnVsbCBpZiBhbiBlcnJvciBvY2N1cnJlZC4KICAgICAqLwogICAgWGZhVXRpbC5sb2FkID0gZnVuY3Rpb24gKHNvdXJjZVN0cikgewogICAgICAgIHZhciB4ZmFTdHIgPSBzb3VyY2VTdHI7IC8vIGluZGlyZWN0aW9uIHNpbXBseSB0byBjaGFuZ2UgdGhlIGV4cG9zZWQgcGFyYW1ldGVyIG5hbWUgd2l0aG91dCB0b3VjaGluZyB0aGUgY29kZSBpbnNpZGUKICAgICAgICBpZiAoIXhmYVN0cikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vIHNwYWNlIHN1YnN0aXR1dGlvbiBjaGFyYWN0ZXIKICAgICAgICB2YXIgc3BhY2VTdWJDaGFyID0gJ3gnOwoKICAgICAgICAvLwogICAgICAgIC8vIFN0ZXAgMTogUmVwbGFjZSBlYWNoIHNwYWNlIGluIHNwYWNlcnVucyB3aXRoICJ4IiBjaGFyYWN0ZXJzLgogICAgICAgIC8vCiAgICAgICAgdmFyIHNwYWNlcnVuU3R5bGUgPSAieGZhLXNwYWNlcnVuIDogeWVzIjsKICAgICAgICB2YXIgc3BhY2VydW5TdGFydCA9ICc8c3BhbiBzdHlsZT0iJyArIHNwYWNlcnVuU3R5bGUgKyAnIj4nOwogICAgICAgIHZhciBzcGFjZXJ1bkVuZCA9ICc8L3NwYW4+JzsKCiAgICAgICAgLy8gdXNlIGdsb2JhbCBmbGFnIHNvIHdlIGNhbiBpdGVyYXRlIG92ZXIgbWF0Y2hlcyB1c2luZyByZS5sYXN0SW5kZXggYXMgc3RhcnQgZm9yIG5leHQgc2VhcmNoCiAgICAgICAgLy8gaGFuZGxlIGV4dHJhIHdoaXRlc3BhY2UgaW4gYmV0d2VlbiBlbGVtZW50IG5hbWUgYW5kIGF0dHJpYnV0ZSBvbiBvcGVuIGFuZCBjbG9zZSB0YWdzCiAgICAgICAgdmFyIHNwYWNlcnVuUkUgPSBYUmVnRXhwKCcvPFxccyo/c3Bhblxccyo/c3R5bGU9InhmYS1zcGFjZXJ1bjp5ZXMiXFxzKj8+KFxccyspPFwvXFxzKj9zcGFuXFxzKj8+LycsICdnaXMnKTsKICAgICAgICB2YXIgc3BhY2VydW5NYXRjaCA9IHNwYWNlcnVuUkUuZXhlYyh4ZmFTdHIpOwogICAgICAgIHZhciBzcGFjZXJ1bkNvdW50ID0gMDsKCiAgICAgICAgd2hpbGUgKHNwYWNlcnVuTWF0Y2gpIHsKICAgICAgICAgICAgc3BhY2VydW5Db3VudCsrOwogICAgICAgICAgICAvLyByZXBsYWNlIHRoZSBzcGFjZXMgaW4gdGhlIG1hdGNoIHdpdGggdGhlIHNhbWUgbnVtYmVyIG9mICJ4IiBjaGFyYWN0ZXJzCiAgICAgICAgICAgIHhmYVN0ciA9IHhmYVN0ci5zdWJzdHJpbmcoMCwgc3BhY2VydW5NYXRjaC5pbmRleCkgKyBzcGFjZXJ1blN0YXJ0ICsgU3RyaW5nSGVscGVyLnJlcGVhdChzcGFjZVN1YkNoYXIsIHNwYWNlcnVuTWF0Y2hbMV0ubGVuZ3RoKSArIHNwYWNlcnVuRW5kICsgeGZhU3RyLnN1YnN0cihzcGFjZXJ1blJFLmxhc3RJbmRleCk7CiAgICAgICAgICAgIC8vIGxvb2sgZm9yIG1vcmUgbWF0Y2hlcwogICAgICAgICAgICBzcGFjZXJ1bk1hdGNoID0gc3BhY2VydW5SRS5leGVjKHhmYVN0cik7CiAgICAgICAgfQoKICAgICAgICAvLwogICAgICAgIC8vIFN0ZXAgMjogUHJvdGVjdCBzaW5nbGUgc3BhY2VzIGF0IHRoZSBzdGFydCBhbmQgZW5kIG9mIHRleHQgbm9kZXMuIFRoZXNlIGFyZW4ndCBtYXJrZWQgYXMgc3BhY2VydW5zICh3aGljaCBjb250YWluIDIgb3IgbW9yZSBjb25zZWN1dGl2ZSBzcGFjZXMgb3IsIGluIHNvbWUgZXhjZXB0aW9ucywKICAgICAgICAvLyAgICAgICAgIGEgc2luZ2xlIHNwYWNlLCBlLmcuIHRvIGluZGljYXRlIGFuIGVtcHR5IHBhcmFncmFwaCkgYW5kIHRoZXknbGwgYmUgcmVtb3ZlZCB3aGVuIHdlIGxvYWQgaWdub3Jpbmcgd2hpdGVzcGFjZSBpbiB0aGUgbmV4dCBzdGVwLgogICAgICAgIC8vCgogICAgICAgIC8vIHRoaXMgaXNuJ3QgYW4gb2ZmaWNpYWwgc3R5bGUgLS0gSSBqdXN0IG1hZGUgdGhpcyB1cCBob3BpbmcgaXQncyB1bmlxdWUKICAgICAgICB2YXIgc2luZ2xlcnVuU3R5bGUgPSBzcGFjZXJ1blN0eWxlICsgIjtsb2FkZXItc2luZ2xlcnVuOnllcyI7CiAgICAgICAgdmFyIHNpbmdsZXJ1blN0ciA9ICc8c3BhbiBzdHlsZT0iJyArIHNpbmdsZXJ1blN0eWxlICsgJyI+JyArIHNwYWNlU3ViQ2hhciArICc8L3NwYW4+JzsKCiAgICAgICAgdmFyIHNpbmdsZXJ1blJFID0gbmV3IFJlZ0V4cCgpOwogICAgICAgIHZhciBib2R5U3RhcnRSRSA9IFhSZWdFeHAoJzxcXHMqP2JvZHlcXHMuKz8+JywgJ2dpcycpOyAvLyBoYW5kbGUgd2hpdGVzcGFjZSBiZWZvcmUgImJvZHkiIGFuZCByZXF1aXJlIDEgd2hpdGVzcGFjZSBjaGFyIGFmdGVyIGFuZCB0aGVuIHNvbWUgY29udGVudCAobmFtZXNwYWNlcykgYmVmb3JlIGNsb3NpbmcgJz4nCiAgICAgICAgdmFyIGJvZHlFbmRSRSA9IFhSZWdFeHAoJzxcL1xccyo/Ym9keVxccyo/PicsICdnaXMnKTsgLy8gaGFuZGxlIHdoaXRlc3BhY2UgYmVmb3JlIGFuZCBhZnRlciAiYm9keSIKICAgICAgICB2YXIgYm9keVN0YXJ0TWF0Y2ggPSBib2R5U3RhcnRSRS5leGVjKHhmYVN0cik7CiAgICAgICAgdmFyIGJvZHlFbmRNYXRjaCA9IGJvZHlFbmRSRS5leGVjKHhmYVN0cik7CiAgICAgICAgdmFyIHNpbmdsZXJ1bkNvdW50ID0gMDsKCiAgICAgICAgd2hpbGUgKGJvZHlTdGFydE1hdGNoICYmIGJvZHlFbmRNYXRjaCAmJiBib2R5U3RhcnRSRS5sYXN0SW5kZXggPCBib2R5RW5kTWF0Y2guaW5kZXgpIHsKICAgICAgICAgICAgLy8gZm91bmQgYSBib2R5IG5vZGUgd2l0aCBjb250ZW50cwogICAgICAgICAgICAvLyB1cCB0byBhbmQgaW5jbHVkaW5nIDxib2R5IC4uLj4KICAgICAgICAgICAgdmFyIHByZUJvZHlTdHIgPSB4ZmFTdHIuc3Vic3RyaW5nKDAsIGJvZHlTdGFydFJFLmxhc3RJbmRleCk7CiAgICAgICAgICAgIC8vIGNvbnRlbnQgYmV0d2VlbiA8Ym9keSAuLi4+IGFuZCA8L2JvZHk+CiAgICAgICAgICAgIHZhciBjb250ZW50U3RyID0geGZhU3RyLnN1YnN0cmluZyhib2R5U3RhcnRSRS5sYXN0SW5kZXgsIGJvZHlFbmRNYXRjaC5pbmRleCk7CiAgICAgICAgICAgIC8vIDwvYm9keT4gYW5kIHRoZSByZXN0CiAgICAgICAgICAgIHZhciBwb3N0Qm9keVN0ciA9IHhmYVN0ci5zdWJzdHIoYm9keUVuZE1hdGNoLmluZGV4KTsKCiAgICAgICAgICAgIC8vIHNwYWNlIGF0IHN0YXJ0IG9mIHRleHQgbm9kZQogICAgICAgICAgICB2YXIgc3RhcnRSRSA9IG5ldyBSZWdFeHAoJz4gXFMnLCAnZ2knKTsKCiAgICAgICAgICAgIC8vIG1hdGNoIHNpbmdsZSBzcGFjZXMgYXQgc3RhcnQgb2YgdGV4dCBub2RlcwogICAgICAgICAgICB2YXIgc3RhcnRNYXRjaCA9IHN0YXJ0UkUuZXhlYyhjb250ZW50U3RyKTsKICAgICAgICAgICAgdmFyIHNwYWNlQ291bnRlciA9IDA7IC8vIENvdW50IG5vLiBvZiBzcGFjZSByZXBsYWNlZAogICAgICAgICAgICB3aGlsZSAoc3RhcnRNYXRjaCkgewogICAgICAgICAgICAgICAgc2luZ2xlcnVuQ291bnQrKzsKICAgICAgICAgICAgICAgIHNwYWNlQ291bnRlcisrOwogICAgICAgICAgICAgICAgLy8gcGF0dGVybiB3aWxsIG1hdGNoIG9uZSBjaGFyYWN0ZXIgcHJlY2VkaW5nIGFuZCBvbmUgZm9sbG93aW5nIHRoZSBzaW5nbGUgc3BhY2Ugd2hpY2ggbXVzdCBiZSBwcmVzZXJ2ZWQKICAgICAgICAgICAgICAgIGNvbnRlbnRTdHIgPSBjb250ZW50U3RyLnN1YnN0cmluZygwLCBzdGFydE1hdGNoLmluZGV4ICsgMSkgKyBzaW5nbGVydW5TdHIgKyBjb250ZW50U3RyLnN1YnN0cihzdGFydFJFLmxhc3RJbmRleCAtIDEpOwogICAgICAgICAgICAgICAgc3RhcnRNYXRjaCA9IHN0YXJ0UkUuZXhlYyhjb250ZW50U3RyKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gc3BhY2UgYXQgZW5kIG9mIHRleHQgbm9kZQogICAgICAgICAgICB2YXIgZW5kUkUgPSBuZXcgUmVnRXhwKCdcUyA8JywgJ2dpJyk7CgogICAgICAgICAgICAvLyBtYXRjaCBzaW5nbGUgc3BhY2VzIGF0IGVuZCBvZiB0ZXh0IG5vZGVzCiAgICAgICAgICAgIHZhciBlbmRNYXRjaCA9IGVuZFJFLmV4ZWMoY29udGVudFN0cik7CiAgICAgICAgICAgIHdoaWxlIChlbmRNYXRjaCkgewogICAgICAgICAgICAgICAgc2luZ2xlcnVuQ291bnQrKzsKICAgICAgICAgICAgICAgIHNwYWNlQ291bnRlcisrOwogICAgICAgICAgICAgICAgLy8gcGF0dGVybiB3aWxsIG1hdGNoIG9uZSBjaGFyYWN0ZXIgcHJlY2VkaW5nIGFuZCBvbmUgZm9sbG93aW5nIHRoZSBzaW5nbGUgc3BhY2Ugd2hpY2ggbXVzdCBiZSBwcmVzZXJ2ZWQKICAgICAgICAgICAgICAgIGNvbnRlbnRTdHIgPSBjb250ZW50U3RyLnN1YnN0cmluZygwLCBlbmRNYXRjaC5pbmRleCArIDEpICsgc2luZ2xlcnVuU3RyICsgY29udGVudFN0ci5zdWJzdHIoZW5kUkUubGFzdEluZGV4IC0gMSk7CiAgICAgICAgICAgICAgICBlbmRNYXRjaCA9IGVuZFJFLmV4ZWMoY29udGVudFN0cik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gcmVidWlsZCB0aGUgWEZBIHN0cmluZyB3aXRoIHRoZSBuZXcgY29udGVudHMgY29udGFpbmluZyB0aGUgc3Vic3RpdHV0aW9ucwogICAgICAgICAgICB4ZmFTdHIgPSBwcmVCb2R5U3RyICsgY29udGVudFN0ciArIHBvc3RCb2R5U3RyOwogICAgICAgICAgICBib2R5U3RhcnRSRS5sYXN0SW5kZXggKz0gKHNwYWNlQ291bnRlciAqIHNpbmdsZXJ1blN0ci5sZW5ndGgpIC0gc3BhY2VDb3VudGVyOwogICAgICAgICAgICBib2R5RW5kUkUubGFzdEluZGV4ICs9IChzcGFjZUNvdW50ZXIgKiBzaW5nbGVydW5TdHIubGVuZ3RoKSAtIHNwYWNlQ291bnRlcjsKICAgICAgICAgICAgLy8gbG9vayBmb3IgbW9yZSA8Ym9keSAuLi4+Li4uPC9ib2R5PiBtYXRjaGVzCiAgICAgICAgICAgIGJvZHlTdGFydE1hdGNoID0gYm9keVN0YXJ0UkUuZXhlYyh4ZmFTdHIpOwogICAgICAgICAgICBib2R5RW5kTWF0Y2ggPSBib2R5RW5kUkUuZXhlYyh4ZmFTdHIpOwogICAgICAgIH0KICAgICAgICAvLwogICAgICAgIC8vIFN0ZXAgMzogTG9hZCB0aGUgWEZBIGlnbm9yaW5nIHdoaXRlc3BhY2UuCiAgICAgICAgLy8KICAgICAgICAvLyBzYXZlIGN1cnJlbnQgc2V0dGluZ3MKICAgICAgICB2YXIgeG1sU2V0dGluZ3MgPSBYTUwuc2V0dGluZ3MoKTsKICAgICAgICBYTUwuaWdub3JlQ29tbWVudHMgPSBmYWxzZTsKICAgICAgICBYTUwuaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucyA9IGZhbHNlOwogICAgICAgIFhNTC5pZ25vcmVXaGl0ZXNwYWNlID0gdHJ1ZTsKICAgICAgICB2YXIgeGZhWG1sID0gbnVsbDsKICAgICAgICB0cnkgewogICAgICAgICAgICAvLyBSZW1vdmluZyB2ZXJzaW9uIGRldGFpbHMgdG8gcmVzb2x2ZSBFcnJvciAoRXJyb3IgOiBYTUwgZGVjbGFyYXRpb24gYWxsb3dlZCBvbmx5IGF0IHRoZSBzdGFydCBvZiB0aGUgZG9jdW1lbnQpCiAgICAgICAgICAgIHhmYVN0ciA9IHhmYVN0ci5yZXBsYWNlKC9ccypcPFw/eG1sLio/XD9cPi9pLCAiIik7CiAgICAgICAgICAgIC8vIFJlcGxhY2UgYWxsIG5vbi1icmVha2FibGUgc3BhY2UgdG8gc3BhY2UgdW5pY29kZSBpbiBjYXNlIG9mIElFMTAgYXMgQWN0aXZlWCBsb2FkWG1sIGlzIGZhaWxpbmcgaW4geGJlNHgKICAgICAgICAgICAgaWYgKG5zLlJURVV0aWxzLmlzSUUoKSkgewogICAgICAgICAgICAgICAgeGZhU3RyID0geGZhU3RyLnJlcGxhY2UoL1wmbmJzcFw7L2csICImIzE2MDsiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB4ZmFYbWwgPSBuZXcgWE1MKHhmYVN0cik7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChlcnIpIHsKICAgICAgICAgICAgYWxlcnQoImV4Y2VwdGlvbiAiICsgZXJyKTsKICAgICAgICAgICAgLy8gZmFpbCBzaWxlbnRseSBzaW5jZSBjYWxsZXIgbWF5IGJlIHRlc3Rpbmcgc3RyaW5nIGFzIGJlaW5nIHZhbGlkIFhNTAogICAgICAgIH0KICAgICAgICAvLyByZXN0b3JlIHByZXZpb3VzIHNldHRpbmdzCiAgICAgICAgWE1MLnNldFNldHRpbmdzKHhtbFNldHRpbmdzKTsKICAgICAgICAvLwogICAgICAgIC8vIFN0ZXAgMzogUmVzdG9yZSB0aGUgc3Vic3RpdHV0ZWQgc3BhY2VzIGluIHRoZSBYTUwuCiAgICAgICAgdmFyIGk7CiAgICAgICAgaWYgKHhmYVhtbCkgewogICAgICAgICAgICB2YXIgcnVuWG1sID0gbnVsbDsKICAgICAgICAgICAgLy8gcmVzdG9yZSBzcGFjZXJ1bnMKICAgICAgICAgICAgaWYgKHNwYWNlcnVuQ291bnQgPiAwKSB7CiAgICAgICAgICAgICAgICB2YXIgc3BhY2VydW5MaXN0ID0gbnMuWG1sVXRpbC5zZWxlY3ROb2Rlcyh4ZmFYbWwsICJzcGFuIiwgdHJ1ZSwgc3BhY2VydW5TdHlsZSwgInN0eWxlIiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICBpZiAoc3BhY2VydW5MaXN0Lmxlbmd0aCgpICE9IHNwYWNlcnVuQ291bnQpIHsKICAgICAgICAgICAgICAgICAgICB3aW5kb3cuY29uc29sZS53YXJuKCJmb3VuZCAiICsgc3BhY2VydW5Db3VudCArICIgc3BhY2VydW4gbWF0Y2hlcyBidXQgZm91bmQgIiArIHNwYWNlcnVuTGlzdC5sZW5ndGgoKSArICIgc3BhY2VydW4gbm9kZXMiLCBudWxsKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOwogICAgICAgICAgICAgICAgICAgICBpIDwgc3BhY2VydW5MaXN0Lmxlbmd0aCgpOwogICAgICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgICAgICBydW5YbWwgPSBzcGFjZXJ1bkxpc3RbaV07CiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHQgPSBucy5YbWxVdGlsLmdldE5vZGVUZXh0KHJ1blhtbCk7CiAgICAgICAgICAgICAgICAgICAgbnMuWG1sVXRpbC5zZXROb2RlVGV4dChydW5YbWwsIFN0cmluZ0hlbHBlci5yZXBlYXQoIiAiLCB0ZXh0Lmxlbmd0aCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyByZXN0b3JlIG91ciBjdXN0b20gInNpbmdsZXJ1bnMiCiAgICAgICAgICAgIGlmIChzaW5nbGVydW5Db3VudCA+IDApIHsKICAgICAgICAgICAgICAgIHZhciBzaW5nbGVydW5MaXN0ID0gbnMuWG1sVXRpbC5zZWxlY3ROb2Rlcyh4ZmFYbWwsICJzcGFuIiwgdHJ1ZSwgc2luZ2xlcnVuU3R5bGUsICJzdHlsZSIsIHRydWUpOwogICAgICAgICAgICAgICAgaWYgKHNpbmdsZXJ1bkxpc3QubGVuZ3RoKCkgIT0gc2luZ2xlcnVuQ291bnQpIHsKICAgICAgICAgICAgICAgICAgICB3aW5kb3cuY29uc29sZS53YXJuKCJmb3VuZCAiICsgc2luZ2xlcnVuQ291bnQgKyAiIHNpbmdsZXJ1biBtYXRjaGVzIGJ1dCBmb3VuZCBvbmx5ICIgKyBzaW5nbGVydW5MaXN0Lmxlbmd0aCgpICsgIiBzaW5nbGVydW4gbm9kZXMiLCBudWxsKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgaWdub3JlV2hpdGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgIFhNTC5pZ25vcmVXaGl0ZXNwYWNlID0gZmFsc2U7CiAgICAgICAgICAgICAgICAvLyB0ZXh0IG5vZGUgd2l0aCBhIHNpbmdsZSBzcGFjZQogICAgICAgICAgICAgICAgdmFyIHNpbmdsZVhtbCA9IG5ldyBYTUwoIjxzcGFuPiA8L3NwYW4+Iik7CiAgICAgICAgICAgICAgICAvLyBpbnNlcnQgc2luZ2xlIHNwYWNlIHRleHQgbm9kZSBhcyBhIHNpYmxpbmcgb2YgZWFjaCBzaW5nbGVydW4gbm9kZQogICAgICAgICAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgICAgICAgICAgaSA8IHNpbmdsZXJ1bkxpc3QubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgICAgIHJ1blhtbCA9IHNpbmdsZXJ1bkxpc3RbaV07CiAgICAgICAgICAgICAgICAgICAgdmFyIHJ1blBhcmVudFhtbCA9IG5zLlhtbFV0aWwuZ2V0UGFyZW50KHJ1blhtbCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJ1blBhcmVudFhtbCkgewogICAgICAgICAgICAgICAgICAgICAgICBydW5QYXJlbnRYbWwuaW5zZXJ0Q2hpbGRBZnRlcihydW5YbWwsIHNpbmdsZVhtbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBzaW5nbGVydW4gbm9kZQogICAgICAgICAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgICAgICAgICAgaSA8IHNpbmdsZXJ1bkxpc3QubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgICAgIHJ1blhtbCA9IHNpbmdsZXJ1bkxpc3RbaV07CiAgICAgICAgICAgICAgICAgICAgbGV0IGNoaWxkcmVuID0gbnMuWG1sVXRpbC5nZXRBbGxDaGlsZHJlbihydW5QYXJlbnRYbWwpOwogICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSBjaGlsZHJlbi5sZW5ndGggLSAxOyBqID49IDAgOyBqLS0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkcmVuW2pdICE9IG51bGwgJiYgcnVuWG1sID09PSBjaGlsZHJlbltqXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGNoaWxkcmVuW2pdOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gcmVtb3ZlIGFsbCBzaW5nbGVydW5zIGZyb20gdGhlIFhNTAogICAgICAgICAgICAgICAgLy8gbnMuWG1sVXRpbC5yZW1vdmVJdGVtcyhzaW5nbGVydW5MaXN0KTsKICAgICAgICAgICAgICAgICQoc2luZ2xlcnVuTGlzdCkuZW1wdHkoKTsKCiAgICAgICAgICAgICAgICAvLyByZXN0b3JlIG9yaWdpbmFsIHdoaXRlc3BhY2UgZmxhZwogICAgICAgICAgICAgICAgWE1MLmlnbm9yZVdoaXRlc3BhY2UgPSBpZ25vcmVXaGl0ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4geGZhWG1sOwogICAgfTsKICAgIFhmYVV0aWwuZ2V0Tm9kZVRleHQgPSBmdW5jdGlvbiAoeG1sb2JqLCBkZWVwLCBkZWNvZGUpIHsKICAgICAgICBkZWVwID0gZGVlcCAhPT0gdW5kZWZpbmVkID8gZGVlcCA6IHRydWU7CiAgICAgICAgZGVjb2RlID0gZGVjb2RlICE9PSB1bmRlZmluZWQgPyBkZWNvZGUgOiB0cnVlOwoKICAgICAgICB2YXIgbm9kZSA9IHRoaXMuZ2V0WG1sT2JqZWN0KHhtbG9iaik7CgogICAgICAgIGlmICghbm9kZSkgewogICAgICAgICAgICBpZiAodHlwZW9mIHhtbG9iaiA9PSAic3RyaW5nIikgewogICAgICAgICAgICAgICAgcmV0dXJuIGRlY29kZSA/IG5zLlhtbFV0aWwuZGVjb2RlWG1sQ2hhcnMoU3RyaW5nKHhtbG9iaikpIDogU3RyaW5nKHhtbG9iaik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChub2RlLmhhc1NpbXBsZUNvbnRlbnQoKSkgewogICAgICAgICAgICAvLyBhbHdheXMgdXNlIFhNTC50b1N0cmluZygpLCBldmVuIGlmIGl0IGRlY29kZXMgd2hlbiB3ZSBtaWdodCBub3Qgd2FudCBpdCB0bywgYmVjYXVzZSBpdCdsbCBlbnN1cmUgdGhhdCB3ZSBnZXQgZXZlcnl0aGluZywgaW5jbHVkaW5nIHNwYWNlcywKICAgICAgICAgICAgLy8gIGV2ZW4gaWYgdGhlIGNvbnRlbnQgb2YgdGhlIG5vZGUgaXMgb25seSB3aGl0ZXNwYWNlCiAgICAgICAgICAgIHZhciBzaW1wbGVDb250ZW50ID0gbm9kZS50b1N0cmluZygpOwogICAgICAgICAgICBpZiAoIWRlY29kZSkgewogICAgICAgICAgICAgICAgc2ltcGxlQ29udGVudCA9IG5zLlhtbFV0aWwuZW5jb2RlWG1sQ2hhcnMoc2ltcGxlQ29udGVudCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBzaW1wbGVDb250ZW50OwogICAgICAgIH0KCiAgICAgICAgLy9nZXQgYWxsIHRoZSBub2RlJ3MgY2hpbGRyZW4KICAgICAgICB2YXIgY2hpbGROb2RlLCBzVGV4dCA9ICIiOwogICAgICAgIHZhciBsaXN0ID0gbm9kZS5jaGlsZHJlbigpOwoKICAgICAgICBmb3IgKHZhciBpID0gMDsKICAgICAgICAgICAgIGkgPCBsaXN0Lmxlbmd0aDsKICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICBjaGlsZE5vZGUgPSBsaXN0W2ldOwogICAgICAgICAgICBzd2l0Y2ggKGNoaWxkTm9kZS5ub2RlS2luZCgpKSB7CiAgICAgICAgICAgICAgICBjYXNlIG5zLlhtbFV0aWwuTk9ERUtJTkRfVEVYVDoKICAgICAgICAgICAgICAgICAgICBzVGV4dCArPSAoZGVjb2RlID8gY2hpbGROb2RlLnRvU3RyaW5nKCkgOiBjaGlsZE5vZGUudG9YTUxTdHJpbmcoKSk7IC8vIFhNTC50b1N0cmluZygpIGRlY29kZXMgZW5jb2RlZCBYTUwgY2hhcmFjdGVycwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgbnMuWG1sVXRpbC5OT0RFS0lORF9FTEVNRU5UOgogICAgICAgICAgICAgICAgICAgIGlmIChkZWVwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNUZXh0ICs9IG5zLlhtbFV0aWwuZ2V0Tm9kZVRleHQoY2hpbGROb2RlLCBkZWVwLCBkZWNvZGUpOyAvLyByZWN1cnNpdmUgY2FsbAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc1RleHQ7CiAgICB9OwoKICAgIFhmYVV0aWwuUElfRE9NQUlOID0gInhmYWxpYiI7CiAgICBYZmFVdGlsLk5PREVLSU5EX1RFWFQgPSAidGV4dCI7CiAgICBYZmFVdGlsLk5PREVLSU5EX0VMRU1FTlQgPSAiZWxlbWVudCI7CiAgICBYZmFVdGlsLk5PREVLSU5EX0NPTU1FTlQgPSAiY29tbWVudCI7CiAgICBYZmFVdGlsLk5PREVLSU5EX1BJID0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iOwogICAgWGZhVXRpbC5OT0RFS0lORF9BVFRSSUJVVEUgPSAiYXR0cmlidXRlIjsKICAgIFhmYVV0aWwuUElfUkVHRVhQID0gIjxcXD8oP1A8cGlEb21haW4+XFxTKylcXHMrKD9QPHBpS2V5PlxcUyspKD86XFxzPykoP1A8cGlWYWx1ZT4uKilcXD8+IjsKICAgIFhmYVV0aWwuUElfUkVHRVhQX0ZMQUdTID0gImdzIjsKICAgIFhmYVV0aWwuX1BSRVRUWVBSSU5UX0lOREVOVF9DSEFSID0gIiAiOwoKfSkoRm9ybS5ydGUudXRpbCk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCihmdW5jdGlvbiAobnMpIHsKICAgIHZhciBYZmFSaWNoVGV4dFV0aWwgPSBucy5YZmFSaWNoVGV4dFV0aWwgPSBmdW5jdGlvbiAoKSB7CgogICAgICAgIHRoaXMuZXJyb3IgPSBudWxsOwogICAgfTsKCiAgICAvKioKICAgICAqIFRlc3RzIHRoZSBzdXBwbGllZCBzdHJpbmcgdG8gZGV0ZXJtaW5lIGlmIGl0IG9ubHkgY29udGFpbnMgcGxhaW4gdGV4dCBhbmQgbm8gWE1MIGVsZW1lbnRzLCBjb21tZW50cywgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMsIGV0Yy4KICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyaW5nIHRvIHRlc3QgZm9yIHBsYWluIHRleHQuCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgPGNvZGU+dmFsdWU8L2NvZGU+IGlzIHBsYWluIHRleHQ7IGZhbHNlIGlmIG5vdC4KICAgICAqLwogICAgWGZhUmljaFRleHRVdGlsLmlzUGxhaW5UZXh0ID0gZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgdmFyIHBsYWluID0gbnMuWG1sVXRpbC5nZXRYbWxPYmplY3QodmFsdWUpOwoKICAgICAgICBpZiAocGxhaW4pIHsKICAgICAgICAgICAgcmV0dXJuIChwbGFpbi5ub2RlS2luZCgpID09IG5zLlhtbFV0aWwuTk9ERUtJTkRfVEVYVCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CgogICAgLyoqCiAgICAgKiBUZXN0cyB0aGUgc3VwcGxpZWQgc3RyaW5nIHRvIGRldGVybWluZSBpZiBpdCBpcyB2YWxpZCBYRkEgcmljaCB0ZXh0LiBBbGwgWEZBIHJpY2ggdGV4dCBtdXN0IGJlIHZhbGlkIFhNTCBhbmQgaGF2ZSBvbmUgb2YgdGhlIGZvbGxvd2luZwogICAgICogIHRvcC1sZXZlbCBjb250YWluZXIgbm9kZXM6CiAgICAgKiA8dWw+CiAgICAgKiA8bGk+ZXhEYXRhIC0tIG9ubHkgaWYgaW5jbHVkZUV4RGF0YSBpcyB0cnVlIChYRkEgbm9kZSwgaW4gWE1MIGZvcm0sIGV4cGVjdGVkIHRvIGNvbnRhaW4gcmljaCB0ZXh0IGNvbnRlbnQpPC9saT4KICAgICAqIDxsaT5odG1sPC9saT4KICAgICAqIDxsaT5ib2R5PC9saT4KICAgICAqIDxsaT5wPC9saT4KICAgICAqIDwvdWw+CiAgICAgKiBAcGFyYW0gdmFsdWUgQ2FuIGJlIGVpdGhlciBhIFN0cmluZyAod2hpY2ggaXMgY29udmVydGVkIHRvIFhNTCkgb3IgWE1MLgogICAgICogQHBhcmFtIGluY2x1ZGVFeERhdGEgSWYgdHJ1ZSwgJmx0O2V4RGF0YSZndDsgWE1MIG5vZGVzIGFyZSBjb25zaWRlcmVkIGFzIHJpY2ggdGV4dC4KICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYXNzdW1lZCB0byBiZSAob3IgY29udGFpbiwgaW4gdGhlIGNhc2Ugb2YgJmx0O2V4RGF0YSZndDspIHJpY2ggdGV4dDsgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBYZmFSaWNoVGV4dFV0aWwuaXNYZmFSaWNoVGV4dCA9IGZ1bmN0aW9uICh2YWx1ZSwgaW5jbHVkZUV4RGF0YSkgewogICAgICAgIGluY2x1ZGVFeERhdGEgPSBpbmNsdWRlRXhEYXRhICE9PSB1bmRlZmluZWQgPyBpbmNsdWRlRXhEYXRhIDogdHJ1ZTsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwgfHwgISh0eXBlb2YgdmFsdWUgPT0gInN0cmluZyIgfHwgdmFsdWUgaW5zdGFuY2VvZiBYTUwpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHZhciB4ZmEgPSAodmFsdWUgaW5zdGFuY2VvZiBYTUwpID8gdmFsdWUgOiBucy5YZmFVdGlsLmxvYWQodmFsdWUpOwoKICAgICAgICBpZiAoeGZhICYmIHhmYS5ub2RlS2luZCgpID09IG5zLlhtbFV0aWwuTk9ERUtJTkRfRUxFTUVOVCkgewogICAgICAgICAgICBpZiAoKHhmYS5sb2NhbE5hbWUoKSA9PSBYZmFFbGVtLkVYREFUQSAmJiBpbmNsdWRlRXhEYXRhKSB8fAogICAgICAgICAgICAgICAgeGZhLmxvY2FsTmFtZSgpID09ICJodG1sIiB8fAogICAgICAgICAgICAgICAgeGZhLmxvY2FsTmFtZSgpID09IFhmYVhodG1sLkJPRFkgfHwgeGZhLmxvY2FsTmFtZSgpID09ICJwIikgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfTsKCiAgICAvKioKICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygc3R5bGUgb2JqZWN0cyBmb3JtIGEgZ2l2ZW4gQ1NTIHN0cmluZy4KICAgICAqIEBwYXJhbSBzdHlsZVN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuCiAgICAgKiBAcmV0dXJuIEFuIGFycmF5IHdoZXJlIGVhY2ggZWxlbWVudCBpcyBhbiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIGR5bmFtaWMgcHJvcGVydGllczoKICAgICAqICA8dWw+CiAgICAgKiAgIDxsaT5zdHlsZU5hbWUgKFN0cmluZyk6IFRoZSBuYW1lIG9mIHRoZSBzdHlsZS48L2xpPgogICAgICogICA8bGk+c3R5bGVWYWx1ZSAoU3RyaW5nKTogVGhlIHZhbHVlIG9mIHRoZSBzdHlsZS48L2xpPgogICAgICogIDwvdWw+CiAgICAgKi8KICAgIFhmYVJpY2hUZXh0VXRpbC5jcmVhdGVTdHlsZUFycmF5ID0gZnVuY3Rpb24gKHN0eWxlU3RyaW5nKSB7CiAgICAgICAgaWYgKCFzdHlsZVN0cmluZykgewogICAgICAgICAgICByZXR1cm4gW107CiAgICAgICAgfQoKICAgICAgICB2YXIgc1N0eWxlQXJyYXkgPSBzdHlsZVN0cmluZy5zcGxpdCgiOyIpOwogICAgICAgIHZhciBzdHlsZU9iakFycmF5ID0gW107CgogICAgICAgIGZvciAodmFyIGogPSAwOwogICAgICAgICAgICAgaiA8IHNTdHlsZUFycmF5Lmxlbmd0aDsKICAgICAgICAgICAgIGorKykgewogICAgICAgICAgICB2YXIgc1N0eWxlID0gc1N0eWxlQXJyYXlbal07CiAgICAgICAgICAgIC8vIFNraXAgZW1wdHkgc3R5bGUKICAgICAgICAgICAgaWYgKCFzU3R5bGUpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbmFtZVZhbHVlID0gc1N0eWxlLnNwbGl0KCI6Iik7CiAgICAgICAgICAgIGlmIChuYW1lVmFsdWUubGVuZ3RoICE9IDIpIHsKICAgICAgICAgICAgICAgIHdpbmRvdy5jb25zb2xlLndhcm4oc1N0eWxlICsgIiBpcyBub3QgZm9ybWF0dGVkIGNvcnJlY3RseTogc2tpcHBlZCIsIG51bGwpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHNTdHlsZU5hbWUgPSBuYW1lVmFsdWVbMF07CiAgICAgICAgICAgIHZhciBzU3R5bGVWYWx1ZSA9IG5hbWVWYWx1ZVsxXTsKCiAgICAgICAgICAgIHZhciBvU3R5bGUgPSB7fTsKICAgICAgICAgICAgb1N0eWxlLnN0eWxlTmFtZSA9IHNTdHlsZU5hbWU7CiAgICAgICAgICAgIG9TdHlsZS5zdHlsZVZhbHVlID0gc1N0eWxlVmFsdWU7CiAgICAgICAgICAgIHN0eWxlT2JqQXJyYXkucHVzaChvU3R5bGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3R5bGVPYmpBcnJheTsKICAgIH07CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3ICZsdDtib2R5IC4uLi8mZ3Q7IGVsZW1lbnQgd2hpY2ggaXMgdGhlIGNvbnRhaW5lciBmb3IgWEZBIFJpY2ggVGV4dC4KICAgICAqIEByZXR1cm4gVGhlIG5ldyAmbHQ7Ym9keSAuLi4vJmd0OyBlbGVtZW50IGFzIGFuIFhNTCBvYmplY3QuCiAgICAgKi8KICAgIFhmYVJpY2hUZXh0VXRpbC5jcmVhdGVCb2R5RWxlbWVudCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAvLyBYSFRNTCBpcyB0aGUgZGVmYXVsdCBuYW1lc3BhY2UgLS0gbWFrZSBzdXJlIHlvdSBzcGVjaWZ5IGFuIGVtcHR5IHN0cmluZyBwcmVmaXggb3RoZXJ3aXNlIGxhdGVyIGNvZGUgdGhhdCBjYWxscyBuYW1lc3BhY2VEZWNsYXJhdGlvbnMoKQogICAgICAgIC8vICBvbiB0aGlzIG5vZGUgd2lsbCBub3Qgc2VlIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSEKICAgICAgICB2YXIgbnNYaHRtbCA9IG5ldyBOYW1lc3BhY2UoIiIsIFhmYVhodG1sLlhIVE1MTlNVUkkpOwogICAgICAgIHZhciBuc1hmYSA9IG5ldyBOYW1lc3BhY2UoWGZhU2NoZW1hLlhGQU5TLCBYZmFEYXRhLlhGQURBVEFOU1VSSSk7CgogICAgICAgIHZhciB4ZmFCb2R5ID0gbnMuWG1sVXRpbC5jcmVhdGVUYWcoWGZhWGh0bWwuQk9EWSk7CiAgICAgICAgeGZhQm9keS5zZXROYW1lc3BhY2UobnNYaHRtbCk7CiAgICAgICAgeGZhQm9keS5hZGROYW1lc3BhY2UobnNYZmEpOwogICAgICAgIHZhciBhdHRyaWJ1dGUgPSBuZXcgQXR0cmlidXRlTmFtZShRTmFtZShuc1hmYSwgInhmYTpBUElWZXJzaW9uIikpOwogICAgICAgIHhmYUJvZHkuUHV0KCJAeGZhOkFQSVZlcnNpb24iLCBYZmFYaHRtbC5BWFRFQVBJVkVSU0lPTik7CgogICAgICAgIHJldHVybiB4ZmFCb2R5OwogICAgfTsKCn0pKEZvcm0ucnRlLnV0aWwpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTYuIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgooZnVuY3Rpb24gKG5zKSB7CiAgICB2YXIgUGxhaW5UZXh0Rm9ybWF0dGVyID0gbnMuUGxhaW5UZXh0Rm9ybWF0dGVyID0gZnVuY3Rpb24gKCkgewoKICAgICAgICB0aGlzLmVycm9yID0gbnVsbDsKICAgIH07CgogICAgUGxhaW5UZXh0Rm9ybWF0dGVyLnByb3RvdHlwZS5mb3JtYXQgPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICBpZiAodGhpcy5lcnJvcikgewogICAgICAgICAgICB0aGlzLmVycm9yID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIGlmICghdmFsdWUgfHwgU3RyaW5nKHZhbHVlKS5sZW5ndGggPT0gMCkgewogICAgICAgICAgICB0aGlzLmVycm9yID0gIkludmFsaWQgdmFsdWUiOwogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzLmZvcm1hdEFzUGxhaW4odmFsdWUpOwogICAgfTsKCiAgICBQbGFpblRleHRGb3JtYXR0ZXIucHJvdG90eXBlLmZvcm1hdEFzUGxhaW4gPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICB2YXIgaW5wdXRUZXh0OwoKICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBYTUwpIHsKICAgICAgICAgICAgLy8gYXNzdW1lIHRoaXMgY291bGQgYmUgWEZBIGFuZCBiZSBjYXJlZnVsIHdpdGggd2hpdGVzcGFjZQogICAgICAgICAgICBpbnB1dFRleHQgPSBucy5YZmFVdGlsLnByaW50KHZhbHVlKTsKICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PSAic3RyaW5nIikgewogICAgICAgICAgICAvLyBjb3VsZCBiZSBYRkEgUmljaCBUZXh0IFhNTCBpbiBzdHJpbmcgZm9ybWF0IG9yIGNvdWxkIGJlIHBsYWluIHRleHQKICAgICAgICAgICAgaW5wdXRUZXh0ID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhpcy5lcnJvciA9ICJJbnZhbGlkIHR5cGUiOwogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQoKICAgICAgICBpZiAobnMuWGZhUmljaFRleHRVdGlsLmlzUGxhaW5UZXh0KGlucHV0VGV4dCkpIHsKICAgICAgICAgICAgLy8gdmFsdWUgaXMgYWxyZWFkeSBmb3JtYXR0ZWQgYXMgcGxhaW4gdGV4dAogICAgICAgICAgICByZXR1cm4gaW5wdXRUZXh0OwogICAgICAgIH0KCiAgICAgICAgaWYgKG5zLlhmYVJpY2hUZXh0VXRpbC5pc1hmYVJpY2hUZXh0KGlucHV0VGV4dCkpIHsKICAgICAgICAgICAgdmFyIHhmYU5vZGUgPSBucy5YZmFVdGlsLmxvYWQoaW5wdXRUZXh0KTsKICAgICAgICAgICAgdmFyIHhmYVBsYWluVGV4dCA9IHt9OwogICAgICAgICAgICB0aGlzLmZvcm1hdFhmYVBsYWluVGV4dCh4ZmFOb2RlLCB4ZmFQbGFpblRleHQpOwoKICAgICAgICAgICAgaWYgKHhmYVBsYWluVGV4dC5oYXNPd25Qcm9wZXJ0eSgiZXJyb3IiKSkgewogICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IHhmYVBsYWluVGV4dC5lcnJvcjsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiB4ZmFQbGFpblRleHQudGV4dDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLmVycm9yID0gIkludmFsaWQgdmFsdWUiOwogICAgICAgIHJldHVybiAiIjsKICAgIH07CiAgICAvKioKICAgICAqIFRha2VzIGEgbm9kZSByZXByZXNlbnRpbmcgWEZBIFhIVE1MIG1hcmt1cCBhbmQgY29udmVydHMgaXQgaW50byBwbGFpbiB0ZXh0IHdpdGhvdXQgYW55IGZvcm1hdGluZy4KICAgICAqIEBwYXJhbSB4ZmFOb2RlIFtpbl0gWE1MIG5vZGUgcmVwcmVzZW50aW5nIFhGQSByaWNoIHRleHQgbWFya3VwLgogICAgICogQHBhcmFtIHJlc3VsdCBbb3V0XSBEeW5hbWljIG9iamVjdCB3aGljaCwgdXBvbiByZXR1cm4sIGhhcyBhICJ0ZXh0IiBwcm9wZXJ0eSBjb250YWluaW5nIHRoZSBwbGFpbiB0ZXh0IHN0cmluZyBhbmQsCiAgICAgKiAgaWYgYW4gZXJyb3Igb2NjdXJyZWQsIGFuICJlcnJvciIgcHJvcGVydHkgY29udGFpbmluZyB0aGUgZXJyb3IgbWVzc2FnZS4KICAgICAqLwogICAgUGxhaW5UZXh0Rm9ybWF0dGVyLnByb3RvdHlwZS5mb3JtYXRYZmFQbGFpblRleHQgPSBmdW5jdGlvbiAoeGZhTm9kZSwgcmVzdWx0KSB7CiAgICAgICAgaWYgKCF4ZmFOb2RlKSB7CiAgICAgICAgICAgIHJlc3VsdC5lcnJvciA9ICJJbnZhbGlkIFhGQSByaWNoIHRleHQgbWFya3VwIjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdmFyIGNoaWxkWG1sLCBjaGlsZExpc3QgPSB4ZmFOb2RlLmNoaWxkcmVuKCk7CgogICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsKICAgICAgICAgICAgIGluZGV4IDwgY2hpbGRMaXN0Lmxlbmd0aCgpOwogICAgICAgICAgICAgaW5kZXgrKykgewogICAgICAgICAgICBjaGlsZFhtbCA9IGNoaWxkTGlzdFtpbmRleF07CiAgICAgICAgICAgIGlmIChjaGlsZFhtbC5ub2RlS2luZCgpID09IG5zLlhtbFV0aWwuTk9ERUtJTkRfRUxFTUVOVCkgewogICAgICAgICAgICAgICAgdmFyIGxvb2tJbnNpZGUgPSB0cnVlOwogICAgICAgICAgICAgICAgdmFyIGNsYXNzTmFtZSA9IGNoaWxkWG1sLmxvY2FsTmFtZSgpOwoKICAgICAgICAgICAgICAgIHN3aXRjaCAoY2xhc3NOYW1lLnRvVXBwZXJDYXNlKCkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJQIjoKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb252ZXJ0UGFyYVRhZyhyZXN1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAiQlIiOgogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnZlcnRCcmVha1RhZyhyZXN1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRoZSBjb252ZXJzaW9ucyBhcmUgT0sKICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuaGFzT3duUHJvcGVydHkoImVycm9yIikpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGxvb2tJbnNpZGUpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm1hdFhmYVBsYWluVGV4dChjaGlsZFhtbCwgcmVzdWx0KTsKICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0Lmhhc093blByb3BlcnR5KCJlcnJvciIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hpbGRYbWwubm9kZUtpbmQoKSA9PSBucy5YbWxVdGlsLk5PREVLSU5EX1RFWFQpIHsKICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuaGFzT3duUHJvcGVydHkoInRleHQiKSkgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdC50ZXh0ICs9IG5zLlhtbFV0aWwuZ2V0Tm9kZVRleHQoY2hpbGRYbWwpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQudGV4dCA9IG5zLlhtbFV0aWwuZ2V0Tm9kZVRleHQoY2hpbGRYbWwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGVsc2UsIGlnbm9yZSBhdHRyaWJ1dGVzLCBQSXMgYW5kIGNvbW1lbnRzCiAgICAgICAgfQogICAgfTsKCiAgICAvKiogQ29udmVydHMgYSAmbHQ7cCZndDsgdGFnIHRvIHBsYWluIHRleHQuIEFwcGVuZHMgdGhlIHJlc3VsdCB0byB0aGUgcmVzdWx0IG9iamVjdCdzICJ0ZXh0IiBwcm9wZXJ0eS4gKi8KICAgIFBsYWluVGV4dEZvcm1hdHRlci5wcm90b3R5cGUuY29udmVydFBhcmFUYWcgPSBmdW5jdGlvbiAocmVzdWx0KSB7CiAgICAgICAgLy8gaWYgaXQncyBub3QgdGhlIHZlcnkgZmlyc3QgcGFyYWdyYXBoLCBhIHBhcmFncmFwaCBlcXVhbHMgdHdvIG5ldyBsaW5lcwogICAgICAgIGlmIChyZXN1bHQuaGFzT3duUHJvcGVydHkoInRleHQiKSkgewogICAgICAgICAgICByZXN1bHQudGV4dCArPSAiXG5cbiI7CiAgICAgICAgfQogICAgfTsKCiAgICAvKiogQ29udmVydHMgYSAmbHQ7YnImZ3Q7IHRhZyB0byBwbGFpbiB0ZXh0LiBBcHBlbmRzIHRoZSByZXN1bHQgdG8gdGhlIHJlc3VsdCBvYmplY3QncyAidGV4dCIgcHJvcGVydHkuICovCiAgICBQbGFpblRleHRGb3JtYXR0ZXIucHJvdG90eXBlLmNvbnZlcnRCcmVha1RhZyA9IGZ1bmN0aW9uIChyZXN1bHQpIHsKICAgICAgICAvLyBhIGxpbmUgYnJlYWsgaXMgYWx3YXlzIGVxdWFsIHRvIGEgc2luZ2xlIG5ldyBsaW5lCiAgICAgICAgdmFyIG5ld0xpbmUgPSAiXG4iOwoKICAgICAgICBpZiAocmVzdWx0Lmhhc093blByb3BlcnR5KCJ0ZXh0IikpIHsKICAgICAgICAgICAgcmVzdWx0LnRleHQgKz0gbmV3TGluZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHQudGV4dCA9IG5ld0xpbmU7CiAgICAgICAgfQogICAgfTsKfSkoRm9ybS5ydGUudXRpbCk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCihmdW5jdGlvbiAobnMpIHsKICAgIHZhciBIdG1sVXRpbHMgPSBucy5IdG1sVXRpbHMgPSBmdW5jdGlvbiAoKSB7CiAgICB9OwoKICAgIEh0bWxVdGlscy5jYWxjdWxhdGVIdG1sUG9zaXRpb24gPSBmdW5jdGlvbiAoaHRtbHN0ciwgcG9zKSB7CiAgICAgICAgLy8gd2UgcmV0dXJuIC0xIChub3QgZm91bmQpIGlmIHRoZSBwb3NpdGlvbiBpcyBiYWQKICAgICAgICBpZiAocG9zIDw9IC0xKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgICAgIC8vIGNoYXJhY3RlcnMgdGhhdCBhcHBlYXJzIHdoZW4gYSB0YWcgc3RhcnRzCiAgICAgICAgdmFyIG9wZW5UYWdzID0gWyI8IiwgIiYiXTsKICAgICAgICAvLyBjaGFyYWN0ZXJzIHRoYXQgYXBwZWFycyB3aGVuIGEgdGFnIGVuZHMKICAgICAgICB2YXIgY2xvc2VUYWdzID0gWyI+IiwgIjsiXTsKICAgICAgICAvLyB0aGUgdGFnIHNob3VsZCBiZSByZXBsYWNlZCB3aXRoCiAgICAgICAgLy8gZXg6ICZhbXA7IGlzICYgYW5kIGhhcyAxIGFzIGxlbmd0aCBidXQgbm9ybWFsCiAgICAgICAgLy8gdGFncyBoYXZlIDAgbGVuZ3RoCiAgICAgICAgdmFyIHRhZ1JlcGxhY2VMZW5ndGggPSBbMCwgMV07CiAgICAgICAgLy8gZmxhZyB0byBrbm93IHdoZW4gd2UgYXJlIGluc2lkZSBhIHRhZwogICAgICAgIHZhciBpc0luc2lkZVRhZyA9IGZhbHNlOwogICAgICAgIHZhciBjbnQgPSAwOwogICAgICAgIC8vIHRoZSBpZCBvZiB0aGUgdGFnIG9wZW5pbmcgZm91bmQKICAgICAgICB2YXIgdGFnSWQgPSAtMTsKICAgICAgICB2YXIgdGFnQ29udGVudCA9ICIiOwoKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGh0bWxzdHIubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgLy8gaWYgdGhlIGNvdW50ZXIgcGFzc2VzIHRoZSBwb3NpdGlvbiBzcGVjaWZpZWQKICAgICAgICAgICAgLy8gbWVhbnMgdGhhdCB3ZSByZWFjaCB0aGUgdGV4dCBwb3NpdGlvbgogICAgICAgICAgICBpZiAoY250ID49IHBvcykgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gY3VycmVudCBjaGFyCiAgICAgICAgICAgIHZhciBjdXJyZW50Q2hhciA9IGh0bWxzdHIuY2hhckF0KGkpOwogICAgICAgICAgICAvLyBjaGVja2luZyBpZiB0aGUgY3VycmVudCBjaGFyIGlzIGluIHRoZSBvcGVuIHRhZyBhcnJheQogICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG9wZW5UYWdzLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICBpZiAoY3VycmVudENoYXIgPT0gb3BlblRhZ3Nbal0pIHsKICAgICAgICAgICAgICAgICAgICAvLyBzZXQgZmxhZwogICAgICAgICAgICAgICAgICAgIGlzSW5zaWRlVGFnID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAvLyBzdG9yZSB0aGUgdGFnIG9wZW4gaWQKICAgICAgICAgICAgICAgICAgICB0YWdJZCA9IGo7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpc0luc2lkZVRhZykgewogICAgICAgICAgICAgICAgLy8gaW5jcmVtZW50IHRoZSBjb3VudGVyCiAgICAgICAgICAgICAgICBjbnQrKzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIHN0b3JlIHRoZSB0YWcgY29udGVudAogICAgICAgICAgICAgICAgLy8gbmVlZGVkIGFmdGVyd2FyZHMgdG8gZmluZCBuZXcgbGluZXMKICAgICAgICAgICAgICAgIHRhZ0NvbnRlbnQgKz0gY3VycmVudENoYXI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGN1cnJlbnRDaGFyID09IGNsb3NlVGFnc1t0YWdJZF0pIHsKICAgICAgICAgICAgICAgIC8vIHdlIGFkIHRoZSByZXBsYWNlIGxlbmd0aAogICAgICAgICAgICAgICAgaWYgKHRhZ0lkID4gLTEpIHsKICAgICAgICAgICAgICAgICAgICBjbnQgKz0gdGFnUmVwbGFjZUxlbmd0aFt0YWdJZF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBpZiB3ZSBlbmNvdW50ZXIgdGhlIDwvUD4gdGFnIHdlIGluY3JlbWVudCB0aGUgY291bnRlcgogICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBvZiBuZXcgbGluZSBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgIGlmICh0YWdDb250ZW50ID09ICI8L1A+IikgewogICAgICAgICAgICAgICAgICAgIGNudCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gc2V0IGZsYWcKICAgICAgICAgICAgICAgIGlzSW5zaWRlVGFnID0gZmFsc2U7CiAgICAgICAgICAgICAgICAvLyByZXNldCB0YWcgY29udGVudAogICAgICAgICAgICAgICAgdGFnQ29udGVudCA9ICIiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIHJldHVybiB0aGUgcG9zaXRpb24gaW4gaHRtbCB0ZXh0CiAgICAgICAgcmV0dXJuIGk7CiAgICB9OwoKICAgIC8qKgogICAgICogR2l2ZW4gVExGIEh0bWwgVGV4dCwgd2hpY2ggbWVhbnMgdGhlIHN0cmluZyBoYXMgdGhlIGZvcm1hdCA8Y29kZT4mbHQ7aHRtbCZndDsmbHQ7Ym9keSAuLi4mZ3Q7e0hUTUx9Jmx0Oy9ib2R5Jmd0OyZsdDsvaHRtbCZndDs8L2NvZGU+LCByZW1vdmUKICAgICAqICB0aGUgPGNvZGU+Jmx0O2h0bWwmZ3Q7Jmx0O2JvZHkmZ3Q7PC9jb2RlPiByb290IGVsZW1lbnQgYW5kIHJldHVybiB0aGUgY29udGVudC4KICAgICAqIEBwYXJhbSB0bGZIdG1sIFRMRiBleHBvcnRlZCBIdG1sLgogICAgICogQHJldHVybiBUaGUgWEhUTUwgY29udGVudCBvZiB0aGUgVExGIFRleHQuIElmIHRoZSBwcm92aWRlZCBzdHJpbmcgd2Fzbid0IHdyYXBwZWQgaW4gdGhlIGJvZHkgZWxlbWVudCwgdGhlIG9yaWdpbmFsCiAgICAgKiAgc3RyaW5nIGlzIHJldHVybmVkLgogICAgICovCiAgICBIdG1sVXRpbHMuZXh0cmFjdFhodG1sQ29udGVudCA9IGZ1bmN0aW9uICh0bGZIdG1sKSB7CiAgICAgICAgaWYgKCF0bGZIdG1sKSB7CiAgICAgICAgICAgIHJldHVybiB0bGZIdG1sOwogICAgICAgIH0gLy8gbnVsbCBvciBlbXB0eSBzdHJpbmcKCiAgICAgICAgdmFyIFJlZ0V4cHIgPSBYUmVnRXhwKCdePEhUTUw+PEJPRFlbXj5dKj5cXHMqKC4qKVxccyo8XC9CT0RZPjxcL0hUTUw+JywgImdpcyIpOwogICAgICAgIHZhciByZXN1bHQgPSBSZWdFeHByLmV4ZWModGxmSHRtbCk7CiAgICAgICAgaWYgKHJlc3VsdCkgewogICAgICAgICAgICByZXR1cm4gcmVzdWx0WzFdOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRsZkh0bWw7CiAgICB9OwogICAgSHRtbFV0aWxzLnNlYXJjaEJhY2t3YXJkcyA9IGZ1bmN0aW9uIChzb3VyY2UsIHNlYXJjaFRleHQsIGluZGV4UG9zaXRpb24pIHsKICAgICAgICBmb3IgKHZhciBpID0gaW5kZXhQb3NpdGlvbjsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgdmFyIGluZGV4ID0gc291cmNlLmluZGV4T2Yoc2VhcmNoVGV4dCwgaSk7CiAgICAgICAgICAgIGlmIChpbmRleCA9PSBpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gLTE7CiAgICB9OwoKICAgIEh0bWxVdGlscy5zZWFyY2hGb3J3YXJkID0gZnVuY3Rpb24gKHNvdXJjZSwgc2VhcmNoVGV4dCwgaW5kZXhQb3NpdGlvbikgewogICAgICAgIGZvciAodmFyIGkgPSBpbmRleFBvc2l0aW9uOyBpIDwgc291cmNlLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHZhciBpbmRleCA9IHNvdXJjZS5pbmRleE9mKHNlYXJjaFRleHQsIGkpOwogICAgICAgICAgICBpZiAoaW5kZXggPT0gaSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIC0xOwogICAgfTsKCiAgICAvKioKICAgICAqIENvbnZlcnRzIEhUTUwgdG8gWEZBIFhIVE1MLgogICAgICogQHBhcmFtIHN0ciBIVE1MIHRleHQgdG8gY29udmVydC4KICAgICAqIEByZXR1cm4gWEZBIFhIVE1MIGVxdWl2YWxlbnQgYXMgYSA8Y29kZT5TdHJpbmc8L2NvZGU+LiBOb3RlIHRoYXQgd2hpbGUgdGhlIHN0cmluZyBjb250YWlucyBYTUwsIGl0IHdpbGwgYmUgYSBzZXJpZXMgb2YgZWxlbWVudHMgd2l0aG91dAogICAgICogIGEgcm9vdCBub2RlIHdoaWNoIG1lYW5zIGl0IHNob3VsZCBiZSB3cmFwcGVkIGluIGEgcm9vdCBub2RlIGluIG9yZGVyIHRvIGxvYWQgaXQgYXMgdmFsaWQgWE1MLgogICAgICovCgogICAgSHRtbFV0aWxzLnJpY2hUZXh0RWRpdG9yVG9IdG1sID0gZnVuY3Rpb24gKHN0ciwgY29uZmlnKSB7CiAgICAgICAgdmFyIHhtbFNldHRpbmdzID0gWE1MLnNldHRpbmdzKCk7CiAgICAgICAgWE1MLnByZXR0eVByaW50aW5nID0gZmFsc2U7CiAgICAgICAgWE1MLmlnbm9yZVdoaXRlc3BhY2UgPSBmYWxzZTsKCiAgICAgICAgLy9SZW1vdmUgdGhlICI8aHRtbD48Ym9keT4iIHdyYXBwZXIgdGFncyB0aGF0IG1pZ2h0IGhhdmUgYmVlbiBpbnRyb2R1Y2VkIGR1ZSB0byBUTEYgZXhwb3J0ZWQgaHRtbC4KICAgICAgICBzdHIgPSBIdG1sVXRpbHMuZXh0cmFjdFhodG1sQ29udGVudChzdHIpOwoKICAgICAgICAvLyBDb2RlIHRvIGNvbnZlcnQgPGJyPiA8L2JyPiB0byA8YnIvPiBhcyBvdGhlcndpc2UgaXQgZ2V0cyBjb252ZXJ0ZWQgdG8gPGJyPiA8YnI+IGJ5IGlubmVySFRNTAogICAgICAgIHZhciBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPGJyPjxcL2JyPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8YnIvPiIpOwoKICAgICAgICAvLyBDcmVhdGUgWE1MIGRvY3VtZW50CiAgICAgICAgdmFyIFhNTE9iaiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkJPRFkiKTsKICAgICAgICBYTUxPYmouaW5uZXJIVE1MID0gc3RyOwogICAgICAgIC8vIHRlbXBvcmFyeQogICAgICAgIHZhciB0MTsKICAgICAgICB2YXIgdDI7CiAgICAgICAgLy8gcmVtb3ZlIHRoZSBUQUJTVE9QUyBBdHRyaWJ1dGUKICAgICAgICAvL3ZhciBlbGVtZW50cyA9ICQoeG1sT2JqKTsKICAgICAgICAkKFhNTE9iaikuZmluZCgnKicpLnJlbW92ZUF0dHIoJ1RBQlNUT1BTJyk7CgogICAgICAgIC8vIHJlbW92ZSB0aGUgVEFSR0VUIEF0dHJpYnV0ZSBFeGNlcHQgZm9yIEFuY2hvciB0YWcKICAgICAgICAvL3ZhciBlbGVtZW50cyA9ICQoeG1sT2JqKTsKICAgICAgICAkKFhNTE9iaikuZmluZCgnKicpLm5vdCgiYSIpLnJlbW92ZUF0dHIoJ1RBUkdFVCcpOwoKICAgICAgICAvLyBGaW5kIHRoZSBURVhURk9STUFUIExFQURJTkcgQXR0cmlidXRlCiAgICAgICAgJChYTUxPYmopLmZpbmQoJypbTEVBRElOR10nKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHQyID0gJCh0aGlzKTsKICAgICAgICAgICAgdmFyIGxlYWRpbmcgPSBwYXJzZUZsb2F0KHQyLmF0dHIoImxlYWRpbmciKSk7CiAgICAgICAgICAgIHZhciB0MzsKICAgICAgICAgICAgdmFyIHQ0OwogICAgICAgICAgICB2YXIgdDU7CiAgICAgICAgICAgICQodDIpLmZpbmQoJ1AnKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHQ0ID0gJCh0aGlzKTsKICAgICAgICAgICAgICAgIHZhciBzaXplID0gcGFyc2VGbG9hdChsZWFkaW5nKTsKICAgICAgICAgICAgICAgICQodDQpLmZpbmQoJ0ZPTlQnKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB0NSA9ICQodGhpcyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHQ1ICE9IG51bGwgJiYgdDUubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZm9udFNpemUgPSBwYXJzZUZsb2F0KHQ1LmF0dHIoIlNJWkUiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZm9udFNpemUgKyBsZWFkaW5nKSA+IHNpemUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSBmb250U2l6ZSArIGxlYWRpbmc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHZhciBzdHlsZTEgPSAkKHQ0KS5hdHRyKCJzdHlsZSIpOwogICAgICAgICAgICAgICAgaWYgKHN0eWxlMSAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICAvL3JlbW92aW5nIHRoZSBvbGQgbGluZS1oZWlnaHQgaWYgZXhpc3RzIHRvIHVwZGF0ZSB3aXRoIG5ldyBsaW5lLWhlaWdodAogICAgICAgICAgICAgICAgICAgIC8vYXMgY3VycmVudGx5IG5ldyBsaW5lLWhlaWdodCBpcyBhcHBlbmRlZCB0byBzdHlsZSBidXQgbm90IGhvbm91cmVkIGJlY2F1c2Ugb2Ygb2xkIGxpbmUtaGVpZ2h0IHN0aWxsIHByZXNlbnQKICAgICAgICAgICAgICAgICAgICB2YXIgcmVnID0gLyhsaW5lLWhlaWdodDouKj9wdDspL2dpOwogICAgICAgICAgICAgICAgICAgIHN0eWxlMSA9IHN0eWxlMS5yZXBsYWNlKHJlZywgIiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJCh0NCkuYXR0cignc3R5bGUnLCAnbGluZS1oZWlnaHQ6JyArIHNpemUgKyAncHQ7JyArICgodHlwZW9mIHN0eWxlMSA9PSAndW5kZWZpbmVkJykgPyAnJyA6IHN0eWxlMSkpOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgJCh0MikucmVtb3ZlQXR0cignTEVBRElORycpOwogICAgICAgIH0pOwoKICAgICAgICAvLyBGaW5kIGFsbCBMRUZUTUFSR0lOIGluIFRFWFRGT1JNQVQKICAgICAgICAkKFhNTE9iaikuZmluZCgnKltMRUZUTUFSR0lOXScpLmVhY2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgdDIgPSAkKHRoaXMpOwogICAgICAgICAgICB2YXIgbGVmdE1hcmdpbiA9IHBhcnNlRmxvYXQodDIuYXR0cignTEVGVE1BUkdJTicpKTsKICAgICAgICAgICAgJCh0MikuZmluZCgnUCcpLmVhY2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHQ0ID0gKHRoaXMpOwogICAgICAgICAgICAgICAgdmFyIHN0eWxlID0gdDQuYXR0cignc3R5bGUnKTsKICAgICAgICAgICAgICAgIHQ0LmF0dHIoJ3N0eWxlJywgJ21hcmdpbi1sZWZ0OiAnICsgbGVmdE1hcmdpbiArICdwdDsnICsgKCh0eXBlb2Ygc3R5bGUgPT0gJ3VuZGVmaW5lZCcpID8gJycgOiBzdHlsZSkpOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgJCh0MikucmVtb3ZlQXR0cignTEVGVE1BUkdJTicpOwogICAgICAgIH0pOwoKICAgICAgICAvLyBGaW5kIGFsbCBJTkRFTlQgaW4gVEVYVEZPUk1BdAogICAgICAgICQoWE1MT2JqKS5maW5kKCcqW0lOREVOVF0nKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHQyID0gJCh0aGlzKTsKICAgICAgICAgICAgdmFyIGluZGVudCA9IHBhcnNlRmxvYXQodDIuYXR0cignSU5ERU5UJykpOwogICAgICAgICAgICAkKHQyKS5maW5kKCdQJykuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgdDQgPSAkKHRoaXMpOwogICAgICAgICAgICAgICAgdmFyIHN0eWxlID0gdDQuYXR0cignc3R5bGUnKTsKICAgICAgICAgICAgICAgIC8vICBhbGVydCgic3R5bGUxIGluZGVudCIrc3R5bGUpOwogICAgICAgICAgICAgICAgdDQuYXR0cignc3R5bGUnLCAndGV4dC1pbmRlbnQ6ICcgKyBpbmRlbnQgKyAncHQ7JyArICgodHlwZW9mIHN0eWxlID09ICd1bmRlZmluZWQnKSA/ICcnIDogc3R5bGUpKTsKICAgICAgICAgICAgICAgIC8vYWxlcnQoJCh0NCkuYXR0cignc3R5bGUnKSk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICAkKHQyKS5yZW1vdmVBdHRyKCdJTkRFTlQnKTsKICAgICAgICB9KTsKCiAgICAgICAgLy8gRmluZCBhbGwgQUxJR04KICAgICAgICAkKFhNTE9iaikuZmluZCgnKltBTElHTl0nKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHQyID0gJCh0aGlzKTsKICAgICAgICAgICAgdmFyIGFsaWduID0gdDIuYXR0cignQUxJR04nKTsKICAgICAgICAgICAgdmFyIHN0eWxlID0gdDIuYXR0cignc3R5bGUnKTsKICAgICAgICAgICAgLy9hbGVydCgic3R5bGUxIGFsaWduIitzdHlsZSk7CiAgICAgICAgICAgIHQyLmF0dHIoJ3N0eWxlJywgJ3RleHQtYWxpZ246ICcgKyBhbGlnbiArICc7JyArICgodHlwZW9mIHN0eWxlID09ICd1bmRlZmluZWQnKSA/ICcnIDogc3R5bGUpKTsKICAgICAgICAgICAgLy9hbGVydCgkKHQyKS5hdHRyKCdzdHlsZScpKTsKICAgICAgICAgICAgJCh0MikucmVtb3ZlQXR0cignQUxJR04nKTsKICAgICAgICB9KTsKCiAgICAgICAgLy8gRmluZCBhbGwgRkFDRQogICAgICAgICQoWE1MT2JqKS5maW5kKCcqW0ZBQ0VdJykuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciB0MiA9ICQodGhpcyk7CiAgICAgICAgICAgIHZhciBmYWNlID0gdDIuYXR0cignRkFDRScpOwogICAgICAgICAgICB2YXIgc3R5bGUgPSB0Mi5hdHRyKCdzdHlsZScpOwogICAgICAgICAgICAvLyAgYWxlcnQoInN0eWxlMSBmYWNlIitzdHlsZSk7CiAgICAgICAgICAgIHQyLmF0dHIoJ3N0eWxlJywgJ2ZvbnQtZmFtaWx5OiAnICsgZmFjZSArICc7JyArICgodHlwZW9mIHN0eWxlID09ICd1bmRlZmluZWQnKSA/ICcnIDogc3R5bGUpKTsKICAgICAgICAgICAgLy8JYWxlcnQoJCh0MikuYXR0cignc3R5bGUnKSk7CiAgICAgICAgICAgICQodDIpLnJlbW92ZUF0dHIoJ0ZBQ0UnKTsKICAgICAgICB9KTsKICAgICAgICAvLyBGaW5kIGFsbCBTSVpFCiAgICAgICAgJChYTUxPYmopLmZpbmQoJypbU0laRV0nKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHQyID0gJCh0aGlzKTsKICAgICAgICAgICAgdmFyIHNpemUgPSBwYXJzZUZsb2F0KHQyLmF0dHIoJ1NJWkUnKSk7CiAgICAgICAgICAgIHZhciBzdHlsZSA9IHQyLmF0dHIoJ3N0eWxlJyk7CiAgICAgICAgICAgIC8vYWxlcnQoInN0eWxlMSBzaXplIitzdHlsZSk7CiAgICAgICAgICAgIHQyLmF0dHIoJ3N0eWxlJywgJ2ZvbnQtc2l6ZTogJyArIHNpemUgKyAncHQ7JyArICgodHlwZW9mIHN0eWxlID09ICd1bmRlZmluZWQnKSA/ICcnIDogc3R5bGUpKTsKICAgICAgICAgICAgLy9hbGVydCgkKHQyKS5hdHRyKCdzdHlsZScpKTsKICAgICAgICAgICAgJCh0MikucmVtb3ZlQXR0cignU0laRScpOwogICAgICAgIH0pOwoKICAgICAgICAvLyBGaW5kIGFsbCBDT0xPUgogICAgICAgICQoWE1MT2JqKS5maW5kKCcqW0NPTE9SXScpLmVhY2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgdDIgPSAkKHRoaXMpOwogICAgICAgICAgICB2YXIgY29sb3IgPSB0Mi5hdHRyKCdDT0xPUicpOwogICAgICAgICAgICB2YXIgc3R5bGUgPSB0Mi5hdHRyKCdzdHlsZScpOwogICAgICAgICAgICAvL2FsZXJ0KCJzdHlsZTEgY29sb3IgIitzdHlsZSk7CiAgICAgICAgICAgIHQyLmF0dHIoJ3N0eWxlJywgJ2NvbG9yOiAnICsgY29sb3IgKyAnOycgKyAoKHR5cGVvZiBzdHlsZSA9PSAndW5kZWZpbmVkJykgPyAnJyA6IHN0eWxlKSk7CiAgICAgICAgICAgIC8vYWxlcnQoJCh0MikuYXR0cignc3R5bGUnKSk7CiAgICAgICAgICAgICQodDIpLnJlbW92ZUF0dHIoJ0NPTE9SJyk7CiAgICAgICAgfSk7CiAgICAgICAgLy8gRmluZCBhbGwgTEVUVEVSU1BBQ0lORwogICAgICAgICQoWE1MT2JqKS5maW5kKCcqW0xFVFRFUlNQQUNJTkddJykuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciB0MiA9ICQodGhpcyk7CiAgICAgICAgICAgIHZhciBsZXR0ZXJTcGFjaW5nID0gdDIuYXR0cignTEVUVEVSU1BBQ0lORycpOwogICAgICAgICAgICB2YXIgc3R5bGUgPSB0Mi5hdHRyKCdzdHlsZScpOwogICAgICAgICAgICAvL2FsZXJ0KCJzdHlsZTEgbGV0dGVyU3BhY2luZyAiK3N0eWxlKTsKICAgICAgICAgICAgdDIuYXR0cignc3R5bGUnLCAnbGV0dGVyLXNwYWNpbmc6ICcgKyBsZXR0ZXJTcGFjaW5nICsgJ3B0OycgKyAoKHR5cGVvZiBzdHlsZSA9PSAndW5kZWZpbmVkJykgPyAnJyA6IHN0eWxlKSk7CiAgICAgICAgICAgIC8vYWxlcnQoJCh0MikuYXR0cignc3R5bGUnKSk7CiAgICAgICAgICAgICQodDIpLnJlbW92ZUF0dHIoJ0xFVFRFUlNQQUNJTkcnKTsKICAgICAgICB9KTsKICAgICAgICAvLyBGaW5kIGFsbCBLRVJOSU5HCiAgICAgICAgJChYTUxPYmopLmZpbmQoJypbS0VSTklOR10nKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHQyID0gJCh0aGlzKTsKCiAgICAgICAgICAgICQodDIpLnJlbW92ZUF0dHIoJ0tFUk5JTkcnKTsKICAgICAgICB9KTsKCiAgICAgICAgdmFyIGNsZWFuSHRtbCA9IHRoaXMuY2xlYW5IVE1MKFhNTE9iai5pbm5lckhUTUwsIGNvbmZpZyk7CgogICAgICAgIFhNTC5zZXRTZXR0aW5ncyh4bWxTZXR0aW5ncyk7IC8vIHJlc3RvcmUgb3JpZ2luYWwgc2V0dGluZ3MKICAgICAgICByZXR1cm4gY2xlYW5IdG1sOwogICAgfTsKICAgIEh0bWxVdGlscy53cmFwSW5Cb2R5ID0gZnVuY3Rpb24gKGh0bWwpIHsKICAgICAgICBpZiAoaHRtbC5tYXRjaCgvPGJvZHlbXj5dKj5bXHNcU10qPFwvYm9keT4vZ2kpID09IG51bGwpIHsKICAgICAgICAgICAgaHRtbCA9ICc8Ym9keSB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgeG1sbnM6eGZhPSJodHRwOi8vd3d3LnhmYS5vcmcvc2NoZW1hL3hmYS1kYXRhLzEuMC8iIHhmYTpBUElWZXJzaW9uPSIyLjcuMC4wIj4nICsgaHRtbCArICc8L2JvZHk+JzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGh0bWw7CiAgICB9OwoKICAgIC8qKgogICAgICogR2l2ZW4gYSBzdHJpbmcgd2l0aCB0aGUgZm9ybWF0IDxib2R5IC4uLj57WEhUTUx9PC9ib2R5PiwgcmVtb3ZlIHRoZSA8Ym9keT4gcm9vdCBlbGVtZW50IGFuZCBzdXJyb3VuZGluZyB3aGl0ZXNwYWNlIGFuZCByZXR1cm4gdGhlIGNvbnRlbnQKICAgICAqIEBwYXJhbSBodG1sCiAgICAgKi8KICAgIEh0bWxVdGlscy5leHRyYWN0Qm9keUNvbnRlbnQgPSBmdW5jdGlvbiAoaHRtbCkgewogICAgICAgIGlmICghaHRtbCkgewogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQogICAgICAgIC8vIGdpdmVuIGEgc3RyaW5nIHdpdGggdGhlIGZvcm1hdCA8Ym9keSAuLi4+e1hIVE1MfTwvYm9keT4sIHJlbW92ZSB0aGUgPGJvZHk+IHJvb3QgZWxlbWVudCBhbmQgc3Vycm91bmRpbmcgd2hpdGVzcGFjZSBhbmQgcmV0dXJuIHRoZSBjb250ZW50CiAgICAgICAgdmFyIHJlID0gWFJlZ0V4cCgiXlxccyo8Ym9keVtePl0qPlxccyooLiopXFxzKjxcL2JvZHk+XFxzKiQiLCAiZ3MiKTsKICAgICAgICB2YXIgcmVzdWx0ID0gcmUuZXhlYyhodG1sKTsgLy8gd2lsbCByZXR1cm4gbnVsbCBpZiB0aGUgYm9keSBub2RlIGlzIDxib2R5IC4uLi8+CgogICAgICAgIHZhciBjb250ZW50ID0gIiI7CiAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsICYmIHJlc3VsdC5sZW5ndGggPiAxKSB7CiAgICAgICAgICAgIGNvbnRlbnQgPSByZXN1bHRbMV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY29udGVudDsKICAgIH07CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIHRoZSBSaWNoIFRleHQgYW5kIGFkZHMgYWxsIGNvbnRlbnQgaW5zaWRlIDxwPjxzcGFuPjwvc3Bhbj48L3A+CiAgICAgKiBAcGFyYW0gc3RyCiAgICAgKiBAcmV0dXJucyByZXR1cm5zIHRoZSBmb3JtYXR0ZWQgc3RyaW5nCiAgICAgKi8KICAgIEh0bWxVdGlscy5jbGVhblJpY2hUZXh0ID0gZnVuY3Rpb24gKHN0ciwgY29uZmlnKSB7CgogICAgICAgIC8vUmVwbGFjZSBEaXYncyB3aXRoIHBhcmEgdGFnCiAgICAgICAgdmFyIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8ZGl2JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgJzxwJyk7CgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8L2Rpdj4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAnPC9wPicpOwoKICAgICAgICAvL01vdmUgYWxsIG91dHNpZGUgY29udGVudCBhZnRlciA8L3A+IGluc2lkZSBwID4gc3BhbgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCdcL3A+KFtePF0rfDxicj48L2JyPikoPHB8W148XSokKScsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICJcL3A+PHA+PHNwYW4+JDE8L3NwYW4+PFwvcD4kMiIpOwoKICAgICAgICAvL01vdmUgYWxsIG91dHNpZGUgY29udGVudCBiZWZvcmUgPHA+IGluc2lkZSBwID4gc3BhbgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCcoXltePF0rfDxicj48L2JyPikoPHB8W148XSokKScsICdpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxwPjxzcGFuPiQxPC9zcGFuPjxcL3A+JDIiKTsKCiAgICAgICAgLy9Nb3ZlIHBhcmEgY29udGVudCB3aXRob3V0IGFueSBzcGFuIHdpdGhpbiBzcGFuCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJyg8cFtePF0qPikoKCg/ISgoPHNwYW4pfCg8XC9wPikpKS4pKik8XC9wPicsJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiQxPHNwYW4+JDI8XC9zcGFuPjxcL3A+Iik7CgogICAgICAgIC8vIGVtcHR5IGxpbmVzIHdpbGwgZ2V0IGxvc3QgaWYgdGhleSBkb24ndCBjb250YWluIGF0IGxlYXN0IG9uZSBzcGFjZQogICAgICAgIC8vIGFuIGVtcHR5IGxpbmUgd2lsbCBtYXkgbG9vayBsaWtlIDxwIC4uLj48c3BhbiAuLi4+PHNwYW4gLi4uPjwvc3BhbiAuLi4+PC9zcGFuIC4uLj48L3A+IHNvIHJlcGxhY2UgaXQgd2l0aCA8cCAuLi4+PHNwYW4gLi4uPjxzcGFuIC4uLj48L3NwYW4gLi4uPjwvc3BhbiAuLi4+PC9wPgogICAgICAgIC8vKGF0IGxlYXN0IG9uZSBzcGFuIHNob3VsZCBoYXZlIHNpbmdsZSBzcGFjZSBhcyBjb250ZW50KQogICAgICAgIC8vICBzbyB0aGF0IHdoZW4gd2UgYWRkICd4ZmEtc3BhY2VydW46eWVzJyB0byBhbGwgc3BhbiBzdHlsZXMgKGxhdGVyKSwgdGhlIHNwYWNlIGlzIHJldGFpbmVkIGFuZCB0aGUgQWRvYmUgVGV4dCBFbmdpbmUgcmVuZGVycyB0aGUgZW1wdHkgbGluZQoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPHAoW14+XSopPiguKj8pPFwvcD4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCBIdG1sVXRpbHMuY29udmVydEVtcHR5UGFyYVRvWGh0bWwpOwoKICAgICAgICAvL1JlbW92ZSBFbXB0eSBQYXJhCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxwKFtePl0qKT48XC9wPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICcnKTsKCiAgICAgICAgLy9BZGQgZGVmYXVsdCBzdHlsZXMgdG8gbGkgYWxyZWFkeSBjb250YWluaW5nIHN0eWxlIGF0dHJpYnV0ZQogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8bGkoW148XSopIHN0eWxlPSIoW148Il0qKSIoW148XSopPicsICdnaScpOwogICAgICAgIHZhciByZXN1bHQgPSBwYXR0ZXJuLmV4ZWMoc3RyKTsKICAgICAgICB3aGlsZSAocmVzdWx0ICYmIHJlc3VsdC5sZW5ndGggPiAzKSB7CiAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHJlc3VsdFswXSwgJzxsaScgKyByZXN1bHRbMV0gKyAnIHN0eWxlPSInICsgSHRtbFV0aWxzLmdldE1pc3NpbmdQYXJhU3R5bGUocmVzdWx0WzJdLCBjb25maWcpICsgJyInICsgcmVzdWx0WzNdICsgJz4nKTsKICAgICAgICAgICAgcmVzdWx0ID0gcGF0dGVybi5leGVjKHN0cik7CiAgICAgICAgfQoKICAgICAgICAvL0FkZCBkZWZhdWx0IHN0eWxlIHRvIGxpCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxsaSgoKD8hc3R5bGU9IilbXj5dKSopPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICc8bGkgc3R5bGU9IicgKyBIdG1sVXRpbHMuZ2V0RGVmYXVsdFBhcmFTdHlsZShjb25maWcpICsgJyI+Jyk7CgogICAgICAgIC8vUmVwbGFjaW5nIGFsbCBwYXJhIGluc2lkZSBsaSB0byB0ZW1wIHRhZyB0byBhdm9pZCBkZWZhdWx0IHN0eWxlIHRvIGJlIGFkZGVkLgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8bGkoW14+XSopPihbXjxdKik8cChbXj5dKik+KCgoPyE8cCkuKSopPC9wPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICc8bGkkMT4kMjx0ZW1wJDM+JDQ8L3RlbXA+Jyk7CgogICAgICAgIC8vQWRkIGRlZmF1bHQgc3R5bGVzIHRvIHBhcmEgYWxyZWFkeSBjb250YWluaW5nIHN0eWxlIGF0dHJpYnV0ZQogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8cChbXjxdKikgc3R5bGU9IihbXjwiXSopIihbXjxdKik+JywgJ2dpJyk7CiAgICAgICAgdmFyIHJlc3VsdCA9IHBhdHRlcm4uZXhlYyhzdHIpOwogICAgICAgIHdoaWxlIChyZXN1bHQgJiYgcmVzdWx0Lmxlbmd0aCA+IDMpIHsKICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocmVzdWx0WzBdLCAnPHAnICsgcmVzdWx0WzFdICsgJyBzdHlsZT0iJyArIEh0bWxVdGlscy5nZXRNaXNzaW5nUGFyYVN0eWxlKHJlc3VsdFsyXSwgY29uZmlnKSArICciJyArIHJlc3VsdFszXSArICc+Jyk7CiAgICAgICAgICAgIHJlc3VsdCA9IHBhdHRlcm4uZXhlYyhzdHIpOwogICAgICAgIH0KCiAgICAgICAgLy9BZGQgZGVmYXVsdCBzdHlsZSB0byBwYXJhCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxwKCgoPyFzdHlsZT0iKVtePl0pKik+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgJzxwIHN0eWxlPSInICsgSHRtbFV0aWxzLmdldERlZmF1bHRQYXJhU3R5bGUoY29uZmlnKSArICciPicpOwoKICAgICAgICAvL0NoYW5naW5nIHRlbXAgdGFnIGJhY2sgdG8gcGFyYQogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8dGVtcChbXj5dKik+KCgoPyE8dGVtcCkuKSopPC90ZW1wPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICc8cCQxPiQyPC9wPicpOwoKICAgICAgICByZXR1cm4gc3RyOwogICAgfTsKCiAgICAvKioKICAgICAqIENsZWFucyBhbiBhbHJlYWR5IHNvbWV3aGF0IGZvcm1hdHRlZCBYSFRNTCBzdHJpbmcgY29udmVydGVkIGZyb20gSFRNTC4KICAgICAqIEBwYXJhbSBzdHIgUGFydGlhbGx5LWNvbnZlcnRlZCBYRkEgWEhUTUwgY29udGVudCBmcm9tIEhUTUwgc291cmNlLiBUaGUgc3RyaW5nIGlzIGV4cGVjdGVkIHRvIGNvbnRhaW4gbXVsdGlwbGUKICAgICAqICBlbGVtZW50cyB3aXRob3V0IGEgcm9vdCBub2RlLgogICAgICogQHJldHVybiBYRkEgWEhUTUwgY29udGVudCwgZnVsbHktY29udmVydGVkLCBjb250YWluaW5nIG11bHRpcGxlIGVsZW1lbnRzIHdpdGhvdXQgYSByb290IG5vZGUuCiAgICAgKi8KICAgIEh0bWxVdGlscy5jbGVhbkhUTUwgPSBmdW5jdGlvbiAoc3RyLCBjb25maWcpIHsKCiAgICAgICAgaWYgKHN0ciA9PSAiIikgewogICAgICAgICAgICByZXR1cm4gc3RyOwogICAgICAgIH0KCiAgICAgICAgLy9UT0RPOiBXaHkgd2UgbmVlZCB0byByZXBsYWNlIHRoZXNlLiBUaGVuIHdlIHNob3VsZCBjb3JyZWN0IHRoZSByZWdleAogICAgICAgIC8qIHJlcGxhY2UgYWxsIGVtcHR5IGxpbmVzIHRoYXQgYXJlIGZvcm1hdHRlZCB3aXRoIGJ1bGxldCBzdHlsZQogICAgICAgICB2YXIgcGF0dGVybjpSZWdFeHAgPSAvKDxURVhURk9STUFULio/Pik/PExJPjxGT05UXHNbXj5dKj9cLz8+KDwoQnxJfFUpPikqPyg8XC8oQnxJfFUpPikqPyg8XC9GT05UPik/PFwvTEk+KDxcL1RFWFRGT1JNQVQ+KT8vaWc7CiAgICAgICAgIHZhciBzdHI6U3RyaW5nID0gc3RyaW5nLnJlcGxhY2UocGF0dGVybiwgIjxwLz4iKTsgKi8KICAgICAgICAvLyBmb3JtYXQgPGluZGVudD4gdGFnCgogICAgICAgIHZhciBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnVEVYVEZPUk1BVCcsICJnaSIpOwoKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiU1BBTiIpOwogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCdDT0xPUj1cIiguKj8pXCInLCAnZ2knKTsKCiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgImNvbG9yOiQxOyIpOwogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCdTSVpFPVwiKC4qPylcIicsICdnaScpOwoKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiZm9udC1zaXplOiQxcHQ7Iik7CiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJ0ZBQ0U9IiguKj8pXCIvJywgJ2dpJyk7CgogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICJmb250LWZhbWlseTokMTsiKTsKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnQUxJR049XCIoLio/KVwiJywgJ2dpJyk7CgogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICJ0ZXh0LWFsaWduOiQxOyIpOwoKICAgICAgICAvLyBmb3JtYXQgPGluZGVudD4gdGFnCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJ0lOREVOVD1cIiguKj8pXCInLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAidGV4dC1pbmRlbnQ6JDE7Iik7CgogICAgICAgIC8vZm9ybWF0IDxmb250PiB0YWcKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPEZPTlQgU1RZTEUnLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPHNwYW4gc3R5bGUiKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxGT05UPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8c3Bhbj4iKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxcL0ZPTlQ+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxcL3NwYW4+Iik7CgogICAgICAgIC8vTEs6IHJlcGxhY2UgZW1wdHkgPEZPTlQvPiB0YWdzCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxGT05UXC8+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiIpOwoKICAgICAgICAvL2Zvcm1hdCA8cD4gdGFnCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxQIFNUWUxFJywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxwIHN0eWxlIik7CgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8XC9QPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8XC9wPiIpOwoKICAgICAgICAvL2Zvcm1hdCA8YT4gdGFnCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxBIEhSRUYnLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPGEgaHJlZiIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPFwvQT4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPFwvYT4iKTsKCiAgICAgICAgLy9mb3JtYXQgPHNwYW4+IHRhZwogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8U1BBTiBTVFlMRScsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8c3BhbiBzdHlsZSIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPFNQQU4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPHNwYW4iKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxcL1NQQU4+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxcL3NwYW4+Iik7CgogICAgICAgIHZhciBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPGJyPig/ITxcL2JyPiknLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPGJyPjxcL2JyPiIpOwoKICAgICAgICAvLyByZW1vdmUgYW55IGJ1bGxldHMgd2UgbWlnaHQgZmluZCBzaW5jZSB3ZSBkb24ndCBzdXBwb3J0IGJ1bGxldGluZyBpbiBhIHRleHQgbW9kdWxlCiAgICAgICAgLy8gcGF0dGVybiA9IC88TEk+L2dpOwogICAgICAgIC8vIHZhciBidWxsZXRGb3JtYXQ6U3RyaW5nID0gIjxwPiI7CiAgICAgICAgLy8gc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgYnVsbGV0Rm9ybWF0KTsKICAgICAgICAvLyBwYXR0ZXJuPSAvPFwvTEk+L2dpOwogICAgICAgIC8vIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8L3A+Iik7CgogICAgICAgIC8vVE9ETzogY291bnQgY29ubmVjdGVkIFx0IG9jY3VycmVuY2VzIGFuZCBhZGQgb25seSBvbmUgc3BhbiB0YWcgd2l0aCB0aGUgcmlnaHQgdGFiLWNvdW50IHByb3BlcnR5CiAgICAgICAgLy9yZXBsYWNlIGFsbCBcdCBlc2NhcGUgY2hhcmFjdGVycyB3aXRoIFx0IGFuZCB4ZmEgdGFiIHNpbmNlIFx0IGlzIG5vdCBob25vdXJlZCB3aGlsZSBwcmV2aWV3aW5nIGxldHRlciBpbiBDQ1IKICAgICAgICAvLyBhbmQgeGZhIHRhYiBpcyBub3QgaG9ub3VyZWQgaW4gSFRNTCB0ZXh0IGVkaXRvci4KICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnXHQoPyEoPHNwYW4gc3R5bGU9InhmYS10YWItY291bnQ6MSI+PFwvc3Bhbj4pKScsICdnJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIlx0PHNwYW4gc3R5bGU9XCJ4ZmEtdGFiLWNvdW50OjFcIj48L3NwYW4+Iik7CgogICAgICAgIC8vZG8gVmFyaWFibGUgcmVwbGFjZW1lbnQKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnKFx7XCQoLio/KVwkXH0pJywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxzcGFuIHhmYTplbWJlZFR5cGU9XCJ1cmlcIiB4ZmE6ZW1iZWRNb2RlPVwicmF3XCIgeGZhOmVtYmVkPVwiJDJcIj4kMTwvc3Bhbj4iKTsKCiAgICAgICAgLy8gZm9ybWF0IDx1bD4gdGFnIC0tIHdlIGRvbid0IHN1cHBvcnQgbGlzdHMsIHNvIHJlbW92ZSB0aGVzZSB0YWdzIHNpbmNlIGVhY2ggbGlzdCBpdGVtIHdlIG1heSBoYXZlIGZvdW5kIHdpbGwgbm93IGJlIGl0cyBvd24gcGFyYWdyYXBoCiAgICAgICAgLy8gcGF0dGVybj0gLzxVTD4vZ2k7CiAgICAgICAgLy8gc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiIpOwogICAgICAgIC8vIHBhdHRlcm49IC88XC9VTD4vZ2k7CiAgICAgICAgLy8gc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiIpOwogICAgICAgIC8vIGZvcm1hdCA8b2w+IHRhZyAtLSB3ZSBkb24ndCBzdXBwb3J0IGxpc3RzLCBzbyByZW1vdmUgdGhlc2UgdGFncyBzaW5jZSBlYWNoIGxpc3QgaXRlbSB3ZSBtYXkgaGF2ZSBmb3VuZCB3aWxsIG5vdyBiZSBpdHMgb3duIHBhcmFncmFwaAogICAgICAgIC8vIHBhdHRlcm49IC88T0w+L2dpOwogICAgICAgIC8vIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICIiKTsKICAgICAgICAvLyBwYXR0ZXJuPSAvPFwvT0w+L2dpOwogICAgICAgIC8vIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICIiKTsKCiAgICAgICAgLy9mb3JtYXQgYWxpZ25tZW50IGluIHN0eWxlcyB0YWcKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgndGV4dC1hbGlnbjogUklHSFQnLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAidGV4dC1hbGlnbjogcmlnaHQiKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJ3RleHQtYWxpZ246IExFRlQnLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAidGV4dC1hbGlnbjogbGVmdCIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgndGV4dC1hbGlnbjogQ0VOVEVSJywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgInRleHQtYWxpZ246IGNlbnRlciIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgndGV4dC1hbGlnbjogSlVTVElGWScsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICJ0ZXh0LWFsaWduOiBqdXN0aWZ5Iik7CgogICAgICAgIC8vdGhpcyBpcyB0byBmaXggYSBidWcKICAgICAgICAvL2ZvciBzb21lIHJlYXNvbiB0aGVyZSBpcyBhIFUvQi9JLyB0YWcgc2hvd2luZyB1cD8KCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxVXC8+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPFU+PFwvVT4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiIik7CgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8VT48YnI+PC9VPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8YnI+PC9icj4iKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxVPjxicj48XC9icj48L1U+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxicj48L2JyPiIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPEJcLz4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiIik7CgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8Qj48XC9CPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICIiKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxCPjxicj48L0I+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxicj48L2JyPiIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPEI+PGJyPjxcL2JyPjwvQj4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPGJyPjwvYnI+Iik7CgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8SVwvPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICIiKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxJPjxcL0k+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPEk+PGJyPjwvST4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPGJyPjwvYnI+Iik7CgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8ST48YnI+PFwvYnI+PC9JPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8YnI+PC9icj4iKTsKCiAgICAgICAgLy9MSzogcCBpbiBzcGFuIHNob3VsZCBub3QgaGFwcGVuLi4uCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxzcGFuPlxzKjxwICcsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8cCAiKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxcL3A+XHMqPFwvc3Bhbj4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPC9wPiIpOwoKICAgICAgICAvL0xLIGF2b2lkIGJsYW5rcyBhdCBiZWdpbm5pbmcgb2YgbGluZXMKICAgICAgICAvLyB3ZSBuZWVkIHRvIGFzc2VtYmxlIHNwYW4gdGFncwogICAgICAgIC8vcGF0dGVybiA9IC88c3BhbiBzdHlsZT0iKFteIl0qKSI+W148XSo8c3BhbiBzdHlsZT0iKFteIl0qKSI+KFtePF0qKTxcL3NwYW4+XHMqPFwvc3Bhbj4vZ2k7CiAgICAgICAgLy9TU1QgMDkuMDUuMDggOiBBc3NlbWJsZSBzcGFuIHRhZ3MgaW4gY2FzZSB0aGVyZSBpcyBubyBvdGhlciB0ZXh0IGJldHdlZW4gdGhlIHNwYW4gdGFncwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPHNwYW4gc3R5bGU9IihbXiJdKikiPjxzcGFuIHN0eWxlPSIoW14iXSopIj4oW148XSopPFwvc3Bhbj5ccyo8XC9zcGFuPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sIEh0bWxVdGlscy5tZXJnZVhodG1sU3BhblN0eWxlcyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgSHRtbFV0aWxzLm1lcmdlWGh0bWxTcGFuU3R5bGVzKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCBIdG1sVXRpbHMubWVyZ2VYaHRtbFNwYW5TdHlsZXMpOwoKICAgICAgICAvLyBSZXBsYWNlIG11bHRpcGxlIHNwYWNlcyB3aXRoICYjMTYwOwogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCcgICcsICdnJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiYjMTYwOyYjMTYwOyIpOwoKICAgICAgICAvLyByZXBsYWNpbmcgYWxsICZuYnNwOyB0byAmIzE2MDsKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnJm5ic3A7JywgJ2cnKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiJiMxNjA7Iik7CgogICAgICAgIHN0ciA9IEh0bWxVdGlscy5jbGVhblJpY2hUZXh0KHN0ciwgY29uZmlnKTsKCiAgICAgICAgLy9uZXh0IGFsbCBzcGFucyB3aXRoIHhmYS1zcGFjZXJ1bjp5ZXM6CiAgICAgICAgLy9wYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPHNwYW4gc3R5bGU9IihbXiJdKikiPicsJ2dpJyk7CiAgICAgICAgLy9zdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPHNwYW4gc3R5bGU9XCIkMTsgeGZhLXNwYWNlcnVuOnllc1wiPiIpOwogICAgICAgIC8vU3BhY2VzIGJldHdlZW4gdGhlIHRhZ3Mgd2lsbCBnZXQgbG9zdCBpZiB0aGV5IGRvbid0IG93biBTcGFucwogICAgICAgIC8vTW92aW5nIHRhYnMvd2hpdGUtc3BhY2VzIG91dHNpZGUgaHRtbCB0YWdzIGluc2lkZSBzcGFuIHRhZwogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc+KFsgXHRdKyk8PyEoXC8pJywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIj48c3BhbiBzdHlsZT1cInhmYS1zcGFjZXJ1bjp5ZXNcIj4kMTwvc3Bhbj48Iik7CgogICAgICAgIC8vTEs6IEZvcm1hdHRpbmcgb2YgdmFyaWFibGVzIG11c3QgYmUgY2hvc2VuLCBvdGhlcndpc2UgaXQgd2lsbCBiZSBsb3N0IHdoZW4gcmVwbGFjaW5nCiAgICAgICAgLy8gICAgdGhlIHZhcmlhYmxlcyBieSBpdHMgdmFsdWUKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPHNwYW4geGZhOmVtYmVkVHlwZT0idXJpIiB4ZmE6ZW1iZWRNb2RlPSJyYXciIHhmYTplbWJlZD0iKFteIl0qKSI+XHMqPHNwYW4gc3R5bGU9KFtePl0qKT4oW148XSopPFwvc3Bhbj5ccyo8XC9zcGFuPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8c3BhbiBzdHlsZT0kMj48c3BhbiB4ZmE6ZW1iZWRUeXBlPVwidXJpXCIgeGZhOmVtYmVkTW9kZT1cInJhd1wiIHhmYTplbWJlZD1cIiQxXCI+JDM8L3NwYW4+PC9zcGFuPiIpOwoKICAgICAgICByZXR1cm4gc3RyOwogICAgfTsKCiAgICAvKioKICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBhcyByZXBsYWNlbWVudCBmdW5jdGlvbiB0byBhc3NlbWJsZSBzcGFuIHRhZ3MgaW4gY2FzZSB0aGVyZSBpcyBubyBvdGhlciB0ZXh0IGJldHdlZW4gdGhlIHNwYW4gdGFncwogICAgICogcGF0dGVybiA9IC88c3BhbiBzdHlsZT0iKFteIl0qKSI+W148XSo8c3BhbiBzdHlsZT0iKFteIl0qKSI+KFtePF0qKTxcL3NwYW4+XHMqPFwvc3Bhbj4vZ2k7CiAgICAgKiBwYXJhbSBhcmd1bWVudHMKICAgICAqIEByZXR1cm4KICAgICAqCiAgICAgKi8KICAgIEh0bWxVdGlscy5tZXJnZVhodG1sU3BhblN0eWxlcyA9IGZ1bmN0aW9uICgpIHsKCiAgICAgICAgLy9UaGVyZSBzaG91bGQgYmUgdGhyZWUgZ3JvdXBzIGluIG1hdGNoZWQgc3RyaW5nczogb3V0ZXIgc3BhbiBzdHlsZXMsIGlubmVyIHNwYW4gc3R5bGVzLCBpbm5lciBzcGFuIGNvbnRlbnRzLiBJZiB0aGF0J3Mgbm90IHRoZSBjYXNlLCByZXR1cm4gdGhlIG9yaWdpbmFsIHN0cmluZwoKICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCAhPSA2KSB7CiAgICAgICAgICAgIHJldHVybiBhcmd1bWVudHNbMF07CiAgICAgICAgfQoKICAgICAgICB2YXIgb3V0ZXJTdHlsZXNTdHIgPSBhcmd1bWVudHNbMV07CiAgICAgICAgdmFyIGlubmVyU3R5bGVzID0gYXJndW1lbnRzWzJdOwogICAgICAgIHZhciBzcGFuQ29udGVudCA9IGFyZ3VtZW50c1szXTsKCiAgICAgICAgdmFyIG1hcmdlZFN0eWxlcyA9IChpbm5lclN0eWxlcyAhPSBudWxsKSA/IGlubmVyU3R5bGVzIDogIiI7CiAgICAgICAgdmFyIG91dGVyU3R5bGVzID0gb3V0ZXJTdHlsZXNTdHIuc3BsaXQoIjsiKTsKCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvdXRlclN0eWxlcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICB2YXIgb3V0ZXJTdHlsZSA9IG91dGVyU3R5bGVzW2ldOwogICAgICAgICAgICBpZiAob3V0ZXJTdHlsZS5pbmRleE9mKCI6IikgPiAwKSB7CiAgICAgICAgICAgICAgICB2YXIgc3R5bGVOYW1lID0gb3V0ZXJTdHlsZS5zdWJzdHJpbmcoMCwgb3V0ZXJTdHlsZS5pbmRleE9mKCI6IikpOwogICAgICAgICAgICAgICAgc3R5bGVOYW1lID0gc3R5bGVOYW1lLnRyaW0oKTsKICAgICAgICAgICAgICAgIGlmIChtYXJnZWRTdHlsZXMudG9Mb3dlckNhc2UoKS5pbmRleE9mKHN0eWxlTmFtZS50b0xvd2VyQ2FzZSgpKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICBtYXJnZWRTdHlsZXMgPSBtYXJnZWRTdHlsZXMgKyAiOyAiICsgb3V0ZXJTdHlsZS50cmltKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICI8c3BhbiBzdHlsZT1cIiIgKyBtYXJnZWRTdHlsZXMgKyAiXCI+IiArIHNwYW5Db250ZW50ICsgIjwvc3Bhbj4iOwogICAgfTsKCiAgICAvKioKICAgICAqIEhhbmRsZXMgdGhlIHBhcmFncmFwaCB0aGF0IGRvZXMgbm90IGhhdmUgYW55IGNvbnRlbnQgdG8gaW5zZXJ0IGEgZW1wdHkgc3BhY2Ugc28gdGhhdCBjYW4gYmUgdXNlZCB3aXRoIHNwYWNlIHJ1bgogICAgICogdG8gc2hvdyBuZXcgbGluZXMgaW4geGZhIGZvciBlbXB0eSBwYXJhLgogICAgICogTm90ZTogdGhpcyBkb2VzIG5vdCBleHBsaWNpdGx5IGFkZHMgeGZhLXNwYWNlcnVuIHRvIHNwYW4gdGFncwogICAgICogcGFyYW0gYXJndW1lbnRzCiAgICAgKiBAcmV0dXJuCiAgICAgKi8KCiAgICBIdG1sVXRpbHMuY29udmVydEVtcHR5UGFyYVRvWGh0bWwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHN0ciA9IFN0cmluZyhhcmd1bWVudHNbMF0pOwogICAgICAgIHZhciBwbGFpblRleHRGb3JtYXR0ZXIgPSBuZXcgbnMuUGxhaW5UZXh0Rm9ybWF0dGVyKCk7CiAgICAgICAgdmFyIHBsYWluVGV4dCA9IHBsYWluVGV4dEZvcm1hdHRlci5mb3JtYXQoc3RyKTsKICAgICAgICAvL2lmKCEocGxhaW5UZXh0KSAmJiAhKGVycm9yKSl7CiAgICAgICAgaWYgKCEocGxhaW5UZXh0KSkgewogICAgICAgICAgICB2YXIgc3RyMSA9IHN0cjsKICAgICAgICAgICAgLy9IYW5kbGUgYm90aCBleHBhbmRlZCBhbmQgbm9uIGV4cGFuZGVkIHNwYW4uCgogICAgICAgICAgICB2YXIgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxzcGFuKFtePl0qKVwvPicsICdpJyk7CiAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8c3BhbiQxPiA8L3NwYW4+Iik7CgogICAgICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPHNwYW4oW14+XSopXD48XC9zcGFuPicsICdpJyk7CiAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8c3BhbiQxPiA8L3NwYW4+Iik7CgogICAgICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPHNwYW4oW14+XSopPltccyBdKjwvc3Bhbj4nLCAnaScpOwogICAgICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPHNwYW4kMT48YnI+PC9icj48L3NwYW4+Iik7CgogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHN0cjsKICAgIH07CgogICAgSHRtbFV0aWxzLmdldERlZmF1bHRQYXJhU3R5bGUgPSBmdW5jdGlvbiAoY29uZmlnKSB7CiAgICAgICAgdmFyIHN0eWxlID0gIiI7CiAgICAgICAgaWYgKGNvbmZpZykgewogICAgICAgICAgICBzdHlsZSArPSAnZm9udC1mYW1pbHk6JyArIGNvbmZpZy5mb250RmFtaWx5LmRlZmF1bHRWYWx1ZSArICc7JzsKICAgICAgICAgICAgc3R5bGUgKz0gJ2ZvbnQtc2l6ZTonICsgY29uZmlnLmZvbnRTaXplLmRlZmF1bHRWYWx1ZSArICdwdDsnOwogICAgICAgICAgICBzdHlsZSArPSAnbGV0dGVyLXNwYWNpbmc6JyArIGNvbmZpZy5sZXR0ZXJTcGFjaW5nLmRlZmF1bHRWYWx1ZSArICdwdDsnOwogICAgICAgICAgICBzdHlsZSArPSAnY29sb3I6IzAwMDAwMDsnOwogICAgICAgICAgICBzdHlsZSArPSAndGV4dC1hbGlnbjpsZWZ0Oyc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3R5bGU7CiAgICB9OwoKICAgIEh0bWxVdGlscy5nZXRNaXNzaW5nUGFyYVN0eWxlID0gZnVuY3Rpb24gKHN0eWxlLCBjb25maWcpIHsKICAgICAgICBpZiAoc3R5bGUgJiYgc3R5bGUubGVuZ3RoID4gMCkgewogICAgICAgICAgICBpZiAoY29uZmlnKSB7CiAgICAgICAgICAgICAgICBpZiAoIW5zLlN0cmluZ0hlbHBlci5lbmRzV2l0aChzdHlsZSwgIjsiKSkgewogICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICI7IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChzdHlsZS5pbmRleE9mKCJmb250LWZhbWlseSIpIDwgMCkgewogICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdmb250LWZhbWlseTonICsgY29uZmlnLmZvbnRGYW1pbHkuZGVmYXVsdFZhbHVlICsgJzsnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHN0eWxlLmluZGV4T2YoImZvbnQtc2l6ZSIpIDwgMCkgewogICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdmb250LXNpemU6JyArIGNvbmZpZy5mb250U2l6ZS5kZWZhdWx0VmFsdWUgKyAncHQ7JzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChzdHlsZS5pbmRleE9mKCJsZXR0ZXItc3BhY2luZyIpIDwgMCkgewogICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdsZXR0ZXItc3BhY2luZzonICsgY29uZmlnLmxldHRlclNwYWNpbmcuZGVmYXVsdFZhbHVlICsgJ3B0Oyc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoc3R5bGUuaW5kZXhPZigiY29sb3IiKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICBzdHlsZSArPSAnY29sb3I6IzAwMDAwMDsnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHN0eWxlLmluZGV4T2YoInRleHQtYWxpZ24iKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICBzdHlsZSArPSAndGV4dC1hbGlnbjpsZWZ0Oyc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdHlsZSA9IEh0bWxVdGlscy5nZXREZWZhdWx0UGFyYVN0eWxlKGNvbmZpZyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHlsZTsKICAgIH07Cgp9KShGb3JtLnJ0ZS51dGlsKTsKCihmdW5jdGlvbiAoKSB7Ci8vIFNvdXJjZTogL2FwcHMvam5rbi93b3Jrc3BhY2UvZ3JlZW5TaG9vdHMtUlRFLVJlcG9fcmVsZWFzZV82NjAvbWFpbi90YXJnZXQvY2hlY2tvdXQvY29udGVudC9zcmMvbWFpbi90ZW1wbGF0ZXMvYnV0dG9uLmhhbmRsZWJhcnMKCiAgdmFyIHRlbXBsYXRlID0gSGFuZGxlYmFycy50ZW1wbGF0ZSh7ImNvbXBpbGVyIjpbNywiPj0gNC4wLjAiXSwibWFpbiI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHsKICAgIHZhciBzdGFjazEsIGhlbHBlcjsKCiAgcmV0dXJuICI8YnV0dG9uIGNsYXNzPVwicnRlLWJ1dHRvbiBydGUtYnV0dG9uLXF1aWV0ICIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5lbGVtZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbGVtZW50IDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImVsZW1lbnQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICIgIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzWyJjbGFzcyJdIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFsiY2xhc3MiXSA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjbGFzcyIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIiAiCiAgICArICgoc3RhY2sxID0gaGVscGVyc1siaWYiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNlbGVjdGVkIDogZGVwdGgwKSx7Im5hbWUiOiJpZiIsImhhc2giOnt9LCJmbiI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksImludmVyc2UiOmNvbnRhaW5lci5ub29wLCJkYXRhIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiAiIikKICAgICsgIlwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQ9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuY29tbWFuZCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY29tbWFuZCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjb21tYW5kIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiXCIgZGF0YS13eXNpaHRtbDUtY29tbWFuZC1zdGF0ZWNhbGxiYWNrZm49XCJGb3JtLnJ0ZS5Db21tYW5kU3RhdGVDYWxsYmFja3Muc2V0QnV0dG9uU3RhdGVcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kLWVsZW1lbnQ9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuZWxlbWVudCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZWxlbWVudCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJlbGVtZW50IiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiXCIgdHlwZT1cImJ1dHRvblwiIG5hbWU9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuY29tbWFuZCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY29tbWFuZCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjb21tYW5kIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiXCIgZGF0YS13eXNpaHRtbDUtY29tbWFuZC12YWx1ZT1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy52YWx1ZSB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWUgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoidmFsdWUiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiB0aXRsZT1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudGl0bGUgOiBkZXB0aDApLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiXCIgaHJlZj1cImphdmFzY3JpcHQ6O1wiIHVuc2VsZWN0YWJsZT1cIm9uXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJpY29uLSIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5pY29uIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pY29uIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6Imljb24iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L3NwYW4+XG4gICAgIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50ZXh0IDogZGVwdGgwKSx7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIlxuPC9idXR0b24+IjsKfSwiMSI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHsKICAgIHJldHVybiAiYWN0aXZlIjsKfSwidXNlRGF0YSI6dHJ1ZX0pOwogIHZhciB0ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzIHx8IHt9OwogIHRlbXBsYXRlc1snYnV0dG9uJ10gPSB0ZW1wbGF0ZTsKICB2YXIgcGFydGlhbHMgPSBIYW5kbGViYXJzLnBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyB8fCB7fTsKICBwYXJ0aWFsc1snYnV0dG9uJ10gPSB0ZW1wbGF0ZTsKCgovLyBTb3VyY2U6IC9hcHBzL2pua24vd29ya3NwYWNlL2dyZWVuU2hvb3RzLVJURS1SZXBvX3JlbGVhc2VfNjYwL21haW4vdGFyZ2V0L2NoZWNrb3V0L2NvbnRlbnQvc3JjL21haW4vdGVtcGxhdGVzL2NvbG9ySW5wdXQuaGFuZGxlYmFycwoKICB2YXIgdGVtcGxhdGUgPSBIYW5kbGViYXJzLnRlbXBsYXRlKHsiY29tcGlsZXIiOls3LCI+PSA0LjAuMCJdLCJtYWluIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkgewogICAgdmFyIGhlbHBlcjsKCiAgcmV0dXJuICI8ZGl2IGNsYXNzPVwicnRlLWNvbG9ySW5wdXQgIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzWyJjbGFzcyJdIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFsiY2xhc3MiXSA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjbGFzcyIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIHRpdGxlPVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50aXRsZSA6IGRlcHRoMCkseyJuYW1lIjoiSTE4biIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkpCiAgICArICJcIj5cbiAgICA8c3Bhbj4iCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKChoZWxwZXJzLkkxOG4gfHwgKGRlcHRoMCAmJiBkZXB0aDAuSTE4bikgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmxhYmVsIDogZGVwdGgwKSx7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIjwvc3Bhbj5cbiAgICA8aW5wdXQgY2xhc3M9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuZWxlbWVudCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZWxlbWVudCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJlbGVtZW50IiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiIHJ0ZS1jb2xvcklucHV0LWNvbnRyb2xcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kPVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLmNvbW1hbmQgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmNvbW1hbmQgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoiY29tbWFuZCIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQtc3RhdGVDYWxsYmFja0ZuPVwiRm9ybS5ydGUuQ29tbWFuZFN0YXRlQ2FsbGJhY2tzLnNldENvbG9ySW5wdXRWYWx1ZVwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQtZWxlbWVudD1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5lbGVtZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbGVtZW50IDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImVsZW1lbnQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBkYXRhLXd5c2lodG1sNS1za2lwPlxuPC9kaXY+IjsKfSwidXNlRGF0YSI6dHJ1ZX0pOwogIHZhciB0ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzIHx8IHt9OwogIHRlbXBsYXRlc1snY29sb3JJbnB1dCddID0gdGVtcGxhdGU7CiAgdmFyIHBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyA9IEhhbmRsZWJhcnMucGFydGlhbHMgfHwge307CiAgcGFydGlhbHNbJ2NvbG9ySW5wdXQnXSA9IHRlbXBsYXRlOwoKCi8vIFNvdXJjZTogL2FwcHMvam5rbi93b3Jrc3BhY2UvZ3JlZW5TaG9vdHMtUlRFLVJlcG9fcmVsZWFzZV82NjAvbWFpbi90YXJnZXQvY2hlY2tvdXQvY29udGVudC9zcmMvbWFpbi90ZW1wbGF0ZXMvZmluZEFuZFJlcGxhY2UuaGFuZGxlYmFycwoKICB2YXIgdGVtcGxhdGUgPSBIYW5kbGViYXJzLnRlbXBsYXRlKHsiY29tcGlsZXIiOls3LCI+PSA0LjAuMCJdLCJtYWluIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkgewogICAgcmV0dXJuICI8Zm9ybSBjbGFzcz1cInJ0ZV9maW5kQW5kUmVwbGFjZV9kaWFsb2dcIj5cbiAgICA8aW5wdXQgbmFtZT1cImZpbmRUZXh0XCIgdHlwZT1cInRleHRcIiBwbGFjZWhvbGRlcj1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwiRmluZCIseyJuYW1lIjoiSTE4biIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkpCiAgICArICJcIiBjbGFzcz1cInJ0ZS1pbnB1dFwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQ9XCJjaGFuZ2VGaW5kVGV4dFwiIGRhdGEtd3lzaWh0bWw1LXNraXA+XG4gICAgPGlucHV0IG5hbWU9XCJyZXBsYWNlVGV4dFwiIHR5cGU9XCJ0ZXh0XCIgcGxhY2Vob2xkZXI9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKChoZWxwZXJzLkkxOG4gfHwgKGRlcHRoMCAmJiBkZXB0aDAuSTE4bikgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIlJlcGxhY2UiLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiXCIgY2xhc3M9XCJydGUtaW5wdXRcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kPVwiY2hhbmdlUmVwbGFjZVRleHRcIiBkYXRhLXd5c2lodG1sNS1za2lwPlxuICAgIDxkaXYgY2xhc3M9XCJydGUtYmxvY2stZ3JvdXBcIj5cbiAgICAgICAgPGxhYmVsPlxuICAgICAgICAgICAgPGlucHV0IG5hbWU9XCJtYXRjaENhc2VcIiB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cInJ0ZV9tYXRjaENhc2VcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kPVwiY2hhbmdlTWF0Y2hDYXNlXCIgZGF0YS13eXNpaHRtbDUtc2tpcD5cbiAgICAgICAgICAgICIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwiTWF0Y2ggY2FzZSIseyJuYW1lIjoiSTE4biIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkpCiAgICArICJcbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGxhYmVsPlxuICAgICAgICAgICAgPGlucHV0IG5hbWU9XCJ3aG9sZVdvcmRcIiB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cInJ0ZV93aG9sZVdvcmRcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kPVwiY2hhbmdlV2hvbGVXb3JkXCIgZGF0YS13eXNpaHRtbDUtc2tpcD5cbiAgICAgICAgICAgICIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwiV2hvbGUgd29yZCIseyJuYW1lIjoiSTE4biIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkpCiAgICArICJcbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGxhYmVsPlxuICAgICAgICAgICAgPGlucHV0IG5hbWU9XCJyZWdFeHBcIiBvbmNoYW5nZT1cInRoaXMuZm9ybS53aG9sZVdvcmQuZGlzYWJsZWQgPSB0aGlzLmNoZWNrZWRcIiB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cInJ0ZV9yZWdFeHBcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kPVwiY2hhbmdlUmVnRXhwXCIgZGF0YS13eXNpaHRtbDUtc2tpcD5cbiAgICAgICAgICAgICIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwiUmVnIEV4Iix7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIlxuICAgICAgICA8L2xhYmVsPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJydGUtYmxvY2stZ3JvdXBcIj5cbiAgICA8YnV0dG9uIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQ9XCJmaW5kXCIgY2xhc3M9XCJydGUtYnV0dG9uXCIgdGFiaW5kZXg9XCItMVwiIHR5cGU9XCJidXR0b25cIj4iCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKChoZWxwZXJzLkkxOG4gfHwgKGRlcHRoMCAmJiBkZXB0aDAuSTE4bikgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIkZpbmQiLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiPC9idXR0b24+XG4gICAgPGJ1dHRvbiB0YWJpbmRleD1cIi0xXCIgZGF0YS13eXNpaHRtbDUtY29tbWFuZD1cInJlcGxhY2VcIiBjbGFzcz1cInJ0ZS1idXR0b25cIiB0eXBlPVwiYnV0dG9uXCI+IgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCJSZXBsYWNlIix7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIjwvYnV0dG9uPlxuICAgIDxidXR0b24gZGF0YS13eXNpaHRtbDUtY29tbWFuZD1cInJlcGxhY2VBbGxcIiBjbGFzcz1cInJ0ZS1idXR0b25cIiB0YWJpbmRleD1cIi0xXCIgdHlwZT1cImJ1dHRvblwiPiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwiUmVwbGFjZSBhbGwiLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiPC9idXR0b24+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInJ0ZV9maW5kTlJlcGxhY2VfYWxlcnQgYWxlcnQgYWxlcnQtaW5mbyBhbGVydC1kaXNtaXNzYWJsZVwiPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImNsb3NlXCIgZGF0YS1kaXNtaXNzPVwiYWxlcnRcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICZ0aW1lcztcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxzdHJvbmc+IgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCJJbmZvIix7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIjwvc3Ryb25nPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInJ0ZV9maW5kTlJlcGxhY2VfbWVzc2FnZVwiPjwvc3Bhbj5cbiAgICA8L2Rpdj5cbjwvZm9ybT5cbiI7Cn0sInVzZURhdGEiOnRydWV9KTsKICB2YXIgdGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyB8fCB7fTsKICB0ZW1wbGF0ZXNbJ2ZpbmRBbmRSZXBsYWNlJ10gPSB0ZW1wbGF0ZTsKICB2YXIgcGFydGlhbHMgPSBIYW5kbGViYXJzLnBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyB8fCB7fTsKICBwYXJ0aWFsc1snZmluZEFuZFJlcGxhY2UnXSA9IHRlbXBsYXRlOwoKCi8vIFNvdXJjZTogL2FwcHMvam5rbi93b3Jrc3BhY2UvZ3JlZW5TaG9vdHMtUlRFLVJlcG9fcmVsZWFzZV82NjAvbWFpbi90YXJnZXQvY2hlY2tvdXQvY29udGVudC9zcmMvbWFpbi90ZW1wbGF0ZXMvZ3JvdXAuaGFuZGxlYmFycwoKICB2YXIgdGVtcGxhdGUgPSBIYW5kbGViYXJzLnRlbXBsYXRlKHsiY29tcGlsZXIiOls3LCI+PSA0LjAuMCJdLCJtYWluIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkgewogICAgdmFyIHN0YWNrMSwgaGVscGVyOwoKICByZXR1cm4gIjxkaXYgY2xhc3M9XCJydGUtZ3JvdXAgIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzWyJjbGFzcyJdIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFsiY2xhc3MiXSA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjbGFzcyIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIHJvbGU9XCJncm91cFwiPlxuIgogICAgKyAoKHN0YWNrMSA9ICgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuY29udGVudCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY29udGVudCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjb250ZW50IiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKSAhPSBudWxsID8gc3RhY2sxIDogIiIpCiAgICArICJcbjwvZGl2PiI7Cn0sInVzZURhdGEiOnRydWV9KTsKICB2YXIgdGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyB8fCB7fTsKICB0ZW1wbGF0ZXNbJ2dyb3VwJ10gPSB0ZW1wbGF0ZTsKICB2YXIgcGFydGlhbHMgPSBIYW5kbGViYXJzLnBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyB8fCB7fTsKICBwYXJ0aWFsc1snZ3JvdXAnXSA9IHRlbXBsYXRlOwoKCi8vIFNvdXJjZTogL2FwcHMvam5rbi93b3Jrc3BhY2UvZ3JlZW5TaG9vdHMtUlRFLVJlcG9fcmVsZWFzZV82NjAvbWFpbi90YXJnZXQvY2hlY2tvdXQvY29udGVudC9zcmMvbWFpbi90ZW1wbGF0ZXMvbGluay5oYW5kbGViYXJzCgogIHZhciB0ZW1wbGF0ZSA9IEhhbmRsZWJhcnMudGVtcGxhdGUoeyJjb21waWxlciI6WzcsIj49IDQuMC4wIl0sIm1haW4iOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7CiAgICByZXR1cm4gIjxmb3JtIGNsYXNzPVwicnRlX2luc2VydExpbmtfZGlhbG9nXCIgcm9sZT1cImZvcm1cIj5cbiAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBwbGFjZWhvbGRlcj1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwiVVJMIix7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIlwiIGNsYXNzPVwicnRlLWlucHV0XCIgbmFtZT1cInVybFwiPlxuICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIHBsYWNlaG9sZGVyPVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCJBbHQgVGV4dCIseyJuYW1lIjoiSTE4biIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkpCiAgICArICJcIiB2YWx1ZT1cIlwiIG5hbWU9XCJhbHRcIiBjbGFzcz1cInJ0ZS1pbnB1dFwiPlxuICAgIDxzcGFuPlxuICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgbmFtZT1cInRhcmdldFwiIHZhbHVlPVwiZmFsc2VcIj5cbiAgICAgICAgIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCJPcGVuIGluIG5ldyBwYWdlIix7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIlxuICAgIDwvc3Bhbj5cbiAgICA8YnV0dG9uIG5hbWU9XCJzdWJtaXRcIiB0YWJpbmRleD1cIi0xXCIgY2xhc3M9XCJydGUtYnV0dG9uIHJ0ZS1idXR0b24tc3F1YXJlXCIgdHlwZT1cImJ1dHRvblwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQ9XCJjcmVhdGVMaW5rXCIgcnRlLWNsb3NlPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImljb24tb2tcIj48L3NwYW4+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvbiB0YWJpbmRleD1cIi0xXCIgY2xhc3M9XCJydGUtYnV0dG9uIHJ0ZS1idXR0b24tc3F1YXJlXCIgdHlwZT1cImJ1dHRvblwiIHJ0ZS1jbG9zZT5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJpY29uLWNhbmNlbFwiPjwvc3Bhbj5cbiAgICA8L2J1dHRvbj5cbjwvZm9ybT4iOwp9LCJ1c2VEYXRhIjp0cnVlfSk7CiAgdmFyIHRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgfHwge307CiAgdGVtcGxhdGVzWydsaW5rJ10gPSB0ZW1wbGF0ZTsKICB2YXIgcGFydGlhbHMgPSBIYW5kbGViYXJzLnBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyB8fCB7fTsKICBwYXJ0aWFsc1snbGluayddID0gdGVtcGxhdGU7CgoKLy8gU291cmNlOiAvYXBwcy9qbmtuL3dvcmtzcGFjZS9ncmVlblNob290cy1SVEUtUmVwb19yZWxlYXNlXzY2MC9tYWluL3RhcmdldC9jaGVja291dC9jb250ZW50L3NyYy9tYWluL3RlbXBsYXRlcy9udW1iZXJJbnB1dC5oYW5kbGViYXJzCgogIHZhciB0ZW1wbGF0ZSA9IEhhbmRsZWJhcnMudGVtcGxhdGUoeyJjb21waWxlciI6WzcsIj49IDQuMC4wIl0sIm1haW4iOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7CiAgICB2YXIgaGVscGVyOwoKICByZXR1cm4gIjxkaXYgY2xhc3M9XCJydGUtbnVtYmVySW5wdXQgIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzWyJjbGFzcyJdIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFsiY2xhc3MiXSA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjbGFzcyIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIHRpdGxlPVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50aXRsZSA6IGRlcHRoMCkseyJuYW1lIjoiSTE4biIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkpCiAgICArICJcIj5cbiAgICA8c3Bhbj4iCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKChoZWxwZXJzLkkxOG4gfHwgKGRlcHRoMCAmJiBkZXB0aDAuSTE4bikgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmxhYmVsIDogZGVwdGgwKSx7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIjwvc3Bhbj5cbiAgICA8aW5wdXQgY2xhc3M9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuZWxlbWVudCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZWxlbWVudCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJlbGVtZW50IiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiXCIgdmFsdWU9XCIwXCIgbmFtZT1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5jb21tYW5kIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb21tYW5kIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImNvbW1hbmQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiB0eXBlPVwibnVtYmVyXCIgZGF0YS13eXNpaHRtbDUtY29tbWFuZD1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5jb21tYW5kIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb21tYW5kIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImNvbW1hbmQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kLXN0YXRlQ2FsbGJhY2tGbj1cIkZvcm0ucnRlLkNvbW1hbmRTdGF0ZUNhbGxiYWNrcy5zZXROdW1iZXJJbnB1dFZhbHVlXCIgZGF0YS13eXNpaHRtbDUtY29tbWFuZC1lbGVtZW50PVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLmVsZW1lbnQgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmVsZW1lbnQgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoiZWxlbWVudCIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIHVuc2VsZWN0YWJsZT1cIm9mZlwiIGRhdGEtd3lzaWh0bWw1LXNraXAgbWluPVwiMFwiIHN0ZXA9XCJhbnlcIj5cbjwvZGl2PiI7Cn0sInVzZURhdGEiOnRydWV9KTsKICB2YXIgdGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyB8fCB7fTsKICB0ZW1wbGF0ZXNbJ251bWJlcklucHV0J10gPSB0ZW1wbGF0ZTsKICB2YXIgcGFydGlhbHMgPSBIYW5kbGViYXJzLnBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyB8fCB7fTsKICBwYXJ0aWFsc1snbnVtYmVySW5wdXQnXSA9IHRlbXBsYXRlOwoKCi8vIFNvdXJjZTogL2FwcHMvam5rbi93b3Jrc3BhY2UvZ3JlZW5TaG9vdHMtUlRFLVJlcG9fcmVsZWFzZV82NjAvbWFpbi90YXJnZXQvY2hlY2tvdXQvY29udGVudC9zcmMvbWFpbi90ZW1wbGF0ZXMvcG9wb3Zlci5oYW5kbGViYXJzCgogIHZhciB0ZW1wbGF0ZSA9IEhhbmRsZWJhcnMudGVtcGxhdGUoeyJjb21waWxlciI6WzcsIj49IDQuMC4wIl0sIm1haW4iOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7CiAgICB2YXIgc3RhY2sxLCBoZWxwZXI7CgogIHJldHVybiAiPGRpdiBjbGFzcz1cInJ0ZS1wb3BvdmVyXCI+XG4gICAgPGJ1dHRvbiBjbGFzcz1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5lbGVtZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbGVtZW50IDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImVsZW1lbnQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICIgcnRlLWJ1dHRvbiBydGUtYnV0dG9uLXF1aWV0ICIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVyc1siY2xhc3MiXSB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbImNsYXNzIl0gOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoiY2xhc3MiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1wbGFjZW1lbnQ9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMucGxhY2VtZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wbGFjZW1lbnQgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoicGxhY2VtZW50IiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiXCIgbmFtZT1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5jb21tYW5kIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb21tYW5kIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImNvbW1hbmQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kPVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLmNvbW1hbmQgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmNvbW1hbmQgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoiY29tbWFuZCIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQtc3RhdGVjYWxsYmFja2ZuPVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLmNhbGxiYWNrIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jYWxsYmFjayA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjYWxsYmFjayIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQtZWxlbWVudD1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5lbGVtZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbGVtZW50IDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImVsZW1lbnQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBocmVmPVwiamF2YXNjcmlwdDo7XCIgdW5zZWxlY3RhYmxlPVwib25cIiB0aXRsZT1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudGl0bGUgOiBkZXB0aDApLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaWNvbi0iCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuaWNvbiB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWNvbiA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJpY29uIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9zcGFuPlxuICAgICAgICAiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKChoZWxwZXJzLkkxOG4gfHwgKGRlcHRoMCAmJiBkZXB0aDAuSTE4bikgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnRleHQgOiBkZXB0aDApLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiXG4gICAgPC9idXR0b24+XG4gICAgPGRpdiBjbGFzcz1cInBvcG92ZXJcIj4iCiAgICArICgoc3RhY2sxID0gKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5jb250ZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb250ZW50IDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImNvbnRlbnQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpICE9IG51bGwgPyBzdGFjazEgOiAiIikKICAgICsgIjwvZGl2PlxuPC9kaXY+IjsKfSwidXNlRGF0YSI6dHJ1ZX0pOwogIHZhciB0ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzIHx8IHt9OwogIHRlbXBsYXRlc1sncG9wb3ZlciddID0gdGVtcGxhdGU7CiAgdmFyIHBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyA9IEhhbmRsZWJhcnMucGFydGlhbHMgfHwge307CiAgcGFydGlhbHNbJ3BvcG92ZXInXSA9IHRlbXBsYXRlOwoKCi8vIFNvdXJjZTogL2FwcHMvam5rbi93b3Jrc3BhY2UvZ3JlZW5TaG9vdHMtUlRFLVJlcG9fcmVsZWFzZV82NjAvbWFpbi90YXJnZXQvY2hlY2tvdXQvY29udGVudC9zcmMvbWFpbi90ZW1wbGF0ZXMvcnRldG9vbGJhci5oYW5kbGViYXJzCgogIHZhciB0ZW1wbGF0ZSA9IEhhbmRsZWJhcnMudGVtcGxhdGUoeyJjb21waWxlciI6WzcsIj49IDQuMC4wIl0sIm1haW4iOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7CiAgICB2YXIgc3RhY2sxOwoKICByZXR1cm4gIjxkaXYgY2xhc3M9XCJydGVfdG9vbEJhclwiIHJvbGU9XCJ0b29sYmFyXCI+IgogICAgKyAoKHN0YWNrMSA9IGNvbnRhaW5lci5sYW1iZGEoZGVwdGgwLCBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxIDogIiIpCiAgICArICI8L2Rpdj4iOwp9LCJ1c2VEYXRhIjp0cnVlfSk7CiAgdmFyIHRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgfHwge307CiAgdGVtcGxhdGVzWydydGV0b29sYmFyJ10gPSB0ZW1wbGF0ZTsKICB2YXIgcGFydGlhbHMgPSBIYW5kbGViYXJzLnBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyB8fCB7fTsKICBwYXJ0aWFsc1sncnRldG9vbGJhciddID0gdGVtcGxhdGU7CgoKLy8gU291cmNlOiAvYXBwcy9qbmtuL3dvcmtzcGFjZS9ncmVlblNob290cy1SVEUtUmVwb19yZWxlYXNlXzY2MC9tYWluL3RhcmdldC9jaGVja291dC9jb250ZW50L3NyYy9tYWluL3RlbXBsYXRlcy9zZWxlY3QuaGFuZGxlYmFycwoKICB2YXIgdGVtcGxhdGUgPSBIYW5kbGViYXJzLnRlbXBsYXRlKHsiY29tcGlsZXIiOls3LCI+PSA0LjAuMCJdLCJtYWluIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkgewogICAgdmFyIHN0YWNrMSwgaGVscGVyOwoKICByZXR1cm4gIjxkaXYgY2xhc3M9XCJydGUtc2VsZWN0XCIgdGl0bGU9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKChoZWxwZXJzLkkxOG4gfHwgKGRlcHRoMCAmJiBkZXB0aDAuSTE4bikgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnRpdGxlIDogZGVwdGgwKSx7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIlwiPlxuICAgIDxzZWxlY3QgY2xhc3M9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuZWxlbWVudCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZWxlbWVudCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJlbGVtZW50IiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiICIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVyc1siY2xhc3MiXSB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbImNsYXNzIl0gOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoiY2xhc3MiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBkYXRhLXd5c2lodG1sNS1za2lwPVwiXCIgZGF0YS13eXNpaHRtbDUtY29tbWFuZD1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5jb21tYW5kIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb21tYW5kIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImNvbW1hbmQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kLXN0YXRlQ2FsbGJhY2tGbj1cIkZvcm0ucnRlLkNvbW1hbmRTdGF0ZUNhbGxiYWNrcy5zZXRTZWxlY3RTdGF0ZVwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQtZWxlbWVudD1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5lbGVtZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbGVtZW50IDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImVsZW1lbnQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIj5cbiAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiIHN0eWxlPVwiZGlzcGxheTpub25lXCI+IgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCJTZWxlY3QiLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiPC9vcHRpb24+XG4iCiAgICArICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAub3B0aW9ucyA6IGRlcHRoMCkseyJuYW1lIjoiZWFjaCIsImhhc2giOnt9LCJmbiI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksImludmVyc2UiOmNvbnRhaW5lci5ub29wLCJkYXRhIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiAiIikKICAgICsgIiAgICA8L3NlbGVjdD5cbiAgICA8aSBjbGFzcz1cInJ0ZS10b2dnbGVTZWxlY3QgaWNvbi1kb3duLW9wZW5cIj48L2k+XG48L2Rpdj5cbiI7Cn0sIjEiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7CiAgICB2YXIgc3RhY2sxOwoKICByZXR1cm4gIiAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCIiCiAgICArICgoc3RhY2sxID0gaGVscGVyc1siaWYiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlIDogZGVwdGgwKSx7Im5hbWUiOiJpZiIsImhhc2giOnt9LCJmbiI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksImludmVyc2UiOmNvbnRhaW5lci5wcm9ncmFtKDQsIGRhdGEsIDApLCJkYXRhIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiAiIikKICAgICsgIlwiPiIKICAgICsgKChzdGFjazEgPSBoZWxwZXJzWyJpZiJdLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubGFiZWwgOiBkZXB0aDApLHsibmFtZSI6ImlmIiwiaGFzaCI6e30sImZuIjpjb250YWluZXIucHJvZ3JhbSg2LCBkYXRhLCAwKSwiaW52ZXJzZSI6Y29udGFpbmVyLnByb2dyYW0oOCwgZGF0YSwgMCksImRhdGEiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6ICIiKQogICAgKyAiPC9vcHRpb24+XG4iOwp9LCIyIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkgewogICAgdmFyIGhlbHBlcjsKCiAgcmV0dXJuIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMudmFsdWUgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6InZhbHVlIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKTsKfSwiNCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHsKICAgIHJldHVybiBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbihjb250YWluZXIubGFtYmRhKGRlcHRoMCwgZGVwdGgwKSk7Cn0sIjYiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7CiAgICByZXR1cm4gY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubGFiZWwgOiBkZXB0aDApLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKTsKfSwiOCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHsKICAgIHJldHVybiBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LGRlcHRoMCx7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSk7Cn0sInVzZURhdGEiOnRydWV9KTsKICB2YXIgdGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyB8fCB7fTsKICB0ZW1wbGF0ZXNbJ3NlbGVjdCddID0gdGVtcGxhdGU7CiAgdmFyIHBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyA9IEhhbmRsZWJhcnMucGFydGlhbHMgfHwge307CiAgcGFydGlhbHNbJ3NlbGVjdCddID0gdGVtcGxhdGU7CgoKCn0pKCk7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDcvMjkvMjAxNi4KICovCgooZnVuY3Rpb24gKG5zKSB7CgogICAgLyogT3V0IG9mIHRoZSBib3ggcHJvdmlkZWQgQ29tbWFuZHMqLwogICAgdmFyIENvbW1hbmRzID0gbnMuQ29tbWFuZHMgPSB7fTsKCiAgICBDb21tYW5kcy5VTkRPID0gInVuZG8iOwogICAgQ29tbWFuZHMuUkVETyA9ICJyZWRvIjsKCiAgICBDb21tYW5kcy5CT0xEID0gImJvbGQiOwogICAgQ29tbWFuZHMuSVRBTElDID0gIml0YWxpYyI7CiAgICBDb21tYW5kcy5VTkRFUkxJTkUgPSAidW5kZXJsaW5lIjsKICAgIENvbW1hbmRzLlNVUEVSU0NSSVBUID0gInN1cGVyc2NyaXB0IjsKICAgIENvbW1hbmRzLlNVQlNDUklQVCA9ICJzdWJzY3JpcHQiOwogICAgQ29tbWFuZHMuRk9SRV9DT0xPUiA9ICJmb3JlQ29sb3IiOwogICAgQ29tbWFuZHMuSElMSVRFX0NPTE9SID0gImhpbGl0ZUNvbG9yIjsKCiAgICBDb21tYW5kcy5GT05UX0ZBTUlMWSA9ICJmb250RmFtaWx5IjsKICAgIENvbW1hbmRzLkZPTlRfU0laRSA9ICJmb250U2l6ZSI7CiAgICBDb21tYW5kcy5MSU5FX0hFSUdIVCA9ICJsaW5lSGVpZ2h0IjsKICAgIENvbW1hbmRzLkxFVFRFUl9TUEFDSU5HID0gImxldHRlclNwYWNpbmciOwogICAgQ29tbWFuZHMuSEVBREVSID0gImhlYWRlciI7CgogICAgQ29tbWFuZHMuSlVTVElGWV9MRUZUID0gImp1c3RpZnlMZWZ0IjsKICAgIENvbW1hbmRzLkpVU1RJRllfQ0VOVEVSID0gImp1c3RpZnlDZW50ZXIiOwogICAgQ29tbWFuZHMuSlVTVElGWV9GVUxMID0gImp1c3RpZnlGdWxsIjsKICAgIENvbW1hbmRzLkpVU1RJRllfUklHSFQgPSAianVzdGlmeVJpZ2h0IjsKCiAgICBDb21tYW5kcy5NQVJHSU5fTEVGVCA9ICJtYXJnaW5MZWZ0IjsKICAgIENvbW1hbmRzLk1BUkdJTl9SSUdIVCA9ICJtYXJnaW5SaWdodCI7CiAgICBDb21tYW5kcy5NQVJHSU5fVE9QID0gIm1hcmdpblRvcCI7CiAgICBDb21tYW5kcy5NQVJHSU5fQk9UVE9NID0gIm1hcmdpbkJvdHRvbSI7CgogICAgQ29tbWFuZHMuSU5TRVJUX1VOT1JERVJFRF9MSVNUID0gImluc2VydFVub3JkZXJlZExpc3QiOwogICAgQ29tbWFuZHMuSU5TRVJUX09SREVSRURfTElTVCA9ICJpbnNlcnRPcmRlcmVkTGlzdCI7CiAgICBDb21tYW5kcy5JTlNFUlRfVVBQRVJDQVNFX0FMUEhBQkVUX0xJU1QgPSAiaW5zZXJ0VXBwZXJjYXNlQWxwaGFiZXRMaXN0IjsKICAgIENvbW1hbmRzLklOU0VSVF9MT1dFUkNBU0VfQUxQSEFCRVRfTElTVCA9ICJpbnNlcnRMb3dlcmNhc2VBbHBoYWJldExpc3QiOwogICAgQ29tbWFuZHMuSU5TRVJUX1VQUEVSQ0FTRV9ST01BTl9MSVNUID0gImluc2VydFVwcGVyY2FzZVJvbWFuTGlzdCI7CiAgICBDb21tYW5kcy5JTlNFUlRfTE9XRVJDQVNFX1JPTUFOX0xJU1QgPSAiaW5zZXJ0TG93ZXJjYXNlUm9tYW5MaXN0IjsKCiAgICBDb21tYW5kcy5JTkRFTlQgPSAiaW5kZW50IjsKICAgIENvbW1hbmRzLk9VVERFTlQgPSAib3V0ZGVudCI7CgogICAgQ29tbWFuZHMuTU9ERSA9ICJtb2RlIjsKICAgIENvbW1hbmRzLkZJTkRfQU5EX1JFUExBQ0UgPSAiZmluZEFuZFJlcGxhY2UiOwogICAgQ29tbWFuZHMuTElOSyA9ICJsaW5rIjsKICAgIENvbW1hbmRzLklOU0VSVF9URVhUID0gImluc2VydFRleHQiOwoKICAgIC8qIFRvb2xiYXIgTW9kZXMqLwogICAgdmFyIFRvb2xiYXJNb2RlID0gbnMuVG9vbGJhck1vZGUgPSB7fTsKICAgIFRvb2xiYXJNb2RlLkJBU0lDID0gImJhc2ljIjsKICAgIFRvb2xiYXJNb2RlLkZVTEwgPSAiZnVsbCI7CgogICAgdmFyIEtleWJvYXJkID0gbnMuS2V5Ym9hcmQgPSB7fTsKCiAgICBLZXlib2FyZC5LRVlDT0RFX0IgPSA2NjsKICAgIEtleWJvYXJkLktFWUNPREVfSSA9IDczOwogICAgS2V5Ym9hcmQuS0VZQ09ERV9VID0gODU7CiAgICBLZXlib2FyZC5LRVlDT0RFX1MgPSA4MzsKICAgIEtleWJvYXJkLktFWUNPREVfRSA9IDY5OwogICAgS2V5Ym9hcmQuS0VZQ09ERV9MID0gNzY7CiAgICBLZXlib2FyZC5LRVlDT0RFX1IgPSA4MjsKICAgIEtleWJvYXJkLktFWUNPREVfSiA9IDc0OwogICAgS2V5Ym9hcmQuS0VZQ09ERV9HUkVBVEVSX1RIQU4gPSAxOTA7CiAgICBLZXlib2FyZC5LRVlDT0RFX0xFU1NfVEhBTiA9IDE4ODsKCn0pKEZvcm0ucnRlKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKKGZ1bmN0aW9uIChucykgewogICAgInVzZSBzdHJpY3QiOwoKICAgIC8qIERlZmF1bHQgRWRpdG9yIGNvbmZpZ3VyYXRpb25zKi8KICAgIG5zLkRlZmF1bHRDb25maWcgPSB7CiAgICAgICAgZm9udEZhbWlseSA6IHsKICAgICAgICAgICAgZGVmYXVsdFZhbHVlIDogIlRpbWVzIE5ldyBSb21hbiIsCiAgICAgICAgICAgIG9wdGlvbnMgOiBbIlRpbWVzIE5ldyBSb21hbiIsICJBcmlhbCIsICJDb3VyaWVyIiwgIkNvdXJpZXIgTmV3IiwgIkdlbmV2YSIsICJHZW9yZ2lhIiwgIkhlbHZldGljYSIsICJUYWhvbWEiLCAiVGltZXMiLCAiVmVyZGFuYSJdCiAgICAgICAgfSwKICAgICAgICBmb250U2l6ZSA6IHsKICAgICAgICAgICAgZGVmYXVsdFZhbHVlIDogMTIsCiAgICAgICAgICAgIG9wdGlvbnMgOiBbOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNiwgMTgsIDIwLCAyMiwgMjQsIDI2LCAyOCwgMzYsIDQ4LCA3Ml0KICAgICAgICB9LAogICAgICAgIGxpbmVIZWlnaHQgOiB7CiAgICAgICAgICAgIG9wdGlvbnMgOiBbMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwgMTZdCiAgICAgICAgfSwKICAgICAgICBsZXR0ZXJTcGFjaW5nIDogewogICAgICAgICAgICBkZWZhdWx0VmFsdWUgOiAiMCIsCiAgICAgICAgICAgIG9wdGlvbnMgOiBbIjAiLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LCAxNl0KICAgICAgICB9LAogICAgICAgIGhlYWRlciA6IHsKICAgICAgICAgICAgZGVmYXVsdFZhbHVlIDogInAiLAogICAgICAgICAgICBvcHRpb25zIDogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhbHVlIDogInAiLAogICAgICAgICAgICAgICAgICAgIGxhYmVsIDogIk5vbmUiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhbHVlIDogImgxIiwKICAgICAgICAgICAgICAgICAgICBsYWJlbCA6ICJIZWFkZXIgMSIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgOiAiaDIiLAogICAgICAgICAgICAgICAgICAgIGxhYmVsIDogIkhlYWRlciAyIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA6ICJoMyIsCiAgICAgICAgICAgICAgICAgICAgbGFiZWwgOiAiSGVhZGVyIDMiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhbHVlIDogImg0IiwKICAgICAgICAgICAgICAgICAgICBsYWJlbCA6ICJIZWFkZXIgNCIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgOiAiaDUiLAogICAgICAgICAgICAgICAgICAgIGxhYmVsIDogIkhlYWRlciA1IgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA6ICJoNiIsCiAgICAgICAgICAgICAgICAgICAgbGFiZWwgOiAiSGVhZGVyIDYiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICB9LAogICAgICAgIGNvbG9yIDogewogICAgICAgICAgICB3aGl0ZSA6ICdmZmYnLAogICAgICAgICAgICByZWQgOiAnZjAwJywKICAgICAgICAgICAgb3JhbmdlIDogJ2Y2MCcsCiAgICAgICAgICAgIHllbGxvdyA6ICdmZjAnLAogICAgICAgICAgICBncmVlbiA6ICcwMDgwMDAnLAogICAgICAgICAgICBibHVlIDogJzAwZicsCiAgICAgICAgICAgIHB1cnBsZSA6ICc4MDAwODAnLAogICAgICAgICAgICBibGFjayA6ICcwMDAnCiAgICAgICAgfQogICAgICAgIC8vVE9ETyA6IGFkZCBjb25maWd1cmF0aW9uIGZvciBDdXN0b20gY2xhc3NlcwogICAgfTsKCiAgICAvKiBPdXQgb2YgdGhlIGJveCB0b29sYmFyIGNvbmZpZ3VyYXRpb24gcHJvdmlkZWQgKi8KICAgIG5zLlRvb2xiYXJDb25maWcgPSB7CiAgICAgICAgZGVmYXVsdE1vZGUgOiAnYmFzaWMnLAogICAgICAgIHRvb2xiYXJzIDogewogICAgICAgICAgICBiYXNpYyA6IHsKICAgICAgICAgICAgICAgIGxheW91dCA6IFsKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgOiAiSGVhZGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMgOiBbbnMuQ29tbWFuZHMuSEVBREVSXQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuYW1lIDogIlBhcmFncmFwaCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zIDogW25zLkNvbW1hbmRzLkJPTEQsIG5zLkNvbW1hbmRzLklUQUxJQywgbnMuQ29tbWFuZHMuVU5ERVJMSU5FXQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kIDogJ2xpc3RzJywKICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgOiAiTGlzdCBUeXBlIiwKICAgICAgICAgICAgICAgICAgICAgICAgaWNvbiA6ICdsaXN0JywKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA6ICdwb3BvdmVyJywKICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2VtZW50IDogJ2JvdHRvbScsCiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zIDogW25zLkNvbW1hbmRzLklOU0VSVF9VTk9SREVSRURfTElTVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLklOU0VSVF9PUkRFUkVEX0xJU1QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBucy5Db21tYW5kcy5JTlNFUlRfTE9XRVJDQVNFX0FMUEhBQkVUX0xJU1RdCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlIDogJ0V4cGFuZCcsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgOiBucy5Db21tYW5kcy5NT0RFLAogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA6IG5zLlRvb2xiYXJNb2RlLkZVTEwsCiAgICAgICAgICAgICAgICAgICAgICAgIGljb24gOiAncmVzaXplLWZ1bGwnCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgIGZsb2F0aW5nIDogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICBmdWxsIDogewogICAgICAgICAgICAgICAgbGF5b3V0IDogWwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMgOiBbbnMuQ29tbWFuZHMuVU5ETywgbnMuQ29tbWFuZHMuUkVETywgbnMuQ29tbWFuZHMuTElOSywgbnMuQ29tbWFuZHMuRklORF9BTkRfUkVQTEFDRV0KICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA6ICJQYXJhZ3JhcGgiLAogICAgICAgICAgICAgICAgICAgICAgICBpdGVtcyA6IFsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLkhFQURFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLkZPTlRfRkFNSUxZLG5zLkNvbW1hbmRzLkZPTlRfU0laRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLkJPTEQsIG5zLkNvbW1hbmRzLklUQUxJQywgbnMuQ29tbWFuZHMuVU5ERVJMSU5FLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMuQ29tbWFuZHMuU1VQRVJTQ1JJUFQsIG5zLkNvbW1hbmRzLlNVQlNDUklQVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLkxFVFRFUl9TUEFDSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMuQ29tbWFuZHMuTElORV9IRUlHSFQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBucy5Db21tYW5kcy5GT1JFX0NPTE9SLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMuQ29tbWFuZHMuSElMSVRFX0NPTE9SCiAgICAgICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA6ICJBbGlnbm1lbnQiLAogICAgICAgICAgICAgICAgICAgICAgICBpdGVtcyA6IFsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLkpVU1RJRllfTEVGVCwgbnMuQ29tbWFuZHMuSlVTVElGWV9DRU5URVIsIG5zLkNvbW1hbmRzLkpVU1RJRllfRlVMTCwgbnMuQ29tbWFuZHMuSlVTVElGWV9SSUdIVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLk1BUkdJTl9MRUZULCBucy5Db21tYW5kcy5NQVJHSU5fUklHSFQsIG5zLkNvbW1hbmRzLk1BUkdJTl9UT1AsIG5zLkNvbW1hbmRzLk1BUkdJTl9CT1RUT00KICAgICAgICAgICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuYW1lIDogIkxpc3RpbmciLAogICAgICAgICAgICAgICAgICAgICAgICBpdGVtcyA6IFtucy5Db21tYW5kcy5JTlNFUlRfVU5PUkRFUkVEX0xJU1QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMuQ29tbWFuZHMuSU5TRVJUX09SREVSRURfTElTVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBucy5Db21tYW5kcy5JTlNFUlRfVVBQRVJDQVNFX0FMUEhBQkVUX0xJU1QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMuQ29tbWFuZHMuSU5TRVJUX0xPV0VSQ0FTRV9BTFBIQUJFVF9MSVNULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLklOU0VSVF9VUFBFUkNBU0VfUk9NQU5fTElTVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBucy5Db21tYW5kcy5JTlNFUlRfTE9XRVJDQVNFX1JPTUFOX0xJU1QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMuQ29tbWFuZHMuSU5ERU5ULCBucy5Db21tYW5kcy5PVVRERU5UCiAgICAgICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgOiAnQ29sbGFwc2UnLAogICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kIDogbnMuQ29tbWFuZHMuTU9ERSwKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgOiBucy5Ub29sYmFyTW9kZS5CQVNJQywKICAgICAgICAgICAgICAgICAgICAgICAgaWNvbiA6ICdyZXNpemUtc21hbGwnLAogICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZCA6IHRydWUKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Owp9KShGb3JtLnJ0ZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiA3LzI5LzIwMTYuCiAqLwoKKGZ1bmN0aW9uIChucykgewoKICAgIHZhciBGaW5kQW5kUmVwbGFjZSA9IG5zLkZpbmRBbmRSZXBsYWNlID0gZnVuY3Rpb24gKHRleHRFZGl0b3IpIHsKICAgICAgICB0aGlzLnRleHRFZGl0b3IgPSB0ZXh0RWRpdG9yOwogICAgICAgIHRoaXMuX21lc3NhZ2UgPSAiIjsKICAgICAgICB0aGlzLl93aG9sZVdvcmRFbmFibGVkID0gdHJ1ZTsKICAgICAgICB0aGlzLmlzRGlydHkgPSB0cnVlOwogICAgICAgIHRoaXMuaXNWYWxpZCA9IHRydWU7CiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcywgeyJzb3VyY2UiIDogeyJnZXQiIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy50ZXh0RWRpdG9yICYmIHRoaXMudGV4dEVkaXRvci5lZGl0b3IgJiYgdGhpcy50ZXh0RWRpdG9yLmVkaXRvci5jb21wb3NlciAmJiB0aGlzLnRleHRFZGl0b3IuZWRpdG9yLmNvbXBvc2VyLmNvbnRhaW5lciA/IHRoaXMudGV4dEVkaXRvci5lZGl0b3IuY29tcG9zZXIuY29udGFpbmVyLnRleHRDb250ZW50IHx8IHRoaXMudGV4dEVkaXRvci5lZGl0b3IuY29tcG9zZXIuY29udGFpbmVyLm91dGVyVGV4dCA6ICIiOwogICAgICAgIH19fSk7CiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcywgeyJtZXNzYWdlIiA6IHsiZ2V0IiA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21lc3NhZ2U7CiAgICAgICAgfSwgInNldCIgOiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgdGhpcy5fbWVzc2FnZSA9IHZhbHVlOwogICAgICAgIH19fSk7CiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcywgeyJ3aG9sZVdvcmRFbmFibGVkIiA6IHsiZ2V0IiA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dob2xlV29yZEVuYWJsZWQ7CiAgICAgICAgfSwgInNldCIgOiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgdGhpcy5fd2hvbGVXb3JkRW5hYmxlZCA9IHZhbHVlOwogICAgICAgIH19fSk7CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5zZXRTZWxlY3Rpb25BbmRIaWdobGlnaHQgPSBmdW5jdGlvbiAoY29udGFpbmVyLCByZWxhdGl2ZVN0YXJ0LCByZWxhdGl2ZUVuZCkgewogICAgICAgIGlmIChjb250YWluZXIgPT0gbnVsbCkgewogICAgICAgICAgICBjb250YWluZXIgPSB0aGlzLnRleHRFZGl0b3IuY29udGFpbmVyOwogICAgICAgICAgICBpZiAoIWNvbnRhaW5lcikgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHZhciBjaGFySW5kZXggPSAwLCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgcmFuZ2Uuc2V0U3RhcnQoZG9jdW1lbnQsIDApOwogICAgICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpOwogICAgICAgIHZhciBub2RlU3RhY2sgPSBbY29udGFpbmVyXSwgbm9kZSwgZm91bmRTdGFydCA9IGZhbHNlLCBzdG9wID0gZmFsc2U7CiAgICAgICAgdmFyIG5ld0xpbmVDb3VudCA9IDA7CiAgICAgICAgd2hpbGUgKCFzdG9wICYmIChub2RlID0gbm9kZVN0YWNrLnBvcCgpKSkgewogICAgICAgICAgICBpZiAobm9kZSAmJiBub2RlLm5vZGVUeXBlID09IDMpIHsKICAgICAgICAgICAgICAgIHZhciBuZXh0Q2hhckluZGV4ID0gY2hhckluZGV4ICsgbm9kZS5ub2RlVmFsdWUubGVuZ3RoOwogICAgICAgICAgICAgICAgaWYgKHRoaXMucmVsYXRpdmVTdGFydCA+PSBjaGFySW5kZXggJiYgdGhpcy5yZWxhdGl2ZVN0YXJ0IDw9IG5leHRDaGFySW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICByYW5nZS5zZXRTdGFydChub2RlLCB0aGlzLnJlbGF0aXZlU3RhcnQgLSBjaGFySW5kZXgpOwogICAgICAgICAgICAgICAgICAgIGZvdW5kU3RhcnQgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGZvdW5kU3RhcnQgJiYgdGhpcy5yZWxhdGl2ZUVuZCA+PSBjaGFySW5kZXggJiYgdGhpcy5yZWxhdGl2ZUVuZCA8PSBuZXh0Q2hhckluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2Uuc2V0RW5kKG5vZGUsIHRoaXMucmVsYXRpdmVFbmQgLSBjaGFySW5kZXgpOwogICAgICAgICAgICAgICAgICAgIHN0b3AgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2hhckluZGV4ID0gbmV4dENoYXJJbmRleDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBpID0gbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDsKICAgICAgICAgICAgICAgIHdoaWxlIChpLS0pIHsKICAgICAgICAgICAgICAgICAgICBub2RlU3RhY2sucHVzaChub2RlLmNoaWxkTm9kZXNbaV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB2YXIgc2VsID0gZG9jdW1lbnQuZ2V0U2VsZWN0aW9uKCk7CiAgICAgICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpOwogICAgICAgIHNlbC5hZGRSYW5nZShyYW5nZSk7CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5vblJlZ0V4cFNlbGVjdGlvbkNoYW5nZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlKCk7CiAgICAgICAgdGhpcy5zZXRXaG9sZVdvcmRFbmFibGVkKCk7CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5vbkZpbmRWYWx1ZUNoYW5nZSA9IGZ1bmN0aW9uIChmaW5kVmFsKSB7CiAgICAgICAgaWYgKGZpbmRWYWwgIT0gdGhpcy5maW5kVGV4dCkgewogICAgICAgICAgICB0aGlzLmZpbmRUZXh0ID0gZmluZFZhbDsKICAgICAgICB9CiAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZSgpOwogICAgICAgIHRoaXMuc2V0V2hvbGVXb3JkRW5hYmxlZCgpOwogICAgfTsKCiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUub25SZXBsYWNlVmFsdWVDaGFuZ2UgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZSgpOwogICAgfTsKCiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUuc2V0V2hvbGVXb3JkRW5hYmxlZCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAodGhpcy5maW5kVGV4dCkgewogICAgICAgICAgICB2YXIgcmVzdWx0ID0gbnMudXRpbC5TdHJpbmdIZWxwZXIucmVzdHJpY3QodGhpcy5maW5kVGV4dCwgIl5gfiFAIyUmKigpPStbXXt9L1x8J1wiOzovPy4+PCwiKTsKICAgICAgICAgICAgaWYgKHRoaXMuZmluZFRleHQgIT0gcmVzdWx0KSB7CiAgICAgICAgICAgICAgICB0aGlzLndob2xlV29yZEVuYWJsZWQgPSBmYWxzZTsKICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmlzUmVnRXgpIHsKICAgICAgICAgICAgICAgIHRoaXMud2hvbGVXb3JkRW5hYmxlZCA9ICF0aGlzLmlzUmVnRXg7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLndob2xlV29yZEVuYWJsZWQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghdGhpcy53aG9sZVdvcmRFbmFibGVkKSB7CiAgICAgICAgICAgICAgICB0aGlzLmlzV2hvbGVXb3JkID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5vblNlbGVjdGlvbkNoYW5nZSA9IGZ1bmN0aW9uIChpc0Nhc2VTZW5zaXRpdmVWYWwsIGlzV2hvbGVXb3JkVmFsLCBpc1JlZ0V4VmFsKSB7CiAgICAgICAgdGhpcy5pc0RpcnR5ID0gdHJ1ZTsKICAgICAgICB0aGlzLnJlbGF0aXZlU3RhcnQgPSAtMTsKICAgICAgICB0aGlzLnJlbGF0aXZlRW5kID0gLTE7CiAgICAgICAgdGhpcy5tZXNzYWdlID0gIiI7CgogICAgICAgIGlmIChpc1dob2xlV29yZFZhbCAhPT0gdW5kZWZpbmVkICYmIGlzV2hvbGVXb3JkVmFsICE9IG51bGwpIHsKICAgICAgICAgICAgdGhpcy5pc1dob2xlV29yZCA9IGlzV2hvbGVXb3JkVmFsOwogICAgICAgIH0KICAgICAgICBpZiAoaXNSZWdFeFZhbCAhPT0gdW5kZWZpbmVkICYmIGlzUmVnRXhWYWwgIT0gbnVsbCAmJiB0aGlzLmlzUmVnRXggIT09IGlzUmVnRXhWYWwpIHsKICAgICAgICAgICAgdGhpcy5pc1JlZ0V4ID0gaXNSZWdFeFZhbDsKICAgICAgICAgICAgdGhpcy5zZXRXaG9sZVdvcmRFbmFibGVkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChpc0Nhc2VTZW5zaXRpdmVWYWwgIT09IHVuZGVmaW5lZCAmJiBpc0Nhc2VTZW5zaXRpdmVWYWwgIT0gbnVsbCkgewogICAgICAgICAgICB0aGlzLmlzQ2FzZVNlbnNpdGl2ZSA9IGlzQ2FzZVNlbnNpdGl2ZVZhbDsKICAgICAgICB9CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLmlzVmFsaWQgPSB0aGlzLmZpbmRUZXh0ID8gdHJ1ZSA6IGZhbHNlOwogICAgICAgIHRoaXMuaXNEaXJ0eSA9IHRydWU7CiAgICAgICAgdGhpcy5tZXNzYWdlID0gIiI7CiAgICAgICAgdGhpcy5yZWxhdGl2ZVN0YXJ0ID0gLTE7CiAgICAgICAgdGhpcy5yZWxhdGl2ZUVuZCA9IC0xOwogICAgfTsKCiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUuZXhlY3V0ZUZpbmQgPSBmdW5jdGlvbiAoZmluZFZhbCkgewogICAgICAgIHRoaXMuZmluZFRleHQgPSBmaW5kVmFsOwogICAgICAgIGlmICh0aGlzLmZpbmRUZXh0KSB7CiAgICAgICAgICAgIHRoaXMuZmluZFBvc2l0aW9uKHRoaXMuZmluZFRleHQpOwogICAgICAgICAgICB0aGlzLnNldFNlbGVjdGlvbkFuZEhpZ2hsaWdodChudWxsLCB0aGlzLnJlbGF0aXZlU3RhcnQsIHRoaXMucmVsYXRpdmVFbmQsIHRydWUpOwogICAgICAgIH0KICAgIH07CgogICAgRmluZEFuZFJlcGxhY2UucHJvdG90eXBlLmFkanVzdFNlYXJjaFBvc2l0aW9uQWZ0ZXJSZXBsYWNlID0gZnVuY3Rpb24gKG5ld1ZhbCkgewogICAgICAgIGlmICh0aGlzLnJlbGF0aXZlRW5kICE9IC0xIHx8IHRoaXMucmVsYXRpdmVTdGFydCAhPSAtMSkgewogICAgICAgICAgICB0aGlzLnJlbGF0aXZlRW5kID0gdGhpcy5yZWxhdGl2ZVN0YXJ0ICsgbmV3VmFsLmxlbmd0aDsKICAgICAgICB9CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5leGVjdXRlUmVwbGFjZSA9IGZ1bmN0aW9uIChmaW5kVmFsLCByZXBsYWNlVmFsKSB7CiAgICAgICAgdGhpcy5maW5kVGV4dCA9IGZpbmRWYWw7CiAgICAgICAgaWYgKGZpbmRWYWwpIHsKICAgICAgICAgICAgdGhpcy5yZXBsYWNlKGZpbmRWYWwsIHJlcGxhY2VWYWwpOwogICAgICAgICAgICB0aGlzLmV4ZWN1dGVGaW5kKGZpbmRWYWwpOwogICAgICAgIH0KICAgIH07CgogICAgRmluZEFuZFJlcGxhY2UucHJvdG90eXBlLmV4ZWN1dGVSZXBsYWNlQWxsID0gZnVuY3Rpb24gKGZpbmRWYWwsIHJlcGxhY2VWYWwpIHsKICAgICAgICB0aGlzLmZpbmRUZXh0ID0gZmluZFZhbDsKICAgICAgICBpZiAoZmluZFZhbCkgewogICAgICAgICAgICB0aGlzLnJlcGxhY2VBbGwoZmluZFZhbCwgcmVwbGFjZVZhbCk7CiAgICAgICAgfQogICAgfTsKCiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUuY3JlYXRlUmVnRXhwID0gZnVuY3Rpb24gKHNlYXJjaFRleHQpIHsKICAgICAgICBpZiAodGhpcy5pc0RpcnR5IHx8ICF0aGlzLnJlZ0V4cCkgewogICAgICAgICAgICBpZiAodGhpcy5pc1JlZ0V4ICYmIHRoaXMuaXNDYXNlU2Vuc2l0aXZlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnJlZ0V4cCA9IG5ldyBSZWdFeHAoc2VhcmNoVGV4dCwgImciKTsKICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmlzV2hvbGVXb3JkICYmIHRoaXMuaXNDYXNlU2Vuc2l0aXZlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnJlZ0V4cCA9IG5ldyBSZWdFeHAoIlxcYiIgKyBzZWFyY2hUZXh0ICsgIlxcYiIsICJnIik7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1dob2xlV29yZCkgewogICAgICAgICAgICAgICAgdGhpcy5yZWdFeHAgPSBuZXcgUmVnRXhwKCJcXGIiICsgc2VhcmNoVGV4dCArICJcXGIiLCAiaWciKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMucmVnRXhwID0gbmV3IFJlZ0V4cChzZWFyY2hUZXh0LCAiaWciKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLmlzRGlydHkgPSBmYWxzZTsKICAgICAgICB9CiAgICB9OwogICAgRmluZEFuZFJlcGxhY2UucHJvdG90eXBlLmZpbmRQb3NpdGlvbiA9IGZ1bmN0aW9uIChzZWFyY2gpIHsKICAgICAgICBpZiAodGhpcy5pc1JlZ0V4IHx8IHRoaXMuaXNXaG9sZVdvcmQpIHsKICAgICAgICAgICAgdGhpcy5maW5kUG9zaXRpb25XaXRoUmVnRXhwKHNlYXJjaCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhpcy5maW5kUG9zaXRpb25XaXRoSW5kZXhPZihzZWFyY2gpOwogICAgICAgIH0KICAgIH07CiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUuZmluZFBvc2l0aW9uV2l0aFJlZ0V4cCA9IGZ1bmN0aW9uIChzZWFyY2gpIHsKICAgICAgICBpZiAodGhpcy5pc0RpcnR5IHx8ICF0aGlzLnJlZ0V4cCkgewogICAgICAgICAgICB0aGlzLmNyZWF0ZVJlZ0V4cChzZWFyY2gpOwogICAgICAgIH0KICAgICAgICB2YXIgcmVzdWx0ID0gdGhpcy5yZWdFeHAuZXhlYyh0aGlzLnNvdXJjZSk7CiAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQuaGFzT3duUHJvcGVydHkoImluZGV4IikpIHsKICAgICAgICAgICAgdGhpcy5zZXRQb3NpdGlvbihyZXN1bHQuaW5kZXgsIHJlc3VsdC5pbmRleCArIHJlc3VsdFswXS5sZW5ndGgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRoaXMuc2V0UG9zaXRpb24oLTEsIC0xKTsKICAgICAgICB9CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5maW5kUG9zaXRpb25XaXRoSW5kZXhPZiA9IGZ1bmN0aW9uIChzZWFyY2gpIHsKICAgICAgICB2YXIgbW9kaWZpZWRTb3VyY2UgPSB0aGlzLnNvdXJjZTsKICAgICAgICB2YXIgc3RhcnRGcm9tID0gMDsKICAgICAgICBpZiAodGhpcy5pc0RpcnR5KSB7CiAgICAgICAgICAgIHN0YXJ0RnJvbSA9IDA7CiAgICAgICAgICAgIHRoaXMuaXNEaXJ0eSA9IGZhbHNlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN0YXJ0RnJvbSA9IHRoaXMucmVsYXRpdmVFbmQ7CiAgICAgICAgfQogICAgICAgIGlmICghdGhpcy5pc0Nhc2VTZW5zaXRpdmUpIHsKICAgICAgICAgICAgbW9kaWZpZWRTb3VyY2UgPSB0aGlzLnNvdXJjZS50b0xvY2FsZUxvd2VyQ2FzZSgpOwogICAgICAgICAgICBzZWFyY2ggPSBzZWFyY2gudG9Mb2NhbGVMb3dlckNhc2UoKTsKICAgICAgICB9CiAgICAgICAgdmFyIHN0YXJ0ID0gbW9kaWZpZWRTb3VyY2UuaW5kZXhPZihzZWFyY2gsIHN0YXJ0RnJvbSk7CiAgICAgICAgdmFyIGVuZCA9IHN0YXJ0ICE9IC0xID8gc3RhcnQgKyBzZWFyY2gubGVuZ3RoIDogLTE7CiAgICAgICAgdGhpcy5zZXRQb3NpdGlvbihzdGFydCwgZW5kKTsKICAgIH07CiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUuc2V0UG9zaXRpb24gPSBmdW5jdGlvbiAoc3RhcnQsIGVuZCkgewogICAgICAgIGlmICgoc3RhcnQgPT0gLTEgfHwgZW5kID09IC0xKSAmJiB0aGlzLnJlbGF0aXZlRW5kID4gMCkgewogICAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSBucy5JMThuLmdldCgiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIpOwogICAgICAgIH0gZWxzZSBpZiAoc3RhcnQgPT0gLTEgfHwgZW5kID09IC0xKSB7CiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9IG5zLkkxOG4uZ2V0KCJNYXRjaCBOb3QgRm91bmQiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSAiIjsKICAgICAgICB9CiAgICAgICAgdGhpcy5yZWxhdGl2ZVN0YXJ0ID0gc3RhcnQ7CiAgICAgICAgdGhpcy5yZWxhdGl2ZUVuZCA9IGVuZDsKICAgIH07CiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUucmVwbGFjZSA9IGZ1bmN0aW9uIChzZWFyY2gsIHJlcGxhY2VXaXRoKSB7CiAgICAgICAgaWYgKHRoaXMucmVsYXRpdmVTdGFydCA9PSAtMSB8fCB0aGlzLnJlbGF0aXZlRW5kID09IC0xKSB7CiAgICAgICAgICAgIHRoaXMuZmluZFBvc2l0aW9uKHNlYXJjaCk7CiAgICAgICAgfQogICAgICAgIHRoaXMucmVwbGFjZVZhbHVlKHJlcGxhY2VXaXRoKTsKICAgIH07CgogICAgRmluZEFuZFJlcGxhY2UucHJvdG90eXBlLnJlcGxhY2VBbGwgPSBmdW5jdGlvbiAoc2VhcmNoLCByZXBsYWNlV2l0aCkgewogICAgICAgIHZhciByZXBsYWNlQ291bnQgPSAwOwogICAgICAgIHRoaXMucmVsYXRpdmVTdGFydCA9IHRoaXMucmVsYXRpdmVFbmQgPSAtMTsKICAgICAgICB0aGlzLmZpbmRQb3NpdGlvbihzZWFyY2gpOwogICAgICAgIHdoaWxlICh0aGlzLnJlbGF0aXZlU3RhcnQgIT0gLTEpIHsKICAgICAgICAgICAgcmVwbGFjZUNvdW50Kys7CiAgICAgICAgICAgIHRoaXMucmVwbGFjZVZhbHVlKHJlcGxhY2VXaXRoKTsKICAgICAgICAgICAgdGhpcy5maW5kUG9zaXRpb24oc2VhcmNoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXNzYWdlID0gcmVwbGFjZUNvdW50ID09IDAgPyBucy5JMThuLmdldCgiTWF0Y2ggTm90IEZvdW5kIikgOiBucy5JMThuLmdldCgiezB9IG1hdGNoZXMgcmVwbGFjZWQiLCBbcmVwbGFjZUNvdW50XSk7CiAgICB9OwogICAgRmluZEFuZFJlcGxhY2UucHJvdG90eXBlLnJlcGxhY2VWYWx1ZSA9IGZ1bmN0aW9uIChyZXBsYWNlV2l0aCkgewogICAgICAgIGlmICh0aGlzLnRleHRFZGl0b3IpIHsKICAgICAgICAgICAgdGhpcy5zZXRTZWxlY3Rpb25BbmRIaWdobGlnaHQobnVsbCwgdGhpcy5yZWxhdGl2ZVN0YXJ0LCB0aGlzLnJlbGF0aXZlRW5kLCBmYWxzZSk7CiAgICAgICAgICAgIHRoaXMudGV4dEVkaXRvci5leGVjdXRlQ29tbWFuZCgiaW5zZXJ0VGV4dCIsIHJlcGxhY2VXaXRoKTsKICAgICAgICAgICAgdGhpcy5hZGp1c3RTZWFyY2hQb3NpdGlvbkFmdGVyUmVwbGFjZShyZXBsYWNlV2l0aCk7CiAgICAgICAgfQogICAgfTsKCn0pKEZvcm0ucnRlKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDcvMjcvMjAxNi4KICovCgooZnVuY3Rpb24gKCQsIG5zKSB7CiAgICAidXNlIHN0cmljdCI7CgogICAgSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcignSTE4bicsIGZ1bmN0aW9uIChvYmplY3QpIHsKICAgICAgICByZXR1cm4gbmV3IEhhbmRsZWJhcnMuU2FmZVN0cmluZyhucy5JMThuLmdldChvYmplY3QpKTsKICAgIH0pOwoKICAgIHZhciBjb21tYW5kcyA9IHsKICAgICAgICB1bmRvIDogewogICAgICAgICAgICB0aXRsZSA6ICdVbmRvJywKICAgICAgICAgICAgdGV4dCA6ICdVbmRvJywKICAgICAgICAgICAgaWNvbiA6ICdjY3cnCiAgICAgICAgfSwKICAgICAgICByZWRvIDogewogICAgICAgICAgICB0aXRsZSA6ICdSZWRvJywKICAgICAgICAgICAgdGV4dCA6ICdSZWRvJywKICAgICAgICAgICAgaWNvbiA6ICdjdycKICAgICAgICB9LAogICAgICAgIGJvbGQgOiB7CiAgICAgICAgICAgIHRpdGxlIDogJ0JvbGQnLAogICAgICAgICAgICBpY29uIDogJ2JvbGQnCiAgICAgICAgfSwKICAgICAgICBpdGFsaWMgOiB7CiAgICAgICAgICAgIHRpdGxlIDogJ0l0YWxpYycsCiAgICAgICAgICAgIGljb24gOiAnaXRhbGljJwogICAgICAgIH0sCiAgICAgICAgdW5kZXJsaW5lIDogewogICAgICAgICAgICB0aXRsZSA6ICdVbmRlcmxpbmUnLAogICAgICAgICAgICBpY29uIDogJ3VuZGVybGluZScsCiAgICAgICAgICAgICdjbGFzcycgOiAncnRlLWN1c3RvbS1pY29uJwogICAgICAgIH0sCiAgICAgICAgc3VwZXJzY3JpcHQgOiB7CiAgICAgICAgICAgIHRpdGxlIDogJ1N1cGVyLXNjcmlwdCcsCiAgICAgICAgICAgIGljb24gOiAnc3VwZXJzY3JpcHQnCiAgICAgICAgfSwKICAgICAgICBzdWJzY3JpcHQgOiB7CiAgICAgICAgICAgIHRpdGxlIDogJ1N1Yi1zY3JpcHQnLAogICAgICAgICAgICBpY29uIDogJ3N1YnNjcmlwdCcKICAgICAgICB9LAogICAgICAgIGZvcmVDb2xvciA6IHsKICAgICAgICAgICAgdGl0bGUgOiAnVGV4dCBDb2xvcicsCiAgICAgICAgICAgIHR5cGUgOiAnY29sb3JJbnB1dCcsCiAgICAgICAgICAgIGljb24gOiAndGV4dC1jb2xvcicKICAgICAgICB9LAogICAgICAgIGhpbGl0ZUNvbG9yIDogewogICAgICAgICAgICB0aXRsZSA6ICdIaWdobGlnaHQgQ29sb3InLAogICAgICAgICAgICB0eXBlIDogJ2NvbG9ySW5wdXQnCiAgICAgICAgfSwKICAgICAgICBmb250RmFtaWx5IDogewogICAgICAgICAgICB0eXBlIDogJ3NlbGVjdCcsCiAgICAgICAgICAgIHRpdGxlIDogJ0ZvbnQgRmFtaWx5JwogICAgICAgIH0sCiAgICAgICAgZm9udFNpemUgOiB7CiAgICAgICAgICAgIHR5cGUgOiAnc2VsZWN0JywKICAgICAgICAgICAgdGl0bGUgOiAnRm9udCBTaXplJwogICAgICAgIH0sCiAgICAgICAgbGluZUhlaWdodCA6IHsKICAgICAgICAgICAgdHlwZSA6ICdzZWxlY3QnLAogICAgICAgICAgICBjb21tYW5kIDogJ2NoYW5nZUxpbmVIZWlnaHQnLAogICAgICAgICAgICB0aXRsZSA6ICdMaW5lIEhlaWdodCcKICAgICAgICB9LAogICAgICAgIGxldHRlclNwYWNpbmcgOiB7CiAgICAgICAgICAgIHR5cGUgOiAnc2VsZWN0JywKICAgICAgICAgICAgdGl0bGUgOiAnTGV0dGVyIFNwYWNpbmcnCiAgICAgICAgfSwKICAgICAgICBoZWFkZXIgOiB7CiAgICAgICAgICAgIHR5cGUgOiAnc2VsZWN0JywKICAgICAgICAgICAgdGl0bGUgOiAnUGFyYWdyYXBoIEZvcm1hdCcKICAgICAgICB9LAogICAgICAgIGp1c3RpZnlMZWZ0IDogewogICAgICAgICAgICB0aXRsZSA6ICdKdXN0aWZ5IExlZnQnLAogICAgICAgICAgICBpY29uIDogJ2FsaWduLWxlZnQnCiAgICAgICAgfSwKICAgICAgICBqdXN0aWZ5Q2VudGVyIDogewogICAgICAgICAgICB0aXRsZSA6ICdKdXN0aWZ5IENlbnRlcicsCiAgICAgICAgICAgIGljb24gOiAnYWxpZ24tY2VudGVyJwogICAgICAgIH0sCiAgICAgICAganVzdGlmeUZ1bGwgOiB7CiAgICAgICAgICAgIHRpdGxlIDogJ0p1c3RpZnkgRnVsbCcsCiAgICAgICAgICAgIGljb24gOiAnYWxpZ24tanVzdGlmeScKICAgICAgICB9LAogICAgICAgIGp1c3RpZnlSaWdodCA6IHsKICAgICAgICAgICAgdGl0bGUgOiAnSnVzdGlmeSBSaWdodCcsCiAgICAgICAgICAgIGljb24gOiAnYWxpZ24tcmlnaHQnCiAgICAgICAgfSwKICAgICAgICBtYXJnaW5MZWZ0IDogewogICAgICAgICAgICB0eXBlIDogJ251bWJlcklucHV0JywKICAgICAgICAgICAgdGl0bGUgOiAnTWFyZ2luIExlZnQnCiAgICAgICAgfSwKICAgICAgICBtYXJnaW5SaWdodCA6IHsKICAgICAgICAgICAgdHlwZSA6ICdudW1iZXJJbnB1dCcsCiAgICAgICAgICAgIHRpdGxlIDogJ01hcmdpbiBSaWdodCcKICAgICAgICB9LAogICAgICAgIG1hcmdpblRvcCA6IHsKICAgICAgICAgICAgdHlwZSA6ICdudW1iZXJJbnB1dCcsCiAgICAgICAgICAgIHRpdGxlIDogJ01hcmdpbiBUb3AnCiAgICAgICAgfSwKICAgICAgICBtYXJnaW5Cb3R0b20gOiB7CiAgICAgICAgICAgIHR5cGUgOiAnbnVtYmVySW5wdXQnLAogICAgICAgICAgICB0aXRsZSA6ICdNYXJnaW4gQm90dG9tJwogICAgICAgIH0sCiAgICAgICAgaW5zZXJ0VW5vcmRlcmVkTGlzdCA6IHsKICAgICAgICAgICAgdGl0bGUgOiAnQnVsbGV0ZWQgTGlzdCcsCiAgICAgICAgICAgIGljb24gOiAibGlzdCIKICAgICAgICB9LAogICAgICAgIGluc2VydE9yZGVyZWRMaXN0IDogewogICAgICAgICAgICBjb21tYW5kIDogImluc2VydE9yZGVyZWRMaXN0IiwKICAgICAgICAgICAgdmFsdWUgOiAiT3JkZXJlZCIsCiAgICAgICAgICAgIHRpdGxlIDogIk51bWJlcmVkIExpc3QiLAogICAgICAgICAgICBpY29uIDogInRleHROdW1iZXJlZCIsCiAgICAgICAgICAgICdjbGFzcycgOiAicnRlLWN1c3RvbS1pY29uIgogICAgICAgIH0sCiAgICAgICAgaW5zZXJ0VXBwZXJjYXNlQWxwaGFiZXRMaXN0IDogewogICAgICAgICAgICBjb21tYW5kIDogImluc2VydE9yZGVyZWRMaXN0IiwKICAgICAgICAgICAgZWxlbWVudCA6ICJydGVfY2Fwc19hbHBoYV9saXN0X2NvbW1hbmQiLAogICAgICAgICAgICB2YWx1ZSA6ICJBIiwKICAgICAgICAgICAgdGl0bGUgOiAiVXBwZXItY2FzZSBBbHBoYWJldCBMaXN0IiwKICAgICAgICAgICAgaWNvbiA6ICJ0ZXh0TGV0dGVyZWRVcHBlcmNhc2UiLAogICAgICAgICAgICAnY2xhc3MnIDogInJ0ZS1jdXN0b20taWNvbiIKICAgICAgICB9LAogICAgICAgIGluc2VydExvd2VyY2FzZUFscGhhYmV0TGlzdCA6IHsKICAgICAgICAgICAgY29tbWFuZCA6ICJpbnNlcnRPcmRlcmVkTGlzdCIsCiAgICAgICAgICAgIGVsZW1lbnQgOiAicnRlX2FscGhhX2xpc3RfY29tbWFuZCIsCiAgICAgICAgICAgIHZhbHVlIDogImEiLAogICAgICAgICAgICB0aXRsZSA6ICJMb3dlci1jYXNlIEFscGhhYmV0IExpc3QiLAogICAgICAgICAgICBpY29uIDogInRleHRMZXR0ZXJlZExvd2VyY2FzZSIsCiAgICAgICAgICAgICdjbGFzcycgOiAicnRlLWN1c3RvbS1pY29uIgogICAgICAgIH0sCiAgICAgICAgaW5zZXJ0VXBwZXJjYXNlUm9tYW5MaXN0IDogewogICAgICAgICAgICBjb21tYW5kIDogImluc2VydE9yZGVyZWRMaXN0IiwKICAgICAgICAgICAgZWxlbWVudCA6ICJydGVfY2Fwc19yb21hbl9saXN0X2NvbW1hbmQiLAogICAgICAgICAgICB2YWx1ZSA6ICJJIiwKICAgICAgICAgICAgdGl0bGUgOiAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiwKICAgICAgICAgICAgaWNvbiA6ICJ0ZXh0Um9tYW5VcHBlcmNhc2UiLAogICAgICAgICAgICAnY2xhc3MnIDogInJ0ZS1jdXN0b20taWNvbiIKICAgICAgICB9LAogICAgICAgIGluc2VydExvd2VyY2FzZVJvbWFuTGlzdCA6IHsKICAgICAgICAgICAgY29tbWFuZCA6ICJpbnNlcnRPcmRlcmVkTGlzdCIsCiAgICAgICAgICAgIGVsZW1lbnQgOiAicnRlX3JvbWFuX2xpc3RfY29tbWFuZCIsCiAgICAgICAgICAgIHZhbHVlIDogImkiLAogICAgICAgICAgICB0aXRsZSA6ICJMb3dlci1jYXNlIFJvbWFuIExpc3QiLAogICAgICAgICAgICBpY29uIDogInRleHRSb21hbkxvd2VyY2FzZSIsCiAgICAgICAgICAgICdjbGFzcycgOiAicnRlLWN1c3RvbS1pY29uIgogICAgICAgIH0sCiAgICAgICAgaW5kZW50IDogewogICAgICAgICAgICB0aXRsZSA6ICdJbmRlbnQnLAogICAgICAgICAgICBpY29uIDogImluZGVudC1sZWZ0IgogICAgICAgIH0sCiAgICAgICAgb3V0ZGVudCA6IHsKICAgICAgICAgICAgdGl0bGUgOiAnT3V0ZGVudCcsCiAgICAgICAgICAgIGljb24gOiAiaW5kZW50LXJpZ2h0IgogICAgICAgIH0sCiAgICAgICAgZmluZEFuZFJlcGxhY2UgOiB7CiAgICAgICAgICAgIHRleHQgOiAiRmluZCAmIFJlcGxhY2UiLAogICAgICAgICAgICBpY29uIDogJ3NlYXJjaCcsCiAgICAgICAgICAgIHR5cGUgOiAncG9wb3ZlcicsCiAgICAgICAgICAgIGNvbnRlbnQgOiBIYW5kbGViYXJzLnRlbXBsYXRlcy5maW5kQW5kUmVwbGFjZSgpLAogICAgICAgICAgICBjYWxsYmFjayA6ICJGb3JtLnJ0ZS5Db21tYW5kU3RhdGVDYWxsYmFja3Muc2V0RmluZEFuZFJlcGxhY2VNZXNzYWdlIiwKICAgICAgICAgICAgcGxhY2VtZW50IDogJ2JvdHRvbScKICAgICAgICB9LAogICAgICAgIGxpbmsgOiB7CiAgICAgICAgICAgIHRpdGxlIDogIkluc2VydCBMaW5rIiwKICAgICAgICAgICAgaWNvbiA6ICdsaW5rJywKICAgICAgICAgICAgdHlwZSA6ICdwb3BvdmVyJywKICAgICAgICAgICAgY29udGVudCA6IEhhbmRsZWJhcnMudGVtcGxhdGVzLmxpbmsoKSwKICAgICAgICAgICAgcGxhY2VtZW50IDogJ2JvdHRvbScKICAgICAgICB9CiAgICB9OwoKICAgIG5zLlRvb2xiYXIgPSBmdW5jdGlvbiAob3B0aW9ucywgY29uZmlnKSB7CiAgICAgICAgdGhpcy50b29sYmFycyA9IChvcHRpb25zICYmIG9wdGlvbnMudG9vbGJhcnMpIHx8IG5zLlRvb2xiYXJDb25maWcudG9vbGJhcnM7CiAgICAgICAgdGhpcy5tb2RlcyA9IHt9OwogICAgICAgIHRoaXMubW9kZSA9IChvcHRpb25zICYmIG9wdGlvbnMuZGVmYXVsdE1vZGUpIHx8IG5zLlRvb2xiYXJDb25maWcuZGVmYXVsdE1vZGU7CiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7CiAgICB9OwoKICAgIC8qKgogICAgICogUmVuZGVycyB0aGUgdG9vbGJhciBzcGVjaWZpYyB0byBjdXJyZW50IG1vZGUKICAgICAqIEByZXR1cm5zIHsqfQogICAgICovCiAgICBucy5Ub29sYmFyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIG1vZGUgPSB0aGlzLm1vZGU7CiAgICAgICAgdmFyIGNvbmZpZyA9IHRoaXMuY29uZmlnOwogICAgICAgIGlmICghdGhpcy5tb2Rlcy5oYXNPd25Qcm9wZXJ0eShtb2RlKSkgewogICAgICAgICAgICB2YXIgdG9vbGJhckhUTUwgPSAiIjsKICAgICAgICAgICAgdmFyIG1vZGVDb25maWcgPSB0aGlzLnRvb2xiYXJzW21vZGVdOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdmFyIGxheW91dCA9IG1vZGVDb25maWcubGF5b3V0OwogICAgICAgICAgICAgICAgaWYgKGxheW91dCBpbnN0YW5jZW9mIEFycmF5KSB7CiAgICAgICAgICAgICAgICAgICAgbGF5b3V0LmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgdG9vbGJhckhUTUwgKz0gcmVuZGVyQ29tbWFuZHMoaXRlbSwgY29uZmlnKTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMubW9kZXNbbW9kZV0gPSAgJChIYW5kbGViYXJzLnRlbXBsYXRlcy5ydGV0b29sYmFyKHRvb2xiYXJIVE1MKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoIkVycm9yIGluIGNvbnN0cnVjdGluZyBUb29sYmFyIDogIiArIGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzLm1vZGVzW21vZGVdOwogICAgfTsKCiAgICAvKioKICAgICAqIFNldCBjdXJyZW50IG1vZGUgb2YgdGhlIFRvb2xiYXIKICAgICAqIEBwYXJhbSBtb2RlCiAgICAgKi8KICAgIG5zLlRvb2xiYXIucHJvdG90eXBlLnNldE1vZGUgPSBmdW5jdGlvbiAobW9kZSkgewogICAgICAgIHRoaXMubW9kZSA9IG1vZGU7CiAgICAgICAgcmV0dXJuIHRoaXMucmVuZGVyKCk7CiAgICB9OwoKICAgIC8qKgogICAgICogUmV0dXJucyBjdXJyZW50IG1vZGUgb2YgdGhlIFRvb2xiYXIKICAgICAqIEByZXR1cm5zIEN1cnJlbnQgbW9kZQogICAgICovCiAgICBucy5Ub29sYmFyLnByb3RvdHlwZS5nZXRNb2RlID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiB0aGlzLm1vZGU7CiAgICB9OwoKICAgIG5zLlRvb2xiYXIucHJvdG90eXBlLl90b2dnbGVGbG9hdGluZ1Rvb2xiYXIgPSBmdW5jdGlvbiAocnRlLCB0b29sYmFyLCBlLCBzaG93KSB7CiAgICAgICAgdmFyIGVkaXRvciA9IHJ0ZS4kZWxlbWVudC5maW5kKCIud3lzaWh0bWw1LWVkaXRvciIpWzBdLAogICAgICAgICAgICBlZGl0b3JGb2N1c2VkID0gc2hvdyB8fCBlZGl0b3IuY29udGFpbnMoZS50YXJnZXQpIHx8IGVkaXRvciA9PSBlLnRhcmdldCwKICAgICAgICAgICAgdG9vbGJhckZvY3VzZWQgPSBlICYmIHRvb2xiYXIuaGFzKGUudGFyZ2V0KTsKICAgICAgICBpZiAoZWRpdG9yRm9jdXNlZCkgewogICAgICAgICAgICB0b29sYmFyLnNob3coKTsKICAgICAgICAgICAgdmFyIG9mZnNldCA9ICQoZWRpdG9yKS5vZmZzZXQoKTsKICAgICAgICAgICAgdG9vbGJhci5vZmZzZXQoewogICAgICAgICAgICAgICAgdG9wIDogb2Zmc2V0LnRvcCAtIHRvb2xiYXIuaGVpZ2h0KCkgLSA0LAogICAgICAgICAgICAgICAgbGVmdCA6IG9mZnNldC5sZWZ0CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSBpZiAoIXRvb2xiYXJGb2N1c2VkIHx8IHRvb2xiYXJGb2N1c2VkLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIHRvb2xiYXIuaGlkZSgpOwogICAgICAgIH0KICAgIH07CgogICAgbnMuVG9vbGJhci5wcm90b3R5cGUuaW5pdGlhbGl6ZVRvb2xiYXJFdmVudHMgPSBmdW5jdGlvbiAocnRlKSB7CiAgICAgICAgdmFyIG1vZGUgPSB0aGlzLm1vZGU7CiAgICAgICAgaWYgKHRoaXMubW9kZXMuaGFzT3duUHJvcGVydHkobW9kZSkpIHsKICAgICAgICAgICAgdmFyIHRvb2xiYXIgPSB0aGlzLm1vZGVzW21vZGVdOwogICAgICAgICAgICBpZiAodGhpcy50b29sYmFycyAmJiB0aGlzLnRvb2xiYXJzW21vZGVdICYmIHRoaXMudG9vbGJhcnNbbW9kZV0uZmxvYXRpbmcgJiYgIXRoaXMudG9nZ2xlVG9vbGJhcikgewogICAgICAgICAgICAgICAgLyogQWRkIGZvY3VzIGhhbmRsZXIgdG8gZWRpdG9yIGlmIHRoZSB0b29sYmFyIGlzIG9mIGZsb2F0aW5nIG5hdHVyZSAqLwogICAgICAgICAgICAgICAgdGhpcy50b2dnbGVUb29sYmFyID0gJC5wcm94eSh0aGlzLl90b2dnbGVGbG9hdGluZ1Rvb2xiYXIsIHRoaXMsIHJ0ZSwgdG9vbGJhcik7CiAgICAgICAgICAgICAgICAkKGRvY3VtZW50KS5vbigibW91c2V1cCIsIHRoaXMudG9nZ2xlVG9vbGJhcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzOwogICAgICAgICAgICAvKiBMaXN0ZW4gZm9yIG1vZGUgY2hhbmdlIG9uIHRvb2xiYXIgKi8KICAgICAgICAgICAgaWYgKHRvb2xiYXIuaGFzQ2xhc3MoImluaXRpYWxpemVkIikpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICB0b29sYmFyLmZpbmQoIltkYXRhLXd5c2lodG1sNS1jb21tYW5kPSdtb2RlJ10iKS5vbigiY2xpY2siLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgbW9kZSA9IHRoaXMuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS1jb21tYW5kLXZhbHVlIik7CiAgICAgICAgICAgICAgICAkKHNlbGYpLnRyaWdnZXIoIm1vZGVDaGFuZ2VkIiwgbW9kZSk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICB2YXIgY29sb3JzID0gcnRlLmVkaXRvckNvbmZpZyA/IHJ0ZS5lZGl0b3JDb25maWcuY29sb3IgOiB7fTsKICAgICAgICAgICAgdG9vbGJhci5maW5kKCIucnRlLWNvbG9ySW5wdXQtY29udHJvbDpub3QoLnBpY2stYS1jb2xvcikiKS5waWNrQUNvbG9yKHsKICAgICAgICAgICAgICAgIHRvdWNoT25seU1vZGUgOiBmYWxzZSwgLy8gZm9yIHRvdWNoLW9ubHkgZGV2aWNlcyBbdGFibGV0LCBzbWFydHBob25lLCBldGMuXQogICAgICAgICAgICAgICAgc2hvd1NwZWN0cnVtIDogdHJ1ZSwKICAgICAgICAgICAgICAgIHNob3dTYXZlZENvbG9ycyA6IGZhbHNlLAogICAgICAgICAgICAgICAgc2F2ZUNvbG9yc1BlckVsZW1lbnQgOiBmYWxzZSwKICAgICAgICAgICAgICAgIGZhZGVNZW51VG9nZ2xlIDogdHJ1ZSwKICAgICAgICAgICAgICAgIHNob3dBZHZhbmNlZCA6IHRydWUsCiAgICAgICAgICAgICAgICBzaG93QmFzaWNDb2xvcnMgOiB0cnVlLAogICAgICAgICAgICAgICAgc2hvd0hleElucHV0IDogZmFsc2UsCiAgICAgICAgICAgICAgICBiYXNpY0NvbG9ycyA6IGNvbG9ycwogICAgICAgICAgICB9KS5vbignY2hhbmdlJywgZnVuY3Rpb24gKGUpIHsKICAgICAgICAgICAgICAgIHJ0ZS5leGVjdXRlQ29tbWFuZChlLnRhcmdldC5nZXRBdHRyaWJ1dGUoImRhdGEtd3lzaWh0bWw1LWNvbW1hbmQiKSwgIiMiICsgZS50YXJnZXQudmFsdWUpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIGZvciAodmFyIGNvbG9yIGluIGNvbG9ycykgewogICAgICAgICAgICAgICAgaWYgKGNvbG9ycy5oYXNPd25Qcm9wZXJ0eShjb2xvcikpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0b3IgPSB0b29sYmFyLmZpbmQoIi5waWNrLWEtY29sb3ItbWFya3VwIC5zcGVjdHJ1bS0iICsgY29sb3IpOwogICAgICAgICAgICAgICAgICAgIG5zLnV0aWwuUlRFVXRpbHMuYWRkU3BlY3RydW1HcmFkaWVudChzZWxlY3RvciwgY29sb3JzW2NvbG9yXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdG9vbGJhci5vbigiY2xpY2siLCAiLnJ0ZS1wb3BvdmVyID4gYnV0dG9uIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHBvcG92ZXIgPSAkKHRoaXMpLnNpYmxpbmdzKCIucG9wb3ZlciIpOwogICAgICAgICAgICAgICAgdmFyIG9mZnNldCA9ICQodGhpcykub2Zmc2V0KCk7CiAgICAgICAgICAgICAgICBvZmZzZXQudG9wICs9IHRoaXMuY2xpZW50SGVpZ2h0OwogICAgICAgICAgICAgICAgcG9wb3Zlci50b2dnbGUoKTsKICAgICAgICAgICAgICAgIHBvcG92ZXIub2Zmc2V0KG9mZnNldCk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICB0b29sYmFyLm9uKCJjbGljayIsICIucnRlLXBvcG92ZXIgPiAucnRlX2xpbmtfY29tbWFuZCIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBwb3BvdmVyID0gJCh0aGlzKS5zaWJsaW5ncygiLnBvcG92ZXIiKTsKICAgICAgICAgICAgICAgIGlmIChwb3BvdmVyKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHQgPSBydGUuY29tcG9zZXIgJiYgcnRlLmNvbXBvc2VyLnNlbGVjdGlvbiA/IHJ0ZS5jb21wb3Nlci5zZWxlY3Rpb24uZ2V0VGV4dCgpIDogIiI7CiAgICAgICAgICAgICAgICAgICAgcG9wb3Zlci5maW5kKCJpbnB1dFtuYW1lPSdhbHQnXSIpLnZhbCh0ZXh0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CgogICAgICAgICAgICB0b29sYmFyLm9uKCJjbGljayIsICIucnRlLXBvcG92ZXIgLnBvcG92ZXIgW3J0ZS1jbG9zZV0iLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgcG9wb3ZlciA9ICQodGhpcykuY2xvc2VzdCgiLnBvcG92ZXIiKTsKICAgICAgICAgICAgICAgIHBvcG92ZXIuaGlkZSgpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIHRoaXMuX3RvZ2dsZUZsb2F0aW5nVG9vbGJhcihydGUsIHRvb2xiYXIsIG51bGwsIHRydWUpOwogICAgICAgICAgICB0b29sYmFyLmFkZENsYXNzKCJpbml0aWFsaXplZCIpOwogICAgICAgIH0KICAgIH07CgogICAgdmFyIHJlbmRlckNvbW1hbmRzID0gZnVuY3Rpb24gKGNvbW1hbmRPYmosIGNvbmZpZykgewogICAgICAgIHZhciBodG1sID0gIiI7CiAgICAgICAgdmFyIGl0ZW1Db25maWc7CiAgICAgICAgaWYgKHR5cGVvZiBjb21tYW5kT2JqID09ICJzdHJpbmciKSB7CiAgICAgICAgICAgIC8qIEZldGNoIGNvbmZpZ3VyYXRpb24gZnJvbSBPT1RCIGNvbW1hbmQgaWYgcHJlc2VudCAqLwogICAgICAgICAgICBpZiAoY29tbWFuZHMgJiYgY29tbWFuZHMuaGFzT3duUHJvcGVydHkoY29tbWFuZE9iaikpIHsKICAgICAgICAgICAgICAgIGl0ZW1Db25maWcgPSBjb21tYW5kc1tjb21tYW5kT2JqXTsKICAgICAgICAgICAgICAgIGl0ZW1Db25maWcuY29tbWFuZCA9IGl0ZW1Db25maWcuY29tbWFuZCB8fCBjb21tYW5kT2JqOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgY29tbWFuZE9iaiA9PSAib2JqZWN0IikgewogICAgICAgICAgICAvKiBGZXRjaCBjb25maWd1cmF0aW9uIGZyb20gT09UQiBjb21tYW5kIGlmIHByZXNlbnQgKi8KICAgICAgICAgICAgaXRlbUNvbmZpZyA9ICQuZXh0ZW5kKGNvbW1hbmRzW2NvbW1hbmRPYmouY29tbWFuZF0sIGNvbW1hbmRPYmopOwogICAgICAgIH0KICAgICAgICBpZiAoaXRlbUNvbmZpZykgewogICAgICAgICAgICBpZiAoY29uZmlnICYmIGNvbmZpZy5oYXNPd25Qcm9wZXJ0eShjb21tYW5kT2JqKSkgewogICAgICAgICAgICAgICAgaXRlbUNvbmZpZyA9ICQuZXh0ZW5kKGl0ZW1Db25maWcsIGNvbmZpZ1tjb21tYW5kT2JqXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGl0ZW1Db25maWcuaXRlbXMpIHsKICAgICAgICAgICAgICAgIGl0ZW1Db25maWcudHlwZSA9IGl0ZW1Db25maWcudHlwZSB8fCAgImdyb3VwIjsKICAgICAgICAgICAgICAgIGl0ZW1Db25maWcuY29udGVudCA9ICIiOwogICAgICAgICAgICAgICAgaXRlbUNvbmZpZy5pdGVtcy5mb3JFYWNoKGZ1bmN0aW9uIChpKSB7CiAgICAgICAgICAgICAgICAgICAgaXRlbUNvbmZpZy5jb250ZW50ICs9IHJlbmRlckNvbW1hbmRzKGksIGNvbmZpZyk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiB0ZW1wbGF0ZVR5cGUgZGVmYXVsdHMgdG8gZ3JvdXAgaWYgaXQgY29udGFpbnMgYW55IGl0ZW1zIGVsc2UgZGVmYXVsdHMgdG8gYnV0dG9uKi8KICAgICAgICAgICAgaXRlbUNvbmZpZy50eXBlID0gaXRlbUNvbmZpZy50eXBlIHx8ICJidXR0b24iOwogICAgICAgICAgICBpdGVtQ29uZmlnLmVsZW1lbnQgPSBpdGVtQ29uZmlnLmVsZW1lbnQgfHwgInJ0ZV8iICsgaXRlbUNvbmZpZy5jb21tYW5kICsgIl9jb21tYW5kIjsKICAgICAgICAgICAgaWYgKEhhbmRsZWJhcnMudGVtcGxhdGVzLmhhc093blByb3BlcnR5KGl0ZW1Db25maWcudHlwZSkpIHsKICAgICAgICAgICAgICAgIGh0bWwgKz0gSGFuZGxlYmFycy50ZW1wbGF0ZXNbaXRlbUNvbmZpZy50eXBlXShpdGVtQ29uZmlnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoIlVuYWJsZSB0byByZXRyaWV2ZSB0ZW1wbGF0ZSBmb3IgIiArIGl0ZW1Db25maWcudHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGh0bWw7CiAgICB9Owp9KSgkLCBGb3JtLnJ0ZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiA3LzI3LzIwMTYuCiAqLwoKKGZ1bmN0aW9uIChkb2N1bWVudCwgbnMpIHsKCiAgICB2YXIgY2FsbGJhY2tGdW5jdGlvbnMgPSBucy5Db21tYW5kU3RhdGVDYWxsYmFja3MgPSB7fTsKCiAgICAvKioKICAgICAqIENhbGxiYWNrIHRvIHNldCBCdXR0b24gc3RhdGUgY29ycmVzcG9uZGluZyB0byBjb21tYW5kCiAgICAgKiBAcGFyYW0gZG9tRWxlbSBlbGVtZW50IHRvIHNldCBzdGF0ZSBvbgogICAgICogQHBhcmFtIHN0YXRlIHdoZXRoZXIgY29tbWFuZCBleGVjdXRlZCBvciBub3QKICAgICAqLwogICAgY2FsbGJhY2tGdW5jdGlvbnMuc2V0QnV0dG9uU3RhdGUgPSBmdW5jdGlvbiAoZG9tRWxlbWVudCwgc3RhdGUpIHsKICAgICAgICBzdGF0ZSA9ICEoc3RhdGUgPT0gdW5kZWZpbmVkIHx8IHN0YXRlID09IGZhbHNlKTsKICAgICAgICBpZiAoZG9tRWxlbWVudCkgewogICAgICAgICAgICBpZiAoc3RhdGUpIHsKICAgICAgICAgICAgICAgIGRvbUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgiYWN0aXZlIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBkb21FbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoImFjdGl2ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKCiAgICAvKioKICAgICAqIENhbGxiYWNrIHRvIHNldCBEcm9wZG93biBzdGF0ZSBjb3JyZXNwb25kaW5nIHRvIGNvbW1hbmQKICAgICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSBvZiB0aGUgZHJvcGRvd24gdG8gc2V0CiAgICAgKiBAcGFyYW0gZG9tRWxlbWVudCBlbGVtZW50IHRvIHNldCBzdGF0ZSBvbgogICAgICovCiAgICBjYWxsYmFja0Z1bmN0aW9ucy5zZXRTZWxlY3RTdGF0ZSA9IGZ1bmN0aW9uIChkb21FbGVtZW50LCB2YWx1ZSkgewogICAgICAgIGlmIChkb21FbGVtZW50KSB7CiAgICAgICAgICAgIHZhciBvcHRpb25zID0gZG9tRWxlbWVudC5vcHRpb25zLAogICAgICAgICAgICAgICAgaXNPcHRpb25QcmVzZW50ID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChvcHRpb25zKSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9wdGlvbnMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9uc1tpXS52YWx1ZSA9PSB2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpc09wdGlvblByZXNlbnQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpc09wdGlvblByZXNlbnQpIHsKICAgICAgICAgICAgICAgIHZhbHVlID0gIiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZG9tRWxlbWVudC52YWx1ZSA9IHZhbHVlOwogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBDYWxsYmFjayB0byBzZXQgTnVtYmVyIElucHV0IHN0YXRlIGNvcnJlc3BvbmRpbmcgdG8gY29tbWFuZAogICAgICogQHBhcmFtIHZhbHVlIHZhbHVlIHRvIHNldAogICAgICogQHBhcmFtIG51bWJlcklucHV0IGVsZW1lbnQgdG8gc2V0IHZhbHVlIHRvCiAgICAgKi8KICAgIGNhbGxiYWNrRnVuY3Rpb25zLnNldE51bWJlcklucHV0VmFsdWUgPSBmdW5jdGlvbiAobnVtYmVySW5wdXQsIHZhbHVlKSB7CiAgICAgICAgaWYgKG51bWJlcklucHV0KSB7CiAgICAgICAgICAgIG51bWJlcklucHV0LnZhbHVlID0gdmFsdWU7CiAgICAgICAgfQogICAgfTsKCiAgICAvKioKICAgICAqIENhbGxiYWNrIHRvIHNldCBGaW5kICYgUmVwbGFjZSBtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWVzc2FnZSBtZXNzYWdlIHRvIHNldAogICAgICogQHBhcmFtIGZpbmRSZXBsYWNlQnV0dG9uCiAgICAgKi8KICAgIGNhbGxiYWNrRnVuY3Rpb25zLnNldEZpbmRBbmRSZXBsYWNlTWVzc2FnZSA9IGZ1bmN0aW9uIChmaW5kUmVwbGFjZUJ1dHRvbiwgbWVzc2FnZSkgewogICAgICAgIHZhciBwb3BvdmVyID0gJChmaW5kUmVwbGFjZUJ1dHRvbikuc2libGluZ3MoIi5wb3BvdmVyIilbMF07CiAgICAgICAgaWYgKHBvcG92ZXIpIHsKICAgICAgICAgICAgdmFyIG1lc3NhZ2VFbCA9IHBvcG92ZXIucXVlcnlTZWxlY3RvcigiLnJ0ZV9maW5kTlJlcGxhY2VfbWVzc2FnZSIpOwogICAgICAgICAgICB2YXIgYWxlcnQgPSBwb3BvdmVyLnF1ZXJ5U2VsZWN0b3IoIi5ydGVfZmluZE5SZXBsYWNlX2FsZXJ0Iik7CiAgICAgICAgICAgIGlmIChtZXNzYWdlRWwgJiYgYWxlcnQpIHsKICAgICAgICAgICAgICAgIG1lc3NhZ2VFbC5pbm5lckhUTUwgPSBtZXNzYWdlOwogICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UgJiYgbWVzc2FnZS50cmltKCkgIT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICAkKGFsZXJ0KS5zaG93KCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICQoYWxlcnQpLmhpZGUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgY2FsbGJhY2tGdW5jdGlvbnMuc2V0Q29sb3JJbnB1dFZhbHVlID0gZnVuY3Rpb24gKGRvbUVsZW1lbnQsIHN0YXRlLCBkb21FbGVtZW50TmFtZSwgY21kKSB7CiAgICAgICAgaWYgKGRvbUVsZW1lbnQpIHsKICAgICAgICAgICAgdmFyIGNvbG9yID0gInJnYigwLCAwLCAwKSI7CiAgICAgICAgICAgIGlmIChzdGF0ZSAmJiBzdGF0ZS5zdHlsZSkgewogICAgICAgICAgICAgICAgaWYgKGNtZCA9PSBGb3JtLnJ0ZS5Db21tYW5kcy5GT1JFX0NPTE9SKSB7CiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBzdGF0ZS5zdHlsZS5jb2xvcjsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY21kID09IEZvcm0ucnRlLkNvbW1hbmRzLkhJTElURV9DT0xPUikgewogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gc3RhdGUuc3R5bGUuYmFja2dyb3VuZENvbG9yOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICQoZG9tRWxlbWVudCkuY2xvc2VzdCgiLnBpY2stYS1jb2xvci1tYXJrdXAiKS5maW5kKCIuY3VycmVudC1jb2xvciIpLmNzcygiYmFja2dyb3VuZC1jb2xvciIsIGNvbG9yKTsKICAgICAgICB9CiAgICB9Owp9KShkb2N1bWVudCwgRm9ybS5ydGUpOwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKKGZ1bmN0aW9uIChkb2N1bWVudCwgbnMpIHsKICAgICJ1c2Ugc3RyaWN0IjsKCiAgICB2YXIgU2hvcnRjdXRLZXlzQ3RybCA9IG5zLlNob3J0Y3V0S2V5c0N0cmwgPSB7fTsKCiAgICB2YXIgZ2V0Rm9udFNpemUgPSBmdW5jdGlvbiAobmV4dCwgY29tcG9zZXIsIGZvbnRTaXplTGlzdCkgewogICAgICAgIHZhciBmb250U2l6ZSA9IGNvbXBvc2VyLmNvbW1hbmRzLmNhbGxiYWNrU3RhdGUoImZvbnRTaXplIik7CiAgICAgICAgaWYgKHR5cGVvZiBmb250U2l6ZSA9PT0gInN0cmluZyIpIHsKICAgICAgICAgICAgZm9udFNpemUgPSBwYXJzZUZsb2F0KGZvbnRTaXplKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZvbnRTaXplTGlzdCAmJiBmb250U2l6ZUxpc3QubGVuZ3RoID4gMCkgewogICAgICAgICAgICB2YXIgZm9udEluZGV4ID0gLTEsCiAgICAgICAgICAgICAgICBpID0gMCwKICAgICAgICAgICAgICAgIHZhbHVlID0gcGFyc2VGbG9hdChmb250U2l6ZUxpc3RbaV0pOwogICAgICAgICAgICB3aGlsZSAoaSA8IGZvbnRTaXplTGlzdC5sZW5ndGggJiYgdmFsdWUgPCBmb250U2l6ZSkgewogICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZUZsb2F0KGZvbnRTaXplTGlzdFsrK2ldKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodmFsdWUgPT0gZm9udFNpemUpIHsKICAgICAgICAgICAgICAgIGZvbnRJbmRleCA9IG5leHQgPyBpICsgMSA6IGkgLSAxOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZm9udEluZGV4ID0gbmV4dCA/IGkgOiBpIC0gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZm9udEluZGV4ID4gLTEgJiYgZm9udEluZGV4IDwgZm9udFNpemVMaXN0Lmxlbmd0aCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZvbnRTaXplTGlzdFtmb250SW5kZXhdOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfTsKCiAgICBTaG9ydGN1dEtleXNDdHJsLm9ua2V5ZG93biA9IGZ1bmN0aW9uIChldmVudCwgY29tcG9zZXIsIGNvbmZpZykgewogICAgICAgIHZhciBpc0N0cmwgPSBldmVudC5jdHJsS2V5LAogICAgICAgICAgICBpc0FsdCA9IGV2ZW50LmFsdEtleSwKICAgICAgICAgICAgaXNTaGlmdCA9IGV2ZW50LnNoaWZ0S2V5LAogICAgICAgICAgICB3aGljaCA9IGV2ZW50LndoaWNoOwogICAgICAgIGlmIChpc0N0cmwgJiYgaXNTaGlmdCkgewogICAgICAgICAgICB2YXIgZm9udFNpemUgPSBudWxsLAogICAgICAgICAgICAgICAgZm9udFNpemVPcHRpb25zID0gY29uZmlnLmZvbnRTaXplID8gY29uZmlnLmZvbnRTaXplLm9wdGlvbnMgOiBbXTsKICAgICAgICAgICAgaWYgKHdoaWNoID09IG5zLktleWJvYXJkLktFWUNPREVfR1JFQVRFUl9USEFOKSB7Ly8gQ3RybCArIFNoaWZ0ICsgPiB0byBJbmNyZWFzZSBmb250IHNpemUKICAgICAgICAgICAgICAgIGZvbnRTaXplID0gZ2V0Rm9udFNpemUodHJ1ZSwgY29tcG9zZXIsIGZvbnRTaXplT3B0aW9ucyk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAod2hpY2ggPT0gbnMuS2V5Ym9hcmQuS0VZQ09ERV9MRVNTX1RIQU4pIHsvLyBDdHJsICsgU2hpZnQgKyA8IHRvIERlY3JlYXNlIGZvbnQgc2l6ZQogICAgICAgICAgICAgICAgZm9udFNpemUgPSBnZXRGb250U2l6ZShmYWxzZSwgY29tcG9zZXIsIGZvbnRTaXplT3B0aW9ucyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGZvbnRTaXplKSB7CiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgY29tcG9zZXIuY29tbWFuZHMuZXhlYygiZm9udFNpemUiLCBmb250U2l6ZSwgZmFsc2UpOwogICAgICAgICAgICB9CiAgICAgICAgfSBpZiAoaXNDdHJsKSB7CiAgICAgICAgICAgIHZhciBjb21tYW5kID0gIiI7CiAgICAgICAgICAgIGlmIChpc0FsdCkgewogICAgICAgICAgICAgICAgaWYgKHdoaWNoID09IG5zLktleWJvYXJkLktFWUNPREVfQikgey8vIEN0cmwgKyBBbHQgKyBCIGZvciBCb2xkCiAgICAgICAgICAgICAgICAgICAgY29tbWFuZCA9ICJib2xkIjsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAod2hpY2ggPT0gbnMuS2V5Ym9hcmQuS0VZQ09ERV9JKSB7Ly8gQ3RybCArIEFsdCArIEkgZm9yIEl0YWxpYwogICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSAiaXRhbGljIjsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAod2hpY2ggPT0gbnMuS2V5Ym9hcmQuS0VZQ09ERV9VKSB7Ly8gQ3RybCArIEFsdCArIFUgZm9yIFVuZGVybGluZQogICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSAidW5kZXJsaW5lIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICh3aGljaCA9PSBucy5LZXlib2FyZC5LRVlDT0RFX0UpIHsvLyBDdHJsICsgRSBmb3IgQ2VudGVyLUFsaWduZWQgVGV4dAogICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSAianVzdGlmeUNlbnRlciI7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHdoaWNoID09IG5zLktleWJvYXJkLktFWUNPREVfTCkgey8vQ3RybCArIEwgZm9yIExlZnQtQWxpZ25lZCBUZXh0CiAgICAgICAgICAgICAgICAgICAgY29tbWFuZCA9ICJqdXN0aWZ5TGVmdCI7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHdoaWNoID09IG5zLktleWJvYXJkLktFWUNPREVfUikgey8vQ3RybCArIFIgZm9yIFJpZ2h0LUFsaWduZWQgVGV4dAogICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSAianVzdGlmeVJpZ2h0IjsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAod2hpY2ggPT0gbnMuS2V5Ym9hcmQuS0VZQ09ERV9KKSB7Ly9DdHJsICsgSiBmb3IgRnVsbHktSnVzdGlmaWVkIFRleHQKICAgICAgICAgICAgICAgICAgICBjb21tYW5kID0gImp1c3RpZnlGdWxsIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY29tbWFuZCAhPSAiIikgewogICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgIGNvbXBvc2VyLmNvbW1hbmRzLmV4ZWMoY29tbWFuZCwgdW5kZWZpbmVkLCB0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07Cgp9KShkb2N1bWVudCwgRm9ybS5ydGUpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTYuIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgooZnVuY3Rpb24gKGRvY3VtZW50LCAkLCBucykgewogICAgInVzZSBzdHJpY3QiOwoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBSaWNoIFRleHQgRWRpdG9yIHdoaWNoIHRha2VzIG9iamVjdCB3aXRoIGZvbGxvd2luZyBjb25maWd1cmF0aW9ucyA6CiAgICAgKiBTZWxlY3RvciA6IHNlbGVjdG9yIG9yIERPTSBlbGVtZW50IG9mIEVsZW1lbnQgZm9yIHdoaWNoIFJURSBuZWVkcyB0byBiZSBsaW5rZWQKICAgICAqIFRvb2xiYXIgOiBzZWxlY3RvciBvZiBUb29sYmFyIG9yIGNvbmZpZyB0byB1c2UgY3VzdG9tIFRvb2xiYXIKICAgICAqIGRhdGEgOiBIVE1MIHRvIGJlIHNldCB3aGlsZSBpbnN0YW50aWF0aW5nCiAgICAgKgogICAgICogQHR5cGUge1JpY2hUZXh0RWRpdG9yfQogICAgICovCiAgICB2YXIgUmljaFRleHRFZGl0b3IgPSBucy5SaWNoVGV4dEVkaXRvciA9IGZ1bmN0aW9uIChvcHRpb25zKSB7CgogICAgICAgIHZhciBzZWxlY3RvciA9IHR5cGVvZiBvcHRpb25zLnNlbGVjdG9yID09PSAic3RyaW5nIiA/IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG9wdGlvbnMuc2VsZWN0b3IpIDogb3B0aW9ucy5zZWxlY3RvcjsKICAgICAgICB2YXIgdG9vbGJhciA9IG9wdGlvbnMudG9vbGJhcjsKICAgICAgICBucy5JMThuLnNldExvY2FsZShvcHRpb25zLmxvY2FsZSk7CiAgICAgICAgdGhpcy5lZGl0b3JDb25maWcgPSAkLmV4dGVuZChucy5EZWZhdWx0Q29uZmlnLCBvcHRpb25zLmNvbmZpZyk7CgogICAgICAgIHZhciBpbnNlcnRBZnRlcjsKICAgICAgICB2YXIgcmljaFRleHRFZGl0b3IgPSAkKCI8ZGl2IGNsYXNzPSdmb3Jtcy1yaWNoVGV4dEVkaXRvcic+PC9kaXY+Iik7CiAgICAgICAgaWYgKCEodG9vbGJhciBpbnN0YW5jZW9mIEhUTUxFbGVtZW50IHx8IHR5cGVvZiB0b29sYmFyID09ICJzdHJpbmciKSkgewogICAgICAgICAgICAvKiBDcmVhdGUgb3V0IG9mIHRoZSBib3ggdG9vbGJhciBpcyBubyB0b29sYmFyIERPTSBlbGVtZW50IG9yIHNlbGVjdG9yIGlzIHByb3ZpZGVyKi8KICAgICAgICAgICAgdGhpcy50b29sYmFyID0gbmV3IG5zLlRvb2xiYXIodG9vbGJhciwgdGhpcy5lZGl0b3JDb25maWcpOwogICAgICAgICAgICB0aGlzLiR0b29sYmFyID0gdGhpcy50b29sYmFyLnJlbmRlcigpOwogICAgICAgICAgICBpbnNlcnRBZnRlciA9IHRvb2xiYXIgPSB0aGlzLiR0b29sYmFyWzBdOwogICAgICAgICAgICByaWNoVGV4dEVkaXRvci5hcHBlbmQodGhpcy4kdG9vbGJhcik7CiAgICAgICAgICAgIHJpY2hUZXh0RWRpdG9yLmFkZENsYXNzKCJydGUtbW9kZS0iICsgdGhpcy50b29sYmFyLmdldE1vZGUoKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW5zZXJ0QWZ0ZXIgPSAkKCI8ZGl2PjwvZGl2PiIpWzBdOwogICAgICAgICAgICByaWNoVGV4dEVkaXRvci5hcHBlbmQoaW5zZXJ0QWZ0ZXIpOwogICAgICAgIH0KCiAgICAgICAgcmljaFRleHRFZGl0b3IuaW5zZXJ0QWZ0ZXIoJChzZWxlY3RvcikpOwogICAgICAgIHRoaXMuJGVsZW1lbnQgPSByaWNoVGV4dEVkaXRvcjsKCiAgICAgICAgdmFyIHBhcnNlclJ1bGVzID0gd3lzaWh0bWw1U3VwcG9ydGVkUGFyc2VyUnVsZXM7CiAgICAgICAgaWYgKG9wdGlvbnMucGFyc2VyUnVsZXMpIHsKICAgICAgICAgICAgaWYgKG9wdGlvbnMucGFyc2VyUnVsZXMudGFncykgewogICAgICAgICAgICAgICAgcGFyc2VyUnVsZXMudGFncyA9ICQuZXh0ZW5kKHBhcnNlclJ1bGVzLnRhZ3MsIG9wdGlvbnMucGFyc2VyUnVsZXMudGFncyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG9wdGlvbnMucGFyc2VyUnVsZXMuY2xhc3NlcykgewogICAgICAgICAgICAgICAgcGFyc2VyUnVsZXMuY2xhc3NlcyA9ICQuZXh0ZW5kKHBhcnNlclJ1bGVzLmNsYXNzZXMsIG9wdGlvbnMucGFyc2VyUnVsZXMuY2xhc3Nlcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG9wdGlvbnMucGFyc2VyUnVsZXMuc3R5bGVzKSB7CiAgICAgICAgICAgICAgICBwYXJzZXJSdWxlcy5zdHlsZXMgPSBwYXJzZXJSdWxlcy5zdHlsZXMuY29uY2F0KG9wdGlvbnMucGFyc2VyUnVsZXMuc3R5bGVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAob3B0aW9ucy5wYXJzZXJSdWxlcy5wc2V1ZG9UYWdzKSB7CiAgICAgICAgICAgICAgICBwYXJzZXJSdWxlcy5wc2V1ZG9UYWdzID0gb3B0aW9ucy5wYXJzZXJSdWxlcy5wc2V1ZG9UYWdzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChvcHRpb25zLnBhcnNlclJ1bGVzLnRleHROb2RlcykgewogICAgICAgICAgICAgICAgcGFyc2VyUnVsZXMudGV4dE5vZGVzID0gb3B0aW9ucy5wYXJzZXJSdWxlcy50ZXh0Tm9kZXMubWFwKGZ1bmN0aW9uIChub2RlTmFtZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlTmFtZS50b1VwcGVyQ2FzZSgpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICh3aW5kb3cuaGFzT3duUHJvcGVydHkoInd5c2lodG1sNSIpICYmIHdpbmRvdy53eXNpaHRtbDUpIHsKICAgICAgICAgICAgaWYgKCF0aGlzLmVkaXRvcikgewogICAgICAgICAgICAgICAgdGhpcy5lZGl0b3IgPSBuZXcgd3lzaWh0bWw1LkVkaXRvcihzZWxlY3RvciwgewogICAgICAgICAgICAgICAgICAgIHRvb2xiYXIgOiB0b29sYmFyLAogICAgICAgICAgICAgICAgICAgIGluc2VydEFmdGVyIDogaW5zZXJ0QWZ0ZXIsCiAgICAgICAgICAgICAgICAgICAgdXNlTGluZUJyZWFrcyA6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIHBhc3RlQXNQbGFpblRleHQgOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBzdHlsZXNoZWV0cyA6IG9wdGlvbnMuY3NzUGF0aCwKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0Rm9udFNpemUgOiB0aGlzLmVkaXRvckNvbmZpZy5mb250U2l6ZS5kZWZhdWx0VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgcGFyc2VyUnVsZXMgOiBwYXJzZXJSdWxlcwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5lZGl0b3IuY29tcG9zZXIpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY29tcG9zZXIgPSB0aGlzLmVkaXRvci5jb21wb3NlciwKICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyID0gY29tcG9zZXIuY29udGFpbmVyLAogICAgICAgICAgICAgICAgICAgICAgICBkb2MgPSBjb21wb3Nlci5kb2MsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZyA9IHRoaXMuZWRpdG9yQ29uZmlnOwogICAgICAgICAgICAgICAgICAgIGlmIChjb250YWluZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgc3R5bGUgaW4gdGhpcy5lZGl0b3JDb25maWcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmVkaXRvckNvbmZpZy5oYXNPd25Qcm9wZXJ0eShzdHlsZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXIuc3R5bGVbc3R5bGVdID0gdGhpcy5lZGl0b3JDb25maWdbc3R5bGVdLmRlZmF1bHRWYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkKGRvYykub24oImtleWRvd24iLCBmdW5jdGlvbiAoZSkgewogICAgICAgICAgICAgICAgICAgICAgICBucy5TaG9ydGN1dEtleXNDdHJsLm9ua2V5ZG93bihlLCBjb21wb3NlciwgY29uZmlnKTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmRhdGEpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFJpY2hUZXh0RWRpdG9yQ29udGVudChvcHRpb25zLmRhdGEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGZpbmRBbmRSZXBsYWNlID0gdGhpcy5maW5kQW5kUmVwbGFjZSA9IG5ldyBucy5GaW5kQW5kUmVwbGFjZSh0aGlzKTsKICAgICAgICAgICAgICAgIFJpY2hUZXh0RWRpdG9yLmFkZENvbW1hbmQoImNoYW5nZUxpbmVIZWlnaHQiLCB7CiAgICAgICAgICAgICAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZE5hbWUsIHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHd5c2lodG1sNS51dGlsLmNoYW5nZUxpbmVIZWlnaHQodmFsdWUsIHRydWUsIG51bGwsIGNvbXBvc2VyLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHN0YXRlIDogd3lzaWh0bWw1LmNvbW1hbmRzLmxpbmVIZWlnaHQuc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tTdGF0ZSA6IHd5c2lodG1sNS5jb21tYW5kcy5saW5lSGVpZ2h0LmNhbGxiYWNrU3RhdGUKCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIFJpY2hUZXh0RWRpdG9yLmFkZENvbW1hbmQoImZpbmRBbmRSZXBsYWNlIiwgewogICAgICAgICAgICAgICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmluZEFuZFJlcGxhY2UubWVzc2FnZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIFJpY2hUZXh0RWRpdG9yLmFkZENvbW1hbmQoImZpbmQiLCB7CiAgICAgICAgICAgICAgICAgICAgZm9jdXMgOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kTmFtZSwgdmFsdWVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmRBbmRSZXBsYWNlLmV4ZWN1dGVGaW5kKHZhbHVlcy5maW5kVGV4dCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIFJpY2hUZXh0RWRpdG9yLmFkZENvbW1hbmQoInJlcGxhY2UiLCB7CiAgICAgICAgICAgICAgICAgICAgZm9jdXMgOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kTmFtZSwgdmFsdWVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmRBbmRSZXBsYWNlLmV4ZWN1dGVSZXBsYWNlKHZhbHVlcy5maW5kVGV4dCwgdmFsdWVzLnJlcGxhY2VUZXh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgUmljaFRleHRFZGl0b3IuYWRkQ29tbWFuZCgicmVwbGFjZUFsbCIsIHsKICAgICAgICAgICAgICAgICAgICBmb2N1cyA6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmROYW1lLCB2YWx1ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluZEFuZFJlcGxhY2UuZXhlY3V0ZVJlcGxhY2VBbGwodmFsdWVzLmZpbmRUZXh0LCB2YWx1ZXMucmVwbGFjZVRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBSaWNoVGV4dEVkaXRvci5hZGRDb21tYW5kKCJjaGFuZ2VGaW5kVGV4dCIsIHsKICAgICAgICAgICAgICAgICAgICBmb2N1cyA6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmROYW1lLCB2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5kQW5kUmVwbGFjZS5vbkZpbmRWYWx1ZUNoYW5nZSh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBSaWNoVGV4dEVkaXRvci5hZGRDb21tYW5kKCJjaGFuZ2VSZXBsYWNlVGV4dCIsIHsKICAgICAgICAgICAgICAgICAgICBmb2N1cyA6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmROYW1lLCB2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5kQW5kUmVwbGFjZS5vblJlcGxhY2VWYWx1ZUNoYW5nZSh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBSaWNoVGV4dEVkaXRvci5hZGRDb21tYW5kKCJjaGFuZ2VXaG9sZVdvcmQiLCB7CiAgICAgICAgICAgICAgICAgICAgZm9jdXMgOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kTmFtZSwgdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluZEFuZFJlcGxhY2Uub25TZWxlY3Rpb25DaGFuZ2UodW5kZWZpbmVkLCB2YWx1ZSwgdW5kZWZpbmVkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIFJpY2hUZXh0RWRpdG9yLmFkZENvbW1hbmQoImNoYW5nZU1hdGNoQ2FzZSIsIHsKICAgICAgICAgICAgICAgICAgICBmb2N1cyA6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmROYW1lLCB2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5kQW5kUmVwbGFjZS5vblNlbGVjdGlvbkNoYW5nZSh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBSaWNoVGV4dEVkaXRvci5hZGRDb21tYW5kKCJjaGFuZ2VSZWdFeHAiLCB7CiAgICAgICAgICAgICAgICAgICAgZm9jdXMgOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kTmFtZSwgdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluZEFuZFJlcGxhY2Uub25TZWxlY3Rpb25DaGFuZ2UodW5kZWZpbmVkLCB1bmRlZmluZWQsIHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLnRvb2xiYXIpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnRvb2xiYXIuaW5pdGlhbGl6ZVRvb2xiYXJFdmVudHModGhpcyk7CiAgICAgICAgICAgICAgICAgICAgJCh0aGlzLnRvb2xiYXIpLm9uKCJtb2RlQ2hhbmdlZCIsICQucHJveHkodGhpcy50b2dnbGVUb29sYmFyTW9kZSwgdGhpcykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIHsiY29tcG9zZXIiIDogeyJnZXQiIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gKHRoaXMuZWRpdG9yICYmIHRoaXMuZWRpdG9yLmNvbXBvc2VyKSA/IHRoaXMuZWRpdG9yLmNvbXBvc2VyIDogbnVsbDsKICAgICAgICB9fX0pOwogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIHsiY29udGFpbmVyIiA6IHsiZ2V0IiA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICh0aGlzLmVkaXRvciAmJiB0aGlzLmVkaXRvci5jb21wb3NlcikgPyB0aGlzLmVkaXRvci5jb21wb3Nlci5jb250YWluZXIgOiBudWxsOwogICAgICAgIH19fSk7CiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcywgeyJkb2MiIDogeyJnZXQiIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gZG9jdW1lbnQ7CiAgICAgICAgfX19KTsKICAgIH07CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBodG1sIHByb3ZpZGVkIHRvIHRoZSBSaWNoIFRleHQgRWRpdG9yCiAgICAgKiBAcGFyYW0gaHRtbERhdGEgSHRtbCB0byBiZSBpbnNlcnRlZAogICAgICovCiAgICBSaWNoVGV4dEVkaXRvci5wcm90b3R5cGUuc2V0UmljaFRleHRFZGl0b3JDb250ZW50ID0gZnVuY3Rpb24gKGh0bWxEYXRhKSB7CiAgICAgICAgaWYgKGh0bWxEYXRhICE9PSB0aGlzLmdldFJpY2hUZXh0RWRpdG9yQ29udGVudCgpKSB7CiAgICAgICAgICAgIGh0bWxEYXRhID0gaHRtbERhdGEgfHwgIiI7CiAgICAgICAgICAgIHZhciBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPGJyPjxcL2JyPicsICdnaScpOwogICAgICAgICAgICBodG1sRGF0YSA9IGh0bWxEYXRhLnJlcGxhY2UocGF0dGVybiwgIjxicj4iKTsKICAgICAgICAgICAgaWYgKGh0bWxEYXRhLmluZGV4T2YoIjxib2R5IikgPiAtMSkgewogICAgICAgICAgICAgICAgaHRtbERhdGEgPSBucy51dGlsLkh0bWxVdGlscy5leHRyYWN0Qm9keUNvbnRlbnQoaHRtbERhdGEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuZWRpdG9yLnNldFZhbHVlKGh0bWxEYXRhKTsKICAgICAgICAgICAgaWYgKHRoaXMuZWRpdG9yLmNvbXBvc2VyICYmIHRoaXMuZWRpdG9yLmNvbXBvc2VyLnVuZG9NYW5hZ2VyKSB7CiAgICAgICAgICAgICAgICB0aGlzLmVkaXRvci5jb21wb3Nlci51bmRvTWFuYWdlci5jbGVhckhpc3RvcnkoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBGZXRjaGVzIHRoZSBjdXJyZW50IGh0bWwgZnJvbSBSaWNoIFRleHQgRWRpdG9yCiAgICAgKiBAcmV0dXJucyBodG1sIGZyb20gUmljaCBUZXh0IEVkaXRvcgogICAgICovCiAgICBSaWNoVGV4dEVkaXRvci5wcm90b3R5cGUuZ2V0UmljaFRleHRFZGl0b3JDb250ZW50ID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBodG1sID0gbnMudXRpbC5IdG1sVXRpbHMucmljaFRleHRFZGl0b3JUb0h0bWwodGhpcy5lZGl0b3IuZ2V0VmFsdWUoKSwgdGhpcy5lZGl0b3JDb25maWcpOwogICAgICAgIHJldHVybiBucy51dGlsLkh0bWxVdGlscy53cmFwSW5Cb2R5KGh0bWwpOwogICAgfTsKCiAgICAvKioKICAgICAqIEV4ZWN1dGVzIGNvbW1hbmQoYm9sZCxpdGFsaWNzLGV0Yykgb24gdGhlIEVkaXRvcgogICAgICogQHBhcmFtIGNvbW1hbmQgTmFtZSBvZiB0aGUgY29tbWFuZAogICAgICogQHBhcmFtIHZhbHVlIHZhbHVlIGZvciB0aGUgY29tbWFuZAogICAgICogQHBhcmFtIGFsbG93VW5kbyB3aGV0aGVyIHVuZG8gdG8gYmUgZW5hYmxlZCBmb3IgdGhlIGNvbW1hbmQgb3Igbm90CiAgICAgKi8KICAgIFJpY2hUZXh0RWRpdG9yLnByb3RvdHlwZS5leGVjdXRlQ29tbWFuZCA9IGZ1bmN0aW9uIChjb21tYW5kLCB2YWx1ZSwgYWxsb3dVbmRvKSB7CiAgICAgICAgaWYgKGFyZ3VtZW50cyAmJiBhcmd1bWVudHMubGVuZ3RoID4gMCkgewogICAgICAgICAgICBpZiAodGhpcy5lZGl0b3IgJiYgdGhpcy5lZGl0b3IuY29tcG9zZXIpIHsKICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yLmNvbXBvc2VyLmNvbW1hbmRzLmV4ZWMuYXBwbHkodGhpcywgYXJndW1lbnRzLCBhbGxvd1VuZG8pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgd2luZG93LmNvbnNvbGUuZXJyb3IoIlVuYWJsZSB0byBmaW5kIHRoZSBFZGl0b3IgaW5zdGFuY2UiKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHdpbmRvdy5jb25zb2xlLmVycm9yKCJJbnZhbGlkIGNvbW1hbmQgIik7CiAgICAgICAgfQogICAgfTsKCiAgICAvKioKICAgICAqIENoYW5nZXMgdGhlIHRvb2xiYXIgbW9kZQogICAgICogQHBhcmFtIGUgVG9vbGJhciBtb2RlIGNoYW5nZSBFdmVudAogICAgICogQHBhcmFtIG1vZGUgTW9kZSBmb3IgdGhlIHRvb2xiYXIgdG8gYmUgZW5hYmxlZAogICAgICovCiAgICBSaWNoVGV4dEVkaXRvci5wcm90b3R5cGUudG9nZ2xlVG9vbGJhck1vZGUgPSBmdW5jdGlvbiAoZSwgbW9kZSkgewogICAgICAgIHRoaXMuJGVsZW1lbnQucmVtb3ZlQ2xhc3MoInJ0ZS1tb2RlLSIgKyB0aGlzLnRvb2xiYXIuZ2V0TW9kZSgpKTsKICAgICAgICBpZiAodGhpcy4kdG9vbGJhcikgewogICAgICAgICAgICAkKHRoaXMudG9vbGJhcikub2ZmKCJtb2RlQ2hhbmdlZCIpOwogICAgICAgICAgICB0aGlzLiR0b29sYmFyLmRldGFjaCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLiR0b29sYmFyID0gdGhpcy50b29sYmFyLnNldE1vZGUobW9kZSk7CiAgICAgICAgdGhpcy4kZWxlbWVudC5wcmVwZW5kKHRoaXMuJHRvb2xiYXIpOwogICAgICAgIHRoaXMuJGVsZW1lbnQuYWRkQ2xhc3MoInJ0ZS1tb2RlLSIgKyB0aGlzLnRvb2xiYXIuZ2V0TW9kZSgpKTsKICAgICAgICB0aGlzLmVkaXRvci5zZXRUb29sYmFyKHRoaXMuJHRvb2xiYXJbMF0pOwogICAgICAgIHRoaXMudG9vbGJhci5pbml0aWFsaXplVG9vbGJhckV2ZW50cyh0aGlzKTsKICAgICAgICAkKHRoaXMudG9vbGJhcikub24oIm1vZGVDaGFuZ2VkIiwgJC5wcm94eSh0aGlzLnRvZ2dsZVRvb2xiYXJNb2RlLCB0aGlzKSk7CiAgICB9OwoKICAgIFJpY2hUZXh0RWRpdG9yLmFkZENvbW1hbmQgPSBmdW5jdGlvbiAoY29tbWFuZE5hbWUsIG9wdGlvbnMpIHsKICAgICAgICB3eXNpaHRtbDUuY29tbWFuZHNbY29tbWFuZE5hbWVdID0gb3B0aW9uczsKICAgIH07Cgp9KShkb2N1bWVudCwgJCwgRm9ybS5ydGUpOwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX18KICoKICogIENvcHlyaWdodCAyMDE2IEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiBzdXBwbGllcnMgYW5kIG1heSBiZSBjb3ZlcmVkIGJ5IFUuUy4gYW5kIEZvcmVpZ24gUGF0ZW50cywKICogcGF0ZW50cyBpbiBwcm9jZXNzLCBhbmQgYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCndpbmRvdy54ZmFsaWIuJCA9IHdpbmRvdy4kOwp3aW5kb3cueGZhbGliLmpRdWVyeSA9IHdpbmRvdy5qUXVlcnk7CndpbmRvdy54ZmFsaWIuXyA9IHdpbmRvdy5fOwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgIENvcHlyaWdodCAyMDEzIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCjsoZnVuY3Rpb24gKCQpIHsKICAgIC8qCiAgICAgKiBGb3JtIEJyaWRnZSBBUEkKICAgICAqIFRoZSBBUEkgcHJvdmlkZXMgYSBtZXRob2QgZm9yIGV4dGVybmFsIGFwcGxpY2F0aW9ucyB0byBjb25uZWN0IHdpdGggWGZhIGFuZCBmb3JtRG9tLiBUaGUgQVBJcyBhcmUgZGl2aWRlZCBpbnRvIHR3byBjYXRlZ29yaWVzLCBzeW5jaHJvbm91cyBhbmQgYXN5bmNocm9ub3VzLgogICAgICoKICAgICAqIEFsbCB0aGUgQVBJcyB0aGF0IGFyZSBpbnRlcm5hbCB0byB1cyBtdXN0IGdvIGludG8gRm9ybUJyaWRnZUludGVybmFsLmpzIGFuZCBub3QgaGVyZQogICAgICoKICAgICAqIEVhY2ggU3luY2hyb25vdXMgZ2V0dGVyIEFQSSByZXR1cm5zIGEgWEZBUmVzdWx0T2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgQVBJIHdoZXJlYXMgZWFjaCBzZXR0ZXIgQVBJIHRocm93cyBhbiBleGNlcHRpb24gaW4gY2FzZSBvZiBlcnJvciBhbmQKICAgICAqIGl0IGlzIHRoZSByZXNwb25zaWJpbGl0eSBvZiB0aGUgQVBJIHRvIGNhdGNoIHRob3NlIGV4Y2VwdGlvbnMuIFRoZSBYRkFSZXN1bHRPYmplY3QgZWl0aGVyIGNvbnRhaW5zIGVycm9yIG9yIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIEFQSSBhbmQgcHJvdmlkZXMgZWFzeQogICAgICogbWVjaGFuaXNtIHRvIGFjY2VzcyBlYWNoIG9mIHRoZW0uCiAgICAgKgogICAgICogRWFjaCBBc3luY2hyb25vdXMgQVBJIHByb3ZpZGVzIGNhbGxiYWNrIG1lY2hhbmlzbSB0byByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgQVBJLiBFYWNoIEFQSSB0YWtlcyBhIEphdmFzY3JpcHQgT2JqZWN0IGNvbnRhaW5pbmcgZXJyb3IsIHN1Y2Nlc3MgSGFuZGxlcnMgYW5kIGEKICAgICAqIGNvbnRleHQgaW4gd2hpY2ggdG8gaW52b2tlIHRob3NlIGZ1bmN0aW9ucy4gVGhlIHN5bnRheCBvZiB0aGUgb2JqZWN0IGlzCiAgICAgKiB7IGVycm9yOiBlcnJvckhhbmRsZXJGdW5jLAogICAgICogICBzdWNjZXNzOiBzdWNjZXNzSGFuZGxlckZ1bmMsCiAgICAgKiAgIGNvbnRleHQ6IE9iamVjdENvbnRleHQKICAgICAqIH0KICAgICAqIFRoZSBzaWduYXR1cmUgb2YgdGhlIGZ1bmN0aW9ucyBpcwogICAgICogZnVuY3Rpb24oWEZBUmVzdWx0T2JqZWN0KSB7CiAgICAgKgogICAgICogIH0KICAgICAqIEVhY2ggb2YgdGhlIGZ1bmN0aW9ucyBpcyBwYXNzZWQgYSBYRkFSZXN1bHRPYmplY3QgY29udGFpbmluZyBlaXRoZXIgdGhlIGRhdGEgb2YgdGhlIG9wZXJhdGlvbiBvciB0aGUgZXJyb3JzLgogICAgICoKICAgICAqLwoKICAgIEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgfHwgZnVuY3Rpb24gKGN0eCkgewogICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGF0LmNhbGwoY3R4LCBhcmd1bWVudHMpOwogICAgICAgIH0KICAgIH07CgogICAgLyogcHVibGljIGludGVyZmFjZSBYRkFSZXN1bHRPYmplY3QKICAgICBwdWJsaWMgc3RyaW5nW10gbWVzc2FnZSAgICAgICAgICAvLyBlcnJvciBtZXNzYWdlcwogICAgIHB1YmxpYyBzdHJpbmdbXSBzb21FeHByZXNzaW9uICAgIC8vIHNvbUV4cHJlc3Npb25zIHRoYXQgY2F1c2VkIHRoZSBlcnJvcnMKICAgICBwdWJsaWMgc3RyaW5nW10gZXJyb3JDb2RlICAgICAgICAvLyBpbnRlcm5hbAogICAgIHB1YmxpYyBib29sIGVycm9ycyAgICAgICAgICAgICAgIC8vIHdoZXRoZXIgdGhlIHJlc3VsdCBvYmplY3QgaGFzIGVycm9ycyBvciBub3QKICAgICBwdWJsaWMgT2JqZWN0IGRhdGEgICAgICAgICAgICAgICAvLyBkYXRhIHJldHVybmVkIGJ5IHRoZSBmdW5jdGlvbgoKICAgICBwdWJsaWMgZ2V0TmV4dE1lc3NhZ2UgICAgICAgICAgICAvLyByZXR1cm5zIGEgbWVzc2FnZSBPYmplY3Qge2NvZGUsc29tRXhwcmVzc2lvbixtZXNzYWdlfSBvciBudWxsIGlmIG5vIGVycm9yIG1lc3NhZ2UgaXMgcHJlc2VudAogICAgICovCiAgICB2YXIgWEZBUmVzdWx0T2JqZWN0ID0gZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIF9tZXNzYWdlID0gW10sCiAgICAgICAgICAgIF9lcnJvckNvZGUgPSBbXSwKICAgICAgICAgICAgX3NvbUV4cHJlc3Npb24gPSBbXTsKICAgICAgICB0aGlzLmVycm9ycyA9IGZhbHNlOwoKICAgICAgICB0aGlzLmFkZE1lc3NhZ2UgPSBmdW5jdGlvbiAoY29kZSwgbXNnLCBzb20pIHsKICAgICAgICAgICAgdGhpcy5lcnJvcnMgPSB0cnVlOwogICAgICAgICAgICBfbWVzc2FnZS5wdXNoKG1zZyk7CiAgICAgICAgICAgIF9zb21FeHByZXNzaW9uLnB1c2goc29tKTsKICAgICAgICAgICAgX2Vycm9yQ29kZS5wdXNoKGNvZGUpOwogICAgICAgIH07CgogICAgICAgIHRoaXMuZ2V0TmV4dE1lc3NhZ2UgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmIChfZXJyb3JDb2RlLmxlbmd0aCA9PSAwKQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICBjb2RlOiBfZXJyb3JDb2RlLnBvcCgpLAogICAgICAgICAgICAgICAgc29tRXhwcmVzc2lvbjogX3NvbUV4cHJlc3Npb24ucG9wKCksCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBfbWVzc2FnZS5wb3AoKQogICAgICAgICAgICB9OwogICAgICAgIH07CiAgICB9OwoKICAgIHZhciBGT1JNX0JSSURHRV9WRVJTSU9OID0gIjguMS4xNiI7CiAgICB2YXIgRm9ybUJyaWRnZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLl94ZmEgPSBudWxsOwogICAgICAgIHRoaXMuX3ZlcnNpb24gPSBGT1JNX0JSSURHRV9WRVJTSU9OOwogICAgICAgIHRoaXMuX3hmYUluaXRIYW5kbGVyID0ge307CiAgICAgICAgdGhpcy5fJHRhcmdldCA9IG51bGw7CiAgICAgICAgdGhpcy5pc0FuYWx5dGljc0VuYWJsZWQgPSBmYWxzZTsKICAgICAgICAkKHdpbmRvdykub24oIlhmYUluaXRpYWxpemVkIiwgdGhpcy5feGZhSW5pdGlhbGl6ZWQuYmluZCh0aGlzKSk7CiAgICAgICAgJCh3aW5kb3cpLm9uKCJYZmFJbml0aWFsaXphdGlvbkVycm9yIiwgdGhpcy5feGZhRXJyb3IpOwogICAgICAgIHRoaXMuX2Zvcm1Eb2MgPSB3aW5kb3cuZG9jdW1lbnQ7CiAgICAgICAgdGhpcy51c2VyQ29uZmlnID0ge307CiAgICAgICAgLy8gaW5kaWNhdGVzIGlmIGFqYXggY2FsbCBpcyBleGVjdXRlZCBpbiBjbGllbnQgb3Igc2VydmVyCiAgICAgICAgLy8gbm90ZTogdGhpcyBzaG91bGQgbm90IGJlIG1vZGlmaWVkIGluIGNsaWVudAogICAgICAgIHRoaXMuYWpheENhbGxNb2RlID0gImNsaWVudCI7CiAgICAgICAgdGhpcy5fUFJPRklMRV9SRVNPVVJDRV9QQVRIID0gIi9jb250ZW50L3hmYWZvcm1zL3Byb2ZpbGVzL2RlZmF1bHQiOwogICAgfTsKCiAgICAvKgogICAgICogRGVmYXVsdCBlcnJvciBoYW5kbGVyIGZvciBmdW5jdGlvbnMgaW4gY2FzZSBub25lIGlzIHByb3ZpZGVkIGJ5IHRoZSBjYWxsZXIKICAgICAqIFRPRE8gOiBtYWtlIHRoZSBzdHJpbmcgbG9jYWxpemVkIGFuZCBjYWxsIHRoZSB4ZmEgTG9nZ2VyCiAgICAgKi8KICAgIHZhciBkZWZhdWx0RXJyb3JIYW5kbGVyID0gZnVuY3Rpb24gKG9iaikgewogICAgICAgIGlmICh0eXBlb2YoY29uc29sZSkgPT0gInVuZGVmaW5lZCIpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB2YXIgZCA9IG51bGw7CiAgICAgICAgd2hpbGUgKGQgPSBvYmouZ2V0TmV4dE1lc3NhZ2UoKSkKICAgICAgICAgICAgY29uc29sZS5lcnJvcihkLm1lc3NhZ2UpOwogICAgfTsKCiAgICB2YXIgX2lzRmlyc3RUZW1wU3RvcmFnZUNyZWF0aW9uUGVuZGluZyA9IGZhbHNlLAogICAgICAgIFRFTVBfU1RPUkFHRV9QQVRIID0gIi90bXAvZmQveGZhZm9ybXMiOwogICAgdmFyIGNyZWF0ZVVVSURTdG9yYWdlICA9IGZ1bmN0aW9uKHV1aWQpewogICAgICAgIGlmKCFmb3JtQnJpZGdlLl9pc0xvZ2luQW5vbnltb3VzKCkpIHsKICAgICAgICAgICAgdmFyIHN1Y2Nlc3NGbGFnID0gdHJ1ZTsKICAgICAgICAgICAgJC5hamF4KHsKICAgICAgICAgICAgdXJsOiBmb3JtQnJpZGdlLl9nZXRQYXRoVXJsKCIuZmQudGVtcHN0b3JhZ2Vwcm92aWRlci5qc3AiKSwKICAgICAgICAgICAgICAgIHR5cGU6ICJQT1NUIiwKICAgICAgICAgICAgICAgIGFzeW5jOiBmYWxzZSwKICAgICAgICAgICAgICAgIGRhdGE6IHsidXVpZFBhdGgiOiBURU1QX1NUT1JBR0VfUEFUSCArICIvIiArIHV1aWR9LAogICAgICAgICAgICAgICAgZXJyb3IgOiBmdW5jdGlvbiAobWVzc2FnZSkgewogICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NGbGFnID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICByZXR1cm4gc3VjY2Vzc0ZsYWc7CiAgICAgICAgfQoKICAgIH07CgogICAgLyoKICAgICAqIERlZmF1bHQgZnVuY3Rpb24gdG8gY2hlY2sgVmFsaWRhdGlvbnMgZXJyb3JzIGFmdGVyIGdldHRpbmcgdGhlIGRhdGEgZnJvbSB0aGUKICAgICAqIHNlcnZlciB3aXRoIGdldERhdGFYTUwgY2FsbC4KICAgICAqLwogICAgdmFyIGRlZmF1bHRWYWxpZGF0aW9uQ2hlY2tlciA9IGZ1bmN0aW9uICh2YWxpZGF0aW9ucywgb2JqKSB7CiAgICAgICAgaWYgKHZhbGlkYXRpb25zICYmIHZhbGlkYXRpb25zLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWxpZGF0aW9ucy5sZW5ndGg7IGkrKykKICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDAsIHZhbGlkYXRpb25zW2ldLCAiIik7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9OwoKICAgICQuZXh0ZW5kKEZvcm1CcmlkZ2UucHJvdG90eXBlLCB7CiAgICAgICAgLyoKICAgICAgICAgKiBSZXR1cm5zIHdoZXRoZXIgRm9ybSBEb20gaXMgaW5pdGlhbGl6ZWQgb3Igbm90LgogICAgICAgICAqLwogICAgICAgIGlzQ29ubmVjdGVkOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMuX3hmYTsKICAgICAgICB9LAogICAgICAgIC8qCiAgICAgICAgICogQHB1YmxpYwogICAgICAgICAqIFNwZWNpZnkgYSBmdW5jdGlvbiB0byBleGVjdXRlIGFmdGVyIG1ha2luZyBhIGNvbm5lY3Rpb24gd2l0aCBGb3JtQnJpZGdlCiAgICAgICAgICogaGFuZGxlcjogaGFuZGxlciB0byBleGVjdXRlCiAgICAgICAgICogY29udGV4dDogdmFyaWFibGUgJ3RoaXMnIHdpbGwgcmVmZXIgdG8gY29udGV4dCBpbiB0aGUgaGFuZGxlci4KICAgICAgICAgKi8KICAgICAgICBjb25uZWN0OiBmdW5jdGlvbiAoaGFuZGxlciwgY29udGV4dCkgewogICAgICAgICAgICBjb250ZXh0ID0gY29udGV4dCB8fCBmb3JtQnJpZGdlOwogICAgICAgICAgICBpZiAodGhpcy5pc0Nvbm5lY3RlZCgpKQogICAgICAgICAgICAgICAgaGFuZGxlci5jYWxsKGNvbnRleHQpOwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMuX3hmYUluaXRIYW5kbGVyLmhhbmRsZXIgPSB0aGlzLl94ZmFJbml0SGFuZGxlci5oYW5kbGVyIHx8IFtdOwogICAgICAgICAgICAgICAgdGhpcy5feGZhSW5pdEhhbmRsZXIuaGFuZGxlci5wdXNoKGhhbmRsZXIpOwogICAgICAgICAgICAgICAgdGhpcy5feGZhSW5pdEhhbmRsZXIuY29udGV4dCA9IHRoaXMuX3hmYUluaXRIYW5kbGVyLmNvbnRleHQgfHwgW107CiAgICAgICAgICAgICAgICB0aGlzLl94ZmFJbml0SGFuZGxlci5jb250ZXh0LnB1c2goY29udGV4dCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIC8qCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBIYW5kbGVyIGZvciBYZmFJbml0aWFsaXplZCBldmVudCB3aGljaCBpcyBmaXJlZCBieSBYRkEgbGlicmFyeSBhZnRlciBGb3JtIERvbSBpcyBpbml0aWFsaXplZAogICAgICAgICAqLwogICAgICAgIF94ZmFJbml0aWFsaXplZDogZnVuY3Rpb24gKGUpIHsKICAgICAgICAgICAgdGhpcy5feGZhID0geGZhbGliLnJ1bnRpbWUueGZhOwogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwogICAgICAgICAgICBpZiAodGhpcy5zdG9yYWdlKSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdG9yYWdlLmZvcm1TdGF0ZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYS5ob3N0LnBsYXlKc29uKEpTT04ucGFyc2UodGhpcy5zdG9yYWdlLmZvcm1TdGF0ZS54ZmFEb20pKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2Uuc3VjY2Vzcy5jYWxsKHRoaXMuc3RvcmFnZS5jb250ZXh0KTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UgPSBudWxsOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnN0b3JhZ2Uuc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5zdWNjZXNzLmNhbGwodGhpcy5zdG9yYWdlLmNvbnRleHQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHRoaXMueG1sU3RvcmFnZSAmJiB0aGlzLnhtbFN0b3JhZ2UueG1sRG9jdW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEuTG9nZ2VyLmRlYnVnKCJ4ZmEiLCAiUmVzdG9yaW5nIERhdGEgWE1MIGFmdGVyIGluaXRpYWlsemF0aW9uIik7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYS5ob3N0LnBsYXlEYXRhWG1sKHRoaXMueG1sU3RvcmFnZS54bWxEb2N1bWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMueG1sU3RvcmFnZS5zdWNjZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnhtbFN0b3JhZ2Uuc3VjY2Vzcy5jYWxsKHRoaXMueG1sU3RvcmFnZS5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMueG1sU3RvcmFnZS5lcnJvcikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMiwgIlVuZXhwZWN0ZWQgRXhjZXB0aW9uOiBVbmFibGUgdG8gcGxheSBEYXRhIFhNTCAiICsgZSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnhtbFN0b3JhZ2UuZXJyb3IuY2FsbCh0aGlzLnhtbFN0b3JhZ2UuY29udGV4dCwgb2JqKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy54bWxTdG9yYWdlICYmIHRoaXMueG1sU3RvcmFnZS5zdWNjZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy54bWxTdG9yYWdlLnN1Y2Nlc3MuY2FsbCh0aGlzLnhtbFN0b3JhZ2UuY29udGV4dCwgb2JqKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMueG1sU3RvcmFnZSA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRoaXMuX3hmYUluaXRIYW5kbGVyLmhhbmRsZXIpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5feGZhSW5pdEhhbmRsZXIuaGFuZGxlci5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYUluaXRIYW5kbGVyLmhhbmRsZXJbaV0uY2FsbCh0aGlzLl94ZmFJbml0SGFuZGxlci5jb250ZXh0W2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX3hmYUluaXRIYW5kbGVyID0ge307CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIEBwdWJsaWMKICAgICAgICAgKiBTcGVjaWZ5IGEgZnVuY3Rpb24gdG8gZGVjaWRlIHdoZXRoZXIgdGhlIGFuYWx5dGljcyB3aWxsIGJlIGVuYWJsZWQgb3IgZGlzYWJsZWQKICAgICAgICAgKiBwdWJsaWMgQm9vbGVhbiBpc0FuYWx5dGljc0VuYWJsZWQ6IHRoaXMgYXJndW1lbnQgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBhbmFseXRpY3Mgd2lsbCBiZSBlbmFibGVkIG9yIG5vdAogICAgICAgICAqLwogICAgICAgIGVuYWJsZUFuYWx5dGljczogZnVuY3Rpb24oc3RhdGUpewogICAgICAgICAgICB0aGlzLmlzQW5hbHl0aWNzRW5hYmxlZCA9IHN0YXRlOwogICAgICAgIH0sCgogICAgICAgIF94ZmFFcnJvcjogZnVuY3Rpb24gKGUpIHsKICAgICAgICAgICAgdGhpcy5feGZhID0gd2luZG93LnhmYTsKICAgICAgICAgICAgdmFyIG9iaiA9IG5ldyBYRkFSZXN1bHRPYmplY3QoKTsKICAgICAgICAgICAgLy8gc2luY2UgdGhlcmUgaXMgeGZhIGluaXQgZXJyb3IsIHdoeSBzaG91bGQgd2UgY2FsbCBwbGF5SnNvbgogICAgICAgICAgICBpZiAodGhpcy5zdG9yYWdlLmZvcm1TdGF0ZSkgewogICAgICAgICAgICAgICAgdGhpcy5feGZhLmhvc3QucGxheUpzb24oSlNPTi5wYXJzZSh0aGlzLnN0b3JhZ2UuZm9ybVN0YXRlLnhmYURvbSkpOwogICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlID0gbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0b3JhZ2UuZXJyb3IpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLmVycm9yLmNhbGwodGhpcy5zdG9yYWdlLmNvbnRleHQsIGUubWVzc2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRoaXMueG1sU3RvcmFnZS5lcnJvcikgewogICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMiwgZS5tZXNzYWdlLCBudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMueG1sU3RvcmFnZS5lcnJvci5jYWxsKHRoaXMueG1sU3RvcmFnZS5jb250ZXh0LCBvYmopOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldFJlc3VsdE9iamVjdDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgWEZBUmVzdWx0T2JqZWN0KCk7CiAgICAgICAgfSwKCiAgICAgICAgX2NoZWNrWGZhOiBmdW5jdGlvbiAob2JqKSB7CiAgICAgICAgICAgIGlmICghdGhpcy5feGZhKSB7CiAgICAgICAgICAgICAgICBvYmouYWRkTWVzc2FnZSgxLCAiWGZhIERvbSBub3QgSW5pdGlhbGl6ZWQiLCAiIik7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSwKICAgICAgICAvKgogICAgICAgICAqIHJldHVybnMgdGhlIHZlcnNpb24gb2YgbGlicmFyeQogICAgICAgICAqLwogICAgICAgIGdldEJyaWRnZVZlcnNpb246IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZlcnNpb247CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBSZWdpc3RlcnMgdXNlci9wb3J0YWwgc3BlY2lmaWMgY29uZmlndXJhdGlvbnMgdG8gRm9ybUJyaWRnZS4KICAgICAgICAgKiBDdXJyZW50bHkgc3VwcG9ydGVkIGNvbmZpZ3VyYXRpb25zIGFyZToKICAgICAgICAgKiB7d2lkZ2V0Q29uZmlnIDoge3NlbGVjdG9yOiBqcVdpZGdldE5hbWV9fQogICAgICAgICAqIHtwYWdpbmdDb25maWcgOiB7cGFnaW5nRW5hYmxlZDogdHJ1ZX19CiAgICAgICAgICoge0xvZ2dlckNvbmZpZyA6IHt7Im9uIjoidHJ1ZSIsICJjYXRlZ29yeSI6InhmYSIsICJsZXZlbCI6IjUiLCAidHlwZSI6ImNvbnNvbGUifX0KICAgICAgICAgKiB7cG9zdEV4dGVybmFsTWVzc2FnZUNvbmZpZyA6IHtwb3N0RXh0ZXJuYWxIYW5kbGVyOiBmbn19CiAgICAgICAgICoge2NvbnRleHRQYXRoIDogY29udGV4dFBhdGh9CiAgICAgICAgICoge3ZpZXdwb3J0V2lkdGggOiA8MTAwMD59CiAgICAgICAgICogZS5nLjogZm9ybUJyaWRnZS5yZWdpc3RlckNvbmZpZygid2lkZ2V0Q29uZmlnIiwgeyIuaW1hZ2VmaWVsZCIgOiAic2lnSW1hZ2VGaWVsZCJ9KTsKICAgICAgICAgKgogICAgICAgICAqIHJldHVybnMgYSBYRkFSZXN1bHRPYmplY3QuIE9sZCBjb25maWcgYWdhaW5zdCBzYW1lIGtleSBpcyBzdG9yZWQgaW4gb2JqLmRhdGFbMF0KICAgICAgICAgKi8KICAgICAgICByZWdpc3RlckNvbmZpZzogZnVuY3Rpb24gKGtleSwgY29uZmlnKSB7CiAgICAgICAgICAgIHZhciBvYmogPSBuZXcgWEZBUmVzdWx0T2JqZWN0KCk7CiAgICAgICAgICAgIG9iai5kYXRhID0gdGhpcy51c2VyQ29uZmlnW2tleV07CiAgICAgICAgICAgIHRoaXMudXNlckNvbmZpZ1trZXldID0gY29uZmlnOwogICAgICAgICAgICBvYmouY29tcGxldGVkID0gdHJ1ZTsKICAgICAgICAgICAgcmV0dXJuIG9iajsKICAgICAgICB9LAoKCiAgICAgICAgLyoKICAgICAgICAgKiBSZXR1cm5zIHRoZSBwYWdpbmdNYW5hZ2VyIGhhbmRsZSBmb3IgdGhlIGN1cnJlbnQgeGZhIHZpZXcuCiAgICAgICAgICogU2hvdWxkIGJlIGNhbGxlZCBhZnRlciBGb3JtQnJpZGdlIGlzIGluIGNvbm5lY3RlZCBtb2RlIGVsc2UgcGFnaW5NYW5hZ2VyIGhhbmRsZSB3b3VsZCBiZSBudWxsCiAgICAgICAgICovCiAgICAgICAgcGFnaW5nTWFuYWdlcjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBpZiAodGhpcy5feGZhICYmIHRoaXMuX3hmYS5ob3N0KQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3hmYS5ob3N0LnBhZ2luZ01hbmFnZXI7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogaGlkZSB0aGUgZmllbGRzIHdob3NlIHNvbSBpcyBwcm92aWRlZCBpbiB0aGUgZmllbGRBcnJheQogICAgICAgICAqIGZpZWxkQXJyYXk6IGFycmF5IG9mIHNvbUV4cHJlc3Npb25zCiAgICAgICAgICovCiAgICAgICAgaGlkZUZpZWxkczogZnVuY3Rpb24gKGZpZWxkQXJyYXkpIHsKICAgICAgICAgICAgdGhpcy5zZXRGaWVsZFByb3BlcnRpZXMoZmllbGRBcnJheSwgInByZXNlbmNlIiwgImludmlzaWJsZSIpOwogICAgICAgIH0sCiAgICAgICAgLyoKICAgICAgICAgKiBNYWtlIHRoZSBmaWVsZHMsIHdob3NlIHNvbSBpcyBwcm92aWRlZCBpbiB0aGUgZmllbGRBcnJheSwgdmlzaWJsZQogICAgICAgICAqIGZpZWxkQXJyYXk6IGFycmF5IG9mIHNvbUV4cHJlc3Npb25zCiAgICAgICAgICovCiAgICAgICAgc2hvd0ZpZWxkczogZnVuY3Rpb24gKGZpZWxkQXJyYXkpIHsKICAgICAgICAgICAgdGhpcy5zZXRGaWVsZFByb3BlcnRpZXMoZmllbGRBcnJheSwgInByZXNlbmNlIiwgInZpc2libGUiKTsKICAgICAgICB9LAogICAgICAgIC8qCiAgICAgICAgICogc2V0IHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQuIFRocm93cyBhbiBleGNlcHRpb24gaWYgdGhlIHNvbUV4cHJlc3Npb24gaXMgaW5jb3JyZWN0CiAgICAgICAgICogZmllbGQ6IHNvbUV4cHJlc3Npb25zIG9mIHRoZSBmaWVsZAogICAgICAgICAqLwogICAgICAgIHNldEZpZWxkVmFsdWU6IGZ1bmN0aW9uIChmaWVsZCwgdmFsdWUpIHsKICAgICAgICAgICAgdGhpcy5zZXRGaWVsZFByb3BlcnRpZXMoZmllbGQsICJyYXdWYWx1ZSIsIHZhbHVlKTsKICAgICAgICB9LAogICAgICAgIC8qCiAgICAgICAgICogZ2V0IHRoZSB2YWx1ZSBvZiB0aGUgZmllbGRzLCB3aG9zZSBzb20gaXMgcHJvdmlkZWQgaW4gdGhlIGZpZWxkQXJyYXkKICAgICAgICAgKiBmaWVsZEFycmF5OiBhcnJheSBvZiBzb21FeHByZXNzaW9ucwogICAgICAgICAqCiAgICAgICAgICogcmV0dXJucyBhIFhGQVJlc3VsdE9iamVjdC4gVGhlIHJlc3VsdCBpcyBzdG9yZWQgaW4gb2JqLmRhdGFbMF0KICAgICAgICAgKi8KICAgICAgICBnZXRGaWVsZFZhbHVlOiBmdW5jdGlvbiAoZmllbGQpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RmllbGRQcm9wZXJ0aWVzKGZpZWxkLCAicmF3VmFsdWUiKTsKICAgICAgICB9LAogICAgICAgIC8qCiAgICAgICAgICogc2V0IHRoZSBwcm9wZXJ0eSBvZiB0aGUgZmllbGRzLCB3aG9zZSBzb20gaXMgcHJvdmlkZWQgaW4gdGhlIGZpZWxkQXJyYXksIHdpdGggdGhlIHZhbHVlcyBwcm92aWRlZAogICAgICAgICAqIGZpZWxkQXJyYXk6IGFycmF5IG9mIHNvbUV4cHJlc3Npb25zCiAgICAgICAgICogcHJvcDogcHJvcGVydHkgdG8gc2V0CiAgICAgICAgICogdmFsdWVzOiBhcnJheSBvZiB2YWx1ZXMuCiAgICAgICAgICovCiAgICAgICAgc2V0RmllbGRQcm9wZXJ0aWVzOiBmdW5jdGlvbiAoZmllbGRBcnJheSwgcHJvcCwgdmFsdWVzKSB7CiAgICAgICAgICAgIHZhciBvYmogPSBuZXcgWEZBUmVzdWx0T2JqZWN0KCk7CiAgICAgICAgICAgIGlmICghdGhpcy5fY2hlY2tYZmEob2JqKSkKICAgICAgICAgICAgICAgIHRocm93IG9iai5nZXROZXh0TWVzc2FnZSgpLm1lc3NhZ2U7CgogICAgICAgICAgICBpZiAoIV8uaXNBcnJheShmaWVsZEFycmF5KSkgewogICAgICAgICAgICAgICAgZmllbGRBcnJheSA9IFtmaWVsZEFycmF5XTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFfLmlzQXJyYXkodmFsdWVzKSl7CiAgICAgICAgICAgICAgICB2YWx1ZXMgPSBbdmFsdWVzXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWVsZEFycmF5Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB2YXIgZmllbGQgPSB0aGlzLl94ZmEucmVzb2x2ZU5vZGUoZmllbGRBcnJheVtpXSk7CiAgICAgICAgICAgICAgICBpZiAoZmllbGQgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB0aHJvdyAiTm8gZmllbGQgIiArIGZpZWxkQXJyYXlbaV0gKyAiIGV4aXN0cyIKICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIG9iai5jb21wbGV0ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGZpZWxkW3Byb3BdID0gdmFsdWVzW2ldIHx8IHZhbHVlc1swXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBjaGFuZ2UgbWFkZSB0byByZS1ldmFsdWF0ZSBmbG9hdGluZyBmaWVsZCB0ZXh0IGluIGRyYXcKICAgICAgICAgICAgaWYocHJvcCAmJiBwcm9wID09PSAicmF3VmFsdWUiICYmIHRoaXMuX3hmYS5tb0NvbnRleHROb2Rlcy5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgdGhpcy5feGZhLnJ1bkNhbGNBbmRWYWxpZGF0ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAvKgogICAgICAgICAqIGdldCB0aGUgcHJvcGVydHkgdmFsdWUgb2YgdGhlIGZpZWxkcywgd2hvc2Ugc29tIGlzIHByb3ZpZGVkIGluIHRoZSBmaWVsZEFycmF5CiAgICAgICAgICogZmllbGRBcnJheTogYXJyYXkgb2Ygc29tRXhwcmVzc2lvbnMKICAgICAgICAgKiBwcm9wOiBwcm9wZXJ0eSB0byBnZXQKICAgICAgICAgKgogICAgICAgICAqIHJldHVybnMgYSBYRkFSZXN1bHRPYmplY3Qgd2hvc2UgZGF0YSBtZW1iZXIgaXMgdGhlIGFycmF5IG9mIHJldHVybmVkIHZhbHVlcy4gSWYgYQogICAgICAgICAqIHNvbUV4cHJlc3Npb24gcHJvdmlkZWQgZG9lc24ndCBleGlzdHMgbnVsbCBpcyByZXR1cm5lZCBmb3IgdGhhdCBlbGVtZW50IGluIHRoZSBkYXRhCiAgICAgICAgICovCiAgICAgICAgZ2V0RmllbGRQcm9wZXJ0aWVzOiBmdW5jdGlvbiAoZmllbGRBcnJheSwgcHJvcCkgewogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwogICAgICAgICAgICBpZiAoIXRoaXMuX2NoZWNrWGZhKG9iaikpCiAgICAgICAgICAgICAgICByZXR1cm4gb2JqOwoKICAgICAgICAgICAgaWYgKCFfLmlzQXJyYXkoZmllbGRBcnJheSkpIHsKICAgICAgICAgICAgICAgIGZpZWxkQXJyYXkgPSBbZmllbGRBcnJheV07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG9iai5kYXRhID0gW107CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZmllbGRBcnJheS5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIGZpZWxkID0gdGhpcy5feGZhLnJlc29sdmVOb2RlKGZpZWxkQXJyYXlbaV0pOwogICAgICAgICAgICAgICAgaWYgKGZpZWxkID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBvYmouYWRkTWVzc2FnZSgwLCAiTm8gZmllbGQgIiArIGZpZWxkQXJyYXlbaV0gKyAiIGV4aXN0cyIsIGZpZWxkQXJyYXlbaV0pCiAgICAgICAgICAgICAgICAgICAgb2JqLmRhdGEucHVzaChudWxsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIG9iai5jb21wbGV0ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIG9iai5kYXRhLnB1c2goZmllbGRbcHJvcF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBvYmo7CiAgICAgICAgfSwKICAgICAgICBoaWRlU3VibWl0QnV0dG9uczogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwogICAgICAgICAgICBpZiAoIXRoaXMuX2NoZWNrWGZhKG9iaikpCiAgICAgICAgICAgICAgICB0aHJvdyBvYmouZ2V0TmV4dE1lc3NhZ2UoKS5tZXNzYWdlOwogICAgICAgICAgICB0aGlzLl94ZmEuX2hpZGVTdWJtaXRCdXR0b25zKCk7CiAgICAgICAgfSwKICAgICAgICBfZ2V0UGF0aFVybDogZnVuY3Rpb24gKHVybFN1ZmZpeCkgewogICAgICAgICAgICB2YXIgdXJsID0gdGhpcy5fUFJPRklMRV9SRVNPVVJDRV9QQVRIICsgKHVybFN1ZmZpeCB8fCAiIik7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRVcmwodXJsKTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0RmlsZVdpZGdldElmUHJlc2VudDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4geGZhbGliLnJ1bnRpbWUuZmlsZVVwbG9hZFdpZGdldDsKCiAgICAgICAgfSwKICAgICAgICBfZ2V0RmlsZUxpc3RGcm9tRmlsZVdpZGdldDogIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGZpbGVXaWRnZXQgPSB0aGlzLl9nZXRGaWxlV2lkZ2V0SWZQcmVzZW50KCk7CiAgICAgICAgICAgIGlmKGZpbGVXaWRnZXQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmaWxlV2lkZ2V0Ll9nZXRGaWxlTGlzdCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCiAgICAgICAgX2dldENvbW1pdFZhbHVlRnJvbUZpbGVXaWRnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGZpbGVXaWRnZXQgPSB0aGlzLl9nZXRGaWxlV2lkZ2V0SWZQcmVzZW50KCk7CiAgICAgICAgICAgIGlmKGZpbGVXaWRnZXQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmaWxlV2lkZ2V0LmdldENvbW1pdFZhbHVlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gb3B0aW1pemV7Ym9vbGVhbn0gZmxhZyB0byB0dXJuIG9wdGltaXphdGlvbiBvbjsgaWYgZmFsc2UsIGVudGlyZSBqc29uTW9kZWwgaXMgcmV0dXJuZWQsCiAgICAgICAgICogZWxzZSBkaWZmIG9mIGluaXRpYWwgYW5kIGN1cnJlbnQgbW9kZWwgcmV0dXJuZWQuCiAgICAgICAgICogQHBhcmFtIG9wdGltaXplX2xldmVsezAsMSBvciAyfSA6IGRldGVybWluZXMgdGhlIGFnZ3Jlc3NpdmVuZXNzIGxldmVsIG9mIHNpemUgb3B0aW1pemF0aW9ucyB1c2VkCiAgICAgICAgICogIDA6IHJldHVybnMgYWxsIHByb3BlcnRpZXMgd2hpY2ggY2hhbmdlZCBiZXR3ZWVuIGluaXRpYWwgYW5kIGN1cnJlbnQgbW9kZWwuCiAgICAgICAgICogIDE6IGpzb25Nb2RlbERpZmYgd2l0aCBhY2Nlc3MgJiBwcmVzZW5jZSwgbXVzdCBiZSByZXBheWFibGUgdmlhIHBsYXlKc29uIG9uIGNhbGxpbmcgcmVzdG9yZUZvcm1TdGF0ZS4gYnV0IHRvIGtlZXAgZGlmZiBzeiB0byBtaW4uCiAgICAgICAgICogICAgICByZW1vdmUgdW5wbGF5ZWQgaXRlbXMgZnJvbSB0aGUgZGlmZi4gQWxzbyB0byBtYWludGFpbiBoaWVyYXJjaHkgbXVzdCBoYXZlIGFsbCBpbnN0YW5jZSBtYW5hZ2VycywgYW5kIHVuYmluZGVkIGZpZWxkcy4KICAgICAgICAgKiAgMjogbWluaW1hbCBqc29uTW9kZWxEaWZmIHdpdGggb25seSBoaWVyYXJjaHkgc2tlbGV0b24gYW5kIGNsYXNzLCBuYW1lIGFuZCAndmFsdWUncyBwcmVzZXJ2ZWQgZm9yIHRyYW5zZmVyIGR1cmluZyBzdWJtaXQuCiAgICAgICAgICoKICAgICAgICAgKiBAcmV0dXJucyB7WEZBUmVzdWx0T2JqZWN0fQogICAgICAgICAqIHJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgWEZBIEZvcm0gRE9NIGFuZCBpbmNsdWRlcyBhbGwgdGhlIFhGQSBwYWNrZXRzCiAgICAgICAgICogcmV0dXJucyBhIFhGQVJlc3VsdE9iamVjdCB3aG9zZSAnZGF0YScgbWVtYmVyIGlzIHRoZSBmb3JtU3RhdGUKICAgICAgICAgKi8KICAgICAgICBnZXRGb3JtU3RhdGU6IGZ1bmN0aW9uIChvcHRpbWl6ZSwgb3B0aW1pemVfbGV2ZWwpIHsKICAgICAgICAgICAgdmFyIG9iaiA9IG5ldyBYRkFSZXN1bHRPYmplY3QoKTsKICAgICAgICAgICAgaWYgKCF0aGlzLl9jaGVja1hmYShvYmopKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb2JqOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBiZWhhdmlvckNvbmZpZyA9IG5ldyB4ZmFsaWIudXQuVmVyc2lvbihmb3JtQnJpZGdlLnVzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl0pOwogICAgICAgICAgICAvL1RvIG1haW50YWluIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkKICAgICAgICAgICAgaWYgKGJlaGF2aW9yQ29uZmlnLmlzT24oJ2Rpc2FibGVMZWFuU3VibWl0JykgfHwgYmVoYXZpb3JDb25maWcuaXNPbignbWZEaXNhYmxlTGVhblN1Ym1pdCcpKSB7CiAgICAgICAgICAgICAgICBvcHRpbWl6ZV9sZXZlbCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHhmYURvbSA9IG9wdGltaXplID09PSB0cnVlID8gdGhpcy5feGZhLl9jb21wdXRlSnNvbkRpZmYob3B0aW1pemVfbGV2ZWwpLmpzb25EaWZmZXJlbmNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRoaXMuX3hmYS5qc29uTW9kZWw7CgogICAgICAgICAgICB4ZmFEb20uaXNDb21wbGV0ZSA9ICFvcHRpbWl6ZTsKCiAgICAgICAgICAgIC8vYWRkIHRoZSBpbmZvcm1hdGlvbiByZXF1aXJlZCBmcm9tIERPTSBkdXJpbmcgc3VibWl0IGluIHRoZSBmb3JtIHN0YXRlCiAgICAgICAgICAgIHZhciBmb3JtQXR0cmlidXRlc0RhdGEgPSB7fSwKICAgICAgICAgICAgICAgIGZvcm1FbGVtZW50ID0gJCgiI2xjZm9ybXNfeGZhZm9ybV9jb250YWluZXIiKVswXTsKICAgICAgICAgICAgaWYoZm9ybUVsZW1lbnQpewogICAgICAgICAgICAgICAgXy5lYWNoKGZvcm1FbGVtZW50LmF0dHJpYnV0ZXMsZnVuY3Rpb24oYXR0cmliKXsKICAgICAgICAgICAgICAgICAgICBmb3JtQXR0cmlidXRlc0RhdGFbYXR0cmliLm5hbWVdID0gYXR0cmliLnZhbHVlOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBhZGRpdGlvbmFsU3VibWl0SW5mb3JtYXRpb24gPSB7CiAgICAgICAgICAgICAgICAiZm9ybUF0dHJpYnV0ZXNEYXRhIjogZm9ybUF0dHJpYnV0ZXNEYXRhLAogICAgICAgICAgICAgICAgInVzZXJDb25maWciOiBmb3JtQnJpZGdlLnVzZXJDb25maWcKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHZhciB4ZmFEb21TdHJpbmcgPSBKU09OLnN0cmluZ2lmeSh4ZmFEb20pOwogICAgICAgICAgICBvYmouZGF0YSA9IHsKICAgICAgICAgICAgICAgIHhmYURvbTogeGZhRG9tU3RyaW5nLAogICAgICAgICAgICAgICAgLy9zYXZlIHJlbmRlckNvbnRleHQgaW4gZm9ybSBzdGF0ZSB0byBlbmFibGUgZGVmZXJyZWQgc3VibWl0IGV2ZW4gaWYgZm9ybSBpcyBub3Qgb3BlbgogICAgICAgICAgICAgICAgcmVuZGVyQ29udGV4dDogeGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dCwKICAgICAgICAgICAgICAgIGN1c3RvbVByb3BlcnR5TWFwOiB4ZmFsaWIucnVudGltZS5jdXN0b21Qcm9wZXJ0eU1hcCwKICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxTdWJtaXRJbmZvcm1hdGlvbjogYWRkaXRpb25hbFN1Ym1pdEluZm9ybWF0aW9uCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHJldHVybiBvYmo7CiAgICAgICAgfSwKICAgICAgICAvKgogICAgICAgICAqIHNldHMgdGhlIGZpZWxkIG9uIGZvY3VzIHdob3NlIHNvbUV4cHJlc3Npb24gaXMgcHJvdmlkZWQKICAgICAgICAgKgogICAgICAgICAqIHRocm93cyBhbiBleGNlcHRpb24gaW4gY2FzZSBvZiBlcnJvci4KICAgICAgICAgKi8KICAgICAgICBzZXRGb2N1czogZnVuY3Rpb24gKHNvbSkgewogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwogICAgICAgICAgICBpZiAoIXRoaXMuX2NoZWNrWGZhKG9iaikpCiAgICAgICAgICAgICAgICB0aHJvdyBvYmouZ2V0TmV4dE1lc3NhZ2UoKS5tZXNzYWdlOwogICAgICAgICAgICB2YXIgbm9kZSA9IHRoaXMuX3hmYS5yZXNvbHZlTm9kZShzb20pOwogICAgICAgICAgICBpZiAobm9kZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICB0aHJvdyAiTm8gZmllbGQgIiArIHNvbSArICIgZXhpc3RzICI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmEuaG9zdC5fc2V0Rm9jdXMoc29tKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogIEhlbHBlciBmdW5jdGlvbiB0byBnZXIgc3VibWl0IHNlcnZpY2UgcHJveHkgdXJsCiAgICAgICAgICovCiAgICAgICAgX2dldFN1Ym1pdFNlcnZpY2VQcm94eVVybDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgc3VibWl0U2VydmljZVByb3h5Q29uZmlnID0gdGhpcy51c2VyQ29uZmlnWyJzdWJtaXRTZXJ2aWNlUHJveHlDb25maWciXSwKICAgICAgICAgICAgICAgIHN1Ym1pdFNlcnZpY2VQcm94eVVybCA9ICIiLAogICAgICAgICAgICAgICAgY29udGV4dFBhdGggPSB0aGlzLnVzZXJDb25maWdbImNvbnRleHRQYXRoIl07CiAgICAgICAgICAgIGlmIChzdWJtaXRTZXJ2aWNlUHJveHlDb25maWcgJiYgc3VibWl0U2VydmljZVByb3h5Q29uZmlnWyJzdWJtaXRTZXJ2aWNlUHJveHkiXSkgewogICAgICAgICAgICAgICAgc3VibWl0U2VydmljZVByb3h5VXJsICs9IHN1Ym1pdFNlcnZpY2VQcm94eUNvbmZpZ1sic3VibWl0U2VydmljZVByb3h5Il07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAvL2ZpbmFsbHkgaGFyZCBjb2RlIGl0CiAgICAgICAgICAgICAgICBzdWJtaXRTZXJ2aWNlUHJveHlVcmwgKz0gKChjb250ZXh0UGF0aCAmJiBjb250ZXh0UGF0aCAhPT0gIi8iKSA/IGNvbnRleHRQYXRoIDogIiIpICsgIi9jb250ZW50L3hmYWZvcm1zL3Byb2ZpbGVzL2RlZmF1bHQuc3VibWl0Lmh0bWwiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzdWJtaXRTZXJ2aWNlUHJveHlVcmw7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiByZW1vdGUgaW52b2NhdGlvbiAtLS0tCiAgICAgICAgICogVGhpcyBtZXRob2QgcG9zdCBmb3JtIGRvbSB0byBMQ0Zvcm1zU2VydmljZSBhbmQgcnVuIHRoZSBzdWNjZXNzIGhhbmRsZXJzCiAgICAgICAgICogSXQgYWNjZXB0cyB0aGUgb2JqZWN0IHdpdGggZm9sbG93aW5nIHBhcmFtczoKICAgICAgICAgKiB7CiAgICAgICAgICogIHVybDogJycsCiAgICAgICAgICogIHR5cGU6ICcnLAogICAgICAgICAqICBjb250ZW50VHlwZTogJycsCiAgICAgICAgICogIGRhdGE6ICcnLAogICAgICAgICAqICBzdWNjZXNzOiAnJywKICAgICAgICAgKiAgZXJyb3I6ICcnCiAgICAgICAgICogIH0KICAgICAgICAgKiAgVGhlIGNhbGxlZCBjYW4gY2hvb3NlIHRvIG92ZXJyaWRlIG9uZSBvZiBtb3JlIHBhcmFtZXRlcnMgb2YgJC5hamF4IEFQSSBvZiBKUXVlcnkKICAgICAgICAgKi8KCiAgICAgICAgX2ludm9rZUF0U2VydmVyOiBmdW5jdGlvbiAob3B0aW9ucykgewogICAgICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICAgICAgICAgICAgdmFyIHN1Ym1pdFNlcnZpY2VQcm94eVVybCA9IHRoaXMuX2dldFN1Ym1pdFNlcnZpY2VQcm94eVVybCgpLAogICAgICAgICAgICAgICAgaXNTZXJ2ZXJBamF4Q2FsbE1vZGUgPSB0aGlzLmFqYXhDYWxsTW9kZSA9PT0gInNlcnZlciI7CgogICAgICAgICAgICBpZiAob3B0aW9ucy5kYXRhICYmICFvcHRpb25zLmRhdGFbIl9jaGFyc2V0XyJdKSB7CiAgICAgICAgICAgICAgICBvcHRpb25zLmRhdGFbIl9jaGFyc2V0XyJdID0gIlVURi04IjsgLy90byBsZXQgc2xpbmcga25vdyBkYXRhIGVuY29kaW5nCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKGlzU2VydmVyQWpheENhbGxNb2RlKXsKICAgICAgICAgICAgICAgIHZhciBtZXJnZWRGb3JtRG9tID0gIiI7CiAgICAgICAgICAgICAgICAvLyBEb25lIHRvIGZpeDogTEMtOTIwNAogICAgICAgICAgICAgICAgLy8gTm90IGludm9raW5nIEhUVFAgcmVxdWVzdCBpbnN0ZWFkIG1ha2luZyB1c2Ugb2Ygc2VydmVyIHNlc3Npb24KICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgbWVyZ2VkRm9ybURvbSA9IGdldE1lcmdlZEZvcm1Eb21Gcm9tUmhpbm8ob3B0aW9ucy5kYXRhKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2goZXhjZXB0aW9uKXsKICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmVycm9yKCJ4ZmEiLCBleGNlcHRpb24ubWVzc2FnZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBJZiBzdWNjZXNzIGhhbmRsZXIgaXMgcHJlc2VudCwgaW52b2tlIGl0LCBjb250ZXh0IGlzIHByb3ZpZGVkIGJ5IHRoZSBjYWxsZXIKICAgICAgICAgICAgICAgIGlmKF8uaXNGdW5jdGlvbihvcHRpb25zLnN1Y2Nlc3MpICYmIG1lcmdlZEZvcm1Eb20pIHsKICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnN1Y2Nlc3MoSlNPTi5wYXJzZShtZXJnZWRGb3JtRG9tKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgc3RyQ29udGVudCA9IHRoaXMuZ2V0TXVsdGlwYXJ0RGF0YShvcHRpb25zLmRhdGEpOyAgLy8gVE9ETyA6IG1heWJlIHVzZSB0aGUgYnJvd3NlcidzIEZvcm1EYXRhIG9iamVjdCwgYW5kIGhhbmRsZSBJRSBhcyB3ZSBhcmUgZG9pbmcgbm93CiAgICAgICAgICAgICAgICBvcHRpb25zLmRhdGEgPSBzdHJDb250ZW50WzFdOwogICAgICAgICAgICAgICAgdmFyIHBhcmFtcyA9IF8uZXh0ZW5kKHsKICAgICAgICAgICAgICAgICAgICAgICAgYmVmb3JlU2VuZDogZm9ybUJyaWRnZS51aUZyZWV6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGU6IGZvcm1CcmlkZ2UudWlVbkZyZWV6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgYXN5bmM6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICB1cmw6IHN1Ym1pdFNlcnZpY2VQcm94eVVybCwKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ1BPU1QnLAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzRGF0YTogZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFR5cGU6ICJtdWx0aXBhcnQvZm9ybS1kYXRhOyBjaGFyc2V0PVVURi04OyBib3VuZGFyeT0iICsgc3RyQ29udGVudFswXQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyk7CgogICAgICAgICAgICAgICAgJC5hamF4KHBhcmFtcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqIFRoaXMgZnVuY3Rpb24gZG9lcyBmb2xsb3dpbmc6CiAgICAgICAgICogYSkgT24gZmlyc3QgY2FsbCwgaXQgY3JlYXRlcyB0aGUgdXVpZCBzdG9yYWdlIGFuZCByZXR1cm5zIHRoZSBVVUlECiAgICAgICAgICogYikgT24gc3Vic2VxdWVudCBjYWxscywgaXQganVzdCByZXR1cm5zIHRoZSB1dWlkCiAgICAgICAgICogYykgaWYgdXVpZCBpcyBub3QgY3JlYXRlZCB0aGVuIGl0IHJldHVybnMgbnVsbAogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgX2dldFVVSUQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYodGhpcy5fZm9ybUluc3RhbmNlVVVJRCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Zvcm1JbnN0YW5jZVVVSUQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9HZW5lcmF0ZSB0aGUgVVVJRCBmb3IgdGhlIGZvcm0gaW5zdGFuY2Ugb24gY2xpZW50IHNpZGUKICAgICAgICAgICAgdmFyIHV1aWQgPSAkKCdib2R5I2Zvcm1Cb2R5JykuZGF0YSgidG1wcm9vdCIpLAogICAgICAgICAgICAgICAgdXVpZFN1ZmZpeCA9IE1hdGguZmxvb3IoKE1hdGgucmFuZG9tKCkgKiAxMDAwMCkgKyAxKSwKICAgICAgICAgICAgICAgIHV1aWRDdXJyZW50VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpLAogICAgICAgICAgICAgICAgc3VjY2Vzc0ZsYWcgPSB0cnVlOwogICAgICAgICAgICB0aGlzLl9mb3JtSW5zdGFuY2VVVUlEID0gdXVpZCArICJfIiArIHV1aWRDdXJyZW50VGltZSArIHV1aWRTdWZmaXg7CiAgICAgICAgICAgIHN1Y2Nlc3NGbGFnID0gY3JlYXRlVVVJRFN0b3JhZ2UodGhpcy5fZm9ybUluc3RhbmNlVVVJRCk7CiAgICAgICAgICAgIGlmKHN1Y2Nlc3NGbGFnKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9mb3JtSW5zdGFuY2VVVUlEOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIF9nZXRVcmw6IGZ1bmN0aW9uICh1cmwpIHsKICAgICAgICAgICAgLy91cmwgcHJvdmlkZWQgY2FuIGNvbnRhaW4gdGhlIGhvc3RuYW1lIGFuZCBwb3J0IHRvbywgaW4gdGhhdCBjYXNlIHJldHVybiB0aGUgdXJsIGFzIGl0IGlzCiAgICAgICAgICAgIGlmICh1cmwuaW5kZXhPZigiaHR0cDoiKSA9PSAwIHx8IHVybC5pbmRleE9mKCJodHRwczoiKSA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdXJsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBiYXNlVXJsID0gdGhpcy51c2VyQ29uZmlnWyJiYXNlVXJsIl0sCiAgICAgICAgICAgICAgICBjb250ZXh0UGF0aCA9IHRoaXMudXNlckNvbmZpZ1siY29udGV4dFBhdGgiXTsKICAgICAgICAgICAgaWYgKGJhc2VVcmwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBiYXNlVXJsICsgdXJsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGNvbnRleHRQYXRoICYmIGNvbnRleHRQYXRoIT09ICIvIiAmJiB1cmwuaW5kZXhPZihjb250ZXh0UGF0aCkhPT0gMCAmJih1cmwubGVuZ3RoID09PTAgfHwgdXJsLmluZGV4T2YoIi8iKSA9PT0gMCkpewogICAgICAgICAgICAgICAgLy9pZiB1cmwgZG9lcyBub3QgaGF2ZSBjb250ZXh0UGF0aCBhbmQgc3RhcnRzIHdpdGggLywgcHJlLXBlbmQgY29udGV4dFBhdGgKICAgICAgICAgICAgICAgIC8vIEFsc28gdXJsLmxlbmd0aCBjaGVjayBiZWNhdXNlIEkgbmVlZCB0byBwYXNzICIiIHRvIGdldFVybCBhbmQgZ2V0IGNvbnRleHQgcGF0aAogICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHRQYXRoICsgdXJsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB1cmw7CiAgICAgICAgfSwKICAgICAgICBnZXRGaWxlQXR0YWNobWVudHNJbmZvOiBmdW5jdGlvbiAob3B0aW9ucykgewogICAgICAgICAgICB2YXIgZmlsZUF0dGFjaG1lbnRzTGlzdCA9IFtdLAogICAgICAgICAgICAgICAgbGlzdDsKCgogICAgICAgICAgICBmdW5jdGlvbiBjb2xsZWN0RmlsZVVybHMoZXZlbnQpIHsKICAgICAgICAgICAgICAgIGxpc3QgPSBbXTsKICAgICAgICAgICAgICAgIC8vVE9ETzogbmVlZCB0byBtb2R1bGFyaXplIGNvbGxlY3RGaWxlVXJzKCkKICAgICAgICAgICAgICAgIC8vIGhlcmUgdGhpcyBpcyB0aGUgY29udGV4dCBvZiB0aGUgZnVuY3Rpb24gd2hvIGNhbGxzIGl0CiAgICAgICAgICAgICAgICBfLmVhY2godGhpcy5hdHRhY2htZW50cywgZnVuY3Rpb24gKGF0dCkgewogICAgICAgICAgICAgICAgICAgIC8vdGhpcy5maWxlVXJsIGlzIG51bGwgd2hlbiBubyBmaWxlIGlzIHVwbG9hZGVkLiBhdHQgY29udGFpbnMgcGF0aCAtICJmaWxldXBsb2FkL+KEomEuanBnIiBpZiBub3QgdXBsb2FkZWQKICAgICAgICAgICAgICAgICAgICAvLyBpZiBhdHQgc3RhcnRzIHdpdGggIi8iLCB0aGlzIG1lYW5zIHRoYXQgdGhlIGF0dGFjaG1lbnQgaGFzIGFscmVhZHkgYmVlbiB1cGxvYWRlZC4KICAgICAgICAgICAgICAgICAgICBpZighXy5pc0VtcHR5KHRoaXMuZmlsZVVybCkgJiYgYXR0LmluZGV4T2YoIi8iKSE9MCApIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5wdXNoKHtuYW1lOiBhdHQuc3BsaXQoIi8iKVsxXSwgcGF0aDogdGhpcy5maWxlVXJsICsgIi8iICsgYXR0fSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5wdXNoKHtuYW1lOiBhdHQuc3Vic3RyaW5nKGF0dC5sYXN0SW5kZXhPZigiLyIpKzEpLCBwYXRoOiBhdHR9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5zdWNjZXNzLmNhbGwodGhpcy5vcHRpb25zLmNvbnRleHQsIGxpc3QpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLl9nZXRBdHRhY2htZW50cyhmaWxlQXR0YWNobWVudHNMaXN0LCBvcHRpb25zLmZpbGVVcGxvYWRQYXRoIHx8IHRoaXMuZ2V0VGVtcFBhdGgoKSwgY29sbGVjdEZpbGVVcmxzLCBvcHRpb25zKTsKCiAgICAgICAgfSwKCiAgICAgICAgX2dldEF0dGFjaG1lbnRzOiBmdW5jdGlvbiAoZmlsZUF0dGFjaG1lbnREb21FbGVtZW50LCBmaWxlVXBsb2FkUGF0aCwgY2FsbGJhY2ssIG9wdGlvbnMpIHsKCiAgICAgICAgICAgIHZhciBhbGxGaWxlcyA9IFtdLAogICAgICAgICAgICAgICAgYXR0YWNobWVudHMgPSBbXSwKICAgICAgICAgICAgICAgIGZpbGVVcmwgPSBudWxsLAogICAgICAgICAgICAgICAgZmlsZUNvdW50ID0gMCwKICAgICAgICAgICAgICAgIGRpZFN1Ym1pdCA9IGZhbHNlLAogICAgICAgICAgICAgICAgY29udGV4dFJvb3QgPSB0aGlzLl9nZXRDb250ZXh0Um9vdCgpLAogICAgICAgICAgICAgICAgRklMRV9DT01QT05FTlRfTkFNRSA9ICJmaWxldXBsb2FkIjsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEluIHRoZSBjYXNlIG9mIGRyYWZ0LCB1cmwgY29tZXMgd2l0aCBjb250ZXh0IHJvb3QuIE5lZWQgdG8gcmVtb3ZlIGl0IHNvIHRoYXQgY29ycmVjdCB2YWx1ZSBnZXRzIHN0b3JlZCBpbiBtb2RlbAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKGNvbnRleHRSb290KSB7CiAgICAgICAgICAgICAgICBpZiAoZmlsZVVwbG9hZFBhdGguaW5kZXhPZihjb250ZXh0Um9vdCkgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICBmaWxlVXBsb2FkUGF0aCA9IGZpbGVVcGxvYWRQYXRoLnN1YnN0cmluZyhjb250ZXh0Um9vdC5sZW5ndGgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgY3VycmVudENvdW50ID0gMDsKICAgICAgICAgICAgdmFyIGZpbGVOYW1lTGlzdCA9IGZvcm1CcmlkZ2UuX2dldENvbW1pdFZhbHVlRnJvbUZpbGVXaWRnZXQoKTsKCiAgICAgICAgICAgIGlmIChmaWxlTmFtZUxpc3QubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgdmFyIGZpbGVOYW1lcyA9IGZpbGVOYW1lTGlzdDsKICAgICAgICAgICAgICAgIHZhciBmaWxlTGlzdCA9ICQuZXh0ZW5kKHRydWUsIFtdLCBmb3JtQnJpZGdlLl9nZXRGaWxlTGlzdEZyb21GaWxlV2lkZ2V0KCkpOwogICAgICAgICAgICAgICAgXy5lYWNoKGZpbGVMaXN0LCBmdW5jdGlvbiAoZmlsZSwgaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZU9mRmlsZSA9IGZpbGVOYW1lc1tpbmRleF0sCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlTmFtZU9mRmlsZSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVPZkZpbGUgIT0gbnVsbCAmJiBmaWxlICE9IG51bGwpIHsgLy9maWxlIGNhbiBiZSBudWxsIHdoZW4geW91IGNsaWNrIHNhdmUgdHdvIHRpbWVzIGNvbnRpbnVvdXNseSB3aXRob3V0IGNoYW5nZSBpbiBndWlkZSBjb250ZXh0CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlTmFtZU9mRmlsZSA9IEZJTEVfQ09NUE9ORU5UX05BTUUgKyAiLyIgKyBuYW1lT2ZGaWxlOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBjYXNlOiBpZiB0aGVyZSBpcyBhIGZpbGUgZG9tZQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV8uaXNTdHJpbmcoZmlsZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSB2YWx1ZSBleGlzdCBpbiB0aGUgZmlsZSwgdGhpcyBpcyBkb25lIGJlY2F1c2UgaW4gSUU5IGFuZCBJRTEwIHRoZSBsaXN0IHdpbGwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhdmUgYW4gZXh0cmEgZW1wdHkgZG9tCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJChmaWxlKS52YWwoKS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJChmaWxlKS5hdHRyKCduYW1lJywgY29tcGxldGVOYW1lT2ZGaWxlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRhY2htZW50c1tmaWxlQ291bnRdID0gY29tcGxldGVOYW1lT2ZGaWxlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbEZpbGVzW2ZpbGVDb3VudCsrXSA9ICQoZmlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaW5jZSB0aGVyZSBpcyBubyBmaWxlIGRvbSBpbiBjYXNlIG9mIGRyYWZ0IHVzZWNhc2UsIG1ha2UgaXQgbnVsbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0YWNobWVudHNbZmlsZUNvdW50XSA9IGZpbGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxGaWxlc1tmaWxlQ291bnQrK10gPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwgdGhpcyk7CgoKICAgICAgICAgICAgICAgIGlmIChhbGxGaWxlcy5sZW5ndGggPiAwKSB7CgogICAgICAgICAgICAgICAgICAgIC8vIHNpbmNlIHRoZXJlIGNhbiBiZSBhIGRvbSBlbGVtZW50IHdoaWNoIGlzIG51bGwsIGluIGNhc2Ugb2YgZHJhZnQgdXNlY2FzZQogICAgICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgZmlyc3Qgbm9uIG51bGwgZmlsZSBkb20KICAgICAgICAgICAgICAgICAgICB2YXIgZmlyc3ROb25OdWxsRmlsZURvbSA9IF8uaW5kZXhPZihhbGxGaWxlcywgXy5maW5kKGFsbEZpbGVzLCBmdW5jdGlvbiAoaXRlbSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlbSAhPT0gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9KSk7CiAgICAgICAgICAgICAgICAgICAgdmFyIHVwbG9hZGVyUGx1Z2luTmFtZSA9IGZvcm1CcmlkZ2UudXNlckNvbmZpZy51cGxvYWRlclBsdWdpbk5hbWUgfHwgImFkb2JlRmlsZVVwbG9hZGVyIjsKICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3ROb25OdWxsRmlsZURvbSAhPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVVybCA9IGFsbEZpbGVzW2ZpcnN0Tm9uTnVsbEZpbGVEb21dW3VwbG9hZGVyUGx1Z2luTmFtZV0oInVwbG9hZEZpbGUiLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZmlsZU5hbWUnOiBhdHRhY2htZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmaWxlRG9tJzogYWxsRmlsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZmlsZVVwbG9hZFBhdGgnOiBmaWxlVXBsb2FkUGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdtdWx0aXBsZSc6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnX3V1aWRHZW5lcmF0b3InOiBmdW5jdGlvbiAoKSB7IHJldHVybiBmb3JtQnJpZGdlLl9nZXRVVUlELmFwcGx5KHRoaXMpOyB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgX2dldFVybDogZm9ybUJyaWRnZS5fZ2V0VXJsKCIiKQogICAgICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8qVGhlIGZpbGUgdXJsIHJldHVybmVkIGJ5IGZpbGUgdXBsb2FkIHdpZGdldCBjYW4gY29udGFpbiBjb250ZXh0IHJvb3QuIFJlbW92ZSBpdCBzbyB0aGF0IGNvcnJlY3QgdmFsdWUgZ2V0cyBzdG9yZWQgaW4gbW9kZWwuKi8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRleHRSb290KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZVVybC5pbmRleE9mKGNvbnRleHRSb290KSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVVcmwgPSBmaWxlVXJsLnN1YnN0cmluZyhjb250ZXh0Um9vdC5sZW5ndGgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBhbGxGaWxlc1tmaXJzdE5vbk51bGxGaWxlRG9tXS5vbmUoImFkb2JlRmlsZVVwbG9hZGVyLm11bHRpcGxlRmlsZVVwbG9hZGVkIiwgJC5wcm94eShjYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYXR0YWNobWVudHMiOiBhdHRhY2htZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlsZVVybCI6IGZpbGVVcmwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9wdGlvbnMiOiBvcHRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfdXVpZEdlbmVyYXRvciI6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZvcm1CcmlkZ2UuX2dldFVVSUQuYXBwbHkodGhpcyk7IH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRpZFN1Ym1pdCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFkaWRTdWJtaXQpIHsKICAgICAgICAgICAgICAgIC8vIGlmIHRoZXJlIGFyZSBubyBmaWxlcyBhdHRhY2hlZCwgc3RpbGwgY2FsbCB0aGUgY2FsbGJhY2sgdG8gc3VibWl0IHRoZSBqc29uIGNvbnRlbnRzCiAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBvbmx5IG9uZSBmaWxlIGF0dGFjaG1lbnQgY29tcG9uZW50IHdpdGggbm8gZmlsZXMsIGluIHRoaXMgY2FzZSBlbHNlIGlzIGltcG9ydGFudAogICAgICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkoewogICAgICAgICAgICAgICAgICAgICJhdHRhY2htZW50cyI6IGF0dGFjaG1lbnRzLAogICAgICAgICAgICAgICAgICAgICJmaWxlVXJsIjogZmlsZVVybCwKICAgICAgICAgICAgICAgICAgICAib3B0aW9ucyI6IG9wdGlvbnMKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgfQoKICAgICAgICB9LAogICAgICAgIF9pc0ZpbGVBdHRhY2htZW50RW5hYmxlZDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4geGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dC5tZkFsbG93QXR0YWNobWVudHMgPT09ICd0cnVlJzsKICAgICAgICB9LAogICAgICAgIF9pc0xvZ2luQW5vbnltb3VzOiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgdmFyIGZsYWc7CiAgICAgICAgICAgICAgICBpZih4ZmFsaWIucnVudGltZSkgewogICAgICAgICAgICAgICAgICAgIGZsYWcgPSB4ZmFsaWIucnVudGltZS5faXNBbm9ueW1vdXM7CiAgICAgICAgICAgICAgICAgICAgaWYoXy5pc1VuZGVmaW5lZCh2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZsYWc7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLl9pc0Fub255bW91cyA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBmbGFnOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9nZXRDb250ZXh0Um9vdDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnVzZXJDb25maWdbImNvbnRleHRQYXRoIl07CiAgICAgICAgfSwKCiAgICAgICAgZ2V0VGVtcFBhdGg6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gIi90bXAvZmQveGZhZm9ybXMvIiArIHRoaXMuX2dldFVVSUQoKTsKICAgICAgICB9LAogICAgICAgIF9nZXRGaWxlTmFtZVBhdGhNYXA6IGZ1bmN0aW9uKHZhbHVlTGlzdCkgewogICAgICAgICAgICB2YXIgZmlsZVdpZGdldCA9IHRoaXMuX2dldEZpbGVXaWRnZXRJZlByZXNlbnQoKTsKICAgICAgICAgICAgaWYoZmlsZVdpZGdldCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVXaWRnZXQuX2dldEZpbGVOYW1lUGF0aE1hcCh2YWx1ZUxpc3QpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB7fTsKICAgICAgICB9LAoKCgoKCgogICAgICAgIGdldE11bHRpcGFydERhdGE6IGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgICAgIC8vU3RhcnQgbXVsdGlwYXJ0IGZvcm1hdHRpbmcKICAgICAgICAgICAgdmFyIGluaXRCb3VuZGFyeSA9IHRoaXMucmFuZG9tU3RyaW5nKCk7CiAgICAgICAgICAgIHZhciBzdHJCb3VuZGFyeSA9ICItLSIgKyBpbml0Qm91bmRhcnk7CiAgICAgICAgICAgIHZhciBzdHJNdWx0aXBhcnRCb2R5ID0gIiI7CiAgICAgICAgICAgIHZhciBzdHJDUkxGID0gIlxyXG4iOwoKICAgICAgICAgICAgLy9DcmVhdGUgbXVsdGlwYXJ0IGZvciBlYWNoIGVsZW1lbnQgb2YgdGhlIGZvcm0KICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIGRhdGEpIHsKICAgICAgICAgICAgICAgIGlmIChkYXRhLmhhc093blByb3BlcnR5KGtleSkpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSB0eXBlb2YgZGF0YVtrZXldID09ICJzdHJpbmciID8gZGF0YVtrZXldIDogSlNPTi5zdHJpbmdpZnkoZGF0YVtrZXldKTsKICAgICAgICAgICAgICAgICAgICBzdHJNdWx0aXBhcnRCb2R5ICs9CiAgICAgICAgICAgICAgICAgICAgICAgIHN0ckJvdW5kYXJ5CiAgICAgICAgICAgICAgICAgICAgICAgICsgc3RyQ1JMRgogICAgICAgICAgICAgICAgICAgICAgICArICJDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9XCIiICsga2V5ICsgIlwiIgogICAgICAgICAgICAgICAgICAgICAgICArIHN0ckNSTEYKICAgICAgICAgICAgICAgICAgICAgICAgKyBzdHJDUkxGCiAgICAgICAgICAgICAgICAgICAgICAgICsgdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgKyBzdHJDUkxGOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vRW5kIHRoZSBib2R5IGJ5IGRlbGltaXRpbmcgaXQKICAgICAgICAgICAgc3RyTXVsdGlwYXJ0Qm9keSArPSBzdHJCb3VuZGFyeSArICItLSIgKyBzdHJDUkxGOwogICAgICAgICAgICAvL1JldHVybiBib3VuZGFyeSB3aXRob3V0IC0tIGFuZCB0aGUgbXVsdGlwYXJ0IGNvbnRlbnQKICAgICAgICAgICAgcmV0dXJuIFtpbml0Qm91bmRhcnksIHN0ck11bHRpcGFydEJvZHldOwogICAgICAgIH0sCgogICAgICAgIHJhbmRvbVN0cmluZzogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgY2hhcnMgPSAiMDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFRaYWJjZGVmZ2hpa2xtbm9wcXJzdHV2d3h5eiI7CiAgICAgICAgICAgIHZhciBzdHJpbmdfbGVuZ3RoID0gODsKICAgICAgICAgICAgdmFyIHJhbmRvbVN0cmluZyA9ICcnOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZ19sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIHJudW0gPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBjaGFycy5sZW5ndGgpOwogICAgICAgICAgICAgICAgcmFuZG9tU3RyaW5nICs9IGNoYXJzLnN1YnN0cmluZyhybnVtLCBybnVtICsgMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJhbmRvbVN0cmluZzsKICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIHJldHVybnMgdGhlIGlucHV0IGRhdGEgaW4gWE1MIEZvcm0uIFRoZSBjYWxsIGlzIGFzeW5jaHJvbm91cyBhbmQgcmVjaWV2ZXMgdGhlIGZvbGxvd2luZyBvcHRpb25zIGFwYXJ0IGZyb20gdGhlIGRlZmF1bHQKICAgICAgICAgKiBvbmVzIHByb3ZpZGVkIGVhcmxpZXIKICAgICAgICAgKiAgICAgIHZhbGlkYXRpb25DaGVja2VyIC8vZnVuY3Rpb24gdG8gY2FsbCBmb3IgY2hlY2tpbmcgdmFsaWRhdGlvbiBlcnJvcnMgcmVjZWl2ZWQgZnJvbSBzZXJ2ZXIKICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgVGhlIHNpZ25hdHVyZSBmb3IgdGhlIGZ1bmN0aW9ucyBpcwogICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24odmFsaWRhdGlvbnMpCiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFsaWRhdGlvbnMgaXMgYW4gYXJyYXkgb2YgZXJyb3Igc3RyaW5ncy4KICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgKiAgICAgIGZvcm1TdGF0ZSAgICAgICAvLyBUaGUgc3RhdGUgb2YgdGhlIFhGQSBGb3JtLCBpZiBzYXZlZCBieSB0aGUgdXNlciwgb3RoZXJ3aXNlIHRoZSBjdXJyZW50IG9uZQogICAgICAgICAqLwogICAgICAgIGdldERhdGFYTUw6IGZ1bmN0aW9uIChvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwogICAgICAgICAgICBpZiAoIW9wdGlvbnMuZm9ybVN0YXRlICYmICF0aGlzLl9jaGVja1hmYShvYmopKSB7CiAgICAgICAgICAgICAgICBvcHRpb25zLmVycm9yLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKCFvcHRpb25zLmZvcm1TdGF0ZSAmJiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0T3JFbHNlKHhmYWxpYi5ydW50aW1lLCAiY3VzdG9tUHJvcGVydHlNYXAueG1sT25DbGllbnQiLCAiMCIpID09PSAiMSIpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHhtbCA9IHRoaXMuZ2VuZXJhdGVEYXRhWE1MKCk7CiAgICAgICAgICAgICAgICAgICAgb2JqLmRhdGEgPSB4bWw7CiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnN1Y2Nlc3MuY2FsbChvcHRpb25zLmNvbnRleHQsIG9iaik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaChleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbXNnID0gIlVuYWJsZSB0byBnZW5lcmF0ZSB4bWwgb24gY2xpZW50LiBVc2UgU2VydmVyIG9wdGlvbiB0byBnZW5lcmF0ZSB0aGUgeG1sLiAiICsgZXhjZXB0aW9uOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYS5Mb2dnZXIuZXJyb3IoInhmYSIsIG1zZyk7CiAgICAgICAgICAgICAgICAgICAgb2JqLmNvbXBsZXRlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDIsIG1zZywgIiIpOwogICAgICAgICAgICAgICAgICAgIGlmKG9wdGlvbnMuZXJyb3IpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5lcnJvci5hcHBseShvcHRpb25zLmNvbnRleHQsIFtvYmpdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGZvcm1TdGF0ZSA9IG9wdGlvbnMuZm9ybVN0YXRlIHx8IHRoaXMuZ2V0Rm9ybVN0YXRlKHRydWUsIDIpLmRhdGE7CiAgICAgICAgICAgIC8vY2xvbmUgdGhlIG9iamVjdCB0byBhdm9pZCBwb2xsdXRpbmcgdGhlIG9sZCBjb3B5CiAgICAgICAgICAgIHZhciBwYXJhbXMgPSBfLmV4dGVuZCh7Zm9ybURvbTogZm9ybVN0YXRlLnhmYURvbSwgcmVxdWVzdERhdGFYbWwgOiAidHJ1ZSJ9LCBmb3JtU3RhdGUucmVuZGVyQ29udGV4dCk7CiAgICAgICAgICAgIHRoaXMuX2ludm9rZUF0U2VydmVyKHsKICAgICAgICAgICAgICAgIGRhdGE6IHBhcmFtcywKICAgICAgICAgICAgICAgIGRhdGFUeXBlOiAndGV4dCcsCiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAocmVzdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgb2JqLmNvbXBsZXRlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFyZXN1bHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMCwgIlRoZXJlIHdhcyBhbiBlcnJvciBpbiBnZXR0aW5nIGRhdGEgeG1sIiwgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmVycm9yLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG9iai5kYXRhID0gcmVzdWx0OwogICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnZhbGlkYXRpb25DaGVja2VyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghb3B0aW9ucy52YWxpZGF0aW9uQ2hlY2tlci5jYWxsKG9wdGlvbnMuY29udGV4dCwgcmVzdWx0LnZhbGlkYXRpb25FcnJvcnMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmVycm9yLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnN1Y2Nlc3MpCiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuc3VjY2Vzcy5jYWxsKG9wdGlvbnMuY29udGV4dCwgb2JqLGZvcm1TdGF0ZSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICh4aHIsIHR4dFN0YXR1cywgZXJyb3JUaHJvd24pIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbXNnID0gZm9ybUJyaWRnZS5fZ2V0RGF0YVhNTEVycm9yKHhociwgdHh0U3RhdHVzLCBlcnJvclRocm93bik7CiAgICAgICAgICAgICAgICAgICAgb2JqLmNvbXBsZXRlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDIsIG1zZywgIiIpOwogICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmVycm9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuZXJyb3IuY2FsbChvcHRpb25zLmNvbnRleHQsIG9iaik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChmb3JtQnJpZGdlLl94ZmEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUJyaWRnZS5feGZhLmhvc3QubWVzc2FnZUJveChtc2cpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldERhdGFYTUxFcnJvcjogZnVuY3Rpb24gKHhociwgdHh0U3RhdHVzLCBlcnJvclRocm93bikgewogICAgICAgICAgICB2YXIgbXNnOwogICAgICAgICAgICBzd2l0Y2ggKHhoci5zdGF0dXMpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgICBtc2cgPSB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDgiXTsKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl94ZmEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhLkxvZ2dlci5lcnJvcigieGZhIiwgbXNnICsgIiAiICsgeGhyLnN0YXR1c1RleHQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgbXNnID0geGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDE2Il07CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5feGZhKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYS5Mb2dnZXIuZXJyb3IoInhmYSIsIG1zZyArICIgIiArIHhoci5zdGF0dXNUZXh0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG1zZzsKCiAgICAgICAgfSwKCiAgICAgICAgX2lkZW50aWZ5Q29ubmVjdGlvbkVycm9yOiBmdW5jdGlvbiAoeGhyLCB0eHRTdGF0dXMpIHsKICAgICAgICAgICAgdmFyIG1zZyA9ICIiOwogICAgICAgICAgICBzd2l0Y2ggKHhoci5zdGF0dXMpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgICBtc2cgPSB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDgiXTsKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl94ZmEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhLkxvZ2dlci5lcnJvcigieGZhIiwgbXNnICsgIiAiICsgeGhyLnN0YXR1c1RleHQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgNDA0OgogICAgICAgICAgICAgICAgICAgIG1zZyA9IHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAwOCJdOwogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX3hmYSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEuTG9nZ2VyLmVycm9yKCJ4ZmEiLCBtc2cgKyAiICIgKyB4aHIuc3RhdHVzVGV4dCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBtc2c7CgoKICAgICAgICB9LAoKICAgICAgICBfZ2V0QWxsb3dBdHRhY2htZW50c0Zyb21Gb3JtU3RhdGU6IGZ1bmN0aW9uIChmb3JtU3RhdGUpIHsKICAgICAgICAgICAgcmV0dXJuIGZvcm1TdGF0ZS5yZW5kZXJDb250ZXh0Lm1mQWxsb3dBdHRhY2htZW50cyA9PT0gJ3RydWUnOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwdWJsaWMKICAgICAgICAgKiBUaGlzIHBlcmZvcm1zIGFuIGFqYXggc3VibWl0IHRvIGEgdXJsLgogICAgICAgICAqIFRoaXMgQVBJIGNyZWF0ZXMgYSBmb3JtIGRhdGEgb2JqZWN0IGFuZCBzdWJtaXRzIHRoaXMgb2JqZWN0LgogICAgICAgICAqIEBwYXJhbSBvcHRpb25zCiAgICAgICAgICovCiAgICAgICAgZG9BamF4U3VibWl0OiBmdW5jdGlvbihvcHRpb25zKXsKCiAgICAgICAgICAgIGlmKHdpbmRvdy5Gb3JtRGF0YSl7CgogICAgICAgICAgICAgICAgdmFyIHBzdWVkb0Zvcm0gPSAkKCI8Zm9ybT4iKSwKICAgICAgICAgICAgICAgICAgICBmb3JtU3RhdGUgPSBvcHRpb25zLmZvcm1TdGF0ZSB8fCB0aGlzLmdldEZvcm1TdGF0ZSh0cnVlLCAyKS5kYXRhLAogICAgICAgICAgICAgICAgICAgIHN1Ym1pdFNlcnZpY2VQcm94eUNvbmZpZyA9IGZvcm1TdGF0ZS5hZGRpdGlvbmFsU3VibWl0SW5mb3JtYXRpb24udXNlckNvbmZpZ1sic3VibWl0U2VydmljZVByb3h5Q29uZmlnIl0sCiAgICAgICAgICAgICAgICAgICAgYWN0aW9uID0gb3B0aW9ucy5hY3Rpb24gfHwgdGhpcy5fZ2V0U3VibWl0U2VydmljZVByb3h5VXJsKCk7CgogICAgICAgICAgICAgICAgXy5lYWNoKGZvcm1TdGF0ZS5hZGRpdGlvbmFsU3VibWl0SW5mb3JtYXRpb24uZm9ybUF0dHJpYnV0ZXNEYXRhLCBmdW5jdGlvbiAodmFsdWUsIGtleSkgewogICAgICAgICAgICAgICAgICAgIHBzdWVkb0Zvcm0uYXR0cihrZXksIHZhbHVlKTsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwoKICAgICAgICAgICAgICAgIHBzdWVkb0Zvcm0uYXR0cigiYWN0aW9uIiwgYWN0aW9uKTsKICAgICAgICAgICAgICAgIHZhciAkY2hhclNldEZpZWxkID0gJCgiPGlucHV0PiIpLmF0dHIoeyJ0eXBlIjogImhpZGRlbiIsICJuYW1lIjogIl9jaGFyc2V0XyIsICJ2YWx1ZSI6ICJVVEYtOCJ9KTsKICAgICAgICAgICAgICAgICQocHN1ZWRvRm9ybSkuYXBwZW5kKCRjaGFyU2V0RmllbGQpOwoKICAgICAgICAgICAgICAgIF8uZWFjaChzdWJtaXRTZXJ2aWNlUHJveHlDb25maWcsIGZ1bmN0aW9uIChmaWVsZFZhbHVlLCBmaWVsZE5hbWUpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbmV3RmllbGQgPSAkKCI8aW5wdXQ+IikuYXR0cigidHlwZSIsICJoaWRkZW4iKQogICAgICAgICAgICAgICAgICAgICAgICAuYXR0cigibmFtZSIsIGZpZWxkTmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgLnZhbChmaWVsZFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAkKHBzdWVkb0Zvcm0pLmFwcGVuZCgkKG5ld0ZpZWxkKSk7CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAvL2Nsb25lIHRoZSBvYmplY3QgdG8gYXZvaWQgcG9sbHV0aW5nIHRoZSBvbGQgY29weQogICAgICAgICAgICAgICAgdmFyIHBhcmFtcyA9IF8uZXh0ZW5kKHt9LCBmb3JtU3RhdGUuY3VzdG9tUHJvcGVydHlNYXAsIHtmb3JtRG9tOiBmb3JtU3RhdGUueGZhRG9tfSwgZm9ybVN0YXRlLnJlbmRlckNvbnRleHQpOwoKICAgICAgICAgICAgICAgIGZvciAodmFyIHBhcmFtIGluIHBhcmFtcykgewogICAgICAgICAgICAgICAgICAgIGlmIChwYXJhbXMuaGFzT3duUHJvcGVydHkocGFyYW0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0ZpZWxkID0gJCgiPGlucHV0PiIpLmF0dHIoInR5cGUiLCAiaGlkZGVuIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJuYW1lIiwgcGFyYW0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudmFsKHBhcmFtc1twYXJhbV0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgJChwc3VlZG9Gb3JtKS5hcHBlbmQoJChuZXdGaWVsZCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgZmlsZUF0dGFjaG1lbnRFbmFibGVkID0gZm9ybUJyaWRnZS5fZ2V0QWxsb3dBdHRhY2htZW50c0Zyb21Gb3JtU3RhdGUoZm9ybVN0YXRlKTsKICAgICAgICAgICAgICAgIGlmIChmaWxlQXR0YWNobWVudEVuYWJsZWQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5maWxlQXR0YWNobWVudE1hcCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmlsZUF0dGFjaG1lbnRNYXBJbnB1dCA9ICQoIjxpbnB1dD4iKS5hdHRyKCJ0eXBlIiwgImhpZGRlbiIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYXR0cigibmFtZSIsICJmaWxlQXR0YWNobWVudE1hcCIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudmFsKEpTT04uc3RyaW5naWZ5KG9wdGlvbnMuZmlsZUF0dGFjaG1lbnRNYXApKTsKICAgICAgICAgICAgICAgICAgICAgICAgJChwc3VlZG9Gb3JtKS5hcHBlbmQoJChmaWxlQXR0YWNobWVudE1hcElucHV0KSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZpbGVBdHRhY2htZW50TWFwID0gZm9ybUJyaWRnZS5fZ2V0RmlsZU5hbWVQYXRoTWFwKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlQXR0YWNobWVudElucHV0cyA9IGZvcm1CcmlkZ2UuX2dldEZpbGVMaXN0RnJvbUZpbGVXaWRnZXQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVBdHRhY2htZW50TWFwSW5wdXQ7CgogICAgICAgICAgICAgICAgICAgICAgICBfLmVhY2goZm9ybUJyaWRnZS5fZ2V0Q29tbWl0VmFsdWVGcm9tRmlsZVdpZGdldCgpLCBmdW5jdGlvbiAobmFtZU9mRmlsZSwgaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfLmlzT2JqZWN0KGZpbGVBdHRhY2htZW50SW5wdXRzW2luZGV4XSkgJiYgXy5pc1N0cmluZyhuYW1lT2ZGaWxlKSAmJiAhbmFtZU9mRmlsZS5tYXRjaCgvXC8vZykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlQXR0YWNobWVudElucHV0c1tpbmRleF0uYXR0cigibmFtZSIsIG5hbWVPZkZpbGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlsZUF0dGFjaG1lbnRNYXBbbmFtZU9mRmlsZV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUF0dGFjaG1lbnRNYXBbbmFtZU9mRmlsZV0gPSAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJChwc3VlZG9Gb3JtKS5hcHBlbmQoZmlsZUF0dGFjaG1lbnRJbnB1dHNbaW5kZXhdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICBmaWxlQXR0YWNobWVudE1hcElucHV0ID0gJCgiPGlucHV0PiIpLmF0dHIoInR5cGUiLCAiaGlkZGVuIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJuYW1lIiwgImZpbGVBdHRhY2htZW50TWFwIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC52YWwoSlNPTi5zdHJpbmdpZnkoZmlsZUF0dGFjaG1lbnRNYXApKTsKICAgICAgICAgICAgICAgICAgICAgICAgJChwc3VlZG9Gb3JtKS5hcHBlbmQoJChmaWxlQXR0YWNobWVudE1hcElucHV0KSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy90aGUgWEZBUmVzdWx0T2JqZWN0IHRoYXQgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIHN1Y2Nlc3MgYW5kIGVycm9yIGhhbmRsZXIKICAgICAgICAgICAgICAgIHZhciBvYmogPSBuZXcgWEZBUmVzdWx0T2JqZWN0KCk7CgogICAgICAgICAgICAgICAgdmFyIGZkID0gbmV3IEZvcm1EYXRhKHBzdWVkb0Zvcm1bMF0pOwogICAgICAgICAgICAgICAgLy9zZXQgY29udGVudFR5cGUgdG8gZmFsc2UgdG8gcHJldmVudCBqcXVlcnkgZnJvbSBzZXR0aW5nIGl0IHRvIGRlZmF1bHQgdmFsdWUKICAgICAgICAgICAgICAgIC8vU2V0dGluZyBwcm9jZXNzRGF0YSB0byBmYWxzZSB0byBwcmV2ZW50IGpRdWVyeSBmcm9tIGF1dG9tYXRpY2FsbHkgdHJhbnNmb3JtaW5nIHRoZSBkYXRhIGludG8gYSBxdWVyeSBzdHJpbmcKICAgICAgICAgICAgICAgIC8vIHNldCBkYXRhVHlwZSB0byAidGV4dCIgdG8gcmV0cmlldmUgdGhlIHhtbCBhcyBzdHJpbmcuCiAgICAgICAgICAgICAgICAvLyBUaGUgYWpheCBjYWxsIHJldHVybnMgZGF0YVhtbCB0aGF0IGlzIHBhc3NlZCBpbnNpZGUgWEZBUmVzdWx0T2JqZWN0LgogICAgICAgICAgICAgICAgJC5hamF4KHsKICAgICAgICAgICAgICAgICAgICB1cmw6IGZvcm1CcmlkZ2UuX2dldFVybChhY3Rpb24pLAogICAgICAgICAgICAgICAgICAgIGRhdGE6IGZkLAogICAgICAgICAgICAgICAgICAgIHByb2Nlc3NEYXRhOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTondGV4dCcsCiAgICAgICAgICAgICAgICAgICAgY29udGVudFR5cGU6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIHR5cGU6ICdQT1NUJywKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAocmVzdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9iai5jb21wbGV0ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMCwgIlRoZXJlIHdhcyBhbiBlcnJvciBpbiBzdWJtaXR0aW5nIHRoZSBmb3JtIiwgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5lcnJvci5jYWxsKG9wdGlvbnMuY29udGV4dCwgb2JqKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBvYmouZGF0YSA9IHJlc3VsdDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMudmFsaWRhdGlvbkNoZWNrZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghb3B0aW9ucy52YWxpZGF0aW9uQ2hlY2tlci5jYWxsKG9wdGlvbnMuY29udGV4dCwgcmVzdWx0LnZhbGlkYXRpb25FcnJvcnMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5lcnJvci5jYWxsKG9wdGlvbnMuY29udGV4dCwgb2JqKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zdWNjZXNzLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKHhociwgdHh0U3RhdHVzLCBlcnJvclRocm93bikgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXNnID0gZm9ybUJyaWRnZS5fZ2V0RGF0YVhNTEVycm9yKHhociwgdHh0U3RhdHVzLCBlcnJvclRocm93bik7CiAgICAgICAgICAgICAgICAgICAgICAgIG9iai5jb21wbGV0ZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMiwgbXNnLCAiIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmVycm9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmVycm9yLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3JtQnJpZGdlLl94ZmEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1CcmlkZ2UuX3hmYS5ob3N0Lm1lc3NhZ2VCb3gobXNnKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG9wdGlvbnMuZXJyb3IuY2FsbChvcHRpb25zLmNvbnRleHQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBzdWJtaXRzIHRoZSBmb3JtIGRhdGEgdG8gYSB1cmwgcHJvdmlkZWQgaW4gQ29uZmlnIG9yIEZvcm0gVGVtcGxhdGUKICAgICAgICAgKiBUaGUgQVBJIGNhbGxzIGdldERhdGFYTUwsIGNoZWNrcyB2YWxpZGF0aW9uIGVycm9ycyBhbmQgZWl0aGVyIHN1Ym1pdHMgdGhlIGRhdGEgaXRzZWxmCiAgICAgICAgICogb3IgcGFzc2VzIHRoZSBkYXRhIHRvIHRoZSBzdWNjZXNzIGhhbmRsZXIgcHJvdmlkZWQgYnkgdGhlIGNhbGxlcgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgc3VibWl0Rm9ybTogZnVuY3Rpb24gKG9wdGlvbnMpIHsKICAgICAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CgkJCW9wdGlvbnMuZXJyb3IgPSBvcHRpb25zLmVycm9yIHx8IGRlZmF1bHRFcnJvckhhbmRsZXI7CiAgICAgICAgICAgIG9wdGlvbnMuY29udGV4dCA9IG9wdGlvbnMuY29udGV4dCB8fCBmb3JtQnJpZGdlOwogICAgICAgICAgICBvcHRpb25zLnZhbGlkYXRpb25DaGVja2VyID0gb3B0aW9ucy52YWxpZGF0aW9uQ2hlY2tlciB8fCBkZWZhdWx0VmFsaWRhdGlvbkNoZWNrZXI7CiAgICAgICAgICAgIC8vZm9ybUJyaWRnZS5rZXlWYWx1ZVBhaXJTdWJtaXNzaW9uID0gdHJ1ZTsKCiAgICAgICAgICAgIHRoaXMudWlGcmVlemUoKTsgICAvLyBCdWc6IExDLTYwNjggVG8gc2hvdyBjdXJzb3IgaW4gd2FpdCBzdGF0ZSBhbmQgYWxzbyBmcmVlemluZyB0aGUgdWkgYnkgbWFya2luZyByb290IHN1YmZvcm0gYWNjZXNzIGFzIHJlYWRPbmx5LgogICAgICAgICAgICB2YXIgb3JpZ2luYWxTdWNjZXNzID0gb3B0aW9ucy5zdWNjZXNzOwogICAgICAgICAgICB2YXIgb3JpZ2luYWxFcnJvciA9IG9wdGlvbnMuZXJyb3IgfHwgZGVmYXVsdEVycm9ySGFuZGxlcjsKICAgICAgICAgICAgdmFyIG9yaWdpbmFsQ29udGV4dCA9IG9wdGlvbnMuY29udGV4dDsKICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwoKICAgICAgICAgICAgb3B0aW9ucy5lcnJvciA9IChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHRoYXQudWlVbkZyZWV6ZSgpOyAgLy8gQnVnOiBMQy02MDY4IFRvIHJlc3RvcmUgY3Vyc29yIGZyb20gd2FpdCBzdGF0ZSBhbmQgYWxzbyByZXN0b3JpbmcgdGhlIHVpIGJ5IG1hcmtpbmcgcm9vdCBzdWJmb3JtIGFjY2VzcyBhcyBpdHMgb2xkIGFjY2Vzcy4KICAgICAgICAgICAgICAgICAgICBpZiAob3JpZ2luYWxFcnJvcikgewogICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbEVycm9yLmFwcGx5KG9yaWdpbmFsQ29udGV4dCwgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9KSgpOwogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwoKICAgICAgICAgICAgLy8gaWYgY2FuY2VsQWN0aW9uIHByb3BlcnR5IGlzIHNldCB0byB0cnVlIGluIHByZVN1Ym1pdCwgZXhlY1ByZVN1Ym1pdCByZXR1cm4gZmFsc2UKICAgICAgICAgICAgaWYgKHRoaXMuX3hmYSAmJiB0aGlzLl94ZmEuZm9ybS5leGVjUHJlU3VibWl0KCkgPT0gZmFsc2UgKSB7CiAgICAgICAgICAgICAgICB2YXIgbXNnID0gIlN1Ym1pdCBjYW5jZWxsZWQiOwogICAgICAgICAgICAgICAgdGhpcy5feGZhLmhvc3QubWVzc2FnZUJveChtc2cpOwogICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMCwgbXNnLCAieGZhIik7CiAgICAgICAgICAgICAgICBvcHRpb25zLmVycm9yLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5feGZhICYmIHRoaXMuX3hmYS5ob3N0Ll92YWxpZGF0ZSgpID09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICBvYmouYWRkTWVzc2FnZSgwLCAiY2xpZW50IHNpZGUgdmFsaWRhdGlvbnMgZmFpbGVkIiwgInhmYSIpOyAvL1RPRE86IGhhbmRsZXNvbUV4cHJlc3Npb24gcGFzc2luZwogICAgICAgICAgICAgICAgb3B0aW9ucy5lcnJvci5jYWxsKG9wdGlvbnMuY29udGV4dCwgb2JqKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5fdHJpZ2dlck9uQnJpZGdlKCJzdWJtaXRTdGFydCIsIHRoaXMsICJzdWJtaXQiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAob3B0aW9ucy5zdWNjZXNzIC8qfHwgZm9ybUJyaWRnZS5rZXlWYWx1ZVBhaXJTdWJtaXNzaW9uKi8pIHsKICAgICAgICAgICAgICAgIC8qdmFyIGRlZmF1bHRTdWNjZXNzSGFuZGxlciA9IGZ1bmN0aW9uKG9iaikgewogICAgICAgICAgICAgICAgIHZhciBmb3JtU3RhdGUgPSBvcHRpb25zLmZvcm1TdGF0ZSB8fCB0aGlzLmdldEZvcm1TdGF0ZSgpLmRhdGE7CiAgICAgICAgICAgICAgICAgLy9jbG9uZSB0aGUgb2JqZWN0IHRvIGF2b2lkIHBvbGx1dGluZyB0aGUgb2xkIGNvcHkKICAgICAgICAgICAgICAgICB2YXIgcGFyYW1zID0gXy5leHRlbmQoe2Zvcm1Eb206IGZvcm1TdGF0ZS54ZmFEb219LCBmb3JtU3RhdGUucmVuZGVyQ29udGV4dCk7CgogICAgICAgICAgICAgICAgIGZvcih2YXIgcCBpbiBwYXJhbXMpIHsKICAgICAgICAgICAgICAgICB2YXIgZmllbGQgPSAkKCI8aW5wdXQ+IikuYXR0cigidHlwZSIsICJoaWRkZW4iKS5hdHRyKCJuYW1lIixwKS52YWwocGFyYW1zW3BdKTsKICAgICAgICAgICAgICAgICAkKCIjbGNmb3Jtc194ZmFmb3JtX2NvbnRhaW5lciIpLmFwcGVuZCgkKGZpZWxkKSk7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIHZhciBkYXRhRmllbGQgPSAkKCI8aW5wdXQ+IikuYXR0cigidHlwZSIsICJoaWRkZW4iKS5hdHRyKCJuYW1lIiwiZGF0YSIpLnZhbChvYmouZGF0YSk7CiAgICAgICAgICAgICAgICAgJCgiI2xjZm9ybXNfeGZhZm9ybV9jb250YWluZXIiKS5hcHBlbmQoJChkYXRhRmllbGQpKTsKCiAgICAgICAgICAgICAgICAgdmFyIHN1Ym1pdFNlcnZpY2VQcm94eUNvbmZpZyA9IHRoaXMudXNlckNvbmZpZ1sic3VibWl0U2VydmljZVByb3h5Q29uZmlnIl07CiAgICAgICAgICAgICAgICAgdmFyIHN1Ym1pdFVybCA9IG9wdGlvbnMuYWN0aW9uIHx8IHN1Ym1pdFNlcnZpY2VQcm94eUNvbmZpZy5zdWJtaXRVcmw7CiAgICAgICAgICAgICAgICAgJCgiI2xjZm9ybXNfeGZhZm9ybV9jb250YWluZXIiKS5hdHRyKCJhY3Rpb24iLCBzdWJtaXRVcmwpOwogICAgICAgICAgICAgICAgICQoIiNsY2Zvcm1zX3hmYWZvcm1fY29udGFpbmVyIikuc3VibWl0KCk7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIG9wdGlvbnMuc3VjY2VzcyA9IG9wdGlvbnMuc3VjY2VzcyB8fCBkZWZhdWx0U3VjY2Vzc0hhbmRsZXIqLwogICAgICAgICAgICAgICAgLy9TdWJtaXQgZnJvbSBmb3JtIGJyaWRnZSBhcGkKCiAgICAgICAgICAgICAgICBvcHRpb25zLnN1Y2Nlc3MgPSAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQudWlVbkZyZWV6ZSgpOyAgLy8gQnVnOiBMQy02MDY4IFRvIHJlc3RvcmUgY3Vyc29yIGZyb20gd2FpdCBzdGF0ZSBhbmQgYWxzbyByZXN0b3JpbmcgdGhlIHVpIGJ5IG1hcmtpbmcgcm9vdCBzdWJmb3JtIGFjY2VzcyBhcyBpdHMgb2xkIGFjY2Vzcy4KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9yaWdpbmFsU3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxTdWNjZXNzLmFwcGx5KG9yaWdpbmFsQ29udGV4dCwgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgfSkoKTsKICAgICAgICAgICAgICAgIGZvcm1CcmlkZ2UuZG9BamF4U3VibWl0KG9wdGlvbnMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgLy9BbHdheXMgc3VibWl0IGZvcm0gc3RhdGUgdG8gc3VibWl0U2VydmljZVByb3h5IGFuZCB0aGVuIHRoZSBwcm94eSB3aWxsIGluLXR1cm4gc3VibWl0IHRoZSBkYXRhIHhtbCB0byB0aGUgc3VibWl0VXJsIG9uIGJlaGFsZiBvZiBNb2JpbGVGb3JtCiAgICAgICAgICAgICAgICAvL2NyZWF0ZSBhIHBzdWVkbyBmb3JtIGVsZW1lbnQgYW5kIGRvIHN1Ym1pc3Npb24KICAgICAgICAgICAgICAgIHZhciBjb250ID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHZhciBiZWhhdmlvckNvbmZpZyA9IG5ldyB4ZmFsaWIudXQuVmVyc2lvbihmb3JtQnJpZGdlLnVzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl0pOwogICAgICAgICAgICAgICAgLy9UbyBtYWludGFpbiBiYWNrd2FyZCBjb21wYXRpYmlsaXR5CiAgICAgICAgICAgICAgICBpZiAoIWJlaGF2aW9yQ29uZmlnLmlzT24oJ2Rpc2FibGVIZWFkUmVxdWVzdCcpICYmICFiZWhhdmlvckNvbmZpZy5pc09uKCdtZkRpc2FibGVIZWFkUmVxdWVzdCcpKSB7CiAgICAgICAgICAgICAgICAgICAgJC5hamF4KHsKICAgICAgICAgICAgICAgICAgICAgICAgYXN5bmM6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICB1cmw6IHRoaXMuX2dldFN1Ym1pdFNlcnZpY2VQcm94eVVybCgpLAogICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnSEVBRCcsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOiBmdW5jdGlvbiAoeGhyLCB0eHRTdGF0dXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtc2cgPSBmb3JtQnJpZGdlLl9pZGVudGlmeUNvbm5lY3Rpb25FcnJvcih4aHIsIHR4dFN0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobXNnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmNvbXBsZXRlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDIsIG1zZywgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmVycm9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuZXJyb3IuY2FsbChvcHRpb25zLmNvbnRleHQsIG9iaik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3JtQnJpZGdlLl94ZmEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUJyaWRnZS5feGZhLmhvc3QubWVzc2FnZUJveChtc2cpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ID0gZmFsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChjb250KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGFjdGlvbiA9IHRoaXMuX2dldFN1Ym1pdFNlcnZpY2VQcm94eVVybCgpOwoKICAgICAgICAgICAgICAgICAgICB2YXIgc3VibWl0U2VydmljZVByb3h5Q29uZmlnID0gdGhpcy51c2VyQ29uZmlnWyJzdWJtaXRTZXJ2aWNlUHJveHlDb25maWciXTsKCiAgICAgICAgICAgICAgICAgICAgdmFyIHBzdWVkb0Zvcm0gPSAkKCI8Zm9ybT4iKTsKCiAgICAgICAgICAgICAgICAgICAgdmFyIGZvcm1TdGF0ZSA9IG9wdGlvbnMuZm9ybVN0YXRlIHx8IHRoaXMuZ2V0Rm9ybVN0YXRlKHRydWUsIDMpLmRhdGE7CgogICAgICAgICAgICAgICAgICAgIC8vYWRkIHRoZSBhZGRpdGlvbmFsSW5mb3JtYXRpb24KICAgICAgICAgICAgICAgICAgICBfLmVhY2goZm9ybVN0YXRlLmFkZGl0aW9uYWxTdWJtaXRJbmZvcm1hdGlvbi5mb3JtQXR0cmlidXRlc0RhdGEsZnVuY3Rpb24odmFsdWUsa2V5KXsKICAgICAgICAgICAgICAgICAgICAgICAgcHN1ZWRvRm9ybS5hdHRyKGtleSwgdmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0sdGhpcyk7CgogICAgICAgICAgICAgICAgICAgIC8vb3ZlcnJpZGUgYWN0aW9uCiAgICAgICAgICAgICAgICAgICAgcHN1ZWRvRm9ybS5hdHRyKCJhY3Rpb24iLCBhY3Rpb24pOwoKICAgICAgICAgICAgICAgICAgICAvL0FkZCBfY2hhcnNldF8gdG8gbGV0IHNsaW5nIGtub3cgdGhhdCBpdCBzaG91bGQgZGVjb2RlIGluIFVURi04CiAgICAgICAgICAgICAgICAgICAgdmFyICRjaGFyU2V0RmllbGQgPSAkKCI8aW5wdXQ+IikuYXR0cigidHlwZSIsICJoaWRkZW4iKS5hdHRyKCJuYW1lIiwgIl9jaGFyc2V0XyIpLnZhbCgiVVRGLTgiKTsKICAgICAgICAgICAgICAgICAgICAkKHBzdWVkb0Zvcm0pLmFwcGVuZCgkY2hhclNldEZpZWxkKTsKCiAgICAgICAgICAgICAgICAgICAgYmVoYXZpb3JDb25maWcgPSB0aGlzLnVzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl07CgogICAgICAgICAgICAgICAgICAgIC8vYWRkIHN1cHBvcnRpbmcgZmllbGRzIHRvIHBzdWVkbyBmb3JtCiAgICAgICAgICAgICAgICAgICAgc3VibWl0U2VydmljZVByb3h5Q29uZmlnLnN1Ym1pdFVybCA9IG9wdGlvbnMuYWN0aW9uIHx8IHN1Ym1pdFNlcnZpY2VQcm94eUNvbmZpZy5zdWJtaXRVcmw7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgZmllbGROYW1lIGluIHN1Ym1pdFNlcnZpY2VQcm94eUNvbmZpZykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3VibWl0U2VydmljZVByb3h5Q29uZmlnW2ZpZWxkTmFtZV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdGaWVsZCA9ICQoIjxpbnB1dD4iKS5hdHRyKCJ0eXBlIiwgImhpZGRlbiIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoIm5hbWUiLCBmaWVsZE5hbWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnZhbChzdWJtaXRTZXJ2aWNlUHJveHlDb25maWdbZmllbGROYW1lXSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJChwc3VlZG9Gb3JtKS5hcHBlbmQoJChuZXdGaWVsZCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBmaWxlQXR0YWNobWVudEVuYWJsZWQgPSBmb3JtQnJpZGdlLl9pc0ZpbGVBdHRhY2htZW50RW5hYmxlZCgpOwogICAgICAgICAgICAgICAgICAgIGlmICghZmlsZUF0dGFjaG1lbnRFbmFibGVkKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAvL2Nsb25lIHRoZSBvYmplY3QgdG8gYXZvaWQgcG9sbHV0aW5nIHRoZSBvbGQgY29weQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyYW1zID0gXy5leHRlbmQoe30sIGZvcm1TdGF0ZS5jdXN0b21Qcm9wZXJ0eU1hcCwge2Zvcm1Eb206IGZvcm1TdGF0ZS54ZmFEb219LCBmb3JtU3RhdGUucmVuZGVyQ29udGV4dCk7CgogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBwYXJhbSBpbiBwYXJhbXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJhbXNbcGFyYW1dKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld0ZpZWxkID0gJCgiPGlucHV0PiIpLmF0dHIoInR5cGUiLCAiaGlkZGVuIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoIm5hbWUiLCBwYXJhbSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnZhbChwYXJhbXNbcGFyYW1dKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJChwc3VlZG9Gb3JtKS5hcHBlbmQoJChuZXdGaWVsZCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvL2ZvciBJRSBhcyB5b3UgY2Fubm90IHN1Ym1pdCBhIGZvcm0gd2l0aG91dCBhdHRhY2hpbmcgaXQgdG8gZG9jdW1lbnQuCiAgICAgICAgICAgICAgICAgICAgICAgICQoIiNsY2Zvcm1zX3hmYWZvcm1fY29udGFpbmVyIikuYXBwZW5kKCQocHN1ZWRvRm9ybSkpOwogICAgICAgICAgICAgICAgICAgICAgICAkKHBzdWVkb0Zvcm0pLnN1Ym1pdCgpOwoKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZpbGVBdHRhY2htZW50TWFwID0gZm9ybUJyaWRnZS5fZ2V0RmlsZU5hbWVQYXRoTWFwKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlQXR0YWNobWVudElucHV0cyA9IGZvcm1CcmlkZ2UuX2dldEZpbGVMaXN0RnJvbUZpbGVXaWRnZXQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVBdHRhY2htZW50TWFwSW5wdXQgOwogICAgICAgICAgICAgICAgICAgICAgICAvL2Nsb25lIHRoZSBvYmplY3QgdG8gYXZvaWQgcG9sbHV0aW5nIHRoZSBvbGQgY29weQogICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBfLmV4dGVuZCh7fSwgZm9ybVN0YXRlLmN1c3RvbVByb3BlcnR5TWFwLCB7Zm9ybURvbTogZm9ybVN0YXRlLnhmYURvbX0sIGZvcm1TdGF0ZS5yZW5kZXJDb250ZXh0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAocGFyYW0gaW4gcGFyYW1zKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyYW1zW3BhcmFtXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdGaWVsZCA9ICQoIjxpbnB1dD4iKS5hdHRyKCJ0eXBlIiwgImhpZGRlbiIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJuYW1lIiwgcGFyYW0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC52YWwocGFyYW1zW3BhcmFtXSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQocHN1ZWRvRm9ybSkuYXBwZW5kKCQobmV3RmllbGQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBfLmVhY2goZm9ybUJyaWRnZS5fZ2V0Q29tbWl0VmFsdWVGcm9tRmlsZVdpZGdldCgpLCBmdW5jdGlvbiAobmFtZU9mRmlsZSwgaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBfLmlzT2JqZWN0KGZpbGVBdHRhY2htZW50SW5wdXRzW2luZGV4XSkgJiYgXy5pc1N0cmluZyhuYW1lT2ZGaWxlKSAmJiAhbmFtZU9mRmlsZS5tYXRjaCgvXC8vZykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlQXR0YWNobWVudElucHV0c1tpbmRleF0uYXR0cigibmFtZSIsIG5hbWVPZkZpbGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCFmaWxlQXR0YWNobWVudE1hcFtuYW1lT2ZGaWxlXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlQXR0YWNobWVudE1hcFtuYW1lT2ZGaWxlXSA9IiI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQocHN1ZWRvRm9ybSkuYXBwZW5kKGZpbGVBdHRhY2htZW50SW5wdXRzW2luZGV4XSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUF0dGFjaG1lbnRNYXBJbnB1dCA9ICAkKCI8aW5wdXQ+IikuYXR0cigidHlwZSIsICJoaWRkZW4iKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoIm5hbWUiLCAiZmlsZUF0dGFjaG1lbnRNYXAiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLnZhbChKU09OLnN0cmluZ2lmeShmaWxlQXR0YWNobWVudE1hcCkpOwogICAgICAgICAgICAgICAgICAgICAgICAkKHBzdWVkb0Zvcm0pLmFwcGVuZCgkKGZpbGVBdHRhY2htZW50TWFwSW5wdXQpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vZm9yIElFIGFzIHlvdSBjYW5ub3Qgc3VibWl0IGEgZm9ybSB3aXRob3V0IGF0dGFjaGluZyBpdCB0byBkb2N1bWVudC4KICAgICAgICAgICAgICAgICAgICAgICAgJCgiI2xjZm9ybXNfeGZhZm9ybV9jb250YWluZXIiKS5hcHBlbmQoJChwc3VlZG9Gb3JtKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICQocHN1ZWRvRm9ybSkuc3VibWl0KCk7CgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvL2lmIHN1Ym1pdCBpcyBzdWNjZXNzZnVsLCB3ZSBuYXZpZ2F0ZSB0byBhbm90aGVyIHBhZ2Ugc28gbm8gbmVlZCB0byBjYWxsIHVpVW5GcmVlemUuCiAgICAgICAgfSwKCiAgICAgICAgdWlGcmVlemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyICR4ZmFfdWlfZnJlZXplID0gJCgnI2xjZm9ybXNfeGZhZm9ybV9jb250YWluZXIgPiAjeGZhX3VpX2ZyZWV6ZScpOwogICAgICAgICAgICBpZiAoJHhmYV91aV9mcmVlemUubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgJHhmYV91aV9mcmVlemUuc2hvdygpCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkKCcjbGNmb3Jtc194ZmFmb3JtX2NvbnRhaW5lcicpLmFwcGVuZCgnPGRpdiBpZD0ieGZhX3VpX2ZyZWV6ZSI+PC9kaXY+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICB1aVVuRnJlZXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICQoJyNsY2Zvcm1zX3hmYWZvcm1fY29udGFpbmVyID4gI3hmYV91aV9mcmVlemUnKS5oaWRlKCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0IGFsbCB0aGUgZmllbGRzIGluIHRoZSBmb3JtLgogICAgICAgICAqIEBwYXJhbSBmaWx0ZXIgZmlsdGVyIGZ1bmN0aW9uIHRvIHRlbGwgd2hpY2ggZmllbGRzIHRvIHJldHVybi4gVGhlCiAgICAgICAgICogICAgICAgICAgICAgICBmdW5jdGlvbiB3aWxsIGJlIHBhc3NlZCBlYWNoIGZpZWxkIGluIHRoZSBmb3JtIGFuZCBpZgogICAgICAgICAqICAgICAgICAgICAgICAgaXQgcmV0dXJucyB0cnVlIHRoZSBmaWVsZCB3aWxsIGJlIHJldHVybmVkIG90aGVyd2lzZSBub3QuCiAgICAgICAgICogICAgICAgICAgICAgICAqKkRvZXNuJ3QgcmV0dXJuIE1hc3RlciBQYWdlIEZpZWxkcyoqCiAgICAgICAgICogICAgICAgICAgICAgICAqKlJlbmRlcnMgYWxsIHBhZ2VzIGluIHRoZSBwcm9jZXNzKioKICAgICAgICAgKiBAcmV0dXJuIHtBcnJheX0KICAgICAgICAgKi8KICAgICAgICBnZXRBbGxGaWVsZHM6IGZ1bmN0aW9uIChmaWx0ZXIpIHsKICAgICAgICAgICAgdmFyIGFsbEZpZWxkcyA9IFtdOwogICAgICAgICAgICBmb3IgKHZhciBwYWdlID0gMDsgcGFnZSA8IHRoaXMuX3hmYS5sYXlvdXQucGFnZUNvdW50KCk7IHBhZ2UrKykgewogICAgICAgICAgICAgICAgdmFyIHBhZ2VGaWVsZHMgPSB0aGlzLl94ZmEubGF5b3V0LnBhZ2VDb250ZW50KHBhZ2UsICJmaWVsZCIpOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYWdlRmllbGRzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGZpZWxkID0gcGFnZUZpZWxkcy5pdGVtKGkpOwogICAgICAgICAgICAgICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKGZpbHRlcikgfHwgXy5pc051bGwoZmlsdGVyKSB8fCBmaWx0ZXIuYXBwbHkod2luZG93LCBbZmllbGRdKSA9PT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBhbGxGaWVsZHMucHVzaChmaWVsZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBhbGxGaWVsZHM7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0IHRoZSBjdXJyZW50IGZpZWxkIGluIGZvY3VzLgogICAgICAgICAqIEByZXR1cm4geyp9CiAgICAgICAgICovCiAgICAgICAgZ2V0Rm9jdXM6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKHRoaXMuX3hmYS5ob3N0LmdldEZvY3VzKSB7CiAgICAgICAgICAgICAgICB2YXIgb2JqID0gdGhpcy5feGZhLmhvc3QuZ2V0Rm9jdXMoKTsKICAgICAgICAgICAgICAgIGlmIChvYmopCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3hmYS5ob3N0LmdldEZvY3VzKCkuc29tRXhwcmVzc2lvbjsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiAidW5zdXBwb3J0ZWQiOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogVmFsaWRhdGUgdGhlIGZvcm0uCiAgICAgICAgICogUnVuIGNsaWVudCBzaWRlIHZhbGlkYXRpb25zLgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICB2YWxpZGF0ZUZvcm06IGZ1bmN0aW9uIChvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogICAgICAgICAgICBvcHRpb25zLmVycm9yID0gb3B0aW9ucy5lcnJvciB8fCBkZWZhdWx0RXJyb3JIYW5kbGVyOwogICAgICAgICAgICBvcHRpb25zLmNvbnRleHQgPSBvcHRpb25zLmNvbnRleHQgfHwgdGhpczsKICAgICAgICAgICAgdmFyIHZhbE1lc3NhZ2VzID0gW107CiAgICAgICAgICAgIHZhciB2YWxpZGF0aW9uc1ZhbHVlID0gdGhpcy5feGZhLmhvc3QuX3ZhbGlkYXRlKHsKICAgICAgICAgICAgICAgIHZhbE1lc3NhZ2VzOiB2YWxNZXNzYWdlcwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIHZhciBvYmogPSBuZXcgWEZBUmVzdWx0T2JqZWN0KCk7CiAgICAgICAgICAgIGlmICghdGhpcy5fY2hlY2tYZmEob2JqKSkKICAgICAgICAgICAgICAgIHRocm93IG9iai5nZXROZXh0TWVzc2FnZSgpLm1lc3NhZ2U7CgogICAgICAgICAgICBpZiAodmFsaWRhdGlvbnNWYWx1ZSA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMCwgImNsaWVudCBzaWRlIHZhbGlkYXRpb25zIGZhaWxlZCIsICJ4ZmEiKTsKICAgICAgICAgICAgICAgIF8uZWFjaCgKICAgICAgICAgICAgICAgICAgICBfLmZpbHRlcih2YWxNZXNzYWdlcywgZnVuY3Rpb24gKG1zZykgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbXNnLnNldmVyaXR5ID09PSAiZXJyb3IiCiAgICAgICAgICAgICAgICAgICAgfSksCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKG1zZykgewogICAgICAgICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDEsIG1zZy5tZXNzYWdlLCBtc2cucmVmKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBvcHRpb25zLmVycm9yLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKG9wdGlvbnMuc3VjY2VzcykKICAgICAgICAgICAgICAgIG9wdGlvbnMuc3VjY2Vzcy5jYWxsKG9wdGlvbnMuY29udGV4dCwgb2JqKTsKCiAgICAgICAgICAgIHJldHVybiB2YWxpZGF0aW9uc1ZhbHVlOwogICAgICAgIH0sCiAgICAgICAgLy8tLWNoZWNraW5nIGZvciBicm93c2VyIGNvbXBhdGliaWxpdHkKICAgICAgICBfaXNCcm93c2VyQ29tcGF0aWJsZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgaXNXaW4gPSBmYWxzZTsKICAgICAgICAgICAgdmFyIGlzTWFjID0gZmFsc2U7CiAgICAgICAgICAgIHZhciBpc2lQYWQgPSBmYWxzZTsKICAgICAgICAgICAgdmFyIGlzQW5kcm9pZCA9IGZhbHNlOwogICAgICAgICAgICB2YXIgaXNXZWJLaXQgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5hcHBWZXJzaW9uLmluZGV4T2YoIldpbiIpICE9IC0xKQogICAgICAgICAgICAgICAgaXNXaW4gPSB0cnVlOwogICAgICAgICAgICBlbHNlIGlmIChuYXZpZ2F0b3IuYXBwVmVyc2lvbi5pbmRleE9mKCJNYWMiKSAhPSAtMSkKICAgICAgICAgICAgICAgIGlzTWFjID0gdHJ1ZTsKICAgICAgICAgICAgZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBhZC9pKSAhPSBudWxsKQogICAgICAgICAgICAgICAgaXNpUGFkID0gdHJ1ZTsKICAgICAgICAgICAgZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpLmluZGV4T2YoImFuZHJvaWQiKSA+IC0xKQogICAgICAgICAgICAgICAgaXNBbmRyb2lkID0gdHJ1ZTsKICAgICAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5pbmRleE9mKCJ3ZWJraXQiKSA+IC0xKQogICAgICAgICAgICAgICAgaXNXZWJLaXQgPSB0cnVlOwoKICAgICAgICAgICAgdmFyIGJyb3dzZXJWZXJzaW9uID0gcGFyc2VJbnQoJC5icm93c2VyLnZlcnNpb24sIDEwKTsKICAgICAgICAgICAgaWYgKGlzV2luICYmICgkLmJyb3dzZXIubXNpZSAmJiAoYnJvd3NlclZlcnNpb24gPT0gNiB8fCBicm93c2VyVmVyc2lvbiA9PSA3IHx8IGJyb3dzZXJWZXJzaW9uID09IDgpKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgZWxzZSBpZiAoaXNXaW4gJiYgKGlzV2ViS2l0IHx8ICQuYnJvd3Nlci5tb3ppbGxhIHx8ICgkLmJyb3dzZXIubXNpZSAmJiAoYnJvd3NlclZlcnNpb24gPT0gOSB8fCBicm93c2VyVmVyc2lvbiA9PSAxMCkpKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoKGlzTWFjIHx8IGlzaVBhZCB8fCBpc0FuZHJvaWQpICYmIGlzV2ViS2l0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgLyoKICAgICAgICAgKiBSZXN0b3JlcyB0aGUgRm9ybSBTdGF0ZSB0byBhIHByZXZpb3VzIHN0YXRlLiBUaGlzIGlzIGEgQXN5bmNocm9ub3VzIGNhbGwgYW5kIHJlY2lldmVzIGEgZm9ybVN0YXRlIGZyb20gdGhlCiAgICAgICAgICogY2FsbGVyLiBUaGUgc3RhdGUgd2lsbCBiZSBhcHBsaWVkIGFuZCBzdWNjZXNzIG9yIGVycm9yIGhhbmRsZXJzIHdpbGwgYmUgY2FsbGVkIGFmdGVyIHRoZSBvcGVyYXRpb24gaXMKICAgICAgICAgKiBjb21wbGV0ZWQuCiAgICAgICAgICovCiAgICAgICAgcmVzdG9yZUZvcm1TdGF0ZTogZnVuY3Rpb24gKG9wdGlvbnMpIHsKICAgICAgICAgICAgaWYgKHdpbmRvdy5hdG9iICYmIG9wdGlvbnMuYmFzZTY0Rm9ybVN0YXRlICE9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgIC8vIERlY29kZSBiYXNlIDY0IGVuY29kZWQgc3RyaW5nIHRvIGZvcm0gdGhlIGZvcm0gRE9NIG9iamVjdC4KICAgICAgICAgICAgICAgIHZhciB1dGZ0ZXh0ID0gYXRvYihvcHRpb25zLmJhc2U2NEZvcm1TdGF0ZSksCiAgICAgICAgICAgICAgICAgICAgc3RyaW5nID0gIiIsCiAgICAgICAgICAgICAgICAgICAgaSA9IDAsCiAgICAgICAgICAgICAgICAgICAgYyA9IDAsCiAgICAgICAgICAgICAgICAgICAgYzEgPSAwLAogICAgICAgICAgICAgICAgICAgIGMyID0gMCwKICAgICAgICAgICAgICAgICAgICBjMyA9IDA7CiAgICAgICAgICAgICAgICB3aGlsZSAoIGkgPCB1dGZ0ZXh0Lmxlbmd0aCApIHsKICAgICAgICAgICAgICAgICAgICBjID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkpOwogICAgICAgICAgICAgICAgICAgIGlmIChjIDwgMTI4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpOwogICAgICAgICAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoKGMgPiAxOTEpICYmIChjIDwgMjI0KSkgewogICAgICAgICAgICAgICAgICAgICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpKzEpOwogICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgJiAzMSkgPDwgNikgfCAoYzIgJiA2MykpOwogICAgICAgICAgICAgICAgICAgICAgICBpICs9IDI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpKzEpOwogICAgICAgICAgICAgICAgICAgICAgICBjMyA9IHV0ZnRleHQuY2hhckNvZGVBdChpKzIpOwogICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgJiAxNSkgPDwgMTIpIHwgKChjMiAmIDYzKSA8PCA2KSB8IChjMyAmIDYzKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGkgKz0gMzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB1dGZ0ZXh0ID0gc3RyaW5nOwogICAgICAgICAgICAgICAgdmFyIGZvcm1Eb20gPSBKU09OLnBhcnNlKHV0ZnRleHQpOwogICAgICAgICAgICAgICAgb3B0aW9ucy5mb3JtU3RhdGUgPSBmb3JtRG9tOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBXZSBoYXZlIHRvIG1lcmdlIHRoZSBydW50aW1lIHJlbmRlckNvbnRleHQgd2l0aCB0aGUgcmVuZGVyQ29udGV4dCBvZiB0aGUgZm9ybVN0YXRlIHBhc3NlZAogICAgICAgICAgICAgKiBzbyB0aGF0IG5vIGN1c3RvbSBwcm9wZXJ0aWVzIHRoYXQgd2VyZSBzZXQgaW4gdGhlIGNvbnRleHQocHJlc2VudCBpbiB0aGUgZm9ybSBzdGF0ZSkgYXJlIGlnbm9yZWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB4ZmFsaWIucnVudGltZS5yZW5kZXJDb250ZXh0ID0geGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dCB8fCB7fTsKICAgICAgICAgICAgXy5leHRlbmQoeGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dCwgb3B0aW9ucy5mb3JtU3RhdGUucmVuZGVyQ29udGV4dCk7CiAgICAgICAgICAgIGlmICghdGhpcy5feGZhKSB7CiAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UgPSB7fTsKICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5mb3JtU3RhdGUgPSBvcHRpb25zLmZvcm1TdGF0ZTsKICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5lcnJvciA9IG9wdGlvbnMuZXJyb3I7CiAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2Uuc3VjY2VzcyA9IG9wdGlvbnMuc3VjY2VzczsKICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5jb250ZXh0ID0gb3B0aW9ucy5jb250ZXh0OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5feGZhLmhvc3QucGxheUpzb24oSlNPTi5wYXJzZShvcHRpb25zLmZvcm1TdGF0ZS54ZmFEb20pKTsKICAgICAgICAgICAgICAgIHRoaXMuY3VzdG9tQ29udGV4dFByb3BlcnR5KG9wdGlvbnMuZm9ybVN0YXRlLmN1c3RvbVByb3BlcnR5TWFwKTsKICAgICAgICAgICAgICAgIGlmKF8uaXNGdW5jdGlvbihvcHRpb25zLnN1Y2Nlc3MpKSB7CiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zdWNjZXNzLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGN1c3RvbUNvbnRleHRQcm9wZXJ0eTogZnVuY3Rpb24ocHJvcGVydHksdmFsdWUpIHsKICAgICAgICAgICAgdmFyIGN1c3RvbVByb3BlcnR5TWFwID0geGZhbGliLnJ1bnRpbWUuY3VzdG9tUHJvcGVydHlNYXAgfHwge307CiAgICAgICAgICAgIGlmKF8uaXNVbmRlZmluZWQodmFsdWUpKSB7CiAgICAgICAgICAgICAgICBpZihfLmlzT2JqZWN0KHByb3BlcnR5KSkgewogICAgICAgICAgICAgICAgICAgIF8uZXh0ZW5kKGN1c3RvbVByb3BlcnR5TWFwLCBwcm9wZXJ0eSk7CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuY3VzdG9tUHJvcGVydHlNYXA9Y3VzdG9tUHJvcGVydHlNYXA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGN1c3RvbVByb3BlcnR5TWFwW3Byb3BlcnR5XTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBvbGRWYWx1ZSA9IGN1c3RvbVByb3BlcnR5TWFwW3Byb3BlcnR5XTsKICAgICAgICAgICAgICAgIGN1c3RvbVByb3BlcnR5TWFwW3Byb3BlcnR5XT1lbmNvZGVVUklDb21wb25lbnQodmFsdWUpOwogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuY3VzdG9tUHJvcGVydHlNYXA9Y3VzdG9tUHJvcGVydHlNYXA7CiAgICAgICAgICAgICAgICByZXR1cm4gb2xkVmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIC8qCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfZ2V0U3RvcmFnZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgcyA9IG51bGw7CiAgICAgICAgICAgIGlmICh0aGlzLnN0b3JhZ2UpIHsKICAgICAgICAgICAgICAgIHZhciBzID0gdGhpcy5zdG9yYWdlLmZvcm1TdGF0ZQogICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLmZvcm1TdGF0ZSA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSwKCiAgICAgICAgX2dldFhtbFN0b3JhZ2U6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHMgPSBudWxsOwogICAgICAgICAgICBpZiAodGhpcy54bWxTdG9yYWdlKSB7CiAgICAgICAgICAgICAgICB2YXIgcyA9IHRoaXMueG1sU3RvcmFnZS54bWxEb2N1bWVudDsKICAgICAgICAgICAgICAgIHRoaXMueG1sU3RvcmFnZS54bWxEb2N1bWVudCA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9nZXRIVE1MRWxlbWVudDogZnVuY3Rpb24gKHNvbUV4cHJlc3Npb24sIGZ1bGwpIHsKICAgICAgICAgICAgdmFyIG9iaiA9IHRoaXMuX2dldEhUTUxFbGVtZW50SW50ZXJuYWwoc29tRXhwcmVzc2lvbiwgZnVsbCx0aGlzLl9mb3JtRG9jKTsKICAgICAgICAgICAgcmV0dXJuIG9iajsKICAgICAgICB9LAoKICAgICAgICBfZ2V0SFRNTEVsZW1lbnRJbnRlcm5hbDogZnVuY3Rpb24oc29tRXhwcmVzc2lvbiwgZnVsbCxyZWZlcmVuY2VEb2N1bWVudCl7CiAgICAgICAgICAgIHNvbUV4cHJlc3Npb24gPSBmdWxsID09PSB0cnVlID8gc29tRXhwcmVzc2lvbiA6ICJ4ZmFbMF0uZm9ybVswXS4iICsgc29tRXhwcmVzc2lvbjsKICAgICAgICAgICAgdmFyIG9iaiA9IG5ldyBYRkFSZXN1bHRPYmplY3QoKTsKICAgICAgICAgICAgaWYgKCF0aGlzLl9jaGVja1hmYShvYmopKQogICAgICAgICAgICAgICAgcmV0dXJuIG9iajsKICAgICAgICAgICAgdmFyIGVsZW0gPSB0aGlzLl94ZmEucmVzb2x2ZU5vZGUoc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgIGlmIChfLmlzRW1wdHkoZWxlbSkpewogICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMCwgc29tRXhwcmVzc2lvbiArICIgbm90IGZvdW5kIiwgc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgZWxlbUlkID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmpxSWQoZWxlbS5odG1sSWQpOwogICAgICAgICAgICAgICAgJChlbGVtSWQsIHJlZmVyZW5jZURvY3VtZW50KS5jaGlsZHJlbigpOwogICAgICAgICAgICAgICAgc3dpdGNoIChlbGVtLmNsYXNzTmFtZSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgImluc3RhbmNlTWFuYWdlciI6CiAgICAgICAgICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDAsICJObyBIVE1MIEVsZW1lbnQgZXhpc3RzIGZvciBpbnN0YW5jZU1hbmFnZXJzIiwgc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgInN1YmZvcm0iOgogICAgICAgICAgICAgICAgICAgICAgICBvYmouZGF0YSA9IHtlbGVtOiAkKGVsZW1JZCwgcmVmZXJlbmNlRG9jdW1lbnQpWzBdfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJmaWVsZCI6CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkYXRhID0gJChlbGVtSWQsIHJlZmVyZW5jZURvY3VtZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gZGF0YS5jaGlsZHJlbigpOwoKICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmRhdGEgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtOiBkYXRhWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwdGlvbjogY2hpbGRbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWRnZXQ6IHsgZWxlbTogY2hpbGRbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQ6ICQoImlucHV0LHNlbGVjdCIsIGNoaWxkWzFdKVswXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9iai5kYXRhLndpZGdldCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmRhdGEud2lkZ2V0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW06IGNoaWxkWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkOiAkKCJpbnB1dCxzZWxlY3QiLCBjaGlsZFswXSkgWzBdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmRhdGEgPSB7ZWxlbTogJChlbGVtSWQsIHJlZmVyZW5jZURvY3VtZW50KVswXX07CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBvYmo7CiAgICAgICAgfSwKCiAgICAgICAgX3Bvc3RFeHRlcm5hbE1lc3NhZ2U6IGZ1bmN0aW9uIChtZXNzYWdlKSB7CiAgICAgICAgICAgIGlmICh0aGlzLnVzZXJDb25maWdbInBvc3RFeHRlcm5hbE1lc3NhZ2VDb25maWciXSAmJiBfLmlzRnVuY3Rpb24odGhpcy51c2VyQ29uZmlnWyJwb3N0RXh0ZXJuYWxNZXNzYWdlQ29uZmlnIl1bInBvc3RFeHRlcm5hbEhhbmRsZXIiXSkpIHsKICAgICAgICAgICAgICAgIHZhciBleHRlcm5hbEhhbmRsZXIgPSB0aGlzLnVzZXJDb25maWdbInBvc3RFeHRlcm5hbE1lc3NhZ2VDb25maWciXVsicG9zdEV4dGVybmFsSGFuZGxlciJdOwogICAgICAgICAgICAgICAgZXh0ZXJuYWxIYW5kbGVyKG1lc3NhZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc2NhbGVGb3JtOiBmdW5jdGlvbiAodmlld3BvcnRXaWR0aCkgewogICAgICAgICAgICBpZiAodmlld3BvcnRXaWR0aCkgewogICAgICAgICAgICAgICAgdGhpcy51c2VyQ29uZmlnWyJ2aWV3cG9ydFdpZHRoIl0gPSB2aWV3cG9ydFdpZHRoOwogICAgICAgICAgICAgICAgd2luZG93LnhmYVZpZXdSZWdpc3RyeS5zY2FsZUZvcm0oKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFRoaXMgZnVuY3Rpb24gaGlkZXMgdGhlIHRvb2xiYXIgd2hlcmUgcmVxdWlyZWQuCiAgICAgICAgICogQG1lbWJlcm9mIEZvcm1CcmlkZ2UKICAgICAgICAgKi8KICAgICAgICBoaWRlVG9vbGJhcjogZnVuY3Rpb24oKXsKICAgICAgICAgICQoIi50b29sYmFyaGVhZGVyIikuaGlkZSgpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgdG8gUmVnaXN0ZXIgYW4gZXZlbnQgbGlzdGVuZXIgZm9yIHNwZWNpZmljIEZvcm0gQnJpZGdlIEV2ZW50LgogICAgICAgICAqIEBwYXJhbSBldmVudE5hbWUge3N0cmluZ30gbmFtZSBvZiB0aGUgZXZlbnQgZm9yIHdoaWNoIGxpc3RlbmVyIGhhcyB0byBiZSBhZGRlZC4gSXQgbXVzdCBiZSBvbmUgb2YgdGhlIGV2ZW50cwogICAgICAgICAqIG1lbnRpb25lZCBpbiB0aGUgZG9jdW1lbnRhdGlvbi4KICAgICAgICAgKiBAcGFyYW0gaGFuZGxlciB7ZnVuY3Rpb259IGV2ZW50IGxpc3RlbmVyIHdoaWNoIGlzIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyB0cmlnZ2VyZWQuCiAgICAgICAgICogQHBhcmFtIFtjb250ZXh0XSB7b2JqZWN0fSBjb250ZXh0IGlzIHVzZWQgYXMgdGhlIDxpPnRoaXM8L2k+IG9iamVjdCBpbnNpZGUgaGFuZGxlciBmdW5jdGlvbgogICAgICAgICAqLwoKICAgICAgICBvbjogZnVuY3Rpb24gKGV2ZW50TmFtZSwgaGFuZGxlciwgY29udGV4dCkgewogICAgICAgICAgICB0aGlzLl8kdGFyZ2V0Lm9uKGV2ZW50TmFtZSwgaGFuZGxlciwgY29udGV4dCk7CiAgICAgICAgfSwKCgogICAgICAgIC8qKgogICAgICAgICAqIFVucmVnaXN0ZXIgdGhlIGV2ZW50IHJlZ2lzdGVyZWQgdXNpbmcgdGhlIHtAbGluayBGb3JtQnJpZGdlLm9ufG9ufSBmdW5jdGlvbgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGV2ZW50TmFtZSB7c3RyaW5nfSBuYW1lIG9mIHRoZSBldmVudCB0byB1bi1yZWdpc3Rlci4KICAgICAgICAgKiBAcGFyYW0gW3NlbGVjdG9yXSB7c3RyaW5nfSBzZWxlY3RvciB3aGljaCBzaG91bGQgbWF0Y2ggdGhlIG9uZSBvcmlnaW5hbGx5IHBhc3NlZCB0byBGb3JtQnJpZGdlJ3Mgb24oKSB3aGlsZSByZWdpc3RlcmluZyBoYW5kbGVycwogICAgICAgICAqIEBwYXJhbSBbaGFuZGxlcl0ge2Z1bmN0aW9ufSBoYW5kbGVyIHdoaWNoIG5lZWRzIHRvIHVuLXJlZ2lzdGVyZWQuIElmIG5vdCBwcm92aWRlZCBhbGwgdGhlIGV2ZW50IGxpc3RlbmVycwogICAgICAgICAqIHdpbGwgYmUgdW5yZWdpc3RlcmVkCiAgICAgICAgICovCgogICAgICAgIG9mZjogZnVuY3Rpb24gKGV2ZW50TmFtZSwgc2VsZWN0b3IsIGhhbmRsZXIpIHsKICAgICAgICAgICAgdGhpcy5fJHRhcmdldC5vZmYoZXZlbnROYW1lLCBzZWxlY3RvciwgaGFuZGxlcik7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogSW50ZXJuYWwgQVBJCiAgICAgICAgICoKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwoKICAgICAgICB0cmlnZ2VyOiBmdW5jdGlvbiAoZXZlbnROYW1lLCBleHRyYVBhcmFtZXJ0cykgewogICAgICAgICAgICBpZih0aGlzLmlzQW5hbHl0aWNzRW5hYmxlZCB8fCBldmVudE5hbWUgPT0geGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5zY3JpYmJsZUNoYW5nZUV2ZW50KSB7CiAgICAgICAgICAgICAgICB0aGlzLl8kdGFyZ2V0LnRyaWdnZXIoZXZlbnROYW1lLCBleHRyYVBhcmFtZXJ0cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBjb25zdHJ1Y3RzIHRoZSBkYXRhU29tTWFwIGFuZCByZXR1cm5zIHRoYXQuIElmIGEgdmFsaWQgb2JqZWN0IGlzIHByb3ZpZGVkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCB0aGVuIGl0CiAgICAgICAgICogbW9kaWZpZXMgYW5kIGFkZHMgZW50cmllcyBpbiB0aGF0IG1hcCBvbmx5LCBvdGhlcndpc2UgY29uc3RydWN0cyBhIG5ldyBtYXAuCiAgICAgICAgICogQHBhcmFtIG1hcCB7b2JqZWN0fQogICAgICAgICAqIEByZXR1cm5zIHtYRkFSZXN1bHRPYmplY3R9IHdpdGggdGhlIGRhdGEgcGFyYW1ldGVyIGFzIHRoZSBkYXRhU29tTWFwCiAgICAgICAgICovCiAgICAgICAgZ2V0RGF0YVNvbU1hcDogZnVuY3Rpb24gKG1hcCkgewogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwogICAgICAgICAgICBpZiAoIXRoaXMuX2NoZWNrWGZhKG9iaikpIHsKICAgICAgICAgICAgICAgIHJldHVybiBvYmo7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIF9tYXAgPSBtYXA7CiAgICAgICAgICAgIGlmKCFfLmlzT2JqZWN0KG1hcCkpIHsKICAgICAgICAgICAgICAgIF9tYXAgPSB7fTsKICAgICAgICAgICAgfQogICAgICAgICAgICBfbWFwID0gdGhpcy5feGZhLmZvcm0uX2dldERhdGFTb21NYXAoX21hcCk7CiAgICAgICAgICAgIG9iai5kYXRhID0gX21hcDsKICAgICAgICAgICAgcmV0dXJuIG9iajsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBVcGRhdGVzIHRoZSBmaWVsZCB2YWx1ZXMgd2l0aCB0aGUgdmFsdWVzIHByb3ZpZGVkIGluIHRoZSBtYXAuIElmIG1hcCBpcyBub3QgYW4gb2JqZWN0LCByZXR1cm5zIGFuIGVycm9yLgogICAgICAgICAqIEBwYXJhbSBtYXAge29iamVjdH0KICAgICAgICAgKiBAcmV0dXJuIHtYRkFSZXN1bHRPYmplY3R9IHdpdGggdGhlIGRhdGEgcGFyYW1ldGVyIGFzIG51bGwuCiAgICAgICAgICovCiAgICAgICAgcmVzdG9yZURhdGFTb21NYXA6IGZ1bmN0aW9uIChtYXApIHsKICAgICAgICAgICAgdmFyIG9iaiA9IG5ldyBYRkFSZXN1bHRPYmplY3QoKTsKICAgICAgICAgICAgaWYgKCF0aGlzLl9jaGVja1hmYShvYmopKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb2JqOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKCFfLmlzT2JqZWN0KG1hcCkpIHsKICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDAsICJJbnZhbGlkIEFyZ3VtZW50IHBhc3NlZC4gRmlyc3QgYXJndW1lbnQgaGFzIHRvIGJlIGFuIG9iamVjdCIsIG51bGwpOwogICAgICAgICAgICAgICAgcmV0dXJuIG9iajsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl94ZmEuZm9ybS5fcmVzdG9yZURhdGFTb21NYXAobWFwKTsKICAgICAgICAgICAgb2JqLmRhdGEgPSBudWxsOwogICAgICAgICAgICByZXR1cm4gb2JqOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIE5hbWVzcGFjZSByZXNvbHZlciBuZWVkZWQgZm9yIHhwYXRoIHJlc29sdXRpb24uIFdlIG5lZWQgdG8gYWRkIG1vcmUgbmFtZXBzYWNlcwogICAgICAgICAqIEBwYXJhbSBwcmVmaXgKICAgICAgICAgKiBAcmV0dXJucyB7KnxudWxsfQogICAgICAgICAqLwogICAgICAgIG5zUmVzb2x2ZXIgOiBmdW5jdGlvbiAocHJlZml4KSB7CiAgICAgICAgICAgIHZhciBucyA9IHsKICAgICAgICAgICAgICAgICd4ZmEnIDogJ2h0dHA6Ly93d3cueGZhLm9yZy9zY2hlbWEveGZhLWRhdGEvMS4wLycsCiAgICAgICAgICAgICAgICAneGRwJyA6ICdodHRwOi8vbnMuYWRvYmUuY29tL3hkcC8nCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHJldHVybiBuc1twcmVmaXhdIHx8IG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogbWVyZ2VzIHRoZSBGb3JtIHdpdGggdGhlIHhtbERvY3VtZW50IHByb3ZpZGVkCiAgICAgICAgICogQHBhcmFtIG9wdGlvbnMge29iamVjdH0gd2l0aCB0aGUgZm9sbGxvd2luZyBzeW50YXgKICAgICAgICAgKiAgewogICAgICAgICAqICAgeG1sRG9jdW1lbnQKICAgICAgICAgKiAgIHN1Y2Nlc3M6IGZ1bmN0aW9uKCkge30KICAgICAgICAgKiAgIGVycm9yOiBmdW5jdGlvbih4ZmFSZXN1bHRPYmplY3QpIHt9CiAgICAgICAgICogICBjb250ZXh0OgogICAgICAgICAqICB9CiAgICAgICAgICogQHJldHVybiB7WEZBUmVzdWx0T2JqZWN0fSB3aXRoIHRoZSBkYXRhIHBhcmFtZXRlciBhcyBudWxsLgogICAgICAgICAqLwogICAgICAgIHBsYXlEYXRhWE1MOiBmdW5jdGlvbihvcHRpb25zKSB7CiAgICAgICAgICAgIGlmICghdGhpcy5feGZhKSB7CiAgICAgICAgICAgICAgICB0aGlzLnhtbFN0b3JhZ2UgPSB7fTsKICAgICAgICAgICAgICAgIHRoaXMueG1sU3RvcmFnZS54bWxEb2N1bWVudCA9IG9wdGlvbnMueG1sRG9jdW1lbnQ7CiAgICAgICAgICAgICAgICB0aGlzLnhtbFN0b3JhZ2UuZXJyb3IgPSBvcHRpb25zLmVycm9yIHx8IGRlZmF1bHRFcnJvckhhbmRsZXI7CiAgICAgICAgICAgICAgICB0aGlzLnhtbFN0b3JhZ2Uuc3VjY2VzcyA9IG9wdGlvbnMuc3VjY2VzczsKICAgICAgICAgICAgICAgIHRoaXMueG1sU3RvcmFnZS5jb250ZXh0ID0gb3B0aW9ucy5jb250ZXh0OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIG9iaiA9IG5ldyBYRkFSZXN1bHRPYmplY3QoKSwKICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fSwKICAgICAgICAgICAgICAgICAgICBlcnJvciA9IG9wdGlvbnMuZXJyb3IgfHwgZGVmYXVsdEVycm9ySGFuZGxlciwKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gb3B0aW9ucy5zdWNjZXNzLAogICAgICAgICAgICAgICAgICAgIHhtbERvY3VtZW50ID0gb3B0aW9ucy54bWxEb2N1bWVudCwKICAgICAgICAgICAgICAgICAgICByb290RWxlbWVudDsKICAgICAgICAgICAgICAgIGlmKHhtbERvY3VtZW50ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBvYmouYWRkTWVzc2FnZSgwLCAiSW52YWxpZCBBcmd1bWVudCBFcnJvci4gWE1MIERvY3VtZW50IGlzIG5vdCBkZWZpbmVkIiwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IuYXBwbHkob3B0aW9ucy5jb250ZXh0LCBbb2JqXSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYoXy5pc1N0cmluZyh4bWxEb2N1bWVudCkpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEuTG9nZ2VyLmluZm8oInhmYSIsICJ4bWxEb2N1bWVudCBpcyBvZiB0eXBlIHN0cmluZy4gY29udmVydGluZyBpdCB0byBkb2N1bWVudCIpOwogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbERvY3VtZW50ID0gJC5wYXJzZVhNTCh4bWxEb2N1bWVudCk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDIsICJVbmFibGUgdG8gcGFyc2UgRGF0YSBYTUwgIiArIGUsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5hcHBseShvcHRpb25zLmNvbnRleHQsIFtvYmpdKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKCEoeG1sRG9jdW1lbnQgaW5zdGFuY2VvZiBEb2N1bWVudCkgJiYgISh4bWxEb2N1bWVudCBpbnN0YW5jZW9mIEVsZW1lbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMSwgIkludmFsaWQgQXJndW1lbnQgRXJyb3IuIFhNTCBEb2N1bWVudCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgRG9jdW1lbnQgb3IgRWxlbWVudCIsIG51bGwpOwogICAgICAgICAgICAgICAgICAgIGVycm9yLmFwcGx5KG9wdGlvbnMuY29udGV4dCwgW29ial0pOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhLmhvc3QucGxheURhdGFYbWwoeG1sRG9jdW1lbnQpOwogICAgICAgICAgICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMiwgIlVuZXhwZWN0ZWQgRXhjZXB0aW9uOiBVbmFibGUgdG8gcGxheSBEYXRhIFhNTCAiICsgZSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IuYXBwbHkob3B0aW9ucy5jb250ZXh0LCBbb2JqXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihzdWNjZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzcy5hcHBseShvcHRpb25zLmNvbnRleHQsW29ial0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyBEYXRhIFhNTCBvZiB0aGUgRm9ybS4gSWYgZGF0YVhNTCBpcyBwYXNzZWQsIGl0IGlzIG1lcmdlZCB3aXRoCiAgICAgICAgICogdGhlIERhdGEgWE1MLgogICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8Tm9kZX0gSWYgZGF0YVhNTCBpbnB1dCBpcyBTdHJpbmcsIGl0IHJldHVybnMgc3RyaW5nLCBvdGhlcndpc2UKICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFYTUwgaXMgdXBkYXRlZCBhbmQgcmV0dXJuZWQKICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIFJldHVybnMgbnVsbCBpbiBjYXNlIGl0IGZhaWxzIHRvIGdlbmVyYXRlIGRhdGEgeG1sLgogICAgICAgICAqIEBwYXJhbSBiR2VuZXJhdGVYRFBSb290IHdoZXRoZXIgdG8gZ2VuZXJhdGUgdGhlIHhkcCByb290IGlmIGl0IGRvZXNuJ3QgZXhpc3RzCiAgICAgICAgICogQHBhcmFtIGRhdGFYTUwge0VsZW1lbnR8RG9jdW1lbnR8U3RyaW5nfSBJZiBkYXRhWE1MIHBhc3NlZCBpcyBkb2N1bWVudCBvciBFbGVtZW50LCBpdCB1cGRhdGVzIHRoYXQgYW5kCiAgICAgICAgICogcmV0dXJucyBpdC4gSW4gY2FzZSBvZiBzdHJpbmcgYSBuZXcgc3RyaW5nIGlzIHJldHVybmVkLgogICAgICAgICAqLwogICAgICAgIGdlbmVyYXRlRGF0YVhNTDogZnVuY3Rpb24gKGRhdGFYTUwsIGJHZW5lcmF0ZVhEUFJvb3QpIHsKICAgICAgICAgICAgaWYoXy5pc1VuZGVmaW5lZChkb2N1bWVudC5ldmFsdWF0ZSkpIHsKICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gZG8gaXQgaGVyZSBzaW5jZSBYUGF0aFJlc3VsdCBpcyBhbHNvIHVuZGVmaW5lZCBpbiBJRQogICAgICAgICAgICAgICAgd2d4cGF0aC5pbnN0YWxsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHZhciBwcmVmaWxsWE1MID0gZGF0YVhNTCB8fCB4ZmFsaWIucnVudGltZS5yZW5kZXJDb250ZXh0LmRhdGEsCiAgICAgICAgICAgICAgICAgICAgcm9vdFN1YmZvcm0gPSB0aGlzLl94ZmEuZm9ybS5fZ2V0Um9vdFN1YmZvcm0oKSwKICAgICAgICAgICAgICAgICAgICBiQWRkWERQUm9vdCA9ICEoYkdlbmVyYXRlWERQUm9vdCA9PT0gZmFsc2UpLAogICAgICAgICAgICAgICAgICAgIGltcGwsIHhtbERvYywgeGRwRWxlbWVudCwgZGF0YXNldHMsIGRhdGEsIHJvb3ROb2RlLCB4UGF0aFJlc3VsdCwgbmV3WG1sRG9jOwogICAgICAgICAgICAgICAgaWYgKHByZWZpbGxYTUwgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGltcGwgICAgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbjsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MgID0gaW1wbC5jcmVhdGVEb2N1bWVudCAoJ2h0dHA6Ly9ucy5hZG9iZS5jb20veGRwLycsICd4ZHA6eGRwJywgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgZGF0YXNldHMgPSB4bWxEb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnhmYS5vcmcvc2NoZW1hL3hmYS1kYXRhLzEuMC8iLCAieGZhOmRhdGFzZXRzIik7CiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHhtbERvYy5jcmVhdGVFbGVtZW50KCJ4ZmE6ZGF0YSIpOwogICAgICAgICAgICAgICAgICAgIHJvb3ROb2RlID0geG1sRG9jLmNyZWF0ZUVsZW1lbnQocm9vdFN1YmZvcm0uZ2V0QXR0cmlidXRlKCJuYW1lIikpOwogICAgICAgICAgICAgICAgICAgIGRhdGEuYXBwZW5kQ2hpbGQocm9vdE5vZGUpOwogICAgICAgICAgICAgICAgICAgIGRhdGFzZXRzLmFwcGVuZENoaWxkKGRhdGEpOwogICAgICAgICAgICAgICAgICAgIHhtbERvYy5kb2N1bWVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoZGF0YXNldHMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MgPSBwcmVmaWxsWE1MOwogICAgICAgICAgICAgICAgICAgIGlmKF8uaXNTdHJpbmcoeG1sRG9jKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEuTG9nZ2VyLmluZm8oInhmYSIsICJ4bWxEb2N1bWVudCBpcyBvZiB0eXBlIHN0cmluZy4gY29udmVydGluZyBpdCB0byBkb2N1bWVudCIpCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbERvYyA9ICQucGFyc2VYTUwoeG1sRG9jKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcm9vdE5vZGUgPSB4ZmFsaWIudXQuWE1MVXRpbHMuZ2V0WEZBUm9vdEZvcm1FbGVtZW50RnJvbVhNTCh4bWxEb2MpOwogICAgICAgICAgICAgICAgICAgIHZhciB4bWxEb2NFbGVtZW50ID0geG1sRG9jIGluc3RhbmNlb2YgRWxlbWVudCA/IHhtbERvYyA6IHhtbERvYy5kb2N1bWVudEVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJBZGRYRFBSb290ICYmIHhtbERvY0VsZW1lbnQubm9kZU5hbWUgIT09ICJ4ZHA6eGRwIikgewogICAgICAgICAgICAgICAgICAgICAgICBpbXBsICAgID0gZG9jdW1lbnQuaW1wbGVtZW50YXRpb247CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbERvYyAgPSBpbXBsLmNyZWF0ZURvY3VtZW50ICgnaHR0cDovL25zLmFkb2JlLmNvbS94ZHAvJywgJ3hkcDp4ZHAnLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YXNldHMgPSB4bWxEb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnhmYS5vcmcvc2NoZW1hL3hmYS1kYXRhLzEuMC8iLCAieGZhOmRhdGFzZXRzIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSB4bWxEb2MuY3JlYXRlRWxlbWVudCgieGZhOmRhdGEiKTsKICAgICAgICAgICAgICAgICAgICAgICAgcm9vdE5vZGUgPSB4bWxEb2MuaW1wb3J0Tm9kZShyb290Tm9kZSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEuYXBwZW5kQ2hpbGQocm9vdE5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICBkYXRhc2V0cy5hcHBlbmRDaGlsZChkYXRhKTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sRG9jLmRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZChkYXRhc2V0cyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcm9vdFN1YmZvcm0uZ2VuZXJhdGVEYXRhWE1MKHJvb3ROb2RlLCByb290Tm9kZSk7CiAgICAgICAgICAgICAgICBpZihwcmVmaWxsWE1MID09IG51bGwgfHwgXy5pc1N0cmluZyhwcmVmaWxsWE1MKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgWE1MU2VyaWFsaXplcigpLnNlcmlhbGl6ZVRvU3RyaW5nKHhtbERvYy5kb2N1bWVudEVsZW1lbnQpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4geG1sRG9jOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgICAgICAgIHRoaXMuX3hmYS5Mb2dnZXIuZXJyb3IoInhmYSIsICJFcnJvciBpbiBHZW5lcmF0aW5nIERhdGEgWE1MIG9uIENsaWVudCAiICsgZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIERlc3Ryb3kgTW9iaWxlIEZvcm0gc28gdGhhdCBhbm90aGVyIGZvcm0gY2FuIGJlIHJlbmRlcmVkLiBpZiBiRnVsbCBwYXJhbWV0ZXIKICAgICAgICAgKiBpcyBwYXNzZWQgYXMgdHJ1ZSwgdGhlbiBhbGwgdGhlIHNjcmlwdHMgYXJlIGRlc3Ryb3llZCBhcyB3ZWxsLgogICAgICAgICAqIEBwYXJhbSBiRnVsbAogICAgICAgICAqLwogICAgICAgIGRlc3Ryb3lGb3JtOiBmdW5jdGlvbiAoYkZ1bGwpIHsKICAgICAgICAgICAgJCgiI21mc3R5bGUiKS5yZW1vdmUoKTsKICAgICAgICAgICAgdmFyIG9sZE1hcCA9IHhmYWxpYi5ydW50aW1lLmN1c3RvbVByb3BlcnR5TWFwOwogICAgICAgICAgICAvLyBJbiBhZGFwdGl2ZSBmb3JtLCB3ZSBuZXZlciB1c2UgdGhlIHZpZXcgbGF5ZXIgb2YgbW9iaWxlIGZvcm1zLCBoZW5jZSBhZGRpbmcgbnVsbCBjaGVjawogICAgICAgICAgICBpZih4ZmFWaWV3UmVnaXN0cnkgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgeGZhVmlld1JlZ2lzdHJ5LnJvb3RTdWJmb3JtVmlldyA9IG51bGw7CiAgICAgICAgICAgICAgICB4ZmFWaWV3UmVnaXN0cnkuY2xlYXJUZW1wbGF0ZUNhY2hlKCk7CiAgICAgICAgICAgICAgICB4ZmFWaWV3UmVnaXN0cnkucmVzZXRMYXlvdXRNYW5hZ2VyKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUgPSB7CiAgICAgICAgICAgICAgICB4ZmE6IG51bGwsCiAgICAgICAgICAgICAgICBhcHA6IG51bGwsCiAgICAgICAgICAgICAgICBEb2N1bWVudDogbnVsbCwKICAgICAgICAgICAgICAgIGZvcm06IG51bGwsCiAgICAgICAgICAgICAgICByZW5kZXJDb250ZXh0OiBudWxsLAogICAgICAgICAgICAgICAgX3ByaXZhdGU6IHt9LAogICAgICAgICAgICAgICAgY3VzdG9tUHJvcGVydHlNYXA6IG9sZE1hcAogICAgICAgICAgICB9OwogICAgICAgICAgICBpZih4ZmFsaWIucnVudGltZS5jb25zb2xlKSB7CiAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS5jb25zb2xlID0gdW5kZWZpbmVkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuX3hmYSA9IG51bGw7CiAgICAgICAgICAgIHhmYWxpYi5zY3JpcHQuWGZhLkluc3RhbmNlID0gbnVsbDsKICAgICAgICAgICAgJCh3aW5kb3cpLnRyaWdnZXIoImRlc3Ryb3kueGZhIik7CiAgICAgICAgICAgICQod2luZG93KS5vZmYoIi54ZmEiKTsKICAgICAgICAgICAgeGZhbGliLnZpZXcudXRpbC5UZXh0TWV0cmljcy5fZGVzdHJveSgpOwogICAgICAgICAgICB4ZmFsaWIudmlldy51dGlsLnRyYXZlcnNhbE1hbmFnZXIuX2Rlc3Ryb3koKTsKICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fY2xlYXJGb2N1c0luZm8oKTsKICAgICAgICAgICAgaWYoYkZ1bGwgPT09IHRydWUpIHsKICAgICAgICAgICAgICAgICQod2luZG93KS5vZmYoKTsKICAgICAgICAgICAgICAgICQoImJvZHkiKS5lbXB0eSgpOwogICAgICAgICAgICAgICAgLy90aGlzIGlzIGFkZGVkIGJ5IEZpbGVBdHRhY2htZW50LiBJdCBzaG91bGQgaGF2ZSBiZWVuCiAgICAgICAgICAgICAgICAvLyBhIG5hbWVzcGFjZSBldmVudAogICAgICAgICAgICAgICAgJChkb2N1bWVudCkub2ZmKCJtb3VzZWRvd24iKTsKICAgICAgICAgICAgICAgIF8uZWFjaCh4ZmFsaWIsIGZ1bmN0aW9uIChvYmosIGtleSkgewogICAgICAgICAgICAgICAgICAgeGZhbGliW2tleV0gPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHhmYWxpYiA9IG51bGw7CiAgICAgICAgICAgICAgICB3Z3hwYXRoID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgRm9ybUNhbGMgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAvLyBJbiBhZGFwdGl2ZSBmb3JtLCB3ZSBuZXZlciB1c2UgdGhlIHZpZXcgbGF5ZXIgb2YgbW9iaWxlIGZvcm1zLCBoZW5jZSBhZGRpbmcgbnVsbCBjaGVjawogICAgICAgICAgICAgICAgaWYoeGZhVmlld1JlZ2lzdHJ5ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB4ZmFWaWV3UmVnaXN0cnkuZGVzdHJveSgpOwogICAgICAgICAgICAgICAgICAgIHhmYVZpZXdSZWdpc3RyeSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICQuV2lkZ2V0ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC53aWRnZXQgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnhmYVdpZGdldCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgICQuZm4gPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnByb3RvdHlwZS5hYnN0cmFjdFdpZGdldCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgICQucHJvdG90eXBlLmFkb2JlRGF0ZVRpbWVQaWNrZXIgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnByb3RvdHlwZS5hZG9iZUZpbGVBdHRhY2htZW50ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUuYWRvYmVGaWxlVXBsb2FkZXIgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnByb3RvdHlwZS5kYXRlVGltZUVkaXQgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnByb3RvdHlwZS5kcm9wRG93bkxpc3QgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnByb3RvdHlwZS5kZWZhdWx0V2lkZ2V0ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUuZmlsZVVwbG9hZCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgICQucHJvdG90eXBlLmltYWdlRmllbGQgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnByb3RvdHlwZS5saXN0Qm94ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUubndrTGlzdEJveCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgICQucHJvdG90eXBlLm51bWVyaWNJbnB1dCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgICQucHJvdG90eXBlLnNpZ25hdHVyZUZpZWxkID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUuU2NyaWJibGVJbWFnZUZpZWxkID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUudGV4dEZpZWxkID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUueGZhQnV0dG9uID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUuWGZhQ2hlY2tCb3ggPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLmV4cHIgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB3aW5kb3cuZm9ybUJyaWRnZSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIEZvcm1CcmlkZ2UgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB3aW5kb3cucmVuZGVyTmV4dFBhZ2UgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB3aW5kb3cuaGFuZGxlRm9vdGVyTG9naWMgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB3aW5kb3cuaGFuZGxlU2Nyb2xsID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgb3B0aW9uc0Zyb21Qcm9maWxlTm9kZSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICBGRCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIHdpbmRvdy5fID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJHBsdWdGaWxlV2lkZ2V0RG9tID0gdW5kZWZpbmVkOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgd2luZG93LmZvcm1CcmlkZ2UgPSBuZXcgRm9ybUJyaWRnZSgpOwogICAgd2luZG93LmZvcm1CcmlkZ2UuXyR0YXJnZXQgPSAkKHdpbmRvdy5mb3JtQnJpZGdlKTsKICAgIHRyeSB7CiAgICAgICAgdmFyIGV2bnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgiQ3VzdG9tRXZlbnQiKTsKICAgICAgICBldm50LmluaXRDdXN0b21FdmVudCgiRm9ybUJyaWRnZUluaXRpYWxpemVkIiwgdHJ1ZSwgdHJ1ZSwgeyJmb3JtQnJpZGdlIjogd2luZG93LmZvcm1CcmlkZ2V9KTsKICAgICAgICB3aW5kb3cuZGlzcGF0Y2hFdmVudChldm50KTsKICAgIH0KCiAgICBjYXRjaCAoZXhjZXB0aW9uKSB7CiAgICAgICAgLy8gd3JpdHRlbiBmb3IgZW52IHJoaW5vIHRvIGV4ZWN1dGUoZm9yIHNlcnZlciBzaWRlIHZhbGlkYXRpb24pCiAgICB9CgogICAgaWYgKCF3aW5kb3cuZm9ybUJyaWRnZS51c2VyQ29uZmlnWyJwb3N0RXh0ZXJuYWxNZXNzYWdlQ29uZmlnIl0pIHsKICAgICAgICBpZiAod2luZG93ICE9PSB3aW5kb3cucGFyZW50KSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB3aW5kb3cucGFyZW50LmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHdpbmRvdy5uYW1lKTsKICAgICAgICAgICAgICAgIC8vV2UgYXJlIGhlcmUgbWVhbnMgbm8gY3Jvc3MgZG9tYWluIGlzc3VlLiBTbyBpZiB1c2VyIGhhcyBub3QgZGVmaW5lZCBjdXN0b20gcG9zdEV4dGVybmFsTWVzc2FnZUNvbmZpZyBhbmQKICAgICAgICAgICAgICAgIC8vIHRoZW4gd2UnbGwgY3JlYXRlIG9uZSB3aGljaCB3b3VsZCBqdXN0IHNlbmQgZXZlbnQgb24gcGFyZW50LgogICAgICAgICAgICAgICAgd2luZG93LmZvcm1CcmlkZ2UucmVnaXN0ZXJDb25maWcoInBvc3RFeHRlcm5hbE1lc3NhZ2VDb25maWciLCB7CiAgICAgICAgICAgICAgICAgICAgInBvc3RFeHRlcm5hbEhhbmRsZXIiOiBmdW5jdGlvbiAobWVzc2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG1wRXZlbnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgiQ3VzdG9tRXZlbnQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgdG1wRXZlbnQuaW5pdEN1c3RvbUV2ZW50KG1lc3NhZ2UubmFtZSwgdHJ1ZSwgdHJ1ZSwgbWVzc2FnZS5kYXRhKTsKICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LnBhcmVudC5kaXNwYXRjaEV2ZW50KHRtcEV2ZW50KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgLy9pZ25vcmUgdGhlIGVycm9yCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICB3aW5kb3cuZm9ybUJyaWRnZS5fcG9zdEV4dGVybmFsTWVzc2FnZSh7CiAgICAgICAgbmFtZTogIkZvcm1CcmlkZ2VJbml0aWFsaXplZCIsCiAgICAgICAgZGF0YTogewogICAgICAgICAgICAiZm9ybUJyaWRnZSI6IHdpbmRvdy5mb3JtQnJpZGdlCiAgICAgICAgfQogICAgfSk7Cn0pKCQpOwoKLyoqCiAqIFRoaXMgc2hvdWxkIGhvdXNlIGFsbCB0aGUgaW50ZXJuYWwgQVBJcyBhZGRlZCB0cCBGb3JtQnJpZGdlCiAqIENyZWF0ZWQgYnkgc2FzZHV0dGEgb24gMTIvMjMvMjAxNC4KICovCgooZnVuY3Rpb24gKCQsIF8sIGZvcm1CcmlkZ2UpIHsKICAgIGZvcm1CcmlkZ2UuaW50ZXJuYWwgPSB7CgogICAgICAgIC8qKgogICAgICAgICAqIEdldCBTT00gZXhwcmVzc2lvbnMgb2YgYWxsIHRoZSBmaWVsZHMgaW4gdGhlIGZvcm0sIGluY2x1ZGluZyBtYXN0ZXIgcGFnZSBmaWVsZHMKICAgICAgICAgKgogICAgICAgICAqIEByZXR1cm4ge0FycmF5fSBvZiBzb20gZXhwcmVzc2lvbnMgYXMgc3RyaW5ncy4KICAgICAgICAgKi8KICAgICAgICBnZXRBbGxGaWVsZHNTb206IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGZpZWxkc1NvbSA9IFtdOwogICAgICAgICAgICBmdW5jdGlvbiBnZXRBbGxGaWVsZHNTb21WaXNpdG9yKHRhcmdldCkgewogICAgICAgICAgICAgICAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIHhmYWxpYi5zY3JpcHQuRmllbGQpIHsKICAgICAgICAgICAgICAgICAgICBmaWVsZHNTb20ucHVzaCh0YXJnZXQuc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcm1CcmlkZ2UuX3hmYS5mb3JtLl9nZXRSb290U3ViZm9ybSgpLl92aXNpdEFsbG1vQ2hpbGRyZW4oZ2V0QWxsRmllbGRzU29tVmlzaXRvcik7CiAgICAgICAgICAgIHJldHVybiBmaWVsZHNTb207CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHBhcmFtIHBhZ2VOdW0ge2ludH0gc2Nyb2xsIHRvIHNwZWNpZmllZCBwZyBubyBpZiBhdmFpbGFibGUKICAgICAgICAgKiBAcmV0dXJucyBub3RoaW5nCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBzY3JvbGxUb1BhZ2U6IGZ1bmN0aW9uIChwYWdlTnVtKSB7CiAgICAgICAgICAgIGlmIChwYWdlTnVtID4gMCAmJiBwYWdlTnVtIDw9IGZvcm1CcmlkZ2UucGFnaW5nTWFuYWdlcigpLnBhZ2VDb3VudCgpKSB7CiAgICAgICAgICAgICAgICBmb3JtQnJpZGdlLnBhZ2luZ01hbmFnZXIoKS5fbWFrZVBhZ2UocGFnZU51bSk7CgogICAgICAgICAgICAgICAgdmFyICR0YXJnZXRQZyA9ICQoIiNsY2Zvcm1zX3hmYWZvcm1fY29udGFpbmVyIC5wYWdlIikuZXEocGFnZU51bSAtIDEpOyAvLyB6ZXJvIGJhc2VkIGluZGV4IGluIEpRCgogICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgJCh3aW5kb3cpLnNjcm9sbFRvcCgkdGFyZ2V0UGcub2Zmc2V0KCkudG9wKTsgLy8gbmV3bHkgYWRkZWQgcGFnZXMgbmVlZCB0aW1lIHRvIHJlbmRlcgogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICByZXNvbHZlTm9kZTogZnVuY3Rpb24gKHNvbUV4cHJlc3Npb24pIHsKICAgICAgICAgICAgcmV0dXJuIGZvcm1CcmlkZ2UuX3hmYS5yZXNvbHZlTm9kZShzb21FeHByZXNzaW9uKTsKICAgICAgICB9LAoKICAgICAgICBwYWdlQ291bnQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIGZvcm1CcmlkZ2UucGFnaW5nTWFuYWdlcigpLnBhZ2VDb3VudCgpOwogICAgICAgIH0sCgogICAgICAgIHBhZ2U6IGZ1bmN0aW9uIChmaWVsZE5vZGUpIHsKICAgICAgICAgICAgcmV0dXJuIGZvcm1CcmlkZ2UuX3hmYS4kbGF5b3V0LnBhZ2UoZmllbGROb2RlKTsKICAgICAgICB9LAoKICAgICAgICBub3JtYWxpemVTb206IGZ1bmN0aW9uIChzb20pIHsKICAgICAgICAgICAgLy8gYWRkaW5nIGluZGV4IGFuZCBwcmVmaXggdG8gdGhlIHNvbSBleHByZXNzaW9uIGFzIG9idGFpbmVkIGZyb20gZGVzaWduZXIKICAgICAgICAgICAgaWYoIV8uaXNTdHJpbmcoc29tKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc29tID0gc29tLnJlcGxhY2UoL1xzL2csICcnKTsKICAgICAgICAgICAgdmFyIHhmYVByZWZpeCA9ICJ4ZmFbMF0uZm9ybVswXS4iLAogICAgICAgICAgICAgICAgbm9ybWFsaXplZFNvbSA9IChzb20gKyAiLiIpLnJlcGxhY2UoLyhcXSk/XC4vZywgZnVuY3Rpb24gKCQwLCAkMSkgeyByZXR1cm4gJDEgPyAkMCA6ICdbMF0uJzsgfSkuc2xpY2UoMCwgLTEpOwoKICAgICAgICAgICAgaWYobm9ybWFsaXplZFNvbS5zbGljZSgwLHhmYVByZWZpeC5sZW5ndGgpICE9PSB4ZmFQcmVmaXgpIHsKICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRTb20gPSB4ZmFQcmVmaXggKyBub3JtYWxpemVkU29tOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBub3JtYWxpemVkU29tOwogICAgICAgIH0KICAgIH07Cn0oJCwgXywgd2luZG93LmZvcm1CcmlkZ2UpKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDEzIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogVGhpcyBvYmplY3QgaG9zdHMgRm9ybUNhbGMgYnVpbGQtaW4gZnVuY3Rpb25zCiAqLwpGb3JtQ2FsYyA9IGZ1bmN0aW9uKCl7fTsKCgpGb3JtQ2FsYy5jb252ZXJ0QXJndW1lbnRzVG9BcnJheSA9IGZ1bmN0aW9uKCkgewogICAgdmFyIGFyZ3M9IFtdOwogICAgZm9yICh2YXIgaSA9IDA7aTxhcmd1bWVudHMubGVuZ3RoO2krKykgewogICAgICAgIGlmKGFyZ3VtZW50c1tpXSBpbnN0YW5jZW9mIEFycmF5KSB7CiAgICAgICAgICAgIGFyZ3MgPSBhcmdzLmNvbmNhdChhcmd1bWVudHNbaV0pCiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBhcmdzLnB1c2goYXJndW1lbnRzW2ldKQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBhcmdzOwp9CgovLy8vQXJpdGhtZXRpYyBCdWlsdC1pbiBGdW5jdGlvbnMKLyoqCiAqIFJldHVybnMgdGhlIGF2ZXJhZ2Ugb2YgdGhlIG5vbi1udWxsIGVsZW1lbnRzIG9mIGEgZ2l2ZW4gc2V0IG9mIG51bWJlcnMuCiAqLwpGb3JtQ2FsYy5hdmcgPSBmdW5jdGlvbigpewogICAgdmFyIGFyZ3MgPSB0aGlzLmNvbnZlcnRBcmd1bWVudHNUb0FycmF5LmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKCXJldHVybiBGb3JtQ2FsYy5ydW5XaXRoTnVtZXJpY0FyZ3MoZnVuY3Rpb24oKXsKICAgICAgICB2YXIgc3VtID0gMCA7CiAgICAgICAgdmFyIHZhbGlkX2NvdW50ID0gMDsKICAgICAgICBmb3IodmFyIGlkeD0wOyBpZHg8YXJndW1lbnRzLmxlbmd0aDsgaWR4KysgKXsKICAgICAgICAJCXN1bSArPSBhcmd1bWVudHNbaWR4XTsKICAgICAgICAJCXZhbGlkX2NvdW50Kys7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2YWxpZF9jb3VudCA/IHN1bS92YWxpZF9jb3VudCA6bnVsbDsKCX0sIGFyZ3MpOwp9OwoKLyoqCiAqIFJldHVybnMgdGhlIGNvdW50IG9mIHRoZSBub24tbnVsbCBlbGVtZW50cyBvZiBhIGdpdmVuIHNldCBvZiBudW1iZXJzLgogKi8KRm9ybUNhbGMuY291bnQgPSBmdW5jdGlvbigpewogICAgdmFyIGFyZ3MgPSB0aGlzLmNvbnZlcnRBcmd1bWVudHNUb0FycmF5LmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgIHZhciBhcmd1cyA9IEZvcm1DYWxjLmxpbWl0QWxsTnVsbEFyZ3MoYXJncyk7CglyZXR1cm4gYXJndXMubGVuZ3RoID8gYXJndXMubGVuZ3RoIDogMAp9OwoKLyoqCiAqIFJldHVybnMgdGhlIG1heCBvZiB0aGUgbm9uLW51bGwgZWxlbWVudHMgb2YgYSBnaXZlbiBzZXQgb2YgbnVtYmVycy4KICovCkZvcm1DYWxjLm1heCA9IGZ1bmN0aW9uKCl7CiAgICB2YXIgYXJncyA9IHRoaXMuY29udmVydEFyZ3VtZW50c1RvQXJyYXkuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgcmV0dXJuIEZvcm1DYWxjLnJ1bldpdGhOdW1lcmljQXJncyhNYXRoLm1heCwgYXJncyk7Cn07CgovKioKICogUmV0dXJucyB0aGUgbWluIG9mIHRoZSBub24tbnVsbCBlbGVtZW50cyBvZiBhIGdpdmVuIHNldCBvZiBudW1iZXJzLgogKi8KRm9ybUNhbGMubWluID0gZnVuY3Rpb24oKXsKICAgIHZhciBhcmdzID0gdGhpcy5jb252ZXJ0QXJndW1lbnRzVG9BcnJheS5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICByZXR1cm4gRm9ybUNhbGMucnVuV2l0aE51bWVyaWNBcmdzKE1hdGgubWluLCBhcmdzKTsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBtb2R1bHVzIG9mIG9uZSBudW1iZXIgZGl2aWRlZCBieSBhbm90aGVyLi4KICovCkZvcm1DYWxjLm1vZCA9IGZ1bmN0aW9uKGEsYil7CglpZihiPT0wICl7CgkJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwoJfQoJcmV0dXJuIGElYjsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBzdW0gb2YgdGhlIG5vbi1udWxsIGVsZW1lbnRzIG9mIGEgZ2l2ZW4gc2V0IG9mIG51bWJlcnMuCiAqLwpGb3JtQ2FsYy5zdW0gPSBmdW5jdGlvbigpewogICAgdmFyIGFyZ3MgPSB0aGlzLmNvbnZlcnRBcmd1bWVudHNUb0FycmF5LmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgIHJldHVybiBGb3JtQ2FsYy5ydW5XaXRoTnVtZXJpY0FyZ3MoZnVuY3Rpb24oKXsKICAgIAl2YXIgcmVzdWx0ID0gMDsKICAgICAgICBmb3IodmFyIGlkeD0wO2lkeDxhcmd1bWVudHMubGVuZ3RoO2lkeCsrICl7CiAgICAgICAgCXJlc3VsdCArPSBhcmd1bWVudHNbaWR4XTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKCX0sIGFyZ3MpOwp9OwoKLyoqCiAqIFJldHVybnMgYSBudW1iZXIgcm91bmRlZCB0byBhIGdpdmVuIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlcwogKi8KRm9ybUNhbGMucm91bmQgPSBmdW5jdGlvbihuMSxuMil7CglpZighRm9ybUNhbGMuaXNOdW1lcmljKG4xKSl7CgkJcmV0dXJuIDA7Cgl9CglpZihhcmd1bWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgICByZXR1cm4gTWF0aC5yb3VuZChuMSk7CiAgICB9ZWxzZSBpZihhcmd1bWVudHMubGVuZ3RoID09IDIpewogICAgCWlmKG4yPT1udWxsKXsKICAgIAkJcmV0dXJuIG51bGw7CiAgICAJfQogICAgCQogICAgCW4xID0gcGFyc2VGbG9hdChuMSk7CiAgICAJaWYobjIgPiAxMil7CiAgICAJCW4yID0gMTI7CiAgICAJfQogICAgCWlmKGlzTmFOKG4xKSB8fCAhaXNGaW5pdGUobjEpKXsKICAgIAkJcmV0dXJuIG4xOwogICAgCX1lbHNlewogICAgCQlyZXR1cm4gbjEudG9GaXhlZChuMik7ICAgIAkJCiAgICAJfQkKICAgIH0KfTsKCi8qKgogKiBSZXR1cm5zIHRoZSByYWRpYW4gdmFsdWUgb2YgYSBnaXZlbiBudW1iZXIuCiAqLwpGb3JtQ2FsYy5kZWcyUmFkID0gZnVuY3Rpb24oYW5nbGUpewoJcmV0dXJuIEZvcm1DYWxjLmlzTnVtZXJpYyhhbmdsZSkgPyAoYW5nbGUgLyAxODApICogTWF0aC5QSSA6bnVsbDsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBkZWdyZWUgdmFsdWUgb2YgYSBnaXZlbiBudW1iZXIuCiAqLwpGb3JtQ2FsYy5yYWQyRGVnID0gZnVuY3Rpb24ocmFkaW8pewoJcmV0dXJuIEZvcm1DYWxjLmlzTnVtZXJpYyhyYWRpbykgPyByYWRpbyAqIDE4MCAvIE1hdGguUEkgOiBudWxsOwkKfTsKLy8vL1N0cmluZyBCdWlsdC1pbiBGdW5jdGlvbnMgCi8qKgogKiBMb2NhdGVzIHRoZSBzdGFydGluZyBjaGFyYWN0ZXIgcG9zaXRpb24gb2Ygc3RyaW5nIHMyIHdpdGhpbiBzdHJpbmcgczEuCiAqLwpGb3JtQ2FsYy5hdCA9IGZ1bmN0aW9uKG4xLG4yKXsKCXJldHVybiBuMS5pbmRleE9mKG4yKSArIDE7Cn07CgovKioKICogUmV0dXJucyB0aGUgc3RyaW5nIGNvbmNhdGVuYXRpb24gb2YgYSBnaXZlbiBzZXQgb2Ygc3RyaW5ncy4KICovCkZvcm1DYWxjLmNvbmNhdCA9IGZ1bmN0aW9uKCl7Cgl2YXIgc0FycmF5ID0gbmV3IEFycmF5KCk7Cglmb3IodmFyIGk9MDtpPGFyZ3VtZW50cy5sZW5ndGg7aSsrKXsKCQlpZihhcmd1bWVudHNbaV0hPW51bGwpewoJCQlzQXJyYXlbc0FycmF5Lmxlbmd0aF0gPSBhcmd1bWVudHNbaV0udG9TdHJpbmcoKTsKCQl9Cgl9CgoJaWYoc0FycmF5Lmxlbmd0aCA9PSAwKXsKCQlyZXR1cm4gbnVsbDsKCX1lbHNlewoJCXJldHVybiBzQXJyYXkuam9pbigiIik7Cgl9Cn07CgovKioKICogRXh0cmFjdHMgYSBudW1iZXIgb2YgY2hhcmFjdGVycyBmcm9tIGEgZ2l2ZW4gc3RyaW5nLCAKICogc3RhcnRpbmcgd2l0aCB0aGUgZmlyc3QgY2hhcmFjdGVyIG9uIHRoZSBsZWZ0LgogKi8KRm9ybUNhbGMubGVmdCA9IGZ1bmN0aW9uKHMsbil7CglpZihzPT1udWxsKXsKCQlyZXR1cm4gbnVsbDsKCX0KCXJldHVybiBzLnN1YnN0cmluZygwLG4pOwp9OwoKLyoqCiAqIEV4dHJhY3RzIGEgbnVtYmVyIG9mIGNoYXJhY3RlcnMgZnJvbSBhIGdpdmVuIHN0cmluZywgCiAqIGJlZ2lubmluZyB3aXRoIHRoZSBsYXN0IGNoYXJhY3RlciBvbiB0aGVyaWdodC4KICovCgpGb3JtQ2FsYy5yaWdodCA9IGZ1bmN0aW9uKHMsbil7CglpZihzPT1udWxsKXsKCQlyZXR1cm4gbnVsbDsKCX0KCXJldHVybiBzLnN1YnN0cmluZyhzLmxlbmd0aC1uLHMubGVuZ3RoKTsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBhIGdpdmVuIHN0cmluZy4KICovCkZvcm1DYWxjLmxlbiA9IGZ1bmN0aW9uKHMpewoJaWYocz09bnVsbCl7CgkJcmV0dXJuIDA7Cgl9ZWxzZXsKCQlyZXR1cm4gcy50b1N0cmluZygpLmxlbmd0aDsJCQoJfQp9OwoKLyoqCiAqIFJldHVybnMgYSBzdHJpbmcgd2l0aCBhbGwgbGVhZGluZyB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXJzIHJlbW92ZWQuCiAqLwpGb3JtQ2FsYy5sdHJpbSA9IGZ1bmN0aW9uKHMpewoJaWYocz09bnVsbCl7CgkJcmV0dXJuIG51bGw7Cgl9CglyZXR1cm4gcy5yZXBsYWNlKC9eXHMrLywiIik7Cn07CgovKioKICogUmV0dXJucyBhIHN0cmluZyB3aXRoIGFsbCB0cmFpbGluZyB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXJzIHJlbW92ZWQuCiAqLwpGb3JtQ2FsYy5ydHJpbSA9IGZ1bmN0aW9uKHMpewoJaWYocyA9PSBudWxsKXsKCQlyZXR1cm4gbnVsbDsKCX0KCXJldHVybiBzLnJlcGxhY2UoL1xzKyQvLCIiKTsKfTsKCi8qKgogKiBSZXBsYWNlcyBhbGwgb2NjdXJyZW5jZXMgb2Ygb25lIHN0cmluZyB3aXRoIGFub3RoZXIgd2l0aGluIGEgZ2l2ZW4gc3RyaW5nLgogKi8KRm9ybUNhbGMucmVwbGFjZSA9IGZ1bmN0aW9uKHMxLCBzMiwgczMpIHsKCWlmKHMxID09IG51bGwpewoJCXJldHVybiBudWxsOwoJfQoJaWYgKHVuZGVmaW5lZCA9PSBzMykgewoJCXMzID0gIiI7Cgl9CglyZXR1cm4gczEucmVwbGFjZShzMiwgczMpOwp9OwoKLyoqCiAqIHJldHVybnMgYSBzdHJpbmcgY29uc2lzdGluZyBvZiBhIGdpdmVuIG51bWJlciBvZiBibGFuayBzcGFjZXMuCiAqLwpGb3JtQ2FsYy5zcGFjZSA9IGZ1bmN0aW9uKG4pewoJdmFyIHNBcnJheSA9IG5ldyBBcnJheSgpOwoJdmFyIG51bSA9IE1hdGguZmxvb3Iobik7Cglmb3IodmFyIGk9MDtpPG51bTtpKyspewoJCXNBcnJheVtzQXJyYXkubGVuZ3RoXT0iICI7Cgl9CglyZXR1cm4gc0FycmF5LmpvaW4oIiIpOwp9OwoKLyoqCiAqIEV4dHJhY3RzIGEgcG9ydGlvbiBvZiBhIGdpdmVuIHN0cmluZy4KICogCiAqLwpGb3JtQ2FsYy5zdWJzdHIgPSBmdW5jdGlvbihzMSxuMSxuMil7CiAgICBpZihuMjw9MCl7CiAgICAJcmV0dXJuICIiOwogICAgfQogICAgaWYobjEgPCAxKXsKICAgIAluMSA9IDE7CiAgICB9IGVsc2UgaWYobjEgPiBzMS5sZW5ndGgpewogICAgCW4xID0gczEubGVuZ3RoOwogICAgfQoJcmV0dXJuIHMxLnN1YnN0cmluZyhuMS0xLG4xLTErbjIpOwp9OwoKLyoqCiAqIEluc2VydHMgYSBzdHJpbmcgaW50byBhbm90aGVyIHN0cmluZy4KICogCiAqLwpGb3JtQ2FsYy5zdHVmZiA9IGZ1bmN0aW9uKHMxLCBuMSwgbjIsIHMyKXsKICAgIGlmKG4yPDApewogICAgCW4yPTA7CiAgICB9CiAgICBpZihuMSA8IDEpewogICAgCW4xID0gMTsKICAgIH0gZWxzZSBpZihuMSA+IHMxLmxlbmd0aCl7CiAgICAJbjEgPSBzMS5sZW5ndGg7CiAgICB9CiAgICBpZihzMiA9PSB1bmRlZmluZWQpewogICAgCXMyPSIiOwogICAgfQoJcmV0dXJuIHMxLnN1YnN0cmluZygwLCBuMS0xKSArIHMyICsgczEuc3Vic3RyaW5nKG4xICsgbjItMSxzMS5sZW5ndGgpOwp9OwoKLyoqCiAqIFJldHVybnMgYSBzdHJpbmcgd2hlcmUgYWxsIGdpdmVuIHVwcGVyY2FzZSBjaGFyYWN0ZXJzIGFyZSBjb252ZXJ0ZWQgdG8gbG93ZXJjYXNlLgogKi8KRm9ybUNhbGMubG93ZXIgPSBmdW5jdGlvbihzMSl7CglpZihzMT09bnVsbCl7CgkJcmV0dXJuIG51bGw7Cgl9ZWxzZXsKCQlyZXR1cm4gczEudG9Mb3dlckNhc2UoKTsJCQoJfQp9OwoKLyoqCiAqIFJldHVybnMgYSBzdHJpbmcgd2l0aCBhbGwgZ2l2ZW4gbG93ZXJjYXNlIGNoYXJhY3RlcnMgY29udmVydGVkIHRvIHVwcGVyY2FzZS4KICovCkZvcm1DYWxjLnVwcGVyID0gZnVuY3Rpb24oczEpewoJaWYoczE9PW51bGwpewoJCXJldHVybiBudWxsOwoJfWVsc2V7CgkJcmV0dXJuIHMxLnRvVXBwZXJDYXNlKCk7CQkKCX0KfTsKCi8qKgogKiBTZWxlY3RzIGEgdmFsdWUgZnJvbSBhIGdpdmVuIHNldCBvZiBwYXJhbWV0ZXJzLgogKi8KRm9ybUNhbGMuY2hvb3NlID0gZnVuY3Rpb24objEsczEpewoJaWYobjEgPCAxKXsKCQlyZXR1cm4gIiI7Cgl9CglpZihuMSA8IGFyZ3VtZW50cy5sZW5ndGgpewoJCXJldHVybiBhcmd1bWVudHNbbjFdOwoJfSBlbHNlIHsKCQlyZXR1cm4gIiI7Cgl9Cn07CgkKLyoqCiAqIFJldHVybnMgdHJ1ZSBpZiBhIHZhbHVlIGlzIGluIGEgZ2l2ZW4gc2V0LgogKi8KRm9ybUNhbGMub25lb2YgPSBmdW5jdGlvbihzMSwgczIpewoJZm9yKHZhciBpZHggPSAxOyBpZHggPCBhcmd1bWVudHMubGVuZ3RoOyBpZHgrKyl7CgkJaWYoczEgPT0gYXJndW1lbnRzW2lkeF0pewoJCQlyZXR1cm4gdHJ1ZTsKCQl9Cgl9CglyZXR1cm4gZmFsc2U7Cn07CgovKioKICogVGhpcyBsb2dpY2FsIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSBpZiBhIHZhbHVlIGlzIHdpdGhpbiBhIGdpdmVuIHJhbmdlLgogKi8KRm9ybUNhbGMud2l0aGluID0gZnVuY3Rpb24oczEsIHMyLCBzMyl7CglyZXR1cm4gKHMxPj1zMiAmJiBzMTw9czMpOwp9CgovKioKICogCiAqLwpGb3JtQ2FsYy5pZmZ1biA9IGZ1bmN0aW9uKHMxLCBzMiwgczMpewoJRm9ybUNhbGMuY2hlY2tNaW5BcmdzKGFyZ3VtZW50cy5sZW5ndGgsIDIpOwoJRm9ybUNhbGMuY2hlY2tNYXhBcmdzKGFyZ3VtZW50cy5sZW5ndGgsIDMpOwoJaWYoczEpewoJCXJldHVybiBzMjsKCX1lbHNlewoJCXJldHVybiBzMzsKCX0KfTsKCgovKioKICogUmV0dXJucyB0aGUgYW5udWFsIHBlcmNlbnRhZ2UgcmF0ZSBmb3IgYSBsb2FuLgogKi8KRm9ybUNhbGMuYXByID0gZnVuY3Rpb24oblByaW5jaXBhbCwgblBheW1lbnQsIG5QZXJpb2RzKSB7CglGb3JtQ2FsYy5jaGVja01pbkFyZ3MoYXJndW1lbnRzLmxlbmd0aCwgMyk7CglGb3JtQ2FsYy5jaGVja01heEFyZ3MoYXJndW1lbnRzLmxlbmd0aCwgMyk7CglpZiAoblByaW5jaXBhbCA8PSAwIHx8IG5QYXltZW50IDw9IDAgfHwgblBlcmlvZHMgPCAwKSB7CgkJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwoJfQoJCgl2YXIgbWF4SXRlcmF0aW9ucyA9IDUwMDsKCXZhciBlcHMgPSAwLjAwNTsKCXZhciBkZWx0YSA9IDAuMDAwMDAwMTsKCXZhciBuSW50ZXJlc3QgPSAwLjA1OwoJdmFyIG5QbXRaZXJvID0gblByaW5jaXBhbCAvIG5QZXJpb2RzOwoJdmFyIG5QbXRDdXIgPSBGb3JtQ2FsYy5sb2FuUG10KG5QcmluY2lwYWwsIG5JbnRlcmVzdCwgblBlcmlvZHMpOwoJdmFyIGkgPSAxOwoKCWRvIHsKCQlpZiAoTWF0aC5hYnMoblBtdEN1ciAtIG5QbXRaZXJvKSA8IGRlbHRhKQoJCQlicmVhazsKCQluSW50ZXJlc3QgKj0gKG5QYXltZW50IC0gblBtdFplcm8pIC8gKG5QbXRDdXIgLSBuUG10WmVybyk7CgkJblBtdEN1ciA9IEZvcm1DYWxjLmxvYW5QbXQoblByaW5jaXBhbCwgbkludGVyZXN0LCBuUGVyaW9kcyk7Cgl9IHdoaWxlICghKCsraSA+IG1heEl0ZXJhdGlvbnMgfHwgTWF0aC5hYnMoblBheW1lbnQgLSBuUG10Q3VyKSA8IGVwcykpOwoJdmFyIG5SYXRlID0gKE1hdGguYWJzKG5QbXRDdXIgLSBuUG10WmVybykgPCBkZWx0YSkgPyAwIDogMTIgKiBuSW50ZXJlc3Q7CglyZXR1cm4gRm9ybUNhbGMuY2hlY2tSZXN1bHQoblJhdGUpOwp9OwoKLyoqCiAqIFJldHVybnMgdGhlIG51bWJlciBvZiBwZXJpb2RzIG5lZWRlZCBmb3IgYW4gaW52ZXN0bWVudCBlYXJuaW5nIGEgZml4ZWQsIGJ1dCBjb21wb3VuZGVkLAogKiBpbnRlcmVzdCByYXRlIHRvIGdyb3cgdG8gYSBmdXR1cmUgdmFsdWUuCiAqLwpGb3JtQ2FsYy5jdGVybSA9IGZ1bmN0aW9uKG5JbnRlcmVzdCwgbkZ1dHVyZSwgblByZXNlbnQpIHsKCUZvcm1DYWxjLmNoZWNrTWluQXJncyhhcmd1bWVudHMubGVuZ3RoLCAzKTsKCUZvcm1DYWxjLmNoZWNrTWF4QXJncyhhcmd1bWVudHMubGVuZ3RoLCAzKTsKCWlmIChuSW50ZXJlc3QgPD0gMCB8fCBuRnV0dXJlIDw9IDAgfHwgblByZXNlbnQgPCAwKSB7CgkJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwoJfQoJdmFyIG5QZXJpb2RzID0gTWF0aC5sb2cobkZ1dHVyZSAvIG5QcmVzZW50KSAvIE1hdGgubG9nKDEgKyBuSW50ZXJlc3QpOwoJcmV0dXJuIEZvcm1DYWxjLmNoZWNrUmVzdWx0KG5QZXJpb2RzKTsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBmdXR1cmUgdmFsdWUgb2YgcGVyaW9kaWMgY29uc3RhbnQgcGF5bWVudHMgYXQgYSBjb25zdGFudCBpbnRlcmVzdCByYXRlLgogKi8KRm9ybUNhbGMuZnYgPSBmdW5jdGlvbihuUGF5bWVudCwgbkludGVyZXN0LCBwblBlcmlvZHMpIHsKCUZvcm1DYWxjLmNoZWNrTWluQXJncyhhcmd1bWVudHMubGVuZ3RoLCAzKTsKCUZvcm1DYWxjLmNoZWNrTWF4QXJncyhhcmd1bWVudHMubGVuZ3RoLCAzKTsKCXZhciBuUGVyaW9kcyA9IHBhcnNlSW50KHBuUGVyaW9kcyk7CglpZiAoblBlcmlvZHMgPD0gMCB8fCBuUGF5bWVudCA8PSAwIHx8IG5JbnRlcmVzdCA8IDApIHsKCQl0aHJvdyAiPG1pc3Npbmcgb3IgaWxsZWdhbCBwYXJhbWV0ZXIocykuPiI7Cgl9CgoJdmFyIG5WYWw7CglpZiAobkludGVyZXN0ID09IDApIHsKCQluVmFsID0gblBheW1lbnQgKiBuUGVyaW9kczsKCX0gZWxzZSB7CgkJblZhbCA9IG5QYXltZW50ICogKDEgKyBuSW50ZXJlc3QpCgkJCQkqIChGb3JtQ2FsYy5pbnRSYXRlKG5JbnRlcmVzdCwgblBlcmlvZHMgLSAxKSAtIDEpIC8gbkludGVyZXN0ICsgblBheW1lbnQ7Cgl9CgoJcmV0dXJuIEZvcm1DYWxjLmNoZWNrUmVzdWx0KG5WYWwpOwp9OwoKLyoqCiAqIFJldHVybnMgdGhlIGFtb3VudCBvZiBpbnRlcmVzdCBwYWlkIG9uIGEgbG9hbiBvdmVyIGEgcGVyaW9kIG9mIHRpbWUuCiAqCiAqLwpGb3JtQ2FsYy5pcG10ID0gZnVuY3Rpb24oblByaW5jaXBhbCwgbkludGVyZXN0LCBuUGF5bWVudCwgblN0YXJ0LCBuTW9udGhzKSB7CglGb3JtQ2FsYy5jaGVja01pbkFyZ3MoYXJndW1lbnRzLmxlbmd0aCwgNSk7CglGb3JtQ2FsYy5jaGVja01heEFyZ3MoYXJndW1lbnRzLmxlbmd0aCwgNSk7CiAgICBpZihuUHJpbmNpcGFsIDw9MCB8fCBuSW50ZXJlc3QgPD0wIHx8blBheW1lbnQgPD0wICB8fG5TdGFydDwxIHx8bk1vbnRoczwxKXsKICAgIAl0aHJvdyAiPG1pc3Npbmcgb3IgaWxsZWdhbCBwYXJhbWV0ZXIocykuPiI7CiAgICB9CgkKCW5JbnRlcmVzdCAvPSAxMjsKCW5TdGFydCA9IHBhcnNlRmxvYXQoblN0YXJ0KTsKCW5Nb250aHMgPSBwYXJzZUZsb2F0KG5Nb250aHMpOwoJaWYgKG5QYXltZW50IDw9IG5QcmluY2lwYWwgKiBuSW50ZXJlc3QpIHsKCQlyZXR1cm4gMDsKCX0gZWxzZSBpZiAobk1vbnRocyArIG5TdGFydCAtIDEgPiBGb3JtQ2FsYy5sb2FuVGVybShuUHJpbmNpcGFsLCBuSW50ZXJlc3QsIG5QYXltZW50KSkgewoJCXJldHVybiAwOwoJfSBlbHNlIHsKCQl2YXIgblByaW5jaXBhbFJlbWFpbmluZyA9IG5QcmluY2lwYWw7CgkJdmFyIG5QcmluY2lwYWxQYWlkSW5QZXJpb2QgPSAwOwoJCXZhciBuSW50ZXJlc3RQYWlkSW5QZXJpb2QgPSAwOwoJCWZvciAoIHZhciBpID0gMTsgaSA8IG5TdGFydDsgaSsrKSB7CgkJCW5JbnRlcmVzdFBhaWRJblBlcmlvZCA9IG5QcmluY2lwYWxSZW1haW5pbmcgKiBuSW50ZXJlc3Q7CgkJCW5QcmluY2lwYWxQYWlkSW5QZXJpb2QgPSBuUGF5bWVudCAtIG5JbnRlcmVzdFBhaWRJblBlcmlvZDsKCQkJblByaW5jaXBhbFJlbWFpbmluZyAtPSBuUHJpbmNpcGFsUGFpZEluUGVyaW9kOwoJCQlpZiAoblByaW5jaXBhbFJlbWFpbmluZyA8PSAwKQoJCQkJYnJlYWs7CgkJfQoJCXZhciBuSW50ZXJlc3RQYWlkID0gMC47CgkJZm9yICggdmFyIGkgPSBuU3RhcnQ7IGkgPCBuU3RhcnQgKyBuTW9udGhzOyBpKyspIHsKCQkJbkludGVyZXN0UGFpZEluUGVyaW9kID0gblByaW5jaXBhbFJlbWFpbmluZyAqIG5JbnRlcmVzdDsKCQkJblByaW5jaXBhbFBhaWRJblBlcmlvZCA9IG5QYXltZW50IC0gbkludGVyZXN0UGFpZEluUGVyaW9kOwoJCQluUHJpbmNpcGFsUmVtYWluaW5nIC09IG5QcmluY2lwYWxQYWlkSW5QZXJpb2Q7CgkJCW5JbnRlcmVzdFBhaWQgKz0gbkludGVyZXN0UGFpZEluUGVyaW9kOwoJCQlpZiAoblByaW5jaXBhbFJlbWFpbmluZyA8PSAwKQoJCQkJYnJlYWs7CgkJfQoJCXJldHVybiBGb3JtQ2FsYy5jaGVja1Jlc3VsdChuSW50ZXJlc3RQYWlkKTsKCX0KfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBuZXQgcHJlc2VudCB2YWx1ZSBvZiBhbiBpbnZlc3RtZW50IGJhc2VkIG9uIGEgZGlzY291bnQgcmF0ZSwgYW5kIGEgc2VyaWVzIG9mCiAqIHBlcmlvZGljIGZ1dHVyZSBjYXNoIGZsb3dzLgogKgogKi8KRm9ybUNhbGMubnB2ID0gZnVuY3Rpb24oKXsKCUZvcm1DYWxjLmNoZWNrTWluQXJncyhhcmd1bWVudHMubGVuZ3RoLCAxKTsKCgl2YXIgbkRpc2NvdW50UmF0ZSA9IEZvcm1DYWxjLnBhcnNlRmxvYXQoYXJndW1lbnRzWzBdKTsKICAgIGlmKG5EaXNjb3VudFJhdGU8PTApewogICAgCXRocm93ICI8bWlzc2luZyBvciBpbGxlZ2FsIHBhcmFtZXRlcihzKS4+IjsKICAgIH0JCgkKCXZhciBuVmFsID0gMDsKCXZhciBuRGVub20gPSAxOwoJZm9yICggdmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7CgkJaWYobnVsbCA9PSBhcmd1bWVudHNbaV0pewoJCQlyZXR1cm4gbnVsbDsKCQl9CgkJbkRlbm9tICo9ICgxICsgbkRpc2NvdW50UmF0ZSk7CgkJblZhbCArPSBGb3JtQ2FsYy5wYXJzZUZsb2F0KGFyZ3VtZW50c1tpXSkgLyBuRGVub207Cgl9CglyZXR1cm4gRm9ybUNhbGMuY2hlY2tSZXN1bHQoblZhbCk7Cgp9OwoKLyoqCiAqIFJldHVybnMgdGhlIHBheW1lbnQgZm9yIGEgbG9hbiBiYXNlZCBvbiBjb25zdGFudCBwYXltZW50cyBhbmQgYSBjb25zdGFudCBpbnRlcmVzdCByYXRlLgogKi8KRm9ybUNhbGMucG10ID0gZnVuY3Rpb24oblByaW5jaXBhbCwgbkludGVyZXN0LCBuUGVyaW9kcykgewoJRm9ybUNhbGMuY2hlY2tNaW5BcmdzKGFyZ3VtZW50cy5sZW5ndGgsIDMpOwoJRm9ybUNhbGMuY2hlY2tNYXhBcmdzKGFyZ3VtZW50cy5sZW5ndGgsIDMpOwoJaWYoblByaW5jaXBhbCA8PTAgfHwgbkludGVyZXN0PD0wIHx8IG5QZXJpb2RzIDw9MCl7CiAgICAJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwogICAgfQoJdmFyIG5QYXltZW50ID0gRm9ybUNhbGMubG9hblBtdChwYXJzZUZsb2F0KG5QcmluY2lwYWwpLCBwYXJzZUZsb2F0KG5JbnRlcmVzdCksCgkJCXBhcnNlSW50KG5QZXJpb2RzKSk7CglyZXR1cm4gRm9ybUNhbGMuY2hlY2tSZXN1bHQoblBheW1lbnQpOwoKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBhbW91bnQgb2YgcHJpbmNpcGFsIHBhaWQgb24gYSBsb2FuIG92ZXIgYSBwZXJpb2Qgb2YgdGltZS4KICogCiAqLwpGb3JtQ2FsYy5wcG10ID0gZnVuY3Rpb24oblByaW5jaXBhbCwgbkludGVyZXN0LCBuUGF5bWVudCwgblN0YXJ0LCBuTW9udGhzKSB7CglGb3JtQ2FsYy5jaGVja01pbkFyZ3MoYXJndW1lbnRzLmxlbmd0aCwgNSk7CglGb3JtQ2FsYy5jaGVja01heEFyZ3MoYXJndW1lbnRzLmxlbmd0aCwgNSk7CiAgICBpZihuUHJpbmNpcGFsIDw9MCB8fCBuSW50ZXJlc3QgPD0wIHx8blBheW1lbnQgPD0wICB8fG5TdGFydDwxIHx8bk1vbnRoczwxKXsKICAgIAl0aHJvdyAiPG1pc3Npbmcgb3IgaWxsZWdhbCBwYXJhbWV0ZXIocykuPiI7CiAgICB9CgkKCW5QcmluY2lwYWwgPSBwYXJzZUZsb2F0KG5QcmluY2lwYWwpOwoJbkludGVyZXN0ID0gcGFyc2VGbG9hdChuSW50ZXJlc3QpOwoJblBheW1lbnQgPSBwYXJzZUZsb2F0KG5QYXltZW50KTsKCW5TdGFydCA9IHBhcnNlSW50KG5TdGFydCk7CgluTW9udGhzID0gcGFyc2VJbnQobk1vbnRocyk7CgoJbkludGVyZXN0IC89IDEyOwoJaWYgKG5QYXltZW50IDw9IG5QcmluY2lwYWwgKiBuSW50ZXJlc3QpIHsKCQlyZXR1cm4gMDsKCX0gZWxzZSBpZiAobk1vbnRocyArIG5TdGFydCAtIDEgPiBGb3JtQ2FsYy5sb2FuVGVybShuUHJpbmNpcGFsLCBuSW50ZXJlc3QsIG5QYXltZW50KSkgewoJCXJldHVybiAwOwoJfSBlbHNlIHsKCQl2YXIgblByaW5jaXBhbFJlbWFpbmluZyA9IG5QcmluY2lwYWw7CgkJdmFyIG5QcmluY2lwYWxQYWlkSW5QZXJpb2QgPSAwOwoJCXZhciBuSW50ZXJlc3RQYWlkSW5QZXJpb2QgPSAwOwoJCWZvciAoIHZhciBpID0gMTsgaSA8IG5TdGFydDsgaSsrKSB7CgkJCW5JbnRlcmVzdFBhaWRJblBlcmlvZCA9IG5QcmluY2lwYWxSZW1haW5pbmcgKiBuSW50ZXJlc3Q7CgkJCW5QcmluY2lwYWxQYWlkSW5QZXJpb2QgPSBuUGF5bWVudCAtIG5JbnRlcmVzdFBhaWRJblBlcmlvZDsKCQkJblByaW5jaXBhbFJlbWFpbmluZyAtPSBuUHJpbmNpcGFsUGFpZEluUGVyaW9kOwoJCQlpZiAoblByaW5jaXBhbFJlbWFpbmluZyA8PSAwKQoJCQkJYnJlYWs7CgkJfQoJCXZhciBuUHJpbmNpcGxlUGFpZCA9IDA7CgkJZm9yICggdmFyIGkgPSBuU3RhcnQ7IGkgPCBuU3RhcnQgKyBuTW9udGhzOyBpKyspIHsKCQkJbkludGVyZXN0UGFpZEluUGVyaW9kID0gblByaW5jaXBhbFJlbWFpbmluZyAqIG5JbnRlcmVzdDsKCQkJblByaW5jaXBhbFBhaWRJblBlcmlvZCA9IG5QYXltZW50IC0gbkludGVyZXN0UGFpZEluUGVyaW9kOwoJCQluUHJpbmNpcGFsUmVtYWluaW5nIC09IG5QcmluY2lwYWxQYWlkSW5QZXJpb2Q7CgkJCW5QcmluY2lwbGVQYWlkICs9IG5QcmluY2lwYWxQYWlkSW5QZXJpb2Q7CgkJCWlmIChuUHJpbmNpcGFsUmVtYWluaW5nIDw9IDApCgkJCQlicmVhazsKCQl9CgkJcmV0dXJuIEZvcm1DYWxjLmNoZWNrUmVzdWx0KG5QcmluY2lwbGVQYWlkKTsKCX0KfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBwcmVzZW50IHZhbHVlIG9mIGFuIGludmVzdG1lbnQgb2YgcGVyaW9kaWMgY29uc3RhbnQgcGF5bWVudHMgYXQgYSBjb25zdGFudCAKICogaW50ZXJlc3QgcmF0ZS4KICoKICovCkZvcm1DYWxjLnB2ID0gZnVuY3Rpb24oblBheW1lbnQsIG5JbnRlcmVzdCwgblBlcmlvZHMpIHsKCUZvcm1DYWxjLmNoZWNrTWluQXJncyhhcmd1bWVudHMubGVuZ3RoLCAzKTsKCUZvcm1DYWxjLmNoZWNrTWF4QXJncyhhcmd1bWVudHMubGVuZ3RoLCAzKTsKCWlmIChuUGF5bWVudCA8PSAwIHx8IG5QZXJpb2RzIDw9IDAgKSB7CgkJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwoJfQoJaWYoblBheW1lbnQ9PW51bGwgfHwgbkludGVyZXN0PT1udWxsKXsKCQlyZXR1cm4gbnVsbDsKCX0KCXZhciBuUGF5bWVudCA9IHBhcnNlRmxvYXQoblBheW1lbnQpOwoJdmFyIG5JbnRlcmVzdCA9IHBhcnNlRmxvYXQobkludGVyZXN0KTsKCXZhciBuUGVyaW9kcyA9IHBhcnNlSW50KG5QZXJpb2RzKTsKCgl2YXIgblZhbDsKCWlmIChuSW50ZXJlc3QgPT0gMCkgewoJCW5WYWwgPSBuUGF5bWVudCAqIG5QZXJpb2RzOwoJfSBlbHNlIHsKCQluVmFsID0gblBheW1lbnQgKiAoMSAtIDEgLyBGb3JtQ2FsYy5pbnRSYXRlKG5JbnRlcmVzdCwgblBlcmlvZHMpKSAvIG5JbnRlcmVzdDsKCX0KCXJldHVybiBGb3JtQ2FsYy5jaGVja1Jlc3VsdChuVmFsKTsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBjb21wb3VuZCBpbnRlcmVzdCByYXRlIHBlciBwZXJpb2QgcmVxdWlyZWQgZm9yIGFuIGludmVzdG1lbnQgdG8gZ3JvdyBmcm9tCiAqIHByZXNlbnQgdG8gZnV0dXJlIHZhbHVlIGluIGEgZ2l2ZW4gcGVyaW9kLgogKiAKICovCkZvcm1DYWxjLnJhdGUgPSBmdW5jdGlvbihuRnV0dXJlLCBuUHJlc2VudCwgblBlcmlvZHMpIHsKCWlmIChuRnV0dXJlIDw9IDAuIHx8IG5QcmVzZW50IDw9IDAuIHx8IG5QZXJpb2RzIDw9IDApIHsKCQl0aHJvdyAiPG1pc3Npbmcgb3IgaWxsZWdhbCBwYXJhbWV0ZXIocykuPiI7Cgl9CgoJdmFyIG5GdXR1cmUgPSBwYXJzZUZsb2F0KG5GdXR1cmUpOwoJdmFyIG5QcmVzZW50ID0gcGFyc2VGbG9hdChuUHJlc2VudCk7Cgl2YXIgblBlcmlvZHMgPSBwYXJzZUludChuUGVyaW9kcyk7CgoJdmFyIG5SYXRlID0gTWF0aC5leHAoTWF0aC5sb2cobkZ1dHVyZSAvIG5QcmVzZW50KSAvIG5QZXJpb2RzKSAtIDE7CglyZXR1cm4gRm9ybUNhbGMuY2hlY2tSZXN1bHQoblJhdGUpOwp9OwoKLyoKICogVGVybSBUaGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIG51bWJlciBvZiBwZXJpb2RzIG5lZWRlZCBmb3IgYW4gaW52ZXN0bWVudAogKiBlYXJuaW5nIGEgZml4ZWQsIGJ1dCBjb21wb3VuZGVkIGludGVyZXN0IHJhdGUgdG8gZ3JvdyB0byBhIGZ1dHVyZSB2YWx1ZS4KICovCkZvcm1DYWxjLnRlcm0gPSBmdW5jdGlvbihuUGF5bWVudCwgbkludGVyZXN0LCBuRnV0dXJlKSB7Cgl2YXIgblBheW1lbnQgPSBGb3JtQ2FsYy5wYXJzZUZsb2F0T3JUaHJvd0Vycm9yKG5QYXltZW50KTsKCXZhciBuSW50ZXJlc3QgPSBGb3JtQ2FsYy5wYXJzZUZsb2F0T3JUaHJvd0Vycm9yKG5JbnRlcmVzdCk7Cgl2YXIgbkZ1dHVyZSA9IEZvcm1DYWxjLnBhcnNlRmxvYXRPclRocm93RXJyb3IobkZ1dHVyZSk7CgoJaWYgKG5QYXltZW50IDw9IDAuIHx8IG5JbnRlcmVzdCA8PSAwLiB8fCBuRnV0dXJlIDw9IDAuKSB7CgkJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwoJfQoJCgl2YXIgblBlcmlvZHM7CglpZiAobkZ1dHVyZSA8PSBuUGF5bWVudCkgewoJCW5QZXJpb2RzID0gMTsKCX0gZWxzZSB7CgkJblBlcmlvZHMgPSBNYXRoLmxvZygobkZ1dHVyZSAtIG5QYXltZW50KSAvIG5QYXltZW50ICogbkludGVyZXN0CgkJCQkrICgxICsgbkludGVyZXN0KSkKCQkJCS8gTWF0aC5sb2coMSArIG5JbnRlcmVzdCk7Cgl9CglyZXR1cm4gRm9ybUNhbGMuY2hlY2tSZXN1bHQoblBlcmlvZHMpOwp9OwoKRm9ybUNhbGMubG9hblRlcm0gPSBmdW5jdGlvbihuUHJpbmNpcGFsLCBuSW50ZXJlc3QsIG5QYXltZW50KSB7Cgl2YXIgblJlbWFpbmluZyA9IG5QcmluY2lwYWw7Cgl2YXIgbk1vbnRocyA9IDA7Cgl3aGlsZSAoblJlbWFpbmluZyA+IDAuMCkgewoJCW5SZW1haW5pbmcgPSBuUmVtYWluaW5nIC0gblBheW1lbnQgKyBuUmVtYWluaW5nICogbkludGVyZXN0OwoJCW5Nb250aHMrKzsKCX0KCXJldHVybiBGb3JtQ2FsYy5jaGVja1Jlc3VsdChuTW9udGhzKTsKfTsKLyoqCiAqIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBhIFVuaXZlcnNhbGx5IFVuaXF1ZSBJZGVudGlmaWVyIChVVUlEKS4KICovCkZvcm1DYWxjLnV1aWQgPSBmdW5jdGlvbihuMSkgewogICAgdmFyIFM0ID0gZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuICgoKDErTWF0aC5yYW5kb20oKSkqMHgxMDAwMCl8MCkudG9TdHJpbmcoMTYpLnN1YnN0cmluZygxKTsKICAgIH07CiAgICBpZihuMT09MSl7CiAgICAgICAgcmV0dXJuIChTNCgpK1M0KCkrIi0iK1M0KCkrIi0iK1M0KCkrIi0iK1M0KCkrIi0iK1M0KCkrUzQoKStTNCgpKTsKICAgIH1lbHNlewogICAgCXJldHVybiAoUzQoKStTNCgpK1M0KCkrUzQoKStTNCgpK1M0KCkrUzQoKStTNCgpKTsKICAgIH0KfTsKLy8gUHJpdmF0ZSBmdW5jdGlvbnMKCkZvcm1DYWxjLmxvYW5QbXQgPSBmdW5jdGlvbihuUHJpbmNpcGFsLCBuSW50ZXJlc3QsIG5QZXJpb2RzKSB7CglyZXR1cm4gKG5QcmluY2lwYWwgKiBuSW50ZXJlc3QgLyAoKDEgLSAxIC8gRm9ybUNhbGMuaW50UmF0ZShuSW50ZXJlc3QsIG5QZXJpb2RzKSkpKTsKfTsKCkZvcm1DYWxjLmludFJhdGUgPSBmdW5jdGlvbihuSW50ZXJlc3QsIG5QZXJpb2RzKSB7CglyZXR1cm4gTWF0aC5wb3coKDEgKyBuSW50ZXJlc3QpLCBuUGVyaW9kcykKfTsKCkZvcm1DYWxjLnBhcnNlRmxvYXRPclRocm93RXJyb3IgPSBmdW5jdGlvbihvYmopIHsKCXZhciBudW0gPSBOdW1iZXIob2JqKTsKCWlmKGlzTmFOKG51bSkpewoJCXRocm93ICI8bWlzc2luZyBvciBpbGxlZ2FsIHBhcmFtZXRlcihzKS4+IjsKCX1lbHNlewoJCXJldHVybiBudW07Cgl9Cn07CgpGb3JtQ2FsYy5wYXJzZUZsb2F0ID0gZnVuY3Rpb24ob2JqKSB7Cgl2YXIgbnVtID0gTnVtYmVyKG9iaik7CglpZihpc05hTihudW0pKXsKCQlyZXR1cm4gMDsKCX1lbHNlewoJCXJldHVybiBudW07Cgl9Cn07CgpGb3JtQ2FsYy5jaGVja1Jlc3VsdCA9IGZ1bmN0aW9uKHJlc3VsdCkgewoJaWYgKHJlc3VsdCA9PSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgfHwgcmVzdWx0ID09IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSl7CgkgICB0aHJvdyAiPGFyaXRobWV0aWMgb3Zlci91bmRlcmZsb3cuPiI7Cgl9ZWxzZXsKCQlyZXR1cm4gcmVzdWx0OwoJfQp9OwoKRm9ybUNhbGMuaXNOdW1lcmljID0gZnVuY3Rpb24oaW5wdXQpewoJcmV0dXJuIGlucHV0IT1udWxsICYmICFpc05hTihOdW1iZXIoaW5wdXQpKTsKfTsKCkZvcm1DYWxjLmNoZWNrTWluQXJncyA9IGZ1bmN0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpIHsKCWlmKGFjdHVhbCA8IGV4cGVjdGVkKXsKCQl0aHJvdyAiPG1pc3Npbmcgb3IgaWxsZWdhbCBwYXJhbWV0ZXIocykuPiI7Cgl9Cn07CgpGb3JtQ2FsYy5jaGVja01heEFyZ3MgPSBmdW5jdGlvbihhY3R1YWwsIGV4cGVjdGVkKSB7CglpZihhY3R1YWwgPiBleHBlY3RlZCl7CgkJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwoJfQp9OwoKRm9ybUNhbGMubGltaXRBbGxOdWxsQXJncyA9IGZ1bmN0aW9uKGFycmF5QXJndXMpIHsKCXZhciByZXN1bHQgPSBuZXcgQXJyYXkoKTsKCWZvcih2YXIgaT0wO2k8YXJyYXlBcmd1cy5sZW5ndGg7aSsrKXsKCQlpZihhcnJheUFyZ3VzW2ldIT1udWxsKXsKCQkJcmVzdWx0LnB1c2goYXJyYXlBcmd1c1tpXSk7CgkJfQoJfQoJcmV0dXJuIHJlc3VsdDsKfTsKCkZvcm1DYWxjLnJ1bldpdGhvdXROdWxsQXJncyA9IGZ1bmN0aW9uKGZ1bmMsIGFycmF5QXJndXMpIHsKCXZhciBhcmd1cyA9IEZvcm1DYWxjLmxpbWl0QWxsTnVsbEFyZ3MoYXJyYXlBcmd1cyk7CglyZXR1cm4gYXJndXMubGVuZ3RoID8gZnVuYy5hcHBseShudWxsLGFyZ3VzKSA6IG51bGw7CQp9OwoKRm9ybUNhbGMucnVuV2l0aE51bWVyaWNBcmdzID0gZnVuY3Rpb24oZnVuYywgYXJyYXlBcmd1cykgewoJdmFyIGFyZ3VzID0gbmV3IEFycmF5KCk7Cglmb3IodmFyIGk9MDtpPGFycmF5QXJndXMubGVuZ3RoO2krKyl7CgkJaWYoYXJyYXlBcmd1c1tpXSE9bnVsbCl7CiAgICAgICAgCXZhciBlbCA9IHBhcnNlRmxvYXQoYXJyYXlBcmd1c1tpXSk7CiAgICAgICAgCWlmKCFpc05hTihlbCkpewogICAgICAgIAkJYXJndXMucHVzaChlbCk7CiAgICAgICAgCX0KCQl9Cgl9CgoJcmV0dXJuIGFyZ3VzLmxlbmd0aCA/IGZ1bmMuYXBwbHkobnVsbCxhcmd1cykgOiBudWxsOwkKfTsKCi8qKgogKiBUaGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIEVuZ2xpc2ggdGV4dCBlcXVpdmFsZW50IG9mIGEgZ2l2ZW4gbnVtYmVyLgogKiAKICovCkZvcm1DYWxjLldvcmROdW09ZnVuY3Rpb24oKXsKCXZhciBPbmVzPSBuZXcgQXJyYXkoIlplcm8iLCJPbmUiLCJUd28iLCJUaHJlZSIsIkZvdXIiLCJGaXZlIiwKCQkJIlNpeCIsIlNldmVuIiwiRWlnaHQiLCJOaW5lIik7Cgl2YXIgVGVlbnMgPW5ldyBBcnJheSAoIlRlbiIsIkVsZXZlbiIsIlR3ZWx2ZSIsIlRoaXJ0ZWVuIiwiRm91cnRlZW4iLAoJCQkiRmlmdGVlbiIsICJTaXh0ZWVuIiwgIlNldmVudGVlbiIsICJFaWdodGVlbiIsICJOaW5ldGVlbiIpOwoJdmFyIFRlbnM9IG5ldyBBcnJheSAoCgkJCSJaZXJvIiwgICJUZW4iLCAgICJUd2VudHkiLCAgIlRoaXJ0eSIsICJGb3J0eSIsCgkJCSJGaWZ0eSIsICJTaXh0eSIsICJTZXZlbnR5IiwgIkVpZ2h0eSIsICJOaW5ldHkiLCAiSHVuZHJlZCIgKTsKCXZhciBUaG91c2FuZHMgPSBuZXcgQXJyYXkgKAoJCQkiVGhvdXNhbmQiLCAiTWlsbGlvbiIsICAgICAiQmlsbGlvbiIsCgkJCSJUcmlsbGlvbiIsICJRdWFkcmlsbGlvbiIsICJRdWludGlsbGlvbiIgKTsKCXZhciBDZW50cyA9IG5ldyBBcnJheSgiQ2VudCIpOyAKCXZhciBDb21tYT1uZXcgQXJyYXkoIiIpOwoJdmFyIEFuZHMgID1uZXcgQXJyYXkgKCIiLCAiQW5kICIgLyogdXNlZCBieSBGRjk5ICovICk7Cgl2YXIgRG9sbGFycz1uZXcgQXJyYXkgKCAiRG9sbGFyIiApOwoJdmFyIFNwYWNlID0gIiAiOwoJdmFyIEh5cGhlbiA9ICItIjsKCXZhciBRVUlOVElMTElPTiA9IDEwMDAwMDAwMDAwMDAwMDAwMDA7Cgl2YXIgbj1hcmd1bWVudHNbMF07Cgl2YXIgZj1hcmd1bWVudHNbMV07CglpZihuID09PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICBpZihpc05hTihuKXx8IWlzRmluaXRlKG4pfHxuPDApewoJCXJldHVybiAiKioqKioqKioqKioqKioiOyAKCX0KCQoJaWYgKGYgPCAwIHx8IDIgPCBmKSB7CgkJZiA9IDA7Cgl9CgkKCXZhciBkb2xsYXJzID0gICBuOwoJdmFyIGNlbnRzID0gICAgTWF0aC5mbG9vcigoKG4gLSAgTWF0aC5mbG9vcihkb2xsYXJzKSsgMC4wMDUpICogMTAwKSk7ICAKCWlmIChjZW50cyA+PSAxMDApIHsKCQlkb2xsYXJzICs9IDE7CgkJY2VudHMgLT0gMTAwOwoJfQoJCgl2YXIgcz0gbmV3IEFycmF5KCk7Cgl2YXIgdGhvdXNhbmRzID0gNjsKCWZvciAodmFyIGRpdiA9IFFVSU5USUxMSU9OOyBkaXYgPj0gMSA7IGRpdi89MTAwMCkgeyAKCQl2YXIgbnVtYmVyID0gTWF0aC5mbG9vcihkb2xsYXJzIC8gZGl2KSA7IAoJCXZhciBodW5kcmVkcyA9IE1hdGguZmxvb3IobnVtYmVyLyAxMDApIDsKCQl2YXIgdGVucyA9IE1hdGguZmxvb3IoKG51bWJlci0gaHVuZHJlZHMgKiAxMDApIC8gMTApOwoJCXZhciBvbmVzID0gTWF0aC5mbG9vcihudW1iZXItIGh1bmRyZWRzICogMTAwIC0gdGVucyAqIDEwKTsgIAogICAgICAgICAgICAgICAgaWYobnVtYmVyPj0xKXsKICAgICAgICAgICAgICAgICAgICBkb2xsYXJzIC09IChkaXYgKiBudW1iZXIgKTsgCiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAKCQlpZiAoaHVuZHJlZHMgPj0xKSB7CgkJCXMucHVzaChPbmVzW2h1bmRyZWRzXSk7CgkJCXMucHVzaChTcGFjZSk7CgkJCXMucHVzaChUZW5zWzEwXSk7CgkJCXMucHVzaChTcGFjZSk7CgkJCWlmICh0ZW5zID4gMCB8fCBvbmVzID4gMCkKCQkJCXMucHVzaChBbmRzWzBdKTsKCQl9CgkJaWYgKHRlbnMgPj0xICkgewoJCQlzLnB1c2goKHRlbnMgPT0gMSkgPyBUZWVuc1tvbmVzXSA6IFRlbnNbdGVuc10pOwoJCQlzLnB1c2goKG9uZXMgPiAwICYmIHRlbnMgIT0gMSkgPyBIeXBoZW4gOiBTcGFjZSk7CgkJfQoJCWlmIChvbmVzID49MSAmJiB0ZW5zICE9IDEpIHsgCgkJCWlmICh0ZW5zID4gMCAmJiBvbmVzID4gMCkgewoJCQkJLy8gc2FmZSBzaW5jZSBPbmVzIGNvbnRhaW5zIHRydWUgbGl0ZXJhbCBjb25zdGFudHMKCQkJCXZhciBvID0gT25lc1tvbmVzXTsKCQkJCS8vcys9Rm9ybUNhbGMuTXlsb3dlckNhc2Uobyk7ICAKCQkJCXMucHVzaChvLnRvTG93ZXJDYXNlKCkpOyAKCQkJfQoJCQllbHNlIHsKCQkJCXMucHVzaChPbmVzW29uZXNdKTsKCQkJfQoJCQlzLnB1c2goU3BhY2UpOwoJCX0KCQl0aG91c2FuZHMtLTsKCQlpZiAodGhvdXNhbmRzID49IDAgJiYgbnVtYmVyID49IDEpIHsKCQkJcy5wdXNoKFRob3VzYW5kc1t0aG91c2FuZHNdKTsKCQkJcy5wdXNoKENvbW1hWzBdKTsKCQkJcy5wdXNoKFNwYWNlKTsKCQl9CiAKICAKCX0KCS8vCgkvLyBJZiBsZXNzIHRoYW4gb25lIHRoZW4gdXNlIHplcm8uCgkvLwoJaWYgKG4gPCAxLikgewoJCXMucHVzaChPbmVzWzBdKTsKCQlzLnB1c2goU3BhY2UpOwoJfQoJLy8KCS8vIEZhY3RvciBpbiBmb3JtYXQ6CgkvLyAgICAgMCA9PiAiT25lIEh1bmRyZWQgVHdlbnR5LXRocmVlIgoJLy8gICAgIDEgPT4gIk9uZSBIdW5kcmVkIFR3ZW50eS10aHJlZSBEb2xsYXJzIgoJLy8gICAgIDIgPT4gIk9uZSBIdW5kcmVkIFR3ZW50eS10aHJlZSBEb2xsYXJzIEFuZCBGb3J0eSBDZW50cyIKCS8vCglpZiAoZiA9PSAxIHx8IGYgPT0gMikgewoJCS8vCgkJLy8gQXBwZW5kIGRvbGxhciBDYWxjU3ltYm9sLgoJCS8vCgkJcy5wdXNoKERvbGxhcnNbMF0pOwoJCWlmICggTWF0aC5mbG9vcihuKSAhPSAxKQoJCQlzLnB1c2goJ3MnKTsKCQkvLwoJCS8vIEFwcGVuZCBjZW50cy4KCQkvLwoJCWlmIChmID09IDIpIHsKCQkJcy5wdXNoKFNwYWNlKTsKCQkJcy5wdXNoKEFuZHNbMV0pOwoJCQl2YXIgdGVucyA9ICBNYXRoLmZsb29yKGNlbnRzIC8gMTApOwoJCQl2YXIgb25lcyA9ICBNYXRoLmZsb29yKGNlbnRzIC0gdGVucyAqIDEwKTsKCQkJaWYgKHRlbnMgPiAwKSB7CgkJCQlzLnB1c2goKHRlbnMgPT0gMSkgPyBUZWVuc1tvbmVzXSA6IFRlbnNbdGVuc10pOwoJCQl9CgkJCWlmICh0ZW5zICE9IDEpIHsKCQkJCWlmICh0ZW5zID4gMCAmJiBvbmVzID4gMCkgewoJCQkJCS8vIHNhZmUgc2luY2UgT25lcyBjb250YWlucyB0cnVlIGxpdGVyYWwgY29uc3RhbnRzCgkJCQkJdmFyIG8gPSBPbmVzW29uZXNdOwoJCQkJCXMucHVzaChIeXBoZW4pOwoJCQkJCXMucHVzaChvLnRvTG93ZXJDYXNlKCkpOwoJCQkJfQoJCQkJZWxzZSBpZiAodGVucyA9PSAwKSB7CgkJCQkJcy5wdXNoKE9uZXNbb25lc10pOwoJCQkJfQoJCQl9CgkJCXMucHVzaChTcGFjZSk7CgkJCXMucHVzaChDZW50c1swXSk7CgkJCWlmIChjZW50cyAhPSAxLikKCQkJCXMucHVzaCgncycpOwoJCX0KCX0KCWlmKHNbcy5sZW5ndGgtMV0gPT0gJyAnKXsKCQlzLnBvcCgpOwkJCgl9CglyZXR1cm4gcy5qb2luKCIiKTsKfTsKCkZvcm1DYWxjLl9BY2Nlc3NvciA9IGZ1bmN0aW9uKGEpIHsKICAgIGlmKGEgJiYgdHlwZW9mKGEpID09PSAib2JqZWN0IikgewogICAgICAgIGlmKGEuY2xhc3NOYW1lID09PSAiZmllbGQiIHx8IGEuY2xhc3NOYW1lID09PSAiZXhjbEdyb3VwIikKICAgICAgICAgICAgcmV0dXJuIGEucmF3VmFsdWU7CiAgICB9CiAgICByZXR1cm4gYTsKfTsKCkZvcm1DYWxjLl9BcnJheUFjY2Vzc29yID0gZnVuY3Rpb24oYSkgewogICAgaWYodHlwZW9mKGEpID09ICJzdHJpbmciKSB7CiAgICAgICAgdmFyIGluZGV4QXJyYXkgPSBhLmxhc3RJbmRleE9mKCJdIikrIDEsCiAgICAgICAgICAgIG5vZGUgPSBhLnN1YnN0cigwLCBpbmRleEFycmF5KSwKICAgICAgICAgICAgcHJvcEluZGV4ID0gYS5pbmRleE9mKCIuIixpbmRleEFycmF5KSwKICAgICAgICAgICAgcHJvcCA9IHByb3BJbmRleCA9PSAtMSA/ICIiIDogYS5zdWJzdHIocHJvcEluZGV4ICsgMSwgYS5sZW5ndGgpLAogICAgICAgICAgICBjdHhOb2RlID0geGZhbGliLnJ1bnRpbWUueGZhLl9jb250ZXh0Tm9kZSgpLAogICAgICAgICAgICBsaXN0ID0gY3R4Tm9kZS5yZXNvbHZlTm9kZXMobm9kZSksCiAgICAgICAgICAgIHJldEFycmF5ID0gW10KICAgICAgICBmb3IodmFyIGkgPSAwO2k8bGlzdC5sZW5ndGg7aSsrKSB7CiAgICAgICAgICAgIHZhciBpdGVtID0gbGlzdC5pdGVtKGkpLAogICAgICAgICAgICAgICAgdmFsID0gcHJvcC5sZW5ndGggPyB0aGlzLl9BY2Nlc3NvcihpdGVtW3Byb3BdKSA6dGhpcy5fQWNjZXNzb3IoaXRlbSk7CiAgICAgICAgICAgIHJldEFycmF5LnB1c2godmFsKTsKICAgICAgICB9CiAgICAgICAgaWYocmV0QXJyYXkubGVuZ3RoID09IDEpCiAgICAgICAgICAgIHJldHVybiByZXRBcnJheVswXQogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuIHJldEFycmF5OwogICAgfQogICAgcmV0dXJuIGE7Cn07CgpGb3JtQ2FsYy5lcG9jaCA9IG5ldyBEYXRlKDE5MDAsMCwxKQpGb3JtQ2FsYy5lcG9jaFRpbWUgPSBGb3JtQ2FsYy5lcG9jaC5nZXRUaW1lKCkKRm9ybUNhbGMubnVtTWlsbGlzSW5EYXkgPSAyNCo2MCo2MCoxMDAwCkZvcm1DYWxjLkRhdGVGb3JtYXRzPSBbIm1lZCIsInNob3J0IiwibWVkIiwibG9uZyIsImZ1bGwiXQoKRm9ybUNhbGMubnVtMmRhdGUgPSBmdW5jdGlvbihuLGZtdCxsb2NhbGUpIHsKICAgIGZ1bmN0aW9uIHBhZDIobnVtKSB7CiAgICAgICAgcmV0dXJuICgrbnVtKT45ID8gbnVtKyIiIDogIjAiK251bTsKICAgIH0KICAgIGxvY2FsZSA9IGxvY2FsZSB8fCAiZW5fVVMiCiAgICBmbXQgPSBmbXQgfHwgRm9ybUNhbGMuRGF0ZUZtdCgwLGxvY2FsZSk7CiAgICB2YXIgZXBvY2ggPSBuZXcgRGF0ZSgxOTAwLDAsMSkKICAgIGVwb2NoLnNldERhdGUobik7CiAgICB2YXIgaW5wdXREYXRlID0gZXBvY2guZ2V0RnVsbFllYXIoKSsiLSIrcGFkMigoZXBvY2guZ2V0TW9udGgoKSsxKSkrIi0iK3BhZDIoZXBvY2guZ2V0RGF0ZSgpKTsKICAgIHJldHVybiB4ZmFsaWIudXQuUGljdHVyZUZtdC5mb3JtYXREYXRlKGlucHV0RGF0ZSxmbXQsbG9jYWxlKTsKfQoKRm9ybUNhbGMuZGF0ZSA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1hdGguY2VpbCgobmV3IERhdGUoKS5nZXRUaW1lKCkgLSB0aGlzLmVwb2NoVGltZSkvdGhpcy5udW1NaWxsaXNJbkRheSkKfQoKRm9ybUNhbGMuRGF0ZUZtdCA9IGZ1bmN0aW9uKHN5bWJvbCxsb2NhbGUpIHsKICAgIHN5bWJvbCA9IHN5bWJvbCB8fCAwCiAgICBsb2NhbGUgPSBsb2NhbGUgfHwgImVuX1VTIgogICAgcmV0dXJuIHhmYWxpYi5zY3JpcHQuWGZhLkluc3RhbmNlLl9nZXRMb2NhbGVTeW1ib2xzKGxvY2FsZSwiZGF0ZVBhdHRlcm5zLiIrRm9ybUNhbGMuRGF0ZUZvcm1hdHNbc3ltYm9sXSkKfTsKLyoKICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqIF9fX19fX19fX19fX19fX19fXwogKgogKiBDb3B5cmlnaHQgMjAxNSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiBzdXBwbGllcnMgYW5kIG1heSBiZSBjb3ZlcmVkIGJ5IFUuUy4gYW5kIEZvcmVpZ24gUGF0ZW50cywKICogcGF0ZW50cyBpbiBwcm9jZXNzLCBhbmQgYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqLwoKKGZ1bmN0aW9uICgkKSB7CiAgICAkLnVhTWF0Y2ggPSBmdW5jdGlvbiggdWEgKSB7CiAgICAgICAgdWEgPSB1YS50b0xvd2VyQ2FzZSgpOwogICAgICAgIHZhciBtYXRjaCA9IC8oY2hyb21lKVsgXC9dKFtcdy5dKykvLmV4ZWMoIHVhICkgfHwKICAgICAgICAgICAgLyh3ZWJraXQpWyBcL10oW1x3Ll0rKS8uZXhlYyggdWEgKSB8fAogICAgICAgICAgICAvKG9wZXJhKSg/Oi4qdmVyc2lvbnwpWyBcL10oW1x3Ll0rKS8uZXhlYyggdWEgKSB8fAogICAgICAgICAgICAvKG1zaWUpIChbXHcuXSspLy5leGVjKCB1YSApIHx8CiAgICAgICAgICAgIHVhLmluZGV4T2YoImNvbXBhdGlibGUiKSA8IDAgJiYgLyhtb3ppbGxhKSg/Oi4qPyBydjooW1x3Ll0rKXwpLy5leGVjKCB1YSApIHx8IFtdOwogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIGJyb3dzZXI6IG1hdGNoWyAxIF0gfHwgIiIsCiAgICAgICAgICAgIHZlcnNpb246IG1hdGNoWyAyIF0gfHwgIjAiCiAgICAgICAgfTsKICAgIH07CiAgICAvLyBOb3QgY2xvYmJlcmluZyBhbnkgZXhpc3RpbmcgJC5icm93c2VyCiAgICBpZiAoICEkLmJyb3dzZXIgKSB7CiAgICAgICAgdmFyCiAgICAgICAgICAgIG1hdGNoZWQgPSAkLnVhTWF0Y2goIG5hdmlnYXRvci51c2VyQWdlbnQgKSwKICAgICAgICAgICAgYnJvd3NlciA9IHt9OwogICAgICAgIGlmICggbWF0Y2hlZC5icm93c2VyICkgewogICAgICAgICAgICBicm93c2VyWyBtYXRjaGVkLmJyb3dzZXIgXSA9IHRydWU7CiAgICAgICAgICAgIGJyb3dzZXIudmVyc2lvbiA9IG1hdGNoZWQudmVyc2lvbjsKICAgICAgICB9CiAgICAgICAgLy8gQ2hyb21lIGlzIFdlYmtpdCwgYnV0IFdlYmtpdCBpcyBhbHNvIFNhZmFyaS4KICAgICAgICBpZiAoIGJyb3dzZXIuY2hyb21lICkgewogICAgICAgICAgICBicm93c2VyLndlYmtpdCA9IHRydWU7CiAgICAgICAgfSBlbHNlIGlmICggYnJvd3Nlci53ZWJraXQgKSB7CiAgICAgICAgICAgIGJyb3dzZXIuc2FmYXJpID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgJC5icm93c2VyID0gYnJvd3NlcjsKICAgIH0KfSkoJCk7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX19fCiAqCiAqICBDb3B5cmlnaHQgMjAxMyBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LkNsYXNzCiAqLwooZnVuY3Rpb24oXywgeGZhbGliKXsKCiAgICB4ZmFsaWIubnMgPSB4ZmFsaWIubnMgfHwgZnVuY3Rpb24gKG5hbWVzcGFjZVN0cmluZykgewogICAgICAgIHZhciBwYXJ0cyA9IG5hbWVzcGFjZVN0cmluZy5zcGxpdCgnLicpLAogICAgICAgICAgICBwYXJlbnQgPSB3aW5kb3csCiAgICAgICAgICAgIGN1cnJlbnRQYXJ0ID0gJyc7CgogICAgICAgIGZvcih2YXIgaSA9IDAsIGxlbmd0aCA9IHBhcnRzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGN1cnJlbnRQYXJ0ID0gcGFydHNbaV07CiAgICAgICAgICAgIHBhcmVudFtjdXJyZW50UGFydF0gPSBwYXJlbnRbY3VycmVudFBhcnRdIHx8IHt9OwogICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnRbY3VycmVudFBhcnRdOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHBhcmVudDsKICAgIH07CgogICAgdmFyIENsYXNzID0geGZhbGliLnV0LkNsYXNzID0gZnVuY3Rpb24ob3B0aW9ucykgewogICAgICAgIHRoaXMub3B0aW9ucyA9IF8uZXh0ZW5kKHt9LCB0aGlzLm9wdGlvbnMsIG9wdGlvbnMpOwogICAgICAgIGlmKCF0aGlzLm9wdGlvbnMuanNvbk1vZGVsKQogICAgICAgICAgICB0aGlzLm9wdGlvbnMuanNvbk1vZGVsID0ge307CiAgICAgICAgLy9Gb3IgcGVyZiByZWFzb24sIHdlIGFyZSBzZXR0aW5nIGpzb25Nb2RlbCBhcyBkaXJlY3QgcHJvcGVydHkgaW5zdGVhZCBvZiB1c2luZyBwcm9wZXJ0eSBkZXNjcmlwdG9yCiAgICAgICAgdGhpcy5qc29uTW9kZWwgPSB0aGlzLm9wdGlvbnMuanNvbk1vZGVsOwogICAgICAgIHRoaXMuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgfTsKCiAgICBfLmV4dGVuZChDbGFzcy5wcm90b3R5cGUsIHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICB9LAoKICAgICAgICB4ZmFVdGlsIDpmdW5jdGlvbigpewogICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZTsKICAgICAgICB9LAoKICAgICAgICBjb3B5QXJyYXkgOiBmdW5jdGlvbihzcmMsZHN0LG9wdGlvbnMpIHsKICAgICAgICAgICAgdmFyIGtlZXBSZWZlcmVuY2UgPSB0aGlzLmdldE9yRWxzZShvcHRpb25zLCAia2VlcFJlZmVyZW5jZSIsIHRydWUpOwogICAgICAgICAgICBpZihzcmMgaW5zdGFuY2VvZiBBcnJheSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7aTxzcmMubGVuZ3RoO2krKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgb2JqOwogICAgICAgICAgICAgICAgICAgIGlmKHNyY1tpXSBpbnN0YW5jZW9mIEFycmF5KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgb2JqID0gdGhpcy5fY3JlYXRlRGVzdGluYXRpb24oZHN0LCBpLCBrZWVwUmVmZXJlbmNlLCBbXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29weUFycmF5KHNyY1tpXSxvYmosb3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYodHlwZW9mIHNyY1tpXSA9PSAib2JqZWN0IikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9iaiA9IHRoaXMuX2NyZWF0ZURlc3RpbmF0aW9uKGRzdCwgaSwga2VlcFJlZmVyZW5jZSwge30pOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvcHlPYmplY3Qoc3JjW2ldLG9iaixvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBvYmogPSBzcmNbaV07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRzdFtpXSA9IG9iajsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGRzdC5sZW5ndGggPiBzcmMubGVuZ3RoKXsKICAgICAgICAgICAgICAgICAgICBkc3Quc3BsaWNlKHNyYy5sZW5ndGgsIChkc3QubGVuZ3RoIC0gc3JjLmxlbmd0aCkpOyAgLy9SZW1vdmUgdGhzIHJlc3Qgb2YgdGhlIGV4dHJhIGRlc3RpbmF0aW9uIGl0ZW1zCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBzcmMKICAgICAgICAgKiBAcGFyYW0gZHN0CiAgICAgICAgICogQHBhcmFtIG9wdGlvbnMgZS5nLiB7a2VlcFJlZmVyZW5jZTogdHJ1ZSwgZXhjZXB0aW9uczpbImh0bWxJZCJdLCB0cmFuc2Zvcm1NYXBzOiB7ImRhdGFJZCIsIGZ1bmN0aW9uKHNyYywgb3B0aW9ucyl7IHJldHVybiBzcmMgIjMzIitzcmM7IH19fQogICAgICAgICAqLwogICAgICAgIGNvcHlPYmplY3QgOiBmdW5jdGlvbihzcmMsZHN0LG9wdGlvbnMpIHsKICAgICAgICAgICAgdmFyIGtlZXBSZWZlcmVuY2UgPSB0aGlzLmdldE9yRWxzZShvcHRpb25zLCAia2VlcFJlZmVyZW5jZSIsIHRydWUpOwogICAgICAgICAgICB2YXIgZXhjZXB0aW9ucyA9IHRoaXMuZ2V0T3JFbHNlKG9wdGlvbnMsICJleGNlcHRpb25zIiwgW10pOwogICAgICAgICAgICB2YXIgdHJhbnNmb3JtTWFwcyA9IHRoaXMuZ2V0T3JFbHNlKG9wdGlvbnMsICJ0cmFuc2Zvcm1NYXBzIiwge30pOwogICAgICAgICAgICBpZih0eXBlb2Ygc3JjID09ICJvYmplY3QiKSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBjaGlsZCBpbiBzcmMpIHsKICAgICAgICAgICAgICAgICAgICBpZihleGNlcHRpb25zLmluZGV4T2YoY2hpbGQpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHNyY1tjaGlsZF0gaW5zdGFuY2VvZiBBcnJheSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0W2NoaWxkXSA9IHRoaXMuX2NyZWF0ZURlc3RpbmF0aW9uKGRzdCwgY2hpbGQsIGtlZXBSZWZlcmVuY2UsIFtdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29weUFycmF5KHNyY1tjaGlsZF0sZHN0W2NoaWxkXSxvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKHR5cGVvZiBzcmNbY2hpbGRdID09ICJvYmplY3QiICYmIHNyY1tjaGlsZF0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0W2NoaWxkXSA9IHRoaXMuX2NyZWF0ZURlc3RpbmF0aW9uKGRzdCwgY2hpbGQsIGtlZXBSZWZlcmVuY2UsIHt9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29weU9iamVjdChzcmNbY2hpbGRdLGRzdFtjaGlsZF0sb3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCFfLmlzVW5kZWZpbmVkKHRyYW5zZm9ybU1hcHNbY2hpbGRdKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0W2NoaWxkXSA9IHRyYW5zZm9ybU1hcHNbY2hpbGRdKHNyY1tjaGlsZF0sIG9wdGlvbnMsIHNyYyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0W2NoaWxkXSA9IHNyY1tjaGlsZF07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlRGVzdGluYXRpb24gOiBmdW5jdGlvbihvYmosIHByb3BlcnR5LCBrZWVwUmVmZXJlbmNlLCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICAgICAgaWYoIWtlZXBSZWZlcmVuY2UpCiAgICAgICAgICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlOwogICAgICAgICAgICBlbHNlIGlmKF8uaXNPYmplY3Qob2JqKSAmJiAhb2JqLmhhc093blByb3BlcnR5KHByb3BlcnR5KSkKICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBvYmpbcHJvcGVydHldIHx8IGRlZmF1bHRWYWx1ZSA7ICAvL1dvdWxkIGhhbmRsZSBib3RoLCBBcnJheSBhbmQgb2JqZWN0cwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIHdpbGwgcmVwbGFjZSBmdW5jdGlvbnMgaW4gdGhlIG9iamVjdCB3aXRoIG5vb3AgZnVuY3Rpb24gYmFzZWQgb24gYSBwcmVkaWNhdGUgZnVuY3Rpb24ncyByZXN1bHQuCiAgICAgICAgICogSWYgbm8gcHJlZGljYXRlIGlzIHBhc3NlZCBhbGwgZnVuY3Rpb25zIHdpbGwgYmUgZGlzYWJsZWQuCiAgICAgICAgICogV2FybmluZyBvbmNlIGRpc2FibGVkIG9iamVjdCBjYW50IGJlIHJlLWVuYWJsZWQuCiAgICAgICAgICoKICAgICAgICAgKiBzYW1wbGUgcHJlZGljYXRlIHRvIGRpc2FibGUgYWxsICdwdWJsaWMnIGZ1bmN0aW9ucyA6IGZ1bmN0aW9uIChmdW5jTmFtZSkgeyByZXR1cm4gZnVuY05hbWVbMF0gIT0gJ18nfQogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHByZWRpY2F0ZQogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2Rpc2FibGVGdW5jdGlvbnM6IGZ1bmN0aW9uIChwcmVkaWNhdGUpIHsKICAgICAgICAgICAgdmFyIG5vb3AgPSBmdW5jdGlvbiAoKSB7fSwKICAgICAgICAgICAgICAgIGRpc2FibGVBbGwgPSAhXy5pc0Z1bmN0aW9uKHByZWRpY2F0ZSk7CgogICAgICAgICAgICBfLmVhY2goXy5mdW5jdGlvbnModGhpcyksIGZ1bmN0aW9uIChmdW5jTmFtZSkgewogICAgICAgICAgICAgICAgaWYgKGRpc2FibGVBbGwgfHwgcHJlZGljYXRlKGZ1bmNOYW1lKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXNbZnVuY05hbWVdID0gbm9vcDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogZ2V0T3JFbHNlIGNhbiB0YWtlIG11bHRpcGxlIGFyZ3VtZW50cy4KICAgICAgICAgKiBhcmcxKG9iaik6IGJhc2UgT2JqZWN0CiAgICAgICAgICogYXJnMjogc3RyaW5nIHJlcHJlc2VudGluZyBwcm9wZXJ0eSBjaGFpbiB3aGVyZSBwcm9wZXJ0aWVzIGFyZSBjb25jYXRlbmF0ZWQgdmlhIGRvdAogICAgICAgICAqIGFyZzM6IGRlZmF1bHQgdmFsdWUKICAgICAgICAgKiovCgogICAgICAgIGdldE9yRWxzZSA6IGZ1bmN0aW9uKG9iail7CiAgICAgICAgICAgIHZhciBjdXJyT2JqZWN0ID0gb2JqOwogICAgICAgICAgICBpZihhcmd1bWVudHMubGVuZ3RoIDwgMikKICAgICAgICAgICAgICAgIHJldHVybiBjdXJyT2JqZWN0OwogICAgICAgICAgICBlbHNlIGlmKGFyZ3VtZW50cy5sZW5ndGggPT0gMikgewogICAgICAgICAgICAgICAgaWYoIV8uaXNVbmRlZmluZWQoY3Vyck9iamVjdCkpewogICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyT2JqZWN0OwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gXy5jbG9uZShhcmd1bWVudHNbMV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgdmFyIHByb3BDaGFpbiA9IChhcmd1bWVudHNbMV0gfHwgIiIpLnNwbGl0KCIuIik7CiAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdFZhbHVlID0gYXJndW1lbnRzWzJdOwogICAgICAgICAgICAgICAgXy5lYWNoKHByb3BDaGFpbiwgZnVuY3Rpb24ocHJvcCl7CiAgICAgICAgICAgICAgICAgICAgaWYoXy5pc09iamVjdChjdXJyT2JqZWN0KSkKICAgICAgICAgICAgICAgICAgICAgICAgY3Vyck9iamVjdCA9IGN1cnJPYmplY3RbcHJvcF07CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBjdXJyT2JqZWN0ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICAgICAgaWYoIV8uaXNVbmRlZmluZWQoY3Vyck9iamVjdCkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJPYmplY3Q7CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gXy5jbG9uZShkZWZhdWx0VmFsdWUpIDsgLy9NYXkgaGF2ZSB0byBkbyBkZWVwIGNsb25lIGluIGZ1dHVyZS4gVE9ETzogc3VwcG9ydCBmb3IgY29uZGl0aW9uYWwgY2xvbmUKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGpxSWQ6IGZ1bmN0aW9uIChpZCkgewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmpxSWQoaWQpOwogICAgICAgIH0sCgogICAgICAgIGxvZ2dlciA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnhmYVV0aWwoKS5nZXRMb2dnZXIoKTsKICAgICAgICB9LAoKICAgICAgICB2YWxpZGF0ZUlucHV0IDogZnVuY3Rpb24ocGFyYW0sIGRhdGFUeXBlLGZhbGxiYWNrKXsKICAgICAgICAJaWYodHlwZW9mIHBhcmFtICE9PSAidW5kZWZpbmVkIiAmJiBwYXJhbSAhPT0gbnVsbCkgewogICAgICAgIAkJc3dpdGNoKGRhdGFUeXBlKSB7CiAgICAgICAgCQljYXNlICJzdHJpbmciOgogICAgICAgIAkJCXBhcmFtID0gcGFyYW0rIiI7CiAgICAgICAgCQkJYnJlYWs7CiAgICAgICAgCQljYXNlICJvYmplY3QiOgogICAgICAgIAkJCWlmKHR5cGVvZiBwYXJhbSAhPT0gIm9iamVjdCIpCiAgICAgICAgCQkJCXBhcmFtID0gZmFsbGJhY2s7CiAgICAgICAgCQkJYnJlYWs7CiAgICAgICAgCSAgICBjYXNlICJpbnRlZ2VyIjoKICAgICAgICAgICAgICAgICAgICBwYXJhbSA9IHBhcnNlSW50KHBhcmFtKTsKICAgICAgICAgICAgICAgICAgICBpZihpc05hTihwYXJhbSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtID0gZmFsbGJhY2s7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgIGNhc2UgIm1lYXN1cmVtZW50IjoKICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgCQlkZWZhdWx0OgogICAgICAgIAkJCWlmKGRhdGFUeXBlIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIX5kYXRhVHlwZS5pbmRleE9mKHBhcmFtKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtID0gZmFsbGJhY2sKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgCQl9CiAgICAgICAgCX0KICAgICAgICAJcmV0dXJuIHBhcmFtOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBfLmV4dGVuZChDbGFzcywgewogICAgICAgIGRlZmluZVByb3BzIDogZnVuY3Rpb24ocHJvcHNNYXApewogICAgICAgICAgICBfLmVhY2gocHJvcHNNYXAsIGZ1bmN0aW9uKHByb3BEZXNjLCBwcm9wTmFtZSl7CiAgICAgICAgICAgICAgICAvL0NoZWNrIHByb3BlcnR5IGNhbiBiZSByZXNvbHZlZCB1c2luZyByZXNvbHZlTm9kZQogICAgICAgICAgICAgICAgaWYocHJvcERlc2MucmVzb2x2ZSkgewogICAgICAgICAgICAgICAgICAgIC8vQ2hlY2sgd2hldGhlciBwcm90b3R5cGUgb3ducyB0aGUgb2JqZWN0IHJlc29sdmVQcm9wZXJ0aWVzCiAgICAgICAgICAgICAgICAgICAgaWYoIXRoaXMucHJvdG90eXBlLmhhc093blByb3BlcnR5KCJyZXNvbHZlUHJvcGVydGllcyIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vY2hlY2sgd2hldGhlciBwcm90b3R5cGUgaW5oZXJpdHMgdGhlIG9iamVjdCByZXNvbHZlUHJvcGVydGllcwogICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLnByb3RvdHlwZS5yZXNvbHZlUHJvcGVydGllcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9jbG9uZSB0aGUgb2JqZWN0IHNpbmNlIHdlIGRvIG5vdCB3YW50IHRvIG1vZGlmeSBwYXJlbnQncyBwcm90b3R5cGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvdG90eXBlLnJlc29sdmVQcm9wZXJ0aWVzID0gXy5jbG9uZSh0aGlzLnByb3RvdHlwZS5yZXNvbHZlUHJvcGVydGllcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm90b3R5cGUucmVzb2x2ZVByb3BlcnRpZXMgPSBbXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm90b3R5cGUucmVzb2x2ZVByb3BlcnRpZXMucHVzaChwcm9wTmFtZSkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLnByb3RvdHlwZSwgcHJvcE5hbWUsIHByb3BEZXNjKTsKCiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgIH0sCiAgICAgICAgZXh0ZW5kIDogZnVuY3Rpb24ocHJvcHMpewogICAgICAgICAgICB2YXIgY2hpbGQgPSBpbmhlcml0cyh0aGlzLCBwcm9wcyk7CiAgICAgICAgICAgIGNoaWxkLmV4dGVuZCA9IHRoaXMuZXh0ZW5kOwogICAgICAgICAgICByZXR1cm4gY2hpbGQ7CiAgICAgICAgfSwKICAgICAgICBhZGRNaXhpbnMgOiBmdW5jdGlvbihtaXhpbkJha2Vycyl7CiAgICAgICAgICAgIGlmKCFfLmlzQXJyYXkobWl4aW5CYWtlcnMpKXsKICAgICAgICAgICAgICAgIG1peGluQmFrZXJzID0gW21peGluQmFrZXJzXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBfLmVhY2gobWl4aW5CYWtlcnMsIGZ1bmN0aW9uKG1peGluQmFrZXIpewogICAgICAgICAgICAgICAgaWYobWl4aW5CYWtlci5ub3JtYWxQcm9wZXJ0aWVzKXsKICAgICAgICAgICAgICAgICAgICBfLmV4dGVuZCh0aGlzLnByb3RvdHlwZSwgbWl4aW5CYWtlci5ub3JtYWxQcm9wZXJ0aWVzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKG1peGluQmFrZXIucHJvcGVydHlEZXNjcmlwdG9ycyl7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWZpbmVQcm9wcyhtaXhpbkJha2VyLnByb3BlcnR5RGVzY3JpcHRvcnMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICB9CiAgICB9KTsKCiAgICAvLyBTaGFyZWQgZW1wdHkgY29uc3RydWN0b3IgZnVuY3Rpb24gdG8gYWlkIGluIHByb3RvdHlwZS1jaGFpbiBjcmVhdGlvbi4KICAgIHZhciBjdG9yID0gZnVuY3Rpb24oKXt9OwoKICAgIC8vIEhlbHBlciBmdW5jdGlvbiB0byBjb3JyZWN0bHkgc2V0IHVwIHRoZSBwcm90b3R5cGUgY2hhaW4sIGZvciBzdWJjbGFzc2VzLgogICAgLy8gU2ltaWxhciB0byBgZ29vZy5pbmhlcml0c2AsIGJ1dCB1c2VzIGEgaGFzaCBvZiBwcm90b3R5cGUgcHJvcGVydGllcyBhbmQKICAgIC8vIGNsYXNzIHByb3BlcnRpZXMgdG8gYmUgZXh0ZW5kZWQuCiAgICBmdW5jdGlvbiBpbmhlcml0cyhwYXJlbnQsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7CiAgICAgICAgdmFyIGNoaWxkOwogICAgICAgIHZhciBfc3VwZXIgPSBwYXJlbnQucHJvdG90eXBlOwogICAgICAgIC8vIFRoZSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBmb3IgdGhlIG5ldyBzdWJjbGFzcyBpcyBlaXRoZXIgZGVmaW5lZCBieSB5b3UKICAgICAgICAvLyAodGhlICJjb25zdHJ1Y3RvciIgcHJvcGVydHkgaW4geW91ciBgZXh0ZW5kYCBkZWZpbml0aW9uKSwgb3IgZGVmYXVsdGVkCiAgICAgICAgLy8gYnkgdXMgdG8gc2ltcGx5IGNhbGwgdGhlIHBhcmVudCdzIGNvbnN0cnVjdG9yLgogICAgICAgIGlmIChwcm90b1Byb3BzICYmIHByb3RvUHJvcHMuaGFzT3duUHJvcGVydHkoJ2NvbnN0cnVjdG9yJykpIHsKICAgICAgICAgICAgY2hpbGQgPSBwcm90b1Byb3BzLmNvbnN0cnVjdG9yOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNoaWxkID0gZnVuY3Rpb24oKXsgcGFyZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07CiAgICAgICAgfQoKICAgICAgICAvLyBJbmhlcml0IGNsYXNzIChzdGF0aWMpIHByb3BlcnRpZXMgZnJvbSBwYXJlbnQuCiAgICAgICAgXy5leHRlbmQoY2hpbGQsIHBhcmVudCk7CgogICAgICAgIC8vIFNldCB0aGUgcHJvdG90eXBlIGNoYWluIHRvIGluaGVyaXQgZnJvbSBgcGFyZW50YCwgd2l0aG91dCBjYWxsaW5nCiAgICAgICAgLy8gYHBhcmVudGAncyBjb25zdHJ1Y3RvciBmdW5jdGlvbi4KICAgICAgICBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7CiAgICAgICAgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsKICAgICAgICBjaGlsZC5fc3VwZXIgPSBwYXJlbnQucHJvdG90eXBlOwogICAgICAgIGNoaWxkLl9zdXBlckNsYXNzID0gcGFyZW50OwoKICAgICAgICAvLyBBZGQgcHJvdG90eXBlIHByb3BlcnRpZXMgKGluc3RhbmNlIHByb3BlcnRpZXMpIHRvIHRoZSBzdWJjbGFzcywKICAgICAgICAvLyBpZiBzdXBwbGllZC4KICAgICAgICBpZiAocHJvdG9Qcm9wcykgeyAvL18uZXh0ZW5kKGNoaWxkLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7CiAgICAgICAgICAgIC8vIENvcHkgdGhlIHByb3BlcnRpZXMgb3ZlciBvbnRvIHRoZSBuZXcgcHJvdG90eXBlCiAgICAgICAgICAgIGZvciAodmFyIG5hbWUgaW4gcHJvdG9Qcm9wcykgewogICAgICAgICAgICAgICAgaWYobmFtZSA9PSAiX2RlZmF1bHRzIil7CiAgICAgICAgICAgICAgICAgICAgcHJvdG9Qcm9wc1tuYW1lXSA9IF8uZXh0ZW5kKHt9LCBfc3VwZXJbbmFtZV0sIHByb3RvUHJvcHNbbmFtZV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2hpbGQucHJvdG90eXBlW25hbWVdID0gcHJvdG9Qcm9wc1tuYW1lXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCgogICAgICAgIC8vIEFkZCBzdGF0aWMgcHJvcGVydGllcyB0byB0aGUgY29uc3RydWN0b3IgZnVuY3Rpb24sIGlmIHN1cHBsaWVkLgogICAgICAgIGlmIChzdGF0aWNQcm9wcykgXy5leHRlbmQoY2hpbGQsIHN0YXRpY1Byb3BzKTsKCiAgICAgICAgLy8gQ29ycmVjdGx5IHNldCBjaGlsZCdzIGBwcm90b3R5cGUuY29uc3RydWN0b3JgLgogICAgICAgIGNoaWxkLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGNoaWxkOwoKICAgICAgICAvLyBTZXQgYSBjb252ZW5pZW5jZSBwcm9wZXJ0eSBpbiBjYXNlIHRoZSBwYXJlbnQncyBwcm90b3R5cGUgaXMgbmVlZGVkIGxhdGVyLgogICAgICAgIGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7CgogICAgICAgIHJldHVybiBjaGlsZDsKICAgIH07Cn0pKF8sIHdpbmRvdy54ZmFsaWIpOwovKioKICogQ3JlYXRlZCBieSB2ZHVhIG9uIDIvMTgvMjAxNS4KICovCihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgWE1MVXRpbHMgPSB7CiAgICAgICAgZGF0YVNvbTJ4cGF0aDogZnVuY3Rpb24gKGRhdGFTb20pIHsKICAgICAgICAgICAgdmFyIHhwYXRoID0gIiI7CgogICAgICAgICAgICBpZiAoIV8uaXNFbXB0eShkYXRhU29tKSkgewogICAgICAgICAgICAgICAgLy8gYW55IGRvdCBwcmVjZWRlZCBieSBdLCB0YWtlcyBjYXJlIG9mIGRvdC1zIGluIG5hbWUsCiAgICAgICAgICAgICAgICAvLyBhbmQgcmVtb3ZlIGNvbnN0YW50IHByZWZpeCAieGZhWzBdLmRhdGFzZXRzWzBdLmRhdGFbMF0iIGFuZCBmb3JtIHJvb3QgbmFtZSwgdGhlbiBqb2luIHVzaW5nICcvJwogICAgICAgICAgICAgICAgXy5lYWNoKGRhdGFTb20uc3BsaXQoL1xdXC4vKS5zbGljZSg0KSwKICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAocGFydCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3BlbkJyYWNrZXRQb3MgPSBwYXJ0Lmxhc3RJbmRleE9mKCdbJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHhwYXRoICs9IHBhcnQuc3Vic3RyaW5nKDAsIG9wZW5CcmFja2V0UG9zICsgMSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBhcnNlSW50KHBhcnQuc3Vic3RyaW5nKG9wZW5CcmFja2V0UG9zICsgMSkpICsgMSkgKyAvLyBpbmNyZW1lbnQgaW5kZXggYnkgMSBmb3IgeHBhdGggcXVlcnkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJdLyI7CiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgaWYgKF8uaXNFbXB0eSh4cGF0aCkpIHsKICAgICAgICAgICAgICAgICAgICB4cGF0aCA9IGRhdGFTb207CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHhwYXRoW3hwYXRoLmxlbmd0aCAtIDFdID09PSAnLycpIHsKICAgICAgICAgICAgICAgICAgICB4cGF0aCA9IHhwYXRoLnNsaWNlKDAsIC0xKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHhwYXRoOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIENvbnZlcnRzIGFuIHhQYXRoUmVzdWx0IG9mIHR5cGUgaXRlcmF0b3IgdG8gYW4gYXJyYXkKICAgICAgICAgKiBAcGFyYW0geFBhdGhSZXN1bHQKICAgICAgICAgKiBAcmV0dXJucyB7QXJyYXl9CiAgICAgICAgICovCiAgICAgICAgaXRlcmF0b3JUb0FycmF5OiBmdW5jdGlvbiAoeFBhdGhSZXN1bHQpIHsKICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFtdOwogICAgICAgICAgICAvLyBpbiBzb21lIGJyb3dzZXJzLCBpZiB4cGF0aCBpcyBpbnZhbGlkIHhQYXRoIHJlc3VsdCBpcyBudWxsIHdoZXJlYXMgc29tZSBicm93c2VycyByZXR1cm4gWHBhdGhSZXN1bHQgd2l0aCBlbXB0eSBpdGVyYXRvcgogICAgICAgICAgICB2YXIgbm9kZSA9IHhQYXRoUmVzdWx0ID8geFBhdGhSZXN1bHQuaXRlcmF0ZU5leHQoKSA6IG51bGw7CiAgICAgICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgbm9kZSA9IHhQYXRoUmVzdWx0Lml0ZXJhdGVOZXh0KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9LAogICAgICAgIC8qKgogICAgICAgICAqIFdyYXBwZXIgQVBJIGZvciBkb2N1bWVudC5ldmFsdWF0ZSB0byBwcm92aWRlIGNyb3NzLWJyb3dzZXIgc3VwcG9ydC4KICAgICAgICAgKiBAcGFyYW0geHBhdGgKICAgICAgICAgKiBAcGFyYW0gbm9kZQogICAgICAgICAqIEBwYXJhbSBuc1Jlc29sdmVyCiAgICAgICAgICogQHBhcmFtIHJlc3VsdFR5cGUKICAgICAgICAgKiBAcGFyYW0gcmVzdWx0CiAgICAgICAgICogQHJldHVybnMge09iamVjdHwqfQogICAgICAgICAqLwogICAgICAgIGV2YWx1YXRlWFBhdGg6IGZ1bmN0aW9uICh4cGF0aCwgbm9kZSwgbnNSZXNvbHZlciwgcmVzdWx0VHlwZSwgcmVzdWx0KSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpZihfLmlzRW1wdHkoeHBhdGgpIHx8ICFfLmlzU3RyaW5nKHhwYXRoKSB8fCAhKG5vZGUgaW5zdGFuY2VvZiBOb2RlKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIERldGVybWluZSB0aGUgYXBwcm9wcmlhdGUgZG9jdW1lbnQgY29udGV4dCBmb3Igc2VhcmNoaW5nLgogICAgICAgICAgICAgICAgdmFyIHNlYXJjaENvbnRleHQgPSBub2RlIGluc3RhbmNlb2YgRG9jdW1lbnQgPyBub2RlIDogbm9kZS5vd25lckRvY3VtZW50OwogICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGRvY3VtZW50LmV2YWx1YXRlIGZ1bmN0aW9uIGlzIHVuZGVmaW5lZCBvciBpZiB3ZSdyZSBpbiBhIHNlcnZlci1zaWRlIGNvbnRleHQuCiAgICAgICAgICAgICAgICB2YXIgaXNFdmFsdWF0ZVVuZGVmaW5lZCA9IHR5cGVvZiBzZWFyY2hDb250ZXh0LmV2YWx1YXRlID09PSAndW5kZWZpbmVkJzsKICAgICAgICAgICAgICAgIHZhciBpc1NlcnZlclNpZGUgPSB3aW5kb3cuZ3VpZGVCcmlkZ2UgJiYgd2luZG93Lmd1aWRlQnJpZGdlLmhvc3ROYW1lID09PSAic2VydmVyIjsKICAgICAgICAgICAgICAgIHZhciBuZWVkc1hQYXRoUG9seWZpbGwgPSBpc0V2YWx1YXRlVW5kZWZpbmVkIHx8IGlzU2VydmVyU2lkZTsKICAgICAgICAgICAgICAgIGlmIChuZWVkc1hQYXRoUG9seWZpbGwpIHsKICAgICAgICAgICAgICAgICAgICAvLyBJbnN0YWxsIHRoZSB3Z3hwYXRoIHBvbHlmaWxsIHRvIHByb3ZpZGUgZXZhbHVhdGUgZnVuY3Rpb25hbGl0eS4KICAgICAgICAgICAgICAgICAgICB3Z3hwYXRoLmluc3RhbGwod2luZG93LCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAvLyBBc3NpZ24gdGhlIG5ld2x5IGluc3RhbGxlZCBldmFsdWF0ZSBmdW5jdGlvbiB0byB0aGUgc2VhcmNoIGNvbnRleHQuCiAgICAgICAgICAgICAgICAgICAgc2VhcmNoQ29udGV4dC5ldmFsdWF0ZSA9IHdpbmRvdy5kb2N1bWVudC5ldmFsdWF0ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgZG9jdW1lbnRUb0V2YWwgPSBzZWFyY2hDb250ZXh0LmV2YWx1YXRlID8gc2VhcmNoQ29udGV4dCA6IGRvY3VtZW50OwogICAgICAgICAgICAgICAgeHBhdGggPSB0aGlzLnNhbml0aXplWFBhdGgoeHBhdGgpOwoKICAgICAgICAgICAgICAgIHJldHVybiBkb2N1bWVudFRvRXZhbC5ldmFsdWF0ZSh4cGF0aCwgbm9kZSwgbnNSZXNvbHZlciwgcmVzdWx0VHlwZSwgcmVzdWx0KTsKCiAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmdldExvZ2dlcigpLmVycm9yKCJDb3VsZCBub3QgZXZhbHVhdGUgeHBhdGg6ICIgKyB4cGF0aCAgKyBleGNlcHRpb24pOwoKICAgICAgICAgICAgfQoKICAgICAgICB9LAogICAgICAgICAvKioKICAgICAgICAgKlJlbW92ZXMgYWxsIFsqXSBvdGhlciB0aGFuIFsnbnVtZXJpYyddIGZyb20geHBhdGgKICAgICAgICAgKkBwYXJhbSB4cGF0aAogICAgICAgICAqQHJldHVybnMgeHBhdGggYWZ0ZXIgcmVtb3ZpbmcgIlsqXSIKICAgICAgICAgKi8KICAgICAgICAgc2FuaXRpemVYUGF0aDogZnVuY3Rpb24oeHBhdGgpIHsKICAgICAgICAgICAgIHZhciB4cGF0aEFycmF5PXhwYXRoLnNwbGl0KCIvIiksCiAgICAgICAgICAgICAgICAgcmVzdWx0WHBhdGggPSBfLm1hcCh4cGF0aEFycmF5LCBmdW5jdGlvbiAocGF0aCkgewogICAgICAgICAgICAgICAgIHJldHVybiBwYXRoLnJlcGxhY2UoL1xbKC4qXEQrLiopXF18XFtcXS9nLCIiKTsKICAgICAgICAgICAgIH0pLmpvaW4oIi8iKTsKICAgICAgICAgICAgIHJldHVybiByZXN1bHRYcGF0aDsKICAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlcyBhbGwgdGhlIEVsZW1lbnRzIChpZiB0aGV5IGRvbid0IGV4aXN0KSBpbiB0aGUgeHBhdGggbGVhZGluZyB0byB0aGUgbm9kZSBiZWluZyBzZWFyY2hlZCBmb3IgaW4gdGhlCiAgICAgICAgICogeHBhdGggcmVsYXRpdmUgdG8gdGhlIGVsZW1lbnQuIE9wdGlvbmFsbHkgY3JlYXRlcyB0aGUgbm9kZSBhcyB3ZWxsIGlmIGJQYXJlbnRzT25seSBpcyBmYWxzZQogICAgICAgICAqIEBwYXJhbSB4cGF0aAogICAgICAgICAqIEBwYXJhbSBlbGVtZW50CiAgICAgICAgICogQHBhcmFtIGJQYXJlbnRzT25seSB3aGV0aGVyIHRvIGNyZWF0ZSBvbmx5IHRoZSBwYXJlbnRzIG9yIHRoZSBub2RlIGFzIHdlbGwKICAgICAgICAgKiBAcmV0dXJucyBub2RlIHRoYXQgaXMgYmVpbmcgcmVwcmVzZW50ZWQgYnkgdGhlIHhwYXRoIHJlbGF0aXZlIHRvIHRoZSBlbGVtZW50LgogICAgICAgICAqLwogICAgICAgIGNyZWF0ZUVsZW1lbnRzRnJvbVhQYXRoOiBmdW5jdGlvbiAoeHBhdGgsIGVsZW1lbnQsIGJQYXJlbnRzT25seSkgewogICAgICAgICAgICBpZiAoeHBhdGggIT0gbnVsbCB8fCBlbGVtZW50ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHZhciBwYXJ0cyA9IHhwYXRoLnNwbGl0KCIvIiksCiAgICAgICAgICAgICAgICAgICAgYWN0dWFsUGFydHMgPSBiUGFyZW50c09ubHkgPyBfLmluaXRpYWwocGFydHMpIDogcGFydHMsCiAgICAgICAgICAgICAgICAgICAgZWwgPSBlbGVtZW50OwogICAgICAgICAgICAgICAgXy5lYWNoKGFjdHVhbFBhcnRzLCBmdW5jdGlvbiAocGFydCwgaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgc29tID0gcGFydC5tYXRjaCgvXihbXltdKykoXFsoXGQrKVxdKT8vKSwKICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRFbDsKICAgICAgICAgICAgICAgICAgICBpZiAoc29tID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmdldExvZ2dlcigpLmVycm9yKCJVbnN1cHBvcnRlZCBleHByZXNzaW9uIGluIEJpbmRyZWYgIiArIHBhcnQpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy9vbmx5IHRoZSBsYXN0IGVsZW1lbnQgY2FuIGJlIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgIGNoaWxkRWwgPSB0aGlzLmZpbmRPckNyZWF0ZUVsZW1lbnQocGFydCwgZWwsIGluZGV4ID09PSBhY3R1YWxQYXJ0cy5sZW5ndGggLSAxKTsKICAgICAgICAgICAgICAgICAgICBlbCA9IGNoaWxkRWw7CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIHJldHVybiBlbDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBGb3JtIGFuIHhwYXRoIHBhcnQgcmV0dXJucyB0aGUgaW5kZXggYXMgd2VsbCBhcyB0aGUgdGFnTmFtZS4gSW5kZXggY2FuIGJlICogYXMgd2VsbAogICAgICAgICAqIEBwYXJhbSB4cGF0aE5hbWUKICAgICAgICAgKiBAcmV0dXJucyB7Kn0KICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9nZXRFbGVtZW50TmFtZUFuZEluZGV4RnJvbVhQYXRoUGFydDogZnVuY3Rpb24gKHhwYXRoTmFtZSkgewogICAgICAgICAgICB2YXIgc29tICA9ICB4cGF0aE5hbWUubWF0Y2goL14oW15bXSspKD86XFsoXGQrfFwqKVxdKT8vKTsKICAgICAgICAgICAgaWYgKHNvbSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICBuYW1lOiBzb21bMV0sCiAgICAgICAgICAgICAgICAgICAgaW5kZXg6IHNvbVsyXSB8fCAwCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIGNyZWF0ZSBhbiBlbGVtZW50IHdpdGggdGhlIHRhZ05hbWUgZWxlbWVudE5hbWUgZm9yIHRoZSBvd25lckRvY3VtZW50IG9mIGVsZW1lbnQuCiAgICAgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCiAgICAgICAgICogQHBhcmFtIGVsZW1lbnQKICAgICAgICAgKiBAcmV0dXJucyB7SFRNTEVsZW1lbnR9CiAgICAgICAgICovCiAgICAgICAgY3JlYXRlRWxlbWVudDogZnVuY3Rpb24gKGVsZW1lbnROYW1lLCBlbGVtZW50KSB7CiAgICAgICAgICAgIHZhciBlbCA9IGVsZW1lbnQub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KGVsZW1lbnROYW1lKTsKICAgICAgICAgICAgcmV0dXJuIGVsOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFNlYXJjaGVzIGZvciB0aGUgbm9kZVhwYXRoIHJlbGF0aXZlIHRvIGVsZW1lbnQuIElmIGl0IGRvZXNuJ3QgZXhpc3RzIGNyZWF0ZXMgaXQgYW5kIHJldHVybnMgdGhlIG5vZGUKICAgICAgICAgKiBAcGFyYW0gZWxlbWVudAogICAgICAgICAqIEBwYXJhbSBub2RlWHBhdGgKICAgICAgICAgKiBAcGFyYW0gYkF0dHJpYnV0ZSBpZiB0cnVlIHRoZW4gY2hlY2sgZm9yIGF0dHJpYnV0ZSBvdGhlcndpc2Ugbm90LgogICAgICAgICAqIEByZXR1cm5zIHtOb2RlfCp9CiAgICAgICAgICovCiAgICAgICAgZmluZE9yQ3JlYXRlRWxlbWVudDogZnVuY3Rpb24gKG5vZGVYcGF0aCwgZWxlbWVudCwgYkF0dHJpYnV0ZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHRoaXMuZXZhbHVhdGVYUGF0aChub2RlWHBhdGgsIGVsZW1lbnQsIG51bGwsIFhQYXRoUmVzdWx0Lk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFLCBudWxsKSwKICAgICAgICAgICAgICAgICAgICBlbCA9IHJlc3VsdC5pdGVyYXRlTmV4dCgpLAogICAgICAgICAgICAgICAgICAgIHJlczsKICAgICAgICAgICAgICAgIGlmIChlbCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzID0gdGhpcy5fZ2V0RWxlbWVudE5hbWVBbmRJbmRleEZyb21YUGF0aFBhcnQobm9kZVhwYXRoKTsKICAgICAgICAgICAgICAgICAgICBpZiAocmVzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJBdHRyaWJ1dGUgJiYgcmVzLm5hbWUubWF0Y2goL15ALykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRyTmFtZSA9IHJlcy5uYW1lLnJlcGxhY2UoL15ALywgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSBlbGVtZW50Lm93bmVyRG9jdW1lbnQuY3JlYXRlQXR0cmlidXRlKGF0dHJOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZShlbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbCA9IGVsZW1lbnQub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KHJlcy5uYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoZWwpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGVsOwoKICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0TG9nZ2VyKCkuZXJyb3IoIkZvbGxvd2luZyBleGNlcHRpb24gIgogICAgICAgICAgICAgICAgICAgICsgICJvY2N1cnJlZCB3aGlsZSBleGVjdXRpbmcgZmluZE9yQ3JlYXRlRWxlbWVudCAiICsgZXhjZXB0aW9uKTsKICAgICAgICAgICAgfQoKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRoZSBSb290IEZvcm0gRWxtZW50IGZyb20gdGhlIHhtbERvY3VtZW50RWxlbWVudAogICAgICAgICAqIEBwYXJhbSB4bWxEb2N1bWVudEVsZW1lbnQgSXQgY2FuIGJlIGEgZG9jdW1lbnQgb3IgRWxlbWVudC4gSWYgdGhlIHJvb3QgZWxlbWVudCBpcyB4ZHAgZWxlbWVudCwgaXQgcmV0dXJucwogICAgICAgICAqICAgICAgICB0aGUgZ3JhbmQgZ3JhbmQgY2hpbGQgb2YgdGhhdCBlbGVtZW50LiBvdGhlcndpc2UgdGhlIHJvb3QgZWxlbWVudCBpcyByZXR1cm5lZC4gVGhlIHJvb3QKICAgICAgICAgKiAgICAgICAgRWxlbWVudCBjYW4gYmUgZWl0aGVyIHRoZSBlbGVtZW50IGl0c2VsZiBvciBkb2N1bWVudEVsZW1lbnQgb2YgdGhlIGVsZW1lbnQuCiAgICAgICAgICovCiAgICAgICAgZ2V0WEZBUm9vdEZvcm1FbGVtZW50RnJvbVhNTDogZnVuY3Rpb24gKHhtbERvY3VtZW50RWxlbWVudCkgewogICAgICAgICAgICBpZihfLmlzVW5kZWZpbmVkKGRvY3VtZW50LmV2YWx1YXRlKSkgewogICAgICAgICAgICAgICAgd2d4cGF0aC5pbnN0YWxsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGlzRWxlbWVudCA9IHhtbERvY3VtZW50RWxlbWVudCBpbnN0YW5jZW9mIEVsZW1lbnQsCiAgICAgICAgICAgICAgICBkb2NFbGVtTmFtZSA9IGlzRWxlbWVudCA/IHhtbERvY3VtZW50RWxlbWVudC5ub2RlTmFtZSA6IHhtbERvY3VtZW50RWxlbWVudC5kb2N1bWVudEVsZW1lbnQubm9kZU5hbWUsCiAgICAgICAgICAgICAgICByb290RWxlbWVudCA9IGlzRWxlbWVudCA/IHhtbERvY3VtZW50RWxlbWVudCA6IHhtbERvY3VtZW50RWxlbWVudC5kb2N1bWVudEVsZW1lbnQsCiAgICAgICAgICAgICAgICBub2RlTGlzdDsKCiAgICAgICAgICAgIGlmICgieGRwOnhkcCIgPT09IGRvY0VsZW1OYW1lIHx8ICJ4ZHAiID09PSBkb2NFbGVtTmFtZSkgewogICAgICAgICAgICAgICAgaWYgKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5pc0lFKCkpIHsKICAgICAgICAgICAgICAgICAgICAvL0lFIGRvZXNuJ3Qgc3VwcG9ydCBldmFsdWF0aW5nIG5hbWVzcGFjZSBlbGVtZW50cwogICAgICAgICAgICAgICAgICAgIHZhciBkYXRhc2V0cyA9IHJvb3RFbGVtZW50LmZpcnN0RWxlbWVudENoaWxkLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YXNldHMuZmlyc3RFbGVtZW50Q2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgcm9vdEVsZW1lbnQgPSBkYXRhLmZpcnN0RWxlbWVudENoaWxkOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBhc3N1bXB0aW9uIGlzIHRoYXQgdGhlIHhtbCB3aWxsIGJlIG9mIGZvcm1hdCA8eGRwPjxkYXRhc2V0cz48ZGF0YT48Zm9ybTE+CiAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogY2hhbmdlIGZpcnN0ICogdG8geGZhOmRhdGFzZXRzCiAgICAgICAgICAgICAgICAgICAgbm9kZUxpc3QgPSB0aGlzLmV2YWx1YXRlWFBhdGgoIioveGZhOmRhdGEvKiIsIHJvb3RFbGVtZW50LCBmb3JtQnJpZGdlLm5zUmVzb2x2ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBhdGhSZXN1bHQuT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUsIG51bGwpOwogICAgICAgICAgICAgICAgICAgIHJvb3RFbGVtZW50ID0gbm9kZUxpc3QuaXRlcmF0ZU5leHQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcm9vdEVsZW1lbnQ7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgcHJlZml4IGFuZCBuYW1lc3BhY2VzIHByZXNlbnQgaW4gdGhlIHJvb3RFbGVtZW50LiBGb3IgZGVmYXVsdCBuYW1lc3BhY2UgdGhlCiAgICAgICAgICogcHJlZml4IGlzICJfZGVmYXVsdCIKICAgICAgICAgKiBAcGFyYW0gcm9vdEVsZW1lbnQge0VsZW1lbnR9IHhtbCBlbGVtZW50IHdoaWNoIGhhcyB0byBiZSBsb29rZWQgZm9yIG5hbWVzcGFjZXMKICAgICAgICAgKiBAcmV0dXJucyB7b2JqZWN0fSBvYmplY3Qgd2hvc2Uga2V5cyBhcmUgdGhlIHByZWZpeCBhbmQgdmFsdWVzIGFyZSB0aGUgbmFtZXNwYWNlCiAgICAgICAgICovCiAgICAgICAgZ2V0TmFtZXNwYWNlczogZnVuY3Rpb24gKHJvb3RFbGVtZW50KSB7CiAgICAgICAgICAgIHZhciBuYW1lc3BhY2VzID0gewogICAgICAgICAgICAgICAgIl9kZWZhdWx0IiA6IG51bGwKICAgICAgICAgICAgfTsKICAgICAgICAgICAgXy5lYWNoKHJvb3RFbGVtZW50LmF0dHJpYnV0ZXMsIGZ1bmN0aW9uIChhdHRyKSB7CiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IGF0dHIubmFtZSwKICAgICAgICAgICAgICAgICAgICBwYXJzZWRBdHRyTmFtZSA9IG5hbWUubWF0Y2goL154bWxucyg/Olw6KC4qKSk/LyksCiAgICAgICAgICAgICAgICAgICAgaXNOYW1lc3BhY2UgPSBwYXJzZWRBdHRyTmFtZSAhPSBudWxsLAogICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZU5hbWUgPSBpc05hbWVzcGFjZSA/IHBhcnNlZEF0dHJOYW1lWzFdIHx8ICJfZGVmYXVsdCIgOiBudWxsOwogICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZU5hbWUpIHsKICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VzW25hbWVzcGFjZU5hbWVdID0gYXR0ci52YWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHJldHVybiBuYW1lc3BhY2VzOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgYSBuYW1lc3BhY2UgcmVzb2x2ZXIgZ2l2ZW4gYSBlbGVtZW50LiBUaGUgbnNSZXNvbHZlciByZXR1cm5zIHRoZSBuYW1lc3BhY2UgZ2l2ZW4gYSBwcmVmaXggYnkKICAgICAgICAgKiB1c2luZyB0aGUgbmFtZXNwYWNlcyBtZW50aW9uZWQgaW4gdGhlIGVsZW1lbnQuCiAgICAgICAgICogQHBhcmFtIHJvb3RFbGVtZW50IGVsZW1lbnQgZnJvbSB3aGljaCB0byBjcmVhdGUgdGhlIG5zUmVzb2x2ZXIKICAgICAgICAgKiBAcmV0dXJucyB7ZnVuY3Rpb259IHRoZSBmdW5jdGlvbiByZXR1cm5zIHRoZSBuYW1lc3BhY2UgZ2l2ZW4gYSBwcmVmaXguCiAgICAgICAgICovCiAgICAgICAgZ2V0TnNSZXNvbHZlcjogZnVuY3Rpb24gKHJvb3RFbGVtZW50KSB7CiAgICAgICAgICAgIHZhciBuYW1lc3BhY2VzID0gdGhpcy5nZXROYW1lc3BhY2VzKHJvb3RFbGVtZW50KSwKICAgICAgICAgICAgICAgIG5zUmVzb2x2ZXIgPSAoZnVuY3Rpb24gKG5hbWVzcGFjZXMpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG5zUHJlZml4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuYW1lc3BhY2UgPSBmb3JtQnJpZGdlLm5zUmVzb2x2ZXIobnNQcmVmaXgpIHx8IG5hbWVzcGFjZXNbbnNQcmVmaXhdOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmFtZXNwYWNlOwogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9KG5hbWVzcGFjZXMpKTsKICAgICAgICAgICAgcmV0dXJuIG5zUmVzb2x2ZXI7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogUmVtb3ZlcyBkZWZhdWx0IG5hbWVzcGFjZXMgZnJvbSB4bWwsIGJhc2ljYWxseSB0aGUgbmFtZXNwYWNlIGRlZmluZWQgYXMgeG1sbnM9InNvbWUgbmFtZXNwYWNlIi4gVGhlCiAgICAgICAgICogc2lkZS1lZmZlY3Qgb2YgdGhlIEFQSSBpcyBpdCByZW1vdmVzIHRoZSBzdHJpbmcgInhtbG5zPSdzb21lIG5hbWVzcGFjZSciIGZyb20gYW55IGF0dHJpYnV0ZSB2YWx1ZSBhcyB3ZWxsLgogICAgICAgICAqIEBwYXJhbSB4bWwge3N0cmluZ30KICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfQogICAgICAgICAqLwogICAgICAgIHJlbW92ZURlZmF1bHROYW1lc3BhY2U6IGZ1bmN0aW9uICh4bWwpIHsKICAgICAgICAgICAgdmFyIHN0cmluZ1JlZ2V4ID0gIihcXHMrKSIgKyAvLyBhbnkgbnVtYmVyIG9mIHNwYWNlcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoeG1sbnM9IiArIC8vIHRoZW4geG1sbnM9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCdbXiddKid8XCJbXlwiXSpcIikpIiArIC8vIHRoZW4gdmFsdWUgaW4gc2luZ2xlIHF1b3RlcyAoJ1teJ10nKSBvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgIGRvdWJsZSBxdW90ZXMgKCJbXiJdIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoPz1bXjw+XSo+KSIsICAvLyBmb2xsb3dlZCBieSBjbG9zaW5nIHRhZyAoaW1wbGllcyBhdHRyaWJ1dGUpIGFuZCBiZWZvcmUgYW5vdGhlcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3BlbmluZyB0YWcoaW1wbGllcyB0ZXh0KQogICAgICAgICAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKHN0cmluZ1JlZ2V4LCAiZyIpOwogICAgICAgICAgICByZXR1cm4geG1sLnJlcGxhY2UocmVnZXgsICIkMSIpOwogICAgICAgIH0KICAgIH07CiAgICB4ZmFsaWIudXQuWE1MVXRpbHMgPSBYTUxVdGlsczsKfShfLCB4ZmFsaWIpKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5Mb2dnZXIKICogQGltcG9ydCB4ZmFsaWIudXQuQ2xhc3MKICovCgooZnVuY3Rpb24oXywgeGZhbGliLCAkKXsKICAgIHZhciBjYXRlZ29yeUFjcm9ueW1zID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgImEiOiAieGZhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiIjogInhmYVZpZXciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImMiOiAieGZhUGVyZiIKICAgICAgICB9LAogICAgICAgIGxvZ2dlclR5cGVzID0gWyJvZmYiLCAiY29uc29sZSIsICJzZXJ2ZXIiLCAiY29uc29sZVNlcnZlciJdOwogICAgdmFyIExvZ2dlciA9IHhmYWxpYi51dC5Mb2dnZXIgPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKCi8vICAgICAgQ291bnQgb2YgbG9nIG1lc3NhZ2VzIHNvIGZhci4KICAgICAgICBMT0dfQ09VTlQgOiB7CiAgICAgICAgICAgIGxldmVsIDogewogICAgICAgICAgICAgICAgIkZBVEFMIiA6IDAsCiAgICAgICAgICAgICAgICAiRVJST1IiIDogMCwKICAgICAgICAgICAgICAgICJXQVJOIiA6IDAsCiAgICAgICAgICAgICAgICAiSU5GTyIgOiAwLAogICAgICAgICAgICAgICAgIkRFQlVHIiA6IDAsCiAgICAgICAgICAgICAgICAiVFJBQ0UiIDogMCwKICAgICAgICAgICAgICAgICJBTEwiIDogMAogICAgICAgICAgICB9LAogICAgICAgICAgICBjYXRlZ29yeSA6IHsKICAgICAgICAgICAgICAgICJ4ZmEiIDogMCwKICAgICAgICAgICAgICAgICJ4ZmFWaWV3IiA6IDAsCiAgICAgICAgICAgICAgICAieGZhUGVyZiIgOiAwLAogICAgICAgICAgICAgICAgIlVua25vd24iIDogMAogICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBMb2cgbGV2ZWwgdG8gdHVybiBsb2dnaW5nIG9mZiAoZGVmYXVsdCkuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEBmaW5hbAogICAgICAgICAqIEB0eXBlIE51bWJlcgogICAgICAgICAqLwogICAgICAgIE9GRiA6IDAsCgogICAgICAgIC8qKgogICAgICAgICAqIExvZyBsZXZlbCBmb3IgZmF0YWwgZXJyb3IgbWVzc2FnZXMuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEBmaW5hbAogICAgICAgICAqIEB0eXBlIE51bWJlcgogICAgICAgICAqLwogICAgICAgIEZBVEFMIDogMSwKCiAgICAgICAgLyoqCiAgICAgICAgICogTG9nIGxldmVsIGZvciBlcnJvciBtZXNzYWdlcy4KICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICogQHR5cGUgTnVtYmVyCiAgICAgICAgICogQGZpbmFsCiAgICAgICAgICovCiAgICAgICAgRVJST1IgOiAyLAoKICAgICAgICAvKioKICAgICAgICAgKiBMb2cgbGV2ZWwgZm9yIHdhcm5pbmcgbWVzc2FnZXMuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEB0eXBlIE51bWJlcgogICAgICAgICAqIEBmaW5hbAogICAgICAgICAqLwogICAgICAgIFdBUk4gOiAzLAoKICAgICAgICAvKioKICAgICAgICAgKiBMb2cgbGV2ZWwgZm9yIGluZm8gbWVzc2FnZXMuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEB0eXBlIE51bWJlcgogICAgICAgICAqIEBmaW5hbAogICAgICAgICAqLwogICAgICAgIElORk8gOiA0LAoKICAgICAgICAvKioKICAgICAgICAgKiBMb2cgbGV2ZWwgZm9yIGRlYnVnIG1lc3NhZ2VzLgogICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgKiBAdHlwZSBOdW1iZXIKICAgICAgICAgKiBAZmluYWwKICAgICAgICAgKi8KICAgICAgICBERUJVRyA6IDUsCgogICAgICAgIC8qKgogICAgICAgICAqIExvZyBsZXZlbCBmb3IgdHJhY2UgbWVzc2FnZXMuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEB0eXBlIE51bWJlcgogICAgICAgICAqIEBmaW5hbAogICAgICAgICAqLwogICAgICAgIFRSQUNFIDogNiwKCiAgICAgICAgLyoqCiAgICAgICAgICogTG9nIGxldmVsIGZvciBhbGwgbWVzc2FnZXMuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEB0eXBlIE51bWJlcgogICAgICAgICAqIEBmaW5hbAogICAgICAgICAqLwogICAgICAgIEFMTCA6IDcsCgoKICAgICAgICBsb2dMZXZlbE5hbWVzIDogWyJPRkYiLCAiRkFUQUwiLCAiRVJST1IiLCAiV0FSTiIsICJJTkZPIiwgIkRFQlVHIiwgIlRSQUNFIiwgIkFMTCJdLAoKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIHN0ciA9ICIiLAogICAgICAgICAgICAgICAgdGhhdCA9dGhpczsKICAgICAgICAgICAgTG9nZ2VyLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMubG9ncyA9IHt9OwogICAgICAgICAgICB0aGlzLmxvZ01lc3NhZ2VzID0gIiI7CiAgICAgICAgICAgIHRoaXMubG9nU2VydmljZVByb3h5ID0gdGhpcy5vcHRpb25zLmxvZ1NlcnZpY2VQcm94eTsKICAgICAgICAgICAgdGhpcy5jb250ZXh0UGF0aCA9IHRoaXMub3B0aW9ucy5jb250ZXh0UGF0aDsKICAgICAgICAgICAgdGhpcy5yZW5kZXJDb250ZXh0ID0gIHRoaXMub3B0aW9ucy5yZW5kZXJDb250ZXh0OwogICAgICAgICAgICBpZih0aGlzLmpzb25Nb2RlbC5sb2dDb25maWdTdHJpbmcpIHsKICAgICAgICAgICAgICAgIF8uZXh0ZW5kKHRoaXMuanNvbk1vZGVsLCB0aGlzLnBhcnNlKHRoaXMuanNvbk1vZGVsLmxvZ0NvbmZpZ1N0cmluZykpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF8uZWFjaCh0aGlzLmpzb25Nb2RlbC5jYXRlZ29yeSwgZnVuY3Rpb24oY2F0ZWdvcnkpIHsKICAgICAgICAgICAgICAgIHRoYXQuTE9HX0NPVU5ULmNhdGVnb3J5W2NhdGVnb3J5XSA9IDA7CiAgICAgICAgICAgIH0pCiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogcGFyc2VzIGEgbG9nIGNvbmZpZyBzdHJpbmcgb2YgdGhlIGZvcm0gPDAsMSwyLDM+LTxjYXRlZ29yeSBzdHJpbmc+PGxldmVsIGludGVnZXI+LTxjYXRlZ29yeSBzdHJpbmc+PGxldmVsIGludGVnZXI+Li4KICAgICAgICAgKiBhbmQgcmV0dXJucyBhbiBhIGNvbmZpZyBvYmplY3QgdGhhdCBsb2dnZXIgdXNlcy4gVGhlIGZ1bmN0aW9uIGlzIGEgcHJpdmF0ZSBhbmQgbm90IHRvIGJlIGNhbGxlZCBvdXRzaWRlCiAgICAgICAgICogdGhpcyBmdW5jdGlvbgogICAgICAgICAqCiAgICAgICAgICogY2F0ZWdvcnkgY2FuIG5vdCBjb250YWluIG51bWJlcnMgYW5kIG9ubHkgdmFsaWQgY2hhcmFjdGVycyBhcmUgYS16QS1aCiAgICAgICAgICogbGV2ZWwgY2FuIGJlIGFueSBpbnRlZ2VyLgogICAgICAgICAqCiAgICAgICAgICogY2F0ZWdvcnkgc3RyaW5nIGlzIGNvbnZlcnRlZCBpbnRvIGFjdHVhbCBjYXRlZ29yeSBmb3IgdGhlIGxvZ2dlciBieSB1c2luZyBkZWZhdWx0IGNhdGVnb3J5QWNyb255bXMKICAgICAgICAgKiBbYSA6IHhmYSwgYjogeGZhVmlldywgYzogeGZhUGVyZn0gYW5kIHRoZSBjYXRlZ29yeUFjcm9ueW1zIHBhc3NlZCB0byB0aGUgb3B0aW9ucyB3aGlsZSBpbnN0YW50aWF0aW5nIHRoZQogICAgICAgICAqIG9iamVjdC4gSWYgbm90IGZvdW5kIGluIGJvdGggdGhlIGFjcm9ueW1zIHRoZW4gdGhlIHZhbHVlIGNhdGVnb3J5IHN0cmluZyBpcyB1c2VkIGFzIGFjdHVhbCBjYXRlZ29yeQogICAgICAgICAqCiAgICAgICAgICogRm9yIGV4YW1wbGUgZm9yIHRoZSBpbnB1dCBzdHJpbmcgMS1hOS1iOS1jOSByZXR1cm4gb2JqZWN0IGlzCiAgICAgICAgICoge29uOiB0cnVlLCBjYXRlZ29yeTogW3hmYSx4ZmFWaWV3LCB4ZmFQZXJmXSwgbGV2ZWw6IFs5LCA5LCA5XSwgdHlwZTogY29uc29sZX0KICAgICAgICAgKgogICAgICAgICAqIEZvciB0aGUgaW5wdXQgc3RyaW5nIDEtYTktYjktYzktZDktZTExIHdpdGggb3B0aW9ucy5jYXRlZ29yeUFjcm9ueW1zIHthOmEsIGQ6QUZ9IHJldHVybiBvYmplY3QgaXMKICAgICAgICAgKiB7b246IHRydWUsIGNhdGVnb3J5OiBbeGZhLHhmYVZpZXcsIHhmYVBlcmYsIEFGLCBlXSwgbGV2ZWw6IFs5LCA5LCA5LCA5LCAxMV0sIHR5cGU6IGNvbnNvbGV9CiAgICAgICAgICovCiAgICAgICAgcGFyc2UgOiBmdW5jdGlvbihjb25maWdTdHJpbmcpIHsKICAgICAgICAgICAgdmFyIGFyciA9IGNvbmZpZ1N0cmluZy5zcGxpdCgiLSIpLAogICAgICAgICAgICAgICAgbG9nVHlwZSA9IF8uZmlyc3QoYXJyKSwKICAgICAgICAgICAgICAgIGxvZ0NvbmZpZyA9IF8ucmVzdChhcnIpLAogICAgICAgICAgICAgICAgcmVzID0gewogICAgICAgICAgICAgICAgICAgIG9uOiBsb2dUeXBlID09PSAiMCIgPyAiZmFsc2UiOiAidHJ1ZSIsCiAgICAgICAgICAgICAgICAgICAgY2F0ZWdvcnk6IFtdLAogICAgICAgICAgICAgICAgICAgIGxldmVsOltdLAogICAgICAgICAgICAgICAgICAgIHR5cGU6bG9nZ2VyVHlwZXNbcGFyc2VJbnQobG9nVHlwZSldCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgIF8uZWFjaChsb2dDb25maWcsIGZ1bmN0aW9uKGl0ZW0sIGluZGV4KSB7CiAgICAgICAgICAgICAgICB2YXIgY29uZmlnID0gaXRlbS5tYXRjaCgvXihbQS1aYS16XSspKFxkKykkLyksCiAgICAgICAgICAgICAgICAgICAgY2F0ZWdvcnk7CiAgICAgICAgICAgICAgICBpZiAoY29uZmlnICYmIGNvbmZpZy5sZW5ndGggPT09IDMpIHsKICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeSA9IHRoaXMuZ2V0T3JFbHNlKGNhdGVnb3J5QWNyb255bXMsIGNvbmZpZ1sxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwsICJjYXRlZ29yeUFjcm9ueW1zLiIgKyBjb25maWdbMV0sIGNvbmZpZ1sxXSkpOwogICAgICAgICAgICAgICAgICAgIHJlcy5jYXRlZ29yeS5wdXNoKGNhdGVnb3J5KTsKICAgICAgICAgICAgICAgICAgICByZXMubGV2ZWwucHVzaChwYXJzZUludChjb25maWdbMl0pKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy9jYWxsaW5nIHRoaXMgYmVjYXVzZSBsb2dnZXIgaXMgbm90IGluaXRpYWxpemVkIGFzIG9mIG5vdwogICAgICAgICAgICAgICAgICAgIHRoaXMuY29uc29sZUhhbmRsZXIodGhpcy5yZXNvbHZlTWVzc2FnZSh4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMjAiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpdGVtLCBjb25maWdTdHJpbmddKSkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKgogICAgICAgICAqLwogICAgICAgIHJlc29sdmVNZXNzYWdlIDogZnVuY3Rpb24obWVzc2FnZSwgc25pcHBldHMpIHsKICAgICAgICAgICAgc25pcHBldHMgPSBzbmlwcGV0cyB8fCBbXTsKICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2UucmVwbGFjZSgveyhcZCspfS9nLCBmdW5jdGlvbihtYXRjaCwgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZW9mIHNuaXBwZXRzW251bWJlcl0gIT0gJ3VuZGVmaW5lZCcKICAgICAgICAgICAgICAgICAgICA/IHNuaXBwZXRzW251bWJlcl0KICAgICAgICAgICAgICAgICAgICA6IG1hdGNoCiAgICAgICAgICAgICAgICAgICAgOwogICAgICAgICAgICB9KTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBXcml0ZXMgYSBtZXNzYWdlIHRvIHRoZSBjb25zb2xlLgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IGxldmVsIFRoZSBsb2cgbGV2ZWwKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBUaGUgbG9nIG1lc3NhZ2UKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZy9TdHJpbmdbXX0gc25pcHBldHMgKG9wdGlvbmFsKSBUaGUgdGV4dHMgcmVwbGFjaW5nCiAgICAgICAgICogICAgICAgIDxjb2RlPntufTwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBsb2cgbWVzc2FnZQogICAgICAgICAqIEB0eXBlIFN0cmluZwogICAgICAgICAqLwogICAgICAgIGxvZyA6IGZ1bmN0aW9uKGNhdGVnb3J5LCBsZXZlbCwgbWVzc2FnZSwgc25pcHBldHMpIHsKICAgICAgICAgICAgdmFyIGQ9IG5ldyBEYXRlKCk7CiAgICAgICAgICAgIHZhciBkYXkgPSBkLmdldERhdGUoKTsKICAgICAgICAgICAgdmFyIG1vbnRoID0gZC5nZXRNb250aCgpICsgMTsKICAgICAgICAgICAgdmFyIHllYXIgPSBkLmdldEZ1bGxZZWFyKCk7CiAgICAgICAgICAgIHZhciBtaWxpID0gZC5nZXRNaWxsaXNlY29uZHMoKTsKICAgICAgICAgICAgdmFyIHNlYyA9IGQuZ2V0U2Vjb25kcygpOwogICAgICAgICAgICB2YXIgbWluID0gZC5nZXRNaW51dGVzKCk7CiAgICAgICAgICAgIHZhciBob3VyID0gZC5nZXRIb3VycygpOwogICAgICAgICAgICB2YXIgZGF0ZSA9IGRheSArICIuIiArIG1vbnRoICsgIi4iICsgeWVhciArIiAiICsgaG91ciArICI6IiArIG1pbiArICI6IiArIHNlYyArICI6IiArIG1pbGk7CiAgICAgICAgICAgIGlmKHRoaXMuanNvbk1vZGVsICYmIHRoaXMuanNvbk1vZGVsLmNhdGVnb3J5KSB7CiAgICAgICAgICAgICAgICBmb3IodmFyIGkgPSAwOyBpPHRoaXMuanNvbk1vZGVsLmNhdGVnb3J5Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGxldmVsICE9IDAgJiYgdGhpcy5qc29uTW9kZWwubGV2ZWxbaV0gPj0gbGV2ZWwgJiYgdGhpcy5qc29uTW9kZWwuY2F0ZWdvcnlbaV0gPT0gY2F0ZWdvcnkgJiYgdGhpcy5qc29uTW9kZWwub24gPT0gInRydWUiKSB7CgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzb2x2ZWRNZXNzYWdlID0gbWVzc2FnZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoc25pcHBldHMpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9yZXNvbHZlIG1lc3NhZ2Ugd2l0aCBzbmlwcGV0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlZE1lc3NhZ2UgPSB0aGlzLnJlc29sdmVNZXNzYWdlKG1lc3NhZ2UsIHNuaXBwZXRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRleHQgPSAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCArPSBkYXRlIDsKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCArPSAiICoiICsgdGhpcy5sb2dMZXZlbE5hbWVzW2xldmVsXSArICIqIjsKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCArPSAiIFsiICsgIGNhdGVnb3J5ICsgIl0iIDsKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCArPSAiICAiICsgcmVzb2x2ZWRNZXNzYWdlICsgIlxyXG4iIDsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dNZXNzYWdlcyArPSB0ZXh0IDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5qc29uTW9kZWwudHlwZSA9PSAiY29uc29sZSIgfHwgdGhpcy5qc29uTW9kZWwudHlwZSA9PSAiY29uc29sZVNlcnZlciIgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICArK3RoaXMuTE9HX0NPVU5ULmNhdGVnb3J5W2NhdGVnb3J5IHx8ICdVbmtub3duJ107CiAgICAgICAgICAgICAgICAgICAgICAgICAgICArK3RoaXMuTE9HX0NPVU5ULmxldmVsW3RoaXMubG9nTGV2ZWxOYW1lc1twYXJzZUludChsZXZlbCkgPCA4PyBsZXZlbDo3XV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnNvbGVIYW5kbGVyKHRleHQsIGxldmVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNvbnNvbGVIYW5kbGVyIDogZnVuY3Rpb24odGV4dCwgbGV2ZWwpewogICAgICAgICAgICBpZih0eXBlb2YgY29uc29sZSAhPSAidW5kZWZpbmVkIikgewogICAgICAgICAgICAgICAgdmFyIGxldmVsTmFtZSA9IHR5cGVvZiB0aGlzLmxvZ0xldmVsTmFtZXNbbGV2ZWxdID09PSAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgID8gdGhpcy5sb2dMZXZlbE5hbWVzW2xldmVsXS50b0xvd2VyQ2FzZSgpCiAgICAgICAgICAgICAgICAgICAgOiAibG9nIiwKICAgICAgICAgICAgICAgICAgICBsb2dGdW5jdGlvbiA9IGNvbnNvbGUubG9nOwogICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlW2xldmVsTmFtZV0gPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgICAgICAgICBsb2dGdW5jdGlvbiA9IGNvbnNvbGVbbGV2ZWxOYW1lXQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbG9nRnVuY3Rpb24uY2FsbChjb25zb2xlLCAiXG5cblxuIiArIHRleHQpOwogICAgICAgICAgICAgICAgLy9FcnJvciBsb2cgYWxyZWFkeSBzaG93cyB0aGUgY2FsbCBzdGFjayBmb3IgZGVidWdnaW5nLgogICAgICAgICAgICAgICAgaWYobGV2ZWxOYW1lICE9PSAiZXJyb3IiKSB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgbi50ZXN0CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChleGNlcHRpb24uc3RhY2spIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ0Z1bmN0aW9uLmNhbGwoY29uc29sZSwgZXhjZXB0aW9uLnN0YWNrLnJlcGxhY2UoIlJlZmVyZW5jZUVycm9yOiBuIGlzIG5vdCBkZWZpbmVkIiwgIiIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqICBIZWxwZXIgZnVuY3Rpb24gdG8gZ2VyIHN1Ym1pdCBzZXJ2aWNlIHByb3h5IHVybAogICAgICAgICAqLwogICAgICAgIF9nZXRMb2dTZXJ2aWNlUHJveHlVcmw6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgbG9nU2VydmljZVByb3h5VXJsID0gIiI7CiAgICAgICAgICAgIGlmKHRoaXMubG9nU2VydmljZVByb3h5KQogICAgICAgICAgICAgICAgbG9nU2VydmljZVByb3h5VXJsICs9IHRoaXMubG9nU2VydmljZVByb3h5OwogICAgICAgICAgICBlbHNlIC8vZmluYWxseSBoYXJkIGNvZGUgaXQKICAgICAgICAgICAgICAgIGxvZ1NlcnZpY2VQcm94eVVybCArPSAoKHRoaXMuY29udGV4dFBhdGggJiYgdGhpcy5jb250ZXh0UGF0aCAhPSAiLyIpID8gdGhpcy5jb250ZXh0UGF0aCA6ICIiKSArICIvY29udGVudC94ZmFmb3Jtcy9wcm9maWxlcy9kZWZhdWx0LmxvZy5odG1sIjsKICAgICAgICAgICAgcmV0dXJuIGxvZ1NlcnZpY2VQcm94eVVybDsKICAgICAgICB9LAoKICAgICAgICBfaW52b2tlQXRTZXJ2ZXI6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgdmFyIGxvY2FsU3VibWl0VXJsID0gIHRoaXMuX2dldExvZ1NlcnZpY2VQcm94eVVybCgpOwogICAgICAgICAgICB2YXIgcGFyYW1zID0gewogICAgICAgICAgICAgICAgICAgIGFzeW5jOiB0cnVlLAogICAgICAgICAgICAgICAgICAgIHVybDogbG9jYWxTdWJtaXRVcmwsCiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ1BPU1QnLAogICAgICAgICAgICAgICAgICAgIGNvbnRlbnRUeXBlOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04JywKICAgICAgICAgICAgICAgICAgICBkYXRhOiBvcHRpb25zCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAkLmFqYXgocGFyYW1zKTsKICAgICAgICB9LAoKICAgICAgICBpc1NlcnZlckxvZ2dpbmdFbmFibGVkIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgaWYoKHRoaXMuanNvbk1vZGVsLm9uID09ICJ0cnVlIikgJiYgKHRoaXMuanNvbk1vZGVsLnR5cGUgPT0gInNlcnZlciIgfHwgdGhpcy5qc29uTW9kZWwudHlwZSA9PSAiY29uc29sZVNlcnZlciIpKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBzZXJ2ZXJIYW5kbGVyIDpmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIG9wdGlvbnMgPSB7J2xvZ01lc3NhZ2VzJyA6IHRoaXMubG9nTWVzc2FnZXMsICdyZW5kZXJDb250ZXh0JyA6IHRoaXMucmVuZGVyQ29udGV4dH07CiAgICAgICAgICAgIHRoaXMuX2ludm9rZUF0U2VydmVyKG9wdGlvbnMpOwogICAgICAgICAgICB0aGlzLmxvZ01lc3NhZ2VzID0gIiIgOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFdyaXRlcyBhIG1lc3NhZ2UgdG8gdGhlIGNvbnNvbGUgaWYgbG9nIGxldmVsIGlzIHNldCB0bwogICAgICAgICAqIHtAbGluayAjRkFUQUx9IG9yIGhpZ2hlci4KICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgVGhlIGxvZyBtZXNzYWdlCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmcvU3RyaW5nW119IHNuaXBwZXRzIChvcHRpb25hbCkgVGhlIHRleHRzIHJlcGxhY2luZwogICAgICAgICAqICAgICAgICA8Y29kZT57bn08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgZmF0YWwgOiBmdW5jdGlvbihjYXRlZ29yeSwgbWVzc2FnZSwgc25pcHBldHMpIHsKICAgICAgICAgICAgdGhpcy5sb2coY2F0ZWdvcnksIHRoaXMuRkFUQUwsIG1lc3NhZ2UsIHNuaXBwZXRzKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBXcml0ZXMgYSBtZXNzYWdlIHRvIHRoZSBjb25zb2xlIGlmIGxvZyBsZXZlbCBpcyBzZXQgdG8KICAgICAgICAgKiB7QGxpbmsgI0VSUk9SfSBvciBoaWdoZXIuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIFRoZSBsb2cgbWVzc2FnZQogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nL1N0cmluZ1tdfSBzbmlwcGV0cyAob3B0aW9uYWwpIFRoZSB0ZXh0cyByZXBsYWNpbmcKICAgICAgICAgKiAgICAgICAgPGNvZGU+e259PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIGVycm9yIDogZnVuY3Rpb24oY2F0ZWdvcnksIG1lc3NhZ2UsIHNuaXBwZXRzKSB7CiAgICAgICAgICAgIHRoaXMubG9nKGNhdGVnb3J5LCB0aGlzLkVSUk9SLCBtZXNzYWdlLCBzbmlwcGV0cyk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV3JpdGVzIGEgbWVzc2FnZSB0byB0aGUgY29uc29sZSBpZiBsb2cgbGV2ZWwgaXMgc2V0IHRvCiAgICAgICAgICoge0BsaW5rICNXQVJOfSBvciBoaWdoZXIuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIFRoZSBsb2cgbWVzc2FnZQogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nL1N0cmluZ1tdfSBzbmlwcGV0cyAob3B0aW9uYWwpIFRoZSB0ZXh0cyByZXBsYWNpbmcKICAgICAgICAgKiAgICAgICAgPGNvZGU+e259PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHdhcm4gOiBmdW5jdGlvbihjYXRlZ29yeSwgbWVzc2FnZSwgc25pcHBldHMpIHsKICAgICAgICAgICAgdGhpcy5sb2coY2F0ZWdvcnksIHRoaXMuV0FSTiwgbWVzc2FnZSwgc25pcHBldHMpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFdyaXRlcyBhIG1lc3NhZ2UgdG8gdGhlIGNvbnNvbGUgaWYgbG9nIGxldmVsIGlzIHNldCB0bwogICAgICAgICAqIHtAbGluayAjSU5GT30gb3IgaGlnaGVyLgogICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBUaGUgbG9nIG1lc3NhZ2UKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZy9TdHJpbmdbXX0gc25pcHBldHMgKG9wdGlvbmFsKSBUaGUgdGV4dHMgcmVwbGFjaW5nCiAgICAgICAgICogICAgICAgIDxjb2RlPntufTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBpbmZvIDogZnVuY3Rpb24oY2F0ZWdvcnksIG1lc3NhZ2UsIHNuaXBwZXRzKSB7CiAgICAgICAgICAgIHRoaXMubG9nKGNhdGVnb3J5LCB0aGlzLklORk8sIG1lc3NhZ2UsIHNuaXBwZXRzKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBXcml0ZXMgYSBtZXNzYWdlIHRvIHRoZSBjb25zb2xlIGlmIGxvZyBsZXZlbCBpcyBzZXQgdG8KICAgICAgICAgKiB7QGxpbmsgI0RFQlVHfSBvciBoaWdoZXIuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIFRoZSBsb2cgbWVzc2FnZQogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nL1N0cmluZ1tdfSBzbmlwcGV0cyAob3B0aW9uYWwpIFRoZSB0ZXh0cyByZXBsYWNpbmcKICAgICAgICAgKiAgICAgICAgPGNvZGU+e259PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIGRlYnVnIDogZnVuY3Rpb24oY2F0ZWdvcnksIG1lc3NhZ2UsIHNuaXBwZXRzKSB7CiAgICAgICAgICAgIHRoaXMubG9nKGNhdGVnb3J5LCB0aGlzLkRFQlVHLCBtZXNzYWdlLCBzbmlwcGV0cyk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV3JpdGVzIGEgbWVzc2FnZSB0byB0aGUgY29uc29sZSBpZiBsb2cgbGV2ZWwgaXMgc2V0IHRvCiAgICAgICAgICoge0BsaW5rICNUUkFDRX0gb3IgaGlnaGVyLgogICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBUaGUgbG9nIG1lc3NhZ2UKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZy9TdHJpbmdbXX0gc25pcHBldHMgKG9wdGlvbmFsKSBUaGUgdGV4dHMgcmVwbGFjaW5nCiAgICAgICAgICogICAgICAgIDxjb2RlPntufTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICB0cmFjZSA6ICBmdW5jdGlvbihjYXRlZ29yeSwgbWVzc2FnZSwgc25pcHBldHMpIHsKICAgICAgICAgICAgdGhpcy5sb2coY2F0ZWdvcnksIHRoaXMuVFJBQ0UsIG1lc3NhZ2UsIHNuaXBwZXRzKTsKICAgICAgICB9LAoKICAgICAgICBpc0xvZ0VuYWJsZWQgOiBmdW5jdGlvbihjYXRlZ29yeSwgbGV2ZWwpIHsKICAgICAgICAgICAgaWYodGhpcy5qc29uTW9kZWwub24gPT0gInRydWUiKSB7CiAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5qc29uTW9kZWwuY2F0ZWdvcnkuaW5kZXhPZihjYXRlZ29yeSkgOwogICAgICAgICAgICAgICAgaWYodGhpcy5qc29uTW9kZWwubGV2ZWxbcG9zXSA+PSBsZXZlbCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCB4ZmFsaWIsICQpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LkV2ZW50Q2xhc3MKICogQGltcG9ydCB4ZmFsaWIudXQuQ2xhc3MKICovCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgLy8gUmVndWxhciBleHByZXNzaW9uIHVzZWQgdG8gc3BsaXQgZXZlbnQgc3RyaW5ncwogICAgLy8gUmVndWxhciBleHByZXNzaW9uIHVzZWQgdG8gc3BsaXQgZXZlbnQgc3RyaW5ncwogICAgdmFyIGV2ZW50U3BsaXR0ZXIgPSAvXHMrLzsKCiAgICAvLyBBIG1vZHVsZSB0aGF0IGNhbiBiZSBtaXhlZCBpbiB0byAqYW55IG9iamVjdCogaW4gb3JkZXIgdG8gcHJvdmlkZSBpdCB3aXRoCiAgICAvLyBjdXN0b20gZXZlbnRzLiBZb3UgbWF5IGJpbmQgd2l0aCBgb25gIG9yIHJlbW92ZSB3aXRoIGBvZmZgIGNhbGxiYWNrIGZ1bmN0aW9ucwogICAgLy8gdG8gYW4gZXZlbnQ7IHRyaWdnZXJgLWluZyBhbiBldmVudCBmaXJlcyBhbGwgY2FsbGJhY2tzIGluIHN1Y2Nlc3Npb24uCiAgICAvLwogICAgdmFyIEV2ZW50Q2xhc3MgPSB4ZmFsaWIudXQuRXZlbnRDbGFzcyA9ICB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKCiAgICAgICAgLy8gQmluZCBvbmUgb3IgbW9yZSBzcGFjZSBzZXBhcmF0ZWQgZXZlbnRzLCBgZXZlbnRzYCwgdG8gYSBgbGlzdGVuZXJgCiAgICAgICAgLy8gb2JqZWN0LiBUaGUgb2JqZWN0IHNob3VsZCBpbXBsZW1lbnQgYGhhbmRsZUV2ZW50YCBmdW5jdGlvbiB3aGljaCB3aWxsIGJlCiAgICAgICAgLy8gY2FsbGVkIG9uIGV2ZW50IGRpc3BhdGNoCiAgICAgICAgb246IGZ1bmN0aW9uKGV2ZW50LCBsaXN0ZW5lciwgY29udGV4dCkgewoKICAgICAgICAgICAgdmFyIGNhbGxzLCBsaXN0LHJldFZhbCA9IHRydWU7CiAgICAgICAgICAgIHZhciBmbkNhbGxiYWNrID0gXy5pc0Z1bmN0aW9uKGxpc3RlbmVyKSA/IGxpc3RlbmVyIDogbnVsbDsKICAgICAgICAgICAgaWYgKCFsaXN0ZW5lciB8fCAoIWxpc3RlbmVyWyJoYW5kbGVFdmVudCJdICYmICFmbkNhbGxiYWNrKSkgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgY2FsbHMgPSB0aGlzLl9jYWxsYmFja3MgfHwgKHRoaXMuX2NhbGxiYWNrcyA9IHt9KTsKCiAgICAgICAgICAgIGxpc3QgPSBjYWxsc1tldmVudF0gfHwgKGNhbGxzW2V2ZW50XSA9IFtdKTsKICAgICAgICAgICAgaWYoZm5DYWxsYmFjayl7CiAgICAgICAgICAgICAgICBjb250ZXh0ID0gY29udGV4dCB8fCB0aGlzOwogICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gXy5maW5kKGxpc3QsIGZ1bmN0aW9uKGNhbGxiYWNrKXsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGNhbGxiYWNrLmZuID09IGZuQ2FsbGJhY2sgJiYgY2FsbGJhY2suY29udGV4dCA9PSBjb250ZXh0KTsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICAgICAgaWYoZm91bmQpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbGlzdC5wdXNoKHsiZm4iIDogZm5DYWxsYmFjaywgImNvbnRleHQiOiBjb250ZXh0fSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZXsKICAgICAgICAgICAgICAgIGlmKH5saXN0LmluZGV4T2YobGlzdGVuZXIpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBsaXN0LnB1c2gobGlzdGVuZXIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gIHRydWU7CiAgICAgICAgfSwKCiAgICAgICAgLy8gUmVtb3ZlIG9uZSBvciBtYW55IGNhbGxiYWNrcy4gSWYgYGxpc3RlbmVyYCBpcyBudWxsLCByZW1vdmVzIGFsbCBsaXN0ZW5lciBmb3IgdGhlCiAgICAgICAgLy8gZXZlbnQuIElmIGBldmVudHNgIGlzIG51bGwsIHJlbW92ZXMgYWxsIGJvdW5kIGNhbGxiYWNrcyBmb3IgYWxsIGV2ZW50cy4KICAgICAgICBvZmY6IGZ1bmN0aW9uKGV2ZW50cywgbGlzdGVuZXIsIGNvbnRleHQpIHsKICAgICAgICAgICAgdmFyIGV2ZW50LCBjYWxscywgbm9kZTsKCiAgICAgICAgICAgIC8vIE5vIGV2ZW50cywgb3IgcmVtb3ZpbmcgKmFsbCogZXZlbnRzLgogICAgICAgICAgICBpZiAoIShjYWxscyA9IHRoaXMuX2NhbGxiYWNrcykpIHJldHVybjsKICAgICAgICAgICAgaWYgKCEoZXZlbnRzIHx8IGxpc3RlbmVyKSkgewogICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2NhbGxiYWNrczsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgZm5DYWxsYmFjayA9IF8uaXNGdW5jdGlvbihsaXN0ZW5lcikgPyBsaXN0ZW5lciA6IG51bGw7CiAgICAgICAgICAgIC8vIExvb3AgdGhyb3VnaCB0aGUgbGlzdGVkIGV2ZW50cyBhbmQgY29udGV4dHMgYW5kIHJlbW92ZSB0aGUgcmVxdWlyZWQgb25lcy4KICAgICAgICAgICAgZXZlbnRzID0gZXZlbnRzID8gZXZlbnRzLnNwbGl0KGV2ZW50U3BsaXR0ZXIpIDogXy5rZXlzKGNhbGxzKTsKICAgICAgICAgICAgd2hpbGUgKGV2ZW50ID0gZXZlbnRzLnNoaWZ0KCkpIHsKICAgICAgICAgICAgICAgIG5vZGUgPSBjYWxsc1tldmVudF07CiAgICAgICAgICAgICAgICBjYWxsc1tldmVudF0gPSBfLmZpbHRlcihjYWxsc1tldmVudF0sZnVuY3Rpb24oZWxlbSkgewogICAgICAgICAgICAgICAgICAgIGlmKHR5cGVvZihsaXN0ZW5lcikgIT09ICJ1bmRlZmluZWQiKXsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoZm5DYWxsYmFjayAmJiBlbGVtLmZuID09IGZuQ2FsbGJhY2sgJiYgZWxlbS5jb250ZXh0ID09IGNvbnRleHQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoIWZuQ2FsbGJhY2sgJiYgbGlzdGVuZXIgPT09IGVsZW0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGlmKCFjYWxsc1tldmVudF0ubGVuZ3RoKQogICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBjYWxsc1tldmVudF07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCgogICAgICAgIC8vIFRyaWdnZXIgb25lIG9yIG1hbnkgZXZlbnRzLCBmaXJpbmcgYWxsIGJvdW5kIGNhbGxiYWNrcy4gQ2FsbGJhY2tzIGFyZQogICAgICAgIC8vIHBhc3NlZCB0aGUgc2FtZSBhcmd1bWVudHMgYXMgYHRyaWdnZXJgIGV4Y2VwdCB0aGUgZmlyc3QKICAgICAgICB0cmlnZ2VyOiBmdW5jdGlvbihldmVudHMpIHsKICAgICAgICAgICAgdmFyIGV2ZW50LCBjYWxscywgcmVzdDsKICAgICAgICAgICAgaWYgKCEoY2FsbHMgPSB0aGlzLl9jYWxsYmFja3MpKSByZXR1cm4gdGhpczsKICAgICAgICAgICAgZXZlbnRzID0gZXZlbnRzLnNwbGl0KGV2ZW50U3BsaXR0ZXIpOwogICAgICAgICAgICB2YXIgcGF5TG9hZCA9IF8ucmVzdChhcmd1bWVudHMpOwogICAgICAgICAgICB3aGlsZSAoZXZlbnQgPSBldmVudHMuc2hpZnQoKSkgewogICAgICAgICAgICAgICAgXy5lYWNoKGNhbGxzW2V2ZW50XSxmdW5jdGlvbihjYWxsYmFjaykgewogICAgICAgICAgICAgICAgICAgIGlmKGNhbGxiYWNrLmZuICYmIGNhbGxiYWNrLmNvbnRleHQpewogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5mbi5hcHBseShjYWxsYmFjay5jb250ZXh0LCBwYXlMb2FkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoXy5pc0Z1bmN0aW9uKGNhbGxiYWNrLmhhbmRsZUV2ZW50KSl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmhhbmRsZUV2ZW50LmFwcGx5KGNhbGxiYWNrLCBwYXlMb2FkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgIH0pOwoKCn0pKF8sIHhmYWxpYik7CgoKKGZ1bmN0aW9uIChfLCAkLCB4ZmFsaWIpIHsKICAgIHZhciBYZmFVdGlsID0geGZhbGliLnV0LlhmYVV0aWwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgfSwKICAgICAgICByZWdpc3RlcmVkTG9jYWxlUHJvcGVydGllcyA9IG51bGwsCiAgICAgICAgdGltZW91dExpc3RlbmVyQXR0YWNoZWQgPSBmYWxzZSwKICAgICAgICB0aW1lb3V0cyA9IFtdLAogICAgICAgIGF0dGFjaENsZWFyVGltZW91dExpc3RlbmVyID0gZnVuY3Rpb24gKHRpbWVvdXQpIHsKICAgICAgICAgICAgdGltZW91dHMucHVzaCh0aW1lb3V0KTsKICAgICAgICAgICAgaWYgKHRpbWVvdXRMaXN0ZW5lckF0dGFjaGVkID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJCh3aW5kb3cpLm9uZSgiZGVzdHJveS54ZmEiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgXy5lYWNoKHRpbWVvdXRzLCBmdW5jdGlvbiAoX3RpbWVvdXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF90aW1lb3V0KTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB0aW1lb3V0cyA9IFtdOwogICAgICAgICAgICAgICAgICAgIHRpbWVvdXRMaXN0ZW5lckF0dGFjaGVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHRpbWVvdXRMaXN0ZW5lckF0dGFjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICBfLmV4dGVuZChYZmFVdGlsLnByb3RvdHlwZSwgewogICAgICAgIF9nbG9iYWxVbmlxdWVJZDogKG5ldyBEYXRlKCkpLmdldFRpbWUoKSwKICAgICAgICBsb2dnZXI6IG51bGwsCgogICAgICAgIGZvcm1TY2FsZUZhY3RvcjogMSwgICAgICAvLyB1c2VkIHRvIGFwcHJvcHJpYXRlbHkgc2NhbGUgdGhlIGZvcm0gd2hlbiBjb250YWluZWQgaW5zaWRlIGFuIGlmcmFtZQoKICAgICAgICBnZXRPckVsc2U6IHhmYWxpYi51dC5DbGFzcy5wcm90b3R5cGUuZ2V0T3JFbHNlLAogICAgICAgIC8vbWFwIG9mIGV2ZW50IG5hbWVzIGJldHdlZW4gWFRHIGFuZCBNb2JpbGUgRm9ybQogICAgICAgIC8vTW9iaWxlIEZvcm0gdXNlcyBkaWZmZXJlbnQgbmFtZXMgZm9yIHNvbWUgdGhlIGV2ZW50IGFuZCBsZXQncyBmaXggdGhvc2UgbmFtZXMgYmVmb3JlIHNlbmRpbmcgdGhlbSB0byBYVEcuCiAgICAgICAgX3h0Z0V2ZW50TmFtZTogewogICAgICAgICAgICAiJGZvcm1yZWFkeSI6ICJyZWFkeSIsCiAgICAgICAgICAgICIkbGF5b3V0cmVhZHkiOiAicmVhZHkiCiAgICAgICAgfSwKCiAgICAgICAgZ2VuZXJhdGVVSUQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICJVSUQiICsgKCsrWGZhVXRpbC5wcm90b3R5cGUuX2dsb2JhbFVuaXF1ZUlkKTsKICAgICAgICB9LAoKICAgICAgICBtYXRjaEpzb25UeXBlOiBmdW5jdGlvbiAoanNvbk1vZGVsLCBfY2xhc3MpIHsgICAvL1RPRE86IGhhbmRsZSBnZXRPckVsc2UKICAgICAgICAgICAgcmV0dXJuIChqc29uTW9kZWwgJiYgX2NsYXNzICYmIFhmYVV0aWwucHJvdG90eXBlLmdldE9yRWxzZShqc29uTW9kZWwuX2NsYXNzLCAiIikudG9Mb3dlckNhc2UoKSA9PSAoIiIgKyBfY2xhc3MpLnRvTG93ZXJDYXNlKCkpOwogICAgICAgIH0sCgogICAgICAgICRkYXRhOiBmdW5jdGlvbiAoZWxlbSwgbmFtZSwgZGF0YSkgewogICAgICAgICAgICBpZiAoISQuZGF0YShlbGVtLCAiX3hmYUluaXRpYWxpemVkIikpIHsKICAgICAgICAgICAgICAgIC8vSW5pdGlhbGl6ZWQgZGF0YS0gYXR0cmlidXRlcyBwYXJzZSBmb3Igb25jZSB1c2luZyB0aGlzIGNhbGwuCiAgICAgICAgICAgICAgICAvLyBOZXh0IG9ud2FyZCBkb24ndCB1c2UgdGhpcy4gSW5zdGVhZCB1c2UgJC5kYXRhIHdoaWNoIGlzIGNoZWFwLwogICAgICAgICAgICAgICAgJChlbGVtKS5kYXRhKCk7CiAgICAgICAgICAgICAgICAkLmRhdGEoZWxlbSwgIl94ZmFJbml0aWFsaXplZCIsIHRydWUpOyAvL01hcmsgdGhlIGVsZW1lbnQgdG8gc2F5IHRoYXQgZGF0YSBoYXMgYmVlbiBpbml0aWFsaXplZC4KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gJC5kYXRhKGVsZW0sIG5hbWUsIGRhdGEpOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogYWx0ZXJuYXRpdmUgdG8galF1ZXJ5LmNzcyB3aGljaCBzZXRzIHN0eWxlIHByb3BlcnRpZXMgZGlyZWN0bHkgdGhyb3VnaCBlbGVtZW50LnN0eWxlLiBUaGlzIGlzIG11Y2ggZmFzdGVyIHRoZW4KICAgICAgICAgKiBjb3JyZXNwb25kaW5nIGpRdWVyeS5jc3MgYWx0ZXJuYXRpdmUuCiAgICAgICAgICoKICAgICAgICAgKiBXYXJuaW5nOiB0aGlzIG9ubHkgc3VwcG9ydHMgc3RhbmRhcmQgY3NzIHByb3BlcnR5IG5hbWVzIGFuZCBkb2VzIG5vdCBkbyBhbnkgcHJlLXByb2Nlc3Npbmcgb2YgbmFtZSBhbmQgdmFsdWUuCiAgICAgICAgICogU28gY2FsbGluZyB0aGlzLCBtYWtlIHN1cmUgdGhlIHN0eWxlIG5hbWVzIGFyZSBjb21wYXRpYmxlLgogICAgICAgICAqLwogICAgICAgICRjc3M6IGZ1bmN0aW9uIChlbGVtLCBzdHlsZXNPYmopIHsKICAgICAgICAgICAgLy8gRXhjbHVkZSB0aGUgZm9sbG93aW5nIGNzcyBwcm9wZXJ0aWVzIHRvIGFkZCBweC4gY29waWVkIGZyb20ganF1ZXJ5LmNzc051bWJlciB0byBhZGQgaHlwaGVuYXRlZCBzdHlsZSBuYW1lcwogICAgICAgICAgICB2YXIgY3NzTnVtYmVyID0gewogICAgICAgICAgICAgICAgImZpbGxPcGFjaXR5IjogdHJ1ZSwKICAgICAgICAgICAgICAgICJmaWxsLW9wYWNpdHkiOiB0cnVlLAogICAgICAgICAgICAgICAgImZvbnRXZWlnaHQiOiB0cnVlLAogICAgICAgICAgICAgICAgImZvbnQtd2VpZ2h0IjogdHJ1ZSwKICAgICAgICAgICAgICAgICJsaW5lSGVpZ2h0IjogdHJ1ZSwKICAgICAgICAgICAgICAgICJsaW5lLWhlaWdodCI6IHRydWUsCiAgICAgICAgICAgICAgICAiekluZGV4IjogdHJ1ZSwKICAgICAgICAgICAgICAgICJ6LWluZGV4IjogdHJ1ZSwKICAgICAgICAgICAgICAgICJvcGFjaXR5IjogdHJ1ZSwKICAgICAgICAgICAgICAgICJvcnBoYW5zIjogdHJ1ZSwKICAgICAgICAgICAgICAgICJ3aWRvd3MiOiB0cnVlLAogICAgICAgICAgICAgICAgInpvb20iOiB0cnVlCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBmb3IgKHZhciBwcm9wIGluIHN0eWxlc09iaikgewogICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gc3R5bGVzT2JqW3Byb3BdOwogICAgICAgICAgICAgICAgLy8gSWYgYSBudW1iZXIgd2FzIHBhc3NlZCBpbiwgYWRkICdweCcgdG8gdGhlIChleGNlcHQgZm9yIGNlcnRhaW4gQ1NTIHByb3BlcnRpZXMpCiAgICAgICAgICAgICAgICBpZiAoXy5pc051bWJlcih2YWx1ZSkgJiYgIWNzc051bWJlclsgcHJvcCBdKSB7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgKz0gInB4IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsZW0uc3R5bGVbcHJvcF0gPSB2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGlzVGFibGVIRjogZnVuY3Rpb24gKGlDaGlsZE5vZGUpIHsKICAgICAgICAgICAgLy9tb2RlbCBjYW4gYmUgYSBOb2RlIG9iamVjdCBvciBzaW1wbHkgYSBqc29uCiAgICAgICAgICAgIHZhciBhc3Npc3RKc29uID0gXy5maW5kKGlDaGlsZE5vZGUuY2hpbGRyZW4sIGZ1bmN0aW9uIChqQ2hpbGQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBqQ2hpbGQuX2NsYXNzID09ICJhc3Npc3QiOwogICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgdmFyIGNoaWxkUm9sZSA9IChhc3Npc3RKc29uIHx8IHt9KS5yb2xlOwogICAgICAgICAgICBpZiAoY2hpbGRSb2xlID09ICJUSCIgfHwgY2hpbGRSb2xlID09ICJURiIpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIGdldFVpT25lT2ZDaGlsZFRhZzogZnVuY3Rpb24gKHVpUGFyZW50KSB7CiAgICAgICAgICAgIHZhciB1aUVsID0gXy5maW5kKHVpUGFyZW50LmNoaWxkcmVuLCBmdW5jdGlvbiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZC5fY2xhc3MgPT0gInVpIjsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlmICghdWlFbCkKICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgIHZhciB1aU9uZU9mQ2hpbGRNYXAgPSB4ZmFsaWIucnVudGltZS54ZmEuX3RlbXBsYXRlU2NoZW1hLl9nZXRPbmVPZkNoaWxkKCJ1aSIpOwogICAgICAgICAgICB2YXIgdWlPbmVPZkNoaWxkID0gXy5maW5kKHVpRWwuY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHVpT25lT2ZDaGlsZE1hcFtjaGlsZC5fY2xhc3NdID09IHRydWU7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBpZiAoIXVpT25lT2ZDaGlsZCkKICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgIHJldHVybiB1aU9uZU9mQ2hpbGQuX2NsYXNzOwogICAgICAgIH0sCgogICAgICAgIC8vVE9ETzogdGhpcyBzaG91bGQgYmUgcmVtb3ZlZC4gT25lIG9mIHRoZSB3b3JzdCBmdW5jdGlvbi4KICAgICAgICBkSW5kZXhPZjogZnVuY3Rpb24gKHNlYXJjaEFycmF5LCBpdGVtMkZpbmQpIHsKICAgICAgICAgICAgdmFyIGluZCA9IC0xOwogICAgICAgICAgICBfLmZpbmQoc2VhcmNoQXJyYXksIGZ1bmN0aW9uIChpdGVtLCBpbmRleCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT0gaXRlbTJGaW5kICYmIChpbmQgPSBpbmRleCkKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHJldHVybiBpbmQ7CiAgICAgICAgfSwKCiAgICAgICAgc3BsaXRTdHJpbmdCeVdpZHRoOiBmdW5jdGlvbiAodmFsdWUsIHdpZHRoLCByZWZFbCkgewogICAgICAgICAgICB2YXIgaSA9IHZhbHVlLmxlbmd0aCAsIGV4cGVjdGVkV2lkdGg7CiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIGV4cGVjdGVkV2lkdGggPSB4ZmFsaWIudmlldy51dGlsLlRleHRNZXRyaWNzLm1lYXN1cmVFeHRlbnQodmFsdWUuc2xpY2UoMCwgaSksIHsicmVmRWwiOiByZWZFbCwgbWF4V2lkdGg6IC0xfSkud2lkdGg7CiAgICAgICAgICAgICAgICBpLS07CiAgICAgICAgICAgIH0gd2hpbGUgKGV4cGVjdGVkV2lkdGggPiB3aWR0aCkKICAgICAgICAgICAgaWYgKGkgIT0gdmFsdWUubGVuZ3RoIC0gMSkKICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5zbGljZSgwLCBpICsgMSk7CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9LAoKICAgICAgICBpc1JlcGVhdGFiZUVsOiBmdW5jdGlvbiAoZWxUYWcpIHsKICAgICAgICAgICAgaWYgKGVsVGFnID09ICJzdWJmb3JtIiB8fCBlbFRhZyA9PSAic3ViZm9ybVNldCIpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqIHN0cmlwT3JDYWxsKHRvU3RyaXAsIGRpZmZGdW5jLCBmQXJncykKICAgICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICAgKiBjb21tb24gdXRpbGl0eSBmdW5jdGlvbiB0byBoYW5kbGUgZmluYWwgc3VibWlzc2lvbiBwYXlsb2FkIHN0cmlwcGluZwogICAgICAgICAqIEBwYXJhbSB7Ym9vbH0gdG9TdHJpcCA6IGZsYWcgdG8gc2lnbmlmeSB3aGV0aGVyIHRvIG9wdGltaXplIGpzb25Nb2RlbERpZmYgc2l6ZSwgYnkgc3RyaXBwaW5nIG9mZiB1bm5lY2Vzc2FyeSBwcm9wZXJ0aWVzCiAgICAgICAgICogQHBhcmFtIHtmdW5jdGlvbn0gZGlmZkZ1bmMgOiBjYWxsYmFjayBmdW5jLiBjYWxsIGluIGNhc2Ugc3VibWl0IGlzIG5vdCBvbgogICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGZBcmdzIDogYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byB0aGUgZGlmZiBmdW5jLgogICAgICAgICAqIEByZXR1cm5zIHtvYmplY3R9IG9iamVjdCBjb250YWluaW5nIHRoZSBqc29uRGlmZgogICAgICAgICAqLwogICAgICAgIC8vIHNob3VsZCBBTFdBWVMgYmUgY2FsbGVkIHdpdGggYSBmbGFnIHNpZ25pZnlpbmcgaWYgYSBzdWJtaXNzaW9uIGlzIGluIHByb2dyZXNzLAogICAgICAgIC8vIGFuZCBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGNvbXB1dGUgdGhlIGpzb24gdG8gYmUgc2VudCBiYWNrIGR1cmluZyBzdWJtaXNzaW9uLCB1c3VhbGx5IGFuIGFwdCAnX2NvbXB1dGVKc29uRGlmZicKICAgICAgICBzdHJpcE9yQ2FsbDogZnVuY3Rpb24gKHRvU3RyaXAsIGRpZmZGdW5jLCBmQXJncykgewogICAgICAgICAgICBpZiAodG9TdHJpcCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICAiY2hhbmdlZCI6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICJqc29uRGlmZmVyZW5jZSI6IHt9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKF8uaXNGdW5jdGlvbihkaWZmRnVuYykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBkaWZmRnVuYy5hcHBseSh0aGlzLCBmQXJncyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBwYXJ0aWFsU3RyaXBPckNhbGwoc3RyaXBMdmwsIGRpZmZGdW5jLCBmQXJncykKICAgICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICAgKiBjb21tb24gdXRpbGl0eSBmdW5jdGlvbiB0byBoYW5kbGUgZmluYWwgc3VibWlzc2lvbiBwYXlsb2FkIHN0cmlwcGluZyBvciBmb3Igb3V0cHV0IG9mIGdldEZvcm1TdGF0ZS4KICAgICAgICAgKiBAcGFyYW0ge2ludH0gZGlmZl9sZXZlbCA6IGZsYWcgdG8gc2lnbmlmeSB3aGV0aGVyIHRvIG9wdGltaXplIGpzb25Nb2RlbERpZmYgc2l6ZSwgYnkgc3RyaXBwaW5nIG9mZiB1bm5lY2Vzc2FyeSBwcm9wZXJ0aWVzCiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICBtdXN0IGJlIDAsMSwgb3IgMiwgYXMgd2l0aCAiZGlmZl9sZXZlbCIgcGFyYW0gb2YgX2NvbXB1dGVKc29uRGlmZi4KICAgICAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBkaWZmRnVuYyA6IGNhbGxiYWNrIGZ1bmMuIGNhbGwgaW4gY2FzZSBzdWJtaXQgaXMgbm90IG9uCiAgICAgICAgICogQHJldHVybnMge29iamVjdH0gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGpzb25EaWZmCiAgICAgICAgICovCiAgICAgICAgcGFydGlhbFN0cmlwT3JDYWxsOiBmdW5jdGlvbiAoZGlmZl9sZXZlbCwgZGlmZkZ1bmMpIHsKICAgICAgICAgICAgdmFyIGRpZmZPYmogPSBkaWZmRnVuYy5jYWxsKHRoaXMsIGRpZmZfbGV2ZWwpOwoKICAgICAgICAgICAgaWYgKCFkaWZmT2JqLmNoYW5nZWQpIHsKICAgICAgICAgICAgICAgIGlmKGRpZmZfbGV2ZWwgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICBkaWZmT2JqID0gewogICAgICAgICAgICAgICAgICAgICAgICAiY2hhbmdlZCI6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICJqc29uRGlmZmVyZW5jZSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfY2xhc3MiOiB0aGlzLmpzb25Nb2RlbC5fY2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibmFtZSI6IHRoaXMuanNvbk1vZGVsLm5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGRpZmZPYmouanNvbkRpZmZlcmVuY2UgPSB7fTsgIC8vIGRvbid0IG5lZWQgc3R1ZmYgZm9yIG90aGVyIGNhc2VzCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBkaWZmT2JqOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqIHN0cmlwT2JqZWN0KG9iaiwgZXhjZXB0aW9uTmFtZXMpCiAgICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAgICogVXRpbGl0eSBmdW5jdGlvbiB0byBzdHJpcCB1bm5lY2Vzc2FyeSBwcm9wZXJ0aWVzIGZyb20gYW4gb2JqZWN0CiAgICAgICAgICogQHBhcmFtIHtvYmplY3R9IG9iaiA6IHRoZSBvYmplY3QgdG8gc3RyaXAKICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBleGNlcHRpb25OYW1lcyA6IGFycmF5IGhvbGRpbmcgbmFtZXMgb2YgaW1wb3J0YW50IHByb3BlcnRpZXMgdG8gcHJlc2VydmUKICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gOiB0cnVlIGlmIHRoaXMgb2JqLCBvciBhbnkgb2YgaXQncyBkZXNjZW5kYW50IGlzIHJldHVybmVkIHVuLXN0cmlwcGVkCiAgICAgICAgICovCiAgICAgICAgc3RyaXBPYmplY3Q6IGZ1bmN0aW9uIChvYmosIGV4Y2VwdGlvbk5hbWVzKSB7CiAgICAgICAgICAgIGlmIChfLmlzRW1wdHkob2JqKSB8fCAhXy5pc09iamVjdChvYmopKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBkb250U3RyaXAgPSBmYWxzZTsKICAgICAgICAgICAgICAgIF8uZWFjaChfLmtleXMob2JqKSwgZnVuY3Rpb24gKHByb3BOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGtlZXBQcm9wID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFfLmNvbnRhaW5zKGV4Y2VwdGlvbk5hbWVzLCBwcm9wTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF8uaXNBcnJheShvYmpbcHJvcE5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5lYWNoKG9ialtwcm9wTmFtZV0sIGZ1bmN0aW9uIChhcnJFbGVtKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzVW5TdHJpcHBlZCA9IFhmYVV0aWwucHJvdG90eXBlLnN0cmlwT2JqZWN0KGFyckVsZW0sIGV4Y2VwdGlvbk5hbWVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwUHJvcCA9IGtlZXBQcm9wIHx8IGlzVW5TdHJpcHBlZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKF8uaXNPYmplY3Qob2JqW3Byb3BOYW1lXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXBQcm9wID0gWGZhVXRpbC5wcm90b3R5cGUuc3RyaXBPYmplY3Qob2JqW3Byb3BOYW1lXSwgZXhjZXB0aW9uTmFtZXMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWtlZXBQcm9wKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgb2JqW3Byb3BOYW1lXTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbnRTdHJpcCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBkb250U3RyaXAgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgcmV0dXJuIGRvbnRTdHJpcDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNvbXB1dGVEb21Kc29uRGlmZjogZnVuY3Rpb24gKGRvbU5vZGUsIGRpZmZfbGV2ZWwpIHsKICAgICAgICAgICAgdmFyIGNoYW5nZWQgPSB0cnVlOwogICAgICAgICAgICBpZiAoZG9tTm9kZS5oYXNPd25Qcm9wZXJ0eSgiX21vZGVsQ2hhbmdlZCIpKSB7CiAgICAgICAgICAgICAgICBjaGFuZ2VkID0gZG9tTm9kZS5fbW9kZWxDaGFuZ2VkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBqc29uRGlmZiA9IHt9OwogICAgICAgICAgICBpZiAoY2hhbmdlZCkgewogICAgICAgICAgICAgICAgdGhpcy5jb3B5T2JqZWN0KGRvbU5vZGUuanNvbk1vZGVsLCBqc29uRGlmZiwgeyJleGNlcHRpb25zIjogWyJjaGlsZHJlbiIsICJ7ZGVmYXVsdH0iLCAiZXh0cmFzIl19KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGpzb25EaWZmID0ge19jbGFzczogZG9tTm9kZS5jbGFzc05hbWV9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghY2hhbmdlZCAmJiBkb21Ob2RlLmpzb25Nb2RlbC5oYXNPd25Qcm9wZXJ0eSgibmFtZSIpKSB7CiAgICAgICAgICAgICAgICBqc29uRGlmZi5uYW1lID0gZG9tTm9kZS5qc29uTW9kZWwubmFtZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZG9tTm9kZS5uYW1lID09PSAiRlNfRVhUUkFTIiAmJiBkaWZmX2xldmVsID09PSAzKSB7CiAgICAgICAgICAgICAgICBkb21Ob2RlLl9jaGlsZE1vZGlmaWVkID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgImNoYW5nZWQiOiBjaGFuZ2VkLAogICAgICAgICAgICAgICAganNvbkRpZmZlcmVuY2U6IGpzb25EaWZmCiAgICAgICAgICAgIH07CiAgICAgICAgfSwKCiAgICAgICAgZ2V0TG9nZ2VyOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBYZmFVdGlsLnByb3RvdHlwZS5sb2dnZXIgfHwgWGZhVXRpbC5wcm90b3R5cGUuZ2V0T3JFbHNlKHhmYWxpYiwgInJ1bnRpbWUueGZhLkxvZ2dlciIsIG51bGwpOwogICAgICAgIH0sCgogICAgICAgIGdldEVycm9yTWFuYWdlcjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gWGZhVXRpbC5wcm90b3R5cGUuZ2V0T3JFbHNlKHhmYWxpYiwgInJ1bnRpbWUueGZhLkVycm9yTWFuYWdlciIsIG51bGwpOwogICAgICAgIH0sCgogICAgICAgIFhGQV9DTElDS19FVkVOVDogInhmYWNsaWNrIiwKICAgICAgICBYRkFfRVhJVF9FVkVOVDogInhmYWV4aXQiLAogICAgICAgIFhGQV9FTlRFUl9FVkVOVDogInhmYWVudGVyIiwKICAgICAgICBYRkFfQ0hBTkdFX0VWRU5UOiAieGZhY2hhbmdlIiwKICAgICAgICBYRkFfUFJFT1BFTl9FVkVOVDogInhmYXByZW9wZW4iLAoKICAgICAgICBidHduOiBmdW5jdGlvbiAodmFsLCBhLCBiKSB7CiAgICAgICAgICAgIHJldHVybiB2YWwgPiBhICYmIHZhbCA8IGI7CiAgICAgICAgfSwKCiAgICAgICAgLy8gZnVuY3Rpb24gdG8gZGV0ZWN0IGlmIEJyb3dzZXIgaXMgY2hyb21lIC8gc2FmYXJpICh3ZWJraXQpCiAgICAgICAgaXNXZWJraXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICAhISQuYnJvd3Nlci53ZWJraXQgfHwgL3dlYmtpdC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkpIHx8ICEhd2luZG93LmNocm9tZSB8fCAhISQuYnJvd3Nlci5jaHJvbWUgfHwgL2Nocm9tKGV8aXVtKS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkpIHx8ICEhJC5icm93c2VyLnNhZmFyaSB8fCAhIXdpbmRvdy53ZWJraXRVUkwgfHwKICAgICAgICAgICAgICAgICggL3NhZmFyaS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkpICYmCiAgICAgICAgICAgICAgICAgICAgL2FwcGxlIGNvbXB1dGVyLy50ZXN0KG5hdmlnYXRvci52ZW5kb3IudG9Mb3dlckNhc2UoKSkgKTsKCiAgICAgICAgICAgIC8vIFRPRE8gOiBmaW5kIGEgYmV0dGVyIHdheSB0byBkbyB0aGlzIGFzICQuYnJvd3NlciBpcyBkZXByZWNhdGVkIGFuZAogICAgICAgICAgICAvLyB1c2VyQWdlbnQgbWF5IGJlIHNwb29mZWQKICAgICAgICB9LAoKICAgICAgICBjbGVhclRpbWVvdXRPbkRlc3Ryb3k6IGZ1bmN0aW9uICh0aW1lb3V0KSB7CiAgICAgICAgICAgIGF0dGFjaENsZWFyVGltZW91dExpc3RlbmVyKHRpbWVvdXQpOwogICAgICAgIH0sCgogICAgICAgIC8vIGZ1bmN0aW9uIHRvIGRldGVjdCBpZiBCcm93c2VyIGlzICBzYWZhcmkKICAgICAgICBpc1NhZmFyaTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gKCAvc2FmYXJpLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKSkgJiYKICAgICAgICAgICAgICAgICAgICAvYXBwbGUgY29tcHV0ZXIvLnRlc3QobmF2aWdhdG9yLnZlbmRvci50b0xvd2VyQ2FzZSgpKSApOwogICAgICAgIH0sCgogICAgICAgIGdldExvY2FsZVN0cmluZ3M6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi5sb2NhbGUuU3RyaW5nczsKICAgICAgICB9LAoKICAgICAgICBnZXRMb2dNZXNzYWdlczogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4geGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlczsKICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIFRoaXMgZnVuY3Rpb24gc2hvdWxkIG5vdCBiZSBhZGRlZCBpbiB0aGUgcHJvdG90eXBlIG9mIGFueSBPYmplY3QKICAgICAgICAgKiBhcyBpbiB0aGUgY2FzZSBvZiBvdGhlciBmdW5jdGlvbnMKICAgICAgICAgKi8KICAgICAgICByZWdpc3RlckxvY2FsZVByb3BlcnRpZXM6IGZ1bmN0aW9uIChwcm9wcykgewogICAgICAgICAgICByZWdpc3RlcmVkTG9jYWxlUHJvcGVydGllcyA9IHByb3BzOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogVGhpcyBmdW5jdGlvbiBzaG91bGQgbm90IGJlIGFkZGVkIGluIHRoZSBwcm90b3R5cGUgb2YgYW55IE9iamVjdAogICAgICAgICAqIGFzIGluIHRoZSBjYXNlIG9mIG90aGVyIGZ1bmN0aW9ucwogICAgICAgICAqLwogICAgICAgIGdldERlZmF1bHRMb2NhbGVQcm9wZXJ0eTogZnVuY3Rpb24gKHByb3BlcnR5KSB7CiAgICAgICAgICAgIHZhciBsb2NhbGVQcm9wcyA9IHJlZ2lzdGVyZWRMb2NhbGVQcm9wZXJ0aWVzIHx8IHRoaXMuZ2V0T3JFbHNlKHhmYWxpYiwgInNjcmlwdC5YZmEuX2RlZmF1bHRMb2NhbGUiLCBudWxsKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JFbHNlKGxvY2FsZVByb3BzLCBwcm9wZXJ0eSwgbnVsbCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogRW5jb2RlcyA8c2NyaXB0PiBhbmQgPC9zY3JpcHQ+IHdpdGggJmx0O3NjcmlwdCZndDsgYW5kICZsdDsvc2NyaXB0Jmd0OwogICAgICAgICAqIERvZXMgc2FtZSB3aXRoIGltZywgdmlkZW8gYW5kIGF1ZGlvIHRhZ3MgYWxzby4KICAgICAgICAgKiBUaGVzZSB0YWdzIGFyZSBiZWluZyByZW1vdmVkIHNpbmNlIHNjcmlwdHMgY2FuIGJlIHJ1biB0aHJvdWdoCiAgICAgICAgICogPGltZyBvbmVycm9yPSJzY3JpcHQiIC8+IChzYW1lIGZvciBhdWRpbyBhbmQgdmlkZW8pLgogICAgICAgICAqLwogICAgICAgIGVuY29kZVNjcmlwdGFibGVUYWdzOiBmdW5jdGlvbiAoc3RyKSB7CiAgICAgICAgICAgIHZhciBpbmRleDsKICAgICAgICAgICAgaWYgKF8uaXNTdHJpbmcoc3RyKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKC88KFwvPykoc2NyaXB0W148Pl0qKT4vZ2ksICcmbHQ7JDEkMiZndDsnKQogICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC88KFwvPykoaW1nW148Pl0qKT4vZ2ksICcmbHQ7JDEkMiZndDsnKQogICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC88KFwvPykodmlkZW9bXjw+XSopPi9naSwgJyZsdDskMSQyJmd0OycpCiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLzwoXC8/KShhdWRpb1tePD5dKik+L2dpLCAnJmx0OyQxJDImZ3Q7JykKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGlkIDogYSBzdHJpbmcgcmVwcmVzZW50aW5nIGFuIEhUTUwgZWxlbWVudCBpZC4KICAgICAgICAgKgogICAgICAgICAqIHJldHVybiBhZnRlciBhcHBseWluZyBhbiBlc2NhcGluZyAnXCcgYmVmb3JlIGVhY2ggIyAuIDogWyBdCiAgICAgICAgICovCiAgICAgICAganFJZDogZnVuY3Rpb24oaWQpIHsKICAgICAgICAgICAgcmV0dXJuICIjIiArIGlkLnJlcGxhY2UoLygjfDp8XC58XFt8XF0pL2csICJcXCQxIik7CiAgICAgICAgfSwKCiAgICAgICAgX3RyaWdnZXJPbkJyaWRnZTogZnVuY3Rpb24gKGV2ZW50TmFtZSwgdGFyZ2V0LCBwcm9wZXJ0eSwgb2xkVmFsLCBuZXdWYWwpIHsKICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoZXZlbnROYW1lLCB0YXJnZXQsCiAgICAgICAgICAgICAgICBwcm9wZXJ0eSwgb2xkVmFsLCBuZXdWYWwpOwogICAgICAgICAgICBpZihmb3JtQnJpZGdlKXsKICAgICAgICAgICAgICAgIHdpbmRvdy5mb3JtQnJpZGdlLnRyaWdnZXIoZXZlbnROYW1lLCBldm50KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogcGFkcyB0aGUgcGFzc2VkIGluIFN0cmluZyBzdHIgYnkgcHJlLXBlbmRpbmcgcGFkQ2hhcnMgdG8gY29udmVydCBpdCB0byBhIHN0cmluZyBvZiBnaXZlbiB3aWR0aC4KICAgICAgICAgKiBJZiBzdHJpbmcgbGVuZ3RoIGlzIGFscmVhZHkgZ3JlYXRlciB0aGF0IGVxdWFsIHRvIGdpdmVuIHdpZHRoLCBvcmlnaW5hbCBzdHJpbmcgaXMgcmV0dXJuZWQuCiAgICAgICAgICovCiAgICAgICAgcGFkU3RyaW5nIDogZnVuY3Rpb24gKHN0ciwgd2lkdGgsIHBhZENoYXIpIHsKICAgICAgICAgICAgcGFkQ2hhciA9IHBhZENoYXIgfHwgJzAnOwogICAgICAgICAgICBzdHIgPSBzdHIgKyAnJzsKICAgICAgICAgICAgcmV0dXJuIHN0ci5sZW5ndGggPj0gd2lkdGggPyBzdHIgOiBuZXcgQXJyYXkod2lkdGggLSBzdHIubGVuZ3RoICsgMSkuam9pbihwYWRDaGFyKSArIHN0cjsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiByZXR1cm5zIHRydWUgaWYgdGhlIGJyb3dzZXIgaXMgSUUgb3RoZXJ3aXNlIGZhbHNlCiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59CiAgICAgICAgICovCiAgICAgICAgaXNJRTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gJC5icm93c2VyLm1zaWUgfHwgKG5hdmlnYXRvci5hcHBOYW1lID09PSAiTmV0c2NhcGUiICYmIG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL1RyaWRlbnRcLy8pKQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIHJldHVybnMgZmFsc2UgaWYgb3RoZXIgYnJvd3NlcgogICAgICAgICAqIGlmIGllIHRyaWVzIHRvIHJldHVybiBicm93c2VyIHZlcnNpb24gKG5vbiBmYWxzeSkKICAgICAgICAgKiBAcmV0dXJucyB7Kn0KICAgICAgICAgKi8KCiAgICAgICAgZGV0ZWN0SUU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgLy8gMXN0IHRyeSBqcQogICAgICAgICAgICBpZigkLmJyb3dzZXIubXNpZSkgewogICAgICAgICAgICAgICAgaWYoJC5icm93c2VyLnZlcnNpb24gJiYgcGFyc2VJbnQoJC5icm93c2VyLnZlcnNpb24sIDEwKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludCgkLmJyb3dzZXIudmVyc2lvbiwgMTApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgdWEgPSB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDsKCiAgICAgICAgICAgIC8vIElFIDEwCiAgICAgICAgICAgIC8vIHVhID0gJ01vemlsbGEvNS4wIChjb21wYXRpYmxlOyBNU0lFIDEwLjA7IFdpbmRvd3MgTlQgNi4yOyBUcmlkZW50LzYuMCknOwoKICAgICAgICAgICAgLy8gSUUgMTEKICAgICAgICAgICAgLy8gdWEgPSAnTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgNi4zOyBUcmlkZW50LzcuMDsgcnY6MTEuMCkgbGlrZSBHZWNrbyc7CgogICAgICAgICAgICAvLyBJRSAxMiAvIFNwYXJ0YW4KICAgICAgICAgICAgLy8gdWEgPSAnTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV09XNjQpIEFwcGxlV2ViS2l0LzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZS8zOS4wLjIxNzEuNzEgU2FmYXJpLzUzNy4zNiBFZGdlLzEyLjAnOwoKICAgICAgICAgICAgLy8gRWRnZSAoSUUgMTIrKQogICAgICAgICAgICAvLyB1YSA9ICdNb3ppbGxhLzUuMCAoV2luZG93cyBOVCAxMC4wOyBXaW42NDsgeDY0KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvNDYuMC4yNDg2LjAgU2FmYXJpLzUzNy4zNiBFZGdlLzEzLjEwNTg2JzsKCiAgICAgICAgICAgIHZhciBtc2llID0gdWEuaW5kZXhPZignTVNJRSAnKTsKICAgICAgICAgICAgaWYgKG1zaWUgPiAwKSB7CiAgICAgICAgICAgICAgICAvLyBJRSAxMCBvciBvbGRlciA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXIKICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh1YS5zdWJzdHJpbmcobXNpZSArIDUsIHVhLmluZGV4T2YoJy4nLCBtc2llKSksIDEwKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHRyaWRlbnQgPSB1YS5pbmRleE9mKCdUcmlkZW50LycpOwogICAgICAgICAgICBpZiAodHJpZGVudCA+IDApIHsKICAgICAgICAgICAgICAgIC8vIElFIDExID0+IHJldHVybiB2ZXJzaW9uIG51bWJlcgogICAgICAgICAgICAgICAgdmFyIHJ2ID0gdWEuaW5kZXhPZigncnY6Jyk7CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodWEuc3Vic3RyaW5nKHJ2ICsgMywgdWEuaW5kZXhPZignLicsIHJ2KSksIDEwKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGVkZ2UgPSB1YS5pbmRleE9mKCdFZGdlLycpOwogICAgICAgICAgICBpZiAoZWRnZSA+IDApIHsKICAgICAgICAgICAgICAgIC8vIEVkZ2UgKElFIDEyKykgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyCiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodWEuc3Vic3RyaW5nKGVkZ2UgKyA1LCB1YS5pbmRleE9mKCcuJywgZWRnZSkpLCAxMCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIG90aGVyIGJyb3dzZXIKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCiAgICAgICAgLyoqCiAgICAgICAgICogcmV0dXJucyB0cnVlIGlmIHRoZSBicm93c2VyIGlzIGNocm9tZSBvdGhlcndpc2UgZmFsc2UKICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0KICAgICAgICAgKi8KICAgICAgICBkZXRlY3RDaHJvbWUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAoISF3aW5kb3cuY2hyb21lIHx8ICEhJC5icm93c2VyLmNocm9tZSB8fCAvY2hyb20oZXxpdW0pLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKSkpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHZhbDogdmFsdWUgdG8gYmUgdmVyaWZpZWQKICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufQogICAgICAgICogcmV0dXJucyB0cnVlIGlmIHRoZSBwcm92aWRlZCBzdHJpbmcgY29udGFpbnMgRE9NIGVsZW1lbnQKICAgICAgICAqLwogICAgICAgIGlzSFRNTDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIC8vY2hlY2sgd2hldGhlciBzdHJpbmcgY29udGFpbnMgdGFncywgc28gdGhhdCAkdmFsIGRvZXMgbm90IGNvbnRhaW4gcmVzdWx0IG9mIHRoZSB2YWwgdXNlZCBhcyBzZWxlY3RvcgogICAgICAgICAgICAvLyBlZzogdmFsID0gImEiIHdpbGwgcmV0dXJuIHJlc3VsdCBmb3IgJCh2YWwpIHdoaWNoIGlzIG5vdCByZXF1aXJlZAogICAgICAgICAgICBpZih2YWwgJiYgLzxbYS16XVtcc1xTXSo+Ly50ZXN0KHZhbCkpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgdmFyICR2YWwgPSAkKHZhbCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWwubGVuZ3RoID4gMDsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgIC8vIGlmIGpxdWVyeSB0aHJvd3MgZXhjZXB0aW9uIHRoYXQgbWVhbnMgc3RyaW5nIGlzIG5vdCBhIHByb3BlciBIVE1MCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogcmV0dXJucyB0cnVlIGlmIHBhc3NlZCBrZXkgaXMgbm9uIHByaW50YWJsZSwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgZXZlbnQua2V5IHByb3BlcnR5IG9mIGEgS2V5Ym9hcmQgZXZlbnQKICAgICAgICAgKi8KICAgICAgICBpc05vblByaW50YWJsZUtleSA6IGZ1bmN0aW9uIChrZXkpIHsKICAgICAgICAgICAgcmV0dXJuIChrZXkgICAvLyBJbiBJRSwgZXZlbnQua2V5IHJldHVybnMgd29yZHMgaW5zdGVhZCBvZiBhY3R1YWwgY2hhcmFjdGVycyBmb3Igc29tZSBrZXlzLgogICAgICAgICAgICAgICAmJiAhXy5jb250YWlucyhbJ01velByaW50YWJsZUtleScsJ0RpdmlkZScsJ011bHRpcGx5JywnU3VidHJhY3QnLCdBZGQnLCdFbnRlcicsJ0RlY2ltYWwnLCdTcGFjZWJhcicsJ0RlbCddLGtleSkKICAgICAgICAgICAgICAgJiYga2V5Lmxlbmd0aCAhPSAxICkKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAqIHJldHVybnMgdHJ1ZSBmb3IgaXBhZAogICAgICAgICogQHJldHVybnMge2Jvb2xlYW59CiAgICAgICAgKi8KICAgICAgICBfaXNJcGFkIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBhZC9pKSAhPSBudWxsOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICogcmV0dXJucyB0cnVlIGlmIHRoZSBzdWJmb3JtIGlzIHRhYmxlIG9yIGhhdmluZyByb2xlIHRhYmxlIGVsc2UgZmFsc2UKICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSB2aWV3CiAgICAgICAgKi8KICAgICAgICBfdGFibGVDaGVja0ZvckFjY2Vzc2liaWxpdHkgOiBmdW5jdGlvbiAodmlldykgewogICAgICAgICAgICB2YXIgYXNzaXN0ID0gdmlldy5tb2RlbC5nZXRFbGVtZW50KCJhc3Npc3QiLCAwLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JFbHNlKHZpZXcsICJsYXlvdXRNb2RlbC5sYXlvdXQiLCBudWxsKSA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfVEFCTEUKICAgICAgICAgICAgICAgIHx8IHRoaXMuZ2V0T3JFbHNlKGFzc2lzdCwgInJvbGUiLCBudWxsKSA9PSAiVGFibGUiOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICogcmV0dXJucyB2YWx1ZSBvZiB0b29sdGlwIHRvIGJlIGFzc2lnbmVkIGFzIHRpdGxlIGJhc2VkIG9uIHZhbHVlcyBwcm92aWRlZCBpbiBhY2Nlc3NpYmlsaXR5CiAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gbW9kZWwKICAgICAgICAqIEByZXR1cm5zIHRvb2xUaXBUZXh0CiAgICAgICAgKi8KICAgICAgICBfZ2V0VG9vbFRpcFRleHQgOiBmdW5jdGlvbiAobW9kZWwpIHsKICAgICAgICAgICAgdmFyIGFzc2lzdCA9IG1vZGVsLmdldEVsZW1lbnQoImFzc2lzdCIsIDAsIHRydWUpLAogICAgICAgICAgICAgICAgdG9vbFRpcFRleHQgPSAiIjsKICAgICAgICAgICAgLy8gZ29pbmcgYWdhaW5zdCB4ZmEgc3BlYywgb24gaG92ZXIgc2hvdyB0b29sdGlwIG9yIHNwZWFrIHRleHQgb3IgZWxlbWVudCBuYW1lLCBkb24ndCBzaG93IGNhcHRpb24gYXMgaXQncyBhbHJlYWR5IHZpc2libGUKICAgICAgICAgICAgLy8gYXNzaXN0IHByaW9yaXR5IGRvZXNuJ3QgbWF0dGVyLCBidXQgc2VsZWN0aW5nIG5vbmUgd2lsbCBkaXNhYmxlIHRvb2x0aXAgb24gaG92ZXIKICAgICAgICAgICAgaWYgKHRoaXMuZ2V0T3JFbHNlKGFzc2lzdCwgInNwZWFrLmRpc2FibGUiLCAwKSAhPSAxKSB7IC8vIGxvb3NlIGNvbXBhcmUgc3RyaW5nIHZhbHVlCiAgICAgICAgICAgICAgICB0b29sVGlwVGV4dCA9IHRoaXMuZ2V0T3JFbHNlKGFzc2lzdCwgInRvb2xUaXAudmFsdWUiLCAiIikgfHwKICAgICAgICAgICAgICAgICAgICB0aGlzLmdldE9yRWxzZShhc3Npc3QsICJzcGVhay52YWx1ZSIsICIiKSAgIHx8CiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRPckVsc2UobW9kZWwsICJqc29uTW9kZWwubmFtZSIsICIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdG9vbFRpcFRleHQ7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgKiByZXR1cm5zIHZhbHVlIG9mIG1hbmRhdG9yeSBtZXNzYWdlCiAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gbW9kZWwKICAgICAgICAqIEByZXR1cm5zIG1hbmRhdG9yeU1lc3NhZ2UKICAgICAgICAqLwogICAgICAgIF9nZXRNYW5kYXRvcnlNZXNzYWdlIDogZnVuY3Rpb24gKG1vZGVsKSB7CiAgICAgICAgICAgIHZhciBkZWZhdWx0TWVzc2FnZSA9IG1vZGVsLl9kZWZhdWx0cy52YWxpZGF0ZS5tZXNzYWdlLmRlZmF1bHRNZXNzYWdlLAogICAgICAgICAgICAgICAgbXNnID0gdGhpcy5nZXRPckVsc2UobW9kZWwsICJ2YWxpZGF0ZS5tZXNzYWdlLm51bGxUZXN0IiwgZGVmYXVsdE1lc3NhZ2UpOwogICAgICAgICAgICByZXR1cm4gKG1zZyAmJiBtc2cudmFsdWUpID8gbXNnLnZhbHVlIDogZGVmYXVsdE1lc3NhZ2UudmFsdWU7CiAgICAgICAgfSwKICAgICAgICAvKioKICAgICAgICAqIHJldHVybnMgYm9vbGVhbiBiYXNlZCBvbiB2YWwxLCB2YWwyLCBjaGVja0VxdWFsCiAgICAgICAgKiBGb3IgY29tcGFyaW5nIGRhdGUsIHVzZSBkYXRlIG9iamVjdAogICAgICAgICovCiAgICAgICAgX2NvbXBhcmVWYWwgOiBmdW5jdGlvbiAodmFsMSwgdmFsMiwgY2hlY2tFcXVhbCkgewogICAgICAgICAgICBpZighdmFsMSB8fCAhdmFsMikgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihjaGVja0VxdWFsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdmFsMSA+PSB2YWwyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHZhbDEgPiB2YWwyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgLy9TcGVjaWFsIGhhbmRsaW5nIGZvciBJRS4KICAgIGlmICgkLmJyb3dzZXIubXNpZSB8fCAkLmJyb3dzZXIubW96aWxsYSkgewogICAgICAgIFhmYVV0aWwucHJvdG90eXBlLiRjc3MgPSBmdW5jdGlvbiAoZWxlbSwgc3R5bGVzT2JqKSB7CiAgICAgICAgICAgICQoZWxlbSkuY3NzKHN0eWxlc09iaik7CiAgICAgICAgfQogICAgfQp9KShfLCAkLCB4ZmFsaWIpOwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogX19fX19fX19fX19fX19fX19fXwogKgogKiAgQ29weXJpZ2h0IDIwMTMgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKKGZ1bmN0aW9uIChfLCAkLCB4ZmFsaWIpIHsKICAgIHhmYWxpYi51dC5VdGlsaXRpZXMgPSB7CgogICAgICAgIGlzSUUxMTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gISFuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9UcmlkZW50Lipydlw6MTFcLi8pOwogICAgICAgIH0sCgogICAgICAgIGNoZWNrTWluTW96aWxsYVZlcnNpb246IGZ1bmN0aW9uICh2ZXJzaW9uKSB7CiAgICAgICAgICAgIHJldHVybiAoIXRoaXMuaXNJRTExKCkgJiYgJC5icm93c2VyLm1vemlsbGEgJiYgcGFyc2VJbnQoJC5icm93c2VyLnZlcnNpb24pID49IHZlcnNpb24pOwogICAgICAgIH0sCgogICAgICAgIGdldE9iamVjdEZyb21LZXlWYWx1ZVN0cmluZ0xpc3Q6IGZ1bmN0aW9uIChsaXN0KSB7CiAgICAgICAgICAgIHZhciBrZXksIHZhbHVlLCBvYmplY3QgPSB7fSwgdGVtcEFycmF5OwogICAgICAgICAgICBfLmVhY2gobGlzdCwgZnVuY3Rpb24gKGtleVZhbHVlUGFpciwgaW5kZXgpIHsKICAgICAgICAgICAgICAgIHRlbXBBcnJheSA9IGtleVZhbHVlUGFpci5zcGxpdCgiPSIpOwogICAgICAgICAgICAgICAgaWYgKHRlbXBBcnJheSAmJiB0ZW1wQXJyYXkubGVuZ3RoID4gMSkgewogICAgICAgICAgICAgICAgICAgIG9iamVjdFt0ZW1wQXJyYXlbMF1dID0gdGVtcEFycmF5WzFdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgcmV0dXJuIG9iamVjdDsKICAgICAgICB9LAoKICAgICAgICBfZ2V0TmFtZVdpdGhvdXRNYXJrZXI6IGZ1bmN0aW9uIChmaWxlTmFtZSkgewogICAgICAgICAgICB2YXIgbWFya2VySW5kZXggPSBmaWxlTmFtZS5pbmRleE9mKCJfX2FmQXR0YWNobWVudF9fIik7CiAgICAgICAgICAgIGlmIChtYXJrZXJJbmRleCAhPT0gLTEpIHsKICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gZmlsZU5hbWUuc3Vic3RyaW5nKG1hcmtlckluZGV4ICsgIl9fYWZBdHRhY2htZW50X18iLmxlbmd0aCwgZmlsZU5hbWUubGVuZ3RoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmlsZU5hbWU7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBUaGlzIGlzIHRvIGNoZWNrIHN1cHBvcnQgb2YgbXVsdGlwbGUgZmlsZXMgc2VsZWN0aW9uIGluIG9uZSBhZGQgbmV3IGRpYWxvZwogICAgICAgICAqLwogICAgICAgIF9pc0RhdGFDb250YWluZXJTdXBwb3J0ZWQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB2YXIgZGF0YUNvbnRhaW5lciA9IG5ldyBEYXRhVHJhbnNmZXIoKSB8fCAobmV3IENsaXBib2FyZEV2ZW50KCIiKSkuY2xpcGJvYXJkRGF0YTsKICAgICAgICAgICAgICAgIGlmIChkYXRhQ29udGFpbmVyICYmIGRhdGFDb250YWluZXIuaXRlbXMpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaChlcnIpIHsKICAgICAgICAgICAgICAgIC8vIGlmIGVyciBjb21lcyB0aGVuIGRhdGFDb250YWluZXIgaXMgbm90IHN1cHBvcnRlZAogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Owp9KShfLCAkLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlNjYW5uZXIKICogQGZpbGVPdmVydmlldyBoZWxwZXIgY2xhc3MgdG8gc2NhbiBvdmVyIGEgc3RyaW5nLgogKiBAdmVyc2lvbiAwLjAuMQogKi8KCi8qKgogKiBAY29uc3RydWN0b3IKICogQHBhcmFtIE9iamVjdCB7anNvbk1vZGVsOntfc3RyOiBTdHJpbmd9fQogKi8KCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgU2Nhbm5lciA9IHhmYWxpYi51dC5TY2FubmVyID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB0aGlzLl9wb3MgPSAwOwogICAgICAgIH0sCgogICAgICAgIGlzRU9GIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuICh0aGlzLmpzb25Nb2RlbC5fc3RyLmxlbmd0aCA8PSB0aGlzLl9wb3MpOwogICAgICAgIH0sCgogICAgICAgIHBlZWsgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gKHRoaXMuaXNFT0YoKSkgPyBudWxsIDogdGhpcy5qc29uTW9kZWwuX3N0ci5jaGFyQXQodGhpcy5fcG9zKTsKICAgICAgICB9LAoKICAgICAgICBvcHRpb25hbENvbnN1bWVDaGFyIDogZnVuY3Rpb24oYUNoYXIpewogICAgICAgICAgICBpZih0aGlzLmpzb25Nb2RlbC5fc3RyLmNoYXJBdCh0aGlzLl9wb3MpID09IGFDaGFyKXsKICAgICAgICAgICAgICAgIHRoaXMuX3BvcysrOwogICAgICAgICAgICAgICAgcmV0dXJuIGFDaGFyOwogICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0cyBuZXh0IGNoYXIgaWdub3JlIHF1b3RlZCBzdHJpbmcuCiAgICAgICAgICogICAgfAogICAgICAgICAqICAgYWJjIHJldHVybnMgYy4KICAgICAgICAgKiAgICAgfAogICAgICAgICAqICAgYWJjJ2RlJ2YgcmV0dXJucyBmLgogICAgICAgICAqIEBwYXJhbSBhQ2hhcgogICAgICAgICAqLwogICAgICAgIGdldE5DaGFySVFTIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdGhpcy5fcG9zKys7CiAgICAgICAgICAgIGlmKHRoaXMuanNvbk1vZGVsLl9zdHIubGVuZ3RoIDw9IHRoaXMuX3Bvcyl7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudCA9IHRoaXMuanNvbk1vZGVsLl9zdHIuY2hhckF0KHRoaXMuX3Bvcyk7CiAgICAgICAgICAgICAgICBpZihjdXJyZW50ICE9ICdcJycpewogICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OwogICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgaWYobW92ZU5leHRFeHBlY3RlZENoYXIoJ1wnJykpewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwuX3N0ci5jaGFyQXQodGhpcy5fcG9zKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgbW92ZU5leHRFeHBlY3RlZENoYXIgOiBmdW5jdGlvbihhQ2hhcil7CiAgICAgICAgICAgIHRoaXMuX3BvcysrOy8vIGN1cnJlbnRseSBwb2ludCB0byAnCiAgICAgICAgICAgIHdoaWxlKHRoaXMuX3BvczwgdGhpcy5qc29uTW9kZWwuX3N0ci5sZW5ndGggJiYgdGhpcy5qc29uTW9kZWwuX3N0ci5jaGFyQXQodGhpcy5fcG9zKSAhPSBhQ2hhcil7CiAgICAgICAgICAgICAgICB0aGlzLl9wb3MrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdGhpcy5fcG9zIDwgdGhpcy5qc29uTW9kZWwuX3N0ci5sZW5ndGg7CiAgICAgICAgfSwKCiAgICAgICAgcmVhZEludGVnZXIgOiBmdW5jdGlvbihsZW4pewogICAgICAgICAgICBpZih0aGlzLnBvcytsZW4gPnRoaXMuanNvbk1vZGVsLl9zdHIubGVuZ3RoKXsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBpbnRlZ2VyID0geGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYXJzZUludEV4YWN0KHRoaXMuanNvbk1vZGVsLl9zdHIsdGhpcy5fcG9zLGxlbik7CiAgICAgICAgICAgIHRoaXMuX3Bvcys9bGVuOwogICAgICAgICAgICByZXR1cm4gaW50ZWdlcjsKICAgICAgICB9CiAgICB9KTsKCiAgICBTY2FubmVyLmxvb2t1cE5leHQgPSBmdW5jdGlvbihwYXQsIHBhdFBvcywgZmlsdGVyKXsKICAgICAgICB2YXIgcGF0TGVuID0gcGF0Lmxlbmd0aDsKICAgICAgICBpZihwYXRQb3MgPj0gcGF0TGVuKXsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICB2YXIgdG9rZW4gPSB7fTsKICAgICAgICB0b2tlbi5zdGFydFBvcyA9IHBhdFBvczsKCiAgICAgICAgdmFyIGZpcnN0Q2hhciA9IHBhdC5jaGFyQXQocGF0UG9zKTsKICAgICAgICB2YXIgcGF0VmFsaWQgPSBmYWxzZTsKICAgICAgICAvLwogICAgICAgIGlmIChmaXJzdENoYXIgPT0gJ1wnJyl7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSBwYXRQb3MrMTsgaSA8IHBhdExlbjtpKysgKXsKICAgICAgICAgICAgICAgIHZhciBjaHIgPSBwYXQuY2hhckF0KGkpOwogICAgICAgICAgICAgICAgaWYoY2hyID09J1wnJyl7CiAgICAgICAgICAgICAgICAgICAgdG9rZW4udHlwZT0xOwogICAgICAgICAgICAgICAgICAgIHRva2VuLmxlbiA9IGkgLSBwYXRQb3MgKyAxOwogICAgICAgICAgICAgICAgICAgIHBhdFZhbGlkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICB9ZWxzZSBpZiggKCdhJyA8PSBmaXJzdENoYXIgJiYgZmlyc3RDaGFyIDw9ICd6JyB8fCAnQScgPD0gZmlyc3RDaGFyICYmIGZpcnN0Q2hhciA8PSAnWicpIHx8IGZpbHRlci5jYWxsKG51bGwsIGZpcnN0Q2hhcikpewogICAgICAgICAgICB2YXIgZW5kUG9zID0gcGF0TGVuOy8vZW5kIGlzIGV4Y2x1c2l2ZQogICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgcGF0UG9zK2kgPCBwYXRMZW47aSsrICl7CiAgICAgICAgICAgICAgICBpZihwYXQuY2hhckF0KHBhdFBvcytpKSE9Zmlyc3RDaGFyKXsKICAgICAgICAgICAgICAgICAgICBlbmRQb3MgPSBwYXRQb3MraTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0b2tlbi50eXBlPTI7CiAgICAgICAgICAgIHRva2VuLmxlbiA9IGVuZFBvcyAtIHBhdFBvczsKICAgICAgICAgICAgdG9rZW4ucGF0Q2hhciA9IGZpcnN0Q2hhcjsKICAgICAgICAgICAgdG9rZW4ucGF0UG9zID0gcGF0UG9zOwogICAgICAgICAgICBwYXRWYWxpZCA9IHRydWU7CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIGlmIChmaXJzdENoYXIgPT0gJz8nIHx8IGZpcnN0Q2hhciA9PSAnKycgfHwgZmlyc3RDaGFyID09ICcqJykgewogICAgICAgICAgICAgICAgdG9rZW4udHlwZT0zOwogICAgICAgICAgICAgICAgdG9rZW4ubGVuID0gMTsKICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICB0b2tlbi50eXBlPTQ7CiAgICAgICAgICAgICAgICB0b2tlbi5sZW4gPSAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHBhdFZhbGlkID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYocGF0VmFsaWQpewogICAgICAgICAgICByZXR1cm4gdG9rZW47CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIHRocm93ICJQaWN0dXJlIGlzIGludmFsaWQuIjsKICAgICAgICB9CiAgICB9Cn0pKF8seGZhbGliKTsKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlBpY3R1cmVGbXQKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBkZWZpbmVzIG1ldGhvZHMgdG8gcGFyc2UgYW5kIGZvcm1hdCBkYXRhCiAqIGFjY29yZGluZyB0byBYRkEgcGljdHVyZSBwYXR0ZXJucy4KICogQHZlcnNpb24gMC4wLjEKICovCihmdW5jdGlvbihfLHhmYWxpYikgewoKICAgIHZhciBQaWN0dXJlRm10ID0geGZhbGliLnV0LlBpY3R1cmVGbXQgPSBmdW5jdGlvbigpIHt9OwogICAgUGljdHVyZUZtdC5EYXRlUGljdHVyZVBhdHRlcm4gPSAgL15kYXRlKD86XChbYS16QS1aXSpfW2EtekEtWl0qXCkpP1x7KFtcd1xXXSo/KVx9JC87CiAgICBQaWN0dXJlRm10LlRpbWVQaWN0dXJlUGF0dGVybiA9ICAvXnRpbWUoPzpcKFthLXpBLVpdKl9bYS16QS1aXSpcKSk/XHsoW1x3XFddKj8pXH0kLzsKICAgIFBpY3R1cmVGbXQuVGV4dFBpY3R1cmVQYXR0ZXJuID0gIC9edGV4dFx7KFtcd1xXXSo/KVx9JC87CiAgICBQaWN0dXJlRm10Lk51bVBpY3R1cmVQYXR0ZXJuID0gIC9ebnVtXHsoW1x3XFddKj8pXH0kLzsKCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGdpdmVuIGRhdGEgc291cmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gcGljdHVyZS4KICAgICAqIEBwYXJhbSBzU291cmNlIHtzdHJpbmd9CiAgICAgKiBAcGFyYW0gc1BpY3R1cmUge3N0cmluZ30KICAgICAqIEBwYXJhbSBzTG9jYWxlIHtzdHJpbmd9CiAgICAgKiBAcmV0dXJucyB7b2JqZWN0fQogICAgICovCiAgICBQaWN0dXJlRm10LnBhcnNlICA9IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLHNMb2NhbGUpewogICAgICAgIHZhciBQaWN0dXJlRW5naW5lID0gbmV3IHhmYWxpYi51dC5QaWN0dXJlRW5naW5lKHtqc29uTW9kZWw6e2xvY2FsZTpzTG9jYWxlfX0pOwoKICAgICAgICB2YXIgbWF0Y2ggPSBQaWN0dXJlRm10LkRhdGVQaWN0dXJlUGF0dGVybi5leGVjKHNQaWN0dXJlKTsKICAgICAgICBpZihtYXRjaCAmJiBtYXRjaFsxXSl7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLnBhcnNlRGF0ZShzU291cmNlLCBtYXRjaFsxXSk7CiAgICAgICAgfQogICAgICAgIG1hdGNoID0gUGljdHVyZUZtdC5UaW1lUGljdHVyZVBhdHRlcm4uZXhlYyhzUGljdHVyZSk7CiAgICAgICAgaWYobWF0Y2ggJiYgbWF0Y2hbMV0pewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5wYXJzZVRpbWUoc1NvdXJjZSwgbWF0Y2hbMV0pOwogICAgICAgIH0KICAgICAgICBtYXRjaCA9IFBpY3R1cmVGbXQuVGV4dFBpY3R1cmVQYXR0ZXJuLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUucGFyc2VUZXh0KHNTb3VyY2UsIG1hdGNoWzFdKTsKICAgICAgICB9CiAgICAgICAgbWF0Y2ggPSBQaWN0dXJlRm10Lk51bVBpY3R1cmVQYXR0ZXJuLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUucGFyc2VOdW1lcmljKHNTb3VyY2UsIG1hdGNoWzFdKTsKICAgICAgICB9CiAgICAgICAgdGhyb3cgIkludmFsaWQgcGljdHVyZSBjbGF1c2UgIitzUGljdHVyZTsKICAgIH07CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgZ2l2ZW4gZGF0YSBzb3VyY2UgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBwaWN0dXJlLgogICAgICogQHBhcmFtIGRhdGUge29iamVjdH0KICAgICAqIEBwYXJhbSBzUGljdHVyZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNMb2NhbGUge3N0cmluZ30KICAgICAqIEByZXR1cm5zIHtzdHJpbmd9CiAgICAgKi8KICAgIFBpY3R1cmVGbXQuZm9ybWF0ICA9IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLCBzTG9jYWxlLGJSZWxheGVkLGJGb3JtYXROdW1iZXJGcm9tYXNEZWZhdWx0UEMpewogICAgICAgIHZhciBQaWN0dXJlRW5naW5lID0gbmV3IHhmYWxpYi51dC5QaWN0dXJlRW5naW5lKHtqc29uTW9kZWw6e2xvY2FsZTpzTG9jYWxlfX0pOwoKICAgICAgICB2YXIgbWF0Y2ggPSBQaWN0dXJlRm10LkRhdGVQaWN0dXJlUGF0dGVybi5leGVjKHNQaWN0dXJlKTsKICAgICAgICBpZihtYXRjaCAmJiBtYXRjaFsxXSl7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLmZvcm1hdERhdGUoc1NvdXJjZSwgbWF0Y2hbMV0pOwogICAgICAgIH0KICAgICAgICBtYXRjaCA9IFBpY3R1cmVGbXQuVGltZVBpY3R1cmVQYXR0ZXJuLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUuZm9ybWF0VGltZShzU291cmNlLCBtYXRjaFsxXSk7CiAgICAgICAgfQogICAgICAgIG1hdGNoID0gUGljdHVyZUZtdC5UZXh0UGljdHVyZVBhdHRlcm4uZXhlYyhzUGljdHVyZSk7CiAgICAgICAgaWYobWF0Y2ggJiYgbWF0Y2hbMV0pewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5mb3JtYXRUZXh0KHNTb3VyY2UsIG1hdGNoWzFdLGJSZWxheGVkKTsKICAgICAgICB9CiAgICAgICAgbWF0Y2ggPSBQaWN0dXJlRm10Lk51bVBpY3R1cmVQYXR0ZXJuLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUuZm9ybWF0TnVtZXJpYyhzU291cmNlLCBtYXRjaFsxXSxzTG9jYWxlLGJSZWxheGVkLGJGb3JtYXROdW1iZXJGcm9tYXNEZWZhdWx0UEMpOwogICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgIkludmFsaWQgcGljdHVyZSBjbGF1c2UgIitzUGljdHVyZTsKICAgIH07CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgYSBnaXZlbiBkYXRhIHNvdXJjZSBpcyBmb3JtYXR0ZWQgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBwaWN0dXJlLgogICAgICogQHBhcmFtIGRhdGUge29iamVjdH0KICAgICAqIEBwYXJhbSBzUGljdHVyZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNMb2NhbGUge3N0cmluZ30KICAgICAqIEByZXR1cm5zIHtib29sZWFufQogICAgICovCiAgICBQaWN0dXJlRm10LmZvcm1hdFRlc3QgPSBmdW5jdGlvbiAoc1NvdXJjZSwgc1BpY3R1cmUsIHNMb2NhbGUsIGJSZWxheGVkLCBiRm9ybWF0TnVtYmVyRnJvbWFzRGVmYXVsdFBDKSB7CiAgICAgICAgdmFyIGZvcm1hdHRlZERhdGE7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgZm9ybWF0dGVkRGF0YSA9IFBpY3R1cmVGbXQuZm9ybWF0KHNTb3VyY2UsIHNQaWN0dXJlLCBzTG9jYWxlLCBiUmVsYXhlZCwgYkZvcm1hdE51bWJlckZyb21hc0RlZmF1bHRQQyk7CiAgICAgICAgfWNhdGNoKGUpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYoIV8uaXNTdHJpbmcoZm9ybWF0dGVkRGF0YSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZhciBwYXJzZWREYXRhOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcGFyc2VkRGF0YSA9IFBpY3R1cmVGbXQucGFyc2UoZm9ybWF0dGVkRGF0YSwgc1BpY3R1cmUsIHNMb2NhbGUpOwogICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoIV8uaXNTdHJpbmcocGFyc2VkRGF0YSkgJiYgcGFyc2VkRGF0YSAhPT0gZm9ybWF0dGVkRGF0YSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfTsKCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGdpdmVuIGRhdGEgc291cmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gZGF0ZSBwaWN0dXJlCiAgICAgKiB1bmRlciB0aGUgZ2l2ZW4gc0xvY2FsZS4KICAgICAqIEBwYXJhbSBzU291cmNlIHtzdHJpbmd9CiAgICAgKiBAcGFyYW0gc1BpY3R1cmUge3N0cmluZ30KICAgICAqIEBwYXJhbSBzTG9jYWxlIHtzdHJpbmd9CiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfQogICAgICovCiAgICBQaWN0dXJlRm10LnBhcnNlRGF0ZSAgPSBmdW5jdGlvbihzU291cmNlLCBzUGljdHVyZSxzTG9jYWxlKXsKICAgICAgICB2YXIgcGljUmVnZXhwID0gUGljdHVyZUZtdC5EYXRlUGljdHVyZVBhdHRlcm47CiAgICAgICAgdmFyIG1hdGNoID0gcGljUmVnZXhwLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIHZhciBQaWN0dXJlRW5naW5lID0gbmV3IHhmYWxpYi51dC5QaWN0dXJlRW5naW5lKHtqc29uTW9kZWw6e2xvY2FsZTpzTG9jYWxlfX0pOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUucGFyc2VEYXRlKHNTb3VyY2UsIG1hdGNoWzFdKTsKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUucGFyc2VEYXRlKHNTb3VyY2UsIHNQaWN0dXJlKTsKICAgICAgICB9CiAgICB9OwoKCiAgICAvKioKICAgICAqIEZvcm1hdHMgYSBnaXZlbiBkYXRhIHNvdXJjZSBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIGRhdGUgcGljdHVyZQogICAgICogKiB1bmRlciB0aGUgZ2l2ZW4gc0xvY2FsZS4KICAgICAqIEBwYXJhbSBkYXRlIHtzdHJpbmd9CiAgICAgKiBAcGFyYW0gc1BpY3R1cmUge3N0cmluZ30KICAgICAqIEBwYXJhbSBzTG9jYWxlIHtzdHJpbmd9CiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfQogICAgICovCiAgICBQaWN0dXJlRm10LmZvcm1hdERhdGUgID0gZnVuY3Rpb24oZGF0ZSwgc1BpY3R1cmUsIHNMb2NhbGUpewogICAgICAgIHZhciBwaWNSZWdleHAgPSAgUGljdHVyZUZtdC5EYXRlUGljdHVyZVBhdHRlcm47CiAgICAgICAgdmFyIG1hdGNoID0gcGljUmVnZXhwLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIHZhciBQaWN0dXJlRW5naW5lID0gbmV3IHhmYWxpYi51dC5QaWN0dXJlRW5naW5lKHtqc29uTW9kZWw6e2xvY2FsZTpzTG9jYWxlfX0pOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUuZm9ybWF0RGF0ZShkYXRlLCBtYXRjaFsxXSk7CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLmZvcm1hdERhdGUoZGF0ZSwgc1BpY3R1cmUpOwogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBnaXZlbiBkYXRhIHNvdXJjZSBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIGRhdGUgcGljdHVyZQogICAgICogdW5kZXIgdGhlIGdpdmVuIHNMb2NhbGUuCiAgICAgKiBAcGFyYW0gc1NvdXJjZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNQaWN0dXJlIHtzdHJpbmd9CiAgICAgKiBAcGFyYW0gc0xvY2FsZSB7c3RyaW5nfQogICAgICogQHJldHVybnMge2RhdGV9CiAgICAgKi8KICAgIFBpY3R1cmVGbXQucGFyc2VUaW1lICA9IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLHNMb2NhbGUpewogICAgICAgIHZhciBwaWNSZWdleHAgPSBQaWN0dXJlRm10LlRpbWVQaWN0dXJlUGF0dGVybjsKICAgICAgICB2YXIgbWF0Y2ggPSBwaWNSZWdleHAuZXhlYyhzUGljdHVyZSk7CiAgICAgICAgdmFyIFBpY3R1cmVFbmdpbmUgPSBuZXcgeGZhbGliLnV0LlBpY3R1cmVFbmdpbmUoe2pzb25Nb2RlbDp7bG9jYWxlOnNMb2NhbGV9fSk7CiAgICAgICAgaWYobWF0Y2ggJiYgbWF0Y2hbMV0pewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5wYXJzZVRpbWUoc1NvdXJjZSwgbWF0Y2hbMV0pOwogICAgICAgIH1lbHNlewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5wYXJzZVRpbWUoc1NvdXJjZSwgc1BpY3R1cmUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH07CgoKICAgIC8qKgogICAgICogRm9ybWF0cyBhIGdpdmVuIGRhdGEgc291cmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gZGF0ZSBwaWN0dXJlCiAgICAgKiAqIHVuZGVyIHRoZSBnaXZlbiBzTG9jYWxlLgogICAgICogQHBhcmFtIGRhdGUge3N0cmluZ30KICAgICAqIEBwYXJhbSBzUGljdHVyZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNMb2NhbGUge3N0cmluZ30KICAgICAqIEByZXR1cm5zIHtzdHJpbmd9CiAgICAgKi8KICAgIFBpY3R1cmVGbXQuZm9ybWF0VGltZSAgPSBmdW5jdGlvbihkYXRlLCBzUGljdHVyZSwgc0xvY2FsZSl7CiAgICAgICAgdmFyIHBpY1JlZ2V4cCA9ICBQaWN0dXJlRm10LlRpbWVQaWN0dXJlUGF0dGVybjsKICAgICAgICB2YXIgbWF0Y2ggPSBwaWNSZWdleHAuZXhlYyhzUGljdHVyZSk7CiAgICAgICAgdmFyIFBpY3R1cmVFbmdpbmUgPSBuZXcgeGZhbGliLnV0LlBpY3R1cmVFbmdpbmUoe2pzb25Nb2RlbDp7bG9jYWxlOnNMb2NhbGV9fSk7CiAgICAgICAgaWYobWF0Y2ggJiYgbWF0Y2hbMV0pewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5mb3JtYXRUaW1lKGRhdGUsIG1hdGNoWzFdKTsKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUuZm9ybWF0VGltZShkYXRlLCBzUGljdHVyZSk7CiAgICAgICAgfQogICAgfTsKCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGdpdmVuIGRhdGEgc291cmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gdGV4dCBwaWN0dXJlCiAgICAgKiB1bmRlciB0aGUgZ2l2ZW4gc0xvY2FsZS4KICAgICAqIEBwYXJhbSBzU291cmNlIHtzdHJpbmd9CiAgICAgKiBAcGFyYW0gc1BpY3R1cmUge3N0cmluZ30KICAgICAqIEBwYXJhbSBzTG9jYWxlIHtzdHJpbmd9CiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfQogICAgICovCiAgICBQaWN0dXJlRm10LnBhcnNlVGV4dCAgPSBmdW5jdGlvbihzU291cmNlLCBzUGljdHVyZSxzTG9jYWxlKXsKICAgICAgICB2YXIgcGljUmVnZXhwID0gUGljdHVyZUZtdC5UZXh0UGljdHVyZVBhdHRlcm47CiAgICAgICAgdmFyIG1hdGNoID0gcGljUmVnZXhwLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIHZhciBQaWN0dXJlRW5naW5lID0gbmV3IHhmYWxpYi51dC5QaWN0dXJlRW5naW5lKHtqc29uTW9kZWw6e2xvY2FsZTpzTG9jYWxlfX0pOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUucGFyc2VUZXh0KHNTb3VyY2UsIG1hdGNoWzFdKTsKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUucGFyc2VUZXh0KHNTb3VyY2UsIHNQaWN0dXJlKTsKICAgICAgICB9CiAgICB9OwoKICAgIC8qKgogICAgICogRm9ybWF0cyBhIGdpdmVuIGRhdGEgc291cmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gdGV4dCBwaWN0dXJlCiAgICAgKiAgdW5kZXIgdGhlIGdpdmVuIHNMb2NhbGUuCiAgICAgKiBAcGFyYW0gc1NvdXJjZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNQaWN0dXJlIHtzdHJpbmd9CiAgICAgKiBAcGFyYW0gc0xvY2FsZSB7c3RyaW5nfQogICAgICogQHJldHVybnMge3N0cmluZ30KICAgICAqLwogICAgUGljdHVyZUZtdC5mb3JtYXRUZXh0ICA9IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLCBzTG9jYWxlLGJSZWxheGVkKXsKICAgICAgICB2YXIgcGljUmVnZXhwID0gIFBpY3R1cmVGbXQuVGV4dFBpY3R1cmVQYXR0ZXJuOwogICAgICAgIHZhciBtYXRjaCA9IHBpY1JlZ2V4cC5leGVjKHNQaWN0dXJlKTsKICAgICAgICB2YXIgUGljdHVyZUVuZ2luZSA9IG5ldyB4ZmFsaWIudXQuUGljdHVyZUVuZ2luZSh7anNvbk1vZGVsOntsb2NhbGU6c0xvY2FsZX19KTsKICAgICAgICBpZihtYXRjaCAmJiBtYXRjaFsxXSl7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLmZvcm1hdFRleHQoc1NvdXJjZSwgbWF0Y2hbMV0sYlJlbGF4ZWQpOwogICAgICAgIH1lbHNlewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5mb3JtYXRUZXh0KHNTb3VyY2UsIHNQaWN0dXJlLGJSZWxheGVkKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9OwoKICAgIC8qKgogICAgICogUGFyc2VzIGEgZ2l2ZW4gZGF0YSBzb3VyY2UgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBudW1lcmljIHBpY3R1cmUKICAgICAqIHVuZGVyIHRoZSBnaXZlbiBzTG9jYWxlLgogICAgICogQHBhcmFtIHNTb3VyY2Uge3N0cmluZ30KICAgICAqIEBwYXJhbSBzUGljdHVyZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNMb2NhbGUge3N0cmluZ30KICAgICAqIEByZXR1cm5zIHtzdHJpbmd9CiAgICAgKi8KICAgIFBpY3R1cmVGbXQucGFyc2VOdW1lcmljICA9IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLHNMb2NhbGUpewogICAgICAgIHZhciBwaWNSZWdleHAgPSBQaWN0dXJlRm10Lk51bVBpY3R1cmVQYXR0ZXJuOwogICAgICAgIHZhciBtYXRjaCA9IHBpY1JlZ2V4cC5leGVjKHNQaWN0dXJlKTsKICAgICAgICB2YXIgUGljdHVyZUVuZ2luZSA9IG5ldyB4ZmFsaWIudXQuUGljdHVyZUVuZ2luZSh7anNvbk1vZGVsOntsb2NhbGU6c0xvY2FsZX19KTsKICAgICAgICBpZihtYXRjaCAmJiBtYXRjaFsxXSl7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLnBhcnNlTnVtZXJpYyhzU291cmNlLCBtYXRjaFsxXSk7CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLnBhcnNlTnVtZXJpYyhzU291cmNlLCBzUGljdHVyZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfTsKCiAgICAvKioKICAgICAqIEZvcm1hdHMgYSBnaXZlbiBkYXRhIHNvdXJjZSBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIG51bWVyaWMgcGljdHVyZQogICAgICogIHVuZGVyIHRoZSBnaXZlbiBzTG9jYWxlLgogICAgICogQHBhcmFtIHNTb3VyY2Uge3N0cmluZ30KICAgICAqIEBwYXJhbSBzUGljdHVyZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNMb2NhbGUge3N0cmluZ30KICAgICAqIEByZXR1cm5zIHtzdHJpbmd9CiAgICAgKi8KICAgIFBpY3R1cmVGbXQuZm9ybWF0TnVtZXJpYyAgPSBmdW5jdGlvbihzU291cmNlLCBzUGljdHVyZSwgc0xvY2FsZSl7CiAgICAgICAgdmFyIHBpY1JlZ2V4cCA9ICBQaWN0dXJlRm10Lk51bVBpY3R1cmVQYXR0ZXJuOwogICAgICAgIHZhciBtYXRjaCA9IHBpY1JlZ2V4cC5leGVjKHNQaWN0dXJlKTsKICAgICAgICB2YXIgUGljdHVyZUVuZ2luZSA9IG5ldyB4ZmFsaWIudXQuUGljdHVyZUVuZ2luZSh7anNvbk1vZGVsOntsb2NhbGU6c0xvY2FsZX19KTsKICAgICAgICBpZihtYXRjaCAmJiBtYXRjaFsxXSl7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLmZvcm1hdE51bWVyaWMoc1NvdXJjZSwgbWF0Y2hbMV0pOwogICAgICAgIH1lbHNlewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5mb3JtYXROdW1lcmljKHNTb3VyY2UsIHNQaWN0dXJlKTsKICAgICAgICB9CiAgICB9OwoKCgoKICAgIC8qKgogICAgICogUGFyc2VzIGEgZ2l2ZW4gZGF0YSBzb3VyY2UgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBkYXRldGltZSBwaWN0dXJlCiAgICAgKiB1bmRlciB0aGUgZ2l2ZW4gc0xvY2FsZS4KICAgICAqIEBwYXJhbSBzU291cmNlIHtzdHJpbmd9CiAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgZGF0YS4KICAgICAqIEBwYXJhbSBzUGljdHVyZSB7c3RyaW5nfQogICAgICogICAgICAgICAgICB0aGUgZGF0ZXRpbWUgcGljdHVyZS4KICAgICAqIEBwYXJhbSBzRGF0ZU1hc2sge3N0cmluZ30KICAgICAqICAgICAgICAgICAgdGhlIGRhdGUgc3ViLXBpY3R1cmUuCiAgICAgKiBAcGFyYW0gc1RpbWVNYXNrIHtzdHJpbmd9CiAgICAgKiAgICAgICAgICAgIHRoZSB0aW1lIHN1Yi1waWN0dXJlLgogICAgICogQHBhcmFtIHNMb2NhbGUKICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsZSBuYW1lLgogICAgICoKICAgICAqLwogICAgUGljdHVyZUZtdC5wYXJzZURhdGVUaW1lICA9IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLCBzRGF0ZU1hc2ssIHNUaW1lTWFzaywgc0xvY2FsZSl7CgogICAgfTsKICAgIC8qKgogICAgICogRm9ybWF0cyBhIGdpdmVuIGRhdGEgc291cmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gZGF0ZXRpbWUgcGljdHVyZQogICAgICogdW5kZXIgdGhlIGdpdmVuIGxvY2FsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc1NvdXJjZSB7c3RyaW5nfQogICAgICogICAgICAgICAgICB0aGUgc291cmNlIGRhdGEuCiAgICAgKiBAcGFyYW0gc1BpY3R1cmUge3N0cmluZ30KICAgICAqICAgICAgICAgICAgdGhlIGRhdGV0aW1lIHBpY3R1cmUuCiAgICAgKiBAcGFyYW0gc0RhdGVNYXNrIHtzdHJpbmd9CiAgICAgKiAgICAgICAgICAgIHRoZSBkYXRlIHN1Yi1waWN0dXJlLgogICAgICogQHBhcmFtIHNUaW1lTWFzayB7c3RyaW5nfQogICAgICogICAgICAgICAgICB0aGUgdGltZSBzdWItcGljdHVyZS4KICAgICAqIEBwYXJhbSBzTG9jYWxlIHtzdHJpbmd9CiAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbGUgbmFtZS4KICAgICAqLwogICAgUGljdHVyZUZtdC5mb3JtYXREYXRlVGltZSAgPSBmdW5jdGlvbihzU291cmNlLCBzUGljdHVyZSwgc0RhdGVNYXNrLCBzVGltZU1hc2ssIHNMb2NhbGUpewoKICAgIH07Cgp9KShfLHhmYWxpYik7Ci8qKgogKiBAcGFja2FnZSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgZGVmaW5lcyBzdGF0aWMgdXRpbGl0aWVzIG1ldGhvZHMuCiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHZhciBQaWN0dXJlVXRpbHMgPSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzID0gZnVuY3Rpb24oKSB7fQoKICAgIFBpY3R1cmVVdGlscy5wYWRkaW5nID0gZnVuY3Rpb24obnVtYmVyLCBkaWdpdHMsIGlzRncsIHplcm8pewogICAgICAgIHZhciBsZWFkaW5nID0gWyIwIiwiMDAiLCIwMDAiLCIwMDAwIl07CiAgICAgICAgdmFyIG51bVN0ciA9IGxlYWRpbmdbZGlnaXRzLTFdICsgbnVtYmVyOwogICAgICAgIHJldHVybiBudW1TdHIuc2xpY2UoLSBkaWdpdHMpOwogICAgfTsKCiAgICBQaWN0dXJlVXRpbHMucGFyc2VJbnRBZ2dyZXNzaXZlID0gZnVuY3Rpb24oZGF0ZVN0cmluZywgc3RhcnRQb3MsbGVuKXsKICAgICAgICB2YXIgcmVzdWx0ID0gbmV3IE9iamVjdCgpOwogICAgICAgIHZhciBwYXJzZWROdW0gPSAwOyAvL1RoZSBudW1iZXIgdmFsdWUgcGFyc2VkIGZyb20gZGF0ZVN0cmluZwogICAgICAgIHZhciBwYXJzZWRMZW4gPSAtMTsgLy9Ib3cgbWFueSBjaGFycyBwYXJzZWQgYWNjb3JkaW5nIHRvIHRoaXMgcGF0dGVybjsKICAgICAgICBmb3IodmFyIGlkeD0wOyBpZHg8bGVuICYmIChzdGFydFBvcyArIGlkeCkgPCBkYXRlU3RyaW5nLmxlbmd0aDsgaWR4KyspewogICAgICAgICAgICB2YXIgY2hyID0gZGF0ZVN0cmluZy5jaGFyQXQoc3RhcnRQb3MgKyBpZHgpOwogICAgICAgICAgICBpZihjaHIgPj0nMCcgJiYgY2hyIDw9JzknKXsKICAgICAgICAgICAgICAgIHBhcnNlZE51bSA9IHBhcnNlZE51bSAqMTAgKyAoY2hyLSAnMCcpOwogICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgIHBhcnNlZExlbiA9IGlkeDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmKHBhcnNlZExlbiA9PSAtMSkgewogICAgICAgICAgICBwYXJzZWRMZW4gPSBsZW47CiAgICAgICAgfQogICAgICAgIHJlc3VsdC52YWx1ZSA9IHBhcnNlZE51bTsKICAgICAgICByZXN1bHQubGVuID0gcGFyc2VkTGVuOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9OwoKICAgIFBpY3R1cmVVdGlscy5wYXJzZUludEV4YWN0ID0gZnVuY3Rpb24oZGF0ZVN0cmluZywgc3RhcnRQb3MsbGVuKXsKICAgICAgICB2YXIgcmVzdWx0ID0gMDsKICAgICAgICBQaWN0dXJlVXRpbHMuYXNzZXJ0KHN0YXJ0UG9zKyBsZW4gPD0gZGF0ZVN0cmluZy5sZW5ndGgsICJtaXNtYXRjaCIpOwogICAgICAgIGZvcih2YXIgaWR4PTA7IGlkeDxsZW4gOyBpZHgrKyl7CiAgICAgICAgICAgIHZhciBjaHIgPSBkYXRlU3RyaW5nLmNoYXJBdChzdGFydFBvcyArIGlkeCk7CiAgICAgICAgICAgIGlmKGNociA+PScwJyAmJiBjaHIgPD0nOScpewogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICoxMCArIChjaHItICcwJyk7CiAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgdGhyb3cgInVuZXhwZWN0ZWQgY3VycmVudENoYXIgaW4gUGljdHVyZVV0aWxzLnBhcnNlSW50IjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfTsKCiAgICBQaWN0dXJlVXRpbHMuaXNEaWdpdCA9IGZ1bmN0aW9uKGNocil7CiAgICAgICAgcmV0dXJuIC9bMC05XS8udGVzdChjaHIpIDsKICAgIH07CgogICAgUGljdHVyZVV0aWxzLmluU3RyaW5nID0gZnVuY3Rpb24oY2hyLGFTdHJpbmcpewogICAgICAgIHJldHVybiAoYVN0cmluZy5pbmRleE9mKGNocikgPj0wKSA7CiAgICB9OwoKCiAgICB2YXIgcmVnRXhwSXNMZXR0ZXIgPSAvW1x1MDA0MS1cdTAwNWFcdTAwNjEtXHUwMDdhXHUwMGFhLVx1MDBhYVx1MDBiNS1cdTAwYjVcdTAwYmEtXHUwMGJhXHUwMGMwLVx1MDBkNlx1MDBkOC1cdTAwZjZcdTAwZjgtXHUwMjM2XHUwMjUwLVx1MDJjMVx1MDJjNi1cdTAyZDFcdTAyZTAtXHUwMmU0XHUwMmVlLVx1MDJlZVx1MDM3YS1cdTAzN2FcdTAzODYtXHUwMzg2XHUwMzg4LVx1MDM4YVx1MDM4Yy1cdTAzOGNcdTAzOGUtXHUwM2ExXHUwM2EzLVx1MDNjZVx1MDNkMC1cdTAzZjVcdTAzZjctXHUwM2ZiXHUwNDAwLVx1MDQ4MVx1MDQ4YS1cdTA0Y2VcdTA0ZDAtXHUwNGY1XHUwNGY4LVx1MDRmOVx1MDUwMC1cdTA1MGZcdTA1MzEtXHUwNTU2XHUwNTU5LVx1MDU1OVx1MDU2MS1cdTA1ODdcdTA1ZDAtXHUwNWVhXHUwNWYwLVx1MDVmMlx1MDYyMS1cdTA2M2FcdTA2NDAtXHUwNjRhXHUwNjZlLVx1MDY2Zlx1MDY3MS1cdTA2ZDNcdTA2ZDUtXHUwNmQ1XHUwNmU1LVx1MDZlNlx1MDZlZS1cdTA2ZWZcdTA2ZmEtXHUwNmZjXHUwNmZmLVx1MDZmZlx1MDcxMC1cdTA3MTBcdTA3MTItXHUwNzJmXHUwNzRkLVx1MDc0Zlx1MDc4MC1cdTA3YTVcdTA3YjEtXHUwN2IxXHUwOTA0LVx1MDkzOVx1MDkzZC1cdTA5M2RcdTA5NTAtXHUwOTUwXHUwOTU4LVx1MDk2MVx1MDk4NS1cdTA5OGNcdTA5OGYtXHUwOTkwXHUwOTkzLVx1MDlhOFx1MDlhYS1cdTA5YjBcdTA5YjItXHUwOWIyXHUwOWI2LVx1MDliOVx1MDliZC1cdTA5YmRcdTA5ZGMtXHUwOWRkXHUwOWRmLVx1MDllMVx1MDlmMC1cdTA5ZjFcdTBhMDUtXHUwYTBhXHUwYTBmLVx1MGExMFx1MGExMy1cdTBhMjhcdTBhMmEtXHUwYTMwXHUwYTMyLVx1MGEzM1x1MGEzNS1cdTBhMzZcdTBhMzgtXHUwYTM5XHUwYTU5LVx1MGE1Y1x1MGE1ZS1cdTBhNWVcdTBhNzItXHUwYTc0XHUwYTg1LVx1MGE4ZFx1MGE4Zi1cdTBhOTFcdTBhOTMtXHUwYWE4XHUwYWFhLVx1MGFiMFx1MGFiMi1cdTBhYjNcdTBhYjUtXHUwYWI5XHUwYWJkLVx1MGFiZFx1MGFkMC1cdTBhZDBcdTBhZTAtXHUwYWUxXHUwYjA1LVx1MGIwY1x1MGIwZi1cdTBiMTBcdTBiMTMtXHUwYjI4XHUwYjJhLVx1MGIzMFx1MGIzMi1cdTBiMzNcdTBiMzUtXHUwYjM5XHUwYjNkLVx1MGIzZFx1MGI1Yy1cdTBiNWRcdTBiNWYtXHUwYjYxXHUwYjcxLVx1MGI3MVx1MGI4My1cdTBiODNcdTBiODUtXHUwYjhhXHUwYjhlLVx1MGI5MFx1MGI5Mi1cdTBiOTVcdTBiOTktXHUwYjlhXHUwYjljLVx1MGI5Y1x1MGI5ZS1cdTBiOWZcdTBiYTMtXHUwYmE0XHUwYmE4LVx1MGJhYVx1MGJhZS1cdTBiYjVcdTBiYjctXHUwYmI5XHUwYzA1LVx1MGMwY1x1MGMwZS1cdTBjMTBcdTBjMTItXHUwYzI4XHUwYzJhLVx1MGMzM1x1MGMzNS1cdTBjMzlcdTBjNjAtXHUwYzYxXHUwYzg1LVx1MGM4Y1x1MGM4ZS1cdTBjOTBcdTBjOTItXHUwY2E4XHUwY2FhLVx1MGNiM1x1MGNiNS1cdTBjYjlcdTBjYmQtXHUwY2JkXHUwY2RlLVx1MGNkZVx1MGNlMC1cdTBjZTFcdTBkMDUtXHUwZDBjXHUwZDBlLVx1MGQxMFx1MGQxMi1cdTBkMjhcdTBkMmEtXHUwZDM5XHUwZDYwLVx1MGQ2MVx1MGQ4NS1cdTBkOTZcdTBkOWEtXHUwZGIxXHUwZGIzLVx1MGRiYlx1MGRiZC1cdTBkYmRcdTBkYzAtXHUwZGM2XHUwZTAxLVx1MGUzMFx1MGUzMi1cdTBlMzNcdTBlNDAtXHUwZTQ2XHUwZTgxLVx1MGU4Mlx1MGU4NC1cdTBlODRcdTBlODctXHUwZTg4XHUwZThhLVx1MGU4YVx1MGU4ZC1cdTBlOGRcdTBlOTQtXHUwZTk3XHUwZTk5LVx1MGU5Zlx1MGVhMS1cdTBlYTNcdTBlYTUtXHUwZWE1XHUwZWE3LVx1MGVhN1x1MGVhYS1cdTBlYWJcdTBlYWQtXHUwZWIwXHUwZWIyLVx1MGViM1x1MGViZC1cdTBlYmRcdTBlYzAtXHUwZWM0XHUwZWM2LVx1MGVjNlx1MGVkYy1cdTBlZGRcdTBmMDAtXHUwZjAwXHUwZjQwLVx1MGY0N1x1MGY0OS1cdTBmNmFcdTBmODgtXHUwZjhiXHUxMDAwLVx1MTAyMVx1MTAyMy1cdTEwMjdcdTEwMjktXHUxMDJhXHUxMDUwLVx1MTA1NVx1MTBhMC1cdTEwYzVcdTEwZDAtXHUxMGY4XHUxMTAwLVx1MTE1OVx1MTE1Zi1cdTExYTJcdTExYTgtXHUxMWY5XHUxMjAwLVx1MTIwNlx1MTIwOC1cdTEyNDZcdTEyNDgtXHUxMjQ4XHUxMjRhLVx1MTI0ZFx1MTI1MC1cdTEyNTZcdTEyNTgtXHUxMjU4XHUxMjVhLVx1MTI1ZFx1MTI2MC1cdTEyODZcdTEyODgtXHUxMjg4XHUxMjhhLVx1MTI4ZFx1MTI5MC1cdTEyYWVcdTEyYjAtXHUxMmIwXHUxMmIyLVx1MTJiNVx1MTJiOC1cdTEyYmVcdTEyYzAtXHUxMmMwXHUxMmMyLVx1MTJjNVx1MTJjOC1cdTEyY2VcdTEyZDAtXHUxMmQ2XHUxMmQ4LVx1MTJlZVx1MTJmMC1cdTEzMGVcdTEzMTAtXHUxMzEwXHUxMzEyLVx1MTMxNVx1MTMxOC1cdTEzMWVcdTEzMjAtXHUxMzQ2XHUxMzQ4LVx1MTM1YVx1MTNhMC1cdTEzZjRcdTE0MDEtXHUxNjZjXHUxNjZmLVx1MTY3Nlx1MTY4MS1cdTE2OWFcdTE2YTAtXHUxNmVhXHUxNzAwLVx1MTcwY1x1MTcwZS1cdTE3MTFcdTE3MjAtXHUxNzMxXHUxNzQwLVx1MTc1MVx1MTc2MC1cdTE3NmNcdTE3NmUtXHUxNzcwXHUxNzgwLVx1MTdiM1x1MTdkNy1cdTE3ZDdcdTE3ZGMtXHUxN2RjXHUxODIwLVx1MTg3N1x1MTg4MC1cdTE4YThcdTE5MDAtXHUxOTFjXHUxOTUwLVx1MTk2ZFx1MTk3MC1cdTE5NzRcdTFkMDAtXHUxZDZiXHUxZTAwLVx1MWU5Ylx1MWVhMC1cdTFlZjlcdTFmMDAtXHUxZjE1XHUxZjE4LVx1MWYxZFx1MWYyMC1cdTFmNDVcdTFmNDgtXHUxZjRkXHUxZjUwLVx1MWY1N1x1MWY1OS1cdTFmNTlcdTFmNWItXHUxZjViXHUxZjVkLVx1MWY1ZFx1MWY1Zi1cdTFmN2RcdTFmODAtXHUxZmI0XHUxZmI2LVx1MWZiY1x1MWZiZS1cdTFmYmVcdTFmYzItXHUxZmM0XHUxZmM2LVx1MWZjY1x1MWZkMC1cdTFmZDNcdTFmZDYtXHUxZmRiXHUxZmUwLVx1MWZlY1x1MWZmMi1cdTFmZjRcdTFmZjYtXHUxZmZjXHUyMDcxLVx1MjA3MVx1MjA3Zi1cdTIwN2ZcdTIxMDItXHUyMTAyXHUyMTA3LVx1MjEwN1x1MjEwYS1cdTIxMTNcdTIxMTUtXHUyMTE1XHUyMTE5LVx1MjExZFx1MjEyNC1cdTIxMjRcdTIxMjYtXHUyMTI2XHUyMTI4LVx1MjEyOFx1MjEyYS1cdTIxMmRcdTIxMmYtXHUyMTMxXHUyMTMzLVx1MjEzOVx1MjEzZC1cdTIxM2ZcdTIxNDUtXHUyMTQ5XHUzMDA1LVx1MzAwNlx1MzAzMS1cdTMwMzVcdTMwM2ItXHUzMDNjXHUzMDQxLVx1MzA5Nlx1MzA5ZC1cdTMwOWZcdTMwYTEtXHUzMGZhXHUzMGZjLVx1MzBmZlx1MzEwNS1cdTMxMmNcdTMxMzEtXHUzMThlXHUzMWEwLVx1MzFiN1x1MzFmMC1cdTMxZmZcdTM0MDAtXHU0ZGI1XHU0ZTAwLVx1OWZhNVx1YTAwMC1cdWE0OGNcdWFjMDAtXHVkN2EzXHVmOTAwLVx1ZmEyZFx1ZmEzMC1cdWZhNmFcdWZiMDAtXHVmYjA2XHVmYjEzLVx1ZmIxN1x1ZmIxZC1cdWZiMWRcdWZiMWYtXHVmYjI4XHVmYjJhLVx1ZmIzNlx1ZmIzOC1cdWZiM2NcdWZiM2UtXHVmYjNlXHVmYjQwLVx1ZmI0MVx1ZmI0My1cdWZiNDRcdWZiNDYtXHVmYmIxXHVmYmQzLVx1ZmQzZFx1ZmQ1MC1cdWZkOGZcdWZkOTItXHVmZGM3XHVmZGYwLVx1ZmRmYlx1ZmU3MC1cdWZlNzRcdWZlNzYtXHVmZWZjXHVmZjIxLVx1ZmYzYVx1ZmY0MS1cdWZmNWFcdWZmNjYtXHVmZmJlXHVmZmMyLVx1ZmZjN1x1ZmZjYS1cdWZmY2ZcdWZmZDItXHVmZmQ3XHVmZmRhLVx1ZmZkY10vCgogICAgLyoqCiAgICAgKiBUT0RPIEltcGxlbWVudCBtZXRob2QgZXF1aXZhbGVudCB0byBDaGFyYWN0ZXIuaXNMZXR0ZXIuCiAgICAgKi8KICAgIFBpY3R1cmVVdGlscy5pc0xldHRlciA9IGZ1bmN0aW9uKGNocil7CiAgICAgICAgcmV0dXJuIHJlZ0V4cElzTGV0dGVyLnRlc3QoY2hyKTsKICAgIH07CgogICAgUGljdHVyZVV0aWxzLmlzTGV0dGVyT3JEaWdpdCA9IGZ1bmN0aW9uKGNocil7CiAgICAgICAgcmV0dXJuIHRoaXMuaXNMZXR0ZXIoY2hyKSB8fCB0aGlzLmlzRGlnaXQoY2hyKTsKICAgIH07CgogICAgLyoqCiAgICAgKiBTY2FuIHRoaXMgc3RyaW5nIGZvciB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBnaXZlbiBzZXQuIFNpbWlsYXIgdG8KICAgICAqIHN0cmNzcG4oKS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3Jje1N0cmluZ30KICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBzY2FuCiAgICAgKiBAcGFyYW0gc1NraXB7U3RyaW5nfQogICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVycyB0byBzY2FuIGZvcgogICAgICogQHBhcmFtIG5PZmZzZXR7bnVtYmVyfQogICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gd2hlcmUgdG8gc3RhcnQgdGhlIHNjYW4uIERlZmF1bHQgPSAwLgogICAgICogQHJldHVybiBUaGUgcG9zaXRpb24sIHJlbGF0aXZlIHRvIG5PZmZzZXQsIGZvciB0aGUgZmlyc3QgY2hhcmFjdGVyIGZvdW5kCiAgICAgKiAgICAgICAgIGluIHRoZSBnaXZlbiBzZXQKICAgICAqLwogICAgUGljdHVyZVV0aWxzLnNraXBVbnRpbCA9IGZ1bmN0aW9uKHNyY1N0ciwgc1NraXAsIG5PZmZzZXQpIHsKICAgICAgICB2YXIgbkNoYXJzU2tpcHBlZCA9IG5PZmZzZXQ7CgogICAgICAgIC8vIHN0YXJ0aW5nIGF0IHRoZSBvZmZzZXQgcG9zaXRpb24sIHNjYW4gdGhlIGNoYXJhY3RlcnMgaW4gdGhpcyBzdHJpbmcKICAgICAgICAvLyB1bnRpbCBpdCBtYXRjaGVzIG9uZSBvZiB0aGUgY2hhcmFjdGVycyBpbiB0aGUgZ2l2ZW4gc2V0LgogICAgICAgIHdoaWxlIChuQ2hhcnNTa2lwcGVkIDwgc3JjU3RyLmxlbmd0aCkgewogICAgICAgICAgICB2YXIgaSA9IG5DaGFyc1NraXBwZWQ7CiAgICAgICAgICAgIGlmIChzU2tpcC5pbmRleE9mKHNyY1N0ci5jaGFyQXQoaSsrKSkgPj0gMCkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBuQ2hhcnNTa2lwcGVkID0gaTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuQ2hhcnNTa2lwcGVkIC0gbk9mZnNldDsKICAgIH07CgogICAgUGljdHVyZVV0aWxzLm1hdGNoU3RyaW5nID0gZnVuY3Rpb24oc3RyLCBzdGFydFBvcywgdGFyZ2V0KXsKICAgICAgICBpZihzdGFydFBvcyArIHRhcmdldC5sZW5ndGggPiBzdHIubGVuZ3RoKXsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH1lbHNlewogICAgICAgICAgICBmb3IodmFyIGlkeCA9IDA7IGlkeDx0YXJnZXQubGVuZ3RoOyBpZHgrKyl7CiAgICAgICAgICAgICAgICBpZih0YXJnZXQuY2hhckF0KGlkeCkgIT0gc3RyLmNoYXJBdChzdGFydFBvcyArIGlkeCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9OwoKICAgIFBpY3R1cmVVdGlscy5hc3NlcnQgPSBmdW5jdGlvbihjb25kaXRpb24sIG1lc3NhZ2UpewogICAgICAgIGlmKCFjb25kaXRpb24pewogICAgICAgICAgICB0aHJvdyBtZXNzYWdlOwogICAgICAgIH0KICAgIH07CgogICAgUGljdHVyZVV0aWxzLmdldExvY2FsZU9iamVjdCA9IGZ1bmN0aW9uKGxvY2FsZSxwcm9wZXJ0eSkgewogICAgICAgIGlmKGxvY2FsZSAhPT0gbnVsbCAmJiB4ZmFsaWIucnVudGltZS54ZmEpIHsKICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi5ydW50aW1lLnhmYS5fZ2V0TG9jYWxlU3ltYm9scyhsb2NhbGUsIHByb3BlcnR5KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmdldERlZmF1bHRMb2NhbGVQcm9wZXJ0eShwcm9wZXJ0eSkKICAgICAgICB9CiAgICB9CgogICAgUGljdHVyZVV0aWxzLmdldEhhc2hPZkxvY2FsZU9iamVjdCA9IGZ1bmN0aW9uKGxvY2FsZSxwcm9wZXJ0eSkgewogICAgICAgICAgaWYoIVBpY3R1cmVVdGlscy5nZXRIYXNoT2ZMb2NhbGVPYmplY3RbbG9jYWxlKyJfIitwcm9wZXJ0eV0pIHsKICAgICAgICAgICAgICB2YXIgaGFzaE9iaiA9IHt9OwogICAgICAgICAgICAgIF8uZWFjaChQaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KGxvY2FsZSxwcm9wZXJ0eSksIGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAgICAgICB2YXIgc1ZhbCA9ICh2YWwrIiIpLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICAgIHZhciBoYXNoID0gMDsKICAgICAgICAgICAgICAgICAgZm9yKHZhciBpID0wO2k8c1ZhbC5sZW5ndGg7aSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICBoYXNoKz0oaSsxKSpzVmFsLmNoYXJDb2RlQXQoaSkKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBoYXNoT2JqW2hhc2hdID0gaGFzaE9ialtoYXNoXSB8fCBbXTsKICAgICAgICAgICAgICAgICAgaGFzaE9ialtoYXNoXS5wdXNoKHNWYWwpOwogICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgUGljdHVyZVV0aWxzLmdldEhhc2hPZkxvY2FsZU9iamVjdFtsb2NhbGUrIl8iK3Byb3BlcnR5XSA9IGhhc2hPYmo7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gUGljdHVyZVV0aWxzLmdldEhhc2hPZkxvY2FsZU9iamVjdFtsb2NhbGUrIl8iK3Byb3BlcnR5XQogICAgfQoKICAgIFBpY3R1cmVVdGlscy5jb252ZXJ0TnVtYmVyVG9Mb2NhbGUgPSBmdW5jdGlvbihsb2NhbGUsbnVtYmVyKSB7CiAgICAgICAgdmFyIHplcm8gPSBQaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KGxvY2FsZSwibnVtYmVyU3ltYm9scy56ZXJvIik7CiAgICAgICAgdmFyIHplcm9Db2RlID0gemVyby5jaGFyQ29kZUF0KDApOwogICAgICAgIG51bWJlciArPSAiIjsKICAgICAgICB2YXIgbmV3TnVtYmVyID0gW107CiAgICAgICAgZm9yKHZhciBpID0gMDtpIDwgbnVtYmVyLmxlbmd0aDtpKyspIHsKICAgICAgICAgICAgbmV3TnVtYmVyLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZSh6ZXJvQ29kZSArIHBhcnNlSW50KG51bWJlci5jaGFyQXQoaSkpKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXdOdW1iZXIuam9pbigiIik7CiAgICB9CgogICAgUGljdHVyZVV0aWxzLnBhcnNlUGljdHVyZUNsYXVzZSA9IGZ1bmN0aW9uIChjbGF1c2UpewogICAgICAgIGlmKGNsYXVzZSA9PT0gbnVsbCB8fCBjbGF1c2UgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICByZXR1cm4gW107CiAgICAgICAgfQogICAgICAgIHZhciBpbnNpZGVQYXR0ZXJuID0gZmFsc2UsCiAgICAgICAgICAgIGluc2lkZVF1b3RlPWZhbHNlLAogICAgICAgICAgICBpbnNpZGVMb2NhbGUgPSBmYWxzZSwKICAgICAgICAgICAgbG9jYWxlID0gIiIsCiAgICAgICAgICAgIHR5cGUgPSAiIiwKICAgICAgICAgICAgcGF0dGVybiA9ICIiLAogICAgICAgICAgICBmbGFnID0gZmFsc2UsCiAgICAgICAgICAgIGN1cnJlbnRDaGFyID0gIiIsCiAgICAgICAgICAgIHJlc3VsdCA9IFtdLAogICAgICAgICAgICBtYXRjaFR5cGUgPSAvXm51bSR8XnRleHQkfF5kYXRlJC8sCiAgICAgICAgICAgIG1hdGNoTG9jYWxlID0gL15bYS16QS1aXSpfW2EtekEtWl0qJC8sCiAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICBicmFja2V0T3BlbkNvdW50ID0gMDsKICAgICAgICBmb3IoO2k8Y2xhdXNlLmxlbmd0aDtpKyspIHsKICAgICAgICAgICAgY3VycmVudENoYXIgPSBjbGF1c2UuY2hhckF0KGkpOwogICAgICAgICAgICBpZihpbnNpZGVRdW90ZSAmJiBjdXJyZW50Q2hhciAhPT0gIiciKSB7CiAgICAgICAgICAgICAgICBwYXR0ZXJuICs9IGN1cnJlbnRDaGFyOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3dpdGNoKGN1cnJlbnRDaGFyKSB7CiAgICAgICAgICAgICAgIGNhc2UgIiciOgogICAgICAgICAgICAgICAgICAgaWYoIWluc2lkZVBhdHRlcm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAvLyAnIGlzIG5vdCBhbGxvd2VkIGV4Y2VwdCBpbnNpZGVQYXR0ZXJuCiAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICBpbnNpZGVRdW90ZSA9ICFpbnNpZGVRdW90ZTsKICAgICAgICAgICAgICAgICAgIHBhdHRlcm4gKz0gY3VycmVudENoYXI7CiAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgY2FzZSAieyI6CiAgICAgICAgICAgICAgICAgICAgaWYoaW5zaWRlUGF0dGVybiB8fCBpbnNpZGVMb2NhbGUgfHwgdHlwZSA9PT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8geyBpcyBub3QgYWxsb3dlZCBpbnNpZGVQYXR0ZXJuIG9yIGluc2lkZUxvY2FsZQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICBpbnNpZGVQYXR0ZXJuID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIn0iOgogICAgICAgICAgICAgICAgICAgIGlmKCFpbnNpZGVQYXR0ZXJuIHx8IChpbnNpZGVMb2NhbGUgJiYgcGF0dGVybiA9PT0gIiIpIHx8IHR5cGUgPT09ICIiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHsgaXMgYWxsb3dlZCBvbmx5IGluc2lkZVBhdHRlcm4gYW5kIG5vdCBpbnNpZGVMb2NhbGUKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJhY2tldE9wZW5Db3VudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGluc2lkZVBhdHRlcm4gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYobWF0Y2hUeXBlLmV4ZWModHlwZSkgPT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGxvY2FsZSAhPT0gIiIgJiYgbWF0Y2hMb2NhbGUuZXhlYyhsb2NhbGUpID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaCh7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeTogdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hc2s6IHBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbGU6IGxvY2FsZQogICAgICAgICAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInwiOgogICAgICAgICAgICAgICAgICAgIGlmKHR5cGUgPT09ICIiIHx8IGluc2lkZVBhdHRlcm4gfHwgaW5zaWRlTG9jYWxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBwYXR0ZXJuID0gbG9jYWxlID0gIiI7CiAgICAgICAgICAgICAgICAgICAgICAgIGluc2lkZVBhdHRlcm4gPSBpbnNpZGVMb2NhbGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICIoIiA6CiAgICAgICAgICAgICAgICAgICAgaWYodHlwZSA9PT0gIiIgfHwgYnJhY2tldE9wZW5Db3VudCA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyAoIGlzIG5vdCBhbGxvd2VkIGluc2lkZSBMb2NhbGUKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIWluc2lkZVBhdHRlcm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc2lkZUxvY2FsZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuICs9IGN1cnJlbnRDaGFyOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyYWNrZXRPcGVuQ291bnQrKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICIpIiA6CiAgICAgICAgICAgICAgICAgICAgaWYoKCFpbnNpZGVMb2NhbGUgJiYgIWluc2lkZVBhdHRlcm4pIHx8IGJyYWNrZXRPcGVuQ291bnQgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoaW5zaWRlUGF0dGVybikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybiArPSBjdXJyZW50Q2hhcjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpbnNpZGVMb2NhbGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJhY2tldE9wZW5Db3VudC0tOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYoaW5zaWRlUGF0dGVybikgewogICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuICs9IGN1cnJlbnRDaGFyOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZihpbnNpZGVMb2NhbGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlICs9IGN1cnJlbnRDaGFyOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZih0eXBlICE9PSAiIiAmJiAocGF0dGVybiAhPT0gIiIgfHwgbG9jYWxlICE9PSAiIikpewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0eXBlICs9IGN1cnJlbnRDaGFyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICB9CiAgICAgICB9CiAgICAgICBpZihpbnNpZGVQYXR0ZXJuIHx8IGluc2lkZUxvY2FsZSB8fCBpbnNpZGVRdW90ZSB8fCBicmFja2V0T3BlbkNvdW50ICE9PSAwKSB7CiAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICB9CiAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKfSkoXyx4ZmFsaWIpOwoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5WaXNpdG9yQmFzZQogKiBAaW1wb3J0IHhmYWxpYi51dC5DbGFzcwogKiBAZmlsZU92ZXJ2aWV3IEJhc2UgY2xhc3MgZm9yIHZpc2l0b3IKICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nfX0KICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpIHsKICAgIHZhciBWaXNpdG9yQmFzZSA9IHhmYWxpYi51dC5WaXNpdG9yQmFzZSA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewogICAgICAgIGNvbnN1bWUgOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgICAgIHN3aXRjaCAodG9rZW4udHlwZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgIHRoaXMuY29uc3VtZVN0cmluZ0xpdGVyYWwodG9rZW4pOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgICAgIHRoaXMuY29uc3VtZVN1YlBhdHRlcm4odG9rZW4pOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgICAgIHRoaXMuY29uc3VtZVN0cmluZ1dpbGRDYXJkKHRva2VuKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnN1bWVDaGFyTGl0ZXJhbCh0b2tlbik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGFjY2VwdFBhdHRlcm5DaGFyIDogZnVuY3Rpb24oY2hyKXsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCiAgICAgICAgZ2V0UGljdHVyZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmU7CiAgICAgICAgfSwKICAgICAgICBhYnN0cmFjdE1ldGhvZCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHRocm93ICJOb3QgaW1wbGVtZW50ZWQiOwogICAgICAgIH0sCiAgICAgICAgY29uc3VtZVN0cmluZ1dpbGRDYXJkIDogdGhpcy5hYnN0cmFjdE1ldGhvZCwKICAgICAgICBjb25zdW1lU3RyaW5nTGl0ZXJhbDogdGhpcy5hYnN0cmFjdE1ldGhvZCwKICAgICAgICBjb25zdW1lQ2hhckxpdGVyYWw6IHRoaXMuYWJzdHJhY3RNZXRob2QsCiAgICAgICAgY29uc3VtZVN1YlBhdHRlcm46IHRoaXMuYWJzdHJhY3RNZXRob2QsCiAgICAgICAgZ2V0UmVzdWx0OiB0aGlzLmFic3RyYWN0TWV0aG9kCiAgICB9KTsKfSkoXyx4ZmFsaWIpOwoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYwogKiBAaW1wb3J0IHhmYWxpYi51dC5DbGFzcwogKiBAZmlsZU92ZXJ2aWV3IFByZS1wcm9jZXNzIE51bWVyaWMgUGljdHVyZS4KICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nfX0KICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgdmFyIE51bVBpY3R1cmVEZXNjID0geGZhbGliLnV0Lk51bVBpY3R1cmVEZXNjID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB0aGlzLmhhc1JhZGl4ID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuaGFzRXhwb24gPSBmYWxzZTsKICAgICAgICAgICAgdGhpcy5oYXNTaWduID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuaGFzUGVyY2VudCA9IGZhbHNlOwogICAgICAgICAgICB0aGlzLmZyYWNEaWdpdCA9IDA7CiAgICAgICAgICAgIHRoaXMuaW50RGlnaXQgPSAwOwoKICAgICAgICAgICAgdGhpcy5fbWJMZWZ0UGFyZW5TZWVuID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuX21iUmlnaHRQYXJlblNlZW4gPSBmYWxzZTsKICAgICAgICAgICAgdGhpcy5fY29tcGFjdFBhdHRlcm4oKTsKICAgICAgICAgICAgdGhpcy5feGxhdGVQYXR0ZXJuKCk7CiAgICAgICAgICAgIE51bVBpY3R1cmVEZXNjLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgfSwKICAgICAgICAKICAgICAgICBnZXRQaWN0dXJlIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZTsKICAgICAgICB9LAoKICAgICAgICBfbWF0Y2gyQ2hhciA6IGZ1bmN0aW9uIChjaGFyMSwgY2hhcjIsIGlkeCl7CiAgICAgICAgICAgIGlmKGlkeCsxIDwgdGhpcy5qc29uTW9kZWwuX3NQaWN0dXJlLmxlbmd0aCl7CiAgICAgICAgICAgICAgICByZXR1cm4gKHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5jaGFyQXQoaWR4KSA9PWNoYXIxICYmIHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5jaGFyQXQoaWR4KzEpID09Y2hhcjIpOwogICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF94bGF0ZVBhdHRlcm4gOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgcGF0UG9zID0gMDsKICAgICAgICAgICAgZm9yKHZhciB0b2tlbiA9IHhmYWxpYi51dC5TY2FubmVyLmxvb2t1cE5leHQodGhpcy5qc29uTW9kZWwuX3NQaWN0dXJlLCBwYXRQb3MsIHRoaXMuX2FjY2VwdFBhdHRlcm5DaGFyKTsgdG9rZW4gIT0gbnVsbDsgICl7CiAgICAgICAgICAgICAgICB0aGlzLl9jb25zdW1lKHRva2VuKTsKICAgICAgICAgICAgICAgIHBhdFBvcyA9IHBhdFBvcyArIHRva2VuLmxlbjsKICAgICAgICAgICAgICAgIHRva2VuID0geGZhbGliLnV0LlNjYW5uZXIubG9va3VwTmV4dCh0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmUsIHBhdFBvcywgdGhpcy5fYWNjZXB0UGF0dGVybkNoYXIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAKICAgICAgICBfY29tcGFjdFBhdHRlcm4gOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgYnVmID0gbmV3IEFycmF5KCk7CiAgICAgICAgICAgIGZvcih2YXIgaW5kZXggPTAsIGxlbiA9IHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5sZW5ndGg7IGluZGV4IDxsZW47IGluZGV4KyspewogICAgICAgICAgICAgICAgaWYodGhpcy5fbWF0Y2gyQ2hhcignRCcsJ0InLGluZGV4KSl7CiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goJ0QnKTsKICAgICAgICAgICAgICAgICAgICBpbmRleCsrOwogICAgICAgICAgICAgICAgfWVsc2UgaWYodGhpcy5fbWF0Y2gyQ2hhcignZCcsJ2InLGluZGV4KSl7CiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goJ2QnKTsKICAgICAgICAgICAgICAgICAgICBpbmRleCsrOwogICAgICAgICAgICAgICAgfWVsc2UgaWYodGhpcy5fbWF0Y2gyQ2hhcignQycsJ1InLGluZGV4KSl7CiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goJ0MnKTsKICAgICAgICAgICAgICAgICAgICBpbmRleCsrOwogICAgICAgICAgICAgICAgfWVsc2UgaWYodGhpcy5fbWF0Y2gyQ2hhcignYycsJ3InLGluZGV4KSl7CiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goJ2MnKTsKICAgICAgICAgICAgICAgICAgICBpbmRleCsrOwogICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2godGhpcy5qc29uTW9kZWwuX3NQaWN0dXJlLmNoYXJBdChpbmRleCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZSA9IGJ1Zi5qb2luKCIiKTsKICAgICAgICB9LAoKICAgICAgICBfYWNjZXB0UGF0dGVybkNoYXIgOiBmdW5jdGlvbihjaHIpewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlBpY3R1cmVVdGlscy5pblN0cmluZyhjaHIsICIoJSQsLik4OUJDREVSU1ZaYmNkcnN2enQiKTsKICAgICAgICB9LAoKICAgICAgICBfY29uc3VtZSA6IGZ1bmN0aW9uKHRva2VuKXsKICAgICAgICAgICAgaWYodG9rZW4udHlwZSA9PSAyKXsKICAgICAgICAgICAgICAgIHRoaXMuX3N1YkNvbnN1bWUodG9rZW4ucGF0Q2hhciwgdG9rZW4ubGVuKTsKICAgICAgICAgICAgfS8vIGVsc2Ugbm90IGEgcGF0dGVybgogICAgICAgIH0sCgogICAgICAgIF9zdWJDb25zdW1lIDogZnVuY3Rpb24oY2hyLCBjaHJDbnQpewogICAgICAgICAgICBzd2l0Y2ggKGNocikgewogICAgICAgICAgICAgICAgY2FzZSdFJyA6CiAgICAgICAgICAgICAgICAgICAgaWYgKGNockNudCA+IDEgfHwgdGhpcy5oYXNFeHBvbiB8fCAodGhpcy5mcmFjRGlnaXQgKyB0aGlzLmludERpZ2l0KT09MCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIklsbGVnYWwgTnVtZXJpYyBQaWN0dXJlOiBtb3JlIHRoYW4gb25lIEV4cG9uIjsKICAgICAgICAgICAgICAgICAgICB0aGlzLmhhc0V4cG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJygnOgogICAgICAgICAgICAgICAgICAgIGlmIChjaHJDbnQgPiAxIHx8IHRoaXMuX21iTGVmdFBhcmVuU2Vlbgl8fCB0aGlzLmZyYWNEaWdpdCArIHRoaXMuaW50RGlnaXQgPjAgKQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiSWxsZWdhbCBOdW1lcmljIFBpY3R1cmU6ICAoKSI7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJMZWZ0UGFyZW5TZWVuID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICcpJzoKICAgICAgICAgICAgICAgICAgICBpZiAoY2hyQ250ID4gMSB8fCAhIHRoaXMuX21iTGVmdFBhcmVuU2VlbiB8fCB0aGlzLl9tYlJpZ2h0UGFyZW5TZWVuKQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiSWxsZWdhbCBOdW1lcmljIFBpY3R1cmU6ICAoKSI7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJSaWdodFBhcmVuU2VlbiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5mcmFjRGlnaXQgKyB0aGlzLmludERpZ2l0ID4wKSB0aGlzLmhhc1NpZ24gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnUyc6CiAgICAgICAgICAgICAgICBjYXNlICdzJzoKICAgICAgICAgICAgICAgIGNhc2UgJ0MnOiAvL0NSCiAgICAgICAgICAgICAgICBjYXNlICdjJzogLy9jcgogICAgICAgICAgICAgICAgY2FzZSAnRCc6IC8vREIKICAgICAgICAgICAgICAgIGNhc2UgJ2QnOiAvL2RiCiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYXNTaWduID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJyUnIDoKICAgICAgICAgICAgICAgICAgICB0aGlzLmhhc1BlcmNlbnQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnLic6CiAgICAgICAgICAgICAgICBjYXNlICdWJzoKICAgICAgICAgICAgICAgIGNhc2UgJ3YnOgogICAgICAgICAgICAgICAgICAgIGlmIChjaHJDbnQgPiAxIHx8IHRoaXMuaGFzUmFkaXgpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJJbGxlZ2FsIE51bWVyaWMgUGljdHVyZTogdG9vIG1hbnkgdlYuIjsKICAgICAgICAgICAgICAgICAgICB0aGlzLmhhc1JhZGl4ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYkZyYWNTdGFydFNlZW4gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnOCcgOgogICAgICAgICAgICAgICAgY2FzZSAnOScgOgogICAgICAgICAgICAgICAgY2FzZSAnWic6CiAgICAgICAgICAgICAgICBjYXNlICd6JzoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5oYXNSYWRpeCl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZnJhY0RpZ2l0ICs9IGNockNudDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW50RGlnaXQgKz0gY2hyQ250OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHBhcnNlTnVtYmVySW5mbyA6IGZ1bmN0aW9uKG1zVGV4dCl7CiAgICAgICAgICAgIHZhciB0ZXh0PW1zVGV4dCwKICAgICAgICAgICAgICAgIG51bSA9IE51bWJlcih0ZXh0KSwKICAgICAgICAgICAgICAgIG5lZ2F0aXZlID0gZmFsc2UKICAgICAgICAgICAgaWYobnVtIDwgMCl7CiAgICAgICAgICAgICAgICBuZWdhdGl2ZSA9IHRydWU7CiAgICAgICAgICAgICAgICBudW0gPSAtbnVtOwogICAgICAgICAgICAgICAgdGV4dCA9IHRleHQucmVwbGFjZSgiLSIsIiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKHRoaXMuaGFzUGVyY2VudCl7CiAgICAgICAgICAgICAgICBudW0gKj0gMTAwOwogICAgICAgICAgICAgICAgdGV4dCA9ICIiK251bTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgc2hpZnQgPSAwOwogICAgICAgICAgICBpZih0aGlzLmhhc0V4cG9uKXsKICAgICAgICAgICAgICAgIHZhciB0aHJlc2hvbGQgPSBNYXRoLnBvdygxMCx0aGlzLmludERpZ2l0KTsKICAgICAgICAgICAgICAgIGlmKG51bSA8IHRocmVzaG9sZCl7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUobnVtKjEwIDwgdGhyZXNob2xkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG51bSAqPSAxMDsKICAgICAgICAgICAgICAgICAgICAgICAgc2hpZnQtLTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgICAgICB3aGlsZShudW0gPiB0aHJlc2hvbGQpewogICAgICAgICAgICAgICAgICAgICAgICBudW0gLz0gMTA7CiAgICAgICAgICAgICAgICAgICAgICAgIHNoaWZ0Kys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGV4dCA9IG51bSsiIjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgcmFkaXhQb3MgPSB0ZXh0LmluZGV4T2YoIi4iLCAwKSwKICAgICAgICAgICAgICAgIGZyYWN0aW9uRGlnaXQgPSByYWRpeFBvczwwID8gMCA6IHRleHQubGVuZ3RoIC0gcmFkaXhQb3MgLSAxCgogICAgICAgICAgICBpZih0aGlzLmZyYWNEaWdpdCA8IGZyYWN0aW9uRGlnaXQpIHsKICAgICAgICAgICAgICAgIG51bSA9IG51bS50b0ZpeGVkKHRoaXMuZnJhY0RpZ2l0KTsKICAgICAgICAgICAgICAgIHRleHQgPSBudW0gKyIiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHRleHQuaW5kZXhPZigiMCIpID09IDAgJiYgbXNUZXh0LmluZGV4T2YoIjAiKSAhPSAwKSB7CiAgICAgICAgICAgICAgICB0ZXh0ID0gdGV4dC5zdWJzdHJpbmcoMSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJhZGl4UG9zID0gdGV4dC5pbmRleE9mKCIuIiwgMCkKICAgICAgICAgICAgdmFyIGludGVnZXJEaWdpdCA9IHJhZGl4UG9zIDwgMCA/IHRleHQubGVuZ3RoIDogcmFkaXhQb3MsCiAgICAgICAgICAgICAgICBvZmZzZXQgPSB0aGlzLmludERpZ2l0IC0gaW50ZWdlckRpZ2l0CgogICAgICAgICAgICBpZihvZmZzZXQgPDAgKXsKICAgICAgICAgICAgICAgIHRocm93ICJFeGl0OiBtb3N0IHNpZ25pZmljYW50ICIgKyBvZmZzZXQgKyIgZGlnaXQgbG9zdCI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICJpbnRlZ2VyRGlnaXQiIDogaW50ZWdlckRpZ2l0LAogICAgICAgICAgICAgICAgInJhZGl4UG9zIiA6IHJhZGl4UG9zICwKICAgICAgICAgICAgICAgICJmcmFjdGlvbkRpZ2l0IiA6ICByYWRpeFBvczwwID8gMCA6IHRleHQubGVuZ3RoIC0gcmFkaXhQb3MgLSAxLAogICAgICAgICAgICAgICAgIm1zVGV4dCIgOiB0ZXh0LAogICAgICAgICAgICAgICAgInNoaWZ0IiA6IHNoaWZ0LAogICAgICAgICAgICAgICAgImlzTmVnYXRpdmUiIDogbmVnYXRpdmUsCiAgICAgICAgICAgICAgICAicGFkZGluZyIgOm9mZnNldAogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0pOwoKICAgIE51bVBpY3R1cmVEZXNjLmdzREIgPSAiREIiOwogICAgTnVtUGljdHVyZURlc2MuZ3NDUiA9ICJDUiI7CiAgICBOdW1QaWN0dXJlRGVzYy5nc0UgPSAiRSI7CiAgICBOdW1QaWN0dXJlRGVzYy5nc0RTUCA9ICIgICI7CiAgICBOdW1QaWN0dXJlRGVzYy5nc1NTUCA9ICIgIjsKCn0pKF8seGZhbGliKTsKCgoKCgoKCgoKCgogICAgLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5UaW1lSW5mbwogKiBAaW1wb3J0IHhmYWxpYi51dC5DbGFzcwogKiBAZmlsZU92ZXJ2aWV3IEEgd3JhcHBlciBjbGFzcyBmb3IgZGF0ZSByZWxhdGVkIGluZm9ybWF0aW9uLgogKiBAdmVyc2lvbiAwLjAuMQogKi8KCi8qKgogKiBAY29uc3RydWN0b3IKICovCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgVGltZUluZm8gPSB4ZmFsaWIudXQuVGltZUluZm8gPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHRoaXMubUhvdXJPZk1lcmlEaWVtID0gLTE7CiAgICAgICAgICAgIHRoaXMubUhvdXJPZkRheSA9IC0xOwogICAgICAgICAgICB0aGlzLm1NaW51dGVPZkhvdXIgPSAtMTsKICAgICAgICAgICAgdGhpcy5tU2Vjb25kT2ZNaW51dGUgPSAtMTsKICAgICAgICAgICAgdGhpcy5tVGhvdXNhbmR0aE9mU2Vjb25kID0gLTE7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0SVNPVGltZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciB0aW1lU3RyID0gIiI7CiAgICAgICAgICAgIGlmKHRoaXMubVRob3VzYW5kdGhPZlNlY29uZD4wKXsKICAgICAgICAgICAgICAgIHRpbWVTdHIgPSAiLSIgKyB0aGlzLmZvcm1hdE51bSh0aGlzLm1UaG91c2FuZHRoT2ZTZWNvbmQsMyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYodGhpcy5tU2Vjb25kT2ZNaW51dGU+MCB8fCB0aW1lU3RyIT0iIil7CiAgICAgICAgICAgICAgICB0aW1lU3RyID0gdGhpcy5mb3JtYXROdW0odGhpcy5tU2Vjb25kT2ZNaW51dGUsMikrdGltZVN0cjsKICAgICAgICAgICAgICAgIHRpbWVTdHIgPSAiOiIrdGltZVN0cjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZih0aGlzLm1NaW51dGVPZkhvdXI+MCB8fCB0aW1lU3RyIT0iIil7CiAgICAgICAgICAgICAgICB0aW1lU3RyID0gdGhpcy5mb3JtYXROdW0odGhpcy5tTWludXRlT2ZIb3VyLDIpK3RpbWVTdHI7CiAgICAgICAgICAgICAgICB0aW1lU3RyID0gIjoiK3RpbWVTdHI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGltZVN0ciA9IHRoaXMuZm9ybWF0TnVtKHRoaXMubUhvdXJPZkRheSwyKSArIHRpbWVTdHI7CgogICAgICAgICAgICByZXR1cm4gdGltZVN0cjsKICAgICAgICB9LAoKICAgICAgICBmb3JtYXROdW0gOiBmdW5jdGlvbihudW0sIGRpZ2l0cyl7CiAgICAgICAgICAgIGlmKG51bTwwKXsKICAgICAgICAgICAgICAgIG51bSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5QaWN0dXJlVXRpbHMucGFkZGluZyhudW0sIGRpZ2l0cyk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RGF0ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciBkYXRlID0gbmV3IERhdGUoKTsKICAgICAgICAgICAgdGhpcy5zZXRUaW1lKGRhdGUpOwogICAgICAgICAgICByZXR1cm4gZGF0ZTsKICAgICAgICB9LAoKICAgICAgICBzZXRUaW1lIDogZnVuY3Rpb24oZGF0ZSl7CiAgICAgICAgICAgIGRhdGUuc2V0SG91cnModGhpcy5tSG91ck9mRGF5KTsKICAgICAgICAgICAgZGF0ZS5zZXRNaW51dGVzKHRoaXMubU1pbnV0ZU9mSG91cik7CiAgICAgICAgICAgIGRhdGUuc2V0U2Vjb25kcyh0aGlzLm1TZWNvbmRPZk1pbnV0ZSk7CiAgICAgICAgICAgIGRhdGUuc2V0TWlsbGlzZWNvbmRzKHRoaXMubVRob3VzYW5kdGhPZlNlY29uZCk7CiAgICAgICAgfQogICAgfSk7CgogICAgLyoqCiAgICAgKgogICAgICogPHA+VmFsaWQgSVNPODYwMS9YRkEgdGltZSBzdHJpbmdzIGFyZSBpbiBhbnkgb25lCiAgICAgKiBvZiB0aGUgZm9sbG93aW5nIHRpbWUgcGF0dGVybnM6CiAgICAgKiA8dWw+CiAgICAgKiA8bGk+IEhIW01NW1NTWy5GRkZdW3pdXV0KICAgICAqIDxsaT4gSEhbTU1bU1NbLkZGRl1bK0hIW01NXV1dXQogICAgICogPGxpPiBISFtNTVtTU1suRkZGXVstSEhbTU1dXV1dCiAgICAgKiA8bGk+IEhIWzpNTVs6U1NbLkZGRl1bel1dXQogICAgICogPGxpPiBISFs6TU1bOlNTWy5GRkZdWytISFs6TU1dXV1dCiAgICAgKiA8bGk+IEhIWzpNTVs6U1NbLkZGRl1bLUhIWzpNTV1dXV0KICAgICAqIDwvdWw+CiAgICAgKi8KICAgIFRpbWVJbmZvLlBhcnNlID0gZnVuY3Rpb24oaXNvRGF0ZVN0ciwgbG9jYWxlKXsKICAgICAgICB2YXIgc2Nhbm5lciA9IG5ldyB4ZmFsaWIudXQuU2Nhbm5lcih7anNvbk1vZGVsOntfc3RyOmlzb0RhdGVTdHJ9fSk7CiAgICAgICAgdmFyIGhvdXJzID0gc2Nhbm5lci5yZWFkSW50ZWdlcigyKTsKICAgICAgICB2YXIgbWluaXR1ZXMgPSAtMTsKICAgICAgICBpZighc2Nhbm5lci5pc0VPRigpKXsKICAgICAgICAgICAgc2Nhbm5lci5vcHRpb25hbENvbnN1bWVDaGFyKCc6Jyk7CiAgICAgICAgICAgIG1pbml0dWVzID0gc2Nhbm5lci5yZWFkSW50ZWdlcigyKTsKICAgICAgICB9CiAgICAgICAgdmFyIHNlY29uZHMgPSAtMTsKICAgICAgICBpZighc2Nhbm5lci5pc0VPRigpKXsKICAgICAgICAgICAgc2Nhbm5lci5vcHRpb25hbENvbnN1bWVDaGFyKCc6Jyk7CiAgICAgICAgICAgIHNlY29uZHMgPSBzY2FubmVyLnJlYWRJbnRlZ2VyKDIpOwogICAgICAgIH0KICAgICAgICB2YXIgbWlsbGlzZWNvbmRzID0gLTE7CiAgICAgICAgaWYoIXNjYW5uZXIuaXNFT0YoKSl7CiAgICAgICAgICAgIHNjYW5uZXIub3B0aW9uYWxDb25zdW1lQ2hhcignLScpOwogICAgICAgICAgICBtaWxsaXNlY29uZHMgPSBzY2FubmVyLnJlYWRJbnRlZ2VyKDMpOwogICAgICAgIH0KICAgICAgICAvL1RPRE8gdGltZXpvbmUKICAgICAgICB2YXIgaW5mbyA9IG5ldyB4ZmFsaWIudXQuVGltZUluZm8oKTsKICAgICAgIFRpbWVJbmZvLnNldFByb3BlcnR5SWZOb3ROdWxsKGluZm8saG91cnMsIm1Ib3VyT2ZEYXkiKTsKICAgICAgIFRpbWVJbmZvLnNldFByb3BlcnR5SWZOb3ROdWxsKGluZm8sbWluaXR1ZXMsIm1NaW51dGVPZkhvdXIiKTsKICAgICAgIFRpbWVJbmZvLnNldFByb3BlcnR5SWZOb3ROdWxsKGluZm8sc2Vjb25kcywibVNlY29uZE9mTWludXRlIik7CiAgICAgICBUaW1lSW5mby5zZXRQcm9wZXJ0eUlmTm90TnVsbChpbmZvLG1pbGxpc2Vjb25kcywibVRob3VzYW5kdGhPZlNlY29uZCIpOwogICAgICAgIHJldHVybiBpbmZvOwogICAgfTsKCiAgICAvKioKICAgICAqCiAgICAgKiBzdGF0aWMgbWV0aG9kCiAgICAgKi8KICAgIFRpbWVJbmZvLnNldFByb3BlcnR5SWZOb3ROdWxsID0gZnVuY3Rpb24ob2JqZWN0LCB2YWx1ZSwgcHJvTmFtZSl7CiAgICAgICAgaWYodmFsdWUhPW51bGwpewogICAgICAgICAgICB2YXIgZCA9IE51bWJlcih2YWx1ZSk7CiAgICAgICAgICAgIGlmKCFpc05hTihkKSl7CiAgICAgICAgICAgICAgICBvYmplY3RbcHJvTmFtZV0gPSBkOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKCn0pKF8seGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5EYXRlSW5mbwogKiBAaW1wb3J0IHhmYWxpYi51dC5DbGFzcwogKiBAZmlsZU92ZXJ2aWV3IEEgd3JhcHBlciBjbGFzcyBmb3IgZGF0ZSByZWxhdGVkIGluZm9ybWF0aW9uLgogKiBAdmVyc2lvbiAwLjAuMQogKi8KCi8qKgogKiBAY29uc3RydWN0b3IKICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpIHsKICAgIHZhciBEYXRlSW5mbyA9IHhmYWxpYi51dC5EYXRlSW5mbyA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRpb25zKSB7CiAgICAgICAgICAgIGlmIChvcHRpb25zICYmICFvcHRpb25zLmlzUGFyc2luZ0NhbGwgKSB7IC8vIHNraXAgc2V0dGluZyBpbnRlcm5hbCB2YWx1ZXMgd2hlbiBjYWxsZWQgd2hpbGUgcGFyc2luZyBkYXRlIGZvcm1hdHMKICAgICAgICAgICAgICAgIHRoaXMuZGF0ZSA9IG5ldyBEYXRlKCk7CiAgICAgICAgICAgICAgICB0aGlzLl95ZWFyID0gdGhpcy5kYXRlLmdldEZ1bGxZZWFyKCk7CiAgICAgICAgICAgICAgICB0aGlzLl9tb250aCA9IHRoaXMuZGF0ZS5nZXRNb250aCgpICsgMTsKICAgICAgICAgICAgICAgIHRoaXMuX2RheSA9IHRoaXMuZGF0ZS5nZXREYXkoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBEYXRlSW5mby5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIGZvcm1hdE51bSA6IGZ1bmN0aW9uKG51bSwgZGlnaXRzKXsKICAgICAgICAgICAgaWYobnVtPDApCiAgICAgICAgICAgICAgICBudW0gPSAwOwogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYWRkaW5nKG51bSwgZGlnaXRzKTsKICAgICAgICB9LAoKICAgICAgICBnZXREYXRlIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0ZTsKICAgICAgICB9LAogICAgICAgIHNldERhdGUgOiBmdW5jdGlvbigpIHsKICAgICAgICAgIHRoaXMuZGF0ZSA9IG5ldyBEYXRlKHRoaXMuX3llYXIsdGhpcy5fbW9udGgtMSx0aGlzLl9kYXkpCiAgICAgICAgfSwKICAgICAgICBnZXRJU09EYXRlIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIGlzb0RhdGUgPSBbXTsKCiAgICAgICAgICAgIGlzb0RhdGUucHVzaCh0aGlzLmZvcm1hdE51bSh0aGlzLl95ZWFyLCA0KSk7CiAgICAgICAgICAgIGlzb0RhdGUucHVzaCgiLSIpOwogICAgICAgICAgICBpc29EYXRlLnB1c2godGhpcy5mb3JtYXROdW0odGhpcy5fbW9udGgsIDIpKTsKICAgICAgICAgICAgaXNvRGF0ZS5wdXNoKCItIik7CiAgICAgICAgICAgIGlzb0RhdGUucHVzaCh0aGlzLmZvcm1hdE51bSh0aGlzLl9kYXksIDIpKTsKCiAgICAgICAgICAgIHJldHVybiBpc29EYXRlLmpvaW4oIiIpOwogICAgICAgIH0sCgogICAgICAgIHllYXIgOiBmdW5jdGlvbih5KSB7CiAgICAgICAgICAgIGlmKHkgJiYgeSA+IDAgJiYgeSA8PSA5OTk5KQogICAgICAgICAgICAgICAgdGhpcy5feWVhciA9IHk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHRocm93ICJ1bmRlZmluZWQgeWVhciI7CiAgICAgICAgfSwKCiAgICAgICAgbW9udGggOiBmdW5jdGlvbihtKSB7CiAgICAgICAgICAgIGlmKG0gJiYgbT4wICYmIG0gPCAxMykgewogICAgICAgICAgICAgICB0aGlzLl9tb250aCA9IG07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgdGhyb3cgIkludmFsaWQgbW9udGggIiArIG07CiAgICAgICAgfSwKCiAgICAgICAgX2xlYXBZZWFyIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB5ZWFyID0gdGhpcy5feWVhcjsKICAgICAgICAgICAgcmV0dXJuIHllYXIgJSA0MDAgPT0gMCB8fCAoeWVhciAlIDEwMCAhPSAwICYmIHllYXIgJSA0ID09IDApOwogICAgICAgIH0sCgogICAgICAgIF9tYXhEYXRlIDogZnVuY3Rpb24obSkgewogICAgICAgICAgICAgIGlmKHRoaXMuX2xlYXBZZWFyKCkgJiYgbSA9PSAyKQogICAgICAgICAgICAgICAgIHJldHVybiAyOTsKICAgICAgICAgICAgICBlbHNlIHJldHVybiBEYXRlSW5mby5kYXRlc1ttLTFdOwogICAgICAgIH0sCgogICAgICAgIGRheSA6IGZ1bmN0aW9uKGQpIHsKICAgICAgICAgICAgaWYoZCAmJiBkID4gMCAmJiBkIDw9IHRoaXMuX21heERhdGUodGhpcy5fbW9udGggfHwgMCkpCiAgICAgICAgICAgICAgICB0aGlzLl9kYXkgPSBkOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB0aHJvdyAiSW52YWxpZCBEYXRlICIrIGQgKyAiIGZvciB0aGUgbW9udGggIisodGhpcy5fbW9udGgpOwogICAgICAgIH0sCgogICAgICAgIHZhbGlkYXRlIDogZnVuY3Rpb24oeSwgbSwgZCkgewogICAgICAgICAgICAgICAgdGhpcy55ZWFyKHkpOwogICAgICAgICAgICAgICAgdGhpcy5tb250aChtKTsKICAgICAgICAgICAgICAgIHRoaXMuZGF5KGQpOwogICAgICAgIH0KICAgIH0pOwoKICAgIERhdGVJbmZvLlBhcnNlSXNvU3RyaW5nID0gZnVuY3Rpb24oaXNvRGF0ZVN0ciwgbG9jYWxlKXsKCQl2YXIgaXNEYXRlUmVnZXhwID0gL14oXGR7NH0pKD86LT8oXGR7MSwyfSkoPzotPyhcZHsxLDJ9KSk/KT8oPzpUKChcZHsyfSk6KFxkezJ9KTooXGR7Mn0pKVopPyQvOwogICAgICAgIHZhciBtYXRjaCA9IGlzRGF0ZVJlZ2V4cC5leGVjKGlzb0RhdGVTdHIpOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoLmxlbmd0aCA+PSA0KXsKICAgICAgICAgICAgdmFyIGRhdGVJbmZvID0gbmV3IERhdGVJbmZvKCk7CiAgICAgICAgICAgIHZhciBkYXRlID0gbmV3IERhdGUoaXNvRGF0ZVN0cik7CiAgICAgICAgICAgIC8vIFRPRE8gLSBjaGVjayBpZiBkYXRlIGlzIGludmFsaWQuCiAgICAgICAgICAgIGlmKG1hdGNoWzRdICYmIGRhdGUgIT0gbnVsbCkgeyAvLyBpZiB0aW1lIGlzIGF2YWlsYWJsZSB0aGVuIHVzZSBkYXRlIG9iamVjdCBmb3IgY29udmVyc2lvbiBvdGhlcndpc2UgdXNlIHByZXZpb3VzIGFwcHJvYWNoIHRvIHN1cHBvcnQgaW52YWxpZCBkYXRlIGxpa2UgMjAxMi0xMC0xMDEsIDIwMTAtMDItMjkgZXRjIGZvciBSVEMgQ1EtNDIwMTI3NAogICAgICAgICAgICAgICAgZGF0ZUluZm8ueWVhcihkYXRlLmdldEZ1bGxZZWFyKCkpOwogICAgICAgICAgICAgICAgZGF0ZUluZm8ubW9udGgoZGF0ZS5nZXRNb250aCgpKzEpOwogICAgICAgICAgICAgICAgZGF0ZUluZm8uZGF5KGRhdGUuZ2V0RGF0ZSgpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgZGF0ZUluZm8ueWVhcihOdW1iZXIobWF0Y2hbMV0pKTsKICAgICAgICAgICAgICAgICAgICBkYXRlSW5mby5tb250aChOdW1iZXIobWF0Y2hbMl0pKTsKICAgICAgICAgICAgICAgICAgICBkYXRlSW5mby5kYXkoTnVtYmVyKG1hdGNoWzNdKSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBkYXRlSW5mby5zZXREYXRlKCk7CiAgICAgICAgICAgIHJldHVybiBkYXRlSW5mbzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9OwoKICAgIERhdGVJbmZvLlBhcnNlID0gZnVuY3Rpb24oZGF0ZVN0ciwgbG9jYWxlLCB2YWxpZGF0ZVdpdGhEZWZhdWx0UGF0dGVybnMpewogICAgICAgIGxvY2FsZSA9IGxvY2FsZSB8fCAiZW5fVVMiOwogICAgICAgIHZhciBwYXR0ZXJucyA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KGxvY2FsZSwiZGF0ZVBhdHRlcm5zIiksCiAgICAgICAgICAgIGlzb0RhdGUgPSB0aGlzLlBhcnNlSXNvU3RyaW5nKGRhdGVTdHIsIGxvY2FsZSk7CiAgICAgICAgaWYoIV8uaXNFbXB0eShpc29EYXRlKSkgewogICAgICAgICAgICByZXR1cm4gaXNvRGF0ZTsgIC8vIGluIGNhc2UgZWRpdCBwYXR0ZXJuIGlzIHByZXNlbnQsIGl0J2xsIGJlIHBhcnNlZCBieSB0aGUgd2lkZ2V0IGR1cmluZyBpbnB1dCBhbmQgcmV0dXJuIGFuIGlzbyBkYXRlIHN0cmluZy4KICAgICAgICB9CiAgICAgICAgLy9pZiBlZGl0IHBhdHRlcm4gaXMgcHJlc2VudCB0aGVuIGRvbid0IHRyeSB0byBtYXRjaCBpdCBmcm9tIGRlZmF1bHQgbG9jYWxlIHBhdHRlcm5zLgogICAgICAgIGlmKHZhbGlkYXRlV2l0aERlZmF1bHRQYXR0ZXJucyA9PT0gZmFsc2UpewogICAgICAgICAgICBfLmZpbmQocGF0dGVybnMsIGZ1bmN0aW9uKHBhdHRlcm4pIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgaXNvRGF0ZSA9IHhmYWxpYi51dC5QaWN0dXJlRm10LnBhcnNlRGF0ZShkYXRlU3RyLHBhdHRlcm4sbG9jYWxlKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gY2F0Y2goZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgaXNvRGF0ZSA9IGlzb0RhdGUgfHwgZGF0ZVN0cjsKICAgICAgICByZXR1cm4gRGF0ZUluZm8uUGFyc2VJc29TdHJpbmcoaXNvRGF0ZSk7CiAgICB9OwoKICAgIERhdGVJbmZvLmRhdGVzID0gWzMxLDI4LDMxLDMwLDMxLDMwLDMxLDMxLDMwLDMxLDMwLDMxXTsKICAgIERhdGVJbmZvLmRheXNPZldlZWsgPSBbIlN1bmRheSIsIk1vbmRheSIsIlR1ZXNkYXkiLCJXZWRuZXNkYXkiLCJUaHVyc2RheSIsIkZyaWRheSIsIlNhdHVyZGF5Il07Cn0pKF8seGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5QaWN0dXJlRW5naW5lCiAqIEBpbXBvcnQgeGZhbGliLnV0LlNjYW5uZXIKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBpcyBhIGZhY2FkZSB0byBhc3NlbWJseSBhbGwgY29tcG9uZW50cyB0b2dldGhlci4KICogQHZlcnNpb24gMC4wLjEKICovCihmdW5jdGlvbihfLHhmYWxpYikgewoKICAgIHZhciBQaWN0dXJlRW5naW5lID0geGZhbGliLnV0LlBpY3R1cmVFbmdpbmUgPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKCiAgICAgICAgX2xvb2t1cE5leHQ6IHhmYWxpYi51dC5TY2FubmVyLmxvb2t1cE5leHQsCgogICAgICAgIE1BWF9YRkFfUFJFQwk6IDgsCQkvLyBNYXggbm8uIG9mIGZyYWN0aW9uYWwgZGlnaXRzIGluIFhGQS4KICAgICAgICBNQVhfREJMX0RJRwk6MTgsCQkvLyBNYXggbm8uIG9mIHNpZ25pZmljYW50IGRpZ2l0cyBpbiBhIGRvdWJsZS4KICAgICAgICBNQVhfSU5UX0RJRwk6MTAsCQkvLyBNYXggbm8uIG9mIHNpZ25pZmljYW50IGRpZ2l0cyBpbiBhbiBpbnRlZ2VyLgogICAgICAgIE1BWF9EQkxfV0lEVEgJOjE1LAkJLy8gTWF4IHdpZHRoIGJlZm9yZSBwcmVjaXNpb24gbG9zcyBpbiBhIGRvdWJsZS4KICAgICAgICBJTlRFR1JBTF9GTVQgOiAgMCwKICAgICAgICBERUNJTUFMX0ZNVCA6IDEsCiAgICAgICAgQ1VSUkVOQ1lfRk1UIDogMiwKICAgICAgICBQRVJDRU5UX0ZNVCA6IDMsCgogICAgICAgIHBhcnNlRGF0ZSA6IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLCBsb2NhbGUpewogICAgICAgICAgICByZXR1cm4gdGhpcy5fYWNjZXB0VmlzaXRvcihuZXcgeGZhbGliLnV0LkRhdGVQYXJzaW5nVmlzaXRvcih7anNvbk1vZGVsOntfc1BpY3R1cmU6c1BpY3R1cmUsX2RhdGFTdHJpbmc6c1NvdXJjZSxfbG9jYWxlOnRoaXMuanNvbk1vZGVsLmxvY2FsZX19KSk7CiAgICAgICAgfSwKCiAgICAgICAgZm9ybWF0RGF0ZSA6IGZ1bmN0aW9uKGREYXRlLCBzUGljdHVyZSl7CiAgICAgICAgICAgIHZhciB2YWxpZGF0ZVdpdGhEZWZhdWx0UGF0dGVybnMgPSB0eXBlb2Ygc1BpY3R1cmUgIT09ICd1bmRlZmluZWQnOwogICAgICAgICAgICB2YXIgZGF0ZUluZm8gPSB4ZmFsaWIudXQuRGF0ZUluZm8uUGFyc2UoZERhdGUsIHRoaXMuanNvbk1vZGVsLmxvY2FsZSwgdmFsaWRhdGVXaXRoRGVmYXVsdFBhdHRlcm5zKTsKICAgICAgICAgICAgaWYoZGF0ZUluZm8gPT0gbnVsbCl7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYWNjZXB0VmlzaXRvcihuZXcgeGZhbGliLnV0LkRhdGVGb3JtYXR0aW5nVmlzaXRvcih7anNvbk1vZGVsOntfc1BpY3R1cmU6c1BpY3R1cmUsX2RhdGVJbmZvOmRhdGVJbmZvLF9sb2NhbGU6dGhpcy5qc29uTW9kZWwubG9jYWxlfX0pKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHBhcnNlVGltZSA6IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2FjY2VwdFZpc2l0b3IobmV3IHhmYWxpYi51dC5UaW1lUGFyc2luZ1Zpc2l0b3Ioe2pzb25Nb2RlbDp7X3NQaWN0dXJlOnNQaWN0dXJlLF9kYXRhU3RyaW5nOnNTb3VyY2V9fSkpOwogICAgICAgIH0sCgogICAgICAgIGZvcm1hdFRpbWUgOiBmdW5jdGlvbihkRGF0ZSwgc1BpY3R1cmUpewogICAgICAgICAgICB2YXIgdGltZUluZm8gPSB4ZmFsaWIudXQuVGltZUluZm8uUGFyc2UoZERhdGUsIHRoaXMuanNvbk1vZGVsLmxvY2FsZSk7CiAgICAgICAgICAgIGlmKHRpbWVJbmZvID09IG51bGwpewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2FjY2VwdFZpc2l0b3IobmV3IHhmYWxpYi51dC5UaW1lRm9ybWF0dGluZ1Zpc2l0b3Ioe2pzb25Nb2RlbDp7X3NQaWN0dXJlOnNQaWN0dXJlLF90aW1lSW5mbzp0aW1lSW5mb319KSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBwYXJzZVRleHQgOiBmdW5jdGlvbihzU291cmNlLCBzUGljdHVyZSl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hY2NlcHRWaXNpdG9yKG5ldyB4ZmFsaWIudXQuVGV4dFBhcnNpbmdWaXNpdG9yKHtqc29uTW9kZWw6e19zUGljdHVyZTpzUGljdHVyZSxfZGF0YVN0cmluZzpzU291cmNlfX0pKTsKICAgICAgICB9LAoKICAgICAgICBmb3JtYXRUZXh0IDogZnVuY3Rpb24oc1NvdXJjZSwgc1BpY3R1cmUsYlJlbGF4ZWQpewogICAgICAgICAgICByZXR1cm4gdGhpcy5fYWNjZXB0VmlzaXRvcihuZXcgeGZhbGliLnV0LlRleHRGb3JtYXR0aW5nVmlzaXRvcih7anNvbk1vZGVsOntfc1BpY3R1cmU6c1BpY3R1cmUsX3RleHQ6c1NvdXJjZSxyZWxheGVkOmJSZWxheGVkfX0pKTsKICAgICAgICB9LAoKICAgICAgICBwYXJzZU51bWVyaWMgOiBmdW5jdGlvbihzU291cmNlLCBzUGljdHVyZSl7CiAgICAgICAgICAgIHZhciB2aXNpdG9yID0gbmV3IHhmYWxpYi51dC5OdW1QYXJzaW5nVmlzaXRvcih7anNvbk1vZGVsOntfc1BpY3R1cmU6c1BpY3R1cmUsX2RhdGFTdHJpbmc6c1NvdXJjZSxfbG9jYWxlOnRoaXMuanNvbk1vZGVsLmxvY2FsZX19KTsgLy8gVE9ETyA6IElzIGxvY2FsZSByZXF1aXJlZAogICAgICAgICAgICB2aXNpdG9yLnBhcnNlKCk7CiAgICAgICAgICAgIHJldHVybiB2aXNpdG9yLmdldFJlc3VsdCgpOwogICAgICAgIH0sCgogICAgICAgZm9ybWF0TnVtZXJpYyA6IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLGxvY2FsZSxiUmVsYXhlZCxiRm9ybWF0TnVtYmVyRnJvbWFzRGVmYXVsdFBDKXsKCiAgICAgICAgICAgICB2YXIgc0Zvcm1hdFBpY3R1cmUgPXNQaWN0dXJlOwogICAgICAgICAgICAgaWYoIGJSZWxheGVkICYmIGJGb3JtYXROdW1iZXJGcm9tYXNEZWZhdWx0UEMpewogICAgICAgICAgICAgICAgIHNGb3JtYXRQaWN0dXJlID0gdGhpcy5nZXROdW1iZXJGb3JtYXQoc1BpY3R1cmUsMSwge2Zvcm1hdE9wdGlvbjogIldJVEhfR1JPVVBJTkdTIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicHJlY2lzaW9uIiAgOiB0aGlzLmdldE51bWJlclByZWNpc2lvbihzU291cmNlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndpZHRoIiAgICAgIDogc1NvdXJjZS5sZW5ndGgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIHJldHVybiB0aGlzLl9hY2NlcHRWaXNpdG9yKG5ldyB4ZmFsaWIudXQuTnVtRm9ybWF0dGluZ1Zpc2l0b3Ioe2pzb25Nb2RlbDp7X3NQaWN0dXJlOnNGb3JtYXRQaWN0dXJlLF9sb2NhbGU6dGhpcy5qc29uTW9kZWwubG9jYWxlfSx0ZXh0OnNTb3VyY2V9KSk7CiAgICAgICAgfSwKCiAgICAgICAgX2FjY2VwdFZpc2l0b3IgOiBmdW5jdGlvbih2aXNpdG9yKXsKICAgICAgICAgICAgdGhpcy5fc2NhblBhdHRlcm4odmlzaXRvcik7CiAgICAgICAgICAgIHJldHVybiB2aXNpdG9yLmdldFJlc3VsdCgpOwogICAgICAgIH0sCgogICAgICAgIF9zY2FuUGF0dGVybiA6IGZ1bmN0aW9uKHZpc2l0b3IpewogICAgICAgICAgICB2YXIgcGF0UG9zID0gMDsKICAgICAgICAgICAgdmFyIHNQaWN0dXJlID0gdmlzaXRvci5nZXRQaWN0dXJlKCk7CiAgICAgICAgICAgIGZvcih2YXIgdG9rZW4gPSB0aGlzLl9sb29rdXBOZXh0KHNQaWN0dXJlLCBwYXRQb3MsIHZpc2l0b3IuYWNjZXB0UGF0dGVybkNoYXIpOyB0b2tlbiAhPSBudWxsOyAgKXsKICAgICAgICAgICAgICAgIHZpc2l0b3IuY29uc3VtZSh0b2tlbik7CiAgICAgICAgICAgICAgICBwYXRQb3MgPSBwYXRQb3MgKyB0b2tlbi5sZW47CiAgICAgICAgICAgICAgICB0b2tlbiA9IHRoaXMuX2xvb2t1cE5leHQoc1BpY3R1cmUsIHBhdFBvcywgdmlzaXRvci5hY2NlcHRQYXR0ZXJuQ2hhcik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgIC8qKgogICAgICAgICAgKiBSZW1vdmVzIG4gYnl0ZXMgZnJvbSB0aGlzIHN0cmluZyBzdGFydGluZyBhdCBwb3NpdGlvbiBuT2Zmc2V0LgogICAgICAgICAqCiAgICAgICAgICAqIEBwYXJhbSBuT2Zmc2V0IC0gc3RhcnQgcG9zaXRpb24gZm9yIHRoZSByZW1vdmUKICAgICAgICAgICogQHBhcmFtIG5MZW5ndGggLSB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVtb3ZlCiAgICAgICAgICAqIEByZXR1cm4gVGhpcyBzdHJpbmcKICAgICAgICAgICovCgogICAgICAgICBfc3dhbGxvdyA6IGZ1bmN0aW9uKHNTdHJpbmcgLCBuT2Zmc2V0LCBuTGVuVG9Td2FsbG93KQogICAgICAgICB7CiAgICAgICAgICAgICBpZihfLmlzRW1wdHkoc1N0cmluZykgfHwgbkxlblRvU3dhbGxvdyA9PTApewogICAgICAgICAgICAgICAgIHJldHVybiBzU3RyaW5nOwogICAgICAgICAgICAgfQoKICAgICAgICAgICAgIGlmKCAobk9mZnNldCArIG5MZW5Ub1N3YWxsb3cpPiBzU3RyaW5nLmxlbmd0aCApIHsKICAgICAgICAgICAgICAgICBuTGVuVG9Td2FsbG93ID0gKG5PZmZzZXQgKyBuTGVuVG9Td2FsbG93KSAtIHNTdHJpbmcubGVuZ3RoOwogICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgc3ViU3RyID0gc1N0cmluZy5zdWJzdHIoMCxuT2Zmc2V0KSArIHNTdHJpbmcuc3Vic3RyKG9mZnNldCArIG5MZW5Ub1N3YWxsb3cpOwoKICAgICAgICAgICAgIHJldHVybiBzdWJTdHIKICAgICAgICAgfSwKICAgICAgICAgLyoqCiAgICAgICAgICogUmVwbGFjZSBzb21lIHBvcnRpb24gb2Ygb25lIHN0cmluZyB3aXRoIGFub3RoZXIgU3RyaW5nLgogICAgICAgICAgKiBAcGFyYW0gc1N0cmluZyAtIHRoZSBTdHJpbmcgd2hlcmUgaXQgaGFzIHRvIGJlIHJlcGxhY2VkLgogICAgICAgICAgKiBAcGFyYW0gc1JlcGxhY2VtZW50IC0gdGhlIHJlcGxhY2VtZW50IHN0cmluZy4KICAgICAgICAgICogQHBhcmFtIG5PZmZzZXQgLSBzdGFydCBwb3NpdGlvbiBmb3IgdGhlIHJlcGxhY2VtZW50LiBEZWZhdWx0IHZhbHVlID0gMC4KICAgICAgICAgICogQHBhcmFtIG5DdXRMZW5ndGggLSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHJlbW92ZSBmcm9tIHRoZQogICAgICAgICAgKiBvcmlnaW5hbCBzdHJpbmcuCiAgICAgICAgICAqLwoKICAgICAgICAgX3JlcGxhY2VBbGwgOiBmdW5jdGlvbihzU3RyaW5nICxzUmVwbGFjZW1lbnQgLCBuT2Zmc2V0ICxuQ3V0bGVuZ3RoKSB7CiAgICAgICAgICAgICByZXR1cm4gc1N0cmluZy5zdWJzdHIoMCxuT2Zmc2V0KSArIHNSZXBsYWNlbWVudCAgKyBzU3RyaW5nLnN1YnN0cihuT2Zmc2V0ICsgbkN1dGxlbmd0aCkKICAgICAgICAgfSwKCiAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAvLyBTa2lwT3ZlcgogICAgICAgICAvLwogICAgICAgICAvLyBTY2FuIHRoaXMgc3RyaW5nIGZvciB0aGUgZmlyc3QgYnl0ZSBvZiB0aGUgY2hhcmFjdGVyIG5vdCBpbiB0aGUgZ2l2ZW4gc2V0LgogICAgICAgICAvLyBTaW1pbGFyIHRvIHN0cnNwbigpLgogICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgX3NraXBPdmVyIDogZnVuY3Rpb24oZnJvbVN0cmluZyxzU2tpcCwgbk9mZnNldCkKICAgICAgICAgewogICAgICAgICAgICAgLy8gc3RhcnRpbmcgYXQgdGhlIG9mZnNldCBwb3NpdGlvbiwgc2NhbiB0aGUgY2hhcmFjdGVycyBpbiB0aGlzIHN0cmluZwogICAgICAgICAgICAgLy8gdW50aWwgaXQgZG9lcyBub3QgbWF0Y2ggYW55IG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBnaXZlbiBzZXQuCiAgICAgICAgICAgIHZhciBuQ2hhcnNTa2lwcGVkID0gbk9mZnNldDsKICAgICAgICAgICAgIHZhciBpID0gMDsKICAgICAgICAgICAgIHdoaWxlIChuQ2hhcnNTa2lwcGVkIDwgZnJvbVN0cmluZy5sZW5ndGgpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgaSA9IG5DaGFyc1NraXBwZWQ7CiAgICAgICAgICAgICAgICAgaWYgKHNTa2lwLmluZGV4T2YoZnJvbVN0cmluZ1tpXSkgPT0tMSkgewogICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgaSsrOwogICAgICAgICAgICAgICAgIG5DaGFyc1NraXBwZWQgPSBpOwogICAgICAgICAgICAgfQoKICAgICAgICAgICAgIHJldHVybiBuQ2hhcnNTa2lwcGVkIC0gbk9mZnNldDsKICAgICAgICAgfSwKCiAgICAgICAgIC8qCiAgICAgICAgICAqIEdldCB0aGUgbnVtZXJpYyBmb3JtYXQgaW4gdGhlIGdpdmVuIHN0eWxlLgogICAgICAgICAgKiBAcGFyYW0gc3R5bGUgaW4gdGhlIHJhbmdlIG9mIHZhbHVlcyAwLTIsCiAgICAgICAgICAqIHdoZXJlICgwID0gaW50ZWdyYWwsIDEgPSBkZWNpbWFsLCAyID0gY3VycmVuY3kpLgogICAgICAgICAgKiBAcGFyYW0gb3B0aW9uIGluIHRoZSBzZXQgb2YgZm9ybWF0IG9wdGlvbnM6CiAgICAgICAgICAqLwogICAgICAgICBnZXROdW1iZXJGb3JtYXQgOiBmdW5jdGlvbihmb3JtYXQgLCBzdHlsZSwgb3B0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgIGlmIChzdHlsZSA8IHRoaXMuSU5URUdSQUxfRk1UIHx8IHRoaXMuUEVSQ0VOVF9GTVQgPCBzdHlsZSkgewogICAgICAgICAgICAgICAgIHN0eWxlID0gdGhpcy5ERUNJTUFMX0ZNVDsKICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICB2YXIgc0Zvcm1hdCA9IGZvcm1hdDsKCiAgICAgICAgICAgICAvLwogICAgICAgICAgICAgLy8gVXNlIGFueSBhbHRlcm5hdGUgcGFydCBiZWNhdXNlIHRoZXkgaGFuZGxlIG5lZ2F0aXZlIHZhbHVlcy4KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICB2YXIgIG5CYXIgPSAwOwogICAgICAgICAgICAgaWYgKChuQmFyID0gc0Zvcm1hdC5pbmRleE9mKCd8JykpICE9IC0xKSB7CiAgICAgICAgICAgICAgICAgc0Zvcm1hdCA9IHRoaXMuX3N3YWxsb3coc0Zvcm1hdCwgMCwgbkJhciArIDEpOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgLy8KICAgICAgICAgICAgIC8vIERldGVybWluZSBwb3NpdGlvbiBvZiByYWRpeCAob3IgYW55dGhpbmcgbGlrZSBpdCkKICAgICAgICAgICAgIC8vIGFuZCB0aGUgcmVwbGljYXRpbmcgcGFydCBvZiB0aGUgcGF0dGVybiwgaS5lLiwgZnJvbQogICAgICAgICAgICAgLy8gdGhlIHNlcGFyYXRvciB0byB0aGlzIHJhZGl4LgogICAgICAgICAgICAvLwogICAgICAgICAgICAgdmFyIG5Eb3Q7CiAgICAgICAgICAgICBpZiAoIChuRG90ID0gc0Zvcm1hdC5pbmRleE9mKCcuJykpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgaWYgKChuRG90ID0gc0Zvcm1hdC5pbmRleE9mKCd2JykpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgIGlmICgobkRvdCA9IHNGb3JtYXQuaW5kZXhPZignVicpKSA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChuRG90ID0gc0Zvcm1hdC5pbmRleE9mKCdFJykpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChuRG90ID0gc0Zvcm1hdC5pbmRleE9mKCcgJykpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobkRvdCA9IHNGb3JtYXQuaW5kZXhPZignJScpKSA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkRvdCA9IHNGb3JtYXQubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgICAgaWYgKG5Eb3QpIHsKICAgICAgICAgICAgICAgICBpZiAodGhpcy5fc2tpcE92ZXIoc0Zvcm1hdCwiODl6WiIsIG5Eb3QgLSAxKSAhPSAxKSB7CiAgICAgICAgICAgICAgICAgICAgIG5Eb3QgPSBzRm9ybWF0Lmxlbmd0aDsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICB2YXIgc1paWjsKICAgICAgICAgICAgIHZhciBuWmVkOwogICAgICAgICAgICAgaWYgKCAoblplZCA9IHNGb3JtYXQuaW5kZXhPZigieiwiKSkgIT0gLTEpIHsKICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgIC8vIFdhdHNvbiAxMjMwNzY4LiAgSGFuZGxlIGxvY2FsZXMsIGxpa2UgSW5kaWEsIHRoYXQgaGF2ZQogICAgICAgICAgICAgICAgIC8vIHBpY3R1cmVzIHdpdGggbW9yZSB0aGFuIG9uZSBncm91cGluZyBzeW1ib2wuCiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgIHZhciBuU2VwID0gbkRvdDsKICAgICAgICAgICAgICAgICB2YXIgbkNvbW1hOwogICAgICAgICAgICAgICAgIGlmICgobkNvbW1hID0gc0Zvcm1hdC5pbmRleE9mKCcsJywgblplZCArIDIpKSAhPS0xKSB7CiAgICAgICAgICAgICAgICAgICAgblNlcCA9IG5Db21tYTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgaWYgKG5TZXAgPiBuWmVkICsgMikgewogICAgICAgICAgICAgICAgICAgICBzWlpaID0gQXJyYXkoblNlcCAtIG5aZWQpLmpvaW4oJ3onKTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgIHNaWlogPSBBcnJheSgxKS5qb2luKCd6Jyk7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBuWmVkID0gMDsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAvLyBJZiBub24taW50ZWdyYWwgc3R5bGVzIFRoZW4gZGV0ZXJtaW5lIHdpZHRoIGFuZCBwcmVjaXNpb24uCiAgICAgICAgICAgICAvLwogICAgICAgICAgICAgdmFyIG5QcmVjID0gMDsKICAgICAgICAgICAgIHZhciBuV2lkdGggPSB0aGlzLk1BWF9JTlRfRElHOwogICAgICAgICAgICAgaWYgKHN0eWxlICE9IHRoaXMuSU5URUdSQUxfRk1UKSB7CiAgICAgICAgICAgICAgICAgblByZWMgPSBvcHRpb24ucHJlY2lzaW9uOyAvLyAob3B0aW9uID4+IDgpICYgMHhmZjsKICAgICAgICAgICAgICAgICB2YXIgdHJpbSA9ICgoblByZWMgJiAweDgwKSA9PSAwKTsKICAgICAgICAgICAgICAgICBuUHJlYyAmPSAweDdmOwogICAgICAgICAgICAgICAgIGlmIChuUHJlYyA9PSAweDdmKSB7CiAgICAgICAgICAgICAgICAgICAgIG5QcmVjID0gdGhpcy5fc2tpcE92ZXIoc0Zvcm1hdCwgIjg5eloiLCBuRG90ICsgMSk7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIGlmICgob3B0aW9uLndpZHRoKSAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICAgbldpZHRoID0gb3B0aW9uLndpZHRoOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgbldpZHRoID0gdGhpcy5NQVhfREJMX0RJRzsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAvLyBGaXggZm9yIFdhdHNvbiAxMjI5NDIzLiAgSWYgdGhlIGxvY2FsZSdzIGZvcm1hdCBjb250YWlucwogICAgICAgICAgICAgICAgIC8vIGFueSBzaWduIHBpY3R1cmVzIFRoZW4gd2lkZW4gYWNjb3JkaW5nbHkuICBBbHNvIHdpZGVuIGlmCiAgICAgICAgICAgICAgICAgLy8gcHJlY2lzaW9uIG9mIGxvY2FsZSdzIHBpY3R1cmUgZm9ybWF0IGlzIGdyZWF0ZXIgdGhhbiByZXF1ZXN0ZWQuCiAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICBpZiAoc0Zvcm1hdC5pbmRleE9mKCdzJykhPS0xKSB7CiAgICAgICAgICAgICAgICAgICAgIG5XaWR0aCArPSAxOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICBpZiAoc0Zvcm1hdC5pbmRleE9mKCcoJykhPS0xKSB7CiAgICAgICAgICAgICAgICAgICAgIG5XaWR0aCArPSAxOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICBpZiAoc0Zvcm1hdC5pbmRleE9mKCcpJykgIT0tMSkgewogICAgICAgICAgICAgICAgICAgICBuV2lkdGggKz0gMTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgbkZtdFByZWMgPSB0aGlzLl9za2lwT3ZlcihzRm9ybWF0LCI4OXpaIiwgbkRvdCArIDEpOwogICAgICAgICAgICAgICAgIGlmICgwIDwgblByZWMgJiYgblByZWMgPCBuRm10UHJlYykgewogICAgICAgICAgICAgICAgICAgICBuV2lkdGggKz0gbkZtdFByZWMgLSBuUHJlYzsKICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgLy8gUGFyZSBkb3duIHRoZSBwcmVjaXNpb24gaWYgdGhlIHdpZHRoIGlzIGJpZyBlbm91Z2ggdG8geWllbGQKICAgICAgICAgICAgICAgICAvLyBJRUVFIDc1NCA2NC1iaXQgZG91YmxlIHByZWNpc2lvbiBlcnJvcnMsIHdoaWNoIGFwcGVhcnMgdG8gYmUKICAgICAgICAgICAgICAgICAvLyBhbnl0aGluZyBvdmVyIDE0IHNpZ25pZmljYW50IGRpZ2l0cy4KICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgIGlmICh0cmltICYmIG5QcmVjID4gMCAmJiBuV2lkdGggPiBuUHJlYykgewogICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgICAvLyBGaXggZm9yIFdhdHNvbiAxMjExNDgxLiAgSWYgdGhlIGdpdmVuIHByZWNpc2lvbiBpcyBsZXNzCiAgICAgICAgICAgICAgICAgICAgIC8vIHRoYW4gd2hhdCB0aGUgbG9jYWxlJ3MgZm9ybWF0IGRpY3RhdGVzIHRoZW4gd2lkZW4gdGhlIGdpdmVuCiAgICAgICAgICAgICAgICAgICAgIC8vIHdpZHRoLgogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgIGlmIChuUHJlYyA8PSBzRm9ybWF0Lmxlbmd0aCAtIDEgLSBuRG90KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICBuV2lkdGggKz0gc0Zvcm1hdC5sZW5ndGggLSAxIC0gbkRvdCAtIG5QcmVjOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSBuV2lkdGggLSAxOyBpID4gdGhpcy5NQVhfREJMX1dJRFRIOyBpLS0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOZXZlciBwYXJlIGRvd24gdGhlIHByZWNpc2lvbiBiZWxvdyB3aGF0IHRoZSBsb2NhbGUncwogICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9ybWF0IGRpY3RhdGVzLgogICAgICAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuUHJlYyA8PSBzRm9ybWF0Lmxlbmd0aCAtIDEgLSBuRG90KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICBuUHJlYy0tOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgICAgLy9XYXRzb24gMTQ4MzY3NSAtIElmIHRoZSBsb2NhbGUncyBmb3JtYXQgY29udGFpbnMKICAgICAgICAgICAgIC8vIGEgZG9sbGFyIHNpZ24gb3IgYSBzcGFjZSB0aGVuIHdpZGVuIGFjY29yZGluZ2x5LgogICAgICAgICAgICAgaWYgKHN0eWxlID09IHRoaXMuQ1VSUkVOQ1lfRk1UKSB7CiAgICAgICAgICAgICAgICAgaWYgKHNGb3JtYXQuaW5kZXhPZignJCcpIT0tMSkgewogICAgICAgICAgICAgICAgICAgICBuV2lkdGgrKzsKICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIGlmIChzRm9ybWF0LmluZGV4T2YoJyAnKSE9LTEpIHsKICAgICAgICAgICAgICAgICAgICAgbldpZHRoICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CgogICAgICAgICAgICAgLy8KICAgICAgICAgICAgIC8vIElmIHBlcmNlbnQgc3R5bGUgd2FzIHdhbnRlZCBUaGVuIHRydW5jYXRlIGFmdGVyIHRoZSBwZXJjZW50IGNoYXJhY3Rlci4KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICBpZiAoc3R5bGUgPT0gdGhpcy5QRVJDRU5UX0ZNVCkgewogICAgICAgICAgICAgICAgIHZhciBuVHJpbSA9IHRoaXMuX3NraXBPdmVyKHNGb3JtYXQsIjg5eloiLCBuRG90ICsgMSk7CiAgICAgICAgICAgICAgICAgc0Zvcm1hdCA9IHRoaXMuX3JlcGxhY2VBbGwoc0Zvcm1hdCwiIixuVHJpbSwwKQogICAgICAgICAgICAgICAgIC8vc0Zvcm1hdC5SZXBsYWNlKGpmU3RyaW5nOjpFbXB0eVN0cmluZygpLCBuRG90ICsgMSwgblRyaW0pOwoKICAgICAgICAgICAgICAgICAvL1dhdHNvbiAxNDgzNjc1IC0gSWYgdGhlIGxvY2FsZSdzIGZvcm1hdCBjb250YWlucwogICAgICAgICAgICAgICAgIC8vIGEgcGVyY2VudCBzaWduIHRoZW4gd2lkZW4gYWNjb3JkaW5nbHkuCiAgICAgICAgICAgICAgICAgaWYgKHNGb3JtYXQuaW5kZXhPZignJScpIT0tMSkgewogICAgICAgICAgICAgICAgICAgICBuV2lkdGgrKzsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICAvLwogICAgICAgICAgICAgLy8gRWxzZSBpZiBpbnRlZ3JhbCBzdHlsZSB3YXMgd2FudGVkIFRoZW4gdHJ1bmNhdGUgYXQgdGhlIHJhZGl4IGNoYXJhY3Rlci4KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAvLwogICAgICAgICAgICAgLy8gSWYgaW50ZWdyYWwgc3R5bGUgd2FzIHdhbnRlZCBUaGVuIHRydW5jYXRlIGF0IHRoZSByYWRpeCBjaGFyYWN0ZXIuCiAgICAgICAgICAgICAvLwogICAgICAgICAgICAgZWxzZSBpZiAoc3R5bGUgPT0gdGhpcy5JTlRFR1JBTF9GTVQgfHwgblByZWMgPT0gMCl7Ly8gJiYgb3B0aW9uLmZvcm1hdE9wdGlvbiA9PSAiV0lUSE9VVF9SQURJWCIpIHsKICAgICAgICAgICAgICAgICB2YXIgblRyaW0gPSB0aGlzLl9za2lwT3ZlcihzRm9ybWF0LCI4OXpaIiwgbkRvdCArIDEpOwogICAgICAgICAgICAgICAgIHNGb3JtYXQgPSB0aGlzLl9yZXBsYWNlQWxsKHNGb3JtYXQsIiIsbkRvdCxuVHJpbSsxKTsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAvLyBPdGhlcndpc2UgZm9yIGRlY2ltYWwgYW5kIGN1cnJlbmN5IHN0eWxlcyBEbwogICAgICAgICAgICAgLy8gcmVwbGFjZSBmcmFjdGlvbmFsICd6JyBwaWN0dXJlcyB3aXRoICc4J3MgdG8gcmVxdWVzdGVkIHByZWNpc2lvbiwKICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICBlbHNlIGlmIChvcHRpb24uZm9ybWF0T3B0aW9uID09ICJXSVRIX0VJR0hUUyIpIHsKICAgICAgICAgICAgICAgICB2YXIgbkVpZ2h0ID0gbkRvdCArIDE7CiAgICAgICAgICAgICAgICAgd2hpbGUgKChuRWlnaHQgPXNGb3JtYXQuaW5kZXhPZigneicpKSE9LTEpIHsKICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVwbGFjZUFsbChzRm9ybWF0LCAnOCcsIG5FaWdodCwnOCcubGVuZ3RoKTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgd2hpbGUgKHNGb3JtYXQuTGVuZ3RoKCkgLSBuRG90IDw9IG5QcmVjKSB7CiAgICAgICAgICAgICAgICAgICAgIHNGb3JtYXQgPSB0aGlzLl9yZXBsYWNlQWxsKHNGb3JtYXQsICI4IiwgbkRvdCArIDEsIDApOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgIH0KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAvLyBPciByZXBsYWNlIGZyYWN0aW9uYWwgJzknIHBpY3R1cmVzIHdpdGggJ3oncyB0byByZXF1ZXN0ZWQgcHJlY2lzaW9uCiAgICAgICAgICAgICAvLyBXYXRzb24gMTMyMjg1MCAtIGFkZCBvcHRpb24gdG8ga2VlcCBuaW5lcywgcHJldmlvdXNseSB0aGlzIGZ1bmN0aW9uCiAgICAgICAgICAgICAvLyB3b3VsZCBmb3JjZSBmcmFjLiBkaWdpdHMgdG8gYmUgZWl0aGVyIHoncyBvciA4J3Mgd2l0aCBubyBvcHRpb24gZm9yIDkncy4KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICBlbHNlIGlmICgob3B0aW9uLmZvcm1hdE9wdGlvbikgPT0gIldJVEhfWkVEUyIgJiYgISgob3B0aW9uLmZvcm1hdE9wdGlvbikgPT0gIktFRVBfTklORVMiKSkgewogICAgICAgICAgICAgICAgIHZhciBuTmluZSA9IG5Eb3QgKyAxOwogICAgICAgICAgICAgICAgIHdoaWxlICgobk5pbmUgPSBzRm9ybWF0LmluZGV4T2YoJzknKSkhPS0xKSB7CiAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlcGxhY2VBbGwoc0Zvcm1hdCwgJ3onLCBuTmluZSwxKTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgd2hpbGUgKHNGb3JtYXQuTGVuZ3RoKCkgLSBuRG90IDw9IG5QcmVjKSB7CiAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlcGxhY2VBbGwoc0Zvcm1hdCwgInoiLCBuRG90ICsgMSwgMCk7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgICAgLy8KICAgICAgICAgICAgIC8vIFJlcGxpY2F0ZSBzZWN0aW9uIGZyb20gc2VwYXJhdG9yIHRvIHJhZGl4IHRvIHJlcXVlc3RlZCB3aWR0aC4KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICBpZiAoIXNaWlopIHsKICAgICAgICAgICAgICAgICBzWlpaID0gInoiOwogICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICgob3B0aW9uLmZvcm1hdE9wdGlvbikgPT0gIldJVEhPVVRfR1JPVVBJTkdTIiApIHsKICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgIC8vIFdhdHNvbiAxMjMwNzY4LiAgSGFuZGxlIGxvY2FsZXMsIGxpa2UgSW5kaWEsIHRoYXQgaGF2ZQogICAgICAgICAgICAgICAgIC8vIHBpY3R1cmVzIHdpdGggbW9yZSB0aGFuIG9uZSBncm91cGluZyBzeW1ib2wuCiAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICB2YXIgbkNvbW1hID0gblplZCArIDEgOwogICAgICAgICAgICAgICAgIHRoaXMuX3JlcGxhY2VBbGwoc0Zvcm1hdCwgJ3onICxuQ29tbWEsMSk7CiAgICAgICAgICAgICAgICAgd2hpbGUgKCBuQ29tbWEhPSAtMSAmJiAobkNvbW1hIDwgbkRvdCkpIHsKICAgICAgICAgICAgICAgICAgICAgbkNvbW1hID0gc0Zvcm1hdC5pbmRleE9mKCcsJyk7CiAgICAgICAgICAgICAgICAgICAgIHNGb3JtYXQgPSB0aGlzLl9yZXBsYWNlQWxsKHNGb3JtYXQsJ3onLG5Db21tYSwxKTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICBlbHNlIGlmICgob3B0aW9uLmZvcm1hdE9wdGlvbiA9PSAiV0lUSF9HUk9VUElOR1MiKSkgewogICAgICAgICAgICAgICAgIHNaWlogPSB0aGlzLl9yZXBsYWNlQWxsKHNaWlosJywnLDAsMSk7CiAgICAgICAgICAgICAgICAgbldpZHRoICs9IChuV2lkdGggKyBzWlpaLmxlbmd0aCkgLyBzWlpaLmxlbmd0aDsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIHdoaWxlIChzRm9ybWF0Lmxlbmd0aCA8IG5XaWR0aCkgewogICAgICAgICAgICAgICAgIHNGb3JtYXQgPSB0aGlzLl9yZXBsYWNlQWxsKHNGb3JtYXQsIHNaWlosIG5aZWQgKyAxLCAwKTsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIHJldHVybiBzRm9ybWF0OwogICAgICAgICB9LAoKICAgICAgICAgLyoqCiAgICAgICAgICAqIEdldCB0aGUgZGVjaW1hbCBwcmVjaXNpb24gb2YgdGhlIGdpdmVuIG51bWVyaWMgc3RyaW5nLgogICAgICAgICAgKiBAcmV0dXJuIHRoZSBkZWNpbWFsIHByZWNpc2lvbiBvciAwIGZvciBpbnRlZ3JhbCB2YWx1ZXMuCiAgICAgICAgICAqLwogICAgICAgICBnZXROdW1iZXJQcmVjaXNpb246IGZ1bmN0aW9uKHNWYWwpCiAgICAgICAgIHsKICAgICAgICAgICAgIHZhciBuUmFkaXggPSAwOwogICAgICAgICAgICAgdmFyIGkgPSAtMTsKICAgICAgICAgICAgIC8vIFJlYXNvbiBmb3Igbm90IHVzaW5nIHRoZSBjb21tZW50ZWQgbGluZS4gV2UgYXJlIGFsd2F5cyBzdG9yaW5nIHRoZSB2YWx1ZSBpbiBtb2RlbCB3aXRoIC4gYXMgZGVjaW1hbCBzZXBhcmF0b3IKICAgICAgICAgICAgIC8vIFBhc3NpbmcgZmllbGQgbG9jYWxlLyBicm93c2VyIGxvY2FsZSB3b3VsZCBsZWFkIHRvIHByZWNpc2lvbiB3aWR0aCBiZWluZyB6ZXJvIGZvciBub24tZW5nbGlzaCBsb2NhbGVzIHdoZXJlCiAgICAgICAgICAgICAvLyBkZWNpbWFsIHNlcGFyYXRlciBtYXkgYmUgZGlmZmVyZW50LgogICAgICAgICAgICAgLy8gdmFyIHJJbmRleCA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KHRoaXMuanNvbk1vZGVsLmxvY2FsZSwibnVtYmVyU3ltYm9scyIpLmRlY2ltYWw7CiAgICAgICAgICAgICAvLyBzbyBoYXJkY29kaW5nIC4gZm9yIG5vdwogICAgICAgICAgICAgdmFyIHJJbmRleCA9ICIuIjsKICAgICAgICAgICAgIGlmKCAoblJhZGl4ID0gc1ZhbC5pbmRleE9mKHJJbmRleCkpIT0tMSkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgZm9yKDsgblJhZGl4IDw9c1ZhbC5sZW5ndGggO25SYWRpeCsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgIH0KICAgIH0pCn0pKF8seGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5Gb3JtYXR0aW5nVmlzaXRvckJhc2UKICogQGltcG9ydCB4ZmFsaWIudXQuVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBCYXNlIGNsYXNzIGZvciB2aXNpdG9yCiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKLyoqCiAqIEBjb25zdHJ1Y3RvcgogKiBAcGFyYW0gT2JqZWN0IHtqc29uTW9kZWw6IHtfc1BpY3R1cmU6IFN0cmluZ119CiAqLwoKKGZ1bmN0aW9uKF8seGZhbGliKSB7CiAgICB2YXIgRm9ybWF0dGluZ1Zpc2l0b3JCYXNlID0geGZhbGliLnV0LkZvcm1hdHRpbmdWaXNpdG9yQmFzZSA9IHhmYWxpYi51dC5WaXNpdG9yQmFzZS5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdGhpcy5fYnVmZmVyID0gW107IC8vVE9ETzogQVNLIFJlbiB3aGVyZSBkb2VzIHRoaXMgX2J1ZmZlciBjb21lcyBmcm9tCiAgICAgICAgICAgIEZvcm1hdHRpbmdWaXNpdG9yQmFzZS5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIGNvbnN1bWVTdHJpbmdXaWxkQ2FyZCA6IGZ1bmN0aW9uKHRva2VuKXsKICAgICAgICAgICAgLy8nPycgJyonICcrCiAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKCIgIik7CiAgICAgICAgfSwKCiAgICAgICAgY29uc3VtZVN0cmluZ0xpdGVyYWwgOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5zdWJzdHIodG9rZW4uc3RhcnRQb3MrMSx0b2tlbi5sZW4tMikpOwogICAgICAgIH0sCgogICAgICAgIGNvbnN1bWVDaGFyTGl0ZXJhbCA6IGZ1bmN0aW9uKHRva2VuKXsKICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goIiIrIHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5jaGFyQXQodG9rZW4uc3RhcnRQb3MpKTsKICAgICAgICB9CiAgICB9KQoKfSkoXyx4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlBhcnNpbmdWaXNpdG9yQmFzZQogKiBAaW1wb3J0IHhmYWxpYi51dC5WaXNpdG9yQmFzZQogKiBAZmlsZU92ZXJ2aWV3IEJhc2UgY2xhc3MgZm9yIHZpc2l0b3IKICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nLF9kYXRhU3RyaW5nOiBTdHJpbmd9fQogKi8KCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgUGFyc2luZ1Zpc2l0b3JCYXNlID0geGZhbGliLnV0LlBhcnNpbmdWaXNpdG9yQmFzZSA9IHhmYWxpYi51dC5WaXNpdG9yQmFzZS5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdGhpcy5fc3RyTGVuID0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcubGVuZ3RoOwogICAgICAgICAgICB0aGlzLl9zdHJQb3MgPSAwOwogICAgICAgICAgICBQYXJzaW5nVmlzaXRvckJhc2UuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICB9LAoKICAgICAgICBjb25zdW1lU3RyaW5nV2lsZENhcmQgOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgICAgIGlmIChjaHIgPT0gJz8nKSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RyUG9zIDwgdGhpcy5fc3RyTGVuKS8vJiYgQ2hhcmFjdGVyLmlzRGVmaW5lZChzdHIuY2hhckF0KHN0clBvcykpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RyUG9zICs9IDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hyID09ICcrJykgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX3N0clBvcyA+PSB0aGlzLl9zdHJMZW4pLy8gfHwgISBDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKHN0ci5jaGFyQXQoc3RyUG9zKSkpCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgIk1pc21hdGNoIjsKICAgICAgICAgICAgICAgIHRoaXMuX3N0clBvcyArPSAxOwogICAgICAgICAgICAgICAgd2hpbGUgKHRoaXMuX3N0clBvcyA8IHRoaXMuX3N0ckxlbikvLyAmJiBDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKHN0ci5jaGFyQXQoc3RyUG9zKSkpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RyUG9zICs9IDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hyID09ICcqJykgewogICAgICAgICAgICAgICAgd2hpbGUgKHRoaXMuX3N0clBvcyA8IHRoaXMuX3N0ckxlbikvLyAmJiBDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKHN0ci5jaGFyQXQoc3RyUG9zKSkpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RyUG9zICs9IDE7CiAgICAgICAgICAgIH0KCiAgICAgICAgfSwKCiAgICAgICAgY29uc3VtZVN0cmluZ0xpdGVyYWwgOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgICAgIGZvcih2YXIgb2Zmc2V0PTA7IG9mZnNldDx0b2tlbi5sZW4tMiA7b2Zmc2V0KyspeyAvLy0yLCBoZWFkaW5nIGFuZCB0cmFpbGluZyBxdW90ZQogICAgICAgICAgICAgICAgaWYodGhpcy5qc29uTW9kZWwuX3NQaWN0dXJlLmNoYXJBdCh0b2tlbi5zdGFydFBvcytvZmZzZXQrMSkgIT0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcuY2hhckF0KHRoaXMuX3N0clBvcytvZmZzZXQpKXsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAoIk1pc21hdGNoIiArIHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5zdWJzdHIodG9rZW4uc3RhcnRQb3MsIHRva2VuLmxlbikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuX3N0clBvcyArPSB0b2tlbi5sZW4tMjsKCiAgICAgICAgfSwKCiAgICAgICAgY29uc3VtZUNoYXJMaXRlcmFsIDogZnVuY3Rpb24odG9rZW4pewogICAgICAgICAgICBpZih0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmUuY2hhckF0KHRva2VuLnN0YXJ0UG9zKSA9PSB0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy5jaGFyQXQodGhpcy5fc3RyUG9zKSl7CiAgICAgICAgICAgICAgICB0aGlzLl9zdHJQb3MgKz0gMTsKICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICB0aHJvdyAiTWlzbWF0Y2giOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSkKfSkoXyx4ZmFsaWIpOwoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5EYXRlRm9ybWF0dGluZ1Zpc2l0b3IKICogQGltcG9ydCB4ZmFsaWIudXQuRm9ybWF0dGluZ1Zpc2l0b3JCYXNlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgcHJvdmlkZXMgZm9ybWF0aW5nIGxvZ2ljIG9uIGRhdGUgcGF0dGVybiBjaGFyYWN0ZXJzLgogKiBAdmVyc2lvbiAwLjAuMQogKi8KCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBvYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTpTdHJpbmcsX2RhdGVJbmZvOiB4ZmFsaWIudXQuRGF0ZUluZm99fQogKi8KCihmdW5jdGlvbihfLHhmYWxpYikgewogICAgdmFyIFBpY3R1cmVVdGlscyA9ICB4ZmFsaWIudXQuUGljdHVyZVV0aWxzOwogICAgdmFyIERhdGVGb3JtYXR0aW5nVmlzaXRvciA9IHhmYWxpYi51dC5EYXRlRm9ybWF0dGluZ1Zpc2l0b3IgPSB4ZmFsaWIudXQuRm9ybWF0dGluZ1Zpc2l0b3JCYXNlLmV4dGVuZCh7CgogICAgICAgIGNvbnN1bWVTdWJQYXR0ZXJuIDogZnVuY3Rpb24odG9rZW4pewogICAgICAgICAgICB2YXIgY2hyID0gdG9rZW4ucGF0Q2hhcjsKICAgICAgICAgICAgdmFyIGNockNudCA9IHRva2VuLmxlbjsKCiAgICAgICAgICAgIHN3aXRjaCAoY2hyKSB7CiAgICAgICAgICAgICAgICBjYXNlICdEJzoKICAgICAgICAgICAgICAgICAgICB2YXIgZGF5T2ZNb250aD10aGlzLmpzb25Nb2RlbC5fZGF0ZUluZm8uZGF0ZS5nZXREYXRlKCk7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXlPZk1vbnRoID0gUGljdHVyZVV0aWxzLnBhZGRpbmcoZGF5T2ZNb250aCwyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChQaWN0dXJlVXRpbHMuY29udmVydE51bWJlclRvTG9jYWxlKHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsZGF5T2ZNb250aCkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnSic6CgogICAgICAgICAgICAgICAgICAgIC8vdGhpcy5fbURheU9mWWVhcjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ00nOgogICAgICAgICAgICAgICAgICAgIHZhciBtb250aE9mWWVhciA9IHRoaXMuanNvbk1vZGVsLl9kYXRlSW5mby5kYXRlLmdldE1vbnRoKCk7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKFBpY3R1cmVVdGlscy5jb252ZXJ0TnVtYmVyVG9Mb2NhbGUodGhpcy5qc29uTW9kZWwuX2xvY2FsZSxtb250aE9mWWVhcisxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goUGljdHVyZVV0aWxzLmNvbnZlcnROdW1iZXJUb0xvY2FsZSh0aGlzLmpzb25Nb2RlbC5fbG9jYWxlLFBpY3R1cmVVdGlscy5wYWRkaW5nKG1vbnRoT2ZZZWFyKzEsMikpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbW9udGhOYW1lcyA9IFBpY3R1cmVVdGlscy5nZXRMb2NhbGVPYmplY3QodGhpcy5qc29uTW9kZWwuX2xvY2FsZSwiY2FsZW5kYXJTeW1ib2xzLmFiYnJtb250aE5hbWVzIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChtb250aE5hbWVzW21vbnRoT2ZZZWFyXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1vbnRoTmFtZXMgPSBQaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsImNhbGVuZGFyU3ltYm9scy5tb250aE5hbWVzIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChtb250aE5hbWVzW21vbnRoT2ZZZWFyXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnRSc6CiAgICAgICAgICAgICAgICAgICAgdmFyIGRheU9mV2VlayA9IHRoaXMuanNvbk1vZGVsLl9kYXRlSW5mby5kYXRlLmdldERheSgpOwogICAgICAgICAgICAgICAgICAgIHZhciBkYXlOYW1lczsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2goY2hyQ250KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKGRheU9mV2Vlayk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF5TmFtZXMgPSAgUGljdHVyZVV0aWxzLmdldExvY2FsZU9iamVjdCh0aGlzLmpzb25Nb2RlbC5fbG9jYWxlLCJjYWxlbmRhclN5bWJvbHMuYWJicmRheU5hbWVzIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChkYXlOYW1lc1tkYXlPZldlZWtdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXlOYW1lcyA9ICAgUGljdHVyZVV0aWxzLmdldExvY2FsZU9iamVjdCh0aGlzLmpzb25Nb2RlbC5fbG9jYWxlLCJjYWxlbmRhclN5bWJvbHMuZGF5TmFtZXMiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKGRheU5hbWVzW2RheU9mV2Vla10pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAidW5zdXBwb3J0ZWQgUGljdHVyZSBDbGF1c2UgIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdlJzoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ0cnOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnWSc6CgogICAgICAgICAgICAgICAgICAgIHZhciB5ZWFyT2ZFcmEgPSB0aGlzLmpzb25Nb2RlbC5fZGF0ZUluZm8uZGF0ZS5nZXRGdWxsWWVhcigpCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHllYXJPZkVyYT4yMDI5IHx8IHllYXJPZkVyYSA8IDE5MzApewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJ1bnN1cHBvcnRlZCAiICsgeWVhck9mRXJhICsgIiBieSBwYXR0ZXJuIFlZIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJPZkVyYSA9IFBpY3R1cmVVdGlscy5wYWRkaW5nKHllYXJPZkVyYSAlIDEwMCwgMik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhck9mRXJhID0gUGljdHVyZVV0aWxzLnBhZGRpbmcoeWVhck9mRXJhLCA0KTsgLy8gMiBkaWdpdCgwMDAwLTk5OTkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goUGljdHVyZVV0aWxzLmNvbnZlcnROdW1iZXJUb0xvY2FsZSh0aGlzLmpzb25Nb2RlbC5fbG9jYWxlLHllYXJPZkVyYSkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAndyc6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdXJzoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93ICJVbnN1cHBvcnRlZCBwYXR0ZXJuIjsKICAgICAgICAgICAgfQoKICAgICAgICB9LAogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgZ2V0UmVzdWx0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5qb2luKCIiKTsKICAgICAgICB9CgogICAgfSk7Cn0pKF8seGZhbGliKTsKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlRleHRGb3JtYXR0aW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5Gb3JtYXR0aW5nVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBGb3JtYXRzIGEgc3RyaW5nIGFjY29yZGluZyB0byBUZXh0IFBpY3R1cmUuCiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKLyoqCiAqIEBjb25zdHJ1Y3RvcgogKiBAcGFyYW0gT2JqZWN0IHsganNvbk1vZGVsOntfc1BpY3R1cmU6IFN0cmluZywgX3RleHQ6IFN0cmluZ319CiAqLwooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgdmFyIFRleHRGb3JtYXR0aW5nVmlzaXRvciA9IHhmYWxpYi51dC5UZXh0Rm9ybWF0dGluZ1Zpc2l0b3IgPSB4ZmFsaWIudXQuRm9ybWF0dGluZ1Zpc2l0b3JCYXNlLmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB0aGlzLl90ZXh0UG9zID0gMDsKICAgICAgICAgICAgdGhpcy5fcmVsYXhlZCA9IHR5cGVvZiB0aGlzLmpzb25Nb2RlbC5yZWxheGVkID09PSAidW5kZWZpbmVkIiA/IHRydWU6IHRoaXMuanNvbk1vZGVsLnJlbGF4ZWQ7CiAgICAgICAgICAgIFRleHRGb3JtYXR0aW5nVmlzaXRvci5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIGNvbnN1bWVTdWJQYXR0ZXJuIDogZnVuY3Rpb24odG9rZW4pewogICAgICAgICAgICB2YXIgY2hyID0gdG9rZW4ucGF0Q2hhcjsKICAgICAgICAgICAgdmFyIGNockNudCA9IHRva2VuLmxlbjsKICAgICAgICAgICAgZm9yKHZhciBpbmRleCA9IDA7IGluZGV4IDwgY2hyQ250ICYmICghdGhpcy5fcmVsYXhlZCB8fCB0aGlzLl90ZXh0UG9zIDwgdGhpcy5qc29uTW9kZWwuX3RleHQubGVuZ3RoKTsgaW5kZXgrKyl7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGNocikgewogICAgICAgICAgICAgICAgICAgIGNhc2UgJzknOiAvLyBOdW1lcmljCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjVW5pID0gdGhpcy5qc29uTW9kZWwuX3RleHQuY2hhckF0KHRoaXMuX3RleHRQb3MrKyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCF4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmlzRGlnaXQoY1VuaSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRGb3JtYXR0aW5nOiBub3QgYSBkaWdpdCBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goY1VuaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ0EnOiAvLyBBbHBoZWJldGljCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjVW5pID0gdGhpcy5qc29uTW9kZWwuX3RleHQuY2hhckF0KHRoaXMuX3RleHRQb3MrKyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCF4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmlzTGV0dGVyKGNVbmkpKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJUZXh0Rm9ybWF0dGluZzogbm90IGEgY2hhcmFjdGVyIGFzIGV4cGVjdGVkIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChjVW5pKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnTyc6IC8vIEFscGhhbnVtZXJpYwogICAgICAgICAgICAgICAgICAgIGNhc2UgJzAnOgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY1VuaSA9IHRoaXMuanNvbk1vZGVsLl90ZXh0LmNoYXJBdCh0aGlzLl90ZXh0UG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBjVW5pID09PSAiIiBpcyBhIGhhY2sgZm9yIExDLTYxNTIKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVG8gcHJldmVudCBleHRyYSBsb29wW29uZSBtb3JlIHRpbWUgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmddIGZvciB3aGljaCBjVW5pIHdhcyAiIgogICAgICAgICAgICAgICAgICAgICAgICAvLyB3aGljaCB3YXMgbmVpdGhlciBhIGxldHRlciBub3IgYSBkaWdpdAogICAgICAgICAgICAgICAgICAgICAgICAvLyBzbyB3ZSB3ZXJlIGdldHRpbmcgdGV4dGZvcm1hdHRpbmcgZXJyb3IKICAgICAgICAgICAgICAgICAgICAgICAgLy93aGljaCBjYXVzZWQgZW1haWwgaWQgdmFsaWRhdGlvbiB0byBmYWlsIGZvciBjaGFycyBsZXNzIHRoYW4gcGljdHVyZSBjbGF1c2UKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIShjVW5pID09PSIiIHx8IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuaXNMZXR0ZXIoY1VuaSkgfHwgeGZhbGliLnV0LlBpY3R1cmVVdGlscy5pc0RpZ2l0KGNVbmkpKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dEZvcm1hdHRpbmc6IG5vdCBhIGNoYXJhY3RlciBvciBkaWdpdCBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goY1VuaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ1gnOgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY1VuaSA9IHRoaXMuanNvbk1vZGVsLl90ZXh0LmNoYXJBdCh0aGlzLl90ZXh0UG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChjVW5pKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAndCc6CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKCJcdCIpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB0aGlzLl9idWZmZXIucHVzaChjaHIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgZ2V0UmVzdWx0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgaWYodGhpcy5fdGV4dFBvcyA8IHRoaXMuanNvbk1vZGVsLl90ZXh0Lmxlbmd0aCkKICAgICAgICAgICAgICAgIHRocm93ICJUZXh0Rm9ybWF0dGluZzogcGljdHVyZSBjbGF1c2Ugc21hbGxlciB0aGFuIGlucHV0IFRleHQiOwogICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLmpvaW4oIiIpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgYWNjZXB0UGF0dGVybkNoYXIgOiBmdW5jdGlvbihjaHIpewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlBpY3R1cmVVdGlscy5pblN0cmluZyhjaHIsICI5QU8wWHQiKTsKICAgICAgICB9LAoKICAgICAgICBjb25zdW1lQ2hhckxpdGVyYWwgOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKCIiKyB0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmUuY2hhckF0KHRva2VuLnN0YXJ0UG9zKSk7CiAgICAgICAgIC8vIExDLTM4NjkgOiBmb3J3YXJkIHRoZSB0ZXh0IHBvaW50ZXIgYWZ0ZXIgbGl0ZXJhbCBpcyBwcmVzZW50IGFuZCBtYXRjaGVkIHdpdGggdGhlIHBpY3R1cmUuCiAgICAgICAgIGlmKHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5jaGFyQXQodG9rZW4uc3RhcnRQb3MpID09IHRoaXMuanNvbk1vZGVsLl90ZXh0LmNoYXJBdCh0b2tlbi5zdGFydFBvcykpCiAgICAgICAgICAgICB0aGlzLl90ZXh0UG9zKys7CiAgICAgICAgfQogICAgfSkKCn0pKF8seGZhbGliKTsKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlRleHRGb3JtYXR0aW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5Gb3JtYXR0aW5nVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBwcm92aWRlcyBmb3JtYXRpbmcgbG9naWMgb24gZGF0ZSBwYXR0ZXJuIGNoYXJhY3RlcnMuCiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKLyoqCiAqIEBjb25zdHJ1Y3RvcgogKiBAcGFyYW0gb2JqZWN0IHtqc29uTW9kZWw6IHtfc1BpY3R1cmU6U3RyaW5nLF90aW1lSW5mbzogeGZhbGliLnV0LlRpbWVJbmZvfX0KICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgdmFyIFRpbWVGb3JtYXR0aW5nVmlzaXRvciA9IHhmYWxpYi51dC5UaW1lRm9ybWF0dGluZ1Zpc2l0b3I9ICB4ZmFsaWIudXQuRm9ybWF0dGluZ1Zpc2l0b3JCYXNlLmV4dGVuZCh7CgogICAgICAgIGNvbnN1bWVTdWJQYXR0ZXJuIDogZnVuY3Rpb24odG9rZW4pewogICAgICAgICAgICB2YXIgY2hyID0gdG9rZW4ucGF0Q2hhcjsKICAgICAgICAgICAgdmFyIGNockNudCA9IHRva2VuLmxlbjsKCiAgICAgICAgICAgIHN3aXRjaCAoY2hyKSB7CiAgICAgICAgICAgICAgICBjYXNlICdIJzoKICAgICAgICAgICAgICAgIGNhc2UgJ0snOgogICAgICAgICAgICAgICAgICAgIHZhciBob3VyT2ZEYXkgPSB0aGlzLmpzb25Nb2RlbC5fdGltZUluZm8ubUhvdXJPZkRheTsKICAgICAgICAgICAgICAgICAgICBpZihjaHI9PSdLJyl7CiAgICAgICAgICAgICAgICAgICAgICAgIGhvdXJPZkRheSArPSAxOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzd2l0Y2goY2hyQ250KXsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goaG91ck9mRGF5KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCh4ZmFsaWIudXQuUGljdHVyZVV0aWxzLnBhZGRpbmcoaG91ck9mRGF5LDIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdNJzoKICAgICAgICAgICAgICAgICAgICB2YXIgbWludXRlT2ZIb3VyID0gdGhpcy5qc29uTW9kZWwuX3RpbWVJbmZvLm1NaW51dGVPZkhvdXI7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKG1pbnV0ZU9mSG91cik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goeGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYWRkaW5nKG1pbnV0ZU9mSG91ciwyKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnUyc6CiAgICAgICAgICAgICAgICAgICAgdmFyIHNlY29uZE9mTWludXRlID0gdGhpcy5qc29uTW9kZWwuX3RpbWVJbmZvLm1TZWNvbmRPZk1pbnV0ZTsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2goY2hyQ250KXsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goc2Vjb25kT2ZNaW51dGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHhmYWxpYi51dC5QaWN0dXJlVXRpbHMucGFkZGluZyhzZWNvbmRPZk1pbnV0ZSwyKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdGJzoKICAgICAgICAgICAgICAgICAgICB2YXIgTWlsbGlzZWNvbmRzID10aGlzLmpzb25Nb2RlbC5fdGltZUluZm8ubVRob3VzYW5kdGhPZlNlY29uZDsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCh4ZmFsaWIudXQuUGljdHVyZVV0aWxzLnBhZGRpbmcoTWlsbGlzZWNvbmRzLDMpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0aHJvdyAiVW5zdXBwb3J0ZWQgcGF0dGVybiI7CiAgICAgICAgICAgIH07CgogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgZ2V0UmVzdWx0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5qb2luKCIiKTsKICAgICAgICB9CgogICAgfSk7Cgp9KShfLHhmYWxpYik7CgoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5OdW1Gb3JtYXR0aW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5Gb3JtYXR0aW5nVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBGb3JtYXRzIGEgc3RyaW5nIGFjY29yZGluZyB0byBUZXh0IFBpY3R1cmUuCiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKLyoqCiAqIEBjb25zdHJ1Y3RvcgogKiBAcGFyYW0gT2JqZWN0IHsganNvbk1vZGVsOntfc1BpY3R1cmU6IFN0cmluZ30sIHRleHQ6IFN0cmluZ30KICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgdmFyIFBpY3R1cmVVdGlscyA9ICB4ZmFsaWIudXQuUGljdHVyZVV0aWxzOwogICAgdmFyIE51bUZvcm1hdHRpbmdWaXNpdG9yID0geGZhbGliLnV0Lk51bUZvcm1hdHRpbmdWaXNpdG9yID0geGZhbGliLnV0LkZvcm1hdHRpbmdWaXNpdG9yQmFzZS5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRpb25zKSB7CiAgICAgICAgICAgIE51bUZvcm1hdHRpbmdWaXNpdG9yLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX3RleHRQb3MgPSAwOwoKICAgICAgICAgICAgLy9ib29sZWFuIHZhbHVlIHVzZWQgZm9yIGludGVybmFsIHN0YXRlIHRyYWNrCiAgICAgICAgICAgIHRoaXMuX21iRGlnaXRBZGRlZFRvT3V0cHV0ID0gZmFsc2U7IC8vIGF0IGxlYXN0IG9uZSBkaWdpdCBoYXMgYmVlbiBhZGRlZCB0byBvdXRwdXQKICAgICAgICAgICAgdGhpcy5fbWJTaWduQWRkZWRUb091dHB1dCA9IGZhbHNlOwogICAgICAgICAgICB0aGlzLl9uU2Nhbm5lZFBhdHRlcm5EaWdpdCA9IDA7IC8vaG93IG1hbnkgZGlnaXQoOThaeikgY2hhcmFjdGVycyBzY2FubmVkIGluIHBhdHRlcm4sIHJlc2V0IHRvIDAgYWZ0ZXIgJy5WdicKICAgICAgICAgICAgdGhpcy5fbWJSYWRpeFNlZW4gPSBmYWxzZTsKCiAgICAgICAgICAgIHRoaXMuX3BpY3R1cmVEZXNjID0gbmV3IHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYyh7anNvbk1vZGVsOntfc1BpY3R1cmU6dGhpcy5qc29uTW9kZWwuX3NQaWN0dXJlfX0pOwogICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmU9IHRoaXMuX3BpY3R1cmVEZXNjLmdldFBpY3R1cmUoKTsKICAgICAgICAgICAgdGhpcy5fbnVtYmVySW5mbyA9IHRoaXMuX3BpY3R1cmVEZXNjLnBhcnNlTnVtYmVySW5mbyhvcHRpb25zLnRleHQpOwoKICAgICAgICAgICAgdGhpcy5fbWJOZWdhdGl2ZSA9IHRoaXMuX251bWJlckluZm8uaXNOZWdhdGl2ZTsKICAgICAgICAgICAgdGhpcy5fbXNUZXh0ID0gdGhpcy5fbnVtYmVySW5mby5tc1RleHQ7CiAgICAgICAgICAgIHRoaXMuX2xlYWRpbmdQYWRkaW5nID0gdGhpcy5fbnVtYmVySW5mby5wYWRkaW5nOwogICAgICAgICAgICAvLwogICAgICAgICAgICB0aGlzLl9tTnVtYmVyU3ltYm9scyA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsIm51bWJlclN5bWJvbHMiKTsKICAgICAgICAgICAgdGhpcy5fbUN1cnJlbmN5U3ltYm9scyA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsImN1cnJlbmN5U3ltYm9scyIpOwogICAgICAgIH0sCgogICAgICAgIF9jaGVja0FuZEFkZERlY2ltYWxQb2ludDogZnVuY3Rpb24oZncpIHsKICAgICAgICAgICAgaWYodGhpcy5fbUFkZFJhZGl4KSB7CiAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCh0aGlzLl9mbXRTdHIodGhpcy5fbU51bWJlclN5bWJvbHMuZGVjaW1hbCwgZncpKTsKICAgICAgICAgICAgICAgIHRoaXMuX21BZGRSYWRpeCA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgY29uc3VtZVN1YlBhdHRlcm4gOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgICAgIHZhciBjaHIgPSB0b2tlbi5wYXRDaGFyLAogICAgICAgICAgICAgICAgY2hyQ250ID0gdG9rZW4ubGVuOwogICAgICAgICAgICBzd2l0Y2ggKGNocikgewogICAgICAgICAgICAgICAgY2FzZSAnOSc6CiAgICAgICAgICAgICAgICBjYXNlICc4JzoKICAgICAgICAgICAgICAgIGNhc2UgJ1onOiAvLyBEaWdpdCBvciBzcGFjZSBpZiB6ZXJvLgogICAgICAgICAgICAgICAgY2FzZSAneic6Ly8gRGlnaXQgb3Igbm90aGluZyBpZiB6ZXJvLgogICAgICAgICAgICAgICAgICAgIGlmKCF0aGlzLl9tYlNpZ25BZGRlZFRvT3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9lbnN1cmVTaWduSXNBZGRlZCgpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaHJDbnQtLSA+IDAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCF0aGlzLl9tYlJhZGl4U2Vlbil7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl9sZWFkaW5nUGFkZGluZyA+IHRoaXMuX25TY2FubmVkUGF0dGVybkRpZ2l0KyspewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwbGFjZUhvbGRlciA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fbWJEaWdpdEFkZGVkVG9PdXRwdXQpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZUhvbGRlciA9IHRoaXMuX21OdW1iZXJTeW1ib2xzLnplcm87CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNociA9PSAnOScgfHwgY2hyID09JzgnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZUhvbGRlciA9IHRoaXMuX21OdW1iZXJTeW1ib2xzLnplcm87CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYkRpZ2l0QWRkZWRUb091dHB1dCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlIGlmKGNociA9PSAnWicpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2VIb2xkZXIgPSAiICI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYocGxhY2VIb2xkZXIpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCh0aGlzLl9tYXRjaENocihwbGFjZUhvbGRlcikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY1ZhbHVlID0gdGhpcy5fbXNUZXh0LmNoYXJBdCh0aGlzLl90ZXh0UG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2Vuc3VyZUNoYXJJc0RpZ2l0KGNWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goUGljdHVyZVV0aWxzLmNvbnZlcnROdW1iZXJUb0xvY2FsZSh0aGlzLmpzb25Nb2RlbC5fbG9jYWxlLGNWYWx1ZSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iRGlnaXRBZGRlZFRvT3V0cHV0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7ICAvL2hhbmRsaW5nIGZyYWN0aW9uYWwgcGFydAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fblNjYW5uZWRQYXR0ZXJuRGlnaXQrKyAgPCB0aGlzLl9udW1iZXJJbmZvLmZyYWN0aW9uRGlnaXQgKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY1ZhbHVlID0gdGhpcy5fbXNUZXh0LmNoYXJBdCh0aGlzLl90ZXh0UG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2Vuc3VyZUNoYXJJc0RpZ2l0KGNWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2hlY2tBbmRBZGREZWNpbWFsUG9pbnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChQaWN0dXJlVXRpbHMuY29udmVydE51bWJlclRvTG9jYWxlKHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsY1ZhbHVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJEaWdpdEFkZGVkVG9PdXRwdXQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2hyID09ICc5J3x8IGNociA9PSdaJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGVja0FuZEFkZERlY2ltYWxQb2ludCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCh0aGlzLl9tYXRjaENocih0aGlzLl9tTnVtYmVyU3ltYm9scy56ZXJvKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmKGNociA9PSAnOCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNWYWx1ZSA9IHRoaXMuX21zVGV4dC5jaGFyQXQodGhpcy5fdGV4dFBvcysrKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY1ZhbHVlICE9ICcnICYmIHRoaXMuX2Vuc3VyZUNoYXJJc0RpZ2l0KGNWYWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NoZWNrQW5kQWRkRGVjaW1hbFBvaW50KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChQaWN0dXJlVXRpbHMuY29udmVydE51bWJlclRvTG9jYWxlKHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsY1ZhbHVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYkRpZ2l0QWRkZWRUb091dHB1dCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ0UnOiAvLyBFeHBvbmVudC4KICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCgnRScpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKCIiICsgdGhpcy5fbnVtYmVySW5mby5zaGlmdCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdDJzogLy8gQ1Igc3ltYm9sIGlmIG5lZ2F0aXZlIGFuZCBzcGFjZXMgaWYgcG9zaXRpdmUuCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goKHRoaXMuX21iTmVnYXRpdmUpID8geGZhbGliLnV0Lk51bVBpY3R1cmVEZXNjLmdzQ1IgOiB4ZmFsaWIudXQuTnVtUGljdHVyZURlc2MuZ3NEU1ApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnYyc6IC8vIENSIHN5bWJvbCBpZiBuZWdhdGl2ZSBhbmQgbm90aGluZyBpZiBwb3NpdGl2ZS4KICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbWJOZWdhdGl2ZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYy5nc0NSKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdEJzogLy8gREIgc3ltYm9sIGlmIG5lZ2F0aXZlIGFuZCBzcGFjZXMgaWYgcG9zaXRpdmUuCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goKHRoaXMuX21iTmVnYXRpdmUpID8geGZhbGliLnV0Lk51bVBpY3R1cmVEZXNjLmdzREIgOiB4ZmFsaWIudXQuTnVtUGljdHVyZURlc2MuZ3NEU1ApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnZCc6IC8vIERCIHN5bWJvbCBpZiBuZWdhdGl2ZSBhbmQgbm90aGluZyBpZiBwb3NpdGl2ZS4KICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbWJOZWdhdGl2ZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYy5nc0RCKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdTJzogLy8gTWludXMgc2lnbiBpZiBuZWdhdGl2ZSBhbmQgYSBzcGFjZSBpZiBwb3NpdGl2ZS4KICAgICAgICAgICAgICAgIGNhc2UgJ3MnOgogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9tYk5lZ2F0aXZlKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2godGhpcy5fZm10U3RyKAl0aGlzLl9tTnVtYmVyU3ltYm9scy5taW51cykpOwogICAgICAgICAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgICAgICAgICBpZignUycgPT0gY2hyKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHRoaXMuX21hdGNoQ2hyKCcgJykpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnVic6IC8vIEltcGxpZWQgZGVjaW1hbCBzaWduIGlmIHBhcnNpbmcuCiAgICAgICAgICAgICAgICBjYXNlICcuJzoKICAgICAgICAgICAgICAgIGNhc2UgJ3YnOiAvLyBJbXBsaWVkIGRlY2ltYWwgc2lnbi4KICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fdGV4dFBvcyA8IHRoaXMuX21zVGV4dC5sZW5ndGggJiYgdGhpcy5fbXNUZXh0LmNoYXJBdCh0aGlzLl90ZXh0UG9zKSA9PSAnLicpewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl90ZXh0UG9zKys7IC8vY29uc3VtZSBhICcuJwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoY2hyID09ICdWJyB8fCBjaHIgPT0gJy4nKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbUFkZFJhZGl4ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzLl9idWZmZXIucHVzaCh0aGlzLl9mbXRTdHIodGhpcy5fbU51bWJlclN5bWJvbHMuZGVjaW1hbCwgKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHRoaXMuX21iUmFkaXhTZWVuID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9uU2Nhbm5lZFBhdHRlcm5EaWdpdCA9IDA7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAweEZGMEM6IC8vIEZ1bGx3aWR0aCAnLCcuCiAgICAgICAgICAgICAgICBjYXNlICcsJzogLy8gR3JvdXBpbmcgc2VwYXJhdG9yLgogICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaHJDbnQtLSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX21iRGlnaXRBZGRlZFRvT3V0cHV0KXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHRoaXMuX2ZtdFN0cigJdGhpcy5fbU51bWJlclN5bWJvbHMuZ3JvdXBpbmcgKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJDb21tYVNlZW4gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMHhGRjA0OiAvLyBGdWxsd2lkdGggJyQnLgogICAgICAgICAgICAgICAgY2FzZSAnJCc6IC8vIEN1cnJlbmN5IG5hbWUgb3Igc3ltYm9sLgogICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaHJDbnQtLSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2godGhpcy5fZm10U3RyKAl0aGlzLl9tQ3VycmVuY3lTeW1ib2xzLnN5bWJvbCApKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDB4RkYwNTogLy8gRnVsbHdpZHRoICclJy4KICAgICAgICAgICAgICAgIGNhc2UgJyUnOiAvLyBQZXJjZW50IHN5bWJvbC4KICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hyQ250LS0gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHRoaXMuX2ZtdFN0cigJdGhpcy5fbU51bWJlclN5bWJvbHMucGVyY2VudCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMHhGRjA4OiAvLyBGdWxsd2lkdGggJygnLgogICAgICAgICAgICAgICAgY2FzZSAweEZGMDk6IC8vIEZ1bGx3aWR0aCAnKScuCiAgICAgICAgICAgICAgICBjYXNlICcoJzogLy8gTGVmdCBwYXJlbnRoZXNpcy4KICAgICAgICAgICAgICAgIGNhc2UgJyknOiAvLyBSaWdodCBwYXJlbnRoZXNpcy4KICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCh0aGlzLl9tYXRjaENocigodGhpcy5fbWJOZWdhdGl2ZSkgPyBjaHIgOiAnICcpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZW5zdXJlQ2hhcklzRGlnaXQgOiBmdW5jdGlvbihjVmFsdWUpewogICAgICAgICAgICBpZiAoJzAnID4gY1ZhbHVlIHx8IGNWYWx1ZSA+ICc5Jyl7CiAgICAgICAgICAgICAgICB0aHJvdyAiTnViZXJpYyBGb3JtYXR0aW5nOiBub3QgYSBkaWdpdCBhcyBleHBlY3RlZCAiICsgY1ZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCgogICAgICAgIF9mbXRTdHIgOiBmdW5jdGlvbihzdHIpewogICAgICAgICAgICByZXR1cm4gc3RyOwogICAgICAgIH0sCgogICAgICAgIF9tYXRjaFN0ciA6IGZ1bmN0aW9uKHN0cil7CiAgICAgICAgICAgIHJldHVybiBzdHI7CiAgICAgICAgfSwKCiAgICAgICAgX21hdGNoQ2hyIDogZnVuY3Rpb24oc3RyKXsKICAgICAgICAgICAgcmV0dXJuIHN0cjsKICAgICAgICB9LAoKICAgICAgICBfZW5zdXJlU2lnbklzQWRkZWQgOiBmdW5jdGlvbigpewogICAgICAgICAgICBpZiAodGhpcy5fbWJOZWdhdGl2ZSAmJiAhIHRoaXMuX21iRGlnaXRBZGRlZFRvT3V0cHV0ICYmICEgdGhpcy5fcGljdHVyZURlc2MuaGFzU2lnbikgewogICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2godGhpcy5fbU51bWJlclN5bWJvbHMubWludXMpOwogICAgICAgICAgICAgICAgdGhpcy5fbWJTaWduQWRkZWRUb091dHB1dCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqIEBvdmVycmlkZQogICAgICAgICAqLwogICAgICAgIGdldFJlc3VsdCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIuam9pbigiIik7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKiBAb3ZlcnJpZGUKICAgICAgICAgKi8KICAgICAgICBhY2NlcHRQYXR0ZXJuQ2hhciA6IGZ1bmN0aW9uKGNocil7CiAgICAgICAgICAgIHJldHVybiB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmluU3RyaW5nKGNociwgIiglJCwuKTg5QkNERVJTVlpiY2Ryc3Z6dCIpOwogICAgICAgIH0KCiAgICB9KTsKCn0pKF8seGZhbGliKTsKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlRpbWVQYXJzaW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5QYXJzaW5nVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBwcm92aWRlcyBwYXJzaW5nL2Zvcm1hdGluZyBsb2dpYyBvbiBkYXRlIHBhdHRlcm4gY2hhcmFjdGVycy4KICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nLCBfZGF0YVN0cmluZzogU3RyaW5nXX0KICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgdmFyIFRpbWVQYXJzaW5nVmlzaXRvciA9IHhmYWxpYi51dC5UaW1lUGFyc2luZ1Zpc2l0b3IgPSB4ZmFsaWIudXQuUGFyc2luZ1Zpc2l0b3JCYXNlLmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB0aGlzLl90aW1lSW5mbyA9IG5ldyB4ZmFsaWIudXQuVGltZUluZm8oKTsKICAgICAgICAgICAgVGltZVBhcnNpbmdWaXNpdG9yLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgfSwKCiAgICAgICAgY29uc3VtZVN1YlBhdHRlcm4gOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgICAgIHZhciBjaHIgPSB0b2tlbi5wYXRDaGFyOwogICAgICAgICAgICB2YXIgY2hyQ250ID0gdG9rZW4ubGVuOwogICAgICAgICAgICB2YXIgY3VyUG9zID0gdGhpcy5fc3RyUG9zOwogICAgICAgICAgICB2YXIgc2Nhbm5lZENoYXIgPSBjaHJDbnQ7CiAgICAgICAgICAgIHRoaXMuX2Fzc2VydChjdXJQb3MrY2hyQ250IDw9dGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcubGVuZ3RoLCAiTWlzbWF0Y2giKTsKCiAgICAgICAgICAgIHN3aXRjaCAoY2hyKSB7CiAgICAgICAgICAgICAgICBjYXNlICdoJzoKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl90aW1lSW5mby5tSG91ck9mTWVyaURpZW0gIT0gLTEgfHwgdGhpcy5fdGltZUluZm8ubUhvdXJPZkRheSAhPSAtMSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJhbWJpZ3VpdHkgdGltZSBzdHJpbmciOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgaG91ck9mTWVyaURpZW09LTE7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJzZWQgPSB0aGlzLnBhcnNlSW50QWdncmVzc2l2ZSh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDEtMTIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyT2ZNZXJpRGllbSA9IHBhcnNlZC52YWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5uZWRDaGFyID0gcGFyc2VkLmxlbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyT2ZNZXJpRGllbSA9IHRoaXMucGFyc2VJbnRFeGFjdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDEtMTIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVJbmZvLm1Ib3VyT2ZNZXJpRGllbSA9IGhvdXJPZk1lcmlEaWVtIC0xOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Fzc2VydCh0aGlzLl90aW1lSW5mby5tSG91ck9mTWVyaURpZW0+PTAgJiYgdGhpcy5fdGltZUluZm8ubUhvdXJPZk1lcmlEaWVtPD0xMSwgIkludmFsaWQgSG91ciBPZiBNZXJpRGllbSB2YWx1ZS4iKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdrJzoKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl90aW1lSW5mby5tSG91ck9mTWVyaURpZW0gIT0gLTEgfHwgdGhpcy5fdGltZUluZm8ubUhvdXJPZkRheSAhPSAtMSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJhbWJpZ3VpdHkgdGltZSBzdHJpbmciOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgaG91ck9mTWVyaURpZW09LTE7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJzZWQgPSB0aGlzLnBhcnNlSW50QWdncmVzc2l2ZSh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDAtMTEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyT2ZNZXJpRGllbSA9IHBhcnNlZC52YWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5uZWRDaGFyID0gcGFyc2VkLmxlbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyT2ZNZXJpRGllbSA9IHRoaXMucGFyc2VJbnRFeGFjdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDAtMTEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVJbmZvLm1Ib3VyT2ZNZXJpRGllbSA9IGhvdXJPZk1lcmlEaWVtOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Fzc2VydCh0aGlzLl90aW1lSW5mby5tSG91ck9mTWVyaURpZW0+PTAgJiYgdGhpcy5fdGltZUluZm8ubUhvdXJPZk1lcmlEaWVtPD0xMSwgIkludmFsaWQgaG91ciBvZiBtZXJpRGllbSB2YWx1ZS4iKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdIJzoKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl90aW1lSW5mby5tSG91ck9mTWVyaURpZW0gIT0gLTEgfHwgdGhpcy5fdGltZUluZm8ubUhvdXJPZkRheSAhPSAtMSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJhbWJpZ3VpdHkgdGltZSBzdHJpbmciOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgaG91ck9mRGF5PS0xOwogICAgICAgICAgICAgICAgICAgIHN3aXRjaChjaHJDbnQpewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyc2VkID0gdGhpcy5wYXJzZUludEFnZ3Jlc3NpdmUodGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcsIGN1clBvcywgMik7IC8vIDEtMiBkaWdpdCgwLTIzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91ck9mRGF5ID0gcGFyc2VkLnZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbm5lZENoYXIgPSBwYXJzZWQubGVuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvdXJPZkRheSA9IHRoaXMucGFyc2VJbnRFeGFjdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDAtMjMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVJbmZvLm1Ib3VyT2ZEYXkgPSBob3VyT2ZEYXk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXNzZXJ0KHRoaXMuX3RpbWVJbmZvLm1Ib3VyT2ZEYXk+PTAgJiYgdGhpcy5fdGltZUluZm8ubUhvdXJPZkRheTw9MjMsICJJbnZhbGlkIGhvdXIgb2YgZGF5IHZhbHVlLiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ0snOgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX3RpbWVJbmZvLm1Ib3VyT2ZNZXJpRGllbSAhPSAtMSB8fCB0aGlzLl90aW1lSW5mby5tSG91ck9mRGF5ICE9IC0xKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgImFtYmlndWl0eSB0aW1lIHN0cmluZyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBob3VyT2ZEYXk9LTE7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJzZWQgPSB0aGlzLnBhcnNlSW50QWdncmVzc2l2ZSh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDAtMjMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyT2ZEYXkgPSBwYXJzZWQudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FubmVkQ2hhciA9IHBhcnNlZC5sZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91ck9mRGF5ID0gdGhpcy5wYXJzZUludEV4YWN0KHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCBjdXJQb3MsIDIpOyAvLyAxLTIgZGlnaXQoMC0yMykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGltZUluZm8ubUhvdXJPZkRheSA9IGhvdXJPZkRheSAtIDE7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXNzZXJ0KHRoaXMuX3RpbWVJbmZvLm1Ib3VyT2ZEYXk+PTAgJiYgdGhpcy5fdGltZUluZm8ubUhvdXJPZkRheTw9MjMsICJJbnZhbGlkIGhvdXIgb2YgZGF5IHZhbHVlLiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnTSc6CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fdGltZUluZm8ubU1pbnV0ZU9mSG91ciAhPSAtMSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJhbWJpZ3VpdHkgdGltZSBzdHJpbmciOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgbWludXRlT2ZIb3VyPS0xOwogICAgICAgICAgICAgICAgICAgIHN3aXRjaChjaHJDbnQpewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyc2VkID0gdGhpcy5wYXJzZUludEFnZ3Jlc3NpdmUodGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcsIGN1clBvcywgMik7IC8vIDEtMiBkaWdpdCgwLTU5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlT2ZIb3VyID0gcGFyc2VkLnZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbm5lZENoYXIgPSBwYXJzZWQubGVuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZU9mSG91ciA9IHRoaXMucGFyc2VJbnRFeGFjdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDAtNTkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVJbmZvLm1NaW51dGVPZkhvdXIgPSBtaW51dGVPZkhvdXI7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXNzZXJ0KHRoaXMuX3RpbWVJbmZvLm1NaW51dGVPZkhvdXI+PTAgJiYgdGhpcy5fdGltZUluZm8ubU1pbnV0ZU9mSG91cjw9NTksICJJbnZhbGlkIG1pbnV0ZSBvZiBob3VyLiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnUyc6CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fdGltZUluZm8ubVNlY29uZE9mTWludXRlICE9IC0xKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgImFtYmlndWl0eSB0aW1lIHN0cmluZyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBzZWNvbmRPZk1pbnV0ZT0tMTsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2goY2hyQ250KXsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcnNlZCA9IHRoaXMucGFyc2VJbnRBZ2dyZXNzaXZlKHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCBjdXJQb3MsIDIpOyAvLyAxLTIgZGlnaXQoMC01OSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZE9mTWludXRlID0gcGFyc2VkLnZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbm5lZENoYXIgPSBwYXJzZWQubGVuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZE9mTWludXRlID0gdGhpcy5wYXJzZUludEV4YWN0KHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCBjdXJQb3MsIDIpOyAvLyAxLTIgZGlnaXQoMC01OSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGltZUluZm8ubVNlY29uZE9mTWludXRlID0gc2Vjb25kT2ZNaW51dGU7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXNzZXJ0KHRoaXMuX3RpbWVJbmZvLm1TZWNvbmRPZk1pbnV0ZT49MCAmJiB0aGlzLl90aW1lSW5mby5tU2Vjb25kT2ZNaW51dGU8PTU5LCAiSW52YWxpZCBzZWNvbmQgb2YgbWludXRlLiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnRic6CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Fzc2VydChjaHJDbnQ9PTMsICJJbnZhbGlkIHBhdHRlcm4gRi4iKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl90aW1lSW5mby5tVGhvdXNhbmR0aE9mU2Vjb25kID0gdGhpcy5wYXJzZUludEV4YWN0KHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCBjdXJQb3MsIDMpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Fzc2VydCh0aGlzLl90aW1lSW5mby5tVGhvdXNhbmR0aE9mU2Vjb25kPj0wICYmIHRoaXMuX3RpbWVJbmZvLm1UaG91c2FuZHRoT2ZTZWNvbmQ8PTk5OSwgIkludmFsaWQgdGhvdXNhbmQgb2Ygc2Vjb25kLiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93ICJVbnN1cHBvcnRlZCBwYXR0ZXJuIjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fc3RyUG9zICs9IHNjYW5uZWRDaGFyOwogICAgICAgIH0sCgogICAgICAgIHBhcnNlSW50QWdncmVzc2l2ZSA6IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMucGFyc2VJbnRBZ2dyZXNzaXZlLAoKICAgICAgICBwYXJzZUludEV4YWN0IDogeGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYXJzZUludEV4YWN0LAoKICAgICAgICBnZXRSZXN1bHQgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZUluZm8uZ2V0SVNPVGltZSgpOwogICAgICAgIH0sCgogICAgICAgIGdldFRpbWVJbmZvIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVJbmZvOwogICAgICAgIH0sCgogICAgICAgIF9hc3NlcnQgOiBmdW5jdGlvbihjb25kaXRpb24sIG1lc3NhZ2UpewogICAgICAgICAgICBpZighY29uZGl0aW9uKXsKICAgICAgICAgICAgICAgIHRocm93IG1lc3NhZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKfSkoXyx4ZmFsaWIpOwoKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlRleHRQYXJzaW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5QYXJzaW5nVmlzaXRvckJhc2UKICoKICogQGZpbGVPdmVydmlldyBQYXJzZXMgYSBzdHJpbmcgYWNjb3JkaW5nIHRvIFRleHQgUGljdHVyZS4KICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nLCBfZGF0YVN0cmluZzogU3RyaW5nXX0KICovCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgVGV4dFBhcnNpbmdWaXNpdG9yID0geGZhbGliLnV0LlRleHRQYXJzaW5nVmlzaXRvciA9IHhmYWxpYi51dC5QYXJzaW5nVmlzaXRvckJhc2UuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIFRleHRQYXJzaW5nVmlzaXRvci5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLl9idWZmZXIgPSBbXTsKICAgICAgICB9LAoKICAgICAgICBjb25zdW1lU3ViUGF0dGVybiA6IGZ1bmN0aW9uKHRva2VuKXsKICAgICAgICAgICAgdmFyIGNociA9IHRva2VuLnBhdENoYXI7CiAgICAgICAgICAgIHZhciBjaHJDbnQgPSB0b2tlbi5sZW47CiAgICAgICAgICAgIGZvcih2YXIgaW5kZXggPSAwOyBpbmRleCA8IGNockNudDsgaW5kZXgrKyl7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGNocikgewogICAgICAgICAgICAgICAgICAgIGNhc2UgJzknOiAvLyBOdW1lcmljCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjVW5pID0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcuY2hhckF0KHRoaXMuX3N0clBvcysrKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIXhmYWxpYi51dC5QaWN0dXJlVXRpbHMuaXNEaWdpdChjVW5pKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCBhIGRpZ2l0IGFzIGV4cGVjdGVkIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChjVW5pKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnQSc6IC8vIEFscGhlYmV0aWMKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNVbmkgPSB0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy5jaGFyQXQodGhpcy5fc3RyUG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICBpZigheGZhbGliLnV0LlBpY3R1cmVVdGlscy5pc0xldHRlcihjVW5pKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCBhIGNoYXJhY3RlciBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goY1VuaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ08nOiAvLyBBbHBoYW51bWVyaWMKICAgICAgICAgICAgICAgICAgICBjYXNlICcwJzoKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNVbmkgPSB0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy5jaGFyQXQodGhpcy5fc3RyUG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICBpZigheGZhbGliLnV0LlBpY3R1cmVVdGlscy5pc0xldHRlck9yRGlnaXQoY1VuaSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBjaGFyYWN0ZXIgb3IgZGlnaXQgYXMgZXhwZWN0ZWQiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKGNVbmkpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICdYJzoKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNVbmkgPSB0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy5jaGFyQXQodGhpcy5fc3RyUG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChjVW5pKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAndCc6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLmNoYXJBdCh0aGlzLl9zdHJQb3MrKyk9PSJcdCIpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goIlx0Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBUYWIgYXMgZXhwZWN0ZWQiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLmNoYXJBdCh0aGlzLl9zdHJQb3MrKyk9PSBjaHIpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goY2hyKTsKICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCAnIiArIGNocisiJyBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICB9LAogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgZ2V0UmVzdWx0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgaWYodGhpcy5fc3RyUG9zIDwgdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcubGVuZ3RoKQogICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBwaWN0dXJlIGNsYXVzZSBzbWFsbGVyIHRoYW4gaW5wdXQgVGV4dCI7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIuam9pbigiIik7CiAgICAgICAgfSwKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqIEBvdmVycmlkZQogICAgICAgICAqLwogICAgICAgIGFjY2VwdFBhdHRlcm5DaGFyIDogZnVuY3Rpb24oY2hyKXsKICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuaW5TdHJpbmcoY2hyLCAiOUFPMFh0Iik7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLHhmYWxpYik7CgoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5OdW1QYXJzaW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5QYXJzaW5nVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBQYXJzZXMgYSBzdHJpbmcgYWNjb3JkaW5nIHRvIFRleHQgUGljdHVyZS4KICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nLF9kYXRhU3RyaW5nOiBTdHJpbmd9fQogKi8KCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgTnVtUGFyc2luZ1Zpc2l0b3IgPSB4ZmFsaWIudXQuTnVtUGFyc2luZ1Zpc2l0b3IgPSB4ZmFsaWIudXQuUGFyc2luZ1Zpc2l0b3JCYXNlLmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgdGhpcy5fcGljdHVyZURlc2MgPSBuZXcgeGZhbGliLnV0Lk51bVBpY3R1cmVEZXNjKHtqc29uTW9kZWw6e19zUGljdHVyZTp0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmV9fSk7CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZSA9IHRoaXMuX3BpY3R1cmVEZXNjLmdldFBpY3R1cmUoKTsKICAgICAgICAgICAgdGhpcy5fYnVmZmVyID0gW107CiAgICAgICAgICAgIHRoaXMuX3N0clBvcyA9IDA7CiAgICAgICAgICAgIHRoaXMuX2hhc1JhZGl4ID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuX21iTmVnYXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgdGhpcy5fbWJEaWdpdFNlZW4gPSBmYWxzZTsgLy8gYXQgbGVhc3Qgb25lIGRpZ2l0IGhhcyBiZWVuIGFkZGVkIHRvIG91dHB1dAogICAgICAgICAgICB0aGlzLl9tYlNpZ25TZWVuID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuX21CYWNrdHJhY2sgPSBudWxsOwogICAgICAgICAgICB0aGlzLl9oYXNQZXJjZW50ID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuX21iRXhwb25TZWVuID0gZmFsc2U7CgogICAgICAgICAgICB0aGlzLl9tTnVtYmVyU3ltYm9scyA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KHRoaXMub3B0aW9ucy5fbG9jYWxlLCJudW1iZXJTeW1ib2xzIik7CiAgICAgICAgICAgIHRoaXMuX21DdXJyZW5jeVN5bWJvbHMgPSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmdldExvY2FsZU9iamVjdCh0aGlzLm9wdGlvbnMuX2xvY2FsZSwiY3VycmVuY3lTeW1ib2xzIik7CiAgICAgICAgfSwKCiAgICAgICAgX2xvb2t1cE5leHQgOiB4ZmFsaWIudXQuU2Nhbm5lci5sb29rdXBOZXh0LAoKICAgICAgICBwYXJzZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciBwYXRQb3MgPSAwOwogICAgICAgICAgICB3aGlsZSh0cnVlKXsKICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICBmb3IodmFyIHRva2VuID0gdGhpcy5fbG9va3VwTmV4dCh0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmUsIHBhdFBvcywgdGhpcy5hY2NlcHRQYXR0ZXJuQ2hhcik7IHRva2VuICE9IG51bGw7ICApewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnN1bWUodG9rZW4pOwogICAgICAgICAgICAgICAgICAgICAgICBwYXRQb3MgPSBwYXRQb3MgKyB0b2tlbi5sZW47CiAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuID0gdGhpcy5fbG9va3VwTmV4dCh0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmUsIHBhdFBvcywgdGhpcy5hY2NlcHRQYXR0ZXJuQ2hhcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfWNhdGNoKGUpewogICAgICAgICAgICAgICAgICAgIC8vbWlzbWF0Y2gsIHRyeSBhZ2FpbiEKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl9tQmFja3RyYWNrKXsKICAgICAgICAgICAgICAgICAgICAgICAgcGF0UG9zID0gdGhpcy5fbUJhY2t0cmFjay5wYXRQb3M7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5sZW5ndGggPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdHJQb3MgPSB0aGlzLl9tQmFja3RyYWNrLnN0clBvczsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJEaWdpdFNlZW4gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbUJhY2t0cmFjayA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb25zdW1lU3ViUGF0dGVybiA6IGZ1bmN0aW9uKHRva2VuKXsKCiAgICAgICAgICAgIHZhciBjaHIgPSB0b2tlbi5wYXRDaGFyOwogICAgICAgICAgICB2YXIgY2hyQ250ID0gdG9rZW4ubGVuOwogICAgICAgICAgICB2YXIgZncgPSBmYWxzZTsKICAgICAgICAgICAgc3dpdGNoIChjaHIpIHsKICAgICAgICAgICAgICAgIGNhc2UgJzknOgogICAgICAgICAgICAgICAgY2FzZSAnOCc6CiAgICAgICAgICAgICAgICBjYXNlICdaJzogLy8gRGlnaXQgb3Igc3BhY2UgaWYgemVyby4KICAgICAgICAgICAgICAgIGNhc2UgJ3onOi8vIERpZ2l0IG9yIG5vdGhpbmcgaWYgemVyby4KICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hyQ250LS0gPiAwICkgewogICAgICAgICAgICAgICAgICAgICAgICBpZighdGhpcy5fbWJEaWdpdFNlZW4pewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNVbmkgPSB0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy5jaGFyQXQodGhpcy5fc3RyUG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNVbmkgPT0gJy0nKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYk5lZ2F0aXZlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjVW5pID0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcuY2hhckF0KCsrdGhpcy5fc3RyUG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNocj09ICc5JyB8fCBjaHIgPT0gJzgnKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZigheGZhbGliLnV0LlBpY3R1cmVVdGlscy5pc0RpZ2l0KGNVbmkpKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBkaWdpdCBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKGNVbmkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iRGlnaXRTZWVuID10cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2UgaWYoY2hyID09J1onKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZih4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmlzRGlnaXQoY1VuaSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChjVW5pKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJEaWdpdFNlZW4gPXRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2UgaWYoY1VuaSAhPSAnICcpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCBhIGRpZ2l0IG9yIHNwYWNlIGFzIGV4cGVjdGVkIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFzIHRvIGJlICd6JywgZWFnZXJseSB0cnkgdG8gbWF0Y2ggYSBkaWdpdCwgaWYgYSBtaXNtYXRjaCBpcyBsYXR0ZXJseSBmb3VuZCwgYmFja3RyYWNrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoeGZhbGliLnV0LlBpY3R1cmVVdGlscy5pc0RpZ2l0KGNVbmkpKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goY1VuaSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iRGlnaXRTZWVuID10cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tQmFja3RyYWNrID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBhdFBvcyIgOiB0b2tlbi5wYXRQb3MgKyB0b2tlbi5sZW4gLSBjaHJDbnQsIC8vbmV3IHBvc2l0aW9uIGZyb20gbmV4dCBjaGFyIGFmdGVyICd6JwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN0clBvcyIgOiB0aGlzLl9zdHJQb3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJUZXh0UGFyc2luZzogbm90IGEgZGlnaXQgb3Igc3BhY2UgYXMgZXhwZWN0ZWQiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICsrdGhpcy5fc3RyUG9zOwogICAgICAgICAgICAgICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjVW5pID0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcuY2hhckF0KHRoaXMuX3N0clBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZih4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmlzRGlnaXQoY1VuaSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKGNVbmkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsrdGhpcy5fc3RyUG9zOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2hyICE9J3onKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBkaWdpdCBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsrdGhpcy5fc3RyUG9zOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdWJyA6CiAgICAgICAgICAgICAgICBjYXNlICd2JyA6CiAgICAgICAgICAgICAgICBjYXNlICcuJyA6CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fbWF0Y2hTdHIodGhpcy5fbU51bWJlclN5bWJvbHMuZGVjaW1hbCkpewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYXNSYWRpeCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKCcuJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iRGlnaXRTZWVuID10cnVlOwogICAgICAgICAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCBhIHJhZGl4IGFzIGV4cGVjdGVkIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdFJzogLy8gRXhwb25lbnQuCiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fbWF0Y2hTdHIoJ0UnKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKCdFJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX21hdGNoU3RyKCcrJykpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2UgaWYodGhpcy5fbWF0Y2hTdHIoJy0nKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC5fYnVmZmVyLnB1c2goJy0nKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyTGVuID0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSh0aGlzLl9zdHJQb3MgPCBzdHJMZW4gJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuaXNEaWdpdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy5jaGFyQXQodGhpcy5fc3RyUG9zKSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2godGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcuY2hhckF0KHRoaXMuX3N0clBvcysrKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnQyc6IC8vIENSIHN5bWJvbCBpZiBuZWdhdGl2ZSBhbmQgc3BhY2VzIGlmIHBvc2l0aXZlLgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX21hdGNoU3RyKHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYy5nc0NSKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iTmVnYXRpdmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH1lbHNlIGlmKCF0aGlzLl9tYXRjaFN0cih4ZmFsaWIudXQuTnVtUGljdHVyZURlc2MuZ3NEU1ApKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBDUiBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnYyc6IC8vIENSIHN5bWJvbCBpZiBuZWdhdGl2ZSBhbmQgbm90aGluZyBpZiBwb3NpdGl2ZS4KICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl9tYXRjaFN0cih4ZmFsaWIudXQuTnVtUGljdHVyZURlc2MuZ3NDUikpewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYk5lZ2F0aXZlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdEJzogLy8gREIgc3ltYm9sIGlmIG5lZ2F0aXZlIGFuZCBzcGFjZXMgaWYgcG9zaXRpdmUuCiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fbWF0Y2hTdHIoeGZhbGliLnV0Lk51bVBpY3R1cmVEZXNjLmdzREIpKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJOZWdhdGl2ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfWVsc2UgaWYoIXRoaXMuX21hdGNoU3RyKHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYy5nc0RTUCkpewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCBhIENSIGFzIGV4cGVjdGVkIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdkJzogLy8gREIgc3ltYm9sIGlmIG5lZ2F0aXZlIGFuZCBub3RoaW5nIGlmIHBvc2l0aXZlLgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX21hdGNoU3RyKHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYy5nc0RCKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iTmVnYXRpdmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ1MnOiAvLyBNaW51cyBzaWduIGlmIG5lZ2F0aXZlIGFuZCBhIHNwYWNlIGlmIHBvc2l0aXZlLgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX21hdGNoU3RyKHRoaXMuX21OdW1iZXJTeW1ib2xzLm5lZ2F0aXZlLGZ3KSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iTmVnYXRpdmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH1lbHNlIGlmKCF0aGlzLl9tYXRjaFN0cigiICIpKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBDUiBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAncyc6CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fbWF0Y2hTdHIodGhpcy5fbU51bWJlclN5bWJvbHMubmVnYXRpdmUsZncpKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJOZWdhdGl2ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAweEZGMEM6IC8vIEZ1bGx3aWR0aCAnLCcuCiAgICAgICAgICAgICAgICBjYXNlICcsJzogLy8gR3JvdXBpbmcgc2VwYXJhdG9yLgogICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaHJDbnQtLSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIXRoaXMuX21hdGNoU3RyKHRoaXMuX21OdW1iZXJTeW1ib2xzLmdyb3VwaW5nLCBmdykpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBncm91cGluZyBzeW1ib2wgYXMgZXhwZWN0ZWQiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAweEZGMDQ6IC8vIEZ1bGx3aWR0aCAnJCcuCiAgICAgICAgICAgICAgICBjYXNlICckJzogLy8gQ3VycmVuY3kgbmFtZSBvciBzeW1ib2wuCiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNockNudC0tID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZighdGhpcy5fbWF0Y2hTdHIodGhpcy5fbUN1cnJlbmN5U3ltYm9scy5zeW1ib2wsIGZ3KSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCBhIGdyb3VwaW5nIHN5bWJvbCBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDB4RkYwNTogLy8gRnVsbHdpZHRoICclJy4KICAgICAgICAgICAgICAgIGNhc2UgJyUnOiAvLyBQZXJjZW50IHN5bWJvbC4KICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hyQ250LS0gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCF0aGlzLl9tYXRjaFN0cih0aGlzLl9tTnVtYmVyU3ltYm9scy5wZXJjZW50LCBmdykpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBncm91cGluZyBzeW1ib2wgYXMgZXhwZWN0ZWQiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhc1BlcmNlbnQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAweEZGMDg6IC8vIEZ1bGx3aWR0aCAnKCcuCiAgICAgICAgICAgICAgICBjYXNlIDB4RkYwOTogLy8gRnVsbHdpZHRoICcpJy4KICAgICAgICAgICAgICAgIGNhc2UgJygnOiAvLyBMZWZ0IHBhcmVudGhlc2lzLgogICAgICAgICAgICAgICAgY2FzZSAnKSc6IC8vIFJpZ2h0IHBhcmVudGhlc2lzLgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX21hdGNoU3RyKGNocixmdykpewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYk5lZ2F0aXZlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9ZWxzZSBpZighdGhpcy5fbWF0Y2hTdHIoIiAiKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJUZXh0UGFyc2luZzogbm90IHBhcmVudGVzaXMgYXMgZXhwZWN0ZWQiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ3QnOiAvLyB0YWIuCiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNockNudC0tID4gMCkgdGhpcy5fbWF0Y2hTdHIoJ1x0Jyxmdyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGdldFJlc3VsdCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciBzdHJpbmdOdW0gPSAgdGhpcy5fYnVmZmVyLmpvaW4oIiIpOwogICAgICAgICAgICBpZih0aGlzLl9oYXNQZXJjZW50KSB7CiAgICAgICAgICAgICAgICB2YXIgYnVmID0gbmV3IEFycmF5KCk7CiAgICAgICAgICAgICAgICBzdHJpbmdOdW0gPSBOdW1iZXIoc3RyaW5nTnVtKS50b1N0cmluZygpOwogICAgICAgICAgICAgICAgdmFyIGRvdCA9IHN0cmluZ051bS5pbmRleE9mKCcuJyk7CgogICAgICAgICAgICAgICAgdmFyIHBvcyA9IGRvdC0yOwogICAgICAgICAgICAgICAgaWYocG9zID09MCkgYnVmLnB1c2goIjAiKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYocG9zID09LTEpIGJ1Zi5wdXNoKCIwLjAiKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYocG9zID09LTMpIHBvcyA9IHN0cmluZ051bS5sZW5ndGggLSAyOwogICAgICAgICAgICAgICAgZm9yKHZhciBpbmRleD0wO2luZGV4IDwgc3RyaW5nTnVtLmxlbmd0aDsgaW5kZXgrKyl7CiAgICAgICAgICAgICAgICAgICAgaWYoaW5kZXggPT0gcG9zKXsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goIi4iKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYoaW5kZXggIT0gZG90KXsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goc3RyaW5nTnVtLmNoYXJBdChpbmRleCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHN0cmluZ051bSA9IGJ1Zi5qb2luKCIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgbnVtYmVyID0gTnVtYmVyKHN0cmluZ051bSk7CiAgICAgICAgICAgIGlmKHRoaXMuX21iTmVnYXRpdmUpIG51bWJlciA9IC1udW1iZXI7CiAgICAgICAgICAgIHJldHVybiBudW1iZXIudG9TdHJpbmcoKTsKICAgICAgICB9LAoKICAgICAgICBfbWF0Y2hTdHIgOiBmdW5jdGlvbih0YXJnZXQpewogICAgICAgICAgICBpZih4ZmFsaWIudXQuUGljdHVyZVV0aWxzLm1hdGNoU3RyaW5nKHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCB0aGlzLl9zdHJQb3MsIHRhcmdldCkpewogICAgICAgICAgICAgICAgdGhpcy5fc3RyUG9zKz0gdGFyZ2V0Lmxlbmd0aDsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgYWNjZXB0UGF0dGVybkNoYXIgOiBmdW5jdGlvbihjaHIpewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlBpY3R1cmVVdGlscy5pblN0cmluZyhjaHIsICIoJSQsLik4OUJDREVSU1ZaYmNkcnN2enQiKTsKICAgICAgICB9CiAgICB9KTsKfSkoXyx4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LkRhdGVQYXJzaW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5QYXJzaW5nVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBwcm92aWRlcyBwYXJzaW5nL2Zvcm1hdGluZyBsb2dpYyBvbiBkYXRlIHBhdHRlcm4gY2hhcmFjdGVycy4KICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nLCBfZGF0YVN0cmluZzogU3RyaW5nXX0KICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpIHsKICAgIHZhciBEYXRlUGFyc2luZ1Zpc2l0b3IgPSB4ZmFsaWIudXQuRGF0ZVBhcnNpbmdWaXNpdG9yID0geGZhbGliLnV0LlBhcnNpbmdWaXNpdG9yQmFzZS5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdGhpcy5fZGF0ZUluZm8gPSBuZXcgeGZhbGliLnV0LkRhdGVJbmZvKHtpc1BhcnNpbmdDYWxsIDogdHJ1ZX0pOwogICAgICAgICAgICB0aGlzLl9kYXlPZk1vbnRoID0gdGhpcy5fbW9udGhPZlllYXIgPSB0aGlzLl95ZWFyT2ZFcmEgPSBudWxsOyAvLyB1c2VkIHRvIHZhbGlkYXRlIGRhdGUgb25jZSBhbGwgc3ViIHBhdHRlcm5zIGFyZSBjb25zdW1lZAogICAgICAgICAgICBEYXRlUGFyc2luZ1Zpc2l0b3IuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICB9LAoKICAgICAgICBjb25zdW1lU3ViUGF0dGVybiA6IGZ1bmN0aW9uKHRva2VuKXsKICAgICAgICAgICAgdmFyIGNociA9IHRva2VuLnBhdENoYXI7CiAgICAgICAgICAgIHZhciBjaHJDbnQgPSB0b2tlbi5sZW47CiAgICAgICAgICAgIHZhciBjdXJQb3MgPSB0aGlzLl9zdHJQb3M7CiAgICAgICAgICAgIHZhciBzY2FubmVkQ2hhciA9IGNockNudDsKCiAgICAgICAgICAgIC8vVE9ETzogbmVlZCB0byByZW1vdmUgdGhpcyBhc3NlcnQuCiAgICAgICAgICAgIHRoaXMuX2Fzc2VydChjdXJQb3MrY2hyQ250IDw9dGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcubGVuZ3RoLCAiTWlzbWF0Y2giKTsKCiAgICAgICAgICAgIHN3aXRjaCAoY2hyKSB7CiAgICAgICAgICAgICAgICBjYXNlICdEJzoKICAgICAgICAgICAgICAgICAgICBzd2l0Y2goY2hyQ250KXsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcnNlZCA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMucGFyc2VJbnRBZ2dyZXNzaXZlKHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCBjdXJQb3MsIDIpOyAvLyAxLTIgZGlnaXQoMS0zMSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2RheU9mTW9udGggPSBwYXJzZWQudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FubmVkQ2hhciA9IHBhcnNlZC5sZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGF5T2ZNb250aCA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMucGFyc2VJbnRFeGFjdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDEtMzEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXNzZXJ0KHRoaXMuX2RheU9mTW9udGggPD0gMzEgJiYgdGhpcy5fZGF5T2ZNb250aCA+MCwgIkludmFsaWQgZGF0ZSBzdHJpbmcxIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdKJzoKCiAgICAgICAgICAgICAgICAgICAgLy90aGlzLl9tRGF5T2ZZZWFyOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnTSc6CiAgICAgICAgICAgICAgICAgICAgdmFyIHN5bWJvbCA9ICIiOwogICAgICAgICAgICAgICAgICAgIHN3aXRjaChjaHJDbnQpewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyc2VkID0geGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYXJzZUludEFnZ3Jlc3NpdmUodGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcsIGN1clBvcywgMik7IC8vIDEtMiBkaWdpdCgxLTEyKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbW9udGhPZlllYXIgPSBwYXJzZWQudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FubmVkQ2hhciA9IHBhcnNlZC5sZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbW9udGhPZlllYXIgPSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLnBhcnNlSW50RXhhY3QodGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcsIGN1clBvcywgMik7IC8vIDIgZGlnaXQoMDEtMTIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltYm9sID0gImNhbGVuZGFyU3ltYm9scy5hYmJybW9udGhOYW1lcyI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltYm9sID0gImNhbGVuZGFyU3ltYm9scy5tb250aE5hbWVzIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZihzeW1ib2wpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2hPYmogPSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmdldEhhc2hPZkxvY2FsZU9iamVjdCh0aGlzLmpzb25Nb2RlbC5fbG9jYWxlLHN5bWJvbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIgPSB0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy50b0xvd2VyQ2FzZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzaCA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJTdHIgPSAiIgogICAgICAgICAgICAgICAgICAgICAgICBzY2FubmVkQ2hhciA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlKGN1clBvcytzY2FubmVkQ2hhciA8IHN0ci5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc2ggKz0gKHNjYW5uZWRDaGFyKzEpKnN0ci5jaGFyQ29kZUF0KGN1clBvcytzY2FubmVkQ2hhcikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1clN0cis9IHN0ci5jaGFyQXQoY3VyUG9zK3NjYW5uZWRDaGFyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5uZWRDaGFyKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihoYXNoT2JqW2hhc2hdICYmIGhhc2hPYmpbaGFzaF0uaW5kZXhPZihjdXJTdHIpID4gLTEgKSBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbW9udGhOYW1lcyA9IF8ubWFwKHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsIHN5bWJvbCksIGZ1bmN0aW9uIChzdHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHIudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoT2ZZZWFyID0gbW9udGhOYW1lcy5pbmRleE9mKGN1clN0cikgKyAxOyAvLyBtb250aHMgYXJlIGZyb20gMSB0byAxMgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvL1RPRE86IHJlbW92ZSB0aGlzIGFzc2VydAogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Fzc2VydCh0aGlzLl9tb250aE9mWWVhciA8PSAxMiAmJiB0aGlzLl9tb250aE9mWWVhciA+MCwgIkludmFsaWQgZGF0ZSBzdHJpbmcyIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdFJzoKICAgICAgICAgICAgICAgICAgICB2YXIgc3ltYm9sID0gIiIKICAgICAgICAgICAgICAgICAgICBzd2l0Y2goY2hyQ250KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5uZWRDaGFyID0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1ib2wgPSAiY2FsZW5kYXJTeW1ib2xzLmFiYnJkYXlOYW1lcyI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltYm9sID0gImNhbGVuZGFyU3ltYm9scy5kYXlOYW1lcyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgInVuc3VwcG9ydGVkIFBpY3R1cmUgQ2xhdXNlICI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmKHN5bWJvbCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGFzaE9iaiA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0SGFzaE9mTG9jYWxlT2JqZWN0KHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsc3ltYm9sKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbm5lZENoYXIgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyID0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2ggPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyU3RyID0gIiI7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlKGN1clBvcytzY2FubmVkQ2hhciA8IHN0ci5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc2ggKz0gKHNjYW5uZWRDaGFyKzEpKnN0ci5jaGFyQ29kZUF0KGN1clBvcytzY2FubmVkQ2hhcikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1clN0cis9IHN0ci5jaGFyQXQoY3VyUG9zK3NjYW5uZWRDaGFyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5uZWRDaGFyKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihoYXNoT2JqW2hhc2hdICYmIGhhc2hPYmpbaGFzaF0uaW5kZXhPZihjdXJTdHIpID4gLTEpIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2UnOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnRyc6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdZJzoKCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3llYXJPZkVyYSA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMucGFyc2VJbnRFeGFjdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMiBkaWdpdCgwMC05OSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3llYXJPZkVyYSs9MjAwMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX3llYXJPZkVyYSA+PSAyMDI5KXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl95ZWFyT2ZFcmEgLT0xMDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feWVhck9mRXJhID0geGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYXJzZUludEV4YWN0KHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCBjdXJQb3MsIDQpOyAvLyAyIGRpZ2l0KDAwMDAtOTk5OSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXNzZXJ0KHRoaXMuX3llYXJPZkVyYSA8PSA5OTk5ICYmIHRoaXMuX3llYXJPZkVyYSA+PTAsICJJbnZhbGlkIGRhdGUgc3RyaW5nMyIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAndyc6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdXJzoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93ICJVbnN1cHBvcnRlZCBwYXR0ZXJuIjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYodGhpcy5feWVhck9mRXJhICYmIHRoaXMuX21vbnRoT2ZZZWFyICYmIHRoaXMuX2RheU9mTW9udGgpewogICAgICAgICAgICAgICAgdGhpcy5fZGF0ZUluZm8udmFsaWRhdGUodGhpcy5feWVhck9mRXJhLCB0aGlzLl9tb250aE9mWWVhciwgdGhpcy5fZGF5T2ZNb250aCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX3N0clBvcyArPSBzY2FubmVkQ2hhcjsKICAgICAgICB9LAoKICAgICAgICBnZXREYXRlIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGVJbmZvLmRhdGU7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0UmVzdWx0OiBmdW5jdGlvbigpewogICAgICAgICAgICBpZiAodGhpcy5fc3RyUG9zIDwgdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB0aHJvdyAiRGF0ZVBhcnNpbmc6IHBpY3R1cmUgY2xhdXNlIHNtYWxsZXIgdGhhbiBpbnB1dCBEYXRlIjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdGhpcy5fZGF0ZUluZm8uZ2V0SVNPRGF0ZSgpOwogICAgICAgIH0sCgogICAgICAgIF9hc3NlcnQgOiBmdW5jdGlvbihjb25kaXRpb24sIG1lc3NhZ2UpewogICAgICAgICAgICBpZighY29uZGl0aW9uKXsKICAgICAgICAgICAgICAgIHRocm93IG1lc3NhZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKfSkoXyx4ZmFsaWIpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogQURPQkUgQ09ORklERU5USUFMCiAqIF9fX19fX19fX19fX19fX19fX18KICoKICogIENvcHlyaWdodCAyMDEzIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuCiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewoKICAgIHZhciBMb2NhbGl6YXRpb25VdGlsID0geGZhbGliLnV0LkxvY2FsaXphdGlvblV0aWwgPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKCiAgICAgICAgZ2V0TG9jYWxpemVkTWVzc2FnZTogZnVuY3Rpb24oY2F0ZWdvcnksIG1lc3NhZ2UsIHNuaXBwZXRzKXsKICAgICAgICAgICAgdmFyIHJlc29sdmVkTWVzc2FnZSA9IG1lc3NhZ2U7CiAgICAgICAgICAgIGlmKHNuaXBwZXRzKXsKICAgICAgICAgICAgICAgIC8vcmVzb2x2ZSBtZXNzYWdlIHdpdGggc25pcHBldAogICAgICAgICAgICAgICAgcmVzb2x2ZWRNZXNzYWdlID0gcmVzb2x2ZWRNZXNzYWdlLnJlcGxhY2UoL3soXGQrKX0vZywgZnVuY3Rpb24obWF0Y2gsIG51bWJlcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlb2Ygc25pcHBldHNbbnVtYmVyXSAhPSAndW5kZWZpbmVkJwogICAgICAgICAgICAgICAgICAgICAgICA/IHNuaXBwZXRzW251bWJlcl0KICAgICAgICAgICAgICAgICAgICAgICAgOiBtYXRjaAogICAgICAgICAgICAgICAgICAgICAgICA7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgdGV4dCA9ICIiOwogICAgICAgICAgICBpZiAoY2F0ZWdvcnkpIHsKICAgICAgICAgICAgICAgIHRleHQgKz0gIiBbIiArIGNhdGVnb3J5ICsgIl0iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRleHQgKz0gIiAgIiArIHJlc29sdmVkTWVzc2FnZSArICJcclxuIiA7CiAgICAgICAgICAgIHJldHVybiB0ZXh0OwogICAgICAgIH0KCiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogX19fX19fX19fX19fX19fX19fXwogKgogKiAgQ29weXJpZ2h0IDIwMTMgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LnV0aWwuVGV4dE1ldHJpY3MgPSB7CiAgICAgICAgeGZhVXRpbCA6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZSwKICAgICAgICBFUlJPUl9NQVJHSU4gOiAxLAogICAgICAgICRtZWFzdXJlRWwgOiBudWxsLAogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbihkaXZFbCl7CiAgICAgICAgICAgIGlmKCFkaXZFbCl7CiAgICAgICAgICAgICAgICB2YXIgJGRpdiA9ICQoIjxkaXY+PC9kaXY+Iik7CiAgICAgICAgICAgICAgICAkZGl2LmF0dHIoImlkIiwgInRleHRNZXRyaWNzIik7CiAgICAgICAgICAgICAgICB2YXIgZGl2U3R5bGVzID0ge307CiAgICAgICAgICAgICAgICBkaXZTdHlsZXMubGVmdCA9IC0xMDAwOwogICAgICAgICAgICAgICAgZGl2U3R5bGVzLnRvcCA9IC0xMDAwOwogICAgICAgICAgICAgICAgZGl2U3R5bGVzLnBvc2l0aW9uID0gImFic29sdXRlIjsKICAgICAgICAgICAgICAgIGRpdlN0eWxlcy52aXNpYmlsaXR5ID0gImhpZGRlbiI7CiAgICAgICAgICAgICAgICB0aGlzLnhmYVV0aWwuJGNzcygkZGl2LmdldCgwKSwgZGl2U3R5bGVzKTsKICAgICAgICAgICAgICAgIHRoaXMuJG1lYXN1cmVFbCA9ICRkaXY7CiAgICAgICAgICAgICAgICAkKCJib2R5IikuYXBwZW5kKHRoaXMuJG1lYXN1cmVFbCk7CiAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgdGhpcy4kbWVhc3VyZUVsID0gZGl2RWw7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBtZWFzdXJlRXh0ZW50IDogZnVuY3Rpb24odGV4dCwgb3B0aW9ucyl7CiAgICAgICAgICAgIHRleHQgPSB0ZXh0ICsgIiAiOwogICAgICAgICAgICBpZighdGhpcy4kbWVhc3VyZUVsKXsKICAgICAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogICAgICAgICAgICB2YXIgdGV4dFN0eWxlcyA9IHt9OwogICAgICAgICAgICB2YXIgJHJlZkVsID0gICQob3B0aW9ucy5yZWZFbCB8fCAiPGRpdj48L2Rpdj4iKSA7CiAgICAgICAgICAgIHZhciByZWZFbCA9ICRyZWZFbC5nZXQoMCk7CiAgICAgICAgICAgIHRleHRTdHlsZXMuZm9udFNpemUgPSAkcmVmRWwuY3NzKCJmb250U2l6ZSIpIHx8IG9wdGlvbnNbImZvbnQtc2l6ZSJdIHx8IG9wdGlvbnNbImZvbnRTaXplIl07CiAgICAgICAgICAgIHRleHRTdHlsZXMuZm9udFN0eWxlID0gJHJlZkVsLmNzcygiZm9udFN0eWxlIikgfHwgb3B0aW9uc1siZm9udC1zdHlsZSJdIHx8IG9wdGlvbnNbImZvbnRTdHlsZSJdOwogICAgICAgICAgICB0ZXh0U3R5bGVzLmZvbnRXZWlnaHQgPSAkcmVmRWwuY3NzKCJmb250V2VpZ2h0IikgfHwgb3B0aW9uc1siZm9udC13ZWlnaHQiXSB8fCBvcHRpb25zWyJmb250V2VpZ2h0Il07CiAgICAgICAgICAgIHRleHRTdHlsZXMuZm9udEZhbWlseSA9ICRyZWZFbC5jc3MoImZvbnRGYW1pbHkiKSB8fCBvcHRpb25zWyJmb250LWZhbWlseSJdIHx8IG9wdGlvbnNbImZvbnRGYW1pbHkiXTsKICAgICAgICAgICAgdGV4dFN0eWxlcy5saW5lSGVpZ2h0ID0gcmVmRWwuc3R5bGUubGluZUhlaWdodCB8fCBvcHRpb25zWyJsaW5lLWhlaWdodCJdIHx8IG9wdGlvbnNbImxpbmVIZWlnaHQiXTsKICAgICAgICAgICAgdGV4dFN0eWxlcy5sZXR0ZXJTcGFjaW5nID0gJHJlZkVsLmNzcygibGV0dGVyU3BhY2luZyIpIHx8IG9wdGlvbnNbImxldHRlci1zcGFjaW5nIl0gfHwgb3B0aW9uc1sibGV0dGVyU3BhY2luZyJdOwogICAgICAgICAgICB0ZXh0U3R5bGVzLndoaXRlU3BhY2UgPSAgJHJlZkVsLmNzcygid2hpdGVTcGFjZSIpIHx8IG9wdGlvbnNbIndoaXRlLXNwYWNlIl0gfHwgb3B0aW9uc1sid2hpdGVTcGFjZSJdIHx8ICJwcmUtd3JhcCI7CiAgICAgICAgICAgIGlmKCAkLmJyb3dzZXIubW96aWxsYSAmJiAkcmVmRWwuaXMoInRleHRhcmVhIikpICAgICAgLy8gZm9yIEJ1ZyAjMzYyMTE4MAogICAgICAgICAgICAgICAgdGV4dFN0eWxlcy53aGl0ZVNwYWNlID0gInByZS13cmFwIjsKICAgICAgICAgICAgdGV4dFN0eWxlcy53b3JkQnJlYWsgPSAgJHJlZkVsLmNzcygid29yZEJyZWFrIikgfHwgb3B0aW9uc1sid29yZC1icmVhayJdIHx8IG9wdGlvbnNbIndvcmRCcmVhayJdIHx8ICJicmVhay1hbGwiOwogICAgICAgICAgICB0ZXh0U3R5bGVzLndvcmRXcmFwID0gICRyZWZFbC5jc3MoIndvcmRXcmFwIikgfHwgb3B0aW9uc1sid29yZC13cmFwIl0gfHwgb3B0aW9uc1sid29yZFdyYXAiXSB8fCAiYnJlYWstd29yZCI7CiAgICAgICAgICAgIHRleHRTdHlsZXMud2lkdGggPSB0aGlzLl9lbFdpZHRoKHJlZkVsLCBvcHRpb25zKTsKICAgICAgICAgICAgdGV4dFN0eWxlcy5oZWlnaHQgPSB0aGlzLl9lbEhlaWdodChyZWZFbCwgb3B0aW9ucyk7CiAgICAgICAgICAgIHRleHRTdHlsZXMubWluV2lkdGggPSB0aGlzLl9lbE1pbldpZHRoKHJlZkVsLCBvcHRpb25zKTsKICAgICAgICAgICAgdGV4dFN0eWxlcy5taW5IZWlnaHQgPSB0aGlzLl9lbE1pbkhlaWdodChyZWZFbCwgb3B0aW9ucyk7CiAgICAgICAgICAgIHRleHRTdHlsZXMubWF4V2lkdGggPSB0aGlzLl9lbE1heFdpZHRoKHJlZkVsLCBvcHRpb25zKTsKICAgICAgICAgICAgdGV4dFN0eWxlcy5tYXhIZWlnaHQgPSB0aGlzLl9lbE1heEhlaWdodChyZWZFbCwgb3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMueGZhVXRpbC4kY3NzKHRoaXMuJG1lYXN1cmVFbC5nZXQoMCksIHRleHRTdHlsZXMpOwogICAgICAgICAgICAvLyBmb3IgdGV4dCBmaWVsZHMvYXJlYXMgYW5kIGRyYXcgcmVxdWlyaW5nIHJpY2ggdGV4dCBzdXBwb3J0CiAgICAgICAgICAgIGlmKG9wdGlvbnMuY29udGVudFR5cGUgPT09ICJ0ZXh0L2h0bWwiKXsKICAgICAgICAgICAgICAvLyByZXRhaW5pbmcgZm9yIGZ1dHVyZSB1c2UgLiBJZiB3ZSB1c2UgdGhlIGFib3ZlIHByb3BlcnR5IGZvciBvdGhlciByaWNoIHRleHQKICAgICAgICAgICAgICAgaWYob3B0aW9ucy5za2lwWFNTUHJvdGVjdGlvbikgewogICAgICAgICAgICAgICAgIHRoaXMuJG1lYXN1cmVFbC5odG1sKHRleHQpOwogICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgIHRoaXMuJG1lYXN1cmVFbC5odG1sKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5lbmNvZGVTY3JpcHRhYmxlVGFncyh0ZXh0KSk7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfWVsc2UgewogICAgICAgICAgICAgICB0ZXh0ID0gdGV4dC5yZXBsYWNlKC9cblxyL2csIlxuIikucmVwbGFjZSgvXHJcbi9nLCJcbiIpLnJlcGxhY2UoL1xyL2csICJcbiIpOwogICAgICAgICAgICAgICB0aGlzLiRtZWFzdXJlRWwudGV4dCh0ZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgbWVhc3VyZWRXaWR0aCA9ICB0aGlzLiRtZWFzdXJlRWwud2lkdGgoKTsKICAgICAgICAgICAgdmFyIG1lYXN1cmVkSGVpZ2h0ID0gIHRoaXMuJG1lYXN1cmVFbC5oZWlnaHQoKTsKCiAgICAgICAgICAgIGlmKG1lYXN1cmVkV2lkdGggPT0gTWF0aC5jZWlsKG9wdGlvbnNbIndpZHRoIl0pIHx8IG1lYXN1cmVkV2lkdGggPT0gTWF0aC5mbG9vcihvcHRpb25zWyJ3aWR0aCJdKSl7CiAgICAgICAgICAgICAgICBtZWFzdXJlZFdpZHRoID0gb3B0aW9uc1sid2lkdGgiXTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKgogICAgICAgICAgICAgRk9STVMtMTEzNjMgOiBmaXggZm9yIGhlaWdodCBjYWxjdWxhdGlvbiBvZiB0YWJsZSBjZWxsCiAgICAgICAgICAgICBFbmFibGUgdGhpcyB0b2dnbGUgZm9yIG9sZCBiZWhhdmlvdXIgKGlmIGFueSByZWdyZXNzaW9uIGNvbWVzKQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZWxzZSBpZiAoKHdpbmRvdy5GRCAmJiB3aW5kb3cuRkQuaXNUb2dnbGVFbmFibGVkKCJGVF9GT1JNUy0xMTM2MyIpKSAmJiAob3B0aW9uc1sibWF4V2lkdGgiXSA+IG1lYXN1cmVkV2lkdGggfHwgKG1lYXN1cmVkV2lkdGggPiBvcHRpb25zWyJtaW5XaWR0aCJdID4gMCAmJiAob3B0aW9uc1sibWF4V2lkdGgiXSB8fCAtMSkgPCAwKSkpIHsKICAgICAgICAgICAgICAgIC8vY29tcGxpY2F0ZWQsIHBsZWFzZSBzaW1wbGlmeSBpZiBiZWxvdyBodXJ0cyB5b3U6ICBBZGQgZXJyb3IgbWFyZ2luIGlmIHRoZXJlIGlzIHNjb3BlIG9mIGZ1cnRoZXIgZXh0ZW5zaW9uIG9mIGV4dGVudAogICAgICAgICAgICAgICAgbWVhc3VyZWRXaWR0aCA9IG1lYXN1cmVkV2lkdGggKyAxOwogICAgICAgICAgICB9IGVsc2UgaWYgKG9wdGlvbnNbIm1heFdpZHRoIl0gPiBtZWFzdXJlZFdpZHRoIHx8IChtZWFzdXJlZFdpZHRoID4gb3B0aW9uc1sibWluV2lkdGgiXSA+IDAgJiYgKG9wdGlvbnNbIm1heFdpZHRoIl0gfHwgLTEpIDwgMCkpIHsKICAgICAgICAgICAgICAgIC8vY29tcGxpY2F0ZWQsIHBsZWFzZSBzaW1wbGlmeSBpZiBiZWxvdyBodXJ0cyB5b3U6ICBBZGQgZXJyb3IgbWFyZ2luIGlmIHRoZXJlIGlzIHNjb3BlIG9mIGZ1cnRoZXIgZXh0ZW5zaW9uIG9mIGV4dGVudAogICAgICAgICAgICAgICAgbWVhc3VyZWRXaWR0aCA9IG1lYXN1cmVkV2lkdGg7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKG1lYXN1cmVkSGVpZ2h0ID09IE1hdGguY2VpbChvcHRpb25zWyJoZWlnaHQiXSkgfHwgbWVhc3VyZWRIZWlnaHQgPT0gTWF0aC5mbG9vcihvcHRpb25zWyJoZWlnaHQiXSkpewogICAgICAgICAgICAgICAgbWVhc3VyZWRIZWlnaHQgPSBvcHRpb25zWyJoZWlnaHQiXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKCAkcmVmRWwuaXMoInRleHRhcmVhIikgJiYgKG9wdGlvbnNbIm1heEhlaWdodCJdID4gbWVhc3VyZWRIZWlnaHQgfHwgKG1lYXN1cmVkSGVpZ2h0ID4gb3B0aW9uc1sibWluSGVpZ2h0Il0gPiAwICYmIChvcHRpb25zWyJtYXhIZWlnaHQiXSB8fCAtMSkgPCAwKSkpewogICAgICAgICAgICAgICAgbWVhc3VyZWRIZWlnaHQgPSBtZWFzdXJlZEhlaWdodCArMTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLiRtZWFzdXJlRWwuZW1wdHkoKTsKICAgICAgICAgICAgcmV0dXJuIHt3aWR0aCA6IG1lYXN1cmVkV2lkdGgsIGhlaWdodCA6IG1lYXN1cmVkSGVpZ2h0fTsKICAgICAgICB9LAoKICAgICAgICBfZWxXaWR0aCA6IGZ1bmN0aW9uKHJlZkVsLCBvcHRpb25zKXsKICAgICAgICAgICAgaWYob3B0aW9uc1sibWluV2lkdGgiXSAmJiBvcHRpb25zWyJtaW5XaWR0aCJdID4gLTEpCiAgICAgICAgICAgICAgICByZXR1cm4gImF1dG8iOwogICAgICAgICAgICBlbHNlIGlmKG9wdGlvbnNbIm1heFdpZHRoIl0gJiYgb3B0aW9uc1sibWF4V2lkdGgiXSA+IC0xKQogICAgICAgICAgICAgICAgcmV0dXJuICJhdXRvIjsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnNbIndpZHRoIl0gfHwgImF1dG8iOwogICAgICAgIH0sCgogICAgICAgIF9lbEhlaWdodCA6IGZ1bmN0aW9uKHJlZkVsLCBvcHRpb25zKXsKICAgICAgICAgICAgLy8gVE9ETzogY2hlY2sgZm9yIGNhbGN1bGF0aW9ucyBoZXJlIGZvciBmbG9hdGluZyBmaWVsZCBhbmQgb3RoZXIgY2FzZXMuCiAgICAgICAgICAgIGlmKG9wdGlvbnNbImNvbnRlbnRUeXBlIl0gPT09ICJ0ZXh0L2h0bWwiKQogICAgICAgICAgICAgICAgcmV0dXJuICJhdXRvIjsKICAgICAgICAgICAgaWYob3B0aW9ucy5pc0RyYXcpIHsgLy8gZm9yIGhhbmRsaW5nIHRoZSBjYXNlIG9mIGRyYXcgaGF2aW5nIGZsb2F0aW5nIGZpZWxkcwogICAgICAgICAgICAgICAgcmV0dXJuICJhdXRvIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZighJChyZWZFbCkuaXMoInRleHRhcmVhIikpCiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9uc1siaGVpZ2h0Il0gfHwgImF1dG8iOwogICAgICAgICAgICBpZihvcHRpb25zWyJtaW5IZWlnaHQiXSAmJiBvcHRpb25zWyJtaW5IZWlnaHQiXSA+IC0xKQogICAgICAgICAgICAgICAgcmV0dXJuICJhdXRvIjsKICAgICAgICAgICAgZWxzZSBpZihvcHRpb25zWyJtYXhIZWlnaHQiXSAmJiBvcHRpb25zWyJtYXhIZWlnaHQiXSA+IC0xKQogICAgICAgICAgICAgICAgcmV0dXJuICJhdXRvIjsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnNbImhlaWdodCJdIHx8ICJhdXRvIjsKICAgICAgICB9LAoKICAgICAgICBfZWxNaW5XaWR0aCA6IGZ1bmN0aW9uKHJlZkVsLCBvcHRpb25zKXsKICAgICAgICAgICAgaWYob3B0aW9uc1sibWluV2lkdGgiXSAmJiBvcHRpb25zWyJtaW5XaWR0aCJdID4gLTEpCiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9uc1sibWluV2lkdGgiXTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuICIwIjsgLy9kZWZhdWx0IGNzcyB2YWx1ZQogICAgICAgIH0sCgogICAgICAgIF9lbE1pbkhlaWdodCA6IGZ1bmN0aW9uKHJlZkVsLCBvcHRpb25zKXsKICAgICAgICAgICAgaWYob3B0aW9uc1sibWluSGVpZ2h0Il0gJiYgb3B0aW9uc1sibWluSGVpZ2h0Il0gPiAtMSkKICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zWyJtaW5IZWlnaHQiXTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuICIwIjsgLy9kZWZhdWx0IGNzcyB2YWx1ZQogICAgICAgIH0sCgogICAgICAgIF9lbE1heFdpZHRoIDogZnVuY3Rpb24ocmVmRWwsIG9wdGlvbnMpewogICAgICAgICAgICBpZihvcHRpb25zWyJtYXhXaWR0aCJdICYmIG9wdGlvbnNbIm1heFdpZHRoIl0gPiAtMSkKICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zWyJtYXhXaWR0aCJdOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gIm5vbmUiOyAvL2RlZmF1bHQgY3NzIHZhbHVlCiAgICAgICAgfSwKCiAgICAgICAgX2VsTWF4SGVpZ2h0IDogZnVuY3Rpb24ocmVmRWwsIG9wdGlvbnMpewogICAgICAgICAgICBpZihvcHRpb25zWyJtYXhIZWlnaHQiXSAmJiBvcHRpb25zWyJtYXhIZWlnaHQiXSA+IC0xKQogICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnNbIm1heEhlaWdodCJdOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gIm5vbmUiOyAvL2RlZmF1bHQgY3NzIHZhbHVlCiAgICAgICAgfSwKCiAgICAgICAgX2Rlc3Ryb3kgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgJCgiI3RleHRNZXRyaWNzIikucmVtb3ZlKCk7CiAgICAgICAgICAgIHRoaXMuJG1lYXN1cmVFbCA9IG51bGw7CiAgICAgICAgfQogICAgfQp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oJCwgXykgewoKCSQuYWxlcnRCb3ggPSB7CgoJCXZlcnRpY2FsT2Zmc2V0OiAtNzUsCgkJaG9yaXpvbnRhbE9mZnNldDogMCwKCQlyZXBvc2l0aW9uT25SZXNpemU6IHRydWUsCgkJb3ZlcmxheU9wYWNpdHk6IDAuMDEsCgkJb3ZlcmxheUNvbG9yOiAnI0ZGRicsCgkJZHJhZ2dhYmxlOiBmYWxzZSwKCQlkaWFsb2dDbGFzczogbnVsbCwKCQlpbWFnZURpcmVjdG9yeTogIi4uIiwKCQlpbWFnZXM6IFsiQV9XYXJuaW5nX0xnX04ucG5nIiwgIkFfQWxlcnQyX0xnX04ucG5nIiwgIkNfUXVlc3Rpb25CdWJibGVfWGxfTi5wbmciLCAiQV9JbmZvQmx1ZV8zMngzMl9OLnBuZyJdLAoKCQlhbGVydDogZnVuY3Rpb24oaW1nLCBtZXNzYWdlLCB0aXRsZSwgY2FsbGJhY2spIHsKCQkJdGhpcy5fc2hvdyhpbWcsIHRpdGxlLCBtZXNzYWdlLCBudWxsLCAnT0snLCBmdW5jdGlvbihyZXN1bHQpIHsKCQkJCWlmKCBjYWxsYmFjayApIGNhbGxiYWNrKHJlc3VsdCk7CgkJCX0pOwoJCX0sCgoJCW9rQ2FuY2VsOiBmdW5jdGlvbihpbWcsIG1lc3NhZ2UsIHRpdGxlLCBjYWxsYmFjaykgewoJCQl0aGlzLl9zaG93KGltZywgdGl0bGUsIG1lc3NhZ2UsIG51bGwsICdPSy1DYW5jZWwnLCBmdW5jdGlvbihyZXN1bHQpIHsKCQkJCWlmKCBjYWxsYmFjayApIGNhbGxiYWNrKHJlc3VsdCk7CgkJCX0pOwoJCX0sCgkJeWVzTm86IGZ1bmN0aW9uKGltZywgbWVzc2FnZSwgdGl0bGUsIGNhbGxiYWNrKSB7CgkJCXRoaXMuX3Nob3coaW1nLCB0aXRsZSwgbWVzc2FnZSwgbnVsbCwgJ1llcy1ObycsIGZ1bmN0aW9uKHJlc3VsdCkgewoJCQkJaWYoIGNhbGxiYWNrICkgY2FsbGJhY2socmVzdWx0KTsKCQkJfSk7CgkJfSwKCgkJeWVzTm9DYW5jZWw6IGZ1bmN0aW9uKGltZywgbWVzc2FnZSwgdGl0bGUsIGNhbGxiYWNrKSB7CgkJCXRoaXMuX3Nob3coaW1nLCB0aXRsZSwgbWVzc2FnZSwgbnVsbCwgJ1llcy1Oby1DYW5jZWwnLCBmdW5jdGlvbihyZXN1bHQpIHsKCQkJCWlmKCBjYWxsYmFjayApIGNhbGxiYWNrKHJlc3VsdCk7CgkJCX0pOwoJCX0sCgoJCV9jcmVhdGVCb3g6IGZ1bmN0aW9uKG1zZ0JveF9tZXNzYWdlLGJ1dHRvbnMsY2FsbGJhY2spIHsKCQkJdmFyIHRoYXQgPSB0aGlzOwoJCQkkKCIjIittc2dCb3hfbWVzc2FnZSkuYWZ0ZXIoIjxkaXYgaWQ9J21zZ0JveF9wYW5lbCc+Iik7CgkJCV8uZWFjaChidXR0b25zLnNwbGl0KCItIiksZnVuY3Rpb24odmFsLGkpIHsKICAgICAgICAgICAgICAgIHZhciBkaXNwdmFsID0geGZhbGliLmxvY2FsZS5TdHJpbmdzW3ZhbC50b0xvd2VyQ2FzZSgpXSA/IHhmYWxpYi5sb2NhbGUuU3RyaW5nc1t2YWwudG9Mb3dlckNhc2UoKV0gOiB2YWw7ICAvLyBrZXlzIGluIGxvYWNsaXphdGlvbiBmaWxlcyBhcmUgaW4gbG93ZXItY2FzZQogICAgICAgICAgICAgICAgJCgiI21zZ0JveF9wYW5lbCIpLmFwcGVuZCgiPGlucHV0IHR5cGU9J2J1dHRvbicgdmFsdWU9JyIrZGlzcHZhbCsiJyBpZCA9ICdtc2dCb3hfIit2YWwrIicgY2xhc3M9bXNnYm94X2lucHV0IC8+Iik7CgkJCQkkKCIjbXNnQm94XyIrdmFsKS5jbGljayggZnVuY3Rpb24oKSB7CgkJCQkJdGhhdC5faGlkZSgpOwoJCQkJCWNhbGxiYWNrKCFpKTsKCQkJCX0pOwoJCQkJaWYoIWkpICQoIm1zZ0JveF8iK3ZhbCkuZm9jdXMoKTsKCQkJfSk7CgkJfSwKCgkJX3Nob3c6IGZ1bmN0aW9uKGltZywgdGl0bGUsIG1zZywgdmFsdWUsIHR5cGUsIGNhbGxiYWNrKSB7CgoJCQl0aGlzLl9oaWRlKCk7CgkJCXRoaXMuX292ZXJsYXkoJ3Nob3cnKTsKCgkJCSQoIkJPRFkiKS5hcHBlbmQoCgkJCSAgJzxkaXYgaWQ9Im1zZ0JveF9jb250YWluZXIiPicgKwoJCQkgICAgJzxoMSBpZD0ibXNnQm94X3RpdGxlIj48L2gxPicgKwoJCQkgICAgJzxkaXYgaWQ9Im1zZ0JveF9jb250ZW50Ij4nICsKCQkJICAgICAgJzxkaXYgaWQ9Im1zZ0JveF9tZXNzYWdlIj48L2Rpdj4nICsKCQkJCSc8L2Rpdj4nICsKCQkJICAnPC9kaXY+Jyk7CgoJCQlpZiggdGhpcy5kaWFsb2dDbGFzcyApICQoIiNtc2dCb3hfY29udGFpbmVyIikuYWRkQ2xhc3MoJC5hbGVydEJveC5kaWFsb2dDbGFzcyk7CgoJCQkkKCIjbXNnQm94X2NvbnRhaW5lciIpLmNzcyh7CgkJCQlwb3NpdGlvbjogJ2Fic29sdXRlJywKCQkJCXpJbmRleDogOTk5OTksCgkJCQlwYWRkaW5nOiAwLAoJCQkJbWFyZ2luOiAwCgkJCX0pOwoKCQkJJCgiI21zZ0JveF90aXRsZSIpLnRleHQodGl0bGUpOwoJCQkkKCIjbXNnQm94X2NvbnRlbnQiKS5hZGRDbGFzcygibXNnQm94VHlwZSIraW1nKTsvL2NzcygiYmFja2dyb3VuZC1pbWFnZSIsInVybCgiK3RoaXMuaW1hZ2VEaXJlY3RvcnkrIHRoaXMuaW1hZ2VzW2ltZ10rIikiKTsKCQkJbXNnID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmVuY29kZVNjcmlwdGFibGVUYWdzKG1zZy5yZXBsYWNlKC9cbi9nLCAnPGJyIC8+JykpOwogICAgICAgICAgICAkKCIjbXNnQm94X21lc3NhZ2UiKS5odG1sKG1zZyk7CgoJCQkkKCIjbXNnQm94X2NvbnRhaW5lciIpLmNzcyh7CgkJCQltaW5XaWR0aDogJCgiI21zZ0JveF9jb250YWluZXIiKS5vdXRlcldpZHRoKCksCgkJCQltYXhXaWR0aDogJCgiI21zZ0JveF9jb250YWluZXIiKS5vdXRlcldpZHRoKCkKCQkJfSk7CgoJCQl0aGlzLl9yZXBvc2l0aW9uKCk7CgkJCXRoaXMuX21haW50YWluUG9zaXRpb24odHJ1ZSk7CgoJCQl0aGlzLl9jcmVhdGVCb3goIm1zZ0JveF9tZXNzYWdlIix0eXBlLGNhbGxiYWNrKTsKCgkJCS8vVE9ETzogTWFrZSBrZXlib2FyZCBpbnB1dCB3b3JrCgkJCS8qJCgiI21zZ0JveF9vayIpLmtleXByZXNzKCBmdW5jdGlvbihlKSB7CgkJCQlpZiggZS5rZXlDb2RlID09IDEzIHx8IGUua2V5Q29kZSA9PSAyNyApICQoIiNtc2dCb3hfb2siKS50cmlnZ2VyKCdjbGljaycpOwoJCQl9KTsKCQkJJCgiI21zZ0JveF9jYW5jZWwiKS5rZXlwcmVzcyggZnVuY3Rpb24oZSkgewoJCQkJaWYoIGUua2V5Q29kZSA9PSAxMyApICQoIiNtc2dCb3hfb2siKS50cmlnZ2VyKCdjbGljaycpOwoJCQkJaWYoIGUua2V5Q29kZSA9PSAyNyApICQoIiNtc2dCb3hfY2FuY2VsIikudHJpZ2dlcignY2xpY2snKTsKCQkJfSk7CgkJCSQoIiNtc2dCb3hfeWVzLCAjbXNnQm94X25vIikua2V5cHJlc3MoIGZ1bmN0aW9uKGUpIHsKCQkJCWlmKCBlLmtleUNvZGUgPT0gMTMgKSAkKCIjbXNnQm94X3llcyIpLnRyaWdnZXIoJ2NsaWNrJyk7CgkJCQkJaWYoIGUua2V5Q29kZSA9PSAyNyApICQoIiNtc2dCb3hfbm8iKS50cmlnZ2VyKCdjbGljaycpOwoJCQkJfSk7Ki8KCgkJfSwKCgkJX2hpZGU6IGZ1bmN0aW9uKCkgewoJCQkkKCIjbXNnQm94X2NvbnRhaW5lciIpLnJlbW92ZSgpOwoJCQl0aGlzLl9vdmVybGF5KCdoaWRlJyk7CgkJCXRoaXMuX21haW50YWluUG9zaXRpb24oZmFsc2UpOwoJCX0sCgoJCV9vdmVybGF5OiBmdW5jdGlvbihzdGF0dXMpIHsKCQkJc3dpdGNoKCBzdGF0dXMgKSB7CgkJCQljYXNlICdzaG93JzoKCQkJCQl0aGlzLl9vdmVybGF5KCdoaWRlJyk7CgkJCQkJJCgiQk9EWSIpLmFwcGVuZCgnPGRpdiBpZD0ibXNnQm94X292ZXJsYXkiPjwvZGl2PicpOwoJCQkJCSQoIiNtc2dCb3hfb3ZlcmxheSIpLmNzcyh7CgkJCQkJCXBvc2l0aW9uOiAnYWJzb2x1dGUnLAoJCQkJCQl6SW5kZXg6IDk5OTk4LAoJCQkJCQl0b3A6ICcwcHgnLAoJCQkJCQlsZWZ0OiAnMHB4JywKCQkJCQkJd2lkdGg6ICcxMDAlJywKCQkJCQkJaGVpZ2h0OiAkKGRvY3VtZW50KS5oZWlnaHQoKSwKCQkJCQkJYmFja2dyb3VuZDogdGhpcy5vdmVybGF5Q29sb3IsCgkJCQkJCW9wYWNpdHk6IHRoaXMub3ZlcmxheU9wYWNpdHkKCQkJCQl9KTsKCQkJCWJyZWFrOwoJCQkJY2FzZSAnaGlkZSc6CgkJCQkJJCgiI21zZ0JveF9vdmVybGF5IikucmVtb3ZlKCk7CgkJCQlicmVhazsKCQkJfQoJCX0sCgoJCV9yZXBvc2l0aW9uOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHdpbmRvd0hlaWdodCA9ICQod2luZG93KS5oZWlnaHQoKSAvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IsCiAgICAgICAgICAgICAgICB3aW5kb3dXaWR0aCA9ICQod2luZG93KS53aWR0aCgpIC8geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmZvcm1TY2FsZUZhY3RvciwKICAgICAgICAgICAgICAgIHdpbmRvd1Njcm9sbFRvcCA9ICAkKHdpbmRvdykuc2Nyb2xsVG9wKCkgLyB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZm9ybVNjYWxlRmFjdG9yLAogICAgICAgICAgICAgICAgd2luZG93U2Nyb2xsTGVmdCA9ICAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpIC8geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmZvcm1TY2FsZUZhY3RvciwKCQkJICAgIHRvcCA9ICgod2luZG93SGVpZ2h0IC8gMikgLSAoJCgiI21zZ0JveF9jb250YWluZXIiKS5vdXRlckhlaWdodCgpIC8gMikpICsgdGhpcy52ZXJ0aWNhbE9mZnNldCwKCQkJICAgIGxlZnQgPSAoKHdpbmRvd1dpZHRoIC8gMikgLSAoJCgiI21zZ0JveF9jb250YWluZXIiKS5vdXRlcldpZHRoKCkgLyAyKSkgKyB0aGlzLmhvcml6b250YWxPZmZzZXQ7CgkJCWlmKCB0b3AgPCAwICkgdG9wID0gMDsKCQkJaWYoIGxlZnQgPCAwICkgbGVmdCA9IDA7CgoJCQkvLyBJRTYgZml4CgkJCWlmKCAkLmJyb3dzZXIubXNpZSAmJiBwYXJzZUludCgkLmJyb3dzZXIudmVyc2lvbikgPD0gNiApIHRvcCA9IHRvcCArIHdpbmRvd1Njcm9sbFRvcDsKCgkJCSQoIiNtc2dCb3hfY29udGFpbmVyIikuY3NzKHsKCQkJCXRvcDogdG9wICsgd2luZG93U2Nyb2xsVG9wICsgJ3B4JywKCQkJCWxlZnQ6ICBsZWZ0ICsgd2luZG93U2Nyb2xsTGVmdCArICdweCcKCQkJfSk7CgkJCSQoIiNtc2dCb3hfb3ZlcmxheSIpLmhlaWdodCggJChkb2N1bWVudCkuaGVpZ2h0KCkgKTsKCQl9LAoKCQlfbWFpbnRhaW5Qb3NpdGlvbjogZnVuY3Rpb24oc3RhdHVzKSB7CgkJCWlmKCB0aGlzLnJlcG9zaXRpb25PblJlc2l6ZSApIHsKCQkJCXN3aXRjaChzdGF0dXMpIHsKCQkJCQljYXNlIHRydWU6CgkJCQkJCSQod2luZG93KS5vbigncmVzaXplJywgdGhpcy5fcmVwb3NpdGlvbik7CgkJCQkJYnJlYWs7CgkJCQkJY2FzZSBmYWxzZToKCQkJCQkJJCh3aW5kb3cpLm9mZigncmVzaXplJywgdGhpcy5fcmVwb3NpdGlvbik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9CgoJfTsKfSkoJCwgd2luZG93Ll8pOy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX19fCiAqCiAqICBDb3B5cmlnaHQgMjAxNiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LnV0aWwuSHRtbFV0aWwgPSB7CiAgICAgICAgLyoKICAgICAgICAqIE1vc3Qgb2YgdGhlIHRpbWUgaXQgcmV0dXJucyB1bmRlZmluZWQgd2hpbGUgYWNjZXNzaW5nIGFuIHVuZGVmaW5lZCBhdHRyaWJ1dGUgb2YgYSBkb20gZWxlbWVudC4KICAgICAgICAqIEJ1dCBzb21lIGJyb3dzZXJzIGNhbiB0aHJvdyBzcGVjaWZpYyBleGNlcHRpb25zIHdoaWxlIGFjY2Vzc2luZyBhbiBhdHRyaWJ1dGUgd2hpY2ggaXMgdW4tc3VwcG9ydGVkIGZvciBhIHNwZWNpZmljIGNhc2UuCiAgICAgICAgKiBUaGlzIEFQSSBpcyB0byBtYWtlIHRoaXMgYmVoYXZpb3VyIGNvbnNpc3RlbnQgYWNyb3NzIGJyb3dzZXJzIGFuZCByZXR1cm4gdW5kZWZpbmVkIGZvciB1bi1zdXBwb3J0ZWQgYXR0cmlidXRlcy4KICAgICAgICAqICovCiAgICAgICAgZ2V0SFRNTFN1cHBvcnRlZEF0dHIgOiBmdW5jdGlvbigkZG9tRWxlbWVudCwgYXR0cil7CiAgICAgICAgICAgdHJ5ewogICAgICAgICAgICAgICByZXR1cm4gJGRvbUVsZW1lbnRbYXR0cl07CiAgICAgICAgICAgIH0KICAgICAgICAgICBjYXRjaCAoZXJyKXsKICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrcyBpZiB0aGUgYXR0cmlidXRlIGlzIHN1cHBvcnRlZCBmb3IgdGhlIGdpdmVuIEhUTUwgZWxlbWVudC4KICAgICAgICAgKiBUaGlzIGlzIHByaW1hcmlseSB1c2VmdWwgdG8gc3VwcG9ydCBIVE1MNSBmZWF0dXJlcyBpbiB3aWRnZXRzCiAgICAgICAgICogQHBhcmFtIGVsZW1lbnQgICAgICAgbmFtZSBvZiBIVE1MIGVsZW1lbnQKICAgICAgICAgKiBAcGFyYW0gYXR0cmlidXRlICAgICBhdHRyaWJ1dGUgdG8gY2hlY2sgb24gdGhlIGVsZW1lbnQKICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0KICAgICAgICAgKi8KICAgICAgICBlbGVtZW50U3VwcG9ydHNBdHRyaWJ1dGUgOiBmdW5jdGlvbiAoZWxlbWVudCwgYXR0cmlidXRlKSB7CiAgICAgICAgICAgIHZhciB0ZXN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChlbGVtZW50KTsKICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZSBpbiB0ZXN0KSB7CiAgICAgICAgICAgICAgICAkKHRlc3QpLnJlbW92ZSgpOwogICAgICAgICAgICAgICAgdGVzdCA9IG51bGw7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICQodGVzdCkucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICB0ZXN0ID0gbnVsbDsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfSkoXywgJCwgeGZhbGliKTsKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKgoqIEFET0JFIENPTkZJREVOVElBTAoqIF9fX19fX19fX19fX19fX19fX18KKgoqICBDb3B5cmlnaHQgMjAxMyBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAoqICBBbGwgUmlnaHRzIFJlc2VydmVkLgoqCiogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAoqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKKiBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuCiogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiogaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy51dGlsLlN0eWxlcyA9IHsKICAgICAgICB4ZmFVdGlsIDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLAogICAgICAgIF9kZXZpY2VSZXNvbHV0aW9uIDogIDE0NC4wLCAvL0RQSQogICAgICAgIF9pbjJtbUZhY3RvciA6IDI1LjQsCiAgICAgICAgX3BkZlJlc29sdXRpb24gOiA3Mi4wICwKICAgICAgICBnZXRTdHlsZUZvckVkZ2UgOiBmdW5jdGlvbiAoZWRnZUVsZW1lbnQsIHN0ciwgY3NzU3R5bGVPYmopewogICAgICAgICAgICB2YXIgc3R5bGUgPSB7ICJyYWlzZWQiIDogIm91dHNldCIgLAogICAgICAgICAgICAgICAgImRhc2hEb3QiIDogImRhc2hlZCIgLAogICAgICAgICAgICAgICAgImRhc2hEb3REb3QiIDogImRhc2hlZCIgLAogICAgICAgICAgICAgICAgImRhc2hlZCIgOiAiZGFzaGVkIiAsCiAgICAgICAgICAgICAgICAiZG90dGVkIiA6ICJkb3R0ZWQiICwKICAgICAgICAgICAgICAgICJlbWJvc3NlZCIgOiAiZ3Jvb3ZlIiAsCiAgICAgICAgICAgICAgICAiZXRjaGVkIiA6ICJpbnNldCIgLAogICAgICAgICAgICAgICAgImxvd2VyZWQiIDogInJpZGdlIiwKICAgICAgICAgICAgICAgICJzb2xpZCIgOiAic29saWQifTsKICAgICAgICAgICAgaWYoZWRnZUVsZW1lbnQgJiYgZWRnZUVsZW1lbnQuanNvbk1vZGVsLnByZXNlbmNlICE9ICJoaWRkZW4iICYmIGVkZ2VFbGVtZW50Lmpzb25Nb2RlbC5wcmVzZW5jZSAhPSJpbnZpc2libGUiKSB7CiAgICAgICAgICAgICAgICBjc3NTdHlsZU9ialsnYm9yZGVyJytzdHIrJ3dpZHRoJ10gPSB0aGlzLl9zdWJQaXhlbFZhbHVlKHRoaXMuX2NvbnZlcnRUb1B4KGVkZ2VFbGVtZW50LmdldEF0dHJpYnV0ZSgndGhpY2tuZXNzJykpKSB8fCAiMXB4IjsKICAgICAgICAgICAgICAgIGlmKGVkZ2VFbGVtZW50LmdldEVsZW1lbnQoImNvbG9yIikgJiYgZWRnZUVsZW1lbnQuZ2V0RWxlbWVudCgiY29sb3IiKS5nZXRBdHRyaWJ1dGUoInZhbHVlIikgIT0iIikgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY29sb3IgPSAgIGVkZ2VFbGVtZW50LmdldEVsZW1lbnQoImNvbG9yIikuZ2V0QXR0cmlidXRlKCJ2YWx1ZSIpOwogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gInJnYigiICsgY29sb3IgKyAiKSI7CiAgICAgICAgICAgICAgICAgICAgY3NzU3R5bGVPYmpbJ2JvcmRlcicrc3RyKydjb2xvciddICAgPSBjb2xvciAgOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY3NzU3R5bGVPYmpbJ2JvcmRlcicrc3RyKydjb2xvciddID0gInJnYigwLDAsMCkiICA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjc3NTdHlsZU9ialsnYm9yZGVyJytzdHIrJ3N0eWxlJ10gICA9IHN0eWxlW2VkZ2VFbGVtZW50LmdldEF0dHJpYnV0ZSgnc3Ryb2tlJyldIHx8ICJzb2xpZCIgOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY3NzU3R5bGVPYmpbJ2JvcmRlcicrc3RyKyd3aWR0aCddID0gICIwcHgiOwogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0KCiAgICAgICAgfSwKCiAgICAgICAgZ2V0U3R5bGVGb3JCb3JkZXIgOiBmdW5jdGlvbiAoYm9yZGVyKSB7CiAgICAgICAgICAgIGlmKGJvcmRlcikgewogICAgICAgICAgICAgICAgdmFyIGVkZ2UgID0gIGJvcmRlci5nZXRFbGVtZW50KCdlZGdlJywgMCwgdHJ1ZSksCiAgICAgICAgICAgICAgICAgICAgZWRnZTEgPSBib3JkZXIuZ2V0RWxlbWVudCgnZWRnZScsIDEsIHRydWUpLAogICAgICAgICAgICAgICAgICAgIGVkZ2UyID0gYm9yZGVyLmdldEVsZW1lbnQoJ2VkZ2UnLCAyLCB0cnVlKSwKICAgICAgICAgICAgICAgICAgICBlZGdlMyA9IGJvcmRlci5nZXRFbGVtZW50KCdlZGdlJywgMywgdHJ1ZSk7CiAgICAgICAgICAgICAgICBpZihlZGdlIHx8IGVkZ2UxIHx8IGVkZ2UyIHx8IGVkZ2UzKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNzc1N0eWxlT2JqID0ge30gOwogICAgICAgICAgICAgICAgICAgIHZhciBlMCA9IHRoaXMuZ2V0U3R5bGVGb3JFZGdlKGVkZ2UsICItdG9wLSIsY3NzU3R5bGVPYmopOwogICAgICAgICAgICAgICAgICAgIHZhciBlMSA9IHRoaXMuZ2V0U3R5bGVGb3JFZGdlKGVkZ2UxIHx8IGVkZ2UsIi1yaWdodC0iLGNzc1N0eWxlT2JqKTsKICAgICAgICAgICAgICAgICAgICB2YXIgZTIgPSB0aGlzLmdldFN0eWxlRm9yRWRnZShlZGdlMnx8IGVkZ2UsIi1ib3R0b20tIixjc3NTdHlsZU9iaik7CiAgICAgICAgICAgICAgICAgICAgdmFyIGUzID0gdGhpcy5nZXRTdHlsZUZvckVkZ2UoZWRnZTMgfHwgZWRnZSwiLWxlZnQtIixjc3NTdHlsZU9iaik7CiAgICAgICAgICAgICAgICAgICAgaWYoZTAgIT0xfHwgZTEgIT0xfHwgZTIgIT0xfHwgZTMhPTEpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjc3NTdHlsZU9iaiA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIF9jb252ZXJ0VG9QeCA6IGZ1bmN0aW9uKHNpemUpewogICAgICAgICAgICBpZighc2l6ZSkKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICBzaXplID0gIiIgKyBzaXplOwogICAgICAgICAgICB2YXIgcHhTaXplID0gc2l6ZTsKICAgICAgICAgICAgaWYoc2l6ZS5pbmRleE9mKCJpbiIpID49MCl7CiAgICAgICAgICAgICAgICBweFNpemUgPSB0aGlzLl9tbTJweChwYXJzZUZsb2F0KHNpemUpICogdGhpcy5faW4ybW1GYWN0b3IpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYoc2l6ZS5pbmRleE9mKCJtbSIpID49MCl7CiAgICAgICAgICAgICAgICBweFNpemUgPSB0aGlzLl9tbTJweChzaXplKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKHNpemUuaW5kZXhPZigiY20iKSA+PTApewogICAgICAgICAgICAgICAgcHhTaXplID0gdGhpcy5fbW0ycHgocGFyc2VGbG9hdChzaXplKSAqIDEwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKHNpemUuaW5kZXhPZigicHQiKSA+PTApewogICAgICAgICAgICAgICAgcHhTaXplID0gcGFyc2VGbG9hdChzaXplKSAqICh0aGlzLl9kZXZpY2VSZXNvbHV0aW9uL3RoaXMuX3BkZlJlc29sdXRpb24pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYoc2l6ZS5pbmRleE9mKCJweCIpID49MCl7CiAgICAgICAgICAgICAgICBweFNpemUgPSBwYXJzZUZsb2F0KHNpemUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBweFNpemU7CiAgICAgICAgfSwKCiAgICAgICAgX21tMnB4IDogZnVuY3Rpb24obW1TaXplKXsKICAgICAgICAgICAgdmFyIG1tU2l6ZU51bSA9IDA7CiAgICAgICAgICAgIGlmKF8uaXNOdW1iZXIobW1TaXplKSkKICAgICAgICAgICAgICAgIG1tU2l6ZU51bSA9IG1tU2l6ZTsKICAgICAgICAgICAgZWxzZXsKICAgICAgICAgICAgICAgIG1tU2l6ZU51bSA9IHBhcnNlRmxvYXQobW1TaXplKQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBtbTJpbiA9IDEvMjUuNCA7CiAgICAgICAgICAgIHZhciBweFNpemUgPSBtbVNpemVOdW0qbW0yaW4qdGhpcy5fZGV2aWNlUmVzb2x1dGlvbjsKICAgICAgICAgICAgcmV0dXJuIHB4U2l6ZTsKICAgICAgICB9LAoKICAgICAgICBfc3ViUGl4ZWxWYWx1ZSA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgaWYodmFsdWUgPiAwLjAxKQogICAgICAgICAgICAgICAgcmV0dXJuIE1hdGgubWF4KHZhbHVlLCAxLjApOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgfQogICAgfQp9KShfLCAkLCB4ZmFsaWIpOwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogX19fX19fX19fX19fX19fX19fXwogKgogKiAgQ29weXJpZ2h0IDIwMTcgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LnV0aWwudHJhdmVyc2FsTWFuYWdlciA9IHsKCiAgICAgICAgLy8gY29tcHV0ZSB0YWJJbmRleCBmb3IgdGhlIHByb3ZpZGVkIHBhZ2UKICAgICAgICBfY29tcHV0VGFiSW5kZXggOiBmdW5jdGlvbiAocGFnZVZpZXcpIHsKICAgICAgICAgICAgdmFyIHBhZ2VOdW0gPSBwYWdlVmlldy5fcGFnZU51bWJlcigpLAogICAgICAgICAgICAgICAgdGFiSW5kZXggPSB0aGlzLl90YWJJbmRleEJhc2VkT25SYW5nZShwYWdlTnVtKTsKICAgICAgICAgICAgdGhpcy5nZW9ncmFwaGljYWxPcmRlciA9IFtdOwogICAgICAgICAgICB0aGlzLl9jcmVhdGVHZW9ncmFwaGljYWxPcmRlcihwYWdlVmlldyk7CiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUZpbmFsVHJhdmVyc2FsT3JkZXIodGFiSW5kZXgpOyAvLyBhc3NpZ24gdGFiIGluZGV4IHVzaW5nIHRyYXZlcnNhbCBlbGVtZW50IGFuZCBnZW9ncmFwaGljYWxPcmRlcgogICAgICAgICAgICAvLyBrZWVwIHRyYWNrcyBvZiB0aGUgbGFzdCBmaWVsZCBvbiB0aGUgcGFnZSB0byBnZXQgdGFiIGluZGV4IHNvIHRoYXQgaGFuZGxlciB0byByZW5kZXIgbmV4dCBwYWdlIGNhbiBiZSBhZGRlZCBvbiBnZXR0aW5nIGZvY3VzIHRocm91Z2ggdGFiYmluZwogICAgICAgICAgICB0aGlzLl9sYXN0RmllbGRUYWJiZWQgPSBudWxsOwogICAgICAgIH0sCgogICAgICAgIF90YWJJbmRleEJhc2VkT25SYW5nZSA6IGZ1bmN0aW9uIChwYWdlTnVtKSB7CiAgICAgICAgICAgIHZhciBiZWhhdmlvckNvbmZpZyA9IG5ldyB4ZmFsaWIudXQuVmVyc2lvbihmb3JtQnJpZGdlLnVzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl0pLAogICAgICAgICAgICAgICAgdGFiSW5kZXhDb25maWcgPSAoYmVoYXZpb3JDb25maWcuaXNPbignbWZSYW5nZVRhYkluZGV4Jyl8fCBiZWhhdmlvckNvbmZpZy5pc09uKCdyYW5nZVRhYkluZGV4JykpLAogICAgICAgICAgICAgICAgLyphc3N1bWluZyBzaW5nbGUgcGFnZSBjYW4gbm90IGhhdmUgbW9yZSB0aGFuIDEwMDAgZmllbGRzLltpbmRleCAtPiAwIHRvIDk5OV0KICAgICAgICAgICAgICAgICAgdGhpcyBpcyBhbHNvIGNvbmZpZ3VyYWJsZSBieSBwYXNzaW5nIHRoZSBtYXhpbXVtIG51bWJlciBvZiBmaWVsZHMgYWxsb3dhYmxlIGluIHRoZSBwYWdlCiAgICAgICAgICAgICAgICAgIGluIHRoZSBjb25maWcgcGFyYW1ldGVyICovCiAgICAgICAgICAgICAgICBtYXhGaWVsZEluUGFnZUZvclRhYkluZGV4ID0gdGFiSW5kZXhDb25maWc/IHBhcnNlSW50KHRhYkluZGV4Q29uZmlnKToxMDAwOwoKICAgICAgICAgICAgcmV0dXJuIHBhZ2VOdW0gKiBtYXhGaWVsZEluUGFnZUZvclRhYkluZGV4OwogICAgICAgIH0sCgogICAgICAgIC8vIHRvIGNyZWF0ZSBnZW9ncmFwaGljYWwgb3JkZXIgYXJyYXkgd2hpY2ggd2lsbCBiZSBjb250YWluaW5nIGFsbCB0aGUgdmlld3MgaW4gdGhlIGdlb2dyYXBoaWNhbCBvcmRlcgogICAgICAgIF9jcmVhdGVHZW9ncmFwaGljYWxPcmRlciA6IGZ1bmN0aW9uIChjdXJyZW50VmlldykgewogICAgICAgICAgICB2YXIgc29ydGVkQ2hpbGRWaWV3V3JhcHBlciA9IHRoaXMuX3NvcnRWaWV3R2VvZ3JhcGhpY2FsbHkoY3VycmVudFZpZXcuY2hpbGRWaWV3cyk7CiAgICAgICAgICAgIF8uZWFjaChzb3J0ZWRDaGlsZFZpZXdXcmFwcGVyLCBmdW5jdGlvbiAod3JhcHBlcikgewogICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRWaWV3ID0gd3JhcHBlci52aWV3LAogICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQ2hlY2tNYXAgPSB0aGlzLl9nZXRNYXBPZkluc3RhbmNlQ2hlY2soY3VycmVudFZpZXcpLAogICAgICAgICAgICAgICAgICAgIGlzVmlld0VsaWdpYmxlRm9yVGFiYmluZyA9IHRoaXMuX2lzVmlld0VsaWdpYmxlRm9yVGFiYmluZyhjdXJyZW50Vmlldyk7CiAgICAgICAgICAgICAgICAvLyAgSWYgdGhlIGNoaWxkIHZpZXcgaXMgZmllbGRWaWV3LCBkcmF3VmlldywgZXhjbEdyb3VwVmlldyBvciBzdWJmb3JtVmlldyB0aGVuIHdlIHdpbGwgcHVzaCB0aGVzZSB2aWV3cyBpbiB0aGlzLmdlb2dyYXBoaWNhbE9yZGVyIGFycmF5LAogICAgICAgICAgICAgICAgLy8gIGFzIHdlIG5lZWQgdGhlaXIgdHJhdmVyc2Ugb2JqZWN0IGR1cmluZyBmaW5hbCB0cmF2ZXJzaW5nCiAgICAgICAgICAgICAgICBpZiAoKChpbnN0YW5jZUNoZWNrTWFwLmlzRmllbGQgJiYgIWluc3RhbmNlQ2hlY2tNYXAuaXNDaGlsZE9mRXhjbEdyb3VwKSB8fCBpbnN0YW5jZUNoZWNrTWFwLmlzU3ViZm9ybSB8fCBpbnN0YW5jZUNoZWNrTWFwLmlzRHJhdwogICAgICAgICAgICAgICAgICAgIHx8IGluc3RhbmNlQ2hlY2tNYXAuaXNFeGNsR3JvdXApICYmIGlzVmlld0VsaWdpYmxlRm9yVGFiYmluZykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZ2VvZ3JhcGhpY2FsT3JkZXIucHVzaCh7CiAgICAgICAgICAgICAgICAgICAgICAgIHZpZXcgOiBjdXJyZW50VmlldywKICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXRlZCA6IGZhbHNlCiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2VDaGVja01hcC5pc0NvbnRhaW5lciAmJiBpc1ZpZXdFbGlnaWJsZUZvclRhYmJpbmcpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVHZW9ncmFwaGljYWxPcmRlcihjdXJyZW50Vmlldyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIC8vIHRvIHNvcnQgcHJvdmlkZWQgdmlld3MgaW4gZ2VvZ3JhcGhpY2FsIG9yZGVyCiAgICAgICAgX3NvcnRWaWV3R2VvZ3JhcGhpY2FsbHkgOiBmdW5jdGlvbiAodmlld3MpIHsKICAgICAgICAgICAgdmFyIHZpZXdzV3JhcHBlciA9IFtdOyAgIC8vIHdyYXBwZXIgb2YgdmlldyBhbmQgdGhlaXIgZ2VvZ3JhcGhpY2FsIHJlZmVyZW5jZQogICAgICAgICAgICBfLmVhY2godmlld3MsIGZ1bmN0aW9uKHZpZXcpIHsKICAgICAgICAgICAgICAgIHZhciBwb3NpdGlvbiA9IHZpZXcuJGVsLm9mZnNldCgpLAogICAgICAgICAgICAgICAgICAgIHBhZGRlZFggPSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUucGFkU3RyaW5nKHBhcnNlSW50KHBvc2l0aW9uLmxlZnQpLCA1LCAnMCcpLAogICAgICAgICAgICAgICAgICAgIG1hcmdpblRvcCA9IHZpZXcuX21hcmdpblRvcCgpLAogICAgICAgICAgICAgICAgICAgIHBhZGRlZFkgPSBwb3NpdGlvbi50b3AgLSBwYXJzZUZsb2F0KG1hcmdpblRvcCksCiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25hbFJlZmVyZW5jZSA9IHBhcnNlSW50KCIiICsgcGFyc2VJbnQocGFkZGVkWSkgKyBwYWRkZWRYKTsKICAgICAgICAgICAgICAgIHZpZXdzV3JhcHBlci5wdXNoKHsKICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbmFsUmVmZXJlbmNlOiBwb3NpdGlvbmFsUmVmZXJlbmNlLAogICAgICAgICAgICAgICAgICAgIHZpZXc6IHZpZXcKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgcmV0dXJuIF8uc29ydEJ5KHZpZXdzV3JhcHBlciwgZnVuY3Rpb24odmlld1dyYXBwZXIpeyByZXR1cm4gdmlld1dyYXBwZXIucG9zaXRpb25hbFJlZmVyZW5jZTsgfSk7CiAgICAgICAgfSwKCiAgICAgICAgLy8gV2FsayB0aHJvdWdoIHZpZXdzIGluIGdlb2dyYXBoaWNhbCBvcmRlciBhbmQgYXNzaWduIHRhYiBpbmRleCBob25vdXJpbmcgdHJhdmVyc2FsIG9iamVjdCBpZiBwcmVzZW50CiAgICAgICAgX2NyZWF0ZUZpbmFsVHJhdmVyc2FsT3JkZXIgOiBmdW5jdGlvbiAodGFiSW5kZXgpIHsKICAgICAgICAgICAgdmFyIGdlb2dyYXBoaWNhbE9yZGVyTGVuZ3RoID0gdGhpcy5nZW9ncmFwaGljYWxPcmRlci5sZW5ndGgsCiAgICAgICAgICAgICAgICBjdXJyZW50V3JhcHBlZE9iaiA9IG51bGwsCiAgICAgICAgICAgICAgICBpbmRleCA9IC0xLAogICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXggPSAwLCAgLy8gaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gYmUgdHJhdmVyc2VkCiAgICAgICAgICAgICAgICB2aWV3VHJhdmVyc2VkID0gMDsgIC8vIGNvdW50ZXIgb2YgdmlldyB0cmF2ZXJzZWQKCiAgICAgICAgICAgIHdoaWxlICgxKSB7CiAgICAgICAgICAgICAgICBpZiAodHJhdmVyc2FsSW5kZXggPj0gZ2VvZ3JhcGhpY2FsT3JkZXJMZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0cmF2ZXJzYWxJbmRleCA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdXJyZW50V3JhcHBlZE9iaiA9IHRoaXMuZ2VvZ3JhcGhpY2FsT3JkZXJbdHJhdmVyc2FsSW5kZXhdOwoKICAgICAgICAgICAgICAgIGlmICghY3VycmVudFdyYXBwZWRPYmogfHwgY3VycmVudFdyYXBwZWRPYmoudmlzaXRlZCkgeyAgLy8gaWYgdGhlIHdyYXBwZWQgb2JqZWN0IGRvZXMgbm90IGV4aXN0IG9yIGl0IGhhcyBiZWVuIHZpc2l0ZWQgbW92ZSB0byB0aGUgbmV4dCBvbmUKICAgICAgICAgICAgICAgICAgICB0cmF2ZXJzYWxJbmRleCsrOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50V3JhcHBlZE9iai52aXNpdGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB2aWV3VHJhdmVyc2VkKys7CiAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRWaWV3ID0gY3VycmVudFdyYXBwZWRPYmoudmlldywKICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VDaGVja01hcCA9IHRoaXMuX2dldE1hcE9mSW5zdGFuY2VDaGVjayhjdXJyZW50VmlldyksCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNb2RlbCA9IGN1cnJlbnRWaWV3Lm1vZGVsLAogICAgICAgICAgICAgICAgICAgICAgICBuZXh0VmlldyA9IG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRWaWV3U29tID0gbnVsbDsKCiAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBmaXJzdCB0cmF2ZXJzYWwgb2YgdGhlIHN1YmZvcm0gaWYgdHJhdmVyc2FsIG9iamVjdCBpcyBwcmVzZW50LCBlbHNlIG1vdmUgdG8gdGhlIG5leHQgZ2VvZ3JhcGhpY2FsIGVsZW1lbnQKICAgICAgICAgICAgICAgICAgICAvLyBuZXh0IG9mIHRoZSBzdWJmb3JtIHdpbGwgYmUgdGFrZW4gY2FyZSB3aGVuIHdlIHdpbGwgYmUgZmluZGluZyB0aGUgbmV4dCB2aWV3IHRvIGJlIHRyYXZlcnNlZCwKICAgICAgICAgICAgICAgICAgICAvLyBhcyB3ZSB3aWxsIGJlIGNoZWNraW5nIGlmIHRoZSBhbmNlc3RvciBjb250YWluIG5leHQgYmVmb3JlIG1vdmluZyB0byBnZW9ncmFwaGljYWxseSBuZXh0IHZpZXcKICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2VDaGVja01hcC5pc1N1YmZvcm0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRNb2RlbCAmJiBjdXJyZW50TW9kZWwuZ2V0VHJhdmVyc2FsT2JqZWN0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgZmlyc3QgZWxlbWVudCB0byBiZSB0cmF2ZXJzZWQgYW5kIHVwZGF0ZSB0cmF2ZXJzYWxJbmRleAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dFZpZXdTb20gPSBjdXJyZW50TW9kZWwuZ2V0TmV4dFRyYXZlcnNhbFNvbSh4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmZpcnN0VHJhdmVyc2FsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5fZmluZFZpZXdJbkdlb2dyYXBoaWNhbE9yZGVyQXJyYXkobmV4dFZpZXdTb20pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXggPSBpbmRleCAhPSAtMSA/IGluZGV4IDogdHJhdmVyc2FsSW5kZXggKyAxOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXgrKzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgbmV4dCB0cmF2ZXJzYWwgZm9yIHRoZSBmaWVsZC9kcmF3IGlmIHRyYXZlcnNhbCBvYmplY3QgaXMgcHJlc2VudCwgZWxzZSBtb3ZlIHRvIHRoZSBuZXh0IGdlb2dyYXBoaWNhbCBlbGVtZW50CiAgICAgICAgICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSB0YWJpbmRleCBmb3IgdGhlIGZpZWxkCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbnN0YW5jZUNoZWNrTWFwLmlzRmllbGQgfHwgaW5zdGFuY2VDaGVja01hcC5pc0RyYXcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlQ2hlY2tNYXAuaXNGaWVsZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudFZpZXcudXBkYXRlVGFiSW5kZXgodGFiSW5kZXgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbGFzdEZpZWxkVGFiYmVkID0gY3VycmVudFZpZXc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJJbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50TW9kZWwgJiYgY3VycmVudE1vZGVsLmdldFRyYXZlcnNhbE9iamVjdCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2dldCBuZXh0IGVsZW1lbnQgdG8gYmUgdHJhdmVyc2VkIGFuZCB1cGRhdGUgdHJhdmVyc2FsSW5kZXgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRWaWV3U29tID0gY3VycmVudE1vZGVsLmdldE5leHRUcmF2ZXJzYWxTb20oeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5uZXh0VHJhdmVyc2FsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5fZmluZFZpZXdJbkdlb2dyYXBoaWNhbE9yZGVyQXJyYXkobmV4dFZpZXdTb20pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXggPSBpbmRleCAhPSAtMSA/IGluZGV4IDogdHJhdmVyc2FsSW5kZXggKyAxOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXggPSB0aGlzLl9maW5kTmV4dFZpZXdUb0JlVHJhdmVyc2VkKHRyYXZlcnNhbEluZGV4KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIGlmIHRyYXZlcnNhbCBvYmplY3QgcHJlc2VudCBnZXQgdGhlIG5leHQgZWxlbWVudCB0byBiZSB0cmF2ZXJzZWQsIGlmIGZpcnN0IGlzIGFsc28gcHJlc2VudCB0aGVuIHVwZGF0ZSB0YWIgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQKICAgICAgICAgICAgICAgICAgICAvLyBlbHNlIGxvb2sgZm9yIHRoZSB0cmF2ZXJzYWwgZWxlbWVudCBpbiB0aGUgY2hpbGRyZW4KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluc3RhbmNlQ2hlY2tNYXAuaXNFeGNsR3JvdXApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRNb2RlbCAmJiBjdXJyZW50TW9kZWwuZ2V0VHJhdmVyc2FsT2JqZWN0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldCBuZXh0IGVsZW1lbnQgdG8gYmUgdHJhdmVyc2VkIGFuZCB1cGRhdGUgdHJhdmVyc2FsSW5kZXgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRWaWV3U29tID0gY3VycmVudE1vZGVsLmdldE5leHRUcmF2ZXJzYWxTb20oeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5uZXh0VHJhdmVyc2FsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5fZmluZFZpZXdJbkdlb2dyYXBoaWNhbE9yZGVyQXJyYXkobmV4dFZpZXdTb20pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXggPSBpbmRleCAhPSAtMSA/IGluZGV4IDogdHJhdmVyc2FsSW5kZXggKyAxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgZmlyc3QgaXMgYWxzbyBwcmVzZW50IGFzc2lnbiB0YWIgaW5kZXggdG8gdGhhdCByZWZlcnJlZCBjaGlsZCBlbHNlIGFzc2lnbiBzYW1lIHRhYiBpbmRleCB0byBhbGwgY2hpbGQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRWaWV3U29tID0gY3VycmVudE1vZGVsLmdldE5leHRUcmF2ZXJzYWxTb20oeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5maXJzdFRyYXZlcnNhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJJbmRleCA9IHRoaXMuX3VwZGF0ZVRhYkluZGV4T2ZFeGNsR3JvdXBDaGlsZHJlbihjdXJyZW50VmlldywgdGFiSW5kZXgsIG5leHRWaWV3U29tKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYkluZGV4ID0gdGhpcy5fdXBkYXRlVGFiSW5kZXhPZkV4Y2xHcm91cENoaWxkcmVuKGN1cnJlbnRWaWV3LCB0YWJJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmF2ZXJzYWxJbmRleCA9IHRoaXMuX2ZpbmRUcmF2ZXJzYWxJbkV4Y2xHcm91cENoaWxkcmVuKGN1cnJlbnRWaWV3LCB0cmF2ZXJzYWxJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0cmF2ZXJzYWxJbmRleCsrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBpZiBhbGwgdGhlIHZpZXcgYXJlIHRyYXZlcnNlZCwgd2UgaGF2ZSBhc3NpZ25lZCB0YWIgaW5kZXggdG8gYWxsIHRoZSB2aWV3cwogICAgICAgICAgICAgICAgaWYgKHZpZXdUcmF2ZXJzZWQgPj0gZ2VvZ3JhcGhpY2FsT3JkZXJMZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZW5kZXJOZXh0UGFnZUZ1dHVyZSgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG5leHRWaWV3IGlzIGEgc2libGluZyBvZiB0aGUgY3VycmVudFZpZXcgKHNoYXJlcyB0aGUgc2FtZSBwYXJlbnQpCiAgICAgICAgLy8gaWYgaXQgaXMgbm90IGEgc2libGluZywgY2hlY2sgaWYgdGhlIHBhcmVudCBoYXMgYSBORVhUIHRyYXZlcnNhbC4KICAgICAgICAvLyBpZiBzbyBnZXQgdGhlIG5vZGUgdHJhdmVyc2VkIHRvIGVsc2UgcmVjdXJzZSB0byBzZWUgaWYgbmV4dFZpZXcgaXMgYSBzaWJsaW5nIG9mIG91ciBwYXJlbnQKICAgICAgICAvLyByZXR1cm4gLTEgaWYgdGhlIHByb3ZpZGVkIG5leHQgbm9kZSBpcyBzaWJsaW5nIG9mIGN1cnJlbnQgbm9kZSBvciBpZiBubyBhbmNlc3RvciBjb250YWluIG5leHQgdHJhdmVyc2FsCiAgICAgICAgLy8gZWxzZSByZXR1cm4gaW5kZXggb2YgdGhlIG5leHQgdHJhdmVyc2FsIG9iamVjdCBvZiBwYXJlbnQKICAgICAgICBfZ2V0UGFyZW50TmV4dFRyYXZlcnNhbCA6IGZ1bmN0aW9uIChjdXJyZW50VmlldywgbmV4dFZpZXcsIHRyYXZlcnNhbEluZGV4KSB7CiAgICAgICAgICAgIHZhciBwYXJlbnRWaWV3ID0gY3VycmVudFZpZXcucGFyZW50VmlldywKICAgICAgICAgICAgICAgIHBhcmVudE1vZGVsID0gcGFyZW50Vmlldy5tb2RlbCwKICAgICAgICAgICAgICAgIG5leHRWaWV3UGFyZW50TW9kZWwgPSBuZXh0Vmlldy5wYXJlbnRWaWV3Lm1vZGVsLAogICAgICAgICAgICAgICAgdHJhdmVyc2FsT2JqID0gbnVsbCwKICAgICAgICAgICAgICAgIG5leHRJbmRleCA9IC0xOwoKICAgICAgICAgICAgaWYgKHBhcmVudE1vZGVsICYmIG5leHRWaWV3UGFyZW50TW9kZWwgJiYgcGFyZW50TW9kZWwuc29tRXhwcmVzc2lvbiAhPSBuZXh0Vmlld1BhcmVudE1vZGVsLnNvbUV4cHJlc3Npb24pIHsKICAgICAgICAgICAgICAgIGlmKHBhcmVudFZpZXcgJiYgcGFyZW50VmlldyBpbnN0YW5jZW9mIHhmYWxpYi52aWV3LlN1YmZvcm1WaWV3KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudE1vZGVsLmdldFRyYXZlcnNhbE9iamVjdCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXh0Vmlld1NvbSA9IHBhcmVudE1vZGVsLmdldE5leHRUcmF2ZXJzYWxTb20oeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5uZXh0VHJhdmVyc2FsKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV4dEluZGV4ID0gdGhpcy5fZmluZFZpZXdJbkdlb2dyYXBoaWNhbE9yZGVyQXJyYXkobmV4dFZpZXdTb20pOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dEluZGV4ICE9IC0xICYmICF0aGlzLmdlb2dyYXBoaWNhbE9yZGVyW25leHRJbmRleF0udmlzaXRlZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5leHRJbmRleDsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cmF2ZXJzYWxJbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZ2V0UGFyZW50TmV4dFRyYXZlcnNhbChwYXJlbnRWaWV3LCBuZXh0VmlldywgdHJhdmVyc2FsSW5kZXgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7ICAvLyBwYXJlbnRWaWV3IGlzIG5vdCBhIHN1YmZvcm0gc28gc2tpcCB1cCBhIGxldmVsIGFuZCByZS1jaGVjayBzaWJsaW5nCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZ2V0UGFyZW50TmV4dFRyYXZlcnNhbChwYXJlbnRWaWV3LCBuZXh0VmlldywgdHJhdmVyc2FsSW5kZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOyAgLy9wcm92aWRlZCBjdXJyZW50VmlldyBhbmQgbmV4dFZpZXcgYXJlIHNpYmxpbmcKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHJhdmVyc2FsSW5kZXgrKzsKICAgICAgICB9LAoKICAgICAgICAvLyByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSB2aWV3IGhhdmluZyBwcm92aWRlZCBzb21FeHByZXNzaW9uIGluIHRoZSBnZW9ncmFwaGljYWxPcmRlciBhcnJheQogICAgICAgIF9maW5kVmlld0luR2VvZ3JhcGhpY2FsT3JkZXJBcnJheSA6IGZ1bmN0aW9uIChzb21FeHByZXNzaW9uKSB7CiAgICAgICAgICAgIHJldHVybiBfLmZpbmRJbmRleCh0aGlzLmdlb2dyYXBoaWNhbE9yZGVyLCBmdW5jdGlvbiAodmlld1dyYXBwZXIpIHsKICAgICAgICAgICAgICAgIHZhciBjdXJyZW50Vmlld01vZGVsID0gdmlld1dyYXBwZXIudmlldy5tb2RlbDsKICAgICAgICAgICAgICAgIHJldHVybiAoY3VycmVudFZpZXdNb2RlbCAmJiBjdXJyZW50Vmlld01vZGVsLnNvbUV4cHJlc3Npb24gPT0gc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIC8vIGZpbmQgdGhlIG5leHQgZWxlbWVudCB0byBiZSB0cmF2ZXJzZWQgYmFzZWQgb24gdGhlIHByb3ZpZGVkIHRyYXZlcnNhbEluZGV4CiAgICAgICAgX2ZpbmROZXh0Vmlld1RvQmVUcmF2ZXJzZWQgOiBmdW5jdGlvbiAodHJhdmVyc2FsSW5kZXgpIHsKICAgICAgICAgICAgdmFyIGN1cnJlbnRWaWV3ID0gdGhpcy5nZW9ncmFwaGljYWxPcmRlclt0cmF2ZXJzYWxJbmRleF0udmlldywKICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5fZ2V0TmV4dFVudmlzaXRlZCh0cmF2ZXJzYWxJbmRleCksICAgLy9nZXQgbmV4dCB1bnZpc2l0ZWQgYmFzZWQgb24gZ2VvZ3JhcGhpY2FsIGxvY2F0aW9uCiAgICAgICAgICAgICAgICBuZXh0VmlldyA9IG51bGwsCiAgICAgICAgICAgICAgICBuZXh0SW5kZXggPSAtMTsKCiAgICAgICAgICAgIGlmIChpbmRleCAhPSAtMSkgewogICAgICAgICAgICAgICAgbmV4dFZpZXcgPSB0aGlzLmdlb2dyYXBoaWNhbE9yZGVyW2luZGV4XS52aWV3OwogICAgICAgICAgICAgICAgLy9jaGVjayBpZiBib3RoIGFyZSBzaWJsaW5nIGFuZCBpZiBub3QgZmluZCB0aGUgbmV4dCBvZiB0aGUgcGFyZW50IGFuZCB1cGRhdGUgdHJhdmVyc2FsSW5kZXgKICAgICAgICAgICAgICAgIG5leHRJbmRleCA9IHRoaXMuX2dldFBhcmVudE5leHRUcmF2ZXJzYWwoY3VycmVudFZpZXcsIG5leHRWaWV3LCB0cmF2ZXJzYWxJbmRleCk7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV4dEluZGV4ICE9IC0xID8gbmV4dEluZGV4IDogaW5kZXg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNhbEluZGV4Kys7CiAgICAgICAgfSwKCiAgICAgICAgLy8gcmV0dXJuIHRoZSBuZXh0IHVudmlzaXRlZCBub2RlIGJhc2VkIG9uIGdlb2dyYXBoaWNhbCBsb2NhdGlvbgogICAgICAgIC8vIHN0YXJ0aW5nIGZyb20gdGhlIHRyYXZlcnNhbEluZGV4IGFuZCB3cmFwcyBhcm91bmQgdG8gY2hlY2sgYWxsIHRoZSB2aWV3cwogICAgICAgIF9nZXROZXh0VW52aXNpdGVkIDogZnVuY3Rpb24gKHRyYXZlcnNhbEluZGV4KSB7CiAgICAgICAgICAgIHZhciBnZW9ncmFwaGljYWxPcmRlckxlbmd0aCA9IHRoaXMuZ2VvZ3JhcGhpY2FsT3JkZXIubGVuZ3RoLAogICAgICAgICAgICAgICAgaW5kZXggPSAwLAogICAgICAgICAgICAgICAgYWN0dWFsSW5kZXggPSAwOwogICAgICAgICAgICB3aGlsZShpbmRleCA8IGdlb2dyYXBoaWNhbE9yZGVyTGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBhY3R1YWxJbmRleCA9IChpbmRleCArIHRyYXZlcnNhbEluZGV4KSAlIGdlb2dyYXBoaWNhbE9yZGVyTGVuZ3RoOwogICAgICAgICAgICAgICAgaWYoIXRoaXMuZ2VvZ3JhcGhpY2FsT3JkZXJbYWN0dWFsSW5kZXhdLnZpc2l0ZWQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWN0dWFsSW5kZXg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbmRleCsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9LAoKICAgICAgICAvLyBhc3NpZ24gc2FtZSB0YWIgaW5kZXggdG8gYWxsIHRoZSBjaGlsZCBvZiBleGNsdWRlIGdyb3VwCiAgICAgICAgLy8gaWYgZXhjbHVkZSBncm91cCBjb250YWluIGZpcnN0IHRyYXZlcnNlIG9iamVjdCwgdGhlbiB0aGUgY2hpbGQgYmVpbmcgcmVmZXJyZWQgYXMgZmlyc3Qgc2hvdWxkIGhhdmUgbGVzcyB0YWJpbmRleAogICAgICAgIC8vIGNvbXBhcmVkIHRvIG90aGVyIGNoaWxkCiAgICAgICAgX3VwZGF0ZVRhYkluZGV4T2ZFeGNsR3JvdXBDaGlsZHJlbiA6IGZ1bmN0aW9uIChleGNsR3JvdXBWaWV3LCB0YWJJbmRleCwgZmlyc3RDaGlsZFNvbSkgewogICAgICAgICAgICBfLmVhY2goZXhjbEdyb3VwVmlldy5jaGlsZFZpZXdzLCBmdW5jdGlvbihjaGlsZCl7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5faXNWaWV3RWxpZ2libGVGb3JUYWJiaW5nKGNoaWxkKSkgewogICAgICAgICAgICAgICAgICAgIGlmKGZpcnN0Q2hpbGRTb20gJiYgY2hpbGQubW9kZWwuc29tRXhwcmVzc2lvbiA9PSBmaXJzdENoaWxkU29tKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhYkluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnVwZGF0ZVRhYkluZGV4KHRhYkluZGV4LTEpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9sYXN0RmllbGRUYWJiZWQgPSBjaGlsZDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC51cGRhdGVUYWJJbmRleCh0YWJJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgaWYgKCFmaXJzdENoaWxkU29tKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9sYXN0RmllbGRUYWJiZWQgPSBleGNsR3JvdXBWaWV3LmNoaWxkVmlld3NbMF07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICsrdGFiSW5kZXg7CiAgICAgICAgfSwKCiAgICAgICAgLy8gZmluZCBpZiBhbnkgY2hpbGQgY29udGFpbnMgbmV4dCBwb2ludGVyIGFuZCB1cGRhdGUgdHJhdmVyc2FsIGluZGV4CiAgICAgICAgLy8gc3RhcnQgd2l0aCB0aGUgbGFzdCBpbiB0aGUgZ2VvZ3JhcGhpY2FsIG9yZGVyIG9mIHRoZSBjaGlsZHJlbiBhbmQgZmluZCBjaGlsZCB3aGljaCBoYXZlIG5leHQgdHJhdmVyc2FsCiAgICAgICAgX2ZpbmRUcmF2ZXJzYWxJbkV4Y2xHcm91cENoaWxkcmVuIDogZnVuY3Rpb24gKGV4Y2xHcm91cFZpZXcsIHRyYXZlcnNhbEluZGV4KSB7CiAgICAgICAgICAgIHZhciBzb3J0ZWRDaGlsZFZpZXcgPSB0aGlzLl9zb3J0Vmlld0dlb2dyYXBoaWNhbGx5KGV4Y2xHcm91cFZpZXcuY2hpbGRWaWV3cyksCiAgICAgICAgICAgICAgICB0ZW1wT2JqID0gbnVsbCwKICAgICAgICAgICAgICAgIGNoaWxkVmlldyA9IG51bGwsCiAgICAgICAgICAgICAgICBjaGlsZE1vZGVsID0gbnVsbCwKICAgICAgICAgICAgICAgIHRyYXZlcnNhbE9iaiA9IG51bGwsCiAgICAgICAgICAgICAgICBuZXh0Vmlld1NvbSA9IG51bGwsCiAgICAgICAgICAgICAgICBpbmRleCA9IC0xOwoKICAgICAgICAgICAgc29ydGVkQ2hpbGRWaWV3LnJldmVyc2UoKTsKICAgICAgICAgICAgdGVtcE9iaiA9IF8uZmluZChzb3J0ZWRDaGlsZFZpZXcsIGZ1bmN0aW9uKGNoaWxkKSB7CiAgICAgICAgICAgICAgICBjaGlsZFZpZXcgPSBjaGlsZC52aWV3OwogICAgICAgICAgICAgICAgY2hpbGRNb2RlbCA9IGNoaWxkVmlldy5tb2RlbDsKICAgICAgICAgICAgICAgIGlmKGNoaWxkTW9kZWwgJiYgKHRyYXZlcnNhbE9iaiA9IGNoaWxkTW9kZWwuZ2V0VHJhdmVyc2FsT2JqZWN0KCkpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNhbE9iai5sZW5ndGggPiAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIGlmICh0ZW1wT2JqKSB7CiAgICAgICAgICAgICAgICBuZXh0Vmlld1NvbSA9IHRlbXBPYmoubW9kZWwuZ2V0TmV4dFRyYXZlcnNhbFNvbSh4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLm5leHRUcmF2ZXJzYWwpOwogICAgICAgICAgICAgICAgaW5kZXggPSB0aGlzLl9maW5kVmlld0luR2VvZ3JhcGhpY2FsT3JkZXJBcnJheShuZXh0Vmlld1NvbSk7CiAgICAgICAgICAgICAgICB0cmF2ZXJzYWxJbmRleCA9IGluZGV4ICE9IC0xID8gaW5kZXggOiB0cmF2ZXJzYWxJbmRleCArIDE7CiAgICAgICAgICAgIH0gZWxzZSB7IC8vIGVsc2UgZ2V0IG5leHQgdW52aXNpdGVkIGJhc2VkIG9uIGdlb2dyYXBoaWNhbCBsb2NhdGlvbgogICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXggPSB0aGlzLl9maW5kTmV4dFZpZXdUb0JlVHJhdmVyc2VkKHRyYXZlcnNhbEluZGV4KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHJhdmVyc2FsSW5kZXg7CiAgICAgICAgfSwKCiAgICAgICAgLy8gY2hlY2sgaWYgdGhlIHZpZXcgaXMgaW5pdGlhbGl6ZWQgYW5kIHZpc2libGUKICAgICAgICBfaXNWaWV3RWxpZ2libGVGb3JUYWJiaW5nIDogZnVuY3Rpb24gKHZpZXcpIHsKICAgICAgICAgICAgaWYgKHZpZXcuX2luaXRpYWxpemVkICYmIHZpZXcuJGVsLmNzcygidmlzaWJpbGl0eSIpICE9ICJoaWRkZW4iKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgLy8gcmV0dXJuIG1hcCBvZiB3aGV0aHRlciBwcm92aWRlZCB2aWV3IGlzIGluc3RhbmNlIG9mIHRoZSB2YXJpb3VzIHZpZXdzCiAgICAgICAgX2dldE1hcE9mSW5zdGFuY2VDaGVjayA6IGZ1bmN0aW9uICh2aWV3KSB7CiAgICAgICAgICAgIHZhciBpbnN0YW5jZUNoZWNrTWFwID0ge307CiAgICAgICAgICAgIGluc3RhbmNlQ2hlY2tNYXAuaXNTdWJmb3JtID0gdmlldyBpbnN0YW5jZW9mIHhmYWxpYi52aWV3LlN1YmZvcm1WaWV3OwogICAgICAgICAgICBpbnN0YW5jZUNoZWNrTWFwLmlzRmllbGQgPSB2aWV3IGluc3RhbmNlb2YgeGZhbGliLnZpZXcuRmllbGRWaWV3OwogICAgICAgICAgICBpbnN0YW5jZUNoZWNrTWFwLmlzRHJhdyA9IHZpZXcgaW5zdGFuY2VvZiB4ZmFsaWIudmlldy5YZmFEcmF3VmlldzsKICAgICAgICAgICAgaW5zdGFuY2VDaGVja01hcC5pc0V4Y2xHcm91cCA9IHZpZXcgaW5zdGFuY2VvZiB4ZmFsaWIudmlldy5FeGNsR3JvdXBWaWV3OwogICAgICAgICAgICBpbnN0YW5jZUNoZWNrTWFwLmlzQ2hpbGRPZkV4Y2xHcm91cCA9IHZpZXcucGFyZW50VmlldyBpbnN0YW5jZW9mIHhmYWxpYi52aWV3LkV4Y2xHcm91cFZpZXc7CiAgICAgICAgICAgIGluc3RhbmNlQ2hlY2tNYXAuaXNDb250YWluZXIgPSB2aWV3IGluc3RhbmNlb2YgeGZhbGliLnZpZXcuQ29udGFpbmVyVmlldzsKCiAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZUNoZWNrTWFwOwogICAgICAgIH0sCgogICAgICAgIC8vIGFkZCBldmVudCBoYW5kbGVyIGZvciByZW5kZXJpbmcgbmV4dCBwYWdlIG9uIHRhYmJpbmcgb24gbGFzdCBmaWVsZCBvZiB0aGUgcGFnZQogICAgICAgIF9yZW5kZXJOZXh0UGFnZUZ1dHVyZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKHRoaXMuX2xhc3RGaWVsZFRhYmJlZCkgewogICAgICAgICAgICAgICAgdGhpcy5fbGFzdEZpZWxkVGFiYmVkLiRlbC5vbmUoJ2ZvY3VzaW4udHJhdmVyc2FsTWFuYWdlcicsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHZhciBwYWdpbmdNYW5hZ2VyID0gd2luZG93LmZvcm1CcmlkZ2UgPyB3aW5kb3cuZm9ybUJyaWRnZS5wYWdpbmdNYW5hZ2VyKCkgOiBudWxsOwogICAgICAgICAgICAgICAgICAgICQod2luZG93KS5vbiggImtleXVwLnRyYXZlcnNhbE1hbmFnZXIiLCBmdW5jdGlvbiAoZSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29kZSA9IChlLmtleUNvZGUgPyBlLmtleUNvZGUgOiBlLndoaWNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvZGUgPT0gOSAmJiBwYWdpbmdNYW5hZ2VyICYmIHBhZ2luZ01hbmFnZXIuaGFzTW9yZVBhZ2VzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2luZ01hbmFnZXIucmVuZGVyTmV4dFBhZ2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQod2luZG93KS5vZmYoImtleXVwLnRyYXZlcnNhbE1hbmFnZXIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIF9kZXN0cm95IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHRoaXMuZ2VvZ3JhcGhpY2FsT3JkZXIgPSBudWxsOwogICAgICAgIH0KICAgIH0KfSkoXywgJCwgeGZhbGliKTsKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKgoqIEFET0JFIENPTkZJREVOVElBTAoqIF9fX19fX19fX19fX19fX19fX18KKgoqICBDb3B5cmlnaHQgMjAxMyBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAoqICBBbGwgUmlnaHRzIFJlc2VydmVkLgoqCiogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAoqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKKiBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuCiogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiogaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CgogICAgdmFyIEVycm9yTWFuYWdlciA9IHhmYWxpYi52aWV3LnV0aWwuRXJyb3JNYW5hZ2VyID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CgogICAgICAgIG9wdGlvbnM6IHsKICAgICAgICAgICAgd2FybmluZ01lc3NhZ2VWaXNpYmxlOmZhbHNlLAogICAgICAgICAgICBlcnJvck1lc3NhZ2VWaXNpYmxlOiBmYWxzZQogICAgICAgIH0sCgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgJCh3aW5kb3cpLm9uKCJkZXN0cm95LnhmYSIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICQoIiNlcnJvci1tc2ciKS5oaWRlKCk7CiAgICAgICAgICAgICAgICAkKCIjd2FybmluZy1tc2ciKS5oaWRlKCk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIG9uRmllbGRFbnRlcjogZnVuY3Rpb24gKGpxV2lkZ2V0KSB7CiAgICAgICAgICAgIHZhciBlbGVtZW50ID0ganFXaWRnZXQuZWxlbWVudDsKICAgICAgICAgICAgaWYgKGpxV2lkZ2V0Lm9wdGlvbigiZXJyb3JNZXNzYWdlIil8fCBqcVdpZGdldC5vcHRpb24oIndhcm5pbmdNZXNzYWdlIikpIHsKICAgICAgICAgICAgICAgIHZhciBwb3MgPSAkKGVsZW1lbnQpLm9mZnNldCgpLAogICAgICAgICAgICAgICAgICAgIHN0eWxlcyA9IHt9OwogICAgICAgICAgICAgICAgc3R5bGVzLmxlZnQgPSAocG9zLmxlZnQgKiAoMSAvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IpICsgZWxlbWVudC53aWR0aCgpICsgNSkgKyAicHgiOwogICAgICAgICAgICAgICAgc3R5bGVzLnRvcCA9IHBvcy50b3AgKiAoMSAvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IpICsgInB4IjsKICAgICAgICAgICAgICAgIGlmIChqcVdpZGdldC5vcHRpb24oImVycm9yTWVzc2FnZSIpKSB7CiAgICAgICAgICAgICAgICAgICAganFXaWRnZXQuJGNzcygkKCIjZXJyb3ItbXNnIikuZ2V0KDApLCBzdHlsZXMpOwogICAgICAgICAgICAgICAgICAgICQoIiNlcnJvci1tc2ciKS50ZXh0KGpxV2lkZ2V0Lm9wdGlvbigiZXJyb3JNZXNzYWdlIikpLnNob3coKTsKICAgICAgICAgICAgICAgICAgICBqcVdpZGdldC5vcHRpb24oImVycm9yTWVzc2FnZVZpc2libGUiLHRydWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoanFXaWRnZXQub3B0aW9uKCJ3YXJuaW5nTWVzc2FnZSIpKSB7CiAgICAgICAgICAgICAgICAgICAganFXaWRnZXQuJGNzcygkKCIjd2FybmluZy1tc2ciKS5nZXQoMCksIHN0eWxlcyk7CiAgICAgICAgICAgICAgICAgICAgJCgiI3dhcm5pbmctbXNnIikudGV4dChqcVdpZGdldC5vcHRpb24oIndhcm5pbmdNZXNzYWdlIikpLnNob3coKTsKICAgICAgICAgICAgICAgICAgICBqcVdpZGdldC5vcHRpb24oIndhcm5pbmdNZXNzYWdlVmlzaWJsZSIsdHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBvbkZpZWxkRXhpdDogZnVuY3Rpb24gKGpxV2lkZ2V0KSB7CiAgICAgICAgICAgIGlmIChqcVdpZGdldC5vcHRpb24oImVycm9yTWVzc2FnZVZpc2libGUiKSkgewogICAgICAgICAgICAgICAgJCgiI2Vycm9yLW1zZyIpLmhpZGUoKTsKICAgICAgICAgICAgICAgIGpxV2lkZ2V0Lm9wdGlvbigiZXJyb3JNZXNzYWdlVmlzaWJsZSIsZmFsc2UpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGpxV2lkZ2V0Lm9wdGlvbigid2FybmluZ01lc3NhZ2VWaXNpYmxlIikpIHsKICAgICAgICAgICAgICAgICQoIiN3YXJuaW5nLW1zZyIpLmhpZGUoKTsKICAgICAgICAgICAgICAgIGpxV2lkZ2V0Lm9wdGlvbigid2FybmluZ01lc3NhZ2VWaXNpYmxlIixmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBtYXJrRXJyb3I6IGZ1bmN0aW9uIChqcVdpZGdldCwgbXNnLCB0eXBlKSB7CiAgICAgICAgICAgIC8vIGFzc2lnbmluZyByb2xlPSJhbGVydCIgc28gdGhhdCBKQVdTIHJlYWRzLW91dCB0aGUgdmFsaWRhdGlvbiBtZXNzYWdlCiAgICAgICAgICAgIGlmICh0eXBlICE9ICJ3YXJuaW5nIikgewogICAgICAgICAgICAgICAgaWYgKCQoIiNlcnJvci1tc2ciKS5sZW5ndGggPCAxKQogICAgICAgICAgICAgICAgICAgICQoIjxkaXYgaWQ9J2Vycm9yLW1zZycgcm9sZT0nYWxlcnQnPjwvZGl2PiIpLmFwcGVuZFRvKCdib2R5Jyk7CiAgICAgICAgICAgICAgICBqcVdpZGdldC5vcHRpb24oImVycm9yTWVzc2FnZSIsbXNnKTsKICAgICAgICAgICAgICAgIGpxV2lkZ2V0LmVsZW1lbnQuYWRkQ2xhc3MoImRhdGFJbnZhbGlkIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoJCgiI3dhcm5pbmctbXNnIikubGVuZ3RoIDwgMSkKICAgICAgICAgICAgICAgICAgICAkKCI8ZGl2IGlkPSd3YXJuaW5nLW1zZycgcm9sZT0nYWxlcnQnPjwvZGl2PiIpLmFwcGVuZFRvKCdib2R5Jyk7CiAgICAgICAgICAgICAgICBqcVdpZGdldC5vcHRpb24oIndhcm5pbmdNZXNzYWdlIixtc2cpOwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIGNsZWFyRXJyb3I6IGZ1bmN0aW9uIChqcVdpZGdldCkgewogICAgICAgICAgICB0aGlzLm9uRmllbGRFeGl0KGpxV2lkZ2V0KTsKICAgICAgICAgICAganFXaWRnZXQuZWxlbWVudC5yZW1vdmVDbGFzcygiZGF0YUludmFsaWQiKTsKICAgICAgICAgICAganFXaWRnZXQub3B0aW9uKCJlcnJvck1lc3NhZ2UiLG51bGwpOwogICAgICAgICAgICBqcVdpZGdldC5vcHRpb24oIndhcm5pbmdNZXNzYWdlIixudWxsKTsKICAgICAgICB9CiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sJCwgeGZhbGliKSB7CiAgICB2YXIgeGZhVXRpbCA9IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZSwKICAgICAgICBCVUZGRVJfU1BDID0gMjA7CgogICAgLyogdGVtcGxhdGUgZm9yIHRoZSBjbGVhciBCdXR0b24gKi8KICAgIHZhciBjbGVhckJ1dHRvblRlbXBsYXRlID0gJzxkaXYgY2xhc3M9ImRwLWNsZWFyIj4nICsKICAgICAgICAnPGE+PC9hPicgKwogICAgICAgICc8L2Rpdj4nOwoKICAgIC8qIHRlbXBsYXRlIGZvciB0aGUgY2FsZW5kYXIKICAgICogaGVhZGVyIGNvbnRhaW5zIHRoZSBuYXZpZ2F0aW9uIGljb25zIChsZWZ0IGFuZCByaWdodCBhcnJvd3MpCiAgICAqIGFuZCB0aGUgY3VycmVudCBjYXB0aW9uICh3aGljaCBjYW4gYmUgZGF0ZSwgeWVhciBvciBtb250aCkKICAgICoKICAgICogbW9udGh2aWV3IGRpc3BsYXlzIHRoZSBncmlkIGZvciBzaG93aW5nIHRoZSBkYXRlcyBmb3IgYSBwYXJ0aWN1bGFyCiAgICAqIG1vbnRoCiAgICAqCiAgICAqIHllYXJ2aWV3IGRpc3BsYXlzIGFsbCB0aGUgbW9udGhzIG9mIHRoYXQgeWVhcgogICAgKgogICAgKiB5ZWFyc2V0dmlldyBkaXNwbGF5cyBhIGdyaWQgb2YgMTYgeWVhcnMuIFRoaXMgY2FuIGJlIGNvbmZpZ3VyZWQKICAgICogdGhyb3VnaCB0aGUgb3B0aW9uOiB5ZWFyc1BlclZpZXcKICAgICoKICAgICovCiAgICB2YXIgY2FsZW5kYXJUZW1wbGF0ZSA9ICc8ZGl2IGNsYXNzPSJkcC1oZWFkZXIiPicgKwogICAgICAgICc8ZGl2IGNsYXNzPSJkcC1sZWZ0bmF2Ij48L2Rpdj4nICsKICAgICAgICAnPGRpdiBjbGFzcz0iZHAtY2FwdGlvbiI+PC9kaXY+JyArCiAgICAgICAgJzxkaXYgY2xhc3M9ImRwLXJpZ2h0bmF2Ij48L2Rpdj4nICsKICAgICAgICAnPC9kaXY+JyArCiAgICAgICAgJzxkaXYgcm9sZT0idGFibGUiIGNsYXNzPSJ2aWV3IGRwLW1vbnRodmlldyI+PC9kaXY+JyArCiAgICAgICAgJzxkaXYgcm9sZT0idGFibGUiIGNsYXNzPSJ2aWV3IGRwLXllYXJ2aWV3Ij48L2Rpdj4nICsKICAgICAgICAnPGRpdiByb2xlPSJ0YWJsZSIgY2xhc3M9InZpZXcgZHAteWVhcnNldHZpZXciPjwvZGl2Pic7CgogICAgLyp0ZW1wbGF0ZSBmb3IgdGhlIHRpbWVyOiBub3QgaW1wbGVtZW50ZWQgeWV0ICovCiAgICB2YXIgd2F0Y2hUZW1wbGF0ZSA9ICc8ZGl2IGNsYXNzPSJkcC1oZWFkZXIiPicgKwogICAgICAgICc8ZGl2IGNsYXNzPSJkcC1sZWZ0bmF2Ij48L2Rpdj4nICsKICAgICAgICAnPGRpdiBjbGFzcz0iZHAtY2FwdGlvbiI+PC9kaXY+JyArCiAgICAgICAgJzxkaXYgY2xhc3M9ImRwLXJpZ2h0bmF2Ij48L2Rpdj4nICsKICAgICAgICAnPC9kaXY+JyArCiAgICAgICAgJzxkaXYgY2xhc3M9InZpZXcgZHAtbW9udGh2aWV3Ij48L2Rpdj4nICsKICAgICAgICAnPGRpdiBjbGFzcz0idmlldyBkcC15ZWFydmlldyI+PC9kaXY+JyArCiAgICAgICAgJzxkaXYgY2xhc3M9InZpZXcgZHAteWVhcnNldHZpZXciPjwvZGl2Pic7CgogICAgLyoqIGRlZmF1bHQgY29uZmlndXJhdGlvbiBvcHRpb25zCiAgICAgKgogICAgICogY29udGFpbmVyOiB0aGUgaHRtbCBlbGVtZW50IHdoZXJlIHRoZSBkYXRlcGlja2VyIHRlbXBsYXRlIHdpbGwgYmUgYWRkZWQKICAgICAqCiAgICAgKiB5ZWFyc1BlclZpZXc6IG51bWJlciBvZiB5ZWFycyB0byBzaG93IGluIHRoZSB5ZWFyc2V0IHZpZXcKICAgICAqCiAgICAgKiB3aWR0aDogd2l0aCBvZiB0aGUgd2lkZ2V0CiAgICAgKgogICAgICogdmlld0hlaWdodDogSGVpZ2h0IG9mIHRoZSBtb250aCx5ZWFyIGFuZCB5ZWFyc2V0IHZpZXcuIFRoaXMgZG9lc24ndCBpbmNsdWRlCiAgICAgKiAgICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBoZWFkZXIKICAgICAqCiAgICAgKiBsb2NhbGU6IGxvY2FsZSBpbmZvcm1hdGlvbiBmb3IgdGhlIGxvY2FsZSBpbiB3aGljaCB0byBzaG93IHRoZSBkYXRlcGlja2VyIHdoaWNoIGNvbXByaXNlcyBvZgogICAgICogICAgICAgIGRheXM6IGRheSBuYW1lcyB0byBkaXNwbGF5IGluIHRoZSBtb250aHZpZXcKICAgICAqICAgICAgICBtb250aHM6IG1vbnRoIG5hbWVzIHRvIGRpc3BsYXkgaW4gdGhlIHllYXJ2aWV3CiAgICAgKiAgICAgICAgemVybzogc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHplcm8gaW4gdGhlIGxvY2FsZS4gTnVtYmVycyB3aWxsIGJlCiAgICAgKiAgICAgICAgICAgICAgZGlzcGxheWVkIGluIHRoYXQgbG9jYWxlIG9ubHkKICAgICAqICAgICAgICBjbGVhclRleHQ6IFRleHQgdG8gZGlzcGxheSBmb3IgdGhlIHJlc2V0IGJ1dHRvbgogICAgICogICAgICAgIG5hbWU6IG5hbWUgb2YgdGhlIGxvY2FsZQogICAgICoKICAgICAqIGZvcm1hdDogaW5wdXQgZm9ybWF0IGZvciB0aGUgZGF0ZXBpY2tlciAobm90IGltcGxlbWVudGVkKQogICAgICoKICAgICAqIHBpY2tlclR5cGU6IHR5cGUgb2YgdGhlIGRhdGV0aW1lcGlja2VyIChkYXRlLCBkYXRldGltZSBhbmQgdGltZSkKICAgICAqCiAgICAgKiBwb3NpdGlvbmluZzogZWxlbWVudCBhcm91bmQgd2hpY2ggZGF0ZXBpY2tlciB3aWxsIGJlIGRpc3BsYXllZC4gaWYgbnVsbCB0aGVuIGl0CiAgICAgKiAgICAgICAgICAgICAgd2lsbCBiZSBkaXNwbGF5ZWQgYXJvdW5kIHRoZSBpbnB1dCBlbGVtZW50CiAgICAgKgogICAgICogc2hvd0NhbGVuZGFySWNvbjogdG8gc2hvdyB0aGUgQ2FsZW5kYXIgb24gdGhlIHJpZ2h0IG9mIHRoZSB0ZXh0IGZpZWxkIG9yIG5vdAogICAgICovCgogICAgdmFyIGRlZmF1bHRzID0gewogICAgICAgIGNvbnRhaW5lcjogImJvZHkiLAogICAgICAgIHllYXJzUGVyVmlldzogMTYsCiAgICAgICAgd2lkdGg6IDM0MCwKICAgICAgICB2aWV3SGVpZ2h0OiAyNDgsCiAgICAgICAgbG9jYWxlOiB7CiAgICAgICAgICAgIGRheXM6WyJTIiwiTSIsIlQiLCJXIiwiVCIsIkYiLCJTIl0sCiAgICAgICAgICAgIG1vbnRoczogWyJKYW51YXJ5IiwiRmVicnVhcnkiLCJNYXJjaCIsIkFwcmlsIiwiTWF5IiwiSnVuZSIsIkp1bHkiLCJBdWd1c3QiLCJTZXB0ZW1iZXIiLCJPY3RvYmVyIiwiTm92ZW1iZXIiLCJEZWNlbWJlciJdLAogICAgICAgICAgICB6ZXJvOiAiMCIsCiAgICAgICAgICAgIGNsZWFyVGV4dDogIkNsZWFyIiwKICAgICAgICAgICAgbmFtZToiZW5fVVMiCiAgICAgICAgfSwKICAgICAgICBmb3JtYXQ6IllZWVktTU0tREQiLAogICAgICAgIHBpY2tlclR5cGU6ImRhdGUiLAogICAgICAgIHBvc2l0aW9uaW5nOiBudWxsLAogICAgICAgIHNob3dDYWxlbmRhckljb246IGZhbHNlCiAgICB9LAogICAgZGF0ZXMgPSBbMzEsMjgsMzEsMzAsMzEsMzAsMzEsMzEsMzAsMzEsMzAsMzFdLAogICAgLyoKICAgICAqICBBY3Rpb25zIHRvIHBlcmZvcm0gd2hlbiBjbGlja2VkIG9uIHRoZSBkYXRlcGlja2VyIGJ1dHRvbnMKICAgICAqICBmb3IgZGlmZmVyZW50IHZpZXdzCiAgICAgKiAgY2FwdGlvbjogdmlldyB0byBzaG93IHdoZW4gY2xpY2tlZCBvbiBjYXB0aW9uCiAgICAgKiAgICAgICAgICAgKFllYXIvWWVhclNldC9Nb250aC9udWxsKSBudWxsIG1lYW5zIGRvbid0IGNoYW5nZSB0aGUgdmlldwogICAgICogIGxpOiB2aWV3IHRvIHNob3cgd2hlbiBjbGlja2VkIG9uIGRhdGUsIG1vbnRoIG9yIHllYXIgZWxlbWVudAogICAgICogIHVwRG93bjogYWRkKHVwIGtleSkgb3Igc3VidHJhY3QoZG93biBrZXkpIGN1cnJlbnQgZGF0ZSAoZm9yIG1vbnRodmlldyksCiAgICAgKiAgICAgICAgICBtb250aChZZWFyIFZpZXcpIG9yIHllYXIoWWVhclNldFZpZXcpIHdpdGggdGhlIG51bWJlciBwcm92aWRlZAogICAgICogIGtleTogaWRlbnRpZmllcyB0aGUga2V5IHRoYXQgbmVlZHMgdG8gYmUgY2hhbmdlZCBmb3IgdGhhdCB2aWV3CiAgICAgKi8KICAgIHZpZXdBY3Rpb24gPSB7CiAgICAgICAgTW9udGg6IHsKICAgICAgICAgICAgY2FwdGlvbjogJ1llYXInLAogICAgICAgICAgICBsaTogbnVsbCwKICAgICAgICAgICAga2V5OiJkYXkiLAogICAgICAgICAgICB1cERvd246NwogICAgICAgIH0sCiAgICAgICAgWWVhcjogewogICAgICAgICAgICBjYXB0aW9uOiAiWWVhcnNldCIsCiAgICAgICAgICAgIGxpOiAiTW9udGgiLAogICAgICAgICAgICBrZXk6Im1vbnRoIiwKICAgICAgICAgICAgdXBEb3duOjMKICAgICAgICB9LAogICAgICAgIFllYXJzZXQ6IHsKICAgICAgICAgICAgY2FwdGlvbjogbnVsbCwKICAgICAgICAgICAgbGk6ICJZZWFyIiwKICAgICAgICAgICAga2V5OiJ5ZWFyIiwKICAgICAgICAgICAgdXBEb3duOjQKICAgICAgICB9CiAgICB9LAogICAgaGVhZGVyQ2xhc3MgPSAiaGVhZGVyIiwKCiAgICBEYXRlVGltZVBpY2tlciA9IGZ1bmN0aW9uKCkgewogICAgICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSBmYWxzZTsKICAgIH0KCiAgICAkLmV4dGVuZChEYXRlVGltZVBpY2tlci5wcm90b3R5cGUsIHsKICAgICAgICAvKgogICAgICAgICAqIGNyZWF0ZSB0aGUgd2lkZ2V0IHVzaW5nIHRoZSBwcm92aWRlZCBvcHRpb25zCiAgICAgICAgICovCiAgICAgICAgY3JlYXRlOiBmdW5jdGlvbihvcHRpb25zKSB7CiAgICAgICAgICAgIHZhciAkZHAsc2VsZiA9IHRoaXMsaHRtbD0iIixwcmV2TmF2V2lkdGgsbmV4dE5hdldpZHRoOwogICAgICAgICAgICBpZiAod2luZG93LkZEICYmIHdpbmRvdy5GRC5pc1RvZ2dsZUVuYWJsZWQoIkZUX0ZPUk1TLTEzNTk5IikpIHsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0cy53aWR0aCA9IDQzMzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gJC5leHRlbmQoe30sZGVmYXVsdHMsb3B0aW9ucyk7CiAgICAgICAgICAgIC8vIHByZXZlbnQgbWVtb3J5IGxlYWsgc2luY2Ugb3B0aW9ucy5wb3NpdGlvbmluZyBob2xkcyByZWZlcmVuY2UgdG8gSFRNTCBET00KICAgICAgICAgICAgdGhpcy5vcHRpb25zLnBvc2l0aW9uaW5nID0gbnVsbDsKICAgICAgICAgICAgLy8gSWYgd2lkdGggb2YgZGF0ZS1waWNrZXIgZXhjZWVkcyBzY3JlZW4gd2lkdGggdGhlbiBpdCdsbCB0YWtlIHVwIHRoZSBlbnRpcmUgc2NyZWVuIHdpZHRoIGluIEFGCiAgICAgICAgICAgIGlmKHdpbmRvdy5ndWlkZUJyaWRnZSAmJiB0aGlzLm9wdGlvbnMud2lkdGggPiB3aW5kb3cuaW5uZXJXaWR0aCAmJiB3aW5kb3cuaW5uZXJXaWR0aCA+IDApIHsKICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLndpZHRoPXdpbmRvdy5pbm5lcldpZHRoIC0gQlVGRkVSX1NQQzsgLy8gYnVmZmVyCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLnBpY2tlclR5cGUubWF0Y2goL2RhdGUvKSkgewogICAgICAgICAgICAgICAgaHRtbCArPSBjYWxlbmRhclRlbXBsYXRlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZih0aGlzLm9wdGlvbnMucGlja2VyVHlwZS5tYXRjaCgvdGltZS8pKSB7CiAgICAgICAgICAgICAgICBodG1sICs9IHdhdGNoVGVtcGxhdGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGh0bWwgKz0gY2xlYXJCdXR0b25UZW1wbGF0ZTsKCiAgICAgICAgICAgICQuZXh0ZW5kKHRoaXMsIHsKICAgICAgICAgICAgICAgIHNlbGVjdGVkRGF5OjAsCiAgICAgICAgICAgICAgICBzZWxlY3RlZE1vbnRoOjAsCiAgICAgICAgICAgICAgICBzZWxlY3RlZFllYXI6MCwKICAgICAgICAgICAgICAgIGN1cnJlbnREYXk6MCwKICAgICAgICAgICAgICAgIGN1cnJlbnRNb250aDowLAogICAgICAgICAgICAgICAgY3VycmVudFllYXI6MCwKICAgICAgICAgICAgICAgIHRvdWNoU3VwcG9ydGVkIDogeGZhbGliLnV0LlRvdWNoVXRpbC5UT1VDSF9FTkFCTEVELAogICAgICAgICAgICAgICAgX3Zpc2libGU6ZmFsc2UsCiAgICAgICAgICAgICAgICBfZGVmYXVsdFZpZXc6Ik1vbnRoIiwKICAgICAgICAgICAgICAgIF9rZXlzRW5hYmxlZDpmYWxzZSwKICAgICAgICAgICAgICAgIGZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtIDogZmFsc2UsCiAgICAgICAgICAgICAgICBrZXlib2FyZEFjY2Vzc2liaWxpdHkgOiB0cnVlLAogICAgICAgICAgICAgICAgJGRwOiQoIjxkaXY+PC9kaXY+IikuYWRkQ2xhc3MoImRhdGV0aW1lcGlja2VyIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndpZHRoKHRoaXMub3B0aW9ucy53aWR0aCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFwcGVuZChodG1sKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoImRhdGVQaWNrZXJUYXJnZXQiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kVG8odGhpcy5vcHRpb25zLmNvbnRhaW5lcikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvZ2dsZUNsYXNzKCJkYXRldGltZXBpY2tlci1ub3RvdWNoIix0aGlzLnRvdWNoU3VwcG9ydGVkKSwKICAgICAgICAgICAgICAgICRtb250aDogJCgiLmRwLW1vbnRodmlldyIsdGhpcy4kZHApLmhlaWdodCh0aGlzLm9wdGlvbnMudmlld0hlaWdodCksCiAgICAgICAgICAgICAgICAkeWVhcjogJCgiLmRwLXllYXJ2aWV3Iix0aGlzLiRkcCkuaGVpZ2h0KHRoaXMub3B0aW9ucy52aWV3SGVpZ2h0KSwKICAgICAgICAgICAgICAgICR5ZWFyc2V0IDogJCgiLmRwLXllYXJzZXR2aWV3Iix0aGlzLiRkcCkuaGVpZ2h0KHRoaXMub3B0aW9ucy52aWV3SGVpZ2h0KQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgdGhpcy5hY3R1YWxXaWR0aCA9IE1hdGguZmxvb3IodGhpcy4kZHAud2lkdGgoKSk7CiAgICAgICAgICAgIHRoaXMuJGNsZWFyID0gJCgnLmRwLWNsZWFyIGEnLCB0aGlzLiRkcCkub24oImNsaWNrIiwgJC5wcm94eSh0aGlzLl9jbGVhckRhdGUsIHRoaXMpKTsKICAgICAgICAgICAgdGhpcy4kcHJldk5hdldpZHRoQnRuID0gJCgiLmRwLWxlZnRuYXYiLCB0aGlzLiRkcCkub24oImNsaWNrIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oZXZudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fYWRqdXN0RGF0ZSgtMSwgc2VsZi52aWV3LCBmYWxzZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHRoaXMuJG5leHROYXZXaWR0aEJ0biA9ICQoIi5kcC1yaWdodG5hdiIsIHRoaXMuJGRwKS5vbigiY2xpY2siLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9hZGp1c3REYXRlKDEsIHNlbGYudmlldywgZmFsc2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICBwcmV2TmF2V2lkdGggPSB0aGlzLiRwcmV2TmF2V2lkdGhCdG4ub3V0ZXJXaWR0aCh0cnVlKTsKICAgICAgICAgICAgbmV4dE5hdldpZHRoID0gdGhpcy4kbmV4dE5hdldpZHRoQnRuLm91dGVyV2lkdGgodHJ1ZSk7CiAgICAgICAgICAgIHRoaXMuJGNhcHRpb24gPSAkKCIuZHAtY2FwdGlvbiIsIHRoaXMuJGRwKS53aWR0aCh0aGlzLmFjdHVhbFdpZHRoIC0gcHJldk5hdldpZHRoIC0gbmV4dE5hdldpZHRoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbigiY2xpY2siLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZighc2VsZi4kY2FwdGlvbi5oYXNDbGFzcygiZGlzYWJsZWQiKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2xheW91dCh2aWV3QWN0aW9uW3NlbGYudmlld10uY2FwdGlvbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICBpZiAodGhpcy5rZXlib2FyZEFjY2Vzc2liaWxpdHkpIHsKICAgICAgICAgICAgICAgIF8uZWFjaChbdGhpcy4kcHJldk5hdldpZHRoQnRuLCB0aGlzLiRjYXB0aW9uLCB0aGlzLiRuZXh0TmF2V2lkdGhCdG4sIHRoaXMuJGNsZWFyXSwgZnVuY3Rpb24gKGVsZW0sIGkpIHsKICAgICAgICAgICAgICAgICAgICBlbGVtLmF0dHIoInRhYkluZGV4IiwgaSArIDEpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gYXR0YWNoIGNsaWNrIGV2ZW50IG9uIGVudGlyZSBkYXRlUGlja2VyIHBvcHVwCiAgICAgICAgICAgICQodGhpcy4kZHApLm9uKCJjbGljayIsCiAgICAgICAgICAgICAgICBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgICAgICAgICAgLy9mb2N1cyBvbmx5IGlmIHRoZSBkZXZpY2UgZG9lc24ndCBzdXBwb3J0IHRvdWNoCiAgICAgICAgICAgICAgICAgICAgLy8gaW5wdXQgb3RoZXJ3aXNlIG9uIHNjcmVlbiBrZXlib2FyZCB3aWxsIHBvcHVwCiAgICAgICAgICAgICAgICAgICAgaWYoIXNlbGYudG91Y2hTdXBwb3J0ZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2N1ckluc3RhbmNlLiRmaWVsZC5mb2N1cygpOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAkKHdpbmRvdykub24oInRvdWNoc3RhcnQuZGF0ZXRpbWVwaWNrZXIgbW91c2Vkb3duLmRhdGV0aW1lcGlja2VyIixzZWxmLl9jaGVja1dpbmRvd0NsaWNrZWQpOwogICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZSA9IG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBhdHRhY2hlcyB0aGUgZGF0ZSBwaWNrZXIgdG8gdGhlIGZpZWxkLiBUaGlzIGlzIGEgb25lIHRpbWUgb3BlcmF0aW9uCiAgICAgICAgICogRmlyc3QgY3JlYXRlcyBhIGNvbmZpZ3VyYXRpb24gb2JqZWN0IGFuZCBzdG9yZXMgaXQgaW4gdGhlIGZpZWxkIGRhdGEgYXR0cmlidXRlcwogICAgICAgICAqIHRoZW4gYXR0YWNoZXMgZXZlbnQgaGFuZGxlcnMgb24gY2xpY2ssIGZvY3VzICh0byBzaG93IHRoZSBwaWNrZXIpIGFuZCBibHVyICh0byBoaWRlKSBldmVudHMKICAgICAgICAgKi8KICAgICAgICBfYXR0YWNoRmllbGQ6IGZ1bmN0aW9uKCRmaWVsZCxvcHRpb25zLCB2YWx1ZSkgewogICAgICAgICAgICB2YXIgaW5zdCA9IHRoaXMuX25ld0luc3QoJGZpZWxkLG9wdGlvbnMsIHZhbHVlKSwKICAgICAgICAgICAgICAgIHNlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgYWN0aXZhdGVGaWVsZCA9IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IHhmYVV0aWwuJGRhdGEoZXZudC50YXJnZXQsImRhdGV0aW1lcGlja2VyIik7CiAgICAgICAgICAgICAgICAgICAgaWYoZGF0YS5hY2Nlc3MgPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZighc2VsZi5fY3VySW5zdGFuY2UpCiAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9hY3RpdmF0ZUZpZWxkKGV2bnQpOwoKICAgICAgICAgICAgICAgICAgICBpZihzZWxmLm9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbikgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZudC50eXBlID09PSBzZWxmLmdldEV2ZW50KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLl9pY29uQ2xpY2tlZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2ljb25DbGlja2VkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuX3Zpc2libGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5faGlkZSgpOyAvLyBoaWRlIHRoZSBjYWxlbmRhciBwb3B1cCBpZiB2aXNpYmxlIHdoZW4gY2FsZW5kYXIgaWNvbiBpcyBjbGlja2VkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2N1ckluc3RhbmNlLiRmaWVsZC5mb2N1cygpOyAvLyBicmluZyBiYWNrIGZvY3VzIGluIGZpZWxkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fc2hvdygpOyAvLy8vIHNob3cgdGhlIGNhbGVuZGFyIHBvcHVwIGlmIG5vdCB2aXNpYmxlIHdoZW4gY2FsZW5kYXIgaWNvbiBpcyBjbGlja2VkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLypzaG93IHRoZSBwb3B1cCBvbmx5IGlmCiAgICAgICAgICAgICAgICAgICAgICAgICAxLiBjbGljay90b3VjaCBldmVudAogICAgICAgICAgICAgICAgICAgICAgICAgMi4gZm9jdXMgZXZlbnQgaW4gY2FzZSBvZiBub24tdG91Y2ggZGV2aWNlcyBhbmQgZm9jdXMgaXMgbm90IGRvbmUgdXNpbmcgc2NyaXB0CiAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZudC50eXBlID09PSBzZWxmLmdldEV2ZW50KCkgfHwgKGV2bnQudHlwZSA9PT0gImZvY3VzIiAmJiAhc2VsZi50b3VjaFN1cHBvcnRlZCAmJiAhc2VsZi5zY3JpcHRGb2N1cykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3Nob3coZXZudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2NsaWNrZWRXaW5kb3cgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIHNlbGYuc2NyaXB0Rm9jdXMgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBkZWFjdGl2YXRlRmllbGQgPSBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgICAgICAgICAgLy9kZWFjdGl2YXRlIG9ubHkgaWYgY2xpY2tlZCBvdXRzaWRlIHdpbmRvdwogICAgICAgICAgICAgICAgICAgIC8vIG9uIHRvdWNoIGRldmljZXMgb25seSBrZXlib2FyZCBvciBjYWxhbmRlciBzaG91bGQgYmUgYWN0aXZlIGF0IG9uY2UsIHRvdWNoaW5nIGtleWJvYXJkIHNob3VsZCBkZWFjdGl2YXRlIGNhbGVuZGFyCiAgICAgICAgICAgICAgICAgICAgaWYgKChzZWxmLl9jbGlja2VkV2luZG93ICYmICFzZWxmLmZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtKSAmJiAoc2VsZi5vcHRpb25zLnNob3dDYWxlbmRhckljb24gfHwgIXNlbGYudG91Y2hTdXBwb3J0ZWQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2hpZGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGVhY3RpdmF0ZUZpZWxkKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NsaWNrZWRXaW5kb3cgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICB4ZmFVdGlsLiRkYXRhKCRmaWVsZFswXSwiZGF0ZXRpbWVwaWNrZXIiLGluc3QpOwoKICAgICAgICAgICAgJGZpZWxkLm9uKHRoaXMuZ2V0RXZlbnQoKSxhY3RpdmF0ZUZpZWxkKQogICAgICAgICAgICAgICAgICAuZm9jdXMoYWN0aXZhdGVGaWVsZCkKICAgICAgICAgICAgICAgICAgLmJsdXIoZGVhY3RpdmF0ZUZpZWxkKTsKICAgICAgICAgICAgaWYob3B0aW9ucy5zaG93Q2FsZW5kYXJJY29uKSB7CiAgICAgICAgICAgICAgICB2YXIgY2FsZW5kYXJJY29uID0gJCgiPGRpdj48L2Rpdj4iKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoImRhdGVwaWNrZXItY2FsZW5kYXItaWNvbiIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jc3MoewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndpZHRoIjogb3B0aW9ucy5pY29uV2lkdGggKyAicHgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImhlaWdodCI6IG9wdGlvbnMuaWNvbkhlaWdodCArICJweCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBjYWxlbmRhckljb24uaW5zZXJ0QWZ0ZXIoJGZpZWxkKTsKCiAgICAgICAgICAgICAgICBpZiAodGhpcy5rZXlib2FyZEFjY2Vzc2liaWxpdHkpIHsKICAgICAgICAgICAgICAgICAgICBjYWxlbmRhckljb24uYXR0cigidGFiaW5kZXgiLCAwKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjYWxlbmRhckljb24ub24odGhpcy5nZXRFdmVudCgpLCBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2ljb25DbGlja2VkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZmllbGQuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9uKCJrZXlkb3duIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudC5rZXlDb2RlID09PSAzMiB8fCBldmVudC5rZXlDb2RlID09PSAxMykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGZpZWxkLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfbmV3SW5zdDogZnVuY3Rpb24oJGYsb3B0aW9ucywgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICRmaWVsZDokZiwKICAgICAgICAgICAgICAgIGxvY2FsZTogb3B0aW9ucy5sb2NhbGUsCiAgICAgICAgICAgICAgICBwb3NpdGlvbmluZzogb3B0aW9ucy5wb3NpdGlvbmluZyB8fCAkZiwKICAgICAgICAgICAgICAgIGFjY2VzczpvcHRpb25zLmFjY2VzcywKICAgICAgICAgICAgICAgIHNlbGVjdGVkRGF0ZTpvcHRpb25zLnZhbHVlLAogICAgICAgICAgICAgICAgZWRpdFZhbHVlIDpvcHRpb25zLmVkaXRWYWx1ZSwKICAgICAgICAgICAgICAgIG1pblZhbGlkRGF0ZSA6IG9wdGlvbnMubWluVmFsaWREYXRlLAogICAgICAgICAgICAgICAgbWF4VmFsaWREYXRlIDogb3B0aW9ucy5tYXhWYWxpZERhdGUsCiAgICAgICAgICAgICAgICBleGNsTWluRGF0ZSA6ICBvcHRpb25zLmV4Y2xNaW5EYXRlLAogICAgICAgICAgICAgICAgZXhjbE1heERhdGUgOiBvcHRpb25zLmV4Y2xNYXhEYXRlCiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIFRvIGNoZWNrIHdoZXJlIHRoZSBjbGljayBoYXBwZW5lZCwgaWYgaGFwcGVuZWQgb3V0c2lkZSB0aGUgZGF0ZXBpY2tlcgogICAgICAgICAqIHRoZW4gaGlkZSB0aGUgcGlja2VyLiBUaGlzIGlzIGNoZWNrZWQgd2hldGhlciBhbnkgYW5jZXN0b3Igb2YgY2xpY2tlZCB0YXJnZXQKICAgICAgICAgKiBoYXMgYSBjbGFzcyBkYXRlUGlja2VyVGFyZ2V0LiBUaGlzIGNsYXNzIGlzIGFkZGVkIHRvIHRoZSBhdHRhY2hlZCBlbGVtZW50IGFzIHdlbGwKICAgICAgICAgKi8KICAgICAgICBfY2hlY2tXaW5kb3dDbGlja2VkIDogZnVuY3Rpb24oZXZudCkgewogICAgICAgICAgICB2YXIgc2VsZiA9IGFkb2JlRGF0ZVRpbWVQaWNrZXI7CiAgICAgICAgICAgIGlmKHNlbGYuX2N1ckluc3RhbmNlKSB7CiAgICAgICAgICAgICAgICAvLyBkYXRlcGlja2VyVGFyZ2V0IGNsYXNzIGRlcGljdHMgdGhhdCB0aGUgY29tcG9uZW50IGlzIGEgcGFydCBvZiB0aGUgRGF0ZSBGaWVsZAogICAgICAgICAgICAgICAgLy8gYW5kIG9uIGNsaWNrIG9mIHRoYXQgY2xhc3MsIHdlIHNob3VsZCBub3QgaGlkZSB0aGUgZGF0ZXBpY2tlciBvciBmaXJlIGV4aXQgZXZlbnRzLgogICAgICAgICAgICAgICAgaWYoISQoZXZudC50YXJnZXQpLmNsb3Nlc3QoIi5kYXRlUGlja2VyVGFyZ2V0IikubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgLy9ub24tdG91Y2ggZGV2aWNlcyBkbyBub3QgZGVhY3RpdmF0ZSBvbiBibHVyLiBIZW5jZSBuZWVkcyB0byBiZSBkb25lIGhlcmUKICAgICAgICAgICAgICAgICAgICBpZihzZWxmLnRvdWNoU3VwcG9ydGVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2hpZGUoKQogICAgICAgICAgICAgICAgICAgICAgICAvL2NsaWNraW5nIG91dHNpZGUgYSBmaWVsZCBkb2Vzbid0IGJsdXIgdGhlIGZpZWxkIGluIElQYWQuIERvaW5nIGl0IGJ5IHNjcmlwdAogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jdXJJbnN0YW5jZS4kZmllbGRbMF0uYmx1cigpCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2RlYWN0aXZhdGVGaWVsZCgpCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlewogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jbGlja2VkV2luZG93ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2V0IGZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtIHRvIGZhbHNlLCBpdCBoaWRlcyB0aGUgZGF0ZXBpY2tlciBzZWUgbWV0aG9kIGRlYWN0aXZhdGVGaWVsZC4KICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5mb2N1c2VkT25EYXRlcGlja2VySXRlbSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jdXJJbnN0YW5jZS4kZmllbGQuYmx1cigpCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fY2xpY2tlZFdpbmRvdyA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBoYW5kbGluZyBvZiBrZXkgc3Ryb2tlcy4gQWxsIHRoZSBrZXkgc3Ryb2tlcyBwcmV2ZW50IHRoZSBkZWZhdWx0IGJyb3dzZXIgYWN0aW9uCiAgICAgICAgICogdW5sZXNzIHNwZWNpZmllZCBvdGhlcndpc2UKICAgICAgICAgKiB0YWI6IHNldCBmb2N1cyBvbiBjYWxlbmRhciBpY29uIHdoZW4gZGF0ZWlucHV0IGZpZWxkIGlzIGFjdGl2ZSwgbmF2aWdhdGVzIHRocm91Z2ggZGF0ZSBwaWNrZXIgYnV0dG9ucyB3aGVuIGRhdGVwaWNrZXIgaXMgb3BlbiwKICAgICAgICAgKiBvdGhlcndpc2UgcGVyZm9ybSBkZWZhdWx0IGJyb3dzZXIgYWN0aW9uCiAgICAgICAgICogZXNjYXBlOiBoaWRlcyB0aGUgZGF0ZXBpY2tlcgogICAgICAgICAqIGRvd24gYXJyb3cga2V5OiBuYXZpZ2F0ZSB0aGUgcGlja2VyIGRvd253YXJkcyBieSB0aGUgbnVtYmVyIHNwZWNpZmllZCBpbiBhY3Rpb25WaWV3LnVwRG93biBvZiB0aGUgY3VycmVudCBWaWV3CiAgICAgICAgICogdXAgYXJyb3cga2V5OiBuYXZpZ2F0ZSB0aGUgcGlja2VyIHVwd2FyZHMgYnkgdGhlIG51bWJlciBzcGVjaWZpZWQgaW4gYWN0aW9uVmlldy51cERvd24gb2YgdGhlIGN1cnJlbnQgVmlldwogICAgICAgICAqIGxlZnQgYXJyb3cga2V5OiBuYXZpZ2F0ZSB0aGUgcGlja2VyIG9uZSB1bml0IG9mIHRoYXQgdmlldyBiYWNrd2FyZAogICAgICAgICAqIHJpZ2h0IGFycm93IGtleTogbmF2aWdhdGUgdGhlIHBpY2tlciBvbmUgdW5pdCBvZiB0aGF0IHZpZXcgZm9yd2FyZAogICAgICAgICAqIHNoaWZ0ICsgdXA6IHBlcmZvcm0gdGhlIGFjdGlvbiB0aGF0IGhhcHBlbnMgb24gY2xpY2tpbmcgdGhlIGNhcHRpb24gKGFzIHNwZWNpZmllZCBpbiBhY3Rpb25WaWV3LmNhcHRpb24pCiAgICAgICAgICogc2hpZnQgKyBsZWZ0OiBwZXJmb3JtIHRoZSBhY3Rpb24gdGhhdCBoYXBwZW5zIG9uIGNsaWNraW5nIHRoZSBsZWZ0IG5hdmlnYXRpb24gYnV0dG9uCiAgICAgICAgICogc2hpZnQgKyByaWdodDogcGVyZm9ybSB0aGUgYWN0aW9uIHRoYXQgaGFwcGVucyBvbiBjbGlja2luZyB0aGUgcmlnaHQgbmF2aWdhdGlvbiBidXR0b24KICAgICAgICAgKiBzcGFjZS9lbnRlcjogdHJpZ2dlcnMgdGhlIGNsaWNrIGV2ZW50IGZvciB0aGUgY3VycmVudCBmb2N1c2VkIGVsZW1lbnQgZnJvbSBkYXRlcGlja2VyLyBvcGVucyBkYXRlcGlja2VyIHdoZW4gY2FsZW5kYXIgaWNvbiBpcyBmb2N1c2VkLgogICAgICAgICAqLwogICAgICAgIF9ob3RLZXlzOiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgIHZhciBoYW5kbGVkID0gZmFsc2UsIGRhdGU7CiAgICAgICAgICAgIHN3aXRjaChldm50LmtleUNvZGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgOTogLy90YWIKICAgICAgICAgICAgICAgICAgICAvLyBDUS00MjM5MzUyIDogU2V0dGluZyBjbGlja2VkV2luZG93IHByb3BlcnR5IHRvIHRydWUgb24gdGFiYmluZyBzbyB0aGF0IGRlYWN0aXZhdGVGaWVsZCBsb2dpYyBnZXRzIGV4ZWN1dGVkCiAgICAgICAgICAgICAgICAgICAgLy8gV2hlbiBjbGlja2luZyBvbiAieCIgb24gaW5wdXQgZmllbGQgaW4gaW4gSUUgYW5kIHdoZW4gc2VsZWN0aW5nIHRoZSBjb250ZW50IGFuZCByZWxlYXNpbmcgdGhlIG1vdXNlIHNlbGVjdCBvdXRzaWRlIHRoZSBmaWVsZAogICAgICAgICAgICAgICAgICAgIC8vIHRoZSBjbGljayBldmVudCBpcyBub3QgdHJpZ2VycmVkIG9uIHRoZSBmaWVsZCBhbmQgaGVuY2UgYWN0aXZhdGVGaWVsZCBpcyBub3QgZXhlY3V0ZWQsIHNvIGNsaWNrZWRXaW5kb3cgcmVtYWlucyBhcyBmYWxzZQogICAgICAgICAgICAgICAgICAgIGFkb2JlRGF0ZVRpbWVQaWNrZXIuX2NsaWNrZWRXaW5kb3cgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGhhbmRsZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMjc6Ly9lc2NhcGUKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl92aXNpYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkb2JlRGF0ZVRpbWVQaWNrZXIuX2hpZGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLmZvY3VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMzI6IC8vc3BhY2UKICAgICAgICAgICAgICAgIGNhc2UgMTM6IC8vIGVudGVyCiAgICAgICAgICAgICAgICAgICAgaWYoJChldm50LnRhcmdldCkuaGFzQ2xhc3MoImRhdGVwaWNrZXItY2FsZW5kYXItaWNvbiIpKXsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIXRoaXMuX3Zpc2libGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Nob3coKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRmb2N1c2VkRGF0ZS5hZGRDbGFzcygiZHAtZm9jdXMiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDQwOiAvL2Rvd24gYXJyb3cga2V5CiAgICAgICAgICAgICAgICAgICAgaWYoIXRoaXMuX3Zpc2libGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2hvdygpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHRoaXMuJGZvY3VzZWREYXRlLmFkZENsYXNzKCJkcC1mb2N1cyIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihhZG9iZURhdGVUaW1lUGlja2VyLl92aXNpYmxlICYmIHRoaXMuX2tleXNFbmFibGVkKSB7CiAgICAgICAgICAgICAgICB2YXIgdiA9IHZpZXdBY3Rpb25bdGhpcy52aWV3XS5rZXksCiAgICAgICAgICAgICAgICAgICAgdXBkb3duPXZpZXdBY3Rpb25bdGhpcy52aWV3XS51cERvd247CiAgICAgICAgICAgICAgICBzd2l0Y2goZXZudC5rZXlDb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSA5OiAvLyB0YWIKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2bnQuc2hpZnRLZXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkKGV2bnQudGFyZ2V0KS5oYXNDbGFzcygiZHAtbGVmdG5hdiIpIHx8ICQoZXZudC50YXJnZXQpLmhhc0NsYXNzKCJkcC1mb2N1cyIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faGlkZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlLiRmaWVsZC5mb2N1cygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYnV0dG9uVGFiaW5kZXggPSAkKGV2bnQudGFyZ2V0KS5hdHRyKCJ0YWJpbmRleCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJ1dHRvblRhYmluZGV4ID09PSAnMCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZudC50YXJnZXQudGFnTmFtZS50b0xvY2FsZUxvd2VyQ2FzZSgpID09PSAiaW5wdXQiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2hpZGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHByZXZOYXZXaWR0aEJ0bi5mb2N1cygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJ1dHRvblRhYmluZGV4ID09PSAnNCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9oaWRlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLmZvY3VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIDMyOiAvL3NlbGVjdCBvbiBzcGFjZQogICAgICAgICAgICAgICAgICAgIGNhc2UgMTM6IC8vIHNlbGVjdCBvbiBlbnRlcgogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhvdEtleVByZXNzZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5mb2N1c2VkT25EYXRlcGlja2VySXRlbSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJChldm50LnRhcmdldCwgdGhpcy4kZHApLnRyaWdnZXJIYW5kbGVyKCJjbGljayIpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuJGZvY3VzZWREYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kZm9jdXNlZERhdGUudHJpZ2dlcigiY2xpY2siKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhvdEtleVByZXNzZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgMzc6IC8vbGVmdCBhcnJvdyBrZXkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2bnQuc2hpZnRLZXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoIi5kcC1sZWZ0bmF2IiwgdGhpcy4kZHApLnRyaWdnZXJIYW5kbGVyKCJjbGljayIpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYWRqdXN0RGF0ZSgtMSwgdiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgMzg6IC8vdXAgYXJyb3cga2V5CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldm50LnNoaWZ0S2V5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRjYXB0aW9uLnRyaWdnZXJIYW5kbGVyKCJjbGljayIpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYWRqdXN0RGF0ZSgtdXBkb3duLCB2LCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAzOTogLy9yaWdodCBhcnJvdyBrZXkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2bnQuc2hpZnRLZXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoIi5kcC1yaWdodG5hdiIsIHRoaXMuJGRwKS50cmlnZ2VySGFuZGxlcigiY2xpY2siKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkanVzdERhdGUoKzEsIHYsIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIDQwOiAvL2Rvd24gYXJyb3cga2V5CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkanVzdERhdGUodXBkb3duLCB2LCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoaGFuZGxlZCkgewogICAgICAgICAgICAgICAgZXZudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBzaG93IHRoZSBkYXRlcGlja2VyLgogICAgICAgICAqLwogICAgICAgIF9zaG93OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYodGhpcy5fY3VySW5zdGFuY2UuYWNjZXNzID09IGZhbHNlKQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB0aGlzLm9wdGlvbnMubG9jYWxlID0gdGhpcy5fY3VySW5zdGFuY2UubG9jYWxlOwogICAgICAgICAgICBpZighdGhpcy5fdmlzaWJsZSkgewogICAgICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZSgpLAogICAgICAgICAgICAgICAgICAgIHZhbCwKICAgICAgICAgICAgICAgICAgICBtYXhEYXRlSW5mbywKICAgICAgICAgICAgICAgICAgICBtaW5EYXRlSW5mbywKICAgICAgICAgICAgICAgICAgICB2YWxpZERhdGU7CiAgICAgICAgICAgICAgICAvL0J1ZyMzNjA3NzM1OgogICAgICAgICAgICAgICAgLy8gRGF0ZSBjb25zdHJ1Y3RvciBpbiBpcGFkIDUuMSBkb2Vzbid0IHN1cHBvcnQgIllZWVktTU0tREQiLCBoZW5jZSBwYXJzaW5nIHRoZSBkYXRlIG9uIG91ciBvd24KICAgICAgICAgICAgICAgIHZhbGlkRGF0ZSA9IHhmYWxpYi51dC5EYXRlSW5mby5QYXJzZUlzb1N0cmluZyh0aGlzLl9jdXJJbnN0YW5jZS5zZWxlY3RlZERhdGUpOwogICAgICAgICAgICAgICAgZGF0ZSA9ICh2YWxpZERhdGUgIT0gbnVsbCk/IHZhbGlkRGF0ZS5nZXREYXRlKCk6IG5ldyBEYXRlKCk7CiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkRGF5ID0gdGhpcy5jdXJyZW50RGF5ID0gZGF0ZS5nZXREYXRlKCk7CiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkTW9udGggPSB0aGlzLmN1cnJlbnRNb250aCA9IGRhdGUuZ2V0TW9udGgoKTsKICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRZZWFyID0gdGhpcy5jdXJyZW50WWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKTsKICAgICAgICAgICAgICAgIG1heERhdGVJbmZvID0gdGhpcy5vcHRpb25zLm1heFZhbGlkRGF0ZSA/IHhmYWxpYi51dC5EYXRlSW5mby5QYXJzZUlzb1N0cmluZyh0aGlzLl9jdXJJbnN0YW5jZS5tYXhWYWxpZERhdGUpIDogbnVsbDsKICAgICAgICAgICAgICAgIHRoaXMubWF4VmFsaWREYXRlID0gbWF4RGF0ZUluZm8gPyBtYXhEYXRlSW5mby5nZXREYXRlKCkgOiBudWxsOwogICAgICAgICAgICAgICAgbWluRGF0ZUluZm8gPSB0aGlzLm9wdGlvbnMubWluVmFsaWREYXRlID8geGZhbGliLnV0LkRhdGVJbmZvLlBhcnNlSXNvU3RyaW5nKHRoaXMuX2N1ckluc3RhbmNlLm1pblZhbGlkRGF0ZSkgOiBudWxsOwogICAgICAgICAgICAgICAgdGhpcy5taW5WYWxpZERhdGUgPSBtaW5EYXRlSW5mbyA/IG1pbkRhdGVJbmZvLmdldERhdGUoKSA6IG51bGw7CiAgICAgICAgICAgICAgICB0aGlzLmV4Y2xNYXhEYXRlID0gdGhpcy5fY3VySW5zdGFuY2UuZXhjbE1heERhdGU7CiAgICAgICAgICAgICAgICB0aGlzLmV4Y2xNaW5EYXRlID0gdGhpcy5fY3VySW5zdGFuY2UuZXhjbE1pbkRhdGU7CiAgICAgICAgICAgICAgICAkKCcuZHAtY2xlYXIgYScsdGhpcy4kZHApLnRleHQodGhpcy5vcHRpb25zLmxvY2FsZS5jbGVhclRleHQpOwogICAgICAgICAgICAgICAgdGhpcy5fbGF5b3V0KCdNb250aCcpOwogICAgICAgICAgICAgICAgdGhpcy5fcG9zaXRpb24oKTsKICAgICAgICAgICAgICAgIHRoaXMuJGRwLnNob3coKTsKICAgICAgICAgICAgICAgIC8vIGlmIGxpIGVsZW1lbnQgb2YgZGF0ZXBpY2tlciBpcyBmb2N1c2VkIHRoZW4gc2V0IGZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtIHRvIHRydWUsIGl0IG1hbmFnZXMgdGhlIHZpc2liaWxpdHkgb2YgdGhlIGRhdGVwaWNrZXIuCiAgICAgICAgICAgICAgICB0aGlzLmZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtID0gZmFsc2U7CiAgICAgICAgICAgICAgICB0aGlzLl92aXNpYmxlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbikgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlLiRmaWVsZC5hdHRyKCdyZWFkb25seScsIHRydWUpOyAgICAvLyB3aGVuIHRoZSBkYXRlcGlja2VyIGlzIGFjdGl2ZSwgZGVhY3RpdmF0ZSB0aGUgZmllbGQKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gICBEaXNhYmxpbmcgdGhlIGZvY3VzIG9uIGlwYWQgIGR1ZSB0byBhIGJ1ZyB3aGVyZSB2YWx1ZSBvZgogICAgICAgICAgICAvLyBkYXRlIHBpY2tlciBpcyBub3QgYmVpbmcgc2V0CiAgICAgICAgICAgIC8vIFJlbW92aW5nIHRoaXMgY29kZSB3aWxsIG9ubHkgaGFtcGVyIG9uZSB1c2UgY2FzZQogICAgICAgICAgICAvLyB3aGVyZSBvbiBpcGFkIGlmIHlvdSBjbGljayBvbiB0aGUgY2FsYW5kZXIgdGhlbgogICAgICAgICAgICAvLyB0aGUgZmllbGQgYmVjb21lcyByZWFkIG9ubHkgc28KICAgICAgICAgICAgLy8gdGhlcmUgaXMgbm8gaW5kaWNhdGlvbiB3aGVyZSB0aGUgY3VycmVudCBmb2N1cyBpcwogICAgICAgICAgICAvLyBBbmQgIGlmIHlvdSByZW1vdmUgdGhpcyBmb3VjcyBjb2RlIGFsbCB0b2dldGhlcgogICAgICAgICAgICAvLyB0aGVuIHdoYXQgaGFwcGVucyBpcyB0aGF0IG9uIGRlc2t0b3AgTUYgaW4gaWZyYW1lIHRoZSBleGl0IGV2ZW50CiAgICAgICAgICAgIC8vIGlzIG5vdCBnZXR0aW5nIGNhbGxlZCBoZW5jZSBjYWxhbmRlciBnZXR0aW5nIHJlbWFpbmVkIG9wZW4gZXZlbgogICAgICAgICAgICAvLyB3aGVuIHlvdSBjbGljayBzb21ld2hlcmUgb24gd2luZG93IG9yIGZvY3VzIGludG8gc29tZSBvdGhlciBmaWVsZAogICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNob3dDYWxlbmRhckljb24gICYmICF0aGlzLnRvdWNoU3VwcG9ydGVkKSB7CiAgICAgICAgICAgICAgICBpZih0aGlzLiRmb2N1c2VkRGF0ZS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZm9jdXNlZERhdGUuZm9jdXMoKTsgIC8vIHNoaWZ0IGZvY3VzIG9uIGN1cnJlbnQgZGF0ZSBvciBzZWxlY3RlZCBkYXRlLgogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQuZm9jdXMoKTsgLy8gZmllbGQgbG9zZXMgZm9jdXMgYWZ0ZXIgYmVpbmcgbWFya2VkIHJlYWRvbmx5LCBjYXVzaW5nIGJsdXIgZXZlbnQgbm90IHRvIGJlIGZpcmVkIGxhdGVyCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIHBvc2l0aW9uIHRoZSBkYXRlcGlja2VyIGFyb3VuZCB0aGUgcG9zaXRpb25pbmcgZWxlbWVudAogICAgICAgICAqIHByb3ZpZGVkIGluIHRoZSBvcHRpb25zCiAgICAgICAgICovCiAgICAgICAgX3Bvc2l0aW9uOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyICRlbGVtID0gdGhpcy5fY3VySW5zdGFuY2UucG9zaXRpb25pbmcsCiAgICAgICAgICAgICAgICB3aW5kb3dTY3JvbGxYID0gd2luZG93LnNjcm9sbFgvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IsCiAgICAgICAgICAgICAgICB3aW5kb3dTY3JvbGxZID0gd2luZG93LnNjcm9sbFkvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IsCiAgICAgICAgICAgICAgICB3aW5kb3dJbm5lckhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodC8geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmZvcm1TY2FsZUZhY3RvciwKICAgICAgICAgICAgICAgIHdpbmRvd0lubmVyV2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aC8geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmZvcm1TY2FsZUZhY3RvciwKICAgICAgICAgICAgICAgIGhlaWdodCA9ICRlbGVtLm91dGVySGVpZ2h0KHRydWUpLAogICAgICAgICAgICAgICAgd2lkdGggID0gJGVsZW0ub3V0ZXJXaWR0aCh0cnVlKSwKICAgICAgICAgICAgICAgIHRvcCA9ICRlbGVtLm9mZnNldCgpLnRvcCAvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IgKyBoZWlnaHQsCiAgICAgICAgICAgICAgICBsZWZ0ID0gJGVsZW0ub2Zmc2V0KCkubGVmdCAvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IsCiAgICAgICAgICAgICAgICBzdHlsZXMgPSB7InRvcCI6ICh0b3ArInB4IiksICJsZWZ0IjogKGxlZnQrInB4Iil9LAogICAgICAgICAgICAgICAgZGlmZkJvdHRvbSA9IHRvcCArIHRoaXMuJGRwLm91dGVySGVpZ2h0KHRydWUpIC0gd2luZG93SW5uZXJIZWlnaHQgLSB3aW5kb3dTY3JvbGxZLAogICAgICAgICAgICAgICAgbmV3TGVmdCwKICAgICAgICAgICAgICAgIG5ld1RvcDsKICAgICAgICAgICAgaWYoZGlmZkJvdHRvbSA+IDApIHsKICAgICAgICAgICAgICAgIC8vY2FuJ3QgYXBwZWFyIGF0IHRoZSBib3R0b20KICAgICAgICAgICAgICAgIC8vY2hlY2sgdG9wCiAgICAgICAgICAgICAgICBuZXdUb3AgPSB0b3AgLSBoZWlnaHQgLSB0aGlzLiRkcC5vdXRlckhlaWdodCh0cnVlKSAtIEJVRkZFUl9TUEM7CiAgICAgICAgICAgICAgICBpZihuZXdUb3AgPCB3aW5kb3dTY3JvbGxZKSB7CiAgICAgICAgICAgICAgICAgICAgLy9jYW4ndCBhcHBlYXIgYXQgdGhlIHRvcCBhcyB3ZWxsIC4uLiB0aGUgZGF0ZVBpY2tlciBwb3AgdXAgb3ZlcmxhcHMgdGhlIGRhdGUgZmllbGQKICAgICAgICAgICAgICAgICAgICBuZXdUb3AgPSB0b3AgLSBkaWZmQm90dG9tOwogICAgICAgICAgICAgICAgICAgIC8vIEZpeCBmb3IgQlVHICMzNjI2OTc0CiAgICAgICAgICAgICAgICAgICAgaWYoeGZhVXRpbC5pc1dlYmtpdCgpICYmICF0aGlzLm9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbikgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQudHJpZ2dlcigib25vdmVybGFwLmRhdGV0aW1lcGlja2VyIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc3R5bGVzLnRvcCA9IG5ld1RvcCArICJweCI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYobGVmdCArIHRoaXMuJGRwLm91dGVyV2lkdGgodHJ1ZSkgPiB3aW5kb3dTY3JvbGxYICsgd2luZG93SW5uZXJXaWR0aCApIHsKICAgICAgICAgICAgICAgIC8vYWxpZ24gd2l0aCB0aGUgcmlnaHQgZWRnZQogICAgICAgICAgICAgICAgbmV3TGVmdCA9IHdpbmRvd1Njcm9sbFggKyB3aW5kb3dJbm5lcldpZHRoIC0gdGhpcy4kZHAub3V0ZXJXaWR0aCh0cnVlKSAtIEJVRkZFUl9TUEM7CiAgICAgICAgICAgICAgICBzdHlsZXMubGVmdCA9IG5ld0xlZnQgKyAicHgiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHhmYVV0aWwuJGNzcyh0aGlzLiRkcC5nZXQoMCksIHN0eWxlcyk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogbGF5b3V0IHRoZSBuZXh0Vmlldy4gaWYgbmV4dFZpZXcgaXMgbnVsbCByZXR1cm4KICAgICAgICAgKgogICAgICAgICAqLwogICAgICAgIF9sYXlvdXQ6IGZ1bmN0aW9uKG5leHRWaWV3KSB7CiAgICAgICAgICAgIGlmKG5leHRWaWV3ID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2hpZGUoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMudmlldykKICAgICAgICAgICAgICAgICAgICB0aGlzWyckJyt0aGlzLnZpZXcudG9Mb3dlckNhc2UoKV0uaGlkZSgpOwogICAgICAgICAgICAgICAgdGhpcy52aWV3ID0gbmV4dFZpZXc7CiAgICAgICAgICAgICAgICB0aGlzLiRjYXB0aW9uLnRvZ2dsZUNsYXNzKCJkaXNhYmxlZCIsIXZpZXdBY3Rpb25bdGhpcy52aWV3XS5jYXB0aW9uKTsKICAgICAgICAgICAgICAgIHRoaXNbJyQnK3RoaXMudmlldy50b0xvd2VyQ2FzZSgpXS5zaG93KCk7CiAgICAgICAgICAgICAgICB0aGlzWyJzaG93Iit0aGlzLnZpZXddKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBzaG93IHRoZSBtb250aCB2aWV3CiAgICAgICAgICovCiAgICAgICAgc2hvd01vbnRoOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgY3VyRGF0ZSA9IG5ldyBEYXRlKHRoaXMuY3VycmVudFllYXIsIHRoaXMuY3VycmVudE1vbnRoKSwKICAgICAgICAgICAgICAgIG1heERheSA9ICAgdGhpcy5fbWF4RGF0ZSh0aGlzLmN1cnJlbnRNb250aCksCiAgICAgICAgICAgICAgICBwcmV2TWF4RGF5ID0gdGhpcy5fbWF4RGF0ZSgodGhpcy5jdXJyZW50TW9udGggKyAxMSklMTIpLAogICAgICAgICAgICAgICAgZGF5MSA9IG5ldyBEYXRlKHRoaXMuY3VycmVudFllYXIsdGhpcy5jdXJyZW50TW9udGgsMSkuZ2V0RGF5KCksCiAgICAgICAgICAgICAgICBkYXRhLGRpc3BsYXk7CgogICAgICAgICAgICB0aGlzLnRhYnVsYXRlVmlldygKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXB0aW9uOiB0aGlzLm9wdGlvbnMubG9jYWxlLm1vbnRoc1t0aGlzLmN1cnJlbnRNb250aF0gKyAiLCAiKyB0aGlzLl9jb252ZXJ0TnVtYmVyVG9Mb2NhbGUodGhpcy5jdXJyZW50WWVhciksCiAgICAgICAgICAgICAgICAgICAgaGVhZGVyOnRoaXMub3B0aW9ucy5sb2NhbGUuZGF5cywKICAgICAgICAgICAgICAgICAgICBudW1Sb3dzOjcsCiAgICAgICAgICAgICAgICAgICAgbnVtQ29sdW1uczo3LAogICAgICAgICAgICAgICAgICAgIGVsZW1lbnRBdDogZnVuY3Rpb24ocm93LGNvbCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGF5ID0gKHJvdy0xKSo3ICsgY29sIC0gZGF5MSArIDE7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtb250aFZhbCA9IHNlbGYuY3VycmVudE1vbnRoICsgMTsKICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheSA9IHNlbGYuX2NvbnZlcnROdW1iZXJUb0xvY2FsZShkYXkpOwogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF5OwogICAgICAgICAgICAgICAgICAgICAgICBpZihkYXkgPCAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5ID0gc2VsZi5fY29udmVydE51bWJlclRvTG9jYWxlKHByZXZNYXhEYXkgKyBkYXkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IC0xOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9udGhWYWwgPSBzZWxmLmN1cnJlbnRNb250aDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKGRheSA+IG1heERheSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheSA9IHNlbGYuX2NvbnZlcnROdW1iZXJUb0xvY2FsZShkYXktbWF4RGF5KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSAtMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vbnRoVmFsID0gc2VsZi5jdXJyZW50TW9udGggKyAyOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyRGF0ZS5zZXREYXRlKGRheSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29tcGFyZUZuID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLl9jb21wYXJlVmFsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgdGhlIGN1cnJlbnRkYXRlIGlzIHZhbGlkIGJhc2VkIG9uIG1heCBhbmQgbWluIHZhbGlkIGRhdGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNvbXBhcmVGbihjdXJEYXRlLCBzZWxmLm1heFZhbGlkRGF0ZSwgc2VsZi5leGNsTWF4RGF0ZSkgfHwgY29tcGFyZUZuKHNlbGYubWluVmFsaWREYXRlLCBjdXJEYXRlLCBzZWxmLmV4Y2xNaW5EYXRlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSAtMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA6IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5IDogZGlzcGxheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWFMYWJlbCA6IHNlbGYub3B0aW9ucy5lZGl0VmFsdWUoc2VsZi5jdXJyZW50WWVhcisiLSIrc2VsZi5fcGFkMihtb250aFZhbCkrIi0iK3NlbGYuX3BhZDIoZGlzcGxheSkpCiAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgfSwKCgoKICAgICAgICAvKgogICAgICAgICAqIHNob3cgdGhlIHllYXIgdmlldwogICAgICAgICAqLwogICAgICAgIHNob3dZZWFyOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgbWluRGF0ZSA9IHRoaXMubWluVmFsaWREYXRlID8gbmV3IERhdGUodGhpcy5taW5WYWxpZERhdGUuZ2V0RnVsbFllYXIoKSwgdGhpcy5taW5WYWxpZERhdGUuZ2V0TW9udGgoKSkgOiBudWxsLAogICAgICAgICAgICAgICAgbWF4RGF0ZSA9IHRoaXMubWF4VmFsaWREYXRlID8gbmV3IERhdGUodGhpcy5tYXhWYWxpZERhdGUuZ2V0RnVsbFllYXIoKSwgdGhpcy5tYXhWYWxpZERhdGUuZ2V0TW9udGgoKSkgOiBudWxsLAogICAgICAgICAgICAgICAgY3VyRGF0ZSA9IG5ldyBEYXRlKHRoaXMuY3VycmVudFllYXIsIDApLCAvL2Nhbid0IG9taXQgbW9udGgsIGlmIG9ubHkgb25lIHBhcmFtIHByZXNlbnQgaXQgaXMgdHJlYXRlZCBhcyBtaWxsaXNlY29uZAogICAgICAgICAgICAgICAgZGF0YSwKICAgICAgICAgICAgICAgIG1vbnRoOwogICAgICAgICAgICB0aGlzLnRhYnVsYXRlVmlldygKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXB0aW9uIDogdGhpcy5fY29udmVydE51bWJlclRvTG9jYWxlKHRoaXMuY3VycmVudFllYXIpLAogICAgICAgICAgICAgICAgICAgIG51bVJvd3MgOiA0LAogICAgICAgICAgICAgICAgICAgIG51bUNvbHVtbnMgOiAzLAogICAgICAgICAgICAgICAgICAgIGVsZW1lbnRBdCA6IGZ1bmN0aW9uKHJvdyxjb2wpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IG1vbnRoID0gIHJvdyozICsgY29sOwogICAgICAgICAgICAgICAgICAgICAgICBjdXJEYXRlLnNldE1vbnRoKG1vbnRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChtaW5EYXRlICYmIGN1ckRhdGUgPCBtaW5EYXRlKSB8fCAobWF4RGF0ZSAmJiBjdXJEYXRlID4gbWF4RGF0ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSAtMTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA6IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5IDogc2VsZi5vcHRpb25zLmxvY2FsZS5tb250aHNbbW9udGhdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYUxhYmVsIDogc2VsZi5vcHRpb25zLmxvY2FsZS5tb250aHNbbW9udGhdICsgIiAiICtzZWxmLmN1cnJlbnRZZWFyCiAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBzaG93IHRoZSB5ZWFyIHNldCB2aWV3CiAgICAgICAgICovCiAgICAgICAgc2hvd1llYXJzZXQ6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgeWVhciwKICAgICAgICAgICAgICAgIG1pbkRhdGUgPSB0aGlzLm1pblZhbGlkRGF0ZSA/IG5ldyBEYXRlKHRoaXMubWluVmFsaWREYXRlLmdldEZ1bGxZZWFyKCksIDApIDogbnVsbCAsCiAgICAgICAgICAgICAgICBtYXhEYXRlID0gdGhpcy5tYXhWYWxpZERhdGUgPyBuZXcgRGF0ZSh0aGlzLm1heFZhbGlkRGF0ZS5nZXRGdWxsWWVhcigpICsgMSwgMCkgOiBudWxsLAogICAgICAgICAgICAgICAgY3VyRGF0ZSA9IG5ldyBEYXRlKCksCiAgICAgICAgICAgICAgICBkYXRhLAogICAgICAgICAgICAgICAgc2VsZiA9IHRoaXM7CiAgICAgICAgICAgIHRoaXMudGFidWxhdGVWaWV3KAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhcHRpb246IHRoaXMuX2NvbnZlcnROdW1iZXJUb0xvY2FsZSh0aGlzLmN1cnJlbnRZZWFyIC0gdGhpcy5vcHRpb25zLnllYXJzUGVyVmlldy8yKSArIi0iK3RoaXMuX2NvbnZlcnROdW1iZXJUb0xvY2FsZSh0aGlzLmN1cnJlbnRZZWFyIC0gdGhpcy5vcHRpb25zLnllYXJzUGVyVmlldy8yICsgdGhpcy5vcHRpb25zLnllYXJzUGVyVmlldyAtIDEpLAogICAgICAgICAgICAgICAgICAgIG51bVJvd3M6NCwKICAgICAgICAgICAgICAgICAgICBudW1Db2x1bW5zOjQsCiAgICAgICAgICAgICAgICAgICAgZWxlbWVudEF0OiBmdW5jdGlvbihyb3csY29sKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSB5ZWFyID0gIHNlbGYuY3VycmVudFllYXIgLSA4ICsgKHJvdyo0ICsgY29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3VyRGF0ZS5zZXRGdWxsWWVhcih5ZWFyKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChtaW5EYXRlICYmIGN1ckRhdGUgPCBtaW5EYXRlKSB8fCAobWF4RGF0ZSAmJiBjdXJEYXRlID4gbWF4RGF0ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSAtMTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgImRhdGEiIDogZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkaXNwbGF5IiA6IHNlbGYuX2NvbnZlcnROdW1iZXJUb0xvY2FsZSh5ZWFyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWFMYWJlbCA6IHllYXIKICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICB9LAoKICAgICAgICBpbnNlcnRSb3cgOiAgZnVuY3Rpb24ocm93TnVtLHJvd0FycmF5LGlzSGVhZGVyLGhlaWdodCkgewogICAgICAgICAgICB2YXIgJHZpZXcgPSB0aGlzWyIkIit0aGlzLnZpZXcudG9Mb3dlckNhc2UoKV0sCiAgICAgICAgICAgICAgICB3aWR0aCA9ICh0aGlzLmFjdHVhbFdpZHRoKS9yb3dBcnJheS5sZW5ndGgsCiAgICAgICAgICAgICAgICAkcm93ID0gJCgidWwiLCR2aWV3KS5lcShyb3dOdW0pLAogICAgICAgICAgICAgICAgaXRlbXMsJGxpLGVsZW1lbnQsJHRtcCwKICAgICAgICAgICAgICAgIHNlbGY9IHRoaXM7CiAgICAgICAgICAgIGlmKCEkcm93Lmxlbmd0aCkKICAgICAgICAgICAgICAgICRyb3cgPSAkKCI8dWw+PC91bD4iKS5hdHRyKCJhcmlhLWxhYmVsIiwgIiIpLmF0dHIoInJvbGUiLCAicm93IikuYXBwZW5kVG8oJHZpZXcpLnRvZ2dsZUNsYXNzKGhlYWRlckNsYXNzLGlzSGVhZGVyKTsKICAgICAgICAgICAgJHJvdy5oZWlnaHQoaGVpZ2h0KTsKICAgICAgICAgICAgaXRlbXMgPSAkKCJsaSIsJHJvdykubGVuZ3RoOwogICAgICAgICAgICB3aGlsZShpdGVtcysrIDwgcm93QXJyYXkubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAkdG1wID0gJCgiPGxpPjwvbGk+IikuYXR0cigicm9sZSIsICJjZWxsIikuYXBwZW5kVG8oJHJvdyk7CiAgICAgICAgICAgICAgICBpZighaXNIZWFkZXIpCiAgICAgICAgICAgICAgICAgICAgJHRtcC5vbigiY2xpY2siLCAkLnByb3h5KHRoaXMuX3NlbGVjdERhdGUsdGhpcykpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBfLmVhY2gocm93QXJyYXksIGZ1bmN0aW9uKGVsLGluZGV4KSB7CiAgICAgICAgICAgICAgICAkbGkgPSAkKCJsaSIsJHJvdykuZXEoaW5kZXgpOwogICAgICAgICAgICAgICAgaWYoaXNIZWFkZXIpCiAgICAgICAgICAgICAgICAgICAgJGxpLnRleHQocm93QXJyYXlbaW5kZXhdKTsKICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSByb3dBcnJheVtpbmRleF07CiAgICAgICAgICAgICAgICAgICAgeGZhVXRpbC4kZGF0YSgkbGkuZ2V0KDApLCAidmFsdWUiLCBlbGVtZW50LmRhdGEpOwogICAgICAgICAgICAgICAgICAgIGlmKHNlbGYuX2NoZWNrRGF0ZUlzRm9jdXNzZWQoZWxlbWVudC5kYXRhKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZihzZWxmLiRmb2N1c2VkRGF0ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi4kZm9jdXNlZERhdGUucmVtb3ZlQ2xhc3MoImRwLWZvY3VzIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLiRmb2N1c2VkRGF0ZS5hdHRyKCJ0YWJpbmRleCIsICItMSIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuJGZvY3VzZWREYXRlID0gJGxpOwogICAgICAgICAgICAgICAgICAgICAgICBpZihzZWxmLl9rZXlzRW5hYmxlZCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuJGZvY3VzZWREYXRlLmFkZENsYXNzKCJkcC1mb2N1cyIpCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRsaS50b2dnbGVDbGFzcygiZHAtc2VsZWN0ZWQiLHNlbGYuX2NoZWNrRGF0ZUlzU2VsZWN0ZWQoZWxlbWVudC5kYXRhKSkKICAgICAgICAgICAgICAgICAgICAgICAgLnRvZ2dsZUNsYXNzKCJkaXNhYmxlZCIsIGVsZW1lbnQuZGF0YSA9PSAtMSkudGV4dChlbGVtZW50LmRpc3BsYXkpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJ0aXRsZSIsIGVsZW1lbnQuYXJpYUxhYmVsKQogICAgICAgICAgICAgICAgICAgICAgICAuYXR0cigiYXJpYS1sYWJlbCIsIGVsZW1lbnQuYXJpYUxhYmVsKQogICAgICAgICAgICAgICAgICAgICAgICAuYXR0cigidGFiaW5kZXgiLCAtMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbGkuY3NzKCB7ImhlaWdodCI6aGVpZ2h0KyJweCIsIndpZHRoIjp3aWR0aCsicHgiLCJsaW5lLWhlaWdodCI6aGVpZ2h0KyJweCJ9KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHJldHVybiAkcm93OwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogY3JlYXRlcyBhIHRhYnVsYXIgdmlldyBiYXNlZCBvbiB0aGUgb3B0aW9ucyBwcm92aWRlZC4gVGhlIG9wdGlvbnMgdGhhdCBjYW4gYmUgcGFzc2VkIGFyZQogICAgICAgICAqIG51bVJvd3M6IG51bWJlciBvZiByb3dzIHRoYXQgbmVlZHMgcmVuZGVyaW5nCiAgICAgICAgICogbnVtQ29sczogbnVtYmVyIG9mIGNvbHVtbnMgdGhhdCBuZWVkcyByZW5kZXJpbmcKICAgICAgICAgKiBjYXB0aW9uOiB0ZXh0IGZvciB0aGUgZGF0ZXBpY2tlcnMgY2FwdGlvbiBlbGVtZW50CiAgICAgICAgICogaGVhZGVyOiBhbiBhcnJheSBvZiBlbGVtZW50cyB0aGF0IGlkZW50aWZpZXMgdGhlIGhlYWRlciByb3cKICAgICAgICAgKiBlbGVtZW50QXQ6IGEgZnVuY3Rpb24ocm93LCBjb2x1bW4pIHRoYXQgcmV0dXJucyBhbiBvYmplY3QgKGRhdGE6IDxkYXRhPiwgZGlzcGxheTogPGRpc3BsYXk+KSB3aGVyZQogICAgICAgICAqICAgICAgICAgICAgPGRhdGE+IGlzIHRoZSB2YWx1ZSB0byBzZXQgZm9yIHRoYXQgdmlldyB3aGVuIHRoZSBlbGVtZW50IGF0IChyb3csY29sdW1uKSBpcyBjbGlja2VkIGFuZAogICAgICAgICAqICAgICAgICAgICAgPGRpc3BsYXk+IGlzIHRoZSB2YWx1ZSB0aGF0IHdpbGwgYmUgdmlzaWJsZSB0byB0aGUgdXNlcgogICAgICAgICAqLwogICAgICAgIHRhYnVsYXRlVmlldyA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgdmFyIHIgPSAwLHJvd3MgPSAwLAogICAgICAgICAgICAgICAgcm93ID0gW10sCiAgICAgICAgICAgICAgICBodCA9ICB0aGlzLm9wdGlvbnMudmlld0hlaWdodC9vcHRpb25zLm51bVJvd3MsCiAgICAgICAgICAgICAgICBjOwogICAgICAgICAgICB0aGlzLiRjYXB0aW9uLnRleHQob3B0aW9ucy5jYXB0aW9uKTsKICAgICAgICAgICAgaWYob3B0aW9ucy5oZWFkZXIpIHsKICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0Um93KHIrKyxvcHRpb25zLmhlYWRlcix0cnVlLGh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICB3aGlsZShyIDwgb3B0aW9ucy5udW1Sb3dzKSB7CiAgICAgICAgICAgICAgICBjID0gMDsKICAgICAgICAgICAgICAgIHdoaWxlKGMgPCBvcHRpb25zLm51bUNvbHVtbnMpIHsKICAgICAgICAgICAgICAgICAgICByb3dbY10gPSBvcHRpb25zLmVsZW1lbnRBdChyLGMpOwogICAgICAgICAgICAgICAgICAgIGMrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0Um93KHIrKyxyb3csZmFsc2UsaHQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2FjdGl2YXRlRmllbGQgOiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlID0geGZhVXRpbC4kZGF0YShldm50LnRhcmdldCwiZGF0ZXRpbWVwaWNrZXIiKTsKICAgICAgICAgICAgdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLnRyaWdnZXIoIm9uZm9jdXMxLmRhdGV0aW1lcGlja2VyIikuYWRkQ2xhc3MoImRhdGVQaWNrZXJUYXJnZXQiKTsKICAgICAgICAgICAgLy8gSXNzdWUgTEMtNzA0OToKICAgICAgICAgICAgLy8gZGF0ZXBpY2tlclRhcmdldCBzaG91bGQgYmUgYWRkZWQgd2hlbiBhY3RpdmF0ZSB0aGUgZmllbGQgYW5kIHNob3VsZCBiZSByZW1vdmVkCiAgICAgICAgICAgIC8vIGFmdGVyIHRoZSBmaWVsZHMgZ2V0cyBkZWFjdGl2YXRlZC4KICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaG93Q2FsZW5kYXJJY29uKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQucGFyZW50KCkuYWRkQ2xhc3MoImRhdGVQaWNrZXJUYXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL2VuYWJsZSBob3Qga2V5cyBvbmx5IGZvciBub24gdG91Y2ggZGV2aWNlcwogICAgICAgICAgICBpZighdGhpcy50b3VjaFN1cHBvcnRlZCAmJiAhdGhpcy5fa2V5c0VuYWJsZWQpIHsKICAgICAgICAgICAgICAgICQod2luZG93KS5vbigia2V5ZG93bi5kYXRldGltZXBpY2tlciIsICQucHJveHkodGhpcy5faG90S2V5cyx0aGlzKSk7CiAgICAgICAgICAgICAgICB0aGlzLl9rZXlzRW5hYmxlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZGVhY3RpdmF0ZUZpZWxkOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYodGhpcy5fY3VySW5zdGFuY2UpIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMuX2tleXNFbmFibGVkKSB7CiAgICAgICAgICAgICAgICAgICAgJCh3aW5kb3cpLm9mZigia2V5ZG93bi5kYXRldGltZXBpY2tlciIpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5c0VuYWJsZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vQnVnIzM2MDc0OTk6IG9uIGRlYWN0aXZhdGUgY2hlY2sgdGhlIHZhbHVlIGluIHRoZSBpbnB1dCBib3gsIGlmIHRoYXQgaXMKICAgICAgICAgICAgICAgIC8vIGRpZmZlcmVudCB0aGFuIHRoZSBzZWxlY3RlZCBEYXRlLCBjaGFuZ2UgdGhlIHNlbGVjdGVkRGF0ZQogICAgICAgICAgICAgICAgLy9pZiAodGhpcy5fY3VySW5zdGFuY2Uuc2VsZWN0ZWREYXRlICE9IHRoaXMuX2N1ckluc3RhbmNlLiRmaWVsZC52YWwoKSkgewogICAgICAgICAgICAgICAgLy8gICAgdGhpcy5fY3VySW5zdGFuY2Uuc2VsZWN0ZWREYXRlID0gdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLnZhbCgpOwogICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQudHJpZ2dlcigib25mb2N1c291dC5kYXRldGltZXBpY2tlciIpLnJlbW92ZUNsYXNzKCJkYXRlUGlja2VyVGFyZ2V0Iik7CiAgICAgICAgICAgICAgICAvLyBJc3N1ZSBMQy03MDQ5OgogICAgICAgICAgICAgICAgLy8gZGF0ZXBpY2tlclRhcmdldCBzaG91bGQgYmUgYWRkZWQgd2hlbiBhY3RpdmF0ZSB0aGUgZmllbGQgYW5kIHNob3VsZCBiZSByZW1vdmVkCiAgICAgICAgICAgICAgICAvLyBhZnRlciB0aGUgZmllbGRzIGdldHMgZGVhY3RpdmF0ZWQuIE90aGVyd2lzZSBjbGlja2luZyBvbiBhbnkgb3RoZXIgZGF0ZWZpZWxkCiAgICAgICAgICAgICAgICAvLyB3aWxsIG5vdCBoaWRlIHRoZSBleGlzdGluZyBkYXRlcGlja2VyCiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNob3dDYWxlbmRhckljb24pIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQucGFyZW50KCkucmVtb3ZlQ2xhc3MoImRhdGVQaWNrZXJUYXJnZXQiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9oaWRlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYodGhpcy5fdmlzaWJsZSkgewogICAgICAgICAgICAgICAgdGhpcy4kZHAuaGlkZSgpOwogICAgICAgICAgICAgICAgdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLnRyaWdnZXIoIm9uY2xvc2UuZGF0ZXRpbWVwaWNrZXIiKTsKICAgICAgICAgICAgICAgIHRoaXMuX3Zpc2libGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbikgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlLiRmaWVsZC5hdHRyKCdyZWFkb25seScsIGZhbHNlKTsgICAgLy8gd2hlbiB0aGUgZGF0ZXBpY2tlciBpcyBkZWFjdGl2YXRlZCwgYWN0aXZhdGUgdGhlIGZpZWxkCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfYWRqdXN0RGF0ZTogZnVuY3Rpb24oc3RlcCwgdmlldywgZm9jdXMpIHsKICAgICAgICAgICAgdmFyIG1heERhdGUscHJldk1heERhdGU7CiAgICAgICAgICAgIHZhciBfZm9jdXMgPSBmb2N1cyB8fCBmYWxzZTsKICAgICAgICAgICAgc3dpdGNoKHZpZXcudG9Mb3dlckNhc2UoKSkgewogICAgICAgICAgICAgICAgY2FzZSAiZGF5IjoKICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnREYXkgKz0gc3RlcDsKICAgICAgICAgICAgICAgICAgICBtYXhEYXRlID0gdGhpcy5fbWF4RGF0ZSh0aGlzLmN1cnJlbnRNb250aCkKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmN1cnJlbnREYXkgPCAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHByZXZNYXhEYXRlID0gIHRoaXMuX21heERhdGUoKHRoaXMuY3VycmVudE1vbnRoIC0gMSArIDEyKSUxMik7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudERheSA9IHByZXZNYXhEYXRlICsgdGhpcy5jdXJyZW50RGF5OwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYWRqdXN0RGF0ZSgtMSwgIm1vbnRoIiwgX2ZvY3VzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5jdXJyZW50RGF5ID4gbWF4RGF0ZSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnREYXkgLT0gbWF4RGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2FkanVzdERhdGUoKzEsICJtb250aCIsIF9mb2N1cyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAibW9udGgiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudE1vbnRoICs9IHN0ZXA7CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5jdXJyZW50TW9udGggPiAxMSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRZZWFyKys7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudE1vbnRoID0gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5jdXJyZW50TW9udGggPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFllYXItLTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50TW9udGggPSAxMTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJ5ZWFyIjoKICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRZZWFyICs9IHN0ZXA7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJ5ZWFyc2V0IjoKICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRZZWFyICs9IHN0ZXAqdGhpcy5vcHRpb25zLnllYXJzUGVyVmlldzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl9sYXlvdXQodGhpcy52aWV3KTsKICAgICAgICAgICAgaWYgKF9mb2N1cykgewogICAgICAgICAgICAgICAgdGhpcy5mb2N1c2VkT25EYXRlcGlja2VySXRlbSA9IHRydWU7CiAgICAgICAgICAgICAgICB0aGlzLiRmb2N1c2VkRGF0ZS5hdHRyKCJ0YWJpbmRleCIsIDApWzBdLmZvY3VzKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfY2hlY2tEYXRlSXNTZWxlY3RlZDogZnVuY3Rpb24oZGF0YSkgewogICAgICAgICAgICBzd2l0Y2godGhpcy52aWV3LnRvTG93ZXJDYXNlKCkpIHsKICAgICAgICAgICAgICAgIGNhc2UgIm1vbnRoIjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50WWVhciA9PSB0aGlzLnNlbGVjdGVkWWVhciAmJiB0aGlzLmN1cnJlbnRNb250aCA9PSB0aGlzLnNlbGVjdGVkTW9udGggJiYgZGF0YSA9PSB0aGlzLnNlbGVjdGVkRGF5OwogICAgICAgICAgICAgICAgY2FzZSAieWVhciI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFllYXIgPT0gdGhpcy5zZWxlY3RlZFllYXIgJiYgdGhpcy5zZWxlY3RlZE1vbnRoID09IGRhdGE7CiAgICAgICAgICAgICAgICBjYXNlICJ5ZWFyc2V0IjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3RlZFllYXIgPT0gZGF0YTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jaGVja0RhdGVJc0ZvY3Vzc2VkOiBmdW5jdGlvbihkYXRhKSB7CiAgICAgICAgICAgIHN3aXRjaCh0aGlzLnZpZXcudG9Mb3dlckNhc2UoKSkgewogICAgICAgICAgICAgICAgY2FzZSAibW9udGgiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhID09IHRoaXMuY3VycmVudERheTsKICAgICAgICAgICAgICAgIGNhc2UgInllYXIiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRNb250aCA9PSBkYXRhOwogICAgICAgICAgICAgICAgY2FzZSAieWVhcnNldCI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFllYXIgPT0gZGF0YTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jb252ZXJ0TnVtYmVyVG9Mb2NhbGUgOiBmdW5jdGlvbihudW1iZXIpIHsKICAgICAgICAgICAgdmFyIHplcm9Db2RlID0gdGhpcy5vcHRpb25zLmxvY2FsZS56ZXJvLmNoYXJDb2RlQXQoMCk7CiAgICAgICAgICAgIG51bWJlciArPSAiIjsKICAgICAgICAgICAgdmFyIG5ld051bWJlciA9IFtdOwogICAgICAgICAgICBmb3IodmFyIGkgPSAwO2kgPCBudW1iZXIubGVuZ3RoO2krKykgewogICAgICAgICAgICAgICAgbmV3TnVtYmVyLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZSh6ZXJvQ29kZSArIHBhcnNlSW50KG51bWJlci5jaGFyQXQoaSkpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ld051bWJlci5qb2luKCIiKTsKICAgICAgICB9LAoKICAgICAgICBfY2xlYXJEYXRlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIGlzRGF0ZUVtcHR5ID0gdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLnZhbCgpID8gZmFsc2UgOiB0cnVlOwogICAgICAgICAgICB0aGlzLnNlbGVjdGVkWWVhcgogICAgICAgICAgICAgICAgPSB0aGlzLnNlbGVjdGVkTW9udGgKICAgICAgICAgICAgICAgID0gdGhpcy5zZWxlY3RlZFllYXIKICAgICAgICAgICAgICAgID0gLTE7CiAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlLnNlbGVjdGVkRGF0ZSA9ICIiOwogICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQudmFsKCIiKTsKICAgICAgICAgICAgaWYgKCFpc0RhdGVFbXB0eSkgewogICAgICAgICAgICAgICAgdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLnRyaWdnZXIoIm9udmFsdWVjaGFuZ2UuZGF0ZXRpbWVwaWNrZXIiLCBbCiAgICAgICAgICAgICAgICAgICAge3NlbGVjdGVkRGF0ZTogIiJ9CiAgICAgICAgICAgICAgICBdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkKCIuZHAtc2VsZWN0ZWQiLHRoaXNbJyQnK3RoaXMudmlldy50b0xvd2VyQ2FzZSgpXSkucmVtb3ZlQ2xhc3MoImRwLXNlbGVjdGVkIik7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RXZlbnQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuICJjbGljayI7Ly90aGlzLnRvdWNoU3VwcG9ydGVkID8gInRvdWNoc3RhcnQiIDogImNsaWNrIjsKICAgICAgICB9LAoKICAgICAgICBfcGFkMjogZnVuY3Rpb24obSkgewogICAgICAgICAgICByZXR1cm4gbSA9IG0gPCAxMCA/IjAiK206bTsKICAgICAgICB9LAoKICAgICAgICB0b1N0cmluZyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3RlZFllYXIgKyItIit0aGlzLl9wYWQyKHRoaXMuc2VsZWN0ZWRNb250aCArIDEpKyItIit0aGlzLl9wYWQyKHRoaXMuc2VsZWN0ZWREYXkpOwogICAgICAgIH0sCgogICAgICAgIF9zZWxlY3REYXRlIDogZnVuY3Rpb24oZXZudCkgewogICAgICAgICAgICB2YXIgdmFsID0geGZhVXRpbC4kZGF0YShldm50LnRhcmdldCwgInZhbHVlIiksCiAgICAgICAgICAgICAgICBuZXh0VmlldyA9IHZpZXdBY3Rpb25bdGhpcy52aWV3XS5saSwKICAgICAgICAgICAgICAgIGVkaXRWYWw7CiAgICAgICAgICAgIC8vZGlzYWJsZWQgZGF0ZXMgaGF2ZSBhIHZhbHVlIG9mIC0xLiBEbyBub3RoaW5nIGluIHRoYXQgY2FzZQogICAgICAgICAgICBpZih2YWwgPT0gLTEpCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIHN3aXRjaCh0aGlzLnZpZXcudG9Mb3dlckNhc2UoKSkgewogICAgICAgICAgICAgICAgY2FzZSAibW9udGgiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRNb250aCA9IHRoaXMuY3VycmVudE1vbnRoOwogICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRZZWFyID0gdGhpcy5jdXJyZW50WWVhcjsKICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkRGF5ID0gdmFsOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlLnNlbGVjdGVkRGF0ZSA9IHRoaXMudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgICAgICBlZGl0VmFsID0gdGhpcy5fY3VySW5zdGFuY2UuZWRpdFZhbHVlKHRoaXMudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLnZhbChlZGl0VmFsKS5mb2N1cygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlLiRmaWVsZC50cmlnZ2VyKCJvbnZhbHVlY2hhbmdlLmRhdGV0aW1lcGlja2VyIiwgWwogICAgICAgICAgICAgICAgICAgICAgICB7c2VsZWN0ZWREYXRlOiBlZGl0VmFsfQogICAgICAgICAgICAgICAgICAgIF0pOwogICAgICAgICAgICAgICAgICAgICQoIi5kcC1zZWxlY3RlZCIsdGhpc1snJCcrdGhpcy52aWV3LnRvTG93ZXJDYXNlKCldKS5yZW1vdmVDbGFzcygiZHAtc2VsZWN0ZWQiKTsKICAgICAgICAgICAgICAgICAgICAkKGV2bnQudGFyZ2V0KS5hZGRDbGFzcygiZHAtc2VsZWN0ZWQiKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInllYXIiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudE1vbnRoID0gdmFsOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAieWVhcnNldCI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50WWVhciA9IHZhbDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl9sYXlvdXQobmV4dFZpZXcpOwogICAgICAgICAgICAvL21hbnVhbGx5IGZvY3VzIG9uIHRoZSBmaWVsZCBpZiBjbGlja2VkIG9uIHRoZSBwb3B1cCBidXR0b25zIGZvciBub24tdG91Y2ggZGV2aWNlCiAgICAgICAgICAgIGlmKCF0aGlzLnRvdWNoU3VwcG9ydGVkKSB7CiAgICAgICAgICAgICAgICAvL05vIG5lZWQgdG8gZm9jdXMgaWYgc2VsZWN0aW9uIGlzIG1hZGUgYnkgcHJlc3Npbmcgc3BhY2UuCiAgICAgICAgICAgICAgICBpZighdGhpcy5ob3RLZXlQcmVzc2VkKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zY3JpcHRGb2N1cyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgaWYobmV4dFZpZXcgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYobmV4dFZpZXcgPT0gbnVsbCl7CiAgICAgICAgICAgICAgICAvL0ZvciB0b3VjaCBkZXZpY2VzLCBkZWFjdGl2YXRlIHRoZSBmaWVsZCBpZiBhIHNlbGVjdGlvbiBpcyBtYWRlCiAgICAgICAgICAgICAgICB0aGlzLmZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtID0gZmFsc2U7CiAgICAgICAgICAgICAgICB0aGlzLl9kZWFjdGl2YXRlRmllbGQoKQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2xlYXBZZWFyIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRZZWFyICUgNDAwID09IDAgfHwgKHRoaXMuY3VycmVudFllYXIgJSAxMDAgIT0gMCAmJiB0aGlzLmN1cnJlbnRZZWFyICUgNCA9PSAwKTsKICAgICAgICB9LAoKICAgICAgICBfbWF4RGF0ZSA6IGZ1bmN0aW9uKG0pIHsKICAgICAgICAgICAgaWYodGhpcy5fbGVhcFllYXIoKSAmJiBtID09IDEpCiAgICAgICAgICAgICAgICByZXR1cm4gMjk7CiAgICAgICAgICAgIGVsc2UgcmV0dXJuIGRhdGVzW21dOwogICAgICAgIH0sCgogICAgICAgIF9hY2Nlc3M6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICBpZih0eXBlb2YgdmFsID09ICJ1bmRlZmluZWQiKQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWNjZXNzCiAgICAgICAgICAgIHRoaXMuYWNjZXNzID0gdmFsOwogICAgICAgIH0sCgogICAgICAgIF92YWx1ZTpmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgaWYodHlwZW9mIHZhbCA9PSAidW5kZWZpbmVkIikKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLiRmaWVsZC52YWwoKQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gdmFsOwogICAgICAgICAgICAgICAgdmFyIGVkaXRWYWx1ZSA9IHRoaXMuZWRpdFZhbHVlKHZhbCk7CiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgdGhlIGZpZWxkIHZhbCB3aXRoIHByb3ZpZGVkIHZhbHVlIGluc3RlYWQgb2YgbnVsbAogICAgICAgICAgICAgICAgaWYgKCFlZGl0VmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICBlZGl0VmFsdWUgPSB2YWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLiRmaWVsZC52YWwoZWRpdFZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKICAgIHZhciBhZG9iZURhdGVUaW1lUGlja2VyID0gbmV3IERhdGVUaW1lUGlja2VyKCk7CgogICAgJC5mbi5hZG9iZURhdGVUaW1lUGlja2VyID0gZnVuY3Rpb24ob3B0aW9ucywgdmFsdWUpIHsKICAgICAgICBpZighYWRvYmVEYXRlVGltZVBpY2tlci5pbml0aWFsaXplZCkgewogICAgICAgICAgICBhZG9iZURhdGVUaW1lUGlja2VyLmNyZWF0ZShvcHRpb25zKTsKICAgICAgICAgICAgYWRvYmVEYXRlVGltZVBpY2tlci5pbml0aWFsaXplZCA9IHRydWU7CiAgICAgICAgfQogICAgICAgIGlmKHR5cGVvZiBvcHRpb25zID09PSAib2JqZWN0IikgewogICAgICAgICAgICBhZG9iZURhdGVUaW1lUGlja2VyLl9hdHRhY2hGaWVsZCh0aGlzLCBvcHRpb25zKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gInN0cmluZyIpIHsKICAgICAgICAgICAgaWYoYXJndW1lbnRzLmxlbmd0aCA9PSAyKQogICAgICAgICAgICAgICAgYWRvYmVEYXRlVGltZVBpY2tlclsiXyIrb3B0aW9uc10uYXBwbHkoeGZhVXRpbC4kZGF0YSh0aGlzWzBdLCJkYXRldGltZXBpY2tlciIpLFt2YWx1ZV0pCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBhZG9iZURhdGVUaW1lUGlja2VyWyJfIitvcHRpb25zXS5hcHBseSh4ZmFVdGlsLiRkYXRhKHRoaXNbMF0sImRhdGV0aW1lcGlja2VyIikpCiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgfQp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24gKHhmYWxpYikgewogICAgeGZhbGliLnV0LlRvdWNoVXRpbCA9IChmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHRvdWNoQXZhaWxhYmxlID0gISEoIm9udG91Y2hzdGFydCIgaW4gd2luZG93IHx8IHdpbmRvdy5Eb2N1bWVudFRvdWNoICYmIGRvY3VtZW50IGluc3RhbmNlb2YgRG9jdW1lbnRUb3VjaCkgLAogICAgICAgICAgICBwb2ludGVyRW5hYmxlZCA9ICEhKHdpbmRvdy5NU1BvaW50ZXJFdmVudCB8fCB3aW5kb3cuUG9pbnRlckV2ZW50KSAsCiAgICAgICAgICAgIFBPSU5URVJfRE9XTl9FVkVOVCA9ICJtb3VzZWRvd24iLAogICAgICAgICAgICBQT0lOVEVSX01PVkVfRVZFTlQgPSAibW91c2Vtb3ZlIiwKICAgICAgICAgICAgUE9JTlRFUl9VUF9FVkVOVCA9ICJtb3VzZXVwIiwKICAgICAgICAgICAgRVZFTlRfVFlQRSA9ICJNb3VzZUV2ZW50IjsKCiAgICAgICAgaWYgKHdpbmRvdy5Qb2ludGVyRXZlbnQpIHsgLy8+IElFMTEKICAgICAgICAgICAgUE9JTlRFUl9ET1dOX0VWRU5UID0gInBvaW50ZXJkb3duIjsKICAgICAgICAgICAgUE9JTlRFUl9NT1ZFX0VWRU5UID0gInBvaW50ZXJtb3ZlIjsKICAgICAgICAgICAgUE9JTlRFUl9VUF9FVkVOVCA9ICJwb2ludGVydXAiOwogICAgICAgICAgICBFVkVOVF9UWVBFID0gIlBvaW50ZXJFdmVudCI7CgogICAgICAgIH0gZWxzZSBpZiAod2luZG93Lk1TUG9pbnRlckV2ZW50KSB7IC8vIElFMTAKICAgICAgICAgICAgUE9JTlRFUl9ET1dOX0VWRU5UID0gIk1TUG9pbnRlckRvd24iOwogICAgICAgICAgICBQT0lOVEVSX01PVkVfRVZFTlQgPSAiTVNQb2ludGVyTW92ZSI7CiAgICAgICAgICAgIFBPSU5URVJfVVBfRVZFTlQgPSAiTVNQb2ludGVyVXAiOwogICAgICAgICAgICBFVkVOVF9UWVBFID0gIk1TUG9pbnRlckV2ZW50IiA7CgogICAgICAgIH0gZWxzZSBpZiAodG91Y2hBdmFpbGFibGUpIHsgIC8vIG90aGVyIHRvdWNoIGRldmljZXMKICAgICAgICAgICAgUE9JTlRFUl9ET1dOX0VWRU5UID0gInRvdWNoc3RhcnQiOwogICAgICAgICAgICBQT0lOVEVSX01PVkVfRVZFTlQgPSAidG91Y2htb3ZlIjsKICAgICAgICAgICAgUE9JTlRFUl9VUF9FVkVOVCA9ICJ0b3VjaGVuZCI7CiAgICAgICAgICAgIEVWRU5UX1RZUEUgPSAiVG91Y2hFdmVudCI7CiAgICAgICAgfQogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIFRPVUNIX0VOQUJMRUQ6IHRvdWNoQXZhaWxhYmxlLAogICAgICAgICAgICAvLyBuZXcgTVMgUG9pbnRlciBFdmVudHMKICAgICAgICAgICAgUE9JTlRFUl9FVkVOVDogRVZFTlRfVFlQRSwKICAgICAgICAgICAgUE9JTlRFUl9FTkFCTEVEOiBwb2ludGVyRW5hYmxlZCwKICAgICAgICAgICAgUE9JTlRFUl9ET1dOOiBQT0lOVEVSX0RPV05fRVZFTlQsCiAgICAgICAgICAgIFBPSU5URVJfTU9WRTogUE9JTlRFUl9NT1ZFX0VWRU5ULAogICAgICAgICAgICBQT0lOVEVSX1VQOiBQT0lOVEVSX1VQX0VWRU5ULAogICAgICAgICAgICBnZXRUb3VjaEV2ZW50OiBmdW5jdGlvbiAoZXZ0KSB7CiAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0OwogICAgICAgICAgICAgICAgaWYgKHBvaW50ZXJFbmFibGVkKSB7CiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gZXZ0Lm9yaWdpbmFsRXZlbnQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRvdWNoQXZhaWxhYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gZXZ0Lm9yaWdpbmFsRXZlbnQgfHwgZXZ0OwogICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IHRhcmdldC50b3VjaGVzWzBdOwogICAgICAgICAgICAgICAgICAgIC8vaWYgKGV2dC5vcmlnaW5hbEV2ZW50ICYmIGV2dC5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzICYmIGV2dC5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gICAgdGUgPSBldnQub3JpZ2luYWxFdmVudC5jaGFuZ2VkVG91Y2hlc1swXTsKICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0IHx8IGV2dDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZ2V0UG9pbnRlckV2ZW50OiBmdW5jdGlvbiAoZXZlbnRUeXBlKSB7CiAgICAgICAgICAgICAgICB2YXIgZXZlbnQgPSBudWxsOwogICAgICAgICAgICAgICAgaWYgKCh0eXBlb2YgUG9pbnRlckV2ZW50KSA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICAgICAgICAgIGV2ZW50ID0gbmV3IFBvaW50ZXJFdmVudChldmVudFR5cGUsIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnViYmxlczogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgY2FuY2VsYWJsZTogdHJ1ZQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KEVWRU5UX1RZUEUpOwogICAgICAgICAgICAgICAgICAgIGV2ZW50LmluaXRFdmVudChldmVudFR5cGUsIHRydWUsIHRydWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50OwogICAgICAgICAgICB9LAogICAgICAgICAgICBnZXRUb3VjaGVzOmZ1bmN0aW9uKGV2dCl7CiAgICAgICAgICAgICAgICB2YXIgdG91Y2hlcyA9IFtdOwogICAgICAgICAgICAgICAgaWYodG91Y2hBdmFpbGFibGUgJiYgZXZ0Lm9yaWdpbmFsRXZlbnQgJiYgZXZ0Lm9yaWdpbmFsRXZlbnQudG91Y2hlcyApewogICAgICAgICAgICAgICAgICAgIHRvdWNoZXMgPSBldnQub3JpZ2luYWxFdmVudC50b3VjaGVzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRvdWNoZXM7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfSkoKTsKfSkoeGZhbGliKTsKKGZ1bmN0aW9uICgkLCBfKSB7CiAgICAkLndpZGdldCgieGZhV2lkZ2V0LmFic3RyYWN0V2lkZ2V0IiwgewoKICAgICAgICAkdXNlckNvbnRyb2w6IG51bGwsCgogICAgICAgICRkYXRhOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuJGRhdGEsCgogICAgICAgICRjc3M6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS4kY3NzLAoKICAgICAgICBnZXRPckVsc2U6IHhmYWxpYi51dC5DbGFzcy5wcm90b3R5cGUuZ2V0T3JFbHNlLAoKICAgICAgICBkSW5kZXhPZjogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmRJbmRleE9mLAoKICAgICAgICBidHduOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuYnR3biwKCiAgICAgICAgbG9nZ2VyOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0TG9nZ2VyLAoKICAgICAgICBsb2NhbGVTdHJpbmdzOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0TG9jYWxlU3RyaW5ncywKCiAgICAgICAgbG9nTXNnczogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmdldExvZ01lc3NhZ2VzLAoKICAgICAgICBlcnJvck1hbmFnZXI6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5nZXRFcnJvck1hbmFnZXIsCgogICAgICAgIF93aWRnZXROYW1lOiAiYWJzdHJhY3RXaWRnZXQiLAoKICAgICAgICAvLyBpZiB0aGVyZSBhcmUgYW55IHNwZWNpZmljIGJsYWNrIGxpc3RlZCBhdHRyaWJ1dGVzLCBlYWNoIHdpZGdldCBzaG91bGQgZGVmaW5lIHRoZWlyIG93bgogICAgICAgIF9ibGFja0xpc3RlZEF0dHJpYnV0ZXMgOiBbInR5cGUiXSwKCiAgICAgICAgb3B0aW9uczogewogICAgICAgICAgICBuYW1lOiAiIiwKICAgICAgICAgICAgdmFsdWU6IG51bGwsCiAgICAgICAgICAgIGNvbW1pdFByb3BlcnR5OiAidmFsdWUiLAogICAgICAgICAgICBkaXNwbGF5VmFsdWU6IG51bGwsCiAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHQ6IG51bGwsCiAgICAgICAgICAgIHRhYkluZGV4OiAwLAogICAgICAgICAgICByb2xlOiBudWxsLAogICAgICAgICAgICBwYXJhU3R5bGVzOiBudWxsLAogICAgICAgICAgICBkaXI6IG51bGwsCiAgICAgICAgICAgIGVycm9yTWVzc2FnZTogbnVsbCwKICAgICAgICAgICAgd2FybmluZ01lc3NhZ2U6IG51bGwsCiAgICAgICAgICAgIGhTY3JvbGxEaXNhYmxlZDogZmFsc2UsCiAgICAgICAgICAgIHBsYWNlaG9sZGVyOiIiLAogICAgICAgICAgICBpc1ZhbGlkOnRydWUsCiAgICAgICAgICAgIG1hbmRhdG9yeTogZmFsc2UKICAgICAgICB9LAoKICAgICAgICBnZXRPcHRpb25zTWFwOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAidGFiSW5kZXgiOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigidGFiaW5kZXgiLCB2YWwpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJyb2xlIjogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgIGlmICh2YWwpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoInJvbGUiLCB2YWwpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJzY3JlZW5SZWFkZXJUZXh0IjogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgIGlmICh2YWwpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImFyaWEtbGFiZWwiLCB2YWwpCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInBhcmFTdHlsZXMiOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuJHVzZXJDb250cm9sLmdldCgwKSwgdmFsKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZGlyIjogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgIGlmICh2YWwpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImRpciIsIHRoaXMub3B0aW9ucy5kaXIpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJoZWlnaHQiOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy4kdXNlckNvbnRyb2xbMF0sIHsiaGVpZ2h0IjogdmFsfSkKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIndpZHRoIjogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgIGlmICh2YWwpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLiR1c2VyQ29udHJvbFswXSwgeyJ3aWR0aCI6IHZhbH0pCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImlzVmFsaWQiOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYodmFsKXsKICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImFyaWEtaW52YWxpZCIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJhcmlhLWludmFsaWQiLHRydWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiY29sb3IiIDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICBpZighXy5pc0VtcHR5KHZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29sb3IgPSAicmdiKCIgKyB2YWx1ZSArICIpIjsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuJHVzZXJDb250cm9sWzBdLCB7ImNvbG9yIjogY29sb3J9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImZvbnQtc3R5bGUiIDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFfLmlzRW1wdHkodmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLiR1c2VyQ29udHJvbFswXSwgeyJmb250LXN0eWxlIjogdmFsdWV9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIm1hbmRhdG9yeSIgOiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICBpZih2YWx1ZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImFyaWEtcmVxdWlyZWQiLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJhcmlhLXJlcXVpcmVkIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIGdldEV2ZW50TWFwOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAiZm9jdXMiOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VOVEVSX0VWRU5ULAogICAgICAgICAgICAgICAgImJsdXIiOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VYSVRfRVZFTlQsCiAgICAgICAgICAgICAgICAiY2xpY2siOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NMSUNLX0VWRU5UCiAgICAgICAgICAgIH07CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQ29waWVzIGFsbCB0aGUgYXR0cmlidXRlcyBmcm9tIHNvdXJjZSBqcXVlcnkgb2JqZWN0IHRvIGRlc3RpbmF0aW9uIGpxdWVyeSBvYmplY3QKICAgICAgICAgKiBAcGFyYW0gJHNyYyAgICAgIHNvdXJjZSBqcXVlcnkgb2JqZWN0CiAgICAgICAgICogQHBhcmFtICRkZXN0ICAgICBkZXN0aW5hdGlvbiBqcXVlcnkgb2JqZWN0CiAgICAgICAgICovCiAgICAgICAgY29weUF0dHJpYnV0ZXNGcm9tU3JjVG9EZXN0IDogZnVuY3Rpb24oJHNyYywgJGRlc3QpewogICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgIC8vIGxldCdzIGdldCBhbGwgdGhlIGF0dHJpYnV0ZSBmcm9tIHRoZSBzcmMgZWxlbWVudCBhbmQgY29weSBpdCB0byBkZXN0IGpxdWVyeSBvYmplY3QKICAgICAgICAgICAgaWYoJHNyYyAhPSBudWxsICYmICRzcmNbMF0gJiYgJHNyY1swXS5hdHRyaWJ1dGVzICYmICRkZXN0ICE9IG51bGwpewogICAgICAgICAgICAgICAgJC5lYWNoKCRzcmNbMF0uYXR0cmlidXRlcywgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gd2UgZG9uJ3QgYWRkIHRoZSBibGFjayBsaXN0ZWQgc2V0IG9mIGF0dHJpYnV0ZXMKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLnNwZWNpZmllZCAmJiB0aGlzLnZhbHVlICE9IG51bGwgJiYgXy5pc1N0cmluZyh0aGlzLnZhbHVlKSAmJiB0aGlzLnZhbHVlLmxlbmd0aCA+IDAgJiYgdGhhdC5fYmxhY2tMaXN0ZWRBdHRyaWJ1dGVzLmluZGV4T2YodGhpcy5uYW1lKSA9PT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGRlc3QuYXR0cih0aGlzLm5hbWUsIHRoaXMudmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2NyZWF0ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLndpZGdldEV2ZW50UHJlZml4ID0gIiI7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5hZGRDbGFzcyh0aGlzLl93aWRnZXROYW1lKTsKICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wgPSB0aGlzLnJlbmRlcigpOwogICAgICAgICAgICB0aGlzLm9wdGlvbnNIYW5kbGVyID0gdGhpcy5nZXRPcHRpb25zTWFwKCk7CiAgICAgICAgICAgIHRoaXMuZXZlbnRNYXAgPSB0aGlzLmdldEV2ZW50TWFwKCk7CiAgICAgICAgICAgIHRoaXMuX2luaXRpYWxpemVPcHRpb25zKCk7CiAgICAgICAgICAgIHRoaXMuX2luaXRpYWxpemVFdmVudEhhbmRsZXJzKCk7CiAgICAgICAgICAgIHRoaXMuZXJyT2JqID0gdGhpcy5lcnJvck1hbmFnZXIoKTsKICAgICAgICAgICAgLy9jYWxsIGl0IG9ubHkgYWZ0ZXIgcmVuZGVyCiAgICAgICAgICAgIC8vIERpcnR5IGhhY2sgdG8gcHJldmVudCB0aGlzIGJlaW5nIGNhbGxlZCBpbiBHdWlkZQogICAgICAgICAgICBpZiAodHlwZW9mIGd1aWRlbGliID09PSAidW5kZWZpbmVkIikgewogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuJHVzZXJDb250cm9sLmdldCgwKSwgewogICAgICAgICAgICAgICAgICAgICJib3gtc2l6aW5nIjogImJvcmRlci1ib3giLAogICAgICAgICAgICAgICAgICAgICJwb3NpdGlvbiI6ICJhYnNvbHV0ZSIKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRpYWxpemVFdmVudEhhbmRsZXJzOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5nZXRMb2dnZXIoKS5kZWJ1ZygieGZhIiwgImluaXRpYWxpemUgZXZlbnQgaGFuZGxlcnMgZm9yICIgKyB0aGlzLl93aWRnZXROYW1lKTsKICAgICAgICAgICAgXy5lYWNoKHRoaXMuZXZlbnRNYXAsIGZ1bmN0aW9uICh4ZmFldmVudCwgaHRtbGV2ZW50KSB7CiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICAgICAgICAgICAgICBpZiAoeGZhZXZlbnQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoISh4ZmFldmVudCBpbnN0YW5jZW9mICBBcnJheSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeGZhZXZlbnQgPSBbeGZhZXZlbnRdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhmYWV2ZW50Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5nZXRMb2dnZXIoKS5kZWJ1ZygieGZhIiwgImJpbmRpbmcgIiArIGh0bWxldmVudCArICIgd2l0aCAiICsgeGZhZXZlbnRbaV0pOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5vbihodG1sZXZlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKHhmZXZudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0TG9nZ2VyKCkuZGVidWcoInhmYSIsICJ0cmlnZ2VyICIgKyBldm50LnR5cGUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIHhmYS1ldmVudCAiICsgeGZldm50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fcHJlUHJvY2Vzc0V2ZW50LmFwcGx5KHNlbGYsIFt4ZmV2bnQsIGV2bnRdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9zaW5jZSB0aGUgZml4IGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvanF1ZXJ5L3B1bGwvOTcyLCBGaXggZm9yIGtlZXBpbmcgbmFtZXNwYWNlIHdoZW4gdHJpZ2dlcmluZyBhbiBldmVudCB1c2luZyBhbiBFdmVudCAjOTcyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vd2UgbmVlZCB0byBjbGVhciB0aGUgbmFtZXNwYWNlIGFuZCBpdHMgcmVndWxhciBleHByZXNzaW9uIG9mIHRyaWdnZXJpbmcgZXZlbnQsIGFzIHRoZSBsaXN0ZW5lcnMgYXJlIHJlZ2lzdGVyZWQgb24gdW4tbmFtZXNwYWNlZCBldmVudHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZudC5uYW1lc3BhY2UgPSAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZudC5uYW1lc3BhY2VfcmUgPSAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fdHJpZ2dlcih4ZmV2bnQsIGV2bnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9wb3N0UHJvY2Vzc0V2ZW50LmFwcGx5KHNlbGYsIFt4ZmV2bnQsIGV2bnRdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSh4ZmFldmVudFtpXSkKICAgICAgICAgICAgICAgICAgICAgICAgKQoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIHRoaXMpCiAgICAgICAgfSwKCiAgICAgICAgX3ByZVByb2Nlc3NFdmVudDogZnVuY3Rpb24gKHhmYWV2ZW50LCBodG1sZXZlbnQpIHsKICAgICAgICAgICAgaWYgKHhmYWV2ZW50ID09IHRoaXMub3B0aW9ucy5jb21taXRFdmVudCkgewogICAgICAgICAgICAgICAgdGhpcy5wcmVQcm9jZXNzQ29tbWl0KGh0bWxldmVudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3dpdGNoICh4ZmFldmVudCkgewogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VOVEVSX0VWRU5UOgogICAgICAgICAgICAgICAgICAgIHRoaXMucHJlUHJvY2Vzc0VudGVyKGh0bWxldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRVhJVF9FVkVOVDoKICAgICAgICAgICAgICAgICAgICB0aGlzLnByZVByb2Nlc3NFeGl0KGh0bWxldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0hBTkdFX0VWRU5UOgogICAgICAgICAgICAgICAgICAgIHRoaXMucHJlUHJvY2Vzc0NoYW5nZShodG1sZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NMSUNLX0VWRU5UOgogICAgICAgICAgICAgICAgICAgIHRoaXMucHJlUHJvY2Vzc0NsaWNrKGh0bWxldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgfSwKCiAgICAgICAgX3Bvc3RQcm9jZXNzRXZlbnQ6IGZ1bmN0aW9uICh4ZmFldmVudCwgaHRtbGV2ZW50KSB7CiAgICAgICAgICAgIGlmICh4ZmFldmVudCA9PSB0aGlzLm9wdGlvbnMuY29tbWl0RXZlbnQpIHsKICAgICAgICAgICAgICAgIHRoaXMucG9zdFByb2Nlc3NDb21taXQoaHRtbGV2ZW50KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzd2l0Y2ggKHhmYWV2ZW50KSB7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRU5URVJfRVZFTlQ6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3N0UHJvY2Vzc0VudGVyKGh0bWxldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRVhJVF9FVkVOVDoKICAgICAgICAgICAgICAgICAgICB0aGlzLnBvc3RQcm9jZXNzRXhpdChodG1sZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NIQU5HRV9FVkVOVDoKICAgICAgICAgICAgICAgICAgICB0aGlzLnBvc3RQcm9jZXNzQ2hhbmdlKGh0bWxldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0xJQ0tfRVZFTlQ6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3N0UHJvY2Vzc0NsaWNrKGh0bWxldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaW5pdGlhbGl6ZU9wdGlvbnM6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgXy5lYWNoKHRoaXMub3B0aW9uc0hhbmRsZXIsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7CiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAiZnVuY3Rpb24iKQogICAgICAgICAgICAgICAgICAgIHZhbHVlLmFwcGx5KHRoaXMsIFt0aGlzLm9wdGlvbnNba2V5XV0pOyAvLyBUT0RPOiBjaGVjayB3aGV0aGVyIGl0IGlzIG5lZWRlZCBmb3IgaW5pdGlhbGl6YXRpb24gb3Igbm90CiAgICAgICAgICAgIH0sIHRoaXMpCiAgICAgICAgfSwKCiAgICAgICAgX3NldE9wdGlvbjogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHsKICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9uc1trZXldICE9IHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnNbIGtleSBdID0gdmFsdWU7CiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMub3B0aW9uc0hhbmRsZXJba2V5XSA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9uc0hhbmRsZXJba2V5XS5hcHBseSh0aGlzLCBbdGhpcy5vcHRpb25zW2tleV1dKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgb3B0aW9uOiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkgewogICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJgogICAgICAgICAgICAgICAgdHlwZW9mIGtleSA9PT0gInN0cmluZyIgJiYKICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmCiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnNba2V5XSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAkLldpZGdldC5wcm90b3R5cGUub3B0aW9uLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykKICAgICAgICB9LAoKICAgICAgICBkZXN0cm95OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUNsYXNzKHRoaXMuX3dpZGdldE5hbWUpOwogICAgICAgIH0sCgoKICAgICAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGNvbnRyb2w7CiAgICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnQuY2hpbGRyZW4oKS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICBjb250cm9sID0gJCh0aGlzLmVsZW1lbnQuY2hpbGRyZW4oKS5nZXQoMCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGNvbnRyb2wgPSB0aGlzLmVsZW1lbnQ7CiAgICAgICAgICAgIGNvbnRyb2wuYXR0cigibmFtZSIsIHRoaXMub3B0aW9ucy5uYW1lKQogICAgICAgICAgICByZXR1cm4gY29udHJvbDsKICAgICAgICB9LAoKCiAgICAgICAgcHJlUHJvY2Vzc0NvbW1pdDogZnVuY3Rpb24gKGV2bnQpIHsKICAgICAgICAgICAgdGhpcy5vcHRpb25zLnZhbHVlID0gdGhpcy5nZXRDb21taXRWYWx1ZSgpOwogICAgICAgICAgICB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0TG9nZ2VyKCkuZGVidWcoInhmYSIsICJwYXNzaW5nIGNvbW1pdCB2YWx1ZSAiICsgdGhpcy5vcHRpb25zLnZhbHVlICsKICAgICAgICAgICAgInRvIG1vZGVsICIpOwogICAgICAgIH0sCgogICAgICAgIGdldENvbW1pdFZhbHVlOiBmdW5jdGlvbiAoKSB7CgogICAgICAgIH0sCgogICAgICAgIHByZVByb2Nlc3NFeGl0OiBmdW5jdGlvbiAoZXZudCkgewoKICAgICAgICB9LAoKICAgICAgICBwcmVQcm9jZXNzRW50ZXI6IGZ1bmN0aW9uIChldm50KSB7CiAgICAgICAgICAgIC8vT25seSBmb2N1cyB0aGUgZW5hYmxlZCB3aWRnZXRzCiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuYWNjZXNzID09PSAib3BlbiIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX3Nob3dFcnJvcigpOwogICAgICAgICAgICAgICAgdGhpcy5zaG93VmFsdWUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHByZVByb2Nlc3NDaGFuZ2U6IGZ1bmN0aW9uIChldm50KSB7CgogICAgICAgIH0sCgogICAgICAgIHByZVByb2Nlc3NDbGljazogZnVuY3Rpb24gKGV2bnQpIHsKCiAgICAgICAgfSwKCiAgICAgICAgcG9zdFByb2Nlc3NDb21taXQ6IGZ1bmN0aW9uIChldm50KSB7CiAgICAgICAgICAgIHRoaXMuc2hvd0Rpc3BsYXlWYWx1ZSgpOwogICAgICAgIH0sCgogICAgICAgIHBvc3RQcm9jZXNzRXhpdDogZnVuY3Rpb24gKGV2bnQpIHsKICAgICAgICAgICAgLy9Pbmx5IGZvciB0aGUgZW5hYmxlZCB3aWRnZXRzCiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuYWNjZXNzID09PSAib3BlbiIpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2hvd0Rpc3BsYXlWYWx1ZSgpOwogICAgICAgICAgICAgICAgdGhpcy5faGlkZUVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBwb3N0UHJvY2Vzc0VudGVyOiBmdW5jdGlvbiAoZXZudCkgewogICAgICAgIH0sCgogICAgICAgIHBvc3RQcm9jZXNzQ2hhbmdlOiBmdW5jdGlvbiAoZXZudCkgewoKICAgICAgICB9LAoKICAgICAgICBwb3N0UHJvY2Vzc0NsaWNrOiBmdW5jdGlvbiAoZXZudCkgewoKICAgICAgICB9LAoKICAgICAgICBzaG93RGlzcGxheVZhbHVlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnZhbCh0aGlzLm9wdGlvbnMuZGlzcGxheVZhbHVlKQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrcyBpZiB0aGUgZWRpdCB2YWx1ZSBpcyBzYW1lIGFzIHZhbHVlIHByZXNlbnQgaW4gdGhlIHVzZXIgY29udHJvbChodG1sIGZvcm0gZWxlbWVudCkKICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0KICAgICAgICAgKi8KICAgICAgICBfaXNWYWx1ZVNhbWUgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gKCgodGhpcy5vcHRpb25zLnZhbHVlID09PSBudWxsKSAmJiAodGhpcy4kdXNlckNvbnRyb2wudmFsKCkgPT09ICIiKSkgfHwgKHRoaXMub3B0aW9ucy52YWx1ZSA9PT0gdGhpcy4kdXNlckNvbnRyb2wudmFsKCkpKTsKICAgICAgICB9LAoKICAgICAgICBzaG93VmFsdWU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgLy8gTWF5IGJlICR1c2VyQ29udHJvbCBkb2Vzbid0IGhhdmUgdmFsKCksIHVzaW5nIGl0IGFzIG9mIG5vdwogICAgICAgICAgICAvLyBJZiB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkIGlzIG5vdCBzYW1lIGFzIGVkaXQgdmFsdWUsIG9ubHkgdGhlbiBzZXQgdGhlIHZhbHVlLCB0aGlzIGFsc28gc29sdmVzIElFIGJ1ZyBvZiBjdXJzb3IKICAgICAgICAgICAgLy8gbW92aW5nIHRvIHRoZSBlbmQgb2YgZmllbGQgb24gY2xpY2sKICAgICAgICAgICAgaWYoIXRoaXMuX2lzVmFsdWVTYW1lKCkpIHsKICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnZhbCh0aGlzLm9wdGlvbnMudmFsdWUpCiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBmb2N1czogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgIC8vIHNldFRpbWVvdXQgYWRkZWQgdG8gZml4IENRLTUxMTQxCiAgICAgICAgICAgIC8vIFdoaWxlIHVzaW5nIHNldEZvY3VzIEFQSSBpbiBhZGFwdGl2ZSBmb3JtLCB0aGUgZm9jdXMgd2FzIG5vdCBiZWluZyBzZXQgaW4gVGV4dEJveCBvbiBjaHJvbWUKICAgICAgICAgICAgLy8gYW5kIGFsc28gb24gY2xpY2sgb2YgY2FwdGlvbiBvZiBSYWRpb0J1dHRvbi9DaGVja2JveCwgZHVlIHRvIGZhc3QgZXZlbnQgZXhlY3V0aW9uLCBoZW5jZSBhZGRpbmcgZGVsYXkgZHVyaW5nIGZvY3VzLgogICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICB0aGF0LiR1c2VyQ29udHJvbFswXS5mb2N1cygpOwogICAgICAgICAgICB9LCAxKTsKICAgICAgICB9LAoKICAgICAgICBjbGljazogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLmZvY3VzKCk7CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXJIYW5kbGVyKCJjbGljayIpOyAvLyB3ZSBkbyBub3Qgd2FudCB0aGUgZXhhY3QgY2xpY2sgYXMgbWlnaHQgYnViYmxlIHVwIHRvIHRoZSBmaWVsZC4KICAgICAgICB9LAoKICAgICAgICAvKiB3aWRnZXQgc3BlY2lmaWMgY29kZSAqLwoKICAgICAgICBfc2hvd0Vycm9yOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmKHRoaXMuZXJyT2JqICYmIF8uaXNGdW5jdGlvbih0aGlzLmVyck9iai5vbkZpZWxkRW50ZXIpKSB7CiAgICAgICAgICAgICAgICB0aGlzLmVyck9iai5vbkZpZWxkRW50ZXIodGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfY2FsY3VsYXRlUGFkZGluZ0ZvclZBbGlnbjpmdW5jdGlvbihkaWZmKXsKICAgICAgICAgICB2YXIgZmxhZ0Zvck1veiA9ICQuYnJvd3Nlci5tb3ppbGxhICYmICF4ZmFsaWIudXQuVXRpbGl0aWVzLmlzSUUxMSgpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5tdWx0aUxpbmUsCiAgICAgICAgICAgICAgIHZBbGlnbkJvdHRvbU9yVG9wID0gdGhpcy5vcHRpb25zLnBhcmFTdHlsZXMgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodGhpcy5vcHRpb25zLnBhcmFTdHlsZXNbInZlcnRpY2FsLWFsaWduIl0gPT0gImJvdHRvbSIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLnBhcmFTdHlsZXNbInZlcnRpY2FsLWFsaWduIl0gPT0gInRvcCIpOwoKICAgICAgICAgICBpZihmbGFnRm9yTW96ICYmIHZBbGlnbkJvdHRvbU9yVG9wIHx8ICQuYnJvd3Nlci5tc2llICYmIHRoaXMub3B0aW9ucy5tdWx0aUxpbmUpIHsKICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgfQogICAgICAgICAgIC8vIHRvIGhhbmRsZSB0aGUgZWRnZSBjYXNlcywgaWYgdGhlIGRpZmYgaXMgbGlrZSAtMC4wMSB0aGUgd2hvbGUgb3BlcmF0aW9uIGlzIGdldHRpbmcgYWJvcnRlZAogICAgICAgICAgIC8vIHRoaXMgZGlmZiBjb21lcyBtYWlubHkgZHVlIHRvIHNjcm9sbCBoZWlnaHQgZ2V0dGluZyByb3VuZGVkIG9mZiB3aGVuIHdpZGdldEhlaWdodCBpcyBsaWtlIHguOTk5OTk5CiAgICAgICAgICAgZGlmZiA9IChkaWZmID4gLTAuMDEpID8gTWF0aC5hYnMoZGlmZikgOiBkaWZmOwogICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMucGFyYVN0eWxlcyAmJiBkaWZmID4gMCkgewogICAgICAgICAgICAgICAgdmFyIHZBbGlnbiA9IHRoaXMub3B0aW9ucy5wYXJhU3R5bGVzWyJ2ZXJ0aWNhbC1hbGlnbiJdOwogICAgICAgICAgICAgICAgaWYgKHZBbGlnbiA9PSAiYm90dG9tIikgewogICAgICAgICAgICAgICAgICAgIGRpZmYgPSBkaWZmIC0gdGhpcy5vcHRpb25zLnBhcmFTdHlsZXNbInBhZGRpbmctYm90dG9tIl07CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuY3NzKCJwYWRkaW5nLXRvcCIsIGRpZmYpOwogICAgICAgICAgICAgICAgICAgIHRoaXMucGFkZGluZyA9IHRoaXMuJHVzZXJDb250cm9sLmNzcygicGFkZGluZy10b3AiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZBbGlnbiA9PSAidG9wIiB8fCAodkFsaWduICE9ICJtaWRkbGUiICYmIHZBbGlnbiA9PSB1bmRlZmluZWQpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wYXJhU3R5bGVzWyJwYWRkaW5nLXRvcCJdKQogICAgICAgICAgICAgICAgICAgICAgICBkaWZmID0gZGlmZiAtIHRoaXMub3B0aW9ucy5wYXJhU3R5bGVzWyJwYWRkaW5nLXRvcCJdOwogICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNzcygicGFkZGluZy1ib3R0b20iLCBkaWZmKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnBhZGRpbmcgPSB0aGlzLiR1c2VyQ29udHJvbC5jc3MoInBhZGRpbmctYm90dG9tIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLm9wdGlvbnMubXVsdGlMaW5lICYmIHZBbGlnbiA9PSAibWlkZGxlIikgewogICAgICAgICAgICAgICAgICAgIHZhciBuZXdEaWZmID0gZGlmZiAvIDI7CiAgICAgICAgICAgICAgICAgICAgbmV3RGlmZiA9IG5ld0RpZmYgLSB0aGlzLm9wdGlvbnMucGFyYVN0eWxlc1sicGFkZGluZy1ib3R0b20iXTsKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnBhcmFTdHlsZXNbInBhZGRpbmctdG9wIl0pCiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0RpZmYgPSBuZXdEaWZmICsgdGhpcy5vcHRpb25zLnBhcmFTdHlsZXNbInBhZGRpbmctdG9wIl07CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuY3NzKCJwYWRkaW5nLXRvcCIsIG5ld0RpZmYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZVZBbGlnbk9uRXhpdDogZnVuY3Rpb24gKGV2bnQpIHsKCiAgICAgICAgICAgIGlmICghdGhpcy5vcHRpb25zLnBhcmFTdHlsZXMpIHsKICAgICAgICAgICAgICAgIC8vdkFsaWduIGhhcyB0byBiZSBoYW5kbGVkIG9ubHkgaWYgdGhlcmUgaXMgcGFyYVN0eWxlcwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMub3B0aW9ucy5kaXNwbGF5VmFsdWUsCiAgICAgICAgICAgICAgICBsaW5lSGVpZ2h0ID0geGZhbGliLnZpZXcudXRpbC5UZXh0TWV0cmljcy5tZWFzdXJlRXh0ZW50KHZhbHVlLCB7cmVmRWw6IHRoaXMuJHVzZXJDb250cm9sLmdldCgwKSwgbWF4SGVpZ2h0OiAtMX0pLmhlaWdodCwKICAgICAgICAgICAgICAgIHdpZGdldEhlaWdodCA9IHRoaXMub3B0aW9ucy5oZWlnaHQsCiAgICAgICAgICAgICAgICBkaWZmID0gd2lkZ2V0SGVpZ2h0IC0gbGluZUhlaWdodDsKICAgICAgICAgICAgdGhpcy5fY2FsY3VsYXRlUGFkZGluZ0ZvclZBbGlnbihkaWZmKTsKCiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZVZBbGlnbk9uRW50ZXI6IGZ1bmN0aW9uIChldm50KSB7CiAgICAgICAgICAgIC8vT25seSBhbGlnbiB0aGUgZW5hYmxlZCB3aWRnZXRzCiAgICAgICAgICAgIHZhciBmbGFnRm9ySUUgPSAkLmJyb3dzZXIubXNpZSAmJiB0aGlzLm9wdGlvbnMubXVsdGlMaW5lOwogICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnBhcmFTdHlsZXMgJiYgIWZsYWdGb3JJRSkgewogICAgICAgICAgICAgICAgIHZhciB2QWxpZ24gPSB0aGlzLm9wdGlvbnMucGFyYVN0eWxlc1sidmVydGljYWwtYWxpZ24iXTsKICAgICAgICAgICAgICAgICBpZiAodkFsaWduID09ICJib3R0b20iICYmIHRoaXMucGFkZGluZykKICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuY3NzKCJwYWRkaW5nLXRvcCIsIHRoaXMucGFkZGluZyk7CiAgICAgICAgICAgICAgICAgZWxzZSBpZiAodkFsaWduID09ICJ0b3AiICYmIHRoaXMucGFkZGluZykKICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuY3NzKCJwYWRkaW5nLWJvdHRvbSIsIHRoaXMucGFkZGluZyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaGlkZUVycm9yOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmKHRoaXMuZXJyT2JqICYmIF8uaXNGdW5jdGlvbih0aGlzLmVyck9iai5vbkZpZWxkRXhpdCkpIHsKICAgICAgICAgICAgICAgIHRoaXMuZXJyT2JqLm9uRmllbGRFeGl0KHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbWFya0Vycm9yOiBmdW5jdGlvbiAobXNnLCB0eXBlKSB7CiAgICAgICAgICAgIGlmKHRoaXMuZXJyT2JqICYmIF8uaXNGdW5jdGlvbih0aGlzLmVyck9iai5tYXJrRXJyb3IpKSB7CiAgICAgICAgICAgICAgICB0aGlzLmVyck9iai5tYXJrRXJyb3IodGhpcywgbXNnLCB0eXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNsZWFyRXJyb3I6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYodGhpcy5lcnJPYmogJiYgXy5pc0Z1bmN0aW9uKHRoaXMuZXJyT2JqLmNsZWFyRXJyb3IpKSB7CiAgICAgICAgICAgICAgICB0aGlzLmVyck9iai5jbGVhckVycm9yKHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RWRpdFZhbHVlOiBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgICBpZih0aGlzLm9wdGlvbnMuZWRpdFBhdHRlcm4gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlBpY3R1cmVGbXQuZm9ybWF0KHZhbHVlLCB0aGlzLm9wdGlvbnMuZWRpdFBhdHRlcm4pOwogICAgICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcGFyc2VFZGl0VmFsdWU6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5lZGl0UGF0dGVybiA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiB4ZmFsaWIudXQuUGljdHVyZUZtdC5wYXJzZSh2YWx1ZSwgdGhpcy5vcHRpb25zLmVkaXRQYXR0ZXJuKTsKICAgICAgICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKfSkoJCwgd2luZG93Ll8pOwooZnVuY3Rpb24oJCkgewogICAgJC53aWRnZXQoICJ4ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCIsICQueGZhV2lkZ2V0LmFic3RyYWN0V2lkZ2V0LCB7CgogICAgICAgIF93aWRnZXROYW1lOiAiZGVmYXVsdFdpZGdldCIsCgogICAgICAgIGdldE9wdGlvbnNNYXA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgcGFyZW50T3B0aW9uc01hcCA9ICQueGZhV2lkZ2V0LmFic3RyYWN0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LHBhcmVudE9wdGlvbnNNYXAsewogICAgICAgICAgICAgICAgImFjY2VzcyI6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAgICAgICAgIHN3aXRjaCh2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAib3BlbiIgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQXR0cigicmVhZE9ubHkiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImFyaWEtcmVhZG9ubHkiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJhcmlhLWRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAibm9uSW50ZXJhY3RpdmUiIDoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAicHJvdGVjdGVkIiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJkaXNhYmxlZCIsICJkaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiYXJpYS1kaXNhYmxlZCIsICJ0cnVlIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAicmVhZE9ubHkiIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoInJlYWRPbmx5IiwgInJlYWRPbmx5Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJhcmlhLXJlYWRvbmx5IiwgInRydWUiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0ICA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJkaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQXR0cigiYXJpYS1kaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKCiAgICAgICAgICAgICAgICAiZGlzcGxheVZhbHVlIjogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLmNvbW1pdFByb3BlcnR5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCQuYnJvd3Nlci5tb3ppbGxhICYmIHRoaXMub3B0aW9ucy5jb21taXRQcm9wZXJ0eSA9PSAidmFsdWUiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvbiBzdWJtaXR0aW5nIGZvcm0gZmlyZWZveCBkb2VzIG5vdCByZW1lbWJlciBhdXRvY29tcGxldGUgdmFsdWVzLCBpZiB1cGRhdGVkIHRocm91Z2ggYXR0cigpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC52YWwodGhpcy5fZGlzcGxheUVtcHR5U3RyaW5nRm9ySUUodGhpcy5vcHRpb25zLmRpc3BsYXlWYWx1ZSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucHJvcCh0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHksIHRoaXMuX2Rpc3BsYXlFbXB0eVN0cmluZ0ZvcklFKHRoaXMub3B0aW9ucy5kaXNwbGF5VmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIodGhpcy5vcHRpb25zLmNvbW1pdFByb3BlcnR5LCB0aGlzLl9kaXNwbGF5RW1wdHlTdHJpbmdGb3JJRSh0aGlzLm9wdGlvbnMuZGlzcGxheVZhbHVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlcigpLmRlYnVnKCJ4ZmFWaWV3IiwgIltEZWZhdWx0V2lkZ2V0Ll91cGRhdGVdLCBVc2VyIENvbnRyb2wgb3IgQ29tbWl0IFByb3BlcnR5IGlzIG51bGwiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgICJwbGFjZWhvbGRlciI6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJwbGFjZWhvbGRlciIsIHZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfSwKCiAgICAgICAgX2Rpc3BsYXlFbXB0eVN0cmluZ0ZvcklFOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgIC8qQ1EtNjk0MTc6IEJ5IGRlZmF1bHQgIm51bGwiIGlzIGRpc3BsYXllZCBpbiB0aGUgY29tbWVudHMgdGV4dCBib3gKICAgICAgICAgICAgICAibnVsbCIgdmFsdWVzIHNob3duIGluIElFICovCiAgICAgICAgICAgIC8vIENRLTY5MTA3IGluY2x1ZGVkIGNoZWNrIGZvciBlZGdlIGFzIHdlbGwKICAgICAgICAgICAgcmV0dXJuICh2YWx1ZSA9PSBudWxsICYmIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5kZXRlY3RJRSgpKSA/ICcnIDogdmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgcmVuZGVyIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBjb250cm9sID0gJC54ZmFXaWRnZXQuYWJzdHJhY3RXaWRnZXQucHJvdG90eXBlLnJlbmRlci5hcHBseSh0aGlzLGFyZ3VtZW50cykKICAgICAgICAgICAgdGhpcy5fYXR0YWNoRXZlbnRIYW5kbGVycyhjb250cm9sKQogICAgICAgICAgICByZXR1cm4gY29udHJvbAogICAgICAgIH0sCgogICAgICAgIGdldENvbW1pdFZhbHVlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHZhbHVlID0gdGhpcy4kdXNlckNvbnRyb2wudmFsKCk7CiAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5oU2Nyb2xsRGlzYWJsZWQgJiYgIXRoaXMub3B0aW9ucy5tdWx0aUxpbmUpCiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuc3BsaXRTdHJpbmdCeVdpZHRoKHRoaXMuJHVzZXJDb250cm9sLnZhbCgpLHRoaXMuJHVzZXJDb250cm9sLndpZHRoKCksdGhpcy4kdXNlckNvbnRyb2wuZ2V0KDApKSA7CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9LAoKICAgICAgICBfYXR0YWNoRXZlbnRIYW5kbGVyczogZnVuY3Rpb24oJGNvbnRyb2wpIHsKICAgICAgICAgICAgJGNvbnRyb2wua2V5ZG93bigkLnByb3h5KHRoaXMuX2hhbmRsZUtleURvd24sdGhpcykpOwogICAgICAgICAgICAkY29udHJvbC5rZXlwcmVzcygkLnByb3h5KHRoaXMuX2hhbmRsZUtleVByZXNzLHRoaXMpKTsKICAgICAgICAgICAgJGNvbnRyb2wub24oJ3Bhc3RlJywkLnByb3h5KHRoaXMuX2hhbmRsZVBhc3RlLHRoaXMpKTsKICAgICAgICAgICAgJGNvbnRyb2wub24oJ2N1dCcsJC5wcm94eSh0aGlzLl9oYW5kbGVDdXQsdGhpcykpOwogICAgICAgIH0sCgogICAgICAgIF9jb21wb3NpdGlvblVwZGF0ZUNhbGxiYWNrIDogZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfYXR0YWNoQ29tcG9zaXRpb25FdmVudEhhbmRsZXJzIDogZnVuY3Rpb24oJGNvbnRyb2wpIHsKICAgICAgICAgICAgdmFyIGlzQ29tcG9zaW5nID0gZmFsc2U7IC8vIElNRSBDb21wb3NpbmcgZ29pbmcgb24KICAgICAgICAgICAgdmFyIGhhc0NvbXBvc2l0aW9uSnVzdEVuZGVkID0gZmFsc2U7IC8vIFVzZWQgdG8gc3dhbGxvdyBrZXl1cCBldmVudCByZWxhdGVkIHRvIGNvbXBvc2l0aW9uZW5kCiAgICAgICAgICAgIC8vIElNRSBzcGVjaWZpYyBoYW5kbGluZywgdG8gaGFuZGxlIGphcGFuZXNlIGxhbmd1YWdlcyBtYXggbGltaXQKICAgICAgICAgICAgLy8gc2luY2UgZW50ZXIgY2FuIGFsc28gYmUgaW52b2tlZCBkdXJpbmcgY29tcG9zaW5nLCBhIHNwZWNpYWwgaGFuZGxpbmcgaXMgZG9uZSBoZXJlCiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcywKICAgICAgICAgICAgICAgIGNoYW5nZUNhcmF0UG9zaXRpb24gPSBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICAvLyBjaGFuZ2UgdGhlIGNhcmF0IHNlbGVjdGlvbiBwb3NpdGlvbiB0byBmdXJ0aGVyIGxpbWl0IGlucHV0IG9mIGNoYXJhY3RlcnMKICAgICAgICAgICAgICAgICAgICB2YXIgcmFuZ2UgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2Uuc2VsZWN0QWxsQ2hpbGRyZW4odGhhdC4kdXNlckNvbnRyb2xbMF0pOwogICAgICAgICAgICAgICAgICAgIHJhbmdlLmNvbGxhcHNlVG9FbmQoKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICRjb250cm9sLmtleXVwKGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgICAgICBpZiAoLyppc0NvbXBvc2luZyB8fCAqL2hhc0NvbXBvc2l0aW9uSnVzdEVuZGVkKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoYXQuX2NvbXBvc2l0aW9uVXBkYXRlQ2FsbGJhY2soZXZlbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZUNhcmF0UG9zaXRpb24oKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gSU1FIGNvbXBvc2luZyBmaXJlcyBrZXlkb3duL2tleXVwIGV2ZW50cwogICAgICAgICAgICAgICAgICAgIGhhc0NvbXBvc2l0aW9uSnVzdEVuZGVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICAkY29udHJvbC5vbigiY29tcG9zaXRpb25zdGFydCIsCiAgICAgICAgICAgICAgICBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAgICAgICAgIGlzQ29tcG9zaW5nID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAub24oImNvbXBvc2l0aW9udXBkYXRlIiwKICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBldmVudC5vcmlnaW5hbEV2ZW50LmRhdGEgcmVmZXJzIHRvIHRoZSBhY3R1YWwgY29udGVudAogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5fY29tcG9zaXRpb25VcGRhdGVDYWxsYmFjayhldmVudCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZUNhcmF0UG9zaXRpb24oKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAub24oImNvbXBvc2l0aW9uZW5kIiwKICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBpc0NvbXBvc2luZyA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBzb21lIGJyb3dzZXJzIChJRSwgRmlyZWZveCwgU2FmYXJpKSBzZW5kIGEga2V5dXAgZXZlbnQgYWZ0ZXIKICAgICAgICAgICAgICAgICAgICAgICAgLy8gIGNvbXBvc2l0aW9uZW5kLCBzb21lIChDaHJvbWUsIEVkZ2UpIGRvbid0LiBUaGlzIGlzIHRvIHN3YWxsb3cKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIG5leHQga2V5dXAgZXZlbnQsIHVubGVzcyBhIGtleWRvd24gZXZlbnQgaGFwcGVucyBmaXJzdAogICAgICAgICAgICAgICAgICAgICAgICBoYXNDb21wb3NpdGlvbkp1c3RFbmRlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIC5vbigia2V5ZG93biIsCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIG9uIE9TIFggbWF5IHNlbmQgYSBrZXlkb3duIG9mIDIyOSBhZnRlciBjb21wb3NpdGlvbmVuZAogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQud2hpY2ggIT09IDIyOSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzQ29tcG9zaXRpb25KdXN0RW5kZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVLZXlEb3duIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICBpZihldmVudC5rZXlDb2RlID09IDEzIHx8IGV2ZW50LmNoYXJDb2RlID09IDEzIHx8IGV2ZW50LndoaWNoID09IDEzKSAvLyB0b3VjaCBkZXZpY2VzIG1heSByZXR1cm4gY2hhckNvZGUKICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUtleVByZXNzIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICBpZihldmVudC5rZXlDb2RlID09IDEzIHx8IGV2ZW50LmNoYXJDb2RlID09IDEzIHx8IGV2ZW50LndoaWNoID09IDEzKSAvLyB0b3VjaCBkZXZpY2VzIG1heSByZXR1cm4gY2hhckNvZGUKICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgfQogICAgfSk7Cn0pKCQpOwooZnVuY3Rpb24oJCwgXykgewogICAgdmFyIHhmYVV0aWwgPSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGU7CiAgICAkLndpZGdldCggInhmYVdpZGdldC5kYXRlVGltZUVkaXQiLCAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LCB7CgogICAgICAgIF93aWRnZXROYW1lIDogImRhdGVUaW1lRWRpdCIsCgogICAgICAgIGdldEV2ZW50TWFwOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRFdmVudE1hcC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMuX25hdGl2ZVdpZGdldCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSwgcGFyZW50T3B0aW9uc01hcCwgewogICAgICAgICAgICAgICAgICAgICJvbmZvY3VzMS5kYXRldGltZXBpY2tlciI6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRU5URVJfRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgIm9udmFsdWVjaGFuZ2UuZGF0ZXRpbWVwaWNrZXIiOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NIQU5HRV9FVkVOVCwKICAgICAgICAgICAgICAgICAgICAib25mb2N1c291dC5kYXRldGltZXBpY2tlciI6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRVhJVF9FVkVOVCwKICAgICAgICAgICAgICAgICAgICAib25vdmVybGFwLmRhdGV0aW1lcGlja2VyIjogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DTElDS19FVkVOVCwgLy8gQ3VzdG9tIEV2ZW50IHRvIGZpeCBCVUcgIzM2MjY5NzQKICAgICAgICAgICAgICAgICAgICAiaW5wdXQiOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NIQU5HRV9FVkVOVCwgLy8gVE9ETyA6IGFkZCBoYW5kbGVyIGZvciB4ZmEuZXZlbnQuY2hhbmdlCiAgICAgICAgICAgICAgICAgICAgImZvY3VzIjogbnVsbCwKICAgICAgICAgICAgICAgICAgICAiYmx1ciI6IG51bGwKICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJC5leHRlbmQoe30sIHBhcmVudE9wdGlvbnNNYXAsIHsKICAgICAgICAgICAgICAgICAgICAiY2hhbmdlIjogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQKICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZ2V0QWRvYmVEYXRlUGlja2VyT3B0aW9uc01hcCA6IGZ1bmN0aW9uKHBhcmVudE9wdGlvbnNNYXApIHsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICJhY2Nlc3MiIDogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIm9wZW4iIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmFkb2JlRGF0ZVRpbWVQaWNrZXIoImFjY2VzcyIsIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIm5vbkludGVyYWN0aXZlIiA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInByb3RlY3RlZCIgOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJyZWFkT25seSIgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYWRvYmVEYXRlVGltZVBpY2tlcigiYWNjZXNzIiwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHBhcmVudE9wdGlvbnNNYXAuYWNjZXNzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImRpc3BsYXlWYWx1ZSIgOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gc2V0IHRoZSB2YWx1ZSBpbiB0aGUgZGF0ZXBpY2tlciBwbHVnaW4KICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hZG9iZURhdGVUaW1lUGlja2VyKCJ2YWx1ZSIsIHRoaXMub3B0aW9ucy52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgLy8gc2hvdyB0aGUgZGlzcGxheSB2YWx1ZQogICAgICAgICAgICAgICAgICAgIHRoaXMuc2hvd0Rpc3BsYXlWYWx1ZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldE5hdGl2ZURhdGVQaWNrZXJPcHRpb25zTWFwOiBmdW5jdGlvbiAocGFyZW50T3B0aW9uc01hcCkgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgImRpc3BsYXlWYWx1ZSI6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dEaXNwbGF5VmFsdWUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgoKICAgICAgICBnZXRPcHRpb25zTWFwOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKSwKICAgICAgICAgICAgICAgIGRhdGVQaWNrZXJPcHRpb25zID0gdGhpcy5fbmF0aXZlV2lkZ2V0ID09PSBmYWxzZSA/IHRoaXMuX2dldEFkb2JlRGF0ZVBpY2tlck9wdGlvbnNNYXAocGFyZW50T3B0aW9uc01hcCkKICAgICAgICAgICAgICAgICAgICA6IHRoaXMuX2dldE5hdGl2ZURhdGVQaWNrZXJPcHRpb25zTWFwKHBhcmVudE9wdGlvbnNNYXApLAogICAgICAgICAgICAgICAgY29tbW9uT3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgICAgICAicGFyYVN0eWxlcyI6IGZ1bmN0aW9uIChwYXJhU3R5bGVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE9wdGlvbnNNYXAucGFyYVN0eWxlcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVWQWxpZ25PbkV4aXQoKTsKICAgICAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgICAgICAgImFjY2VzcyI6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyB1cGRhdGUgd2lkdGggb24gY2hhbmdlIG9mIGFjY2VzcyAoYXMgd2lkdGggb2Ygd2lkZ2V0IGlzIGRlcGVuZGVudCBvbiBhY2Nlc3MpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBjYWxlbmRlciBpY29uIHNob3VsZCBiZSBoaWRkZW4sIGFuZCB3aWRnZXQgc2hvdWxkIHRha2UgZnVsbCBzcGFjZSB3aGVuIHJlYWRPbmx5CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE9wdGlvbnNNYXAuYWNjZXNzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uc01hcCgpLndpZHRoLmFwcGx5KHRoaXMsW3RoaXMub3B0aW9ucy53aWR0aF0pOwogICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgIndpZHRoIjogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRPcHRpb25zTWFwLndpZHRoLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbiAmJiB2YWwgJiYgdGhpcy5vcHRpb25zLmFjY2VzcyA9PSAib3BlbiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlZmZlY3RpdmVXaWR0aCA9IHZhbCA+IHRoaXMub3B0aW9ucy5jYWxlbmRhckljb25XaWR0aCA/IHZhbCAtIHRoaXMub3B0aW9ucy5jYWxlbmRhckljb25XaWR0aCA6IHZhbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLndpZHRoKGVmZmVjdGl2ZVdpZHRoKTsgIC8vIGxlYXZlIHNwYWNlIGZvciB0aGUgY2FsIGljb24KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgICAgICJoZWlnaHQiOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50T3B0aW9uc01hcC5oZWlnaHQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlVkFsaWduT25FeGl0KCk7CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAic2NyZWVuUmVhZGVyVGV4dCI6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVkaXRQYXR0ZXJuID0gdGhpcy5vcHRpb25zLmVkaXRQYXR0ZXJuOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdEVkaXRQYXR0ZXJuID0gdGhpcy5fbmF0aXZlV2lkZ2V0ID8gIm1tL2RkL3l5eXkiIDogIllZWVktTU0tREQiOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVnZXggPSAvKD86ZGF0ZSl7MCwxfXsoLiopfS87IC8vIGRhdGV7PHBhdHRlcm4+fSBvciB7PHBhdHRlcm4+fSBib3RoIGFyZSB2YWxpZCBhcyBwZXIgeGZhIHNwZWMKICAgICAgICAgICAgICAgICAgICAgICAgZWRpdFBhdHRlcm4gPSB0eXBlb2YgZWRpdFBhdHRlcm4gPT09ICJzdHJpbmciID8gZWRpdFBhdHRlcm4ubWF0Y2gocmVnZXgpWzFdIDogZGVmYXVsdEVkaXRQYXR0ZXJuOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdExhYmVsID0gIlBsZWFzZSBFbnRlciBkYXRlIGluIHswfSBmb3JtYXQgb25seSI7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlZGl0UGF0dGVybikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFyaWFMYWJlbCA9IHhmYWxpYi51dC5Mb2NhbGl6YXRpb25VdGlsLnByb3RvdHlwZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmYWxpYi5sb2NhbGUuU3RyaW5ncy5kYXRlUGlja2VyQXJpYUxhYmVsIHx8IGRlZmF1bHRMYWJlbCwgW2VkaXRQYXR0ZXJuXSkKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmluYWxWYWwgPSB2YWwgIT09IHVuZGVmaW5lZCA/IHZhbCArICIgIiArIGFyaWFMYWJlbCA6IHZhbDsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiYXJpYS1sYWJlbCIsIGZpbmFsVmFsKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICByZXR1cm4gJC5leHRlbmQoe30scGFyZW50T3B0aW9uc01hcCxkYXRlUGlja2VyT3B0aW9ucywgY29tbW9uT3B0aW9ucyk7CiAgICAgICAgfSwKCiAgICAgICAgcG9zdFByb2Nlc3NFeGl0OiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLnBvc3RQcm9jZXNzRXhpdC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuX2hhbmRsZVZBbGlnbk9uRXhpdCAoKTsKICAgICAgICB9LAoKICAgICAgICBwcmVQcm9jZXNzRW50ZXI6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUucHJlUHJvY2Vzc0VudGVyLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5faGFuZGxlVkFsaWduT25FbnRlcigpOwogICAgICAgIH0sCgogICAgICAgIHByZVByb2Nlc3NDaGFuZ2U6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAvL0NRLTQ2MzMyOmxvc3Mgb2YgZGF0ZSB2YWx1ZSBpbiBkYXRlLXBpY2tlciAsIHNldHRpbmcgdGhlIHZhbHVlIGhlcmUgb3IgZWxzZQogICAgICAgICAgIC8vaXQgZ2V0cyBsb3N0IGR1cmluZyBmb2N1cwogICAgICAgICAgIGlmKHRoaXMuX25hdGl2ZVdpZGdldCA9PT0gdHJ1ZSl7CiAgICAgICAgICAgIHRoaXMub3B0aW9ucy52YWx1ZSA9IHRoaXMuJHVzZXJDb250cm9sLnZhbCgpOwogICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBzaG93RGlzcGxheVZhbHVlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYodGhpcy5fbmF0aXZlV2lkZ2V0ID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuc2hvd0Rpc3BsYXlWYWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5zaG93VmFsdWUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgoKICAgICAgICBzaG93VmFsdWU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKHRoaXMuX25hdGl2ZVdpZGdldCA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYWRvYmVEYXRlVGltZVBpY2tlcigidmFsdWUiLCB0aGlzLm9wdGlvbnMudmFsdWUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuc2hvd1ZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJC54ZmFXaWRnZXQudGV4dEZpZWxkLnByb3RvdHlwZS5fc2VsZWN0T25Gb2N1c0luSUUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBnZXRDb21taXRWYWx1ZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVXaWRnZXQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLiR1c2VyQ29udHJvbC5hZG9iZURhdGVUaW1lUGlja2VyKCJ2YWx1ZSIpLAogICAgICAgICAgICAgICAgICAgIHBhcnNlZFZhbHVlID0gdGhpcy5wYXJzZUVkaXRWYWx1ZSh2YWx1ZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VkVmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmdldENvbW1pdFZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfSwKCiAgICAgICAgcmVuZGVyOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgdGV4dFN0eWxlID0gdGhpcy5nZXRPckVsc2UodGhpcy4kZGF0YSh0aGlzLmVsZW1lbnQuZ2V0KDApLCAieGZhbW9kZWwiKSwgInRleHRzdHlsZSIsICIiKSwKICAgICAgICAgICAgICAgICRjb250cm9sID0gJC54ZmFXaWRnZXQuYWJzdHJhY3RXaWRnZXQucHJvdG90eXBlLnJlbmRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpLAogICAgICAgICAgICAgICAgJHNvdXJjZSA9ICRjb250cm9sLAogICAgICAgICAgICAgICAgaWQsCiAgICAgICAgICAgICAgICBleGlzdGluZ0lubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzLAogICAgICAgICAgICAgICAgbmV3SW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXMsCiAgICAgICAgICAgICAgICBjb21iaW5lZElubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzOwogICAgICAgICAgICBleGlzdGluZ0lubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzID0gdGhpcy5lbGVtZW50LmZpbmQoImlucHV0IikuYXR0cigic3R5bGUiKSB8fCAnJzsKICAgICAgICAgICAgdGhpcy5fbmF0aXZlV2lkZ2V0ID0gdHJ1ZTsKICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLnVzZU5hdGl2ZVdpZGdldCA9PT0gZmFsc2UgfHwgJGNvbnRyb2xbMF0udHlwZSAhPT0gImRhdGUiKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVXaWRnZXQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGlkID0gdGhpcy5lbGVtZW50LmZpbmQoImlucHV0IilbMF0uaWQ7CiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQuY2hpbGRyZW4oKS5yZW1vdmUoKTsKICAgICAgICAgICAgICAgICQoIjxkaXY+PC9kaXY+IikuY3NzKHtwb3NpdGlvbjogInJlbGF0aXZlIiwgd2lkdGg6ICIxMDAlIiwgaGVpZ2h0OiAiMTAwJSJ9KSAvLyB3YW50IHRvIGZpbGwgZW50aXJlIHdpZHRoIG9mIGNvbnRhaW5pbmcgdGFibGUgY2VsbAogICAgICAgICAgICAgICAgICAgIC5hcHBlbmQoJCgiPGlucHV0IHR5cGU9J3RleHQnLz4iKSkKICAgICAgICAgICAgICAgICAgICAuYXBwZW5kVG8odGhpcy5lbGVtZW50KTsKICAgICAgICAgICAgICAgICRjb250cm9sID0gJCgiaW5wdXQiLCB0aGlzLmVsZW1lbnQpLgogICAgICAgICAgICAgICAgICAgIGF0dHIoInN0eWxlIiwgdGV4dFN0eWxlKS4KICAgICAgICAgICAgICAgICAgICBhdHRyKCJuYW1lIiwgdGhpcy5vcHRpb25zLm5hbWUpLgogICAgICAgICAgICAgICAgICAgIGF0dHIoImlkIiwgaWQpLgogICAgICAgICAgICAgICAgICAgIGFkb2JlRGF0ZVRpbWVQaWNrZXIoewogICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbmluZzogdGhpcy5lbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICBsb2NhbGU6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vbnRoczogdGhpcy5vcHRpb25zLm1vbnRocywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRheXM6IHRoaXMub3B0aW9ucy5kYXlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgemVybzogdGhpcy5vcHRpb25zLnplcm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRleHQ6IHRoaXMub3B0aW9ucy5jbGVhclRleHQKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzOiB0aGlzLm9wdGlvbnMuYWNjZXNzLAogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdGhpcy5vcHRpb25zLnZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICBzaG93Q2FsZW5kYXJJY29uOiB0aGlzLm9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbiwKICAgICAgICAgICAgICAgICAgICAgICAgaWNvbldpZHRoOiB0aGlzLm9wdGlvbnMuY2FsZW5kYXJJY29uV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgIG1pblZhbGlkRGF0ZSA6IHRoaXMub3B0aW9ucy5taW5WYWxpZERhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgIG1heFZhbGlkRGF0ZSA6IHRoaXMub3B0aW9ucy5tYXhWYWxpZERhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2xNaW5EYXRlIDogIHRoaXMub3B0aW9ucy5leGNsTWluRGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXhjbE1heERhdGUgOiB0aGlzLm9wdGlvbnMuZXhjbE1heERhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgIGVkaXRWYWx1ZTogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5nZXRFZGl0VmFsdWUodmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5fYXR0YWNoRXZlbnRIYW5kbGVycygkY29udHJvbCk7CiAgICAgICAgICAgIG5ld0lubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzID0gdGhpcy5lbGVtZW50LmZpbmQoImlucHV0IikuYXR0cigic3R5bGUiKSB8fCAnJzsKICAgICAgICAgICAgLy9hcHBlbmQgdGhlIHByZXZpb3VzIGlubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzIHRvIG5ld0lubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzIHNvIHRoYXQgdGhlIGlubGluZSBzdHlsZXMKICAgICAgICAgICAgLy9hZGRlZCBmcm9tIHRoZSBkaWFsb2cgYXJlIGFwcGxpZWQuCiAgICAgICAgICAgIGNvbWJpbmVkSW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXMgPSBuZXdJbmxpbmVTdHlsZUF0dHJpYnV0ZVZhbHVlcyArIGV4aXN0aW5nSW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXM7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5maW5kKCJpbnB1dCIpLmF0dHIoInN0eWxlIiwgY29tYmluZWRJbmxpbmVTdHlsZUF0dHJpYnV0ZVZhbHVlcyk7CiAgICAgICAgICAgIC8vIG9ubHkgaW4gY2FzZSBvZiBhZGFwdGl2ZSBmb3JtLCB3ZSB3b3VsZCBjb3B5IHRoZSBhdHRyaWJ1dGVzIGJhY2sKICAgICAgICAgICAgaWYod2luZG93Lmd1aWRlQnJpZGdlKSB7CiAgICAgICAgICAgICAgICAvLyByZXN0b3JlIHRoZSBvcmlnaW5hbCBhdHRyaWJ1dGUgYmFjayB0byBkZXN0aW5hdGlvbiBvYmplY3QKICAgICAgICAgICAgICAgIHRoaXMuY29weUF0dHJpYnV0ZXNGcm9tU3JjVG9EZXN0KCRzb3VyY2UsIHRoaXMuZWxlbWVudC5maW5kKCJpbnB1dCIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gJGNvbnRyb2w7CiAgICAgICAgfQogICAgfSkgOwoKfSkoJCwgXyk7CihmdW5jdGlvbigkLCBfKSB7CiQud2lkZ2V0KCJ4ZmFXaWRnZXQubnVtZXJpY0lucHV0IiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgewoKICAgIF93aWRnZXROYW1lOiAibnVtZXJpY0lucHV0IiwKCglvcHRpb25zIDogewoJCXZhbHVlIDogbnVsbCwKCQljdXJWYWx1ZTogbnVsbCwKICAgICAgICBwb3M6IDAsCiAgICAgICAgbGVuZ3RoTGltaXRWaXNpYmxlOiB0cnVlLAogICAgICAgIHplcm86IjAiLAogICAgICAgIGRlY2ltYWw6Ii4iLAogICAgICAgIG1pbnVzOiItIgoJfSwKCiAgICAvL1RPRE86IHRvIHN1cHBvcnQgd3JpdGluZyBpbiBkaWZmZXJlbnQgbG9jYWxlcyBcZCBzaG91bGQgYmUgcmVwbGFjZWQgYnkgWzAtOV0gZm9yIGRpZmZlcmVudCBsb2NhbGVzCiAgICBfbWF0Y2hBcnJheSA6IHsKICAgICAgICAgICAgICAgICAgICAiaW50ZWdlciI6Il5bKy1dP3tkaWdpdHN9KiQiLAogICAgICAgICAgICAgICAgICAgICJkZWNpbWFsIjoiXlsrLV0/e2RpZ2l0c317bGVhZGluZ30oe2RlY2ltYWx9e2RpZ2l0c317ZnJhY3Rpb259KT8kIiwKICAgICAgICAgICAgICAgICAgICAiZmxvYXQiOiJeWystXT97ZGlnaXRzfSooe2RlY2ltYWx9e2RpZ2l0c30qKT8kIgogICAgICAgICAgICAgICAgICB9LAoKICAgIF9yZWdleCA6IG51bGwsCgogICAgX2VuZ1JlZ2V4IDogbnVsbCwKCiAgICBfd3JpdHRlbkluTG9jYWxlIDogZmFsc2UsCgogICAgX3ByZXZpb3VzQ29tcG9zaXRpb25WYWwgOiAiIiwKCgogICAgX3RvTGF0aW5Gb3JtIDogZnVuY3Rpb24gKGhhbGZPckZ1bGxXaWR0aFN0cikgewogICAgICAgIC8vIHJlZmVyIGh0dHA6Ly93d3cuZmlsZWZvcm1hdC5pbmZvL2luZm8vdW5pY29kZS9ibG9jay9oYWxmd2lkdGhfYW5kX2Z1bGx3aWR0aF9mb3Jtcy91dGY4dGVzdC5odG0KICAgICAgICByZXR1cm4gaGFsZk9yRnVsbFdpZHRoU3RyLnJlcGxhY2UoCiAgICAgICAgICAgIC9bXHVmZjAwLVx1ZmZlZl0vZywKICAgICAgICAgICAgZnVuY3Rpb24oY2gpIHsgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoY2guY2hhckNvZGVBdCgwKSAtIDB4ZmVlMCk7IH0KICAgICAgICApOwogICAgfSwKCiAgICBnZXRPcHRpb25zTWFwOiBmdW5jdGlvbigpIHsKICAgICAgICB2YXIgcGFyZW50T3B0aW9uc01hcCA9ICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmdldE9wdGlvbnNNYXAuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSxwYXJlbnRPcHRpb25zTWFwLHsKICAgICAgICAgICAgInBhcmFTdHlsZXMiOiBmdW5jdGlvbihwYXJhU3R5bGVzKXsKICAgICAgICAgICAgICAgIHBhcmVudE9wdGlvbnNNYXAucGFyYVN0eWxlcy5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVWQWxpZ25PbkV4aXQgKCk7CiAgICAgICAgICAgIH0gLAoKICAgICAgICAgICAgImhlaWdodCI6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAgICAgaWYodmFsKSAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy4kdXNlckNvbnRyb2xbMF0seyJoZWlnaHQiIDp2YWx9KTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVWQWxpZ25PbkV4aXQoKTsgICAgLy8gVG8gSGFuZGxlIHRoZSBjYXNlIG9mIGV4cGFuZGFibGUgRmllbGRzCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgfSkKICAgIH0sCgogICAgZ2V0RXZlbnRNYXA6IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0RXZlbnRNYXAuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSxwYXJlbnRPcHRpb25zTWFwLHsKICAgICAgICAgICAgIm9uS2V5SW5wdXQubnVtZXJpY0lucHV0IiA6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0hBTkdFX0VWRU5UCiAgICAgICAgfSkKICAgIH0sCgogICAgX2dldERpZ2l0czogZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIHplcm9Db2RlID0gdGhpcy5vcHRpb25zLnplcm8uY2hhckNvZGVBdCgwKSwKICAgICAgICAgICAgZGlnaXRzID0gIiI7CiAgICAgICAgZm9yKHZhciBpID0gMDtpIDwgMTA7aSsrKSB7CiAgICAgICAgICAgIGRpZ2l0cyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHplcm9Db2RlICsgaSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAiWyIrZGlnaXRzKyJdIgogICAgfSwKCiAgICBfZXNjYXBlOiBmdW5jdGlvbihzdHIpIHsKICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKCIuIiwiXFwuIikKICAgIH0sCgogICAgcG9zdFByb2Nlc3NFeGl0OiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUucG9zdFByb2Nlc3NFeGl0LmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICB0aGlzLl9oYW5kbGVWQWxpZ25PbkV4aXQgKCk7CiAgICB9LAoKICAgIHByZVByb2Nlc3NFbnRlcjogZnVuY3Rpb24oZXZudCkgewogICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLnByZVByb2Nlc3NFbnRlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgdGhpcy5faGFuZGxlVkFsaWduT25FbnRlcigpOwogICAgfSwKCglyZW5kZXIgOiBmdW5jdGlvbigpIHsKICAgICAgICB2YXIgbWF0Y2hTdHIgPSAgdGhpcy5fbWF0Y2hBcnJheVt0aGlzLm9wdGlvbnMuZGF0YVR5cGVdOwogICAgICAgIGlmKG1hdGNoU3RyKSB7CiAgICAgICAgICAgIHZhciBsZCA9IHRoaXMub3B0aW9ucy5sZWFkRGlnaXRzLAogICAgICAgICAgICAgICAgZmQgPSB0aGlzLm9wdGlvbnMuZnJhY0RpZ2l0cywKICAgICAgICAgICAgICAgIGxkc3RyID0gbGQgJiYgbGQgIT0gLTEgPyAiezAsIitsZCsifSIKICAgICAgICAgICAgICAgICAgICA6ICIqIiwKICAgICAgICAgICAgICAgIGZkc3RyID0gZmQgJiYgZmQgIT0gLTEgPyAiezAsIitmZCsifSIKICAgICAgICAgICAgICAgICAgICA6ICIqIiwKICAgICAgICAgICAgICAgIG1hdGNoU3RyID0gIG1hdGNoU3RyLnJlcGxhY2UoIntsZWFkaW5nfSIsbGRzdHIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKCJ7ZnJhY3Rpb259IixmZHN0ciksCiAgICAgICAgICAgICAgICBsb2NhbGVTdHIgPSBtYXRjaFN0ci5yZXBsYWNlKC97ZGlnaXRzfS9nLHRoaXMuX2dldERpZ2l0cygpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgie2RlY2ltYWx9Iix0aGlzLl9lc2NhcGUodGhpcy5vcHRpb25zLmRlY2ltYWwpKSwKICAgICAgICAgICAgICAgIGVuZ1N0ciA9IG1hdGNoU3RyLnJlcGxhY2UoL3tkaWdpdHN9L2csIlswLTldIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgie2RlY2ltYWx9IiwiXFwuIikKICAgICAgICAgICAgdGhpcy5fcHJvY2Vzc1ZhbHVlID0gISh0aGlzLl9nZXREaWdpdHMoKSA9PSAiWzAxMjM0NTY3ODldIiAmJiB0aGlzLm9wdGlvbnMuZGVjaW1hbCA9PSAiLiIpCiAgICAgICAgICAgIHRoaXMuX3JlZ2V4ID0gbmV3IFJlZ0V4cChsb2NhbGVTdHIsICJnIik7CiAgICAgICAgICAgIHRoaXMuX2VuZ1JlZ2V4ID0gbmV3IFJlZ0V4cChlbmdTdHIsICJnIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5yZW5kZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgIH0sCgogICAgZ2V0Q29tbWl0VmFsdWU6IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciB2YWx1ZSA9ICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmdldENvbW1pdFZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgLy8gd2Ugc3VwcG9ydCBmdWxsIHdpZHRoLCBoYWxmIHdpZHRoIGFuZCBsb2NhbGUgc3BlY2lmaWMgbnVtYmVycwogICAgICAgIHZhbHVlID0gdGhpcy5fdG9MYXRpbkZvcm0odmFsdWUpOwogICAgICAgIGlmKHZhbHVlLmxlbmd0aCA+IDAgJiYgdGhpcy5fcHJvY2Vzc1ZhbHVlICYmICF2YWx1ZS5tYXRjaCh0aGlzLl9lbmdSZWdleCkpIHsKICAgICAgICAgICAgdGhpcy5fd3JpdHRlbkluTG9jYWxlID0gdHJ1ZTsKICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9jb252ZXJ0VmFsdWVGcm9tTG9jYWxlKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aGlzLl93cml0dGVuSW5Mb2NhbGUgPSBmYWxzZQogICAgICAgIH0KICAgICAgICBpZih2YWx1ZSAmJiB2YWx1ZS5sZW5ndGggPj0gdGhpcy5vcHRpb25zLmNvbWJDZWxscyApCiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc2xpY2UoMCx0aGlzLm9wdGlvbnMuY29tYkNlbGxzKTsKICAgICAgICB0aGlzLl9wcmV2aW91c0NvbXBvc2l0aW9uVmFsID0gdmFsdWU7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgfSwKCiAgICBfY29tcG9zaXRpb25VcGRhdGVDYWxsYmFjayA6IGZ1bmN0aW9uIChldmVudCkgewogICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICB2YXIgZmxhZyA9IGZhbHNlOwogICAgICAgIHZhciBsZWFkRGlnaXRzID0gdGhhdC5vcHRpb25zLmxlYWREaWdpdHM7CiAgICAgICAgdmFyIGZyYWNEaWdpdHMgPSB0aGF0Lm9wdGlvbnMuZnJhY0RpZ2l0czsKICAgICAgICAvLyB3ZSBkb24ndCBjaGVjayB1c2UtY2FzZSB3aGVyZSBqdXN0IGZyYWNEaWdpdHMgaXMgc2V0IHNpbmNlIGluIGNhc2Ugb2YgY29tcG9zaXRpb24gdXBkYXRlLCB0aGUgdmFsdWUgdG8gdXBkYXRlIGlzIG5vdCBrbm93bgogICAgICAgIGlmIChsZWFkRGlnaXRzICE9PSAtMSkgewogICAgICAgICAgICB2YXIgdmFsID0gdGhhdC4kdXNlckNvbnRyb2wudmFsKCk7CiAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSAiY29tcG9zaXRpb251cGRhdGUiICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQuZGF0YSkgewogICAgICAgICAgICAgICAgdmFsID0gdmFsICsgZXZlbnQub3JpZ2luYWxFdmVudC5kYXRhLnN1YnN0cihldmVudC5vcmlnaW5hbEV2ZW50LmRhdGEubGVuZ3RoIC0gMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gY2FuJ3QgdXNlIHRoZSBleGlzdGluZyByZWdleCAoc2luY2UgY3VycmVudCByZWdleCBjaGVja3MgZm9yIGVuZ2xpc2ggZGlnaXRzKSwgcmF0aGVyIGRvaW5nIGxlYWREaWdpdCBjb21wYXJlCiAgICAgICAgICAgIHZhciB0b3RhbExlbmd0aCA9IGxlYWREaWdpdHMgKyAoZnJhY0RpZ2l0cyAhPT0gLTEgPyAoZnJhY0RpZ2l0cyArIHRoYXQub3B0aW9ucy5kZWNpbWFsLmxlbmd0aCkgOiAwKTsKICAgICAgICAgICAgaWYgKHZhbC5pbmRleE9mKHRoYXQub3B0aW9ucy5kZWNpbWFsKSA9PT0gLTEpIHsKICAgICAgICAgICAgICAgIHRvdGFsTGVuZ3RoID0gbGVhZERpZ2l0czsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgbGF0aW5WYWwgPSB0aGlzLl90b0xhdGluRm9ybSh2YWwpOwogICAgICAgICAgICAvLyBtYXRjaCBib3RoIHNpbmNlIHdlIHN1cHBvcnQgZnVsbCB3aWR0aCwgaGFsZiB3aWR0aCBhbmQgbG9jYWxlIHNwZWNpZmljIGlucHV0CiAgICAgICAgICAgIHZhciBtYXRjaCA9IGxhdGluVmFsLm1hdGNoKHRoYXQuX3JlZ2V4KXx8IGxhdGluVmFsLm1hdGNoKHRoaXMuX2VuZ1JlZ2V4KTsKICAgICAgICAgICAgZmxhZyAgPSAhbWF0Y2g7CiAgICAgICAgICAgIGlmIChtYXRjaCA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgLy8gZW50ZXJlZCBpbnZhbGlkIGNoYXJhY3RlciwgcmV2ZXJ0IHRvIHByZXZpb3VzIHZhbHVlCiAgICAgICAgICAgICAgICB0aGF0LiR1c2VyQ29udHJvbC52YWwodGhhdC5fcHJldmlvdXNDb21wb3NpdGlvblZhbCk7CiAgICAgICAgICAgICAgICBmbGFnID0gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIGlmIChmbGFnKSB7CiAgICAgICAgICAgICAgICAvLyBpZiBtYXggcmVhY2hlZAogICAgICAgICAgICAgICAgdmFyIG5ld1ZhbCA9IHZhbC5zdWJzdHIoMCwgdG90YWxMZW5ndGgpOwogICAgICAgICAgICAgICAgdGhhdC4kdXNlckNvbnRyb2wudmFsKG5ld1ZhbCk7CiAgICAgICAgICAgICAgICB0aGF0Ll9wcmV2aW91c0NvbXBvc2l0aW9uVmFsID0gbmV3VmFsOwogICAgICAgICAgICAgICAgZmxhZyA9IHRydWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGF0Ll9wcmV2aW91c0NvbXBvc2l0aW9uVmFsID0gdmFsOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmbGFnOwogICAgfSwKCiAgICBfYXR0YWNoRXZlbnRIYW5kbGVycyA6IGZ1bmN0aW9uKCRjb250cm9sKSB7CiAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuX2F0dGFjaEV2ZW50SGFuZGxlcnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAvLyBJTUUgc3BlY2lmaWMgaGFuZGxpbmcsIHRvIGhhbmRsZSBqYXBhbmVzZSBsYW5ndWFnZXMgbWF4IGxpbWl0CiAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuX2F0dGFjaENvbXBvc2l0aW9uRXZlbnRIYW5kbGVycy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwoJfSwKCiAgICBfaGFuZGxlS2V5SW5wdXQgOiBmdW5jdGlvbihldmVudCwgY2hhcmFjdGVyLCBjb2RlKXsKICAgICAgICBpZihldmVudC5jdHJsS2V5ICYmICFfLmNvbnRhaW5zKFsncGFzdGUnLCAnY3V0J10sIGV2ZW50LnR5cGUpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuX2hhbmRsZUtleURvd24uYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgIHRoaXMub3B0aW9ucy5sZW5ndGhMaW1pdFZpc2libGUgPSB0cnVlOwoKICAgICAgICB2YXIgdmFsID0gdGhpcy4kdXNlckNvbnRyb2wucHJvcCh0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHkpIHx8ICcnLAogICAgICAgICAgICAvLyBpZiBzZWxlY3Rpb25TdGFydCBhdHRyaWJ1dGUgaXNuJ3Qgc3VwcG9ydGVkIHRoZW4gaXRzIHZhbHVlIHdpbGwgYmUgdW5kZWZpbmVkCiAgICAgICAgICAgIHNlbGVjdGlvblN0YXJ0ID0geGZhbGliLnZpZXcudXRpbC5IdG1sVXRpbC5nZXRIVE1MU3VwcG9ydGVkQXR0cih0aGlzLiR1c2VyQ29udHJvbFswXSwgInNlbGVjdGlvblN0YXJ0IiksCiAgICAgICAgICAgIGlzU2VsZWN0aW9uQXR0clN1cHBvcnRlZCA9ICEoc2VsZWN0aW9uU3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzZWxlY3Rpb25TdGFydCA9PT0gbnVsbCksCiAgICAgICAgICAgIHNlbGVjdGlvblN0YXJ0ID0gc2VsZWN0aW9uU3RhcnQgfHwgMCwKICAgICAgICAgICAgc2VsZWN0aW9uRW5kID0geGZhbGliLnZpZXcudXRpbC5IdG1sVXRpbC5nZXRIVE1MU3VwcG9ydGVkQXR0cih0aGlzLiR1c2VyQ29udHJvbFswXSwgInNlbGVjdGlvbkVuZCIpIHx8IDAsCiAgICAgICAgICAgIGNvbWJDZWxscyA9IHBhcnNlSW50KHRoaXMub3B0aW9ucy5jb21iQ2VsbHMpIHx8IDAsCiAgICAgICAgICAgIGN1cnJlbnQsCiAgICAgICAgICAgIGNoYW5nZSA9IGNoYXJhY3RlcjsKCiAgICAgICAgaWYgKGNvbWJDZWxscyA+IDAgKSB7CiAgICAgICAgICAgIGNoYW5nZSA9IGNoYXJhY3Rlci5zdWJzdHIoMCwgY29tYkNlbGxzIC0gdmFsLmxlbmd0aCArIHNlbGVjdGlvbkVuZCAtIHNlbGVjdGlvblN0YXJ0KTsKICAgICAgICB9CgogICAgICAgIGN1cnJlbnQgPSB2YWwuc3Vic3RyKDAsIHNlbGVjdGlvblN0YXJ0KSArIGNoYW5nZSArIHZhbC5zdWJzdHIoc2VsZWN0aW9uRW5kKTsKICAgICAgICAvLyBkb25lIHRvIGhhbmRsZSBzdXBwb3J0IGZvciBib3RoIGZ1bGwgd2lkdGgsIGhhbGYgd2lkdGggb3IgbWl4ZWQgaW5wdXQgaW4gbnVtYmVyIGZpZWxkCiAgICAgICAgdmFyIGxhdGluQ3VycmVudFZhbHVlID0gdGhpcy5fdG9MYXRpbkZvcm0oY3VycmVudCk7CgoJLy8gd2Ugd2FudCB0byBjaGVjayByZWdleCBmaXJzdCBhbmQgdGhlbiBzZWUgd2hldGhlciBpdCB3YXMgbnVtZXJpYyBvciBub3QuCiAgICAgICAgaWYgKCEodGhpcy5fcmVnZXggPT0gbnVsbCB8fCBsYXRpbkN1cnJlbnRWYWx1ZS5tYXRjaCh0aGlzLl9yZWdleCkgfHwgbGF0aW5DdXJyZW50VmFsdWUubWF0Y2godGhpcy5fZW5nUmVnZXgpKSkgewogICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKCS8vIENRLTQyNDU0MDcgOiBzZWxlY3Rpb25TdGFydCBhbmQgc2VsZWN0aW9uRW5kIGF0dHJpYnV0ZXMgYXJlbid0IHN1cHBvcnRlZCBpbiBjYXNlIG9mIGlucHV0IHR5cGUgPSBudW1iZXIKICAgICAgICAvLyBpdCBpcyB1c2VkIGZvciBwcm92aWRpbmcgbmF0aXZlIEhUTUw1IGltcGxlbWVudGF0aW9uIGZvciBudW1lcmljIGZpZWxkLCBzbyBubyBmdXJ0aGVyIHByb2Nlc3NpbmcgaXMgcmVxdWlyZWQKICAgICAgICAvLyBBcyBpdCBpcyBzcGVjaWZpYyB0byBBRiBhbmQgQUYgZG9lc24ndCBzdXBwb3J0IGNoYW5nZSBldmVudCBvbiBlYWNoIGtleXByZXNzLCBzbyB0aGlzIGNoYW5nZSBzaG91bGQgYmUgZmluZQogICAgICAgIGlmICghaXNTZWxlY3Rpb25BdHRyU3VwcG9ydGVkKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFfLmNvbnRhaW5zKFsna2V5ZG93bicsICdjdXQnXSwgZXZlbnQudHlwZSkgJiYgY29tYkNlbGxzICYmICh2YWwubGVuZ3RoID49IGNvbWJDZWxscyB8fCBjdXJyZW50Lmxlbmd0aCA+IGNvbWJDZWxscykgJiYgc2VsZWN0aW9uU3RhcnQgPT09IHNlbGVjdGlvbkVuZCkgewogICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICB0aGlzLm9wdGlvbnMuY3VyVmFsdWUgPSB2YWw7CiAgICAgICAgdGhpcy5fcHJldmlvdXNDb21wb3NpdGlvblZhbCA9IHZhbDsKICAgICAgICB0aGlzLm9wdGlvbnMucG9zID0gc2VsZWN0aW9uU3RhcnQ7CgogICAgICAgIGlmKHRoaXMub3B0aW9ucy5oU2Nyb2xsRGlzYWJsZWQgJiYgIV8uY29udGFpbnMoWydrZXlkb3duJywgJ2N1dCddLCBldmVudC50eXBlKSkgewogICAgICAgICAgICB2YXIgZXhwZWN0ZWRXaWR0aCA9IHhmYWxpYi52aWV3LnV0aWwuVGV4dE1ldHJpY3MubWVhc3VyZUV4dGVudChjdXJyZW50LCB7cmVmRWw6IHRoaXMuJHVzZXJDb250cm9sWzBdLCBtYXhXaWR0aDotMX0pLndpZHRoOwogICAgICAgICAgICBpZighZXZlbnQuY3RybEtleSAmJiBleHBlY3RlZFdpZHRoID4gdGhpcy4kdXNlckNvbnRyb2wud2lkdGgoKSAtIDUpewogICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5sZW5ndGhMaW1pdFZpc2libGUgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wudHJpZ2dlcih7CiAgICAgICAgICAgIHR5cGUgOiAib25LZXlJbnB1dC5udW1lcmljSW5wdXQiLAogICAgICAgICAgICBvcmlnaW5hbFR5cGUgOiBldmVudC50eXBlLAogICAgICAgICAgICBjaGFyYWN0ZXIgOiBjaGFyYWN0ZXIsICAvLyBjb250YWlucyB0aGUgcGFzdGVkIHN0cmluZyBvciBwcmVzc2VkIGtleQogICAgICAgICAgICBrZXlDb2RlIDogZXZlbnQua2V5Q29kZSB8fCAwLAogICAgICAgICAgICBjaGFyQ29kZSA6IGV2ZW50LmNoYXJDb2RlIHx8IDAsCiAgICAgICAgICAgIHdoaWNoIDogZXZlbnQud2hpY2ggfHwgMCwKICAgICAgICAgICAgY3RybEtleSA6IGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSB8fCBmYWxzZSwKICAgICAgICAgICAgc2hpZnRLZXkgOiBldmVudC5zaGlmdEtleSB8fCBmYWxzZSwKICAgICAgICAgICAga2V5RG93biA6IGZhbHNlLCAvLyBUaGlzIHByb3BlcnR5IGlzIGF2YWlsYWJsZSBvbmx5IGZvciBsaXN0IGJveGVzIGFuZCBkcm9wLWRvd24gbGlzdHMKICAgICAgICAgICAgc2VsZWN0aW9uU3RhcnQ6IHNlbGVjdGlvblN0YXJ0LAogICAgICAgICAgICBzZWxlY3Rpb25FbmQ6IHNlbGVjdGlvbkVuZAogICAgICAgIH0pOwogICAgfSwKCiAgICBfaGFuZGxlS2V5RG93biA6IGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICBpZiAoZXZlbnQpIHsKICAgICAgICAgICAgdmFyIGNvZGUgPSBldmVudC5jaGFyQ29kZSB8fCBldmVudC53aGljaCB8fCBldmVudC5rZXlDb2RlIHx8IDA7CiAgICAgICAgICAgIGlmKGNvZGUgPT0gOCB8fCBjb2RlID09IDQ2KSAvLyBiYWNrc3BhY2UgYW5kIGRlbAogICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVLZXlJbnB1dChldmVudCwgIiIsIGNvZGUpOwogICAgICAgICAgICBlbHNlIGlmKGNvZGUgPT0gMzIpIHsgLy8gc3VwcHJlc3Mgc3BhY2UKICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAoKICAgIF9pc1ZhbGlkQ2hhcjogZnVuY3Rpb24gKGNoYXJhY3RlcikgewogICAgICAgIGNoYXJhY3RlciA9IHRoaXMuX3RvTGF0aW5Gb3JtKGNoYXJhY3Rlcik7CiAgICAgICAgdmFyIGxhc3RTaW5nbGVEaWdpdENoYXIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMub3B0aW9ucy56ZXJvLmNoYXJDb2RlQXQoMCkgKyA5KTsKICAgICAgICAvLyB3ZSBvbmx5IGZ1bGwgd2lkdGgsIGhhbGYgd2lkdGggYW5kIGFsc28gbG9jYWxlIHNwZWNpZmljIGlmIGN1c3RvbWVyIGhhcyBvdmVybGF5ZWQgdGhlIGkxOG4gZmlsZQogICAgICAgIHJldHVybiAoY2hhcmFjdGVyID49ICIwIiAmJiBjaGFyYWN0ZXIgPD0gIjkiKSB8fCAoY2hhcmFjdGVyPj10aGlzLm9wdGlvbnMuemVybyAmJiBjaGFyYWN0ZXI8PWxhc3RTaW5nbGVEaWdpdENoYXIpIHx8IGNoYXJhY3Rlcj09PXRoaXMub3B0aW9ucy5kZWNpbWFsIHx8IGNoYXJhY3Rlcj09PXRoaXMub3B0aW9ucy5taW51czsKICAgIH0sCgogICAgX2hhbmRsZUtleVByZXNzIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgIGlmIChldmVudCkgewogICAgICAgICAgICB2YXIgY29kZSA9IGV2ZW50LmNoYXJDb2RlIHx8IGV2ZW50LndoaWNoIHx8IGV2ZW50LmtleUNvZGUgfHwgMCwKICAgICAgICAgICAgICAgIGNoYXJhY3RlciA9IFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZSk7CgogICAgICAgICAgICBpZih4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuaXNOb25QcmludGFibGVLZXkoZXZlbnQua2V5KSkgeyAvLyBtb3ppbGxhIGFsc28gZ2VuZXJhdGVzIGEga2V5cHJlc3MsIGFsb25nIHdpdGgga2V5ZG93bgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgYWxsIGtleXMsIHNvIG9ubHkgaGFuZGxpbmcgcHJpbnRhYmxlIGtleXMgaW4ga2V5cHJlc3MKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRoaXMuX2lzVmFsaWRDaGFyKGNoYXJhY3RlcikpCiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVLZXlJbnB1dChldmVudCwgY2hhcmFjdGVyLCBjb2RlKTsKICAgICAgICAgICAgZWxzZSBpZiAoIWV2ZW50LmN0cmxLZXkpewogICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sCgogICAgX2hhbmRsZVBhc3RlIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgIGlmIChldmVudCkgewogICAgICAgICAgICB2YXIgcGFzdGVkQ2hhciA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgaWYgKHdpbmRvdy5jbGlwYm9hcmREYXRhICYmIHdpbmRvdy5jbGlwYm9hcmREYXRhLmdldERhdGEpIHsgLy8gSUUKICAgICAgICAgICAgICAgIHBhc3RlZENoYXIgPSB3aW5kb3cuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCdUZXh0Jyk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnQub3JpZ2luYWxFdmVudC5jbGlwYm9hcmREYXRhICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQuY2xpcGJvYXJkRGF0YS5nZXREYXRhKSB7CiAgICAgICAgICAgICAgICBwYXN0ZWRDaGFyID0gZXZlbnQub3JpZ2luYWxFdmVudC5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQvcGxhaW4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYocGFzdGVkQ2hhcikgewogICAgICAgICAgICAgICAgdmFyIGFsbFBhc3RlZENoYXJzVmFsaWQgPSBfLmV2ZXJ5KHBhc3RlZENoYXIuc3BsaXQoJycpLCBmdW5jdGlvbiAoY2hhcmFjdGVyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2lzVmFsaWRDaGFyKGNoYXJhY3Rlcik7CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIGlmIChhbGxQYXN0ZWRDaGFyc1ZhbGlkKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gZHVyaW5nIHBhc3RlIHdlIHN1cHBvcnQgYm90aCBoYWxmIHdpZHRoLCBmdWxsIHdpZHRoIGFuZCBsb2NhbGUgc3BlY2lmaWMgbnVtYmVycwogICAgICAgICAgICAgICAgICAgIHBhc3RlZENoYXIgPSB0aGlzLl90b0xhdGluRm9ybShwYXN0ZWRDaGFyKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVLZXlJbnB1dChldmVudCwgcGFzdGVkQ2hhciwgMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICghZXZlbnQuY3RybEtleSkgewogICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwKCiAgICBfaGFuZGxlQ3V0IDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICBpZiAoZXZlbnQpIHsKICAgICAgICAgICAgdGhpcy5faGFuZGxlS2V5SW5wdXQoZXZlbnQsICIiLCAwKTsKICAgICAgICB9CiAgICB9LAogICAgLy8gQ1EtMTA3ODg2IDogYWRkZWQgaGFuZGxpbmcgZm9yIG5lZ2F0aXZlIHZhbHVlcywgYXMgZm9yICctJywgJy0zJyB3YXMgZ2V0dGluZyByZXR1cm5lZAogICAgX2NvbnZlcnRWYWx1ZVRvTG9jYWxlOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICB2YXIgemVyb0NvZGUgPSB0aGlzLm9wdGlvbnMuemVyby5jaGFyQ29kZUF0KDApOwogICAgICAgIHJldHVybiAgXy5tYXAodmFsLGZ1bmN0aW9uKGMpIHsKICAgICAgICAgICAgaWYoYyA9PSAiLiIpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZGVjaW1hbDsKICAgICAgICAgICAgfSBlbHNlIGlmKGMgPT0gIi0iKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLm1pbnVzOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUocGFyc2VJbnQoYykgKyB6ZXJvQ29kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LHRoaXMpLmpvaW4oIiIpOwogICAgfSwKCiAgICBfY29udmVydFZhbHVlRnJvbUxvY2FsZTogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgdmFsID0gdGhpcy5fdG9MYXRpbkZvcm0odmFsKTsKICAgICAgICB2YXIgemVyb0NvZGUgPSB0aGlzLm9wdGlvbnMuemVyby5jaGFyQ29kZUF0KDApOwogICAgICAgIHJldHVybiAgXy5tYXAodmFsLGZ1bmN0aW9uKGMpIHsKICAgICAgICAgICAgaWYoYyA9PSB0aGlzLm9wdGlvbnMuZGVjaW1hbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICIuIjsKICAgICAgICAgICAgfSBlbHNlIGlmKGMgPT0gdGhpcy5vcHRpb25zLm1pbnVzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIi0iOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIChjLmNoYXJDb2RlQXQoMCkgLSB6ZXJvQ29kZSkudG9TdHJpbmcoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sdGhpcykuam9pbigiIik7CiAgICB9LAoKICAgIHNob3dWYWx1ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgLy8gaWYgdGhlIHZhbHVlIGlzIHNhbWUsIGRvbid0IGRvIGFueXRoaW5nCiAgICAgICBpZighdGhpcy5faXNWYWx1ZVNhbWUoKSl7CiAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLnZhbHVlICYmIHRoaXMuX3dyaXR0ZW5JbkxvY2FsZSkgewogICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC52YWwodGhpcy5fY29udmVydFZhbHVlVG9Mb2NhbGUodGhpcy5vcHRpb25zLnZhbHVlKSkKICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC52YWwodGhpcy5vcHRpb25zLnZhbHVlKQogICAgICAgICAgIH0KICAgICAgIH0KICAgICAgIC8vSUUgZG9lc24ndCBzaG93IHNlbGVjdGVkIHRleHQgaWYgd2UgZm9jdXMgYW5kIHNldCBpdHMgdmFsdWUgYWxsIHRoZSB0aW1lIHNvIGZvcmNlIHNlbGVjdGlvbgogICAgICAgJC54ZmFXaWRnZXQudGV4dEZpZWxkLnByb3RvdHlwZS5fc2VsZWN0T25Gb2N1c0luSUUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgIH0KfSk7Cn0pKCQsIHdpbmRvdy5fKTsoZnVuY3Rpb24gKCQsIF8pIHsKICAgICQud2lkZ2V0KCJ4ZmFXaWRnZXQuZHJvcERvd25MaXN0IiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgeyAgICAgICAgICAgIC8vY29tbWl0RXZlbnQ6IGNoYW5nZTsgY29tbWl0UHJvcGVydHk6IHZhbHVlPEFycmF5PgoKICAgICAgICBfd2lkZ2V0TmFtZTogImRyb3BEb3duTGlzdCIsCgogICAgICAgIG9wdGlvbnM6IHsKICAgICAgICAgICAgdmFsdWU6IFtdLAogICAgICAgICAgICBpdGVtczogW10sCiAgICAgICAgICAgIGVkaXRhYmxlOiBmYWxzZSwKICAgICAgICAgICAgcGxhY2Vob2xkZXI6ICIiLAogICAgICAgICAgICBkaXNwbGF5VmFsdWU6IFtdCiAgICAgICAgfSwKCiAgICAgICAgd2lkZ2V0U2tlbGV0b246ICc8c2VsZWN0IG5hbWU9IiIgc3R5bGU9IiIgc2l6ZSA9ICIxIj48L3NlbGVjdD4nLAogICAgICAgIG9wdGlvblNrZWxldG9uOiAnPG9wdGlvbiBkYXRhLXVzZXItb3B0aW9uPjwvb3B0aW9uPicsCiAgICAgICAgb3B0R3JvdXBTa2VsZXRvbjogJzxvcHRncm91cCBsYWJlbD0iIj48L29wdGdyb3VwPicsCiAgICAgICAgQUZfT1BUR1JPVVBfTkFNRTogImFmT3B0R3JvdXBOYW1lIiwKICAgICAgICBQTEFDRV9IT0xERVJfU1RZTEVfQ0xBU1MgOiAicGxhY2VIb2xkZXIiLAoKICAgICAgICBnZXRPcHRpb25zTWFwOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0T3B0aW9uc01hcC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICByZXR1cm4gJC5leHRlbmQoe30sIHBhcmVudE9wdGlvbnNNYXAsIHsKICAgICAgICAgICAgICAgICJ2YWx1ZSI6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIV8uaXNBcnJheSh2YWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA9IFt2YWxdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWRPcHRpb25Gb3VuZCA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICB0aGF0ID0gdGhpczsKICAgICAgICAgICAgICAgICAgICAvL3N5bmMgb3B0aW9uIHNlbGVjdGlvbiBhcyBwZXIgbmV3IHZhbHVlcwogICAgICAgICAgICAgICAgICAgICQoIm9wdGlvbiIsIHRoaXMuJHVzZXJDb250cm9sKS5lYWNoKGZ1bmN0aW9uIChpbmRleCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0VmFsdWUgPSAkKHRoaXMpLnZhbCgpOwogICAgICAgICAgICAgICAgICAgICAgICAvL0NoZWNrIGlmIHRoaXMgdmFsdWUgaXMgcHJlc2VudCBpbiBvcHRpb25zIHZhbHVlIGFycmF5CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfLmNvbnRhaW5zKHZhbCwgc2VsZWN0VmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLnByb3AoInNlbGVjdGVkIiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZE9wdGlvbkZvdW5kID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcykucHJvcCgic2VsZWN0ZWQiLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pZCA9PT0gImVtcHR5VmFsdWUiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS52YWwoIiIpLmh0bWwodGhhdC5vcHRpb25zLnBsYWNlaG9sZGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0hpZGluZyBlbXB0eVZhbHVlIHdpdGggbm8gcGxhY2Vob2xkZXIgdGV4dCBjb25maWd1cmVkLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoYXQub3B0aW9ucy5wbGFjZWhvbGRlci5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLmhpZGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgLyogQWRkIGRlZmF1bHQgb3B0aW9uIGlmIDoKICAgICAgICAgICAgICAgICAgICAvIDEuIElmIHBsYWNlaG9sZGVyIGFkZCBhbiBleHRyYSBvcHRpb24KICAgICAgICAgICAgICAgICAgICAvIDIuIElmIHRoZSB2YWx1ZSBpcyBzZXQgYW55dGhpbmcgb3RoZXIgdGhhbiB0aGUgb3B0aW9ucyAoYW5kIG51bGwvIiIpIGNyZWF0ZSBhIG5ldyBvcHRpb24KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoKCFzZWxlY3RlZE9wdGlvbkZvdW5kICYmIHZhbC5sZW5ndGggIT0gMCAmJiB2YWxbMF0gIT0gbnVsbCkgfHwgdGhhdC5vcHRpb25zLnBsYWNlaG9sZGVyLmxlbmd0aCAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLiR1c2VyQ29udHJvbC5jaGlsZHJlbignW2RhdGEtZW1wdHktb3B0aW9uXScpLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXh0cmFPcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJvcHRpb24iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhT3B0aW9uLnNldEF0dHJpYnV0ZSgiZGF0YS1lbXB0eS1vcHRpb24iLCAiIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyYU9wdGlvbi5zZXRBdHRyaWJ1dGUoInJvbGUiLCAibm9uZSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFPcHRpb24uc2V0QXR0cmlidXRlKCJ2YWx1ZSIsICIiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2xbMF0uaW5zZXJ0QmVmb3JlKGV4dHJhT3B0aW9uLCB0aGlzLiR1c2VyQ29udHJvbFswXS5maXJzdENoaWxkKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBwbGFjZWhvbGRlciBpcyBwcmVzZW50IHRoZSBzZXQgdmFsdWUgb2YgZW1wdHkgb3B0aW9uIHRvIHBsYWNlaG9sZGVyCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGF0Lm9wdGlvbnMucGxhY2Vob2xkZXIubGVuZ3RoICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCdbZGF0YS1lbXB0eS1vcHRpb25dJykudGV4dCh0aGF0Lm9wdGlvbnMucGxhY2Vob2xkZXIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHBsYWNlaG9sZGVyIGlzIHByZXNlbnQgYW5kIHZhbHVlIGlzIG5vdCBwcmVzZW50IHRoZW4gc2VsZWN0IHBsYWNlaG9sZGVyCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWwubGVuZ3RoID09IDAgfHwgdmFsWzBdID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCdbZGF0YS1lbXB0eS1vcHRpb25dJykucHJvcCgic2VsZWN0ZWQiLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSAvLyBJZiB2YWx1ZSBpcyBzZXQgYW55dGhpbmcgb3RoZXIgdGhhbiBvcHRpb24gdGhlbiBzZXQgZW1wdHkgb3B0aW9uIHRvIHZhbHVlCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzZWxlY3RlZE9wdGlvbkZvdW5kICYmIHZhbC5sZW5ndGggIT0gMCAmJiB2YWxbMF0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oJ1tkYXRhLWVtcHR5LW9wdGlvbl0nKS50ZXh0KHZhbFswXSkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wKCJzZWxlY3RlZCIsIHRydWUpLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsKF8uZXNjYXBlKHZhbFswXSkpLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvdygpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGF0Lm9wdGlvbnMucGxhY2Vob2xkZXIubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRlIGRlZmF1bHQgb3B0aW9uIGlmIHZhbHVlIGlzIGZvdW5kIGluIG9wdGlvbnMgd2hpbGUgYWRkaW5nIG9wdGlvbnMKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkT3B0aW9uRm91bmQgJiYgdGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oJ1tkYXRhLWVtcHR5LW9wdGlvbl0nKS52YWwoKSAhPSB0aGF0Lm9wdGlvbnMuZGlzcGxheVZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oJ1tkYXRhLWVtcHR5LW9wdGlvbl0nKS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2xbMF0ucmVtb3ZlQ2hpbGQodGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oJ1tkYXRhLWVtcHR5LW9wdGlvbl0nKVswXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVzZXQgdGhlIHZhbHVlIG9mIGRyb3Bkb3duIGJhc2VkIG9uIHJ1bGUKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoIXNlbGVjdGVkT3B0aW9uRm91bmQgJiYgKHZhbC5sZW5ndGggPT0gMCB8fCB2YWwgPT0gbnVsbCB8fCB2YWxbMF0gPT0gbnVsbCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sWzBdLnZhbHVlID0gIiI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wudG9nZ2xlQ2xhc3ModGhpcy5QTEFDRV9IT0xERVJfU1RZTEVfQ0xBU1MsIHZhbC5sZW5ndGggPT0gMCB8fCB2YWwgPT0gbnVsbCk7CiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgICJpdGVtcyI6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIV8uaXNBcnJheSh2YWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA9IFt2YWxdOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdmFyIEFGX09QVEdST1VQX05BTUUgPSAiYWZPcHRHcm91cE5hbWUiOwogICAgICAgICAgICAgICAgICAgIHZhciBpLCBqLCBvcHRncm91cE9wdGlvbnMgPSBbXSwgZWxlbWVudCwgJHZpZXdPcHRncm91cCwgJHByZU9wdGdyb3VwOwogICAgICAgICAgICAgICAgICAgIHZhciB2aWV3T3B0Z3JvdXBzID0gJCgib3B0Z3JvdXAiLCB0aGlzLiR1c2VyQ29udHJvbCk7CiAgICAgICAgICAgICAgICAgICAgLy8gUmVtb3ZlcyBhbGwgb3B0aW9ucyB3aGljaCBlYXJsaWVyIGRpZG4ndCBiZWxvbmcgdG8gYW55IG9wdGdyb3VwLgogICAgICAgICAgICAgICAgICAgIGlmICh2aWV3T3B0Z3JvdXBzLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNhdmUgc2VsZWN0ZWQgdmFsdWUgYmVjYXVzZSB3aGVuIHZhbHVlIGlzIHNldCBiZWZvcmUgaXRlbXMgaW4gc2V0V2lkZ2V0T3B0aW9ucwogICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgc2VsZWN0ZWQgdmFsdWUgd291bGQgZ2V0IGxvc3QgaW4gaHRtbAogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWRPcHRpb24gPSB0aGlzLiR1c2VyQ29udHJvbC5maW5kKCdbc2VsZWN0ZWRdJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCJvcHRpb25bZGF0YS11c2VyLW9wdGlvbl0iKS5yZW1vdmUoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMCwgaiA9IDA7IGogPCB2YWwubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IHZhbFtqXTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQuc2F2ZSAhPSBBRl9PUFRHUk9VUF9OQU1FKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgb3B0aW9ucyB0byBTdHJpbmdbXSB3aGljaCB3aWxsIGJlIGxhdGVyIHN5bmNlZCB0byB0aGUgb3B0Z3JvdXAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRncm91cE9wdGlvbnMucHVzaChlbGVtZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2aWV3T3B0Z3JvdXAgPSB2aWV3T3B0Z3JvdXBzW2krK107CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIG9wdGdyb3VwIGlzIGxlc3MgdGhhbiB0aGUgcmVxdWlyZWQgb3B0Z3JvdXBzLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiB2aWV3T3B0Z3JvdXBzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2aWV3T3B0Z3JvdXAgPSB0aGlzLmFkZEdyb3VwKGVsZW1lbnQuZGlzcGxheSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBVbmRlZmluZWQgYXMgaXQgbWF5IG5vdCBvY2N1ciBldmVuIG9uY2Ugd2hlbiBsaXN0IGlzIHB1cmVseSBvZiBvcHRpb25zLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKCR2aWV3T3B0Z3JvdXApICYmICR2aWV3T3B0Z3JvdXAubGFiZWwgIT0gZWxlbWVudC5kaXNwbGF5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHZpZXdPcHRncm91cC5sYWJlbCA9IGVsZW1lbnQuZGlzcGxheSB8fCAnJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIHRvIHNraXAgdGhlIGZpcnN0IG9wdGdyb3VwLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGogIT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN5bmNzIG9wdGlvbnMgdG8gdGhlIHByZXYgb3B0Z3JvdXAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUHJldiBvcHRncm91cCBiZWNhdXNlIGN1cnJlbnQgb3B0Z3JvdXAgbWFya3MgdGhlIGVuZCBvZiBvcHRpb25zIG9mIHByZXYuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVPcHRpb25zKCRwcmVPcHRncm91cCwgb3B0Z3JvdXBPcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDbGVhciBvcHRpb25zIG9mIHRoZSBvcHRncm91cCBmb3IgbmV4dCBvcHRncm91cC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRncm91cE9wdGlvbnMgPSBbXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwcmVPcHRncm91cCA9ICR2aWV3T3B0Z3JvdXA7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gUmVtb3ZlcyBhbGwgZXh0cmEgb3B0Z3JvdXBzLgogICAgICAgICAgICAgICAgICAgIHdoaWxlIChpIDwgdmlld09wdGdyb3Vwcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZpZXdPcHRncm91cCA9IHZpZXdPcHRncm91cHNbaSsrXTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWxldGVHcm91cCgkdmlld09wdGdyb3VwLmxhYmVsKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy9BZGQgcmVtYWluaW5nIG9wdGlvbnMgdG8gcmVzcGVjdGl2ZSBvcHRncm91cC4KICAgICAgICAgICAgICAgICAgICBpZiAob3B0Z3JvdXBPcHRpb25zLmxlbmd0aCAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlT3B0aW9ucygkcHJlT3B0Z3JvdXAsIG9wdGdyb3VwT3B0aW9ucywgc2VsZWN0ZWRPcHRpb24pOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy9JbnRlbnRpb25hbGx5IGxlZnQgdGhlIHNlbGVjdGlvbiBjaGVjayAtPiBJIGFtIHJlbHlpbmcgb24gdGhlIGZhY3QgdGhhdCAidmFsdWUiIHN5bmMgZXZlbnQgaXMgY2FsbGVkIGFmdGVyICJpdGVtcyIgc3luYy4KICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgImRpc3BsYXlWYWx1ZSI6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicGxhY2Vob2xkZXIiOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICAgICAgLy8gb3ZlcnJpZGluZyB0aGUgZGVmYXVsdCBoYW5kbGluZyBvZiBwbGFjZSBob2xkZXIgb3B0aW9ucyBzZXR0ZXIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiYWNjZXNzIjogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIm9wZW4iIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJhcmlhLWRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAibm9uSW50ZXJhY3RpdmUiIDoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAicHJvdGVjdGVkIiA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInJlYWRPbmx5IiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJkaXNhYmxlZCIsICJkaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiYXJpYS1kaXNhYmxlZCIsICJ0cnVlIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCAgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQXR0cigiZGlzYWJsZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImFyaWEtZGlzYWJsZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSkKICAgICAgICB9LAoKICAgICAgICBnZXRFdmVudE1hcDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgcGFyZW50T3B0aW9uc01hcCA9ICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmdldEV2ZW50TWFwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSwgcGFyZW50T3B0aW9uc01hcCwgewogICAgICAgICAgICAgICAgImZvY3VzIjogW3hmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRU5URVJfRVZFTlQsIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfUFJFT1BFTl9FVkVOVF0sCiAgICAgICAgICAgICAgICAiY2hhbmdlIjogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQKICAgICAgICAgICAgfSkKICAgICAgICB9LAoKICAgICAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGV4aXN0aW5nSW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXMgPSB0aGlzLmVsZW1lbnQuZmluZCgic2VsZWN0IikuYXR0cigic3R5bGUiKSwKICAgICAgICAgICAgICAgIG5ld0lubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzLAogICAgICAgICAgICAgICAgY29tYmluZWRJbmxpbmVTdHlsZUF0dHJpYnV0ZVZhbHVlcywKICAgICAgICAgICAgICAgIHNpemUgPSAxOwoKICAgICAgICAgICAgdGhpcy5lbGVtZW50LmFkZENsYXNzKHRoaXMuX3dpZGdldE5hbWUpOwogICAgICAgICAgICB0aGlzLmVsZW1lbnQuY2hpbGRyZW4oKS5yZW1vdmUoKTsKCiAgICAgICAgICAgIHZhciBpbnB1dE5hbWUgPSBfLnVuaXF1ZUlkKCJzZWxlY3QiKSwgIC8vVW5pcXVlIElkCiAgICAgICAgICAgICAgICB0ZXh0U3R5bGUgPSB0aGlzLmdldE9yRWxzZSh0aGlzLiRkYXRhKHRoaXMuZWxlbWVudC5nZXQoMCksICJ4ZmFtb2RlbCIpLCAidGV4dHN0eWxlIiwgIiIpLAogICAgICAgICAgICAgICAgJHdpZGdldFNrZWxldG9uID0gJCh0aGlzLndpZGdldFNrZWxldG9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYXR0cignc3R5bGUnLCB0ZXh0U3R5bGUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCduYW1lJywgaW5wdXROYW1lKTsKICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLmVkaXRhYmxlKSB7CiAgICAgICAgICAgICAgICAkd2lkZ2V0U2tlbGV0b24uYWRkQ2xhc3MoJ2NvbWJvYm94Jyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5pdGVtcyAmJiB0aGlzLm9wdGlvbnMuaXRlbXMubGVuZ3RoPjApewogICAgICAgICAgICAgICAgc2l6ZSA9IHRoaXMub3B0aW9ucy5pdGVtcy5sZW5ndGgKICAgICAgICAgICAgfQogICAgICAgICAgICBpZih0aGlzLm9wdGlvbnMubXVsdGlTZWxlY3QpIHsKICAgICAgICAgICAgICAgICR3aWRnZXRTa2VsZXRvbi5hZGRDbGFzcygnbXVsdGlEcm9wZG93bicpOwogICAgICAgICAgICAgICAgJHdpZGdldFNrZWxldG9uLmF0dHIoJ211bHRpcGxlJywnbXVsdGlwbGUnKTsKICAgICAgICAgICAgICAgICR3aWRnZXRTa2VsZXRvbi5hdHRyKCdzaXplJyxzaXplKTsKICAgICAgICAgICAgICAgICR3aWRnZXRTa2VsZXRvbi5hdHRyKCdkYXRhLW11bHRpcGxlLXNlbGVjdGlvbicsInRydWUiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyICRwYXJFbCA9ICR3aWRnZXRTa2VsZXRvbjsKICAgICAgICAgICAgXy5lYWNoKHRoaXMub3B0aW9ucy5pdGVtcywgZnVuY3Rpb24oaXRlbSl7CiAgICAgICAgICAgICAgICB2YXIgc2F2ZUl0ZW0gPSBfLmlzU3RyaW5nKGl0ZW0uc2F2ZSkgPyBpdGVtLnNhdmUucmVwbGFjZSgvXCIvZywgIiZxdW90OyIpIDogIiI7CiAgICAgICAgICAgICAgICBpZiAoc2F2ZUl0ZW0gPT09IHRoaXMuQUZfT1BUR1JPVVBfTkFNRSl7IC8vIGFzc3VtaW5nIG9wdGdyb3VwcyBhcHBlYXIgYmVmb3JlIG9wdGlvbnMKICAgICAgICAgICAgICAgICAgICAkcGFyRWwgPSAkKHRoaXMub3B0R3JvdXBTa2VsZXRvbikuYXR0cignbGFiZWwnLCBpdGVtLmRpc3BsYXkpLmFwcGVuZFRvKCR3aWRnZXRTa2VsZXRvbik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICQodGhpcy5vcHRpb25Ta2VsZXRvbikudmFsKHNhdmVJdGVtKS50ZXh0KGl0ZW0uZGlzcGxheSkuYXBwZW5kVG8oJHBhckVsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSx0aGlzKTsKCiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmQoJHdpZGdldFNrZWxldG9uKTsKCiAgICAgICAgICAgIHZhciBjb250cm9sID0gdGhpcy5lbGVtZW50LmNoaWxkcmVuKCkuZXEoMCkuYXR0cigibmFtZSIsIHRoaXMub3B0aW9ucy5uYW1lKTsKICAgICAgICAgICAgdGhpcy5fYXR0YWNoRXZlbnRIYW5kbGVycyhjb250cm9sKTsKICAgICAgICAgICAgbmV3SW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXMgPSB0aGlzLmVsZW1lbnQuZmluZCgic2VsZWN0IikuYXR0cigic3R5bGUiKTsKICAgICAgICAgICAgLy9hcHBlbmQgdGhlIHByZXZpb3VzIGlubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzIHRvIG5ld0lubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzIHNvIHRoYXQgdGhlIGlubGluZSBzdHlsZXMKICAgICAgICAgICAgLy9hZGRlZCBmcm9tIHRoZSBkaWFsb2cgYXJlIGFwcGxpZWQuCiAgICAgICAgICAgIGNvbWJpbmVkSW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXMgPSBuZXdJbmxpbmVTdHlsZUF0dHJpYnV0ZVZhbHVlcyArIGV4aXN0aW5nSW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXM7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5maW5kKCJzZWxlY3QiKS5hdHRyKCJzdHlsZSIsIGNvbWJpbmVkSW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXMpOwogICAgICAgICAgICByZXR1cm4gY29udHJvbDsKICAgICAgICB9LAoKICAgICAgICAvL3N5bmNzIHRoZSBvcHRpb25zIHRvIHRoZSBvcHRncm91cCBkeW5hbWljYWxseS4KICAgICAgICBoYW5kbGVPcHRpb25zIDogZnVuY3Rpb24gKCR2aWV3T3B0Z3JvdXAsIHZhbCwgc2VsZWN0ZWRPcHRpb24pIHsKICAgICAgICAgICAgLy9XaGVuIHRoZSBsaXN0IHNvIGZhciBjb25zaXN0cyBwdXJlbHkgb2Ygb3B0aW9ucy4KICAgICAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoJHZpZXdPcHRncm91cCkpIHsKICAgICAgICAgICAgICAgICR2aWV3T3B0Z3JvdXAgPSB0aGlzLiR1c2VyQ29udHJvbFswXTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgdmlld09wdGlvbnMgPSAkKCJvcHRpb25bZGF0YS11c2VyLW9wdGlvbl0iLCAkdmlld09wdGdyb3VwKTsKICAgICAgICAgICAgLy9TeW5jcyB0aGUgdmFsdWUgb2Ygb3B0aW9ucy4KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGogPSAwOyBpIDwgdmlld09wdGlvbnMubGVuZ3RoICYmIGogPCB2YWwubGVuZ3RoOyBpKyssIGorKykgewogICAgICAgICAgICAgICAgdmFyICR2aWV3T3B0aW9uID0gdmlld09wdGlvbnNbaV07CiAgICAgICAgICAgICAgICB2YXIgZWxlbWVudCA9IHZhbFtqXTsKICAgICAgICAgICAgICAgIGlmICgkdmlld09wdGlvbi50ZXh0ICE9IGVsZW1lbnQuZGlzcGxheSkgewogICAgICAgICAgICAgICAgICAgICR2aWV3T3B0aW9uLnRleHQgPSBlbGVtZW50LmRpc3BsYXkgfHwgJyc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJHZpZXdPcHRpb24udmFsdWUgIT0gZWxlbWVudC5zYXZlKSB7CiAgICAgICAgICAgICAgICAgICAgJHZpZXdPcHRpb24udmFsdWUgPSBlbGVtZW50LnNhdmUgfHwgJyc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9EZWxldGVzIG9wdGlvbnMgaWYgY291bnQgaXMgbW9yZSB0aGFuIHJlcXVpcmVkLgogICAgICAgICAgICB3aGlsZSAoaSA8IHZpZXdPcHRpb25zLmxlbmd0aCkgewogICAgICAgICAgICAgICAgdGhpcy5kZWxldGVPcHRpb24odmlld09wdGlvbnNbaSsrXSkKICAgICAgICAgICAgfQogICAgICAgICAgICAvL0FkZCBvcHRpb25zIGlmIGNvdW50IGlzIGxlc3MgdGhhbiByZXF1aXJlZC4KICAgICAgICAgICAgd2hpbGUgKGogPCB2YWwubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB0aGlzLmFkZE9wdGlvbigkdmlld09wdGdyb3VwLCB2YWxbaisrXSwgc2VsZWN0ZWRPcHRpb24pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFNldCBlbXB0eSB2YWx1ZSB0byBkcm9wZG93biBpZiBwbGFjZWhvbGRlciBhbmQgZGVmYXVsdCB2YWx1ZSBpcyBub3QgcHJlc2VudAogICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnBsYWNlaG9sZGVyLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIAlpZiAodGhpcy5jaGVja0ZvckVtcHR5VmFsdWUodGhpcy5vcHRpb25zLnZhbHVlKSkgewogICAgICAgICAgICAJCXRoaXMuJHVzZXJDb250cm9sWzBdLnZhbHVlID0gIiI7CiAgICAgICAgICAgIAl9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBhZGRPcHRpb24gOiBmdW5jdGlvbiAoJHZpZXdPcHRncm91cCwgZWxlbWVudCwgc2VsZWN0ZWRPcHRpb24pIHsKICAgICAgICAgICAgdmFyICRuZXdPcHRpb24gPSAkKHRoaXMub3B0aW9uU2tlbGV0b24pLnZhbChlbGVtZW50LnNhdmUpLnRleHQoZWxlbWVudC5kaXNwbGF5KTsKICAgICAgICAgICAgJG5ld09wdGlvbi5hcHBlbmRUbygkdmlld09wdGdyb3VwKTsKICAgICAgICAgICAgaWYoc2VsZWN0ZWRPcHRpb24pIHsKICAgICAgICAgICAgICAgIGlmKGVsZW1lbnQuc2F2ZSA9PT0gc2VsZWN0ZWRPcHRpb24udmFsKCkgJiYgZWxlbWVudC5kaXNwbGF5ID09PSBzZWxlY3RlZE9wdGlvbi50ZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICAkbmV3T3B0aW9uLnByb3AoInNlbGVjdGVkIiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2luY2UgdGhlIGRpc3BsYXlWYWx1ZSBpcyBhICdcbicgc2VwYXJhdGVkIHN0cmluZyBvZiBzZWxlY3RlZCB2YWx1ZXMgaW4gY2FzZSBvZiBtdWx0aVNlbGVjdCwKICAgICAgICAgICAgLy8gd2UgY29udmVydCBpdCB0byBhbiBhcnJheSBhbmQgY2hlY2sgd2hldGhlciB0aGF0IGFycmF5IGNvbnRhaW5zIHRoZSBzYXZlIHZhbHVlIG9mIHRoZSBlbGVtZW50CiAgICAgICAgICAgIHZhciB2YWx1ZXM7CiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMudmFsdWUgJiYgXy5pc1N0cmluZyh0aGlzLm9wdGlvbnMudmFsdWUpKSB7CiAgICAgICAgICAgICAgICB2YWx1ZXMgPSB0aGlzLm9wdGlvbnMudmFsdWUuc3BsaXQoJ1xuJyk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoXy5pc0FycmF5KHRoaXMub3B0aW9ucy52YWx1ZSkpIHsKICAgICAgICAgICAgICAgIC8vIEluIHRoZSBjYXNlIG9mIEFGIHdlIGhhdmUgdmFsdWUvZGlzcGxheVZhbHVlIGFzIGFuIGFycmF5CiAgICAgICAgICAgICAgICB2YWx1ZXMgPSB0aGlzLm9wdGlvbnMudmFsdWUKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodmFsdWVzICYmIHZhbHVlcy5pbmRleE9mKGVsZW1lbnQuc2F2ZSkgPj0gMCkgewogICAgICAgICAgICAgICAgLy9EZWxldGUgZW1wdHlWYWx1ZSB3aXRoIG5vIHBsYWNlaG9sZGVyIHRleHQgY29uZmlndXJlZCBhbmQgdmFsdWUgaXMgZm91bmQgaW4gb3B0aW9ucwogICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wbGFjZWhvbGRlci5sZW5ndGggPT0gMCAmJiB0aGlzLiR1c2VyQ29udHJvbC5jaGlsZHJlbignW2RhdGEtZW1wdHktb3B0aW9uXScpLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbFswXS5yZW1vdmVDaGlsZCh0aGlzLiR1c2VyQ29udHJvbC5jaGlsZHJlbignW2RhdGEtZW1wdHktb3B0aW9uXScpWzBdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCkuZmlsdGVyKGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlID09IGVsZW1lbnQuc2F2ZTsKICAgICAgICAgICAgICAgIH0pLnByb3AoInNlbGVjdGVkIiwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBkZWxldGVPcHRpb246IGZ1bmN0aW9uICgkdmlld09wdGlvbikgewogICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5maW5kKCdvcHRpb25bdmFsdWU9Jyskdmlld09wdGlvbi52YWx1ZSsnXScpLnJlbW92ZSgpOwogICAgICAgIH0sCgogICAgICAgIGNoZWNrRm9yRW1wdHlWYWx1ZTogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgaWYgKCh2YWx1ZSAmJiBfLmlzQXJyYXkodmFsdWUpICYmIHZhbHVlWzBdID09IG51bGwpIHx8ICh0aGlzLm9wdGlvbnMudmFsdWUgPT0gbnVsbCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIGFkZEdyb3VwOiBmdW5jdGlvbihsYWJlbCkgewogICAgICAgICAgICAvL0NyZWF0ZXMgYSBvcHRncm91cCBOb2RlLgogICAgICAgICAgICB2YXIgb3B0aW9uR3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJPUFRHUk9VUCIpOwogICAgICAgICAgICBvcHRpb25Hcm91cC5sYWJlbCA9IGxhYmVsOwogICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbFswXS5hcHBlbmRDaGlsZChvcHRpb25Hcm91cCk7CiAgICAgICAgICAgIHJldHVybiBvcHRpb25Hcm91cDsKICAgICAgICB9LAoKICAgICAgICBkZWxldGVHcm91cDogZnVuY3Rpb24obGFiZWwpIHsKICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oKS5yZW1vdmUoJ29wdGdyb3VwW2xhYmVsPScrbGFiZWwrJ10nKTsKICAgICAgICB9LAoKICAgICAgICBhZGRJdGVtOiBmdW5jdGlvbihpdGVtVmFsdWVzKSB7CiAgICAgICAgICAgIHZhciBuZXdPcHRpb24gPSBuZXcgT3B0aW9uKGl0ZW1WYWx1ZXMuc0Rpc3BsYXlWYWwgfHwgJycsIGl0ZW1WYWx1ZXMuc1NhdmVWYWwgfHwgJycpLAogICAgICAgICAgICAgICAgdmFsID0gdGhpcy5vcHRpb25zLnZhbHVlOwogICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbFswXS5hZGQobmV3T3B0aW9uLCBudWxsKTsKICAgICAgICAgICAgLy8gaWYgaXRlbSBoYXMgc2FtZSB2YWx1ZSBhcyBwcmVzZW50IGluIG9wdGlvbnMgdGhlbiBtYXJrIGl0IGFzIHNlbGVjdGVkCiAgICAgICAgICAgIGlmIChfLmNvbnRhaW5zKHZhbCwgaXRlbVZhbHVlcy5zU2F2ZVZhbCkpIHsKICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmZpbmQoIm9wdGlvblt2YWx1ZT0iICsgaXRlbVZhbHVlcy5zU2F2ZVZhbCArICJdIikucHJvcCgic2VsZWN0ZWQiLCB0cnVlKTsKICAgICAgICAgICAgICAgIHZhciBlbXB0eVZhbHVlID0gdGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oJ1tkYXRhLWVtcHR5LW9wdGlvbl0nKTsKICAgICAgICAgICAgICAgIGlmIChlbXB0eVZhbHVlLmxlbmd0aCA+IDAgJiYgZW1wdHlWYWx1ZS52YWwoKSA9PT0gaXRlbVZhbHVlcy5zU2F2ZVZhbCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sWzBdLnJlbW92ZUNoaWxkKGVtcHR5VmFsdWVbMF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKCh2YWwgPT0gbnVsbCB8fCB2YWwubGVuZ3RoID09IDAgfHwgdmFsWzBdID09IG51bGwpICYmIHRoaXMub3B0aW9ucy5wbGFjZWhvbGRlci5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgLy8gVmFsdWUgc2hvdWxkIHJlbWFpbiBlbXB0eSBpZiBvcHRpb24gaXMgbm90IGFscmVhZHkgc2VsZWN0ZWQgJiBwbGFjZWhvbGRlciBpcyBlbXB0eQogICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2xbMF0udmFsdWUgPSAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNsZWFySXRlbXM6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgLy9EZWxldGluZyBhbGwgdGhlIG9wdGlvbnMgaW5jbHVkaW5nIG9wdEdyb3VwIGV4Y2VwdCB0aGUgZW1wdHkgdmFsdWUuCiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCkubm90KCdbZGF0YS1lbXB0eS1vcHRpb25dJykucmVtb3ZlKCk7CiAgICAgICAgfSwKCiAgICAgICAgZGVsZXRlSXRlbTogZnVuY3Rpb24gKG5JbmRleCkgewogICAgICAgICAgICAvL2NoZWNrIGZvciBlbXB0eVZhbHVlIGluc3RlYWQgb2YgYmxpbmRseSBkb2luZyArIDEKICAgICAgICAgICAgaWYgKHRoaXMuJHVzZXJDb250cm9sWzBdLml0ZW0oMCkgJiYgdGhpcy4kdXNlckNvbnRyb2xbMF0uaXRlbSgwKS5pZCA9PSAiZW1wdHlWYWx1ZSIpCiAgICAgICAgICAgICAgICBuSW5kZXggPSBuSW5kZXggKyAxOwogICAgICAgICAgICAvL2lmIHRoZXJlIGlzIGVtcHR5VmFsdWUgZWxlbWVudCB0aGVuIGp1c3QgZGVsZXRlIG9uZSBpbmRleCBoaWdoZXIKICAgICAgICAgICAgLy90aGlzIGNoZWNrIGlzIG11c3QgaW5zdGVhZCBvZiBibGluZGx5IGluY3JlYXNpbmcgdGhlIGluZGV4IGJ5IDEgYmVjYXVzZSBOV0tMaXN0Qm94IGV4dGVuZHMgdGhpcyBjbGFzcyBhbmQgdGhhdCBkb2Vzbid0IG1haW50YWluIGVtcHR5VmFsdWUKICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2xbMF0ucmVtb3ZlKG5JbmRleCk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0Q29tbWl0VmFsdWU6IGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICB2YXIgdmFsdWUgPSAkKCJvcHRpb246c2VsZWN0ZWQiLCB0aGlzLiR1c2VyQ29udHJvbCkubWFwKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkKHRoaXMpLnZhbCgpOwogICAgICAgICAgICB9KS5nZXQoKTsKICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgIH0sCgogICAgICAgIHNob3dEaXNwbGF5VmFsdWU6IGZ1bmN0aW9uICgpIHsKICAgICAgICB9LAoKICAgICAgICBkZXN0cm95OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC4KICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKHRoaXMuX3dpZGdldE5hbWUpLgogICAgICAgICAgICAgICAgY2hpbGRyZW4oKS5yZW1vdmUoKS4KICAgICAgICAgICAgICAgIHRleHQoIiIpOwoKICAgICAgICAgICAgLy8gY2FsbCB0aGUgYmFzZSBkZXN0cm95IGZ1bmN0aW9uCiAgICAgICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmRlc3Ryb3kuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlS2V5RG93bjogZnVuY3Rpb24gKGV2ZW50KSB7CgogICAgICAgICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PSAxMykgewogICAgICAgICAgICAgICAgLy9kbyBub3RoaW5nCiAgICAgICAgICAgICAgICAvL2p1c3Qgb3ZlcnJpZGUgdGhlIHJldHVybiBrZXkgYmVoYXZpb3VyIGFuZCBvdmVyIHRvIGRlZmF1bHRXaWRnZXQgZm9yIHJlc3Qgb2YgdGhlIHN0dWZmLgogICAgICAgICAgICAgICAgLy9yZXR1cm4ga2V5IGlzIGludGVyY2VwdGVkIHRvIGF2b2lkIHN1Ym1pc3Npb24gb2YgZm9ybSB3aGljaCBpcyBkZWZhdWx0IGJlaGF2aW9yIG9mIGh0bWwgZm9ybSBlbGVtZW50CiAgICAgICAgICAgICAgICAvL2J1dCBhcyBhIHNpZGUgZWZmZWN0IGl0IGFsc28gc3RvcHMgdGhlIGNsb3Npbmcgb2YgZHJvcCBkb3duIG9ubHkgaW4gSUUgLT4gcHJvYmFibHkgSSBzaG91bGQgdXNlIElFIGNvbmRpdGlvbiBidXQKICAgICAgICAgICAgICAgIC8vIHRoaXMgY29kZSB3b3JrcyBmaW5lIGluICAgICAgICAgIGNocm9tZSBhcyB3ZWxsIHNvIGtlZXBpbmcgaXQgdGhhdCB3YXkuCiAgICAgICAgICAgICAgICAvL3dhdHNvbiBidWcjMzY3NTE0MQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLl9oYW5kbGVLZXlEb3duLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfSwKCiAgICAgICAgLy8gQ1EtNTE0NjIgOiBmb2N1cyBhbmQgY29tbWl0IGV2ZW50IChjaGFuZ2UpIGhhcHBlbiB0b2dldGhlciBoZW5jZSBmaXJzdCBzZWxlY3Rpb24gd2FzIG1vZGlmeWluZyB0aGUgdmFsdWUKICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCBmb2N1cyB0byBtb2RpZnkgdGhlIHZhbHVlIHRoYXQgaXMgYWJvdXQgdG8gYmUgY29tbWl0dGVkCiAgICAgICAgc2hvd1ZhbHVlIDogZnVuY3Rpb24oKSB7CgogICAgICAgIH0KICAgIH0pOwp9KSgkLCBfKTsKKGZ1bmN0aW9uKCQsIF8pewoJJC53aWRnZXQoICJ4ZmFXaWRnZXQubGlzdEJveCIsICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQsIHsKCiAgICBfd2lkZ2V0TmFtZTogImxpc3RCb3hXaWRnZXQiLAoKICAgIG9wdGlvbnMgOiB7CiAgICAgICAgdmFsdWUgOiBbXSwKICAgICAgICBpdGVtcyA6IFtdLAogICAgICAgIG11bHRpU2VsZWN0IDogZmFsc2UKICAgIH0sCgogICAgZ2V0T3B0aW9uc01hcDogZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICByZXR1cm4gJC5leHRlbmQoe30scGFyZW50T3B0aW9uc01hcCx7CiAgICAgICAgICAgICJ3aWR0aCIgOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgIC8vQnVnIzM1OTc3NzEuIHNldHRpbmcgdGhlIGhlaWdodCBtb3JlIHRoYW4gMC45NSBicmluZ3Mgc2Nyb2xsYmFyCiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMud2lkdGggPSB2YWwqMC45NQogICAgICAgICAgICAgICAgcGFyZW50T3B0aW9uc01hcC53aWR0aC5hcHBseSh0aGlzLFt0aGlzLm9wdGlvbnMud2lkdGhdKQogICAgICAgICAgICB9LAogICAgICAgICAgICAiYWNjZXNzIiA6IGZ1bmN0aW9uKCkge30sCiAgICAgICAgICAgICJ2YWx1ZSI6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAgICAgdmFyIG5ld1ZhbHVlcyA9IHRoaXMub3B0aW9ucy52YWx1ZSwKICAgICAgICAgICAgICAgICAgICBzZWxmID0gdGhpcywKICAgICAgICAgICAgICAgICAgICB0YWJTZXQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGlmKCFfLmlzQXJyYXkobmV3VmFsdWVzKSkKICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZXMgPSBbbmV3VmFsdWVzXTsKICAgICAgICAgICAgICAgIHZhciB0YWJTZXQKICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpewogICAgICAgICAgICAgICAgICAgIHZhciBzYXZlVmFsID0gJCh0aGlzKS5hdHRyKCJkYXRhLXNhdmUiKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyB2YWx1ZSBpcyBwcmVzZW50IGluIG9wdGlvbnMgdmFsdWUgYXJyYXkKICAgICAgICAgICAgICAgICAgICBpZihuZXdWYWx1ZXMgJiYgXy5jb250YWlucyhuZXdWYWx1ZXMsIHNhdmVWYWwpKXsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fc2VsZWN0TGlzdEl0ZW0oJCh0aGlzKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhYlNldCA9IHRydWU7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIHNlbGVjdGVkIGRhdGEgYXR0cmlidXRlIHRvIHRydWUuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJC5kYXRhKHRoaXMsICJfeGZhSW5pdGlhbGl6ZWQiKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9Jbml0aWFsaXplZCBkYXRhLSBhdHRyaWJ1dGVzIHBhcnNlIGZvciBvbmNlIHVzaW5nIHRoaXMgY2FsbC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5leHQgb253YXJkIGRvbid0IHVzZSB0aGlzLiBJbnN0ZWFkIHVzZSAkLmRhdGEgd2hpY2ggaXMgY2hlYXAvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLmRhdGEoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQuZGF0YSh0aGlzLCAiX3hmYUluaXRpYWxpemVkIiwgdHJ1ZSk7IC8vTWFyayB0aGUgZWxlbWVudCB0byBzYXkgdGhhdCBkYXRhIGhhcyBiZWVuIGluaXRpYWxpemVkLgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICQuZGF0YSh0aGlzLCAic2VsZWN0ZWQiLCB0cnVlKTsKCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcykucmVtb3ZlQ2xhc3MoIml0ZW0tc2VsZWN0ZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5hZGRDbGFzcygiaXRlbS1zZWxlY3RhYmxlIik7CiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcykuYXR0cigidGFiSW5kZXgiLCAiLTEiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGlmKCF0YWJTZXQpIHsKICAgICAgICAgICAgICAgICAgICAkKHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCkuZ2V0KDApKS5hdHRyKCJ0YWJJbmRleCIsIHRoaXMub3B0aW9ucy50YWJJbmRleCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAiaXRlbXMiIDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgICAgICBpZighXy5pc0FycmF5KHZhbCkpCiAgICAgICAgICAgICAgICAgICAgdmFsID0gW3ZhbF07CiAgICAgICAgICAgICAgICB2YXIgdmlld0l0ZW1zID0gdGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oKTsKCiAgICAgICAgICAgICAgICAvL2lmIG51bWJlciBvZiBpdGVtcyBhcmUgbm90IHNhbWUgaW4gbW9kZWwgYW5kIHZpZXcgdGhlbiBiYWxhbmNlIGl0CiAgICAgICAgICAgICAgICBpZigodmlld0l0ZW1zLmxlbmd0aCkgPiB2YWwubGVuZ3RoKXsKICAgICAgICAgICAgICAgICAgICBmb3IodmFyIGk9dmlld0l0ZW1zLmxlbmd0aDsgaSA+ICB2YWwubGVuZ3RoOyBpLS0pewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlbGV0ZUl0ZW0oaS0xKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKCh2aWV3SXRlbXMubGVuZ3RoKSA8IHZhbC5sZW5ndGgpewogICAgICAgICAgICAgICAgICAgIGZvcih2YXIgaT12aWV3SXRlbXMubGVuZ3RoOyBpIDwgKHZhbC5sZW5ndGgpOyBpKyspewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZEl0ZW0oe3NEaXNwbGF5VmFsOiB2YWxbaV0uZGlzcGxheSwgc1NhdmVWYWw6IHZhbFtpXS5zYXZlfSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIF8uZWFjaCh2YWwsIGZ1bmN0aW9uKGVsZW1lbnQsIGluZGV4KXsKICAgICAgICAgICAgICAgICAgICB2YXIgJHZpZXdJdGVtID0gJCh2aWV3SXRlbXNbaW5kZXhdKTsKICAgICAgICAgICAgICAgICAgICBpZiggJHZpZXdJdGVtLnRleHQoKSAhPSBlbGVtZW50LmRpc3BsYXkpewogICAgICAgICAgICAgICAgICAgICAgICAkdmlld0l0ZW0udGV4dChlbGVtZW50LmRpc3BsYXkgfHwgJycpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYoICR2aWV3SXRlbS5hdHRyKCJkYXRhLXNhdmUiKSAhPSBlbGVtZW50LnNhdmUpewogICAgICAgICAgICAgICAgICAgICAgICAkdmlld0l0ZW0uYXR0cigiZGF0YS1zYXZlIiwgZWxlbWVudC5zYXZlIHx8ICcnKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAvL0ludGVudGlvbmFsbHkgbGVmdCB0aGUgc2VsZWN0aW9uIGNoZWNrIC0+IEkgYW0gcmVseWluZyBvbiB0aGUgZmFjdCB0aGF0ICJ2YWx1ZSIgc3luYyBldmVudCBpcyBjYWxsZWQgYWZ0ZXIgIml0ZW1zIiBzeW5jLgogICAgICAgICAgICB9LAoKICAgICAgICAgICAgImRpc3BsYXlWYWx1ZSIgOiBmdW5jdGlvbigpezt9LAoKICAgICAgICAgICAgInRhYkluZGV4IjogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWRJdGVtID0gdGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oIi5pdGVtLXNlbGVjdGVkIiksCiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPXRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCkKICAgICAgICAgICAgICAgIGlmKHNlbGVjdGVkSXRlbS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEl0ZW0uZXEoMCkuYXR0cigidGFiSW5kZXgiLCB0aGlzLm9wdGlvbnMudGFiSW5kZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZihjaGlsZHJlbi5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4uZXEoMCkuYXR0cigidGFiSW5kZXgiLCB0aGlzLm9wdGlvbnMudGFiSW5kZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSkKICAgIH0sCgogICAgZ2V0RXZlbnRNYXA6IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0RXZlbnRNYXAuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSxwYXJlbnRPcHRpb25zTWFwLHsKICAgICAgICAgICAgImxpc3Rib3hlbnRlciI6eGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FTlRFUl9FVkVOVCwKICAgICAgICAgICAgImxpc3Rib3hleGl0Ijp4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VYSVRfRVZFTlQsCiAgICAgICAgICAgICJsaXN0Ym94Y2hhbmdlIjp4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NIQU5HRV9FVkVOVCwKICAgICAgICAgICAgImZvY3VzIjpudWxsLAogICAgICAgICAgICAiYmx1ciI6bnVsbAogICAgICAgIH0pCiAgICB9LAoKICAgIHNob3dEaXNwbGF5VmFsdWUgOiBmdW5jdGlvbigpIHsKICAgICAgICB9LAoKICAgIHJlbmRlciA6IGZ1bmN0aW9uKCkgewogICAgICAgIHRoaXMuZWxlbWVudC5hZGRDbGFzcyggdGhpcy5fd2lkZ2V0TmFtZSk7CiAgICAgICAgdGhpcy5lbGVtZW50LmNoaWxkcmVuKCkucmVtb3ZlKCk7CgogICAgICAgIC8vVE9ETzogYWRkIGEgZnVuY3Rpb24gZm9yIGdldGluZyB0ZXh0U3R5bGUKICAgICAgICB2YXIgdGV4dFN0eWxlID0gdGhpcy5nZXRPckVsc2UodGhpcy4kZGF0YSh0aGlzLmVsZW1lbnQuZ2V0KDApLCAieGZhbW9kZWwiKSwgInRleHRzdHlsZSIsICIiKSwKICAgICAgICAgICAgdGhhdCA9IHRoaXMsCiAgICAgICAgICAgIC8vQnVnIzM1OTc3NzEgd2lkdGggYW5kIGhlaWdodCBhcmUgcHJvdmlkZWQgYnkgdGhlIHZpZXcgaXRzZWxmLgogICAgICAgICAgICBsaXN0RWxUZW1wbGF0ZSA9CiAgICAgICAgICAgICc8b2wgc3R5bGU9InBvc2l0aW9uOmFic29sdXRlOzwlPXRleHRTdHlsZSU+IiByb2xlPSJsaXN0Ym94Ij4nICsKICAgICAgICAgICAgICAgICc8JSBfLmVhY2goaXRlbXMsIGZ1bmN0aW9uKGl0ZW0peyAlPicgKwogICAgICAgICAgICAgICAgJzwlIHZhciBzYXZlSXRlbSA9IGl0ZW0uc2F2ZSA/IGl0ZW0uc2F2ZS5yZXBsYWNlKC9cIi9nLCImcXVvdDsiKTpudWxsICU+JysKICAgICAgICAgICAgICAgICAgICAnPGxpIHJvbGU9Im9wdGlvbiIgZGF0YS1zYXZlPSI8JSBwcmludChzYXZlSXRlbSkgJT4iIGRhdGEtc2VsZWN0ZWQ9ImZhbHNlIj48JSBwcmludChpdGVtLmRpc3BsYXkpICU+PC9saT4nKwogICAgICAgICAgICAgICAgJzwlfSklPicrCiAgICAgICAgICAgICc8L29sPicsCiAgICAgICAgICAgIGNvbXBpbGVkTGlzdEVsVGVtcGxhdGUgPSBfLnRlbXBsYXRlKGxpc3RFbFRlbXBsYXRlKSwKICAgICAgICAgICAgdGVtcGxhdGVPcHRpb25zID0gXy5leHRlbmQoewogICAgICAgICAgICAgICAgInRleHRTdHlsZSIgOiB0ZXh0U3R5bGUKICAgICAgICAgICAgICAgIH0sIHRoaXMub3B0aW9ucyksCiAgICAgICAgICAgIHJlc29sdmVkTGlzdEVsID0gY29tcGlsZWRMaXN0RWxUZW1wbGF0ZSh0ZW1wbGF0ZU9wdGlvbnMpOwogICAgICAgIHRoYXQuZWxlbWVudC5odG1sKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5lbmNvZGVTY3JpcHRhYmxlVGFncyhyZXNvbHZlZExpc3RFbCkpOwogICAgICAgIHZhciBjb250cm9sID0gJCh0aGF0LmVsZW1lbnQuY2hpbGRyZW4oKS5nZXQoMCkpLmF0dHIoIm5hbWUiLHRoaXMub3B0aW9ucy5uYW1lKTsKICAgICAgICB0aGlzLl9hdHRhY2hFdmVudEhhbmRsZXJzKGNvbnRyb2wpOwogICAgICAgIHJldHVybiBjb250cm9sCiAgICB9LAoKICAgIGZvY3VzOiBmdW5jdGlvbigpIHsKICAgICAgICBpZih0aGlzLiR1c2VyQ29udHJvbC5jaGlsZHJlbigiLml0ZW0tc2VsZWN0ZWQiKS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCIuaXRlbS1zZWxlY3RlZCIpWzBdLmZvY3VzKCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYodGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oKS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKClbMF0uZm9jdXMoKTsKICAgICAgICB9CiAgICB9LAoKICAgIGFkZEl0ZW0gOiBmdW5jdGlvbihpdGVtVmFsdWVzKXsKICAgICAgICAkKCI8bGk+PC9saT4iKQogICAgICAgICAgICAuYXR0cigiZGF0YS1zYXZlIiwgaXRlbVZhbHVlcy5zU2F2ZVZhbCB8fCAnJykKICAgICAgICAgICAgLnRleHQoaXRlbVZhbHVlcy5zRGlzcGxheVZhbCB8fCAnJykKICAgICAgICAgICAgLmFwcGVuZFRvKHRoaXMuJHVzZXJDb250cm9sKQogICAgICAgICAgICAuY2xpY2soJC5wcm94eSh0aGlzLl9oYW5kbGVJdGVtQ2xpY2ssIHRoaXMpKQogICAgICAgICAgICAuZm9jdXMoJC5wcm94eSh0aGlzLl9oYW5kbGVJdGVtRm9jdXMsIHRoaXMpKTsKCiAgICAgICAgLy8gYWRkIG5ldyBpdGVtIGFzIHNlbGVjdGVkIGlmIHRoZSB2YWx1ZSBpcyBhbHJlYWR5IHByZXNlbnQgaW4gb3B0aW9ucwogICAgICAgIGlmIChfLmNvbnRhaW5zKHRoaXMub3B0aW9ucy52YWx1ZSwgaXRlbVZhbHVlcy5zU2F2ZVZhbCkpIHsKICAgICAgICAgICAgdGhpcy5fc2VsZWN0TGlzdEl0ZW0odGhpcy4kdXNlckNvbnRyb2wuZmluZCgiW2RhdGEtc2F2ZT0iICsgaXRlbVZhbHVlcy5zU2F2ZVZhbCsgIl0iKSk7CiAgICAgICAgfQogICAgfSwKCiAgICBjbGVhckl0ZW1zIDogZnVuY3Rpb24oKXsKICAgICAgICAkKHRoaXMuJHVzZXJDb250cm9sKS5lbXB0eSgpOwogICAgfSwKCiAgICBkZWxldGVJdGVtIDogZnVuY3Rpb24obkluZGV4KXsKICAgICAgICAkKHRoaXMuJHVzZXJDb250cm9sKS5jaGlsZHJlbignbGknKS5lYWNoKGZ1bmN0aW9uKGluZGV4LGVsZW1lbnQpewogICAgICAgICAgICBpZihpbmRleD09bkluZGV4KXsKICAgICAgICAgICAgICAgICQoZWxlbWVudCkub2ZmKCJjbGljayIpLm9mZigiZm9jdXMiKS5yZW1vdmUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0pCiAgICB9LAoKCiAgICBfYXR0YWNoRXZlbnRIYW5kbGVycyA6IGZ1bmN0aW9uKCRjb250cm9sKXsKICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICAgICAgJGNvbnRyb2wua2V5ZG93bigkLnByb3h5KHRoaXMuX2hvdEtleXMsdGhpcykpCiAgICAgICAgICAgIC5jaGlsZHJlbigpLm9uKCJtb3VzZWRvd24iLGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIGlmKHNlbGYuaW5Gb2N1cyA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubW91c2VEb3duID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICAuY2xpY2soJC5wcm94eSh0aGlzLl9oYW5kbGVJdGVtQ2xpY2ssIHRoaXMpKQogICAgICAgICAgICAuZm9jdXMoJC5wcm94eSh0aGlzLl9oYW5kbGVJdGVtRm9jdXMsIHRoaXMpKQogICAgICAgICAgICAuYmx1cigkLnByb3h5KHRoaXMuX2hhbmRsZUZvY3VzT3V0LHRoaXMpKQoKICAgIH0sCgogICAgIF9ob3RLZXlzIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICBpZih0aGlzLm9wdGlvbnMuYWNjZXNzICE9ICJvcGVuIikKICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgaWYodGhpcy5pdGVtSW5Gb2N1cyl7CiAgICAgICAgICAgICBzd2l0Y2goZXZlbnQud2hpY2gpIHsKICAgICAgICAgICAgICAgICBjYXNlIDM4OiAvL2Fycm93IHVwCiAgICAgICAgICAgICAgICAgICAgIHZhciBwcmV2U2libGluZyA9ICQodGhpcy5pdGVtSW5Gb2N1cykucHJldigpOwogICAgICAgICAgICAgICAgICAgICBpZihwcmV2U2libGluZyl7CiAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmtleURvd24gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgcHJldlNpYmxpbmcuZm9jdXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMua2V5RG93biA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgIGNhc2UgNDA6IC8vYXJyb3cgZG93bgogICAgICAgICAgICAgICAgICAgICB2YXIgbmV4dFNpYmxpbmcgPSAkKHRoaXMuaXRlbUluRm9jdXMpLm5leHQoKTsKICAgICAgICAgICAgICAgICAgICAgaWYobmV4dFNpYmxpbmcpewogICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5rZXlEb3duID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRTaWJsaW5nLmZvY3VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmtleURvd24gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICBjYXNlIDkxOiAvL2xlZnQgYXJyb3cKICAgICAgICAgICAgICAgICBjYXNlIDkyOiAvL3JpZ2h0IGFycm93CiAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgIGNhc2UgMzI6CiAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3RvZ2dsZUl0ZW0odGhpcy5pdGVtSW5Gb2N1cyk7CiAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICB9CiAgICAgICAgIH0KICAgICB9LAoKICAgICBfdG9nZ2xlSXRlbTogZnVuY3Rpb24oaXRlbSkgewogICAgICAgICB2YXIgJGl0ZW0gPSAkKGl0ZW0pLAogICAgICAgICAgICAgbXVsdGlNb2RlID0gdGhpcy5vcHRpb25zLm11bHRpU2VsZWN0LCAvLyAmJiBldmVudC5jdHJsS2V5IDsKICAgICAgICAgICAgIHRoYXQgPSB0aGlzOwogICAgICAgICAgICAgLy90b2dnbGUgc2VsZWN0ZWQgc3RhdGUgb2YgdGhpcyBpdGVtCiAgICAgICAgICAgICB0aGlzLiRkYXRhKGl0ZW0sICJzZWxlY3RlZCIsICF0aGlzLiRkYXRhKGl0ZW0sICJzZWxlY3RlZCIpKTsKICAgICAgICAgdmFyIHN0YXRlID0gdGhpcy4kZGF0YShpdGVtLCAic2VsZWN0ZWQiKQoKICAgICAgICAgaWYoIW11bHRpTW9kZSkgewogICAgICAgICAgICAgdmFyICRzZWxlY3RlZEl0ZW0gPSB0aGlzLiR1c2VyQ29udHJvbC5jaGlsZHJlbigiLml0ZW0tc2VsZWN0ZWQiKQogICAgICAgICAgICAgaWYoJHNlbGVjdGVkSXRlbS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICB0aGlzLiRkYXRhKCRzZWxlY3RlZEl0ZW1bMF0sInNlbGVjdGVkIixmYWxzZSkKICAgICAgICAgICAgICAgICAkc2VsZWN0ZWRJdGVtLnJlbW92ZUNsYXNzKCJpdGVtLXNlbGVjdGVkIikuYWRkQ2xhc3MoIml0ZW0tc2VsZWN0YWJsZSIpCiAgICAgICAgICAgICB9CiAgICAgICAgIH0KICAgICAgICAgJGl0ZW0udG9nZ2xlQ2xhc3MoIml0ZW0tc2VsZWN0YWJsZSIsIXN0YXRlKS4KICAgICAgICAgICAgICAgdG9nZ2xlQ2xhc3MoIml0ZW0tc2VsZWN0ZWQiLHN0YXRlKQoKICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wudHJpZ2dlcigibGlzdGJveGNoYW5nZSIpOwogICAgIH0sCgogICAgIGdldENvbW1pdFZhbHVlOiBmdW5jdGlvbigpIHsKICAgICAgICAgdmFyIHRoYXQgPSB0aGlzLAogICAgICAgICAgICAgbXVsdGlNb2RlID0gdGhpcy5vcHRpb25zLm11bHRpU2VsZWN0OwoKCiAgICAgICAgIHJldHVybiB0aGlzLiR1c2VyQ29udHJvbC5jaGlsZHJlbigpLm1hcChmdW5jdGlvbigpewogICAgICAgICAgICAgLy8gaW50ZW50aW9uYWxseSB1c2luZyAkdGhpcy5hdHRyKCJkYXRhLXNhdmUiKSBpbnN0ZWFkIG9mICR0aGlzLmRhdGEoImRhdGEiKQogICAgICAgICAgICAgcmV0dXJuIHRoYXQuJGRhdGEodGhpcywgInNlbGVjdGVkIikgPyAkKHRoaXMpLmF0dHIoImRhdGEtc2F2ZSIpIDogbnVsbDsKICAgICAgICAgfSkuZ2V0KCk7CiAgICAgfSwKCiAgICAgIF9oYW5kbGVJdGVtRm9jdXMgOiBmdW5jdGlvbihldmVudCl7CiAgICAgICAgICBpZih0aGlzLm9wdGlvbnMuYWNjZXNzICE9ICJvcGVuIikKICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICB2YXIgaXRlbSA9IGV2ZW50LnRhcmdldDsKICAgICAgICAgIHRoaXMuaXRlbUluRm9jdXMgPSBpdGVtOwoKICAgICAgICAgIC8vIG92ZXJyaWRpbmcgZGVmYXVsdCB3aWRnZXRzIGhhbmRsZUZvY3VzCiAgICAgICAgICBpZighKHRoaXMua2V5RG93biB8fCB0aGlzLm1vdXNlRG93bikpIHsgICAgICAgIC8vd2UgZG8gbm90IG5lZWQgdG8gZmlyZSBmb2N1cyBldmVudCBpZgogICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXIoImxpc3Rib3hlbnRlciIpICAvLyBjbGlja2VkIG9uIGFub3RoZXIgbGkgZWxlbWVudCBvciBwcmVzc2VkIGEga2V5IHRvIG1vdmUgdGhlIHNlbGVjdGlvCiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1vdXNlRG93biA9IGZhbHNlOwogICAgICAgICAgdGhpcy5pbkZvY3VzID0gdHJ1ZTsKICAgICAgfSwKCiAgICAgX2hhbmRsZUl0ZW1DbGljayA6IGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAvLyBCdWcjMzUwMTgxMSBJZiBjbGlja2VkIG9ubGlzdGJveCBlbnRyeSBtb3JlIHRoYW4gb25jZSwgZXhpdCBldmVudCBpcyBub3QgZmlyZWQKICAgICAgICAvLyBDbGlja2luZyBvbiB0aGUgc2FtZSBlbnRyeSBkb2VzIG5vdCBjYWxsIGZvY3VzIGFuZCBoZW5jZSB3ZSB3ZXJlIG5vdCByZXNldHRpbmcgdGhlIHN0YXRlLiBEb2luZyBpdCBpbiBvbkNsaWNrCiAgICAgICAgaWYodGhpcy5tb3VzZURvd24gPT0gdHJ1ZSkKICAgICAgICAgICAgdGhpcy5tb3VzZURvd24gPSBmYWxzZTsKICAgICAgICBpZih0aGlzLm9wdGlvbnMuYWNjZXNzICE9ICJvcGVuIikKICAgICAgICAgICAgIHJldHVybjsKICAgICAgICB0aGlzLl90b2dnbGVJdGVtKGV2ZW50LnRhcmdldCkKICAgIH0sCgogICAgX2hhbmRsZUZvY3VzT3V0OiBmdW5jdGlvbigpewogICAgICAgIGlmKCEodGhpcy5rZXlEb3duIHx8IHRoaXMubW91c2VEb3duKSkgewogICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC50cmlnZ2VyKCJsaXN0Ym94ZXhpdCIpOwogICAgICAgICAgICB0aGlzLmluRm9jdXMgPSBmYWxzZQogICAgICAgIH0KICAgIH0sCgogICAgX3NlbGVjdExpc3RJdGVtIDogZnVuY3Rpb24gKCRlbGVtKSB7CiAgICAgICAgaWYgKCRlbGVtICYmICRlbGVtLmxlbmd0aCkgewogICAgICAgICAgICAkZWxlbS5yZW1vdmVDbGFzcygiaXRlbS1zZWxlY3RhYmxlIikKICAgICAgICAgICAgICAgIC5hZGRDbGFzcygiaXRlbS1zZWxlY3RlZCIpCiAgICAgICAgICAgICAgICAuYXR0cigidGFiSW5kZXgiLCB0aGlzLm9wdGlvbnMudGFiSW5kZXgpOwogICAgICAgIH0KICAgIH0sCgogICAgZGVzdHJveTogZnVuY3Rpb24oKSB7CiAgICAgICAgdGhpcy5lbGVtZW50LgogICAgICAgICAgICByZW1vdmVDbGFzcyh0aGlzLl93aWRnZXROYW1lKS4KICAgICAgICAgICAgY2hpbGRyZW4oKS5yZW1vdmUoKS4KICAgICAgICAgICAgdGV4dCgiIik7CgogICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmRlc3Ryb3kuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgIH0KfSk7Cn0pKCQsIHdpbmRvdy5fKTsKKGZ1bmN0aW9uKCQpIHsKICAgICQud2lkZ2V0KCAieGZhV2lkZ2V0Lm53a0xpc3RCb3giLCAgJC54ZmFXaWRnZXQuZHJvcERvd25MaXN0LCB7ICAgICAgICAgICAgLy9ub24td2Via2l0IGxpc3Rib3gKCiAgICAgICAgX3dpZGdldE5hbWUgOiAibndrTGlzdEJveCIsCgogICAgICAgIG9wdGlvbnMgOiB7CiAgICAgICAgICAgIHZhbHVlIDogW10sCiAgICAgICAgICAgIG11bHRpU2VsZWN0IDogZmFsc2UKICAgICAgICB9LAoKICAgICAgICByZW5kZXIgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyICRjb250cm9sID0gJC54ZmFXaWRnZXQuZHJvcERvd25MaXN0LnByb3RvdHlwZS5yZW5kZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgaWYoJGNvbnRyb2wpewogICAgICAgICAgICAgICAgJGNvbnRyb2wuY2hpbGRyZW4oIiNlbXB0eVZhbHVlIikucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICBpZih0aGlzLm9wdGlvbnMubXVsdGlTZWxlY3QpCiAgICAgICAgICAgICAgICAgICAgJGNvbnRyb2wuYXR0cigibXVsdGlwbGUiLCAibXVsdGlwbGUiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl91cGRhdGVTZWxlY3RTaXplKCRjb250cm9sKTsKICAgICAgICAgICAgcmV0dXJuICRjb250cm9sOwogICAgICAgIH0sCgogICAgICAgIGFkZEl0ZW0gOiBmdW5jdGlvbihpdGVtVmFsdWVzKXsKICAgICAgICAgICAgJC54ZmFXaWRnZXQuZHJvcERvd25MaXN0LnByb3RvdHlwZS5hZGRJdGVtLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdFNpemUoKTsKICAgICAgICB9LAoKICAgICAgICBjbGVhckl0ZW1zIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgJC54ZmFXaWRnZXQuZHJvcERvd25MaXN0LnByb3RvdHlwZS5jbGVhckl0ZW1zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdFNpemUoKTsKICAgICAgICB9LAoKICAgICAgICBkZWxldGVJdGVtIDogZnVuY3Rpb24obkluZGV4KXsKICAgICAgICAgICAgJC54ZmFXaWRnZXQuZHJvcERvd25MaXN0LnByb3RvdHlwZS5kZWxldGVJdGVtLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdFNpemUoKTsKICAgICAgICB9LAoKICAgICAgICBfdXBkYXRlU2VsZWN0U2l6ZSA6IGZ1bmN0aW9uKCRjb250cm9sKXsKICAgICAgICAgICAgJGNvbnRyb2wgPSAkY29udHJvbCB8fCB0aGlzLiR1c2VyQ29udHJvbDsKICAgICAgICAgICAgJGNvbnRyb2wuYXR0cigic2l6ZSIsICh0aGlzLm9wdGlvbnMuaXRlbXMgfHwgW10pLmxlbmd0aCk7CiAgICAgICAgfSwKCiAgICAgICAgLy8gQnVnIzM1OTc3NzEKICAgICAgICAvLyBmb2N1cyBhbmQgY29tbWl0IGV2ZW50IGhhcHBlbiB0b2dldGhlciBoZW5jZSBmaXJzdCBzZWxlY3Rpb24gd2FzIG1vZGlmeWluZyB0aGUgdmFsdWUKICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCBmb2N1cyB0byBtb2RpZnkgdGhlIHZhbHVlIHRoYXQgaXMgYWJvdXQgdG8gYmUgY29tbWl0dGVkCiAgICAgICAgc2hvd1ZhbHVlIDogZnVuY3Rpb24oKSB7CgogICAgICAgIH0KCiAgfSk7Cn0pKCQpOwooZnVuY3Rpb24gKCQpIHsKICAgICQud2lkZ2V0KCJ4ZmFXaWRnZXQueGZhQnV0dG9uIiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgeyAgICAgICAgICAgIC8vY29tbWl0RXZlbnQ6IGNoYW5nZTsgY29tbWl0UHJvcGVydHk6IHZhbHVlPEFycmF5PgoKICAgICAgICBfd2lkZ2V0TmFtZTogInhmYUJ1dHRvbiIsCgogICAgICAgIG9wdGlvbnM6IHsKICAgICAgICAgICAgdmFsdWU6IG51bGwsCiAgICAgICAgICAgIHN2Z0NhcHRpb246IGZhbHNlIC8vb3B0aW9uIHRvIGluZGljYXRlIGlmIGJ1dHRvbiBhbHJlYWR5IGhhcyBhbiBTVkcgY2FwdGlvbgogICAgICAgIH0sCgogICAgICAgIGdldE9wdGlvbnNNYXA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSwgcGFyZW50T3B0aW9uc01hcCwgewogICAgICAgICAgICAgICAgImFjY2VzcyI6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJvcGVuIiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJkaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQXR0cigiYXJpYS1kaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIm5vbkludGVyYWN0aXZlIiA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInByb3RlY3RlZCIgOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJyZWFkT25seSIgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiZGlzYWJsZWQiLCAiZGlzYWJsZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImFyaWEtZGlzYWJsZWQiLCAidHJ1ZSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJhcmlhLWRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInZhbHVlIjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJkaXNwbGF5VmFsdWUiOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInN2Z0NhcHRpb24iOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJ2YWx1ZSIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSkKICAgICAgICB9LAoKICAgICAgICBfYXR0YWNoRXZlbnRIYW5kbGVyczogZnVuY3Rpb24gKCRjb250cm9sKSB7CiAgICAgICAgICAgICRjb250cm9sLmNsaWNrKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHRoaXMuZm9jdXMoKQogICAgICAgICAgICB9KTsKICAgICAgICB9LAoKICAgICAgICBnZXRDb21taXRWYWx1ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnZhbHVlOwogICAgICAgIH0sCgogICAgICAgIHNob3dWYWx1ZTogZnVuY3Rpb24gKCkgewogICAgICAgIH0sCgogICAgICAgIHNob3dEaXNwbGF5VmFsdWU6IGZ1bmN0aW9uICgpIHsKICAgICAgICB9CiAgICB9KTsKfSkoJCk7KGZ1bmN0aW9uICgkKSB7CiAgICAkLndpZGdldCgieGZhV2lkZ2V0LlhmYUNoZWNrQm94IiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgeyAgICAgICAgICAgIC8vY29tbWl0RXZlbnQ6IGNoYW5nZTsgY29tbWl0UHJvcGVydHk6IHZhbHVlPEFycmF5PgoKICAgICAgICBfd2lkZ2V0TmFtZTogIlhmYUNoZWNrQm94IiwKCiAgICAgICAgb3B0aW9uczogewogICAgICAgICAgICB2YWx1ZTogbnVsbCwKICAgICAgICAgICAgc3RhdGU6IC0xLAogICAgICAgICAgICBzdGF0ZXM6IDIsCiAgICAgICAgICAgIHZhbHVlczogW10sCiAgICAgICAgICAgIG1hbmRhdG9yeTogZmFsc2UKICAgICAgICB9LAoKICAgICAgICBjaGVja2VkU3RhdGU6IGZhbHNlLAogICAgICAgIGNsaWNrUGVuZGluZzogZmFsc2UsCgogICAgICAgIGdldE9wdGlvbnNNYXA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSwgcGFyZW50T3B0aW9uc01hcCwgewogICAgICAgICAgICAgICAgImFjY2VzcyI6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJvcGVuIiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJkaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQXR0cigiYXJpYS1kaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIm5vbkludGVyYWN0aXZlIiA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInByb3RlY3RlZCIgOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJyZWFkT25seSIgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiZGlzYWJsZWQiLCAiZGlzYWJsZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImFyaWEtZGlzYWJsZWQiLCAidHJ1ZSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJhcmlhLWRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgICJkaXNwbGF5VmFsdWUiOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cih0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHksIHRoaXMub3B0aW9ucy52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUodGhpcy5kSW5kZXhPZih0aGlzLm9wdGlvbnMudmFsdWVzLCB0aGlzLm9wdGlvbnMudmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJjaGVja2VkIiwgdGhpcy5jaGVja2VkU3RhdGUgPyAiY2hlY2tlZCIgOiBudWxsKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5wcm9wKCJjaGVja2VkIiwgdGhpcy5jaGVja2VkU3RhdGUgPyAiY2hlY2tlZCIgOiBudWxsKTsKICAgICAgICAgICAgICAgICAgICAvL2ZvciBhY2Nlc3NpYmlsaXR5CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiYXJpYS1jaGVja2VkIiwgdGhpcy5jaGVja2VkU3RhdGUpOwogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc3RhdGUgPT0gMikKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYWRkQ2xhc3MoIm5ldXRyYWwiKTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLm9wdGlvbnMuc3RhdGVzID09IDMpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUNsYXNzKCJuZXV0cmFsIik7ICAgLy8gc2luY2UgY3VycmVudCBzdGF0ZSAhPSBuZXV0cmFsCiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgICJhbGxvd05ldXRyYWwiOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGludFZhbCA9IHBhcnNlSW50KHZhbCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGludFZhbCA9PSAwIHx8IGludFZhbCA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5zdGF0ZXMgPSAyICsgaW50VmFsOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgInBhcmFTdHlsZXMiOiBmdW5jdGlvbiAocGFyYVN0eWxlcykgewogICAgICAgICAgICAgICAgICAgIHBhcmVudE9wdGlvbnNNYXAucGFyYVN0eWxlcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVZBbGlnbk9uRXhpdCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KQogICAgICAgIH0sCgogICAgICAgIGdldEV2ZW50TWFwOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0RXZlbnRNYXAuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LCBwYXJlbnRPcHRpb25zTWFwLCB7CiAgICAgICAgICAgICAgICAgInhmYWNoZWNrYm94Y2hhbmdlIiA6ICB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NIQU5HRV9FVkVOVCwKICAgICAgICAgICAgICAgICAieGZhY2hlY2tib3hjbGljayIgOiAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0xJQ0tfRVZFTlQsCiAgICAgICAgICAgICAgICAgImNoYW5nZSI6IG51bGwsCiAgICAgICAgICAgICAgICAgImNsaWNrIiA6IG51bGwKICAgICAgICAgICAgICAgfSkKICAgICAgICB9LAoKICAgICAgICBfYXR0YWNoRXZlbnRIYW5kbGVyczogZnVuY3Rpb24gKCRjb250cm9sKSB7CiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgdmFyIGZvY3VzRnVuYyA9IGZ1bmN0aW9uIChldm50KSB7CiAgICAgICAgICAgICAgICBpZiAoIXRoYXQuaW5Gb2N1cykgewogICAgICAgICAgICAgICAgICAgIHRoYXQuZm9jdXMoKTsKICAgICAgICAgICAgICAgICAgICB0aGF0LmluRm9jdXMgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBmb2N1c091dEZ1bmMgPSBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICAgICAgdGhhdC5pbkZvY3VzID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGNvbnRyb2wuY2xpY2soZm9jdXNGdW5jKS5jaGFuZ2UoZm9jdXNGdW5jKS5ibHVyKGZvY3VzT3V0RnVuYyk7CiAgICAgICAgICAgICRjb250cm9sLmNoYW5nZSgkLnByb3h5KHRoaXMuX2hhbmRsZUNoYW5nZSx0aGlzKSkuY2xpY2soJC5wcm94eSh0aGlzLl9oYW5kbGVDbGljayx0aGlzKSk7ICAgLy9MQy01MTA2CiAgICAgICAgfSwKCiAgICAgICAgZ2V0Q29tbWl0VmFsdWU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdGhpcy5fc3RhdGUoKHRoaXMub3B0aW9ucy5zdGF0ZSArIDEpICUgdGhpcy5vcHRpb25zLnN0YXRlcyk7CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImNoZWNrZWQiLCB0aGlzLmNoZWNrZWRTdGF0ZSA/ICJjaGVja2VkIiA6IG51bGwpOwogICAgICAgICAgICAvL2ZvciBhY2Nlc3NpYmlsaXR5CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImFyaWEtY2hlY2tlZCIsIHRoaXMuY2hlY2tlZFN0YXRlKQogICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnN0YXRlID09IDIpIHsKICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmFkZENsYXNzKCJuZXV0cmFsIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5vcHRpb25zLnN0YXRlcyA9PSAzKQogICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQ2xhc3MoIm5ldXRyYWwiKTsgLy8gc2luY2UgY3VycmVudCBzdGF0ZSAhPSBuZXV0cmFsCgogICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnZhbHVlc1t0aGlzLm9wdGlvbnMuc3RhdGVdOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVWQWxpZ25PbkV4aXQ6IGZ1bmN0aW9uIChldm50KSB7CiAgICAgICAgICAgIC8vLS10aGlzIGlzIGJlaW5nIGtlcHQgZW1wdHkgYXMgbm8gb3RoZXIgYnJvd3NlciAoaS5lIE1vemlsbGEgYW5kIENocm9tZSkgdGFrZSB0aGUgcGFkZGluZy1ib3R0b20gb3IgcGFkZGluZy10b3AgaW50byBhY2NvdW50LgogICAgICAgICAgICAvLyB0aGUgb25seSBicm93c2VyIHRvIHRha2UgaXQgaW50byBjb25zaWRlcmF0aW9uIGlzIElFLiBBbmQgbW9yZW92ZXIgdGhlIGFsaWdubWVudCBhbmQgcGFkZGluZyBjb25zaWRlcmF0aW9ucyBoYXZlIGFscmVhZHkgYmVlbiB0YWtlbiBpbnRvIGFjY291bnQgaW4KICAgICAgICAgICAgLy8gY2FsY3VsYXRpb25zIGluIENoZWNrQnV0dG9uRmllbGRWaWV3LmpzLiBBbmQgb24gcmVtb3ZpbmcgdGhlIGVudGlyZSBmdW5jdGlvbiBpdCB0YWtlcyB1cCB0aGUgX2hhbmRsZVZBbGlnbk9uRXhpdCgpIG9mIEFic3RyYWN0V2lkZ2V0LgoKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlQ2hhbmdlOiBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC50cmlnZ2VyKCJ4ZmFjaGVja2JveGNoYW5nZSIpOyAvL2NoYW5nZSBpcyBhbHdheXMgZmlyZWQKICAgICAgICAgICAgaWYodGhpcy5jbGlja1BlbmRpbmcgPT09IHRydWUpIHsKICAgICAgICAgICAgICB0aGlzLmNsaWNrUGVuZGluZyA9IGZhbHNlOwogICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXIoInhmYWNoZWNrYm94Y2xpY2siKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGhhbmRsaW5nIG9mIHRoaXMuY2xpY2tQZW5kaW5nIGlzIGFkZGVkIHRvIGhhbmRsZSB0aGUgY2FzZSB3aGVuIGNsaWNrZWQgb24gY2hlY2tib3gvcmFkaW9idXR0b24gbGFiZWwvY2FwdGlvbgogICAgICAgICAgICAgICAgdGhpcy5jbGlja1BlbmRpbmcgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUNsaWNrOiBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICAgdmFyIGlzQ2hyb21lID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmRldGVjdENocm9tZSgpLAogICAgICAgICAgICAgICAgIGlzSUUgPSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZGV0ZWN0SUUoKSwKICAgICAgICAgICAgICAgICBpc1NhZmFyaSA9IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5pc1NhZmFyaSgpLAogICAgICAgICAgICAgICAgIHVzZXJDb250cm9sVHlwZSA9IHRoaXMuJHVzZXJDb250cm9sLmF0dHIoInR5cGUiKTsKICAgICAgICAgICAgIC8vIGNsaWNrIHdpbGwgbm90IGJlIGZpcmVkIGlmIHRoZSBwcmV2aW91cyBzdGF0ZSBvZiB0aGUgcmFkaW9idXR0b24gaXMgJ29uJy4KICAgICAgICAgICAgIC8vIE5QUi0zNTY1MiA6IENoZWNrYm94IG1vdmVtZW50IC0gQ2xpY2sgZXZlbnQgd29ya3MgZmluZSBvbiBjaHJvbWUgYnV0IG5vdCBpbiBpT1Mgc2FmYXJpIGZvciBjb2xsYXBzaWJsZSBmaWVsZHMKICAgICAgICAgICAgIC8vIENRLTEwMzAyMyA6IENsaWNrIEV2ZW50IG9uIFJhZGlvIEJ1dHRvbiBub3Qgd29ya2luZyBjb3JyZWN0bHkgaW4gQ2hyb21lIDUzCiAgICAgICAgICAgICAvLyBDUS0xMDM3MTUgOiBDUS0xMDM3MTUgOiBDbGljayBFdmVudCBvbiBDaGVjayBCb3ggbm90IHdvcmtpbmcgY29ycmVjdGx5IGluIENocm9tZSBhbmQgRmlyZWZveCwgYWRkZWQgaGFuZGxpbmcgZm9yIGNoZWNrYm94IGFsc28KICAgICAgICAgICAgIC8vIGhhbmRsaW5nIG9mIHRoaXMuY2xpY2tQZW5kaW5nIGlzIGFkZGVkIHRvIGhhbmRsZSB0aGUgY2FzZSB3aGVuIGNsaWNrZWQgb24gY2hlY2tib3gvcmFkaW9idXR0b24gbGFiZWwvY2FwdGlvbgogICAgICAgICAgICAgaWYoKCQuYnJvd3Nlci5tb3ppbGxhIHx8IGlzQ2hyb21lIHx8IGlzU2FmYXJpKSAmJiAhaXNJRSAmJiB0aGlzLmNsaWNrUGVuZGluZyA9PT0gZmFsc2UgJiYgKCh1c2VyQ29udHJvbFR5cGUgPT09ICJyYWRpbyIgJiYgdGhpcy5jaGVja2VkU3RhdGUgPT09IGZhbHNlKSB8fCAodXNlckNvbnRyb2xUeXBlID09PSAiY2hlY2tib3giKSkpIHsKICAgICAgICAgICAgICAgdGhpcy5jbGlja1BlbmRpbmcgPSB0cnVlOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC50cmlnZ2VyKCJ4ZmFjaGVja2JveGNsaWNrIik7CiAgICAgICAgICAgICAgICB0aGlzLmNsaWNrUGVuZGluZyA9IGZhbHNlOwogICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9zdGF0ZTogZnVuY3Rpb24gKG5ld1N0YXRlKSB7CiAgICAgICAgICAgIGlmIChuZXdTdGF0ZSA9PSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnN0YXRlOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuc3RhdGUgPSBuZXdTdGF0ZTsKICAgICAgICAgICAgdGhpcy5jaGVja2VkU3RhdGUgPSAobmV3U3RhdGUgPT0gMCB8fCBuZXdTdGF0ZSA9PSAyKTsKICAgICAgICB9LAoKICAgICAgICBjbGljazogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAvLyB0cmlnZ2VyIGNoYW5nZSBmb3IgY2hlY2sgYm94IGFuZCBmb3IgcmFkaW8gb25seSBpZiBpdCBpcyBub3Qgc2VsZWN0ZWQKICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHJhZGlvIGJ1dHRvbiB3aWxsIGdvIGluIGRlc2VsZWN0ZWQgc3RhdGUKICAgICAgICAgICAgaWYgKHRoaXMuJHVzZXJDb250cm9sLmF0dHIoInR5cGUiKSAhPT0gInJhZGlvIiB8fCB0aGlzLm9wdGlvbnMuc3RhdGUgIT09IDApIHsKICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXIoImNoYW5nZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vd2Ugc2hvdWxkIGNhbGwgb25seSB0aGUgaGFuZGxlciBzaW5jZSBjYWxsaW5nIGNsaWNrIHdpbGwgdHJpZ2dlciBjaGFuZ2UuCiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXJIYW5kbGVyKCJjbGljayIpOwogICAgICAgIH0KICAgIH0pOwp9KSgkKTsKKGZ1bmN0aW9uKCQsIF8pewogICAgJC53aWRnZXQoICJ4ZmFXaWRnZXQudGV4dEZpZWxkIiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgewoKICAgICAgICBfd2lkZ2V0TmFtZTogInRleHRGaWVsZCIsCgogICAgICAgIG9wdGlvbnM6IHsKICAgICAgICAgICAgY3VyVmFsdWUgOiBudWxsICwKICAgICAgICAgICAgcG9zOjAsCiAgICAgICAgICAgIGxlbmd0aExpbWl0VmlzaWJsZTogdHJ1ZSwKICAgICAgICAgICAgbWF4Q2hhcnM6MCAsCiAgICAgICAgICAgIGZsYWc6IiIsCiAgICAgICAgICAgIC8vIGJ5IGRlZmF1bHQgaHRtbDVUeXBlIGlzIHNldCB0byB0cnVlCiAgICAgICAgICAgIC8vIHdlIGxldmVyYWdlIHBhdHRlcm4sIG1heExlbmd0aCBzdXBwb3J0IGZyb20gSFRNTDUgYnJvd3NlciBmb3IgbW9iaWxlIGZvcm1zCiAgICAgICAgICAgIGh0bWw1VHlwZSA6ICJ0ZXh0IiwKICAgICAgICAgICAgbGVuZ3RoIDogbnVsbCwKICAgICAgICAgICAgbWluTGVuZ3RoIDogMCwKICAgICAgICAgICAgdG90YWxMZW5ndGhNZXNzYWdlIDogIiIsCiAgICAgICAgICAgIG1pbmltdW1MZW5ndGhNZXNzYWdlIDogIiIsCiAgICAgICAgfSwKCiAgICAgICAgZ2V0T3B0aW9uc01hcDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0T3B0aW9uc01hcC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSxwYXJlbnRPcHRpb25zTWFwLHsKICAgICAgICAgICAgICAgICJtYXhDaGFycyI6IGZ1bmN0aW9uKG1heGNoYXJzKSB7CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fbWF4Q2hhcnNSZWFjaGVkKHRoaXMub3B0aW9ucy52YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5vcHRpb25zLnZhbHVlLnNsaWNlKDAsbWF4Y2hhcnMpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NldE9wdGlvbigidmFsdWUiLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NldE9wdGlvbigiZGlzcGxheVZhbHVlIiwgdmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgICJtdWx0aUxpbmUgIjogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLm11bHRpTGluZSkKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiYXJpYS1tdWx0aWxpbmUiLCAidHJ1ZSIpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQXR0cigiYXJpYS1tdWx0aWxpbmUiLCAiZmFsc2UiKTsKICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgImhlaWdodCI6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAgICAgICAgIGlmKHZhbCkgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLiR1c2VyQ29udHJvbFswXSx7ImhlaWdodCIgOnZhbH0pCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVZBbGlnbk9uRXhpdCgpOyAgICAvLyBUbyBIYW5kbGUgdGhlIGNhc2Ugb2YgZXhwYW5kYWJsZSBGaWVsZHMKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIndpZHRoIjogZnVuY3Rpb24odmFsKXsKICAgICAgICAgICAgICAgICAgICBwYXJlbnRPcHRpb25zTWFwLndpZHRoLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICAvLyBoYW5kbGUgdmFsaWduIG9uIHdpZHRoIGNoYW5nZSBhcyB3ZWxsCiAgICAgICAgICAgICAgICAgICAgLy8gYXMgY29udGVudCBoZWlnaHQoc2Nyb2xsSGVpZ2h0KSB2YXJpZXMgYWNjb3JkaW5nIHRvIHdpZHRoCiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlVkFsaWduT25FeGl0KCk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInBhcmFTdHlsZXMiOiBmdW5jdGlvbihwYXJhU3R5bGVzKXsKICAgICAgICAgICAgICAgICAgICBwYXJlbnRPcHRpb25zTWFwLnBhcmFTdHlsZXMuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVZBbGlnbk9uRXhpdCgpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgfSkKICAgICAgICB9LAoKICAgICAgICByZW5kZXIgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIGNvbnRyb2wgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5yZW5kZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgLy8gdXNlIHRoZSBjb250cm9sIHRvIHNldCBIVE1MNSBhdHRyaWJ1dGVzCiAgICAgICAgICAgIGlmIChjb250cm9sICYmIGNvbnRyb2wubGVuZ3RoID4gMCAmJiB0aGlzLm9wdGlvbnMuaHRtbDVUeXBlKSB7CiAgICAgICAgICAgICAgICB2YXIgbWluTGVuZ3RoID0gdGhpcy5vcHRpb25zLm1pbkxlbmd0aCwKICAgICAgICAgICAgICAgICAgICBtYXhMZW5ndGggPSB0aGlzLm9wdGlvbnMubWF4Q2hhcnMsCiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID0gdGhpcy5vcHRpb25zLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICBpc01pbkxlbmd0aFNldCA9IG1pbkxlbmd0aCAhPSBudWxsICYmIG1pbkxlbmd0aCA+IDAsCiAgICAgICAgICAgICAgICAgICAgaXNNYXhMZW5ndGhTZXQgPSBtYXhMZW5ndGggIT0gbnVsbCAmJiBtYXhMZW5ndGggPiAwLAogICAgICAgICAgICAgICAgICAgIGlzTGVuZ3RoU2V0ID0gbGVuZ3RoICE9IG51bGwgJiYgbGVuZ3RoID4gMCwKICAgICAgICAgICAgICAgICAgICBpc011bHRpbGluZSA9IHRoaXMub3B0aW9ucy5tdWx0aUxpbmUsCiAgICAgICAgICAgICAgICAgICAgbWluTGVuZ3RoTXNnID0gdGhpcy5vcHRpb25zLm1pbmltdW1MZW5ndGhNZXNzYWdlLAogICAgICAgICAgICAgICAgICAgIHRvdExlbmd0aE1zZyA9IHRoaXMub3B0aW9ucy50b3RhbExlbmd0aE1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgcGF0dGVybiA9ICIiOyAvLyBodG1sNSBwYXR0ZXJuIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHRleHRhcmVhCgogICAgICAgICAgICAgICAgLy8gb3JkZXIgb2YgZXhlY3V0aW9uIG1hdHRlcnMgZm9yIHRoZSBiZWxvdyBjb2RlIHNuaXBwZXQKICAgICAgICAgICAgICAgIGlmIChpc01pbkxlbmd0aFNldCkgewogICAgICAgICAgICAgICAgICAgIC8vIGFkZCBtaW5MZW5ndGggdGhvdWdoIGl0IGlzIG5vdCBmdWxseSBzdXBwb3J0ZWQgaW4gYWxsIGJyb3dzZXJzCiAgICAgICAgICAgICAgICAgICAgLy8gaGVuY2UgYWxzbyBhZGRpbmcgcGF0dGVybiBhdHRyaWJ1dGUKICAgICAgICAgICAgICAgICAgICBjb250cm9sLmF0dHIoIm1pbmxlbmd0aCIsIHBhcnNlSW50KG1pbkxlbmd0aCkpOwogICAgICAgICAgICAgICAgICAgIGlmKG1pbkxlbmd0aE1zZyAmJiBtaW5MZW5ndGhNc2cubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sLmF0dHIoInRpdGxlIiwgdGhpcy5vcHRpb25zLm1pbmltdW1MZW5ndGhNZXNzYWdlKTsgLy8gaHRtbDUgc3VwcG9ydGVkIG1lc3NhZ2Ugb24gcGF0dGVybiB2YWxpZGF0aW9uIGZhaWx1cmUKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGlzTWF4TGVuZ3RoU2V0KSB7CiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5hdHRyKCJtYXhsZW5ndGgiLCBwYXJzZUludChtYXhMZW5ndGgpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBpZiBib3RoIG1pbiBhbmQgbWF4IGxlbmd0aCBpcyBzZXQKICAgICAgICAgICAgICAgIGlmKGlzTWluTGVuZ3RoU2V0ICYmIGlzTWF4TGVuZ3RoU2V0KXsKICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuICs9ICIueyIgKyBtaW5MZW5ndGggKyAiLCIgKyBtYXhMZW5ndGggKyAifSI7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYoaXNNaW5MZW5ndGhTZXQpIHsKICAgICAgICAgICAgICAgICAgICAvLyBpZiBvbmx5IG1pbiBsZW5ndGggc2V0CiAgICAgICAgICAgICAgICAgICAgcGF0dGVybiArPSAiLnsiICsgbWluTGVuZ3RoICsgIix9IjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBpZiBsZW5ndGggaXMgc2V0IHRoZW4gc2V0IG1pbiBhbmQgbWF4IGxlbmd0aCBpbiBwYXR0ZXJuIGVxdWFsIHRvIGxlbmd0aAogICAgICAgICAgICAgICAgaWYgKGlzTGVuZ3RoU2V0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYoaXNNdWx0aWxpbmUpeyAvLyBzZXQgYm90aCBtaW4gYW5kIG1heGxlbmd0aCBhcyBwYXR0ZXJuIGlzIG5vdCBzdXBwb3J0ZWQKICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC5hdHRyKCJtaW5sZW5ndGgiLCBwYXJzZUludChsZW5ndGgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC5hdHRyKCJtYXhsZW5ndGgiLCBwYXJzZUludChsZW5ndGgpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYodG90TGVuZ3RoTXNnICYmIHRvdExlbmd0aE1zZy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wuYXR0cigidGl0bGUiLCB0aGlzLm9wdGlvbnMudG90YWxMZW5ndGhNZXNzYWdlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gcmVzZXQgdGhlIHBhdHRlcm4gc3RyaW5nCiAgICAgICAgICAgICAgICAgICAgcGF0dGVybiA9ICIueyIgKyBsZW5ndGggKyAiLCIgKyBsZW5ndGggKyAifSI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBpZiByZXF1aXJlZCBpcyBzZXQsIHNldCB0aGUgcmVxdWlyZWQgYXR0cmlidXRlLCBpdCBpcyBuZWNlc3NhcnkgZWxzZSBhbiBlbXB0eSB2YWx1ZSB3aWxsIGJlIGV4Y2x1ZGVkIGZyb20gY29uc3RyYWludCB2YWxpZGF0aW9uCiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnJlcXVpcmVkKSB7CiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5hdHRyKCJyZXF1aXJlZCIsIHRydWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gc2V0IHRoZSBwYXR0ZXJuIGlmIG5vdCBlbXB0eSBhbmQgY2hlY2sgaWYgdGhpcyBpcyBub3QgbXVsdGlsaW5lLCBzaW5jZSBwYXR0ZXJuIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHRleHRhcmVhCiAgICAgICAgICAgICAgICBpZiAocGF0dGVybiAmJiBwYXR0ZXJuLmxlbmd0aCA+IDAgJiYgIWlzTXVsdGlsaW5lKSB7CiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5hdHRyKCJwYXR0ZXJuIiwgcGF0dGVybik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGNvbnRyb2w7CiAgICAgICAgfSwKCiAgICAgICAgLyogIFRoaXMgZnVuY3Rpb24gYWxpZ25zIHZBbGlnbiB3aGVuOgogICAgICAgICAxLiBwYXJhc3R5bGVzIGlzIHByZXNlbnQgYW5kIHRoZSB3aWRnZXQgY29udGFpbnMgYSB2YWx1ZS4KICAgICAgICAgMi4gRHVyaW5nIGluaXRpYWwgcmVuZGVyaW5nIGlmIG5vIGNvbnRlbnQgcHJlc2VudCBmYWxsYmFjayB0byB0aGUgcHJldmlvdXMgbG9naWMuCiAgICAgICAgIDMuIFByZXNlbmNlIG9mIGNvbnRlbnQgaW4gd2lkZ2V0LgogICAgICAgICovCiAgICAgICAgX2hhbmRsZVZBbGlnbk9uRXhpdDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMub3B0aW9ucy5kaXNwbGF5VmFsdWUsCiAgICAgICAgICAgICAgICAgbm9Db250ZW50UHJlc2VudCA9IF8uaXNFbXB0eSh0aGlzLiR1c2VyQ29udHJvbC52YWwoKSB8fCB0aGlzLm9wdGlvbnMuZGlzcGxheVZhbHVlKSwKICAgICAgICAgICAgICAgICBjb250ZW50SGVpZ2h0LHdpZGdldEhlaWdodCxkaWZmLHRlbXBDU1M7CgogICAgICAgICAgICAgLy90aGUgd2lkZ2V0IGRvZXNuJ3QgaGF2ZSB2YWx1ZSBhcyB5ZXQgYnV0IGNvbnRlbnQgZXhpc3RzIFsgUmVuZGVyaW5nIG9mIHdpZGdldF0KICAgICAgICAgICAgIGlmICghdGhpcy5vcHRpb25zLnBhcmFTdHlsZXMgfHwgbm9Db250ZW50UHJlc2VudCkgewogICAgICAgICAgICAgICAgLy92QWxpZ24gaGFzIHRvIGJlIGhhbmRsZWQgb25seSBpZiB0aGVyZSBpcyBwYXJhU3R5bGVzIGFuZCB3aWRnZXQgaGFzIGNvbnRlbnQKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAvLyBtb3ppbGxhIHJlc3VsdHMgaW4gdkFsaWduIHJlZ3Jlc3Npb24gaGVuY2UgbWFkZSB0aGlzIGNoYW5nZSBvbmx5IGZvciB0ZXh0YXJlYQogICAgICAgICAgICAgaWYoJCh0aGlzLmVsZW1lbnRbMF0pLmZpbmQoInRleHRhcmVhIikubGVuZ3RoID4wICYmICFub0NvbnRlbnRQcmVzZW50KSAgewogICAgICAgICAgICAgICAvKiBtZWFzdXJlRXh0ZW50IG5vdCByZXR1cm5pbmcgY29ycmVjdCBoZWlnaHQgb2YgY29udGVudCBpbiB0ZXh0YXJlYSBldmVuIHdpdGggYWxsCiAgICAgICAgICAgICAgICAgY3NzIHZhbHVlcyAqLwogICAgICAgICAgICAgICB0ZW1wQ1NTPXsnaGVpZ2h0Jzp0aGlzLiR1c2VyQ29udHJvbC5jc3MoJ2hlaWdodCcpLCdwYWRkaW5nJzp0aGlzLiR1c2VyQ29udHJvbC5jc3MoJ3BhZGRpbmcnKX07CiAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLiR1c2VyQ29udHJvbFswXSx7J2hlaWdodCc6JzFweCcsJ3BhZGRpbmcnOicwcHgnfSk7CgogICAgICAgICAgICAgICBjb250ZW50SGVpZ2h0ID0gdGhpcy5fZ2V0Q29udGVudEhlaWdodCgpOwogICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy4kdXNlckNvbnRyb2xbMF0sdGVtcENTUyk7CiAgICAgICAgICAgICAgIHdpZGdldEhlaWdodCA9IHRoaXMub3B0aW9ucy5oZWlnaHQ7CiAgICAgICAgICAgICAgIGRpZmYgPSB3aWRnZXRIZWlnaHQgLSBjb250ZW50SGVpZ2h0OwogICAgICAgICAgICAgICB0aGlzLl9jYWxjdWxhdGVQYWRkaW5nRm9yVkFsaWduKGRpZmYpOwogICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIHdpZGdldCBoYXMgbm8gaW5pdGlhbCBjb250ZW50IG9yIGlzIGEgdGV4dGZpZWxkLlByb2NlZWQgYXMgYmVmb3JlLgogICAgICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuX2hhbmRsZVZBbGlnbk9uRXhpdC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RXZlbnRNYXA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgcGFyZW50T3B0aW9uc01hcCA9ICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmdldEV2ZW50TWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LHBhcmVudE9wdGlvbnNNYXAsewogICAgICAgICAgICAgICAgIm9uS2V5SW5wdXQudGV4dEZpZWxkIiA6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0hBTkdFX0VWRU5UCiAgICAgICAgICAgIH0pCiAgICAgICAgfSwKCiAgICAgICAgX21heENoYXJzUmVhY2hlZDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIHZhciBpc01heExlbmd0aFN1cHBvcnRlZCA9IGZhbHNlLAogICAgICAgICAgICAgICAgZWxlbWVudE5hbWUgPSB0aGlzLm9wdGlvbnMubXVsdGlMaW5lID8gInRleHRhcmVhIiA6ICJpbnB1dCI7CiAgICAgICAgICAgIC8vIGluIGJyb3dzZXJzLCB3aGVyZSBtYXggbGVuZ3RoIGlzIHN1cHBvcnRlZCwgd2UgZG9uJ3QgY3VzdG9tIGphdmFzY3JpcHQgY2hlY2tzLCB3ZSBsZXQgSFRNTCBkbyB0aGUgdmFsaWRhdGlvbiBvZiBtYXggbGVuZ3RoCiAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5odG1sNVR5cGUgJiYgeGZhbGliLnZpZXcudXRpbC5IdG1sVXRpbC5lbGVtZW50U3VwcG9ydHNBdHRyaWJ1dGUoZWxlbWVudE5hbWUsICJtYXhMZW5ndGgiKSl7CiAgICAgICAgICAgICAgICBpc01heExlbmd0aFN1cHBvcnRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICFpc01heExlbmd0aFN1cHBvcnRlZCAmJiB0aGlzLm9wdGlvbnMubWF4Q2hhcnMKICAgICAgICAgICAgICAgICAgICYmIHRoaXMub3B0aW9ucy5tYXhDaGFycyE9PSIwIgogICAgICAgICAgICAgICAgICAgJiYgdmFsCiAgICAgICAgICAgICAgICAgICAmJiAgdmFsLmxlbmd0aCA+PSB0aGlzLm9wdGlvbnMubWF4Q2hhcnMKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlS2V5SW5wdXQgOiBmdW5jdGlvbihldmVudCwgY2hhcmFjdGVyLCBjb2RlKSB7CiAgICAgICAgICAgIGlmKGV2ZW50LmN0cmxLZXkgJiYgIV8uY29udGFpbnMoWydwYXN0ZScsICdjdXQnXSwgZXZlbnQudHlwZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZighdGhpcy5vcHRpb25zLm11bHRpTGluZSkgewogICAgICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuX2hhbmRsZUtleURvd24uYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgIGNoYXJhY3RlciA9IChjb2RlID09IDEzKSA/ICcnIDogY2hhcmFjdGVyIDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHZhbCA9ICB0aGlzLiR1c2VyQ29udHJvbC52YWwoKSwKICAgICAgICAgICAgICAgIHNlbGVjdGlvblN0YXJ0ID0geGZhbGliLnZpZXcudXRpbC5IdG1sVXRpbC5nZXRIVE1MU3VwcG9ydGVkQXR0cih0aGlzLiR1c2VyQ29udHJvbFswXSwgInNlbGVjdGlvblN0YXJ0IikgfHwgMCwKICAgICAgICAgICAgICAgIHNlbGVjdGlvbkVuZCA9IHhmYWxpYi52aWV3LnV0aWwuSHRtbFV0aWwuZ2V0SFRNTFN1cHBvcnRlZEF0dHIodGhpcy4kdXNlckNvbnRyb2xbMF0sICJzZWxlY3Rpb25FbmQiKSB8fCAwLAogICAgICAgICAgICAgICAgcG9zID0gc2VsZWN0aW9uU3RhcnQsCiAgICAgICAgICAgICAgICAvLyBDUS00MjYwMjM5IDogIiZuYnNwIiB0YWtpbmcgc3BhY2Ugb2YgNSBjaGFycyBmb3IgcmVzdHJpY3RpbmcgdGhlIGxlbmd0aCB0byB2aXNpYmxlIGFyZWEKICAgICAgICAgICAgICAgIG5ld1ZhbCA9ICh2YWwuc3Vic3RyKDAsIHNlbGVjdGlvblN0YXJ0KSArIGNoYXJhY3RlciArIHZhbC5zdWJzdHIoc2VsZWN0aW9uRW5kKSk7CiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5jdXJWYWx1ZSA9IHZhbDsKICAgICAgICAgICAgaWYoIXRoaXMub3B0aW9ucy5tdWx0aUxpbmUpIHsgLy9UT0RPOmxvb2tzIGxpa2UgYSBidWcKICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5sZW5ndGhMaW1pdFZpc2libGUgPSB0cnVlOwogICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLnBvcyA9IHBvczsKICAgICAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5oU2Nyb2xsRGlzYWJsZWQgJiYgIV8uY29udGFpbnMoWydrZXlkb3duJywgJ2N1dCddLCBldmVudC50eXBlKSkgewogICAgICAgICAgICAgICAgICAgIHZhciBleHBlY3RlZFdpZHRoID0geGZhbGliLnZpZXcudXRpbC5UZXh0TWV0cmljcy5tZWFzdXJlRXh0ZW50KG5ld1ZhbCwge3JlZkVsOiB0aGlzLiR1c2VyQ29udHJvbFswXSwgbWF4V2lkdGg6LTF9KS53aWR0aDsKICAgICAgICAgICAgICAgICAgICBpZighZXZlbnQuY3RybEtleSAmJiBleHBlY3RlZFdpZHRoID4gdGhpcy4kdXNlckNvbnRyb2wud2lkdGgoKSl7ICAgLy8gV2h5ICBhbGxvd2FuY2Ugb2YgNSByZXF1aXJlZD8/CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5sZW5ndGhMaW1pdFZpc2libGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLm9wdGlvbnMubXVsdGlMaW5lICYmIHRoaXMub3B0aW9ucy5oU2Nyb2xsRGlzYWJsZWQpIHsgIC8vIExDLTQ2NTYgOiB3YWl0IHRpbGwgdXNlciBpbnB1dCwgaWYgaXQgY2F1c2VzIGFuIG92ZXJmbG93IHJldmVydCB0byBvbGQgdGV4dAogICAgICAgICAgICAgICAgdmFyICR0ZXh0QXJlYSA9IHRoaXMuJHVzZXJDb250cm9sOwogICAgICAgICAgICAgICAgJHRleHRBcmVhLmNzcygicGFkZGluZyIsICIwcHggMHB4IDBweCIpOyAgLy8gVE9ETyA6IHRha2UgY2FyZSBvZiBtdWx0aWxpbmUgc2VsZWN0aW9uICYgcGFkZGluZyBsYXRlcgoKICAgICAgICAgICAgICAgIC8vIFRPRE8gOiBmaW5kIGEgc2NoZW1lIHRvIGF2b2lkIGF0dGFjaGluZyBhbmQgZGV0YWNoaW5nIGxpc3RlbmVycywgY3VycmVudGx5ICQudmFsKCkgY2F1c2VzICdpbnB1dCcgdG8gZmlyZSwgcmVzdWx0aW5nIGluIGFuIGluZmluaXRlIGxvb3AKICAgICAgICAgICAgICAgICR0ZXh0QXJlYS5vbmUoImlucHV0IiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkdGV4dEFyZWEucHJvcCgnc2Nyb2xsSGVpZ2h0JykgPiAkdGV4dEFyZWEucHJvcCgnb2Zmc2V0SGVpZ2h0JykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHRBcmVhLnZhbCh2YWwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wcm9wKCJzZWxlY3Rpb25TdGFydCIsIHNlbGVjdGlvbkVuZCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnByb3AoInNlbGVjdGlvbkVuZCIsIHNlbGVjdGlvbkVuZCk7ICAvLyBMQy00NjU2IDogcmVzZXQgdGhlIGN1cnNvciBwb3MsIGFmdGVyd2FyZHMKICAgICAgICAgICAgICAgICAgICAgICAgY2hhcmFjdGVyID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgY29kZSA9IDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghXy5jb250YWlucyhbJ2tleWRvd24nLCAnY3V0J10sIGV2ZW50LnR5cGUpICYmIHRoaXMuX21heENoYXJzUmVhY2hlZCh2YWwpICYmIHNlbGVjdGlvblN0YXJ0ID09PSBzZWxlY3Rpb25FbmQpIHsKICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXIoewogICAgICAgICAgICAgICAgdHlwZSA6ICJvbktleUlucHV0LnRleHRGaWVsZCIsCiAgICAgICAgICAgICAgICBvcmlnaW5hbFR5cGUgOiBldmVudC50eXBlLAogICAgICAgICAgICAgICAgY2hhcmFjdGVyIDogY2hhcmFjdGVyLCAgLy8gY29udGFpbnMgdGhlIHBhc3RlZCBzdHJpbmcgb3IgcHJlc3NlZCBrZXkKICAgICAgICAgICAgICAgIGtleUNvZGUgOiBldmVudC5rZXlDb2RlIHx8IDAsCiAgICAgICAgICAgICAgICBjaGFyQ29kZSA6IGV2ZW50LmNoYXJDb2RlIHx8IDAsCiAgICAgICAgICAgICAgICB3aGljaCA6IGV2ZW50LndoaWNoIHx8IDAsCiAgICAgICAgICAgICAgICBjdHJsS2V5IDogZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5IHx8IGZhbHNlLAogICAgICAgICAgICAgICAgc2hpZnRLZXkgOiBldmVudC5zaGlmdEtleSB8fCBmYWxzZSwKICAgICAgICAgICAgICAgIGtleURvd246IGZhbHNlLCAvLyBUaGlzIHByb3BlcnR5IGlzIGF2YWlsYWJsZSBvbmx5IGZvciBsaXN0IGJveGVzIGFuZCBkcm9wLWRvd24gbGlzdHMKICAgICAgICAgICAgICAgIHNlbGVjdGlvblN0YXJ0OiBzZWxlY3Rpb25TdGFydCwKICAgICAgICAgICAgICAgIHNlbGVjdGlvbkVuZDogc2VsZWN0aW9uRW5kCiAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVLZXlEb3duIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICBpZiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgIHZhciBjb2RlID0gZXZlbnQuY2hhckNvZGUgfHwgZXZlbnQud2hpY2ggfHwgZXZlbnQua2V5Q29kZSB8fCAwOwogICAgICAgICAgICAgICAgaWYoY29kZSA9PSA4IHx8IGNvZGUgPT0gNDYpIC8vIGJhY2tzcGFjZSBhbmQgZGVsCiAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVLZXlJbnB1dChldmVudCwgIiIsIGNvZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUtleVByZXNzIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICBpZiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgIHZhciBjb2RlID0gZXZlbnQuY2hhckNvZGUgfHwgZXZlbnQud2hpY2ggfHwgZXZlbnQua2V5Q29kZSB8fCAwLAogICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlciA9IChjb2RlID09IDEzKSA/ICJcbiIgOiBTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGUpOyAvLyBtb2RpZmllZCAnXHJcbicgLT4gJ1xuJwoKICAgICAgICAgICAgaWYoeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmlzTm9uUHJpbnRhYmxlS2V5KGV2ZW50LmtleSkpIHsgLy8gbW96aWxsYSBhbHNvIGdlbmVyYXRlcyBhIGtleXByZXNzLCBhbG9uZyB3aXRoIGtleWRvd24KICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIGFsbCBrZXlzLCBzbyBvbmx5IGhhbmRsaW5nIHByaW50YWJsZSBrZXlzIGluIGtleXByZXNzCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX2hhbmRsZUtleUlucHV0KGV2ZW50LCBjaGFyYWN0ZXIsIGNvZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2NvbXBvc2l0aW9uVXBkYXRlQ2FsbGJhY2sgOiBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICB2YXIgdmFsID0gdGhhdC4kdXNlckNvbnRyb2wudmFsKCk7CiAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSAiY29tcG9zaXRpb251cGRhdGUiICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQuZGF0YSkgewogICAgICAgICAgICAgICAgLy8gdGhpcyBoYXMgYmVlbiBkZWxpYmVyYXRlbHkgZG9uZSB0byBnZXQgdGhlIGFjdHVhbCBkYXRhIGluIGNhc2Ugb2YgbWF4IGNoYXJhY3Rlci4KICAgICAgICAgICAgICAgIGlmICh0aGF0Lm9wdGlvbnMubWF4Q2hhcnMpIHsKICAgICAgICAgICAgICAgICAgICB2YWwgPSBldmVudC5vcmlnaW5hbEV2ZW50LmRhdGE7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHZhbCA9IHZhbCArIGV2ZW50Lm9yaWdpbmFsRXZlbnQuZGF0YS5zdWJzdHIoZXZlbnQub3JpZ2luYWxFdmVudC5kYXRhLmxlbmd0aCAtIDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBmbGFnID0gdGhhdC5fbWF4Q2hhcnNSZWFjaGVkKHZhbCk7CiAgICAgICAgICAgIGlmIChmbGFnKSB7CiAgICAgICAgICAgICAgICAvLyBpZiBtYXggcmVhY2hlZAogICAgICAgICAgICAgICAgdmFyIG5ld1ZhbCA9IHZhbC5zdWJzdHIoMCwgdGhhdC5vcHRpb25zLm1heENoYXJzKTsKICAgICAgICAgICAgICAgIC8vaW4gY2FzZSB0aGUgdmFsdWUgaXMgbm90IGNoYW5nZWQgdGhlbiB3ZSBkbyBub3QgbmVlZCB0byB1cGRhdGUgdmFsdWUgYW5kIGNsb3NlIHRoZSBhbmRyb2lkIGtleWJvYXJkLgogICAgICAgICAgICAgICAgaWYgKHZhbCA9PT0gbmV3VmFsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhhdC4kdXNlckNvbnRyb2wudmFsKG5ld1ZhbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZsYWc7CiAgICAgICAgfSwKCiAgICAgICAgX2F0dGFjaEV2ZW50SGFuZGxlcnM6IGZ1bmN0aW9uKCRjb250cm9sKSB7CiAgICAgICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLl9hdHRhY2hFdmVudEhhbmRsZXJzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIC8vIElNRSBzcGVjaWZpYyBoYW5kbGluZywgdG8gaGFuZGxlIGphcGFuZXNlIGxhbmd1YWdlcyBtYXggbGltaXQKICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuX2F0dGFjaENvbXBvc2l0aW9uRXZlbnRIYW5kbGVycy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVQYXN0ZSA6IGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgaWYgKGV2ZW50KSB7CiAgICAgICAgICAgICAgICB2YXIgcGFzdGVkQ2hhciA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIGlmICh3aW5kb3cuY2xpcGJvYXJkRGF0YSAmJiB3aW5kb3cuY2xpcGJvYXJkRGF0YS5nZXREYXRhKSB7IC8vIElFCiAgICAgICAgICAgICAgICAgICAgcGFzdGVkQ2hhciA9IHdpbmRvdy5jbGlwYm9hcmREYXRhLmdldERhdGEoJ1RleHQnKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnQub3JpZ2luYWxFdmVudC5jbGlwYm9hcmREYXRhICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQuY2xpcGJvYXJkRGF0YS5nZXREYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgcGFzdGVkQ2hhciA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCd0ZXh0L3BsYWluJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihwYXN0ZWRDaGFyKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlS2V5SW5wdXQoZXZlbnQsIHBhc3RlZENoYXIsIDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUN1dCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmIChldmVudCkgewogICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlS2V5SW5wdXQoZXZlbnQsICIiLCAwKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHBvc3RQcm9jZXNzRXhpdDogZnVuY3Rpb24oZXZudCkgewogICAgICAgICAgICAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5wb3N0UHJvY2Vzc0V4aXQuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLm11bHRpTGluZSAmJiB0aGlzLm9wdGlvbnMuaFNjcm9sbERpc2FibGVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5faGFuZGxlVkFsaWduT25FeGl0KCk7CiAgICAgICAgfSwKCiAgICAgICAgcHJlUHJvY2Vzc0VudGVyOiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLnByZVByb2Nlc3NFbnRlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5tdWx0aUxpbmUgJiYgdGhpcy5vcHRpb25zLmhTY3JvbGxEaXNhYmxlZCkKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgdGhpcy5faGFuZGxlVkFsaWduT25FbnRlcigpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBicmllZjogU2VsZWN0IHRoZSBnaXZlbiBmaWVsZCBvbiBmb2N1cyBpbiBJbnRlcm5ldCBFeHBsb3JlcgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgX3NlbGVjdE9uRm9jdXNJbklFIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgLy8gaWYgdGhlIHZhbHVlIGlzIG5vdCBzYW1lIG9ubHkgdGhlbiBkbyBzZWxlY3Rpb24gaW4gSUUKICAgICAgICAgICAgLy8gRm9yIElzc3VlOiBMQy05ODk1LCB3ZSBjaGVjayBpZiB2YWx1ZSBub3Qgc2FtZQogICAgICAgICAgICBpZigkLmJyb3dzZXIubXNpZSAmJiAhdGhpcy5faXNWYWx1ZVNhbWUoKSkgewogICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuc2VsZWN0KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAvL2FsbCBvdGhlciBicm93c2VycyBiZWhhdmUgbGlrZSBhIGdvb2QgYm95CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBzaG93VmFsdWUgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuc2hvd1ZhbHVlLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICAgICAgLy9JRSBkb2Vzbid0IHNob3cgc2VsZWN0ZWQgdGV4dCBpZiB3ZSBmb2N1cyBhbmQgc2V0IGl0cyB2YWx1ZSBhbGwgdGhlIHRpbWUgc28gZm9yY2Ugc2VsZWN0aW9uCiAgICAgICAgICAgIHRoaXMuX3NlbGVjdE9uRm9jdXNJbklFKCk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0Q29tbWl0VmFsdWU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgdmFsdWUgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRDb21taXRWYWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwoKICAgICAgICAgICAgaWYodGhpcy5fbWF4Q2hhcnNSZWFjaGVkKHZhbHVlKSkgewogICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5zbGljZSgwLHRoaXMub3B0aW9ucy5tYXhDaGFycyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnZhbCh0aGlzLm9wdGlvbnMudmFsdWUpOwoKICAgICAgICAgICAgLy9UT0RPOiBhc2sgU2hhcmFkIHdoZXRoZXIgaXQgaXMgcmlnaHQKICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLm11bHRpTGluZSAmJiB0aGlzLm9wdGlvbnMuaFNjcm9sbERpc2FibGVkKSAgewogICAgICAgICAgICAgICAgLy92YXIgc3RyPSB0aGlzLl9jaGVja0xpbmVzKHZhbHVlKTsKICAgICAgICAgICAgICAgIC8vaWYodmFsdWUgIT0gc3RyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgKiogcmV0dXJucyB0aGUgY29udGVudEhlaWdodCB3aGljaCBuZWVkcyB0byBiZSBjb25zaWRlcmVkIGZvciBwYWRkaW5nIGZvciB2YWxpZ24sCiAgICAgICAgKiogaWYgbm8gY29udGVudEhlaWdodCBpcyBwcmVzZW50IHRoZW4gZm9udFNpemUgaXMgcmV0dXJuZWQuCiAgICAgICAgKi8KICAgICAgICBfZ2V0Q29udGVudEhlaWdodDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgY29udGVudEhlaWdodCA9IE1hdGguY2VpbCh0aGlzLiR1c2VyQ29udHJvbC5nZXQoMCkuc2Nyb2xsSGVpZ2h0KTsKICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnRIZWlnaHQgPyBjb250ZW50SGVpZ2h0IDogdGhpcy5vcHRpb25zLmZvbnRTaXplOwogICAgICAgIH0KICAgIH0pOwp9KSgkLCB3aW5kb3cuXyk7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX18KICoKICogIENvcHlyaWdodCAyMDE5IEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiBzdXBwbGllcnMgYW5kIG1heSBiZSBjb3ZlcmVkIGJ5IFUuUy4gYW5kIEZvcmVpZ24gUGF0ZW50cywKICogcGF0ZW50cyBpbiBwcm9jZXNzLCBhbmQgYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCihmdW5jdGlvbiAoJCkgewogICAgJC53aWRnZXQoInhmYVdpZGdldC5yaWNoVGV4dEZpZWxkIiwgJC54ZmFXaWRnZXQudGV4dEZpZWxkLCB7CgogICAgICAgIF93aWRnZXROYW1lIDogInJpY2hUZXh0RmllbGQiLAoKICAgICAgICBfcmljaFRleHRXaWRnZXQgOiBudWxsLAoKICAgICAgICBfY2hhbmdlQWNjZXNzIDogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICBzd2l0Y2ggKHZhbCkgewogICAgICAgICAgICAgICAgY2FzZSAib3BlbiI6CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3JpY2hUZXh0V2lkZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3JpY2hUZXh0V2lkZ2V0LmVkaXRvci5lbmFibGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmljaFRleHRXaWRnZXQuJHRvb2xiYXIucmVtb3ZlQ2xhc3MoImhpZGVUb29sYmFyIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAicmVhZE9ubHkiOgogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9yaWNoVGV4dFdpZGdldCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9yaWNoVGV4dFdpZGdldC5lZGl0b3IuZGlzYWJsZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9yaWNoVGV4dFdpZGdldC4kdG9vbGJhci5hZGRDbGFzcygiaGlkZVRvb2xiYXIiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBnZXRPcHRpb25zTWFwIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgcGFyZW50T3B0aW9uc01hcCA9ICQueGZhV2lkZ2V0LnRleHRGaWVsZC5wcm90b3R5cGUuZ2V0T3B0aW9uc01hcC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICByZXR1cm4gJC5leHRlbmQoe30sIHBhcmVudE9wdGlvbnNNYXAsIHsKICAgICAgICAgICAgICAgICJ2YWx1ZSIgOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3JpY2hUZXh0V2lkZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3JpY2hUZXh0V2lkZ2V0LnNldFJpY2hUZXh0RWRpdG9yQ29udGVudCh2YWwpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiYWNjZXNzIiA6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VBY2Nlc3ModmFsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RXZlbnRNYXAgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vIGluIGNhc2Ugb2YgSUUgYnJvd3NlcnMsIGZvY3VzIGV2ZW50IGlzIGRlbGF5ZWQsIGhlbmNlIGFkZGluZyBhY3RpdmF0ZSBtZXRob2QgZm9yIGNvbnRlbnQgZWRpdGFibGUKICAgICAgICAgICAgaWYgKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5pc0lFKCkpIHsKICAgICAgICAgICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQudGV4dEZpZWxkLnByb3RvdHlwZS5nZXRFdmVudE1hcC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LCBwYXJlbnRPcHRpb25zTWFwLCB7CiAgICAgICAgICAgICAgICAgICAgImFjdGl2YXRlLnJpY2hUZXh0RmllbGQiIDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FTlRFUl9FVkVOVAogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJC54ZmFXaWRnZXQudGV4dEZpZWxkLnByb3RvdHlwZS5nZXRFdmVudE1hcC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcmVuZGVyIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgJHJpY2hUZXh0V2lkZ2V0ID0gdGhpcy5lbGVtZW50LmZpbmQoImRpdi5yaWNoVGV4dFdpZGdldCIpLmVxKDApOwogICAgICAgICAgICBpZighJHJpY2hUZXh0V2lkZ2V0Lmxlbmd0aCl7CiAgICAgICAgICAgICAgICB2YXIgYXR0YWNoZWRUZXh0YXJlYUNsYXNzZXMgPSB0aGlzLmVsZW1lbnQuY2hpbGRyZW4oKS5hdHRyKCdjbGFzcycpOwogICAgICAgICAgICAgICAgdmFyIHJpY2hUZXh0V2lkZ2V0RWxlbWVudCA9ICc8ZGl2IGNsYXNzPSJyaWNoVGV4dFdpZGdldCAnICsgYXR0YWNoZWRUZXh0YXJlYUNsYXNzZXMgKyAnIiBpZD0icmljaFRleHRGaWVsZF8nICsgdGhpcy5vcHRpb25zLm5hbWUgKyAnXycgKyBhdHRhY2hlZFRleHRhcmVhQ2xhc3NlcyArICciPjwvZGl2Pic7CiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQuY2hpbGRyZW4oKS5yZW1vdmUoKTsKICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmQocmljaFRleHRXaWRnZXRFbGVtZW50KTsKICAgICAgICAgICAgICAgICRyaWNoVGV4dFdpZGdldCA9IHRoaXMuZWxlbWVudC5maW5kKCJkaXYucmljaFRleHRXaWRnZXQiKS5lcSgwKTsKICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAkcmljaFRleHRXaWRnZXQuY2hpbGRyZW4oKS5yZW1vdmUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcmljaFRleHRXaWRnZXQuYXBwZW5kKHRoaXMub3B0aW9ucy52YWx1ZSk7CiAgICAgICAgICAgIHJldHVybiAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5yZW5kZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBnZXRDb21taXRWYWx1ZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHZhbHVlID0gIiI7CiAgICAgICAgICAgIGlmICh0aGlzLl9yaWNoVGV4dFdpZGdldCkgewogICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9yaWNoVGV4dFdpZGdldC5nZXRSaWNoVGV4dEVkaXRvckNvbnRlbnQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgcHJlUHJvY2Vzc0VudGVyIDogZnVuY3Rpb24gKGV2bnQpIHsKICAgICAgICAgICAgJC54ZmFXaWRnZXQudGV4dEZpZWxkLnByb3RvdHlwZS5wcmVQcm9jZXNzRW50ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdmFyICRyaWNoVGV4dERpdiA9IHRoaXMuJHVzZXJDb250cm9sLmZpbmQoImRpdi5yaWNoVGV4dFdpZGdldCIpLmVxKDApOwogICAgICAgICAgICBpZighJHJpY2hUZXh0RGl2Lmxlbmd0aCl7CiAgICAgICAgICAgICAgICAkcmljaFRleHREaXYgPSB0aGlzLmVsZW1lbnQuZmluZCgiZGl2LnJpY2hUZXh0V2lkZ2V0IikuZXEoMCk7CiAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZURlZmF1bHRUb29sYmFyQ29uZmlnKCk7CiAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5wYXJlbnRzKCcucmljaHRleHRzdXBwb3J0JykuY3NzKCd6LWluZGV4JywgJ2F1dG8nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAod2luZG93LkZvcm0gPT09IHVuZGVmaW5lZCB8fCB3aW5kb3cuRm9ybS5ydGUgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgLyogRm9ybXMgUlRFIGlzIHBhcnQgb2YgRm9ybXMgQWRkb24gcGFja2FnZSBvbmx5LiBEb250IGRvIGFueXRoaW5nIGlmIGFkZG9uIGlzIG5vdCBpbnN0YWxsZWQuKi8KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9yaWNoVGV4dFdpZGdldCA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhpcy5faW5pdGlhbGl6ZVJURVRvb2xiYXIoKTsKICAgICAgICAgICAgICAgIHRoaXMuX3JpY2hUZXh0V2lkZ2V0ID0gbmV3IHdpbmRvdy5Gb3JtLnJ0ZS5SaWNoVGV4dEVkaXRvcih7CiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3IgOiAkcmljaFRleHREaXYuYXR0cigiaWQiKSwKICAgICAgICAgICAgICAgICAgICB0b29sYmFyIDogd2luZG93LkZvcm0ucnRlLlJpY2hUZXh0RWRpdG9yLk1GVG9vbGJhciwKICAgICAgICAgICAgICAgICAgICBkYXRhIDogdGhpcy5vcHRpb25zLnZhbHVlLAogICAgICAgICAgICAgICAgICAgIGxvY2FsZSA6ICRyaWNoVGV4dERpdi5kYXRhKCJsb2NhbGUiKQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgICAgICB0aGlzLl9yaWNoVGV4dFdpZGdldC5lZGl0b3Iub24oImJsdXI6Y29tcG9zZXIiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgdGhhdC4kdXNlckNvbnRyb2wudHJpZ2dlcigiYmx1ciIpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAvLyBpbml0aWFsaXplIHRoZSBhY2Nlc3MKICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuYWNjZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2hhbmdlQWNjZXNzKHRoaXMub3B0aW9ucy5hY2Nlc3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgY2hhbmdlRGVmYXVsdFRvb2xiYXJDb25maWc6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHdpbmRvdy5Gb3JtICYmIHdpbmRvdy5Gb3JtLnJ0ZSl7CiAgICAgICAgICAgICAgICB2YXIgdG9vbGJhckRlZmF1bHRDb25maWdEYXRhID0gd2luZG93LkZvcm0ucnRlLkRlZmF1bHRDb25maWc7CiAgICAgICAgICAgICAgICB0b29sYmFyRGVmYXVsdENvbmZpZ0RhdGEuZm9udFNpemUuZGVmYXVsdFZhbHVlID0gdGhpcy5vcHRpb25zLmZvbnRTaXplOwogICAgICAgICAgICAgICAgdG9vbGJhckRlZmF1bHRDb25maWdEYXRhLmZvbnRGYW1pbHkuZGVmYXVsdFZhbHVlID0gdGhpcy5vcHRpb25zLmZvbnRGYW1pbHk7CgogICAgICAgICAgICAgICAgLy8gQWRkaW5nICdpc0ZvbnRJblB4JyBmbGFnIGFuZCBvdmVycmlkaW5nIHR3byB1dGlsaXR5IGZ1bmN0aW9ucwogICAgICAgICAgICAgICAgLy8gJ2dldERlZmF1bHRQYXJhU3R5bGUnIGFuZCAnZ2V0TWlzc2luZ1BhcmFTdHlsZScgYXJlIHJlc3BvbnNpYmxlIGZvciBhZGRpbmcgUlRFIGZvbnQgc3R5bGluZyBhdHRyaWJ1dGVzIHRvIHJpY2ggdGV4dCBlbGVtZW50cwogICAgICAgICAgICAgICAgdG9vbGJhckRlZmF1bHRDb25maWdEYXRhLmlzRm9udEluUHggPSB0cnVlOwogICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VEZWZhdWx0UGFyYVN0eWxlVXRpbGl0eSgpOwogICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VNaXNzaW5nUGFyYVN0eWxlVXRpbGl0eSgpOwoKICAgICAgICAgICAgICAgIC8vIEFkZGluZyBkcm9wZG93biB2YWx1ZXMgaW4gZGVmYXVsdCBjb25maWcgaWYgbm90IGF2YWlsYWJsZSBpbiBvcHRpb25zCiAgICAgICAgICAgICAgICBpZih0b29sYmFyRGVmYXVsdENvbmZpZ0RhdGEuZm9udFNpemUub3B0aW9ucy5pbmRleE9mKHRoaXMub3B0aW9ucy5mb250U2l6ZSkgPT09IC0xKXsKICAgICAgICAgICAgICAgICAgICB0b29sYmFyRGVmYXVsdENvbmZpZ0RhdGEuZm9udFNpemUub3B0aW9ucy5wdXNoKHRoaXMub3B0aW9ucy5mb250U2l6ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZih0b29sYmFyRGVmYXVsdENvbmZpZ0RhdGEuZm9udEZhbWlseS5vcHRpb25zLmluZGV4T2YodGhpcy5vcHRpb25zLmZvbnRGYW1pbHkpID09PSAtMSl7CiAgICAgICAgICAgICAgICAgICAgdG9vbGJhckRlZmF1bHRDb25maWdEYXRhLmZvbnRGYW1pbHkub3B0aW9ucy5wdXNoKHRoaXMub3B0aW9ucy5mb250RmFtaWx5KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNoYW5nZURlZmF1bHRQYXJhU3R5bGVVdGlsaXR5OiBmdW5jdGlvbigpewogICAgICAgICAgICBGb3JtLnJ0ZS51dGlsLkh0bWxVdGlscy5nZXREZWZhdWx0UGFyYVN0eWxlID0gZnVuY3Rpb24gKGNvbmZpZykgewogICAgICAgICAgICAgICAgdmFyIHN0eWxlID0gIiI7CiAgICAgICAgICAgICAgICBpZiAoY29uZmlnKSB7CiAgICAgICAgICAgICAgICAgICAgc3R5bGUgKz0gJ2ZvbnQtZmFtaWx5OicgKyBjb25maWcuZm9udEZhbWlseS5kZWZhdWx0VmFsdWUgKyAnOyc7CiAgICAgICAgICAgICAgICAgICAgaWYoY29uZmlnLmlzRm9udEluUHgpewogICAgICAgICAgICAgICAgICAgICAgICBzdHlsZSArPSAnZm9udC1zaXplOicgKyBjb25maWcuZm9udFNpemUuZGVmYXVsdFZhbHVlICsgJ3B4Oyc7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdsZXR0ZXItc3BhY2luZzonICsgY29uZmlnLmxldHRlclNwYWNpbmcuZGVmYXVsdFZhbHVlICsgJ3B4Oyc7CiAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdmb250LXNpemU6JyArIGNvbmZpZy5mb250U2l6ZS5kZWZhdWx0VmFsdWUgKyAncHQ7JzsKICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgKz0gJ2xldHRlci1zcGFjaW5nOicgKyBjb25maWcubGV0dGVyU3BhY2luZy5kZWZhdWx0VmFsdWUgKyAncHQ7JzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgc3R5bGUgKz0gJ2NvbG9yOiMwMDAwMDA7JzsKICAgICAgICAgICAgICAgICAgICBzdHlsZSArPSAndGV4dC1hbGlnbjpsZWZ0Oyc7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIHN0eWxlOwogICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIGNoYW5nZU1pc3NpbmdQYXJhU3R5bGVVdGlsaXR5IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgRm9ybS5ydGUudXRpbC5IdG1sVXRpbHMuZ2V0TWlzc2luZ1BhcmFTdHlsZSA9IGZ1bmN0aW9uIChzdHlsZSwgY29uZmlnKSB7CiAgICAgICAgICAgICAgICBpZiAoc3R5bGUgJiYgc3R5bGUubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgIGlmIChjb25maWcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFGb3JtLnJ0ZS51dGlsLlN0cmluZ0hlbHBlci5lbmRzV2l0aChzdHlsZSwgIjsiKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgKz0gIjsiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHlsZS5pbmRleE9mKCJmb250LWZhbWlseSIpIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgKz0gJ2ZvbnQtZmFtaWx5OicgKyBjb25maWcuZm9udEZhbWlseS5kZWZhdWx0VmFsdWUgKyAnOyc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0eWxlLmluZGV4T2YoImZvbnQtc2l6ZSIpIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY29uZmlnLmlzRm9udEluUHgpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdmb250LXNpemU6JyArIGNvbmZpZy5mb250U2l6ZS5kZWZhdWx0VmFsdWUgKyAncHg7JzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdmb250LXNpemU6JyArIGNvbmZpZy5mb250U2l6ZS5kZWZhdWx0VmFsdWUgKyAncHQ7JzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGUuaW5kZXhPZigibGV0dGVyLXNwYWNpbmciKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNvbmZpZy5pc0ZvbnRJblB4KXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZSArPSAnbGV0dGVyLXNwYWNpbmc6JyArIGNvbmZpZy5sZXR0ZXJTcGFjaW5nLmRlZmF1bHRWYWx1ZSArICdweDsnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgKz0gJ2xldHRlci1zcGFjaW5nOicgKyBjb25maWcubGV0dGVyU3BhY2luZy5kZWZhdWx0VmFsdWUgKyAncHQ7JzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGUuaW5kZXhPZigiY29sb3IiKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdjb2xvcjojMDAwMDAwOyc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0eWxlLmluZGV4T2YoInRleHQtYWxpZ24iKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICd0ZXh0LWFsaWduOmxlZnQ7JzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBGb3JtLnJ0ZS51dGlsLkh0bWxVdGlscy5nZXREZWZhdWx0UGFyYVN0eWxlKGNvbmZpZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gc3R5bGU7CiAgICAgICAgICAgIH07CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRpYWxpemVSVEVUb29sYmFyIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB3aW5kb3cuRm9ybS5ydGUuUmljaFRleHRFZGl0b3IuTUZUb29sYmFyID0gd2luZG93LkZvcm0ucnRlLlJpY2hUZXh0RWRpdG9yLk1GVG9vbGJhciB8fCB7CiAgICAgICAgICAgICAgICBkZWZhdWx0TW9kZSA6ICdiYXNpYycsCiAgICAgICAgICAgICAgICB0b29sYmFycyA6IHsKICAgICAgICAgICAgICAgICAgICBiYXNpYyA6IHsKICAgICAgICAgICAgICAgICAgICAgICAgbGF5b3V0IDogWwogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zIDogW0Zvcm0ucnRlLkNvbW1hbmRzLkhFQURFUl0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMgOiBbRm9ybS5ydGUuQ29tbWFuZHMuQk9MRCwgRm9ybS5ydGUuQ29tbWFuZHMuSVRBTElDLCBGb3JtLnJ0ZS5Db21tYW5kcy5VTkRFUkxJTkVdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgOiAnbGlzdHMnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb24gOiAnbGlzdCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgOiAiTGlzdCBUeXBlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlIDogJ3BvcG92ZXInLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlbWVudCA6ICdib3R0b20nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zIDogW0Zvcm0ucnRlLkNvbW1hbmRzLklOU0VSVF9VTk9SREVSRURfTElTVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybS5ydGUuQ29tbWFuZHMuSU5TRVJUX09SREVSRURfTElTVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybS5ydGUuQ29tbWFuZHMuSU5TRVJUX0xPV0VSQ0FTRV9BTFBIQUJFVF9MSVNUXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA6ICdFeHBhbmQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgOiBGb3JtLnJ0ZS5Db21tYW5kcy5NT0RFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIDogRm9ybS5ydGUuVG9vbGJhck1vZGUuRlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpY29uIDogJ3Jlc2l6ZS1mdWxsJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICAgICBmbG9hdGluZyA6IHRydWUKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIGZ1bGwgOiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxheW91dCA6IFsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtcyA6IFtGb3JtLnJ0ZS5Db21tYW5kcy5CT0xELCBGb3JtLnJ0ZS5Db21tYW5kcy5JVEFMSUMsIEZvcm0ucnRlLkNvbW1hbmRzLlVOREVSTElORV0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMgOiBbRm9ybS5ydGUuQ29tbWFuZHMuU1VQRVJTQ1JJUFQsIEZvcm0ucnRlLkNvbW1hbmRzLlNVQlNDUklQVF0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMgOiBbCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvcm0ucnRlLkNvbW1hbmRzLkhFQURFUiwgRm9ybS5ydGUuQ29tbWFuZHMuRk9OVF9GQU1JTFksIEZvcm0ucnRlLkNvbW1hbmRzLkxJTkVfSEVJR0hULCBGb3JtLnJ0ZS5Db21tYW5kcy5GT1JFX0NPTE9SLCBGb3JtLnJ0ZS5Db21tYW5kcy5ISUxJVEVfQ09MT1IsIEZvcm0ucnRlLkNvbW1hbmRzLkxJTksKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zIDogW0Zvcm0ucnRlLkNvbW1hbmRzLklOU0VSVF9VTk9SREVSRURfTElTVCwgRm9ybS5ydGUuQ29tbWFuZHMuSU5TRVJUX09SREVSRURfTElTVCwgRm9ybS5ydGUuQ29tbWFuZHMuSU5TRVJUX0xPV0VSQ0FTRV9BTFBIQUJFVF9MSVNUCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA6ICdDb2xsYXBzZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZCA6IEZvcm0ucnRlLkNvbW1hbmRzLk1PREUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgOiBGb3JtLnJ0ZS5Ub29sYmFyTW9kZS5CQVNJQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpY29uIDogJ3Jlc2l6ZS1zbWFsbCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQgOiB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfSk7Cgp9KSgkKTsoZnVuY3Rpb24oJCl7CgkkLndpZGdldCggInhmYVdpZGdldC5pbWFnZUZpZWxkIiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgewoKICAgIF93aWRnZXROYW1lOiJpbWFnZUZpZWxkIiwKCiAgICBvcHRpb25zOiB7CiAgICAgICAgdGFiSW5kZXg6IDAsCiAgICAgICAgInJvbGUiOiAiaW1nIgogICAgfSwKCiAgICBnZXRFdmVudE1hcDogZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0RXZlbnRNYXAuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICByZXR1cm4gJC5leHRlbmQoe30sIHBhcmVudE9wdGlvbnNNYXAsIHsKICAgICAgICAgICAgImltYWdlY2hhbmdlIjogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQKICAgICAgICB9KQogICAgfSwKCiAgICBnZXRPcHRpb25zTWFwOiBmdW5jdGlvbigpIHsKICAgICAgICB2YXIgcGFyZW50T3B0aW9uc01hcCA9ICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmdldE9wdGlvbnNNYXAuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSxwYXJlbnRPcHRpb25zTWFwLHsKICAgICAgICAgICAgInNjcmVlblJlYWRlclRleHQiOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgIGlmKHZhbCkKICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJhbHQiLCB2YWwpCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJkaXNwbGF5VmFsdWUiOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgIHZhciB3aWRnZXRWYWx1ZTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMudmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICB3aWRnZXRWYWx1ZSA9ICJkYXRhOjtiYXNlNjQsIiArIHRoaXMub3B0aW9ucy52YWx1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgd2lkZ2V0VmFsdWUgPSAiIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnByb3AodGhpcy5vcHRpb25zLmNvbW1pdFByb3BlcnR5LCB3aWRnZXRWYWx1ZSk7CiAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKHRoaXMub3B0aW9ucy5jb21taXRQcm9wZXJ0eSwgd2lkZ2V0VmFsdWUpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAiYWNjZXNzIiA6IGZ1bmN0aW9uKCkge30sCgogICAgICAgICAgICAvLyBDUS04NTUxNCA6IHVzZSBtYXgtaHQgJiBtYXgtd2QgdG8gaG9ub3IgaW1hZ2UncyBpbnRyaW5zaWMgaHQgJiB3ZCBhdHRyaWJ1dGVzICYgcHJldmVudCBkaXN0b3J0aW9uCiAgICAgICAgICAgICJoZWlnaHQiIDogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgLy8gaW4gY2FzZSBhc3BlY3QgaXMgYWN0dWFsIHRoZW4gd2UgbmVlZCB0byBjcm9wIHRoZSBpbWFnZSwgd2hpY2ggd2lsbCBiZSBub3QgcG9zc2libGUgaWYgbWF4IGhlaWdodCBhbmQgd2lkdGggYXJlIHNldAogICAgICAgICAgICAgICAgaWYgKHZhbCAmJiB0aGlzLm9wdGlvbnMuYXNwZWN0ICE9ICJhY3R1YWwiKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuJHVzZXJDb250cm9sWzBdLCB7Im1heC1oZWlnaHQiOiB2YWx9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgIndpZHRoIiA6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgIGlmICh2YWwgJiYgdGhpcy5vcHRpb25zLmFzcGVjdCAhPSAiYWN0dWFsIikgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLiR1c2VyQ29udHJvbFswXSwgeyJtYXgtd2lkdGgiOiB2YWx9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgImFzcGVjdCIgOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAvLyB2YWx1ZSBvZiBhY3R1YWwgdHVybnMgb2ZmIHNjYWxpbmcsIGNhdXNpbmcgdGhlIGltYWdlIHRvIGJlIGRyYXduIGF0IGl0cyBuYXRpdmUgc2l6ZSwKICAgICAgICAgICAgICAgIC8vIGFzIHBlciB4ZmEgc3BlYyBBZG9iZSBpbXBsZW1lbnRhdGlvbnMgY3JvcCB0aGUgaW1hZ2UKICAgICAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5hc3BlY3QgPT0gImFjdHVhbCIpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcmlnaHQgPSB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJ3aWR0aCIpLAogICAgICAgICAgICAgICAgICAgICAgICBib3R0b20gPSB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJoZWlnaHQiKTsKICAgICAgICAgICAgICAgICAgICByaWdodCA9IHJpZ2h0LmluZGV4T2YoInB4IikgPj0gMCA/IHJpZ2h0IDogcmlnaHQgKyAicHgiOwogICAgICAgICAgICAgICAgICAgIGJvdHRvbSA9IGJvdHRvbS5pbmRleE9mKCJweCIpID49IDAgPyBib3R0b20gOiBib3R0b20gKyAicHgiOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Nyb3BJbWFnZSgiMHB4IiwgcmlnaHQsIGJvdHRvbSwgIjBweCIpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImhlaWdodCB3aWR0aCIpOwogICAgICAgICAgICAgICAgLy8gdmFsdWUgb2Ygbm9uZSBpbmRpY2F0ZXMgbm8gYXNwZWN0IHJhdGlvCiAgICAgICAgICAgICAgICAvLyBhcyBwZXIgeGZhIHNwZWMgaW1hZ2UgaXMgaW5kZXBlbmRlbnRseSBzY2FsZWQgaW4gdGhlIGhvcml6b250YWwgYW5kIHZlcnRpY2FsIGRpcmVjdGlvbnMgdG8gZXhhY3RseSBmaWxsIHRoZSBmaWVsZCwKICAgICAgICAgICAgICAgIC8vIHdoaWNoIGFyZSBhbHJlYWR5IHNldCB0byBmaWxsIHRoZSBmaWVsZAogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLm9wdGlvbnMuYXNwZWN0ICE9ICJub25lIikgewogICAgICAgICAgICAgICAgLy8gQSB2YWx1ZSBvZiBmaXQsIHdoaWNoIGlzIHRoZSBkZWZhdWx0LCBjYXVzZXMgdGhlIHNjYWxlIHRvIGJlIHN1Y2ggdGhhdCB0aGUgaW1hZ2UgZmlsbHMgYXMgbXVjaCBvZiB0aGUgZmllbGQgYXMgcG9zc2libGUKICAgICAgICAgICAgICAgIC8vIHdpdGhvdXQgb3ZlcmZsb3dpbmcgaXQgaW4gZWl0aGVyIGRpbWVuc2lvbi4KICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKHsiaGVpZ2h0IiA6ICJhdXRvIiwgIndpZHRoIiA6ICJhdXRvIn0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9LAoKICAgIC8vIGNyb3AgdGhlIGltYWdlIHVzaW5nIHRvcCxyaWdodCwgYm90dG9tLCBsZWZ0IGNvb3JkaWFudGVzIG9mIHRoZSBpbWFnZQogICAgX2Nyb3BJbWFnZSA6IGZ1bmN0aW9uICh0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQpIHsKICAgICAgICB2YXIgY2xpcFJlY3QgPSAicmVjdCgiICsgdG9wICsgIiwiICsgcmlnaHQgKyAiLCIgKyBib3R0b20gKyAiLCIgKyBsZWZ0ICsgIikiOwogICAgICAgIHZhciBjbGlwUGF0aFBvbHlnb24gPSAicG9seWdvbiggMHB4IDBweCwgMHB4ICIgKyBib3R0b20gKyAiLCIgKyByaWdodCArICIgIiArIGJvdHRvbSArIiwiICsgcmlnaHQgKyAiIDBweCkiOwogICAgICAgIC8vIGNsaXAgcHJvcGVydHkgaXMgZGVwcmVjYXRlZCBidXQgc3RpbGwgc3VwcG9ydGVkIGJ5IGFsbCB0aGUgbWFqb3IgYnJvd3NlcnMKICAgICAgICAvLyBjbGlwLXBhdGggcmVwbGFjZXMgdGhlIGRlcHJlY2F0ZWQgY2xpcCBwcm9wZXJ0eSBidXQgc3RpbGwgaXMgbm90IGZ1bGx5IHN1cHBvcnRlZCBieSBhbGwgbWFqb3IgYnJvd3NlcgogICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNzcyh7ImNsaXAiIDogY2xpcFJlY3QsICJjbGlwLXBhdGgiIDogY2xpcFBhdGhQb2x5Z29ufSk7CiAgICB9LAoKICAgIHJlbmRlciA6IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciBzZWxmID0gdGhpczsKICAgICAgICBpZiAodHlwZW9mIEZpbGVSZWFkZXIgIT09ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgIHRoaXMucmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0TG9nZ2VyKCkuZXJyb3IoIkltYWdlIEZpZWxkIGlzIHN1cHBvcnRlZCBvbmx5IGZvciBIVE1MNSBzdXBwb3J0ZWQgYnJvd3NlcnMuIik7CiAgICAgICAgfQogICAgICAgIGlmICh0aGlzLmVsZW1lbnQpIHsKICAgICAgICAgICAgLy8gY2hhbmdlIGV2ZW50IHRyaWdnZXJlZCB3aGVuIG5ldyBpbWFnZSBpcyBzZWxlY3RlZAogICAgICAgICAgICB0aGlzLiR3aWRnZXRJbnB1dCA9IHRoaXMuZWxlbWVudC5maW5kKCJpbnB1dCIpLm9uKCJjaGFuZ2UuaW1hZ2VGaWVsZCIsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgc2VsZi5faGFuZGxlSW5wdXRDaGFuZ2UoKTsKICAgICAgICAgICAgfSkuY2xpY2soZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgICAgIC8vIHRvIHN0b3AgYnViYmxpbmcgb2YgZXZlbnQgZnJvbSBpbnB1dCB0byB3aWRnZXQKICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgdGhpcy4kd2lkZ2V0SW1nID0gdGhpcy5lbGVtZW50Lm9uKCJjbGljay5pbWFnZUZpZWxkIiwgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICBzZWxmLl9pbWFnZUNsaWNrKCk7CiAgICAgICAgICAgIH0pLmZpbmQoImltZyIpOwogICAgICAgIH0KICAgICAgICBpZiAodGhpcy5yZWFkZXIpIHsKICAgICAgICAgICAgLy9sb2FkIGV2ZW50IGlzIHRyaWdnZXJlZCBlYWNoIHRpbWUgdGhlIHJlYWRpbmcgb3BlcmF0aW9uIGlzIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQKICAgICAgICAgICAgdGhpcy5yZWFkZXIuYWRkRXZlbnRMaXN0ZW5lcigibG9hZCIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHNlbGYuJHdpZGdldEltZy5hdHRyKCJzcmMiLHNlbGYucmVhZGVyLnJlc3VsdCk7CiAgICAgICAgICAgICAgICBzZWxmLiR3aWRnZXRJbWcudHJpZ2dlcigiaW1hZ2VjaGFuZ2UiKTsKICAgICAgICAgICAgfSwgZmFsc2UpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUucmVuZGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICB9LAoKICAgIGdldENvbW1pdFZhbHVlOiBmdW5jdGlvbigpIHsKICAgICAgICByZXR1cm4gdGhpcy5fZXh0cmFjdERhdGEodGhpcy4kdXNlckNvbnRyb2wuYXR0cigic3JjIikpOwogICAgfSwKCiAgICAvLyBoaWRkZW4gaW5wdXQgY2hhbmdlIGhhbmRsZXIsIGlucHV0IGNoYW5nZSB3aWxsIGJlIHRyaWdnZXJlZCBvbiBzZWxlY3RpbmcgYSBuZXcgaW1hZ2UKICAgIF9oYW5kbGVJbnB1dENoYW5nZSA6IGZ1bmN0aW9uKCkgewogICAgICAgIHRoaXMuX2Rpc3BsYXlJbWFnZSgpOwogICAgfSwKCiAgICBfaW1hZ2VDbGljayA6IGZ1bmN0aW9uKGNsaWNrRXZlbnQpIHsKICAgICAgICAvL2FzIHRoZSBpbnB1dCBidXR0b24gaXMgaGlkZGVuIHdlIHRyaWdnZXIgY2xpY2sgZXhwbGljaXRseSBvbiBjbGljayBvZiB0aGUgd2lkZ2V0CiAgICAgICAgdGhpcy4kd2lkZ2V0SW5wdXQudHJpZ2dlcigiY2xpY2siKTsKICAgIH0sCgogICAgLy8gcmVtb3ZlcyAiZGF0YVw6LipcO2Jhc2U2NCwiIGZyb20gdGhlIGltYWdlIGJhc2U2NCBzdHJpbmcKICAgIF9leHRyYWN0RGF0YSA6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL2RhdGFcOi4qXDtiYXNlNjQsLywgIiIpOwogICAgfSwKCiAgICAvLyBwcmV2aWV3cyBpbWFnZSBpbiB0aGUgaW1hZ2VmaWVsZCB3aWRnZXQKICAgIF9kaXNwbGF5SW1hZ2UgOiBmdW5jdGlvbigpIHsKICAgICAgICB2YXIgaW1hZ2VGaWxlID0gdGhpcy4kd2lkZ2V0SW5wdXQuZ2V0KDApLmZpbGVzID8gdGhpcy4kd2lkZ2V0SW5wdXQuZ2V0KDApLmZpbGVzWzBdIDogbnVsbDsKICAgICAgICBpZiAoaW1hZ2VGaWxlICYmIHRoaXMuX2lzRmlsZU9mSW1hZ2VUeXBlKGltYWdlRmlsZS5uYW1lKSkgewogICAgICAgICAgICBpZiAodGhpcy5yZWFkZXIpIHsKICAgICAgICAgICAgICAgIC8vcmVhZEFzRGF0YVVSTCBtZXRob2QgaXMgdXNlZCB0byByZWFkIHRoZSBjb250ZW50cyBvZiB0aGUgc3BlY2lmaWVkIGZpbGUsIHJlc3VsdCBhdHRyaWJ1dGUgY29udGFpbnMgIHRoZSBkYXRhIGFzIGEgVVJMIHJlcHJlc2VudGluZyB0aGUgZmlsZSdzIGRhdGEgYXMgYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcKICAgICAgICAgICAgICAgIHRoaXMucmVhZGVyLnJlYWRBc0RhdGFVUkwoaW1hZ2VGaWxlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sCgogICAgLy8gVGVzdCBmb3Igc3VwcG9ydGVkIGltYWdlIGZpbGUoanBnLGpwZWcscG5nLGdpZix0aWYsYm1wKQogICAgX2lzRmlsZU9mSW1hZ2VUeXBlIDogZnVuY3Rpb24oZmlsZU5hbWUpIHsKICAgICAgICBpZiAoZmlsZU5hbWUpIHsKICAgICAgICAgICAgcmV0dXJuICgvXC4oanBlP2d8cG5nfGdpZnx0aWZ8Ym1wKSQvaS50ZXN0KGZpbGVOYW1lKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfSk7Cn0pKCQpOwovKioKICogQ3JlYXRlZCB3aXRoIEludGVsbGlKIElERUEuCiAqIFVzZXI6IHJwYW5kZXkKICogRGF0ZTogMTIvMjQvMTIKICogVGltZTogODowNiBQTQogKiBUbyBjaGFuZ2UgdGhpcyB0ZW1wbGF0ZSB1c2UgRmlsZSB8IFNldHRpbmdzIHwgRmlsZSBUZW1wbGF0ZXMuCiAqLwoKCihmdW5jdGlvbigkKXsKICAgICQud2lkZ2V0KCAieGZhV2lkZ2V0LnNpZ25hdHVyZUZpZWxkIiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgewoKICAgICAgICBfd2lkZ2V0TmFtZToic2lnbmF0dXJlRmllbGQiLAoKICAgICAgICBnZXRPcHRpb25zTWFwOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LHBhcmVudE9wdGlvbnNNYXAsewogICAgICAgICAgICAgICAgImRpc3BsYXlWYWx1ZSI6IGZ1bmN0aW9uKHZhbCkge30sCiAgICAgICAgICAgICAgICAiYWNjZXNzIjogZnVuY3Rpb24odmFsKSB7fQogICAgICAgICAgICB9KQogICAgICAgIH0sCgogICAgICAgIHJlbmRlciA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgJGNvbnRyb2wgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5yZW5kZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgLy9wZXNzaW1pc3RpYyBjaGVja3MKICAgICAgICAgICAgaWYoJGNvbnRyb2wpIHsKICAgICAgICAgICAgICAgICRjb250cm9sLmF0dHIoInJlYWRPbmx5IiwicmVhZG9ubHkiKS5hdHRyKCJkaXNhYmxlZCIsIHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAkY29udHJvbDsKICAgICAgICB9CiAgICB9KTsKfSkoJCk7Ci8qCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX19fCiAqCiAqIENvcHlyaWdodCAyMDExLTIwMTIgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogc3VwcGxpZXJzIGFuZCBtYXkgYmUgY292ZXJlZCBieSBVLlMuIGFuZCBGb3JlaWduIFBhdGVudHMsCiAqIHBhdGVudHMgaW4gcHJvY2VzcywgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuCiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKi8KIAovKioKICogd2lkZ2V0IGRlZmluaXRpb24gZm9yIHNjcmliYmxlYWJsZSBmaWVsZAogKi8KKGZ1bmN0aW9uKCQseGZhbGliKXsKCiB2YXIgVG91Y2hVdGlsPXhmYWxpYi51dC5Ub3VjaFV0aWw7CiB2YXIgU2NyaWJibGVVdGlsPShmdW5jdGlvbigpewogICAgICByZXR1cm4gewogICAgICAgICAgbG9jYWxlU3RyaW5nOmZ1bmN0aW9uKGlkKXsKICAgICAgICAgICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmVuY29kZVNjcmlwdGFibGVUYWdzKCQueGZhV2lkZ2V0LmFic3RyYWN0V2lkZ2V0LnByb3RvdHlwZS5sb2NhbGVTdHJpbmdzKClbaWRdKSAgfHwgaWQ7CiAgICAgICAgICB9CiAgICAgIH07CiB9KSgpOwogdmFyIERFTEVURV9LRVkgPSA0NjsKIHZhciBFU0NfS0VZID0gMjc7CiB2YXIgRU5URVJfS0VZID0gMTM7Ci8qKgogKiBTY3JpYmJsZSBjbGFzcyBkZWZpbml0aW9uLCB1c2VkIGZvciBkcmF3aW5nIG9uIGNhbnZhcyB1c2luZyBtb3VzZSBvciB0b3VjaAogKi8KZnVuY3Rpb24gU2NyaWJibGUoIGNhbnZhc0lELGltYWdlLF93aWR0aCxfaGVpZ2h0LCBjYWxsYmFjaykgewogICAgdGhpcy5fY2FsbGJhY2sgPSBjYWxsYmFjazsKICAgIHRoaXMuY2FudmFzSUQgPSBjYW52YXNJRDsKICAgIHRoaXMuX2xpbmVXaWR0aD01OwogICAgdGhpcy5jYW52YXMgPSAkKCIjIitjYW52YXNJRCk7CiAgICB0aGlzLmNvbnRleHQgPSB0aGlzLmNhbnZhcy5nZXQoMCkuZ2V0Q29udGV4dCgiMmQiKTsgCiAgICB0aGlzLmNvbnRleHQuY2xlYXJSZWN0KDAsMCx0aGlzLmNhbnZhcy53aWR0aCx0aGlzLmNhbnZhcy5oZWlnaHQpOwogICAgdGhpcy5fZW5hYmxlZD10cnVlOwogICAgdGhpcy5jb250ZXh0LnN0cm9rZVN0eWxlID0gIiMwMDAwMDAiOwogICAgdGhpcy5jYW52YXNCb3JkZXJXaWR0aCA9IHBhcnNlSW50KHRoaXMuY2FudmFzLmNzcygnYm9yZGVyLWxlZnQtd2lkdGgnKSwxMCk7IC8vIGFzc3VtaW5nIHRvcCBhbmQgbGVmdCBib3JkZXJzIGFyZSBzYW1lIHdpZHRoCiAgICB0aGlzLmNvbnRleHQubGluZVdpZHRoID0gdGhpcy5fbGluZVdpZHRoOwogICAgdGhpcy5sYXN0TW91c2VQb2ludCA9IHt4OjAsIHk6MH07CiAgICAKICAgIHRoaXMuY2FudmFzWzBdLndpZHRoID0gX3dpZHRoOy8vIHRoaXMuY2FudmFzLnBhcmVudCgpLmlubmVyV2lkdGgoKTsKICAgIHRoaXMuY2FudmFzWzBdLmhlaWdodCA9IF9oZWlnaHQ7Ly90aGlzLmNhbnZhcy5wYXJlbnQoKS5pbm5lckhlaWdodCgpOwogICAgaWYoIWltYWdlKXsKICAgICAgICB0aGlzLmNvbnRleHQuZmlsbFN0eWxlICAgPSAnI2ZmZmZmZic7CiAgICAgICAgdGhpcy5jb250ZXh0LmNsZWFyUmVjdCgwLDAsX3dpZHRoLF9oZWlnaHQpOwogICAgfSBlbHNlIHsKICAgICAgICB0aGlzLmNvbnRleHQuZHJhd0ltYWdlKGltYWdlLDAsMCk7CiAgICB9CiAgICB0aGlzLmNhbnZhcy5vbiggVG91Y2hVdGlsLlBPSU5URVJfRE9XTiwgdGhpcy5vbkNhbnZhc01vdXNlRG93bigpICk7Cn0KU2NyaWJibGUucHJvdG90eXBlLnNldExpbmVXaWR0aD1mdW5jdGlvbih3KXsKICAgIHRoaXMuX2xpbmVXaWR0aD13Owp9OwpTY3JpYmJsZS5wcm90b3R5cGUub25DYW52YXNNb3VzZURvd24gPSBmdW5jdGlvbiAoKSB7CiAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICByZXR1cm4gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICBpZihUb3VjaFV0aWwuZ2V0VG91Y2hlcyhldmVudCkubGVuZ3RoIDwgMil7CiAgICAgICAgICAgIHNlbGYubW91c2VNb3ZlSGFuZGxlciA9IHNlbGYub25DYW52YXNNb3VzZU1vdmUoKTsKICAgICAgICAgICAgc2VsZi5tb3VzZVVwSGFuZGxlciA9IHNlbGYub25DYW52YXNNb3VzZVVwKCk7CiAgICAgICAgICAgIC8vQ1EtNDI2MTc2NSA6IFNjcmliYmxlIHNpZ24gc2Nyb2xsIGlzc3VlIHdpdGggaW9zCiAgICAgICAgICAgIC8vaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDk1MDAzMzkvY2FudC1wcmV2ZW50LXRvdWNobW92ZS1mcm9tLXNjcm9sbGluZy13aW5kb3ctb24taW9zCiAgICAgICAgICAgIC8vaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9qcXVlcnkvaXNzdWVzLzI4NzEKICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihUb3VjaFV0aWwuUE9JTlRFUl9NT1ZFLCBzZWxmLm1vdXNlTW92ZUhhbmRsZXIseyBwYXNzaXZlOiBmYWxzZSB9KTsKICAgICAgICAgICAgJChkb2N1bWVudCkub24oVG91Y2hVdGlsLlBPSU5URVJfVVAsIHNlbGYubW91c2VVcEhhbmRsZXIgKTsKICAgICAgICAgICAgc2VsZi51cGRhdGVNb3VzZVBvc2l0aW9uKCBldmVudCApOwogICAgICAgICAgICBzZWxmLnVwZGF0ZUNhbnZhcyggZXZlbnQgKTsKICAgICAgICB9CiAgICB9Cn07CgpTY3JpYmJsZS5wcm90b3R5cGUub25DYW52YXNNb3VzZU1vdmUgPSBmdW5jdGlvbiAoKSB7CiAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICByZXR1cm4gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICBpZihUb3VjaFV0aWwuZ2V0VG91Y2hlcyhldmVudCkubGVuZ3RoIDwgMil7CiAgICAgICAgICAgIHNlbGYudXBkYXRlQ2FudmFzKCBldmVudCApOwogICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9OwoKU2NyaWJibGUucHJvdG90eXBlLm9uQ2FudmFzTW91c2VVcCA9IGZ1bmN0aW9uIChldmVudCkgewogICAgdmFyIHNlbGYgPSB0aGlzOwogICAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihUb3VjaFV0aWwuUE9JTlRFUl9NT1ZFLCBzZWxmLm1vdXNlTW92ZUhhbmRsZXIseyBwYXNzaXZlOiBmYWxzZSB9KTsKICAgICAgICAkKGRvY3VtZW50KS5vZmYoVG91Y2hVdGlsLlBPSU5URVJfVVAsIHNlbGYubW91c2VVcEhhbmRsZXIgKTsKICAgICAgICBzZWxmLm1vdXNlTW92ZUhhbmRsZXIgPSBudWxsOwogICAgICAgIHNlbGYubW91c2VVcEhhbmRsZXIgPSBudWxsOwogICAgfQp9OwoKU2NyaWJibGUucHJvdG90eXBlLnVwZGF0ZU1vdXNlUG9zaXRpb24gPSBmdW5jdGlvbiAoZXZlbnQpIHsKICAgIGlmKCF0aGlzLl9lbmFibGVkKSByZXR1cm4gOwogICAgdmFyIHRhcmdldCA9IFRvdWNoVXRpbC5nZXRUb3VjaEV2ZW50KGV2ZW50KTsKCiAgICB2YXIgb2Zmc2V0ID0gdGhpcy5jYW52YXMub2Zmc2V0KCk7CiAgICAvKiBJbiBJRT49MTAgcGFnZVggdmFsdWVzIGFyZSBpbmNvcnJlY3Qgd2hlbiB1c2luZyB6b29tCiAgICAgc28gY2FsY3VsYXRlIHRoZW0gdXNpbmcgY2xpZW50WCBhbmQgc2Nyb2xsTGVmdCAqLwogICAgdGhpcy5sYXN0TW91c2VQb2ludC54ID0gdGFyZ2V0LmNsaWVudFggKyAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpIC0gb2Zmc2V0LmxlZnQgLSB0aGlzLmNhbnZhc0JvcmRlcldpZHRoOwogICAgdGhpcy5sYXN0TW91c2VQb2ludC55ID0gdGFyZ2V0LmNsaWVudFkgKyAkKHdpbmRvdykuc2Nyb2xsVG9wKCkgLSBvZmZzZXQudG9wIC0gdGhpcy5jYW52YXNCb3JkZXJXaWR0aDsKCn07ClNjcmliYmxlLnByb3RvdHlwZS5faXNJbnNpZGVDYW52YXMgPSBmdW5jdGlvbih4LHkpewogICAgcmV0dXJuIHk+PTAgJiYgeTx0aGlzLmNhbnZhc1swXS5oZWlnaHQgJiYgeD49MCAmJiB4IDwgdGhpcy5jYW52YXNbMF0ud2lkdGg7Cn07CiAgICBTY3JpYmJsZS5wcm90b3R5cGUudXBkYXRlQ2FudmFzID0gZnVuY3Rpb24gKGV2ZW50KSB7CiAgICBpZighdGhpcy5fZW5hYmxlZCkgewogICAgICAgcmV0dXJuOwogICAgfQogICAgdmFyIG9sZFgsb2xkWSxkWCxkWSxjYW5EcmF3LHNjYWxlWCxzY2FsZVksY3NzV2lkdGgsY3NzSGVpZ2h0OwogICAgY3NzV2lkdGggPSBwYXJzZUludCh0aGlzLmNhbnZhc1swXS5zdHlsZS53aWR0aCwxMCk7CiAgICBjc3NIZWlnaHQgPSBwYXJzZUludCh0aGlzLmNhbnZhc1swXS5zdHlsZS5oZWlnaHQsMTApOwogICAgc2NhbGVYID0gIGNzc1dpZHRoP3RoaXMuY2FudmFzWzBdLndpZHRoL2Nzc1dpZHRoOjE7CiAgICBzY2FsZVkgPSBjc3NIZWlnaHQ/dGhpcy5jYW52YXNbMF0uaGVpZ2h0L2Nzc0hlaWdodDoxOwoKICAgIHNjYWxlWCAvPSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZm9ybVNjYWxlRmFjdG9yOwogICAgc2NhbGVZIC89IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3I7CgogICAgb2xkWCA9IHRoaXMubGFzdE1vdXNlUG9pbnQueCpzY2FsZVg7CiAgICBvbGRZID0gdGhpcy5sYXN0TW91c2VQb2ludC55KnNjYWxlWTsKICAgCiAgICB0aGlzLnVwZGF0ZU1vdXNlUG9zaXRpb24oIGV2ZW50ICk7CgogICAgdmFyIG5ld1ggPSAgdGhpcy5sYXN0TW91c2VQb2ludC54KnNjYWxlWDsKICAgIHZhciBuZXdZID0gIHRoaXMubGFzdE1vdXNlUG9pbnQueSpzY2FsZVk7CgogICAgZFggPSBNYXRoLmFicyhuZXdYIC0gb2xkWCApOwogICAgZFkgPSBNYXRoLmFicyhuZXdZIC0gb2xkWSApOwoKICAgIGNhbkRyYXcgPSAoIGRYID4gMCB8fCBkWSA+IDAgKSAmJiB0aGlzLl9pc0luc2lkZUNhbnZhcyhvbGRYLG9sZFkpICYmIHRoaXMuX2lzSW5zaWRlQ2FudmFzKG5ld1gsbmV3WSk7OwoKICAgIGlmKGNhbkRyYXcpewogICAgICAgIHRoaXMuY29udGV4dC5iZWdpblBhdGgoKTsKICAgICAgICB0aGlzLmNvbnRleHQubW92ZVRvKCBvbGRYLCBvbGRZICk7CiAgICAgICAgdGhpcy5jb250ZXh0LmxpbmVUbyhuZXdYLCBuZXdZICk7CiAgICAgICAgdGhpcy5jb250ZXh0LmxpbmVXaWR0aD10aGlzLl9saW5lV2lkdGg7CiAgICAgICAgdGhpcy5jb250ZXh0LmxpbmVDYXA9J3JvdW5kJzsKICAgICAgICB0aGlzLmNvbnRleHQuc3Ryb2tlKCk7CgkJCiAgICAgICAgdGhpcy5fY2FsbGJhY2soKTsKCQkKICAgIH0KfTsKClNjcmliYmxlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHsKCiAgICB2YXIgZGF0YVN0cmluZyA9IHRoaXMuY2FudmFzLmdldCgwKS50b0RhdGFVUkwoImltYWdlL3BuZyIpOwogICAgLy92YXIgaW5kZXggPSBkYXRhU3RyaW5nLmluZGV4T2YoICIsIiApKzE7CiAgICAvL2RhdGFTdHJpbmcgPSBkYXRhU3RyaW5nLnN1YnN0cmluZyggaW5kZXggKTsKCiAgICByZXR1cm4gZGF0YVN0cmluZzsKfTsKU2NyaWJibGUucHJvdG90eXBlLnNldEVuYWJsZWQ9ZnVuY3Rpb24oZW5hYmxlKXsKICAgIHRoaXMuX2VuYWJsZWQ9ZW5hYmxlOwp9OwpTY3JpYmJsZS5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7CgogICAgdmFyIGMgPSB0aGlzLmNhbnZhc1swXTsKICAgIHRoaXMuY29udGV4dC5jbGVhclJlY3QoIDAsIDAsIGMud2lkdGgsIGMuaGVpZ2h0ICk7Cn07CgoKLy8gSW1hZ2VFZGl0IGRpYWxvZyBib3gKdmFyIGltYWdlRWRpdERpYWxvZz0oZnVuY3Rpb24oXyl7CiAgCiAgICAvLyBodG1sIHVzZWQgdG8gY29uc3RydWN0IGRpYWxvZyBib3gKICAgIHZhciBodG1sU3RyPShmdW5jdGlvbigpewogICAgICAgICB2YXIgaHRtbD1bCiAgICAgICAgICAgICAnPGRpdiBpZD0iaUVCb3hfY29udGFpbmVyIiB0YWJpbmRleD0iMCIgcm9sZT0iZGlhbG9nIiBhcmlhLWxhYmVsPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoInBsZWFzZVNpZ25UZXh0IikrJyI+JywKICAgICAgICAgICAgICAgICAgJzxkaXYgaWQ9ImlFQm94X3BhbmVsIj4nLAogICAgICAgICAgICAgICAgICAgICAgJzxkaXYgIGlkID0gImlFQm94X0NhbmNlbCIgY2xhc3M9ImlFQm94X2J1dHRvbiIgdGFiaW5kZXg9IjAiIHJvbGU9ImJ1dHRvbiIgYXJpYS1sYWJlbD0iJytTY3JpYmJsZVV0aWwubG9jYWxlU3RyaW5nKCJjYW5jZWwiKSsnIiB0aXRsZT0iJytTY3JpYmJsZVV0aWwubG9jYWxlU3RyaW5nKCJjYW5jZWwiKSsnIiA+PC9kaXY+JywKICAgICAgICAgICAgICAgICAgJzwvZGl2PicsCiAgICAgICAgICAgICAgICAgICc8ZGl2IGlkPSJpRUJveF9jb250ZW50Ij4nLAogICAgICAgICAgICAgICAgICAgICAgJzxkaXYgaWQ9ImlFQm94X2NhbnZhc2VzIiBhbGlnbj1jZW50ZXI+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBzdHlsZT0iZGlzcGxheTppbmxpbmUtYmxvY2s7IHZlcnRpY2FsLWFsaWduOnRvcDsiPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGNhbnZhcyAgaWQ9ImlFQm94X2NhbnZhcyIgc3R5bGU9Im1hcmdpbjowcHg7Ym9yZGVyLWJvdHRvbTowcHg7IiB3aWR0aD0iNjk2IiBoZWlnaHQ9IjM5MCIgPjwvY2FudmFzPicgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxpbnB1dCB0eXBlPSJ0ZXh0IiBpZD0ia2V5Ym9hcmRfU2lnbl9Cb3giIG5hbWU9InNpZ25hdHVyZVRleHQiIHBsYWNlaG9sZGVyPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoInR5cGVZb3VyU2lnbmF0dXJlSGVyZSIpKyciPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGZpZWxkc2V0IGlkPSJpRUJveF9jYXB0aW9uIj48bGVnZW5kIGFsaWduPSJjZW50ZXIiPicrU2NyaWJibGVVdGlsLmxvY2FsZVN0cmluZygicGxlYXNlU2lnblRleHQiKSsnPC9sZWdlbmQ+PC9maWVsZHNldD4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICc8Y2FudmFzIGlkPSJpRUJveF9nZW9DYW52YXNSaWdodCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgPjwvY2FudmFzPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJzxkaXY+PGNhbnZhcyBpZD0iaUVCb3hfZ2VvQ2FudmFzQm90dG9tIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiA+PC9jYW52YXM+PC9kaXY+JywKICAgICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nLAogICAgICAgICAgICAgICAgICAgICAgJzxkaXY+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBpZD0iaUVCb3hfQnJ1c2giIGNsYXNzPSJpRUJveF9idXR0b24iIHRhYmluZGV4PSIwIiAgcm9sZT0iYnV0dG9uIiBhcmlhLWxhYmVsPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoImJydXNoZXMiKSsnIiAgdGl0bGU9IicrU2NyaWJibGVVdGlsLmxvY2FsZVN0cmluZygiYnJ1c2hlcyIpKyciPjwvZGl2PicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJzxkaXYgaWQ9ImlFQm94X0NsZWFyIiBjbGFzcz0iaUVCb3hfYnV0dG9uIiB0YWJpbmRleD0iMCIgIHJvbGU9ImJ1dHRvbiIgYXJpYS1sYWJlbD0iJytTY3JpYmJsZVV0aWwubG9jYWxlU3RyaW5nKCJjbGVhciIpKyciICB0aXRsZT0iJytTY3JpYmJsZVV0aWwubG9jYWxlU3RyaW5nKCJjbGVhciIpKyciID48L2Rpdj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICc8ZGl2IGlkPSJpRUJveF9HZW8iIGNsYXNzPSJpRUJveF9idXR0b24iIHRhYmluZGV4PSIwIiAgcm9sZT0iYnV0dG9uIiBhcmlhLWxhYmVsPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoImdlb2xvY2F0aW9uIikrJyIgIHRpdGxlPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoImdlb2xvY2F0aW9uIikrJyIgPjwvZGl2PicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJzxkaXYgaWQ9ImlFQm94X1RleHQiIGNsYXNzPSJpRUJveF9idXR0b24iIHRhYmluZGV4PSIwIiAgcm9sZT0iYnV0dG9uIiBhcmlhLWxhYmVsPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoInR5cGVZb3VyTmFtZSIpKyciICB0aXRsZT0iJytTY3JpYmJsZVV0aWwubG9jYWxlU3RyaW5nKCJ0eXBlWW91ck5hbWUiKSsnIj48L2Rpdj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICc8ZGl2IGlkPSJpRUJveF90aXRsZSI+PC9kaXY+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBpZD0iaUVCb3hfT2siIGNsYXNzPSJpRUJveF9idXR0b24iIHRhYmluZGV4PSIwIiAgcm9sZT0iYnV0dG9uIiBhcmlhLWxhYmVsPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoIm9rIikrJyIgIHRpdGxlPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoIm9rIikrJyIgPjwvZGl2PicsCiAgICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JyAsCiAgICAgICAgICAgICAgICAgICc8L2Rpdj4nICwKICAgICAgICAgICAgICAgICAgJzxkaXYgaWQ9ImlFQm94X21vdmVmcmFtZSIgPjwvZGl2PicsCiAgICAgICAgICAgICAgICAgICc8ZGl2IGlkPSJpRUJveF9icnVzaExpc3QiID48L2Rpdj4nLAogICAgICAgICAgICAgICc8L2Rpdj4nXS5qb2luKCIiKTsKICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKXsKICAgICAgICAgICAgICByZXR1cm4gaHRtbDsKICAgICAgICAgICB9OwogICAgfSk7CgkKICAgIC8qKgoJICogICAKCSAqLwoJCiAgICB2YXIgZGlhbG9nT2JqID0gewogICAgICAgIHZlcnRpY2FsT2Zmc2V0OiAwLCAvLyByZW1vdmluZyB0aGUgbWFnaWMgdmFsdWUgb2YgLTc1IHNpbmNlIGl0IHdhcyBub3QgY2F1c2luZyBhbnkgaW1wYWN0CiAgICAgICAgaG9yaXpvbnRhbE9mZnNldDogMCwKICAgICAgICByZXBvc2l0aW9uT25SZXNpemU6IHRydWUsCiAgICAgICAgb3ZlcmxheU9wYWNpdHk6IC43NSwKICAgICAgICBvdmVybGF5Q29sb3I6ICcjQ0NDQ0NDJywKICAgICAgICBkcmFnZ2FibGU6IHRydWUsCiAgICAgICAgX2JydXNoZXM6WzIsMyw0LDUsNiw3LDgsOSwxMF0sCgkJX2J1dHRvbnNFbmFibGVkOnt9LAoJCV9pc09wZW46ZmFsc2UsCiAgICAgICAgc2hvdzpmdW5jdGlvbih0aXRsZSxjYWxsYmFjayl7CiAgICAgICAgICAgdGhpcy5fc2hvdyhjYWxsYmFjayk7CgkJICAgdGhpcy5fYnV0dG9uc0VuYWJsZWQ9e0dlbzp0cnVlLENsZWFyOnRydWUsT2s6dHJ1ZSxDYW5jZWw6dHJ1ZSxCcnVzaDp0cnVlLFRleHQ6dHJ1ZX07CiAgICAgICAgfSwKCQlzZXRFbmFibGVkOmZ1bmN0aW9uKGJ1dHRvbixlbmFibGUpewoJCSAgICBpZih0aGlzLl9idXR0b25zRW5hYmxlZFtidXR0b25dIT1lbmFibGUpewoJCSAgICAgICAgICAgdGhpcy5fYnV0dG9uc0VuYWJsZWRbYnV0dG9uXT1lbmFibGU7CgkJCQkgICBpZihlbmFibGUpewoJCQkJICAgICAgICQoJyNpRUJveF8nK2J1dHRvbikuZW1wdHkoJzxkaXYgc3R5bGU9ImJhY2tncm91bmQ6d2hpdGU7d2lkdGg6MTAwJTtoZWlnaHQ6MTAwJTtvcGFjaXR5OjAuNzU7Ij48L2Rpdj4nKS4KCQkJCSAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKCJkaXNhYmxlX2J1dHRvbiIpOwoJCQkJICAgfSBlbHNlIHsKCQkJCSAgICAgICAkKCcjaUVCb3hfJytidXR0b24pLmFwcGVuZCgnPGRpdiBzdHlsZT0iYmFja2dyb3VuZDp3aGl0ZTt3aWR0aDoxMDAlO2hlaWdodDoxMDAlO29wYWNpdHk6MC43NTsiPjwvZGl2PicpLgoJCQkJICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoImRpc2FibGVfYnV0dG9uIik7CgkJCQkgICB9CgkJCSAgICAgICAKCQkJfQoJCX0sCgkJZW5hYmxlQnV0dG9uczpmdW5jdGlvbihidXR0b25zKXsKCQkgICAgZm9yKHZhciBrIGluIGJ1dHRvbnMpewoJCQkJICAgdGhpcy5zZXRFbmFibGVkKGssYnV0dG9uc1trXSk7CgkJCX0KCQl9LAogICAgICAgIHRvZ2dsZUJydXNoTGlzdDpmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgICAgICBpZigkKCcjaUVCb3hfYnJ1c2hMaXN0JykuY3NzKCdkaXNwbGF5JykhPSdub25lJyl7CiAgICAgICAgICAgICAgICAgICAgJCgnI2lFQm94X2JydXNoTGlzdCcpLmNzcyh7ZGlzcGxheTonbm9uZSd9KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgdmFyIHRtcEZuID0gIGRvY3VtZW50Lm9uc2VsZWN0c3RhcnQ7CiAgICAgICAgICAgICAgICAgZG9jdW1lbnQub25zZWxlY3RzdGFydD1mdW5jdGlvbigpe3JldHVybiBmYWxzZTt9OwogICAgICAgICAgICAgICAgICQoJyNpRUJveF9icnVzaExpc3QnKS5jc3Moe2Rpc3BsYXk6J2Jsb2NrJyx2aXNpYmlsaXR5OidoaWRkZW4nfSk7CiAgICAgICAgICAgICAgICAgICAgJCgnI2lFQm94X2JydXNoTGlzdCcpLm9mZnNldCgkKCcjaUVCb3hfQnJ1c2gnKS5vZmZzZXQoKSk7CiAgICAgICAgICAgICAgICAgICAgJCgnI2lFQm94X2JydXNoTGlzdCcpLm9mZnNldCh7dG9wOiQoJyNpRUJveF9CcnVzaCcpLm9mZnNldCgpLnRvcC0kKCcjaUVCb3hfYnJ1c2hMaXN0JykuaGVpZ2h0KCl9KTsKICAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfYnJ1c2hMaXN0JykuY3NzKHtkaXNwbGF5OidibG9jaycsdmlzaWJpbGl0eTondmlzaWJsZSd9KTsKICAgICAgICAgICAgICAgICAgLy8gICQoJyNpRUJveF9icnVzaExpc3QnKS5mb2N1cygpOwogICAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfYnJ1c2hMaXN0Jykub25lKCdtb3VzZWxlYXZlJyxmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfYnJ1c2hMaXN0JykuY3NzKHtkaXNwbGF5Oidub25lJ30pOwogICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50Lm9uc2VsZWN0c3RhcnQ9dG1wRm47CiAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgIH0sCiAgICAgICAgX2F0dGFjaENhbGxiYWNrczogZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICB2YXIgc2lnQ2FudmFzID0gJCgnI2lFQm94X2NhbnZhcycpWzBdOwogICAgICAgICAgICB2YXIgY3R4PXNpZ0NhbnZhcy5nZXRDb250ZXh0KCIyZCIpOwogICAgICAgICAgICB2YXIgbWluU2lnQ2FudmFzRm9udFNpemU9MTA7CiAgICAgICAgICAgIHZhciBtYXhTaWdDYW52YXNGb250U2l6ZT03MDsKICAgICAgICAgICAgdmFyIHNpZ0NhbnZhc0ZvbnRTaXplPW1pblNpZ0NhbnZhc0ZvbnRTaXplOwogICAgICAgICAgICB2YXIgaW5pdGlhbFNpZ0NhbnZhc0ZvbnRTaXplPXNpZ0NhbnZhc0ZvbnRTaXplOwogICAgICAgICAgICB2YXIgaW5pdGlhbEZvbnRDYWxjdWxhdGVkRmxhZz1mYWxzZTsKICAgICAgICAgICAgdmFyIHNpZ0NhbnZhc0ZvbnRGYW1pbHk9InNhbnMtc2VyaWYsIEdlb3JnaWEiOwogICAgICAgICAgICB2YXIgc2lnQ2FudmFzRm9udFN0eWxlPSJpdGFsaWMiOwogICAgICAgICAgIF8uZWFjaCgiQ2FuY2VsLUNsZWFyLUdlby1Pay1CcnVzaC1UZXh0Ii5zcGxpdCgiLSIpLGZ1bmN0aW9uKHZhbCxpZHgpewogICAgICAgICAgICAgICAgICAgICQoIiNpRUJveF8iK3ZhbCkuY2xpY2soIGZ1bmN0aW9uKGV2ZW50KSB7CgkJCQkgICAgICAgaWYodGhhdC5fYnV0dG9uc0VuYWJsZWRbdmFsXSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sodmFsKTsKCQkJCSAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CgkJCQkJJCgiI2lFQm94XyIrdmFsKS5rZXlkb3duKCBmdW5jdGlvbihldmVudCkgewoJCQkJICAgICAgIGlmKHRoYXQuX2J1dHRvbnNFbmFibGVkW3ZhbF0gJiYgKGV2ZW50LmtleUNvZGUgPT0gRU5URVJfS0VZIHx8IGV2ZW50LmNoYXJDb2RlID09IEVOVEVSX0tFWSB8fCBldmVudC53aGljaCA9PSBFTlRFUl9LRVkpICl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sodmFsKTsKCQkJCSAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBfLmVhY2goJCgiI2lFQm94X2JydXNoTGlzdCIpLmNoaWxkcmVuKCksZnVuY3Rpb24oaXRtLGlkeCl7CiAgICAgICAgICAgICAgICAgICQoaXRtKS5vbihUb3VjaFV0aWwuUE9JTlRFUl9VUCxmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygiQnJ1c2hTZWxlY3QiLHRoYXQuX2JydXNoZXNbaWR4XSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfYnJ1c2hMaXN0JykuY3NzKHtkaXNwbGF5Oidub25lJ30pOwogICAgICAgICAgICAgICAgICAgICAgICAgIC8vICQoaXRtKS5jc3Moe2JhY2tncm91bmRDb2xvcjonI0ZGRkZGRid9KTsKICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICQoaXRtKS5vbihUb3VjaFV0aWwuUE9JTlRFUl9ET1dOLGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAkKGl0bSkuY3NzKHtiYWNrZ3JvdW5kQ29sb3I6JyNBQUFBQUEnfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAkKCcja2V5Ym9hcmRfU2lnbl9Cb3gnKS5rZXlkb3duKGZ1bmN0aW9uIChldmVudCl7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXRTaWduPSQoJyNrZXlib2FyZF9TaWduX0JveCcpWzBdLnZhbHVlOwoKICAgICAgICAgICAgICAgIGlmKGV2ZW50LmtleT09PSJCYWNrc3BhY2UiKSB7CiAgICAgICAgICAgICAgICAgICAgY3R4LmZvbnQ9c2lnQ2FudmFzRm9udFN0eWxlK3NpZ0NhbnZhc0ZvbnRTaXplKyJweCAiK3NpZ0NhbnZhc0ZvbnRGYW1pbHk7CiAgICAgICAgICAgICAgICAgICAgc2lnQ2FudmFzRm9udFNpemU9ZGlhbG9nT2JqLl9pbmNyZWFzZUZvbnRGb3JTaWduYXR1cmUoY3R4Lm1lYXN1cmVUZXh0KGlucHV0U2lnbikud2lkdGgsc2lnQ2FudmFzLndpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICBzaWdDYW52YXNGb250U2l6ZSxpbml0aWFsU2lnQ2FudmFzRm9udFNpemUpOwogICAgICAgICAgICAgICAgICAgIGN0eC5mb250PXNpZ0NhbnZhc0ZvbnRTdHlsZSsiICIrc2lnQ2FudmFzRm9udFNpemUrInB4ICIrc2lnQ2FudmFzRm9udEZhbWlseTsKICAgICAgICAgICAgICAgICAgICBjdHguY2xlYXJSZWN0KDAsIDAsIHNpZ0NhbnZhcy53aWR0aCwgc2lnQ2FudmFzLmhlaWdodCk7CiAgICAgICAgICAgICAgICAgICAgY3R4LmZpbGxUZXh0KGlucHV0U2lnbiwgMywgc2lnQ2FudmFzRm9udFNpemUsIHNpZ0NhbnZhcy53aWR0aC01KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICQoIiNrZXlib2FyZF9TaWduX0JveCIpLmtleXVwKGZ1bmN0aW9uIChldmVudCl7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXRTaWduPSQoJyNrZXlib2FyZF9TaWduX0JveCcpWzBdLnZhbHVlOwogICAgICAgICAgICAgICAgaWYoaW5wdXRTaWduLmxlbmd0aD09MCkgewogICAgICAgICAgICAgICAgICAgIGRpYWxvZ09iai5lbmFibGVCdXR0b25zKHtPazogZmFsc2UsIENsZWFyOiBmYWxzZX0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYoaW5wdXRTaWduLmxlbmd0aD49MSAmJiBpbnB1dFNpZ24udHJpbSgpLmxlbmd0aCE9MCkgewogICAgICAgICAgICAgICAgICAgIGRpYWxvZ09iai5lbmFibGVCdXR0b25zKHtPazogdHJ1ZSwgQ2xlYXI6IHRydWV9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGluaXRpYWxGb250Q2FsY3VsYXRlZEZsYWc9PT1mYWxzZSl7CiAgICAgICAgICAgICAgICAgICAgc2lnQ2FudmFzRm9udFNpemU9c2lnQ2FudmFzLmhlaWdodC0yMDsKICAgICAgICAgICAgICAgICAgICBzaWdDYW52YXNGb250U2l6ZT1zaWdDYW52YXNGb250U2l6ZTxtaW5TaWdDYW52YXNGb250U2l6ZT9taW5TaWdDYW52YXNGb250U2l6ZTpzaWdDYW52YXNGb250U2l6ZTsKICAgICAgICAgICAgICAgICAgICBzaWdDYW52YXNGb250U2l6ZT1zaWdDYW52YXNGb250U2l6ZT5tYXhTaWdDYW52YXNGb250U2l6ZT9tYXhTaWdDYW52YXNGb250U2l6ZTpzaWdDYW52YXNGb250U2l6ZTsKICAgICAgICAgICAgICAgICAgICBpbml0aWFsU2lnQ2FudmFzRm9udFNpemU9c2lnQ2FudmFzRm9udFNpemU7CiAgICAgICAgICAgICAgICAgICAgJCgnI2tleWJvYXJkX1NpZ25fQm94JylbMF0uc3R5bGUuZm9udD1zaWdDYW52YXNGb250U3R5bGUrIiAycmVtICIrc2lnQ2FudmFzRm9udEZhbWlseTsKICAgICAgICAgICAgICAgICAgICBpbml0aWFsRm9udENhbGN1bGF0ZWRGbGFnPXRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdHguZm9udD1zaWdDYW52YXNGb250U3R5bGUrc2lnQ2FudmFzRm9udFNpemUrInB4ICIrc2lnQ2FudmFzRm9udEZhbWlseTsKICAgICAgICAgICAgICAgIHNpZ0NhbnZhc0ZvbnRTaXplPWRpYWxvZ09iai5fZGVjcmVhc2VGb250Rm9yU2lnbmF0dXJlKGN0eCxpbnB1dFNpZ24sc2lnQ2FudmFzLndpZHRoLAogICAgICAgICAgICAgICAgICAgIHNpZ0NhbnZhc0ZvbnRTaXplLHNpZ0NhbnZhc0ZvbnRGYW1pbHkpOwogICAgICAgICAgICAgICAgY3R4LmZvbnQ9c2lnQ2FudmFzRm9udFN0eWxlKyIgIitzaWdDYW52YXNGb250U2l6ZSsicHggIitzaWdDYW52YXNGb250RmFtaWx5OwogICAgICAgICAgICAgICAgY3R4LmNsZWFyUmVjdCgwLCAwLCBzaWdDYW52YXMud2lkdGgsIHNpZ0NhbnZhcy5oZWlnaHQpOwogICAgICAgICAgICAgICAgY3R4LmZpbGxUZXh0KGlucHV0U2lnbiwzLHNpZ0NhbnZhc0ZvbnRTaXplLHNpZ0NhbnZhcy53aWR0aC01KTsKICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIC8vIGNhcHR1cmUgdGFiIGtleSBhbmQgZXNjYXBlCiAgICAgICAgICAgICQoJyNpRUJveF9jb250YWluZXInKS5rZXlkb3duKGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgICAgIHZhciBmaXJzdEZvY3VzYWJsZUl0ZW0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIjaUVCb3hfY29udGFpbmVyIik7CiAgICAgICAgICAgICAgICB2YXIgbGFzdEZvY3VzYWJsZUl0ZW0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIjaUVCb3hfT2siKTsKICAgICAgICAgICAgICAgIHZhciBLRVlDT0RFX1RBQiA9IDk7CiAgICAgICAgICAgICAgICB2YXIgaXNUYWJQcmVzc2VkID0gKGV2ZW50LmtleSA9PT0gJ1RhYicgfHwgZXZlbnQua2V5Q29kZSA9PT0gS0VZQ09ERV9UQUIpOwogICAgICAgICAgICAgICAgaWYoKGV2ZW50LmtleUNvZGUgPT0gRVNDX0tFWSB8fCBldmVudC5jaGFyQ29kZSA9PSBFU0NfS0VZIHx8IGV2ZW50LndoaWNoID09IEVTQ19LRVkpKSB7CiAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygiQ2FuY2VsIik7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzVGFiUHJlc3NlZCkgewogICAgICAgICAgICAgICAgICAgIC8vIFRyYXAgZm9jdXMgaW5zaWRlIHRoZSBkaWFsb2cgYm94CiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5ICYmIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT09IGZpcnN0Rm9jdXNhYmxlSXRlbSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyB3aGVuIHNoaWZ0ICsgdGFiIGtleSBpcyBwcmVzc2VkCiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RGb2N1c2FibGVJdGVtLmZvY3VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09PSBsYXN0Rm9jdXNhYmxlSXRlbSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyB3aGVuIHRhYiBrZXkgaXMgcHJlc3NlZAogICAgICAgICAgICAgICAgICAgICAgICBmaXJzdEZvY3VzYWJsZUl0ZW0uZm9jdXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIGlmKHRoaXMuZHJhZ2dhYmxlKXsKICAgICAgICAgICAgICAgIHRoaXMuX21ha2VEcmFnZ2FibGUoVG91Y2hVdGlsLlRPVUNIX0VOQUJMRUQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2RlY3JlYXNlRm9udEZvclNpZ25hdHVyZTpmdW5jdGlvbihjdHgsaW5wdXRTaWduLHNpZ0NhbnZhc1dpZHRoLGZvbnRTaXplLHNpZ0NhbnZhc0ZvbnRGYW1pbHkpewogICAgICAgICAgICB3aGlsZShjdHgubWVhc3VyZVRleHQoaW5wdXRTaWduKS53aWR0aD5zaWdDYW52YXNXaWR0aC01ICYmIGZvbnRTaXplPjIwKXsKICAgICAgICAgICAgICAgIGZvbnRTaXplPWZvbnRTaXplLTEwOwogICAgICAgICAgICAgICAgY3R4LmZvbnQ9Zm9udFNpemUrInB4ICIrc2lnQ2FudmFzRm9udEZhbWlseTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZm9udFNpemUKICAgICAgICB9LAogICAgICAgIF9pbmNyZWFzZUZvbnRGb3JTaWduYXR1cmU6ZnVuY3Rpb24odGV4dFdpZHRoLHNpZ0NhbnZhc1dpZHRoLGZvbnRTaXplLGluaXRpYWxTaWdDYW52YXNGb250U2l6ZSl7CiAgICAgICAgICAgIGlmKHNpZ0NhbnZhc1dpZHRoLXRleHRXaWR0aD4wKXsKICAgICAgICAgICAgICAgIGZvbnRTaXplPWluaXRpYWxTaWdDYW52YXNGb250U2l6ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZm9udFNpemU7CiAgICAgICAgfSwKICAgICAgICBfbWFrZURyYWdnYWJsZTpmdW5jdGlvbih0b3VjaEVuYWJsZWQpewogICAgICAgICAgICAgIHZhciBfaXNNb3VzZURvd249ZmFsc2U7CiAgICAgICAgICAgICAgdmFyIF90aGF0PXRoaXM7CiAgICAgICAgICAgICAgdmFyIGRYOwogICAgICAgICAgICAgIHZhciBkWTsKICAgICAgICAgICAgICB2YXIgb2Zmc2V0UG9zOwogICAgICAgICAgICAgIHZhciBfbW91c2VNb3ZGdW47CiAgICAgICAgICAgICAgdmFyIF9tb3VzZVVwRnVuOwogICAgICAgICAgICAgICQoJyNpRUJveF9wYW5lbCcpLm9uKFRvdWNoVXRpbC5QT0lOVEVSX0RPV04sZnVuY3Rpb24oIGV2ZW50ICl7CiAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgIGlmKFRvdWNoVXRpbC5nZXRUb3VjaGVzKGV2ZW50KS5sZW5ndGggPCAyKXsKICAgICAgICAgICAgICAgICAgICAgIGlmKCQoZXZlbnQudGFyZ2V0KS5pcygnI2lFQm94X3BhbmVsJykpewogICAgICAgICAgICAgICAgICAgICAgICAgICQoJ2JvZHknKVswXS5hZGRFdmVudExpc3RlbmVyKFRvdWNoVXRpbC5QT0lOVEVSX01PVkUsX21vdXNlTW92RnVuPWZ1bmN0aW9uKCBldmVudCApewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihUb3VjaFV0aWwuZ2V0VG91Y2hlcyhldmVudCkubGVuZ3RoIDwgMiAmJiBfaXNNb3VzZURvd24pewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBldnQgPSBUb3VjaFV0aWwuZ2V0VG91Y2hFdmVudChldmVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVsWCA9IGV2dC5wYWdlWCAtIGRYOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRlbFkgPSBldnQucGFnZVkgLSBkWTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJyNpRUJveF9tb3ZlZnJhbWUnKS5vZmZzZXQoewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogb2Zmc2V0UG9zLnRvcCtkZWxZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IG9mZnNldFBvcy5sZWZ0K2RlbFgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgeyBwYXNzaXZlOiBmYWxzZSB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAkKCdib2R5Jykub24oVG91Y2hVdGlsLlBPSU5URVJfVVAsX21vdXNlVXBGdW49ZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihfaXNNb3VzZURvd24pewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9mZnNldE1vdmUgPSAkKCcjaUVCb3hfbW92ZWZyYW1lJykub2Zmc2V0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG9wRWRnZSAgPSAkKHdpbmRvdykuc2Nyb2xsVG9wKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYm90dG9tRWRnZSA9IHRvcEVkZ2UgKyAkKHdpbmRvdykuaGVpZ2h0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihvZmZzZXRNb3ZlLnRvcCAtIHRvcEVkZ2UgPCAxKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRNb3ZlLnRvcCA9IHRvcEVkZ2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihvZmZzZXRNb3ZlLnRvcCAtIGJvdHRvbUVkZ2UgKyAkKCcjaUVCb3hfcGFuZWwnKS5oZWlnaHQoKSA+IDAgKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRNb3ZlLnRvcCA9IGJvdHRvbUVkZ2UgLSAkKCcjaUVCb3hfcGFuZWwnKS5oZWlnaHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJyNpRUJveF9jb250YWluZXInKS5vZmZzZXQob2Zmc2V0TW92ZSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJCgnI2lFQm94X21vdmVmcmFtZScpLmNzcyh7ZGlzcGxheTonbm9uZSd9KS5vZmZzZXQob2Zmc2V0TW92ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaXNNb3VzZURvd249ZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCdib2R5JylbMF0ucmVtb3ZlRXZlbnRMaXN0ZW5lcihUb3VjaFV0aWwuUE9JTlRFUl9NT1ZFLF9tb3VzZU1vdkZ1bix7IHBhc3NpdmU6IGZhbHNlIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJCgnYm9keScpLm9mZihUb3VjaFV0aWwuUE9JTlRFUl9VUCxfbW91c2VVcEZ1bik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGV2dCA9IFRvdWNoVXRpbC5nZXRUb3VjaEV2ZW50KGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICBfaXNNb3VzZURvd249dHJ1ZTsgZFggPSBldnQucGFnZVg7ZFk9ZXZ0LnBhZ2VZOwogICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldFBvcyA9ICQoJyNpRUJveF9jb250YWluZXInKS5vZmZzZXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfbW92ZWZyYW1lJykuY3NzKHtkaXNwbGF5OidibG9jayd9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfbW92ZWZyYW1lJykub2Zmc2V0KG9mZnNldFBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgJCgnI2lFQm94X21vdmVmcmFtZScpLmNzcygnd2lkdGgnLCQoJyNpRUJveF9jb250YWluZXInKS5jc3MoJ3dpZHRoJykpOwogICAgICAgICAgICAgICAgICAgICAgICAgICQoJyNpRUJveF9tb3ZlZnJhbWUnKS5jc3MoJ2hlaWdodCcsJCgnI2lFQm94X2NvbnRhaW5lcicpLmNzcygnaGVpZ2h0JykpOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAKICAgICAgICB9LAogICAgICAgIF9jcmVhdGVCcnVzaGVzOmZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgIHZhciBfdGhhdD10aGlzOwogICAgICAgICAgICAgIF8uZWFjaCh0aGlzLl9icnVzaGVzLGZ1bmN0aW9uKHZhbCxpZHgpewogICAgICAgICAgICAgICAgICB2YXIgZGl2ZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdESVYnKTsKICAgICAgICAgICAgICAgICAgdmFyIGNudiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ0NBTlZBUycpOwogICAgICAgICAgICAgICAgICB2YXIgY3R4ID0gY252LmdldENvbnRleHQoJzJkJyk7CiAgICAgICAgICAgICAgICAgIGNudi5zdHlsZS5ib3JkZXI9JzFweCBzb2xpZCAjQUFBQUFBJzsKICAgICAgICAgICAgICAgICAgY252LndpZHRoPVRvdWNoVXRpbC5UT1VDSF9FTkFCTEVEPzIwMDoxMDA7CiAgICAgICAgICAgICAgICAgIGNudi5oZWlnaHQ9VG91Y2hVdGlsLlRPVUNIX0VOQUJMRUQ/NDA6MjA7OwogICAgICAgICAgICAgICAgICBjdHgubGluZVdpZHRoPXZhbDsKICAgICAgICAgICAgICAgICAgY3R4LmJlZ2luUGF0aCgpOwogICAgICAgICAgICAgICAgICBjdHgubW92ZVRvKDEwLGNudi5oZWlnaHQvMik7CiAgICAgICAgICAgICAgICAgIGN0eC5saW5lVG8oY252LndpZHRoLTEwLGNudi5oZWlnaHQvMik7CiAgICAgICAgICAgICAgICAgIGN0eC5zdHJva2UoKTsKICAgICAgICAgICAgICAgICAgZGl2ZWwuYXBwZW5kQ2hpbGQoY252KTsKICAgICAgICAgICAgICAgICAgJCgnI2lFQm94X2JydXNoTGlzdCcpLmFwcGVuZChkaXZlbCk7CiAgICAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgkJZ2V0SXNPcGVuOmZ1bmN0aW9uKCl7CgkJICAgIHJldHVybiBkaWFsb2dPYmouX2lzT3BlbjsKCQl9LAoJCXNldElzT3BlbjpmdW5jdGlvbihvcGVuKXsKCQkgICAgZGlhbG9nT2JqLl9pc09wZW4gPSBvcGVuOwoJCX0sCiAgICAgICAgX3Nob3c6IGZ1bmN0aW9uKGNhbGxiYWNrKSB7CiAgICAgICAgICAgIGRpYWxvZ09iai5oaWRlKCk7CiAgICAgICAgICAgIGRpYWxvZ09iai5fb3ZlcmxheSgnc2hvdycpOwogICAgICAgICAgICAKICAgICAgICAgICAgJCgiQk9EWSIpLmFwcGVuZChodG1sU3RyKCkpOwogICAgICAgICAgICBkaWFsb2dPYmouc2V0SXNPcGVuKHRydWUpOwogICAgICAgICAgICAkKCcjaUVCb3hfY29udGFpbmVyJykuZm9jdXMoKTsKICAgICAgICAgICAgZGlhbG9nT2JqLl9jcmVhdGVCcnVzaGVzKCk7CgogICAgICAgICAgICBkaWFsb2dPYmouX3JlcG9zaXRpb24oKTsKCiAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSBzcGFjaW5nIGFyb3VuZCBjYW52YXMgYXJlYQogICAgICAgICAgICAvLyB0aGlzIHdpbGwgYmUgdXNlZCB0byBmaW5kIGNhbnZhcyBkaW1lbnNpb25zIGJhc2VkIG9uIGF2YWlsYWJsZSBzY3JlZW4gYXJlYS4KICAgICAgICAgICAgdmFyIGNvbnRhaW5lcl9lbCA9ICQoJyNpRUJveF9jb250YWluZXInKTsKICAgICAgICAgICAgdmFyIGNhbnZhc19lbCA9ICAkKCcjaUVCb3hfY2FudmFzJyk7CiAgICAgICAgICAgIHZhciBjb250YWluZXJfd2lkdGggPSAkKCcjaUVCb3hfY29udGFpbmVyJykub3V0ZXJXaWR0aCh0cnVlKTsKICAgICAgICAgICAgdmFyIGNvbnRhaW5lcl9oZWlnaHQgPSAkKCcjaUVCb3hfY29udGFpbmVyJykub3V0ZXJIZWlnaHQodHJ1ZSk7CiAgICAgICAgICAgIHZhciBjYW52YXNfd2lkdGggPSBjYW52YXNfZWxbMF0ud2lkdGg7CiAgICAgICAgICAgIHZhciBjYW52YXNfaGVpZ2h0ID0gY2FudmFzX2VsWzBdLmhlaWdodDsKICAgICAgICAgICAgZGlhbG9nT2JqLmNhbnZhc19zcGFjaW5nID0geyB4OmNvbnRhaW5lcl93aWR0aCAtIGNhbnZhc193aWR0aCwgeTpjb250YWluZXJfaGVpZ2h0LWNhbnZhc19oZWlnaHR9OwoKICAgICAgICAgICAgZGlhbG9nT2JqLl9tYWludGFpblBvc2l0aW9uKHRydWUpOwogICAgICAgICAgICAKICAgICAgICAgICAgZGlhbG9nT2JqLl9hdHRhY2hDYWxsYmFja3MoY2FsbGJhY2spOwogICAgICAgIH0sCgogICAgICAgIGhpZGU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAkKCIjaUVCb3hfY29udGFpbmVyIikucmVtb3ZlKCk7CiAgICAgICAgICAgIHRoaXMuX292ZXJsYXkoJ2hpZGUnKTsKICAgICAgICAgICAgZGlhbG9nT2JqLnNldElzT3BlbihmYWxzZSk7CiAgICAgICAgICAgIHRoaXMuX21haW50YWluUG9zaXRpb24oZmFsc2UpOwogICAgICAgIH0sCiAgICAgICAgX292ZXJsYXlSZXNpemU6ZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgaWYoJCgiI2lFQm94X292ZXJsYXkiKS5oZWlnaHQoKSE9ICQoZG9jdW1lbnQpLmhlaWdodCgpKXsKICAgICAgICAgICAgICAgICQoIiNpRUJveF9vdmVybGF5IikuaGVpZ2h0KCAkKGRvY3VtZW50KS5oZWlnaHQoKSApOwogICAgICAgICAgICB9CgogICAgICAgIH0sCiAgICAgICAgX2Rpc2FibGVNb3ZlOmZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgfSwKICAgICAgICBfb3ZlcmxheTogZnVuY3Rpb24oc3RhdHVzKSB7CiAgICAgICAgICAgIHN3aXRjaCggc3RhdHVzICkgewogICAgICAgICAgICAgICAgY2FzZSAnc2hvdyc6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb3ZlcmxheSgnaGlkZScpOwogICAgICAgICAgICAgICAgICAgICQoIkJPRFkiKS5hcHBlbmQoJzxkaXYgaWQ9ImlFQm94X292ZXJsYXkiPjwvZGl2PicpOwogICAgICAgICAgICAgICAgICAgICQoIiNpRUJveF9vdmVybGF5IikuY3NzKHsKICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246ICdmaXhlZCcsCiAgICAgICAgICAgICAgICAgICAgICAgIHpJbmRleDogOTk5OTcsCiAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogJzBweCcsCiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6ICcwcHgnLAogICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogJzEwMCUnLAogICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6ICQoZG9jdW1lbnQpLmhlaWdodCgpLAogICAgICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiB0aGlzLm92ZXJsYXlDb2xvciwKICAgICAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogdGhpcy5vdmVybGF5T3BhY2l0eQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIGlmKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5pc1NhZmFyaSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiNpRUJveF9vdmVybGF5Iikub24oJ3RvdWNobW92ZScsIHRoaXMuX2Rpc2FibGVNb3ZlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJChkb2N1bWVudCkub24oJ3Njcm9sbCcsdGhpcy5fb3ZlcmxheVJlc2l6ZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ2hpZGUnOgogICAgICAgICAgICAgICAgICAgIGlmKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5pc1NhZmFyaSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiNpRUJveF9vdmVybGF5Iikub2ZmKCd0b3VjaG1vdmUnKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJCgiI2lFQm94X292ZXJsYXkiKS5yZW1vdmUoKTsKICAgICAgICAgICAgICAgICAgICAkKGRvY3VtZW50KS5vZmYoJ3Njcm9sbCcsdGhpcy5fb3ZlcmxheVJlc2l6ZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgLyoqCiAgICAgICAgICogcmVzaXplIGRpYWxvZyBiYXNlZCBvbiBhdmFpbGFibGUgc2NyZWVuIGFyZWEKICAgICAgICAgKi8KICAgICAgICBfcmVzaXplOmZ1bmN0aW9uKCl7CiAgICAgICAgICAgIC8vIGF2YWlsYWJsZSBzY3JlZW4gYXJlYQogICAgICAgICAgICB2YXIgYVdpZHRoID0gJCh3aW5kb3cpLndpZHRoKCk7CiAgICAgICAgICAgIHZhciBhSGVpZ2h0ID0gJCh3aW5kb3cpLmhlaWdodCgpOwoKICAgICAgICAgICAgdmFyIHNpZ0NudiA9ICQoJyNpRUJveF9jYW52YXMnKVswXTsKICAgICAgICAgICAgdmFyIHNpZ1RleHRCb3ggPSAkKCcja2V5Ym9hcmRfU2lnbl9Cb3gnKVswXTsKICAgICAgICAgICAgdmFyIGJHZW9DbnYgPSAkKCcjaUVCb3hfZ2VvQ2FudmFzQm90dG9tJylbMF07CiAgICAgICAgICAgIHZhciByR2VvQ252ID0gJCgnI2lFQm94X2dlb0NhbnZhc1JpZ2h0JylbMF07CgogICAgICAgICAgICAvLyBjYWxjdWxhdGUgYW1vdW50IG9mIHdpZHRoIGhlaWdodCB3ZSBuZWVkIHRvIHJlZHVjZQoKICAgICAgICAgICAgdmFyIHRvdGFsQ252V2lkdGggPSBzaWdDbnYud2lkdGggKyByR2VvQ252LndpZHRoOwogICAgICAgICAgICB2YXIgdG90YWxDbnZIZWlnaHQgPSBzaWdDbnYuaGVpZ2h0ICsgYkdlb0Nudi5oZWlnaHQ7CgoKCgoKICAgICAgICAgICAgdmFyIGRpZmZXID0gdG90YWxDbnZXaWR0aCArIGRpYWxvZ09iai5jYW52YXNfc3BhY2luZy54IC0gYVdpZHRoOwogICAgICAgICAgICBpZihkaWZmVyA8IDApIHsKICAgICAgICAgICAgICAgIGRpZmZXID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgZGlmZkggPSB0b3RhbENudkhlaWdodCArIGRpYWxvZ09iai5jYW52YXNfc3BhY2luZy55IC0gYUhlaWdodDsKICAgICAgICAgICAgaWYoZGlmZkggPCAwKXsKICAgICAgICAgICAgICAgIGRpZmZIID0gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIG5ld1RvdGFsQ252SGVpZ2h0LCBuZXdUb3RhbENudldpZHRoOwogICAgICAgICAgICBpZiggZGlmZlcgPiAwIHx8IGRpZmZIID4gMCApeyAvLyBkb2VzIGFueSBzaWRlIG5lZWQgcmVzaXplCgogICAgICAgICAgICAgICAgaWYoZGlmZkggKiB0b3RhbENudldpZHRoID4gdG90YWxDbnZIZWlnaHQgKiBkaWZmVyl7IC8vIG5lZWQgdG8gcmVkdWNlIGhlaWdodAogICAgICAgICAgICAgICAgICAgbmV3VG90YWxDbnZIZWlnaHQgPSB0b3RhbENudkhlaWdodCAtIGRpZmZIOwogICAgICAgICAgICAgICAgICAgbmV3VG90YWxDbnZXaWR0aCA9IChuZXdUb3RhbENudkhlaWdodCAqIHRvdGFsQ252V2lkdGgpLyB0b3RhbENudkhlaWdodDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICBuZXdUb3RhbENudldpZHRoID0gdG90YWxDbnZXaWR0aCAtIGRpZmZXOwogICAgICAgICAgICAgICAgICAgbmV3VG90YWxDbnZIZWlnaHQgPSAobmV3VG90YWxDbnZXaWR0aCAqIHRvdGFsQ252SGVpZ2h0KS8gdG90YWxDbnZXaWR0aDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBkaXN0cmlidXRlIGV2ZW5seSB0aGUgbmV3IGRpbWVuc2lvbnMKCgogICAgICAgICAgICAgICAgdmFyIG5ld1NpZ0NudldpZHRoICAgPSAobmV3VG90YWxDbnZXaWR0aCpzaWdDbnYud2lkdGgpL3RvdGFsQ252V2lkdGg7CiAgICAgICAgICAgICAgICB2YXIgbmV3U2lnQ252SGVpZ2h0ID0gKG5ld1RvdGFsQ252SGVpZ2h0KnNpZ0Nudi5oZWlnaHQpL3RvdGFsQ252SGVpZ2h0OwoKICAgICAgICAgICAgICAgIHNpZ0Nudi5zdHlsZS53aWR0aCA9IG5ld1NpZ0NudldpZHRoICsgInB4IjsKICAgICAgICAgICAgICAgIHNpZ0Nudi5zdHlsZS5oZWlnaHQgPSBuZXdTaWdDbnZIZWlnaHQgKyAicHgiOwoKICAgICAgICAgICAgICAgIHNpZ1RleHRCb3guc3R5bGUud2lkdGggPSBuZXdTaWdDbnZXaWR0aCArICJweCI7CiAgICAgICAgICAgICAgICBzaWdUZXh0Qm94LnN0eWxlLmhlaWdodCA9IG5ld1NpZ0NudkhlaWdodCArICJweCI7CgoKICAgICAgICAgICAgICAgIGJHZW9DbnYuc3R5bGUud2lkdGggPSBuZXdTaWdDbnZXaWR0aCArInB4IjsKICAgICAgICAgICAgICAgIGJHZW9DbnYuc3R5bGUuaGVpZ2h0ID0gKG5ld1RvdGFsQ252SGVpZ2h0IC0gbmV3U2lnQ252SGVpZ2h0KSArInB4IjsKCiAgICAgICAgICAgICAgICByR2VvQ252LnN0eWxlLndpZHRoID0gKG5ld1RvdGFsQ252V2lkdGggLSBuZXdTaWdDbnZXaWR0aCkgKyJweCI7CiAgICAgICAgICAgICAgICByR2VvQ252LnN0eWxlLmhlaWdodCA9IG5ld1NpZ0NudkhlaWdodCArICJweCI7CgoKICAgICAgICAgICAgICAgICQoJyNpRUJveF9jYXB0aW9uJykud2lkdGgoTWF0aC5mbG9vcihuZXdTaWdDbnZXaWR0aCkpOwoKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNpZ0Nudi5zdHlsZS53aWR0aCA9ICBzaWdDbnYud2lkdGggKyAicHgiOwogICAgICAgICAgICAgICAgc2lnQ252LnN0eWxlLmhlaWdodCA9IHNpZ0Nudi5oZWlnaHQgKyAicHgiOwoKICAgICAgICAgICAgICAgIHNpZ1RleHRCb3guc3R5bGUud2lkdGggPSAgc2lnQ252LndpZHRoICsgInB4IjsKICAgICAgICAgICAgICAgIHNpZ1RleHRCb3guc3R5bGUuaGVpZ2h0ID0gc2lnQ252LmhlaWdodCArICJweCI7CgogICAgICAgICAgICAgICAgYkdlb0Nudi5zdHlsZS53aWR0aCA9ICBiR2VvQ252LndpZHRoICsgInB4IjsKICAgICAgICAgICAgICAgIGJHZW9DbnYuc3R5bGUuaGVpZ2h0ID0gYkdlb0Nudi5oZWlnaHQgKyAicHgiOwoKICAgICAgICAgICAgICAgIHJHZW9DbnYuc3R5bGUud2lkdGggPSAgckdlb0Nudi53aWR0aCArICJweCI7CiAgICAgICAgICAgICAgICByR2VvQ252LnN0eWxlLmhlaWdodCA9IHJHZW9DbnYuaGVpZ2h0ICsgInB4IjsKCiAgICAgICAgICAgICAgICAkKCcjaUVCb3hfY2FwdGlvbicpLndpZHRoKHNpZ0Nudi53aWR0aCk7CgogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBfcmVwb3NpdGlvbjogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB0b3AgPSAoKCQod2luZG93KS5oZWlnaHQoKSAqICgxIC8geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmZvcm1TY2FsZUZhY3RvcikgLyAyKSAtICgkKCIjaUVCb3hfY29udGFpbmVyIikub3V0ZXJIZWlnaHQoKSAvIDIpKSArIGRpYWxvZ09iai52ZXJ0aWNhbE9mZnNldDsKICAgICAgICAgICAgdmFyIGxlZnQgPSAoKCQod2luZG93KS53aWR0aCgpICogKDEgLyB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZm9ybVNjYWxlRmFjdG9yKSAvIDIpIC0gKCQoIiNpRUJveF9jb250YWluZXIiKS5vdXRlcldpZHRoKCkgLyAyKSkgKyBkaWFsb2dPYmouaG9yaXpvbnRhbE9mZnNldDsKICAgICAgICAgICAgaWYoIHRvcCA8IDAgKSB0b3AgPSAwOwogICAgICAgICAgICBpZiggbGVmdCA8IDAgKSBsZWZ0ID0gMDsKCiAgICAgICAgICAgICQoIiNpRUJveF9jb250YWluZXIiKS5jc3MoewogICAgICAgICAgICAgICAgdG9wOiB0b3AgKyAkKHdpbmRvdykuc2Nyb2xsVG9wKCkgKiAoMSAvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IpICsgJ3B4JywKICAgICAgICAgICAgICAgIGxlZnQ6IGxlZnQgKyAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpICogKDEgLyB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZm9ybVNjYWxlRmFjdG9yKSArICdweCcKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICQoIiNpRUJveF9jb250YWluZXIiKS5mb2N1cygpOyAgIC8vIHNjcm9sbCB1cCB0byB0aGUgY2FudmFzCiAgICAgICAgICAgICQoIiNpRUJveF9vdmVybGF5IikuaGVpZ2h0KCAkKGRvY3VtZW50KS5oZWlnaHQoKSApOwogICAgICAgIH0sCiAgICAgICAgX21haW50YWluRGlhbG9nOmZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGRpYWxvZ09iai5fcmVzaXplKCk7CiAgICAgICAgICAgIGRpYWxvZ09iai5fcmVwb3NpdGlvbigpOwogICAgICAgIH0sCiAgICAgICAgX21haW50YWluUG9zaXRpb246IGZ1bmN0aW9uKHN0YXR1cykgewogICAgICAgICAgICBpZihkaWFsb2dPYmoucmVwb3NpdGlvbk9uUmVzaXplICkgewogICAgICAgICAgICAgICAgc3dpdGNoKHN0YXR1cykgewogICAgICAgICAgICAgICAgICAgIGNhc2UgdHJ1ZToKICAgICAgICAgICAgICAgICAgICAgICAgJCh3aW5kb3cpLm9uKCdvcmllbnRhdGlvbmNoYW5nZScsIGRpYWxvZ09iai5fbWFpbnRhaW5EaWFsb2cpOyAvLyBhbHNvIHJlcG9zaXRpb24gaWYgZGV2aWNlIGlzIHRpbHRlZAogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgZmFsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgICQod2luZG93KS5vZmYoJ29yaWVudGF0aW9uY2hhbmdlJywgZGlhbG9nT2JqLl9tYWludGFpbkRpYWxvZyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICB9OwogICAgcmV0dXJuIGRpYWxvZ09iajsKfSkod2luZG93Ll8pOwoKLyoqCiAqIGNsYXNzIGRlZmluaXRpb24gZm9yIEdlb0xvY2F0aW9uUXVlcnlSZXF1ZXN0CiAqIGVuY2Fwc3VsYXRlZCBzdWNjZXNzIGFuZCBlcnJvciBoYW5kbGVycyAKICovCmZ1bmN0aW9uIEdlb0xvY1F1ZXJ5KCl7fQpHZW9Mb2NRdWVyeS5wcm90b3R5cGU9ewogICAgaW5pdDpmdW5jdGlvbihzdWNjZXNzLGZhaWx1cmUpewogICAgICAgIHRoaXMuX3N1Y2Nlc3NIYW5kbGVyID0gc3VjY2VzczsKICAgICAgICB0aGlzLl9lcnJvckhhbmRsZXIgPSBmYWlsdXJlOwogICAgICAgIHRoaXMuX2FjdGl2ZT10cnVlOwogICAgICAgIHJldHVybiB0aGlzOwogICAgfSwKICAgIF9oYW5kbGVTdWNjZXNzOmZ1bmN0aW9uKGRhdGEpewogICAgICAgIHRoaXMuX3N1Y2Nlc3NIYW5kbGVyKGRhdGEpOyAKICAgIH0sCiAgICBfaGFuZGxlRXJyb3I6ZnVuY3Rpb24oZXJyKXsKICAgICAgICB0aGlzLl9lcnJvckhhbmRsZXIoZXJyKTsgICAKICAgIH0sCiAgICBxdWVyeTpmdW5jdGlvbigpewogICAgICAgICBfdGhhdD10aGlzOwogICAgICAgICBuYXZpZ2F0b3IuZ2VvbG9jYXRpb24uZ2V0Q3VycmVudFBvc2l0aW9uKGZ1bmN0aW9uKHBvcyl7CiAgICAgICAgICBpZihfdGhhdC5fYWN0aXZlKXsKICAgICAgICAgICAgIF90aGF0Ll9oYW5kbGVTdWNjZXNzKHBvcyk7CiAgICAgICAgICB9CiAgICAgICAgICBfdGhhdC5fYWN0aXZlPWZhbHNlOwogICAgICAgfSxmdW5jdGlvbihlcnIpewogICAgICAgICAgaWYoX3RoYXQuX2FjdGl2ZSl7CiAgICAgICAgICAgICBfdGhhdC5faGFuZGxlRXJyb3IoZXJyKTsKICAgICAgICAgIH0KICAgICAgICAgIF90aGF0Ll9hY3RpdmU9ZmFsc2U7CiAgICAgICB9LHt0aW1lb3V0OjEwMDAwfSk7CiAgICB9LAogICAgY2FuY2VsOmZ1bmN0aW9uKCl7CiAgICAgICAgX3RoYXQuX2FjdGl2ZT1mYWxzZTsKICAgIH0KCn07Ci8vIEdlb0xvY1F1ZXJ5IGRlZmluaXRpb24gZW5kcyBoZXJlCgovKioKKgoqICBCYXNlNjQgZW5jb2RlIC8gZGVjb2RlCiogIGh0dHA6Ly93d3cud2VidG9vbGtpdC5pbmZvLwoqCioqLwogCnZhciBCYXNlNjQgPSB7CiAKCS8vIHByaXZhdGUgcHJvcGVydHkKCV9rZXlTdHIgOiAiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz0iLAogCgkvLyBwdWJsaWMgbWV0aG9kIGZvciBlbmNvZGluZwoJZW5jb2RlIDogZnVuY3Rpb24gKGlucHV0KSB7CgkJdmFyIG91dHB1dCA9ICIiOwoJCXZhciBjaHIxLCBjaHIyLCBjaHIzLCBlbmMxLCBlbmMyLCBlbmMzLCBlbmM0OwoJCXZhciBpID0gMDsKIAoJCXdoaWxlIChpIDwgaW5wdXQubGVuZ3RoKSB7CiAKCQkJY2hyMSA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTsKCQkJY2hyMiA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTsKCQkJY2hyMyA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTsKIAoJCQllbmMxID0gY2hyMSA+PiAyOwoJCQllbmMyID0gKChjaHIxICYgMykgPDwgNCkgfCAoY2hyMiA+PiA0KTsKCQkJZW5jMyA9ICgoY2hyMiAmIDE1KSA8PCAyKSB8IChjaHIzID4+IDYpOwoJCQllbmM0ID0gY2hyMyAmIDYzOwogCgkJCWlmIChpc05hTihjaHIyKSkgewoJCQkJZW5jMyA9IGVuYzQgPSA2NDsKCQkJfSBlbHNlIGlmIChpc05hTihjaHIzKSkgewoJCQkJZW5jNCA9IDY0OwoJCQl9CiAKCQkJb3V0cHV0ID0gb3V0cHV0ICsKCQkJdGhpcy5fa2V5U3RyLmNoYXJBdChlbmMxKSArIHRoaXMuX2tleVN0ci5jaGFyQXQoZW5jMikgKwoJCQl0aGlzLl9rZXlTdHIuY2hhckF0KGVuYzMpICsgdGhpcy5fa2V5U3RyLmNoYXJBdChlbmM0KTsKIAoJCX0KIAoJCXJldHVybiBvdXRwdXQ7Cgl9LAogCgkvLyBwdWJsaWMgbWV0aG9kIGZvciBkZWNvZGluZwoJZGVjb2RlIDogZnVuY3Rpb24gKGlucHV0KSB7CgkJdmFyIG91dHB1dCA9ICIiOwoJCXZhciBjaHIxLCBjaHIyLCBjaHIzOwoJCXZhciBlbmMxLCBlbmMyLCBlbmMzLCBlbmM0OwoJCXZhciBpID0gMDsKIAoJCWlucHV0ID0gaW5wdXQucmVwbGFjZSgvW15BLVphLXowLTlcK1wvXD1dL2csICIiKTsKIAoJCXdoaWxlIChpIDwgaW5wdXQubGVuZ3RoKSB7CiAKCQkJZW5jMSA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTsKCQkJZW5jMiA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTsKCQkJZW5jMyA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTsKCQkJZW5jNCA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTsKIAoJCQljaHIxID0gKGVuYzEgPDwgMikgfCAoZW5jMiA+PiA0KTsKCQkJY2hyMiA9ICgoZW5jMiAmIDE1KSA8PCA0KSB8IChlbmMzID4+IDIpOwoJCQljaHIzID0gKChlbmMzICYgMykgPDwgNikgfCBlbmM0OwogCgkJCW91dHB1dCA9IG91dHB1dCArIFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMSk7CiAKCQkJaWYgKGVuYzMgIT0gNjQpIHsKCQkJCW91dHB1dCA9IG91dHB1dCArIFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMik7CgkJCX0KCQkJaWYgKGVuYzQgIT0gNjQpIHsKCQkJCW91dHB1dCA9IG91dHB1dCArIFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMyk7CgkJCX0KIAoJCX0KIAoJCXJldHVybiBvdXRwdXQ7CiAKCX0KIAoJCiAKfTsKCi8qKgogKiBVdGlsaXR5IFNpbmdsZXRvbiBmb3IgaGFuZGxpbmcgUE5HIERhdGEKICovCnZhciBQTkdVdGlsPShmdW5jdGlvbigpewogICAgdmFyIHNsZj17CiAgIF9MQ19TY3JpYmJsZV9NZXRhRGF0YUtleToiTENfU0NJQkJMRV9NRVRBREFUQSIsCiAgICAgICAgICAgX2lzUG5nOmZ1bmN0aW9uKGI2NGRhdGEpewogICAgICAgICAgICAgICByZXR1cm4gIGI2NGRhdGEgJiYgYjY0ZGF0YS5yZXBsYWNlKC9ccysvZywgIiIpLmluZGV4T2YoImlWQk9SdzBLR2dvIikgPT0gMDsgICAvLyBMQy01NzExIDogdHJpbSBhbnkgbGVhZGluZyBXaGl0ZVNwYWNlCiAgICAgICAgICAgICAgIC8vIFRPRE8gOiAgYmFzZTY0IGVuY29kaW5nIG1heSBoYXZlIHdoaXRlIHNwYWNlcyBldmVuIGJldHdlZW4gdGhlIG1hZ2ljIG51bWJlcnMgISEgVGhpbmsgb2YgYSBiZXR0ZXIgd2F5IHRvIHN0b3Agc3RyaXBwaW5nIHdoaXRlIHNwYWNlcyByZXBlYXRlZGx5IGluIFBOR1V0aWwsIGFuZCBjYWNoZSB0aGUgcmVzdWx0CiAgICAgICAgICAgfSwKICAgICAgICAgICBfdXBkYXRlX2NyYzpmdW5jdGlvbihjcmMsZGF0YSl7CiAgICAgICAgICAgICAgIHZhciBjID0gY3JjOwogICAgICAgICAgICAgICB2YXIgbjsKICAgICAgICAgICAgICAgZm9yKG49MDtuPGRhdGEubGVuZ3RoO24rKyl7CiAgICAgICAgICAgICAgICAgIGMgPSB0aGlzLl9YT1Ioc2xmLl9jcmNfdGFibGVbKHRoaXMuX1hPUihjLGRhdGEuY2hhckNvZGVBdChuKSkmMHhmZik+Pj4wXSwoYz4+PjgpKTsKICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICByZXR1cm4gYzsKICAgICAgICAgICB9LAoJCSAgIF9YT1I6ZnVuY3Rpb24oYSxiKXsKCQkgICAgICAgcmV0dXJuIChhXmIpPj4+MDsKCQkgICB9LAogICAgICAgICAgIF9VMzJJbnQyU3RyOmZ1bmN0aW9uKG4pewogICAgICAgICAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoKG4+Pj4yNCkmMHhGRikrU3RyaW5nLmZyb21DaGFyQ29kZSgobj4+PjE2KSYweEZGKStTdHJpbmcuZnJvbUNoYXJDb2RlKChuPj4+OCkmMHhGRikrU3RyaW5nLmZyb21DaGFyQ29kZShuPj4+MCYweEZGKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICBfaW5pdF9jcmNfdGFibGU6ZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgdmFyIGM9MDsKICAgICAgICAgICAgICAgdmFyIG4sazsKICAgICAgICAgICAgICAgc2xmLl9jcmNfdGFibGU9W107CiAgICAgICAgICAgICAgIGZvcihuPTA7bjwyNTY7bisrKXsKICAgICAgICAgICAgICAgICAgIGMgPSBuOwogICAgICAgICAgICAgICAgICAgZm9yKGs9MDtrPDg7aysrKXsKICAgICAgICAgICAgICAgICAgICAgIGlmKCgoYyYxKT4+PjApPjApewogICAgICAgICAgICAgICAgICAgICAgICAgIGMgPSBzbGYuX1hPUigweGVkYjg4MzIwICwgKGM+Pj4xKSk7CiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgIGMgPSBjPj4+MTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIHNsZi5fY3JjX3RhYmxlW25dPWM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgfSwKICAgICAgICAgICBfQ1JDOmZ1bmN0aW9uKGRhdGEpewogICAgICAgICAgICAgICAgaWYoIXRoaXMuX2NyY190YWJsZSkgdGhpcy5faW5pdF9jcmNfdGFibGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9YT1IodGhpcy5fdXBkYXRlX2NyYygweGZmZmZmZmZmLGRhdGEpICwgMHhmZmZmZmZmZik7CiAgICAgICAgICB9LAogICAgICAgICAgX3ByZXBhcmVUZXh0Q2h1bms6ZnVuY3Rpb24oY29udGVudCxwYWQpewogICAgICAgICAgICAgIC8vIHBhZCB0aGUgZGF0YSBhcHByb3ByaWF0ZWx5ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICB2YXIgbGVuID0gY29udGVudC5sZW5ndGg7CiAgICAgICAgICAgICAgIHZhciBsZW5TdHIgPSBzbGYuX1UzMkludDJTdHIobGVuKTsKICAgICAgICAgICAgICAgdmFyIGNodW5rVHlwZT0idEVYdCI7CiAgICAgICAgICAgICAgIHZhciBjaGVja1N1bVN0ciA9IHNsZi5fVTMySW50MlN0cihzbGYuX0NSQyhjaHVua1R5cGUrY29udGVudCkpOwogICAgICAgICAgICAgICByZXR1cm4gbGVuU3RyK2NodW5rVHlwZStjb250ZW50K2NoZWNrU3VtU3RyOwogICAgICAgICAgIH0sCiAgICAgICAgX3N0YXJ0OmZ1bmN0aW9uKHN0cil7CiAgICAgICAgICAgc2xmLl9zdGFydFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTsKICAgICAgICAgICBzbGYuX3N0YXJ0RnVuPXN0cjsKICAgICAgICB9LAogICAgICAgIF9lbmQ6ZnVuY3Rpb24oKXsKICAgICAgICAgICB2YXIgc3RyID0gIlRpbWUgIitzbGYuX3N0YXJ0RnVuKyI6ICIrKG5ldyBEYXRlKCkuZ2V0VGltZSgpLXNsZi5fc3RhcnRUaW1lKTsKICAgICAgICAgIC8vICAkKCdCT0RZJykuYXBwZW5kKCI8cD4iK3N0cisiPC9wPjxici8+Iik7CiAgICAgICAgfSwKICAgICAgICBfcmVhZFUzMkludDpmdW5jdGlvbihjdHgpewogICAgICAgICAgICB2YXIgdmFsPTA7CiAgICAgICAgICAgIHZhciBkPWN0eC5kOwogICAgICAgICAgICB2YWw9KChkLmNoYXJDb2RlQXQoY3R4LnArKyk8PDI0KXwoZC5jaGFyQ29kZUF0KGN0eC5wKyspPDwxNil8KGQuY2hhckNvZGVBdChjdHgucCsrKTw8OCl8KGQuY2hhckNvZGVBdChjdHgucCsrKSkpPj4+MDsKICAgICAgICAgICAgIHJldHVybiB2YWw7CiAgICAgICAgfSwKICAgICAgIF9yZWFkQ2h1bmtUeXBlOmZ1bmN0aW9uKGN0eCl7CiAgICAgICAgICB2YXIgZCA9IGN0eC5kOwogICAgICAgICAgdmFyIHN0ciA9IGRbY3R4LnArK10rZFtjdHgucCsrXStkW2N0eC5wKytdK2RbY3R4LnArK107CiAgICAgICAgICByZXR1cm4gc3RyOwogICAgICAgfSwKICAgICAgICBfbWFrZVJlYWRPbmx5OmZ1bmN0aW9uKGI2NGRhdGEpewogICAgICBzbGYuX3N0YXJ0KCJfbWFrZVJlYWRPbmx5Iik7CiAgICAgIC8vIGFzc3VtZSBhIHZhbGlkIHBuZyBpbWFnZSBlbmNvZGVkIGluIGJhc2U2NDsKICAgICAgdmFyIGJpbmRhdGEgPSBzbGYuX2F0b2IoYjY0ZGF0YS5yZXBsYWNlKC9ccysvZywgJycpKTsgLy8gcmVtb3ZlIHdoaXRlIHNwYWNlcyB0aGF0IG1pZ2h0IGhhdmUgYmVlbiBpbnNlcnRlZAogICAgICB2YXIgcG5nY3R4PXtwOjAsZDpiaW5kYXRhfTsKICAgICAgcG5nY3R4LnArPTg7Ly8gc2tpcCBwbmdoZWFkZXIKICAgICAgLy8gcmVhZCBJSERSCiAgICAgIHZhciBzaXplID0gc2xmLl9yZWFkVTMySW50KHBuZ2N0eCk7CiAgICAgIHNsZi5fcmVhZENodW5rVHlwZShwbmdjdHgpOyAvL0lIRFIKICAgICAgcG5nY3R4LnArPXNpemU7IC8vRGF0YQogICAgICBzbGYuX3JlYWRVMzJJbnQocG5nY3R4KTsvL0NSQwogICAgICB2YXIgbWV0YWRhdGFDaHVuayA9IHNsZi5fcHJlcGFyZVRleHRDaHVuayhzbGYuX0xDX1NjcmliYmxlX01ldGFEYXRhS2V5K1N0cmluZy5mcm9tQ2hhckNvZGUoMCkrInRydWUiKTsKICAgICAgdmFyIG5ld2RhdGEgPSBwbmdjdHguZC5zdWJzdHJpbmcoMCxwbmdjdHgucCkrbWV0YWRhdGFDaHVuaytwbmdjdHguZC5zdWJzdHJpbmcocG5nY3R4LnApOwogICAgICB2YXIgcmV0PSBzbGYuX2J0b2EobmV3ZGF0YSk7CiAgICAgIHNsZi5fZW5kKCk7CiAgICAgIHJldHVybiByZXQ7CiAgIH0sCiAgIF9hdG9iOmZ1bmN0aW9uKGlucCl7CiAgICAgIGlmKHdpbmRvdy5hdG9iKXsgcmV0dXJuIGF0b2IoaW5wKTsgfQoJICByZXR1cm4gQmFzZTY0LmRlY29kZShpbnApOwogICB9LAogICBfYnRvYTpmdW5jdGlvbihpbnApewogICAgICBpZih3aW5kb3cuYnRvYSl7IHJldHVybiBidG9hKGlucCk7IH0KCSAgcmV0dXJuIEJhc2U2NC5lbmNvZGUoaW5wKTsKICAgfSwKICAgX2lzUmVhZE9ubHk6ZnVuY3Rpb24oYjY0ZGF0YSl7CiAgICBzbGYuX3N0YXJ0KCJfaXNSZWFkT25seSIpOwogICAgICAgaWYoc2xmLl9pc1BuZyhiNjRkYXRhKSl7CiAgICAgICAgICAgdmFyIHRlc3RTdHIgPSBzbGYuX0xDX1NjcmliYmxlX01ldGFEYXRhS2V5K1N0cmluZy5mcm9tQ2hhckNvZGUoMCkrInRydWUiOwogICAgICAgICAgIHZhciBiaW5kYXRhID0gc2xmLl9hdG9iKGI2NGRhdGEucmVwbGFjZSgvXHMrL2csICcnKSk7IC8vIHN0cmlwIHdoaXRlIHNwYWNlcwogICAgICAgICAgIHZhciBwbmdjdHg9e3A6MCxkOmJpbmRhdGF9OwogICAgICAgICAgIHBuZ2N0eC5wKz04Oy8vIHNraXAgaGVhZGVyCiAgICAgICAgICAgd2hpbGUocG5nY3R4LnA8cG5nY3R4LmQubGVuZ3RoKXsKICAgICAgICAgICAgICAgdmFyIHNpemUgPSBzbGYuX3JlYWRVMzJJbnQocG5nY3R4KTsKICAgICAgICAgICAgICAgdmFyIHR5cGUgPSBzbGYuX3JlYWRDaHVua1R5cGUocG5nY3R4KTsKICAgICAgICAgICAgICAgaWYodHlwZT09InRFWHQiKXsKICAgICAgICAgICAgICAgICAgIGlmKHBuZ2N0eC5kLmluZGV4T2YodGVzdFN0cixwbmdjdHgucCk9PXBuZ2N0eC5wKXsKICAgICAgICAgICAgICAgICAgICAgICBzbGYuX2VuZCgpOwogICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcG5nY3R4LnArPXNpemU7CiAgICAgICAgICAgICAgc2xmLl9yZWFkVTMySW50KHBuZ2N0eCk7Ly8gCiAgICAgICAgICB9Ly8gd2hpbGUgZW5kCiAgICAgICB9CiAgICAgICBzbGYuX2VuZCgpOwogICAgICAgcmV0dXJuIGZhbHNlOwogICB9CiAgICB9OwogICAgcmV0dXJuIHNsZjsKfSkoKTsKCi8qKgogKiBKUXVlcnkgd2lkZ2V0IGRlZmluaXRpb24gc3RhcnRzIGhlcmUKICovCiQud2lkZ2V0KCAieGZhV2lkZ2V0LlNjcmliYmxlSW1hZ2VGaWVsZCIsICQueGZhV2lkZ2V0LmltYWdlRmllbGQsIHsKCiAgICBfd2lkZ2V0TmFtZToiU2NyaWJibGVJbWFnZUZpZWxkIiwKICAgIF9nZW9Mb2NRdWVyeTpudWxsLAogICBfZW1wdHlJbWFnZVZhbDpudWxsLC8vIHNob3VsZCBiZSBudWxsLCBidXQgZm9yIG5vdwogICBfZXh0cmFJbmZvOm51bGwsCiAgIF9kZWZhdWx0U3RhdHVzOiImbmJzcDsiLAogICBfZW5mb3JjZUdlb0xvYzohIW5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQYWQvaSksCiAgIF9zaWdDYW52YXNXaWR0aDo2OTYsCiAgIF9zaWdDYW52YXNIZWlnaHQ6MzkwLAogICBfZ2VvQ2FudklkOm51bGwsCiAgICBfZ2VvTG9jQXRCb3R0b206ZmFsc2UsCiAgIF9nZW9DYW52YXNIZWlnaHQ6MTAwLAogICBfZ2VvQ2FudmFzV2lkdGg6Njk2LAogICAKICAgIF9pc19yZWFkb25seTpmYWxzZSwKCQogICAgb3B0aW9uczogewogICAgICAgIHRhYkluZGV4OiAwLAogICAgICAgICJyb2xlIjogImltZyIKICAgIH0sCgogICAgZ2V0T3B0aW9uc01hcDogZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICByZXR1cm4gJC5leHRlbmQoe30scGFyZW50T3B0aW9uc01hcCx7CiAgICAgICAgICAgICJkaXNwbGF5VmFsdWUiOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5jb21taXRQcm9wZXJ0eSkgewogICAgICAgICAgICAgICAgICAgIGlmKCF2YWwpewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9kaXNwbGF5VmFsdWUodGhpcy5fZXh0cmFjdERhdGEodGhpcy5fY3JlYXRlRW1wdHlJbWFnZURhdGEoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hZGRDbGFzcygiZW1wdHlTY3JpYmJsZSIpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9pc19yZWFkb25seT1mYWxzZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVDbGFzcygiZW1wdHlTY3JpYmJsZSIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZihQTkdVdGlsLl9pc1BuZyh2YWwpKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aWRnZXRWYWx1ZSA9ICJkYXRhOmltYWdlL3BuZztiYXNlNjQsIit0aGlzLm9wdGlvbnMudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aWRnZXRWYWx1ZSA9ICJkYXRhOjtiYXNlNjQsIiArIHRoaXMub3B0aW9ucy52YWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZXRWYWx1ZSh3aWRnZXRWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSkKICAgIH0sCgogICAgZ2V0RXZlbnRNYXA6IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0RXZlbnRNYXAuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSxwYXJlbnRPcHRpb25zTWFwLHsKICAgICAgICAgICAgInNjcmliYmxlZm9jdXMiOnhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRU5URVJfRVZFTlQsCiAgICAgICAgICAgICJjbGljayI6bnVsbCwKICAgICAgICAgICAgInNjcmliYmxlY2xpY2siOnhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0xJQ0tfRVZFTlQsCiAgICAgICAgICAgICJjaGFuZ2UiOm51bGwsCiAgICAgICAgICAgICJzY3JpYmJsZWNoYW5nZSI6eGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQsCiAgICAgICAgICAgICJibHVyIjpudWxsLAogICAgICAgICAgICAic2NyaWJibGVjbG9zZSI6eGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FWElUX0VWRU5UCiAgICAgICAgfSkKICAgIH0sCgoJLyoqCgkgKiBUaGlzIGZ1bmN0aW9uIGFjaGlldmVzIGZvbGxvd2luZwoJICogMS4gQ2FsY3VsYXRlIGRpbWVuc2lvbnMgb2YgY2FudmFzZXMgdG8gYmUgdXNlZAoJICogMi4gRmluZG91dCBpZiByaWdodCBvciBib3R0b20gY2FudmFzIGlzIHRvIGJlIHVzZWQgZm9yIGdlbyBsb2NhdGlvbgoJICovCgoJIGFzcGVjdFJhdGlvVG9CZVVzZWQgOmZ1bmN0aW9uKCl7CiAgICAgICAgdmFyIGFzcGVjdFJhdGlvIDsKICAgICAgICBpZih0aGlzLm9wdGlvbnMuYXNwZWN0UmF0aW8gJiYgcGFyc2VGbG9hdCh0aGlzLm9wdGlvbnMuYXNwZWN0UmF0aW8pID4gMCl7CiAgICAgICAgICAgYXNwZWN0UmF0aW8gPSAxL3BhcnNlRmxvYXQodGhpcy5vcHRpb25zLmFzcGVjdFJhdGlvKTsgIC8vLS1pbiBNRiByYXRpbyBpcyBjb21wdXRlZCBhcyBoZWlnaHQvd2lkdGggaW5zdGVhZCBvZiB3aWR0aC9oZWlnaHQKICAgICAgICB9IGVsc2UgewogICAgICAgICAgIHZhciBpbWdFbCA9IHRoaXMuZWxlbWVudC5jaGlsZHJlbigiaW1nIiksCiAgICAgICAgICAgICAgIHdpZHRoID0gaW1nRWwuYXR0cignd2lkdGgnKSwKICAgICAgICAgICAgICAgaGVpZ2h0ID0gaW1nRWwuYXR0cignaGVpZ2h0JyksCiAgICAgICAgICAgICAgIGZpZWxkV2lkdGgsCiAgICAgICAgICAgICAgIGZpZWxkSGVpZ2h0OwoKICAgICAgICAgICBpZih3aWR0aCl7CiAgICAgICAgICAgICAgZmllbGRXaWR0aCA9IHBhcnNlSW50KHdpZHRoLDEwKTsKICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGZpZWxkV2lkdGggPSBpbWdFbC53aWR0aCgpOwogICAgICAgICAgIH0KICAgICAgICAgICBpZihoZWlnaHQpewogICAgICAgICAgICAgIGZpZWxkSGVpZ2h0ID0gcGFyc2VJbnQoaGVpZ2h0LDEwKTsKICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGZpZWxkSGVpZ2h0ID0gaW1nRWwuaGVpZ2h0KCk7CiAgICAgICAgICAgfQogICAgICAgICAgIGFzcGVjdFJhdGlvID0gZmllbGRIZWlnaHQvZmllbGRXaWR0aDsKICAgICAgICB9CgkgICAgcmV0dXJuIGFzcGVjdFJhdGlvOwoJIH0sCgogICAgX3NldFVwQ2FudmFzOmZ1bmN0aW9uKCl7CiAgICAgICAgdmFyIGFzcGVjdFJhdGlvIDsKCQlhc3BlY3RSYXRpbyA9IHRoaXMuYXNwZWN0UmF0aW9Ub0JlVXNlZCgpOwogICAgICAgCiAgICAgICAgLy8gbWF4IHdpZHRoLCBoZWlnaHQgb2YgZ2VuZXJhdGVkIGltYWdlCiAgICAgICAgdmFyIG1heFdpZHRoID0gNjQwOwogICAgICAgIHZhciBtYXhIZWlnaHQgPSA0ODA7CiAgICAgICAgCiAgICAgICAgLy8gd2lkdGggb2YgZmllbGQgc2NhbGVkIHRvIGZpdCBtYXggaW1hZ2Ugc2l6ZQogICAgICAgIHZhciBzY2FsZWRXaWR0aDsKICAgICAgICB2YXIgc2NhbGVkSGVpZ2h0OwogICAgICAgIAogICAgICAgIAoJCS8vIGFwcHJveCBwaXhlbHMgcmVxdWlyZWQgZm9yIHJlbmRlcmluZyBnZW8gbG9jIGluZm8gaW4gMTJwdCBBcmlhbCBmb250IAoJCXZhciBhcHByb3hHZW9Mb2NXaWR0aD0yNTA7CgkJdmFyIGFwcHJveEdlb0xvY0hlaWdodD04NDsKICAgICAgICAKICAgICAgICBzY2FsZWRXaWR0aCA9IG1heFdpZHRoOwogICAgICAgIHNjYWxlZEhlaWdodCA9IG1heFdpZHRoKmFzcGVjdFJhdGlvOwogICAgICAgIGlmKHNjYWxlZEhlaWdodD5tYXhIZWlnaHQpewogICAgICAgICAgICBzY2FsZWRIZWlnaHQgPSBtYXhIZWlnaHQ7CiAgICAgICAgICAgIHNjYWxlZFdpZHRoID0gbWF4SGVpZ2h0L2FzcGVjdFJhdGlvOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBzZXQgY2FudmFzIGRpbWVuc2lvbnMKICAgICAgICBpZihhc3BlY3RSYXRpbz49MSl7CgkJCXRoaXMuX2dlb0NhbnZJZD0naUVCb3hfZ2VvQ2FudmFzQm90dG9tJzsKICAgICAgICAgICAgdGhpcy5fZ2VvTG9jQXRCb3R0b209dHJ1ZTsKICAgICAgICAgIAoJCQkKICAgICAgICAgICAgIHRoaXMuX2dlb0NhbnZhc1dpZHRoID0gc2NhbGVkV2lkdGg7CgkJCSAvLyBsaW1pdCBoZWlnaHQgdG8gMzAlIG9mIGZ1bGwgaGVpZ2h0OwoJCQkgdGhpcy5fZ2VvQ2FudmFzSGVpZ2h0PU1hdGgubWluKGFwcHJveEdlb0xvY0hlaWdodCxzY2FsZWRIZWlnaHQvMyk7CiAgICAgICAgICAgICB0aGlzLl9zaWdDYW52YXNXaWR0aCA9IHNjYWxlZFdpZHRoOwogICAgICAgICAgICAgdGhpcy5fc2lnQ2FudmFzSGVpZ2h0PSBzY2FsZWRIZWlnaHQtKHRoaXMuX2VuZm9yY2VHZW9Mb2M/dGhpcy5fZ2VvQ2FudmFzSGVpZ2h0OjApOwogICAgICAgIH0gZWxzZSB7CgkJCXRoaXMuX2dlb0NhbnZJZD0naUVCb3hfZ2VvQ2FudmFzUmlnaHQnOwogICAgICAgICAgICB0aGlzLl9nZW9Mb2NBdEJvdHRvbT1mYWxzZTsKICAgICAgICAgICAKCQkJCiAgICAgICAgICAgIHRoaXMuX2dlb0NhbnZhc0hlaWdodCA9IHNjYWxlZEhlaWdodDsKCQkJLy8gbGltaXQgd2lkdGggdG8gMzAlIG9mIGZ1bGwgd2lkdGg7CgkJCXRoaXMuX2dlb0NhbnZhc1dpZHRoPU1hdGgubWluKGFwcHJveEdlb0xvY1dpZHRoLHNjYWxlZFdpZHRoLzMpOwogICAgICAgICAgICB0aGlzLl9zaWdDYW52YXNIZWlnaHQ9IHNjYWxlZEhlaWdodDsKICAgICAgICAgICAgdGhpcy5fc2lnQ2FudmFzV2lkdGg9IHNjYWxlZFdpZHRoLSh0aGlzLl9lbmZvcmNlR2VvTG9jP3RoaXMuX2dlb0NhbnZhc1dpZHRoOjApOwogICAgICAgIH0KICAgICAgIAogICAgfSwKCiAgIHJlbmRlciA6IGZ1bmN0aW9uKCkgewogICAgICAgdmFyIGdlb0xvY01hbmRhdG9yeU9uSXBhZCA9IHRoaXMub3B0aW9ucy5nZW9Mb2NNYW5kYXRvcnlPbklwYWQ7CiAgICAgICBpZih0eXBlb2YoZ2VvTG9jTWFuZGF0b3J5T25JcGFkKSE9InVuZGVmaW5lZCIpewogICAgICAgICAgIHRoaXMuX2VuZm9yY2VHZW9Mb2M9IHRoaXMuX2VuZm9yY2VHZW9Mb2MgJiYgKC9eKHRydWV8MSkkL2kpLnRlc3QoJC50cmltKGdlb0xvY01hbmRhdG9yeU9uSXBhZCkpOwogICAgICAgfQogICAgICAgdGhpcy5fd2d0SWQ9IndpZCIrfn4oTWF0aC5yYW5kb20oKSoyMDAwKSsiXyIrbmV3IERhdGUoKS5nZXRUaW1lKCk7CgogICAgICAgdmFyICRjb250cm9sID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUucmVuZGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykKCiAgICAgICBpZih0aGlzLm9wdGlvbnMudmFsdWUgfHwgdGhpcy5vcHRpb25zLnZhbHVlICE9IHRoaXMuX2VtcHR5SW1hZ2VWYWwpewogICAgICAgICAgdGhpcy5faXNfcmVhZG9ubHk9ISFQTkdVdGlsLl9pc1JlYWRPbmx5KHRoaXMub3B0aW9ucy52YWx1ZSk7CiAgICAgICB9CiAgIAogICAgICAgaWYodGhpcy5faXNfcmVhZG9ubHkpewogICAgICAgICAgJGNvbnRyb2wuYWZ0ZXIoIjxkaXYgaWQ9JyIrdGhpcy5fd2d0SWQrIicgY2xhc3M9J3NjX3BvcFVwTWVudSc+PC9kaXY+Iik7CiAgICAgICB9IGVsc2UgewogICAgICAgICAgJGNvbnRyb2wuYWZ0ZXIoIjxkaXYgaWQ9JyIrdGhpcy5fd2d0SWQrIicgc3R5bGU9J2Rpc3BsYXk6bm9uZTsnIGNsYXNzPSdzY19wb3BVcE1lbnUnPjwvZGl2PiIpOwogICAgICAgfQoJICAgCgkgICB0aGlzLl9zZXRVcENhbnZhcygpOwogICAgICAgcmV0dXJuICRjb250cm9sOwogICAgfSwKCiAgIGNsaWNrOiBmdW5jdGlvbigpIHsKICAgICAgICB0aGlzLmZvY3VzKCk7CiAgICAgICAgdmFyIHRtcEVsID0gdGhpcy5lbGVtZW50Lmxlbmd0aD90aGlzLmVsZW1lbnRbMF06dGhpcy5lbGVtZW50OwogICAgICAgIGlmKHRoaXMub3B0aW9ucy5hY2Nlc3MgIT0gIm9wZW4iKQogICAgICAgICAgcmV0dXJuOwogICAgICAgaWYgKFRvdWNoVXRpbC5QT0lOVEVSX0VOQUJMRUQgfHwgVG91Y2hVdGlsLlRPVUNIX0VOQUJMRUQpIHsKICAgICAgICAgICAvLyBzaW11bGF0ZSBhIGNsaWNrIGV2ZW50CiAgICAgICAgICAgdG1wRWwuZGlzcGF0Y2hFdmVudChUb3VjaFV0aWwuZ2V0UG9pbnRlckV2ZW50KFRvdWNoVXRpbC5QT0lOVEVSX0RPV04pKTsKICAgICAgICAgICB0bXBFbC5kaXNwYXRjaEV2ZW50KFRvdWNoVXRpbC5nZXRQb2ludGVyRXZlbnQoVG91Y2hVdGlsLlBPSU5URVJfVVApKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wudHJpZ2dlckhhbmRsZXIoImNsaWNrIik7CiAgICAgICAgfQogICB9LAoKICAgIF9hdHRhY2hFdmVudEhhbmRsZXJzOmZ1bmN0aW9uKCRjb250cm9sKXsKCSAgICAgaWYoVG91Y2hVdGlsLlBPSU5URVJfRU5BQkxFRCB8fCBUb3VjaFV0aWwuVE9VQ0hfRU5BQkxFRCl7CiAgICAgICAgICAgIHRoaXMuX2F0dGFjaFRvdWNoRXZlbnRIYW5kbGVycygkY29udHJvbCk7CiAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRoaXMuX2F0dGFjaE1vdXNlRXZlbnRIYW5kbGVycygkY29udHJvbCk7CiAgICAgICAgIH0KICAgICAgICAgJGNvbnRyb2wua2V5ZG93bigkLnByb3h5KHRoaXMuX2hhbmRsZUtleURvd24sdGhpcykpOwogICAgfSwKCV9hdHRhY2hFdmVudEhhbmRsZXJGb3JDcm9zc0ljb246ZnVuY3Rpb24oJGNvbnRyb2wpewoJICAgIHZhciBfdGhhdCA9IHRoaXM7CgkgICAgJGNvbnRyb2wubW91c2VlbnRlcihmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgICBpZihfdGhhdC5vcHRpb25zLmFjY2VzcyAhPSAib3BlbiIpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgICAgICAgICBpZihfdGhhdC5faXNfcmVhZG9ubHkpewogICAgICAgICAgICAgICAgJCgnIycrX3RoYXQuX3dndElkKS5jc3Moe2Rpc3BsYXk6J2Jsb2NrJ30pOwogICAgICAgICAgICAgICAgdmFyIGJvZHlNb3ZlSGFuZGxlcjsKICAgICAgICAgICAgICAgICQoJ2JvZHknKS5vbignbW91c2Vtb3ZlJyxib2R5TW92ZUhhbmRsZXI9ZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICAgICAgICAgIGlmKGV2ZW50LnRhcmdldCE9JCgnIycrX3RoYXQuX3dndElkKVswXSYmZXZlbnQudGFyZ2V0IT1fdGhhdC4kdXNlckNvbnRyb2xbMF0pewogICAgICAgICAgICAgICAgICAgICAgICAkKCcjJytfdGhhdC5fd2d0SWQpLmNzcyh7ZGlzcGxheTonbm9uZSd9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICQoJ2JvZHknKS5vZmYoJ21vdXNlbW92ZScsYm9keU1vdmVIYW5kbGVyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9CiAgICAgICB9KTsKCiAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ICQoIiMiK190aGF0Ll93Z3RJZCkuY2xpY2soJC5wcm94eShfdGhhdC5fb25Dcm9zc0NsaWNrLF90aGF0KSk7fSw1MCk7ICAKCX0sCiAgICBfYXR0YWNoVG91Y2hFdmVudEhhbmRsZXJzOmZ1bmN0aW9uKCRjb250cm9sKXsKICAgICAgICB2YXIgX3RpbWVyLF90aGF0PXRoaXM7CiAgICAgICAgdmFyIHRtcEVsID0gdGhpcy5lbGVtZW50Lmxlbmd0aD90aGlzLmVsZW1lbnRbMF06dGhpcy5lbGVtZW50OwogICAgICAgdG1wRWwuYWRkRXZlbnRMaXN0ZW5lcihUb3VjaFV0aWwuUE9JTlRFUl9ET1dOLGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICBpZihfdGhhdC5vcHRpb25zLmFjY2VzcyAhPSAib3BlbiIpCiAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICBfdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICBfdGltZXI9MDsKICAgICAgICAgICAgICAgX3RoYXQuX29uQ3Jvc3NDbGljayhldmVudCk7CiAgICAgICAgICAgIH0sMTAwMCk7CiAgICAgICAgfSk7CiAgICAgICB0bXBFbC5hZGRFdmVudExpc3RlbmVyKFRvdWNoVXRpbC5QT0lOVEVSX1VQLGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgaWYoX3RoYXQub3B0aW9ucy5hY2Nlc3MgIT0gIm9wZW4iKQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICBpZihfdGltZXIpewogICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoX3RpbWVyKTsKICAgICAgICAgICAgICAgX3RoYXQuX29uSW1hZ2VDbGljayhldmVudCk7CiAgICAgICAgICAgIH0gCiAgICAgICAgfSk7CgkJCgkgICBpZihUb3VjaFV0aWwuUE9JTlRFUl9FTkFCTEVEKXsKCQkgICAgIHRoaXMuX2F0dGFjaEV2ZW50SGFuZGxlckZvckNyb3NzSWNvbigkY29udHJvbCk7CgkJCSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ICQoIiMiK190aGF0Ll93Z3RJZCkub24oVG91Y2hVdGlsLlBPSU5URVJfVVAsZnVuY3Rpb24oZXZlbnQpewoJCQkgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwoJCQkgfSk7fSw1MCk7CgkgICB9CiAgICB9LAoKICAgIF9hdHRhY2hNb3VzZUV2ZW50SGFuZGxlcnM6ZnVuY3Rpb24oJGNvbnRyb2wpewogICAgICAgICB2YXIgX3RpbWVyPTAsX3RoYXQ9dGhpcyxfaG92ZXJUaW1lcj0wOwogICAgICAgICRjb250cm9sLmRibGNsaWNrKGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgaWYoX3RoYXQub3B0aW9ucy5hY2Nlc3MgIT0gIm9wZW4iKQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgICAgICAgaWYoX3RpbWVyLnZhbCl7CiAgICAgICAgICAgICBjbGVhclRpbWVvdXQoX3RpbWVyKTtfdGltZXIgPTA7CiAgICAgICAgICAgfQogICAgICAgICAgIF90aGF0Ll9vbkNyb3NzQ2xpY2soZXZlbnQpOwogICAgICAgIH0pLmNsaWNrKGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICBfdGhhdC4kdXNlckNvbnRyb2wudHJpZ2dlcigic2NyaWJibGVjbGljayIsZXZlbnQpOwogICAgICAgICAgIGlmKF90aGF0Lm9wdGlvbnMuYWNjZXNzICE9ICJvcGVuIikKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgICAgICAgIGlmKF90aW1lcil7CiAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF90aW1lcik7X3RpbWVyPTA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgX3RpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpewogICAgICAgICAgICAgICAgIF90aW1lcj0wOwogICAgICAgICAgICAgICAgIF90aGF0Ll9vbkltYWdlQ2xpY2soZXZlbnQpOwogICAgICAgICAgICAgIH0sNTAwKTsKICAgICAgICAgICAgfQogICAgICAgfSk7CgkgICAKCSAgIHRoaXMuX2F0dGFjaEV2ZW50SGFuZGxlckZvckNyb3NzSWNvbigkY29udHJvbCk7CiAgICAgICAKICAgIH0sCgogICAgX29uQ3Jvc3NDbGljazpmdW5jdGlvbihldmVudCl7CiAgICAgICAgaWYoIXRoaXMuX2lzX3JlYWRvbmx5KSByZXR1cm47CiAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wudHJpZ2dlcigic2NyaWJibGVmb2N1cyIsZXZlbnQpOwogICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXIoInNjcmliYmxlY2xpY2siLGV2ZW50KTsKICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgICAkLmFsZXJ0Qm94Lnllc05vKG51bGwsCiAgICAgICAgIHRoaXMubG9jYWxlU3RyaW5ncygpLmNsZWFyU2lnbmF0dXJlQ29uZmlybSwKICAgICAgICAgdGhpcy5sb2NhbGVTdHJpbmdzKCkuY2xlYXJTaWduYXR1cmUsCiAgICAgICAgICQucHJveHkodGhpcy5fcmVtb3ZlU2lnQ29uZmlybWF0aW9uSGFuZGxlcix0aGlzKSk7CiAgICAgfSwKCiAgICAgX3JlbW92ZVNpZ0NvbmZpcm1hdGlvbkhhbmRsZXI6ZnVuY3Rpb24oaXNZZXMpewogICAgICAgIGlmKGlzWWVzKXsKICAgICAgICAgICB0aGlzLl9zYXZlVmFsdWUodGhpcy5fZW1wdHlJbWFnZVZhbCk7CiAgICAgICAgICAgdGhpcy5fZGlzcGxheVZhbHVlKHRoaXMuX2V4dHJhY3REYXRhKHRoaXMuX2NyZWF0ZUVtcHR5SW1hZ2VEYXRhKCkpKTsKICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hZGRDbGFzcygiZW1wdHlTY3JpYmJsZSIpLnRyaWdnZXIoInNjcmliYmxlY2xvc2UiLHt9KTsKICAgICAgICAgICB0aGlzLl9pc19yZWFkb25seT1mYWxzZTsKICAgICAgICB9CiAgICAgfSwKCiAgICBfY3JlYXRlRW1wdHlJbWFnZURhdGE6ZnVuY3Rpb24oKXsKICAgICAgICAgaWYoIXRoaXMuX2VtcHR5SW1hZ2VEYXRhKXsKICAgICAgICAgICAgdmFyIGVtcHR5Q2FudmFzT2JqID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7CiAgICAgICAgICAgIGVtcHR5Q2FudmFzT2JqLnN0eWxlLndpZHRoPXRoaXMuX3NpZ0NhbnZhc1dpZHRoKydweCc7CiAgICAgICAgICAgIGVtcHR5Q2FudmFzT2JqLnN0eWxlLmhlaWdodD10aGlzLl9zaWdDYW52YXNIZWlnaHQrJ3B4JzsKICAgICAgICAgICAgZW1wdHlDYW52YXNPYmoud2lkdGg9dGhpcy5fc2lnQ2FudmFzV2lkdGg7CiAgICAgICAgICAgIGVtcHR5Q2FudmFzT2JqLmhlaWdodD10aGlzLl9zaWdDYW52YXNIZWlnaHQ7CiAgICAgICAgICAgIHZhciBjdHggPSBlbXB0eUNhbnZhc09iai5nZXRDb250ZXh0KCcyZCcpOwogICAgICAgICAgICBjdHguZmlsbFN0eWxlPScjZmZmZmZmJzsKICAgICAgICAgICAgY3R4LmNsZWFyUmVjdCgwLDAsdGhpcy5fc2lnQ2FudmFzV2lkdGgsdGhpcy5fc2lnQ2FudmFzSGVpZ2h0KTsKICAgICAgICAgICAgdGhpcy5fZW1wdHlJbWFnZURhdGEgPSBlbXB0eUNhbnZhc09iai50b0RhdGFVUkwoImltYWdlL3BuZyIpOwogICAgICAgICB9CiAgICAgICAgIHJldHVybiB0aGlzLl9lbXB0eUltYWdlRGF0YTsKICAgICB9LAoKICAgIGdldENvbW1pdFZhbHVlOiBmdW5jdGlvbigpIHsKICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnZhbHVlCiAgICB9LAoKICAgIF9zYXZlVmFsdWU6ZnVuY3Rpb24odmFsKXsKICAgICAgICB0aGlzLm9wdGlvbnMudmFsdWU9dmFsOwogICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXIoJ3NjcmliYmxlY2hhbmdlJyk7CiAgICB9LAoKICAgIF9kaXNwbGF5VmFsdWU6ZnVuY3Rpb24odmFsKXsKICAgICAgICBpZih0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHkpIHsKICAgICAgICAgICAgLy9oYXJkY29kZSB0aGUgd2lkZ2V0IFZBTFVFIGJ5IHVua25vd24gaW1hZ2UgdHlwZQogICAgICAgICAgICBpZih2YWwpewogICAgICAgICAgICAgIHZhciB3aWRnZXRWYWx1ZSA9ICJkYXRhOmltYWdlL3BuZztiYXNlNjQsIit2YWw7CiAgICAgICAgICAgICAgICB0aGlzLl9zZXRWYWx1ZSh3aWRnZXRWYWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICB0aGlzLmxvZ2dlcigpLmRlYnVnKCJ4ZmFWaWV3IiwiW0RlZmF1bHRXaWRnZXQuX3VwZGF0ZV0sIFVzZXIgQ29udHJvbCBvciBDb21taXQgUHJvcGVydHkgaXMgbnVsbCIgKTsKICAgIH0sCgogICAgX2RvT2s6ZnVuY3Rpb24oKXsKICAgICAgICB2YXIgbWFpbkNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ0NBTlZBUycpOwogICAgICAgIHZhciBnZW9DbnYgPSAkKCcjJyt0aGlzLl9nZW9DYW52SWQpWzBdOwogICAgICAgIHZhciBzaWdDbnYgPSAkKCcjaUVCb3hfY2FudmFzJylbMF07CiAgICAgICAgdmFyIGN0eCA9IG1haW5DYW52YXMuZ2V0Q29udGV4dCgnMmQnKTsKICAgICAgIAogICAgICAgIGlmKGdlb0Nudi53aWR0aD4wJiZnZW9DbnYuaGVpZ2h0PjApewogICAgICAgICAgICAKICAgICAgICAgICAgaWYodGhpcy5fZ2VvTG9jQXRCb3R0b20pewogICAgICAgICAgICAgICAgbWFpbkNhbnZhcy53aWR0aD1zaWdDbnYud2lkdGg7CiAgICAgICAgICAgICAgICBtYWluQ2FudmFzLmhlaWdodCA9c2lnQ252LmhlaWdodCtnZW9DbnYuaGVpZ2h0OwogICAgICAgICAgICAgICAgY3R4LmRyYXdJbWFnZShzaWdDbnYsMCwwKTsKICAgICAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2UoZ2VvQ252LDAsc2lnQ252LmhlaWdodCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBtYWluQ2FudmFzLndpZHRoPXNpZ0Nudi53aWR0aCtnZW9DbnYud2lkdGg7CiAgICAgICAgICAgICAgICBtYWluQ2FudmFzLmhlaWdodCA9c2lnQ252LmhlaWdodDsKICAgICAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2Uoc2lnQ252LDAsMCk7CiAgICAgICAgICAgICAgICBjdHguZHJhd0ltYWdlKGdlb0NudixzaWdDbnYud2lkdGgsMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgbWFpbkNhbnZhcy53aWR0aD1zaWdDbnYud2lkdGg7CiAgICAgICAgICAgICBtYWluQ2FudmFzLmhlaWdodCA9c2lnQ252LmhlaWdodDsKICAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2Uoc2lnQ252LDAsMCk7CiAgICAgICAgfQogICAgICAgIGltYWdlRWRpdERpYWxvZy5oaWRlKCk7CiAgICAgICAgdmFyIG5ld2RhdGEgPSBtYWluQ2FudmFzLnRvRGF0YVVSTCgiaW1hZ2UvcG5nIik7Ly8odGhpcy5teVNjcmliYmxlSGFuZGxlfHwiIikudG9TdHJpbmcoKTsKICAgICAgICAKICAgICAgICAgdmFyIHZhbCx2YWwxOwogICAgICAgICBpZigodmFsPS8qPSovdGhpcy5fZXh0cmFjdERhdGEobmV3ZGF0YSkpKXsKICAgICAgICAgLy8gIHZhbDEgPSBQTkdVdGlsLl9tYWtlUmVhZE9ubHkodmFsKTsKICAgICAgICAgICAgdmFsID0gUE5HVXRpbC5fbWFrZVJlYWRPbmx5KHZhbCk7CiAgICAgICAgICAgIHRoaXMuX3NhdmVWYWx1ZSh2YWwpOyAgIAogICAgICAgICAgICB0aGlzLl9pc19yZWFkb25seT10cnVlOyAgICAgICAKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMuX2dlb0xvY1F1ZXJ5JiZ0aGlzLl9nZW9Mb2NRdWVyeS5jYW5jZWwoKTsvLyBjYW5jZWwgY3VycmVudCBnZW8gbG9jIHJlcXVlc3Q7CiAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wudHJpZ2dlcigic2NyaWJibGVjbG9zZSIpCiAgICB9LAogICAgX2hhbmRsZU9rOmZ1bmN0aW9uKCl7CiAgICAgICAgaWYodGhpcy5fZW5mb3JjZUdlb0xvYyl7CiAgICAgICAgICAgdGhpcy5fZ2VvTG9jUXVlcnkgPSBuZXcgR2VvTG9jUXVlcnkoKS5pbml0KCQucHJveHkoZnVuY3Rpb24oZGF0YSl7CiAgICAgICAgICAgICAgIHRoaXMuX2dlb1F1ZXJ5U3VjY2Vzc0hhbmRsZXIoZGF0YSk7CiAgICAgICAgICAgICAgIHRoaXMuX2RvT2soKTsKICAgICAgICAgICB9LHRoaXMpLCQucHJveHkodGhpcy5fZ2VvUXVlcnlFcnJvckhhbmRsZXIsdGhpcykpOwogICAgICAgICAgIHRoaXMuX2dlb0xvY1F1ZXJ5LnF1ZXJ5KCk7CiAgICAgICAgICAgdGhpcy5fc2hvd01lc3NhZ2UodGhpcy5sb2NhbGVTdHJpbmdzKCkuZmV0Y2hHZW9Mb2NhdGlvbik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHRoaXMuX2RvT2soKTsKICAgICAgICB9CiAgICB9LAoKICAgIF9oYW5kbGVDYW5jZWw6ZnVuY3Rpb24oKXsKICAgICAgICAgaW1hZ2VFZGl0RGlhbG9nLmhpZGUoKTsKICAgICAgICAgdGhpcy5fZ2VvTG9jUXVlcnkmJnRoaXMuX2dlb0xvY1F1ZXJ5LmNhbmNlbCgpOy8vIGNhbmNlbCBjdXJyZW50IGdlbyBsb2MgcmVxdWVzdDsKICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC50cmlnZ2VyKCJzY3JpYmJsZWNsb3NlIikKICAgIH0sCgogICAgX2hhbmRsZUNsZWFyOmZ1bmN0aW9uKCl7CiAgICAgICAgdGhpcy5teVNjcmliYmxlSGFuZGxlLnNldEVuYWJsZWQodHJ1ZSk7CiAgICAgICAgdGhpcy5faXNfcmVhZG9ubHk9ZmFsc2U7CiAgICAgICAgdGhpcy5fbWFrZVJlYWRPbmx5KHRoaXMuX2lzX3JlYWRvbmx5KTsKICAgICAgICAkKCcjaUVCb3hfY2FudmFzJylbMF0ud2lkdGg9dGhpcy5fc2lnQ2FudmFzV2lkdGg7CiAgICAgICAgICQoJyNpRUJveF9jYXB0aW9uJykud2lkdGgodGhpcy5fc2lnQ2FudmFzV2lkdGgpOwoJCSQoJyNpRUJveF9jYW52YXMnKVswXS5oZWlnaHQ9dGhpcy5fc2lnQ2FudmFzSGVpZ2h0OwogICAgICAgICQoJyNrZXlib2FyZF9TaWduX0JveCcpWzBdLnZhbHVlPSIiOwogICAgICAgIHZhciBnZW9DYW52ID0gJCgnIycrdGhpcy5fZ2VvQ2FudklkKVswXTsKICAgICAgICBpbWFnZUVkaXREaWFsb2cuZW5hYmxlQnV0dG9ucyh7T2s6ZmFsc2UsQ2xlYXI6ZmFsc2V9KTsKICAgICAgICBnZW9DYW52LndpZHRoPTA7CiAgICAgICAgZ2VvQ2Fudi5oZWlnaHQ9MDsKICAgICAgICBpbWFnZUVkaXREaWFsb2cuX3Jlc2l6ZSgpOwogICAgICAgIHRoaXMuX2dlb0xvY1F1ZXJ5JiZ0aGlzLl9nZW9Mb2NRdWVyeS5jYW5jZWwoKTsvLyBjYW5jZWwgY3VycmVudCBnZW8gbG9jIHJlcXVlc3Q7CiAgICB9LAogICAgX21ha2VSZWFkT25seTpmdW5jdGlvbihyZWFkb25seSl7CiAgICAgICBpbWFnZUVkaXREaWFsb2cuZW5hYmxlQnV0dG9ucyh7T2s6ZmFsc2UsQ2xlYXI6ZmFsc2UsR2VvOiFyZWFkb25seSxCcnVzaDohcmVhZG9ubHksVGV4dDohcmVhZG9ubHl9KTsKICAgICAgIGlmKHJlYWRvbmx5KXsKCQkgICAkKCcjaUVCb3hfY2FudmFzJykuY3NzKHtib3JkZXI6JzFweCBzb2xpZCBncmF5J30pOwogICAgICAgICAgICQoJyNpRUJveF9jYXB0aW9uJykuY3NzKHtkaXNwbGF5Oidub25lJ30pOwoKICAgICAgIH0KICAgICAgIHRoaXMuX2RlZmF1bHRTdGF0dXMgPSAiJm5ic3A7IjsKICAgICAgIHRoaXMuX3Nob3dNZXNzYWdlKHRoaXMuX2RlZmF1bHRTdGF0dXMpOwogICAgfSwKCiAgICBfc2hvd01lc3NhZ2U6ZnVuY3Rpb24obXNnKXsKICAgICAgICB2YXIgX3RoYXQgPSB0aGlzOwogICAgICAgIGlmKHRoaXMuX21zZ1RpbWVvdXQpIHsgY2xlYXJUaW1lb3V0KHRoaXMuX21zZ1RpbWVvdXQpOyB0aGlzLl9tc2dUaW1lb3V0PTA7IH0KICAgICAgICAgJCgiI2lFQm94X3RpdGxlIikucmVwbGFjZVdpdGgoJzxkaXYgaWQ9ImlFQm94X3RpdGxlIj4nK21zZysnPC9kaXY+Jyk7CiAgICAgICAgIHRoaXMuX21zZ1RpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpewogICAgICAgICAgICAgJCgiI2lFQm94X3RpdGxlIikucmVwbGFjZVdpdGgoJzxkaXYgaWQ9ImlFQm94X3RpdGxlIj4nK190aGF0Ll9kZWZhdWx0U3RhdHVzKyc8L2Rpdj4nKTsKICAgICAgICAgfSwxNTAwMCk7CiAgICB9LAoKICAgIF9nZW9RdWVyeUVycm9ySGFuZGxlcjpmdW5jdGlvbihlcnIpewogICAgICAgIHRoaXMuX3Nob3dNZXNzYWdlKHRoaXMubG9jYWxlU3RyaW5ncygpLmVycm9yRmV0Y2hHZW9Mb2NhdGlvbik7CiAgICB9LAoKCV9nZXRMb2dNZXNzYWdlOmZ1bmN0aW9uKGtleSl7CgkJICAgICByZXR1cm4gdGhpcy5sb2dNc2dzKClba2V5XXx8a2V5OwoJfSwKCiAgICBfaGFuZGxlR2VvOmZ1bmN0aW9uKCl7CiAgICAgICAgICAvLyBpbml0aWF0ZSBnZW9sb2NhdGlvbiAKICAgICAgIGlmKG5hdmlnYXRvci5nZW9sb2NhdGlvbil7CiAgICAgICAgICAgdGhpcy5fZ2VvTG9jUXVlcnkgPSBuZXcgR2VvTG9jUXVlcnkoKS5pbml0KCQucHJveHkodGhpcy5fZ2VvUXVlcnlTdWNjZXNzSGFuZGxlcix0aGlzKSwkLnByb3h5KHRoaXMuX2dlb1F1ZXJ5RXJyb3JIYW5kbGVyLHRoaXMpKTsKICAgICAgICAgICB0aGlzLl9nZW9Mb2NRdWVyeS5xdWVyeSgpOwogICAgICAgICAgIHRoaXMuX3Nob3dNZXNzYWdlKHRoaXMubG9jYWxlU3RyaW5ncygpLmZldGNoR2VvTG9jYXRpb24pOwogICAgICAgfSBlbHNlIHsKICAgICAgICAgICB0aGlzLmxvZ2dlcigpLmRlYnVnKCJ4ZmFWaWV3Iix0aGlzLl9nZXRMb2dNZXNzYWdlKCJBTEMtRlJNLTkwMS0wMTEiKSk7CiAgICAgICB9CiAgICB9LAoKICAgIC8vIFRoaXMgRnVuY3Rpb24gaXMgdXNlZCB0byBmZXRjaCB0aGUgZ2VvbG9jYXRpb24uCiAgICBjYWxjdWxhdGVHZW9sb2NhdGlvbjogZnVuY3Rpb24oKXsKICAgICAgdGhpcy5faGFuZGxlR2VvKCk7CiAgICB9LAoKICAgIF9oYW5kbGVUZXh0OmZ1bmN0aW9uKCl7CiAgICAgICAgdmFyIHNpZ25Cb3hFbD1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgia2V5Ym9hcmRfU2lnbl9Cb3giKTsKICAgICAgICB2YXIgc2lnbkNhbnZhc0VsPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJpRUJveF9jYW52YXMiKTsKICAgICAgICBpZihzaWduQm94RWwudmFsdWUubGVuZ3RoPT0wKXsKICAgICAgICAgICAgdGhpcy5faGFuZGxlQ2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5fZGlzYWJsZVNpZ25hdHVyZUNhbnZhcygpOwogICAgICAgIHRoaXMuX2VuYWJsZVNpZ25hdHVyZVRleHRCb3goKTsKICAgICAgICBzaWduQm94RWwuZm9jdXMoKTsKICAgIH0sCgogICAgX2Rpc2FibGVTaWduYXR1cmVUZXh0Qm94OmZ1bmN0aW9uKCl7CiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImtleWJvYXJkX1NpZ25fQm94Iikuc3R5bGUuZGlzcGxheSA9ICJub25lIjsKICAgIH0sCgogICAgX2VuYWJsZVNpZ25hdHVyZVRleHRCb3g6ZnVuY3Rpb24oKXsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgia2V5Ym9hcmRfU2lnbl9Cb3giKS5zdHlsZS5kaXNwbGF5ID0gImlubGluZS1ibG9jayI7CiAgICB9LAoKICAgIF9kaXNhYmxlU2lnbmF0dXJlQ2FudmFzOmZ1bmN0aW9uKCl7CiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlFQm94X2NhbnZhcyIpLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7CiAgICB9LAoKICAgIF9lbmFibGVTaWduYXR1cmVDYW52YXM6ZnVuY3Rpb24oKXsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiaUVCb3hfY2FudmFzIikuc3R5bGUuZGlzcGxheSA9ICJpbmxpbmUtYmxvY2siOwogICAgfSwKCiAgICBfaGFuZGxlQnJ1c2hTZWxlY3Q6ZnVuY3Rpb24odyl7CiAgICAgICAgaWYodGhpcy5teVNjcmliYmxlSGFuZGxlJiYhdGhpcy5faXNfcmVhZG9ubHkpIHsKICAgICAgICAgICAgdGhpcy5teVNjcmliYmxlSGFuZGxlLnNldExpbmVXaWR0aCh3KTsKICAgICAgICB9CiAgICB9LAoKICAgIF9oYW5kbGVCcnVzaDpmdW5jdGlvbihldnQpewogICAgICAgIGlmKCQoJyNrZXlib2FyZF9TaWduX0JveCcpWzBdLnZhbHVlLmxlbmd0aD4wKXsKICAgICAgICAgICAgdGhpcy5faGFuZGxlQ2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5fZGlzYWJsZVNpZ25hdHVyZVRleHRCb3goKTsKICAgICAgICB0aGlzLl9lbmFibGVTaWduYXR1cmVDYW52YXMoKTsKICAgICAgICBpbWFnZUVkaXREaWFsb2cudG9nZ2xlQnJ1c2hMaXN0KGV2dCk7CiAgICB9LAoJX2hhbmRsZUtleURvd246ZnVuY3Rpb24oZXZlbnQpewoJCWlmKGV2ZW50LmtleUNvZGUgPT0gRU5URVJfS0VZIHx8IGV2ZW50LmNoYXJDb2RlID09IEVOVEVSX0tFWSB8fCBldmVudC53aGljaCA9PSBFTlRFUl9LRVkpIHsgLy8gdG91Y2ggZGV2aWNlcyBtYXkgcmV0dXJuIGNoYXJDb2RlCgkJICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CgkJICAgIHRoaXMuX29uSW1hZ2VDbGljayhldmVudCk7CgkJfSBlbHNlIGlmKGV2ZW50LmtleUNvZGUgPT0gREVMRVRFX0tFWSB8fCBldmVudC5jaGFyQ29kZSA9PSBERUxFVEVfS0VZIHx8IGV2ZW50LndoaWNoID09IERFTEVURV9LRVkpIHsKCQkgICAgdGhpcy5fb25Dcm9zc0NsaWNrKGV2ZW50KTsKCQl9CiAgICB9LAogICAgX2RpYWxvZ0NhbGxiYWNrOmZ1bmN0aW9uKGJ1dHRvbl92YWwsYXJnMSl7CiAgICAgICAgICAgLy8gYWRkIGJhY2sgb24gY2xpY2sgaGFuZGxlcgogICAgICAgICAvLyAgdGhpcy4kdXNlckNvbnRyb2wuY2xpY2soJC5wcm94eSh0aGlzLl9vbkltYWdlQ2xpY2ssIHRoaXMpKTsKICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgc3dpdGNoKGJ1dHRvbl92YWwpewogICAgICAgICAgICAgICBjYXNlICJPayI6CiAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZU9rKCk7CiAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICBjYXNlICJDYW5jZWwiOgogICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVDYW5jZWwoKTsKICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgIGNhc2UgIkNsZWFyIjoKICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQ2xlYXIoKTsKICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgIGNhc2UgIkdlbyI6CiAgICAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlR2VvbG9jYXRpb24oKTsKICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgIGNhc2UgIkJydXNoU2VsZWN0IjoKICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQnJ1c2hTZWxlY3QoYXJnMSk7CiAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICBjYXNlICJCcnVzaCI6CiAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUJydXNoKGFyZzEpOwogICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgY2FzZSAiVGV4dCI6CiAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVRleHQoKTsKICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgCiAgICAgICAgICAgfQogICAgfSwKCiAgICBfZ2VvUXVlcnlTdWNjZXNzSGFuZGxlcjpmdW5jdGlvbihkYXRhKXsKICAgICAgICB0aGlzLl9yZW5kZXJQb3NpdGlvbihkYXRhKTsKICAgIH0sCgoJX2ZpdEdlb0xvY1RleHQ6ZnVuY3Rpb24obGF0U3RyLGxvbmdTdHIsdGltZVN0cixjdHgsbWF4V2lkdGgsbWF4SGVpZ2h0KXsKCSAgICB2YXIgZm9udFNpemU9MTI7CgkJY3R4LmZvbnQ9ImJvbGQgIitmb250U2l6ZSsicHQgQXJpYWwiOwoJCXZhciB3aWR0aCA9IE1hdGgubWF4KGN0eC5tZWFzdXJlVGV4dChsYXRTdHIpLndpZHRoLGN0eC5tZWFzdXJlVGV4dChsb25nU3RyKS53aWR0aCxjdHgubWVhc3VyZVRleHQodGltZVN0cikud2lkdGgpOwoJCXZhciBsaW5lSGVpZ2h0ID0gY3R4Lm1lYXN1cmVUZXh0KCJtIikud2lkdGgqMS41OwoJCXdoaWxlKCh3aWR0aD5tYXhXaWR0aHx8MypsaW5lSGVpZ2h0Pm1heEhlaWdodCkmJmZvbnRTaXplPjEpewoJCSAgICBmb250U2l6ZS0tOwoJCSAgICBjdHguZm9udD0iYm9sZCAiK2ZvbnRTaXplKyJwdCBBcmlhbCI7CgkJICAgIHdpZHRoID0gTWF0aC5tYXgoY3R4Lm1lYXN1cmVUZXh0KGxhdFN0cikud2lkdGgsY3R4Lm1lYXN1cmVUZXh0KGxvbmdTdHIpLndpZHRoLGN0eC5tZWFzdXJlVGV4dCh0aW1lU3RyKS53aWR0aCk7CgkJICAgIGxpbmVIZWlnaHQgPSBjdHgubWVhc3VyZVRleHQoIm0iKS53aWR0aCoxLjU7CgkJfQoJCXJldHVybiB7d2lkdGg6d2lkdGgsbGluZUhlaWdodDpsaW5lSGVpZ2h0LGZvbnRTaXplOmZvbnRTaXplfTsKCX0sCgogICAgX3JlbmRlclBvc2l0aW9uOmZ1bmN0aW9uKHBvc2l0aW9uKXsKICAgICAgICBpZihwb3NpdGlvbiYmcG9zaXRpb24uY29vcmRzKXsKICAgICAgICAgdGhpcy5fc2hvd01lc3NhZ2UoIiZuYnNwOyIpOwogICAgICAgICAgICB2YXIgbGF0U3RyID0gdGhpcy5sb2NhbGVTdHJpbmdzKCkubGF0aXR1ZGUrIjogIiArIHBvc2l0aW9uLmNvb3Jkcy5sYXRpdHVkZTsKICAgICAgICAgICAgdmFyIGxvbmdTdHIgPSB0aGlzLmxvY2FsZVN0cmluZ3MoKS5sb25naXR1ZGUrIjogIiArIHBvc2l0aW9uLmNvb3Jkcy5sb25naXR1ZGU7CiAgICAgICAgICAgIHZhciBkYXRlT2JqID0gbmV3IERhdGUoKTsKICAgICAgICAgICAgdmFyIHRab25lID0gKGRhdGVPYmouZ2V0VGltZXpvbmVPZmZzZXQoKS82MCotMSk7CiAgICAgICAgICAgIAogICAgICAgICAgICB2YXIgdGltZVN0ciA9IHRoaXMubG9jYWxlU3RyaW5ncygpLnRpbWUrIjogIisoZGF0ZU9iai5nZXRNb250aCgpKzEpKyIvIitkYXRlT2JqLmdldERhdGUoKSsiLyIrZGF0ZU9iai5nZXRGdWxsWWVhcigpKyIgIitkYXRlT2JqLmdldEhvdXJzKCkrIjoiK2RhdGVPYmouZ2V0TWludXRlcygpKyI6IitkYXRlT2JqLmdldFNlY29uZHMoKSsoKHRab25lPjApPyIgKyI6IiAiKSsodFpvbmUpOwogICAgICAgICAgICB2YXIgY2FudmFzT2JqICA9ICQoJyMnK3RoaXMuX2dlb0NhbnZJZClbMF07CgkJCXZhciBzaWdDYW52YXMgPSAkKCcjaUVCb3hfY2FudmFzJylbMF07CiAgICAgICAgICAgIHZhciBzaWdUZXh0Qm94ID0gJCgnI2tleWJvYXJkX1NpZ25fQm94JylbMF07CgkJCXZhciBkdW1teUNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpOwogICAgICAgICAgICBpZihjYW52YXNPYmopewoJCQkgICB2YXIgY3R4ID0gY2FudmFzT2JqLmdldENvbnRleHQoJzJkJyk7CgkJCSAgIGN0eC5mb250PSJib2xkIDEycHQgQXJpYWwiOwoKCQkJICAgY2FudmFzT2JqLndpZHRoPXRoaXMuX2dlb0NhbnZhc1dpZHRoOwogICAgICAgICAgICAgICBjYW52YXNPYmouaGVpZ2h0PXRoaXMuX2dlb0NhbnZhc0hlaWdodDsKCQkJICAgdmFyIGxheW91dCA9IHRoaXMuX2ZpdEdlb0xvY1RleHQobGF0U3RyLGxvbmdTdHIsdGltZVN0cixjdHgsY2FudmFzT2JqLndpZHRoLGNhbnZhc09iai5oZWlnaHQpOwogICAgICAgICAgICAgICB2YXIgYXNwZWN0UmF0aW8gOwogICAgIAkJICAgYXNwZWN0UmF0aW8gPSB0aGlzLmFzcGVjdFJhdGlvVG9CZVVzZWQoKTsKCQkJICAgaWYoIXRoaXMuX2VuZm9yY2VHZW9Mb2MpewoJCQkgICAgICAgaWYodGhpcy5fZ2VvTG9jQXRCb3R0b20pewogICAgICAgICAgICAgICAgICAgICBkdW1teUNhbnZhcy5oZWlnaHQgPSB0aGlzLl9zaWdDYW52YXNIZWlnaHQtY2FudmFzT2JqLmhlaWdodDsKICAgICAgICAgICAgICAgICAgICAgZHVtbXlDYW52YXMud2lkdGggPSBkdW1teUNhbnZhcy5oZWlnaHQvYXNwZWN0UmF0aW87CiAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICBkdW1teUNhbnZhcy53aWR0aCA9IHRoaXMuX3NpZ0NhbnZhc1dpZHRoLWNhbnZhc09iai53aWR0aDsKCQkJCQkgZHVtbXlDYW52YXMuaGVpZ2h0ID0gZHVtbXlDYW52YXMud2lkdGgqYXNwZWN0UmF0aW87CgkJCQkgICB9CgkJCQkgICAvLyBtb3ZlIGRyYXduIHNpZ25hdHVyZSB0byBhIHRlbXBvcmFyeSBjYW52YXMgYW5kIHNjYWxlIGl0IHRvIG5ldyBkaW1lbnNpb24KICAgICAgICAgICAgICAgICAgIGR1bW15Q2FudmFzLmdldENvbnRleHQoJzJkJykuZHJhd0ltYWdlKHNpZ0NhbnZhcywwLDAsZHVtbXlDYW52YXMud2lkdGgsZHVtbXlDYW52YXMuaGVpZ2h0KTsKICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX2dlb0xvY0F0Qm90dG9tKXsKICAgICAgICAgICAgICAgICAgICAgc2lnQ2FudmFzLmhlaWdodCA9IGR1bW15Q2FudmFzLmhlaWdodDsKICAgICAgICAgICAgICAgICAgICAgc2lnVGV4dEJveC5oZWlnaHQgPSBkdW1teUNhbnZhcy5oZWlnaHQ7CiAgICAgICAgICAgICAgICAgICAgIHNpZ0NhbnZhcy5nZXRDb250ZXh0KCcyZCcpLmRyYXdJbWFnZShkdW1teUNhbnZhcywoc2lnQ2FudmFzLndpZHRoLWR1bW15Q2FudmFzLndpZHRoKS8yLDApOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgc2lnQ2FudmFzLndpZHRoID0gZHVtbXlDYW52YXMud2lkdGg7CiAgICAgICAgICAgICAgICAgICAgIHNpZ1RleHRCb3gud2lkdGggPSBkdW1teUNhbnZhcy53aWR0aDsKICAgICAgICAgICAgICAgICAgICAgc2lnQ2FudmFzLmdldENvbnRleHQoJzJkJykuZHJhd0ltYWdlKGR1bW15Q2FudmFzLDAsKHNpZ0NhbnZhcy5oZWlnaHQtZHVtbXlDYW52YXMuaGVpZ2h0KS8yKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICQoJyNpRUJveF9jYXB0aW9uJykud2lkdGgoc2lnQ2FudmFzLndpZHRoKTsKCQkJCSAgIGltYWdlRWRpdERpYWxvZy5lbmFibGVCdXR0b25zKHtDbGVhcjp0cnVlfSk7CgkJCSAgIH0KCQkJICAgICAgCgkJCSAgIHZhciBmd2lkdGggPSBsYXlvdXQud2lkdGg7CiAgICAgICAgICAgICAgIHZhciBmaGVpZ2h0ID0gbGF5b3V0LmxpbmVIZWlnaHQ7CgkJCSAgIHZhciBib3R0b21NYXJnaW49MjsKICAgICAgICAgICAgICAgY3R4LmZpbGxTdHlsZT0nIzU1NTU1NSc7CiAgICAgICAgICAgICAgIGN0eC5mb250PSJib2xkICIrbGF5b3V0LmZvbnRTaXplKyJwdCBBcmlhbCI7CiAgICAgICAgICAgICAgIGN0eC5maWxsVGV4dChsYXRTdHIsMCxjYW52YXNPYmouaGVpZ2h0LTIqZmhlaWdodC1ib3R0b21NYXJnaW4pOwogICAgICAgICAgICAgICBjdHguZmlsbFRleHQobG9uZ1N0ciwwLGNhbnZhc09iai5oZWlnaHQtZmhlaWdodC1ib3R0b21NYXJnaW4pOwogICAgICAgICAgICAgICBjdHguZmlsbFRleHQodGltZVN0ciwwLGNhbnZhc09iai5oZWlnaHQtYm90dG9tTWFyZ2luKTsKCQkJICAgCgkJCSAgIGltYWdlRWRpdERpYWxvZy5fcmVzaXplKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAogICAgX3NjcmliYmxlQ2FsbGJhY2s6ZnVuY3Rpb24oKXsKICAgICAgIGltYWdlRWRpdERpYWxvZy5lbmFibGVCdXR0b25zKHtDbGVhcjp0cnVlLE9rOnRydWV9KTsgIC8vICBlbmFibGUgY2xlYXIgYW5kIG9rIGJ1dHRvbnMKICAgIH0sCiAgICBfb25JbWFnZUNsaWNrOmZ1bmN0aW9uKCl7CiAgICAgICBpZighaW1hZ2VFZGl0RGlhbG9nLmdldElzT3BlbigpKXsKICAgICAgICAgICB2YXIgX3RoYXQgPSB0aGlzOwogICAgICAgICAgIGltYWdlRWRpdERpYWxvZy5zaG93KCImbmJzcDsiLCQucHJveHkodGhpcy5fZGlhbG9nQ2FsbGJhY2ssIHRoaXMpKTsKICAgICAgICAgICBpZighdGhpcy5fZW5mb3JjZUdlb0xvYyl7CiAgICAgICAgICAgICAgICQoJyNpRUJveF9HZW8nKS5jc3Moe2Rpc3BsYXk6J2lubGluZS1ibG9jayd9KTsKICAgICAgICAgICB9CiAgICAgICAgICAgdmFyIGltYWdlID0gbmV3IEltYWdlKCk7CiAgICAgICAgICAgaW1hZ2Uub25sb2FkPWZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgIF90aGF0Lm15U2NyaWJibGVIYW5kbGUgPSBuZXcgU2NyaWJibGUoImlFQm94X2NhbnZhcyIsaW1hZ2UsaW1hZ2Uud2lkdGgsaW1hZ2UuaGVpZ2h0LCQucHJveHkoX3RoYXQuX3NjcmliYmxlQ2FsbGJhY2ssX3RoYXQpKTsKICAgICAgICAgICAgICAgX3RoYXQubXlTY3JpYmJsZUhhbmRsZS5zZXRFbmFibGVkKCFfdGhhdC5faXNfcmVhZG9ubHkpOwogICAgICAgICAgICAgICAkKCcjaUVCb3hfY2FwdGlvbicpLndpZHRoKGltYWdlLndpZHRoKTsKICAgICAgICAgICAgICAgJCgnI2lFQm94X2NvbnRhaW5lcicpLmNzcyh7ZGlzcGxheTondGFibGUnfSk7CiAgICAgICAgICAgICAgIGlmKCQoJyNpRUJveF9jb250YWluZXInKS5sZW5ndGggPT0gMSl7CiAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfY29udGFpbmVyJylbMF0uZm9jdXMoKTsKICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICBpbWFnZUVkaXREaWFsb2cuX3Jlc2l6ZSgpOwogICAgICAgICAgICAgICBpbWFnZUVkaXREaWFsb2cuX3JlcG9zaXRpb24oKTsgICAgICAvLyByZWNhbGN1bGF0ZSBwb3NpdGlvbiwgc28gdGhhdCB0aGUgdmFsdWVzIGFyZSB1cGRhdGVkLCBlc3AuIGluIGlQYWQKICAgICAgICAgICB9CiAgICAgICAgICAgaWYoIXRoaXMub3B0aW9ucy52YWx1ZXx8dGhpcy5vcHRpb25zLnZhbHVlPT10aGlzLl9lbXB0eUltYWdlVmFsKXsKICAgICAgICAgICAgICAgdGhpcy5faXNfcmVhZG9ubHk9ZmFsc2U7CiAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmFkZENsYXNzKCJlbXB0eVNjcmliYmxlIik7CiAgICAgICAgICAgICAgIGltYWdlLnNyYyA9IHRoaXMuX2NyZWF0ZUVtcHR5SW1hZ2VEYXRhKCk7CiAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQ2xhc3MoImVtcHR5U2NyaWJibGUiKTsKICAgICAgICAgICAgICAgaWYoUE5HVXRpbC5faXNQbmcodGhpcy5vcHRpb25zLnZhbHVlKSl7CiAgICAgICAgICAgICAgICAgICB0aGlzLl9pc19yZWFkb25seSA9ICEhUE5HVXRpbC5faXNSZWFkT25seSh0aGlzLm9wdGlvbnMudmFsdWUpOwoJCQkgICAgICAgaW1hZ2Uuc3JjID0gImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCwiK3RoaXMub3B0aW9ucy52YWx1ZTsvL3RoaXMuY3JlYXRlQmwgX3RoYXQuJHVzZXJDb250cm9sLmF0dHIoX3RoYXQub3B0aW9ucy5jb21taXRQcm9wZXJ0eSk7CiAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICBpbWFnZS5zcmMgPSAiZGF0YTo7YmFzZTY0LCIgKyB0aGlzLm9wdGlvbnMudmFsdWU7Ly90aGlzLmNyZWF0ZUJsIF90aGF0LiR1c2VyQ29udHJvbC5hdHRyKF90aGF0Lm9wdGlvbnMuY29tbWl0UHJvcGVydHkpOwoJCSAgICAgICB9CiAgICAgICAgICAgfQogICAgICAgICAgIHRoaXMuX21ha2VSZWFkT25seSh0aGlzLl9pc19yZWFkb25seSk7CiAgICAgICB9CiAgICB9LAoKICAgIF9leHRyYWN0RGF0YTpmdW5jdGlvbihkYXRhdXJpKXsKICAgICAgICB2YXIgaWR4OwogICAgICAgIGlmKGRhdGF1cmkhPW51bGwmJmRhdGF1cmkubGVuZ3RoPjAmJmRhdGF1cmkuaW5kZXhPZigiZGF0YToiKT09MCl7CiAgICAgICAgICAgIGlmKChpZHg9ZGF0YXVyaS5pbmRleE9mKCIsIikpPjApewogICAgICAgICAgICAgICAgcmV0dXJuIGRhdGF1cmkuc3Vic3RyKGlkeCsxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sCgogICAgX3NldFZhbHVlOmZ1bmN0aW9uKHZhbCl7CiAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucHJvcCh0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHksIHZhbCk7CiAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cih0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHksIHZhbCk7CiAgICAgICAgaWYodGhpcy5fZHVtbXlJbWcpewogICAgICAgICAgICB0aGlzLl9kdW1teUltZy5zZXRBdHRyaWJ1dGUodGhpcy5vcHRpb25zLmNvbW1pdFByb3BlcnR5LHZhbCk7CiAgICAgICAgfQogICAgfQp9KTsKIC8vaGFjayBmb3IgSU9TNSB0b3VjaCBidWcKICAkKGZ1bmN0aW9uKCl7CiAgICAgICAgICQoJ2JvZHknKS5vbigndG91Y2hzdGFydCcsIGZ1bmN0aW9uKGUpIHt9KTsKICB9KTsKICAKfSkoJCx4ZmFsaWIpOwooZnVuY3Rpb24gKCQsIHdpbmRvdywgXykgewoKICAgIHZhciBfZGVmYXVsdHMgPSB7CiAgICAgICAgcGxhY2VIb2xkZXJUZXh0IDogIkVudGVyIGNvbW1lbnRzIGhlcmUiCiAgICB9OwoKICAgIHZhciBBZG9iZUZpbGVBdHRhY2htZW50ID0gZnVuY3Rpb24gKGVsZW1lbnQsIG9wdGlvbnMpIHsKICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zOwogICAgICAgIHRoaXMuJGVsZW1lbnRGaWxlVXBsb2FkQnRuID0gW107CiAgICAgICAgdGhpcy4kZWxlbWVudEZpbGVMaXN0ID0gW107CiAgICAgICAgdGhpcy4kZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICAgICAgaWYgKHRoaXMuJGVsZW1lbnQuYXR0cigibXVsdGlwbGUiKSAmJiAheGZhbGliLnV0LlV0aWxpdGllcy5faXNEYXRhQ29udGFpbmVyU3VwcG9ydGVkKCkpIHsKICAgICAgICAgICAgLy8gcmVtb3ZlIG11bHRpcGxlIGF0dHJpYnV0ZSBpZiBtdWx0aSBmaWxlIHNlbGVjdGlvbiBpbiBvbmUgZ28gaXMgbm90IHN1cHBvcnRlZAogICAgICAgICAgICB0aGlzLiRlbGVtZW50LnJlbW92ZUF0dHIoIm11bHRpcGxlIik7CiAgICAgICAgfQogICAgICAgIHRoaXMuJHBhcmVudCA9IHRoaXMuJGVsZW1lbnQucGFyZW50KCk7CiAgICAgICAgdGhpcy5pbnZhbGlkRmVhdHVyZSA9IHsKICAgICAgICAgICAgIlNJWkUiOjEsCiAgICAgICAgICAgICJOQU1FIjoyLAogICAgICAgICAgICAiTUlNRVRZUEUiOjMKICAgICAgICB9OwogICAgICAgIE9iamVjdC5mcmVlemUodGhpcy5pbnZhbGlkRmVhdHVyZSk7CiAgICAgICAgLy8gaW5pdGlhbGl6ZSB0aGUgcmVnZXggaW5pdGlhbGx5CiAgICAgICAgdGhpcy5yZWdleE1pbWVUeXBlTGlzdCAgPSB0aGlzLm9wdGlvbnMubWltZVR5cGUubWFwKGZ1bmN0aW9uICh2YWx1ZSwgaSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWdFeHAodmFsdWUudHJpbSgpKTsKICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgLy8gZmFpbHVyZSBkdXJpbmcgcmVnZXggcGFyc2luZywgZG9uJ3QgcmV0dXJuIGFueXRoaW5nIHNwZWNpZmljIHRvIHRoaXMgdmFsdWUgc2luY2UgdGhlIHZhbHVlIGNvbnRhaW5zCiAgICAgICAgICAgICAgICAvLyBpbmNvcnJlY3QgcmVnZXggc3RyaW5nCiAgICAgICAgICAgICAgICBpZih3aW5kb3cuY29uc29sZSkgewogICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9OwoKICAgIHZhciBpc0Jyb3dzZXJJRTlPcklFMTAgPSAoJC5icm93c2VyLm1zaWUgJiYgKCQuYnJvd3Nlci52ZXJzaW9uID09PSAnOS4wJyB8fCAkLmJyb3dzZXIudmVyc2lvbiA9PT0gJzEwLjAnKSksCiAgICAgICAgZmlsZUxhYmVsc0NvdW50ID0gMDsKCgogICAgQWRvYmVGaWxlQXR0YWNobWVudC5wcm90b3R5cGUgPSB7CiAgICAgICAgX2ZpbGVJZnJhbWVOYW1lIDogImd1aWRlLWZ1LWlmcmFtZSIsCiAgICAgICAgX2FkZEZpbGUgOiAiQWRkIEZpbGUiLAoKICAgICAgICBjbGVhcjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLiRlbGVtZW50LnZhbCgnJyk7CiAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRGaWxlTGlzdC5lbXB0eSgpOwogICAgICAgIH0sCgogICAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdGhpcy4kZmlsZURvbUVsZW1lbnRzID0gJC5tYXAodGhpcy4kZmlsZURvbUVsZW1lbnRzLCBmdW5jdGlvbihpdGVtKXsKICAgICAgICAgICAgICAgIC8vIHNpbmNlIGl0ZW0gY2FuIGJlIG51bGwgb3Igb2JqZWN0LCBkb2luZyB0aGlzIGNoZWNrCiAgICAgICAgICAgICAgICBpZihfLmlzT2JqZWN0KGl0ZW0pICYmIGl0ZW0udmFsKCkubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgLy9UT0RPOiByZW1vdmUgaXRlbSBmcm9tIGRvbSwgc2luY2UgdGhlcmUgaXMgYSBtZW1vcnkgbGVhawogICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgdGhpcy52YWx1ZXMgPSBbXTsKICAgICAgICAgICAgaWYoaXNCcm93c2VySUU5T3JJRTEwKXsKICAgICAgICAgICAgICAgIGlmKF8ubGFzdCh0aGlzLiRmaWxlRG9tRWxlbWVudHMpID09IG51bGwpewogICAgICAgICAgICAgICAgICAgIHRoaXMuY2xvbmVGaWxlSW5wdXRBbmRVcGRhdGVJZEZvcklFOSgpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUxhYmVsRm9yQXR0cihfLmxhc3QodGhpcy4kZmlsZURvbUVsZW1lbnRzKS5hdHRyKCJpZCIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoImNoYW5nZS5maWxldXBsb2FkIik7CiAgICAgICAgfSwKCiAgICAgICAgX3NldFVybCA6IGZ1bmN0aW9uKHVybCwgaW5kZXgpewogICAgICAgICAgICB0aGlzLiRlbGVtZW50RmlsZUxpc3QuZmluZCgic3Bhbi5ndWlkZS1mdS1maWxlTmFtZSIpLmVxKGluZGV4KS5kYXRhKCJrZXkiLCB1cmwpOwogICAgICAgIH0sCgogICAgICAgIF9nZXRVcmwgOiBmdW5jdGlvbihpbmRleCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy4kZWxlbWVudEZpbGVMaXN0LmZpbmQoInNwYW4uZ3VpZGUtZnUtZmlsZU5hbWUiKS5lcShpbmRleCkuZGF0YSgia2V5Iik7CiAgICAgICAgfSwKICAgICAgICBnZXRTZXRGaWxlUGF0aEFuZFJldHVybk5hbWVQYXRoTWFwOiBmdW5jdGlvbih2YWx1ZUxpc3QpIHsKCiAgICAgICAgICAgIHZhciBtYXBPZk9iamVjdHNIYXZpbmdUZW1wUGF0aEFuZEZpbGVOYW1lcyA9IHt9LAogICAgICAgICAgICAgICAgJHRlbXAsCiAgICAgICAgICAgICAgICB0ZW1wUGF0aDsKCiAgICAgICAgICAgICQuZWFjaCh0aGlzLiRlbGVtZW50RmlsZUxpc3QuY2hpbGRyZW4oKSwgZnVuY3Rpb24gKCBpbmRleCwgY2hpbGRMaUVsZW1lbnQpIHsKICAgICAgICAgICAgICAgICR0ZW1wID0gJChjaGlsZExpRWxlbWVudCkuZmluZCgic3Bhbi5ndWlkZS1mdS1maWxlTmFtZSIpOwogICAgICAgICAgICAgICAgdGVtcFBhdGggPSAkdGVtcC5kYXRhKCJrZXkiKTsKICAgICAgICAgICAgICAgIGlmKCF0ZW1wUGF0aCAmJiB2YWx1ZUxpc3QgJiYgdmFsdWVMaXN0W2luZGV4XSkgewogICAgICAgICAgICAgICAgICAgICR0ZW1wLmRhdGEoImtleSIsIHZhbHVlTGlzdFtpbmRleF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbWFwT2ZPYmplY3RzSGF2aW5nVGVtcFBhdGhBbmRGaWxlTmFtZXNbJHRlbXAuaHRtbCgpXSA9IHRlbXBQYXRoIHx8ICR0ZW1wLmRhdGEoImtleSIpOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgcmV0dXJuIG1hcE9mT2JqZWN0c0hhdmluZ1RlbXBQYXRoQW5kRmlsZU5hbWVzOwogICAgICAgIH0sCgoKICAgICAgICB2YWx1ZSA6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgIGlmKCFfLmlzVW5kZWZpbmVkKHZhbHVlKSkgewogICAgICAgICAgICAgICAgdmFyIF9zZWxmID0gdGhpcywKICAgICAgICAgICAgICAgICAgICBjb21tZW50cyA9IHRoaXMuY29tbWVudCgpLAogICAgICAgICAgICAgICAgICAgIGlzQ2hhbmdlID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZmlsZU5hbWVzID0gXy5pc0FycmF5KHRoaXMub3B0aW9ucy5maWxlTmFtZXMpID8gdGhpcy5vcHRpb25zLmZpbGVOYW1lcyA6IG51bGwsCiAgICAgICAgICAgICAgICAgICAgb2xkVXJscyA9IHt9OwogICAgICAgICAgICAgICAgLy8gQ2FjaGUgdGhlIHVybCBiZWZvcmUgZGVsZXRpb24KICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRGaWxlTGlzdC5jaGlsZHJlbigpLmZpbmQoInNwYW4uZ3VpZGUtZnUtZmlsZU5hbWUiKS5lYWNoKGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICAgICAgdmFyIHVybCA9ICQodGhpcykuZGF0YSgia2V5Iik7CiAgICAgICAgICAgICAgICAgICAgaWYoIV8uaXNVbmRlZmluZWQodXJsKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmaWxlTmFtZSA9IHVybC5zdWJzdHJpbmcodXJsLmxhc3RJbmRleE9mKCIvIikgKyAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgb2xkVXJsc1tmaWxlTmFtZV0gPSB1cmw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB0aGlzLiRlbGVtZW50RmlsZUxpc3QuZW1wdHkoKTsKICAgICAgICAgICAgICAgIGlmKHZhbHVlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgYXJyID0gdmFsdWUuc3BsaXQoIlxuIik7CiAgICAgICAgICAgICAgICAgICAgLy8gY29udHJ1Y3QgaW5pdGlhbCBmaWxlIG5hbWUgYW5kIHZhbHVlIG1hcAogICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgZG9uZSBvbmx5IG9uY2UgaW4gZW50aXJlIGxpdmUgY3ljbGUsIGl0cyBkb25lIGhlcmUsIHNpbmNlIHdlIGdldCB2YWx1ZSBoZXJlCiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVOYW1lcyAmJiBfLmlzRW1wdHkodGhpcy5faW5pdGlhbEZpbGVWYWx1ZUZpbGVOYW1lTWFwKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgZmlsZU5hbWVzLmxlbmd0aDsgaW5kZXgrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NlbGYuX2luaXRpYWxGaWxlVmFsdWVGaWxlTmFtZU1hcFthcnJbaW5kZXhdXSA9IGZpbGVOYW1lc1tpbmRleF0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBVcGRhdGUgdGhlIHZhbHVlIGFycmF5IHdpdGggdGhlIGZpbGUKICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlcyA9IF8ubWFwKGFyciwgZnVuY3Rpb24oZmlsZU5hbWUsIGluZGV4KXsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgZmlsZSBOYW1lIGlzIGEgcGF0aCwgaWYgeWVzIGdldCB0aGUgbGFzdCBwYXJ0IGFmdGVyICIvIgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2xhc2ggPSBmaWxlTmFtZS5sYXN0SW5kZXhPZigiLyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVVybCA9IGZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVVwbG9hZFVybCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHNsYXNoICE9PSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RvcmUgdGhlIGNhY2hlZCB1cmwgaGVyZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVVybCA9IGZpbGVVcGxvYWRVcmwgPSBmaWxlTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gZmlsZU5hbWUuc3Vic3RyaW5nKHNsYXNoICsgMSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYXNlOiB3aGVuIHlvdSBjbGljayBvbiBzYXZlIHNlY29uZCB0aW1lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZigoXy5pc09iamVjdChfc2VsZi4kZmlsZURvbUVsZW1lbnRzW2luZGV4XSkgJiYgX3NlbGYuJGZpbGVEb21FbGVtZW50c1tpbmRleF0udmFsKCkubGVuZ3RoID4gMCkgfHwgXy5pc1N0cmluZyhfc2VsZi4kZmlsZURvbUVsZW1lbnRzW2luZGV4XSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQ2hhbmdlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2VsZi4kZmlsZURvbUVsZW1lbnRzW2luZGV4XSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYoX3NlbGYuJGZpbGVEb21FbGVtZW50c1tpbmRleF0gIT09IG51bGwpIHsgLy8gY3JlYXRlIGEgZHVtbXkgZmlsZSBkb20gZm9yIHRoZSBjYWNoZWQgdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNDaGFuZ2UgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zZWxmLiRmaWxlRG9tRWxlbWVudHMuc3BsaWNlKGluZGV4LCAwLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvbGRVcmxzW2ZpbGVOYW1lXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVVwbG9hZFVybCA9IG9sZFVybHNbZmlsZU5hbWVdOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIGZpbGVOYW1lcyBvcHRpb25zIGlzIGV4cGxpY2l0bHkgcGFzc2VkLCB1c2UgaXQKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVOYW1lcyAmJiBfc2VsZi5faW5pdGlhbEZpbGVWYWx1ZUZpbGVOYW1lTWFwW2ZpbGVVcmxdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZSA9IF9zZWxmLl9pbml0aWFsRmlsZVZhbHVlRmlsZU5hbWVNYXBbZmlsZVVybF07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgX3NlbGYuc2hvd0ZpbGVMaXN0KGZpbGVOYW1lLCBjb21tZW50c1tpbmRleF0sIGZpbGVVcGxvYWRVcmwpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsZVVybDsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICBpZihpc0NoYW5nZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcigiY2hhbmdlLmZpbGV1cGxvYWQiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmKF8uaXNBcnJheSh0aGlzLnZhbHVlcykgJiYgdGhpcy52YWx1ZXMubGVuZ3RoICE9PSAwKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXN0cm95KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVzOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgZmlsZUF0dGFjaG1lbnQ6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlczsKICAgICAgICB9LAoKICAgICAgICBjb21tZW50IDogZnVuY3Rpb24odmFsdWUpewogICAgICAgICAgICB2YXIgX3NlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgJGVsZW0gPSBudWxsLAogICAgICAgICAgICAgICAgY29tbWVudHM7CiAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZCh2YWx1ZSkpIHsKICAgICAgICAgICAgICAgIGlmKHZhbHVlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBjb21tZW50cyA9IHZhbHVlLnNwbGl0KCJcbiIpOwogICAgICAgICAgICAgICAgICAgICRlbGVtID0gdGhpcy4kZWxlbWVudEZpbGVMaXN0LmZpbmQoJ2Rpdi5ndWlkZS1mdS1jb21tZW50Jyk7CiAgICAgICAgICAgICAgICAgICAgJGVsZW0uZWFjaChmdW5jdGlvbihpbmRleCl7CiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcykudGV4dChjb21tZW50c1tpbmRleF0pOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJGVsZW0gPSB0aGlzLiRlbGVtZW50RmlsZUxpc3QuZmluZCgnZGl2Lmd1aWRlLWZ1LWNvbW1lbnQnKTsKICAgICAgICAgICAgICAgIGNvbW1lbnRzID0gW107CiAgICAgICAgICAgICAgICAkZWxlbS5lYWNoKGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICAgICAgY29tbWVudHMucHVzaCgkKHRoaXMpLnRleHQoKSk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHJldHVybiBjb21tZW50czsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIG11bHRpU2VsZWN0IDogZnVuY3Rpb24odmFsdWUpewogICAgICAgICAgICBpZih2YWx1ZSAhPT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLm11bHRpU2VsZWN0ID0gdmFsdWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMubXVsdGlTZWxlY3Q7CiAgICAgICAgfSwKCiAgICAgICAgZmlsZVNpemVMaW1pdCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgaWYodmFsdWUgIT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5maWxlU2l6ZUxpbWl0ID0gdmFsdWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZmlsZVNpemVMaW1pdDsKICAgICAgICB9LAoKICAgICAgICBtaW1lVHlwZSA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgaWYodmFsdWUgIT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5taW1lVHlwZSA9IHZhbHVlOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLm1pbWVUeXBlOwogICAgICAgIH0sCgogICAgICAgIGFjY2VzcyA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgaWYodmFsdWUgPT0gInJlYWRPbmx5IikgewogICAgICAgICAgICAgICAgdGhpcy4kZWxlbWVudC5hdHRyKCJkaXNhYmxlZCIsICJkaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgLy9mb3IgcmVhZE9ubHkgaGlkZSB0aGUgZGVsZXRlIGljb24gaW4gZmlsZSBsaXN0CiAgICAgICAgICAgICAgICAkKHRoaXMuJHBhcmVudCkuYWRkQ2xhc3MoJ2d1aWRlLWZ1LWRpc2FibGVkJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZih2YWx1ZSA9PSAib3BlbiIpIHsKICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnQucmVtb3ZlQXR0cigiZGlzYWJsZWQiKTsKICAgICAgICAgICAgICAgICQodGhpcy4kcGFyZW50KS5yZW1vdmVDbGFzcygnZ3VpZGUtZnUtZGlzYWJsZWQnKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGZpbGVMaXN0IDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgdmFyIGZpbHRlcmVkLAogICAgICAgICAgICAgICAgX3NlbGYgPSB0aGlzOwogICAgICAgICAgICBpZih2YWx1ZSAhPT0gdW5kZWZpbmVkKXsKICAgICAgICAgICAgICAgIHRoaXMuJGZpbGVEb21FbGVtZW50cyA9IFtdOwogICAgICAgICAgICAgICAgXy5lYWNoKHZhbHVlLCBmdW5jdGlvbihpdGVtLCBpbmRleCl7CiAgICAgICAgICAgICAgICAgICAgaWYoKF8uaXNPYmplY3QoaXRlbSkgJiYgKGlzQnJvd3NlcklFOU9ySUUxMCB8fCBpdGVtLnZhbCgpLmxlbmd0aCA+IDApKSB8fCAoXy5pc1N0cmluZyhpdGVtKSkpewogICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgaW5kZXggaXMgd2l0aGluIHRoZSBsZW5ndGgKICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgd3JpdHRlbiBmb3IgZGVsZXRlIGNhc2UKICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIGl0ZW0gaXMgYSBzdHJpbmcsIHRoZW4gaXQgc2hvdWxkIGJlIHNldCBudWxsCiAgICAgICAgICAgICAgICAgICAgICAgICBpZihfLmlzU3RyaW5nKGl0ZW0pKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgIF9zZWxmLiRmaWxlRG9tRWxlbWVudHNbaW5kZXhdID0gaXRlbTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGZpbHRlcmVkID0gdGhpcy4kZmlsZURvbUVsZW1lbnRzOwogICAgICAgICAgICAgICAgLy8gSW4gY2FzZSBvZiBJRTksIGdldCB0aGUgbGFzdCBlbGVtZW50IG9mIGZpbGVEb20gYW5kIHVwZGF0ZSB0aGUgaWQgZm9yIGxhYmVsCiAgICAgICAgICAgICAgICBpZihpc0Jyb3dzZXJJRTlPcklFMTAgJiYgdmFsdWUgIT09IG51bGwpewogICAgICAgICAgICAgICAgICAgIC8vIENhc2U6IGlmIGl0IGlzIHNpbmdsZSBzZWxlY3QsIGFuZCB0aGVuIHdlIGRvIGEgcmVzdG9yZSBhbmQgdGhlbiBhZnRlciBhdHRhY2hpbmcgYW5vdGhlciBmaWxlIHdlIGNsaWNrIHNhdmUKICAgICAgICAgICAgICAgICAgICBpZihfLmxhc3QodGhpcy4kZmlsZURvbUVsZW1lbnRzKSA9PSBudWxsKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbG9uZUZpbGVJbnB1dEFuZFVwZGF0ZUlkRm9ySUU5KCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVMYWJlbEZvckF0dHIoXy5sYXN0KHRoaXMuJGZpbGVEb21FbGVtZW50cykuYXR0cigiaWQiKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgLy8gaGVyZSBmaWx0ZXJlZCBpcyBhIG5ldyBhcnJheQogICAgICAgICAgICAgICAgLy8gQSBuZXcgYXJyYXkgaXMgcmV0dXJuZWQgb3ZlciBoZXJlIHNvIHRoYXQgdGhlIHVzZXIgb2YgdGhpcyBBUEkgZG9lc24ndCB0cnkgdG8gY2hhbmdlIHRoZSB3aWRnZXQgYXJyYXkgZGlyZWN0bHkKICAgICAgICAgICAgICAgIGZpbHRlcmVkID0gJC5tYXAodGhpcy4kZmlsZURvbUVsZW1lbnRzLCBmdW5jdGlvbihpdGVtLCBpbmRleCl7CiAgICAgICAgICAgICAgICAgICAgaWYoIWl0ZW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9zZWxmLl9nZXRVcmwoaW5kZXgpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZigoaXRlbVswXS5maWxlcyAmJiBpdGVtWzBdLmZpbGVzLmxlbmd0aCAhPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IChfc2VsZi5vcHRpb25zLm11bHRpU2VsZWN0IHx8IGl0ZW1bMF0udmFsdWUubGVuZ3RoID4gMCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZpbHRlcmVkOwogICAgICAgIH0sCgogICAgICAgIC8vIGZpbGUgcHJldmlldyBodG1sCiAgICAgICAgZmlsZUl0ZW1QcmV2aWV3OiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gJCgiPHNwYW4+PC9zcGFuPiIpLmFkZENsYXNzKCJndWlkZS1mdS1maWxlUHJldmlldyBnbHlwaGljb24gZ2x5cGhpY29uLW9rIik7CiAgICAgICAgfSwKCiAgICAgICAgLy8gZm9yY2UgZmxhZyBpbmRpY2F0ZXMgdGhhdCBmb3JjZWZ1bGx5IHNldCB0aGUgZG9tIGJ1dCBkb24ndCB1cGRhdGUgdGhlIG9wdGlvbnMKICAgICAgICBidXR0b25UZXh0OiBmdW5jdGlvbiAodmFsdWUsIGZvcmNlKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICBpZighZm9yY2UpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLmJ1dHRvblRleHQgPSB2YWx1ZTsKICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRGaWxlVXBsb2FkQnRuLmZpbmQoJ3NwYW4uZ3VpZGUtZnUtbGFiZWwnKS5odG1sKHZhbHVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuYnV0dG9uVGV4dDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8vIFRvIGNoYW5nZSB0aGUgaWNvbiBvZiB0aGUgYnV0dG9uLCB0aGUgdXNlciBzaG91bGQgY3VzdG9taXplIHRoZSBjbGFzcwogICAgICAgIGJ0bkljb246IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICQoIjxzcGFuPjwvc3Bhbj4iKS5hZGRDbGFzcygiZ3VpZGUtZnUtaWNvbiBnbHlwaGljb24gZ2x5cGhpY29uLWZvbGRlci1vcGVuIik7CiAgICAgICAgfSwKCiAgICAgICAgYnRuTGFiZWw6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiAkKCI8c3Bhbj48L3NwYW4+IikuYWRkQ2xhc3MoImd1aWRlLWZ1LWxhYmVsIikuaHRtbCh0aGlzLm9wdGlvbnMuYnV0dG9uVGV4dCk7CiAgICAgICAgfSwKCiAgICAgICAgZmlsZUl0ZW1MaXN0OiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy4kcGFyZW50LmZpbmQodGhpcy5vcHRpb25zLmZpbGVJdGVtTGlzdENsYXNzKTsKICAgICAgICB9LAoKICAgICAgICBnZXROZXdDb21tZW50RWxlbWVudFN1bW1hcnkgOiBmdW5jdGlvbih0ZXh0KXsKICAgICAgICAgICAgcmV0dXJuICQoIjxkaXYgdGl0bGU9J0NsaWNrIHRvIGVkaXQnIHRhYmluZGV4PScwJz48L3A+IikuYWRkQ2xhc3MoImd1aWRlLWZ1LWNvbW1lbnQiKS50ZXh0KHRleHQgfHwgX2RlZmF1bHRzLnBsYWNlSG9sZGVyVGV4dCk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0TmV3Q29tbWVudEVsZW1lbnQgOiBmdW5jdGlvbih0ZXh0KXsKICAgICAgICAgICAgcmV0dXJuICQoIjxkaXYgY29udGVudGVkaXRhYmxlPSd0cnVlJyB0YWJpbmRleD0nMCc+PC9kaXY+IikuYWRkQ2xhc3MoImd1aWRlLWZ1LWNvbW1lbnQiKS50ZXh0KHRleHQgfHwgIiIpOwogICAgICAgIH0sCgogICAgICAgIGZpbGVJdGVtOiBmdW5jdGlvbihmaWxlTmFtZSwgY29tbWVudCwgZmlsZVVybCl7CiAgICAgICAgICAgIHZhciAkZmlsZUl0ZW0gPSAkKCI8bGk+PC9saT4iKS5hZGRDbGFzcygiZ3VpZGUtZnUtZmlsZUl0ZW0iKTsKICAgICAgICAgICAgdmFyIG5hbWVXaXRob3V0TWFya2VyID0geGZhbGliLnV0LlV0aWxpdGllcy5fZ2V0TmFtZVdpdGhvdXRNYXJrZXIoZmlsZU5hbWUpOwogICAgICAgICAgICB2YXIgJGVsZW0gPSAkKCI8c3BhbiB0YWJpbmRleD0nMCc+PC9zcGFuPiIpLmFkZENsYXNzKCJndWlkZS1mdS1maWxlTmFtZSIpLmF0dHIoImFyaWEtbGFiZWwiLCBuYW1lV2l0aG91dE1hcmtlcikudGV4dChuYW1lV2l0aG91dE1hcmtlcikuYXBwZW5kVG8oJGZpbGVJdGVtKS5rZXlwcmVzcyhmdW5jdGlvbihlKSB7CiAgICAgICAgICAgICAgICBpZiAoZS5rZXlDb2RlID09PSAxMyB8fCBlLmNoYXJDb2RlID09PSAzMikgewogICAgICAgICAgICAgICAgICAgICQoZS50YXJnZXQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pLmNsaWNrKCQucHJveHkodGhpcy5oYW5kbGVGaWxlUHJldmlldywgdGhpcykpOwogICAgICAgICAgICBpZih0aGlzLm9wdGlvbnMuZGlzYWJsZVByZXZpZXcpIHsKICAgICAgICAgICAgICAgJGVsZW0uYWRkQ2xhc3MoJ25vbi1wcmV2aWV3LWZpbGVOYW1lJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoZmlsZVVybCAhPSBudWxsKXsKICAgICAgICAgICAgICAgICRlbGVtLmF0dHIoImRhdGEta2V5IiwgZmlsZVVybCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJCgiPHNwYW4gdGFiaW5kZXg9JzAnPjwvc3Bhbj4iKS5hZGRDbGFzcygiZ3VpZGUtZnUtZmlsZUNsb3NlIGNsb3NlIikuYXR0cigicm9sZSIsICJidXR0b24iKS5hdHRyKCJhcmlhLWxhYmVsIiwgeGZhbGliLmxvY2FsZS5TdHJpbmdzLkZpbGVDbG9zZUFjY2Vzc1RleHQgKyBuYW1lV2l0aG91dE1hcmtlcikudGV4dCgieCIpLmFwcGVuZFRvKCRmaWxlSXRlbSkua2V5cHJlc3MoZnVuY3Rpb24oZSkgewogICAgICAgICAgICAgICAgaWYgKGUua2V5Q29kZSA9PT0gMTMgfHwgZS5jaGFyQ29kZSA9PT0gMzIpIHsKICAgICAgICAgICAgICAgICAgICAkKGUudGFyZ2V0KS5jbGljaygpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KQogICAgICAgICAgICAgICAgLmNsaWNrKCQucHJveHkodGhpcy5oYW5kbGVDbGljaywgdGhpcykpOwoKICAgICAgICAgICAgdGhpcy5maWxlSXRlbVByZXZpZXcoKS5hcHBlbmRUbygkZmlsZUl0ZW0pOwoKICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLnNob3dDb21tZW50KXsKICAgICAgICAgICAgICAgIHRoaXMuZ2V0TmV3Q29tbWVudEVsZW1lbnRTdW1tYXJ5KGNvbW1lbnQpLmFwcGVuZFRvKCRmaWxlSXRlbSkuZm9jdXMoJC5wcm94eSh0aGlzLmhhbmRsZUNvbW1lbnRDbGljaywgdGhpcykpLmNsaWNrKCQucHJveHkodGhpcy5oYW5kbGVDb21tZW50Q2xpY2ssIHRoaXMpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gJGZpbGVJdGVtOwogICAgICAgIH0sCgogICAgICAgIHRvZ2dsZUZpbGVVcGxvYWRCdG46IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5tdWx0aVNlbGVjdCkgewogICAgICAgICAgICAgICAgLy8gQ2hhbmdlIHRoZSBsb29rIG9mIGZpbGUgdXBsb2FkIGJ1dHRvbgogICAgICAgICAgICAgICAgaWYodGhpcy4kZWxlbWVudEZpbGVMaXN0LmNoaWxkcmVuKCkubGVuZ3RoID4gMCl7CiAgICAgICAgICAgICAgICAgICAgLy8gQ2hhbmdlIHRoZSB0ZXh0CiAgICAgICAgICAgICAgICAgICAgdGhpcy5idXR0b25UZXh0KHRoaXMuX2FkZEZpbGUsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIC8vIENoYW5nZSB0aGUgaWNvbiB0b28KICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbGVtZW50RmlsZVVwbG9hZEJ0bi5maW5kKCdzcGFuLmd1aWRlLWZ1LWljb24nKS5yZW1vdmVDbGFzcygiZ2x5cGhpY29uLWZvbGRlci1vcGVuIikuYWRkQ2xhc3MoImdseXBoaWNvbi1wbHVzIik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoaXMuYnV0dG9uVGV4dCh0aGlzLm9wdGlvbnMuYnV0dG9uVGV4dCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZWxlbWVudEZpbGVVcGxvYWRCdG4uZmluZCgnc3Bhbi5ndWlkZS1mdS1pY29uJykucmVtb3ZlQ2xhc3MoImdseXBoaWNvbi1wbHVzIikuYWRkQ2xhc3MoImdseXBoaWNvbi1mb2xkZXItb3BlbiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc2hvd0ludmFsaWRNZXNzYWdlOiBmdW5jdGlvbihmaWxlTmFtZSwgaW52YWxpZEZlYXR1cmUpewogICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgIHZhciBJU19JUEFEID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBhZC9pKSAhPT0gbnVsbCwKICAgICAgICAgICAgICAgIElTX0lQSE9ORSA9IChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmUvaSkgIT09IG51bGwpOwogICAgICAgICAgICBpZihJU19JUEFEIHx8IElTX0lQSE9ORSl7CiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICB0aGF0LmludmFsaWRNZXNzYWdlKHRoYXQsZmlsZU5hbWUsIGludmFsaWRGZWF0dXJlKTsKICAgICAgICAgICAgICAgIH0sIDApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICB0aGlzLmludmFsaWRNZXNzYWdlKHRoaXMsZmlsZU5hbWUsIGludmFsaWRGZWF0dXJlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGludmFsaWRNZXNzYWdlOiBmdW5jdGlvbihyZWZPYmosZmlsZU5hbWUsIGludmFsaWRGZWF0dXJlKXsKICAgICAgICAgICAgaWYoaW52YWxpZEZlYXR1cmUgPT09IHJlZk9iai5pbnZhbGlkRmVhdHVyZS5TSVpFKSB7CiAgICAgICAgICAgICAgICBhbGVydCh4ZmFsaWIudXQuTG9jYWxpemF0aW9uVXRpbC5wcm90b3R5cGUuZ2V0TG9jYWxpemVkTWVzc2FnZSgiIiwgeGZhbGliLmxvY2FsZS5TdHJpbmdzWyJGaWxlU2l6ZUdyZWF0ZXIiXSwgW2ZpbGVOYW1lLCByZWZPYmoub3B0aW9ucy5maWxlU2l6ZUxpbWl0XSkpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGludmFsaWRGZWF0dXJlID09PSByZWZPYmouaW52YWxpZEZlYXR1cmUuTkFNRSkgewogICAgICAgICAgICAgICAgYWxlcnQoeGZhbGliLnV0LkxvY2FsaXphdGlvblV0aWwucHJvdG90eXBlLmdldExvY2FsaXplZE1lc3NhZ2UoIiIsIHhmYWxpYi5sb2NhbGUuU3RyaW5nc1siRmlsZU5hbWVJbnZhbGlkIl0sIFtmaWxlTmFtZV0pKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChpbnZhbGlkRmVhdHVyZSA9PT0gcmVmT2JqLmludmFsaWRGZWF0dXJlLk1JTUVUWVBFKSB7CiAgICAgICAgICAgICAgICBhbGVydCh4ZmFsaWIudXQuTG9jYWxpemF0aW9uVXRpbC5wcm90b3R5cGUuZ2V0TG9jYWxpemVkTWVzc2FnZSgiIiwgeGZhbGliLmxvY2FsZS5TdHJpbmdzWyJGaWxlTWltZVR5cGVJbnZhbGlkIl0sIFtmaWxlTmFtZV0pKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKioKICAgICAgICAgKiBGaW5kcyB0aGUgdmFsdWUgaW4gdGhlIGFycmF5LCBpZiB0aGUgdmFsdWUgaXMgYSB1cmwgdGhlbiBpdCB1c2VzIHRoZSBmaWxlbmFtZSBpbiB0aGUgdXJsIHRvIHNlYXJjaCBmb3IgdGhlIHRleHQKICAgICAgICAgKiBUaGlzIGlzIGRvbmUgc2luY2Ugb3VyIG1vZGVsIHN0b3JlcyB0aGUgVVJMIHRvbyBpbiBjYXNlIG9mIGRyYWZ0IHJlc3RvcmUgb3IgY2xpY2tpbmcgb24gc2F2ZSBpbiBndWlkZQogICAgICAgICAqIEBwYXJhbSB0ZXh0ICAgICAgICAgIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHRleHQgb2Ygd2hpY2ggdGhlIGluZGV4IGlzIHRvIGJlIGZvdW5kCiAgICAgICAgICogQHBhcmFtICRlbGVtICAgICAgICAgcmVmZXJlbmNlIHRvIHRoZSBqcXVlcnkgZWxlbWVudC4gVGhpcyBpcyB1c2VkIGlmIHRoZXJlIGFyZSBkdXBsaWNhdGUgZmlsZSBuYW1lcyBwcmVzZW50IGluIHRoZSBmaWxlIHVwbG9hZC4KICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfQogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2dldEluZGV4T2ZUZXh0IDogZnVuY3Rpb24odGV4dCwgJGVsZW0pewogICAgICAgICAgICB2YXIgaW5kZXggPSAtMSwKICAgICAgICAgICAgICAgIHNlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgaXNEdXBsaWNhdGVQcmVzZW50ID0gZmFsc2U7CiAgICAgICAgICAgIF8uZmluZCh0aGlzLnZhbHVlcywgZnVuY3Rpb24odmFsdWUsIGl0ZXIpewogICAgICAgICAgICAgICAgLy8gaWYgdmFsdWUgaXMgYSB1cmwsIHRoZW4gY29tcGFyZSB3aXRoIGxhc3QKICAgICAgICAgICAgICAgIHZhciB0ZW1wVmFsdWUgPSB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAvLyBjYW4ndCB1c2UgZ2V0T3JFbHNlIGhlcmUgc2luY2UgdmFsdWUgY2FuIGhhdmUgIi4iIGluIFVSTCBhbmQgZ2V0T3JFbHNlIHNwbGl0cyBiYXNlZCBvbiBwZXJpb2QgdG8gZmluZCBrZXkgaW5zaWRlIG9iamVjdAogICAgICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gIChfLmlzT2JqZWN0KHNlbGYuX2luaXRpYWxGaWxlVmFsdWVGaWxlTmFtZU1hcCkgJiYgdHlwZW9mIHNlbGYuX2luaXRpYWxGaWxlVmFsdWVGaWxlTmFtZU1hcFt2YWx1ZV0gIT09IHVuZGVmaW5lZCkgPyBzZWxmLl9pbml0aWFsRmlsZVZhbHVlRmlsZU5hbWVNYXBbdmFsdWVdIDogbnVsbDsKICAgICAgICAgICAgICAgIGlmKHRlbXBWYWx1ZS5tYXRjaCgvXC8vZykgJiYgdGVtcFZhbHVlLm1hdGNoKC9cLy9nKS5sZW5ndGggPiAxKXsKICAgICAgICAgICAgICAgICAgICB0ZW1wVmFsdWUgPSAgdmFsdWUuc3Vic3RyaW5nKHZhbHVlLmxhc3RJbmRleE9mKCIvIikrMSk7CiAgICAgICAgICAgICAgICAgICAgdGVtcFZhbHVlID0geGZhbGliLnV0LlV0aWxpdGllcy5fZ2V0TmFtZVdpdGhvdXRNYXJrZXIodGVtcFZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIHdlIHBhc3MgZmlsZSBuYW1lIGV4cGxpY2l0eWx5IGFzIG9wdGlvbnMsIGlmIHBhc3NlZCB1c2UgdGhhdCBhcyBmYWxsYmFjayB0byBmaW5kIHRoZSBVUkwKICAgICAgICAgICAgICAgIGlmKHRlbXBWYWx1ZSA9PT0gdGV4dCB8fCBmaWxlTmFtZSA9PT0gdGV4dCl7CiAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBpdGVyOwogICAgICAgICAgICAgICAgICAgIGlzRHVwbGljYXRlUHJlc2VudCA9IHNlbGYudmFsdWVzLmluZGV4T2YodmFsdWUsIGluZGV4ICsgMSkgIT09IC0xOwogICAgICAgICAgICAgICAgICAgIGlmKCRlbGVtICYmIGlzRHVwbGljYXRlUHJlc2VudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdyBjaGVjayBpZiBkdXBsaWNhdGUgcHJlc2VudCBhbmQgZ2V0IGl0cyBjb3JyZWN0IGluZGV4CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRvZGF5IGFsbCBmaWxlcyBhcmUgd3JhcHBlZCB1bmRlciAuZ3VpZGUtZnUtZmlsZUl0ZW0gbm9kZQogICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9ICRlbGVtLmNsb3Nlc3QoIi5ndWlkZS1mdS1maWxlSXRlbSIpLmluZGV4KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIHRoZXJlIGlzIGEgZHVwbGljYXRlCiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBqdXN0IGJyZWFrIHRoZSBsb29wCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgcmV0dXJuIGluZGV4OwogICAgICAgIH0sCgoKICAgICAgICAvKgogICAgICAgICAqIFNpbmNlIGlucHV0IGZpbGUgZWxlbWVudCBtaWdodCBjb250YWluIG11bHRpcGxlIGZpbGVzLgogICAgICAgICAqIFRoaXMgZnVuY3Rpb24gdGFrZXMgYWJzb2x1dGUgZmlsZSBpbmRleCBhcyBwYXJhbWV0ZXIgJiByZXR1cm5zIHBvc2l0aW9uIG9mIHRoZSBmaWxlIHcuci50IGlucHV0IGZpbGUgZWx0CiAgICAgICAgICovCiAgICAgICAgX2dldEZpbGVPYmpJZHggOiBmdW5jdGlvbiAoaW5kZXgpIHsKICAgICAgICAgICAgaWYgKGluZGV4ID49IDApIHsKICAgICAgICAgICAgICAgIHZhciBjdXJyZW50SWR4ID0gMDsKICAgICAgICAgICAgICAgIGZvciAodmFyIGZpbGVJbnB1dEVsdElkeCA9IDA7IGZpbGVJbnB1dEVsdElkeCA8IHRoaXMuJGZpbGVEb21FbGVtZW50cy5sZW5ndGg7IGZpbGVJbnB1dEVsdElkeCsrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuJGZpbGVEb21FbGVtZW50c1tmaWxlSW5wdXRFbHRJZHhdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmaWxlcyA9IHRoaXMuJGZpbGVEb21FbGVtZW50c1tmaWxlSW5wdXRFbHRJZHhdWzBdLmZpbGVzOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmaWxlc0xlbmd0aCA9ICBmaWxlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGluZGV4IDw9IGN1cnJlbnRJZHggKyBmaWxlc0xlbmd0aCAtIDEgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtmaWxlSW5wdXRFbHRJZHgsIGluZGV4IC0gY3VycmVudElkeF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50SWR4Kz1maWxlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT0gY3VycmVudElkeCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtmaWxlSW5wdXRFbHRJZHgsMF07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudElkeCsrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBGaWxlTGlzdCBvYmplY3Qgb2YgdGhlIHBhc3NlZCBmaWxlIGFycmF5CiAgICAgICAgICovCiAgICAgICAgX2dldEZpbGVMaXN0SXRlbSA6IGZ1bmN0aW9uIChmaWxlcykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdmFyIGRhdGFDb250YWluZXIgPSBuZXcgRGF0YVRyYW5zZmVyKCkgfHwgKG5ldyBDbGlwYm9hcmRFdmVudCgiIikpLmNsaXBib2FyZERhdGE7CiAgICAgICAgICAgICAgICBfLmVhY2goZmlsZXMsIGZ1bmN0aW9uIChmaWxlKSB7CiAgICAgICAgICAgICAgICAgICAgZGF0YUNvbnRhaW5lci5pdGVtcy5hZGQoZmlsZSk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHJldHVybiBkYXRhQ29udGFpbmVyLmZpbGVzOwogICAgICAgICAgICB9IGNhdGNoKGVycikgewogICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpOwogICAgICAgICAgICAgICAgdGhyb3cgZXJyOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX3VwZGF0ZUZpbGVzSW5Eb20gOiBmdW5jdGlvbigkZmlsZURvbSwgZmlsZXMpIHsKICAgICAgICAgICAgLy8gaW4gc2FmYXJpLCBhIGNoYW5nZSBldmVudCBpcyB0cmlnZ2VkIGlmIGZpbGVzIHByb3BlcnR5IGlzIGNoYW5nZWQgZHluYW1pY2FsbHkKICAgICAgICAgICAgLy8gaGVuY2UgYWRkaW5nIHRoaXMgY2hlY2sgdG8gY2xlYXIgZXhpc3Rpbmcgc3RhdGUgb25seSBmb3Igc2FmYXJpIGJyb3dzZXJzCiAgICAgICAgICAgIHRoaXMuX2lzRmlsZVVwZGF0ZSA9IHRydWU7CiAgICAgICAgICAgICRmaWxlRG9tWzBdLmZpbGVzID0gdGhpcy5fZ2V0RmlsZUxpc3RJdGVtKGZpbGVzKTsKICAgICAgICAgICAgdGhpcy5faXNGaWxlVXBkYXRlID0gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBUaGlzIGZ1bmN0aW9uIGRlbGV0ZXMgZmlsZXMgYXQgc3BlY2lmaWVkIGluZGV4ZXMgZnJvbSBpbnB1dCBkb20gZWx0CiAgICAgICAgICovCiAgICAgICAgX2RlbGV0ZUZpbGVzRnJvbUlucHV0RG9tIDogZnVuY3Rpb24gKCRmaWxlRG9tRWx0LCBkZWxldGVkSW5kZXhlcykgewogICAgICAgICAgICB2YXIgcmVtYWluaW5nRmlsZXMgPSBbXTsKICAgICAgICAgICAgXy5lYWNoKCRmaWxlRG9tRWx0WzBdLmZpbGVzLCBmdW5jdGlvbihmaWxlLGlkeCl7CiAgICAgICAgICAgICAgICBpZighZGVsZXRlZEluZGV4ZXMuaW5jbHVkZXMoaWR4KSl7CiAgICAgICAgICAgICAgICAgICAgcmVtYWluaW5nRmlsZXMucHVzaChmaWxlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAvLyBpbiBzYWZhcmksIGEgY2hhbmdlIGV2ZW50IGlzIHRyaWdnZWQgaWYgZmlsZXMgcHJvcGVydHkgaXMgY2hhbmdlZCBkeW5hbWljYWxseQogICAgICAgICAgICAgICAgLy8gaGVuY2UgYWRkaW5nIHRoaXMgY2hlY2sgdG8gY2xlYXIgZXhpc3Rpbmcgc3RhdGUgb25seSBmb3Igc2FmYXJpIGJyb3dzZXJzCiAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVGaWxlc0luRG9tKCRmaWxlRG9tRWx0LCByZW1haW5pbmdGaWxlcyk7CiAgICAgICAgICAgIH0gY2F0Y2goZXJyKXsKICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoIkRlbGV0aW5nIGZpbGVzIGlzIG5vdCBzdXBwb3J0ZWQgaW4geW91ciBicm93c2VyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIGV2ZW50IGxpc3RlbmVyIGdldHMgY2FsbGVkIG9uIGNsaWNrIG9mIGNsb3NlIGJ1dHRvbiBpbiBmaWxlIHVwbG9hZAogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGV2ZW50CiAgICAgICAgICovCiAgICAgICAgaGFuZGxlQ2xpY2s6IGZ1bmN0aW9uKGV2ZW50KXsKCiAgICAgICAgICAgIHZhciAkZWxlbSA9ICQoZXZlbnQudGFyZ2V0KSwKICAgICAgICAgICAgICAgIHRleHQgPSAkZWxlbS5wcmV2KCkudGV4dCgpLAogICAgICAgICAgICAgICAgaW5kZXggPSB0aGlzLl9nZXRJbmRleE9mVGV4dCh0ZXh0LCAkZWxlbSksCiAgICAgICAgICAgICAgICB1cmwgPSAkZWxlbS5wcmV2KCkuZGF0YSgia2V5IiksCiAgICAgICAgICAgICAgICBvYmplY3RVcmwgPSAkZWxlbS5wcmV2KCkuZGF0YSgib2JqZWN0VXJsIik7CiAgICAgICAgICAgIGlmIChpbmRleCAhPSAtMSkgewogICAgICAgICAgICAgICAgdGhpcy52YWx1ZXMuc3BsaWNlKGluZGV4LCAxKTsKICAgICAgICAgICAgICAgIHZhciBmaWxlT2JqSWR4ID0gdGhpcy5fZ2V0RmlsZU9iaklkeChpbmRleCk7CiAgICAgICAgICAgICAgICB2YXIgJGZpbGVEb21FbHQgPSB0aGlzLiRmaWxlRG9tRWxlbWVudHNbZmlsZU9iaklkeFswXV07CiAgICAgICAgICAgICAgICBpZiAoISRmaWxlRG9tRWx0IHx8ICRmaWxlRG9tRWx0WzBdLmZpbGVzLmxlbmd0aCA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGZpbGVEb21FbGVtZW50cy5zcGxpY2UoZmlsZU9iaklkeFswXSwgMSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX2RlbGV0ZUZpbGVzRnJvbUlucHV0RG9tKCRmaWxlRG9tRWx0LCBbZmlsZU9iaklkeFsxXV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGlzQnJvd3NlcklFOU9ySUUxMCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuY2xvbmVGaWxlSW5wdXRBbmRVcGRhdGVJZEZvcklFOSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHVybCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBkYXRhIHNvIHRoYXQgb3RoZXJzIGRvbid0IHVzZSB0aGlzIHVybAogICAgICAgICAgICAgICAgICAgICRlbGVtLnByZXYoKS5yZW1vdmVEYXRhKCJrZXkiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKG9iamVjdFVybCkgewogICAgICAgICAgICAgICAgICAgIC8vIHJldm9rZSB0aGUgb2JqZWN0IFVSTCB0byBhdm9pZCBtZW1vcnkgbGVha3MgaW4gYnJvd3NlcgogICAgICAgICAgICAgICAgICAgIC8vIHNpbmNlIGZpbGUgaXMgYW55d2F5cyBnZXR0aW5nIGRlbGV0ZWQsIHJlbW92ZSB0aGUgb2JqZWN0IFVSTCdzIHRvbwogICAgICAgICAgICAgICAgICAgIHdpbmRvdy5VUkwucmV2b2tlT2JqZWN0VVJMKG9iamVjdFVybCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBkb20gZnJvbSB2aWV3CiAgICAgICAgICAgIC8vQWxsIGJvdW5kIGV2ZW50cyBhbmQgalF1ZXJ5IGRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSBlbGVtZW50IGFyZSBhbHNvIHJlbW92ZWQKICAgICAgICAgICAgJGVsZW0ucGFyZW50KCkucmVtb3ZlKCk7CiAgICAgICAgICAgIC8vIHRyaWdnZXIgdGhlIGNoYW5nZSBldmVudCB0byB1cGRhdGUgdGhlIHZhbHVlCiAgICAgICAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcigiY2hhbmdlLmZpbGV1cGxvYWQiKTsKICAgICAgICAgICAgLy8gU2V0IHRoZSBmb2N1cyBvbiBmaWxlIHVwbG9hZCBidXR0b24gYWZ0ZXIgY2xpY2sgb2YgY2xvc2UKICAgICAgICAgICAgdGhpcy4kZWxlbWVudEZpbGVVcGxvYWRCdG4uZm9jdXMoKTsKCiAgICAgICAgfSwKCgogICAgICAgIGRpc3BsYXlTVkcob2JqZWN0VXJsKSB7CiAgICAgICAgICAgIGNvbnN0IHVybCA9IG9iamVjdFVybDsKICAgICAgICAgICAgY29uc3QgaW1nID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpOwogICAgICAgICAgICBpbWcuc3JjID0gdXJsOwogICAgICAgICAgICBjb25zdCBuZXdUYWIgPSB3aW5kb3cub3BlbignJywgJ19ibGFuaycsICdzY3JvbGxiYXJzPW5vLG1lbnViYXI9bm8saGVpZ2h0PTYwMCx3aWR0aD04MDAscmVzaXphYmxlPXllcyx0b29sYmFyPW5vLHN0YXR1cz1ubycpOwogICAgICAgICAgICBuZXdUYWIuZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChpbWcpOwogICAgICAgIH0sCgoKICAgICAgICBfcHJldmlld0ZpbGVVc2luZ09iamVjdFVybCA6IGZ1bmN0aW9uIChmaWxlKSB7CiAgICAgICAgICAgIGlmIChmaWxlKSB7CiAgICAgICAgICAgICAgICBpZiAod2luZG93Lm5hdmlnYXRvciAmJiB3aW5kb3cubmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IpIHsgLy8gZm9yIElFCiAgICAgICAgICAgICAgICAgICAgd2luZG93Lm5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iKGZpbGUsIGZpbGUubmFtZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHZhciB1cmwgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChmaWxlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZS50eXBlID09PSAnaW1hZ2Uvc3ZnK3htbCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5U1ZHKHVybCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93Lm9wZW4odXJsLCAnJywgJ3Njcm9sbGJhcnM9bm8sbWVudWJhcj1ubyxoZWlnaHQ9NjAwLHdpZHRoPTgwMCxyZXNpemFibGU9eWVzLHRvb2xiYXI9bm8sc3RhdHVzPW5vJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiB1cmw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvLyB0aGlzIGZ1bmN0aW9uIG1haW50YWlucyBhIG1hcCBmb3IKICAgICAgICBoYW5kbGVGaWxlUHJldmlldzogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICBpZighdGhpcy5vcHRpb25zLmRpc2FibGVQcmV2aWV3KSB7CiAgICAgICAgICAgICAgICB2YXIgJGVsZW0gPSAkKGV2ZW50LnRhcmdldCksCiAgICAgICAgICAgICAgICAgICAgdGV4dCA9ICRlbGVtLnRleHQoKSwKICAgICAgICAgICAgICAgICAgICBpbmRleCA9IHRoaXMuX2dldEluZGV4T2ZUZXh0KHRleHQsICRlbGVtKSwKICAgICAgICAgICAgICAgICAgICBmaWxlRG9tID0gbnVsbCwKICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZSA9IG51bGwsCiAgICAgICAgICAgICAgICAgICAgZmlsZVVybCA9IG51bGwsCiAgICAgICAgICAgICAgICAgICAgdGltZVN0YW1wID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7CgogICAgICAgICAgICAgICAgLy8gZm9yIGRyYWZ0IHVzZWNhc2UsIGlmIHRleHQgY29udGFpbnMgIi8iIGluIGl0LCBpdCBtZWFucyB0aGUgZmlsZSBpcyBhbHJlYWR5IHVwbG9hZGVkCiAgICAgICAgICAgICAgICAvLyB0ZXh0IHNob3VsZCBjb250YWluIHRoZSBwYXRoLCBhc3N1bWluZyB0aGF0IHRoZSBmaWxlVXJsIGlzIHN0b3JlZCBpbiBkYXRhIGVsZW1lbnQKCiAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAvLyBTdG9yZSB0aGUgdXJsIG9mIGZpbGUgYXMgZGF0YQogICAgICAgICAgICAgICAgICAgIGlmKCFfLmlzVW5kZWZpbmVkKCRlbGVtLmRhdGEoImtleSIpKSkKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVVybCA9ICRlbGVtLmRhdGEoImtleSIpOwoKICAgICAgICAgICAgICAgICAgICBpZihmaWxlVXJsKSAgewogICAgICAgICAgICAgICAgICAgICAgICAvL3ByZXBlbmQgY29udGV4dCBwYXRoIGlmIG5vdCBhbHJlYWR5IGFwcGVuZGVkCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKGZpbGVVcmwubGFzdEluZGV4T2YodGhpcy5vcHRpb25zLl9nZXRVcmwsIDApID09PSAwKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVVybCA9ICB0aGlzLm9wdGlvbnMuX2dldFVybCArIGZpbGVVcmw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aWV3RmlsZS5hcHBseSh0aGlzLCBbbnVsbCwgeyJmaWxlVXJsIiA6IGZpbGVVcmx9XSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHByZXZpZXdGaWxlT2JqSWR4ID0gdGhpcy5fZ2V0RmlsZU9iaklkeChpbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcmV2aWV3RmlsZSA9IHRoaXMuJGZpbGVEb21FbGVtZW50c1twcmV2aWV3RmlsZU9iaklkeFswXV1bMF0uZmlsZXNbcHJldmlld0ZpbGVPYmpJZHhbMV1dOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2JqZWN0VXJsID0gdGhpcy5fcHJldmlld0ZpbGVVc2luZ09iamVjdFVybChwcmV2aWV3RmlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvYmplY3RVcmwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRlbGVtLmRhdGEoIm9iamVjdFVybCIsIG9iamVjdFVybCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBwcmV2aWV3RmlsZTogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICB2YXIgdXJsID0gbnVsbDsKICAgICAgICAgICAgaWYoXy5pc1VuZGVmaW5lZChhcmd1bWVudHNbMV0pKQogICAgICAgICAgICAgICAgdXJsID0gdGhpcy4kZWxlbWVudFt0aGlzLm9wdGlvbnMudXBsb2FkZXJQbHVnaW5OYW1lXSgiZ2V0RmlsZVVybCIpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB1cmwgPSBhcmd1bWVudHNbMV0uZmlsZVVybDsKICAgICAgICAgICAgdmFyIGxhc3RJbmRleCA9IHVybC5sYXN0SW5kZXhPZignLycpOwogICAgICAgICAgICAvL3RvIG1ha2Ugc3VyZSB1cmwgaGFzIGEgc2xhc2ggJy8nCiAgICAgICAgICAgIGlmKGxhc3RJbmRleCA+PSAwKSB7CiAgICAgICAgICAgICAgICAvL2VuY29kZSB0aGUgZmlsZW5hbWUgYWZ0ZXIgbGFzdCBzbGFzaCB0byBlbnN1cmUgdGhlIGhhbmRsaW5nIG9mIHNwZWNpYWwgY2hhcmFjdGVycwogICAgICAgICAgICAgICAgdXJsID0gdXJsLnN1YnN0cigwLCBsYXN0SW5kZXgpICsnLycrIGVuY29kZVVSSUNvbXBvbmVudCh1cmwuc3Vic3RyKGxhc3RJbmRleCArIDEpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyB0aGlzIHdvdWxkIHdvcmsgZm9yIGRhdGFVUmwgb3Igbm9ybWFsIFVSTAogICAgICAgICAgICAvLyB0b2RvOiBhZGQgc3VwcG9ydCB0byBwcmV2aWV3IGJhc2UgNjQgZW5jb2RlZCBpbWFnZSwgdG8gcHJldmlldyBiYXNlNjQgZW5jb2RlZCBiaW5hcnksIHdlIHdvdWxkIHByb2JhYmx5IG5lZWQKICAgICAgICAgICAgLy8gdG9kbzogdGhlIGNvbnRlbnQgdHlwZSBpbiB0aGUgd2lkZ2V0IHRvbwogICAgICAgICAgICB3aW5kb3cub3Blbih1cmwsICcnLCAnc2Nyb2xsYmFycz1ubyxtZW51YmFyPW5vLGhlaWdodD02MDAsd2lkdGg9ODAwLHJlc2l6YWJsZT15ZXMsdG9vbGJhcj1ubyxzdGF0dXM9bm8nKTsKCiAgICAgICAgfSwKCiAgICAgICAgcmVzZXRJZk5vdE11bHRpU2VsZWN0OiBmdW5jdGlvbigpewogICAgICAgICAgICBpZighdGhpcy5vcHRpb25zLm11bHRpU2VsZWN0KXsKICAgICAgICAgICAgICAgIC8vIFJlc2V0IHRoZSB2YWx1ZSBhbmQgZmlsZSBhcnJheQogICAgICAgICAgICAgICAgdGhpcy52YWx1ZXMgPSBbXTsKICAgICAgICAgICAgICAgIC8vdGhpcy5jb21tZW50cyA9IFtdOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc2hvd0ZpbGVMaXN0OiBmdW5jdGlvbihmaWxlTmFtZSwgY29tbWVudCwgZmlsZVVybCl7CiAgICAgICAgICAgIGlmKCF0aGlzLm9wdGlvbnMubXVsdGlTZWxlY3QgfHwgZmlsZU5hbWUgPT0gbnVsbCB8fCBfLmlzVW5kZWZpbmVkKGZpbGVOYW1lKSkgewogICAgICAgICAgICAgICAgLy8gaWYgbm90IG11bHRpc2VsZWN0LCByZW1vdmUgYWxsIHRoZSBjaGlsZHJlbiBvZiBmaWxlIGxpc3QKICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRGaWxlTGlzdC5lbXB0eSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBBZGQgdGhlIGZpbGUgaXRlbQogICAgICAgICAgICAvLyBPbiBjbGljayBvZiBjbG9zZSwgcmVtb3ZlIHRoZSBlbGVtZW50IGFuZCB1cGRhdGUgdGhlIG1vZGVsCiAgICAgICAgICAgIC8vIGhhbmRsZSBvbiBjbGljayBvZiBwcmV2aWV3IGJ1dHRvbgogICAgICAgICAgICBpZihmaWxlTmFtZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICB0aGlzLiRmaWxlSXRlbSA9IHRoaXMuJGVsZW1lbnRGaWxlTGlzdC5hcHBlbmQodGhpcy5maWxlSXRlbShmaWxlTmFtZSwgY29tbWVudCwgZmlsZVVybCkpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogSGFuZGxlcyB0aGUgY2xpY2sgb24gY29tbWVudCBmaWVsZAogICAgICAgICAqCiAgICAgICAgICogVE9ETzogSW1wbGVtZW50IHNob3cvaGlkZSBiZWhhdmlvdXIgaW5zdGVhZCBvZiByZXBsYWNlV2l0aAogICAgICAgICAqIFRoaXMgbWF5IGJlIGNhdXNlIHByb2JsZW0gZHVyaW5nIGJ1YmJsZSB1cCBvZiBldmVudAogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGV2ZW50CiAgICAgICAgICovCiAgICAgICAgaGFuZGxlQ29tbWVudENsaWNrIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICB2YXIgJGNvbW1lbnRFbGVtID0gbnVsbCwKICAgICAgICAgICAgICAgICRlbGVtID0gJChldmVudC50YXJnZXQpOwogICAgICAgICAgICBpZiAoJGVsZW0udGV4dCgpID09PSBfZGVmYXVsdHMucGxhY2VIb2xkZXJUZXh0KSB7CiAgICAgICAgICAgICAgICAkY29tbWVudEVsZW0gPSB0aGlzLmdldE5ld0NvbW1lbnRFbGVtZW50KCkKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRjb21tZW50RWxlbSA9IHRoaXMuZ2V0TmV3Q29tbWVudEVsZW1lbnQoJChldmVudC50YXJnZXQpLnRleHQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGVsZW0ucmVwbGFjZVdpdGgoJGNvbW1lbnRFbGVtKTsKICAgICAgICAgICAgLy8gcmVnaXN0ZXIgdGhlIGV2ZW50IGFnYWluCiAgICAgICAgICAgIGlmKGlzQnJvd3NlcklFOU9ySUUxMCl7CiAgICAgICAgICAgICAgICAkY29tbWVudEVsZW0uZm9jdXMoKS5mb2N1c291dCgkLnByb3h5KHRoaXMuaGFuZGxlQ29tbWVudEJsdXIsIHRoaXMpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICRjb21tZW50RWxlbS5mb2N1cygpLmJsdXIoJC5wcm94eSh0aGlzLmhhbmRsZUNvbW1lbnRCbHVyLCB0aGlzKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYW5kbGVDb21tZW50Qmx1ciA6IGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgdmFyICRjb21tZW50U3VtbWFyeUVsZW0gPSBudWxsLAogICAgICAgICAgICAgICAgJGVsZW0gPSAkKGV2ZW50LnRhcmdldCk7CiAgICAgICAgICAgIGlmICgkZWxlbS50ZXh0KCkgPT09IF9kZWZhdWx0cy5wbGFjZUhvbGRlclRleHQpIHsKICAgICAgICAgICAgICAgICRjb21tZW50U3VtbWFyeUVsZW0gPSB0aGlzLmdldE5ld0NvbW1lbnRFbGVtZW50U3VtbWFyeSgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGNvbW1lbnRTdW1tYXJ5RWxlbSA9IHRoaXMuZ2V0TmV3Q29tbWVudEVsZW1lbnRTdW1tYXJ5KCQoZXZlbnQudGFyZ2V0KS50ZXh0KCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRlbGVtLnJlcGxhY2VXaXRoKCRjb21tZW50U3VtbWFyeUVsZW0pOwogICAgICAgICAgICAkY29tbWVudFN1bW1hcnlFbGVtLmZvY3VzKCQucHJveHkodGhpcy5oYW5kbGVDb21tZW50Q2xpY2ssdGhpcykpLmNsaWNrKCQucHJveHkodGhpcy5oYW5kbGVDb21tZW50Q2xpY2ssdGhpcykpOwogICAgICAgICAgICAvLyBBZGQgYSBkaXYgd2l0aCB0aGUgaHRtbAogICAgICAgICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoImNoYW5nZS5maWxldXBsb2FkIik7CiAgICAgICAgfSwKCiAgICAgICAgLy8gY2hlY2tzIGlmIGZpbGUgbmFtZSBpcyB2YWxpZCBvciBub3QgdG8gcHJldmVudCBzZWN1cml0eSB0aHJlYXRzCiAgICAgICAgaXNWYWxpZCA6IGZ1bmN0aW9uKGZuYW1lKSB7CiAgICAgICAgICAgIHZhciByZzE9L15bXlxcLzpcKlw7XCRcJVw/Ijw+XHxdKyQvOyAvLyBmb3JiaWRkZW4gY2hhcmFjdGVycyBcIC8gOiAqID8gIiA8ID4gfCA7ICUgJAogICAgICAgICAgICB2YXIgcmcyPS9eXC4vOyAvLyBjYW5ub3Qgc3RhcnQgd2l0aCBkb3QgKC4pCiAgICAgICAgICAgIHZhciByZzM9L14obnVsfHBybnxjb258bHB0WzAtOV18Y29tWzAtOV0pKFwufCQpL2k7IC8vIGZvcmJpZGRlbiBmaWxlIG5hbWVzCiAgICAgICAgICAgIHJldHVybiByZzEudGVzdChmbmFtZSkgJiYgIXJnMi50ZXN0KGZuYW1lKSAmJiAhcmczLnRlc3QoZm5hbWUpOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUNoYW5nZTogZnVuY3Rpb24gKGV2bnQpIHsKICAgICAgICAgICAgaWYgKCF0aGlzLl9pc0ZpbGVVcGRhdGUpIHsKICAgICAgICAgICAgICAgIHZhciBjdXJyRmlsZU5hbWUgPSAnJywKICAgICAgICAgICAgICAgICAgICBpblZhbGlkU2l6ZWZpbGVOYW1lcyA9ICcnLAogICAgICAgICAgICAgICAgICAgIGluVmFsaWROYW1lZmlsZU5hbWVzID0gJycsCiAgICAgICAgICAgICAgICAgICAgaW5WYWxpZE1pbWVUeXBlZmlsZU5hbWVzID0gJycsCiAgICAgICAgICAgICAgICAgICAgJGVsZW0gPSAkKGV2bnQudGFyZ2V0KSwKICAgICAgICAgICAgICAgICAgICBmaWxlcyA9ICRlbGVtWzBdLmZpbGVzOwogICAgICAgICAgICAgICAgLy8gSW5pdGlhbGx5IHNldCB0aGUgaW52YWxpZCBmbGFnIHRvIGZhbHNlCiAgICAgICAgICAgICAgICAvLyBpZiBub3QgbXVsdGlzZWxlY3QgdGhlbiByZW1vdmUgdGhlIGV4dHJhIGRvbUVMZW1lbnQgY2xvbmUKICAgICAgICAgICAgICAgIGlmICghdGhpcy5vcHRpb25zLm11bHRpU2VsZWN0ICYmIHRoaXMuJGZpbGVEb21FbGVtZW50cy5sZW5ndGggPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZmlsZURvbUVsZW1lbnRzLnNwbGljZSgwLCAxKQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBpc0ludmFsaWRTaXplID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgaXNJbnZhbGlkRmlsZU5hbWUgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBpc0ludmFsaWRNaW1lVHlwZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgdGhpcy5yZXNldElmTm90TXVsdGlTZWxlY3QoKTsKICAgICAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBhbGwgdGhlIGZpbGVzCiAgICAgICAgICAgICAgICBpZiAoaXNCcm93c2VySUU5T3JJRTEwKSB7IC8vIElFOSBkb2Vzbid0IHN1cHBvcnQgRmlsZUxpc3QsIGhlbmNlIGZpbGVzIHZhcmlhYmxlIGlzIHVuZGVmaW5lZAogICAgICAgICAgICAgICAgICAgIGN1cnJGaWxlTmFtZSA9ICRlbGVtLnZhbCgpLnNwbGl0KCJcXCIpLnBvcCgpOwogICAgICAgICAgICAgICAgICAgIC8vdXBkYXRlIHRoZSBsYXN0IGVsZW1lbnQgb2YgYXJyYXkKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy4kZmlsZURvbUVsZW1lbnRzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kZmlsZURvbUVsZW1lbnRzW3RoaXMuJGZpbGVEb21FbGVtZW50cy5sZW5ndGggLSAxXSA9ICRlbGVtOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aGlzLmNsb25lRmlsZUlucHV0QW5kVXBkYXRlSWRGb3JJRTkoKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gSW4gY2FzZSBvZiBJRTksIG9ubHkgZG8gdGhpcwogICAgICAgICAgICAgICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKGZpbGVzKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dGaWxlTGlzdChjdXJyRmlsZU5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlcy5wdXNoKGN1cnJGaWxlTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRyaWdnZXIgdGhlIGNoYW5nZSBldmVudCB0byB1cGRhdGUgdGhlIHZhbHVlCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcigiY2hhbmdlLmZpbGV1cGxvYWQiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQoZmlsZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGludmFsaWRGaWxlc0luZGV4ZXMgPSBbXTsKICAgICAgICAgICAgICAgICAgICBfLmVhY2goZmlsZXMsIGZ1bmN0aW9uIChmaWxlLCBmaWxlSW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzQ3VycmVudEludmFsaWRGaWxlU2l6ZSA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNDdXJyZW50SW52YWxpZEZpbGVOYW1lID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0N1cnJlbnRJbnZhbGlkTWltZVR5cGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgY3VyckZpbGVOYW1lID0gZmlsZS5uYW1lLnNwbGl0KCJcXCIpLnBvcCgpOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3cgc2l6ZSBpcyBpbiBNQgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2l6ZSA9IGZpbGUuc2l6ZSAvIDEwMjQgLyAxMDI0OwogICAgICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBpZiBmaWxlIHNpemUgbGltaXQgaXMgd2l0aGluIGxpbWl0cwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoKHNpemUgPiBwYXJzZUZsb2F0KHRoaXMub3B0aW9ucy5maWxlU2l6ZUxpbWl0KSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzSW52YWxpZFNpemUgPSBpc0N1cnJlbnRJbnZhbGlkRmlsZVNpemUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5WYWxpZFNpemVmaWxlTmFtZXMgPSBjdXJyRmlsZU5hbWUgKyAiLCIgKyBpblZhbGlkU2l6ZWZpbGVOYW1lczsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5pc1ZhbGlkKGN1cnJGaWxlTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIGZpbGUgbmFtZXMgYXJlIHZhbGlkIChpZSkgdGhlcmUgYXJlIG5vIGNvbnRyb2wgY2hhcmFjdGVycyBpbiBmaWxlIG5hbWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0ludmFsaWRGaWxlTmFtZSA9IGlzQ3VycmVudEludmFsaWRGaWxlTmFtZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpblZhbGlkTmFtZWZpbGVOYW1lcyA9IGN1cnJGaWxlTmFtZSArICIsIiArIGluVmFsaWROYW1lZmlsZU5hbWVzOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGZpbGUudHlwZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzTWF0Y2ggPSB0aGlzLnJlZ2V4TWltZVR5cGVMaXN0LnNvbWUoZnVuY3Rpb24gKHJ4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJ4LnRlc3QoZmlsZS50eXBlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc01hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNJbnZhbGlkTWltZVR5cGUgPSBpc0N1cnJlbnRJbnZhbGlkTWltZVR5cGUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluVmFsaWRNaW1lVHlwZWZpbGVOYW1lcyA9IGN1cnJGaWxlTmFtZSArICIsIiArIGluVmFsaWRNaW1lVHlwZWZpbGVOYW1lczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIGZpbGUgaXMgbm90IGludmFsaWQsIHNob3cgaXQgYW5kIHB1c2ggaXQgdG8gaW50ZXJuYWwgYXJyYXkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0N1cnJlbnRJbnZhbGlkRmlsZVNpemUgJiYgIWlzQ3VycmVudEludmFsaWRGaWxlTmFtZSAmJiAhaXNDdXJyZW50SW52YWxpZE1pbWVUeXBlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dGaWxlTGlzdChjdXJyRmlsZU5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZXMucHVzaChjdXJyRmlsZU5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW52YWxpZEZpbGVzSW5kZXhlcy5wdXNoKGZpbGVJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCgogICAgICAgICAgICAgICAgICAgIH0sIHRoaXMpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoaW52YWxpZEZpbGVzSW5kZXhlcy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJyZW50RmlsZURvbUluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGN1cnJlbnRGaWxlRG9tRWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLiRmaWxlRG9tRWxlbWVudHMubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudEZpbGVEb21JbmRleCA9IHRoaXMuJGZpbGVEb21FbGVtZW50cy5sZW5ndGggLSAxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGN1cnJlbnRGaWxlRG9tRWxlbWVudCA9IHRoaXMuJGZpbGVEb21FbGVtZW50c1tjdXJyZW50RmlsZURvbUluZGV4XTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkY3VycmVudEZpbGVEb21FbGVtZW50ICYmICRjdXJyZW50RmlsZURvbUVsZW1lbnQubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzQ291bnQgPSAkY3VycmVudEZpbGVEb21FbGVtZW50WzBdLmZpbGVzLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIGFsbCB0aGUgZmlsZXMgYXJlIGludmFsaWQgcmVtb3ZlIHRoZSBpbnB1dCBlbGVtZW50IGFzIHdlbGwgb3RoZXJ3aXNlIG9ubHkgcmVtb3ZlIHRoZSBpbnZhbGlkIGZpbGVzLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWxlc0NvdW50ID09PSBpbnZhbGlkRmlsZXNJbmRleGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRmaWxlRG9tRWxlbWVudHMuc3BsaWNlKC0xLCAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9kZWxldGVGaWxlc0Zyb21JbnB1dERvbSgkY3VycmVudEZpbGVEb21FbGVtZW50LCBpbnZhbGlkRmlsZXNJbmRleGVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluIGNhc2Ugb2YgSUUxMCwgY3JlYXRlIG9uZSBleHRyYSBlbGVtZW50CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0Jyb3dzZXJJRTlPcklFMTApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2xvbmVGaWxlSW5wdXRBbmRVcGRhdGVJZEZvcklFOSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyB0cmlnZ2VyIHRoZSBjaGFuZ2UgZXZlbnQgdG8gdXBkYXRlIHRoZSB2YWx1ZQogICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcigiY2hhbmdlLmZpbGV1cGxvYWQiKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoaXNJbnZhbGlkU2l6ZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc2hvd0ludmFsaWRNZXNzYWdlKGluVmFsaWRTaXplZmlsZU5hbWVzLnN1YnN0cmluZygwLCBpblZhbGlkU2l6ZWZpbGVOYW1lcy5sYXN0SW5kZXhPZignLCcpKSwgdGhpcy5pbnZhbGlkRmVhdHVyZS5TSVpFKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNJbnZhbGlkRmlsZU5hbWUpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dJbnZhbGlkTWVzc2FnZShpblZhbGlkTmFtZWZpbGVOYW1lcy5zdWJzdHJpbmcoMCwgaW5WYWxpZE5hbWVmaWxlTmFtZXMubGFzdEluZGV4T2YoJywnKSksIHRoaXMuaW52YWxpZEZlYXR1cmUuTkFNRSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzSW52YWxpZE1pbWVUeXBlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zaG93SW52YWxpZE1lc3NhZ2UoaW5WYWxpZE1pbWVUeXBlZmlsZU5hbWVzLnN1YnN0cmluZygwLCBpblZhbGlkTWltZVR5cGVmaWxlTmFtZXMubGFzdEluZGV4T2YoJywnKSksIHRoaXMuaW52YWxpZEZlYXR1cmUuTUlNRVRZUEUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgY2xvbmVGaWxlSW5wdXRBbmRVcGRhdGVJZEZvcklFOSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciBlbGVtID0gXy5sYXN0KHRoaXMuJGZpbGVEb21FbGVtZW50cyksCiAgICAgICAgICAgICAgICBlbGVtRXhpc3RzID0gZWxlbSAhPSBudWxsLAogICAgICAgICAgICAgICAgZWxlbUhhc1ZhbHVlID0gZWxlbUV4aXN0cyAmJiBlbGVtLnZhbCgpLmxlbmd0aCA+IDAsCiAgICAgICAgICAgICAgICBlbGVtSWQgPSBudWxsLAogICAgICAgICAgICAgICAgc2VsZWN0b3IgPSBudWxsOwoKICAgICAgICAgICAgLy8gQ1EtNDIzNzkwMyA6IGNyZWF0ZSBjbG9uZSB0byBoYW5kbGUgdGhlIGNhc2Ugd2hlbiB1c2VyIGNsaWNrcyBjYW5jZWwgaW4gY2hyb21lIGFuZCBmb3IgbXVsdGlzZWxlY3QKICAgICAgICAgICAgLy8gb24gY2xpY2tpbmcgY2FuY2VsIGluIGNocm9tZSBmaWxlIGJyb3dzZXIsIGNocm9tZSByZW1vdmVzIGFsbCB0aGUgZmlsZXMgZnJvbSB0aGUgaW5wdXQgZWxlbWVudAogICAgICAgICAgICAvLyByZW1vdmUgdGhlIGV4dHJhIGNsb25lIGluICRmaWxlRG9tRWxlbWVudCBvbiBoYW5kbGVDaGFuZ2UKICAgICAgICAgICAgaWYoIWVsZW1FeGlzdHMgfHwgZWxlbUhhc1ZhbHVlKSB7CiAgICAgICAgICAgICAgICBlbGVtID0gdGhpcy4kZWxlbWVudC5jbG9uZSgpOwogICAgICAgICAgICAgICAgLy8gY29weSB0aGUgZGF0YSBhdHRyaWJ1dGVzCiAgICAgICAgICAgICAgICBlbGVtLmRhdGEodGhpcy4kZWxlbWVudC5kYXRhKCkpOwogICAgICAgICAgICAgICAgaWYoaXNCcm93c2VySUU5T3JJRTEwKXsKICAgICAgICAgICAgICAgICAgICBlbGVtSWQgPSB0aGlzLiRlbGVtZW50LmF0dHIoImlkIikgKyAoKytmaWxlTGFiZWxzQ291bnQpOwogICAgICAgICAgICAgICAgICAgIGVsZW0uYXR0cigiaWQiLCBlbGVtSWQpOwogICAgICAgICAgICAgICAgICAgIGVsZW0uY3NzKHsKICAgICAgICAgICAgICAgICAgICAgICAgJ3Bvc2l0aW9uJyA6ICdhYnNvbHV0ZScsCiAgICAgICAgICAgICAgICAgICAgICAgICd0b3AnIDogJy0yMDAwcHgnLAogICAgICAgICAgICAgICAgICAgICAgICAnbGVmdCc6ICctMjAwMHB4JwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIGVsZW0uYXBwZW5kVG8oJ2JvZHknKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUxhYmVsRm9yQXR0cihlbGVtSWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxlbS5jaGFuZ2UoJC5wcm94eSh0aGlzLmhhbmRsZUNoYW5nZSwgdGhpcykpOwogICAgICAgICAgICAgICAgdGhpcy4kZmlsZURvbUVsZW1lbnRzLnB1c2goZWxlbSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gQ2FzZTogaWYgaXQgaXMgbm90IG11bHRpc2VsZWN0IGFuZCBpZiB0aGUgZmlyc3QgZmlsZSBkb20gZWxlbWVudCBpcyBudWxsCiAgICAgICAgICAgIC8vIHRoaXMgY2FzZSB3b3VsZCBoaXQgd2hlbiB3ZSByZXN0b3JlIGEgc2luZ2xlIHNlbGVjdCBmaWxlIGF0dGFjaG1lbnQgYW5kIGF0dGFjaCBhIG5ldyBmaWxlCiAgICAgICAgICAgIGlmKCF0aGlzLm9wdGlvbnMubXVsdGlTZWxlY3QgJiYgdGhpcy4kZmlsZURvbUVsZW1lbnRzWzBdID09PSBudWxsKXsKICAgICAgICAgICAgICAgIC8vU3BsaWNlIG51bGwgb3V0IG9mIGl0LCBzaW5jZSB3ZSBhcmUgYXR0YWNoaW5nIGEgbmV3IGZpbGUKICAgICAgICAgICAgICAgIHRoaXMuJGZpbGVEb21FbGVtZW50cy5zcGxpY2UoMCwgMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gaWYgdGhlIGJyb3dzZXIgaXMgbm90IElFOSwgdGhlbiBjbGljayBpdAogICAgICAgICAgICBpZighaXNCcm93c2VySUU5T3JJRTEwKSB7CiAgICAgICAgICAgICAgICBlbGVtLmNsaWNrKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogSW4gY2FzZSBvZiBJRTksIGdldCB0aGUgbGFzdCBlbGVtZW50IG9mIGZpbGVEb20gYW5kIHVwZGF0ZSB0aGUgaWQgZm9yIGxhYmVsCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gZmlsZUlucHV0SWQKICAgICAgICAgKi8KICAgICAgICB1cGRhdGVMYWJlbEZvckF0dHIgOiBmdW5jdGlvbihmaWxlSW5wdXRJZCl7CiAgICAgICAgICAgIHRoaXMuJGxhYmVsLmF0dHIoImZvciIgLCBmaWxlSW5wdXRJZCk7CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlTGFiZWxGb3JGaWxlSW5wdXQgOiBmdW5jdGlvbiAoZmlsZUlucHV0SWQpewogICAgICAgICAgICBpZihpc0Jyb3dzZXJJRTlPcklFMTApIHsKICAgICAgICAgICAgICAgIHRoaXMuJGxhYmVsID0gJCgiPGxhYmVsPjwvbGFiZWw+IikuYWRkQ2xhc3MoImd1aWRlLWZ1LWF0dGFjaC1idXR0b24gYnV0dG9uIikKICAgICAgICAgICAgICAgICAgICAgICAgLnRleHQodGhpcy5vcHRpb25zLmJ1dHRvblRleHQpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCdmb3InLGZpbGVJbnB1dElkKTsKICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRGaWxlVXBsb2FkQnRuLnJlcGxhY2VXaXRoKHRoaXMuJGxhYmVsKTsKICAgICAgICAgICAgICAgIHRoaXMuJGxhYmVsLnBhcmVudCgpLmF0dHIoInRhYmluZGV4IiwgMCkuYXR0cigicm9sZSIsICJidXR0b24iKS5hdHRyKCJhcmlhLWxhYmVsIiwgdGhpcy5vcHRpb25zLnNjcmVlblJlYWRlclRleHQgfHwgIiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCgogICAgICAgIGNvbnN0cnVjdG9yOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vIEluaXRpYWxpemUgdGhlIHNlbGYgaW5zdGFuY2UKICAgICAgICAgICAgdmFyIF9zZWxmID0gdGhpcywKICAgICAgICAgICAgICAgIGlzRmlyc3QgPSB0cnVlOwogICAgICAgICAgICAvL2pxdWVyeSBpbnN0YW5jZSBvZiBmaWxlIHVwbG9hZCBidXR0b24KICAgICAgICAgICAgdGhpcy4kZWxlbWVudEZpbGVVcGxvYWRCdG4gPSB0aGlzLiRwYXJlbnQuZmluZCh0aGlzLm9wdGlvbnMuYnV0dG9uQ2xhc3MpOwogICAgICAgICAgICB0aGlzLiRlbGVtZW50RmlsZVVwbG9hZEJ0bi5hdHRyKCJhcmlhLWxhYmVsIiwgdGhpcy5vcHRpb25zLnNjcmVlblJlYWRlclRleHQgfHwgIiIpOwogICAgICAgICAgICBpZihpc0Jyb3dzZXJJRTlPcklFMTApewogICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50SWQgPSB0aGlzLiRlbGVtZW50LmF0dHIoImlkIik7CiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZUxhYmVsRm9yRmlsZUlucHV0KHRoaXMuJGVsZW1lbnQuYXR0cigiaWQiKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGh0bWwgZm9yIGZpbGUgbGlzdAogICAgICAgICAgICB0aGlzLiRlbGVtZW50RmlsZUxpc3QgPSAkKHRoaXMuZmlsZUl0ZW1MaXN0KCkpOwogICAgICAgICAgICAvLyBJbml0aWFsaXplIHRoZSB2YWx1ZSBhbmQgZmlsZShSZWZlciBGaWxlTGlzdCBjbGFzcyBtZG4pCiAgICAgICAgICAgIHRoaXMudmFsdWVzID0gW107CiAgICAgICAgICAgIHRoaXMuX2luaXRpYWxGaWxlVmFsdWVGaWxlTmFtZU1hcCA9IHt9OwogICAgICAgICAgICAvLyBMaXN0IG9mIGRvbSBlbGVtZW50cyBvZiBpbnB1dCB0eXBlIGZpbGUKICAgICAgICAgICAgdGhpcy4kZmlsZURvbUVsZW1lbnRzID0gW107CgogICAgICAgICAgICB2YXIgZmxhZyA9IGZhbHNlLAogICAgICAgICAgICAgICAgJGN1cnJFbGVtID0gbnVsbDsKCiAgICAgICAgICAgICQoZG9jdW1lbnQpLm1vdXNlZG93bihmdW5jdGlvbihlKSB7CiAgICAgICAgICAgICAgICAkY3VyckVsZW0gPSAkKGUudGFyZ2V0KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIC8vIEVudGVyIGtleSBzaG91bGQgcmVzdWx0IGluIGNsaWNrIG9mIGJ1dHRvbgogICAgICAgICAgICB0aGlzLiRlbGVtZW50RmlsZVVwbG9hZEJ0bgogICAgICAgICAgICAgICAgLmZvY3VzKGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICAgICAgX3NlbGYuJGVsZW1lbnQudHJpZ2dlcigiZm9jdXMuZmlsZXVwbG9hZCIpOwogICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIC5jbGljaygkLnByb3h5KHRoaXMuY2xvbmVGaWxlSW5wdXRBbmRVcGRhdGVJZEZvcklFOSwgdGhpcykpCiAgICAgICAgICAgICAgICAuYmx1cihmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGN1cnJFbGVtIGRvZXMgbm90IGJlbG9uZyB0byB0aGUgZmlsZUl0ZW1MaXN0CiAgICAgICAgICAgICAgICAgICAgaWYoIWZsYWcgJiYgJGN1cnJFbGVtIT0gbnVsbCAmJiAkY3VyckVsZW0uY2xvc2VzdCgiLmd1aWRlLWZ1LWZpbGVJdGVtTGlzdCIpLmxlbmd0aCA8PTApewogICAgICAgICAgICAgICAgICAgICAgICBfc2VsZi4kZWxlbWVudC50cmlnZ2VyKCJmb2N1c291dC5maWxldXBsb2FkIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGZsYWcgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAvL0luaXRpYWxpemUgdGhlIGZpbGVQcmV2aWV3IFBsdWdpbgogICAgICAgICAgICB0aGlzLiRlbGVtZW50W3RoaXMub3B0aW9ucy51cGxvYWRlclBsdWdpbk5hbWVdKHsKICAgICAgICAgICAgICAgIGlmcmFtZUNvbnRhaW5lcjogdGhpcy5vcHRpb25zLmlmcmFtZUNvbnRhaW5lciwKICAgICAgICAgICAgICAgIF9maWxlUGF0aDogdGhpcy5vcHRpb25zLl9maWxlUGF0aCwKICAgICAgICAgICAgICAgIF91dWlkR2VuZXJhdG9yOiB0aGlzLm9wdGlvbnMuX3V1aWRHZW5lcmF0b3IsCiAgICAgICAgICAgICAgICBfZ2V0VXJsOiB0aGlzLm9wdGlvbnMuX2dldFVybAoKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIC8vIEdldHRpbmcgaW5wdXQgZmlsZSB2YWx1ZQogICAgICAgICAgICAvLyBsaXN0ZW5pbmcgb24gZmlsZXVwbG9hZGVkIGV2ZW50CiAgICAgICAgICAgIHRoaXMuJGVsZW1lbnQuY2hhbmdlKCQucHJveHkodGhpcy5oYW5kbGVDaGFuZ2UsIHRoaXMpKQogICAgICAgICAgICAgICAgLm9uKCJhZG9iZUZpbGVVcGxvYWRlci5maWxlVXBsb2FkZWQiLCAkLnByb3h5KHRoaXMucHJldmlld0ZpbGUsIHRoaXMpKTsKICAgICAgICB9CiAgICB9OwoKICAgICQuZm4uYWRvYmVGaWxlQXR0YWNobWVudCA9IGZ1bmN0aW9uIChvcHRpb24sIHZhbHVlKSB7CiAgICAgICAgdmFyIGdldCA9ICcnLAogICAgICAgICAgICBlbGVtZW50ID0gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIC8vIGluIGNhc2Ugb2YgaW5wdXQgdHlwZSBmaWxlCiAgICAgICAgICAgICAgICBpZiAoJCh0aGlzKS5hdHRyKCd0eXBlJykgPT09ICdmaWxlJykgewogICAgICAgICAgICAgICAgICAgIHZhciAkdGhpcyA9ICQodGhpcyksCiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSAkdGhpcy5kYXRhKCdhZG9iZUZpbGVBdHRhY2htZW50JyksCiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgQWRvYmVGaWxlQXR0YWNobWVudC5wcm90b3R5cGUuZGVmYXVsdHMsIHR5cGVvZiBvcHRpb24gPT09ICdvYmplY3QnICYmIG9wdGlvbik7CgogICAgICAgICAgICAgICAgICAgIC8vIFNhdmUgdGhlIGFkb2JlRmlsZUF0dGFjaG1lbnQgZGF0YSBpbiBqcXVlcnkKICAgICAgICAgICAgICAgICAgICBpZiAoIWRhdGEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMuZGF0YSgnYWRvYmVGaWxlQXR0YWNobWVudCcsIChkYXRhID0gbmV3IEFkb2JlRmlsZUF0dGFjaG1lbnQodGhpcywgb3B0aW9ucykpKTsKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5jb25zdHJ1Y3RvcigpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gY29kZSB0byBnZXQgYW5kIHNldCBhbiBvcHRpb24KICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZ2V0ID0gZGF0YVtvcHRpb25dKHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwoKICAgICAgICBpZiAodHlwZW9mIGdldCAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICAgICAgcmV0dXJuIGdldDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgICAgICB9CiAgICB9OwoKICAgIC8vIGZpbGVTaXplTGltaXQgaXMgaW4gTUIsIGRlZmF1bHQgdmFsdWUgaXMgMk1CCiAgICBBZG9iZUZpbGVBdHRhY2htZW50LnByb3RvdHlwZS5kZWZhdWx0cyA9IHsKICAgICAgICAnYnV0dG9uVGV4dCc6ICdBdHRhY2gnLAogICAgICAgICdtdWx0aVNlbGVjdCc6IGZhbHNlLAogICAgICAgICdmaWxlU2l6ZUxpbWl0JzogMiwKICAgICAgICAndXBsb2FkZXJQbHVnaW5OYW1lJzogImFkb2JlRmlsZVVwbG9hZGVyIiwKICAgICAgICAnbWltZVR5cGUnIDogWydhdWRpby8qJywgJ3ZpZGVvLyonLCAnaW1hZ2UvKicsICd0ZXh0LyonLCAnYXBwbGljYXRpb24vcGRmJ10KICAgIH07Cgp9KSgkLCB3aW5kb3csIHdpbmRvdy5fKTsKKGZ1bmN0aW9uKCQsIF8pIHsKICAgIHZhciB4ZmFVdGlsID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlOwogICAgJC53aWRnZXQoICJ4ZmFXaWRnZXQuZmlsZVVwbG9hZCIsICQueGZhV2lkZ2V0LmFic3RyYWN0V2lkZ2V0LCB7CgogICAgICAgIF93aWRnZXROYW1lOiJmaWxlVXBsb2FkIiwKICAgICAgICBfc3VwZXJQcm90b3R5cGUgOiAkLnhmYVdpZGdldC5hYnN0cmFjdFdpZGdldC5wcm90b3R5cGUsCiAgICAgICAgZ2V0T3B0aW9uc01hcDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSB0aGlzLl9zdXBlclByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKSwKICAgICAgICAgICAgICAgIG5ld01hcCA9ICQuZXh0ZW5kKHt9LHBhcmVudE9wdGlvbnNNYXAsICQuZXh0ZW5kKHt9LCB0aGlzLm9wdGlvbnMsIHsKICAgICAgICAgICAgICAgICAgICAidmFsdWUiIDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYWRvYmVGaWxlQXR0YWNobWVudCgidmFsdWUiLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAiZmlsZUxpc3QiOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmFkb2JlRmlsZUF0dGFjaG1lbnQoImZpbGVMaXN0IiwgdmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgImNvbW1lbnQiIDogZnVuY3Rpb24odmFsdWUpewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hZG9iZUZpbGVBdHRhY2htZW50KCJjb21tZW50IiwgdmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgLy8gImFjY2VzcyIgY2FuIGJlIGVpdGhlciBvcGVuIG9yIHJlYWRvbmx5CiAgICAgICAgICAgICAgICAgICAgImFjY2VzcyIgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmFkb2JlRmlsZUF0dGFjaG1lbnQoImFjY2VzcyIsIHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgfSkpOwoKICAgICAgICAgICAgcmV0dXJuIG5ld01hcDsKCiAgICAgICAgfSwKICAgICAgICAvLyBUT0RPOiBXaWxsIG5lZWQgdG8gcmVtb3ZlIHRoaXMgZnVuY3Rpb25zCiAgICAgICAgLy8gIHdpbGwgYmUgdHJhY2tlZCBieSBMQy0zOTEyMDAKCiAgICAgICAgX2luaXRpYWxpemVPcHRpb25zOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIF8uZWFjaCh0aGlzLm9wdGlvbnNIYW5kbGVyLCBmdW5jdGlvbiAodmFsdWUsIGtleSkgewogICAgICAgICAgICAgICAgLy8gb3ZlcnJpZGluZyB0aGUgYmVoYXZpb3VyIG9mIF9pbml0aWFsaXplT3B0aW9ucwogICAgICAgICAgICAgICAgLy8gb25seSBmb3IgX3V1aWRHZW5lcmF0b3IKICAgICAgICAgICAgICAgIC8vIGFzIHdlIGZvbnQgd2FudCBnZXRVVUlEIHRvIGJlIGNhbGxlZCBhdCByZW5kZXIgdGltZQogICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gImZ1bmN0aW9uIiAmJiBrZXkgIT09ICdfdXVpZEdlbmVyYXRvcicgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLmFwcGx5KHRoaXMsIFt0aGlzLm9wdGlvbnNba2V5XV0pCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIHRoaXMpCiAgICAgICAgfSwKCiAgICAgICAgX2dldEZpbGVMaXN0OiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy4kdXNlckNvbnRyb2wuYWRvYmVGaWxlQXR0YWNobWVudCgiZmlsZUxpc3QiKTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0Q29tbWVudDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuJHVzZXJDb250cm9sLmFkb2JlRmlsZUF0dGFjaG1lbnQoImNvbW1lbnQiKTsKICAgICAgICB9LAogICAgICAgIF9nZXRGaWxlTmFtZVBhdGhNYXA6IGZ1bmN0aW9uIChwYXRoTGlzdCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy4kdXNlckNvbnRyb2wuYWRvYmVGaWxlQXR0YWNobWVudCgiZ2V0U2V0RmlsZVBhdGhBbmRSZXR1cm5OYW1lUGF0aE1hcCIsIHBhdGhMaXN0KTsKICAgICAgICB9LAogICAgICAgIGdldEV2ZW50TWFwOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHBhcmVudEV2ZW50TWFwID0gdGhpcy5fc3VwZXJQcm90b3R5cGUuZ2V0RXZlbnRNYXAuYXBwbHkodGhpcywgYXJndW1lbnRzKSwKICAgICAgICAgICAgICAgIG5ld01hcCA9ICQuZXh0ZW5kKHt9LCBwYXJlbnRFdmVudE1hcCwKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJjaGFuZ2UiIDogbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgImZvY3Vzb3V0LmZpbGV1cGxvYWQiIDogeGZhVXRpbC5YRkFfRVhJVF9FVkVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgImZvY3VzLmZpbGV1cGxvYWQiIDogeGZhVXRpbC5YRkFfRU5URVJfRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgICAgICJjaGFuZ2UuZmlsZXVwbG9hZCIgOiB4ZmFVdGlsLlhGQV9DSEFOR0VfRVZFTlQKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgcmV0dXJuIG5ld01hcDsKICAgICAgICB9LAogICAgICAgIHJlbmRlcjogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciAkZWwgPSB0aGlzLl9zdXBlclByb3RvdHlwZS5yZW5kZXIuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgICAgICAkZWwuYWRvYmVGaWxlQXR0YWNobWVudCh0aGlzLmdldE9wdGlvbnNNYXAoKSk7CiAgICAgICAgICAgIHJldHVybiAkZWw7CiAgICAgICAgfSwKICAgICAgICBzaG93RGlzcGxheVZhbHVlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgIC8vc2luY2UgdmFsdWUgY2FuJ3QgYmUgc2V0IGluIGZpbGUgZWxlbWVudCBpbnB1dCwgbGVhdmluZyB0aGlzIGZuIGVtcHR5CiAgICAgICAgfSwKICAgICAgICBzaG93VmFsdWU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAvL3NpbmNlIHZhbHVlIGNhbid0IGJlIHNldCBpbiBmaWxlIGVsZW1lbnQgaW5wdXQsIGxlYXZpbmcgdGhpcyBmbiBlbXB0eQogICAgICAgIH0sCiAgICAgICAgZ2V0Q29tbWl0VmFsdWU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB0aGlzLm9wdGlvbnMuZmlsZUxpc3QgPSB0aGlzLl9nZXRGaWxlTGlzdCgpOwogICAgICAgICAgICB0aGlzLm9wdGlvbnMuY29tbWVudCA9IHRoaXMuX2dldENvbW1lbnQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuJHVzZXJDb250cm9sLmFkb2JlRmlsZUF0dGFjaG1lbnQoInZhbHVlIik7CiAgICAgICAgfQogICAgfSk7Cn0pKCQsIHdpbmRvdy5fKTsKCi8qKgogKiBBZG9iZSBGaWxlUHJldmlldyBXaWRnZXQgUGx1Z2luCiAqCiAqIE9wdGlvbnMgZXhwZWN0ZWQgYnkgZmlsZSBwcmV2aWV3IGlzIHRoZSB1cmwKICoKICogT3B0aW9ucyBSZXF1aXJlZCBBcmU6CiAqCiAqICBpZnJhbWVOYW1lOiBOYW1lIG9mIHRoZSBJZnJhbWUKICogIGlmcmFtZUNvbnRhaW5lcjogQ29udGFpbmVyIG9mIHRoZSBpZnJhbWUoZWcgQm9keSkKICogIGZpbGVVcGxvYWRQYXRoOiBQYXRoIHdoZXJlIHRoZSBmaWxlIGlzIHRvIGJlIHVwbG9hZGVkCiAqICBmaWxlVXBsb2FkU2VydmxldDogU2VydmxldCB3aGVyZSB0aGUgZmlsZSBpcyB0byBiZSB1cGxvYWRlZAogKgogKi8KKGZ1bmN0aW9uICgkLCBfKSB7CgogICAgdmFyIEFkb2JlRmlsZVVwbG9hZGVyID0gZnVuY3Rpb24gKGVsZW1lbnQsIG9wdGlvbnMpIHsKICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zOwogICAgICAgIHRoaXMuJGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgfTsKCiAgICBBZG9iZUZpbGVVcGxvYWRlci5wcm90b3R5cGUgPSB7CgogICAgICAgIF9maWxlSWZyYW1lTmFtZTogImd1aWRlLWZ1LWlmcmFtZSIsCgogICAgICAgIF9maWxlUGF0aDogIi90bXAvZmQvbWYiLAoKICAgICAgICBfaWZyYW1lQ29udGFpbmVyOiAiYm9keSNmb3JtQm9keSIsCgoKICAgICAgICBmaWxlSWZyYW1lOiBmdW5jdGlvbiAobmFtZSkgewogICAgICAgICAgICByZXR1cm4gJCgiPGlmcmFtZT48L2lmcmFtZT4iKS5hdHRyKHsKICAgICAgICAgICAgICAgIHN0eWxlOiAiZGlzcGxheTpub25lIiwKICAgICAgICAgICAgICAgIG5hbWU6IG5hbWUKICAgICAgICAgICAgfSk7CiAgICAgICAgfSwKCiAgICAgICAgdXBsb2FkRmlsZTogZnVuY3Rpb24gKGZpbGVPYmplY3QpIHsKICAgICAgICAgICAgdmFyIG11bHRpcGxlID0gZmFsc2UsCiAgICAgICAgICAgICAgICBmaWxlTmFtZSA9IG51bGwsCiAgICAgICAgICAgICAgICBhY3Rpb25VcmwgPSBudWxsLAogICAgICAgICAgICAgICAgZmlsZVVwbG9hZFBhdGggPSBmaWxlT2JqZWN0LmZpbGVVcGxvYWRQYXRoLAogICAgICAgICAgICAgICAgdXVpZDsKCiAgICAgICAgICAgIGlmICghZmlsZVVwbG9hZFBhdGgpIHsKICAgICAgICAgICAgICAgIHV1aWQgPSBmaWxlT2JqZWN0Ll91dWlkR2VuZXJhdG9yKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGlmIHV1aWQgZXhpc3RzIG9ubHkgdGhlbiB1cGxvYWQgdGhlIGZpbGUgaW4gdGhlIGN1cnJlbnQgIGluc3RhbmNlCiAgICAgICAgICAgIGlmIChfLmlzT2JqZWN0KGZpbGVPYmplY3QpICYmIChmaWxlVXBsb2FkUGF0aCB8fCB1dWlkKSkgewogICAgICAgICAgICAgICAgdmFyIGZpbGVEb20gPSBmaWxlT2JqZWN0LmZpbGVEb20sCiAgICAgICAgICAgICAgICAgICAgJGZvcm0gPSAkKHRoaXMub3B0aW9ucy5pZnJhbWVDb250YWluZXIpLmZpbmQoIi5maWxlUHJldmlldyIpOwogICAgICAgICAgICAgICAgZmlsZU5hbWUgPSBmaWxlT2JqZWN0LmZpbGVOYW1lOwogICAgICAgICAgICAgICAgbXVsdGlwbGUgPSBmaWxlT2JqZWN0Lm11bHRpcGxlOwogICAgICAgICAgICAgICAgaWYoIWZpbGVVcGxvYWRQYXRoKSB7CiAgICAgICAgICAgICAgICAgICAgZmlsZVVwbG9hZFBhdGggPSB0aGlzLm9wdGlvbnMuZmlsZVVwbG9hZFBhdGggKyAiLyIgKyB1dWlkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGZpbGVEb20gIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAvL3ByZXBlbmQgY29udGV4dHBhdGgKICAgICAgICAgICAgICAgICAgICBhY3Rpb25VcmwgPSBmaWxlT2JqZWN0Ll9nZXRVcmwgKyBmaWxlVXBsb2FkUGF0aDsKICAgICAgICAgICAgICAgICAgICBpZiAoIW11bHRpcGxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKGZpbGVVcGxvYWRQYXRoLmxhc3RJbmRleE9mKGZpbGVPYmplY3QuX2dldFVybCwgMCkgPT09IDApKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbGVVcmwgPSBmaWxlT2JqZWN0Ll9nZXRVcmwgKyBmaWxlVXBsb2FkUGF0aCArICIvIiArIGZpbGVOYW1lOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWxlVXJsID0gZmlsZVVwbG9hZFBhdGggKyAiLyIgKyBmaWxlTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZmlsZVVybCA9IGFjdGlvblVybDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gZG9uZSB0byBzb2x2ZSBpc3N1ZSBMQy01ODM1CiAgICAgICAgICAgICAgICAgICAgaWYoJGZvcm0ubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRmb3JtID0gJCgiPGZvcm0gbWV0aG9kPSdwb3N0JyBlbmN0eXBlPSdtdWx0aXBhcnQvZm9ybS1kYXRhJy8+IikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygiZmlsZVByZXZpZXciKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY3JlYXRlIGlkIHNvIHRoYXQgaXQgZG9lcyBub3QgaW50ZXJjZXB0IHdpdGggb3RoZXIgZm9ybXMgaW4gdGhlIHBhZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZCA6ICJmb3JtIiArIG5ldyBEYXRlKCkudmFsdWVPZigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbiA6IGFjdGlvblVybCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQgOiB0aGlzLm9wdGlvbnMuaWZyYW1lTmFtZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hcHBlbmRUbyh0aGlzLm9wdGlvbnMuaWZyYW1lQ29udGFpbmVyKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLy8gZmlyc3QgZW1wdHkgYWxsIGNoaWxkcmVuLCB1c2luZyBkZXRhY2ggc28gdGhhdCBkYXRhIGlzIG5vdCBjbGVhcgogICAgICAgICAgICAgICAgICAgICAgICAkZm9ybS5jaGlsZHJlbigpLmRldGFjaCgpOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBub3cgdXBkYXRlIHRoZSBuZXcgYXR0cmlidXRlcwogICAgICAgICAgICAgICAgICAgICAgICAkZm9ybS5hdHRyKHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbiA6IGFjdGlvblVybCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCA6IHRoaXMub3B0aW9ucy5pZnJhbWVOYW1lCiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIGRvbmUgc28gdGhhdCB0aGUgb3RoZXIgZXZlbnRzIGF0dGFjaGVkIGF0IHNvbWUgb3RoZXIgbGV2ZWwgaW4gRE9NIFRyZWUgZG9uJ3QgaW50ZXJmZXJlCiAgICAgICAgICAgICAgICAgICAgJGZvcm0ub25lKCJzdWJtaXQiLCBmdW5jdGlvbihldm50KXsKICAgICAgICAgICAgICAgICAgICAgICAgZXZudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgIHZhciBkYXRhID0gbmV3IEZvcm1EYXRhKCk7CgogICAgICAgICAgICAgICAgICAgIGlmIChtdWx0aXBsZSkgewogICAgICAgICAgICAgICAgICAgICAgICBfLmVhY2goZmlsZURvbSwgZnVuY3Rpb24gKGZpbGVEb21FbGVtZW50LCBpbmRleCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT09UQiwgdGhpcyBjb2RlIGlzIHN0aWxsIHVzZWQgaW4gZGFzaGJvYXJkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihmaWxlRG9tRWxlbWVudCAhPT0gbnVsbCAmJiAhXy5pc1N0cmluZyhmaWxlRG9tRWxlbWVudCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKGZpbGVEb21FbGVtZW50WzBdKS5hdHRyKCduYW1lJywgZmlsZU5hbWVbaW5kZXhdKS5hcHBlbmRUbygkZm9ybSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlsZURvbUVsZW1lbnQgbWlnaHQgY29udGFpbiBtdWx0aXBsZSBmaWxlcyBzbyBhbGwgdGhlIGZpbGVzIG5lZWRzIHRvIGJlIGFkZGVkIHRvIGZvcm1kYXRhLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJyZW50RmlsZU5hbWVzID0gZmlsZU5hbWVbaW5kZXhdLnNwbGl0KCJcbiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcih2YXIgZmlsZUluZGV4ID0gMDsgZmlsZUluZGV4IDwgY3VycmVudEZpbGVOYW1lcy5sZW5ndGg7IGZpbGVJbmRleCsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEuYXBwZW5kKGN1cnJlbnRGaWxlTmFtZXNbZmlsZUluZGV4XSwgZmlsZURvbUVsZW1lbnRbMF0uZmlsZXNbZmlsZUluZGV4XSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBmaWxlRG9tLmF0dHIoJ25hbWUnLCBmaWxlTmFtZSkuYXBwZW5kVG8oJGZvcm0pOwogICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmFwcGVuZChmaWxlTmFtZSwgZmlsZURvbVswXS5maWxlc1swXSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvKiBVc2VDYXNlOiBTdXBwb3NlIHRoZSBmaWxlTmFtZSBpcyBpbiBvdGhlciBsYW5ndWFnZSwgb24gY2xpY2sgb2YgZmlsZU5hbWUsIGl0IHRyaWVzIHRvIHVwbG9hZCB0aGUgZmlsZQogICAgICAgICAgICAgICAgICAgICBzbyB0aGF0IGl0IGNvdWxkIGJlIHByZXZpZXcsIHRoaXMgY2hhbmdlIHdvdWxkIGVuc3VyZSB0aGF0IHRoZSBmaWxlIGlzIHByb3Blcmx5IHByZXZpZXdlZCBzdXBwb3J0aW5nCiAgICAgICAgICAgICAgICAgICAgIHRoZSBnaXZlbiBVVEYtOCBjaGFyc2V0ICovCiAgICAgICAgICAgICAgICAgICAgJCgiPGlucHV0IHR5cGU9J2hpZGRlbicgbmFtZT0nX2NoYXJzZXRfJyB2YWx1ZT0nVVRGLTgnLz4iKS5hcHBlbmRUbygkZm9ybSk7CiAgICAgICAgICAgICAgICAgICAgZGF0YS5hcHBlbmQoIl9jaGFyc2V0XyIsICJVVEYtOCIpOwogICAgICAgICAgICAgICAgICAgIGlmICghbXVsdGlwbGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWxlTWFwW3RoaXMuZmlsZVVybF0gPSB0aGlzLiRlbGVtZW50OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgJC5hamF4KHsKICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiAkZm9ybS5hdHRyKCJhY3Rpb24iKSwKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGU6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50VHlwZTogZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NEYXRhOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdQT1NUJywKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24oZGF0YSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW11bHRpcGxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5oYW5kbGVTaW5nbGVGaWxlVXBsb2FkKGRhdGEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmhhbmRsZU11bHRpcGxlRmlsZVVwbG9hZChkYXRhKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCJhZG9iZUZpbGVVcGxvYWRlci5maWxlVXBsb2FkRmFpbGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdGhpcy5maWxlVXJsOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZU11bHRpcGxlRmlsZVVwbG9hZDogZnVuY3Rpb24gKGRhdGEpIHsKICAgICAgICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCJhZG9iZUZpbGVVcGxvYWRlci5tdWx0aXBsZUZpbGVVcGxvYWRlZCIpOwogICAgICAgIH0sCgogICAgICAgIGdldEZpbGVVcmw6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmlsZVVybDsKICAgICAgICB9LAoKICAgICAgICBnZXRVcmxDb250ZW50c0Zyb21VcGxvYWREYXRhOiBmdW5jdGlvbiAoZGF0YSkgewogICAgICAgICAgICB2YXIgdGVtcDsKICAgICAgICAgICAgaWYoZGF0YSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICB0ZW1wID0gJChkYXRhKS5maW5kKCIjQ2hhbmdlTG9nIikudGV4dCgpLnNwbGl0KCJiciIsIDIpWzFdOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIHNlbGVjdG9yID0gdGhpcy5vcHRpb25zLmlmcmFtZUNvbnRhaW5lciArICIgaWZyYW1lW25hbWU9JyIgKyB0aGlzLm9wdGlvbnMuaWZyYW1lTmFtZSArICInXSI7CiAgICAgICAgICAgICAgICB0ZW1wID0gJChzZWxlY3RvcikuY29udGVudHMoKS5maW5kKCIjQ2hhbmdlTG9nIikudGV4dCgpLnNwbGl0KCJiciIsIDIpWzFdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICB0ZW1wID0gdGVtcC5zdWJzdHJpbmcodGVtcC5pbmRleE9mKCJjcmVhdGVkIikgKyA5LCB0ZW1wLmluZGV4T2YoIjs8IikpOwogICAgICAgICAgICB0ZW1wID0gdGVtcC5zdWJzdHJpbmcoMCwgdGVtcC5sZW5ndGggLSAyKTsKICAgICAgICAgICAgdmFyIGluZGV4ID0gdGVtcC5pbmRleE9mKCIvamNyOmNvbnRlbnQiKTsKICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkKICAgICAgICAgICAgICAgIHRlbXAgPSB0ZW1wLnN1YnN0cmluZygwLCBpbmRleCk7CiAgICAgICAgICAgIHJldHVybiB0ZW1wOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZVNpbmdsZUZpbGVVcGxvYWQ6IGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgICAgIHZhciB1cmwgPSB0aGlzLmdldFVybENvbnRlbnRzRnJvbVVwbG9hZERhdGEoZGF0YSk7CgogICAgICAgICAgICAvL3ByZXBlbmQgY29udGV4dCBwYXRoCiAgICAgICAgICAgIHVybCA9IHRoaXMub3B0aW9ucy5fZ2V0VXJsICsgdXJsOwogICAgICAgICAgICBpZiAodXJsIGluIHRoaXMuZmlsZU1hcCkgewogICAgICAgICAgICAgICAgdGhpcy5maWxlTWFwW3VybF0udHJpZ2dlcigiYWRvYmVGaWxlVXBsb2FkZXIuZmlsZVVwbG9hZGVkIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vIFB1dCBpZnJhbWUgaW5zaWRlIHRoZSBpZnJhbWUgY29udGFpbmVyCiAgICAgICAgICAgIC8vIE9uIHRoZSBsb2FkIG9mIGlmcmFtZSwgZGlzcGxheSB0aGUgY29udGVudHMgb2YgZmlsZQogICAgICAgICAgICAvLyBzaW5jZSB0aGVyZSBpcyBvbmx5IG9uZSBpZnJhbWUgZm9yIGFsbCB0aGUgZmlsZSBhdHRhY2htZW50cywgdGhlcmUgbWF5IGJlIHJhY2UgY29uZGl0aW9uCiAgICAgICAgICAgIGlmICh0aGlzLiRpZnJhbWUgPT0gbnVsbCB8fCB0aGlzLiRpZnJhbWUubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgICAgICB0aGlzLiRpZnJhbWUgPSB0aGlzLmZpbGVJZnJhbWUodGhpcy5vcHRpb25zLmlmcmFtZU5hbWUpLmFwcGVuZFRvKHRoaXMub3B0aW9ucy5pZnJhbWVDb250YWluZXIpOwogICAgICAgICAgICAgICAgLy8gc2luY2UgdGhlcmUgaXMgb25seSBpZnJhbWUgZm9yIHRoZSBwcmV2aWV3IG9mIGFsbCBmaWxlIGF0dGFjaG1lbnRzCiAgICAgICAgICAgICAgICAvLyB0aGlzIG1hcCBpcyBhZGRlZCBpbiB0aGUgY2xvc3VyZSBzY29wZQogICAgICAgICAgICAgICAgLy8gbWFwIGNvbnRhaW5zIHRoZSB1cmwoa2V5KSB2cyBmaWxlRG9tRWxlbWVudCh2YWx1ZSkKICAgICAgICAgICAgICAgIC8vIGl0IGhlbHBzIGF2b2lkcyB0aGUgcmFjZSBjb25kaXRpb24KICAgICAgICAgICAgICAgIHRoaXMuZmlsZU1hcCA9IHt9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKCiAgICAkLmZuLmFkb2JlRmlsZVVwbG9hZGVyID0gZnVuY3Rpb24gKG9wdGlvbiwgdmFsdWUpIHsKICAgICAgICB2YXIgZ2V0ID0gJycsCiAgICAgICAgICAgIGVsZW1lbnQgPSB0aGlzLmVhY2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgLy8gaW4gY2FzZSBvZiBpbnB1dCB0eXBlIGZpbGUKICAgICAgICAgICAgICAgIGlmICgkKHRoaXMpLmF0dHIoJ3R5cGUnKSA9PT0gJ2ZpbGUnKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyICR0aGlzID0gJCh0aGlzKSwKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9ICR0aGlzLmRhdGEoJ2Fkb2JlRmlsZVVwbG9hZGVyJyksCiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgQWRvYmVGaWxlVXBsb2FkZXIucHJvdG90eXBlLmRlZmF1bHRzKG9wdGlvbiwgdmFsdWUpLCB0eXBlb2Ygb3B0aW9uID09PSAnb2JqZWN0JyAmJiBvcHRpb24pOwoKICAgICAgICAgICAgICAgICAgICAvLyBTYXZlIHRoZSBhZG9iZUZpbGVBdHRhY2htZW50IGRhdGEgaW4ganF1ZXJ5CiAgICAgICAgICAgICAgICAgICAgaWYgKCFkYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICR0aGlzLmRhdGEoJ2Fkb2JlRmlsZVVwbG9hZGVyJywgKGRhdGEgPSBuZXcgQWRvYmVGaWxlVXBsb2FkZXIodGhpcywgb3B0aW9ucykpKTsKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5pbml0aWFsaXplKCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXBkYXRlIGVsZW1lbnRzIGlmIG5vdCBlcXVhbCwgc2luY2Ugc29tZXRpbWVzIG9uZSBjYW4gY2xvbmUgdG9vCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGRhdGEuJGVsZW1lbnQuZ2V0KDApICE9PSB0aGlzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLiRlbGVtZW50ID0gJCh0aGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gY29kZSB0byBnZXQgYW5kIHNldCBhbiBvcHRpb24KICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZ2V0ID0gZGF0YVtvcHRpb25dKHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwoKICAgICAgICBpZiAodHlwZW9mIGdldCAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICAgICAgcmV0dXJuIGdldDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgICAgICB9CiAgICB9OwoKCiAgICBBZG9iZUZpbGVVcGxvYWRlci5wcm90b3R5cGUuZGVmYXVsdHMgPSBmdW5jdGlvbiAob3B0aW9ucyx2YWx1ZSkgIHsKICAgICAgICB2YXIgcHJvcGVydHlPYmplY3QgPSB7fTsKICAgICAgICBpZih0eXBlb2Ygb3B0aW9ucyA9PSAnb2JqZWN0JykgewogICAgICAgICAgICBwcm9wZXJ0eU9iamVjdC5fZmlsZUlmcmFtZU5hbWUgPSBvcHRpb25zLl9maWxlSWZyYW1lTmFtZTsKICAgICAgICAgICAgcHJvcGVydHlPYmplY3QuX2ZpbGVQYXRoID0gb3B0aW9ucy5fZmlsZVBhdGg7CiAgICAgICAgICAgIHByb3BlcnR5T2JqZWN0LmFjdGlvblVybCA9IG9wdGlvbnMuYWN0aW9uVXJsOwogICAgICAgICAgICBwcm9wZXJ0eU9iamVjdC5fZ2V0VXJsID0gb3B0aW9ucy5fZ2V0VXJsOwogICAgICAgIH0KICAgICAgICBpZih0eXBlb2YgIHZhbHVlID09ICdvYmplY3QnKSB7CiAgICAgICAgICAgIHByb3BlcnR5T2JqZWN0Ll9maWxlSWZyYW1lTmFtZSA9IHZhbHVlLl9maWxlSWZyYW1lTmFtZTsKICAgICAgICAgICAgcHJvcGVydHlPYmplY3QuX2ZpbGVQYXRoID0gdmFsdWUuX2ZpbGVQYXRoOwogICAgICAgICAgICBwcm9wZXJ0eU9iamVjdC5hY3Rpb25VcmwgPSB2YWx1ZS5hY3Rpb25Vcmw7CiAgICAgICAgICAgIHByb3BlcnR5T2JqZWN0Ll9nZXRVcmwgPSBvcHRpb25zLl9nZXRVcmw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICdmaWxlVXBsb2FkUGF0aCc6IHByb3BlcnR5T2JqZWN0Ll9maWxlUGF0aCB8fCBBZG9iZUZpbGVVcGxvYWRlci5wcm90b3R5cGUuX2ZpbGVQYXRoLAogICAgICAgICAgICAnaWZyYW1lTmFtZSc6IEFkb2JlRmlsZVVwbG9hZGVyLnByb3RvdHlwZS5fZmlsZUlmcmFtZU5hbWUgKyBuZXcgRGF0ZSgpLnZhbHVlT2YoKSwKICAgICAgICAgICAgJ2ZpbGVVcGxvYWRTZXJ2bGV0JzogcHJvcGVydHlPYmplY3QuX2ZpbGVQYXRoIHx8IEFkb2JlRmlsZVVwbG9hZGVyLnByb3RvdHlwZS5fZmlsZVBhdGgsCiAgICAgICAgICAgICdpZnJhbWVDb250YWluZXInOiBwcm9wZXJ0eU9iamVjdC5faWZyYW1lQ29udGFpbmVyIHx8IEFkb2JlRmlsZVVwbG9hZGVyLnByb3RvdHlwZS5faWZyYW1lQ29udGFpbmVyLAogICAgICAgICAgICAnX2dldFVybCc6IHByb3BlcnR5T2JqZWN0Ll9nZXRVcmwgfHwgIiIKICAgICAgICB9OwogICAgfTsKCn0pKCQsIHdpbmRvdy5fKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDEzIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgooZnVuY3Rpb24oXyx4ZmFsaWIpIHsKICAgIHZhciBDb25zdGFudHMgPSB7CiAgICAgICAgYWNjZXNzVmFsdWVzIDogWyJvcGVuIiwicHJvdGVjdGVkIiwicmVhZE9ubHkiLCJub25JbnRlcmFjdGl2ZSJdLAogICAgICAgIHByZXNlbmNlVmFsdWVzIDogWyJ2aXNpYmxlIiwgImhpZGRlbiIsImluYWN0aXZlIiwiaW52aXNpYmxlIl0sCiAgICAgICAgaXRlbVNhdmVWYWx1ZXMgOiBbMCwxXSwKICAgICAgICB2YWx1ZU92ZXJyaWRlVmFsdWVzIDogWzAsMV0sCiAgICAgICAgb25lT2ZDaGlsZCA6IHt0eXBlOiAib25lT2ZDaGlsZCIsIG1pbjowLCBtYXg6MX0sCiAgICAgICAgemVyb09yTW9yZSA6IHt0eXBlOiAiemVyb09yTW9yZSIsbWluOjAsIG1heDpJbmZpbml0eX0sCiAgICAgICAgemVyb09yT25lIDoge3R5cGU6ICJ6ZXJvT3JPbmUiLG1pbjowLCBtYXg6MX0sCiAgICAgICAgemVyb09yVHdvIDoge3R5cGU6ICJ6ZXJvT3JUd28iLCBtaW46MCwgbWF4OjJ9LAogICAgICAgIHplcm9PckZvdXIgOiB7dHlwZTogInplcm9PckZvdXIiLCBtaW46MCwgbWF4OjR9LAogICAgICAgIG9uZU9yTW9yZSA6IHt0eXBlOiAib25lT3JNb3JlIiwgbWluOjEsIG1heDpJbmZpbml0eX0sCgogICAgICAgIGVuY3J5cHREYXRhT3BlcmF0aW9uVmFsdWVzIDogWyJlbmNyeXB0IiwgImRlY3J5cHQiXSwKICAgICAgICByZXF1aXJlZFR5cGVWYWx1ZXMgOiBbIm9wdGlvbmFsIiwgInJlcXVpcmVkIl0sCiAgICAgICAgZGF0YVZhbHVlcyA6IFsibGluayIsICJlbWJlZCJdLAogICAgICAgIGhTY3JvbGxQb2xpY3lWYWx1ZXMgOiBbImF1dG8iLCAib2ZmIiwgIm9uIl0sCiAgICAgICAgZGlzYWJsZUFsbFZhbHVlcyA6IFsiMCIsICIxIl0sCiAgICAgICAgZm9ybWF0VGVzdFZhbHVlcyA6IFsid2FybmluZyIsICJkaXNhYmxlZCIsICJlcnJvciJdLAogICAgICAgIG51bGxUZXN0VmFsdWVzIDogWyJkaXNhYmxlZCIsICJlcnJvciIsICJ3YXJuaW5nIiBdLAogICAgICAgIHNjcmlwdFRlc3RWYWx1ZXMgOiBbImVycm9yIiwgImRpc2FibGVkIiwgIndhcm5pbmciXSwKICAgICAgICBhZnRlclZhbHVlcyA6IFsiYXV0byIsICJjb250ZW50QXJlYSIsICJwYWdlQXJlYSIsICJwYWdlRXZlbiIsICJwYWdlT2RkIl0sCiAgICAgICAgYmVmb3JlVmFsdWVzIDogWyJhdXRvIiwgImNvbnRlbnRBcmVhIiwgInBhZ2VBcmVhIiwgInBhZ2VFdmVuIiwgInBhZ2VPZGQiXSwKICAgICAgICBzdGFydE5ld1ZhbHVlcyA6IFsiMCIsICIxIl0sCiAgICAgICAgY2lyY3VsYXJWYWx1ZXMgOiBbIjAiLCAiMSJdLAogICAgICAgIGhhbmRWYWx1ZXMgOiBbImV2ZW4iLCAibGVmdCIsICJyaWdodCJdLAogICAgICAgIGhpZ2hsaWdodFZhbHVlcyA6IFsiaW52ZXJ0ZWQiLCAibm9uZSIsICJvdXRsaW5lIiwgInB1c2giXSwKICAgICAgICBhY3Rpdml0eVZhbHVlcyA6IFsiY2xpY2siLCAiY2hhbmdlIiwgImRvY0Nsb3NlIiwgImRvY1JlYWR5IiwgImVudGVyIiwKICAgICAgICAgICAgImV4aXQiLCAiZnVsbCIsICJpbmRleENoYW5nZSIsICJpbml0aWFsaXplIiwKICAgICAgICAgICAgIm1vdXNlRG93biIsICJtb3VzZUVudGVyIiwgIm1vdXNlRXhpdCIsICJtb3VzZVVwIiwKICAgICAgICAgICAgInBvc3RFeGVjdXRlIiwgInBvc3RPcGVuIiwgInBvc3RQcmludCIsICJwb3N0U2F2ZSIsCiAgICAgICAgICAgICJwb3N0U2lnbiIsICJwb3N0U3VibWl0IiwgInByZUV4ZWN1dGUiLCAicHJlT3BlbiIsCiAgICAgICAgICAgICJwcmVQcmludCIsICJwcmVTYXZlIiwgInByZVNpZ24iLCAicHJlU3VibWl0IiwKICAgICAgICAgICAgInJlYWR5IiwgInZhbGlkYXRpb25TdGF0ZSJdLAogICAgICAgIGxpc3RlblZhbHVlcyA6IFsicmVmT25seSIsICJyZWZBbmREZXNjZW5kZW50cyJdLAogICAgICAgIGJyZWFrVmFsdWVzIDogWyJjbG9zZSIsICJvcGVuIl0sCiAgICAgICAgdGFyZ2V0VHlwZVZhbHVlcyA6IFsiYXV0byIsICJjb250ZW50QXJlYSIsICJwYWdlQXJlYSIsICJwYWdlRXZlbiIsICJwYWdlT2RkIl0sCiAgICAgICAgc2lnblR5cGVWYWx1ZXMgOiBbIlBERjEuMyIsICJQREYxLjYiXSwKICAgICAgICBzaWduRGF0YU9wZXJhdGlvblZhbHVlcyA6IFsic2lnbiIsICJjbGVhciIsICJ2ZXJpZnkiXSwKICAgICAgICBhc3BlY3RWYWx1ZXMgOiBbImZpdCIsICJhY3R1YWwiLCAiaGVpZ2h0IiwgIm5vbmUiLCAid2lkdGgiXSwKICAgICAgICB0cmFuc2ZlckVuY29kaW5nVmFsdWVzIDogWyJub25lIiwgInBhY2thZ2UiLCAiYmFzZTY0Il0sCiAgICAgICAgbWFuaWZlc3RBY3Rpb25WYWx1ZXMgOiBbImluY2x1ZGUiLCAiYWxsIiwgImV4Y2x1ZGUiXSwKICAgICAgICB0cmF2ZXJzZURlbGVnYXRlVmFsdWVzIDogWyIwIiwgIjEiXSwKICAgICAgICB0cmF2ZXJzZU9wZXJhdGlvblZhbHVlcyA6IFsibmV4dCIsICJiYWNrIiwgImRvd24iLCAiZmlyc3QiLCAibGVmdCIsICJyaWdodCIsICJ1cCJdLAogICAgICAgIHNsb3BlVmFsdWVzIDogWyJcXCIsICIvIl0sCiAgICAgICAgZXhjbHVkZUFsbENhcHNWYWx1ZXMgOiBbIjAiLCAiMSJdLAogICAgICAgIGV4Y2x1ZGVJbml0aWFsQ2FwVmFsdWVzIDogWyIwIiwgIjEiXSwKICAgICAgICBoeXBoZW5hdGVWYWx1ZXMgOiBbIjAiLCAiMSJdLAogICAgICAgIGFsbG93TmV1dHJhbFZhbHVlcyA6IFsiMCIsICIxIl0sCiAgICAgICAgbWFya1ZhbHVlcyA6IFsiZGVmYXVsdCIsICJjaGVjayIsICJjaXJjbGUiLCAiY3Jvc3MiLCAiZGlhbW9uZCIsICJzcXVhcmUiLCAic3RhciJdLAogICAgICAgIHNoYXBlVmFsdWVzIDogWyJzcXVhcmUiLCAicm91bmQiXSwKICAgICAgICBjb21taXRPblZhbHVlcyA6IFsgInNlbGVjdCIsICJleGl0Il0sCiAgICAgICAgb3BlblZhbHVlcyA6IFsidXNlckNvbnRyb2wiLCAiYWx3YXlzIiwgIm11bHRpU2VsZWN0IiwgIm9uRW50cnkiIF0sCiAgICAgICAgdGV4dEVudHJ5VmFsdWVzIDogWyIwIiwgIjEiXSwKICAgICAgICBsaW5lYXJUeXBlVmFsdWVzIDogWyJ0b1JpZ2h0IiwgInRvQm90dG9tIiwgInRvTGVmdCIsICJ0b1RvcCJdLAogICAgICAgIGVkZ2VDYXBWYWx1ZXMgOiBbInNxdWFyZSIsICJidXR0IiwgInJvdW5kIl0sCiAgICAgICAgc3Ryb2tlVmFsdWVzIDogWyJzb2xpZCIsICJkYXNoRG90IiwgImRhc2hEb3REb3QiLCAiZGFzaGVkIiwgImRvdHRlZCIsICJlbWJvc3NlZCIsICJldGNoZWQiLCAibG93ZXJlZCIsICJyYWlzZWQiXSwKICAgICAgICBjb3JuZXJJbnZlcnRlZFZhbHVlcyA6IFsiMCIsICIxIl0sCiAgICAgICAgY29ybmVySm9pblZhbHVlcyA6IFsic3F1YXJlIiwicm91bmQiXSwKICAgICAgICBzcGVha0Rpc2FibGVWYWx1ZXMgOiBbIjAiLCAiMSJdLAogICAgICAgIHNwZWFrUHJpb3JpdHlWYWx1ZXMgOiBbICJjdXN0b20iLCAiY2FwdGlvbiIsICJuYW1lIiwgInRvb2xUaXAiXSwKICAgICAgICBjYXB0aW9uUGxhY2VtZW50VmFsdWVzIDogWyJsZWZ0IiwgImJvdHRvbSIsICJpbmxpbmUiLCAicmlnaHQiLCAidG9wIl0sCiAgICAgICAgb3JpZW50YXRpb25WYWx1ZXMgOiBbInBvcnRyYWl0IiwgImxhbmRzY2FwZSJdLAogICAgICAgIG1lZGl1bVRyYXlJblZhbHVlcyA6IFsiYXV0byIsICJkZWxlZ2F0ZSIsICJwYWdlRnJvbnQiXSwKICAgICAgICBtZWRpdW1UcmF5T3V0VmFsdWVzIDogWyJhdXRvIiwgImRlbGVnYXRlIl0sCiAgICAgICAgcGF0dGVyblR5cGVWYWx1ZXMgOiBbImNyb3NzSGF0Y2giLCAiY3Jvc3NEaWFnb25hbCIsICJkaWFnb25hbExlZnQiLCAiZGlhZ29uYWxSaWdodCIsICJob3Jpem9udGFsIiwgInZlcnRpY2FsIl0sCiAgICAgICAga2VlcEludGFjdFZhbHVlcyA6IFsibm9uZSIsICJjb250ZW50QXJlYSIsICJwYWdlQXJlYSJdLAogICAgICAgIGtlZXBOZXh0VmFsdWVzIDogWyJub25lIiwgImNvbnRlbnRBcmVhIiwgInBhZ2VBcmVhIl0sCiAgICAgICAga2VlcFByZXZpb3VzVmFsdWVzIDogWyJub25lIiwgImNvbnRlbnRBcmVhIiwgInBhZ2VBcmVhIl0sCiAgICAgICAgcGFzc1Rocm91Z2hWYWx1ZXMgOiBbIjAiLCAiMSJdLAogICAgICAgIGFsbG93UmljaFRleHRWYWx1ZXMgOiBbIjAiLCAiMSJdLAogICAgICAgIG11bHRpTGluZVZhbHVlcyA6IFsiMSIsICIwIl0sCiAgICAgICAgdlNjcm9sbFBvbGljeVZhbHVlcyA6IFsiYXV0byIsICJvZmYiLCAib24iXSwKICAgICAgICBrZXJuaW5nTW9kZVZhbHVlcyA6IFsibm9uZSIsICJwYWlyIl0sCiAgICAgICAgbGluZVRocm91Z2hWYWx1ZXMgOiBbIjAiLCAiMSIsICIyIl0sCiAgICAgICAgbGluZVRocm91Z2hQZXJpb2RWYWx1ZXMgOiBbImFsbCIsICJ3b3JkIl0sCiAgICAgICAgZm9udE92ZXJsaW5lVmFsdWVzIDogWyIwIiwgIjEiLCAiMiJdLAogICAgICAgIGZvbnRPdmVybGluZVBlcmlvZFZhbHVlcyA6IFsiYWxsIiwgIndvcmQiXSwKICAgICAgICBwb3N0dXJlVmFsdWVzIDogWyJub3JtYWwiLCAiaXRhbGljIl0sCiAgICAgICAgdW5kZXJsaW5lVmFsdWVzIDogWyIwIiwgIjEiLCAiMiJdLAogICAgICAgIHVuZGVybGluZVBlcmlvZFZhbHVlcyA6IFsiYWxsIiwgIndvcmQiXSwKICAgICAgICBmb250V2VpZ2h0VmFsdWVzIDogWyJub3JtYWwiLCAiYm9sZCJdLAogICAgICAgIGNoZWNrc3VtVmFsdWVzIDogWyJub25lIiwgIjFtb2QxMCIsICIxbW9kMTBfMW1vZDExIiwgIjJtb2QxMCIsICJhdXRvIl0sCiAgICAgICAgZGF0YVByZXBWYWx1ZXMgOiBbIm5vbmUiLCAiZmxhdGVDb21wcmVzcyJdLAogICAgICAgIHByaW50Q2hlY2tEaWdpdFZhbHVlcyA6IFsiMCIsICIxIl0sCiAgICAgICAgdGV4dExvY2F0aW9uVmFsdWVzIDogWyJiZWxvdyIsICJiZWxvd0VtYmVkZGVkIiwgIm5vbmUiLCAiYWJvdmUiLCAiYWJvdmVFbWJlZGRlZCJdLAogICAgICAgIHRydW5jYXRlVmFsdWVzIDogWyIwIiwgIjEiXSwKICAgICAgICB1cHNNb2RlVmFsdWVzIDogWyJ1c0NhcnJpZXIiLCAiaW50ZXJuYXRpb25hbENhcnJpZXIiLCAic2VjdXJlU3ltYm9sIiwgInN0YW5kYXJkU3ltYm9sIl0sCiAgICAgICAgbWRwUGVybWlzc2lvbnNWYWx1ZXMgOiBbIjIiLCAiMSIsICIzIl0sCiAgICAgICAgbWRwU2lnbmF0dXJlVHlwZVZhbHVlcyA6IFsiZmlsbGVyIiwgImF1dGhvciJdLAogICAgICAgIGNvbm5lY3RVc2FnZVZhbHVlcyA6IFsiZXhwb3J0QW5kSW1wb3J0IiwgImV4cG9ydE9ubHkiLCAiaW1wb3J0T25seSJdLAogICAgICAgIHJhZGlhbFR5cGVWYWx1ZXMgOiBbInRvRWRnZSIsICJ0b0NlbnRlciJdLAogICAgICAgIGNyZWRlbnRpYWxTZXJ2ZXJQb2xpY3lWYWx1ZXMgOiBbIm9wdGlvbmFsIiwgInJlcXVpcmVkIl0sCiAgICAgICAgZGF0ZVRpbWVFZGl0UGlja2VyVmFsdWVzIDogWyJob3N0IiwgIm5vbmUiXSwKICAgICAgICBiaW5kTWF0Y2hWYWx1ZXMgOiBbIm9uY2UiLCAiZGF0YVJlZiIsICJnbG9iYWwiLCAibm9uZSJdLAogICAgICAgIHJ1bkF0VmFsdWVzIDogWyJjbGllbnQiLCAiYm90aCIsICJzZXJ2ZXIiXSwKICAgICAgICBzdGF0ZWxlc3NWYWx1ZXMgOiBbIjAiLCAiMSJdLAogICAgICAgIGV4ZWN1dGVUeXBlVmFsdWVzIDogWyJpbXBvcnQiLCAicmVtZXJnZSJdLAogICAgICAgIGNhbGNPdmVycmlkZVZhbHVlcyA6IFsiZGlzYWJsZWQiLCAiZXJyb3IiLCAiaWdub3JlIiwgIndhcm5pbmciIF0sCiAgICAgICAgZW1iZWRQREZWYWx1ZXMgOiBbIjAiLCAiMSJdLAogICAgICAgIHN1Ym1pdEZvcm1hdFZhbHVlcyA6IFsieGRwIiwgImZvcm1kYXRhIiwgInBkZiIsICJ1cmxlbmNvZGVkIiwgInhmZCIsICJ4bWwiIF0sCiAgICAgICAgc2V0UmVsYXRpb25WYWx1ZXMgOiBbIm9yZGVyZWQiICwgImNob2ljZSIgLCAidW5vcmRlcmVkIl0sCiAgICAgICAgZmlyc3RUcmF2ZXJzYWwgOiAiZmlyc3QiLAogICAgICAgIG5leHRUcmF2ZXJzYWwgOiAibmV4dCIsCiAgICAgICAgU2NyaWJibGVJbWFnZUZpZWxkIDogIlNjcmliYmxlSW1hZ2VGaWVsZCIsCiAgICAgICAgc2NyaWJibGVDaGFuZ2VFdmVudCA6ICJzY3JpYmJsZUNoYW5nZSIsCiAgICAgICAgY2FsZW5kYXJJY29uTWF4V2lkdGggOiA0MAoKICAgIH07CiAgICB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzID0gQ29uc3RhbnRzOwp9KShfLHhmYWxpYik7CihmdW5jdGlvbihfLCB4ZmFsaWIpewoKdmFyIFhmYVRlbXBsYXRlU2NoZW1hID0ge307Cgp2YXIgVGVtcGxhdGVTY2hlbWEgPSB4ZmFsaWIudGVtcGxhdGUuVGVtcGxhdGVTY2hlbWEgPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpIHsKICAgICAgICB2YXIgZWxlbSA9IG51bGw7CiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImZpZWxkIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbImFjY2VzcyIseGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5hY2Nlc3NWYWx1ZXMsMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsiaCIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJ3IiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbIngiLCJtZWFzdXJlbWVudCIsMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsieSIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJwcmVzZW5jZSIseGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5wcmVzZW5jZVZhbHVlcywwXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJuYW1lIiwic3RyaW5nIiwiIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsicmVsZXZhbnQiLCAic3RyaW5nIiwgIiIgXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJsb2NhbGUiLCJzdHJpbmciLCJlbl9VUyJdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsiaXRlbXMiLCJ6ZXJvT3JUd28iXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJleHRyYXMiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJkZXNjIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsiZXZlbnQiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsidmFsdWUiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJ1aSIsInplcm9Pck9uZSJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbImFzc2lzdCIsInplcm9Pck9uZSJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbImJvcmRlciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbInBhcmEiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJjYXB0aW9uIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsidmFsaWRhdGUiLCJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbIm1hcmdpbiIsICJ6ZXJvT3JPbmUiXSAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsiZm9udCIsICJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJjYWxjdWxhdGUiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJmb3JtYXQiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJiaW5kSXRlbXMiLCJ6ZXJvT3JNb3JlIl0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKTsKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImFyZWEiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsieCIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgWyJ5IiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICBbInJlbGV2YW50IiwgInN0cmluZyIsICIiIF0sCiAgICAgICAgICAgIFsibmFtZSIsInN0cmluZyIsIiJdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZXh0cmFzIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiZGVzYyIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbImZpZWxkIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImRyYXciLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZXhjbEdyb3VwIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImluc3RhbmNlTWFuYWdlciIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJhcmVhIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbInN1YmZvcm0iLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsic3ViZm9ybVNldCIsInplcm9Pck1vcmUiXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsic3ViZm9ybVNldCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJyZWxhdGlvbiIseGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5zZXRSZWxhdGlvblZhbHVlcywwXSwKICAgICAgICAgICAgWyJyZWxldmFudCIsInN0cmluZyIsIiJdLAogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImJvb2tlbmQiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJicmVhayIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbImRlc2MiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJleHRyYXMiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJvY2N1ciIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbIm92ZXJmbG93IiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiYnJlYWtBZnRlciIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJicmVha0JlZm9yZSIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJpbnN0YW5jZU1hbmFnZXIiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsic3ViZm9ybSIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJzdWJmb3JtU2V0IiwiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJjb250ZW50QXJlYSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJuYW1lIiwic3RyaW5nIiwiIl0sCiAgICAgICAgICAgIFsiaCIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgWyJ3IiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICBbIngiLCJtZWFzdXJlbWVudCIsMF0sCiAgICAgICAgICAgIFsicmVsZXZhbnQiLCAic3RyaW5nIiwgIiIgXSwKICAgICAgICAgICAgWyJ5IiwibWVhc3VyZW1lbnQiLDBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZXh0cmFzIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiZGVzYyIsInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJkYXRlIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZGVjaW1hbCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJuYW1lIiwic3RyaW5nIiwiIl0sCiAgICAgICAgICAgIFsibGVhZERpZ2l0cyIsImludGVnZXIiLC0xXSwKICAgICAgICAgICAgWyJmcmFjRGlnaXRzIiwiaW50ZWdlciIsMl0KICAgICAgICBdKTsKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImRyYXciXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiaCIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgWyJ3IiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICBbIngiLCJtZWFzdXJlbWVudCIsMF0sCiAgICAgICAgICAgIFsieSIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgWyJwcmVzZW5jZSIseGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5wcmVzZW5jZVZhbHVlcywwXSwKICAgICAgICAgICAgWyJuYW1lIiwic3RyaW5nIiwiIl0sCiAgICAgICAgICAgIFsiYWNjZXNzIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5hY2Nlc3NWYWx1ZXMsIDBdLCAgLy8gVE9ETyA6IGZpeCBzY2hlbWEgdmlvbGF0aW9uCiAgICAgICAgICAgIFsicmVsZXZhbnQiLCAic3RyaW5nIiwgIiIgXSwKICAgICAgICAgICAgWyJsb2NhbGUiLCJzdHJpbmciLCJlbl9VUyJdCgogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbImRlc2MiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJ2YWx1ZSIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbInVpIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiYm9yZGVyIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZm9udCIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbInBhcmEiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJjYXB0aW9uIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiYXNzaXN0IiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiZm9udCIsICJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJtYXJnaW4iLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImV4Y2xHcm91cCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJhY2Nlc3MiLHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuYWNjZXNzVmFsdWVzLDBdLAogICAgICAgICAgICBbImgiLCJtZWFzdXJlbWVudCIsMF0sCiAgICAgICAgICAgIFsidyIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgWyJ4IiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICBbInkiLCJtZWFzdXJlbWVudCIsMF0sCiAgICAgICAgICAgIFsicmVsZXZhbnQiLCAic3RyaW5nIiwgIiIgXSwKICAgICAgICAgICAgWyJwcmVzZW5jZSIseGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5wcmVzZW5jZVZhbHVlcywwXSwKICAgICAgICAgICAgWyJuYW1lIiwic3RyaW5nIiwiIl0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJkZXNjIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiZmllbGQiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiYXNzaXN0IiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiYm9yZGVyIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsicGFyYSIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImNhcHRpb24iLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJ2YWxpZGF0ZSIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbIm1hcmdpbiIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZmxvYXQiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsibmFtZSIsInN0cmluZyIsIiJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJpbnRlZ2VyIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiaXRlbXMiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsic2F2ZSIseGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5pdGVtU2F2ZVZhbHVlcywwXSwKICAgICAgICAgICAgWyJwcmVzZW5jZSIseGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5wcmVzZW5jZVZhbHVlcywwXSwKICAgICAgICAgICAgWyJuYW1lIiwic3RyaW5nIiwiIl0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJ0ZXh0IiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImludGVnZXIiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZGF0ZSIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJkZWNpbWFsIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImZsb2F0IiwiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJvY2N1ciJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJpbml0aWFsIiwiaW50ZWdlciIsMV0sCiAgICAgICAgICAgIFsibWF4IiwiaW50ZWdlciIsMV0sCiAgICAgICAgICAgIFsibWluIiwiaW50ZWdlciIsMV0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsicGFnZUFyZWEiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsicmVsZXZhbnQiLCAic3RyaW5nIiwgIiIgXSwKICAgICAgICAgICAgWyJuYW1lIiwic3RyaW5nIiwiIl0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJvY2N1ciIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbImV4dHJhcyIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbImRlc2MiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJhcmVhIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImZpZWxkIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImRyYXciLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZXhjbEdyb3VwIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImluc3RhbmNlTWFuYWdlciIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJzdWJmb3JtIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImNvbnRlbnRBcmVhIiwiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInBhZ2VTZXQiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsicmVsZXZhbnQiLCAic3RyaW5nIiwgIiIgXSwKICAgICAgICAgICAgWyJuYW1lIiwic3RyaW5nIiwiIl0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJvY2N1ciIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbImV4dHJhcyIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbInBhZ2VBcmVhIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbInBhZ2VTZXQiLCJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInN1YmZvcm0iXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiYWNjZXNzIix4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmFjY2Vzc1ZhbHVlcywwXSwKICAgICAgICAgICAgWyJoIiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICBbInciLCJtZWFzdXJlbWVudCIsMF0sCiAgICAgICAgICAgIFsieCIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgWyJ5IiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICBbInByZXNlbmNlIix4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnByZXNlbmNlVmFsdWVzLDBdLAogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXSwKICAgICAgICAgICAgWyJyZWxldmFudCIsICJzdHJpbmciLCAiIiBdLAogICAgICAgICAgICBbImxvY2FsZSIsInN0cmluZyIsImVuX1VTIl0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJvY2N1ciIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbImV4dHJhcyIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbImRlc2MiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJwYWdlU2V0IiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsidmFyaWFibGVzIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiYXJlYSIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJmaWVsZCIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJkcmF3IiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImV4Y2xHcm91cCIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJpbnN0YW5jZU1hbmFnZXIiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsic3ViZm9ybSIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJhc3Npc3QiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJib3JkZXIiLCAiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsicGFyYSIsICJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJ2YWxpZGF0ZSIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbInN1YmZvcm1TZXQiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiYmluZCIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbIm1hcmdpbiIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsidGV4dCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJuYW1lIiwic3RyaW5nIiwiIl0sCiAgICAgICAgICAgIFsibWF4Q2hhcnMiLCJpbnRlZ2VyIiwwXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZXhEYXRhIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXSwKICAgICAgICAgICAgWyJtYXhMZW5ndGgiLCJpbnRlZ2VyIiwtMV0sCiAgICAgICAgICAgIFsidHJhbnNmZXJFbmNvZGluZyIseGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy50cmFuc2ZlckVuY29kaW5nVmFsdWVzLDBdLAogICAgICAgICAgICBbImNvbnRlbnRUeXBlIiwic3RyaW5nIiwidGV4dC9wbGFpbiJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZXh0cmFzIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbInRleHQiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiaW50ZWdlciIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJkYXRlIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImRlY2ltYWwiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZmxvYXQiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsidmFsdWUiLCAiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiZXh0cmFzIiwiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJkZXNjIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsidGV4dCIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJpbnRlZ2VyIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImRhdGUiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZGVjaW1hbCIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJmbG9hdCIsInplcm9Pck1vcmUiXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsidmFyaWFibGVzIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiYm9vbGVhbiIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJkYXRlIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImRhdGVUaW1lIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImRlY2ltYWwiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZXhEYXRhIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImZsb2F0IiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImltYWdlIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImludGVnZXIiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsibWFuaWZlc3QiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsic2NyaXB0IiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbInNjcmlwdCIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJ0aW1lIiwiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsicGFyYSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJoQWxpZ24iLCJzdHJpbmciLCJsZWZ0Il0sCiAgICAgICAgICAgIFsibGluZUhlaWdodCIsIm1lYXN1cmVtZW50IiwiMHB0Il0sCiAgICAgICAgICAgIFsibWFyZ2luTGVmdCIsIm1lYXN1cmVtZW50IiwiMGluIl0sCiAgICAgICAgICAgIFsibWFyZ2luUmlnaHQiLCJtZWFzdXJlbWVudCIsIjBpbiJdLAogICAgICAgICAgICBbIm9ycGhhbnMiLCJpbnRlZ2VyIiwwXSwKICAgICAgICAgICAgWyJwcmVzZXJ2ZSIsInN0cmluZyIsIiJdLAogICAgICAgICAgICBbInJhZGl4T2Zmc2V0IiwibWVhc3VyZW1lbnQiLCIwaW4iXSwKICAgICAgICAgICAgWyJzcGFjZUFib3ZlIiwibWVhc3VyZW1lbnQiLCIwaW4iXSwKICAgICAgICAgICAgWyJzcGFjZUJlbG93IiwibWVhc3VyZW1lbnQiLCIwaW4iXSwKICAgICAgICAgICAgWyJ0YWJEZWZhdWx0Iiwic3RyaW5nIiwiIl0sCiAgICAgICAgICAgIFsidGFiU3RvcHMiLCJzdHJpbmciLCIiXSwKICAgICAgICAgICAgWyJ0ZXh0SW5kZW50IiwibWVhc3VyZW1lbnQiLCIwaW4iXSwKICAgICAgICAgICAgWyJ2QWxpZ24iLCJzdHJpbmciLCJ0b3AiXSwKICAgICAgICAgICAgWyJ3aWRvd3MiLCJpbnRlZ2VyIiwwXSwKICAgICAgICAgICAgWyJ3b3JkU3BhY2luZ01heGltdW0iLCJzdHJpbmciLCIiXSwKICAgICAgICAgICAgWyJ3b3JkU3BhY2luZ01pbmltdW0iLCJzdHJpbmciLCIiXSwKICAgICAgICAgICAgWyJ3b3JkU3BhY2luZ09wdGltdW0iLCJzdHJpbmciLCIiXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZW5jcnlwdERhdGEiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsib3BlcmF0aW9uIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5lbmNyeXB0RGF0YU9wZXJhdGlvblZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsidGFyZ2V0IiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJmaWx0ZXIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJtYW5pZmVzdCIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImlzc3VlcnMiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsidHlwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucmVxdWlyZWRUeXBlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJjZXJ0aWZpY2F0ZSIsICJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJpbWFnZUVkaXQiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiZGF0YSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuZGF0YVZhbHVlcywgMSBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiYm9yZGVyIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsibWFyZ2luIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiYm9va2VuZCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJsZWFkZXIiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInRyYWlsZXIiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInJlYXNvbiJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJuYW1lIiwic3RyaW5nIiwiIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJwYXNzd29yZEVkaXQiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiaFNjcm9sbFBvbGljeSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuaFNjcm9sbFBvbGljeVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicGFzc3dvcmRDaGFyIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJib3JkZXIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJtYXJnaW4iLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJ2YWxpZGF0ZSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJkaXNhYmxlQWxsIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5kaXNhYmxlQWxsVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJmb3JtYXRUZXN0IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5mb3JtYXRUZXN0VmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJudWxsVGVzdCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMubnVsbFRlc3RWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInNjcmlwdFRlc3QiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnNjcmlwdFRlc3RWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbIm1lc3NhZ2UiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJwaWN0dXJlIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsic2NyaXB0IiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiYnJlYWsiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiYWZ0ZXIiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmFmdGVyVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJhZnRlclRhcmdldCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsiYmVmb3JlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5iZWZvcmVWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbImJlZm9yZVRhcmdldCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsiYm9va2VuZExlYWRlciIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsiYm9va2VuZFRyYWlsZXIiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbIm92ZXJmbG93TGVhZGVyIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJvdmVyZmxvd1RhcmdldCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsib3ZlcmZsb3dUcmFpbGVyIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJzdGFydE5ldyIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuc3RhcnROZXdWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInRpbWUiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsibmFtZSIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiY2VydGlmaWNhdGUiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsibmFtZSIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsibG9ja0RvY3VtZW50Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnJlcXVpcmVkVHlwZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiYXJjIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImNpcmN1bGFyIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5jaXJjdWxhclZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsiaGFuZCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuaGFuZFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsic3RhcnRBbmdsZSIsICJzdHJpbmciLCAiMCIgXSAgLAogICAgICAgICAgICBbInN3ZWVwQW5nbGUiLCAic3RyaW5nIiwgIjM2MCIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImVkZ2UiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJmaWxsIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiYnV0dG9uIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImhpZ2hsaWdodCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuaGlnaGxpZ2h0VmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJldmVudCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJhY3Rpdml0eSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuYWN0aXZpdHlWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbImxpc3RlbiIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMubGlzdGVuVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJuYW1lIiwgInN0cmluZyIsICIiIF0sCiAgICAgICAgICAgIFsicmVmIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJlbmNyeXB0RGF0YSIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJleGVjdXRlIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbInNjcmlwdCIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJzaWduRGF0YSIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJzdWJtaXQiLCAib25lT2ZDaGlsZCJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiYm9vbGVhbiJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJuYW1lIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJtYXJnaW4iXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiYm90dG9tSW5zZXQiLCAibWVhc3VyZW1lbnQiLCAiMGluIiBdICAsCiAgICAgICAgICAgIFsibGVmdEluc2V0IiwgIm1lYXN1cmVtZW50IiwgIjBpbiIgXSAgLAogICAgICAgICAgICBbInJpZ2h0SW5zZXQiLCAibWVhc3VyZW1lbnQiLCAiMGluIiBdICAsCiAgICAgICAgICAgIFsidG9wSW5zZXQiLCAibWVhc3VyZW1lbnQiLCAiMGluIiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiYm9yZGVyIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImJyZWFrIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5icmVha1ZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsiaGFuZCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuaGFuZFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicHJlc2VuY2UiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnByZXNlbmNlVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJyZWxldmFudCIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiY29ybmVyIiwgInplcm9PckZvdXIiXSAgLAogICAgICAgICAgICBbImVkZ2UiLCAiemVyb09yRm91ciJdICAsCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZmlsbCIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbIm1hcmdpbiIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImJyZWFrQWZ0ZXIiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsibGVhZGVyIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJzdGFydE5ldyIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuc3RhcnROZXdWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInRhcmdldCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidGFyZ2V0VHlwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMudGFyZ2V0VHlwZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsidHJhaWxlciIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsic2NyaXB0IiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsic2lnbmF0dXJlIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnNpZ25UeXBlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJib3JkZXIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJmaWx0ZXIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJtYW5pZmVzdCIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbIm1hcmdpbiIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInNpZ25EYXRhIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm9wZXJhdGlvbiIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuc2lnbkRhdGFPcGVyYXRpb25WYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInJlZiIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidGFyZ2V0IiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJmaWx0ZXIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJtYW5pZmVzdCIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImltYWdlIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImFzcGVjdCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuYXNwZWN0VmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJjb250ZW50VHlwZSIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsiaHJlZiIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsibmFtZSIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidHJhbnNmZXJFbmNvZGluZyIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMudHJhbnNmZXJFbmNvZGluZ1ZhbHVlcywgMiBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsib2lkcyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJ0eXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5yZXF1aXJlZFR5cGVWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbIm9pZCIsICJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJzb2xpZCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbIm1hbmlmZXN0Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImFjdGlvbiIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMubWFuaWZlc3RBY3Rpb25WYWx1ZXMsIDAgXSwKICAgICAgICAgICAgWyJuYW1lIiwgInN0cmluZyIsICIyIiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsicmVmIiwgInplcm9Pck1vcmUiXQogICAgICAgIF0pOwoKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJ0cmF2ZXJzZSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJkZWxlZ2F0ZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMudHJhdmVyc2VEZWxlZ2F0ZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsib3BlcmF0aW9uIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy50cmF2ZXJzZU9wZXJhdGlvblZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicmVmIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJzY3JpcHQiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJsaW5lIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImhhbmQiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmhhbmRWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInNsb3BlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5zbG9wZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZWRnZSIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImRpZ2VzdE1ldGhvZHMiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsidHlwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucmVxdWlyZWRUeXBlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJkaWdlc3RNZXRob2QiLCAiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsicmVhc29ucyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJ0eXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5yZXF1aXJlZFR5cGVWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbInJlYXNvbiIsICJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJkZWZhdWx0VWkiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJoeXBoZW5hdGlvbiJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJleGNsdWRlQWxsQ2FwcyIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuZXhjbHVkZUFsbENhcHNWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbImV4Y2x1ZGVJbml0aWFsQ2FwIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5leGNsdWRlSW5pdGlhbENhcFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsiaHlwaGVuYXRlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5oeXBoZW5hdGVWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbImxhZGRlckNvdW50IiwgImludGVnZXIiLCAyIF0gICwKICAgICAgICAgICAgWyJwdXNoQ2hhcmFjdGVyQ291bnQiLCAiaW50ZWdlciIsIDMgXSAgLAogICAgICAgICAgICBbInJlbWFpbkNoYXJhY3RlckNvdW50IiwgImludGVnZXIiLCAzIF0gICwKICAgICAgICAgICAgWyJ3b3JkQ2hhcmFjdGVyQ291bnQiLCAiaW50ZWdlciIsIDcgXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInJlY3RhbmdsZSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJoYW5kIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5oYW5kVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJjb3JuZXIiLCAiemVyb09yRm91ciJdICAsCiAgICAgICAgICAgIFsiZWRnZSIsICJ6ZXJvT3JGb3VyIl0gICwKICAgICAgICAgICAgWyJmaWxsIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZW5jcnlwdGlvbk1ldGhvZCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImNoZWNrQnV0dG9uIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImFsbG93TmV1dHJhbCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuYWxsb3dOZXV0cmFsVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJtYXJrIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5tYXJrVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJzaGFwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuc2hhcGVWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInNpemUiLCAic3RyaW5nIiwgIjEwcHQiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJib3JkZXIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJtYXJnaW4iLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJjaG9pY2VMaXN0Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImNvbW1pdE9uIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5jb21taXRPblZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsib3BlbiIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMub3BlblZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsidGV4dEVudHJ5IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy50ZXh0RW50cnlWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImJvcmRlciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbIm1hcmdpbiIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbIm9pZCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJuYW1lIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJlbmNvZGluZyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInVpIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsicGljdHVyZSIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImJhcmNvZGUiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsiYnV0dG9uIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbImNoZWNrQnV0dG9uIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbImNob2ljZUxpc3QiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsiZGF0ZVRpbWVFZGl0IiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbImRlZmF1bHRVaSIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJleE9iamVjdCIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJpbWFnZUVkaXQiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsibnVtZXJpY0VkaXQiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsicGFzc3dvcmRFZGl0IiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbInNpZ25hdHVyZSIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJ0ZXh0RWRpdCIsICJvbmVPZkNoaWxkIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJsaW5lYXIiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsidHlwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMubGluZWFyVHlwZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiY29sb3IiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJlZGdlIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImNhcCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuZWRnZUNhcFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicHJlc2VuY2UiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnByZXNlbmNlVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJzdHJva2UiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnN0cm9rZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsidGhpY2tuZXNzIiwgInN0cmluZyIsICIwLjVwdCIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImNvbG9yIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiY29ybmVyIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImludmVydGVkIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5jb3JuZXJJbnZlcnRlZFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsiam9pbiIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuY29ybmVySm9pblZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicHJlc2VuY2UiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnByZXNlbmNlVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJyYWRpdXMiLCAic3RyaW5nIiwgIjBpbiIgXSAgLAogICAgICAgICAgICBbInN0cm9rZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuc3Ryb2tlVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJ0aGlja25lc3MiLCAic3RyaW5nIiwgIjAuMDVwdCIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImNvbG9yIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsidG9vbFRpcCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJyaWQiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInNwZWFrIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImRpc2FibGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnNwZWFrRGlzYWJsZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicHJpb3JpdHkiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnNwZWFrUHJpb3JpdHlWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInJpZCIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiY2FwdGlvbiJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJwbGFjZW1lbnQiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmNhcHRpb25QbGFjZW1lbnRWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInByZXNlbmNlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5wcmVzZW5jZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicmVzZXJ2ZSIsICJzdHJpbmciLCAiLTEiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJmb250IiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsibWFyZ2luIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsicGFyYSIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbInZhbHVlIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiY29tYiJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJudW1iZXJPZkNlbGxzIiwgImludGVnZXIiLCAwIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJtZWRpdW0iXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiaW1hZ2luZ0JCb3giLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbImxvbmciLCAic3RyaW5nIiwgIjBpbiIgXSAgLAogICAgICAgICAgICBbIm9yaWVudGF0aW9uIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5vcmllbnRhdGlvblZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsic2hvcnQiLCAic3RyaW5nIiwgIjBpbiIgXSAgLAogICAgICAgICAgICBbInN0b2NrIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJ0cmF5SW4iLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLm1lZGl1bVRyYXlJblZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsidHJheU91dCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMubWVkaXVtVHJheU91dFZhbHVlcywgMCBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsicmVmIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsicGF0dGVybiJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJ0eXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5wYXR0ZXJuVHlwZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiY29sb3IiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJrZWVwIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImludGFjdCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMua2VlcEludGFjdFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsibmV4dCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMua2VlcE5leHRWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInByZXZpb3VzIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5rZWVwUHJldmlvdXNWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImRpZ2VzdE1ldGhvZCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInNpZ25pbmciXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsidHlwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucmVxdWlyZWRUeXBlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJjZXJ0aWZpY2F0ZSIsICJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJlbmNyeXB0aW9uIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnJlcXVpcmVkVHlwZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiY2VydGlmaWNhdGUiLCAiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsic3ViamVjdEROcyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJ0eXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5yZXF1aXJlZFR5cGVWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbInN1YmplY3RETiIsICJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJlbmNyeXB0Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiY2VydGlmaWNhdGUiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJ2YWx1ZSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJvdmVycmlkZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMudmFsdWVPdmVycmlkZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicmVsZXZhbnQiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImFyYyIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJib29sZWFuIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbImRhdGUiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsiZGF0ZVRpbWUiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsiZGVjaW1hbCIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJleERhdGEiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsiZmxvYXQiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsiaW1hZ2UiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsiaW50ZWdlciIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJsaW5lIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbInJlY3RhbmdsZSIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJ0ZXh0IiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbInRpbWUiLCAib25lT2ZDaGlsZCJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsidHJhdmVyc2FsIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInBhc3NUaHJvdWdoIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5wYXNzVGhyb3VnaFZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsidHJhdmVyc2UiLCAiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsidGV4dEVkaXQiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiYWxsb3dSaWNoVGV4dCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuYWxsb3dSaWNoVGV4dFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsiaFNjcm9sbFBvbGljeSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuaFNjcm9sbFBvbGljeVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsibXVsdGlMaW5lIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5tdWx0aUxpbmVWYWx1ZXMsIDEgXSAgLAogICAgICAgICAgICBbInZTY3JvbGxQb2xpY3kiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnZTY3JvbGxQb2xpY3lWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImJvcmRlciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImNvbWIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJtYXJnaW4iLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJzdGlwcGxlIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInJhdGUiLCAiaW50ZWdlciIsIDUwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJjb2xvciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImZvbnQiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiYmFzZWxpbmVTaGlmdCIsICJzdHJpbmciLCAiMGluIiBdICAsCiAgICAgICAgICAgIFsiZm9udEhvcml6b250YWxTY2FsZSIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsiZm9udFZlcnRpY2FsU2NhbGUiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbImtlcm5pbmdNb2RlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5rZXJuaW5nTW9kZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsibGV0dGVyU3BhY2luZyIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsibGluZVRocm91Z2giLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmxpbmVUaHJvdWdoVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJsaW5lVGhyb3VnaFBlcmlvZCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMubGluZVRocm91Z2hQZXJpb2RWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbIm92ZXJsaW5lIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5mb250T3ZlcmxpbmVWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbIm92ZXJsaW5lUGVyaW9kIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5mb250T3ZlcmxpbmVQZXJpb2RWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInBvc3R1cmUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnBvc3R1cmVWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInNpemUiLCAic3RyaW5nIiwgIjEwcHQiIF0gICwKICAgICAgICAgICAgWyJ0eXBlZmFjZSIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidW5kZXJsaW5lIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy51bmRlcmxpbmVWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInVuZGVybGluZVBlcmlvZCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMudW5kZXJsaW5lUGVyaW9kVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJ3ZWlnaHQiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmZvbnRXZWlnaHRWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImZpbGwiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJiYXJjb2RlIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImNoYXJFbmNvZGluZyIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsiY2hlY2tzdW0iLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmNoZWNrc3VtVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJkYXRhQ29sdW1uQ291bnQiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbImRhdGFMZW5ndGgiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbImRhdGFQcmVwIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5kYXRhUHJlcFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsiZGF0YVJvd0NvdW50IiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJlbmRDaGFyIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJlcnJvckNvcnJlY3Rpb25MZXZlbCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsibW9kdWxlSGVpZ2h0IiwgInN0cmluZyIsICI1bW0iIF0gICwKICAgICAgICAgICAgWyJtb2R1bGVXaWR0aCIsICJzdHJpbmciLCAiMC4yNW1tIiBdICAsCiAgICAgICAgICAgIFsicHJpbnRDaGVja0RpZ2l0IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5wcmludENoZWNrRGlnaXRWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInJvd0NvbHVtblJhdGlvIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJzdGFydENoYXIiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInRleHRMb2NhdGlvbiIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMudGV4dExvY2F0aW9uVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJ0cnVuY2F0ZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMudHJ1bmNhdGVWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInR5cGUiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInVwc01vZGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnVwc01vZGVWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbIndpZGVOYXJyb3dSYXRpbyIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZW5jcnlwdCIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImFzc2lzdCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJyb2xlIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJzcGVhayIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbInRvb2xUaXAiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJicmVha0JlZm9yZSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJsZWFkZXIiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInN0YXJ0TmV3IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5zdGFydE5ld1ZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsidGFyZ2V0IiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJ0YXJnZXRUeXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy50YXJnZXRUeXBlVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJ0cmFpbGVyIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJzY3JpcHQiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJmb3JtYXQiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJwaWN0dXJlIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsia2V5VXNhZ2UiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiY3JsU2lnbiIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsiZGF0YUVuY2lwaGVybWVudCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsiZGVjaXBoZXJPbmx5IiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJkaWdpdGFsU2lnbmF0dXJlIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJlbmNpcGhlck9ubHkiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbImtleUFncmVlbWVudCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsia2V5Q2VydFNpZ24iLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbImtleUVuY2lwaGVybWVudCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsibm9uUmVwdWRpYXRpb24iLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnJlcXVpcmVkVHlwZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CgoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInBpY3R1cmUiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbIm1kcCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJwZXJtaXNzaW9ucyIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMubWRwUGVybWlzc2lvbnNWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInNpZ25hdHVyZVR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLm1kcFNpZ25hdHVyZVR5cGVWYWx1ZXMsIDAgXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbIm92ZXJmbG93Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImxlYWRlciIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidGFyZ2V0IiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJ0cmFpbGVyIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJudW1lcmljRWRpdCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJoU2Nyb2xsUG9saWN5IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5oU2Nyb2xsUG9saWN5VmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJib3JkZXIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJjb21iIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsibWFyZ2luIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiYXBwZWFyYW5jZUZpbHRlciJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJ0eXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5yZXF1aXJlZFR5cGVWYWx1ZXMsIDAgXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImZpbHRlciJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJhZGRSZXZvY2F0aW9uSW5mbyIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsibmFtZSIsICJzdHJpbmciLCAiIiBdLAogICAgICAgICAgICBbInZlcnNpb24iLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImFwcGVhcmFuY2VGaWx0ZXIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJjZXJ0aWZpY2F0ZXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJkaWdlc3RNZXRob2RzIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZW5jb2RpbmdzIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZW5jcnlwdGlvbk1ldGhvZHMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJoYW5kbGVyIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsibG9ja0RvY3VtZW50IiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsibWRwIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsicmVhc29ucyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbInRpbWVTdGFtcCIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInJlbmRlckFzIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIkFQSVZlcnNpb24iLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbInN2ZyIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInRpbWVTdGFtcCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJzZXJ2ZXIiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnJlcXVpcmVkVHlwZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiY29ubmVjdCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJjb25uZWN0aW9uIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJyZWYiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInVzYWdlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5jb25uZWN0VXNhZ2VWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbInBpY3R1cmUiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJkYXRlVGltZSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJuYW1lIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJiaW5kSXRlbXMiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiY29ubmVjdGlvbiIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsibGFiZWxSZWYiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInJlZiIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidmFsdWVSZWYiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImVuY29kaW5ncyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJ0eXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5yZXF1aXJlZFR5cGVWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImVuY29kaW5nIiwgInplcm9Pck1vcmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInJhZGlhbCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJ0eXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5yYWRpYWxUeXBlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJjb2xvciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImNlcnRpZmljYXRlcyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJjcmVkZW50aWFsU2VydmVyUG9saWN5IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5jcmVkZW50aWFsU2VydmVyUG9saWN5VmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJ1cmwiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInVybFBvbGljeSIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZW5jcnlwdGlvbiIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImlzc3VlcnMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJrZXlVc2FnZSIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbIm9pZHMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJzaWduaW5nIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsic3ViamVjdEROcyIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInN2ZyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJoZWlnaHQiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInZpZXdCb3giLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbIndpZHRoIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJmaWxsIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInByZXNlbmNlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5wcmVzZW5jZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiY29sb3IiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJsaW5lYXIiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsicGF0dGVybiIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJyYWRpYWwiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsic29saWQiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsic3RpcHBsZSIsICJvbmVPZkNoaWxkIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJzZXRQcm9wZXJ0eSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJjb25uZWN0aW9uIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJyZWYiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInRhcmdldCIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZW5jcnlwdGlvbk1ldGhvZHMiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsidHlwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucmVxdWlyZWRUeXBlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJlbmNyeXB0aW9uTWV0aG9kIiwgInplcm9Pck1vcmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImRhdGVUaW1lRWRpdCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJoU2Nyb2xsUG9saWN5IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5oU2Nyb2xsUG9saWN5VmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJwaWNrZXIiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmRhdGVUaW1lRWRpdFBpY2tlclZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiYm9yZGVyIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiY29tYiIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbIm1hcmdpbiIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbIm1lc3NhZ2UiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJ0ZXh0IiwgInplcm9Pck1vcmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImNvbG9yIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImNTcGFjZSIsICJzdHJpbmciLCAiU1JHQiIgXSAgLAogICAgICAgICAgICBbInZhbHVlIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJzdWJqZWN0RE4iXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiZGVsaW1pdGVyIiwgInN0cmluZyIsICIiIF0sCiAgICAgICAgICAgIFsibmFtZSIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiYmluZCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJtYXRjaCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuYmluZE1hdGNoVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJyZWYiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbInBpY3R1cmUiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJoYW5kbGVyIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnJlcXVpcmVkVHlwZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsib2NjdXIiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiaW5pdGlhbCIsICJpbnRlZ2VyIiwgMSBdICAsCiAgICAgICAgICAgIFsibWF4IiwgImludGVnZXIiLCAxIF0gICwKICAgICAgICAgICAgWyJtaW4iLCAiaW50ZWdlciIsIDEgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbInNjcmlwdCIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsic2NyaXB0Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImJpbmRpbmciLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbImNvbnRlbnRUeXBlIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJuYW1lIiwgInN0cmluZyIsICIiIF0sCiAgICAgICAgICAgIFsicnVuQXQiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnJ1bkF0VmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJzdGF0ZWxlc3MiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnN0YXRlbGVzc1ZhbHVlcywgMCBdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJleGVjdXRlIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImNvbm5lY3Rpb24iLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbImV4ZWN1dGVUeXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5leGVjdXRlVHlwZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicnVuQXQiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnJ1bkF0VmFsdWVzLCAwIF0KICAgICAgICBdKTsKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImNhbGN1bGF0ZSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJvdmVycmlkZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuY2FsY092ZXJyaWRlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJtZXNzYWdlIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsic2NyaXB0IiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJzdWJtaXQiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiZW1iZWRQREYiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmVtYmVkUERGVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJmb3JtYXQiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnN1Ym1pdEZvcm1hdFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsidGFyZ2V0IiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJ0ZXh0RW5jb2RpbmciLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInhkcENvbnRlbnQiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImVuY3J5cHQiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJlbmNyeXB0RGF0YSIsICJ6ZXJvT3JNb3JlIl0gICwKICAgICAgICAgICAgWyJzaWduRGF0YSIsICJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCiAgICB9LAoKICAgIGFkZEF0dHJpYnV0ZXM6IGZ1bmN0aW9uKGVsZW1lbnQsYXR0ckFycmF5KSB7CiAgICAgICAgXy5lYWNoKGF0dHJBcnJheSwgZnVuY3Rpb24oZWxlbSkgewogICAgICAgICAgICBlbGVtZW50LmF0dHJpYnV0ZXNbZWxlbVswXV0gPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOmVsZW1bMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGVmYXVsdCI6ZWxlbVsyXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9LAoKICAgIGFkZENoaWxkcmVuOiBmdW5jdGlvbihlbGVtZW50LGNoaWxkcmVuQXJyYXkpIHsKICAgICAgICBfLmVhY2goY2hpbGRyZW5BcnJheSwgZnVuY3Rpb24oZWxlbSkgewogICAgICAgICAgICBlbGVtZW50LmNoaWxkcmVuW2VsZW1bMF1dID0gewogICAgICAgICAgICAgICAgcmVsYXRpb24gOiB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzW2VsZW1bMV1dCiAgICAgICAgICAgIH07CiAgICAgICAgfSk7CiAgICB9LAoKICAgIGNyZWF0ZUVsZW1lbnQ6IGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiB7YXR0cmlidXRlczoge30sY2hpbGRyZW46IHt9fTsKICAgIH0sCgogICAgZ2V0RGVmYXVsdEF0dHJpYnV0ZTogZnVuY3Rpb24oZWxlbWVudCxhdHRyaWJ1dGUpIHsKICAgICAgICB2YXIgZWxlbSA9ICBYZmFUZW1wbGF0ZVNjaGVtYVtlbGVtZW50XTsKICAgICAgICBpZighZWxlbSkKICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIHZhciBhdHRyID0gZWxlbS5hdHRyaWJ1dGVzW2F0dHJpYnV0ZV07CiAgICAgICAgaWYoIWF0dHIpCiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgaWYoYXR0ci50eXBlIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgICAgICAgcmV0dXJuIGF0dHIudHlwZVthdHRyWyJkZWZhdWx0Il1dOwogICAgICAgIH0gZWxzZQogICAgICAgICAgICByZXR1cm4gYXR0clsiZGVmYXVsdCJdOwogICAgfSwKCiAgICBoYXNBdHRyaWJ1dGU6IGZ1bmN0aW9uIChlbGVtZW50LCBhdHRyaWJ1dGUpIHsKICAgICAgICB2YXIgZWxlbSA9IFhmYVRlbXBsYXRlU2NoZW1hW2VsZW1lbnRdOwogICAgICAgIGlmICghZWxlbSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiBfLmhhcyhlbGVtLmF0dHJpYnV0ZXMsIGF0dHJpYnV0ZSk7CiAgICB9LAoKICAgIGdldENoaWxkcmVuIDogZnVuY3Rpb24oZWxlbWVudCl7CiAgICAgICAgaWYoWGZhVGVtcGxhdGVTY2hlbWFbZWxlbWVudF0pCiAgICAgICAgICAgIHJldHVybiBYZmFUZW1wbGF0ZVNjaGVtYVtlbGVtZW50XS5jaGlsZHJlbjsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgfSwKCiAgICBfZ2V0UmVsYXRpb246IGZ1bmN0aW9uKHBhcmVudCxjaGlsZCkgewogICAgICAgdmFyIHAgPSBYZmFUZW1wbGF0ZVNjaGVtYVtwYXJlbnRdOwogICAgICAgaWYoIXApCiAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgIHZhciBjID0gcC5jaGlsZHJlbltjaGlsZF0KICAgICAgIGlmKGMpCiAgICAgICAgICAgcmV0dXJuIGMucmVsYXRpb247CiAgICAgICByZXR1cm4gbnVsbDsKICAgIH0sCgogICAgX2dldERhdGFUeXBlOiBmdW5jdGlvbihlbGVtZW50LGF0dHJpYnV0ZSkgewogICAgICAgIHZhciBhdHRyID0gIFhmYVRlbXBsYXRlU2NoZW1hW2VsZW1lbnRdLmF0dHJpYnV0ZXNbYXR0cmlidXRlXTsKICAgICAgICByZXR1cm4gYXR0ci50eXBlOwogICAgfSwKCiAgICBfZ2V0T25lT2ZDaGlsZDogZnVuY3Rpb24oZWxlbWVudCkgewogICAgICAgIHZhciByZXMgPSB7fTsKICAgICAgICBfLmVhY2goWGZhVGVtcGxhdGVTY2hlbWFbZWxlbWVudF0uY2hpbGRyZW4sCiAgICAgICAgICAgIGZ1bmN0aW9uKG9iaixjbGFzKSB7CiAgICAgICAgICAgICAgICBpZihvYmoucmVsYXRpb24udHlwZSA9PSAib25lT2ZDaGlsZCIpCiAgICAgICAgICAgICAgICAgICAgcmVzW2NsYXNdID0gdHJ1ZQogICAgICAgICAgICB9KTsKICAgICAgICByZXR1cm4gcmVzOwogICAgfQoKfSk7Cn0pKF8sIHhmYWxpYik7Ci8qKgogKiBAcGFja2FnZSB4ZmFsaWIudXQuVmVyc2lvbgogKiBAaW1wb3J0IHhmYWxpYi51dC5DbGFzcwogKi8KCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIFZlcnNpb24gPSB4ZmFsaWIudXQuVmVyc2lvbiA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewoKICAgICAgICBFUzQ6IDExMDAsCiAgICAgICAgRVM0U1AxOiAxMTAxLAogICAgICAgIFA5QTogMTEwMiwgLy9hZGRlZCBuZXcgdmVyc2lvbiBmb3IgUDlBIC0+IG5vdCBiZWluZyB1c2VkIGJ1dCBzdGlsbCBpZiB3ZSBuZWVkIHNvbWVkYXkKCiAgICAgICAgY3VycmVudDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLlA5QTsKICAgICAgICB9LAoKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24ob3B0aW9ucyl7CiAgICAgICAgICAgIFZlcnNpb24uX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgdGhpcy5fb3JpZ2luYWxWZXJzaW9uID0gb3B0aW9ucyAhPSBudWxsID8gb3B0aW9ucy5vcmlnaW5hbFZlcnNpb24gOiB0aGlzLmN1cnJlbnQoKTsKICAgICAgICAgICAgdGhpcy5fb3ZlcnJpZGUgPSBvcHRpb25zID8gb3B0aW9ucy5vdmVycmlkZSA6IHt9IDsKICAgICAgICAgICAgaWYoIXRoaXMuX292ZXJyaWRlKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9vdmVycmlkZSA9IHt9OwogICAgICAgICAgICB9CiAgICAgICAgfSwKCgogICAgICAgIGlzU2FtZSA6IGZ1bmN0aW9uKHYpIHsKICAgICAgICAgICAgcmV0dXJuICh0aGlzLl9vcmlnaW5hbFZlcnNpb24gPT0gdik7CiAgICAgICAgfSwKCiAgICAgICAgaXNBZnRlcjogZnVuY3Rpb24odikgewogICAgICAgICAgICByZXR1cm4gKHRoaXMuX29yaWdpbmFsVmVyc2lvbiA+IHYpOwogICAgICAgIH0sCgogICAgICAgIGlzQWZ0ZXJPclNhbWUgOiBmdW5jdGlvbih2KSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmlzQWZ0ZXIodikgfHwgdGhpcy5pc1NhbWUodik7CiAgICAgICAgfSwKCiAgICAgICAgaXNQcmV2aW91czogZnVuY3Rpb24odikgewogICAgICAgICAgICByZXR1cm4gKHRoaXMuX29yaWdpbmFsVmVyc2lvbiA8IHYpOwogICAgICAgIH0sCgogICAgICAgIGlzUHJldmlvdXNPclNhbWUgOiBmdW5jdGlvbih2KSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmlzUHJldmlvdXModikgfHwgdGhpcy5pc1NhbWUodik7CiAgICAgICAgfSwKCiAgICAgICAgaXNPbiA6IGZ1bmN0aW9uKGZsYWcpIHsKICAgICAgICAgICAgLy9mdW5jdGlvbiB0byBjb250cm9sIGlmIGEgcGFydGljdWxhciBmbGFnIGlzIG9uCiAgICAgICAgICAgIC8vc2luY2UgaXQgbWlnaHQgZGVwZW5kZW50IG9uIHZlcnNpb24gc28gaXQgaXMgaW4gVmVyc2lvbiBjbGFzcwogICAgICAgICAgIHJldHVybih0aGlzLl9vdmVycmlkZVtmbGFnXSk7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRBc3Npc3QgPSB7CiAgICAgICAgcHJvcGVydHlEZXNjcmlwdG9ycyA6IHsKICAgICAgICAgICAgImFzc2lzdCIgOiB7CiAgICAgICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJhc3Npc3QiLCAwKTsKICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiYXNzaXN0Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0pKF8sIHhmYWxpYik7CgoKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQm9yZGVyID0gewogICAgICAgIHByb3BlcnR5RGVzY3JpcHRvcnMgOiB7CiAgICAgICAgICAgICJib3JkZXIiIDogewogICAgICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiYm9yZGVyIiwgMCk7CiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImJvcmRlciIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9KShfLCB4ZmFsaWIpOwoKCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZENhcHRpb24gPSB7CiAgICAgICAgcHJvcGVydHlEZXNjcmlwdG9ycyA6IHsKICAgICAgICAgICAgImNhcHRpb24iIDogewogICAgICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiY2FwdGlvbiIsIDApOwogICAgICAgICAgICAgICAgfSwKCiAgICAgICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJjYXB0aW9uIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0pKF8sIHhmYWxpYik7CgoKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkUHJlc2VuY2UgPSB7CiAgICAgICAgcHJvcGVydHlEZXNjcmlwdG9ycyA6IHsKICAgICAgICAgICAgInByZXNlbmNlIiA6IHsKICAgICAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIC8vQXZvaWRlZCBnZXRBdHRyaWJ1dGUgY2FsbCB0byBhdm9pZCBhbnkgcmVncmVzc2lvbiBpbiBjYXNlIHNvbWV0aGluZyBpcyBtaXNzaW5nIGluIFRlbXBsYXRlIFNjaGVtYQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5wcmVzZW5jZSwgeGZhbGliLnNjcmlwdC5Ob2RlLnByb3RvdHlwZS5fZGVmYXVsdHMucHJlc2VuY2UpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHNQcmVzZW5jZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBvbGRQcmVzZW5jZSA9IHRoaXMuanNvbk1vZGVsLnByZXNlbmNlOwogICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHNQcmVzZW5jZSwgInByZXNlbmNlIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuanNvbk1vZGVsLnByZXNlbmNlICE9IG9sZFByZXNlbmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NhbGN1bGF0ZUVmZmVjdGl2ZVByZXNlbmNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLCJwcmVzZW5jZSIsb2xkUHJlc2VuY2UsdGhpcy5qc29uTW9kZWwucHJlc2VuY2UpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfSkoXyx4ZmFsaWIpOwoKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkWFlXSCA9IHsKICAgICAgICBwcm9wZXJ0eURlc2NyaXB0b3JzIDogewogICAgICAgICAgICAiaCIgOiB7CiAgICAgICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwuaCwgeGZhbGliLnNjcmlwdC5Ob2RlLnByb3RvdHlwZS5fZGVmYXVsdHMuaCk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwiaCIpOwogICAgICAgICAgICAgICAgICAgIHZhciBldmVudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLCJoIix2YWx1ZSwgdmFsdWUpOwogICAgICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldmVudC5uYW1lLGV2ZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgICJ3IiA6IHsKICAgICAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC53LCB4ZmFsaWIuc2NyaXB0Lk5vZGUucHJvdG90eXBlLl9kZWZhdWx0cy53KTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBzZXQgOiBmdW5jdGlvbigpIHsKCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAieCIgOiB7CiAgICAgICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwueCwgeGZhbGliLnNjcmlwdC5Ob2RlLnByb3RvdHlwZS5fZGVmYXVsdHMueCk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24oKSB7CgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgInkiIDogewogICAgICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JFbHNlKHRoaXMuanNvbk1vZGVsLnksIHhmYWxpYi5zY3JpcHQuTm9kZS5wcm90b3R5cGUuX2RlZmF1bHRzLnkpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKCkgewoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfSkoXyx4ZmFsaWIpOwoKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkRmlsbENvbG9yID0gewogICAgICAgIHByb3BlcnR5RGVzY3JpcHRvcnMgOiB7CiAgICAgICAgICAgICJmaWxsQ29sb3IiIDogewogICAgICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICByZXR1cm4gKHRoaXMuYm9yZGVyLmZpbGwuY29sb3IudmFsdWUgPT0gIiIpID8gIjI1NSwyNTUsMjU1IiA6IHRoaXMuYm9yZGVyLmZpbGwuY29sb3IudmFsdWU7CiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKGNvbG9yKSB7CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5ib3JkZXIgJiYgdGhpcy5ib3JkZXIuZmlsbCAmJiB0aGlzLmJvcmRlci5maWxsLmNvbG9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYm9yZGVyLmZpbGwucHJlc2VuY2U9InZpc2libGUiOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJvcmRlci5maWxsLmNvbG9yLnZhbHVlID0gY29sb3I7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9KShfLHhmYWxpYik7CihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZEJvcmRlckNvbG9yID0gewogICAgICAgIHByb3BlcnR5RGVzY3JpcHRvcnMgOiB7CiAgICAgICAgICAgICJib3JkZXJDb2xvciIgOiB7CiAgICAgICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5ib3JkZXIuZWRnZS5jb2xvci52YWx1ZTsKICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24oY29sb3IpIHsKICAgICAgICAgICAgICAgICAgICAvL1RPRE86IFNldCBib3JkZXIuZWRnZS5wcmVzZW5jZSBwcm9wZXJ0eSB0byB2aXNpYmxlIG9uY2UgQm9yZGVyIGlzIGltcGxlbWVudGVkCiAgICAgICAgICAgICAgICAgICAgdGhpcy5ib3JkZXIuZWRnZS5jb2xvci52YWx1ZSA9IGNvbG9yIDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfSkoXywgeGZhbGliKTsKCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZEJvcmRlcldpZHRoID0gewogICAgICAgIHByb3BlcnR5RGVzY3JpcHRvcnMgOiB7CiAgICAgICAgICAgICJib3JkZXJXaWR0aCIgOiB7CiAgICAgICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5ib3JkZXIuZWRnZS50aGlja25lc3M7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmJvcmRlci5lZGdlLnRoaWNrbmVzcyA9IHZhbHVlIDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfSkoXywgeGZhbGliKTsoZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRQYXJhID0gewogICAgICAgIHByb3BlcnR5RGVzY3JpcHRvcnMgOiB7CiAgICAgICAgICAgICJwYXJhIiA6IHsKICAgICAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInBhcmEiLCAwKTsKICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAicGFyYSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9KShfLCB4ZmFsaWIpOwoKCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZE1hcmdpbiA9IHsKICAgICAgICBwcm9wZXJ0eURlc2NyaXB0b3JzIDogewogICAgICAgICAgICAibWFyZ2luIiA6IHsKICAgICAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoIm1hcmdpbiIsIDApOwogICAgICAgICAgICAgICAgfSwKCiAgICAgICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJtYXJnaW4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfSkoXywgeGZhbGliKTsKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5PYmplY3QKICogQGltcG9ydCB4ZmFsaWIudXQuRXZlbnRDbGFzcwogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIE9iamVjdCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBjbGFzcwogICAgICogQGNsYXNzIEJhc2UgWEZBIGNsYXNzLiBBbGwgdGhlIG90aGVyIGNsYXNzZXMgYXJlIGEgc3ViY2xhc3Mgb2YgdGhpcy4KICAgICAqIEBjb25zdHJ1Y3RvcgogICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGNsYXNzTmFtZSByZXByZXNlbnRzIHRoZSBuYW1lIG9mIHRoZSBjbGFzcyBmb3IgdGhpcyBvYmplY3QKICAgICAqLwogICAgdmFyIHhmYU9iamVjdCA9IHhmYWxpYi5zY3JpcHQuT2JqZWN0ID0geGZhbGliLnV0LkV2ZW50Q2xhc3MuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZSA6ICJvYmplY3QiLAogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICAvL0ZvciBwZXJmIHJlYXNvbiwgd2UgYXJlIGNvbXB1dGluZyBjbGFzc05hbWUgYXQgaW50aWFsaXplIHRpbWUgaW5zdGVhZCBvZiBhY2Nlc3NpbmcgaXQgdmlhIHByb3BlcnR5RGVzY3JpcHRvcgogICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSA9IHRoaXMuanNvbk1vZGVsLl9jbGFzcyB8fCB0aGlzLm1zQ2xhc3NOYW1lOwogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuWGZhTGlzdAogKiBAaW1wb3J0IHhmYWxpYi51dC5DbGFzcwogKi8KCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIFhmYUxpc3QgPSB4ZmFsaWIuc2NyaXB0LlhmYUxpc3QgPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBYZmFMaXN0Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuY3VycmVudEluZGV4ID0gLTE7CiAgICAgICAgICAgIHRoaXMubW9BcnJheWxpc3QgPSAgbmV3IEFycmF5KCk7CiAgICAgICAgICAgIHRoaXMubVBhcmVudCA9IHRoaXMub3B0aW9ucy5wYXJlbnQ7CiAgICAgICAgfSwKCiAgICAgICAgaXRlbSA6IGZ1bmN0aW9uKG5JbmRleCkgewogICAgICAgICAgICBpZihuSW5kZXggPD0gdGhpcy5jdXJyZW50SW5kZXgpCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tb0FycmF5bGlzdFtuSW5kZXhdOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICBfYXBwZW5kIDogZnVuY3Rpb24ob1BhcmFtKSB7CiAgICAgICAgICAgIHRoaXMubW9BcnJheWxpc3RbKyt0aGlzLmN1cnJlbnRJbmRleF0gPSBvUGFyYW07CiAgICAgICAgfSwKCiAgICAgICAgYXBwZW5kIDogZnVuY3Rpb24ob1BhcmFtKSB7CiAgICAgICAgICAgIGlmKHRoaXMubVBhcmVudCAmJiB0aGlzLm1QYXJlbnQgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQpICAgewogICAgICAgICAgICAgICAgdmFyIHJlbGF0aW9uID0gdGhpcy5tUGFyZW50Ll94ZmEoKS5fdGVtcGxhdGVTY2hlbWEuX2dldFJlbGF0aW9uKHRoaXMubVBhcmVudC5jbGFzc05hbWUsb1BhcmFtLmNsYXNzTmFtZSk7CiAgICAgICAgICAgICAgICBzd2l0Y2gocmVsYXRpb24udHlwZSkKICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgY2FzZSAiemVyb09yT25lIjoKICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICBjYXNlICJ6ZXJvT3JUd28iOgogICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgIGNhc2UgInplcm9Pck1vcmUiOgogICAgICAgICAgICAgICAgdGhpcy5tUGFyZW50Ll9hZGRDaGlsZChvUGFyYW0pOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgZGVmYXVsdDoKCiAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl9hcHBlbmQob1BhcmFtKTsKICAgICAgICB9LAoKICAgICAgICByZW1vdmUgOiBmdW5jdGlvbihvUGFyYW0pIHsKICAgICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5tb0FycmF5bGlzdC5pbmRleE9mKG9QYXJhbSk7CiAgICAgICAgICAgIGlmKGluZGV4ID49IDApIHsKICAgICAgICAgICAgICAgIHRoaXMubW9BcnJheWxpc3Quc3BsaWNlKGluZGV4LDEpOwogICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50SW5kZXgtLTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGluc2VydCA6IGZ1bmN0aW9uKG9JbnNlcnQsb0JlZm9yZSkgewogICAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLm1vQXJyYXlsaXN0LmluZGV4T2Yob0JlZm9yZSk7CiAgICAgICAgICAgIHRoaXMuY3VycmVudEluZGV4Kys7CiAgICAgICAgICAgIGlmKGluZGV4IDw9IDApCiAgICAgICAgICAgICAgICBpbmRleCA9IHRoaXMuY3VycmVudEluZGV4OwogICAgICAgICAgICB0aGlzLm1vQXJyYXlsaXN0LnNwbGljZShpbmRleCwwLG9JbnNlcnQpOwogICAgICAgIH0sCgogICAgICAgIF9jb25jYXQgOiBmdW5jdGlvbihvTGlzdCkgewogICAgICAgICAgICBpZihvTGlzdCA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICBmb3IodmFyIGkgPTA7IGk8IG9MaXN0Lmxlbmd0aDtpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuX2FwcGVuZChvTGlzdC5pdGVtKGkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIG5hbWVkSXRlbSA6IGZ1bmN0aW9uKG9QYXJhbSl7CiAgICAgICAgICAgIHZhciBub2RlID0gdGhpcy5fZmluZChmdW5jdGlvbihvYmopIHsKICAgICAgICAgICAgICAgIHJldHVybiBvYmouZ2V0QXR0cmlidXRlKCJuYW1lIikgPT09IG9QYXJhbTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlmKG5vZGUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgIH0sCgogICAgICAgIF9maW5kIDogZnVuY3Rpb24oZm4pIHsKICAgICAgICAgICAgcmV0dXJuIF8uZmluZCh0aGlzLm1vQXJyYXlsaXN0LGZuKTsKICAgICAgICB9LAoKICAgICAgICBfZmlsdGVyIDogZnVuY3Rpb24oZm4pIHsKICAgICAgICAgICAgcmV0dXJuIF8uZmlsdGVyKHRoaXMubW9BcnJheWxpc3QsZm4pOwogICAgICAgIH0KICAgIH0pOwoKICAgIFhmYUxpc3QuZGVmaW5lUHJvcHMoewogICAgICAgICJsZW5ndGgiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1vQXJyYXlsaXN0Lmxlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIpOwoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuU09NRXhwcmVzc2lvbgogKiBAaW1wb3J0IHhmYWxpYi51dC5DbGFzcwogKi8KIAooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBTT01FeHByZXNzaW9uID0geGZhbGliLnNjcmlwdC5TT01FeHByZXNzaW9uID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBTT01FeHByZXNzaW9uLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIC8vIEZvcm1hdDogc3ViZm9ybUFbbnwqXQogICAgICAgICAgICAvLyBGb3JtYXQ6IHN1YmZvcm1BW258Kl0uW3ByZWRpY2F0ZSBleHByXQogICAgICAgICAgICAvLyBGb3JtYXQ6IHN1YmZvcm1BLltwcmVkaWNhdGUgZXhwcl0KICAgICAgICAgICAgLy8gcHJlZGljYXRlIGV4cHI6IGJvb2xlYW4gZXhwcmVzc2lvbiB0aGF0IG1heSBpbmNsdWRlIG9iamVjdCByZWZlcmVuY2VzIGFuZAogICAgICAgICAgICAvLyBTT01FeHByZXNzaW9ucwoKICAgICAgICAgICAgdGhpcy5fZXhwciA9IHRoaXMub3B0aW9ucy5leHByZXNzaW9uOwogICAgICAgICAgICB0aGlzLnNjYWxlck1hdGNoID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5wcmVkaWNhdGUgPSBudWxsOwogICAgICAgICAgICB0aGlzLm5hbWUgPSB0aGlzLm9wdGlvbnMuZXhwcmVzc2lvbjsKICAgICAgICAgICAgdGhpcy5pbmRleCA9IHRoaXMub3B0aW9ucy5kZWZhdWx0T2NjdXJyZW5jZTsKICAgICAgICAgICAgdGhpcy5fYkRlZmF1bHRJbmRleCA9IHRydWU7CiAgICAgICAgICAgIHRoaXMuX21hdGNoQ291bnQgPSAwOwoKICAgICAgICAgICAgdmFyIGFyciA9IHRoaXMuX3BhcnNlRXhwcmVzc2lvbih0aGlzLm9wdGlvbnMuZXhwcmVzc2lvbik7CiAgICAgICAgICAgIGlmIChhcnIgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgICAgIGlmIChhcnIubGVuZ3RoID09IDEpCiAgICAgICAgICAgICAgICB0aGlzLm5hbWUgPSBhcnJbMF07CiAgICAgICAgICAgIGVsc2UgaWYgKGFyci5sZW5ndGggPT0gMikgewogICAgICAgICAgICAgICAgdGhpcy5uYW1lID0gYXJyWzBdOwogICAgICAgICAgICAgICAgaWYgKGFyclsxXSAhPSAnJykgewogICAgICAgICAgICAgICAgICAgIC8vIFN0cmlwIGJyYWNrZXRzCiAgICAgICAgICAgICAgICAgICAgdmFyIG9jYyA9IGFyclsxXS5zdWJzdHJpbmcoMSwgYXJyWzFdLmxlbmd0aCAtIDEpOwogICAgICAgICAgICAgICAgICAgIGlmIChvY2MgPT0gJyonKQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluZGV4ID0gJyonOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmRleCA9IHBhcnNlSW50KG9jYyk7CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX2JEZWZhdWx0SW5kZXggPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmIChhcnIubGVuZ3RoID09IDMpIHsKICAgICAgICAgICAgICAgIHRoaXMubmFtZSA9IGFyclswXTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuaWdub3JlUHJlZGljYXRlID09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gU3RyaXAgYnJhY2tldHMKICAgICAgICAgICAgICAgICAgICB0aGlzLnByZWRpY2F0ZSA9IGFyclsyXS5zdWJzdHJpbmcoMSwgYXJyWzJdLmxlbmd0aCAtIDEpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5kZXggPSAnKic7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBlcXVhbHMgOiBmdW5jdGlvbihvYmopIHsKICAgICAgICAgIHJldHVybiB0aGlzLm5hbWVzRXF1YWwob2JqKSB8fCB0aGlzLmNsYXNzZXNFcXVhbChvYmopOwogICAgICAgIH0sCgogICAgICAgIGV2YWxQcmVkaWNhdGUgOiBmdW5jdGlvbiAob2JqKSB7CiAgICAgICAgICAgIC8vIERlZmF1bHQ6IHRydWUsIGluZGljYXRpbmcgb2JqIHBhc3NlcyBwcmVkIGV4cHIgcXVhbGlmaWNhdGlvbgogICAgICAgICAgICB2YXIgYlByZWRpY2F0ZVJlc3VsdCA9IHRydWU7CgogICAgICAgICAgICAvL1RPRE86IEltcGxlbWVudCBsYXRlcgogICAgICAgICAgICAvKgogICAgICAgICAgICAgaWYgKHRoaXMucHJlZGljYXRlICE9IG51bGwgJiYgb2JqICE9IG51bGwpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICB2YXIgcGFyc2VyOktQYXJzZXIgPSBuZXcgS1BhcnNlcigpOwogICAgICAgICAgICAgdmFyIHJlc3VsdDpPYmplY3QgPSBwYXJzZXIuZXZhbHVhdGVFeHByZXNzaW9uICh0aGlzLnByZWRpY2F0ZSwgb2JqKTsKICAgICAgICAgICAgIGlmIChyZXN1bHQgaXMgQm9vbGVhbikKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIHRyYWNlICgiZXZhbFByZWRpY2F0ZSgpIG9uOiAiICsgdGhpcy5wcmVkaWNhdGUgKyAiLCByZXN1bHQ6ICIgKyByZXN1bHQpOwogICAgICAgICAgICAgYlByZWRpY2F0ZVJlc3VsdCA9IHJlc3VsdDsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIH0KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJldHVybiBiUHJlZGljYXRlUmVzdWx0OwogICAgICAgIH0sCgogICAgICAgIG5hbWVzRXF1YWwgOiBmdW5jdGlvbihvYmopIHsKICAgICAgICAgICAgaWYgKHRoaXMubmFtZSA9PSBvYmouZ2V0QXR0cmlidXRlKCJuYW1lIikpewogICAgICAgICAgICAgICAgdmFyIGJQcmVkUmVzdWx0ID0gdGhpcy5ldmFsUHJlZGljYXRlKG9iaik7CgogICAgICAgICAgICAgICAgaWYgKCgodGhpcy5pbmRleCA9PSAnKicpIHx8ICh0aGlzLmluZGV4ID09IG9iai5pbmRleCkpICYmIGJQcmVkUmVzdWx0ID09IHRydWUpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIC8vIElmIHRoZSBTT00gZXhwcmVzc2lvbiBkb2VzIG5vdCBoYXZlIGEgc3BlY2lmaWMgaW5kZXgKICAgICAgICAgICAgICAgIC8vIHJlY29yZCBhIG5hbWUgbWF0Y2ggd2l0aCB0aGUgb2JqIHdpdGggdGhlIGxvd2VzdCBpbmRleAogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIGlmICh0aGlzLl9iRGVmYXVsdEluZGV4ICYmIGJQcmVkUmVzdWx0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICgodGhpcy5zY2FsZXJNYXRjaCA9PSBudWxsKSB8fCAob2JqLmluZGV4IDwgdGhpcy5zY2FsZXJNYXRjaC5pbmRleCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2NhbGVyTWF0Y2ggPSBvYmo7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIGNsYXNzZXNFcXVhbCA6IGZ1bmN0aW9uICggb2JqKXsKICAgICAgICAgICAgdmFyIGJSZXQgPSBmYWxzZTsKICAgICAgICAgICAgdmFyIGJQcmVkUmVzdWx0ID0gdGhpcy5ldmFsUHJlZGljYXRlKG9iaik7CgogICAgICAgICAgICBpZiAodGhpcy5uYW1lID09ICIjIitvYmouY2xhc3NOYW1lKXsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmluZGV4ID09ICcqJyAmJiBiUHJlZFJlc3VsdCA9PSB0cnVlKXsKICAgICAgICAgICAgICAgICAgICBiUmV0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaW5kZXggPT0gb2JqLm1uQ2xhc3NJbmRleCAmJiBiUHJlZFJlc3VsdCA9PSB0cnVlKQogICAgICAgICAgICAgICAgICAgICAgICBiUmV0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIGJSZXQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYlJldDsKICAgICAgICB9LAoKICAgICAgICB0YWdFcXVhbHMgOiBmdW5jdGlvbiAob2JqKSB7CiAgICAgICAgICAgIHZhciBwYXJlbnQgPSBvYmoucGFyZW50OwogICAgICAgICAgICB2YXIgbWF4OwogICAgICAgICAgICBpZihwYXJlbnQpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHJlbGF0aW9uID0gcGFyZW50Ll9nZXRSZWxhdGlvbihvYmopOwogICAgICAgICAgICAgICAgICAgIGlmKHJlbGF0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICBtYXggPSByZWxhdGlvbi5tYXg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXRjaChlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuTG9nZ2VyLmRlYnVnKCJ4ZmEiLCAiaW5jb21wbGV0ZSBzY2hlbWEuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9pZiB0aGlzIG9iaiBpcyB0aGUgb25seSBwb3NzaWJsZSBjaGlsZCBvZiBpdHMgdHlwZSB0aGVuIGlnbm9yZSBjbGFzcyBpbmRleC4KICAgICAgICAgICAgcmV0dXJuIHRoaXMubmFtZSA9PSBvYmouY2xhc3NOYW1lICYmIChtYXggPT0gMSB8fCB0aGlzLmluZGV4ID09JyonIHx8IHRoaXMuaW5kZXggPT0gb2JqLm1uQ2xhc3NJbmRleCkKICAgICAgICB9LAoKICAgICAgICBfcGFyc2VFeHByZXNzaW9uIDogZnVuY3Rpb24oc1NvbUV4cHJlc3Npb24pIHsKICAgICAgICAgICAgaWYgKHNTb21FeHByZXNzaW9uID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgYXJyID0gW107CiAgICAgICAgICAgIHZhciBidWYgPSAiIjsKICAgICAgICAgICAgdmFyIGluQnJhY2UgPSAwOwogICAgICAgICAgICB2YXIgYkVzY2FwZSA9IGZhbHNlOwogICAgICAgICAgICBmb3IgKCB2YXIgaiA9IDA7IGogPCBzU29tRXhwcmVzc2lvbi5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgdmFyIHMgPSBzU29tRXhwcmVzc2lvbi5jaGFyQXQoaik7CiAgICAgICAgICAgICAgICBpZiAocyA9PSAiWyIgJiYgIWluQnJhY2UpIHsKICAgICAgICAgICAgICAgICAgICBpbkJyYWNlKys7CiAgICAgICAgICAgICAgICAgICAgYXJyLnB1c2goYnVmKTsKICAgICAgICAgICAgICAgICAgICBidWYgPSAiIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChzID09ICJbIiAmJiBpbkJyYWNlKSB7CiAgICAgICAgICAgICAgICAgICAgaW5CcmFjZSsrOwogICAgICAgICAgICAgICAgICAgIGJ1ZiArPSBzOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzID09ICJdIiAmJiBpbkJyYWNlKSB7CiAgICAgICAgICAgICAgICAgICAgLS1pbkJyYWNlOwogICAgICAgICAgICAgICAgICAgIGJ1ZiArPSBzOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzID09ICJcXCIpIHsKICAgICAgICAgICAgICAgICAgICBiRXNjYXBlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocyA9PSAiLiIgJiYgIWluQnJhY2UgJiYgIWJFc2NhcGUpIHsKICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChidWYpOwogICAgICAgICAgICAgICAgICAgIGJ1ZiA9ICIiOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBidWYgKz0gczsKICAgICAgICAgICAgICAgICAgICBiRXNjYXBlID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGogPT0gc1NvbUV4cHJlc3Npb24ubGVuZ3RoIC0gMSkKICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChidWYpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBhcnI7CiAgICAgICAgfSwKCiAgICAgICAgc3BsaXRFeHByZXNzaW9uIDogZnVuY3Rpb24oc1NvbUV4cHJlc3Npb24pIHsKICAgICAgICAgICAgaWYgKHNTb21FeHByZXNzaW9uID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKCiAgICAgICAgICAgIHZhciBhcnIgPSBbXTsKICAgICAgICAgICAgdmFyIGJ1ZiA9ICIiOwogICAgICAgICAgICB2YXIgaW5CcmFjZSA9IDA7CiAgICAgICAgICAgIHZhciBiRXNjYXBlID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAoIHZhciBqID0gMDsgaiA8IHNTb21FeHByZXNzaW9uLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICB2YXIgcyA9IHNTb21FeHByZXNzaW9uLmNoYXJBdChqKTsKICAgICAgICAgICAgICAgIGlmIChzID09ICJbIikgewogICAgICAgICAgICAgICAgICAgIGluQnJhY2UrKzsKICAgICAgICAgICAgICAgICAgICBidWYgKz0gczsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocyA9PSAiXSIpIHsKICAgICAgICAgICAgICAgICAgICAtLWluQnJhY2U7CiAgICAgICAgICAgICAgICAgICAgYnVmICs9IHM7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHMgPT0gIlxcIikgewogICAgICAgICAgICAgICAgICAgIGJFc2NhcGUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJ1ZiArPSBzOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzID09ICIuIiAmJiBpbkJyYWNlID09IDAgJiYgYkVzY2FwZSA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgIGlmIChidWYubGVuZ3RoID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgIGFyci5wdXNoKCIuLiIpOyAvLyBlbGlwc2lzCiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChidWYuaW5kZXhPZigiI3ZhcmlhYmxlcyIpIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnB1c2goYnVmKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBidWYgPSAiIjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnVmICs9IHM7CiAgICAgICAgICAgICAgICAgICAgYkVzY2FwZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChqID09IHNTb21FeHByZXNzaW9uLmxlbmd0aCAtIDEpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYnVmLmluZGV4T2YoIiN2YXJpYWJsZXMiKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnB1c2goYnVmKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChhcnIubGVuZ3RoID09IDEpCiAgICAgICAgICAgICAgICByZXR1cm4gYXJyOwoKICAgICAgICAgICAgdmFyIG91dCA9IFtdOwogICAgICAgICAgICB2YXIgcGF0dGVybiA9IC9eXFsuKlxdLzsKICAgICAgICAgICAgZm9yICggdmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB2YXIgc2VnID0gU3RyaW5nKGFycltpXSk7CiAgICAgICAgICAgICAgICBpZiAoc2VnLm1hdGNoKHBhdHRlcm4pICYmIGkgPiAwKQogICAgICAgICAgICAgICAgICAgIG91dC5zcGxpY2UoaSAtIDEsIDEsIGFycltpIC0gMV0gKyAiLiIgKyBzZWcpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIG91dC5wdXNoKGFycltpXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG91dDsKICAgICAgICB9CgogICAgfSk7CgogICAgU09NRXhwcmVzc2lvbi5kZWZpbmVQcm9wcyh7CiAgICAgICAgImV4cHJlc3Npb24iIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9leHByOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbihleHByZXNzaW9uKSB7ICAgICAgICAgICAgCQogICAgICAgICAgICAJZXhwcmVzc2lvbiA9IHRoaXMudmFsaWRhdGVJbnB1dChleHByZXNzaW9uLCJzdHJpbmciKTsKICAgICAgICAgICAgICAgIHRoaXMuX2V4cHIgPSBleHByZXNzaW9uOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwoKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50CiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5PYmplY3QKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBYZmFNb2RlbEV2ZW50IENsYXNzIHJlcXVpcmVkIGZvciBYRkEgbGlicmFyeQogKiBAdmVyc2lvbiAwLjAuMQogKi8KKGZ1bmN0aW9uKF8seGZhbGliKSB7CgogICAgdmFyIFhmYU1vZGVsRXZlbnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQgPSB4ZmFsaWIuc2NyaXB0Lk9iamVjdC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiAiZXZlbnRQc2V1ZG9Nb2RlbCIKICAgIH0pOwoKICAgIFhmYU1vZGVsRXZlbnQuZGVmaW5lUHJvcHMoewogICAgICAgICJwcmV2VGV4dCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwucHJldlRleHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJuZXdUZXh0IiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmpzb25Nb2RlbC5uZXdUZXh0OwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiZnVsbFRleHQiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuanNvbk1vZGVsLmZ1bGxUZXh0OwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAibmFtZSIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwubmFtZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImtleURvd24iIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuanNvbk1vZGVsLmtleURvd247CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJtb2RpZmllciIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwubW9kaWZpZXI7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJ0YXJnZXQiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuanNvbk1vZGVsLnRhcmdldDsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInNoaWZ0IiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmpzb25Nb2RlbC5zaGlmdDsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5nZSIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwuY2hhbmdlOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC5jaGFuZ2UgPSB2YWx1ZTsKICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsdGhpcy50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgJ2NoYW5nZScsdmFsdWUsbnVsbCk7CiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldC50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgIl9wcm9wZXJ0eSIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwuX3Byb3BlcnR5OwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsdWUpewogICAgICAgICAgICAgICAgdGhpcy5qc29uTW9kZWwuX3Byb3BlcnR5ID0gdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCiAgICBYZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50ID0gZnVuY3Rpb24obm0sdGd0LHByb3Asb2xkVmFsLG5ld1ZhbCkgewogICAgICAgIHZhciBldm50ID0gewogICAgICAgICAgICBuYW1lOm5tLAogICAgICAgICAgICB0YXJnZXQ6dGd0LAogICAgICAgICAgICBfcHJvcGVydHk6cHJvcCwKICAgICAgICAgICAgcHJldlRleHQ6b2xkVmFsLAogICAgICAgICAgICBuZXdUZXh0Om5ld1ZhbAogICAgICAgIH07CiAgICAgICAgcmV0dXJuIG5ldyBYZmFNb2RlbEV2ZW50KHsianNvbk1vZGVsIiA6IGV2bnR9KTsKICAgIH07CgogICAgWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQgPSAiZm9ybU1vZGVsQ2hhbmdlZCI7CiAgICBYZmFNb2RlbEV2ZW50LlJBV19WQUxVRV9DSEFOR0VEID0gInJhd1ZhbHVlQ2hhbmdlZCI7CiAgICBYZmFNb2RlbEV2ZW50LkNISUxEX0FEREVEID0gImNoaWxkQWRkZWQiOwogICAgWGZhTW9kZWxFdmVudC5DSElMRF9SRU1PVkVEID0gImNoaWxkUmVtb3ZlZCI7CiAgICBYZmFNb2RlbEV2ZW50LkNISUxEX01PVkVEID0gImNoaWxkTW92ZWQiOwogICAgWGZhTW9kZWxFdmVudC5PQkpFQ1RfREVTVFJPWUVEID0gIm9iamVjdERlc3Ryb3llZCI7CiAgICBYZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfUkVGUkVTSCA9ICJmb3JtTW9kZWxSZWZyZXNoIjsKICAgIFhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQgPSAiZG9tQ2hhbmdlZCI7Cn0pKF8seGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuTGF5b3V0CiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5DbGFzcwogKi8KCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIExheW91dCA9IHhmYWxpYi5zY3JpcHQuTGF5b3V0ID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHRoaXMucGFnaW5nTWFuYWdlciA9IG51bGwgOwogICAgICAgICAgICBMYXlvdXQuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKCiAgICAgICAgfSwKCiAgICAgICAgX3hmYSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4geGZhbGliLnNjcmlwdC5YZmEuSW5zdGFuY2U7CiAgICAgICAgfSwKCiAgICAgICAgcmVsYXlvdXQ6IGZ1bmN0aW9uKCkgewogICAgICAgIH0sCgogICAgICAgIHBhZ2U6IGZ1bmN0aW9uKG5vZGUpewogICAgICAgICAgICByZXR1cm4gdGhpcy5wYWdpbmdNYW5hZ2VyLmZpbmRQYWdlKG5vZGUuaHRtbElkKSArIDE7CiAgICAgICAgfSwKCiAgICAgICAgcGFnZUNvdW50OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYodGhpcy5wYWdpbmdNYW5hZ2VyKQogICAgICAgICAgICAgICAgcmV0dXJuKHRoaXMucGFnaW5nTWFuYWdlci5wYWdlQ291bnQoKSk7CiAgICAgICAgfSwKCiAgICAgICAgYWJzUGFnZUNvdW50OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYodGhpcy5wYWdpbmdNYW5hZ2VyKQogICAgICAgICAgICAgICAgcmV0dXJuKHRoaXMucGFnaW5nTWFuYWdlci5wYWdlQ291bnQoKSk7CiAgICAgICAgfSwKCiAgICAgICAgcGFnZUNvbnRlbnQgOiBmdW5jdGlvbihwYWdlTnVtLCBjbGFzc05hbWUsIGJQYWdlQXJlYSl7CiAgICAgICAgICAgIGlmKHRoaXMucGFnaW5nTWFuYWdlcil7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYWdpbmdNYW5hZ2VyLl9wYWdlQ29udGVudChwYWdlTnVtLCBjbGFzc05hbWUsIGJQYWdlQXJlYSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LlhmYUxpc3QoKTsKICAgICAgICB9LAoKICAgICAgICBweDJwdDogZnVuY3Rpb24ocHgpIHsKICAgICAgICAgICAgcmV0dXJuIHB4LzI7CiAgICAgICAgfSwKCiAgICAgICAgcHQyaW5jaDogZnVuY3Rpb24ocHQpIHsKICAgICAgICAgICAgcmV0dXJuIHB0LzcyOwogICAgICAgIH0sCgogICAgICAgIHB0Mm1tOiBmdW5jdGlvbihwdCkgewogICAgICAgICAgICByZXR1cm4gKHB0KjI1LjQpLzcyOwogICAgICAgIH0sCgogICAgICAgIGg6IGZ1bmN0aW9uKG5vZGUsIHVuaXQsIG9mZnNldCkgewogICAgICAgICAgICBpZih0aGlzLnBhZ2luZ01hbmFnZXIpICAgIHsKICAgICAgICAgICAgICAgIHRoaXMucGFnaW5nTWFuYWdlci5fbWFrZVBhZ2VGb3JIdG1sSWQobm9kZS5odG1sSWQpOwogICAgICAgICAgICAgICAgdmFyIGxheW91dCA9IHRoaXMucGFnaW5nTWFuYWdlci5nZXRMYXlvdXQobm9kZS5odG1sSWQpOwogICAgICAgICAgICAgICAgaWYobGF5b3V0KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGggPSB0aGlzLnB4MnB0KGxheW91dC5leHRlbnRoKSA7CiAgICAgICAgICAgICAgICAgICAgaWYodW5pdCA9PSAiaW5jaCIgfHwgdW5pdCA9PSAiaW4iKQogICAgICAgICAgICAgICAgICAgICAgICBoID0gdGhpcy5wdDJpbmNoKGgpOwogICAgICAgICAgICAgICAgICAgIGlmKHVuaXQgPT0gIm1tIikKICAgICAgICAgICAgICAgICAgICAgICAgaCA9IHRoaXMucHQybW0oaCk7CiAgICAgICAgICAgICAgICAgICAgaWYob2Zmc2V0ICE9IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgICAgICAgICAgaD0gMDsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgcmV0dXJuIDA7CgogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIHc6IGZ1bmN0aW9uKG5vZGUsIHVuaXQsIG9mZnNldCkgewogICAgICAgICAgICBpZih0aGlzLnBhZ2luZ01hbmFnZXIpICAgIHsKICAgICAgICAgICAgICAgIHRoaXMucGFnaW5nTWFuYWdlci5fbWFrZVBhZ2VGb3JIdG1sSWQobm9kZS5odG1sSWQpOwogICAgICAgICAgICAgICAgdmFyIGxheW91dCA9IHRoaXMucGFnaW5nTWFuYWdlci5nZXRMYXlvdXQobm9kZS5odG1sSWQpOwogICAgICAgICAgICAgICAgaWYobGF5b3V0KSAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdyA9IHRoaXMucHgycHQobGF5b3V0LmV4dGVudHcpIDsKICAgICAgICAgICAgICAgICAgICBpZih1bml0ID09ICJpbmNoIiB8fCB1bml0ID09ICJpbiIpCiAgICAgICAgICAgICAgICAgICAgICAgIHcgPSB0aGlzLnB0MmluY2godyk7CiAgICAgICAgICAgICAgICAgICAgaWYodW5pdCA9PSAibW0iKQogICAgICAgICAgICAgICAgICAgICAgICB3ID0gdGhpcy5wdDJtbSh3KTsKICAgICAgICAgICAgICAgICAgICBpZihvZmZzZXQgIT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgICAgICAgICB3PSAwOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB3IDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgcmV0dXJuIDA7CgogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgeDogZnVuY3Rpb24obm9kZSwgdW5pdCwgb2Zmc2V0KSB7CiAgICAgICAgICAgIGlmKHRoaXMucGFnaW5nTWFuYWdlcikgICAgewogICAgICAgICAgICAgICAgdGhpcy5wYWdpbmdNYW5hZ2VyLl9tYWtlUGFnZUZvckh0bWxJZChub2RlLmh0bWxJZCk7CiAgICAgICAgICAgICAgICB2YXIgbGF5b3V0ID0gdGhpcy5wYWdpbmdNYW5hZ2VyLmdldExheW91dChub2RlLmh0bWxJZCk7CiAgICAgICAgICAgICAgICBpZihsYXlvdXQpewogICAgICAgICAgICAgICAgICAgIHZhciB4ID0gdGhpcy5weDJwdChsYXlvdXQuZXh0ZW50eCkgOwogICAgICAgICAgICAgICAgICAgIGlmKHVuaXQgPT0gImluY2giIHx8IHVuaXQgPT0gImluIikKICAgICAgICAgICAgICAgICAgICAgICAgeCA9IHRoaXMucHQyaW5jaCh4KTsKICAgICAgICAgICAgICAgICAgICBpZih1bml0ID09ICJtbSIpCiAgICAgICAgICAgICAgICAgICAgICAgIHggPSB0aGlzLnB0Mm1tKHgpOwogICAgICAgICAgICAgICAgICAgIGlmKG9mZnNldCAhPSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIHg9IDA7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHJldHVybiAwOwoKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHk6IGZ1bmN0aW9uKG5vZGUsIHVuaXQsIG9mZnNldCkgewogICAgICAgICAgICBpZih0aGlzLnBhZ2luZ01hbmFnZXIpICAgIHsKICAgICAgICAgICAgICAgIHRoaXMucGFnaW5nTWFuYWdlci5fbWFrZVBhZ2VGb3JIdG1sSWQobm9kZS5odG1sSWQpOwogICAgICAgICAgICAgICAgdmFyIGxheW91dCA9IHRoaXMucGFnaW5nTWFuYWdlci5nZXRMYXlvdXQobm9kZS5odG1sSWQpOwogICAgICAgICAgICAgICAgaWYobGF5b3V0KXsKICAgICAgICAgICAgICAgICAgICB2YXIgeSA9IHRoaXMucHgycHQobGF5b3V0LmV4dGVudHkpIDsKICAgICAgICAgICAgICAgICAgICBpZih1bml0ID09ICJpbmNoIiB8fCB1bml0ID09ICJpbiIpCiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSB0aGlzLnB0MmluY2goeSk7CiAgICAgICAgICAgICAgICAgICAgaWYodW5pdCA9PSAibW0iKQogICAgICAgICAgICAgICAgICAgICAgICB5ID0gdGhpcy5wdDJtbSh5KTsKICAgICAgICAgICAgICAgICAgICBpZihvZmZzZXQgIT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgICAgICAgICB5PSAwOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB5OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSByZXR1cm4gMDsKCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7CiAgICBMYXlvdXQuZGVmaW5lUHJvcHMoewogICAgICAgICJyZWFkeSIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIpOwoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuTm9kZQogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuT2JqZWN0CiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5TT01FeHByZXNzaW9uCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5YZmFMaXN0CiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgTm9kZSBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgoKKGZ1bmN0aW9uKF8sIHhmYWxpYil7CiAgICB2YXIgTm9kZSA9IHhmYWxpYi5zY3JpcHQuTm9kZSA9IHhmYWxpYi5zY3JpcHQuT2JqZWN0LmV4dGVuZCh7CiAgICAgICAgX2RlZmF1bHRzIDogewogICAgICAgICAgICAicHJlc2VuY2UiIDogInZpc2libGUiCiAgICAgICAgfSwKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIE5vZGUuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICAgICAqIEB0eXBlIHhmYWxpYi5zY3JpcHQuTm9kZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdGhpcy5tUGFyZW50ID0gbnVsbDsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICAgICAqIEB0eXBlIHN0cmluZwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdGhpcy5tbkluZGV4ID0gMDsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICAgICAqIEB0eXBlIHN0cmluZwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdGhpcy5tbkNsYXNzSW5kZXggPSAwOwogICAgICAgIH0sCgogICAgICAgIHBsYXlKc29uIDogZnVuY3Rpb24ocEpzb25Nb2RlbCkgewogICAgICAgICAgICAvLyB0YWJJbmRleCBzaG91bGQgYmUgZXhlbXB0ZWQgYmVjYXVzZSB3ZSBhcmUgYWxyZWFkeSBjb21wdXRpbmcgaXQgaW4gX2luc2VydCBJbnN0YW5jZQogICAgICAgICAgICAvLyBDUS00MzI0OTcwOiByZXBsYWNlIGRlZmF1bHQgRlNfREFUQV9TT00gcHJlc2VudCBpbiBGU19FWFRSQVMgd2l0aCBkYXRhU29tIHByZXNlbnQgaW4gZXh0cmFzIGZvciByZXBlYXRlZCBlbGVtZW50cy4KICAgICAgICAgICAgdGhpcy5zZXRGc0RhdGFTb20ocEpzb25Nb2RlbCk7CiAgICAgICAgICAgIHRoaXMuY29weU9iamVjdChwSnNvbk1vZGVsLCB0aGlzLmpzb25Nb2RlbCwge2V4Y2VwdGlvbnMgOiBbImh0bWxJZCIsICJjaGlsZHJlbiIsInRhYkluZGV4Il0sIGtlZXBSZWZlcmVuY2UgOiB0cnVlfSk7CiAgICAgICAgfSwKCiAgICAgICAgc2V0RnNEYXRhU29tIDogZnVuY3Rpb24ocEpzb25Nb2RlbCkgewogICAgICAgICAgICBpZiAod2luZG93LkZEICYmIHdpbmRvdy5GRC5pc1RvZ2dsZUVuYWJsZWQoIkZUX0ZPUk1TLTE0MzQ5IikpIHsgLy8gRk9STVMtMTA3MzEgOiBkb24ndCBjaGFuZ2UgRlNfREFUQV9TT00gaWYgZmllbGQgaXMgbm90IG5hbWVkLgogICAgICAgICAgICAgICAgdGhpcy5zZXRGc0RhdGFTb21WYWx1ZShwSnNvbk1vZGVsKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmdldEF0dHJpYnV0ZSgibmFtZSIpICYmIHRoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIikubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0RnNEYXRhU29tVmFsdWUocEpzb25Nb2RlbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBzZXRGc0RhdGFTb21WYWx1ZSA6IGZ1bmN0aW9uKHBKc29uTW9kZWwpIHsKICAgICAgICAgICAgdmFyIGZzRGF0YVNvbSA9IHRoaXMucmVzb2x2ZU5vZGUoIiNleHRyYXMuRlNfRVhUUkFTLkZTX0RBVEFfU09NIik7CiAgICAgICAgICAgIGlmIChmc0RhdGFTb20gJiYgcEpzb25Nb2RlbC5leHRyYXMgJiYgcEpzb25Nb2RlbC5leHRyYXMuZGF0YVNvbSkgewogICAgICAgICAgICAgICAgZnNEYXRhU29tLnZhbHVlID0gcEpzb25Nb2RlbC5leHRyYXMuZGF0YVNvbTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8vVE9ETzogUkVNT1ZFIHRoaXMgd2hlbiB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIGlzIGF2YWlsYWJsZQogICAgICAgIHNhdmVYTUwgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0sCgogICAgICAgIC8vVE9ETzogUkVNT1ZFIHRoaXMgd2hlbiB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIGlzIGF2YWlsYWJsZQogICAgICAgIGxvYWRYTUwgOiBmdW5jdGlvbigpIHsKICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUpzb25EaWZmIDogZnVuY3Rpb24oZGlmZl9sZXZlbCl7CiAgICAgICAgICAgIHZhciBkZXN0ID0ge307CiAgICAgICAgICAgIGRlc3QuX2NsYXNzID0gdGhpcy5jbGFzc05hbWU7CiAgICAgICAgICAgIGlmKHRoaXMuanNvbk1vZGVsLmhhc093blByb3BlcnR5KCJuYW1lIikpewogICAgICAgICAgICAgICAgZGVzdC5uYW1lID0gdGhpcy5qc29uTW9kZWwubmFtZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgY2hhbmdlRm91bmQgPSBmYWxzZTsKICAgICAgICAgICAgdmFyIGluaXRpYWxKc29uID0gdGhpcy5feGZhKCkuX3hmYVRlbXBsYXRlQ2FjaGUuZ2V0SW5pdGlhbEZvcm1Eb21SZWYodGhpcy5odG1sSWQpOwogICAgICAgICAgICBpZighaW5pdGlhbEpzb24pCiAgICAgICAgICAgICAgICBpbml0aWFsSnNvbiA9IHRoaXMuX3hmYSgpLl94ZmFUZW1wbGF0ZUNhY2hlLmdldEluaXRpYWxGb3JtRG9tUmVmKHRoaXMuX3RlbXBsYXRlSWQoKSkgfHwge307CiAgICAgICAgICAgIHZhciBpbml0aWFsUHJvcExlbmd0aCA9IF8uZmlsdGVyKGluaXRpYWxKc29uLCBmdW5jdGlvbih2YWx1ZSwga2V5KXsKICAgICAgICAgICAgICAgIHJldHVybiBrZXkgIT0iZXh0cmFzIjsKICAgICAgICAgICAgfSwgdGhpcykubGVuZ3RoOwogICAgICAgICAgICB2YXIganNvblByb3BMZW5ndGggPSBfLmZpbHRlcih0aGlzLmpzb25Nb2RlbCwgZnVuY3Rpb24odmFsdWUsIGtleSl7CiAgICAgICAgICAgICAgICByZXR1cm4ga2V5ICE9ImV4dHJhcyI7CiAgICAgICAgICAgIH0sIHRoaXMpLmxlbmd0aDsKCiAgICAgICAgICAgIGlmKGpzb25Qcm9wTGVuZ3RoICE9IGluaXRpYWxQcm9wTGVuZ3RoKXsKICAgICAgICAgICAgICAgIC8vV2UgbmVlZCB0byBjb21wYXJlIHByb3BlcnR5IHNpemVzIHdpdGhvdXQgJ2V4dHJhJyBwcm9wZXJ0eSBzaW5jZSB0aGlzIGlzIG5vdCBhY3R1YWxseSBwYXJ0IG9mIHNjaGVtYQogICAgICAgICAgICAgICAgY2hhbmdlRm91bmQgPSBkaWZmX2xldmVsPT09MDsgICAvLyBvbmx5IG5lZWQgX2NsYXNzIGFuZCBuYW1lIGR1cmluZyBzdWJtaXNzaW9uICYgcmVzdG9yZUZvcm1TdGF0ZQogICAgICAgICAgICB9CgogICAgICAgICAgICBfLmVhY2godGhpcy5qc29uTW9kZWwsIGZ1bmN0aW9uKHZhbHVlLCBrZXkpewogICAgICAgICAgICAgICAgaWYoa2V5ID09PSAiX2NsYXNzIiB8fCBrZXkgPT09ICJjaGlsZHJlbiIgfHwga2V5ID09PSAiZXh0cmFzIiB8fCBrZXkgPT0gIntkZWZhdWx0fSIpewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vTm90ZTogV2UgYXJlIGFzc3VtaW5nIHRoYXQgYW55IGtleSB0aGF0IGlzIHByZXNlbnQgaW4gdGVtcGxhdGVKc29uIHdvdWxkIGFsc28gYmUgdGhlcmUgaW4gbW9kZWwganNvbiB0aG91Z2ggaXQncyB2YWx1ZSBtYXkgYmUgbnVsbC91bmRlZmluZWQKICAgICAgICAgICAgICAgICAgICBpZih2YWx1ZSAhPT0gaW5pdGlhbEpzb25ba2V5XSl7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKF8uaXNBcnJheSh2YWx1ZSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5lcnJvcigieGZhIiwgImtleToiK2tleSArICIgaGFzIHVuZXhwZWN0ZWQgYXJyYXkgdmFsdWU6IitKU09OLnN0cmluZ2lmeSh2YWx1ZSkgKyAicGFyZW50OlxuIisgSlNPTi5zdHJpbmdpZnkoc3JjKSkgOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoXy5pc09iamVjdCh2YWx1ZSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5lcnJvcigieGZhIiwgImtleToiK2tleSArICIgaGFzIHVuZXhwZWN0ZWQgb2JqZWN0IHZhbHVlOiIrSlNPTi5zdHJpbmdpZnkodmFsdWUpICsgInBhcmVudDpcbiIrIEpTT04uc3RyaW5naWZ5KHNyYykpIDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRpZmZfbGV2ZWw9PT0wKSB7ICAgLy8gb25seSBuZWVkIF9jbGFzcyBhbmQgbmFtZSBkdXJpbmcgc3VibWlzc2lvbiAmIHJlc3RvcmVGb3JtU3RhdGUsIHJlc3Qgd2lsbCBzdHJpcHBlZCBieSBjb21wdXRlSnNvbkRJZmYtcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3Rba2V5XSA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZUZvdW5kID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICBpZiAoZGlmZl9sZXZlbCA9PT0gMSkgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX3hmYSgpLl90ZW1wbGF0ZVNjaGVtYS5oYXNBdHRyaWJ1dGUodGhpcy5jbGFzc05hbWUsICdhY2Nlc3MnKSAmJgogICAgICAgICAgICAgICAgICAgIF8uY29udGFpbnMoWyJleGNsR3JvdXAiLCAiZmllbGQiLCAic3ViZm9ybSJdLCB0aGlzLmNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBkZXN0LmFjY2VzcyA9IHRoaXMuanNvbk1vZGVsLmFjY2VzczsKICAgICAgICAgICAgICAgICAgICBjaGFuZ2VGb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAodGhpcy5feGZhKCkuX3RlbXBsYXRlU2NoZW1hLmhhc0F0dHJpYnV0ZSh0aGlzLmNsYXNzTmFtZSwgJ3ByZXNlbmNlJykgJiYKICAgICAgICAgICAgICAgICAgICBfLmNvbnRhaW5zKFsiZXhjbEdyb3VwIiwgImZpZWxkIiwgIml0ZW1zIiwgInN1YmZvcm0iLCAiZHJhdyJdLCB0aGlzLmNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBkZXN0LnByZXNlbmNlID0gdGhpcy5qc29uTW9kZWwucHJlc2VuY2U7CiAgICAgICAgICAgICAgICAgICAgY2hhbmdlRm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB7ImNoYW5nZWQiIDogY2hhbmdlRm91bmQsCiAgICAgICAgICAgICAgICBqc29uRGlmZmVyZW5jZSA6IGRlc3QKICAgICAgICAgICAgfTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0U29tRXhwcmVzc2lvbiA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpZiAodGhpcy5tUGFyZW50ID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gInhmYVswXS4iICsgdGhpcy5fZXNjYXBlUXVhbGlmaWVkTmFtZSgpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tUGFyZW50LnNvbUV4cHJlc3Npb24gKyAiLiIgKyB0aGlzLl9lc2NhcGVRdWFsaWZpZWROYW1lKCk7CiAgICAgICAgfSwKCiAgICAgICAgX2VzY2FwZVF1YWxpZmllZE5hbWUgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIG5hbWUgPSAiIyIgKyB0aGlzLmNsYXNzTmFtZSwKICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5tbkNsYXNzSW5kZXgsCiAgICAgICAgICAgICAgICBvYmpOYW1lID0gdGhpcy5nZXRBdHRyaWJ1dGUoIm5hbWUiKQogICAgICAgICAgICBpZiAob2JqTmFtZS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICBuYW1lID0gb2JqTmFtZTsKICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5pbmRleDsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgcW5hbWUgPSBuYW1lICsgIlsiICsgaW5kZXggKyAiXSI7CiAgICAgICAgICAgIHJldHVybiBxbmFtZS5yZXBsYWNlKC9cLi8sICJcXC4iKTsKICAgICAgICB9LAoKICAgICAgICBfeGZhIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB4ZmFsaWIuc2NyaXB0LlhmYS5JbnN0YW5jZTsKICAgICAgICB9LAoKICAgICAgICBfcmVzZXREYXRhOiBmdW5jdGlvbigpIHsKCiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogRXZhbHVhdGVzIHRoZSBzcGVjaWZpZWQgU09NIGV4cHJlc3Npb24sIGJlZ2lubmluZyB3aXRoIHRoZSBjdXJyZW50IFhNTCBmb3JtCiAgICAgICAgICogb2JqZWN0IG1vZGVsIG9iamVjdCwgYW5kIHJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBvYmplY3Qgc3BlY2lmaWVkIGluIHRoZSBTT00KICAgICAgICAgKiBleHByZXNzaW9uCiAgICAgICAgICoKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKi8KICAgICAgICByZXNvbHZlTm9kZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgbm9kZXMgPSBudWxsOwogICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAxKQogICAgICAgICAgICAgICAgbm9kZXMgPSB0aGlzLl9yZXNvbHZlTm9kZXNDb21tb24odGhpcywgYXJndW1lbnRzWzBdLCBmYWxzZSwgdHJ1ZSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIG5vZGVzID0gdGhpcy5fcmVzb2x2ZU5vZGVzQ29tbW9uKGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLCBmYWxzZSwKICAgICAgICAgICAgICAgICAgICB0cnVlKTsKCiAgICAgICAgICAgIGlmIChub2RlcyAmJiBub2Rlcy5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgcmV0dXJuIG5vZGVzLml0ZW0oMCk7CiAgICAgICAgICAgIGVsc2UgewoKICAgICAgICAgICAgICAgIC8veGZhLkxvZ2dlci5kZWJ1ZygicmVzb2x2ZU5vZGUgZm9yIHNvbUV4cHJlc3Npb24gIiArIGFyZ3VtZW50c1sxXQogICAgICAgICAgICAgICAgLy8gICAgKyAiIGZhaWxlZCIpOwogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBFdmFsdWF0ZXMgdGhlIHNwZWNpZmllZCBTT00gZXhwcmVzc2lvbiwgYmVnaW5uaW5nIHdpdGggdGhlIGN1cnJlbnQgWE1MIGZvcm0KICAgICAgICAgKiBvYmplY3QgbW9kZWwgb2JqZWN0LCBhbmQgcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIG9iamVjdCBzcGVjaWZpZWQgaW4gdGhlIFNPTQogICAgICAgICAqIGV4cHJlc3Npb24KICAgICAgICAgKgogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqLwogICAgICAgIHJlc29sdmVOb2RlcyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgbm9kZXMgPSBudWxsOwogICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAxKQogICAgICAgICAgICAgICAgbm9kZXMgPSB0aGlzLl9yZXNvbHZlTm9kZXNDb21tb24odGhpcywgYXJndW1lbnRzWzBdLCB0cnVlLCB0cnVlKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbm9kZXMgPSB0aGlzLl9yZXNvbHZlTm9kZXNDb21tb24oYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0sIHRydWUsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gbm9kZXM7CiAgICAgICAgfSwKCiAgICAgICAgX29iakluTGlzdDogZnVuY3Rpb24ob2JqKSB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICBsaXN0Ll9hcHBlbmQob2JqKTsKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfSwKCiAgICAgICAgX2ZpbmRQcm9wZXJ0eTogZnVuY3Rpb24ob1NvbSkgewogICAgICAgICAgICB2YXIgYXJyID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgaWYob1NvbS5pbmRleCA9PSAwKSB7CiAgICAgICAgICAgICAgLy9jaGVjayB3aGV0aGVyIHNvbSBpcyBhIGR5bmFtaWMgcHJvcGVydHkKICAgICAgICAgICAgICBpZih0aGlzLnJlc29sdmVQcm9wZXJ0aWVzICYmIHRoaXMucmVzb2x2ZVByb3BlcnRpZXMuaW5kZXhPZihvU29tLm5hbWUpICE9IC0xKQogICAgICAgICAgICAgICAgYXJyLl9hcHBlbmQodGhpc1tvU29tLm5hbWVdKQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGFycjsKICAgICAgICB9LAoKICAgICAgICBfcmVzb2x2ZU5vZGVzQ29tbW9uIDogZnVuY3Rpb24ob2JqLCBzU29tRXhwcmVzc2lvbiwgYk11bHRpcGxlLCBiRmlyc3QpIHsKICAgICAgICAgICAgdmFyIGFycjEgPSB4ZmFsaWIuc2NyaXB0LlNPTUV4cHJlc3Npb24ucHJvdG90eXBlLnNwbGl0RXhwcmVzc2lvbihzU29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgIGlmKGFycjFbMF0gPT0gJyQnKSB7CiAgICAgICAgICAgICAgICBhcnIxLnNwbGljZSgwLDEsdGhpcy5zb21FeHByZXNzaW9uKTsKICAgICAgICAgICAgICAgIHNTb21FeHByZXNzaW9uID0gYXJyMS5qb2luKCIuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoYXJyMVswXS5jaGFyQXQoMCkgPT0gJyQnIHx8IGFycjFbMF0gPT0gJ3hmYScgfHwgYXJyMVswXSA9PSAndGhpcycpIHsKICAgICAgICAgICAgICAgIHZhciByb290LCBpID0gYXJyMVswXS5sZW5ndGggKyAxOwogICAgICAgICAgICAgICAgc3dpdGNoKGFycjFbMF0pIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJ4ZmEiOgogICAgICAgICAgICAgICAgICAgIGNhc2UgIiR4ZmEiOgogICAgICAgICAgICAgICAgICAgICAgICByb290ID0gdGhpcy5feGZhKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIiR0ZW1wbGF0ZSI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJvb3QgPSB0aGlzLl94ZmEoKS50ZW1wbGF0ZQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICIkZm9ybSI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJvb3QgPSB0aGlzLl94ZmEoKS5mb3JtOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJ0aGlzIjoKICAgICAgICAgICAgICAgICAgICAgICAgcm9vdCA9IHRoaXMuX3hmYSgpLl9jb250ZXh0Tm9kZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGFycjEubGVuZ3RoID09IDEpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29iakluTGlzdChyb290KQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc29sdmVOb2Rlc0NvbW1vbihyb290LHNTb21FeHByZXNzaW9uCiAgICAgICAgICAgICAgICAgICAgLnN1YnN0cihpKSwgYk11bHRpcGxlLCBiRmlyc3QpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbkN1cnJlbnRJbmRleCA9IDA7CiAgICAgICAgICAgIC8vIFRPRE86IERvIGNvbnRleHROb2RlIG11bWJvIGp1bWJvCiAgICAgICAgICAgIGlmICh0aGlzLl94ZmEoKSAmJiAodGhpcy5feGZhKCkuX2NvbnRleHROb2RlKCkgIT0gbnVsbCkpCiAgICAgICAgICAgICAgICBuQ3VycmVudEluZGV4ID0gdGhpcy5feGZhKCkuX2NvbnRleHROb2RlKCkuaW5kZXg7CgogICAgICAgICAgICB2YXIgb0NoaWxkcmVuID0gbnVsbDsgLy8gcmV0dXJuZWQgYXMgZWl0aGVyIGFuIGFycmF5IG9mIHNpbmdsZSBvYmplY3QKICAgICAgICAgICAgdmFyIG9QYXJlbnQgPSBvYmo7CiAgICAgICAgICAgIHZhciBzaSA9IDA7CiAgICAgICAgICAgIHZhciBiUm9vdE1hdGNoID0gZmFsc2U7CgogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyBTZWUgaWYgdGhlIGZpcnN0IHRva2VuIG9mIHRoZSBleHByZXNzaW9uIG1hdGNoZXMgdGhpcyBub2RlCiAgICAgICAgICAgIC8vIE9uIHRoZSBmaXJzdCBjYWxsIHRoZSBjaGlsZHJlbiBhcmUgY2hlY2tlZCBmaXJzdAogICAgICAgICAgICAvLwogICAgICAgICAgICB2YXIgb1NPTSA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlU29tRXhwcmVzc2lvbihhcnIxWzBdLCBvYmouaW5kZXgpOwogICAgICAgICAgICBpZiAoKGJGaXJzdCA9PSBmYWxzZSkgJiYgKG9TT00uZXF1YWxzKG9iaikgfHwgKG9TT00uc2NhbGVyTWF0Y2ggPT0gb2JqKSkpIHsKICAgICAgICAgICAgICAgIGJSb290TWF0Y2ggPSB0cnVlOwogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIC8vIGZvdW5kCiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgaWYgKChhcnIxLmxlbmd0aCA9PSAxKSkgewogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGV4cHJlc3Npb24gb25seSBoYXMgb25lIHRva2VuIHRoZW4gdGhlIGV4cHJlc3Npb24gbWF0Y2hlcwogICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgbm9kZQogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgaWYgKCFiTXVsdGlwbGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgeGZhbGliLnNjcmlwdC5YZmFMaXN0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuX2FwcGVuZChvYmopOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIG9QYXJlbnQgPSBvYmoucGFyZW50OwogICAgICAgICAgICAgICAgICAgIGlmIChvUGFyZW50ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb0NoaWxkcmVuID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICAgICAgICAgICAgICBvQ2hpbGRyZW4uX2FwcGVuZChvYmopOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb0NoaWxkcmVuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzaSA9IDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGV4cHJlc3Npb24gaGFzIG1vcmUgdGhhbiBvbmUgdG9rZW4gdGhlbiBzdGFydCBsb29raW5nIGZvcgogICAgICAgICAgICAgICAgICAgIC8vIGEgbWF0Y2ggb2Ygc3Vic2VxdWVudCB0b2tlbnMgd2l0aCB0aGUgY2hpbGRyZW4gb2YgdGhpcyBub2RlLgogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgc2kgPSAxOwogICAgICAgICAgICAgICAgICAgIG9TT00gPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZVNvbUV4cHJlc3Npb24oYXJyMVsxXSwgMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIG1hdGNoIHdpdGggb25lIG9mIHRoZSBjaGlsZCBub2RlcwogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIG9TT00gPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZVNvbUV4cHJlc3Npb24oYXJyMVswXSwgbkN1cnJlbnRJbmRleCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChvYmouX2lzQ29udGFpbmVyTm9kZSgpKSB7CiAgICAgICAgICAgICAgICB2YXIgYkVsaXBzaXMgPSBmYWxzZTsKCiAgICAgICAgICAgICAgICBmb3IgKCB2YXIgaiA9IHNpOyBqIDwgYXJyMS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGlmIChhcnIxW2pdID09ICIuLiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYkVsaXBzaXMgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBqKys7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqID09IGFycjEubGVuZ3RoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIG9TT00gPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZVNvbUV4cHJlc3Npb24oYXJyMVtqXSwgMCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB2YXIgYkxhc3QgPSAoKGogKyAxKSA9PSBhcnIxLmxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgb0NoaWxkcmVuID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoIShvUGFyZW50IGluc3RhbmNlb2YgeGZhbGliLnNjcmlwdC5YZmFMaXN0KSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgb1BhcmVudExpc3QgPSBuZXcgeGZhbGliLnNjcmlwdC5YZmFMaXN0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG9QYXJlbnRMaXN0Ll9hcHBlbmQob1BhcmVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG9QYXJlbnQgPSBvUGFyZW50TGlzdDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGZvciAoIHZhciBrID0gMDsgayA8IG9QYXJlbnQubGVuZ3RoOyBrKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkcmVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gb1BhcmVudC5pdGVtKGspOwogICAgICAgICAgICAgICAgICAgICAgICBpZihwYXJlbnQgIT0gbnVsbCAmJiBwYXJlbnQuX2lzQ29udGFpbmVyTm9kZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYkVsaXBzaXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IHBhcmVudC5fZmluZENoaWxkcmVuRGVlcChvU09NLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiTXVsdGlwbGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJFbGlwc2lzID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gcGFyZW50Ll9maW5kQ2hpbGRyZW4ob1NPTSwgYk11bHRpcGxlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihjaGlsZHJlbi5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IHBhcmVudC5fZmluZFByb3BlcnR5KG9TT00pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgb0NoaWxkcmVuLl9jb25jYXQoY2hpbGRyZW4pOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKG9DaGlsZHJlbi5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGJSb290TWF0Y2ggPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGlmIChiTGFzdCA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgICAgICBvU09NID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVTb21FeHByZXNzaW9uKGFycjFbaiArIDFdLCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgb1BhcmVudCA9IG9DaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChvQ2hpbGRyZW4gJiYgKG9DaGlsZHJlbi5sZW5ndGggIT0gMCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBvQ2hpbGRyZW47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgoYlJvb3RNYXRjaCA9PSB0cnVlKSB8fCAob2JqLnBhcmVudCA9PSBudWxsKSkgewogICAgICAgICAgICAgICAgaWYgKGJGaXJzdCA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAvLyBUcnkgYWdhaW4gYXR0ZW1wdGluZyB0byBtYXRjaCB0aGUgY3VycmVudCBub2RlCiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVzb2x2ZU5vZGVzQ29tbW9uKG9iaiwgc1NvbUV4cHJlc3Npb24sIGJNdWx0aXBsZSwKICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG9iai5wYXJlbnQgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVzb2x2ZU5vZGVzQ29tbW9uKG9iai5wYXJlbnQsIHNTb21FeHByZXNzaW9uLAogICAgICAgICAgICAgICAgICAgICAgICBiTXVsdGlwbGUsIGZhbHNlKTsKCiAgICAgICAgICAgICAgICBpZiAoYk11bHRpcGxlKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5YZmFMaXN0KCk7CgogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgLy8gdHJ5IHBhcmVudAogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc29sdmVOb2Rlc0NvbW1vbihvYmoucGFyZW50LCBzU29tRXhwcmVzc2lvbiwgYk11bHRpcGxlLAogICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IHJldHVybnMgd2hldGhlciB0aGUgbm9kZSBpcyBhbiBpbnN0YW5jZSBvZiBhIGNvbnRhaW5lcgogICAgICAgICAqICAgICAgICAgIE5vZGUgb3Igbm90CiAgICAgICAgICovCiAgICAgICAgX2lzQ29udGFpbmVyTm9kZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgX2lzWEZBQ29udGFpbmVyTm9kZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gcmV0dXJucyB3aGV0aGVyIHRoZSBub2RlIGlzIGFuIGluc3RhbmNlIG9mIGEgRmllbGQgb3Igbm90CiAgICAgICAgICovCiAgICAgICAgX2lzRmllbGQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IHJldHVybnMgd2hldGhlciB0aGUgbm9kZSBpcyBhbiBpbnN0YW5jZSBvZiBhIHN1YmZvcm0gb3IKICAgICAgICAgKiAgICAgICAgICBub3QKICAgICAgICAgKi8KICAgICAgICBfaXNTdWJmb3JtIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfaXNFeGNsdXNpb25Hcm91cCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgX2ZpbmRDaGlsZHJlbiA6IGZ1bmN0aW9uKG9TT00sIGJNdWx0aXBsZSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICBfZmluZENoaWxkcmVuRGVlcCA6IGZ1bmN0aW9uKG9TT00sIGJNdWx0aXBsZSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSByZXR1cm5zIHdoZXRoZXIgdGhlIG5vZGUgaXMgYW4gaW5zdGFuY2Ugb2YgYSBjb250ZW50IE5vZGUKICAgICAgICAgKiAgICAgICAgICBvciBub3QKICAgICAgICAgKi8KICAgICAgICBfaXNDb250ZW50IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfaXNFdmVudE5vZGUgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgY2xvbmUgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIGNsb25lZEpzb24gPSB7fTsKICAgICAgICAgICAgdGhpcy5jb3B5T2JqZWN0KHRoaXMuanNvbk1vZGVsLCBjbG9uZWRKc29uLHtleGNlcHRpb25zIDogWyJodG1sSWQiXX0gKTsKICAgICAgICAgICAgdmFyIG5vZGUgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZU1vZGVsKGNsb25lZEpzb24pOwogICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICB9LAoKICAgICAgICBuYWtlZEZpZWxkUmVmZXJlbmNlcyA6IGZ1bmN0aW9uKG5JbmRleCwgY3JlYXRlR2V0dGVyU2V0dGVyLG9iaikgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfSwKCiAgICAgICAgZ2V0QXR0cmlidXRlOiBmdW5jdGlvbihuYW1lLCBiUGVlaykgewogICAgICAgICAgICB2YXIgYXR0clZhbHVlID0gdW5kZWZpbmVkOwogICAgICAgICAgICAvL0J1ZyMzNjA5NDM0IDogY2hlY2sgb25seSBmb3IgdW5kZWZpbmVkCiAgICAgICAgICAgIGlmKG5hbWUgJiYgIV8uaXNVbmRlZmluZWQodGhpcy5qc29uTW9kZWxbbmFtZV0pKSB7CiAgICAgICAgICAgICAgICBhdHRyVmFsdWUgPSB0aGlzLmpzb25Nb2RlbFtuYW1lXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKGJQZWVrICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgYXR0clZhbHVlID0gdGhpcy5fZ2V0RGVmYXVsdEF0dHJpYnV0ZShuYW1lKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKG5hbWUgPT0gIm5hbWUiICYmIChfLmlzVW5kZWZpbmVkKGF0dHJWYWx1ZSkgfHwgXy5pc051bGwoYXR0clZhbHVlKSkpewogICAgICAgICAgICAgICAgLyogTEMtODE1MDogSWYgYXR0ck5hbWUgaXMgbmFtZSBhbmQgYXR0clZhbHVlIGlzIHVuZGVmaW5lZCBvciBudWxsIHRoZW4gd2UgcmV0dXJuIGVtcHR5IHN0cmluZyBpbnN0ZWFkIG9mIG51bGwuCiAgICAgICAgICAgICAgICAqIFJlYXNvbiBiZWluZyBtb3N0IG9mIHRoZSBjb2RlIGFzc3VtZSB0aGF0IGV2ZXJ5IG5vZGUgd291bGQgaGF2ZSBuYW1lIHByb3BlcnR5CiAgICAgICAgICAgICAgICAqICovCiAgICAgICAgICAgICAgICBhdHRyVmFsdWUgPSAiIjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYXR0clZhbHVlOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogY29uZGl0aW9ucyBmb3IgcHV0dGluZyBhIG5vZGUgaW4gZ2xvYmFsIGNvbnRleHQKICAgICAgICAgKiAxLiBJdCBzaG91bGQgaGF2ZSBhIG5hbWUKICAgICAgICAgKiAyLiBJdHMgaW5kZXggc2hvdWxkIG1hdGNoIHdpdGggdGhlIGluZGV4IHByb3ZpZGVkCiAgICAgICAgICogICAgICAgICAgICAgICAgICBPUgogICAgICAgICAqIDIuIFRoZXJlIHNob3VsZCBub3QgYmUgbW9yZSB0aGFuIG9uZSBub2RlIHdpdGggdGhlIHNhbWUgbmFtZSBpbiBpdHMgbm9ybWFsaXplZFBhcmVudCBCdWcjMzU5NDI4MgogICAgICAgICAqLwogICAgICAgIGdldE5ha2VkIDogZnVuY3Rpb24obkluZGV4LGNyZWF0ZUdldHRlclNldHRlcixPYmosc2NvcGUpIHsKICAgICAgICAgICAgdmFyIG5vZGVOYW1lID0gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwsICJuYW1lIiwgIiIpOwogICAgICAgICAgICBpZiAoKG5vZGVOYW1lICE9IG51bGwpICYmIChub2RlTmFtZS5sZW5ndGggIT0gMCkgJiYgKChzY29wZSAmJiBzY29wZS5tb05hbWVBcnJheVtub2RlTmFtZV0gPT0gMSkgfHwgKG5JbmRleCA9PSB0aGlzLmluZGV4KSkpIHsKICAgICAgICAgICAgICAgIC8vVE9ETzoga2VlcCBhIHN0YXRlIHdoZXRoZXIgdGhpcyBub2RlIHdhcyBwcmV2aW91c2x5IG5ha2VkIG9yIG5vdC4gSWYgeWVzIGRvIG5vdGhpbmcKICAgICAgICAgICAgICAgIHZhciBvT2JqZWN0ID0gZG9jdW1lbnRbbm9kZU5hbWVdOwogICAgICAgICAgICAgICAgaWYgKChvT2JqZWN0ID09IG51bGwpIHx8IChvT2JqZWN0IGluc3RhbmNlb2YgeGZhbGliLnNjcmlwdC5Ob2RlKSkgewogICAgICAgICAgICAgICAgICAgIGlmKGNyZWF0ZUdldHRlclNldHRlciApewogICAgICAgICAgICAgICAgICAgICAgICBpZihPYmouX3ByaXZhdGVbIl8iK25vZGVOYW1lKyJfIl09PW51bGwgfHwgT2JqLl9wcml2YXRlWyJfIitub2RlTmFtZSsiXyJdPT11bmRlZmluZWQpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlR2V0dGVyU2V0dGVyKE9iaiwgbm9kZU5hbWUsIHRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgT2JqWyJfIitub2RlTmFtZSsiXyJdID0gT2JqWyJfIitub2RlTmFtZSsiXyJdIHx8IHRoaXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZ2V0TmFrZWRUaGlzIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgdG9KU09OU3RyaW5nIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzLmpzb25Nb2RlbCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKgogICAgICAgICAqIHRoaXMgZnVuY3Rpb24gcGVyZm9ybXMgaW5pdGlhbGl6YXRpb24gZm9yIHRoaXMgbm9kZS4KICAgICAgICAgKi8KICAgICAgICBfaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewoKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqIEBmdW5jdGlvbiBpbmRpY2F0ZSB0aGF0IHRoaXMgaXMgYSBGb3JtIG5vZGUgKH5+KS4KICAgICAgICAgKi8KICAgICAgICBfaXNGb3JtIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfZGVzdHJveSA6IGZ1bmN0aW9uKG9DaGlsZCkgewogICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCggeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50Lk9CSkVDVF9ERVNUUk9ZRUQsIHRoaXMsCiAgICAgICAgICAgICAgICAnZGVzdHJveScsIG51bGwsIHRoaXMpOwogICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICB0aGlzLm9mZigpOwogICAgICAgICAgICB2YXIgcHJvcCA9ICAiXyIrdGhpcy5nZXRBdHRyaWJ1dGUoIm5hbWUiKSsiXyI7CiAgICAgICAgICAgIGlmICh4ZmFsaWIucnVudGltZS5oYXNPd25Qcm9wZXJ0eShwcm9wKSAmJiB0eXBlb2YgeGZhbGliLnJ1bnRpbWVbcHJvcF0gIT0gInVuZGVmaW5lZCIpCiAgICAgICAgICAgICAgICBpZiAoeGZhbGliLnJ1bnRpbWVbcHJvcF0uc29tRXhwcmVzc2lvbiA9PSB0aGlzLnNvbUV4cHJlc3Npb24pCiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWVbcHJvcF0gPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIHRoaXMuX3hmYSgpLl94ZmFUZW1wbGF0ZUNhY2hlLnJlbW92ZU1vZGVsKHRoaXMuaHRtbElkKTsKICAgICAgICB9LAoKICAgICAgICBfbWF0Y2hlcyA6IGZ1bmN0aW9uKG9Ob2RlKSB7CiAgICAgICAgICAgIHJldHVybiAob05vZGUgIT0gbnVsbCAmJiB0aGlzLnNvbUV4cHJlc3Npb24gPT0gb05vZGUuc29tRXhwcmVzc2lvbik7CiAgICAgICAgfSwKCiAgICAgICAgX3NldEZvY3VzIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KCB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELCB0aGlzLAogICAgICAgICAgICAgICAgJ2ZvY3VzJywgbnVsbCwgdGhpcyk7CiAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsZXZudCk7CiAgICAgICAgfSwKCiAgICAgICAgX3RlbXBsYXRlUmVmIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3hmYSgpLl94ZmFUZW1wbGF0ZUNhY2hlLmdldFRlbXBsYXRlUmVmKHRoaXMuZ2V0T3JFbHNlKHRoaXMuanNvbk1vZGVsLCAiZXh0cmFzLmh0bWxJZCIsIG51bGwpKTsKICAgICAgICB9LAoKICAgICAgICBfdGVtcGxhdGVJZCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLl90ZW1wbGF0ZVJlZigpLCAiZXh0cmFzLmh0bWxJZCIsIG51bGwpOwogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVHZXR0ZXJTZXR0ZXIgOiBmdW5jdGlvbihjb250YWluZXIsbmFtZSxvYmopIHsKICAgICAgICAgICAgdmFyIGlOYW1lID0gIl8iICsgbmFtZSArICJfIjsKICAgICAgICAgICAgaWYoIWNvbnRhaW5lci5oYXNPd25Qcm9wZXJ0eShuYW1lKSl7CiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29udGFpbmVyLG5hbWUsewogICAgICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX3ByaXZhdGVbaU5hbWVdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcHJpdmF0ZVtpTmFtZV0uX2dldE5ha2VkVGhpcygpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9iaiA9IHRoaXMuX3ByaXZhdGVbaU5hbWVdOwogICAgICAgICAgICAgICAgICAgICAgICBvYmpbb2JqLl9kZWZhdWx0XSA9IHZhbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250YWluZXIuX3ByaXZhdGVbaU5hbWVdPW9iajsKICAgICAgICB9LAoKICAgICAgICBfZ2V0RGVmYXVsdEF0dHJpYnV0ZSA6IGZ1bmN0aW9uKGF0dHJpYnV0ZSkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5feGZhKCkuX3RlbXBsYXRlU2NoZW1hLmdldERlZmF1bHRBdHRyaWJ1dGUodGhpcy5jbGFzc05hbWUsIGF0dHJpYnV0ZSk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldERlZmF1bHRFbGVtZW50IDogZnVuY3Rpb24oZWxOYW1lLCBpbmRleCwgYXBwZW5kKSB7CiAgICAgICAgICAgIHZhciByZWxhdGlvbiA9IHRoaXMuX3hmYSgpLl90ZW1wbGF0ZVNjaGVtYS5fZ2V0UmVsYXRpb24odGhpcy5jbGFzc05hbWUsIGVsTmFtZSk7CiAgICAgICAgICAgIGlmKHJlbGF0aW9uID09IHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuemVyb09yT25lIHx8IHJlbGF0aW9uID09IHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMub25lT2ZDaGlsZCB8fAogICAgICAgICAgICAgICAgKChyZWxhdGlvbiA9PSB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnplcm9PclR3byB8fCByZWxhdGlvbiA9PSB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnplcm9PckZvdXIpICYmIGluZGV4ID09IDApKXsKICAgICAgICAgICAgICAgIHZhciBkZWZhdWx0RWwgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZU1vZGVsKHtfY2xhc3MgOiBlbE5hbWV9KTsKICAgICAgICAgICAgICAgIGlmKGRlZmF1bHRFbCAmJiBhcHBlbmQpewogICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkZENoaWxkKGRlZmF1bHRFbC5fZ2V0TmFrZWRUaGlzKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRFbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICBfZ2V0RGF0YVR5cGU6IGZ1bmN0aW9uKGF0dHJpYnV0ZSkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5feGZhKCkuX3RlbXBsYXRlU2NoZW1hLl9nZXREYXRhVHlwZSh0aGlzLmNsYXNzTmFtZSwgYXR0cmlidXRlKTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0UmVsYXRpb246IGZ1bmN0aW9uKGNoaWxkKSB7CiAgICAgICAgICAgIHJldHVybiAgdGhpcy5feGZhKCkuX3RlbXBsYXRlU2NoZW1hLl9nZXRSZWxhdGlvbih0aGlzLmNsYXNzTmFtZSxjaGlsZC5jbGFzc05hbWUpOwogICAgICAgIH0sCgogICAgICAgIC8vdGhpcyBmdW5jdGlvbiBmaWx0ZXJzIHRoZSBub2RlcyBiYXNlZCBvbiBhIGZpbHRlckZuLgogICAgICAgIC8vdGhpcyBwcm9jZXNzZXMgbm90IG9ubHkgaW1tZWRpYXRlIGNoaWxkcmVuIGJ1dCBnb2VzIHJlY3Vyc2l2ZWx5IHRocm91Z2ggdGhlIHdob2xlIHRyZWUKICAgICAgICBfZmlsdGVyTm9kZXM6ZnVuY3Rpb24oZmlsdGVyRm4pIHsKICAgICAgICAgICAgdmFyIG5vZGVMaXN0ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICBpZiAodGhpcy5faXNDb250YWluZXJOb2RlKCkpIHsKICAgICAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuX2dldENoaWxkcmVuKCk7CiAgICAgICAgICAgICAgICBmb3IodmFyIGk9MDsgaTwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspewogICAgICAgICAgICAgICAgICAgIHZhciBuID0gY2hpbGRyZW4uaXRlbShpKTsKICAgICAgICAgICAgICAgICAgICBpZihmaWx0ZXJGbihuKSkKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUxpc3QuX2FwcGVuZChuKTsKICAgICAgICAgICAgICAgICAgICBub2RlTGlzdC5fY29uY2F0KG4uX2ZpbHRlck5vZGVzKGZpbHRlckZuKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5vZGVMaXN0OwogICAgICAgIH0sCgogICAgICAgIGdldEVsZW1lbnQ6IGZ1bmN0aW9uKGNsYXNzTmFtZSxpbmRleCwgYlBlZWspIHsKICAgICAgICAgICAgaW5kZXggPSBpbmRleCB8fCAwOwogICAgICAgICAgICB2YXIgYXJyID0gdGhpcy5fZmluZENoaWxkcmVuKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlU29tRXhwcmVzc2lvbihjbGFzc05hbWUrIlsiK2luZGV4KyJdIiksZmFsc2UpOwogICAgICAgICAgICBpZihhcnIgJiYgYXJyLmxlbmd0aCA+MCkKICAgICAgICAgICAgICAgIHJldHVybiBhcnIuaXRlbSgwKTsKICAgICAgICAgICAgZWxzZSBpZighYlBlZWsgJiYgKHRoaXMuX2dldE9uZU9mQ2hpbGQgJiYgICF0aGlzLl9nZXRPbmVPZkNoaWxkKHRydWUpKSkKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXREZWZhdWx0RWxlbWVudChjbGFzc05hbWUsIGluZGV4LCB0cnVlKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgc2V0RWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgY2xhc3NOYW1lLGluZGV4KXsKICAgICAgICAgICAgaWYoXy5pc051bWJlcihlbGVtZW50KSB8fCBfLmlzQm9vbGVhbihlbGVtZW50KSB8fCBfLmlzRGF0ZShlbGVtZW50KSB8fCBfLmlzU3RyaW5nKGVsZW1lbnQpKXsKICAgICAgICAgICAgICAgIHZhciBjaGlsZE5vZGUgPSB0aGlzLmdldEVsZW1lbnQoY2xhc3NOYW1lLCBpbmRleCk7CiAgICAgICAgICAgICAgICBpZihjaGlsZE5vZGUgJiYgY2hpbGROb2RlLl9kZWZhdWx0KXsKICAgICAgICAgICAgICAgICAgICBjaGlsZE5vZGVbY2hpbGROb2RlLl9kZWZhdWx0XSA9IGVsZW1lbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgc2V0QXR0cmlidXRlOiBmdW5jdGlvbih2YWx1ZSwgYXR0ck5hbWUpewogICAgICAgICAgICB0aGlzLmpzb25Nb2RlbFthdHRyTmFtZV0gPSB0aGlzLnZhbGlkYXRlSW5wdXQodmFsdWUsIHRoaXMuX2dldERhdGFUeXBlKGF0dHJOYW1lKSx0aGlzLmpzb25Nb2RlbFthdHRyTmFtZV0pOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiB0aGUgRGF0YVNPTU1hcCBhZnRlciBhZGRpbmcgYW4gZW50cnkgaW4gdGhlIG1hcCBmb3IgdGhlIG5vZGUuIFRoZSBlbnRyeSBjb250YWlucyB0aGUgdmFsdWUgb2YgdGhlIG5vZGUKICAgICAgICAgKiBhbG9uZyB3aXRoIGl0cyBEYXRhIFNPTS4gSWYgdGhlcmUgaXMgbm8gRGF0YSBTT00gdGhlbiByZXR1cm4gdGhlIHVubW9kaWZpZWQgbWFwCiAgICAgICAgICogQHBhcmFtIG1hcAogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2dldERhdGFTb21NYXAgOiBmdW5jdGlvbihtYXApIHsKICAgICAgICAgICAgcmV0dXJuIG1hcDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBVcGRhdGUgdGhlIHZhbHVlIG9mIHRoZSBub2RlIHdpdGggdGhlIHZhbHVlIHByb3ZpZGVkIGluIHRoZSBpbnB1dCBtYXAuIFRoZSBtYXAgY29udGFpbnMgdGhlIHZhbHVlcyBvZiB0aGUgZmllbGRzCiAgICAgICAgICogbWFwcGVkIHdpdGggdGhlaXIgRGF0YVNPTS4gVGhlIGZ1bmN0aW9uIGlzIGVtcHR5IGZvciBhbGwgdGhlIG5vZGVzLCBleGNlcHQgZm9yIEZpZWxkLCBTdWJmb3JtIGFuZCBBcmVhLgogICAgICAgICAqIEBwYXJhbSBtYXAKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9yZXN0b3JlRGF0YVNvbU1hcCA6IGZ1bmN0aW9uIChtYXApIHsKCiAgICAgICAgfSwKCiAgICAgICAgX3BsYXlEYXRhWE1MOiBmdW5jdGlvbih4bWxEb2N1bWVudCwgY29udGV4dE5vZGUpIHsKCiAgICAgICAgfSwKCiAgICAgICAgZ2VuZXJhdGVEYXRhWE1MOiBmdW5jdGlvbihyb290Tm9kZSwgY29udGV4dE5vZGUpIHsKCiAgICAgICAgfQoKICAgIH0pOwoKICAgIE5vZGUuZGVmaW5lUHJvcHMoewogICAgICAgICJwYXJlbnQiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1QYXJlbnQ7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHBhcmVudCkgewogICAgICAgICAgICAgICAgcGFyZW50ID0gdGhpcy52YWxpZGF0ZUlucHV0KHBhcmVudCwgIm9iamVjdCIsbnVsbCk7CiAgICAgICAgICAgICAgICB0aGlzLm1QYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHJlc29sdmU6dHJ1ZQogICAgICAgIH0sCgogICAgICAgICJuYW1lIiAgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHNOYW1lKSB7CiAgICAgICAgICAgICAgICAvL3NOYW1lID0gdGhpcy52YWxpZGF0ZUlucHV0KHNOYW1lLCAic3RyaW5nIik7CiAgICAgICAgICAgICAgICAvL3RoaXMuanNvbk1vZGVsLm5hbWUgPSBzTmFtZTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgY29uZmlndXJhYmxlOnRydWUKICAgICAgICB9LAoKICAgICAgICAibm9kZXMiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9pc0NvbnRhaW5lck5vZGUoKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRDaGlsZHJlbigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LlhmYUxpc3QoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJpbmRleCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubW5JbmRleDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24obkluZGV4KSB7CiAgICAgICAgICAgICAgICBuSW5kZXggPSB0aGlzLnZhbGlkYXRlSW5wdXQobkluZGV4LCAiaW50ZWdlciIsdGhpcy5tbkluZGV4KTsKICAgICAgICAgICAgICAgIHRoaXMubW5JbmRleCA9IG5JbmRleDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJzb21FeHByZXNzaW9uIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0U29tRXhwcmVzc2lvbigpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZXJyb3IoInhmYSIsIHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAwNiJdLFsic2V0dGluZyBTb21FeHByZXNzaW9uIl0pCiAgICAgICAgICAgICAgICB0aHJvdyAidW5zdXBwb3J0ZWQgb3BlcmF0aW9uIjsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJpc0NvbnRhaW5lciIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2lzWEZBQ29udGFpbmVyTm9kZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImh0bWxJZCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwsICJleHRyYXMuaHRtbElkIiwgbnVsbCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHNIdG1sSWQpewogICAgICAgICAgICAgICAgdGhpcy5qc29uTW9kZWwuZXh0cmFzID0gdGhpcy5qc29uTW9kZWwuZXh0cmFzIHx8IHt9OwogICAgICAgICAgICAgICAgdGhpcy5qc29uTW9kZWwuZXh0cmFzLmh0bWxJZCA9IHNIdG1sSWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAiaXNOdWxsIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJhbGwiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgeGZhbGliLnNjcmlwdC5YZmFMaXN0KCk7CiAgICAgICAgICAgICAgICB2YXIgc29tID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVTb21FeHByZXNzaW9uKHRoaXMuanNvbk1vZGVsLm5hbWUrIlsqXSIpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmpzb25Nb2RlbC5uYW1lKSAgewogICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLnBhcmVudCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBhcmVudC5fZmluZENoaWxkcmVuRGVlcChzb20sIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHJldHVybiBsaXN0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHRocm93ICJOYW1lIHVuZGVmaW5lZCIgOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2F0Y2goZSkgICB7CiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcigiR2V0IG9wZXJhdGlvbiBhbGwgcmVxdWlyZXMgdGhlIG5vZGUgdG8gaGF2ZSBhIG5hbWUiKTsKICAgICAgICAgICAgICAgIH0KCgogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImV4dHJhcyIgOnsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsMCkKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKfSkoXywgeGZhbGliKTsKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5FbGVtZW50CiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Ob2RlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgRWxlbWVudCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBCiAqICAgICAgICAgICAgICAgbGlicmFyeQogKiBAdmVyc2lvbiAwLjAuMgogKi8KCihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICAvKioKICAgICAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyBhbGwgdGhlIFhGQSBPYmplY3RzIHdoaWNoIGNhbiBjb250YWluIG90aGVyIFhGQQogICAgICogICAgICAgIG5vZGVzIGluc2lkZSB0aGVtCiAgICAgKiBAZXh0ZW5kcyBjb20uYWRvYmUueGZhLnNjcmlwdGluZy5Ob2RlCiAgICAgKgogICAgICogQHByb3BlcnR5IHtBcnJheX0gY2hpbGRyZW4gY2hpbGRyZW4gb2YgdGhlIEVsZW1lbnQKICAgICAqCiAgICAgKiBAY29uc3RydWN0b3IKICAgICAqIEBwYXJhbSB7c3RyaW5nfQogICAgICogICAgICAgICAgICBuYW1lIHRoZSBuYW1lIG9mIHRoZSBub2RlCiAgICAgKgogICAgICogQHR5cGUgeyp8dm9pZH0KICAgICAqLwogICAgdmFyIEVsZW1lbnQgPSB4ZmFsaWIuc2NyaXB0LkVsZW1lbnQgPSB4ZmFsaWIuc2NyaXB0Lk5vZGUuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBFbGVtZW50Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX21vQ2hpbGROb2RlcyA9IFtdOwogICAgICAgICAgICB0aGlzLm1uQ3VycmVudEluZGV4ID0gLTE7CiAgICAgICAgICAgIHRoaXMubW9OYW1lQXJyYXkgPSBuZXcgT2JqZWN0KCk7CiAgICAgICAgICAgIHRoaXMubW9Ob3JtYWxpemVkQ2hpbGRyZW4gPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5fcHJpdmF0ZSA9IHt9OwogICAgICAgICAgICB0aGlzLl9pbml0Q2hpbGRyZW4oKTsKICAgICAgICB9LAoKICAgICAgICBfaW5pdENoaWxkcmVuOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IG5ldyBBcnJheSgpOwogICAgICAgICAgICB2YXIgbGFzdENyZWF0ZWRJbnN0YW5jZU1hbmFnZXIgPSBudWxsOwoKICAgICAgICAgICAgaWYgKHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuKSB7CiAgICAgICAgICAgICAgICB2YXIgaiA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5qc29uTW9kZWwuY2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkTW9kZWwgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZU1vZGVsKGNoaWxkKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRNb2RlbCBpbnN0YW5jZW9mIHhmYWxpYi5zY3JpcHQuSW5zdGFuY2VNYW5hZ2VyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RDcmVhdGVkSW5zdGFuY2VNYW5hZ2VyID0gY2hpbGRNb2RlbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY2hpbGRNb2RlbCBpbnN0YW5jZW9mIHhmYWxpYi5zY3JpcHQuU3ViZm9ybSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAobGFzdENyZWF0ZWRJbnN0YW5jZU1hbmFnZXIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RDcmVhdGVkSW5zdGFuY2VNYW5hZ2VyLm5hbWUubGVuZ3RoID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdENyZWF0ZWRJbnN0YW5jZU1hbmFnZXIubmFtZSA9ICJfIiArIGNoaWxkTW9kZWwubmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RDcmVhdGVkSW5zdGFuY2VNYW5hZ2VyLl9tYW5hZ2VDaGlsZChjaGlsZE1vZGVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRNb2RlbCkgewogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbltqKytdID0gY2hpbGRNb2RlbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLmNoaWxkcmVuID0gY2hpbGRyZW47CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZ2V0Q2hpbGRyZW46IGZ1bmN0aW9uIChjaGlsZCkgewogICAgICAgICAgICB2YXIgcGFyZW50ID0gdGhpczsKICAgICAgICAgICAgdmFyIG9iaiA9IHsicGFyZW50IjogcGFyZW50fTsKICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgeGZhbGliLnNjcmlwdC5YZmFMaXN0KG9iaik7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tb0NoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIGxpc3QuX2FwcGVuZCh0aGlzLm1vQ2hpbGROb2Rlc1tpXS5fZ2V0TmFrZWRUaGlzKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBmdW5jdGlvbnMgYWRkcyBhIGNoaWxkIHRvIHRoaXMgY29udGFpbmVyTm9kZQogICAgICAgICAqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHBhcmFtIHtub2RlfQogICAgICAgICAqICAgICAgICAgICAgY2hpbGQgVGhlIGNoaWxkIG5vZGUgdG8gYWRkIHRvIHRoaXMgRWxlbWVudAogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgX2FkZENoaWxkOiBmdW5jdGlvbiAoY2hpbGQpIHsKICAgICAgICAgICAgaWYgKGNoaWxkICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2FkZENoaWxkQXQoY2hpbGQsIHRoaXMubW9DaGlsZE5vZGVzLmxlbmd0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqIEBmdW5jdGlvbiByZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIHNjb3BlbGVzcyBjb250YWluZXIKICAgICAgICAgKgogICAgICAgICAqLwogICAgICAgIHNjb3BlbGVzczogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgLy9pbmNsdWRlRG9tRWxlbWVudCB0ZWxscyB3aGV0aGVyIERPTUVsZW1lbnQgc2hvdWxkIGJlIGVzY2FsYXRlZCB0byB0aGVpciBwYXJlbnQKICAgICAgICBhcHBlbmROb3JtYWxpemVkQ2hpbGRyZW46IGZ1bmN0aW9uIChvTm9ybWFsaXplZENoaWxkcmVuLCBpbmNsdWRlRG9tRWxlbWVudCkgewogICAgICAgICAgICB2YXIgaSA9IDA7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLm1vQ2hpbGROb2Rlcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIG9DaGlsZCA9IHRoaXMubW9DaGlsZE5vZGVzW2ldOwogICAgICAgICAgICAgICAgaWYgKG9DaGlsZCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgLy9DUS0xMDIzNDEgOiBib3JkZXIgY2hpbGQgb2YgdW5uYW1lZCBzdWJmb3JtIHdhcyBnZXR0aW5nIGFwcGVuZGVkIHRvIHBhcmVudCBzdWJmb3JtCiAgICAgICAgICAgICAgICAgICAgaWYoaW5jbHVkZURvbUVsZW1lbnQgPT09IHRydWUgfHwgIShvQ2hpbGQgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LmRvbS5Cb3JkZXIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9Ob3JtYWxpemVkQ2hpbGRyZW4ucHVzaChvQ2hpbGQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgb0NvbnRhaW5lciA9IG9DaGlsZDsKICAgICAgICAgICAgICAgICAgICBpZiAob0NvbnRhaW5lcgogICAgICAgICAgICAgICAgICAgICAgICAmJiAob0NvbnRhaW5lci5faXNDb250YWluZXJOb2RlKCkgJiYgb0NvbnRhaW5lci5zY29wZWxlc3MoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb0NvbnRhaW5lci5hcHBlbmROb3JtYWxpemVkQ2hpbGRyZW4ob05vcm1hbGl6ZWRDaGlsZHJlbiwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICoKICAgICAgICAgKiBhZGRzIGEgZHluYW1pYyBwcm9wZXJ0eSB0byB0aGlzIGNvbnRhaW5lci4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBzTmFtZQogICAgICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGJlIGFkZGVkLgogICAgICAgICAqIEBwYXJhbSBvVmFsdWVPYmplY3QKICAgICAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgdGhhdCBpcyBhZGRlZC4KICAgICAgICAgKiBAcmV0dXJuIHRoZSAwIGJhc2VkIGluZGV4IG9mIHRoZSBwcm9wZXJ0eSBuYW1lLgogICAgICAgICAqLwogICAgICAgIF9hZGRQcm9wZXJ0eTogZnVuY3Rpb24gKHNOYW1lLCBvVmFsdWVPYmplY3QsIGNyZWF0ZUdldHRlclNldHRlcikgewogICAgICAgICAgICB2YXIgbkluZGV4ID0gMDsKICAgICAgICAgICAgaWYgKChzTmFtZSAhPSBudWxsKSAmJiAoc05hbWUubGVuZ3RoID4gMCkpIHsKICAgICAgICAgICAgICAgIGlmIChvVmFsdWVPYmplY3QgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgLy8ganVzdCByZXNldCBpdAogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXNbc05hbWVdKQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzW3NOYW1lXSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb05hbWVBcnJheVtzTmFtZV0gPSAwOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgIC8vIGFkZCBpdCBhcyBhIHByb3BlcnR5IGFsc28ga2VlcCB0cmFjayBvZiB0aGUgaW5kZXgKICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgIHRoaXMubW9OYW1lQXJyYXlbc05hbWVdID0gdGhpcy5tb05hbWVBcnJheVtzTmFtZV0gfHwgbkluZGV4OwogICAgICAgICAgICAgICAgICAgIG5JbmRleCA9IHRoaXMubW9OYW1lQXJyYXlbc05hbWVdKys7CiAgICAgICAgICAgICAgICAgICAgaWYgKG5JbmRleCA9PSAwICYmIGNyZWF0ZUdldHRlclNldHRlcikgewogICAgICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IHB1dCB0aGUgZmlyc3QgaW5zdGFuY2UgYXMgYSBwcm9wZXJ0eSBvZiB0aGUgY29udGFpbmVyCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvbid0IG92ZXJ3cml0ZSBub24gZHluYW1pYyBwcm9wZXJ0aWVzCiAgICAgICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUdldHRlclNldHRlcih0aGlzLCBzTmFtZSwgb1ZhbHVlT2JqZWN0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5JbmRleDsKICAgICAgICB9LAoKICAgICAgICBub3JtYWxpemVDaGlsZHJlbjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLm1vTm9ybWFsaXplZENoaWxkcmVuID0gbmV3IEFycmF5KCk7CiAgICAgICAgICAgIHRoaXMuYXBwZW5kTm9ybWFsaXplZENoaWxkcmVuKHRoaXMubW9Ob3JtYWxpemVkQ2hpbGRyZW4sIHRydWUpOwogICAgICAgICAgICB2YXIgYlNjb3BlbGVzcyA9IHRoaXMuc2NvcGVsZXNzKCk7CgogICAgICAgICAgICBpZiAoYlNjb3BlbGVzcykgewogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIC8vIG11c3Qgc2NvcGUgY2hpbGRyZW4gaW4gdGhlIHBhcmVudCBjb250YWluZXIKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICB2YXIgb1BhcmVudCA9IHRoaXMucGFyZW50OwogICAgICAgICAgICAgICAgaWYgKG9QYXJlbnQgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBvUGFyZW50Lm5vcm1hbGl6ZUNoaWxkcmVuKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBpID0gMDsKICAgICAgICAgICAgdGhpcy5tb05hbWVBcnJheSA9IG5ldyBPYmplY3QoKTsKICAgICAgICAgICAgZm9yICg7IGkgPCB0aGlzLm1vTm9ybWFsaXplZENoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB2YXIgb0NoaWxkID0gdGhpcy5tb05vcm1hbGl6ZWRDaGlsZHJlbltpXTsKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAvLyBTZXQgcHJvcGVydGllcyBhbmQgaW5kaWNlcyBiYXNlZCBvbiBub3JtYWxpemVkIGNoaWxkcmVuCiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgdmFyIGNyZWF0ZUdldHRlclNldHRlciA9IHRoaXMuX3JlcXVpcmVHZXR0ZXJTZXR0ZXIob0NoaWxkKTsKICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX2FkZFByb3BlcnR5KHRoaXMuZ2V0T3JFbHNlKG9DaGlsZC5qc29uTW9kZWwsICJuYW1lIiwgIiIpLCBvQ2hpbGQsIGNyZWF0ZUdldHRlclNldHRlcik7CiAgICAgICAgICAgICAgICB2YXIgY2xhc3NJbmRleCA9IHRoaXMuX2FkZFByb3BlcnR5KCcjJyArIG9DaGlsZC5jbGFzc05hbWUsIG9DaGlsZCwgZmFsc2UpOwogICAgICAgICAgICAgICAgaWYgKCFiU2NvcGVsZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAvLyBzY29wZSBpbmRleGVzIHJlbGF0aXZlIHRvIHRoaXMgY29udGFpbmVyCiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICBvQ2hpbGQuaW5kZXggPSBpbmRleDsKICAgICAgICAgICAgICAgICAgICBvQ2hpbGQubW5DbGFzc0luZGV4ID0gY2xhc3NJbmRleDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IHJldHVybnMgd2hldGhlciB0aGUgbm9kZSBpcyBhbiBpbnN0YW5jZSBvZiBhIGNvbnRhaW5lcgogICAgICAgICAqICAgICAgICAgIE5vZGUgb3Igbm90CiAgICAgICAgICovCiAgICAgICAgX2lzQ29udGFpbmVyTm9kZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBfcmVxdWlyZUdldHRlclNldHRlcjogZnVuY3Rpb24gKG9DaGlsZCkgewogICAgICAgICAgICAvL1Rlc3RzIHdoZXRoZXIgZHluYW1pYyBnZXR0ZXIvc2V0dGVyIHNob3VsZCBiZSBnZW5lcmF0ZWQgZm9yIHRoaXMgY2hpbGQgd2hpY2ggaGFwcGVucyBmb3IgaW5maW5pdGUgY2FyZGluYWxpdHkKICAgICAgICAgICAgdmFyIHJlbGF0aW9uID0gdGhpcy5fZ2V0UmVsYXRpb24ob0NoaWxkKTsKICAgICAgICAgICAgcmV0dXJuIChyZWxhdGlvbiA9PSBudWxsIHx8IHJlbGF0aW9uLm1heCA9PSBJbmZpbml0eSk7CiAgICAgICAgfSwKCiAgICAgICAgX2ZpbmRDaGlsZHJlbjogZnVuY3Rpb24gKG9TT00sIGJNdWx0aXBsZSkgewogICAgICAgICAgICB2YXIgYXJyID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICB2YXIgZWxlbUZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdGhpcy5tb05vcm1hbGl6ZWRDaGlsZHJlbi5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgdmFyIG9DaGlsZCA9IHRoaXMubW9Ob3JtYWxpemVkQ2hpbGRyZW5bal07CiAgICAgICAgICAgICAgICB2YXIgcmVsYXRpb24gPSB0aGlzLl9nZXRSZWxhdGlvbihvQ2hpbGQpOwogICAgICAgICAgICAgICAgaWYgKG9TT00uZXF1YWxzKG9DaGlsZCkgfHwgKHJlbGF0aW9uICYmIHJlbGF0aW9uLm1heCAhPSBJbmZpbml0eSAmJiBvU09NLnRhZ0VxdWFscyhvQ2hpbGQpKSkgewogICAgICAgICAgICAgICAgICAgIGFyci5fYXBwZW5kKG9DaGlsZC5fZ2V0TmFrZWRUaGlzKCkpOwogICAgICAgICAgICAgICAgICAgIGVsZW1Gb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZWxlbUZvdW5kICYmICFiTXVsdGlwbGUpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFycjsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVsZW1Gb3VuZCAmJiBvU09NLmluZGV4ICE9ICcqJykKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG9TT00uc2NhbGVyTWF0Y2ggIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKGJNdWx0aXBsZSA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgIGFyci5fYXBwZW5kKG9TT00uc2NhbGVyTWF0Y2guX2dldE5ha2VkVGhpcygpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gYXJyID0gW107CiAgICAgICAgICAgICAgICAgICAgLy8gYXJyLmxlbmd0aCA9IG9TT00uc2NhbGFyTWF0Y2g7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBhcnI7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKgogICAgICAgICAqIGxpa2UgX2ZpbmRDaGlsZHJlbiBidXQgc2VhcmNoZXMgZGVlcCBmb3IgYSBtYXRjaAogICAgICAgICAqLwogICAgICAgIF9maW5kQ2hpbGRyZW5EZWVwOiBmdW5jdGlvbiAob1NPTSwgYk11bHRpcGxlKSB7CiAgICAgICAgICAgIHZhciBvT2JqZWN0ID0gdGhpcy5fZmluZENoaWxkcmVuKG9TT00sIGJNdWx0aXBsZSk7CiAgICAgICAgICAgIGlmIChvT2JqZWN0ID09IG51bGwgfHwgb09iamVjdC5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgdmFyIG9DaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW47CiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG9DaGlsZHJlbi5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIG9PYmplY3QgPSBvQ2hpbGRyZW5bal0uX2ZpbmRDaGlsZHJlbkRlZXAob1NPTSwgYk11bHRpcGxlKTsKICAgICAgICAgICAgICAgICAgICBpZiAob09iamVjdCAmJiBvT2JqZWN0Lmxlbmd0aCA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBvT2JqZWN0OwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICoKICAgICAgICAgKiBnZXQgdGhlIGluZGV4IG9mIHRoZSBzcGVjaWZpZWQgY2hpbGQuCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge2NvbS5hZG9iZS54ZmEuc2NyaXB0aW5nLk5vZGV9CiAgICAgICAgICogICAgICAgICAgICBvTm9kZSB0aGUgbm9kZSBvZiB3aGljaCB0aGUgaW5kZXggaXMgdG8gYmUgZm91bmQuCiAgICAgICAgICogQHJldHVybiB7bnVtYmVyfSB0aGUgMCBiYXNlZCBpbmRleCBvZiB0aGUgbm9kZSBvciAtMSBpZiBub3QgZm91bmQuCiAgICAgICAgICovCiAgICAgICAgX2dldENoaWxkSW5kZXg6IGZ1bmN0aW9uIChvTm9kZSkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5tb0NoaWxkTm9kZXMuaW5kZXhPZihvTm9kZSk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKgogICAgICAgICAqIGFkZCBzcGVjaWZpZWQgY2hpbGQgdG8gdGhlIHNwZWNpZmllZCBpbmRleC4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBvTm9kZQogICAgICAgICAqICAgICAgICAgICAgdGhlIG5vZGUgdG8gYmUgYWRkZWQuCiAgICAgICAgICogQHBhcmFtIG5JTmRleAogICAgICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHdoZXJlIHRoZSBjaGlsZCB3aWxsIGJlIGluc2VydGVkLgogICAgICAgICAqLwogICAgICAgIF9hZGRDaGlsZEF0OiBmdW5jdGlvbiAob05vZGUsIG5JbmRleCkgewogICAgICAgICAgICB0aGlzLm1vQ2hpbGROb2Rlcy5zcGxpY2UobkluZGV4LCAwLCBvTm9kZSk7CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuID0gdGhpcy5qc29uTW9kZWwuY2hpbGRyZW4gfHwgW107CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuLnNwbGljZShuSW5kZXgsIDAsIG9Ob2RlLmpzb25Nb2RlbCk7CiAgICAgICAgICAgIG9Ob2RlLnBhcmVudCA9IHRoaXM7CiAgICAgICAgICAgIHRoaXMubm9ybWFsaXplQ2hpbGRyZW4oKTsKICAgICAgICAgICAgdGhpcy5fcG9zdEFkZENoaWxkKG9Ob2RlKTsKICAgICAgICB9LAoKICAgICAgICBfcG9zdEFkZENoaWxkOiBmdW5jdGlvbiAob05vZGUpIHsKICAgICAgICAgICAgb05vZGUuX2luaXRpYWxpemUoKTsKICAgICAgICAgICAgaWYgKG9Ob2RlIGluc3RhbmNlb2YgeGZhbGliLnNjcmlwdC5ET01FbGVtZW50IHx8IG9Ob2RlIGluc3RhbmNlb2YgeGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dCkgewogICAgICAgICAgICAgICAgb05vZGUub24oeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkRPTV9DSEFOR0VELCB0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9kZXN0cm95OiBmdW5jdGlvbiAob0NoaWxkKSB7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tb0NoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IHRoaXMubW9DaGlsZE5vZGVzW2ldOwogICAgICAgICAgICAgICAgaWYgKGNoaWxkICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgY2hpbGQuX2Rlc3Ryb3koKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBFbGVtZW50Ll9zdXBlci5fZGVzdHJveS5jYWxsKHRoaXMsIG9DaGlsZCk7CiAgICAgICAgfSwKCiAgICAgICAgX3JlbW92ZUFsbDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBfLmVhY2godGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uIChvQ2hpbGQsIGluZGV4KSB7CiAgICAgICAgICAgICAgICBvQ2hpbGQuX2Rlc3Ryb3koKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHRoaXMubW9DaGlsZE5vZGVzID0gW107CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuID0gW107CiAgICAgICAgICAgIHRoaXMubm9ybWFsaXplQ2hpbGRyZW4oKTsKICAgICAgICAgICAgLy9Ub0RvIGFkZCBldmVudCB0cmlnZ2VyIGxpa2UgX3JlbW92ZSBtZXRob2QgaWYgcmVxdWlyZWQKICAgICAgICB9LAoKICAgICAgICBfcmVtb3ZlQ2hpbGQ6IGZ1bmN0aW9uIChvQ2hpbGQpIHsKICAgICAgICAgICAgb0NoaWxkLl9kZXN0cm95KCk7CiAgICAgICAgICAgIHZhciBuSW5kZXggPSB0aGlzLm1vQ2hpbGROb2Rlcy5pbmRleE9mKG9DaGlsZCk7CiAgICAgICAgICAgIHRoaXMubW9DaGlsZE5vZGVzLnNwbGljZShuSW5kZXgsIDEpOwogICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC5jaGlsZHJlbi5zcGxpY2UobkluZGV4LCAxKTsKICAgICAgICAgICAgdGhpcy5ub3JtYWxpemVDaGlsZHJlbigpOwogICAgICAgICAgICB0aGlzLl9wb3N0UmVtb3ZlQ2hpbGQob0NoaWxkKTsKICAgICAgICB9LAoKICAgICAgICBfcG9zdFJlbW92ZUNoaWxkOiBmdW5jdGlvbiAob0NoaWxkKSB7CiAgICAgICAgICAgIC8vZG8gbm90aGluZyBoZXJlCiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKgogICAgICAgICAqIGluaXRpYWxpemUgdGhpcyBDb250YWluZXIgTm9kZQogICAgICAgICAqLwogICAgICAgIF9pbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmICgodGhpcy5tb0NoaWxkTm9kZXMgPT0gbnVsbCkgfHwgKHRoaXMubW9DaGlsZE5vZGVzLmxlbmd0aCA9PSAwKSkgewogICAgICAgICAgICAgICAgdGhpcy5tYkluaXRpYWxpemVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRoaXMuX3hmYSgpID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRocm93ICh4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDMiXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEluaXQgdGhpcwogICAgICAgICAgICBpZiAodGhpcy5wYXJlbnQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhpcy5pbmRleCA9IDA7CiAgICAgICAgICAgICAgICAvL3RoaXMuX3hmYSgpLl9wdXNoQ29udGV4dE5vZGUodGhpcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIGxvb3AgdGhyb3VnaCB0aGUgY29udHJvbHMgdGhhdCBhcmUgY2hpbGQgY29tcG9uZW50cyBvZiB0aGlzIGNvbnRhaW5lcgogICAgICAgICAgICAvLyBjb3B5IGludG8gYXJyYXksIHNpbmNlIG1vQ2hpbGROb2RlcyBtYXkgYmUgbW9kaWZpZWQgYXMgd2UgaW5pdGlhbGl6ZQogICAgICAgICAgICAvLyBJbnN0YW5jZU1hbmFnZXJzCiAgICAgICAgICAgIC8vCgogICAgICAgICAgICB2YXIgb0NoaWxkcmVuID0gdGhpcy5tb0NoaWxkTm9kZXM7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb0NoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB2YXIgb05vZGUgPSBvQ2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICBpZiAob05vZGUgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmVycm9yKCJ4ZmEiLCB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDQiXSwgW3RoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIiksIGldKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBvTm9kZS5faW5pdGlhbGl6ZSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLm1iSW5pdGlhbGl6ZWQgPSB0cnVlOwoKICAgICAgICB9LAoKICAgICAgICBwbGF5SnNvbjogZnVuY3Rpb24gKHBKc29uTW9kZWwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogcGxheUpzb24gYXNzdW1wdGlvbjogVGhlIG5vbiBkb20gZWxlbWVudHMgc2hvdWxkIGFsd2F5cyBtYWludGFpbiB0aGUgc3RydWN0dXJhbCBoaWVyYXJjaHkuCiAgICAgICAgICAgICAqIEZvciBkb20gZWxlbWVudHMsIHdlIHN1cHBvcnQgb25seSB2YWx1ZSBhbmQgaXRlbXMuIHJlc3QgYXJlIGlnbm9yZWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBFbGVtZW50Ll9zdXBlci5wbGF5SnNvbi5jYWxsKHRoaXMsIHBKc29uTW9kZWwpOwogICAgICAgICAgICB2YXIgc2NoZW1hQ2hpbGRyZW4gPSB0aGlzLl94ZmEoKS5fdGVtcGxhdGVTY2hlbWEuZ2V0Q2hpbGRyZW4odGhpcy5jbGFzc05hbWUpOwogICAgICAgICAgICBfLmVhY2goc2NoZW1hQ2hpbGRyZW4sIGZ1bmN0aW9uIChzY2hlbWFDaGlsZFByb3BzLCBzY2hlbWFDaGlsZFRhZykgewogICAgICAgICAgICAgICAgLy8gaWYgc2NoZW1hQ2hpbGRUYWcgaXMgYSBET01lbGVtIG90aGVyIHRoYW4gaXRlbXMsdmFsdWUgY29udGludWUKICAgICAgICAgICAgICAgIGlmICh4ZmFsaWIuc2NyaXB0LmRvbVtzY2hlbWFDaGlsZFRhZy5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHNjaGVtYUNoaWxkVGFnLnN1YnN0cmluZygxKV0gIT09IHVuZGVmaW5lZCAvLyBUT0RPIDogdGFrZSBjYXJlIG9mIHRob3NlIGRvbUVsZW1lbnRzIHdpdGggMm5kIG9yZGVyIGluaGVyaXRhbmNlCiAgICAgICAgICAgICAgICAgICAgJiYgIV8uY29udGFpbnMoWyJ2YWx1ZSIsICJpdGVtcyJdLCBzY2hlbWFDaGlsZFRhZykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAodGhpcy5wbGF5SnNvbkZvckVsZW1lbnQoc2NoZW1hQ2hpbGRUYWcsIHBKc29uTW9kZWwpKSB7ICAgLy8gY29udGludWUgaWYgdGhpcyBjaGlsZFRhZyBoYXMgc3BlY2lhbCBoYW5kbGluZwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgcmVsYXRpb24gPSBzY2hlbWFDaGlsZFByb3BzLnJlbGF0aW9uOwogICAgICAgICAgICAgICAgdmFyIG5ld0pDaGlsZHJlbiA9IF8uZmlsdGVyKF8uY29tcGFjdChwSnNvbk1vZGVsLmNoaWxkcmVuKSwgZnVuY3Rpb24gKGpDaGlsZCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBqQ2hpbGQuX2NsYXNzID09IHNjaGVtYUNoaWxkVGFnOwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICB2YXIgb2xkTUNoaWxkcmVuID0gXy5maWx0ZXIodGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uIChtQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbUNoaWxkLmNsYXNzTmFtZSA9PSBzY2hlbWFDaGlsZFRhZzsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICAgICAgdmFyIG9uZU9mQ2hpbGRQcm9jZXNzZWQgPSBmYWxzZTsKCiAgICAgICAgICAgICAgICAvLyB0byBtZXJnZSBmaWVsZCBpdGVtcyBoYXZpbmcgYmluZ2RJdGVtcyBwcm9wZXJ0eQogICAgICAgICAgICAgICAgLy8gaG9ub3VyIHNhdmVQcm9wZXJ0eSB3aGlsZSBwbGF5aW5nSnNvbiBmb3IgbmV3IGFuZCBvbGQgY2hpbGRyZW4KICAgICAgICAgICAgICAgIC8vIGl0ZW1zIGhhdmUgemVyb09yVHdvIHJlbGF0aW9uCiAgICAgICAgICAgICAgICBpZiAoc2NoZW1hQ2hpbGRUYWcgPT0gIml0ZW1zIiAmJiB0aGlzLmdldEVsZW1lbnQoIiNiaW5kSXRlbXMiKSAmJiBvbGRNQ2hpbGRyZW4ubGVuZ3RoICYmIG5ld0pDaGlsZHJlbi5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRJbmRleCA9IC0xLAogICAgICAgICAgICAgICAgICAgICAgICBuZXdDaGlsZCA9IG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgIG9sZENoaWxkID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBjaGlsZEluZGV4ID0gXy5maW5kSW5kZXgob2xkTUNoaWxkcmVuICwgZnVuY3Rpb24gKG9sZE1DaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2Uob2xkTUNoaWxkLCAic2F2ZSIsIDApID09IDE7CiAgICAgICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICAgICAgb2xkQ2hpbGQgPSBvbGRNQ2hpbGRyZW4uc3BsaWNlKGNoaWxkSW5kZXgsIDEpOwogICAgICAgICAgICAgICAgICAgIGNoaWxkSW5kZXggPSBfLmZpbmRJbmRleChuZXdKQ2hpbGRyZW4gLCBmdW5jdGlvbiAobmV3SkNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZShuZXdKQ2hpbGQsICJzYXZlIiwgMCkgPT0gMTsKICAgICAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICBuZXdDaGlsZCA9IG5ld0pDaGlsZHJlbi5zcGxpY2UoY2hpbGRJbmRleCwgMSk7CiAgICAgICAgICAgICAgICAgICAgb2xkQ2hpbGRbMF0ucGxheUpzb24obmV3Q2hpbGRbMF0pOyAgLy8gcGxheUpzb24gZm9yIGl0ZW0gaGF2aW5nIHNhdmUgcHJvcGVydHkKCiAgICAgICAgICAgICAgICAgICAgb2xkQ2hpbGQgPSBvbGRNQ2hpbGRyZW4uc2hpZnQoKTsKICAgICAgICAgICAgICAgICAgICBuZXdDaGlsZCA9IG5ld0pDaGlsZHJlbi5zaGlmdCgpOwogICAgICAgICAgICAgICAgICAgIGlmIChvbGRDaGlsZCAmJiBuZXdDaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICBvbGRDaGlsZC5wbGF5SnNvbihuZXdDaGlsZCk7ICAvL3BsYXlKc29uIGZvciBpdGVtIHdpdGhvdXQgc2F2ZSBwcm9wZXJ0eQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBzd2l0Y2ggKHJlbGF0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnplcm9Pck9uZSA6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdKQ2hpbGRyZW4ubGVuZ3RoID4gMCAmJiBvbGRNQ2hpbGRyZW4ubGVuZ3RoID09IDApIHsgLy9BZGRpdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld01DaGlsZCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlTW9kZWwobmV3SkNoaWxkcmVuWzBdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkZENoaWxkKG5ld01DaGlsZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobmV3SkNoaWxkcmVuLmxlbmd0aCA9PSAwICYmIG9sZE1DaGlsZHJlbi5sZW5ndGggPiAwKSB7IC8vcmVtb3ZhbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVtb3ZlQ2hpbGQob2xkTUNoaWxkcmVuWzBdKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChuZXdKQ2hpbGRyZW4ubGVuZ3RoID4gMCAmJiBvbGRNQ2hpbGRyZW4ubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkTUNoaWxkcmVuWzBdLnBsYXlKc29uKG5ld0pDaGlsZHJlblswXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5vbmVPZkNoaWxkIDoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFvbmVPZkNoaWxkUHJvY2Vzc2VkICYmIG5ld0pDaGlsZHJlbi5sZW5ndGggPiAwICYmIG9sZE1DaGlsZHJlbi5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3IgdGhlIHRpbWUgYmVpbmcgbGV0J3MgYXNzdW1lIG9uZU9mQ2hpbGQgdHlwZSBjYW4gbm90IGJlIG1vZGlmaWVkIGFuZCBjYW4gbm90IGJlIGFkZGVkL3JlbW92ZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZE1DaGlsZHJlblswXS5wbGF5SnNvbihuZXdKQ2hpbGRyZW5bMF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb25lT2ZDaGlsZFByb2Nlc3NlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgOgogICAgICAgICAgICAgICAgICAgICAgICBfLmVhY2gob2xkTUNoaWxkcmVuLCBmdW5jdGlvbiAob2xkTUNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3SkNoaWxkID0gbmV3SkNoaWxkcmVuLnNoaWZ0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3SkNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkTUNoaWxkLnBsYXlKc29uKG5ld0pDaGlsZCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVDaGlsZChvbGRNQ2hpbGQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0pDaGlsZHJlbi5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLmVhY2gobmV3SkNoaWxkcmVuLCBmdW5jdGlvbiAobmV3SkNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld01DaGlsZCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlTW9kZWwobmV3SkNoaWxkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9hZGRDaGlsZChuZXdNQ2hpbGQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIHBsYXlKc29uRm9yRWxlbWVudDogZnVuY3Rpb24gKGVsTmFtZSwgcEpzb25Nb2RlbCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgIGlmIChkaWZmX2xldmVsPT09MCAmJiB0aGlzLl9uZXdDaGlsZCA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICJjaGFuZ2VkIjogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAianNvbkRpZmZlcmVuY2UiOiB0aGlzLmpzb25Nb2RlbAogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgZGlmZiA9IEVsZW1lbnQuX3N1cGVyLl9jb21wdXRlSnNvbkRpZmYuY2FsbCh0aGlzLCBkaWZmX2xldmVsKTsKICAgICAgICAgICAgdmFyIGF0dHJDaGFuZ2VGb3VuZCA9IGRpZmYuY2hhbmdlZDsKICAgICAgICAgICAgdmFyIGRlc3QgPSBkaWZmLmpzb25EaWZmZXJlbmNlOwogICAgICAgICAgICB2YXIgaW5pdGlhbEpzb24gPSB0aGlzLl94ZmEoKS5feGZhVGVtcGxhdGVDYWNoZS5nZXRJbml0aWFsRm9ybURvbVJlZih0aGlzLmh0bWxJZCk7CiAgICAgICAgICAgIGlmICghaW5pdGlhbEpzb24pIHsKICAgICAgICAgICAgICAgIGluaXRpYWxKc29uID0gdGhpcy5feGZhKCkuX3hmYVRlbXBsYXRlQ2FjaGUuZ2V0SW5pdGlhbEZvcm1Eb21SZWYodGhpcy5fdGVtcGxhdGVJZCgpKSB8fCB7fTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgY2hpbGRDaGFuZ2VGb3VuZCA9IGZhbHNlOwogICAgICAgICAgICB2YXIgaW5pdGlhbEpzb25DaGlsZHJlbiA9IHRoaXMuZ2V0T3JFbHNlKGluaXRpYWxKc29uLCAiY2hpbGRyZW4iLCBbXSk7CiAgICAgICAgICAgIGlmICh0aGlzLmdldE9yRWxzZSh0aGlzLm1vQ2hpbGROb2RlcywgImxlbmd0aCIsIDApICE9IHRoaXMuZ2V0T3JFbHNlKGluaXRpYWxKc29uQ2hpbGRyZW4sICJsZW5ndGgiLCAwKSkgewogICAgICAgICAgICAgICAgY2hpbGRDaGFuZ2VGb3VuZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBjaGlsZENoYW5nZUZvdW5kID0gKG51bGwgIT0gXy5maW5kKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbiAobUNoaWxkLCBpbmRleCkgewogICAgICAgICAgICAgICAgICAgIGlmICgobUNoaWxkLmNsYXNzTmFtZSAhPSBpbml0aWFsSnNvbkNoaWxkcmVuW2luZGV4XS5fY2xhc3MpIHx8IChtQ2hpbGQuanNvbk1vZGVsLm5hbWUgIT09IGluaXRpYWxKc29uQ2hpbGRyZW5baW5kZXhdLm5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9LCB0aGlzKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBkZXN0Q2hpbGRyZW4gPSBbXTsKICAgICAgICAgICAgXy5lYWNoKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbiAobUNoaWxkLCBpbmRleCkgewogICAgICAgICAgICAgICAgdmFyIGNoaWxkRGlmZiA9IG1DaGlsZC5fY29tcHV0ZUpzb25EaWZmKGRpZmZfbGV2ZWwpIHx8IHt9OwogICAgICAgICAgICAgICAgaWYgKCEoZGlmZl9sZXZlbD4wICYmIF8uaXNFbXB0eShjaGlsZERpZmYuanNvbkRpZmZlcmVuY2UpKSkgeyAgLy8gc2tpcCBpZiBkdXJpbmcgc3VibWlzc2lvbiAmIHJlc3RvcmVGb3JtU3RhdGUgdGhlIGNoaWxkRGlmZiBpcyBlbXB0eQogICAgICAgICAgICAgICAgICAgIGRlc3RDaGlsZHJlbi5wdXNoKGNoaWxkRGlmZi5qc29uRGlmZmVyZW5jZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZENoYW5nZUZvdW5kICYmIGNoaWxkRGlmZi5jaGFuZ2VkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkQ2hhbmdlRm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICBpZiAoZGlmZl9sZXZlbD4wICYmIGRlc3RDaGlsZHJlbi5sZW5ndGggPT0gMCkgeyAvLyBza2lwIGlmIGR1cmluZyBzdWJtaXNzaW9uICAmIHJlc3RvcmVGb3JtU3RhdGUgbm8gY2hpbGRyZW4gcHJlc2VudAogICAgICAgICAgICAgICAgaWYgKHRoaXMuanNvbk1vZGVsLl9jbGFzcyAhPT0gJ2Zvcm0nKSB7IC8vIGV4Y2VwdCBmb3Igcm9vdCBzdWJmb3JtIExDLTkzMTcKICAgICAgICAgICAgICAgICAgICBkZXN0ID0gdW5kZWZpbmVkOyAvLyBtdXN0IGJlIGNhcmVmdWwgd2hpbGUgYXNzaWduaW5nIHRvIGpzb25EaWZmZXJlbmNlLCBpZGVhbGx5IHNob3VsZCBsZXQgaXQgYmUge30sIGJ1dCB0aGlzIGNvc3RzIGJ5dGVzIGluIGZpbmFsIGpzb24KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGRlc3QuY2hpbGRyZW4gPSBkZXN0Q2hpbGRyZW47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB7ImNoYW5nZWQiOiBjaGlsZENoYW5nZUZvdW5kIHx8IGF0dHJDaGFuZ2VGb3VuZCwKICAgICAgICAgICAgICAgIGpzb25EaWZmZXJlbmNlOiBkZXN0CiAgICAgICAgICAgIH07CiAgICAgICAgfSwKCiAgICAgICAgX2dldE9uZU9mQ2hpbGQ6IGZ1bmN0aW9uIChiUGVlaykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgYlBlZWsgPSB0eXBlb2YgYlBlZWsgPT09ICJ1bmRlZmluZWQiID8gZmFsc2UgOiB0cnVlOwogICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9vbmVPZkNoaWxkICYmIGJQZWVrID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuX3hmYSgpLl90ZW1wbGF0ZVNjaGVtYS5fZ2V0T25lT2ZDaGlsZCh0aGlzLmNsYXNzTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb25lT2ZDaGlsZCA9IF8uZmluZCh0aGlzLm1vQ2hpbGROb2RlcywgZnVuY3Rpb24gKGNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZC5jbGFzc05hbWUgaW4gY2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX29uZU9mQ2hpbGQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX29uZU9mQ2hpbGQgPSB0aGlzLl9vbmVPZkNoaWxkLl9nZXROYWtlZFRoaXMoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbmVPZkNoaWxkOwogICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLkxvZ2dlci5lcnJvcigieGZhIiwgeGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDE3Il0sIFtleGNlcHRpb24sICJvbmVPZkNoaWxkIiwgY29udGV4dE9iai5zb21FeHByZXNzaW9uXSkKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiB0aGUgYmluZCBjaGlsZCBvZiB0aGUgY3VycmVudCBlbGVtZW50LiBnZXRFbGVtZW50IEFQSSBkb2Vzbid0IHJldHVybiB0aGUgY29ycmVjdCB2YWx1ZSBpbiBjYXNlIG9mCiAgICAgICAgICogdW5uYW1lZCBlbGVtZW50IGluc2lkZSB0aGUgY3VycmVudCBlbGVtZW50CiAgICAgICAgICogQHJldHVybnMgeyp9CiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfZ2V0QmluZGluZzogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gXy5maW5kKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbihjaGlsZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkLmNsYXNzTmFtZSA9PT0gImJpbmQiCiAgICAgICAgICAgIH0pCiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2tzIHdoZXRoZXIgYmluZGluZyBpcyBub25lIG9yIG5vdC4gUmV0dXJucyBmYWxzZSBpZiBiaW5kaW5nIGlzIHNldCB0byBub25lLCBvdGhlcndpc2UgZmFsc2UuCiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59CiAgICAgICAgICovCiAgICAgICAgaGFzRGF0YUJpbmRpbmc6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGJpbmQgPSB0aGlzLl9nZXRCaW5kaW5nKCk7CiAgICAgICAgICAgIC8vYmluZCA9IG51bGwgbWVhbnMgdXNlIG5hbWUgYmluZGluZwogICAgICAgICAgICByZXR1cm4gYmluZCA9PSBudWxsIHx8IGJpbmQubWF0Y2ggIT09ICJub25lIjsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiByZXR1cm5zIGRhdGFTb20gZm9yIHRoZSBjdXJyZW50IGZpZWxkCiAgICAgICAgICogQHJldHVybnMgeyp9CiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfZ2V0RGF0YVNvbTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcywgImV4dHJhcy5GU19FWFRSQVMuRlNfREFUQV9TT00udmFsdWUiLCBudWxsKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGJpbmRSZWYgZm9yIHRoZSBlbGVtZW50IHBvaW50cyB0byBhbiBhdHRyaWJ1dGUgb3RoZXJ3aXNlIGZhbHNlLgogICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufQogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2lzQmluZFJlZkF0dHJpYnV0ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gMSA9PSB0aGlzLmdldE9yRWxzZSh0aGlzLCAiZXh0cmFzLkZTX0VYVFJBUy5JU19BVFRSSUJVVEUudmFsdWUiLCAwKTsKICAgICAgICB9LAoKICAgICAgICBfY29udmVydFJlZlRvWFBhdGg6IGZ1bmN0aW9uIChiaW5kUmVmKSB7CiAgICAgICAgICAgIHZhciAkcmVnZXggPSAvXlwkXC4vLAogICAgICAgICAgICAgICAgJHJlY29yZFJlZ2V4ID0gL15cJHJlY29yZFwuLywKICAgICAgICAgICAgICAgIHJlbGF0aXZlLAogICAgICAgICAgICAgICAgX2JpbmRSZWYsCiAgICAgICAgICAgICAgICBzb21BcnJheTsKICAgICAgICAgICAgaWYoYmluZFJlZi5tYXRjaCgkcmVjb3JkUmVnZXgpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHJlbGF0aXZlID0gZmFsc2U7CiAgICAgICAgICAgICAgICBfYmluZFJlZiA9IGJpbmRSZWYucmVwbGFjZSgkcmVjb3JkUmVnZXgsICIiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJlbGF0aXZlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIF9iaW5kUmVmID0gYmluZFJlZi5yZXBsYWNlKCRyZWdleCwgIiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNvbUFycmF5ID0geGZhbGliLnNjcmlwdC5TT01FeHByZXNzaW9uLnByb3RvdHlwZS5zcGxpdEV4cHJlc3Npb24oX2JpbmRSZWYpOwogICAgICAgICAgICBfYmluZFJlZiA9IF8ucmVkdWNlKHNvbUFycmF5LCBmdW5jdGlvbiAobWVtbywgc29tLCBpbmR4KSB7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudFNvbSA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlU29tRXhwcmVzc2lvbihzb20sIDApLAogICAgICAgICAgICAgICAgICAgIGluZGV4ID0gY3VycmVudFNvbS5pbmRleDsKICAgICAgICAgICAgICAgIC8vIGluZGV4IGluIFNPTSBFeHByZXNzaW9uIHN0YXJ0cyBmcm9tIDAgd2hlcmVhcyBpbiB4cGF0aCBpdCBzdGFydHMgZnJvbSAxCiAgICAgICAgICAgICAgICBpZihfLmlzTnVtYmVyKGluZGV4KSkgewogICAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihpbmR4ID09PSBzb21BcnJheS5sZW5ndGggLSAxICYmIHRoaXMuX2lzQmluZFJlZkF0dHJpYnV0ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gb25seSBsYXN0IHBhcnQgaW4gdGhlIGJpbmRSZWYgY2FuIGJlIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgIHJldHVybiBtZW1vICsgIkAiICsgY3VycmVudFNvbS5uYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIG1lbW8gKyBjdXJyZW50U29tLm5hbWUgKyAiWyIgKyBpbmRleCArICJdLyIKICAgICAgICAgICAgfSwgIiIsIHRoaXMpOwogICAgICAgICAgICAvL3JlcGxhY2UgdGhlIGxhc3QgLyBpZiBleGlzdHMgd2l0aCBlbXB0eSBzdHJpbmcKICAgICAgICAgICAgX2JpbmRSZWYgPSBfYmluZFJlZi5yZXBsYWNlKC9cLyQvLCIiKTsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgIHJlbGF0aXZlOiByZWxhdGl2ZSwKICAgICAgICAgICAgICAgIGJpbmRSZWY6IF9iaW5kUmVmCiAgICAgICAgICAgIH07CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyB0aGUgeHBhdGggZnJvbSB0aGUgYmluZC5kYXRhcmVmIHByb3BlcnR5LiByZW1vdmVzIHRoZSBsZWFkaW5nICQuIGZyb20gdGhlIGRhdGFSZWYuCiAgICAgICAgICogVE9ETzogaW4gc29tZSBwbGFjZXMgdGhlIGRhdGFSZWYgcHJvcGVydHkgaGFzICRyZWNvcmQuIE5lZWQgdG8gZGlzY3VzcyB0aGF0IGNhc2UKICAgICAgICAgKiBNb3Jlb3ZlciB0aGlzIG1pZ2h0IG5vdCBiZSBuZWVkZWQgaWYgWFRHIHByb3ZpZGVzIERBVEFTT00gZm9yIHRoZSBzdWJmb3Jtcy4KICAgICAgICAgKiBAcmV0dXJucyB7Kn0KICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9nZXRYcGF0aEZyb21CaW5kUmVmOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBiaW5kID0gdGhpcy5fZ2V0QmluZGluZygpLAogICAgICAgICAgICAgICAgYmluZFJlZiA9IHRoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIiksCiAgICAgICAgICAgICAgICAkcmVnZXggPSAvXlwkXC4vLAogICAgICAgICAgICAgICAgJHJlY29yZFJlZ2V4ID0gL15cJHJlY29yZFwuLywKICAgICAgICAgICAgICAgIHJlbGF0aXZlID0gdHJ1ZSwKICAgICAgICAgICAgICAgIHNvbUFycmF5OwogICAgICAgICAgICBpZihiaW5kICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGlmKGJpbmQubWF0Y2ggPT09ICJkYXRhUmVmIikgewogICAgICAgICAgICAgICAgICAgIGlmKGJpbmQucmVmLm1hdGNoKCRyZWNvcmRSZWdleCkgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBiaW5kUmVmID0gYmluZC5yZWYucmVwbGFjZSgkcmVjb3JkUmVnZXgsICIiKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRSZWYgPSBiaW5kLnJlZi5yZXBsYWNlKCRyZWdleCwgIiIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzb21BcnJheSA9IHhmYWxpYi5zY3JpcHQuU09NRXhwcmVzc2lvbi5wcm90b3R5cGUuc3BsaXRFeHByZXNzaW9uKGJpbmRSZWYpOwogICAgICAgICAgICAgICAgICAgIGJpbmRSZWYgPSBfLnJlZHVjZShzb21BcnJheSwgZnVuY3Rpb24gKG1lbW8sIHNvbSwgaW5keCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VycmVudFNvbSA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlU29tRXhwcmVzc2lvbihzb20sIDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBjdXJyZW50U29tLmluZGV4OwogICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmRleCBpbiBTT00gRXhwcmVzc2lvbiBzdGFydHMgZnJvbSAwIHdoZXJlYXMgaW4geHBhdGggaXQgc3RhcnRzIGZyb20gMQogICAgICAgICAgICAgICAgICAgICAgICBpZihfLmlzTnVtYmVyKGluZGV4KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDE7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYoaW5keCA9PT0gc29tQXJyYXkubGVuZ3RoIC0gMSAmJiB0aGlzLl9pc0JpbmRSZWZBdHRyaWJ1dGUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb25seSBsYXN0IHBhcnQgaW4gdGhlIGJpbmRSZWYgY2FuIGJlIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1lbW8gKyAiQCIgKyBjdXJyZW50U29tLm5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1lbW8gKyBjdXJyZW50U29tLm5hbWUgKyAiWyIgKyBpbmRleCArICJdLyIKICAgICAgICAgICAgICAgICAgICB9LCAiIiwgdGhpcyk7CiAgICAgICAgICAgICAgICAgICAgLy9yZXBsYWNlIHRoZSBsYXN0IC8gaWYgZXhpc3RzIHdpdGggZW1wdHkgc3RyaW5nCiAgICAgICAgICAgICAgICAgICAgYmluZFJlZiA9IGJpbmRSZWYucmVwbGFjZSgvXC8kLywiIik7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmU6IHJlbGF0aXZlLAogICAgICAgICAgICAgICAgICAgICAgICBiaW5kUmVmOiBiaW5kUmVmCiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYmluZC5tYXRjaCA9PT0gImdsb2JhbCIgJiYgWyJmaWVsZCIsICJleGNsR3JvdXAiXS5pbmRleE9mKHRoaXMuY2xhc3NOYW1lKSAhPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZTogImdsb2JhbCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRSZWY6IHRoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIikgKyAiWzFdIgogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYoYmluZC5tYXRjaCA9PT0gIm9uY2UiKSB7IC8vIGZvciBmaWVsZHMgd2l0aCBwYXR0ZXJucwogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRYUGF0aEZvclVzZU5hbWVCaW5kaW5nKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBiaW5kLm1hdGNoID09PSBudWxsCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL3VzZSBuYW1lIGJpbmRpbmcKICAgICAgICAgICAgLyoqIGZvciB1bm5hbWVkIGVsZW1lbnRzLCB3aXRoIGRhdGEgYmluZGluZyBhcyB1c2UgbmFtZSwgd2UgYXJlIHJldHVybmluZyBudWxsICovCiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRYUGF0aEZvclVzZU5hbWVCaW5kaW5nKCk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldFhQYXRoRm9yVXNlTmFtZUJpbmRpbmc6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIG5hbWUgPSB0aGlzLmdldEF0dHJpYnV0ZSgibmFtZSIpLAogICAgICAgICAgICAgICAgLy9TT00gSW5kZXggc3RhcnRzIGZyb20gMCB3aGlsZSBpbiBYUGF0aCBpdCBzdGFydHMgZnJvbSAxCiAgICAgICAgICAgICAgICBpbmRleCA9IHRoaXMuaW5kZXggKyAxOwogICAgICAgICAgICByZXR1cm4gbmFtZSA9PT0gIiIgPyBudWxsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmU6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRSZWY6IG5hbWUgKyAiWyIgKyBpbmRleCArICJdIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeSBjaGlsZCBhbmQgYWRkIGVudHJ5IGZvciB0aGVtIGludG8gdGhlIGRhdGFTT01NYXAuIFNlZSBAIE5vZGUuX2dldERhdGFTb21NYXAgZm9yIG1vcmUgZGV0YWlscwogICAgICAgICAqIEBwYXJhbSBtYXAKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqIGlmIG1hcCBpcyBub3QgYW4gb2JqZWN0IGl0IGJlaGF2ZXMgYXMgYW4gaWRlbnRpdHkgZnVuY3Rpb24KICAgICAgICAgKi8KICAgICAgICBfZ2V0RGF0YVNvbU1hcDogZnVuY3Rpb24obWFwKSB7CiAgICAgICAgICAgIGlmKCFfLmlzT2JqZWN0KG1hcCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBtYXA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgXy5lYWNoKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgIG1hcCA9IGNoaWxkLl9nZXREYXRhU29tTWFwKG1hcCk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICByZXR1cm4gbWFwOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeSBjaGlsZCBhbmQgdXBkYXRlIHRoZWlyIHZhbHVlcyBiYXNlZCBvbiB0aGUgZW50cmllcyBpbiB0aGUgbWFwLiBTZWUgQCBOb2RlLl9nZXREYXRhU29tTWFwCiAgICAgICAgICogZm9yIG1vcmUgZGV0YWlscwogICAgICAgICAqIEBwYXJhbSBtYXAKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9yZXN0b3JlRGF0YVNvbU1hcDogZnVuY3Rpb24gKG1hcCkgewogICAgICAgICAgICBpZighXy5pc09iamVjdChtYXApKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgXy5lYWNoKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgIGNoaWxkLl9yZXN0b3JlRGF0YVNvbU1hcChtYXApOwogICAgICAgICAgICB9KQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEV2YWx1YXRlcyB0aGUgZ2l2ZW4geHBhdGggcmVsYXRpdmUgdG8gY29udGV4dE5vZGUgb3IgUm9vdE5vZGUgZGVwZW5kaW5nIHVwb24gdGhlIHZhbHVlIG9mIHhwYXRoLnJlbGF0aXZlCiAgICAgICAgICogSW4gY2FzZSBpdCBpcyB0cnVlLCB4cGF0aCBpcyBldmFsdWF0ZXMgcmVsYXRpdmUgdG8gY29udGV4dE5vZGUgb3RoZXJ3aXNlIHJvb3ROb2RlCiAgICAgICAgICogQHBhcmFtIHhwYXRoCiAgICAgICAgICogQHBhcmFtIGNvbnRleHROb2RlCiAgICAgICAgICogQHBhcmFtIHJvb3ROb2RlCiAgICAgICAgICogQHJldHVybnMgeyp9CiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfZ2V0RWxlbWVudHNGcm9tWHBhdGg6IGZ1bmN0aW9uKHhwYXRoLCBjb250ZXh0Tm9kZSwgcm9vdE5vZGUpIHsKICAgICAgICAgICAgdmFyIG5vZGVJdGVyLAogICAgICAgICAgICAgICAgWE1MVXRpbHMgPSB4ZmFsaWIudXQuWE1MVXRpbHMsCiAgICAgICAgICAgICAgICBkb2MgPSByb290Tm9kZSBpbnN0YW5jZW9mIERvY3VtZW50ID8gcm9vdE5vZGUgOiByb290Tm9kZS5vd25lckRvY3VtZW50OwogICAgICAgICAgICBpZih4cGF0aC5yZWxhdGl2ZSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIG5vZGVJdGVyID0gWE1MVXRpbHMuZXZhbHVhdGVYUGF0aCh4cGF0aC5iaW5kUmVmLCByb290Tm9kZSwgbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBhdGhSZXN1bHQuT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUsIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYoY29udGV4dE5vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgbm9kZUl0ZXIgPSBYTUxVdGlscy5ldmFsdWF0ZVhQYXRoKHhwYXRoLmJpbmRSZWYsIGNvbnRleHROb2RlLCBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYUGF0aFJlc3VsdC5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSwgbnVsbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5vZGVJdGVyOwogICAgICAgIH0sCgogICAgICAgIF9wbGF5RGF0YVhNTCA6IGZ1bmN0aW9uICh4bWxEb2N1bWVudCwgY29udGV4dE5vZGUsIGN1cnJlbnRCaW5kUmVmKSB7CiAgICAgICAgICAgIF8uZWFjaCh0aGlzLmNoaWxkcmVuLCBmdW5jdGlvbihjaGlsZCkgewogICAgICAgICAgICAgICBjaGlsZC5fcGxheURhdGFYTUwoeG1sRG9jdW1lbnQsIGNvbnRleHROb2RlLCBjdXJyZW50QmluZFJlZik7CiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEdlbmVyYXRlcyB0aGUgWE1MIGJ5IGFwcGVuZGluZyB0aGUgZWxlbWVudHMgaW4gdGhlIHJvb3ROb2RlCiAgICAgICAgICogQHBhcmFtIHJvb3ROb2RlIFRoZSByb290Tm9kZSBvZiB0aGUgeG1sLiBHZW5lcmFsbHkgdGhlIGVsZW1lbnQgdGhhdCBtYXBzIHRvIHRoZSByb290IG9mIHRoZSBmb3JtCiAgICAgICAgICogQHBhcmFtIGNvbnRleHROb2RlIEN1cnJlbnQgTm9kZSB3aGVyZSB0byBpbnNlcnQgdGhlIGVsZW1lbnRzIGluIGNhc2Ugb2YgcmVsYXRpdmUgYmluZGluZ3MKICAgICAgICAgKi8KICAgICAgICBnZW5lcmF0ZURhdGFYTUw6IGZ1bmN0aW9uIChyb290Tm9kZSwgY29udGV4dE5vZGUpIHsKICAgICAgICAgICAgXy5lYWNoKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbihjaGlsZCkgewogICAgICAgICAgICAgICAgY2hpbGQuZ2VuZXJhdGVEYXRhWE1MKHJvb3ROb2RlLCBjb250ZXh0Tm9kZSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgYmluZFJlZiByZWxhdGl2ZSB0byBwYXJlbnRCaW5kUmVmLiBJZiBiaW5kUmVmIGlzIG5vdCBhIGNoaWxkIG9mIHBhcmVudEJpbmRSZWYsIHJldHVybnMgbnVsbAogICAgICAgICAqIG90aGVyd2lzZSByZW1vdmVzIHRoZSBwYXJlbnRCaW5kUmVmIHN0cmluZyBmcm9tIHRoZSBiaW5kUmVmCiAgICAgICAgICogQHBhcmFtIHBhcmVudEJpbmRSZWYKICAgICAgICAgKiBAcGFyYW0gYmluZFJlZgogICAgICAgICAqIEByZXR1cm5zIHsqfQogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2dldFJlbGF0aXZlWFBhdGg6IGZ1bmN0aW9uKHBhcmVudEJpbmRSZWYsIGJpbmRSZWYpIHsKICAgICAgICAgICB2YXIgcmVnZXhwID0gbmV3IFJlZ0V4cCgiXiIgKyBwYXJlbnRCaW5kUmVmKyIvIik7CiAgICAgICAgICAgaWYoYmluZFJlZi5tYXRjaChyZWdleHApKSB7CiAgICAgICAgICAgICAgcmV0dXJuIGJpbmRSZWYucmVwbGFjZShyZWdleHAsIiIpOwogICAgICAgICAgIH0KICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICB9KTsKCiAgICBFbGVtZW50LmRlZmluZVByb3BzKHsKICAgICAgICAiY2hpbGRyZW4iOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIG5vZGVzID0gW107CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubW9DaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5tb0NoaWxkTm9kZXNbaV07CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzLnB1c2goY2hpbGQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIG5vZGVzOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChtb0NoaWxkcmVuKSB7CiAgICAgICAgICAgICAgICBtb0NoaWxkcmVuID0gdGhpcy52YWxpZGF0ZUlucHV0KG1vQ2hpbGRyZW4sICJvYmplY3QiLCBudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMubW9DaGlsZE5vZGVzID0gbmV3IEFycmF5KG1vQ2hpbGRyZW4ubGVuZ3RoKTsKICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuID0gW107CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1vQ2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLm1vQ2hpbGROb2Rlc1tpXSA9IG1vQ2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb0NoaWxkTm9kZXNbaV0ucGFyZW50ID0gdGhpczsKICAgICAgICAgICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC5jaGlsZHJlbltpXSA9IG1vQ2hpbGRyZW5baV0uanNvbk1vZGVsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5ub3JtYWxpemVDaGlsZHJlbigpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgIm9uZU9mQ2hpbGQiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldE9uZU9mQ2hpbGQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIG1vQ2hpbGROb2RlczogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb0NoaWxkTm9kZXM7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tb0NoaWxkTm9kZXMgPSB2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoiYm9yZGVyV2lkdGgiIDogewogICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgdGhpcy5fYm9yZGVyV2lkdGggPSB0aGlzLl9ib3JkZXJXaWR0aCB8fCAiMC42NjI0IHB4IiA7CiAgICAgICAgIHJldHVybiAodGhpcy5fYm9yZGVyV2lkdGgpOwogICAgICAgICB9LAoKICAgICAgICAgc2V0IDogZnVuY3Rpb24od2lkdGgpIHsKICAgICAgICAgLy9UT0RPOiBTZXQgYm9yZGVyLmVkZ2UucHJlc2VuY2UgcHJvcGVydHkgdG8gdmlzaWJsZSBvbmNlIEJvcmRlciBpcyBpbXBsZW1lbnRlZAogICAgICAgICB0aGlzLl9ib3JkZXJXaWR0aCA9IHdpZHRoIDsKICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwKICAgICAgICAgdGhpcywiYm9yZGVyV2lkdGgiLG51bGwsd2lkdGgpOwogICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICB9CiAgICAgICAgIH0sICAgICAgKi8KCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CgoKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBHZW5lcmljVGV4dCA9IHhmYWxpYi5zY3JpcHQuR2VuZXJpY1RleHQgPSB4ZmFsaWIuc2NyaXB0Lk5vZGUuZXh0ZW5kKHsKICAgICAgICBfZGVmYXVsdDogInZhbHVlIiwKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIEdlbmVyaWNUZXh0Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX21vZGVsQ2hhbmdlZCA9IGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIHNldEF0dHJpYnV0ZTogZnVuY3Rpb24gKHZhbHVlLCBhdHRyTmFtZSkgewogICAgICAgICAgICBHZW5lcmljVGV4dC5fc3VwZXIuc2V0QXR0cmlidXRlLmNhbGwodGhpcywgdmFsdWUsIGF0dHJOYW1lKTsKICAgICAgICAgICAgdGhpcy5fbW9kZWxDaGFuZ2VkID0gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUpzb25EaWZmOiBmdW5jdGlvbiAoZGlmZl9sZXZlbCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTaW5jZSB3ZSBkbyBub3QgbWFpbnRhaW4gaW5pdGlhbEpzb24gb3IgdGVtcGxhdGVKc29uIGZvciBET00gZWxlbWVudHMsIHdlIHVzZSB0aGlzIGFwcHJveGltYXRlIG1ldGhvZCB0byBjb21wdXRlIGpzb25EaWZmLgogICAgICAgICAgICAgKiBUaGlzIGFzc3VtZXMgdGhhdCBhbGwgYXR0ciBjaGFuZ2VzIHdvdWxkIGhhcHBlbiB0aHJvdWdoIHNldEF0dHJpYnV0ZSBBUEkuCiAgICAgICAgICAgICAqIHNlZUFsc286IERPTUVsZW1lbnQgYW5kIE5vZGVWYWx1ZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgLy8gbXVzdCBwYXNzICd0aGlzJyBub2RlIGFzIGFyZ3VtZW50IGFycmF5IHRvIGNvbXB1dGVEb21Kc29uRGlmZgogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLnN0cmlwT3JDYWxsLmNhbGwodGhpcywgZGlmZl9sZXZlbD4wLCB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuY29tcHV0ZURvbUpzb25EaWZmLCBbdGhpc10pOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBHZW5lcmljVGV4dC5kZWZpbmVQcm9wcyh7CiAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmpzb25Nb2RlbC5fdmFsdWU7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT09IHRoaXMuanNvbk1vZGVsLl92YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX21vZGVsQ2hhbmdlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgdmFyIG9sZFZhbCA9IHRoaXMuanNvbk1vZGVsLl92YWx1ZQogICAgICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLl92YWx1ZSA9IHRoaXMudmFsaWRhdGVJbnB1dCh2YWx1ZSwgInN0cmluZyIsIHRoaXMuanNvbk1vZGVsLl92YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGV2ZW50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwgdGhpcywgdGhpcy5jbGFzc05hbWUsIG9sZFZhbCwgdGhpcy5qc29uTW9kZWwuX3ZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZlbnQubmFtZSwgZXZlbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwoKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBET01FbGVtZW50ID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50ID0geGZhbGliLnNjcmlwdC5FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgX2RlZmF1bHQ6ICJ2YWx1ZSIsCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBET01FbGVtZW50Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX25vcm1hbGl6ZVBlbmRpbmcgPSB0cnVlOwogICAgICAgICAgICB0aGlzLl9jaGlsZHJlbkluaXRpYWxpemVQZW5kaW5nID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5fY2hpbGRNb2RpZmllZCA9IGZhbHNlOwogICAgICAgICAgICB0aGlzLl9tb2RlbENoYW5nZWQgPSBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBoYW5kbGVFdmVudDogZnVuY3Rpb24gKGV2bnQpIHsKICAgICAgICAgICAgaWYgKGV2bnQubmFtZSA9PSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQpIHsKICAgICAgICAgICAgICAgIGV2bnQuX3Byb3BlcnR5ID0gdGhpcy5jbGFzc05hbWUgKyAiLiIgKyBldm50Ll9wcm9wZXJ0eTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsIGV2bnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRDaGlsZHJlbjogZnVuY3Rpb24gKCkgewogICAgICAgIH0sCgogICAgICAgIF9pbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vZG8gbm90aGluZwogICAgICAgIH0sCgogICAgICAgIF9pbml0Q2hpbGRyZW5JbnRlcm5hbDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgY2hpbGRyZW4gPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgdmFyIHRlbXBOYW1lQ29udGFpbmVyID0ge307CiAgICAgICAgICAgIGlmICh0aGlzLmpzb25Nb2RlbC5jaGlsZHJlbikgewogICAgICAgICAgICAgICAgdmFyIGogPSAwOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmpzb25Nb2RlbC5jaGlsZHJlbi5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuW2ldOwogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZE1vZGVsID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVNb2RlbChjaGlsZCk7CiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5baisrXSA9IGNoaWxkTW9kZWw7CiAgICAgICAgICAgICAgICAgICAgY2hpbGRNb2RlbC5wYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgIGNoaWxkTW9kZWwub24oeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkRPTV9DSEFOR0VELCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICBjaGlsZE1vZGVsLl9pbml0aWFsaXplKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkTW9kZWwubmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZUluZGV4ID0gdGVtcE5hbWVDb250YWluZXJbY2hpbGRNb2RlbC5uYW1lXSB8fCAwOwogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZE1vZGVsLmluZGV4ID0gbmFtZUluZGV4OwogICAgICAgICAgICAgICAgICAgICAgICBuYW1lSW5kZXgrKzsKICAgICAgICAgICAgICAgICAgICAgICAgdGVtcE5hbWVDb250YWluZXJbY2hpbGRNb2RlbC5uYW1lXSA9IG5hbWVJbmRleDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkTW9kZWwuY2xhc3NOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc0luZGV4ID0gdGVtcE5hbWVDb250YWluZXJbIiMiICsgY2hpbGRNb2RlbC5jbGFzc05hbWVdIHx8IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkTW9kZWwubW5DbGFzc0luZGV4ID0gY2xhc3NJbmRleDsKICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NJbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wTmFtZUNvbnRhaW5lclsiIyIgKyBjaGlsZE1vZGVsLmNsYXNzTmFtZV0gPSBjbGFzc0luZGV4OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX21vQ2hpbGROb2RlcyA9IGNoaWxkcmVuOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldE5ha2VkVGhpczogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBpZiAodGhpcy5fbm9ybWFsaXplUGVuZGluZykgewogICAgICAgICAgICAgICAgdGhpcy5ub3JtYWxpemVDaGlsZHJlbigpOwogICAgICAgICAgICAgICAgdGhpcy5fbm9ybWFsaXplUGVuZGluZyA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBET01FbGVtZW50Ll9zdXBlci5fZ2V0TmFrZWRUaGlzLmNhbGwodGhpcyk7CiAgICAgICAgfSwKCiAgICAgICAgc2V0QXR0cmlidXRlOiBmdW5jdGlvbiAodmFsdWUsIGF0dHJOYW1lKSB7CiAgICAgICAgICAgIERPTUVsZW1lbnQuX3N1cGVyLnNldEF0dHJpYnV0ZS5jYWxsKHRoaXMsIHZhbHVlLCBhdHRyTmFtZSk7CiAgICAgICAgICAgIHRoaXMuX21vZGVsQ2hhbmdlZCA9IHRydWU7CiAgICAgICAgfSwKCiAgICAgICAgX3Bvc3RBZGRDaGlsZDogZnVuY3Rpb24gKG9Ob2RlKSB7CiAgICAgICAgICAgIERPTUVsZW1lbnQuX3N1cGVyLl9wb3N0QWRkQ2hpbGQuY2FsbCh0aGlzLCBvTm9kZSk7Ci8vICAgICAgICAgICAgaWYob05vZGUgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQpCiAgICAgICAgICAgIC8vICAgICAgICBvTm9kZS5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQsdGhpcykgOwogICAgICAgICAgICB0aGlzLl9jaGlsZE1vZGlmaWVkID0gdHJ1ZTsKICAgICAgICAgICAgb05vZGUuX25ld0NoaWxkID0gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBfcG9zdFJlbW92ZUNoaWxkOiBmdW5jdGlvbiAob0NoaWxkKSB7CiAgICAgICAgICAgIERPTUVsZW1lbnQuX3N1cGVyLl9wb3N0UmVtb3ZlQ2hpbGQuY2FsbCh0aGlzLCBvQ2hpbGQpOwogICAgICAgICAgICB0aGlzLl9jaGlsZE1vZGlmaWVkID0gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBwbGF5SnNvbjogZnVuY3Rpb24gKHBKc29uTW9kZWwpIHsKICAgICAgICAgICAgaWYgKF8uY29udGFpbnMoWyJ2YWx1ZSIsICJpdGVtcyJdLCB0aGlzLmNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi5zY3JpcHQuRWxlbWVudC5wcm90b3R5cGUucGxheUpzb24uY2FsbCh0aGlzLCBwSnNvbk1vZGVsKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgIGlmIChkaWZmX2xldmVsICYmIGRpZmZfbGV2ZWwgIT0gMykgewogICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICAiY2hhbmdlZCI6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICJqc29uRGlmZmVyZW5jZSI6IHt9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9IGVsc2UgeyAvLyBub3QgY2FsbGVkIGR1cmluZyBzdWJtaXNzaW9uCiAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmV3Q2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAiY2hhbmdlZCI6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICdqc29uRGlmZmVyZW5jZSc6IHRoaXMuanNvbk1vZGVsCiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBTaW5jZSB3ZSBkbyBub3QgbWFpbnRhaW4gaW5pdGlhbEpzb24gb3IgdGVtcGxhdGVKc29uIGZvciBET00gZWxlbWVudHMsIHdlIHVzZSB0aGlzIGFwcHJveGltYXRlIG1ldGhvZCB0byBjb21wdXRlIGpzb25EaWZmLgogICAgICAgICAgICAgICAgICAgICAqIFRoaXMgYXNzdW1lcyB0aGF0IGFsbCBhdHRyIGNoYW5nZXMgd291bGQgaGFwcGVuIHRocm91Z2ggc2V0QXR0cmlidXRlIEFQSS4KICAgICAgICAgICAgICAgICAgICAgKiBzZWVBbHNvOiBHZW5lcmljVGV4dCBhbmQgTm9kZVZhbHVlCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGZEaWZmID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmNvbXB1dGVEb21Kc29uRGlmZi5jYWxsKHRoaXMsIHRoaXMsIGRpZmZfbGV2ZWwpLAogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbkRpZmYgPSBbXSwKICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlZCA9IHNlbGZEaWZmLmNoYW5nZWQgfHwgdGhpcy5fY2hpbGRNb2RpZmllZCwKICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRDaGFuZ2VkID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25EaWZmZXJlbmNlID0gc2VsZkRpZmYuanNvbkRpZmZlcmVuY2U7CgogICAgICAgICAgICAgICAgICAgIF8uZWFjaCh0aGlzLm1vQ2hpbGROb2RlcywgZnVuY3Rpb24gKG1DaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkRGlmZiA9IG1DaGlsZC5fY29tcHV0ZUpzb25EaWZmKGRpZmZfbGV2ZWwpIHx8IHt9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRDaGFuZ2VkID0gY2hpbGRDaGFuZ2VkIHx8IGNoaWxkRGlmZi5jaGFuZ2VkOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkRGlmZi5jaGFuZ2VkICYmICFfLmlzRW1wdHkoY2hpbGREaWZmLmpzb25EaWZmZXJlbmNlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuRGlmZi5wdXNoKGNoaWxkRGlmZi5qc29uRGlmZmVyZW5jZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMpOwogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jaGlsZE1vZGlmaWVkIHx8IGNoaWxkQ2hhbmdlZCkgewogICAgICAgICAgICAgICAgICAgICAgICBqc29uRGlmZmVyZW5jZS5jaGlsZHJlbiA9IGNoaWxkcmVuRGlmZjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJjaGFuZ2VkIjogY2hhbmdlZCwKICAgICAgICAgICAgICAgICAgICAgICAgImpzb25EaWZmZXJlbmNlIjoganNvbkRpZmZlcmVuY2UKICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJuIHRoZSBEYXRhU09NTWFwIGFmdGVyIGFkZGluZyBhbiBlbnRyeSBpbiB0aGUgbWFwIGZvciB0aGUgbm9kZS4gVGhlIGVudHJ5IGNvbnRhaW5zIHRoZSB2YWx1ZSBvZiB0aGUgbm9kZQogICAgICAgICAqIGFsb25nIHdpdGggaXRzIERhdGEgU09NLiBJZiB0aGVyZSBpcyBubyBEYXRhIFNPTSB0aGVuIHJldHVybiB0aGUgdW5tb2RpZmllZCBtYXAKICAgICAgICAgKiBAcGFyYW0gbWFwCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfZ2V0RGF0YVNvbU1hcCA6IGZ1bmN0aW9uIChtYXApIHsKICAgICAgICAgICAgcmV0dXJuIG1hcDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBVcGRhdGUgdGhlIHZhbHVlIG9mIHRoZSBub2RlIHdpdGggdGhlIHZhbHVlIHByb3ZpZGVkIGluIHRoZSBpbnB1dCBtYXAuIFRoZSBtYXAgY29udGFpbnMgdGhlIHZhbHVlcyBvZiB0aGUgZmllbGRzCiAgICAgICAgICogbWFwcGVkIHdpdGggdGhlaXIgRGF0YVNPTS4gVGhlIGZ1bmN0aW9uIGlzIGVtcHR5IGZvciBhbGwgdGhlIG5vZGVzLCBleGNlcHQgZm9yIEZpZWxkLCBTdWJmb3JtIGFuZCBBcmVhLgogICAgICAgICAqIEBwYXJhbSBtYXAKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9yZXN0b3JlRGF0YVNvbU1hcCA6IGZ1bmN0aW9uIChtYXApIHsKCiAgICAgICAgfSwKCiAgICAgICAgX3BsYXlEYXRhWE1MOiBmdW5jdGlvbiAocm9vdE5vZGUsIGNvbnRleHROb2RlKSB7CgogICAgICAgIH0sCgogICAgICAgIGdlbmVyYXRlRGF0YVhNTDogZnVuY3Rpb24gKHhtbERvY3VtZW50LCBjb250ZXh0Tm9kZSkgewoKICAgICAgICB9CgogICAgfSk7CgogICAgRE9NRWxlbWVudC5kZWZpbmVQcm9wcyh7CiAgICAgICAgbW9DaGlsZE5vZGVzOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX2NoaWxkcmVuSW5pdGlhbGl6ZVBlbmRpbmcpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbml0Q2hpbGRyZW5JbnRlcm5hbCgpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2NoaWxkcmVuSW5pdGlhbGl6ZVBlbmRpbmcgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb0NoaWxkTm9kZXM7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tb0NoaWxkTm9kZXMgPSB2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CgoKCi8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LkNvbnRhaW5lck5vZGUKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LkVsZW1lbnQKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBDb250YWluZXIgRWxlbWVudCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBCiAqICAgICAgICAgICAgICAgbGlicmFyeQogKiBAdmVyc2lvbiAwLjAuMQogKi8KCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgLyoqCiAgICAgKiBAY2xhc3MgVGhlIGNsYXNzIHJlcHJlc2VudHMgYWxsIHRoZSBYRkEgT2JqZWN0cyB3aGljaCBjYW4gY29udGFpbiBvdGhlciBYRkEKICAgICAqICAgICAgICBub2RlcyBpbnNpZGUgdGhlbQogICAgICogQGV4dGVuZHMgY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuRWxlbWVudAogICAgICoKICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IGNoaWxkcmVuIGNoaWxkcmVuIG9mIHRoZSBDb250YWluZXJOb2RlCiAgICAgKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgbm9kZQogICAgICoKICAgICAqLwogICAgdmFyIENvbnRhaW5lck5vZGUgPSB4ZmFsaWIuc2NyaXB0LkNvbnRhaW5lck5vZGUgPSB4ZmFsaWIuc2NyaXB0LkVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBfaXNYRkFDb250YWluZXJOb2RlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CgoKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHZhciBFdmVudENvbnRhaW5lck5vZGUgPSB4ZmFsaWIuc2NyaXB0LkV2ZW50Q29udGFpbmVyTm9kZSA9IHhmYWxpYi5zY3JpcHQuQ29udGFpbmVyTm9kZS5leHRlbmQoewogICAgICAgIF9kZWZhdWx0cyA6IHsKICAgICAgICAgICAgImFjY2VzcyIgOiAib3BlbiIsCiAgICAgICAgICAgICJldmVudCIgOiB7CiAgICAgICAgICAgICAgICAidHlwZSIgOiAiY2xpY2siIC8vaWRlYWxseSwgdGhpcyBzaG91bGQgYmUgYWN0aXZpdHkKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInZhbGlkYXRlIiA6IHsKICAgICAgICAgICAgICAgICJkaXNhYmxlQWxsIiA6ICIwIiwKICAgICAgICAgICAgICAgICJmb3JtYXRUZXN0IiA6ICJ3YXJuaW5nIiwKICAgICAgICAgICAgICAgICJudWxsVGVzdCIgOiAiZGlzYWJsZWQiLAogICAgICAgICAgICAgICAgInNjcmlwdFRlc3QiIDogImVycm9yIiwKICAgICAgICAgICAgICAgICJtZXNzYWdlIiA6IHsKICAgICAgICAgICAgICAgICAgICAiZGVmYXVsdE1lc3NhZ2UiIDogewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogeGZhbGliLmxvY2FsZS5TdHJpbmdzLnZhbGlkYXRpb25Jc3N1ZQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICBFdmVudENvbnRhaW5lck5vZGUuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICAgICAqIEB0eXBlIE9iamVjdAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdGhpcy5tb0V2ZW50cyA9IHt9OwogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogbWFya3MgdGhlIGV2ZW50IHRoYXQgYXJlIGZpcmVkIGluIHRoZSBjdXJyZW50IHNjcmlwdCBleGVjdXRpb24gYXMgdHJ1ZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgICAgICogQHR5cGUgT2JqZWN0CiAgICAgICAgICAgICAqLwogICAgICAgICAgICB0aGlzLm1BY3RpdmVFdmVudHMgPSB7fTsKICAgICAgICAgICAgdGhpcy5fZXJyb3JUZXh0ID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5fbUZhaWxlZFZhbFRlc3QgPSBudWxsOwogICAgICAgICAgICB0aGlzLl9tRmFpbGVkVmFsTGV2ZWwgPSBudWxsOyAvL2NhbiBiZSB3YXJuaW5nIG9yIGVycm9yCiAgICAgICAgICAgIHRoaXMuZGVwZW5kYW50ID0gW107CiAgICAgICAgICAgIHRoaXMudGVzdHM9IG51bGw7IC8vbXVzdCBiZSBvdmVycmlkZGVuIGJ5IHN1YiBjbGFzc2VzCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAgICAgKiBAdHlwZSBzdHJpbmcKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHRoaXMubUVmZmVjdGl2ZUFjY2VzcyA9IG51bGw7CiAgICAgICAgICAgIHRoaXMubUVmZmVjdGl2ZVByZXNlbmNlID0gbnVsbDsKICAgICAgICAgICAgLy9Jbml0aWFsaXplIGV2ZW50cyBhcnJheQogICAgICAgICAgICB0aGlzLl9hZGRFdmVudHMoKTsKICAgICAgICAgICAgdGhpcy5fZXZlbnRMaXN0ZW5lcigpOwoKICAgICAgICAgICAgdGhpcy5fbW9Db250ZXh0ID0gbnVsbDsgIC8vIHdpbGwgY2FjaGUgdGhlIG5ha2VkUmVmZXJlbmNlcyBmb3IgZWFjaCBFdmVudENvbnRhaW5lck5vZGUKICAgICAgICAgfSwKCiAgICAgICAgLy8gdmlzaXQgdGhpcyBhbmQgYWxsIGNoaWxkIG5vZGVzIHJlY3Vyc2l2ZWx5CiAgICAgICAgX3Zpc2l0QWxsbW9DaGlsZHJlbjogZnVuY3Rpb24gKHZpc2l0b3IpIHsKICAgICAgICAgICAgaWYgKF8uaXNGdW5jdGlvbih2aXNpdG9yKSkgewogICAgICAgICAgICAgICAgdmlzaXRvcih0aGlzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgXy5lYWNoKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgIGlmIChfLmlzRnVuY3Rpb24oY2hpbGQuX3Zpc2l0QWxsbW9DaGlsZHJlbikpIHsKICAgICAgICAgICAgICAgICAgICBjaGlsZC5fdmlzaXRBbGxtb0NoaWxkcmVuKHZpc2l0b3IpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9LAoKCiAgICAgICAgX2V2ZW50TGlzdGVuZXIgOmZ1bmN0aW9uKCkgewogICAgICAgICAgICBmb3IgKCB2YXIgaSA9IDA7IGkgPCB0aGlzLm1vQ2hpbGROb2Rlcy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICAgICB2YXIgb05vZGUgPSB0aGlzLm1vQ2hpbGROb2Rlc1tpXTsKICAgICAgICAgICAgICAgaWYob05vZGUgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQpCiAgICAgICAgICAgICAgICAgIG9Ob2RlLm9uKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCx0aGlzKSA7CiAgICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcGFyYW0gcHJlZGljYXRlVGVzdCA6IGZ1bmN0aW9uIGNvbnRhaW5pbmcgcHJlZGljYXRlIHRlc3QuCiAgICAgICAgICogQHBhcmFtIGV4ZWNFdmVudCA6IGZ1bmN0aW9uIGNvbnRhaW5pbmcgZXZlbnRzIHdoaWNoIG5lZWRzIHRvIGJlIGV4ZWN1dGVkLgogICAgICAgICAqIGV4ZWN1dGVzIGV2ZW50cyBvbiBjaGlsZCBub2RlcyBwcm92aWRlZCBhcyBleGVjRXZlbnQuCiAgICAgICAgICovCiAgICAgICAgX2V4ZWNFdmVudE9uQ2hpbGROb2RlcyA6IGZ1bmN0aW9uIChjaGlsZE5vZGVzRmlsdGVyLCBleGVjRXZlbnQpIHsKICAgICAgICAgICAgaWYoIXRoaXMuX2lzRmllbGQoKSl7IC8vSWRlYWxseSBpc0ZpZWxkIGNoZWNrIHNob3VsZCBub3QgYmUgaGVyZSBidXQgYSBzaG9ydCBjdXQgZm9yIG5vdyBzaW5jZSBpdCdzIHRoZSBvbmx5IGV4Y3B0aW9uLgogICAgICAgICAgICAgICAgXy5lYWNoICh0aGlzLm1vQ2hpbGROb2RlcywgZnVuY3Rpb24ob05vZGUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGROb2Rlc0ZpbHRlcihvTm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZXhlY0V2ZW50KG9Ob2RlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jaGlsZE5vZGVzRmlsdGVyIDogZnVuY3Rpb24gKG9Ob2RlKSB7CiAgICAgICAgICAgIHJldHVybiBvTm9kZS5faXNFdmVudE5vZGUoKSAmJiBvTm9kZS5jbGFzc05hbWUgIT0gInBhZ2VTZXQiICYmIG9Ob2RlLnByZXNlbmNlICE9ICJpbmFjdGl2ZSI7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY0luaXRpYWxpemUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGZ1bmN0aW9uIGV4ZWNFdmVudCAob05vZGUpIHsKICAgICAgICAgICAgICAgIG9Ob2RlLmV4ZWNJbml0aWFsaXplKCkKICAgICAgICAgICAgfTsKICAgICAgICAgICAgdGhpcy5fZXhlY0V2ZW50T25DaGlsZE5vZGVzKHRoaXMuX2NoaWxkTm9kZXNGaWx0ZXIsIGV4ZWNFdmVudCk7CiAgICAgICAgICAgIHRoaXMuZXhlY0V2ZW50KCJpbml0aWFsaXplIik7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY0Zvcm1SZWFkeSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBmdW5jdGlvbiBleGVjRXZlbnQgKG9Ob2RlKSB7CiAgICAgICAgICAgICAgICBvTm9kZS5leGVjRm9ybVJlYWR5KCkKICAgICAgICAgICAgfTsKICAgICAgICAgICAgdGhpcy5fZXhlY0V2ZW50T25DaGlsZE5vZGVzKHRoaXMuX2NoaWxkTm9kZXNGaWx0ZXIsIGV4ZWNFdmVudCk7CiAgICAgICAgICAgIHRoaXMuZXhlY0V2ZW50KCIkZm9ybXJlYWR5Iik7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY0xheW91dFJlYWR5IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGZ1bmN0aW9uIGV4ZWNFdmVudCAob05vZGUpIHsKICAgICAgICAgICAgICAgIG9Ob2RlLmV4ZWNMYXlvdXRSZWFkeSgpCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHRoaXMuX2V4ZWNFdmVudE9uQ2hpbGROb2Rlcyh0aGlzLl9jaGlsZE5vZGVzRmlsdGVyLCBleGVjRXZlbnQpOwogICAgICAgICAgICB0aGlzLmV4ZWNFdmVudCgiJGxheW91dHJlYWR5Iik7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY0NhbGN1bGF0ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBmdW5jdGlvbiBjaGlsZE5vZGVzRmlsdGVyIChvTm9kZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG9Ob2RlLl9pc0V2ZW50Tm9kZSgpICYmIG9Ob2RlLnByZXNlbmNlICE9ICJpbmFjdGl2ZSI7CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIGZ1bmN0aW9uIGV4ZWNFdmVudCAob05vZGUpIHsKICAgICAgICAgICAgICAgIG9Ob2RlLmV4ZWNDYWxjdWxhdGUoKQogICAgICAgICAgICB9OwogICAgICAgICAgICBpZiAoIXRoaXMuX3hmYSgpLmhvc3QuY2FsY3VsYXRpb25zRW5hYmxlZCkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMuX2V4ZWNFdmVudE9uQ2hpbGROb2RlcyhjaGlsZE5vZGVzRmlsdGVyLCBleGVjRXZlbnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgdGhpcy5leGVjRXZlbnQoImNhbGN1bGF0ZSIpOwogICAgICAgIH0sCgogICAgICAgIGV4ZWNWYWxpZGF0ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpZiAoIXRoaXMuX3hmYSgpLmhvc3QudmFsaWRhdGlvbnNFbmFibGVkKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIHZhciB2YWxpZCA9IHRydWU7CiAgICAgICAgICAgIGlmKCF0aGlzLl9pc0ZpZWxkKCkpewogICAgICAgICAgICAgICAgZm9yICggdmFyIGkgPSAwOyBpIDwgdGhpcy5tb0NoaWxkTm9kZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgb05vZGUgPSB0aGlzLm1vQ2hpbGROb2Rlc1tpXTsKICAgICAgICAgICAgICAgICAgICBpZiAob05vZGUuX2lzRXZlbnROb2RlKCkpewogICAgICAgICAgICAgICAgICAgICAgICBpZighb05vZGUuZXhlY1ZhbGlkYXRlKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB2YWxpZCA9IHZhbGlkICYmIHRoaXMuX3ZhbGlkYXRlKFtdKTsKICAgICAgICAgICAgcmV0dXJuIHZhbGlkOwogICAgICAgIH0sCgogICAgICAgIGV4ZWNQcmVTdWJtaXQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBpc1N1Ym1pc3Npb25BbGxvd2VkID0gdHJ1ZTsgIC8vIHRvIGhhbmRsZSB0aGUgY2FuY2VsQWN0aW9uIHByb3BlcnR5LCB3aGljaCBpZiB0cnVlIHdpbGwgcHJldmVudCBzdWJtaXNzaW9uCiAgICAgICAgICAgIGlmKCF0aGlzLl9pc0ZpZWxkKCkpIHsKICAgICAgICAgICAgICAgIF8uZWFjaCAodGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uKG9Ob2RlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKG9Ob2RlLl9pc0V2ZW50Tm9kZSgpICYmIG9Ob2RlLnByZXNlbmNlICE9ICJpbmFjdGl2ZSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXNTdWJtaXNzaW9uQWxsb3dlZCA9IG9Ob2RlLmV4ZWNQcmVTdWJtaXQoKSAmJiBpc1N1Ym1pc3Npb25BbGxvd2VkOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLmV4ZWNFdmVudCgiJGZvcm1wcmVTdWJtaXQiKSA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgaXNTdWJtaXNzaW9uQWxsb3dlZCA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBpc1N1Ym1pc3Npb25BbGxvd2VkOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogY3JlYXRlcyBhIHNjb3BlIHNvIHRoYXQgYWxsIHRoZSBub2RlcyBhY2Nlc3NpYmxlIGZyb20gdGhpcyBub2RlCiAgICAgICAgICogYXJlIGF2YWlsYWJsZSB0byB0aGUgc2NyaXB0IGV2ZW50IGFuZCByZXR1cm5zIHRoZSBwcmV2aW91cyBzY29wZQogICAgICAgICAqCiAgICAgICAgICogQWZ0ZXIgZXhlY3V0aW5nIHRoZSBzY3JpcHQgdGhlIHNjb3BlIG11c3QgYmUgcmVzZXQgdXNpbmcgX3Jlc2V0TmFrZWRSZWZlcmVuY2VzU2NvcGUKICAgICAgICAgKiBOb3QgZG9pbmcgdGhhdCB3aWxsIHJlc3VsdCBpbiB1bnN0YWJsZSBzdGF0ZSBhbmQgY2F1c2Ugc2VyaW91cyBpc3N1ZXMKICAgICAgICAgKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgX2NyZWF0ZU5ha2VkUmVmZXJlbmNlc1Njb3BlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBzdGFydE5vZGUgPSB0aGlzLAogICAgICAgICAgICAgICAgY3VycmVudEluZGV4ID0gdGhpcy5pbmRleCwKICAgICAgICAgICAgICAgIG9sZENvbnRleHQgPSB7fTsKCiAgICAgICAgICAgIC8vc3RvcmUgdGhlIG9sZCBjb250ZXh0IGluIG9yZGVyIHRvIHJlc2V0IGl0LgogICAgICAgICAgICBfLmV4dGVuZChvbGRDb250ZXh0LHhmYWxpYi5ydW50aW1lLl9wcml2YXRlKTsKCiAgICAgICAgICAgIC8vVE9ETzogb3B0aW1pemUgdG8gY2hlY2sgd2l0aCBsYXN0TmFrZWRTdWJmb3JtCiAgICAgICAgICAgIGlmICh0aGlzLl9tb0NvbnRleHQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuX3ByaXZhdGUgPSB7fTsKICAgICAgICAgICAgICAgIHdoaWxlIChzdGFydE5vZGUpIHsKICAgICAgICAgICAgICAgICAgICBzdGFydE5vZGUubmFrZWRGaWVsZFJlZmVyZW5jZXMoY3VycmVudEluZGV4LCB0cnVlLCB4ZmFsaWIucnVudGltZSk7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudEluZGV4ID0gc3RhcnROb2RlLmluZGV4OwogICAgICAgICAgICAgICAgICAgIHN0YXJ0Tm9kZSA9IHN0YXJ0Tm9kZS5wYXJlbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLl9tb0NvbnRleHQgPSB4ZmFsaWIucnVudGltZS5fcHJpdmF0ZTsgICAgLy8ganVzdCBjb3B5IHJlZiBhcyB3ZSBhcmUgcmVjcmVhdGluZyB4ZmFsaWIucnVudGltZS5fcHJpdmF0ZQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuX3ByaXZhdGUgPSB0aGlzLl9tb0NvbnRleHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG9sZENvbnRleHQ7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKiBUaGUgZnVuY3Rpb24gc2hvdWxkIGJlIGNhbGxlZCBhZnRlciBleGVjdXRpbmcgdGhlIHNjcmlwdCB0byByZXNldCB0aGUgc2NvcGUKICAgICAgICAgKiBOb3QgZG9pbmcgdGhhdCB3aWxsIHJlc3VsdCBpbiB1bnN0YWJsZSBzdGF0ZSBhbmQgY2F1c2Ugc2VyaW91cyBpc3N1ZXMKICAgICAgICAgKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgX3Jlc2V0TmFrZWRSZWZlcmVuY2VzU2NvcGUgOiBmdW5jdGlvbihzY29wZSkgewogICAgICAgICAgICB4ZmFsaWIucnVudGltZS5fcHJpdmF0ZSA9IHt9OwogICAgICAgICAgICBfLmV4dGVuZCh4ZmFsaWIucnVudGltZS5fcHJpdmF0ZSwgc2NvcGUpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBjYXB0dXJlcyB0aGUgZXZlbnQgYW5kIHNlbmRzIGl0IHRvIHRoZSB7QGxpbmsgX2V2ZW50SGFuZGxlcn0KICAgICAgICAgKi8KICAgICAgICBleGVjRXZlbnQgOiBmdW5jdGlvbihldmVudE5hbWUsIGRldGFpbCkgewogICAgICAgICAgICBpZih0eXBlb2YgdGhpcy5tb0V2ZW50c1tldmVudE5hbWVdID09PSAidW5kZWZpbmVkIikgewogICAgICAgICAgICAgICAgaWYodGhpcy5feGZhKCkubW9Db250ZXh0Tm9kZXMubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5ydW5DYWxjQW5kVmFsaWRhdGUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZGVidWcoInhmYSIsIGV2ZW50TmFtZSsiIGZpcmVkIGZvciAiK3RoaXMuc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgIC8vdXNlIHN0YW5kYXJkIGV2ZW50IG5hbWVzIGluc3RlYWQgb2Ygb3VyIGhvbWUgbWFkZSBuYW1lcyB0byBtYXRjaCB3aGF0IHBkZiByZXR1cm5zIHRvIHVzZXIKICAgICAgICAgICAgdmFyIHN0ZEV2ZW50TmFtZSA9IHRoaXMueGZhVXRpbCgpLl94dGdFdmVudE5hbWVbZXZlbnROYW1lXSA/IHRoaXMueGZhVXRpbCgpLl94dGdFdmVudE5hbWVbZXZlbnROYW1lXSA6IGV2ZW50TmFtZTsKICAgICAgICAgICAgc3dpdGNoKGV2ZW50TmFtZSl7CiAgICAgICAgICAgICAgICBjYXNlICJjaGFuZ2UiOgogICAgICAgICAgICAgICAgICAgIGlmIChkZXRhaWw9PT11bmRlZmluZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciAkZXZlbnQgPSBuZXcgeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50KHsianNvbk1vZGVsIjp7Im5hbWUiOnN0ZEV2ZW50TmFtZSwidGFyZ2V0Ijp0aGlzfX0pOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgdmFyICRldmVudCA9IG5ldyB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQoeyJqc29uTW9kZWwiOnsibmFtZSI6c3RkRXZlbnROYW1lLCJ0YXJnZXQiOnRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicHJldlRleHQiOmRldGFpbC5wcmV2VGV4dCwibmV3VGV4dCI6ZGV0YWlsLm5ld1RleHQsImtleURvd24iOmRldGFpbC5rZXlEb3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1vZGlmaWVyIjpkZXRhaWwubW9kaWZpZXIsInNoaWZ0IjpkZXRhaWwuc2hpZnQsImNoYW5nZSI6ZGV0YWlsLmNoYW5nZSwiZnVsbFRleHQiOmRldGFpbC5mdWxsVGV4dH19KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgImNsaWNrIjoKICAgICAgICAgICAgICAgICAgICBpZiAoZGV0YWlsPT09dW5kZWZpbmVkKQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgJGV2ZW50ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudCh7Impzb25Nb2RlbCI6eyJuYW1lIjpzdGRFdmVudE5hbWUsInRhcmdldCI6dGhpc319KTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciAkZXZlbnQgPSBuZXcgeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50KHsianNvbk1vZGVsIjp7Im5hbWUiOnN0ZEV2ZW50TmFtZSwidGFyZ2V0Ijp0aGlzLCJtb2RpZmllciI6ZGV0YWlsLm1vZGlmaWVyLCJzaGlmdCI6ZGV0YWlsLnNoaWZ0fX0pOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB2YXIgJGV2ZW50ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudCh7Impzb25Nb2RlbCI6eyJuYW1lIjpzdGRFdmVudE5hbWUsInRhcmdldCI6dGhpc319KTsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuJGV2ZW50ID0gJGV2ZW50OwogICAgICAgICAgICB0aGlzLl94ZmEoKS5ldmVudCA9ICRldmVudDsKICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuZXZlbnQgPSB4ZmFsaWIuYWNyb2JhdC5BY3JvRXZlbnQuY2xvbmVFdmVudCgkZXZlbnQpOwogICAgICAgICAgICBpZih0aGlzLmFjY2VzcyA9PSAicHJvdGVjdGVkIiAmJiBldmVudE5hbWUhPT0iY2FsY3VsYXRlIiAmJiBldmVudE5hbWUhPT0gInZhbGlkYXRlIikgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEFjY29yZGluZyB0byB4ZmEgc3BlYyA6IHdoZW4gYSBjb250YWluZXIgaXMgaW5hY3RpdmUgYW55IGNhbGN1bGF0aW9ucywgdmFsaWRhdGlvbnMsIG9yIGV2ZW50cyBpdCB3b3VsZCBub3JtYWxseSBnZW5lcmF0ZSBhcmUgc3VwcHJlc3NlZAogICAgICAgICAgICBpZiAodGhpcy5tRWZmZWN0aXZlUHJlc2VuY2UgPT0gImluYWN0aXZlIikgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5tQWN0aXZlRXZlbnRzW2V2ZW50TmFtZV0pIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLm1BY3RpdmVFdmVudHNbZXZlbnROYW1lXSA9IHRydWU7CiAgICAgICAgICAgIHRoaXMuX3hmYSgpLl9wdXNoQ29udGV4dE5vZGUodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX3hmYSgpLm1vQ29udGV4dFNjcmlwdEV2ZW50ID0gZXZlbnROYW1lOwoKICAgICAgICAgICAgdmFyIG9sZFNjb3BlID0gdGhpcy5fY3JlYXRlTmFrZWRSZWZlcmVuY2VzU2NvcGUoKTsKCiAgICAgICAgICAgIHZhciB0ZW1wJCA9ICQ7CiAgICAgICAgICAgICQgPSB0aGlzOwogICAgICAgICAgICB2YXIgclZhbHVlID0gdGhpcy5fZXZlbnRIYW5kbGVyKGV2ZW50TmFtZSk7CiAgICAgICAgICAgICQgPSB0ZW1wJDsKICAgICAgICAgICAgdGhpcy5tQWN0aXZlRXZlbnRzW2V2ZW50TmFtZV0gPSBmYWxzZTsKICAgICAgICAgICAgdGhpcy5feGZhKCkuX3BvcENvbnRleHROb2RlKCk7CiAgICAgICAgICAgIHRoaXMuX3hmYSgpLm1vQ29udGV4dFNjcmlwdEV2ZW50ID0gbnVsbDsKCiAgICAgICAgICAgICRldmVudCA9IG51bGw7CiAgICAgICAgICAgIGlmKHRoaXMuX3hmYSgpLm1vQ29udGV4dE5vZGVzLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5ydW5DYWxjQW5kVmFsaWRhdGUoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2V0TmFrZWRSZWZlcmVuY2VzU2NvcGUob2xkU2NvcGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByVmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRG9tRXZlbnQ6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICB9LAoKICAgICAgICBoYW5kbGVFdmVudCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQubmFtZSkgewogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuT0JKRUNUX0RFU1RST1lFRDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZW1vdmVEZXBlbmRhbnQoZXZlbnQudGFyZ2V0KTsKICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkRPTV9DSEFOR0VEOgogICAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVEb21FdmVudChldmVudCkKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgLy94ZmEuTG9nZ2VyLmRlYnVnKCJldmVudCAiICsgZXZlbnQubmFtZSArICIgbm90IHN1cHBvcnRlZCIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGFkZERlcGVuZGFudDogZnVuY3Rpb24ob05vZGUpIHsKICAgICAgICAgICAgaWYoIX50aGlzLmRlcGVuZGFudC5pbmRleE9mKG9Ob2RlKSAmJiBvTm9kZSAhPSB0aGlzKQogICAgICAgICAgICAgICAgdGhpcy5kZXBlbmRhbnQucHVzaChvTm9kZSk7CiAgICAgICAgfSwKCiAgICAgICAgX2FkZEV2ZW50cyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgZXZlbnRzID0gXy5maWx0ZXIodGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uKGNoaWxkTW9kZWwpewogICAgICAgICAgICAgICByZXR1cm4gY2hpbGRNb2RlbC5jbGFzc05hbWUgPT0gImV2ZW50IjsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlmIChldmVudHMgJiYgZXZlbnRzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIGZvciAoIHZhciBpID0gMDsgaSA8IGV2ZW50cy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHZhciBldmVudCA9IGV2ZW50c1tpXTsKICAgICAgICAgICAgICAgICAgICAvLyByZWYgd2FzIGFkZGVkIHRvIHN1cHBvcnQgZm9ybVJlYWR5IGFuZCBsYXlvdXRSZWFkeSB3aGVyZSB0aGUgZXZlbnQgbmFtZXMgYXJlIGF2YWlsYWJsZSBhcwogICAgICAgICAgICAgICAgICAgIC8vJGZvcm1SZWFkeSBhbmQgJGxheW91dFJlYWR5IChjaGVjayAtIF94dGdFdmVudE5hbWUgaW4gdGhlIGNsYXNzOiBYZmFVdGlsLmpzKS4KICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHdlIGFkZCBhIHN0eWxlIHRvIGFuIGVsZW1lbnQsIGRlc2lnbmVyIGFkZHMgYSByZWYgdmFsdWUgb2YgJyQnCiAgICAgICAgICAgICAgICAgICAgLy93aGljaCBpcyBhbHNvIHRoZSBkZWZhdWx0LiBJbiBzdWNoIGEgc2NlbmFyaW8gdGhlIGV2ZW50IG5hbWVzIGJlY29tZSAkY2xpY2ssICRjaGFuZ2UsIGV0Yy4gVG8KICAgICAgICAgICAgICAgICAgICAvL2hhbmRsZSB0aGlzIGZvciBub3cgKHdpdGhvdXQgYSBmdWxsIGltcGxlbWVudGF0aW9uIG9mIHJlZikgd2UgYXJlIHJlbW92aW5nIHRoZSAkIGRlZmF1bHQgdmFsdWUKICAgICAgICAgICAgICAgICAgICAvL2FuZCBzZXR0aW5nIGl0IGFzICRjbGljayAtPiBjbGljaywgZXRjLiBGb3IgZGV0YWlscyBvbiByZWY6CiAgICAgICAgICAgICAgICAgICAgLy9odHRwOi8vYmxvZ3MuYWRvYmUuY29tL2Zvcm1mZWVkLzIwMDkvMDMveGZhXzMwX2V2ZW50X3Byb3BhZ2F0aW9uLmh0bWwKICAgICAgICAgICAgICAgICAgICB2YXIgcmVmID0gKGV2ZW50LnJlZiB8fCAiIik7CiAgICAgICAgICAgICAgICAgICAgaWYocmVmID09ICIkIikgcmVmID0gIiI7CiAgICAgICAgICAgICAgICAgICAgdmFyIHR5cGUgPSByZWYgKyBldmVudC5hY3Rpdml0eTsKICAgICAgICAgICAgICAgICAgICB0aGlzLm1vRXZlbnRzW3R5cGVdID0gdGhpcy5tb0V2ZW50c1t0eXBlXSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnRDaGlsZCA9IGV2ZW50Lm9uZU9mQ2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGV2ZW50Q2hpbGQuY2xhc3NOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInNjcmlwdCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihldmVudENoaWxkLnZhbHVlIT1udWxsICYmIChldmVudENoaWxkLnJ1bkF0ID09PSAic2VydmVyIiB8fCBldmVudENoaWxkLnZhbHVlLnRyaW0oKS5sZW5ndGggPjApKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubW9FdmVudHNbdHlwZV0ucHVzaChuZXcgeGZhbGliLnNjcmlwdC5FeGVjdXRhYmxlU2NyaXB0KHsianNvbk1vZGVsIiA6IGV2ZW50Q2hpbGQuanNvbk1vZGVsfSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInN1Ym1pdCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1vRXZlbnRzW3R5cGVdLnB1c2gobmV3IHhmYWxpYi5zY3JpcHQuU3VibWl0KHsianNvbk1vZGVsIiA6IGV2ZW50Q2hpbGQuanNvbk1vZGVsfSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuX25ld1N1Ym1pdEJ1dHRvbih0aGlzKTsgIC8vVE9ETzogV2hhdCBpcyBpdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgY2FsY0NoaWxkID0gIF8uZmluZCh0aGlzLm1vQ2hpbGROb2RlcywgZnVuY3Rpb24oY2hpbGRNb2RlbCl7CiAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGRNb2RlbC5jbGFzc05hbWUgPT0gImNhbGN1bGF0ZSI7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBpZihjYWxjQ2hpbGQpIHsKICAgICAgICAgICAgICAgIHZhciBjYWxjU2NyID0gXy5maW5kKGNhbGNDaGlsZC5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uKGNoaWxkTW9kZWwpewogICAgICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZE1vZGVsLmNsYXNzTmFtZSA9PSAic2NyaXB0IjsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgaWYoY2FsY1NjcikgewogICAgICAgICAgICAgICAgICAgIHRoaXMubW9FdmVudHNbImNhbGN1bGF0ZSJdID0gW25ldyB4ZmFsaWIuc2NyaXB0LkNhbGN1bGF0ZVNjcmlwdCh7Impzb25Nb2RlbCIgOiBjYWxjU2NyLmpzb25Nb2RlbH0pXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHZhbGlkQ2hpbGQgPSAgXy5maW5kKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbihjaGlsZE1vZGVsKXsKICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZE1vZGVsLmNsYXNzTmFtZSA9PSAidmFsaWRhdGUiOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgaWYodmFsaWRDaGlsZCkgewogICAgICAgICAgICAgICAgdmFyIHZhbGlkU2NyID0gXy5maW5kKHZhbGlkQ2hpbGQubW9DaGlsZE5vZGVzLCBmdW5jdGlvbihjaGlsZE1vZGVsKXsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGRNb2RlbC5jbGFzc05hbWUgPT0gInNjcmlwdCI7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGlmKHZhbGlkU2NyKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb0V2ZW50c1sidmFsaWRhdGUiXSA9IFtuZXcgeGZhbGliLnNjcmlwdC5WYWxpZGF0ZVNjcmlwdCh7Impzb25Nb2RlbCIgOiB2YWxpZFNjci5qc29uTW9kZWx9KV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vaXMgaXQgYSBnb29kIGlkZWEgdG8gY3JlYXRlIGJlaGF2aW9yQ29uZmlnIGF0IHRoZSBmb3JtYnJpZGdlIG9yIHhmYWxpYi5ydW50aW1lIGxldmVsPz8/CiAgICAgICAgICAgIHZhciBiZWhhdmlvckNvbmZpZyA9IG5ldyB4ZmFsaWIudXQuVmVyc2lvbihmb3JtQnJpZGdlLnVzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl0pOwoKICAgICAgICAgICAgLy9UbyBtYWludGFpbiBiYWNrd2FyZCBjb21wYXRpYmlsaXR5CiAgICAgICAgICAgIGlmKGJlaGF2aW9yQ29uZmlnLmlzT24oJ2RhdGFEZXBlbmRlbnRGbG9hdGluZ0ZpZWxkJykgfHwgYmVoYXZpb3JDb25maWcuaXNPbignbWZEYXRhRGVwZW5kZW50RmxvYXRpbmdGaWVsZCcpKSB7CiAgICAgICAgICAgICAgICAvL3RoaXMgaXMgaW5zZXJ0ZWQgYnkgc2VydmVyIHdoZW4gYSBkcmF3IGVsZW1lbnQgY29udGFpbnMgZmxvYXRpbmcgZmllbGRzLgogICAgICAgICAgICAgICAgdmFyIHJlc29sdmVDaGlsZCA9IF8uZmluZCh0aGlzLm1vQ2hpbGROb2RlcywgZnVuY3Rpb24oY2hpbGRNb2RlbCl7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkTW9kZWwuY2xhc3NOYW1lID09ICJyZXNvbHZlIjsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgaWYgKHJlc29sdmVDaGlsZCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMubW9FdmVudHNbImNhbGN1bGF0ZSJdID0gW107CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl0ucHVzaChuZXcgeGZhbGliLnNjcmlwdC5GbG9hdGluZ0ZpZWxkU2NyaXB0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIEV2ZW50IEhhbmRsZXIgZnVuY3Rpb24gdG8gaGFuZGxlIGV2ZW50cyB0aHJvd24KICAgICAgICAgKi8KICAgICAgICBfZXZlbnRIYW5kbGVyIDogZnVuY3Rpb24oZXZlbnROYW1lKSB7CiAgICAgICAgICAgIHZhciByVmFsdWUgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIHN3aXRjaCAoZXZlbnROYW1lKSB7CiAgICAgICAgICAgICAgICBjYXNlICJ2YWxpZGF0ZSI6CiAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gclZhbHVlOwogICAgICAgIH0sCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiByZXR1cm5zIGlmIHRoZSBub2RlIGlzIGVsaWdpYmxlIGZvciB2YWxpZGF0aW9uIG9yIG5vdCBiYXNlZCBvbiB0aGUgcHJlc2VuY2UKICAgICAgICAgKi8KICAgICAgICBfaXNFbGlnaWJsZUZvclZhbGlkYXRpb24gOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMubUVmZmVjdGl2ZVByZXNlbmNlICE9ICJpbmFjdGl2ZSI7CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZURlcGVuZGFudHM6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBmb3IodmFyIGkgPTA7aTx0aGlzLmRlcGVuZGFudC5sZW5ndGg7aSsrKSB7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5xdWV1ZUNhbGNFdmVudCh0aGlzLmRlcGVuZGFudFtpXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaXNFdmVudE5vZGUgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICByZW1vdmVEZXBlbmRhbnQ6IGZ1bmN0aW9uKG9Ob2RlKSB7CiAgICAgICAgICAgIHRoaXMuZGVwZW5kYW50ID0gXy53aXRob3V0KG9Ob2RlKTsgICAgICAgLy9UT0RPOiBXaGF0IGlzIGl0LCBubyBzZWNvbmQgYXJndW1lbnQ/CiAgICAgICAgfSwKCiAgICAgICAgX2NoZWNrVGVzdHM6IGZ1bmN0aW9uKHNNZXNzYWdlcykgewogICAgICAgICAgICB2YXIgdmFsaWQgPSB0cnVlOwogICAgICAgICAgICB2YXIgdGVzdHMgPSB0aGlzLnRlc3RzIHx8IFtdOwogICAgICAgICAgICBmb3IodmFyIGkgPSAwO2k8dGVzdHMubGVuZ3RoO2krKykgewogICAgICAgICAgICAgICAgdmFsaWQgPSB0ZXN0c1tpXS5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICBpZighdmFsaWQpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbGlkOwogICAgICAgIH0sCgogICAgICAgIF9zY3JpcHRUZXN0IDogZnVuY3Rpb24oc01lc3NhZ2VzKSB7CiAgICAgICAgICAgIHZhciB2YWxpZCA9IHRydWU7CiAgICAgICAgICAgIHZhciB2YWxpZCA9IHRoaXMuZXhlY0V2ZW50KCJ2YWxpZGF0ZSIpOwogICAgICAgICAgICBpZiAodmFsaWQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tRmFpbGVkVmFsVGVzdCA9ICJzY3JpcHRUZXN0IjsKICAgICAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxMZXZlbCAgPSB0aGlzLmdldE9yRWxzZSh0aGlzLnZhbGlkYXRlLnNjcmlwdFRlc3QsIHRoaXMuX2RlZmF1bHRzLnZhbGlkYXRlLnNjcmlwdFRlc3QpIDsKICAgICAgICAgICAgICAgIHRoaXMuX2Vycm9yVGV4dCA9IHRoaXMudmFsaWRhdGlvbk1lc3NhZ2U7CiAgICAgICAgICAgICAgICB0aGlzLl9hZGRNZXNzYWdlKHNNZXNzYWdlcywgdGhpcy5fZXJyb3JUZXh0LCB0aGlzLl9tRmFpbGVkVmFsTGV2ZWwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB2YWxpZDsKICAgICAgICB9LAoKICAgICAgICBfdmFsaWRhdGUgOiBmdW5jdGlvbihzTWVzc2FnZXMpIHsKICAgICAgICAgICAgdmFyIG9sZEZhaWxlZFRlc3QgPSB0aGlzLl9tRmFpbGVkVmFsVGVzdDsKICAgICAgICAgICAgdmFyIG9sZFZhbGlkID0gdGhpcy5fZXJyb3JUZXh0ID8gZmFsc2UgOiB0cnVlOwogICAgICAgICAgICB0aGlzLl9tRmFpbGVkVmFsVGVzdCA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxMZXZlbCA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuX2Vycm9yVGV4dCA9IG51bGw7CiAgICAgICAgICAgIHZhciBjaGlsZFZhbGlkID0gdHJ1ZTsKICAgICAgICAgICAgaWYgKCF0aGlzLl9pc0VsaWdpYmxlRm9yVmFsaWRhdGlvbigpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhpcy5feGZhKCkuaG9zdC52YWxpZGF0aW9uc0VuYWJsZWQpIHsKICAgICAgICAgICAgICAgIGZvciAoIHZhciBpID0gMDsgaSA8IHRoaXMubW9DaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkTm9kZSA9IHRoaXMubW9DaGlsZE5vZGVzW2ldOwogICAgICAgICAgICAgICAgICAgIGlmKGNoaWxkTm9kZS5faXNFdmVudE5vZGUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFZhbGlkID0gdGhpcy5tb0NoaWxkTm9kZXNbaV0uX3ZhbGlkYXRlKHNNZXNzYWdlcykgJiYgY2hpbGRWYWxpZDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgdmFsaWQgPSB0aGlzLl9jaGVja1Rlc3RzKHNNZXNzYWdlcykgJiYgY2hpbGRWYWxpZDsKICAgICAgICAgICAgICAgIGlmKHZhbGlkPT1mYWxzZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsIHRoaXMsIlZhbGlkYXRpb25TdGF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxMZXZlbCwgdGhpcy5fZXJyb3JUZXh0KTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICAgICAgICAgIC8vIHRydWUgaW5kaWNhdGluZyB0aGF0IHByZXZpb3VzbHkgdGhpcyBmaWVsZCBpcyBub3QgaGF2aW5nIGVycm9yCiAgICAgICAgICAgICAgICAgICAgLy8gZmFsc2UgaW5kaWNhdGluZyB0aGF0IG5vdyB0aGlzIGZpZWxkIGlzIGhhdmluZyBhbiBlcnJvcgogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELAogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLCJDbGVhckVycm9yIixudWxsLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICAgICAgICAgIC8vIGZhbHNlIGluZGljYXRpbmcgdGhhdCBwcmV2aW91c2x5IHRoaXMgZmllbGQgaXMgIGhhdmluZyBlcnJvcgogICAgICAgICAgICAgICAgICAgIC8vIHRydWUgaW5kaWNhdGluZyB0aGF0IG5vdyB0aGlzIGZpZWxkIGlzIGhhdmluZyBhbiBlcnJvciBpLmUuIGVycm9yIENsZWFyZWQKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5fdHJpZ2dlck9uQnJpZGdlKCJlbGVtZW50VmFsaWRhdGlvblN0YXR1c0NoYW5nZWQiLCB0aGlzLCAidmFsaWRhdGlvblN0YXR1cyIsICF2YWxpZCwgdmFsaWQpOwogICAgICAgICAgICAgICAgLy9UT0RPOiBzaG93IHRoZSBlcnJvciB0byB1c2VyLgogICAgICAgICAgICAgICAgaWYgKHRoaXMuX21GYWlsZWRWYWxUZXN0ICE9IG9sZEZhaWxlZFRlc3QgfHwgdmFsaWQgIT0gb2xkVmFsaWQpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5leGVjRXZlbnQoInZhbGlkYXRpb25TdGF0ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB2YWxpZDsKICAgICAgICB9LAoKICAgICAgICBfYWRkTWVzc2FnZSA6IGZ1bmN0aW9uKHNNZXNzYWdlcywgc01lc3NhZ2UsIHNTZXZlcml0eSkgewogICAgICAgICAgICBpZiAoc01lc3NhZ2UpIHsKICAgICAgICAgICAgICAgIHZhciBvTWVzc2FnZU9iamVjdCA9IG5ldyBPYmplY3QoKTsKICAgICAgICAgICAgICAgIG9NZXNzYWdlT2JqZWN0Lm1lc3NhZ2UgPSBzTWVzc2FnZTsKICAgICAgICAgICAgICAgIG9NZXNzYWdlT2JqZWN0LnNldmVyaXR5ID0gc1NldmVyaXR5OwogICAgICAgICAgICAgICAgb01lc3NhZ2VPYmplY3QucmVmID0gdGhpcy5zb21FeHByZXNzaW9uOwogICAgICAgICAgICAgICAgc01lc3NhZ2VzLnB1c2gob01lc3NhZ2VPYmplY3QpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2NhbGN1bGF0ZUVmZmVjdGl2ZUFjY2VzcyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgcGFyZW50QWNjZXNzID0gdGhpcy5wYXJlbnQgPyB0aGlzLnBhcmVudC5tRWZmZWN0aXZlQWNjZXNzOiAib3BlbiIKICAgICAgICAgICAgdmFyIG5ld0VmZkFjY2VzcyA9ICh0aGlzLmFjY2VzcyA9PT0gIm9wZW4iICYmIHBhcmVudEFjY2Vzcyk/cGFyZW50QWNjZXNzIDp0aGlzLmFjY2VzczsKICAgICAgICAgICAgaWYodGhpcy5tRWZmZWN0aXZlQWNjZXNzICE9IG5ld0VmZkFjY2VzcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIG9sZFZhbCA9IHRoaXMubUVmZmVjdGl2ZUFjY2VzczsKICAgICAgICAgICAgICAgIHRoaXMubUVmZmVjdGl2ZUFjY2VzcyA9IG5ld0VmZkFjY2VzczsKICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUNoaWxkcmVuRWZmZWN0aXZlQWNjZXNzKCk7CiAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELAogICAgICAgICAgICAgICAgICAgIHRoaXMsImFjY2VzcyIsb2xkVmFsLHRoaXMubUVmZmVjdGl2ZUFjY2Vzcyk7CiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX3VwZGF0ZUNoaWxkcmVuRWZmZWN0aXZlQWNjZXNzIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmKCF0aGlzLl9pc0ZpZWxkKCkpeyAvL0lkZWFsbHkgaXNGaWVsZCBjaGVjayBzaG91bGQgbm90IGJlIGhlcmUgYnV0IGEgc2hvcnQgY3V0IGZvciBub3cgc2luY2UgaXQncyB0aGUgb25seSBleGNlcHRpb24uCiAgICAgICAgICAgICAgICBfLmVhY2godGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uKGVsZW0pIHsKICAgICAgICAgICAgICAgICAgICBpZihlbGVtLl9pc0V2ZW50Tm9kZSgpKQogICAgICAgICAgICAgICAgICAgICAgICBlbGVtLl9jYWxjdWxhdGVFZmZlY3RpdmVBY2Nlc3MoKTsKICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqIGNhbGN1bGF0ZSBlZmZlY3RpdmUgcHJlc2VuY2Ugd2hpY2ggaXMgdXNlZCB0byBpZGVudGlmeSB3aGV0aGVyIGN1cnJlbnQgbm9kZSBoYXZlIGFuY2VzdG9yIHByZXNlbmNlIGluYWN0aXZlCiAgICAgICAgICogQWNjb3JkaW5nIHRvIFhGQSBTUEVDIDogQSBuZXcgdmFsdWUsIGluYWN0aXZlLCBpcyBkZWZpbmVkIGZvciB0aGUgdWJpcXVpdG91cyBwcmVzZW5jZSBwcm9wZXJ0eS4gV2hlbiBhcHBsaWVkIHRvIGNvbnRhaW5lcnMKICAgICAgICAgKiB0aGlzIHByZXZlbnRzIHRoZSBjb250YWluZXIgYW5kIGl0cyBjb250ZW50cyBmcm9tIHByb2Nlc3NpbmcgY2FsY3VsYXRpb25zLCB2YWxpZGF0aW9ucywgYW5kIGV2ZW50cy4KICAgICAgICAgKiBXaGVuIGFuIG91dGVyIGNvbnRhaW5lciBjb250YWlucyBpbm5lciBjb250YWluZXJzLCBhbmQgdGhlIG91dGVyIGNvbnRhaW5lciBoYXMgYSBwcmVzZW5jZSB2YWx1ZSB0aGF0IHJlc3RyaWN0cyBpdHMgYmVoYXZpb3IsCiAgICAgICAgICogdGhlIGlubmVyIGNvbnRhaW5lcnMgaW5oZXJpdCB0aGUgb3V0ZXIgY29udGFpbmVy4oCZcyByZXN0cmljdGVkIGJlaGF2aW9yIHJlZ2FyZGxlc3Mgb2YgdGhlaXIgcHJlc2VuY2UgdmFsdWUuCiAgICAgICAgICovCiAgICAgICAgX2NhbGN1bGF0ZUVmZmVjdGl2ZVByZXNlbmNlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICh0aGlzLnByZXNlbmNlKSB7ICAgICAvLyBvbmx5IGNhbGN1bGF0ZSBlZmZlY3RpdmUgcHJlc2VuY2UgaWYgaXQgY29udGFpbnMgcHJlc2VuY2UgcHJvcGVydHkKICAgICAgICAgICAgICAgIHZhciBwYXJlbnRQcmVzZW5jZSA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMsICJwYXJlbnQubUVmZmVjdGl2ZVByZXNlbmNlIiwgInZpc2libGUiKSwKICAgICAgICAgICAgICAgICAgICBuZXdFZmZQcmVzZW5jZSA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAocGFyZW50UHJlc2VuY2UgPT0gImluYWN0aXZlIiApIHsKICAgICAgICAgICAgICAgICAgICBuZXdFZmZQcmVzZW5jZSA9ICJpbmFjdGl2ZSI7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmVudFByZXNlbmNlID09ICJoaWRkZW4iICYmIHRoaXMucHJlc2VuY2UgIT0gImluYWN0aXZlIikgewogICAgICAgICAgICAgICAgICAgIG5ld0VmZlByZXNlbmNlID0gImhpZGRlbiI7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmVudFByZXNlbmNlID09ICJpbnZpc2libGUiICYmIHRoaXMucHJlc2VuY2UgPT0gInZpc2libGUiKSB7CiAgICAgICAgICAgICAgICAgICAgbmV3RWZmUHJlc2VuY2UgPSAiaW52aXNpYmxlIjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbmV3RWZmUHJlc2VuY2UgPSB0aGlzLnByZXNlbmNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYodGhpcy5tRWZmZWN0aXZlUHJlc2VuY2UgIT0gbmV3RWZmUHJlc2VuY2UpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLm1FZmZlY3RpdmVQcmVzZW5jZSA9IG5ld0VmZlByZXNlbmNlOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUNoaWxkcmVuRWZmZWN0aXZlUHJlc2VuY2UoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUNoaWxkcmVuRWZmZWN0aXZlUHJlc2VuY2UoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogY2FsY3VsYXRlIGVmZmVjdGl2ZSBwcmVzZW5jZSBmb3IgY2hpbGQgbm9kZQogICAgICAgICAqLwogICAgICAgIF91cGRhdGVDaGlsZHJlbkVmZmVjdGl2ZVByZXNlbmNlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmKCF0aGlzLl9pc0ZpZWxkKCkgJiYgdGhpcy5tb0NoaWxkTm9kZXMpewogICAgICAgICAgICAgICAgXy5lYWNoKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbihvTm9kZSkgewogICAgICAgICAgICAgICAgICAgIGlmKG9Ob2RlLl9pc0V2ZW50Tm9kZSgpKQogICAgICAgICAgICAgICAgICAgICAgICBvTm9kZS5fY2FsY3VsYXRlRWZmZWN0aXZlUHJlc2VuY2UoKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcGxheUpzb24gOiBmdW5jdGlvbihwSnNvbk1vZGVsKSB7CiAgICAgICAgICAgIC8vT25seSBoYW5kbGUgc3BlY2lhbCBwcm9wZXJ0aWVzIHdoaWNoIGhhcyBwcml2YXRlIHByb3BlcnR5IGluIG1vZGVsLiBOZWVkIGEgcmV2aWV3IG9mIGFjY2VzcyBwcm9wZXJ0eQogICAgICAgICAgICBpZiAodGhpcy5feGZhKCkuX3RlbXBsYXRlU2NoZW1hLmhhc0F0dHJpYnV0ZSh0aGlzLmNsYXNzTmFtZSwgJ2FjY2VzcycpKSB7CiAgICAgICAgICAgICAgICB0aGlzLmFjY2VzcyA9IHBKc29uTW9kZWwuYWNjZXNzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLl94ZmEoKS5fdGVtcGxhdGVTY2hlbWEuaGFzQXR0cmlidXRlKHRoaXMuY2xhc3NOYW1lLCAncHJlc2VuY2UnKSkgewogICAgICAgICAgICAgICAgdGhpcy5wcmVzZW5jZSA9IHBKc29uTW9kZWwucHJlc2VuY2U7IC8vV2F0c29uIGJ1ZyAzNzg3MDAyIDogcHJlc2VuY2UgcHJvcGVydHkgY2hhbmdlZCBieSBzZXJ2ZXIgc2lkZSBzY3JpcAogICAgICAgICAgICB9CiAgICAgICAgICAgIEV2ZW50Q29udGFpbmVyTm9kZS5fc3VwZXIucGxheUpzb24uY2FsbCh0aGlzLCBwSnNvbk1vZGVsKTsKICAgICAgICB9LAoKICAgICAgICBzY29wZWxlc3MgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgLy8gVE9ETzogY2hlY2sgaXNBcmVhCiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibmFtZSIpLmxlbmd0aCA9PSAwOwogICAgICAgIH0sCgogICAgICAgIF9yZXNldERhdGEgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgZm9yICggdmFyIGkgPSAwOyBpIDwgdGhpcy5tb0NoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBvTm9kZSA9IHRoaXMubW9DaGlsZE5vZGVzW2ldOwogICAgICAgICAgICAgICAgb05vZGUuX3Jlc2V0RGF0YSgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbmFrZWRGaWVsZFJlZmVyZW5jZXMgOiBmdW5jdGlvbihuSW5kZXgsIGNyZWF0ZUdldHRlclNldHRlcixvYmopIHsKICAgICAgICAgICAgZm9yICggdmFyIGkgPSAwOyBpIDwgdGhpcy5tb05vcm1hbGl6ZWRDaGlsZHJlbi5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIG9Ob2RlID0gdGhpcy5tb05vcm1hbGl6ZWRDaGlsZHJlbltpXTsKICAgICAgICAgICAgICAgIGlmKHRoaXMuX3JlcXVpcmVHZXR0ZXJTZXR0ZXIob05vZGUpKQogICAgICAgICAgICAgICAgICAgIG9Ob2RlLmdldE5ha2VkKG5JbmRleCwgY3JlYXRlR2V0dGVyU2V0dGVyLCBvYmosdGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvLyByZXR1cm4gdGhlIHRyYXZlcnNhbCBvYmplY3QKICAgICAgICBnZXRUcmF2ZXJzYWxPYmplY3QgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMsICJqc29uTW9kZWwuY2hpbGRyZW4iLCBudWxsKSwKICAgICAgICAgICAgICAgIHRyYXZlcnNhbE9iaiA9IG51bGw7CiAgICAgICAgICAgIGlmKGNoaWxkcmVuKSB7CiAgICAgICAgICAgICAgICB0cmF2ZXJzYWxPYmogPSBfLmZpbmQoY2hpbGRyZW4sIGZ1bmN0aW9uKGNoaWxkKXsgcmV0dXJuIGNoaWxkLl9jbGFzcyA9PSAidHJhdmVyc2FsIjsgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNhbE9iajsKICAgICAgICB9LAoKICAgICAgICAvLyByZXR1cm4gTkVYVC9GSVJTVCB0cmF2ZXJzYWwgb2JqZWN0IGJhc2VkIG9uIHRoZSBvcGVyYXRpb24oZmlyc3QvbmV4dCkgcHJvdmlkZWQKICAgICAgICBnZXROZXh0VHJhdmVyc2FsU29tIDogZnVuY3Rpb24gKG9wZXJhdGlvbikgewogICAgICAgICAgICB2YXIgdHJhdmVyc2UgPSBudWxsLAogICAgICAgICAgICAgICAgdHJhdmVyc2FsUmVmID0gbnVsbCwKICAgICAgICAgICAgICAgIHRyYXZlcnNhbE9iaiA9IHRoaXMuZ2V0VHJhdmVyc2FsT2JqZWN0KCk7CiAgICAgICAgICAgIGlmICh0cmF2ZXJzYWxPYmogJiYgKHRyYXZlcnNlID0gdHJhdmVyc2FsT2JqLmNoaWxkcmVuKSkgewogICAgICAgICAgICAgICAgaWYgKG9wZXJhdGlvbiA9PSB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmZpcnN0VHJhdmVyc2FsKSB7CiAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsUmVmID0gXy5maW5kKHRyYXZlcnNlLCBmdW5jdGlvbihjaGlsZCl7IHJldHVybiBjaGlsZC5vcGVyYXRpb24gPT0geGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5maXJzdFRyYXZlcnNhbH0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gb25seSBmaXJzdCBhbmQgbmV4dCBhcmUgc3VwcG9ydGVkIGFuZCBpZiBubyBvcGVyYXRpb24gaXMgbWVudGlvbmVkIHRoZW4gaXQgaXMgdHJlYXRlZCBhcyBuZXh0CiAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsUmVmID0gXy5maW5kKHRyYXZlcnNlLCBmdW5jdGlvbihjaGlsZCl7IHJldHVybiBjaGlsZC5vcGVyYXRpb24gIT0geGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5maXJzdFRyYXZlcnNhbH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFRPIERPOiBhZGQgaGFuZGxpbmcgZm9yIHNjcmlwdCBpbiByZWZlcmVuY2UKICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNhbFJlZiAmJiB0aGlzLnJlc29sdmVOb2RlKHRyYXZlcnNhbFJlZi5yZWYpID8gdGhpcy5yZXNvbHZlTm9kZSh0cmF2ZXJzYWxSZWYucmVmKS5zb21FeHByZXNzaW9uIDogbnVsbDsKICAgICAgICB9CiAgICB9KTsKCiAgICBFdmVudENvbnRhaW5lck5vZGUuZGVmaW5lUHJvcHMoewogICAgICAgICJ2YWxpZGF0ZSIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgidmFsaWRhdGUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRFbGVtZW50KHZhbCwidmFsaWRhdGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJlcnJvclRleHQiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Vycm9yVGV4dCB8fCAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJ2YWxpZGF0aW9uTWVzc2FnZSIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgdmFyIG0gPSB0aGlzLmdldE9yRWxzZSh0aGlzLnZhbGlkYXRlLm1lc3NhZ2Uuc2NyaXB0VGVzdCwgdGhpcy5fZGVmYXVsdHMudmFsaWRhdGUubWVzc2FnZS5kZWZhdWx0TWVzc2FnZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbS52YWx1ZTsKICAgICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgIHZhciBub2RlcyA9IHRoaXMudmFsaWRhdGUubWVzc2FnZS5ub2RlczsKICAgICAgICAgICAgICAgIGlmKG5vZGVzLm5hbWVkSXRlbSgic2NyaXB0VGVzdCIpID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSB0aGlzLl94ZmEoKS5mb3JtLmNyZWF0ZU5vZGUoInRleHQiLCJzY3JpcHRUZXN0Iik7CiAgICAgICAgICAgICAgICAgICAgbm9kZXMuYXBwZW5kKG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy52YWxpZGF0ZS5tZXNzYWdlLnNjcmlwdFRlc3QudmFsdWUgPXZhbDsKICAgICAgICAgICAgICAgIHRoaXMuZXhlY1ZhbGlkYXRlKCkgOwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgICJhY2Nlc3MiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5hY2Nlc3MsIHRoaXMuX2RlZmF1bHRzLmFjY2Vzcyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZBY2Nlc3MpIHsKICAgICAgICAgICAgICAgIHZBY2Nlc3MgPSB0aGlzLnZhbGlkYXRlSW5wdXQodkFjY2VzcywgdGhpcy5fZ2V0RGF0YVR5cGUoImFjY2VzcyIpLCB0aGlzLmpzb25Nb2RlbC5hY2Nlc3MpOwogICAgICAgICAgICAgICAgaWYgKHRoaXMuanNvbk1vZGVsLmFjY2VzcyAhPSB2QWNjZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5qc29uTW9kZWwuYWNjZXNzID0gdkFjY2VzczsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWxjdWxhdGVFZmZlY3RpdmVBY2Nlc3MoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJyZWxldmFudCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyZWxldmFudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgIHZhbCA9IHRoaXMudmFsaWRhdGVJbnB1dCh2YWwsIHRoaXMuX2dldERhdGFUeXBlKCJyZWxldmFudCIpLCB0aGlzLmpzb25Nb2RlbC5yZWxldmFudCkgOwogICAgICAgICAgICAgICAgaWYgKHRoaXMuZ2V0QXR0cmlidXRlKCJyZWxldmFudCIpICE9IHZhbCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLnJlbGV2YW50ID0gdmFsOwogICAgICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsInJlbGV2YW50IixudWxsLHZhbCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJkZXNjIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJkZXNjIiwwKQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXyx4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5Db250ZW50CiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Ob2RlCQogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIENvbnRlbnQgTm9kZSBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgovL2dvb2cucHJvdmlkZSgnY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuQ29udGVudCcpOwovLwovL2dvb2cucmVxdWlyZSgnY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuTm9kZScpOwoKKGZ1bmN0aW9uKF8sIHhmYWxpYil7CiAgICB2YXIgQ29udGVudCA9IHhmYWxpYi5zY3JpcHQuQ29udGVudCA9IHhmYWxpYi5zY3JpcHQuTm9kZS5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiAiY29udGVudCIsCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gcmV0dXJucyB3aGV0aGVyIHRoZSBub2RlIGlzIGFuIGluc3RhbmNlIG9mIGEgY29udGVudCBOb2RlIG9yIG5vdAogICAgICAgICAqLwogICAgICAgIF9pc0NvbnRlbnQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYik7CgoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuTm9kZVZhbHVlCiAqIEBpbXBvcnQgeGZhbGliLnV0LkNsYXNzCiAqLwoKCihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgTm9kZVZhbHVlID0geGZhbGliLnNjcmlwdC5Ob2RlVmFsdWUgPSB4ZmFsaWIuc2NyaXB0LkNvbnRlbnQuZXh0ZW5kKHsKCiAgICAgICAgX2RlZmF1bHQ6ICJ2YWx1ZSIsCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBOb2RlVmFsdWUuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgdGhpcy5qc29uTW9kZWwuX3ZhbHVlID0gdGhpcy5qc29uTW9kZWwuX3ZhbHVlIHx8IG51bGw7CiAgICAgICAgICAgIHRoaXMuX2luaXRpYWxKc29uU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkodGhpcy5qc29uTW9kZWwpOwogICAgICAgICAgICB0aGlzLl9tb2RlbENoYW5nZWQgPSBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBOb2RlVmFsdWUuX3N1cGVyLl9pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmICh0aGlzLl9pc0ZpZWxkRGVzY2VuZGFudCgpKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tb2RlbENoYW5nZWQgPSB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogY29udmVydHMgYSB2YWx1ZSBpbnRvIHRoZSBkZXNpZ25hdGVkIHR5cGUuIG51bGwgaXMgYSB2YWxpZCB2YWx1ZQogICAgICAgICAqIGZvciBhbGwgdHlwZXMuIEZvciBpbnZhbGlkIHZhbHVlIGl0IHJldHVybnMgdW5kZWZpbmVkCiAgICAgICAgICovCiAgICAgICAgdHlwZWRWYWx1ZTogZnVuY3Rpb24gKHZhbCwgY29udGVudFR5cGUpIHsKICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICJ1bmRlZmluZWQiKQogICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICAgICAgaWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09ICIiKQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIHJldHVybiB2YWw7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiByZXR1cm5zIHRoZSB0eXBlZCB2YWx1ZS4gc2luY2Ugd2UgbmV2ZXIgc3RvcmUgdW5kZWZpbmVkIHZhbHVlcwogICAgICAgICAqIGl0IGFsd2F5cyByZXR1cm5zIHZhbGlkIHZhbHVlCiAgICAgICAgICovCiAgICAgICAgZ2V0VmFsdWU6IGZ1bmN0aW9uIChjb250ZW50VHlwZSwgc2tpcFR5cGVDaGVjaykgewogICAgICAgICAgICBpZihza2lwVHlwZUNoZWNrID09PSB0cnVlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwuX3ZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzLnR5cGVkVmFsdWUodGhpcy5qc29uTW9kZWwuX3ZhbHVlLCBjb250ZW50VHlwZSk7CiAgICAgICAgfSwKCiAgICAgICAgX3N0b3JlVmFsdWU6IGZ1bmN0aW9uICh2YWwsIHR5cGVWYWwpIHsKICAgICAgICAgICAgdGhpcy5qc29uTW9kZWwuX3ZhbHVlID0gdmFsOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogY29udmVydHMgdmFsIHRvIGl0cyB0eXBlZCB2ZXJzaW9uIGFuZCBpZiB2YWwgaXMgdmFsaWQgc3RvcmVzCiAgICAgICAgICogaXQuCiAgICAgICAgICogcmV0dXJucyB3aGV0aGVyIHRoZSBuZXcgdmFsdWUgaXMgZGlmZmVyZW50IGZyb20gdGhlIG9sZCBvbmUuCiAgICAgICAgICovCiAgICAgICAgc2V0VmFsdWU6IGZ1bmN0aW9uICh2YWwsIHNraXBUeXBlQ2hlY2spIHsKICAgICAgICAgICAgdmFyIG9sZFZhbCA9IHRoaXMuanNvbk1vZGVsLl92YWx1ZSwKICAgICAgICAgICAgICAgIHR5cGVWYWwgPSB0aGlzLnR5cGVkVmFsdWUodmFsKSwKICAgICAgICAgICAgICAgIHJldFZhbCA9IGZhbHNlOwoKICAgICAgICAgICAgaWYgKHNraXBUeXBlQ2hlY2sgPT09IHRydWUgfHwgdHlwZW9mIHR5cGVWYWwgIT09ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9zdG9yZVZhbHVlKHZhbCwgdHlwZVZhbCk7CiAgICAgICAgICAgICAgICByZXRWYWwgPSB0aGlzLnR5cGVkVmFsdWUob2xkVmFsKSAhPT0gdHlwZVZhbDsKICAgICAgICAgICAgICAgIHRoaXMuX21vZGVsQ2hhbmdlZCA9IHRydWU7ICAvLyBMQy01NDY1IDogYWxsIGZpZWxkJ3Mgd2hvc2UgdmFsdWUgaXMgc2V0IGlzIHRvIGJlIHJlZmxlY3RlZCBpbiBqc29uRGlmZgogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgICAgfSwKCiAgICAgICAgZXF1YWxzOiBmdW5jdGlvbiAob1ZhbCkgewogICAgICAgICAgICByZXR1cm4gKHRoaXMuZ2V0VmFsdWUoKSA9PT0gb1ZhbC5nZXRWYWx1ZSgpKTsKICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUpzb25EaWZmOiBmdW5jdGlvbiAoZGlmZl9sZXZlbCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTaW5jZSB3ZSBkbyBub3QgbWFpbnRhaW4gaW5pdGlhbEpzb24gb3IgdGVtcGxhdGVKc29uIGZvciBET00gZWxlbWVudHMsIHdlIHVzZSB0aGlzIGFwcHJveGltYXRlIG1ldGhvZCB0byBjb21wdXRlIGpzb25EaWZmLgogICAgICAgICAgICAgKiBTaW5jZSB2YWx1ZSBBUEkgaXMgbm90IGFzIHNpbXBsZSBhcyBvdGhlciBET00gYXBpLCB3ZSBzaW1wbHkgY29tcGFyZSBvbGQgYW5kIG5ldyBqc29uIHN0cmluZyB0byBjaGVjayBpZiBhbnl0aGluZyBoYXMgY2hhbmdlZAogICAgICAgICAgICAgKiBzZWVBbHNvOiBET01FbGVtZW50IGFuZCBHZW5lcmljVGV4dAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdmFyIGpzb25TdHIgPSBKU09OLnN0cmluZ2lmeSh0aGlzLmpzb25Nb2RlbCk7CiAgICAgICAgICAgIHZhciBjaGFuZ2VkID0gKHRoaXMuX2luaXRpYWxKc29uU3RyaW5nICE9IGpzb25TdHIpOwogICAgICAgICAgICBpZiAodGhpcy5uYW1lID09PSAiRlNfREFUQV9TT00iICYmIGRpZmZfbGV2ZWwgPT09IDMpIHsKICAgICAgICAgICAgICAgIGNoYW5nZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgdGhpcy5fbW9kZWxDaGFuZ2VkID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIganNvbkRpZmYgPSBjaGFuZ2VkID8gdGhpcy5qc29uTW9kZWwgOiB7X2NsYXNzOiB0aGlzLmNsYXNzTmFtZSwgbmFtZTogdGhpcy5qc29uTW9kZWwubmFtZX07CiAgICAgICAgICAgIGlmICghY2hhbmdlZCAmJiB0aGlzLl9tb2RlbENoYW5nZWQpCiAgICAgICAgICAgICAgICBqc29uRGlmZi5fdmFsdWUgPSB0aGlzLmpzb25Nb2RlbC5fdmFsdWU7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAiY2hhbmdlZCI6IHRoaXMuX21vZGVsQ2hhbmdlZCwKICAgICAgICAgICAgICAgIGpzb25EaWZmZXJlbmNlOiBqc29uRGlmZgogICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIF9pc0ZpZWxkRGVzY2VuZGFudDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgZ3JhbmRQYXJlbnQgPSB0aGlzLmdldE9yRWxzZSh0aGlzLCAicGFyZW50LnBhcmVudCIsIG51bGwpOwogICAgICAgICAgICBpZiAoZ3JhbmRQYXJlbnQgJiYgZ3JhbmRQYXJlbnQuY2xhc3NOYW1lID09ICJmaWVsZCIpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIHBsYXlKc29uOiBmdW5jdGlvbiAocEpzb25Nb2RlbCkgewogICAgICAgICAgICBpZiAocEpzb25Nb2RlbC5fdmFsdWUgIT0gdGhpcy5qc29uTW9kZWwuX3ZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tb2RlbENoYW5nZWQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIE5vZGVWYWx1ZS5fc3VwZXIucGxheUpzb24uYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgaWYgKHR5cGVvZiBwSnNvbk1vZGVsLl92YWx1ZSA9PSAidW5kZWZpbmVkIikKICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLl92YWx1ZSA9IG51bGw7CiAgICAgICAgfQogICAgfSk7CgogICAgTm9kZVZhbHVlLmRlZmluZVByb3BzKHsKICAgICAgICAicHJlc2VuY2UiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgeyAvL2kgYW0gbm90IHN1cmUgaG93IHRvIG1ha2UgdGhpcyBwcm9wZXJ0eSB1bmRlZmluZWQgc28ganVzdCByZW1vdmVkIHNldHRlcnMKICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAidmFsdWUiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWUoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHNWYWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRWYWx1ZShzVmFsdWUpOwogICAgICAgICAgICAgICAgdmFyIGV2ZW50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwgdGhpcywgdGhpcy5jbGFzc05hbWUsIG51bGwsIHRoaXMudmFsdWUpOwogICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2ZW50Lm5hbWUsIGV2ZW50KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5JbWFnZVZhbHVlCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Ob2RlVmFsdWUKICovCgooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEltYWdlVmFsdWUgPSB4ZmFsaWIuc2NyaXB0LkltYWdlVmFsdWUgPSB4ZmFsaWIuc2NyaXB0Lk5vZGVWYWx1ZS5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiAiaW1hZ2UiCiAgICB9KTsKICAgIEltYWdlVmFsdWUuZGVmaW5lUHJvcHMoewogICAgICAgICJocmVmIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiaHJlZiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cn0oXywgeGZhbGliKSk7LyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuVGV4dFZhbHVlCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Ob2RlVmFsdWUKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBUZXh0VmFsdWUgPSB4ZmFsaWIuc2NyaXB0LlRleHRWYWx1ZSA9IHhmYWxpYi5zY3JpcHQuTm9kZVZhbHVlLmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJ0ZXh0IiwKICAgICAgICB0eXBlZFZhbHVlIDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIHZhciB0VmFsdWUgPSBUZXh0VmFsdWUuX3N1cGVyLnR5cGVkVmFsdWUuY2FsbCh0aGlzLCB2YWwpOwogICAgICAgICAgICBpZiAodFZhbHVlICE9IG51bGwpCiAgICAgICAgICAgICAgICB0VmFsdWUgPSB0VmFsdWUudG9TdHJpbmcoKTsKICAgICAgICAgICAgcmV0dXJuIHRWYWx1ZTsKICAgICAgICB9CgogICAgfSk7CgogICAgVGV4dFZhbHVlLmRlZmluZVByb3BzKHsKICAgICAgICAibWF4Q2hhcnMiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5tYXhDaGFycywgIjAiKSA7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZih2YWx1ZSA8IDAgJiYgdmFsdWUgPT0gcGFyc2VJbnQodmFsdWUpKQogICAgICAgICAgICAgICAgICAgIHZhbHVlID0gIjAiOwogICAgICAgICAgICAgICAgaWYodmFsdWUgPj0gMCAmJiB2YWx1ZSA9PSBwYXJzZUludCh2YWx1ZSkpICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLm1heENoYXJzID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAodmFsdWUgPT0gIjAiKT8iMjU1Ijp2YWx1ZTsKICAgICAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQsCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsIm1heENoYXJzIix2YWx1ZSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pCn0pKF8sIHhmYWxpYik7CgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5FeERhdGFWYWx1ZQogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuTm9kZVZhbHVlCiAqLwoKKGZ1bmN0aW9uKF8sIHhmYWxpYiwgJCl7CgogICAgdmFyIEV4RGF0YVZhbHVlID0geGZhbGliLnNjcmlwdC5FeERhdGFWYWx1ZSA9IHhmYWxpYi5zY3JpcHQuTm9kZVZhbHVlLmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJleERhdGEiLAogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICBFeERhdGFWYWx1ZS5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLl90cmFuc2Zvcm1Ub1hGQUNvbXBsaWFudE1vZGVsKCk7CiAgICAgICAgICAgIHRoaXMuXyRpbnRlcm5hbFhNTERvYyA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuX29yaWdUbXBsdFZhbCA9IG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgX3RyYW5zZm9ybVRvWEZBQ29tcGxpYW50TW9kZWw6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMuY2xhc3NOYW1lID09PSAiZXhEYXRhIiAmJiB0aGlzLmpzb25Nb2RlbC5fdmFsdWUgIT09IG51bGwgJiYgdGhpcy5qc29uTW9kZWwuX3ZhbHVlLmluZGV4T2YoIjxib2R5IHhtbG5zPSIpID09PSAtMSAmJiB0aGlzLmpzb25Nb2RlbC5fdmFsdWUuaW5kZXhPZigiPGJvZHkiKSAhPT0gLTEpewogICAgICAgICAgICAgICAgdmFyIG9wZW5pbmdCb2R5VGFnSW5kZXggPSB0aGlzLmpzb25Nb2RlbC5fdmFsdWUuaW5kZXhPZignPCcpOwogICAgICAgICAgICAgICAgdmFyIGVuZGluZ0JvZHlUYWdJbmRleCA9IHRoaXMuanNvbk1vZGVsLl92YWx1ZS5pbmRleE9mKCc+Jyk7CiAgICAgICAgICAgICAgICB2YXIgYm9keVRhZ1N0cmluZyA9IHRoaXMuanNvbk1vZGVsLl92YWx1ZS5zdWJzdHJpbmcob3BlbmluZ0JvZHlUYWdJbmRleCwgZW5kaW5nQm9keVRhZ0luZGV4KzEpOwogICAgICAgICAgICAgICAgdGhpcy5qc29uTW9kZWwuX3ZhbHVlID0gdGhpcy5qc29uTW9kZWwuX3ZhbHVlLnJlcGxhY2UoYm9keVRhZ1N0cmluZywgJzxib2R5IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiB4bWxuczp4ZmE9Imh0dHA6Ly93d3cueGZhLm9yZy9zY2hlbWEveGZhLWRhdGEvMS4wLyIgeGZhOkFQSVZlcnNpb249IjIuNy4wLjAiPicpOwogICAgICAgICAgICAgICAgLy8gdGhpcy5qc29uTW9kZWwuX3ZhbHVlID0gJzxib2R5IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiB4bWxuczp4ZmE9Imh0dHA6Ly93d3cueGZhLm9yZy9zY2hlbWEveGZhLWRhdGEvMS4wLyIgeGZhOkFQSVZlcnNpb249IjIuNy4wLjAiPicgKyB0aGlzLmpzb25Nb2RlbC5fdmFsdWUgKyAnPC9ib2R5Pic7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUpzb25EaWZmOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgLy8gcmljaHRleHQgZmllbGQgdmFsdWUgc2hvdWxkIG5vdCBiZSBlbXB0eSBzdHJpbmcuCiAgICAgICAgICAgIGlmKHRoaXMuanNvbk1vZGVsLl9jbGFzcyA9PT0gImV4RGF0YSIgJiYgIXRoaXMuanNvbk1vZGVsLl92YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC5fdmFsdWUgPSBKU09OLnBhcnNlKHRoaXMuX2luaXRpYWxKc29uU3RyaW5nKS5fdmFsdWU7CiAgICAgICAgICAgICAgICB0aGlzLl90cmFuc2Zvcm1Ub1hGQUNvbXBsaWFudE1vZGVsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHsiY2hhbmdlZCIgOiB0cnVlLAogICAgICAgICAgICAgICAganNvbkRpZmZlcmVuY2UgOiB0aGlzLmpzb25Nb2RlbAogICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIHR5cGVkVmFsdWU6IGZ1bmN0aW9uKHZhbCwgY29udGVudFR5cGUpIHsKICAgICAgICAgICAgLy9pZiBjb250ZW50VHlwZSBpcyBub3QgcGFzc2VkIC0+IGRlcml2ZSBpdCBmcm9tIGNvbnRlbnRUeXBlIGF0dHJpYnV0ZQogICAgICAgICAgICBpZighY29udGVudFR5cGUpCiAgICAgICAgICAgICAgICBjb250ZW50VHlwZSA9IHRoaXMuZ2V0QXR0cmlidXRlKCJjb250ZW50VHlwZSIpOwogICAgICAgICAgICBzd2l0Y2goY29udGVudFR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgInRleHQvcGxhaW4iOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBFeERhdGFWYWx1ZS5fc3VwZXIudHlwZWRWYWx1ZS5hcHBseSh0aGlzLFt2YWxdKTsKICAgICAgICAgICAgICAgIGNhc2UgInRleHQveG1sIjoKICAgICAgICAgICAgICAgICAgICBpZih2YWwgPT0gbnVsbCB8fCB2YWwubGVuZ3RoID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl8kaW50ZXJuYWxYTUxEb2MgPSAkLnBhcnNlWE1MKHZhbCk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLkxvZ2dlci5lcnJvcigiSW52YWxpZCBYTUwgZm9yIHRoZSBmaWVsZCIpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvL0lFIDkgc3VwcG9ydHMgWE1MU2VyaWFsaXplcgogICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxTZXJpYWxpemVyID8gKG5ldyBYTUxTZXJpYWxpemVyKCkpLnNlcmlhbGl6ZVRvU3RyaW5nKHRoaXMuXyRpbnRlcm5hbFhNTERvYyk6IHZhbAogICAgICAgICAgICAgICAgY2FzZSAidGV4dC9odG1sIjoKICAgICAgICAgICAgICAgICAgICBpZighKHZhbCAmJiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuaXNIVE1MKHZhbCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuXyRpbnRlcm5hbEhUTUwgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl8kaW50ZXJuYWxIVE1MID0gJCgiPGJvZHk+PHA+PC9wPjwvYm9keT4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl8kaW50ZXJuYWxIVE1MLmh0bWwoeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmVuY29kZVNjcmlwdGFibGVUYWdzKHZhbCkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciAkdmFsID0gJCh2YWwpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl8kaW50ZXJuYWxIVE1MID0gJHZhbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuXyRpbnRlcm5hbEhUTUwudGV4dCgpOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXhEYXRhVmFsdWUuX3N1cGVyLnR5cGVkVmFsdWUuYXBwbHkodGhpcyxbdmFsXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBzYXZlWE1MOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHByZWZpeCA9ICc8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PicgKwogICAgICAgICAgICAgICAgICAgICAgICAgJzxleERhdGEgY29udGVudFR5cGU9InRleHQvaHRtbCIgeG1sbnM9Imh0dHA6Ly93d3cueGZhLm9yZy9zY2hlbWEveGZhLXRlbXBsYXRlLzMuNi8iPicgKwogICAgICAgICAgICAgICAgICAgICAgICAgJzxib2R5IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiB4bWxuczp4ZmE9Imh0dHA6Ly93d3cueGZhLm9yZy9zY2hlbWEveGZhLWRhdGEvMS4wLyI+JywKICAgICAgICAgICAgICAgIHN1ZmZpeCA9ICc8L2JvZHk+PC9leERhdGE+JywKICAgICAgICAgICAgICAgIHN0clhNTCA9IHRoaXMuanNvblZhbHVlOwoKICAgICAgICAgICAgICAgIC8vIFRPRE8gOiB1c2UgalF1ZXJ5IG9yIFhNTHBhcnNlciB0byBkbyB0aGlzIG1vcmUgcmVsaWFibHkKICAgICAgICAgICAgICAgIGlmKHN0clhNTC5pbmRleE9mKCI8Ym9keSIpID49MCkKICAgICAgICAgICAgICAgICAgICBzdHJYTUwgPSBzdHJYTUwuc2xpY2Uoc3RyWE1MLmluZGV4T2YoIj4iLCBzdHJYTUwuaW5kZXhPZigiPGJvZHkiKSkrMSk7CiAgICAgICAgICAgICAgICBpZihzdHJYTUwubGFzdEluZGV4T2YoIjwvYm9keT4iKSA+PTApCiAgICAgICAgICAgICAgICAgICAgc3RyWE1MID0gc3RyWE1MLnNsaWNlKDAsc3RyWE1MLmxhc3RJbmRleE9mKCI8L2JvZHk+IikpOwoKICAgICAgICAgICByZXR1cm4gcHJlZml4ICsgc3RyWE1MICsgc3VmZml4IDsKICAgICAgICB9LAoKICAgICAgICBsb2FkWE1MOiBmdW5jdGlvbihzdHJYTUwpIHsKICAgICAgICAvL1RPRE8gOiBhZGQgc3VwcG9ydCBmb3Igb3RoZXIgcGFyYW1zIHRvIGxvYWRYTUwsIGFzIG9mIG5vdyBhbGwgY2FsbHMgYXJlIGVxdWl2YWxlbnQgdG8gbG9hZFhNTCh4LHRydWUsdHJ1ZSkKICAgICAgICAgICAgdmFyIGRpc3BWYWx1ZTsKICAgICAgICAgICAgaWYoc3RyWE1MLmluZGV4T2YoIjxib2R5IikgIT0gLTEgJiYgc3RyWE1MLmxhc3RJbmRleE9mKCI8L2JvZHk+IikgIT0gLTEpIHsgLy8gYXNzdW1pbmcgYSB3ZWxsIGZvcm1lZCB2YWxpZCBYTUwgc3RyaW5nCiAgICAgICAgICAgICAgICBkaXNwVmFsdWUgPSBzdHJYTUwuc2xpY2Uoc3RyWE1MLmluZGV4T2YoIj4iLCBzdHJYTUwuaW5kZXhPZigiPGJvZHkiKSkrMSxzdHJYTUwubGFzdEluZGV4T2YoIjwvYm9keT4iKSk7IC8vIGdldCBjb250ZW50cyB3aXRoaW4gPGJvZHk+IHRhZ3MKICAgICAgICAgICAgfQogICAgICAgICAgICBpZih0aGlzLmdldEF0dHJpYnV0ZSgiY29udGVudFR5cGUiKSA9PSAndGV4dC9odG1sJykgewogICAgICAgICAgICAgICAgaWYoZGlzcFZhbHVlLmluZGV4T2YoJzxzcGFuPicpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBkaXNwVmFsdWUgPSAnPHNwYW4+JyArIGRpc3BWYWx1ZSArICc8L3NwYW4+JzsgIC8vIGluIGNhc2Ugb2YgbXVsdGlwbGUgaHRtbCBlbGVtZW50cywgd3JhcCBpbiBhIHNwYW4sIGVsc2UgdGhleSBvdmVybGFwICEhCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyICRpbnRlcm5hbEhUTUwgPSAkKCc8c3Bhbj4nKyBkaXNwVmFsdWUgKyc8L3NwYW4+Jyk7CiAgICAgICAgICAgICAgICAkaW50ZXJuYWxIVE1MLmZpbmQoInAiKS5lcSgwKS5jc3MoJ2Rpc3BsYXknLCdpbmxpbmUnKTsKICAgICAgICAgICAgICAgIGRpc3BWYWx1ZSA9ICRpbnRlcm5hbEhUTUwuaHRtbCgpOyAgIC8vIGdldCB0aGUgaW5uZXIgaHRtbCB3aXRoIGFsbCBtYXJrdXBzCgogICAgICAgICAgICAgICAgdGhpcy5qc29uVmFsdWUgPSBkaXNwVmFsdWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBkaXNwVmFsdWUgPSAnPGJvZHk+JyArIGRpc3BWYWx1ZSArICc8L2JvZHk+JzsKICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSBkaXNwVmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgIH0pOwoKICAgIEV4RGF0YVZhbHVlLmRlZmluZVByb3BzKHsKICAgICAgICAianNvblZhbHVlIjogeyAgLy8gc2hvdWxkIHVzZSBpdCB0byBjaXJjdW12ZW50ICd0eXBlZFZhbHVlJywgd2hpY2ggc3RyaXBzIGh0bWwgdGFncwogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmpzb25Nb2RlbC5fdmFsdWU7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChzVmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmKF8uaXNOdWxsKHRoaXMuX29yaWdUbXBsdFZhbCkpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9vcmlnVG1wbHRWYWwgPSB0aGlzLmpzb25Nb2RlbC5fdmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLl9tb2RlbENoYW5nZWQgPSB0cnVlOyAgLy8ganVzdCB0byBiZSBjb25zaXN0ZW50ICYgc2FmZSB3aXRoICd2YWx1ZScKCiAgICAgICAgICAgICAgICBpZihzVmFsdWUgIT09IHRoaXMuanNvbk1vZGVsLl92YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLl92YWx1ZSA9IHNWYWx1ZTsKICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkRPTV9DSEFOR0VELCB0aGlzLCB0aGlzLmNsYXNzTmFtZSwgbnVsbCwgc1ZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZlbnQubmFtZSwgZXZlbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYiwgJCk7CgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5JbnRlZ2VyVmFsdWUKICogQGltcG9ydCAgeGZhbGliLnNjcmlwdC5Ob2RlVmFsdWUKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBJbnRlZ2VyVmFsdWUgPSB4ZmFsaWIuc2NyaXB0LkludGVnZXJWYWx1ZSA9IHhmYWxpYi5zY3JpcHQuTm9kZVZhbHVlLmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJpbnRlZ2VyIiwKICAgICAgICB0eXBlZFZhbHVlIDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIHZhciB0VmFsdWUgPSBJbnRlZ2VyVmFsdWUuX3N1cGVyLnR5cGVkVmFsdWUuY2FsbCh0aGlzLCB2YWwpOwogICAgICAgICAgICBpZiAodFZhbHVlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHRWYWx1ZSA9IHBhcnNlSW50KHRWYWx1ZSk7CiAgICAgICAgICAgICAgICBpZiAoaXNOYU4odFZhbHVlKSkKICAgICAgICAgICAgICAgICAgIHRWYWx1ZSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdFZhbHVlOwogICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5EZWNpbWFsVmFsdWUKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk5vZGVWYWx1ZQogKi8KCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIERlY2ltYWxWYWx1ZSA9IHhmYWxpYi5zY3JpcHQuRGVjaW1hbFZhbHVlID0geGZhbGliLnNjcmlwdC5Ob2RlVmFsdWUuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZTogImRlY2ltYWwiLAoKICAgICAgICB0eXBlZFZhbHVlIDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIHZhciB0VmFsdWUgPSBEZWNpbWFsVmFsdWUuX3N1cGVyLnR5cGVkVmFsdWUuY2FsbCh0aGlzLCB2YWwpOwogICAgICAgICAgICBpZiAodFZhbHVlKSB7CiAgICAgICAgICAgICAgICB0VmFsdWUgPSBwYXJzZUZsb2F0KHRWYWx1ZSk7CiAgICAgICAgICAgICAgICBpZiAoaXNOYU4odFZhbHVlKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgdmFyIHN0ciA9IHRWYWx1ZSArICcnOwogICAgICAgICAgICAgICAgdmFyIGxlbiA9IHN0ci5sZW5ndGg7CiAgICAgICAgICAgICAgICB2YXIgbGVhZEQgPSBzdHIuaW5kZXhPZigiLiIpOwogICAgICAgICAgICAgICAgdmFyIGZyYWNEID0gbGVuIC0gbGVhZEQgLSAxOwogICAgICAgICAgICAgICAgaWYoZnJhY0QgPiB0aGlzLmZyYWNEaWdpdHMgJiYgdGhpcy5mcmFjRGlnaXRzICE9IC0xKQogICAgICAgICAgICAgICAgICAgIHRWYWx1ZSA9IHBhcnNlRmxvYXQodFZhbHVlLnRvRml4ZWQodGhpcy5mcmFjRGlnaXRzKSk7CiAgICAgICAgICAgICAgICBpZihsZWFkRCA+IHRoaXMubGVhZERpZ2l0cyAmJiB0aGlzLmxlYWREaWdpdHMgIT0gLTEpCiAgICAgICAgICAgICAgICAgICAgdFZhbHVlID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdFZhbHVlOwogICAgICAgIH0KICAgIH0pOwoKICAgIERlY2ltYWxWYWx1ZS5kZWZpbmVQcm9wcyh7CiAgICAgICAgImZyYWNEaWdpdHMiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJmcmFjRGlnaXRzIikKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJsZWFkRGlnaXRzIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGVhZERpZ2l0cyIpCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKfSkoXywgeGZhbGliKTsKCgovKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LkZsb2F0VmFsdWUKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk5vZGVWYWx1ZQogKi8KICAKCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIEZsb2F0VmFsdWUgPSB4ZmFsaWIuc2NyaXB0LkZsb2F0VmFsdWUgPSB4ZmFsaWIuc2NyaXB0Lk5vZGVWYWx1ZS5leHRlbmQoewoKICAgICAgICBtc0NsYXNzTmFtZTogImZsb2F0IiwKICAgICAgICB0eXBlZFZhbHVlIDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIHZhciB0VmFsdWUgPSBGbG9hdFZhbHVlLl9zdXBlci50eXBlZFZhbHVlLmNhbGwodGhpcywgdmFsKTsKICAgICAgICAgICAgaWYgKHRWYWx1ZSkgewogICAgICAgICAgICAgICAgdFZhbHVlID0gcGFyc2VGbG9hdCh0VmFsdWUpOwogICAgICAgICAgICAgICAgaWYgKGlzTmFOKHRWYWx1ZSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0VmFsdWU7CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYik7LyoKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5EYXRlVmFsdWUKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk5vZGVWYWx1ZQogKi8KCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBEYXRlVmFsdWUgPSB4ZmFsaWIuc2NyaXB0LkRhdGVWYWx1ZSA9IHhmYWxpYi5zY3JpcHQuTm9kZVZhbHVlLmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJkYXRlIiwKICAgICAgICB0eXBlZFZhbHVlIDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIHZhciB0VmFsdWUgPSBEYXRlVmFsdWUuX3N1cGVyLnR5cGVkVmFsdWUuY2FsbCh0aGlzLCB2YWwpOwogICAgICAgICAgICBpZiAodFZhbHVlKSB7CiAgICAgICAgICAgICAgICB2YXIgdFZhbHVlUGFyc2VkID0geGZhbGliLnV0LkRhdGVJbmZvLlBhcnNlKHRWYWx1ZSwgdW5kZWZpbmVkLCBmYWxzZSk7CiAgICAgICAgICAgICAgICBpZiAodFZhbHVlUGFyc2VkICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdFZhbHVlUGFyc2VkID0gdFZhbHVlUGFyc2VkLmdldElTT0RhdGUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIGlmIHZhbHVlIGlzIG5vdCBjb3JyZWN0bHkgcGFyc2VkIHRoZW4gcmV0dXJuIHRoZSBvcmlnaW5hbCB2YWx1ZQogICAgICAgICAgICAgICAgcmV0dXJuIHRWYWx1ZVBhcnNlZCA/IHRWYWx1ZVBhcnNlZCA6IHRWYWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdFZhbHVlOwogICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIpOy8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LkZvcm0KICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LkNvbnRhaW5lck5vZGUKICovCgooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgLyoqCiAgICAgKiBAY2xhc3MKICAgICAqIDxwPgogICAgICogVGhlIEZvcm0gY2xhc3MgaXMgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSB0b3AgbGV2ZWwgWEZBIGZvcm0gb2JqZWN0LgogICAgICogPC9wPgogICAgICoKICAgICAqIDxwPgogICAgICogVGhlIGZvcm0gb2JqZWN0IGlzIGFjY2Vzc2VkIGZyb20gdGhlIHhmYSBvYmplY3QgYXMgeGZhLmZvcm0KICAgICAqIDwvcD4KICAgICAqCiAgICAgKi8KICAgIHZhciBEYXRhTm9kZSA9IHhmYWxpYi5zY3JpcHQuRGF0YU5vZGUgPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLnZhbHVlID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5maWVsZHMgPSBbXTsKICAgICAgICB9LAoKICAgICAgICBnZXRJZCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuanNvbk1vZGVsLmlkOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIHdpbGwgc3luYyBmaWVsZHMgaGF2aW5nIHNhbWUgZGF0YUlkIChzYW1lIGJpbmRyZWYgb3IgdXNlIGdsb2JhbCkKICAgICAgICAgKiBAcGFyYW0gbW9kZWwKICAgICAgICAgKi8KICAgICAgICBhZGRGaWVsZCA6IGZ1bmN0aW9uIChtb2RlbCkgewogICAgICAgICAgICBpZiAodGhpcy5maWVsZHMubGVuZ3RoID09PSAwICYmIG1vZGVsLnJhd1ZhbHVlICE9IG51bGwpIHsgLy8gbG9vc2UgY2hlY2sgZm9yIG51bGwvdW5kZWYKICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLnZhbHVlID0gbW9kZWwucmF3VmFsdWU7IC8vIGluaXRpYWxpemUgZGF0YU5vZGUgZ3JvdXAncyB2YWx1ZSB0byAxc3QgaGllcmFyY2hpY2FsbHkgcmVhY2hlZCBmaWVsZAogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbW9kZWwucmF3VmFsdWUgPSB0aGlzLmpzb25Nb2RlbC52YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLmZpZWxkcy5wdXNoKG1vZGVsKTsKICAgICAgICAgICAgbW9kZWwub24oeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwgdGhpcyk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRXZlbnQgOiBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICBzd2l0Y2ggKGV2bnQubmFtZSkgewogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VEOgogICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlTW9kZWxDaGFuZ2VkKGV2bnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmRlYnVnKCJ4ZmEiLCAnVW5leHBlY3RlZCAgRXZlbnQgICJ7MH0iIHRocm93biBpbiBkYXRhTm9kZSB3aXRoIGlkIDogInsxfSIgJywgW2V2bnQubmFtZSwgdGhpcy5qc29uTW9kZWwuaWRdKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGhhbmRsZU1vZGVsQ2hhbmdlZCA6IGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICBpZiAoZXZlbnQuX3Byb3BlcnR5ID09PSAicmF3VmFsdWUiKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVWYWx1ZUNoYW5nZShldmVudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlVmFsdWVDaGFuZ2UgOiBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgdGhpcy5fdXBkYXRlTGlua2VkRmllbGRzVmFsdWUoZXZlbnQucHJldlRleHQsIGV2ZW50LnRhcmdldCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogd2lsbCB1cGRhdGUgYWxsIGxpbmtlZCBmaWVsZHMgdG8gdGhlIG5ldyB2YWx1ZSBwYXNzZWQgaW4KICAgICAgICAgKiBAcGFyYW0gbmV3VmFsdWUKICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0CiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAbWVtYmVyb2YgRGF0YU5vZGUKICAgICAgICAgKi8KICAgICAgICBfdXBkYXRlTGlua2VkRmllbGRzVmFsdWUgOiBmdW5jdGlvbiAobmV3VmFsdWUsIHRhcmdldCkgewogICAgICAgICAgICBpZiAobmV3VmFsdWUgIT09IHVuZGVmaW5lZCAmJiBuZXdWYWx1ZSAhPSB0aGlzLmpzb25Nb2RlbC52YWx1ZSkgeyAvLyBsb29zZSB0eXBlIGNvZXJjaW9uIGhlcmUgZm9yIGludC9zdHIKICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLnZhbHVlID0gbmV3VmFsdWU7CgogICAgICAgICAgICAgICAgXy5lYWNoKHRoaXMuZmllbGRzLCBmdW5jdGlvbiAoZmllbGQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZmllbGQgIT09IHRhcmdldCkgewogICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC5vZmYoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwgdGhpcyk7IC8vIHJlbW92ZSBsaXN0ZW5lcnMgdG8gcHJldmVudCBldmVudCB0aHJvdyBzdG9ybQogICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC5yYXdWYWx1ZSA9IG5ld1ZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELCB0aGlzKTsgLy8gcmUgYXR0YWNoIGxpc3RlbmVycwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYik7Ci8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LkV4ZWN1dGFibGVTY3JpcHQKICogQGltcG9ydCB4ZmFsaWIudXQuQ2xhc3MKICovCgoKKGZ1bmN0aW9uKF8sIHhmYWxpYil7CiAgICB2YXIgRXhlY3V0YWJsZVNjcmlwdCA9IHhmYWxpYi5zY3JpcHQuRXhlY3V0YWJsZVNjcmlwdCA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewogICAgICAgIF9kZWZhdWx0cyA6IHsKICAgICAgICAgICAgInJ1bkF0IiA6ICJjbGllbnQiCiAgICAgICAgfSwKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIEV4ZWN1dGFibGVTY3JpcHQuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgdGhpcy5fc2NyaXB0Rm4gPSBudWxsOwogICAgICAgIH0sCgogICAgICAgIGV4ZWN1dGUgOiBmdW5jdGlvbihjb250ZXh0T2JqLCBldmVudE5hbWUpIHsKICAgICAgICAgICAgLy8gQWNjb3JkaW5nIHRvIFhGQSBTUEVDIDogSWYgdGhlIHByZXN1Ym1pdCBzY3JpcHQgaXMgbWFya2VkIHRvIGJlIHJ1biBvbmx5IGF0IHRoZSBzZXJ2ZXIsIHRoZSBkYXRhIGlzIHNlbnQgdG8gdGhlIHNlcnZlciB3aXRoIGFuCiAgICAgICAgICAgIC8vIGluZGljYXRpb24gdGhhdCBpdCBzaG91bGQgcnVuIHRoZSBhc3NvY2lhdGVkIHNjcmlwdCBiZWZvcmUgcGVyZm9ybWluZyB0aGUgcmVzdCBvZiB0aGUgcHJvY2Vzc2luZy4gQ2xpZW50IHNpZGUgc2NyaXB0IGZvciBwcmVzdWJtaXQKICAgICAgICAgICAgLy8gYXJlIGV4ZWN1dGVkIGJlZm9yZSBydW5uaW5nIHZhbGlkYXRpb24uCiAgICAgICAgICAgIGlmKHRoaXMucnVuQXQgPT0gInNlcnZlciIgJiYgZXZlbnROYW1lICE9ICIkZm9ybXByZVN1Ym1pdCIpIHsKICAgICAgICAgICAgICAgIHZhciBvcHRpb25zID0ge307CiAgICAgICAgICAgICAgICBvcHRpb25zLmFjdGl2aXR5ID0gdGhpcy54ZmFVdGlsKCkuX3h0Z0V2ZW50TmFtZVtldmVudE5hbWVdID8gdGhpcy54ZmFVdGlsKCkuX3h0Z0V2ZW50TmFtZVtldmVudE5hbWVdIDogZXZlbnROYW1lOwogICAgICAgICAgICAgICAgb3B0aW9ucy5jb250ZXh0U29tID0gY29udGV4dE9iai5zb21FeHByZXNzaW9uOwogICAgICAgICAgICAgICAgY29udGV4dE9iai5feGZhKCkuaG9zdC5ydW5TZXJ2ZXJTY3JpcHQob3B0aW9ucyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXhlY3V0ZUxvY2FsKGNvbnRleHRPYmosIGV2ZW50TmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZXhlY3V0ZUxvY2FsIDogIGZ1bmN0aW9uKGNvbnRleHRPYmosIGV2ZW50TmFtZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5zY3JpcHQuY2FsbChjb250ZXh0T2JqKTsgICAgICAvLyBUT0RPIDogVGhlIGJlc3Qgd2F5IHdpbGwgYmUgdG8gdXNlIGB3aXRoYCBzbyB0aGF0IGV2YWwgY2FuIGFsc28gYmUgdXNlZCB3aXRob3V0IG1vZGlmeWluZyBhbnl0aGluZwogICAgICAgICAgICB9IGNhdGNoKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgY29udGV4dE9iai5feGZhKCkuTG9nZ2VyLmVycm9yKCJ4ZmEiLCB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDIiXSxbZXZlbnROYW1lLCBjb250ZXh0T2JqLnNvbUV4cHJlc3Npb24sZXhjZXB0aW9uLm1lc3NhZ2VdKQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgfQoKICAgIH0pOwoKICAgIEV4ZWN1dGFibGVTY3JpcHQuZGVmaW5lUHJvcHMoewogICAgICAgICJydW5BdCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwucnVuQXQsIHRoaXMuX2RlZmF1bHRzLnJ1bkF0KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJzY3JpcHQiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMuX3NjcmlwdEZuID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgc2NyaXB0Q29udGVudCA9IHRoaXMuanNvbk1vZGVsLl92YWx1ZTsKICAgICAgICAgICAgICAgICAgICB0cnl7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50ID0gIndpdGgodGhpcykge1xuXG4gd2l0aCh4ZmFsaWIucnVudGltZSkge1xuXG4iICsgc2NyaXB0Q29udGVudCArICJcblxufVxuXG4gfSI7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NjcmlwdEZuID0gbmV3IEZ1bmN0aW9uKGNvbnRlbnQpOwogICAgICAgICAgICAgICAgICAgIH1jYXRjaChleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5lcnJvcigieGZhIiwgeGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDA1Il0sW2V4Y2VwdGlvbi5tZXNzYWdlLHNjcmlwdENvbnRlbnRdKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2NyaXB0Rm4gPSBuZXcgRnVuY3Rpb24oIiIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9zY3JpcHRGbjsKICAgICAgICAgICAgfQogICAgICAgIH0KCgogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuVmFsaWRhdGVTY3JpcHQKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LkV4ZWN1dGFibGVTY3JpcHQKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBWYWxpZGF0ZVNjcmlwdCA9IHhmYWxpYi5zY3JpcHQuVmFsaWRhdGVTY3JpcHQgPSB4ZmFsaWIuc2NyaXB0LkV4ZWN1dGFibGVTY3JpcHQuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBWYWxpZGF0ZVNjcmlwdC5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIGV2YWxTY3JpcHQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgd2l0aCh0aGlzKXsKICAgICAgICAgICAgICAgIHdpdGgoeGZhbGliLnJ1bnRpbWUpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgX19YRkFfZXZhbFZhbGlkYXRlU2NyaXB0UmV0VmFsX18gPSBldmFsKGFyZ3VtZW50c1swXSk7IC8vIExDLTczMTkgOiB2YXJpYWJsZSBuYW1lcyBwYXNzZWQgaW4gJ2V2YWwnIGFyZSBvdmVycmlkZGVuIGR1ZSB0byBlbmNsb3NpbmcgJ3dpdGgnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIF9fWEZBX2V2YWxWYWxpZGF0ZVNjcmlwdFJldFZhbF9fOwogICAgICAgIH0sCgogICAgICAgIF9leGVjdXRlTG9jYWwgOiAgZnVuY3Rpb24oY29udGV4dE9iaiwgZXZlbnROYW1lKSB7CiAgICAgICAgICAgIHZhciByVmFsdWUgPSB0cnVlOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgaWYodGhpcy5zY3JpcHQpCiAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdGhpcy5ldmFsU2NyaXB0LmNhbGwoY29udGV4dE9iaix0aGlzLnNjcmlwdCk7CiAgICAgICAgICAgICAgICBpZighclZhbHVlKQogICAgICAgICAgICAgICAgICAgIGNvbnRleHRPYmouX3hmYSgpLkxvZ2dlci5kZWJ1ZygieGZhIiwgeGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDE0Il0sW2NvbnRleHRPYmouc29tRXhwcmVzc2lvbix0aGlzLnNjcmlwdF0pCiAgICAgICAgICAgIH0gY2F0Y2goZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICBjb250ZXh0T2JqLl94ZmEoKS5Mb2dnZXIuZXJyb3IoInhmYSIsIHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAwMiJdLFtldmVudE5hbWUsIGNvbnRleHRPYmouc29tRXhwcmVzc2lvbixleGNlcHRpb24ubWVzc2FnZV0pCiAgICAgICAgICAgICAgICByVmFsdWUgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByVmFsdWU7CiAgICAgICAgfQoKICAgIH0pOwoKICAgIFZhbGlkYXRlU2NyaXB0LmRlZmluZVByb3BzKHsKICAgICAgICAic2NyaXB0IiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwuX3ZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5DYWxjdWxhdGVTY3JpcHQKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LlZhbGlkYXRlU2NyaXB0CiAqLwooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBDYWxjdWxhdGVTY3JpcHQgPSB4ZmFsaWIuc2NyaXB0LkNhbGN1bGF0ZVNjcmlwdCA9IHhmYWxpYi5zY3JpcHQuVmFsaWRhdGVTY3JpcHQuZXh0ZW5kKHsKCiAgICAgICAgX2V4ZWN1dGVMb2NhbCA6ICBmdW5jdGlvbihjb250ZXh0T2JqLCBldmVudE5hbWUpIHsKICAgICAgICAgICAgdmFyIHJWYWx1ZSA7CiAgICAgICAgICAgIGlmKHRoaXMuc2NyaXB0KXsKICAgICAgICAgICAgICAgIC8vIHByZV9wcm9jZXNzCiAgICAgICAgICAgICAgICBjb250ZXh0T2JqLl94ZmEoKS5fcHVzaENhbGN1bGF0ZUV2ZW50Tm9kZShjb250ZXh0T2JqKTsKCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGNvbnRleHRPYmoucmF3VmFsdWUgPSB0aGlzLmV2YWxTY3JpcHQuY2FsbChjb250ZXh0T2JqLHRoaXMuc2NyaXB0KQogICAgICAgICAgICAgICAgfSBjYXRjaChleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICBjb250ZXh0T2JqLl94ZmEoKS5Mb2dnZXIuZXJyb3IoInhmYSIsIHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAwMiJdLFtldmVudE5hbWUsIGNvbnRleHRPYmouc29tRXhwcmVzc2lvbixleGNlcHRpb24ubWVzc2FnZV0pCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gcG9zdF9wcm9jZXNzCiAgICAgICAgICAgICAgICBjb250ZXh0T2JqLl94ZmEoKS5fcG9wQ2FsY3VsYXRlRXZlbnROb2RlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJWYWx1ZTsKICAgICAgICB9CgogICAgfSk7Cn0pKF8sIHhmYWxpYik7Ci8qKgogKiBDcmVhdGVkIHdpdGggSW50ZWxsaUogSURFQS4KICogVXNlcjogcnBhbmRleQogKiBEYXRlOiAxMS8yNy8xMwogKiBUaW1lOiAxMDoyNiBBTQogKi8KLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuRmxvYXRpbmdGaWVsZFNjcmlwdAogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuQ2FsY3VsYXRlU2NyaXB0CiAqLwooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBGbG9hdGluZ0ZpZWxkU2NyaXB0ID0geGZhbGliLnNjcmlwdC5GbG9hdGluZ0ZpZWxkU2NyaXB0ID0geGZhbGliLnNjcmlwdC5DYWxjdWxhdGVTY3JpcHQuZXh0ZW5kKHsKICAgICAgICAvL0RvIHdlIHJlYWxseSBuZWVkIG5ldyBjbGFzcyBmb3IgRmxvYXRpbmdGaWVsZFNjcmlwdCBqdXN0IGZvciBhIGRpZmZlcmVudCBlcnJvciBtZXNzYWdlIGFuZCBhIGRpZmZlcmVudCBzY3JpcHQKCiAgICAgICAgX2V4ZWN1dGVMb2NhbCA6ICBmdW5jdGlvbihjb250ZXh0T2JqLCBldmVudE5hbWUpIHsKICAgICAgICAgICAgaWYoY29udGV4dE9iai5fcmVzb2x2ZUZsb2F0aW5nRmllbGQpewogICAgICAgICAgICAgICAgLy8gcHJlX3Byb2Nlc3MKICAgICAgICAgICAgICAgIGNvbnRleHRPYmouX3hmYSgpLl9wdXNoQ2FsY3VsYXRlRXZlbnROb2RlKGNvbnRleHRPYmopOwoKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgLy9DYWxsIF9yZXNvbHZlRmxvYXRpbmdGaWVsZCBpbiB0aGlzIGNvbnRleHQKICAgICAgICAgICAgICAgICAgICAvL3RoaXMgaGFyZC1jb2RpbmcgZGVjb3VwbGVzIHRoZSBzZXJ2ZXIgZnJvbSBzY3JpcHQgZnVuY3Rpb24gbmFtZS4uLgogICAgICAgICAgICAgICAgICAgIC8vTm93IGl0IGlzIG9ubHkgYXQgdGhlIGNsaWVudCBzaWRlIHdlIGtlZXAgdGhlIG5hbWUgb2YgZmxvYXRpbmcgZmllbGRzIHJlc29sdmVyIHNjcmlwdAogICAgICAgICAgICAgICAgICAgIHRoaXMuZXZhbFNjcmlwdC5jYWxsKGNvbnRleHRPYmosICdfcmVzb2x2ZUZsb2F0aW5nRmllbGQoKScpOwogICAgICAgICAgICAgICAgfSBjYXRjaChleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICBjb250ZXh0T2JqLl94ZmEoKS5Mb2dnZXIuZXJyb3IoInhmYSIsIHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAxOSJdLFtjb250ZXh0T2JqLnNvbUV4cHJlc3Npb25dKQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIHBvc3RfcHJvY2VzcwogICAgICAgICAgICAgICAgY29udGV4dE9iai5feGZhKCkuX3BvcENhbGN1bGF0ZUV2ZW50Tm9kZSgpOwoKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICB9CgogICAgfSk7Cn0pKF8sIHhmYWxpYik7Ci8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LlN1Ym1pdAogKiBAaW1wb3J0IHhmYWxpYi51dC5DbGFzcwogKi8KCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIFN1Ym1pdCA9IHhmYWxpYi5zY3JpcHQuU3VibWl0ID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgU3VibWl0Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY3V0ZSA6IGZ1bmN0aW9uKG9iaiwgZXZlbnROYW1lKSB7CiAgICAgICAgICAgIHZhciBvcHRpb25zID0ge307CiAgICAgICAgICAgIGlmKHRoaXMudGFyZ2V0KQogICAgICAgICAgICAgICAgb3B0aW9ucy5hY3Rpb24gPSB0aGlzLnRhcmdldDsKICAgICAgICAgICAgb3B0aW9ucy5mb3JtYXQgPSB0aGlzLmZvcm1hdDsKICAgICAgICAgICAgb3B0aW9ucy50ZXh0RW5jb2RpbmcgPSB0aGlzLnRleHRFbmNvZGluZzsKCiAgICAgICAgICAgIGZvcm1CcmlkZ2Uuc3VibWl0Rm9ybShvcHRpb25zKTsgLy9UT0RPOiByZW1vdmUgZGlyZWN0IGRlcGVuZGVuY3kgb24gRm9ybUJyaWRnZQogICAgICAgIH0KCiAgICB9KTsKCiAgICBTdWJtaXQuZGVmaW5lUHJvcHMoewogICAgICAgIGZvcm1hdCA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5mb3JtYXQsIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgdGFyZ2V0IDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JFbHNlKHRoaXMuanNvbk1vZGVsLnRhcmdldCwgbnVsbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICB0ZXh0RW5jb2RpbmcgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwudGV4dEVuY29kaW5nLCBudWxsKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKfSkoXywgeGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuRmllbGQKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk5vZGUKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBGaWVsZCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3IEZpZWxkIGNsYXNzCiAgICAgKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgRmllbGQKICAgICAqIEBwYXJhbSB7c3RyaW5nfQogICAgICogICAgICAgICAgICByYXdWYWwgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgRmllbGQKICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByYXdWYWwgcmVwcmVzZW50cyB0aGUgZGF0YSB2YWx1ZSBpbiB0aGUgbm9kZQogICAgICogQGV4dGVuZHMgeGZhbGliLnNjcmlwdC5Ob2RlCiAgICAgKi8KICAgIHZhciBGaWVsZCA9IHhmYWxpYi5zY3JpcHQuRmllbGQgPSB4ZmFsaWIuc2NyaXB0LkV2ZW50Q29udGFpbmVyTm9kZS5leHRlbmQoewogICAgICAgIF9kZWZhdWx0czogewogICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAic2F2ZSI6ICIwIgogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgIl9kZWZhdWx0IjogInJhd1ZhbHVlIiwKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIEZpZWxkLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsWyJ7ZGVmYXVsdH0iXSA9IHRoaXMuX2dldFZhbHVlKCk7CiAgICAgICAgICAgIHRoaXMudGVzdHMgPSBbdGhpcy5fbnVsbFRlc3QsIHRoaXMuX2Zvcm1hdFRlc3QsIHRoaXMuX3NjcmlwdFRlc3RdOwogICAgICAgICAgICBpZiAodGhpcy5qc29uTW9kZWwuZXh0cmFzICYmIHRoaXMuanNvbk1vZGVsLmV4dHJhcy5kYXRhSWQpCiAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5jcmVhdGVEYXRhTm9kZSh0aGlzLmpzb25Nb2RlbC5leHRyYXMuZGF0YUlkLCB0aGlzKTsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm1vQ2hpbGROb2Rlcy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICAgICAgdmFyIG9Ob2RlID0gdGhpcy5tb0NoaWxkTm9kZXNbaV07CiAgICAgICAgICAgICAgICBvTm9kZS5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQsIHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLmpzb25Nb2RlbC5pZCkgewogICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuTG9nZ2VyLmRlYnVnKCJ4ZmEiLCAiQWRkZWQgZmllbGQgd2l0aCBpZCA6IiArIHRoaXMuanNvbk1vZGVsLmlkKQogICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuX3hmYVRlbXBsYXRlQ2FjaGUuaWRNYXBbdGhpcy5qc29uTW9kZWwuaWRdID0gdGhpczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5lZGl0UGF0dGVybiA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMuanNvbk1vZGVsLCAiZXh0cmFzLmVkaXRQYXR0ZXJuRXgiLCBudWxsKTsKICAgICAgICB9LAoKICAgICAgICBwbGF5SnNvbjogZnVuY3Rpb24gKHBKc29uTW9kZWwpIHsKICAgICAgICAgICAgRmllbGQuX3N1cGVyLnBsYXlKc29uLmNhbGwodGhpcywgcEpzb25Nb2RlbCk7CgogICAgICAgICAgICAvLyB1cGRhdGUgZGF0YSBub2RlIGNhY2hlZCB2YWx1ZQogICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELCB0aGlzLAogICAgICAgICAgICAgICAgJ3Jhd1ZhbHVlJywgdGhpcy5yYXdWYWx1ZSwgdGhpcy5mb3JtYXR0ZWRWYWx1ZSk7CiAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsIGV2bnQpOwogICAgICAgIH0sCgogICAgICAgIF9zZXRQYXR0ZXJuOiBmdW5jdGlvbiAodHlwZSwgcGF0dGVybnMsIGNhbGxiYWNrKSB7CiAgICAgICAgICAgIGlmIChwYXR0ZXJucyAmJiBwYXR0ZXJucy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLmV4dHJhcyA9IHRoaXMuanNvbk1vZGVsLmV4dHJhcyB8fCB7fTsKICAgICAgICAgICAgICAgIF8uZWFjaChwYXR0ZXJucywgZnVuY3Rpb24gKHBhdHRlcm4sIGkpIHsKICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuLmxvY2FsZSA9IHBhdHRlcm4ubG9jYWxlIHx8IHRoaXMubG9jYWxlCiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLmV4dHJhc1t0eXBlXSA9IHBhdHRlcm5zOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZURvbUV2ZW50OiBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICBzd2l0Y2ggKGV2bnQuX3Byb3BlcnR5KSB7CiAgICAgICAgICAgICAgICBjYXNlICJmb3JtYXQucGljdHVyZSI6CiAgICAgICAgICAgICAgICAgICAgdmFyIHJlcyA9IHRoaXMuX3NldFBhdHRlcm4oImRpc3BsYXlQYXR0ZXJuRXgiLAogICAgICAgICAgICAgICAgICAgICAgICB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLnBhcnNlUGljdHVyZUNsYXVzZShldm50Lm5ld1RleHQpKTsKICAgICAgICAgICAgICAgICAgICBpZiAocmVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Nob3dEaXNwbGF5Rm9ybWF0KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAidmFsaWRhdGUucGljdHVyZSI6CiAgICAgICAgICAgICAgICAgICAgdmFyIHJlcyA9IHRoaXMuX3NldFBhdHRlcm4oInZhbGlkYXRlUGF0dGVybkV4IiwKICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYXJzZVBpY3R1cmVDbGF1c2UoZXZudC5uZXdUZXh0KSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlcykgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWxpZGF0ZShbXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB4ZmFsaWIuc2NyaXB0LkV2ZW50Q29udGFpbmVyTm9kZS5wcm90b3R5cGUuaGFuZGxlRG9tRXZlbnQuYXBwbHkodGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHNhdmVYTUw6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMucmF3VmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgbG9hZFhNTDogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAvL3RoaXMucmF3VmFsdWUgPSB2YWw7CiAgICAgICAgfSwKCgogICAgICAgIGFkZEl0ZW06IGZ1bmN0aW9uIChzRGlzcGxheVZhbCwgc1NhdmVWYWwpIHsKICAgICAgICAgICAgLy9jYWxsIF9nZXREaXNwbGF5SXRlbXMgYmVmb3JlIHNhdmluZyBhbnkgU2F2ZUl0ZW1zLgogICAgICAgICAgICB2YXIgc0l0ZW1zID0gdGhpcy5fZ2V0U2F2ZUl0ZW1zKHRydWUpOwogICAgICAgICAgICB2YXIgZEl0ZW1zID0gdGhpcy5fZ2V0RGlzcGxheUl0ZW1zKHRydWUpOwoKICAgICAgICAgICAgdmFyIHNhdmVJdGVtID0gewogICAgICAgICAgICAgICAgIl9jbGFzcyI6ICJ0ZXh0IiwKICAgICAgICAgICAgICAgICJfdmFsdWUiOiBzU2F2ZVZhbCA9PT0gdW5kZWZpbmVkID8gc0Rpc3BsYXlWYWwgOiBzU2F2ZVZhbAogICAgICAgICAgICB9OwoKICAgICAgICAgICAgc0l0ZW1zLl9hZGRDaGlsZCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZU1vZGVsKHNhdmVJdGVtKSk7CgogICAgICAgICAgICB2YXIgZGlzcGxheUl0ZW0gPSB7CiAgICAgICAgICAgICAgICAiX2NsYXNzIjogInRleHQiLAogICAgICAgICAgICAgICAgIl92YWx1ZSI6IHNEaXNwbGF5VmFsCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBkSXRlbXMuX2FkZENoaWxkKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlTW9kZWwoZGlzcGxheUl0ZW0pKTsKCiAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsCiAgICAgICAgICAgICAgICB0aGlzLCAiYWRkSXRlbSIsIHNhdmVJdGVtLl92YWx1ZSwgZGlzcGxheUl0ZW0uX3ZhbHVlKTsKICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSwgZXZudCk7CiAgICAgICAgfSwKCiAgICAgICAgX3NwbGl0U3RyaW5nV2l0aEVzY2FwZWRDb21tYXM6IGZ1bmN0aW9uIChzdHJpbmcpIHsKICAgICAgICAgICAgdmFyIGFyciA9IFtdOwogICAgICAgICAgICB2YXIgc3RhcnQgPSAwOwogICAgICAgICAgICAvLyBhIG5lZ2F0aXZlIGxvb2t1cCB3YXMgYXZvaWRlZCBhcyBpdCdzIG5vdCBzdXBwb3J0ZWQgaW4gcmhpbm8gYW5kIElFIDExCiAgICAgICAgICAgIGZvcih2YXIgaSA9IDAgOyBpIDwgc3RyaW5nLmxlbmd0aCA7IGkrKyApewogICAgICAgICAgICAgICAgaWYoc3RyaW5nW2ldID09PSAnLCcgJiYgc3RyaW5nW2ktMV0hPT0gJ1xcJyApLy8gaS0xIGlzIHNhZmUgYmVjYXVzZSB0aGUgY29tbWFzIGFyZSBhbHJlYWR5IGRlbGltaXRlZAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFyci5wdXNoKHN0cmluZy5zdWJzdHJpbmcoc3RhcnQsIGkpLnJlcGxhY2UoL1xcLC9nLCAnLCcpKTsKICAgICAgICAgICAgICAgICAgICBzdGFydCA9IGkgKyAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGFyci5wdXNoKHN0cmluZy5zdWJzdHJpbmcoc3RhcnQpLnJlcGxhY2UoL1xcLC9nLCAnLCcpKTsKICAgICAgICAgICAgcmV0dXJuIGFycjsKICAgICAgICB9LAoKICAgICAgICBzZXRJdGVtczogZnVuY3Rpb24gKHN0cmluZywgcGFpcikgewogICAgICAgICAgICBwYWlyID0gcGFpciA9PT0gdW5kZWZpbmVkID8gMSA6IHBhaXI7CiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgdmFyIHZhbCA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuY2xlYXJJdGVtcygpOwogICAgICAgICAgICB2YXIgYXJyYXkgPSBudWxsOwogICAgICAgICAgICBpZihzdHJpbmcuaW5kZXhPZignXFwsJykgPiAtMSl7CiAgICAgICAgICAgICAgICBhcnJheSA9IHRoaXMuX3NwbGl0U3RyaW5nV2l0aEVzY2FwZWRDb21tYXMoc3RyaW5nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGFycmF5ID0gc3RyaW5nLnNwbGl0KCcsJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHBhaXIgPT0gMikgewogICAgICAgICAgICAgICAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbiAoZW50cnksIGluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ICUgMiA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuYWRkSXRlbShlbGVtLCBlbnRyeSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA9IGVudHJ5OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0gPSBlbnRyeTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgaWYgKGFycmF5Lmxlbmd0aCAlIDIpCiAgICAgICAgICAgICAgICAgICAgdGhhdC5hZGRJdGVtKGVsZW0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHBhaXIgPT0gMSkgewogICAgICAgICAgICAgICAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbiAoZW50cnkpIHsKICAgICAgICAgICAgICAgICAgICB0aGF0LmFkZEl0ZW0oZW50cnkpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChwYWlyID4gMikKICAgICAgICAgICAgICAgIHJldHVybiAgZmFsc2U7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9LAoKICAgICAgICBjbGVhckl0ZW1zOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBzSXRlbXMgPSB0aGlzLl9nZXRTYXZlSXRlbXMoZmFsc2UpOwogICAgICAgICAgICB2YXIgZEl0ZW1zID0gdGhpcy5fZ2V0RGlzcGxheUl0ZW1zKGZhbHNlKTsKICAgICAgICAgICAgaWYgKHNJdGVtcykKICAgICAgICAgICAgICAgIHNJdGVtcy5fcmVtb3ZlQWxsKCk7CiAgICAgICAgICAgIGlmIChkSXRlbXMpCiAgICAgICAgICAgICAgICBkSXRlbXMuX3JlbW92ZUFsbCgpOwogICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELAogICAgICAgICAgICAgICAgdGhpcywgImNsZWFySXRlbXMiLCBudWxsLCBudWxsKTsKICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSwgZXZudCk7CiAgICAgICAgfSwKCiAgICAgICAgYm91bmRJdGVtOiBmdW5jdGlvbiAoc0Rpc3BsYXlWYWwpIHsKICAgICAgICAgICAgdmFyIGRJdGVtcyA9IHRoaXMuX2dldERpc3BsYXlJdGVtcyhmYWxzZSk7CiAgICAgICAgICAgIHZhciBzYXZlVmFsdWUgPSBudWxsOwogICAgICAgICAgICBfLmZpbmQoZEl0ZW1zID8gZEl0ZW1zLmNoaWxkcmVuIDogW10sCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoaXRlbSwgaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS52YWx1ZSA9PSBzRGlzcGxheVZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICBzYXZlVmFsdWUgPSB0aGlzLmdldFNhdmVJdGVtKGluZGV4KTsgLy9UaGlzIHNob3VsZCBhbHdheXMgYmUgcHJlc2VudAogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9LCB0aGlzCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybiBzYXZlVmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RGlzcGxheUl0ZW06IGZ1bmN0aW9uIChuSW5kZXgpIHsKICAgICAgICAgICAgdmFyIGRJdGVtcyA9IHRoaXMuX2dldERpc3BsYXlJdGVtcyh0cnVlKTsKICAgICAgICAgICAgaWYgKG5JbmRleCA+PSAwICYmIGRJdGVtcyAmJiBkSXRlbXMuY2hpbGRyZW4ubGVuZ3RoID4gbkluZGV4KQogICAgICAgICAgICAgICAgcmV0dXJuIGRJdGVtcy5tb0NoaWxkTm9kZXNbbkluZGV4XS52YWx1ZTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsgLy9Eb24ndCBjaGFuZ2UKICAgICAgICB9LAoKICAgICAgICBnZXRTYXZlSXRlbTogZnVuY3Rpb24gKG5JbmRleCkgewogICAgICAgICAgICB2YXIgc0l0ZW1zID0gdGhpcy5fZ2V0U2F2ZUl0ZW1zKHRydWUpOwogICAgICAgICAgICBpZiAobkluZGV4ID49IDAgJiYgc0l0ZW1zICYmIHNJdGVtcy5jaGlsZHJlbi5sZW5ndGggPiBuSW5kZXgpCiAgICAgICAgICAgICAgICByZXR1cm4gc0l0ZW1zLm1vQ2hpbGROb2Rlc1tuSW5kZXhdLnZhbHVlOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkOyAvL0Rvbid0IGNoYW5nZQogICAgICAgIH0sCgogICAgICAgIGdldEl0ZW1TdGF0ZTogZnVuY3Rpb24gKG5JbmRleCkgewogICAgICAgICAgICB2YXIgaXRlbVZhbHVlID0gdGhpcy5nZXRPckVsc2UodGhpcy5nZXRTYXZlSXRlbShuSW5kZXgpLCB0aGlzLmdldERpc3BsYXlJdGVtKG5JbmRleCkpOwogICAgICAgICAgICBpZiAoaXRlbVZhbHVlICE9PSBudWxsICYmIGl0ZW1WYWx1ZSAhPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yYXdWYWx1ZSA9PSBpdGVtVmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vIFRPRE86IHJldHVybiBudWxsIG9yIGZhbHNlCiAgICAgICAgfSwKCiAgICAgICAgc2V0SXRlbVN0YXRlOiBmdW5jdGlvbiAobkluZGV4LCBiVmFsKSB7CiAgICAgICAgICAgIHZhciBpdGVtVmFsdWUgPSB0aGlzLmdldE9yRWxzZSh0aGlzLmdldFNhdmVJdGVtKG5JbmRleCksIHRoaXMuZ2V0RGlzcGxheUl0ZW0obkluZGV4KSk7CiAgICAgICAgICAgIGlmIChpdGVtVmFsdWUgIT09IG51bGwgJiYgaXRlbVZhbHVlICE9PSB1bmRlZmluZWQpIHsgICAgICAgICAgICAgICAgICAgICAgLy9UT0RPOklzIGl0IGNvcnJlY3QuIFdoYXQgYWJvdXQgVGV4dCBhbmQgTnVtZXJpY0lucHV0PwogICAgICAgICAgICAgICAgaWYgKGJWYWwpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5yYXdWYWx1ZSA9IGl0ZW1WYWx1ZTsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMucmF3VmFsdWUgPT0gaXRlbVZhbHVlKQogICAgICAgICAgICAgICAgICAgIHRoaXMucmF3VmFsdWUgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgZGVsZXRlSXRlbTogZnVuY3Rpb24gKG5JbmRleCkgewogICAgICAgICAgICB2YXIgc0l0ZW1zID0gdGhpcy5fZ2V0U2F2ZUl0ZW1zKGZhbHNlKTsKICAgICAgICAgICAgdmFyIGRJdGVtcyA9IHRoaXMuX2dldERpc3BsYXlJdGVtcyhmYWxzZSk7CiAgICAgICAgICAgIGlmIChuSW5kZXggPj0gMCAmJiBzSXRlbXMgJiYgc0l0ZW1zLm1vQ2hpbGROb2Rlcy5sZW5ndGggPiBuSW5kZXgpIC8vQ2hlY2sgd2hldGhlciBuZWdhdGl2ZSB2YWx1ZSBvZiBuSW5kZXggaXMgYSBsZWdhbCB2YWx1ZT8/CiAgICAgICAgICAgICAgICBzSXRlbXMuX3JlbW92ZUNoaWxkKHNJdGVtcy5tb0NoaWxkTm9kZXNbbkluZGV4XSk7CiAgICAgICAgICAgIGlmIChuSW5kZXggPj0gMCAmJiBkSXRlbXMgJiYgZEl0ZW1zLm1vQ2hpbGROb2Rlcy5sZW5ndGggPiBuSW5kZXgpIC8vQ2hlY2sgd2hldGhlciBuZWdhdGl2ZSB2YWx1ZSBvZiBuSW5kZXggaXMgYSBsZWdhbCB2YWx1ZT8/CiAgICAgICAgICAgICAgICBkSXRlbXMuX3JlbW92ZUNoaWxkKGRJdGVtcy5tb0NoaWxkTm9kZXNbbkluZGV4XSk7CiAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsCiAgICAgICAgICAgICAgICB0aGlzLCAiZGVsZXRlSXRlbSIsIG51bGwsIG5JbmRleCk7CiAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsIGV2bnQpOwogICAgICAgIH0sCgogICAgICAgIGV4ZWNWYWxpZGF0ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4odGhpcy5fdmFsaWRhdGUoW10pKTsKICAgICAgICB9LAoKICAgICAgICBuYWtlZEZpZWxkUmVmZXJlbmNlczogZnVuY3Rpb24gKG5JbmRleCwgY3JlYXRlR2V0dGVyU2V0dGVyLCBvYmopIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0sCgogICAgICAgIF9yZXNldERhdGE6IGZ1bmN0aW9uIChuSW5kZXgsIGJGb3JjZSkgewogICAgICAgICAgICB0aGlzLnJhd1ZhbHVlID0gdGhpcy5qc29uTW9kZWxbIntkZWZhdWx0fSJdOwogICAgICAgIH0sCgogICAgICAgIF9udWxsVGVzdDogZnVuY3Rpb24gKHNNZXNzYWdlcykgewogICAgICAgICAgICB2YXIgdmFsaWQgPSB0cnVlOwogICAgICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLl9nZXRWYWx1ZSgpOwogICAgICAgICAgICBpZiAoKHZhbHVlID09IG51bGwgfHwgdmFsdWUubGVuZ3RoID09IDApICYmIHRoaXMubWFuZGF0b3J5ICE9ICJkaXNhYmxlZCIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxUZXN0ID0gIm51bGxUZXN0IjsKICAgICAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxMZXZlbCA9IHRoaXMubWFuZGF0b3J5OwogICAgICAgICAgICAgICAgdGhpcy5fZXJyb3JUZXh0ID0gdGhpcy5tYW5kYXRvcnlNZXNzYWdlOwogICAgICAgICAgICAgICAgdGhpcy5fYWRkTWVzc2FnZShzTWVzc2FnZXMsIHRoaXMuX2Vycm9yVGV4dCwgdGhpcy5fbUZhaWxlZFZhbExldmVsKTsKICAgICAgICAgICAgICAgIHZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbGlkOwogICAgICAgIH0sCgogICAgICAgIF9mb3JtYXRUZXN0OiBmdW5jdGlvbiAoc01lc3NhZ2VzKSB7CiAgICAgICAgICAgIHZhciB2YWxpZCA9IHRydWU7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuX2dldFZhbHVlKCk7CiAgICAgICAgICAgIGlmICh2YWx1ZSkKICAgICAgICAgICAgICAgIHZhbHVlICs9ICIiOwogICAgICAgICAgICB2YXIgcGljdHVyZSA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMuanNvbk1vZGVsLCJleHRyYXMudmFsaWRhdGVQYXR0ZXJuRXgiLCB1bmRlZmluZWQpOwogICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiBwaWN0dXJlKSB7CiAgICAgICAgICAgICAgICB2YXIgcmV0VmFsID0gdGhpcy5fZm9ybWF0VmFsdWUodmFsdWUsIHBpY3R1cmUsIDApOwogICAgICAgICAgICAgICAgaWYgKCFyZXRWYWwpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZXRFcnJvckRhdGEoImZvcm1hdFRlc3QiLCB0aGlzLmdldE9yRWxzZSh0aGlzLnZhbGlkYXRlLmZvcm1hdFRlc3QsIHRoaXMuX2RlZmF1bHRzLnZhbGlkYXRlLmZvcm1hdFRlc3QpLCB0aGlzLmZvcm1hdE1lc3NhZ2UpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkZE1lc3NhZ2Uoc01lc3NhZ2VzLCB0aGlzLl9lcnJvclRleHQsIHRoaXMuX21GYWlsZWRWYWxMZXZlbCk7CiAgICAgICAgICAgICAgICAgICAgdmFsaWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdmFsaWQ7CiAgICAgICAgfSwKCiAgICAgICAgX3NldEVycm9yRGF0YTogZnVuY3Rpb24gKGZhaWxlZFRlc3QsIGZhaWxlZExldmVsLCBlcnJvclRleHQpIHsKICAgICAgICAgICAgdGhpcy5fbUZhaWxlZFZhbFRlc3QgPSBmYWlsZWRUZXN0OwogICAgICAgICAgICB0aGlzLl9tRmFpbGVkVmFsTGV2ZWwgPSBmYWlsZWRMZXZlbDsKICAgICAgICAgICAgdGhpcy5fZXJyb3JUZXh0ID0gZXJyb3JUZXh0OwogICAgICAgIH0sCgogICAgICAgIF9nZXRTYXZlSXRlbXM6IGZ1bmN0aW9uIChjcmVhdGVJZlJlcWQpIHsKICAgICAgICAgICAgdmFyIGl0ZW1zTGlzdCA9IHRoaXMuCiAgICAgICAgICAgICAgICBfZmluZENoaWxkcmVuKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlU29tRXhwcmVzc2lvbigiaXRlbXNbKl0iKSwKICAgICAgICAgICAgICAgIHRydWUpCiAgICAgICAgICAgIHZhciBzYXZlSXRlbXMgPSBpdGVtc0xpc3QuX2ZpbmQoZnVuY3Rpb24gKGl0ZW0sIGluZGV4KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaXRlbS5zYXZlID09IDE7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBpZiAoIXNhdmVJdGVtcyAmJiBjcmVhdGVJZlJlcWQpIHsKICAgICAgICAgICAgICAgIHNhdmVJdGVtcyA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlTW9kZWwoewogICAgICAgICAgICAgICAgICAgIF9jbGFzczogIml0ZW1zIiwKICAgICAgICAgICAgICAgICAgICBzYXZlOiAiMSIsCiAgICAgICAgICAgICAgICAgICAgbmFtZTogIml0ZW1zIgogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB0aGlzLl9hZGRDaGlsZChzYXZlSXRlbXMpOwogICAgICAgICAgICAgICAgdmFyIGRpc3BsYXlJdGVtcyA9IGl0ZW1zTGlzdC5fZmluZChmdW5jdGlvbiAoaXRlbSwgaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlbS5zYXZlID09IDA7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHNhdmVJdGVtcy5jaGlsZHJlbiA9IGRpc3BsYXlJdGVtcyA/IGRpc3BsYXlJdGVtcy5tb0NoaWxkTm9kZXMgOiBbXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoc2F2ZUl0ZW1zKQogICAgICAgICAgICAgICAgcmV0dXJuIHNhdmVJdGVtczsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgX2dldERpc3BsYXlJdGVtczogZnVuY3Rpb24gKGNyZWF0ZUlmUmVxZCkgewogICAgICAgICAgICB2YXIgaXRlbXNMaXN0ID0gdGhpcy4KICAgICAgICAgICAgICAgIF9maW5kQ2hpbGRyZW4oeGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVTb21FeHByZXNzaW9uKCJpdGVtc1sqXSIpLAogICAgICAgICAgICAgICAgdHJ1ZSkKICAgICAgICAgICAgdmFyIGRpc3BsYXlJdGVtcyA9IGl0ZW1zTGlzdC5fZmluZChmdW5jdGlvbiAoaXRlbSwgaW5kZXgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpdGVtLnNhdmUgPT0gMDsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlmICghZGlzcGxheUl0ZW1zICYmIGNyZWF0ZUlmUmVxZCkgewogICAgICAgICAgICAgICAgZGlzcGxheUl0ZW1zID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVNb2RlbCh7CiAgICAgICAgICAgICAgICAgICAgX2NsYXNzOiAiaXRlbXMiLAogICAgICAgICAgICAgICAgICAgIG5hbWU6ICJpdGVtcyIKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgdGhpcy5fYWRkQ2hpbGQoZGlzcGxheUl0ZW1zKTsKICAgICAgICAgICAgICAgIHZhciBzYXZlSXRlbXMgPSBpdGVtc0xpc3QuX2ZpbmQoZnVuY3Rpb24gKGl0ZW0sIGluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0uc2F2ZSA9PSAxOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBkaXNwbGF5SXRlbXMuY2hpbGRyZW4gPSBzYXZlSXRlbXMgPyBzYXZlSXRlbXMubW9DaGlsZE5vZGVzIDogW107CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGRpc3BsYXlJdGVtcykKICAgICAgICAgICAgICAgIHJldHVybiBkaXNwbGF5SXRlbXM7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRTYXZlSXRlbXMoKTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0VmFsdWU6IGZ1bmN0aW9uIChjb250ZW50VHlwZSwgc2tpcFR5cGVDaGVjaykgewogICAgICAgICAgICByZXR1cm4gdGhpcy52YWx1ZS5vbmVPZkNoaWxkLmdldFZhbHVlKGNvbnRlbnRUeXBlLCBza2lwVHlwZUNoZWNrKTsKICAgICAgICB9LAoKICAgICAgICBfc2V0VmFsdWU6IGZ1bmN0aW9uIChzVmFsLCBza2lwVHlwZUNoZWNrKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlLm9uZU9mQ2hpbGQuc2V0VmFsdWUoc1ZhbCwgc2tpcFR5cGVDaGVjayk7CiAgICAgICAgfSwKCiAgICAgICAgX3NldEhUTUxWYWx1ZTogZnVuY3Rpb24oaHRtbFN0cikgewogICAgICAgICAgICAvLyBhcGkgdG8gc2V0IHRoZSBodG1sIHZhbHVlIGZvciBjbSB1c2UtY2FzZQogICAgICAgICAgICB0aGlzLl9zZXRWYWx1ZShodG1sU3RyLCB0cnVlKTsKICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwgdGhpcywKICAgICAgICAgICAgICAgICdyYXdWYWx1ZScsIG51bGwsIGh0bWxTdHIpOwogICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLCBldm50KTsKICAgICAgICB9LAoKICAgICAgICBfZXZlbnRIYW5kbGVyOiBmdW5jdGlvbiAoZXZlbnROYW1lKSB7CiAgICAgICAgICAgIHZhciByVmFsdWUgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIHN3aXRjaCAoZXZlbnROYW1lKSB7CiAgICAgICAgICAgICAgICBjYXNlICJjYWxjdWxhdGUiOgogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm1vRXZlbnRzWyJjYWxjdWxhdGUiXSAmJiB0aGlzLm1vRXZlbnRzWyJjYWxjdWxhdGUiXS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJWYWx1ZSA9IHRoaXMubW9FdmVudHNbImNhbGN1bGF0ZSJdWzBdLmV4ZWN1dGUodGhpcywgImNhbGN1bGF0ZSIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInZhbGlkYXRlIjoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5tb0V2ZW50c1sidmFsaWRhdGUiXSAmJiB0aGlzLm1vRXZlbnRzWyJ2YWxpZGF0ZSJdLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdGhpcy5tb0V2ZW50c1sidmFsaWRhdGUiXVswXS5leGVjdXRlKHRoaXMsICJ2YWxpZGF0ZSIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgICAgICAgICByVmFsdWUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiJGZvcm1wcmVTdWJtaXQiOgogICAgICAgICAgICAgICAgICAgIHJWYWx1ZSA9IHRoaXMuX3ByZVN1Ym1pdEV2ZW50SGFuZGxlcigpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5tb0V2ZW50c1tldmVudE5hbWVdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tb0V2ZW50c1tldmVudE5hbWVdLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1vRXZlbnRzW2V2ZW50TmFtZV1baV0uZXhlY3V0ZSh0aGlzLCBldmVudE5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByVmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgX2lzRmllbGQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSwKCiAgICAgICAgX3Nob3dEaXNwbGF5Rm9ybWF0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsIHRoaXMsCiAgICAgICAgICAgICAgICAncmF3VmFsdWUnLCB0aGlzLnJhd1ZhbHVlLCB0aGlzLmZvcm1hdHRlZFZhbHVlKTsKICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSwgZXZudCk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldERlZmF1bHRQaWN0dXJlQ2xhdXNlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9LAoKICAgICAgICBfZm9ybWF0VmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSwgcGljdHVyZSwgZm9yY2UpIHsKICAgICAgICAgICAgLy90ZXN0aW5nIHNwZWNpZmljYWxseSBmb3Igb25seSBudWxsIGFuZCB6ZXJvIGxlbmd0aCBzdHJpbmcKICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAidW5kZWZpbmVkIiB8fCB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gIiIpCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKCiAgICAgICAgICAgIC8vZm9yY2UgaXMgc2FtZSBhcyBiUmVsYXhlZCAsIHdoaWNoIGlzIHRydWUgaW4gY2FzZSBvZiBEaXNwbGF5IGFuZCBmYWxzZSBpbiBjYXNlIG9mIHBhcnNpbmcuCiAgICAgICAgICAgIGZvcmNlID0gZm9yY2UgfHwgZmFsc2U7CiAgICAgICAgICAgIGlmIChwaWN0dXJlKSB7CiAgICAgICAgICAgICAgICB2YXIgaSA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IHBpY3R1cmUubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGF0dGVybiA9IHBpY3R1cmVbaV0uY2F0ZWdvcnkgKyAieyIgKyBwaWN0dXJlW2ldLm1hc2sgKyAifSI7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB4ZmFsaWIudXQuUGljdHVyZUZtdC5mb3JtYXQodmFsdWUgKyAiIiwgcGF0dGVybiwgcGljdHVyZVtpXS5sb2NhbGUsIGZvcmNlICxmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vY29udGludWUgdG8gbmV4dCBwYwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZm9yY2UpIHsKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSB0aGlzLl9nZXREZWZhdWx0UGljdHVyZUNsYXVzZSgpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlBpY3R1cmVGbXQuZm9ybWF0KHZhbHVlICsgIiIsIHBhdHRlcm4sIHRoaXMubG9jYWxlLGZvcmNlLHRydWUpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIF9wYXJzZVZhbHVlOiBmdW5jdGlvbiAodmFsdWUsIHBpY3R1cmUpIHsKICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwoKICAgICAgICAgICAgaWYgKHBpY3R1cmUpIHsKICAgICAgICAgICAgICAgIHZhciBpID0gMDsKICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgcGljdHVyZS5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXR0ZXJuID0gcGljdHVyZVtpXS5jYXRlZ29yeSArICJ7IiArIHBpY3R1cmVbaV0ubWFzayArICJ9IjsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5QaWN0dXJlRm10LnBhcnNlKHZhbHVlLCBwYXR0ZXJuLCBwaWN0dXJlW2ldLmxvY2FsZSk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vY29udGludWUgdG8gbmV4dCBwYwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBwYXR0ZXJuID0gdGhpcy5fZ2V0RGVmYXVsdFBpY3R1cmVDbGF1c2UoKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiB4ZmFsaWIudXQuUGljdHVyZUZtdC5wYXJzZSh2YWx1ZSwgcGF0dGVybiwgdGhpcy5sb2NhbGUpOwogICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgoKICAgICAgICBfZ2V0TG9jYWxlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBvYmogPSB0aGlzOwogICAgICAgICAgICB2YXIgbG9jYWxlOwogICAgICAgICAgICB3aGlsZSAoIWxvY2FsZSAmJiBvYmopIHsKICAgICAgICAgICAgICAgIGxvY2FsZSA9IG9iai5qc29uTW9kZWwubG9jYWxlOwogICAgICAgICAgICAgICAgb2JqID0gb2JqLnBhcmVudDsKICAgICAgICAgICAgfQogICAgICAgICAgICBsb2NhbGUgPSBsb2NhbGUgfHwgdGhpcy5feGZhKCkuZGVmYXVsdExvY2FsZTsKICAgICAgICAgICAgcmV0dXJuIGxvY2FsZTsKICAgICAgICB9LAoKICAgICAgICBzY29wZWxlc3M6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgIC8vY2hlY2sgYmluZGluZ3MgLT4gaWYgaXQgaXMgbm9uZSB0aGVuIHRoaXMgZmllbGQgaXMgbm90IG5lZWRlZCBpbiB4bWwKICAgICAgICAgICAgaWYgKGRpZmZfbGV2ZWw+MCkgewogICAgICAgICAgICAgICAgdmFyIGJpbmRFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50KCJiaW5kIiwgMCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICBpZiAoYmluZEVsZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYmluZEVsZW1lbnQuZ2V0QXR0cmlidXRlKCJtYXRjaCIpID09PSAibm9uZSIgJiYgZGlmZl9sZXZlbCA9PT0gMikgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgImNoYW5nZWQiOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqc29uRGlmZmVyZW5jZSI6IHt9CiAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBGaWVsZC5fc3VwZXIuX2NvbXB1dGVKc29uRGlmZi5jYWxsKHRoaXMsIGRpZmZfbGV2ZWwpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiB0aGUgRGF0YVNPTU1hcCBhZnRlciBhZGRpbmcgYW4gZW50cnkgaW4gdGhlIG1hcCBmb3IgdGhlIG5vZGUuIFRoZSBlbnRyeSBjb250YWlucyB0aGUgdmFsdWUgb2YgdGhlIG5vZGUKICAgICAgICAgKiBhbG9uZyB3aXRoIGl0cyBEYXRhIFNPTS4gSWYgdGhlcmUgaXMgbm8gRGF0YSBTT00gdGhlbiByZXR1cm4gdGhlIHVubW9kaWZpZWQgbWFwCiAgICAgICAgICogQHBhcmFtIG1hcAogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2dldERhdGFTb21NYXAgOiBmdW5jdGlvbihtYXApIHsKICAgICAgICAgICAgaWYoIV8uaXNPYmplY3QobWFwKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG1hcDsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgZGF0YXNvbSA9IHRoaXMuX2dldERhdGFTb20oKTsKICAgICAgICAgICAgaWYoZGF0YXNvbSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgbWFwW2RhdGFzb21dID0gdGhpcy5yYXdWYWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbWFwOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFVwZGF0ZSB0aGUgdmFsdWUgb2YgdGhlIG5vZGUgd2l0aCB0aGUgdmFsdWUgcHJvdmlkZWQgaW4gdGhlIGlucHV0IG1hcC4gVGhlIG1hcCBjb250YWlucyB0aGUgdmFsdWVzIG9mIHRoZSBmaWVsZHMKICAgICAgICAgKiBtYXBwZWQgd2l0aCB0aGVpciBEYXRhU09NLiBUaGUgZnVuY3Rpb24gaXMgZW1wdHkgZm9yIGFsbCB0aGUgbm9kZXMsIGV4Y2VwdCBmb3IgRmllbGQsIFN1YmZvcm0gYW5kIEFyZWEuCiAgICAgICAgICogVGhlIGZ1bmN0aW9uIGRvZXMgbm90aGluZyBpZiB0aGUgbWFwIGlzIG5vdCBhbiBvYmplY3QKICAgICAgICAgKiBAcGFyYW0gbWFwIHtvYmplY3R9CiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfcmVzdG9yZURhdGFTb21NYXAgOiBmdW5jdGlvbiAobWFwKSB7CiAgICAgICAgICAgIGlmKCFfLmlzT2JqZWN0KG1hcCkpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgZGF0YXNvbSA9IHRoaXMuX2dldERhdGFTb20oKTsKICAgICAgICAgICAgaWYgKGRhdGFzb20gIT0gbnVsbCAmJiBtYXBbZGF0YXNvbV0gIT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgdGhpcy5yYXdWYWx1ZSA9IG1hcFtkYXRhc29tXTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEV2YWx1YXRlcyB0aGUgZ2l2ZW4geHBhdGggcmVsYXRpdmUgdG8gY29udGV4dE5vZGUgb3IgUm9vdE5vZGUgZGVwZW5kaW5nIHVwb24gdGhlIHZhbHVlIG9mIHhwYXRoLnJlbGF0aXZlCiAgICAgICAgICogSW4gY2FzZSBpdCBpcyB0cnVlLCB4cGF0aCBpcyBldmFsdWF0ZXMgcmVsYXRpdmUgdG8gY29udGV4dE5vZGUgb3RoZXJ3aXNlIHJvb3ROb2RlCiAgICAgICAgICogRm9yIEZpZWxkcywgdGhlIHZhbHVlIG9mIHhwYXRoLnJlbGF0aXZlIGNhbiBiZSAiZ2xvYmFsIiBpbiB3aGljaCBjYXNlIHdlIG5lZWQgdG8gc2VhcmNoIHRoZSBkZXNjZW5kYW50cyBvZgogICAgICAgICAqIHRoZSByb290Tm9kZQogICAgICAgICAqIEBwYXJhbSB4cGF0aAogICAgICAgICAqIEBwYXJhbSBjb250ZXh0Tm9kZQogICAgICAgICAqIEBwYXJhbSByb290Tm9kZQogICAgICAgICAqIEByZXR1cm5zIHsqfQogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2dldEVsZW1lbnRzRnJvbVhwYXRoOiBmdW5jdGlvbih4cGF0aCwgY29udGV4dE5vZGUsIHJvb3ROb2RlKSB7CiAgICAgICAgICAgIHZhciBub2RlSXRlciwKICAgICAgICAgICAgICAgIFhNTFV0aWxzID0geGZhbGliLnV0LlhNTFV0aWxzLAogICAgICAgICAgICAgICAgZG9jID0gcm9vdE5vZGUgaW5zdGFuY2VvZiBEb2N1bWVudCA/IHJvb3ROb2RlIDogcm9vdE5vZGUub3duZXJEb2N1bWVudDsKICAgICAgICAgICAgaWYoeHBhdGgucmVsYXRpdmUgPT09ICJnbG9iYWwiKSB7CiAgICAgICAgICAgICAgICBub2RlSXRlciA9IFhNTFV0aWxzLmV2YWx1YXRlWFBhdGgoIi8vIit4cGF0aC5iaW5kUmVmLCByb290Tm9kZSwgbnVsbCwKICAgICAgICAgICAgICAgICAgICBYUGF0aFJlc3VsdC5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSwgbnVsbCk7CiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZUl0ZXI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIEZpZWxkLl9zdXBlci5fZ2V0RWxlbWVudHNGcm9tWHBhdGguYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBfcGxheURhdGFYTUw6IGZ1bmN0aW9uKHhtbERvY3VtZW50LCBjb250ZXh0Tm9kZSwgY3VycmVudEJpbmRSZWYpIHsKICAgICAgICAgICAgaWYodGhpcy5oYXNEYXRhQmluZGluZygpKSB7CiAgICAgICAgICAgICAgICB2YXIgeHBhdGggPSB0aGlzLl9nZXRYcGF0aEZyb21CaW5kUmVmKCksCiAgICAgICAgICAgICAgICAgICAgZGF0YVBhdHRlcm4gPSB0aGlzLmpzb25Nb2RlbC5kYXRhUGF0dGVybiwvLyBUT0RPIDogaWRlYWxseSBzaG91bGQgcmVhZCBmcm9tIGJpbmQucGljdHVyZS52YWx1ZQogICAgICAgICAgICAgICAgICAgIHJlc3VsdCwgbm9kZSwKICAgICAgICAgICAgICAgICAgICBsb2dnZXIgPSB0aGlzLl94ZmEoKS5Mb2dnZXI7CiAgICAgICAgICAgICAgICBpZih4cGF0aCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5fZ2V0RWxlbWVudHNGcm9tWHBhdGgoeHBhdGgsIGNvbnRleHROb2RlLCB4bWxEb2N1bWVudCk7CiAgICAgICAgICAgICAgICAgICAgaWYocmVzdWx0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IHJlc3VsdC5pdGVyYXRlTmV4dCgpOwogICAgICAgICAgICAgICAgICAgICAgICBpZihub2RlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcmVGaWxsVmFsdWUgPSBub2RlLnRleHRDb250ZW50OwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKF8uaXNTdHJpbmcoZGF0YVBhdHRlcm4pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcnNlZFBhdHRlcm4gPSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLnBhcnNlUGljdHVyZUNsYXVzZShkYXRhUGF0dGVybik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoXy5pc0FycmF5KHBhcnNlZFBhdHRlcm4pICYmIHBhcnNlZFBhdHRlcm4ubGVuZ3RoID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDUS00MjQ0OTgzIDogY2hhbmdpbmcgdGhlIGZvcm1hdFRlc3QgY29uZGl0aW9uLiBDYXNlcyB3aGVyZSBwcmVmaWxsZWQgdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlzIHByb3Blcmx5IGZvcm1hdHRlZCwgdmFsdWUgd2FzIG5vdCBiZWluZyBwYXJzZWQgYW5kIHRoZSByYXdWYWx1ZSBpbiBtb2RlbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2FzIGJlaW5nIHN0b3JlZCBpbiBkYXRhIHBhdHRlcm4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV4IDogZGF0YSBwYXR0ZXJuIGlzIHRleHR7OTk5LTk5LTk5OTl9IGFuZCB2YWx1ZSBpcyAxMjMtNDUtNjc4OQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gMSkgZm9yIG1vYmlsZSBmb3JtcyByYXdWYWx1ZSBiZWluZyBzdG9yZWQgaXMgMTIzNDU2Nzg5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAyKSBmb3IgZm9ybXNldCByYXdWYWx1ZSBiZWluZyBzdG9yZWQgd2FzIDEyMy00NS02Nzg5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbiBjYXNlIHRoZSBwYXJzZSBpcyBpbmNvcnJlY3QgYmVjYXVzZSBvZiBtaXNtYXRjaCBpbiBkYXRhIHBhdHRlcm4gYW5kIHByZWZpbGxWYWx1ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlbiB0aGVyZSB3aWxsIGJlIGRhdGEgbG9zcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIGlmIHRoZXJlIGlzIGFueSBleGNlcHRpb24gd2hpbGUgcGFyc2luZyB0aGVuIG9yaWdpbmFsIHZhbHVlIGlzIHN0b3JlZC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZUZpbGxWYWx1ZSA9IHhmYWxpYi51dC5QaWN0dXJlRm10LnBhcnNlKHByZUZpbGxWYWx1ZSwgZGF0YVBhdHRlcm4pOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdGUgOiBudW1lcmljIHBhcnNlIGRvZXNuJ3QgdGhyb3csIGJ1dCByZXR1cm5zIDAsIG5lZWQgdG8gdGFrZSBjYXJlIG9mIGl0IGxhdGVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG11c3Qgc2V0IHZhbHVlIHRvIHByZXNlcnZlIHByZWZpbGwgZGF0YSBvbiBzdWJtaXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NldFZhbHVlKG5vZGUudGV4dENvbnRlbnQsIHRydWUpOyAgLy8gbmVlZCB0byBzZXQgdmFsdWUgd2l0aG91dCB0eXBlIGNoZWNraW5nLCBmb3IgbnVtZXJpYyBmaWVsZCBkb2Vzbid0IGFsbG93IG5vbiBudW1lcmljIGNoYXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybigieGZhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIucmVzb2x2ZU1lc3NhZ2UoeGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDIxIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRhUGF0dGVybiwgbm9kZS50ZXh0Q29udGVudCwgZV0pKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NldFZhbHVlKG5vZGUudGV4dENvbnRlbnQsIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybigieGZhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5yZXNvbHZlTWVzc2FnZSh4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMjIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0YVBhdHRlcm4sIG5vZGUudGV4dENvbnRlbnRdKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnVnIGluIHBpY3R1cmVmbXQgbnVtZXJpYyBwYXJzZSA6IGNhbnQgcGFyc2UgcGF0dGVybnMgd2l0aCAoIG9yICksIGJ1dCBkb2VzbnQgdGhyb3csIHJldHVybnMgMCBpbnN0ZWFkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoXy5pc1N0cmluZyhkYXRhUGF0dGVybikgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhUGF0dGVybi50cmltKCkuaW5kZXhPZigibnVtIikgPT09IDAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocHJlRmlsbFZhbHVlID09IDAgJiYgcGFyc2VGbG9hdChub2RlLnRleHRDb250ZW50LnJlcGxhY2UoL1teMC05XS9nLCAiIikpICE9PSAwKSkgeyAvLyBoYWNrOiBpZiBwYXJzZXIgcmV0dXJucyAwLCBhbmQgaW5wdXQgaGFzIGFueSBub24gemVybyBkaWdpdCB0aGVuIHBhcnNpbmcgZmFpbGVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2V0VmFsdWUobm9kZS50ZXh0Q29udGVudCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oInhmYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5yZXNvbHZlTWVzc2FnZSh4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMjMiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRhUGF0dGVybiwgbm9kZS50ZXh0Q29udGVudF0pKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2V0VmFsdWUocHJlRmlsbFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2V0RGF0YSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEdlbmVyYXRlcyB0aGUgWE1MIGJ5IGFwcGVuZGluZyB0aGUgZWxlbWVudHMgaW4gdGhlIHJvb3ROb2RlCiAgICAgICAgICogQHBhcmFtIHJvb3ROb2RlIFRoZSByb290Tm9kZSBvZiB0aGUgeG1sLiBHZW5lcmFsbHkgdGhlIGVsZW1lbnQgdGhhdCBtYXBzIHRvIHRoZSByb290IG9mIHRoZSBmb3JtCiAgICAgICAgICogQHBhcmFtIGNvbnRleHROb2RlIEN1cnJlbnQgTm9kZSB3aGVyZSB0byBpbnNlcnQgdGhlIGVsZW1lbnRzIGluIGNhc2Ugb2YgcmVsYXRpdmUgYmluZGluZ3MKICAgICAgICAgKi8KICAgICAgICBnZW5lcmF0ZURhdGFYTUw6IGZ1bmN0aW9uIChyb290Tm9kZSwgY29udGV4dE5vZGUpIHsKICAgICAgICAgICAgaWYodGhpcy5oYXNEYXRhQmluZGluZygpKSB7CiAgICAgICAgICAgICAgICB2YXIgeHBhdGggPSB0aGlzLl9nZXRYcGF0aEZyb21CaW5kUmVmKCksCiAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmVYUGF0aCwgbm9kZUl0ZXIsIG5vZGVMaXN0ID0gW10sIHJlc3VsdCwgbm9kZTsKICAgICAgICAgICAgICAgIGlmKHhwYXRoICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudCA9IHhwYXRoLnJlbGF0aXZlID09PSBmYWxzZSB8fCB4cGF0aC5yZWxhdGl2ZSA9PT0gImdsb2JhbCIgPyByb290Tm9kZSA6IGNvbnRleHROb2RlOwogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSB4ZmFsaWIudXQuWE1MVXRpbHMuY3JlYXRlRWxlbWVudHNGcm9tWFBhdGgoeHBhdGguYmluZFJlZiwgZWxlbWVudCwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2FwcGVuZFZhbHVlSW5YTUxFbGVtZW50KGVsZW1lbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2FwcGVuZFZhbHVlSW5YTUxFbGVtZW50OiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICBpZihlbGVtZW50ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGVsZW1lbnQudGV4dENvbnRlbnQgPSB0aGlzLl9nZXRWYWx1ZShudWxsLCB0cnVlKTsgLy8gTEMtMzkxMTE4MCA6IG5lZWQgdG8gY2lyY3VtdmVudCB0eXBlIGNoZWNrIHRvIHByZXNlcnZlIGRhdGEKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogZXhlY3V0ZXMgcHJlc3VibWl0IGV2ZW50IHNjcmlwdHMgYW5kIGNoZWNrIGZvciBjYW5jZWxBY3Rpb24gcHJvcGVydHkKICAgICAgICAgKiByZXR1cm4gZmFsc2UgaWYgdGhlIGNhbmNlbEFjdGlvbiBwcm9wZXJ0eSBpcyBzZXQgdHJ1ZQogICAgICAgICAqLwogICAgICAgIF9wcmVTdWJtaXRFdmVudEhhbmRsZXIgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmICh0aGlzLm1vRXZlbnRzWyIkZm9ybXByZVN1Ym1pdCJdICYmIHRoaXMubW9FdmVudHNbIiRmb3JtcHJlU3VibWl0Il0ubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgdGhpcy5tb0V2ZW50c1siJGZvcm1wcmVTdWJtaXQiXVswXS5leGVjdXRlKHRoaXMsICIkZm9ybXByZVN1Ym1pdCIpOwogICAgICAgICAgICAgICAgLy8gSWYgYSBzY3JpcHQgaW52b2tlZCBieSB0aGUgcHJlLXN1Ym1pdCBldmVudCBzZXRzICRldmVudC5jYW5jZWxBY3Rpb24sIHRoZSBzdWJtaXQgYWN0aW9uIGRvZXMgbm90IHRha2UgcGxhY2UKICAgICAgICAgICAgICAgIGlmICh0aGlzLl94ZmEoKS5ldmVudC5jYW5jZWxBY3Rpb24pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgIH0pOwoKICAgIEZpZWxkLmRlZmluZVByb3BzKHsKICAgICAgICAibG9jYWxlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGlmICghdGhpcy5fbG9jYWxlKQogICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvY2FsZSA9IHRoaXMuX2dldExvY2FsZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvY2FsZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJtdWx0aUxpbmUiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICh0aGlzLnVpLm9uZU9mQ2hpbGQubXVsdGlMaW5lID09IDEpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInJhd1ZhbHVlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBjdXJyZW50Tm9kZSA9IHRoaXMuX3hmYSgpLm1vQ2FsY3VsYXRlRXZlbnROb2RlOwogICAgICAgICAgICAgICAgaWYgKGN1cnJlbnROb2RlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZERlcGVuZGFudChjdXJyZW50Tm9kZSk7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudE5vZGUub24oeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50Lk9CSkVDVF9ERVNUUk9ZRUQsIHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldFZhbHVlKG51bGwsIHRoaXMudmFsdWUub25lT2ZDaGlsZC5nZXRBdHRyaWJ1dGUoImNvbnRlbnRUeXBlIikgPT09ICJ0ZXh0L2h0bWwiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAob1ZhbHVlKSB7CiAgICAgICAgICAgICAgICBvVmFsdWUgPSB0aGlzLnZhbGlkYXRlSW5wdXQob1ZhbHVlLCAic3RyaW5nIik7CiAgICAgICAgICAgICAgICBpZiAodGhpcy52YWx1ZS5vbmVPZkNoaWxkLm1heENoYXJzICYmIHRoaXMudmFsdWUub25lT2ZDaGlsZC5tYXhDaGFycyAhPT0gIjAiICYmIG9WYWx1ZSAmJiB0aGlzLnZhbHVlLm9uZU9mQ2hpbGQubWF4Q2hhcnMgPCBvVmFsdWUubGVuZ3RoKQogICAgICAgICAgICAgICAgICAgIG9WYWx1ZSA9IG9WYWx1ZS5zbGljZSgwLCB0aGlzLnZhbHVlLm9uZU9mQ2hpbGQubWF4Q2hhcnMpOwogICAgICAgICAgICAgICAgdmFyIG9sZHZhbCA9IHRoaXMuX2dldFZhbHVlKCk7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc2V0VmFsdWUob1ZhbHVlLCB0aGlzLnZhbHVlLm9uZU9mQ2hpbGQuZ2V0QXR0cmlidXRlKCJjb250ZW50VHlwZSIpID09PSAidGV4dC9odG1sIikpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVEZXBlbmRhbnRzKCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkucXVldWVWYWxpZGF0ZUV2ZW50KHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG9sZHZhbCAhPSBvVmFsdWUpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2hvd0Rpc3BsYXlGb3JtYXQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICAiZm9udCI6IHsKICAgICAgICAgICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICB0aGlzLmdldEVsZW1lbnQoImZvbnQiLDApOwogICAgICAgICAgICAgICAgICAgIH0gLAogICAgICAgICAgICAgICAgICAgIHNldCA6ZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsImZvbnQiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAiZm9udENvbG9yIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZm9udCIsIDApLmdldEVsZW1lbnQoImZpbGwiLCAwKS5nZXRFbGVtZW50KCJjb2xvciIsIDApLnZhbHVlOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuZ2V0RWxlbWVudCgiZm9udCIsIDApLmdldEVsZW1lbnQoImZpbGwiLCAwKS5nZXRFbGVtZW50KCJjb2xvciIsIDApLnZhbHVlID0gdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAidmFsdWUiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiAgdGhpcy5nZXRFbGVtZW50KCJ2YWx1ZSIsMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKCkge30KICAgICAgICB9LAoKICAgICAgICAvL1RPRE86IE5vdGU6IEJlbG93IGhhbmRsaW5nIHNob3VsZCBoYW5kbGUgYm90aCBtdWx0aVNlbGVjdCBhbmQgc2luZ2xlIFNlbGVjdHMuIE5lZWQgdG8gdmVyaWZ5IHRoaXMuCiAgICAgICAgInNlbGVjdGVkSW5kZXgiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5yYXdWYWx1ZTsKICAgICAgICAgICAgICAgIHZhciBpdGVtU2l6ZSA9IHRoaXMubGVuZ3RoOwogICAgICAgICAgICAgICAgaWYgKGl0ZW1TaXplID49IDApIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZW1TaXplOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkID0gdGhpcy5nZXRJdGVtU3RhdGUoaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAtMTsgICAvL2RlZmF1bHQgLTEKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAobkluZGV4KSB7CiAgICAgICAgICAgICAgICBuSW5kZXggPSB0aGlzLnZhbGlkYXRlSW5wdXQobkluZGV4LCAic3RyaW5nIik7CiAgICAgICAgICAgICAgICB0aGlzLl9zZXRWYWx1ZShudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMuc2V0SXRlbVN0YXRlKG5JbmRleCwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAibGVuZ3RoIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBpdGVtcyA9ICh0aGlzLl9nZXRTYXZlSXRlbXMoZmFsc2UpIHx8IHRoaXMuX2dldERpc3BsYXlJdGVtcyhmYWxzZSkpOwogICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW1zID8gaXRlbXMubW9DaGlsZE5vZGVzLmxlbmd0aCA6IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAicGFyZW50U3ViZm9ybSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgdGVtcCA9IHRoaXMucGFyZW50OwogICAgICAgICAgICAgICAgd2hpbGUgKHRlbXAgJiYgdGVtcC5jbGFzc05hbWUgIT09ICJzdWJmb3JtIikKICAgICAgICAgICAgICAgICAgICB0ZW1wID0gdGVtcC5wYXJlbnQ7CiAgICAgICAgICAgICAgICByZXR1cm4gdGVtcDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJtYW5kYXRvcnkiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JFbHNlKHRoaXMudmFsaWRhdGUubnVsbFRlc3QsIHRoaXMuX2RlZmF1bHRzLnZhbGlkYXRlLm51bGxUZXN0KTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLnZhbGlkYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy52YWxpZGF0ZS5udWxsVGVzdCA9IHZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgIm1hbmRhdG9yeU1lc3NhZ2UiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5fZ2V0TWFuZGF0b3J5TWVzc2FnZSh0aGlzKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICB2YXIgbm9kZXMgPSB0aGlzLnZhbGlkYXRlLm1lc3NhZ2Uubm9kZXM7CiAgICAgICAgICAgICAgICBpZiAobm9kZXMubmFtZWRJdGVtKCJudWxsVGVzdCIpID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSB0aGlzLl94ZmEoKS5mb3JtLmNyZWF0ZU5vZGUoInRleHQiLCAibnVsbFRlc3QiKTsKICAgICAgICAgICAgICAgICAgICBub2Rlcy5hcHBlbmQobm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLnZhbGlkYXRlLm1lc3NhZ2UubnVsbFRlc3QudmFsdWUgPSB2YWw7CiAgICAgICAgICAgICAgICB0aGlzLmV4ZWNWYWxpZGF0ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImZvcm1hdE1lc3NhZ2UiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIG1zZyA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMudmFsaWRhdGUsICJtZXNzYWdlLmZvcm1hdFRlc3QiLCB0aGlzLl9kZWZhdWx0cy52YWxpZGF0ZS5tZXNzYWdlLmRlZmF1bHRNZXNzYWdlKTsKICAgICAgICAgICAgICAgIHJldHVybiBtc2cudmFsdWU7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgdmFyIG5vZGVzID0gdGhpcy52YWxpZGF0ZS5tZXNzYWdlLm5vZGVzOwogICAgICAgICAgICAgICAgaWYgKG5vZGVzLm5hbWVkSXRlbSgiZm9ybWF0VGVzdCIpID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSB0aGlzLl94ZmEoKS5mb3JtLmNyZWF0ZU5vZGUoInRleHQiLCAiZm9ybWF0VGVzdCIpOwogICAgICAgICAgICAgICAgICAgIG5vZGVzLmFwcGVuZChub2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMudmFsaWRhdGUubWVzc2FnZS5mb3JtYXRUZXN0LnZhbHVlID0gdmFsOwogICAgICAgICAgICAgICAgdGhpcy5leGVjVmFsaWRhdGUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJmb3JtYXR0ZWRWYWx1ZSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZm9ybWF0VmFsdWUodGhpcy5fZ2V0VmFsdWUoKSwgdGhpcy5qc29uTW9kZWwuZXh0cmFzLmRpc3BsYXlQYXR0ZXJuRXgsIHRydWUpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgIHRoaXMucmF3VmFsdWUgPSB0aGlzLl9wYXJzZVZhbHVlKHZhbCwgdGhpcy5qc29uTW9kZWwuZXh0cmFzLmRpc3BsYXlQYXR0ZXJuRXgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImlzTnVsbCI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fZ2V0VmFsdWUoKSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIGVsc2UgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAiZWRpdFZhbHVlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9mb3JtYXRWYWx1ZSh0aGlzLl9nZXRWYWx1ZSgpLCB0aGlzLmpzb25Nb2RlbC5leHRyYXMuZWRpdFBhdHRlcm5FeCwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICB1aTogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInVpIiwgMCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAidWkiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJpdGVtcyIsIDApOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImNhbGN1bGF0ZSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjYWxjdWxhdGUiLCAwKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJmb3JtYXQiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZm9ybWF0IiwgMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoKICAgIH0pOwoKICAgIEZpZWxkLmFkZE1peGlucyhbCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRBc3Npc3QsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRDYXB0aW9uLAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkUHJlc2VuY2UsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRYWVdILAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkRmlsbENvbG9yLAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQm9yZGVyLAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQm9yZGVyQ29sb3IsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRCb3JkZXJXaWR0aCwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFBhcmEsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRNYXJnaW4KICAgIF0pOwoKfSkoXywgeGZhbGliKTsKCgoKCgoKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5EcmF3CiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Ob2RlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgRHJhdyBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24gKF8sIHhmYWxpYiwgJCkgewogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3IERyYXcgY2xhc3MKICAgICAqCiAgICAgKiBAY29uc3RydWN0b3IKICAgICAqIEBwYXJhbSB7c3RyaW5nfQogICAgICogICAgICAgICAgICBuYW1lIHRoZSBuYW1lIG9mIHRoZSBEcmF3CiAgICAgKiBAZXh0ZW5kcyBjb20uYWRvYmUueGZhLnNjcmlwdGluZy5Ob2RlCiAgICAgKi8KICAgIHZhciBEcmF3ID0geGZhbGliLnNjcmlwdC5EcmF3ID0geGZhbGliLnNjcmlwdC5FdmVudENvbnRhaW5lck5vZGUuZXh0ZW5kKHsKCiAgICAgICAgX3NldFZhbHVlOiB4ZmFsaWIuc2NyaXB0LkZpZWxkLnByb3RvdHlwZS5fc2V0VmFsdWUsCgogICAgICAgIF9nZXRWYWx1ZTogeGZhbGliLnNjcmlwdC5GaWVsZC5wcm90b3R5cGUuX2dldFZhbHVlLAoKICAgICAgICBfZ2V0RmllbGRCeUlkOiBmdW5jdGlvbiAoZmllbGRJZCkgewoKICAgICAgICAgICAgaWYgKHRoaXMuX3hmYSgpLl94ZmFUZW1wbGF0ZUNhY2hlLmlkTWFwLmhhc093blByb3BlcnR5KGZpZWxkSWQpKSB7CiAgICAgICAgICAgICAgICAvL3h0ZyB1c2VzIGp1c3QgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGZpbmQgdGhlIGFjdHVhbCBjb250ZXh0IG5vZGUKICAgICAgICAgICAgICAgIC8vdGhpcyBpcyBhIHF1aWNrIGFuZCBkaXJ0eSB3YXkgdG8gZW5zdXJlIGluZGV4IGFmZmluaXR5CiAgICAgICAgICAgICAgICAvL2p1c3QgdG8gYmUgaW4gc3luYyB3aXRoIFhURywgSSBhbSB1c2luZyB0aGUgc2FtZSBpbXBsZW1lbnRhdGlvbiBhcyBYRkFMYXlvdXRUZXh0UmVzb2x2ZXIgY2xhc3MKICAgICAgICAgICAgICAgIHZhciBmaWVsZCA9IHRoaXMuX3hmYSgpLl94ZmFUZW1wbGF0ZUNhY2hlLmlkTWFwW2ZpZWxkSWRdOwogICAgICAgICAgICAgICAgdmFyIHJlc29sdmVkRmllbGQgPSBudWxsOwoKICAgICAgICAgICAgICAgIHZhciBiUXVpdCA9IGZhbHNlOwogICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gMDsKICAgICAgICAgICAgICAgIC8vVE9ETyA6IENhbiB3ZSBoYXZlIHByb2JsZW0gaW4gY29udGV4dCBvYmplY3Qgc2V0dGluZyB3aGlsZSBkb2luZyBpbmRleCBhZmZpbmUgcmVzb2x1dGlvbnMgPwogICAgICAgICAgICAgICAgd2hpbGUgKCFiUXVpdCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgc29tID0gZmllbGQubmFtZSArICdbJyArIGluZGV4ICsgJ10nOwogICAgICAgICAgICAgICAgICAgIC8vdGhpcyB3aWxsIGJlIGRvbmUgaW4gdGhlIGNvbnRleHQgb2YgX3Jlc29sdmVGbG9hdGluZ0ZpZWxkCiAgICAgICAgICAgICAgICAgICAgdmFyIHByb2JGaWVsZCA9IHRoaXMucmVzb2x2ZU5vZGUoc29tKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIV8uaXNFbXB0eShwcm9iRmllbGQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9iRmllbGQuanNvbk1vZGVsLmlkID09PSBmaWVsZC5qc29uTW9kZWwuaWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJRdWl0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVkRmllbGQgPSBwcm9iRmllbGQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2tlZXAgbG9va2luZwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgeyAvL3RoaXMgd2lsbCBub3QgYmUgdXNlZCB2ZXJ5IG9mdGVuIGluIGZhY3QgSSBrZXB0IGl0IGp1c3QgZm9yIGNvbXBsZXRlbmVzcy4uLgogICAgICAgICAgICAgICAgICAgICAgICBiUXVpdCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlTmFtZSA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vdmR1YSBzdWdnZXN0cyB0byB1c2UgeGZhLmZvcm0uLm5vZGVOYW1lIGluc3RlYWQgb2YgX2ZpbHRlck5vZGVzLgogICAgICAgICAgICAgICAgICAgICAgICAvL2l0IHRha2VzIGNhcmUgb2YgaW5kZXggYWZmaW5pdHkgYWxzbyB3aGljaCBpcyBhIGJpdCB1bnByZWRpY3RhYmxlCiAgICAgICAgICAgICAgICAgICAgICAgIC8vTGV0J3MgdHJ5IHRoaXMgaW4gbmV4dCBpdGVyYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRleHROb2RlcyA9IHRoaXMuX3hmYSgpLmZvcm0uX2ZpbHRlck5vZGVzKGZ1bmN0aW9uIChuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbi5uYW1lID09IG5vZGVOYW1lOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvY2N1cnJlbmNlVG9Mb29rRm9yID0gMDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29udGV4dE5vZGVzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29udGV4dE5vZGVzLml0ZW0oaSkgPT0gdGhpcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jY3VycmVuY2VUb0xvb2tGb3IgPSBpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmxvYXRpbmdGaWVsZE5vZGVzID0gdGhpcy5feGZhKCkuZm9ybS5fZmlsdGVyTm9kZXMoZnVuY3Rpb24gKG4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuLm5hbWUgPT0gZmllbGQubmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2NjdXJyZW5jZSA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmb3VuZEF0TGVhc3RPbmVNYXRjaCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXhPZkZpcnN0Rm91bmQgPSAwOwoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBmbG9hdGluZ0ZpZWxkTm9kZXMubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcm9iRmllbGQgPSBmbG9hdGluZ0ZpZWxkTm9kZXMuaXRlbShqKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9iRmllbGQuanNvbk1vZGVsLmlkID09IGZpZWxkLmpzb25Nb2RlbC5pZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZm91bmRBdExlYXN0T25lTWF0Y2gpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4T2ZGaXJzdEZvdW5kID0gajsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3VuZEF0TGVhc3RPbmVNYXRjaCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9jY3VycmVuY2VUb0xvb2tGb3IgPT0gb2NjdXJyZW5jZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByb2JGaWVsZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvY2N1cnJlbmNlKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3VuZEF0TGVhc3RPbmVNYXRjaCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmbG9hdGluZ0ZpZWxkTm9kZXMuaXRlbShpbmRleE9mRmlyc3RGb3VuZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGluZGV4Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZWRGaWVsZDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUpzb25EaWZmOiBmdW5jdGlvbiAoZGlmZl9sZXZlbCkgewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLnN0cmlwT3JDYWxsLmNhbGwodGhpcywgZGlmZl9sZXZlbCA9PT0gMiwgeGZhbGliLnNjcmlwdC5Ob2RlLnByb3RvdHlwZS5fY29tcHV0ZUpzb25EaWZmLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIHBsYXlKc29uIDogZnVuY3Rpb24ocEpzb25Nb2RlbCkgewogICAgICAgICAgICAvL0RvIG5vdCBkbyBhbnkgcGxheUpzb24gZm9yIGRyYXcgY2hpbGRyZW4uIEl0IHNob3VsZCBub3QgaW1wYWN0IGZsb2F0aW5nIGZpZWxkcy4KICAgICAgICAgICAgeGZhbGliLnNjcmlwdC5Ob2RlLnByb3RvdHlwZS5wbGF5SnNvbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIF9wbGF5RGF0YVhNTDogZnVuY3Rpb24gKCkgewoKICAgICAgICB9LAoKICAgICAgICBnZW5lcmF0ZURhdGFYTUw6IGZ1bmN0aW9uIChyb290Tm9kZSwgY29udGV4dE5vZGUpIHsKCiAgICAgICAgfSwKCiAgICAgICAgX3Jlc29sdmVGbG9hdGluZ0ZpZWxkOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vQ2FuIHdlIHNvbWVob3cgc3RvcmUgZW1iZWRzIGFuZCBodG1sIHRleHQgaW4gRHJhdyBvYmplY3QgYW5kIGNvbXB1dGUgaXQgb3ZlciBhbmQgb3ZlciBhZ2FpbgogICAgICAgICAgICAvL21heSB3ZSBuZWVkIGFub3RoZXIgTm9kZVZhbHVlIHR5cGUgdG8gaGFuZGxlIGl0Pz8/PwoKICAgICAgICAgICAgaWYgKHRoaXMudmFsdWUpIHsKICAgICAgICAgICAgICAgIHZhciBjb250ZW50ID0gdGhpcy52YWx1ZS5vbmVPZkNoaWxkOwogICAgICAgICAgICAgICAgaWYgKGNvbnRlbnQuZ2V0QXR0cmlidXRlKCdjb250ZW50VHlwZScpID09PSAndGV4dC9odG1sJykgewogICAgICAgICAgICAgICAgICAgIGlmKF8uaXNOdWxsKGNvbnRlbnQuX29yaWdUbXBsdFZhbCkpewogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Ll9vcmlnVG1wbHRWYWwgPSBjb250ZW50Lmpzb25WYWx1ZTsgLy8gc2F2ZSBvcmlnaW5hbCB0ZW1wbGF0ZSBpbmZvIGNvbnRhaW5pbmcgdGhlIGVtYmVkIHRhZ3MKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdmFyIGlzVGV4dEVtYmVkcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICB0aGF0ID0gdGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgaHRtbFRleHQgPSBjb250ZW50Ll9vcmlnVG1wbHRWYWw7CiAgICAgICAgICAgICAgICAgICAgaHRtbFRleHQgPSBodG1sVGV4dC5yZXBsYWNlQWxsKCI8L2JyPiIsIiIpOwogICAgICAgICAgICAgICAgICAgIHZhciAkaW50ZXJuYWxIVE1MID0gJCgnPHNwYW4+JyArIGh0bWxUZXh0ICsgJzwvc3Bhbj4nKTsKICAgICAgICAgICAgICAgICAgICAvL2NoYW5nZSB0aGUgdG9wIGxldmVsIGVsZW1lbnQgdG8gc3BhbiB0byB3cmFwIHVwIGFsbCB0aGUgPHA+LCBiZWNhdXNlIGl0IHdpbGwgY2F1c2UgdW5uZWNlc3NhcnkgcGFyYWdyYXBoIGJyZWFrCgogICAgICAgICAgICAgICAgICAgIC8vbm8gbnVsbCBjaGVjayBiZWNhdXNlIGpRdWVyeSBpcyBjb29sIQogICAgICAgICAgICAgICAgICAgICRpbnRlcm5hbEhUTUwuZmluZCgicCIpLmVxKDApLmNzcygnZGlzcGxheScsICdpbmxpbmUnKTsKCiAgICAgICAgICAgICAgICAgICAgJGludGVybmFsSFRNTC5maW5kKCdbeGZhXFw6ZW1iZWRdJykuZWFjaChmdW5jdGlvbiAoaW5kZXgsIHNwYW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXNUZXh0RW1iZWRzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyICRzcGFuID0gJChzcGFuKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVtYmVkID0gJHNwYW4uYXR0cigneGZhOmVtYmVkJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbWJlZFR5cGUgPSAkc3Bhbi5hdHRyKCd4ZmE6ZW1iZWRUeXBlJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbWJlZE1vZGUgPSAkc3Bhbi5hdHRyKCd4ZmE6ZW1iZWRNb2RlJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbWJlZCAmJiBlbWJlZC5sZW5ndGggPiAxICYmIGVtYmVkWzBdID09ICcjJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1iZWQgPSBlbWJlZC5zdWJzdHIoMSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc29sdmUgTm9kZSB3aWxsIHRha2UgY2FyZSBvZiBpbmRleCBhZmZpbml0eSBoZXJlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmllbGQgPSAoZW1iZWRUeXBlID09ICd1cmknKSA/IHRoYXQuX2dldEZpZWxkQnlJZChlbWJlZCkgOiB0aGF0LnJlc29sdmVOb2RlKGVtYmVkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbWJlZE1vZGUgPT09ICdyYXcnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZC5yYXdWYWx1ZSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNwYW4ucmVwbGFjZVdpdGgoZmllbGQucmF3VmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc3Bhbi5yZXBsYWNlV2l0aCgkLnBhcnNlSFRNTCh4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZW5jb2RlU2NyaXB0YWJsZVRhZ3MoZmllbGQucmF3VmFsdWUudG9TdHJpbmcoKSkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc3Bhbi5yZXBsYWNlV2l0aCh4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZW5jb2RlU2NyaXB0YWJsZVRhZ3MoZmllbGQuZm9ybWF0dGVkVmFsdWUudG9TdHJpbmcoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5feGZhKCkuTG9nZ2VyLmRlYnVnKCJ4ZmEiLCAicmVmZXJyZWQgZmllbGQgd2l0aCBpZCAiICsgZW1iZWQgKyAiIGRvZXNuJ3QgZXhpc3QuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNwYW4ucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll94ZmEoKS5Mb2dnZXIuZGVidWcoInhmYSIsICJyZWZlcnJlZCBmaWVsZCB3aXRoIGludmFsaWQgaWQgIiArIGVtYmVkICsgIiBkb2Vzbid0IGV4aXN0LiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNwYW4ucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgLy9pc1RleHRFbWJlZHMgaXMgc2V0IHRvIHRydWUgaWYgdGhlcmUgaXMgYW55IGVtYmVkZGVkIHRleHQgZmllbGQuCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzVGV4dEVtYmVkcykgewogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Lmpzb25WYWx1ZSA9ICI8c3Bhbj4iICsgJGludGVybmFsSFRNTC5odG1sKCkgKyAiPC9zcGFuPiI7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHBhZ2VzIG1heSBub3QgeWV0IGJlIHJlbmRlcmVkLCBidXQgaW5pdGlhbGl6ZSBjYWxsZWQgZHVlIHRvICJpbml0aWFsIGNvdW50IiBvZiBycHQuIFNGCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlY29yZCB1cGRhdGVkIHZhbHVlIHRvIGJlIGFwcGxpZWQgaW4gX3N5bmNGb3JtTm9kZVRvSHRtbCBkdXJpbmcgcGcuIHJlbmRlcgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHNjb3BlbGVzczogZnVuY3Rpb24gKCkgeyAvL1tMQy04ODAxXSBET00gUHJvcGVydGllcyBvZiBkcmF3IGdldHMgaW5jb3JyZWN0bHkgYXR0YWNoZWQKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIF9ldmVudEhhbmRsZXI6IGZ1bmN0aW9uIChldmVudE5hbWUpIHsKICAgICAgICAgICAgLy93YW50IHRvIGhhbmRsZSBvbmx5IGNhbGN1bGF0ZSBldmVudCB0aGF0IHRvbyBpbiBjYXNlIG9mIGRyYXcgdGV4dAogICAgICAgICAgICBpZiAodGhpcy51aSAmJiB0aGlzLnVpLm9uZU9mQ2hpbGQgJiYgdGhpcy51aS5vbmVPZkNoaWxkLmNsYXNzTmFtZSA9PSAndGV4dEVkaXQnKSB7CiAgICAgICAgICAgICAgICB2YXIgclZhbHVlID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgc3dpdGNoIChldmVudE5hbWUpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJjYWxjdWxhdGUiOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl0gJiYgdGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl0ubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl1bMF0uZXhlY3V0ZSh0aGlzLCAiY2FsY3VsYXRlIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCA6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBEcmF3Ll9zdXBlci5fZXZlbnRIYW5kbGVyLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gclZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBEcmF3Ll9zdXBlci5fZXZlbnRIYW5kbGVyLmNhbGwodGhpcyk7CgogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiB0aGUgRGF0YVNPTU1hcCBhZnRlciBhZGRpbmcgYW4gZW50cnkgaW4gdGhlIG1hcCBmb3IgdGhlIG5vZGUuIFRoZSBlbnRyeSBjb250YWlucyB0aGUgdmFsdWUgb2YgdGhlIG5vZGUKICAgICAgICAgKiBhbG9uZyB3aXRoIGl0cyBEYXRhIFNPTS4gSWYgdGhlcmUgaXMgbm8gRGF0YSBTT00gdGhlbiByZXR1cm4gdGhlIHVubW9kaWZpZWQgbWFwCiAgICAgICAgICogQHBhcmFtIG1hcAogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2dldERhdGFTb21NYXA6IGZ1bmN0aW9uIChtYXApIHsKICAgICAgICAgICAgcmV0dXJuIG1hcDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBVcGRhdGUgdGhlIHZhbHVlIG9mIHRoZSBub2RlIHdpdGggdGhlIHZhbHVlIHByb3ZpZGVkIGluIHRoZSBpbnB1dCBtYXAuIFRoZSBtYXAgY29udGFpbnMgdGhlIHZhbHVlcyBvZiB0aGUgZmllbGRzCiAgICAgICAgICogbWFwcGVkIHdpdGggdGhlaXIgRGF0YVNPTS4gVGhlIGZ1bmN0aW9uIGlzIGVtcHR5IGZvciBhbGwgdGhlIG5vZGVzLCBleGNlcHQgZm9yIEZpZWxkLCBTdWJmb3JtIGFuZCBBcmVhLgogICAgICAgICAqIEBwYXJhbSBtYXAKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9yZXN0b3JlRGF0YVNvbU1hcCA6IGZ1bmN0aW9uIChtYXApIHsKCiAgICAgICAgfQogICAgfSk7CgogICAgRHJhdy5kZWZpbmVQcm9wcyh7CiAgICAgICAgInJhd1ZhbHVlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRWYWx1ZSgpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChzVmFsdWUpIHsKICAgICAgICAgICAgICAgIHZhciBvbGR2YWwgPSB0aGlzLl9nZXRWYWx1ZSgpOwogICAgICAgICAgICAgICAgc1ZhbHVlID0gdGhpcy52YWxpZGF0ZUlucHV0KHNWYWx1ZSwgInN0cmluZyIpOwogICAgICAgICAgICAgICAgdGhpcy5fc2V0VmFsdWUoc1ZhbHVlKTsKICAgICAgICAgICAgICAgIHZhciBldmVudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELCB0aGlzLCAncmF3VmFsdWUnLCBudWxsLCBzVmFsdWUpOwogICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2ZW50Lm5hbWUsIGV2ZW50KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHVpOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgidWkiLCAwKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJ1aSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImZvbnQiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICB0aGlzLmdldEVsZW1lbnQoImZvbnQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImZvbnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIHRoaXMuZ2V0RWxlbWVudCgidmFsdWUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsLCAidmFsdWUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJkZXNjIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImRlc2MiLCAwKQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgRHJhdy5hZGRNaXhpbnMoWwogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQXNzaXN0LAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQ2FwdGlvbiwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFhZV0gsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRQcmVzZW5jZSwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZEJvcmRlciwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFBhcmEsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRNYXJnaW4KICAgIF0pOwoKfSkoXywgeGZhbGliLCAkKTsKCgoKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5EYXRlVGltZUZpZWxkCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5GaWVsZAogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIERhdGUgVGltZSBGaWVsZCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBEYXRlIFRpbWUgRmllbGQgY2xhc3MKICAgICAqCiAgICAgKiBAY29uc3RydWN0b3IKICAgICAqIEBwYXJhbSB7c3RyaW5nfQogICAgICAgICogICAgICAgICAgICBuYW1lIHRoZSBuYW1lIG9mIHRoZSBGaWVsZAogICAgICogQHBhcmFtIHtzdHJpbmd9CiAgICAgICAgKiAgICAgICAgICAgIHJhd1ZhbCBpbml0aWFsIHZhbHVlIG9mIHRoZSBGaWVsZAogICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHJhd1ZhbCByZXByZXNlbnRzIHRoZSBkYXRhIHZhbHVlIGluIHRoZSBub2RlCiAgICAgKiBAZXh0ZW5kcyBjb20uYWRvYmUueGZhLnNjcmlwdGluZy5Ob2RlCiAgICAgKi8KICAgIHZhciBEYXRlVGltZUZpZWxkID0geGZhbGliLnNjcmlwdC5EYXRlVGltZUZpZWxkID0geGZhbGliLnNjcmlwdC5GaWVsZC5leHRlbmQoewogICAgICAgIF9nZXREZWZhdWx0UGljdHVyZUNsYXVzZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIC8vd2F0c29uIGJ1ZyMzNjcyMzY0IGFuZCAzNjcyMzY3LgogICAgICAgICAgICAvL1N0YXJ0IHJlYWRpbmcgY2FsZW5kYXIgcGljdHVyZSBmb3JtYXQgZnJvbSB0aGUgbG9jYWxlc2V0LgogICAgICAgICAgICBpZih0aGlzLnZhbHVlLm9uZU9mQ2hpbGQuY2xhc3NOYW1lID09PSAiZGF0ZSIpCiAgICAgICAgICAgICAgICByZXR1cm4gImRhdGV7Iit0aGlzLl94ZmEoKS5fZ2V0TG9jYWxlU3ltYm9scyh0aGlzLmxvY2FsZSwiZGF0ZVBhdHRlcm5zIikubWVkKyJ9IjsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0sCgogICAgICAgIF9zZXRWYWx1ZTogZnVuY3Rpb24gKHNWYWwsIHNraXBUeXBlQ2hlY2spIHsKICAgICAgICAgICAgcmV0dXJuIERhdGVUaW1lRmllbGQuX3N1cGVyLl9zZXRWYWx1ZS5jYWxsKHRoaXMsIHNWYWwsIHNraXBUeXBlQ2hlY2spOwogICAgICAgIH0sCgogICAgICAgIF9zaG93RGlzcGxheUZvcm1hdDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgZm9ybWF0dGVkVmFsdWUgPSB0aGlzLmZvcm1hdHRlZFZhbHVlLAogICAgICAgICAgICAgICAgcmF3VmFsdWUgPSB0aGlzLnJhd1ZhbHVlOwogICAgICAgICAgICAvLyBpZiBmb3JtYXR0ZWRWYWx1ZSBpcyBudWxsIHRoZW4gc2hvdyByYXdWYWx1ZSBpbiB3aWRnZXQgYWxvbmcgd2l0aCBlcnJvciBtZXNzYWdlCiAgICAgICAgICAgIGlmICghZm9ybWF0dGVkVmFsdWUpIHsKICAgICAgICAgICAgICAgIGZvcm1hdHRlZFZhbHVlID0gcmF3VmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwgdGhpcywKICAgICAgICAgICAgICAgICdyYXdWYWx1ZScsIHJhd1ZhbHVlLCBmb3JtYXR0ZWRWYWx1ZSk7CiAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsIGV2bnQpOwogICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5OdW1lcmljRmllbGQKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LkZpZWxkCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgTnVtZXJpYyBGaWVsZCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBOdW1lcmljIEZpZWxkIGNsYXNzCiAgICAgKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgRmllbGQKICAgICAqIEBwYXJhbSB7c3RyaW5nfQogICAgICAgICogICAgICAgICAgICByYXdWYWwgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgRmllbGQKICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByYXdWYWwgcmVwcmVzZW50cyB0aGUgZGF0YSB2YWx1ZSBpbiB0aGUgbm9kZQogICAgICogQGV4dGVuZHMgY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuTm9kZQogICAgICovCiAgICB2YXIgTnVtZXJpY0ZpZWxkID0geGZhbGliLnNjcmlwdC5OdW1lcmljRmllbGQgPSB4ZmFsaWIuc2NyaXB0LkZpZWxkLmV4dGVuZCh7CiAgICAgICAgIF9nZXREZWZhdWx0UGljdHVyZUNsYXVzZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiAibnVteyIrdGhpcy5feGZhKCkuX2dldExvY2FsZVN5bWJvbHModGhpcy5sb2NhbGUsIm51bWJlclBhdHRlcm5zIikubnVtZXJpYysifSI7CiAgICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5CdXR0b25GaWVsZAogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuRmllbGQKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBCdXR0b24gRmllbGQgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQQogKiAgICAgICAgICAgICAgIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJ1dHRvbkZpZWxkID0geGZhbGliLnNjcmlwdC5CdXR0b25GaWVsZCA9IHhmYWxpYi5zY3JpcHQuRmllbGQuZXh0ZW5kKHsKICAgICAgICBfY29tcHV0ZUpzb25EaWZmOiBmdW5jdGlvbiAoZGlmZl9sZXZlbCkgewogICAgICAgICAgICAvL3dlIGRvbid0IHdhbnQgYnV0dG9uIHRvIGFwcGVhciBpbiBmaW5hbCBzdWJtaXQsIGJ1dCBmb3IgcmVzdG9yZUZvcm1TdGF0ZQogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLnN0cmlwT3JDYWxsLmNhbGwodGhpcywgZGlmZl9sZXZlbCA9PT0gMiwgQnV0dG9uRmllbGQuX3N1cGVyLl9jb21wdXRlSnNvbkRpZmYsIGFyZ3VtZW50cyk7CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYik7CgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5DaGVja0J1dHRvbkZpZWxkCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5GaWVsZAogKi8KLyoqCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgQ2hlY2tCdXR0b24gRmllbGQgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQQogKiAgICAgICAgICAgICAgIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBDaGVja0J1dHRvbkZpZWxkIEZpZWxkIGNsYXNzCiAgICAgKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgRmllbGQKICAgICAqIEBwYXJhbSB7c3RyaW5nfQogICAgICAgICogICAgICAgICAgICByYXdWYWwgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgRmllbGQKICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByYXdWYWwgcmVwcmVzZW50cyB0aGUgZGF0YSB2YWx1ZSBpbiB0aGUgbm9kZQogICAgICogQGV4dGVuZHMgY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuTm9kZQogICAgICovCiAgICB2YXIgQ2hlY2tCdXR0b25GaWVsZCA9IHhmYWxpYi5zY3JpcHQuQ2hlY2tCdXR0b25GaWVsZCA9IHhmYWxpYi5zY3JpcHQuRmllbGQuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgQ2hlY2tCdXR0b25GaWVsZC5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLl9vbiA9IDA7CiAgICAgICAgICAgIHRoaXMuX29mZiA9IDE7CiAgICAgICAgICAgIHRoaXMuX25ldXRyYWwgPSAyOwogICAgICAgIH0sCgogICAgICAgIGFkZEl0ZW0gOiBmdW5jdGlvbihzRGlzcGxheVZhbCwgc1NhdmVWYWwpIHsKICAgICAgICAgICAgaWYgKHRoaXMubGVuZ3RoID09IHRoaXMuX2dldE1heEl0ZW1zKCkpCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIENoZWNrQnV0dG9uRmllbGQuX3N1cGVyLmFkZEl0ZW0uY2FsbCh0aGlzLCBzRGlzcGxheVZhbCwgc1NhdmVWYWwpOwogICAgICAgIH0sCgogICAgICAgIF9nZXRNYXhJdGVtcyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hbGxvd05ldXRyYWwoKSA/IDMgOiAyOwogICAgICAgIH0sCgogICAgICAgIF9hbGxvd05ldXRyYWwgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy51aS5vbmVPZkNoaWxkLmFsbG93TmV1dHJhbCA9PSAxID8gdHJ1ZSA6IGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVEZXBlbmRhbnRzIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIENoZWNrQnV0dG9uRmllbGQuX3N1cGVyLl9oYW5kbGVEZXBlbmRhbnRzLmNhbGwodGhpcyk7CiAgICAgICAgICAgIGlmICh0aGlzLnBhcmVudC5faXNFeGNsdXNpb25Hcm91cCgpKSB7CiAgICAgICAgICAgICAgICB0aGlzLnBhcmVudC5faGFuZGxlU2VsZWN0Q2hpbGQodGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sIHhmYWxpYik7Ci8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LkNob2ljZUxpc3RGaWVsZAogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuRmllbGQKICovCi8qKgogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIENob2ljZUxpc3QgRmllbGQgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQQogKiAgICAgICAgICAgICAgIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgoKKGZ1bmN0aW9uKF8sIHhmYWxpYiwgJCl7CiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgQ2hvaWNlTGlzdCBGaWVsZCBjbGFzcwogICAgICoKICAgICAqIEBjb25zdHJ1Y3RvcgogICAgICogQHBhcmFtIHtzdHJpbmd9CiAgICAgICAgKiAgICAgICAgICAgIG5hbWUgdGhlIG5hbWUgb2YgdGhlIEZpZWxkCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAqICAgICAgICAgICAgcmF3VmFsIGluaXRpYWwgdmFsdWUgb2YgdGhlIEZpZWxkCiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcmF3VmFsIHJlcHJlc2VudHMgdGhlIGRhdGEgdmFsdWUgaW4gdGhlIG5vZGUKICAgICAqIEBleHRlbmRzIGNvbS5hZG9iZS54ZmEuc2NyaXB0aW5nLk5vZGUKICAgICAqLwogICAgdmFyIENob2ljZUxpc3RGaWVsZCA9IHhmYWxpYi5zY3JpcHQuQ2hvaWNlTGlzdEZpZWxkID0geGZhbGliLnNjcmlwdC5GaWVsZC5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBDaG9pY2VMaXN0RmllbGQuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgLy8gdG8gaGFuZGxlIHRoZSBzY2VuYXJpbyB3aGVyZSBiaW5kUmVmIGl0ZW1zIHdlcmUgbm90IGdldHRpbmcgcG9wdWxhdGVkIG9uIGFkZGluZyBuZXcgaW5zdGFuY2UKICAgICAgICAgICAgaWYgKHRoaXMuZ2V0RWxlbWVudCgiI2JpbmRJdGVtcyIpICYmIHhmYWxpYi5ydW50aW1lLnJlbmRlckNvbnRleHQuZGF0YSkgewogICAgICAgICAgICAgICAgdmFyIHByZWZpbGxYbWxEb2MgPSB4ZmFsaWIudXQuWE1MVXRpbHMuZ2V0WEZBUm9vdEZvcm1FbGVtZW50RnJvbVhNTCgkLnBhcnNlWE1MKHhmYWxpYi5ydW50aW1lLnJlbmRlckNvbnRleHQuZGF0YSkpOwogICAgICAgICAgICAgICAgdGhpcy5fcGxheUl0ZW1zKHByZWZpbGxYbWxEb2MsIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2NvbnZlcnRWYWx1ZVRvWG1sOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICBpZih2YWwgPT0gbnVsbCB8fCB2YWwubGVuZ3RoID09IDApCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbAogICAgICAgICAgIHZhciB4bWwgPSAiPCIrdGhpcy5uYW1lKyI+IgogICAgICAgICAgIF8uZWFjaCgodmFsKyIiKS5zcGxpdCgiXG4iKSxmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgICAgICBpZih2YWx1ZSAmJiB2YWx1ZS5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgICAgIHhtbCArPSI8dmFsdWU+Iit2YWx1ZSsiPC92YWx1ZT4iCiAgICAgICAgICAgIH0pCiAgICAgICAgICAgIHhtbCArPSAiPC8iK3RoaXMubmFtZSsiPiIKICAgICAgICAgICAgcmV0dXJuIHhtbAogICAgICAgIH0sCgogICAgICAgIF9nZXRUZXh0OiBmdW5jdGlvbih4bWwsc2VwLCQpIHsKICAgICAgICAgICAgdmFyIHJlY1RleHQgPSBmdW5jdGlvbihvYmosYXJyKSB7CiAgICAgICAgICAgICAgICBpZihvYmouY2hpbGRyZW4oKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBvYmouY2hpbGRyZW4oKS5tYXAoZnVuY3Rpb24oaW5keCxjaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICByZWNUZXh0KCQoY2hpbGQpLGFycik7CiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYXJyLnB1c2gob2JqLnRleHQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHZhciBhcnIgPSBbXTsKICAgICAgICAgICAgcmVjVGV4dCgkKCQucGFyc2VYTUwoeG1sKSksYXJyKTsKICAgICAgICAgICAgcmV0dXJuIGFyci5qb2luKHNlcCk7CiAgICAgICAgfSwKCiAgICAgICAgX2NvbnZlcnRYbWxUb1ZhbHVlOiBmdW5jdGlvbigkeG1sKSB7CiAgICAgICAgICAgIGlmKCR4bWwgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0VGV4dCgkeG1sLCJcbiIsJCk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldFZhbHVlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IENob2ljZUxpc3RGaWVsZC5fc3VwZXIuX2dldFZhbHVlLmFwcGx5KHRoaXMsIHRoaXMuX211bHRpU2VsZWN0KCkgPyBbInRleHQveG1sIl0gOiBbXSk7CiAgICAgICAgICAgIGlmKHRoaXMuX211bHRpU2VsZWN0KCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fY29udmVydFhtbFRvVmFsdWUodmFsdWUpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUKICAgICAgICB9LAoKICAgICAgICBfc2V0VmFsdWUgOiBmdW5jdGlvbihzVmFsKSB7CiAgICAgICAgICAgIGlmKHRoaXMuX211bHRpU2VsZWN0KCkpCiAgICAgICAgICAgICAgICBzVmFsID0gdGhpcy5fY29udmVydFZhbHVlVG9YbWwoc1ZhbCk7CiAgICAgICAgICAgIHJldHVybiBDaG9pY2VMaXN0RmllbGQuX3N1cGVyLl9zZXRWYWx1ZS5hcHBseSh0aGlzLFtzVmFsXSk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0SXRlbVN0YXRlIDogZnVuY3Rpb24obkluZGV4KSB7CiAgICAgICAgICAgIGlmICh0aGlzLl9tdWx0aVNlbGVjdCgpICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgdmFyIHNhdmVWYWx1ZSA9IHRoaXMuZ2V0U2F2ZUl0ZW0obkluZGV4KTsKICAgICAgICAgICAgICAgIGlmKHNhdmVWYWx1ZSE9PSBudWxsICYmIHNhdmVWYWx1ZSE9PSB1bmRlZmluZWQpewogICAgICAgICAgICAgICAgICAgIHNhdmVWYWx1ZSA9ICIiK3NhdmVWYWx1ZTsKICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWVBcnJheSA9ICh0aGlzLnJhd1ZhbHVlICsgIiIpLnNwbGl0KCJcbiIpOwogICAgICAgICAgICAgICAgICAgIHZhciBjdXJyZW50VmFsSW5kZXggPSB0aGlzLnhmYVV0aWwoKS5kSW5kZXhPZih2YWx1ZUFycmF5LHNhdmVWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRWYWxJbmRleCA+PSAwOwogICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vIFRPRE86IHJldHVybiBudWxsIG9yIGZhbHNlCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gQ2hvaWNlTGlzdEZpZWxkLl9zdXBlci5nZXRJdGVtU3RhdGUuY2FsbCh0aGlzLCBuSW5kZXgpOwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIC8vIHJldHVybnMgYXJyYXkgb2YgaW5kaWNlcyBjb3JyZXNwb25kaW5nIHRvIHNlbGVjdGVkIHZhbHVlCiAgICAgICAgX3NlbGVjdGVkTGFzdEluZGljZXMgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIGl0ZW1TaXplID0gdGhpcy5sZW5ndGgsCiAgICAgICAgICAgICAgICBsYXN0U2VsZWN0ZWRJbmRpY2VzID0gW107CgogICAgICAgICAgICBmb3IgKHZhciBpPTA7IGk8IGl0ZW1TaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmdldEl0ZW1TdGF0ZShpKSkgewogICAgICAgICAgICAgICAgICAgIGxhc3RTZWxlY3RlZEluZGljZXMucHVzaChpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbGFzdFNlbGVjdGVkSW5kaWNlczsKICAgICAgICB9LAoKICAgICAgICAvLyByZXR1cm5zIGRpc3BsYXkgdmFsdWUgY29ycmVzcG9uZGluZyB0byBzZWxlY3RlZCB2YWx1ZQogICAgICAgIF9mb3JtYXRWYWx1ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgbGFzdFNlbGVjdGVkSW5kaWNlcyA9IHRoaXMuX3NlbGVjdGVkTGFzdEluZGljZXMoKTsKICAgICAgICAgICAgcmV0dXJuIGxhc3RTZWxlY3RlZEluZGljZXMubWFwKCBmdW5jdGlvbiAoc2VsSW5kZXgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldERpc3BsYXlJdGVtKHNlbEluZGV4KTsKICAgICAgICAgICAgfSwgdGhpcykuam9pbigiXG4iKTsKICAgICAgICB9LAoKICAgICAgICBfbXVsdGlTZWxlY3QgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy51aS5vbmVPZkNoaWxkLm9wZW4gPT0gIm11bHRpU2VsZWN0IiA/IHRydWUgOiBmYWxzZTsKICAgICAgICB9LAoKCgogICAgICAgIHNldEl0ZW1TdGF0ZSA6IGZ1bmN0aW9uKG5JbmRleCwgYlZhbCkgewogICAgICAgICAgICBpZiAodGhpcy5fbXVsdGlTZWxlY3QoKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIHZhciBzYXZlVmFsdWUgPSB0aGlzLmdldFNhdmVJdGVtKG5JbmRleCk7CiAgICAgICAgICAgICAgICBpZihzYXZlVmFsdWUgIT09IG51bGwgJiYgc2F2ZVZhbHVlICE9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICBzYXZlVmFsdWUgPSAiIitzYXZlVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlQXJyYXkgPSAodGhpcy5yYXdWYWx1ZSArICIiKS5zcGxpdCgiXG4iKTsKICAgICAgICAgICAgICAgICAgICB2YXIgY3VycmVudFZhbEluZGV4ID0gdGhpcy54ZmFVdGlsKCkuZEluZGV4T2YodmFsdWVBcnJheSxzYXZlVmFsdWUpOyAvKml0ZW0gdmFsdWUgaXMgdHlwZWQgc28gY29udmVydGluZyBpdCB0byBzdHJpbmcgZm9yIG1hdGNoaW5nICovCiAgICAgICAgICAgICAgICAgICAgaWYoYlZhbCAmJiBjdXJyZW50VmFsSW5kZXggPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzYXZlSXRlbXMgPSB0aGlzLl9nZXRTYXZlSXRlbXMoKS5jaGlsZHJlbgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3VmFsQXJyYXkgPSBfLnJlZHVjZShzYXZlSXRlbXMsZnVuY3Rpb24obWVtbyxpdGVtKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy54ZmFVdGlsKCkuZEluZGV4T2YodmFsdWVBcnJheSxpdGVtLnZhbHVlKSA+PSAwIHx8IGl0ZW0udmFsdWUgPT0gc2F2ZVZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1vLnB1c2goaXRlbS52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1lbW8KICAgICAgICAgICAgICAgICAgICAgICAgfSxbXSx0aGlzKQogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZUFycmF5ID0gbmV3VmFsQXJyYXk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoIWJWYWwgJiYgY3VycmVudFZhbEluZGV4ID49MCkKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVBcnJheS5zcGxpY2UoY3VycmVudFZhbEluZGV4LCAxKQogICAgICAgICAgICAgICAgICAgIHRoaXMucmF3VmFsdWUgPSB2YWx1ZUFycmF5LmpvaW4oIlxuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBDaG9pY2VMaXN0RmllbGQuX3N1cGVyLnNldEl0ZW1TdGF0ZS5jYWxsKHRoaXMsIG5JbmRleCwgYlZhbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfcGxheURhdGFYTUw6IGZ1bmN0aW9uICh4bWxEb2N1bWVudCwgY29udGV4dE5vZGUsIGN1cnJlbnRCaW5kUmVmKSB7CiAgICAgICAgICAgIHZhciB4cGF0aCA9IHRoaXMuX2dldFhwYXRoRnJvbUJpbmRSZWYoKSwKICAgICAgICAgICAgICAgIHZhbHVlLCBub2RlSXRlciwgbm9kZTsKICAgICAgICAgICAgaWYoeHBhdGggIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYodGhpcy5fbXVsdGlTZWxlY3QoKSkgewogICAgICAgICAgICAgICAgICAgIC8vIGluIGNhc2Ugb2YgbXVsdGlzZWxlY3QgdGhlIHZhbHVlIGlzIHhtbCBhbmQgaGVuY2UgbmVlZHMgc3BlY2lhbCBwcm9jZXNzaW5nCiAgICAgICAgICAgICAgICAgICAgbm9kZUl0ZXIgPSB0aGlzLl9nZXRFbGVtZW50c0Zyb21YcGF0aCh4cGF0aCwgY29udGV4dE5vZGUsIHhtbERvY3VtZW50KTsKICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZSA9IG5vZGVJdGVyLml0ZXJhdGVOZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgaWYobm9kZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbmV3IFhNTFNlcmlhbGl6ZXIoKS5zZXJpYWxpemVUb1N0cmluZyhub2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgQ2hvaWNlTGlzdEZpZWxkLl9zdXBlci5fc2V0VmFsdWUuYXBwbHkodGhpcyxbdmFsdWVdKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy90b2RvOiBJZiB3ZSBtb3ZlIHByb2Nlc3Npbmcgb2YgZGF0YSB4bWwgYmVmb3JlIHZpZXcKICAgICAgICAgICAgICAgICAgICAgICAgLy9nZW5lcmF0aW9uIHRoZW4gc2hvd0Rpc3BsYXlGb3JtYXQgY2FsbCB3aWxsIG5vdCBiZSBuZWVkZWQuCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Nob3dEaXNwbGF5Rm9ybWF0KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBDaG9pY2VMaXN0RmllbGQuX3N1cGVyLl9wbGF5RGF0YVhNTC5hcHBseSh0aGlzLCBbeG1sRG9jdW1lbnQsIGNvbnRleHROb2RlLCBjdXJyZW50QmluZFJlZl0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuX3BsYXlJdGVtcyh4bWxEb2N1bWVudCwgY29udGV4dE5vZGUpOwogICAgICAgIH0sCgogICAgICAgIF9wbGF5SXRlbXM6IGZ1bmN0aW9uICh4bWxEb2N1bWVudCwgY29udGV4dE5vZGUpIHsKICAgICAgICAgICAgdmFyIGJpbmRJdGVtcyA9IHRoaXMuZ2V0RWxlbWVudCgiI2JpbmRJdGVtc1swXSIpOwogICAgICAgICAgICBpZiAoYmluZEl0ZW1zICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHZhciBjb25uZWN0aW9uID0gYmluZEl0ZW1zLmNvbm5lY3Rpb247CiAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvbiA9PSBudWxsIHx8IGNvbm5lY3Rpb24ubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcmVmID0gYmluZEl0ZW1zLnJlZjsKICAgICAgICAgICAgICAgICAgICBpZiAocmVmICE9IG51bGwgJiYgcmVmLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHhwYXRoID0gdGhpcy5fY29udmVydFJlZlRvWFBhdGgocmVmKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHhwYXRoICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpdGVtTm9kZXMgPSB0aGlzLl9nZXRFbGVtZW50c0Zyb21YcGF0aCh4cGF0aCwgY29udGV4dE5vZGUsIHhtbERvY3VtZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtTm9kZXMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYXJJdGVtcygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpdGVtTm9kZSA9IGl0ZW1Ob2Rlcy5pdGVyYXRlTmV4dCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4bWxVdGlscyA9IHhmYWxpYi51dC5YTUxVdGlsczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaXRlbU5vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1RPRE86IHN1cHBvcnQgdmFsdWVSZWYvbGFiZWxSZWYgd2l0aCB4UGF0aCBoYXZpbmcgbW9yZSB0aGFuIG9uZSBlbGVtZW50CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCB2YWx1ZVJlZi9sYWJlbFJlZiBwb2ludGluZyB0byBhbiBhdHRyaWJ1dGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlTm9kZVJlc3VsdCA9IHhtbFV0aWxzLmV2YWx1YXRlWFBhdGgoYmluZEl0ZW1zLnZhbHVlUmVmLCBpdGVtTm9kZSwgbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhQYXRoUmVzdWx0Lk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlTm9kZVJlc3VsdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbGFiZWxOb2RlUmVzdWx0ID0gdmFsdWVOb2RlUmVzdWx0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJpbmRJdGVtcy5sYWJlbFJlZikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsTm9kZVJlc3VsdCA9IHhtbFV0aWxzLmV2YWx1YXRlWFBhdGgoYmluZEl0ZW1zLmxhYmVsUmVmLCBpdGVtTm9kZSwgbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBhdGhSZXN1bHQuT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlTm9kZSA9IHZhbHVlTm9kZVJlc3VsdC5pdGVyYXRlTmV4dCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodmFsdWVOb2RlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbGFiZWxOb2RlID0gbGFiZWxOb2RlUmVzdWx0ID8gbGFiZWxOb2RlUmVzdWx0Lml0ZXJhdGVOZXh0KCkgOiBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGxhYmVsTm9kZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsTm9kZSA9IHZhbHVlTm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuTG9nZ2VyLndhcm4oInhmYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxhYmVsUmVmIGRvZXNuJ3QgZXhpc3QgZm9yIFsiICsgdGhpcy5zb21FeHByZXNzaW9uICsgIiwiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBiaW5kSXRlbXMucmVmICsgIiwiICsgYmluZEl0ZW1zLmxhYmVsUmVmICsgIl0iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRJdGVtKGxhYmVsTm9kZS50ZXh0Q29udGVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVOb2RlLnRleHRDb250ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuTG9nZ2VyLmVycm9yKCJ4ZmEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInZhbHVlUmVmIGRvZXNuJ3QgZXhpc3QgZm9yIFsiICsgdGhpcy5zb21FeHByZXNzaW9uICsgIiwiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBiaW5kSXRlbXMucmVmICsgIiwiICsgYmluZEl0ZW1zLmxhYmVsUmVmICsgIl0iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLkxvZ2dlci5lcnJvcigieGZhIiwgInZhbHVlUmVmIHBvaW50cyB0byBhbiBpbnZhbGlkIHhtbCBlbGVtZW50ICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGJpbmRJdGVtcy52YWx1ZVJlZik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1Ob2RlID0gaXRlbU5vZGVzLml0ZXJhdGVOZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5Mb2dnZXIud2FybigieGZhIiwgImNvbm5lY3Rpb24gaW4gYmluZEl0ZW1zIGlzIG5vdCBzdXBwb3J0ZWQgaW4gRm9ybXNldCIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2FwcGVuZFZhbHVlSW5YTUxFbGVtZW50OiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICBpZighdGhpcy5fbXVsdGlTZWxlY3QoKSkgewogICAgICAgICAgICAgICAgQ2hvaWNlTGlzdEZpZWxkLl9zdXBlci5fYXBwZW5kVmFsdWVJblhNTEVsZW1lbnQuYXBwbHkodGhpcyxbZWxlbWVudF0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gbmVlZCB0byByZW1vdmUgdGhlIG9sZCBjaG9pY2VzIGJlZm9yZSBhcHBlbmRpbmcgdGhlIG5ldyBvbmVzCiAgICAgICAgICAgICAgICB3aGlsZSAoZWxlbWVudC5maXJzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVDaGlsZChlbGVtZW50LmZpcnN0Q2hpbGQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHhtbFZhbHVlID0gdGhpcy52YWx1ZS5vbmVPZkNoaWxkLmdldFZhbHVlKCJ0ZXh0L3htbCIpLAogICAgICAgICAgICAgICAgICAgIHhtbERvYywgbm9kZUl0ZXIsIG5vZGUsIGltcG9ydGVkTm9kZSwgYWRkZWRDaGlsZDsKICAgICAgICAgICAgICAgIGlmKHhtbFZhbHVlICE9IG51bGwgJiYgeG1sVmFsdWUgIT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MgPSAkLnBhcnNlWE1MKHhtbFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICBub2RlSXRlciA9IHhmYWxpYi51dC5YTUxVdGlscy5ldmFsdWF0ZVhQYXRoKCIqIiwgeG1sRG9jLmRvY3VtZW50RWxlbWVudCwgbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYUGF0aFJlc3VsdC5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5vZGVJdGVyLml0ZXJhdGVOZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUobm9kZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGltcG9ydGVkTm9kZSA9IGVsZW1lbnQub3duZXJEb2N1bWVudC5pbXBvcnROb2RlKG5vZGUsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkZWRDaGlsZCA9IGVsZW1lbnQuYXBwZW5kQ2hpbGQoaW1wb3J0ZWROb2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkZWRDaGlsZC50ZXh0Q29udGVudCA9IG5vZGUudGV4dENvbnRlbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlSXRlci5pdGVyYXRlTmV4dCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIsICQpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5TdWJmb3JtCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Db250YWluZXJOb2RlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgU3ViZm9ybSBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQGNsYXNzIFRoZSBjbGFzcyByZXByZXNlbnRzIGEgc3ViZm9ybSBpbiB0aGUgWEZBIERvbQogKiBAdmVyc2lvbiAwLjAuMQogKi8KKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHZhciBTdWJmb3JtID0geGZhbGliLnNjcmlwdC5TdWJmb3JtID0geGZhbGliLnNjcmlwdC5FdmVudENvbnRhaW5lck5vZGUuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgU3ViZm9ybS5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLl9pbnN0YW5jZU1hbmFnZXIgPSBudWxsOwogICAgICAgICAgICB0aGlzLm1uSW5zdGFuY2VJbmRleCA9IDA7CiAgICAgICAgICAgIHRoaXMudGVzdHM9IFt0aGlzLl9zY3JpcHRUZXN0XTsKICAgICAgICB9LAoKICAgICAgICBfaXNTdWJmb3JtIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0sCgogICAgICAgIGdldEludmFsaWRPYmplY3RzIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICB2YXIgc01lc3NhZ2VzID0gbmV3IEFycmF5KCk7CiAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRlKHNNZXNzYWdlcyk7CiAgICAgICAgICAgIGZvciAoIHZhciBpID0gMDsgaSA8IHNNZXNzYWdlcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgbGlzdC5fYXBwZW5kKHNNZXNzYWdlc1tpXS5yZWYpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH0sCgogICAgICAgIF9ldmVudEhhbmRsZXIgOiBmdW5jdGlvbihldmVudE5hbWUpIHsKICAgICAgICAgICAgdmFyIHJWYWx1ZSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgc3dpdGNoIChldmVudE5hbWUpIHsKICAgICAgICAgICAgICAgIGNhc2UgInZhbGlkYXRlIjoKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLm1vRXZlbnRzWyJ2YWxpZGF0ZSJdICYmIHRoaXMubW9FdmVudHNbInZhbGlkYXRlIl0ubGVuZ3RoID4wKXsKICAgICAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdGhpcy5tb0V2ZW50c1sidmFsaWRhdGUiXVswXS5leGVjdXRlKHRoaXMsICJ2YWxpZGF0ZSIpOwogICAgICAgICAgICAgICAgICAgIH1lbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHJWYWx1ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICIkZm9ybXByZVN1Ym1pdCI6CiAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdGhpcy5fcHJlU3VibWl0RXZlbnRIYW5kbGVyKCk7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgaWYgKHRoaXMubW9FdmVudHNbZXZlbnROYW1lXSkgewogICAgICAgICAgICAgICAgICAgIGZvciAoIHZhciBpID0gMDsgaSA8IHRoaXMubW9FdmVudHNbZXZlbnROYW1lXS5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1vRXZlbnRzW2V2ZW50TmFtZV1baV0uZXhlY3V0ZSh0aGlzLCBldmVudE5hbWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gclZhbHVlOwogICAgICAgIH0sCgogICAgICAgIF9udWxsVGVzdCA6IGZ1bmN0aW9uKHZhbHVlLHNNZXNzYWdlcykgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBfcmVxdWlyZUdldHRlclNldHRlciA6IGZ1bmN0aW9uKG9DaGlsZCl7CiAgICAgICAgICAgIGlmKG9DaGlsZC5jbGFzc05hbWUgPT0gInBhZ2VTZXQiKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBTdWJmb3JtLl9zdXBlci5fcmVxdWlyZUdldHRlclNldHRlci5jYWxsKHRoaXMsIG9DaGlsZCk7CiAgICAgICAgfSwKCiAgICAgICAgX3Bvc3RBZGRDaGlsZCA6IGZ1bmN0aW9uKG9Ob2RlKXsKICAgICAgICAgICAgaWYob05vZGUuaW5zdGFuY2VNYW5hZ2VyKXsKICAgICAgICAgICAgICAgIC8vIGNsZWFyIGFsbCBjYWNoZWQgY29udGV4dHMgaW4gRXZlbnRDb250YWluZXJOb2RlLXMKICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5fY2xlYXJBbGxNb0NvbnRleHRzKCk7CgogICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuX3hmYVRlbXBsYXRlQ2FjaGUucHV0TW9kZWwob05vZGUsIG9Ob2RlLmluc3RhbmNlTWFuYWdlci5faW5zdGFuY2VUZW1wbGF0ZSgpKTsKICAgICAgICAgICAgICAgIGlmKHRoaXMubUVmZmVjdGl2ZUFjY2Vzcyl7CiAgICAgICAgICAgICAgICAgICAgb05vZGUuX2NhbGN1bGF0ZUVmZmVjdGl2ZUFjY2VzcygpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYodGhpcy5tRWZmZWN0aXZlUHJlc2VuY2UpewogICAgICAgICAgICAgICAgICAgIG9Ob2RlLl9jYWxjdWxhdGVFZmZlY3RpdmVQcmVzZW5jZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgb05vZGUuX2luaXRpYWxpemUoKTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm1iSW5pdGlhbGl6ZWQpIHsKICAgICAgICAgICAgICAgICAgICAvLyBvTm9kZS5leGVjRXZlbnQoImluaXRpYWxpemUiKTsKICAgICAgICAgICAgICAgICAgICBvTm9kZS5leGVjQ2FsY3VsYXRlKCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gaW50ZXJuYWxEaXNwYXRjaEV2ZW50KENvbGxlY3Rpb25FdmVudEtpbmQuQURELCBvTm9kZSwgaW5kZXgpOwoKICAgICAgICAgICAgICAgIC8vIGlmICh0aGlzLmhhc0V2ZW50TGlzdGVuZXIoImNoYW5nZSIpKQogICAgICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkNISUxEX0FEREVELHRoaXMsImNoaWxkIixudWxsLG9Ob2RlKTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsZXZudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAvL2RvIG5vdGhpbmcgLS0tIExldCdzIGZhY2UgaXQgWW91IG1pZ2h0IGNhbGwgdGhpcyBmdW5jdGlvbiBmb3Igb3RoZXIgdGhpbmdzIGJlc2lkZXMgc3ViZm9ybSBlLnguIGl0ZW1zIChzZWUgX2dldERpc3BsYXlJdGVtcygpKQogICAgICAgICAgICAgICAgU3ViZm9ybS5fc3VwZXIuX3Bvc3RBZGRDaGlsZC5jYWxsKHRoaXMsIG9Ob2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9wb3N0UmVtb3ZlQ2hpbGQgOiBmdW5jdGlvbihvQ2hpbGQpewogICAgICAgICAgICBpZihvQ2hpbGQuaW5zdGFuY2VNYW5hZ2VyKXsKICAgICAgICAgICAgICAgIC8vIGNsZWFyIGFsbCBjYWNoZWQgY29udGV4dHMgaW4gRXZlbnRDb250YWluZXJOb2RlLXMKICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5fY2xlYXJBbGxNb0NvbnRleHRzKCk7CgogICAgICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkNISUxEX1JFTU9WRUQsdGhpcywiY2hpbGQiLCBvQ2hpbGQsIG51bGwpOwogICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIFN1YmZvcm0uX3N1cGVyLl9wb3N0UmVtb3ZlQ2hpbGQuY2FsbCh0aGlzLCBvQ2hpbGQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcGxheUpzb25Gb3JFbGVtZW50IDogZnVuY3Rpb24oZWxOYW1lLCBwSnNvbk1vZGVsKXsKICAgICAgICAgICAgaWYoZWxOYW1lID09ICJpbnN0YW5jZU1hbmFnZXIiKXsKICAgICAgICAgICAgICAgIHZhciBuZXdKQ2hpbGRyZW4gPSBfLmZpbHRlcihfLmNvbXBhY3QocEpzb25Nb2RlbC5jaGlsZHJlbiksIGZ1bmN0aW9uIChqQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy54ZmFVdGlsKCkuaXNSZXBlYXRhYmVFbChqQ2hpbGQuX2NsYXNzKSB8fCBqQ2hpbGQuX2NsYXNzID09ICJpbnN0YW5jZU1hbmFnZXIiOwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICB2YXIgb2xkTUNoaWxkcmVuID0gXy5maWx0ZXIodGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uKG1DaGlsZCl7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICB0aGlzLnhmYVV0aWwoKS5pc1JlcGVhdGFiZUVsKG1DaGlsZC5jbGFzc05hbWUpICB8fCBtQ2hpbGQuY2xhc3NOYW1lID09ICJpbnN0YW5jZU1hbmFnZXIiIDsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwoKICAgICAgICAgICAgICAgIHZhciBsYXN0SU0gPSBudWxsOwogICAgICAgICAgICAgICAgXy5lYWNoKG9sZE1DaGlsZHJlbiwgZnVuY3Rpb24ob2xkTUNoaWxkKXsKICAgICAgICAgICAgICAgICAgICAvL0lmIG9sZE1DaGlsZCBoYXMgYW55IHJlbWFpbmluZyBJTSB0aGVuIG5ld0pDaGlsZHJlbiBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIElNIGxlZnQKICAgICAgICAgICAgICAgICAgICBpZihvbGRNQ2hpbGQuY2xhc3NOYW1lID09ICJpbnN0YW5jZU1hbmFnZXIiICYmIG5ld0pDaGlsZHJlblswXS5fY2xhc3MgPT0gImluc3RhbmNlTWFuYWdlciIpewogICAgICAgICAgICAgICAgICAgICAgICBuZXdKQ2hpbGRyZW4uc2hpZnQoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZihvbGRNQ2hpbGQuY2xhc3NOYW1lID09ICJpbnN0YW5jZU1hbmFnZXIiICYmIHRoaXMueGZhVXRpbCgpLmlzUmVwZWF0YWJlRWwobmV3SkNoaWxkcmVuWzBdLl9jbGFzcykpewogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSh0aGlzLnhmYVV0aWwoKS5pc1JlcGVhdGFiZUVsKG5ld0pDaGlsZHJlblswXS5fY2xhc3MpKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhZGRlZFNmID1sYXN0SU0uYWRkSW5zdGFuY2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZGVkU2YucGxheUpzb24obmV3SkNoaWxkcmVuLnNoaWZ0KCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0pDaGlsZHJlbi5zaGlmdCgpOyAvLyBUaGlzIG11c3QgYmUgaW5zdGFuY2VNYW5hZ2VyIGZvciBuZXh0IHN1YmZvcm0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih0aGlzLnhmYVV0aWwoKS5pc1JlcGVhdGFiZUVsKG9sZE1DaGlsZC5jbGFzc05hbWUgKSAmJiAobmV3SkNoaWxkcmVuWzBdID09IG51bGwgfHwgbmV3SkNoaWxkcmVuWzBdLl9jbGFzcyA9PSAiaW5zdGFuY2VNYW5hZ2VyIikpewogICAgICAgICAgICAgICAgICAgICAgICBsYXN0SU0ucmVtb3ZlSW5zdGFuY2Uob2xkTUNoaWxkLmluc3RhbmNlSW5kZXgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9vbGRNQ2hpbGQuY2xhc3NOYW1lID09ICJzdWJmb3JtIiAmJiBuZXdKQ2hpbGRyZW5bMF0uX2NsYXNzID09ICJzdWJmb3JtIgogICAgICAgICAgICAgICAgICAgICAgICBvbGRNQ2hpbGQucGxheUpzb24obmV3SkNoaWxkcmVuLnNoaWZ0KCkpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYob2xkTUNoaWxkLmNsYXNzTmFtZSA9PSAiaW5zdGFuY2VNYW5hZ2VyIiApCiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RJTSA9IG9sZE1DaGlsZDsKCiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIHdoaWxlKG5ld0pDaGlsZHJlbi5sZW5ndGggPiAwKXsKICAgICAgICAgICAgICAgICAgICB2YXIgbmV3SlNGID0gbmV3SkNoaWxkcmVuLnNoaWZ0KCk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGFkZGVkU0YgPSBsYXN0SU0uYWRkSW5zdGFuY2UoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYWRkZWRTRikgewogICAgICAgICAgICAgICAgICAgICAgICBhZGRlZFNGLnBsYXlKc29uKG5ld0pTRik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy54ZmFVdGlsKCkuaXNSZXBlYXRhYmVFbChlbE5hbWUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIGlmIChlbE5hbWUgPT09ICJ2YXJpYWJsZXMiKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgIC8vIExDLTk1MDg6IGRvbid0IHBsYXlKc29uIGZvciB2YXJpYWJsZXMKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBTdWJmb3JtLl9zdXBlci5wbGF5SnNvbkZvckVsZW1lbnQuY2FsbCh0aGlzLCBlbE5hbWUsIHBKc29uTW9kZWwpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldFhQYXRoRm9yVXNlTmFtZUJpbmRpbmc6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYodGhpcy5pbnN0YW5jZU1hbmFnZXIuX2lzUmVwZWF0YWJsZSgpKSB7CiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IHRoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIik7CiAgICAgICAgICAgICAgICByZXR1cm4gbmFtZSA9PT0gIiIgPyBudWxsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZTogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRSZWY6IG5hbWUgKyAiWypdIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBTdWJmb3JtLl9zdXBlci5fZ2V0WFBhdGhGb3JVc2VOYW1lQmluZGluZy5hcHBseSh0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9wbGF5RGF0YVhNTDogZnVuY3Rpb24oeG1sRG9jdW1lbnQsIGNvbnRleHROb2RlLCBjdXJyZW50QmluZFJlZikgewogICAgICAgICAgICBpZih0aGlzLnBhcmVudC5jbGFzc05hbWUgPT09ICJmb3JtIikgewogICAgICAgICAgICAgICAgcmV0dXJuIFN1YmZvcm0uX3N1cGVyLl9wbGF5RGF0YVhNTC5hcHBseSh0aGlzLFt4bWxEb2N1bWVudCxjb250ZXh0Tm9kZSwgY3VycmVudEJpbmRSZWZdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgeHBhdGggPSB0aGlzLl9nZXRYcGF0aEZyb21CaW5kUmVmKCksCiAgICAgICAgICAgICAgICByZWxhdGl2ZVhQYXRoLCBub2RlSXRlciwgbm9kZUxpc3QgPSBbXSwgbm9kZSwgY291bnQsIGluc3RhbmNlOwogICAgICAgICAgICBpZih4cGF0aCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgIFN1YmZvcm0uX3N1cGVyLl9wbGF5RGF0YVhNTC5hcHBseSh0aGlzLFt4bWxEb2N1bWVudCxjb250ZXh0Tm9kZSwgY3VycmVudEJpbmRSZWZdKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBmaXJzdCBpbnN0YW5jZSB3aWxsIHRha2UgY2FyZSBvZiB0aGUgcmVzdCBvZiB0aGUgaW5zdGFuY2VzLgogICAgICAgICAgICAgICAgaWYodGhpcy5pbnN0YW5jZUluZGV4ID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgbm9kZUl0ZXIgPSB0aGlzLl9nZXRFbGVtZW50c0Zyb21YcGF0aCh4cGF0aCwgY29udGV4dE5vZGUsIHhtbERvY3VtZW50KTsKICAgICAgICAgICAgICAgICAgICBpZiAobm9kZUl0ZXIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZUl0ZXIuaXRlcmF0ZU5leHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKG5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVMaXN0LnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZUl0ZXIuaXRlcmF0ZU5leHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZUxpc3Quc2hpZnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAobm9kZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPiB0aGlzLmluc3RhbmNlTWFuYWdlci5jb3VudCAtIDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZSA9IHRoaXMuaW5zdGFuY2VNYW5hZ2VyLmFkZEluc3RhbmNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlID0gdGhpcy5pbnN0YW5jZU1hbmFnZXIuaW5zdGFuY2VzW2NvdW50XTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN1YmZvcm0uX3N1cGVyLl9wbGF5RGF0YVhNTC5hcHBseShpbnN0YW5jZSwgW3htbERvY3VtZW50LCBub2RlLCB4cGF0aF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5vZGVMaXN0LnNoaWZ0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChjb3VudCA8IHRoaXMuaW5zdGFuY2VNYW5hZ2VyLmNvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pbnN0YW5jZU1hbmFnZXIuY291bnQgPT09IHRoaXMuaW5zdGFuY2VNYW5hZ2VyLm1pbikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlID0gdGhpcy5pbnN0YW5jZU1hbmFnZXIuaW5zdGFuY2VzW2NvdW50XTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdWJmb3JtLl9zdXBlci5fcGxheURhdGFYTUwuYXBwbHkoaW5zdGFuY2UsIFt4bWxEb2N1bWVudCwgbnVsbCwgeHBhdGhdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluc3RhbmNlTWFuYWdlci5yZW1vdmVJbnN0YW5jZShjb3VudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBHZW5lcmF0ZXMgdGhlIFhNTCBieSBhcHBlbmRpbmcgdGhlIGVsZW1lbnRzIGluIHRoZSByb290Tm9kZQogICAgICAgICAqIEBwYXJhbSByb290Tm9kZSBUaGUgcm9vdE5vZGUgb2YgdGhlIHhtbC4gR2VuZXJhbGx5IHRoZSBlbGVtZW50IHRoYXQgbWFwcyB0byB0aGUgcm9vdCBvZiB0aGUgZm9ybQogICAgICAgICAqIEBwYXJhbSBjb250ZXh0Tm9kZSBDdXJyZW50IE5vZGUgd2hlcmUgdG8gaW5zZXJ0IHRoZSBlbGVtZW50cyBpbiBjYXNlIG9mIHJlbGF0aXZlIGJpbmRpbmdzCiAgICAgICAgICovCiAgICAgICAgZ2VuZXJhdGVEYXRhWE1MOiBmdW5jdGlvbihyb290Tm9kZSwgY29udGV4dE5vZGUpIHsKICAgICAgICAgICAgaWYodGhpcy5wYXJlbnQuY2xhc3NOYW1lID09PSAiZm9ybSIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBTdWJmb3JtLl9zdXBlci5nZW5lcmF0ZURhdGFYTUwuYXBwbHkodGhpcyxbcm9vdE5vZGUsY29udGV4dE5vZGVdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgeHBhdGggPSB0aGlzLl9nZXRYcGF0aEZyb21CaW5kUmVmKCksCiAgICAgICAgICAgICAgICB4bWxVdGlscyA9IHhmYWxpYi51dC5YTUxVdGlscywKICAgICAgICAgICAgICAgIHBhcmVudEVsZW1lbnQsIGVsZW1lbnQsIGNoaWxkRWxlbWVudCwgY2hpbGRYUGF0aCwgY2hpbGRYUGF0aFBhcnRzLAogICAgICAgICAgICAgICAgY2hpbGRFbGVtZW50TmFtZSwgY2hpbGRFbGVtZW50SW5kZXg7CiAgICAgICAgICAgIGlmKHhwYXRoID09IG51bGwpIHsKICAgICAgICAgICAgICAgIFN1YmZvcm0uX3N1cGVyLmdlbmVyYXRlRGF0YVhNTC5hcHBseSh0aGlzLFtyb290Tm9kZSxjb250ZXh0Tm9kZV0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZWxlbWVudCA9IHhwYXRoLnJlbGF0aXZlID09PSBmYWxzZSA/IHJvb3ROb2RlIDogY29udGV4dE5vZGU7CiAgICAgICAgICAgICAgICBwYXJlbnRFbGVtZW50ID0geG1sVXRpbHMuY3JlYXRlRWxlbWVudHNGcm9tWFBhdGgoeHBhdGguYmluZFJlZiwgZWxlbWVudCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICBjaGlsZFhQYXRoID0gXy5sYXN0KHhwYXRoLmJpbmRSZWYuc3BsaXQoIi8iKSk7CiAgICAgICAgICAgICAgICBjaGlsZFhQYXRoUGFydHMgPSB4bWxVdGlscy5fZ2V0RWxlbWVudE5hbWVBbmRJbmRleEZyb21YUGF0aFBhcnQoY2hpbGRYUGF0aCk7CiAgICAgICAgICAgICAgICBjaGlsZEVsZW1lbnROYW1lID0gY2hpbGRYUGF0aFBhcnRzLm5hbWU7CiAgICAgICAgICAgICAgICBjaGlsZEVsZW1lbnRJbmRleCA9IGNoaWxkWFBhdGhQYXJ0cy5pbmRleDsKICAgICAgICAgICAgICAgIC8vVE9ETzogKiBkb2Vzbid0IGdhdXJhbnRlZXMgdGhhdCB0aGUgZWxlbWVudCBjYW4gYmUgcmVwZWF0ZWQgaW4gc2NoZW1hLiBCdXQgd2UgaGF2ZSBubyBjaG9pY2UgZm9yIG5vdwogICAgICAgICAgICAgICAgaWYoY2hpbGRFbGVtZW50SW5kZXggPT09ICIqIikgewogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuaW5zdGFuY2VJbmRleCA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3IgcmVwZWF0YWJsZSBzdWJmb3JtcyB0aGUgZmlyc3QgY2hpbGQgZG9lcyB0aGUgcHJvY2Vzc2luZyBmb3IgYWxsIHRoZSBzaWJsaW5ncwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FjaGUgYWxsIGV4aXN0aW5nIGNoaWxkcmVuCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleGlzdGluZ0luc3RhbmNlcyA9IHBhcmVudEVsZW1lbnQuaGFzQ2hpbGROb2RlcygpID8gcGFyZW50RWxlbWVudC5jaGlsZE5vZGVzIDogbnVsbDsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbHRlciBvdXQgY3VycmVudCByZXBlYXRhYmxlIG9uZXMKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfLmlzRW1wdHkoZXhpc3RpbmdJbnN0YW5jZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0luc3RhbmNlcyA9IF8uZmlsdGVyKGV4aXN0aW5nSW5zdGFuY2VzLCBmdW5jdGlvbiAoY2hpbGQpIHsgcmV0dXJuIGNoaWxkLm5vZGVOYW1lID09PSBjaGlsZEVsZW1lbnROYW1lOyB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgXy5lYWNoKHRoaXMuaW5zdGFuY2VNYW5hZ2VyLmluc3RhbmNlcywgZnVuY3Rpb24gKGluc3RhbmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBpbnN0YW5jZS5pbnN0YW5jZUluZGV4ICsgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZEVsZW1lbnQgPSB4bWxVdGlscy5maW5kT3JDcmVhdGVFbGVtZW50KGNoaWxkRWxlbWVudE5hbWUgKyAiWyIgKyBpbmRleCArICJdIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50RWxlbWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdWJmb3JtLl9zdXBlci5nZW5lcmF0ZURhdGFYTUwuYXBwbHkoaW5zdGFuY2UsW3Jvb3ROb2RlLCBjaGlsZEVsZW1lbnRdKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZighXy5pc0VtcHR5KGV4aXN0aW5nSW5zdGFuY2VzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBsZWZ0IG92ZXIgb25lcywgY2F1c2VkIGlmIG9uZSBkZWxldGVzIGFuIGluc3RhbmNlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2luY2Ugd2UgYXJlIHJlZ2VuZXJhdGluZyB4bWwsIG5vIG5lZWQgdG8gd29ycnkgYWJvdXQgb3JkZXIsIHJlbWFpbmluZyBTRnMgd2lsbCB1cGRhdGUgdGhlaXIgZGF0YSBmcm9tIHRoZSB4bWwncyB0b3AgZWxlbXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcih2YXIgaSA9IHRoaXMuaW5zdGFuY2VNYW5hZ2VyLmNvdW50OyBpIDwgZXhpc3RpbmdJbnN0YW5jZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKGV4aXN0aW5nSW5zdGFuY2VzW2ldKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAvLyBCdXQgdGhpcyB3aWxsIGhhdmUgYSBzaWRlIGVmZmVjdCBpbiBjYXNlIG9mIGFueSBvdGhlciByZXBlYXRhYmxlIHN1YmZvcm0gbWFwcGluZyB0byB0aGUgc2FtZSB4cGF0aCBMQy0zOTExNTE4CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjaGlsZEVsZW1lbnQgPSB4bWxVdGlscy5maW5kT3JDcmVhdGVFbGVtZW50KGNoaWxkRWxlbWVudE5hbWUgKyJbIiArIGNoaWxkRWxlbWVudEluZGV4ICsgIl0iLAogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRFbGVtZW50KTsKICAgICAgICAgICAgICAgICAgICBTdWJmb3JtLl9zdXBlci5nZW5lcmF0ZURhdGFYTUwuYXBwbHkodGhpcyxbcm9vdE5vZGUsIGNoaWxkRWxlbWVudF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldERhdGFTb21NYXAgOiBmdW5jdGlvbiAoZGF0YVNvbU1hcCkgewogICAgICAgICAgICBpZighdGhpcy5pbnN0YW5jZU1hbmFnZXIgfHwgIXRoaXMuaW5zdGFuY2VNYW5hZ2VyLl9pc1JlcGVhdGFibGUoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIFN1YmZvcm0uX3N1cGVyLl9nZXREYXRhU29tTWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBkYXRhU29tTWFwOwogICAgICAgIH0sCgogICAgICAgIF9yZXN0b3JlRGF0YVNvbU1hcDogZnVuY3Rpb24obWFwKSB7CiAgICAgICAgICAgIGlmKCF0aGlzLmluc3RhbmNlTWFuYWdlciB8fCAhdGhpcy5pbnN0YW5jZU1hbmFnZXIuX2lzUmVwZWF0YWJsZSgpKSB7CiAgICAgICAgICAgICAgICBTdWJmb3JtLl9zdXBlci5fcmVzdG9yZURhdGFTb21NYXAuYXBwbHkodGhpcyxhcmd1bWVudHMpCiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfcHJlU3VibWl0RXZlbnRIYW5kbGVyOiB4ZmFsaWIuc2NyaXB0LkZpZWxkLnByb3RvdHlwZS5fcHJlU3VibWl0RXZlbnRIYW5kbGVyCiAgICB9KTsKCiAgICBTdWJmb3JtLmRlZmluZVByb3BzKHsKICAgICAgICAibG9jYWxlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgdmFyIG9iaiA9IHRoaXM7CiAgICAgICAgICAgICAgICB2YXIgbG9jYWxlOwogICAgICAgICAgICAgICAgd2hpbGUoIWxvY2FsZSAmJiBvYmopIHsKICAgICAgICAgICAgICAgICAgICBsb2NhbGUgPSBvYmouanNvbk1vZGVsLmxvY2FsZTsKICAgICAgICAgICAgICAgICAgICBvYmogPSBvYmoucGFyZW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbG9jYWxlID0gbG9jYWxlIHx8ICJlbi1VUyI7IC8vVE9ETzogcmVhZCBmcm9tIGpzcAogICAgICAgICAgICAgICAgcmV0dXJuIGxvY2FsZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJpbnN0YW5jZUluZGV4IjoKICAgICAgICB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubW5JbnN0YW5jZUluZGV4OwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImluc3RhbmNlTWFuYWdlciI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9pbnN0YW5jZU1hbmFnZXI7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHJlc29sdmU6dHJ1ZQogICAgICAgIH0sCgogICAgICAgICJvY2N1ciI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmluc3RhbmNlTWFuYWdlci5vY2N1cjsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgcmVzb2x2ZTp0cnVlCiAgICAgICAgfSwKCiAgICAgICAgInBhZ2VTZXQiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInBhZ2VTZXQiLCAwLCB0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJ2YXJpYWJsZXMiOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICB0aGlzLmdldEVsZW1lbnQoInZhcmlhYmxlcyIsMCk7CiAgICAgICAgICAgIH0gLAogICAgICAgICAgICBzZXQgOmZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsInZhcmlhYmxlcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgU3ViZm9ybS5hZGRNaXhpbnMoWwogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQXNzaXN0LAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkUHJlc2VuY2UsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRYWVdILAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkRmlsbENvbG9yLAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQm9yZGVyLAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQm9yZGVyQ29sb3IsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRCb3JkZXJXaWR0aCwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFBhcmEsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRNYXJnaW4KICAgIF0pOwoKfSkoXyx4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5Db250ZW50QXJlYQogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuQ29udGFpbmVyTm9kZQogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIENvbnRlbnRBcmVhIENsYXNzIHJlcXVpcmVkIGZvciBYRkEgbGlicmFyeQogKiBAdmVyc2lvbiAwLjAuMQogKi8KCihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgQ29udGVudEFyZWEgY2xhc3MKICAgICAqCiAgICAgKiBAY2xhc3MgVGhlIGNsYXNzIHJlcHJlc2VudHMgYSBzdWJmb3JtIGluIHRoZSBYRkEgRG9tCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgbm9kZQogICAgICogQGV4dGVuZHMgY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuQ29udGFpbmVyTm9kZQogICAgICovCiAgICB2YXIgQ29udGVudEFyZWEgPSB4ZmFsaWIuc2NyaXB0LkNvbnRlbnRBcmVhID0geGZhbGliLnNjcmlwdC5Db250YWluZXJOb2RlLmV4dGVuZCh7CiAgICAgICAgX2NvbXB1dGVKc29uRGlmZjogZnVuY3Rpb24gKGRpZmZfbGV2ZWwpIHsKICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5wYXJ0aWFsU3RyaXBPckNhbGwuY2FsbCh0aGlzLCBkaWZmX2xldmVsLCBDb250ZW50QXJlYS5fc3VwZXIuX2NvbXB1dGVKc29uRGlmZik7CiAgICAgICAgfQogICAgfSk7CgogICAgQ29udGVudEFyZWEuYWRkTWl4aW5zKFsKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFhZV0gKICAgIF0pOwoKfSkoXywgeGZhbGliKTsKCi8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LlBhZ2VBcmVhCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Db250YWluZXJOb2RlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgUGFnZUFyZWEgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKKGZ1bmN0aW9uKF8sIHhmYWxpYil7CiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgUGFnZUFyZWEgY2xhc3MKICAgICAqCiAgICAgKiBAY2xhc3MgVGhlIGNsYXNzIHJlcHJlc2VudHMgYSBzdWJmb3JtIGluIHRoZSBYRkEgRG9tCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgbm9kZQogICAgICogQGV4dGVuZHMgY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuQ29udGFpbmVyTm9kZQogICAgICovCiAgICB2YXIgUGFnZUFyZWEgPSB4ZmFsaWIuc2NyaXB0LlBhZ2VBcmVhID0geGZhbGliLnNjcmlwdC5FdmVudENvbnRhaW5lck5vZGUuZXh0ZW5kKHsKICAgICAgICBleGVjRXZlbnQgOiBmdW5jdGlvbihldmVudE5hbWUpIHsKICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICB9LAoKICAgICAgICBwbGF5SnNvbkZvckVsZW1lbnQ6IHhmYWxpYi5zY3JpcHQuU3ViZm9ybS5wcm90b3R5cGUucGxheUpzb25Gb3JFbGVtZW50LAoKICAgICAgICBfY29tcHV0ZUpzb25EaWZmOiBmdW5jdGlvbiAoZGlmZl9sZXZlbCkgewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLnBhcnRpYWxTdHJpcE9yQ2FsbC5jYWxsKHRoaXMsIGRpZmZfbGV2ZWwsIFBhZ2VBcmVhLl9zdXBlci5fY29tcHV0ZUpzb25EaWZmKTsKICAgICAgICB9CiAgICB9KTsKCiAgICBQYWdlQXJlYS5kZWZpbmVQcm9wcyh7CiAgICAgICAgImFjY2VzcyIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgeyAgLy9pIGFtIG5vdCBzdXJlIGhvdyB0byBtYWtlIHRoaXMgcHJvcGVydHkgdW5kZWZpbmVkIHNvIGp1c3QgcmVtb3ZlZCBzZXR0ZXJzCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwuYWNjZXNzLCB0aGlzLl9kZWZhdWx0cy5hY2Nlc3MpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCgogICAgICAgICJwcmVzZW5jZSIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgeyAvL2kgYW0gbm90IHN1cmUgaG93IHRvIG1ha2UgdGhpcyBwcm9wZXJ0eSB1bmRlZmluZWQgc28ganVzdCByZW1vdmVkIHNldHRlcnMKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5wcmVzZW5jZSwgdGhpcy5fZGVmYXVsdHMucHJlc2VuY2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYik7CgoKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5QYWdlU2V0CiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Db250YWluZXJOb2RlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgUGFnZVNldCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBQYWdlU2V0IGNsYXNzCiAgICAgKgogICAgICogQGNsYXNzIFRoZSBjbGFzcyByZXByZXNlbnRzIGEgc3ViZm9ybSBpbiB0aGUgWEZBIERvbQogICAgICogQHBhcmFtIHtzdHJpbmd9CiAgICAgICAgKiAgICAgICAgICAgIG5hbWUgdGhlIG5hbWUgb2YgdGhlIG5vZGUKICAgICAqIEBleHRlbmRzIGNvbS5hZG9iZS54ZmEuc2NyaXB0aW5nLkNvbnRhaW5lck5vZGUKICAgICAqLwogICAgdmFyIFBhZ2VTZXQgPSB4ZmFsaWIuc2NyaXB0LlBhZ2VTZXQgPSB4ZmFsaWIuc2NyaXB0LkV2ZW50Q29udGFpbmVyTm9kZS5leHRlbmQoewogICAgICAgIGV4ZWNFdmVudCA6IGZ1bmN0aW9uKGV2ZW50TmFtZSkgewogICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgIHJldHVybiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUucGFydGlhbFN0cmlwT3JDYWxsLmNhbGwodGhpcywgZGlmZl9sZXZlbCwgUGFnZVNldC5fc3VwZXIuX2NvbXB1dGVKc29uRGlmZik7CiAgICAgICAgfSwKCiAgICAgICAgcGxheUpzb25Gb3JFbGVtZW50OiBmdW5jdGlvbiAoZWxOYW1lLCBwSnNvbk1vZGVsKSB7CiAgICAgICAgICAgIGlmKGVsTmFtZSA9PT0gInBhZ2VBcmVhIikgeyAvLyBMQy0zNjQyNTE4IDogYWxsb3cgZGF0YS1tZXJnZSBvbiBtYXN0ZXIgcGFnZQogICAgICAgICAgICAgICAgdmFyIG5ld0pDaGlsZHJlbiA9IF8uZmlsdGVyKF8uY29tcGFjdChwSnNvbk1vZGVsLmNoaWxkcmVuKSwgZnVuY3Rpb24gKGpDaGlsZCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBqQ2hpbGQuX2NsYXNzID09PSAicGFnZUFyZWEiOwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICB2YXIgb2xkTUNoaWxkcmVuID0gXy5maWx0ZXIodGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uIChtQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbUNoaWxkLmNsYXNzTmFtZSA9PT0gInBhZ2VBcmVhIjsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwoKICAgICAgICAgICAgICAgIF8uZWFjaChvbGRNQ2hpbGRyZW4sIGZ1bmN0aW9uIChvbGRNQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaWRQYXR0ZXJuID0gbmV3IFJlZ0V4cCgiXiIgKyBvbGRNQ2hpbGQuanNvbk1vZGVsLmlkICsgIig/Ol9JRCkqJCIpOyAvLyBsb29rIGZvciBhbiBpZCB2YWx1ZSwgZm9sbG93ZWQgYnkgemVybyBvciBtb3JlICJfSUQiIHN1ZmZpeGVzCiAgICAgICAgICAgICAgICAgICAgXy5lYWNoKG5ld0pDaGlsZHJlbiwgZnVuY3Rpb24gKG5ld0pDaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAob2xkTUNoaWxkLm5hbWUgJiYgb2xkTUNoaWxkLm5hbWUgPT0gbmV3SkNoaWxkLm5hbWUgJiYgaWRQYXR0ZXJuLnRlc3QobmV3SkNoaWxkLmlkKSkgeyAvLyBtYXRjaCBuYW1lIGFzIHdlbGwgYXMgaWQsIHRvIGFjY291bnQgZm9yIG15c3RlcnkgeHRnIG1hc3RlciBwZyBpZCBnZW4gbG9naWMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkTUNoaWxkLnBsYXlKc29uKG5ld0pDaGlsZCk7IC8vIG1heSB0aHJvdyBhbiBleGNlcHRpb24sIHNheSBmb3IgMC1pbnN0YW5jZSBmaWVsZHMgb24gbWFzdGVyIHBnLiBTYXkgZXhwZWN0ZWQgYW4gaW5zdC5tYW4gYnV0IGZvdW5kIG51bGwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZXJyb3IoInhmYSIsICJFeGNlcHRpb24gZHVyaW5nIERhdGFNZXJnZSBvbiBmaWVsZHMgaW4gbWFzdGVyIHBhZ2UuICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZXhjZXB0aW9uLCBvbGRNQ2hpbGQsIiBQbGF5SlNPTiBvbiIsIG5ld0pDaGlsZF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBQYWdlU2V0Ll9zdXBlci5wbGF5SnNvbkZvckVsZW1lbnQuY2FsbCh0aGlzLCBlbE5hbWUsIHBKc29uTW9kZWwpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgUGFnZVNldC5kZWZpbmVQcm9wcyh7CiAgICAgICAgImFjY2VzcyIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgeyAgLy9pIGFtIG5vdCBzdXJlIGhvdyB0byBtYWtlIHRoaXMgcHJvcGVydHkgdW5kZWZpbmVkIHNvIGp1c3QgcmVtb3ZlZCBzZXR0ZXJzCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwuYWNjZXNzLCB0aGlzLl9kZWZhdWx0cy5hY2Nlc3MpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInByZXNlbmNlIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7IC8vaSBhbSBub3Qgc3VyZSBob3cgdG8gbWFrZSB0aGlzIHByb3BlcnR5IHVuZGVmaW5lZCBzbyBqdXN0IHJlbW92ZWQgc2V0dGVycwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JFbHNlKHRoaXMuanNvbk1vZGVsLnByZXNlbmNlLCB0aGlzLl9kZWZhdWx0cy5wcmVzZW5jZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sIHhmYWxpYik7Ci8qKgogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIFN1YmZvcm1TZXQgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyBhIFN1YmZvcm1TZXQgaW4gdGhlIFhGQSBEb20KICogQHZlcnNpb24gMC4wLjEKICovCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgU3ViZm9ybVNldCA9IHhmYWxpYi5zY3JpcHQuU3ViZm9ybVNldCA9IHhmYWxpYi5zY3JpcHQuU3ViZm9ybS5leHRlbmQoewogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBTdWJmb3JtU2V0Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMudGVzdHMgPSBudWxsOwogICAgICAgIH0sCgogICAgICAgIGV4ZWNFdmVudCA6IGZ1bmN0aW9uKGV2ZW50TmFtZSkgewogICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBTdWJmb3JtU2V0LmRlZmluZVByb3BzKHsKICAgICAgICAiYWNjZXNzIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgIC8vaSBhbSBub3Qgc3VyZSBob3cgdG8gbWFrZSB0aGlzIHByb3BlcnR5IHVuZGVmaW5lZCBzbyBqdXN0IHJlbW92ZWQgc2V0dGVycyBmb3Igbm93CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwuYWNjZXNzLCB0aGlzLl9kZWZhdWx0cy5hY2Nlc3MpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvL1RPRE8gOiBBZGQgc2V0dGVyIHRvIGRlbGVnYXRlIHRvIGNoaWxkcmVuCgogICAgICAgIH0sCgogICAgICAgICJwcmVzZW5jZSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IC8vaSBhbSBub3Qgc3VyZSBob3cgdG8gbWFrZSB0aGlzIHByb3BlcnR5IHVuZGVmaW5lZCBzbyBqdXN0IHJlbW92ZWQgc2V0dGVycyBmb3Igbm93CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwucHJlc2VuY2UsIHRoaXMuX2RlZmF1bHRzLnByZXNlbmNlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9UT0RPIDogQWRkIHNldHRlciB0byBkZWxlZ2F0ZSB0byBjaGlsZHJlbgogICAgICAgIH0KCiAgICB9KTsKfSkoXyx4ZmFsaWIpOy8qKgogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIEFyZWEgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyBhIEFyZWEgaW4gdGhlIFhGQSBEb20KICogQHZlcnNpb24gMC4wLjEKICovCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgQXJlYSA9IHhmYWxpYi5zY3JpcHQuQXJlYSA9IHhmYWxpYi5zY3JpcHQuRXZlbnRDb250YWluZXJOb2RlLmV4dGVuZCh7CiAgICAgICAgZXhlY0V2ZW50IDogZnVuY3Rpb24oZXZlbnROYW1lKSB7CiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgfSwKCiAgICAgICAgcGxheUpzb25Gb3JFbGVtZW50IDogeGZhbGliLnNjcmlwdC5TdWJmb3JtLnByb3RvdHlwZS5wbGF5SnNvbkZvckVsZW1lbnQKCiAgICB9KTsKCiAgICBBcmVhLmRlZmluZVByb3BzKHsKICAgICAgICAiYWNjZXNzIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7ICAvL2kgYW0gbm90IHN1cmUgaG93IHRvIG1ha2UgdGhpcyBwcm9wZXJ0eSB1bmRlZmluZWQgc28ganVzdCByZW1vdmVkIHNldHRlcnMKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5hY2Nlc3MsIHRoaXMuX2RlZmF1bHRzLmFjY2Vzcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAicHJlc2VuY2UiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsgLy9pIGFtIG5vdCBzdXJlIGhvdyB0byBtYWtlIHRoaXMgcHJvcGVydHkgdW5kZWZpbmVkIHNvIGp1c3QgcmVtb3ZlZCBzZXR0ZXJzCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwucHJlc2VuY2UsIHRoaXMuX2RlZmF1bHRzLnByZXNlbmNlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKCiAgICBBcmVhLmFkZE1peGlucyhbCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRYWVdICiAgICBdKTsKCn0pKF8seGZhbGliKTsvKioKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBWYXJpYWJsZXMgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyBhIFZhcmlhYmxlcyBpbiB0aGUgWEZBIERvbQogKiBAdmVyc2lvbiAwLjAuMQogKi8KKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBWYXJpYWJsZXMgPSB4ZmFsaWIuc2NyaXB0LlZhcmlhYmxlcyA9IHhmYWxpYi5zY3JpcHQuQ29udGFpbmVyTm9kZS5leHRlbmQoewogICAgICAgIF9pbml0Q2hpbGRyZW46IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gbmV3IEFycmF5KCk7CiAgICAgICAgICAgIGlmICh0aGlzLmpzb25Nb2RlbC5jaGlsZHJlbikgewogICAgICAgICAgICAgICAgdmFyIGogPSAwOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmpzb25Nb2RlbC5jaGlsZHJlbi5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuW2ldOwogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZE1vZGVsID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVOb2RlVmFsdWUoY2hpbGQpOwogICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZE1vZGVsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuW2orK10gPSBjaGlsZE1vZGVsOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgIC8vIGRvbid0IG5lZWQgdmFyaWFibGVzIGZvciBzdWJtaXNzaW9uLCBidXQgbmVlZCB0aGVtIGZvciByZXBsYXkgb24gcmVzdG9yZUZvcm1TdGF0ZQogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLnN0cmlwT3JDYWxsLmNhbGwodGhpcywgZGlmZl9sZXZlbCA9PT0gMiwgVmFyaWFibGVzLl9zdXBlci5fY29tcHV0ZUpzb25EaWZmLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIHNjb3BlbGVzczogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gKCh0aGlzLm5hbWUgfHwgIiIpLmxlbmd0aCA9PSAwKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm4gdGhlIERhdGFTT01NYXAgYWZ0ZXIgYWRkaW5nIGFuIGVudHJ5IGluIHRoZSBtYXAgZm9yIHRoZSBub2RlLiBUaGUgZW50cnkgY29udGFpbnMgdGhlIHZhbHVlIG9mIHRoZSBub2RlCiAgICAgICAgICogYWxvbmcgd2l0aCBpdHMgRGF0YSBTT00uIElmIHRoZXJlIGlzIG5vIERhdGEgU09NIHRoZW4gcmV0dXJuIHRoZSB1bm1vZGlmaWVkIG1hcAogICAgICAgICAqIEBwYXJhbSBtYXAKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9nZXREYXRhU29tTWFwOiBmdW5jdGlvbiAobWFwKSB7CiAgICAgICAgICAgIHJldHVybiBtYXA7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXBkYXRlIHRoZSB2YWx1ZSBvZiB0aGUgbm9kZSB3aXRoIHRoZSB2YWx1ZSBwcm92aWRlZCBpbiB0aGUgaW5wdXQgbWFwLiBUaGUgbWFwIGNvbnRhaW5zIHRoZSB2YWx1ZXMgb2YgdGhlIGZpZWxkcwogICAgICAgICAqIG1hcHBlZCB3aXRoIHRoZWlyIERhdGFTT00uIFRoZSBmdW5jdGlvbiBpcyBlbXB0eSBmb3IgYWxsIHRoZSBub2RlcywgZXhjZXB0IGZvciBGaWVsZCwgU3ViZm9ybSBhbmQgQXJlYS4KICAgICAgICAgKiBAcGFyYW0gbWFwCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfcmVzdG9yZURhdGFTb21NYXAgOiBmdW5jdGlvbiAobWFwKSB7CgogICAgICAgIH0KCiAgICB9KTsKCiAgICBWYXJpYWJsZXMuZGVmaW5lUHJvcHMoewogICAgICAgICJwcmVzZW5jZSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IC8vaSBhbSBub3Qgc3VyZSBob3cgdG8gbWFrZSB0aGlzIHByb3BlcnR5IHVuZGVmaW5lZCBzbyBqdXN0IHJlbW92ZWQgc2V0dGVycwogICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sIHhmYWxpYik7Ci8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0Lk9jY3VyCiAqIEBpbXBvcnQgeGZhbGliLnV0LkNsYXNzCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgT2NjdXIgQ2xhc3MgcmVxdWlyZWQgYnkgSW5zdGFuY2VNYW5hZ2VyCiAqICAgICAgICAgICAgICAgZm9yIFhGQSBsaWJyYXJ5CiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3IE9jY3VyIG9iamVjdAogICAgICoKICAgICAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyB0aGUgT2NjdXIgT2JqZWN0CiAgICAgKiBAY29uc3RydWN0b3IKICAgICAqIEBwYXJhbSB7bnVtYmVyfQogICAgICAgICogICAgICAgICAgICBpbml0aWFsIEluaXRpYWwgb2NjdXJyZW5jZSBvZiB0aGUgc3ViZm9ybSBtYW5hZ2VkIGJ5IHBhcmVudAogICAgICogICAgICAgICAgICBJbnN0YW5jZU1hbmFnZXIKICAgICAqIEBwYXJhbSB7bnVtYmVyfQogICAgICAgICogICAgICAgICAgICBtYXggTWF4aW11bSBvY2N1cnJlbmNlIG9mIHRoZSBzdWJmb3JtIG1hbmFnZWQgYnkgcGFyZW50CiAgICAgKiAgICAgICAgICAgIEluc3RhbmNlTWFuYWdlcgogICAgICogQHBhcmFtIHtudW1iZXJ9CiAgICAgICAgKiAgICAgICAgICAgIG1pbiBNaW5pbXVtIG9jY3VycmVuY2Ugb2YgdGhlIHN1YmZvcm0gbWFuYWdlZCBieSBwYXJlbnQKICAgICAqICAgICAgICAgICAgSW5zdGFuY2VNYW5hZ2VyCiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gaW5pdGlhbCBJbml0aWFsIG9jY3VycmVuY2Ugb2YgdGhlIHN1YmZvcm0gbWFuYWdlZCBieQogICAgICogICAgICAgICAgIHBhcmVudCBJbnN0YW5jZU1hbmFnZXIKICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtYXggTWF4aW11bSBvY2N1cnJlbmNlIG9mIHRoZSBzdWJmb3JtIG1hbmFnZWQgYnkgcGFyZW50CiAgICAgKiAgICAgICAgICAgSW5zdGFuY2VNYW5hZ2VyCiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gbWluIE1pbmltdW0gb2NjdXJyZW5jZSBvZiB0aGUgc3ViZm9ybSBtYW5hZ2VkIGJ5IHBhcmVudAogICAgICogICAgICAgICAgIEluc3RhbmNlTWFuYWdlcgogICAgICovCiAgICB2YXIgT2NjdXIgPSB4ZmFsaWIuc2NyaXB0Lk9jY3VyID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CiAgICAgICAgX2RlZmF1bHRzIDogewogICAgICAgICAgICAibWluIiA6ICIxIiwKICAgICAgICAgICAgIm1heCIgOiAiMSIsCiAgICAgICAgICAgICJpbml0aWFsIiA6ICIxIgogICAgICAgIH0sCiAgICAgICAgbXNDbGFzc05hbWU6ICJvY2N1ciIKCiAgICB9KTsKCiAgICBPY2N1ci5kZWZpbmVQcm9wcyh7CiAgICAgICAgaW5pdGlhbDp7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwuaW5pdGlhbCwgdGhpcy5fZGVmYXVsdHMuaW5pdGlhbCkpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbWluOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwubWluLCB0aGlzLl9kZWZhdWx0cy5taW4pKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbihuTWluKSB7CiAgICAgICAgICAgIAl0aGlzLmpzb25Nb2RlbC5taW4gPSBuTWluICsgIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBtYXg6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5tYXgsIHRoaXMubWluKSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24obk1heCkgewogICAgICAgICAgICAJdGhpcy5qc29uTW9kZWwubWF4ID0gbk1heCArICIiOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcGxheUpzb24gOiBmdW5jdGlvbihwSnNvbk1vZGVsKSB7CgogICAgICAgIH0KCiAgICB9KQp9KShfLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5JbnN0YW5jZU1hbmFnZXIKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk5vZGUKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk9jY3VyCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgSW5zdGFuY2VNYW5hZ2VyIENsYXNzIHJlcXVpcmVkIGZvciBYRkEKICogICAgICAgICAgICAgICBsaWJyYXJ5CiAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyBhIEluc3RhbmNlIE1hbmFnZXIgdG8gbWFuYWdlIG11bHRpcGxlIGluc3RhbmNlIG9mCiAqICAgICAgICBzdWJmb3JtcwogKiBAdmVyc2lvbiAwLjAuMQogKi8KCihmdW5jdGlvbiAoXywgeGZhbGliKSB7CgogICAgdmFyIEluc3RhbmNlTWFuYWdlciA9IHhmYWxpYi5zY3JpcHQuSW5zdGFuY2VNYW5hZ2VyID0geGZhbGliLnNjcmlwdC5Ob2RlLmV4dGVuZCgKICAgICAgICB7CiAgICAgICAgICAgIG1zQ2xhc3NOYW1lOiAiaW5zdGFuY2VNYW5hZ2VyIiwKICAgICAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgSW5zdGFuY2VNYW5hZ2VyLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgICB0aGlzLl9vY2N1ciA9IG5ldyB4ZmFsaWIuc2NyaXB0Lk9jY3VyKHsianNvbk1vZGVsIjogdGhpcy5qc29uTW9kZWx9KTsKICAgICAgICAgICAgICAgIHRoaXMubW9DaGlsZHJlbkNyZWF0ZWQgPSBbXTsKICAgICAgICAgICAgICAgIHRoaXMubW5DdXJyZW50ID0gMDsKICAgICAgICAgICAgICAgIHRoaXMubWJTdGFuZGFsb25lID0gZmFsc2U7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfaW5zdGFuY2VUZW1wbGF0ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50OwogICAgICAgICAgICAgICAgaWYgKHRoaXMuX3RlbXBsYXRlUmVmKCkgPT0gbnVsbCB8fCBwYXJlbnQgPT0gbnVsbCB8fCBwYXJlbnQuX3RlbXBsYXRlUmVmKCkgPT0gbnVsbCB8fCBwYXJlbnQuX3RlbXBsYXRlUmVmKCkuY2hpbGRyZW4gPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIHZhciB0bXBsdFBhcmVudCA9IHBhcmVudC5fdGVtcGxhdGVSZWYoKTsKICAgICAgICAgICAgICAgIHZhciBpbUluZGV4ID0gdG1wbHRQYXJlbnQuY2hpbGRyZW4uaW5kZXhPZih0aGlzLl90ZW1wbGF0ZVJlZigpKTsKICAgICAgICAgICAgICAgIGlmIChpbUluZGV4IDwgMCB8fCB0bXBsdFBhcmVudC5jaGlsZHJlbi5sZW5ndGggPCBpbUluZGV4ICsgMikKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0bXBsdFBhcmVudC5jaGlsZHJlbltpbUluZGV4ICsgMV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfaXNSZXBlYXRhYmxlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgbWF4OwogICAgICAgICAgICAgICAgcmV0dXJuICgobWF4ID0gK3RoaXMubWF4KSA8IDAgfHwgK3RoaXMubWluIDwgbWF4KTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9pc0luc3RhbmNlTWFuYWdlcjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogTWFuYWdlIGEgY2hpbGQgaW5zdGFuY2UgdGhhdCB3YXMgY3JlYXRlZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIG9DcmVhdGVkQ2hpbGQKICAgICAgICAgICAgICogICAgICAgIHRoZSBjaGlsZCB0byBiZSBtYW5hZ2VkLgogICAgICAgICAgICAgKi8KCgogICAgICAgICAgICBfbWFuYWdlQ2hpbGQ6IGZ1bmN0aW9uIChvQ3JlYXRlZENoaWxkLCBuSW5kZXgpIHsKICAgICAgICAgICAgICAgIG9DcmVhdGVkQ2hpbGQuX2luc3RhbmNlTWFuYWdlciA9IHRoaXM7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5tb0NoaWxkcmVuQ3JlYXRlZC5sZW5ndGggPj0gMSkgewogICAgICAgICAgICAgICAgICAgIG9DcmVhdGVkQ2hpbGQgPSB0aGlzLl91cGRhdGVEYXRhU29tRm9yUmVwZWF0ZWRSb3dzKG9DcmVhdGVkQ2hpbGQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG5JbmRleCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb0NoaWxkcmVuQ3JlYXRlZC5zcGxpY2UodGhpcy5tbkN1cnJlbnQsIDAsIG9DcmVhdGVkQ2hpbGQpOwogICAgICAgICAgICAgICAgICAgIG9DcmVhdGVkQ2hpbGQubW5JbnN0YW5jZUluZGV4ID0gdGhpcy5tbkN1cnJlbnQrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoaXMubW9DaGlsZHJlbkNyZWF0ZWQuc3BsaWNlKG5JbmRleCwgMCwgb0NyZWF0ZWRDaGlsZCk7CiAgICAgICAgICAgICAgICAgICAgb0NyZWF0ZWRDaGlsZC5tbkluc3RhbmNlSW5kZXggPSBuSW5kZXg7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tbkN1cnJlbnQrKzsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gbkluZGV4ICsgMTsgaSA8IHRoaXMubW9DaGlsZHJlbkNyZWF0ZWQubGVuZ3RoOyBpKyspCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubW9DaGlsZHJlbkNyZWF0ZWRbaV0ubW5JbnN0YW5jZUluZGV4ID0gaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9yZXBsYWNlTGFzdE9jY3VycmVuY2VPZlN1YlN0cmluZzogZnVuY3Rpb24oc3RyaW5nLCBmaW5kLCByZXBsYWNlKSB7CiAgICAgICAgICAgICAgICB2YXIgbGFzdEluZGV4ID0gc3RyaW5nLmxhc3RJbmRleE9mKGZpbmQpOwogICAgICAgICAgICAgICAgaWYgKGxhc3RJbmRleCA9PT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyaW5nOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGJlZ2luU3RyaW5nID0gc3RyaW5nLnN1YnN0cmluZygwLCBsYXN0SW5kZXgpOwogICAgICAgICAgICAgICAgdmFyIGVuZFN0cmluZyA9IHN0cmluZy5zdWJzdHJpbmcobGFzdEluZGV4ICsgZmluZC5sZW5ndGgpOwogICAgICAgICAgICAgICAgcmV0dXJuIGJlZ2luU3RyaW5nICsgcmVwbGFjZSArIGVuZFN0cmluZzsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF91cGRhdGVEYXRhU29tRm9yUmVwZWF0ZWRSb3dzOiBmdW5jdGlvbihvQ3JlYXRlZENoaWxkKSB7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudERhdGFTb20gPSBvQ3JlYXRlZENoaWxkLmpzb25Nb2RlbC5leHRyYXMuZGF0YVNvbTsKICAgICAgICAgICAgICAgIHZhciBsZW5ndGhPZkNoaWxkQ3JlYXRlZCA9IHRoaXMubW9DaGlsZHJlbkNyZWF0ZWQubGVuZ3RoOwogICAgICAgICAgICAgICAgdmFyIGxhc3RBZGRlZFJvd0RhdGFTb20gPSB0aGlzLm1vQ2hpbGRyZW5DcmVhdGVkW2xlbmd0aE9mQ2hpbGRDcmVhdGVkIC0gMV0uanNvbk1vZGVsLmV4dHJhcy5kYXRhU29tOwogICAgICAgICAgICAgICAgaWYgKGN1cnJlbnREYXRhU29tICYmIGxhc3RBZGRlZFJvd0RhdGFTb20pIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXhUb1VwZGF0ZSA9IGN1cnJlbnREYXRhU29tLnN1YnN0cmluZyhjdXJyZW50RGF0YVNvbS5sYXN0SW5kZXhPZigiWyIpICsgMSwgY3VycmVudERhdGFTb20ubGFzdEluZGV4T2YoIl0iKSk7CiAgICAgICAgICAgICAgICAgICAgdmFyIHVwZGF0ZWREYXRhU29tSW5kZXggPSBsYXN0QWRkZWRSb3dEYXRhU29tLnN1YnN0cmluZyhsYXN0QWRkZWRSb3dEYXRhU29tLmxhc3RJbmRleE9mKCJbIikgKyAxLCBsYXN0QWRkZWRSb3dEYXRhU29tLmxhc3RJbmRleE9mKCJdIikpOwogICAgICAgICAgICAgICAgICAgIHVwZGF0ZWREYXRhU29tSW5kZXgrKzsKICAgICAgICAgICAgICAgICAgICB2YXIgdXBkYXRlZERhdGFTb20gPSB0aGlzLl9yZXBsYWNlTGFzdE9jY3VycmVuY2VPZlN1YlN0cmluZyhjdXJyZW50RGF0YVNvbSwgaW5kZXhUb1VwZGF0ZSwgdXBkYXRlZERhdGFTb21JbmRleCk7CiAgICAgICAgICAgICAgICAgICAgb0NyZWF0ZWRDaGlsZC5qc29uTW9kZWwuZXh0cmFzLmRhdGFTb20gPSB1cGRhdGVkRGF0YVNvbTsKICAgICAgICAgICAgICAgICAgICBvQ3JlYXRlZENoaWxkLnJlc29sdmVOb2RlKCIjZXh0cmFzLkZTX0VYVFJBUy5GU19EQVRBX1NPTSIpLnZhbHVlID0gdXBkYXRlZERhdGFTb207CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gb0NyZWF0ZWRDaGlsZDsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgICAgICAvL3dlIGRvbid0IG5lZWQgSW5zdGFuY2VNYW5hZ2VyIGZvciBmaW5hbCBzdWJtaXNzaW9uIGlmIHRoZXJlIGlzIG9ubHkgb25lIGluc3RhbmNlLCBhbmQgaXQncyBub3QgYSByZXBlYXRhYmxlIFNGCiAgICAgICAgICAgICAgICAvLyBidXQgbmVlZCBpdCBmb3IgbWFpbnRhaW5pbmcgaGllcmFyY2h5IGluIHJlc3RvcmVGb3JtU3RhdGUKICAgICAgICAgICAgICAgIHJldHVybiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuc3RyaXBPckNhbGwuY2FsbCh0aGlzLCBkaWZmX2xldmVsID09PSAyICYmICghdGhpcy5faXNSZXBlYXRhYmxlKCkgJiYgdGhpcy5tb0NoaWxkcmVuQ3JlYXRlZC5sZW5ndGggPD0gMSksIEluc3RhbmNlTWFuYWdlci5fc3VwZXIuX2NvbXB1dGVKc29uRGlmZiwgYXJndW1lbnRzKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGFkZCBhbiBpbnN0YW5jZSBvZiB0aGUgcmVwZWF0YWJsZSBzdWJmb3JtLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYWRkSW5zdGFuY2U6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9pbnNlcnRJbnN0YW5jZSgpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgX2luc2VydEluc3RhbmNlOiBmdW5jdGlvbiAobkluZGV4LCBvQ2hpbGRBZGRlZCkgewogICAgICAgICAgICAgICAgaWYgKCgrdGhpcy5tYXggPj0gMCkgJiYgKCt0aGlzLm1heCA9PSB0aGlzLmNvdW50KSkgLy9UT0RPIDogZGlzY3VzcyB3aGV0aGVyIHRvIHVzZSBwcml2YXRlIHZhcmlhYmxlcyBvciBub3QKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIGlmIChuSW5kZXggIT09IHVuZGVmaW5lZCAmJiBuSW5kZXggPiArdGhpcy5jb3VudCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKCiAgICAgICAgICAgICAgICBpZiAob0NoaWxkQWRkZWQgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgIHZhciBzZlRlbXBsYXRlID0gdGhpcy5faW5zdGFuY2VUZW1wbGF0ZSgpOwogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgLy8gbmVlZHMgdG8gYWRkIGFuIGluc3RhbmNlIHRvIHRoZSBtb2RlbAogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgaWYgKHNmVGVtcGxhdGUgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNsb25lZEpzb24gPSB7fTsKICAgICAgICAgICAgICAgICAgICB2YXIgdW5pcXVlUHJlZml4ID0gdGhpcy54ZmFVdGlsKCkuZ2VuZXJhdGVVSUQoKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmNvcHlPYmplY3Qoc2ZUZW1wbGF0ZSwgY2xvbmVkSnNvbiwKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uczogWyJodG1sSWQiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybU1hcHM6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGF0YUlkIjogZnVuY3Rpb24gKHNyY1ZhbHVlLCBvcHRpb25zKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmlxdWVQcmVmaXggKyAiXyIgKyBzcmNWYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIG9DaGlsZEFkZGVkID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVNb2RlbChjbG9uZWRKc29uKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChvQ2hpbGRBZGRlZCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAvLyBmaXJzdCBhZGQgdGhlIGNoaWxkIHRvIHRoZSBsaXN0IG9mIG1hbmFnZWQgY2hpbGRyZW4KICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgIG9DaGlsZEFkZGVkLl9uZXdDaGlsZCA9IHRydWUKICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYW5hZ2VDaGlsZChvQ2hpbGRBZGRlZCwgbkluZGV4KTsKICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgIC8vVE9ETzogSWYgbm90IHN0YW5kYWxvbmUgbW9kZSwgYWRkIHRoZSBuZXcgaXRlbSB0byB0aGUgcGFyZW50IGNvbnRhaW5lciBhcyB3ZWxsLiBVbmRlcnN0YW5kaW5nIHN0YW5kYWxvbmUgbW9kZQogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubWJTdGFuZGFsb25lID09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5JbmRleCAhPT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb0NoaWxkQWRkZWQuaW5kZXggPSBuSW5kZXg7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9DaGlsZEFkZGVkLmluZGV4ID0gdGhpcy5tbkN1cnJlbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIG9DaGlsZEFkZGVkLnBhcmVudCA9IHRoaXMucGFyZW50OwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvUGFyZW50Q29udGFpbmVyID0gdGhpcy5wYXJlbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvUGFyZW50Q29udGFpbmVyICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm1uQ3VycmVudCA+IDEgJiYgbkluZGV4IT09MCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgd2UgYWxyZWFkeSBoYWQgY2hpbGRyZW4gZ2V0IHRoZSBpbmRleCBvZiBmaXJzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoaWxkIGluIHRoZSBwYXJlbnQgY29udGFpbmVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuSW5kZXggPSBuSW5kZXggIT09IHVuZGVmaW5lZCA/IG5JbmRleCA6IHRoaXMubW5DdXJyZW50IC0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbkluc2VydGlvbkluZGV4ID0gb1BhcmVudENvbnRhaW5lcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuX2dldENoaWxkSW5kZXgodGhpcy5tb0NoaWxkcmVuQ3JlYXRlZFtuSW5kZXggLSAxXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkluc2VydGlvbkluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb1BhcmVudENvbnRhaW5lci5fYWRkQ2hpbGRBdChvQ2hpbGRBZGRlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkluc2VydGlvbkluZGV4KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIGlzIHRoZSBmaXJzdCBjaGlsZCwgYWRkIGl0IGp1c3QgYWZ0ZXIgdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5zdGFuY2UgbWFuYWdlcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb1BhcmVudENvbnRhaW5lci5fYWRkQ2hpbGRBdChvQ2hpbGRBZGRlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9QYXJlbnRDb250YWluZXIuX2dldENoaWxkSW5kZXgodGhpcykgKyAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKF8uY29udGFpbnMoWydJTklUSUFMSVpFRCcsICdJTklUSUFMSVpJTkcnXSwgdGhpcy5feGZhKCkuX21vZGVsSW5pdGlhbGl6ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9DaGlsZEFkZGVkLmV4ZWNJbml0aWFsaXplKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGUgaW5zdGFuY2UgYmVpbmcgYWRkZWQgaXMgdGhlIGZpcnN0IG9uZSwgd2UgbmVlZCB0byBydW4gZXhlY0NhbGN1bGF0ZSBvbiB0aGUgZm9ybSB0byBnZXQgZGVwZW5kZW50cwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIHRoZSBpbnN0YW5jZSBiZWluZyBhZGRlZC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvdW50ID09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5mb3JtLmV4ZWNDYWxjdWxhdGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZpcnN0SW5zdGFuY2UgPSB0aGlzLmluc3RhbmNlc1swXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmlnZ2VyQ2FsY3VsYXRlRm9yRGVwZW5kYW50RmllbGRzKGZpcnN0SW5zdGFuY2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9DaGlsZEFkZGVkLmV4ZWNDYWxjdWxhdGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLkxvZ2dlci5lcnJvcigieGZhIiwgeGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDEzIl0sIFsiYWRkSW5zdGFuY2UiXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9DaGlsZEFkZGVkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBpbnNlcnRJbnN0YW5jZTogZnVuY3Rpb24gKG5JbmRleCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2luc2VydEluc3RhbmNlKG5JbmRleCk7CiAgICAgICAgICAgIH0sCgoKICAgICAgICAgICAgbW92ZUluc3RhbmNlOiBmdW5jdGlvbiAoc0luZGV4LCBkSW5kZXgpIHsKICAgICAgICAgICAgICAgIGlmICgoK3RoaXMubWF4ID49IDApICYmIGRJbmRleCA+PSArdGhpcy5jb3VudCB8fCBzSW5kZXggPj0gK3RoaXMuY291bnQgfHwgc0luZGV4ID09IGRJbmRleCkgLy9UT0RPIDogZGlzY3VzcyB3aGV0aGVyIHRvIHVzZSBwcml2YXRlIHZhcmlhYmxlcyBvciBub3QKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIHZhciB0SW5kZXgsCiAgICAgICAgICAgICAgICAgICAgb1BhcmVudENvbnRhaW5lciA9IHRoaXMucGFyZW50LAogICAgICAgICAgICAgICAgICAgIG9DaGlsZCA9IHRoaXMubW9DaGlsZHJlbkNyZWF0ZWRbc0luZGV4XSwKICAgICAgICAgICAgICAgICAgICB0c0luZGV4ID0gZEluZGV4IDwgc0luZGV4ID8gc0luZGV4ICsgMSA6IHNJbmRleCwKICAgICAgICAgICAgICAgICAgICB0ZEluZGV4ID0gZEluZGV4ID4gc0luZGV4ID8gZEluZGV4ICsgMSA6IGRJbmRleDsKICAgICAgICAgICAgICAgIHRoaXMubWF4Kys7CiAgICAgICAgICAgICAgICB2YXIgbmV3Q2hpbGQgPSB0aGlzLl9pbnNlcnRJbnN0YW5jZSh0ZEluZGV4KTsKICAgICAgICAgICAgICAgIHRoaXMubWF4LS07CiAgICAgICAgICAgICAgICBuZXdDaGlsZC5wbGF5SnNvbihvQ2hpbGQuanNvbk1vZGVsKTsKICAgICAgICAgICAgICAgIGlmIChvUGFyZW50Q29udGFpbmVyICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuQ0hJTERfTU9WRUQsIG9QYXJlbnRDb250YWluZXIsICJjaGlsZCIsIG51bGwsIG51bGwpOwogICAgICAgICAgICAgICAgICAgIG9QYXJlbnRDb250YWluZXIudHJpZ2dlcihldm50Lm5hbWUsIGV2bnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVJbnN0YW5jZSh0c0luZGV4KTsKICAgICAgICAgICAgfSwKCgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBhZGQgYW4gaW5zdGFuY2Ugb2YgdGhlIHJlcGVhdGFibGUgc3ViZm9ybS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJlbW92ZUluc3RhbmNlOiBmdW5jdGlvbiAoaW5kZXgpIHsKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAvLyBkb24ndCByZW1vdmUgYW55IG1vcmUgdGhhbiB0aGUgbWluaW11bQogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvdW50ID09IDAgfHwgdGhpcy5taW4gPT0gdGhpcy5jb3VudCkKICAgICAgICAgICAgICAgICAgICByZXR1cm47CgogICAgICAgICAgICAgICAgaWYgKGluZGV4ID49ICt0aGlzLmNvdW50KQogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAvLyBuZWVkcyB0byByZW1vdmUgYW4gaW5zdGFuY2UgdG8gdGhlIG1vZGVsCiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgdmFyIGZpcnN0SW5zdGFuY2UgPSB0aGlzLmluc3RhbmNlc1swXTsKICAgICAgICAgICAgICAgIHZhciBvQ2hpbGQgPSB0aGlzLm1vQ2hpbGRyZW5DcmVhdGVkW2luZGV4XTsKICAgICAgICAgICAgICAgIHRoaXMubW9DaGlsZHJlbkNyZWF0ZWQuc3BsaWNlKGluZGV4LCAxKTsKICAgICAgICAgICAgICAgIHRoaXMubW5DdXJyZW50LS07CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gaW5kZXg7IGkgPCB0aGlzLm1vQ2hpbGRyZW5DcmVhdGVkLmxlbmd0aDsgaSsrKQogICAgICAgICAgICAgICAgICAgIHRoaXMubW9DaGlsZHJlbkNyZWF0ZWRbaV0ubW5JbnN0YW5jZUluZGV4ID0gaTsKICAgICAgICAgICAgICAgIHZhciBwYXJlbnQgPSBvQ2hpbGQucGFyZW50OwogICAgICAgICAgICAgICAgcGFyZW50Ll9yZW1vdmVDaGlsZChvQ2hpbGQpOwoKICAgICAgICAgICAgICAgIGlmIChfLmNvbnRhaW5zKFsnSU5JVElBTElaRUQnLCAnSU5JVElBTElaSU5HJ10sIHRoaXMuX3hmYSgpLl9tb2RlbEluaXRpYWxpemUpKSB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlckNhbGN1bGF0ZUZvckRlcGVuZGFudEZpZWxkcyhmaXJzdEluc3RhbmNlKTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5Mb2dnZXIuZXJyb3IoInhmYSIsIHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAxMyJdLCBbInJlbW92ZUluc3RhbmNlIl0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGVtcHR5IGZ1bmN0aW9uIHNpbmNlIHRoZXJlIGlzIG5vIGRhdGEgYXNzb2NpYXRlZCB3aXRoIElNCiAgICAgICAgICAgICAqLwogICAgICAgICAgICByZXNldERhdGE6IGZ1bmN0aW9uICgpIHsKCiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBzZXRJbnN0YW5jZXM6IGZ1bmN0aW9uIChudW0pIHsKICAgICAgICAgICAgICAgIHRoaXMuY291bnQgPSBudW07CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBnZXROYWtlZDogZnVuY3Rpb24gKG5JbmRleCwgY3JlYXRlR2V0dGVyU2V0dGVyLCBPYmosIHNjb3BlKSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5nZXRBdHRyaWJ1dGUoIm5hbWUiKS5sZW5ndGggPiAwICYmIHRoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIikgIT0gIl8iKQogICAgICAgICAgICAgICAgICAgIEluc3RhbmNlTWFuYWdlci5fc3VwZXIuZ2V0TmFrZWQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHBsYXlKc29uOiBmdW5jdGlvbiAocEpzb25Nb2RlbCkgewoKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVHJpZ2dlciBjYWxjdWxhdGUgZXZlbnQgZm9yIG9ubHkgdGhlIGRlcGVuZGVudCBmaWVsZHMgaW4gdGhlIHJlcGVhdGFibGUgc3ViZm9ybQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgX3RyaWdnZXJDYWxjdWxhdGVGb3JEZXBlbmRhbnRGaWVsZHMgOiBmdW5jdGlvbiAobW9kZWwpIHsKICAgICAgICAgICAgICAgIHZhciBtb2RlbENoaWxkcmVuID0gbW9kZWwubW9DaGlsZE5vZGVzOwogICAgICAgICAgICAgICAgXy5lYWNoKG1vZGVsQ2hpbGRyZW4sIGZ1bmN0aW9uKG1vZGVsQ2hpbGQpewogICAgICAgICAgICAgICAgICAgIC8vIHRyaWdnZXIgY2FsY3VsYXRlIGZvciB0aGUgZGVwZW5kZW50cyBvZiB0aGUgZmllbGQgYW5kIGV4Y2x1c2lvbiBncm91cAogICAgICAgICAgICAgICAgICAgIGlmIChtb2RlbENoaWxkLl9pc0ZpZWxkKCkgfHwgbW9kZWxDaGlsZC5faXNFeGNsdXNpb25Hcm91cCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZXBlbmRhbnROb2RlcyA9IG1vZGVsQ2hpbGQuZGVwZW5kYW50OwogICAgICAgICAgICAgICAgICAgICAgICBfLmVhY2goZGVwZW5kYW50Tm9kZXMsIGZ1bmN0aW9uKGRlcGVuZGFudE5vZGUpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwZW5kYW50Tm9kZS5leGVjRXZlbnQoImNhbGN1bGF0ZSIpOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG1vZGVsQ2hpbGQuX2lzRXZlbnROb2RlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlckNhbGN1bGF0ZUZvckRlcGVuZGFudEZpZWxkcyhtb2RlbENoaWxkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgKTsKICAgIEluc3RhbmNlTWFuYWdlci5kZWZpbmVQcm9wcyh7CiAgICAgICAgIm1pbiI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vY2N1ci5taW4gKyAiIjsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAobk1pbikgewogICAgICAgICAgICAgICAgdGhpcy5vY2N1ci5taW4gPSBuTWluOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAibWF4IjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9jY3VyLm1heCArICIiOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuTWF4KSB7CiAgICAgICAgICAgICAgICB0aGlzLm9jY3VyLm1heCA9IG5NYXg7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAib2NjdXIiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29jY3VyOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAvLyBUaGlzIEFQSSBpcyB1c2VkIGluIGFkYXB0aXZlIGZvcm0KICAgICAgICAiaW5zdGFuY2VzIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIF8uZXh0ZW5kKFtdLCB0aGlzLm1vQ2hpbGRyZW5DcmVhdGVkKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJjb3VudCI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tb0NoaWxkcmVuQ3JlYXRlZC5sZW5ndGggKyAiIjsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBwYXJzZUludCh2YWx1ZSkpCiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZUludCh2YWx1ZSk7CiAgICAgICAgICAgICAgICBlbHNlIHJldHVybjsKICAgICAgICAgICAgICAgIHZhciBjb3VudCA9ICt0aGlzLmNvdW50LAogICAgICAgICAgICAgICAgICAgIHR2YWx1ZSA9IE1hdGguYWJzKHZhbHVlIC0gY291bnQpLAogICAgICAgICAgICAgICAgICAgIG1heCA9ICt0aGlzLm1heCwKICAgICAgICAgICAgICAgICAgICBtaW4gPSArdGhpcy5taW47CiAgICAgICAgICAgICAgICAvL0J1ZyMzNTQ0MzY4IHZhbHVlID4gbWF4IGNvbmRpdGlvbiB3aWxsIG9ubHkgaG9sZCBpZiBtYXggaXMgcG9zaXRpdmUgKGlmIG1heCA9PSAtMQogICAgICAgICAgICAgICAgLy8gdGhlcmUgaXMgbm8gbGltaXQgb24gdGhlIHVwcGVyIGNvdW50ICkKICAgICAgICAgICAgICAgIGlmICgobWF4ID4gMCAmJiB2YWx1ZSA+IG1heCkgfHwgdmFsdWUgPCBtaW4gfHwgdmFsdWUgPT0gY291bnQpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgaWYgKHZhbHVlID4gY291bnQpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR2YWx1ZTsgaSsrKQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbnNlcnRJbnN0YW5jZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHZhbHVlIDwgY291bnQpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR2YWx1ZTsgaSsrKQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUluc3RhbmNlKC0tY291bnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSkKfSkoXywgeGZhbGliKTsKCi8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LkV4Y2x1c2lvbkdyb3VwCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Db250YWluZXJOb2RlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgRXhjbHVzaW9uR3JvdXAgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQQogKiAgICAgICAgICAgICAgIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBFeGNsdXNpb25Hcm91cCBjbGFzcwogICAgICoKICAgICAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyBhIEV4Y2x1c2lvbkdyb3VwIGluIHRoZSBYRkEgRG9tCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgbm9kZQogICAgICogQGV4dGVuZHMgY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuQ29udGFpbmVyTm9kZQogICAgICovCiAgICB2YXIgRXhjbHVzaW9uR3JvdXAgPSB4ZmFsaWIuc2NyaXB0LkV4Y2x1c2lvbkdyb3VwID0geGZhbGliLnNjcmlwdC5FdmVudENvbnRhaW5lck5vZGUuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIEV4Y2x1c2lvbkdyb3VwLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMudGVzdHM9IFt0aGlzLl9udWxsVGVzdCx0aGlzLl9zY3JpcHRUZXN0XTsKICAgICAgICAgICAgdmFyIGRhdGFJZCA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMsICJqc29uTW9kZWwuZXh0cmFzLmRhdGFJZCIsIG51bGwpOwogICAgICAgICAgICBpZiAoZGF0YUlkKSB7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5jcmVhdGVEYXRhTm9kZShkYXRhSWQsIHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldE9uQ2hpbGQ6IGZ1bmN0aW9uKG90aGVyQ2hpbGQpIHsKICAgICAgICAgICAgcmV0dXJuIF8uZmluZCh0aGlzLm1vQ2hpbGROb2RlcywgZnVuY3Rpb24oY2hpbGQpIHsKICAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGQuY2xhc3NOYW1lID09ICJmaWVsZCIgJiYgY2hpbGQuc2VsZWN0ZWRJbmRleCA9PSAwICYmIGNoaWxkICE9IG90aGVyQ2hpbGQKICAgICAgICAgICAgfSkKICAgICAgICB9LAoKICAgICAgICBfZXZlbnRIYW5kbGVyIDogZnVuY3Rpb24oZXZlbnROYW1lKSB7CiAgICAgICAgICAgIHZhciByVmFsdWUgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIHN3aXRjaChldmVudE5hbWUpIHsKICAgICAgICAgICAgICAgIGNhc2UgImNhbGN1bGF0ZSI6CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl0gJiYgdGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl0ubGVuZ3RoID4wKXsKICAgICAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl1bMF0uZXhlY3V0ZSh0aGlzLCAiY2FsY3VsYXRlIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAidmFsaWRhdGUiOgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMubW9FdmVudHNbInZhbGlkYXRlIl0gJiYgdGhpcy5tb0V2ZW50c1sidmFsaWRhdGUiXS5sZW5ndGggPjApewogICAgICAgICAgICAgICAgICAgICAgICByVmFsdWUgPSB0aGlzLm1vRXZlbnRzWyJ2YWxpZGF0ZSJdWzBdLmV4ZWN1dGUodGhpcywgInZhbGlkYXRlIik7CiAgICAgICAgICAgICAgICAgICAgfWVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIiRmb3JtcHJlU3VibWl0IjoKICAgICAgICAgICAgICAgICAgICByVmFsdWUgPSB0aGlzLl9wcmVTdWJtaXRFdmVudEhhbmRsZXIoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubW9FdmVudHNbZXZlbnROYW1lXSkgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKCB2YXIgaSA9IDA7IGkgPCB0aGlzLm1vRXZlbnRzW2V2ZW50TmFtZV0ubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubW9FdmVudHNbZXZlbnROYW1lXVtpXS5leGVjdXRlKHRoaXMsIGV2ZW50TmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9Ci8vICAgICAgICAgICAgICAgICAgICBFeGNsdXNpb25Hcm91cC5fc3VwZXIuX2V2ZW50SGFuZGxlci5jYWxsKHRoaXMsIGV2ZW50TmFtZSk7ICAvL1RPRE86IFdoeSB0aGlzIGlzIHJlcXVpcmVkPwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByVmFsdWUKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlU2VsZWN0Q2hpbGQgOiBmdW5jdGlvbihjaGlsZCkgewogICAgICAgICAgICB2YXIgb2xkVmFsID0gdGhpcy5yYXdWYWx1ZSwKICAgICAgICAgICAgICAgIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsIkNsZWFyRXJyb3IiLG51bGwsIG51bGwpLAogICAgICAgICAgICAgICAgb25DaGlsZCA9IHRoaXMuX2dldE9uQ2hpbGQoY2hpbGQpOwoKICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKCiAgICAgICAgICAgIGlmIChjaGlsZC5zZWxlY3RlZEluZGV4ID09IDApIHsKICAgICAgICAgICAgICAgIGlmKG9uQ2hpbGQpCiAgICAgICAgICAgICAgICAgICAgb25DaGlsZC5zZXRJdGVtU3RhdGUoMCxmYWxzZSk7CiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVEZXBlbmRhbnRzKCk7CiAgICAgICAgICAgICAgICAvLyB0cmlnZ2VyIG1vZGVsIGNoYW5nZSBldmVudCBmb3IgcmF3VmFsdWUsIHNvIHRoYXQgdmFsdWUgY2FuIGJlIHByb3BvZ2F0ZWQgdG8gcmVzdCBvZiB0aGUgZmllbGRzIHdpdGggc2FtZSBkYXRhSWQKICAgICAgICAgICAgICAgIHZhciBldm50UmF3VmFsdWUgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLCJyYXdWYWx1ZSIsdGhpcy5yYXdWYWx1ZSwgdGhpcy5yYXdWYWx1ZSk7CiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudFJhd1ZhbHVlLm5hbWUsZXZudFJhd1ZhbHVlKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChjaGlsZC5fbWF0Y2hlcyhvbkNoaWxkKSkgewogICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZURlcGVuZGFudHMoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHNlbGVjdGVkTWVtYmVyIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBjdXJyZW50Tm9kZSA9IHRoaXMuX3hmYSgpLm1vQ2FsY3VsYXRlRXZlbnROb2RlOwogICAgICAgICAgICBpZiAoY3VycmVudE5vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhpcy5hZGREZXBlbmRhbnQoY3VycmVudE5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRPbkNoaWxkKCk7CiAgICAgICAgfSwKCiAgICAgICAgX2lzRXhjbHVzaW9uR3JvdXAgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSwKCiAgICAgICAgX2dldFZhbHVlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBvbkNoaWxkID0gdGhpcy5fZ2V0T25DaGlsZCgpCiAgICAgICAgICAgIHJldHVybiBvbkNoaWxkID8gb25DaGlsZC5fZ2V0VmFsdWUoKSA6IG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgX251bGxUZXN0IDogZnVuY3Rpb24oc01lc3NhZ2VzKSB7CiAgICAgICAgICAgIHZhciB2YWxpZCA9IHRydWU7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuX2dldFZhbHVlKCk7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsICYmIHRoaXMubWFuZGF0b3J5ICE9ICJkaXNhYmxlZCIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxUZXN0ID0gIm51bGxUZXN0IjsKICAgICAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxMZXZlbCA9IHRoaXMubWFuZGF0b3J5OwogICAgICAgICAgICAgICAgdGhpcy5fZXJyb3JUZXh0ID0gdGhpcy5tYW5kYXRvcnlNZXNzYWdlOwogICAgICAgICAgICAgICAgdGhpcy5fYWRkTWVzc2FnZShzTWVzc2FnZXMsIHRoaXMuX2Vycm9yVGV4dCwgdGhpcy5fbUZhaWxlZFZhbExldmVsKTsKICAgICAgICAgICAgICAgIHZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbGlkOwogICAgICAgIH0sCgogICAgICAgIF9nZXRFbGVtZW50c0Zyb21YcGF0aDogeGZhbGliLnNjcmlwdC5GaWVsZC5wcm90b3R5cGUuX2dldEVsZW1lbnRzRnJvbVhwYXRoLAoKICAgICAgICBfcHJlU3VibWl0RXZlbnRIYW5kbGVyOiB4ZmFsaWIuc2NyaXB0LkZpZWxkLnByb3RvdHlwZS5fcHJlU3VibWl0RXZlbnRIYW5kbGVyLAoKICAgICAgICAvKioKICAgICAgICAgKiBFeGNsdXNpb24gR3JvdXAgY2FuIGhhdmUgdHdvIHR5cGVzIG9mIHByZWZpbGwgeG1sLiBMb25nIGZvcm1hdCBhbmQgc2hvcnQgZm9ybWF0IC4gSW4gY2FzZSBvZiBMb25nIGZvcm1hdCwKICAgICAgICAgKiB0aGUgdmFsdWUgb2YgZWFjaCBvZiAgdGhlIGNoaWxkcmVuIG9mIGV4Y2x1c2lvbiBncm91cCBpcyBwcmVzZW50IGFuZCBoZW5jZSB3ZSBuZWVkIHRvIGl0ZXJhdGUgdGhlIGNoaWxkcmVuIHRvCiAgICAgICAgICogcHJlZmlsbCB0aGUgdmFsdWUuIEZvciBzaG9ydCBmb3JtYXQgdGhlIHRleHRDb250ZW50IGlzIHRoZSB2YWx1ZSBvZiB0aGUgRXhjbHVzaW9uIEdyb3VwCiAgICAgICAgICoKICAgICAgICAgKiBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBzaG9ydCBhbmQgTG9uZyBmb3JtYXQgaXMgdGhhdCBpbiBzaG9ydCBGb3JtYXQsIHRoZXJlIGFyZSBubyBjaGlsZHJlbiBvZiBFeGNsdXNpb24KICAgICAgICAgKiBHcm91cCBpbiB4bWwuCiAgICAgICAgICogQHBhcmFtIHhtbERvY3VtZW50CiAgICAgICAgICogQHBhcmFtIGNvbnRleHROb2RlCiAgICAgICAgICogQHBhcmFtIGN1cnJlbnRCaW5kUmVmCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfcGxheURhdGFYTUw6IGZ1bmN0aW9uKHhtbERvY3VtZW50LCBjb250ZXh0Tm9kZSwgY3VycmVudEJpbmRSZWYpIHsKICAgICAgICAgICAgdmFyIHhwYXRoID0gdGhpcy5fZ2V0WHBhdGhGcm9tQmluZFJlZigpLAogICAgICAgICAgICAgICAgbm9kZUl0ZXI7CiAgICAgICAgICAgIGlmKHhwYXRoICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIG5vZGVJdGVyID0gdGhpcy5fZ2V0RWxlbWVudHNGcm9tWHBhdGgoeHBhdGgsIGNvbnRleHROb2RlLCB4bWxEb2N1bWVudCk7CiAgICAgICAgICAgICAgICBpZihub2RlSXRlciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSBub2RlSXRlci5pdGVyYXRlTmV4dCgpOwogICAgICAgICAgICAgICAgICAgIGlmKG5vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBub2RlIGhhcyBmdXJ0aGVyIGVsZW1lbnQgY2hpbGRzIHRoZW4gaXRlcmF0ZSBvdmVyIHRoZW0gb3RoZXJ3aXNlIHNldCB0aGUgY29udGVudCBhcyBpdHMgcmF3VmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgaWYobm9kZS5jaGlsZEVsZW1lbnRDb3VudCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2x1c2lvbkdyb3VwLl9zdXBlci5fcGxheURhdGFYTUwuYXBwbHkodGhpcywgW3htbERvY3VtZW50LCBub2RlLCBjdXJyZW50QmluZFJlZl0pOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yYXdWYWx1ZSA9IG5vZGUudGV4dENvbnRlbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2V0RGF0YSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgZ2VuZXJhdGVEYXRhWE1MOiB4ZmFsaWIuc2NyaXB0LkZpZWxkLnByb3RvdHlwZS5nZW5lcmF0ZURhdGFYTUwsCgogICAgICAgIF9hcHBlbmRWYWx1ZUluWE1MRWxlbWVudDogeGZhbGliLnNjcmlwdC5GaWVsZC5wcm90b3R5cGUuX2FwcGVuZFZhbHVlSW5YTUxFbGVtZW50CiAgICB9KTsKCiAgICBFeGNsdXNpb25Hcm91cC5kZWZpbmVQcm9wcyh7CiAgICAgICAgInJhd1ZhbHVlIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudE5vZGUgPSB0aGlzLl94ZmEoKS5tb0NhbGN1bGF0ZUV2ZW50Tm9kZTsKICAgICAgICAgICAgICAgIGlmIChjdXJyZW50Tm9kZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGREZXBlbmRhbnQoY3VycmVudE5vZGUpOwogICAgICAgICAgICAgICAgICAgIC8vIFRoZSBjaGlsZHJlbiBzaG91bGQgbm90IHJlZ2lzdGVyIHRoZQogICAgICAgICAgICAgICAgICAgIC8vIGNhbGN1bGF0ZU5vZGUgYXMgZGVwZW5kZW50IG9uIHRoZW0sIGVsc2UgdGhlCiAgICAgICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIGV2ZW50IGZvciBjYWxjdWxhdGVOb2RlIHdpbGwgYmUgY2FsbGVkCiAgICAgICAgICAgICAgICAgICAgLy8gbXVsdGlwbGUgdGltZXMuCiAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuX3BvcENhbGN1bGF0ZUV2ZW50Tm9kZSgpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciB2YWwgPSB0aGlzLl9nZXRWYWx1ZSgpOwoKICAgICAgICAgICAgICAgIGlmIChjdXJyZW50Tm9kZSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLl9wdXNoQ2FsY3VsYXRlRXZlbnROb2RlKGN1cnJlbnROb2RlKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gdmFsOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbihvVmFsdWUpIHsKICAgICAgICAgICAgCXZhciBzTWVzc2FnZXMgPSBuZXcgQXJyYXkoKSwKICAgICAgICAgICAgICAgICAgICBvbkNoaWxkID0gdGhpcy5fZ2V0T25DaGlsZCgpLAogICAgICAgICAgICAgICAgICAgIG9sZFZhbCA9IG9uQ2hpbGQgPyBvbkNoaWxkLl9nZXRWYWx1ZSgpIDogbnVsbAoKICAgICAgICAgICAgICAgIG9WYWx1ZSA9IHRoaXMudmFsaWRhdGVJbnB1dChvVmFsdWUsICJzdHJpbmciKTsKICAgICAgICAgICAgICAgIGlmIChvbGRWYWwgPT09IG9WYWx1ZSkKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICBpZiAob25DaGlsZCkgewogICAgICAgICAgICAgICAgICAgIG9uQ2hpbGQuc2V0SXRlbVN0YXRlKDAsIGZhbHNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG9uQ2hpbGQgPSBfLmZpbmQodGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uKGNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZC5jbGFzc05hbWUgPT0gImZpZWxkIiAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQuZ2V0T3JFbHNlKGNoaWxkLmdldFNhdmVJdGVtKDApLCBjaGlsZC5nZXREaXNwbGF5SXRlbSgwKSkgPT0gb1ZhbHVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIGlmIChvbkNoaWxkKQogICAgICAgICAgICAgICAgICAgIG9uQ2hpbGQucmF3VmFsdWUgPSBvVmFsdWU7CiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVEZXBlbmRhbnRzKCk7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5xdWV1ZVZhbGlkYXRlRXZlbnQodGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAibWFuZGF0b3J5IiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy52YWxpZGF0ZS5udWxsVGVzdCwgdGhpcy5fZGVmYXVsdHMudmFsaWRhdGUubnVsbFRlc3QpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgaWYodGhpcy52YWxpZGF0ZSl7CiAgICAgICAgICAgICAgICAgICAgdGhpcy52YWxpZGF0ZS5udWxsVGVzdCA9IHZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgIm1lbWJlcnMiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICAgICAgdGhpcy5tb0NoaWxkTm9kZXMuZmlsdGVyKGZ1bmN0aW9uKGVsZW0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxlbS5faXNGaWVsZCgpOwogICAgICAgICAgICAgICAgfSkubWFwKGZ1bmN0aW9uKGVsZW0xKXsKICAgICAgICAgICAgICAgICAgICBsaXN0Ll9hcHBlbmQoZWxlbTEpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJpc051bGwiOnsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgIGlmKHRoaXMuX2dldFZhbHVlKCkgIT0gbnVsbClyZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgIGVsc2UgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAibWFuZGF0b3J5TWVzc2FnZSIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5fZ2V0TWFuZGF0b3J5TWVzc2FnZSh0aGlzKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICB2YXIgbm9kZXMgPSB0aGlzLnZhbGlkYXRlLm1lc3NhZ2Uubm9kZXM7CiAgICAgICAgICAgICAgICBpZiAobm9kZXMubmFtZWRJdGVtKCJudWxsVGVzdCIpID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSB0aGlzLl94ZmEoKS5mb3JtLmNyZWF0ZU5vZGUoInRleHQiLCAibnVsbFRlc3QiKTsKICAgICAgICAgICAgICAgICAgICBub2Rlcy5hcHBlbmQobm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLnZhbGlkYXRlLm1lc3NhZ2UubnVsbFRlc3QudmFsdWUgPSB2YWw7CiAgICAgICAgICAgICAgICB0aGlzLmV4ZWNWYWxpZGF0ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgRXhjbHVzaW9uR3JvdXAuYWRkTWl4aW5zKFsKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZEFzc2lzdCwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZENhcHRpb24sCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRQcmVzZW5jZSwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFhZV0gsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRGaWxsQ29sb3IsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRCb3JkZXIsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRCb3JkZXJDb2xvciwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFBhcmEsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRNYXJnaW4KICAgIF0pOwoKfSkoXywgeGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuTW9kZWwKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk5vZGUKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBNb2RlbCA9IHhmYWxpYi5zY3JpcHQuTW9kZWwgPSB4ZmFsaWIuc2NyaXB0LkVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZTogIm1vZGVsIiwKCiAgICAgICAgY3JlYXRlTm9kZSA6IGZ1bmN0aW9uKHNDbGFzc05hbWUsc05hbWUsc05hbWVzcGFjZSkgeyAgICAvL1RPRE86IGxvb2tzIGluY29tcGxldGUKICAgICAgICAgICAgc05hbWUgPSAodHlwZW9mIHNOYW1lICE9ICd1bmRlZmluZWQnKT9zTmFtZToiIjsKICAgICAgICAgICAgc05hbWVzcGFjZSA9ICh0eXBlb2Ygc05hbWVzcGFjZSAhPSAndW5kZWZpbmVkJyk/c05hbWVzcGFjZToiIjsKICAgICAgICAgICAgdmFyIGpzb25Nb2RlbCA9IHt9OwogICAgICAgICAgICBqc29uTW9kZWwuX2NsYXNzID0gc0NsYXNzTmFtZTsKICAgICAgICAgICAganNvbk1vZGVsLm5hbWUgPSBzTmFtZTsKICAgICAgICAgICAgdmFyIG5vZGUgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZU1vZGVsKGpzb25Nb2RlbCk7CiAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIpOwoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuRm9ybQogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuQ29udGFpbmVyTm9kZQogKi8KCihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICAvKioKICAgICAqIEBjbGFzcwogICAgICogPHA+CiAgICAgKiBUaGUgRm9ybSBjbGFzcyBpcyB0aGUgaW1wbGVtZW50YXRpb24gb2YgdGhlIHRvcCBsZXZlbCBYRkEgZm9ybSBvYmplY3QuCiAgICAgKiA8L3A+CiAgICAgKgogICAgICogPHA+CiAgICAgKiBUaGUgZm9ybSBvYmplY3QgaXMgYWNjZXNzZWQgZnJvbSB0aGUgeGZhIG9iamVjdCBhcyB4ZmEuZm9ybQogICAgICogPC9wPgogICAgICoKICAgICAqLwogICAgdmFyIEZvcm0gPSB4ZmFsaWIuc2NyaXB0LkZvcm0gPSB4ZmFsaWIuc2NyaXB0LkV2ZW50Q29udGFpbmVyTm9kZS5leHRlbmQoewogICAgICAgIF9nZXRSb290U3ViZm9ybTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5jaGlsZHJlblswXTsKICAgICAgICB9LAoKICAgICAgICBfaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLl94ZmEoKS5fbW9kZWxJbml0aWFsaXplID0gJ0lOSVRJQUxJWklORyc7CiAgICAgICAgICAgIHZhciByb290U3ViZm9ybSA9IHRoaXMuX2dldFJvb3RTdWJmb3JtKCk7CiAgICAgICAgICAgIHJvb3RTdWJmb3JtLl9pbml0aWFsaXplKCk7CiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIENhbGwgYWxsIGluaXRpYWxpemF0aW9uIHRoZW4KICAgICAgICAgICAgLy8gY2FsY3VsYXRpb25zCiAgICAgICAgICAgIC8vIHNjcmlwdHMgdG8gZXhlY3V0ZQogICAgICAgICAgICAvLwogICAgICAgICAgICB2YXIgcGdTZXRzID0gcm9vdFN1YmZvcm0ucmVzb2x2ZU5vZGVzKCIjcGFnZVNldFsqXSIpOwogICAgICAgICAgICBmdW5jdGlvbiBleGVjT25QZ1NldHMgKGV4ZWNGdW5jbmFtZSkgewogICAgICAgICAgICAgICAgZm9yKHZhciBpPTA7IGkgPCBwZ1NldHMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICBwZ1NldHMuaXRlbShpKVtleGVjRnVuY25hbWVdKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJvb3RTdWJmb3JtLmV4ZWNGb3JtUmVhZHkoKTsKICAgICAgICAgICAgZXhlY09uUGdTZXRzKCJleGVjRm9ybVJlYWR5Iik7CiAgICAgICAgICAgIHJvb3RTdWJmb3JtLmV4ZWNJbml0aWFsaXplKCk7CiAgICAgICAgICAgIGV4ZWNPblBnU2V0cygiZXhlY0luaXRpYWxpemUiKTsKICAgICAgICAgICAgcm9vdFN1YmZvcm0uZXhlY0xheW91dFJlYWR5KCk7CiAgICAgICAgICAgIGV4ZWNPblBnU2V0cygiZXhlY0xheW91dFJlYWR5Iik7CiAgICAgICAgICAgIHJvb3RTdWJmb3JtLmV4ZWNDYWxjdWxhdGUoKTsKICAgICAgICAgICAgdGhpcy5feGZhKCkuX21vZGVsSW5pdGlhbGl6ZSA9ICdJTklUSUFMSVpFRCc7CiAgICAgICAgfSwKCiAgICAgICAgcGxheUpzb246IGZ1bmN0aW9uIChwSnNvbk1vZGVsKSB7CiAgICAgICAgICAgIHRoaXMuX2dldFJvb3RTdWJmb3JtKCkucGxheUpzb24ocEpzb25Nb2RlbC5jaGlsZHJlblswXSk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAZnVuY3Rpb24gaW5kaWNhdGUgdGhhdCB0aGlzIGlzIGEgRm9ybSBub2RlICh+fikuCiAgICAgICAgICovCiAgICAgICAgX2lzRm9ybTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBleGVjQ2FsY3VsYXRlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRSb290U3ViZm9ybSgpLmV4ZWNDYWxjdWxhdGUoKTsKICAgICAgICB9LAoKICAgICAgICBleGVjSW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLl9nZXRSb290U3ViZm9ybSgpLmV4ZWNJbml0aWFsaXplKCk7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY0Zvcm1SZWFkeTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLl9nZXRSb290U3ViZm9ybSgpLmV4ZWNGb3JtUmVhZHkoKTsKICAgICAgICB9LAoKICAgICAgICBleGVjTGF5b3V0UmVhZHk6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdGhpcy5fZ2V0Um9vdFN1YmZvcm0oKS5leGVjTGF5b3V0UmVhZHkoKTsKICAgICAgICB9LAoKICAgICAgICBleGVjVmFsaWRhdGU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldFJvb3RTdWJmb3JtKCkuZXhlY1ZhbGlkYXRlKCk7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY1ByZVN1Ym1pdDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Um9vdFN1YmZvcm0oKS5leGVjUHJlU3VibWl0KCk7CiAgICAgICAgfSwKICAgICAgICAvKioKICAgICAgICAgKiByZW1lcmdlIHRoZSBkYXRhIHdpdGggdGhlIGZvcm0gbW9kZWwKICAgICAgICAgKi8KICAgICAgICByZW1lcmdlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuX2dldFJvb3RTdWJmb3JtKCkuX2JpbmQoKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiByZWNhbGN1bGF0ZSB0aGlzIGZvcm0gbW9kZWwKICAgICAgICAgKi8KICAgICAgICByZWNhbGN1bGF0ZTogZnVuY3Rpb24gKGJvb2wpIHsKICAgICAgICAgICAgdmFyIHhmID0gdGhpcy5feGZhKCk7CiAgICAgICAgICAgIGlmICh4Zi5ob3N0LmNhbGN1bGF0aW9uc0VuYWJsZWQpIHsKICAgICAgICAgICAgICAgIGlmICh4Zi5jYWxjdWxhdGVSdW5uaW5nKQogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIGlmIChib29sKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5leGVjQ2FsY3VsYXRlKCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5leGVjRm9ybVJlYWR5KCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHhmLnJ1bkNhbGNzKCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgIHZhciBkaWZmID0gRm9ybS5fc3VwZXIuX2NvbXB1dGVKc29uRGlmZi5jYWxsKHRoaXMsIGRpZmZfbGV2ZWwpOwogICAgICAgICAgICBkaWZmLmpzb25EaWZmZXJlbmNlWyJ2ZXJzaW9uTlMiXSA9IHRoaXMuanNvbk1vZGVsWyJ2ZXJzaW9uTlMiXTsKICAgICAgICAgICAgcmV0dXJuIHsgImNoYW5nZWQiOiB0cnVlLAogICAgICAgICAgICAgICAgImpzb25EaWZmZXJlbmNlIjogZGlmZi5qc29uRGlmZmVyZW5jZQogICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZU5vZGU6IHhmYWxpYi5zY3JpcHQuTW9kZWwucHJvdG90eXBlLmNyZWF0ZU5vZGUKCiAgICB9KTsKfSkoXywgeGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuSG9zdAogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuTm9kZQogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIEhvc3QgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKKGZ1bmN0aW9uKF8sIHhmYWxpYiwgJCl7CiAgICAvKioKICAgICAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyB0aGUgSG9zdCBPYmplY3QKICAgICAqIEBleHRlbmRzIGNvbS5hZG9iZS54ZmEuc2NyaXB0aW5nLk5vZGUKICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBhcHBUeXBlIHRoZSBhcHBsaWNhdGlvbiB0eXBlIG9mIHRoZSBob3N0CiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gY3VycmVudFBhZ2UgUGFnZSBudW1iZXIgb2YgdGhlIGZvcm0gdGhhdCBpcyBiZWluZwogICAgICogICAgICAgICAgIGRpc3BsYXllZAogICAgICogQHByb3BlcnR5IHtudW1iZXJ9IG51bVBhZ2VzIHRvdGFsIG51bWJlciBvZiBwYWdlcyBpbiB0aGUgZm9ybQogICAgICogQHByb3BlcnR5IHtuYW1lfSBuYW1lIG5hbWUgb2YgdGhlIGFwcGxpY2F0aW9uCiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gcGxhdGZvcm0gT1MgcGxhdGZvcm0gb24gd2hpY2ggdGhlIGFwcGxpY2F0aW9uIGlzIHJ1bm5pbmcKICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB0aXRsZSB0aXRsZSBvZiB0aGUgZG9jdW1lbnQKICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB2ZXJzaW9uIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBjdXJyZW50IGFwcGxpY2F0aW9uCiAgICAgKi8KICAgIHZhciBIb3N0ID0geGZhbGliLnNjcmlwdC5Ib3N0ID0geGZhbGliLnNjcmlwdC5Ob2RlLmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJob3N0UHNldWRvTW9kZWwiLAogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICBIb3N0Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLm5hbWUgPSAiIjsKICAgICAgICAgICAgdGhpcy5tUGFnZU51bWJlciA9IDA7CiAgICAgICAgICAgIHRoaXMucGFnaW5nTWFuYWdlciA9IG51bGwgOwogICAgICAgICAgICB0aGlzLm1DYWxjdWxhdGlvbnNFbmFibGVkID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5tVmFsaWRhdGFpb25zRW5hYmxlZCA9IHRydWU7CiAgICAgICAgICAgIHRoaXMubU51bVBhZ2VzID0gIiI7CiAgICAgICAgICAgIHRoaXMuZGF0YUJyb3dzZXIgPSBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RyaW5nOiBuYXZpZ2F0b3IudXNlckFnZW50LAogICAgICAgICAgICAgICAgICAgIHN1YlN0cmluZzogIkNocm9tZSIsCiAgICAgICAgICAgICAgICAgICAgaWRlbnRpdHk6ICJDaHJvbWUiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0cmluZzogbmF2aWdhdG9yLnZlbmRvciwKICAgICAgICAgICAgICAgICAgICBzdWJTdHJpbmc6ICJBcHBsZSIsCiAgICAgICAgICAgICAgICAgICAgaWRlbnRpdHk6ICJTYWZhcmkiLAogICAgICAgICAgICAgICAgICAgIHZlcnNpb25TZWFyY2g6ICJWZXJzaW9uIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBwcm9wOiB3aW5kb3cub3BlcmEsCiAgICAgICAgICAgICAgICAgICAgaWRlbnRpdHk6ICJPcGVyYSIsCiAgICAgICAgICAgICAgICAgICAgdmVyc2lvblNlYXJjaDogIlZlcnNpb24iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0cmluZzogbmF2aWdhdG9yLnVzZXJBZ2VudCwKICAgICAgICAgICAgICAgICAgICBzdWJTdHJpbmc6ICJGaXJlZm94IiwKICAgICAgICAgICAgICAgICAgICBpZGVudGl0eTogIkZpcmVmb3giCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewkJLy8gZm9yIG5ld2VyIE5ldHNjYXBlcyAoNispCiAgICAgICAgICAgICAgICAgICAgc3RyaW5nOiBuYXZpZ2F0b3IudXNlckFnZW50LAogICAgICAgICAgICAgICAgICAgIHN1YlN0cmluZzogIk5ldHNjYXBlIiwKICAgICAgICAgICAgICAgICAgICBpZGVudGl0eTogIk5ldHNjYXBlIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdHJpbmc6IG5hdmlnYXRvci51c2VyQWdlbnQsCiAgICAgICAgICAgICAgICAgICAgc3ViU3RyaW5nOiAiTVNJRSIsCiAgICAgICAgICAgICAgICAgICAgaWRlbnRpdHk6ICJJbnRlcm5ldCBFeHBsb3JlciIsCiAgICAgICAgICAgICAgICAgICAgdmVyc2lvblNlYXJjaDogIk1TSUUiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0cmluZzogbmF2aWdhdG9yLnVzZXJBZ2VudCwKICAgICAgICAgICAgICAgICAgICBzdWJTdHJpbmc6ICJHZWNrbyIsCiAgICAgICAgICAgICAgICAgICAgaWRlbnRpdHk6ICJNb3ppbGxhIiwKICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uU2VhcmNoOiAicnYiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgeyAJCS8vIGZvciBvbGRlciBOZXRzY2FwZXMgKDQtKQogICAgICAgICAgICAgICAgICAgIHN0cmluZzogbmF2aWdhdG9yLnVzZXJBZ2VudCwKICAgICAgICAgICAgICAgICAgICBzdWJTdHJpbmc6ICJNb3ppbGxhIiwKICAgICAgICAgICAgICAgICAgICBpZGVudGl0eTogIk5ldHNjYXBlIiwKICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uU2VhcmNoOiAiTW96aWxsYSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgXTsKICAgICAgICB9LAoKICAgICAgICBfc2VhcmNoVmVyc2lvbiA6IGZ1bmN0aW9uKGRhdGEsc3JjaCkgewogICAgICAgICAgICB2YXIgaW5kZXggPSBkYXRhLmluZGV4T2Yoc3JjaCk7CiAgICAgICAgICAgIGlmIChpbmRleCA9PSAtMSkgcmV0dXJuOwogICAgICAgICAgICB2YXIgc3BjSW5kZXggPSBkYXRhLmluZGV4T2YoIiAiLGluZGV4KTsKICAgICAgICAgICAgaWYoc3BjSW5kZXggPT0gLTEpCiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5zdWJzdHJpbmcoaW5kZXgrc3JjaC5sZW5ndGgrMSk7CiAgICAgICAgICAgIHJldHVybiBkYXRhLnN1YnN0cmluZyhpbmRleCtzcmNoLmxlbmd0aCsxLHNwY0luZGV4KTsKICAgICAgICB9LAoKICAgICAgICBfYnJvd3NlckRldGVjdCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YUJyb3dzZXI7CiAgICAgICAgICAgIGZvciAodmFyIGk9MDtpPGRhdGEubGVuZ3RoO2krKykJewogICAgICAgICAgICAgICAgdmFyIGRhdGFTdHJpbmcgPSBkYXRhW2ldLnN0cmluZzsKICAgICAgICAgICAgICAgIHZhciBkYXRhUHJvcCA9IGRhdGFbaV0ucHJvcDsKICAgICAgICAgICAgICAgIHZhciB2ZXJzaW9uU2VhcmNoU3RyaW5nID0gZGF0YVtpXS52ZXJzaW9uU2VhcmNoIHx8IGRhdGFbaV0uaWRlbnRpdHk7CiAgICAgICAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMuX3NlYXJjaFZlcnNpb24obmF2aWdhdG9yLnVzZXJBZ2VudCx2ZXJzaW9uU2VhcmNoU3RyaW5nKSB8fCB0aGlzLl9zZWFyY2hWZXJzaW9uKG5hdmlnYXRvci5hcHBWZXJzaW9uLHZlcnNpb25TZWFyY2hTdHJpbmcpIHx8ICJhbiB1bmtub3duIHZlcnNpb24iOwogICAgICAgICAgICAgICAgaWYgKGRhdGFTdHJpbmcpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YVN0cmluZy5pbmRleE9mKGRhdGFbaV0uc3ViU3RyaW5nKSAhPSAtMSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGFbaV0uaWRlbnRpdHkrIiAiK3ZlcnNpb247CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChkYXRhUHJvcCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVtpXS5pZGVudGl0eSsiICIrdmVyc2lvbjsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBmdW5jdGlvbiBkaXNwbGF5cyBhIGRpYWxvZyBib3ggb24gdGhlIHNjcmVlbi4gPGJyIC8+CiAgICAgICAgICogPGI+VE8gRE88L2I+PGJyIC8+CiAgICAgICAgICogPHVsPgogICAgICAgICAqIDxsaT4gVGhlIGZ1bmN0aW9uIGRvZXNuJ3Qgc3VwcG9ydHMgaWNvbnMgYXMgb2Ygbm93LiBOZWVkcyBhZGRpbmcgc3VwcG9ydCBmb3IKICAgICAgICAgKiB0aGF0LjwvbGk+CiAgICAgICAgICogPGxpPiBUaGUgZGlhbG9nIHVzZXMgdGhlIGRlZmF1bHQgc3R5bGluZyAocHJvdmlkZWQgYnkgZ29vZ2xlKS4gTmVlZCB0byBjaGFuZ2UKICAgICAgICAgKiB0aGF0IHRvby4gPC9saT4KICAgICAgICAgKiA8L3VsPgogICAgICAgICAqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9CiAgICAgICAgICAgICogICAgICAgICAgICBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAgICAgKiAgICAgICAgICAgIHRpdGxlIFRoZSB0aXRsZSB0byBhcHBlYXIgaW4gdGhlIGRpYWxvZydzIHdpbmRvdyB0aXRsZQogICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfQogICAgICAgICAgICAqICAgICAgICAgICAgdHlwZSBUaGUgaWNvbiB0byBkaXNwbGF5OiAnMCcgKEVycm9yIChkZWZhdWx0KSksICcxJyAoV2FybmluZyksCiAgICAgICAgICogICAgICAgICAgICAnMicgKFF1ZXN0aW9uKSwgYW5kICczJyAoU3RhdHVzKS4KICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0KICAgICAgICAgICAgKiAgICAgICAgICAgIGJ1dHRvbnMgVGhlIGJ1dHRvbnMgdG8gZGlzcGxheTogJzAnIChPSyAoZGVmYXVsdCkpLCAnMScgKE9LLAogICAgICAgICAqICAgICAgICAgICAgQ2FuY2VsKSwgJzInIChZZXMsIE5vKSwgYW5kICczJyAoWWVzLCBObywgQ2FuY2VsKS4KICAgICAgICAgKi8KICAgICAgICBtZXNzYWdlQm94IDogZnVuY3Rpb24obWVzc2FnZSwgdGl0bGUsIHR5cGUsIGJ1dHRvbnMpIHsKICAgICAgICAgICAgcmV0dXJuICh0aGlzLl9tZXNzYWdlQm94KG1lc3NhZ2UsdGl0bGUsdHlwZSxidXR0b25zLG51bGwpKTsKICAgICAgICB9LAoKICAgICAgICBfbWVzc2FnZUJveCA6IGZ1bmN0aW9uKG1lc3NhZ2UsIHRpdGxlLCB0eXBlLCBidXR0b25zLGNhbGxiYWNrKSB7CiAgICAgICAgICAgIHRpdGxlID0gdGl0bGUgfHwgIiI7CiAgICAgICAgICAgIGJ1dHRvbnMgPSBidXR0b25zIHx8IDA7CiAgICAgICAgICAgIHZhciBpbWcgPVsiRXJyb3IiLCJXYXJuaW5nIiwiUXVlc3Rpb24iLCJTdGF0dXMiXTsKICAgICAgICAgICAgdmFyIGltZ1R5cGUgPSAiIjsKICAgICAgICAgICAgaWYodHlwZSE9dW5kZWZpbmVkKQogICAgICAgICAgICAgICAgaW1nVHlwZSA9ICAiWyAiICsgaW1nW3R5cGVdICsgIiBdICAiOwogICAgICAgICAgICBtZXNzYWdlID0gaW1nVHlwZSAgKyAgdGl0bGUgKyAiXG5cciIgKyBtZXNzYWdlIDsKCiAgICAgICAgICAgIHN3aXRjaCAoYnV0dG9ucykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICAgIGFsZXJ0KG1lc3NhZ2UpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAxIDsKICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICB2YXIgYSA9IGNvbmZpcm0obWVzc2FnZSk7CiAgICAgICAgICAgICAgICAgICAgaWYoYT09dHJ1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgICAgICAgZWxzZSByZXR1cm4gMjsKICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICB2YXIgYSA9IGNvbmZpcm0obWVzc2FnZSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuTG9nZ2VyLmVycm9yKCJ4ZmEiLCB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDkiXSkgOwogICAgICAgICAgICAgICAgICAgIGlmKGE9PXRydWUpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiA0OwogICAgICAgICAgICAgICAgICAgIGVsc2UgcmV0dXJuIDM7CgogICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLkxvZ2dlci5lcnJvcigieGZhIiwgeGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDEwIl0pOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIGZ1bmN0aW9uIGRpc3BsYXlzIHRoZSBuZXh0IHBhZ2Ugb2YgdGhlIGRvY3VtZW50IChpZiBvbmUgZXhpc3RzKQogICAgICAgICAqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgcGFnZURvd24gOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudFBhZ2UgIT0gdGhpcy5udW1QYWdlcyAtMSApIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMucGFnaW5nTWFuYWdlcikKICAgICAgICAgICAgICAgICAgICB0aGlzLnBhZ2luZ01hbmFnZXIucGFnZURvd24oKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBmdW5jdGlvbiBkaXNwbGF5cyB0aGUgcHJldmlvdXMgcGFnZSBvZiB0aGUgZG9jdW1lbnQgKGlmIG9uZSBleGlzdHMpCiAgICAgICAgICoKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKi8KICAgICAgICBwYWdlVXAgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudFBhZ2UgIT0gMCkgIHsKICAgICAgICAgICAgICAgIHZhciBwcmV2UGFnZSA9IHRoaXMuY3VycmVudFBhZ2UgLSAxOwogICAgICAgICAgICAgICAgdmFyIGEgPSAkKCQoIi5wYWdlIilbcHJldlBhZ2VdKSAgOwogICAgICAgICAgICAgICAgd2luZG93LnNjcm9sbFRvKDAsYS5vZmZzZXQoKS50b3ApIDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGdvdG9VUkw6IGZ1bmN0aW9uKHVybCwgYk5ld0ZyYW1lKSB7CiAgICAgICAgICAgIC8qaWYoISQoImEjZ290b3VybCIpLmxlbmd0aCkKICAgICAgICAgICAgICAgICQoIjxhIGlkPSdnb3RvdXJsJz48L2E+IikuYXBwZW5kVG8oJ2JvZHknKTsKICAgICAgICAgICAgJCgiYSNnb3RvdXJsIikuYXR0cigiaHJlZiIsdXJsKVswXS5jbGljaygpOwogICAgICAgICAgICAvLyQoImEiKS5jbGljaygpOyAgICAgKi8KICAgICAgICAgICAgaWYodXJsLnNlYXJjaCgiaHR0cCIpID09IC0xKQogICAgICAgICAgICAgICAgdXJsID0gImh0dHA6Ly8iICsgdXJsIDsKICAgICAgICAgICAgaWYoYk5ld0ZyYW1lICE9IHRydWUpIHsKICAgICAgICAgICAgICAgIHdpbmRvdy5vcGVuKHVybCkgOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbiA9IHVybDsKICAgICAgICB9LAoKICAgICAgICByZXNldERhdGEgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYoYXJndW1lbnRzLmxlbmd0aCkKICAgICAgICAgICAgICAgIF8uZWFjaChhcmd1bWVudHMsZnVuY3Rpb24oc29tKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSB0aGlzLl94ZmEoKS5yZXNvbHZlTm9kZShzb20pOwogICAgICAgICAgICAgICAgICAgIGlmKG5vZGUpCiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuX3Jlc2V0RGF0YSgpOwogICAgICAgICAgICAgICAgfSx0aGlzKQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLmZvcm0uX3Jlc2V0RGF0YSgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc2V0Rm9jdXMgOiBmdW5jdGlvbihzb20pIHsKICAgICAgICAgICAgaWYobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBhZC9pKSAhPSBudWxsICYmIHRoaXMuX3hmYSgpLm1vQ29udGV4dFNjcmlwdEV2ZW50ID09ICdjaGFuZ2UnKSB7CiAgICAgICAgICAgIC8vIExDLTQ2NjMgOiBzZXRGb2N1cyB3YXMgc2hpZnRpbmcgZm9jdXMsIGJlZm9yZSBrZXlwcmVzcyB3YXMgdmlzaWJsZSBpbiBicm93c2VyLgogICAgICAgICAgICAvLyBDdXJyZW50bHkgaVBhZCBkb2VzbnQgc3VwcG9ydCBjYWxsaW5nIGZvY3VzKCkgZnJvbSB3aXRoaW4gc2V0VGltZW91dCwgc28gZGlzYWJsaW5nIHRoZSBmdW5jdGlvbmFsaXR5LgogICAgICAgICAgICAgICAgdGhpcy5fc2V0Rm9jdXMoc29tKTsgLy8gZG9uJ3QgcXVldWUgZm9jdXMgZXZlbnRzLCBmaXJlIGl0IGltbWVkaWF0ZWx5CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5xdWV1ZUZvY3VzRXZlbnQodGhpcywgc29tKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICBfc2V0Rm9jdXMgOiBmdW5jdGlvbihzb20pIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZSA9IHNvbTsKICAgICAgICAgICAgICAgICAgICBpZih0eXBlb2Ygc29tID09ICJzdHJpbmciKQogICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gdGhpcy5feGZhKCkucmVzb2x2ZU5vZGUoc29tKTsKICAgICAgICAgICAgICAgICAgICBpZihub2RlICE9IG51bGwpewogICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMucGFnaW5nTWFuYWdlcil7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGFkL2kpICE9IG51bGwgJiYgdGhpcy5feGZhKCkubW9Db250ZXh0U2NyaXB0RXZlbnQgPT0gJ2NoYW5nZScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBhZ2luZ01hbmFnZXIuX21ha2VQYWdlRm9ySHRtbElkKG5vZGUuaHRtbElkKTsgLy8gTEMtNDY2MyA6IGp1c3QgcmVuZGVyLCBub3Qgc2V0Rm9jdXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYWdpbmdNYW5hZ2VyLl9tYWtlUGFnZUZvckh0bWxJZChub2RlLmh0bWxJZCxub2RlLl9zZXRGb2N1cyxub2RlKTsgIC8vIGZvciBhbGwgb3RoZXIgZXZlbnRzIHNldCB0aGUgZm9jdXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICB9LAoKICAgICAgICAgZ2V0Rm9jdXMgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBpZih4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1cykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybih4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1cy5tb2RlbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gLAoKICAgICAgICBwbGF5RGF0YVhtbDogZnVuY3Rpb24gKHhtbERvY3VtZW50KSB7CiAgICAgICAgICAgIHZhciByb290RWxlbWVudDsKICAgICAgICAgICAgaWYoXy5pc1VuZGVmaW5lZChkb2N1bWVudC5ldmFsdWF0ZSkpIHsKICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gZG8gaXQgaGVyZSBzaW5jZSBYUGF0aFJlc3VsdCBpcyBhbHNvIHVuZGVmaW5lZCBpbiBJRQogICAgICAgICAgICAgICAgd2d4cGF0aC5pbnN0YWxsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoXy5pc1N0cmluZyh4bWxEb2N1bWVudCkpIHsKICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLkxvZ2dlci5pbmZvKCJ4ZmEiLCAieG1sRG9jdW1lbnQgaXMgb2YgdHlwZSBzdHJpbmcuIGNvbnZlcnRpbmcgaXQgdG8gZG9jdW1lbnQiKTsKICAgICAgICAgICAgICAgIHhtbERvY3VtZW50ID0gJC5wYXJzZVhNTCh4bWxEb2N1bWVudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcm9vdEVsZW1lbnQgPSB4ZmFsaWIudXQuWE1MVXRpbHMuZ2V0WEZBUm9vdEZvcm1FbGVtZW50RnJvbVhNTCh4bWxEb2N1bWVudCk7CiAgICAgICAgICAgIHRoaXMuX3hmYSgpLmZvcm0uX3BsYXlEYXRhWE1MKHJvb3RFbGVtZW50LCByb290RWxlbWVudCwgIiIpOwogICAgICAgIH0sCgogICAgICAgIHBsYXlKc29uIDogZnVuY3Rpb24oeGZhSnNvbk1vZGVsKSB7CiAgICAgICAgICAgIHZhciBmb3JtRG9tID0gIF8uZmluZCh4ZmFKc29uTW9kZWwuY2hpbGRyZW4sCiAgICAgICAgICAgICAgICBmdW5jdGlvbihjaGlsZCl7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkLl9jbGFzcyA9PSAiZm9ybSI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHRoaXMuX3hmYSgpLmZvcm0ucGxheUpzb24oZm9ybURvbSk7CiAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX1JFRlJFU0gsCiAgICAgICAgICAgICAgICB0aGlzLCJqc29uTW9kZWwiLG51bGwsdGhpcy5feGZhKCkuZm9ybS5qc29uTW9kZWwpOwogICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgIH0sCgogICAgICAgIHJ1blNlcnZlclNjcmlwdCA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnN8fCB7fTsKICAgICAgICAgICAgdmFyIHhmYURpZmY7CiAgICAgICAgICAgIGlmICh3aW5kb3cuRkQgJiYgd2luZG93LkZELmlzVG9nZ2xlRW5hYmxlZCgiRlRfRk9STVMtMTQyMjQiKSkgewogICAgICAgICAgICAgICAgeGZhRGlmZiA9IHRoaXMuX3hmYSgpLl9jb21wdXRlSnNvbkRpZmYoMykuanNvbkRpZmZlcmVuY2U7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB4ZmFEaWZmID0gdGhpcy5feGZhKCkuX2NvbXB1dGVKc29uRGlmZigwKS5qc29uRGlmZmVyZW5jZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgeGZhRG9tU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkoeGZhRGlmZik7CiAgICAgICAgICAgLy9jbG9uZSB0aGUgb2JqZWN0IHRvIGF2b2lkIHBvbGx1dGluZyB0aGUgY29udGV4dAogICAgICAgICAgICB2YXIgcGFyYW1zID0gXy5leHRlbmQoewogICAgICAgICAgICAgICAgICAgIGZvcm1Eb206IHhmYURvbVN0cmluZywKICAgICAgICAgICAgICAgICAgICBwYWNrZXQ6ICdmb3JtJwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIG9wdGlvbnMsCiAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS5yZW5kZXJDb250ZXh0KTsKCiAgICAgICAgICAgIHZhciBzZXJ2ZXJTY3JpcHRTdWNjZXNzSGFuZGxlciA9IGZ1bmN0aW9uKHJlc3VsdCl7CiAgICAgICAgICAgICAgICB0aGlzLnBsYXlKc29uKHJlc3VsdCk7IC8vcmVzdWx0IHdpbGwgYmUgYSBKU09OIG9iamVjdCBzbyBqdXN0IHBsYXkgaXQuCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBpZihvcHRpb25zLmNvbnRleHRTb20gJiYgb3B0aW9ucy5hY3Rpdml0eSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICAgICAgd2luZG93LmZvcm1CcmlkZ2UuX2ludm9rZUF0U2VydmVyKHsKICAgICAgICAgICAgICAgICAgICBkYXRhOiBwYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgc3VjY2VzczpfLmJpbmQoc2VydmVyU2NyaXB0U3VjY2Vzc0hhbmRsZXIsdGhpcyksCiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uKHhocix0eHRTdGF0dXMsZXJyb3JUaHJvd24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1zZwogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2goeGhyLnN0YXR1cykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zZyA9IHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAwOCJdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX3hmYSgpLkxvZ2dlci5lcnJvcigieGZhIiwgbXNnICsgIiAiICsgeGhyLnN0YXR1c1RleHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2cgPSB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDEiXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll94ZmEoKS5Mb2dnZXIuZXJyb3IoInhmYSIsIG1zZyArICIgIiArIHhoci5zdGF0dXNUZXh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGF0Lm1lc3NhZ2VCb3gobXNnKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF92YWxpZGF0ZSA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgdmFyIF9vcHRpb25zID0gb3B0aW9ucyB8fCB7fSwKICAgICAgICAgICAgICAgIHZhbE1lc3NhZ2VzID0gX29wdGlvbnMudmFsTWVzc2FnZXMgfHwgW107CiAgICAgICAgICAgIHZhciB2YWxpZCA9IHRoaXMuX3hmYSgpLmZvcm0uX3ZhbGlkYXRlKHZhbE1lc3NhZ2VzKTsKICAgICAgICAgICAgaWYodmFsaWQpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgICAgIHZhciBlcnJvcnMgPSAiIjsKICAgICAgICAgICAgdmFyIHdhcm5pbmdzID0gIiI7CgogICAgICAgICAgICBmb3IodmFyIGk9MDsgaSA8IHZhbE1lc3NhZ2VzLmxlbmd0aDsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgbXNnID0gbnVsbDsKICAgICAgICAgICAgICAgIGlmKG1zZyA9IHZhbE1lc3NhZ2VzW2ldKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmKG1zZy5zZXZlcml0eSA9PSAiZXJyb3IiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ycyA9IGVycm9ycyArIG1zZy5tZXNzYWdlICsgIlxyXG4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZihtc2cuc2V2ZXJpdHkgPT0gIndhcm5pbmciKXsKICAgICAgICAgICAgICAgICAgICAgICAgd2FybmluZ3MgPSB3YXJuaW5ncyArIG1zZy5tZXNzYWdlICsgIlxyXG4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZihlcnJvcnMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgICAgIHZhciBtc2cgPSAiICBUaGUgZm9ybSBjb3VsZCBub3QgYmUgc3VibWl0dGVkIGJlY2F1c2UgIit2YWxNZXNzYWdlcy5sZW5ndGggKyIgZXJyb3JzIHdlcmUgZm91bmQiCiAgICAgICAgICAgICAgICBpZigkKCIjd2ItbWFpbi1pbiIpLmxlbmd0aCl7CiAgICAgICAgICAgICAgICAgICAgaWYoISQoIiN4ZmEtZXJyb3JNZXNzYWdlcyIpLmxlbmd0aCl7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN3Yi1tYWluLWluIikucHJlcGVuZCgiPGRpdiBpZCA9J3hmYS1lcnJvck1lc3NhZ2VzJz48L2Rpdj4iKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJCgiI3hmYS1lcnJvck1lc3NhZ2VzIikuZW1wdHkoKS50ZXh0KG1zZykuYXBwZW5kKCI8dWwgaWQ9J3hmYS1lcnJvckxpc3QnPjwvdWw+Iik7CiAgICAgICAgICAgICAgICAgICAgXy5lYWNoKHZhbE1lc3NhZ2VzLGZ1bmN0aW9uKGVsZW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiPGE+PC9hPiIpLmFwcGVuZFRvKCQoIjxsaT48L2xpPiIpLmFwcGVuZFRvKCcjeGZhLWVycm9yTGlzdCcpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50ZXh0KGVsZW0ubWVzc2FnZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNsaWNrKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGF0LnNldEZvY3VzKGVsZW0ucmVmKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICAgICBpZih2YWxNZXNzYWdlcy5sZW5ndGggPT0wKQogICAgICAgICAgICAgICAgICAgICAgICAkKCIjeGZhLWVycm9yTWVzc2FnZXMiKS5oaWRlKCk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAkKCIjeGZhLWVycm9yTWVzc2FnZXMiKS5zaG93KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLnNldEZvY3VzKHZhbE1lc3NhZ2VzWzBdLnJlZik7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZih3YXJuaW5ncykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlQm94KHdhcm5pbmdzLCB4ZmFsaWIubG9jYWxlLlN0cmluZ3Mud2FybmluZywgMSwgMCk7ICAgLy9UT0RPIDpTaG91bGQgIGJlIG9rL2NhbmNlbAogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGN1cnJlbnREYXRlVGltZQogICAgICAgICAqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgX3BhZHplcm8gOiBmdW5jdGlvbihuKSB7CiAgICAgICAgICAgIHJldHVybiBuIDwgMTAgPyAnMCcgKyBuIDogbjsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGN1cnJlbnREYXRlVGltZQogICAgICAgICAqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgX3BhZDJ6ZXJvcyA6IGZ1bmN0aW9uKG4pIHsKICAgICAgICAgICAgaWYgKG4gPCAxMDApIHsKICAgICAgICAgICAgICAgIG4gPSAnMCcgKyBuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChuIDwgMTApIHsKICAgICAgICAgICAgICAgIG4gPSAnMCcgKyBuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICogVGhlIGZ1bmN0aW9uIFJldHVybnMgY3VycmVudCBkYXRlIGFuZCB0aW1lIGluIFttXW0vW2RdZC95eSBbSF1IOltNXU0gKEF8UClNIGZvcm1hdAogICAgICAgICoKICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICovCiAgICAgICAgY3VycmVudERhdGVUaW1lIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBub3cgPSBuZXcgRGF0ZSgpLAogICAgICAgICAgICAgICAgICAgIGN1clllYXIgPSBub3cuZ2V0RnVsbFllYXIoKSArJycsCiAgICAgICAgICAgICAgICAgICAgY3VyTW9udGggPSBub3cuZ2V0TW9udGgoKSsxICsnJywKICAgICAgICAgICAgICAgICAgICBjdXJEYXRlID0gbm93LmdldERhdGUoKSArJycsCiAgICAgICAgICAgICAgICAgICAgY3VySG91ciA9IG5vdy5nZXRIb3VycygpICsnJywKICAgICAgICAgICAgICAgICAgICBjdXJNaW4gPSBub3cuZ2V0TWludXRlcygpICsnJywKICAgICAgICAgICAgICAgICAgICBjdXJTZWMgPSBub3cuZ2V0U2Vjb25kcygpICsnJzsKCiAgICAgICAgICAgIHJldHVybiAoY3VyWWVhciArIHRoaXMuX3BhZHplcm8oY3VyTW9udGgpICsgdGhpcy5fcGFkemVybyhjdXJEYXRlKSArICdUJyArCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFkemVybyhjdXJIb3VyKSArIHRoaXMuX3BhZHplcm8oY3VyTWluKSArIHRoaXMuX3BhZHplcm8oY3VyU2VjKSk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogSGVscGVyIGZ1bmN0aW9uIGZvciBjdXJyZW50RGF0ZVRpbWUKICAgICAgICAgKgogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqLwogICAgICAgIF90b0lTT1N0cmluZyA6IGZ1bmN0aW9uKGQpIHsKICAgICAgICAgICAgcmV0dXJuIGQuZ2V0VVRDRnVsbFllYXIoKSArICctJyArICB0aGlzLl9wYWR6ZXJvKGQuZ2V0VVRDTW9udGgoKSArIDEpICsgJy0nICsKICAgICAgICAgICAgICAgIHRoaXMuX3BhZHplcm8oZC5nZXRVVENEYXRlKCkpICsgJ1QnICsgdGhpcy5fcGFkemVybyhkLmdldFVUQ0hvdXJzKCkpICsgJzonICsKICAgICAgICAgICAgICAgIHRoaXMuX3BhZHplcm8oZC5nZXRVVENNaW51dGVzKCkpICsgJzonICsgdGhpcy5fcGFkemVybyhkLmdldFVUQ1NlY29uZHMoKSkgKyAnLicgKyB0aGlzLl9wYWQyemVyb3MoZC5nZXRVVENNaWxsaXNlY29uZHMoKSkgKyAnWic7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIGZ1bmN0aW9uIFJldHVybnMgY3VycmVudCBkYXRlIGFuZCB0aW1lIGluIElTTyA4NjAxIGZvcm1hdAogICAgICAgICAqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgX2N1cnJlbnREYXRlVGltZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgbm93ID0gbmV3IERhdGUoKTsKICAgICAgICAgICAgcmV0dXJuKHRoaXMuX3RvSVNPU3RyaW5nKG5vdykpOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBIb3N0LnBsYXRmb3JtcyA9IFtbIldpbiIsIldpbmRvd3MiXSxbIk1hYyJdLFsiaVBob25lIiwiaVBob25lL2lQb2QiXSxbImlQYWQiXSxbIkxpbnV4Il0sWyJVbmtub3duIl1dOwoKICAgIEhvc3QuZGVmaW5lUHJvcHMoewogICAgICAgICJhcHBUeXBlIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIkhUTUwgNSI7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAiY3VycmVudFBhZ2UiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMucGFnaW5nTWFuYWdlcikKICAgICAgICAgICAgICAgICAgICByZXR1cm4odGhpcy5wYWdpbmdNYW5hZ2VyLmN1cnJlbnRQYWdlKCkpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbihwYWdlKSB7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudFBhZ2UgPSAwLAogICAgICAgICAgICAgICAgICAgIGxhc3RQYWdlID0gMDsKICAgICAgICAgICAgICAgIHBhZ2UgPSBwYXJzZUludChwYWdlKTsKICAgICAgICAgICAgICAgIGlmKHRoaXMucGFnaW5nTWFuYWdlcikgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRQYWdlID0gdGhpcy5wYWdpbmdNYW5hZ2VyLmN1cnJlbnRQYWdlKCk7CiAgICAgICAgICAgICAgICAgICAgbGFzdFBhZ2UgPSB0aGlzLnBhZ2luZ01hbmFnZXIucGFnZUNvdW50KCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYocGFnZSA8IDApCiAgICAgICAgICAgICAgICAgICAgcGFnZSA9IDA7CiAgICAgICAgICAgICAgICBlbHNlIGlmKHBhZ2UgPj0gbGFzdFBhZ2UpCiAgICAgICAgICAgICAgICAgICAgcGFnZSA9ICAobGFzdFBhZ2UgPiAwKSA/IGxhc3RQYWdlIC0xIDogMDsKCiAgICAgICAgICAgICAgICB2YXIgJHBhZ2VzID0gJCgiLnBhZ2UiKTsKCiAgICAgICAgICAgICAgICBpZiggcGFnZSA+ICRwYWdlcy5sZW5ndGgtMSApIHsgIC8vIG5vdCBhbGwgcGFnZXMgcmVuZGVyZWQgeWV0CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5wYWdpbmdNYW5hZ2VyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlKHRoaXMucGFnaW5nTWFuYWdlci5oYXNNb3JlUGFnZXMoKSAmJiBjdXJyZW50UGFnZSA8PSBwYWdlKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFnaW5nTWFuYWdlci5yZW5kZXJOZXh0UGFnZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudFBhZ2UrKzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkcGFnZXMgPSAkKCIucGFnZSIpOyAgIC8vIHNlbGVjdCBuZXdseSByZW5kZXJlZCBwYWdlcwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBhID0gJCgkcGFnZXNbcGFnZV0pOwogICAgICAgICAgICAgICAgd2luZG93LnNjcm9sbFRvKDAsYS5vZmZzZXQoKS50b3ApIDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJuYW1lIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYnJvd3NlckRldGVjdCgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInZhcmlhdGlvbiIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewoKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJudW1QYWdlcyIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgaWYodGhpcy5wYWdpbmdNYW5hZ2VyKQogICAgICAgICAgICAgICAgICAgIHJldHVybih0aGlzLnBhZ2luZ01hbmFnZXIucGFnZUNvdW50KCkpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInBsYXRmb3JtIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICB2YXIgYXJyID0gSG9zdC5wbGF0Zm9ybXM7CiAgICAgICAgICAgICAgICBpZiAoIXRoaXMubVBsYXRmb3JtKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBpID0gMDtpPGFyci5sZW5ndGg7aSsrKQogICAgICAgICAgICAgICAgICAgICAgICAgIGlmKH5uYXZpZ2F0b3IucGxhdGZvcm0uaW5kZXhPZihhcnJbaV1bMF0pKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGkgPSBpID09IGFyci5sZW5ndGggPyBpIC0gMSA6aTsKICAgICAgICAgICAgICAgICAgICB0aGlzLm1QbGF0Zm9ybSA9ICBhcnJbaV1bYXJyW2ldLmxlbmd0aC0xXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1QbGF0Zm9ybQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInRpdGxlIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZG9jdW1lbnQudGl0bGU7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHRpdGxlKSB7CiAgICAgICAgICAgIAl0aXRsZSA9IHRoaXMudmFsaWRhdGVJbnB1dCh0aXRsZSwgInN0cmluZyIpOwogICAgICAgICAgICAgICAgZG9jdW1lbnQudGl0bGUgPSB0aXRsZTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZW51bWVyYWJsZSA6IHRydWUKICAgICAgICB9LAoKICAgICAgICAidmVyc2lvbiIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICIxLjAiOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCgogICAgICAgICJjYWxjdWxhdGlvbnNFbmFibGVkIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tQ2FsY3VsYXRpb25zRW5hYmxlZDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24oc0NhbGN1bGF0aW9uc0VuYWJsZWQpIHsKICAgICAgICAgICAgCS8vc0NhbGN1bGF0aW9uc0VuYWJsZWQgPSB0aGlzLnZhbGlkYXRlSW5wdXQoc0NhbGN1bGF0aW9uc0VuYWJsZWQsICJzdHJpbmciKTsKICAgICAgICAgICAgICAgIHZhciBzT3JpZ2luYWxWYWx1ZSA9IHRoaXMubUNhbGN1bGF0aW9uc0VuYWJsZWQ7CiAgICAgICAgICAgICAgICB0aGlzLm1DYWxjdWxhdGlvbnNFbmFibGVkID0gc0NhbGN1bGF0aW9uc0VuYWJsZWQ7CiAgICAgICAgICAgICAgICBpZiAoIXNDYWxjdWxhdGlvbnNFbmFibGVkKSB7CiAgICAgICAgICAgICAgICAgICAgLy90aGlzLnhmYS5fcm9vdFN1YmZvcm0uX2NsZWFyTWVzc2FnZXMoKTsgVE9ETzogQ2xlYXIgQ2FsY3VsYXRpb24gbWVzc2FnZXMKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc0NhbGN1bGF0aW9uc0VuYWJsZWQgJiYgKHNPcmlnaW5hbFZhbHVlID09IGZhbHNlKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLmZvcm0uZXhlY0NhbGN1bGF0ZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInZhbGlkYXRpb25zRW5hYmxlZCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubVZhbGlkYXRhaW9uc0VuYWJsZWQ7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHNWYWxpZGF0aW9uc0VuYWJsZWQpIHsKICAgICAgICAgICAgCS8vc1ZhbGlkYXRpb25zRW5hYmxlZCA9IHRoaXMudmFsaWRhdGVJbnB1dChzVmFsaWRhdGlvbnNFbmFibGVkLCAic3RyaW5nIik7CiAgICAgICAgICAgICAgICB2YXIgc09yaWdpbmFsVmFsdWUgPSB0aGlzLm1WYWxpZGF0YWlvbnNFbmFibGVkOwogICAgICAgICAgICAgICAgdGhpcy5tVmFsaWRhdGFpb25zRW5hYmxlZCA9IHNWYWxpZGF0aW9uc0VuYWJsZWQ7CiAgICAgICAgICAgICAgICBpZiAoIXNWYWxpZGF0aW9uc0VuYWJsZWQpIHsKICAgICAgICAgICAgICAgICAgICAvL3RoaXMueGZhLl9yb290U3ViZm9ybS5fY2xlYXJNZXNzYWdlcygpOyBUT0RPOiBDbGVhciBWYWxpZGF0aW9uIG1lc3NhZ2VzCiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNWYWxpZGF0aW9uc0VuYWJsZWQgJiYgKHNPcmlnaW5hbFZhbHVlID09IGZhbHNlKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLmZvcm0uX3ZhbGlkYXRlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sIHhmYWxpYiwgJCk7CgoKCgoKCgooZnVuY3Rpb24gKF8sICQsIHhmYWxpYikgewogICAgdmFyIFhmYVRlbXBsYXRlQ2FjaGUgPSB4ZmFsaWIuc2NyaXB0LlhmYVRlbXBsYXRlQ2FjaGUgPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBYZmFUZW1wbGF0ZUNhY2hlLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX2xhc3RJRCA9IChuZXcgRGF0ZSgpKS5nZXRUaW1lKCk7IC8vVE9ETzogR2V0IGEgYmV0dGVyIHNjaGVtZQogICAgICAgICAgICB0aGlzLl9ub2RlQ2FjaGUgPSB7fTsgICAgICAgIC8vIGxpdmUgY2FjaGUKICAgICAgICAgICAgdGhpcy5fdDBKc29uTm9kZUNhY2hlID0ge307IC8vIGluaXRpYWwgY2FjaGUKICAgICAgICAgICAgdGhpcy5pZE1hcCA9IHt9OyAgICAgICAgICAgLy8tLW1hcCB0byBnZXQgdGhlIGZpZWxkIGluc3RhbmNlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGZpZWxkLWlkCgogICAgICAgICAgICB2YXIganNvblN0cmluZyA9IEpTT04uc3RyaW5naWZ5KHRoaXMub3B0aW9ucy5pbml0aWFsRm9ybURvbSksIC8vV2UgY3JlYXRlIGNvcHkgb2YgaW5pdGlhbCBmb3JtIGRvbSB2aWEgSlNPTiBhcGkgaW5zdGVhZCBvZiB0aGlzLmNvcHlPYmplY3Qgc2luY2UgdGhhdCBpcyBmYXN0CiAgICAgICAgICAgICAgICBpbml0aWFsRm9ybURvbUNvcHkgPSBKU09OLnBhcnNlKGpzb25TdHJpbmcpLCAgICAvL0NyZWF0ZSBjb3B5IG9mIGluaXRpYWwgZm9ybSBkb20gdG8gZ3VhcmQgYWdhaW5zdCBmdXR1cmUgbW9kaWZpY2F0aW9ucwogICAgICAgICAgICAgICAgZm9ybURvbVRlbXBsYXRlID0ge307ICAgLy9Db3B5IGhvbGRpbmcgZm9ybURvbVRlbXBsYXRlCgogICAgICAgICAgICB0aGlzLmNvcHlPYmplY3QoaW5pdGlhbEZvcm1Eb21Db3B5LCBmb3JtRG9tVGVtcGxhdGUsIHsiZXhjZXB0aW9ucyI6IFsiY2hpbGRyZW4iXX0pOwogICAgICAgICAgICAvL0dlbmVyYXRlIHRlbXBsYXRlCiAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3NUZW1wbGF0ZShmb3JtRG9tVGVtcGxhdGUsIGluaXRpYWxGb3JtRG9tQ29weSwgZmFsc2UpOwogICAgICAgICAgICB2YXIgYmVoYXZpb3JDb25maWcgPSBuZXcgeGZhbGliLnV0LlZlcnNpb24oZm9ybUJyaWRnZS51c2VyQ29uZmlnWyJiZWhhdmlvckNvbmZpZyJdKTsKICAgICAgICAgICAgLy9UbyBtYWludGFpbiBiYWNrd2FyZCBjb21wYXRpYmlsaXR5CiAgICAgICAgICAgIGlmIChiZWhhdmlvckNvbmZpZy5pc09uKCdzdHJpcEluaXRpYWxGb3JtRG9tJykgfHwgYmVoYXZpb3JDb25maWcuaXNPbignbWZTdHJpcEluaXRpYWxGb3JtRG9tJykpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5zdHJpcE9iamVjdCh0aGlzLl90MEpzb25Ob2RlQ2FjaGVbaW5pdGlhbEZvcm1Eb21Db3B5LmV4dHJhcy5odG1sSWRdLmluaXRpYWxSZWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWydfY2xhc3MnLCAnbmFtZScsICdodG1sSWQnLCAncHJlc2VuY2UnLCAnbWluJywgJ21heCddKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGdldFRlbXBsYXRlUmVmOiBmdW5jdGlvbiAoaHRtbElkKSB7CiAgICAgICAgICAgIGlmICh0aGlzLl9ub2RlQ2FjaGUuaGFzT3duUHJvcGVydHkoaHRtbElkKSkKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9ub2RlQ2FjaGVbaHRtbElkXS50ZW1wbGF0ZVJlZjsKICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fdDBKc29uTm9kZUNhY2hlLmhhc093blByb3BlcnR5KGh0bWxJZCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdDBKc29uTm9kZUNhY2hlW2h0bWxJZF0udGVtcGxhdGVSZWY7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIGdldEluaXRpYWxGb3JtRG9tUmVmOiBmdW5jdGlvbiAoaHRtbElkKSB7CiAgICAgICAgICAgIGlmICh0aGlzLl90MEpzb25Ob2RlQ2FjaGUuaGFzT3duUHJvcGVydHkoaHRtbElkKSkKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl90MEpzb25Ob2RlQ2FjaGVbaHRtbElkXS5pbml0aWFsUmVmOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICBnZXRNb2RlbDogZnVuY3Rpb24gKGh0bWxJZCkgewogICAgICAgICAgICBpZiAodGhpcy5fbm9kZUNhY2hlLmhhc093blByb3BlcnR5KGh0bWxJZCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbm9kZUNhY2hlW2h0bWxJZF0ubW9kZWw7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIHB1dE1vZGVsOiBmdW5jdGlvbiAobW9kZWwsIGpzb25UZW1wbGF0ZSkgewogICAgICAgICAgICB0aGlzLl9wcm9jZXNzTW9kZWwoanNvblRlbXBsYXRlLCBtb2RlbCk7CiAgICAgICAgfSwKCiAgICAgICAgcmVtb3ZlTW9kZWw6IGZ1bmN0aW9uIChodG1sSWQpIHsKICAgICAgICAgICAgaWYgKHRoaXMuX25vZGVDYWNoZS5oYXNPd25Qcm9wZXJ0eShodG1sSWQpKQogICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX25vZGVDYWNoZVtodG1sSWRdOwogICAgICAgIH0sCgogICAgICAgIF9wcm9jZXNzVGVtcGxhdGU6IGZ1bmN0aW9uIChqc29uVGVtcGxhdGUsIGpzb25Nb2RlbCwgY2FuUmVwZWF0KSB7CiAgICAgICAgICAgIHZhciB0ZW1wbGF0ZUlkID0gbnVsbDsKICAgICAgICAgICAgaWYgKHRoaXMuZ2V0T3JFbHNlKGpzb25UZW1wbGF0ZSwgImV4dHJhcy5odG1sSWQiLCBudWxsKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBqc29uVGVtcGxhdGUuZXh0cmFzID0ganNvblRlbXBsYXRlLmV4dHJhcyB8fCB7fTsKICAgICAgICAgICAgICAgIGpzb25UZW1wbGF0ZS5leHRyYXMuaHRtbElkID0gIkNMXyIgKyAoKyt0aGlzLl9sYXN0SUQpOwogICAgICAgICAgICAgICAgdGVtcGxhdGVJZCA9IGpzb25UZW1wbGF0ZS5leHRyYXMuaHRtbElkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLmdldE9yRWxzZShqc29uTW9kZWwsICJleHRyYXMuaHRtbElkIiwgbnVsbCkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAganNvbk1vZGVsLmV4dHJhcyA9IGpzb25Nb2RlbC5leHRyYXMgfHwge307CiAgICAgICAgICAgICAgICBpZiAodGVtcGxhdGVJZCAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIGpzb25Nb2RlbC5leHRyYXMuaHRtbElkID0gdGVtcGxhdGVJZDsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBqc29uTW9kZWwuZXh0cmFzLmh0bWxJZCA9ICJDTF8iICsgKCsrdGhpcy5fbGFzdElEKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl90MEpzb25Ob2RlQ2FjaGVbanNvbk1vZGVsLmV4dHJhcy5odG1sSWRdID0ge3RlbXBsYXRlUmVmOiBqc29uVGVtcGxhdGUsIGluaXRpYWxSZWY6IGpzb25Nb2RlbH07CgogICAgICAgICAgICBpZiAoIWNhblJlcGVhdCAmJiAhXy5jb250YWlucyhbImFyZWEiLCAicGFnZVNldCIsICJwYWdlQXJlYSIsICJzdWJmb3JtIiwgInN1YmZvcm1TZXQiLCAiY29udGVudEFyZWEiLCAiZXhjbEdyb3VwIiwgImZvcm0iXSwganNvbk1vZGVsLl9jbGFzcykpIHsKICAgICAgICAgICAgICAgIC8vUHJvY2VzcyBpdCdzIGNoaWxkIG9ubHkgaWYgdGhhdCBjYW4gcmVwZWF0IG9yIGl0IGNhbiBoYXZlIHBhaW50YWJsZSBjaGlsZHJlbi4gVGhpcyBpcyBiYWRseSB3cml0dGVuIGNoZWNrLiBOZWVkIHRvIHJlLWNvZGUgdGhpcy4KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGxhc3RJTSA9IG51bGw7CiAgICAgICAgICAgIHZhciBsYXN0Q2hpbGRTRiA9IGZhbHNlOwogICAgICAgICAgICB2YXIgY2hpbGRUZW1wbGF0ZUluZGV4ID0gLTE7CiAgICAgICAgICAgIF8uZWFjaChqc29uTW9kZWwuY2hpbGRyZW4sCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoY2hpbGROb2RlLCBpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubWF0Y2hKc29uVHlwZShjaGlsZE5vZGUsICJpbnN0YW5jZU1hbmFnZXIiKSkgewogICAgICAgICAgICAgICAgICAgICAgICBsYXN0SU0gPSBjaGlsZE5vZGU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoIWxhc3RDaGlsZFNGKSB7ICAgLy9JZiBsYXN0IGNoaWxkIHdhcyBub3Qgc3ViZm9ybSB0aGVuIGluY3JlYXNlIHRlbXBsYXRlIGluZGV4CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkVGVtcGxhdGVJbmRleCA9IGNoaWxkVGVtcGxhdGVJbmRleCArIDE7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy54ZmFVdGlsKCkuaXNSZXBlYXRhYmVFbChjaGlsZE5vZGUuX2NsYXNzKSkgeyAvL0Vsc2UgaW5jcmVhc2UgdGVtcGxhdGUgaW5kZXggb25seSBmb3Igbm9uLXN1YmZvcm0KICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRUZW1wbGF0ZUluZGV4ID0gY2hpbGRUZW1wbGF0ZUluZGV4ICsgMTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZFJlcGVhdCA9IGNhblJlcGVhdDsKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy54ZmFVdGlsKCkuaXNSZXBlYXRhYmVFbChjaGlsZE5vZGUuX2NsYXNzKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFJlcGVhdCA9IGNoaWxkUmVwZWF0IHx8IHBhcnNlSW50KHRoaXMuZ2V0T3JFbHNlKGxhc3RJTSwgIm1heCIsIHhmYWxpYi5zY3JpcHQuT2NjdXIucHJvdG90eXBlLl9kZWZhdWx0cy5tYXgpKSA8IDAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChwYXJzZUludCh0aGlzLmdldE9yRWxzZShsYXN0SU0sICJtaW4iLCB4ZmFsaWIuc2NyaXB0Lk9jY3VyLnByb3RvdHlwZS5fZGVmYXVsdHMubWluKSkgPCBwYXJzZUludCh0aGlzLmdldE9yRWxzZShsYXN0SU0sICJtYXgiLCB4ZmFsaWIuc2NyaXB0Lk9jY3VyLnByb3RvdHlwZS5fZGVmYXVsdHMubWF4KSkpOwogICAgICAgICAgICAgICAgICAgICAgICBsYXN0Q2hpbGRTRiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgbGFzdENoaWxkU0YgPSBmYWxzZTsKCiAgICAgICAgICAgICAgICAgICAganNvblRlbXBsYXRlLmNoaWxkcmVuID0ganNvblRlbXBsYXRlLmNoaWxkcmVuIHx8IFtdOwogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZFRlbXBsYXRlID0ganNvblRlbXBsYXRlLmNoaWxkcmVuW2NoaWxkVGVtcGxhdGVJbmRleF07CiAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZFRlbXBsYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkVGVtcGxhdGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3M6IGNoaWxkTm9kZS5fY2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBjaGlsZE5vZGUubmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhczogY2hpbGROb2RlLmV4dHJhcyB8fCB7fQogICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRSZXBlYXQpIHsgLy9Gb3IgcmVwZWF0YWJsZSBjaGlsZCBjb3B5IGFsbCBwcm9wZXJ0aWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvcHlPYmplY3QoY2hpbGROb2RlLCBjaGlsZFRlbXBsYXRlLCB7ZXhjZXB0aW9uczogWyJjaGlsZHJlbiJdLCBrZWVwUmVmZXJlbmNlOiBmYWxzZX0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25UZW1wbGF0ZS5jaGlsZHJlbi5wdXNoKGNoaWxkVGVtcGxhdGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcm9jZXNzVGVtcGxhdGUoY2hpbGRUZW1wbGF0ZSwgY2hpbGROb2RlLCBjaGlsZFJlcGVhdCk7CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICB9LAoKICAgICAgICBfcHJvY2Vzc01vZGVsOiBmdW5jdGlvbiAoanNvblRlbXBsYXRlLCBtb2RlbCkgewogICAgICAgICAgICBpZiAobW9kZWwuaHRtbElkID09IG51bGwpIHsKICAgICAgICAgICAgICAgIG1vZGVsLmh0bWxJZCA9ICJDTF8iICsgKCsrdGhpcy5fbGFzdElEKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl9ub2RlQ2FjaGVbbW9kZWwuaHRtbElkXSA9IHt0ZW1wbGF0ZVJlZjoganNvblRlbXBsYXRlLCBtb2RlbDogbW9kZWx9OwogICAgICAgICAgICB2YXIgY2hpbGRUZW1wbGF0ZUluZGV4ID0gLTE7CiAgICAgICAgICAgIHZhciBsYXN0Q2hpbGRTRiA9IGZhbHNlOwogICAgICAgICAgICBfLmVhY2gobW9kZWwuY2hpbGRyZW4sCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoY2hpbGROb2RlLCBpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFsYXN0Q2hpbGRTRikgeyAgIC8vSWYgbGFzdCBjaGlsZCB3YXMgbm90IHN1YmZvcm0gdGhlbiBpbmNyZWFzZSB0ZW1wbGF0ZSBpbmRleAogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFRlbXBsYXRlSW5kZXggPSBjaGlsZFRlbXBsYXRlSW5kZXggKyAxOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIShjaGlsZE5vZGUgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LlN1YmZvcm0pKSB7IC8vRWxzZSBpbmNyZWFzZSB0ZW1wbGF0ZSBpbmRleCBvbmx5IGZvciBub24tc3ViZm9ybQogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFRlbXBsYXRlSW5kZXggPSBjaGlsZFRlbXBsYXRlSW5kZXggKyAxOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgbGFzdENoaWxkU0YgPSBjaGlsZE5vZGUgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LlN1YmZvcm07CgogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZFRlbXBsYXRlID0ganNvblRlbXBsYXRlLmNoaWxkcmVuID8ganNvblRlbXBsYXRlLmNoaWxkcmVuW2NoaWxkVGVtcGxhdGVJbmRleF0gOiB1bmRlZmluZWQKICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRUZW1wbGF0ZSkKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcHJvY2Vzc01vZGVsKGNoaWxkVGVtcGxhdGUsIGNoaWxkTm9kZSk7CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICB9LAoKICAgICAgICBtYXRjaEpzb25UeXBlOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUubWF0Y2hKc29uVHlwZQoKICAgIH0pOwoKfSkoXywgJCwgeGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuWGZhCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Nb2RlbAogKiBAaW1wb3J0IHhmYWxpYi51dC5Mb2dnZXIKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lkhvc3QKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBYRkEgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIC8qKgogICAgICogQGNsYXNzIFRoZSBjbGFzcyByZXByZXNlbnRzIHRoZSBYRkEgT2JqZWN0CiAgICAgKiBAZXh0ZW5kcyBjb20uYWRvYmUueGZhLnNjcmlwdGluZy5Nb2RlbAogICAgICogQHByb3BlcnR5IHtjb20uYWRvYmUueGZhLnNjcmlwdGluZy5Ib3N0fSBob3N0IE9iamVjdCBvZiB0aGUgaG9zdCBjbGFzcwogICAgICovCiAgICB2YXIgWGZhID0geGZhbGliLnNjcmlwdC5YZmEgPSB4ZmFsaWIuc2NyaXB0Lk1vZGVsLmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJ4ZmEiLAogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhID0gdGhpczsgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1RPRE86IEhhbmRsZSBhbml0aGluZyBiZWluZyB1c2VkIGJlZm9yZSBzdXBlcgogICAgICAgICAgICB4ZmFsaWIucnVudGltZVsiJHhmYSJdID0gdGhpczsKICAgICAgICAgICAgdGhpcy4kbGF5b3V0ID0gdGhpcy5sYXlvdXQgPSBuZXcgeGZhbGliLnNjcmlwdC5MYXlvdXQoeyJqc29uTW9kZWwiOiB7fX0pOwogICAgICAgICAgICB2YXIgbG9nQ29uZiA9IHdpbmRvdy5mb3JtQnJpZGdlLnJlZ2lzdGVyQ29uZmlnKCJMb2dnZXJDb25maWciKS5kYXRhIHx8IHt9OwogICAgICAgICAgICB2YXIgcmVuZGVyQ29udGV4dENvcHkgPSB7fTsKICAgICAgICAgICAgdGhpcy5jb3B5T2JqZWN0KHhmYWxpYi5ydW50aW1lLnJlbmRlckNvbnRleHQsIHJlbmRlckNvbnRleHRDb3B5LCB7ImV4Y2VwdGlvbnMiOiBbImRhdGEiXX0pCiAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIgPSBuZXcgeGZhbGliLnV0LkxvZ2dlcih7CiAgICAgICAgICAgICAgICAianNvbk1vZGVsIjogbG9nQ29uZiwKICAgICAgICAgICAgICAgIGxvZ1NlcnZpY2VQcm94eTogdGhpcy5nZXRPckVsc2Uod2luZG93LmZvcm1CcmlkZ2UudXNlckNvbmZpZ1sic3VibWl0U2VydmljZVByb3h5Q29uZmlnIl0sICJsb2dTZXJ2aWNlUHJveHkiLCAiIiksCiAgICAgICAgICAgICAgICByZW5kZXJDb250ZXh0OiByZW5kZXJDb250ZXh0Q29weSwKICAgICAgICAgICAgICAgIGNvbnRleHRQYXRoOiB3aW5kb3cuZm9ybUJyaWRnZS51c2VyQ29uZmlnWyJjb250ZXh0UGF0aCJdCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuRXJyb3JNYW5hZ2VyID0gdGhpcy5nZXRPckVsc2Uod2luZG93LmZvcm1CcmlkZ2UudXNlckNvbmZpZ1siZXJyb3JDb25maWciXSxuZXcgeGZhbGliLnZpZXcudXRpbC5FcnJvck1hbmFnZXIpCiAgICAgICAgICAgIHhmYWxpYi5zY3JpcHQuWGZhLkluc3RhbmNlID0gdGhpczsgICAgICAgICAgLy9UT0RPOiBTaW5nbGV0b24gcmVxZD8KICAgICAgICAgICAgdGhpcy5fc3VibWl0QnV0dG9ucyA9IFtdOwogICAgICAgICAgICB0aGlzLl9tb2RlbEluaXRpYWxpemUgPSAnVU5JTklUSUFMSVpFRCc7IC8vIGNhbiBiZSBzZXQgdG8gJ0lOSVRJQUxJWkVEJyBvciAnJ0lOSVRJQUxJWklORycKICAgICAgICAgICAgdGhpcy5tb0NvbnRleHROb2RlcyA9IFtdOwogICAgICAgICAgICB0aGlzLm1vQ2FsY3VsYXRlRXZlbnRTdGFjayA9IFtdOwogICAgICAgICAgICB0aGlzLm1vQ2FsY3VsYXRlRXZlbnROb2RlID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5ob3N0ID0gbmV3IHhmYWxpYi5zY3JpcHQuSG9zdCgpOwogICAgICAgICAgICB4ZmFsaWIucnVudGltZVsiJGhvc3QiXSA9IHRoaXMuaG9zdDsKICAgICAgICAgICAgdGhpcy5jb3VudEVycm9yID0gMDsKICAgICAgICAgICAgdGhpcy5kYXRhTm9kZXMgPSB7fTsKICAgICAgICAgICAgdGhpcy5fdGVtcGxhdGVTY2hlbWEgPSBuZXcgeGZhbGliLnRlbXBsYXRlLlRlbXBsYXRlU2NoZW1hKCk7CiAgICAgICAgICAgIHRoaXMubW9Db250ZXh0U2NyaXB0RXZlbnQgPSBudWxsOyAvLyB3aWxsIGhvbGQgY3VycmVudCBldmVudCBmb3Igd2hpY2ggc2NyaXB0IGlzIGV4ZWN1dGluZwogICAgICAgICAgICB0aGlzLlF1ZXVlID0geyJjYWxjIjogW10sICJjYWxjaW5kZXgiOiAwLCAidmFsaWRhdGUiOiBbXSwgInZhbGlkYXRlaW5kZXgiOiAwLCBjYWxjQ291bnQ6IHt9LAogICAgICAgICAgICAgICAgInNldGZvY3VzIjogW10sICJzZXRmb2N1c2luZGV4IjogMH07CgogICAgICAgICAgICAvLyB0byBjbGVhciBhbGwgX21vQ29udGV4dC1zIGNhY2hlZCBpbiBldmVudENvbnRhaW5lck5vZGUtcywgYWZ0ZXIgc3ViZm9ybS5hZGRJbnN0YW5jZSBvciBzdWJmb3JtLnJlbW92ZUluc3RhbmNlCiAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5fY2xlYXJBbGxNb0NvbnRleHRzID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgZnVuY3Rpb24gY2xlYXJNb0NvbnRleHRWaXNpdG9yKHRhcmdldCkgewogICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LkV2ZW50Q29udGFpbmVyTm9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQuX21vQ29udGV4dCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLmZvcm0uX2dldFJvb3RTdWJmb3JtKCkuX3Zpc2l0QWxsbW9DaGlsZHJlbihjbGVhck1vQ29udGV4dFZpc2l0b3IpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgLy9DcmVhdGUgRm9ybSBDaGlsZAogICAgICAgICAgICB2YXIgZm9ybUpzb24gPSBfLmZpbmQodGhpcy5qc29uTW9kZWwuY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkLl9jbGFzcyA9PSAiZm9ybSI7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICB0aGlzLl94ZmFUZW1wbGF0ZUNhY2hlID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhVGVtcGxhdGVDYWNoZSh7aW5pdGlhbEZvcm1Eb206IGZvcm1Kc29ufSk7CgogICAgICAgICAgICAvL1dlIGNhbGwgU3VwZXIgbGF0ZXIgYXQgdGhpcyBzdGFnZSBzaW5jZSB3ZSBuZWVkIHRvIGluaXRpYWxpemUgZmV3IHZhcmlhYmxlcyB3aGljaCBhcmUgcmVxdWlyZWQgd2hpbGUgaW5pdGlhbGl6aW5nIGNoaWxkcmVuCiAgICAgICAgICAgIFhmYS5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwoKICAgICAgICAgICAgLy9nZXQgdGhlIGNoaWxkIGZyb20gY2hpbGRyZW4gbW9kZWxzIHRoYXQgYXJlIGFscmVhZHkgY3JlYXRlZC4KICAgICAgICAgICAgdGhpcy5mb3JtID0gXy5maW5kKHRoaXMuY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkLl9pc0Zvcm0oKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHRoaXMuX3hmYVRlbXBsYXRlQ2FjaGUucHV0TW9kZWwodGhpcy5mb3JtLAogICAgICAgICAgICAgICAgdGhpcy5feGZhVGVtcGxhdGVDYWNoZS5nZXRUZW1wbGF0ZVJlZih0aGlzLmdldE9yRWxzZShmb3JtSnNvbiwgImV4dHJhcy5odG1sSWQiLCB7fSkpCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAvL05vdGU6IHNpbmNlIHdlIGRvIG5vdCBzdXBwb3J0IHRlbXBsYXRlIGN1cnJlbnRseSwgd2Ugd29ya2Fyb25kIGJ5IHBvaW50aW5nIHRlbXBsYXRlIG5vZGUgdG8gZm9ybSBub2RlIHdoaWNoIHdvdWxkIGhhdmUgc2ltaWxhciBzdHJ1Y3R1cmUgaW4gbW9zdCBjYXNlcy4KICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWVbJyR0ZW1wbGF0ZSddID0gdGhpcy50ZW1wbGF0ZSA9IHhmYWxpYi5ydW50aW1lWyckZm9ybSddID0gdGhpcy5mb3JtOwogICAgICAgICAgICB4ZmFsaWIucnVudGltZVsndGVtcGxhdGUnXSA9IHhmYWxpYi5ydW50aW1lWydmb3JtJ10gPSB0aGlzLmZvcm07CgogICAgICAgICAgICAvL0NyZWF0ZSBDb25maWcgQ2hpbGQuIE5vdGljZSB0aGF0IGl0IGlzIG5vdCBYRkEgTm9kZSBtb2RlbCwganVzdCBhIGpzb24gY2hpbGQgZm9yIG5vdy4KICAgICAgICAgICAgdGhpcy5jb25maWcgPSBfLmZpbmQodGhpcy5qc29uTW9kZWwuY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkLl9jbGFzcyA9PSAiY29uZmlnIjsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lWyckY29uZmlnJ10gPSB0aGlzLmNvbmZpZzsKCiAgICAgICAgICAgIC8vQ3JlYXRlIGxvY2FsZVNldCBDaGlsZC4gTm90aWNlIHRoYXQgaXQgaXMgbm90IFhGQSBOb2RlIG1vZGVsLCBqdXN0IGEganNvbiBjaGlsZCBmb3Igbm93LgogICAgICAgICAgICB0aGlzLmxvY2FsZVNldCA9IHRoaXMuanNvbk1vZGVsLmxvY2FsZVNldDsKICAgICAgICAgICAgdGhpcy5kZWZhdWx0TG9jYWxlID0gImVuX1VTIjsgLy9UT0RPOiByZWFkIGZyb20ganNwCgogICAgICAgICAgICAvL09uY2UgZXZlcnl0aGluZyBpcyBzZXQgdXAsIG5vdyBpcyB0aGUgdGltZSB0byBzZXQgcGFyZW50IGFjY2VzcwogICAgICAgICAgICB0aGlzLmZvcm0uX2NhbGN1bGF0ZUVmZmVjdGl2ZUFjY2VzcygpOwogICAgICAgICAgICB0aGlzLmZvcm0uX2NhbGN1bGF0ZUVmZmVjdGl2ZVByZXNlbmNlKCk7CiAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlUnVubmluZyA9IGZhbHNlOwogICAgICAgICAgICB0aGlzLnZhbGlkYXRlUnVubmluZyA9IGZhbHNlOwogICAgICAgICAgICB0aGlzLnZlcnNpb25Db25maWcgPSBuZXcgeGZhbGliLnV0LlZlcnNpb24oZm9ybUJyaWRnZS51c2VyQ29uZmlnWyJiZWhhdmlvckNvbmZpZyJdKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBFdmFsdWF0ZXMgdGhlIHNwZWNpZmllZCBTT00gZXhwcmVzc2lvbiwgYmVnaW5uaW5nIHdpdGggdGhlIGN1cnJlbnQgWE1MIGZvcm0KICAgICAgICAgKiBvYmplY3QgbW9kZWwgb2JqZWN0LCBhbmQgcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIG9iamVjdCBzcGVjaWZpZWQgaW4gdGhlIFNPTQogICAgICAgICAqIGV4cHJlc3Npb24KICAgICAgICAgKiBAT3ZlcnJpZGVzCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgcmVzb2x2ZU5vZGU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMSkKICAgICAgICAgICAgICAgIHJldHVybiBYZmEuX3N1cGVyLnJlc29sdmVOb2RlLmNhbGwodGhpcywgdGhpcy5fY29udGV4dE5vZGUoKSB8fCB0aGlzLCBhcmd1bWVudHNbMF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gWGZhLl9zdXBlci5yZXNvbHZlTm9kZS5jYWxsKHRoaXMsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBFdmFsdWF0ZXMgdGhlIHNwZWNpZmllZCBTT00gZXhwcmVzc2lvbiwgYmVnaW5uaW5nIHdpdGggdGhlIGN1cnJlbnQgWE1MIGZvcm0KICAgICAgICAgKiBvYmplY3QgbW9kZWwgb2JqZWN0LCBhbmQgcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIG9iamVjdCBzcGVjaWZpZWQgaW4gdGhlIFNPTQogICAgICAgICAqIGV4cHJlc3Npb24KICAgICAgICAgKiBAT3ZlcnJpZGVzCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgcmVzb2x2ZU5vZGVzOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDEpCiAgICAgICAgICAgICAgICByZXR1cm4gWGZhLl9zdXBlci5yZXNvbHZlTm9kZXMuY2FsbCh0aGlzLCB0aGlzLl9jb250ZXh0Tm9kZSgpLCBhcmd1bWVudHNbMF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gWGZhLl9zdXBlci5yZXNvbHZlTm9kZXMuY2FsbCh0aGlzLCBhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSk7CiAgICAgICAgfSwKCiAgICAgICAgX25ld1N1Ym1pdEJ1dHRvbjogZnVuY3Rpb24gKGVsZW0pIHsKICAgICAgICAgICAgaWYgKCF+dGhpcy5fc3VibWl0QnV0dG9ucy5pbmRleE9mKGVsZW0pKSAgICAgLy9UT0RPOiBXaGF0IGlzIHRoaXMuIEFkZCBhIGNvbW1lbnQKICAgICAgICAgICAgICAgIHRoaXMuX3N1Ym1pdEJ1dHRvbnMucHVzaChlbGVtKTsKICAgICAgICB9LAoKICAgICAgICBfaGlkZVN1Ym1pdEJ1dHRvbnM6IGZ1bmN0aW9uIChlbGVtKSB7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fc3VibWl0QnV0dG9ucy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5fc3VibWl0QnV0dG9uc1tpXS5wcmVzZW5jZSA9ICJoaWRkZW4iOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIGZ1bmN0aW9uIHB1c2hlcyBhIG5ldyBDYWxjdWxhdGUgRXZlbnQgTm9kZSBpbnRvIHRoZSBDYWxjdWxhdGUgU3RhY2sKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcGFyYW0ge2NvbS5hZG9iZS54ZmEuc2NyaXB0aW5nLk5vZGV9IG5vZGUgY3VycmVudCBjb250ZXh0IG5vZGUKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9wdXNoQ2FsY3VsYXRlRXZlbnROb2RlOiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICB0aGlzLm1vQ2FsY3VsYXRlRXZlbnRTdGFjay5wdXNoKG5vZGUpOwogICAgICAgICAgICB0aGlzLm1vQ2FsY3VsYXRlRXZlbnROb2RlID0gbm9kZTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgZnVuY3Rpb24gcHVzaGVzIGEgbmV3IFhGQSBOb2RlIGluIHRoZSBjdXJyZW50IGNvbnRleHQKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcGFyYW0ge2NvbS5hZG9iZS54ZmEuc2NyaXB0aW5nLk5vZGV9IG5vZGUgY3VycmVudCBjb250ZXh0IG5vZGUKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9wdXNoQ29udGV4dE5vZGU6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgIHRoaXMubW9Db250ZXh0Tm9kZXMucHVzaChub2RlKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgZnVuY3Rpb24gcG9wcyBDYWxjdWxhdGUgRXZlbnQgTm9kZSBmcm9tIHRoZSBzdGFjayBvZiBjb250ZXh0IG5vZGVzCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfcG9wQ2FsY3VsYXRlRXZlbnROb2RlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMubW9DYWxjdWxhdGVFdmVudFN0YWNrLnBvcCgpOwogICAgICAgICAgICB0aGlzLm1vQ2FsY3VsYXRlRXZlbnROb2RlID0gbnVsbDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgZnVuY3Rpb24gcG9wcyBhIFhGQSBOb2RlIGZyb20gdGhlIHN0YWNrIG9mIGNvbnRleHQgbm9kZXMKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9wb3BDb250ZXh0Tm9kZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLm1vQ29udGV4dE5vZGVzLnBvcCgpOwogICAgICAgIH0sCgogICAgICAgIF9jb250ZXh0Tm9kZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgbGVuID0gdGhpcy5tb0NvbnRleHROb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgIGlmIChsZW4gPiAwKQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubW9Db250ZXh0Tm9kZXNbbGVuIC0gMV0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgX2lzWEZBQ29udGFpbmVyTm9kZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0U29tRXhwcmVzc2lvbjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm5hbWUiKSArICJbIiArIHRoaXMuaW5kZXggKyAiXSI7CiAgICAgICAgfSwKCiAgICAgICAgX2dldExvY2FsZVN5bWJvbHM6IGZ1bmN0aW9uIChsb2NhbGUsIHN5bWJvbCkgewogICAgICAgICAgICB2YXIgcmV0ID0gbnVsbDsKICAgICAgICAgICAgdmFyIG5ld1N5bWJvbCA9ICJsb2NhbGVzLiIgKyBsb2NhbGUgKyAiLiIgKyBzeW1ib2w7CiAgICAgICAgICAgIHJldCA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMubG9jYWxlU2V0LCBuZXdTeW1ib2wsIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5nZXREZWZhdWx0TG9jYWxlUHJvcGVydHkoc3ltYm9sKSk7CiAgICAgICAgICAgIGlmICghcmV0KSB7CiAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmVycm9yKCJ4ZmEiLCAidW5hYmxlIHRvIGZpbmQgIiArIHN5bWJvbCArICIgZm9yIGxvY2FsZSAiICsgbG9jYWxlICsgImluIGxvY2FsZVNldCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfSwKCiAgICAgICAgc2V0U3ViZm9ybUZvY3VzOiBmdW5jdGlvbiAoc3ViZm9ybSkgewogICAgICAgICAgICB2YXIgb2xkU3ViZm9ybSA9IHRoaXMuY3VycmVudFN1YmZvcm07CiAgICAgICAgICAgIHRoaXMuY3VycmVudFN1YmZvcm0gPSBzdWJmb3JtOwogICAgICAgICAgICB2YXIgdmlld3MgPSBbXTsKICAgICAgICAgICAgaWYgKG9sZFN1YmZvcm0pIHsKICAgICAgICAgICAgICAgIHZhciBwU3ViZm9ybSA9IHN1YmZvcm07CiAgICAgICAgICAgICAgICB3aGlsZSAocFN1YmZvcm0pIHsKICAgICAgICAgICAgICAgICAgICB2aWV3cy5wdXNoKHBTdWJmb3JtKTsKICAgICAgICAgICAgICAgICAgICBwU3ViZm9ybSA9IHBTdWJmb3JtLnBhcmVudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHdoaWxlIChvbGRTdWJmb3JtICYmIHZpZXdzLmluZGV4T2Yob2xkU3ViZm9ybSkgPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICBvbGRTdWJmb3JtLmV4ZWNFdmVudCgiZXhpdCIpOwogICAgICAgICAgICAgICAgICAgIG9sZFN1YmZvcm0gPSBvbGRTdWJmb3JtLnBhcmVudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZURhdGFOb2RlOiBmdW5jdGlvbiAoaWQsIG1vZGVsKSB7CiAgICAgICAgICAgIGlmIChpZCkgewogICAgICAgICAgICAgICAgdmFyIGRuID0gdGhpcy5kYXRhTm9kZXNbaWRdIHx8IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlRGF0YU5vZGUoaWQpOwogICAgICAgICAgICAgICAgZG4uYWRkRmllbGQobW9kZWwpOwogICAgICAgICAgICAgICAgdGhpcy5kYXRhTm9kZXNbaWRdID0gZG47CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBxdWV1ZUNhbGNFdmVudDogZnVuY3Rpb24gKG9MaXN0ZW5lcikgewogICAgICAgICAgICBpZiAoIXRoaXMuaG9zdC5jYWxjdWxhdGlvbnNFbmFibGVkKQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB2YXIgcSA9IHRoaXMuUXVldWVbImNhbGMiXTsKICAgICAgICAgICAgdmFyIHNvbSA9IG9MaXN0ZW5lci5zb21FeHByZXNzaW9uOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHEubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBpdGVtID0gcVtpXTsKICAgICAgICAgICAgICAgIGlmIChvTGlzdGVuZXIgPT0gaXRlbSkgewogICAgICAgICAgICAgICAgICAgIGlmIChpIDwgdGhpcy5RdWV1ZS5jYWxjaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuUXVldWUuY2FsY0NvdW50W3NvbV0gPT09IDEwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLlF1ZXVlLmNhbGNDb3VudFtzb21dID0gdGhpcy5RdWV1ZS5jYWxjQ291bnRbc29tXSB8fCAwOwogICAgICAgICAgICB0aGlzLlF1ZXVlLmNhbGNDb3VudFtzb21dKys7CiAgICAgICAgICAgIHEucHVzaChvTGlzdGVuZXIpOwogICAgICAgIH0sCgogICAgICAgIHF1ZXVlVmFsaWRhdGVFdmVudDogZnVuY3Rpb24gKG9Ob2RlKSB7CiAgICAgICAgICAgIGlmICghdGhpcy5ob3N0LnZhbGlkYXRpb25zRW5hYmxlZCkKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgaWYgKCF+dGhpcy5RdWV1ZVsidmFsaWRhdGUiXS5pbmRleE9mKG9Ob2RlKSkKICAgICAgICAgICAgICAgIHRoaXMuUXVldWVbInZhbGlkYXRlIl0ucHVzaChvTm9kZSk7CiAgICAgICAgfSwKCiAgICAgICAgcXVldWVGb2N1c0V2ZW50OiBmdW5jdGlvbiAoY29udGV4dCwgc29tKSB7CiAgICAgICAgICAgIHRoaXMuUXVldWVbInNldGZvY3VzIl0ucHVzaCh7J2NvbnRleHQnOiBjb250ZXh0LCAnc29tJzogc29tfSk7CiAgICAgICAgfSwKCiAgICAgICAgcnVuUXVldWU6IGZ1bmN0aW9uIChxdWV1ZSwgZXZudCkgewogICAgICAgICAgICBpZiAocXVldWUgIT09ICJjYWxjIiAmJiBxdWV1ZSAhPT0gInZhbGlkYXRlIikKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgaWYgKHF1ZXVlID09ICJjYWxjIiAmJiAhdGhpcy5ob3N0LmNhbGN1bGF0aW9uc0VuYWJsZWQpCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIGlmIChxdWV1ZSA9PSAidmFsaWRhdGUiICYmICF0aGlzLmhvc3QudmFsaWRhdGlvbnNFbmFibGVkKQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB2YXIgUSA9IHRoaXMuUXVldWVbcXVldWVdOwogICAgICAgICAgICB2YXIgaW5kID0gdGhpcy5RdWV1ZVtxdWV1ZSArICJpbmRleCJdOwogICAgICAgICAgICBmb3IgKHZhciBpID0gaW5kOyBpIDwgUS5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5RdWV1ZVtxdWV1ZSArICJpbmRleCJdKys7CiAgICAgICAgICAgICAgICBpZiAoZXZudCA9PT0gInZhbGlkYXRlIikgewogICAgICAgICAgICAgICAgICAgIFFbaV0uX3ZhbGlkYXRlKFtdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIFFbaV0uZXhlY0V2ZW50KGV2bnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcnVuQ2FsY0FuZFZhbGlkYXRlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuX3B1c2hDb250ZXh0Tm9kZSh0aGlzLmZvcm0pOwogICAgICAgICAgICB0aGlzLnJ1bkNhbGNzKCk7CiAgICAgICAgICAgIHRoaXMucnVuVmFsaWRhdGVzKCk7CiAgICAgICAgICAgIHRoaXMucnVuU2V0Rm9jdXNlcygpOwogICAgICAgICAgICB0aGlzLlF1ZXVlWyJjYWxjIl0gPSBbXTsKICAgICAgICAgICAgdGhpcy5RdWV1ZS5jYWxjaW5kZXggPSAwOwogICAgICAgICAgICB0aGlzLlF1ZXVlLmNhbGNDb3VudCA9IHt9OwogICAgICAgICAgICB0aGlzLlF1ZXVlWyJ2YWxpZGF0ZSJdID0gW107CiAgICAgICAgICAgIHRoaXMuUXVldWUudmFsaWRhdGVpbmRleCA9IDA7CiAgICAgICAgICAgIHRoaXMuUXVldWVbInNldGZvY3VzIl0gPSBbXTsKICAgICAgICAgICAgdGhpcy5RdWV1ZS5zZXRmb2N1c2luZGV4ID0gMDsKICAgICAgICAgICAgdGhpcy5fcG9wQ29udGV4dE5vZGUoKTsKICAgICAgICB9LAoKICAgICAgICBydW5DYWxjczogZnVuY3Rpb24gKHN0YXJ0KSB7CiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3RhcnQgIT0gInVuZGVmaW5lZCIgJiYgc3RhcnQgPT09ICJ0cnVlIikKICAgICAgICAgICAgICAgIHRoaXMuUXVldWUuY2FsY2luZGV4ID0gMDsKICAgICAgICAgICAgdGhpcy5jYWxjdWxhdGVSdW5uaW5nID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5ydW5RdWV1ZSgiY2FsYyIsICJjYWxjdWxhdGUiKTsKICAgICAgICAgICAgdGhpcy5jYWxjdWxhdGVSdW5uaW5nID0gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgcnVuVmFsaWRhdGVzOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMudmFsaWRhdGVSdW5uaW5nID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5ydW5RdWV1ZSgidmFsaWRhdGUiLCAidmFsaWRhdGUiKQogICAgICAgICAgICB0aGlzLnZhbGlkYXRlUnVubmluZyA9IGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIHJ1blNldEZvY3VzZXM6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIFEgPSB0aGlzLlF1ZXVlWyJzZXRmb2N1cyJdLAogICAgICAgICAgICAgICAgaW5kZXggPSB0aGlzLlF1ZXVlWyJzZXRmb2N1c2luZGV4Il07CiAgICAgICAgICAgIGZvciAodmFyIGkgPSBpbmRleDsgaSA8IFEubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuUXVldWVbInNldGZvY3VzaW5kZXgiXSsrOwogICAgICAgICAgICAgICAgdmFyIHNvbSA9IFFbaV1bJ3NvbSddLAogICAgICAgICAgICAgICAgICAgIG5vZGUgPSBzb20sCiAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IFFbaV1bJ2NvbnRleHQnXTsKICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc29tID09ICJzdHJpbmciKQogICAgICAgICAgICAgICAgICAgIG5vZGUgPSBjb250ZXh0Ll94ZmEoKS5yZXNvbHZlTm9kZShzb20pOwogICAgICAgICAgICAgICAgaWYgKG5vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChjb250ZXh0LnBhZ2luZ01hbmFnZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQYWQvaSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmNsZWFyVGltZW91dE9uRGVzdHJveSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5wYWdpbmdNYW5hZ2VyLl9tYWtlUGFnZUZvckh0bWxJZChub2RlLmh0bWxJZCwgbm9kZS5fc2V0Rm9jdXMsIG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApOyAgLy8ganVzdCBnaXZlIGJyb3dzZXIgZW5vdWdoIHRpbWUgdG8gcmVnaXN0ZXIgdGhlIGtleXByZXNzCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LnBhZ2luZ01hbmFnZXIuX21ha2VQYWdlRm9ySHRtbElkKG5vZGUuaHRtbElkLCBub2RlLl9zZXRGb2N1cywgbm9kZSk7IC8vICQuZm9jdXMoKSBkb2Vzbid0IHdvcmsgaW5zaWRlIHNldFRpbWVvdXQgaW4gaVBhZAogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2NvbXB1dGVKc29uRGlmZjogZnVuY3Rpb24gKGRpZmZfbGV2ZWwpIHsKICAgICAgICAgICAgdmFyIGZvcm1EaWZmID0gdGhpcy5mb3JtLl9jb21wdXRlSnNvbkRpZmYoZGlmZl9sZXZlbCk7CiAgICAgICAgICAgIHZhciBkZXN0ID0gewogICAgICAgICAgICAgICAgX2NsYXNzOiB0aGlzLmNsYXNzTmFtZSwKICAgICAgICAgICAgICAgIG5hbWU6ICJ4ZmEiLAogICAgICAgICAgICAgICAgdmVyc2lvbk5TOiB0aGlzLmpzb25Nb2RlbC52ZXJzaW9uTlMsCiAgICAgICAgICAgICAgICBjaGlsZHJlbjogW2Zvcm1EaWZmLmpzb25EaWZmZXJlbmNlXQogICAgICAgICAgICB9OwoKICAgICAgICAgICAgcmV0dXJuIHsgImNoYW5nZWQiOiB0cnVlLAogICAgICAgICAgICAgICAgImpzb25EaWZmZXJlbmNlIjogZGVzdAogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0pOwoKICAgIFhmYS5fZGVmYXVsdExvY2FsZSA9IHsKICAgICAgICAiY2FsZW5kYXJTeW1ib2xzIjogewogICAgICAgICAgICAibW9udGhOYW1lcyI6IFsiSmFudWFyeSIsICJGZWJydWFyeSIsICJNYXJjaCIsICJBcHJpbCIsICJNYXkiLCAiSnVuZSIsICJKdWx5IiwgIkF1Z3VzdCIsICJTZXB0ZW1iZXIiLCAiT2N0b2JlciIsICJOb3ZlbWJlciIsICJEZWNlbWJlciJdLAogICAgICAgICAgICAiYWJicm1vbnRoTmFtZXMiOiBbIkphbiIsICJGZWIiLCAiTWFyIiwgIkFwciIsICJNYXkiLCAiSnVuIiwgIkp1bCIsICJBdWciLCAiU2VwIiwgIk9jdCIsICJOb3YiLCAiRGVjIl0sCiAgICAgICAgICAgICJkYXlOYW1lcyI6IFsiU3VuZGF5IiwgIk1vbmRheSIsICJUdWVzZGF5IiwgIldlZG5lc2RheSIsICJUaHVyc2RheSIsICJGcmlkYXkiLCAiU2F0dXJkYXkiXSwKICAgICAgICAgICAgImFiYnJkYXlOYW1lcyI6IFsiU3VuIiwgIk1vbiIsICJUdWUiLCAiV2VkIiwgIlRodSIsICJGcmkiLCAiU2F0Il0sCiAgICAgICAgICAgICJtZXJpZGllbU5hbWVzIjogWyJBTSIsICJQTSJdLAogICAgICAgICAgICAiZXJhTmFtZXMiOiBbIkJDIiwgIkFEIl0KICAgICAgICB9LAogICAgICAgICJkYXRlUGF0dGVybnMiOiB7CiAgICAgICAgICAgICJmdWxsIjogIkVFRUUgRCBNTU1NIFlZWVkiLAogICAgICAgICAgICAibG9uZyI6ICJEIE1NTU0gWVlZWSIsCiAgICAgICAgICAgICJtZWQiOiAiREQtTU1NLVlZIiwKICAgICAgICAgICAgInNob3J0IjogIkREL01NL1lZIgogICAgICAgIH0sCiAgICAgICAgInRpbWVQYXR0ZXJucyI6IHsKICAgICAgICAgICAgImZ1bGwiOiAiaDpNTTpTUyBBIFoiLAogICAgICAgICAgICAibG9uZyI6ICJoOk1NOlNTIEEgWiIsCiAgICAgICAgICAgICJtZWQiOiAiaDpNTTpTUyBBIiwKICAgICAgICAgICAgInNob3J0IjogImg6TU0gQSIKICAgICAgICB9LAogICAgICAgICJkYXRlVGltZVN5bWJvbHMiOiAiR3lNZGtIbXNTRURGd1dhaEt6WiIsCiAgICAgICAgIm51bWJlclBhdHRlcm5zIjogewogICAgICAgICAgICAibnVtZXJpYyI6ICJ6LHp6LHp6OS56enoiLAogICAgICAgICAgICAiY3VycmVuY3kiOiAiJCB6LHp6LHp6OS45OSIsCiAgICAgICAgICAgICJwZXJjZW50IjogInosenoseno5JSIKICAgICAgICB9LAogICAgICAgICJudW1iZXJTeW1ib2xzIjogewogICAgICAgICAgICAiZGVjaW1hbCI6ICIuIiwKICAgICAgICAgICAgImdyb3VwaW5nIjogIiwiLAogICAgICAgICAgICAicGVyY2VudCI6ICIlIiwKICAgICAgICAgICAgIm1pbnVzIjogIi0iLAogICAgICAgICAgICAiemVybyI6ICIwIgogICAgICAgIH0sCiAgICAgICAgImN1cnJlbmN5U3ltYm9scyI6IHsKICAgICAgICAgICAgInN5bWJvbCI6ICIkIiwKICAgICAgICAgICAgImlzb25hbWUiOiAiVVNEIiwKICAgICAgICAgICAgImRlY2ltYWwiOiAiLiIKICAgICAgICB9LAogICAgICAgICJ0eXBlZmFjZXMiOiB7fQogICAgfQp9KShfLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5CiAqIEBpbXBvcnQgeGZhbGliLnV0LkNsYXNzCiAqLwooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBYZmFNb2RlbFJlZ2lzdHJ5ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5ID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CgogICAgICAgIF9jbGFzc1RvRmFjdG9yeU1hcCA6IHsKICAgICAgICAgICAgInNjcmlwdCIgOiAiY3JlYXRlU2NyaXB0IiwKICAgICAgICAgICAgImV4Y2xHcm91cCIgOiAiY3JlYXRlRXhjbHVzaW9uR3JvdXAiLAoKICAgICAgICAgICAgImFyYyIgOiAiY3JlYXRlTm9kZVZhbHVlIiwKICAgICAgICAgICAgImJvb2xlYW4iOiAiY3JlYXRlTm9kZVZhbHVlIiwKICAgICAgICAgICAgImRhdGUiOiAiY3JlYXRlTm9kZVZhbHVlIiwKICAgICAgICAgICAgImRhdGVUaW1lIjogImNyZWF0ZU5vZGVWYWx1ZSIsCiAgICAgICAgICAgICJkZWNpbWFsIjogImNyZWF0ZU5vZGVWYWx1ZSIsCiAgICAgICAgICAgICJleERhdGEiOiAiY3JlYXRlTm9kZVZhbHVlIiwKICAgICAgICAgICAgImZsb2F0IjogImNyZWF0ZU5vZGVWYWx1ZSIsCiAgICAgICAgICAgICJpbWFnZSI6ICJjcmVhdGVOb2RlVmFsdWUiLAogICAgICAgICAgICAiaW50ZWdlciI6ICJjcmVhdGVOb2RlVmFsdWUiLAogICAgICAgICAgICAibGluZSI6ICJjcmVhdGVOb2RlVmFsdWUiLAogICAgICAgICAgICAicmVjdGFuZ2xlIjogImNyZWF0ZU5vZGVWYWx1ZSIsCiAgICAgICAgICAgICJ0ZXh0IjogImNyZWF0ZU5vZGVWYWx1ZSIsCiAgICAgICAgICAgICJ0aW1lIjogImNyZWF0ZU5vZGVWYWx1ZSIKCiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlTW9kZWwgOiBmdW5jdGlvbihqc29uTW9kZWwpewogICAgICAgICAgICB2YXIgbW9kZWwgPSBudWxsOwogICAgICAgICAgICB2YXIgZWxDbGFzcyA9IGpzb25Nb2RlbC5fY2xhc3MuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBqc29uTW9kZWwuX2NsYXNzLnN1YnN0cigxKTsKICAgICAgICAgICAgdmFyIGZhY3RvcnlGbk5hbWUgPSAiY3JlYXRlIiArIGVsQ2xhc3MgOwogICAgICAgICAgICBpZih0aGlzLl9jbGFzc1RvRmFjdG9yeU1hcFtqc29uTW9kZWwuX2NsYXNzXSl7CiAgICAgICAgICAgICAgICBmYWN0b3J5Rm5OYW1lID0gdGhpcy5fY2xhc3NUb0ZhY3RvcnlNYXBbanNvbk1vZGVsLl9jbGFzc107CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYodGhpc1tmYWN0b3J5Rm5OYW1lXSkKICAgICAgICAgICAgICAgIG1vZGVsID0gdGhpc1tmYWN0b3J5Rm5OYW1lXS5jYWxsKHRoaXMsIGpzb25Nb2RlbCk7CgoKICAgICAgICAgICAgaWYoIW1vZGVsICYmIHhmYWxpYi5zY3JpcHQuZG9tW2VsQ2xhc3NdKXsKICAgICAgICAgICAgICAgIG1vZGVsID0gbmV3IHhmYWxpYi5zY3JpcHQuZG9tW2VsQ2xhc3NdKHsianNvbk1vZGVsIiA6IGpzb25Nb2RlbH0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZighbW9kZWwpIHsKICAgICAgICAgICAgICAgIG1vZGVsID0gbmV3IHhmYWxpYi5zY3JpcHQuTm9kZSh7Impzb25Nb2RlbCIgOiBqc29uTW9kZWx9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbW9kZWw7CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlWGZhIDogZnVuY3Rpb24oanNvbil7CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5YZmEoeyJqc29uTW9kZWwiIDoganNvbn0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUZvcm0gOiBmdW5jdGlvbihqc29uKXsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LkZvcm0oeyJqc29uTW9kZWwiIDoganNvbn0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUNvbmZpZyA6IGZ1bmN0aW9uKGpzb24pewogICAgICAgICAgICByZXR1cm4ganNvbjsgICAgICAvL05vIHNlcGVyYXRlIG1vZGVsIEFQSSBmb3IgY29uZmlnIGZvciBub3cKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVUZXh0RmllbGQgOiBmdW5jdGlvbihmaWVsZCkgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuRmllbGQoeyJqc29uTW9kZWwiIDogZmllbGR9KTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVJbWFnZUZpZWxkIDogZnVuY3Rpb24oZmllbGQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LkZpZWxkKHsianNvbk1vZGVsIiA6IGZpZWxkfSk7CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlRGF0ZVRpbWVGaWVsZCA6IGZ1bmN0aW9uKGZpZWxkKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5EYXRlVGltZUZpZWxkKHsianNvbk1vZGVsIiA6IGZpZWxkfSk7CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlTnVtZXJpY0ZpZWxkIDogZnVuY3Rpb24oZmllbGQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0Lk51bWVyaWNGaWVsZCh7Impzb25Nb2RlbCIgOiBmaWVsZH0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUNob2ljZUxpc3RGaWVsZCA6IGZ1bmN0aW9uKGZpZWxkKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5DaG9pY2VMaXN0RmllbGQoeyJqc29uTW9kZWwiIDogZmllbGR9KTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVCdXR0b25GaWVsZCA6IGZ1bmN0aW9uKGZpZWxkKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5CdXR0b25GaWVsZCh7Impzb25Nb2RlbCIgOiBmaWVsZH0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUNoZWNrQnV0dG9uRmllbGQgOiBmdW5jdGlvbihmaWVsZCkgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuQ2hlY2tCdXR0b25GaWVsZCh7Impzb25Nb2RlbCIgOiBmaWVsZH0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZVRleHREcmF3IDogZnVuY3Rpb24oZHJhdykgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuRHJhdyh7Impzb25Nb2RlbCIgOiBkcmF3fSk7CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlSW5zdGFuY2VNYW5hZ2VyIDogZnVuY3Rpb24ob0luc3RhbmNlTWFuYWdlcikgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuSW5zdGFuY2VNYW5hZ2VyKHsianNvbk1vZGVsIiA6IG9JbnN0YW5jZU1hbmFnZXJ9KTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVQYWdlU2V0OiBmdW5jdGlvbih2UGFnZVNldCkgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuUGFnZVNldCh7Impzb25Nb2RlbCIgOiB2UGFnZVNldH0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZVBhZ2VBcmVhOiBmdW5jdGlvbih2UGFnZUFyZWEpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LlBhZ2VBcmVhKHsianNvbk1vZGVsIiA6IHZQYWdlQXJlYX0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUNvbnRlbnRBcmVhOiBmdW5jdGlvbih2Q29udGVudEFyZWEpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LkNvbnRlbnRBcmVhKHsianNvbk1vZGVsIiA6IHZDb250ZW50QXJlYX0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUV4Y2x1c2lvbkdyb3VwIDogZnVuY3Rpb24oZXhjbEdyb3VwKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5FeGNsdXNpb25Hcm91cCh7Impzb25Nb2RlbCIgOiBleGNsR3JvdXB9KTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVTdWJmb3JtOiBmdW5jdGlvbih2U3ViZm9ybSkgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuU3ViZm9ybSh7Impzb25Nb2RlbCIgOiB2U3ViZm9ybX0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUFyZWE6IGZ1bmN0aW9uKHZBcmVhKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5BcmVhKHsianNvbk1vZGVsIiA6IHZBcmVhfSk7CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlU3ViZm9ybVNldDogZnVuY3Rpb24odlN1YmZvcm1TZXQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LlN1YmZvcm1TZXQoeyJqc29uTW9kZWwiIDogdlN1YmZvcm1TZXR9KTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVWYXJpYWJsZXM6IGZ1bmN0aW9uKHZWYXJpYWJsZXMpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LlZhcmlhYmxlcyh7Impzb25Nb2RlbCIgOiB2VmFyaWFibGVzfSk7CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlU2NyaXB0OiBmdW5jdGlvbih2U2NyaXB0KSB7CiAgICAgICAgICAgIGlmKHZTY3JpcHQuX3BhcmVudENsYXNzICYmIHZTY3JpcHQuX3BhcmVudENsYXNzID09ICJ2YXJpYWJsZXMiKXsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5kb20uU2NyaXB0T2JqZWN0KHsianNvbk1vZGVsIiA6IHZTY3JpcHR9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5kb20uU2NyaXB0KHsianNvbk1vZGVsIiA6IHZTY3JpcHR9KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUZpZWxkIDogZnVuY3Rpb24oZmllbGQpIHsKICAgICAgICAgICAgdmFyIHQgPSBudWxsOwogICAgICAgICAgICB2YXIgY2hpbGRUeXBlID0gdGhpcy5nZXRPckVsc2UodGhpcy54ZmFVdGlsKCkuZ2V0VWlPbmVPZkNoaWxkVGFnKGZpZWxkKSwgIiIpLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgIHN3aXRjaCAoY2hpbGRUeXBlKSB7CiAgICAgICAgICAgICAgICBjYXNlICJkYXRldGltZWVkaXQiOgogICAgICAgICAgICAgICAgICAgIHQgPXRoaXMuY3JlYXRlRGF0ZVRpbWVGaWVsZChmaWVsZCkKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInRleHRlZGl0IjoKICAgICAgICAgICAgICAgICAgICB0ID0gdGhpcy5jcmVhdGVUZXh0RmllbGQoZmllbGQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiaW1hZ2VlZGl0IjoKICAgICAgICAgICAgICAgICAgICB0ID0gdGhpcy5jcmVhdGVJbWFnZUZpZWxkKGZpZWxkKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIm51bWVyaWNlZGl0IjoKICAgICAgICAgICAgICAgICAgICB0ID0gdGhpcy5jcmVhdGVOdW1lcmljRmllbGQoZmllbGQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiY2hvaWNlbGlzdCI6CiAgICAgICAgICAgICAgICAgICAgdCA9IHRoaXMuY3JlYXRlQ2hvaWNlTGlzdEZpZWxkKGZpZWxkKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgImJ1dHRvbiI6CiAgICAgICAgICAgICAgICAgICAgdCA9IHRoaXMuY3JlYXRlQnV0dG9uRmllbGQoZmllbGQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiY2hlY2tidXR0b24iOgogICAgICAgICAgICAgICAgICAgIHQgPSB0aGlzLmNyZWF0ZUNoZWNrQnV0dG9uRmllbGQoZmllbGQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAvL3hmYS5Mb2dnZXIud2FybigidW5rbm93biB1aVR5cGUgZm9yIHRoZSBmaWVsZCAiICsgZmllbGQudWkudHlwZSArICIgPCIKICAgICAgICAgICAgICAgICAgICAvLyAgICArIGZpZWxkLm5hbWUgKyAiPiBDcmVhdGluZyBhIFRleHRGaWVsZCBpbnN0ZWFkIik7CiAgICAgICAgICAgICAgICAgICAgdCA9IHRoaXMuY3JlYXRlVGV4dEZpZWxkKGZpZWxkKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVEcmF3IDogZnVuY3Rpb24oZHJhdykgewogICAgICAgICAgICB2YXIgdCA9IG51bGw7CiAgICAgICAgICAgIHZhciBjaGlsZFR5cGUgPSB0aGlzLmdldE9yRWxzZSh0aGlzLnhmYVV0aWwoKS5nZXRVaU9uZU9mQ2hpbGRUYWcoZHJhdyksICIiKS50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICBzd2l0Y2ggKGNoaWxkVHlwZSkgewogICAgICAgICAgICAgICAgY2FzZSAidGV4dGVkaXQiOgogICAgICAgICAgICAgICAgICAgIHQgPSB0aGlzLmNyZWF0ZVRleHREcmF3KGRyYXcpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAvL3hmYS5Mb2dnZXIud2FybigidW5rbm93biB1aVR5cGUgZm9yIHRoZSBkcmF3ICIgKyBkcmF3LnVpLnR5cGUgKyAiIDwiCiAgICAgICAgICAgICAgICAgICAgLy8gICAgKyBkcmF3Lm5hbWUgKyAiPiBDcmVhdGluZyBhIFN0YXRpYyBUZXh0IGluc3RlYWQiKTsKICAgICAgICAgICAgICAgICAgICB0ID0gdGhpcy5jcmVhdGVUZXh0RHJhdyhkcmF3KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVTb21FeHByZXNzaW9uIDogZnVuY3Rpb24oc0V4cHJlc3Npb24sIG5EZWZhdWx0T2NjdXJyZW5jZSwgYklnbm9yZVByZWRpY2F0ZSkgewogICAgICAgICAgICB2YXIgb3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIGV4cHJlc3Npb24gOiBzRXhwcmVzc2lvbiwKICAgICAgICAgICAgICAgIGRlZmF1bHRPY2N1cnJlbmNlIDogbkRlZmF1bHRPY2N1cnJlbmNlLAogICAgICAgICAgICAgICAgaWdub3JlUHJlZGljYXRlIDogYklnbm9yZVByZWRpY2F0ZQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5TT01FeHByZXNzaW9uKG9wdGlvbnMpOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZVZhbHVlOiBmdW5jdGlvbih2YWx1ZUpzb24pIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LmRvbS5WYWx1ZSh7Impzb25Nb2RlbCIgOiB2YWx1ZUpzb259KTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVOb2RlVmFsdWUgOiBmdW5jdGlvbih2YWx1ZUpzb24pIHsKICAgICAgICAgICAgLy9Ub0RvIDogdGhpcyBpcyBhIHN0b3AgZ3JhcCBtZWFzdXJlIHRpbGwgd2UgZmluZCBhIHdheSB0byBoYW5kbGUgZGVmYXVsdCB2YWx1ZUpzb24KICAgICAgICAgICAgdmFsdWVKc29uID0gdmFsdWVKc29uIHx8IHtfY2xhc3M6ICIiLCByYXdWYWx1ZTogIiJ9OwogICAgICAgICAgICB2YXIgdmFsVHlwZSA9IHZhbHVlSnNvbi5fY2xhc3MudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgc3dpdGNoICh2YWxUeXBlKSB7CiAgICAgICAgICAgICAgICBjYXNlICJ0ZXh0IjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuVGV4dFZhbHVlKHsianNvbk1vZGVsIiA6IHZhbHVlSnNvbn0pOwogICAgICAgICAgICAgICAgY2FzZSAiaW50ZWdlciI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LkludGVnZXJWYWx1ZSh7Impzb25Nb2RlbCIgOiB2YWx1ZUpzb259KTsKICAgICAgICAgICAgICAgIGNhc2UgImRlY2ltYWwiOgogICAgICAgICAgICAgICAgCXJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5EZWNpbWFsVmFsdWUoeyJqc29uTW9kZWwiIDogdmFsdWVKc29ufSk7CiAgICAgICAgICAgICAgICBjYXNlICJmbG9hdCI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LkZsb2F0VmFsdWUoeyJqc29uTW9kZWwiIDogdmFsdWVKc29ufSk7IAogICAgICAgICAgICAgICAgY2FzZSAiZXhkYXRhIjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuRXhEYXRhVmFsdWUoeyJqc29uTW9kZWwiIDogdmFsdWVKc29ufSk7CiAgICAgICAgICAgICAgICBjYXNlICJkYXRlIjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuRGF0ZVZhbHVlKHsianNvbk1vZGVsIiA6IHZhbHVlSnNvbn0pOwogICAgICAgICAgICAgICAgY2FzZSAiaW1hZ2UiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5JbWFnZVZhbHVlKHsianNvbk1vZGVsIiA6IHZhbHVlSnNvbn0pOwogICAgICAgICAgICAgICAgY2FzZSAic2NyaXB0IjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVTY3JpcHQodmFsdWVKc29uKTsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgLy94ZmEuTG9nZ2VyLndhcm4oInVua25vd24gdmFsdWUgdHlwZSAiICsgdmFsdWVKc29uLnR5cGUgKyAiIGZvciBlbGVtZW50IDwiCiAgICAgICAgICAgICAgICAgICAgLy8gICAgKyB0aGlzLm5hbWUgKyAiPiIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5Ob2RlVmFsdWUoeyJqc29uTW9kZWwiIDogdmFsdWVKc29ufSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBjcmVhdGVEYXRhTm9kZTogZnVuY3Rpb24oaWQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LkRhdGFOb2RlKHsianNvbk1vZGVsIiA6IHsiaWQiOmlkfX0pOwogICAgICAgIH0KCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIEFwcCA9IHhmYWxpYi5hY3JvYmF0LkFwcCA9ICB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIEFwcC5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB4ZmFsaWIucnVudGltZS5hcHAgPSB0aGlzOwogICAgICAgICAgICB0aGlzLl92ZXJzaW9uID0gd2luZG93LmZvcm1CcmlkZ2UuZ2V0QnJpZGdlVmVyc2lvbigpOwoKICAgICAgICB9LAoKICAgICAgICBhbGVydDogZnVuY3Rpb24oY01zZykgewogICAgICAgICAgICByZXR1cm4gd2luZG93LmFsZXJ0KGNNc2cpOwogICAgICAgIH0sCgogICAgICAgIGJlZXA6IGZ1bmN0aW9uKG5UeXBlKSB7CgogICAgICAgIH0sCgoKICAgICAgICBleGVjRGlhbG9nOiBmdW5jdGlvbihkaWFsb2cpIHsKCiAgICAgICAgfSwKCiAgICAgICAgbGF1bmNoVVJMOiBmdW5jdGlvbih1cmwsIGJOZXdGcmFtZSkgewogICAgICAgICAgICBpZih1cmwuc2VhcmNoKCJodHRwIikgPT0gLTEpCiAgICAgICAgICAgICAgICB1cmwgPSAiaHR0cDovLyIgKyB1cmwgOwogICAgICAgICAgICBpZihiTmV3RnJhbWUgIT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgd2luZG93Lm9wZW4odXJsKSA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uID0gdXJsOwogICAgICAgIH0sCgogICAgICAgIHNldFRpbWVPdXQ6IGZ1bmN0aW9uKGNFeHByLCBuTWlsbGlzZWNvbmRzKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB2YXIgZm4gPSBuZXcgRnVuY3Rpb24odGhpcy5fd2l0aGluKGNFeHByKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgIGZuLmNhbGwoeGZhbGliLnJ1bnRpbWUuRG9jdW1lbnQpOwogICAgICAgICAgICAgICAgfSwgbk1pbGxpc2Vjb25kcyk7CiAgICAgICAgICAgIH0gY2F0Y2goZXgpIHsKICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGV4KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHNldEludGVydmFsOiBmdW5jdGlvbihjRXhwciwgbk1pbGxpc2Vjb25kcykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdmFyIGZuID0gbmV3IEZ1bmN0aW9uKHRoaXMuX3dpdGhpbihjRXhwcikpOwogICAgICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5zZXRJbnRlcnZhbChmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICBmbi5jYWxsKHhmYWxpYi5ydW50aW1lLkRvY3VtZW50KTsKICAgICAgICAgICAgICAgIH0sIG5NaWxsaXNlY29uZHMpOwogICAgICAgICAgICB9IGNhdGNoKGV4KSB7CiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhleCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBjbGVhclRpbWVPdXQ6IGZ1bmN0aW9uKG9UaW1lKSB7CiAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQob1RpbWUpOwogICAgICAgIH0sCgogICAgICAgIGNsZWFySW50ZXJ2YWw6IGZ1bmN0aW9uKG9JbnRlcnZhbCkgewogICAgICAgICAgICB3aW5kb3cuY2xlYXJJbnRlcnZhbChvSW50ZXJ2YWwpOwogICAgICAgIH0sCgogICAgICAgIGV2YWw6IGZ1bmN0aW9uKHNjcmlwdCkgewogICAgICAgICAgICB3aW5kb3cuZXZhbCh0aGlzLl93aXRoaW4oc2NyaXB0KSk7CiAgICAgICAgfSwKCiAgICAgICAgX3dpdGhpbjogZnVuY3Rpb24oc2NyaXB0KXsKICAgICAgICAgICAgdmFyIHN0cmluZyAgPSAgICJ0cnkge1xuIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndpdGgoeGZhbGliLnJ1bnRpbWUuRG9jdW1lbnQpIHtcbiIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2l0aCh4ZmFsaWIucnVudGltZSkge1xuIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JpcHQgKyJcbiIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAifVxuIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIn1cbiIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIn0gY2F0Y2goZXgpIHtcbiIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb25zb2xlLmxvZyhleClcbiIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIn0iOwogICAgICAgICAgICByZXR1cm4gc3RyaW5nOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBBcHAuZGVmaW5lUHJvcHMoewogICAgICAgICJhY3RpdmVEb2NzIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKFtdKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJjYWxjdWxhdGUiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiAodHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAiY29uc3RhbnRzIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKHthbGlnbjp7fX0pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImZvY3VzUmVjdCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICh0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJmb3Jtc1ZlcnNpb24iIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiAodGhpcy5fdmVyc2lvbik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAiZnJvbVBERkNvbnZlcnRlcnMiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoW10pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImZzIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKHtpc0Z1bGxTY3JlZW46IGZhbHNlfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAiZnVsbHNjcmVlbiIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIChmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAibGFuZ3VhZ2UiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIGlmKG5hdmlnYXRvci5sYW5ndWFnZS5zdWJzdHIoMCwyKSA9PT0gImVuIikKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCJFTlUiKTsKICAgICAgICAgICAgICAgIHJldHVybiAoIkVOVSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInBsYXRmb3JtIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICBpZihuYXZpZ2F0b3IuYXBwVmVyc2lvbi5pbmRleE9mKCJXaW4iKSAhPSAtMSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCJXSU4iKTsKICAgICAgICAgICAgICAgIGlmKG5hdmlnYXRvci5hcHBWZXJzaW9uLmluZGV4T2YoIk1hYyIpICE9IC0xKQogICAgICAgICAgICAgICAgICAgIHJldHVybiAoIk1BQyIpOwogICAgICAgICAgICAgICAgcmV0dXJuICgiVU5JWCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInZpZXdlclR5cGUiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoIkV4Y2hhbmdlLVBybyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInZpZXdlclZhcmlhdGlvbiIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICgiRnVsbCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInZpZXdlclZlcnNpb24iIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiAodGhpcy5fdmVyc2lvbik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KQoKfSkoXywgeGZhbGliKTsKCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIENvbnNvbGUgPSB4ZmFsaWIuYWNyb2JhdC5Db25zb2xlID0gIHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbihiUmVnaXN0ZXIpIHsKICAgICAgICAgICAgQ29uc29sZS5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICBpZihiUmVnaXN0ZXIpCiAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS5jb25zb2xlID0gdGhpczsKICAgICAgICB9LAoKICAgICAgICBwcmludGxuOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgLy9hZGQgdGhpcyBtZXRob2QgdG8gaW5zZXJ0IGNvbnNvbGUgd2hlcmUgJ2NvbnNvbGUnIGlzIG5vdCBzdXBwb3J0ZWQKICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBBY3JvYmF0ID0geGZhbGliLmFjcm9iYXQuQWNyb2JhdCA9ICB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIEFjcm9iYXQuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgLy9pbml0aWFsaXplIEFwcCBvYmplY3QKICAgICAgICAgICAgbmV3IHhmYWxpYi5hY3JvYmF0LkFwcCgpOwogICAgICAgICAgICAvL2luc2VydCBwcmludGxuIGluc2lkZSBjb25zb2xlIG9iamVjdAogICAgICAgICAgICBpZih0eXBlb2YoY29uc29sZSkgIT0gInVuZGVmaW5lZCIpIHsKICAgICAgICAgICAgICAgIGlmKGNvbnNvbGUubG9nKQogICAgICAgICAgICAgICAgICAgIGNvbnNvbGUucHJpbnRsbiA9IGNvbnNvbGUubG9nOwogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy9yZWdpc3RlciBlbXB0eSBtZXRob2QKICAgICAgICAgICAgICAgICAgICB2YXIgY29uID0gbmV3IHhmYWxpYi5hY3JvYmF0LkNvbnNvbGUoKTsKICAgICAgICAgICAgICAgICAgICBjb25zb2xlLnByaW50bG4gPSBjb24ucHJpbnRsbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIG5ldyB4ZmFsaWIuYWNyb2JhdC5Db25zb2xlKHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwoKLyoqCiAqIENyZWF0ZWQgd2l0aCBJbnRlbGxpSiBJREVBLgogKiBVc2VyOiB2ZHVhCiAqIERhdGU6IDIxLzUvMTMKICogVGltZTogNTo1NiBQTQogKiBUbyBjaGFuZ2UgdGhpcyB0ZW1wbGF0ZSB1c2UgRmlsZSB8IFNldHRpbmdzIHwgRmlsZSBUZW1wbGF0ZXMuCgogLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudAogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuT2JqZWN0CiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgWGZhTW9kZWxFdmVudCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCihmdW5jdGlvbihfLHhmYWxpYikgewoKICAgIHZhciBGaWVsZCA9IHhmYWxpYi5hY3JvYmF0LkZpZWxkID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBGaWVsZC5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLl94ZmFGaWVsZCA9IHhmYWxpYi5zY3JpcHQuWGZhLkluc3RhbmNlLnJlc29sdmVOb2RlKCJ4ZmEuZm9ybS4iK3RoaXMuanNvbk1vZGVsLnNvbUV4cHJlc3Npb24pOwogICAgICAgIH0sCgogICAgICAgIHNpZ25hdHVyZUluZm8gOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdGhyb3cge21lc3NhZ2U6InNpZ25hdHVyZUluZm8gaXMgbm90IHN1cHBvcnRlZCJ9CiAgICAgICAgfSwKCiAgICAgICAgc2V0Rm9jdXM6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB4ZmFsaWIuc2NyaXB0LlhmYS5JbnN0YW5jZS5ob3N0LnNldEZvY3VzKHRoaXMuanNvbk1vZGVsLnNvbUV4cHJlc3Npb24pOwogICAgICAgIH0KICAgIH0pOwoKICAgIEZpZWxkLmRlZmluZVByb3BzKHsKCiAgICB9KQp9KShfLHhmYWxpYik7Ci8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk9iamVjdAogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIFhmYU1vZGVsRXZlbnQgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwooZnVuY3Rpb24oXyx4ZmFsaWIpIHsKCiAgICB2YXIgRG9jID0geGZhbGliLmFjcm9iYXQuRG9jID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CgogICAgICAgIGdldFVSTDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB3aW5kb3cubG9jYXRpb24uaHJlZjsKICAgICAgICB9LAoKICAgICAgICByZXNldEZvcm06IGZ1bmN0aW9uKGZpZWxkQXJyYXkpIHsKICAgICAgICAgICAgaWYoIShmaWVsZEFycmF5IGluc3RhbmNlb2YgQXJyYXkpKSB7CiAgICAgICAgICAgICAgICBmaWVsZEFycmF5ID0gW2ZpZWxkQXJyYXldOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMueGZhLmhvc3QucmVzZXREYXRhLmFwcGx5KHRoaXMueGZhLmhvc3QsZmllbGRBcnJheSk7CiAgICAgICAgfSwKCiAgICAgICAgc3VibWl0Rm9ybTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHRoaXMueGZhLkxvZ2dlci5lcnJvcigieGZhIix4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDYiXSxbInN1Ym1pdEZvcm0iXSk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RmllbGQ6IGZ1bmN0aW9uKHNvbSkgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5hY3JvYmF0LkZpZWxkKHsianNvbk1vZGVsIiA6IHsic29tRXhwcmVzc2lvbiI6IHNvbX19KTsKICAgICAgICB9LAoKICAgICAgICBpbXBvcnREYXRhT2JqZWN0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdGhyb3cge21lc3NhZ2U6ImltcG9ydERhdGFPYmplY3QgaXMgbm90IHN1cHBvcnRlZCJ9CiAgICAgICAgfQoKICAgIH0pOwoKICAgIERvYy5kZWZpbmVQcm9wcyh7CiAgICAgICAgInhmYSIgOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4geGZhbGliLnNjcmlwdC5YZmEuSW5zdGFuY2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSkKCiAgICB4ZmFsaWIucnVudGltZS5Eb2N1bWVudCA9IG5ldyB4ZmFsaWIuYWNyb2JhdC5Eb2Moe2pzb25Nb2RlbDp7fX0pOwoKfSkoXyx4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50CiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5PYmplY3QKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBYZmFNb2RlbEV2ZW50IENsYXNzIHJlcXVpcmVkIGZvciBYRkEgbGlicmFyeQogKiBAdmVyc2lvbiAwLjAuMQogKi8KKGZ1bmN0aW9uKF8seGZhbGliKSB7CgogICAgdmFyIEFjcm9FdmVudCA9IHhmYWxpYi5hY3JvYmF0LkFjcm9FdmVudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiAiYWNyb0V2ZW50IiwKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC50YXJnZXQgPSB4ZmFsaWIucnVudGltZS5Eb2N1bWVudDsKICAgICAgICB9CiAgICB9KTsKCiAgICBBY3JvRXZlbnQuY2xvbmVFdmVudCA9IGZ1bmN0aW9uKHhmYU1vZGVsRXZlbnQpIHsKICAgICAgICB2YXIgY29weSA9IHhmYU1vZGVsRXZlbnQuY29weU9iamVjdCh4ZmFNb2RlbEV2ZW50Lmpzb25Nb2RlbCwge30seyJleGNlcHRpb25zIjpbInRhcmdldCJdfSk7CiAgICAgICAgcmV0dXJuIG5ldyBBY3JvRXZlbnQoeyJqc29uTW9kZWwiIDogY29weX0pOwogICAgfTsKCn0pKF8seGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBBcHBlYXJhbmNlRmlsdGVyID0geGZhbGliLnNjcmlwdC5kb20uQXBwZWFyYW5jZUZpbHRlciA9IHhmYWxpYi5zY3JpcHQuR2VuZXJpY1RleHQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiYXBwZWFyYW5jZUZpbHRlciIKICAgIH0pOwoKICAgIEFwcGVhcmFuY2VGaWx0ZXIuZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEFzc2lzdCA9IHhmYWxpYi5zY3JpcHQuZG9tLkFzc2lzdCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJhc3Npc3QiCiAgICB9KTsKCiAgICBBc3Npc3QuZGVmaW5lUHJvcHMoewogICAgICAgIHJvbGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyb2xlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicm9sZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzcGVhazp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJzcGVhayIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzcGVhayIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0b29sVGlwOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInRvb2xUaXAiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAidG9vbFRpcCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJhcmNvZGUgPSB4ZmFsaWIuc2NyaXB0LmRvbS5CYXJjb2RlID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImJhcmNvZGUiCiAgICB9KTsKCiAgICBCYXJjb2RlLmRlZmluZVByb3BzKHsKICAgICAgICBjaGFyRW5jb2Rpbmc6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJjaGFyRW5jb2RpbmciKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJjaGFyRW5jb2RpbmciKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY2hlY2tzdW06ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJjaGVja3N1bSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImNoZWNrc3VtIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGRhdGFDb2x1bW5Db3VudDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImRhdGFDb2x1bW5Db3VudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImRhdGFDb2x1bW5Db3VudCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBkYXRhTGVuZ3RoOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZGF0YUxlbmd0aCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImRhdGFMZW5ndGgiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZGF0YVByZXA6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJkYXRhUHJlcCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImRhdGFQcmVwIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGRhdGFSb3dDb3VudDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImRhdGFSb3dDb3VudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImRhdGFSb3dDb3VudCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBlbmRDaGFyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZW5kQ2hhciIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImVuZENoYXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXJyb3JDb3JyZWN0aW9uTGV2ZWw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJlcnJvckNvcnJlY3Rpb25MZXZlbCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImVycm9yQ29ycmVjdGlvbkxldmVsIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG1vZHVsZUhlaWdodDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm1vZHVsZUhlaWdodCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm1vZHVsZUhlaWdodCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtb2R1bGVXaWR0aDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm1vZHVsZVdpZHRoIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibW9kdWxlV2lkdGgiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcHJpbnRDaGVja0RpZ2l0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicHJpbnRDaGVja0RpZ2l0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicHJpbnRDaGVja0RpZ2l0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJvd0NvbHVtblJhdGlvOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicm93Q29sdW1uUmF0aW8iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJyb3dDb2x1bW5SYXRpbyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzdGFydENoYXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJzdGFydENoYXIiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJzdGFydENoYXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdGV4dExvY2F0aW9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidGV4dExvY2F0aW9uIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidGV4dExvY2F0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRydW5jYXRlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidHJ1bmNhdGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0cnVuY2F0ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0eXBlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidHlwZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInR5cGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdXBzTW9kZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInVwc01vZGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ1cHNNb2RlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHdpZGVOYXJyb3dSYXRpbzp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIndpZGVOYXJyb3dSYXRpbyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIndpZGVOYXJyb3dSYXRpbyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBlbmNyeXB0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImVuY3J5cHQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZW5jcnlwdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJpbmQgPSB4ZmFsaWIuc2NyaXB0LmRvbS5CaW5kID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImJpbmQiCiAgICB9KTsKCiAgICBCaW5kLmRlZmluZVByb3BzKHsKICAgICAgICBtYXRjaDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm1hdGNoIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibWF0Y2giKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVmOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicmVmIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicmVmIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHBpY3R1cmU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgicGljdHVyZSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJwaWN0dXJlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgQmluZEl0ZW1zID0geGZhbGliLnNjcmlwdC5kb20uQmluZEl0ZW1zID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJiaW5kSXRlbXMiCiAgICB9KTsKCiAgICBCaW5kSXRlbXMuZGVmaW5lUHJvcHMoewogICAgICAgIGNvbm5lY3Rpb246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJjb25uZWN0aW9uIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiY29ubmVjdGlvbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBsYWJlbFJlZjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImxhYmVsUmVmIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGFiZWxSZWYiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVmOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicmVmIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicmVmIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHZhbHVlUmVmOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidmFsdWVSZWYiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ2YWx1ZVJlZiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJvb2tlbmQgPSB4ZmFsaWIuc2NyaXB0LmRvbS5Cb29rZW5kID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJib29rZW5kIgogICAgfSk7CgogICAgQm9va2VuZC5kZWZpbmVQcm9wcyh7CiAgICAgICAgbGVhZGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGVhZGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGVhZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRyYWlsZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0cmFpbGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHJhaWxlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJvcmRlciA9IHhmYWxpYi5zY3JpcHQuZG9tLkJvcmRlciA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJib3JkZXIiLAoKICAgICAgICBoYW5kbGVFdmVudDogZnVuY3Rpb24gKGV2bnQpIHsKICAgICAgICAgICAgaWYoZXZudC5fcHJvcGVydHkgPT0gJ2VkZ2UuY29sb3IudmFsdWUnKSB7CiAgICAgICAgICAgICAgICAvL0lmIHRoZSBjb2xvciBpcyBiZWluZyBzZXQgZm9yIGZpcnN0IGJvcmRlciBlZGdlLCBhbmQgdGhlIGNvcm5lciBhcmUgcm91bmRlZCAtIHNldCBmb3IgYWxsIHRoZSBlZGdlcwogICAgICAgICAgICAgICAgLy9yZWFzb246IEluIGNhc2Ugb2Ygcm91bmRlZCBjb3JuZXIsIHdlIGRpdmlkZSB0aGUgc2luZ2xlIGVkZ2UgaW50byA0IGVkZ2VzLCBhbmQgdGh1cyB3aGVuIHRyeWluZyB0byBzZXQKICAgICAgICAgICAgICAgIC8vdGhlIGNvbG9yIGZvciBhbGwgb2YgdGhlbSB0b2dldGhlciwgb25seSBmaXJzdCBpcyBzZXQgLSBOUFItMTU0NDQKICAgICAgICAgICAgICAgIHZhciBpc0ZpcnN0SW5kZXggPSBldm50LnRhcmdldC5wYXJlbnQubW5DbGFzc0luZGV4ID09IDAsCiAgICAgICAgICAgICAgICAgICAgaXNSb3VuZGVkQm9yZGVyID0gISEocGFyc2VJbnQodGhpcy5jb3JuZXIucmFkaXVzKSk7CiAgICAgICAgICAgICAgICBpZihpc0ZpcnN0SW5kZXggJiYgaXNSb3VuZGVkQm9yZGVyKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgZWRnZTsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZWRnZSA9IHRoaXMuZ2V0RWxlbWVudCgnZWRnZScsIGluZGV4LCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvL3NldCB0aGUgdmFsdWUgaW4gY2FzZSBhIGRpZmZlcmVudCBjb2xvciBoYXMgbm90IGJlZW4gc2V0IGZvciBhIGRpZmZlcmVudCBlZGdlIGV4cGxpY2l0bHkKICAgICAgICAgICAgICAgICAgICAgICAgZWRnZS5jb2xvci5zZXRBdHRyaWJ1dGUoZXZudC50YXJnZXQudmFsdWUsJ3ZhbHVlJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIEJvcmRlci5fc3VwZXIuaGFuZGxlRXZlbnQuY2FsbCh0aGlzLCBldm50KTsKICAgICAgICB9CiAgICB9KTsKCiAgICBCb3JkZXIuZGVmaW5lUHJvcHMoewogICAgICAgICJicmVhayI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJicmVhayIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImJyZWFrIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGhhbmQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJoYW5kIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaGFuZCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBwcmVzZW5jZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInByZXNlbmNlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicHJlc2VuY2UiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVsZXZhbnQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyZWxldmFudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJlbGV2YW50Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGNvcm5lcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjb3JuZXIiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY29ybmVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGVkZ2U6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZWRnZSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJlZGdlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGZpbGw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZmlsbCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJmaWxsIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG1hcmdpbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJtYXJnaW4iLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWFyZ2luIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgQnJlYWsgPSB4ZmFsaWIuc2NyaXB0LmRvbS5CcmVhayA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJicmVhayIKICAgIH0pOwoKICAgIEJyZWFrLmRlZmluZVByb3BzKHsKICAgICAgICBhZnRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImFmdGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiYWZ0ZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgYWZ0ZXJUYXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJhZnRlclRhcmdldCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImFmdGVyVGFyZ2V0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGJlZm9yZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImJlZm9yZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImJlZm9yZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBiZWZvcmVUYXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJiZWZvcmVUYXJnZXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJiZWZvcmVUYXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgYm9va2VuZExlYWRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImJvb2tlbmRMZWFkZXIiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJib29rZW5kTGVhZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGJvb2tlbmRUcmFpbGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiYm9va2VuZFRyYWlsZXIiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJib29rZW5kVHJhaWxlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBvdmVyZmxvd0xlYWRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm92ZXJmbG93TGVhZGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAib3ZlcmZsb3dMZWFkZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgb3ZlcmZsb3dUYXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJvdmVyZmxvd1RhcmdldCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm92ZXJmbG93VGFyZ2V0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG92ZXJmbG93VHJhaWxlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm92ZXJmbG93VHJhaWxlciIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm92ZXJmbG93VHJhaWxlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzdGFydE5ldzp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInN0YXJ0TmV3Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic3RhcnROZXciKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBCcmVha0FmdGVyID0geGZhbGliLnNjcmlwdC5kb20uQnJlYWtBZnRlciA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJicmVha0FmdGVyIgogICAgfSk7CgogICAgQnJlYWtBZnRlci5kZWZpbmVQcm9wcyh7CiAgICAgICAgbGVhZGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGVhZGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGVhZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHN0YXJ0TmV3OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic3RhcnROZXciKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJzdGFydE5ldyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0YXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0YXJnZXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdGFyZ2V0VHlwZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRhcmdldFR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXRUeXBlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRyYWlsZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0cmFpbGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHJhaWxlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzY3JpcHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic2NyaXB0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInNjcmlwdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJyZWFrQmVmb3JlID0geGZhbGliLnNjcmlwdC5kb20uQnJlYWtCZWZvcmUgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiYnJlYWtCZWZvcmUiCiAgICB9KTsKCiAgICBCcmVha0JlZm9yZS5kZWZpbmVQcm9wcyh7CiAgICAgICAgbGVhZGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGVhZGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGVhZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHN0YXJ0TmV3OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic3RhcnROZXciKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJzdGFydE5ldyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0YXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0YXJnZXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdGFyZ2V0VHlwZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRhcmdldFR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXRUeXBlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRyYWlsZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0cmFpbGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHJhaWxlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzY3JpcHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic2NyaXB0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInNjcmlwdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJ1dHRvbiA9IHhmYWxpYi5zY3JpcHQuZG9tLkJ1dHRvbiA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJidXR0b24iCiAgICB9KTsKCiAgICBCdXR0b24uZGVmaW5lUHJvcHMoewogICAgICAgIGhpZ2hsaWdodDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImhpZ2hsaWdodCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImhpZ2hsaWdodCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIENhbGN1bGF0ZSA9IHhmYWxpYi5zY3JpcHQuZG9tLkNhbGN1bGF0ZSA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJjYWxjdWxhdGUiCiAgICB9KTsKCiAgICBDYWxjdWxhdGUuZGVmaW5lUHJvcHMoewogICAgICAgIG92ZXJyaWRlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgib3ZlcnJpZGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJvdmVycmlkZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtZXNzYWdlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoIm1lc3NhZ2UiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWVzc2FnZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzY3JpcHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic2NyaXB0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInNjcmlwdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIENhcHRpb24gPSB4ZmFsaWIuc2NyaXB0LmRvbS5DYXB0aW9uID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImNhcHRpb24iCiAgICB9KTsKCiAgICBDYXB0aW9uLmRlZmluZVByb3BzKHsKICAgICAgICBwbGFjZW1lbnQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJwbGFjZW1lbnQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwbGFjZW1lbnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcHJlc2VuY2U6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJwcmVzZW5jZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInByZXNlbmNlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlc2VydmU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyZXNlcnZlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicmVzZXJ2ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBmb250OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImZvbnQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZm9udCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYXJnaW46ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFyZ2luIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgIm1hcmdpbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBwYXJhOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInBhcmEiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAicGFyYSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB2YWx1ZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJ2YWx1ZSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJ2YWx1ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIENlcnRpZmljYXRlID0geGZhbGliLnNjcmlwdC5kb20uQ2VydGlmaWNhdGUgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImNlcnRpZmljYXRlIgogICAgfSk7CgogICAgQ2VydGlmaWNhdGUuZGVmaW5lUHJvcHMoewogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIENlcnRpZmljYXRlcyA9IHhmYWxpYi5zY3JpcHQuZG9tLkNlcnRpZmljYXRlcyA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJjZXJ0aWZpY2F0ZXMiCiAgICB9KTsKCiAgICBDZXJ0aWZpY2F0ZXMuZGVmaW5lUHJvcHMoewogICAgICAgIGNyZWRlbnRpYWxTZXJ2ZXJQb2xpY3k6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJjcmVkZW50aWFsU2VydmVyUG9saWN5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiY3JlZGVudGlhbFNlcnZlclBvbGljeSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB1cmw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ1cmwiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ1cmwiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdXJsUG9saWN5OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidXJsUG9saWN5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidXJsUG9saWN5Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGVuY3J5cHRpb246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZW5jcnlwdGlvbiIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJlbmNyeXB0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGlzc3VlcnM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiaXNzdWVycyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJpc3N1ZXJzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGtleVVzYWdlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImtleVVzYWdlIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImtleVVzYWdlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG9pZHM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgib2lkcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJvaWRzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHNpZ25pbmc6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic2lnbmluZyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzaWduaW5nIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHN1YmplY3RETnM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic3ViamVjdEROcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzdWJqZWN0RE5zIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgQ2hlY2tCdXR0b24gPSB4ZmFsaWIuc2NyaXB0LmRvbS5DaGVja0J1dHRvbiA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJjaGVja0J1dHRvbiIKICAgIH0pOwoKICAgIENoZWNrQnV0dG9uLmRlZmluZVByb3BzKHsKICAgICAgICBhbGxvd05ldXRyYWw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJhbGxvd05ldXRyYWwiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJhbGxvd05ldXRyYWwiKTsKICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCx0aGlzLCJhbGxvd05ldXRyYWwiLHZhbHVlLCBudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsZXZudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG1hcms6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJtYXJrIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibWFyayIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzaGFwZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInNoYXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic2hhcGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgc2l6ZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInNpemUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJzaXplIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGJvcmRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJib3JkZXIiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiYm9yZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG1hcmdpbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJtYXJnaW4iLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWFyZ2luIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgQ2hvaWNlTGlzdCA9IHhmYWxpYi5zY3JpcHQuZG9tLkNob2ljZUxpc3QgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiY2hvaWNlTGlzdCIKICAgIH0pOwoKICAgIENob2ljZUxpc3QuZGVmaW5lUHJvcHMoewogICAgICAgIGNvbW1pdE9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiY29tbWl0T24iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJjb21taXRPbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBvcGVuOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgib3BlbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm9wZW4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdGV4dEVudHJ5OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidGV4dEVudHJ5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidGV4dEVudHJ5Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGJvcmRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJib3JkZXIiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiYm9yZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG1hcmdpbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJtYXJnaW4iLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWFyZ2luIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgQ29sb3IgPSB4ZmFsaWIuc2NyaXB0LmRvbS5Db2xvciA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJjb2xvciIKICAgIH0pOwoKICAgIENvbG9yLmRlZmluZVByb3BzKHsKICAgICAgICBjU3BhY2U6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJjU3BhY2UiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJjU3BhY2UiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdmFsdWU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ2YWx1ZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInZhbHVlIik7CiAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQsCiAgICAgICAgICAgICAgICAgICAgdGhpcywiY29sb3IudmFsdWUiLHZhbHVlLCBudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsZXZudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgQ29tYiA9IHhmYWxpYi5zY3JpcHQuZG9tLkNvbWIgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImNvbWIiCiAgICB9KTsKCiAgICBDb21iLmRlZmluZVByb3BzKHsKICAgICAgICBudW1iZXJPZkNlbGxzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibnVtYmVyT2ZDZWxscyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm51bWJlck9mQ2VsbHMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBDb25uZWN0ID0geGZhbGliLnNjcmlwdC5kb20uQ29ubmVjdCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJjb25uZWN0IgogICAgfSk7CgogICAgQ29ubmVjdC5kZWZpbmVQcm9wcyh7CiAgICAgICAgY29ubmVjdGlvbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImNvbm5lY3Rpb24iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJjb25uZWN0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlZjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJlZiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJlZiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB1c2FnZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInVzYWdlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidXNhZ2UiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcGljdHVyZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJwaWN0dXJlIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInBpY3R1cmUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBDb3JuZXIgPSB4ZmFsaWIuc2NyaXB0LmRvbS5Db3JuZXIgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiY29ybmVyIgogICAgfSk7CgogICAgQ29ybmVyLmRlZmluZVByb3BzKHsKICAgICAgICBpbnZlcnRlZDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImludmVydGVkIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaW52ZXJ0ZWQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgam9pbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImpvaW4iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJqb2luIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHByZXNlbmNlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicHJlc2VuY2UiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwcmVzZW5jZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICByYWRpdXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyYWRpdXMiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJyYWRpdXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgc3Ryb2tlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic3Ryb2tlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic3Ryb2tlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRoaWNrbmVzczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRoaWNrbmVzcyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInRoaWNrbmVzcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb2xvcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjb2xvciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJjb2xvciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIERhdGVUaW1lRWRpdCA9IHhmYWxpYi5zY3JpcHQuZG9tLkRhdGVUaW1lRWRpdCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJkYXRlVGltZUVkaXQiCiAgICB9KTsKCiAgICBEYXRlVGltZUVkaXQuZGVmaW5lUHJvcHMoewogICAgICAgIGhTY3JvbGxQb2xpY3k6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJoU2Nyb2xsUG9saWN5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaFNjcm9sbFBvbGljeSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBwaWNrZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJwaWNrZXIiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwaWNrZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgYm9yZGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImJvcmRlciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJib3JkZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY29tYjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjb21iIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImNvbWIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbWFyZ2luOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoIm1hcmdpbiIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJtYXJnaW4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBEZWZhdWx0VWkgPSB4ZmFsaWIuc2NyaXB0LmRvbS5EZWZhdWx0VWkgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiZGVmYXVsdFVpIgogICAgfSk7CgogICAgRGVmYXVsdFVpLmRlZmluZVByb3BzKHsKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgdmFyIERlc2MgPSB4ZmFsaWIuc2NyaXB0LmRvbS5EZXNjID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJkZXNjIgogICAgfSk7Cgp9KShfLHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgRGlnZXN0TWV0aG9kID0geGZhbGliLnNjcmlwdC5kb20uRGlnZXN0TWV0aG9kID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJkaWdlc3RNZXRob2QiCiAgICB9KTsKCiAgICBEaWdlc3RNZXRob2QuZGVmaW5lUHJvcHMoewogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIERpZ2VzdE1ldGhvZHMgPSB4ZmFsaWIuc2NyaXB0LmRvbS5EaWdlc3RNZXRob2RzID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImRpZ2VzdE1ldGhvZHMiCiAgICB9KTsKCiAgICBEaWdlc3RNZXRob2RzLmRlZmluZVByb3BzKHsKICAgICAgICAidHlwZSI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBFZGdlID0geGZhbGliLnNjcmlwdC5kb20uRWRnZSA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJlZGdlIgogICAgfSk7CgogICAgRWRnZS5kZWZpbmVQcm9wcyh7CiAgICAgICAgY2FwOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiY2FwIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiY2FwIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHByZXNlbmNlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicHJlc2VuY2UiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwcmVzZW5jZSIpOwogICAgICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkRPTV9DSEFOR0VELAogICAgICAgICAgICAgICAgICAgIHRoaXMsImVkZ2UucHJlc2VuY2UiLHZhbHVlLCBudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsZXZudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHN0cm9rZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInN0cm9rZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInN0cm9rZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0aGlja25lc3M6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0aGlja25lc3MiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0aGlja25lc3MiKTsKICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICB0aGlzLCJlZGdlLnRoaWNrbmVzcyIsdmFsdWUsIG51bGwpOwogICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY29sb3I6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiY29sb3IiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY29sb3IiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBFbmNvZGluZyA9IHhmYWxpYi5zY3JpcHQuZG9tLkVuY29kaW5nID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJlbmNvZGluZyIKICAgIH0pOwoKICAgIEVuY29kaW5nLmRlZmluZVByb3BzKHsKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBFbmNvZGluZ3MgPSB4ZmFsaWIuc2NyaXB0LmRvbS5FbmNvZGluZ3MgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiZW5jb2RpbmdzIgogICAgfSk7CgogICAgRW5jb2RpbmdzLmRlZmluZVByb3BzKHsKICAgICAgICAidHlwZSI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBFbmNyeXB0ID0geGZhbGliLnNjcmlwdC5kb20uRW5jcnlwdCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJlbmNyeXB0IgogICAgfSk7CgogICAgRW5jcnlwdC5kZWZpbmVQcm9wcyh7CiAgICAgICAgY2VydGlmaWNhdGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiY2VydGlmaWNhdGUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY2VydGlmaWNhdGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBFbmNyeXB0RGF0YSA9IHhmYWxpYi5zY3JpcHQuZG9tLkVuY3J5cHREYXRhID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImVuY3J5cHREYXRhIgogICAgfSk7CgogICAgRW5jcnlwdERhdGEuZGVmaW5lUHJvcHMoewogICAgICAgIG9wZXJhdGlvbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm9wZXJhdGlvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm9wZXJhdGlvbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0YXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0YXJnZXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZmlsdGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImZpbHRlciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJmaWx0ZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbWFuaWZlc3Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFuaWZlc3QiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWFuaWZlc3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBFbmNyeXB0aW9uID0geGZhbGliLnNjcmlwdC5kb20uRW5jcnlwdGlvbiA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJlbmNyeXB0aW9uIgogICAgfSk7CgogICAgRW5jcnlwdGlvbi5kZWZpbmVQcm9wcyh7CiAgICAgICAgdHlwZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0eXBlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEVuY3J5cHRpb25NZXRob2QgPSB4ZmFsaWIuc2NyaXB0LmRvbS5FbmNyeXB0aW9uTWV0aG9kID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJlbmNyeXB0aW9uTWV0aG9kIgogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEVuY3J5cHRpb25NZXRob2RzID0geGZhbGliLnNjcmlwdC5kb20uRW5jcnlwdGlvbk1ldGhvZHMgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiZW5jcnlwdGlvbk1ldGhvZHMiCiAgICB9KTsKCiAgICBFbmNyeXB0aW9uTWV0aG9kcy5kZWZpbmVQcm9wcyh7CiAgICAgICAgInR5cGUiOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidHlwZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInR5cGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgRXZlbnQgPSB4ZmFsaWIuc2NyaXB0LmRvbS5FdmVudCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJldmVudCIKICAgIH0pOwoKICAgIEV2ZW50LmRlZmluZVByb3BzKHsKICAgICAgICBhY3Rpdml0eTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImFjdGl2aXR5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiYWN0aXZpdHkiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbGlzdGVuOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGlzdGVuIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGlzdGVuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlZjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJlZiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJlZiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBlbmNyeXB0RGF0YTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJlbmNyeXB0RGF0YSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJlbmNyeXB0RGF0YSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleGVjdXRlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4ZWN1dGUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXhlY3V0ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzY3JpcHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic2NyaXB0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInNjcmlwdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzaWduRGF0YTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJzaWduRGF0YSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzaWduRGF0YSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzdWJtaXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic3VibWl0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInN1Ym1pdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEV4ZWN1dGUgPSB4ZmFsaWIuc2NyaXB0LmRvbS5FeGVjdXRlID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJleGVjdXRlIgogICAgfSk7CgogICAgRXhlY3V0ZS5kZWZpbmVQcm9wcyh7CiAgICAgICAgY29ubmVjdGlvbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImNvbm5lY3Rpb24iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJjb25uZWN0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4ZWN1dGVUeXBlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZXhlY3V0ZVR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJleGVjdXRlVHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBydW5BdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJ1bkF0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicnVuQXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHZhciBFeHRyYXMgPSB4ZmFsaWIuc2NyaXB0LmRvbS5FeHRyYXMgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZTogImV4dHJhcyIKICAgIH0pOwoKfSkoXyx4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEZpbGwgPSB4ZmFsaWIuc2NyaXB0LmRvbS5GaWxsID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImZpbGwiCiAgICB9KTsKCiAgICBGaWxsLmRlZmluZVByb3BzKHsKICAgICAgICBwcmVzZW5jZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInByZXNlbmNlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicHJlc2VuY2UiKTsKICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICB0aGlzLCJmaWxsLnByZXNlbmNlIix2YWx1ZSwgbnVsbCk7CiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb2xvcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjb2xvciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJjb2xvciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBsaW5lYXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibGluZWFyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImxpbmVhciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBwYXR0ZXJuOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInBhdHRlcm4iLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAicGF0dGVybiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICByYWRpYWw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgicmFkaWFsIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInJhZGlhbCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzb2xpZDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJzb2xpZCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzb2xpZCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzdGlwcGxlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInN0aXBwbGUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAic3RpcHBsZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEZpbHRlciA9IHhmYWxpYi5zY3JpcHQuZG9tLkZpbHRlciA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJmaWx0ZXIiCiAgICB9KTsKCiAgICBGaWx0ZXIuZGVmaW5lUHJvcHMoewogICAgICAgIGFkZFJldm9jYXRpb25JbmZvOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiYWRkUmV2b2NhdGlvbkluZm8iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJhZGRSZXZvY2F0aW9uSW5mbyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB2ZXJzaW9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidmVyc2lvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInZlcnNpb24iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgYXBwZWFyYW5jZUZpbHRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJhcHBlYXJhbmNlRmlsdGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImFwcGVhcmFuY2VGaWx0ZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY2VydGlmaWNhdGVzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImNlcnRpZmljYXRlcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJjZXJ0aWZpY2F0ZXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZGlnZXN0TWV0aG9kczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJkaWdlc3RNZXRob2RzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImRpZ2VzdE1ldGhvZHMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZW5jb2RpbmdzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImVuY29kaW5ncyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJlbmNvZGluZ3MiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZW5jcnlwdGlvbk1ldGhvZHM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZW5jcnlwdGlvbk1ldGhvZHMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZW5jcnlwdGlvbk1ldGhvZHMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgaGFuZGxlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJoYW5kbGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImhhbmRsZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbG9ja0RvY3VtZW50OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImxvY2tEb2N1bWVudCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJsb2NrRG9jdW1lbnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbWRwOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoIm1kcCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJtZHAiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVhc29uczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJyZWFzb25zIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInJlYXNvbnMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdGltZVN0YW1wOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInRpbWVTdGFtcCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJ0aW1lU3RhbXAiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBGb250ID0geGZhbGliLnNjcmlwdC5kb20uRm9udCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJmb250IgogICAgfSk7CgogICAgRm9udC5kZWZpbmVQcm9wcyh7CiAgICAgICAgYmFzZWxpbmVTaGlmdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImJhc2VsaW5lU2hpZnQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJiYXNlbGluZVNoaWZ0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGZvbnRIb3Jpem9udGFsU2NhbGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJmb250SG9yaXpvbnRhbFNjYWxlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZm9udEhvcml6b250YWxTY2FsZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBmb250VmVydGljYWxTY2FsZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImZvbnRWZXJ0aWNhbFNjYWxlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZm9udFZlcnRpY2FsU2NhbGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAga2VybmluZ01vZGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJrZXJuaW5nTW9kZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImtlcm5pbmdNb2RlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGxldHRlclNwYWNpbmc6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJsZXR0ZXJTcGFjaW5nIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGV0dGVyU3BhY2luZyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBsaW5lVGhyb3VnaDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImxpbmVUaHJvdWdoIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGluZVRocm91Z2giKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbGluZVRocm91Z2hQZXJpb2Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJsaW5lVGhyb3VnaFBlcmlvZCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImxpbmVUaHJvdWdoUGVyaW9kIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG92ZXJsaW5lOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgib3ZlcmxpbmUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJvdmVybGluZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBvdmVybGluZVBlcmlvZDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm92ZXJsaW5lUGVyaW9kIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAib3ZlcmxpbmVQZXJpb2QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcG9zdHVyZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInBvc3R1cmUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwb3N0dXJlIik7CiAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQsCiAgICAgICAgICAgICAgICAgICAgdGhpcywgImZvbnQucG9zdHVyZSIsIHZhbHVlLCBudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsIGV2bnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzaXplOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic2l6ZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInNpemUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdHlwZWZhY2U6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlZmFjZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInR5cGVmYWNlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHVuZGVybGluZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInVuZGVybGluZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInVuZGVybGluZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB1bmRlcmxpbmVQZXJpb2Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ1bmRlcmxpbmVQZXJpb2QiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ1bmRlcmxpbmVQZXJpb2QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgd2VpZ2h0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgid2VpZ2h0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAid2VpZ2h0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGZpbGw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZmlsbCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJmaWxsIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgRm9ybWF0ID0geGZhbGliLnNjcmlwdC5kb20uRm9ybWF0ID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImZvcm1hdCIKICAgIH0pOwoKICAgIEZvcm1hdC5kZWZpbmVQcm9wcyh7CiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcGljdHVyZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJwaWN0dXJlIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInBpY3R1cmUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBIYW5kbGVyID0geGZhbGliLnNjcmlwdC5kb20uSGFuZGxlciA9IHhmYWxpYi5zY3JpcHQuR2VuZXJpY1RleHQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiaGFuZGxlciIKICAgIH0pOwoKICAgIEhhbmRsZXIuZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEh5cGhlbmF0aW9uID0geGZhbGliLnNjcmlwdC5kb20uSHlwaGVuYXRpb24gPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6Imh5cGhlbmF0aW9uIgogICAgfSk7CgogICAgSHlwaGVuYXRpb24uZGVmaW5lUHJvcHMoewogICAgICAgIGV4Y2x1ZGVBbGxDYXBzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZXhjbHVkZUFsbENhcHMiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJleGNsdWRlQWxsQ2FwcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleGNsdWRlSW5pdGlhbENhcDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImV4Y2x1ZGVJbml0aWFsQ2FwIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZXhjbHVkZUluaXRpYWxDYXAiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgaHlwaGVuYXRlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiaHlwaGVuYXRlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaHlwaGVuYXRlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGxhZGRlckNvdW50OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGFkZGVyQ291bnQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJsYWRkZXJDb3VudCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBwdXNoQ2hhcmFjdGVyQ291bnQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJwdXNoQ2hhcmFjdGVyQ291bnQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwdXNoQ2hhcmFjdGVyQ291bnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVtYWluQ2hhcmFjdGVyQ291bnQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyZW1haW5DaGFyYWN0ZXJDb3VudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJlbWFpbkNoYXJhY3RlckNvdW50Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHdvcmRDaGFyYWN0ZXJDb3VudDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIndvcmRDaGFyYWN0ZXJDb3VudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIndvcmRDaGFyYWN0ZXJDb3VudCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEltYWdlRWRpdCA9IHhmYWxpYi5zY3JpcHQuZG9tLkltYWdlRWRpdCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJpbWFnZUVkaXQiCiAgICB9KTsKCiAgICBJbWFnZUVkaXQuZGVmaW5lUHJvcHMoewogICAgICAgIGRhdGE6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJkYXRhIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZGF0YSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBib3JkZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiYm9yZGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImJvcmRlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYXJnaW46ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFyZ2luIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgIm1hcmdpbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIElzc3VlcnMgPSB4ZmFsaWIuc2NyaXB0LmRvbS5Jc3N1ZXJzID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6Imlzc3VlcnMiCiAgICB9KTsKCiAgICBJc3N1ZXJzLmRlZmluZVByb3BzKHsKICAgICAgICAidHlwZSI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBJdGVtcyA9IHhmYWxpYi5zY3JpcHQuZG9tLkl0ZW1zID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgX2RlZmF1bHRzOiB7CiAgICAgICAgICAgICJzYXZlIjogIjAiCiAgICAgICAgfSwKCiAgICAgICAgbXNDbGFzc05hbWU6ICJpdGVtcyIsCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBJdGVtcy5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBhbHdheXMgcmV0dXJuIDxpdGVtcz4gLSBidWcjMzYyMTg5OAogICAgICAgICAgICAgKiBJbiBjYXNlIG9mIGZpbmFsIHN1Ym1pc3Npb24sIGRvbid0IHNlbmQgSXRlbXMKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJldHVybiBkaWZmX2xldmVsID09PSAyID8gewogICAgICAgICAgICAgICAgImNoYW5nZWQiOiBmYWxzZSwKICAgICAgICAgICAgICAgIGpzb25EaWZmZXJlbmNlOiB7fQogICAgICAgICAgICB9IDogewogICAgICAgICAgICAgICAgImNoYW5nZWQiOiB0cnVlLAogICAgICAgICAgICAgICAganNvbkRpZmZlcmVuY2U6IHRoaXMuanNvbk1vZGVsCiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgIH0pOwoKICAgIEl0ZW1zLmRlZmluZVByb3BzKHsKICAgICAgICAic2F2ZSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInNhdmUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKICAgIEl0ZW1zLmFkZE1peGlucyhbCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRQcmVzZW5jZQogICAgXSk7Cn0pKF8sIHhmYWxpYik7CgooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEtlZXAgPSB4ZmFsaWIuc2NyaXB0LmRvbS5LZWVwID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImtlZXAiCiAgICB9KTsKCiAgICBLZWVwLmRlZmluZVByb3BzKHsKICAgICAgICBpbnRhY3Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJpbnRhY3QiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJpbnRhY3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbmV4dDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm5leHQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJuZXh0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHByZXZpb3VzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicHJldmlvdXMiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwcmV2aW91cyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEtleVVzYWdlID0geGZhbGliLnNjcmlwdC5kb20uS2V5VXNhZ2UgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImtleVVzYWdlIgogICAgfSk7CgogICAgS2V5VXNhZ2UuZGVmaW5lUHJvcHMoewogICAgICAgIGNybFNpZ246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJjcmxTaWduIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiY3JsU2lnbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBkYXRhRW5jaXBoZXJtZW50OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZGF0YUVuY2lwaGVybWVudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImRhdGFFbmNpcGhlcm1lbnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZGVjaXBoZXJPbmx5OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZGVjaXBoZXJPbmx5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZGVjaXBoZXJPbmx5Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGRpZ2l0YWxTaWduYXR1cmU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJkaWdpdGFsU2lnbmF0dXJlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZGlnaXRhbFNpZ25hdHVyZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBlbmNpcGhlck9ubHk6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJlbmNpcGhlck9ubHkiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJlbmNpcGhlck9ubHkiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAga2V5QWdyZWVtZW50OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgia2V5QWdyZWVtZW50Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAia2V5QWdyZWVtZW50Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGtleUNlcnRTaWduOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgia2V5Q2VydFNpZ24iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJrZXlDZXJ0U2lnbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBrZXlFbmNpcGhlcm1lbnQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJrZXlFbmNpcGhlcm1lbnQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJrZXlFbmNpcGhlcm1lbnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbm9uUmVwdWRpYXRpb246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJub25SZXB1ZGlhdGlvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm5vblJlcHVkaWF0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIExpbmVhciA9IHhmYWxpYi5zY3JpcHQuZG9tLkxpbmVhciA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJsaW5lYXIiCiAgICB9KTsKCiAgICBMaW5lYXIuZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb2xvcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjb2xvciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJjb2xvciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIExvY2tEb2N1bWVudCA9IHhmYWxpYi5zY3JpcHQuZG9tLkxvY2tEb2N1bWVudCA9IHhmYWxpYi5zY3JpcHQuR2VuZXJpY1RleHQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToibG9ja0RvY3VtZW50IgogICAgfSk7CgogICAgTG9ja0RvY3VtZW50LmRlZmluZVByb3BzKHsKICAgICAgICB0eXBlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidHlwZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInR5cGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBNYW5pZmVzdCA9IHhmYWxpYi5zY3JpcHQuZG9tLk1hbmlmZXN0ID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6Im1hbmlmZXN0IgogICAgfSk7CgogICAgTWFuaWZlc3QuZGVmaW5lUHJvcHMoewogICAgICAgIGFjdGlvbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImFjdGlvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImFjdGlvbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBNYXJnaW4gPSB4ZmFsaWIuc2NyaXB0LmRvbS5NYXJnaW4gPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToibWFyZ2luIgogICAgfSk7CgogICAgTWFyZ2luLmRlZmluZVByb3BzKHsKICAgICAgICBib3R0b21JbnNldDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImJvdHRvbUluc2V0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiYm90dG9tSW5zZXQiKTsKICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICB0aGlzLCJib3R0b21JbnNldCIsdmFsdWUsIG51bGwpOwogICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbGVmdEluc2V0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGVmdEluc2V0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGVmdEluc2V0Iik7CiAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQsCiAgICAgICAgICAgICAgICAgICAgdGhpcywibGVmdEluc2V0Iix2YWx1ZSwgbnVsbCk7CiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICByaWdodEluc2V0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicmlnaHRJbnNldCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJpZ2h0SW5zZXQiKTsKICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICB0aGlzLCJyaWdodEluc2V0Iix2YWx1ZSwgbnVsbCk7CiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0b3BJbnNldDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRvcEluc2V0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidG9wSW5zZXQiKTsKICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICB0aGlzLCJ0b3BJbnNldCIsdmFsdWUsIG51bGwpOwogICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBNZHAgPSB4ZmFsaWIuc2NyaXB0LmRvbS5NZHAgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6Im1kcCIKICAgIH0pOwoKICAgIE1kcC5kZWZpbmVQcm9wcyh7CiAgICAgICAgcGVybWlzc2lvbnM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJwZXJtaXNzaW9ucyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInBlcm1pc3Npb25zIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHNpZ25hdHVyZVR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJzaWduYXR1cmVUeXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic2lnbmF0dXJlVHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIE1lZGl1bSA9IHhmYWxpYi5zY3JpcHQuZG9tLk1lZGl1bSA9IHhmYWxpYi5zY3JpcHQuR2VuZXJpY1RleHQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToibWVkaXVtIgogICAgfSk7CgogICAgTWVkaXVtLmRlZmluZVByb3BzKHsKICAgICAgICBpbWFnaW5nQkJveDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImltYWdpbmdCQm94Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaW1hZ2luZ0JCb3giKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImxvbmciOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibG9uZyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImxvbmciKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgb3JpZW50YXRpb246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJvcmllbnRhdGlvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm9yaWVudGF0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzaG9ydCI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJzaG9ydCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInNob3J0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHN0b2NrOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic3RvY2siKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJzdG9jayIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0cmF5SW46ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0cmF5SW4iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0cmF5SW4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdHJheU91dDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRyYXlPdXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0cmF5T3V0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgTWVzc2FnZSA9IHhmYWxpYi5zY3JpcHQuZG9tLk1lc3NhZ2UgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToibWVzc2FnZSIKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBOdW1lcmljRWRpdCA9IHhmYWxpYi5zY3JpcHQuZG9tLk51bWVyaWNFZGl0ID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6Im51bWVyaWNFZGl0IgogICAgfSk7CgogICAgTnVtZXJpY0VkaXQuZGVmaW5lUHJvcHMoewogICAgICAgIGhTY3JvbGxQb2xpY3k6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJoU2Nyb2xsUG9saWN5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaFNjcm9sbFBvbGljeSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBib3JkZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiYm9yZGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImJvcmRlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb21iOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImNvbWIiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY29tYiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYXJnaW46ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFyZ2luIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgIm1hcmdpbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIE9jY3VyID0geGZhbGliLnNjcmlwdC5kb20uT2NjdXIgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToib2NjdXIiLAogICAgICAgIHBsYXlKc29uIDogZnVuY3Rpb24ocEpzb25Nb2RlbCkgewoKICAgICAgICB9CgogICAgfSk7CgogICAgT2NjdXIuZGVmaW5lUHJvcHMoewogICAgICAgIGluaXRpYWw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJpbml0aWFsIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaW5pdGlhbCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYXg6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJtYXgiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJtYXgiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbWluOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibWluIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibWluIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHNjcmlwdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJzY3JpcHQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAic2NyaXB0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgT2lkID0geGZhbGliLnNjcmlwdC5kb20uT2lkID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJvaWQiCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgT2lkcyA9IHhmYWxpYi5zY3JpcHQuZG9tLk9pZHMgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToib2lkcyIKICAgIH0pOwoKICAgIE9pZHMuZGVmaW5lUHJvcHMoewogICAgICAgICJ0eXBlIjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0eXBlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIE92ZXJmbG93ID0geGZhbGliLnNjcmlwdC5kb20uT3ZlcmZsb3cgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6Im92ZXJmbG93IgogICAgfSk7CgogICAgT3ZlcmZsb3cuZGVmaW5lUHJvcHMoewogICAgICAgIGxlYWRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImxlYWRlciIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImxlYWRlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0YXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0YXJnZXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdHJhaWxlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRyYWlsZXIiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0cmFpbGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgUGFyYSA9IHhmYWxpYi5zY3JpcHQuZG9tLlBhcmEgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToicGFyYSIKICAgIH0pOwoKICAgIFBhcmEuZGVmaW5lUHJvcHMoewogICAgICAgIGhBbGlnbiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiaEFsaWduIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaEFsaWduIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBsaW5lSGVpZ2h0IDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJsaW5lSGVpZ2h0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGluZUhlaWdodCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbWFyZ2luTGVmdCA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibWFyZ2luTGVmdCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm1hcmdpbkxlZnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIG1hcmdpblJpZ2h0IDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJtYXJnaW5SaWdodCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm1hcmdpblJpZ2h0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBvcnBoYW5zIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJvcnBoYW5zIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAib3JwaGFucyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcHJlc2VydmUgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInByZXNlcnZlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicHJlc2VydmUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHJhZGl4T2Zmc2V0IDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyYWRpeE9mZnNldCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJhZGl4T2Zmc2V0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBzcGFjZUFib3ZlIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJzcGFjZUFib3ZlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic3BhY2VBYm92ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc3BhY2VCZWxvdyA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic3BhY2VCZWxvdyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInNwYWNlQmVsb3ciKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHRhYkRlZmF1bHQgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRhYkRlZmF1bHQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsdWUpewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YWJEZWZhdWx0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICB0YWJTdG9wcyA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidGFiU3RvcHMiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsdWUpewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YWJTdG9wcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgdGV4dEluZGVudCA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidGV4dEluZGVudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInRleHRJbmRlbnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHZBbGlnbiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidkFsaWduIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidkFsaWduIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICB3aWRvd3MgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIndpZG93cyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIndpZG93cyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgd29yZFNwYWNpbmdNYXhpbXVtIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ3b3JkU3BhY2luZ01heGltdW0iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsdWUpewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ3b3JkU3BhY2luZ01heGltdW0iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHdvcmRTcGFjaW5nTWluaW11bSA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgid29yZFNwYWNpbmdNaW5pbXVtIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAid29yZFNwYWNpbmdNaW5pbXVtIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICB3b3JkU3BhY2luZ09wdGltdW0gOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIndvcmRTcGFjaW5nT3B0aW11bSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIndvcmRTcGFjaW5nT3B0aW11bSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLHhmYWxpYik7CgoKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBQYXNzd29yZEVkaXQgPSB4ZmFsaWIuc2NyaXB0LmRvbS5QYXNzd29yZEVkaXQgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToicGFzc3dvcmRFZGl0IgogICAgfSk7CgogICAgUGFzc3dvcmRFZGl0LmRlZmluZVByb3BzKHsKICAgICAgICBoU2Nyb2xsUG9saWN5OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiaFNjcm9sbFBvbGljeSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImhTY3JvbGxQb2xpY3kiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcGFzc3dvcmRDaGFyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicGFzc3dvcmRDaGFyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicGFzc3dvcmRDaGFyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGJvcmRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJib3JkZXIiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiYm9yZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG1hcmdpbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJtYXJnaW4iLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWFyZ2luIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgUGF0dGVybiA9IHhmYWxpYi5zY3JpcHQuZG9tLlBhdHRlcm4gPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToicGF0dGVybiIKICAgIH0pOwoKICAgIFBhdHRlcm4uZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb2xvcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjb2xvciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJjb2xvciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFBpY3R1cmUgPSB4ZmFsaWIuc2NyaXB0LmRvbS5QaWN0dXJlID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJwaWN0dXJlIgogICAgfSk7CgogICAgUGljdHVyZS5kZWZpbmVQcm9wcyh7CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgUmFkaWFsID0geGZhbGliLnNjcmlwdC5kb20uUmFkaWFsID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InJhZGlhbCIKICAgIH0pOwoKICAgIFJhZGlhbC5kZWZpbmVQcm9wcyh7CiAgICAgICAgdHlwZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0eXBlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGNvbG9yOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImNvbG9yIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImNvbG9yIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgUmVhc29uID0geGZhbGliLnNjcmlwdC5kb20uUmVhc29uID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJyZWFzb24iCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgUmVhc29ucyA9IHhmYWxpYi5zY3JpcHQuZG9tLlJlYXNvbnMgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToicmVhc29ucyIKICAgIH0pOwoKICAgIFJlYXNvbnMuZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBSZWYgPSB4ZmFsaWIuc2NyaXB0LmRvbS5SZWYgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InJlZiIKICAgIH0pOwoKICAgIFJlZi5kZWZpbmVQcm9wcyh7CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgUmVuZGVyQXMgPSB4ZmFsaWIuc2NyaXB0LmRvbS5SZW5kZXJBcyA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJyZW5kZXJBcyIKICAgIH0pOwoKICAgIFJlbmRlckFzLmRlZmluZVByb3BzKHsKICAgICAgICBBUElWZXJzaW9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiQVBJVmVyc2lvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIkFQSVZlcnNpb24iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgc3ZnOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInN2ZyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzdmciKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTY3JpcHQgPSB4ZmFsaWIuc2NyaXB0LmRvbS5TY3JpcHQgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InNjcmlwdCIKICAgIH0pOwoKICAgIFNjcmlwdC5kZWZpbmVQcm9wcyh7CiAgICAgICAgYmluZGluZzp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImJpbmRpbmciKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJiaW5kaW5nIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGNvbnRlbnRUeXBlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiY29udGVudFR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJjb250ZW50VHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBydW5BdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJ1bkF0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicnVuQXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgc3RhdGVsZXNzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic3RhdGVsZXNzIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic3RhdGVsZXNzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIFNjcmlwdE9iamVjdCA9IHhmYWxpYi5zY3JpcHQuZG9tLlNjcmlwdE9iamVjdCA9IHhmYWxpYi5zY3JpcHQuZG9tLlNjcmlwdC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiAic2NyaXB0IiwKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgU2NyaXB0T2JqZWN0Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX3NjcmlwdEluaXRpYWxpemVkID0gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgX2dldE5ha2VkVGhpcyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKCF0aGlzLl9zY3JpcHRJbml0aWFsaXplZCl7CiAgICAgICAgICAgICAgICBpZih0aGlzLnZhbHVlKXsKICAgICAgICAgICAgICAgICAgICB0cnl7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvbGRTY29wZSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMucGFyZW50LnBhcmVudCBpbnN0YW5jZW9mIHhmYWxpYi5zY3JpcHQuRXZlbnRDb250YWluZXJOb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRTY29wZSA9IHRoaXMucGFyZW50LnBhcmVudC5fY3JlYXRlTmFrZWRSZWZlcmVuY2VzU2NvcGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5fcHVzaENvbnRleHROb2RlKHRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICB3aXRoKHRoaXMucGFyZW50LnBhcmVudCkgeyAvLyB0aGUgcGFyZW50IHN1YmZvcm0gb2Ygc2NyaXB0IG9iai4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpdGgoeGZhbGliLnJ1bnRpbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1RPRE86IHBvc3NpYmxlIHhzcyBhdHRhY2sKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZXZhbCgiKCIrdGhpcy52YWx1ZSsiKSIpKS5hcHBseSh0aGlzLnBhcmVudC5wYXJlbnQsW3RoaXNdKTsgLy8gc3ViZm9ybSAtPiBzZWxmLCB0aGlzIC0+IGJhc2VvYmogLyBzY3JpcHQgT2JqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGNhdGNoKGV4Y2VwdGlvbil7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzb20gPSB0aGlzLl94ZmEoKS5tb0NvbnRleHROb2Rlc1swXSA/IHRoaXMuX3hmYSgpLm1vQ29udGV4dE5vZGVzWzBdLnNvbUV4cHJlc3Npb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogIiIKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuTG9nZ2VyLmVycm9yKCJ4ZmEiLCB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMTUiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2V4Y2VwdGlvbi5tZXNzYWdlLCB0aGlzLm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5ldmVudC5uYW1lLCBzb21dKQogICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKG9sZFNjb3BlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFyZW50LnBhcmVudC5fcmVzZXROYWtlZFJlZmVyZW5jZXNTY29wZShvbGRTY29wZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuX3BvcENvbnRleHROb2RlKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5fc2NyaXB0SW5pdGlhbGl6ZWQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICB9KTsKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTZXRQcm9wZXJ0eSA9IHhmYWxpYi5zY3JpcHQuZG9tLlNldFByb3BlcnR5ID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJzZXRQcm9wZXJ0eSIKICAgIH0pOwoKICAgIFNldFByb3BlcnR5LmRlZmluZVByb3BzKHsKICAgICAgICBjb25uZWN0aW9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiY29ubmVjdGlvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImNvbm5lY3Rpb24iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVmOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicmVmIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicmVmIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRhcmdldDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRhcmdldCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInRhcmdldCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFNpZ25hdHVyZSA9IHhmYWxpYi5zY3JpcHQuZG9tLlNpZ25hdHVyZSA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJzaWduYXR1cmUiCiAgICB9KTsKCiAgICBTaWduYXR1cmUuZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBib3JkZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiYm9yZGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImJvcmRlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBmaWx0ZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZmlsdGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImZpbHRlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYW5pZmVzdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJtYW5pZmVzdCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJtYW5pZmVzdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYXJnaW46ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFyZ2luIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgIm1hcmdpbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFNpZ25EYXRhID0geGZhbGliLnNjcmlwdC5kb20uU2lnbkRhdGEgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToic2lnbkRhdGEiCiAgICB9KTsKCiAgICBTaWduRGF0YS5kZWZpbmVQcm9wcyh7CiAgICAgICAgb3BlcmF0aW9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgib3BlcmF0aW9uIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAib3BlcmF0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlZjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJlZiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJlZiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0YXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0YXJnZXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZmlsdGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImZpbHRlciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJmaWx0ZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbWFuaWZlc3Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFuaWZlc3QiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWFuaWZlc3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTaWduaW5nID0geGZhbGliLnNjcmlwdC5kb20uU2lnbmluZyA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJzaWduaW5nIgogICAgfSk7CgogICAgU2lnbmluZy5kZWZpbmVQcm9wcyh7CiAgICAgICAgdHlwZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0eXBlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFNvbGlkID0geGZhbGliLnNjcmlwdC5kb20uU29saWQgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToic29saWQiCiAgICB9KTsKCiAgICBTb2xpZC5kZWZpbmVQcm9wcyh7CiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTcGVhayA9IHhmYWxpYi5zY3JpcHQuZG9tLlNwZWFrID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJzcGVhayIKICAgIH0pOwoKICAgIFNwZWFrLmRlZmluZVByb3BzKHsKICAgICAgICBkaXNhYmxlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZGlzYWJsZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImRpc2FibGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcHJpb3JpdHk6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJwcmlvcml0eSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInByaW9yaXR5Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJpZDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJpZCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJpZCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFN0aXBwbGUgPSB4ZmFsaWIuc2NyaXB0LmRvbS5TdGlwcGxlID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InN0aXBwbGUiCiAgICB9KTsKCiAgICBTdGlwcGxlLmRlZmluZVByb3BzKHsKICAgICAgICByYXRlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicmF0ZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJhdGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY29sb3I6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiY29sb3IiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY29sb3IiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTdWJqZWN0RE4gPSB4ZmFsaWIuc2NyaXB0LmRvbS5TdWJqZWN0RE4gPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InN1YmplY3RETiIKICAgIH0pOwoKICAgIFN1YmplY3RETi5kZWZpbmVQcm9wcyh7CiAgICAgICAgZGVsaW1pdGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZGVsaW1pdGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZGVsaW1pdGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgU3ViamVjdEROcyA9IHhmYWxpYi5zY3JpcHQuZG9tLlN1YmplY3RETnMgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToic3ViamVjdEROcyIKICAgIH0pOwoKICAgIFN1YmplY3RETnMuZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTdWJtaXQgPSB4ZmFsaWIuc2NyaXB0LmRvbS5TdWJtaXQgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToic3VibWl0IgogICAgfSk7CgogICAgU3VibWl0LmRlZmluZVByb3BzKHsKICAgICAgICBlbWJlZFBERjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImVtYmVkUERGIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZW1iZWRQREYiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZm9ybWF0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZm9ybWF0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZm9ybWF0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRhcmdldDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRhcmdldCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInRhcmdldCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0ZXh0RW5jb2Rpbmc6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0ZXh0RW5jb2RpbmciKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0ZXh0RW5jb2RpbmciKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgeGRwQ29udGVudDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInhkcENvbnRlbnQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ4ZHBDb250ZW50Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGVuY3J5cHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZW5jcnlwdCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJlbmNyeXB0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTdmcgPSB4ZmFsaWIuc2NyaXB0LmRvbS5TdmcgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InN2ZyIKICAgIH0pOwoKICAgIFN2Zy5kZWZpbmVQcm9wcyh7CiAgICAgICAgaGVpZ2h0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiaGVpZ2h0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaGVpZ2h0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHZpZXdCb3g6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ2aWV3Qm94Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidmlld0JveCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB3aWR0aDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIndpZHRoIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAid2lkdGgiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBUZXh0RWRpdCA9IHhmYWxpYi5zY3JpcHQuZG9tLlRleHRFZGl0ID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InRleHRFZGl0IgogICAgfSk7CgogICAgVGV4dEVkaXQuZGVmaW5lUHJvcHMoewogICAgICAgIGFsbG93UmljaFRleHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJhbGxvd1JpY2hUZXh0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiYWxsb3dSaWNoVGV4dCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBoU2Nyb2xsUG9saWN5OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiaFNjcm9sbFBvbGljeSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImhTY3JvbGxQb2xpY3kiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbXVsdGlMaW5lOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibXVsdGlMaW5lIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibXVsdGlMaW5lIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHZTY3JvbGxQb2xpY3k6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ2U2Nyb2xsUG9saWN5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidlNjcm9sbFBvbGljeSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBib3JkZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiYm9yZGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImJvcmRlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb21iOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImNvbWIiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY29tYiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYXJnaW46ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFyZ2luIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgIm1hcmdpbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFRleHROb2RlID0geGZhbGliLnNjcmlwdC5UZXh0Tm9kZSA9IHhmYWxpYi5zY3JpcHQuT2JqZWN0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InRleHROb2RlIgogICAgfSk7CgogICAgVGV4dE5vZGUuZGVmaW5lUHJvcHMoewoKICAgIH0pCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgVGltZVN0YW1wID0geGZhbGliLnNjcmlwdC5kb20uVGltZVN0YW1wID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJ0aW1lU3RhbXAiCiAgICB9KTsKCiAgICBUaW1lU3RhbXAuZGVmaW5lUHJvcHMoewogICAgICAgIHNlcnZlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInNlcnZlciIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInNlcnZlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0eXBlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidHlwZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInR5cGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBUb29sVGlwID0geGZhbGliLnNjcmlwdC5kb20uVG9vbFRpcCA9IHhmYWxpYi5zY3JpcHQuR2VuZXJpY1RleHQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToidG9vbFRpcCIKICAgIH0pOwoKICAgIFRvb2xUaXAuZGVmaW5lUHJvcHMoewogICAgICAgIHJpZDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJpZCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJpZCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFRyYXZlcnNhbCA9IHhmYWxpYi5zY3JpcHQuZG9tLlRyYXZlcnNhbCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJ0cmF2ZXJzYWwiCiAgICB9KTsKCiAgICBUcmF2ZXJzYWwuZGVmaW5lUHJvcHMoewogICAgICAgIHBhc3NUaHJvdWdoOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicGFzc1Rocm91Z2giKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwYXNzVGhyb3VnaCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBUcmF2ZXJzZSA9IHhmYWxpYi5zY3JpcHQuZG9tLlRyYXZlcnNlID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InRyYXZlcnNlIgogICAgfSk7CgogICAgVHJhdmVyc2UuZGVmaW5lUHJvcHMoewogICAgICAgIGRlbGVnYXRlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZGVsZWdhdGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJkZWxlZ2F0ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBvcGVyYXRpb246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJvcGVyYXRpb24iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJvcGVyYXRpb24iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVmOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicmVmIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicmVmIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHNjcmlwdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJzY3JpcHQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAic2NyaXB0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgVWkgPSB4ZmFsaWIuc2NyaXB0LmRvbS5VaSA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJ1aSIsCgogICAgICAgIC8vIFRPRE8gOiByZW1vdmUgdGhlc2Ugb25jZSBTaGFyYWQgbWVyZ2VzIGNoYW5nZXMgZnJvbSBITVJDCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIFVpLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tb0NoaWxkTm9kZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIHZhciBvTm9kZSA9IHRoaXMubW9DaGlsZE5vZGVzW2ldOwogICAgICAgICAgICAgICAgb05vZGUub24oeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkRPTV9DSEFOR0VELHRoaXMpIDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUV2ZW50OiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsZXZudCk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldE9uZU9mQ2hpbGQgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgb25lQ2hpbGQgPSBVaS5fc3VwZXIuX2dldE9uZU9mQ2hpbGQuY2FsbCh0aGlzKTsKICAgICAgICAgICAgaWYob25lQ2hpbGQpCiAgICAgICAgICAgICAgICByZXR1cm4gb25lQ2hpbGQ7CgogICAgICAgICAgICB2YXIgY2hpbGRUeXBlID0gInRleHRFZGl0IjsKICAgICAgICAgICAgaWYodGhpcy5wYXJlbnQpewogICAgICAgICAgICAgICAgdmFyIHZhbHVlQ2hpbGQgPSB0aGlzLnBhcmVudC52YWx1ZS5vbmVPZkNoaWxkIHx8IHtjbGFzc05hbWUgOiAidGV4dCJ9OwogICAgICAgICAgICAgICAgc3dpdGNoICh2YWx1ZUNoaWxkLmNsYXNzTmFtZSl7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiZGF0ZVRpbWUiIDoKICAgICAgICAgICAgICAgICAgICBjYXNlICJkYXRlIiA6CiAgICAgICAgICAgICAgICAgICAgY2FzZSAidGltZSIgOgogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFR5cGUgPSAiZGF0ZVRpbWVFZGl0IjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiZGVjaW1hbCIgOgogICAgICAgICAgICAgICAgICAgIGNhc2UgImZsb2F0IiA6CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiaW50ZWdlciIgOgogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFR5cGUgPSAibnVtZXJpY0VkaXQiOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJib29sZWFuIiA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkVHlwZSA9ICJjaGVja0J1dHRvbiI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgInRleHQiIDoKICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRUeXBlID0gInRleHRFZGl0IjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiaW1hZ2UiIDoKICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRUeXBlID0gImltYWdlRWRpdCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXREZWZhdWx0RWxlbWVudChjaGlsZFR5cGUsIDAsIHRydWUpOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBVaS5kZWZpbmVQcm9wcyh7CiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcGljdHVyZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJwaWN0dXJlIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInBpY3R1cmUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgYmFyY29kZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJiYXJjb2RlIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImJhcmNvZGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgYnV0dG9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImJ1dHRvbiIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJidXR0b24iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY2hlY2tCdXR0b246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiY2hlY2tCdXR0b24iLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY2hlY2tCdXR0b24iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY2hvaWNlTGlzdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjaG9pY2VMaXN0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImNob2ljZUxpc3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZGF0ZVRpbWVFZGl0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImRhdGVUaW1lRWRpdCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJkYXRlVGltZUVkaXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZGVmYXVsdFVpOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImRlZmF1bHRVaSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJkZWZhdWx0VWkiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXhPYmplY3Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXhPYmplY3QiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXhPYmplY3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgaW1hZ2VFZGl0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImltYWdlRWRpdCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJpbWFnZUVkaXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbnVtZXJpY0VkaXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibnVtZXJpY0VkaXQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibnVtZXJpY0VkaXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcGFzc3dvcmRFZGl0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInBhc3N3b3JkRWRpdCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJwYXNzd29yZEVkaXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgc2lnbmF0dXJlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInNpZ25hdHVyZSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzaWduYXR1cmUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdGV4dEVkaXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgidGV4dEVkaXQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAidGV4dEVkaXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBWYWxpZGF0ZSA9IHhmYWxpYi5zY3JpcHQuZG9tLlZhbGlkYXRlID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InZhbGlkYXRlIgogICAgfSk7CgogICAgVmFsaWRhdGUuZGVmaW5lUHJvcHMoewogICAgICAgIGRpc2FibGVBbGw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJkaXNhYmxlQWxsIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZGlzYWJsZUFsbCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBmb3JtYXRUZXN0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZm9ybWF0VGVzdCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImZvcm1hdFRlc3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbnVsbFRlc3Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJudWxsVGVzdCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB2YXIgb2xkVmFsdWUgPSB0aGlzLm51bGxUZXN0OwogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJudWxsVGVzdCIpOwogICAgICAgICAgICAgICAgdmFyIGV2ZW50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwgdGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgJ251bGxUZXN0Jywgb2xkVmFsdWUsIHZhbHVlKTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldmVudC5uYW1lLCBldmVudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHNjcmlwdFRlc3Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJzY3JpcHRUZXN0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic2NyaXB0VGVzdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtZXNzYWdlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoIm1lc3NhZ2UiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWVzc2FnZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBwaWN0dXJlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInBpY3R1cmUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAicGljdHVyZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzY3JpcHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic2NyaXB0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInNjcmlwdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFZhbHVlID0geGZhbGliLnNjcmlwdC5kb20uVmFsdWUgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZTogInZhbHVlIiwKCiAgICAgICAgX2dldE9uZU9mQ2hpbGQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIG9uZUNoaWxkID0gVmFsdWUuX3N1cGVyLl9nZXRPbmVPZkNoaWxkLmNhbGwodGhpcyk7CiAgICAgICAgICAgIGlmIChvbmVDaGlsZCkKICAgICAgICAgICAgICAgIHJldHVybiBvbmVDaGlsZDsKCiAgICAgICAgICAgIHZhciBjaGlsZFR5cGUgPSAidGV4dCI7CiAgICAgICAgICAgIGlmICh0aGlzLnBhcmVudCAmJiAodGhpcy5wYXJlbnQuY2xhc3NOYW1lID09ICJmaWVsZCIgfHwgdGhpcy5wYXJlbnQuY2xhc3NOYW1lID09ICJkcmF3IikpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBCdWc6MzYwMDI0NgogICAgICAgICAgICAgICAgICogV2hlbiBjaGVja2luZyB1aSBvbmVPZkNoaWxkLCBkbyBub3QgZGlyZWN0bHkgdXNlIHVpLm9uZU9mQ2hpbGQgc2luY2UgaXQgd291bGQgYWdhaW4gZmFsbGJhY2sgdG8gdmFsdWUub25PZkNoaWxkIGluIGNhc2UgdmFsdWUgaXMgYWxzbyBtaXNzaW5nLgogICAgICAgICAgICAgICAgICogU28gY2hlY2sganNvbiBpbnN0ZWFkIGFuZCBzZWUgaWYgdWkgb25lT2ZDaGlsZCBleGlzdCBhbmQgdGhlbiBvbmx5IGFjY2VzcyBpdC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgdmFyIHVpQ2hpbGQgPSB0aGlzLnhmYVV0aWwoKS5nZXRVaU9uZU9mQ2hpbGRUYWcodGhpcy5wYXJlbnQuanNvbk1vZGVsKSA/IHRoaXMucGFyZW50LnVpLm9uZU9mQ2hpbGQgOiB7Y2xhc3NOYW1lOiAidGV4dCJ9OwogICAgICAgICAgICAgICAgc3dpdGNoICh1aUNoaWxkLmNsYXNzTmFtZSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgIm51bWVyaWNFZGl0IiA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkVHlwZSA9ICJmbG9hdCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgImRhdGVUaW1lRWRpdCIgOgogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFR5cGUgPSAiZGF0ZVRpbWUiOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJpbWFnZUVkaXQiIDoKICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRUeXBlID0gImltYWdlIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAidGV4dEVkaXQiIDoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVpQ2hpbGQuYWxsb3dSaWNoVGV4dCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRUeXBlID0gImV4RGF0YSI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFR5cGUgPSAidGV4dCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiY2hvaWNlTGlzdCIgOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAodWlDaGlsZC5vcGVuID09ICJtdWx0aVNlbGVjdCIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkVHlwZSA9ICJleERhdGEiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRUeXBlID0gInRleHQiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXREZWZhdWx0RWxlbWVudChjaGlsZFR5cGUsIDAsIHRydWUpOwogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CgogICAgICAgICAgICAvL0ZvcmNlIGFsbCB0aGUgZGVzY2VuZGFudHMgb2YgdmFsdWUgaXJyZXNwZWN0aXZlIG9mIHN1Ym1pdCBjYWxsCiAgICAgICAgICAgIHZhciBkaWZmT2JqID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLnN0cmlwT3JDYWxsLmNhbGwodGhpcywgZmFsc2UsIFZhbHVlLl9zdXBlci5fY29tcHV0ZUpzb25EaWZmLCBbMF0pOwoKICAgICAgICAgICAgLy9ub3cgc3RyaXAgYWxsIHRoZSBFWFRSQSBwcm9wZXJ0aWVzIGZyb20gdmFsdWUgaWYgaXQgaXMgZmluYWwgc3VibWlzc2lvbiAgb3IgcmVzdG9yZUZvcm1TdGF0ZQogICAgICAgICAgICBpZiAoZGlmZl9sZXZlbD4wICYmIHRoaXMuZ2V0T3JFbHNlKGRpZmZPYmosICdqc29uRGlmZmVyZW5jZS5jaGlsZHJlbi5sZW5ndGgnLCAwKSkgewogICAgICAgICAgICAgICAgLy9iZWxpZXZlIG1lIHRoaXMgaXMgbm90IHRoYXQgY29zdGx5IGFzIGl0IGxvb2tzIHRvIGJlIGFzIHRoZXJlIHdpbGwgYmUgb25seSBvbmUgY2hpbGQgaW4gYWxsIHRoZSBkaWZmZXJlbmNlcyBhbmQgb25seSB0d28ga2V5cyBwZXIgY2hpbGQKICAgICAgICAgICAgICAgIHZhciBibGFja2xpc3RlZCA9IFsnZXh0cmFzJ107CiAgICAgICAgICAgICAgICBkaWZmT2JqLmpzb25EaWZmZXJlbmNlLmNoaWxkcmVuID0gXy5tYXAoZGlmZk9iai5qc29uRGlmZmVyZW5jZS5jaGlsZHJlbiwgZnVuY3Rpb24gKGNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNvcHkgPSB7fTsKICAgICAgICAgICAgICAgICAgICBfLmVhY2goT2JqZWN0LmtleXMoY2hpbGQpLCBmdW5jdGlvbiAoa2V5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghXy5jb250YWlucyhibGFja2xpc3RlZCwga2V5KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29weVtrZXldID0gY2hpbGRba2V5XTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBjb3B5OwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vTEMtODMxOSA6IGRvbid0IHNlbmQgW10gaW4gZGlmZk9iai5qc29uRGlmZmVyZW5jZS5jaGlsZHJlbgogICAgICAgICAgICBpZiAoZGlmZk9iai5qc29uRGlmZmVyZW5jZSAmJiBfLmV2ZXJ5KGRpZmZPYmouanNvbkRpZmZlcmVuY2UuY2hpbGRyZW4sIF8uaXNFbXB0eSkpIHsgIC8vIGRpZmZPYmogc2hvdWxkIGhhdmUgYSBqc29uRGlmZmVyZW5jZSBtZW1iZXIKICAgICAgICAgICAgICAgIGRpZmZPYmouanNvbkRpZmZlcmVuY2UuY2hpbGRyZW4gPSB1bmRlZmluZWQ7IC8vIHNjYXJ5IHRvIHVzZSBkZWxldGUgZHVlIHRvIHBlcmYuIGltcGFjdAogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBkaWZmT2JqOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBWYWx1ZS5kZWZpbmVQcm9wcyh7CiAgICAgICAgb3ZlcnJpZGU6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm92ZXJyaWRlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm92ZXJyaWRlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlbGV2YW50OiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyZWxldmFudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJyZWxldmFudCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBhcmM6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJhcmMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImFyYyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiYm9vbGVhbiI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJib29sZWFuIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJib29sZWFuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJkYXRlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImRhdGUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImRhdGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImRhdGVUaW1lIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImRhdGVUaW1lIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJkYXRlVGltZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiZGVjaW1hbCI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJkZWNpbWFsIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJkZWNpbWFsIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4RGF0YTogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4RGF0YSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXhEYXRhIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJmbG9hdCI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJmbG9hdCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZmxvYXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImltYWdlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImltYWdlIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJpbWFnZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiaW50ZWdlciI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJpbnRlZ2VyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJpbnRlZ2VyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGxpbmU6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJsaW5lIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJsaW5lIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlY3RhbmdsZTogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInJlY3RhbmdsZSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAicmVjdGFuZ2xlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJ0ZXh0IjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInRleHQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInRleHQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInRpbWUiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgidGltZSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAidGltZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwoKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CgogICAgdmFyIEh0bWxUZW1wbGF0ZUNhY2hlID0geGZhbGliLnZpZXcudXRpbC5IdG1sVGVtcGxhdGVDYWNoZSA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICBIdG1sVGVtcGxhdGVDYWNoZS5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLl9jYWNoZSA9IHt9OwogICAgICAgICAgICB0aGlzLl9oaWRkZW5PYmpQYWdlcyA9IFtdOwogICAgICAgIH0sCgogICAgICAgIHB1dDogZnVuY3Rpb24gKGVsKSB7CiAgICAgICAgICAgIHZhciBvY2N1ckluZGV4ID0gdGhpcy5nZXRPckVsc2UodGhpcy54ZmFVdGlsKCkuJGRhdGEoZWwsIHhmYWxpYi52aWV3LkxheW91dENvbnN0LlhGQV9NT0RFTCksIHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9NT0RFTCArICIuIiArIHhmYWxpYi52aWV3LkxheW91dENvbnN0Lk9DQ1VSX0lOREVYLCAnMCcpOwogICAgICAgICAgICBpZiAoIXRoaXMuY29udGFpbnMoZWwuaWQpIHx8IHRoaXMuX2NhY2hlW2VsLmlkXVtvY2N1ckluZGV4XSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZVtlbC5pZF0gPSB0aGlzLl9jYWNoZVtlbC5pZF0gfHwge307CiAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZVtlbC5pZF1bb2NjdXJJbmRleF0gPSBlbDsgLy8gdGhlIGNhY2hlIGlzIG5vdyAyRCwgYWdhaW5zdCBlYWNoIGVsIGlkIHN0b3JlIGEgbWFwLCBpbmRleGVkIGJ5IG9jY3VyIGluZGV4CiAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUNoaWxkcmVuKGVsKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNvbnRhaW5zIDogZnVuY3Rpb24oZWxJZCl7CiAgICAgICAgICAgIHJldHVybiAodGhpcy5fY2FjaGUuaGFzT3duUHJvcGVydHkoZWxJZCkgJiYgdGhpcy5fY2FjaGVbZWxJZF0gIT09IHVuZGVmaW5lZCk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0IDogZnVuY3Rpb24oZWxJZCwgbG9va1VwSGlkZGVuQ2FjaGUpewogICAgICAgICAgICB2YXIgJG5vZGVEaXYgPSBudWxsLAogICAgICAgICAgICAgICAgbm9kZVhmYU1vZGVsID0gbnVsbCwKICAgICAgICAgICAgICAgIHBhcnRPZmZzZXRZID0gMCwKICAgICAgICAgICAgICAgICRwYWdlRGl2LAogICAgICAgICAgICAgICAgJHNwbGl0UGFydDsKCiAgICAgICAgICAgIGZ1bmN0aW9uIHN0aXRjaE5vZGVzKCkgewogICAgICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBjb2xsZWN0IGFsbCBwYXJ0cyBvZiB0aGlzIG5vZGUgZnJvbSB2YXJpb3VzIHBhZ2VzL29jY3VycmVuY2VzIGFuZCBzdGl0Y2ggdGhlbSB0b2dldGhlci4KICAgICAgICAgICAgICAgIC8vIFdlIHN0YXJ0IGJ5IHBpY2tpbmcgKnN0aXRjaGVkKiBjaGlsZHJlbiBvZiB0aGlzIHBhcnQgYW5kIGFwcGVuZCB0aGVtIHRvIGluaXRpYWxseSBlbXB0eSAkbm9kZURpdi4gQXMgd2UgbW92ZSBvbiB0byBuZXh0CiAgICAgICAgICAgICAgICAvLyBwYXJ0LCB3ZSdsbCBwaWNrIG9ubHkgdGhvc2UgY2hpbGRyZW4gd2hpY2ggc3RhcnRzIGZyb20gdGhhdCBwYXJ0KG9jY3VySW5kZXg6MCkKICAgICAgICAgICAgICAgIC8vIFN0aXRjaGluZyB3b3VsZCByZXF1aXJlIG1vZGlmeSB0aGUgZXh0ZW50eSBvZiBjaGlsZHJlbiB0byBhZGQgY29udGVudCBoZWlnaHQgb2YgY3VycmVudCBzdGl0Y2hlZAogICAgICAgICAgICAgICAgLy8gcGFydCBhbmQgdGhlbiBtb2RpZnkgdGhlIGV4dGVudGggb2YgY3VycmVudGx5IHN0aXRjaGVkIHBhcnQgdG8gaW5jbHVkZSBoZWlnaHQgb2YgbmV3IHBhcnQuIEFsbCB0aGUgY2hpbGRyZW4gZnJvbSBuZXcgcGFydCBhcmUgY2xvbmVkLWFwcGVuZGVkIGludG8KICAgICAgICAgICAgICAgIC8vIGN1cnJlbnQgc3RpdGNoIHBhcnQuCgogICAgICAgICAgICAgICAgaWYgKCEkbm9kZURpdikgewogICAgICAgICAgICAgICAgICAgIC8vZG8gbm90IG1vZGlmeSBleGlzdGluZyBub2RlLiBXb3JrIG9uIGl0J3MgY2xvbmUgYW5kIHN0YXJ0IGJ1aWxkaW5nIGZyb20gc2NyYXRjaC4KICAgICAgICAgICAgICAgICAgICAkbm9kZURpdiA9ICRzcGxpdFBhcnQuY2xvbmUoKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZURpdi5jaGlsZHJlbigpLnJlbW92ZSgpOwogICAgICAgICAgICAgICAgICAgIG5vZGVYZmFNb2RlbCA9IHRoaXMueGZhVXRpbCgpLiRkYXRhKCRub2RlRGl2LmdldCgwKSwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIHBhcnRPZmZzZXRZID0gcGFyc2VGbG9hdChub2RlWGZhTW9kZWxbeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX01PREVMXVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5FWFRFTlRfSF0pIC0KICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VGbG9hdCh0aGlzLmdldE9yRWxzZShub2RlWGZhTW9kZWxbeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX01PREVMXVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5NQVJHSU5fVE9QXSwgMCkpIC0KICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VGbG9hdCh0aGlzLmdldE9yRWxzZShub2RlWGZhTW9kZWxbeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX01PREVMXVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5NQVJHSU5fQk9UVE9NXSwgMCkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIF8uZWFjaCgkc3BsaXRQYXJ0LmNoaWxkcmVuKCkuZ2V0KCksCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHBhcnRDaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRJZCA9IHBhcnRDaGlsZC5pZDsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkSGFzU3BsaXQgPSAodGhpcy5nZXRPckVsc2UodGhpcy54ZmFVdGlsKCkuJGRhdGEocGFydENoaWxkLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5YRkFfTU9ERUwpLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfTU9ERUwgKyAiLiIgKyB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5PQ0NVUlJFTkNFUywgMSkgPiAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzQ2hpbGRGaXJzdFNwbGl0ID0gKHRoaXMuZ2V0T3JFbHNlKHRoaXMueGZhVXRpbCgpLiRkYXRhKHBhcnRDaGlsZCwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMKSwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX01PREVMICsgIi4iICsgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuT0NDVVJfSU5ERVgsIDApID09IDApOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgJGNoaWxkQ2xvbmUgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRIYXNTcGxpdCAmJiAhaXNDaGlsZEZpcnN0U3BsaXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3BsaXQgY2hpbGQgd291bGQgYWxyZWFkeSBiZWVuIGhhbmRsZWQgd2hlbiBpdCdzIGZpcnN0IHBhcnQgd2FzIGZvdW5kLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkSGFzU3BsaXQgJiYgaXNDaGlsZEZpcnN0U3BsaXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vSWYgdGhpcyBjaGlsZCBoYXMgc3BsaXQgYW5kIGl0IGlzIGZpcnN0IHBhcnQgb2YgdGhlIGNoaWxkIHNwbGl0LCBnZXQgdGhlIGVudGlyZSBzdGl0Y2hlZCBjaGlsZC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjaGlsZENsb25lID0gJCh0aGlzLmdldChjaGlsZElkLCB0cnVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2hpbGRDbG9uZSA9ICQocGFydENoaWxkKS5jbG9uZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZFhmYU1vZGVsID0gdGhpcy54ZmFVdGlsKCkuJGRhdGEoJGNoaWxkQ2xvbmUuZ2V0KDApLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5YRkFfTU9ERUwpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRYZmFNb2RlbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbW9kaWZ5IHRoZSBleHRlbnR5IG9mIGNoaWxkIGFuZCB0aGVuIGFwcGVuZCB0aGlzIGNoaWxkIGNsb25lIHRvIGN1cnJlbnQgc3RpdGNoIHBhcnQgJG5vZGVEaXYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkWGZhTW9kZWxbeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX01PREVMXVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5FWFRFTlRfWV0gPSBwYXJ0T2Zmc2V0WSArIHBhcnNlRmxvYXQodGhpcy5nZXRPckVsc2UoY2hpbGRYZmFNb2RlbFt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfTU9ERUxdW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9ZXSwgMCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNoaWxkQ2xvbmUuYXR0cigiZGF0YS0iICsgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMLCBKU09OLnN0cmluZ2lmeShjaGlsZFhmYU1vZGVsKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJGNoaWxkQ2xvbmUuYXBwZW5kVG8oJG5vZGVEaXYpOwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgdGhpcwogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAvLyBtb2RpZnkgdGhlIGV4dGVudGggcGFydCAkbm9kZURpdgogICAgICAgICAgICAgICAgbm9kZVhmYU1vZGVsW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9NT0RFTF1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX0hdID0gcGFyc2VGbG9hdCh0aGlzLnhmYVV0aWwoKS4kZGF0YSgkc3BsaXRQYXJ0LmdldCgwKSwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMKVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfTU9ERUxdW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9IXSkgKyBwYXJ0T2Zmc2V0WTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYodGhpcy5jb250YWlucyhlbElkKSkgewogICAgICAgICAgICAgICAgaWYoXy5rZXlzKHRoaXMuX2NhY2hlW2VsSWRdKS5sZW5ndGggPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fY2FjaGVbZWxJZF1bIjAiXS5jbG9uZU5vZGUodHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBzdWJmb3JtIHdhcyBzcGxpdCBpbnRvIGRpZmZlcmVudCBwYXJ0cywgc3RpdGNoIGVhY2ggcGFydCBpbiBvcmRlciBvZiBvY2N1ckluZGV4CiAgICAgICAgICAgICAgICBmb3IgKHZhciBvY2N1ckluZGV4ID0gMDsgb2NjdXJJbmRleCA8IF8ua2V5cyh0aGlzLl9jYWNoZVtlbElkXSkubGVuZ3RoOyArK29jY3VySW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICAkc3BsaXRQYXJ0ID0gJCh0aGlzLl9jYWNoZVtlbElkXVtvY2N1ckluZGV4XSk7CiAgICAgICAgICAgICAgICAgICAgc3RpdGNoTm9kZXMuY2FsbCh0aGlzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJG5vZGVEaXYgJiYgJG5vZGVEaXYuZ2V0KDApKSB7CiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgc3RpdGNoZWQgbm9kZSBpbiBjYWNoZSwgYWZ0ZXIgbW9kaWZ5aW5nIG9jY3VycmVuY2VzIGFuZCBvY2N1ciBpbmRleCB0byBtYWtlIGl0IGFwcGVhciBhcyB1bnNwbGl0CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVbZWxJZF0gPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAgICAgbm9kZVhmYU1vZGVsW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9NT0RFTF1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuT0NDVVJSRU5DRVNdID0gIjEiOwogICAgICAgICAgICAgICAgICAgIG5vZGVYZmFNb2RlbFt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfTU9ERUxdW3hmYWxpYi52aWV3LkxheW91dENvbnN0Lk9DQ1VSX0lOREVYXSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKGxvb2tVcEhpZGRlbkNhY2hlKSB7CiAgICAgICAgICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faGlkZGVuT2JqUGFnZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICAkcGFnZURpdiA9ICQodGhpcy5faGlkZGVuT2JqUGFnZXNbaV0pOwogICAgICAgICAgICAgICAgICAgICRzcGxpdFBhcnQgPSAkcGFnZURpdi5maW5kKHRoaXMuanFJZChlbElkKSk7CiAgICAgICAgICAgICAgICAgICAgaWYoJHNwbGl0UGFydCAmJiAkc3BsaXRQYXJ0LmdldCgwKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0aXRjaE5vZGVzLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hpZGRlbk9ialBhZ2VzW2ldID0gJHBhZ2VEaXYuZ2V0KDApOyAvLyBjYWNoZSB0aGUgY29uc3RydWN0ZWQgcGFnZSBkb20gYmFjayBpbiBoaWRkZW4gb2JqZWN0cyBhcnJheSBpbiBjYXNlIHBhZ2Ugd2FzIHN0cmluZyBhcyBpdCBoYXBwZW5zIGZvciB0aGUgZmlyc3QgdGltZS4KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRub2RlRGl2ICYmICRub2RlRGl2LmdldCgwKSkgewogICAgICAgICAgICAgICAgJG5vZGVEaXYuYXR0cigiZGF0YS0iICsgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMLCBKU09OLnN0cmluZ2lmeShub2RlWGZhTW9kZWwpKTsKICAgICAgICAgICAgICAgIHRoaXMucHV0KCRub2RlRGl2LmdldCgwKSk7ICAvL3B1dCBpdCBpbiB0aGUgY2FjaGUuCiAgICAgICAgICAgICAgICByZXR1cm4gJG5vZGVEaXYuZ2V0KDApLmNsb25lTm9kZSh0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc2V0SGlkZGVuT2JqUGFnZXMgOiBmdW5jdGlvbihoaWRkZW5QYWdlcyl7CiAgICAgICAgICAgIHRoaXMuX2hpZGRlbk9ialBhZ2VzID0gaGlkZGVuUGFnZXMgfHwgW107CiAgICAgICAgfSwKCiAgICAgICAgX2NhY2hlQ2hpbGRyZW4gOiBmdW5jdGlvbihwYXJlbnQpewogICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgICQocGFyZW50KS5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIC8vY2FjaGUgeGZhIHN1YiBlbGVtZW50cyBhcyB3ZWxsLgogICAgICAgICAgICAgICAgaWYodGhhdC5nZXRPckVsc2UodGhhdC54ZmFVdGlsKCkuJGRhdGEodGhpcywgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMKSwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTk9ERV9UWVBFLCAiIikubGVuZ3RoID4gMCl7CiAgICAgICAgICAgICAgICAgICAgdGhhdC5wdXQodGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXyx4ZmFsaWIpIHsKICAgIHZhciBDb25zdGFudHMgPSB7CiAgICAgICAgWEZBX01PREVMIDogIngiLAogICAgICAgIE5PREVfVFlQRSA6ICJ0IiwKICAgICAgICBMQVlPVVRfTU9ERUw6ICJsIiwKICAgICAgICBTVUJGT1JNX0xBWU9VVDogInNsIiwKICAgICAgICBFWFRFTlRfWCA6ICJ4IiwKICAgICAgICBFWFRFTlRfWSA6ICJ5IiwKICAgICAgICBFWFRFTlRfVyA6ICJ3IiwKICAgICAgICBFWFRFTlRfSCA6ICJoIiwKICAgICAgICBFWFRFTlRfTUlOX0ggOiAibmgiLAogICAgICAgIEVYVEVOVF9NSU5fVyA6ICJudyIsCiAgICAgICAgRVhURU5UX01BWF9IIDogInhoIiwKICAgICAgICBFWFRFTlRfTUFYX1cgOiAieHciLAogICAgICAgIEVYVEVOVF9BQ1RVQUxfSCA6ICJhaCIsCiAgICAgICAgRVhURU5UX0FDVFVBTF9XIDogImF3IiwKICAgICAgICBNQVJHSU5fVE9QIDogInQiLAogICAgICAgIE1BUkdJTl9MRUZUIDogImwiLAogICAgICAgIE1BUkdJTl9CT1RUT00gOiAiYiIsCiAgICAgICAgTUFSR0lOX1JJR0hUIDogInIiLAoKICAgICAgICBCT1JERVJfVE9QIDogImJ0IiwKICAgICAgICBCT1JERVJfTEVGVCA6ICJibCIsCiAgICAgICAgQk9SREVSX0JPVFRPTSA6ICJiYiIsCiAgICAgICAgQk9SREVSX1JJR0hUIDogImJyIiwKCiAgICAgICAgQ09MX1NQQU4gOiAiYyIsCiAgICAgICAgUk9XX1NQQU4gOiAicnMiLAogICAgICAgIE9DQ1VSUkVOQ0VTIDogIm8iLAogICAgICAgIE9DQ1VSX0lOREVYOiAiaSIsCiAgICAgICAgQ09MVU1OX1dJRFRIUyA6ICJjdyIsCiAgICAgICAgUEFHRV9OVU1CRVI6ICJwbiIsCiAgICAgICAgQ0FQX1BMQUNFTUVOVCA6ICJwIiwKICAgICAgICBMQVlPVVRfTEVGVFJJR0hUVE9QQk9UVE9NIDogImxyIiwKICAgICAgICBMQVlPVVRfUklHSFRMRUZUVE9QQk9UVE9NIDogInJsIiwKICAgICAgICBMQVlPVVRfVE9QQk9UVE9NIDogInRiIiwKICAgICAgICBMQVlPVVRfVEFCTEUgOiAidCIsCiAgICAgICAgTEFZT1VUX1JPVyA6ICJyIiwKICAgICAgICBMQVlPVVRfUklHSFRMRUZUUk9XIDogInJyIiwKICAgICAgICBMQVlPVVRfREFUQVRBQkxFIDogImR0IgogICAgfTsKICAgIHhmYWxpYi52aWV3LkxheW91dENvbnN0ID0gQ29uc3RhbnRzOwp9KShfLHhmYWxpYik7CihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgdmFyIExheW91dEJhc2UgPSB4ZmFsaWIudmlldy5sYXlvdXQuTGF5b3V0QmFzZSA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudXQuQ2xhc3MucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5fbGF5b3V0TWFuYWdlciA9IHRoaXMuX3hmYVZpZXdSZWdpc3RyeSgpLmxheW91dE1hbmFnZXIoKTsKICAgICAgICAgICAgdGhpcy50YXJnZXQgPSB0aGlzLm9wdGlvbnMudGFyZ2V0OyAvL0NvbnRhaW5lclZpZXcgaW5zdGFuY2UKICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25pbmdDc3NQcm9wZXJ0eVggPSAibGVmdCI7CiAgICAgICAgICAgIHRoaXMuX3Bvc2l0aW9uaW5nQ3NzUHJvcGVydHlZID0gInRvcCI7CiAgICAgICAgfSwKCiAgICAgICAgbWVhc3VyZVNpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4geGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLm1lYXN1cmVTaXplLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIGludmFsaWRhdGVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5pbnZhbGlkYXRlU2l6ZS5hcHBseSh0aGlzLnRhcmdldCwgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICB1cGRhdGVEaXNwbGF5IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLnVwZGF0ZURpc3BsYXkuYXBwbHkodGhpcy50YXJnZXQsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIF8uZWFjaCh0aGlzLnRhcmdldC5fbm9ybWFsaXplZENoaWxkVmlld3MoKSwgZnVuY3Rpb24oY2hpbGRWaWV3LCBpbmRleCl7CiAgICAgICAgICAgICAgICB2YXIgZXh0ZW50ID0ge307CiAgICAgICAgICAgICAgICBleHRlbnRbdGhpcy5fcG9zaXRpb25pbmdDc3NQcm9wZXJ0eVhdID0gIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHg7CiAgICAgICAgICAgICAgICBleHRlbnRbdGhpcy5fcG9zaXRpb25pbmdDc3NQcm9wZXJ0eVldID0gIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHk7CiAgICAgICAgICAgICAgICB0aGlzLiRjc3MoY2hpbGRWaWV3LmVsLCBleHRlbnQpOwogICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICB9LAoKICAgICAgICBfdGFyZ2V0UGFkZGluZ1ggOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy50YXJnZXQuX3BhZExlZnQoKTsKICAgICAgICB9LAoKICAgICAgICBfdGFyZ2V0UGFkZGluZ1kgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy50YXJnZXQuX3BhZFRvcCgpOwogICAgICAgIH0sCgogICAgICAgICRkYXRhIDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLiRkYXRhLAoKICAgICAgICAkY3NzIDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLiRjc3MsCgogICAgICAgIF94ZmFWaWV3UmVnaXN0cnkgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy54ZmFWaWV3UmVnaXN0cnk7ICAgIC8vVE9ETzogcmVtb3ZlIHdpbmRvdyBkZXBlbmRlbmN5CiAgICAgICAgfQoKICAgIH0pCgp9KShfLCAkLCB4ZmFsaWIpOwoKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgeGZhbGliLnZpZXcubGF5b3V0LlBvc2l0aW9uTGF5b3V0ID0geGZhbGliLnZpZXcubGF5b3V0LkxheW91dEJhc2UuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnZpZXcubGF5b3V0LkxheW91dEJhc2UucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBtZWFzdXJlU2l6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciBsYXlvdXRNb2RlbCA9IHRoaXMudGFyZ2V0LmxheW91dE1vZGVsOwogICAgICAgICAgICB2YXIgcGFyZW50UGFkTGVmdCA9IHRoaXMuX3RhcmdldFBhZGRpbmdYKCk7CiAgICAgICAgICAgIHZhciBwYXJlbnRQYWRUb3AgPSB0aGlzLl90YXJnZXRQYWRkaW5nWSgpOwogICAgICAgICAgICB2YXIgb2xkRXh0ZW50VyA9IGxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgIHZhciBvbGRFeHRlbnRIID0gbGF5b3V0TW9kZWwuZXh0ZW50aDsKICAgICAgICAgICAgdmFyIGNvbnRhaW5lclcgPSAwOwogICAgICAgICAgICB2YXIgY29udGFpbmVySCA9IDA7CiAgICAgICAgICAgIF8uZWFjaCh0aGlzLnRhcmdldC5fbm9ybWFsaXplZENoaWxkVmlld3MoKSwgZnVuY3Rpb24oY2hpbGRWaWV3LCBpbmRleCl7CgogICAgICAgICAgICAgICAgY2hpbGRWaWV3LmxheW91dE1vZGVsLm1lYXN1cmVkeCA9ICBwYXJlbnRQYWRMZWZ0ICsgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHg7CiAgICAgICAgICAgICAgICBjaGlsZFZpZXcubGF5b3V0TW9kZWwubWVhc3VyZWR5ID0gIHBhcmVudFBhZFRvcCArIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnR5OwogICAgICAgICAgICAgICAgaWYoY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHggKyBjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50dyA+IGNvbnRhaW5lclcpCiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyVyA9IGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnR4ICsgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgICAgICBpZihjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50eSArIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnRoID4gY29udGFpbmVySCkKICAgICAgICAgICAgICAgICAgICBjb250YWluZXJIID0gY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHkgKyBjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50aDsKICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICBpZihsYXlvdXRNb2RlbC5leHRlbnRhY3R1YWx3IDwgMCl7CiAgICAgICAgICAgICAgICB2YXIgcGFyZW50RXh0ZW50VyA9IGxheW91dE1vZGVsLm1hcmdpbmxlZnQgKyBjb250YWluZXJXICsgbGF5b3V0TW9kZWwubWFyZ2lucmlnaHQ7CiAgICAgICAgICAgICAgICBsYXlvdXRNb2RlbC5leHRlbnR3ID0gcGFyZW50RXh0ZW50VzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihsYXlvdXRNb2RlbC5leHRlbnRhY3R1YWxoIDwgMCl7CiAgICAgICAgICAgICAgICB2YXIgcGFyZW50RXh0ZW50SCA9IGxheW91dE1vZGVsLm1hcmdpbnRvcCArIGNvbnRhaW5lckggKyBsYXlvdXRNb2RlbC5tYXJnaW5ib3R0b207CiAgICAgICAgICAgICAgICBsYXlvdXRNb2RlbC5leHRlbnRoID0gcGFyZW50RXh0ZW50SDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYob2xkRXh0ZW50VyAhPSBsYXlvdXRNb2RlbC5leHRlbnR3IHx8IG9sZEV4dGVudEggIT0gbGF5b3V0TW9kZWwuZXh0ZW50aCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KQp9KShfLCAkLCB4ZmFsaWIpOwoKCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LmxheW91dC5MZWZ0UmlnaHRMYXlvdXQgPSB4ZmFsaWIudmlldy5sYXlvdXQuTGF5b3V0QmFzZS5leHRlbmQoewogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5sYXlvdXQuTGF5b3V0QmFzZS5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIG1lYXN1cmVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIGxheW91dE1vZGVsID0gdGhpcy50YXJnZXQubGF5b3V0TW9kZWw7CiAgICAgICAgICAgIHZhciBwYXJlbnRQYWRYID0gdGhpcy5fdGFyZ2V0UGFkZGluZ1goKTsKICAgICAgICAgICAgdmFyIHBhcmVudFBhZFkgPSB0aGlzLl90YXJnZXRQYWRkaW5nWSgpOwogICAgICAgICAgICB2YXIgb2xkRXh0ZW50VyA9IGxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgIHZhciBvbGRFeHRlbnRIID0gbGF5b3V0TW9kZWwuZXh0ZW50aDsKICAgICAgICAgICAgdmFyIHBhcmVudENvbnRlbnRXaWR0aCAgPSAgbGF5b3V0TW9kZWwuZXh0ZW50dyAtIGxheW91dE1vZGVsLm1hcmdpbmxlZnQgLSBsYXlvdXRNb2RlbC5tYXJnaW5yaWdodCArIHRoaXMuX2xheW91dE1hbmFnZXIuTEFZT1VUX0VSUk9SX01BUkdJTjsKICAgICAgICAgICAgaWYobGF5b3V0TW9kZWwuZXh0ZW50YWN0dWFsdyA8IDApewogICAgICAgICAgICAgICAgcGFyZW50Q29udGVudFdpZHRoID0gMTAwMDAwMDsgLy9BcmJpdHJhcnkgbGltaXRhdGlvbiBmb3IgbWF4IHdpZHRoLiBDb3VsZCBiZSBNQVhfVkFMVUUsIGJ1dCB0aGF0IG1heSBiZSBjb3N0bHk/CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBjdXJyZW50WCA9ICAwOy8vUmlnaHQgb2YgdGhlIGxhc3QgZWxlbWVudAogICAgICAgICAgICB2YXIgY3VycmVudExpbmVZID0gMDsKICAgICAgICAgICAgdmFyIGxpbmVIZWlnaHQgPSAwOyAvL0xpbmUgSGVpZ2h0IGZvciBjdXJyZW50IGxpbmUKICAgICAgICAgICAgXy5lYWNoKHRoaXMudGFyZ2V0Ll9ub3JtYWxpemVkQ2hpbGRWaWV3cygpLCBmdW5jdGlvbihjaGlsZFZpZXcsIGluZGV4KXsKICAgICAgICAgICAgICAgIGlmKGN1cnJlbnRYICsgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHcgPiBwYXJlbnRDb250ZW50V2lkdGgpewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRYID0gMDsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGluZVkgPSBjdXJyZW50TGluZVkgKyBsaW5lSGVpZ2h0OwogICAgICAgICAgICAgICAgICAgIGxpbmVIZWlnaHQgPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2hpbGRWaWV3LmxheW91dE1vZGVsLm1lYXN1cmVkeCA9ICBwYXJlbnRQYWRYICsgY3VycmVudFg7CiAgICAgICAgICAgICAgICBjaGlsZFZpZXcubGF5b3V0TW9kZWwubWVhc3VyZWR5ID0gcGFyZW50UGFkWSArIGN1cnJlbnRMaW5lWTsKICAgICAgICAgICAgICAgIGlmKGxpbmVIZWlnaHQgPCBjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50aCl7CiAgICAgICAgICAgICAgICAgICAgbGluZUhlaWdodCA9IGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy91cGRhdGUgdG9wIHZhcmlhYmxlcyBmb3Igc2Vjb25kIGVsZW1lbnQKICAgICAgICAgICAgICAgIGN1cnJlbnRYID0gY3VycmVudFggKyAgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICBpZihsYXlvdXRNb2RlbC5leHRlbnRhY3R1YWx3IDwgMCkgewogICAgICAgICAgICAgICAgdmFyIHBhcmVudEV4dGVudFcgPSBsYXlvdXRNb2RlbC5tYXJnaW5sZWZ0ICsgY3VycmVudFggKyBsYXlvdXRNb2RlbC5tYXJnaW5yaWdodDsKICAgICAgICAgICAgICAgIGxheW91dE1vZGVsLmV4dGVudHcgPSBwYXJlbnRFeHRlbnRXOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKGxheW91dE1vZGVsLmV4dGVudGFjdHVhbGggPCAwKSB7CiAgICAgICAgICAgICAgICB2YXIgcGFyZW50RXh0ZW50SCA9IGxheW91dE1vZGVsLm1hcmdpbnRvcCArIGN1cnJlbnRMaW5lWSArIGxpbmVIZWlnaHQgKyBsYXlvdXRNb2RlbC5tYXJnaW5ib3R0b207CiAgICAgICAgICAgICAgICBsYXlvdXRNb2RlbC5leHRlbnRoID0gcGFyZW50RXh0ZW50SDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYob2xkRXh0ZW50VyAhPSBsYXlvdXRNb2RlbC5leHRlbnR3IHx8IG9sZEV4dGVudEggIT0gbGF5b3V0TW9kZWwuZXh0ZW50aCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pCn0pKF8sICQsIHhmYWxpYik7CgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LmxheW91dC5SaWdodExlZnRMYXlvdXQgPSB4ZmFsaWIudmlldy5sYXlvdXQuTGVmdFJpZ2h0TGF5b3V0LmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LmxheW91dC5MZWZ0UmlnaHRMYXlvdXQucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25pbmdDc3NQcm9wZXJ0eVggPSAicmlnaHQiOwogICAgICAgICAgICB0aGlzLl9wb3NpdGlvbmluZ0Nzc1Byb3BlcnR5WSA9ICJ0b3AiOwogICAgICAgIH0sCgogICAgICAgIF90YXJnZXRQYWRkaW5nWCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnRhcmdldC5fcGFkUmlnaHQoKTsKICAgICAgICB9LAoKICAgICAgICBfdGFyZ2V0UGFkZGluZ1kgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy50YXJnZXQuX3BhZFRvcCgpOwogICAgICAgIH0KCiAgICB9KQp9KShfLCAkLCB4ZmFsaWIpOwoKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgeGZhbGliLnZpZXcubGF5b3V0LlRvcEJvdHRvbUxheW91dCA9IHhmYWxpYi52aWV3LmxheW91dC5MYXlvdXRCYXNlLmV4dGVuZCh7CgogICAgICAgIG1lYXN1cmVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIGxheW91dE1vZGVsID0gdGhpcy50YXJnZXQubGF5b3V0TW9kZWw7CiAgICAgICAgICAgIHZhciBwYXJlbnRQYWRMZWZ0ID0gdGhpcy5fdGFyZ2V0UGFkZGluZ1goKTsKICAgICAgICAgICAgdmFyIHBhcmVudFBhZFRvcCA9IHRoaXMuX3RhcmdldFBhZGRpbmdZKCk7CiAgICAgICAgICAgIHZhciBvbGRFeHRlbnRXID0gbGF5b3V0TW9kZWwuZXh0ZW50dzsKICAgICAgICAgICAgdmFyIG9sZEV4dGVudEggPSBsYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICB2YXIgY29udGFpbmVyVyA9IDA7CiAgICAgICAgICAgIHZhciBjdXJyZW50TGluZVkgID0gIDA7CiAgICAgICAgICAgIF8uZWFjaCh0aGlzLnRhcmdldC5fbm9ybWFsaXplZENoaWxkVmlld3MoKSwgZnVuY3Rpb24oY2hpbGRWaWV3LCBpbmRleCl7CiAgICAgICAgICAgICAgICBjaGlsZFZpZXcubGF5b3V0TW9kZWwubWVhc3VyZWR4ID0gcGFyZW50UGFkTGVmdDsKICAgICAgICAgICAgICAgIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHkgPSAgcGFyZW50UGFkVG9wICsgY3VycmVudExpbmVZOwogICAgICAgICAgICAgICAgaWYoY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHcgPiBjb250YWluZXJXKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyVyA9IGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnR3OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy91cGRhdGUgY3VycmVudExpbmVZIHZhcmlhYmxlcyBmb3Igc2Vjb25kIGVsZW1lbnQKICAgICAgICAgICAgICAgIGN1cnJlbnRMaW5lWSA9IGN1cnJlbnRMaW5lWSArIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgIGlmKGxheW91dE1vZGVsLmV4dGVudGFjdHVhbHcgPCAwKXsKICAgICAgICAgICAgICAgIHZhciBwYXJlbnRFeHRlbnRXID0gbGF5b3V0TW9kZWwubWFyZ2lubGVmdCArIGNvbnRhaW5lclcgKyBsYXlvdXRNb2RlbC5tYXJnaW5yaWdodDsKICAgICAgICAgICAgICAgIGxheW91dE1vZGVsLmV4dGVudHcgPSBwYXJlbnRFeHRlbnRXOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKGxheW91dE1vZGVsLmV4dGVudGFjdHVhbGggPCAwKXsKICAgICAgICAgICAgICAgIHZhciBwYXJlbnRFeHRlbnRIID0gbGF5b3V0TW9kZWwubWFyZ2ludG9wICsgY3VycmVudExpbmVZICsgbGF5b3V0TW9kZWwubWFyZ2luYm90dG9tOwogICAgICAgICAgICAgICAgbGF5b3V0TW9kZWwuZXh0ZW50aCA9IHBhcmVudEV4dGVudEg7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKG9sZEV4dGVudFcgIT0gbGF5b3V0TW9kZWwuZXh0ZW50dyB8fCBvbGRFeHRlbnRIICE9IGxheW91dE1vZGVsLmV4dGVudGgpewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSkKfSkoXywgJCwgeGZhbGliKTsKCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LmxheW91dC5Sb3dMYXlvdXQgPSB4ZmFsaWIudmlldy5sYXlvdXQuTGF5b3V0QmFzZS5leHRlbmQoewogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5sYXlvdXQuTGF5b3V0QmFzZS5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIG1lYXN1cmVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIGxheW91dE1vZGVsID0gdGhpcy50YXJnZXQubGF5b3V0TW9kZWw7CiAgICAgICAgICAgIHZhciBsaW5lSGVpZ2h0ID0gMDsgLy9MaW5lIEhlaWdodCBmb3IgY3VycmVudCBsaW5lCiAgICAgICAgICAgIF8uZWFjaCh0aGlzLnRhcmdldC5fbm9ybWFsaXplZENoaWxkVmlld3MoKSwgZnVuY3Rpb24oY2hpbGRWaWV3LCBpbmRleCl7Ci8vICAgICAgICAgICAgICAgIGlmKGNoaWxkVmlldy5tb2RlbCAmJiBjaGlsZFZpZXcubW9kZWwuY2xhc3NOYW1lID09ICJkcmF3IikgICAgICAvL0RyYXcgdGFibGUgY2VsbHMgYXJlIHNldCB0byAxMDAlIHNpemVzLiBUaGV5IGNhbiBub3QgZ3Jvdy4gSWYgbW92ZWQsIHRoZXknbGwgb3ZlcmxheSBib3JkZXIKLy8gICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIGlmKGxpbmVIZWlnaHQgPCBjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50aCl7CiAgICAgICAgICAgICAgICAgICAgbGluZUhlaWdodCA9IGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgLy9TZXQgZXh0ZW50aCBmb3IgYWxsIHJvdyBjZWxscwogICAgICAgICAgICBfLmVhY2godGhpcy50YXJnZXQuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uKGNoaWxkVmlldywgaW5kZXgpewogICAgICAgICAgICAgICAgaWYoY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudGggIT0gbGluZUhlaWdodCl7CiAgICAgICAgICAgICAgICAgICAgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudGggPSBsaW5lSGVpZ2h0OwogICAgICAgICAgICAgICAgICAgIGNoaWxkVmlldy5pbnZhbGlkYXRlRGlzcGxheSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgIGxheW91dE1vZGVsLmV4dGVudGggPSBsYXlvdXRNb2RlbC5tYXJnaW50b3AgKyBsaW5lSGVpZ2h0ICsgbGF5b3V0TW9kZWwubWFyZ2luYm90dG9tOwoKICAgICAgICAgICAgLy9pbiBjYXNlIG9mIHJvd0xheW91dCBtZWFzdXJlIHdvdWxkIGFsd2F5cyByZXR1cm4gdHJ1ZSB3aGljaCBtZWFucwogICAgICAgICAgICAvLyBsYXlvdXQgYWxnbyBvZiB0YWJsZSB3b3VsZCBhbHdheXMgYmUgdHJpZ2dlcmVkIGFzIHJvdyBkb2VzIG5vdCBoYXZlIGVub3VnaCBkYXRhIHRvIGNvbXB1dGUgaWYgYW55IGNvbHVtbiB3aWR0aCBjaGFuZ2VkCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICB9KQp9KShfLCAkLCB4ZmFsaWIpOwoKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgeGZhbGliLnZpZXcubGF5b3V0LkRhdGFUYWJsZVJvd0xheW91dCA9IHhmYWxpYi52aWV3LmxheW91dC5Sb3dMYXlvdXQuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnZpZXcubGF5b3V0LlJvd0xheW91dC5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIG1lYXN1cmVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgLy9pbiBjYXNlIG9mIHJvd0xheW91dCBtZWFzdXJlIHdvdWxkIGFsd2F5cyByZXR1cm4gdHJ1ZSB3aGljaCBtZWFucwogICAgICAgICAgICAvLyBsYXlvdXQgYWxnbyBvZiB0YWJsZSB3b3VsZCBhbHdheXMgYmUgdHJpZ2dlcmVkIGFzIHJvdyBkb2VzIG5vdCBoYXZlIGVub3VnaCBkYXRhIHRvIGNvbXB1dGUgaWYgYW55IGNvbHVtbiB3aWR0aCBjaGFuZ2VkCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0sCgogICAgICAgIHVwZGF0ZURpc3BsYXkgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5sYXlvdXQuUm93TGF5b3V0LnByb3RvdHlwZS51cGRhdGVEaXNwbGF5LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLnRhcmdldC5lbCwgeyJwb3NpdGlvbiI6InJlbGF0aXZlIn0pOwogICAgICAgICAgICBfLmVhY2godGhpcy50YXJnZXQuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uKGNoaWxkVmlldyl7CiAgICAgICAgICAgICAgICB2YXIgZXh0ZW50ID0ge307CiAgICAgICAgICAgICAgICBleHRlbnRbInBvc2l0aW9uIl0gPSAgInJlbGF0aXZlIjsKICAgICAgICAgICAgICAgIHRoaXMuJGNzcyhjaGlsZFZpZXcuZWwsIGV4dGVudCk7CiAgICAgICAgICAgICAgICBpZihjaGlsZFZpZXcubGF5b3V0TW9kZWwuYm9yZGVybGVmdCA+IDIpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3MoY2hpbGRWaWV3LmVsLCB7ImJvcmRlci1sZWZ0LXdpZHRoIjpjaGlsZFZpZXcubGF5b3V0TW9kZWwuYm9yZGVybGVmdC8yLjB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGNoaWxkVmlldy5sYXlvdXRNb2RlbC5ib3JkZXJ0b3AgPiAyKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKGNoaWxkVmlldy5lbCwgeyAiYm9yZGVyLXRvcC13aWR0aCI6Y2hpbGRWaWV3LmxheW91dE1vZGVsLmJvcmRlcnRvcC8yLjB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGNoaWxkVmlldy5sYXlvdXRNb2RlbC5ib3JkZXJib3R0b20gPiAyKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKGNoaWxkVmlldy5lbCwgeyJib3JkZXItYm90dG9tLXdpZHRoIjpjaGlsZFZpZXcubGF5b3V0TW9kZWwuYm9yZGVyYm90dG9tLzIuMH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYoY2hpbGRWaWV3LmxheW91dE1vZGVsLmJvcmRlcnJpZ2h0ID4gMikgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyhjaGlsZFZpZXcuZWwsIHsiYm9yZGVyLXJpZ2h0LXdpZHRoIjpjaGlsZFZpZXcubGF5b3V0TW9kZWwuYm9yZGVycmlnaHQvMi4wfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIHRoaXMpOwoKICAgICAgICB9CiAgICB9KQp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LmxheW91dC5SaWdodExlZnRSb3dMYXlvdXQgPSB4ZmFsaWIudmlldy5sYXlvdXQuUm93TGF5b3V0LmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LmxheW91dC5Sb3dMYXlvdXQucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25pbmdDc3NQcm9wZXJ0eVggPSAicmlnaHQiOwogICAgICAgICAgICB0aGlzLl9wb3NpdGlvbmluZ0Nzc1Byb3BlcnR5WSA9ICJ0b3AiOwogICAgICAgIH0sCgogICAgICAgIF90YXJnZXRQYWRkaW5nWCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnRhcmdldC5fcGFkUmlnaHQoKTsKICAgICAgICB9LAoKICAgICAgICBfdGFyZ2V0UGFkZGluZ1kgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy50YXJnZXQuX3BhZFRvcCgpOwogICAgICAgIH0KICAgIH0pCn0pKF8sICQsIHhmYWxpYik7CgoKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgeGZhbGliLnZpZXcubGF5b3V0LlRhYmxlTGF5b3V0ID0geGZhbGliLnZpZXcubGF5b3V0LkxheW91dEJhc2UuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnZpZXcubGF5b3V0LkxheW91dEJhc2UucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5fdGFibGVDZWxsR3JpZCA9IFsgW10gXTsKICAgICAgICAgICAgdGhpcy5hc3NpZ25lZENvbFdpZHRocyA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMudGFyZ2V0LmxheW91dE1vZGVsLmNvbHVtbndpZHRocywgW10pOwogICAgICAgICAgICB0aGlzLl9jb2x1bW5XaWR0aHMgPSB0aGlzLmFzc2lnbmVkQ29sV2lkdGhzLnNsaWNlKCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyB0aGUgUm93cyBpbiB0aGUgdGFibGUgYnkgZmlsdGVyaW5nIG91dCByb3dzIGZyb20gYWxsIHRoZSBjaGlsZCB2aWV3cwogICAgICAgICAqIEByZXR1cm5zIEFycmF5IGNvbnRhaW5pbmcgdGhlIGNoaWxkIHZpZXdzIHRoYXQgYXJlIHJvd3MKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9nZXRSb3dzIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gXy5maWx0ZXIodGhpcy50YXJnZXQuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uIChjaGlsZFZpZXcpIHsKICAgICAgICAgICAgICAgIGlmIChjaGlsZFZpZXcubGF5b3V0TW9kZWwubGF5b3V0ID09IHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9ST1cKICAgICAgICAgICAgICAgICAgICAgICAgfHwgY2hpbGRWaWV3LmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUklHSFRMRUZUUk9XKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgfSwKCiAgICAgICAgbWVhc3VyZVNpemUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBsYXlvdXRNb2RlbCA9IHRoaXMudGFyZ2V0LmxheW91dE1vZGVsLAogICAgICAgICAgICAgICAgcm93Vmlld3MgPSB0aGlzLl9nZXRSb3dzKCk7CgogICAgICAgICAgICB0aGlzLl92YWxpZENlbGxzSW5Sb3cocm93Vmlld3MpOwoKICAgICAgICAgICAgXy5lYWNoKHJvd1ZpZXdzLCBmdW5jdGlvbihyb3dWaWV3LCByb3dJbmRleCl7CiAgICAgICAgICAgICAgICBfLmVhY2gocm93Vmlldy5fbm9ybWFsaXplZENoaWxkVmlld3MoKSwgZnVuY3Rpb24oY2VsbFZpZXcpewogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsTGF5b3V0ID0gY2VsbFZpZXcubGF5b3V0TW9kZWw7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbHNwYW4gPSB0aGlzLmdldE9yRWxzZShjZWxsTGF5b3V0LmNvbHNwYW4sIDEpOwogICAgICAgICAgICAgICAgICAgIGlmKGNvbHNwYW4gPT0gLTEpCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbHNwYW4gPSB0aGlzLl90YWJsZUNlbGxHcmlkLmxlbmd0aCAtIGNlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleDsgLy9pZiBjb2xwYW4gaXMgLTEsIHRoZW4gc2V0IGl0IHRvIHJlbWFpbmluZyBncmlkIGxlbmd0aAogICAgICAgICAgICAgICAgICAgIHZhciBsYXN0Q2VsbEluZGV4ID0gY2VsbFZpZXcuZWZmZWN0aXZlQ2VsbEluZGV4ICsgY29sc3BhbiAtMTsKCiAgICAgICAgICAgICAgICAgICAgaWYoIXRoaXMuX3RhYmxlQ2VsbEdyaWRbbGFzdENlbGxJbmRleF0pewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbGFzdE5vbkVtcHR5Q29sSW5kZXggPSAtMTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBqID0gbGFzdENlbGxJbmRleDsgaj49MDsgai0tICl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl90YWJsZUNlbGxHcmlkW2pdKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0Tm9uRW1wdHlDb2xJbmRleCA9IGo7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLy9sYXN0Tm9uRW1wdHlDb2xJbmRleCBjYW4gbm90IGJlIC0xIGhlcmUuIHNpbmNlIGl0IHNob3VsZCBiZSBhdCBsZWFzdCAwCiAgICAgICAgICAgICAgICAgICAgICAgIC8vTm93IGNvcHkgZmlsbCBhbGwgcHJldmlvdXMgbWlzc2luZyBjb2x1bW4gZGF0YSB3aXRoIGxhc3ROb25FbXB0eUNvbCBkYXRhCiAgICAgICAgICAgICAgICAgICAgICAgIGZvcih2YXIgayA9IGxhc3ROb25FbXB0eUNvbEluZGV4ICsgMTsgayA8PSBsYXN0Q2VsbEluZGV4IDsgaysrKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3RhYmxlQ2VsbEdyaWRba10gPSB0aGlzLl90YWJsZUNlbGxHcmlkW2stMV0uc3BsaWNlKCkgOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vTm93IGFkZCBjdXJyZW50Q2VsbFZpZXcgdG8gcHJvcGVyIGxvY2F0aW9uIGluIGNlbGwgZ3JpZAogICAgICAgICAgICAgICAgICAgIGZvcih2YXIgaSA9IGNlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleDsgaSA8PSBsYXN0Q2VsbEluZGV4OyAgaSsrKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGFibGVDZWxsR3JpZFtpXVtyb3dJbmRleF0gPSBjZWxsVmlldzsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuYXNzaWduZWRDb2xXaWR0aHNbY2VsbFZpZXcuZWZmZWN0aXZlQ2VsbEluZGV4XSA+IC0xKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29sdW1uV2lkdGhzW2NlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleF0gPSB0aGlzLmFzc2lnbmVkQ29sV2lkdGhzW2NlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleF07CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih0aGlzLmdldE9yRWxzZShjZWxsTGF5b3V0LmNvbHNwYW4sIDEpID09IDEpeyAvLyB1c2UgYWN0dWFsIGNvbHNwYW4KICAgICAgICAgICAgICAgICAgICAgICAgLy9UT0RPOmNoZWNrIGlmIHRhYmxlQ2VsbEluZGV4IG1haW50YWluZWQgcHJvcGVybHkKICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2VsbExheW91dC5leHRlbnR3ID4gKHRoaXMuX2NvbHVtbldpZHRoc1tjZWxsVmlldy5lZmZlY3RpdmVDZWxsSW5kZXhdIHx8IDApKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29sdW1uV2lkdGhzW2NlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleF0gID0gY2VsbExheW91dC5leHRlbnR3OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgIC8vQWRkaXRpb25hbCBwYXNzIHRvIGFkanVzdCBjb2x1bW5XaWR0aHMgZm9yIGNvbHVtbnMgd2l0aCBjb2xwc2FuID4gMQogICAgICAgICAgICBfLmVhY2godGhpcy5fdGFibGVDZWxsR3JpZCwgZnVuY3Rpb24oY29sdW1uQ2VsbHMsIGNvbEluZGV4KXsKICAgICAgICAgICAgICAgIGlmKHRoaXMuYXNzaWduZWRDb2xXaWR0aHNbY29sSW5kZXhdID4gLTEpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgdmFyIGNvbFdpZHRoID0gdGhpcy5fY29sdW1uV2lkdGhzW2NvbEluZGV4XTsKICAgICAgICAgICAgICAgIF8uZWFjaChjb2x1bW5DZWxscywgZnVuY3Rpb24oY2VsbFZpZXcpewogICAgICAgICAgICAgICAgICAgIHZhciBjb2xzcGFuID0gdGhpcy5nZXRPckVsc2UoY2VsbFZpZXcubGF5b3V0TW9kZWwuY29sc3BhbiwgIjEiKTsKICAgICAgICAgICAgICAgICAgICBpZihjb2xzcGFuID09IC0xKQogICAgICAgICAgICAgICAgICAgICAgICBjb2xzcGFuID0gdGhpcy5fdGFibGVDZWxsR3JpZC5sZW5ndGggLSBjZWxsVmlldy5lZmZlY3RpdmVDZWxsSW5kZXg7CiAgICAgICAgICAgICAgICAgICAgLy9JZiBjb2xzcGFuIGlzIG9uZSwgd2UgaGF2ZSBhbHJlYWR5IHRha2VuIGNhcmUuIGlmIHRoaXMgY2VsbCBzdGlsbCBleHRlbmRzIGJleW9uZCB0aGlzIGNvbHVtbiwgd2UnbGwgaGFuZGxlIGl0IGxhdGVyCiAgICAgICAgICAgICAgICAgICAgaWYoIGNvbHNwYW4gPT0gMSB8fCAoKGNlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleCArIGNvbHNwYW4gLTEpICE9IGNvbEluZGV4KSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIC8vRm9yIHNwYW5uZWQgY29sdW1uLCBjb21wdXRlIHRoZSB3aXRoIG9mIHRoZSBjZWxsIHRoYXQgbGllcyBpbiB0aGlzIGNsb3Vtbi4KICAgICAgICAgICAgICAgICAgICB2YXIgc3Bhbm5lZENvbFdpZHRoID0gY2VsbFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50dzsKICAgICAgICAgICAgICAgICAgICBmb3IodmFyIGwgPSBjZWxsVmlldy5lZmZlY3RpdmVDZWxsSW5kZXg7IGwgPCBjb2xJbmRleDsgbCsrKXsKICAgICAgICAgICAgICAgICAgICAgICAgc3Bhbm5lZENvbFdpZHRoID0gc3Bhbm5lZENvbFdpZHRoIC0gdGhpcy5fY29sdW1uV2lkdGhzW2xdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZihzcGFubmVkQ29sV2lkdGggPiB0aGlzLl9jb2x1bW5XaWR0aHNbY29sSW5kZXhdKQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jb2x1bW5XaWR0aHNbY29sSW5kZXhdID0gc3Bhbm5lZENvbFdpZHRoOwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgIH0sIHRoaXMpOwoKICAgICAgICAgICAgLy9Ob3cgdXBkYXRlIHRoZSBmaW5hbCBjb21wdXRlZCBleHRlbnR3IGZvciBjZWxscyBhbmQgcm93cy4KICAgICAgICAgICAgLy9BbHNvIHVwZGF0ZSBtZWFzdXJlZHgveSBmb3IgaXQncyBjZWxscwogICAgICAgICAgICBfLmVhY2gocm93Vmlld3MsIGZ1bmN0aW9uKHJvd1ZpZXcsIHJvd0luZGV4KXsKICAgICAgICAgICAgICAgIHZhciByb3dQYWRYID0gcm93Vmlldy5sYXlvdXQuX3RhcmdldFBhZGRpbmdYKCk7CiAgICAgICAgICAgICAgICB2YXIgcm93UGFkWSA9IHJvd1ZpZXcubGF5b3V0Ll90YXJnZXRQYWRkaW5nWSgpOwogICAgICAgICAgICAgICAgdmFyIHJvd1dpZHRoID0gMDsKICAgICAgICAgICAgICAgIF8uZWFjaChyb3dWaWV3Ll9ub3JtYWxpemVkQ2hpbGRWaWV3cygpLCBmdW5jdGlvbihjZWxsVmlldyl7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5ld0NlbGxXID0gdGhpcy5fY29tcHV0ZUNvbHVtbldpZHRoKGNlbGxWaWV3KTsKICAgICAgICAgICAgICAgICAgICBpZihuZXdDZWxsVyAhPSBjZWxsVmlldy5sYXlvdXRNb2RlbC5leHRlbnR3KXsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50dyA9IG5ld0NlbGxXOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsVmlldy5pbnZhbGlkYXRlRGlzcGxheSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjZWxsVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHggPSByb3dQYWRYICsgcm93V2lkdGg7CiAgICAgICAgICAgICAgICAgICAgY2VsbFZpZXcubGF5b3V0TW9kZWwubWVhc3VyZWR5ID0gcm93UGFkWTsKICAgICAgICAgICAgICAgICAgICByb3dXaWR0aCA9IHJvd1dpZHRoICsgY2VsbFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50dzsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICAgICAgdmFyIG5ld1Jvd1dpZHRoID0gcm93Vmlldy5sYXlvdXRNb2RlbC5tYXJnaW5sZWZ0ICsgcm93V2lkdGggKyByb3dWaWV3LmxheW91dE1vZGVsLm1hcmdpbnJpZ2h0OwogICAgICAgICAgICAgICAgaWYocm93Vmlldy5sYXlvdXRNb2RlbC5leHRlbnR3ICE9IG5ld1Jvd1dpZHRoKXsKICAgICAgICAgICAgICAgICAgICByb3dWaWV3LmxheW91dE1vZGVsLmV4dGVudHcgPSBuZXdSb3dXaWR0aDsKICAgICAgICAgICAgICAgICAgICByb3dWaWV3LmludmFsaWRhdGVEaXNwbGF5KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIHRoaXMpOwoKICAgICAgICAgICAgLy9Ob3cgdXBkYXRlIHRoZSBmaW5hbCBjb21wdXRlZCBleHRlbnR3IGZvciB0YWJsZSBhbmQgbWVhc3VyZWR4L3kgZm9yIGl0J3MgY2hpbGRyZW4KICAgICAgICAgICAgdmFyIHRhYmxlUGFkWCA9IHRoaXMuX3RhcmdldFBhZGRpbmdYKCk7CiAgICAgICAgICAgIHZhciB0YWJsZVBhZFkgPSB0aGlzLl90YXJnZXRQYWRkaW5nWSgpOwogICAgICAgICAgICB2YXIgcGFyZW50VyA9IDA7CiAgICAgICAgICAgIHZhciBwYXJlbnRIID0gMDsKICAgICAgICAgICAgXy5lYWNoKHRoaXMudGFyZ2V0Ll9ub3JtYWxpemVkQ2hpbGRWaWV3cygpLCBmdW5jdGlvbihjaGlsZFZpZXcsIGNoaWxkSW5kZXgpewogICAgICAgICAgICAgICAgaWYoY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHcgPiBwYXJlbnRXKXsKICAgICAgICAgICAgICAgICAgICBwYXJlbnRXID0gY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjaGlsZFZpZXcubGF5b3V0TW9kZWwubWVhc3VyZWR4ID0gdGFibGVQYWRYOwogICAgICAgICAgICAgICAgY2hpbGRWaWV3LmxheW91dE1vZGVsLm1lYXN1cmVkeSA9IHRhYmxlUGFkWSArIHBhcmVudEg7CiAgICAgICAgICAgICAgICBwYXJlbnRIID0gcGFyZW50SCArIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgIHZhciBvbGRFeHRlbnRXID0gbGF5b3V0TW9kZWwuZXh0ZW50dzsKICAgICAgICAgICAgdmFyIG9sZEV4dGVudEggPSBsYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICBsYXlvdXRNb2RlbC5leHRlbnR3ID0gbGF5b3V0TW9kZWwubWFyZ2lubGVmdCArIHBhcmVudFcgKyBsYXlvdXRNb2RlbC5tYXJnaW5yaWdodDsKICAgICAgICAgICAgbGF5b3V0TW9kZWwuZXh0ZW50aCA9IGxheW91dE1vZGVsLm1hcmdpbnRvcCArIHBhcmVudEggKyBsYXlvdXRNb2RlbC5tYXJnaW5ib3R0b207CiAgICAgICAgICAgIGlmKG9sZEV4dGVudFcgIT0gbGF5b3V0TW9kZWwuZXh0ZW50dyB8fCBvbGRFeHRlbnRIICE9IGxheW91dE1vZGVsLmV4dGVudGgpewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUNvbHVtbldpZHRoIDogZnVuY3Rpb24oY2VsbFZpZXcpewogICAgICAgICAgICB2YXIgY29sc3BhbiA9IHRoaXMuZ2V0T3JFbHNlKGNlbGxWaWV3LmxheW91dE1vZGVsLmNvbHNwYW4sIDEpOwogICAgICAgICAgICBpZihjb2xzcGFuIDwwKXsKICAgICAgICAgICAgICAgIGNvbHNwYW4gPSB0aGlzLl9jb2x1bW5XaWR0aHMubGVuZ3RoIC0gY2VsbFZpZXcudGFibGVDZWxsSW5kZXg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoY2VsbFZpZXcuZWZmZWN0aXZlQ2VsbEluZGV4ICsgY29sc3BhbiAtMSA+PSB0aGlzLl9jb2x1bW5XaWR0aHMubGVuZ3RoKQogICAgICAgICAgICAgICAgcmV0dXJuIGNlbGxWaWV3LmxheW91dE1vZGVsLmV4dGVudHc7ICAgICAgICAgICAgICAvL3Nob3VsZCBub3QgYmUgdGhlIGNhc2UgZXZlcgogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgdmFyIGNvbFdpZHRoID0gMDsKICAgICAgICAgICAgICAgIGZvcih2YXIgaT0gY2VsbFZpZXcuZWZmZWN0aXZlQ2VsbEluZGV4OyBpIDw9IGNlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleCArIGNvbHNwYW4gLTE7IGkrKyl7CiAgICAgICAgICAgICAgICAgICAgY29sV2lkdGggPSBjb2xXaWR0aCArIHRoaXMuX2NvbHVtbldpZHRoc1tpXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBjb2xXaWR0aDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF92YWxpZENlbGxzSW5Sb3cgOiBmdW5jdGlvbihyb3dWaWV3cykgewogICAgICAgICAgICB2YXIgaGlkZGVuQ2hpbGRJbmRleDsKICAgICAgICAgICAgdmFyIGluZGV4OwogICAgICAgICAgICB2YXIgY291bnQgPTA7CgogICAgICAgICAgICBfLmVhY2gocm93Vmlld3MsIGZ1bmN0aW9uKHJvd1ZpZXcsIHJvd0luZGV4KXsKICAgICAgICAgICAgICAgIHZhciBDaGlsZFZpZXdzID0gcm93Vmlldy5jaGlsZFZpZXdzOwogICAgICAgICAgICAgICAgaGlkZGVuQ2hpbGRJbmRleCA9IFtdOwogICAgICAgICAgICAgICAgXy5lYWNoKENoaWxkVmlld3MsZnVuY3Rpb24odkNoaWxkVmlldywgaW5kZXgpewogICAgICAgICAgICAgICAgICAgICAgIGlmKHZDaGlsZFZpZXcubW9kZWwucHJlc2VuY2UgIT0gInZpc2libGUiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZGVuQ2hpbGRJbmRleC5wdXNoKGluZGV4KTsgIC8vIGtlZXBzIHRoZSBpbmRleCBvZiBoaWRkZW4gZmllbGRzCiAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9LHRoaXMpOwoKCiAgICAgICAgICAgICAgICAgIGZvcih2YXIgaT1DaGlsZFZpZXdzLmxlbmd0aC0xO2k+MDtpLS0pIHsKICAgICAgICAgICAgICAgICAgICAgY291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICBfLmVhY2goaGlkZGVuQ2hpbGRJbmRleCxmdW5jdGlvbih2YWx1ZSxpbmRleCl7IC8vIHRoaXMgaXMgdG8gZmluZCB0aGUgbnVtYmVyIG9mIGhpZGRlbiBlbGVtZW50cyBiZWZvcmUgdGhlIGdpdmVuIGluZGV4LgogICAgICAgICAgICAgICAgICAgICAgICAgaWYodmFsdWUgPCBpKSBjb3VudCsrOwogICAgICAgICAgICAgICAgICAgICB9LHRoaXMpOwogICAgICAgICAgICAgICAgICAgICBDaGlsZFZpZXdzW2ldLmVmZmVjdGl2ZUNlbGxJbmRleCA9IENoaWxkVmlld3NbaV0udGFibGVDZWxsSW5kZXggLSBjb3VudCA7IC8vIHRvIGNhbGN1bGF0ZSB0aGUgZWZmZWN0aXZlIGNlbGwgaW5kZXggZm9yIHZpc2libGUgZmllbGRzLgogICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9LHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIC8vbGF5b3V0IHJlbGF0ZWQgZnVuY3Rpb25zCiAgICAgICAgaW52YWxpZGF0ZVNpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICBpZighdGhpcy5fbGF5b3V0TWFuYWdlci5pc1BlbmRpbmdWYWxpZGF0ZVNpemUodGhpcy50YXJnZXQpKXsgLy9jaGVjayBpc1BlbmRpbmcgdG8gYXZvaWQgcmVjdXJzaW9uCiAgICAgICAgICAgICAgICBfLmVhY2godGhpcy50YXJnZXQuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uKGNoaWxkVmlldykgewogICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5fbGF5b3V0TWFuYWdlci5pc1BlbmRpbmdWYWxpZGF0ZVNpemUoY2hpbGRWaWV3KSAmJiAoY2hpbGRWaWV3LmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUk9XIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFZpZXcubGF5b3V0TW9kZWwubGF5b3V0ID09IHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9SSUdIVExFRlRST1cpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIF8uZWFjaChjaGlsZFZpZXcuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uKGNlbGxWaWV3KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2xheW91dE1hbmFnZXIuaXNQZW5kaW5nVmFsaWRhdGVTaXplKGNlbGxWaWV3KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGxWaWV3LmludmFsaWRhdGVTaXplKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFZpZXcuaW52YWxpZGF0ZVNpemUoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LmxheW91dC5MYXlvdXRCYXNlLnByb3RvdHlwZS5pbnZhbGlkYXRlU2l6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pCn0pKF8sICQsIHhmYWxpYik7CgoKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewoKICAgIHhmYWxpYi52aWV3LmxheW91dC5EYXRhVGFibGVMYXlvdXQgPSB4ZmFsaWIudmlldy5sYXlvdXQuVGFibGVMYXlvdXQuZXh0ZW5kKHsKCiAgICAgICAgLy9mb3IgYSBnaXZlbiBpZCBnZXQgdGhlIGxpc3Qgb2YgaGVhZGVycyAoaW5jbHVkaW5nIHJvdy1oZWFkZXJzIGFuZCBjb2x1bW4taGVhZGVycykKICAgICAgICAvL3RoaXMgY2FuIGJlIG11bHRpcGxlIGluIGNhc2Ugd2UgaGF2ZSBtdWx0aXBsZSByb3cvY29sdW1uLCBvciBjZWxsIHNwYW5zIG11bHRpcGxlIGNvbHVtbnMKICAgICAgICAvL1RDSDogVGFibGUgQ29sdW1uIEhlYWRlcgogICAgICAgIC8vVFJIOiBUYWJsZSBSb3cgSGVhZGVyCiAgICAgICAgLy9UREM6IFRhYmxlIERhdGEgQ2VsbAogICAgICAgIGdldEhlYWRlcjpmdW5jdGlvbihjZWxsSWQsZGF0YVByZXNlbmNlVGFibGUpIHsKICAgICAgICAgICAgLy8gdXNlIGhlYWRlcnMgYXMgYSBTZXQKICAgICAgICAgICAgdmFyIGhlYWRlcnMgPSB7fTsKICAgICAgICAgICAgXy5lYWNoKGRhdGFQcmVzZW5jZVRhYmxlLCBmdW5jdGlvbihyb3csIGkpIHsKICAgICAgICAgICAgICAgIF8uZWFjaChkYXRhUHJlc2VuY2VUYWJsZVtpXSwgZnVuY3Rpb24oY29sdW1uLCBqKSB7CiAgICAgICAgICAgICAgICAgICAgaWYoY2VsbElkID09IGRhdGFQcmVzZW5jZVRhYmxlW2ldW2pdLnN1YnN0cmluZyg0KSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgaywgaGVhZGVyOwogICAgICAgICAgICAgICAgICAgICAgICBmb3Ioaz0wO2s8aTtrKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGRhdGFQcmVzZW5jZVRhYmxlW2tdW2pdLmluZGV4T2YoIlRDSDoiKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyID0gZGF0YVByZXNlbmNlVGFibGVba11bal0uc3Vic3RyaW5nKDQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCFoZWFkZXJzLmhhc093blByb3BlcnR5KGhlYWRlcikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyc1toZWFkZXJdID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yKGs9MDtrPGo7aysrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihkYXRhUHJlc2VuY2VUYWJsZVtpXVtrXS5pbmRleE9mKCJUUkg6IikgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlciA9IGRhdGFQcmVzZW5jZVRhYmxlW2ldW2tdLnN1YnN0cmluZyg0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZighaGVhZGVycy5oYXNPd25Qcm9wZXJ0eShoZWFkZXIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnNbaGVhZGVyXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSx0aGlzKTsKICAgICAgICAgICAgfSx0aGlzKTsKICAgICAgICAgICAgLy8gY29udmVydCBoZWFkZXJzIFNldCBpbnRvIHN0cmluZyB0byBiZSBhZGRlZCB0byBoZWFkZXJzIGF0dHJpYnV0ZQogICAgICAgICAgICByZXR1cm4gXy5rZXlzKGhlYWRlcnMpLmpvaW4oIiAiKS50cmltKCk7CiAgICAgICAgfSwKCgogICAgICAgIG1lYXN1cmVTaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vaGVpZ2h0VGFibGU6IGNvbnRhaW5zIHRoZSBoZWlnaHQgZm9yIGVhY2ggcm93CiAgICAgICAgICAgIC8vd2lkdGhUYWJsZTogY29udGFpbnMgdGhlIHdpZHRoIGZvciBlYWNoIGNlbGwKICAgICAgICAgICAgLy9kYXRhUHJlc2VuY2VUYWJsZTogY2FwdHVyZXMgdGhlIG1hcHBpbmcgZm9yIGhlYWRlciB0byBkYXRhIGNlbGxzCiAgICAgICAgICAgIHZhciBoZWlnaHRUYWJsZSA9IFtdLCB3aWR0aFRhYmxlID0gW10sIGRhdGFQcmVzZW5jZVRhYmxlID0gW107CgogICAgICAgICAgICB2YXIgbGF5b3V0TW9kZWwgPSB0aGlzLnRhcmdldC5sYXlvdXRNb2RlbDsKICAgICAgICAgICAgLy9nZXQgY2hpbGQgb2YgdGFibGVzIHdoaWNoIGFyZSBhY3R1YWxseSByb3dzCiAgICAgICAgICAgIHZhciByb3dWaWV3cyA9IF8uZmlsdGVyKHRoaXMudGFyZ2V0Ll9ub3JtYWxpemVkQ2hpbGRWaWV3cygpLCBmdW5jdGlvbiAoY2hpbGRWaWV3KSB7CiAgICAgICAgICAgICAgICBpZiAoY2hpbGRWaWV3LmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUk9XIHx8IGNoaWxkVmlldy5sYXlvdXRNb2RlbC5sYXlvdXQgPT0geGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1JJR0hUTEVGVFJPVykKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICB0aGlzLl92YWxpZENlbGxzSW5Sb3cocm93Vmlld3MpOwoKICAgICAgICAgICAgLy9pZGVudGlmeSB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgaW4gdGhlIHRhYmxlICh0aGUgZmlyc3Qgcm93IGlzIHRoZSBiZXQgdG8gZ2V0IHRoaXMgYXMKICAgICAgICAgICAgLy8gcHJldmlvdXMgcm93IHJvd3NwYW4gZG9lcyBub3QgaW1wYWN0IGl0KS4gQWRkIGFsbCBjb2xzcGFucyB0byBnZXQgdGhlIGFjdHVhbCBudW1iZXIgb2YgY29sdW1ucwogICAgICAgICAgICB2YXIgbnVtQ29sdW1ucyA9IDA7CiAgICAgICAgICAgIF8uZWFjaChyb3dWaWV3cywgZnVuY3Rpb24gKHJvd1ZpZXcsIHJvd0luZGV4KSB7CiAgICAgICAgICAgICAgICBfLmVhY2gocm93Vmlldy5fbm9ybWFsaXplZENoaWxkVmlld3MoKSwgZnVuY3Rpb24gKGNlbGxWaWV3LCBjZWxsSW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICBpZihyb3dJbmRleCA9PSAwKXsKICAgICAgICAgICAgICAgICAgICAgICAgbnVtQ29sdW1ucys9dGhpcy5nZXRPckVsc2UoY2VsbFZpZXcubGF5b3V0TW9kZWwuY29sc3BhbiwgMSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICAvL2luaXRpbGFpemUgdGhlIGNvbHVtbnMgdG8gYW4gX19lbXB0eSBzdHJpbmcsIGFuZCB0aGUgZW5kIG9mIHByb2Nlc3NpbmcgdGFibGUgd2lsbCBub3QKICAgICAgICAgICAgICAgIC8vY29udGFpbiBhbnkgX19lbXB0eSBjZWxscwogICAgICAgICAgICAgICAgZGF0YVByZXNlbmNlVGFibGVbcm93SW5kZXhdID0gW107CiAgICAgICAgICAgICAgICBmb3IodmFyIGk9MDtpPG51bUNvbHVtbnM7aSsrKSB7CiAgICAgICAgICAgICAgICAgICAgZGF0YVByZXNlbmNlVGFibGVbcm93SW5kZXhdW2ldID0gIl9fZW1wdHkiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LHRoaXMpOwoKCiAgICAgICAgICAgIC8vUG9wdWxhdGUgdGhlIGRhdGFQcmVzZW5jZVRhYmxlIHdpdGggdGhlIElEcyBmb3IgaGVhZGVyIGFuZCBkYXRhIGNlbGwgLSByZXF1aXJlZCB0byBhc3NvY2lhdGUgdGhlIGhlYWRlcnMKICAgICAgICAgICAgLy8gd2l0aCB0aGUgZGF0YSBjZWxscy4gQWxzbyBwb3B1bGF0ZSB0aGUgaGVpZ2h0IHRhYmxlcyBuZWVkZWQgZm9yIGZvcm1hdHRpbmcgdGhlIHRhYmxlLgogICAgICAgICAgICBfLmVhY2gocm93Vmlld3MsIGZ1bmN0aW9uIChyb3dWaWV3LCByb3dJbmRleCkgewogICAgICAgICAgICAgICAgXy5lYWNoKHJvd1ZpZXcuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uIChjZWxsVmlldywgY2VsbEluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGxMYXlvdXQgPSBjZWxsVmlldy5sYXlvdXRNb2RlbDsKICAgICAgICAgICAgICAgICAgICB2YXIgcm93c3BhbiA9IHRoaXMuZ2V0T3JFbHNlKGNlbGxMYXlvdXQucm93c3BhbiwgMSk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbHNwYW4gPSB0aGlzLmdldE9yRWxzZShjZWxsTGF5b3V0LmNvbHNwYW4sIDEpOwogICAgICAgICAgICAgICAgICAgIGlmIChjb2xzcGFuID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgY29scGFuIGlzIC0xLCB0aGVuIHNldCBpdCB0byByZW1haW5pbmcgZ3JpZCBsZW5ndGgKICAgICAgICAgICAgICAgICAgICAgICAgY29sc3BhbiA9IHRoaXMuX3RhYmxlQ2VsbEdyaWQubGVuZ3RoIC0gY2VsbFZpZXcuZWZmZWN0aXZlQ2VsbEluZGV4OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZihyb3dzcGFuID09IDEpewogICAgICAgICAgICAgICAgICAgICAgICBpZihoZWlnaHRUYWJsZVtyb3dJbmRleF0gPT0gdW5kZWZpbmVkIHx8IGNlbGxWaWV3LmxheW91dE1vZGVsLmV4dGVudGggPiBoZWlnaHRUYWJsZVtyb3dJbmRleF0gKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHRUYWJsZVtyb3dJbmRleF0gPSBjZWxsVmlldy5sYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2VsbFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50aCA8IGNlbGxWaWV3LmxheW91dE1vZGVsLmluaXRpYWxoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodFRhYmxlW3Jvd0luZGV4XSA9IGNlbGxWaWV3LmxheW91dE1vZGVsLmluaXRpYWxoOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBhY3R1YWxDb2x1bW5JbmRleCA9IDA7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW1Db2x1bW5zOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoZGF0YVByZXNlbmNlVGFibGVbcm93SW5kZXhdW2ldID09ICJfX2VtcHR5IikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBqPTA7ajxjb2xzcGFuO2orKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcih2YXIgaz0wO2s8cm93c3BhbjtrKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2VsbFZpZXcuZWwubm9kZU5hbWUgPT0gIlRIIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2VsbFZpZXcuX2lzUGFydE9mSGVhZGVyUm93KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhUHJlc2VuY2VUYWJsZVtyb3dJbmRleCtrXVthY3R1YWxDb2x1bW5JbmRleCtqXSA9ICJUQ0g6IitjZWxsVmlldy5faWQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFQcmVzZW5jZVRhYmxlW3Jvd0luZGV4K2tdW2FjdHVhbENvbHVtbkluZGV4K2pdID0gIlRSSDoiK2NlbGxWaWV3Ll9pZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFQcmVzZW5jZVRhYmxlW3Jvd0luZGV4K2tdW2FjdHVhbENvbHVtbkluZGV4K2pdID0gIlREQzoiK2NlbGxWaWV3Ll9pZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihjb2xzcGFuID09IDEpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYod2lkdGhUYWJsZVthY3R1YWxDb2x1bW5JbmRleF0gPT0gdW5kZWZpbmVkIHx8IGNlbGxWaWV3LmxheW91dE1vZGVsLmV4dGVudHcgPiB3aWR0aFRhYmxlW2FjdHVhbENvbHVtbkluZGV4XSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aFRhYmxlW2FjdHVhbENvbHVtbkluZGV4XSA9IGNlbGxWaWV3LmxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3R1YWxDb2x1bW5JbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGxheW91dE1vZGVsLmV4dGVudGggPSAwOwogICAgICAgICAgICAgICAgICAgIGxheW91dE1vZGVsLmV4dGVudHcgPSAwOwogICAgICAgICAgICAgICAgICAgIF8uZWFjaChoZWlnaHRUYWJsZSwgZnVuY3Rpb24oaGVpZ2h0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxheW91dE1vZGVsLmV4dGVudGgrPWhlaWdodCA7CiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgIF8uZWFjaCh3aWR0aFRhYmxlLCBmdW5jdGlvbih3aWR0aCkgewogICAgICAgICAgICAgICAgICAgICAgICBsYXlvdXRNb2RlbC5leHRlbnR3Kz13aWR0aDsKICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICAvL3NldCB0aGUgcm93IGFuZCBjZWxsIGhlaWdodCBmcm9tIGhlaWdodCB0YWJsZSB0byBrZWVwIGFsbCBjZWxscyBzeW1tZXRyaWMKICAgICAgICAgICAgLy9hbHNvIGFkZCB0aGUgaGVhZGVycyBhdHRyaWJ1dGUgdG8gdGhlIHZpZXcKICAgICAgICAgICAgXy5lYWNoKHJvd1ZpZXdzLCBmdW5jdGlvbiAocm93Vmlldywgcm93SW5kZXgpIHsKICAgICAgICAgICAgICAgIHZhciByb3dQYWRYID0gcm93Vmlldy5sYXlvdXQuX3RhcmdldFBhZGRpbmdYKCk7CiAgICAgICAgICAgICAgICB2YXIgcm93UGFkWSA9IHJvd1ZpZXcubGF5b3V0Ll90YXJnZXRQYWRkaW5nWSgpOwogICAgICAgICAgICAgICAgcm93Vmlldy5sYXlvdXRNb2RlbC5leHRlbnRoID0gIGhlaWdodFRhYmxlW3Jvd0luZGV4XTsKCiAgICAgICAgICAgICAgICAvL3Byb2Nlc3MgdGhlIGluZm8gdG8gZ2V0IHJvdyBoZWlnaHRzLCBjb2x1bW4gaGVpZ2h0cyBhbmQgZmlyc3QgY2VsbAogICAgICAgICAgICAgICAgXy5lYWNoKHJvd1ZpZXcuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uIChjZWxsVmlldywgY2VsbEluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGhlYWRlcnMgPSB0aGlzLmdldEhlYWRlcihjZWxsVmlldy5faWQsZGF0YVByZXNlbmNlVGFibGUpOwogICAgICAgICAgICAgICAgICAgIGlmKGhlYWRlcnMgIT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbFZpZXcuJGVsLmF0dHIoJ2hlYWRlcnMnLCBoZWFkZXJzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYoY2VsbFZpZXcubGF5b3V0TW9kZWwucm93c3BhbiA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGxWaWV3LmxheW91dE1vZGVsLmV4dGVudGggPSAgaGVpZ2h0VGFibGVbcm93SW5kZXhdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIGNlbGxWaWV3LmxheW91dE1vZGVsLmJvcmRlcnRvcCAvIDIuMAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBjZWxsVmlldy5sYXlvdXRNb2RlbC5ib3JkZXJib3R0b20gLyAyLjA7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGxWaWV3LmludmFsaWRhdGVEaXNwbGF5KCk7CgogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB9LHRoaXMpOwogICAgICAgICAgICB9LHRoaXMpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICB1cGRhdGVEaXNwbGF5IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnZpZXcubGF5b3V0LlRhYmxlTGF5b3V0LnByb3RvdHlwZS51cGRhdGVEaXNwbGF5LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLnRhcmdldC5lbCwgeyJib3JkZXItc3BhY2luZyI6IjAifSk7CiAgICAgICAgICAgIC8vIExDLTM5MTE2NjggOiBTYWZhcmkgZG9lcyBub3QgdXBkYXRlIHRoZSBkaXNwbGF5IHdoZW4gYSBET00gY2hhbmdlIGlzIGRvbmUgaW4gYSB0YWJsZToKICAgICAgICAgICAgaWYoeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmlzU2FmYXJpKCkpIHsKICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0LiRlbC5oaWRlKCkuY3NzKCJoZWlnaHQiKTt0aGlzLnRhcmdldC4kZWwuc2hvdygpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0sIHRoaXMpOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sICQsIHhmYWxpYikgewogICAgeGZhbGliLnZpZXcubGF5b3V0LlN0YXRpY0xheW91dCA9IHhmYWxpYi52aWV3LmxheW91dC5MYXlvdXRCYXNlLmV4dGVuZCh7CgogICAgICAgIG1lYXN1cmVTaXplIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgZ3Jvd2FibGVPZmZzZXRIID0gMCwgZ3Jvd2FibGVBc3NpZ25lZEgsIG5ld09mZnNldDsKICAgICAgICAgICAgdmFyIGluaXRpYWxHcm93YWJsZUJvdHRvbSA9IC0xOwogICAgICAgICAgICB2YXIgZ3Jvd2FibGVWaWV3ID0gdGhpcy50YXJnZXQuZ3Jvd2FibGVWaWV3OwogICAgICAgICAgICB2YXIgbGF5b3V0TW9kZWwgPSB0aGlzLnRhcmdldC5sYXlvdXRNb2RlbDsKICAgICAgICAgICAgdmFyIGdyb3dGID0gMDsKICAgICAgICAgICAgaWYgKCFfLmlzRW1wdHkoZ3Jvd2FibGVWaWV3KSkgewogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBncm93YWJsZVZpZXcubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKGdyb3dhYmxlVmlld1tpXS5sYXlvdXRNb2RlbC5leHRlbnRoIC0gZ3Jvd2FibGVWaWV3W2ldLmxheW91dE1vZGVsLmluaXRpYWxoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgZ3Jvd0YgPSBpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBncm93YWJsZUFzc2lnbmVkSCA9IGdyb3dhYmxlVmlld1tncm93Rl0ubGF5b3V0TW9kZWwuaW5pdGlhbGg7CiAgICAgICAgICAgICAgICBuZXdPZmZzZXQgPSBncm93YWJsZVZpZXdbZ3Jvd0ZdLmxheW91dE1vZGVsLmV4dGVudGggLSBncm93YWJsZUFzc2lnbmVkSDsKICAgICAgICAgICAgICAgIGluaXRpYWxHcm93YWJsZUJvdHRvbSA9IGdyb3dhYmxlVmlld1tncm93Rl0ubGF5b3V0TW9kZWwuZXh0ZW50eSArIGdyb3dhYmxlQXNzaWduZWRIOwoKICAgICAgICAgICAgICAgIC8vYnVnIzM0NzU1NjYsIG1ha2UgYW4gZXhjZXB0aW9uIGZvciBmaXJzdCBwYWdlIGFuZCByZW5kZXIgaXQgZXZlbiBpZiB0aGVyZSBpcyBubyBjb250ZW50LgogICAgICAgICAgICAgICAgaWYgKCF0aGlzLnRhcmdldC5fZm9yY2VWaWV3KCkgJiYKICAgICAgICAgICAgICAgICAgICBncm93YWJsZVZpZXdbZ3Jvd0ZdLmxheW91dE1vZGVsLmV4dGVudGggPD0gKGdyb3dhYmxlVmlld1tncm93Rl0ubGF5b3V0TW9kZWwubWFyZ2ludG9wICsgZ3Jvd2FibGVWaWV3W2dyb3dGXS5sYXlvdXRNb2RlbC5tYXJnaW5ib3R0b20pKSB7CiAgICAgICAgICAgICAgICAgICAgLy9BbGwgdGhlIGNoaWxkcmVuIG9mIGdyb3dhYmxlIHN1YmZvcm0gaGF2ZSBlaXRoZXIgYmVlbiByZW1vdmVkIG9yIGJlZW4gaGlkZGVuLiBTbyBzZXQgaXQncyBoZWlnaHQgdG8gemVybyBhcyB3ZWxsLgogICAgICAgICAgICAgICAgICAgIGdyb3dhYmxlT2Zmc2V0SCA9IC1sYXlvdXRNb2RlbC5pbml0aWFsaDsKICAgICAgICAgICAgICAgICAgICBsYXlvdXRNb2RlbC5tZWFzdXJlZGRpc3BsYXkgPSAiaGlkZGVuIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChuZXdPZmZzZXQgPiAwIHx8ICghdGhpcy5feGZhVmlld1JlZ2lzdHJ5KCkucGFnaW5nQ29uZmlnKCkuc2hyaW5rUGFnZURpc2FibGVkICYmCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0Ll9mb3JtRG9tUm9vdCgpLmhvc3QubnVtUGFnZXMgPiAxKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvL0lmIHZpZXcgaGFzIG92ZXJncm93biBvcgogICAgICAgICAgICAgICAgICAgICAgICAvL3BhZ2VTaHJpbmsgaXMgZW5hYmxlZCBhbmQgdG90YWwgbnVtYmVyIG9mIHBhZ2VzIGFyZSBtb3JlIHRoYXQgb25lIHRoZW4gY2hhbmdlIHRoZSBncm93YWJsZU9mZlNldCBhbmQgbW92ZSBldmVyeXRoaW5nLgogICAgICAgICAgICAgICAgICAgICAgICBncm93YWJsZU9mZnNldEggPSBuZXdPZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdPZmZzZXQgPCAwICYmIHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgeGZhbGliLnZpZXcuUGFnZVZpZXcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0Ll9mb3JtRG9tUm9vdCgpLmhvc3QucGFnaW5nTWFuYWdlci5hdXRvUmVuZGVyUGFnZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGxheW91dE1vZGVsLm1lYXN1cmVkZGlzcGxheSA9ICJibG9jayI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHBhcmVudFBhZExlZnQgPSB0aGlzLl90YXJnZXRQYWRkaW5nWCgpOwogICAgICAgICAgICB2YXIgcGFyZW50UGFkVG9wID0gdGhpcy5fdGFyZ2V0UGFkZGluZ1koKTsKICAgICAgICAgICAgdmFyIG9sZEV4dGVudEggPSBsYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICB2YXIgY29udGFpbmVySCA9IGxheW91dE1vZGVsLmluaXRpYWxoICsgZ3Jvd2FibGVPZmZzZXRIOwogICAgICAgICAgICBfLmVhY2godGhpcy50YXJnZXQuY2hpbGRWaWV3cywgZnVuY3Rpb24gKGNoaWxkVmlldywgaW5kZXgpIHsKICAgICAgICAgICAgICAgIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHggPSBwYXJlbnRQYWRMZWZ0ICsgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHg7CiAgICAgICAgICAgICAgICBpZiAoY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHkgPj0gaW5pdGlhbEdyb3dhYmxlQm90dG9tKSB7CiAgICAgICAgICAgICAgICAgICAgY2hpbGRWaWV3LmxheW91dE1vZGVsLm1lYXN1cmVkeSA9IHBhcmVudFBhZFRvcCArIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnR5ICsgZ3Jvd2FibGVPZmZzZXRIOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjaGlsZFZpZXcubGF5b3V0TW9kZWwubWVhc3VyZWR5ID0gcGFyZW50UGFkVG9wICsgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihsYXlvdXRNb2RlbC5tZWFzdXJlZGRpc3BsYXkgIT09ICJoaWRkZW4iKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkVmlldy5tb2RlbCAmJiBjaGlsZFZpZXcubW9kZWwuanNvbk1vZGVsICYmIGNoaWxkVmlldy5tb2RlbC5qc29uTW9kZWwucHJlc2VuY2UgIT09ICJoaWRkZW4iICYmCiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHkgKyBjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50aCA+IGNvbnRhaW5lckgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVySCA9IGNoaWxkVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHkgKyBjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50aAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICBsYXlvdXRNb2RlbC5leHRlbnRoID0gY29udGFpbmVySDsKICAgICAgICAgICAgaWYgKG9sZEV4dGVudEggIT0gbGF5b3V0TW9kZWwuZXh0ZW50aCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZ2V0Um9vdFZpZXcgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS5yb290U3ViZm9ybVZpZXc7CiAgICAgICAgfSwKCiAgICAgICAgcmVuZGVyTmV4dFBhZ2UgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuX2dldFJvb3RWaWV3KCkucmVuZGVyRGVmZXJyZWRQYWdlKCk7CiAgICAgICAgfSwKCiAgICAgICAgdXBkYXRlRGlzcGxheSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgeGZhbGliLnZpZXcubGF5b3V0LkxheW91dEJhc2UucHJvdG90eXBlLnVwZGF0ZURpc3BsYXkuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgaWYgKHRoaXMuZ2V0T3JFbHNlKHRoaXMudGFyZ2V0LCAibGF5b3V0TW9kZWwubWVhc3VyZWRkaXNwbGF5IiwgIiIpID09ICJoaWRkZW4iKSB7CiAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy50YXJnZXQuZWwsIHsiZGlzcGxheSIgOiAiaGlkZGVuIn0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMudGFyZ2V0LmVsLCB7ImRpc3BsYXkiIDogImJsb2NrIn0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pCn0pKF8sICQsIHhmYWxpYik7CgoKCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LmxheW91dC5TdWJmb3JtU2V0TGF5b3V0ID0geGZhbGliLnZpZXcubGF5b3V0LkxheW91dEJhc2UuZXh0ZW5kKHsKICAgICAgICBtZWFzdXJlU2l6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIC8vU3ViZm9ybXNldCBzaG91bGQgYWx3YXlzIHJldHVybiB0cnVlIHNob3cgdGhhdCBtZWFzdXJlU2l6ZSgwIG9mIHBhcmVudCBpcyBjYWxsZWQuCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0sCgogICAgICAgIGludmFsaWRhdGVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgaWYodGhpcy50YXJnZXQucGFyZW50Vmlldyl7CiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldC5wYXJlbnRWaWV3LmludmFsaWRhdGVTaXplKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIH0pCn0pKF8sICQsIHhmYWxpYik7CgoKCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LmxheW91dC5Sb290U3ViZm9ybUxheW91dCA9IHhmYWxpYi52aWV3LmxheW91dC5MYXlvdXRCYXNlLmV4dGVuZCh7CiAgICAgICAgbWVhc3VyZVNpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgdXBkYXRlRGlzcGxheSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9KQp9KShfLCAkLCB4ZmFsaWIpOwoKCgoKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy5sYXlvdXQuTGF5b3V0TWFuYWdlciA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewogICAgICAgIExBWU9VVF9FUlJPUl9NQVJHSU4gOiAxLAoKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnV0LkNsYXNzLnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuX2ludmFsaWRTaXplUSA9IFtdOwogICAgICAgICAgICB0aGlzLl9pbnZhbGlkRGlzcGxheVEgPSBbXTsKICAgICAgICAgICAgdGhpcy5fdmFsaWRhdGluZ1NpemUgPSBmYWxzZTsKICAgICAgICAgICAgdGhpcy5fdmFsaWRhdGluZ0Rpc3BsYXkgPSBmYWxzZTsKICAgICAgICAgICAgdGhpcy5fdmFsaWRhdGlvblBlbmRpbmcgPSBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBpbnZhbGlkYXRlU2l6ZSA6IGZ1bmN0aW9uKHZpZXcpewogICAgICAgICAgICBpZih0aGlzLl92YWxpZGF0aW5nRGlzcGxheSAmJiB2aWV3ICYmIHZpZXcgaW5zdGFuY2VvZiBPYmplY3QpewogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5lcnJvcigieGZhVmlldyIsICJpbnZhbGlkYXRlU2l6ZSBpcyBjYWxsZWQgd2hpbGUgdmFsaWRhdGluZ0Rpc3BsYXkgaXMgcnVubmluZyB3aGljaCBpcyBhbiBpc3N1ZS4gaWQiICsgdmlldy5faWQgKwogICAgICAgICAgICAgICAgICAgICIsIHBhcmVudCBpZDoiKyAodmlldy5wYXJlbnRWaWV3ICYmICh2aWV3LnBhcmVudFZpZXcgaW5zdGFuY2VvZiBPYmplY3QpKSA/IHZpZXcucGFyZW50Vmlldy5faWQgOiB2aWV3LnBhcmVudFZpZXcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZighdGhpcy5fdmFsaWRhdGluZ1NpemUgJiYgIXRoaXMuX3ZhbGlkYXRpb25QZW5kaW5nKXsKICAgICAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRpb25QZW5kaW5nID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHZhciB0aW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgICAgICB0aGF0LnRyaWdnZXJWYWxpZGF0aW9uKCk7CiAgICAgICAgICAgICAgICB9LCAxKTsKICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5jbGVhclRpbWVvdXRPbkRlc3Ryb3kodGltZW91dCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBmb3VuZCA9IHRoaXMuaXNQZW5kaW5nVmFsaWRhdGVTaXplKHZpZXcpOwogICAgICAgICAgICBpZighZm91bmQpewogICAgICAgICAgICAgICAgdGhpcy5faW52YWxpZFNpemVRLnB1c2godmlldyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBpbnZhbGlkYXRlRGlzcGxheSA6IGZ1bmN0aW9uKHZpZXcpewogICAgICAgICAgICB2YXIgZm91bmQgPSBfLmZpbmQodGhpcy5faW52YWxpZERpc3BsYXlRLCBmdW5jdGlvbihpbnZhbGlkVmlldyl7CiAgICAgICAgICAgICAgICBpZihpbnZhbGlkVmlldyA9PSB2aWV3KXsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlmKCFmb3VuZCl7CiAgICAgICAgICAgICAgICB0aGlzLl9pbnZhbGlkRGlzcGxheVEucHVzaCh2aWV3KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHRyaWdnZXJWYWxpZGF0aW9uIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgaWYodGhpcy5fdmFsaWRhdGluZ1NpemUpewogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5kZWJ1ZygieGZhVmlldyIsICJ2YWxpZGF0aW9uIGlzIGFscmVhZHkgcnVubmluZyIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRpb25QZW5kaW5nID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRpbmdTaXplID0gdHJ1ZTsKICAgICAgICAgICAgd2hpbGUodGhpcy5faW52YWxpZFNpemVRLmxlbmd0aCA+IDApewogICAgICAgICAgICAgICAgdmFyIHZpZXcgPSB0aGlzLl9pbnZhbGlkU2l6ZVEuc2hpZnQoKTsKICAgICAgICAgICAgICAgIHZpZXcuX3ZhbGlkYXRlU2l6ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRpbmdTaXplID0gZmFsc2U7CiAgICAgICAgICAgIGlmICh0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS5yb290U3ViZm9ybVZpZXcuX2Zvcm1Eb21Sb290KCkuX21vZGVsSW5pdGlhbGl6ZSA9PT0gJ0lOSVRJQUxJWkVEJykgewogICAgICAgICAgICAgICAgdGhpcy5feGZhVmlld1JlZ2lzdHJ5KCkucm9vdFN1YmZvcm1WaWV3Ll9mb3JtRG9tUm9vdCgpLmZvcm0uZXhlY0xheW91dFJlYWR5KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRpbmdEaXNwbGF5ID0gdHJ1ZTsKICAgICAgICAgICAgd2hpbGUodGhpcy5faW52YWxpZERpc3BsYXlRLmxlbmd0aCA+MCl7CiAgICAgICAgICAgICAgICB2YXIgdmlldyA9IHRoaXMuX2ludmFsaWREaXNwbGF5US5zaGlmdCgpOwogICAgICAgICAgICAgICAgdmlldy5fdmFsaWRhdGVEaXNwbGF5KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5fdmFsaWRhdGluZ0Rpc3BsYXkgPSBmYWxzZTsKCiAgICAgICAgICAgICBpZiAoZm9ybUJyaWRnZSAmJiB4ZmFsaWIuZ2xvYmFscy5oaWdobGlnaHQpICAgLy8gaGlnaExpZ2h0IG5ld2x5IGFkZGVkIGZpZWxkcwogICAgICAgICAgICAgICAgJChmb3JtQnJpZGdlKS50cmlnZ2VyKCJ4ZmFMYXlvdXRDb21wbGV0ZSIpOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUxheW91dCA6IGZ1bmN0aW9uKHZpZXcpewogICAgICAgICAgICB2YXIgb3B0aW9ucyA9IHt0YXJnZXQ6dmlld30gOwogICAgICAgICAgICBpZih2aWV3IGluc3RhbmNlb2YgeGZhbGliLnZpZXcuUm9vdFN1YmZvcm1WaWV3KQogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIudmlldy5sYXlvdXQuUm9vdFN1YmZvcm1MYXlvdXQob3B0aW9ucyk7CiAgICAgICAgICAgIGVsc2UgaWYodmlldyBpbnN0YW5jZW9mIHhmYWxpYi52aWV3LlBhZ2VWaWV3ICkKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnZpZXcubGF5b3V0LlN0YXRpY0xheW91dChvcHRpb25zKTsKICAgICAgICAgICAgZWxzZSBpZih2aWV3IGluc3RhbmNlb2YgeGZhbGliLnZpZXcuQ29udGVudEFyZWFWaWV3KQogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIudmlldy5sYXlvdXQuVG9wQm90dG9tTGF5b3V0KG9wdGlvbnMpOwogICAgICAgICAgICBlbHNlIGlmKHZpZXcgaW5zdGFuY2VvZiB4ZmFsaWIudmlldy5TdWJmb3JtU2V0VmlldykKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnZpZXcubGF5b3V0LlN1YmZvcm1TZXRMYXlvdXQob3B0aW9ucyk7CiAgICAgICAgICAgIGVsc2UgaWYodmlldy5lbC5ub2RlTmFtZSA9PSAiVFIiKQogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIudmlldy5sYXlvdXQuRGF0YVRhYmxlUm93TGF5b3V0KG9wdGlvbnMpOwoKICAgICAgICAgICAgdmFyIGxheW91dCA9IG51bGw7CiAgICAgICAgICAgIHN3aXRjaCAodmlldy5sYXlvdXRNb2RlbC5sYXlvdXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX0xFRlRSSUdIVFRPUEJPVFRPTToKICAgICAgICAgICAgICAgICAgICBsYXlvdXQgPSBuZXcgeGZhbGliLnZpZXcubGF5b3V0LkxlZnRSaWdodExheW91dChvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1JJR0hUTEVGVFRPUEJPVFRPTToKICAgICAgICAgICAgICAgICAgICBsYXlvdXQgPSBuZXcgeGZhbGliLnZpZXcubGF5b3V0LlJpZ2h0TGVmdExheW91dChvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1RPUEJPVFRPTToKICAgICAgICAgICAgICAgICAgICBsYXlvdXQgPSBuZXcgeGZhbGliLnZpZXcubGF5b3V0LlRvcEJvdHRvbUxheW91dChvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1RBQkxFOgogICAgICAgICAgICAgICAgICAgIGxheW91dCA9IG5ldyB4ZmFsaWIudmlldy5sYXlvdXQuVGFibGVMYXlvdXQob3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9ST1c6CiAgICAgICAgICAgICAgICAgICAgbGF5b3V0ID0gbmV3IHhmYWxpYi52aWV3LmxheW91dC5Sb3dMYXlvdXQob3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9SSUdIVExFRlRST1c6CiAgICAgICAgICAgICAgICAgICAgbGF5b3V0ID0gbmV3IHhmYWxpYi52aWV3LmxheW91dC5SaWdodExlZnRSb3dMYXlvdXQob3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9EQVRBVEFCTEU6CiAgICAgICAgICAgICAgICAgICAgbGF5b3V0ID0gbmV3IHhmYWxpYi52aWV3LmxheW91dC5EYXRhVGFibGVMYXlvdXQob3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0IDoKICAgICAgICAgICAgICAgICAgICBsYXlvdXQgPSBuZXcgeGZhbGliLnZpZXcubGF5b3V0LlBvc2l0aW9uTGF5b3V0KG9wdGlvbnMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBsYXlvdXQ7CiAgICAgICAgfSwKCiAgICAgICAgaXNQZW5kaW5nVmFsaWRhdGVTaXplIDogZnVuY3Rpb24odmlldyl7CiAgICAgICAgICAgIHJldHVybiAodGhpcy5faW52YWxpZFNpemVRLmluZGV4T2YodmlldykgID4gLTEpOwogICAgICAgIH0sCgogICAgICAgIF94ZmFWaWV3UmVnaXN0cnkgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy54ZmFWaWV3UmVnaXN0cnk7ICAgIC8vVE9ETzogcmVtb3ZlIHdpbmRvdyBkZXBlbmRlbmN5CiAgICAgICAgfSwKICAgICAgICAvKgogICAgICAgICAqIENoZWNrcyB3aGV0aGVyIGFueSB2aWV3IGhhcyBhbnkga2luZCBvZiBsYXlvdXQgYWN0aXZpdHkgcGVuZGluZyBlaXRoZXIgaW4gbWVhc3VyZSBvciB1cGRhdGUgcGhhc2UuCiAgICAgICAgICovCiAgICAgICAgaXNMYXlvdXRDeWNsZUNvbXBsZXRlIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuICEodGhpcy5faW52YWxpZFNpemVRLmxlbmd0aCAgPiAwIHx8IHRoaXMuX2ludmFsaWREaXNwbGF5US5sZW5ndGggPiAwKTsKICAgICAgICB9CgogICAgfSkKfSkoXywgJCwgeGZhbGliKTsKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgeGZhbGliLnZpZXcuWGZhVmlld0V2ZW50ID0gewogICAgICAgIFBSRVNFTkNFX0NIQU5HRSA6ICJwcmVzZW5jZUNoYW5nZSIsCiAgICAgICAgRVhURU5UX0NIQU5HRSA6ICJleHRlbnRDaGFuZ2UiCiAgICB9Cn0pKF8sICQsIHhmYWxpYik7CgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3Lk9iamVjdFZpZXcgPSB4ZmFsaWIudXQuRXZlbnRDbGFzcy5leHRlbmQoewoKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi51dC5FdmVudENsYXNzLnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuaWQgPSB0aGlzLm9wdGlvbnMuaWQ7CiAgICAgICAgICAgIHRoaXMuJGVsID0gKHRoaXMub3B0aW9ucy5lbCBpbnN0YW5jZW9mICQpID8gdGhpcy5vcHRpb25zLmVsIDogJCh0aGlzLm9wdGlvbnMuZWwpOwogICAgICAgICAgICB0aGlzLmVsID0gdGhpcy4kZWxbMF07CiAgICAgICAgICAgIHRoaXMuX2xheW91dE1hbmFnZXIgPSB0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS5sYXlvdXRNYW5hZ2VyKCk7CiAgICAgICAgfSwKCiAgICAgICAgLy8galF1ZXJ5IGRlbGVnYXRlIGZvciBlbGVtZW50IGxvb2t1cCwgc2NvcGVkIHRvIERPTSBlbGVtZW50cyB3aXRoaW4gdGhlCiAgICAgICAgLy8gY3VycmVudCB2aWV3LiBUaGlzIHNob3VsZCBiZSBwcmVmZXJlZCB0byBnbG9iYWwgbG9va3VwcyB3aGVyZSBwb3NzaWJsZS4KICAgICAgICAkOiBmdW5jdGlvbihzZWxlY3RvcikgewogICAgICAgICAgICByZXR1cm4gdGhpcy4kZWwuZmluZChzZWxlY3Rvcik7CiAgICAgICAgfSwKCiAgICAgICAgX2Zvcm1Eb21Sb290IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB4ZmFsaWIuc2NyaXB0LlhmYS5JbnN0YW5jZTsgLy9UT0RPOiBSZW1vdmUgc2luZ2xldG9uIGRlcGVuZGVuY3kKICAgICAgICB9LAoKICAgICAgICBfYmluZCA6IGZ1bmN0aW9uKGNvbnRleHQsIGZ1bmMpIHsKICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF94ZmFWaWV3UmVnaXN0cnkgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy54ZmFWaWV3UmVnaXN0cnk7ICAgIC8vVE9ETzogcmVtb3ZlIHdpbmRvdyBkZXBlbmRlbmN5CiAgICAgICAgfSwKCiAgICAgICAgX21tMnB4IDogZnVuY3Rpb24obW1TaXplKXsKICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi52aWV3LnV0aWwuU3R5bGVzLl9tbTJweChtbVNpemUpOwogICAgICAgIH0sCgogICAgICAgIF9jb252ZXJ0VG9QeCA6IGZ1bmN0aW9uKHNpemUpewogICAgICAgICAgICByZXR1cm4geGZhbGliLnZpZXcudXRpbC5TdHlsZXMuX2NvbnZlcnRUb1B4KHNpemUpOwogICAgICAgIH0sCgogICAgICAgIGdldE9yRWxzZSA6IHhmYWxpYi51dC5DbGFzcy5wcm90b3R5cGUuZ2V0T3JFbHNlLCAvL3Nob3J0IGN1dCBidXQgcmVhbGx5IG5lZWRlZCB0byBhdm9pZCBkdXBsaWNhdGUgY29kZS4gTWF5IGJlIGJldHRlciB3YXkgbmV4dCB0aW1lLgoKICAgICAgICBqcUlkOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuanFJZCwKCiAgICAgICAgbWF0Y2hKc29uVHlwZTogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLm1hdGNoSnNvblR5cGUsCgogICAgICAgICRkYXRhIDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLiRkYXRhLAoKICAgICAgICAkY3NzIDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLiRjc3MKCiAgICB9KTsKCn0pKF8sICQsIHhmYWxpYik7CihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgdmFyIEJhc2VWaWV3ID0geGZhbGliLnZpZXcuQmFzZVZpZXcgPSAgeGZhbGliLnZpZXcuT2JqZWN0Vmlldy5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHhmYWxpYi52aWV3Lk9iamVjdFZpZXcucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5faWQgPSB0aGlzLmVsLmlkOwogICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplZCA9IGZhbHNlOwogICAgICAgICAgICB0aGlzLnBhcmVudFZpZXcgPSB0aGlzLm9wdGlvbnMucGFyZW50VmlldzsKICAgICAgICAgICAgdGhpcy50YWJsZUNlbGxJbmRleCA9IHRoaXMub3B0aW9ucy50YWJsZUNlbGxJbmRleCB8fCAwOwogICAgICAgICAgICB0aGlzLmVmZmVjdGl2ZUNlbGxJbmRleCA9IDA7CiAgICAgICAgICAgIHRoaXMubW9kZWwgPSBudWxsOwogICAgICAgICAgICB0aGlzLmxheW91dE1vZGVsID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5faW52YWxpZFNpemVGbGFnID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5faW52YWxpZERpc3BsYXlGbGFnID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5fcmVzaXphYmxlID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuZWRnZVByZXNlbmNlID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy4kZGF0YSh0aGlzLmVsLCAieGZhVmlldyIsIHRoaXMpOwogICAgICAgICAgICBpZih0aGlzLl9pZCkKICAgICAgICAgICAgICAgIHRoaXMubW9kZWwgPSB0aGlzLl9mb3JtRG9tUm9vdCgpLl94ZmFUZW1wbGF0ZUNhY2hlLmdldE1vZGVsKHRoaXMuX2lkKTsKICAgICAgICAgICAgaWYodGhpcy5tb2RlbCl7CiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZUJvcmRlcigpOwogICAgICAgICAgICAgICAgaWYodGhpcy5tb2RlbC5wcmVzZW5jZSA9PSAidmlzaWJsZSIpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5pdEhhbmRsZXIgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUV2ZW50OiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihldm50Ll9wcm9wZXJ0eSA9PSAicHJlc2VuY2UiICYmICF0aGF0Ll9pbml0aWFsaXplZCl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5faW5pdExheW91dCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoYXQuX2luaXRpYWxpemVkKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5tb2RlbC5vZmYoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwgaW5pdEhhbmRsZXIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZih0aGF0Ll9pbml0aWFsaXplZCl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9UaGUgb25seSBjYXNlIHdoZW4gaW5pdEhhbmRsZXIgY2FuIGJlIGNhbGxlZCBldmVuIGlmIGl0J3MgaW5pdGlhbGl6ZWQgaXMgaW4gY2FzZSBvZiBzZXJ2ZXIgc2lkZSBzY3JpcHRzIHdoaWNoIGNoYW5nZSBwcmVzZW5jZSBvbiBzZXJ2ZXIuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9idXQgZG9lcyBub3QgY2FsbCBpbml0SGFuZGxlciBhdCB0aGF0IHRpbWUuIFNvIHdlIG5lZWQgdG8gcmVtb3ZlIGluaXRIYW5kbGVyIGV4cGxpY2l0bHkgaW4gbmV4dCBjYWxsLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQubW9kZWwub2ZmKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsIGluaXRIYW5kbGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELCBpbml0SGFuZGxlcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9uKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwgdGhpcyk7CgoKICAgICAgICAgICAgfQoKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVCb3JkZXIgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgYm9yZGVyID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCJib3JkZXIiLDAsdHJ1ZSksCiAgICAgICAgICAgICAgICBmaWxsLAogICAgICAgICAgICAgICAgY29sb3IsCiAgICAgICAgICAgICAgICBlZGdlOwogICAgICAgICAgICBpZihib3JkZXIpewogICAgICAgICAgICAgICAgaWYoKGZpbGwgPSBib3JkZXIuZ2V0RWxlbWVudCgiZmlsbCIsMCx0cnVlKSkgJiYgKGNvbG9yID0gZmlsbC5nZXRFbGVtZW50KCJjb2xvciIsMCx0cnVlKSkKICAgICAgICAgICAgICAgICAgICAmJiBmaWxsLnByZXNlbmNlIT0iaGlkZGVuIgogICAgICAgICAgICAgICAgICAgICYmIGZpbGwucHJlc2VuY2UgIT0iaW52aXNpYmxlIgogICAgICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gY29sb3IudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgaWYoY29sb3IgPT0gIiIpCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPSIyNTUsMjU1LDI1NSI7ICAgICAvLyBpZiBubyBjb2xvciB2YWx1ZSBpcyBzcGVjaWZpZWQgdGhlbiBmaWxsIGRlZmF1bHQgY29sb3IKICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJyZ2IoIiArIGNvbG9yICsgIikiOwogICAgICAgICAgICAgICAgICAgICQodGhpcy5lbCkuY3NzKCJiYWNrZ3JvdW5kLWNvbG9yIiwgY29sb3IpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBhbGxFZGdlSGlkZGVuID0gdHJ1ZSwKICAgICAgICAgICAgICAgIGluZGV4ID0gMCwKICAgICAgICAgICAgICAgIGVkZ2U7CiAgICAgICAgICAgICAgICB3aGlsZShlZGdlID0gYm9yZGVyLmdldEVsZW1lbnQoImVkZ2UiLGluZGV4LHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYoZWRnZS5wcmVzZW5jZSE9ImhpZGRlbiIgJiYgIGVkZ2UucHJlc2VuY2UhPSJpbnZpc2libGUiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFsbEVkZ2VIaWRkZW4gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGluZGV4Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihib3JkZXIucHJlc2VuY2UgPT0gInZpc2libGUiCiAgICAgICAgICAgICAgICAgICAgJiYgIWFsbEVkZ2VIaWRkZW4pIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY3NzU3R5bGVPYmogPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5nZXRTdHlsZUZvckJvcmRlcihib3JkZXIpOwogICAgICAgICAgICAgICAgICAgIGlmKGNzc1N0eWxlT2JqKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuZWwsIGNzc1N0eWxlT2JqKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIExDLTM5MTAzODAgOiBJbiBjYXNlIGJvcmRlciBwcmVzZW5jZSBvciBlZGdlIHByZXNlbmNlIGlzIGludmlzaWJsZSBvciBoaWRkZW4gdGhlbiBtYXJraW5nIGJvcmRlciBhcyBub25lCiAgICAgICAgICAgICAgICAgICAgaWYoYm9yZGVyLnByZXNlbmNlPT0iaGlkZGVuIgogICAgICAgICAgICAgICAgICAgICAgICB8fCBib3JkZXIucHJlc2VuY2U9PSJpbnZpc2libGUiCiAgICAgICAgICAgICAgICAgICAgICAgIHx8IGFsbEVkZ2VIaWRkZW4pewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzLmVsKS5jc3MoImJvcmRlciIsICJub25lIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuZWRnZVByZXNlbmNlID0gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgLy9nZW5lcmljIGZ1bmN0aW9uIHRvIGNvbXB1dGUgY3NzIHN0eWxlIGZyb20gdGhlIDxmb250PiAmIDxwYXJhPiBlbGVtZW50IG9mIHRoZSBtb2RlbAogICAgICAgIF9nZXRUZXh0U3R5bGUgOiBmdW5jdGlvbihyZWZlcmVuY2VNb2RlbCkgewogICAgICAgICAgICB2YXIgY3NzU3R5bGVPYmo9e307CiAgICAgICAgICAgIHZhciBhc3BhcmFTdHlsZXNPYmogPSB7fTsKCiAgICAgICAgICAgIHZhciBmb250RWxlbWVudCA9IHJlZmVyZW5jZU1vZGVsLmdldEVsZW1lbnQoJ2ZvbnQnLDAsdHJ1ZSk7CiAgICAgICAgICAgIGlmKGZvbnRFbGVtZW50KSB7CiAgICAgICAgICAgICAgICBjc3NTdHlsZU9ialsnZm9udC1mYW1pbHknXSA9IGZvbnRFbGVtZW50LmdldEF0dHJpYnV0ZSgndHlwZWZhY2UnKTsKICAgICAgICAgICAgICAgIGNzc1N0eWxlT2JqWydmb250LXNpemUnXSAgID0gdGhpcy5fY29udmVydFRvUHgoZm9udEVsZW1lbnQuZ2V0QXR0cmlidXRlKCdzaXplJykpOwogICAgICAgICAgICAgICAgY3NzU3R5bGVPYmpbJ2ZvbnQtc3R5bGUnXSAgPSBmb250RWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3Bvc3R1cmUnKTsKICAgICAgICAgICAgICAgIGNzc1N0eWxlT2JqWydmb250LXdlaWdodCddID0gZm9udEVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3ZWlnaHQnKTsKICAgICAgICAgICAgICAgIGNzc1N0eWxlT2JqWyd0ZXh0LWRlY29yYXRpb24nXSA9IGZvbnRFbGVtZW50LmdldEF0dHJpYnV0ZSgndW5kZXJsaW5lJykgIT0gMCA/ICd1bmRlcmxpbmUnIDogdW5kZWZpbmVkOwoKICAgICAgICAgICAgICAgIHZhciBmaWxsID0gZm9udEVsZW1lbnQuZ2V0RWxlbWVudCgnZmlsbCcsMCx0cnVlKTsKICAgICAgICAgICAgICAgIGlmKGZpbGwpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY29sb3IgPSBmaWxsLmdldEVsZW1lbnQoJ2NvbG9yJywwLHRydWUpOwogICAgICAgICAgICAgICAgICAgIHZhciBjb2xvclZhbHVlID0gY29sb3IudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgaWYoY29sb3JWYWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBjc3NTdHlsZU9ialsnY29sb3InXSA9ICdyZ2IoJytjb2xvclZhbHVlKycpJzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBwYXJhID0gcmVmZXJlbmNlTW9kZWwuZ2V0RWxlbWVudCgncGFyYScsMCx0cnVlKTsKICAgICAgICAgICAgaWYocGFyYSkgewogICAgICAgICAgICAgICAgaWYocGFyYS5oQWxpZ24pICB7CiAgICAgICAgICAgICAgICAgICAgYXNwYXJhU3R5bGVzT2JqWydyaWdodCddPSB0aGlzLl9jb252ZXJ0VG9QeChwYXJhLm1hcmdpblJpZ2h0KTsKICAgICAgICAgICAgICAgICAgICBhc3BhcmFTdHlsZXNPYmpbJ2xlZnQnXT0gdGhpcy5fY29udmVydFRvUHgocGFyYS5tYXJnaW5MZWZ0KTsKICAgICAgICAgICAgICAgICAgICBhc3BhcmFTdHlsZXNPYmpbJ292ZXJmbG93J109ICJoaWRkZW4iOwogICAgICAgICAgICAgICAgICAgIHN3aXRjaChwYXJhLmhBbGlnbikgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJyaWdodCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3BhcmFTdHlsZXNPYmpbJ3RleHQtYWxpZ24nXT0gInJpZ2h0IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJsZWZ0IjoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAicmFkaXgiOiAgLy9UaWxsIG5vdyByYWRpeCBpcyBub3QgaW1wbGVtZW50ZWQsIGl0IGlzIG1hcHBlZCB0byB0aGUgZGVmYXVsdCBvbmUgaS5lIGxlZnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcGFyYVN0eWxlc09ialsndGV4dC1hbGlnbiddPSAibGVmdCI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAiY2VudGVyIjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcGFyYVN0eWxlc09ialsndGV4dC1hbGlnbiddPSAiY2VudGVyIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJqdXN0aWZ5IjoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAianVzdGlmeUFsbCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3BhcmFTdHlsZXNPYmpbJ3RleHQtYWxpZ24nXT0gImp1c3RpZnkiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc3dpdGNoKHBhcmEudkFsaWduKSB7CiAgICAgICAgICAgICAgICAgICBjYXNlICJ0b3AiOgogICAgICAgICAgICAgICAgICAgICAgIGFzcGFyYVN0eWxlc09ialsndG9wJ109IHRoaXMuX2NvbnZlcnRUb1B4KHBhcmEuc3BhY2VBYm92ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICBjYXNlICJib3R0b20iOgogICAgICAgICAgICAgICAgICAgICAgIGFzcGFyYVN0eWxlc09ialsnYm90dG9tJ109IHRoaXMuX2NvbnZlcnRUb1B4KHBhcmEuc3BhY2VCZWxvdyk7CiAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhc3BhcmFTdHlsZXNPYmpbJ3RleHQtaW5kZW50J10gPSB0aGlzLl9jb252ZXJ0VG9QeChwYXJhLnRleHRJbmRlbnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB7Zm9udFN0eWxlcyA6IGNzc1N0eWxlT2JqLCBwYXJhU3R5bGVzIDogIGFzcGFyYVN0eWxlc09ian07CiAgICAgICAgfSwKCiAgICAgICAgX2NvbnZlcnRYRkFSaWNoVG9IdG1sOiBmdW5jdGlvbih0ZXh0KXsKICAgICAgICAgICAgdmFyIHZhbHVlOwogICAgICAgICAgICBpZih0ZXh0ICE9IG51bGwpICB7CiAgICAgICAgICAgICBpZih0eXBlb2YgdGV4dCA9PSAnc3RyaW5nJyAmJiB0ZXh0WzBdICE9ICc8JykgewogICAgICAgICAgICAgICAgIHRleHQgPSAiPHNwYW4+Iit0ZXh0KyI8L3NwYW4+IjsgICAvLyAkLnJlcGxhY2VXaXRoIGV4cGVjdHMgYSBIVE1MIHN0cmluZwogICAgICAgICAgICAgfQoKICAgICAgICAgICAgIC8vLS1jb252ZXJzaW9uIHRvIGpRdWVyeSBvYmogdG8gaGFuZGxlIGZvbnQtc2l6ZSBvZiBzcGFuCiAgICAgICAgICAgICB2YXIgc3BhblRleHQgPSAkKHRleHQpOwogICAgICAgICAgICAgc3BhblRleHQuZmluZCgiKiIpLmVhY2goZnVuY3Rpb24oaW5kZXgsIHNwYW4pewogICAgICAgICAgICAgICAgICBpZihzcGFuLnN0eWxlKSB7CiAgICAgICAgICAgICAgICAgICAgICBpZihzcGFuLnN0eWxlLmZvbnRTaXplKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5fY29udmVydFRvUHgoc3Bhbi5zdHlsZS5mb250U2l6ZSkrInB4IjsKICAgICAgICAgICAgICAgICAgICAgICAgc3Bhbi5zdHlsZVsnZm9udC1zaXplJ10gPSBzcGFuLnN0eWxlLmZvbnRTaXplID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICB0ZXh0PSAiPHNwYW4+IitzcGFuVGV4dC5odG1sKCkrIjwvc3Bhbj4iOwogICAgICAgICAgIH0KICAgICAgICAgICByZXR1cm4gdGV4dDsKICAgICAgICB9LAoKICAgICAgICBfaW5pdEFjY2Vzc2liaWxpdHlJbmZvOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgLy9hY2Nlc3NpYmlsaXR5IGluZm8KCiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0TW9kZWwuY29sc3BhbiA+IDEpIHsKICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoImNvbHNwYW4iLCB0aGlzLmxheW91dE1vZGVsLmNvbHNwYW4pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0TW9kZWwucm93c3BhbiA+IDEpIHsKICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvd3NwYW4iLCB0aGlzLmxheW91dE1vZGVsLnJvd3NwYW4pOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBUT0RPIC0gbW92ZSB0aGVzZSB0YWJsZSByZWxhdGVkIHN0dWZmIHRvIHRhYmxlIHZpZXcKICAgICAgICAgICAgLy9UaGUgYmVsb3cgcm9sZXMgYXJlIG5vdCBjb25mbGljdGluZyB3aXRoIHRoZSBuYXRpdmUgYWNjZXNzaWJpbGl0eSBzdXBwb3J0IGludHJvZHVjZWQgaW4gRGF0YVRhYmxlcywgYnV0CiAgICAgICAgICAgIC8vbm90IHJlY29tbWVuZGVkIHVudGlsIHNjcmlwdGVkIGRhdGEgZWxlbWVudCBpcyB1c2VkIChSZWZlciB0bzogaHR0cDovL3d3dy53My5vcmcvVFIvYXJpYS1pbi1odG1sLykuCiAgICAgICAgICAgIC8vV2l0aCB0aGUgaW50cm9kdWN0aW9uIG9mIHJvdy1zcGFuIGFuZCByb3cgaGVhZGVyIC0gdGhlIGN1cnJlbnQgaW5mbyBpcyBub3QgY29tcGxldGUgZm9yIEFSSUEtUm9sZXMKICAgICAgICAgICAgLy9TbyBpZiBuYXRpdmUgSFRNTCB0YWJsZSBpcyBiZWluZyB1c2VkIGZvciByZW5kZXIgKERhdGFUYWJsZUxheW91dCwgZG8gbm90IGFkZCB0aGUgQVJJQS1Sb2xlcyBiZWxvdykuCiAgICAgICAgICAgIC8vIC0gTm8gY2hhbmdlIHJlcXVpcmVkIGZvciB0YWJsZSBhcyBsYXlvdXQgZm9yIERhdGFUYWJsZSBpcyAgREFUQV9MQVlPVVRfVEFCTEUKICAgICAgICAgICAgLy8gLSBEbyBub3QgYWRkIGFjY2Vzc2liaWxpdHkgZm9yICdjb2x1bW5oZWFkZXInIG9yICdncmlkY2VsbCcgaWYgbm9kZSBpcyBUSCBvciBUUiAodGhlIGNoZWNrIHdpbGwgYWxzbyBhdm9pZCB0aGUgaW5lZmZpY2llbnQgY2hlY2spCiAgICAgICAgICAgIC8vIC0gRG8gbm90IGFkZCB0aGUgYWNjZXNzaWJpbGl0eSBmb3IgJ3JvdycgaWYgbm9kZSBpcyBUUgogICAgICAgICAgICB2YXIgbm9kZU5hbWUgPSB0aGlzLmVsLm5vZGVOYW1lOwogICAgICAgICAgICB2YXIgcGFydE9mTmF0aXZlVGFibGUgPSAobm9kZU5hbWUgPT0gIlRBQkxFIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBub2RlTmFtZSA9PSAiVFIiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IG5vZGVOYW1lID09ICJURCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgbm9kZU5hbWUgPT0gIlRIIik7CgogICAgICAgICAgICBpZighcGFydE9mTmF0aXZlVGFibGUpIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfVEFCTEUpIHsKICAgICAgICAgICAgICAgICAgICAvL3B1dCBncmlkIHJvbGUKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJyb2xlIiwgImdyaWQiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX2lzVGFibGVIZWFkZXJDZWxsKCkpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJyb2xlIiwgImNvbHVtbmhlYWRlciIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5faXNUYWJsZUNlbGwoKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvbGUiLCAiZ3JpZGNlbGwiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMubGF5b3V0TW9kZWwubGF5b3V0ID09IHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9ST1cpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJyb2xlIiwgInJvdyIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5sYXlvdXRNb2RlbC5sYXlvdXQgPT0geGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1JJR0hUTEVGVFJPVykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvbGUiLCAicm93Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9hZGQgcm9sZSBhbmQgdGl0bGUgdG8gdGhpcy4kZWwKICAgICAgICAgICAgdmFyIGFzc2lzdCA9IHRoaXMubW9kZWwuZ2V0RWxlbWVudCgiYXNzaXN0IiwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIGlmKGFzc2lzdCAmJiBhc3Npc3Qucm9sZSkgewogICAgICAgICAgICAgICAgLy90cmFuc2xhdGUgWEZBIHJvbGVzIHRvIEhUTUw1IHJvbGVzIChXQXJpYSByb2xlcykKICAgICAgICAgICAgICAgIGlmKGFzc2lzdC5yb2xlID09ICdUUicgJiYgIXBhcnRPZk5hdGl2ZVRhYmxlKQogICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvbGUiLCAicm93Iik7CiAgICAgICAgICAgICAgICBlbHNlIGlmKGFzc2lzdC5yb2xlID09ICdUSCcpewogICAgICAgICAgICAgICAgICAgIC8vZG8gbm90aGluZyBhcyBoZWFkZXIgaW5mbyBpcyB0byBiZSBwcm9wYWdhdGVkIHRvIGluZGl2aWR1YWwgY2VsbHMKICAgICAgICAgICAgICAgICAgICAvL3RoaXMuJGVsLmF0dHIoInJvbGUiLCAicm93Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKGFzc2lzdC5yb2xlID09ICdURicpewogICAgICAgICAgICAgICAgICAgIC8vZG8gbm90aGluZyBhcyBoZWFkZXIgaW5mbyBpcyB0byBiZSBwcm9wYWdhdGVkIHRvIGluZGl2aWR1YWwgY2VsbHMKICAgICAgICAgICAgICAgICAgICAvL3RoaXMuJGVsLmF0dHIoInJvbGUiLCAicm93Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKCFwYXJ0T2ZOYXRpdmVUYWJsZSkgewogICAgICAgICAgICAgICAgICAgIC8vIGxpc3Qgcm9sZSBuZWVkcyB0byBiZSB1c2VkIGZvciBhIGRpdiB3aXRoIGxpc3Qgb2YgaXRlbXMgYW5kIGxpc3RpdGVtIHJvbGUgZm9yIGl0cyBjaGlsZHJlbi4KICAgICAgICAgICAgICAgICAgICBpZihhc3Npc3Qucm9sZSA9PSAnVUwnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvbGUiLCAibGlzdCIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZihhc3Npc3Qucm9sZSA9PSAiTEkiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvbGUiLCAibGlzdGl0ZW0iKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJyb2xlIiwgYXNzaXN0LnJvbGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG5vZGVOYW1lID09PSAiVEFCTEUiKSB7CiAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJhcmlhLWxhYmVsIiwgdGhpcy5fZ2V0U2NyZWVuUmVhZGVyVGV4dCgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9hZGQgbGFuZyBwYXJhbWV0ZXIKICAgICAgICAgICAgdmFyIGxhbmcgPSB0aGlzLl9sYW5nRnJvbUxvY2FsZSh0aGlzLm1vZGVsLmpzb25Nb2RlbC5sb2NhbGUpOwogICAgICAgICAgICBpZihsYW5nICYmIGxhbmcubGVuZ3RoID4gMCl7CiAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJsYW5nIiwgbGFuZyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX2Fzc2lnblRvb2xUaXAoKTsKICAgICAgICB9LAoKICAgICAgICBfYXNzaWduVG9vbFRpcCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICB9LAoKICAgICAgICBfZ2V0U2NyZWVuUmVhZGVyVGV4dDogZnVuY3Rpb24oKXsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBpCiAgICAgICAgICogQHBhcmFtIHZhbAogICAgICAgICAqIEByZXR1cm4ge1N0cmluZ30KICAgICAgICAgKiBAcHJpdmF0ZSB1c2VkIGJ5IFhmYURyYXdWaWV3IGFuZCBGaWVsZFZpZXcKICAgICAgICAgKi8KICAgICAgICBfYWRqdXN0VGV4dENvb3JkaW5hdGU6IGZ1bmN0aW9uKGksIHZhbCl7CiAgICAgICAgICAgIC8vc29tZWhvdyBqcXVlcnkgYXR0cigpIGZ1bmN0aW9uIGNhbm5vdCByZWFkIHRleHRMZW5ndGggYXR0cmlidXRlCiAgICAgICAgICAgIHZhciBzVGV4dExlbiA9IHRoaXMuZ2V0QXR0cmlidXRlKCd0ZXh0TGVuZ3RoJyk7CiAgICAgICAgICAgIGlmKHNUZXh0TGVuICYmIHZhbCAmJiB2YWwubGVuZ3RoID4gMikgewogICAgICAgICAgICAgICAgLy9yZW1vdmUgcHgKICAgICAgICAgICAgICAgIHZhciB0ZXh0TGVuID0gTnVtYmVyKHNUZXh0TGVuLnN1YnN0cigwLCBzVGV4dExlbi5sZW5ndGgtMikpOwogICAgICAgICAgICAgICAgdmFyIHggPSBOdW1iZXIodmFsLnN1YnN0cigwLCB2YWwubGVuZ3RoLTIpKTsKICAgICAgICAgICAgICAgIC8vc2VydmVyIGFkanVzdCB4IGZvciBhbGwgcnRsIHRleHQgY29udGVudCBzbyB3ZSBuZWVkIHRvIHJldmVydCBpdCBiYWNrIGZvciB3ZWJraXQKICAgICAgICAgICAgICAgIHggKz0gdGV4dExlbjsKICAgICAgICAgICAgICAgIHJldHVybiB4KyJweCI7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogaW50ZXJuYWwgZnVuY3Rpb24gdG8gZXh0cmFjdCBsYW5nIGZyb20gbG9jYWxlCiAgICAgICAgICovCiAgICAgICAgX2xhbmdGcm9tTG9jYWxlIDogZnVuY3Rpb24obG9jYWxlKSB7CiAgICAgICAgICAgIHZhciBsYW5nOwogICAgICAgICAgICBpZihsb2NhbGUgJiYgbG9jYWxlLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIC8vbG9jYWxlIGNhbiBiZSBpbiB0aGUgZm9ybSBvZiBjb3VudHJ5X0xBTkcgLS0gZW5fVVMKICAgICAgICAgICAgICAgIC8vV2hlcmVhcyBsYW5nIGF0dHJpYnV0ZSBvZiBodG1sIGV4cGVjdHMgb25seSBjb3VudHJ5IGNvZGUKICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IGxvY2FsZS5pbmRleE9mKCdfJyk7CgogICAgICAgICAgICAgICAgaWYoaW5kZXggIT0gLTEpewogICAgICAgICAgICAgICAgICAgIGxhbmcgPSBsb2NhbGUuc3Vic3RyKDAsIGluZGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGxhbmcgPSBsb2NhbGU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy9sZWFwIG9mIGZhaXRoIHRoYXQgbGFuZyB3b3VsZCBiZSBJU08gNjMxIGNvbXBsYWludC4KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbGFuZzsKICAgICAgICB9LAoKICAgICAgICBzZXRFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgICB0aGlzLnVuZGVsZWdhdGVFdmVudHMoKTsKICAgICAgICAgIHRoaXMuX3NldEVsZW1lbnQoZWxlbWVudCk7CiAgICAgICAgICB0aGlzLmRlbGVnYXRlRXZlbnRzKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9LAoKICAgICAgICBfc2V0RWxlbWVudDogZnVuY3Rpb24oZWwpIHsKICAgICAgICAgIHRoaXMuJGVsID0gZWwgaW5zdGFuY2VvZiAkID8gZWwgOiAkKGVsKTsKICAgICAgICAgIHRoaXMuZWwgPSB0aGlzLiRlbFswXTsKICAgICAgICB9LAoKCiAgICAgICAgZGVsZWdhdGVFdmVudHM6IGZ1bmN0aW9uKGV2ZW50cykgewogICAgICAgICAgdmFyIGRlbGVnYXRlRXZlbnRTcGxpdHRlciA9IC9eKFxTKylccyooLiopJC87CiAgICAgICAgICBldmVudHMgfHwgKGV2ZW50cyA9IF8ucmVzdWx0KHRoaXMsICdldmVudHMnKSk7CiAgICAgICAgICBpZiAoIWV2ZW50cykgcmV0dXJuIHRoaXM7CiAgICAgICAgICB0aGlzLnVuZGVsZWdhdGVFdmVudHMoKTsKICAgICAgICAgIGZvciAodmFyIGtleSBpbiBldmVudHMpIHsKICAgICAgICAgICAgdmFyIG1ldGhvZCA9IGV2ZW50c1trZXldOwogICAgICAgICAgICBpZiAoIV8uaXNGdW5jdGlvbihtZXRob2QpKSBtZXRob2QgPSB0aGlzW21ldGhvZF07CiAgICAgICAgICAgIGlmICghbWV0aG9kKSBjb250aW51ZTsKICAgICAgICAgICAgdmFyIG1hdGNoID0ga2V5Lm1hdGNoKGRlbGVnYXRlRXZlbnRTcGxpdHRlcik7CiAgICAgICAgICAgIHRoaXMuZGVsZWdhdGUobWF0Y2hbMV0sIG1hdGNoWzJdLCBfLmJpbmQobWV0aG9kLCB0aGlzKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9LAoKICAgICAgICBkZWxlZ2F0ZTogZnVuY3Rpb24oZXZlbnROYW1lLCBzZWxlY3RvciwgbGlzdGVuZXIpIHsKICAgICAgICAgIHRoaXMuJGVsLm9uKGV2ZW50TmFtZSArICcuZGVsZWdhdGVFdmVudHMnICsgdGhpcy5jaWQsIHNlbGVjdG9yLCBsaXN0ZW5lcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9LAoKICAgICAgICB1bmRlbGVnYXRlRXZlbnRzOiBmdW5jdGlvbigpIHsKICAgICAgICAgIGlmICh0aGlzLiRlbCkgdGhpcy4kZWwub2ZmKCcuZGVsZWdhdGVFdmVudHMnICsgdGhpcy5jaWQpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRMYXlvdXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgcHJlc2VuY2UgPSB0aGlzLm1vZGVsID8gdGhpcy5tb2RlbC5wcmVzZW5jZSA6ICJ2aXNpYmxlIjsKCiAgICAgICAgICAgIGlmKCF0aGlzLmxheW91dE1vZGVsKXsKICAgICAgICAgICAgICAgIC8vSWYgbGF5b3V0bW9kZWwgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkLCBpbml0aWFsaXplIHRoYXQuCiAgICAgICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplTGF5b3V0TW9kZWwoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYodGhpcy5faXNQbGFjZUhvbGRlckVsKCkgJiYgKHByZXNlbmNlID09ICJ2aXNpYmxlIiB8fCBwcmVzZW5jZSA9PSAiaW52aXNpYmxlIikpewogICAgICAgICAgICAgICAgLy8gQ3VycmVudGx5IHdlIGFyZSBvbiBhIHBsYWNlaG9sZGVyIGRpdiBlbCAoYmVjYXVzZSB0aGlzIGVsZW1lbnQgd2FzIGhpZGRlbiBvciBpbmFjdGl2ZSkuIEl0J3MgdGltZSB0byBmaW5kIHRoZSBhY3R1YWwgZWxlbWVudC4KICAgICAgICAgICAgICAgIHZhciB0ZW1wbGF0ZUlkID0gKHRoaXMubW9kZWwgPyB0aGlzLm1vZGVsLl90ZW1wbGF0ZUlkKCkgOiB0aGlzLl9pZCkgfHwgdGhpcy5faWQ7CiAgICAgICAgICAgICAgICB2YXIgYWN0dWFsRWwgPSB0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS50ZW1wbGF0ZUNhY2hlKCkuZ2V0KHRlbXBsYXRlSWQsIHRydWUpOwogICAgICAgICAgICAgICAgaWYoYWN0dWFsRWwpewogICAgICAgICAgICAgICAgICAgIC8vIGhpZGVzIHRoZSBhY3R1YWxFTCBhcyB0aGUgbGF5b3V0IGlzIHN0aWxsIGRpc3R1cmJlZCwgcmVtb3ZlcyB0aGUgaGlkZUVsZW1lbnQgY2xhc3Mgb24gdXBkYXRlRGlzcGxheQogICAgICAgICAgICAgICAgICAgICQoYWN0dWFsRWwpLmFkZENsYXNzKCJoaWRlRWxlbWVudCIpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLnJlcGxhY2VXaXRoKGFjdHVhbEVsKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQoYWN0dWFsRWwpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuJGRhdGEodGhpcy5lbCwgInhmYVZpZXciLCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplTGF5b3V0TW9kZWwoKTsgLy9uZWVkIHRvIHJlLWluaXRpYWxpemUgbGF5b3V0IG1vZGVsIGF0IHRoaXMgcG9pbnQuCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5lcnJvcigieGZhVmlldyIsICJIdG1sIHRlbXBsYXRlIGNvdWxkIG5vdCBiZSBmb3VuZC4gaWQ6Iit0aGlzLl9pZCsiLCBzb206Iit0aGlzLmdldE9yRWxzZSh0aGlzLm1vZGVsLCAic29tRXhwcmVzc2lvbiIpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYocHJlc2VuY2UgPT0gInZpc2libGUiKXsKICAgICAgICAgICAgICAgIHZhciBub2RlTmFtZSA9ICIiOwogICAgICAgICAgICAgICAgaWYodGhpcy5tb2RlbCl7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbml0QWNjZXNzaWJpbGl0eUluZm8oKTsKICAgICAgICAgICAgICAgICAgICBub2RlTmFtZSA9IHRoaXMubW9kZWwuZ2V0QXR0cmlidXRlKCJuYW1lIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBhcyBwYXJ0IG9mIGh0bWwgc2l6ZSByZWR1Y3Rpb24sIHNlcnZlciBzdG9wcGVkIHNlbmRpbmcgbm9kZSB0eXBlIGFuZCBuYW1lIG9mIHRoZSBjb21wb25lbnQKICAgICAgICAgICAgICAgIC8vIGFkZCBjbGFzc2VzIGZvciB0aGUgc2FtZQogICAgICAgICAgICAgICAgdmFyIG5vZGVUeXBlID0gKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS4kZGF0YSh0aGlzLmVsLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5YRkFfTU9ERUwpIHx8e30pW3hmYWxpYi52aWV3LkxheW91dENvbnN0Lk5PREVfVFlQRV07CiAgICAgICAgICAgICAgICBpZihub2RlVHlwZSkKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hZGRDbGFzcyhub2RlVHlwZSk7CiAgICAgICAgICAgICAgICBpZihub2RlTmFtZSAhPSBudWxsICYmIG5vZGVOYW1lLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hZGRDbGFzcyhub2RlTmFtZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgZXh0ZW50ID0gdGhpcy5fY29tcHV0ZUV4dGVudCgpOwogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuZWwsIGV4dGVudCk7CiAgICAgICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7CiAgICAgICAgICAgIH0gZWxzZXsKICAgICAgICAgICAgICAgIC8vSWYgcHJlc2VuY2UgaXMgc2V0IHRvIHZpc2libGUgdGhlbiBfaGFuZGxlUHJlc2VuY2VDaGFuZ2UgaXMgY2FsbGVkIGFzIHBhcnQgb2Ygc3luYyBmcm9tIHN1YmNsYXNzZXMKICAgICAgICAgICAgICAgIC8vIEJ1dCBvdGhlcndpc2Ugd2UgbmVlZCB0byBleHBsaWNpdGxseSBjYWxsIF9oYW5kbGVQcmVzZW5jZUNoYW5nZSBoZXJlLgogICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlUHJlc2VuY2VDaGFuZ2Uoe25ld1RleHQgOiBwcmVzZW5jZX0pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRXZlbnQ6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgc3dpdGNoKGV2bnQubmFtZSkgewogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VEOgogICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlTW9kZWxDaGFuZ2VkKGV2bnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQ6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVEb21DaGFuZ2VkKGV2bnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAvKiBsb2cgYW4gZXJyb3IgbWVzc2FnZSAqLwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRG9tQ2hhbmdlZCA6IGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgc3dpdGNoKGV2ZW50Ll9wcm9wZXJ0eSkgewogICAgICAgICAgICAgICAgY2FzZSAiZm9udC5maWxsLmNvbG9yLnZhbHVlIjoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVGb250RmlsbENvbG9yVmFsdWUoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiYm9yZGVyLmZpbGwuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgY2FzZSAidGV4dEVkaXQuYm9yZGVyLmZpbGwuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgY2FzZSAibnVtZXJpY0VkaXQuYm9yZGVyLmZpbGwuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgY2FzZSAiaW1hZ2VFZGl0LmJvcmRlci5maWxsLmNvbG9yLnZhbHVlIjoKICAgICAgICAgICAgICAgIGNhc2UgInNpZ25hdHVyZS5ib3JkZXIuZmlsbC5jb2xvci52YWx1ZSI6CiAgICAgICAgICAgICAgICBjYXNlICJkYXRlVGltZUVkaXQuYm9yZGVyLmZpbGwuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgY2FzZSAicGFzc3dvcmRFZGl0LmJvcmRlci5maWxsLmNvbG9yLnZhbHVlIjoKICAgICAgICAgICAgICAgIGNhc2UgImNob2ljZUxpc3QuYm9yZGVyLmZpbGwuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUJvcmRlckZpbGxDb2xvclZhbHVlKGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgImJvcmRlci5lZGdlLnByZXNlbmNlIjoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVCb3JkZXJFZGdlUHJlc2VuY2UoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiYm9yZGVyLmVkZ2UuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUJvcmRlckNoYW5nZShldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJib3JkZXIuZWRnZS50aGlja25lc3MiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUJvcmRlckNoYW5nZShldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJib3JkZXIuZmlsbC5wcmVzZW5jZSI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQm9yZGVyRmlsbFByZXNlbmNlKGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInRvcEluc2V0IjoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVUb3BJbnNldChldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJib3R0b21JbnNldCI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQm90dG9tSW5zZXQoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAibGVmdEluc2V0IjoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVMZWZ0SW5zZXQoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAicmlnaHRJbnNldCI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlUmlnaHRJbnNldChldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYW5kbGVNb2RlbENoYW5nZWQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICBpZiAoZXZlbnQuX3Byb3BlcnR5ID09ICJwcmVzZW5jZSIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVByZXNlbmNlQ2hhbmdlKGV2ZW50KTsKICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudC5fcHJvcGVydHkgPT0gImFjY2VzcyIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUFjY2Vzc0NoYW5nZShldmVudCk7CiAgICAgICAgICAgIH1lbHNlIGlmIChldmVudC5fcHJvcGVydHkgPT0gInJlbGV2YW50IikgIHsKICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVJlbGV2YW50Q2hhbmdlKGV2ZW50KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVSZWxldmFudENoYW5nZSA6IGZ1bmN0aW9uKGV2ZW50KSB7Ci8vCQkJCXhmYS5Mb2dnZXIuZGVidWcoIltfaGFuZGxlUHJlc2VuY2VDaGFuZ2VdcHJlc2VuY2U6c29tIgovLwkJCQkJCSsgZXZlbnQubmV3VGV4dCArICI6IiArIHRoaXMuJGVsLmRhdGEoInNvbSIpKTsKICAgICAgICAgICAgc3dpdGNoIChldmVudC5uZXdUZXh0KSB7CiAgICAgICAgICAgICAgICBjYXNlICIrcHJpbnQiOgogICAgICAgICAgICAgICAgY2FzZSAicHJpbnQiIDoKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLm1vZGVsLmdldEF0dHJpYnV0ZSgicHJlc2VuY2UiKSA9PSAidmlzaWJsZSIpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWwuc3R5bGUudmlzaWJpbGl0eSA9ICJoaWRkZW4iIDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIi1wcmludCI6CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5tb2RlbC5nZXRBdHRyaWJ1dGUoInByZXNlbmNlIikgPT0gInZpc2libGUiKQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVsLnN0eWxlLnZpc2liaWxpdHkgPSAidmlzaWJsZSI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMucGFyZW50Vmlldy5pbnZhbGlkYXRlU2l6ZSgpOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVQcmVzZW5jZUNoYW5nZSA6IGZ1bmN0aW9uKGV2ZW50KSB7Ci8vCQkJCXhmYS5Mb2dnZXIuZGVidWcoIltfaGFuZGxlUHJlc2VuY2VDaGFuZ2VdcHJlc2VuY2U6c29tIgovLwkJCQkJCSsgZXZlbnQubmV3VGV4dCArICI6IiArIHRoaXMuJGVsLmRhdGEoInNvbSIpKTsKICAgICAgICAgICAgc3dpdGNoIChldmVudC5uZXdUZXh0KSB7CiAgICAgICAgICAgIGNhc2UgInZpc2libGUiOgogICAgICAgICAgICAgICAgaWYodGhpcy5tb2RlbC5nZXRBdHRyaWJ1dGUoInJlbGV2YW50IikgPT0gInByaW50IiB8fCB0aGlzLm1vZGVsLmdldEF0dHJpYnV0ZSgicmVsZXZhbnQiKSA9PSAiK3ByaW50IikKICAgICAgICAgICAgICAgICAgICB0aGlzLmVsLnN0eWxlLnZpc2liaWxpdHkgPSAiaGlkZGVuIiA7CiAgICAgICAgICAgICAgICBlbHNlIHRoaXMuZWwuc3R5bGUudmlzaWJpbGl0eT0gImluaGVyaXQiOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImludmlzaWJsZSI6CiAgICAgICAgICAgIGNhc2UgImhpZGRlbiI6CiAgICAgICAgICAgIGNhc2UgImluYWN0aXZlIjoKICAgICAgICAgICAgICAgIHRoaXMuZWwuc3R5bGUudmlzaWJpbGl0eSA9ICJoaWRkZW4iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aGlzLmVsLnN0eWxlLnZpc2liaWxpdHk9ICJpbmhlcml0IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICBGT1JNUy0xMTM2MyA6IGZpeCBmb3IgaGVpZ2h0IGNhbGN1bGF0aW9uIG9mIHRhYmxlIGNlbGwKICAgICAgICAgICAgIEVuYWJsZSB0aGlzIHRvZ2dsZSBmb3Igb2xkIGJlaGF2aW91ciAoaWYgYW55IHJlZ3Jlc3Npb24gY29tZXMpCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoKHdpbmRvdy5GRCAmJiB3aW5kb3cuRkQuaXNUb2dnbGVFbmFibGVkKCJGVF9GT1JNUy0xMTM2MyIpKSAmJiB4ZmFsaWIucnVudGltZS54ZmEuZm9ybS5tYkluaXRpYWxpemVkKSB7CiAgICAgICAgICAgICAgICB0aGlzLnBhcmVudFZpZXcuaW52YWxpZGF0ZVNpemUoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMucGFyZW50Vmlldy5pbnZhbGlkYXRlU2l6ZSgpOwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVSaWdodEluc2V0IDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlQm90dG9tSW5zZXQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAvKnZhciBib3R0b21JbnNldCA9IHBhcnNlRmxvYXQoZXZlbnQucHJldlRleHQpIDsKICAgICAgICAgICAgIGlmKGJvdHRvbUluc2V0KSAgewogICAgICAgICAgICAgdmFyIGV4dGVudCA9IHRoaXMuX2NvbXB1dGVFeHRlbnQoKTsKICAgICAgICAgICAgIGV4dGVudFsibWFyZ2luLWJvdHRvbSJdID0gIHRoaXMuX21tMnB4KDI1LjQqIGJvdHRvbUluc2V0KSA7CiAgICAgICAgICAgICB0aGlzLmxheW91dE1vZGVsLm1hcmdpbmJvdHRvbSA9IGV4dGVudFsibWFyZ2luLWJvdHRvbSJdOwogICAgICAgICAgICAgdGhpcy5faW52YWxpZERpc3BsYXlGbGFnID0gdHJ1ZTsKICAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRlRGlzcGxheSgpOwogICAgICAgICAgICAgdmFyIGE9IHRoaXMubWVhc3VyZVNpemUoKTsKICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLmVsLCBleHRlbnQpOwogICAgICAgICAgICAgfSAqLwoKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlTGVmdEluc2V0IDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlVG9wSW5zZXQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVGb250RmlsbENvbG9yVmFsdWUgOiBmdW5jdGlvbihldmVudCkgewoKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlQm9yZGVyRmlsbENvbG9yVmFsdWUgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICB2YXIgYm9yZGVyRmlsbENvbG9yVmFsdWUgPSBldmVudC5wcmV2VGV4dDsKICAgICAgICAgICAgdmFyIHZpc2liaWxpdHkgPSAgdGhpcy5tb2RlbC5ib3JkZXIuZmlsbC5wcmVzZW5jZSA7CgogICAgICAgICAgICBpZihib3JkZXJGaWxsQ29sb3JWYWx1ZSAmJiB2aXNpYmlsaXR5ICE9ICJpbnZpc2libGUiICYmIHZpc2liaWxpdHkgIT0gImhpZGRlbiIpICB7CiAgICAgICAgICAgICAgICBpZihib3JkZXJGaWxsQ29sb3JWYWx1ZS5pbmRleE9mKCJyZ2IiKSA9PSAtMSkKICAgICAgICAgICAgICAgICAgICBib3JkZXJGaWxsQ29sb3JWYWx1ZSA9ICJyZ2IoIiArIGJvcmRlckZpbGxDb2xvclZhbHVlICsgIikiOwoKICAgICAgICAgICAgICAgIGlmIChfLmNvbnRhaW5zKFsidGV4dEVkaXQiLCJudW1lcmljRWRpdCIsImltYWdlRWRpdCIsInNpZ25hdHVyZSIsImRhdGVUaW1lRWRpdCIsImNob2ljZUxpc3QiLAogICAgICAgICAgICAgICAgICAgICAgICAicGFzc3dvcmRFZGl0Il0sIGV2ZW50Ll9wcm9wZXJ0eS5zdWJzdHJpbmcoMCxldmVudC5fcHJvcGVydHkuaW5kZXhPZignLicpKSkpIHsKICAgICAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5jc3MoImJhY2tncm91bmQtY29sb3IiLCBib3JkZXJGaWxsQ29sb3JWYWx1ZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYoIGV2ZW50Ll9wcm9wZXJ0eSA9PT0gImJvcmRlci5maWxsLmNvbG9yLnZhbHVlIikgewogICAgICAgICAgICAgICAgICAgICQodGhpcy5lbCkuY3NzKCJiYWNrZ3JvdW5kLWNvbG9yIiwgYm9yZGVyRmlsbENvbG9yVmFsdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUJvcmRlckVkZ2VQcmVzZW5jZSA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciB2aXNpYmlsaXR5ID0gZXZlbnQucHJldlRleHQ7CiAgICAgICAgICAgIHZhciBkZWZhdWx0Qm9yZGVyID0gIjFweCBzb2xpZCByZ2IoMCwgMCwgMCkiCiAgICAgICAgICAgIGlmKHZpc2liaWxpdHkgPT0gImhpZGRlbiIgfHwgdmlzaWJpbGl0eSA9PSAiaW52aXNpYmxlIikgewogICAgICAgICAgICAgICAgJCh0aGlzLmVsKS5jc3MoImJvcmRlciIsICJub25lIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgY3NzU3R5bGVPYmogPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5nZXRTdHlsZUZvckJvcmRlcih0aGlzLm1vZGVsLmJvcmRlcik7CiAgICAgICAgICAgICAgICBpZihjc3NTdHlsZU9iaikKICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy5lbCwgY3NzU3R5bGVPYmopOwogICAgICAgICAgICAgICAgZWxzZSAkKHRoaXMuZWwpLmNzcygiYm9yZGVyIiwgZGVmYXVsdEJvcmRlcik7CiAgICAgICAgICAgIH0KCgogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVCb3JkZXJDaGFuZ2UgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICB2YXIgY3NzU3R5bGVPYmogPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5nZXRTdHlsZUZvckJvcmRlcih0aGlzLm1vZGVsLmJvcmRlcik7CiAgICAgICAgICAgIGlmKGNzc1N0eWxlT2JqKQogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuZWwsIGNzc1N0eWxlT2JqKTsKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlQm9yZGVyRmlsbFByZXNlbmNlIDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgdmFyIGJvcmRlckZpbGxQcmVzZW5jZSA9IGV2ZW50LnByZXZUZXh0OwogICAgICAgICAgICB2YXIgY29sb3IgPSB0aGlzLm1vZGVsLmJvcmRlci5maWxsLmNvbG9yLnZhbHVlOwogICAgICAgICAgICBpZihib3JkZXJGaWxsUHJlc2VuY2UgPT0gImhpZGRlbiIgfHwgYm9yZGVyRmlsbFByZXNlbmNlID09ICJpbnZpc2libGUiKXsKICAgICAgICAgICAgICAgICQodGhpcy5lbCkuY3NzKCJiYWNrZ3JvdW5kLWNvbG9yIiwgInJnYigyNTUsMjU1LDI1NSkiICkKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGlmKGNvbG9yLmluZGV4T2YoInJnYiIpID09IC0xKQogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gInJnYigiICsgY29sb3IgKyAiKSI7CiAgICAgICAgICAgICAgICAkKHRoaXMuZWwpLmNzcygiYmFja2dyb3VuZC1jb2xvciIsIGNvbG9yKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9maWxsQ29sb3IgOiBmdW5jdGlvbihjb2xvcikgewogICAgICAgICAgICAkKHRoaXMuZWwpLmNzcygiYmFja2dyb3VuZC1jb2xvciIsIGNvbG9yKQogICAgICAgIH0sCgogICAgICAgIF9ib3JkZXJDb2xvciA6IGZ1bmN0aW9uKGNvbG9yKSB7CiAgICAgICAgICAgICQodGhpcy5lbCkuY3NzKCJib3JkZXJDb2xvciIsIGNvbG9yKQogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVBY2Nlc3NDaGFuZ2UgOiBmdW5jdGlvbihldmVudCkgewoKICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIFRoaXMgbWV0aG9kIGNhbGxzIF9pbml0TGF5b3V0IGluIGFkZGl0aW9uIHRvIGNhbGxpbmcgb3JpZ2luYWwgX3N5bmNGb3JtVG9IdG1sLgogICAgICAgICAqIFRoaXMgaXMgc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIHVzaW5nIHNlcnZlciBzaWRlIHNjcmlwdHMgYW5kIGNhbGxzIGRlZXAgc3luYy4KICAgICAgICAgKiBJZiB5b3UgYXJlIHN1cmUgdGhhdCBvYmplY3QgaGFzIGJlZW4gaW5pdGlhbGl6ZWQgY2FsbCBfc3luY0Zvcm1Ub0h0bWwgZWxzZSBjYWxsIHRoaXMgbWV0aG9kLgogICAgICAgICAqIE90aGVyIG9iamVjdHMob3RoZXIgdGhhbiAqdGhpcyopIHNob3VsZCBhbHdheXMgY2FsbCB0aGlzIG1ldGhvZCBpbnN0ZWFkT2YgaW50ZXJuYWwgX3N5bmNGb3JtVG9IdG1sIG1ldGhvZC4KICAgICAgICAgKi8KICAgICAgICBzeW5jRm9ybU5vZGVUb0h0bWw6IGZ1bmN0aW9uKGRlZXBTeW5jKXsKICAgICAgICAgICAgaWYoIXRoaXMuX2luaXRpYWxpemVkICYmIHRoaXMuX2lzUGxhY2VIb2xkZXJFbCgpKXsKICAgICAgICAgICAgICAgIC8vSWYgdGhpcyBpcyB1bmluaXRpYWxpemVkIHBsYWNlSG9sZGVyRWwoaW4gY2FzZSBwcmVzZW5jZSBpcyBoaWRkZW4gaW5pdGlhbGx5IGFuZCBoYXMgbm90IGJlZW4gY2hhbmdlZCBzaW5jZQogICAgICAgICAgICAgICAgLy8gdGhlbiB3ZSB3YW50IHRvIGF0dGVtcHQgYW4gX2luaXRMYXlvdXQgdG8gY2hlY2sgaWYgcHJlc2VuY2UgbmVlZHMgdG8gYmUgaGFuZGxlZC4KICAgICAgICAgICAgICAgIHRoaXMuX2luaXRMYXlvdXQoKTsKICAgICAgICAgICAgICAgIGlmKCF0aGlzLl9pbml0aWFsaXplZCAmJiB0aGlzLl9pc1BsYWNlSG9sZGVyRWwoKSl7CiAgICAgICAgICAgICAgICAgICAgLy9JZiB0aGlzIGlzIHN0aWxsIHBsYWNlSG9sZGVyRWwgdGhlbiBubyBwb2ludCBvZiBydW5uaW5nIGEgc3luYwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl9zeW5jRm9ybU5vZGVUb0h0bWwoZGVlcFN5bmMpOwogICAgICAgIH0sCgogICAgICAgIF9zeW5jRm9ybU5vZGVUb0h0bWwgOiBmdW5jdGlvbihkZWVwU3luYykgewogICAgICAgICAgICAvLyBUT0RPIDogbWFrZSBzeW5jIGxvZ2ljIGJldHRlcgogICAgICAgICAgICBpZiAodGhpcy5tb2RlbCkgewogICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlUHJlc2VuY2VDaGFuZ2Uoe25ld1RleHQ6dGhpcy5tb2RlbC5wcmVzZW5jZX0pICA7CiAgICAgICAgICAgICAgICAvL3RoaXMuX2hhbmRsZUFjY2Vzc0NoYW5nZSh7bmV3VGV4dDp0aGlzLm1vZGVsLm1FZmZBY2Nlc3N9KSAgICAgIDsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLmludmFsaWRhdGVTaXplKCk7CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRpYWxpemVMYXlvdXRNb2RlbCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAvL0luIG9yZGVyIHRvIG1pbmltaXplIHRoZSBzaXplIG9mIGh0bWwgZ2VuZXJhdGVkLCB0aGlzIGxheW91dG1vZGVsIGlzIGdlbmVyYXRlZCBpbiBhIGNyeXB0aWMgd2F5CiAgICAgICAgICAgIC8vaGVyZSBpcyB0aGUgbWFwcGluZyBiZXR3ZWVuIHRoZSBjcnlwdGljIHZhcmlhYmxlcyBhbmQgZXhwbGFuYXRvcnkgdmFyaWFibGVzLgogICAgICAgICAgICAvL2luIHRoZSBpbnRlcmVzdCBvZiByZWFkYWJpbGl0eSwgcHJlc2VydmluZyB0aGUgZ29vZCByZWFkYWJsZSBuYW1lcwoKICAgICAgICAgICAgdmFyIGxtID0gdGhpcy5nZXRPckVsc2UodGhpcy4kZGF0YSh0aGlzLmVsLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5YRkFfTU9ERUwpLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfTU9ERUwsIHt9KQogICAgICAgICAgICB2YXIgbGF5b3V0ID0ge307CiAgICAgICAgICAgIGlmKHRoaXMgaW5zdGFuY2VvZiB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3ICYmICFsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5TVUJGT1JNX0xBWU9VVCkpewogICAgICAgICAgICAgICAgbGF5b3V0LmxheW91dCA9ICJwb3NpdGlvbiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZihsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5TVUJGT1JNX0xBWU9VVCkpIHsKICAgICAgICAgICAgICAgIGxheW91dC5sYXlvdXQgPSBsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5TVUJGT1JNX0xBWU9VVF0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9YKSkKICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnR4ID0gdGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX1hdKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbGF5b3V0LmV4dGVudHggPSAwOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9ZKSkKICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnR5ID0gdGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX1ldKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbGF5b3V0LmV4dGVudHkgPSAwOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NSU5fVykpCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWludyA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NSU5fV10pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWludyA9IC0xOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NSU5fSCkpCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWluaCA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NSU5fSF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWluaCA9IC0xOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NQVhfVykpCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWF4dyA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NQVhfV10pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWF4dyA9IC0xOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NQVhfSCkpCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWF4aCA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NQVhfSF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWF4aCA9IC0xOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9XKSkKICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnR3ID0gTWF0aC5tYXgodGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX1ddKSwgbGF5b3V0LmV4dGVudG1pbncpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50dyA9ICBNYXRoLm1heCgwLCBsYXlvdXQuZXh0ZW50bWludyk7CgogICAgICAgICAgICBpZiAobG0uaGFzT3duUHJvcGVydHkoeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX0gpKQogICAgICAgICAgICAgICAgbGF5b3V0LmV4dGVudGggPSBNYXRoLm1heCh0aGlzLl9tbTJweChsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5FWFRFTlRfSF0pLCBsYXlvdXQuZXh0ZW50bWluaCk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnRoID0gIE1hdGgubWF4KDAsIGxheW91dC5leHRlbnRtaW5oKTsKCiAgICAgICAgICAgIGlmIChsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5FWFRFTlRfQUNUVUFMX1cpKQogICAgICAgICAgICAgICAgbGF5b3V0LmV4dGVudGFjdHVhbHcgPSB0aGlzLl9tbTJweChsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5FWFRFTlRfQUNUVUFMX1ddKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbGF5b3V0LmV4dGVudGFjdHVhbHcgPSAgLTE7CgogICAgICAgICAgICBpZiAobG0uaGFzT3duUHJvcGVydHkoeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX0FDVFVBTF9IKSkKICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnRhY3R1YWxoID0gdGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX0FDVFVBTF9IXSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnRhY3R1YWxoID0gIC0xOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0Lk1BUkdJTl9UT1ApKQogICAgICAgICAgICAgICAgbGF5b3V0Lm1hcmdpbnRvcCA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0Lk1BUkdJTl9UT1BdKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbGF5b3V0Lm1hcmdpbnRvcCA9IDA7CgogICAgICAgICAgICBpZiAobG0uaGFzT3duUHJvcGVydHkoeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTUFSR0lOX1JJR0hUKSkKICAgICAgICAgICAgICAgIGxheW91dC5tYXJnaW5yaWdodCA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0Lk1BUkdJTl9SSUdIVF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQubWFyZ2lucmlnaHQgPSAwOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0Lk1BUkdJTl9CT1RUT00pKQogICAgICAgICAgICAgICAgbGF5b3V0Lm1hcmdpbmJvdHRvbSA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0Lk1BUkdJTl9CT1RUT01dKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbGF5b3V0Lm1hcmdpbmJvdHRvbSA9IDA7CgogICAgICAgICAgICBpZiAobG0uaGFzT3duUHJvcGVydHkoeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTUFSR0lOX0xFRlQpKQogICAgICAgICAgICAgICAgbGF5b3V0Lm1hcmdpbmxlZnQgPSB0aGlzLl9tbTJweChsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5NQVJHSU5fTEVGVF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQubWFyZ2lubGVmdCA9IDA7CgogICAgICAgICAgICBpZiAobG0uaGFzT3duUHJvcGVydHkoeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuQk9SREVSX1RPUCkpCiAgICAgICAgICAgICAgICBsYXlvdXQuYm9yZGVydG9wID0gdGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuQk9SREVSX1RPUF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuYm9yZGVydG9wID0gMDsKCiAgICAgICAgICAgIGlmIChsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5CT1JERVJfUklHSFQpKQogICAgICAgICAgICAgICAgbGF5b3V0LmJvcmRlcnJpZ2h0ID0gdGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuQk9SREVSX1JJR0hUXSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGxheW91dC5ib3JkZXJyaWdodCA9IDA7CgogICAgICAgICAgICBpZiAobG0uaGFzT3duUHJvcGVydHkoeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuQk9SREVSX0JPVFRPTSkpCiAgICAgICAgICAgICAgICBsYXlvdXQuYm9yZGVyYm90dG9tID0gdGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuQk9SREVSX0JPVFRPTV0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuYm9yZGVyYm90dG9tID0gMDsKCiAgICAgICAgICAgIGlmIChsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5CT1JERVJfTEVGVCkpCiAgICAgICAgICAgICAgICBsYXlvdXQuYm9yZGVybGVmdCA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkJPUkRFUl9MRUZUXSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGxheW91dC5ib3JkZXJsZWZ0ID0gMDsKCiAgICAgICAgICAgIGlmIChsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5DT0xfU1BBTikpCiAgICAgICAgICAgICAgICBsYXlvdXQuY29sc3BhbiA9ICtsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5DT0xfU1BBTl07CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGxheW91dC5jb2xzcGFuID0gMTsKCiAgICAgICAgICAgIGlmIChsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5ST1dfU1BBTikpCiAgICAgICAgICAgICAgICBsYXlvdXQucm93c3BhbiA9ICtsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5ST1dfU1BBTl07CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGxheW91dC5yb3dzcGFuID0gMTsKCiAgICAgICAgICAgIGlmKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkNPTFVNTl9XSURUSFMpKXsKICAgICAgICAgICAgICAgIHZhciBjb2xXaWR0aHMgPSBsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5DT0xVTU5fV0lEVEhTXS5zcGxpdCgiICIpOwogICAgICAgICAgICAgICAgdmFyIGNhbGNXaWR0aHMgPSBfLm1hcChjb2xXaWR0aHMsCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oY29sV2lkdGgpewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW0ycHgoY29sV2lkdGgpOwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgdGhpcyk7CiAgICAgICAgICAgICAgICBsYXlvdXQuY29sdW1ud2lkdGhzID0gY2FsY1dpZHRoczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYodGhpcy5faXNUYWJsZUNlbGwoKSl7CiAgICAgICAgICAgICAgICB2YXIgY29sdW1uV2lkdGggPSAtMTsKICAgICAgICAgICAgICAgIHZhciB0YWJsZUxheW91dE1vZGVsID0gdGhpcy5wYXJlbnRWaWV3LnBhcmVudFZpZXcubGF5b3V0TW9kZWw7CiAgICAgICAgICAgICAgICBpZih0YWJsZUxheW91dE1vZGVsLmNvbHVtbndpZHRocyAmJiB0YWJsZUxheW91dE1vZGVsLmNvbHVtbndpZHRocy5sZW5ndGggPj0gdGhpcy50YWJsZUNlbGxJbmRleCkKICAgICAgICAgICAgICAgICAgICBjb2x1bW5XaWR0aCA9IHRhYmxlTGF5b3V0TW9kZWwuY29sdW1ud2lkdGhzW3RoaXMudGFibGVDZWxsSW5kZXhdOwogICAgICAgICAgICAgICAgaWYoY29sdW1uV2lkdGggPj0gMCl7CiAgICAgICAgICAgICAgICAgICAgbGF5b3V0LmV4dGVudHcgPSBjb2x1bW5XaWR0aDsKICAgICAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50YWN0dWFsdyA9IGNvbHVtbldpZHRoOwogICAgICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnRtaW53ID0gMDsKICAgICAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWF4dyA9ICJub25lIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBsYXlvdXQuaW5pdGlhbGggPSBsYXlvdXQuZXh0ZW50aDsKICAgICAgICAgICAgbGF5b3V0LmluaXRpYWx3ID0gbGF5b3V0LmV4dGVudHc7CgogICAgICAgICAgICBpZihsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5DQVBfUExBQ0VNRU5UKSkKICAgICAgICAgICAgICAgIGxheW91dC5jYXB0aW9uUGxhY2VtZW50ID0gbG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuQ0FQX1BMQUNFTUVOVF07CgogICAgICAgICAgICBpZihsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5QQUdFX05VTUJFUikpCiAgICAgICAgICAgICAgICBsYXlvdXQucGFnZU51bWJlciA9IGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0LlBBR0VfTlVNQkVSXTsKCiAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwgPSBsYXlvdXQ7CiAgICAgICAgICAgIHRoaXMucmVzaXphYmxlID0gdGhpcy5sYXlvdXRNb2RlbC5leHRlbnRhY3R1YWx3IDwgMCB8fCAgdGhpcy5sYXlvdXRNb2RlbC5leHRlbnRhY3R1YWxoIDwgMDsKICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUV4dGVudCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgZXh0ZW50ID0ge30gOwogICAgICAgICAgICBleHRlbnRbIm1hcmdpbi1sZWZ0Il0gPSB0aGlzLl9tYXJnaW5MZWZ0KCk7CiAgICAgICAgICAgIGV4dGVudFsibWFyZ2luLXJpZ2h0Il0gPSB0aGlzLl9tYXJnaW5SaWdodCgpOwogICAgICAgICAgICBleHRlbnRbIm1hcmdpbi10b3AiXSA9IHRoaXMuX21hcmdpblRvcCgpOwogICAgICAgICAgICBleHRlbnRbIm1hcmdpbi1ib3R0b20iXSA9IHRoaXMuX21hcmdpbkJvdHRvbSgpOwogICAgICAgICAgICBleHRlbnRbInBhZGRpbmctbGVmdCJdID0gdGhpcy5fcGFkTGVmdCgpOwogICAgICAgICAgICBleHRlbnRbInBhZGRpbmctcmlnaHQiXSA9IHRoaXMuX3BhZFJpZ2h0KCk7CiAgICAgICAgICAgIGV4dGVudFsicGFkZGluZy10b3AiXSA9IHRoaXMuX3BhZFRvcCgpOwogICAgICAgICAgICBleHRlbnRbInBhZGRpbmctYm90dG9tIl0gPSB0aGlzLl9wYWRCb3R0b20oKTsKICAgICAgICAgICAgZXh0ZW50WyJib3JkZXItbGVmdC13aWR0aCJdID0gdGhpcy5fc3ViUGl4ZWxWYWx1ZSh0aGlzLmxheW91dE1vZGVsLmJvcmRlcmxlZnQpOwogICAgICAgICAgICBleHRlbnRbImJvcmRlci1yaWdodC13aWR0aCJdID0gdGhpcy5fc3ViUGl4ZWxWYWx1ZSh0aGlzLmxheW91dE1vZGVsLmJvcmRlcnJpZ2h0KTsKICAgICAgICAgICAgZXh0ZW50WyJib3JkZXItdG9wLXdpZHRoIl0gPSB0aGlzLl9zdWJQaXhlbFZhbHVlKHRoaXMubGF5b3V0TW9kZWwuYm9yZGVydG9wKTsKICAgICAgICAgICAgZXh0ZW50WyJib3JkZXItYm90dG9tLXdpZHRoIl0gPSB0aGlzLl9zdWJQaXhlbFZhbHVlKHRoaXMubGF5b3V0TW9kZWwuYm9yZGVyYm90dG9tKTsKICAgICAgICAgICAgZXh0ZW50WyItd2Via2l0LWJveC1zaXppbmciXSA9ICJib3JkZXItYm94IjsKICAgICAgICAgICAgZXh0ZW50WyItbW96LWJveC1zaXppbmciXSA9ICJib3JkZXItYm94IjsKICAgICAgICAgICAgZXh0ZW50WyJib3gtc2l6aW5nIl0gPSAiYm9yZGVyLWJveCI7CiAgICAgICAgICAgIGV4dGVudFsicG9zaXRpb24iXSA9ICJhYnNvbHV0ZSI7CiAgICAgICAgICAgIHJldHVybiBleHRlbnQ7CiAgICAgICAgfSwKCiAgICAgICAgX3BhZExlZnQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0TW9kZWwubWFyZ2lubGVmdAogICAgICAgICAgICAgICAgICAgIC0gdGhpcy5sYXlvdXRNb2RlbC5ib3JkZXJsZWZ0IC8gMjsKICAgICAgICB9LAoKICAgICAgICBfcGFkUmlnaHQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0TW9kZWwubWFyZ2lucmlnaHQKICAgICAgICAgICAgICAgICAgICAtIHRoaXMubGF5b3V0TW9kZWwuYm9yZGVycmlnaHQgLyAyOwogICAgICAgIH0sCgogICAgICAgIF9wYWRUb3AgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0TW9kZWwubWFyZ2ludG9wIC0gdGhpcy5sYXlvdXRNb2RlbC5ib3JkZXJ0b3AgLyAyOwogICAgICAgIH0sCgogICAgICAgIF9wYWRCb3R0b20gOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0TW9kZWwubWFyZ2luYm90dG9tCiAgICAgICAgICAgICAgICAgICAgLSB0aGlzLmxheW91dE1vZGVsLmJvcmRlcmJvdHRvbSAvIDI7CiAgICAgICAgfSwKCiAgICAgICAgX21hcmdpbkxlZnQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIC10aGlzLmxheW91dE1vZGVsLmJvcmRlcmxlZnQgLyAyOwogICAgICAgIH0sCgogICAgICAgIF9tYXJnaW5SaWdodCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gLXRoaXMubGF5b3V0TW9kZWwuYm9yZGVycmlnaHQgLyAyOwogICAgICAgIH0sCgogICAgICAgIF9tYXJnaW5Ub3AgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIC10aGlzLmxheW91dE1vZGVsLmJvcmRlcnRvcCAvIDI7CiAgICAgICAgfSwKCiAgICAgICAgX21hcmdpbkJvdHRvbSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gLXRoaXMubGF5b3V0TW9kZWwuYm9yZGVyYm90dG9tIC8gMjsKICAgICAgICB9LAoKICAgICAgICBfaXNUYWJsZUNlbGwgOiBmdW5jdGlvbigpeyAvL1RvbyBsb25nIGNoZWNrPz8/IFBsZWFzZSBzaG9ydGVuIGl0LgogICAgICAgICAgICBpZih0aGlzLnBhcmVudFZpZXcgJiYgdGhpcy5wYXJlbnRWaWV3LmxheW91dE1vZGVsICYmCiAgICAgICAgICAgICAgICAodGhpcy5wYXJlbnRWaWV3LmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUk9XIHx8IHRoaXMucGFyZW50Vmlldy5sYXlvdXRNb2RlbC5sYXlvdXQgPT0geGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1JJR0hUTEVGVFJPVykgJiYKICAgICAgICAgICAgICAgIHRoaXMucGFyZW50Vmlldy5wYXJlbnRWaWV3ICYmIHRoaXMucGFyZW50Vmlldy5wYXJlbnRWaWV3LmxheW91dE1vZGVsICYmCiAgICAgICAgICAgICAgICB0aGlzLnBhcmVudFZpZXcucGFyZW50Vmlldy5sYXlvdXRNb2RlbC5sYXlvdXQgPT0geGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1RBQkxFKXsKICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfaXNUYWJsZUhlYWRlckNlbGwgOiBmdW5jdGlvbigpeyAvL1RvbyBsb25nIGNoZWNrPz8/IFBsZWFzZSBzaG9ydGVuIGl0LgogICAgICAgICAgICBpZih0aGlzLnBhcmVudFZpZXcgJiYgdGhpcy5wYXJlbnRWaWV3LmxheW91dE1vZGVsICYmCiAgICAgICAgICAgICAgICAodGhpcy5wYXJlbnRWaWV3LmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUk9XIHx8IHRoaXMucGFyZW50Vmlldy5sYXlvdXRNb2RlbC5sYXlvdXQgPT0geGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1JJR0hUTEVGVFJPVykgJiYKICAgICAgICAgICAgICAgIHRoaXMucGFyZW50Vmlldy5tb2RlbC5nZXRFbGVtZW50KCJhc3Npc3QiLCAwLCB0cnVlKSAmJiB0aGlzLnBhcmVudFZpZXcubW9kZWwuYXNzaXN0LnJvbGUgPT0gIlRIIil7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCgogICAgICAgIC8vRm9yIGEgZ2l2ZW4gY2VsbCBpZGVudGlmeSBpZiB0aGUgY2VsbCBpcyBwYXJ0IG9mIGhlYWRlciByb3cgKFRIRUFEKQogICAgICAgIF9pc1BhcnRPZkhlYWRlclJvdyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMucGFyZW50VmlldyAmJiB0aGlzLnBhcmVudFZpZXcubGF5b3V0TW9kZWwgJiYKICAgICAgICAgICAgICAgICh0aGlzLnBhcmVudFZpZXcubGF5b3V0TW9kZWwubGF5b3V0ID09IHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9ST1cgfHwgdGhpcy5wYXJlbnRWaWV3LmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUklHSFRMRUZUUk9XKSAmJgogICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRWaWV3LmVsLnBhcmVudE5vZGUubm9kZU5hbWUgPT0gIlRIRUFEIil7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgJGNvbXB1dGVXSCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIC8vcHJpdmF0ZSBtZXRob2QgYnV0IHN0aWxsIG92ZXJyaWRkZW4gaW4gU3ViZm9ybVNldFZpZXcKICAgICAgICAgICAgdmFyIGV4dGVudCA9IHt9OwogICAgICAgICAgICAvL0lmIHRoZSBmaWVsZCBpcyBub3QgaW5pdGlhbGl6ZWQoaW52aXNpYmxlIG9yIGhpZGRlbiksIHRoZW4gdGhlcmUgaXMgbm8gbmVlZCB0byBzZXQgdy9oIGZvciBlbC4gVGhpcyB3b3VsZCBhdXRvbWF0aWNhbGx5IGJlIGRvbmUgZHVyaW5nIGluaXRpYWxpemF0aW9uIHZpYSBzeW5jCiAgICAgICAgICAgIGV4dGVudFsid2lkdGgiXSA9IHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50dyArIHRoaXMubGF5b3V0TW9kZWwuYm9yZGVybGVmdC8yICsgdGhpcy5sYXlvdXRNb2RlbC5ib3JkZXJyaWdodC8yOwogICAgICAgICAgICBleHRlbnRbImhlaWdodCJdID0gdGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoICsgdGhpcy5sYXlvdXRNb2RlbC5ib3JkZXJ0b3AvMiArIHRoaXMubGF5b3V0TW9kZWwuYm9yZGVyYm90dG9tLzIgOwogICAgICAgICAgICByZXR1cm4gZXh0ZW50OwogICAgICAgIH0sCgogICAgICAgIF9pc1BsYWNlSG9sZGVyRWwgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy4kZGF0YSh0aGlzLmVsLCAieGZhSGlkZGVuUEgiKTsKICAgICAgICB9LAoKICAgICAgICAvL2xheW91dCByZWxhdGVkIGZ1bmN0aW9ucwogICAgICAgIGludmFsaWRhdGVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdGhpcy5faW52YWxpZFNpemVGbGFnID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5fbGF5b3V0TWFuYWdlci5pbnZhbGlkYXRlU2l6ZSh0aGlzKTsKICAgICAgICAgICAgdGhpcy5pbnZhbGlkYXRlRGlzcGxheSgpOwogICAgICAgIH0sCgogICAgICAgIGludmFsaWRhdGVEaXNwbGF5IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdGhpcy5faW52YWxpZERpc3BsYXlGbGFnID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5fbGF5b3V0TWFuYWdlci5pbnZhbGlkYXRlRGlzcGxheSh0aGlzKTsKICAgICAgICB9LAoKICAgICAgICBfdmFsaWRhdGVTaXplIDogZnVuY3Rpb24ocmVjdXJzaXZlKXsKICAgICAgICAgICAgaWYodGhpcy5faW52YWxpZFNpemVGbGFnKXsKICAgICAgICAgICAgICAgIGlmKHRoaXMuX2luaXRpYWxpemVkKXsKICAgICAgICAgICAgICAgICAgICB2YXIgc2l6ZUNoYW5nZWQgPSB0aGlzLm1lYXN1cmVTaXplKCk7CiAgICAgICAgICAgICAgICAgICAgaWYoc2l6ZUNoYW5nZWQpCiAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRWaWV3LmludmFsaWRhdGVTaXplKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLl9pbnZhbGlkU2l6ZUZsYWcgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF92YWxpZGF0ZURpc3BsYXkgOiBmdW5jdGlvbihyZWN1cnNpdmUpewogICAgICAgICAgICBpZih0aGlzLl9pbnZhbGlkRGlzcGxheUZsYWcpewogICAgICAgICAgICAgICAgaWYodGhpcy5faW5pdGlhbGl6ZWQpewogICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlRGlzcGxheSgpOwogICAgICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcigibGF5b3V0Q29tcGxldGUiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX2ludmFsaWREaXNwbGF5RmxhZyA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbWVhc3VyZVNpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgY2hhbmdlZCA9IGZhbHNlOwogICAgICAgICAgICBpZighdGhpcy5yZXNpemFibGUpewogICAgICAgICAgICAgICAgaWYodGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoICE9IHRoaXMubGF5b3V0TW9kZWwuaW5pdGlhbGgpewogICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50aCA9IHRoaXMubGF5b3V0TW9kZWwuaW5pdGlhbGg7CiAgICAgICAgICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZih0aGlzLmxheW91dE1vZGVsLmV4dGVudHcgIT0gdGhpcy5sYXlvdXRNb2RlbC5pbml0aWFsdyl7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXlvdXRNb2RlbC5leHRlbnR3ID0gdGhpcy5sYXlvdXRNb2RlbC5pbml0aWFsdzsKICAgICAgICAgICAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY2hhbmdlZDsKICAgICAgICB9LAoKICAgICAgICB1cGRhdGVEaXNwbGF5IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIGV4dGVudCA9IHRoaXMuJGNvbXB1dGVXSCgpOwogICAgICAgICAgICB0aGlzLiRjc3ModGhpcy5lbCwgZXh0ZW50KTsKICAgICAgICAgICAgJCh0aGlzLmVsKS5yZW1vdmVDbGFzcygiaGlkZUVsZW1lbnQiKTsKICAgICAgICB9LAoKICAgICAgICBfc3ViUGl4ZWxWYWx1ZSA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgaWYodmFsdWUgPiAwLjAxKQogICAgICAgICAgICAgICAgcmV0dXJuIE1hdGgubWF4KHZhbHVlLCAxLjApOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBSZXR1cm4gdGhlIHBhZ2UgbnVtYmVyIGNvbnRhaW5pbmcgdGhpcyB2aWV3LgogICAgICAgICAqIE5vdGU6IHBhZ2UgbnVtYmVyIHN0YXJ0cyB3aXRoIDEgaW5zdGVhZCBvZiAwCiAgICAgICAgICovCiAgICAgICAgX3BhZ2VOdW1iZXIgOiBmdW5jdGlvbigpewogICAgICAgICAgICAvL1BhZ2UgbnVtYmVyIGlzIHBhc3NlZCBhcyBhcmd1bWVudCB0byBjcmVhdGVWaWV3IGFuZCBpcyBhdmFpbGFibGUgaW4gb3B0aW9ucwogICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcywgIm9wdGlvbnMucGFnZU51bWJlciIsIC0xKTsKICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqIEZvY3VzZXMgdGhlIHdpZGdldCBvZiB0aGUgcHJvdmlkZWQgdmlldy4KICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gdmlldyA6IHZpZXcgd2hvc2Ugd2lkZ2V0IG5lZWRzIHRvIGJlIGZvY3Vzc2VkLgogICAgICAgICAqLwogICAgICAgIF9mb2N1c1dpZGdldCA6IGZ1bmN0aW9uICh2aWV3KSB7CiAgICAgICAgICAgIHZhciBqcVdpZGdldCA9IHZpZXcuanFXaWRnZXQ7CiAgICAgICAgICAgIGlmICghanFXaWRnZXQpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZih4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuX2lzSXBhZCgpKSB7CiAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0ID0ganFXaWRnZXQuJHVzZXJDb250cm9sLm9mZnNldCgpLAogICAgICAgICAgICAgICAgICAgIHRvcCA9IG9mZnNldC50b3AsCiAgICAgICAgICAgICAgICAgICAgbGVmdCA9IG9mZnNldC5sZWZ0OwogICAgICAgICAgICAgICAgd2luZG93LnNjcm9sbFRvKGxlZnQsdG9wKSA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAganFXaWRnZXQuZm9jdXMoKTsKICAgICAgICB9CgogICAgfSk7CgogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJhc2VWaWV3LnByb3RvdHlwZSwgInJlc2l6YWJsZSIsIHsKICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVzaXphYmxlOwogICAgICAgIH0sCgogICAgICAgIHNldCA6IGZ1bmN0aW9uKHNWYWx1ZSl7CiAgICAgICAgICAgIHRoaXMuX3Jlc2l6YWJsZSA9IHNWYWx1ZTsKICAgICAgICB9CiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy5YZmFEcmF3VmlldyA9IHhmYWxpYi52aWV3LkJhc2VWaWV3LmV4dGVuZCh7CiAgICAgICAgJGRyYXdDaGlsZCA6IG51bGwsCgogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5CYXNlVmlldy5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICB0aGlzLl9pbml0TGF5b3V0KCk7CiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUFjY2Vzc2liaWxpdHlJbmZvKCk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlTW9kZWxDaGFuZ2VkIDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgc3dpdGNoKGV2ZW50Ll9wcm9wZXJ0eSkgewogICAgICAgICAgICAgICAgY2FzZSAicmF3VmFsdWUiIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihldmVudC5qc29uTW9kZWwubmV3VGV4dCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVWaWV3KGV2ZW50Lmpzb25Nb2RlbC5uZXdUZXh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5oYW5kbGVNb2RlbENoYW5nZWQuYXBwbHkodGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGhhbmRsZURvbUNoYW5nZWQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAgc3dpdGNoKGV2ZW50Ll9wcm9wZXJ0eSkgewogICAgICAgICAgICAgICAgIGNhc2UgInZhbHVlLnRleHQiIDoKICAgICAgICAgICAgICAgICBjYXNlICJ2YWx1ZS5leERhdGEiIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZXZlbnQuanNvbk1vZGVsLm5ld1RleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVZpZXcoZXZlbnQuanNvbk1vZGVsLm5ld1RleHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgIGNhc2UgImgiIDovLy0td2Ugc3VwcG9ydCBjb21wdXRhdGlvbiBvbmx5IG9uIGxpbmUgZm9yIG5vdy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5nZXRPckVsc2UodGhpcy5tb2RlbCwgInZhbHVlLm9uZU9mQ2hpbGQuY2xhc3NOYW1lIiwgIiIpID09PSAibGluZSIpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29tcHV0ZUxpbmVIZWlnaHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5CYXNlVmlldy5wcm90b3R5cGUuaGFuZGxlRG9tQ2hhbmdlZC5hcHBseSh0aGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlRm9udEZpbGxDb2xvclZhbHVlIDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgaWYodGhpcy5tb2RlbCAmJiB0aGlzLm1vZGVsLnZhbHVlKSB7CiAgICAgICAgICAgICAgICB2YXIgY29udGVudCA9IHRoaXMubW9kZWwudmFsdWUub25lT2ZDaGlsZDsKICAgICAgICAgICAgICAgIHZhciBodG1sVGV4dCA9IGNvbnRlbnQuanNvbk1vZGVsLl92YWx1ZTsKICAgICAgICAgICAgICAgIGlmKGNvbnRlbnQuZ2V0QXR0cmlidXRlKCdjb250ZW50VHlwZScpID09ICd0ZXh0L2h0bWwnKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyICRpbnRlcm5hbEhUTUwgPSAkKCc8c3Bhbj4nK2h0bWxUZXh0Kyc8L3NwYW4+Jyk7CiAgICAgICAgICAgICAgICAgICAgLy9jaGFuZ2UgdGhlIHRvcCBsZXZlbCBlbGVtZW50IHRvIHNwYW4gdG8gd3JhcCB1cCBhbGwgdGhlIDxwPiwgYmVjYXVzZSBpdCB3aWxsIGNhdXNlIHVubmVjZXNzYXJ5IHBhcmFncmFwaCBicmVhawogICAgICAgICAgICAgICAgICAgIC8vYWRkICdkaXNwbGF5OmlubGluZScgc3R5bGUKICAgICAgICAgICAgICAgICAgICAvL25vIG51bGwgY2hlY2sgYmVjYXVzZSBqUXVlcnkgaXMgY29vbCEKICAgICAgICAgICAgICAgICAgICAvL1RvRG86IGNoYW5nZSBhbGwgeW91ciBwYXJhZ3JhcGhzIGludG8gPHNwYW4+IGFuZCBhZGQgYSA8YnI+IGVsZW1lbnQgYmV0d2VlbiB0aGVtCiAgICAgICAgICAgICAgICAgICAgLy90aGlzIHdpbGwgd29yayBmb3IgZmV3IGNhc2VzIHdoZXJlIHRoZXJlIGlzIG9uZSBzaW5nbGUgcGFyYWdyYXBoIGluIHRoZSB0ZXh0IG9yIHBsYWluIHRleHQgY2FzZXMuCiAgICAgICAgICAgICAgICAgICAgJGludGVybmFsSFRNTC5maW5kKCJwIikuZXEoMCkuY3NzKCdkaXNwbGF5JywnaW5saW5lJyk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlVmlldygkaW50ZXJuYWxIVE1MWzBdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVWaWV3KGh0bWxUZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL25vdyBjaGVjayB0aGUgcmF3VmFsdWUgYW5kIHVwZGF0ZSB2aWV3IGJhc2VkIG9uIHRoYXQgcmF3VmFsdWUKCiAgICAgICAgfSwKCiAgICAgICAgX3VwZGF0ZVZpZXcgOiBmdW5jdGlvbih0ZXh0KSB7CiAgICAgICAgICAgICAgaWYgKHRoaXMuX2luaXRpYWxpemVkICYmIHRoaXMubW9kZWwpIHsKICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCd2YWx1ZScsMCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgIGlmKHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICB2YXIgIGNoaWxkID0gdmFsdWUub25lT2ZDaGlsZDsKICAgICAgICAgICAgICAgICAgICAgIGlmIChbInRleHQiLCJleERhdGEiXS5pbmRleE9mKGNoaWxkLmNsYXNzTmFtZSkgIT09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNzc09iaiA9IHRoaXMuX2dldFRleHRTdHlsZSh0aGlzLm1vZGVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3NzT2JqKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy5lbCwgY3NzT2JqLmZvbnRTdHlsZXMpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmVuY29kZVNjcmlwdGFibGVUYWdzKHRoaXMuX2NvbnZlcnRYRkFSaWNoVG9IdG1sKHRleHQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5jaGlsZHJlbigpLnJlcGxhY2VXaXRoKHRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmVsLmNoaWxkcmVuWzBdICYmIGNzc09iaikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy5lbC5jaGlsZHJlblswXSwgY3NzT2JqLnBhcmFTdHlsZXMpOwogICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkLmNsYXNzTmFtZSA9PT0gJ2ltYWdlJyAmJiB0ZXh0KSB7Ly9pZiBkcmF3IGlzIG9mIHR5cGUgaW1hZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5jaGlsZHJlbigpWzBdLnNldEF0dHJpYnV0ZSgnc3JjJywgJ2RhdGE6O2Jhc2U2NCwnICsgdGV4dCk7CiAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5yZXNpemFibGUpewogICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52YWxpZGF0ZVNpemUoKTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbWVhc3VyZVNpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgcmVzaXplZCA9IGZhbHNlLAogICAgICAgICAgICAgICAgdGV4dCA9IG51bGwsCiAgICAgICAgICAgICAgICBjb250ZW50ID0gdGhpcy5nZXRPckVsc2UodGhpcywgIm1vZGVsLnZhbHVlLm9uZU9mQ2hpbGQiLCBudWxsKTsKCiAgICAgICAgICAgIC8vIGNoZWNrIHRvIHJlc2l6ZSBkcmF3IG9ubHkgaW4gY2FzZSBvZiBmbG9hdGluZyBmaWVsZCBhbmQgaXMgcmVzaXphYmxlCiAgICAgICAgICAgIGlmKHRoaXMucmVzaXphYmxlICYmIHRoaXMuX2lzRmxvYXRpbmdGaWVsZFByZXNlbnQoY29udGVudCkpewogICAgICAgICAgICAgICAgLy8gaWYgY29udGVudCBpcyByaWNoIHRleHQsIHRoZW4gdXNlIGpxdWVyeSBodG1sKCkgdG8gc3VwcG9ydCByaWNoIHRleHQgZWxlbWVudCBlbHNlIHRleHQoKQogICAgICAgICAgICAgICAgaWYoY29udGVudCAmJiBjb250ZW50LmdldEF0dHJpYnV0ZSgnY29udGVudFR5cGUnKSA9PSAndGV4dC9odG1sJykgewogICAgICAgICAgICAgICAgICAgIHRleHQgPSB0aGlzLiRlbC5odG1sKCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRleHQgPSB0aGlzLiRlbC50ZXh0KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXNpemVkID0geGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fdXBkYXRlV2lkZ2V0TW9kZWwuY2FsbCh0aGlzLCB0ZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzaXplZDsKICAgICAgICB9LAoKICAgICAgICBfZ2V0TWVhc3VyZW1lbnRPcHRpb25zIDogZnVuY3Rpb24oKXsKICAgICAgICAgICB2YXIgbWVhc3VyZU9wdGlvbnMgPSB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9nZXRNZWFzdXJlbWVudE9wdGlvbnMuYXBwbHkodGhpcywgYXJndW1lbnRzKSwKICAgICAgICAgICAgICAgY29udGVudCA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMsICJtb2RlbC52YWx1ZS5vbmVPZkNoaWxkIiwgbnVsbCk7CiAgICAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LCBtZWFzdXJlT3B0aW9ucywgewogICAgICAgICAgICAgICBjb250ZW50VHlwZSA6IGNvbnRlbnQgPyBjb250ZW50LmdldEF0dHJpYnV0ZSgnY29udGVudFR5cGUnKSA6ICIiLAogICAgICAgICAgICAgICBpc0RyYXcgOiB0cnVlLAogICAgICAgICAgICAgICByZWZFbCA6IHRoaXMuZWwKICAgICAgICAgICB9KTsKCiAgICAgICAgfSwKICAgICAgICAvKioKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uIHRvIGNoZWNrcyB3aGV0aGVyIHRoZSBkcmF3IGlzIGhhdmluZyBmbG9hdGluZyBmaWVsZCBvciBub3QKICAgICAgICAgKiBAcGFyYW0ge29iamVjdH0gY29udGVudCA6IGNvbnRhaW5zIGpzb25WYWx1ZSAsIF9vcmlnVG1wbHRWYWwgZXRjLgogICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSA6IHRydWUgaWYgZHJhdyBjb250YWlucyBmbG9hdGluZyBmaWVsZCBlbHNlIGZhbHNlCiAgICAgICAgICovCiAgICAgICAgX2lzRmxvYXRpbmdGaWVsZFByZXNlbnQgOiBmdW5jdGlvbiAoY29udGVudCkgewogICAgICAgICAgICBpZiAoY29udGVudCAmJiBjb250ZW50Ll9vcmlnVG1wbHRWYWwpIHsKICAgICAgICAgICAgICAgIHZhciAkaW50ZXJuYWxIVE1MID0gJCgnPHNwYW4+JyArIGNvbnRlbnQuX29yaWdUbXBsdFZhbCArICc8L3NwYW4+Jyk7CiAgICAgICAgICAgICAgICByZXR1cm4gJGludGVybmFsSFRNTC5maW5kKCdbeGZhXFw6ZW1iZWRdJykubGVuZ3RoID4gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgX3N5bmNGb3JtTm9kZVRvSHRtbCA6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAvL2luIG9yZGVyIHRvIHNhdmUgc29tZSBieXRlcwogICAgICAgICAgICAvLyB3ZSBkb24ndCBzZW5kIHhtbG5zIGF0dHJpYnV0ZXMgZnJvbSBzZXJ2ZXIgc28gc2V0IGl0IGhlcmUKICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy4kZWwuY2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIHZhbHVlID0gbnVsbDsKICAgICAgICAgICAgaWYoY2hpbGRyZW4ubGVuZ3RoKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoY2hpbGRyZW5bMF0udGFnTmFtZSA9PT0gJ3N2ZycpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluIGNhc2Ugb2Yga2VybmluZywgd2UgYWRkIGxldHRlclNwYWNpbmcgaW4gWERQLiBWaWV3IGdlbmVyYXRlZCBjb250YWlucyBzcGFjZWQgbGV0dGVycyB3aGljaCBhcmUgcmVhZCBzZXBhcmF0ZWx5CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ5IHRoZSBzY3JlZW4gcmVhZGVycywgdG8gYXZvaWQgdGhpcyB3ZSBhcmUgY2hlY2tpbmcgaWYgaXQgY29udGFpbnMgbGV0dGVyU3BhY2luZywgaWYgeWVzIHRoZW4gYWRkIGFyaWEtbGFiZWwKICAgICAgICAgICAgICAgICAgICAgICAgLy8gb24gdG9wIGxldmVsIGFuZCBoaWRlIG5lc3RlZCBlbGVtZW50cyBmcm9tIHNjcmVlbiByZWFkZXIuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMubW9kZWwgJiYgdGhpcy5tb2RlbC5qc29uTW9kZWwgJiYgdGhpcy5tb2RlbC5qc29uTW9kZWwuY2hpbGRyZW4pewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm1vZGVsLmpzb25Nb2RlbC5jaGlsZHJlbi5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMubW9kZWwuanNvbk1vZGVsLmNoaWxkcmVuW2ldLl9jbGFzcz09PSJmb250Iil7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMubW9kZWwuanNvbk1vZGVsLmNoaWxkcmVuW2ldLmxldHRlclNwYWNpbmcpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbC5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWwnLCB0aGlzLm1vZGVsLnJhd1ZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuWzBdLnNldEF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nLCAndHJ1ZScpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuWzBdLnNldEF0dHJpYnV0ZSgncm9sZScsJ3ByZXNlbnRhdGlvbicpOyAvLyBDUS00Mjc0NzMyIDogVG8gcHJldmVudCBzdmcgYmVpbmcgcmVhZCBvdXQgYXMgZ3JhcGhpYwogICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuWzBdLnNldEF0dHJpYnV0ZSgneG1sbnMnLCAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnKTsKICAgICAgICAgICAgICAgICAgICBjaGlsZHJlblswXS5zZXRBdHRyaWJ1dGUoJ3htbG5zOnhsaW5rJywgJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnKTsKICAgICAgICAgICAgICAgICAgICBjaGlsZHJlblswXS5zZXRBdHRyaWJ1dGUoJ2ZvY3VzYWJsZScsICdmYWxzZScpOyAvL0xDLTcxMDUgTEMtNTQ0NCBzdmcgdGFiSW5kZXggZG9lc24ndCB3b3JrIHNvIGFkZGluZyBmb2N1c2FibGUgYXMgZmFsc2UKICAgICAgICAgICAgICAgICAgICAvL1JlcXVpcmVkIHNvIHRoYXQgZHJhdyBkbyBub3Qgc3BpbGwgb3V0IG9mIHRoZWlyIHBhcmVudCBkaXYuCiAgICAgICAgICAgICAgICAgICAgdmFyIGNzc0V4dGVudCA9IHt9OwogICAgICAgICAgICAgICAgICAgIGNzc0V4dGVudFsid2lkdGgiXSA9ICIxMDAlIjsKICAgICAgICAgICAgICAgICAgICBjc3NFeHRlbnRbImhlaWdodCJdPSAiMTAwJSI7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKGNoaWxkcmVuWzBdLCBjc3NFeHRlbnQpOwogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuZ2V0T3JFbHNlKHRoaXMubW9kZWwsICJ2YWx1ZS5vbmVPZkNoaWxkLmNsYXNzTmFtZSIsICIiKSA9PT0gJ2xpbmUnKXsKICAgICAgICAgICAgICAgICAgICAgICB2YXIgcHhIZWlnaHQgPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5fY29udmVydFRvUHgodGhpcy5tb2RlbC5oKTsKICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3ZnSGVpZ2h0ID0geGZhbGliLnZpZXcudXRpbC5TdHlsZXMuX2NvbnZlcnRUb1B4KGNoaWxkcmVuWzBdLmdldEF0dHJpYnV0ZSgnaGVpZ2h0JykpOwogICAgICAgICAgICAgICAgICAgICAgIGlmKHN2Z0hlaWdodCAmJiBweEhlaWdodCAhPSBzdmdIZWlnaHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29tcHV0ZUxpbmVIZWlnaHQoKTsKICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZih0aGlzLm1vZGVsKXsKICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCd2YWx1ZScsMCwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYodmFsdWUpIHsKICAgICAgICAgICAgICAgIHZhciAgY2hpbGQgPSB2YWx1ZS5vbmVPZkNoaWxkOwogICAgICAgICAgICAgICAgaWYgKGNoaWxkLl9tb2RlbENoYW5nZWQgPT09IHRydWUpIHsgLy9ubyBuZWVkIHRvIGNoZWNrIGl0IGhlcmUgYXMgdXBkYXRldmlldyBjaGVja3MgaXQgYW55d2F5CiAgICAgICAgICAgICAgICAgICAgdmFyIGpzb25WYWwgPSBjaGlsZC5qc29uVmFsdWUgfHwgY2hpbGQudmFsdWU7IC8vIGNhbGwgdG8gY2hpbGQudmFsdWUgd2lsbCB1c2UgdHlwZWRWYWwgYW5kIHN0cmlwIG9mZiBodG1sIHRhZ3MgOiBMQy01NDI3CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLmNsYXNzTmFtZSA9PT0gImltYWdlIiAmJiBqc29uVmFsID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9mb3IgaW1hZ2VzLCBpZiB0aGUgdmFsdWUgaXMgdW5kZWZpbmVkIG9yIG51bGwgcmV0dXJuIHRoZSBocmVmIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgICAgICBqc29uVmFsID0gY2hpbGQuaHJlZjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlVmlldyhqc29uVmFsKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vZm9yIGRyYXcgZG8gaXQgZm9yIHRoZSB2ZXJ5IGZpcnN0IHRpbWUgYXMgd2VsbAogICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5jbGFzc05hbWUgPT09ICdpbWFnZScpIHsgLy9pZiBkcmF3IGlzIG9mIHR5cGUgaW1hZ2UKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLnZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5jaGlsZHJlbigpWzBdLnNldEF0dHJpYnV0ZSgnc3JjJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGF0YTo7YmFzZTY0LCcgKyBjaGlsZC52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5jaGlsZHJlbigpWzBdLnNldEF0dHJpYnV0ZSgnc3JjJywgY2hpbGQuaHJlZik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5fc3luY0Zvcm1Ob2RlVG9IdG1sLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfSwKCiAgICAgICAgX2NvbXB1dGVMaW5lSGVpZ2h0IDogZnVuY3Rpb24oKSB7ICAgLy9sYy01NDYzCiAgICAgICAgICAgLy8tLSBjb21wdXRpbmcgbGluZSBoZWlnaHQKICAgICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuJGVsLmNoaWxkcmVuKCk7CiAgICAgICAgICB2YXIgbGluZU5vZGUgPXt9OwogICAgICAgICAgaWYoY2hpbGRyZW5bMF0pIHsKICAgICAgICAgICAgIGxpbmVOb2RlID0gY2hpbGRyZW5bMF0uY2hpbGROb2Rlc1swXTsKICAgICAgICAgIH0KICAgICAgICAgIHZhciBweEhlaWdodCA9IHhmYWxpYi52aWV3LnV0aWwuU3R5bGVzLl9jb252ZXJ0VG9QeCh0aGlzLm1vZGVsLmgpOwogICAgICAgICAgaWYobGluZU5vZGUpIHsKICAgICAgICAgICAgIC8vLS10cmFuc2Zvcm1pbmcgdGhlIGNvZGUgZnJvbSBvdGhlciB1bml0cyB0byBwaXhlbCBhbmQgY2hhbmdpbmcgaXRzIHR5cGUgdG8gTnVtZXIgZm9yIGZ1cnRoZXIgY29tcHV0YXRpb24KICAgICAgICAgICAgIHZhciB4MSA9IHhmYWxpYi52aWV3LnV0aWwuU3R5bGVzLl9jb252ZXJ0VG9QeChsaW5lTm9kZS5nZXRBdHRyaWJ1dGUoJ3gxJykpOwogICAgICAgICAgICAgdmFyIHgyID0geGZhbGliLnZpZXcudXRpbC5TdHlsZXMuX2NvbnZlcnRUb1B4KGxpbmVOb2RlLmdldEF0dHJpYnV0ZSgneDInKSk7CiAgICAgICAgICAgICB2YXIgeTEgPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5fY29udmVydFRvUHgobGluZU5vZGUuZ2V0QXR0cmlidXRlKCd5MScpKTsKICAgICAgICAgICAgIHZhciB5MiA9IHhmYWxpYi52aWV3LnV0aWwuU3R5bGVzLl9jb252ZXJ0VG9QeChsaW5lTm9kZS5nZXRBdHRyaWJ1dGUoJ3kyJykpOwoKICAgICAgICAgICAgIHZhciBzbG9wZSA9ICh5Mi15MSkvKHgyLXgxKTsKICAgICAgICAgICAgIGlmKCFpc0Zpbml0ZShzbG9wZSkpIHsKICAgICAgICAgICAgICAgIHkyID0geTEgKyAgcHhIZWlnaHQ7CiAgICAgICAgICAgICAgICBsaW5lTm9kZS5zZXRBdHRyaWJ1dGUoJ3kyJyxTdHJpbmcoeTIgKydweCcpKTsKICAgICAgICAgICAgICAgIGNoaWxkcmVuWzBdLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JyxTdHJpbmcocHhIZWlnaHQgKydweCcpKTsKICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50aCA9IHB4SGVpZ2h0IDsKICAgICAgICAgICAgICAgIHZhciBjc3NIZWlnaHQgPSB7fTsKICAgICAgICAgICAgICAgIGNzc0hlaWdodFsnaGVpZ2h0J10gPSBTdHJpbmcocHhIZWlnaHQgKydweCcpOwogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuZWwsIGNzc0hlaWdodCk7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgLyppZihzbG9wZSA9PSAwKSB7CiAgICAgICAgICAgICAgICB4MiA9IHgxICsgIHB4SGVpZ2h0OwogICAgICAgICAgICAgfQogICAgICAgICAgICAgaWYoaXNGaW5pdGUoc2xvcGUpICYmIHNsb3BlICE9IDApIHsKICAgICAgICAgICAgICAgIHgyID0geDEgKyAgcHhIZWlnaHQgKiBNYXRoLnNpbihNYXRoLmF0YW4oc2xvcGUpKSA7CiAgICAgICAgICAgICAgICB5MiA9IHkxIC0gIHB4SGVpZ2h0ICogTWF0aC5jb3MoTWF0aC5hdGFuKHNsb3BlKSkgOwogICAgICAgICAgICAgfSovCiAgICAgICAgICAgIC8vIGxpbmVOb2RlLnNldEF0dHJpYnV0ZSgneDInLFN0cmluZyh4MiArJ3B4JykpOwoKICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaW5pdExheW91dCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5faW5pdExheW91dC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICBpZih0aGlzLl9pbml0aWFsaXplZCl7CiAgICAgICAgICAgICAgICB2YXIgZHJhd1R5cGUgPSB0aGlzLmdldE9yRWxzZSh0aGlzLiRkYXRhKHRoaXMuZWwsIHhmYWxpYi52aWV3LkxheW91dENvbnN0LlhGQV9NT0RFTClbeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTk9ERV9UWVBFXSwgIiIpLnRvTG93ZXJDYXNlKCk7CgogICAgICAgICAgICAgICAgaWYoISQuYnJvd3Nlci5tc2llKXsKICAgICAgICAgICAgICAgICAgICAvL0FsbCBzdXBwb3J0ZWQgYnJvd3NlciBleGNlcHQgSUUgYXJlIG5vdCBhYmxlIHRvIGdyYWNlZnVsbHkgaGFuZGxlIDFweCBzdmcgZHJhd2luZ3MuCiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHJlYXNvbiBmb3IgdGhhdCwgdGhleSBzdGFydCBkcmF3IGF0IGdyaWQgbGluZXMgYW5kIGRyYXcgLjVweCBvbiBib3RoIHNpZGVzIG9mIGdyaWRsaW5lcy4KICAgICAgICAgICAgICAgICAgICAvLyBTb21lIGJyb3dzZXJzIG1peCBoYWxmIHBpeGVsIGJsYWNrIHdpdGggd2hpdGUgdG8gcHJvZHVjZSBncmV5IGJ1dCBvdGhlcnMgbWF5IG5vdC4KICAgICAgICAgICAgICAgICAgICAvLyBUbyBoYW5kbGUgdGhpcyBjb25zaXN0ZW50bHksIHdlIHVwZ3JhZGUgMXB4IGRyYXdpbmdzIHRvIDJweCBmb3Igbm9uIElFIGJyb3dzZXJzLgogICAgICAgICAgICAgICAgICAgIGlmKGRyYXdUeXBlID09ICJsaW5lIil7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJCgnbGluZVtzdHJva2Utd2lkdGg9IjFweCJdJykuYXR0cigic3Ryb2tlLXdpZHRoIiwgIjJweCIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKGRyYXdUeXBlID09ICJyZWN0YW5nbGUiKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kKCdwYXRoW3N0cm9rZS13aWR0aD0iMXB4Il0nKS5hdHRyKCJzdHJva2Utd2lkdGgiLCAiMnB4Iik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmKCQuYnJvd3Nlci53ZWJraXQgfHwgJC5icm93c2VyLmNocm9tZSB8fCB4ZmFsaWIudXQuVXRpbGl0aWVzLmNoZWNrTWluTW96aWxsYVZlcnNpb24oMjgpKXsKICAgICAgICAgICAgICAgICAgICAvL2Nocm9tZSBoYW5kbGVzIHRoZSBydGwgdGV4dCBlbGVtZW50IGluIGEgZGlmZmVyZW50IHdheS4KICAgICAgICAgICAgICAgICAgICAvL3RoZXJlIGlzIGEgc2ltaWxhciBmdW5jdGlvbiBpbiBGaWVsZFZpZXcKICAgICAgICAgICAgICAgICAgICB0aGlzLiQoJ3RleHRbZGlyZWN0aW9uPSJydGwiXScpLmF0dHIoJ3RleHQtYW5jaG9yJywgJ2VuZCcpOwogICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICB0aGlzLiRkcmF3Q2hpbGQgPSAkKHRoaXMuX2ZpbmREcmF3RWxlbWVudCgpKTsKICAgICAgICAgICAgICAgIGlmKGRyYXdUeXBlID09ICJsaW5lIil7CiAgICAgICAgICAgICAgICAgICAgLy9Gb3IgdmVyeSB0aGluIGxpbmVzIGxlc3MgdGhhbiBvbmUgcGl4ZWwsIHRvIGF2b2lkIG1pc3NpbmcgbGluZXMsIHRoZWlyIGNvbnRhaW5pbmcgZGl2IHNob3VsZCBiZSAxcHggbWluaW11bSBpbiBzaXplCiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5sYXlvdXRNb2RlbC5leHRlbnR3ID4gMC4wMSAmJiB0aGlzLmxheW91dE1vZGVsLmV4dGVudHcgPCAxLjApCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50dyAgPSAxLjA7CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoID4gMC4wMSAmJiB0aGlzLmxheW91dE1vZGVsLmV4dGVudGggPCAxLjApCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50aCA9IDEuMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGRyYXdUeXBlID09ICJyZWN0YW5nbGUiKXsKICAgICAgICAgICAgICAgICAgICAvL1RvIGF2b2lkIG1pc3NpbmcgZWRnZXMgb2YgcmVjdGFuZ2xlLCB0aGVpciBjb250YWluaW5nIGRpdiBzaG91bGQgYmUgKmNlaWwqZWQgdG8gbmV4dCBpbnRlZ2VyLiBKdXN0IGhldXJpc3RpYy9vYnNlcnZhdGlvbgogICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50dyA9IE1hdGguY2VpbCh0aGlzLmxheW91dE1vZGVsLmV4dGVudHcpOwogICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50aCAgPSBNYXRoLmNlaWwodGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX3N5bmNGb3JtTm9kZVRvSHRtbCh0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVBY2Nlc3NpYmlsaXR5SW5mbzogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBzY3JlZW5SZWFkZXJUZXh0ID0gdGhpcy5fZ2V0U2NyZWVuUmVhZGVyVGV4dCgpOwogICAgICAgICAgICAvL2FkZCBhbHQgZm9yIGltZyB0YWdzLi4uCiAgICAgICAgICAgIGlmKHNjcmVlblJlYWRlclRleHQgJiYgdGhpcy4kZHJhd0NoaWxkICYmIHRoaXMuJGRyYXdDaGlsZC5pcygiaW1nIikpewogICAgICAgICAgICAgICAgdGhpcy4kZHJhd0NoaWxkLmF0dHIoImFsdCIsIHNjcmVlblJlYWRlclRleHQpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZihzY3JlZW5SZWFkZXJUZXh0KSB7CiAgICAgICAgICAgICAgICAkKHRoaXMpLmF0dHIoImFyaWEtbGFiZWwiLCBzY3JlZW5SZWFkZXJUZXh0KQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBjaGVjayBmb3IgaGVhZGluZyByb2xlcwogICAgICAgICAgICB2YXIgcm9sZSA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMubW9kZWwuZ2V0RWxlbWVudCgiYXNzaXN0IiksICJyb2xlIiwgIiIpOwogICAgICAgICAgICBpZiAoL15IWzEtNl0kLy50ZXN0KHJvbGUpKSB7CiAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJyb2xlIiwgImhlYWRpbmciKS5hdHRyKCJhcmlhLWxldmVsIiwgcm9sZVsxXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfYXNzaWduVG9vbFRpcDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgdG9vbFRpcFRleHQgPSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuX2dldFRvb2xUaXBUZXh0KHRoaXMubW9kZWwpOwogICAgICAgICAgICBpZiAodG9vbFRpcFRleHQpIHsKICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInRpdGxlIiwgdG9vbFRpcFRleHQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldFNjcmVlblJlYWRlclRleHQgOiBmdW5jdGlvbigpewogICAgICAgICAgICBpZiAodGhpcy5tb2RlbCkgewogICAgICAgICAgICAgICAgLy9maW5kIHNwZWFrIHByaW9yaXR5IGZpcnN0IC0tLQogICAgICAgICAgICAgICAgdmFyIGFzc2lzdCA9IHRoaXMubW9kZWwuZ2V0RWxlbWVudCgiYXNzaXN0IiwgMCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB2YXIgc2NyZWVuUmVhZGVyVGV4dDsKCiAgICAgICAgICAgICAgICB2YXIgcHJpb3JpdHkgPSAiY3VzdG9tIjsKICAgICAgICAgICAgICAgIHZhciBzcGVhazsKICAgICAgICAgICAgICAgIHZhciB0b29sVGlwOwoKICAgICAgICAgICAgICAgIGlmKGFzc2lzdCApIHsKICAgICAgICAgICAgICAgICAgICAvLyYmIGFzc2lzdC5zcGVhayAmJiBhc3Npc3Quc3BlYWsucHJpb3JpdHkKICAgICAgICAgICAgICAgICAgICBzcGVhayA9IGFzc2lzdC5nZXRFbGVtZW50KCJzcGVhayIsIDAsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIHRvb2xUaXAgPSBhc3Npc3QuZ2V0RWxlbWVudCgidG9vbFRpcCIsIDAsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIGlmKHNwZWFrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yaXR5ID0gc3BlYWsuZ2V0QXR0cmlidXRlKCdwcmlvcml0eScpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZihwcmlvcml0eSA9PSAiY3VzdG9tIikgewogICAgICAgICAgICAgICAgICAgIGlmKHNwZWFrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHQgPSBzcGVhay52YWx1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih0b29sVGlwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHQgPSB0b29sVGlwLnZhbHVlOyAvL0xDLTY4MDU6IHRvb2x0aXAgaXMgc2hvd24gYXMgW09iamVjdCBPYmplY3RdIGZvciB0ZXh0IG9iamVjdHMKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih0aGlzLm1vZGVsLmpzb25Nb2RlbC5leHRyYXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2NyZWVuUmVhZGVyVGV4dCA9IHRoaXMubW9kZWwuanNvbk1vZGVsLmV4dHJhcy5jYXB0aW9uOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2NyZWVuUmVhZGVyVGV4dCA9IHRoaXMubW9kZWwuanNvbk1vZGVsLm5hbWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZihwcmlvcml0eSA9PSAidG9vbFRpcCIpIHsKICAgICAgICAgICAgICAgICAgICBpZih0b29sVGlwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHQgPSB0b29sVGlwLnZhbHVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKHRoaXMubW9kZWwuanNvbk1vZGVsLmV4dHJhcykgewogICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW5SZWFkZXJUZXh0ID0gdGhpcy5tb2RlbC5qc29uTW9kZWwuZXh0cmFzLmNhcHRpb247CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW5SZWFkZXJUZXh0ID0gdGhpcy5tb2RlbC5qc29uTW9kZWwubmFtZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKHByaW9yaXR5ID09ICJuYW1lIikgewogICAgICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHQgPSB0aGlzLm1vZGVsLmpzb25Nb2RlbC5uYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIHJldHVybiBzY3JlZW5SZWFkZXJUZXh0OwoKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlRHJhd0NoaWxkRXh0ZW50IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIGV4dGVudCA9IHt9OwogICAgICAgICAgICB2YXIgZHJhd1R5cGUgPSB0aGlzLmdldE9yRWxzZSh0aGlzLiRkYXRhKHRoaXMuZWwsIHhmYWxpYi52aWV3LkxheW91dENvbnN0LlhGQV9NT0RFTClbeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTk9ERV9UWVBFXSwgIiIpLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgIGlmKGRyYXdUeXBlID09ICJ0ZXh0Iil7CiAgICAgICAgICAgICAgICAvL1RoaXMgaXMgdG8gYXZvaWQgdHJ1bmNhdGlvbiBvZiBzdmcgdGV4dCB3aGVuIFNWRyBpcyBsYXJnZXIgdGhhbiBjb250YWluaW5nIGRpdi4KICAgICAgICAgICAgICAgIC8vSW4gdGhhdCBjYXNlIHdlIGFsbG93IFNWRyB0byBiZSBsYXJnZSB1cHRvIGV4dGVudCBvZiAxMjAlIG9mIHRoZSBhc3NpZ25lZCBkcmF3IGV4dGVudHMKICAgICAgICAgICAgICAgIC8vIEVhY2ggYnJvd3NlciBoYW5kbGVzIHN2ZyBkaWZmZXJlbnRseS4gQmVsb3cgZml4IHdvcmtzIGZvciBhbGwgc3VwcG9ydGVkIGJyb3dzZXIgYW5kIGF2b2lkIDIwJSB0cnVuY2F0aW9uIHdoaWNoIHdvdWxkIGhhbmRsZSBtb3N0IGNvbW1vbiBjYXNlcy4KICAgICAgICAgICAgICAgIC8vIEFjdHVhbCBmaXggd291bGQgcmVxdWlyZSBleGFjdCBjb21iaW5lZCBzdmcgaGVpZ2h0L3dpZHRoIGNhbGN1bGF0aW9uIHByb2JhYmx5IGluIFhURyBzaWRlLgogICAgICAgICAgICAgICAgZXh0ZW50WyJ3aWR0aCJdID0gIjEyMCUiOwogICAgICAgICAgICAgICAgZXh0ZW50WyJoZWlnaHQiXT0gIjEyMCUiOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy9SZXF1aXJlZCBzbyB0aGF0IGRyYXcgZG8gbm90IHNwaWxsIG91dCBvZiB0aGVpciBwYXJlbnQgZGl2LgogICAgICAgICAgICAgICAgZXh0ZW50WyJ3aWR0aCJdID0gIjEwMCUiOwogICAgICAgICAgICAgICAgZXh0ZW50WyJoZWlnaHQiXT0gIjEwMCUiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBleHRlbnQ7CiAgICAgICAgfSwKCiAgICAgICAgX2ZpbmREcmF3RWxlbWVudCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciBkcmF3RWxzID0gdGhpcy4kZWwuY2hpbGRyZW4oKTsKICAgICAgICAgICAgaWYoZHJhd0Vscy5sZW5ndGggPjApCiAgICAgICAgICAgICAgICByZXR1cm4gZHJhd0Vscy5nZXQoMCk7CiAgICAgICAgfSwKCiAgICAgICAgdXBkYXRlRGlzcGxheSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS51cGRhdGVEaXNwbGF5LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMuJGRyYXdDaGlsZCAhPSBudWxsICYmICF0aGlzLiRkcmF3Q2hpbGQuaXMoImltZyIpKSB7CiAgICAgICAgICAgICAgICAvL29ubHkgc2V0IGV4dGVudCBpZiBpdCBpcyBub3QgaW1nIGFzIGltZyBoYXMgaXRzIG93biBleHRlbnQKICAgICAgICAgICAgICAgIHZhciBkcmF3Q2hpbGRFeHRlbnQgPSB0aGlzLl9jb21wdXRlRHJhd0NoaWxkRXh0ZW50KCk7CiAgICAgICAgICAgICAgICAvL2RvIHRoaXMgb25seSBpZgogICAgICAgICAgICAgICAgaWYodGhpcy4kZHJhd0NoaWxkLmxlbmd0aCkKICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy4kZHJhd0NoaWxkLmdldCgwKSwgZHJhd0NoaWxkRXh0ZW50KTsKCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sICQsIHhmYWxpYik7KGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB2YXIgYnR3biA9IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5idHduOwoKICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldyA9ICB4ZmFsaWIudmlldy5CYXNlVmlldy5leHRlbmQoewogICAgICAgIC8vbGlzdCBvZiBSVEwgbGFuZ3VhZ2VzCiAgICAgICAgX3J0bExhbmc6e2hlIDogImhlIiwgYXIgOiAiYXIiLCBmYTogImZhIn0sCgogICAgICAgIF9hZGRPbnM6ewogICAgICAgICAgICAieC1zY3JpYmJsZS1hZGQtb24iIDogeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5TY3JpYmJsZUltYWdlRmllbGQKICAgICAgICB9LAogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5jYXB0aW9uTGF5b3V0TW9kZWwgPSBudWxsOwogICAgICAgICAgICB0aGlzLndpZGdldExheW91dE1vZGVsID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuY29tbWl0RXZlbnQgPSB0aGlzLm9wdGlvbnMuY29tbWl0RXZlbnQ7CiAgICAgICAgICAgIHRoaXMuY29tbWl0UHJvcGVydHkgPSB0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHk7CiAgICAgICAgICAgIHRoaXMuY29tbWl0VGFyZ2V0ID0gdGhpcy5vcHRpb25zLmNvbW1pdFRhcmdldDsKICAgICAgICAgICAgdGhpcy5pc0Vycm9yID0gZmFsc2U7CgogICAgICAgICAgICB0aGlzLmNhcHRpb24gPSB0aGlzLl9maW5kQ2FwdGlvbigpOwogICAgICAgICAgICB0aGlzLndpZGdldCA9IHRoaXMuX2ZpbmRXaWRnZXQoKTsKICAgICAgICAgICAgaWYgKHRoaXMud2lkZ2V0KSB7CiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZUJvcmRlckZvcldpZGdldCgpOwogICAgICAgICAgICAgICAgaWYodGhpcy5jb21taXRFdmVudCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkub24odGhpcy5jb21taXRFdmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYmluZCh0aGlzLCB0aGlzLmhhbmRsZUNvbW1pdCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkub24oeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DTElDS19FVkVOVCwKICAgICAgICAgICAgICAgICAgICB0aGlzLl9iaW5kKHRoaXMsIHRoaXMuaGFuZGxlQ2xpY2tFdmVudCkpOwogICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkub24oeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FWElUX0VWRU5ULAogICAgICAgICAgICAgICAgICAgIHRoaXMuX2JpbmQodGhpcywgdGhpcy5oYW5kbGVGb2N1c091dCkpOwogICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkub24oeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYmluZCh0aGlzLCB0aGlzLmhhbmRsZUNoYW5nZUV2ZW50KSk7CiAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5vbih4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VOVEVSX0VWRU5ULAogICAgICAgICAgICAgICAgICAgIHRoaXMuX2JpbmQodGhpcywgdGhpcy5oYW5kbGVGb2N1c0V2ZW50KSk7CiAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5vbigia2V5cHJlc3MiLAogICAgICAgICAgICAgICAgICAgIHRoaXMuX2JpbmQodGhpcywgdGhpcy5oYW5kbGVLZXlQcmVzc0V2ZW50KSk7CiAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5vbih4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX1BSRU9QRU5fRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgJC5wcm94eSh0aGlzLmhhbmRsZVByZU9wZW5FdmVudCwgdGhpcykpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgaWYodGhpcy5jYXB0aW9uKSB7CiAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy5jYXB0aW9uLHsiY3Vyc29yIjoiZGVmYXVsdCJ9KTsKICAgICAgICAgICAgICAgIC8vYWRkIHByZXNlbnRhdGlvbiByb2xlIHRvIGNhcHRpb24KICAgICAgICAgICAgICAgICQodGhpcy5jYXB0aW9uKS5hdHRyKCJyb2xlIiwgInByZXNlbnRhdGlvbiIpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgJCh0aGlzLiRlbCkub24oIm1vdXNlZG93biIsICQucHJveHkodGhpcy5faGFuZGxlTW91c2VEb3duLHRoaXMpKQogICAgICAgICAgICAgICAgICAgICAgIC5vbigiY2xpY2siLCBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhhdC5tb2RlbC5tRWZmZWN0aXZlQWNjZXNzICE9ICJvcGVuIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9sYWJlbCBpcyBjbGlja2VkIGNsaWNrIHRoZSB3aWRnZXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCEkKGV2ZW50LnRhcmdldCkuY2xvc2VzdCgiLndpZGdldCIpLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuanFXaWRnZXQuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHRoaXMuX2luaXRMYXlvdXQoKTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVCb3JkZXJGb3JXaWRnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICBpZih0aGlzLm1vZGVsKXsKICAgICAgICAgICAgICAgIHZhciB1aSA9IHRoaXMubW9kZWwuZ2V0RWxlbWVudCgidWkiLCAwLHRydWUpOwogICAgICAgICAgICAgICAgdmFyIGZpbGwsY29sb3IgOwogICAgICAgICAgICAgICAgaWYodWkpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgYm9yZGVyID0gdWkub25lT2ZDaGlsZC5nZXRFbGVtZW50KCJib3JkZXIiLCAwLHRydWUpOwogICAgICAgICAgICAgICAgICAgIGlmKGJvcmRlciAmJiBib3JkZXIucHJlc2VuY2UgPT0gInZpc2libGUiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuY2FwdGlvbiAgJiYgcGFyc2VJbnQodGhpcy5tb2RlbC5jYXB0aW9uLmdldEF0dHJpYnV0ZSgicmVzZXJ2ZSIpKSE9MCAgJiYgdGhpcy5tb2RlbC5wYXJlbnQuY2xhc3NOYW1lICE9ImV4Y2xHcm91cCIpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNzc1N0eWxlT2JqID0geGZhbGliLnZpZXcudXRpbC5TdHlsZXMuZ2V0U3R5bGVGb3JCb3JkZXIoYm9yZGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNzc1N0eWxlT2JqKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLndpZGdldCwgY3NzU3R5bGVPYmopOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYoIXRoaXMuZWRnZVByZXNlbmNlICAmJiB0aGlzLm1vZGVsLnBhcmVudC5jbGFzc05hbWUgIT0iZXhjbEdyb3VwIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNzc1N0eWxlT2JqID0geGZhbGliLnZpZXcudXRpbC5TdHlsZXMuZ2V0U3R5bGVGb3JCb3JkZXIoYm9yZGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNzc1N0eWxlT2JqKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLndpZGdldCwgY3NzU3R5bGVPYmopOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmKGJvcmRlciAmJiAoZmlsbCA9IGJvcmRlci5nZXRFbGVtZW50KCJmaWxsIiwwLHRydWUpKSAmJiAoY29sb3IgPSBmaWxsLmdldEVsZW1lbnQoImNvbG9yIiwwLHRydWUpKQogICAgICAgICAgICAgICAgICAgICAgICAmJiBmaWxsLnByZXNlbmNlIT0iaGlkZGVuIgogICAgICAgICAgICAgICAgICAgICAgICAmJiBmaWxsLnByZXNlbmNlICE9ImludmlzaWJsZSIKICAgICAgICAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbG9yID0gY29sb3IudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNvbG9yID09ICIiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9IjI1NSwyNTUsMjU1IjsgIC8vIGlmIG5vIGNvbG9yIHZhbHVlIGlzIHNwZWNpZmllZCB0aGVuIGZpbGwgZGVmYXVsdCBjb2xvcgogICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJyZ2IoIiArIGNvbG9yICsgIikiOwogICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5jc3MoImJhY2tncm91bmQtY29sb3IiLCBjb2xvcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCgogICAgICAgIF9oYW5kbGVNb3VzZURvd246IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmKCAhJChldmVudC50YXJnZXQpLmNsb3Nlc3QoIi53aWRnZXQiKS5sZW5ndGggJiYgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5jdXJyZW50Rm9jdXMgPT0gdGhpcyApIHsKICAgICAgICAgICAgICAgIHRoaXMuY2xpY2tlZE9uQ2FwdGlvbiA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfbWFya0FjY2VzcyA6IGZ1bmN0aW9uKGFjY2VzcykgewogICAgICAgICAgICBzd2l0Y2goYWNjZXNzKSB7CiAgICAgICAgICAgICAgICBjYXNlICJvcGVuIiA6CiAgICAgICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkucmVtb3ZlQ2xhc3MoIndpZGdldHJlYWRvbmx5Iik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJub25JbnRlcmFjdGl2ZSIgOgogICAgICAgICAgICAgICAgY2FzZSAicHJvdGVjdGVkIiA6CiAgICAgICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkuYWRkQ2xhc3MoIndpZGdldHJlYWRvbmx5Iik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJyZWFkT25seSIgOgogICAgICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLmFkZENsYXNzKCJ3aWRnZXRyZWFkb25seSIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRMYXlvdXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5CYXNlVmlldy5wcm90b3R5cGUuX2luaXRMYXlvdXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgaWYodGhpcy5faW5pdGlhbGl6ZWQpewogICAgICAgICAgICAgICAgdGhpcy5faW5pdGlhbGl6ZUZpZWxkQ2hpbGRMYXlvdXRBbmRFeHRlbnQoKTsKICAgICAgICAgICAgICAgIHRoaXMuX3N5bmNGb3JtTm9kZVRvSHRtbCh0cnVlKTsKICAgICAgICAgICAgICAgIHRoaXMubWFya01hbmRhdG9yeSgpOwogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuZWwsIHsiei1pbmRleCI6IDJ9KTsKICAgICAgICAgICAgICAgIGlmKHRoaXMuY2FwdGlvbil7CiAgICAgICAgICAgICAgICAgICAgLy9UaGlzIGlzIHRvIGF2b2lkIHRydW5jYXRpb24gb2Ygc3ZnIHRleHQgd2hlbiBTVkcgaXMgbGFyZ2VyIHRoYW4gY29udGFpbmluZyBkaXYuCiAgICAgICAgICAgICAgICAgICAgLy9JbiB0aGF0IGNhc2Ugd2UgYWxsb3cgU1ZHIHRvIGJlIGxhcmdlIHVwdG8gZXh0ZW50IG9mIDEyMCUgb2YgdGhlIGFzc2lnbmVkIGRyYXcgZXh0ZW50cwogICAgICAgICAgICAgICAgICAgIC8vIEVhY2ggYnJvd3NlciBoYW5kbGVzIHN2ZyBkaWZmZXJlbnRseS4gQmVsb3cgZml4IHdvcmtzIGZvciBhbGwgc3VwcG9ydGVkIGJyb3dzZXIgYW5kIGF2b2lkIDIwJSB0cnVuY2F0aW9uIHdoaWNoIHdvdWxkIGhhbmRsZSBtb3N0IGNvbW1vbiBjYXNlcy4KICAgICAgICAgICAgICAgICAgICAvLyBBY3R1YWwgZml4IHdvdWxkIHJlcXVpcmUgZXhhY3QgY29tYmluZWQgc3ZnIGhlaWdodC93aWR0aCBjYWxjdWxhdGlvbiBwcm9iYWJseSBpbiBYVEcgc2lkZS4KICAgICAgICAgICAgICAgICAgICB2YXIgY2FwdGlvblNWRyA9ICQodGhpcy5jYXB0aW9uKS5jaGlsZHJlbigic3ZnIikuZ2V0KDApOwoKICAgICAgICAgICAgICAgICAgICAvLyBEdWUgdG8gZXh0cmEgMjAlLCBCdXR0b24tMSBhbmQgQnV0dG9uLTIgcGxhY2VkIG5leHQgdG8gZWFjaCBvdGhlciBvdmVybGFwcy4KICAgICAgICAgICAgICAgICAgICAvLyBTbyB3aGVuIGNsaWNraW5nIG9uIEJ1dHRvbi0yLCBjbGljayBvbiBCdXR0b24tMSBnZXRzIHRyaWdnZXJlZCBiZWNhdXNlIG9mIEJ1dHRvbi0xIG92ZXJsYXBwaW5nIGFyZWEKICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmluZyBleHRyYSAyMCUgYW5kIGhpZGluZyBvdmVyZmxvd24gU1ZHIHRleHQgZm9yIGJ1dHRvbiBmaWVsZC4KCiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2tpbmcgZm9yIHN1Ym1pdCBhbmQgcmFkaW8gYnV0dG9uCiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc1BhcmVudEJ1dHRvbkZpZWxkID0gJCh0aGlzLmNhcHRpb24pLnBhcmVudCgpLmxlbmd0aCAmJiAkKHRoaXMuY2FwdGlvbikucGFyZW50KCkuaGFzQ2xhc3MoJ2J1dHRvbmZpZWxkJyk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc1NpYmxpbmdCdXR0b25GaWVsZCA9ICQodGhpcy5jYXB0aW9uKS5zaWJsaW5ncygpLmxlbmd0aCAmJiAkKHRoaXMuY2FwdGlvbikuc2libGluZ3MoKS5oYXNDbGFzcygnYnV0dG9uZmllbGR3aWRnZXQnKTsKICAgICAgICAgICAgICAgICAgICB2YXIgaGFzUGFyZW50UmFkaW9CdXR0b25GaWVsZCA9ICQodGhpcy5jYXB0aW9uKS5wYXJlbnQoKS5sZW5ndGggJiYgJCh0aGlzLmNhcHRpb24pLnBhcmVudCgpLmhhc0NsYXNzKCdyYWRpb2ZpZWxkJyk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc1NpYmxpbmdSYWRpb0J1dHRvbkZpZWxkID0gJCh0aGlzLmNhcHRpb24pLnNpYmxpbmdzKCkubGVuZ3RoICYmICQodGhpcy5jYXB0aW9uKS5zaWJsaW5ncygpLmhhc0NsYXNzKCdyYWRpb2ZpZWxkd2lkZ2V0Jyk7CiAgICAgICAgICAgICAgICAgICAgaWYoY2FwdGlvblNWRyl7CiAgICAgICAgICAgICAgICAgICAgICAgICQoY2FwdGlvblNWRykuYXR0cignZm9jdXNhYmxlJywgJ2ZhbHNlJyk7IC8vTEMtNzEwNSBMQy01NDQ0IHN2ZyB0YWJJbmRleCBkb2Vzbid0IHdvcmsgc28gYWRkaW5nIGZvY3VzYWJsZSBhcyBmYWxzZQogICAgICAgICAgICAgICAgICAgICAgICAvL0NRLTQyNzQ3MzIgOiBUbyBwcmV2ZW50IHN2ZyBiZWluZyByZWFkIG91dC4gQ2FwdGlvbihzdmcpIGFuZCBpbnB1dCBib3RoIGFyZSBiZWluZyByZWFkIGJ5IHNjcmVlbiByZWFkZXIsIG9ubHkgZm9jdXNzYWJsZSBzaG91bGQgYmUgcmVhZC4KICAgICAgICAgICAgICAgICAgICAgICAgJChjYXB0aW9uU1ZHKS5hdHRyKCdhcmlhLWhpZGRlbicsICd0cnVlJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjYXB0aW9uQ2hpbGRFeHRlbnQgPSB7fTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoKGhhc1BhcmVudEJ1dHRvbkZpZWxkICYmIGhhc1NpYmxpbmdCdXR0b25GaWVsZCkgfHwgKGhhc1BhcmVudFJhZGlvQnV0dG9uRmllbGQgJiYgaGFzU2libGluZ1JhZGlvQnV0dG9uRmllbGQpKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRpb25DaGlsZEV4dGVudFsid2lkdGgiXSA9ICIxMDAlIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRpb25DaGlsZEV4dGVudFsiaGVpZ2h0Il09ICIxMDAlIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcy5jYXB0aW9uKS5jc3MoIm92ZXJmbG93IiwgImhpZGRlbiIpOwogICAgICAgICAgICAgICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRpb25DaGlsZEV4dGVudFsid2lkdGgiXSA9ICIxMjAlIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRpb25DaGlsZEV4dGVudFsiaGVpZ2h0Il09ICIxMjAlIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3MoY2FwdGlvblNWRywgY2FwdGlvbkNoaWxkRXh0ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoJC5icm93c2VyLndlYmtpdCB8fCAkLmJyb3dzZXIuY2hyb21lIHx8IHhmYWxpYi51dC5VdGlsaXRpZXMuY2hlY2tNaW5Nb3ppbGxhVmVyc2lvbigyOCkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9jaHJvbWUgaGFuZGxlcyB0aGUgcnRsIHRleHQgZWxlbWVudCBpbiBhIGRpZmZlcmVudCB3YXkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RoZXJlIGlzIGEgc2ltaWxhciBmdW5jdGlvbiBpbiBYZmFEcmF3VmlldwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJChjYXB0aW9uU1ZHKS5jaGlsZHJlbigndGV4dFtkaXJlY3Rpb249InJ0bCJdJykuYXR0cigneCcsIHRoaXMuX2FkanVzdFRleHRDb29yZGluYXRlKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL0ludmFsaWRhdGUgdGhlIHRhYiBpbmRleGVzIGZvciB0aGUgcGFnZSBjb250YWluaW5nIHRoaXMgZmllbGQgd2hlbiB0aGlzIGZpZWxkIGlzIGluaXRpYWxpemVkLgogICAgICAgICAgICAgICAgLy9UaGlzIHdvdWxkIGp1c3QgcXVldWUgdGhlIHRhYmJpbmcgY29tcHV0YXRpb24gZm9yIHRoaXMgcGFydGljdWxhciBwYWdlLgogICAgICAgICAgICAgICAgdGhpcy5feGZhVmlld1JlZ2lzdHJ5KCkuaW52YWxpZGF0ZVRhYkluZGV4KHRoaXMuX3BhZ2VOdW1iZXIoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYW5kbGVQcmVPcGVuRXZlbnQ6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLmV4ZWNFdmVudCgicHJlT3BlbiIpOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUZvY3VzRXZlbnQ6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmKCF0aGlzLmNsaWNrZWRPbkNhcHRpb24pIHsKICAgICAgICAgICAgICAgIHRoaXMubW9kZWwuX3hmYSgpLnNldFN1YmZvcm1Gb2N1cyh0aGlzLm1vZGVsLnBhcmVudFN1YmZvcm0pOwogICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5leGVjRXZlbnQoImVudGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5jbGlja2VkT25DYXB0aW9uID0gZmFsc2U7IC8vIHJlc2V0IHRoZSBzdGF0ZQogICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9zZXRGb2N1c1BhcmFtKHRoaXMpOwogICAgICAgICAgICBpZihmb3JtQnJpZGdlKSB7CiAgICAgICAgICAgICAgICBpZihmb3JtQnJpZGdlLmlzQW5hbHl0aWNzRW5hYmxlZCkgeyAgIC8vT25seSBjb21wdXRpbmcgd2hlbiBhbmFseXRpY3MgZW5hYmxlZAogICAgICAgICAgICAgICAgICAgIHZhciBwcmV2Rm9jdXM9eGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5wcmV2Rm9jdXMsCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJGb2N1cz14ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1czsKICAgICAgICAgICAgICAgICAgICBpZihwcmV2Rm9jdXMpeyAgLy9pZiBwcmV2Rm9jdXMgaXMgYWxyZWFkeSBudWxsIHRoZW4gbm8gbmVlZCB0byBwYXNzIFNPTSBFeHByZXNzaW9uCiAgICAgICAgICAgICAgICAgICAgICAgIHByZXZGb2N1cz1wcmV2Rm9jdXMubW9kZWwuc29tRXhwcmVzc2lvbjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYoY3VyckZvY3VzKXsgLy9pZiBjdXJyRm9jdXMgaXMgYWxyZWFkeSBudWxsIHRoZW4gbm8gbmVlZCB0byBwYXNzIFNPTSBFeHByZXNzaW9uCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJGb2N1cz1jdXJyRm9jdXMubW9kZWwuc29tRXhwcmVzc2lvbjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLl90cmlnZ2VyT25CcmlkZ2UoImVsZW1lbnRGb2N1c0NoYW5nZWQiLCB0aGlzLm1vZGVsLCAiZm9jdXMiLCBwcmV2Rm9jdXMsIGN1cnJGb2N1cyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3JtQnJpZGdlLmNsaWNrZWRPbldpbmRvdyA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRm9jdXNPdXQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICBpZighdGhpcy5jbGlja2VkT25DYXB0aW9uKSB7CiAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLmV4ZWNFdmVudCgiZXhpdCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKGZvcm1CcmlkZ2UgJiYgZm9ybUJyaWRnZS5jbGlja2VkT25XaW5kb3cgPT09IHRydWUpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX3NldEZvY3VzUGFyYW0obnVsbCk7CiAgICAgICAgICAgICAgICBmb3JtQnJpZGdlLmNsaWNrZWRPbldpbmRvdyA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX3NldEZvY3VzUGFyYW0gOiBmdW5jdGlvbihjdXJyRm9jdXMpIHsKICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5wcmV2Rm9jdXMgPSB4ZmFsaWIudXQuQ2xhc3MucHJvdG90eXBlLmdldE9yRWxzZSh4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1cywgbnVsbCk7CiAgICAgICAgICAgIC8vVG8gbWluaW1pemUgcmVncmVzc2lvbiBpbXBhY3QgYXMgInhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuY3VycmVudEZvY3VzIiBpcyB1c2VkIGF0IGFsbCB0aGUgcGxhY2VzIGluIHRoZSBjb2RlCiAgICAgICAgICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuY3VycmVudEZvY3VzPWN1cnJGb2N1czsKICAgICAgICB9LAoKICAgICAgICBfY2xlYXJGb2N1c0luZm8gOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5wcmV2Rm9jdXMgPSBudWxsOwogICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1cz1udWxsOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUtleVByZXNzRXZlbnQ6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciBjb2RlID0gZXZlbnQuY2hhckNvZGUgfHwgZXZlbnQud2hpY2ggfHwgZXZlbnQua2V5Q29kZSB8fCAwOwogICAgICAgICAgICB2YXIgY2hhcmFjdGVyID0gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKTsKCiAgICAgICAgICAgIGlmKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5pc05vblByaW50YWJsZUtleShldmVudC5rZXkpKSB7IC8vIG1vemlsbGEgYWxzbyBnZW5lcmF0ZXMgYSBrZXlwcmVzcywgYWxvbmcgd2l0aCBrZXlkb3duCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBhbGwga2V5cywgc28gb25seSBoYW5kbGluZyBwcmludGFibGUga2V5cyBpbiBrZXlwcmVzcwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZih0aGlzLmNoYXJhY3RlciAhPSB1bmRlZmluZWQpIHsgLy8gdGFrZXMgY2FyZSBvZiBjYXNlcyB3aGVuIHhmYS5ldmVudC5jaGFuZ2UgaXMgc2V0IGJ5IHVzZXIgc2NyaXB0CiAgICAgICAgICAgICAgICBpZih0aGlzLmNoYXJhY3RlciA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24oInZhbHVlIix0aGlzLmpxV2lkZ2V0Lm9wdGlvbigiY3VyVmFsdWUiKSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24oImRpc3BsYXlWYWx1ZSIsdGhpcy5qcVdpZGdldC5vcHRpb24oImN1clZhbHVlIikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZih0aGlzLmNoYXJhY3RlciAhPSBjaGFyYWN0ZXIgJiYKICAgICAgICAgICAgICAgICAgICAhKGV2ZW50LmtleSA9PT0gIkVudGVyIiAmJiB0aGlzLmNoYXJhY3RlciA9PT0gIlxuIikpIHsKICAgICAgICAgICAgICAgICAgICAvL1N0cmluZy5mcm9tQ2hhckNvZGUgcmV0dXJucyBcciBmb3IgRW50ZXIga2V5LCBidXQgY2hhcmFjdGVyIGlzIFxuIC0gaWdub3JlIHRoaXMgbWlzbWF0Y2gKICAgICAgICAgICAgICAgICAgICB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigidmFsdWUiLHRoaXMuY3VycmVudCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24oImRpc3BsYXlWYWx1ZSIsdGhpcy5jdXJyZW50KTsKICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5jaGFyYWN0ZXIgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfc3luY0Zvcm1Ob2RlVG9IdG1sIDogZnVuY3Rpb24oZGVlcFN5bmMpIHsKICAgICAgICAgICAgdmFyIHBsdWdpbk9wdGlvbnMgPSB0aGlzLl9jcmVhdGVQbHVnaW5PcHRpb25zKCk7CiAgICAgICAgICAgIGlmKCF0aGlzLmpxV2lkZ2V0KQogICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVXaWRnZXRQbHVnaW4ocGx1Z2luT3B0aW9ucyk7CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgXy5lYWNoKHBsdWdpbk9wdGlvbnMsIGZ1bmN0aW9uKHZhbHVlLCBrZXkpewogICAgICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQub3B0aW9uKGtleSwgdmFsdWUpOwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5fbWFya0FjY2Vzcyh0aGlzLm1vZGVsLm1FZmZlY3RpdmVBY2Nlc3MpCiAgICAgICAgICAgIGlmKHRoaXMubW9kZWwuX19lcnJvclRleHQpCiAgICAgICAgICAgICAgICB0aGlzLl9kZWZlcnJlZE1hcmtFcnJvcigpOwogICAgICAgICAgICB4ZmFsaWIudmlldy5CYXNlVmlldy5wcm90b3R5cGUuX3N5bmNGb3JtTm9kZVRvSHRtbC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZU1vZGVsQ2hhbmdlZCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmIChldmVudC5fcHJvcGVydHkgPT0gdGhpcy5jb21taXRUYXJnZXQpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVZhbHVlQ2hhbmdlKGV2ZW50KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgc3dpdGNoKGV2ZW50Ll9wcm9wZXJ0eSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgImZvY3VzIjoKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZm9jdXNXaWRnZXQodGhpcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIlZhbGlkYXRpb25TdGF0ZSIgOgogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYXJrRXJyb3IoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJjaGFuZ2UiOgogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVFdmVudENoYW5nZVByb3BlcnR5KGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiQ2xlYXJFcnJvciI6CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NsZWFyRXJyb3IoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJmaWxsQ29sb3IiOgogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9maWxsQ29sb3IoZXZlbnQubmV3VGV4dCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5oYW5kbGVNb2RlbENoYW5nZWQuYXBwbHkodGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRG9tQ2hhbmdlZCA6ZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICBzd2l0Y2goZXZlbnQuX3Byb3BlcnR5KSB7CiAgICAgICAgICAgICAgICBjYXNlICJmb250LmZpbGwuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUZvbnRGaWxsQ29sb3JWYWx1ZShldmVudC5wcmV2VGV4dCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJmb250LnBvc3R1cmUiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUZvbnRQb3N0dXJlKGV2ZW50LnByZXZUZXh0KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInZhbHVlLm1heENoYXJzIjoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVNYXhDaGFycyhldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJjYXB0aW9uLmZvbnQuZmlsbC5jb2xvci52YWx1ZSI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQ2FwdGlvbkZvbnRGaWxsQ29sb3JWYWx1ZShldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJudWxsVGVzdCI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlTnVsbFRlc3QoZXZlbnQsICQodGhpcy53aWRnZXQpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLmhhbmRsZURvbUNoYW5nZWQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVOdWxsVGVzdDogZnVuY3Rpb24gKGV2ZW50LCAkdGFyZ2V0KSB7CiAgICAgICAgICAgIHRoaXMuX2hhbmRsZU1hbmRhdG9yeShldmVudC5uZXdUZXh0LCAkdGFyZ2V0KTsKICAgICAgICAgICAgdGhpcy5faGFuZGxlRGlzYWJsZWQoZXZlbnQpOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVNYW5kYXRvcnk6IGZ1bmN0aW9uIChjaGFuZ2UsICR0YXJnZXQpIHsKICAgICAgICAgICAgaWYgKF8uY29udGFpbnMoWydkaXNhYmxlZCcsICd3YXJuaW5nJ10sIGNoYW5nZSkpIHsKICAgICAgICAgICAgICAgICR0YXJnZXQuYXR0cignZGF0YS1tYW5kYXRvcnknLCAnZmFsc2UnKQogICAgICAgICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnd2lkZ2V0TWFuZGF0b3J5Qm9yZGVyJyk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hhbmdlID09PSAnZXJyb3InKSB7CiAgICAgICAgICAgICAgICAkdGFyZ2V0LmF0dHIoJ2RhdGEtbWFuZGF0b3J5JywgJ3RydWUnKQogICAgICAgICAgICAgICAgICAgICAgIC50b2dnbGVDbGFzcygid2lkZ2V0TWFuZGF0b3J5Qm9yZGVyIiwgeGZhbGliLmdsb2JhbHMuaGlnaGxpZ2h0KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVEaXNhYmxlZDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgIHZhciBjaGFuZ2UgPSBldmVudC5uZXdUZXh0OwogICAgICAgICAgIGlmIChjaGFuZ2UgPT09ICdkaXNhYmxlZCcpIHsKICAgICAgICAgICAgICB0aGlzLl9jbGVhckVycm9yKGV2ZW50KTsKICAgICAgICAgICB9CiAgICAgICAgfSwKCgogICAgICAgIF9oYW5kbGVDYXB0aW9uRm9udEZpbGxDb2xvclZhbHVlIDpmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICB2YXIgY2hpbGRTdmcgPSB0aGlzLmNhcHRpb24uY2hpbGRyZW5bMF07CiAgICAgICAgICAgIHZhciBmaWxsID0gInJnYigiICsgZXZlbnQucHJldlRleHQgKyAiKSIgOwoKICAgICAgICAgICAgaWYoY2hpbGRTdmcudGFnTmFtZSA9PSAic3ZnIiAmJiBjaGlsZFN2Zy5jaGlsZE5vZGVzKSB7CiAgICAgICAgICAgICAgXy5lYWNoKGNoaWxkU3ZnLmNoaWxkTm9kZXMsZnVuY3Rpb24obm9kZSxpbmRleCl7CiAgICAgICAgICAgICAgICBpZihub2RlLnRhZ05hbWUgPT0gJ3RleHQnKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKG5vZGUseydmaWxsJyA6IGZpbGx9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9LHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUZvbnRGaWxsQ29sb3JWYWx1ZSA6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigiY29sb3IiLCB2YWx1ZSk7CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUZvbnRQb3N0dXJlIDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgIHRoaXMuanFXaWRnZXQub3B0aW9uKCJmb250LXN0eWxlIiwgdmFsdWUpOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVNYXhDaGFycyA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciBtYXhjaGFycyA9IGV2ZW50LnByZXZUZXh0OwogICAgICAgICAgICBpZihtYXhjaGFycykKICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQub3B0aW9uKCJtYXhDaGFycyIsZXZlbnQucHJldlRleHQpOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUNvbW1pdCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciByZXNpemVScWQgPSBmYWxzZTsKICAgICAgICAgICAgaWYodGhpcy5yZXNpemFibGUgJiYgdGhpcy5qcVdpZGdldC5vcHRpb24oInZhbHVlIikgIT0gdGhpcy5tb2RlbFt0aGlzLmNvbW1pdFRhcmdldF0pCiAgICAgICAgICAgICAgICByZXNpemVScWQgPSB0cnVlOwogICAgICAgICAgICB0aGlzLm1vZGVsW3RoaXMuY29tbWl0VGFyZ2V0XSA9IHRoaXMuanFXaWRnZXQub3B0aW9uKCJ2YWx1ZSIpOwogICAgICAgICAgICBpZihyZXNpemVScWQpCiAgICAgICAgICAgICAgICB0aGlzLmludmFsaWRhdGVTaXplKCk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlQ2hhbmdlRXZlbnQgOiBmdW5jdGlvbihjaGFuZ2VFdmVudCkgewogICAgICAgICAgICB2YXIgY3VycmVudCwKICAgICAgICAgICAgICAgIGV2ZW50ID0gY2hhbmdlRXZlbnQub3JpZ2luYWxFdmVudCwKICAgICAgICAgICAgICAgIG1heENoYXJzID0gcGFyc2VJbnQodGhpcy5qcVdpZGdldC5vcHRpb24oIm1heENoYXJzIikgfHwgdGhpcy5qcVdpZGdldC5vcHRpb24oImNvbWJDZWxscyIpKSB8fCAwLCAvLyB0byB0YWtlIGNhcmUgZm9yIGJvdGggdGV4dCAmIG51bWVyaWMgZmllbGRzCiAgICAgICAgICAgICAgICB2YWwgPSB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigiY3VyVmFsdWUiKSB8fCB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigiZGlzcGxheVZhbHVlIikgfHwgJycsCiAgICAgICAgICAgICAgICBzZWxlY3Rpb25TdGFydCA9IGV2ZW50LnNlbGVjdGlvblN0YXJ0LAogICAgICAgICAgICAgICAgc2VsZWN0aW9uRW5kID0gZXZlbnQuc2VsZWN0aW9uRW5kLAogICAgICAgICAgICAgICAgY29kZSA9IGV2ZW50LmNoYXJDb2RlIHx8IGV2ZW50LmtleUNvZGUgfHwgZXZlbnQud2hpY2gsCiAgICAgICAgICAgICAgICBjaGFyYWN0ZXIgPSBldmVudC5jaGFyYWN0ZXIgfHwgJycsCiAgICAgICAgICAgICAgICBjaGFuZ2UsCiAgICAgICAgICAgICAgICBmdWxsVGV4dDsKCiAgICAgICAgICAgIGlmKGV2ZW50Lm9yaWdpbmFsVHlwZSA9PSAiY3V0IikgewogICAgICAgICAgICAgICAgY2hhbmdlID0gIiI7CiAgICAgICAgICAgICAgICBpZih2YWwpIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gdmFsLnN1YnN0cigwLCBzZWxlY3Rpb25TdGFydCkgKyB2YWwuc3Vic3RyKHNlbGVjdGlvbkVuZCk7CiAgICAgICAgICAgICAgICAgICAgZnVsbFRleHQgPSBjdXJyZW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYoZXZlbnQub3JpZ2luYWxUeXBlID09ICJrZXlkb3duIikgewogICAgICAgICAgICAgICAgY2hhbmdlID0gIiI7CgogICAgICAgICAgICAgICAgaWYodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvZGUgPT0gOCB8fCBjb2RlID09IDQ2KSB7ICAvLyBiYWNrU3BhY2Ugb3IgRGVsCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3Rpb25TdGFydCAhPT0gc2VsZWN0aW9uRW5kKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gdmFsLnN1YnN0cigwLCBzZWxlY3Rpb25TdGFydCkgKyB2YWwuc3Vic3RyKHNlbGVjdGlvbkVuZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29kZSA9PSA4KSB7ICAvLyBiYWNrc3BhY2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gdmFsLnN1YnN0cigwLCBzZWxlY3Rpb25TdGFydCAtIDEpICsgdmFsLnN1YnN0cihzZWxlY3Rpb25TdGFydCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29kZSA9PSA0NikgeyAgLy8gZGVsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudCA9IHZhbC5zdWJzdHIoMCwgc2VsZWN0aW9uU3RhcnQpICsgdmFsLnN1YnN0cihzZWxlY3Rpb25TdGFydCArIDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gdmFsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZnVsbFRleHQgPSBjdXJyZW50OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgeyAvLyBrZXlwcmVzcyBvciBwYXN0ZQogICAgICAgICAgICAgICAgY2hhbmdlID0gY2hhcmFjdGVyOwogICAgICAgICAgICAgICAgaWYgKG1heENoYXJzID4gMCApIHsKICAgICAgICAgICAgICAgICAgICBpZiAodmFsLmxlbmd0aCAtIChzZWxlY3Rpb25FbmQgLSBzZWxlY3Rpb25TdGFydCkgPj0gbWF4Q2hhcnMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlID0gIiI7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlID0gY2hhcmFjdGVyLnN1YnN0cigwLCBtYXhDaGFycyAtIHZhbC5sZW5ndGggKyBzZWxlY3Rpb25FbmQgLSBzZWxlY3Rpb25TdGFydCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gdmFsLnN1YnN0cigwLCBzZWxlY3Rpb25TdGFydCkgKyBjaGFuZ2UgKyB2YWwuc3Vic3RyKHNlbGVjdGlvbkVuZCk7CiAgICAgICAgICAgICAgICAgICAgZnVsbFRleHQgPSB2YWwuc3Vic3RyKDAsIHNlbGVjdGlvblN0YXJ0KSArIGNoYXJhY3RlciArIHZhbC5zdWJzdHIoc2VsZWN0aW9uRW5kKTsKCiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgPSBjaGFuZ2U7CiAgICAgICAgICAgICAgICAgICAgZnVsbFRleHQgPSBjaGFyYWN0ZXI7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYoIChtYXhDaGFycyAhPTAgJiYgY3VycmVudC5sZW5ndGggID4gbWF4Q2hhcnMpIHx8ICF0aGlzLmpxV2lkZ2V0Lm9wdGlvbigibGVuZ3RoTGltaXRWaXNpYmxlIikgKSB7CiAgICAgICAgICAgICAgICAgICAgY2hhbmdlID0gIiI7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudCA9IHZhbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBMQy02MjkwIDogcHJldmVudCBwYXN0ZSBmcm9tIHRydW5jYXRpbmcgYW55IG9mIHRoZSBwcmV2aW91cyB0ZXh0CiAgICAgICAgICAgICAgICBpZiAoZXZlbnQub3JpZ2luYWxUeXBlID09ICJwYXN0ZSIgJiYKICAgICAgICAgICAgICAgICAgICAoKG1heENoYXJzICE9IDAgJiYgZnVsbFRleHQubGVuZ3RoID4gbWF4Q2hhcnMpIHx8ICF0aGlzLmpxV2lkZ2V0Lm9wdGlvbigibGVuZ3RoTGltaXRWaXNpYmxlIikpKSB7IC8vIFRPRE8gOiB0YWtlIGNhcmUgb2YgbXVsdGlsaW5lIHNlbGVjdGlvbiBsYXRlcgogICAgICAgICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpczsKICAgICAgICAgICAgICAgICAgICBzZWxmLmpxV2lkZ2V0LiR1c2VyQ29udHJvbC5vbmUoImlucHV0IiwgZnVuY3Rpb24gKCkgeyAgLy8gd2FpdCB0aWxsIHRoZSBwYXN0ZSBhY3Rpb24gb2NjdXJzIGFuZCB0aGVuIHJlcGxhY2Ugd2l0aCBjb3JyZWN0IHZhbHVlCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuanFXaWRnZXQuJHVzZXJDb250cm9sLnZhbChjdXJyZW50KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wcm9wKCJzZWxlY3Rpb25TdGFydCIsIHNlbGVjdGlvbkVuZCkgLy8gTEMtNjI5MCA6IHJlc2V0IHRoZSBjdXJzb3IgcG9zIGFmdGVyd2FyZHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucHJvcCgic2VsZWN0aW9uRW5kIiwgc2VsZWN0aW9uRW5kKTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGRldGFpbCA9IHsKICAgICAgICAgICAgICAgIHByZXZUZXh0OnZhbCwKICAgICAgICAgICAgICAgIGtleWNvZGU6Y29kZSwKICAgICAgICAgICAgICAgIG1vZGlmaWVyOmV2ZW50LmN0cmxLZXksCiAgICAgICAgICAgICAgICBrZXlEb3duOiBldmVudC5rZXlEb3duLAogICAgICAgICAgICAgICAgc2hpZnQ6ZXZlbnQuc2hpZnRLZXksCiAgICAgICAgICAgICAgICBjaGFuZ2U6Y2hhbmdlLAogICAgICAgICAgICAgICAgbmV3VGV4dDpjdXJyZW50LAogICAgICAgICAgICAgICAgZnVsbFRleHQ6IGZ1bGxUZXh0CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIGlmKCEhY2hhbmdlIHx8IGN1cnJlbnQgIT0gdmFsKQogICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5leGVjRXZlbnQoImNoYW5nZSIsIGRldGFpbCk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlQ2xpY2tFdmVudCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciBwcmV2VmFsdWU9IHRoaXMuanFXaWRnZXQub3B0aW9uKCJ2YWx1ZSIpOwogICAgICAgICAgICB2YXIgZGV0YWlsID0gewogICAgICAgICAgICAgICAga2V5Y29kZTpldmVudC53aGljaCwKICAgICAgICAgICAgICAgIG1vZGlmaWVyOmV2ZW50LmN0cmxLZXksCiAgICAgICAgICAgICAgICBzaGlmdDpldmVudC5zaGlmdEtleQogICAgICAgICAgICB9OwogICAgICAgICAgICB0aGlzLm1vZGVsLmV4ZWNFdmVudCgiY2xpY2siLCBkZXRhaWwpOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVFdmVudENoYW5nZVByb3BlcnR5IDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgdGhpcy5jaGFyYWN0ZXIgPSBldmVudC5wcmV2VGV4dDsKICAgICAgICAgICAgdmFyIHByZXZWYWx1ZT0gdGhpcy5qcVdpZGdldC5vcHRpb24oImN1clZhbHVlIikgfHwgdGhpcy5qcVdpZGdldC5vcHRpb24oImRpc3BsYXlWYWx1ZSIpIHx8ICIiOwogICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5qcVdpZGdldC5vcHRpb25zLnBvcyA7CiAgICAgICAgICAgIHRoaXMuY3VycmVudCA9IHByZXZWYWx1ZS5zdWJzdHIoMCwgcG9zKSArIHRoaXMuY2hhcmFjdGVyICsgcHJldlZhbHVlLnN1YnN0cihwb3MpOwogICAgICAgICAgICAvL3ZhciB2YWx1ZSA9IHRoaXMuanFXaWRnZXQub3B0aW9uKCJ2YWx1ZSIpIHx8ICIiIDsKICAgICAgICAgICAgLy92YXIgZGlzcGxheVZhbHVlID0gdGhpcy5qcVdpZGdldC5vcHRpb24oImRpc3BsYXlWYWx1ZSIpIHx8ICIiICAgOwoKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlVmFsdWVDaGFuZ2UgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAvL3hmYS5Mb2dnZXIuZGVidWcoIltGaWVsZFZpZXcuX2hhbmRsZVZhbHVlQ2hhbmdlXXZhbHVlOnNvbSIKICAgICAgICAgICAgLy8gICAgICAgICsgZXZlbnQubmV3VGV4dCArICI6IiArIHRoaXMuJGVsLmRhdGEoInNvbSIpKTsKICAgICAgICAgICAgdmFyIHJlc2l6ZVJlcXVpcmVkID0gICh0aGlzLmpxV2lkZ2V0Lm9wdGlvbigiZGlzcGxheVZhbHVlIikgIT0gZXZlbnQubmV3VGV4dCkgJiYgdGhpcy5yZXNpemFibGUgOwogICAgICAgICAgICB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigidmFsdWUiLGV2ZW50LnByZXZUZXh0KTsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24oImRpc3BsYXlWYWx1ZSIsZXZlbnQubmV3VGV4dCk7CiAgICAgICAgICAgIGlmKHJlc2l6ZVJlcXVpcmVkKXsKICAgICAgICAgICAgICAgIHRoaXMuaW52YWxpZGF0ZVNpemUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9tYXJrRXJyb3IgOiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgIC8vdGhpcy4kY3NzKHRoaXMud2lkZ2V0LCAiYmFja2dyb3VuZC1jb2xvciIsIiNEM0QzRDMiKTsKICAgICAgICAgICAgJCh0aGlzLndpZGdldCkuYWRkQ2xhc3MoIndpZGdldEVycm9yIik7CiAgICAgICAgICAgIHRoaXMuanFXaWRnZXQubWFya0Vycm9yKGV2bnQubmV3VGV4dCwgZXZudC5wcmV2VGV4dCk7CiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVdpZGdldE9wdGlvbigiaXNWYWxpZCIsZmFsc2UpOwogICAgICAgIH0sCgogICAgICAgIF9kZWZlcnJlZE1hcmtFcnJvciA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAvL3RoaXMuJGNzcyh0aGlzLndpZGdldCwgImJhY2tncm91bmQtY29sb3IiLCIjRDNEM0QzIik7CiAgICAgICAgICAgIGlmKHRoaXMubW9kZWwubWFuZGF0b3J5ID09ICJlcnJvciIpCiAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5hZGRDbGFzcygid2lkZ2V0RXJyb3IiKTsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5tYXJrRXJyb3IodGhpcy5tb2RlbC5fX2Vycm9yVGV4dCwgdGhpcy5tb2RlbC5tYW5kYXRvcnkpOwogICAgICAgICAgICB0aGlzLl91cGRhdGVXaWRnZXRPcHRpb24oImlzVmFsaWQiLGZhbHNlKTsKICAgICAgICB9LAoKICAgICAgICBfY2xlYXJFcnJvciA6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgLy90aGlzLiRjc3ModGhpcy53aWRnZXQsICJiYWNrZ3JvdW5kLWNvbG9yIiwgIndoaXRlIik7CiAgICAgICAgICAgICQodGhpcy53aWRnZXQpLnJlbW92ZUNsYXNzKCJ3aWRnZXRFcnJvciIpOwogICAgICAgICAgICB0aGlzLmpxV2lkZ2V0LmNsZWFyRXJyb3IoKTsKICAgICAgICAgICAgdGhpcy5fdXBkYXRlV2lkZ2V0T3B0aW9uKCJpc1ZhbGlkIix0cnVlKTsKICAgICAgICB9LAoKICAgICAgICAvLyBmb3IgYWxsIGZpZWxkcwogICAgICAgIF91cGRhdGVXaWRnZXRPcHRpb246IGZ1bmN0aW9uKG9wdGlvbk5hbWUsIG9wdGlvblZhbHVlKXsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24ob3B0aW9uTmFtZSwgb3B0aW9uVmFsdWUpOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVBY2Nlc3NDaGFuZ2UgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAvL3hmYS5Mb2dnZXIuZGVidWcoIltfaGFuZGxlQWNjZXNzQ2hhbmdlXWFjY2Vzczpzb20iCiAgICAgICAgICAgIC8vICAgICAgICArIGV2ZW50Lm5ld1RleHQgKyAiOiIgKyB0aGlzLiRlbC5kYXRhKCJzb20iKSk7CiAgICAgICAgICAgIHRoaXMuanFXaWRnZXQub3B0aW9uKCJhY2Nlc3MiLGV2ZW50Lm5ld1RleHQpOwogICAgICAgICAgICBpZihldmVudC5uZXdUZXh0ICE9IGV2ZW50LnByZXZUZXh0KQogICAgICAgICAgICAgICAgdGhpcy5fbWFya0FjY2VzcyhldmVudC5uZXdUZXh0KQogICAgICAgIH0sCgogICAgICAgIF9maW5kV2lkZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICh0aGlzLiRlbC5oYXNDbGFzcygid2lkZ2V0IikpCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy4kZWwuZ2V0KDApOwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciB3aWRnZXRMaXN0ID0gdGhpcy4kZWwuZmluZCgiLndpZGdldCIpOwogICAgICAgICAgICAgICAgaWYgKHdpZGdldExpc3QubGVuZ3RoID4gMCl7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdpZGdldExpc3QuZ2V0KDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBfZmluZENhcHRpb24gOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIGNhcHRpb25MaXN0ID0gJCgiLmNhcHRpb24iLCB0aGlzLiRlbCk7CiAgICAgICAgICAgIGlmIChjYXB0aW9uTGlzdC5sZW5ndGggPiAwKXsKICAgICAgICAgICAgICAgIHJldHVybiBjYXB0aW9uTGlzdC5nZXQoMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZ2V0UGFyYVN0eWxlcyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciBwYXJhU3R5bGVzID0ge30scGFyYTsKICAgICAgICAgICAgcGFyYSA9IHRoaXMubW9kZWwuZ2V0RWxlbWVudCgicGFyYSIsIDAsIHRydWUpOwogICAgICAgICAgICBpZihwYXJhKXsKICAgICAgICAgICAgICAgIHBhcmFTdHlsZXMgPSB7CiAgICAgICAgICAgICAgICAgICAgInRleHQtYWxpZ24iIDogcGFyYS5oQWxpZ24sCiAgICAgICAgICAgICAgICAgICAgInZlcnRpY2FsLWFsaWduIiA6IHBhcmEudkFsaWduLAogICAgICAgICAgICAgICAgICAgICJ0ZXh0LWluZGVudCIgOiB0aGlzLl9jb252ZXJ0VG9QeChwYXJhLnRleHRJbmRlbnQpLAogICAgICAgICAgICAgICAgICAgICJwYWRkaW5nLWxlZnQiIDogdGhpcy5fY29udmVydFRvUHgocGFyYS5tYXJnaW5MZWZ0KSwKICAgICAgICAgICAgICAgICAgICAicGFkZGluZy1yaWdodCIgOiB0aGlzLl9jb252ZXJ0VG9QeChwYXJhLm1hcmdpblJpZ2h0KSwKICAgICAgICAgICAgICAgICAgICAicGFkZGluZy10b3AiIDogdGhpcy5fY29udmVydFRvUHgocGFyYS5zcGFjZUFib3ZlKSwKICAgICAgICAgICAgICAgICAgICAicGFkZGluZy1ib3R0b20iIDogdGhpcy5fY29udmVydFRvUHgocGFyYS5zcGFjZUJlbG93KQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcGFyYVN0eWxlczsKICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlUGx1Z2luT3B0aW9ucyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpZih0aGlzLm1vZGVsKXsKICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMubW9kZWxbdGhpcy5jb21taXRUYXJnZXRdIHx8IG51bGw7CiAgICAgICAgICAgICAgICB2YXIgc2NyZWVuUmVhZGVyVGV4dDsKICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHQgPSB0aGlzLl9nZXRTY3JlZW5SZWFkZXJUZXh0KCk7CiAgICAgICAgICAgICAgICB2YXIgdGFiSW5kZXggPSAwOwogICAgICAgICAgICAgICAgaWYodGhpcy5tb2RlbC5qc29uTW9kZWwuZXh0cmFzICYmIHRoaXMubW9kZWwuanNvbk1vZGVsLmV4dHJhcy50YWJJbmRleCkgewogICAgICAgICAgICAgICAgICAgIHRhYkluZGV4ID0gdGhpcy5tb2RlbC5qc29uTW9kZWwuZXh0cmFzLnRhYkluZGV4OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBsYW5nID0gdGhpcy5fbGFuZ0Zyb21Mb2NhbGUodGhpcy5tb2RlbC5fZ2V0TG9jYWxlKCkpOwogICAgICAgICAgICAgICAgdmFyIGRpcmVjdGlvbjsKCiAgICAgICAgICAgICAgICBpZihsYW5nICYmIHRoaXMuX3J0bExhbmdbbGFuZ10pewogICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9ICJydGwiOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBwYXJhU3R5bGVzID0gdGhpcy5fZ2V0UGFyYVN0eWxlcygpOwogICAgICAgICAgICAgICAgdmFyIHdpZGdldE1vZGVsID0gdGhpcy53aWRnZXRMYXlvdXRNb2RlbCB8fCB0aGlzLmxheW91dE1vZGVsOwogICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICAibmFtZSIgOiB0aGlzLm1vZGVsLmpzb25Nb2RlbC5uYW1lKyIiK3RoaXMuX2lkLAogICAgICAgICAgICAgICAgICAgICJ2YWx1ZSIgOiB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAiZGlzcGxheVZhbHVlIjogdGhpcy5tb2RlbC5mb3JtYXR0ZWRWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAiY29tbWl0UHJvcGVydHkiIDogdGhpcy5jb21taXRQcm9wZXJ0eSwKICAgICAgICAgICAgICAgICAgICAiYWNjZXNzIjogdGhpcy5tb2RlbC5tRWZmZWN0aXZlQWNjZXNzLAogICAgICAgICAgICAgICAgICAgICJwbGF0Zm9ybSI6IHRoaXMubW9kZWwuX3hmYSgpLmhvc3QucGxhdGZvcm0sCiAgICAgICAgICAgICAgICAgICAgInNjcmVlblJlYWRlclRleHQiOiBzY3JlZW5SZWFkZXJUZXh0LAogICAgICAgICAgICAgICAgICAgIC8qInRhYkluZGV4IjogdGFiSW5kZXgsKi8KICAgICAgICAgICAgICAgICAgICAicGFyYVN0eWxlcyIgOiBwYXJhU3R5bGVzLAogICAgICAgICAgICAgICAgICAgICJkaXIiIDogZGlyZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICJoU2Nyb2xsRGlzYWJsZWQiIDogIXRoaXMucmVzaXphYmxlICYmIHRoaXMubW9kZWwudWkub25lT2ZDaGlsZC5oU2Nyb2xsUG9saWN5ID09PSAib2ZmIiwKICAgICAgICAgICAgICAgICAgICAiaGVpZ2h0IiA6IHdpZGdldE1vZGVsLmV4dGVudGggKyB3aWRnZXRNb2RlbC5ib3JkZXJ0b3AvMiArIHdpZGdldE1vZGVsLmJvcmRlcmJvdHRvbS8yLAogICAgICAgICAgICAgICAgICAgICJjb21taXRFdmVudCIgOiB0aGlzLmNvbW1pdEV2ZW50CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIF9nZXRTY3JlZW5SZWFkZXJUZXh0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBzY3JlZW5SZWFkZXJUZXh0ID0gIiI7CiAgICAgICAgICAgIGlmICh0aGlzLm1vZGVsKSB7CiAgICAgICAgICAgICAgICB2YXIgYXNzaXN0ID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCJhc3Npc3QiLCAwLCB0cnVlKTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmdldE9yRWxzZShhc3Npc3QsICJzcGVhay5kaXNhYmxlIiwgMCkgIT0gMSkgeyAvLyBsb29zZSBjb21wYXJlIHN0cmluZyB2YWx1ZQoKICAgICAgICAgICAgICAgICAgICB2YXIgcHJpb3JpdHkgPSB0aGlzLmdldE9yRWxzZShhc3Npc3QsICJzcGVhay5wcmlvcml0eSIsICJzcGVhayIpLAogICAgICAgICAgICAgICAgICAgICAgICBjYW5kaWRhdGVzID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNwZWFrIjogdGhpcy5nZXRPckVsc2UoYXNzaXN0LCAic3BlYWsudmFsdWUiLCAiIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2FwdGlvbiI6IHRoaXMuZ2V0T3JFbHNlKHRoaXMubW9kZWwsICJqc29uTW9kZWwuZXh0cmFzLmNhcHRpb24iLCAiIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidG9vbFRpcCI6IHRoaXMuZ2V0T3JFbHNlKGFzc2lzdCwgInRvb2xUaXAudmFsdWUiLCAiIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibmFtZSI6IHRoaXMuZ2V0T3JFbHNlKHRoaXMubW9kZWwsICJqc29uTW9kZWwubmFtZSIsICIiKQogICAgICAgICAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgICAgICBzY3JlZW5SZWFkZXJUZXh0ID0gY2FuZGlkYXRlc1twcmlvcml0eV0gfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FuZGlkYXRlc1sic3BlYWsiXSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYW5kaWRhdGVzWyJjYXB0aW9uIl0gfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FuZGlkYXRlc1sidG9vbFRpcCJdIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbmRpZGF0ZXNbIm5hbWUiXTsKICAgICAgICAgICAgICAgICAgICAvLyBDUS04NTE4MyA6IGdvaW5nIGFnYWluc3QgeGZhIHNwZWMgKHBnIDUwNSkgcHJpb3JpdGlzZSBjYXB0aW9uIG92ZXIgdG9vbHRpcAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzY3JlZW5SZWFkZXJUZXh0OwogICAgICAgIH0sCgogICAgICAgIF9hc3NpZ25Ub29sVGlwOiB4ZmFsaWIudmlldy5YZmFEcmF3Vmlldy5wcm90b3R5cGUuX2Fzc2lnblRvb2xUaXAsCgoJCV9pbnN0YW50aWF0ZVdpZGdldDpmdW5jdGlvbih3aWRnZXROYW1lLG9wdGlvbnMpewoJCSAgICBpZiAod2lkZ2V0TmFtZSAmJiB3aWRnZXROYW1lLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICB0cnl7CiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpW3dpZGdldE5hbWVdKG9wdGlvbnMpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy4kZGF0YSh0aGlzLndpZGdldCwgd2lkZ2V0TmFtZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtIit3aWRnZXROYW1lKTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmVycm9yKCJ4ZmFWaWV3IiwgImV4Y2VwdGlvbiAiK2V4Y2VwdGlvbi5tZXNzYWdlKyIgaW4gY3JlYXRpbmcgdXNlciB3aWRnZXQuIHdpZGdldDoiK3dpZGdldE5hbWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoJCX0sCiAgICAgICAgX2NyZWF0ZVNjcmliYmxlV2lkZ2V0T3B0aW9uczpmdW5jdGlvbihvcHRpb25zKXsKICAgICAgICAgICAgdmFyIGluaXRQYXJhbXMgPSB0aGlzLmdldE9yRWxzZSh0aGlzLm1vZGVsLnVpLCJleHRyYXMuY2hpbGRyZW4iLG51bGwpOwogICAgICAgICAgICB2YXIgZ2VvTG9jUGFyYW0gPSBfLmZpbmQoaW5pdFBhcmFtcyxmdW5jdGlvbihvYmopewoJICAgICAgICAgICAgcmV0dXJuIG9iaiYmb2JqLm5hbWU9PSJnZW9Mb2NNYW5kYXRvcnlPbklwYWQiOyAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICB2YXIgZ2VvTG9jTWFuZGF0b3J5T25JcGFkID0gKGdlb0xvY1BhcmFtJiZnZW9Mb2NQYXJhbS52YWx1ZSkgfHwgKCB3aW5kb3cuZm9ybUJyaWRnZS51c2VyQ29uZmlnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgd2luZG93LmZvcm1CcmlkZ2UudXNlckNvbmZpZ1snc2NyaWJibGVJbWFnZUZpZWxkQ29uZmlnJ10KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiB3aW5kb3cuZm9ybUJyaWRnZS51c2VyQ29uZmlnWydzY3JpYmJsZUltYWdlRmllbGRDb25maWcnXS5nZW9Mb2NNYW5kYXRvcnlPbklwYWQgKTsKICAgICAgICAgICAgcmV0dXJuIF8uZXh0ZW5kKHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvTG9jTWFuZGF0b3J5T25JcGFkOmdlb0xvY01hbmRhdG9yeU9uSXBhZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxvcHRpb25zKTsKICAgICAgICB9LAogICAgICAgIGNyZWF0ZVdpZGdldFBsdWdpbiA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgdmFyIHdpZGdldENvbmZpZyA9IHRoaXMuX3hmYVZpZXdSZWdpc3RyeSgpLndpZGdldENvbmZpZygpOwogICAgICAgICAgICB2YXIgd2lkZ2V0TmFtZTsKCQkJCiAgICAgICAgICAgIGlmKHdpZGdldENvbmZpZyl7CiAgICAgICAgICAgICAgICAgICAgd2lkZ2V0TmFtZSA9IF8uZmlsdGVyKHdpZGdldENvbmZpZywKICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih3aWRnZXROYW1lLCBzZWxlY3Rvcil7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuJGVsLmZpbHRlcihzZWxlY3RvcikubGVuZ3RoID4wKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHRoaXMpWzBdOwogICAgICAgICAgICB9IAoKICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuX2luc3RhbnRpYXRlV2lkZ2V0KHdpZGdldE5hbWUsb3B0aW9ucyk7CgkJCQogICAgICAgICAgICBpZighdGhpcy5qcVdpZGdldCl7CiAgICAgICAgICAgICAgICB3aWRnZXROYW1lID0gdGhpcy5fZ2V0V2lkZ2V0TmFtZUZyb21VaUV4dHJhKCk7CiAgICAgICAgICAgICAgICBpZiAod2lkZ2V0TmFtZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQgPSB0aGlzLl9pbnN0YW50aWF0ZVdpZGdldCh3aWRnZXROYW1lLCB0aGlzLl9jcmVhdGVTY3JpYmJsZVdpZGdldE9wdGlvbnMob3B0aW9ucykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgkJCQogICAgICAgICAgICBpZighdGhpcy5qcVdpZGdldCl7CgkJCQkJdGhpcy5fY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbihvcHRpb25zKTsKCQkJfQogICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmRlYnVnKCJ4ZmFWaWV3IiwgImNyZWF0aW5nIHVzZXIgd2lkZ2V0LiB3aWRnZXQ6IiArIHRoaXMuanFXaWRnZXQuX3dpZGdldE5hbWUKICAgICAgICAgICAgKyAiIGZvciAiICsgdGhpcy5tb2RlbC5zb21FeHByZXNzaW9uKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAqIHJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHdpZGdldCBwcmVzZW50IGluIHVpIGV4dHJhcwogICAgICAgICogQHJldHVybnMge3N0cmluZ30gd2lkZ2V0TmFtZQogICAgICAgICovCiAgICAgICAgX2dldFdpZGdldE5hbWVGcm9tVWlFeHRyYSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHdpZGdldE5hbWUgPSBudWxsLAogICAgICAgICAgICAgICAgdWlFeHRyYXNOYW1lID0gdGhpcy5nZXRPckVsc2UodGhpcywibW9kZWwudWkuZXh0cmFzLm5hbWUiLG51bGwpOwogICAgICAgICAgICBpZih1aUV4dHJhc05hbWUgJiYgdWlFeHRyYXNOYW1lLmxlbmd0aCA+PSAyICYmIHRoaXMuX2FkZE9ucy5oYXNPd25Qcm9wZXJ0eSh1aUV4dHJhc05hbWUpKXsKICAgICAgICAgICAgICAgIHdpZGdldE5hbWUgPSB0aGlzLl9hZGRPbnNbdWlFeHRyYXNOYW1lXTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gd2lkZ2V0TmFtZTsKICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbiA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgJCh0aGlzLndpZGdldCkuZGVmYXVsdFdpZGdldChvcHRpb25zKTsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtZGVmYXVsdFdpZGdldCIpOwogICAgICAgIH0sCgogICAgICAgIG1hcmtNYW5kYXRvcnkgOiBmdW5jdGlvbigpewogICAgICAgICAgICBpZih0aGlzLm1vZGVsLm1hbmRhdG9yeT09ICJlcnJvciIpCiAgICAgICAgICAgICAgICBpZih0aGlzLndpZGdldCkKICAgICAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5hdHRyKCJkYXRhLW1hbmRhdG9yeSIsICJ0cnVlIikgOwoKICAgICAgICB9LAoKICAgICAgICBfaW5pdGlhbGl6ZUZpZWxkQ2hpbGRMYXlvdXRBbmRFeHRlbnQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYgKHRoaXMuY2FwdGlvbikgewogICAgICAgICAgICAgICAgdmFyIGNWaWV3ID0gXy5leHRlbmQoe30sIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZSwgewogICAgICAgICAgICAgICAgICAgIGVsIDogdGhpcy5jYXB0aW9uLAogICAgICAgICAgICAgICAgICAgICRlbCA6ICQodGhpcy5jYXB0aW9uKQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5CYXNlVmlldy5wcm90b3R5cGUuX2luaXRpYWxpemVMYXlvdXRNb2RlbC5hcHBseShjVmlldyk7ICAvL1RPRE86IGhhbmRsZSB0aGluZ3Mgd2hlbiBtb3ZpbmcgbGF5b3V0IHRvIGZvcm1Eb20KICAgICAgICAgICAgICAgIHRoaXMuY2FwdGlvbkxheW91dE1vZGVsID0gY1ZpZXcubGF5b3V0TW9kZWw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRoaXMud2lkZ2V0ICYmIHRoaXMuY2FwdGlvbikgewogICAgICAgICAgICAgICAgdmFyIHdWaWV3ID0gXy5leHRlbmQoe30sIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZSwgewogICAgICAgICAgICAgICAgICAgIGVsIDogdGhpcy53aWRnZXQsCiAgICAgICAgICAgICAgICAgICAgJGVsIDogJCh0aGlzLndpZGdldCkKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLl9pbml0aWFsaXplTGF5b3V0TW9kZWwuYXBwbHkod1ZpZXcpOwogICAgICAgICAgICAgICAgdGhpcy53aWRnZXRMYXlvdXRNb2RlbCA9IHdWaWV3LmxheW91dE1vZGVsOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldE1lYXN1cmVtZW50T3B0aW9ucyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciB3aWRnZXRNb2RlbCA9IHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwgfHwgdGhpcy5sYXlvdXRNb2RlbDsKICAgICAgICAgICAgcmV0dXJuICh7CiAgICAgICAgICAgICAgIHJlZkVsIDogdGhpcy5qcVdpZGdldCAmJiB0aGlzLmpxV2lkZ2V0LiR1c2VyQ29udHJvbCA/IHRoaXMuanFXaWRnZXQuJHVzZXJDb250cm9sWzBdIDogbnVsbCwKICAgICAgICAgICAgICAgd2lkdGggOiAod2lkZ2V0TW9kZWwuZXh0ZW50dyAtIHdpZGdldE1vZGVsLm1hcmdpbmxlZnQgLSB3aWRnZXRNb2RlbC5tYXJnaW5yaWdodCksCiAgICAgICAgICAgICAgIGhlaWdodCA6ICh3aWRnZXRNb2RlbC5leHRlbnRoIC0gd2lkZ2V0TW9kZWwubWFyZ2ludG9wIC0gd2lkZ2V0TW9kZWwubWFyZ2luYm90dG9tKSwKICAgICAgICAgICAgICAgbWluV2lkdGggOiAod2lkZ2V0TW9kZWwuZXh0ZW50bWludz4tMSk/KHdpZGdldE1vZGVsLmV4dGVudG1pbncgLSB3aWRnZXRNb2RlbC5tYXJnaW5sZWZ0IC0gd2lkZ2V0TW9kZWwubWFyZ2lucmlnaHQpOndpZGdldE1vZGVsLmV4dGVudG1pbncsCiAgICAgICAgICAgICAgIG1pbkhlaWdodCA6KHdpZGdldE1vZGVsLmV4dGVudG1pbmg+LTEpPyh3aWRnZXRNb2RlbC5leHRlbnRtaW5oIC0gd2lkZ2V0TW9kZWwubWFyZ2ludG9wIC0gd2lkZ2V0TW9kZWwubWFyZ2luYm90dG9tKTp3aWRnZXRNb2RlbC5leHRlbnRtaW5oLAogICAgICAgICAgICAgICBtYXhXaWR0aCA6ICh3aWRnZXRNb2RlbC5leHRlbnRtYXh3ID4gLTEpPyh3aWRnZXRNb2RlbC5leHRlbnRtYXh3IC0gd2lkZ2V0TW9kZWwubWFyZ2lubGVmdCAtIHdpZGdldE1vZGVsLm1hcmdpbnJpZ2h0KTp3aWRnZXRNb2RlbC5leHRlbnRtYXh3LAogICAgICAgICAgICAgICBtYXhIZWlnaHQgOih3aWRnZXRNb2RlbC5leHRlbnRtYXhoID4gLTEpPyh3aWRnZXRNb2RlbC5leHRlbnRtYXhoIC0gd2lkZ2V0TW9kZWwubWFyZ2ludG9wIC0gd2lkZ2V0TW9kZWwubWFyZ2luYm90dG9tKTp3aWRnZXRNb2RlbC5leHRlbnRtYXhoCiAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIG1lYXN1cmVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIHJlc2l6ZWQgPSBmYWxzZTsKICAgICAgICAgICAgaWYodGhpcy5yZXNpemFibGUpewogICAgICAgICAgICAgICAgdmFyIHRleHQgPSAodGhpcy5tb2RlbCAmJiB0aGlzLm1vZGVsW3RoaXMuY29tbWl0VGFyZ2V0XSE9IG51bGwpPyB0aGlzLm1vZGVsW3RoaXMuY29tbWl0VGFyZ2V0XSA6ICIiOwogICAgICAgICAgICAgICAgcmVzaXplZCA9IHRoaXMuX3VwZGF0ZVdpZGdldE1vZGVsKHRleHQpOwogICAgICAgICAgICAgICAgaWYocmVzaXplZCAmJiB0aGlzLmNhcHRpb24gJiYgdGhpcy53aWRnZXQgJiYgdGhpcy5tb2RlbC5jYXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKHRoaXMubW9kZWwuY2FwdGlvbi5nZXRBdHRyaWJ1dGUoInBsYWNlbWVudCIpKXsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAibGVmdCI6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInJpZ2h0IjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50dyAgPSB0aGlzLmxheW91dE1vZGVsLm1hcmdpbmxlZnQgKyB0aGlzLl9nZXRDYXB0aW9uUmVzZXJ2ZWRXKCkgKyB0aGlzLndpZGdldExheW91dE1vZGVsLmV4dGVudHcgKyB0aGlzLmxheW91dE1vZGVsLm1hcmdpbnJpZ2h0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoID0gdGhpcy5sYXlvdXRNb2RlbC5tYXJnaW50b3AgKyBNYXRoLm1heCh0aGlzLl9nZXRDYXB0aW9uUmVzZXJ2ZWRIKCksIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuZXh0ZW50aCkgKyB0aGlzLmxheW91dE1vZGVsLm1hcmdpbmJvdHRvbTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJ0b3AiOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJib3R0b20iOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXlvdXRNb2RlbC5leHRlbnR3ID0gdGhpcy5sYXlvdXRNb2RlbC5tYXJnaW5sZWZ0ICsgTWF0aC5tYXgodGhpcy5fZ2V0Q2FwdGlvblJlc2VydmVkVygpLCB0aGlzLndpZGdldExheW91dE1vZGVsLmV4dGVudHcpICsgdGhpcy5sYXlvdXRNb2RlbC5tYXJnaW5yaWdodCAgICAgOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoICA9IHRoaXMubGF5b3V0TW9kZWwubWFyZ2ludG9wICsgdGhpcy5fZ2V0Q2FwdGlvblJlc2VydmVkSCgpICsgdGhpcy53aWRnZXRMYXlvdXRNb2RlbC5leHRlbnRoICsgdGhpcy5sYXlvdXRNb2RlbC5tYXJnaW5ib3R0b207CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc2l6ZWQ7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogVG8gdXBkYXRlIGhlaWdodCBhbmQgd2lkdGggb2Ygd2lkZ2V0IG1vZGVsCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQgOiB0ZXh0IHRvIGJlIHVzZWQgdG8gY29tcHV0ZSBuZXcgaGVpZ2h0IGFuZCB3aWR0aAogICAgICAgICAqIHJldHVybiB0cnVlIGlmIGhlaWdodCBvciB3aWR0aCB1cGRhdGVkIGVsc2UgZmFsc2UKICAgICAgICAgKi8KICAgICAgICBfdXBkYXRlV2lkZ2V0TW9kZWwgOiBmdW5jdGlvbiAodGV4dCkgewogICAgICAgICAgICB2YXIgc3BhY2VBYm92ZSA9IDAsCiAgICAgICAgICAgICAgICBzcGFjZUJlbG93ID0gMCwKICAgICAgICAgICAgICAgIHBhcmEgPSB0aGlzLmdldE9yRWxzZSh0aGlzLCAibW9kZWwucGFyYSIsIG51bGwpLAogICAgICAgICAgICAgICAgcmVzaXplZCA9IGZhbHNlLAogICAgICAgICAgICAgICAgbWVhc3VyZU9wdGlvbnMgPSB0aGlzLl9nZXRNZWFzdXJlbWVudE9wdGlvbnMoKSwKICAgICAgICAgICAgICAgIG1lYXN1cmVkRXh0ZW50ID0geGZhbGliLnZpZXcudXRpbC5UZXh0TWV0cmljcy5tZWFzdXJlRXh0ZW50KHRleHQsIF8uY2xvbmUobWVhc3VyZU9wdGlvbnMpKSwKICAgICAgICAgICAgICAgIHdpZGdldE1vZGVsID0gdGhpcy53aWRnZXRMYXlvdXRNb2RlbCB8fCB0aGlzLmxheW91dE1vZGVsOwoKICAgICAgICAgICAgaWYocGFyYSkgewogICAgICAgICAgICAgICAgc3BhY2VBYm92ZSA9IHBhcmEuc3BhY2VBYm92ZTsKICAgICAgICAgICAgICAgIHNwYWNlQmVsb3cgPSBwYXJhLnNwYWNlQmVsb3c7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKG1lYXN1cmVPcHRpb25zLndpZHRoICE9IG1lYXN1cmVkRXh0ZW50LndpZHRoIHx8IG1lYXN1cmVPcHRpb25zLmhlaWdodCAhPSBtZWFzdXJlZEV4dGVudC5oZWlnaHQpIHsKICAgICAgICAgICAgICAgIHJlc2l6ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgaWYobWVhc3VyZU9wdGlvbnMud2lkdGggIT0gbWVhc3VyZWRFeHRlbnQud2lkdGgpIHsKICAgICAgICAgICAgICAgICAgICB3aWRnZXRNb2RlbC5leHRlbnR3ID0gd2lkZ2V0TW9kZWwubWFyZ2lubGVmdCArIG1lYXN1cmVkRXh0ZW50LndpZHRoICsgd2lkZ2V0TW9kZWwubWFyZ2lucmlnaHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihtZWFzdXJlT3B0aW9ucy5oZWlnaHQgIT0gbWVhc3VyZWRFeHRlbnQuaGVpZ2h0KSB7CiAgICAgICAgICAgICAgICAgICAgd2lkZ2V0TW9kZWwuZXh0ZW50aCA9IHdpZGdldE1vZGVsLm1hcmdpbnRvcCArIG1lYXN1cmVkRXh0ZW50LmhlaWdodCArIHdpZGdldE1vZGVsLm1hcmdpbmJvdHRvbSArIHRoaXMuX2NvbnZlcnRUb1B4KHNwYWNlQWJvdmUpCiAgICAgICAgICAgICAgICAgICAgICAgICsgdGhpcy5fY29udmVydFRvUHgoc3BhY2VCZWxvdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc2l6ZWQKICAgICAgICB9LAoKICAgICAgICBfZ2V0Q2FwdGlvblJlc2VydmVkVzogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmKHRoaXMuY2FwdGlvbiAmJiB0aGlzLm1vZGVsLmNhcHRpb24pewogICAgICAgICAgICAgICAgc3dpdGNoKHRoaXMubW9kZWwuY2FwdGlvbi5nZXRBdHRyaWJ1dGUoInBsYWNlbWVudCIpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAibGVmdCIgOgogICAgICAgICAgICAgICAgICAgIGNhc2UgInJpZ2h0IiA6CiAgICAgICAgICAgICAgICAgICAgICAgIC8vaW4gY2FzZSBsZWZ0IGFuZCByaWdodCwgInJlc2VydmUiIGRpY3RhdGVzIHRoZSB3aWR0aCBvZiB0aGUgY2FwdGlvbgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzZXJ2ZSA9IHRoaXMubW9kZWwuY2FwdGlvbi5nZXRBdHRyaWJ1dGUoInJlc2VydmUiKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChyZXNlcnZlICE9ICItMSIgPyB0aGlzLl9jb252ZXJ0VG9QeChyZXNlcnZlKSA6IDApOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJ0b3AiIDoKICAgICAgICAgICAgICAgICAgICBjYXNlICJib3R0b20iIDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2FwdGlvbkxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0sCgogICAgICAgIF9nZXRDYXB0aW9uUmVzZXJ2ZWRIOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYodGhpcy5jYXB0aW9uICYmIHRoaXMubW9kZWwuY2FwdGlvbil7CiAgICAgICAgICAgICAgICBzd2l0Y2godGhpcy5tb2RlbC5jYXB0aW9uLmdldEF0dHJpYnV0ZSgicGxhY2VtZW50IikpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJsZWZ0IiA6CiAgICAgICAgICAgICAgICAgICAgY2FzZSAicmlnaHQiIDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2FwdGlvbkxheW91dE1vZGVsLmV4dGVudGg7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgInRvcCIgOgogICAgICAgICAgICAgICAgICAgIGNhc2UgImJvdHRvbSIgOgogICAgICAgICAgICAgICAgICAgICAgICAvL2luIGNhc2UgdG9wIGFuZCBib3R0b20sICJyZXNlcnZlIiBkaWN0YXRlcyB0aGUgaGVpZ2h0IG9mIHRoZSBjYXB0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNlcnZlID0gdGhpcy5tb2RlbC5jYXB0aW9uLmdldEF0dHJpYnV0ZSgicmVzZXJ2ZSIpOwogICAgICAgICAgICAgICAgICAgICAgICAvL0NRLTEwMjM0MSA6IExheW91dCBvZiBvbGRlciBmb3JtcyBnb3QgZGlzdHVyYmVzIHdoaWNoIGhhZCBubyByZXNlcnZlIHZhbHVlLiBTbyBpZiBubyByZXNlcnZlIGlzIGZvdW5kIHRoZSBvbGRlciB2YWx1ZSBpLmUgdGhpcy5jYXB0aW9uTGF5b3V0TW9kZWwuZXh0ZW50aCBpcyByZXR1cm5lZAogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHRoaXMuX2lzUmVzZXJ2ZVByZXNlbnQocmVzZXJ2ZSkgPyB0aGlzLl9jb252ZXJ0VG9QeChyZXNlcnZlKSA6IHRoaXMuY2FwdGlvbkxheW91dE1vZGVsLmV4dGVudGgpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9LAoKICAgICAgICBfaXNSZXNlcnZlUHJlc2VudDogZnVuY3Rpb24ocmVzZXJ2ZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuICEocmVzZXJ2ZSA9PSAiLTEiIHx8IHBhcnNlRmxvYXQocmVzZXJ2ZS5yZXBsYWNlKC9bXi1cZFwuXS9nLCAnJykpID09IDApOwogICAgICAgICAgICB9IGNhdGNoKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci53YXJuKCJ4ZmEiLCJpc3N1ZSB3aXRoIHBhcnNlRmxvYXQgb2YgcmVzZXJ2ZSAsIHJlc2VydmUgdmFsdWUgOiIgKyByZXNlcnZlKTsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jYWxjdWxhdGVEaXNwbGF5IDogZnVuY3Rpb24oY2FwRXh0ZW50LHdFeHRlbnQpIHsKICAgICAgICAgICAgIHdFeHRlbnRbIndpZHRoIl0gPSB0aGlzLndpZGdldExheW91dE1vZGVsLmV4dGVudHcgKyB0aGlzLndpZGdldExheW91dE1vZGVsLmJvcmRlcmxlZnQvMiArIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuYm9yZGVycmlnaHQvMiA7CiAgICAgICAgICAgICB3RXh0ZW50WyJoZWlnaHQiXSA9IHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuZXh0ZW50aCArIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuYm9yZGVydG9wLzIgKyB0aGlzLndpZGdldExheW91dE1vZGVsLmJvcmRlcmJvdHRvbS8yIDsKICAgICAgICAgICAgIHN3aXRjaCh0aGlzLm1vZGVsLmNhcHRpb24ucGxhY2VtZW50KSB7CiAgICAgICAgICAgICAgIGNhc2UgImxlZnQiIDoKICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJsZWZ0Il0gPSB0aGlzLl9wYWRMZWZ0KCk7CiAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsidG9wIl0gPSB0aGlzLl9wYWRUb3AoKTsKICAgICAgICAgICAgICAgICAgd0V4dGVudFsibGVmdCJdID0gdGhpcy5fcGFkTGVmdCgpICsgdGhpcy5fZ2V0Q2FwdGlvblJlc2VydmVkVygpOwogICAgICAgICAgICAgICAgICB3RXh0ZW50WyJ0b3AiXSA9IHRoaXMuX3BhZFRvcCgpOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgY2FzZSAicmlnaHQiIDoKICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJyaWdodCJdID0gdGhpcy5fcGFkUmlnaHQoKTsKICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJ0b3AiXSA9IHRoaXMuX3BhZFRvcCgpOwogICAgICAgICAgICAgICAgICB3RXh0ZW50WyJyaWdodCJdID0gdGhpcy5fcGFkUmlnaHQoKSArIE1hdGgubWF4KHRoaXMuX2dldENhcHRpb25SZXNlcnZlZFcoKSwgY2FwRXh0ZW50WyJ3aWR0aCJdKTsKICAgICAgICAgICAgICAgICAgd0V4dGVudFsidG9wIl0gPSB0aGlzLl9wYWRUb3AoKTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgIGNhc2UgInRvcCIgOgogICAgICAgICAgICAgICAgICBjYXBFeHRlbnRbImxlZnQiXSA9IHRoaXMuX3BhZExlZnQoKTsKICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJ0b3AiXSA9IHRoaXMuX3BhZFRvcCgpOwogICAgICAgICAgICAgICAgICB3RXh0ZW50WyJsZWZ0Il0gPSB0aGlzLl9wYWRMZWZ0KCk7CiAgICAgICAgICAgICAgICAgIHdFeHRlbnRbInRvcCJdID0gdGhpcy5fcGFkVG9wKCkgKyB0aGlzLl9nZXRDYXB0aW9uUmVzZXJ2ZWRIKCk7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICBjYXNlICJib3R0b20iIDoKICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJsZWZ0Il0gPSB0aGlzLl9wYWRMZWZ0KCk7CiAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsiYm90dG9tIl0gPSB0aGlzLl9wYWRCb3R0b20oKTsKICAgICAgICAgICAgICAgICAgd0V4dGVudFsibGVmdCJdID0gdGhpcy5fcGFkTGVmdCgpOwogICAgICAgICAgICAgICAgICB3RXh0ZW50WyJib3R0b20iXSA9IHRoaXMuX3BhZEJvdHRvbSgpICArIHRoaXMuX2dldENhcHRpb25SZXNlcnZlZEgoKTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgfQogICAgICAgfSwKCiAgICAgICAgdXBkYXRlRGlzcGxheSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS51cGRhdGVEaXNwbGF5LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMuY2FwdGlvbiAmJiB0aGlzLndpZGdldCl7CiAgICAgICAgICAgICAgICB2YXIgcGFyZW50UGFkTGVmdCA9IHRoaXMuX3BhZExlZnQoKTsKICAgICAgICAgICAgICAgIHZhciBwYXJlbnRQYWRUb3AgPSB0aGlzLl9wYWRUb3AoKTsKICAgICAgICAgICAgICAgIHZhciBjYXBFeHRlbnQgPSB7fTsKICAgICAgICAgICAgICAgIHZhciB3RXh0ZW50ID0ge307CiAgICAgICAgICAgICAgICBjYXBFeHRlbnRbIndpZHRoIl0gPSB0aGlzLmNhcHRpb25MYXlvdXRNb2RlbC5leHRlbnR3ICsgdGhpcy5jYXB0aW9uTGF5b3V0TW9kZWwuYm9yZGVybGVmdC8yICsgdGhpcy5jYXB0aW9uTGF5b3V0TW9kZWwuYm9yZGVycmlnaHQvMiA7CiAgICAgICAgICAgICAgICBjYXBFeHRlbnRbImhlaWdodCJdID0gdGhpcy5jYXB0aW9uTGF5b3V0TW9kZWwuZXh0ZW50aCArIHRoaXMuY2FwdGlvbkxheW91dE1vZGVsLmJvcmRlcnRvcC8yICsgdGhpcy5jYXB0aW9uTGF5b3V0TW9kZWwuYm9yZGVyYm90dG9tLzIgOwogICAgICAgICAgICAgICAgdGhpcy5fY2FsY3VsYXRlRGlzcGxheShjYXBFeHRlbnQsd0V4dGVudCk7CiAgICAgICAgICAgICAgICB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigid2lkdGgiLHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuZXh0ZW50dyAtIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwubWFyZ2lubGVmdCAtIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwubWFyZ2lucmlnaHQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9wdGlvbigiaGVpZ2h0Iix0aGlzLndpZGdldExheW91dE1vZGVsLmV4dGVudGggLSB0aGlzLndpZGdldExheW91dE1vZGVsLm1hcmdpbmJvdHRvbSAtIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwubWFyZ2ludG9wKQogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuY2FwdGlvbiwgY2FwRXh0ZW50KTsKICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLndpZGdldCwgd0V4dGVudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigid2lkdGgiLHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50dyAtIHRoaXMubGF5b3V0TW9kZWwubWFyZ2lubGVmdCAtIHRoaXMubGF5b3V0TW9kZWwubWFyZ2lucmlnaHQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9wdGlvbigiaGVpZ2h0Iix0aGlzLmxheW91dE1vZGVsLmV4dGVudGggLSB0aGlzLmxheW91dE1vZGVsLm1hcmdpbmJvdHRvbSAtIHRoaXMubGF5b3V0TW9kZWwubWFyZ2ludG9wKQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgdXBkYXRlVGFiSW5kZXggOiBmdW5jdGlvbihuZXdUYWJJbmRleCl7CiAgICAgICAgICAgIHRoaXMuanFXaWRnZXQub3B0aW9uKCJ0YWJJbmRleCIsIG5ld1RhYkluZGV4KTsKICAgICAgICB9LAoKICAgICAgICAvLyBDUS0xMDI0NzIgOiBPdmVycmlkaW5nIEJhc2VWaWV3IF9oYW5kbGVCb3JkZXJDaGFuZ2UsIGFzIGluIGNhc2Ugb2YgZmllbGQgd2l0aCBubyBjYXB0aW9uLCBmaWVsZCBib3JkZXIgY29sb3IgZ2V0cyBhc3NpZ25lZCB0byB3aWRnZXQgYm9yZGVyIGFzIG5vIGNhcHRpb24gYW5kIGZpZWxkIGRpdnMgYXJlIHByZXNlbnQKICAgICAgICBfaGFuZGxlQm9yZGVyQ2hhbmdlIDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgaWYgKHRoaXMuY2FwdGlvbiB8fCB0aGlzLm1vZGVsLmJvcmRlci5lZGdlLmdldEF0dHJpYnV0ZSgidGhpY2tuZXNzIiwgZmFsc2UpKSB7CiAgICAgICAgICAgICAgICB2YXIgY3NzU3R5bGVPYmogPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5nZXRTdHlsZUZvckJvcmRlcih0aGlzLm1vZGVsLmJvcmRlcik7CiAgICAgICAgICAgICAgICBpZihjc3NTdHlsZU9iaikgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLmVsLCBjc3NTdHlsZU9iaik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sICQsIHhmYWxpYik7CgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LkNoZWNrQnV0dG9uRmllbGRWaWV3ID0geGZhbGliLnZpZXcuRmllbGRWaWV3LmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbiA6ICBmdW5jdGlvbihvcHRpb25zKXsKICAgICAgICAgICAgaWYodGhpcy5tb2RlbCl7CiAgICAgICAgICAgICAgICBvcHRpb25zLnNpemUgPSAgdGhpcy5tb2RlbC51aS5vbmVPZkNoaWxkLnNpemU7CiAgICAgICAgICAgICAgICBvcHRpb25zLnN0YXRlID0gdGhpcy5tb2RlbC5zZWxlY3RlZEluZGV4OwogICAgICAgICAgICAgICAgb3B0aW9ucy5zdGF0ZXMgPSB0aGlzLm1vZGVsLnVpLm9uZU9mQ2hpbGQuYWxsb3dOZXV0cmFsID09ICIxIiA/IDM6MjsgIC8vICNidWc9MzY1MDkyMCwgdHlwZW9mIGFsbG93TmV1dHJhbCBpcyBzdHJpbmcKICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLlhmYUNoZWNrQm94KG9wdGlvbnMpOwogICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtWGZhQ2hlY2tCb3giKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbi5hcHBseSh0aGlzLCBbb3B0aW9uc10pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAvL05vdGU6IFRoZSBzY3JlZW5yZWFkZXIgdGV4dCBmb3IgZXhjbHVzaW9uIGdyb3VwIHNob3VsZCBub3QgYmVoYXZlIGRpZmZlcmVudGx5LCBhbmQgc2hvdWxkIGJlIGFsaWduZWQgdG8gUERGLgogICAgICAgIC8vUmVmZXJlbmNlOiBDUS04MTg3NSAoQUVNIEZvcm1zIHNob3cgcmFkaW8gYnV0dG9uIG5hbWUgaW5jbHVkZWQgd2l0aCB0b29sdGlwKQogICAgICAgIF9nZXRTY3JlZW5SZWFkZXJUZXh0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHNjcmVlblJlYWRlclRleHQgPSAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fZ2V0U2NyZWVuUmVhZGVyVGV4dC5hcHBseSh0aGlzKSwKICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHRQYXJlbnQ7CiAgICAgICAgICAgIGlmKHRoaXMubW9kZWwucGFyZW50ICYmIHRoaXMubW9kZWwucGFyZW50Ll9pc0V4Y2x1c2lvbkdyb3VwKCkpIHsKICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHRQYXJlbnQgPSB0aGlzLnBhcmVudFZpZXcuX2dldFNjcmVlblJlYWRlclRleHQoKTsKICAgICAgICAgICAgICAgIGlmKHNjcmVlblJlYWRlclRleHRQYXJlbnQpIHsKICAgICAgICAgICAgICAgICAgICBzY3JlZW5SZWFkZXJUZXh0UGFyZW50ID0gc2NyZWVuUmVhZGVyVGV4dFBhcmVudCArICIgIiA7CiAgICAgICAgICAgICAgICAgICAgaWYoc2NyZWVuUmVhZGVyVGV4dCkgewogICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW5SZWFkZXJUZXh0PSBzY3JlZW5SZWFkZXJUZXh0UGFyZW50ICArICAgc2NyZWVuUmVhZGVyVGV4dDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW5SZWFkZXJUZXh0ID0gc2NyZWVuUmVhZGVyVGV4dFBhcmVudDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAgc2NyZWVuUmVhZGVyVGV4dCA7CgogICAgICAgIH0sCiAgICAgICAgKi8KICAgICAgICBfaGFuZGxlTW91c2VEb3duOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICBpZih4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1cyA9PSB0aGlzKSB7CiAgICAgICAgICAgICAgICB0aGlzLmNsaWNrZWRPbkNhcHRpb24gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlQm9yZGVyRm9yV2lkZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICB9LAoKICAgICAgICBoYW5kbGVDaGFuZ2VFdmVudCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmKHRoaXMubW9kZWwucGFyZW50LmNsYXNzTmFtZSA9PSAiZXhjbEdyb3VwIikgewogICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5wYXJlbnQuZXhlY0V2ZW50KCJjaGFuZ2UiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLm1vZGVsLmV4ZWNFdmVudCgiY2hhbmdlIik7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlQ2xpY2tFdmVudCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpZih0aGlzLm1vZGVsLnBhcmVudC5jbGFzc05hbWUgPT0gImV4Y2xHcm91cCIpIHsKICAgICAgICAgICAgICAgIHRoaXMubW9kZWwucGFyZW50LmV4ZWNFdmVudCgiY2xpY2siKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLm1vZGVsLmV4ZWNFdmVudCgiY2xpY2siKTsKICAgICAgICB9LAoKICAgICAgICBoYW5kbGVEb21DaGFuZ2VkIDpmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgIHN3aXRjaChldmVudC5fcHJvcGVydHkpIHsKICAgICAgICAgICAgICAgIGNhc2UgImFsbG93TmV1dHJhbCI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQWxsb3dOZXV0cmFsKGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5oYW5kbGVEb21DaGFuZ2VkLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAgX2NhbGN1bGF0ZURpc3BsYXkgOiBmdW5jdGlvbihjYXBFeHRlbnQsd0V4dGVudCkgewogICAgICAgICAgICAgICB2YXIgc2l6ZSA9IHRoaXMuX2dldFdpZGdldFJlc2VydmVkKCk7ICAvLy0tIHdlIGFyZSBjaGFuZ2luZyB0aGUgY2FsY3VsYXRpb25zIGZyb20gY2FwdGlvbi1jZW50cmljIHRvIGEgd2lkZ2V0IGNlbnRyaWMKICAgICAgICAgICAgICAgdGhpcy53aWRnZXRMYXlvdXRNb2RlbC5leHRlbnR3ID0gdGhpcy53aWRnZXRMYXlvdXRNb2RlbC5leHRlbnRoID0gc2l6ZTsKICAgICAgICAgICAgICAgdmFyIHBhcmVudEV4dGVudCA9IHt9OwogICAgICAgICAgICAgICB2YXIgcGFyYUZpZWxkID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCJwYXJhIikKICAgICAgICAgICAgICAgaWYocGFyYUZpZWxkKQogICAgICAgICAgICAgICAgIHZhciB2QWxpZ25XaWRnZXQgPSBwYXJhRmllbGQuZ2V0QXR0cmlidXRlKCJ2QWxpZ24iKTsKICAgICAgICAgICAgICAgcGFyZW50RXh0ZW50WyJ3aWR0aCJdID0gdGhpcy5sYXlvdXRNb2RlbC5leHRlbnR3ICsgdGhpcy5sYXlvdXRNb2RlbC5ib3JkZXJsZWZ0LzIgKyB0aGlzLmxheW91dE1vZGVsLmJvcmRlcnJpZ2h0LzIgOwogICAgICAgICAgICAgICBwYXJlbnRFeHRlbnRbImhlaWdodCJdID0gdGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoICsgdGhpcy5sYXlvdXRNb2RlbC5ib3JkZXJ0b3AvMiArIHRoaXMubGF5b3V0TW9kZWwuYm9yZGVyYm90dG9tLzIgOwogICAgICAgICAgICAgICB3RXh0ZW50WyJ3aWR0aCJdID0gdGhpcy53aWRnZXRMYXlvdXRNb2RlbC5leHRlbnR3ICsgdGhpcy53aWRnZXRMYXlvdXRNb2RlbC5ib3JkZXJsZWZ0LzIgKyB0aGlzLndpZGdldExheW91dE1vZGVsLmJvcmRlcnJpZ2h0LzIgOwogICAgICAgICAgICAgICB3RXh0ZW50WyJoZWlnaHQiXSA9IHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuZXh0ZW50aCArIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuYm9yZGVydG9wLzIgKyB0aGlzLndpZGdldExheW91dE1vZGVsLmJvcmRlcmJvdHRvbS8yIDsKICAgICAgICAgICAgICAgdmFyIHRvcEJvdHRvbVBhZGRpbmcgPSAodGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoLSh0aGlzLndpZGdldExheW91dE1vZGVsLmV4dGVudGggKyB0aGlzLmNhcHRpb25MYXlvdXRNb2RlbC5leHRlbnRoKSkvMjsKCiAgICAgICAgICAgICAgIHN3aXRjaCh2QWxpZ25XaWRnZXQpIHsgLy8gc2V0dGluZyB0aGUgdkFsaWduIG9mIHRoZSB3aWRnZXQgZXF1YWwgdG8gaXRzIHBhcmVudC4gKGkuZSBmaWVsZCkKICAgICAgICAgICAgICAgICBjYXNlICJib3R0b20iOgogICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJib3R0b20iXT0gdGhpcy5fcGFkQm90dG9tKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICBjYXNlICJtaWRkbGUiOgogICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJ0b3AiXSA9ICh0aGlzLmxheW91dE1vZGVsLmV4dGVudGgtc2l6ZSkvMjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIGNhc2UgInRvcCI6CiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHdFeHRlbnRbInRvcCJdPSB0aGlzLl9wYWRUb3AoKTsKICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgc3dpdGNoKHRoaXMubW9kZWwuY2FwdGlvbi5wbGFjZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJyaWdodCIgOgogICAgICAgICAgICAgICAgICAgICAgICBjYXBFeHRlbnRbImxlZnQiXSA9IHRoaXMuX3BhZExlZnQoKSArIHNpemU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsidG9wIl0gPSB0aGlzLl9wYWRUb3AoKTsKICAgICAgICAgICAgICAgICAgICAgICAgd0V4dGVudFsibGVmdCJdID0gdGhpcy5fcGFkTGVmdCgpCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgImxlZnQiIDoKICAgICAgICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJyaWdodCJdID0gdGhpcy5fcGFkUmlnaHQoKSArIHNpemU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsidG9wIl0gPSB0aGlzLl9wYWRUb3AoKTsKICAgICAgICAgICAgICAgICAgICAgICAgd0V4dGVudFsicmlnaHQiXSA9IHRoaXMuX3BhZFJpZ2h0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgImJvdHRvbSIgOgogICAgICAgICAgICAgICAgICAgICAgICBjYXBFeHRlbnRbImxlZnQiXSA9IHRoaXMuX3BhZExlZnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJ0b3AiXSA9IHRoaXMuX3BhZFRvcCgpKyBzaXplICsgdG9wQm90dG9tUGFkZGluZzsKICAgICAgICAgICAgICAgICAgICAgICAgd0V4dGVudFsibGVmdCJdID0gdGhpcy5fcGFkTGVmdCgpOwogICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJib3R0b20iXT0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJ0b3AiXSA9IHRoaXMuX3BhZFRvcCgpICsgdG9wQm90dG9tUGFkZGluZyA7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgInRvcCIgOgogICAgICAgICAgICAgICAgICAgICAgICBjYXBFeHRlbnRbImxlZnQiXSA9IHRoaXMuX3BhZExlZnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJib3R0b20iXSA9dGhpcy5fcGFkQm90dG9tKCkrIHNpemUgKyB0b3BCb3R0b21QYWRkaW5nOwogICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJ0b3AiXT0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJsZWZ0Il0gPSB0aGlzLl9wYWRMZWZ0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHdFeHRlbnRbImJvdHRvbSJdID0gdGhpcy5fcGFkQm90dG9tKCkrIHRvcEJvdHRvbVBhZGRpbmc7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgIHZhciBsYW5nID0gdGhpcy5fbGFuZ0Zyb21Mb2NhbGUodGhpcy5tb2RlbC5fZ2V0TG9jYWxlKCkpOwogICAgICAgICAgICAgICB2YXIgZGlyZWN0aW9uID0gImx0ciIKICAgICAgICAgICAgICAgaWYobGFuZyAmJiB0aGlzLl9ydGxMYW5nW2xhbmddKXsKICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAicnRsIjsKICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICBpZihjYXBFeHRlbnRbIndpZHRoIl08KHBhcmVudEV4dGVudFsid2lkdGgiXSAtIHdFeHRlbnRbIndpZHRoIl0pKSB7CiAgICAgICAgICAgICAgICAgICBzd2l0Y2godGhpcy5tb2RlbC5jYXB0aW9uLnBsYWNlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInJpZ2h0IiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsibGVmdCJdID0gIHBhcmVudEV4dGVudFsid2lkdGgiXS1jYXBFeHRlbnRbIndpZHRoIl0gOwogICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJsZWZ0IiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsicmlnaHQiXSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJsZWZ0Il0gPSB0aGlzLl9wYWRMZWZ0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgIHdFeHRlbnRbInJpZ2h0Il0gPSBkaXJlY3Rpb24gPT09ICJydGwiID8gMCA6IHVuZGVmaW5lZAogICAgICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJsZWZ0Il0gPSBkaXJlY3Rpb24gPT09ICJydGwiID8gdW5kZWZpbmVkIDogdGhpcy5fcGFkTGVmdCgpK2NhcEV4dGVudFsid2lkdGgiXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgaWYoY2FwRXh0ZW50WyJoZWlnaHQiXTwocGFyZW50RXh0ZW50WyJoZWlnaHQiXSAtIHdFeHRlbnRbImhlaWdodCJdKSkgewogICAgICAgICAgICAgICAgICAgc3dpdGNoKHRoaXMubW9kZWwuY2FwdGlvbi5wbGFjZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJib3R0b20iIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJ0b3AiXSA9IHBhcmVudEV4dGVudFsiaGVpZ2h0Il0tY2FwRXh0ZW50WyJoZWlnaHQiXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAidG9wIiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsiYm90dG9tIl0gPSBwYXJlbnRFeHRlbnRbImhlaWdodCJdLWNhcEV4dGVudFsiaGVpZ2h0Il07CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICB9CgogICAgICAgICB9LAoKCiAgICAgICAgX2dldFdpZGdldFJlc2VydmVkOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYodGhpcy53aWRnZXQgKXsKICAgICAgICAgICAgICAgICB2YXIgc2l6ZSA9IHRoaXMubW9kZWwudWkub25lT2ZDaGlsZC5nZXRBdHRyaWJ1dGUoInNpemUiKTsKICAgICAgICAgICAgICAgICByZXR1cm4gKHNpemUgIT0gIi0xIiA/IHRoaXMuX2NvbnZlcnRUb1B4KHNpemUpIDogMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlQWxsb3dOZXV0cmFsIDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgaWYoZXZlbnQucHJldlRleHQpIHsKICAgICAgICAgICAgICAgIGlmKGV2ZW50LnByZXZUZXh0ID09ICIwIiAmJiB0aGlzLm1vZGVsLmdldEl0ZW1TdGF0ZSgyKSkgeyAgLy8gaWYgYnV0dG9uIHdhcyBpbiBuZXV0cmFsLAogICAgICAgICAgICAgICAgICAgIHRoaXMubW9kZWwuc2V0SXRlbVN0YXRlKDEsIHRydWUpOyAgIC8vIHNldCBpdCB0byBvZmYsIHdoaWxlIGRpc2FibGluZyBhbGxvd05ldXRyYWwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQub3B0aW9uKCJhbGxvd05ldXRyYWwiLCBldmVudC5wcmV2VGV4dCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlUGx1Z2luT3B0aW9ucyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICB2YXIgdk9wdGlvbnMgPSB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9jcmVhdGVQbHVnaW5PcHRpb25zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMubW9kZWwpIHsKICAgICAgICAgICAgICAgIC8vVE9ETzogdXNlZCBfZ2V0RGlzcGxheUl0ZW1zLiBJbnRlcm5hbCBBUEkKICAgICAgICAgICAgICAgIHZhciB2SXRlbXMgPSBfLm1hcCgKICAgICAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLl9nZXREaXNwbGF5SXRlbXMoKSA/IHRoaXMubW9kZWwuX2dldERpc3BsYXlJdGVtcygpLm1vQ2hpbGROb2RlczogW10sCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oaXRlbSwgaW5kZXgpewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlbS52YWx1ZTsKICAgICAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIHZPcHRpb25zLnZhbHVlcyA9IHZJdGVtczsKCiAgICAgICAgICAgICAgICBpZih0aGlzLm1vZGVsLnBhcmVudCAmJiB0aGlzLm1vZGVsLnBhcmVudC5faXNFeGNsdXNpb25Hcm91cCgpKSB7CiAgICAgICAgICAgICAgICAgICAgLy9wdXNoIGF0bGVhc3Qgb25lIG9mIHRoZXNlCiAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMubmFtZSA9IHRoaXMubW9kZWwucGFyZW50Lm5hbWUrIiIrdGhpcy5wYXJlbnRWaWV3Ll9pZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdk9wdGlvbnM7CiAgICAgICAgfQogICAgfSk7CgogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHhmYWxpYi52aWV3LkNoZWNrQnV0dG9uRmllbGRWaWV3LnByb3RvdHlwZSwgInJlc2l6YWJsZSIsIHsKICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgc2V0IDogZnVuY3Rpb24oc1ZhbHVlKXsKICAgICAgICAgICAgLy9EbyBOb3RoaW5nCiAgICAgICAgfQogICAgfSk7Cgp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LlRleHRGaWVsZFZpZXcgPSB4ZmFsaWIudmlldy5GaWVsZFZpZXcuZXh0ZW5kKHsKICAgICAgICBfY3JlYXRlUGx1Z2luT3B0aW9ucyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgdk9wdGlvbnMgPSB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9jcmVhdGVQbHVnaW5PcHRpb25zLmFwcGx5KHRoaXMsCiAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzKTsKICAgICAgICAgICAgdk9wdGlvbnMubXVsdGlMaW5lID0gZmFsc2U7CiAgICAgICAgICAgIGlmICh0aGlzLm1vZGVsKSB7CiAgICAgICAgICAgICAgICB2YXIgdWkgPSB0aGlzLm1vZGVsLmdldEVsZW1lbnQoJ3VpJywgMCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB2YXIgdWlDaGlsZDsKCiAgICAgICAgICAgICAgICBpZih1aSkgewogICAgICAgICAgICAgICAgICAgIHVpQ2hpbGQgPSB1aS5vbmVPZkNoaWxkOwogICAgICAgICAgICAgICAgICAgIGlmKHVpQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMubXVsdGlMaW5lID0gdWlDaGlsZC5nZXRBdHRyaWJ1dGUoIm11bHRpTGluZSIpID09IDAgPyBmYWxzZSA6IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMubW9kZWwuZ2V0RWxlbWVudCgidmFsdWUiLCAwLCB0cnVlKTsKICAgICAgICAgICAgICAgIGlmKHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlQ2hpbGQgPSB2YWx1ZS5vbmVPZkNoaWxkOwogICAgICAgICAgICAgICAgICAgIGlmKHZhbHVlQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1heENoYXJzID0gdmFsdWVDaGlsZC5nZXRBdHRyaWJ1dGUoIm1heENoYXJzIik7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vbm90ZSA6IG1heENoYXJzLyBudW1iZXJPZkNlbGxzIGFzIHplcm8gc2hvdWxkIGJlIHRyZWF0ZWQgYXMgdW5kZWZpbmVkL25vIHJlc3RyaWN0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgIHZPcHRpb25zLm1heENoYXJzID0gdGhpcy5nZXRPckVsc2UobWF4Q2hhcnMsIHVuZGVmaW5lZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmKHZhbHVlQ2hpbGQuY2xhc3NOYW1lID09PSAiZXhEYXRhIiAmJiB2YWx1ZUNoaWxkLmpzb25Nb2RlbC5fdmFsdWUgIT09IG51bGwgJiYgdmFsdWVDaGlsZC5qc29uTW9kZWwuX3ZhbHVlLmluZGV4T2YoIjxib2R5IHhtbG5zPSIpID09PSAtMSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlQ2hpbGQuX3RyYW5zZm9ybVRvWEZBQ29tcGxpYW50TW9kZWwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMudmFsdWUgPSB2YWx1ZUNoaWxkLmpzb25Nb2RlbC5fdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmKCF2T3B0aW9ucy5tYXhDaGFycyl7CiAgICAgICAgICAgICAgICAgICAgLy9ub3RlIDogbnVtYmVyT2ZDZWxscyBhcyB6ZXJvIHNob3VsZCBiZSB0cmVhdGVkIGFzIHVuZGVmaW5lZC9ubyByZXN0cmljdGlvbgogICAgICAgICAgICAgICAgICAgIGlmKHVpQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbWIgPSB1aUNoaWxkLmdldEVsZW1lbnQoImNvbWIiLCAwLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoY29tYikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMubWF4Q2hhcnMgPSBjb21iLmdldEF0dHJpYnV0ZSgnbnVtYmVyT2ZDZWxscycpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCF2T3B0aW9ucy5mb250U2l6ZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBmb250ID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCJmb250IiwgMCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGZvbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMuZm9udFNpemUgPSB0aGlzLl9jb252ZXJ0VG9QeChmb250LnNpemUpOwogICAgICAgICAgICAgICAgICAgICAgICB2T3B0aW9ucy5mb250RmFtaWx5ID0gZm9udC50eXBlZmFjZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZPcHRpb25zOwogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luIDogZnVuY3Rpb24ob3B0aW9ucykgewogICAgICAgICAgICBpZih0aGlzLl9yaWNoVGV4dFN1cHBvcnQoKSl7CiAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5yaWNoVGV4dEZpZWxkKG9wdGlvbnMpOwogICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtcmljaFRleHRGaWVsZCIpOwogICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLnRleHRGaWVsZChvcHRpb25zKTsKICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQgPSB0aGlzLiRkYXRhKHRoaXMud2lkZ2V0LCAieGZhV2lkZ2V0LXRleHRGaWVsZCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX3JpY2hUZXh0U3VwcG9ydDogZnVuY3Rpb24oKXsKICAgICAgICAgICByZXR1cm4odGhpcy5nZXRPckVsc2UodGhpcy5tb2RlbCwgInZhbHVlLm9uZU9mQ2hpbGQuY2xhc3NOYW1lIiwgbnVsbCkgPT09ICJleERhdGEiPyB0cnVlOmZhbHNlKTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVXaWRnZXRQbHVnaW4gOiBmdW5jdGlvbihvcHRpb25zKSB7CiAgICAgICAgICAgIC8vY20tdXNlY2FzZTogYWRkaW5nIGNsYXNzIHRvIGVuYWJsZSByaWNoIHRleHQgd2lkZ2V0IHJlZ2lzdHJhdGlvbiBhZ2FpbnN0IHRoZSBjbGFzcwogICAgICAgICAgICBpZih0aGlzLl9yaWNoVGV4dFN1cHBvcnQoKSkgewogICAgICAgICAgICAgICAgdGhpcy4kZWwuYWRkQ2xhc3MoJ3JpY2h0ZXh0c3VwcG9ydCcpOwogICAgICAgIH0KICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5jcmVhdGVXaWRnZXRQbHVnaW4uY2FsbCh0aGlzLAogICAgICAgICAgICAgICAgb3B0aW9ucyk7CiAgICAgICAgfSwKCgogICAgICAgIF9nZXRNZWFzdXJlbWVudE9wdGlvbnMgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICB2YXIgbWVhc3VyZU9wdGlvbnMgPSB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9nZXRNZWFzdXJlbWVudE9wdGlvbnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAvLyBhZGRpbmcgdGhpcyBvcHRpb24gdG8gY2hlY2sgZm9yIGZpZWxkcyByZXF1aXJpbmcgcmljaCB0ZXh0IHN1cHBvcnQuCiAgICAgICAgICAgbWVhc3VyZU9wdGlvbnMuY29udGVudFR5cGUgPSB0aGlzLl9yaWNoVGV4dFN1cHBvcnQoKSA/ICJ0ZXh0L2h0bWwiOiJ0ZXh0L3BsYWluIjsKICAgICAgICAgICBtZWFzdXJlT3B0aW9ucy5za2lwWFNTUHJvdGVjdGlvbiA9ICQodGhpcy53aWRnZXQpLmRhdGEoJ3NraXBYU1NQcm90ZWN0aW9uJyk7CiAgICAgICAgICAgcmV0dXJuIG1lYXN1cmVPcHRpb25zOwogICAgICAgIH0sCgogICAgICAgIF9nZXRQYXJhU3R5bGVzIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIHBhcmFTdHlsZXMgPSB7fSxwYXJhOwogICAgICAgICAgICBwYXJhID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCJwYXJhIiwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIGlmKHBhcmEpewogICAgICAgICAgICAgICAgcGFyYVN0eWxlcyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX2dldFBhcmFTdHlsZXMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgIHBhcmFTdHlsZXNbJ2xpbmUtaGVpZ2h0J109IHBhcnNlRmxvYXQocGFyYS5saW5lSGVpZ2h0KT4wPyB0aGlzLl9jb252ZXJ0VG9QeChwYXJhLmxpbmVIZWlnaHQpKyJweCI6Im5vcm1hbCI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHBhcmFTdHlsZXM7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LkRhdGVUaW1lRmllbGRWaWV3ID0geGZhbGliLnZpZXcuRmllbGRWaWV3LmV4dGVuZCh7CgogICAgICAgIF9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luIDogZnVuY3Rpb24ob3B0aW9ucykgewogICAgICAgICAgICBpZiAodGhpcy5tb2RlbCAvKiYmIHhmYS5ob3N0LnBsYXRmb3JtICE9PSAiaVBhZCIqLykgewogICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkuZGF0ZVRpbWVFZGl0KG9wdGlvbnMpOwogICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtZGF0ZVRpbWVFZGl0Iik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luLmFwcGx5KHRoaXMsW29wdGlvbnNdKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVQbHVnaW5PcHRpb25zIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIHZPcHRpb25zID0geGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fY3JlYXRlUGx1Z2luT3B0aW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICBpZih0aGlzLm1vZGVsKSB7CiAgICAgICAgICAgICAgICB2YXIgbG9jYWxlID0gdGhpcy5tb2RlbC5sb2NhbGU7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy5kYXlzID0gdGhpcy5tb2RlbC5feGZhKCkuX2dldExvY2FsZVN5bWJvbHMobG9jYWxlLCJjYWxlbmRhclN5bWJvbHMuYWJicmRheU5hbWVzIik7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy5tb250aHMgPSB0aGlzLm1vZGVsLl94ZmEoKS5fZ2V0TG9jYWxlU3ltYm9scyhsb2NhbGUsImNhbGVuZGFyU3ltYm9scy5tb250aE5hbWVzIik7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy56ZXJvID0gdGhpcy5tb2RlbC5feGZhKCkuX2dldExvY2FsZVN5bWJvbHMobG9jYWxlLCJudW1iZXJTeW1ib2xzLnplcm8iKTsKICAgICAgICAgICAgICAgIHZPcHRpb25zLmNsZWFyVGV4dCA9IHhmYWxpYi5sb2NhbGUuU3RyaW5ncy5jbGVhclRleHQ7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy4kY2xpY2thYmxlID0gdGhpcy4kZWw7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy51c2VOYXRpdmVXaWRnZXQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIHZhciBiZWhhdmlvckNvbmZpZyA9IG5ldyB4ZmFsaWIudXQuVmVyc2lvbihmb3JtQnJpZGdlLnVzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl0pOwogICAgICAgICAgICAgICAgdk9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbiA9ICFiZWhhdmlvckNvbmZpZy5pc09uKCdtZkRpc2FibGVDYWxlbmRhckljb24nKTsKICAgICAgICAgICAgICAgIHZPcHRpb25zLmNhbGVuZGFySWNvbldpZHRoID0gXy5taW4oW3hmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuY2FsZW5kYXJJY29uTWF4V2lkdGgsIE1hdGguZmxvb3Iodk9wdGlvbnMuaGVpZ2h0KV0pIC0gMjsKCiAgICAgICAgICAgICAgICB2YXIgZWRpdFBhdHRlcm4gPSB0aGlzLmdldE9yRWxzZSh0aGlzLm1vZGVsLCAidWkucGljdHVyZS52YWx1ZSIsIG51bGwpOwogICAgICAgICAgICAgICAgaWYgKGVkaXRQYXR0ZXJuKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcnNlZFBhdHRlcm4gPSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLnBhcnNlUGljdHVyZUNsYXVzZShlZGl0UGF0dGVybik7CiAgICAgICAgICAgICAgICAgICAgaWYgKF8uaXNFbXB0eShwYXJzZWRQYXR0ZXJuKSB8fCBfLmlzQXJyYXkocGFyc2VkUGF0dGVybikgJiYgcGFyc2VkUGF0dGVybi5sZW5ndGggPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVkaXRQYXR0ZXJuID0gbnVsbDsgLy8gZm9yIG5vdyBmYWxsIGJhY2sgdG8gZGVmYXVsdCBwYXR0ZXJucyBpbiBjYXNlIG9mIHVuc3VwcG9ydGVkIC8gbXVsdGlwbGUgcGF0dGVybnMKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyA6IG1ha2UgYSBhcnJheSBvZiB0aGUgcGFyc2VkIG9iamVjdHMgYW5kIGl0ZXIgb3ZlciB0aGVtIGluIGFic3RyYWN0IHdpZGdldCA6IHBhcnNlRWRpdFZhbHVlCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZPcHRpb25zLmVkaXRQYXR0ZXJuID0gZWRpdFBhdHRlcm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZPcHRpb25zOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUNoYW5nZUV2ZW50OiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAvL1RPRE86IHBhc3Mgb24gdGhlIGNvcnJlY3QgZGF0YQogICAgICAgICAgICB2YXIgZGV0YWlsID0gewogICAgICAgICAgICAgICAgbmV3VGV4dDpudWxsLAogICAgICAgICAgICAgICAga2V5Y29kZTpudWxsLAogICAgICAgICAgICAgICAgbW9kaWZpZXI6bnVsbCwKICAgICAgICAgICAgICAgIGtleURvd246ZmFsc2UsCiAgICAgICAgICAgICAgICBzaGlmdDpmYWxzZSwKICAgICAgICAgICAgICAgIGNoYW5nZTogbnVsbAogICAgICAgICAgICB9OwogICAgICAgICAgICB0aGlzLm1vZGVsLmV4ZWNFdmVudCgiY2hhbmdlIiwgZGV0YWlsKTsKICAgICAgICB9CiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy5JbWFnZUZpZWxkVmlldyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5leHRlbmQoewoKICAgICAgICBfY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbiA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgJCh0aGlzLndpZGdldCkuaW1hZ2VGaWVsZChvcHRpb25zKTsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtaW1hZ2VGaWVsZCIpOwogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVQbHVnaW5PcHRpb25zIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB2T3B0aW9ucyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX2NyZWF0ZVBsdWdpbk9wdGlvbnMuYXBwbHkoCiAgICAgICAgICAgICAgICAgICAgdGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdmFyIGltYWdlT2JqID0gdGhpcy5nZXRPckVsc2UodGhpcywgIm1vZGVsLnZhbHVlLmltYWdlIiwgbnVsbCk7CiAgICAgICAgICAgIGlmIChpbWFnZU9iaikgewogICAgICAgICAgICAgICAgdk9wdGlvbnMuYXNwZWN0ID0gaW1hZ2VPYmouZ2V0QXR0cmlidXRlKCJhc3BlY3QiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdk9wdGlvbnM7CiAgICAgICAgfSwKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBoYW5kbGVDaGFuZ2VFdmVudCA6IGZ1bmN0aW9uKGNoYW5nZUV2ZW50KSB7CiAgICAgICAgICAgdGhpcy5tb2RlbC5leGVjRXZlbnQoImNoYW5nZSIpOwogICAgICAgICAgIC8vIE5QUi0xNTI4NiA6IHRvIHRyaWdnZXIgZXZlbnQgb24gZm9ybWJyaWRnZSB3aGVuZXZlciB0aGUgdmFsdWUgb2Ygc2NyaWJibGUgY2hhbmdlcy4KICAgICAgICAgICBpZiAodGhpcy5fZ2V0V2lkZ2V0TmFtZUZyb21VaUV4dHJhKCkgPT0geGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5TY3JpYmJsZUltYWdlRmllbGQpIHsKICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLl90cmlnZ2VyT25CcmlkZ2UoeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5zY3JpYmJsZUNoYW5nZUV2ZW50LCB0aGlzLm1vZGVsLCAiY2hhbmdlIiwgdGhpcy5tb2RlbC5zb21FeHByZXNzaW9uKTsKICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cn0pKF8sICQsIHhmYWxpYik7CihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgeGZhbGliLnZpZXcuQnV0dG9uRmllbGRWaWV3ID0geGZhbGliLnZpZXcuRmllbGRWaWV3LmV4dGVuZCh7CiAgICAgICAgaGFuZGxlQ29tbWl0IDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICAvLyB4ZmEuTG9nZ2VyLmRlYnVnKCJbQnV0dG9uRmllbGRWaWV3LmhhbmRsZUNvbW1pdF1zb20iICsKICAgICAgICAgICAgLy8gdGhpcy4kZWwuZGF0YSgic29tIikpOwogICAgICAgICAgICAvLyBkbyBOb3RoaW5nCiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlQ2xpY2tFdmVudCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmKHRoaXMuanFXaWRnZXQub3B0aW9uKCJhY2Nlc3MiKSA9PSAib3BlbiIpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX3NldEZvY3VzUGFyYW0odGhpcyk7CiAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmhhbmRsZUNsaWNrRXZlbnQuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLl90cmlnZ2VyT25CcmlkZ2UoImVsZW1lbnRCdXR0b25DbGlja2VkIiwgdGhpcy5tb2RlbCwgImNsaWNrIiwgdGhpcy5tb2RlbC5zb21FeHByZXNzaW9uKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVLZXlEb3duIDogZnVuY3Rpb24oZXZlbnQpIHsKCiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRG9tQ2hhbmdlZCA6ZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICBzd2l0Y2goZXZlbnQuX3Byb3BlcnR5KSB7CiAgICAgICAgICAgICAgIGNhc2UgImNhcHRpb24udmFsdWUudGV4dCI6CiAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUNhcHRpb25WYWx1ZUNoYW5nZShldmVudC5uZXdUZXh0KTsKICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuaGFuZGxlRG9tQ2hhbmdlZC5hcHBseSh0aGlzLAogICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUNhcHRpb25WYWx1ZUNoYW5nZSA6IGZ1bmN0aW9uKHRleHQpIHsKICAgICAgICAgICAgIHZhciAgY2hpbGQgPSB7fTsKICAgICAgICAgICAgIHZhciBjYXB0aW9uID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCdjYXB0aW9uJywwLCB0cnVlKTsKICAgICAgICAgICAgIHZhciB2YWx1ZSA9IGNhcHRpb24uZ2V0RWxlbWVudCgndmFsdWUnLDAsIHRydWUpOwoKICAgICAgICAgICAgIGlmKHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgY2hpbGQgPSB2YWx1ZS5vbmVPZkNoaWxkOwogICAgICAgICAgICAgICAgIGlmIChbInRleHQiLCJleERhdGEiXS5pbmRleE9mKGNoaWxkLmNsYXNzTmFtZSkgIT09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNzc09iaiA9IHRoaXMuX2dldFRleHRTdHlsZShjYXB0aW9uKTsKICAgICAgICAgICAgICAgICAgICBpZihjc3NPYmopIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuY2FwdGlvbiwgY3NzT2JqLmZvbnRTdHlsZXMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy5jYXB0aW9uLCB7J2Rpc3BsYXknOid0YWJsZSd9KTsgLy8gdXNpbmcgdGhpcyB0byB1dGlsaXNlIHRoZSBjc3MgcHJvcGVydHkgdmVydGljYWwtYWxpZ24gdG8gYWNjb3VudCBmb3IgdkFsaWduCiAgICAgICAgICAgICAgICAgICAgdGV4dD14ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZW5jb2RlU2NyaXB0YWJsZVRhZ3ModGhpcy5fY29udmVydFhGQVJpY2hUb0h0bWwodGV4dCkpOwogICAgICAgICAgICAgICAgICAgICQodGhpcy5jYXB0aW9uLmNoaWxkcmVuWzBdKS5yZXBsYWNlV2l0aCh0ZXh0KTsKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmNhcHRpb24uY2hpbGRyZW5bMF0gJiYgY3NzT2JqKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLmNhcHRpb24uY2hpbGRyZW5bMF0sIGNzc09iai5wYXJhU3R5bGVzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9nZXRUZXh0U3R5bGUgOiBmdW5jdGlvbihjYXB0aW9uKXsKICAgICAgICAgICAgdmFyIGNzc09iaj14ZmFsaWIudmlldy5CYXNlVmlldy5wcm90b3R5cGUuX2dldFRleHRTdHlsZS5hcHBseSh0aGlzLFtjYXB0aW9uXSk7CiAgICAgICAgICAgIHZhciBwYXJhID0gY2FwdGlvbi5nZXRFbGVtZW50KCdwYXJhJywwLHRydWUpOwogICAgICAgICAgICBpZihjc3NPYmogJiYgcGFyYSAmJiBwYXJhLnZBbGlnbikgewogICAgICAgICAgICAgICBjc3NPYmoucGFyYVN0eWxlc1sndmVydGljYWwtYWxpZ24nXT0gcGFyYS52QWxpZ247CiAgICAgICAgICAgICAgIGNzc09iai5wYXJhU3R5bGVzWydkaXNwbGF5J10gPSAndGFibGUtY2VsbCc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGNzc09iajsKICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlUGx1Z2luT3B0aW9ucyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgcGx1Z2luT3B0aW9ucyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX2NyZWF0ZVBsdWdpbk9wdGlvbnMuY2FsbCh0aGlzKTsKICAgICAgICAgICAgdmFyIHBhcmFTdHlsZXMgPSBudWxsOwogICAgICAgICAgICBpZih0aGlzLm1vZGVsLmdldEVsZW1lbnQoImNhcHRpb24iLCAwLCB0cnVlKSAmJiB0aGlzLm1vZGVsLmNhcHRpb24uZ2V0RWxlbWVudCgicGFyYSIsIDAsIHRydWUpKXsKICAgICAgICAgICAgICAgIHZhciBwYXJhID0gdGhpcy5tb2RlbC5jYXB0aW9uLnBhcmE7CiAgICAgICAgICAgICAgICBwYXJhU3R5bGVzID0gewogICAgICAgICAgICAgICAgICAgICJ0ZXh0LWFsaWduIiA6IHBhcmEuaEFsaWduLAogICAgICAgICAgICAgICAgICAgICJ2ZXJ0aWNhbC1hbGlnbiIgOiBwYXJhLnZBbGlnbiwKICAgICAgICAgICAgICAgICAgICAidGV4dC1pbmRlbnQiIDogdGhpcy5fY29udmVydFRvUHgocGFyYS50ZXh0SW5kZW50KSwKICAgICAgICAgICAgICAgICAgICAicGFkZGluZy1sZWZ0IiA6IHRoaXMuX2NvbnZlcnRUb1B4KHBhcmEubWFyZ2luTGVmdCksCiAgICAgICAgICAgICAgICAgICAgInBhZGRpbmctcmlnaHQiIDogdGhpcy5fY29udmVydFRvUHgocGFyYS5tYXJnaW5SaWdodCksCiAgICAgICAgICAgICAgICAgICAgInBhZGRpbmctdG9wIiA6IHRoaXMuX2NvbnZlcnRUb1B4KHBhcmEuc3BhY2VBYm92ZSksCiAgICAgICAgICAgICAgICAgICAgInBhZGRpbmctYm90dG9tIiA6IHRoaXMuX2NvbnZlcnRUb1B4KHBhcmEuc3BhY2VCZWxvdykKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcGx1Z2luT3B0aW9uc1sicGFyYVN0eWxlcyJdID0gcGFyYVN0eWxlczsKICAgICAgICAgICAgcGx1Z2luT3B0aW9uc1sic3ZnQ2FwdGlvbiJdID0gdGhpcy5jYXB0aW9uICE9IG51bGw7CiAgICAgICAgICAgIHJldHVybiBwbHVnaW5PcHRpb25zOwogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luIDogIGZ1bmN0aW9uKG9wdGlvbnMpewogICAgICAgICAgICBpZih0aGlzLm1vZGVsKXsKICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLnhmYUJ1dHRvbihvcHRpb25zKTsKICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQgPSB0aGlzLiRkYXRhKHRoaXMud2lkZ2V0LCAieGZhV2lkZ2V0LXhmYUJ1dHRvbiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luLmFwcGx5KHRoaXMsIFtvcHRpb25zXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sICQsIHhmYWxpYik7KGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy5OdW1lcmljRmllbGRWaWV3ID0geGZhbGliLnZpZXcuRmllbGRWaWV3LmV4dGVuZCh7CiAgICAgICAgX21hdGNoQXJyYXkgOiB7ICJpbnRlZ2VyIjoiXlsrLV0/XFxkKiQiLCAiZGVjaW1hbCI6Il5bKy1dP1xcZGxkKFxcLlxcZGZkKT8kIiwgImZsb2F0IjoiXlsrLV0/XFxkKihcXC5cXGQqKT8kIiB9LAogICAgICAgIF9jcmVhdGVQbHVnaW5PcHRpb25zIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB2T3B0aW9ucyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX2NyZWF0ZVBsdWdpbk9wdGlvbnMuYXBwbHkoCiAgICAgICAgICAgICAgICAgICAgdGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgaWYgKHRoaXMubW9kZWwpIHsKICAgICAgICAgICAgICAgIHZPcHRpb25zLmRhdGFUeXBlID0gdGhpcy5tb2RlbC52YWx1ZS5vbmVPZkNoaWxkLmNsYXNzTmFtZSA7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy5sZWFkRGlnaXRzID0gdGhpcy5tb2RlbC52YWx1ZS5vbmVPZkNoaWxkLmxlYWREaWdpdHM7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy5mcmFjRGlnaXRzID0gdGhpcy5tb2RlbC52YWx1ZS5vbmVPZkNoaWxkLmZyYWNEaWdpdHM7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy56ZXJvID0gdGhpcy5tb2RlbC5feGZhKCkuX2dldExvY2FsZVN5bWJvbHModGhpcy5tb2RlbC5sb2NhbGUsIm51bWJlclN5bWJvbHMuemVybyIpOwogICAgICAgICAgICAgICAgdk9wdGlvbnMuZGVjaW1hbCA9IHRoaXMubW9kZWwuX3hmYSgpLl9nZXRMb2NhbGVTeW1ib2xzKHRoaXMubW9kZWwubG9jYWxlLCJudW1iZXJTeW1ib2xzLmRlY2ltYWwiKTsKICAgICAgICAgICAgICAgIC8vbm90ZSA6IG51bWJlck9mQ2VsbHMgYXMgemVybyBzaG91bGQgYmUgdHJlYXRlZCBhcyB1bmRlZmluZWQvbm8gcmVzdHJpY3Rpb24KICAgICAgICAgICAgICAgIHZhciB1aUNoaWxkID0gdGhpcy5tb2RlbC51aS5vbmVPZkNoaWxkOwogICAgICAgICAgICAgICAgaWYodWlDaGlsZCAhPSBudWxsICYmIHVpQ2hpbGQuZ2V0RWxlbWVudCgiY29tYiIsIDAsIHRydWUpICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMuY29tYkNlbGxzID0gdGhpcy5tb2RlbC51aS5vbmVPZkNoaWxkLmNvbWIubnVtYmVyT2ZDZWxscyB8fCB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZPcHRpb25zOwogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luIDogZnVuY3Rpb24ob3B0aW9ucykgewogICAgICAgICAgICBpZiAodGhpcy5tb2RlbCkgewogICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkubnVtZXJpY0lucHV0KG9wdGlvbnMpOwogICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtbnVtZXJpY0lucHV0Iik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luLmFwcGx5KHRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYW5kbGVDb21taXQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICB2YXIgX3JlZ2V4ID0gbnVsbDsKICAgICAgICAgICAgdmFyIHRlbXAgPSB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigidmFsdWUiKSArICIiOwoKICAgICAgICAgICAgdmFyIGxkID0gdGhpcy5tb2RlbC52YWx1ZS5vbmVPZkNoaWxkLmxlYWREaWdpdHM7CiAgICAgICAgICAgIHZhciBmZCA9IHRoaXMubW9kZWwudmFsdWUub25lT2ZDaGlsZC5mcmFjRGlnaXRzOwoKICAgICAgICAgICAgdmFyIG1hdGNoU3RyID0gdGhpcy5fbWF0Y2hBcnJheVt0aGlzLm1vZGVsLnZhbHVlLm9uZU9mQ2hpbGQuY2xhc3NOYW1lXTsKCiAgICAgICAgICAgIGxkID0gKGxkICE9PSB1bmRlZmluZWQgJiYgfmxkKSA/ICJ7MCwiK2xkKyJ9IiA6ICIqIjsKICAgICAgICAgICAgZmQgPSAoZmQgIT09IHVuZGVmaW5lZCAmJiB+ZmQpID8gInswLCIrZmQrIn0iIDogIioiOwogICAgICAgICAgICBtYXRjaFN0ciA9IG1hdGNoU3RyLnJlcGxhY2UoImxkIiwgbGQpOwogICAgICAgICAgICBtYXRjaFN0ciA9IG1hdGNoU3RyLnJlcGxhY2UoImZkIiwgZmQpOwogICAgICAgICAgICBfcmVnZXggPSBuZXcgUmVnRXhwKG1hdGNoU3RyLCAiZyIpOwoKICAgICAgICAgICAgaWYgKHRlbXAubWF0Y2goX3JlZ2V4KSkgLy8gaWYgd2UgbmVlZCB0byBrZWVwIHRoaXMgbmV3CWVudGVyZWQgdmFsdWUKICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuaGFuZGxlQ29tbWl0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigidmFsdWUiLHRoaXMubW9kZWxbdGhpcy5jb21taXRUYXJnZXRdKTsKICAgICAgICB9CiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy5DaG9pY2VMaXN0RmllbGRWaWV3ID0geGZhbGliLnZpZXcuRmllbGRWaWV3LmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuX3ByZXZTZWxlY3Rpb24gPSBudWxsOwogICAgICAgIH0sCgogICAgICAgIF92YWx1ZVRvQXJyYXk6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgIHZhciB2YWx1ZUFycmF5OwogICAgICAgICAgICBpZih2YWx1ZSAhPSBudWxsKQogICAgICAgICAgICAgICAgdmFsdWVBcnJheSA9IHZhbHVlLnNwbGl0KCJcbiIpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB2YWx1ZUFycmF5ID0gW251bGxdOwogICAgICAgICAgICByZXR1cm4gdmFsdWVBcnJheTsKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlVmFsdWVDaGFuZ2UgOiBmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgIC8veGZhLkxvZ2dlci5kZWJ1ZygiW0Nob2ljZUxpc3RGaWVsZFZpZXcuX2hhbmRsZVZhbHVlQ2hhbmdlXXZhbHVlOnNvbSIgKyBldmVudC5uZXdUZXh0ICsgIjoiICsgdGhpcy4kZWwuZGF0YSgic29tIikpOwogICAgICAgICAgICB2YXIgcHJldlRleHQgPSB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigiZGlzcGxheVZhbHVlIik7CiAgICAgICAgICAgIGlmIChfLmlzQXJyYXkocHJldlRleHQpKSB7CiAgICAgICAgICAgICAgICBwcmV2VGV4dCA9IHByZXZUZXh0LmpvaW4oIlxuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5fcHJldlNlbGVjdGlvbiA9IHByZXZUZXh0OwoKICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24oInZhbHVlIix0aGlzLl92YWx1ZVRvQXJyYXkoZXZlbnQucHJldlRleHQpKTsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24oImRpc3BsYXlWYWx1ZSIsdGhpcy5fdmFsdWVUb0FycmF5KGV2ZW50Lm5ld1RleHQpKTsKICAgICAgICB9LAoKICAgICAgICBoYW5kbGVDb21taXQgOiBmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgIC8veGZhLkxvZ2dlci5kZWJ1ZygiW0Nob2ljZUxpc3RGaWVsZFZpZXcuaGFuZGxlQ29tbWl0XXNvbSIgKyB0aGlzLiRlbC5kYXRhKCJzb20iKSk7CiAgICAgICAgICAgIHZhciB2YWwgPSB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigidmFsdWUiKTsKICAgICAgICAgICAgaWYoXy5pc0FycmF5KHZhbCkpewogICAgICAgICAgICAgICAgdmFsID0gdmFsLmpvaW4oIlxuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5tb2RlbFt0aGlzLmNvbW1pdFRhcmdldF0gPSB2YWw7CiAgICAgICAgfSwKCiAgICAgICAgX2NyZWF0ZURlZmF1bHRXaWRnZXRQbHVnaW4gOiAgZnVuY3Rpb24ob3B0aW9ucyl7CiAgICAgICAgICAgIGlmKHRoaXMubW9kZWwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMubW9kZWwudWkub25lT2ZDaGlsZC5vcGVuID09ICdhbHdheXMnIHx8IHRoaXMubW9kZWwudWkub25lT2ZDaGlsZC5vcGVuID09ICdtdWx0aVNlbGVjdCcpewoJCQkJCS8vZG8gcm9sZSBzZXR0aW5nIC0tCiAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5hdHRyKCJyb2xlIiwgImxpc3Rib3giKTsgLy9maW5kIGEgYmV0dGVyIHBsYWNlIHRvIGRvIHRoaXMKICAgICAgICAgICAgICAgICAgICBpZigkLmJyb3dzZXIubXNpZSB8fCAkLmJyb3dzZXIubW96aWxsYSl7CiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLm53a0xpc3RCb3gob3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQgPSB0aGlzLiRkYXRhKHRoaXMud2lkZ2V0LCAieGZhV2lkZ2V0LW53a0xpc3RCb3giKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLmxpc3RCb3gob3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQgPSB0aGlzLiRkYXRhKHRoaXMud2lkZ2V0LCAieGZhV2lkZ2V0LWxpc3RCb3giKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLmRyb3BEb3duTGlzdChvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmpxV2lkZ2V0ID0gdGhpcy4kZGF0YSh0aGlzLndpZGdldCwgInhmYVdpZGdldC1kcm9wRG93bkxpc3QiKTsKICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5hY2Nlc3MgPT09ICJyZWFkT25seSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlYWRPbmx5RHJvcERvd24gPSB0aGlzLndpZGdldC5nZXRFbGVtZW50c0J5VGFnTmFtZSgic2VsZWN0IilbMF07CiAgICAgICAgICAgICAgICAgICAgICAgIHJlYWRPbmx5RHJvcERvd24uZGlzYWJsZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVhZE9ubHlEcm9wRG93bi5zZXRBdHRyaWJ1dGUoImFyaWEtcmVhZG9ubHkiLCAidHJ1ZSIpOwogICAgICAgICAgICAgICAgICAgICAgICBfLmVhY2gocmVhZE9ubHlEcm9wRG93bi5jaGlsZE5vZGVzLCBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5kaXNhYmxlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbi5hcHBseSh0aGlzLCBbb3B0aW9uc10pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2NyZWF0ZVBsdWdpbk9wdGlvbnMgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgdk9wdGlvbnMgPSAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fY3JlYXRlUGx1Z2luT3B0aW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICBpZih2T3B0aW9ucy52YWx1ZSE9bnVsbCAmJiAhXy5pc0FycmF5KHZPcHRpb25zLnZhbHVlKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoXy5pc1N0cmluZyh2T3B0aW9ucy52YWx1ZSkpCiAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMudmFsdWUgPSB2T3B0aW9ucy52YWx1ZS5zcGxpdCgiXG4iKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB2T3B0aW9ucy52YWx1ZSA9IFt2T3B0aW9ucy52YWx1ZV07IC8vY29udmVydCBuZXcgdmFsdWUgdG8gYXJyYXkKICAgICAgICAgICAgfQogICAgICAgICAgICBpZih0aGlzLm1vZGVsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy5lZGl0YWJsZSA9ICAodGhpcy5tb2RlbC51aS5vbmVPZkNoaWxkLnRleHRFbnRyeSA9PSAnMScpOwogICAgICAgICAgICAgICAgdk9wdGlvbnMubXVsdGlTZWxlY3QgPSAgKHRoaXMubW9kZWwudWkub25lT2ZDaGlsZC5vcGVuID09ICdtdWx0aVNlbGVjdCcpOwogICAgICAgICAgICAgICAgdmFyIHZJdGVtcyA9IF8ubWFwKHRoaXMubW9kZWwuX2dldERpc3BsYXlJdGVtcygpID8gdGhpcy5tb2RlbC5fZ2V0RGlzcGxheUl0ZW1zKCkubW9DaGlsZE5vZGVzIDogW10sCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oaXRlbSwgaW5kZXgpewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2F2ZUl0ZW0gPSAgdGhhdC5tb2RlbC5nZXRTYXZlSXRlbShpbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkaXNwbGF5SXRlbSA9IHRoYXQubW9kZWwuZ2V0RGlzcGxheUl0ZW0oaW5kZXgpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNhdmUiIDogc2F2ZUl0ZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGlzcGxheSIgOiBkaXNwbGF5SXRlbQogICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy5pdGVtcyA9IHZJdGVtczsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdk9wdGlvbnM7CiAgICAgICAgfSwKICAgICAgICAKICAgICAgICBoYW5kbGVNb2RlbENoYW5nZWQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICBpZiAoZXZlbnQuX3Byb3BlcnR5ID09ICJhZGRJdGVtIikgewogICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQWRkSXRlbShldmVudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGV2ZW50Ll9wcm9wZXJ0eSA9PSAiY2xlYXJJdGVtcyIpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVDbGVhckl0ZW1zKGV2ZW50KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZXZlbnQuX3Byb3BlcnR5ID09ICJkZWxldGVJdGVtIikgewogICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlRGVsZXRlSXRlbShldmVudCk7CiAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmhhbmRsZU1vZGVsQ2hhbmdlZC5hcHBseSh0aGlzLAogICAgICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUNoYW5nZUV2ZW50IDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgdmFyIG5ld1ZhbHVlID0gIHRoaXMuanFXaWRnZXQub3B0aW9uKCJkaXNwbGF5VmFsdWUiKTsKICAgICAgICAgICAgaWYoXy5pc0FycmF5KG5ld1ZhbHVlKSkgewogICAgICAgICAgICAgICAgbmV3VmFsdWUgPSBuZXdWYWx1ZS5qb2luKCJcbiIpOyAvLyByZXR1cm4gYSBzdHJpbmcKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgZGV0YWlsID0gewogICAgICAgICAgICAgICAgbmV3VGV4dDpuZXdWYWx1ZSwKICAgICAgICAgICAgICAgIHByZXZUZXh0OiB0aGlzLl9wcmV2U2VsZWN0aW9uLAogICAgICAgICAgICAgICAga2V5Y29kZTpldmVudC53aGljaCwKICAgICAgICAgICAgICAgIG1vZGlmaWVyOmV2ZW50LmN0cmxLZXksCiAgICAgICAgICAgICAgICBrZXlEb3duOmV2ZW50LndoaWNoPT09NDAsCiAgICAgICAgICAgICAgICBzaGlmdDpldmVudC5zaGlmdEtleSwKICAgICAgICAgICAgICAgIGNoYW5nZTogbmV3VmFsdWUKICAgICAgICAgICAgfTsKICAgICAgICAgICAgdGhpcy5tb2RlbC5leGVjRXZlbnQoImNoYW5nZSIsIGRldGFpbCk7CiAgICAgICAgfSwKICAgICAgICAKICAgICAgICBfaGFuZGxlQWRkSXRlbSA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgCXZhciBpdGVtVmFsdWVzID0gewogICAgICAgIAkJCXNEaXNwbGF5VmFsOmV2ZW50Lm5ld1RleHQsCiAgICAgICAgCQkJc1NhdmVWYWw6ZXZlbnQucHJldlRleHQKICAgICAgICAgICAgICAgIH07CiAgICAgICAgCXRoaXMuanFXaWRnZXQuYWRkSXRlbShpdGVtVmFsdWVzKTsKICAgICAgICAgICAgfSwKICAgICAgICAKICAgICAgICBfaGFuZGxlQ2xlYXJJdGVtcyA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgCXRoaXMuanFXaWRnZXQuY2xlYXJJdGVtcygpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgCiAgICAgICAgX2hhbmRsZURlbGV0ZUl0ZW0gOiBmdW5jdGlvbihldmVudCkgewogICAgICAgIAl0aGlzLmpxV2lkZ2V0LmRlbGV0ZUl0ZW0oZXZlbnQubmV3VGV4dCk7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKCiAgICB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3ID0geGZhbGliLnZpZXcuQmFzZVZpZXcuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMubGF5b3V0VGVtcGxhdGUgPSB7fTsKICAgICAgICAgICAgdGhpcy5jaGlsZFZpZXdzID0gW107CiAgICAgICAgICAgIHRoaXMubGF5b3V0ID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5faW5pdExheW91dCgpOwogICAgICAgIH0sCgogICAgICAgIF9pbml0TGF5b3V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLl9pbml0TGF5b3V0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMuX2luaXRpYWxpemVkKXsKICAgICAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3NMYXlvdXRUZW1wbGF0ZSgpOwogICAgICAgICAgICAgICAgdGhpcy5sYXlvdXQgPSB0aGlzLl9sYXlvdXRNYW5hZ2VyLmNyZWF0ZUxheW91dCh0aGlzKTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm1vZGVsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuQ0hJTERfQURERUQsdGhpcyk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuQ0hJTERfUkVNT1ZFRCx0aGlzKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9uKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5DSElMRF9NT1ZFRCx0aGlzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX3N5bmNGb3JtTm9kZVRvSHRtbCh0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9wcm9jZXNzTGF5b3V0VGVtcGxhdGUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgeGZhVGVtcGxhdGVDYWNoZSA9IHRoaXMuX2Zvcm1Eb21Sb290KCkuX3hmYVRlbXBsYXRlQ2FjaGU7CiAgICAgICAgICAgIHZhciBodG1sVGVtcGxhdGVDYWNoZSA9IHRoaXMuX3hmYVZpZXdSZWdpc3RyeSgpLnRlbXBsYXRlQ2FjaGUoKTsKICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICB2YXIgaW5pdGlhbEZvcm1Ob2RlID0geGZhVGVtcGxhdGVDYWNoZS5nZXRJbml0aWFsRm9ybURvbVJlZih0aGlzLl9pZCk7CiAgICAgICAgICAgIGlmKCFpbml0aWFsRm9ybU5vZGUpewogICAgICAgICAgICAgICAgdGhpcy5sYXlvdXRUZW1wbGF0ZS5oYXNUZW1wbGF0ZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0VGVtcGxhdGUuaGFzVGVtcGxhdGUgPSB0cnVlOwoKICAgICAgICAgICAgdGhpcy4kZWxjaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICB2YXIgaUNoaWxkTm9kZSA9IHhmYVRlbXBsYXRlQ2FjaGUuZ2V0SW5pdGlhbEZvcm1Eb21SZWYodGhpcy5pZCk7CiAgICAgICAgICAgICAgICBpZighaUNoaWxkTm9kZSkKICAgICAgICAgICAgICAgICAgICByZXR1cm47CgogICAgICAgICAgICAgICAgdmFyIHBhcnRCZWdpbiA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgcGFydFNwbGl0ID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgcGFydEVuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB2YXIgb2NjdXJyZW5jZXMgPSB0aGF0LmdldE9yRWxzZSh0aGF0LiRkYXRhKHRoaXMsIHhmYWxpYi52aWV3LkxheW91dENvbnN0LlhGQV9NT0RFTCksIHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9NT0RFTCsiLiIreGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuT0NDVVJSRU5DRVMsIDEpOyAvL29jY3VycmVuY2VzCiAgICAgICAgICAgICAgICB2YXIgY3VycmVudE9jY3VyZW5jZSA9IHRoYXQuZ2V0T3JFbHNlKHRoYXQuJGRhdGEodGhpcywgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMKSwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX01PREVMKyIuIit4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5PQ0NVUl9JTkRFWCwgMCk7IC8vb2NjdXJJbmRleAogICAgICAgICAgICAgICAgaWYoY3VycmVudE9jY3VyZW5jZSAhPSAwKXsKICAgICAgICAgICAgICAgICAgICAvL1RoZSBwYXJ0IGhhcyBiZWVuIHNwbGl0IGFuZCBjdXJyZW50T2NjdXJhbmNlIGlzIG5vdCB6ZXJvLiBUaGF0IG1lYW5zIHRoaXMgZWxlbWVudCBkb2VzIG5vdCBzdGFydCBpbiB0aGUgcGFyZW50IGxheW91dC4KICAgICAgICAgICAgICAgICAgICBwYXJ0QmVnaW4gPSBmYWxzZTsgLy8gbm90IHJlYWxseSB1c2VkIGFueXdoZXJlCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZigob2NjdXJyZW5jZXMgLSBjdXJyZW50T2NjdXJlbmNlKSA+IDEpewogICAgICAgICAgICAgICAgICAgIC8vVGhpcyBtZWFucyB0aGF0IHRoaXMgZWxlbWVudCBsYXlvdXQgaGFzIGJlZW4gc3BsaXQgaW50byBtdWx0aXBsZSBwYXJ0cyBhbmQgdGhpcyBwYXJ0IGlzIG5vdCBsYXN0IHBhcnQuCiAgICAgICAgICAgICAgICAgICAgcGFydFNwbGl0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBwYXJ0RW5kID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgY2hpbGRUZW1wbGF0ZUlkID0geGZhVGVtcGxhdGVDYWNoZS5nZXRUZW1wbGF0ZVJlZihpQ2hpbGROb2RlLmV4dHJhcy5odG1sSWQpLmV4dHJhcy5odG1sSWQ7CiAgICAgICAgICAgICAgICB0aGF0LiRkYXRhKHRoaXMsICJ0ZW1wbGF0ZUlkIiwgY2hpbGRUZW1wbGF0ZUlkKTsgLy8gU2V0IHRoZSB0ZW1wbGF0ZUlkIGFzIGFjdHVhbCBpZCBtYXkgY2hhbmdlLgogICAgICAgICAgICAgICAgaWYoeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmlzVGFibGVIRihpQ2hpbGROb2RlKSl7CiAgICAgICAgICAgICAgICAgICAgLy9BIHN1cGVyIGhhY2sgZm9yICMzNDY4NDA3IHRpbGwgd2Ugc3VwcG9ydCBsZWFkZXIvdHJhaWxlci4gRm9yIFRhYmxlIEhlYWRlci9Gb290ZXIgd2UgbWF5IG5vdCBoYXZlIElNIGJlZm9yZSBpdC4gU28gaGFuZGxlIGV4Y2x1c2l2ZWx5IHRpbGwgd2UgZml4IGl0CiAgICAgICAgICAgICAgICAgICAgdGhhdC5sYXlvdXRUZW1wbGF0ZVtpQ2hpbGROb2RlLmV4dHJhcy5odG1sSWRdID0ge2hhc0ZpcnN0UGFydEJlZ2luIDogcGFydEJlZ2luLCBoYXNMYXN0UGFydE92ZXJmbG93IDogcGFydFNwbGl0fTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYoaUNoaWxkTm9kZSAmJiB0aGF0LmdldE9yRWxzZSh0aGF0LiRkYXRhKHRoaXMsIHhmYWxpYi52aWV3LkxheW91dENvbnN0LlhGQV9NT0RFTCksIHhmYWxpYi52aWV3LkxheW91dENvbnN0Lk5PREVfVFlQRSAsIiIpLnRvTG93ZXJDYXNlKCkgPT0gInN1YmZvcm0iKXsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2VJbmRleCA9IC0xOwogICAgICAgICAgICAgICAgICAgIHZhciBzZklNID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICB2YXIgZm91bmQgPSBfLmZpbmQoaW5pdGlhbEZvcm1Ob2RlLmNoaWxkcmVuLCBmdW5jdGlvbihpbml0Q2hpbGQpewogICAgICAgICAgICAgICAgICAgICAgICBpZih0aGF0Lm1hdGNoSnNvblR5cGUoaW5pdENoaWxkLCAiaW5zdGFuY2VNYW5hZ2VyIikpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZJTSA9IGluaXRDaGlsZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSW5kZXggPSAtMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSW5kZXggPSBpbnN0YW5jZUluZGV4ICsgMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGluaXRDaGlsZCA9PSBpQ2hpbGROb2RlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIGlmKGZvdW5kKXsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgcmVwZWF0YWJsZSBwdXQgaW4gY2FjaGUsIGFsb25nIHdpdGggY3VycmVudCBvY2N1ckluZGV4IGZvciBsYXRlciBzdGl0Y2hpbmcKICAgICAgICAgICAgICAgICAgICAgICAgaWYoaUNoaWxkTm9kZS5leHRyYXMuaHRtbElkID09IGNoaWxkVGVtcGxhdGVJZCAmJiBzZklNICYmIChwYXJzZUludCh0aGF0LmdldE9yRWxzZShzZklNLm1heCwgeGZhbGliLnNjcmlwdC5PY2N1ci5wcm90b3R5cGUuX2RlZmF1bHRzLm1heCkpIDwgMCB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VJbnQodGhhdC5nZXRPckVsc2Uoc2ZJTS5taW4sIHhmYWxpYi5zY3JpcHQuT2NjdXIucHJvdG90eXBlLl9kZWZhdWx0cy5taW4gKSkgPCBwYXJzZUludCh0aGF0LmdldE9yRWxzZShzZklNLm1heCwgeGZhbGliLnNjcmlwdC5PY2N1ci5wcm90b3R5cGUuX2RlZmF1bHRzLm1heCApKSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaHRtbFRlbXBsYXRlQ2FjaGUucHV0KHRoaXMuY2xvbmVOb2RlKHRydWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNMYXN0Q2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRJbmRleCA9IGluaXRpYWxGb3JtTm9kZS5jaGlsZHJlbi5pbmRleE9mKGlDaGlsZE5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZihpbml0aWFsRm9ybU5vZGUuY2hpbGRyZW4ubGVuZ3RoID4gY2hpbGRJbmRleCArMSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5tYXRjaEpzb25UeXBlKGluaXRpYWxGb3JtTm9kZS5jaGlsZHJlbltjaGlsZEluZGV4ICsgMV0sICJzdWJmb3JtIikpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNMYXN0Q2hpbGQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUluZGV4ID0gaW5zdGFuY2VJbmRleCArIGN1cnJlbnRPY2N1cmVuY2UvMTAwMDsgIC8vIGhhY2ssIGFzc3VtZSBhdCBtb3N0IDEwMDAgaW5zdGFuY2VzIG9mIGEgcnB0LiBTRi4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBkZWNpbWFsIHBhcnQgaXMgdXNlZCB0byBqdWRnZSB0aGUgb3ZlcmZsb3dlZCBwYXJ0IHdoaWNoIGhhcyBzcGxpdCBvdmVyIG11bHRpcGxlIHBhZ2VzCiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQubGF5b3V0VGVtcGxhdGVbY2hpbGRUZW1wbGF0ZUlkXSA9ICFfLmlzRW1wdHkodGhhdC5sYXlvdXRUZW1wbGF0ZVtjaGlsZFRlbXBsYXRlSWRdKSA/IHRoYXQubGF5b3V0VGVtcGxhdGVbY2hpbGRUZW1wbGF0ZUlkXSA6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBjaGlsZFRlbXBsYXRlSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydCA6IGluc3RhbmNlSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQgOiBpbnN0YW5jZUluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzRmlyc3RQYXJ0QmVnaW4gOiBwYXJ0QmVnaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXNMYXN0UGFydE92ZXJmbG93IDogcGFydFNwbGl0CiAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQubGF5b3V0VGVtcGxhdGVbY2hpbGRUZW1wbGF0ZUlkXS5lbmQgPSBpc0xhc3RDaGlsZCAmJiBwYXJ0RW5kID8gLTEgOiBpbnN0YW5jZUluZGV4OwogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmxheW91dFRlbXBsYXRlW2NoaWxkVGVtcGxhdGVJZF0uaGFzTGFzdFBhcnRPdmVyZmxvdyA9IHBhcnRTcGxpdDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoYXQubGF5b3V0VGVtcGxhdGVbY2hpbGRUZW1wbGF0ZUlkXSA9IHtoYXNGaXJzdFBhcnRCZWdpbiA6IHBhcnRCZWdpbiwgaGFzTGFzdFBhcnRPdmVyZmxvdyA6IHBhcnRTcGxpdH07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pIDsKICAgICAgICB9LAoKICAgICAgICBfc3luY0Zvcm1Ob2RlVG9IdG1sOiBmdW5jdGlvbihkZWVwU3luYyl7CiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgdmFyIGh0bWxUZW1wbGF0ZUNhY2hlID0gdGhpcy5feGZhVmlld1JlZ2lzdHJ5KCkudGVtcGxhdGVDYWNoZSgpOwogICAgICAgICAgICB2YXIgb2xkSWRUb0NoaWxkVmlld3MgPSB7fTsKICAgICAgICAgICAgdmFyIG5ld0lkVG9DaGlsZFZpZXdzID0ge307CiAgICAgICAgICAgIHZhciBjZWxsSW5kZXggPSAwOwogICAgICAgICAgICB2YXIgbGFzdFNpYmxpbmcgPSBudWxsOwoKICAgICAgICAgICAgLy9jYWNoZSB0aGUgb2xkIGNoaWxkIHZpZXdzIGFnYWluc3QgdGhlaXIgSURzCiAgICAgICAgICAgIF8uZWFjaCh0aGlzLmNoaWxkVmlld3MsIGZ1bmN0aW9uKGNoaWxkVmlldyl7CiAgICAgICAgICAgICAgICBvbGRJZFRvQ2hpbGRWaWV3c1tjaGlsZFZpZXcuZWwuaWRdID0gY2hpbGRWaWV3OwogICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgIF8uZWFjaCh0aGlzLmdldE9yRWxzZSh0aGlzLCAibW9kZWwuY2hpbGRyZW4iLCBbXSksCiAgICAgICAgICAgICAgICBmdW5jdGlvbihjaGlsZE1vZGVsKXsKICAgICAgICAgICAgICAgICAgICBpZighdGhpcy5fdmFsaWRhdGVMYXlvdXRUZW1wbGF0ZShjaGlsZE1vZGVsKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIHZhciBjVGVtcGxhdGVJZCA9IGNoaWxkTW9kZWwuX3RlbXBsYXRlSWQoKTsKICAgICAgICAgICAgICAgICAgICB2YXIgaWQgPSBjaGlsZE1vZGVsLmh0bWxJZDsKICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRFbCA9IHRoaXMuJGVsY2hpbGRyZW4odGhhdC5qcUlkKGlkKSlbMF07CiAgICAgICAgICAgICAgICAgICAgaWYoIWNoaWxkRWwgJiYgKCFuZXdJZFRvQ2hpbGRWaWV3cy5oYXNPd25Qcm9wZXJ0eShjVGVtcGxhdGVJZCkgJiYgIW9sZElkVG9DaGlsZFZpZXdzLmhhc093blByb3BlcnR5KGNUZW1wbGF0ZUlkKSkpewogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZEVsID0gdGhpcy4kZWxjaGlsZHJlbih0aGF0LmpxSWQoY1RlbXBsYXRlSWQpKVswXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYoIWNoaWxkRWwpewogICAgICAgICAgICAgICAgICAgICAgICBpZighdGhpcy5faXNIaWRkZW4oY2hpbGRNb2RlbCkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGh0bWxUbXBsdCA9IGh0bWxUZW1wbGF0ZUNhY2hlLmdldChjVGVtcGxhdGVJZCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZighaHRtbFRtcGx0KXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmVycm9yKCJ4ZmFWaWV3IiwgIkh0bWwgdGVtcGxhdGUgY291bGQgbm90IGJlIGZvdW5kLiBjVGVtcGxhdGVJZDoiK2NUZW1wbGF0ZUlkKyIsIHNvbToiK2NoaWxkTW9kZWwuc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZEVsID0gaHRtbFRtcGx0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHhmYUhpZGRlblBIID0gJCgiPGRpdj48L2Rpdj4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNoaWxkTW9kZWwgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LkRyYXcpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmYUhpZGRlblBILmFkZENsYXNzKCJkcmF3Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKGNoaWxkTW9kZWwgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LkZpZWxkKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZmFIaWRkZW5QSC5hZGRDbGFzcygiZmllbGQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkRWwgPSB4ZmFIaWRkZW5QSC5nZXQoMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1RPRE86IGJlbG93IHdheSBvZiBmaW5kaW5nIG5vZGV0eXBlIGlzIG5vdCBhbHdheXMgdHJ1ZSBhbmQgbWF5IGJyZWFrIGhpZGRlbiBvYmplY3RzLiBXZSB3aWxsIG5lZWQgcm9idXN0IHdheSB0byBnZXQgbm9kZSB0eXBlIHRoYXQgY2FuIGJlIHVzZWQgYnkgWGZhVmlld1JlZ2lzdHJ5Lm5vZGVUeXBlcmVnaXN0cnkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0J1dCBmb3IgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBpdCB3b3VsZCB3b3JrIGFzIHdlIGNhcmUgb25seSBhYm91dCBjb250YWluZXIgbm9kZSB0eXBlcy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbE5vZGVUeXBlID0gY2hpbGRNb2RlbC5jbGFzc05hbWUudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGRhdGEoY2hpbGRFbCwgInhmYUhpZGRlblBIIiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgeGZhTW9kZWxPYmogPSB7fTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmYU1vZGVsT2JqW3hmYWxpYi52aWV3LkxheW91dENvbnN0Lk5PREVfVFlQRV0gPSBlbE5vZGVUeXBlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kZGF0YShjaGlsZEVsLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5YRkFfTU9ERUwsIHhmYU1vZGVsT2JqKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjaGlsZEVsLmlkID0gY2hpbGRNb2RlbC5odG1sSWQ7CgogICAgICAgICAgICAgICAgICAgIHRoaXMuJGRhdGEoY2hpbGRFbCwidGVtcGxhdGVJZCIsIGNUZW1wbGF0ZUlkKTsgLy9SZXF1aXJlZCBmb3IgbmVzdGVkIHRlbXBsYXRlIEVMcwogICAgICAgICAgICAgICAgICAgIHZhciB2aWV3ID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBpZihvbGRJZFRvQ2hpbGRWaWV3cy5oYXNPd25Qcm9wZXJ0eShjaGlsZEVsLmlkKSkgewogICAgICAgICAgICAgICAgICAgICAgICB2aWV3ID0gb2xkSWRUb0NoaWxkVmlld3NbY2hpbGRFbC5pZF07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGxhc3RTaWJsaW5nICYmIGxhc3RTaWJsaW5nLm1vZGVsIGluc3RhbmNlb2YgeGZhbGliLnNjcmlwdC5TdWJmb3JtICYmIGxhc3RTaWJsaW5nLm1vZGVsLmluc3RhbmNlTWFuYWdlci5faXNSZXBlYXRhYmxlKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0U2libGluZy4kZWwuYWZ0ZXIodmlldy4kZWwpOyAvL1RoZSByZXBlYXRhYmxlIHN1YmZvcm0gbWlnaHQgaGF2ZSBtb3ZlZCB1c2luZyBtb3ZlSW5zdGFuY2UuIFNvIHBvc2l0aW9uIGl0IGFmdGVyIGl0J3Mgc2libGluZy4KICAgICAgICAgICAgICAgICAgICAgICAgaWYoZGVlcFN5bmMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3LnN5bmNGb3JtTm9kZVRvSHRtbChkZWVwU3luYyk7IC8vU3luYyBleGlzdGluZyB2aWV3cyBvbmx5IGlmIGRlZXBTeW5jIGlzIHJlcXVlc3RlZAogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZpZXcgPSB0aGlzLl9jcmVhdGVDaGlsZChjaGlsZEVsLCBjZWxsSW5kZXgsIGxhc3RTaWJsaW5nKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2VsbEluZGV4ID0gY2VsbEluZGV4ICsgKHZpZXcubGF5b3V0TW9kZWwuY29sc3BhbiB8fCAxKTsgLy9BZGQgdGhlIGNvbHNwYW4gb3Igb25lCiAgICAgICAgICAgICAgICAgICAgbmV3SWRUb0NoaWxkVmlld3NbY2hpbGRNb2RlbC5odG1sSWRdID0gdmlldzsKICAgICAgICAgICAgICAgICAgICBsYXN0U2libGluZyA9IHZpZXc7CiAgICAgICAgICAgICAgICB9LCB0aGlzCiAgICAgICAgICAgICk7CgogICAgICAgICAgICB0aGlzLmNoaWxkVmlld3MgPSBbXTsKICAgICAgICAgICAgaWYgKCF0aGlzLiRlbC5pcygiOmVtcHR5IikpIHsKICAgICAgICAgICAgICAgIHRoaXMuJGVsY2hpbGRyZW4oKS5lYWNoKGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIGlmKG5ld0lkVG9DaGlsZFZpZXdzLmhhc093blByb3BlcnR5KHRoaXMuaWQpKQogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmNoaWxkVmlld3MucHVzaChuZXdJZFRvQ2hpbGRWaWV3c1t0aGlzLmlkXSk7CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmxvZygieGZhVmlldyIsNSwicmVtb3ZpbmcgZWxlbWVudCBhcyBubyBjb3JyZXNwb25kaW5nIGZvcm0gZG9tIG5vZGUgZm91bmQuIGlkOiIgKyB0aGlzLmlkICsgIiwgcGFyZW50IGlkOiIrIHRoYXQuX2lkKTsKICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5yZW1vdmUoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KSA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLl9zeW5jRm9ybU5vZGVUb0h0bWwuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgICAvL3N5bmMgb3RoZXIgcHJvcHMgYmVmb3JlIGxheW91dAogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVDaGlsZCA6IGZ1bmN0aW9uKGNoaWxkRWwsIGNlbGxJbmRleCwgcHJldmlvdXNTaWJsaW5nKXsKICAgICAgICAgICAgdmFyIHZpZXcgPSB0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS5jcmVhdGVWaWV3KGNoaWxkRWwsIHsKICAgICAgICAgICAgICAgICAgICBwYXJlbnRWaWV3OiB0aGlzLAogICAgICAgICAgICAgICAgICAgIHRhYmxlQ2VsbEluZGV4IDogY2VsbEluZGV4LAogICAgICAgICAgICAgICAgICAgIHBhZ2VOdW1iZXI6IHRoaXMuX3BhZ2VOdW1iZXIoKQogICAgICAgICAgICAgICAgfSk7Ci8vICAgICAgICAgICAgaWYodGhpcy5yZXNpemFibGUgfHwgdmlldy5faXNQbGFjZUhvbGRlckVsKCkpewovLyAgICAgICAgICAgICAgICAvL1dlIGFsc28gbmVlZCB0byBjYWxsIGxheW91dENvbnRhaW5lciBmb3IgdGhlIGNhc2VzIHdoZXJlIHRoZSBvYmplY3QgaXMgaW5pdGlhbGx5IGhpZGRlbiBldmVuIGlmIHBhcmVudCBpcyBub3QgcmVzaXphYmxlCi8vICAgICAgICAgICAgICAgIC8vIHNpbmNlIHdlIGRvIG5vdCBoYXZlIGVsIGZvciBoaWRkZW4gb2JqZWN0IGFzIHlldCwuIFRPRE86IG9wdGltaXplIGl0LgovLyAgICAgICAgICAgICAgICB2aWV3Lm9uKHhmYWxpYi52aWV3LlhmYVZpZXdFdmVudC5FWFRFTlRfQ0hBTkdFICsiICIrIHdpbmRvdy54ZmFsaWIudmlldy5YZmFWaWV3RXZlbnQuUFJFU0VOQ0VfQ0hBTkdFLAovLyAgICAgICAgICAgICAgICAgICAgdGhpcy5fbGF5b3V0Q29udGFpbmVyLCB0aGlzKTsKLy8gICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKHRoaXMuJGVsLmZpbmQodmlldy4kZWwpLmxlbmd0aCA8IDEpewogICAgICAgICAgICAgICAgaWYocHJldmlvdXNTaWJsaW5nKQogICAgICAgICAgICAgICAgICAgIHByZXZpb3VzU2libGluZy4kZWwuYWZ0ZXIodmlldy4kZWwpOyAgICAgICAgLy9QdXNoIHRoZSBlbGVtZW50IGFmdGVyIHRoZSBzaWJsaW5nCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZWwucHJlcGVuZCh2aWV3LiRlbCk7ICAgICAgLy9wdXNoIHRoZSBlbGVtZW50IGF0IHRoZSBiZWdpbmluZyBvZiBwYXJlbnQgaWYgbm8gc2libGluZyBpcyBmb3VuZCxcLgogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB2aWV3OwogICAgICAgIH0sCgogICAgICAgIF92YWxpZGF0ZUxheW91dFRlbXBsYXRlIDogZnVuY3Rpb24oY2hpbGRNb2RlbCl7CiAgICAgICAgICAgIHZhciBjVGVtcGxhdGVJZCA9IGNoaWxkTW9kZWwuX3RlbXBsYXRlSWQoKTsKICAgICAgICAgICAgaWYoeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmlzVGFibGVIRihjaGlsZE1vZGVsKSl7CiAgICAgICAgICAgICAgICAvL0Egc3VwZXIgaGFjayBmb3IgIzM0Njg0MDcgdGlsbCB3ZSBzdXBwb3J0IGxlYWRlci90cmFpbGVyLiBGb3IgdGFibGUgSGVhZGVyL0Zvb3RlciwgdGVtcGxhdGVJZCB3b3VsZCBiZSB0aGlzIHNhbWUgaHRtbElkLgogICAgICAgICAgICAgICAgY1RlbXBsYXRlSWQgPSBjaGlsZE1vZGVsLmh0bWxJZDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZighdGhpcy5faXNQYWludGFibGUoY2hpbGRNb2RlbCkpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0VGVtcGxhdGUuaGFzVGVtcGxhdGUpewogICAgICAgICAgICAgICAgdmFyIHhmYVRlbXBsYXRlQ2FjaGUgPSB0aGlzLl9mb3JtRG9tUm9vdCgpLl94ZmFUZW1wbGF0ZUNhY2hlOwogICAgICAgICAgICAgICAgdmFyIGlDaGlsZEpzb24gPSB4ZmFUZW1wbGF0ZUNhY2hlLmdldEluaXRpYWxGb3JtRG9tUmVmKGNoaWxkTW9kZWwuaHRtbElkKTsgLy9maW5kIHRoZSB0MCB2ZXJzaW9uIG9mIHRoaXMgY2hpbGQKICAgICAgICAgICAgICAgIGlmKCF0aGlzLmxheW91dFRlbXBsYXRlLmhhc093blByb3BlcnR5KGNUZW1wbGF0ZUlkKSAmJiAhdGhpcy5faXNIaWRkZW4oaUNoaWxkSnNvbikpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBIZXJlIGJlY2F1c2UgdGhlIHBhZ2UgaGFzIGJlZW4gc3BsaXQgYW5kIHRoaXMgY2hpbGRNb2RlbCBpcyByZW5kZXJlZCBpbiBkaWZmZXJlbnQgcGFnZQogICAgICAgICAgICAgICAgZWxzZSBpZighdGhpcy5sYXlvdXRUZW1wbGF0ZS5oYXNPd25Qcm9wZXJ0eShjVGVtcGxhdGVJZCkgJiYgdGhpcy5faXNIaWRkZW4oaUNoaWxkSnNvbikpewogICAgICAgICAgICAgICAgICAgIC8vaWYgdGhpcyBjaGlsZCBtYXkgbm90IHByZXNlbnQgaW4gbGF5b3V0IHRlbXBsYXRlIGlmIGl0IHdhcyBoaWRkZW4gYXQgdDAgYmVjYXNlIGZvciBoaWRkZW4gY29udGFpbmVycyBsYXlvdXQgaXMgbm90IGdlbmVyYXRlZC4KICAgICAgICAgICAgICAgICAgICAvL1NvIHdlIG5lZWQgdG8gcHV0IGV4dHJhIGVmZm9ydCB0byBjaGVjayBpZiB0aGlzIGhpZGRlbiBvYmplY3QgZml0cyBsYXlvdXQgdGVtcGxhdGUgb2YgdGhpcyB2aWV3LgogICAgICAgICAgICAgICAgICAgIHZhciB2YWxpZCA9IHRoaXMuX3ZhbGlkYXRlSGlkZGVuQ2hpbGRMYXlvdXQoY2hpbGRNb2RlbCk7CiAgICAgICAgICAgICAgICAgICAgaWYodmFsaWQpewogICAgICAgICAgICAgICAgICAgICAgICAvL2lmIGZvdW5kIHZhbGlkYXRlZCwgY2FjaGUgaXQgZm9yIGZ1dHVyZS4gQWxzbyBoaWRkZW4gcGFydCBhcmUgYXV0b21hdGljYWxseSBzdGl0Y2hlZCBpbnRvIG9uZSBwYXJ0LCBzbyBoYXNMYXN0UGFydE92ZXJmbG93IHdvdWxkIGZhbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0VGVtcGxhdGVbY1RlbXBsYXRlSWRdID0ge2hhc0ZpcnN0UGFydEJlZ2luOiB0cnVlLCBoYXNMYXN0UGFydE92ZXJmbG93IDogZmFsc2V9OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsaWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKGNoaWxkTW9kZWwgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LlN1YmZvcm0gJiYKICAgICAgICAgICAgICAgICAgICAoY2hpbGRNb2RlbC5pbnN0YW5jZUluZGV4IDwgTWF0aC5mbG9vcih0aGlzLmxheW91dFRlbXBsYXRlW2NUZW1wbGF0ZUlkXS5zdGFydCkgfHwKICAgICAgICAgICAgICAgICAgICAoY2hpbGRNb2RlbC5pbnN0YW5jZUluZGV4ID4gdGhpcy5sYXlvdXRUZW1wbGF0ZVtjVGVtcGxhdGVJZF0uZW5kICYmIHRoaXMubGF5b3V0VGVtcGxhdGVbY1RlbXBsYXRlSWRdLmVuZCA+IC0xKSkpewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgICAvL1RoaXMgc3ViZm9ybSBpcyBub3QgaW4gdGhlIHJhbmdlIG9mIEluc3RhbmNlcyBoYW5kbGVkIGJ5IHRoaXMgcGFnZS4gTHlpbmcgZWl0aGVyIGluIGVhcmxpZXIgb3IgbmV4dCBwYWdlcy4KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBfdmFsaWRhdGVIaWRkZW5DaGlsZExheW91dCA6IGZ1bmN0aW9uKGNoaWxkTW9kZWwpewogICAgICAgICAgICBpZighY2hpbGRNb2RlbC5wYXJlbnQpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7ICAgICAgIC8vY2FuIGhhcHBlbiBvbmx5IGZvciByb290c3ViZm9ybXZpZXcgYXMgY2hpbGQgbW9kZWwKICAgICAgICAgICAgdmFyIHNpYmxpbmdzID0gY2hpbGRNb2RlbC5wYXJlbnQuY2hpbGRyZW47CiAgICAgICAgICAgIGlmKHNpYmxpbmdzICYmIHNpYmxpbmdzLmluZGV4T2YoY2hpbGRNb2RlbCkgPiAwKXsKICAgICAgICAgICAgICAgIHZhciBjaGlsZEluZGV4ID0gc2libGluZ3MuaW5kZXhPZihjaGlsZE1vZGVsKTsKICAgICAgICAgICAgICAgIHZhciBsYXN0UGFpbnRhYmxlU2libGluZyA9IG51bGw7CiAgICAgICAgICAgICAgICBmb3IodmFyIGxhc3RJbmRleCA9IGNoaWxkSW5kZXgtMTsgbGFzdEluZGV4ID49MDsgbGFzdEluZGV4LS0pewogICAgICAgICAgICAgICAgICAgIHZhciBsYXN0U2libGluZyA9IHNpYmxpbmdzW2xhc3RJbmRleF07CiAgICAgICAgICAgICAgICAgICAgaWYobGFzdFNpYmxpbmcgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0Lkluc3RhbmNlTWFuYWdlcil7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZVRlbXBsYXRlID0gbGFzdFNpYmxpbmcuX2luc3RhbmNlVGVtcGxhdGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRlbXBsYXRlSWQgPSB0aGlzLmdldE9yRWxzZShpbnN0YW5jZVRlbXBsYXRlLCAiZXh0cmFzLmh0bWxJZCIsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmxheW91dFRlbXBsYXRlW3RlbXBsYXRlSWRdICE9IG51bGwpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5sYXlvdXRUZW1wbGF0ZVt0ZW1wbGF0ZUlkXS5lbmQgPT0gLTEgJiYgIXRoaXMubGF5b3V0VGVtcGxhdGVbdGVtcGxhdGVJZF0uaGFzTGFzdFBhcnRPdmVyZmxvdyl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9MYXN0IGxheW91dCBwYXJ0IG9mIGxhc3QgaW5zdGFuY2Ugb2YgdGhpcyBJTSB3YXMgaGVyZSBhdCB0MC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1NvIGhpZGRlbiBvYmplY3Qgc2hvdWxkIGNvbWUgb24gdGhpcyBwYWdlLiBFbHNlIG9uIGFub3RoZXIgcGFnZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7ICAgLy9JTSBvZiB0aGlzIGhpZGRlbiBzZj8uCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoIXRoaXMuX2lzUGFpbnRhYmxlKGxhc3RTaWJsaW5nKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgICAgICAgICBsYXN0UGFpbnRhYmxlU2libGluZyA9IGxhc3RTaWJsaW5nOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZighbGFzdFBhaW50YWJsZVNpYmxpbmcpewogICAgICAgICAgICAgICAgICAgIC8vVGhpcyBoaWRkZW4gY2hpbGQgbW9kZWwgaXMgZmlyc3QgcGFpbnRhYmxlIGNoaWxkIG9mIHRoaXMuIElmIHRoaXMgbGF5b3V0IGVsZW1lbnQgaXMgZmlyc3QgcGFydCBvZiB0aGlzIG1vZGVsIGxheW91dAogICAgICAgICAgICAgICAgICAgIC8vIFRoZW4gaGlkZGVuIGNoaWxkIHNob3VsZCBiZSBwYWludGVkIGluIHRoaXMgcGFnZS92aWV3LiBFbHNlIGluIG90aGVyIHZpZXcuCiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5nZXRPckVsc2UodGhpcy5sYXlvdXRNb2RlbCwgIm9jY3VySW5kZXgiLCAwKSA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vRWxzZSBpZiAqbGFzdCBwYXJ0IG9mIGxhc3QgcGFpbnRhYmxlIHNpYmxpbmcqIG9mIHRoaXMgaGlkZGVuIG5vZGUgYmVsb25nIHRvIHRoaXMgbGF5b3V0IHRlbXBsYXRlIHRoZW4gdGhpcyBoaWRkZW4gbm9kZSB3b3VsZCBhbHNvIGJlbG9uZyBoZXJlLgogICAgICAgICAgICAgICAgICAgIHZhciBsYXN0U2libGluZ1ZhbGlkID0gdGhpcy5fdmFsaWRhdGVMYXlvdXRUZW1wbGF0ZShsYXN0UGFpbnRhYmxlU2libGluZyk7CiAgICAgICAgICAgICAgICAgICAgaWYobGFzdFNpYmxpbmdWYWxpZCl7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsYXN0U2libGluZ1RlbXBsYXRlSWQgPSBsYXN0UGFpbnRhYmxlU2libGluZy5fdGVtcGxhdGVJZCgpOwogICAgICAgICAgICAgICAgICAgICAgICBpZighdGhpcy5sYXlvdXRUZW1wbGF0ZVtsYXN0U2libGluZ1RlbXBsYXRlSWRdLmhhc0xhc3RQYXJ0T3ZlcmZsb3cpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRXZlbnQ6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgc3dpdGNoKGV2bnQubmFtZSkgewogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuQ0hJTERfQURERUQ6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVDaGlsZEFkZGVkKGV2bnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuQ0hJTERfUkVNT1ZFRDoKICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZUNoaWxkUmVtb3ZlZChldm50KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkNISUxEX01PVkVEOgogICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlQ2hpbGRNb3ZlZChldm50KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLmhhbmRsZUV2ZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYW5kbGVEb21DaGFuZ2VkIDpmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgIHN3aXRjaChldmVudC5fcHJvcGVydHkpIHsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLmhhbmRsZURvbUNoYW5nZWQuYXBwbHkodGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGhhbmRsZU1vZGVsQ2hhbmdlZCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmIChldmVudC5fcHJvcGVydHkgPT0gImZpbGxDb2xvciIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2ZpbGxDb2xvcihldmVudC5uZXdUZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChldmVudC5fcHJvcGVydHkgPT0gImJvcmRlckNvbG9yIikgewogICAgICAgICAgICAgICAgdGhpcy5fYm9yZGVyQ29sb3IoZXZlbnQubmV3VGV4dCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyplbHNlIGlmIChldmVudC5fcHJvcGVydHkgPT0gImJvcmRlcldpZHRoIikgewogICAgICAgICAgICAgICAgdGhpcy5fYm9yZGVyV2lkdGgoZXZlbnQubmV3VGV4dCk7CiAgICAgICAgICAgIH0gICAgICovCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5oYW5kbGVNb2RlbENoYW5nZWQuYXBwbHkodGhpcywKICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIC8qX2JvcmRlcldpZHRoIDogZnVuY3Rpb24od2lkdGgpIHsKICAgICAgICAgICAgJCh0aGlzLmVsKS5jc3MoImJvcmRlcldpZHRoIiwgd2lkdGgpCiAgICAgICAgfSwgICAgICAgICAgKi8KCiAgICAgICAgaGFuZGxlQ2hpbGRBZGRlZCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciBhZGRlZENoaWxkICA9IGV2ZW50Lm5ld1RleHQ7CiAgICAgICAgICAgIHZhciBjaGlsZFRlbXBsYXRlSWQgPSBhZGRlZENoaWxkLl90ZW1wbGF0ZUlkKCk7CiAgICAgICAgICAgIGlmKCF0aGlzLmxheW91dFRlbXBsYXRlLmhhc1RlbXBsYXRlIHx8ICh0aGlzLmxheW91dFRlbXBsYXRlLmhhc093blByb3BlcnR5KGNoaWxkVGVtcGxhdGVJZCkgJiYgYWRkZWRDaGlsZC5pbnN0YW5jZUluZGV4ID49ICB0aGlzLmxheW91dFRlbXBsYXRlW2NoaWxkVGVtcGxhdGVJZF0uc3RhcnQgJiYKICAgICAgICAgICAgICAgICh0aGlzLmxheW91dFRlbXBsYXRlW2NoaWxkVGVtcGxhdGVJZF0uZW5kIDwgMCB8fCBhZGRlZENoaWxkLmluc3RhbmNlSW5kZXggPD0gdGhpcy5sYXlvdXRUZW1wbGF0ZVtjaGlsZFRlbXBsYXRlSWRdLmVuZCkpKXsKICAgICAgICAgICAgICAgIC8vSWYgYWRkZWQgY2hpbGQgcmVzaWRlcyBpbiB0aGUgcmFuZ2Ugc3VwcG9ydGVkIGJ5IHRoaXMgdmlldywgc3luYyBpdC4KICAgICAgICAgICAgICAgIHRoaXMuX3N5bmNGb3JtTm9kZVRvSHRtbChmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5kZWJ1ZyggInhmYVZpZXciLCJUaGlzIGluc3RhbmNlTWFuYWdlciBoYXMgbm8gY2hpbGQgaW4gdGhpcyBsYXlvdXQgdGVtcGxhdGUuIFRoaXMgd291bGQgYmUgaGFuZGxlZCBpbiBvdGhlciBwYXJ0IG9mIHNwbGl0dGVkIHN1YmZvcm0uIGVsIGlkOiIrdGhpcy5faWQpOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUNoaWxkTW92ZWQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICB0aGlzLl9zeW5jRm9ybU5vZGVUb0h0bWwodHJ1ZSk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlQ2hpbGRSZW1vdmVkIDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgdmFyIHJlbW92ZWRDaGlsZCA9IGV2ZW50LnByZXZUZXh0OwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBOb3RlL0hhY2s6IFRvIGdldCB0aGUgdGVtcGxhdGVJZCBvZiByZW1vdmVkQ2hpbGQsIHdlIGNhbiBub3Qgc2ltcGx5IGFzayBjaGlsZC5fdGVtcGxhdGVJZCgpIGFzIHRoaXMgd291bGQgcmV0dXJuIHRlbXBsYXRlIElkIG9mIG9ubHkgdGhvc2UKICAgICAgICAgICAgICAqIG5vZGVzIHdoaWNoIGFyZSBzdGlsbCBjb25uZWN0ZWQgdG8geGZhIGRvbS4gU2luY2UgcmVtb3ZlIGNoaWxkIGlzIGRpc2Nvbm5lY3RlZCBmcm9tIHhmYSwgd2UgYXJlIGFza2luZyB0ZW1wbGF0ZSBJZCBvZiB0aGlzIGZyb20gaXQncyBpbnN0YW5jZU1hbmFnZQogICAgICAgICAgICAgICogd2hpY2ggaXMgc3RpbGwgdGhlcmUuIEEgd29ya2Fyb3VuZCBmb3Igbm93LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdmFyIGNoaWxkVGVtcGxhdGVJZCA9IHJlbW92ZWRDaGlsZC5pbnN0YW5jZU1hbmFnZXIuX2luc3RhbmNlVGVtcGxhdGUoKS5leHRyYXMuaHRtbElkOwogICAgICAgICAgICBpZighdGhpcy5sYXlvdXRUZW1wbGF0ZS5oYXNUZW1wbGF0ZSB8fCAodGhpcy5sYXlvdXRUZW1wbGF0ZS5oYXNPd25Qcm9wZXJ0eShjaGlsZFRlbXBsYXRlSWQpICYmCiAgICAgICAgICAgICAgICAodGhpcy5sYXlvdXRUZW1wbGF0ZVtjaGlsZFRlbXBsYXRlSWRdLmVuZCA8IDAgfHwgcmVtb3ZlZENoaWxkLmluc3RhbmNlSW5kZXggPD0gdGhpcy5sYXlvdXRUZW1wbGF0ZVtjaGlsZFRlbXBsYXRlSWRdLmVuZCkpKXsKICAgICAgICAgICAgICAgIC8vSWYgdGhlIHJlbW92ZWQgY2hpbGQgaGFzIGluc3RhbmNlSW5kZXggbGVzcyB0aGFuIHRoZSBlbmQgcmFuZ2UgdGhlbiB0aGVyZSBpcyBwb3RlbnRpYWwgZm9yIHJlbGF5b3V0IG9mIHRoaXMgcGFnZS4gU28gc3luIGl0LgogICAgICAgICAgICAgICAgdGhpcy5fc3luY0Zvcm1Ob2RlVG9IdG1sKGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmRlYnVnKCAieGZhVmlldyIsIlRoaXMgaW5zdGFuY2VNYW5hZ2VyIGhhcyBubyBjaGlsZCBpbiB0aGlzIGxheW91dCB0ZW1wbGF0ZS4gVGhpcyB3b3VsZCBiZSBoYW5kbGVkIGluIG90aGVyIHBhcnQgb2Ygc3BsaXR0ZWQgc3ViZm9ybS4gZWwgaWQ6Iit0aGlzLl9pZCk7CiAgICAgICAgfSwKCiAgICAgICAgZGVzdHJveSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgLy9UT0RPOiBJbXBsZW1lbnQgYW5kIGNhbGwgZGVzdHJveSBtZXRob2QKICAgICAgICB9LAoKICAgICAgICBfaXNBbm9ueW1vdXMgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIF9ub3JtYWxpemVkQ2hpbGRWaWV3cyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgbm9ybWFsaXplZENoaWxkVmlld3MgPSBbXTsKICAgICAgICAgICAgXy5mb2xkbCh0aGlzLmNoaWxkVmlld3MsIGZ1bmN0aW9uKG1lbW8sIGNoaWxkVmlldywgaW5kZXgpewogICAgICAgICAgICAgICAgaWYoY2hpbGRWaWV3IGluc3RhbmNlb2YgeGZhbGliLnZpZXcuQ29udGFpbmVyVmlldyAmJiBjaGlsZFZpZXcuX2lzQW5vbnltb3VzKCkpewogICAgICAgICAgICAgICAgICAgIF8uZWFjaChjaGlsZFZpZXcuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uKG5vcm1hbGl6ZWRDaGlsZCl7CiAgICAgICAgICAgICAgICAgICAgICAgIG1lbW8ucHVzaChub3JtYWxpemVkQ2hpbGQpOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZighdGhpcy5faXNIaWRkZW4oY2hpbGRWaWV3Lm1vZGVsKSl7CiAgICAgICAgICAgICAgICAgICAgbWVtby5wdXNoKGNoaWxkVmlldyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gbWVtbzsKICAgICAgICAgICAgfSwgbm9ybWFsaXplZENoaWxkVmlld3MsIHRoaXMpOwogICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplZENoaWxkVmlld3M7CiAgICAgICAgfSwKCiAgICAgICAgX2lzSGlkZGVuIDogZnVuY3Rpb24obW9kZWwpewogICAgICAgICAgICAvL21vZGVsIGNhbiBiZSBhIE5vZGUgb2JqZWN0IG9yIHNpbXBseSBhIGpzb24KICAgICAgICAgICAgaWYobW9kZWwgJiYgKG1vZGVsLnByZXNlbmNlID09ICJoaWRkZW4iIHx8IG1vZGVsLnByZXNlbmNlID09ICJpbmFjdGl2ZSIpKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfaXNQYWludGFibGUgOiBmdW5jdGlvbihtb2RlbCl7CiAgICAgICAgICAgIC8vY2FuIHRoaXMgbW9kZWwgaGF2ZSB2aXN1YWwgcmVwcmVzZW50YXRpb24KICAgICAgICAgICAgaWYobW9kZWwgJiYgbW9kZWwuaXNDb250YWluZXIgJiYgbW9kZWwuY2xhc3NOYW1lICE9ICJ2YXJpYWJsZXMiKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBtZWFzdXJlU2l6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0KQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0Lm1lYXN1cmVTaXplKCk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBpbnZhbGlkYXRlU2l6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0KQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0LmludmFsaWRhdGVTaXplKCk7CiAgICAgICAgfSwKCiAgICAgICAgdXBkYXRlRGlzcGxheSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0KQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0LnVwZGF0ZURpc3BsYXkoKTsKICAgICAgICB9LAoKICAgICAgICAkZWxjaGlsZHJlbiA6IGZ1bmN0aW9uKGlkKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLiRlbC5jaGlsZHJlbihpZCk7CiAgICAgICAgfQoKCiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICAvL0ludGVybWVkaWF0ZSBoaWVyYXJjaHkgdG8gZXh0cmFjdCBvdXQgY29tbW9uIGNvZGUgZm9yIFBhZ2VWaWV3L0NvbnRlbnRBcmVhVmlldy9Sb290U3ViZm9ybVZpZXcKICAgIHhmYWxpYi52aWV3LkxheW91dENvbnRhaW5lclZpZXcgPSB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3LmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHRoaXMuZ3Jvd2FibGVWaWV3ID0gW107IC8vIEVsZW1lbnQgdGhhdCBjYW4gZ3JvdyBiZXlvbmQgYm91bmRhcnkuIEN1cnJlbnQgYXNzdW1wdGlvbiBpcyB0aGF0IHRoZXJlIGNhbiBiZSBvbmx5IG9uZSBzdWNoIGVsZW1lbnQgaW4gQ29udGVudEFyZWEvUGFnZUFyZWEKICAgICAgICAgICAgeGZhbGliLnZpZXcuQ29udGFpbmVyVmlldy5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIF9zeW5jRm9ybU5vZGVUb0h0bWw6IGZ1bmN0aW9uKGRlZXBTeW5jKXsKICAgICAgICAgICAgaWYodGhpcy5jaGlsZFZpZXdzID09IG51bGwgfHwgdGhpcy5jaGlsZFZpZXdzLmxlbmd0aCA9PSAwKXsKICAgICAgICAgICAgICAgIHRoaXMuY2hpbGRWaWV3cyA9IFtdOwogICAgICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICAgICAgdmFyIGNlbGxJbmRleCA9IDA7CiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuJGVsLmlzKCI6ZW1wdHkiKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuY2hpbGRWaWV3cyA9IHRoaXMuJGVsLmNoaWxkcmVuKCkubWFwKGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRWaWV3ID0gdGhhdC5feGZhVmlld1JlZ2lzdHJ5KCkuY3JlYXRlVmlldyh0aGlzLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRWaWV3OiB0aGF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVDZWxsSW5kZXggOiBjZWxsSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTnVtYmVyOiB0aGF0Ll9wYWdlTnVtYmVyKCkKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGxJbmRleCA9IGNlbGxJbmRleCArIChjaGlsZFZpZXcubGF5b3V0TW9kZWwuY29sc3BhbiB8fCAxKTsgLy9BZGQgdGhlIGNvbHNwYW4gb3Igb25lCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoYXQuX2lzR3Jvd2FibGVWaWV3KGNoaWxkVmlldykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZ3Jvd2FibGVWaWV3LnB1c2goY2hpbGRWaWV3KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGRWaWV3OwogICAgICAgICAgICAgICAgICAgIH0pLmdldCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgXy5lYWNoKHRoaXMuY2hpbGRWaWV3cywgZnVuY3Rpb24oY2hpbGRWaWV3KXsKICAgICAgICAgICAgICAgICAgICBjaGlsZFZpZXcuc3luY0Zvcm1Ob2RlVG9IdG1sKGRlZXBTeW5jKTsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5fc3luY0Zvcm1Ob2RlVG9IdG1sLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7ICAgLy9zeW5jIG90aGVyIHByb3BzIGJlZm9yZSBsYXlwdXQKICAgICAgICB9LAoKICAgICAgICBfaXNHcm93YWJsZVZpZXcgOmZ1bmN0aW9uKGNoaWxkVmlldyl7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfZm9yY2VWaWV3OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgLy90aGlzIGZ1bmN0aW9uIGlzIHRvIGRpY3RhdGUgd2hldGhlciB0aGUgdmlldyBpcyBmb3JjZWQKICAgICAgICAgICAgLy93aWxsIGJlIHVzZWQgdG8gZm9yY2UgdGhlIHJlbmRlciBvZiBmaXJzdCBwYWdlIGF0IGxlYXN0LgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwoKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB2YXIgU3ViZm9ybVZpZXcgPSB4ZmFsaWIudmlldy5TdWJmb3JtVmlldyA9IHhmYWxpYi52aWV3LkNvbnRhaW5lclZpZXcuZXh0ZW5kKHsKCiAgICAgICAgX2Fzc2lnblRvb2xUaXA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHRvb2xUaXBUZXh0ID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLl9nZXRUb29sVGlwVGV4dCh0aGlzLm1vZGVsKTsKICAgICAgICAgICAgLy8gQ1EtNDIyMjk4MSA6IGFzc2lnbiB0b29sdGlwIGZvciBzdWJmb3JtIGhhdmluZyByb2xlIGFzIHRhYmxlIG9yIGl0IGlzIHRhYmxlCiAgICAgICAgICAgIGlmICh0b29sVGlwVGV4dCAmJiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuX3RhYmxlQ2hlY2tGb3JBY2Nlc3NpYmlsaXR5KHRoaXMpKSB7CiAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJ0aXRsZSIsIHRvb2xUaXBUZXh0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKCiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoU3ViZm9ybVZpZXcucHJvdG90eXBlLCAicmVzaXphYmxlIiwgewogICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMuX3Jlc2l6YWJsZSkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB2YXIgbGF5b3V0ID0gdGhpcy5sYXlvdXRNb2RlbC5sYXlvdXQ7CiAgICAgICAgICAgIGlmKGxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfTEVGVFJJR0hUVE9QQk9UVE9NIHx8IGxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUklHSFRMRUZUVE9QQk9UVE9NIHx8IGxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfVE9QQk9UVE9NKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBzZXQgOiBmdW5jdGlvbihzVmFsdWUpewogICAgICAgICAgICB0aGlzLl9yZXNpemFibGUgPSBzVmFsdWU7CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCAkLCB4ZmFsaWIpOyhmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgdmFyIFN1YmZvcm1TZXRWaWV3ID0geGZhbGliLnZpZXcuU3ViZm9ybVNldFZpZXcgPSB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3LmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3LnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfSwKCiAgICAgICAgX2lzQW5vbnltb3VzIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0sCgogICAgICAgICRjb21wdXRlV0ggOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgZXh0ZW50ID0ge307CiAgICAgICAgICAgIHJldHVybiBleHRlbnQ7CiAgICAgICAgfSwKCiAgICAgICAgX2NvbXB1dGVFeHRlbnQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgLy9tYXJrIHRoZSBwb3NpdGlvbiBvZiB0aGUgc3ViZm9ybXNldCBhcyB0cmFuc3BhcmVudAogICAgICAgICAgICB2YXIgZXh0ZW50ID0geGZhbGliLnZpZXcuQ29udGFpbmVyVmlldy5wcm90b3R5cGUuX2NvbXB1dGVFeHRlbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgZXh0ZW50Wydwb3NpdGlvbiddID0gJ3N0YXRpYyc7CiAgICAgICAgICAgIHJldHVybiBleHRlbnQKICAgICAgICB9CiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsoZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LkNvbnRlbnRBcmVhVmlldyA9IHhmYWxpYi52aWV3LkxheW91dENvbnRhaW5lclZpZXcuZXh0ZW5kKHsKICAgICAgICBfaXNHcm93YWJsZVZpZXcgOmZ1bmN0aW9uKGNoaWxkVmlldyl7CiAgICAgICAgICAgIHJldHVybiAoY2hpbGRWaWV3Lm1vZGVsID09PSB0aGlzLl9mb3JtRG9tUm9vdCgpLmZvcm0uY2hpbGRyZW5bMF0pOyAvLyBJcyByb290IHN1YmZvcm0gb2YgdGhlIGZvcm0gZG9tCiAgICAgICAgfSwKCiAgICAgICAgX2luaXRpYWxpemVMYXlvdXRNb2RlbCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkxheW91dENvbnRhaW5lclZpZXcucHJvdG90eXBlLl9pbml0aWFsaXplTGF5b3V0TW9kZWwuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgLy9TcGVjaWFsIGhhbmRsaW5nIGZvciBlbmFibGluZyBzaHJpbmsgcGFnZSBmdW5jdGlvbmFsaXR5LiBXZSdsbCB0cmVhdCBjb250ZW50QXJlYSBhcyBUb3BCb3R0b24gZmxvd2FibGUgc3ViZm9ybS5CdWcjMzYwODc3MwogICAgICAgICAgICB0aGlzLmxheW91dE1vZGVsLmV4dGVudGFjdHVhbGggPSAtMTsKICAgICAgICAgICAgdGhpcy5yZXNpemFibGUgPSB0cnVlOwogICAgICAgIH0KCiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy5QYWdlVmlldyA9IHhmYWxpYi52aWV3LkxheW91dENvbnRhaW5lclZpZXcuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB4ZmFsaWIudmlldy5MYXlvdXRDb250YWluZXJWaWV3LnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIC8qIEZsYWcgaW5kaWNhdGluZyB0aGF0IHRoZSB0YWJiaW5nIGNvbXB1dGF0aW9uIGZvciB0aGlzIFBhZ2Ugd291bGQgYmUgcmVkb25lICovCiAgICAgICAgICAgIHRoaXMuX3RhYkNvbXB1dGVQZW5kaW5nID0gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRMYXlvdXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5MYXlvdXRDb250YWluZXJWaWV3LnByb3RvdHlwZS5faW5pdExheW91dC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICBpZih0aGlzLl9pbml0aWFsaXplZCl7CiAgICAgICAgICAgICAgICAvKiBXaGVuIGEgUGFnZSBWaWV3IGlzIGluaXRpYWxpemVkLCBpbW1lZGlhdGVseSBtYXJrIGl0IGZvciB0YWIgY29tcHV0ZSovCiAgICAgICAgICAgICAgICB0aGlzLmludmFsaWRhdGVUYWJJbmRleCgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2ZvcmNlVmlldzogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIC8vdGhpcyBmdW5jdGlvbiBpcyB0byBkaWN0YXRlIHdoZXRoZXIgdGhlIHZpZXcgaXMgZm9yY2VkCiAgICAgICAgICAgIC8vd2lsbCBiZSB1c2VkIHRvIGZvcmNlIHRoZSByZW5kZXIgb2YgZmlyc3QgcGFnZSBhdCBsZWFzdC4KICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhZ2VOdW1iZXIoKSA9PSAxOwogICAgICAgIH0sCgogICAgICAgIF9pc0dyb3dhYmxlVmlldyA6ZnVuY3Rpb24oY2hpbGRWaWV3KXsKICAgICAgICAgICAgcmV0dXJuIChjaGlsZFZpZXcgaW5zdGFuY2VvZiB4ZmFsaWIudmlldy5Db250ZW50QXJlYVZpZXcpOwogICAgICAgIH0sCgogICAgICAgIF9wYWdlTnVtYmVyIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgLyogUmV0dXJuIHRoZSBwYWdlIG51bWJlciB0aGF0IHdhcyBzZW50IGZyb20gc2VydmVyLiBQYWdlIE51bWJlciBzdGFydHMgd2l0aCAxLiovCiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0TW9kZWwpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0TW9kZWwucGFnZU51bWJlcjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSwKCiAgICAgICAgX2NvbXB1dGVFeHRlbnQgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgZXh0ZW50ID0geGZhbGliLnZpZXcuTGF5b3V0Q29udGFpbmVyVmlldy5wcm90b3R5cGUuX2NvbXB1dGVFeHRlbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgZXh0ZW50WyJwb3NpdGlvbiJdID0gInJlbGF0aXZlIjsKICAgICAgICAgICAgZXh0ZW50WyJtYXJnaW4tbGVmdCJdID0gImF1dG8iOyAgICAgICAgICAgICAgIC8vV2UgbmVlZCB0byBtYXJrIHBhZ2UgbWFyZ2lucyB0byBhdXRvIHRvIGFkanVzdCBwYWdlcyB3aXRoIGRpZmZlcmVudCBtYXN0ZXIgcGFnZSBsYXlvdXQKICAgICAgICAgICAgZXh0ZW50WyJtYXJnaW4tcmlnaHQiXSA9ICJhdXRvIjsKICAgICAgICAgICAgZXh0ZW50WyJtYXJnaW4tYm90dG9tIl0gPSAxMDsKICAgICAgICAgICAgZXh0ZW50WyJtYXJnaW4tdG9wIl0gPSB0aGlzLl9wYWdlTnVtYmVyKCkgPT0gMSA/IDAgOiAxMCA7CiAgICAgICAgICAgIHJldHVybiBleHRlbnQ7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBNYXJrcy9RdWV1ZXMgdGhlIFBhZ2UgZm9yIHJlLWNvbXB1dGUgb2YgdGFiIGluZGV4ZXMuIFJlLWNvbXB1dGF0aW9uIHdvdWxkIGF1dG9tYXRpY2FsbHkgYmUgZmlyZWQKICAgICAgICAgKiBhc3luY2hyb25vdXNseS4KICAgICAgICAgKi8KICAgICAgICBpbnZhbGlkYXRlVGFiSW5kZXggOiBmdW5jdGlvbihmb3JjZUNvbXB1dGUpIHsKICAgICAgICAgICAgaWYoIXRoaXMuX3RhYkNvbXB1dGVQZW5kaW5nIHx8IGZvcmNlQ29tcHV0ZSl7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogVGFiIGNvbXB1dGUgaW52YWxpZGF0aW9uIHNldHMgdGhlIHRhYkNvbXB1dGVQZW5kaW5nIGZsYWcgdG8gdHJ1ZSBhbmQgdGhlbiBmaXJlcyBhY3R1YWwgY29tcHV0YXRpb24gYXN5bmMKICAgICAgICAgICAgICAgICAqIHdheSBpbi1vcmRlciBmb3IgY2FzZXMgd2hlcmUgc2ltdWx0YW5lb3VzIGluLXZhbGlkYXRpb25zIG1heSBvY2N1ciBtdWx0aXBsZSB0aW1lcyBmb3IgZGlmZmVyZW50CiAgICAgICAgICAgICAgICAgKiBmaWVsZHMgb3IgcmVwZWF0YWJsZSBzdWJmb3JtIG9mIHRoZSBzYW1lIHBhZ2UuIEluIHRob3NlIGNhc2VzLCB3ZSB3YW50IHRvIGNvbXB1dGUgdGFiIGluZGV4ZXMgb25seSBvbmNlIHdoZW4KICAgICAgICAgICAgICAgICAqIGV2ZXJ5dGhpbmcgaXMgZG9uZS4KICAgICAgICAgICAgICAgICAqIEFub3RoZXIgdGhpbmcsIGlmIHRoZXJlIGlzIGFueSBsYXlvdXQgY29tcHV0YXRpb24gcGVuZGluZyBpbiBsYXlvdXQgbWFuYWdlciwgd2UgZGVmZXIgdGhlIHRhYiBjb21wdXRhdGlvbiB0aWxsCiAgICAgICAgICAgICAgICAgKiB0aGF0IGlzIGNvbXBsZXRlIHNpbmNlIHgseSBjYW4gY2hhbmdlIGluIHRob3NlIGNhc2VzLgogICAgICAgICAgICAgICAgICoqLwogICAgICAgICAgICAgICAgdGhpcy5fdGFiQ29tcHV0ZVBlbmRpbmcgPSB0cnVlOwogICAgICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmNsZWFyVGltZW91dE9uRGVzdHJveSgKICAgICAgICAgICAgICAgICAgICB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpewogICAgICAgICAgICAgICAgICAgICAgICBpZighdGhhdC5fbGF5b3V0TWFuYWdlci5pc0xheW91dEN5Y2xlQ29tcGxldGUoKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2xheW91dCBjeWNsZSBydW5uaW5nIHNvIGRvIGEgZm9yY2UgaW52YWxpZGF0aW9uIHRvIGRlZmVyIHRhYiBjb21wdXRhdGlvbiB0byBuZXh0IGN5Y2xlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmludmFsaWRhdGVUYWJJbmRleCh0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fY29tcHV0ZVRhYkluZGV4KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9LCAxKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlVGFiSW5kZXggOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuX3RhYkNvbXB1dGVQZW5kaW5nID0gZmFsc2U7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LnV0aWwudHJhdmVyc2FsTWFuYWdlci5fY29tcHV0VGFiSW5kZXgodGhpcyk7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sICQsIHhmYWxpYikgewogICAgeGZhbGliLnZpZXcuUm9vdFN1YmZvcm1WaWV3ID0geGZhbGliLnZpZXcuTGF5b3V0Q29udGFpbmVyVmlldy5leHRlbmQoewogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHBhZ2luZ0NvbmZpZyA9IHRoaXMuX3hmYVZpZXdSZWdpc3RyeSgpLnBhZ2luZ0NvbmZpZygpOwogICAgICAgICAgICB0aGlzLiRlbCA9ICh0aGlzLm9wdGlvbnMuZWwgaW5zdGFuY2VvZiAkKSA/IHRoaXMub3B0aW9ucy5lbCA6ICQodGhpcy5vcHRpb25zLmVsKTsKICAgICAgICAgICAgLy9tYWtlIHBhZ2luZyBkZWZhdWx0CiAgICAgICAgICAgIGlmIChwYWdpbmdDb25maWcucGFnaW5nRGlzYWJsZWQpIHsKICAgICAgICAgICAgICAgIF8uZWFjaCh0aGlzLm9wdGlvbnMucmVzdE9mVGhlUGFnZXMsIGZ1bmN0aW9uIChwYWdlRWwpIHsKICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmVkIGNyZWF0aW9uIG9mIGV4dHJhIHBhZ2UgdmlldyBhcyBjaGlsZFZpZXcsIG9uIGNvbnRhaW5lclZpZXcgaW5pdGlhbGl6ZSB3ZSBhbnl3YXlzIGluaXRpYWxpemUgY2hpbGRWaWV3IGFzIGVtcHR5IGFycmF5CiAgICAgICAgICAgICAgICAgICAgLy8gb24gc3luY0Zvcm1Ob2RlVG9IdG1sIHdlIGFyZSB1c2luZyAkZWwuY2hpbGRyZW4oKSB0byBjcmVhdGUgbmV3IGNoaWxkIHZpZXdzCiAgICAgICAgICAgICAgICAgICAgLy8gc28ganVzdCBhcHBlbmRpbmcgcmVzdCBvZiB0aGUgcGFnZXMgZWxlbWVudCBzaG91bGQgYmUgZW5vdWdoCiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZWwuYXBwZW5kKHBhZ2VFbCk7CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5vcHRpb25zICYmIHRoaXMub3B0aW9ucy5yZXN0T2ZUaGVQYWdlcykgewogICAgICAgICAgICAgICAgLy9kbyBub3RoaW5nLCBqdXN0IG1hcmsgcmVzdCBvZiB0aGUgcGFnZXMgYXMgZGVmZXJyZWQgcGFnZXMKICAgICAgICAgICAgICAgIHRoaXMuX2RlZmVycmVkUGFnZXMgPSB0aGlzLm9wdGlvbnMucmVzdE9mVGhlUGFnZXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMudG90UGFnZXMgPSB0aGlzLmdldE9yRWxzZSh0aGlzLCAib3B0aW9ucy5yZXN0T2ZUaGVQYWdlcy5sZW5ndGgiLCAwKSArIDE7ICAvLyB0b2RvOiBmaXggdGhpcyB3aGVuIGluaXRpYWwgY291bnQgaXMgcHJlc2VudAovLyAgICAgICAgICAgIGNvbnNvbGUucHJvZmlsZSgiUDEiKTsKICAgICAgICAgICAgeGZhbGliLnZpZXcuTGF5b3V0Q29udGFpbmVyVmlldy5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwovLyAgICAgICAgICAgIGNvbnNvbGUucHJvZmlsZUVuZCgpOwoKICAgICAgICAgICAgLy9CdWcjMzY3MDM3MzogYSBjdXN0b20gZXZlbnQgaXMgdHJpZ2dlcmVkIGFmdGVyIHRoZSBmaXJzdCBwYWdlIGlzIGxvYWRlZC4KICAgICAgICAgICAgdmFyIF90cmlnZ2VyWGZhRmlyc3RQZ0xheW91dENvbXBsZXRlID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhpcy5jaGlsZFZpZXdzWzBdLm9mZignbGF5b3V0Q29tcGxldGUnLCBfdHJpZ2dlclhmYUZpcnN0UGdMYXlvdXRDb21wbGV0ZSk7CiAgICAgICAgICAgICAgICAkKHdpbmRvdykudHJpZ2dlcigneGZhRmlyc3RQZ0xheW91dENvbXBsZXRlJyk7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS5zY2FsZUZvcm0oKTsKICAgICAgICAgICAgfTsKICAgICAgICAgICAgdGhpcy5jaGlsZFZpZXdzWzBdLm9uKCdsYXlvdXRDb21wbGV0ZScsIF90cmlnZ2VyWGZhRmlyc3RQZ0xheW91dENvbXBsZXRlLCB0aGlzKTsKCiAgICAgICAgICAgIC8vYWNjZXNzaWJpbGl0eQogICAgICAgICAgICAvL2FkZCBmb3JtIHJvbGUgdG8gcm9vdFN1YmZvcm1WaWV3CiAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvbGUiLCAiZm9ybSIpOwoKICAgICAgICAgICAgLy9hbHNvIGFkZCBsYW5nIGF0dHJpYnV0ZSBpbiBpdAogICAgICAgICAgICAvL2xlYXAgb2YgZmFpdGggLS0gZ2V0dGluZyB0aGUgcm9vdHN1YmZvcm0gb2YgdGhlIGZvcm0gbW9kZWwgYW5kIHRoZW4gc2V0IHRoZSBsYW5nIGF0dHJpYnV0ZQogICAgICAgICAgICBpZiAoeGZhbGliLnJ1bnRpbWUuZm9ybS5jaGlsZHJlblswXSAmJiB4ZmFsaWIucnVudGltZS5mb3JtLmNoaWxkcmVuWzBdLmpzb25Nb2RlbCAmJiB4ZmFsaWIucnVudGltZS5mb3JtLmNoaWxkcmVuWzBdLmxvY2FsZSkgewogICAgICAgICAgICAgICAgLy9hZGQgbGFuZyBwYXJhbWV0ZXIKICAgICAgICAgICAgICAgIHZhciBsYW5nID0gdGhpcy5fbGFuZ0Zyb21Mb2NhbGUoeGZhbGliLnJ1bnRpbWUuZm9ybS5jaGlsZHJlblswXS5sb2NhbGUpOwoKICAgICAgICAgICAgICAgIGlmIChsYW5nICYmIGxhbmcubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoImxhbmciLCBsYW5nKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUV4dGVudDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4ge307CiAgICAgICAgfSwKCiAgICAgICAgcmVuZGVyRGVmZXJyZWRQYWdlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vYXNzZXJ0KHVzZXJDb25maWcgJiYgdXNlckNvbmZpZy5wYWdpbmdDb25maWcgJiYgdXNlckNvbmZpZy5wYWdpbmdDb25maWcucGFnaW5nRW5hYmxlZCk7CiAgICAgICAgICAgIGlmICh0aGlzLmhhc01vcmVEZWZlcnJlZFBhZ2VzKCkpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2p1c3QgbWFrZSBzdXJlIHdlIGhhdmUgbW9yZSB0aGFuIDEwIGJ5dGVzCiAgICAgICAgICAgICAgICAvL2NyZWF0ZSBkb20gaGVyZQogICAgICAgICAgICAgICAgdmFyIG5leHRQYWdlRWwgPSAkKHRoaXMuX2RlZmVycmVkUGFnZXMuc2hpZnQoKSk7CiAgICAgICAgICAgICAgICB2YXIgbmV4dFBhZ2VWaWV3ID0gdGhpcy5feGZhVmlld1JlZ2lzdHJ5KCkuY3JlYXRlVmlldyhuZXh0UGFnZUVsLCB7cGFyZW50VmlldzogdGhpc30pOwogICAgICAgICAgICAgICAgdGhpcy4kZWwuYXBwZW5kKG5leHRQYWdlRWwpOwogICAgICAgICAgICAgICAgdGhpcy5jaGlsZFZpZXdzID0gdGhpcy5jaGlsZFZpZXdzIHx8IFtdOwogICAgICAgICAgICAgICAgdGhpcy5jaGlsZFZpZXdzLnB1c2gobmV4dFBhZ2VWaWV3KTsKICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5fdHJpZ2dlck9uQnJpZGdlKCJlbGVtZW50UGFnZVJlbmRlcmVkIiwgeGZhbGliLnJ1bnRpbWUueGZhLmZvcm0uZm9ybTEsICJuZXh0UGFnZSIsIHRoaXMuY2hpbGRWaWV3cy5sZW5ndGgtMSwgdGhpcy5jaGlsZFZpZXdzLmxlbmd0aCk7CiAgICAgICAgICAgICAgICAvL3RoaXMuY2hpbGRWaWV3cy5sZW5ndGgtMSBpcyB0aGUgcGFnZSBudW1iZXIgdGlsbCB3aGljaCBmb3JtIGlzIGFscmVhZHkgcmVuZGVyZWQKICAgICAgICAgICAgICAgIC8vdGhpcy5jaGlsZFZpZXdzLmxlbmd0aCBpbmRpY2F0ZXMgdGhlIHBhZ2UgbnVtYmVyIG9mIGN1cnJlbnQgcGFnZSByZW5kZXJlZAogICAgICAgICAgICAgICAgLy9pZih3aW5kb3cuaGlnaGxpZ2h0KQogICAgICAgICAgICAgICAgLy8gICAgaGlnaGxpZ2h0RmllbGRzKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV4dFBhZ2VWaWV3OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIGhhc01vcmVEZWZlcnJlZFBhZ2VzOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAodGhpcy5nZXRPckVsc2UodGhpcy5fZGVmZXJyZWRQYWdlcywgW10pLmxlbmd0aCA+IDApOwogICAgICAgIH0KICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LkV4Y2xHcm91cFZpZXcgPSB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3LmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkNvbnRhaW5lclZpZXcucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgJCh0aGlzLiRlbCkub24oeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DTElDS19FVkVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkLnByb3h5KHRoaXMuaGFuZGxlQ2xpY2tFdmVudCx0aGlzKSk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlQ2xpY2tFdmVudCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAvL3RoaXMubW9kZWwuZXhlY0V2ZW50KCJjbGljayIpOwogICAgICAgIH0sCgogICAgICAgIF9nZXRTY3JlZW5SZWFkZXJUZXh0IDogeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fZ2V0U2NyZWVuUmVhZGVyVGV4dCwKCiAgICAgICAgX2Fzc2lnblRvb2xUaXAgOiB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9hc3NpZ25Ub29sVGlwLAoKICAgICAgICBfaW5pdExheW91dCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkNvbnRhaW5lclZpZXcucHJvdG90eXBlLl9pbml0TGF5b3V0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMuX2luaXRpYWxpemVkKXsKICAgICAgICAgICAgICAgIHRoaXMubWFya01hbmRhdG9yeSgpOwogICAgICAgICAgICAgICAgdGhpcy4kZWwuYXR0cigicm9sZSIsICJyYWRpb2dyb3VwIik7IC8vYWRkIHJvbGUKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIG1hcmtNYW5kYXRvcnkgOiBmdW5jdGlvbigpewogICAgICAgICAgICBpZih0aGlzLm1vZGVsLm1hbmRhdG9yeT09ICJlcnJvciIpCiAgICAgICAgICAgICAgICBpZih0aGlzLiRlbCkKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJkYXRhLW1hbmRhdG9yeSIsICJ0cnVlIikgOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZU1vZGVsQ2hhbmdlZCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQuX3Byb3BlcnR5KSB7CiAgICAgICAgICAgICAgICBjYXNlICJmb2N1cyI6CiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkVmlldyA9IHRoaXMuX2dldENoaWxkVG9Gb2N1cygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2ZvY3VzV2lkZ2V0KGNoaWxkVmlldyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJWYWxpZGF0aW9uU3RhdGUiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX21hcmtFcnJvcihldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJDbGVhckVycm9yIjoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9jbGVhckVycm9yKGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuQ29udGFpbmVyVmlldy5wcm90b3R5cGUuaGFuZGxlTW9kZWxDaGFuZ2VkLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYW5kbGVEb21DaGFuZ2VkOiBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgc3dpdGNoIChldmVudC5fcHJvcGVydHkpIHsKICAgICAgICAgICAgICAgIGNhc2UgIm51bGxUZXN0IjoKICAgICAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9oYW5kbGVOdWxsVGVzdC5jYWxsKHRoaXMsIGV2ZW50LCB0aGlzLiRlbC5jbG9zZXN0KCcuZXhjbGdyb3VwJykpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3LnByb3RvdHlwZS5oYW5kbGVEb21DaGFuZ2VkLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlTWFuZGF0b3J5OiB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9oYW5kbGVNYW5kYXRvcnksCiAgICAgICAgX2hhbmRsZURpc2FibGVkOiB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9oYW5kbGVEaXNhYmxlZCwKCiAgICAgICAgX21hcmtFcnJvciA6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgdGhpcy4kZWwuYWRkQ2xhc3MoIndpZGdldEVycm9yIik7CiAgICAgICAgfSwKCiAgICAgICAgX2NsZWFyRXJyb3IgOiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgIHRoaXMuJGVsLnJlbW92ZUNsYXNzKCJ3aWRnZXRFcnJvciIpOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogZ2V0IGNoaWxkIHZpZXcgb2YgZXhjbHVzaW9uIGdyb3VwIHdoaWNoIG5lZWRzIHRvIGJlIGZvY3Vzc2VkLgogICAgICAgICAqLwogICAgICAgIF9nZXRDaGlsZFRvRm9jdXMgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBfLmZpbmQodGhpcy5jaGlsZFZpZXdzLCBmdW5jdGlvbiAoY2hpbGRWaWV3KSB7CiAgICAgICAgICAgICAgICB2YXIgbW9kZWwgPSBjaGlsZFZpZXcubW9kZWw7CiAgICAgICAgICAgICAgICByZXR1cm4gKG1vZGVsICYmIG1vZGVsLnByZXNlbmNlID09ICJ2aXNpYmxlIiAmJiBtb2RlbC5tRWZmZWN0aXZlQWNjZXNzID09ICJvcGVuIik7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwovKioKICogQ3JlYXRlZCB3aXRoIEludGVsbGlKIElERUEuCiAqIFVzZXI6IHJwYW5kZXkKICogRGF0ZTogMTIvMjQvMTIKICogVGltZTogODoxNCBQTQogKiBUbyBjaGFuZ2UgdGhpcyB0ZW1wbGF0ZSB1c2UgRmlsZSB8IFNldHRpbmdzIHwgRmlsZSBUZW1wbGF0ZXMuCiAqLwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LlNpZ25hdHVyZUZpZWxkVmlldyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5leHRlbmQoewogICAgICAgIF9jcmVhdGVQbHVnaW5PcHRpb25zIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB2T3B0aW9ucyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX2NyZWF0ZVBsdWdpbk9wdGlvbnMuYXBwbHkodGhpcywKICAgICAgICAgICAgICAgIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHJldHVybiB2T3B0aW9uczsKICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbiA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgJCh0aGlzLndpZGdldCkuc2lnbmF0dXJlRmllbGQob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMuanFXaWRnZXQgPSB0aGlzLiRkYXRhKHRoaXMud2lkZ2V0LCAieGZhV2lkZ2V0LXNpZ25hdHVyZUZpZWxkIik7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOyhmdW5jdGlvbiAoXywgJCwgeGZhbGliKSB7CgogICAgeGZhbGliLnZpZXcuUGFnaW5nTWFuYWdlciA9IHhmYWxpYi52aWV3Lk9iamVjdFZpZXcuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB4ZmFsaWIudmlldy5PYmplY3RWaWV3LnByb3RvdHlwZS5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuYXV0b1JlbmRlclBhZ2VIYW5kbGVyID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5fYXV0b1BhZ2VSZW5kZXJQZW5kaW5nID0gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgcmVuZGVyTmV4dFBhZ2U6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICB2YXIgcGFnZVZpZXcgPSB0aGlzLl9nZXRSb290VmlldygpLnJlbmRlckRlZmVycmVkUGFnZSgpOwogICAgICAgICAgICBpZiAocGFnZVZpZXcpIHsKICAgICAgICAgICAgICAgIHBhZ2VWaWV3Lm9uKCJsYXlvdXRDb21wbGV0ZSIsCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQudHJpZ2dlcigibmV3UGFnZVJlbmRlciIpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS5zY2FsZUZvcm0oKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBwYWdlVmlldzsKCiAgICAgICAgfSwKCiAgICAgICAgYXV0b1JlbmRlclBhZ2U6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKHRoaXMuYXV0b1JlbmRlclBhZ2VIYW5kbGVyKSB7CiAgICAgICAgICAgICAgICAvL0lkZWFsbHkgYXV0b1JlbmRlclBhZ2VIYW5kbGVyIHNob3VsZCBiZSBwb3N0cG9uZWQgdGlsbCBhbGwgcnVubmluZyBsYXlvdXQvZGlzcGxheSB2YWxpZGF0aW9uIGN5Y2xlcyBhcmUgZmluaXNoZWQgYW5kCiAgICAgICAgICAgICAgICAvL3RoZXJlIGlzIG5vIHBlbmRpbmcgbGF5b3V0IHZhbGlkYXRpb24uIEZvciBub3cgd2UgYXJlIGRvaW5nIGl0IGluIG5leHQgc2NyaXB0IGN5Y2xlL3NldFRpbWVvdXQuCiAgICAgICAgICAgICAgICB2YXIgYXV0b1JlbmRlckhhbmRsZXIgPSB0aGlzLmF1dG9SZW5kZXJQYWdlSGFuZGxlcjsKICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5jbGVhclRpbWVvdXRPbkRlc3Ryb3kod2luZG93LnNldFRpbWVvdXQoYXV0b1JlbmRlckhhbmRsZXIsIDEpKTsKICAgICAgICAgICAgICAgIHRoaXMuX2F1dG9QYWdlUmVuZGVyUGVuZGluZyA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5fYXV0b1BhZ2VSZW5kZXJQZW5kaW5nID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHNldEF1dG9SZW5kZXJQYWdlSGFuZGxlcjogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgIGlmICh0aGlzLmF1dG9SZW5kZXJQYWdlSGFuZGxlciAhPSB2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5hdXRvUmVuZGVyUGFnZUhhbmRsZXIgPSB2YWx1ZTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmF1dG9SZW5kZXJQYWdlSGFuZGxlciAmJiB0aGlzLl9hdXRvUGFnZVJlbmRlclBlbmRpbmcpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmF1dG9SZW5kZXJQYWdlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYXNNb3JlUGFnZXM6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldFJvb3RWaWV3KCkuaGFzTW9yZURlZmVycmVkUGFnZXMoKTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0Um9vdFZpZXc6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3hmYVZpZXdSZWdpc3RyeSgpLnJvb3RTdWJmb3JtVmlldzsKICAgICAgICB9LAoKICAgICAgICBwYWdlQ291bnQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICh0aGlzLl9nZXRSb290VmlldygpLnRvdFBhZ2VzIHx8IDEpOwogICAgICAgIH0sCgogICAgICAgIF9tYWtlUGFnZTogZnVuY3Rpb24gKHBhZ2VOdW0pIHsKICAgICAgICAgICAgaWYgKHBhZ2VOdW0gPiB0aGlzLnBhZ2VDb3VudCgpKSB7CiAgICAgICAgICAgICAgICBwYWdlTnVtID0gdGhpcy5wYWdlQ291bnQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocGFnZU51bSA+IHRoaXMuY3VycmVudFBhZ2UoKSkgewogICAgICAgICAgICAgICAgdmFyIGV4dFBhZ2VDb3VudHMgPSBwYWdlTnVtIC0gdGhpcy5jdXJyZW50UGFnZSgpOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBleHRQYWdlQ291bnRzOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbmRlck5leHRQYWdlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSwKCiAgICAgICAgY3VycmVudFBhZ2U6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGIgPSB0aGlzLl9nZXRSb290VmlldygpLmNoaWxkVmlld3M7CiAgICAgICAgICAgIGlmICh4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1cykgewogICAgICAgICAgICAgICAgdmFyIGEgPSAkKHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuY3VycmVudEZvY3VzLmVsKS5wYXJlbnRzKCIucGFnZSIpWzBdOwogICAgICAgICAgICAgICAgLy9UT0RPOiBUcnkgdG8gZG8gd2l0aG91dCBmb3IgTG9vcAogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiLmxlbmd0aDsgaSsrKQogICAgICAgICAgICAgICAgICAgIGlmIChiW2ldLmVsID09IGEpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0sCgogICAgICAgIHBhZ2VEb3duOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmICh0aGlzLl9nZXRSb290VmlldygpLmhhc01vcmVEZWZlcnJlZFBhZ2VzKCkpIHsKICAgICAgICAgICAgICAgIHZhciBwYWdlVmlldyA9IHRoaXMucmVuZGVyTmV4dFBhZ2UoKTsKICAgICAgICAgICAgICAgIHRoaXMuX3BhZ2VEb3duKHBhZ2VWaWV3KTsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgdGhpcy5fcGFnZURvd24oKTsKCgogICAgICAgIH0sCgoKICAgICAgICBfcGFnZURvd246IGZ1bmN0aW9uIChwYWdlVmlldykgewogICAgICAgICAgICB2YXIgbmV4dFBhZ2UgPSB0aGlzLmN1cnJlbnRQYWdlKCkgKyAxOwogICAgICAgICAgICB2YXIgYSA9ICQoJCgiLnBhZ2UiKVtuZXh0UGFnZV0pOwogICAgICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgYS5vZmZzZXQoKS50b3ApOwogICAgICAgICAgICBwYWdlVmlldy5vZmYoImxheW91dENvbXBsZXRlIiwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgIHRoYXQuX3BhZ2VEb3duKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICk7CiAgICAgICAgfSwKCiAgICAgICAgX21ha2VQYWdlRm9ySHRtbElkOiBmdW5jdGlvbiAoaHRtbElkLCBjYWxsYmFjaywgY29udGV4dCkgewogICAgICAgICAgICBpZiAoaHRtbElkID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIHZhciBub2RlU2VsZWN0b3IgPSB0aGlzLmpxSWQoaHRtbElkKTsKICAgICAgICAgICAgdmFyIHJvb3RWaWV3ID0gdGhpcy5fZ2V0Um9vdFZpZXcoKTsKICAgICAgICAgICAgdmFyIG5vZGVFbEFycmF5ID0gcm9vdFZpZXcuJGVsLmZpbmQobm9kZVNlbGVjdG9yKTsKICAgICAgICAgICAgaWYgKG5vZGVFbEFycmF5Lmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykKICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5hcHBseShjb250ZXh0KTsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgoKICAgICAgICAgICAgdmFyIHBhZ2VGb3VuZCA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAodGhpcy5oYXNNb3JlUGFnZXMoKSkgewogICAgICAgICAgICAgICAgdmFyIHZpZXcgPSByb290Vmlldy5yZW5kZXJEZWZlcnJlZFBhZ2UoKTsKICAgICAgICAgICAgICAgIGlmICh2aWV3LiRlbC5maW5kKG5vZGVTZWxlY3RvcikubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykKLy9MQy00NDI0IFdlIGFyZSBzZW5kaW5nIHRoZSBldmVudCBsYXlvdXRDb21wbGV0ZSB0aGF0IHRoZSBsYXlvdXQgaXMgY29tcGxldGUgZnJvbSBvdXIgdmlldyBwb2ludCBidXQgdGhlCi8vIGJyb3dzZXIgaGFzIG5vdCB5ZXQgcGFpbnRlZCB0aGUgcGFnZSggQ2hyb21lKSBhbmQgaGVuY2UgdGhlIGZvY3VzIGlzIGNvbWluZyBhdCB0aGUgd3JvbmcgcGxhY2UuCiAgICAgICAgICAgICAgICAgICAgICAgIHZpZXcub24oImxheW91dENvbXBsZXRlIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmNsZWFyVGltZW91dE9uRGVzdHJveSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmFwcGx5KGNvbnRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICBwYWdlRm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChwYWdlRm91bmQpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIGZpbmRQYWdlOiBmdW5jdGlvbiAoaHRtbElkKSB7CiAgICAgICAgICAgIGlmIChodG1sSWQgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgdmFyIG5vZGVTZWxlY3RvciA9IHRoaXMuanFJZChodG1sSWQpOwogICAgICAgICAgICB2YXIgcm9vdFZpZXcgPSB0aGlzLl9nZXRSb290VmlldygpOwogICAgICAgICAgICB2YXIgaSA9IDA7CiAgICAgICAgICAgIGZvciAoOyBpIDwgcm9vdFZpZXcuY2hpbGRWaWV3cy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIG5vZGVFbEFycmF5ID0gJChyb290Vmlldy5jaGlsZFZpZXdzW2ldLmVsKS5maW5kKG5vZGVTZWxlY3Rvcik7CiAgICAgICAgICAgICAgICBpZiAobm9kZUVsQXJyYXkubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHdoaWxlICh0aGlzLmhhc01vcmVQYWdlcygpKSB7CiAgICAgICAgICAgICAgICByb290Vmlldy5yZW5kZXJEZWZlcnJlZFBhZ2UoKTsKICAgICAgICAgICAgICAgIHZhciBub2RlRWxBcnJheSA9ICQocm9vdFZpZXcuY2hpbGRWaWV3c1tpXS5lbCkuZmluZChub2RlU2VsZWN0b3IpOwogICAgICAgICAgICAgICAgaWYgKG5vZGVFbEFycmF5Lmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGdldExheW91dDogZnVuY3Rpb24gKGh0bWxJZCkgewogICAgICAgICAgICBpZiAoaHRtbElkID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIHZhciBub2RlU2VsZWN0b3IgPSB0aGlzLmpxSWQoaHRtbElkKTsKICAgICAgICAgICAgdmFyIHJvb3RWaWV3ID0gdGhpcy5fZ2V0Um9vdFZpZXcoKTsKICAgICAgICAgICAgdmFyIGVsID0gcm9vdFZpZXcuJGVsLmZpbmQobm9kZVNlbGVjdG9yKTsKICAgICAgICAgICAgaWYgKGVsLmdldCgwKSkgewogICAgICAgICAgICAgICAgdmFyIGxheW91dCA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMuJGRhdGEoZWwuZ2V0KDApLCAieGZhVmlldyIpLCB7fSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbGF5b3V0LmxheW91dE1vZGVsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgcmV0dXJuIG51bGw7CgogICAgICAgIH0sCgogICAgICAgIF9wYWdlQ29udGVudDogZnVuY3Rpb24gKHBhZ2VOdW0sIGNsYXNzTmFtZSwgYlBhZ2VBcmVhKSB7CiAgICAgICAgICAgIGJQYWdlQXJlYSA9IGJQYWdlQXJlYSB8fCBmYWxzZTsKICAgICAgICAgICAgdGhpcy5fbWFrZVBhZ2UocGFnZU51bSk7CiAgICAgICAgICAgIHZhciBwYWdlVmlldyA9IHRoaXMuX2dldFJvb3RWaWV3KCkuY2hpbGRWaWV3c1twYWdlTnVtXTsKICAgICAgICAgICAgdmFyIGNvbnRlbnRMaXN0ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICBpZiAocGFnZVZpZXcubW9kZWwgJiYgKCFjbGFzc05hbWUgfHwgY2xhc3NOYW1lID09ICJwYWdlQXJlYSIpKSB7CiAgICAgICAgICAgICAgICBjb250ZW50TGlzdC5fYXBwZW5kKHBhZ2VWaWV3Lm1vZGVsKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWJQYWdlQXJlYSkgewogICAgICAgICAgICAgICAgZm9yICh2YXIgcHYgaW4gcGFnZVZpZXcuY2hpbGRWaWV3cykgewogICAgICAgICAgICAgICAgICAgIGlmIChwYWdlVmlldy5jaGlsZFZpZXdzW3B2XSBpbnN0YW5jZW9mICB4ZmFsaWIudmlldy5Db250ZW50QXJlYVZpZXcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudExpc3QuX2NvbmNhdCh0aGlzLiRwYWdlQ29udGVudChwYWdlVmlldy5jaGlsZFZpZXdzW3B2XSwgY2xhc3NOYW1lLCBiUGFnZUFyZWEpKTsgICAvL1JhdGhlciB0aGFuIHBhc3NpbmcgdGhlIHBhZ2VBcmVhLCB3ZSBhcmUgcGFzc2luZyBvbmx5IGNvbnRlbnRBcmVhCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNvIHRoYXQgaXQgcmV0dXJucyBhbGwgbm9uLXBhZ2VBcmVhIGNvbnRlbnQgbm9kZXMKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnRMaXN0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbnRlbnRMaXN0Ll9jb25jYXQodGhpcy4kcGFnZUNvbnRlbnQocGFnZVZpZXcsIGNsYXNzTmFtZSwgYlBhZ2VBcmVhKSk7CiAgICAgICAgICAgIHJldHVybiBjb250ZW50TGlzdDsKICAgICAgICB9LAoKICAgICAgICAkbm9kZUNvbnRlbnQ6IGZ1bmN0aW9uIChub2RlLCBjbGFzc05hbWUsIGJQYWdlQXJlYSkgewogICAgICAgICAgICAvL3Byb2Nlc3MgY2hpbGQgbm9kZXMKICAgICAgICAgICAgdmFyIGNvbnRlbnRMaXN0ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICBpZiAobm9kZSkgewogICAgICAgICAgICAgICAgXy5lYWNoKG5vZGUuY2hpbGRyZW4sIGZ1bmN0aW9uIChub2RlQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWNsYXNzTmFtZSAmJiBub2RlQ2hpbGQuaXNDb250YWluZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudExpc3QuX2FwcGVuZChub2RlQ2hpbGQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChub2RlQ2hpbGQuY2xhc3NOYW1lID09IGNsYXNzTmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50TGlzdC5fYXBwZW5kKG5vZGVDaGlsZCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAobm9kZUNoaWxkLmlzQ29udGFpbmVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlQ2hpbGRDb250ZW50TGlzdCA9IHRoaXMuJG5vZGVDb250ZW50KG5vZGVDaGlsZCwgY2xhc3NOYW1lLCBiUGFnZUFyZWEpOwogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50TGlzdC5fY29uY2F0KG5vZGVDaGlsZENvbnRlbnRMaXN0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY29udGVudExpc3Q7CiAgICAgICAgfSwKCiAgICAgICAgJHBhZ2VDb250ZW50OiBmdW5jdGlvbiAodmlldywgY2xhc3NOYW1lLCBiUGFnZUFyZWEpIHsKCiAgICAgICAgICAgIHZhciBjb250ZW50TGlzdCA9IG5ldyB4ZmFsaWIuc2NyaXB0LlhmYUxpc3QoKTsKICAgICAgICAgICAgLy9wcm9jZXNzIGNoaWxkIG5vZGVzCiAgICAgICAgICAgIGlmIChiUGFnZUFyZWEgJiYgdmlldyBpbnN0YW5jZW9mIHhmYWxpYi52aWV3LkNvbnRlbnRBcmVhVmlldykKICAgICAgICAgICAgICAgIHJldHVybiBjb250ZW50TGlzdDsgICAgICAvLyBCcmVha2luZyB0aGUgcmVjdXJzaW9uIGhlcmUsIHNvIHRoYXQgaXQgd2lsbCByZXR1cm4gb25seSBwYWdlQXJlYSBjb250ZW50IG5vZGVzCiAgICAgICAgICAgIF8uZWFjaCh2aWV3LmNoaWxkVmlld3MsIGZ1bmN0aW9uIChjaGlsZFZpZXcpIHsKICAgICAgICAgICAgICAgIGlmIChjaGlsZFZpZXcubW9kZWwpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRNb2RlbCA9IGNoaWxkVmlldy5tb2RlbDsKICAgICAgICAgICAgICAgICAgICBpZiAoIWNsYXNzTmFtZSAmJiBjaGlsZE1vZGVsLmlzQ29udGFpbmVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRMaXN0Ll9hcHBlbmQoY2hpbGRNb2RlbCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGlsZE1vZGVsLmNsYXNzTmFtZSA9PSBjbGFzc05hbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudExpc3QuX2FwcGVuZChjaGlsZE1vZGVsKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL1RpbWUgdG8gcmVjdXJzZQoKICAgICAgICAgICAgICAgIGlmIChjaGlsZFZpZXcuX2lzUGxhY2VIb2xkZXJFbCgpICYmIGNoaWxkVmlldy5tb2RlbCkgewogICAgICAgICAgICAgICAgICAgIC8vRm9yIGhpZGRlbiB2aWV3cyB0aGF0IGhhdmUgbmV2ZXIgYmVlbiBpbml0aWFsaXplZCwgd2Ugd291bGQgd2FudCB0byByZXR1cm4gYWxsIGNvbnRhaW5lZCBub2RlcyBzaW5jZSB3ZSBzdGl0Y2gKICAgICAgICAgICAgICAgICAgICAvL2hpZGRlbiBub2RlIHRvZ2V0aGVyIGluIGZpcnN0IHBhZ2UuCiAgICAgICAgICAgICAgICAgICAgY29udGVudExpc3QuX2NvbmNhdCh0aGlzLiRub2RlQ29udGVudChjaGlsZFZpZXcubW9kZWwsIGNsYXNzTmFtZSwgYlBhZ2VBcmVhKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjb250ZW50TGlzdC5fY29uY2F0KHRoaXMuJHBhZ2VDb250ZW50KGNoaWxkVmlldywgY2xhc3NOYW1lLCBiUGFnZUFyZWEpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICByZXR1cm4gY29udGVudExpc3Q7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKCiAgICAgICAgeGZhbGliLnZpZXcuRGF0YVRhYmxlVmlldyA9IHhmYWxpYi52aWV3LkNvbnRhaW5lclZpZXcuZXh0ZW5kKHsKCiAgICAgICAgJGVsY2hpbGRyZW4gOiBmdW5jdGlvbihpZCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy4kZWwuY2hpbGRyZW4oKS5jaGlsZHJlbihpZCk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldFNjcmVlblJlYWRlclRleHQ6IHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX2dldFNjcmVlblJlYWRlclRleHQsCgogICAgICAgIF9hc3NpZ25Ub29sVGlwIDogeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fYXNzaWduVG9vbFRpcAoKICAgICAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB2YXIgcm9vdCA9IHdpbmRvdzsKICAgIHJvb3QueGZhVmlld1JlZ2lzdHJ5ID0gKGZ1bmN0aW9uKCl7CiAgICAgICAgdmFyIF90ZW1wbGF0ZUNhY2hlID0gbmV3IHhmYWxpYi52aWV3LnV0aWwuSHRtbFRlbXBsYXRlQ2FjaGUoKTsKICAgICAgICB2YXIgX2xheW91dE1hbmFnZXIgPSBuZXcgeGZhbGliLnZpZXcubGF5b3V0LkxheW91dE1hbmFnZXIoKTsKICAgICAgICB2YXIgeGZhVXRpbCA9IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZTsKCiAgICAgICAgdmFyIF92aWV3VHlwZVJlZ2lzdHJ5ID0gewogICAgICAgICAgICBCYXNlVmlldyA6IHhmYWxpYi52aWV3LkJhc2VWaWV3LAogICAgICAgICAgICBGaWVsZFZpZXcgOiB4ZmFsaWIudmlldy5GaWVsZFZpZXcsCiAgICAgICAgICAgIE51bWVyaWNGaWVsZFZpZXcgOiB4ZmFsaWIudmlldy5OdW1lcmljRmllbGRWaWV3LAogICAgICAgICAgICBDaG9pY2VMaXN0RmllbGRWaWV3IDogeGZhbGliLnZpZXcuQ2hvaWNlTGlzdEZpZWxkVmlldywKICAgICAgICAgICAgT2JqZWN0VmlldyA6IHhmYWxpYi52aWV3Lk9iamVjdFZpZXcsCiAgICAgICAgICAgIFN1YmZvcm1WaWV3IDogeGZhbGliLnZpZXcuU3ViZm9ybVZpZXcsCiAgICAgICAgICAgIFN1YmZvcm1TZXRWaWV3IDogeGZhbGliLnZpZXcuU3ViZm9ybVNldFZpZXcsCiAgICAgICAgICAgIFBhZ2VWaWV3IDogeGZhbGliLnZpZXcuUGFnZVZpZXcsCiAgICAgICAgICAgIENvbnRlbnRBcmVhVmlldyA6IHhmYWxpYi52aWV3LkNvbnRlbnRBcmVhVmlldywKICAgICAgICAgICAgUm9vdFN1YmZvcm1WaWV3IDogeGZhbGliLnZpZXcuUm9vdFN1YmZvcm1WaWV3LAogICAgICAgICAgICBDb250YWluZXJWaWV3IDogeGZhbGliLnZpZXcuQ29udGFpbmVyVmlldywKICAgICAgICAgICAgQnV0dG9uRmllbGRWaWV3IDogeGZhbGliLnZpZXcuQnV0dG9uRmllbGRWaWV3LAogICAgICAgICAgICBDaGVja0J1dHRvbkZpZWxkVmlldyA6IHhmYWxpYi52aWV3LkNoZWNrQnV0dG9uRmllbGRWaWV3LAogICAgICAgICAgICBUZXh0RmllbGRWaWV3IDogeGZhbGliLnZpZXcuVGV4dEZpZWxkVmlldywKICAgICAgICAgICAgU2lnbmF0dXJlRmllbGRWaWV3IDogeGZhbGliLnZpZXcuU2lnbmF0dXJlRmllbGRWaWV3LAogICAgICAgICAgICBJbWFnZUZpZWxkVmlldyA6IHhmYWxpYi52aWV3LkltYWdlRmllbGRWaWV3LAogICAgICAgICAgICBYZmFEcmF3VmlldyA6IHhmYWxpYi52aWV3LlhmYURyYXdWaWV3LAogICAgICAgICAgICBEYXRlVGltZUZpZWxkVmlldzogeGZhbGliLnZpZXcuRGF0ZVRpbWVGaWVsZFZpZXcsCiAgICAgICAgICAgIEV4Y2xHcm91cFZpZXc6IHhmYWxpYi52aWV3LkV4Y2xHcm91cFZpZXcsCiAgICAgICAgICAgIERhdGFUYWJsZVZpZXc6IHhmYWxpYi52aWV3LkRhdGFUYWJsZVZpZXcKICAgICAgICB9OwoKICAgICAgICB2YXIgX2RlZmF1bHREcmF3ID0gewogICAgICAgICAgICB2aWV3IDogX3ZpZXdUeXBlUmVnaXN0cnkuWGZhRHJhd1ZpZXcKICAgICAgICB9OwoKICAgICAgICB2YXIgX2RlZmF1bHRGaWVsZCA9IHsKICAgICAgICAgICAgdmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LkZpZWxkVmlldywKICAgICAgICAgICAgd2lkZ2V0VGVtcGxhdGUgOiBudWxsLAogICAgICAgICAgICB2aWV3SW5pdENvbmZpZyA6IHsKICAgICAgICAgICAgICAgIGNvbW1pdEV2ZW50IDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FWElUX0VWRU5ULAogICAgICAgICAgICAgICAgY29tbWl0UHJvcGVydHkgOiAidmFsdWUiLAogICAgICAgICAgICAgICAgY29tbWl0VGFyZ2V0IDogInJhd1ZhbHVlIgogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICB2YXIgX2RlZmF1bHRDb250YWluZXIgPSB7CiAgICAgICAgICAgIHZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5Db250YWluZXJWaWV3CiAgICAgICAgfTsKICAgICAgICB2YXIgX2RlZmF1bHREYXRhVGFibGUgPSB7CiAgICAgICAgICAgIHZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5EYXRhVGFibGVWaWV3CiAgICAgICAgfTsKCiAgICAgICAgdmFyIF9ub2RlVHlwZVJlZ2lzdHJ5ID0gewogICAgICAgICAgICAvL0NvbnRhaW5lcnMKICAgICAgICAgICAgImFyZWEiIDogICAgX2RlZmF1bHRDb250YWluZXIsCiAgICAgICAgICAgICJjb250ZW50YXJlYSIgOiB7dmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LkNvbnRlbnRBcmVhVmlld30sCiAgICAgICAgICAgICJleGNsZ3JvdXAiIDoge3ZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5FeGNsR3JvdXBWaWV3fSwKICAgICAgICAgICAgInBhZ2UiIDoge3ZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5QYWdlVmlld30sCiAgICAgICAgICAgICJzdWJmb3JtIiA6IHt2aWV3IDogX3ZpZXdUeXBlUmVnaXN0cnkuU3ViZm9ybVZpZXd9LAogICAgICAgICAgICAic3ViZm9ybXNldCIgOiB7dmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LlN1YmZvcm1TZXRWaWV3fSwKICAgICAgICAgICAgInJvb3RzdWJmb3JtIiA6IHt2aWV3IDogX3ZpZXdUeXBlUmVnaXN0cnkuUm9vdFN1YmZvcm1WaWV3fSwKCiAgICAgICAgICAgIC8vRmllbGRzCiAgICAgICAgICAgICJ0ZXh0ZmllbGQiIDogewogICAgICAgICAgICAgICAgdmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LlRleHRGaWVsZFZpZXcsCiAgICAgICAgICAgICAgICB2aWV3SW5pdENvbmZpZyA6IHsKICAgICAgICAgICAgICAgICAgICBjb21taXRFdmVudCA6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRVhJVF9FVkVOVCwKICAgICAgICAgICAgICAgICAgICBjb21taXRQcm9wZXJ0eSA6ICJ2YWx1ZSIsCiAgICAgICAgICAgICAgICAgICAgY29tbWl0VGFyZ2V0IDogInJhd1ZhbHVlIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICAic2lnbmF0dXJlZmllbGQiIDogewogICAgICAgICAgICAgICAgdmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LlNpZ25hdHVyZUZpZWxkVmlldywKICAgICAgICAgICAgICAgIHZpZXdJbml0Q29uZmlnIDogewogICAgICAgICAgICAgICAgICAgIGNvbW1pdEV2ZW50IDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FWElUX0VWRU5ULAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFByb3BlcnR5IDogInZhbHVlIiwKICAgICAgICAgICAgICAgICAgICBjb21taXRUYXJnZXQgOiAicmF3VmFsdWUiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ0ZXh0YXJlYWZpZWxkIiA6IHsKICAgICAgICAgICAgICAgIHZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5UZXh0RmllbGRWaWV3LAogICAgICAgICAgICAgICAgdmlld0luaXRDb25maWcgOiB7CiAgICAgICAgICAgICAgICAgICAgY29tbWl0RXZlbnQgOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VYSVRfRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgY29tbWl0UHJvcGVydHkgOiAidmFsdWUiLAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFRhcmdldCA6ICJyYXdWYWx1ZSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm51bWVyaWNmaWVsZCIgOiB7CiAgICAgICAgICAgICAgICB2aWV3IDogX3ZpZXdUeXBlUmVnaXN0cnkuTnVtZXJpY0ZpZWxkVmlldywKICAgICAgICAgICAgICAgIHZpZXdJbml0Q29uZmlnIDogewogICAgICAgICAgICAgICAgICAgIGNvbW1pdEV2ZW50IDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FWElUX0VWRU5ULAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFByb3BlcnR5IDogInZhbHVlIiwKICAgICAgICAgICAgICAgICAgICBjb21taXRUYXJnZXQgOiAicmF3VmFsdWUiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJpbWFnZWZpZWxkIiA6IHsKICAgICAgICAgICAgICAgIHZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5JbWFnZUZpZWxkVmlldywKICAgICAgICAgICAgICAgIHZpZXdJbml0Q29uZmlnIDogewogICAgICAgICAgICAgICAgICAgIGNvbW1pdEV2ZW50IDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgY29tbWl0UHJvcGVydHkgOiAic3JjIiwKICAgICAgICAgICAgICAgICAgICBjb21taXRUYXJnZXQgOiAicmF3VmFsdWUiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJkYXRlZmllbGQiIDogewogICAgICAgICAgICAgICAgdmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LkRhdGVUaW1lRmllbGRWaWV3LAogICAgICAgICAgICAgICAgdmlld0luaXRDb25maWcgOiB7CiAgICAgICAgICAgICAgICAgICAgY29tbWl0RXZlbnQgOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VYSVRfRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgY29tbWl0UHJvcGVydHkgOiAidmFsdWUiLAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFRhcmdldCA6ICJyYXdWYWx1ZSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgInRpbWVmaWVsZCIgOiBfZGVmYXVsdEZpZWxkLAogICAgICAgICAgICAiZGF0ZXRpbWVmaWVsZCIgOiBfZGVmYXVsdEZpZWxkLAogICAgICAgICAgICAicGFzc3dvcmRmaWVsZCIgOiBfZGVmYXVsdEZpZWxkLAogICAgICAgICAgICAiYnV0dG9uZmllbGQiIDogewogICAgICAgICAgICAgICAgdmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LkJ1dHRvbkZpZWxkVmlldywKICAgICAgICAgICAgICAgIHZpZXdJbml0Q29uZmlnIDogewogICAgICAgICAgICAgICAgICAgIGNvbW1pdEV2ZW50IDogbnVsbCwKICAgICAgICAgICAgICAgICAgICBjb21taXRQcm9wZXJ0eSA6ICJ2YWx1ZSIsCiAgICAgICAgICAgICAgICAgICAgY29tbWl0VGFyZ2V0IDogInJhd1ZhbHVlIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICAic3VibWl0ZmllbGQiIDogX2RlZmF1bHREcmF3LAogICAgICAgICAgICAicmFkaW9maWVsZCIgOiB7CiAgICAgICAgICAgICAgICB2aWV3IDogX3ZpZXdUeXBlUmVnaXN0cnkuQ2hlY2tCdXR0b25GaWVsZFZpZXcsCiAgICAgICAgICAgICAgICB2aWV3SW5pdENvbmZpZyA6IHsKICAgICAgICAgICAgICAgICAgICBjb21taXRFdmVudCA6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0hBTkdFX0VWRU5ULAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFByb3BlcnR5IDogInZhbHVlIiwKICAgICAgICAgICAgICAgICAgICBjb21taXRUYXJnZXQgOiAicmF3VmFsdWUiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJjaGVja2JveGZpZWxkIiA6IHsKICAgICAgICAgICAgICAgIHZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5DaGVja0J1dHRvbkZpZWxkVmlldywKICAgICAgICAgICAgICAgIHZpZXdJbml0Q29uZmlnIDogewogICAgICAgICAgICAgICAgICAgIGNvbW1pdEV2ZW50IDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgY29tbWl0UHJvcGVydHkgOiAidmFsdWUiLAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFRhcmdldCA6ICJyYXdWYWx1ZSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgImNob2ljZWxpc3QiIDogewogICAgICAgICAgICAgICAgdmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LkNob2ljZUxpc3RGaWVsZFZpZXcsCiAgICAgICAgICAgICAgICB2aWV3SW5pdENvbmZpZyA6IHsKICAgICAgICAgICAgICAgICAgICBjb21taXRFdmVudCA6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0hBTkdFX0VWRU5ULAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFByb3BlcnR5IDogInZhbHVlIiwKICAgICAgICAgICAgICAgICAgICBjb21taXRUYXJnZXQgOiAicmF3VmFsdWUiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKCiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgdmlld1R5cGVSZWdpc3RyeSA6IF92aWV3VHlwZVJlZ2lzdHJ5LAogICAgICAgICAgICByb290U3ViZm9ybVZpZXcgOiBudWxsLAogICAgICAgICAgICBub2RlVHlwZVJlZ2lzdHJ5IDogX25vZGVUeXBlUmVnaXN0cnksCiAgICAgICAgICAgIF91c2VyQ29uZmlnIDogbnVsbCwKCiAgICAgICAgICAgIHdpZGdldENvbmZpZyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICBpZih0aGlzLl91c2VyQ29uZmlnICYmIHRoaXMuX3VzZXJDb25maWdbIndpZGdldENvbmZpZyJdKXsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdXNlckNvbmZpZ1sid2lkZ2V0Q29uZmlnIl07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBwYWdpbmdDb25maWcgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgaWYodGhpcy5fdXNlckNvbmZpZyAmJiB0aGlzLl91c2VyQ29uZmlnWyJwYWdpbmdDb25maWciXSl7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3VzZXJDb25maWdbInBhZ2luZ0NvbmZpZyJdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHNocmlua1BhZ2VEaXNhYmxlZFZhbHVlID0gZmFsc2U7CiAgICAgICAgICAgICAgICBpZih0aGlzLl91c2VyQ29uZmlnICYmIHRoaXMuX3VzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl0pewogICAgICAgICAgICAgICAgICAgIC8vVE9ETzogQ3JlYXRlIGEgZ2VuZXJpYyBtZXRob2Qgc29tZXdoZXJlIGluIEZvcm1CcmlkZ2U/CiAgICAgICAgICAgICAgICAgICAgdmFyIHZlcnNpb24gPSBuZXcgeGZhbGliLnV0LlZlcnNpb24odGhpcy5fdXNlckNvbmZpZ1siYmVoYXZpb3JDb25maWciXSk7CiAgICAgICAgICAgICAgICAgICAgaWYodmVyc2lvbi5pc1ByZXZpb3VzT3JTYW1lKHZlcnNpb24uRVM0KSkKICAgICAgICAgICAgICAgICAgICAgICAgc2hyaW5rUGFnZURpc2FibGVkVmFsdWUgPSB0cnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAgICAgcGFnaW5nRGlzYWJsZWQgOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBzaHJpbmtQYWdlRGlzYWJsZWQgOiBzaHJpbmtQYWdlRGlzYWJsZWRWYWx1ZQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGxvb2tVcFZpZXcgOiBmdW5jdGlvbihvcHRpb25zKXsKICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwoKICAgICAgICAgICAgICAgIGlmKG9wdGlvbnMuZGF0YVRhYmxlKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBfZGVmYXVsdERhdGFUYWJsZTsKICAgICAgICAgICAgICAgIHZhciBub2RlVHlwZVZpZXcgPSB0aGlzLm5vZGVUeXBlUmVnaXN0cnlbb3B0aW9ucy5ub2RlVHlwZV07CiAgICAgICAgICAgICAgICBpZihub2RlVHlwZVZpZXcpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGVUeXBlVmlldzsKCiAgICAgICAgICAgICAgICBpZihvcHRpb25zLmZpZWxkKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBfZGVmYXVsdEZpZWxkOwogICAgICAgICAgICAgICAgZWxzZSBpZihvcHRpb25zLmRyYXcpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9kZWZhdWx0RHJhdzsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2RlZmF1bHRDb250YWluZXI7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBjcmVhdGVWaWV3IDogZnVuY3Rpb24oaHRtbERvbU5vZGUsIG9wdGlvbnMpewogICAgICAgICAgICAgICAgdmFyICRodG1sRG9tTm9kZSA9ICQoaHRtbERvbU5vZGUpOwogICAgICAgICAgICAgICAgdmFyIG5vZGVUeXBlID0gKHhmYVV0aWwuJGRhdGEoJGh0bWxEb21Ob2RlLmdldCgwKSwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMKSB8fHt9KVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5OT0RFX1RZUEVdOwogICAgICAgICAgICAgICAgdmFyIGlzRmllbGQgPSAkaHRtbERvbU5vZGUuaGFzQ2xhc3MoImZpZWxkIik7CiAgICAgICAgICAgICAgICB2YXIgaXNEcmF3ID0gJGh0bWxEb21Ob2RlLmhhc0NsYXNzKCJkcmF3Iik7CiAgICAgICAgICAgICAgICB2YXIgaXNEYXRhVGFibGUgPSAoJGh0bWxEb21Ob2RlLnByb3AoInRhZ05hbWUiKSA9PSAiVEFCTEUiKTsKICAgICAgICAgICAgICAgIHZhciBpc0RhdGFUYWJsZVJvdyA9ICgkaHRtbERvbU5vZGUucHJvcCgidGFnTmFtZSIpID09ICJUUiIpOwogICAgICAgICAgICAgICAgdmFyIGlzRGF0YVRhYmxlQ2VsbCA9ICgkaHRtbERvbU5vZGUucHJvcCgidGFnTmFtZSIpID09ICJURCIgfHwgJGh0bWxEb21Ob2RlLnByb3AoInRhZ05hbWUiKSA9PSAiVEgiICk7CiAgICAgICAgICAgICAgICB2YXIgdmlld09wdGlvbnMgPSB7CiAgICAgICAgICAgICAgICAgICAgIm5vZGVUeXBlIiA6IG5vZGVUeXBlLAogICAgICAgICAgICAgICAgICAgICJmaWVsZCIgOiBpc0ZpZWxkLAogICAgICAgICAgICAgICAgICAgICJkcmF3IiA6IGlzRHJhdywKICAgICAgICAgICAgICAgICAgICAiZGF0YVRhYmxlIiA6IGlzRGF0YVRhYmxlLAogICAgICAgICAgICAgICAgICAgICJkYXRhVGFibGVSb3ciIDogaXNEYXRhVGFibGVSb3csCiAgICAgICAgICAgICAgICAgICAgImRhdGFUYWJsZUNlbGwiIDogaXNEYXRhVGFibGVDZWxsCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgdmFyIHZpZXdDb25maWcgPSB0aGlzLmxvb2tVcFZpZXcodmlld09wdGlvbnMpOwogICAgICAgICAgICAgICAgdmFyIGluaXRQYXJhbSA9ICBfLmV4dGVuZCgKICAgICAgICAgICAgICAgICAgICB7ZWw6aHRtbERvbU5vZGV9LAogICAgICAgICAgICAgICAgICAgIHZpZXdDb25maWdbInZpZXdJbml0Q29uZmlnIl0sCiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIHZhciB2aWV3SW5zdGFuY2UgPSAgbmV3IHZpZXdDb25maWdbInZpZXciXShpbml0UGFyYW0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHZpZXdJbnN0YW5jZTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDbGVhcnMgdGhlIHRlbXBsYXRlIGNhY2hlLiBUaGUgQVBJIGlzIG5lZWRlZCB0byBjbGVhciB0aGUgY2FjaGUgd2hlbgogICAgICAgICAgICAgKiB1bmxvYWRpbmcgb25lIGZvcm0gYW5kIGxvYWRpbmcgYW5vdGhlciBmb3JtIGluIEZvcm0gU2V0LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2xlYXJUZW1wbGF0ZUNhY2hlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBfdGVtcGxhdGVDYWNoZSA9IG5ldyB4ZmFsaWIudmlldy51dGlsLkh0bWxUZW1wbGF0ZUNhY2hlKCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ2xlYXJzIHRoZSBMYXlvdXQgTWFuYWdlci4gVGhlIEFQSSBpcyBuZWVkZWQgdG8gdW5sb2FkIHRoZSBsYXlvdXQgTWFuYWdlcgogICAgICAgICAgICAgKiB3aGVuIHVubG9hZGluZyBvbmUgZm9ybSBhbmQgbG9hZGluZyBhbm90aGVyIGZvcm0gaW4gRm9ybSBTZXQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICByZXNldExheW91dE1hbmFnZXIgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgX2xheW91dE1hbmFnZXIgPSBuZXcgeGZhbGliLnZpZXcubGF5b3V0LkxheW91dE1hbmFnZXIoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBUaGUgZnVuY3Rpb24gaXMgdXNlZCB0byBkZXN0cm95IHRoZSByZXNvdXJjZXMgaGVsZCBieSB0aGUgb2JqZWN0LgogICAgICAgICAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuIHRoZSBmb3JtIGlzIGRlc3Ryb3llZC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIF90ZW1wbGF0ZUNhY2hlID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgX2xheW91dE1hbmFnZXIgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICB0ZW1wbGF0ZUNhY2hlIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiBfdGVtcGxhdGVDYWNoZTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGxheW91dE1hbmFnZXIgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIF9sYXlvdXRNYW5hZ2VyOwogICAgICAgICAgICB9LAoKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGxvb2sgdXBzIHRoZSBmb3JtV2lkdGggdmFsdWUgaW4gYmVoYXZpb3VyQ29uZmlnOyBhbmQgaWYgYnJvd3NlciBzdXBwb3J0cyBzY2FsaW5nLCBlbmZvcmNlIHRoYXQgd2lkdGggYnkgc2NhbGluZyB0aGUgZm9ybQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2NhbGVGb3JtOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgZm9ybVdpZHRoID0gdGhpcy5fdXNlckNvbmZpZ1sidmlld3BvcnRXaWR0aCJdOwogICAgICAgICAgICAgICAgaWYgKGZvcm1XaWR0aCkgewogICAgICAgICAgICAgICAgICAgIHZhciB0aW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyAgICAgLy8gd2FpdCBmb3IgZW5vdWdoIHRpbWUgdG8gbGV0IGxheW91dCBjb21wbGV0ZQogICAgICAgICAgICAgICAgICAgICAgICBmb3JtV2lkdGggPSBwYXJzZUludChmb3JtV2lkdGgpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFnZU1heFdpZHRoID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiLnBhZ2UiKS5lYWNoKGZ1bmN0aW9uIChpLCBvYmopIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0bXBXaWR0aCA9IHBhcnNlSW50KCQob2JqKS53aWR0aCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0bXBXaWR0aCA+IHBhZ2VNYXhXaWR0aCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTWF4V2lkdGggPSB0bXBXaWR0aDsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aWR0aCA9IHBhZ2VNYXhXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCA9IHBhcnNlSW50KCQoImJvZHkiKS5oZWlnaHQoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZUZhY3RvciA9IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IgPSBmb3JtV2lkdGggLyB3aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybVZhbHVlID0gInNjYWxlKCIgKyBzY2FsZUZhY3RvciArICIpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbkhlaWdodCA9IGhlaWdodCAtIHNjYWxlRmFjdG9yICogaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luV2lkdGggPSB3aWR0aCAtIHNjYWxlRmFjdG9yICogd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZVN0eWxlcyA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLXdlYmtpdC10cmFuc2Zvcm0iOiB0cmFuc2Zvcm1WYWx1ZSwgLyogU2FmMy4xKywgQ2hyb21lICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi1tb3otdHJhbnNmb3JtIjogdHJhbnNmb3JtVmFsdWUsIC8qIEZGMy41KyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICItbXMtdHJhbnNmb3JtIjogdHJhbnNmb3JtVmFsdWUsIC8qIElFOSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cmFuc2Zvcm0iOiB0cmFuc2Zvcm1WYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLXdlYmtpdC10cmFuc2Zvcm0tb3JpZ2luIjogIjAgMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi1tb3otdHJhbnNmb3JtLW9yaWdpbiI6ICIwIDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICItbXMtdHJhbnNmb3JtLW9yaWdpbiI6ICIwIDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cmFuc2Zvcm0tb3JpZ2luIjogIjAgMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogYmVsb3cgdHdvIHZhbHVlcyBhcmUgYmFzZWQgb24gdG90YWwgaGV1cmlzdGljcy4gYmVzdCBjb21iaW5hdGlvbiB0byBnZXQgdGhpbmcgd29ya2luZyBjcm9zcyBicm93c2VyOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICBJbiBmZXcgYnJvd3NlcnMsIGFmdGVyIHNjYWxpbmcgdGhlcmUgaXMgYmxhbmsgc3BhY2Ugb24gYm90dG9tIHNvIG1hcmdpbi1ib3R0b20gaXMgdXNlZCB3aXRoIG5lZ2F0aXZlIHZhbHVlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICBtYXJnaW4gcmlnaHQgaXMgcmVxdWlyZWQgZm9yIHJlbW92aW5nIHNwYWNlIG9uIHJpZ2h0IGluIGZldyBicm93c2VyLCBhZnRlciBzY2FsaW5nLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICBBbmQgaW50ZXJlc3RpbmdseSwgZm9ybXVsYWUgZm9yIGJvdGggYXJlIGRpZmZlcmVudCwgbm90IG15IG1pc3Rha2UtIHRvdGFsIGhldXJpc3RpY3MuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogIElFIHN0aWxsIGhhcyBzcGFjZSBsZWZ0IGluIGJvdHRvbSZyaWdodCBpbiBzY2FsZWQgZG93biB2ZXJzaW9uIGJ1dCB3b3JrcyBnb29kIGluIHNjYWxlIHVwIHZlcnNpb24uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogIE5ldywgc3RlcCB3b3VsZCBiZSB0byBtYWtlIHRoZXNlIHZhbHVlcyBwZXIgYnJvd3NlciB0eXBlLiBCdXQgY29tbW9uIGZvciBub3cuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWFyZ2luLWJvdHRvbSI6IE1hdGgubWluKDAsIC0xICogbWFyZ2luSGVpZ2h0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWFyZ2luLXJpZ2h0IjogLTEgKiBtYXJnaW5XaWR0aAogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkKCJib2R5IikuY3NzKHNjYWxlU3R5bGVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiLnBhZ2UiKS5jc3MoIm1hcmdpbiIsIDApOwogICAgICAgICAgICAgICAgICAgICAgICAvKmRpc3BhdGNoIGV2ZW50IHNvIHRoYXQgdG9vbGJhciBhbmQgb3RoZXIgd2lkdGhzIGNhbiBiZSByZS1jb21wdXRlZC4qLwogICAgICAgICAgICAgICAgICAgICAgICAkKHdpbmRvdy5mb3JtQnJpZGdlKS50cmlnZ2VyKCJ4ZmFGb3JtU2NhbGUiKTsKICAgICAgICAgICAgICAgICAgICB9LCAxMDApOwogICAgICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5jbGVhclRpbWVvdXRPbkRlc3Ryb3kodGltZW91dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBJbnZhbGlkYXRlcyB0YWIgaW5kZXhlcyBmb3IgZ2l2ZW4gcGFnZSBudW1iZXIuIE5vdGUgdGhhdCBwYWdlIG51bWJlciBzdGFydHMgd2l0aCBvbmUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbnZhbGlkYXRlVGFiSW5kZXggOiBmdW5jdGlvbihwYWdlTnVtKXsKICAgICAgICAgICAgICAgIGlmKHBhZ2VOdW0gPiAtMSAmJiB0aGlzLnJvb3RTdWJmb3JtVmlldyAmJiB0aGlzLnJvb3RTdWJmb3JtVmlldy5jaGlsZFZpZXdzICl7CiAgICAgICAgICAgICAgICAgICAgdmFyIHBhZ2VWaWV3ID0gdGhpcy5yb290U3ViZm9ybVZpZXcuY2hpbGRWaWV3c1twYWdlTnVtIC0xXTsKICAgICAgICAgICAgICAgICAgICBpZihwYWdlVmlldyl7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VWaWV3LmludmFsaWRhdGVUYWJJbmRleCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9KSgpOwoKICAgIHJvb3QueGZhVmlld1JlZ2lzdHJ5LmluaXRpYWxpemVWaWV3ID0gZnVuY3Rpb24oZmlyc3RQYWdlSHRtbFN0ciwgcmVzdE9mVGhlUGFnZXMpewogICAgICAgIHZhciB2aWV3U3RhcnRUaW1lID0gRGF0ZS5ub3coKTsKICAgICAgICB2YXIgJGZvcm1IdG1sID0gJChmaXJzdFBhZ2VIdG1sU3RyKTsKICAgICAgICB2YXIgb3B0aW9ucyA9IHt9OwogICAgICAgIG9wdGlvbnMucmVzdE9mVGhlUGFnZXMgPSByZXN0T2ZUaGVQYWdlczsKICAgICAgICB2YXIgcGFnaW5nTWFuYWdlciA9IG5ldyB4ZmFsaWIudmlldy5QYWdpbmdNYW5hZ2VyKCk7CiAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLmhvc3QucGFnaW5nTWFuYWdlciA9IHBhZ2luZ01hbmFnZXI7CiAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLiRsYXlvdXQucGFnaW5nTWFuYWdlciA9IHBhZ2luZ01hbmFnZXI7CiAgICAgICAgd2luZG93LnhmYVZpZXdSZWdpc3RyeS5yb290U3ViZm9ybVZpZXcgPSB3aW5kb3cueGZhVmlld1JlZ2lzdHJ5LmNyZWF0ZVZpZXcoJGZvcm1IdG1sLCBvcHRpb25zKTsKICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuaG9zdC5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9SRUZSRVNILHsKICAgICAgICAgICAgaGFuZGxlRXZlbnQ6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgICAgIHN3aXRjaChldm50Lm5hbWUpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX1JFRlJFU0g6CiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy54ZmFWaWV3UmVnaXN0cnkucm9vdFN1YmZvcm1WaWV3LnN5bmNGb3JtTm9kZVRvSHRtbCh0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAvKiBsb2cgYW4gZXJyb3IgbWVzc2FnZSAqLwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgLy9UT0RPOiBtb3ZlIHRoaXMgdG8gTG9nZ2VyCiAgICAgICAgZm9ybUJyaWRnZS52aWV3VGltZSA9IERhdGUubm93KCktdmlld1N0YXJ0VGltZTsKICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmRlYnVnKCJ4ZmFWaWV3IiwiIyMjIyMjIyMjIyMjIyMjIyB0b3RhbCB0aW1lIHRvIGNyZWF0ZSB2aWV3OiIrZm9ybUJyaWRnZS52aWV3VGltZSk7CiAgICAgICAgcmV0dXJuICRmb3JtSHRtbDsKICAgIH07CgogICAgcm9vdC54ZmFWaWV3UmVnaXN0cnkuaW5pdGlhbGl6ZU1vZGVsID0gZnVuY3Rpb24oeGZhSnNvbiwgeGZhRGF0YU1lcmdlRG9ybSwgeGZhbG9jYWxlc2V0LCB4ZmFyZW5kZXJjb250ZXh0KSB7CiAgICAgICAgLy9yZWFkIHJlbmRlckNvbnRleHQgYW5kIG90aGVyIHhmYSBzcGVjaWZpYyBub2RlIGFuZCBwdXNoIGl0CiAgICAgICAgeGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dCA9IHhmYXJlbmRlcmNvbnRleHQ7CgogICAgICAgIGlmKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5nZXRPckVsc2UoeGZhbGliLnJ1bnRpbWUsICJjdXN0b21Qcm9wZXJ0eU1hcC54bWxPbkNsaWVudCIsICIwIikgPT09ICIxIikgewogICAgICAgICAgICBpZih4ZmFsaWIucnVudGltZS5yZW5kZXJDb250ZXh0LmRhdGEpIHsKICAgICAgICAgICAgICAgIGZvcm1CcmlkZ2UucGxheURhdGFYTUwoewogICAgICAgICAgICAgICAgICAgIHhtbERvY3VtZW50IDogeGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dC5kYXRhCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvL3JlYWQgbG9jYWxlc2V0IGFzIHdlbGwKICAgICAgICB4ZmFKc29uLmxvY2FsZVNldCA9IHhmYWxvY2FsZXNldDsKCiAgICAgICAgLy9DcmVhdGUgWGZhIE5vZGUKICAgICAgICB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZU1vZGVsKHhmYUpzb24pOyAgICAgICAvL1RPRE86IEhhbmRsZSB3aW5kb3cgZGVwZW5kZW5jeQoKICAgICAgICBpZih4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmlzTG9nRW5hYmxlZCgieGZhIiwgeGZhbGliLnV0LkxvZ2dlci5wcm90b3R5cGUuVFJBQ0UpKXsKICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci50cmFjZSgieGZhIiwiIyMjIyMjIyMjIyMjIyMjIyB0MCB4ZmFkb206XG4iICsgSlNPTi5zdHJpbmdpZnkoeGZhSnNvbikpOwogICAgICAgIH0KCiAgICAgICAgdmFyIGhhc1Jlc3RvcmVTdGF0ZSA9IGZhbHNlOwogICAgICAgIGlmICh3aW5kb3cuZm9ybUJyaWRnZSAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgdmFyIGxvY2FsU3RvcmFnZSA9IHdpbmRvdy5mb3JtQnJpZGdlLl9nZXRTdG9yYWdlKCk7CiAgICAgICAgICAgIGlmIChsb2NhbFN0b3JhZ2UgJiYgbG9jYWxTdG9yYWdlLnhmYURvbSkgewogICAgICAgICAgICAgICAgeGZhSnNvbiA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLnhmYURvbSk7CiAgICAgICAgICAgICAgICBpZih4ZmFKc29uKSB7CiAgICAgICAgICAgICAgICAgICAgaGFzUmVzdG9yZVN0YXRlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBpZih4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmlzTG9nRW5hYmxlZCgieGZhIiwgeGZhbGliLnV0LkxvZ2dlci5wcm90b3R5cGUuVFJBQ0UpKXsKICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci50cmFjZSgieGZhIiwiIyMjIyMjIyMjIyMjIyMjIyByZXN0b3JlIHhmYWRvbTpcbiIgKyBKU09OLnN0cmluZ2lmeSh4ZmFKc29uKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5ob3N0LnBsYXlKc29uKHhmYUpzb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciB4bWxTdG9yYWdlID0gd2luZG93LmZvcm1CcmlkZ2UuX2dldFhtbFN0b3JhZ2UoKTsKICAgICAgICAgICAgaWYoeG1sU3RvcmFnZSkgewogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci50cmFjZSgieGZhIiwiIyMjIyMjIyMjIyMjIyMjIyByZXN0b3JlIHhtbDpcbiIgKyB4bWxTdG9yYWdlKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLmhvc3QucGxheURhdGFYbWwoeG1sU3RvcmFnZSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZXJyb3IoInhmYSIsICJyZXN0b3JpbmcgeG1sIGZhaWxlZCAiKQogICAgICAgICAgICAgICAgICAgIGlmKF8uaXNGdW5jdGlvbihmb3JtQnJpZGdlLnhtbFN0b3JhZ2UuZXJyb3IpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNPYmogPSBmb3JtQnJpZGdlLl9nZXRSZXN1bHRPYmplY3QoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzT2JqLmFkZE1lc3NhZ2UoMiwgZXhjZXB0aW9uLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUJyaWRnZS54bWxTdG9yYWdlLmVycm9yLmFwcGx5KGZvcm1CcmlkZ2UueG1sU3RvcmFnZS5jb250ZXh0LCBbcmVzT2JqXSkKICAgICAgICAgICAgICAgICAgICAgICAgLy90byBlbnN1cmUgdGhhdCBzdWNjZXNzIGhhbmRsZXIgaXMgbm90IGNhbGxlZCBhZnRlciBmb3JtIHJlbmRlciBmcm9tIEZvcm1CcmlkZ2UuX3hmYUluaXRpYWxpemVkCiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1CcmlkZ2UueG1sU3RvcmFnZS5zdWNjZXNzID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYoIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5nZXRPckVsc2UoeGZhbGliLnJ1bnRpbWUsICJjdXN0b21Qcm9wZXJ0eU1hcC54bWxPbkNsaWVudCIsICIwIikgIT09ICIxIikgewogICAgICAgICAgICBpZighaGFzUmVzdG9yZVN0YXRlICYmIHhmYURhdGFNZXJnZURvcm0pewogICAgICAgICAgICAgICAgaWYoeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5pc0xvZ0VuYWJsZWQoInhmYSIsIHhmYWxpYi51dC5Mb2dnZXIucHJvdG90eXBlLlRSQUNFKSl7CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci50cmFjZSgieGZhIiwiIyMjIyMjIyMjIyMjIyMjIyByZXN0b3JlIHhmYWRvbTpcbiIgKyBKU09OLnN0cmluZ2lmeSh4ZmFEYXRhTWVyZ2VEb3JtKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuaG9zdC5wbGF5SnNvbih4ZmFEYXRhTWVyZ2VEb3JtKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiggeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmdldE9yRWxzZSh4ZmFsaWIucnVudGltZSwgImN1c3RvbVByb3BlcnR5TWFwLmRlc3Ryb3lPbkV4aXQiLCAiMCIpID09PSAiMSIpIHsKICAgICAgICAgICAgJCh3aW5kb3cpLm9uKCJiZWZvcmV1bmxvYWQueGZhIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgZm9ybUJyaWRnZS5kZXN0cm95Rm9ybSh0cnVlKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfTsKCiAgICByb290LnhmYVZpZXdSZWdpc3RyeS5pbml0aWFsaXplRm9ybU9uRG9tUmVhZHkgPSBmdW5jdGlvbigpIHsKICAgICAgICAkKGZ1bmN0aW9uKCQpewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdmFyIGluaXRTdGFydCA9IERhdGUubm93KCk7CiAgICAgICAgICAgICAgICAvL2luaXRpYWxpemUgQWNyb2JhdCBzcGVjaWZpYyBzY3JpcHRzCiAgICAgICAgICAgICAgICBuZXcgeGZhbGliLmFjcm9iYXQuQWNyb2JhdCgpOwogICAgICAgICAgICAgICAgaWYoeGZhbGliLnJ1bnRpbWUueGZhKSB7CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLmZvcm0uX2luaXRpYWxpemUodHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgJCh3aW5kb3cpLnRyaWdnZXIoIlhmYUluaXRpYWxpemVkIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3JtQnJpZGdlLm1vZGVsSW5pdFRpbWUgPSBEYXRlLm5vdygpLWluaXRTdGFydDsKICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuY3VycmVudEZvY3VzID0gbnVsbDsKICAgICAgICAgICAgICAgICQod2luZG93KS5vbigibW91c2Vkb3duLnhmYSIsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIGZvcm1CcmlkZ2UuY2xpY2tlZE9uV2luZG93ID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZXJyb3IoInhmYSIsImVycm9yIGluIGZvcm0uX2luaXRpYWxpemUiKTsKICAgICAgICAgICAgICAgIGlmKGUuc3RhY2spewogICAgICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZXJyb3IoInhmYSIsIGUuc3RhY2spOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9OwoKICAgIC8vVE9ETzogUHV0IGJlbG93IGNhbGwgYXQgcHJvcGVyIHBsYWNlCiAgICB3aW5kb3cuX2luaXRpYWxpemVYZmFMb2FkaW5nID0gZnVuY3Rpb24gKHhmYUpzb24sIHhmYURhdGFNZXJnZURvcm0sIHhmYWxvY2FsZXNldCwgeGZhcmVuZGVyY29udGV4dCwgZmlsZUF0dGFjaG1lbnRNYXApIHsKICAgICAgICB3aW5kb3cuZm9ybUJyaWRnZS5fcG9zdEV4dGVybmFsTWVzc2FnZSh7bmFtZSA6ICJfZm9ybWRvbXN0YXJ0In0pOwogICAgICAgIHZhciB4ZmFNb2RlbExvYWRTdGFydCA9IERhdGUubm93KCk7CiAgICAgICAgdmFyIHhmYVZpZXdSZWdpc3RyeSA9IHdpbmRvdy54ZmFWaWV3UmVnaXN0cnk7CgogICAgICAgIC8vcmVhZCBpbnRlcm5hbCBjc3MgYW5kIGF0dGFjaCBpdCB0byBoZWFkCiAgICAgICAgLy9leGN1c2UgbQogICAgICAgIGlmKCQoJyNmb3JtTG9hZGluZ0RpdicpLmRhdGEoJ2ludGVybmFsY3NzJykpIHsKICAgICAgICAgICAgdmFyIGludGVybmFsY3NzID0gJCgnI2Zvcm1Mb2FkaW5nRGl2JykuZGF0YSgnaW50ZXJuYWxjc3MnKSwKICAgICAgICAgICAgICAgIHN0eWxlVGFnID0gJzxzdHlsZSBpZD0ibWZzdHlsZSIgdHlwZT0idGV4dC9jc3MiPicraW50ZXJuYWxjc3MrJzwvc3R5bGU+JzsKICAgICAgICAgICAgLy9pbnNlcnQgaW50ZXJuYWwgY3NzIGJlZm9yZSB0aGUgZmlyc3Qgc3R5bGUgZWxlbWVudC4KICAgICAgICAgICAgaWYoJCgnaGVhZD5zdHlsZTpmaXJzdCcpLmxlbmd0aCA+IDApCiAgICAgICAgICAgICAgICAkKCdoZWFkPnN0eWxlOmZpcnN0JykuYmVmb3JlKHN0eWxlVGFnKTsKICAgICAgICAgICAgZWxzZSBpZigkKCdoZWFkJykubGVuZ3RoID4gMCkKICAgICAgICAgICAgICAgICQoJ2hlYWQnKS5hcHBlbmQoc3R5bGVUYWcpOwogICAgICAgICAgICBlbHNlIGlmKCQoJ2JvZHknKS5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgJCgnYm9keScpLnByZXBlbmQoc3R5bGVUYWcpOwogICAgICAgICAgICBlbHNlIGlmKCQoJ2h0bWwnKS5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgJCgnaHRtbCcpLnByZXBlbmQoc3R5bGVUYWcpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAkKCcjZm9ybUxvYWRpbmdEaXYnKS5wcmVwZW5kKHN0eWxlVGFnKTsKICAgICAgICB9CgogICAgICAgIHhmYVZpZXdSZWdpc3RyeS5pbml0aWFsaXplTW9kZWwoeGZhSnNvbiwgeGZhRGF0YU1lcmdlRG9ybSwgeGZhbG9jYWxlc2V0LCB4ZmFyZW5kZXJjb250ZXh0KTsKCiAgICAgICAgd2luZG93LmZvcm1CcmlkZ2UuX3Bvc3RFeHRlcm5hbE1lc3NhZ2Uoe25hbWUgOiAiX2xheW91dHN0YXJ0In0pOwogICAgICAgIHhmYVZpZXdSZWdpc3RyeS5fdXNlckNvbmZpZyA9IHdpbmRvdy5mb3JtQnJpZGdlLnVzZXJDb25maWc7CiAgICAgICAgLy9UT0RPOiBtb3ZlIHRoaXMgdG8gTG9nZ2VyCiAgICAgICAgZm9ybUJyaWRnZS5tb2RlbFRpbWUgPSBEYXRlLm5vdygpLXhmYU1vZGVsTG9hZFN0YXJ0OwogICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZGVidWcoInhmYVZpZXciLCIjIyMjIyMjIyMjIyMjIyMjIHRvdGFsIHRpbWUgdG8gbG9hZCB4ZmEgbW9kZWw6IisgZm9ybUJyaWRnZS5tb2RlbFRpbWUpOwoKICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuZm9ybS5tYkluaXRpYWxpemVkID0gZmFsc2U7CgogICAgICAgIHZhciB4ZmFodG1sZG9tID0gICQoJyNmb3JtTG9hZGluZ0RpdicpLmRhdGEoJ3hmYWh0bWxkb20nKTsKICAgICAgICB2YXIgeGZhcmVzdGh0bWxkb20gPSAkKCcjZm9ybUxvYWRpbmdEaXYnKS5kYXRhKCd4ZmFyZXN0aHRtbGRvbScpOwogICAgICAgIHZhciB4ZmFoaWRkZW5vYmpkb20gPSAkKCcjZm9ybUxvYWRpbmdEaXYnKS5kYXRhKCd4ZmFoaWRkZW5vYmpkb20nKTsKCiAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci50cmFjZSgieGZhVmlldyIsIiMjIyMjIyMjIyMjIyMjIyMgeGZhaHRtbGRvbTpcbiIgKyB4ZmFodG1sZG9tKTsKICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLnRyYWNlKCJ4ZmFWaWV3IiwiIyMjIyMjIyMjIyMjIyMjIyB4ZmFyZXN0aHRtbGRvbTpcbiIgKyB4ZmFyZXN0aHRtbGRvbSk7CiAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci50cmFjZSgieGZhVmlldyIsIiMjIyMjIyMjIyMjIyMjIyMgeGZhaGlkZGVub2JqZG9tOlxuIDxhPiIgKyB4ZmFoaWRkZW5vYmpkb20gKyAiPC9hPiIpOwoKICAgICAgICB4ZmFWaWV3UmVnaXN0cnkudGVtcGxhdGVDYWNoZSgpLnNldEhpZGRlbk9ialBhZ2VzKHhmYWhpZGRlbm9iamRvbSk7IC8vY2FjaGUgdGhlIHBhZ2VzIHdpdGggaGlkZGVuIG9iamVjdCBsYXlvdXQKICAgICAgICAkKCcjZm9ybUxvYWRpbmdEaXYnKS5yZXBsYWNlV2l0aCh4ZmFWaWV3UmVnaXN0cnkuaW5pdGlhbGl6ZVZpZXcoIHhmYWh0bWxkb20sIHhmYXJlc3RodG1sZG9tKSk7CgogICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZGVidWcoInhmYVZpZXciLCIjIyMjIyMjIyMjIyMjIyMjIHRvdGFsIHRpbWUgdG8gbG9hZCB4ZmEgbW9kZWwgKyB2aWV3OiIrKERhdGUubm93KCkteGZhTW9kZWxMb2FkU3RhcnQpKTsKICAgICAgICB3aW5kb3cuZm9ybUJyaWRnZS5fcG9zdEV4dGVybmFsTWVzc2FnZSh7bmFtZSA6ICJfbGF5b3V0ZW5kIn0pOwoKICAgICAgICB4ZmFWaWV3UmVnaXN0cnkuaW5pdGlhbGl6ZUZvcm1PbkRvbVJlYWR5KCk7CgogICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5mb3JtLm1iSW5pdGlhbGl6ZWQgPSB0cnVlOwoKICAgICAgICAvLyBSZXN0b3JlIGF0dGFjaG1lbnRzCiAgICAgICAgLy8gV2UgYXJlIHNldHRpbmcgdGhpcyB3aGljaCBpcyBwYXNzZWQgYnkgZmlsZSBhdHRhY2htZW50IHBsdWdpbiB0byAgdGhlIGZpbGVVcGxvYWQgd2lkZ2V0CiAgICAgICAgLy8gYXMgb3B0aW9ucy52YWx1ZSBhbmQgdGhlbiB3aWRnZXQgY3JlYXRpb24gdGFrZXMgcGxhY2UKICAgICAgICBpZih4ZmFsaWIucnVudGltZSkgewogICAgICAgICAgICB4ZmFsaWIucnVudGltZS5maWxlQXR0YWNobWVudCA9IGZpbGVBdHRhY2htZW50TWFwOwogICAgICAgIH0KCiAgICB9OwoKfSkoXywgJCwgeGZhbGliKTsKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTMgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKGZ1bmN0aW9uICgkKSB7CgogICAgZnVuY3Rpb24gaGlnaGxpZ2h0RmllbGRzKCkgewogICAgICAgICQoIi53aWRnZXQ6bm90KC5idXR0b25maWVsZHdpZGdldCwuc3VibWl0ZmllbGR3aWRnZXQpIikKICAgICAgICAgICAgLnRvZ2dsZUNsYXNzKCJ3aWRnZXRCYWNrR3JvdW5kQ29sb3JIaWdobGlnaHQiLCB4ZmFsaWIuZ2xvYmFscy5oaWdobGlnaHQpOwogICAgICAgICQoIi53aWRnZXRbZGF0YS1tYW5kYXRvcnk9J3RydWUnXSwuZXhjbGdyb3VwW2RhdGEtbWFuZGF0b3J5PSd0cnVlJ10iKQogICAgICAgICAgICAudG9nZ2xlQ2xhc3MoIndpZGdldE1hbmRhdG9yeUJvcmRlciIsIHhmYWxpYi5nbG9iYWxzLmhpZ2hsaWdodCk7CiAgICB9CgogICAgZnVuY3Rpb24gX2dldFRvb2xiYXJXaWR0aCgpIHsKICAgICAgICB2YXIgX3Rid2lkdGggPSBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoOwogICAgICAgIGlmICh3aW5kb3cuZm9ybUJyaWRnZSAmJiB3aW5kb3cuZm9ybUJyaWRnZS51c2VyQ29uZmlnWyJ2aWV3cG9ydFdpZHRoIl0pIHsKICAgICAgICAgICAgX3Rid2lkdGggPSB3aW5kb3cuZm9ybUJyaWRnZS51c2VyQ29uZmlnWyJ2aWV3cG9ydFdpZHRoIl07CiAgICAgICAgfQogICAgICAgICQoIi5wYWdlIikuZWFjaChmdW5jdGlvbiAoaSwgb2JqKSB7CiAgICAgICAgICAgIHZhciBleHRlbnQgPSB7fTsKICAgICAgICAgICAgdmFyIHRtcFdpZHRoID0gcGFyc2VJbnQoJCh0aGlzKS53aWR0aCgpKTsKICAgICAgICAgICAgaWYgKHRtcFdpZHRoID4gX3Rid2lkdGgpCiAgICAgICAgICAgICAgICBfdGJ3aWR0aCA9IHRtcFdpZHRoOwogICAgICAgIH0pOwogICAgICAgIHJldHVybiBfdGJ3aWR0aCAtIDI7CiAgICB9CgogICAgZnVuY3Rpb24gX3NldFRvb2xiYXJXaWR0aCgpIHsKICAgICAgICB2YXIgZXh0ZW50ID0ge307CiAgICAgICAgZXh0ZW50WyJ3aWR0aCJdID0gX2dldFRvb2xiYXJXaWR0aCgpOwogICAgICAgICQoIi50b29sYmFyaGVhZGVyIikuY3NzKGV4dGVudCk7CiAgICAgICAgJCgiLnBhZ2luZ2Zvb3RlciIpLmNzcyhleHRlbnQpOwogICAgICAgICQoIi50b29sYmFyaGVhZGVyIikuY3NzKCJsZWZ0IiwgIjBweCIpOwogICAgICAgICQoIi50b29sYmFyaGVhZGVyIikuY3NzKCJyaWdodCIsICIwcHgiKTsKICAgIH0KCiAgICAvL3Nob3cgdG9vbGJhciBidXR0b24gYmFzZWQgb24gbG9nZ2VyLgogICAgd2luZG93LmZvcm1CcmlkZ2UuY29ubmVjdCgKICAgICAgICBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICQoIiNsb2FkaW5nUGFnZSIpLmhpZGUoKTsKICAgICAgICAgICAgaWYgKHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuaXNTZXJ2ZXJMb2dnaW5nRW5hYmxlZCgpKSB7CiAgICAgICAgICAgICAgICAkKCIjdG9vbGJhcmxvZ2dlcmJ0biIpLmNzcyh7ZGlzcGxheTogImlubGluZS1ibG9jayJ9KTsKICAgICAgICAgICAgICAgIC8vcmVnaXN0ZXIgY2xpY2sgaGFuZGxlciB0byBzZW5kIGxvZ3MKICAgICAgICAgICAgICAgICQoIiN0b29sYmFybG9nZ2VyYnRuIikuY2xpY2soZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuc2VydmVySGFuZGxlcigpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICApOwoKICAgICQod2luZG93KS5vbmUoJ3hmYUZpcnN0UGdMYXlvdXRDb21wbGV0ZScsIGZ1bmN0aW9uKCkgewogICAgICAgICQoIiNsb2FkaW5nUGFnZSIpLmhpZGUoKTsKICAgICAgICAkKCIubG9hZGluZ0JvZHkiKS5yZW1vdmVDbGFzcygibG9hZGluZ0JvZHkiKTsKICAgIH0pOwoKICAgIC8vcmVnaXN0ZXIgd2hlbiBkb2N1bWVudCBpcyByZWFkeQogICAgJChmdW5jdGlvbiAoJCkgewoKICAgICAgICB2YXIgdG9vbEJhckluaXQgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIF9zZXRUb29sYmFyV2lkdGgoKTsKICAgICAgICAgICAgaGlnaGxpZ2h0RmllbGRzKCk7CgogICAgICAgICAgICAkKHdpbmRvdykub24oJ3Jlc2l6ZScsIF9zZXRUb29sYmFyV2lkdGgpOyAvLyBCdWcjMzY3MDM5NCA6IGNoYW5nZWQgJCgnYm9keScpIHRvICQod2luZG93KQogICAgICAgICAgICAkKGZvcm1CcmlkZ2UpLm9uKCd4ZmFGb3JtU2NhbGUnLCBfc2V0VG9vbGJhcldpZHRoKTsgLy8gcmVzY2FsZSB0aGUgdG9vbGJhcgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgd2luZG93LnBhcmVudC5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB3aW5kb3cueGZhVmlld1JlZ2lzdHJ5LnNjYWxlRm9ybSgpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZXJyb3IoInhmYSIsICJjb3VsZCBub3QgcmVnaXN0ZXIgb3JpZW50YXRpb25jaGFuZ2UgbGlzdGVuZXIiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJChmb3JtQnJpZGdlKS5vbigieGZhTmV4dFBhZ2VSZW5kZXJlZCB4ZmFMYXlvdXRDb21wbGV0ZSIsIGhpZ2hsaWdodEZpZWxkcyk7CgogICAgICAgICAgICAkKCcjdG9vbGJhcmhpZ2hsaWdodCcpLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi5nbG9iYWxzLmhpZ2hsaWdodCA9ICF4ZmFsaWIuZ2xvYmFscy5oaWdobGlnaHQ7CiAgICAgICAgICAgICAgICBoaWdobGlnaHRGaWVsZHMoKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfTsKICAgICAgICAvL0J1ZyMzNjA1NTU4OiBpUGFkIGRvZXNuJ3QgZ2l2ZSB0aGUgd2lkdGggdmFsdWVzIGluc3RhbnRhbmVvdXNseSwgaGVuY2UgcHV0dGluZyBhIHRpbWUgb3V0IHNpbmNlIHdlIG5lZWQKICAgICAgICAvLyB3aWR0aCBvZiB0aGUgcGFnZXMgcmVuZGVyZWQuCiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmICgheGZhbGliLnJ1bnRpbWUueGZhKSAgLy9CdWcjMzY3MDM3MzogSW4gSUUsIGRvYy5yZWFkeSBpcyBjYWxsZWQgdG9vIGVhcmx5IGZvciBzb21lIGZvcm1zLCBzbyB4ZmFsaWIucnVudGltZS54ZmEgaXMgdW5kZWZpbmVkCiAgICAgICAgICAgICAgICAkKHdpbmRvdykub25lKCd4ZmFGaXJzdFBnTGF5b3V0Q29tcGxldGUnLCB0b29sQmFySW5pdCk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHRvb2xCYXJJbml0KCk7CiAgICAgICAgfSwgMTAwKTsKCgogICAgfSk7Cn0pKCQpOwoKCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKiBCb290c3RyYXA6IG1vZGFsLmpzIHYzLjQuMQogKiBodHRwczovL2dldGJvb3RzdHJhcC5jb20vZG9jcy8zLjQvamF2YXNjcmlwdC8jbW9kYWxzCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKiBDb3B5cmlnaHQgMjAxMS0yMDE5IFR3aXR0ZXIsIEluYy4KICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSkKICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovCgoKKGZ1bmN0aW9uICgkKSB7CiAgICAndXNlIHN0cmljdCc7CgogICAgLy8gTU9EQUwgQ0xBU1MgREVGSU5JVElPTgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PQoKICAgIHZhciBNb2RhbCA9IGZ1bmN0aW9uIChlbGVtZW50LCBvcHRpb25zKSB7CiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucwogICAgICAgIHRoaXMuJGJvZHkgPSAkKGRvY3VtZW50LmJvZHkpCiAgICAgICAgdGhpcy4kZWxlbWVudCA9ICQoZWxlbWVudCkKICAgICAgICB0aGlzLiRkaWFsb2cgPSB0aGlzLiRlbGVtZW50LmZpbmQoJy5tb2RhbC1kaWFsb2cnKQogICAgICAgIHRoaXMuJGJhY2tkcm9wID0gbnVsbAogICAgICAgIHRoaXMuaXNTaG93biA9IG51bGwKICAgICAgICB0aGlzLm9yaWdpbmFsQm9keVBhZCA9IG51bGwKICAgICAgICB0aGlzLnNjcm9sbGJhcldpZHRoID0gMAogICAgICAgIHRoaXMuaWdub3JlQmFja2Ryb3BDbGljayA9IGZhbHNlCiAgICAgICAgdGhpcy5maXhlZENvbnRlbnQgPSAnLm5hdmJhci1maXhlZC10b3AsIC5uYXZiYXItZml4ZWQtYm90dG9tJwoKICAgICAgICBpZiAodGhpcy5vcHRpb25zLnJlbW90ZSkgewogICAgICAgICAgICB0aGlzLiRlbGVtZW50CiAgICAgICAgICAgICAgICAuZmluZCgnLm1vZGFsLWNvbnRlbnQnKQogICAgICAgICAgICAgICAgLmxvYWQodGhpcy5vcHRpb25zLnJlbW90ZSwgJC5wcm94eShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCdsb2FkZWQuYnMubW9kYWwnKQogICAgICAgICAgICAgICAgfSwgdGhpcykpCiAgICAgICAgfQogICAgfQoKICAgIE1vZGFsLlZFUlNJT04gPSAnMy40LjEnCgogICAgTW9kYWwuVFJBTlNJVElPTl9EVVJBVElPTiA9IDMwMAogICAgTW9kYWwuQkFDS0RST1BfVFJBTlNJVElPTl9EVVJBVElPTiA9IDE1MAoKICAgIE1vZGFsLkRFRkFVTFRTID0gewogICAgICAgIGJhY2tkcm9wOiB0cnVlLAogICAgICAgIGtleWJvYXJkOiB0cnVlLAogICAgICAgIHNob3c6IHRydWUKICAgIH0KCiAgICBNb2RhbC5wcm90b3R5cGUudG9nZ2xlID0gZnVuY3Rpb24gKF9yZWxhdGVkVGFyZ2V0KSB7CiAgICAgICAgcmV0dXJuIHRoaXMuaXNTaG93biA/IHRoaXMuaGlkZSgpIDogdGhpcy5zaG93KF9yZWxhdGVkVGFyZ2V0KQogICAgfQoKICAgIE1vZGFsLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKF9yZWxhdGVkVGFyZ2V0KSB7CiAgICAgICAgdmFyIHRoYXQgPSB0aGlzCiAgICAgICAgdmFyIGUgPSAkLkV2ZW50KCdzaG93LmJzLm1vZGFsJywgeyByZWxhdGVkVGFyZ2V0OiBfcmVsYXRlZFRhcmdldCB9KQoKICAgICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoZSkKCiAgICAgICAgaWYgKHRoaXMuaXNTaG93biB8fCBlLmlzRGVmYXVsdFByZXZlbnRlZCgpKSByZXR1cm4KCiAgICAgICAgdGhpcy5pc1Nob3duID0gdHJ1ZQoKICAgICAgICB0aGlzLmNoZWNrU2Nyb2xsYmFyKCkKICAgICAgICB0aGlzLnNldFNjcm9sbGJhcigpCiAgICAgICAgdGhpcy4kYm9keS5hZGRDbGFzcygnbW9kYWwtb3BlbicpCgogICAgICAgIHRoaXMuZXNjYXBlKCkKICAgICAgICB0aGlzLnJlc2l6ZSgpCgogICAgICAgIHRoaXMuJGVsZW1lbnQub24oJ2NsaWNrLmRpc21pc3MuYnMubW9kYWwnLCAnW2RhdGEtZGlzbWlzcz0ibW9kYWwiXScsICQucHJveHkodGhpcy5oaWRlLCB0aGlzKSkKCiAgICAgICAgdGhpcy4kZGlhbG9nLm9uKCdtb3VzZWRvd24uZGlzbWlzcy5icy5tb2RhbCcsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdGhhdC4kZWxlbWVudC5vbmUoJ21vdXNldXAuZGlzbWlzcy5icy5tb2RhbCcsIGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgICAgICBpZiAoJChlLnRhcmdldCkuaXModGhhdC4kZWxlbWVudCkpIHRoYXQuaWdub3JlQmFja2Ryb3BDbGljayA9IHRydWUKICAgICAgICAgICAgfSkKICAgICAgICB9KQoKICAgICAgICB0aGlzLmJhY2tkcm9wKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHRyYW5zaXRpb24gPSAkLnN1cHBvcnQudHJhbnNpdGlvbiAmJiB0aGF0LiRlbGVtZW50Lmhhc0NsYXNzKCdmYWRlJykKCiAgICAgICAgICAgIGlmICghdGhhdC4kZWxlbWVudC5wYXJlbnQoKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHRoYXQuJGVsZW1lbnQuYXBwZW5kVG8odGhhdC4kYm9keSkgLy8gZG9uJ3QgbW92ZSBtb2RhbHMgZG9tIHBvc2l0aW9uCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoYXQuJGVsZW1lbnQKICAgICAgICAgICAgICAgIC5zaG93KCkKICAgICAgICAgICAgICAgIC5zY3JvbGxUb3AoMCkKCiAgICAgICAgICAgIHRoYXQuYWRqdXN0RGlhbG9nKCkKCiAgICAgICAgICAgIGlmICh0cmFuc2l0aW9uKSB7CiAgICAgICAgICAgICAgICB0aGF0LiRlbGVtZW50WzBdLm9mZnNldFdpZHRoIC8vIGZvcmNlIHJlZmxvdwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGF0LiRlbGVtZW50LmFkZENsYXNzKCdpbicpCgogICAgICAgICAgICB0aGF0LmVuZm9yY2VGb2N1cygpCgogICAgICAgICAgICB2YXIgZSA9ICQuRXZlbnQoJ3Nob3duLmJzLm1vZGFsJywgeyByZWxhdGVkVGFyZ2V0OiBfcmVsYXRlZFRhcmdldCB9KQoKICAgICAgICAgICAgdHJhbnNpdGlvbiA/CiAgICAgICAgICAgICAgICB0aGF0LiRkaWFsb2cgLy8gd2FpdCBmb3IgbW9kYWwgdG8gc2xpZGUgaW4KICAgICAgICAgICAgICAgICAgICAub25lKCdic1RyYW5zaXRpb25FbmQnLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuJGVsZW1lbnQudHJpZ2dlcignZm9jdXMnKS50cmlnZ2VyKGUpCiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICAgICAuZW11bGF0ZVRyYW5zaXRpb25FbmQoTW9kYWwuVFJBTlNJVElPTl9EVVJBVElPTikgOgogICAgICAgICAgICAgICAgdGhhdC4kZWxlbWVudC50cmlnZ2VyKCdmb2N1cycpLnRyaWdnZXIoZSkKICAgICAgICB9KQogICAgfQoKICAgIE1vZGFsLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKGUpIHsKICAgICAgICBpZiAoZSkgZS5wcmV2ZW50RGVmYXVsdCgpCgogICAgICAgIGUgPSAkLkV2ZW50KCdoaWRlLmJzLm1vZGFsJykKCiAgICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKGUpCgogICAgICAgIGlmICghdGhpcy5pc1Nob3duIHx8IGUuaXNEZWZhdWx0UHJldmVudGVkKCkpIHJldHVybgoKICAgICAgICB0aGlzLmlzU2hvd24gPSBmYWxzZQoKICAgICAgICB0aGlzLmVzY2FwZSgpCiAgICAgICAgdGhpcy5yZXNpemUoKQoKICAgICAgICAkKGRvY3VtZW50KS5vZmYoJ2ZvY3VzaW4uYnMubW9kYWwnKQoKICAgICAgICB0aGlzLiRlbGVtZW50CiAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnaW4nKQogICAgICAgICAgICAub2ZmKCdjbGljay5kaXNtaXNzLmJzLm1vZGFsJykKICAgICAgICAgICAgLm9mZignbW91c2V1cC5kaXNtaXNzLmJzLm1vZGFsJykKCiAgICAgICAgdGhpcy4kZGlhbG9nLm9mZignbW91c2Vkb3duLmRpc21pc3MuYnMubW9kYWwnKQoKICAgICAgICAkLnN1cHBvcnQudHJhbnNpdGlvbiAmJiB0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdmYWRlJykgPwogICAgICAgICAgICB0aGlzLiRlbGVtZW50CiAgICAgICAgICAgICAgICAub25lKCdic1RyYW5zaXRpb25FbmQnLCAkLnByb3h5KHRoaXMuaGlkZU1vZGFsLCB0aGlzKSkKICAgICAgICAgICAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChNb2RhbC5UUkFOU0lUSU9OX0RVUkFUSU9OKSA6CiAgICAgICAgICAgIHRoaXMuaGlkZU1vZGFsKCkKICAgIH0KCiAgICBNb2RhbC5wcm90b3R5cGUuZW5mb3JjZUZvY3VzID0gZnVuY3Rpb24gKCkgewogICAgICAgICQoZG9jdW1lbnQpCiAgICAgICAgICAgIC5vZmYoJ2ZvY3VzaW4uYnMubW9kYWwnKSAvLyBndWFyZCBhZ2FpbnN0IGluZmluaXRlIGZvY3VzIGxvb3AKICAgICAgICAgICAgLm9uKCdmb2N1c2luLmJzLm1vZGFsJywgJC5wcm94eShmdW5jdGlvbiAoZSkgewogICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50ICE9PSBlLnRhcmdldCAmJgogICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRbMF0gIT09IGUudGFyZ2V0ICYmCiAgICAgICAgICAgICAgICAgICAgIXRoaXMuJGVsZW1lbnQuaGFzKGUudGFyZ2V0KS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ2ZvY3VzJykKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcykpCiAgICB9CgogICAgTW9kYWwucHJvdG90eXBlLmVzY2FwZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAodGhpcy5pc1Nob3duICYmIHRoaXMub3B0aW9ucy5rZXlib2FyZCkgewogICAgICAgICAgICB0aGlzLiRlbGVtZW50Lm9uKCdrZXlkb3duLmRpc21pc3MuYnMubW9kYWwnLCAkLnByb3h5KGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgICAgICBlLndoaWNoID09IDI3ICYmIHRoaXMuaGlkZSgpCiAgICAgICAgICAgIH0sIHRoaXMpKQogICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuaXNTaG93bikgewogICAgICAgICAgICB0aGlzLiRlbGVtZW50Lm9mZigna2V5ZG93bi5kaXNtaXNzLmJzLm1vZGFsJykKICAgICAgICB9CiAgICB9CgogICAgTW9kYWwucHJvdG90eXBlLnJlc2l6ZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAodGhpcy5pc1Nob3duKSB7CiAgICAgICAgICAgICQod2luZG93KS5vbigncmVzaXplLmJzLm1vZGFsJywgJC5wcm94eSh0aGlzLmhhbmRsZVVwZGF0ZSwgdGhpcykpCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJCh3aW5kb3cpLm9mZigncmVzaXplLmJzLm1vZGFsJykKICAgICAgICB9CiAgICB9CgogICAgTW9kYWwucHJvdG90eXBlLmhpZGVNb2RhbCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgdGhhdCA9IHRoaXMKICAgICAgICB0aGlzLiRlbGVtZW50LmhpZGUoKQogICAgICAgIHRoaXMuYmFja2Ryb3AoZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGF0LiRib2R5LnJlbW92ZUNsYXNzKCdtb2RhbC1vcGVuJykKICAgICAgICAgICAgdGhhdC5yZXNldEFkanVzdG1lbnRzKCkKICAgICAgICAgICAgdGhhdC5yZXNldFNjcm9sbGJhcigpCiAgICAgICAgICAgIHRoYXQuJGVsZW1lbnQudHJpZ2dlcignaGlkZGVuLmJzLm1vZGFsJykKICAgICAgICB9KQogICAgfQoKICAgIE1vZGFsLnByb3RvdHlwZS5yZW1vdmVCYWNrZHJvcCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLiRiYWNrZHJvcCAmJiB0aGlzLiRiYWNrZHJvcC5yZW1vdmUoKQogICAgICAgIHRoaXMuJGJhY2tkcm9wID0gbnVsbAogICAgfQoKICAgIE1vZGFsLnByb3RvdHlwZS5iYWNrZHJvcCA9IGZ1bmN0aW9uIChjYWxsYmFjaykgewogICAgICAgIHZhciB0aGF0ID0gdGhpcwogICAgICAgIHZhciBhbmltYXRlID0gdGhpcy4kZWxlbWVudC5oYXNDbGFzcygnZmFkZScpID8gJ2ZhZGUnIDogJycKCiAgICAgICAgaWYgKHRoaXMuaXNTaG93biAmJiB0aGlzLm9wdGlvbnMuYmFja2Ryb3ApIHsKICAgICAgICAgICAgdmFyIGRvQW5pbWF0ZSA9ICQuc3VwcG9ydC50cmFuc2l0aW9uICYmIGFuaW1hdGUKCiAgICAgICAgICAgIHRoaXMuJGJhY2tkcm9wID0gJChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSkKICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnbW9kYWwtYmFja2Ryb3AgJyArIGFuaW1hdGUpCiAgICAgICAgICAgICAgICAuYXBwZW5kVG8odGhpcy4kYm9keSkKCiAgICAgICAgICAgIHRoaXMuJGVsZW1lbnQub24oJ2NsaWNrLmRpc21pc3MuYnMubW9kYWwnLCAkLnByb3h5KGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5pZ25vcmVCYWNrZHJvcENsaWNrKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5pZ25vcmVCYWNrZHJvcENsaWNrID0gZmFsc2UKICAgICAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChlLnRhcmdldCAhPT0gZS5jdXJyZW50VGFyZ2V0KSByZXR1cm4KICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5iYWNrZHJvcCA9PSAnc3RhdGljJwogICAgICAgICAgICAgICAgICAgID8gdGhpcy4kZWxlbWVudFswXS5mb2N1cygpCiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLmhpZGUoKQogICAgICAgICAgICB9LCB0aGlzKSkKCiAgICAgICAgICAgIGlmIChkb0FuaW1hdGUpIHRoaXMuJGJhY2tkcm9wWzBdLm9mZnNldFdpZHRoIC8vIGZvcmNlIHJlZmxvdwoKICAgICAgICAgICAgdGhpcy4kYmFja2Ryb3AuYWRkQ2xhc3MoJ2luJykKCiAgICAgICAgICAgIGlmICghY2FsbGJhY2spIHJldHVybgoKICAgICAgICAgICAgZG9BbmltYXRlID8KICAgICAgICAgICAgICAgIHRoaXMuJGJhY2tkcm9wCiAgICAgICAgICAgICAgICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgY2FsbGJhY2spCiAgICAgICAgICAgICAgICAgICAgLmVtdWxhdGVUcmFuc2l0aW9uRW5kKE1vZGFsLkJBQ0tEUk9QX1RSQU5TSVRJT05fRFVSQVRJT04pIDoKICAgICAgICAgICAgICAgIGNhbGxiYWNrKCkKCiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5pc1Nob3duICYmIHRoaXMuJGJhY2tkcm9wKSB7CiAgICAgICAgICAgIHRoaXMuJGJhY2tkcm9wLnJlbW92ZUNsYXNzKCdpbicpCgogICAgICAgICAgICB2YXIgY2FsbGJhY2tSZW1vdmUgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGF0LnJlbW92ZUJhY2tkcm9wKCkKICAgICAgICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCkKICAgICAgICAgICAgfQogICAgICAgICAgICAkLnN1cHBvcnQudHJhbnNpdGlvbiAmJiB0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdmYWRlJykgPwogICAgICAgICAgICAgICAgdGhpcy4kYmFja2Ryb3AKICAgICAgICAgICAgICAgICAgICAub25lKCdic1RyYW5zaXRpb25FbmQnLCBjYWxsYmFja1JlbW92ZSkKICAgICAgICAgICAgICAgICAgICAuZW11bGF0ZVRyYW5zaXRpb25FbmQoTW9kYWwuQkFDS0RST1BfVFJBTlNJVElPTl9EVVJBVElPTikgOgogICAgICAgICAgICAgICAgY2FsbGJhY2tSZW1vdmUoKQoKICAgICAgICB9IGVsc2UgaWYgKGNhbGxiYWNrKSB7CiAgICAgICAgICAgIGNhbGxiYWNrKCkKICAgICAgICB9CiAgICB9CgogICAgLy8gdGhlc2UgZm9sbG93aW5nIG1ldGhvZHMgYXJlIHVzZWQgdG8gaGFuZGxlIG92ZXJmbG93aW5nIG1vZGFscwoKICAgIE1vZGFsLnByb3RvdHlwZS5oYW5kbGVVcGRhdGUgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdGhpcy5hZGp1c3REaWFsb2coKQogICAgfQoKICAgIE1vZGFsLnByb3RvdHlwZS5hZGp1c3REaWFsb2cgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIG1vZGFsSXNPdmVyZmxvd2luZyA9IHRoaXMuJGVsZW1lbnRbMF0uc2Nyb2xsSGVpZ2h0ID4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodAoKICAgICAgICB0aGlzLiRlbGVtZW50LmNzcyh7CiAgICAgICAgICAgIHBhZGRpbmdMZWZ0OiAhdGhpcy5ib2R5SXNPdmVyZmxvd2luZyAmJiBtb2RhbElzT3ZlcmZsb3dpbmcgPyB0aGlzLnNjcm9sbGJhcldpZHRoIDogJycsCiAgICAgICAgICAgIHBhZGRpbmdSaWdodDogdGhpcy5ib2R5SXNPdmVyZmxvd2luZyAmJiAhbW9kYWxJc092ZXJmbG93aW5nID8gdGhpcy5zY3JvbGxiYXJXaWR0aCA6ICcnCiAgICAgICAgfSkKICAgIH0KCiAgICBNb2RhbC5wcm90b3R5cGUucmVzZXRBZGp1c3RtZW50cyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLiRlbGVtZW50LmNzcyh7CiAgICAgICAgICAgIHBhZGRpbmdMZWZ0OiAnJywKICAgICAgICAgICAgcGFkZGluZ1JpZ2h0OiAnJwogICAgICAgIH0pCiAgICB9CgogICAgTW9kYWwucHJvdG90eXBlLmNoZWNrU2Nyb2xsYmFyID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBmdWxsV2luZG93V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aAogICAgICAgIGlmICghZnVsbFdpbmRvd1dpZHRoKSB7IC8vIHdvcmthcm91bmQgZm9yIG1pc3Npbmcgd2luZG93LmlubmVyV2lkdGggaW4gSUU4CiAgICAgICAgICAgIHZhciBkb2N1bWVudEVsZW1lbnRSZWN0ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpCiAgICAgICAgICAgIGZ1bGxXaW5kb3dXaWR0aCA9IGRvY3VtZW50RWxlbWVudFJlY3QucmlnaHQgLSBNYXRoLmFicyhkb2N1bWVudEVsZW1lbnRSZWN0LmxlZnQpCiAgICAgICAgfQogICAgICAgIHRoaXMuYm9keUlzT3ZlcmZsb3dpbmcgPSBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoIDwgZnVsbFdpbmRvd1dpZHRoCiAgICAgICAgdGhpcy5zY3JvbGxiYXJXaWR0aCA9IHRoaXMubWVhc3VyZVNjcm9sbGJhcigpCiAgICB9CgogICAgTW9kYWwucHJvdG90eXBlLnNldFNjcm9sbGJhciA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgYm9keVBhZCA9IHBhcnNlSW50KCh0aGlzLiRib2R5LmNzcygncGFkZGluZy1yaWdodCcpIHx8IDApLCAxMCkKICAgICAgICB0aGlzLm9yaWdpbmFsQm9keVBhZCA9IGRvY3VtZW50LmJvZHkuc3R5bGUucGFkZGluZ1JpZ2h0IHx8ICcnCiAgICAgICAgdmFyIHNjcm9sbGJhcldpZHRoID0gdGhpcy5zY3JvbGxiYXJXaWR0aAogICAgICAgIGlmICh0aGlzLmJvZHlJc092ZXJmbG93aW5nKSB7CiAgICAgICAgICAgIHRoaXMuJGJvZHkuY3NzKCdwYWRkaW5nLXJpZ2h0JywgYm9keVBhZCArIHNjcm9sbGJhcldpZHRoKQogICAgICAgICAgICAkKHRoaXMuZml4ZWRDb250ZW50KS5lYWNoKGZ1bmN0aW9uIChpbmRleCwgZWxlbWVudCkgewogICAgICAgICAgICAgICAgdmFyIGFjdHVhbFBhZGRpbmcgPSBlbGVtZW50LnN0eWxlLnBhZGRpbmdSaWdodAogICAgICAgICAgICAgICAgdmFyIGNhbGN1bGF0ZWRQYWRkaW5nID0gJChlbGVtZW50KS5jc3MoJ3BhZGRpbmctcmlnaHQnKQogICAgICAgICAgICAgICAgJChlbGVtZW50KQogICAgICAgICAgICAgICAgICAgIC5kYXRhKCdwYWRkaW5nLXJpZ2h0JywgYWN0dWFsUGFkZGluZykKICAgICAgICAgICAgICAgICAgICAuY3NzKCdwYWRkaW5nLXJpZ2h0JywgcGFyc2VGbG9hdChjYWxjdWxhdGVkUGFkZGluZykgKyBzY3JvbGxiYXJXaWR0aCArICdweCcpCiAgICAgICAgICAgIH0pCiAgICAgICAgfQogICAgfQoKICAgIE1vZGFsLnByb3RvdHlwZS5yZXNldFNjcm9sbGJhciA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLiRib2R5LmNzcygncGFkZGluZy1yaWdodCcsIHRoaXMub3JpZ2luYWxCb2R5UGFkKQogICAgICAgICQodGhpcy5maXhlZENvbnRlbnQpLmVhY2goZnVuY3Rpb24gKGluZGV4LCBlbGVtZW50KSB7CiAgICAgICAgICAgIHZhciBwYWRkaW5nID0gJChlbGVtZW50KS5kYXRhKCdwYWRkaW5nLXJpZ2h0JykKICAgICAgICAgICAgJChlbGVtZW50KS5yZW1vdmVEYXRhKCdwYWRkaW5nLXJpZ2h0JykKICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5wYWRkaW5nUmlnaHQgPSBwYWRkaW5nID8gcGFkZGluZyA6ICcnCiAgICAgICAgfSkKICAgIH0KCiAgICBNb2RhbC5wcm90b3R5cGUubWVhc3VyZVNjcm9sbGJhciA9IGZ1bmN0aW9uICgpIHsgLy8gdGh4IHdhbHNoCiAgICAgICAgdmFyIHNjcm9sbERpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpCiAgICAgICAgc2Nyb2xsRGl2LmNsYXNzTmFtZSA9ICdtb2RhbC1zY3JvbGxiYXItbWVhc3VyZScKICAgICAgICB0aGlzLiRib2R5LmFwcGVuZChzY3JvbGxEaXYpCiAgICAgICAgdmFyIHNjcm9sbGJhcldpZHRoID0gc2Nyb2xsRGl2Lm9mZnNldFdpZHRoIC0gc2Nyb2xsRGl2LmNsaWVudFdpZHRoCiAgICAgICAgdGhpcy4kYm9keVswXS5yZW1vdmVDaGlsZChzY3JvbGxEaXYpCiAgICAgICAgcmV0dXJuIHNjcm9sbGJhcldpZHRoCiAgICB9CgoKICAgIC8vIE1PREFMIFBMVUdJTiBERUZJTklUSU9OCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PQoKICAgIGZ1bmN0aW9uIFBsdWdpbihvcHRpb24sIF9yZWxhdGVkVGFyZ2V0KSB7CiAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciAkdGhpcyA9ICQodGhpcykKICAgICAgICAgICAgdmFyIGRhdGEgPSAkdGhpcy5kYXRhKCdicy5tb2RhbCcpCiAgICAgICAgICAgIHZhciBvcHRpb25zID0gJC5leHRlbmQoe30sIE1vZGFsLkRFRkFVTFRTLCAkdGhpcy5kYXRhKCksIHR5cGVvZiBvcHRpb24gPT0gJ29iamVjdCcgJiYgb3B0aW9uKQoKICAgICAgICAgICAgaWYgKCFkYXRhKSAkdGhpcy5kYXRhKCdicy5tb2RhbCcsIChkYXRhID0gbmV3IE1vZGFsKHRoaXMsIG9wdGlvbnMpKSkKICAgICAgICAgICAgaWYgKHR5cGVvZiBvcHRpb24gPT0gJ3N0cmluZycpIGRhdGFbb3B0aW9uXShfcmVsYXRlZFRhcmdldCkKICAgICAgICAgICAgZWxzZSBpZiAob3B0aW9ucy5zaG93KSBkYXRhLnNob3coX3JlbGF0ZWRUYXJnZXQpCiAgICAgICAgfSkKICAgIH0KCiAgICB2YXIgb2xkID0gJC5mbi5tb2RhbAoKICAgICQuZm4ubW9kYWwgPSBQbHVnaW4KICAgICQuZm4ubW9kYWwuQ29uc3RydWN0b3IgPSBNb2RhbAoKCiAgICAvLyBNT0RBTCBOTyBDT05GTElDVAogICAgLy8gPT09PT09PT09PT09PT09PT0KCiAgICAkLmZuLm1vZGFsLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgJC5mbi5tb2RhbCA9IG9sZAogICAgICAgIHJldHVybiB0aGlzCiAgICB9CgoKICAgIC8vIE1PREFMIERBVEEtQVBJCiAgICAvLyA9PT09PT09PT09PT09PQoKICAgICQoZG9jdW1lbnQpLm9uKCdjbGljay5icy5tb2RhbC5kYXRhLWFwaScsICdbZGF0YS10b2dnbGU9Im1vZGFsIl0nLCBmdW5jdGlvbiAoZSkgewogICAgICAgIHZhciAkdGhpcyA9ICQodGhpcykKICAgICAgICB2YXIgaHJlZiA9ICR0aGlzLmF0dHIoJ2hyZWYnKQogICAgICAgIHZhciB0YXJnZXQgPSAkdGhpcy5hdHRyKCdkYXRhLXRhcmdldCcpIHx8CiAgICAgICAgICAgIChocmVmICYmIGhyZWYucmVwbGFjZSgvLiooPz0jW15cc10rJCkvLCAnJykpIC8vIHN0cmlwIGZvciBpZTcKCiAgICAgICAgdmFyICR0YXJnZXQgPSAkKGRvY3VtZW50KS5maW5kKHRhcmdldCkKICAgICAgICB2YXIgb3B0aW9uID0gJHRhcmdldC5kYXRhKCdicy5tb2RhbCcpID8gJ3RvZ2dsZScgOiAkLmV4dGVuZCh7IHJlbW90ZTogIS8jLy50ZXN0KGhyZWYpICYmIGhyZWYgfSwgJHRhcmdldC5kYXRhKCksICR0aGlzLmRhdGEoKSkKCiAgICAgICAgaWYgKCR0aGlzLmlzKCdhJykpIGUucHJldmVudERlZmF1bHQoKQoKICAgICAgICAkdGFyZ2V0Lm9uZSgnc2hvdy5icy5tb2RhbCcsIGZ1bmN0aW9uIChzaG93RXZlbnQpIHsKICAgICAgICAgICAgaWYgKHNob3dFdmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSkgcmV0dXJuIC8vIG9ubHkgcmVnaXN0ZXIgZm9jdXMgcmVzdG9yZXIgaWYgbW9kYWwgd2lsbCBhY3R1YWxseSBnZXQgc2hvd24KICAgICAgICAgICAgJHRhcmdldC5vbmUoJ2hpZGRlbi5icy5tb2RhbCcsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICR0aGlzLmlzKCc6dmlzaWJsZScpICYmICR0aGlzLnRyaWdnZXIoJ2ZvY3VzJykKICAgICAgICAgICAgfSkKICAgICAgICB9KQogICAgICAgIFBsdWdpbi5jYWxsKCR0YXJnZXQsIG9wdGlvbiwgdGhpcykKICAgIH0pCgp9KSgkKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX18KICoKICogIENvcHlyaWdodCAyMDE0IEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiBzdXBwbGllcnMgYW5kIG1heSBiZSBjb3ZlcmVkIGJ5IFUuUy4gYW5kIEZvcmVpZ24gUGF0ZW50cywKICogcGF0ZW50cyBpbiBwcm9jZXNzLCBhbmQgYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgokKGZ1bmN0aW9uICgkKSB7CiAgICAvLyAkZG9jLnJlYWR5IGZvciBqcXVlcnkgMS44IGNhdXNpbmcgaXNzdWVzIGZvciBJRSBzbwogICAgLy8gZG9pbmcgd2lkZ2V0IGluaXRpYWxpemF0aW9uIG9uIGNvbm5lY3QKIHdpbmRvdy5mb3JtQnJpZGdlLmNvbm5lY3QoZnVuY3Rpb24gKCkgewogICAgIHZhciBtZXRob2QgPSB7CiAgICAgICAgIGluaXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgIHZhciAkcGx1Z0ZpbGVXaWRnZXREb20gPSAkKCdbZGF0YS1maWxld2lkZ2V0PSJ0cnVlIl0nKSwKICAgICAgICAgICAgICAgICBvcHRpb25zLAogICAgICAgICAgICAgICAgICRmaWxlV2lkZ2V0LAogICAgICAgICAgICAgICAgICRpbnB1dFdpZGdldCwKICAgICAgICAgICAgICAgICAkYnV0dG9uV2lkZ2V0LAogICAgICAgICAgICAgICAgICRsaXN0V2lkZ2V0LAogICAgICAgICAgICAgICAgIHdpZGdldE5hbWUsCiAgICAgICAgICAgICAgICAgbXVsdGlTZWxlY3QgPSB0cnVlLAogICAgICAgICAgICAgICAgIG9wdGlvbnNUb1dpZGdldDsKICAgICAgICAgICAgICAgICBvcHRpb25zID0gJHBsdWdGaWxlV2lkZ2V0RG9tLmRhdGEoIm9wdGlvbnMiKSB8fCB7fTsKICAgICAgICAgICAgICAgICBvcHRpb25zLmJ1dHRvblRleHQgPSBvcHRpb25zLmJ1dHRvblRleHQgfHwgIkF0dGFjaCI7CiAgICAgICAgICAgICAgICAgb3B0aW9ucy5hY2NlcHQgPSBvcHRpb25zLmFjY2VwdCB8fCAiYXVkaW8vKiwgdmlkZW8vKiwgaW1hZ2UvKiwgdGV4dC8qLCBhcHBsaWNhdGlvbi9wZGYiOwogICAgICAgICAgICAgICAgICRmaWxlV2lkZ2V0ID0gJCgiPGRpdj48L2Rpdj4iKS5hZGRDbGFzcygiZ3VpZGVGaWVsZFdpZGdldCIpLmFkZENsYXNzKCJmaWxlVXBsb2FkIikuYXR0cigic3R5bGUiLCIiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJ0aXRsZSIsIHhmYWxpYi5sb2NhbGUuU3RyaW5nc1siQXR0YWNoIl0pOwoKICAgICAgICAgICAgICAgICAkaW5wdXRXaWRnZXQgPSAkKCI8aW5wdXQvPiIpLmF0dHIoImlkIiwgImZpbGVVcGxvYWRfd2lkZ2V0IikuYXR0cigibmFtZSIsICJmaWxlVXBsb2FkIikKICAgICAgICAgICAgICAgICAgICAgLmF0dHIoInR5cGUiLCJmaWxlIikKICAgICAgICAgICAgICAgICAgICAgLmF0dHIoInN0eWxlIiwgIiIpCiAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJhY2NlcHQiLG9wdGlvbnMuYWNjZXB0KQogICAgICAgICAgICAgICAgICAgICAuYXR0cigidGFiaW5kZXgiLCAiLTEiKQogICAgICAgICAgICAgICAgICAgICAuYXR0cigiY2FwdHVyZSIsIiIpOwoKICAgICAgICAgICAgICAgICAkYnV0dG9uV2lkZ2V0ID0gJCgiPGJ1dHRvbj48L2J1dHRvbj4iKS5hZGRDbGFzcygiYnV0dG9uLWRlZmF1bHQiKS5hZGRDbGFzcygiYnV0dG9uLW1lZGl1bSIpCiAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygiZ3VpZGUtZnUtYXR0YWNoLWJ1dHRvbiIpCiAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJ0eXBlIiwgImZpbGUiKQogICAgICAgICAgICAgICAgICAgICAuaHRtbChvcHRpb25zLmJ1dHRvblRleHQpOwoKICAgICAgICAgICAgICAgICAkbGlzdFdpZGdldD0gJCgnPHVsPjwvdWw+JykuYWRkQ2xhc3MoImd1aWRlLWZ1LWZpbGVJdGVtTGlzdCIpOwogICAgICAgICAgICAgICAgICRmaWxlV2lkZ2V0LmFwcGVuZCgkaW5wdXRXaWRnZXQpLmFwcGVuZCgkYnV0dG9uV2lkZ2V0KS5hcHBlbmQoJGxpc3RXaWRnZXQpOwogICAgICAgICAgICAgICAgICRmaWxlV2lkZ2V0LmFwcGVuZFRvKCRwbHVnRmlsZVdpZGdldERvbSk7CiAgICAgICAgICAgICAgICAgd2lkZ2V0TmFtZSA9IG9wdGlvbnMud2lkZ2V0TmFtZSB8fCAiZmlsZVVwbG9hZCI7CiAgICAgICAgICAgICAgICAgLy8gbXVsdGlTZWxlY3QgaXMgZXhwZWN0ZWQgdG8gYmUgYm9vbGVhbiBieSB3aWRnZXQKICAgICAgICAgICAgICAgICAvLyBBbmQgdGhlIHByb2ZpbGUgbm9kZSBwYXNzZXMgaXQgYXMgc3RyaW5nCiAgICAgICAgICAgICAgICAgLy8gYW5kIHdpZGdldC5qc3AgcGFzc2VzIHRoZSBzYW1lIGFzIGJvb2xlYW4KICAgICAgICAgICAgICAgICAvLyAgb3B0aW9ucy5tdWx0aVNlbGVjdCBjYW4gYmUgInRydWUiICwgICJmYWxzZSIKICAgICAgICAgICAgICAgICAvLyBvciBjYW4gYmUgdHJ1ZSAsICBmYWxzZQogICAgICAgICAgICAgICAgIC8vIG9yIGl0IGNhbiBiZSB1bmRlZmluZWQgKHdoZW4gaW5pdGlhbGl6aW5nICBtdWx0aVNlbGVjdCAgdG8gdHJ1ZSBkZWZpbmVzIGRlZmF1bHQgYmVoYXZpb3VyICkKICAgICAgICAgICAgICAgICBpZihfLmlzQm9vbGVhbihvcHRpb25zLm11bHRpU2VsZWN0KSkgewogICAgICAgICAgICAgICAgICAgICBtdWx0aVNlbGVjdCA9IG9wdGlvbnMubXVsdGlTZWxlY3Q7CiAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChfLmlzU3RyaW5nKG9wdGlvbnMubXVsdGlTZWxlY3QpKSB7CiAgICAgICAgICAgICAgICAgICAgIG11bHRpU2VsZWN0ID0gb3B0aW9ucy5tdWx0aVNlbGVjdC50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZSc7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIG9wdGlvbnNUb1dpZGdldCA9ICAgewogICAgICAgICAgICAgICAgICAgICBidXR0b25UZXh0ICA6IG9wdGlvbnMuYnV0dG9uVGV4dCB8fCAiQXR0YWNoIiwKICAgICAgICAgICAgICAgICAgICAgbXVsdGlTZWxlY3QgOiAgbXVsdGlTZWxlY3QsCiAgICAgICAgICAgICAgICAgICAgIGZpbGVTaXplTGltaXQgOiBvcHRpb25zLmZpbGVTaXplTGltaXQgfHwgIjIiLAogICAgICAgICAgICAgICAgICAgICBidXR0b25DbGFzcyA6IG9wdGlvbnMuYnV0dG9uQ2xhc3MgfHwgImJ1dHRvbi5ndWlkZS1mdS1hdHRhY2gtYnV0dG9uIiwKICAgICAgICAgICAgICAgICAgICAgZmlsZUl0ZW1MaXN0Q2xhc3MgOiBvcHRpb25zLmZpbGVJdGVtTGlzdENsYXNzfHwgInVsLmd1aWRlLWZ1LWZpbGVJdGVtTGlzdCIsCiAgICAgICAgICAgICAgICAgICAgIGlmcmFtZUNvbnRhaW5lcjogb3B0aW9ucy5pZnJhbWVDb250YWluZXIgfHwgImJvZHkjZm9ybUJvZHkiLAogICAgICAgICAgICAgICAgICAgICBzaG93Q29tbWVudCA6ICBvcHRpb25zLnNob3dDb21tZW50IHx8IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICBfdXVpZEdlbmVyYXRvcjogZnVuY3Rpb24gKCkgeyByZXR1cm4gZm9ybUJyaWRnZS5fZ2V0VVVJRC5hcHBseSh0aGlzKTsgfSwKICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMudmFsdWUgfHwgeGZhbGliLnJ1bnRpbWUuZmlsZUF0dGFjaG1lbnQgLAogICAgICAgICAgICAgICAgICAgICBfZmlsZVBhdGg6IG9wdGlvbnMuX2ZpbGVQYXRoIHx8ICIvdG1wL2ZkL3hmYWZvcm5zIiwKICAgICAgICAgICAgICAgICAgICAgd2lkZ2V0TmFtZTogImZpbGVVcGxvYWQiLAogICAgICAgICAgICAgICAgICAgICBfZ2V0VXJsOiBvcHRpb25zLl9nZXRVcmwgfHwgZm9ybUJyaWRnZS5fZ2V0VXJsKCIiKSwKICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZVByZXZpZXc6IG9wdGlvbnMuZGlzYWJsZVByZXZpZXcgfHwgZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgIHVwbG9hZGVyUGx1Z2luTmFtZTogImFkb2JlRmlsZVVwbG9hZGVyIgoKCgogICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgdmFyIHdpZGdldCA9ICRmaWxlV2lkZ2V0W3dpZGdldE5hbWVdKG9wdGlvbnNUb1dpZGdldCk7CiAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuZmlsZVVwbG9hZFdpZGdldCA9IHdpZGdldC5kYXRhKHdpZGdldE5hbWUpIHx8IHdpZGdldC5kYXRhKCJ4ZmFXaWRnZXQtIiArIHdpZGdldE5hbWUpOwogICAgICAgICAgICAgfQogICAgIH07CiAgICAgbWV0aG9kLmluaXQoKTsKIH0pOwp9KTsKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTMgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCihmdW5jdGlvbiAoJCkgewogICAgZnVuY3Rpb24gaGFuZGxlU2Nyb2xsKGV2ZW50KSB7CiAgICAgICAgdmFyIHBhZ2luZ01hbmFnZXIgPSB3aW5kb3cuZm9ybUJyaWRnZSA/IHdpbmRvdy5mb3JtQnJpZGdlLnBhZ2luZ01hbmFnZXIoKSA6IG51bGw7CiAgICAgICAgdmFyIHNjcm9sbFRvcCA9ICQod2luZG93KS5zY3JvbGxUb3AoKTsKICAgICAgICB2YXIgd2luSGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0ID8gd2luZG93LmlubmVySGVpZ2h0IDogJCh3aW5kb3cpLmhlaWdodCgpOwogICAgICAgIHZhciB3aW5CdG1Qb3MgPSBzY3JvbGxUb3AgKyB3aW5IZWlnaHQ7CiAgICAgICAgdmFyICRib2R5RWwgPSAkKCIjZm9ybUJvZHkiKTsKICAgICAgICAvKldlIGFsc28gbmVlZCB0byB0YWtlIGJvZHlTY2FsZUZhY3RvciBpbnRvIGFjY291bnQgaW4gb3JkZXIgdG8gY29tcGFyZSBpdCB3aXRoIHdpbmRvdyBoZWlnaHQuKi8KICAgICAgICB2YXIgYm9keUJvdHRvbSA9ICRib2R5RWwuaGVpZ2h0KCkgKiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZm9ybVNjYWxlRmFjdG9yICsgJGJvZHlFbC5vZmZzZXQoKS50b3A7CiAgICAgICAgaWYgKGJvZHlCb3R0b20gPCB3aW5CdG1Qb3MgKyA1MCkgewogICAgICAgICAgICBpZiAocGFnaW5nTWFuYWdlciAmJiBwYWdpbmdNYW5hZ2VyLmhhc01vcmVQYWdlcygpKSB7CiAgICAgICAgICAgICAgICAkKCcjbG9hZGluZ3BhZ2UnKS5jaGlsZHJlbigiOm5vdChhLnBhZ2Vsb2Fkbm93KSIpLmNzcygidmlzaWJpbGl0eSIsICJ2aXNpYmxlIik7CiAgICAgICAgICAgICAgICB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuY2xlYXJUaW1lb3V0T25EZXN0cm95KHNldFRpbWVvdXQocmVuZGVyTmV4dFBhZ2UsIDUpKTsgLy93b3JrYXJvdW5kIGZvciBJUEFEIHRvIHNob3cgaW50ZXJtZWRpYXRlIGxvYWQgaWNvbgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGhhbmRsZUZvb3RlckxvZ2ljKCkgewogICAgICAgIHZhciBwYWdpbmdNYW5hZ2VyID0gd2luZG93LmZvcm1CcmlkZ2UgPyB3aW5kb3cuZm9ybUJyaWRnZS5wYWdpbmdNYW5hZ2VyKCkgOiBudWxsOwogICAgICAgIGlmIChwYWdpbmdNYW5hZ2VyID09IG51bGwpIHJldHVybjsKICAgICAgICBpZiAoIXBhZ2luZ01hbmFnZXIuaGFzTW9yZVBhZ2VzKCkpIHsKICAgICAgICAgICAgJCgnI2xvYWRpbmdwYWdlJykuY3NzKHtkaXNwbGF5OiAibm9uZSJ9KTsKICAgICAgICAgICAgJCh3aW5kb3cpLm9mZigic2Nyb2xsLnhmYXZpZXciKTsKICAgICAgICAgICAgJCgnI25vbW9yZXBhZ2VzJykuY3NzKHtkaXNwbGF5OiAiaW5saW5lLWJsb2NrIn0pOwogICAgICAgIH0gZWxzZSBpZiAocGFnaW5nTWFuYWdlci5oYXNNb3JlUGFnZXMoKSkgewogICAgICAgICAgICAkKCcjbG9hZGluZ3BhZ2UnKS5jaGlsZHJlbigiOm5vdChhLnBhZ2Vsb2Fkbm93KSIpLmNzcyh7dmlzaWJpbGl0eTogImhpZGRlbiJ9KTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gcmVuZGVyTmV4dFBhZ2UoaW5pdGlhbExvYWQpIHsKICAgICAgICB2YXIgcGFnaW5nTWFuYWdlciA9IHdpbmRvdy5mb3JtQnJpZGdlID8gd2luZG93LmZvcm1CcmlkZ2UucGFnaW5nTWFuYWdlcigpIDogbnVsbDsKICAgICAgICBpZiAoIWluaXRpYWxMb2FkICYmIHBhZ2luZ01hbmFnZXIpIHsKICAgICAgICAgICAgcGFnaW5nTWFuYWdlci5yZW5kZXJOZXh0UGFnZSgpOwogICAgICAgIH0KICAgICAgICBoYW5kbGVGb290ZXJMb2dpYygpOwogICAgICAgICQoZm9ybUJyaWRnZSkudHJpZ2dlcigieGZhTmV4dFBhZ2VSZW5kZXJlZCIpOwogICAgfQoKICAgIHdpbmRvdy5yZW5kZXJOZXh0UGFnZSA9IHJlbmRlck5leHRQYWdlOwogICAgd2luZG93LmhhbmRsZUZvb3RlckxvZ2ljID0gaGFuZGxlRm9vdGVyTG9naWM7CiAgICB3aW5kb3cuaGFuZGxlU2Nyb2xsID0gaGFuZGxlU2Nyb2xsOwp9KSgkKTsKCgovKioKIEFET0JFIENPTkZJREVOVElBTAoKIENvcHlyaWdodCAyMDE0IEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiBBbGwgUmlnaHRzIFJlc2VydmVkLgoKIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiBzdXBwbGllcnMgYW5kIG1heSBiZSBjb3ZlcmVkIGJ5IFUuUy4gYW5kIEZvcmVpZ24gUGF0ZW50cywKIHBhdGVudHMgaW4gcHJvY2VzcywgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuCiBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKi8KCihmdW5jdGlvbiAoJCkgewogICAgd2luZG93LkZEID0gd2luZG93LkZEIHx8IHt9OwogICAgRkQuRlAgICAgID0gRkQuRlAgfHwge307CiAgICBGRC5GUC5NRiA9IEZELkZQLk1GIHx8IHt9OwogICAgRkQuRlAuTUYgPSB7CiAgICAgICAgc2F2ZU1GRHJhZnQgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgZHJhZnRJRCA9IHdpbmRvdy5mb3JtQnJpZGdlLmN1c3RvbUNvbnRleHRQcm9wZXJ0eSgibWZEcmFmdElkIiksCiAgICAgICAgICAgICAgICBmaWxlTGlzdCA9ICIiLAogICAgICAgICAgICAgICAgZm9ybVBhdGggPSB3aW5kb3cueGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dC5jb250ZW50Um9vdC5zdWJzdHJpbmcoNikgKyAiLyIgK3dpbmRvdy54ZmFsaWIucnVudGltZS5yZW5kZXJDb250ZXh0LnRlbXBsYXRlLAogICAgICAgICAgICAgICAgZm9ybU5hbWUgPSB3aW5kb3cueGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dC50ZW1wbGF0ZSwKICAgICAgICAgICAgICAgIGZvcm1EYXRhID0gIG51bGwsCiAgICAgICAgICAgICAgICB1cmxGb3JEcmFmdCA9IHdpbmRvdy5mb3JtQnJpZGdlLl9nZXRVcmwoZm9ybVBhdGgpICsgIi9qY3I6Y29udGVudC5mcC5kcmFmdC5qc29uP2Z1bmM9c2F2ZURyYWZ0IiwKICAgICAgICAgICAgICAgIHByb2ZpbGUgPSB4ZmFsaWIucnVudGltZS5jdXN0b21Qcm9wZXJ0eU1hcC5wcm9maWxlLAogICAgICAgICAgICAgICAgc3VibWl0VXJsID0geGZhbGliLnJ1bnRpbWUuY3VzdG9tUHJvcGVydHlNYXAuc3VibWl0VXJsLAogICAgICAgICAgICAgICAgaW5zdGFuY2VJZCA9IHdpbmRvdy5mb3JtQnJpZGdlLmN1c3RvbUNvbnRleHRQcm9wZXJ0eSgiaW5zdGFuY2VJZCIpOwoKICAgICAgICAgICAgdmFyIGZpbGVVcGxvYWRQYXRoID0gd2luZG93LmZvcm1CcmlkZ2UuX2dldFVybChmb3JtUGF0aCkgKyAiL2pjcjpjb250ZW50LmZwLmF0dGFjaC5qc3AvIiArIGRyYWZ0SUQsCiAgICAgICAgICAgICAgICBzaG93RHJhZnRTdGF0dXMgPSBmdW5jdGlvbihtZXNzYWdlLGlkKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCIjIitpZCkudGV4dChtZXNzYWdlKS5zaG93KCkuZmFkZU91dCgxNjAwLCJsaW5lYXIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICB2YXIgb2JqID0gewogICAgICAgICAgICAgICAgInN1Y2Nlc3MiOmZ1bmN0aW9uKHJlc3VsdCl7CiAgICAgICAgICAgICAgICAgICAgd2luZG93LmZvcm1CcmlkZ2UudHJpZ2dlcigKICAgICAgICAgICAgICAgICAgICAgICAgInNhdmVTdGFydGVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LnhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCAoInNhdmVTdGFydGVkIikKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIGZvcm1EYXRhID0gcmVzdWx0LmRhdGE7CiAgICAgICAgICAgICAgICAgICAgdmFyIGRhdGEgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICdmb3JtTmFtZScgIDogZm9ybU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICdmb3JtUGF0aCcgIDogZm9ybVBhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICdmb3JtRGF0YScgIDogZm9ybURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICdkcmFmdElEJyAgIDogZHJhZnRJRCwKICAgICAgICAgICAgICAgICAgICAgICAgJ2Zvcm1UeXBlJyAgOiAibWYiLAogICAgICAgICAgICAgICAgICAgICAgICAnX2NoYXJzZXRfJyA6ICJVVEYtOCIsCiAgICAgICAgICAgICAgICAgICAgICAgICdwcm9maWxlJyAgIDogcHJvZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgJ3N1Ym1pdFVybCcgOiBzdWJtaXRVcmwsCiAgICAgICAgICAgICAgICAgICAgICAgICdmaWxlTGlzdCcgIDogZmlsZUxpc3QKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIGFsbG93ZWRNZXRhZGF0YSA9IFtdOwoKICAgICAgICAgICAgICAgICAgICBpZihpbnN0YW5jZUlkKXsKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVsiaW5zdGFuY2VJZCJdID0gaW5zdGFuY2VJZDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZm9yKGtleSBpbiBkYXRhKXsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoa2V5ICE9PSAnZm9ybURhdGEnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxvd2VkTWV0YWRhdGEucHVzaChrZXkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRhdGFbImZwQWxsb3dlZE1ldGFkYXRhIl0gPSBhbGxvd2VkTWV0YWRhdGEudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgICAgICAkLmFqYXgoewogICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiJQT1NUIiwKICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiB1cmxGb3JEcmFmdCwKICAgICAgICAgICAgICAgICAgICAgICAgYXN5bmM6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3VsdCkgewoJCQkJCQkJaWYocmVzdWx0ICYmIHJlc3VsdC5kcmFmdElEKXsKCQkJCQkJCQl3aW5kb3cuZm9ybUJyaWRnZS50cmlnZ2VyKAoJCQkJCQkJCQkic2F2ZUNvbXBsZXRlZCIsCgkJCQkJCQkJCXdpbmRvdy54ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQgKCJzYXZlQ29tcGxldGVkIikKCQkJCQkJCQkpOwoJCQkJCQkJCXNob3dEcmFmdFN0YXR1cyh4ZmFsaWIubG9jYWxlLlN0cmluZ3MuU2F2ZWRTdWNjZXNzZnVsbHksICJmcERyYWZ0U3RhdHVzIik7CgkJCQkJCQkJd2luZG93LmZvcm1CcmlkZ2UuY3VzdG9tQ29udGV4dFByb3BlcnR5KCJtZkRyYWZ0SWQiLHJlc3VsdC5kcmFmdElEKTsKCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkgICAgc2hvd0RyYWZ0U3RhdHVzKHhmYWxpYi5sb2NhbGUuU3RyaW5ncy5VbmFibGVUb1NhdmUsImZwRHJhZnRTdGF0dXMiKTsKCQkJCQkJCX0KICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgOiBmdW5jdGlvbiAocmVzdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93RHJhZnRTdGF0dXMoeGZhbGliLmxvY2FsZS5TdHJpbmdzLlVuYWJsZVRvU2F2ZSwiZnBEcmFmdFN0YXR1cyIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImVycm9yIjpmdW5jdGlvbihyZXN1bHQpewogICAgICAgICAgICAgICAgICAgIHNob3dEcmFmdFN0YXR1cyh4ZmFsaWIubG9jYWxlLlN0cmluZ3MuVW5hYmxlVG9TYXZlLCJmcERyYWZ0U3RhdHVzIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHZhciBmaWxlVXBsb2FkT2JqID0gewogICAgICAgICAgICAgICAgInN1Y2Nlc3MiOmZ1bmN0aW9uKHJlc3VsdCl7CiAgICAgICAgICAgICAgICAgICAgJC5lYWNoKHJlc3VsdCwgZnVuY3Rpb24oaW5kZXgsIHJlcykgewogICAgICAgICAgICAgICAgICAgICAgICBmaWxlTGlzdCArPSByZXMucGF0aCArICJcbiI7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgLy90byByZW1vdmUgbGFzdCAnXG4nIGZyb20gbGlzdAogICAgICAgICAgICAgICAgICAgIGZpbGVMaXN0ID0gZmlsZUxpc3QucmVwbGFjZSgvXG4kLywgIiIpOwogICAgICAgICAgICAgICAgICAgIHdpbmRvdy5mb3JtQnJpZGdlLmdldERhdGFYTUwob2JqKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZXJyb3IiOmZ1bmN0aW9uKHJlc3VsdCl7CgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJmaWxlVXBsb2FkUGF0aCI6ZmlsZVVwbG9hZFBhdGgKICAgICAgICAgICAgfTsKICAgICAgICAgICAgd2luZG93LmZvcm1CcmlkZ2UuZ2V0RmlsZUF0dGFjaG1lbnRzSW5mbyhmaWxlVXBsb2FkT2JqKTsKICAgICAgICB9LAoKICAgICAgICBfc2F2ZU1GRHJhZnRXcmFwcGVyOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmICh0eXBlb2Ygd2luZG93LmZvcm1CcmlkZ2UuY3VzdG9tQ29udGV4dFByb3BlcnR5KCJtZkRyYWZ0SWQiKSA9PT0gInVuZGVmaW5lZCIgfHwgd2luZG93LmZvcm1CcmlkZ2UuY3VzdG9tQ29udGV4dFByb3BlcnR5KCJtZkRyYWZ0SWQiKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkLmFqYXgoewogICAgICAgICAgICAgICAgICAgIG1ldGhvZDogIkdFVCIsCiAgICAgICAgICAgICAgICAgICAgdXJsOiBHcmFuaXRlLkhUVFAuZXh0ZXJuYWxpemUoIi9jb250ZW50L2Zvcm1zL3BvcnRhbC9kcmFmdGFuZHN1Ym1pc3Npb24uZnAuZHJhZnQuanNvbj9mdW5jPWdldFVpZCIpLAogICAgICAgICAgICAgICAgICAgIGNhY2hlIDogZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6ICJqc29uIgogICAgICAgICAgICAgICAgfSkuZG9uZShmdW5jdGlvbiAocmVzcG9uc2UpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZHJhZnRJRCA9IHJlc3BvbnNlLmlkOwogICAgICAgICAgICAgICAgICAgIHdpbmRvdy5mb3JtQnJpZGdlLmN1c3RvbUNvbnRleHRQcm9wZXJ0eSgibWZEcmFmdElkIiwgZHJhZnRJRCArICJfbWYiKTsKICAgICAgICAgICAgICAgICAgICBGRC5GUC5NRi5zYXZlTUZEcmFmdCgpOwogICAgICAgICAgICAgICAgfSkuZmFpbChmdW5jdGlvbiAoZXJyb3JPYmopIHsKICAgICAgICAgICAgICAgICAgICAkKCIjZnBEcmFmdFN0YXR1cyIpLnRleHQoeGZhbGliLmxvY2FsZS5TdHJpbmdzLlVuYWJsZVRvU2F2ZSkuc2hvdygpLmZhZGVPdXQoMTYwMCwibGluZWFyIik7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEZELkZQLk1GLnNhdmVNRkRyYWZ0KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwoKICAgICQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uKCl7CiAgICAgICAgJCgiI3Rvb2xiYXJzYXZlYnRuIikuY2xpY2soZnVuY3Rpb24oKXsKICAgICAgICAgICAgd2luZG93LkZELkZQLk1GLl9zYXZlTUZEcmFmdFdyYXBwZXIoKTsKICAgICAgICB9KQogICAgfSk7Cn0pKGpRdWVyeSk7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX19fCiAqCiAqIENvcHlyaWdodCAyMDIzIEFkb2JlCiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIE5PVElDRTogQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBhbmQgaXRzIHN1cHBsaWVycywgaWYgYW55LiBUaGUgaW50ZWxsZWN0dWFsCiAqIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUKICogYW5kIGl0cyBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsCiAqIHByb3BlcnR5IGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogZnJvbSBBZG9iZS4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKKGZ1bmN0aW9uICgpIHsKCXdpbmRvdy5GRCA9IHdpbmRvdy5GRCB8fCB7fQoJdmFyIHRvZ2dsZXM7CgoJdmFyIGh0dHBFdmFsID0gZnVuY3Rpb24gKHVybCkgewoJCXZhciByZXNwb25zZSA9ICQuYWpheCh7CgkJCXVybDogdXJsLAoJCQl0eXBlOiAiZ2V0IiwKCQkJYXN5bmM6IGZhbHNlLAoJCQlkYXRhVHlwZTogImpzb24iCgkJfSk7CgkJaWYocmVzcG9uc2Uuc3RhdHVzIT0yMDApewogICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgkJdmFyIHRleHQgPSByZXNwb25zZS5ib2R5ID8gcmVzcG9uc2UuYm9keSA6IHJlc3BvbnNlLnJlc3BvbnNlVGV4dDsKCQlyZXR1cm4gSlNPTi5wYXJzZSh0ZXh0KTsKCX07CgoKCUZELmlzVG9nZ2xlRW5hYmxlZCA9IGZ1bmN0aW9uICh0b2dnbGVOYW1lKSB7CgkJdmFyIGNvbnRleHRSb290ID0gKHR5cGVvZiBmb3JtQnJpZGdlICE9PSAndW5kZWZpbmVkJyAmJiBmb3JtQnJpZGdlLl9nZXRDb250ZXh0Um9vdCgpKSA/IGZvcm1CcmlkZ2UuX2dldENvbnRleHRSb290KCkgOgoJCQkodHlwZW9mIGd1aWRlQnJpZGdlICE9PSAndW5kZWZpbmVkJyAmJiBndWlkZUJyaWRnZS5fZ2V0Q29udGV4dFJvb3QoKSkgPyBndWlkZUJyaWRnZS5fZ2V0Q29udGV4dFJvb3QoKSA6ICIiOwoJCXRvZ2dsZXMgPSB0b2dnbGVzIHx8IGh0dHBFdmFsKGNvbnRleHRSb290ICsgIi9ldGMuY2xpZW50bGlicy90b2dnbGVzLmpzb24iKTsKCQl2YXIgcmV0VmFsID0gZmFsc2U7CgkJaWYgKHRvZ2dsZXMgJiYgdG9nZ2xlcy5lbmFibGVkIGluc3RhbmNlb2YgQXJyYXkpIHsKCQkJcmV0VmFsID0gdG9nZ2xlcy5lbmFibGVkLmluZGV4T2YodG9nZ2xlTmFtZSkgPiAtMQoJCX0KCQlyZXR1cm4gcmV0VmFsOwoJfQp9KSgpOwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDEzIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCihmdW5jdGlvbigkKXsKICAgIHdpbmRvdy5mb3JtQnJpZGdlLmNvbm5lY3QoCiAgICAgICAgZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIHRpdGxlUmVzdWx0ID0gd2luZG93LmZvcm1CcmlkZ2UuZ2V0RmllbGRQcm9wZXJ0aWVzKCJ4ZmEuZm9ybS4uZGVzYy50aXRsZSIsInZhbHVlIik7CiAgICAgICAgICAgIGlmKHRpdGxlUmVzdWx0ICYmICF0aXRsZVJlc3VsdC5lcnJvcnMgJiYgdGl0bGVSZXN1bHQuZGF0YSAmJiB0aXRsZVJlc3VsdC5kYXRhWzBdKXsKICAgICAgICAgICAgICAgICQoZG9jdW1lbnQpLmF0dHIoJ3RpdGxlJywgdGl0bGVSZXN1bHQuZGF0YVswXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICApOwp9KSgkKTsKCgovKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICoKICogQ29weXJpZ2h0IDIwMTYgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogc3VwcGxpZXJzIGFuZCBtYXkgYmUgY292ZXJlZCBieSBVLlMuIGFuZCBGb3JlaWduIFBhdGVudHMsCiAqIHBhdGVudHMgaW4gcHJvY2VzcywgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuCiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKi8KCndpbmRvdy5qUXVlcnkubm9Db25mbGljdCh0cnVlKTsKaWYgKCF3aW5kb3cualF1ZXJ5KSB7CiAgICB3aW5kb3cualF1ZXJ5ID0gd2luZG93LnhmYWxpYi5qUXVlcnk7Cn0KaWYgKCF3aW5kb3cuJCkgewogICAgd2luZG93LiQgPSB3aW5kb3cueGZhbGliLiQ7Cn0KCndpbmRvdy5fLm5vQ29uZmxpY3QoKTsKaWYgKCF3aW5kb3cuXykgewogICAgd2luZG93Ll8gPSB3aW5kb3cueGZhbGliLl87Cn0K",
+ "base64Body" : "LyohIGpRdWVyeSB2My42LjAgfCAoYykgT3BlbkpTIEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9ycyB8IGpxdWVyeS5vcmcvbGljZW5zZSAqLwohZnVuY3Rpb24oZSx0KXsidXNlIHN0cmljdCI7Im9iamVjdCI9PXR5cGVvZiBtb2R1bGUmJiJvYmplY3QiPT10eXBlb2YgbW9kdWxlLmV4cG9ydHM/bW9kdWxlLmV4cG9ydHM9ZS5kb2N1bWVudD90KGUsITApOmZ1bmN0aW9uKGUpe2lmKCFlLmRvY3VtZW50KXRocm93IG5ldyBFcnJvcigialF1ZXJ5IHJlcXVpcmVzIGEgd2luZG93IHdpdGggYSBkb2N1bWVudCIpO3JldHVybiB0KGUpfTp0KGUpfSgidW5kZWZpbmVkIiE9dHlwZW9mIHdpbmRvdz93aW5kb3c6dGhpcyxmdW5jdGlvbihDLGUpeyJ1c2Ugc3RyaWN0Ijt2YXIgdD1bXSxyPU9iamVjdC5nZXRQcm90b3R5cGVPZixzPXQuc2xpY2UsZz10LmZsYXQ/ZnVuY3Rpb24oZSl7cmV0dXJuIHQuZmxhdC5jYWxsKGUpfTpmdW5jdGlvbihlKXtyZXR1cm4gdC5jb25jYXQuYXBwbHkoW10sZSl9LHU9dC5wdXNoLGk9dC5pbmRleE9mLG49e30sbz1uLnRvU3RyaW5nLHY9bi5oYXNPd25Qcm9wZXJ0eSxhPXYudG9TdHJpbmcsbD1hLmNhbGwoT2JqZWN0KSx5PXt9LG09ZnVuY3Rpb24oZSl7cmV0dXJuImZ1bmN0aW9uIj09dHlwZW9mIGUmJiJudW1iZXIiIT10eXBlb2YgZS5ub2RlVHlwZSYmImZ1bmN0aW9uIiE9dHlwZW9mIGUuaXRlbX0seD1mdW5jdGlvbihlKXtyZXR1cm4gbnVsbCE9ZSYmZT09PWUud2luZG93fSxFPUMuZG9jdW1lbnQsYz17dHlwZTohMCxzcmM6ITAsbm9uY2U6ITAsbm9Nb2R1bGU6ITB9O2Z1bmN0aW9uIGIoZSx0LG4pe3ZhciByLGksbz0obj1ufHxFKS5jcmVhdGVFbGVtZW50KCJzY3JpcHQiKTtpZihvLnRleHQ9ZSx0KWZvcihyIGluIGMpKGk9dFtyXXx8dC5nZXRBdHRyaWJ1dGUmJnQuZ2V0QXR0cmlidXRlKHIpKSYmby5zZXRBdHRyaWJ1dGUocixpKTtuLmhlYWQuYXBwZW5kQ2hpbGQobykucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChvKX1mdW5jdGlvbiB3KGUpe3JldHVybiBudWxsPT1lP2UrIiI6Im9iamVjdCI9PXR5cGVvZiBlfHwiZnVuY3Rpb24iPT10eXBlb2YgZT9uW28uY2FsbChlKV18fCJvYmplY3QiOnR5cGVvZiBlfXZhciBmPSIzLjYuMCIsUz1mdW5jdGlvbihlLHQpe3JldHVybiBuZXcgUy5mbi5pbml0KGUsdCl9O2Z1bmN0aW9uIHAoZSl7dmFyIHQ9ISFlJiYibGVuZ3RoImluIGUmJmUubGVuZ3RoLG49dyhlKTtyZXR1cm4hbShlKSYmIXgoZSkmJigiYXJyYXkiPT09bnx8MD09PXR8fCJudW1iZXIiPT10eXBlb2YgdCYmMDx0JiZ0LTEgaW4gZSl9Uy5mbj1TLnByb3RvdHlwZT17anF1ZXJ5OmYsY29uc3RydWN0b3I6UyxsZW5ndGg6MCx0b0FycmF5OmZ1bmN0aW9uKCl7cmV0dXJuIHMuY2FsbCh0aGlzKX0sZ2V0OmZ1bmN0aW9uKGUpe3JldHVybiBudWxsPT1lP3MuY2FsbCh0aGlzKTplPDA/dGhpc1tlK3RoaXMubGVuZ3RoXTp0aGlzW2VdfSxwdXNoU3RhY2s6ZnVuY3Rpb24oZSl7dmFyIHQ9Uy5tZXJnZSh0aGlzLmNvbnN0cnVjdG9yKCksZSk7cmV0dXJuIHQucHJldk9iamVjdD10aGlzLHR9LGVhY2g6ZnVuY3Rpb24oZSl7cmV0dXJuIFMuZWFjaCh0aGlzLGUpfSxtYXA6ZnVuY3Rpb24obil7cmV0dXJuIHRoaXMucHVzaFN0YWNrKFMubWFwKHRoaXMsZnVuY3Rpb24oZSx0KXtyZXR1cm4gbi5jYWxsKGUsdCxlKX0pKX0sc2xpY2U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2socy5hcHBseSh0aGlzLGFyZ3VtZW50cykpfSxmaXJzdDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmVxKDApfSxsYXN0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZXEoLTEpfSxldmVuOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucHVzaFN0YWNrKFMuZ3JlcCh0aGlzLGZ1bmN0aW9uKGUsdCl7cmV0dXJuKHQrMSklMn0pKX0sb2RkOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucHVzaFN0YWNrKFMuZ3JlcCh0aGlzLGZ1bmN0aW9uKGUsdCl7cmV0dXJuIHQlMn0pKX0sZXE6ZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5sZW5ndGgsbj0rZSsoZTwwP3Q6MCk7cmV0dXJuIHRoaXMucHVzaFN0YWNrKDA8PW4mJm48dD9bdGhpc1tuXV06W10pfSxlbmQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wcmV2T2JqZWN0fHx0aGlzLmNvbnN0cnVjdG9yKCl9LHB1c2g6dSxzb3J0OnQuc29ydCxzcGxpY2U6dC5zcGxpY2V9LFMuZXh0ZW5kPVMuZm4uZXh0ZW5kPWZ1bmN0aW9uKCl7dmFyIGUsdCxuLHIsaSxvLGE9YXJndW1lbnRzWzBdfHx7fSxzPTEsdT1hcmd1bWVudHMubGVuZ3RoLGw9ITE7Zm9yKCJib29sZWFuIj09dHlwZW9mIGEmJihsPWEsYT1hcmd1bWVudHNbc118fHt9LHMrKyksIm9iamVjdCI9PXR5cGVvZiBhfHxtKGEpfHwoYT17fSkscz09PXUmJihhPXRoaXMscy0tKTtzPHU7cysrKWlmKG51bGwhPShlPWFyZ3VtZW50c1tzXSkpZm9yKHQgaW4gZSlyPWVbdF0sIl9fcHJvdG9fXyIhPT10JiZhIT09ciYmKGwmJnImJihTLmlzUGxhaW5PYmplY3Qocil8fChpPUFycmF5LmlzQXJyYXkocikpKT8obj1hW3RdLG89aSYmIUFycmF5LmlzQXJyYXkobik/W106aXx8Uy5pc1BsYWluT2JqZWN0KG4pP246e30saT0hMSxhW3RdPVMuZXh0ZW5kKGwsbyxyKSk6dm9pZCAwIT09ciYmKGFbdF09cikpO3JldHVybiBhfSxTLmV4dGVuZCh7ZXhwYW5kbzoialF1ZXJ5IisoZitNYXRoLnJhbmRvbSgpKS5yZXBsYWNlKC9cRC9nLCIiKSxpc1JlYWR5OiEwLGVycm9yOmZ1bmN0aW9uKGUpe3Rocm93IG5ldyBFcnJvcihlKX0sbm9vcDpmdW5jdGlvbigpe30saXNQbGFpbk9iamVjdDpmdW5jdGlvbihlKXt2YXIgdCxuO3JldHVybiEoIWV8fCJbb2JqZWN0IE9iamVjdF0iIT09by5jYWxsKGUpKSYmKCEodD1yKGUpKXx8ImZ1bmN0aW9uIj09dHlwZW9mKG49di5jYWxsKHQsImNvbnN0cnVjdG9yIikmJnQuY29uc3RydWN0b3IpJiZhLmNhbGwobik9PT1sKX0saXNFbXB0eU9iamVjdDpmdW5jdGlvbihlKXt2YXIgdDtmb3IodCBpbiBlKXJldHVybiExO3JldHVybiEwfSxnbG9iYWxFdmFsOmZ1bmN0aW9uKGUsdCxuKXtiKGUse25vbmNlOnQmJnQubm9uY2V9LG4pfSxlYWNoOmZ1bmN0aW9uKGUsdCl7dmFyIG4scj0wO2lmKHAoZSkpe2ZvcihuPWUubGVuZ3RoO3I8bjtyKyspaWYoITE9PT10LmNhbGwoZVtyXSxyLGVbcl0pKWJyZWFrfWVsc2UgZm9yKHIgaW4gZSlpZighMT09PXQuY2FsbChlW3JdLHIsZVtyXSkpYnJlYWs7cmV0dXJuIGV9LG1ha2VBcnJheTpmdW5jdGlvbihlLHQpe3ZhciBuPXR8fFtdO3JldHVybiBudWxsIT1lJiYocChPYmplY3QoZSkpP1MubWVyZ2Uobiwic3RyaW5nIj09dHlwZW9mIGU/W2VdOmUpOnUuY2FsbChuLGUpKSxufSxpbkFycmF5OmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gbnVsbD09dD8tMTppLmNhbGwodCxlLG4pfSxtZXJnZTpmdW5jdGlvbihlLHQpe2Zvcih2YXIgbj0rdC5sZW5ndGgscj0wLGk9ZS5sZW5ndGg7cjxuO3IrKyllW2krK109dFtyXTtyZXR1cm4gZS5sZW5ndGg9aSxlfSxncmVwOmZ1bmN0aW9uKGUsdCxuKXtmb3IodmFyIHI9W10saT0wLG89ZS5sZW5ndGgsYT0hbjtpPG87aSsrKSF0KGVbaV0saSkhPT1hJiZyLnB1c2goZVtpXSk7cmV0dXJuIHJ9LG1hcDpmdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvPTAsYT1bXTtpZihwKGUpKWZvcihyPWUubGVuZ3RoO288cjtvKyspbnVsbCE9KGk9dChlW29dLG8sbikpJiZhLnB1c2goaSk7ZWxzZSBmb3IobyBpbiBlKW51bGwhPShpPXQoZVtvXSxvLG4pKSYmYS5wdXNoKGkpO3JldHVybiBnKGEpfSxndWlkOjEsc3VwcG9ydDp5fSksImZ1bmN0aW9uIj09dHlwZW9mIFN5bWJvbCYmKFMuZm5bU3ltYm9sLml0ZXJhdG9yXT10W1N5bWJvbC5pdGVyYXRvcl0pLFMuZWFjaCgiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvciBTeW1ib2wiLnNwbGl0KCIgIiksZnVuY3Rpb24oZSx0KXtuWyJbb2JqZWN0ICIrdCsiXSJdPXQudG9Mb3dlckNhc2UoKX0pO3ZhciBkPWZ1bmN0aW9uKG4pe3ZhciBlLGQsYixvLGksaCxmLGcsdyx1LGwsVCxDLGEsRSx2LHMsYyx5LFM9InNpenpsZSIrMSpuZXcgRGF0ZSxwPW4uZG9jdW1lbnQsaz0wLHI9MCxtPXVlKCkseD11ZSgpLEE9dWUoKSxOPXVlKCksaj1mdW5jdGlvbihlLHQpe3JldHVybiBlPT09dCYmKGw9ITApLDB9LEQ9e30uaGFzT3duUHJvcGVydHksdD1bXSxxPXQucG9wLEw9dC5wdXNoLEg9dC5wdXNoLE89dC5zbGljZSxQPWZ1bmN0aW9uKGUsdCl7Zm9yKHZhciBuPTAscj1lLmxlbmd0aDtuPHI7bisrKWlmKGVbbl09PT10KXJldHVybiBuO3JldHVybi0xfSxSPSJjaGVja2VkfHNlbGVjdGVkfGFzeW5jfGF1dG9mb2N1c3xhdXRvcGxheXxjb250cm9sc3xkZWZlcnxkaXNhYmxlZHxoaWRkZW58aXNtYXB8bG9vcHxtdWx0aXBsZXxvcGVufHJlYWRvbmx5fHJlcXVpcmVkfHNjb3BlZCIsTT0iW1xceDIwXFx0XFxyXFxuXFxmXSIsST0iKD86XFxcXFtcXGRhLWZBLUZdezEsNn0iK00rIj98XFxcXFteXFxyXFxuXFxmXXxbXFx3LV18W15cMC1cXHg3Zl0pKyIsVz0iXFxbIitNKyIqKCIrSSsiKSg/OiIrTSsiKihbKl4kfCF+XT89KSIrTSsiKig/OicoKD86XFxcXC58W15cXFxcJ10pKiknfFwiKCg/OlxcXFwufFteXFxcXFwiXSkqKVwifCgiK0krIikpfCkiK00rIipcXF0iLEY9IjooIitJKyIpKD86XFwoKCgnKCg/OlxcXFwufFteXFxcXCddKSopJ3xcIigoPzpcXFxcLnxbXlxcXFxcIl0pKilcIil8KCg/OlxcXFwufFteXFxcXCgpW1xcXV18IitXKyIpKil8LiopXFwpfCkiLEI9bmV3IFJlZ0V4cChNKyIrIiwiZyIpLCQ9bmV3IFJlZ0V4cCgiXiIrTSsiK3woKD86XnxbXlxcXFxdKSg/OlxcXFwuKSopIitNKyIrJCIsImciKSxfPW5ldyBSZWdFeHAoIl4iK00rIiosIitNKyIqIiksej1uZXcgUmVnRXhwKCJeIitNKyIqKFs+K35dfCIrTSsiKSIrTSsiKiIpLFU9bmV3IFJlZ0V4cChNKyJ8PiIpLFg9bmV3IFJlZ0V4cChGKSxWPW5ldyBSZWdFeHAoIl4iK0krIiQiKSxHPXtJRDpuZXcgUmVnRXhwKCJeIygiK0krIikiKSxDTEFTUzpuZXcgUmVnRXhwKCJeXFwuKCIrSSsiKSIpLFRBRzpuZXcgUmVnRXhwKCJeKCIrSSsifFsqXSkiKSxBVFRSOm5ldyBSZWdFeHAoIl4iK1cpLFBTRVVETzpuZXcgUmVnRXhwKCJeIitGKSxDSElMRDpuZXcgUmVnRXhwKCJeOihvbmx5fGZpcnN0fGxhc3R8bnRofG50aC1sYXN0KS0oY2hpbGR8b2YtdHlwZSkoPzpcXCgiK00rIiooZXZlbnxvZGR8KChbKy1dfCkoXFxkKilufCkiK00rIiooPzooWystXXwpIitNKyIqKFxcZCspfCkpIitNKyIqXFwpfCkiLCJpIiksYm9vbDpuZXcgUmVnRXhwKCJeKD86IitSKyIpJCIsImkiKSxuZWVkc0NvbnRleHQ6bmV3IFJlZ0V4cCgiXiIrTSsiKls+K35dfDooZXZlbnxvZGR8ZXF8Z3R8bHR8bnRofGZpcnN0fGxhc3QpKD86XFwoIitNKyIqKCg/Oi1cXGQpP1xcZCopIitNKyIqXFwpfCkoPz1bXi1dfCQpIiwiaSIpfSxZPS9IVE1MJC9pLFE9L14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxKPS9eaFxkJC9pLEs9L15bXntdK1x7XHMqXFtuYXRpdmUgXHcvLFo9L14oPzojKFtcdy1dKyl8KFx3Kyl8XC4oW1x3LV0rKSkkLyxlZT0vWyt+XS8sdGU9bmV3IFJlZ0V4cCgiXFxcXFtcXGRhLWZBLUZdezEsNn0iK00rIj98XFxcXChbXlxcclxcblxcZl0pIiwiZyIpLG5lPWZ1bmN0aW9uKGUsdCl7dmFyIG49IjB4IitlLnNsaWNlKDEpLTY1NTM2O3JldHVybiB0fHwobjwwP1N0cmluZy5mcm9tQ2hhckNvZGUobis2NTUzNik6U3RyaW5nLmZyb21DaGFyQ29kZShuPj4xMHw1NTI5NiwxMDIzJm58NTYzMjApKX0scmU9LyhbXDAtXHgxZlx4N2ZdfF4tP1xkKXxeLSR8W15cMC1ceDFmXHg3Zi1cdUZGRkZcdy1dL2csaWU9ZnVuY3Rpb24oZSx0KXtyZXR1cm4gdD8iXDAiPT09ZT8iXHVmZmZkIjplLnNsaWNlKDAsLTEpKyJcXCIrZS5jaGFyQ29kZUF0KGUubGVuZ3RoLTEpLnRvU3RyaW5nKDE2KSsiICI6IlxcIitlfSxvZT1mdW5jdGlvbigpe1QoKX0sYWU9YmUoZnVuY3Rpb24oZSl7cmV0dXJuITA9PT1lLmRpc2FibGVkJiYiZmllbGRzZXQiPT09ZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpfSx7ZGlyOiJwYXJlbnROb2RlIixuZXh0OiJsZWdlbmQifSk7dHJ5e0guYXBwbHkodD1PLmNhbGwocC5jaGlsZE5vZGVzKSxwLmNoaWxkTm9kZXMpLHRbcC5jaGlsZE5vZGVzLmxlbmd0aF0ubm9kZVR5cGV9Y2F0Y2goZSl7SD17YXBwbHk6dC5sZW5ndGg/ZnVuY3Rpb24oZSx0KXtMLmFwcGx5KGUsTy5jYWxsKHQpKX06ZnVuY3Rpb24oZSx0KXt2YXIgbj1lLmxlbmd0aCxyPTA7d2hpbGUoZVtuKytdPXRbcisrXSk7ZS5sZW5ndGg9bi0xfX19ZnVuY3Rpb24gc2UodCxlLG4scil7dmFyIGksbyxhLHMsdSxsLGMsZj1lJiZlLm93bmVyRG9jdW1lbnQscD1lP2Uubm9kZVR5cGU6OTtpZihuPW58fFtdLCJzdHJpbmciIT10eXBlb2YgdHx8IXR8fDEhPT1wJiY5IT09cCYmMTEhPT1wKXJldHVybiBuO2lmKCFyJiYoVChlKSxlPWV8fEMsRSkpe2lmKDExIT09cCYmKHU9Wi5leGVjKHQpKSlpZihpPXVbMV0pe2lmKDk9PT1wKXtpZighKGE9ZS5nZXRFbGVtZW50QnlJZChpKSkpcmV0dXJuIG47aWYoYS5pZD09PWkpcmV0dXJuIG4ucHVzaChhKSxufWVsc2UgaWYoZiYmKGE9Zi5nZXRFbGVtZW50QnlJZChpKSkmJnkoZSxhKSYmYS5pZD09PWkpcmV0dXJuIG4ucHVzaChhKSxufWVsc2V7aWYodVsyXSlyZXR1cm4gSC5hcHBseShuLGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUodCkpLG47aWYoKGk9dVszXSkmJmQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSYmZS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKXJldHVybiBILmFwcGx5KG4sZS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKGkpKSxufWlmKGQucXNhJiYhTlt0KyIgIl0mJighdnx8IXYudGVzdCh0KSkmJigxIT09cHx8Im9iamVjdCIhPT1lLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpKXtpZihjPXQsZj1lLDE9PT1wJiYoVS50ZXN0KHQpfHx6LnRlc3QodCkpKXsoZj1lZS50ZXN0KHQpJiZ5ZShlLnBhcmVudE5vZGUpfHxlKT09PWUmJmQuc2NvcGV8fCgocz1lLmdldEF0dHJpYnV0ZSgiaWQiKSk/cz1zLnJlcGxhY2UocmUsaWUpOmUuc2V0QXR0cmlidXRlKCJpZCIscz1TKSksbz0obD1oKHQpKS5sZW5ndGg7d2hpbGUoby0tKWxbb109KHM/IiMiK3M6IjpzY29wZSIpKyIgIit4ZShsW29dKTtjPWwuam9pbigiLCIpfXRyeXtyZXR1cm4gSC5hcHBseShuLGYucXVlcnlTZWxlY3RvckFsbChjKSksbn1jYXRjaChlKXtOKHQsITApfWZpbmFsbHl7cz09PVMmJmUucmVtb3ZlQXR0cmlidXRlKCJpZCIpfX19cmV0dXJuIGcodC5yZXBsYWNlKCQsIiQxIiksZSxuLHIpfWZ1bmN0aW9uIHVlKCl7dmFyIHI9W107cmV0dXJuIGZ1bmN0aW9uIGUodCxuKXtyZXR1cm4gci5wdXNoKHQrIiAiKT5iLmNhY2hlTGVuZ3RoJiZkZWxldGUgZVtyLnNoaWZ0KCldLGVbdCsiICJdPW59fWZ1bmN0aW9uIGxlKGUpe3JldHVybiBlW1NdPSEwLGV9ZnVuY3Rpb24gY2UoZSl7dmFyIHQ9Qy5jcmVhdGVFbGVtZW50KCJmaWVsZHNldCIpO3RyeXtyZXR1cm4hIWUodCl9Y2F0Y2goZSl7cmV0dXJuITF9ZmluYWxseXt0LnBhcmVudE5vZGUmJnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0KSx0PW51bGx9fWZ1bmN0aW9uIGZlKGUsdCl7dmFyIG49ZS5zcGxpdCgifCIpLHI9bi5sZW5ndGg7d2hpbGUoci0tKWIuYXR0ckhhbmRsZVtuW3JdXT10fWZ1bmN0aW9uIHBlKGUsdCl7dmFyIG49dCYmZSxyPW4mJjE9PT1lLm5vZGVUeXBlJiYxPT09dC5ub2RlVHlwZSYmZS5zb3VyY2VJbmRleC10LnNvdXJjZUluZGV4O2lmKHIpcmV0dXJuIHI7aWYobil3aGlsZShuPW4ubmV4dFNpYmxpbmcpaWYobj09PXQpcmV0dXJuLTE7cmV0dXJuIGU/MTotMX1mdW5jdGlvbiBkZSh0KXtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuImlucHV0Ij09PWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSYmZS50eXBlPT09dH19ZnVuY3Rpb24gaGUobil7cmV0dXJuIGZ1bmN0aW9uKGUpe3ZhciB0PWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtyZXR1cm4oImlucHV0Ij09PXR8fCJidXR0b24iPT09dCkmJmUudHlwZT09PW59fWZ1bmN0aW9uIGdlKHQpe3JldHVybiBmdW5jdGlvbihlKXtyZXR1cm4iZm9ybSJpbiBlP2UucGFyZW50Tm9kZSYmITE9PT1lLmRpc2FibGVkPyJsYWJlbCJpbiBlPyJsYWJlbCJpbiBlLnBhcmVudE5vZGU/ZS5wYXJlbnROb2RlLmRpc2FibGVkPT09dDplLmRpc2FibGVkPT09dDplLmlzRGlzYWJsZWQ9PT10fHxlLmlzRGlzYWJsZWQhPT0hdCYmYWUoZSk9PT10OmUuZGlzYWJsZWQ9PT10OiJsYWJlbCJpbiBlJiZlLmRpc2FibGVkPT09dH19ZnVuY3Rpb24gdmUoYSl7cmV0dXJuIGxlKGZ1bmN0aW9uKG8pe3JldHVybiBvPStvLGxlKGZ1bmN0aW9uKGUsdCl7dmFyIG4scj1hKFtdLGUubGVuZ3RoLG8pLGk9ci5sZW5ndGg7d2hpbGUoaS0tKWVbbj1yW2ldXSYmKGVbbl09ISh0W25dPWVbbl0pKX0pfSl9ZnVuY3Rpb24geWUoZSl7cmV0dXJuIGUmJiJ1bmRlZmluZWQiIT10eXBlb2YgZS5nZXRFbGVtZW50c0J5VGFnTmFtZSYmZX1mb3IoZSBpbiBkPXNlLnN1cHBvcnQ9e30saT1zZS5pc1hNTD1mdW5jdGlvbihlKXt2YXIgdD1lJiZlLm5hbWVzcGFjZVVSSSxuPWUmJihlLm93bmVyRG9jdW1lbnR8fGUpLmRvY3VtZW50RWxlbWVudDtyZXR1cm4hWS50ZXN0KHR8fG4mJm4ubm9kZU5hbWV8fCJIVE1MIil9LFQ9c2Uuc2V0RG9jdW1lbnQ9ZnVuY3Rpb24oZSl7dmFyIHQsbixyPWU/ZS5vd25lckRvY3VtZW50fHxlOnA7cmV0dXJuIHIhPUMmJjk9PT1yLm5vZGVUeXBlJiZyLmRvY3VtZW50RWxlbWVudCYmKGE9KEM9cikuZG9jdW1lbnRFbGVtZW50LEU9IWkoQykscCE9QyYmKG49Qy5kZWZhdWx0VmlldykmJm4udG9wIT09biYmKG4uYWRkRXZlbnRMaXN0ZW5lcj9uLmFkZEV2ZW50TGlzdGVuZXIoInVubG9hZCIsb2UsITEpOm4uYXR0YWNoRXZlbnQmJm4uYXR0YWNoRXZlbnQoIm9udW5sb2FkIixvZSkpLGQuc2NvcGU9Y2UoZnVuY3Rpb24oZSl7cmV0dXJuIGEuYXBwZW5kQ2hpbGQoZSkuYXBwZW5kQ2hpbGQoQy5jcmVhdGVFbGVtZW50KCJkaXYiKSksInVuZGVmaW5lZCIhPXR5cGVvZiBlLnF1ZXJ5U2VsZWN0b3JBbGwmJiFlLnF1ZXJ5U2VsZWN0b3JBbGwoIjpzY29wZSBmaWVsZHNldCBkaXYiKS5sZW5ndGh9KSxkLmF0dHJpYnV0ZXM9Y2UoZnVuY3Rpb24oZSl7cmV0dXJuIGUuY2xhc3NOYW1lPSJpIiwhZS5nZXRBdHRyaWJ1dGUoImNsYXNzTmFtZSIpfSksZC5nZXRFbGVtZW50c0J5VGFnTmFtZT1jZShmdW5jdGlvbihlKXtyZXR1cm4gZS5hcHBlbmRDaGlsZChDLmNyZWF0ZUNvbW1lbnQoIiIpKSwhZS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpLmxlbmd0aH0pLGQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZT1LLnRlc3QoQy5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKSxkLmdldEJ5SWQ9Y2UoZnVuY3Rpb24oZSl7cmV0dXJuIGEuYXBwZW5kQ2hpbGQoZSkuaWQ9UywhQy5nZXRFbGVtZW50c0J5TmFtZXx8IUMuZ2V0RWxlbWVudHNCeU5hbWUoUykubGVuZ3RofSksZC5nZXRCeUlkPyhiLmZpbHRlci5JRD1mdW5jdGlvbihlKXt2YXIgdD1lLnJlcGxhY2UodGUsbmUpO3JldHVybiBmdW5jdGlvbihlKXtyZXR1cm4gZS5nZXRBdHRyaWJ1dGUoImlkIik9PT10fX0sYi5maW5kLklEPWZ1bmN0aW9uKGUsdCl7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiB0LmdldEVsZW1lbnRCeUlkJiZFKXt2YXIgbj10LmdldEVsZW1lbnRCeUlkKGUpO3JldHVybiBuP1tuXTpbXX19KTooYi5maWx0ZXIuSUQ9ZnVuY3Rpb24oZSl7dmFyIG49ZS5yZXBsYWNlKHRlLG5lKTtyZXR1cm4gZnVuY3Rpb24oZSl7dmFyIHQ9InVuZGVmaW5lZCIhPXR5cGVvZiBlLmdldEF0dHJpYnV0ZU5vZGUmJmUuZ2V0QXR0cmlidXRlTm9kZSgiaWQiKTtyZXR1cm4gdCYmdC52YWx1ZT09PW59fSxiLmZpbmQuSUQ9ZnVuY3Rpb24oZSx0KXtpZigidW5kZWZpbmVkIiE9dHlwZW9mIHQuZ2V0RWxlbWVudEJ5SWQmJkUpe3ZhciBuLHIsaSxvPXQuZ2V0RWxlbWVudEJ5SWQoZSk7aWYobyl7aWYoKG49by5nZXRBdHRyaWJ1dGVOb2RlKCJpZCIpKSYmbi52YWx1ZT09PWUpcmV0dXJuW29dO2k9dC5nZXRFbGVtZW50c0J5TmFtZShlKSxyPTA7d2hpbGUobz1pW3IrK10paWYoKG49by5nZXRBdHRyaWJ1dGVOb2RlKCJpZCIpKSYmbi52YWx1ZT09PWUpcmV0dXJuW29dfXJldHVybltdfX0pLGIuZmluZC5UQUc9ZC5nZXRFbGVtZW50c0J5VGFnTmFtZT9mdW5jdGlvbihlLHQpe3JldHVybiJ1bmRlZmluZWQiIT10eXBlb2YgdC5nZXRFbGVtZW50c0J5VGFnTmFtZT90LmdldEVsZW1lbnRzQnlUYWdOYW1lKGUpOmQucXNhP3QucXVlcnlTZWxlY3RvckFsbChlKTp2b2lkIDB9OmZ1bmN0aW9uKGUsdCl7dmFyIG4scj1bXSxpPTAsbz10LmdldEVsZW1lbnRzQnlUYWdOYW1lKGUpO2lmKCIqIj09PWUpe3doaWxlKG49b1tpKytdKTE9PT1uLm5vZGVUeXBlJiZyLnB1c2gobik7cmV0dXJuIHJ9cmV0dXJuIG99LGIuZmluZC5DTEFTUz1kLmdldEVsZW1lbnRzQnlDbGFzc05hbWUmJmZ1bmN0aW9uKGUsdCl7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiB0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUmJkUpcmV0dXJuIHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShlKX0scz1bXSx2PVtdLChkLnFzYT1LLnRlc3QoQy5xdWVyeVNlbGVjdG9yQWxsKSkmJihjZShmdW5jdGlvbihlKXt2YXIgdDthLmFwcGVuZENoaWxkKGUpLmlubmVySFRNTD0iPGEgaWQ9JyIrUysiJz48L2E+PHNlbGVjdCBpZD0nIitTKyItXHJcXCcgbXNhbGxvd2NhcHR1cmU9Jyc+PG9wdGlvbiBzZWxlY3RlZD0nJz48L29wdGlvbj48L3NlbGVjdD4iLGUucXVlcnlTZWxlY3RvckFsbCgiW21zYWxsb3djYXB0dXJlXj0nJ10iKS5sZW5ndGgmJnYucHVzaCgiWypeJF09IitNKyIqKD86Jyd8XCJcIikiKSxlLnF1ZXJ5U2VsZWN0b3JBbGwoIltzZWxlY3RlZF0iKS5sZW5ndGh8fHYucHVzaCgiXFxbIitNKyIqKD86dmFsdWV8IitSKyIpIiksZS5xdWVyeVNlbGVjdG9yQWxsKCJbaWR+PSIrUysiLV0iKS5sZW5ndGh8fHYucHVzaCgifj0iKSwodD1DLmNyZWF0ZUVsZW1lbnQoImlucHV0IikpLnNldEF0dHJpYnV0ZSgibmFtZSIsIiIpLGUuYXBwZW5kQ2hpbGQodCksZS5xdWVyeVNlbGVjdG9yQWxsKCJbbmFtZT0nJ10iKS5sZW5ndGh8fHYucHVzaCgiXFxbIitNKyIqbmFtZSIrTSsiKj0iK00rIiooPzonJ3xcIlwiKSIpLGUucXVlcnlTZWxlY3RvckFsbCgiOmNoZWNrZWQiKS5sZW5ndGh8fHYucHVzaCgiOmNoZWNrZWQiKSxlLnF1ZXJ5U2VsZWN0b3JBbGwoImEjIitTKyIrKiIpLmxlbmd0aHx8di5wdXNoKCIuIy4rWyt+XSIpLGUucXVlcnlTZWxlY3RvckFsbCgiXFxcZiIpLHYucHVzaCgiW1xcclxcblxcZl0iKX0pLGNlKGZ1bmN0aW9uKGUpe2UuaW5uZXJIVE1MPSI8YSBocmVmPScnIGRpc2FibGVkPSdkaXNhYmxlZCc+PC9hPjxzZWxlY3QgZGlzYWJsZWQ9J2Rpc2FibGVkJz48b3B0aW9uLz48L3NlbGVjdD4iO3ZhciB0PUMuY3JlYXRlRWxlbWVudCgiaW5wdXQiKTt0LnNldEF0dHJpYnV0ZSgidHlwZSIsImhpZGRlbiIpLGUuYXBwZW5kQ2hpbGQodCkuc2V0QXR0cmlidXRlKCJuYW1lIiwiRCIpLGUucXVlcnlTZWxlY3RvckFsbCgiW25hbWU9ZF0iKS5sZW5ndGgmJnYucHVzaCgibmFtZSIrTSsiKlsqXiR8IX5dPz0iKSwyIT09ZS5xdWVyeVNlbGVjdG9yQWxsKCI6ZW5hYmxlZCIpLmxlbmd0aCYmdi5wdXNoKCI6ZW5hYmxlZCIsIjpkaXNhYmxlZCIpLGEuYXBwZW5kQ2hpbGQoZSkuZGlzYWJsZWQ9ITAsMiE9PWUucXVlcnlTZWxlY3RvckFsbCgiOmRpc2FibGVkIikubGVuZ3RoJiZ2LnB1c2goIjplbmFibGVkIiwiOmRpc2FibGVkIiksZS5xdWVyeVNlbGVjdG9yQWxsKCIqLDp4Iiksdi5wdXNoKCIsLio6Iil9KSksKGQubWF0Y2hlc1NlbGVjdG9yPUsudGVzdChjPWEubWF0Y2hlc3x8YS53ZWJraXRNYXRjaGVzU2VsZWN0b3J8fGEubW96TWF0Y2hlc1NlbGVjdG9yfHxhLm9NYXRjaGVzU2VsZWN0b3J8fGEubXNNYXRjaGVzU2VsZWN0b3IpKSYmY2UoZnVuY3Rpb24oZSl7ZC5kaXNjb25uZWN0ZWRNYXRjaD1jLmNhbGwoZSwiKiIpLGMuY2FsbChlLCJbcyE9JyddOngiKSxzLnB1c2goIiE9IixGKX0pLHY9di5sZW5ndGgmJm5ldyBSZWdFeHAodi5qb2luKCJ8IikpLHM9cy5sZW5ndGgmJm5ldyBSZWdFeHAocy5qb2luKCJ8IikpLHQ9Sy50ZXN0KGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24pLHk9dHx8Sy50ZXN0KGEuY29udGFpbnMpP2Z1bmN0aW9uKGUsdCl7dmFyIG49OT09PWUubm9kZVR5cGU/ZS5kb2N1bWVudEVsZW1lbnQ6ZSxyPXQmJnQucGFyZW50Tm9kZTtyZXR1cm4gZT09PXJ8fCEoIXJ8fDEhPT1yLm5vZGVUeXBlfHwhKG4uY29udGFpbnM/bi5jb250YWlucyhyKTplLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uJiYxNiZlLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKHIpKSl9OmZ1bmN0aW9uKGUsdCl7aWYodCl3aGlsZSh0PXQucGFyZW50Tm9kZSlpZih0PT09ZSlyZXR1cm4hMDtyZXR1cm4hMX0saj10P2Z1bmN0aW9uKGUsdCl7aWYoZT09PXQpcmV0dXJuIGw9ITAsMDt2YXIgbj0hZS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbi0hdC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbjtyZXR1cm4gbnx8KDEmKG49KGUub3duZXJEb2N1bWVudHx8ZSk9PSh0Lm93bmVyRG9jdW1lbnR8fHQpP2UuY29tcGFyZURvY3VtZW50UG9zaXRpb24odCk6MSl8fCFkLnNvcnREZXRhY2hlZCYmdC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihlKT09PW4/ZT09Q3x8ZS5vd25lckRvY3VtZW50PT1wJiZ5KHAsZSk/LTE6dD09Q3x8dC5vd25lckRvY3VtZW50PT1wJiZ5KHAsdCk/MTp1P1AodSxlKS1QKHUsdCk6MDo0Jm4/LTE6MSl9OmZ1bmN0aW9uKGUsdCl7aWYoZT09PXQpcmV0dXJuIGw9ITAsMDt2YXIgbixyPTAsaT1lLnBhcmVudE5vZGUsbz10LnBhcmVudE5vZGUsYT1bZV0scz1bdF07aWYoIWl8fCFvKXJldHVybiBlPT1DPy0xOnQ9PUM/MTppPy0xOm8/MTp1P1AodSxlKS1QKHUsdCk6MDtpZihpPT09bylyZXR1cm4gcGUoZSx0KTtuPWU7d2hpbGUobj1uLnBhcmVudE5vZGUpYS51bnNoaWZ0KG4pO249dDt3aGlsZShuPW4ucGFyZW50Tm9kZSlzLnVuc2hpZnQobik7d2hpbGUoYVtyXT09PXNbcl0pcisrO3JldHVybiByP3BlKGFbcl0sc1tyXSk6YVtyXT09cD8tMTpzW3JdPT1wPzE6MH0pLEN9LHNlLm1hdGNoZXM9ZnVuY3Rpb24oZSx0KXtyZXR1cm4gc2UoZSxudWxsLG51bGwsdCl9LHNlLm1hdGNoZXNTZWxlY3Rvcj1mdW5jdGlvbihlLHQpe2lmKFQoZSksZC5tYXRjaGVzU2VsZWN0b3ImJkUmJiFOW3QrIiAiXSYmKCFzfHwhcy50ZXN0KHQpKSYmKCF2fHwhdi50ZXN0KHQpKSl0cnl7dmFyIG49Yy5jYWxsKGUsdCk7aWYobnx8ZC5kaXNjb25uZWN0ZWRNYXRjaHx8ZS5kb2N1bWVudCYmMTEhPT1lLmRvY3VtZW50Lm5vZGVUeXBlKXJldHVybiBufWNhdGNoKGUpe04odCwhMCl9cmV0dXJuIDA8c2UodCxDLG51bGwsW2VdKS5sZW5ndGh9LHNlLmNvbnRhaW5zPWZ1bmN0aW9uKGUsdCl7cmV0dXJuKGUub3duZXJEb2N1bWVudHx8ZSkhPUMmJlQoZSkseShlLHQpfSxzZS5hdHRyPWZ1bmN0aW9uKGUsdCl7KGUub3duZXJEb2N1bWVudHx8ZSkhPUMmJlQoZSk7dmFyIG49Yi5hdHRySGFuZGxlW3QudG9Mb3dlckNhc2UoKV0scj1uJiZELmNhbGwoYi5hdHRySGFuZGxlLHQudG9Mb3dlckNhc2UoKSk/bihlLHQsIUUpOnZvaWQgMDtyZXR1cm4gdm9pZCAwIT09cj9yOmQuYXR0cmlidXRlc3x8IUU/ZS5nZXRBdHRyaWJ1dGUodCk6KHI9ZS5nZXRBdHRyaWJ1dGVOb2RlKHQpKSYmci5zcGVjaWZpZWQ/ci52YWx1ZTpudWxsfSxzZS5lc2NhcGU9ZnVuY3Rpb24oZSl7cmV0dXJuKGUrIiIpLnJlcGxhY2UocmUsaWUpfSxzZS5lcnJvcj1mdW5jdGlvbihlKXt0aHJvdyBuZXcgRXJyb3IoIlN5bnRheCBlcnJvciwgdW5yZWNvZ25pemVkIGV4cHJlc3Npb246ICIrZSl9LHNlLnVuaXF1ZVNvcnQ9ZnVuY3Rpb24oZSl7dmFyIHQsbj1bXSxyPTAsaT0wO2lmKGw9IWQuZGV0ZWN0RHVwbGljYXRlcyx1PSFkLnNvcnRTdGFibGUmJmUuc2xpY2UoMCksZS5zb3J0KGopLGwpe3doaWxlKHQ9ZVtpKytdKXQ9PT1lW2ldJiYocj1uLnB1c2goaSkpO3doaWxlKHItLSllLnNwbGljZShuW3JdLDEpfXJldHVybiB1PW51bGwsZX0sbz1zZS5nZXRUZXh0PWZ1bmN0aW9uKGUpe3ZhciB0LG49IiIscj0wLGk9ZS5ub2RlVHlwZTtpZihpKXtpZigxPT09aXx8OT09PWl8fDExPT09aSl7aWYoInN0cmluZyI9PXR5cGVvZiBlLnRleHRDb250ZW50KXJldHVybiBlLnRleHRDb250ZW50O2ZvcihlPWUuZmlyc3RDaGlsZDtlO2U9ZS5uZXh0U2libGluZyluKz1vKGUpfWVsc2UgaWYoMz09PWl8fDQ9PT1pKXJldHVybiBlLm5vZGVWYWx1ZX1lbHNlIHdoaWxlKHQ9ZVtyKytdKW4rPW8odCk7cmV0dXJuIG59LChiPXNlLnNlbGVjdG9ycz17Y2FjaGVMZW5ndGg6NTAsY3JlYXRlUHNldWRvOmxlLG1hdGNoOkcsYXR0ckhhbmRsZTp7fSxmaW5kOnt9LHJlbGF0aXZlOnsiPiI6e2RpcjoicGFyZW50Tm9kZSIsZmlyc3Q6ITB9LCIgIjp7ZGlyOiJwYXJlbnROb2RlIn0sIisiOntkaXI6InByZXZpb3VzU2libGluZyIsZmlyc3Q6ITB9LCJ+Ijp7ZGlyOiJwcmV2aW91c1NpYmxpbmcifX0scHJlRmlsdGVyOntBVFRSOmZ1bmN0aW9uKGUpe3JldHVybiBlWzFdPWVbMV0ucmVwbGFjZSh0ZSxuZSksZVszXT0oZVszXXx8ZVs0XXx8ZVs1XXx8IiIpLnJlcGxhY2UodGUsbmUpLCJ+PSI9PT1lWzJdJiYoZVszXT0iICIrZVszXSsiICIpLGUuc2xpY2UoMCw0KX0sQ0hJTEQ6ZnVuY3Rpb24oZSl7cmV0dXJuIGVbMV09ZVsxXS50b0xvd2VyQ2FzZSgpLCJudGgiPT09ZVsxXS5zbGljZSgwLDMpPyhlWzNdfHxzZS5lcnJvcihlWzBdKSxlWzRdPSsoZVs0XT9lWzVdKyhlWzZdfHwxKToyKigiZXZlbiI9PT1lWzNdfHwib2RkIj09PWVbM10pKSxlWzVdPSsoZVs3XStlWzhdfHwib2RkIj09PWVbM10pKTplWzNdJiZzZS5lcnJvcihlWzBdKSxlfSxQU0VVRE86ZnVuY3Rpb24oZSl7dmFyIHQsbj0hZVs2XSYmZVsyXTtyZXR1cm4gRy5DSElMRC50ZXN0KGVbMF0pP251bGw6KGVbM10/ZVsyXT1lWzRdfHxlWzVdfHwiIjpuJiZYLnRlc3QobikmJih0PWgobiwhMCkpJiYodD1uLmluZGV4T2YoIikiLG4ubGVuZ3RoLXQpLW4ubGVuZ3RoKSYmKGVbMF09ZVswXS5zbGljZSgwLHQpLGVbMl09bi5zbGljZSgwLHQpKSxlLnNsaWNlKDAsMykpfX0sZmlsdGVyOntUQUc6ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5yZXBsYWNlKHRlLG5lKS50b0xvd2VyQ2FzZSgpO3JldHVybiIqIj09PWU/ZnVuY3Rpb24oKXtyZXR1cm4hMH06ZnVuY3Rpb24oZSl7cmV0dXJuIGUubm9kZU5hbWUmJmUubm9kZU5hbWUudG9Mb3dlckNhc2UoKT09PXR9fSxDTEFTUzpmdW5jdGlvbihlKXt2YXIgdD1tW2UrIiAiXTtyZXR1cm4gdHx8KHQ9bmV3IFJlZ0V4cCgiKF58IitNKyIpIitlKyIoIitNKyJ8JCkiKSkmJm0oZSxmdW5jdGlvbihlKXtyZXR1cm4gdC50ZXN0KCJzdHJpbmciPT10eXBlb2YgZS5jbGFzc05hbWUmJmUuY2xhc3NOYW1lfHwidW5kZWZpbmVkIiE9dHlwZW9mIGUuZ2V0QXR0cmlidXRlJiZlLmdldEF0dHJpYnV0ZSgiY2xhc3MiKXx8IiIpfSl9LEFUVFI6ZnVuY3Rpb24obixyLGkpe3JldHVybiBmdW5jdGlvbihlKXt2YXIgdD1zZS5hdHRyKGUsbik7cmV0dXJuIG51bGw9PXQ/IiE9Ij09PXI6IXJ8fCh0Kz0iIiwiPSI9PT1yP3Q9PT1pOiIhPSI9PT1yP3QhPT1pOiJePSI9PT1yP2kmJjA9PT10LmluZGV4T2YoaSk6Iio9Ij09PXI/aSYmLTE8dC5pbmRleE9mKGkpOiIkPSI9PT1yP2kmJnQuc2xpY2UoLWkubGVuZ3RoKT09PWk6In49Ij09PXI/LTE8KCIgIit0LnJlcGxhY2UoQiwiICIpKyIgIikuaW5kZXhPZihpKToifD0iPT09ciYmKHQ9PT1pfHx0LnNsaWNlKDAsaS5sZW5ndGgrMSk9PT1pKyItIikpfX0sQ0hJTEQ6ZnVuY3Rpb24oaCxlLHQsZyx2KXt2YXIgeT0ibnRoIiE9PWguc2xpY2UoMCwzKSxtPSJsYXN0IiE9PWguc2xpY2UoLTQpLHg9Im9mLXR5cGUiPT09ZTtyZXR1cm4gMT09PWcmJjA9PT12P2Z1bmN0aW9uKGUpe3JldHVybiEhZS5wYXJlbnROb2RlfTpmdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvLGEscyx1LGw9eSE9PW0/Im5leHRTaWJsaW5nIjoicHJldmlvdXNTaWJsaW5nIixjPWUucGFyZW50Tm9kZSxmPXgmJmUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSxwPSFuJiYheCxkPSExO2lmKGMpe2lmKHkpe3doaWxlKGwpe2E9ZTt3aGlsZShhPWFbbF0paWYoeD9hLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk9PT1mOjE9PT1hLm5vZGVUeXBlKXJldHVybiExO3U9bD0ib25seSI9PT1oJiYhdSYmIm5leHRTaWJsaW5nIn1yZXR1cm4hMH1pZih1PVttP2MuZmlyc3RDaGlsZDpjLmxhc3RDaGlsZF0sbSYmcCl7ZD0ocz0ocj0oaT0obz0oYT1jKVtTXXx8KGFbU109e30pKVthLnVuaXF1ZUlEXXx8KG9bYS51bmlxdWVJRF09e30pKVtoXXx8W10pWzBdPT09ayYmclsxXSkmJnJbMl0sYT1zJiZjLmNoaWxkTm9kZXNbc107d2hpbGUoYT0rK3MmJmEmJmFbbF18fChkPXM9MCl8fHUucG9wKCkpaWYoMT09PWEubm9kZVR5cGUmJisrZCYmYT09PWUpe2lbaF09W2sscyxkXTticmVha319ZWxzZSBpZihwJiYoZD1zPShyPShpPShvPShhPWUpW1NdfHwoYVtTXT17fSkpW2EudW5pcXVlSURdfHwob1thLnVuaXF1ZUlEXT17fSkpW2hdfHxbXSlbMF09PT1rJiZyWzFdKSwhMT09PWQpd2hpbGUoYT0rK3MmJmEmJmFbbF18fChkPXM9MCl8fHUucG9wKCkpaWYoKHg/YS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpPT09ZjoxPT09YS5ub2RlVHlwZSkmJisrZCYmKHAmJigoaT0obz1hW1NdfHwoYVtTXT17fSkpW2EudW5pcXVlSURdfHwob1thLnVuaXF1ZUlEXT17fSkpW2hdPVtrLGRdKSxhPT09ZSkpYnJlYWs7cmV0dXJuKGQtPXYpPT09Z3x8ZCVnPT0wJiYwPD1kL2d9fX0sUFNFVURPOmZ1bmN0aW9uKGUsbyl7dmFyIHQsYT1iLnBzZXVkb3NbZV18fGIuc2V0RmlsdGVyc1tlLnRvTG93ZXJDYXNlKCldfHxzZS5lcnJvcigidW5zdXBwb3J0ZWQgcHNldWRvOiAiK2UpO3JldHVybiBhW1NdP2Eobyk6MTxhLmxlbmd0aD8odD1bZSxlLCIiLG9dLGIuc2V0RmlsdGVycy5oYXNPd25Qcm9wZXJ0eShlLnRvTG93ZXJDYXNlKCkpP2xlKGZ1bmN0aW9uKGUsdCl7dmFyIG4scj1hKGUsbyksaT1yLmxlbmd0aDt3aGlsZShpLS0pZVtuPVAoZSxyW2ldKV09ISh0W25dPXJbaV0pfSk6ZnVuY3Rpb24oZSl7cmV0dXJuIGEoZSwwLHQpfSk6YX19LHBzZXVkb3M6e25vdDpsZShmdW5jdGlvbihlKXt2YXIgcj1bXSxpPVtdLHM9ZihlLnJlcGxhY2UoJCwiJDEiKSk7cmV0dXJuIHNbU10/bGUoZnVuY3Rpb24oZSx0LG4scil7dmFyIGksbz1zKGUsbnVsbCxyLFtdKSxhPWUubGVuZ3RoO3doaWxlKGEtLSkoaT1vW2FdKSYmKGVbYV09ISh0W2FdPWkpKX0pOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gclswXT1lLHMocixudWxsLG4saSksclswXT1udWxsLCFpLnBvcCgpfX0pLGhhczpsZShmdW5jdGlvbih0KXtyZXR1cm4gZnVuY3Rpb24oZSl7cmV0dXJuIDA8c2UodCxlKS5sZW5ndGh9fSksY29udGFpbnM6bGUoZnVuY3Rpb24odCl7cmV0dXJuIHQ9dC5yZXBsYWNlKHRlLG5lKSxmdW5jdGlvbihlKXtyZXR1cm4tMTwoZS50ZXh0Q29udGVudHx8byhlKSkuaW5kZXhPZih0KX19KSxsYW5nOmxlKGZ1bmN0aW9uKG4pe3JldHVybiBWLnRlc3Qobnx8IiIpfHxzZS5lcnJvcigidW5zdXBwb3J0ZWQgbGFuZzogIituKSxuPW4ucmVwbGFjZSh0ZSxuZSkudG9Mb3dlckNhc2UoKSxmdW5jdGlvbihlKXt2YXIgdDtkb3tpZih0PUU/ZS5sYW5nOmUuZ2V0QXR0cmlidXRlKCJ4bWw6bGFuZyIpfHxlLmdldEF0dHJpYnV0ZSgibGFuZyIpKXJldHVybih0PXQudG9Mb3dlckNhc2UoKSk9PT1ufHwwPT09dC5pbmRleE9mKG4rIi0iKX13aGlsZSgoZT1lLnBhcmVudE5vZGUpJiYxPT09ZS5ub2RlVHlwZSk7cmV0dXJuITF9fSksdGFyZ2V0OmZ1bmN0aW9uKGUpe3ZhciB0PW4ubG9jYXRpb24mJm4ubG9jYXRpb24uaGFzaDtyZXR1cm4gdCYmdC5zbGljZSgxKT09PWUuaWR9LHJvb3Q6ZnVuY3Rpb24oZSl7cmV0dXJuIGU9PT1hfSxmb2N1czpmdW5jdGlvbihlKXtyZXR1cm4gZT09PUMuYWN0aXZlRWxlbWVudCYmKCFDLmhhc0ZvY3VzfHxDLmhhc0ZvY3VzKCkpJiYhIShlLnR5cGV8fGUuaHJlZnx8fmUudGFiSW5kZXgpfSxlbmFibGVkOmdlKCExKSxkaXNhYmxlZDpnZSghMCksY2hlY2tlZDpmdW5jdGlvbihlKXt2YXIgdD1lLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7cmV0dXJuImlucHV0Ij09PXQmJiEhZS5jaGVja2VkfHwib3B0aW9uIj09PXQmJiEhZS5zZWxlY3RlZH0sc2VsZWN0ZWQ6ZnVuY3Rpb24oZSl7cmV0dXJuIGUucGFyZW50Tm9kZSYmZS5wYXJlbnROb2RlLnNlbGVjdGVkSW5kZXgsITA9PT1lLnNlbGVjdGVkfSxlbXB0eTpmdW5jdGlvbihlKXtmb3IoZT1lLmZpcnN0Q2hpbGQ7ZTtlPWUubmV4dFNpYmxpbmcpaWYoZS5ub2RlVHlwZTw2KXJldHVybiExO3JldHVybiEwfSxwYXJlbnQ6ZnVuY3Rpb24oZSl7cmV0dXJuIWIucHNldWRvcy5lbXB0eShlKX0saGVhZGVyOmZ1bmN0aW9uKGUpe3JldHVybiBKLnRlc3QoZS5ub2RlTmFtZSl9LGlucHV0OmZ1bmN0aW9uKGUpe3JldHVybiBRLnRlc3QoZS5ub2RlTmFtZSl9LGJ1dHRvbjpmdW5jdGlvbihlKXt2YXIgdD1lLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7cmV0dXJuImlucHV0Ij09PXQmJiJidXR0b24iPT09ZS50eXBlfHwiYnV0dG9uIj09PXR9LHRleHQ6ZnVuY3Rpb24oZSl7dmFyIHQ7cmV0dXJuImlucHV0Ij09PWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSYmInRleHQiPT09ZS50eXBlJiYobnVsbD09KHQ9ZS5nZXRBdHRyaWJ1dGUoInR5cGUiKSl8fCJ0ZXh0Ij09PXQudG9Mb3dlckNhc2UoKSl9LGZpcnN0OnZlKGZ1bmN0aW9uKCl7cmV0dXJuWzBdfSksbGFzdDp2ZShmdW5jdGlvbihlLHQpe3JldHVyblt0LTFdfSksZXE6dmUoZnVuY3Rpb24oZSx0LG4pe3JldHVybltuPDA/bit0Om5dfSksZXZlbjp2ZShmdW5jdGlvbihlLHQpe2Zvcih2YXIgbj0wO248dDtuKz0yKWUucHVzaChuKTtyZXR1cm4gZX0pLG9kZDp2ZShmdW5jdGlvbihlLHQpe2Zvcih2YXIgbj0xO248dDtuKz0yKWUucHVzaChuKTtyZXR1cm4gZX0pLGx0OnZlKGZ1bmN0aW9uKGUsdCxuKXtmb3IodmFyIHI9bjwwP24rdDp0PG4/dDpuOzA8PS0tcjspZS5wdXNoKHIpO3JldHVybiBlfSksZ3Q6dmUoZnVuY3Rpb24oZSx0LG4pe2Zvcih2YXIgcj1uPDA/bit0Om47KytyPHQ7KWUucHVzaChyKTtyZXR1cm4gZX0pfX0pLnBzZXVkb3MubnRoPWIucHNldWRvcy5lcSx7cmFkaW86ITAsY2hlY2tib3g6ITAsZmlsZTohMCxwYXNzd29yZDohMCxpbWFnZTohMH0pYi5wc2V1ZG9zW2VdPWRlKGUpO2ZvcihlIGlue3N1Ym1pdDohMCxyZXNldDohMH0pYi5wc2V1ZG9zW2VdPWhlKGUpO2Z1bmN0aW9uIG1lKCl7fWZ1bmN0aW9uIHhlKGUpe2Zvcih2YXIgdD0wLG49ZS5sZW5ndGgscj0iIjt0PG47dCsrKXIrPWVbdF0udmFsdWU7cmV0dXJuIHJ9ZnVuY3Rpb24gYmUocyxlLHQpe3ZhciB1PWUuZGlyLGw9ZS5uZXh0LGM9bHx8dSxmPXQmJiJwYXJlbnROb2RlIj09PWMscD1yKys7cmV0dXJuIGUuZmlyc3Q/ZnVuY3Rpb24oZSx0LG4pe3doaWxlKGU9ZVt1XSlpZigxPT09ZS5ub2RlVHlwZXx8ZilyZXR1cm4gcyhlLHQsbik7cmV0dXJuITF9OmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG8sYT1bayxwXTtpZihuKXt3aGlsZShlPWVbdV0paWYoKDE9PT1lLm5vZGVUeXBlfHxmKSYmcyhlLHQsbikpcmV0dXJuITB9ZWxzZSB3aGlsZShlPWVbdV0paWYoMT09PWUubm9kZVR5cGV8fGYpaWYoaT0obz1lW1NdfHwoZVtTXT17fSkpW2UudW5pcXVlSURdfHwob1tlLnVuaXF1ZUlEXT17fSksbCYmbD09PWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSllPWVbdV18fGU7ZWxzZXtpZigocj1pW2NdKSYmclswXT09PWsmJnJbMV09PT1wKXJldHVybiBhWzJdPXJbMl07aWYoKGlbY109YSlbMl09cyhlLHQsbikpcmV0dXJuITB9cmV0dXJuITF9fWZ1bmN0aW9uIHdlKGkpe3JldHVybiAxPGkubGVuZ3RoP2Z1bmN0aW9uKGUsdCxuKXt2YXIgcj1pLmxlbmd0aDt3aGlsZShyLS0paWYoIWlbcl0oZSx0LG4pKXJldHVybiExO3JldHVybiEwfTppWzBdfWZ1bmN0aW9uIFRlKGUsdCxuLHIsaSl7Zm9yKHZhciBvLGE9W10scz0wLHU9ZS5sZW5ndGgsbD1udWxsIT10O3M8dTtzKyspKG89ZVtzXSkmJihuJiYhbihvLHIsaSl8fChhLnB1c2gobyksbCYmdC5wdXNoKHMpKSk7cmV0dXJuIGF9ZnVuY3Rpb24gQ2UoZCxoLGcsdix5LGUpe3JldHVybiB2JiYhdltTXSYmKHY9Q2UodikpLHkmJiF5W1NdJiYoeT1DZSh5LGUpKSxsZShmdW5jdGlvbihlLHQsbixyKXt2YXIgaSxvLGEscz1bXSx1PVtdLGw9dC5sZW5ndGgsYz1lfHxmdW5jdGlvbihlLHQsbil7Zm9yKHZhciByPTAsaT10Lmxlbmd0aDtyPGk7cisrKXNlKGUsdFtyXSxuKTtyZXR1cm4gbn0oaHx8IioiLG4ubm9kZVR5cGU/W25dOm4sW10pLGY9IWR8fCFlJiZoP2M6VGUoYyxzLGQsbixyKSxwPWc/eXx8KGU/ZDpsfHx2KT9bXTp0OmY7aWYoZyYmZyhmLHAsbixyKSx2KXtpPVRlKHAsdSksdihpLFtdLG4sciksbz1pLmxlbmd0aDt3aGlsZShvLS0pKGE9aVtvXSkmJihwW3Vbb11dPSEoZlt1W29dXT1hKSl9aWYoZSl7aWYoeXx8ZCl7aWYoeSl7aT1bXSxvPXAubGVuZ3RoO3doaWxlKG8tLSkoYT1wW29dKSYmaS5wdXNoKGZbb109YSk7eShudWxsLHA9W10saSxyKX1vPXAubGVuZ3RoO3doaWxlKG8tLSkoYT1wW29dKSYmLTE8KGk9eT9QKGUsYSk6c1tvXSkmJihlW2ldPSEodFtpXT1hKSl9fWVsc2UgcD1UZShwPT09dD9wLnNwbGljZShsLHAubGVuZ3RoKTpwKSx5P3kobnVsbCx0LHAscik6SC5hcHBseSh0LHApfSl9ZnVuY3Rpb24gRWUoZSl7Zm9yKHZhciBpLHQsbixyPWUubGVuZ3RoLG89Yi5yZWxhdGl2ZVtlWzBdLnR5cGVdLGE9b3x8Yi5yZWxhdGl2ZVsiICJdLHM9bz8xOjAsdT1iZShmdW5jdGlvbihlKXtyZXR1cm4gZT09PWl9LGEsITApLGw9YmUoZnVuY3Rpb24oZSl7cmV0dXJuLTE8UChpLGUpfSxhLCEwKSxjPVtmdW5jdGlvbihlLHQsbil7dmFyIHI9IW8mJihufHx0IT09dyl8fCgoaT10KS5ub2RlVHlwZT91KGUsdCxuKTpsKGUsdCxuKSk7cmV0dXJuIGk9bnVsbCxyfV07czxyO3MrKylpZih0PWIucmVsYXRpdmVbZVtzXS50eXBlXSljPVtiZSh3ZShjKSx0KV07ZWxzZXtpZigodD1iLmZpbHRlcltlW3NdLnR5cGVdLmFwcGx5KG51bGwsZVtzXS5tYXRjaGVzKSlbU10pe2ZvcihuPSsrcztuPHI7bisrKWlmKGIucmVsYXRpdmVbZVtuXS50eXBlXSlicmVhaztyZXR1cm4gQ2UoMTxzJiZ3ZShjKSwxPHMmJnhlKGUuc2xpY2UoMCxzLTEpLmNvbmNhdCh7dmFsdWU6IiAiPT09ZVtzLTJdLnR5cGU/IioiOiIifSkpLnJlcGxhY2UoJCwiJDEiKSx0LHM8biYmRWUoZS5zbGljZShzLG4pKSxuPHImJkVlKGU9ZS5zbGljZShuKSksbjxyJiZ4ZShlKSl9Yy5wdXNoKHQpfXJldHVybiB3ZShjKX1yZXR1cm4gbWUucHJvdG90eXBlPWIuZmlsdGVycz1iLnBzZXVkb3MsYi5zZXRGaWx0ZXJzPW5ldyBtZSxoPXNlLnRva2VuaXplPWZ1bmN0aW9uKGUsdCl7dmFyIG4scixpLG8sYSxzLHUsbD14W2UrIiAiXTtpZihsKXJldHVybiB0PzA6bC5zbGljZSgwKTthPWUscz1bXSx1PWIucHJlRmlsdGVyO3doaWxlKGEpe2ZvcihvIGluIG4mJiEocj1fLmV4ZWMoYSkpfHwociYmKGE9YS5zbGljZShyWzBdLmxlbmd0aCl8fGEpLHMucHVzaChpPVtdKSksbj0hMSwocj16LmV4ZWMoYSkpJiYobj1yLnNoaWZ0KCksaS5wdXNoKHt2YWx1ZTpuLHR5cGU6clswXS5yZXBsYWNlKCQsIiAiKX0pLGE9YS5zbGljZShuLmxlbmd0aCkpLGIuZmlsdGVyKSEocj1HW29dLmV4ZWMoYSkpfHx1W29dJiYhKHI9dVtvXShyKSl8fChuPXIuc2hpZnQoKSxpLnB1c2goe3ZhbHVlOm4sdHlwZTpvLG1hdGNoZXM6cn0pLGE9YS5zbGljZShuLmxlbmd0aCkpO2lmKCFuKWJyZWFrfXJldHVybiB0P2EubGVuZ3RoOmE/c2UuZXJyb3IoZSk6eChlLHMpLnNsaWNlKDApfSxmPXNlLmNvbXBpbGU9ZnVuY3Rpb24oZSx0KXt2YXIgbix2LHksbSx4LHIsaT1bXSxvPVtdLGE9QVtlKyIgIl07aWYoIWEpe3R8fCh0PWgoZSkpLG49dC5sZW5ndGg7d2hpbGUobi0tKShhPUVlKHRbbl0pKVtTXT9pLnB1c2goYSk6by5wdXNoKGEpOyhhPUEoZSwodj1vLG09MDwoeT1pKS5sZW5ndGgseD0wPHYubGVuZ3RoLHI9ZnVuY3Rpb24oZSx0LG4scixpKXt2YXIgbyxhLHMsdT0wLGw9IjAiLGM9ZSYmW10sZj1bXSxwPXcsZD1lfHx4JiZiLmZpbmQuVEFHKCIqIixpKSxoPWsrPW51bGw9PXA/MTpNYXRoLnJhbmRvbSgpfHwuMSxnPWQubGVuZ3RoO2ZvcihpJiYodz10PT1DfHx0fHxpKTtsIT09ZyYmbnVsbCE9KG89ZFtsXSk7bCsrKXtpZih4JiZvKXthPTAsdHx8by5vd25lckRvY3VtZW50PT1DfHwoVChvKSxuPSFFKTt3aGlsZShzPXZbYSsrXSlpZihzKG8sdHx8QyxuKSl7ci5wdXNoKG8pO2JyZWFrfWkmJihrPWgpfW0mJigobz0hcyYmbykmJnUtLSxlJiZjLnB1c2gobykpfWlmKHUrPWwsbSYmbCE9PXUpe2E9MDt3aGlsZShzPXlbYSsrXSlzKGMsZix0LG4pO2lmKGUpe2lmKDA8dSl3aGlsZShsLS0pY1tsXXx8ZltsXXx8KGZbbF09cS5jYWxsKHIpKTtmPVRlKGYpfUguYXBwbHkocixmKSxpJiYhZSYmMDxmLmxlbmd0aCYmMTx1K3kubGVuZ3RoJiZzZS51bmlxdWVTb3J0KHIpfXJldHVybiBpJiYoaz1oLHc9cCksY30sbT9sZShyKTpyKSkpLnNlbGVjdG9yPWV9cmV0dXJuIGF9LGc9c2Uuc2VsZWN0PWZ1bmN0aW9uKGUsdCxuLHIpe3ZhciBpLG8sYSxzLHUsbD0iZnVuY3Rpb24iPT10eXBlb2YgZSYmZSxjPSFyJiZoKGU9bC5zZWxlY3Rvcnx8ZSk7aWYobj1ufHxbXSwxPT09Yy5sZW5ndGgpe2lmKDI8KG89Y1swXT1jWzBdLnNsaWNlKDApKS5sZW5ndGgmJiJJRCI9PT0oYT1vWzBdKS50eXBlJiY5PT09dC5ub2RlVHlwZSYmRSYmYi5yZWxhdGl2ZVtvWzFdLnR5cGVdKXtpZighKHQ9KGIuZmluZC5JRChhLm1hdGNoZXNbMF0ucmVwbGFjZSh0ZSxuZSksdCl8fFtdKVswXSkpcmV0dXJuIG47bCYmKHQ9dC5wYXJlbnROb2RlKSxlPWUuc2xpY2Uoby5zaGlmdCgpLnZhbHVlLmxlbmd0aCl9aT1HLm5lZWRzQ29udGV4dC50ZXN0KGUpPzA6by5sZW5ndGg7d2hpbGUoaS0tKXtpZihhPW9baV0sYi5yZWxhdGl2ZVtzPWEudHlwZV0pYnJlYWs7aWYoKHU9Yi5maW5kW3NdKSYmKHI9dShhLm1hdGNoZXNbMF0ucmVwbGFjZSh0ZSxuZSksZWUudGVzdChvWzBdLnR5cGUpJiZ5ZSh0LnBhcmVudE5vZGUpfHx0KSkpe2lmKG8uc3BsaWNlKGksMSksIShlPXIubGVuZ3RoJiZ4ZShvKSkpcmV0dXJuIEguYXBwbHkobixyKSxuO2JyZWFrfX19cmV0dXJuKGx8fGYoZSxjKSkocix0LCFFLG4sIXR8fGVlLnRlc3QoZSkmJnllKHQucGFyZW50Tm9kZSl8fHQpLG59LGQuc29ydFN0YWJsZT1TLnNwbGl0KCIiKS5zb3J0KGopLmpvaW4oIiIpPT09UyxkLmRldGVjdER1cGxpY2F0ZXM9ISFsLFQoKSxkLnNvcnREZXRhY2hlZD1jZShmdW5jdGlvbihlKXtyZXR1cm4gMSZlLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKEMuY3JlYXRlRWxlbWVudCgiZmllbGRzZXQiKSl9KSxjZShmdW5jdGlvbihlKXtyZXR1cm4gZS5pbm5lckhUTUw9IjxhIGhyZWY9JyMnPjwvYT4iLCIjIj09PWUuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoImhyZWYiKX0pfHxmZSgidHlwZXxocmVmfGhlaWdodHx3aWR0aCIsZnVuY3Rpb24oZSx0LG4pe2lmKCFuKXJldHVybiBlLmdldEF0dHJpYnV0ZSh0LCJ0eXBlIj09PXQudG9Mb3dlckNhc2UoKT8xOjIpfSksZC5hdHRyaWJ1dGVzJiZjZShmdW5jdGlvbihlKXtyZXR1cm4gZS5pbm5lckhUTUw9IjxpbnB1dC8+IixlLmZpcnN0Q2hpbGQuc2V0QXR0cmlidXRlKCJ2YWx1ZSIsIiIpLCIiPT09ZS5maXJzdENoaWxkLmdldEF0dHJpYnV0ZSgidmFsdWUiKX0pfHxmZSgidmFsdWUiLGZ1bmN0aW9uKGUsdCxuKXtpZighbiYmImlucHV0Ij09PWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSlyZXR1cm4gZS5kZWZhdWx0VmFsdWV9KSxjZShmdW5jdGlvbihlKXtyZXR1cm4gbnVsbD09ZS5nZXRBdHRyaWJ1dGUoImRpc2FibGVkIil9KXx8ZmUoUixmdW5jdGlvbihlLHQsbil7dmFyIHI7aWYoIW4pcmV0dXJuITA9PT1lW3RdP3QudG9Mb3dlckNhc2UoKToocj1lLmdldEF0dHJpYnV0ZU5vZGUodCkpJiZyLnNwZWNpZmllZD9yLnZhbHVlOm51bGx9KSxzZX0oQyk7Uy5maW5kPWQsUy5leHByPWQuc2VsZWN0b3JzLFMuZXhwclsiOiJdPVMuZXhwci5wc2V1ZG9zLFMudW5pcXVlU29ydD1TLnVuaXF1ZT1kLnVuaXF1ZVNvcnQsUy50ZXh0PWQuZ2V0VGV4dCxTLmlzWE1MRG9jPWQuaXNYTUwsUy5jb250YWlucz1kLmNvbnRhaW5zLFMuZXNjYXBlU2VsZWN0b3I9ZC5lc2NhcGU7dmFyIGg9ZnVuY3Rpb24oZSx0LG4pe3ZhciByPVtdLGk9dm9pZCAwIT09bjt3aGlsZSgoZT1lW3RdKSYmOSE9PWUubm9kZVR5cGUpaWYoMT09PWUubm9kZVR5cGUpe2lmKGkmJlMoZSkuaXMobikpYnJlYWs7ci5wdXNoKGUpfXJldHVybiByfSxUPWZ1bmN0aW9uKGUsdCl7Zm9yKHZhciBuPVtdO2U7ZT1lLm5leHRTaWJsaW5nKTE9PT1lLm5vZGVUeXBlJiZlIT09dCYmbi5wdXNoKGUpO3JldHVybiBufSxrPVMuZXhwci5tYXRjaC5uZWVkc0NvbnRleHQ7ZnVuY3Rpb24gQShlLHQpe3JldHVybiBlLm5vZGVOYW1lJiZlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk9PT10LnRvTG93ZXJDYXNlKCl9dmFyIE49L148KFthLXpdW15cL1wwPjpceDIwXHRcclxuXGZdKilbXHgyMFx0XHJcblxmXSpcLz8+KD86PFwvXDE+fCkkL2k7ZnVuY3Rpb24gaihlLG4scil7cmV0dXJuIG0obik/Uy5ncmVwKGUsZnVuY3Rpb24oZSx0KXtyZXR1cm4hIW4uY2FsbChlLHQsZSkhPT1yfSk6bi5ub2RlVHlwZT9TLmdyZXAoZSxmdW5jdGlvbihlKXtyZXR1cm4gZT09PW4hPT1yfSk6InN0cmluZyIhPXR5cGVvZiBuP1MuZ3JlcChlLGZ1bmN0aW9uKGUpe3JldHVybi0xPGkuY2FsbChuLGUpIT09cn0pOlMuZmlsdGVyKG4sZSxyKX1TLmZpbHRlcj1mdW5jdGlvbihlLHQsbil7dmFyIHI9dFswXTtyZXR1cm4gbiYmKGU9Ijpub3QoIitlKyIpIiksMT09PXQubGVuZ3RoJiYxPT09ci5ub2RlVHlwZT9TLmZpbmQubWF0Y2hlc1NlbGVjdG9yKHIsZSk/W3JdOltdOlMuZmluZC5tYXRjaGVzKGUsUy5ncmVwKHQsZnVuY3Rpb24oZSl7cmV0dXJuIDE9PT1lLm5vZGVUeXBlfSkpfSxTLmZuLmV4dGVuZCh7ZmluZDpmdW5jdGlvbihlKXt2YXIgdCxuLHI9dGhpcy5sZW5ndGgsaT10aGlzO2lmKCJzdHJpbmciIT10eXBlb2YgZSlyZXR1cm4gdGhpcy5wdXNoU3RhY2soUyhlKS5maWx0ZXIoZnVuY3Rpb24oKXtmb3IodD0wO3Q8cjt0KyspaWYoUy5jb250YWlucyhpW3RdLHRoaXMpKXJldHVybiEwfSkpO2ZvcihuPXRoaXMucHVzaFN0YWNrKFtdKSx0PTA7dDxyO3QrKylTLmZpbmQoZSxpW3RdLG4pO3JldHVybiAxPHI/Uy51bmlxdWVTb3J0KG4pOm59LGZpbHRlcjpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2soaih0aGlzLGV8fFtdLCExKSl9LG5vdDpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2soaih0aGlzLGV8fFtdLCEwKSl9LGlzOmZ1bmN0aW9uKGUpe3JldHVybiEhaih0aGlzLCJzdHJpbmciPT10eXBlb2YgZSYmay50ZXN0KGUpP1MoZSk6ZXx8W10sITEpLmxlbmd0aH19KTt2YXIgRCxxPS9eKD86XHMqKDxbXHdcV10rPilbXj5dKnwjKFtcdy1dKykpJC87KFMuZm4uaW5pdD1mdW5jdGlvbihlLHQsbil7dmFyIHIsaTtpZighZSlyZXR1cm4gdGhpcztpZihuPW58fEQsInN0cmluZyI9PXR5cGVvZiBlKXtpZighKHI9IjwiPT09ZVswXSYmIj4iPT09ZVtlLmxlbmd0aC0xXSYmMzw9ZS5sZW5ndGg/W251bGwsZSxudWxsXTpxLmV4ZWMoZSkpfHwhclsxXSYmdClyZXR1cm4hdHx8dC5qcXVlcnk/KHR8fG4pLmZpbmQoZSk6dGhpcy5jb25zdHJ1Y3Rvcih0KS5maW5kKGUpO2lmKHJbMV0pe2lmKHQ9dCBpbnN0YW5jZW9mIFM/dFswXTp0LFMubWVyZ2UodGhpcyxTLnBhcnNlSFRNTChyWzFdLHQmJnQubm9kZVR5cGU/dC5vd25lckRvY3VtZW50fHx0OkUsITApKSxOLnRlc3QoclsxXSkmJlMuaXNQbGFpbk9iamVjdCh0KSlmb3IociBpbiB0KW0odGhpc1tyXSk/dGhpc1tyXSh0W3JdKTp0aGlzLmF0dHIocix0W3JdKTtyZXR1cm4gdGhpc31yZXR1cm4oaT1FLmdldEVsZW1lbnRCeUlkKHJbMl0pKSYmKHRoaXNbMF09aSx0aGlzLmxlbmd0aD0xKSx0aGlzfXJldHVybiBlLm5vZGVUeXBlPyh0aGlzWzBdPWUsdGhpcy5sZW5ndGg9MSx0aGlzKTptKGUpP3ZvaWQgMCE9PW4ucmVhZHk/bi5yZWFkeShlKTplKFMpOlMubWFrZUFycmF5KGUsdGhpcyl9KS5wcm90b3R5cGU9Uy5mbixEPVMoRSk7dmFyIEw9L14oPzpwYXJlbnRzfHByZXYoPzpVbnRpbHxBbGwpKS8sSD17Y2hpbGRyZW46ITAsY29udGVudHM6ITAsbmV4dDohMCxwcmV2OiEwfTtmdW5jdGlvbiBPKGUsdCl7d2hpbGUoKGU9ZVt0XSkmJjEhPT1lLm5vZGVUeXBlKTtyZXR1cm4gZX1TLmZuLmV4dGVuZCh7aGFzOmZ1bmN0aW9uKGUpe3ZhciB0PVMoZSx0aGlzKSxuPXQubGVuZ3RoO3JldHVybiB0aGlzLmZpbHRlcihmdW5jdGlvbigpe2Zvcih2YXIgZT0wO2U8bjtlKyspaWYoUy5jb250YWlucyh0aGlzLHRbZV0pKXJldHVybiEwfSl9LGNsb3Nlc3Q6ZnVuY3Rpb24oZSx0KXt2YXIgbixyPTAsaT10aGlzLmxlbmd0aCxvPVtdLGE9InN0cmluZyIhPXR5cGVvZiBlJiZTKGUpO2lmKCFrLnRlc3QoZSkpZm9yKDtyPGk7cisrKWZvcihuPXRoaXNbcl07biYmbiE9PXQ7bj1uLnBhcmVudE5vZGUpaWYobi5ub2RlVHlwZTwxMSYmKGE/LTE8YS5pbmRleChuKToxPT09bi5ub2RlVHlwZSYmUy5maW5kLm1hdGNoZXNTZWxlY3RvcihuLGUpKSl7by5wdXNoKG4pO2JyZWFrfXJldHVybiB0aGlzLnB1c2hTdGFjaygxPG8ubGVuZ3RoP1MudW5pcXVlU29ydChvKTpvKX0saW5kZXg6ZnVuY3Rpb24oZSl7cmV0dXJuIGU/InN0cmluZyI9PXR5cGVvZiBlP2kuY2FsbChTKGUpLHRoaXNbMF0pOmkuY2FsbCh0aGlzLGUuanF1ZXJ5P2VbMF06ZSk6dGhpc1swXSYmdGhpc1swXS5wYXJlbnROb2RlP3RoaXMuZmlyc3QoKS5wcmV2QWxsKCkubGVuZ3RoOi0xfSxhZGQ6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gdGhpcy5wdXNoU3RhY2soUy51bmlxdWVTb3J0KFMubWVyZ2UodGhpcy5nZXQoKSxTKGUsdCkpKSl9LGFkZEJhY2s6ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuYWRkKG51bGw9PWU/dGhpcy5wcmV2T2JqZWN0OnRoaXMucHJldk9iamVjdC5maWx0ZXIoZSkpfX0pLFMuZWFjaCh7cGFyZW50OmZ1bmN0aW9uKGUpe3ZhciB0PWUucGFyZW50Tm9kZTtyZXR1cm4gdCYmMTEhPT10Lm5vZGVUeXBlP3Q6bnVsbH0scGFyZW50czpmdW5jdGlvbihlKXtyZXR1cm4gaChlLCJwYXJlbnROb2RlIil9LHBhcmVudHNVbnRpbDpmdW5jdGlvbihlLHQsbil7cmV0dXJuIGgoZSwicGFyZW50Tm9kZSIsbil9LG5leHQ6ZnVuY3Rpb24oZSl7cmV0dXJuIE8oZSwibmV4dFNpYmxpbmciKX0scHJldjpmdW5jdGlvbihlKXtyZXR1cm4gTyhlLCJwcmV2aW91c1NpYmxpbmciKX0sbmV4dEFsbDpmdW5jdGlvbihlKXtyZXR1cm4gaChlLCJuZXh0U2libGluZyIpfSxwcmV2QWxsOmZ1bmN0aW9uKGUpe3JldHVybiBoKGUsInByZXZpb3VzU2libGluZyIpfSxuZXh0VW50aWw6ZnVuY3Rpb24oZSx0LG4pe3JldHVybiBoKGUsIm5leHRTaWJsaW5nIixuKX0scHJldlVudGlsOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gaChlLCJwcmV2aW91c1NpYmxpbmciLG4pfSxzaWJsaW5nczpmdW5jdGlvbihlKXtyZXR1cm4gVCgoZS5wYXJlbnROb2RlfHx7fSkuZmlyc3RDaGlsZCxlKX0sY2hpbGRyZW46ZnVuY3Rpb24oZSl7cmV0dXJuIFQoZS5maXJzdENoaWxkKX0sY29udGVudHM6ZnVuY3Rpb24oZSl7cmV0dXJuIG51bGwhPWUuY29udGVudERvY3VtZW50JiZyKGUuY29udGVudERvY3VtZW50KT9lLmNvbnRlbnREb2N1bWVudDooQShlLCJ0ZW1wbGF0ZSIpJiYoZT1lLmNvbnRlbnR8fGUpLFMubWVyZ2UoW10sZS5jaGlsZE5vZGVzKSl9fSxmdW5jdGlvbihyLGkpe1MuZm5bcl09ZnVuY3Rpb24oZSx0KXt2YXIgbj1TLm1hcCh0aGlzLGksZSk7cmV0dXJuIlVudGlsIiE9PXIuc2xpY2UoLTUpJiYodD1lKSx0JiYic3RyaW5nIj09dHlwZW9mIHQmJihuPVMuZmlsdGVyKHQsbikpLDE8dGhpcy5sZW5ndGgmJihIW3JdfHxTLnVuaXF1ZVNvcnQobiksTC50ZXN0KHIpJiZuLnJldmVyc2UoKSksdGhpcy5wdXNoU3RhY2sobil9fSk7dmFyIFA9L1teXHgyMFx0XHJcblxmXSsvZztmdW5jdGlvbiBSKGUpe3JldHVybiBlfWZ1bmN0aW9uIE0oZSl7dGhyb3cgZX1mdW5jdGlvbiBJKGUsdCxuLHIpe3ZhciBpO3RyeXtlJiZtKGk9ZS5wcm9taXNlKT9pLmNhbGwoZSkuZG9uZSh0KS5mYWlsKG4pOmUmJm0oaT1lLnRoZW4pP2kuY2FsbChlLHQsbik6dC5hcHBseSh2b2lkIDAsW2VdLnNsaWNlKHIpKX1jYXRjaChlKXtuLmFwcGx5KHZvaWQgMCxbZV0pfX1TLkNhbGxiYWNrcz1mdW5jdGlvbihyKXt2YXIgZSxuO3I9InN0cmluZyI9PXR5cGVvZiByPyhlPXIsbj17fSxTLmVhY2goZS5tYXRjaChQKXx8W10sZnVuY3Rpb24oZSx0KXtuW3RdPSEwfSksbik6Uy5leHRlbmQoe30scik7dmFyIGksdCxvLGEscz1bXSx1PVtdLGw9LTEsYz1mdW5jdGlvbigpe2ZvcihhPWF8fHIub25jZSxvPWk9ITA7dS5sZW5ndGg7bD0tMSl7dD11LnNoaWZ0KCk7d2hpbGUoKytsPHMubGVuZ3RoKSExPT09c1tsXS5hcHBseSh0WzBdLHRbMV0pJiZyLnN0b3BPbkZhbHNlJiYobD1zLmxlbmd0aCx0PSExKX1yLm1lbW9yeXx8KHQ9ITEpLGk9ITEsYSYmKHM9dD9bXToiIil9LGY9e2FkZDpmdW5jdGlvbigpe3JldHVybiBzJiYodCYmIWkmJihsPXMubGVuZ3RoLTEsdS5wdXNoKHQpKSxmdW5jdGlvbiBuKGUpe1MuZWFjaChlLGZ1bmN0aW9uKGUsdCl7bSh0KT9yLnVuaXF1ZSYmZi5oYXModCl8fHMucHVzaCh0KTp0JiZ0Lmxlbmd0aCYmInN0cmluZyIhPT13KHQpJiZuKHQpfSl9KGFyZ3VtZW50cyksdCYmIWkmJmMoKSksdGhpc30scmVtb3ZlOmZ1bmN0aW9uKCl7cmV0dXJuIFMuZWFjaChhcmd1bWVudHMsZnVuY3Rpb24oZSx0KXt2YXIgbjt3aGlsZSgtMTwobj1TLmluQXJyYXkodCxzLG4pKSlzLnNwbGljZShuLDEpLG48PWwmJmwtLX0pLHRoaXN9LGhhczpmdW5jdGlvbihlKXtyZXR1cm4gZT8tMTxTLmluQXJyYXkoZSxzKTowPHMubGVuZ3RofSxlbXB0eTpmdW5jdGlvbigpe3JldHVybiBzJiYocz1bXSksdGhpc30sZGlzYWJsZTpmdW5jdGlvbigpe3JldHVybiBhPXU9W10scz10PSIiLHRoaXN9LGRpc2FibGVkOmZ1bmN0aW9uKCl7cmV0dXJuIXN9LGxvY2s6ZnVuY3Rpb24oKXtyZXR1cm4gYT11PVtdLHR8fGl8fChzPXQ9IiIpLHRoaXN9LGxvY2tlZDpmdW5jdGlvbigpe3JldHVybiEhYX0sZmlyZVdpdGg6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gYXx8KHQ9W2UsKHQ9dHx8W10pLnNsaWNlP3Quc2xpY2UoKTp0XSx1LnB1c2godCksaXx8YygpKSx0aGlzfSxmaXJlOmZ1bmN0aW9uKCl7cmV0dXJuIGYuZmlyZVdpdGgodGhpcyxhcmd1bWVudHMpLHRoaXN9LGZpcmVkOmZ1bmN0aW9uKCl7cmV0dXJuISFvfX07cmV0dXJuIGZ9LFMuZXh0ZW5kKHtEZWZlcnJlZDpmdW5jdGlvbihlKXt2YXIgbz1bWyJub3RpZnkiLCJwcm9ncmVzcyIsUy5DYWxsYmFja3MoIm1lbW9yeSIpLFMuQ2FsbGJhY2tzKCJtZW1vcnkiKSwyXSxbInJlc29sdmUiLCJkb25lIixTLkNhbGxiYWNrcygib25jZSBtZW1vcnkiKSxTLkNhbGxiYWNrcygib25jZSBtZW1vcnkiKSwwLCJyZXNvbHZlZCJdLFsicmVqZWN0IiwiZmFpbCIsUy5DYWxsYmFja3MoIm9uY2UgbWVtb3J5IiksUy5DYWxsYmFja3MoIm9uY2UgbWVtb3J5IiksMSwicmVqZWN0ZWQiXV0saT0icGVuZGluZyIsYT17c3RhdGU6ZnVuY3Rpb24oKXtyZXR1cm4gaX0sYWx3YXlzOmZ1bmN0aW9uKCl7cmV0dXJuIHMuZG9uZShhcmd1bWVudHMpLmZhaWwoYXJndW1lbnRzKSx0aGlzfSwiY2F0Y2giOmZ1bmN0aW9uKGUpe3JldHVybiBhLnRoZW4obnVsbCxlKX0scGlwZTpmdW5jdGlvbigpe3ZhciBpPWFyZ3VtZW50cztyZXR1cm4gUy5EZWZlcnJlZChmdW5jdGlvbihyKXtTLmVhY2gobyxmdW5jdGlvbihlLHQpe3ZhciBuPW0oaVt0WzRdXSkmJmlbdFs0XV07c1t0WzFdXShmdW5jdGlvbigpe3ZhciBlPW4mJm4uYXBwbHkodGhpcyxhcmd1bWVudHMpO2UmJm0oZS5wcm9taXNlKT9lLnByb21pc2UoKS5wcm9ncmVzcyhyLm5vdGlmeSkuZG9uZShyLnJlc29sdmUpLmZhaWwoci5yZWplY3QpOnJbdFswXSsiV2l0aCJdKHRoaXMsbj9bZV06YXJndW1lbnRzKX0pfSksaT1udWxsfSkucHJvbWlzZSgpfSx0aGVuOmZ1bmN0aW9uKHQsbixyKXt2YXIgdT0wO2Z1bmN0aW9uIGwoaSxvLGEscyl7cmV0dXJuIGZ1bmN0aW9uKCl7dmFyIG49dGhpcyxyPWFyZ3VtZW50cyxlPWZ1bmN0aW9uKCl7dmFyIGUsdDtpZighKGk8dSkpe2lmKChlPWEuYXBwbHkobixyKSk9PT1vLnByb21pc2UoKSl0aHJvdyBuZXcgVHlwZUVycm9yKCJUaGVuYWJsZSBzZWxmLXJlc29sdXRpb24iKTt0PWUmJigib2JqZWN0Ij09dHlwZW9mIGV8fCJmdW5jdGlvbiI9PXR5cGVvZiBlKSYmZS50aGVuLG0odCk/cz90LmNhbGwoZSxsKHUsbyxSLHMpLGwodSxvLE0scykpOih1KyssdC5jYWxsKGUsbCh1LG8sUixzKSxsKHUsbyxNLHMpLGwodSxvLFIsby5ub3RpZnlXaXRoKSkpOihhIT09UiYmKG49dm9pZCAwLHI9W2VdKSwoc3x8by5yZXNvbHZlV2l0aCkobixyKSl9fSx0PXM/ZTpmdW5jdGlvbigpe3RyeXtlKCl9Y2F0Y2goZSl7Uy5EZWZlcnJlZC5leGNlcHRpb25Ib29rJiZTLkRlZmVycmVkLmV4Y2VwdGlvbkhvb2soZSx0LnN0YWNrVHJhY2UpLHU8PWkrMSYmKGEhPT1NJiYobj12b2lkIDAscj1bZV0pLG8ucmVqZWN0V2l0aChuLHIpKX19O2k/dCgpOihTLkRlZmVycmVkLmdldFN0YWNrSG9vayYmKHQuc3RhY2tUcmFjZT1TLkRlZmVycmVkLmdldFN0YWNrSG9vaygpKSxDLnNldFRpbWVvdXQodCkpfX1yZXR1cm4gUy5EZWZlcnJlZChmdW5jdGlvbihlKXtvWzBdWzNdLmFkZChsKDAsZSxtKHIpP3I6UixlLm5vdGlmeVdpdGgpKSxvWzFdWzNdLmFkZChsKDAsZSxtKHQpP3Q6UikpLG9bMl1bM10uYWRkKGwoMCxlLG0obik/bjpNKSl9KS5wcm9taXNlKCl9LHByb21pc2U6ZnVuY3Rpb24oZSl7cmV0dXJuIG51bGwhPWU/Uy5leHRlbmQoZSxhKTphfX0scz17fTtyZXR1cm4gUy5lYWNoKG8sZnVuY3Rpb24oZSx0KXt2YXIgbj10WzJdLHI9dFs1XTthW3RbMV1dPW4uYWRkLHImJm4uYWRkKGZ1bmN0aW9uKCl7aT1yfSxvWzMtZV1bMl0uZGlzYWJsZSxvWzMtZV1bM10uZGlzYWJsZSxvWzBdWzJdLmxvY2ssb1swXVszXS5sb2NrKSxuLmFkZCh0WzNdLmZpcmUpLHNbdFswXV09ZnVuY3Rpb24oKXtyZXR1cm4gc1t0WzBdKyJXaXRoIl0odGhpcz09PXM/dm9pZCAwOnRoaXMsYXJndW1lbnRzKSx0aGlzfSxzW3RbMF0rIldpdGgiXT1uLmZpcmVXaXRofSksYS5wcm9taXNlKHMpLGUmJmUuY2FsbChzLHMpLHN9LHdoZW46ZnVuY3Rpb24oZSl7dmFyIG49YXJndW1lbnRzLmxlbmd0aCx0PW4scj1BcnJheSh0KSxpPXMuY2FsbChhcmd1bWVudHMpLG89Uy5EZWZlcnJlZCgpLGE9ZnVuY3Rpb24odCl7cmV0dXJuIGZ1bmN0aW9uKGUpe3JbdF09dGhpcyxpW3RdPTE8YXJndW1lbnRzLmxlbmd0aD9zLmNhbGwoYXJndW1lbnRzKTplLC0tbnx8by5yZXNvbHZlV2l0aChyLGkpfX07aWYobjw9MSYmKEkoZSxvLmRvbmUoYSh0KSkucmVzb2x2ZSxvLnJlamVjdCwhbiksInBlbmRpbmciPT09by5zdGF0ZSgpfHxtKGlbdF0mJmlbdF0udGhlbikpKXJldHVybiBvLnRoZW4oKTt3aGlsZSh0LS0pSShpW3RdLGEodCksby5yZWplY3QpO3JldHVybiBvLnByb21pc2UoKX19KTt2YXIgVz0vXihFdmFsfEludGVybmFsfFJhbmdlfFJlZmVyZW5jZXxTeW50YXh8VHlwZXxVUkkpRXJyb3IkLztTLkRlZmVycmVkLmV4Y2VwdGlvbkhvb2s9ZnVuY3Rpb24oZSx0KXtDLmNvbnNvbGUmJkMuY29uc29sZS53YXJuJiZlJiZXLnRlc3QoZS5uYW1lKSYmQy5jb25zb2xlLndhcm4oImpRdWVyeS5EZWZlcnJlZCBleGNlcHRpb246ICIrZS5tZXNzYWdlLGUuc3RhY2ssdCl9LFMucmVhZHlFeGNlcHRpb249ZnVuY3Rpb24oZSl7Qy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dGhyb3cgZX0pfTt2YXIgRj1TLkRlZmVycmVkKCk7ZnVuY3Rpb24gQigpe0UucmVtb3ZlRXZlbnRMaXN0ZW5lcigiRE9NQ29udGVudExvYWRlZCIsQiksQy5yZW1vdmVFdmVudExpc3RlbmVyKCJsb2FkIixCKSxTLnJlYWR5KCl9Uy5mbi5yZWFkeT1mdW5jdGlvbihlKXtyZXR1cm4gRi50aGVuKGUpWyJjYXRjaCJdKGZ1bmN0aW9uKGUpe1MucmVhZHlFeGNlcHRpb24oZSl9KSx0aGlzfSxTLmV4dGVuZCh7aXNSZWFkeTohMSxyZWFkeVdhaXQ6MSxyZWFkeTpmdW5jdGlvbihlKXsoITA9PT1lPy0tUy5yZWFkeVdhaXQ6Uy5pc1JlYWR5KXx8KFMuaXNSZWFkeT0hMCkhPT1lJiYwPC0tUy5yZWFkeVdhaXR8fEYucmVzb2x2ZVdpdGgoRSxbU10pfX0pLFMucmVhZHkudGhlbj1GLnRoZW4sImNvbXBsZXRlIj09PUUucmVhZHlTdGF0ZXx8ImxvYWRpbmciIT09RS5yZWFkeVN0YXRlJiYhRS5kb2N1bWVudEVsZW1lbnQuZG9TY3JvbGw/Qy5zZXRUaW1lb3V0KFMucmVhZHkpOihFLmFkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLEIpLEMuYWRkRXZlbnRMaXN0ZW5lcigibG9hZCIsQikpO3ZhciAkPWZ1bmN0aW9uKGUsdCxuLHIsaSxvLGEpe3ZhciBzPTAsdT1lLmxlbmd0aCxsPW51bGw9PW47aWYoIm9iamVjdCI9PT13KG4pKWZvcihzIGluIGk9ITAsbikkKGUsdCxzLG5bc10sITAsbyxhKTtlbHNlIGlmKHZvaWQgMCE9PXImJihpPSEwLG0ocil8fChhPSEwKSxsJiYoYT8odC5jYWxsKGUsciksdD1udWxsKToobD10LHQ9ZnVuY3Rpb24oZSx0LG4pe3JldHVybiBsLmNhbGwoUyhlKSxuKX0pKSx0KSlmb3IoO3M8dTtzKyspdChlW3NdLG4sYT9yOnIuY2FsbChlW3NdLHMsdChlW3NdLG4pKSk7cmV0dXJuIGk/ZTpsP3QuY2FsbChlKTp1P3QoZVswXSxuKTpvfSxfPS9eLW1zLS8sej0vLShbYS16XSkvZztmdW5jdGlvbiBVKGUsdCl7cmV0dXJuIHQudG9VcHBlckNhc2UoKX1mdW5jdGlvbiBYKGUpe3JldHVybiBlLnJlcGxhY2UoXywibXMtIikucmVwbGFjZSh6LFUpfXZhciBWPWZ1bmN0aW9uKGUpe3JldHVybiAxPT09ZS5ub2RlVHlwZXx8OT09PWUubm9kZVR5cGV8fCErZS5ub2RlVHlwZX07ZnVuY3Rpb24gRygpe3RoaXMuZXhwYW5kbz1TLmV4cGFuZG8rRy51aWQrK31HLnVpZD0xLEcucHJvdG90eXBlPXtjYWNoZTpmdW5jdGlvbihlKXt2YXIgdD1lW3RoaXMuZXhwYW5kb107cmV0dXJuIHR8fCh0PXt9LFYoZSkmJihlLm5vZGVUeXBlP2VbdGhpcy5leHBhbmRvXT10Ok9iamVjdC5kZWZpbmVQcm9wZXJ0eShlLHRoaXMuZXhwYW5kbyx7dmFsdWU6dCxjb25maWd1cmFibGU6ITB9KSkpLHR9LHNldDpmdW5jdGlvbihlLHQsbil7dmFyIHIsaT10aGlzLmNhY2hlKGUpO2lmKCJzdHJpbmciPT10eXBlb2YgdClpW1godCldPW47ZWxzZSBmb3IociBpbiB0KWlbWChyKV09dFtyXTtyZXR1cm4gaX0sZ2V0OmZ1bmN0aW9uKGUsdCl7cmV0dXJuIHZvaWQgMD09PXQ/dGhpcy5jYWNoZShlKTplW3RoaXMuZXhwYW5kb10mJmVbdGhpcy5leHBhbmRvXVtYKHQpXX0sYWNjZXNzOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gdm9pZCAwPT09dHx8dCYmInN0cmluZyI9PXR5cGVvZiB0JiZ2b2lkIDA9PT1uP3RoaXMuZ2V0KGUsdCk6KHRoaXMuc2V0KGUsdCxuKSx2b2lkIDAhPT1uP246dCl9LHJlbW92ZTpmdW5jdGlvbihlLHQpe3ZhciBuLHI9ZVt0aGlzLmV4cGFuZG9dO2lmKHZvaWQgMCE9PXIpe2lmKHZvaWQgMCE9PXQpe249KHQ9QXJyYXkuaXNBcnJheSh0KT90Lm1hcChYKToodD1YKHQpKWluIHI/W3RdOnQubWF0Y2goUCl8fFtdKS5sZW5ndGg7d2hpbGUobi0tKWRlbGV0ZSByW3Rbbl1dfSh2b2lkIDA9PT10fHxTLmlzRW1wdHlPYmplY3QocikpJiYoZS5ub2RlVHlwZT9lW3RoaXMuZXhwYW5kb109dm9pZCAwOmRlbGV0ZSBlW3RoaXMuZXhwYW5kb10pfX0saGFzRGF0YTpmdW5jdGlvbihlKXt2YXIgdD1lW3RoaXMuZXhwYW5kb107cmV0dXJuIHZvaWQgMCE9PXQmJiFTLmlzRW1wdHlPYmplY3QodCl9fTt2YXIgWT1uZXcgRyxRPW5ldyBHLEo9L14oPzpce1tcd1xXXSpcfXxcW1tcd1xXXSpcXSkkLyxLPS9bQS1aXS9nO2Z1bmN0aW9uIFooZSx0LG4pe3ZhciByLGk7aWYodm9pZCAwPT09biYmMT09PWUubm9kZVR5cGUpaWYocj0iZGF0YS0iK3QucmVwbGFjZShLLCItJCYiKS50b0xvd2VyQ2FzZSgpLCJzdHJpbmciPT10eXBlb2Yobj1lLmdldEF0dHJpYnV0ZShyKSkpe3RyeXtuPSJ0cnVlIj09PShpPW4pfHwiZmFsc2UiIT09aSYmKCJudWxsIj09PWk/bnVsbDppPT09K2krIiI/K2k6Si50ZXN0KGkpP0pTT04ucGFyc2UoaSk6aSl9Y2F0Y2goZSl7fVEuc2V0KGUsdCxuKX1lbHNlIG49dm9pZCAwO3JldHVybiBufVMuZXh0ZW5kKHtoYXNEYXRhOmZ1bmN0aW9uKGUpe3JldHVybiBRLmhhc0RhdGEoZSl8fFkuaGFzRGF0YShlKX0sZGF0YTpmdW5jdGlvbihlLHQsbil7cmV0dXJuIFEuYWNjZXNzKGUsdCxuKX0scmVtb3ZlRGF0YTpmdW5jdGlvbihlLHQpe1EucmVtb3ZlKGUsdCl9LF9kYXRhOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gWS5hY2Nlc3MoZSx0LG4pfSxfcmVtb3ZlRGF0YTpmdW5jdGlvbihlLHQpe1kucmVtb3ZlKGUsdCl9fSksUy5mbi5leHRlbmQoe2RhdGE6ZnVuY3Rpb24obixlKXt2YXIgdCxyLGksbz10aGlzWzBdLGE9byYmby5hdHRyaWJ1dGVzO2lmKHZvaWQgMD09PW4pe2lmKHRoaXMubGVuZ3RoJiYoaT1RLmdldChvKSwxPT09by5ub2RlVHlwZSYmIVkuZ2V0KG8sImhhc0RhdGFBdHRycyIpKSl7dD1hLmxlbmd0aDt3aGlsZSh0LS0pYVt0XSYmMD09PShyPWFbdF0ubmFtZSkuaW5kZXhPZigiZGF0YS0iKSYmKHI9WChyLnNsaWNlKDUpKSxaKG8scixpW3JdKSk7WS5zZXQobywiaGFzRGF0YUF0dHJzIiwhMCl9cmV0dXJuIGl9cmV0dXJuIm9iamVjdCI9PXR5cGVvZiBuP3RoaXMuZWFjaChmdW5jdGlvbigpe1Euc2V0KHRoaXMsbil9KTokKHRoaXMsZnVuY3Rpb24oZSl7dmFyIHQ7aWYobyYmdm9pZCAwPT09ZSlyZXR1cm4gdm9pZCAwIT09KHQ9US5nZXQobyxuKSk/dDp2b2lkIDAhPT0odD1aKG8sbikpP3Q6dm9pZCAwO3RoaXMuZWFjaChmdW5jdGlvbigpe1Euc2V0KHRoaXMsbixlKX0pfSxudWxsLGUsMTxhcmd1bWVudHMubGVuZ3RoLG51bGwsITApfSxyZW1vdmVEYXRhOmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtRLnJlbW92ZSh0aGlzLGUpfSl9fSksUy5leHRlbmQoe3F1ZXVlOmZ1bmN0aW9uKGUsdCxuKXt2YXIgcjtpZihlKXJldHVybiB0PSh0fHwiZngiKSsicXVldWUiLHI9WS5nZXQoZSx0KSxuJiYoIXJ8fEFycmF5LmlzQXJyYXkobik/cj1ZLmFjY2VzcyhlLHQsUy5tYWtlQXJyYXkobikpOnIucHVzaChuKSkscnx8W119LGRlcXVldWU6ZnVuY3Rpb24oZSx0KXt0PXR8fCJmeCI7dmFyIG49Uy5xdWV1ZShlLHQpLHI9bi5sZW5ndGgsaT1uLnNoaWZ0KCksbz1TLl9xdWV1ZUhvb2tzKGUsdCk7ImlucHJvZ3Jlc3MiPT09aSYmKGk9bi5zaGlmdCgpLHItLSksaSYmKCJmeCI9PT10JiZuLnVuc2hpZnQoImlucHJvZ3Jlc3MiKSxkZWxldGUgby5zdG9wLGkuY2FsbChlLGZ1bmN0aW9uKCl7Uy5kZXF1ZXVlKGUsdCl9LG8pKSwhciYmbyYmby5lbXB0eS5maXJlKCl9LF9xdWV1ZUhvb2tzOmZ1bmN0aW9uKGUsdCl7dmFyIG49dCsicXVldWVIb29rcyI7cmV0dXJuIFkuZ2V0KGUsbil8fFkuYWNjZXNzKGUsbix7ZW1wdHk6Uy5DYWxsYmFja3MoIm9uY2UgbWVtb3J5IikuYWRkKGZ1bmN0aW9uKCl7WS5yZW1vdmUoZSxbdCsicXVldWUiLG5dKX0pfSl9fSksUy5mbi5leHRlbmQoe3F1ZXVlOmZ1bmN0aW9uKHQsbil7dmFyIGU9MjtyZXR1cm4ic3RyaW5nIiE9dHlwZW9mIHQmJihuPXQsdD0iZngiLGUtLSksYXJndW1lbnRzLmxlbmd0aDxlP1MucXVldWUodGhpc1swXSx0KTp2b2lkIDA9PT1uP3RoaXM6dGhpcy5lYWNoKGZ1bmN0aW9uKCl7dmFyIGU9Uy5xdWV1ZSh0aGlzLHQsbik7Uy5fcXVldWVIb29rcyh0aGlzLHQpLCJmeCI9PT10JiYiaW5wcm9ncmVzcyIhPT1lWzBdJiZTLmRlcXVldWUodGhpcyx0KX0pfSxkZXF1ZXVlOmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtTLmRlcXVldWUodGhpcyxlKX0pfSxjbGVhclF1ZXVlOmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLnF1ZXVlKGV8fCJmeCIsW10pfSxwcm9taXNlOmZ1bmN0aW9uKGUsdCl7dmFyIG4scj0xLGk9Uy5EZWZlcnJlZCgpLG89dGhpcyxhPXRoaXMubGVuZ3RoLHM9ZnVuY3Rpb24oKXstLXJ8fGkucmVzb2x2ZVdpdGgobyxbb10pfTsic3RyaW5nIiE9dHlwZW9mIGUmJih0PWUsZT12b2lkIDApLGU9ZXx8ImZ4Ijt3aGlsZShhLS0pKG49WS5nZXQob1thXSxlKyJxdWV1ZUhvb2tzIikpJiZuLmVtcHR5JiYocisrLG4uZW1wdHkuYWRkKHMpKTtyZXR1cm4gcygpLGkucHJvbWlzZSh0KX19KTt2YXIgZWU9L1srLV0/KD86XGQqXC58KVxkKyg/OltlRV1bKy1dP1xkK3wpLy5zb3VyY2UsdGU9bmV3IFJlZ0V4cCgiXig/OihbKy1dKT18KSgiK2VlKyIpKFthLXolXSopJCIsImkiKSxuZT1bIlRvcCIsIlJpZ2h0IiwiQm90dG9tIiwiTGVmdCJdLHJlPUUuZG9jdW1lbnRFbGVtZW50LGllPWZ1bmN0aW9uKGUpe3JldHVybiBTLmNvbnRhaW5zKGUub3duZXJEb2N1bWVudCxlKX0sb2U9e2NvbXBvc2VkOiEwfTtyZS5nZXRSb290Tm9kZSYmKGllPWZ1bmN0aW9uKGUpe3JldHVybiBTLmNvbnRhaW5zKGUub3duZXJEb2N1bWVudCxlKXx8ZS5nZXRSb290Tm9kZShvZSk9PT1lLm93bmVyRG9jdW1lbnR9KTt2YXIgYWU9ZnVuY3Rpb24oZSx0KXtyZXR1cm4ibm9uZSI9PT0oZT10fHxlKS5zdHlsZS5kaXNwbGF5fHwiIj09PWUuc3R5bGUuZGlzcGxheSYmaWUoZSkmJiJub25lIj09PVMuY3NzKGUsImRpc3BsYXkiKX07ZnVuY3Rpb24gc2UoZSx0LG4scil7dmFyIGksbyxhPTIwLHM9cj9mdW5jdGlvbigpe3JldHVybiByLmN1cigpfTpmdW5jdGlvbigpe3JldHVybiBTLmNzcyhlLHQsIiIpfSx1PXMoKSxsPW4mJm5bM118fChTLmNzc051bWJlclt0XT8iIjoicHgiKSxjPWUubm9kZVR5cGUmJihTLmNzc051bWJlclt0XXx8InB4IiE9PWwmJit1KSYmdGUuZXhlYyhTLmNzcyhlLHQpKTtpZihjJiZjWzNdIT09bCl7dS89MixsPWx8fGNbM10sYz0rdXx8MTt3aGlsZShhLS0pUy5zdHlsZShlLHQsYytsKSwoMS1vKSooMS0obz1zKCkvdXx8LjUpKTw9MCYmKGE9MCksYy89bztjKj0yLFMuc3R5bGUoZSx0LGMrbCksbj1ufHxbXX1yZXR1cm4gbiYmKGM9K2N8fCt1fHwwLGk9blsxXT9jKyhuWzFdKzEpKm5bMl06K25bMl0sciYmKHIudW5pdD1sLHIuc3RhcnQ9YyxyLmVuZD1pKSksaX12YXIgdWU9e307ZnVuY3Rpb24gbGUoZSx0KXtmb3IodmFyIG4scixpLG8sYSxzLHUsbD1bXSxjPTAsZj1lLmxlbmd0aDtjPGY7YysrKShyPWVbY10pLnN0eWxlJiYobj1yLnN0eWxlLmRpc3BsYXksdD8oIm5vbmUiPT09biYmKGxbY109WS5nZXQociwiZGlzcGxheSIpfHxudWxsLGxbY118fChyLnN0eWxlLmRpc3BsYXk9IiIpKSwiIj09PXIuc3R5bGUuZGlzcGxheSYmYWUocikmJihsW2NdPSh1PWE9bz12b2lkIDAsYT0oaT1yKS5vd25lckRvY3VtZW50LHM9aS5ub2RlTmFtZSwodT11ZVtzXSl8fChvPWEuYm9keS5hcHBlbmRDaGlsZChhLmNyZWF0ZUVsZW1lbnQocykpLHU9Uy5jc3MobywiZGlzcGxheSIpLG8ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChvKSwibm9uZSI9PT11JiYodT0iYmxvY2siKSx1ZVtzXT11KSkpKToibm9uZSIhPT1uJiYobFtjXT0ibm9uZSIsWS5zZXQociwiZGlzcGxheSIsbikpKTtmb3IoYz0wO2M8ZjtjKyspbnVsbCE9bFtjXSYmKGVbY10uc3R5bGUuZGlzcGxheT1sW2NdKTtyZXR1cm4gZX1TLmZuLmV4dGVuZCh7c2hvdzpmdW5jdGlvbigpe3JldHVybiBsZSh0aGlzLCEwKX0saGlkZTpmdW5jdGlvbigpe3JldHVybiBsZSh0aGlzKX0sdG9nZ2xlOmZ1bmN0aW9uKGUpe3JldHVybiJib29sZWFuIj09dHlwZW9mIGU/ZT90aGlzLnNob3coKTp0aGlzLmhpZGUoKTp0aGlzLmVhY2goZnVuY3Rpb24oKXthZSh0aGlzKT9TKHRoaXMpLnNob3coKTpTKHRoaXMpLmhpZGUoKX0pfX0pO3ZhciBjZSxmZSxwZT0vXig/OmNoZWNrYm94fHJhZGlvKSQvaSxkZT0vPChbYS16XVteXC9cMD5ceDIwXHRcclxuXGZdKikvaSxoZT0vXiR8Xm1vZHVsZSR8XC8oPzpqYXZhfGVjbWEpc2NyaXB0L2k7Y2U9RS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkuYXBwZW5kQ2hpbGQoRS5jcmVhdGVFbGVtZW50KCJkaXYiKSksKGZlPUUuY3JlYXRlRWxlbWVudCgiaW5wdXQiKSkuc2V0QXR0cmlidXRlKCJ0eXBlIiwicmFkaW8iKSxmZS5zZXRBdHRyaWJ1dGUoImNoZWNrZWQiLCJjaGVja2VkIiksZmUuc2V0QXR0cmlidXRlKCJuYW1lIiwidCIpLGNlLmFwcGVuZENoaWxkKGZlKSx5LmNoZWNrQ2xvbmU9Y2UuY2xvbmVOb2RlKCEwKS5jbG9uZU5vZGUoITApLmxhc3RDaGlsZC5jaGVja2VkLGNlLmlubmVySFRNTD0iPHRleHRhcmVhPng8L3RleHRhcmVhPiIseS5ub0Nsb25lQ2hlY2tlZD0hIWNlLmNsb25lTm9kZSghMCkubGFzdENoaWxkLmRlZmF1bHRWYWx1ZSxjZS5pbm5lckhUTUw9IjxvcHRpb24+PC9vcHRpb24+Iix5Lm9wdGlvbj0hIWNlLmxhc3RDaGlsZDt2YXIgZ2U9e3RoZWFkOlsxLCI8dGFibGU+IiwiPC90YWJsZT4iXSxjb2w6WzIsIjx0YWJsZT48Y29sZ3JvdXA+IiwiPC9jb2xncm91cD48L3RhYmxlPiJdLHRyOlsyLCI8dGFibGU+PHRib2R5PiIsIjwvdGJvZHk+PC90YWJsZT4iXSx0ZDpbMywiPHRhYmxlPjx0Ym9keT48dHI+IiwiPC90cj48L3Rib2R5PjwvdGFibGU+Il0sX2RlZmF1bHQ6WzAsIiIsIiJdfTtmdW5jdGlvbiB2ZShlLHQpe3ZhciBuO3JldHVybiBuPSJ1bmRlZmluZWQiIT10eXBlb2YgZS5nZXRFbGVtZW50c0J5VGFnTmFtZT9lLmdldEVsZW1lbnRzQnlUYWdOYW1lKHR8fCIqIik6InVuZGVmaW5lZCIhPXR5cGVvZiBlLnF1ZXJ5U2VsZWN0b3JBbGw/ZS5xdWVyeVNlbGVjdG9yQWxsKHR8fCIqIik6W10sdm9pZCAwPT09dHx8dCYmQShlLHQpP1MubWVyZ2UoW2VdLG4pOm59ZnVuY3Rpb24geWUoZSx0KXtmb3IodmFyIG49MCxyPWUubGVuZ3RoO248cjtuKyspWS5zZXQoZVtuXSwiZ2xvYmFsRXZhbCIsIXR8fFkuZ2V0KHRbbl0sImdsb2JhbEV2YWwiKSl9Z2UudGJvZHk9Z2UudGZvb3Q9Z2UuY29sZ3JvdXA9Z2UuY2FwdGlvbj1nZS50aGVhZCxnZS50aD1nZS50ZCx5Lm9wdGlvbnx8KGdlLm9wdGdyb3VwPWdlLm9wdGlvbj1bMSwiPHNlbGVjdCBtdWx0aXBsZT0nbXVsdGlwbGUnPiIsIjwvc2VsZWN0PiJdKTt2YXIgbWU9Lzx8JiM/XHcrOy87ZnVuY3Rpb24geGUoZSx0LG4scixpKXtmb3IodmFyIG8sYSxzLHUsbCxjLGY9dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkscD1bXSxkPTAsaD1lLmxlbmd0aDtkPGg7ZCsrKWlmKChvPWVbZF0pfHwwPT09bylpZigib2JqZWN0Ij09PXcobykpUy5tZXJnZShwLG8ubm9kZVR5cGU/W29dOm8pO2Vsc2UgaWYobWUudGVzdChvKSl7YT1hfHxmLmFwcGVuZENoaWxkKHQuY3JlYXRlRWxlbWVudCgiZGl2IikpLHM9KGRlLmV4ZWMobyl8fFsiIiwiIl0pWzFdLnRvTG93ZXJDYXNlKCksdT1nZVtzXXx8Z2UuX2RlZmF1bHQsYS5pbm5lckhUTUw9dVsxXStTLmh0bWxQcmVmaWx0ZXIobykrdVsyXSxjPXVbMF07d2hpbGUoYy0tKWE9YS5sYXN0Q2hpbGQ7Uy5tZXJnZShwLGEuY2hpbGROb2RlcyksKGE9Zi5maXJzdENoaWxkKS50ZXh0Q29udGVudD0iIn1lbHNlIHAucHVzaCh0LmNyZWF0ZVRleHROb2RlKG8pKTtmLnRleHRDb250ZW50PSIiLGQ9MDt3aGlsZShvPXBbZCsrXSlpZihyJiYtMTxTLmluQXJyYXkobyxyKSlpJiZpLnB1c2gobyk7ZWxzZSBpZihsPWllKG8pLGE9dmUoZi5hcHBlbmRDaGlsZChvKSwic2NyaXB0IiksbCYmeWUoYSksbil7Yz0wO3doaWxlKG89YVtjKytdKWhlLnRlc3Qoby50eXBlfHwiIikmJm4ucHVzaChvKX1yZXR1cm4gZn12YXIgYmU9L14oW14uXSopKD86XC4oLispfCkvO2Z1bmN0aW9uIHdlKCl7cmV0dXJuITB9ZnVuY3Rpb24gVGUoKXtyZXR1cm4hMX1mdW5jdGlvbiBDZShlLHQpe3JldHVybiBlPT09ZnVuY3Rpb24oKXt0cnl7cmV0dXJuIEUuYWN0aXZlRWxlbWVudH1jYXRjaChlKXt9fSgpPT0oImZvY3VzIj09PXQpfWZ1bmN0aW9uIEVlKGUsdCxuLHIsaSxvKXt2YXIgYSxzO2lmKCJvYmplY3QiPT10eXBlb2YgdCl7Zm9yKHMgaW4ic3RyaW5nIiE9dHlwZW9mIG4mJihyPXJ8fG4sbj12b2lkIDApLHQpRWUoZSxzLG4scix0W3NdLG8pO3JldHVybiBlfWlmKG51bGw9PXImJm51bGw9PWk/KGk9bixyPW49dm9pZCAwKTpudWxsPT1pJiYoInN0cmluZyI9PXR5cGVvZiBuPyhpPXIscj12b2lkIDApOihpPXIscj1uLG49dm9pZCAwKSksITE9PT1pKWk9VGU7ZWxzZSBpZighaSlyZXR1cm4gZTtyZXR1cm4gMT09PW8mJihhPWksKGk9ZnVuY3Rpb24oZSl7cmV0dXJuIFMoKS5vZmYoZSksYS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9KS5ndWlkPWEuZ3VpZHx8KGEuZ3VpZD1TLmd1aWQrKykpLGUuZWFjaChmdW5jdGlvbigpe1MuZXZlbnQuYWRkKHRoaXMsdCxpLHIsbil9KX1mdW5jdGlvbiBTZShlLGksbyl7bz8oWS5zZXQoZSxpLCExKSxTLmV2ZW50LmFkZChlLGkse25hbWVzcGFjZTohMSxoYW5kbGVyOmZ1bmN0aW9uKGUpe3ZhciB0LG4scj1ZLmdldCh0aGlzLGkpO2lmKDEmZS5pc1RyaWdnZXImJnRoaXNbaV0pe2lmKHIubGVuZ3RoKShTLmV2ZW50LnNwZWNpYWxbaV18fHt9KS5kZWxlZ2F0ZVR5cGUmJmUuc3RvcFByb3BhZ2F0aW9uKCk7ZWxzZSBpZihyPXMuY2FsbChhcmd1bWVudHMpLFkuc2V0KHRoaXMsaSxyKSx0PW8odGhpcyxpKSx0aGlzW2ldKCksciE9PShuPVkuZ2V0KHRoaXMsaSkpfHx0P1kuc2V0KHRoaXMsaSwhMSk6bj17fSxyIT09bilyZXR1cm4gZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSxlLnByZXZlbnREZWZhdWx0KCksbiYmbi52YWx1ZX1lbHNlIHIubGVuZ3RoJiYoWS5zZXQodGhpcyxpLHt2YWx1ZTpTLmV2ZW50LnRyaWdnZXIoUy5leHRlbmQoclswXSxTLkV2ZW50LnByb3RvdHlwZSksci5zbGljZSgxKSx0aGlzKX0pLGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCkpfX0pKTp2b2lkIDA9PT1ZLmdldChlLGkpJiZTLmV2ZW50LmFkZChlLGksd2UpfVMuZXZlbnQ9e2dsb2JhbDp7fSxhZGQ6ZnVuY3Rpb24odCxlLG4scixpKXt2YXIgbyxhLHMsdSxsLGMsZixwLGQsaCxnLHY9WS5nZXQodCk7aWYoVih0KSl7bi5oYW5kbGVyJiYobj0obz1uKS5oYW5kbGVyLGk9by5zZWxlY3RvciksaSYmUy5maW5kLm1hdGNoZXNTZWxlY3RvcihyZSxpKSxuLmd1aWR8fChuLmd1aWQ9Uy5ndWlkKyspLCh1PXYuZXZlbnRzKXx8KHU9di5ldmVudHM9T2JqZWN0LmNyZWF0ZShudWxsKSksKGE9di5oYW5kbGUpfHwoYT12LmhhbmRsZT1mdW5jdGlvbihlKXtyZXR1cm4idW5kZWZpbmVkIiE9dHlwZW9mIFMmJlMuZXZlbnQudHJpZ2dlcmVkIT09ZS50eXBlP1MuZXZlbnQuZGlzcGF0Y2guYXBwbHkodCxhcmd1bWVudHMpOnZvaWQgMH0pLGw9KGU9KGV8fCIiKS5tYXRjaChQKXx8WyIiXSkubGVuZ3RoO3doaWxlKGwtLSlkPWc9KHM9YmUuZXhlYyhlW2xdKXx8W10pWzFdLGg9KHNbMl18fCIiKS5zcGxpdCgiLiIpLnNvcnQoKSxkJiYoZj1TLmV2ZW50LnNwZWNpYWxbZF18fHt9LGQ9KGk/Zi5kZWxlZ2F0ZVR5cGU6Zi5iaW5kVHlwZSl8fGQsZj1TLmV2ZW50LnNwZWNpYWxbZF18fHt9LGM9Uy5leHRlbmQoe3R5cGU6ZCxvcmlnVHlwZTpnLGRhdGE6cixoYW5kbGVyOm4sZ3VpZDpuLmd1aWQsc2VsZWN0b3I6aSxuZWVkc0NvbnRleHQ6aSYmUy5leHByLm1hdGNoLm5lZWRzQ29udGV4dC50ZXN0KGkpLG5hbWVzcGFjZTpoLmpvaW4oIi4iKX0sbyksKHA9dVtkXSl8fCgocD11W2RdPVtdKS5kZWxlZ2F0ZUNvdW50PTAsZi5zZXR1cCYmITEhPT1mLnNldHVwLmNhbGwodCxyLGgsYSl8fHQuYWRkRXZlbnRMaXN0ZW5lciYmdC5hZGRFdmVudExpc3RlbmVyKGQsYSkpLGYuYWRkJiYoZi5hZGQuY2FsbCh0LGMpLGMuaGFuZGxlci5ndWlkfHwoYy5oYW5kbGVyLmd1aWQ9bi5ndWlkKSksaT9wLnNwbGljZShwLmRlbGVnYXRlQ291bnQrKywwLGMpOnAucHVzaChjKSxTLmV2ZW50Lmdsb2JhbFtkXT0hMCl9fSxyZW1vdmU6ZnVuY3Rpb24oZSx0LG4scixpKXt2YXIgbyxhLHMsdSxsLGMsZixwLGQsaCxnLHY9WS5oYXNEYXRhKGUpJiZZLmdldChlKTtpZih2JiYodT12LmV2ZW50cykpe2w9KHQ9KHR8fCIiKS5tYXRjaChQKXx8WyIiXSkubGVuZ3RoO3doaWxlKGwtLSlpZihkPWc9KHM9YmUuZXhlYyh0W2xdKXx8W10pWzFdLGg9KHNbMl18fCIiKS5zcGxpdCgiLiIpLnNvcnQoKSxkKXtmPVMuZXZlbnQuc3BlY2lhbFtkXXx8e30scD11W2Q9KHI/Zi5kZWxlZ2F0ZVR5cGU6Zi5iaW5kVHlwZSl8fGRdfHxbXSxzPXNbMl0mJm5ldyBSZWdFeHAoIihefFxcLikiK2guam9pbigiXFwuKD86LipcXC58KSIpKyIoXFwufCQpIiksYT1vPXAubGVuZ3RoO3doaWxlKG8tLSljPXBbb10sIWkmJmchPT1jLm9yaWdUeXBlfHxuJiZuLmd1aWQhPT1jLmd1aWR8fHMmJiFzLnRlc3QoYy5uYW1lc3BhY2UpfHxyJiZyIT09Yy5zZWxlY3RvciYmKCIqKiIhPT1yfHwhYy5zZWxlY3Rvcil8fChwLnNwbGljZShvLDEpLGMuc2VsZWN0b3ImJnAuZGVsZWdhdGVDb3VudC0tLGYucmVtb3ZlJiZmLnJlbW92ZS5jYWxsKGUsYykpO2EmJiFwLmxlbmd0aCYmKGYudGVhcmRvd24mJiExIT09Zi50ZWFyZG93bi5jYWxsKGUsaCx2LmhhbmRsZSl8fFMucmVtb3ZlRXZlbnQoZSxkLHYuaGFuZGxlKSxkZWxldGUgdVtkXSl9ZWxzZSBmb3IoZCBpbiB1KVMuZXZlbnQucmVtb3ZlKGUsZCt0W2xdLG4sciwhMCk7Uy5pc0VtcHR5T2JqZWN0KHUpJiZZLnJlbW92ZShlLCJoYW5kbGUgZXZlbnRzIil9fSxkaXNwYXRjaDpmdW5jdGlvbihlKXt2YXIgdCxuLHIsaSxvLGEscz1uZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCksdT1TLmV2ZW50LmZpeChlKSxsPShZLmdldCh0aGlzLCJldmVudHMiKXx8T2JqZWN0LmNyZWF0ZShudWxsKSlbdS50eXBlXXx8W10sYz1TLmV2ZW50LnNwZWNpYWxbdS50eXBlXXx8e307Zm9yKHNbMF09dSx0PTE7dDxhcmd1bWVudHMubGVuZ3RoO3QrKylzW3RdPWFyZ3VtZW50c1t0XTtpZih1LmRlbGVnYXRlVGFyZ2V0PXRoaXMsIWMucHJlRGlzcGF0Y2h8fCExIT09Yy5wcmVEaXNwYXRjaC5jYWxsKHRoaXMsdSkpe2E9Uy5ldmVudC5oYW5kbGVycy5jYWxsKHRoaXMsdSxsKSx0PTA7d2hpbGUoKGk9YVt0KytdKSYmIXUuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSl7dS5jdXJyZW50VGFyZ2V0PWkuZWxlbSxuPTA7d2hpbGUoKG89aS5oYW5kbGVyc1tuKytdKSYmIXUuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQoKSl1LnJuYW1lc3BhY2UmJiExIT09by5uYW1lc3BhY2UmJiF1LnJuYW1lc3BhY2UudGVzdChvLm5hbWVzcGFjZSl8fCh1LmhhbmRsZU9iaj1vLHUuZGF0YT1vLmRhdGEsdm9pZCAwIT09KHI9KChTLmV2ZW50LnNwZWNpYWxbby5vcmlnVHlwZV18fHt9KS5oYW5kbGV8fG8uaGFuZGxlcikuYXBwbHkoaS5lbGVtLHMpKSYmITE9PT0odS5yZXN1bHQ9cikmJih1LnByZXZlbnREZWZhdWx0KCksdS5zdG9wUHJvcGFnYXRpb24oKSkpfXJldHVybiBjLnBvc3REaXNwYXRjaCYmYy5wb3N0RGlzcGF0Y2guY2FsbCh0aGlzLHUpLHUucmVzdWx0fX0saGFuZGxlcnM6ZnVuY3Rpb24oZSx0KXt2YXIgbixyLGksbyxhLHM9W10sdT10LmRlbGVnYXRlQ291bnQsbD1lLnRhcmdldDtpZih1JiZsLm5vZGVUeXBlJiYhKCJjbGljayI9PT1lLnR5cGUmJjE8PWUuYnV0dG9uKSlmb3IoO2whPT10aGlzO2w9bC5wYXJlbnROb2RlfHx0aGlzKWlmKDE9PT1sLm5vZGVUeXBlJiYoImNsaWNrIiE9PWUudHlwZXx8ITAhPT1sLmRpc2FibGVkKSl7Zm9yKG89W10sYT17fSxuPTA7bjx1O24rKyl2b2lkIDA9PT1hW2k9KHI9dFtuXSkuc2VsZWN0b3IrIiAiXSYmKGFbaV09ci5uZWVkc0NvbnRleHQ/LTE8UyhpLHRoaXMpLmluZGV4KGwpOlMuZmluZChpLHRoaXMsbnVsbCxbbF0pLmxlbmd0aCksYVtpXSYmby5wdXNoKHIpO28ubGVuZ3RoJiZzLnB1c2goe2VsZW06bCxoYW5kbGVyczpvfSl9cmV0dXJuIGw9dGhpcyx1PHQubGVuZ3RoJiZzLnB1c2goe2VsZW06bCxoYW5kbGVyczp0LnNsaWNlKHUpfSksc30sYWRkUHJvcDpmdW5jdGlvbih0LGUpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShTLkV2ZW50LnByb3RvdHlwZSx0LHtlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCxnZXQ6bShlKT9mdW5jdGlvbigpe2lmKHRoaXMub3JpZ2luYWxFdmVudClyZXR1cm4gZSh0aGlzLm9yaWdpbmFsRXZlbnQpfTpmdW5jdGlvbigpe2lmKHRoaXMub3JpZ2luYWxFdmVudClyZXR1cm4gdGhpcy5vcmlnaW5hbEV2ZW50W3RdfSxzZXQ6ZnVuY3Rpb24oZSl7T2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsdCx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6ZX0pfX0pfSxmaXg6ZnVuY3Rpb24oZSl7cmV0dXJuIGVbUy5leHBhbmRvXT9lOm5ldyBTLkV2ZW50KGUpfSxzcGVjaWFsOntsb2FkOntub0J1YmJsZTohMH0sY2xpY2s6e3NldHVwOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXN8fGU7cmV0dXJuIHBlLnRlc3QodC50eXBlKSYmdC5jbGljayYmQSh0LCJpbnB1dCIpJiZTZSh0LCJjbGljayIsd2UpLCExfSx0cmlnZ2VyOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXN8fGU7cmV0dXJuIHBlLnRlc3QodC50eXBlKSYmdC5jbGljayYmQSh0LCJpbnB1dCIpJiZTZSh0LCJjbGljayIpLCEwfSxfZGVmYXVsdDpmdW5jdGlvbihlKXt2YXIgdD1lLnRhcmdldDtyZXR1cm4gcGUudGVzdCh0LnR5cGUpJiZ0LmNsaWNrJiZBKHQsImlucHV0IikmJlkuZ2V0KHQsImNsaWNrIil8fEEodCwiYSIpfX0sYmVmb3JldW5sb2FkOntwb3N0RGlzcGF0Y2g6ZnVuY3Rpb24oZSl7dm9pZCAwIT09ZS5yZXN1bHQmJmUub3JpZ2luYWxFdmVudCYmKGUub3JpZ2luYWxFdmVudC5yZXR1cm5WYWx1ZT1lLnJlc3VsdCl9fX19LFMucmVtb3ZlRXZlbnQ9ZnVuY3Rpb24oZSx0LG4pe2UucmVtb3ZlRXZlbnRMaXN0ZW5lciYmZS5yZW1vdmVFdmVudExpc3RlbmVyKHQsbil9LFMuRXZlbnQ9ZnVuY3Rpb24oZSx0KXtpZighKHRoaXMgaW5zdGFuY2VvZiBTLkV2ZW50KSlyZXR1cm4gbmV3IFMuRXZlbnQoZSx0KTtlJiZlLnR5cGU/KHRoaXMub3JpZ2luYWxFdmVudD1lLHRoaXMudHlwZT1lLnR5cGUsdGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQ9ZS5kZWZhdWx0UHJldmVudGVkfHx2b2lkIDA9PT1lLmRlZmF1bHRQcmV2ZW50ZWQmJiExPT09ZS5yZXR1cm5WYWx1ZT93ZTpUZSx0aGlzLnRhcmdldD1lLnRhcmdldCYmMz09PWUudGFyZ2V0Lm5vZGVUeXBlP2UudGFyZ2V0LnBhcmVudE5vZGU6ZS50YXJnZXQsdGhpcy5jdXJyZW50VGFyZ2V0PWUuY3VycmVudFRhcmdldCx0aGlzLnJlbGF0ZWRUYXJnZXQ9ZS5yZWxhdGVkVGFyZ2V0KTp0aGlzLnR5cGU9ZSx0JiZTLmV4dGVuZCh0aGlzLHQpLHRoaXMudGltZVN0YW1wPWUmJmUudGltZVN0YW1wfHxEYXRlLm5vdygpLHRoaXNbUy5leHBhbmRvXT0hMH0sUy5FdmVudC5wcm90b3R5cGU9e2NvbnN0cnVjdG9yOlMuRXZlbnQsaXNEZWZhdWx0UHJldmVudGVkOlRlLGlzUHJvcGFnYXRpb25TdG9wcGVkOlRlLGlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOlRlLGlzU2ltdWxhdGVkOiExLHByZXZlbnREZWZhdWx0OmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5vcmlnaW5hbEV2ZW50O3RoaXMuaXNEZWZhdWx0UHJldmVudGVkPXdlLGUmJiF0aGlzLmlzU2ltdWxhdGVkJiZlLnByZXZlbnREZWZhdWx0KCl9LHN0b3BQcm9wYWdhdGlvbjpmdW5jdGlvbigpe3ZhciBlPXRoaXMub3JpZ2luYWxFdmVudDt0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkPXdlLGUmJiF0aGlzLmlzU2ltdWxhdGVkJiZlLnN0b3BQcm9wYWdhdGlvbigpfSxzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb246ZnVuY3Rpb24oKXt2YXIgZT10aGlzLm9yaWdpbmFsRXZlbnQ7dGhpcy5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZD13ZSxlJiYhdGhpcy5pc1NpbXVsYXRlZCYmZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSx0aGlzLnN0b3BQcm9wYWdhdGlvbigpfX0sUy5lYWNoKHthbHRLZXk6ITAsYnViYmxlczohMCxjYW5jZWxhYmxlOiEwLGNoYW5nZWRUb3VjaGVzOiEwLGN0cmxLZXk6ITAsZGV0YWlsOiEwLGV2ZW50UGhhc2U6ITAsbWV0YUtleTohMCxwYWdlWDohMCxwYWdlWTohMCxzaGlmdEtleTohMCx2aWV3OiEwLCJjaGFyIjohMCxjb2RlOiEwLGNoYXJDb2RlOiEwLGtleTohMCxrZXlDb2RlOiEwLGJ1dHRvbjohMCxidXR0b25zOiEwLGNsaWVudFg6ITAsY2xpZW50WTohMCxvZmZzZXRYOiEwLG9mZnNldFk6ITAscG9pbnRlcklkOiEwLHBvaW50ZXJUeXBlOiEwLHNjcmVlblg6ITAsc2NyZWVuWTohMCx0YXJnZXRUb3VjaGVzOiEwLHRvRWxlbWVudDohMCx0b3VjaGVzOiEwLHdoaWNoOiEwfSxTLmV2ZW50LmFkZFByb3ApLFMuZWFjaCh7Zm9jdXM6ImZvY3VzaW4iLGJsdXI6ImZvY3Vzb3V0In0sZnVuY3Rpb24oZSx0KXtTLmV2ZW50LnNwZWNpYWxbZV09e3NldHVwOmZ1bmN0aW9uKCl7cmV0dXJuIFNlKHRoaXMsZSxDZSksITF9LHRyaWdnZXI6ZnVuY3Rpb24oKXtyZXR1cm4gU2UodGhpcyxlKSwhMH0sX2RlZmF1bHQ6ZnVuY3Rpb24oKXtyZXR1cm4hMH0sZGVsZWdhdGVUeXBlOnR9fSksUy5lYWNoKHttb3VzZWVudGVyOiJtb3VzZW92ZXIiLG1vdXNlbGVhdmU6Im1vdXNlb3V0Iixwb2ludGVyZW50ZXI6InBvaW50ZXJvdmVyIixwb2ludGVybGVhdmU6InBvaW50ZXJvdXQifSxmdW5jdGlvbihlLGkpe1MuZXZlbnQuc3BlY2lhbFtlXT17ZGVsZWdhdGVUeXBlOmksYmluZFR5cGU6aSxoYW5kbGU6ZnVuY3Rpb24oZSl7dmFyIHQsbj1lLnJlbGF0ZWRUYXJnZXQscj1lLmhhbmRsZU9iajtyZXR1cm4gbiYmKG49PT10aGlzfHxTLmNvbnRhaW5zKHRoaXMsbikpfHwoZS50eXBlPXIub3JpZ1R5cGUsdD1yLmhhbmRsZXIuYXBwbHkodGhpcyxhcmd1bWVudHMpLGUudHlwZT1pKSx0fX19KSxTLmZuLmV4dGVuZCh7b246ZnVuY3Rpb24oZSx0LG4scil7cmV0dXJuIEVlKHRoaXMsZSx0LG4scil9LG9uZTpmdW5jdGlvbihlLHQsbixyKXtyZXR1cm4gRWUodGhpcyxlLHQsbixyLDEpfSxvZmY6ZnVuY3Rpb24oZSx0LG4pe3ZhciByLGk7aWYoZSYmZS5wcmV2ZW50RGVmYXVsdCYmZS5oYW5kbGVPYmopcmV0dXJuIHI9ZS5oYW5kbGVPYmosUyhlLmRlbGVnYXRlVGFyZ2V0KS5vZmYoci5uYW1lc3BhY2U/ci5vcmlnVHlwZSsiLiIrci5uYW1lc3BhY2U6ci5vcmlnVHlwZSxyLnNlbGVjdG9yLHIuaGFuZGxlciksdGhpcztpZigib2JqZWN0Ij09dHlwZW9mIGUpe2ZvcihpIGluIGUpdGhpcy5vZmYoaSx0LGVbaV0pO3JldHVybiB0aGlzfXJldHVybiExIT09dCYmImZ1bmN0aW9uIiE9dHlwZW9mIHR8fChuPXQsdD12b2lkIDApLCExPT09biYmKG49VGUpLHRoaXMuZWFjaChmdW5jdGlvbigpe1MuZXZlbnQucmVtb3ZlKHRoaXMsZSxuLHQpfSl9fSk7dmFyIGtlPS88c2NyaXB0fDxzdHlsZXw8bGluay9pLEFlPS9jaGVja2VkXHMqKD86W149XXw9XHMqLmNoZWNrZWQuKS9pLE5lPS9eXHMqPCEoPzpcW0NEQVRBXFt8LS0pfCg/OlxdXF18LS0pPlxzKiQvZztmdW5jdGlvbiBqZShlLHQpe3JldHVybiBBKGUsInRhYmxlIikmJkEoMTEhPT10Lm5vZGVUeXBlP3Q6dC5maXJzdENoaWxkLCJ0ciIpJiZTKGUpLmNoaWxkcmVuKCJ0Ym9keSIpWzBdfHxlfWZ1bmN0aW9uIERlKGUpe3JldHVybiBlLnR5cGU9KG51bGwhPT1lLmdldEF0dHJpYnV0ZSgidHlwZSIpKSsiLyIrZS50eXBlLGV9ZnVuY3Rpb24gcWUoZSl7cmV0dXJuInRydWUvIj09PShlLnR5cGV8fCIiKS5zbGljZSgwLDUpP2UudHlwZT1lLnR5cGUuc2xpY2UoNSk6ZS5yZW1vdmVBdHRyaWJ1dGUoInR5cGUiKSxlfWZ1bmN0aW9uIExlKGUsdCl7dmFyIG4scixpLG8sYSxzO2lmKDE9PT10Lm5vZGVUeXBlKXtpZihZLmhhc0RhdGEoZSkmJihzPVkuZ2V0KGUpLmV2ZW50cykpZm9yKGkgaW4gWS5yZW1vdmUodCwiaGFuZGxlIGV2ZW50cyIpLHMpZm9yKG49MCxyPXNbaV0ubGVuZ3RoO248cjtuKyspUy5ldmVudC5hZGQodCxpLHNbaV1bbl0pO1EuaGFzRGF0YShlKSYmKG89US5hY2Nlc3MoZSksYT1TLmV4dGVuZCh7fSxvKSxRLnNldCh0LGEpKX19ZnVuY3Rpb24gSGUobixyLGksbyl7cj1nKHIpO3ZhciBlLHQsYSxzLHUsbCxjPTAsZj1uLmxlbmd0aCxwPWYtMSxkPXJbMF0saD1tKGQpO2lmKGh8fDE8ZiYmInN0cmluZyI9PXR5cGVvZiBkJiYheS5jaGVja0Nsb25lJiZBZS50ZXN0KGQpKXJldHVybiBuLmVhY2goZnVuY3Rpb24oZSl7dmFyIHQ9bi5lcShlKTtoJiYoclswXT1kLmNhbGwodGhpcyxlLHQuaHRtbCgpKSksSGUodCxyLGksbyl9KTtpZihmJiYodD0oZT14ZShyLG5bMF0ub3duZXJEb2N1bWVudCwhMSxuLG8pKS5maXJzdENoaWxkLDE9PT1lLmNoaWxkTm9kZXMubGVuZ3RoJiYoZT10KSx0fHxvKSl7Zm9yKHM9KGE9Uy5tYXAodmUoZSwic2NyaXB0IiksRGUpKS5sZW5ndGg7YzxmO2MrKyl1PWUsYyE9PXAmJih1PVMuY2xvbmUodSwhMCwhMCkscyYmUy5tZXJnZShhLHZlKHUsInNjcmlwdCIpKSksaS5jYWxsKG5bY10sdSxjKTtpZihzKWZvcihsPWFbYS5sZW5ndGgtMV0ub3duZXJEb2N1bWVudCxTLm1hcChhLHFlKSxjPTA7YzxzO2MrKyl1PWFbY10saGUudGVzdCh1LnR5cGV8fCIiKSYmIVkuYWNjZXNzKHUsImdsb2JhbEV2YWwiKSYmUy5jb250YWlucyhsLHUpJiYodS5zcmMmJiJtb2R1bGUiIT09KHUudHlwZXx8IiIpLnRvTG93ZXJDYXNlKCk/Uy5fZXZhbFVybCYmIXUubm9Nb2R1bGUmJlMuX2V2YWxVcmwodS5zcmMse25vbmNlOnUubm9uY2V8fHUuZ2V0QXR0cmlidXRlKCJub25jZSIpfSxsKTpiKHUudGV4dENvbnRlbnQucmVwbGFjZShOZSwiIiksdSxsKSl9cmV0dXJuIG59ZnVuY3Rpb24gT2UoZSx0LG4pe2Zvcih2YXIgcixpPXQ/Uy5maWx0ZXIodCxlKTplLG89MDtudWxsIT0ocj1pW29dKTtvKyspbnx8MSE9PXIubm9kZVR5cGV8fFMuY2xlYW5EYXRhKHZlKHIpKSxyLnBhcmVudE5vZGUmJihuJiZpZShyKSYmeWUodmUociwic2NyaXB0IikpLHIucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChyKSk7cmV0dXJuIGV9Uy5leHRlbmQoe2h0bWxQcmVmaWx0ZXI6ZnVuY3Rpb24oZSl7cmV0dXJuIGV9LGNsb25lOmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG8sYSxzLHUsbCxjPWUuY2xvbmVOb2RlKCEwKSxmPWllKGUpO2lmKCEoeS5ub0Nsb25lQ2hlY2tlZHx8MSE9PWUubm9kZVR5cGUmJjExIT09ZS5ub2RlVHlwZXx8Uy5pc1hNTERvYyhlKSkpZm9yKGE9dmUoYykscj0wLGk9KG89dmUoZSkpLmxlbmd0aDtyPGk7cisrKXM9b1tyXSx1PWFbcl0sdm9pZCAwLCJpbnB1dCI9PT0obD11Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpJiZwZS50ZXN0KHMudHlwZSk/dS5jaGVja2VkPXMuY2hlY2tlZDoiaW5wdXQiIT09bCYmInRleHRhcmVhIiE9PWx8fCh1LmRlZmF1bHRWYWx1ZT1zLmRlZmF1bHRWYWx1ZSk7aWYodClpZihuKWZvcihvPW98fHZlKGUpLGE9YXx8dmUoYykscj0wLGk9by5sZW5ndGg7cjxpO3IrKylMZShvW3JdLGFbcl0pO2Vsc2UgTGUoZSxjKTtyZXR1cm4gMDwoYT12ZShjLCJzY3JpcHQiKSkubGVuZ3RoJiZ5ZShhLCFmJiZ2ZShlLCJzY3JpcHQiKSksY30sY2xlYW5EYXRhOmZ1bmN0aW9uKGUpe2Zvcih2YXIgdCxuLHIsaT1TLmV2ZW50LnNwZWNpYWwsbz0wO3ZvaWQgMCE9PShuPWVbb10pO28rKylpZihWKG4pKXtpZih0PW5bWS5leHBhbmRvXSl7aWYodC5ldmVudHMpZm9yKHIgaW4gdC5ldmVudHMpaVtyXT9TLmV2ZW50LnJlbW92ZShuLHIpOlMucmVtb3ZlRXZlbnQobixyLHQuaGFuZGxlKTtuW1kuZXhwYW5kb109dm9pZCAwfW5bUS5leHBhbmRvXSYmKG5bUS5leHBhbmRvXT12b2lkIDApfX19KSxTLmZuLmV4dGVuZCh7ZGV0YWNoOmZ1bmN0aW9uKGUpe3JldHVybiBPZSh0aGlzLGUsITApfSxyZW1vdmU6ZnVuY3Rpb24oZSl7cmV0dXJuIE9lKHRoaXMsZSl9LHRleHQ6ZnVuY3Rpb24oZSl7cmV0dXJuICQodGhpcyxmdW5jdGlvbihlKXtyZXR1cm4gdm9pZCAwPT09ZT9TLnRleHQodGhpcyk6dGhpcy5lbXB0eSgpLmVhY2goZnVuY3Rpb24oKXsxIT09dGhpcy5ub2RlVHlwZSYmMTEhPT10aGlzLm5vZGVUeXBlJiY5IT09dGhpcy5ub2RlVHlwZXx8KHRoaXMudGV4dENvbnRlbnQ9ZSl9KX0sbnVsbCxlLGFyZ3VtZW50cy5sZW5ndGgpfSxhcHBlbmQ6ZnVuY3Rpb24oKXtyZXR1cm4gSGUodGhpcyxhcmd1bWVudHMsZnVuY3Rpb24oZSl7MSE9PXRoaXMubm9kZVR5cGUmJjExIT09dGhpcy5ub2RlVHlwZSYmOSE9PXRoaXMubm9kZVR5cGV8fGplKHRoaXMsZSkuYXBwZW5kQ2hpbGQoZSl9KX0scHJlcGVuZDpmdW5jdGlvbigpe3JldHVybiBIZSh0aGlzLGFyZ3VtZW50cyxmdW5jdGlvbihlKXtpZigxPT09dGhpcy5ub2RlVHlwZXx8MTE9PT10aGlzLm5vZGVUeXBlfHw5PT09dGhpcy5ub2RlVHlwZSl7dmFyIHQ9amUodGhpcyxlKTt0Lmluc2VydEJlZm9yZShlLHQuZmlyc3RDaGlsZCl9fSl9LGJlZm9yZTpmdW5jdGlvbigpe3JldHVybiBIZSh0aGlzLGFyZ3VtZW50cyxmdW5jdGlvbihlKXt0aGlzLnBhcmVudE5vZGUmJnRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZSx0aGlzKX0pfSxhZnRlcjpmdW5jdGlvbigpe3JldHVybiBIZSh0aGlzLGFyZ3VtZW50cyxmdW5jdGlvbihlKXt0aGlzLnBhcmVudE5vZGUmJnRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZSx0aGlzLm5leHRTaWJsaW5nKX0pfSxlbXB0eTpmdW5jdGlvbigpe2Zvcih2YXIgZSx0PTA7bnVsbCE9KGU9dGhpc1t0XSk7dCsrKTE9PT1lLm5vZGVUeXBlJiYoUy5jbGVhbkRhdGEodmUoZSwhMSkpLGUudGV4dENvbnRlbnQ9IiIpO3JldHVybiB0aGlzfSxjbG9uZTpmdW5jdGlvbihlLHQpe3JldHVybiBlPW51bGwhPWUmJmUsdD1udWxsPT10P2U6dCx0aGlzLm1hcChmdW5jdGlvbigpe3JldHVybiBTLmNsb25lKHRoaXMsZSx0KX0pfSxodG1sOmZ1bmN0aW9uKGUpe3JldHVybiAkKHRoaXMsZnVuY3Rpb24oZSl7dmFyIHQ9dGhpc1swXXx8e30sbj0wLHI9dGhpcy5sZW5ndGg7aWYodm9pZCAwPT09ZSYmMT09PXQubm9kZVR5cGUpcmV0dXJuIHQuaW5uZXJIVE1MO2lmKCJzdHJpbmciPT10eXBlb2YgZSYmIWtlLnRlc3QoZSkmJiFnZVsoZGUuZXhlYyhlKXx8WyIiLCIiXSlbMV0udG9Mb3dlckNhc2UoKV0pe2U9Uy5odG1sUHJlZmlsdGVyKGUpO3RyeXtmb3IoO248cjtuKyspMT09PSh0PXRoaXNbbl18fHt9KS5ub2RlVHlwZSYmKFMuY2xlYW5EYXRhKHZlKHQsITEpKSx0LmlubmVySFRNTD1lKTt0PTB9Y2F0Y2goZSl7fX10JiZ0aGlzLmVtcHR5KCkuYXBwZW5kKGUpfSxudWxsLGUsYXJndW1lbnRzLmxlbmd0aCl9LHJlcGxhY2VXaXRoOmZ1bmN0aW9uKCl7dmFyIG49W107cmV0dXJuIEhlKHRoaXMsYXJndW1lbnRzLGZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMucGFyZW50Tm9kZTtTLmluQXJyYXkodGhpcyxuKTwwJiYoUy5jbGVhbkRhdGEodmUodGhpcykpLHQmJnQucmVwbGFjZUNoaWxkKGUsdGhpcykpfSxuKX19KSxTLmVhY2goe2FwcGVuZFRvOiJhcHBlbmQiLHByZXBlbmRUbzoicHJlcGVuZCIsaW5zZXJ0QmVmb3JlOiJiZWZvcmUiLGluc2VydEFmdGVyOiJhZnRlciIscmVwbGFjZUFsbDoicmVwbGFjZVdpdGgifSxmdW5jdGlvbihlLGEpe1MuZm5bZV09ZnVuY3Rpb24oZSl7Zm9yKHZhciB0LG49W10scj1TKGUpLGk9ci5sZW5ndGgtMSxvPTA7bzw9aTtvKyspdD1vPT09aT90aGlzOnRoaXMuY2xvbmUoITApLFMocltvXSlbYV0odCksdS5hcHBseShuLHQuZ2V0KCkpO3JldHVybiB0aGlzLnB1c2hTdGFjayhuKX19KTt2YXIgUGU9bmV3IFJlZ0V4cCgiXigiK2VlKyIpKD8hcHgpW2EteiVdKyQiLCJpIiksUmU9ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3O3JldHVybiB0JiZ0Lm9wZW5lcnx8KHQ9QyksdC5nZXRDb21wdXRlZFN0eWxlKGUpfSxNZT1mdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvPXt9O2ZvcihpIGluIHQpb1tpXT1lLnN0eWxlW2ldLGUuc3R5bGVbaV09dFtpXTtmb3IoaSBpbiByPW4uY2FsbChlKSx0KWUuc3R5bGVbaV09b1tpXTtyZXR1cm4gcn0sSWU9bmV3IFJlZ0V4cChuZS5qb2luKCJ8IiksImkiKTtmdW5jdGlvbiBXZShlLHQsbil7dmFyIHIsaSxvLGEscz1lLnN0eWxlO3JldHVybihuPW58fFJlKGUpKSYmKCIiIT09KGE9bi5nZXRQcm9wZXJ0eVZhbHVlKHQpfHxuW3RdKXx8aWUoZSl8fChhPVMuc3R5bGUoZSx0KSksIXkucGl4ZWxCb3hTdHlsZXMoKSYmUGUudGVzdChhKSYmSWUudGVzdCh0KSYmKHI9cy53aWR0aCxpPXMubWluV2lkdGgsbz1zLm1heFdpZHRoLHMubWluV2lkdGg9cy5tYXhXaWR0aD1zLndpZHRoPWEsYT1uLndpZHRoLHMud2lkdGg9cixzLm1pbldpZHRoPWkscy5tYXhXaWR0aD1vKSksdm9pZCAwIT09YT9hKyIiOmF9ZnVuY3Rpb24gRmUoZSx0KXtyZXR1cm57Z2V0OmZ1bmN0aW9uKCl7aWYoIWUoKSlyZXR1cm4odGhpcy5nZXQ9dCkuYXBwbHkodGhpcyxhcmd1bWVudHMpO2RlbGV0ZSB0aGlzLmdldH19fSFmdW5jdGlvbigpe2Z1bmN0aW9uIGUoKXtpZihsKXt1LnN0eWxlLmNzc1RleHQ9InBvc2l0aW9uOmFic29sdXRlO2xlZnQ6LTExMTExcHg7d2lkdGg6NjBweDttYXJnaW4tdG9wOjFweDtwYWRkaW5nOjA7Ym9yZGVyOjAiLGwuc3R5bGUuY3NzVGV4dD0icG9zaXRpb246cmVsYXRpdmU7ZGlzcGxheTpibG9jaztib3gtc2l6aW5nOmJvcmRlci1ib3g7b3ZlcmZsb3c6c2Nyb2xsO21hcmdpbjphdXRvO2JvcmRlcjoxcHg7cGFkZGluZzoxcHg7d2lkdGg6NjAlO3RvcDoxJSIscmUuYXBwZW5kQ2hpbGQodSkuYXBwZW5kQ2hpbGQobCk7dmFyIGU9Qy5nZXRDb21wdXRlZFN0eWxlKGwpO249IjElIiE9PWUudG9wLHM9MTI9PT10KGUubWFyZ2luTGVmdCksbC5zdHlsZS5yaWdodD0iNjAlIixvPTM2PT09dChlLnJpZ2h0KSxyPTM2PT09dChlLndpZHRoKSxsLnN0eWxlLnBvc2l0aW9uPSJhYnNvbHV0ZSIsaT0xMj09PXQobC5vZmZzZXRXaWR0aC8zKSxyZS5yZW1vdmVDaGlsZCh1KSxsPW51bGx9fWZ1bmN0aW9uIHQoZSl7cmV0dXJuIE1hdGgucm91bmQocGFyc2VGbG9hdChlKSl9dmFyIG4scixpLG8sYSxzLHU9RS5jcmVhdGVFbGVtZW50KCJkaXYiKSxsPUUuY3JlYXRlRWxlbWVudCgiZGl2Iik7bC5zdHlsZSYmKGwuc3R5bGUuYmFja2dyb3VuZENsaXA9ImNvbnRlbnQtYm94IixsLmNsb25lTm9kZSghMCkuc3R5bGUuYmFja2dyb3VuZENsaXA9IiIseS5jbGVhckNsb25lU3R5bGU9ImNvbnRlbnQtYm94Ij09PWwuc3R5bGUuYmFja2dyb3VuZENsaXAsUy5leHRlbmQoeSx7Ym94U2l6aW5nUmVsaWFibGU6ZnVuY3Rpb24oKXtyZXR1cm4gZSgpLHJ9LHBpeGVsQm94U3R5bGVzOmZ1bmN0aW9uKCl7cmV0dXJuIGUoKSxvfSxwaXhlbFBvc2l0aW9uOmZ1bmN0aW9uKCl7cmV0dXJuIGUoKSxufSxyZWxpYWJsZU1hcmdpbkxlZnQ6ZnVuY3Rpb24oKXtyZXR1cm4gZSgpLHN9LHNjcm9sbGJveFNpemU6ZnVuY3Rpb24oKXtyZXR1cm4gZSgpLGl9LHJlbGlhYmxlVHJEaW1lbnNpb25zOmZ1bmN0aW9uKCl7dmFyIGUsdCxuLHI7cmV0dXJuIG51bGw9PWEmJihlPUUuY3JlYXRlRWxlbWVudCgidGFibGUiKSx0PUUuY3JlYXRlRWxlbWVudCgidHIiKSxuPUUuY3JlYXRlRWxlbWVudCgiZGl2IiksZS5zdHlsZS5jc3NUZXh0PSJwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0Oi0xMTExMXB4O2JvcmRlci1jb2xsYXBzZTpzZXBhcmF0ZSIsdC5zdHlsZS5jc3NUZXh0PSJib3JkZXI6MXB4IHNvbGlkIix0LnN0eWxlLmhlaWdodD0iMXB4IixuLnN0eWxlLmhlaWdodD0iOXB4IixuLnN0eWxlLmRpc3BsYXk9ImJsb2NrIixyZS5hcHBlbmRDaGlsZChlKS5hcHBlbmRDaGlsZCh0KS5hcHBlbmRDaGlsZChuKSxyPUMuZ2V0Q29tcHV0ZWRTdHlsZSh0KSxhPXBhcnNlSW50KHIuaGVpZ2h0LDEwKStwYXJzZUludChyLmJvcmRlclRvcFdpZHRoLDEwKStwYXJzZUludChyLmJvcmRlckJvdHRvbVdpZHRoLDEwKT09PXQub2Zmc2V0SGVpZ2h0LHJlLnJlbW92ZUNoaWxkKGUpKSxhfX0pKX0oKTt2YXIgQmU9WyJXZWJraXQiLCJNb3oiLCJtcyJdLCRlPUUuY3JlYXRlRWxlbWVudCgiZGl2Iikuc3R5bGUsX2U9e307ZnVuY3Rpb24gemUoZSl7dmFyIHQ9Uy5jc3NQcm9wc1tlXXx8X2VbZV07cmV0dXJuIHR8fChlIGluICRlP2U6X2VbZV09ZnVuY3Rpb24oZSl7dmFyIHQ9ZVswXS50b1VwcGVyQ2FzZSgpK2Uuc2xpY2UoMSksbj1CZS5sZW5ndGg7d2hpbGUobi0tKWlmKChlPUJlW25dK3QpaW4gJGUpcmV0dXJuIGV9KGUpfHxlKX12YXIgVWU9L14obm9uZXx0YWJsZSg/IS1jW2VhXSkuKykvLFhlPS9eLS0vLFZlPXtwb3NpdGlvbjoiYWJzb2x1dGUiLHZpc2liaWxpdHk6ImhpZGRlbiIsZGlzcGxheToiYmxvY2sifSxHZT17bGV0dGVyU3BhY2luZzoiMCIsZm9udFdlaWdodDoiNDAwIn07ZnVuY3Rpb24gWWUoZSx0LG4pe3ZhciByPXRlLmV4ZWModCk7cmV0dXJuIHI/TWF0aC5tYXgoMCxyWzJdLShufHwwKSkrKHJbM118fCJweCIpOnR9ZnVuY3Rpb24gUWUoZSx0LG4scixpLG8pe3ZhciBhPSJ3aWR0aCI9PT10PzE6MCxzPTAsdT0wO2lmKG49PT0ocj8iYm9yZGVyIjoiY29udGVudCIpKXJldHVybiAwO2Zvcig7YTw0O2ErPTIpIm1hcmdpbiI9PT1uJiYodSs9Uy5jc3MoZSxuK25lW2FdLCEwLGkpKSxyPygiY29udGVudCI9PT1uJiYodS09Uy5jc3MoZSwicGFkZGluZyIrbmVbYV0sITAsaSkpLCJtYXJnaW4iIT09biYmKHUtPVMuY3NzKGUsImJvcmRlciIrbmVbYV0rIldpZHRoIiwhMCxpKSkpOih1Kz1TLmNzcyhlLCJwYWRkaW5nIituZVthXSwhMCxpKSwicGFkZGluZyIhPT1uP3UrPVMuY3NzKGUsImJvcmRlciIrbmVbYV0rIldpZHRoIiwhMCxpKTpzKz1TLmNzcyhlLCJib3JkZXIiK25lW2FdKyJXaWR0aCIsITAsaSkpO3JldHVybiFyJiYwPD1vJiYodSs9TWF0aC5tYXgoMCxNYXRoLmNlaWwoZVsib2Zmc2V0Iit0WzBdLnRvVXBwZXJDYXNlKCkrdC5zbGljZSgxKV0tby11LXMtLjUpKXx8MCksdX1mdW5jdGlvbiBKZShlLHQsbil7dmFyIHI9UmUoZSksaT0oIXkuYm94U2l6aW5nUmVsaWFibGUoKXx8bikmJiJib3JkZXItYm94Ij09PVMuY3NzKGUsImJveFNpemluZyIsITEsciksbz1pLGE9V2UoZSx0LHIpLHM9Im9mZnNldCIrdFswXS50b1VwcGVyQ2FzZSgpK3Quc2xpY2UoMSk7aWYoUGUudGVzdChhKSl7aWYoIW4pcmV0dXJuIGE7YT0iYXV0byJ9cmV0dXJuKCF5LmJveFNpemluZ1JlbGlhYmxlKCkmJml8fCF5LnJlbGlhYmxlVHJEaW1lbnNpb25zKCkmJkEoZSwidHIiKXx8ImF1dG8iPT09YXx8IXBhcnNlRmxvYXQoYSkmJiJpbmxpbmUiPT09Uy5jc3MoZSwiZGlzcGxheSIsITEscikpJiZlLmdldENsaWVudFJlY3RzKCkubGVuZ3RoJiYoaT0iYm9yZGVyLWJveCI9PT1TLmNzcyhlLCJib3hTaXppbmciLCExLHIpLChvPXMgaW4gZSkmJihhPWVbc10pKSwoYT1wYXJzZUZsb2F0KGEpfHwwKStRZShlLHQsbnx8KGk/ImJvcmRlciI6ImNvbnRlbnQiKSxvLHIsYSkrInB4In1mdW5jdGlvbiBLZShlLHQsbixyLGkpe3JldHVybiBuZXcgS2UucHJvdG90eXBlLmluaXQoZSx0LG4scixpKX1TLmV4dGVuZCh7Y3NzSG9va3M6e29wYWNpdHk6e2dldDpmdW5jdGlvbihlLHQpe2lmKHQpe3ZhciBuPVdlKGUsIm9wYWNpdHkiKTtyZXR1cm4iIj09PW4/IjEiOm59fX19LGNzc051bWJlcjp7YW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6ITAsY29sdW1uQ291bnQ6ITAsZmlsbE9wYWNpdHk6ITAsZmxleEdyb3c6ITAsZmxleFNocmluazohMCxmb250V2VpZ2h0OiEwLGdyaWRBcmVhOiEwLGdyaWRDb2x1bW46ITAsZ3JpZENvbHVtbkVuZDohMCxncmlkQ29sdW1uU3RhcnQ6ITAsZ3JpZFJvdzohMCxncmlkUm93RW5kOiEwLGdyaWRSb3dTdGFydDohMCxsaW5lSGVpZ2h0OiEwLG9wYWNpdHk6ITAsb3JkZXI6ITAsb3JwaGFuczohMCx3aWRvd3M6ITAsekluZGV4OiEwLHpvb206ITB9LGNzc1Byb3BzOnt9LHN0eWxlOmZ1bmN0aW9uKGUsdCxuLHIpe2lmKGUmJjMhPT1lLm5vZGVUeXBlJiY4IT09ZS5ub2RlVHlwZSYmZS5zdHlsZSl7dmFyIGksbyxhLHM9WCh0KSx1PVhlLnRlc3QodCksbD1lLnN0eWxlO2lmKHV8fCh0PXplKHMpKSxhPVMuY3NzSG9va3NbdF18fFMuY3NzSG9va3Nbc10sdm9pZCAwPT09bilyZXR1cm4gYSYmImdldCJpbiBhJiZ2b2lkIDAhPT0oaT1hLmdldChlLCExLHIpKT9pOmxbdF07InN0cmluZyI9PT0obz10eXBlb2YgbikmJihpPXRlLmV4ZWMobikpJiZpWzFdJiYobj1zZShlLHQsaSksbz0ibnVtYmVyIiksbnVsbCE9biYmbj09biYmKCJudW1iZXIiIT09b3x8dXx8KG4rPWkmJmlbM118fChTLmNzc051bWJlcltzXT8iIjoicHgiKSkseS5jbGVhckNsb25lU3R5bGV8fCIiIT09bnx8MCE9PXQuaW5kZXhPZigiYmFja2dyb3VuZCIpfHwobFt0XT0iaW5oZXJpdCIpLGEmJiJzZXQiaW4gYSYmdm9pZCAwPT09KG49YS5zZXQoZSxuLHIpKXx8KHU/bC5zZXRQcm9wZXJ0eSh0LG4pOmxbdF09bikpfX0sY3NzOmZ1bmN0aW9uKGUsdCxuLHIpe3ZhciBpLG8sYSxzPVgodCk7cmV0dXJuIFhlLnRlc3QodCl8fCh0PXplKHMpKSwoYT1TLmNzc0hvb2tzW3RdfHxTLmNzc0hvb2tzW3NdKSYmImdldCJpbiBhJiYoaT1hLmdldChlLCEwLG4pKSx2b2lkIDA9PT1pJiYoaT1XZShlLHQscikpLCJub3JtYWwiPT09aSYmdCBpbiBHZSYmKGk9R2VbdF0pLCIiPT09bnx8bj8obz1wYXJzZUZsb2F0KGkpLCEwPT09bnx8aXNGaW5pdGUobyk/b3x8MDppKTppfX0pLFMuZWFjaChbImhlaWdodCIsIndpZHRoIl0sZnVuY3Rpb24oZSx1KXtTLmNzc0hvb2tzW3VdPXtnZXQ6ZnVuY3Rpb24oZSx0LG4pe2lmKHQpcmV0dXJuIVVlLnRlc3QoUy5jc3MoZSwiZGlzcGxheSIpKXx8ZS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCYmZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aD9KZShlLHUsbik6TWUoZSxWZSxmdW5jdGlvbigpe3JldHVybiBKZShlLHUsbil9KX0sc2V0OmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpPVJlKGUpLG89IXkuc2Nyb2xsYm94U2l6ZSgpJiYiYWJzb2x1dGUiPT09aS5wb3NpdGlvbixhPShvfHxuKSYmImJvcmRlci1ib3giPT09Uy5jc3MoZSwiYm94U2l6aW5nIiwhMSxpKSxzPW4/UWUoZSx1LG4sYSxpKTowO3JldHVybiBhJiZvJiYocy09TWF0aC5jZWlsKGVbIm9mZnNldCIrdVswXS50b1VwcGVyQ2FzZSgpK3Uuc2xpY2UoMSldLXBhcnNlRmxvYXQoaVt1XSktUWUoZSx1LCJib3JkZXIiLCExLGkpLS41KSkscyYmKHI9dGUuZXhlYyh0KSkmJiJweCIhPT0oclszXXx8InB4IikmJihlLnN0eWxlW3VdPXQsdD1TLmNzcyhlLHUpKSxZZSgwLHQscyl9fX0pLFMuY3NzSG9va3MubWFyZ2luTGVmdD1GZSh5LnJlbGlhYmxlTWFyZ2luTGVmdCxmdW5jdGlvbihlLHQpe2lmKHQpcmV0dXJuKHBhcnNlRmxvYXQoV2UoZSwibWFyZ2luTGVmdCIpKXx8ZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0LU1lKGUse21hcmdpbkxlZnQ6MH0sZnVuY3Rpb24oKXtyZXR1cm4gZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0fSkpKyJweCJ9KSxTLmVhY2goe21hcmdpbjoiIixwYWRkaW5nOiIiLGJvcmRlcjoiV2lkdGgifSxmdW5jdGlvbihpLG8pe1MuY3NzSG9va3NbaStvXT17ZXhwYW5kOmZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0wLG49e30scj0ic3RyaW5nIj09dHlwZW9mIGU/ZS5zcGxpdCgiICIpOltlXTt0PDQ7dCsrKW5baStuZVt0XStvXT1yW3RdfHxyW3QtMl18fHJbMF07cmV0dXJuIG59fSwibWFyZ2luIiE9PWkmJihTLmNzc0hvb2tzW2krb10uc2V0PVllKX0pLFMuZm4uZXh0ZW5kKHtjc3M6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gJCh0aGlzLGZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG89e30sYT0wO2lmKEFycmF5LmlzQXJyYXkodCkpe2ZvcihyPVJlKGUpLGk9dC5sZW5ndGg7YTxpO2ErKylvW3RbYV1dPVMuY3NzKGUsdFthXSwhMSxyKTtyZXR1cm4gb31yZXR1cm4gdm9pZCAwIT09bj9TLnN0eWxlKGUsdCxuKTpTLmNzcyhlLHQpfSxlLHQsMTxhcmd1bWVudHMubGVuZ3RoKX19KSwoKFMuVHdlZW49S2UpLnByb3RvdHlwZT17Y29uc3RydWN0b3I6S2UsaW5pdDpmdW5jdGlvbihlLHQsbixyLGksbyl7dGhpcy5lbGVtPWUsdGhpcy5wcm9wPW4sdGhpcy5lYXNpbmc9aXx8Uy5lYXNpbmcuX2RlZmF1bHQsdGhpcy5vcHRpb25zPXQsdGhpcy5zdGFydD10aGlzLm5vdz10aGlzLmN1cigpLHRoaXMuZW5kPXIsdGhpcy51bml0PW98fChTLmNzc051bWJlcltuXT8iIjoicHgiKX0sY3VyOmZ1bmN0aW9uKCl7dmFyIGU9S2UucHJvcEhvb2tzW3RoaXMucHJvcF07cmV0dXJuIGUmJmUuZ2V0P2UuZ2V0KHRoaXMpOktlLnByb3BIb29rcy5fZGVmYXVsdC5nZXQodGhpcyl9LHJ1bjpmdW5jdGlvbihlKXt2YXIgdCxuPUtlLnByb3BIb29rc1t0aGlzLnByb3BdO3JldHVybiB0aGlzLm9wdGlvbnMuZHVyYXRpb24/dGhpcy5wb3M9dD1TLmVhc2luZ1t0aGlzLmVhc2luZ10oZSx0aGlzLm9wdGlvbnMuZHVyYXRpb24qZSwwLDEsdGhpcy5vcHRpb25zLmR1cmF0aW9uKTp0aGlzLnBvcz10PWUsdGhpcy5ub3c9KHRoaXMuZW5kLXRoaXMuc3RhcnQpKnQrdGhpcy5zdGFydCx0aGlzLm9wdGlvbnMuc3RlcCYmdGhpcy5vcHRpb25zLnN0ZXAuY2FsbCh0aGlzLmVsZW0sdGhpcy5ub3csdGhpcyksbiYmbi5zZXQ/bi5zZXQodGhpcyk6S2UucHJvcEhvb2tzLl9kZWZhdWx0LnNldCh0aGlzKSx0aGlzfX0pLmluaXQucHJvdG90eXBlPUtlLnByb3RvdHlwZSwoS2UucHJvcEhvb2tzPXtfZGVmYXVsdDp7Z2V0OmZ1bmN0aW9uKGUpe3ZhciB0O3JldHVybiAxIT09ZS5lbGVtLm5vZGVUeXBlfHxudWxsIT1lLmVsZW1bZS5wcm9wXSYmbnVsbD09ZS5lbGVtLnN0eWxlW2UucHJvcF0/ZS5lbGVtW2UucHJvcF06KHQ9Uy5jc3MoZS5lbGVtLGUucHJvcCwiIikpJiYiYXV0byIhPT10P3Q6MH0sc2V0OmZ1bmN0aW9uKGUpe1MuZnguc3RlcFtlLnByb3BdP1MuZnguc3RlcFtlLnByb3BdKGUpOjEhPT1lLmVsZW0ubm9kZVR5cGV8fCFTLmNzc0hvb2tzW2UucHJvcF0mJm51bGw9PWUuZWxlbS5zdHlsZVt6ZShlLnByb3ApXT9lLmVsZW1bZS5wcm9wXT1lLm5vdzpTLnN0eWxlKGUuZWxlbSxlLnByb3AsZS5ub3crZS51bml0KX19fSkuc2Nyb2xsVG9wPUtlLnByb3BIb29rcy5zY3JvbGxMZWZ0PXtzZXQ6ZnVuY3Rpb24oZSl7ZS5lbGVtLm5vZGVUeXBlJiZlLmVsZW0ucGFyZW50Tm9kZSYmKGUuZWxlbVtlLnByb3BdPWUubm93KX19LFMuZWFzaW5nPXtsaW5lYXI6ZnVuY3Rpb24oZSl7cmV0dXJuIGV9LHN3aW5nOmZ1bmN0aW9uKGUpe3JldHVybi41LU1hdGguY29zKGUqTWF0aC5QSSkvMn0sX2RlZmF1bHQ6InN3aW5nIn0sUy5meD1LZS5wcm90b3R5cGUuaW5pdCxTLmZ4LnN0ZXA9e307dmFyIFplLGV0LHR0LG50LHJ0PS9eKD86dG9nZ2xlfHNob3d8aGlkZSkkLyxpdD0vcXVldWVIb29rcyQvO2Z1bmN0aW9uIG90KCl7ZXQmJighMT09PUUuaGlkZGVuJiZDLnJlcXVlc3RBbmltYXRpb25GcmFtZT9DLnJlcXVlc3RBbmltYXRpb25GcmFtZShvdCk6Qy5zZXRUaW1lb3V0KG90LFMuZnguaW50ZXJ2YWwpLFMuZngudGljaygpKX1mdW5jdGlvbiBhdCgpe3JldHVybiBDLnNldFRpbWVvdXQoZnVuY3Rpb24oKXtaZT12b2lkIDB9KSxaZT1EYXRlLm5vdygpfWZ1bmN0aW9uIHN0KGUsdCl7dmFyIG4scj0wLGk9e2hlaWdodDplfTtmb3IodD10PzE6MDtyPDQ7cis9Mi10KWlbIm1hcmdpbiIrKG49bmVbcl0pXT1pWyJwYWRkaW5nIituXT1lO3JldHVybiB0JiYoaS5vcGFjaXR5PWkud2lkdGg9ZSksaX1mdW5jdGlvbiB1dChlLHQsbil7Zm9yKHZhciByLGk9KGx0LnR3ZWVuZXJzW3RdfHxbXSkuY29uY2F0KGx0LnR3ZWVuZXJzWyIqIl0pLG89MCxhPWkubGVuZ3RoO288YTtvKyspaWYocj1pW29dLmNhbGwobix0LGUpKXJldHVybiByfWZ1bmN0aW9uIGx0KG8sZSx0KXt2YXIgbixhLHI9MCxpPWx0LnByZWZpbHRlcnMubGVuZ3RoLHM9Uy5EZWZlcnJlZCgpLmFsd2F5cyhmdW5jdGlvbigpe2RlbGV0ZSB1LmVsZW19KSx1PWZ1bmN0aW9uKCl7aWYoYSlyZXR1cm4hMTtmb3IodmFyIGU9WmV8fGF0KCksdD1NYXRoLm1heCgwLGwuc3RhcnRUaW1lK2wuZHVyYXRpb24tZSksbj0xLSh0L2wuZHVyYXRpb258fDApLHI9MCxpPWwudHdlZW5zLmxlbmd0aDtyPGk7cisrKWwudHdlZW5zW3JdLnJ1bihuKTtyZXR1cm4gcy5ub3RpZnlXaXRoKG8sW2wsbix0XSksbjwxJiZpP3Q6KGl8fHMubm90aWZ5V2l0aChvLFtsLDEsMF0pLHMucmVzb2x2ZVdpdGgobyxbbF0pLCExKX0sbD1zLnByb21pc2Uoe2VsZW06byxwcm9wczpTLmV4dGVuZCh7fSxlKSxvcHRzOlMuZXh0ZW5kKCEwLHtzcGVjaWFsRWFzaW5nOnt9LGVhc2luZzpTLmVhc2luZy5fZGVmYXVsdH0sdCksb3JpZ2luYWxQcm9wZXJ0aWVzOmUsb3JpZ2luYWxPcHRpb25zOnQsc3RhcnRUaW1lOlplfHxhdCgpLGR1cmF0aW9uOnQuZHVyYXRpb24sdHdlZW5zOltdLGNyZWF0ZVR3ZWVuOmZ1bmN0aW9uKGUsdCl7dmFyIG49Uy5Ud2VlbihvLGwub3B0cyxlLHQsbC5vcHRzLnNwZWNpYWxFYXNpbmdbZV18fGwub3B0cy5lYXNpbmcpO3JldHVybiBsLnR3ZWVucy5wdXNoKG4pLG59LHN0b3A6ZnVuY3Rpb24oZSl7dmFyIHQ9MCxuPWU/bC50d2VlbnMubGVuZ3RoOjA7aWYoYSlyZXR1cm4gdGhpcztmb3IoYT0hMDt0PG47dCsrKWwudHdlZW5zW3RdLnJ1bigxKTtyZXR1cm4gZT8ocy5ub3RpZnlXaXRoKG8sW2wsMSwwXSkscy5yZXNvbHZlV2l0aChvLFtsLGVdKSk6cy5yZWplY3RXaXRoKG8sW2wsZV0pLHRoaXN9fSksYz1sLnByb3BzO2ZvcighZnVuY3Rpb24oZSx0KXt2YXIgbixyLGksbyxhO2ZvcihuIGluIGUpaWYoaT10W3I9WChuKV0sbz1lW25dLEFycmF5LmlzQXJyYXkobykmJihpPW9bMV0sbz1lW25dPW9bMF0pLG4hPT1yJiYoZVtyXT1vLGRlbGV0ZSBlW25dKSwoYT1TLmNzc0hvb2tzW3JdKSYmImV4cGFuZCJpbiBhKWZvcihuIGluIG89YS5leHBhbmQobyksZGVsZXRlIGVbcl0sbyluIGluIGV8fChlW25dPW9bbl0sdFtuXT1pKTtlbHNlIHRbcl09aX0oYyxsLm9wdHMuc3BlY2lhbEVhc2luZyk7cjxpO3IrKylpZihuPWx0LnByZWZpbHRlcnNbcl0uY2FsbChsLG8sYyxsLm9wdHMpKXJldHVybiBtKG4uc3RvcCkmJihTLl9xdWV1ZUhvb2tzKGwuZWxlbSxsLm9wdHMucXVldWUpLnN0b3A9bi5zdG9wLmJpbmQobikpLG47cmV0dXJuIFMubWFwKGMsdXQsbCksbShsLm9wdHMuc3RhcnQpJiZsLm9wdHMuc3RhcnQuY2FsbChvLGwpLGwucHJvZ3Jlc3MobC5vcHRzLnByb2dyZXNzKS5kb25lKGwub3B0cy5kb25lLGwub3B0cy5jb21wbGV0ZSkuZmFpbChsLm9wdHMuZmFpbCkuYWx3YXlzKGwub3B0cy5hbHdheXMpLFMuZngudGltZXIoUy5leHRlbmQodSx7ZWxlbTpvLGFuaW06bCxxdWV1ZTpsLm9wdHMucXVldWV9KSksbH1TLkFuaW1hdGlvbj1TLmV4dGVuZChsdCx7dHdlZW5lcnM6eyIqIjpbZnVuY3Rpb24oZSx0KXt2YXIgbj10aGlzLmNyZWF0ZVR3ZWVuKGUsdCk7cmV0dXJuIHNlKG4uZWxlbSxlLHRlLmV4ZWModCksbiksbn1dfSx0d2VlbmVyOmZ1bmN0aW9uKGUsdCl7bShlKT8odD1lLGU9WyIqIl0pOmU9ZS5tYXRjaChQKTtmb3IodmFyIG4scj0wLGk9ZS5sZW5ndGg7cjxpO3IrKyluPWVbcl0sbHQudHdlZW5lcnNbbl09bHQudHdlZW5lcnNbbl18fFtdLGx0LnR3ZWVuZXJzW25dLnVuc2hpZnQodCl9LHByZWZpbHRlcnM6W2Z1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG8sYSxzLHUsbCxjLGY9IndpZHRoImluIHR8fCJoZWlnaHQiaW4gdCxwPXRoaXMsZD17fSxoPWUuc3R5bGUsZz1lLm5vZGVUeXBlJiZhZShlKSx2PVkuZ2V0KGUsImZ4c2hvdyIpO2ZvcihyIGluIG4ucXVldWV8fChudWxsPT0oYT1TLl9xdWV1ZUhvb2tzKGUsImZ4IikpLnVucXVldWVkJiYoYS51bnF1ZXVlZD0wLHM9YS5lbXB0eS5maXJlLGEuZW1wdHkuZmlyZT1mdW5jdGlvbigpe2EudW5xdWV1ZWR8fHMoKX0pLGEudW5xdWV1ZWQrKyxwLmFsd2F5cyhmdW5jdGlvbigpe3AuYWx3YXlzKGZ1bmN0aW9uKCl7YS51bnF1ZXVlZC0tLFMucXVldWUoZSwiZngiKS5sZW5ndGh8fGEuZW1wdHkuZmlyZSgpfSl9KSksdClpZihpPXRbcl0scnQudGVzdChpKSl7aWYoZGVsZXRlIHRbcl0sbz1vfHwidG9nZ2xlIj09PWksaT09PShnPyJoaWRlIjoic2hvdyIpKXtpZigic2hvdyIhPT1pfHwhdnx8dm9pZCAwPT09dltyXSljb250aW51ZTtnPSEwfWRbcl09diYmdltyXXx8Uy5zdHlsZShlLHIpfWlmKCh1PSFTLmlzRW1wdHlPYmplY3QodCkpfHwhUy5pc0VtcHR5T2JqZWN0KGQpKWZvcihyIGluIGYmJjE9PT1lLm5vZGVUeXBlJiYobi5vdmVyZmxvdz1baC5vdmVyZmxvdyxoLm92ZXJmbG93WCxoLm92ZXJmbG93WV0sbnVsbD09KGw9diYmdi5kaXNwbGF5KSYmKGw9WS5nZXQoZSwiZGlzcGxheSIpKSwibm9uZSI9PT0oYz1TLmNzcyhlLCJkaXNwbGF5IikpJiYobD9jPWw6KGxlKFtlXSwhMCksbD1lLnN0eWxlLmRpc3BsYXl8fGwsYz1TLmNzcyhlLCJkaXNwbGF5IiksbGUoW2VdKSkpLCgiaW5saW5lIj09PWN8fCJpbmxpbmUtYmxvY2siPT09YyYmbnVsbCE9bCkmJiJub25lIj09PVMuY3NzKGUsImZsb2F0IikmJih1fHwocC5kb25lKGZ1bmN0aW9uKCl7aC5kaXNwbGF5PWx9KSxudWxsPT1sJiYoYz1oLmRpc3BsYXksbD0ibm9uZSI9PT1jPyIiOmMpKSxoLmRpc3BsYXk9ImlubGluZS1ibG9jayIpKSxuLm92ZXJmbG93JiYoaC5vdmVyZmxvdz0iaGlkZGVuIixwLmFsd2F5cyhmdW5jdGlvbigpe2gub3ZlcmZsb3c9bi5vdmVyZmxvd1swXSxoLm92ZXJmbG93WD1uLm92ZXJmbG93WzFdLGgub3ZlcmZsb3dZPW4ub3ZlcmZsb3dbMl19KSksdT0hMSxkKXV8fCh2PyJoaWRkZW4iaW4gdiYmKGc9di5oaWRkZW4pOnY9WS5hY2Nlc3MoZSwiZnhzaG93Iix7ZGlzcGxheTpsfSksbyYmKHYuaGlkZGVuPSFnKSxnJiZsZShbZV0sITApLHAuZG9uZShmdW5jdGlvbigpe2ZvcihyIGluIGd8fGxlKFtlXSksWS5yZW1vdmUoZSwiZnhzaG93IiksZClTLnN0eWxlKGUscixkW3JdKX0pKSx1PXV0KGc/dltyXTowLHIscCksciBpbiB2fHwodltyXT11LnN0YXJ0LGcmJih1LmVuZD11LnN0YXJ0LHUuc3RhcnQ9MCkpfV0scHJlZmlsdGVyOmZ1bmN0aW9uKGUsdCl7dD9sdC5wcmVmaWx0ZXJzLnVuc2hpZnQoZSk6bHQucHJlZmlsdGVycy5wdXNoKGUpfX0pLFMuc3BlZWQ9ZnVuY3Rpb24oZSx0LG4pe3ZhciByPWUmJiJvYmplY3QiPT10eXBlb2YgZT9TLmV4dGVuZCh7fSxlKTp7Y29tcGxldGU6bnx8IW4mJnR8fG0oZSkmJmUsZHVyYXRpb246ZSxlYXNpbmc6biYmdHx8dCYmIW0odCkmJnR9O3JldHVybiBTLmZ4Lm9mZj9yLmR1cmF0aW9uPTA6Im51bWJlciIhPXR5cGVvZiByLmR1cmF0aW9uJiYoci5kdXJhdGlvbiBpbiBTLmZ4LnNwZWVkcz9yLmR1cmF0aW9uPVMuZnguc3BlZWRzW3IuZHVyYXRpb25dOnIuZHVyYXRpb249Uy5meC5zcGVlZHMuX2RlZmF1bHQpLG51bGwhPXIucXVldWUmJiEwIT09ci5xdWV1ZXx8KHIucXVldWU9ImZ4Iiksci5vbGQ9ci5jb21wbGV0ZSxyLmNvbXBsZXRlPWZ1bmN0aW9uKCl7bShyLm9sZCkmJnIub2xkLmNhbGwodGhpcyksci5xdWV1ZSYmUy5kZXF1ZXVlKHRoaXMsci5xdWV1ZSl9LHJ9LFMuZm4uZXh0ZW5kKHtmYWRlVG86ZnVuY3Rpb24oZSx0LG4scil7cmV0dXJuIHRoaXMuZmlsdGVyKGFlKS5jc3MoIm9wYWNpdHkiLDApLnNob3coKS5lbmQoKS5hbmltYXRlKHtvcGFjaXR5OnR9LGUsbixyKX0sYW5pbWF0ZTpmdW5jdGlvbih0LGUsbixyKXt2YXIgaT1TLmlzRW1wdHlPYmplY3QodCksbz1TLnNwZWVkKGUsbixyKSxhPWZ1bmN0aW9uKCl7dmFyIGU9bHQodGhpcyxTLmV4dGVuZCh7fSx0KSxvKTsoaXx8WS5nZXQodGhpcywiZmluaXNoIikpJiZlLnN0b3AoITApfTtyZXR1cm4gYS5maW5pc2g9YSxpfHwhMT09PW8ucXVldWU/dGhpcy5lYWNoKGEpOnRoaXMucXVldWUoby5xdWV1ZSxhKX0sc3RvcDpmdW5jdGlvbihpLGUsbyl7dmFyIGE9ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5zdG9wO2RlbGV0ZSBlLnN0b3AsdChvKX07cmV0dXJuInN0cmluZyIhPXR5cGVvZiBpJiYobz1lLGU9aSxpPXZvaWQgMCksZSYmdGhpcy5xdWV1ZShpfHwiZngiLFtdKSx0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgZT0hMCx0PW51bGwhPWkmJmkrInF1ZXVlSG9va3MiLG49Uy50aW1lcnMscj1ZLmdldCh0aGlzKTtpZih0KXJbdF0mJnJbdF0uc3RvcCYmYShyW3RdKTtlbHNlIGZvcih0IGluIHIpclt0XSYmclt0XS5zdG9wJiZpdC50ZXN0KHQpJiZhKHJbdF0pO2Zvcih0PW4ubGVuZ3RoO3QtLTspblt0XS5lbGVtIT09dGhpc3x8bnVsbCE9aSYmblt0XS5xdWV1ZSE9PWl8fChuW3RdLmFuaW0uc3RvcChvKSxlPSExLG4uc3BsaWNlKHQsMSkpOyFlJiZvfHxTLmRlcXVldWUodGhpcyxpKX0pfSxmaW5pc2g6ZnVuY3Rpb24oYSl7cmV0dXJuITEhPT1hJiYoYT1hfHwiZngiKSx0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgZSx0PVkuZ2V0KHRoaXMpLG49dFthKyJxdWV1ZSJdLHI9dFthKyJxdWV1ZUhvb2tzIl0saT1TLnRpbWVycyxvPW4/bi5sZW5ndGg6MDtmb3IodC5maW5pc2g9ITAsUy5xdWV1ZSh0aGlzLGEsW10pLHImJnIuc3RvcCYmci5zdG9wLmNhbGwodGhpcywhMCksZT1pLmxlbmd0aDtlLS07KWlbZV0uZWxlbT09PXRoaXMmJmlbZV0ucXVldWU9PT1hJiYoaVtlXS5hbmltLnN0b3AoITApLGkuc3BsaWNlKGUsMSkpO2ZvcihlPTA7ZTxvO2UrKyluW2VdJiZuW2VdLmZpbmlzaCYmbltlXS5maW5pc2guY2FsbCh0aGlzKTtkZWxldGUgdC5maW5pc2h9KX19KSxTLmVhY2goWyJ0b2dnbGUiLCJzaG93IiwiaGlkZSJdLGZ1bmN0aW9uKGUscil7dmFyIGk9Uy5mbltyXTtTLmZuW3JdPWZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gbnVsbD09ZXx8ImJvb2xlYW4iPT10eXBlb2YgZT9pLmFwcGx5KHRoaXMsYXJndW1lbnRzKTp0aGlzLmFuaW1hdGUoc3QociwhMCksZSx0LG4pfX0pLFMuZWFjaCh7c2xpZGVEb3duOnN0KCJzaG93Iiksc2xpZGVVcDpzdCgiaGlkZSIpLHNsaWRlVG9nZ2xlOnN0KCJ0b2dnbGUiKSxmYWRlSW46e29wYWNpdHk6InNob3cifSxmYWRlT3V0OntvcGFjaXR5OiJoaWRlIn0sZmFkZVRvZ2dsZTp7b3BhY2l0eToidG9nZ2xlIn19LGZ1bmN0aW9uKGUscil7Uy5mbltlXT1mdW5jdGlvbihlLHQsbil7cmV0dXJuIHRoaXMuYW5pbWF0ZShyLGUsdCxuKX19KSxTLnRpbWVycz1bXSxTLmZ4LnRpY2s9ZnVuY3Rpb24oKXt2YXIgZSx0PTAsbj1TLnRpbWVycztmb3IoWmU9RGF0ZS5ub3coKTt0PG4ubGVuZ3RoO3QrKykoZT1uW3RdKSgpfHxuW3RdIT09ZXx8bi5zcGxpY2UodC0tLDEpO24ubGVuZ3RofHxTLmZ4LnN0b3AoKSxaZT12b2lkIDB9LFMuZngudGltZXI9ZnVuY3Rpb24oZSl7Uy50aW1lcnMucHVzaChlKSxTLmZ4LnN0YXJ0KCl9LFMuZnguaW50ZXJ2YWw9MTMsUy5meC5zdGFydD1mdW5jdGlvbigpe2V0fHwoZXQ9ITAsb3QoKSl9LFMuZnguc3RvcD1mdW5jdGlvbigpe2V0PW51bGx9LFMuZnguc3BlZWRzPXtzbG93OjYwMCxmYXN0OjIwMCxfZGVmYXVsdDo0MDB9LFMuZm4uZGVsYXk9ZnVuY3Rpb24ocixlKXtyZXR1cm4gcj1TLmZ4JiZTLmZ4LnNwZWVkc1tyXXx8cixlPWV8fCJmeCIsdGhpcy5xdWV1ZShlLGZ1bmN0aW9uKGUsdCl7dmFyIG49Qy5zZXRUaW1lb3V0KGUscik7dC5zdG9wPWZ1bmN0aW9uKCl7Qy5jbGVhclRpbWVvdXQobil9fSl9LHR0PUUuY3JlYXRlRWxlbWVudCgiaW5wdXQiKSxudD1FLmNyZWF0ZUVsZW1lbnQoInNlbGVjdCIpLmFwcGVuZENoaWxkKEUuY3JlYXRlRWxlbWVudCgib3B0aW9uIikpLHR0LnR5cGU9ImNoZWNrYm94Iix5LmNoZWNrT249IiIhPT10dC52YWx1ZSx5Lm9wdFNlbGVjdGVkPW50LnNlbGVjdGVkLCh0dD1FLmNyZWF0ZUVsZW1lbnQoImlucHV0IikpLnZhbHVlPSJ0Iix0dC50eXBlPSJyYWRpbyIseS5yYWRpb1ZhbHVlPSJ0Ij09PXR0LnZhbHVlO3ZhciBjdCxmdD1TLmV4cHIuYXR0ckhhbmRsZTtTLmZuLmV4dGVuZCh7YXR0cjpmdW5jdGlvbihlLHQpe3JldHVybiAkKHRoaXMsUy5hdHRyLGUsdCwxPGFyZ3VtZW50cy5sZW5ndGgpfSxyZW1vdmVBdHRyOmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtTLnJlbW92ZUF0dHIodGhpcyxlKX0pfX0pLFMuZXh0ZW5kKHthdHRyOmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG89ZS5ub2RlVHlwZTtpZigzIT09byYmOCE9PW8mJjIhPT1vKXJldHVybiJ1bmRlZmluZWQiPT10eXBlb2YgZS5nZXRBdHRyaWJ1dGU/Uy5wcm9wKGUsdCxuKTooMT09PW8mJlMuaXNYTUxEb2MoZSl8fChpPVMuYXR0ckhvb2tzW3QudG9Mb3dlckNhc2UoKV18fChTLmV4cHIubWF0Y2guYm9vbC50ZXN0KHQpP2N0OnZvaWQgMCkpLHZvaWQgMCE9PW4/bnVsbD09PW4/dm9pZCBTLnJlbW92ZUF0dHIoZSx0KTppJiYic2V0ImluIGkmJnZvaWQgMCE9PShyPWkuc2V0KGUsbix0KSk/cjooZS5zZXRBdHRyaWJ1dGUodCxuKyIiKSxuKTppJiYiZ2V0ImluIGkmJm51bGwhPT0ocj1pLmdldChlLHQpKT9yOm51bGw9PShyPVMuZmluZC5hdHRyKGUsdCkpP3ZvaWQgMDpyKX0sYXR0ckhvb2tzOnt0eXBlOntzZXQ6ZnVuY3Rpb24oZSx0KXtpZigheS5yYWRpb1ZhbHVlJiYicmFkaW8iPT09dCYmQShlLCJpbnB1dCIpKXt2YXIgbj1lLnZhbHVlO3JldHVybiBlLnNldEF0dHJpYnV0ZSgidHlwZSIsdCksbiYmKGUudmFsdWU9biksdH19fX0scmVtb3ZlQXR0cjpmdW5jdGlvbihlLHQpe3ZhciBuLHI9MCxpPXQmJnQubWF0Y2goUCk7aWYoaSYmMT09PWUubm9kZVR5cGUpd2hpbGUobj1pW3IrK10pZS5yZW1vdmVBdHRyaWJ1dGUobil9fSksY3Q9e3NldDpmdW5jdGlvbihlLHQsbil7cmV0dXJuITE9PT10P1MucmVtb3ZlQXR0cihlLG4pOmUuc2V0QXR0cmlidXRlKG4sbiksbn19LFMuZWFjaChTLmV4cHIubWF0Y2guYm9vbC5zb3VyY2UubWF0Y2goL1x3Ky9nKSxmdW5jdGlvbihlLHQpe3ZhciBhPWZ0W3RdfHxTLmZpbmQuYXR0cjtmdFt0XT1mdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvPXQudG9Mb3dlckNhc2UoKTtyZXR1cm4gbnx8KGk9ZnRbb10sZnRbb109cixyPW51bGwhPWEoZSx0LG4pP286bnVsbCxmdFtvXT1pKSxyfX0pO3ZhciBwdD0vXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxidXR0b24pJC9pLGR0PS9eKD86YXxhcmVhKSQvaTtmdW5jdGlvbiBodChlKXtyZXR1cm4oZS5tYXRjaChQKXx8W10pLmpvaW4oIiAiKX1mdW5jdGlvbiBndChlKXtyZXR1cm4gZS5nZXRBdHRyaWJ1dGUmJmUuZ2V0QXR0cmlidXRlKCJjbGFzcyIpfHwiIn1mdW5jdGlvbiB2dChlKXtyZXR1cm4gQXJyYXkuaXNBcnJheShlKT9lOiJzdHJpbmciPT10eXBlb2YgZSYmZS5tYXRjaChQKXx8W119Uy5mbi5leHRlbmQoe3Byb3A6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gJCh0aGlzLFMucHJvcCxlLHQsMTxhcmd1bWVudHMubGVuZ3RoKX0scmVtb3ZlUHJvcDpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7ZGVsZXRlIHRoaXNbUy5wcm9wRml4W2VdfHxlXX0pfX0pLFMuZXh0ZW5kKHtwcm9wOmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG89ZS5ub2RlVHlwZTtpZigzIT09byYmOCE9PW8mJjIhPT1vKXJldHVybiAxPT09byYmUy5pc1hNTERvYyhlKXx8KHQ9Uy5wcm9wRml4W3RdfHx0LGk9Uy5wcm9wSG9va3NbdF0pLHZvaWQgMCE9PW4/aSYmInNldCJpbiBpJiZ2b2lkIDAhPT0ocj1pLnNldChlLG4sdCkpP3I6ZVt0XT1uOmkmJiJnZXQiaW4gaSYmbnVsbCE9PShyPWkuZ2V0KGUsdCkpP3I6ZVt0XX0scHJvcEhvb2tzOnt0YWJJbmRleDp7Z2V0OmZ1bmN0aW9uKGUpe3ZhciB0PVMuZmluZC5hdHRyKGUsInRhYmluZGV4Iik7cmV0dXJuIHQ/cGFyc2VJbnQodCwxMCk6cHQudGVzdChlLm5vZGVOYW1lKXx8ZHQudGVzdChlLm5vZGVOYW1lKSYmZS5ocmVmPzA6LTF9fX0scHJvcEZpeDp7ImZvciI6Imh0bWxGb3IiLCJjbGFzcyI6ImNsYXNzTmFtZSJ9fSkseS5vcHRTZWxlY3RlZHx8KFMucHJvcEhvb2tzLnNlbGVjdGVkPXtnZXQ6ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5wYXJlbnROb2RlO3JldHVybiB0JiZ0LnBhcmVudE5vZGUmJnQucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4LG51bGx9LHNldDpmdW5jdGlvbihlKXt2YXIgdD1lLnBhcmVudE5vZGU7dCYmKHQuc2VsZWN0ZWRJbmRleCx0LnBhcmVudE5vZGUmJnQucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4KX19KSxTLmVhY2goWyJ0YWJJbmRleCIsInJlYWRPbmx5IiwibWF4TGVuZ3RoIiwiY2VsbFNwYWNpbmciLCJjZWxsUGFkZGluZyIsInJvd1NwYW4iLCJjb2xTcGFuIiwidXNlTWFwIiwiZnJhbWVCb3JkZXIiLCJjb250ZW50RWRpdGFibGUiXSxmdW5jdGlvbigpe1MucHJvcEZpeFt0aGlzLnRvTG93ZXJDYXNlKCldPXRoaXN9KSxTLmZuLmV4dGVuZCh7YWRkQ2xhc3M6ZnVuY3Rpb24odCl7dmFyIGUsbixyLGksbyxhLHMsdT0wO2lmKG0odCkpcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihlKXtTKHRoaXMpLmFkZENsYXNzKHQuY2FsbCh0aGlzLGUsZ3QodGhpcykpKX0pO2lmKChlPXZ0KHQpKS5sZW5ndGgpd2hpbGUobj10aGlzW3UrK10paWYoaT1ndChuKSxyPTE9PT1uLm5vZGVUeXBlJiYiICIraHQoaSkrIiAiKXthPTA7d2hpbGUobz1lW2ErK10pci5pbmRleE9mKCIgIitvKyIgIik8MCYmKHIrPW8rIiAiKTtpIT09KHM9aHQocikpJiZuLnNldEF0dHJpYnV0ZSgiY2xhc3MiLHMpfXJldHVybiB0aGlzfSxyZW1vdmVDbGFzczpmdW5jdGlvbih0KXt2YXIgZSxuLHIsaSxvLGEscyx1PTA7aWYobSh0KSlyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKGUpe1ModGhpcykucmVtb3ZlQ2xhc3ModC5jYWxsKHRoaXMsZSxndCh0aGlzKSkpfSk7aWYoIWFyZ3VtZW50cy5sZW5ndGgpcmV0dXJuIHRoaXMuYXR0cigiY2xhc3MiLCIiKTtpZigoZT12dCh0KSkubGVuZ3RoKXdoaWxlKG49dGhpc1t1KytdKWlmKGk9Z3Qobikscj0xPT09bi5ub2RlVHlwZSYmIiAiK2h0KGkpKyIgIil7YT0wO3doaWxlKG89ZVthKytdKXdoaWxlKC0xPHIuaW5kZXhPZigiICIrbysiICIpKXI9ci5yZXBsYWNlKCIgIitvKyIgIiwiICIpO2khPT0ocz1odChyKSkmJm4uc2V0QXR0cmlidXRlKCJjbGFzcyIscyl9cmV0dXJuIHRoaXN9LHRvZ2dsZUNsYXNzOmZ1bmN0aW9uKGksdCl7dmFyIG89dHlwZW9mIGksYT0ic3RyaW5nIj09PW98fEFycmF5LmlzQXJyYXkoaSk7cmV0dXJuImJvb2xlYW4iPT10eXBlb2YgdCYmYT90P3RoaXMuYWRkQ2xhc3MoaSk6dGhpcy5yZW1vdmVDbGFzcyhpKTptKGkpP3RoaXMuZWFjaChmdW5jdGlvbihlKXtTKHRoaXMpLnRvZ2dsZUNsYXNzKGkuY2FsbCh0aGlzLGUsZ3QodGhpcyksdCksdCl9KTp0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgZSx0LG4scjtpZihhKXt0PTAsbj1TKHRoaXMpLHI9dnQoaSk7d2hpbGUoZT1yW3QrK10pbi5oYXNDbGFzcyhlKT9uLnJlbW92ZUNsYXNzKGUpOm4uYWRkQ2xhc3MoZSl9ZWxzZSB2b2lkIDAhPT1pJiYiYm9vbGVhbiIhPT1vfHwoKGU9Z3QodGhpcykpJiZZLnNldCh0aGlzLCJfX2NsYXNzTmFtZV9fIixlKSx0aGlzLnNldEF0dHJpYnV0ZSYmdGhpcy5zZXRBdHRyaWJ1dGUoImNsYXNzIixlfHwhMT09PWk/IiI6WS5nZXQodGhpcywiX19jbGFzc05hbWVfXyIpfHwiIikpfSl9LGhhc0NsYXNzOmZ1bmN0aW9uKGUpe3ZhciB0LG4scj0wO3Q9IiAiK2UrIiAiO3doaWxlKG49dGhpc1tyKytdKWlmKDE9PT1uLm5vZGVUeXBlJiYtMTwoIiAiK2h0KGd0KG4pKSsiICIpLmluZGV4T2YodCkpcmV0dXJuITA7cmV0dXJuITF9fSk7dmFyIHl0PS9cci9nO1MuZm4uZXh0ZW5kKHt2YWw6ZnVuY3Rpb24obil7dmFyIHIsZSxpLHQ9dGhpc1swXTtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD8oaT1tKG4pLHRoaXMuZWFjaChmdW5jdGlvbihlKXt2YXIgdDsxPT09dGhpcy5ub2RlVHlwZSYmKG51bGw9PSh0PWk/bi5jYWxsKHRoaXMsZSxTKHRoaXMpLnZhbCgpKTpuKT90PSIiOiJudW1iZXIiPT10eXBlb2YgdD90Kz0iIjpBcnJheS5pc0FycmF5KHQpJiYodD1TLm1hcCh0LGZ1bmN0aW9uKGUpe3JldHVybiBudWxsPT1lPyIiOmUrIiJ9KSksKHI9Uy52YWxIb29rc1t0aGlzLnR5cGVdfHxTLnZhbEhvb2tzW3RoaXMubm9kZU5hbWUudG9Mb3dlckNhc2UoKV0pJiYic2V0ImluIHImJnZvaWQgMCE9PXIuc2V0KHRoaXMsdCwidmFsdWUiKXx8KHRoaXMudmFsdWU9dCkpfSkpOnQ/KHI9Uy52YWxIb29rc1t0LnR5cGVdfHxTLnZhbEhvb2tzW3Qubm9kZU5hbWUudG9Mb3dlckNhc2UoKV0pJiYiZ2V0ImluIHImJnZvaWQgMCE9PShlPXIuZ2V0KHQsInZhbHVlIikpP2U6InN0cmluZyI9PXR5cGVvZihlPXQudmFsdWUpP2UucmVwbGFjZSh5dCwiIik6bnVsbD09ZT8iIjplOnZvaWQgMH19KSxTLmV4dGVuZCh7dmFsSG9va3M6e29wdGlvbjp7Z2V0OmZ1bmN0aW9uKGUpe3ZhciB0PVMuZmluZC5hdHRyKGUsInZhbHVlIik7cmV0dXJuIG51bGwhPXQ/dDpodChTLnRleHQoZSkpfX0sc2VsZWN0OntnZXQ6ZnVuY3Rpb24oZSl7dmFyIHQsbixyLGk9ZS5vcHRpb25zLG89ZS5zZWxlY3RlZEluZGV4LGE9InNlbGVjdC1vbmUiPT09ZS50eXBlLHM9YT9udWxsOltdLHU9YT9vKzE6aS5sZW5ndGg7Zm9yKHI9bzwwP3U6YT9vOjA7cjx1O3IrKylpZigoKG49aVtyXSkuc2VsZWN0ZWR8fHI9PT1vKSYmIW4uZGlzYWJsZWQmJighbi5wYXJlbnROb2RlLmRpc2FibGVkfHwhQShuLnBhcmVudE5vZGUsIm9wdGdyb3VwIikpKXtpZih0PVMobikudmFsKCksYSlyZXR1cm4gdDtzLnB1c2godCl9cmV0dXJuIHN9LHNldDpmdW5jdGlvbihlLHQpe3ZhciBuLHIsaT1lLm9wdGlvbnMsbz1TLm1ha2VBcnJheSh0KSxhPWkubGVuZ3RoO3doaWxlKGEtLSkoKHI9aVthXSkuc2VsZWN0ZWQ9LTE8Uy5pbkFycmF5KFMudmFsSG9va3Mub3B0aW9uLmdldChyKSxvKSkmJihuPSEwKTtyZXR1cm4gbnx8KGUuc2VsZWN0ZWRJbmRleD0tMSksb319fX0pLFMuZWFjaChbInJhZGlvIiwiY2hlY2tib3giXSxmdW5jdGlvbigpe1MudmFsSG9va3NbdGhpc109e3NldDpmdW5jdGlvbihlLHQpe2lmKEFycmF5LmlzQXJyYXkodCkpcmV0dXJuIGUuY2hlY2tlZD0tMTxTLmluQXJyYXkoUyhlKS52YWwoKSx0KX19LHkuY2hlY2tPbnx8KFMudmFsSG9va3NbdGhpc10uZ2V0PWZ1bmN0aW9uKGUpe3JldHVybiBudWxsPT09ZS5nZXRBdHRyaWJ1dGUoInZhbHVlIik/Im9uIjplLnZhbHVlfSl9KSx5LmZvY3VzaW49Im9uZm9jdXNpbiJpbiBDO3ZhciBtdD0vXig/OmZvY3VzaW5mb2N1c3xmb2N1c291dGJsdXIpJC8seHQ9ZnVuY3Rpb24oZSl7ZS5zdG9wUHJvcGFnYXRpb24oKX07Uy5leHRlbmQoUy5ldmVudCx7dHJpZ2dlcjpmdW5jdGlvbihlLHQsbixyKXt2YXIgaSxvLGEscyx1LGwsYyxmLHA9W258fEVdLGQ9di5jYWxsKGUsInR5cGUiKT9lLnR5cGU6ZSxoPXYuY2FsbChlLCJuYW1lc3BhY2UiKT9lLm5hbWVzcGFjZS5zcGxpdCgiLiIpOltdO2lmKG89Zj1hPW49bnx8RSwzIT09bi5ub2RlVHlwZSYmOCE9PW4ubm9kZVR5cGUmJiFtdC50ZXN0KGQrUy5ldmVudC50cmlnZ2VyZWQpJiYoLTE8ZC5pbmRleE9mKCIuIikmJihkPShoPWQuc3BsaXQoIi4iKSkuc2hpZnQoKSxoLnNvcnQoKSksdT1kLmluZGV4T2YoIjoiKTwwJiYib24iK2QsKGU9ZVtTLmV4cGFuZG9dP2U6bmV3IFMuRXZlbnQoZCwib2JqZWN0Ij09dHlwZW9mIGUmJmUpKS5pc1RyaWdnZXI9cj8yOjMsZS5uYW1lc3BhY2U9aC5qb2luKCIuIiksZS5ybmFtZXNwYWNlPWUubmFtZXNwYWNlP25ldyBSZWdFeHAoIihefFxcLikiK2guam9pbigiXFwuKD86LipcXC58KSIpKyIoXFwufCQpIik6bnVsbCxlLnJlc3VsdD12b2lkIDAsZS50YXJnZXR8fChlLnRhcmdldD1uKSx0PW51bGw9PXQ/W2VdOlMubWFrZUFycmF5KHQsW2VdKSxjPVMuZXZlbnQuc3BlY2lhbFtkXXx8e30scnx8IWMudHJpZ2dlcnx8ITEhPT1jLnRyaWdnZXIuYXBwbHkobix0KSkpe2lmKCFyJiYhYy5ub0J1YmJsZSYmIXgobikpe2ZvcihzPWMuZGVsZWdhdGVUeXBlfHxkLG10LnRlc3QocytkKXx8KG89by5wYXJlbnROb2RlKTtvO289by5wYXJlbnROb2RlKXAucHVzaChvKSxhPW87YT09PShuLm93bmVyRG9jdW1lbnR8fEUpJiZwLnB1c2goYS5kZWZhdWx0Vmlld3x8YS5wYXJlbnRXaW5kb3d8fEMpfWk9MDt3aGlsZSgobz1wW2krK10pJiYhZS5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpKWY9byxlLnR5cGU9MTxpP3M6Yy5iaW5kVHlwZXx8ZCwobD0oWS5nZXQobywiZXZlbnRzIil8fE9iamVjdC5jcmVhdGUobnVsbCkpW2UudHlwZV0mJlkuZ2V0KG8sImhhbmRsZSIpKSYmbC5hcHBseShvLHQpLChsPXUmJm9bdV0pJiZsLmFwcGx5JiZWKG8pJiYoZS5yZXN1bHQ9bC5hcHBseShvLHQpLCExPT09ZS5yZXN1bHQmJmUucHJldmVudERlZmF1bHQoKSk7cmV0dXJuIGUudHlwZT1kLHJ8fGUuaXNEZWZhdWx0UHJldmVudGVkKCl8fGMuX2RlZmF1bHQmJiExIT09Yy5fZGVmYXVsdC5hcHBseShwLnBvcCgpLHQpfHwhVihuKXx8dSYmbShuW2RdKSYmIXgobikmJigoYT1uW3VdKSYmKG5bdV09bnVsbCksUy5ldmVudC50cmlnZ2VyZWQ9ZCxlLmlzUHJvcGFnYXRpb25TdG9wcGVkKCkmJmYuYWRkRXZlbnRMaXN0ZW5lcihkLHh0KSxuW2RdKCksZS5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpJiZmLnJlbW92ZUV2ZW50TGlzdGVuZXIoZCx4dCksUy5ldmVudC50cmlnZ2VyZWQ9dm9pZCAwLGEmJihuW3VdPWEpKSxlLnJlc3VsdH19LHNpbXVsYXRlOmZ1bmN0aW9uKGUsdCxuKXt2YXIgcj1TLmV4dGVuZChuZXcgUy5FdmVudCxuLHt0eXBlOmUsaXNTaW11bGF0ZWQ6ITB9KTtTLmV2ZW50LnRyaWdnZXIocixudWxsLHQpfX0pLFMuZm4uZXh0ZW5kKHt0cmlnZ2VyOmZ1bmN0aW9uKGUsdCl7cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe1MuZXZlbnQudHJpZ2dlcihlLHQsdGhpcyl9KX0sdHJpZ2dlckhhbmRsZXI6ZnVuY3Rpb24oZSx0KXt2YXIgbj10aGlzWzBdO2lmKG4pcmV0dXJuIFMuZXZlbnQudHJpZ2dlcihlLHQsbiwhMCl9fSkseS5mb2N1c2lufHxTLmVhY2goe2ZvY3VzOiJmb2N1c2luIixibHVyOiJmb2N1c291dCJ9LGZ1bmN0aW9uKG4scil7dmFyIGk9ZnVuY3Rpb24oZSl7Uy5ldmVudC5zaW11bGF0ZShyLGUudGFyZ2V0LFMuZXZlbnQuZml4KGUpKX07Uy5ldmVudC5zcGVjaWFsW3JdPXtzZXR1cDpmdW5jdGlvbigpe3ZhciBlPXRoaXMub3duZXJEb2N1bWVudHx8dGhpcy5kb2N1bWVudHx8dGhpcyx0PVkuYWNjZXNzKGUscik7dHx8ZS5hZGRFdmVudExpc3RlbmVyKG4saSwhMCksWS5hY2Nlc3MoZSxyLCh0fHwwKSsxKX0sdGVhcmRvd246ZnVuY3Rpb24oKXt2YXIgZT10aGlzLm93bmVyRG9jdW1lbnR8fHRoaXMuZG9jdW1lbnR8fHRoaXMsdD1ZLmFjY2VzcyhlLHIpLTE7dD9ZLmFjY2VzcyhlLHIsdCk6KGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihuLGksITApLFkucmVtb3ZlKGUscikpfX19KTt2YXIgYnQ9Qy5sb2NhdGlvbix3dD17Z3VpZDpEYXRlLm5vdygpfSxUdD0vXD8vO1MucGFyc2VYTUw9ZnVuY3Rpb24oZSl7dmFyIHQsbjtpZighZXx8InN0cmluZyIhPXR5cGVvZiBlKXJldHVybiBudWxsO3RyeXt0PShuZXcgQy5ET01QYXJzZXIpLnBhcnNlRnJvbVN0cmluZyhlLCJ0ZXh0L3htbCIpfWNhdGNoKGUpe31yZXR1cm4gbj10JiZ0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJwYXJzZXJlcnJvciIpWzBdLHQmJiFufHxTLmVycm9yKCJJbnZhbGlkIFhNTDogIisobj9TLm1hcChuLmNoaWxkTm9kZXMsZnVuY3Rpb24oZSl7cmV0dXJuIGUudGV4dENvbnRlbnR9KS5qb2luKCJcbiIpOmUpKSx0fTt2YXIgQ3Q9L1xbXF0kLyxFdD0vXHI/XG4vZyxTdD0vXig/OnN1Ym1pdHxidXR0b258aW1hZ2V8cmVzZXR8ZmlsZSkkL2ksa3Q9L14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8a2V5Z2VuKS9pO2Z1bmN0aW9uIEF0KG4sZSxyLGkpe3ZhciB0O2lmKEFycmF5LmlzQXJyYXkoZSkpUy5lYWNoKGUsZnVuY3Rpb24oZSx0KXtyfHxDdC50ZXN0KG4pP2kobix0KTpBdChuKyJbIisoIm9iamVjdCI9PXR5cGVvZiB0JiZudWxsIT10P2U6IiIpKyJdIix0LHIsaSl9KTtlbHNlIGlmKHJ8fCJvYmplY3QiIT09dyhlKSlpKG4sZSk7ZWxzZSBmb3IodCBpbiBlKUF0KG4rIlsiK3QrIl0iLGVbdF0scixpKX1TLnBhcmFtPWZ1bmN0aW9uKGUsdCl7dmFyIG4scj1bXSxpPWZ1bmN0aW9uKGUsdCl7dmFyIG49bSh0KT90KCk6dDtyW3IubGVuZ3RoXT1lbmNvZGVVUklDb21wb25lbnQoZSkrIj0iK2VuY29kZVVSSUNvbXBvbmVudChudWxsPT1uPyIiOm4pfTtpZihudWxsPT1lKXJldHVybiIiO2lmKEFycmF5LmlzQXJyYXkoZSl8fGUuanF1ZXJ5JiYhUy5pc1BsYWluT2JqZWN0KGUpKVMuZWFjaChlLGZ1bmN0aW9uKCl7aSh0aGlzLm5hbWUsdGhpcy52YWx1ZSl9KTtlbHNlIGZvcihuIGluIGUpQXQobixlW25dLHQsaSk7cmV0dXJuIHIuam9pbigiJiIpfSxTLmZuLmV4dGVuZCh7c2VyaWFsaXplOmZ1bmN0aW9uKCl7cmV0dXJuIFMucGFyYW0odGhpcy5zZXJpYWxpemVBcnJheSgpKX0sc2VyaWFsaXplQXJyYXk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24oKXt2YXIgZT1TLnByb3AodGhpcywiZWxlbWVudHMiKTtyZXR1cm4gZT9TLm1ha2VBcnJheShlKTp0aGlzfSkuZmlsdGVyKGZ1bmN0aW9uKCl7dmFyIGU9dGhpcy50eXBlO3JldHVybiB0aGlzLm5hbWUmJiFTKHRoaXMpLmlzKCI6ZGlzYWJsZWQiKSYma3QudGVzdCh0aGlzLm5vZGVOYW1lKSYmIVN0LnRlc3QoZSkmJih0aGlzLmNoZWNrZWR8fCFwZS50ZXN0KGUpKX0pLm1hcChmdW5jdGlvbihlLHQpe3ZhciBuPVModGhpcykudmFsKCk7cmV0dXJuIG51bGw9PW4/bnVsbDpBcnJheS5pc0FycmF5KG4pP1MubWFwKG4sZnVuY3Rpb24oZSl7cmV0dXJue25hbWU6dC5uYW1lLHZhbHVlOmUucmVwbGFjZShFdCwiXHJcbiIpfX0pOntuYW1lOnQubmFtZSx2YWx1ZTpuLnJlcGxhY2UoRXQsIlxyXG4iKX19KS5nZXQoKX19KTt2YXIgTnQ9LyUyMC9nLGp0PS8jLiokLyxEdD0vKFs/Jl0pXz1bXiZdKi8scXQ9L14oLio/KTpbIFx0XSooW15cclxuXSopJC9nbSxMdD0vXig/OkdFVHxIRUFEKSQvLEh0PS9eXC9cLy8sT3Q9e30sUHQ9e30sUnQ9IiovIi5jb25jYXQoIioiKSxNdD1FLmNyZWF0ZUVsZW1lbnQoImEiKTtmdW5jdGlvbiBJdChvKXtyZXR1cm4gZnVuY3Rpb24oZSx0KXsic3RyaW5nIiE9dHlwZW9mIGUmJih0PWUsZT0iKiIpO3ZhciBuLHI9MCxpPWUudG9Mb3dlckNhc2UoKS5tYXRjaChQKXx8W107aWYobSh0KSl3aGlsZShuPWlbcisrXSkiKyI9PT1uWzBdPyhuPW4uc2xpY2UoMSl8fCIqIiwob1tuXT1vW25dfHxbXSkudW5zaGlmdCh0KSk6KG9bbl09b1tuXXx8W10pLnB1c2godCl9fWZ1bmN0aW9uIFd0KHQsaSxvLGEpe3ZhciBzPXt9LHU9dD09PVB0O2Z1bmN0aW9uIGwoZSl7dmFyIHI7cmV0dXJuIHNbZV09ITAsUy5lYWNoKHRbZV18fFtdLGZ1bmN0aW9uKGUsdCl7dmFyIG49dChpLG8sYSk7cmV0dXJuInN0cmluZyIhPXR5cGVvZiBufHx1fHxzW25dP3U/IShyPW4pOnZvaWQgMDooaS5kYXRhVHlwZXMudW5zaGlmdChuKSxsKG4pLCExKX0pLHJ9cmV0dXJuIGwoaS5kYXRhVHlwZXNbMF0pfHwhc1siKiJdJiZsKCIqIil9ZnVuY3Rpb24gRnQoZSx0KXt2YXIgbixyLGk9Uy5hamF4U2V0dGluZ3MuZmxhdE9wdGlvbnN8fHt9O2ZvcihuIGluIHQpdm9pZCAwIT09dFtuXSYmKChpW25dP2U6cnx8KHI9e30pKVtuXT10W25dKTtyZXR1cm4gciYmUy5leHRlbmQoITAsZSxyKSxlfU10LmhyZWY9YnQuaHJlZixTLmV4dGVuZCh7YWN0aXZlOjAsbGFzdE1vZGlmaWVkOnt9LGV0YWc6e30sYWpheFNldHRpbmdzOnt1cmw6YnQuaHJlZix0eXBlOiJHRVQiLGlzTG9jYWw6L14oPzphYm91dHxhcHB8YXBwLXN0b3JhZ2V8ListZXh0ZW5zaW9ufGZpbGV8cmVzfHdpZGdldCk6JC8udGVzdChidC5wcm90b2NvbCksZ2xvYmFsOiEwLHByb2Nlc3NEYXRhOiEwLGFzeW5jOiEwLGNvbnRlbnRUeXBlOiJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7IGNoYXJzZXQ9VVRGLTgiLGFjY2VwdHM6eyIqIjpSdCx0ZXh0OiJ0ZXh0L3BsYWluIixodG1sOiJ0ZXh0L2h0bWwiLHhtbDoiYXBwbGljYXRpb24veG1sLCB0ZXh0L3htbCIsanNvbjoiYXBwbGljYXRpb24vanNvbiwgdGV4dC9qYXZhc2NyaXB0In0sY29udGVudHM6e3htbDovXGJ4bWxcYi8saHRtbDovXGJodG1sLyxqc29uOi9cYmpzb25cYi99LHJlc3BvbnNlRmllbGRzOnt4bWw6InJlc3BvbnNlWE1MIix0ZXh0OiJyZXNwb25zZVRleHQiLGpzb246InJlc3BvbnNlSlNPTiJ9LGNvbnZlcnRlcnM6eyIqIHRleHQiOlN0cmluZywidGV4dCBodG1sIjohMCwidGV4dCBqc29uIjpKU09OLnBhcnNlLCJ0ZXh0IHhtbCI6Uy5wYXJzZVhNTH0sZmxhdE9wdGlvbnM6e3VybDohMCxjb250ZXh0OiEwfX0sYWpheFNldHVwOmZ1bmN0aW9uKGUsdCl7cmV0dXJuIHQ/RnQoRnQoZSxTLmFqYXhTZXR0aW5ncyksdCk6RnQoUy5hamF4U2V0dGluZ3MsZSl9LGFqYXhQcmVmaWx0ZXI6SXQoT3QpLGFqYXhUcmFuc3BvcnQ6SXQoUHQpLGFqYXg6ZnVuY3Rpb24oZSx0KXsib2JqZWN0Ij09dHlwZW9mIGUmJih0PWUsZT12b2lkIDApLHQ9dHx8e307dmFyIGMsZixwLG4sZCxyLGgsZyxpLG8sdj1TLmFqYXhTZXR1cCh7fSx0KSx5PXYuY29udGV4dHx8dixtPXYuY29udGV4dCYmKHkubm9kZVR5cGV8fHkuanF1ZXJ5KT9TKHkpOlMuZXZlbnQseD1TLkRlZmVycmVkKCksYj1TLkNhbGxiYWNrcygib25jZSBtZW1vcnkiKSx3PXYuc3RhdHVzQ29kZXx8e30sYT17fSxzPXt9LHU9ImNhbmNlbGVkIixUPXtyZWFkeVN0YXRlOjAsZ2V0UmVzcG9uc2VIZWFkZXI6ZnVuY3Rpb24oZSl7dmFyIHQ7aWYoaCl7aWYoIW4pe249e307d2hpbGUodD1xdC5leGVjKHApKW5bdFsxXS50b0xvd2VyQ2FzZSgpKyIgIl09KG5bdFsxXS50b0xvd2VyQ2FzZSgpKyIgIl18fFtdKS5jb25jYXQodFsyXSl9dD1uW2UudG9Mb3dlckNhc2UoKSsiICJdfXJldHVybiBudWxsPT10P251bGw6dC5qb2luKCIsICIpfSxnZXRBbGxSZXNwb25zZUhlYWRlcnM6ZnVuY3Rpb24oKXtyZXR1cm4gaD9wOm51bGx9LHNldFJlcXVlc3RIZWFkZXI6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gbnVsbD09aCYmKGU9c1tlLnRvTG93ZXJDYXNlKCldPXNbZS50b0xvd2VyQ2FzZSgpXXx8ZSxhW2VdPXQpLHRoaXN9LG92ZXJyaWRlTWltZVR5cGU6ZnVuY3Rpb24oZSl7cmV0dXJuIG51bGw9PWgmJih2Lm1pbWVUeXBlPWUpLHRoaXN9LHN0YXR1c0NvZGU6ZnVuY3Rpb24oZSl7dmFyIHQ7aWYoZSlpZihoKVQuYWx3YXlzKGVbVC5zdGF0dXNdKTtlbHNlIGZvcih0IGluIGUpd1t0XT1bd1t0XSxlW3RdXTtyZXR1cm4gdGhpc30sYWJvcnQ6ZnVuY3Rpb24oZSl7dmFyIHQ9ZXx8dTtyZXR1cm4gYyYmYy5hYm9ydCh0KSxsKDAsdCksdGhpc319O2lmKHgucHJvbWlzZShUKSx2LnVybD0oKGV8fHYudXJsfHxidC5ocmVmKSsiIikucmVwbGFjZShIdCxidC5wcm90b2NvbCsiLy8iKSx2LnR5cGU9dC5tZXRob2R8fHQudHlwZXx8di5tZXRob2R8fHYudHlwZSx2LmRhdGFUeXBlcz0odi5kYXRhVHlwZXx8IioiKS50b0xvd2VyQ2FzZSgpLm1hdGNoKFApfHxbIiJdLG51bGw9PXYuY3Jvc3NEb21haW4pe3I9RS5jcmVhdGVFbGVtZW50KCJhIik7dHJ5e3IuaHJlZj12LnVybCxyLmhyZWY9ci5ocmVmLHYuY3Jvc3NEb21haW49TXQucHJvdG9jb2wrIi8vIitNdC5ob3N0IT1yLnByb3RvY29sKyIvLyIrci5ob3N0fWNhdGNoKGUpe3YuY3Jvc3NEb21haW49ITB9fWlmKHYuZGF0YSYmdi5wcm9jZXNzRGF0YSYmInN0cmluZyIhPXR5cGVvZiB2LmRhdGEmJih2LmRhdGE9Uy5wYXJhbSh2LmRhdGEsdi50cmFkaXRpb25hbCkpLFd0KE90LHYsdCxUKSxoKXJldHVybiBUO2ZvcihpIGluKGc9Uy5ldmVudCYmdi5nbG9iYWwpJiYwPT1TLmFjdGl2ZSsrJiZTLmV2ZW50LnRyaWdnZXIoImFqYXhTdGFydCIpLHYudHlwZT12LnR5cGUudG9VcHBlckNhc2UoKSx2Lmhhc0NvbnRlbnQ9IUx0LnRlc3Qodi50eXBlKSxmPXYudXJsLnJlcGxhY2UoanQsIiIpLHYuaGFzQ29udGVudD92LmRhdGEmJnYucHJvY2Vzc0RhdGEmJjA9PT0odi5jb250ZW50VHlwZXx8IiIpLmluZGV4T2YoImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIpJiYodi5kYXRhPXYuZGF0YS5yZXBsYWNlKE50LCIrIikpOihvPXYudXJsLnNsaWNlKGYubGVuZ3RoKSx2LmRhdGEmJih2LnByb2Nlc3NEYXRhfHwic3RyaW5nIj09dHlwZW9mIHYuZGF0YSkmJihmKz0oVHQudGVzdChmKT8iJiI6Ij8iKSt2LmRhdGEsZGVsZXRlIHYuZGF0YSksITE9PT12LmNhY2hlJiYoZj1mLnJlcGxhY2UoRHQsIiQxIiksbz0oVHQudGVzdChmKT8iJiI6Ij8iKSsiXz0iK3d0Lmd1aWQrKytvKSx2LnVybD1mK28pLHYuaWZNb2RpZmllZCYmKFMubGFzdE1vZGlmaWVkW2ZdJiZULnNldFJlcXVlc3RIZWFkZXIoIklmLU1vZGlmaWVkLVNpbmNlIixTLmxhc3RNb2RpZmllZFtmXSksUy5ldGFnW2ZdJiZULnNldFJlcXVlc3RIZWFkZXIoIklmLU5vbmUtTWF0Y2giLFMuZXRhZ1tmXSkpLCh2LmRhdGEmJnYuaGFzQ29udGVudCYmITEhPT12LmNvbnRlbnRUeXBlfHx0LmNvbnRlbnRUeXBlKSYmVC5zZXRSZXF1ZXN0SGVhZGVyKCJDb250ZW50LVR5cGUiLHYuY29udGVudFR5cGUpLFQuc2V0UmVxdWVzdEhlYWRlcigiQWNjZXB0Iix2LmRhdGFUeXBlc1swXSYmdi5hY2NlcHRzW3YuZGF0YVR5cGVzWzBdXT92LmFjY2VwdHNbdi5kYXRhVHlwZXNbMF1dKygiKiIhPT12LmRhdGFUeXBlc1swXT8iLCAiK1J0KyI7IHE9MC4wMSI6IiIpOnYuYWNjZXB0c1siKiJdKSx2LmhlYWRlcnMpVC5zZXRSZXF1ZXN0SGVhZGVyKGksdi5oZWFkZXJzW2ldKTtpZih2LmJlZm9yZVNlbmQmJighMT09PXYuYmVmb3JlU2VuZC5jYWxsKHksVCx2KXx8aCkpcmV0dXJuIFQuYWJvcnQoKTtpZih1PSJhYm9ydCIsYi5hZGQodi5jb21wbGV0ZSksVC5kb25lKHYuc3VjY2VzcyksVC5mYWlsKHYuZXJyb3IpLGM9V3QoUHQsdix0LFQpKXtpZihULnJlYWR5U3RhdGU9MSxnJiZtLnRyaWdnZXIoImFqYXhTZW5kIixbVCx2XSksaClyZXR1cm4gVDt2LmFzeW5jJiYwPHYudGltZW91dCYmKGQ9Qy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7VC5hYm9ydCgidGltZW91dCIpfSx2LnRpbWVvdXQpKTt0cnl7aD0hMSxjLnNlbmQoYSxsKX1jYXRjaChlKXtpZihoKXRocm93IGU7bCgtMSxlKX19ZWxzZSBsKC0xLCJObyBUcmFuc3BvcnQiKTtmdW5jdGlvbiBsKGUsdCxuLHIpe3ZhciBpLG8sYSxzLHUsbD10O2h8fChoPSEwLGQmJkMuY2xlYXJUaW1lb3V0KGQpLGM9dm9pZCAwLHA9cnx8IiIsVC5yZWFkeVN0YXRlPTA8ZT80OjAsaT0yMDA8PWUmJmU8MzAwfHwzMDQ9PT1lLG4mJihzPWZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG8sYSxzPWUuY29udGVudHMsdT1lLmRhdGFUeXBlczt3aGlsZSgiKiI9PT11WzBdKXUuc2hpZnQoKSx2b2lkIDA9PT1yJiYocj1lLm1pbWVUeXBlfHx0LmdldFJlc3BvbnNlSGVhZGVyKCJDb250ZW50LVR5cGUiKSk7aWYocilmb3IoaSBpbiBzKWlmKHNbaV0mJnNbaV0udGVzdChyKSl7dS51bnNoaWZ0KGkpO2JyZWFrfWlmKHVbMF1pbiBuKW89dVswXTtlbHNle2ZvcihpIGluIG4pe2lmKCF1WzBdfHxlLmNvbnZlcnRlcnNbaSsiICIrdVswXV0pe289aTticmVha31hfHwoYT1pKX1vPW98fGF9aWYobylyZXR1cm4gbyE9PXVbMF0mJnUudW5zaGlmdChvKSxuW29dfSh2LFQsbikpLCFpJiYtMTxTLmluQXJyYXkoInNjcmlwdCIsdi5kYXRhVHlwZXMpJiZTLmluQXJyYXkoImpzb24iLHYuZGF0YVR5cGVzKTwwJiYodi5jb252ZXJ0ZXJzWyJ0ZXh0IHNjcmlwdCJdPWZ1bmN0aW9uKCl7fSkscz1mdW5jdGlvbihlLHQsbixyKXt2YXIgaSxvLGEscyx1LGw9e30sYz1lLmRhdGFUeXBlcy5zbGljZSgpO2lmKGNbMV0pZm9yKGEgaW4gZS5jb252ZXJ0ZXJzKWxbYS50b0xvd2VyQ2FzZSgpXT1lLmNvbnZlcnRlcnNbYV07bz1jLnNoaWZ0KCk7d2hpbGUobylpZihlLnJlc3BvbnNlRmllbGRzW29dJiYobltlLnJlc3BvbnNlRmllbGRzW29dXT10KSwhdSYmciYmZS5kYXRhRmlsdGVyJiYodD1lLmRhdGFGaWx0ZXIodCxlLmRhdGFUeXBlKSksdT1vLG89Yy5zaGlmdCgpKWlmKCIqIj09PW8pbz11O2Vsc2UgaWYoIioiIT09dSYmdSE9PW8pe2lmKCEoYT1sW3UrIiAiK29dfHxsWyIqICIrb10pKWZvcihpIGluIGwpaWYoKHM9aS5zcGxpdCgiICIpKVsxXT09PW8mJihhPWxbdSsiICIrc1swXV18fGxbIiogIitzWzBdXSkpeyEwPT09YT9hPWxbaV06ITAhPT1sW2ldJiYobz1zWzBdLGMudW5zaGlmdChzWzFdKSk7YnJlYWt9aWYoITAhPT1hKWlmKGEmJmVbInRocm93cyJdKXQ9YSh0KTtlbHNlIHRyeXt0PWEodCl9Y2F0Y2goZSl7cmV0dXJue3N0YXRlOiJwYXJzZXJlcnJvciIsZXJyb3I6YT9lOiJObyBjb252ZXJzaW9uIGZyb20gIit1KyIgdG8gIitvfX19cmV0dXJue3N0YXRlOiJzdWNjZXNzIixkYXRhOnR9fSh2LHMsVCxpKSxpPyh2LmlmTW9kaWZpZWQmJigodT1ULmdldFJlc3BvbnNlSGVhZGVyKCJMYXN0LU1vZGlmaWVkIikpJiYoUy5sYXN0TW9kaWZpZWRbZl09dSksKHU9VC5nZXRSZXNwb25zZUhlYWRlcigiZXRhZyIpKSYmKFMuZXRhZ1tmXT11KSksMjA0PT09ZXx8IkhFQUQiPT09di50eXBlP2w9Im5vY29udGVudCI6MzA0PT09ZT9sPSJub3Rtb2RpZmllZCI6KGw9cy5zdGF0ZSxvPXMuZGF0YSxpPSEoYT1zLmVycm9yKSkpOihhPWwsIWUmJmx8fChsPSJlcnJvciIsZTwwJiYoZT0wKSkpLFQuc3RhdHVzPWUsVC5zdGF0dXNUZXh0PSh0fHxsKSsiIixpP3gucmVzb2x2ZVdpdGgoeSxbbyxsLFRdKTp4LnJlamVjdFdpdGgoeSxbVCxsLGFdKSxULnN0YXR1c0NvZGUodyksdz12b2lkIDAsZyYmbS50cmlnZ2VyKGk/ImFqYXhTdWNjZXNzIjoiYWpheEVycm9yIixbVCx2LGk/bzphXSksYi5maXJlV2l0aCh5LFtULGxdKSxnJiYobS50cmlnZ2VyKCJhamF4Q29tcGxldGUiLFtULHZdKSwtLVMuYWN0aXZlfHxTLmV2ZW50LnRyaWdnZXIoImFqYXhTdG9wIikpKX1yZXR1cm4gVH0sZ2V0SlNPTjpmdW5jdGlvbihlLHQsbil7cmV0dXJuIFMuZ2V0KGUsdCxuLCJqc29uIil9LGdldFNjcmlwdDpmdW5jdGlvbihlLHQpe3JldHVybiBTLmdldChlLHZvaWQgMCx0LCJzY3JpcHQiKX19KSxTLmVhY2goWyJnZXQiLCJwb3N0Il0sZnVuY3Rpb24oZSxpKXtTW2ldPWZ1bmN0aW9uKGUsdCxuLHIpe3JldHVybiBtKHQpJiYocj1yfHxuLG49dCx0PXZvaWQgMCksUy5hamF4KFMuZXh0ZW5kKHt1cmw6ZSx0eXBlOmksZGF0YVR5cGU6cixkYXRhOnQsc3VjY2VzczpufSxTLmlzUGxhaW5PYmplY3QoZSkmJmUpKX19KSxTLmFqYXhQcmVmaWx0ZXIoZnVuY3Rpb24oZSl7dmFyIHQ7Zm9yKHQgaW4gZS5oZWFkZXJzKSJjb250ZW50LXR5cGUiPT09dC50b0xvd2VyQ2FzZSgpJiYoZS5jb250ZW50VHlwZT1lLmhlYWRlcnNbdF18fCIiKX0pLFMuX2V2YWxVcmw9ZnVuY3Rpb24oZSx0LG4pe3JldHVybiBTLmFqYXgoe3VybDplLHR5cGU6IkdFVCIsZGF0YVR5cGU6InNjcmlwdCIsY2FjaGU6ITAsYXN5bmM6ITEsZ2xvYmFsOiExLGNvbnZlcnRlcnM6eyJ0ZXh0IHNjcmlwdCI6ZnVuY3Rpb24oKXt9fSxkYXRhRmlsdGVyOmZ1bmN0aW9uKGUpe1MuZ2xvYmFsRXZhbChlLHQsbil9fSl9LFMuZm4uZXh0ZW5kKHt3cmFwQWxsOmZ1bmN0aW9uKGUpe3ZhciB0O3JldHVybiB0aGlzWzBdJiYobShlKSYmKGU9ZS5jYWxsKHRoaXNbMF0pKSx0PVMoZSx0aGlzWzBdLm93bmVyRG9jdW1lbnQpLmVxKDApLmNsb25lKCEwKSx0aGlzWzBdLnBhcmVudE5vZGUmJnQuaW5zZXJ0QmVmb3JlKHRoaXNbMF0pLHQubWFwKGZ1bmN0aW9uKCl7dmFyIGU9dGhpczt3aGlsZShlLmZpcnN0RWxlbWVudENoaWxkKWU9ZS5maXJzdEVsZW1lbnRDaGlsZDtyZXR1cm4gZX0pLmFwcGVuZCh0aGlzKSksdGhpc30sd3JhcElubmVyOmZ1bmN0aW9uKG4pe3JldHVybiBtKG4pP3RoaXMuZWFjaChmdW5jdGlvbihlKXtTKHRoaXMpLndyYXBJbm5lcihuLmNhbGwodGhpcyxlKSl9KTp0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgZT1TKHRoaXMpLHQ9ZS5jb250ZW50cygpO3QubGVuZ3RoP3Qud3JhcEFsbChuKTplLmFwcGVuZChuKX0pfSx3cmFwOmZ1bmN0aW9uKHQpe3ZhciBuPW0odCk7cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihlKXtTKHRoaXMpLndyYXBBbGwobj90LmNhbGwodGhpcyxlKTp0KX0pfSx1bndyYXA6ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMucGFyZW50KGUpLm5vdCgiYm9keSIpLmVhY2goZnVuY3Rpb24oKXtTKHRoaXMpLnJlcGxhY2VXaXRoKHRoaXMuY2hpbGROb2Rlcyl9KSx0aGlzfX0pLFMuZXhwci5wc2V1ZG9zLmhpZGRlbj1mdW5jdGlvbihlKXtyZXR1cm4hUy5leHByLnBzZXVkb3MudmlzaWJsZShlKX0sUy5leHByLnBzZXVkb3MudmlzaWJsZT1mdW5jdGlvbihlKXtyZXR1cm4hIShlLm9mZnNldFdpZHRofHxlLm9mZnNldEhlaWdodHx8ZS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCl9LFMuYWpheFNldHRpbmdzLnhocj1mdW5jdGlvbigpe3RyeXtyZXR1cm4gbmV3IEMuWE1MSHR0cFJlcXVlc3R9Y2F0Y2goZSl7fX07dmFyIEJ0PXswOjIwMCwxMjIzOjIwNH0sJHQ9Uy5hamF4U2V0dGluZ3MueGhyKCk7eS5jb3JzPSEhJHQmJiJ3aXRoQ3JlZGVudGlhbHMiaW4gJHQseS5hamF4PSR0PSEhJHQsUy5hamF4VHJhbnNwb3J0KGZ1bmN0aW9uKGkpe3ZhciBvLGE7aWYoeS5jb3JzfHwkdCYmIWkuY3Jvc3NEb21haW4pcmV0dXJue3NlbmQ6ZnVuY3Rpb24oZSx0KXt2YXIgbixyPWkueGhyKCk7aWYoci5vcGVuKGkudHlwZSxpLnVybCxpLmFzeW5jLGkudXNlcm5hbWUsaS5wYXNzd29yZCksaS54aHJGaWVsZHMpZm9yKG4gaW4gaS54aHJGaWVsZHMpcltuXT1pLnhockZpZWxkc1tuXTtmb3IobiBpbiBpLm1pbWVUeXBlJiZyLm92ZXJyaWRlTWltZVR5cGUmJnIub3ZlcnJpZGVNaW1lVHlwZShpLm1pbWVUeXBlKSxpLmNyb3NzRG9tYWlufHxlWyJYLVJlcXVlc3RlZC1XaXRoIl18fChlWyJYLVJlcXVlc3RlZC1XaXRoIl09IlhNTEh0dHBSZXF1ZXN0IiksZSlyLnNldFJlcXVlc3RIZWFkZXIobixlW25dKTtvPWZ1bmN0aW9uKGUpe3JldHVybiBmdW5jdGlvbigpe28mJihvPWE9ci5vbmxvYWQ9ci5vbmVycm9yPXIub25hYm9ydD1yLm9udGltZW91dD1yLm9ucmVhZHlzdGF0ZWNoYW5nZT1udWxsLCJhYm9ydCI9PT1lP3IuYWJvcnQoKToiZXJyb3IiPT09ZT8ibnVtYmVyIiE9dHlwZW9mIHIuc3RhdHVzP3QoMCwiZXJyb3IiKTp0KHIuc3RhdHVzLHIuc3RhdHVzVGV4dCk6dChCdFtyLnN0YXR1c118fHIuc3RhdHVzLHIuc3RhdHVzVGV4dCwidGV4dCIhPT0oci5yZXNwb25zZVR5cGV8fCJ0ZXh0Iil8fCJzdHJpbmciIT10eXBlb2Ygci5yZXNwb25zZVRleHQ/e2JpbmFyeTpyLnJlc3BvbnNlfTp7dGV4dDpyLnJlc3BvbnNlVGV4dH0sci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSkpfX0sci5vbmxvYWQ9bygpLGE9ci5vbmVycm9yPXIub250aW1lb3V0PW8oImVycm9yIiksdm9pZCAwIT09ci5vbmFib3J0P3Iub25hYm9ydD1hOnIub25yZWFkeXN0YXRlY2hhbmdlPWZ1bmN0aW9uKCl7ND09PXIucmVhZHlTdGF0ZSYmQy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7byYmYSgpfSl9LG89bygiYWJvcnQiKTt0cnl7ci5zZW5kKGkuaGFzQ29udGVudCYmaS5kYXRhfHxudWxsKX1jYXRjaChlKXtpZihvKXRocm93IGV9fSxhYm9ydDpmdW5jdGlvbigpe28mJm8oKX19fSksUy5hamF4UHJlZmlsdGVyKGZ1bmN0aW9uKGUpe2UuY3Jvc3NEb21haW4mJihlLmNvbnRlbnRzLnNjcmlwdD0hMSl9KSxTLmFqYXhTZXR1cCh7YWNjZXB0czp7c2NyaXB0OiJ0ZXh0L2phdmFzY3JpcHQsIGFwcGxpY2F0aW9uL2phdmFzY3JpcHQsIGFwcGxpY2F0aW9uL2VjbWFzY3JpcHQsIGFwcGxpY2F0aW9uL3gtZWNtYXNjcmlwdCJ9LGNvbnRlbnRzOntzY3JpcHQ6L1xiKD86amF2YXxlY21hKXNjcmlwdFxiL30sY29udmVydGVyczp7InRleHQgc2NyaXB0IjpmdW5jdGlvbihlKXtyZXR1cm4gUy5nbG9iYWxFdmFsKGUpLGV9fX0pLFMuYWpheFByZWZpbHRlcigic2NyaXB0IixmdW5jdGlvbihlKXt2b2lkIDA9PT1lLmNhY2hlJiYoZS5jYWNoZT0hMSksZS5jcm9zc0RvbWFpbiYmKGUudHlwZT0iR0VUIil9KSxTLmFqYXhUcmFuc3BvcnQoInNjcmlwdCIsZnVuY3Rpb24obil7dmFyIHIsaTtpZihuLmNyb3NzRG9tYWlufHxuLnNjcmlwdEF0dHJzKXJldHVybntzZW5kOmZ1bmN0aW9uKGUsdCl7cj1TKCI8c2NyaXB0PiIpLmF0dHIobi5zY3JpcHRBdHRyc3x8e30pLnByb3Aoe2NoYXJzZXQ6bi5zY3JpcHRDaGFyc2V0LHNyYzpuLnVybH0pLm9uKCJsb2FkIGVycm9yIixpPWZ1bmN0aW9uKGUpe3IucmVtb3ZlKCksaT1udWxsLGUmJnQoImVycm9yIj09PWUudHlwZT80MDQ6MjAwLGUudHlwZSl9KSxFLmhlYWQuYXBwZW5kQ2hpbGQoclswXSl9LGFib3J0OmZ1bmN0aW9uKCl7aSYmaSgpfX19KTt2YXIgX3QsenQ9W10sVXQ9Lyg9KVw/KD89JnwkKXxcP1w/LztTLmFqYXhTZXR1cCh7anNvbnA6ImNhbGxiYWNrIixqc29ucENhbGxiYWNrOmZ1bmN0aW9uKCl7dmFyIGU9enQucG9wKCl8fFMuZXhwYW5kbysiXyIrd3QuZ3VpZCsrO3JldHVybiB0aGlzW2VdPSEwLGV9fSksUy5hamF4UHJlZmlsdGVyKCJqc29uIGpzb25wIixmdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvLGE9ITEhPT1lLmpzb25wJiYoVXQudGVzdChlLnVybCk/InVybCI6InN0cmluZyI9PXR5cGVvZiBlLmRhdGEmJjA9PT0oZS5jb250ZW50VHlwZXx8IiIpLmluZGV4T2YoImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIpJiZVdC50ZXN0KGUuZGF0YSkmJiJkYXRhIik7aWYoYXx8Impzb25wIj09PWUuZGF0YVR5cGVzWzBdKXJldHVybiByPWUuanNvbnBDYWxsYmFjaz1tKGUuanNvbnBDYWxsYmFjayk/ZS5qc29ucENhbGxiYWNrKCk6ZS5qc29ucENhbGxiYWNrLGE/ZVthXT1lW2FdLnJlcGxhY2UoVXQsIiQxIityKTohMSE9PWUuanNvbnAmJihlLnVybCs9KFR0LnRlc3QoZS51cmwpPyImIjoiPyIpK2UuanNvbnArIj0iK3IpLGUuY29udmVydGVyc1sic2NyaXB0IGpzb24iXT1mdW5jdGlvbigpe3JldHVybiBvfHxTLmVycm9yKHIrIiB3YXMgbm90IGNhbGxlZCIpLG9bMF19LGUuZGF0YVR5cGVzWzBdPSJqc29uIixpPUNbcl0sQ1tyXT1mdW5jdGlvbigpe289YXJndW1lbnRzfSxuLmFsd2F5cyhmdW5jdGlvbigpe3ZvaWQgMD09PWk/UyhDKS5yZW1vdmVQcm9wKHIpOkNbcl09aSxlW3JdJiYoZS5qc29ucENhbGxiYWNrPXQuanNvbnBDYWxsYmFjayx6dC5wdXNoKHIpKSxvJiZtKGkpJiZpKG9bMF0pLG89aT12b2lkIDB9KSwic2NyaXB0In0pLHkuY3JlYXRlSFRNTERvY3VtZW50PSgoX3Q9RS5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoIiIpLmJvZHkpLmlubmVySFRNTD0iPGZvcm0+PC9mb3JtPjxmb3JtPjwvZm9ybT4iLDI9PT1fdC5jaGlsZE5vZGVzLmxlbmd0aCksUy5wYXJzZUhUTUw9ZnVuY3Rpb24oZSx0LG4pe3JldHVybiJzdHJpbmciIT10eXBlb2YgZT9bXTooImJvb2xlYW4iPT10eXBlb2YgdCYmKG49dCx0PSExKSx0fHwoeS5jcmVhdGVIVE1MRG9jdW1lbnQ/KChyPSh0PUUuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50KCIiKSkuY3JlYXRlRWxlbWVudCgiYmFzZSIpKS5ocmVmPUUubG9jYXRpb24uaHJlZix0LmhlYWQuYXBwZW5kQ2hpbGQocikpOnQ9RSksbz0hbiYmW10sKGk9Ti5leGVjKGUpKT9bdC5jcmVhdGVFbGVtZW50KGlbMV0pXTooaT14ZShbZV0sdCxvKSxvJiZvLmxlbmd0aCYmUyhvKS5yZW1vdmUoKSxTLm1lcmdlKFtdLGkuY2hpbGROb2RlcykpKTt2YXIgcixpLG99LFMuZm4ubG9hZD1mdW5jdGlvbihlLHQsbil7dmFyIHIsaSxvLGE9dGhpcyxzPWUuaW5kZXhPZigiICIpO3JldHVybi0xPHMmJihyPWh0KGUuc2xpY2UocykpLGU9ZS5zbGljZSgwLHMpKSxtKHQpPyhuPXQsdD12b2lkIDApOnQmJiJvYmplY3QiPT10eXBlb2YgdCYmKGk9IlBPU1QiKSwwPGEubGVuZ3RoJiZTLmFqYXgoe3VybDplLHR5cGU6aXx8IkdFVCIsZGF0YVR5cGU6Imh0bWwiLGRhdGE6dH0pLmRvbmUoZnVuY3Rpb24oZSl7bz1hcmd1bWVudHMsYS5odG1sKHI/UygiPGRpdj4iKS5hcHBlbmQoUy5wYXJzZUhUTUwoZSkpLmZpbmQocik6ZSl9KS5hbHdheXMobiYmZnVuY3Rpb24oZSx0KXthLmVhY2goZnVuY3Rpb24oKXtuLmFwcGx5KHRoaXMsb3x8W2UucmVzcG9uc2VUZXh0LHQsZV0pfSl9KSx0aGlzfSxTLmV4cHIucHNldWRvcy5hbmltYXRlZD1mdW5jdGlvbih0KXtyZXR1cm4gUy5ncmVwKFMudGltZXJzLGZ1bmN0aW9uKGUpe3JldHVybiB0PT09ZS5lbGVtfSkubGVuZ3RofSxTLm9mZnNldD17c2V0T2Zmc2V0OmZ1bmN0aW9uKGUsdCxuKXt2YXIgcixpLG8sYSxzLHUsbD1TLmNzcyhlLCJwb3NpdGlvbiIpLGM9UyhlKSxmPXt9OyJzdGF0aWMiPT09bCYmKGUuc3R5bGUucG9zaXRpb249InJlbGF0aXZlIikscz1jLm9mZnNldCgpLG89Uy5jc3MoZSwidG9wIiksdT1TLmNzcyhlLCJsZWZ0IiksKCJhYnNvbHV0ZSI9PT1sfHwiZml4ZWQiPT09bCkmJi0xPChvK3UpLmluZGV4T2YoImF1dG8iKT8oYT0ocj1jLnBvc2l0aW9uKCkpLnRvcCxpPXIubGVmdCk6KGE9cGFyc2VGbG9hdChvKXx8MCxpPXBhcnNlRmxvYXQodSl8fDApLG0odCkmJih0PXQuY2FsbChlLG4sUy5leHRlbmQoe30scykpKSxudWxsIT10LnRvcCYmKGYudG9wPXQudG9wLXMudG9wK2EpLG51bGwhPXQubGVmdCYmKGYubGVmdD10LmxlZnQtcy5sZWZ0K2kpLCJ1c2luZyJpbiB0P3QudXNpbmcuY2FsbChlLGYpOmMuY3NzKGYpfX0sUy5mbi5leHRlbmQoe29mZnNldDpmdW5jdGlvbih0KXtpZihhcmd1bWVudHMubGVuZ3RoKXJldHVybiB2b2lkIDA9PT10P3RoaXM6dGhpcy5lYWNoKGZ1bmN0aW9uKGUpe1Mub2Zmc2V0LnNldE9mZnNldCh0aGlzLHQsZSl9KTt2YXIgZSxuLHI9dGhpc1swXTtyZXR1cm4gcj9yLmdldENsaWVudFJlY3RzKCkubGVuZ3RoPyhlPXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksbj1yLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcse3RvcDplLnRvcCtuLnBhZ2VZT2Zmc2V0LGxlZnQ6ZS5sZWZ0K24ucGFnZVhPZmZzZXR9KTp7dG9wOjAsbGVmdDowfTp2b2lkIDB9LHBvc2l0aW9uOmZ1bmN0aW9uKCl7aWYodGhpc1swXSl7dmFyIGUsdCxuLHI9dGhpc1swXSxpPXt0b3A6MCxsZWZ0OjB9O2lmKCJmaXhlZCI9PT1TLmNzcyhyLCJwb3NpdGlvbiIpKXQ9ci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtlbHNle3Q9dGhpcy5vZmZzZXQoKSxuPXIub3duZXJEb2N1bWVudCxlPXIub2Zmc2V0UGFyZW50fHxuLmRvY3VtZW50RWxlbWVudDt3aGlsZShlJiYoZT09PW4uYm9keXx8ZT09PW4uZG9jdW1lbnRFbGVtZW50KSYmInN0YXRpYyI9PT1TLmNzcyhlLCJwb3NpdGlvbiIpKWU9ZS5wYXJlbnROb2RlO2UmJmUhPT1yJiYxPT09ZS5ub2RlVHlwZSYmKChpPVMoZSkub2Zmc2V0KCkpLnRvcCs9Uy5jc3MoZSwiYm9yZGVyVG9wV2lkdGgiLCEwKSxpLmxlZnQrPVMuY3NzKGUsImJvcmRlckxlZnRXaWR0aCIsITApKX1yZXR1cm57dG9wOnQudG9wLWkudG9wLVMuY3NzKHIsIm1hcmdpblRvcCIsITApLGxlZnQ6dC5sZWZ0LWkubGVmdC1TLmNzcyhyLCJtYXJnaW5MZWZ0IiwhMCl9fX0sb2Zmc2V0UGFyZW50OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5vZmZzZXRQYXJlbnQ7d2hpbGUoZSYmInN0YXRpYyI9PT1TLmNzcyhlLCJwb3NpdGlvbiIpKWU9ZS5vZmZzZXRQYXJlbnQ7cmV0dXJuIGV8fHJlfSl9fSksUy5lYWNoKHtzY3JvbGxMZWZ0OiJwYWdlWE9mZnNldCIsc2Nyb2xsVG9wOiJwYWdlWU9mZnNldCJ9LGZ1bmN0aW9uKHQsaSl7dmFyIG89InBhZ2VZT2Zmc2V0Ij09PWk7Uy5mblt0XT1mdW5jdGlvbihlKXtyZXR1cm4gJCh0aGlzLGZ1bmN0aW9uKGUsdCxuKXt2YXIgcjtpZih4KGUpP3I9ZTo5PT09ZS5ub2RlVHlwZSYmKHI9ZS5kZWZhdWx0Vmlldyksdm9pZCAwPT09bilyZXR1cm4gcj9yW2ldOmVbdF07cj9yLnNjcm9sbFRvKG8/ci5wYWdlWE9mZnNldDpuLG8/bjpyLnBhZ2VZT2Zmc2V0KTplW3RdPW59LHQsZSxhcmd1bWVudHMubGVuZ3RoKX19KSxTLmVhY2goWyJ0b3AiLCJsZWZ0Il0sZnVuY3Rpb24oZSxuKXtTLmNzc0hvb2tzW25dPUZlKHkucGl4ZWxQb3NpdGlvbixmdW5jdGlvbihlLHQpe2lmKHQpcmV0dXJuIHQ9V2UoZSxuKSxQZS50ZXN0KHQpP1MoZSkucG9zaXRpb24oKVtuXSsicHgiOnR9KX0pLFMuZWFjaCh7SGVpZ2h0OiJoZWlnaHQiLFdpZHRoOiJ3aWR0aCJ9LGZ1bmN0aW9uKGEscyl7Uy5lYWNoKHtwYWRkaW5nOiJpbm5lciIrYSxjb250ZW50OnMsIiI6Im91dGVyIithfSxmdW5jdGlvbihyLG8pe1MuZm5bb109ZnVuY3Rpb24oZSx0KXt2YXIgbj1hcmd1bWVudHMubGVuZ3RoJiYocnx8ImJvb2xlYW4iIT10eXBlb2YgZSksaT1yfHwoITA9PT1lfHwhMD09PXQ/Im1hcmdpbiI6ImJvcmRlciIpO3JldHVybiAkKHRoaXMsZnVuY3Rpb24oZSx0LG4pe3ZhciByO3JldHVybiB4KGUpPzA9PT1vLmluZGV4T2YoIm91dGVyIik/ZVsiaW5uZXIiK2FdOmUuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50WyJjbGllbnQiK2FdOjk9PT1lLm5vZGVUeXBlPyhyPWUuZG9jdW1lbnRFbGVtZW50LE1hdGgubWF4KGUuYm9keVsic2Nyb2xsIithXSxyWyJzY3JvbGwiK2FdLGUuYm9keVsib2Zmc2V0IithXSxyWyJvZmZzZXQiK2FdLHJbImNsaWVudCIrYV0pKTp2b2lkIDA9PT1uP1MuY3NzKGUsdCxpKTpTLnN0eWxlKGUsdCxuLGkpfSxzLG4/ZTp2b2lkIDAsbil9fSl9KSxTLmVhY2goWyJhamF4U3RhcnQiLCJhamF4U3RvcCIsImFqYXhDb21wbGV0ZSIsImFqYXhFcnJvciIsImFqYXhTdWNjZXNzIiwiYWpheFNlbmQiXSxmdW5jdGlvbihlLHQpe1MuZm5bdF09ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMub24odCxlKX19KSxTLmZuLmV4dGVuZCh7YmluZDpmdW5jdGlvbihlLHQsbil7cmV0dXJuIHRoaXMub24oZSxudWxsLHQsbil9LHVuYmluZDpmdW5jdGlvbihlLHQpe3JldHVybiB0aGlzLm9mZihlLG51bGwsdCl9LGRlbGVnYXRlOmZ1bmN0aW9uKGUsdCxuLHIpe3JldHVybiB0aGlzLm9uKHQsZSxuLHIpfSx1bmRlbGVnYXRlOmZ1bmN0aW9uKGUsdCxuKXtyZXR1cm4gMT09PWFyZ3VtZW50cy5sZW5ndGg/dGhpcy5vZmYoZSwiKioiKTp0aGlzLm9mZih0LGV8fCIqKiIsbil9LGhvdmVyOmZ1bmN0aW9uKGUsdCl7cmV0dXJuIHRoaXMubW91c2VlbnRlcihlKS5tb3VzZWxlYXZlKHR8fGUpfX0pLFMuZWFjaCgiYmx1ciBmb2N1cyBmb2N1c2luIGZvY3Vzb3V0IHJlc2l6ZSBzY3JvbGwgY2xpY2sgZGJsY2xpY2sgbW91c2Vkb3duIG1vdXNldXAgbW91c2Vtb3ZlIG1vdXNlb3ZlciBtb3VzZW91dCBtb3VzZWVudGVyIG1vdXNlbGVhdmUgY2hhbmdlIHNlbGVjdCBzdWJtaXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBjb250ZXh0bWVudSIuc3BsaXQoIiAiKSxmdW5jdGlvbihlLG4pe1MuZm5bbl09ZnVuY3Rpb24oZSx0KXtyZXR1cm4gMDxhcmd1bWVudHMubGVuZ3RoP3RoaXMub24obixudWxsLGUsdCk6dGhpcy50cmlnZ2VyKG4pfX0pO3ZhciBYdD0vXltcc1x1RkVGRlx4QTBdK3xbXHNcdUZFRkZceEEwXSskL2c7Uy5wcm94eT1mdW5jdGlvbihlLHQpe3ZhciBuLHIsaTtpZigic3RyaW5nIj09dHlwZW9mIHQmJihuPWVbdF0sdD1lLGU9biksbShlKSlyZXR1cm4gcj1zLmNhbGwoYXJndW1lbnRzLDIpLChpPWZ1bmN0aW9uKCl7cmV0dXJuIGUuYXBwbHkodHx8dGhpcyxyLmNvbmNhdChzLmNhbGwoYXJndW1lbnRzKSkpfSkuZ3VpZD1lLmd1aWQ9ZS5ndWlkfHxTLmd1aWQrKyxpfSxTLmhvbGRSZWFkeT1mdW5jdGlvbihlKXtlP1MucmVhZHlXYWl0Kys6Uy5yZWFkeSghMCl9LFMuaXNBcnJheT1BcnJheS5pc0FycmF5LFMucGFyc2VKU09OPUpTT04ucGFyc2UsUy5ub2RlTmFtZT1BLFMuaXNGdW5jdGlvbj1tLFMuaXNXaW5kb3c9eCxTLmNhbWVsQ2FzZT1YLFMudHlwZT13LFMubm93PURhdGUubm93LFMuaXNOdW1lcmljPWZ1bmN0aW9uKGUpe3ZhciB0PVMudHlwZShlKTtyZXR1cm4oIm51bWJlciI9PT10fHwic3RyaW5nIj09PXQpJiYhaXNOYU4oZS1wYXJzZUZsb2F0KGUpKX0sUy50cmltPWZ1bmN0aW9uKGUpe3JldHVybiBudWxsPT1lPyIiOihlKyIiKS5yZXBsYWNlKFh0LCIiKX0sImZ1bmN0aW9uIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZCYmZGVmaW5lKCJqcXVlcnkiLFtdLGZ1bmN0aW9uKCl7cmV0dXJuIFN9KTt2YXIgVnQ9Qy5qUXVlcnksR3Q9Qy4kO3JldHVybiBTLm5vQ29uZmxpY3Q9ZnVuY3Rpb24oZSl7cmV0dXJuIEMuJD09PVMmJihDLiQ9R3QpLGUmJkMualF1ZXJ5PT09UyYmKEMualF1ZXJ5PVZ0KSxTfSwidW5kZWZpbmVkIj09dHlwZW9mIGUmJihDLmpRdWVyeT1DLiQ9UyksU30pOwovKiEKICogalF1ZXJ5IFVJIFdpZGdldCAxLjEzLjIKICogaHR0cDovL2pxdWVyeXVpLmNvbQogKgogKiBDb3B5cmlnaHQgalF1ZXJ5IEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9ycwogKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuCiAqIGh0dHA6Ly9qcXVlcnkub3JnL2xpY2Vuc2UKICovCgovLz4+bGFiZWw6IFdpZGdldAovLz4+Z3JvdXA6IENvcmUKLy8+PmRlc2NyaXB0aW9uOiBQcm92aWRlcyBhIGZhY3RvcnkgZm9yIGNyZWF0aW5nIHN0YXRlZnVsIHdpZGdldHMgd2l0aCBhIGNvbW1vbiBBUEkuCi8vPj5kb2NzOiBodHRwOi8vYXBpLmpxdWVyeXVpLmNvbS9qUXVlcnkud2lkZ2V0LwovLz4+ZGVtb3M6IGh0dHA6Ly9qcXVlcnl1aS5jb20vd2lkZ2V0LwoKKCBmdW5jdGlvbiggZmFjdG9yeSApIHsKICAgIGlmICggdHlwZW9mIGRlZmluZSA9PT0gImZ1bmN0aW9uIiAmJiBkZWZpbmUuYW1kICkgewoKICAgICAgICAvLyBBTUQuIFJlZ2lzdGVyIGFzIGFuIGFub255bW91cyBtb2R1bGUuCiAgICAgICAgZGVmaW5lKCBbICJqcXVlcnkiIF0sIGZhY3RvcnkgKTsKICAgIH0gZWxzZSB7CgogICAgICAgIC8vIEJyb3dzZXIgZ2xvYmFscwogICAgICAgIGZhY3RvcnkoIGpRdWVyeSApOwogICAgfQp9KCBmdW5jdGlvbiggJCApIHsKICAgICJ1c2Ugc3RyaWN0IjsKCiAgICAkLnVpID0gJC51aSB8fCB7fTsKCiAgICB2YXIgdmVyc2lvbiA9ICQudWkudmVyc2lvbiA9ICIxLjEzLjIiOwoKICAgIHZhciB3aWRnZXRVdWlkID0gMDsKICAgIHZhciB3aWRnZXRIYXNPd25Qcm9wZXJ0eSA9IEFycmF5LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTsKICAgIHZhciB3aWRnZXRTbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTsKCiAgICAkLmNsZWFuRGF0YSA9ICggZnVuY3Rpb24oIG9yaWcgKSB7CiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCBlbGVtcyApIHsKICAgICAgICAgICAgdmFyIGV2ZW50cywgZWxlbSwgaTsKICAgICAgICAgICAgZm9yICggaSA9IDA7ICggZWxlbSA9IGVsZW1zWyBpIF0gKSAhPSBudWxsOyBpKysgKSB7CgogICAgICAgICAgICAgICAgLy8gT25seSB0cmlnZ2VyIHJlbW92ZSB3aGVuIG5lY2Vzc2FyeSB0byBzYXZlIHRpbWUKICAgICAgICAgICAgICAgIGV2ZW50cyA9ICQuX2RhdGEoIGVsZW0sICJldmVudHMiICk7CiAgICAgICAgICAgICAgICBpZiAoIGV2ZW50cyAmJiBldmVudHMucmVtb3ZlICkgewogICAgICAgICAgICAgICAgICAgICQoIGVsZW0gKS50cmlnZ2VySGFuZGxlciggInJlbW92ZSIgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBvcmlnKCBlbGVtcyApOwogICAgICAgIH07CiAgICB9ICkoICQuY2xlYW5EYXRhICk7CgogICAgJC53aWRnZXQgPSBmdW5jdGlvbiggbmFtZSwgYmFzZSwgcHJvdG90eXBlICkgewogICAgICAgIHZhciBleGlzdGluZ0NvbnN0cnVjdG9yLCBjb25zdHJ1Y3RvciwgYmFzZVByb3RvdHlwZTsKCiAgICAgICAgLy8gUHJveGllZFByb3RvdHlwZSBhbGxvd3MgdGhlIHByb3ZpZGVkIHByb3RvdHlwZSB0byByZW1haW4gdW5tb2RpZmllZAogICAgICAgIC8vIHNvIHRoYXQgaXQgY2FuIGJlIHVzZWQgYXMgYSBtaXhpbiBmb3IgbXVsdGlwbGUgd2lkZ2V0cyAoIzg4NzYpCiAgICAgICAgdmFyIHByb3hpZWRQcm90b3R5cGUgPSB7fTsKCiAgICAgICAgdmFyIG5hbWVzcGFjZSA9IG5hbWUuc3BsaXQoICIuIiApWyAwIF07CiAgICAgICAgbmFtZSA9IG5hbWUuc3BsaXQoICIuIiApWyAxIF07CiAgICAgICAgdmFyIGZ1bGxOYW1lID0gbmFtZXNwYWNlICsgIi0iICsgbmFtZTsKCiAgICAgICAgaWYgKCAhcHJvdG90eXBlICkgewogICAgICAgICAgICBwcm90b3R5cGUgPSBiYXNlOwogICAgICAgICAgICBiYXNlID0gJC5XaWRnZXQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoIEFycmF5LmlzQXJyYXkoIHByb3RvdHlwZSApICkgewogICAgICAgICAgICBwcm90b3R5cGUgPSAkLmV4dGVuZC5hcHBseSggbnVsbCwgWyB7fSBdLmNvbmNhdCggcHJvdG90eXBlICkgKTsKICAgICAgICB9CgogICAgICAgIC8vIENyZWF0ZSBzZWxlY3RvciBmb3IgcGx1Z2luCiAgICAgICAgJC5leHByLnBzZXVkb3NbIGZ1bGxOYW1lLnRvTG93ZXJDYXNlKCkgXSA9IGZ1bmN0aW9uKCBlbGVtICkgewogICAgICAgICAgICByZXR1cm4gISEkLmRhdGEoIGVsZW0sIGZ1bGxOYW1lICk7CiAgICAgICAgfTsKCiAgICAgICAgJFsgbmFtZXNwYWNlIF0gPSAkWyBuYW1lc3BhY2UgXSB8fCB7fTsKICAgICAgICBleGlzdGluZ0NvbnN0cnVjdG9yID0gJFsgbmFtZXNwYWNlIF1bIG5hbWUgXTsKICAgICAgICBjb25zdHJ1Y3RvciA9ICRbIG5hbWVzcGFjZSBdWyBuYW1lIF0gPSBmdW5jdGlvbiggb3B0aW9ucywgZWxlbWVudCApIHsKCiAgICAgICAgICAgIC8vIEFsbG93IGluc3RhbnRpYXRpb24gd2l0aG91dCAibmV3IiBrZXl3b3JkCiAgICAgICAgICAgIGlmICggIXRoaXMgfHwgIXRoaXMuX2NyZWF0ZVdpZGdldCApIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgY29uc3RydWN0b3IoIG9wdGlvbnMsIGVsZW1lbnQgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQWxsb3cgaW5zdGFudGlhdGlvbiB3aXRob3V0IGluaXRpYWxpemluZyBmb3Igc2ltcGxlIGluaGVyaXRhbmNlCiAgICAgICAgICAgIC8vIG11c3QgdXNlICJuZXciIGtleXdvcmQgKHRoZSBjb2RlIGFib3ZlIGFsd2F5cyBwYXNzZXMgYXJncykKICAgICAgICAgICAgaWYgKCBhcmd1bWVudHMubGVuZ3RoICkgewogICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlV2lkZ2V0KCBvcHRpb25zLCBlbGVtZW50ICk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICAvLyBFeHRlbmQgd2l0aCB0aGUgZXhpc3RpbmcgY29uc3RydWN0b3IgdG8gY2Fycnkgb3ZlciBhbnkgc3RhdGljIHByb3BlcnRpZXMKICAgICAgICAkLmV4dGVuZCggY29uc3RydWN0b3IsIGV4aXN0aW5nQ29uc3RydWN0b3IsIHsKICAgICAgICAgICAgdmVyc2lvbjogcHJvdG90eXBlLnZlcnNpb24sCgogICAgICAgICAgICAvLyBDb3B5IHRoZSBvYmplY3QgdXNlZCB0byBjcmVhdGUgdGhlIHByb3RvdHlwZSBpbiBjYXNlIHdlIG5lZWQgdG8KICAgICAgICAgICAgLy8gcmVkZWZpbmUgdGhlIHdpZGdldCBsYXRlcgogICAgICAgICAgICBfcHJvdG86ICQuZXh0ZW5kKCB7fSwgcHJvdG90eXBlICksCgogICAgICAgICAgICAvLyBUcmFjayB3aWRnZXRzIHRoYXQgaW5oZXJpdCBmcm9tIHRoaXMgd2lkZ2V0IGluIGNhc2UgdGhpcyB3aWRnZXQgaXMKICAgICAgICAgICAgLy8gcmVkZWZpbmVkIGFmdGVyIGEgd2lkZ2V0IGluaGVyaXRzIGZyb20gaXQKICAgICAgICAgICAgX2NoaWxkQ29uc3RydWN0b3JzOiBbXQogICAgICAgIH0gKTsKCiAgICAgICAgYmFzZVByb3RvdHlwZSA9IG5ldyBiYXNlKCk7CgogICAgICAgIC8vIFdlIG5lZWQgdG8gbWFrZSB0aGUgb3B0aW9ucyBoYXNoIGEgcHJvcGVydHkgZGlyZWN0bHkgb24gdGhlIG5ldyBpbnN0YW5jZQogICAgICAgIC8vIG90aGVyd2lzZSB3ZSdsbCBtb2RpZnkgdGhlIG9wdGlvbnMgaGFzaCBvbiB0aGUgcHJvdG90eXBlIHRoYXQgd2UncmUKICAgICAgICAvLyBpbmhlcml0aW5nIGZyb20KICAgICAgICBiYXNlUHJvdG90eXBlLm9wdGlvbnMgPSAkLndpZGdldC5leHRlbmQoIHt9LCBiYXNlUHJvdG90eXBlLm9wdGlvbnMgKTsKICAgICAgICAkLmVhY2goIHByb3RvdHlwZSwgZnVuY3Rpb24oIHByb3AsIHZhbHVlICkgewogICAgICAgICAgICBpZiAoIHR5cGVvZiB2YWx1ZSAhPT0gImZ1bmN0aW9uIiApIHsKICAgICAgICAgICAgICAgIHByb3hpZWRQcm90b3R5cGVbIHByb3AgXSA9IHZhbHVlOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHByb3hpZWRQcm90b3R5cGVbIHByb3AgXSA9ICggZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICBmdW5jdGlvbiBfc3VwZXIoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJhc2UucHJvdG90eXBlWyBwcm9wIF0uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZ1bmN0aW9uIF9zdXBlckFwcGx5KCBhcmdzICkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBiYXNlLnByb3RvdHlwZVsgcHJvcCBdLmFwcGx5KCB0aGlzLCBhcmdzICk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHZhciBfX3N1cGVyID0gdGhpcy5fc3VwZXI7CiAgICAgICAgICAgICAgICAgICAgdmFyIF9fc3VwZXJBcHBseSA9IHRoaXMuX3N1cGVyQXBwbHk7CiAgICAgICAgICAgICAgICAgICAgdmFyIHJldHVyblZhbHVlOwoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdXBlciA9IF9zdXBlcjsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdXBlckFwcGx5ID0gX3N1cGVyQXBwbHk7CgogICAgICAgICAgICAgICAgICAgIHJldHVyblZhbHVlID0gdmFsdWUuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApOwoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdXBlciA9IF9fc3VwZXI7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3VwZXJBcHBseSA9IF9fc3VwZXJBcHBseTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJldHVyblZhbHVlOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfSApKCk7CiAgICAgICAgfSApOwogICAgICAgIGNvbnN0cnVjdG9yLnByb3RvdHlwZSA9ICQud2lkZ2V0LmV4dGVuZCggYmFzZVByb3RvdHlwZSwgewoKICAgICAgICAgICAgLy8gVE9ETzogcmVtb3ZlIHN1cHBvcnQgZm9yIHdpZGdldEV2ZW50UHJlZml4CiAgICAgICAgICAgIC8vIGFsd2F5cyB1c2UgdGhlIG5hbWUgKyBhIGNvbG9uIGFzIHRoZSBwcmVmaXgsIGUuZy4sIGRyYWdnYWJsZTpzdGFydAogICAgICAgICAgICAvLyBkb24ndCBwcmVmaXggZm9yIHdpZGdldHMgdGhhdCBhcmVuJ3QgRE9NLWJhc2VkCiAgICAgICAgICAgIHdpZGdldEV2ZW50UHJlZml4OiBleGlzdGluZ0NvbnN0cnVjdG9yID8gKCBiYXNlUHJvdG90eXBlLndpZGdldEV2ZW50UHJlZml4IHx8IG5hbWUgKSA6IG5hbWUKICAgICAgICB9LCBwcm94aWVkUHJvdG90eXBlLCB7CiAgICAgICAgICAgIGNvbnN0cnVjdG9yOiBjb25zdHJ1Y3RvciwKICAgICAgICAgICAgbmFtZXNwYWNlOiBuYW1lc3BhY2UsCiAgICAgICAgICAgIHdpZGdldE5hbWU6IG5hbWUsCiAgICAgICAgICAgIHdpZGdldEZ1bGxOYW1lOiBmdWxsTmFtZQogICAgICAgIH0gKTsKCiAgICAgICAgLy8gSWYgdGhpcyB3aWRnZXQgaXMgYmVpbmcgcmVkZWZpbmVkIHRoZW4gd2UgbmVlZCB0byBmaW5kIGFsbCB3aWRnZXRzIHRoYXQKICAgICAgICAvLyBhcmUgaW5oZXJpdGluZyBmcm9tIGl0IGFuZCByZWRlZmluZSBhbGwgb2YgdGhlbSBzbyB0aGF0IHRoZXkgaW5oZXJpdCBmcm9tCiAgICAgICAgLy8gdGhlIG5ldyB2ZXJzaW9uIG9mIHRoaXMgd2lkZ2V0LiBXZSdyZSBlc3NlbnRpYWxseSB0cnlpbmcgdG8gcmVwbGFjZSBvbmUKICAgICAgICAvLyBsZXZlbCBpbiB0aGUgcHJvdG90eXBlIGNoYWluLgogICAgICAgIGlmICggZXhpc3RpbmdDb25zdHJ1Y3RvciApIHsKICAgICAgICAgICAgJC5lYWNoKCBleGlzdGluZ0NvbnN0cnVjdG9yLl9jaGlsZENvbnN0cnVjdG9ycywgZnVuY3Rpb24oIGksIGNoaWxkICkgewogICAgICAgICAgICAgICAgdmFyIGNoaWxkUHJvdG90eXBlID0gY2hpbGQucHJvdG90eXBlOwoKICAgICAgICAgICAgICAgIC8vIFJlZGVmaW5lIHRoZSBjaGlsZCB3aWRnZXQgdXNpbmcgdGhlIHNhbWUgcHJvdG90eXBlIHRoYXQgd2FzCiAgICAgICAgICAgICAgICAvLyBvcmlnaW5hbGx5IHVzZWQsIGJ1dCBpbmhlcml0IGZyb20gdGhlIG5ldyB2ZXJzaW9uIG9mIHRoZSBiYXNlCiAgICAgICAgICAgICAgICAkLndpZGdldCggY2hpbGRQcm90b3R5cGUubmFtZXNwYWNlICsgIi4iICsgY2hpbGRQcm90b3R5cGUud2lkZ2V0TmFtZSwgY29uc3RydWN0b3IsCiAgICAgICAgICAgICAgICAgICAgY2hpbGQuX3Byb3RvICk7CiAgICAgICAgICAgIH0gKTsKCiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgbGlzdCBvZiBleGlzdGluZyBjaGlsZCBjb25zdHJ1Y3RvcnMgZnJvbSB0aGUgb2xkIGNvbnN0cnVjdG9yCiAgICAgICAgICAgIC8vIHNvIHRoZSBvbGQgY2hpbGQgY29uc3RydWN0b3JzIGNhbiBiZSBnYXJiYWdlIGNvbGxlY3RlZAogICAgICAgICAgICBkZWxldGUgZXhpc3RpbmdDb25zdHJ1Y3Rvci5fY2hpbGRDb25zdHJ1Y3RvcnM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYmFzZS5fY2hpbGRDb25zdHJ1Y3RvcnMucHVzaCggY29uc3RydWN0b3IgKTsKICAgICAgICB9CgogICAgICAgICQud2lkZ2V0LmJyaWRnZSggbmFtZSwgY29uc3RydWN0b3IgKTsKCiAgICAgICAgcmV0dXJuIGNvbnN0cnVjdG9yOwogICAgfTsKCiAgICAkLndpZGdldC5leHRlbmQgPSBmdW5jdGlvbiggdGFyZ2V0ICkgewogICAgICAgIHZhciBpbnB1dCA9IHdpZGdldFNsaWNlLmNhbGwoIGFyZ3VtZW50cywgMSApOwogICAgICAgIHZhciBpbnB1dEluZGV4ID0gMDsKICAgICAgICB2YXIgaW5wdXRMZW5ndGggPSBpbnB1dC5sZW5ndGg7CiAgICAgICAgdmFyIGtleTsKICAgICAgICB2YXIgdmFsdWU7CgogICAgICAgIGZvciAoIDsgaW5wdXRJbmRleCA8IGlucHV0TGVuZ3RoOyBpbnB1dEluZGV4KysgKSB7CiAgICAgICAgICAgIGZvciAoIGtleSBpbiBpbnB1dFsgaW5wdXRJbmRleCBdICkgewogICAgICAgICAgICAgICAgdmFsdWUgPSBpbnB1dFsgaW5wdXRJbmRleCBdWyBrZXkgXTsKICAgICAgICAgICAgICAgIGlmICggd2lkZ2V0SGFzT3duUHJvcGVydHkuY2FsbCggaW5wdXRbIGlucHV0SW5kZXggXSwga2V5ICkgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCApIHsKCiAgICAgICAgICAgICAgICAgICAgLy8gQ2xvbmUgb2JqZWN0cwogICAgICAgICAgICAgICAgICAgIGlmICggJC5pc1BsYWluT2JqZWN0KCB2YWx1ZSApICkgewogICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRbIGtleSBdID0gJC5pc1BsYWluT2JqZWN0KCB0YXJnZXRbIGtleSBdICkgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJC53aWRnZXQuZXh0ZW5kKCB7fSwgdGFyZ2V0WyBrZXkgXSwgdmFsdWUgKSA6CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG9uJ3QgZXh0ZW5kIHN0cmluZ3MsIGFycmF5cywgZXRjLiB3aXRoIG9iamVjdHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQud2lkZ2V0LmV4dGVuZCgge30sIHZhbHVlICk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBDb3B5IGV2ZXJ5dGhpbmcgZWxzZSBieSByZWZlcmVuY2UKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRbIGtleSBdID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0YXJnZXQ7CiAgICB9OwoKICAgICQud2lkZ2V0LmJyaWRnZSA9IGZ1bmN0aW9uKCBuYW1lLCBvYmplY3QgKSB7CiAgICAgICAgdmFyIGZ1bGxOYW1lID0gb2JqZWN0LnByb3RvdHlwZS53aWRnZXRGdWxsTmFtZSB8fCBuYW1lOwogICAgICAgICQuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBvcHRpb25zICkgewogICAgICAgICAgICB2YXIgaXNNZXRob2RDYWxsID0gdHlwZW9mIG9wdGlvbnMgPT09ICJzdHJpbmciOwogICAgICAgICAgICB2YXIgYXJncyA9IHdpZGdldFNsaWNlLmNhbGwoIGFyZ3VtZW50cywgMSApOwogICAgICAgICAgICB2YXIgcmV0dXJuVmFsdWUgPSB0aGlzOwoKICAgICAgICAgICAgaWYgKCBpc01ldGhvZENhbGwgKSB7CgogICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhbiBlbXB0eSBjb2xsZWN0aW9uLCB3ZSBuZWVkIHRvIGhhdmUgdGhlIGluc3RhbmNlIG1ldGhvZAogICAgICAgICAgICAgICAgLy8gcmV0dXJuIHVuZGVmaW5lZCBpbnN0ZWFkIG9mIHRoZSBqUXVlcnkgaW5zdGFuY2UKICAgICAgICAgICAgICAgIGlmICggIXRoaXMubGVuZ3RoICYmIG9wdGlvbnMgPT09ICJpbnN0YW5jZSIgKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtZXRob2RWYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gJC5kYXRhKCB0aGlzLCBmdWxsTmFtZSApOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBvcHRpb25zID09PSAiaW5zdGFuY2UiICkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSBpbnN0YW5jZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAhaW5zdGFuY2UgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJC5lcnJvciggImNhbm5vdCBjYWxsIG1ldGhvZHMgb24gIiArIG5hbWUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgcHJpb3IgdG8gaW5pdGlhbGl6YXRpb247ICIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhdHRlbXB0ZWQgdG8gY2FsbCBtZXRob2QgJyIgKyBvcHRpb25zICsgIiciICk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggdHlwZW9mIGluc3RhbmNlWyBvcHRpb25zIF0gIT09ICJmdW5jdGlvbiIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuY2hhckF0KCAwICkgPT09ICJfIiApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkLmVycm9yKCAibm8gc3VjaCBtZXRob2QgJyIgKyBvcHRpb25zICsgIicgZm9yICIgKyBuYW1lICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIHdpZGdldCBpbnN0YW5jZSIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kVmFsdWUgPSBpbnN0YW5jZVsgb3B0aW9ucyBdLmFwcGx5KCBpbnN0YW5jZSwgYXJncyApOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBtZXRob2RWYWx1ZSAhPT0gaW5zdGFuY2UgJiYgbWV0aG9kVmFsdWUgIT09IHVuZGVmaW5lZCApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVyblZhbHVlID0gbWV0aG9kVmFsdWUgJiYgbWV0aG9kVmFsdWUuanF1ZXJ5ID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5WYWx1ZS5wdXNoU3RhY2soIG1ldGhvZFZhbHVlLmdldCgpICkgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZFZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgICAgIC8vIEFsbG93IG11bHRpcGxlIGhhc2hlcyB0byBiZSBwYXNzZWQgb24gaW5pdAogICAgICAgICAgICAgICAgaWYgKCBhcmdzLmxlbmd0aCApIHsKICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0gJC53aWRnZXQuZXh0ZW5kLmFwcGx5KCBudWxsLCBbIG9wdGlvbnMgXS5jb25jYXQoIGFyZ3MgKSApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gJC5kYXRhKCB0aGlzLCBmdWxsTmFtZSApOwogICAgICAgICAgICAgICAgICAgIGlmICggaW5zdGFuY2UgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLm9wdGlvbiggb3B0aW9ucyB8fCB7fSApOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGluc3RhbmNlLl9pbml0ICkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UuX2luaXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICQuZGF0YSggdGhpcywgZnVsbE5hbWUsIG5ldyBvYmplY3QoIG9wdGlvbnMsIHRoaXMgKSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHJldHVyblZhbHVlOwogICAgICAgIH07CiAgICB9OwoKICAgICQuV2lkZ2V0ID0gZnVuY3Rpb24oIC8qIG9wdGlvbnMsIGVsZW1lbnQgKi8gKSB7fTsKICAgICQuV2lkZ2V0Ll9jaGlsZENvbnN0cnVjdG9ycyA9IFtdOwoKICAgICQuV2lkZ2V0LnByb3RvdHlwZSA9IHsKICAgICAgICB3aWRnZXROYW1lOiAid2lkZ2V0IiwKICAgICAgICB3aWRnZXRFdmVudFByZWZpeDogIiIsCiAgICAgICAgZGVmYXVsdEVsZW1lbnQ6ICI8ZGl2PiIsCgogICAgICAgIG9wdGlvbnM6IHsKICAgICAgICAgICAgY2xhc3Nlczoge30sCiAgICAgICAgICAgIGRpc2FibGVkOiBmYWxzZSwKCiAgICAgICAgICAgIC8vIENhbGxiYWNrcwogICAgICAgICAgICBjcmVhdGU6IG51bGwKICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlV2lkZ2V0OiBmdW5jdGlvbiggb3B0aW9ucywgZWxlbWVudCApIHsKICAgICAgICAgICAgZWxlbWVudCA9ICQoIGVsZW1lbnQgfHwgdGhpcy5kZWZhdWx0RWxlbWVudCB8fCB0aGlzIClbIDAgXTsKICAgICAgICAgICAgdGhpcy5lbGVtZW50ID0gJCggZWxlbWVudCApOwogICAgICAgICAgICB0aGlzLnV1aWQgPSB3aWRnZXRVdWlkKys7CiAgICAgICAgICAgIHRoaXMuZXZlbnROYW1lc3BhY2UgPSAiLiIgKyB0aGlzLndpZGdldE5hbWUgKyB0aGlzLnV1aWQ7CgogICAgICAgICAgICB0aGlzLmJpbmRpbmdzID0gJCgpOwogICAgICAgICAgICB0aGlzLmhvdmVyYWJsZSA9ICQoKTsKICAgICAgICAgICAgdGhpcy5mb2N1c2FibGUgPSAkKCk7CiAgICAgICAgICAgIHRoaXMuY2xhc3Nlc0VsZW1lbnRMb29rdXAgPSB7fTsKCiAgICAgICAgICAgIGlmICggZWxlbWVudCAhPT0gdGhpcyApIHsKICAgICAgICAgICAgICAgICQuZGF0YSggZWxlbWVudCwgdGhpcy53aWRnZXRGdWxsTmFtZSwgdGhpcyApOwogICAgICAgICAgICAgICAgdGhpcy5fb24oIHRydWUsIHRoaXMuZWxlbWVudCwgewogICAgICAgICAgICAgICAgICAgIHJlbW92ZTogZnVuY3Rpb24oIGV2ZW50ICkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGV2ZW50LnRhcmdldCA9PT0gZWxlbWVudCApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGVzdHJveSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSApOwogICAgICAgICAgICAgICAgdGhpcy5kb2N1bWVudCA9ICQoIGVsZW1lbnQuc3R5bGUgPwoKICAgICAgICAgICAgICAgICAgICAvLyBFbGVtZW50IHdpdGhpbiB0aGUgZG9jdW1lbnQKICAgICAgICAgICAgICAgICAgICBlbGVtZW50Lm93bmVyRG9jdW1lbnQgOgoKICAgICAgICAgICAgICAgICAgICAvLyBFbGVtZW50IGlzIHdpbmRvdyBvciBkb2N1bWVudAogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuZG9jdW1lbnQgfHwgZWxlbWVudCApOwogICAgICAgICAgICAgICAgdGhpcy53aW5kb3cgPSAkKCB0aGlzLmRvY3VtZW50WyAwIF0uZGVmYXVsdFZpZXcgfHwgdGhpcy5kb2N1bWVudFsgMCBdLnBhcmVudFdpbmRvdyApOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLm9wdGlvbnMgPSAkLndpZGdldC5leHRlbmQoIHt9LAogICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLAogICAgICAgICAgICAgICAgdGhpcy5fZ2V0Q3JlYXRlT3B0aW9ucygpLAogICAgICAgICAgICAgICAgb3B0aW9ucyApOwoKICAgICAgICAgICAgdGhpcy5fY3JlYXRlKCk7CgogICAgICAgICAgICBpZiAoIHRoaXMub3B0aW9ucy5kaXNhYmxlZCApIHsKICAgICAgICAgICAgICAgIHRoaXMuX3NldE9wdGlvbkRpc2FibGVkKCB0aGlzLm9wdGlvbnMuZGlzYWJsZWQgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fdHJpZ2dlciggImNyZWF0ZSIsIG51bGwsIHRoaXMuX2dldENyZWF0ZUV2ZW50RGF0YSgpICk7CiAgICAgICAgICAgIHRoaXMuX2luaXQoKTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0Q3JlYXRlT3B0aW9uczogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB7fTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0Q3JlYXRlRXZlbnREYXRhOiAkLm5vb3AsCgogICAgICAgIF9jcmVhdGU6ICQubm9vcCwKCiAgICAgICAgX2luaXQ6ICQubm9vcCwKCiAgICAgICAgZGVzdHJveTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKCiAgICAgICAgICAgIHRoaXMuX2Rlc3Ryb3koKTsKICAgICAgICAgICAgJC5lYWNoKCB0aGlzLmNsYXNzZXNFbGVtZW50TG9va3VwLCBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHsKICAgICAgICAgICAgICAgIHRoYXQuX3JlbW92ZUNsYXNzKCB2YWx1ZSwga2V5ICk7CiAgICAgICAgICAgIH0gKTsKCiAgICAgICAgICAgIC8vIFdlIGNhbiBwcm9iYWJseSByZW1vdmUgdGhlIHVuYmluZCBjYWxscyBpbiAyLjAKICAgICAgICAgICAgLy8gYWxsIGV2ZW50IGJpbmRpbmdzIHNob3VsZCBnbyB0aHJvdWdoIHRoaXMuX29uKCkKICAgICAgICAgICAgdGhpcy5lbGVtZW50CiAgICAgICAgICAgICAgICAub2ZmKCB0aGlzLmV2ZW50TmFtZXNwYWNlICkKICAgICAgICAgICAgICAgIC5yZW1vdmVEYXRhKCB0aGlzLndpZGdldEZ1bGxOYW1lICk7CiAgICAgICAgICAgIHRoaXMud2lkZ2V0KCkKICAgICAgICAgICAgICAgIC5vZmYoIHRoaXMuZXZlbnROYW1lc3BhY2UgKQogICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoICJhcmlhLWRpc2FibGVkIiApOwoKICAgICAgICAgICAgLy8gQ2xlYW4gdXAgZXZlbnRzIGFuZCBzdGF0ZXMKICAgICAgICAgICAgdGhpcy5iaW5kaW5ncy5vZmYoIHRoaXMuZXZlbnROYW1lc3BhY2UgKTsKICAgICAgICB9LAoKICAgICAgICBfZGVzdHJveTogJC5ub29wLAoKICAgICAgICB3aWRnZXQ6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50OwogICAgICAgIH0sCgogICAgICAgIG9wdGlvbjogZnVuY3Rpb24oIGtleSwgdmFsdWUgKSB7CiAgICAgICAgICAgIHZhciBvcHRpb25zID0ga2V5OwogICAgICAgICAgICB2YXIgcGFydHM7CiAgICAgICAgICAgIHZhciBjdXJPcHRpb247CiAgICAgICAgICAgIHZhciBpOwoKICAgICAgICAgICAgaWYgKCBhcmd1bWVudHMubGVuZ3RoID09PSAwICkgewoKICAgICAgICAgICAgICAgIC8vIERvbid0IHJldHVybiBhIHJlZmVyZW5jZSB0byB0aGUgaW50ZXJuYWwgaGFzaAogICAgICAgICAgICAgICAgcmV0dXJuICQud2lkZ2V0LmV4dGVuZCgge30sIHRoaXMub3B0aW9ucyApOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIHR5cGVvZiBrZXkgPT09ICJzdHJpbmciICkgewoKICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBuZXN0ZWQga2V5cywgZS5nLiwgImZvby5iYXIiID0+IHsgZm9vOiB7IGJhcjogX19fIH0gfQogICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9OwogICAgICAgICAgICAgICAgcGFydHMgPSBrZXkuc3BsaXQoICIuIiApOwogICAgICAgICAgICAgICAga2V5ID0gcGFydHMuc2hpZnQoKTsKICAgICAgICAgICAgICAgIGlmICggcGFydHMubGVuZ3RoICkgewogICAgICAgICAgICAgICAgICAgIGN1ck9wdGlvbiA9IG9wdGlvbnNbIGtleSBdID0gJC53aWRnZXQuZXh0ZW5kKCB7fSwgdGhpcy5vcHRpb25zWyBrZXkgXSApOwogICAgICAgICAgICAgICAgICAgIGZvciAoIGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoIC0gMTsgaSsrICkgewogICAgICAgICAgICAgICAgICAgICAgICBjdXJPcHRpb25bIHBhcnRzWyBpIF0gXSA9IGN1ck9wdGlvblsgcGFydHNbIGkgXSBdIHx8IHt9OwogICAgICAgICAgICAgICAgICAgICAgICBjdXJPcHRpb24gPSBjdXJPcHRpb25bIHBhcnRzWyBpIF0gXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAga2V5ID0gcGFydHMucG9wKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCBhcmd1bWVudHMubGVuZ3RoID09PSAxICkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VyT3B0aW9uWyBrZXkgXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGN1ck9wdGlvblsga2V5IF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGN1ck9wdGlvblsga2V5IF0gPSB2YWx1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCBhcmd1bWVudHMubGVuZ3RoID09PSAxICkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zWyBrZXkgXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IHRoaXMub3B0aW9uc1sga2V5IF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG9wdGlvbnNbIGtleSBdID0gdmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX3NldE9wdGlvbnMoIG9wdGlvbnMgKTsKCiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCgogICAgICAgIF9zZXRPcHRpb25zOiBmdW5jdGlvbiggb3B0aW9ucyApIHsKICAgICAgICAgICAgdmFyIGtleTsKCiAgICAgICAgICAgIGZvciAoIGtleSBpbiBvcHRpb25zICkgewogICAgICAgICAgICAgICAgdGhpcy5fc2V0T3B0aW9uKCBrZXksIG9wdGlvbnNbIGtleSBdICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCgogICAgICAgIF9zZXRPcHRpb246IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkgewogICAgICAgICAgICBpZiAoIGtleSA9PT0gImNsYXNzZXMiICkgewogICAgICAgICAgICAgICAgdGhpcy5fc2V0T3B0aW9uQ2xhc3NlcyggdmFsdWUgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5vcHRpb25zWyBrZXkgXSA9IHZhbHVlOwoKICAgICAgICAgICAgaWYgKCBrZXkgPT09ICJkaXNhYmxlZCIgKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9zZXRPcHRpb25EaXNhYmxlZCggdmFsdWUgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgX3NldE9wdGlvbkNsYXNzZXM6IGZ1bmN0aW9uKCB2YWx1ZSApIHsKICAgICAgICAgICAgdmFyIGNsYXNzS2V5LCBlbGVtZW50cywgY3VycmVudEVsZW1lbnRzOwoKICAgICAgICAgICAgZm9yICggY2xhc3NLZXkgaW4gdmFsdWUgKSB7CiAgICAgICAgICAgICAgICBjdXJyZW50RWxlbWVudHMgPSB0aGlzLmNsYXNzZXNFbGVtZW50TG9va3VwWyBjbGFzc0tleSBdOwogICAgICAgICAgICAgICAgaWYgKCB2YWx1ZVsgY2xhc3NLZXkgXSA9PT0gdGhpcy5vcHRpb25zLmNsYXNzZXNbIGNsYXNzS2V5IF0gfHwKICAgICAgICAgICAgICAgICAgICAhY3VycmVudEVsZW1lbnRzIHx8CiAgICAgICAgICAgICAgICAgICAgIWN1cnJlbnRFbGVtZW50cy5sZW5ndGggKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gV2UgYXJlIGRvaW5nIHRoaXMgdG8gY3JlYXRlIGEgbmV3IGpRdWVyeSBvYmplY3QgYmVjYXVzZSB0aGUgX3JlbW92ZUNsYXNzKCkgY2FsbAogICAgICAgICAgICAgICAgLy8gb24gdGhlIG5leHQgbGluZSBpcyBnb2luZyB0byBkZXN0cm95IHRoZSByZWZlcmVuY2UgdG8gdGhlIGN1cnJlbnQgZWxlbWVudHMgYmVpbmcKICAgICAgICAgICAgICAgIC8vIHRyYWNrZWQuIFdlIG5lZWQgdG8gc2F2ZSBhIGNvcHkgb2YgdGhpcyBjb2xsZWN0aW9uIHNvIHRoYXQgd2UgY2FuIGFkZCB0aGUgbmV3IGNsYXNzZXMKICAgICAgICAgICAgICAgIC8vIGJlbG93LgogICAgICAgICAgICAgICAgZWxlbWVudHMgPSAkKCBjdXJyZW50RWxlbWVudHMuZ2V0KCkgKTsKICAgICAgICAgICAgICAgIHRoaXMuX3JlbW92ZUNsYXNzKCBjdXJyZW50RWxlbWVudHMsIGNsYXNzS2V5ICk7CgogICAgICAgICAgICAgICAgLy8gV2UgZG9uJ3QgdXNlIF9hZGRDbGFzcygpIGhlcmUsIGJlY2F1c2UgdGhhdCB1c2VzIHRoaXMub3B0aW9ucy5jbGFzc2VzCiAgICAgICAgICAgICAgICAvLyBmb3IgZ2VuZXJhdGluZyB0aGUgc3RyaW5nIG9mIGNsYXNzZXMuIFdlIHdhbnQgdG8gdXNlIHRoZSB2YWx1ZSBwYXNzZWQgaW4gZnJvbQogICAgICAgICAgICAgICAgLy8gX3NldE9wdGlvbigpLCB0aGlzIGlzIHRoZSBuZXcgdmFsdWUgb2YgdGhlIGNsYXNzZXMgb3B0aW9uIHdoaWNoIHdhcyBwYXNzZWQgdG8KICAgICAgICAgICAgICAgIC8vIF9zZXRPcHRpb24oKS4gV2UgcGFzcyB0aGlzIHZhbHVlIGRpcmVjdGx5IHRvIF9jbGFzc2VzKCkuCiAgICAgICAgICAgICAgICBlbGVtZW50cy5hZGRDbGFzcyggdGhpcy5fY2xhc3NlcyggewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQ6IGVsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgIGtleXM6IGNsYXNzS2V5LAogICAgICAgICAgICAgICAgICAgIGNsYXNzZXM6IHZhbHVlLAogICAgICAgICAgICAgICAgICAgIGFkZDogdHJ1ZQogICAgICAgICAgICAgICAgfSApICk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfc2V0T3B0aW9uRGlzYWJsZWQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHsKICAgICAgICAgICAgdGhpcy5fdG9nZ2xlQ2xhc3MoIHRoaXMud2lkZ2V0KCksIHRoaXMud2lkZ2V0RnVsbE5hbWUgKyAiLWRpc2FibGVkIiwgbnVsbCwgISF2YWx1ZSApOwoKICAgICAgICAgICAgLy8gSWYgdGhlIHdpZGdldCBpcyBiZWNvbWluZyBkaXNhYmxlZCwgdGhlbiBub3RoaW5nIGlzIGludGVyYWN0aXZlCiAgICAgICAgICAgIGlmICggdmFsdWUgKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVDbGFzcyggdGhpcy5ob3ZlcmFibGUsIG51bGwsICJ1aS1zdGF0ZS1ob3ZlciIgKTsKICAgICAgICAgICAgICAgIHRoaXMuX3JlbW92ZUNsYXNzKCB0aGlzLmZvY3VzYWJsZSwgbnVsbCwgInVpLXN0YXRlLWZvY3VzIiApOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgZW5hYmxlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NldE9wdGlvbnMoIHsgZGlzYWJsZWQ6IGZhbHNlIH0gKTsKICAgICAgICB9LAoKICAgICAgICBkaXNhYmxlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NldE9wdGlvbnMoIHsgZGlzYWJsZWQ6IHRydWUgfSApOwogICAgICAgIH0sCgogICAgICAgIF9jbGFzc2VzOiBmdW5jdGlvbiggb3B0aW9ucyApIHsKICAgICAgICAgICAgdmFyIGZ1bGwgPSBbXTsKICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwoKICAgICAgICAgICAgb3B0aW9ucyA9ICQuZXh0ZW5kKCB7CiAgICAgICAgICAgICAgICBlbGVtZW50OiB0aGlzLmVsZW1lbnQsCiAgICAgICAgICAgICAgICBjbGFzc2VzOiB0aGlzLm9wdGlvbnMuY2xhc3NlcyB8fCB7fQogICAgICAgICAgICB9LCBvcHRpb25zICk7CgogICAgICAgICAgICBmdW5jdGlvbiBiaW5kUmVtb3ZlRXZlbnQoKSB7CiAgICAgICAgICAgICAgICB2YXIgbm9kZXNUb0JpbmQgPSBbXTsKCiAgICAgICAgICAgICAgICBvcHRpb25zLmVsZW1lbnQuZWFjaCggZnVuY3Rpb24oIF8sIGVsZW1lbnQgKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGlzVHJhY2tlZCA9ICQubWFwKCB0aGF0LmNsYXNzZXNFbGVtZW50TG9va3VwLCBmdW5jdGlvbiggZWxlbWVudHMgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50czsKICAgICAgICAgICAgICAgICAgICB9ICkKICAgICAgICAgICAgICAgICAgICAgICAgLnNvbWUoIGZ1bmN0aW9uKCBlbGVtZW50cyApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50cy5pcyggZWxlbWVudCApOwogICAgICAgICAgICAgICAgICAgICAgICB9ICk7CgogICAgICAgICAgICAgICAgICAgIGlmICggIWlzVHJhY2tlZCApIHsKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZXNUb0JpbmQucHVzaCggZWxlbWVudCApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gKTsKCiAgICAgICAgICAgICAgICB0aGF0Ll9vbiggJCggbm9kZXNUb0JpbmQgKSwgewogICAgICAgICAgICAgICAgICAgIHJlbW92ZTogIl91bnRyYWNrQ2xhc3Nlc0VsZW1lbnQiCiAgICAgICAgICAgICAgICB9ICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NDbGFzc1N0cmluZyggY2xhc3NlcywgY2hlY2tPcHRpb24gKSB7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudCwgaTsKICAgICAgICAgICAgICAgIGZvciAoIGkgPSAwOyBpIDwgY2xhc3Nlcy5sZW5ndGg7IGkrKyApIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gdGhhdC5jbGFzc2VzRWxlbWVudExvb2t1cFsgY2xhc3Nlc1sgaSBdIF0gfHwgJCgpOwogICAgICAgICAgICAgICAgICAgIGlmICggb3B0aW9ucy5hZGQgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRSZW1vdmVFdmVudCgpOwogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gJCggJC51bmlxdWVTb3J0KCBjdXJyZW50LmdldCgpLmNvbmNhdCggb3B0aW9ucy5lbGVtZW50LmdldCgpICkgKSApOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgPSAkKCBjdXJyZW50Lm5vdCggb3B0aW9ucy5lbGVtZW50ICkuZ2V0KCkgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhhdC5jbGFzc2VzRWxlbWVudExvb2t1cFsgY2xhc3Nlc1sgaSBdIF0gPSBjdXJyZW50OwogICAgICAgICAgICAgICAgICAgIGZ1bGwucHVzaCggY2xhc3Nlc1sgaSBdICk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCBjaGVja09wdGlvbiAmJiBvcHRpb25zLmNsYXNzZXNbIGNsYXNzZXNbIGkgXSBdICkgewogICAgICAgICAgICAgICAgICAgICAgICBmdWxsLnB1c2goIG9wdGlvbnMuY2xhc3Nlc1sgY2xhc3Nlc1sgaSBdIF0gKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICggb3B0aW9ucy5rZXlzICkgewogICAgICAgICAgICAgICAgcHJvY2Vzc0NsYXNzU3RyaW5nKCBvcHRpb25zLmtleXMubWF0Y2goIC9cUysvZyApIHx8IFtdLCB0cnVlICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCBvcHRpb25zLmV4dHJhICkgewogICAgICAgICAgICAgICAgcHJvY2Vzc0NsYXNzU3RyaW5nKCBvcHRpb25zLmV4dHJhLm1hdGNoKCAvXFMrL2cgKSB8fCBbXSApOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZnVsbC5qb2luKCAiICIgKTsKICAgICAgICB9LAoKICAgICAgICBfdW50cmFja0NsYXNzZXNFbGVtZW50OiBmdW5jdGlvbiggZXZlbnQgKSB7CiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgJC5lYWNoKCB0aGF0LmNsYXNzZXNFbGVtZW50TG9va3VwLCBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHsKICAgICAgICAgICAgICAgIGlmICggJC5pbkFycmF5KCBldmVudC50YXJnZXQsIHZhbHVlICkgIT09IC0xICkgewogICAgICAgICAgICAgICAgICAgIHRoYXQuY2xhc3Nlc0VsZW1lbnRMb29rdXBbIGtleSBdID0gJCggdmFsdWUubm90KCBldmVudC50YXJnZXQgKS5nZXQoKSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9ICk7CgogICAgICAgICAgICB0aGlzLl9vZmYoICQoIGV2ZW50LnRhcmdldCApICk7CiAgICAgICAgfSwKCiAgICAgICAgX3JlbW92ZUNsYXNzOiBmdW5jdGlvbiggZWxlbWVudCwga2V5cywgZXh0cmEgKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl90b2dnbGVDbGFzcyggZWxlbWVudCwga2V5cywgZXh0cmEsIGZhbHNlICk7CiAgICAgICAgfSwKCiAgICAgICAgX2FkZENsYXNzOiBmdW5jdGlvbiggZWxlbWVudCwga2V5cywgZXh0cmEgKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl90b2dnbGVDbGFzcyggZWxlbWVudCwga2V5cywgZXh0cmEsIHRydWUgKTsKICAgICAgICB9LAoKICAgICAgICBfdG9nZ2xlQ2xhc3M6IGZ1bmN0aW9uKCBlbGVtZW50LCBrZXlzLCBleHRyYSwgYWRkICkgewogICAgICAgICAgICBhZGQgPSAoIHR5cGVvZiBhZGQgPT09ICJib29sZWFuIiApID8gYWRkIDogZXh0cmE7CiAgICAgICAgICAgIHZhciBzaGlmdCA9ICggdHlwZW9mIGVsZW1lbnQgPT09ICJzdHJpbmciIHx8IGVsZW1lbnQgPT09IG51bGwgKSwKICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7CiAgICAgICAgICAgICAgICAgICAgZXh0cmE6IHNoaWZ0ID8ga2V5cyA6IGV4dHJhLAogICAgICAgICAgICAgICAgICAgIGtleXM6IHNoaWZ0ID8gZWxlbWVudCA6IGtleXMsCiAgICAgICAgICAgICAgICAgICAgZWxlbWVudDogc2hpZnQgPyB0aGlzLmVsZW1lbnQgOiBlbGVtZW50LAogICAgICAgICAgICAgICAgICAgIGFkZDogYWRkCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICBvcHRpb25zLmVsZW1lbnQudG9nZ2xlQ2xhc3MoIHRoaXMuX2NsYXNzZXMoIG9wdGlvbnMgKSwgYWRkICk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCgogICAgICAgIF9vbjogZnVuY3Rpb24oIHN1cHByZXNzRGlzYWJsZWRDaGVjaywgZWxlbWVudCwgaGFuZGxlcnMgKSB7CiAgICAgICAgICAgIHZhciBkZWxlZ2F0ZUVsZW1lbnQ7CiAgICAgICAgICAgIHZhciBpbnN0YW5jZSA9IHRoaXM7CgogICAgICAgICAgICAvLyBObyBzdXBwcmVzc0Rpc2FibGVkQ2hlY2sgZmxhZywgc2h1ZmZsZSBhcmd1bWVudHMKICAgICAgICAgICAgaWYgKCB0eXBlb2Ygc3VwcHJlc3NEaXNhYmxlZENoZWNrICE9PSAiYm9vbGVhbiIgKSB7CiAgICAgICAgICAgICAgICBoYW5kbGVycyA9IGVsZW1lbnQ7CiAgICAgICAgICAgICAgICBlbGVtZW50ID0gc3VwcHJlc3NEaXNhYmxlZENoZWNrOwogICAgICAgICAgICAgICAgc3VwcHJlc3NEaXNhYmxlZENoZWNrID0gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIE5vIGVsZW1lbnQgYXJndW1lbnQsIHNodWZmbGUgYW5kIHVzZSB0aGlzLmVsZW1lbnQKICAgICAgICAgICAgaWYgKCAhaGFuZGxlcnMgKSB7CiAgICAgICAgICAgICAgICBoYW5kbGVycyA9IGVsZW1lbnQ7CiAgICAgICAgICAgICAgICBlbGVtZW50ID0gdGhpcy5lbGVtZW50OwogICAgICAgICAgICAgICAgZGVsZWdhdGVFbGVtZW50ID0gdGhpcy53aWRnZXQoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBkZWxlZ2F0ZUVsZW1lbnQgPSAkKCBlbGVtZW50ICk7CiAgICAgICAgICAgICAgICB0aGlzLmJpbmRpbmdzID0gdGhpcy5iaW5kaW5ncy5hZGQoIGVsZW1lbnQgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJC5lYWNoKCBoYW5kbGVycywgZnVuY3Rpb24oIGV2ZW50LCBoYW5kbGVyICkgewogICAgICAgICAgICAgICAgZnVuY3Rpb24gaGFuZGxlclByb3h5KCkgewoKICAgICAgICAgICAgICAgICAgICAvLyBBbGxvdyB3aWRnZXRzIHRvIGN1c3RvbWl6ZSB0aGUgZGlzYWJsZWQgaGFuZGxpbmcKICAgICAgICAgICAgICAgICAgICAvLyAtIGRpc2FibGVkIGFzIGFuIGFycmF5IGluc3RlYWQgb2YgYm9vbGVhbgogICAgICAgICAgICAgICAgICAgIC8vIC0gZGlzYWJsZWQgY2xhc3MgYXMgbWV0aG9kIGZvciBkaXNhYmxpbmcgaW5kaXZpZHVhbCBwYXJ0cwogICAgICAgICAgICAgICAgICAgIGlmICggIXN1cHByZXNzRGlzYWJsZWRDaGVjayAmJgogICAgICAgICAgICAgICAgICAgICAgICAoIGluc3RhbmNlLm9wdGlvbnMuZGlzYWJsZWQgPT09IHRydWUgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoIHRoaXMgKS5oYXNDbGFzcyggInVpLXN0YXRlLWRpc2FibGVkIiApICkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICggdHlwZW9mIGhhbmRsZXIgPT09ICJzdHJpbmciID8gaW5zdGFuY2VbIGhhbmRsZXIgXSA6IGhhbmRsZXIgKQogICAgICAgICAgICAgICAgICAgICAgICAuYXBwbHkoIGluc3RhbmNlLCBhcmd1bWVudHMgKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBDb3B5IHRoZSBndWlkIHNvIGRpcmVjdCB1bmJpbmRpbmcgd29ya3MKICAgICAgICAgICAgICAgIGlmICggdHlwZW9mIGhhbmRsZXIgIT09ICJzdHJpbmciICkgewogICAgICAgICAgICAgICAgICAgIGhhbmRsZXJQcm94eS5ndWlkID0gaGFuZGxlci5ndWlkID0KICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5ndWlkIHx8IGhhbmRsZXJQcm94eS5ndWlkIHx8ICQuZ3VpZCsrOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IGV2ZW50Lm1hdGNoKCAvXihbXHc6LV0qKVxzKiguKikkLyApOwogICAgICAgICAgICAgICAgdmFyIGV2ZW50TmFtZSA9IG1hdGNoWyAxIF0gKyBpbnN0YW5jZS5ldmVudE5hbWVzcGFjZTsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3RvciA9IG1hdGNoWyAyIF07CgogICAgICAgICAgICAgICAgaWYgKCBzZWxlY3RvciApIHsKICAgICAgICAgICAgICAgICAgICBkZWxlZ2F0ZUVsZW1lbnQub24oIGV2ZW50TmFtZSwgc2VsZWN0b3IsIGhhbmRsZXJQcm94eSApOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50Lm9uKCBldmVudE5hbWUsIGhhbmRsZXJQcm94eSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9ICk7CiAgICAgICAgfSwKCiAgICAgICAgX29mZjogZnVuY3Rpb24oIGVsZW1lbnQsIGV2ZW50TmFtZSApIHsKICAgICAgICAgICAgZXZlbnROYW1lID0gKCBldmVudE5hbWUgfHwgIiIgKS5zcGxpdCggIiAiICkuam9pbiggdGhpcy5ldmVudE5hbWVzcGFjZSArICIgIiApICsKICAgICAgICAgICAgICAgIHRoaXMuZXZlbnROYW1lc3BhY2U7CiAgICAgICAgICAgIGVsZW1lbnQub2ZmKCBldmVudE5hbWUgKTsKCiAgICAgICAgICAgIC8vIENsZWFyIHRoZSBzdGFjayB0byBhdm9pZCBtZW1vcnkgbGVha3MgKCMxMDA1NikKICAgICAgICAgICAgdGhpcy5iaW5kaW5ncyA9ICQoIHRoaXMuYmluZGluZ3Mubm90KCBlbGVtZW50ICkuZ2V0KCkgKTsKICAgICAgICAgICAgdGhpcy5mb2N1c2FibGUgPSAkKCB0aGlzLmZvY3VzYWJsZS5ub3QoIGVsZW1lbnQgKS5nZXQoKSApOwogICAgICAgICAgICB0aGlzLmhvdmVyYWJsZSA9ICQoIHRoaXMuaG92ZXJhYmxlLm5vdCggZWxlbWVudCApLmdldCgpICk7CiAgICAgICAgfSwKCiAgICAgICAgX2RlbGF5OiBmdW5jdGlvbiggaGFuZGxlciwgZGVsYXkgKSB7CiAgICAgICAgICAgIGZ1bmN0aW9uIGhhbmRsZXJQcm94eSgpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoIHR5cGVvZiBoYW5kbGVyID09PSAic3RyaW5nIiA/IGluc3RhbmNlWyBoYW5kbGVyIF0gOiBoYW5kbGVyICkKICAgICAgICAgICAgICAgICAgICAuYXBwbHkoIGluc3RhbmNlLCBhcmd1bWVudHMgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgaW5zdGFuY2UgPSB0aGlzOwogICAgICAgICAgICByZXR1cm4gc2V0VGltZW91dCggaGFuZGxlclByb3h5LCBkZWxheSB8fCAwICk7CiAgICAgICAgfSwKCiAgICAgICAgX2hvdmVyYWJsZTogZnVuY3Rpb24oIGVsZW1lbnQgKSB7CiAgICAgICAgICAgIHRoaXMuaG92ZXJhYmxlID0gdGhpcy5ob3ZlcmFibGUuYWRkKCBlbGVtZW50ICk7CiAgICAgICAgICAgIHRoaXMuX29uKCBlbGVtZW50LCB7CiAgICAgICAgICAgICAgICBtb3VzZWVudGVyOiBmdW5jdGlvbiggZXZlbnQgKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYWRkQ2xhc3MoICQoIGV2ZW50LmN1cnJlbnRUYXJnZXQgKSwgbnVsbCwgInVpLXN0YXRlLWhvdmVyIiApOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIG1vdXNlbGVhdmU6IGZ1bmN0aW9uKCBldmVudCApIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVDbGFzcyggJCggZXZlbnQuY3VycmVudFRhcmdldCApLCBudWxsLCAidWktc3RhdGUtaG92ZXIiICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gKTsKICAgICAgICB9LAoKICAgICAgICBfZm9jdXNhYmxlOiBmdW5jdGlvbiggZWxlbWVudCApIHsKICAgICAgICAgICAgdGhpcy5mb2N1c2FibGUgPSB0aGlzLmZvY3VzYWJsZS5hZGQoIGVsZW1lbnQgKTsKICAgICAgICAgICAgdGhpcy5fb24oIGVsZW1lbnQsIHsKICAgICAgICAgICAgICAgIGZvY3VzaW46IGZ1bmN0aW9uKCBldmVudCApIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9hZGRDbGFzcyggJCggZXZlbnQuY3VycmVudFRhcmdldCApLCBudWxsLCAidWktc3RhdGUtZm9jdXMiICk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZm9jdXNvdXQ6IGZ1bmN0aW9uKCBldmVudCApIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVDbGFzcyggJCggZXZlbnQuY3VycmVudFRhcmdldCApLCBudWxsLCAidWktc3RhdGUtZm9jdXMiICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gKTsKICAgICAgICB9LAoKICAgICAgICBfdHJpZ2dlcjogZnVuY3Rpb24oIHR5cGUsIGV2ZW50LCBkYXRhICkgewogICAgICAgICAgICB2YXIgcHJvcCwgb3JpZzsKICAgICAgICAgICAgdmFyIGNhbGxiYWNrID0gdGhpcy5vcHRpb25zWyB0eXBlIF07CgogICAgICAgICAgICBkYXRhID0gZGF0YSB8fCB7fTsKICAgICAgICAgICAgZXZlbnQgPSAkLkV2ZW50KCBldmVudCApOwogICAgICAgICAgICBldmVudC50eXBlID0gKCB0eXBlID09PSB0aGlzLndpZGdldEV2ZW50UHJlZml4ID8KICAgICAgICAgICAgICAgIHR5cGUgOgogICAgICAgICAgICAgICAgdGhpcy53aWRnZXRFdmVudFByZWZpeCArIHR5cGUgKS50b0xvd2VyQ2FzZSgpOwoKICAgICAgICAgICAgLy8gVGhlIG9yaWdpbmFsIGV2ZW50IG1heSBjb21lIGZyb20gYW55IGVsZW1lbnQKICAgICAgICAgICAgLy8gc28gd2UgbmVlZCB0byByZXNldCB0aGUgdGFyZ2V0IG9uIHRoZSBuZXcgZXZlbnQKICAgICAgICAgICAgZXZlbnQudGFyZ2V0ID0gdGhpcy5lbGVtZW50WyAwIF07CgogICAgICAgICAgICAvLyBDb3B5IG9yaWdpbmFsIGV2ZW50IHByb3BlcnRpZXMgb3ZlciB0byB0aGUgbmV3IGV2ZW50CiAgICAgICAgICAgIG9yaWcgPSBldmVudC5vcmlnaW5hbEV2ZW50OwogICAgICAgICAgICBpZiAoIG9yaWcgKSB7CiAgICAgICAgICAgICAgICBmb3IgKCBwcm9wIGluIG9yaWcgKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCAhKCBwcm9wIGluIGV2ZW50ICkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50WyBwcm9wIF0gPSBvcmlnWyBwcm9wIF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLmVsZW1lbnQudHJpZ2dlciggZXZlbnQsIGRhdGEgKTsKICAgICAgICAgICAgcmV0dXJuICEoIHR5cGVvZiBjYWxsYmFjayA9PT0gImZ1bmN0aW9uIiAmJgogICAgICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkoIHRoaXMuZWxlbWVudFsgMCBdLCBbIGV2ZW50IF0uY29uY2F0KCBkYXRhICkgKSA9PT0gZmFsc2UgfHwKICAgICAgICAgICAgICAgIGV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpICk7CiAgICAgICAgfQogICAgfTsKCiAgICAkLmVhY2goIHsgc2hvdzogImZhZGVJbiIsIGhpZGU6ICJmYWRlT3V0IiB9LCBmdW5jdGlvbiggbWV0aG9kLCBkZWZhdWx0RWZmZWN0ICkgewogICAgICAgICQuV2lkZ2V0LnByb3RvdHlwZVsgIl8iICsgbWV0aG9kIF0gPSBmdW5jdGlvbiggZWxlbWVudCwgb3B0aW9ucywgY2FsbGJhY2sgKSB7CiAgICAgICAgICAgIGlmICggdHlwZW9mIG9wdGlvbnMgPT09ICJzdHJpbmciICkgewogICAgICAgICAgICAgICAgb3B0aW9ucyA9IHsgZWZmZWN0OiBvcHRpb25zIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBoYXNPcHRpb25zOwogICAgICAgICAgICB2YXIgZWZmZWN0TmFtZSA9ICFvcHRpb25zID8KICAgICAgICAgICAgICAgIG1ldGhvZCA6CiAgICAgICAgICAgICAgICBvcHRpb25zID09PSB0cnVlIHx8IHR5cGVvZiBvcHRpb25zID09PSAibnVtYmVyIiA/CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdEVmZmVjdCA6CiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5lZmZlY3QgfHwgZGVmYXVsdEVmZmVjdDsKCiAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogICAgICAgICAgICBpZiAoIHR5cGVvZiBvcHRpb25zID09PSAibnVtYmVyIiApIHsKICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IGR1cmF0aW9uOiBvcHRpb25zIH07CiAgICAgICAgICAgIH0gZWxzZSBpZiAoIG9wdGlvbnMgPT09IHRydWUgKSB7CiAgICAgICAgICAgICAgICBvcHRpb25zID0ge307CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGhhc09wdGlvbnMgPSAhJC5pc0VtcHR5T2JqZWN0KCBvcHRpb25zICk7CiAgICAgICAgICAgIG9wdGlvbnMuY29tcGxldGUgPSBjYWxsYmFjazsKCiAgICAgICAgICAgIGlmICggb3B0aW9ucy5kZWxheSApIHsKICAgICAgICAgICAgICAgIGVsZW1lbnQuZGVsYXkoIG9wdGlvbnMuZGVsYXkgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCBoYXNPcHRpb25zICYmICQuZWZmZWN0cyAmJiAkLmVmZmVjdHMuZWZmZWN0WyBlZmZlY3ROYW1lIF0gKSB7CiAgICAgICAgICAgICAgICBlbGVtZW50WyBtZXRob2QgXSggb3B0aW9ucyApOwogICAgICAgICAgICB9IGVsc2UgaWYgKCBlZmZlY3ROYW1lICE9PSBtZXRob2QgJiYgZWxlbWVudFsgZWZmZWN0TmFtZSBdICkgewogICAgICAgICAgICAgICAgZWxlbWVudFsgZWZmZWN0TmFtZSBdKCBvcHRpb25zLmR1cmF0aW9uLCBvcHRpb25zLmVhc2luZywgY2FsbGJhY2sgKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGVsZW1lbnQucXVldWUoIGZ1bmN0aW9uKCBuZXh0ICkgewogICAgICAgICAgICAgICAgICAgICQoIHRoaXMgKVsgbWV0aG9kIF0oKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIGNhbGxiYWNrICkgewogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKCBlbGVtZW50WyAwIF0gKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbmV4dCgpOwogICAgICAgICAgICAgICAgfSApOwogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIH0gKTsKCiAgICB2YXIgd2lkZ2V0ID0gJC53aWRnZXQ7Cn0pKTsKIWZ1bmN0aW9uKG4scil7Im9iamVjdCI9PXR5cGVvZiBleHBvcnRzJiYidW5kZWZpbmVkIiE9dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz1yKCk6ImZ1bmN0aW9uIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUoInVuZGVyc2NvcmUiLHIpOihuPSJ1bmRlZmluZWQiIT10eXBlb2YgZ2xvYmFsVGhpcz9nbG9iYWxUaGlzOm58fHNlbGYsZnVuY3Rpb24oKXt2YXIgdD1uLl8sZT1uLl89cigpO2Uubm9Db25mbGljdD1mdW5jdGlvbigpe3JldHVybiBuLl89dCxlfX0oKSl9KHRoaXMsKGZ1bmN0aW9uKCl7Ci8vICAgICBVbmRlcnNjb3JlLmpzIDEuMTMuNgovLyAgICAgaHR0cHM6Ly91bmRlcnNjb3JlanMub3JnCi8vICAgICAoYykgMjAwOS0yMDIyIEplcmVteSBBc2hrZW5hcywgSnVsaWFuIEdvbmdncmlqcCwgYW5kIERvY3VtZW50Q2xvdWQgYW5kIEludmVzdGlnYXRpdmUgUmVwb3J0ZXJzICYgRWRpdG9ycwovLyAgICAgVW5kZXJzY29yZSBtYXkgYmUgZnJlZWx5IGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS4KdmFyIG49IjEuMTMuNiIscj0ib2JqZWN0Ij09dHlwZW9mIHNlbGYmJnNlbGYuc2VsZj09PXNlbGYmJnNlbGZ8fCJvYmplY3QiPT10eXBlb2YgZ2xvYmFsJiZnbG9iYWwuZ2xvYmFsPT09Z2xvYmFsJiZnbG9iYWx8fEZ1bmN0aW9uKCJyZXR1cm4gdGhpcyIpKCl8fHt9LHQ9QXJyYXkucHJvdG90eXBlLGU9T2JqZWN0LnByb3RvdHlwZSx1PSJ1bmRlZmluZWQiIT10eXBlb2YgU3ltYm9sP1N5bWJvbC5wcm90b3R5cGU6bnVsbCxvPXQucHVzaCxpPXQuc2xpY2UsYT1lLnRvU3RyaW5nLGY9ZS5oYXNPd25Qcm9wZXJ0eSxjPSJ1bmRlZmluZWQiIT10eXBlb2YgQXJyYXlCdWZmZXIsbD0idW5kZWZpbmVkIiE9dHlwZW9mIERhdGFWaWV3LHM9QXJyYXkuaXNBcnJheSxwPU9iamVjdC5rZXlzLHY9T2JqZWN0LmNyZWF0ZSxoPWMmJkFycmF5QnVmZmVyLmlzVmlldyx5PWlzTmFOLGQ9aXNGaW5pdGUsZz0he3RvU3RyaW5nOm51bGx9LnByb3BlcnR5SXNFbnVtZXJhYmxlKCJ0b1N0cmluZyIpLGI9WyJ2YWx1ZU9mIiwiaXNQcm90b3R5cGVPZiIsInRvU3RyaW5nIiwicHJvcGVydHlJc0VudW1lcmFibGUiLCJoYXNPd25Qcm9wZXJ0eSIsInRvTG9jYWxlU3RyaW5nIl0sbT1NYXRoLnBvdygyLDUzKS0xO2Z1bmN0aW9uIGoobixyKXtyZXR1cm4gcj1udWxsPT1yP24ubGVuZ3RoLTE6K3IsZnVuY3Rpb24oKXtmb3IodmFyIHQ9TWF0aC5tYXgoYXJndW1lbnRzLmxlbmd0aC1yLDApLGU9QXJyYXkodCksdT0wO3U8dDt1KyspZVt1XT1hcmd1bWVudHNbdStyXTtzd2l0Y2gocil7Y2FzZSAwOnJldHVybiBuLmNhbGwodGhpcyxlKTtjYXNlIDE6cmV0dXJuIG4uY2FsbCh0aGlzLGFyZ3VtZW50c1swXSxlKTtjYXNlIDI6cmV0dXJuIG4uY2FsbCh0aGlzLGFyZ3VtZW50c1swXSxhcmd1bWVudHNbMV0sZSl9dmFyIG89QXJyYXkocisxKTtmb3IodT0wO3U8cjt1Kyspb1t1XT1hcmd1bWVudHNbdV07cmV0dXJuIG9bcl09ZSxuLmFwcGx5KHRoaXMsbyl9fWZ1bmN0aW9uIF8obil7dmFyIHI9dHlwZW9mIG47cmV0dXJuImZ1bmN0aW9uIj09PXJ8fCJvYmplY3QiPT09ciYmISFufWZ1bmN0aW9uIHcobil7cmV0dXJuIHZvaWQgMD09PW59ZnVuY3Rpb24gQShuKXtyZXR1cm4hMD09PW58fCExPT09bnx8IltvYmplY3QgQm9vbGVhbl0iPT09YS5jYWxsKG4pfWZ1bmN0aW9uIHgobil7dmFyIHI9IltvYmplY3QgIituKyJdIjtyZXR1cm4gZnVuY3Rpb24obil7cmV0dXJuIGEuY2FsbChuKT09PXJ9fXZhciBTPXgoIlN0cmluZyIpLE89eCgiTnVtYmVyIiksTT14KCJEYXRlIiksRT14KCJSZWdFeHAiKSxCPXgoIkVycm9yIiksTj14KCJTeW1ib2wiKSxJPXgoIkFycmF5QnVmZmVyIiksVD14KCJGdW5jdGlvbiIpLGs9ci5kb2N1bWVudCYmci5kb2N1bWVudC5jaGlsZE5vZGVzOyJmdW5jdGlvbiIhPXR5cGVvZi8uLyYmIm9iamVjdCIhPXR5cGVvZiBJbnQ4QXJyYXkmJiJmdW5jdGlvbiIhPXR5cGVvZiBrJiYoVD1mdW5jdGlvbihuKXtyZXR1cm4iZnVuY3Rpb24iPT10eXBlb2Ygbnx8ITF9KTt2YXIgRD1ULFI9eCgiT2JqZWN0IiksRj1sJiZSKG5ldyBEYXRhVmlldyhuZXcgQXJyYXlCdWZmZXIoOCkpKSxWPSJ1bmRlZmluZWQiIT10eXBlb2YgTWFwJiZSKG5ldyBNYXApLFA9eCgiRGF0YVZpZXciKTt2YXIgcT1GP2Z1bmN0aW9uKG4pe3JldHVybiBudWxsIT1uJiZEKG4uZ2V0SW50OCkmJkkobi5idWZmZXIpfTpQLFU9c3x8eCgiQXJyYXkiKTtmdW5jdGlvbiBXKG4scil7cmV0dXJuIG51bGwhPW4mJmYuY2FsbChuLHIpfXZhciB6PXgoIkFyZ3VtZW50cyIpOyFmdW5jdGlvbigpe3ooYXJndW1lbnRzKXx8KHo9ZnVuY3Rpb24obil7cmV0dXJuIFcobiwiY2FsbGVlIil9KX0oKTt2YXIgTD16O2Z1bmN0aW9uICQobil7cmV0dXJuIE8obikmJnkobil9ZnVuY3Rpb24gQyhuKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gbn19ZnVuY3Rpb24gSyhuKXtyZXR1cm4gZnVuY3Rpb24ocil7dmFyIHQ9bihyKTtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQmJnQ+PTAmJnQ8PW19fWZ1bmN0aW9uIEoobil7cmV0dXJuIGZ1bmN0aW9uKHIpe3JldHVybiBudWxsPT1yP3ZvaWQgMDpyW25dfX12YXIgRz1KKCJieXRlTGVuZ3RoIiksSD1LKEcpLFE9L1xbb2JqZWN0ICgoSXxVaSludCg4fDE2fDMyKXxGbG9hdCgzMnw2NCl8VWludDhDbGFtcGVkfEJpZyhJfFVpKW50NjQpQXJyYXlcXS87dmFyIFg9Yz9mdW5jdGlvbihuKXtyZXR1cm4gaD9oKG4pJiYhcShuKTpIKG4pJiZRLnRlc3QoYS5jYWxsKG4pKX06QyghMSksWT1KKCJsZW5ndGgiKTtmdW5jdGlvbiBaKG4scil7cj1mdW5jdGlvbihuKXtmb3IodmFyIHI9e30sdD1uLmxlbmd0aCxlPTA7ZTx0OysrZSlyW25bZV1dPSEwO3JldHVybntjb250YWluczpmdW5jdGlvbihuKXtyZXR1cm4hMD09PXJbbl19LHB1c2g6ZnVuY3Rpb24odCl7cmV0dXJuIHJbdF09ITAsbi5wdXNoKHQpfX19KHIpO3ZhciB0PWIubGVuZ3RoLHU9bi5jb25zdHJ1Y3RvcixvPUQodSkmJnUucHJvdG90eXBlfHxlLGk9ImNvbnN0cnVjdG9yIjtmb3IoVyhuLGkpJiYhci5jb250YWlucyhpKSYmci5wdXNoKGkpO3QtLTspKGk9Ylt0XSlpbiBuJiZuW2ldIT09b1tpXSYmIXIuY29udGFpbnMoaSkmJnIucHVzaChpKX1mdW5jdGlvbiBubihuKXtpZighXyhuKSlyZXR1cm5bXTtpZihwKXJldHVybiBwKG4pO3ZhciByPVtdO2Zvcih2YXIgdCBpbiBuKVcobix0KSYmci5wdXNoKHQpO3JldHVybiBnJiZaKG4scikscn1mdW5jdGlvbiBybihuLHIpe3ZhciB0PW5uKHIpLGU9dC5sZW5ndGg7aWYobnVsbD09bilyZXR1cm4hZTtmb3IodmFyIHU9T2JqZWN0KG4pLG89MDtvPGU7bysrKXt2YXIgaT10W29dO2lmKHJbaV0hPT11W2ldfHwhKGkgaW4gdSkpcmV0dXJuITF9cmV0dXJuITB9ZnVuY3Rpb24gdG4obil7cmV0dXJuIG4gaW5zdGFuY2VvZiB0bj9uOnRoaXMgaW5zdGFuY2VvZiB0bj92b2lkKHRoaXMuX3dyYXBwZWQ9bik6bmV3IHRuKG4pfWZ1bmN0aW9uIGVuKG4pe3JldHVybiBuZXcgVWludDhBcnJheShuLmJ1ZmZlcnx8bixuLmJ5dGVPZmZzZXR8fDAsRyhuKSl9dG4uVkVSU0lPTj1uLHRuLnByb3RvdHlwZS52YWx1ZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLl93cmFwcGVkfSx0bi5wcm90b3R5cGUudmFsdWVPZj10bi5wcm90b3R5cGUudG9KU09OPXRuLnByb3RvdHlwZS52YWx1ZSx0bi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gU3RyaW5nKHRoaXMuX3dyYXBwZWQpfTt2YXIgdW49IltvYmplY3QgRGF0YVZpZXddIjtmdW5jdGlvbiBvbihuLHIsdCxlKXtpZihuPT09cilyZXR1cm4gMCE9PW58fDEvbj09MS9yO2lmKG51bGw9PW58fG51bGw9PXIpcmV0dXJuITE7aWYobiE9bilyZXR1cm4gciE9cjt2YXIgbz10eXBlb2YgbjtyZXR1cm4oImZ1bmN0aW9uIj09PW98fCJvYmplY3QiPT09b3x8Im9iamVjdCI9PXR5cGVvZiByKSYmZnVuY3Rpb24gbihyLHQsZSxvKXtyIGluc3RhbmNlb2YgdG4mJihyPXIuX3dyYXBwZWQpO3QgaW5zdGFuY2VvZiB0biYmKHQ9dC5fd3JhcHBlZCk7dmFyIGk9YS5jYWxsKHIpO2lmKGkhPT1hLmNhbGwodCkpcmV0dXJuITE7aWYoRiYmIltvYmplY3QgT2JqZWN0XSI9PWkmJnEocikpe2lmKCFxKHQpKXJldHVybiExO2k9dW59c3dpdGNoKGkpe2Nhc2UiW29iamVjdCBSZWdFeHBdIjpjYXNlIltvYmplY3QgU3RyaW5nXSI6cmV0dXJuIiIrcj09IiIrdDtjYXNlIltvYmplY3QgTnVtYmVyXSI6cmV0dXJuK3IhPStyPyt0IT0rdDowPT0rcj8xLytyPT0xL3Q6K3I9PSt0O2Nhc2UiW29iamVjdCBEYXRlXSI6Y2FzZSJbb2JqZWN0IEJvb2xlYW5dIjpyZXR1cm4rcj09K3Q7Y2FzZSJbb2JqZWN0IFN5bWJvbF0iOnJldHVybiB1LnZhbHVlT2YuY2FsbChyKT09PXUudmFsdWVPZi5jYWxsKHQpO2Nhc2UiW29iamVjdCBBcnJheUJ1ZmZlcl0iOmNhc2UgdW46cmV0dXJuIG4oZW4ociksZW4odCksZSxvKX12YXIgZj0iW29iamVjdCBBcnJheV0iPT09aTtpZighZiYmWChyKSl7aWYoRyhyKSE9PUcodCkpcmV0dXJuITE7aWYoci5idWZmZXI9PT10LmJ1ZmZlciYmci5ieXRlT2Zmc2V0PT09dC5ieXRlT2Zmc2V0KXJldHVybiEwO2Y9ITB9aWYoIWYpe2lmKCJvYmplY3QiIT10eXBlb2Ygcnx8Im9iamVjdCIhPXR5cGVvZiB0KXJldHVybiExO3ZhciBjPXIuY29uc3RydWN0b3IsbD10LmNvbnN0cnVjdG9yO2lmKGMhPT1sJiYhKEQoYykmJmMgaW5zdGFuY2VvZiBjJiZEKGwpJiZsIGluc3RhbmNlb2YgbCkmJiJjb25zdHJ1Y3RvciJpbiByJiYiY29uc3RydWN0b3IiaW4gdClyZXR1cm4hMX1vPW98fFtdO3ZhciBzPShlPWV8fFtdKS5sZW5ndGg7Zm9yKDtzLS07KWlmKGVbc109PT1yKXJldHVybiBvW3NdPT09dDtpZihlLnB1c2gociksby5wdXNoKHQpLGYpe2lmKChzPXIubGVuZ3RoKSE9PXQubGVuZ3RoKXJldHVybiExO2Zvcig7cy0tOylpZighb24ocltzXSx0W3NdLGUsbykpcmV0dXJuITF9ZWxzZXt2YXIgcCx2PW5uKHIpO2lmKHM9di5sZW5ndGgsbm4odCkubGVuZ3RoIT09cylyZXR1cm4hMTtmb3IoO3MtLTspaWYocD12W3NdLCFXKHQscCl8fCFvbihyW3BdLHRbcF0sZSxvKSlyZXR1cm4hMX1yZXR1cm4gZS5wb3AoKSxvLnBvcCgpLCEwfShuLHIsdCxlKX1mdW5jdGlvbiBhbihuKXtpZighXyhuKSlyZXR1cm5bXTt2YXIgcj1bXTtmb3IodmFyIHQgaW4gbilyLnB1c2godCk7cmV0dXJuIGcmJloobixyKSxyfWZ1bmN0aW9uIGZuKG4pe3ZhciByPVkobik7cmV0dXJuIGZ1bmN0aW9uKHQpe2lmKG51bGw9PXQpcmV0dXJuITE7dmFyIGU9YW4odCk7aWYoWShlKSlyZXR1cm4hMTtmb3IodmFyIHU9MDt1PHI7dSsrKWlmKCFEKHRbblt1XV0pKXJldHVybiExO3JldHVybiBuIT09aG58fCFEKHRbY25dKX19dmFyIGNuPSJmb3JFYWNoIixsbj0iaGFzIixzbj1bImNsZWFyIiwiZGVsZXRlIl0scG49WyJnZXQiLGxuLCJzZXQiXSx2bj1zbi5jb25jYXQoY24scG4pLGhuPXNuLmNvbmNhdChwbikseW49WyJhZGQiXS5jb25jYXQoc24sY24sbG4pLGRuPVY/Zm4odm4pOngoIk1hcCIpLGduPVY/Zm4oaG4pOngoIldlYWtNYXAiKSxibj1WP2ZuKHluKTp4KCJTZXQiKSxtbj14KCJXZWFrU2V0Iik7ZnVuY3Rpb24gam4obil7Zm9yKHZhciByPW5uKG4pLHQ9ci5sZW5ndGgsZT1BcnJheSh0KSx1PTA7dTx0O3UrKyllW3VdPW5bclt1XV07cmV0dXJuIGV9ZnVuY3Rpb24gX24obil7Zm9yKHZhciByPXt9LHQ9bm4obiksZT0wLHU9dC5sZW5ndGg7ZTx1O2UrKylyW25bdFtlXV1dPXRbZV07cmV0dXJuIHJ9ZnVuY3Rpb24gd24obil7dmFyIHI9W107Zm9yKHZhciB0IGluIG4pRChuW3RdKSYmci5wdXNoKHQpO3JldHVybiByLnNvcnQoKX1mdW5jdGlvbiBBbihuLHIpe3JldHVybiBmdW5jdGlvbih0KXt2YXIgZT1hcmd1bWVudHMubGVuZ3RoO2lmKHImJih0PU9iamVjdCh0KSksZTwyfHxudWxsPT10KXJldHVybiB0O2Zvcih2YXIgdT0xO3U8ZTt1KyspZm9yKHZhciBvPWFyZ3VtZW50c1t1XSxpPW4obyksYT1pLmxlbmd0aCxmPTA7ZjxhO2YrKyl7dmFyIGM9aVtmXTtyJiZ2b2lkIDAhPT10W2NdfHwodFtjXT1vW2NdKX1yZXR1cm4gdH19dmFyIHhuPUFuKGFuKSxTbj1BbihubiksT249QW4oYW4sITApO2Z1bmN0aW9uIE1uKG4pe2lmKCFfKG4pKXJldHVybnt9O2lmKHYpcmV0dXJuIHYobik7dmFyIHI9ZnVuY3Rpb24oKXt9O3IucHJvdG90eXBlPW47dmFyIHQ9bmV3IHI7cmV0dXJuIHIucHJvdG90eXBlPW51bGwsdH1mdW5jdGlvbiBFbihuKXtyZXR1cm4gVShuKT9uOltuXX1mdW5jdGlvbiBCbihuKXtyZXR1cm4gdG4udG9QYXRoKG4pfWZ1bmN0aW9uIE5uKG4scil7Zm9yKHZhciB0PXIubGVuZ3RoLGU9MDtlPHQ7ZSsrKXtpZihudWxsPT1uKXJldHVybjtuPW5bcltlXV19cmV0dXJuIHQ/bjp2b2lkIDB9ZnVuY3Rpb24gSW4obixyLHQpe3ZhciBlPU5uKG4sQm4ocikpO3JldHVybiB3KGUpP3Q6ZX1mdW5jdGlvbiBUbihuKXtyZXR1cm4gbn1mdW5jdGlvbiBrbihuKXtyZXR1cm4gbj1Tbih7fSxuKSxmdW5jdGlvbihyKXtyZXR1cm4gcm4ocixuKX19ZnVuY3Rpb24gRG4obil7cmV0dXJuIG49Qm4obiksZnVuY3Rpb24ocil7cmV0dXJuIE5uKHIsbil9fWZ1bmN0aW9uIFJuKG4scix0KXtpZih2b2lkIDA9PT1yKXJldHVybiBuO3N3aXRjaChudWxsPT10PzM6dCl7Y2FzZSAxOnJldHVybiBmdW5jdGlvbih0KXtyZXR1cm4gbi5jYWxsKHIsdCl9O2Nhc2UgMzpyZXR1cm4gZnVuY3Rpb24odCxlLHUpe3JldHVybiBuLmNhbGwocix0LGUsdSl9O2Nhc2UgNDpyZXR1cm4gZnVuY3Rpb24odCxlLHUsbyl7cmV0dXJuIG4uY2FsbChyLHQsZSx1LG8pfX1yZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gbi5hcHBseShyLGFyZ3VtZW50cyl9fWZ1bmN0aW9uIEZuKG4scix0KXtyZXR1cm4gbnVsbD09bj9UbjpEKG4pP1JuKG4scix0KTpfKG4pJiYhVShuKT9rbihuKTpEbihuKX1mdW5jdGlvbiBWbihuLHIpe3JldHVybiBGbihuLHIsMS8wKX1mdW5jdGlvbiBQbihuLHIsdCl7cmV0dXJuIHRuLml0ZXJhdGVlIT09Vm4/dG4uaXRlcmF0ZWUobixyKTpGbihuLHIsdCl9ZnVuY3Rpb24gcW4oKXt9ZnVuY3Rpb24gVW4obixyKXtyZXR1cm4gbnVsbD09ciYmKHI9bixuPTApLG4rTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpKihyLW4rMSkpfXRuLnRvUGF0aD1Fbix0bi5pdGVyYXRlZT1Wbjt2YXIgV249RGF0ZS5ub3d8fGZ1bmN0aW9uKCl7cmV0dXJuKG5ldyBEYXRlKS5nZXRUaW1lKCl9O2Z1bmN0aW9uIHpuKG4pe3ZhciByPWZ1bmN0aW9uKHIpe3JldHVybiBuW3JdfSx0PSIoPzoiK25uKG4pLmpvaW4oInwiKSsiKSIsZT1SZWdFeHAodCksdT1SZWdFeHAodCwiZyIpO3JldHVybiBmdW5jdGlvbihuKXtyZXR1cm4gbj1udWxsPT1uPyIiOiIiK24sZS50ZXN0KG4pP24ucmVwbGFjZSh1LHIpOm59fXZhciBMbj17IiYiOiImYW1wOyIsIjwiOiImbHQ7IiwiPiI6IiZndDsiLCciJzoiJnF1b3Q7IiwiJyI6IiYjeDI3OyIsImAiOiImI3g2MDsifSwkbj16bihMbiksQ249em4oX24oTG4pKSxLbj10bi50ZW1wbGF0ZVNldHRpbmdzPXtldmFsdWF0ZTovPCUoW1xzXFNdKz8pJT4vZyxpbnRlcnBvbGF0ZTovPCU9KFtcc1xTXSs/KSU+L2csZXNjYXBlOi88JS0oW1xzXFNdKz8pJT4vZ30sSm49LyguKV4vLEduPXsiJyI6IiciLCJcXCI6IlxcIiwiXHIiOiJyIiwiXG4iOiJuIiwiXHUyMDI4IjoidTIwMjgiLCJcdTIwMjkiOiJ1MjAyOSJ9LEhuPS9cXHwnfFxyfFxufFx1MjAyOHxcdTIwMjkvZztmdW5jdGlvbiBRbihuKXtyZXR1cm4iXFwiK0duW25dfXZhciBYbj0vXlxzKihcd3xcJCkrXHMqJC87dmFyIFluPTA7ZnVuY3Rpb24gWm4obixyLHQsZSx1KXtpZighKGUgaW5zdGFuY2VvZiByKSlyZXR1cm4gbi5hcHBseSh0LHUpO3ZhciBvPU1uKG4ucHJvdG90eXBlKSxpPW4uYXBwbHkobyx1KTtyZXR1cm4gXyhpKT9pOm99dmFyIG5yPWooKGZ1bmN0aW9uKG4scil7dmFyIHQ9bnIucGxhY2Vob2xkZXIsZT1mdW5jdGlvbigpe2Zvcih2YXIgdT0wLG89ci5sZW5ndGgsaT1BcnJheShvKSxhPTA7YTxvO2ErKylpW2FdPXJbYV09PT10P2FyZ3VtZW50c1t1KytdOnJbYV07Zm9yKDt1PGFyZ3VtZW50cy5sZW5ndGg7KWkucHVzaChhcmd1bWVudHNbdSsrXSk7cmV0dXJuIFpuKG4sZSx0aGlzLHRoaXMsaSl9O3JldHVybiBlfSkpO25yLnBsYWNlaG9sZGVyPXRuO3ZhciBycj1qKChmdW5jdGlvbihuLHIsdCl7aWYoIUQobikpdGhyb3cgbmV3IFR5cGVFcnJvcigiQmluZCBtdXN0IGJlIGNhbGxlZCBvbiBhIGZ1bmN0aW9uIik7dmFyIGU9aigoZnVuY3Rpb24odSl7cmV0dXJuIFpuKG4sZSxyLHRoaXMsdC5jb25jYXQodSkpfSkpO3JldHVybiBlfSkpLHRyPUsoWSk7ZnVuY3Rpb24gZXIobixyLHQsZSl7aWYoZT1lfHxbXSxyfHwwPT09cil7aWYocjw9MClyZXR1cm4gZS5jb25jYXQobil9ZWxzZSByPTEvMDtmb3IodmFyIHU9ZS5sZW5ndGgsbz0wLGk9WShuKTtvPGk7bysrKXt2YXIgYT1uW29dO2lmKHRyKGEpJiYoVShhKXx8TChhKSkpaWYocj4xKWVyKGEsci0xLHQsZSksdT1lLmxlbmd0aDtlbHNlIGZvcih2YXIgZj0wLGM9YS5sZW5ndGg7ZjxjOyllW3UrK109YVtmKytdO2Vsc2UgdHx8KGVbdSsrXT1hKX1yZXR1cm4gZX12YXIgdXI9aigoZnVuY3Rpb24obixyKXt2YXIgdD0ocj1lcihyLCExLCExKSkubGVuZ3RoO2lmKHQ8MSl0aHJvdyBuZXcgRXJyb3IoImJpbmRBbGwgbXVzdCBiZSBwYXNzZWQgZnVuY3Rpb24gbmFtZXMiKTtmb3IoO3QtLTspe3ZhciBlPXJbdF07bltlXT1ycihuW2VdLG4pfXJldHVybiBufSkpO3ZhciBvcj1qKChmdW5jdGlvbihuLHIsdCl7cmV0dXJuIHNldFRpbWVvdXQoKGZ1bmN0aW9uKCl7cmV0dXJuIG4uYXBwbHkobnVsbCx0KX0pLHIpfSkpLGlyPW5yKG9yLHRuLDEpO2Z1bmN0aW9uIGFyKG4pe3JldHVybiBmdW5jdGlvbigpe3JldHVybiFuLmFwcGx5KHRoaXMsYXJndW1lbnRzKX19ZnVuY3Rpb24gZnIobixyKXt2YXIgdDtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4tLW4+MCYmKHQ9ci5hcHBseSh0aGlzLGFyZ3VtZW50cykpLG48PTEmJihyPW51bGwpLHR9fXZhciBjcj1ucihmciwyKTtmdW5jdGlvbiBscihuLHIsdCl7cj1QbihyLHQpO2Zvcih2YXIgZSx1PW5uKG4pLG89MCxpPXUubGVuZ3RoO288aTtvKyspaWYocihuW2U9dVtvXV0sZSxuKSlyZXR1cm4gZX1mdW5jdGlvbiBzcihuKXtyZXR1cm4gZnVuY3Rpb24ocix0LGUpe3Q9UG4odCxlKTtmb3IodmFyIHU9WShyKSxvPW4+MD8wOnUtMTtvPj0wJiZvPHU7bys9bilpZih0KHJbb10sbyxyKSlyZXR1cm4gbztyZXR1cm4tMX19dmFyIHByPXNyKDEpLHZyPXNyKC0xKTtmdW5jdGlvbiBocihuLHIsdCxlKXtmb3IodmFyIHU9KHQ9UG4odCxlLDEpKShyKSxvPTAsaT1ZKG4pO288aTspe3ZhciBhPU1hdGguZmxvb3IoKG8raSkvMik7dChuW2FdKTx1P289YSsxOmk9YX1yZXR1cm4gb31mdW5jdGlvbiB5cihuLHIsdCl7cmV0dXJuIGZ1bmN0aW9uKGUsdSxvKXt2YXIgYT0wLGY9WShlKTtpZigibnVtYmVyIj09dHlwZW9mIG8pbj4wP2E9bz49MD9vOk1hdGgubWF4KG8rZixhKTpmPW8+PTA/TWF0aC5taW4obysxLGYpOm8rZisxO2Vsc2UgaWYodCYmbyYmZilyZXR1cm4gZVtvPXQoZSx1KV09PT11P286LTE7aWYodSE9dSlyZXR1cm4obz1yKGkuY2FsbChlLGEsZiksJCkpPj0wP28rYTotMTtmb3Iobz1uPjA/YTpmLTE7bz49MCYmbzxmO28rPW4paWYoZVtvXT09PXUpcmV0dXJuIG87cmV0dXJuLTF9fXZhciBkcj15cigxLHByLGhyKSxncj15cigtMSx2cik7ZnVuY3Rpb24gYnIobixyLHQpe3ZhciBlPSh0cihuKT9wcjpscikobixyLHQpO2lmKHZvaWQgMCE9PWUmJi0xIT09ZSlyZXR1cm4gbltlXX1mdW5jdGlvbiBtcihuLHIsdCl7dmFyIGUsdTtpZihyPVJuKHIsdCksdHIobikpZm9yKGU9MCx1PW4ubGVuZ3RoO2U8dTtlKyspcihuW2VdLGUsbik7ZWxzZXt2YXIgbz1ubihuKTtmb3IoZT0wLHU9by5sZW5ndGg7ZTx1O2UrKylyKG5bb1tlXV0sb1tlXSxuKX1yZXR1cm4gbn1mdW5jdGlvbiBqcihuLHIsdCl7cj1QbihyLHQpO2Zvcih2YXIgZT0hdHIobikmJm5uKG4pLHU9KGV8fG4pLmxlbmd0aCxvPUFycmF5KHUpLGk9MDtpPHU7aSsrKXt2YXIgYT1lP2VbaV06aTtvW2ldPXIoblthXSxhLG4pfXJldHVybiBvfWZ1bmN0aW9uIF9yKG4pe3ZhciByPWZ1bmN0aW9uKHIsdCxlLHUpe3ZhciBvPSF0cihyKSYmbm4ociksaT0ob3x8cikubGVuZ3RoLGE9bj4wPzA6aS0xO2Zvcih1fHwoZT1yW28/b1thXTphXSxhKz1uKTthPj0wJiZhPGk7YSs9bil7dmFyIGY9bz9vW2FdOmE7ZT10KGUscltmXSxmLHIpfXJldHVybiBlfTtyZXR1cm4gZnVuY3Rpb24obix0LGUsdSl7dmFyIG89YXJndW1lbnRzLmxlbmd0aD49MztyZXR1cm4gcihuLFJuKHQsdSw0KSxlLG8pfX12YXIgd3I9X3IoMSksQXI9X3IoLTEpO2Z1bmN0aW9uIHhyKG4scix0KXt2YXIgZT1bXTtyZXR1cm4gcj1QbihyLHQpLG1yKG4sKGZ1bmN0aW9uKG4sdCx1KXtyKG4sdCx1KSYmZS5wdXNoKG4pfSkpLGV9ZnVuY3Rpb24gU3IobixyLHQpe3I9UG4ocix0KTtmb3IodmFyIGU9IXRyKG4pJiZubihuKSx1PShlfHxuKS5sZW5ndGgsbz0wO288dTtvKyspe3ZhciBpPWU/ZVtvXTpvO2lmKCFyKG5baV0saSxuKSlyZXR1cm4hMX1yZXR1cm4hMH1mdW5jdGlvbiBPcihuLHIsdCl7cj1QbihyLHQpO2Zvcih2YXIgZT0hdHIobikmJm5uKG4pLHU9KGV8fG4pLmxlbmd0aCxvPTA7bzx1O28rKyl7dmFyIGk9ZT9lW29dOm87aWYocihuW2ldLGksbikpcmV0dXJuITB9cmV0dXJuITF9ZnVuY3Rpb24gTXIobixyLHQsZSl7cmV0dXJuIHRyKG4pfHwobj1qbihuKSksKCJudW1iZXIiIT10eXBlb2YgdHx8ZSkmJih0PTApLGRyKG4scix0KT49MH12YXIgRXI9aigoZnVuY3Rpb24obixyLHQpe3ZhciBlLHU7cmV0dXJuIEQocik/dT1yOihyPUJuKHIpLGU9ci5zbGljZSgwLC0xKSxyPXJbci5sZW5ndGgtMV0pLGpyKG4sKGZ1bmN0aW9uKG4pe3ZhciBvPXU7aWYoIW8pe2lmKGUmJmUubGVuZ3RoJiYobj1ObihuLGUpKSxudWxsPT1uKXJldHVybjtvPW5bcl19cmV0dXJuIG51bGw9PW8/bzpvLmFwcGx5KG4sdCl9KSl9KSk7ZnVuY3Rpb24gQnIobixyKXtyZXR1cm4ganIobixEbihyKSl9ZnVuY3Rpb24gTnIobixyLHQpe3ZhciBlLHUsbz0tMS8wLGk9LTEvMDtpZihudWxsPT1yfHwibnVtYmVyIj09dHlwZW9mIHImJiJvYmplY3QiIT10eXBlb2YgblswXSYmbnVsbCE9bilmb3IodmFyIGE9MCxmPShuPXRyKG4pP246am4obikpLmxlbmd0aDthPGY7YSsrKW51bGwhPShlPW5bYV0pJiZlPm8mJihvPWUpO2Vsc2Ugcj1QbihyLHQpLG1yKG4sKGZ1bmN0aW9uKG4sdCxlKXsoKHU9cihuLHQsZSkpPml8fHU9PT0tMS8wJiZvPT09LTEvMCkmJihvPW4saT11KX0pKTtyZXR1cm4gb312YXIgSXI9L1teXHVkODAwLVx1ZGZmZl18W1x1ZDgwMC1cdWRiZmZdW1x1ZGMwMC1cdWRmZmZdfFtcdWQ4MDAtXHVkZmZmXS9nO2Z1bmN0aW9uIFRyKG4pe3JldHVybiBuP1Uobik/aS5jYWxsKG4pOlMobik/bi5tYXRjaChJcik6dHIobik/anIobixUbik6am4obik6W119ZnVuY3Rpb24ga3IobixyLHQpe2lmKG51bGw9PXJ8fHQpcmV0dXJuIHRyKG4pfHwobj1qbihuKSksbltVbihuLmxlbmd0aC0xKV07dmFyIGU9VHIobiksdT1ZKGUpO3I9TWF0aC5tYXgoTWF0aC5taW4ocix1KSwwKTtmb3IodmFyIG89dS0xLGk9MDtpPHI7aSsrKXt2YXIgYT1VbihpLG8pLGY9ZVtpXTtlW2ldPWVbYV0sZVthXT1mfXJldHVybiBlLnNsaWNlKDAscil9ZnVuY3Rpb24gRHIobixyKXtyZXR1cm4gZnVuY3Rpb24odCxlLHUpe3ZhciBvPXI/W1tdLFtdXTp7fTtyZXR1cm4gZT1QbihlLHUpLG1yKHQsKGZ1bmN0aW9uKHIsdSl7dmFyIGk9ZShyLHUsdCk7bihvLHIsaSl9KSksb319dmFyIFJyPURyKChmdW5jdGlvbihuLHIsdCl7VyhuLHQpP25bdF0ucHVzaChyKTpuW3RdPVtyXX0pKSxGcj1EcigoZnVuY3Rpb24obixyLHQpe25bdF09cn0pKSxWcj1EcigoZnVuY3Rpb24obixyLHQpe1cobix0KT9uW3RdKys6blt0XT0xfSkpLFByPURyKChmdW5jdGlvbihuLHIsdCl7blt0PzA6MV0ucHVzaChyKX0pLCEwKTtmdW5jdGlvbiBxcihuLHIsdCl7cmV0dXJuIHIgaW4gdH12YXIgVXI9aigoZnVuY3Rpb24obixyKXt2YXIgdD17fSxlPXJbMF07aWYobnVsbD09bilyZXR1cm4gdDtEKGUpPyhyLmxlbmd0aD4xJiYoZT1SbihlLHJbMV0pKSxyPWFuKG4pKTooZT1xcixyPWVyKHIsITEsITEpLG49T2JqZWN0KG4pKTtmb3IodmFyIHU9MCxvPXIubGVuZ3RoO3U8bzt1Kyspe3ZhciBpPXJbdV0sYT1uW2ldO2UoYSxpLG4pJiYodFtpXT1hKX1yZXR1cm4gdH0pKSxXcj1qKChmdW5jdGlvbihuLHIpe3ZhciB0LGU9clswXTtyZXR1cm4gRChlKT8oZT1hcihlKSxyLmxlbmd0aD4xJiYodD1yWzFdKSk6KHI9anIoZXIociwhMSwhMSksU3RyaW5nKSxlPWZ1bmN0aW9uKG4sdCl7cmV0dXJuIU1yKHIsdCl9KSxVcihuLGUsdCl9KSk7ZnVuY3Rpb24genIobixyLHQpe3JldHVybiBpLmNhbGwobiwwLE1hdGgubWF4KDAsbi5sZW5ndGgtKG51bGw9PXJ8fHQ/MTpyKSkpfWZ1bmN0aW9uIExyKG4scix0KXtyZXR1cm4gbnVsbD09bnx8bi5sZW5ndGg8MT9udWxsPT1yfHx0P3ZvaWQgMDpbXTpudWxsPT1yfHx0P25bMF06enIobixuLmxlbmd0aC1yKX1mdW5jdGlvbiAkcihuLHIsdCl7cmV0dXJuIGkuY2FsbChuLG51bGw9PXJ8fHQ/MTpyKX12YXIgQ3I9aigoZnVuY3Rpb24obixyKXtyZXR1cm4gcj1lcihyLCEwLCEwKSx4cihuLChmdW5jdGlvbihuKXtyZXR1cm4hTXIocixuKX0pKX0pKSxLcj1qKChmdW5jdGlvbihuLHIpe3JldHVybiBDcihuLHIpfSkpO2Z1bmN0aW9uIEpyKG4scix0LGUpe0Eocil8fChlPXQsdD1yLHI9ITEpLG51bGwhPXQmJih0PVBuKHQsZSkpO2Zvcih2YXIgdT1bXSxvPVtdLGk9MCxhPVkobik7aTxhO2krKyl7dmFyIGY9bltpXSxjPXQ/dChmLGksbik6ZjtyJiYhdD8oaSYmbz09PWN8fHUucHVzaChmKSxvPWMpOnQ/TXIobyxjKXx8KG8ucHVzaChjKSx1LnB1c2goZikpOk1yKHUsZil8fHUucHVzaChmKX1yZXR1cm4gdX12YXIgR3I9aigoZnVuY3Rpb24obil7cmV0dXJuIEpyKGVyKG4sITAsITApKX0pKTtmdW5jdGlvbiBIcihuKXtmb3IodmFyIHI9biYmTnIobixZKS5sZW5ndGh8fDAsdD1BcnJheShyKSxlPTA7ZTxyO2UrKyl0W2VdPUJyKG4sZSk7cmV0dXJuIHR9dmFyIFFyPWooSHIpO2Z1bmN0aW9uIFhyKG4scil7cmV0dXJuIG4uX2NoYWluP3RuKHIpLmNoYWluKCk6cn1mdW5jdGlvbiBZcihuKXtyZXR1cm4gbXIod24obiksKGZ1bmN0aW9uKHIpe3ZhciB0PXRuW3JdPW5bcl07dG4ucHJvdG90eXBlW3JdPWZ1bmN0aW9uKCl7dmFyIG49W3RoaXMuX3dyYXBwZWRdO3JldHVybiBvLmFwcGx5KG4sYXJndW1lbnRzKSxYcih0aGlzLHQuYXBwbHkodG4sbikpfX0pKSx0bn1tcihbInBvcCIsInB1c2giLCJyZXZlcnNlIiwic2hpZnQiLCJzb3J0Iiwic3BsaWNlIiwidW5zaGlmdCJdLChmdW5jdGlvbihuKXt2YXIgcj10W25dO3RuLnByb3RvdHlwZVtuXT1mdW5jdGlvbigpe3ZhciB0PXRoaXMuX3dyYXBwZWQ7cmV0dXJuIG51bGwhPXQmJihyLmFwcGx5KHQsYXJndW1lbnRzKSwic2hpZnQiIT09biYmInNwbGljZSIhPT1ufHwwIT09dC5sZW5ndGh8fGRlbGV0ZSB0WzBdKSxYcih0aGlzLHQpfX0pKSxtcihbImNvbmNhdCIsImpvaW4iLCJzbGljZSJdLChmdW5jdGlvbihuKXt2YXIgcj10W25dO3RuLnByb3RvdHlwZVtuXT1mdW5jdGlvbigpe3ZhciBuPXRoaXMuX3dyYXBwZWQ7cmV0dXJuIG51bGwhPW4mJihuPXIuYXBwbHkobixhcmd1bWVudHMpKSxYcih0aGlzLG4pfX0pKTt2YXIgWnI9WXIoe19fcHJvdG9fXzpudWxsLFZFUlNJT046bixyZXN0QXJndW1lbnRzOmosaXNPYmplY3Q6Xyxpc051bGw6ZnVuY3Rpb24obil7cmV0dXJuIG51bGw9PT1ufSxpc1VuZGVmaW5lZDp3LGlzQm9vbGVhbjpBLGlzRWxlbWVudDpmdW5jdGlvbihuKXtyZXR1cm4hKCFufHwxIT09bi5ub2RlVHlwZSl9LGlzU3RyaW5nOlMsaXNOdW1iZXI6Tyxpc0RhdGU6TSxpc1JlZ0V4cDpFLGlzRXJyb3I6Qixpc1N5bWJvbDpOLGlzQXJyYXlCdWZmZXI6SSxpc0RhdGFWaWV3OnEsaXNBcnJheTpVLGlzRnVuY3Rpb246RCxpc0FyZ3VtZW50czpMLGlzRmluaXRlOmZ1bmN0aW9uKG4pe3JldHVybiFOKG4pJiZkKG4pJiYhaXNOYU4ocGFyc2VGbG9hdChuKSl9LGlzTmFOOiQsaXNUeXBlZEFycmF5OlgsaXNFbXB0eTpmdW5jdGlvbihuKXtpZihudWxsPT1uKXJldHVybiEwO3ZhciByPVkobik7cmV0dXJuIm51bWJlciI9PXR5cGVvZiByJiYoVShuKXx8UyhuKXx8TChuKSk/MD09PXI6MD09PVkobm4obikpfSxpc01hdGNoOnJuLGlzRXF1YWw6ZnVuY3Rpb24obixyKXtyZXR1cm4gb24obixyKX0saXNNYXA6ZG4saXNXZWFrTWFwOmduLGlzU2V0OmJuLGlzV2Vha1NldDptbixrZXlzOm5uLGFsbEtleXM6YW4sdmFsdWVzOmpuLHBhaXJzOmZ1bmN0aW9uKG4pe2Zvcih2YXIgcj1ubihuKSx0PXIubGVuZ3RoLGU9QXJyYXkodCksdT0wO3U8dDt1KyspZVt1XT1bclt1XSxuW3JbdV1dXTtyZXR1cm4gZX0saW52ZXJ0Ol9uLGZ1bmN0aW9uczp3bixtZXRob2RzOnduLGV4dGVuZDp4bixleHRlbmRPd246U24sYXNzaWduOlNuLGRlZmF1bHRzOk9uLGNyZWF0ZTpmdW5jdGlvbihuLHIpe3ZhciB0PU1uKG4pO3JldHVybiByJiZTbih0LHIpLHR9LGNsb25lOmZ1bmN0aW9uKG4pe3JldHVybiBfKG4pP1Uobik/bi5zbGljZSgpOnhuKHt9LG4pOm59LHRhcDpmdW5jdGlvbihuLHIpe3JldHVybiByKG4pLG59LGdldDpJbixoYXM6ZnVuY3Rpb24obixyKXtmb3IodmFyIHQ9KHI9Qm4ocikpLmxlbmd0aCxlPTA7ZTx0O2UrKyl7dmFyIHU9cltlXTtpZighVyhuLHUpKXJldHVybiExO249blt1XX1yZXR1cm4hIXR9LG1hcE9iamVjdDpmdW5jdGlvbihuLHIsdCl7cj1QbihyLHQpO2Zvcih2YXIgZT1ubihuKSx1PWUubGVuZ3RoLG89e30saT0wO2k8dTtpKyspe3ZhciBhPWVbaV07b1thXT1yKG5bYV0sYSxuKX1yZXR1cm4gb30saWRlbnRpdHk6VG4sY29uc3RhbnQ6Qyxub29wOnFuLHRvUGF0aDpFbixwcm9wZXJ0eTpEbixwcm9wZXJ0eU9mOmZ1bmN0aW9uKG4pe3JldHVybiBudWxsPT1uP3FuOmZ1bmN0aW9uKHIpe3JldHVybiBJbihuLHIpfX0sbWF0Y2hlcjprbixtYXRjaGVzOmtuLHRpbWVzOmZ1bmN0aW9uKG4scix0KXt2YXIgZT1BcnJheShNYXRoLm1heCgwLG4pKTtyPVJuKHIsdCwxKTtmb3IodmFyIHU9MDt1PG47dSsrKWVbdV09cih1KTtyZXR1cm4gZX0scmFuZG9tOlVuLG5vdzpXbixlc2NhcGU6JG4sdW5lc2NhcGU6Q24sdGVtcGxhdGVTZXR0aW5nczpLbix0ZW1wbGF0ZTpmdW5jdGlvbihuLHIsdCl7IXImJnQmJihyPXQpLHI9T24oe30scix0bi50ZW1wbGF0ZVNldHRpbmdzKTt2YXIgZT1SZWdFeHAoWyhyLmVzY2FwZXx8Sm4pLnNvdXJjZSwoci5pbnRlcnBvbGF0ZXx8Sm4pLnNvdXJjZSwoci5ldmFsdWF0ZXx8Sm4pLnNvdXJjZV0uam9pbigifCIpKyJ8JCIsImciKSx1PTAsbz0iX19wKz0nIjtuLnJlcGxhY2UoZSwoZnVuY3Rpb24ocix0LGUsaSxhKXtyZXR1cm4gbys9bi5zbGljZSh1LGEpLnJlcGxhY2UoSG4sUW4pLHU9YStyLmxlbmd0aCx0P28rPSInK1xuKChfX3Q9KCIrdCsiKSk9PW51bGw/Jyc6Xy5lc2NhcGUoX190KSkrXG4nIjplP28rPSInK1xuKChfX3Q9KCIrZSsiKSk9PW51bGw/Jyc6X190KStcbiciOmkmJihvKz0iJztcbiIraSsiXG5fX3ArPSciKSxyfSkpLG8rPSInO1xuIjt2YXIgaSxhPXIudmFyaWFibGU7aWYoYSl7aWYoIVhuLnRlc3QoYSkpdGhyb3cgbmV3IEVycm9yKCJ2YXJpYWJsZSBpcyBub3QgYSBiYXJlIGlkZW50aWZpZXI6ICIrYSl9ZWxzZSBvPSJ3aXRoKG9ianx8e30pe1xuIitvKyJ9XG4iLGE9Im9iaiI7bz0idmFyIF9fdCxfX3A9JycsX19qPUFycmF5LnByb3RvdHlwZS5qb2luLCIrInByaW50PWZ1bmN0aW9uKCl7X19wKz1fX2ouY2FsbChhcmd1bWVudHMsJycpO307XG4iK28rInJldHVybiBfX3A7XG4iO3RyeXtpPW5ldyBGdW5jdGlvbihhLCJfIixvKX1jYXRjaChuKXt0aHJvdyBuLnNvdXJjZT1vLG59dmFyIGY9ZnVuY3Rpb24obil7cmV0dXJuIGkuY2FsbCh0aGlzLG4sdG4pfTtyZXR1cm4gZi5zb3VyY2U9ImZ1bmN0aW9uKCIrYSsiKXtcbiIrbysifSIsZn0scmVzdWx0OmZ1bmN0aW9uKG4scix0KXt2YXIgZT0ocj1CbihyKSkubGVuZ3RoO2lmKCFlKXJldHVybiBEKHQpP3QuY2FsbChuKTp0O2Zvcih2YXIgdT0wO3U8ZTt1Kyspe3ZhciBvPW51bGw9PW4/dm9pZCAwOm5bclt1XV07dm9pZCAwPT09byYmKG89dCx1PWUpLG49RChvKT9vLmNhbGwobik6b31yZXR1cm4gbn0sdW5pcXVlSWQ6ZnVuY3Rpb24obil7dmFyIHI9KytZbisiIjtyZXR1cm4gbj9uK3I6cn0sY2hhaW46ZnVuY3Rpb24obil7dmFyIHI9dG4obik7cmV0dXJuIHIuX2NoYWluPSEwLHJ9LGl0ZXJhdGVlOlZuLHBhcnRpYWw6bnIsYmluZDpycixiaW5kQWxsOnVyLG1lbW9pemU6ZnVuY3Rpb24obixyKXt2YXIgdD1mdW5jdGlvbihlKXt2YXIgdT10LmNhY2hlLG89IiIrKHI/ci5hcHBseSh0aGlzLGFyZ3VtZW50cyk6ZSk7cmV0dXJuIFcodSxvKXx8KHVbb109bi5hcHBseSh0aGlzLGFyZ3VtZW50cykpLHVbb119O3JldHVybiB0LmNhY2hlPXt9LHR9LGRlbGF5Om9yLGRlZmVyOmlyLHRocm90dGxlOmZ1bmN0aW9uKG4scix0KXt2YXIgZSx1LG8saSxhPTA7dHx8KHQ9e30pO3ZhciBmPWZ1bmN0aW9uKCl7YT0hMT09PXQubGVhZGluZz8wOlduKCksZT1udWxsLGk9bi5hcHBseSh1LG8pLGV8fCh1PW89bnVsbCl9LGM9ZnVuY3Rpb24oKXt2YXIgYz1XbigpO2F8fCExIT09dC5sZWFkaW5nfHwoYT1jKTt2YXIgbD1yLShjLWEpO3JldHVybiB1PXRoaXMsbz1hcmd1bWVudHMsbDw9MHx8bD5yPyhlJiYoY2xlYXJUaW1lb3V0KGUpLGU9bnVsbCksYT1jLGk9bi5hcHBseSh1LG8pLGV8fCh1PW89bnVsbCkpOmV8fCExPT09dC50cmFpbGluZ3x8KGU9c2V0VGltZW91dChmLGwpKSxpfTtyZXR1cm4gYy5jYW5jZWw9ZnVuY3Rpb24oKXtjbGVhclRpbWVvdXQoZSksYT0wLGU9dT1vPW51bGx9LGN9LGRlYm91bmNlOmZ1bmN0aW9uKG4scix0KXt2YXIgZSx1LG8saSxhLGY9ZnVuY3Rpb24oKXt2YXIgYz1XbigpLXU7cj5jP2U9c2V0VGltZW91dChmLHItYyk6KGU9bnVsbCx0fHwoaT1uLmFwcGx5KGEsbykpLGV8fChvPWE9bnVsbCkpfSxjPWooKGZ1bmN0aW9uKGMpe3JldHVybiBhPXRoaXMsbz1jLHU9V24oKSxlfHwoZT1zZXRUaW1lb3V0KGYsciksdCYmKGk9bi5hcHBseShhLG8pKSksaX0pKTtyZXR1cm4gYy5jYW5jZWw9ZnVuY3Rpb24oKXtjbGVhclRpbWVvdXQoZSksZT1vPWE9bnVsbH0sY30sd3JhcDpmdW5jdGlvbihuLHIpe3JldHVybiBucihyLG4pfSxuZWdhdGU6YXIsY29tcG9zZTpmdW5jdGlvbigpe3ZhciBuPWFyZ3VtZW50cyxyPW4ubGVuZ3RoLTE7cmV0dXJuIGZ1bmN0aW9uKCl7Zm9yKHZhciB0PXIsZT1uW3JdLmFwcGx5KHRoaXMsYXJndW1lbnRzKTt0LS07KWU9blt0XS5jYWxsKHRoaXMsZSk7cmV0dXJuIGV9fSxhZnRlcjpmdW5jdGlvbihuLHIpe3JldHVybiBmdW5jdGlvbigpe2lmKC0tbjwxKXJldHVybiByLmFwcGx5KHRoaXMsYXJndW1lbnRzKX19LGJlZm9yZTpmcixvbmNlOmNyLGZpbmRLZXk6bHIsZmluZEluZGV4OnByLGZpbmRMYXN0SW5kZXg6dnIsc29ydGVkSW5kZXg6aHIsaW5kZXhPZjpkcixsYXN0SW5kZXhPZjpncixmaW5kOmJyLGRldGVjdDpicixmaW5kV2hlcmU6ZnVuY3Rpb24obixyKXtyZXR1cm4gYnIobixrbihyKSl9LGVhY2g6bXIsZm9yRWFjaDptcixtYXA6anIsY29sbGVjdDpqcixyZWR1Y2U6d3IsZm9sZGw6d3IsaW5qZWN0OndyLHJlZHVjZVJpZ2h0OkFyLGZvbGRyOkFyLGZpbHRlcjp4cixzZWxlY3Q6eHIscmVqZWN0OmZ1bmN0aW9uKG4scix0KXtyZXR1cm4geHIobixhcihQbihyKSksdCl9LGV2ZXJ5OlNyLGFsbDpTcixzb21lOk9yLGFueTpPcixjb250YWluczpNcixpbmNsdWRlczpNcixpbmNsdWRlOk1yLGludm9rZTpFcixwbHVjazpCcix3aGVyZTpmdW5jdGlvbihuLHIpe3JldHVybiB4cihuLGtuKHIpKX0sbWF4Ok5yLG1pbjpmdW5jdGlvbihuLHIsdCl7dmFyIGUsdSxvPTEvMCxpPTEvMDtpZihudWxsPT1yfHwibnVtYmVyIj09dHlwZW9mIHImJiJvYmplY3QiIT10eXBlb2YgblswXSYmbnVsbCE9bilmb3IodmFyIGE9MCxmPShuPXRyKG4pP246am4obikpLmxlbmd0aDthPGY7YSsrKW51bGwhPShlPW5bYV0pJiZlPG8mJihvPWUpO2Vsc2Ugcj1QbihyLHQpLG1yKG4sKGZ1bmN0aW9uKG4sdCxlKXsoKHU9cihuLHQsZSkpPGl8fHU9PT0xLzAmJm89PT0xLzApJiYobz1uLGk9dSl9KSk7cmV0dXJuIG99LHNodWZmbGU6ZnVuY3Rpb24obil7cmV0dXJuIGtyKG4sMS8wKX0sc2FtcGxlOmtyLHNvcnRCeTpmdW5jdGlvbihuLHIsdCl7dmFyIGU9MDtyZXR1cm4gcj1QbihyLHQpLEJyKGpyKG4sKGZ1bmN0aW9uKG4sdCx1KXtyZXR1cm57dmFsdWU6bixpbmRleDplKyssY3JpdGVyaWE6cihuLHQsdSl9fSkpLnNvcnQoKGZ1bmN0aW9uKG4scil7dmFyIHQ9bi5jcml0ZXJpYSxlPXIuY3JpdGVyaWE7aWYodCE9PWUpe2lmKHQ+ZXx8dm9pZCAwPT09dClyZXR1cm4gMTtpZih0PGV8fHZvaWQgMD09PWUpcmV0dXJuLTF9cmV0dXJuIG4uaW5kZXgtci5pbmRleH0pKSwidmFsdWUiKX0sZ3JvdXBCeTpScixpbmRleEJ5OkZyLGNvdW50Qnk6VnIscGFydGl0aW9uOlByLHRvQXJyYXk6VHIsc2l6ZTpmdW5jdGlvbihuKXtyZXR1cm4gbnVsbD09bj8wOnRyKG4pP24ubGVuZ3RoOm5uKG4pLmxlbmd0aH0scGljazpVcixvbWl0OldyLGZpcnN0OkxyLGhlYWQ6THIsdGFrZTpMcixpbml0aWFsOnpyLGxhc3Q6ZnVuY3Rpb24obixyLHQpe3JldHVybiBudWxsPT1ufHxuLmxlbmd0aDwxP251bGw9PXJ8fHQ/dm9pZCAwOltdOm51bGw9PXJ8fHQ/bltuLmxlbmd0aC0xXTokcihuLE1hdGgubWF4KDAsbi5sZW5ndGgtcikpfSxyZXN0OiRyLHRhaWw6JHIsZHJvcDokcixjb21wYWN0OmZ1bmN0aW9uKG4pe3JldHVybiB4cihuLEJvb2xlYW4pfSxmbGF0dGVuOmZ1bmN0aW9uKG4scil7cmV0dXJuIGVyKG4sciwhMSl9LHdpdGhvdXQ6S3IsdW5pcTpKcix1bmlxdWU6SnIsdW5pb246R3IsaW50ZXJzZWN0aW9uOmZ1bmN0aW9uKG4pe2Zvcih2YXIgcj1bXSx0PWFyZ3VtZW50cy5sZW5ndGgsZT0wLHU9WShuKTtlPHU7ZSsrKXt2YXIgbz1uW2VdO2lmKCFNcihyLG8pKXt2YXIgaTtmb3IoaT0xO2k8dCYmTXIoYXJndW1lbnRzW2ldLG8pO2krKyk7aT09PXQmJnIucHVzaChvKX19cmV0dXJuIHJ9LGRpZmZlcmVuY2U6Q3IsdW56aXA6SHIsdHJhbnNwb3NlOkhyLHppcDpRcixvYmplY3Q6ZnVuY3Rpb24obixyKXtmb3IodmFyIHQ9e30sZT0wLHU9WShuKTtlPHU7ZSsrKXI/dFtuW2VdXT1yW2VdOnRbbltlXVswXV09bltlXVsxXTtyZXR1cm4gdH0scmFuZ2U6ZnVuY3Rpb24obixyLHQpe251bGw9PXImJihyPW58fDAsbj0wKSx0fHwodD1yPG4/LTE6MSk7Zm9yKHZhciBlPU1hdGgubWF4KE1hdGguY2VpbCgoci1uKS90KSwwKSx1PUFycmF5KGUpLG89MDtvPGU7bysrLG4rPXQpdVtvXT1uO3JldHVybiB1fSxjaHVuazpmdW5jdGlvbihuLHIpe2lmKG51bGw9PXJ8fHI8MSlyZXR1cm5bXTtmb3IodmFyIHQ9W10sZT0wLHU9bi5sZW5ndGg7ZTx1Oyl0LnB1c2goaS5jYWxsKG4sZSxlKz1yKSk7cmV0dXJuIHR9LG1peGluOllyLGRlZmF1bHQ6dG59KTtyZXR1cm4gWnIuXz1acixacn0pKTsKLyoqCiAqICAgIHhiZTR4IGlzIGphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIG9yaWdpbmFsIEVDTUFTY3JpcHQgZm9yIFhNTCAoRTRYKQogKiAgICBTcGVjaWZpY2F0aW9uIChFQ01BLTM1NykgRGVjZW1iZXIgMjAwNS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBkZXNpZ25lZCB0byBlbXVsYXRlCiAqICAgIHRoZSBpbXBsZW1lbnRhdGlvbiB0aGF0IGlzIHVzZWQgaW4gU3BpZGVyTW9ua2V5IChNb3ppbGxhJ3MgSmF2YVNjcmlwdChUTSkgRW5naW5lKQogKiAgICBhbmQgdGhlcmVmb3JlIEZpcmVmb3gsIFRodW5kZXJiaXJkLCBhbmQgbW9zdCBvdGhlciBHZWNrbyBiYXNlZCBhcHBsaWNhdGlvbnMuCiAqICAgIEJlY2F1c2UgdGhlIE1vemlsbGEgaW1wbGVtZW50YXRpb24gbGVhdmVzIG91dCBjZXJ0YWluIGZlYXR1cmVzIG9mIHRoZQogKiAgICBzcGVjaWZpY2F0aW9uLCBzbyBkb2VzIHhiZTR4LiBQbGVhc2UgcmVhZCB0aGUgUkVBRE1FIGZpbGUgZm9yIGEgZnVydGhlcgogKiAgICBleHBsYW5hdGlvbiBvZiB0aGVzZSBpc3N1ZXMuCiAqCiAqCiAqICAgIEBhdXRob3IgU2FtIFNodWxsIDxodHRwOi8vc2Ftc2h1bGwuYmxvZ3Nwb3QuY29tLz4KICogICAgQHZlcnNpb24gMC4xCiAqCiAqICAgIEBjb3B5cmlnaHQgQ29weXJpZ2h0IChjKSAyMDA5IFNhbSBTaHVsbCA8aHR0cDovL3NhbXNodWxsLmJsb2dzcG90LmNvbS8+CiAqICAgIEBsaWNlbnNlIDxodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLmh0bWw+CiAqCiAqICAgIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKICogICAgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKICogICAgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwogKiAgICB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiAqICAgIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwogKiAgICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiAgICBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgogKiAgICBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogICAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKICogICAgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiAqICAgIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQogKiAgICBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiAqICAgIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiAqICAgIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KICogICAgVEhFIFNPRlRXQVJFLgogKgogKgogKiAgICBDSEFOR0VTOgogKi8KCi8vdGhpcyBkb2Vzbid0IGxvYWQgaWYgd2luZG93LlhNTCBpcyBhbHJlYWR5IGRlZmluZWQKaWYgKCF0aGlzLlhNTCkKewogICAgKGZ1bmN0aW9uICgpCiAgICB7CiAgICAgICAgLyoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgdmFyIHVuZGVmaW5lZCwgcCwKICAgICAgICAgICAgd2luZG93ICAgICAgICAgICAgICAgICAgICAgICA9IHRoaXMsCiAgICAgICAgICAgIGRucyAgICAgICAgICAgICAgICAgICAgICAgICAgPSBbXSwKICAgICAgICAgICAgZGVmYXVsdE5hbWVzcGFjZSAgICAgICAgICAgICA9ICIiLAogICAgICAgICAgICBFTEVNRU5UX05PREUgICAgICAgICAgICAgICAgID0gMSwKICAgICAgICAgICAgQVRUUklCVVRFX05PREUgICAgICAgICAgICAgICA9IDIsCiAgICAgICAgICAgIFRFWFRfTk9ERSAgICAgICAgICAgICAgICAgICAgPSAzLAogICAgICAgICAgICBDREFUQV9TRUNUSU9OX05PREUgICAgICAgICAgID0gNCwKICAgICAgICAgICAgRU5USVRZX1JFRkVSRU5DRV9OT0RFICAgICAgICA9IDUsCiAgICAgICAgICAgIEVOVElUWV9OT0RFICAgICAgICAgICAgICAgICAgPSA2LAogICAgICAgICAgICBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREUgID0gNywKICAgICAgICAgICAgQ09NTUVOVF9OT0RFICAgICAgICAgICAgICAgICA9IDgsCiAgICAgICAgICAgIERPQ1VNRU5UX05PREUgICAgICAgICAgICAgICAgPSA5LAogICAgICAgICAgICBET0NVTUVOVF9UWVBFX05PREUgICAgICAgICAgID0gMTAsCiAgICAgICAgICAgIERPQ1VNRU5UX0ZSQUdNRU5UX05PREUgICAgICAgPSAxMSwKICAgICAgICAgICAgTk9UQVRJT05fTk9ERSAgICAgICAgICAgICAgICA9IDEyLAogICAgICAgICAgICBpc05TRGVmICAgICAgICAgICAgICAgICAgICAgID0gL154bWxuczooW1x3XC1dKykvaSwKICAgICAgICAgICAgdG9TdHJpbmcgICAgICAgICAgICAgICAgICAgICA9ICh7fSkudG9TdHJpbmcsCiAgICAgICAgICAgIHByb3BlcnR5SXNFbnVtZXJhYmxlICAgICAgICAgPSAoe30pLnByb3BlcnR5SXNFbnVtZXJhYmxlLAogICAgICAgICAgICBoYXNPd25Qcm9wZXJ0eSAgICAgICAgICAgICAgID0gKHt9KS5oYXNPd25Qcm9wZXJ0eSwKICAgICAgICAgICAgZGVmYXVsdFhNTFByb3BlcnRpZXMgICAgICAgICA9ICIscHJvdG90eXBlLGlnbm9yZUNvbW1lbnRzLGlnbm9yZVByb2Nlc3NpbmdJbnN0cnVjdGlvbnMsaWdub3JlV2hpdGVzcGFjZSwiICsKICAgICAgICAgICAgICAgICJwcmV0dHlQcmludGluZyxwcmV0dHlJbmRlbnQsc2V0dGluZ3MsZGVmYXVsdFNldHRpbmdzLHNldFNldHRpbmdzLHNldHRpbmdzLCIgKwogICAgICAgICAgICAgICAgInByb3BlcnR5SXNFbnVtZXJhYmxlLGhhc093blByb3BlcnR5LF9zZXREZWZhdWx0TmFtZXNwYWNlLCIsCiAgICAgICAgICAgIGRlZmF1bHRYTUxQcm90b3R5cGUgICAgICAgICAgPSAiLF9DbGFzcyxfTmFtZSxfUGFyZW50LF9WYWx1ZSxfSW5TY29wZU5hbWVzcGFjZXMsX0F0dHJpYnV0ZXMsX0NoaWxkcmVuLF9Ob2RlIiwKICAgICAgICAgICAgZGVmYXVsdFhNTExpc3RQcm90b3R5cGUgICAgICA9ICIsX0NsYXNzLF9WYWx1ZSxfQ2hpbGRyZW4sX1RhcmdldE9iamVjdCxfVGFyZ2V0UHJvcGVydHkiLAogICAgICAgICAgICB4bWxEb2MgICAgICAgICAgICAgICAgICAgICAgID0gcGFyc2UoIjx4Lz4iKSwKICAgICAgICAgICAgcGlOYW1lICAgICAgICAgICAgICAgICAgICAgICA9IC9eW1x3XC1dK1xzKi8sCiAgICAgICAgICAgIFhTTFRfTlMgICAgICAgICAgICAgICAgICAgICAgPSAiaHR0cDovL3d3dy53My5vcmcvMTk5OS9YU0wvVHJhbnNmb3JtIjsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBYTUwgJHN0cmluZwogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqICAgIEB0aHJvd3MgU3ludGF4RXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBYTUwgKCRzdHJpbmcpCiAgICAgICAgewogICAgICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgWE1MKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIFRvWE1MKCRzdHJpbmcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgeCwgaSwgbDsKCiAgICAgICAgICAgIHRoaXMuX0NsYXNzID0gInRleHQiOwoKICAgICAgICAgICAgdGhpcy5fTmFtZSA9IG51bGw7CgogICAgICAgICAgICB0aGlzLl9WYWx1ZSA9IG51bGw7CgogICAgICAgICAgICB0aGlzLl9QYXJlbnQgPSBudWxsOwoKICAgICAgICAgICAgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMgPSB7fTsKCiAgICAgICAgICAgIHRoaXMuX0RlZmF1bHROYW1lc3BhY2UgPSBudWxsOwoKICAgICAgICAgICAgdGhpcy5fQXR0cmlidXRlcyA9IHt9OwoKICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW4gPSBbXTsKCiAgICAgICAgICAgIHRoaXNbMF0gPSB0aGlzOwoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzd2l0Y2ggKHR5cGVvZigkc3RyaW5nKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSAidW5kZWZpbmVkIjoKICAgICAgICAgICAgICAgIGNhc2UgIm51bGwiOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAibnVtYmVyIjoKICAgICAgICAgICAgICAgIGNhc2UgImJvb2xlYW4iOiAgICAkc3RyaW5nID0gVG9TdHJpbmcoJHN0cmluZyk7CiAgICAgICAgICAgICAgICBjYXNlICJzdHJpbmciOgoKICAgICAgICAgICAgICAgICAgICB4ID0gVG9YTUwodHJpbSgkc3RyaW5nKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHgpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoeC5sZW5ndGgoKSA9PT0xKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DbGFzcyA9IHguX0NsYXNzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fTmFtZSA9IHguX05hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9WYWx1ZSA9IHguX1ZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMgPSB4Ll9JblNjb3BlTmFtZXNwYWNlczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0RlZmF1bHROYW1lc3BhY2UgPSB4Ll9EZWZhdWx0TmFtZXNwYWNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQXR0cmlidXRlcyA9IHguX0F0dHJpYnV0ZXM7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMCwgbCA9IHguX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXSA9IHguX0NoaWxkcmVuW2ldOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldLl9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKCRzdHJpbmcgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoJHN0cmluZy5sZW5ndGgoKSA9PT0xKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gJHN0cmluZzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NsYXNzID0geC5fQ2xhc3M7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9OYW1lID0geC5fTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX1ZhbHVlID0geC5fVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcyA9IHguX0luU2NvcGVOYW1lc3BhY2VzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSA9IHguX0RlZmF1bHROYW1lc3BhY2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzID0geC5fQXR0cmlidXRlczsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0geC5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldID0geC5fQ2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0uX1BhcmVudCA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqICAgIElnbm9yZSBYTUwgY29tbWVudHMuIChEZWZhdWx0OiB0cnVlLikKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAcGFyYW0gTmFtZXNwYWNlIG5zCiAgICAgICAgICogICAgQHJldHVybnMgdm9pZAogICAgICAgICAqLwogICAgICAgIFhNTC5zZXREZWZhdWx0TmFtZXNwYWNlID0gZnVuY3Rpb24gKG5zKQogICAgICAgIHsKICAgICAgICAgICAgZG5zLnVuc2hpZnQoZGVmYXVsdE5hbWVzcGFjZSB8fCAiIik7CiAgICAgICAgICAgIGRlZmF1bHROYW1lc3BhY2UgPSBOYW1lc3BhY2UobnMpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKiAgVXNlIHRoaXMgZnVuY3Rpb24gdG8gcmVzdG9yZSB0aGUgZGVmYXVsdCBuYW1lc3BhY2UKICAgICAgICAgKiAgdG8gdGhlIHByZXZpb3VzIG5hbWVzcGFjZQogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgWE1MLnJlc3RvcmVEZWZhdWx0TmFtZXNwYWNlID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGRlZmF1bHROYW1lc3BhY2UgPSBkbnMuc2hpZnQoKSB8fCAiIjsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgWE1MLmxvYWQgPSBmdW5jdGlvbiAocGF0aFRvRmlsZSwgb25sb2FkKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHhociA9IGlzQWN0aXZlWFN1cHBvcnRlZCgiTWljcm9zb2Z0LlhNTEhUVFAiKSAmJiBuZXcgQWN0aXZlWE9iamVjdCgiTWljcm9zb2Z0LlhNTEhUVFAiKSB8fCBuZXcgWE1MSHR0cFJlcXVlc3QoKSwKICAgICAgICAgICAgICAgIGFzeW5jID0gKHt9KS50b1N0cmluZy5jYWxsKG9ubG9hZCB8fCB7fSkgPT0gIltvYmplY3QgRnVuY3Rpb25dIjsKCiAgICAgICAgICAgIHhoci5vcGVuKCJHRVQiLCBwYXRoVG9GaWxlLCBhc3luYyk7CgogICAgICAgICAgICBpZiAoYXN5bmMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghIXhoci5hZGRFdmVudExpc3RlbmVyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHhoci5hZGRFdmVudExpc3RlbmVyKCJsb2FkIiwgbG9hZGVkLCBmYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uICgpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoeGhyLnJlYWR5U3RhdGUgPT0gNCAmJiB4aHIuc3RhdHVzID09IDIwMCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB4aHIuc2VuZChudWxsKTsKCiAgICAgICAgICAgIHJldHVybiBhc3luYyA/IHhociA6IGxvYWRlZCgxKTsKCiAgICAgICAgICAgIGZ1bmN0aW9uIGxvYWRlZCAocmV0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgeCA9IG5ldyBYTUwoKHhoci5yZXNwb25zZVRleHR8fCIiKS5yZXBsYWNlKC9ccyo8XD94bWwuKj9cPz4vLCIiKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmV0ID8geCA6IG9ubG9hZCh4KTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqICAgIElnbm9yZSBYTUwgY29tbWVudHMuIChEZWZhdWx0OiB0cnVlLikKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAdmFyIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUwuaWdub3JlQ29tbWVudHMgPSB0cnVlOwoKICAgICAgICAvKioKICAgICAgICAgKiAgICBJZ25vcmUgWE1MIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zLiAoRGVmYXVsdDogdHJ1ZS4pCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHZhciBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLmlnbm9yZVByb2Nlc3NpbmdJbnN0cnVjdGlvbnMgPSB0cnVlOwoKICAgICAgICAvKioKICAgICAgICAgKiAgICBJZ25vcmUgd2hpdGVzcGFjZS4gKERlZmF1bHQ6IHRydWUuKQogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEB2YXIgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5pZ25vcmVXaGl0ZXNwYWNlID0gdHJ1ZTsKCiAgICAgICAgLyoqCiAgICAgICAgICogICAgUHJldHR5LXByaW50IFhNTCBvdXRwdXQgd2l0aCB0b1hNTFN0cmluZygpIGV0Yy4gKERlZmF1bHQ6IHRydWUuKQogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEB2YXIgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5wcmV0dHlQcmludGluZyA9IHRydWU7CgogICAgICAgIC8qKgogICAgICAgICAqICAgIFByZXR0eSBpbmRlbnQgbGV2ZWwgZm9yIGNoaWxkIG5vZGVzLiAoRGVmYXVsdDogMi4pCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHZhciBOdW1iZXIKICAgICAgICAgKi8KICAgICAgICBYTUwucHJldHR5SW5kZW50ID0gMjsKCiAgICAgICAgLy9UaGVyZSBhcmUgYWxzbyB0aHJlZSBtZXRob2RzIHRvIG1vcmUgZWFzaWx5IGFwcGx5IGFuZCByZXN0b3JlIHNldHRpbmdzIGZvciB1c2UsIHNheSwgd2l0aGluIGEgZnVuY3Rpb24uCgogICAgICAgIC8qKgogICAgICAgICAqICAgIEdldCBhbiBPYmplY3QgY29udGFpbmluZyB0aGUgYWJvdmUgc2V0dGluZ3MuCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHJldHVybnMgT2JqZWN0CiAgICAgICAgICovCiAgICAgICAgWE1MLnNldHRpbmdzID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICBpZ25vcmVDb21tZW50czogICAgICAgICAgICAgICAgIFhNTC5pZ25vcmVDb21tZW50cywKICAgICAgICAgICAgICAgIGlnbm9yZVByb2Nlc3NpbmdJbnN0cnVjdGlvbnM6ICAgWE1MLmlnbm9yZVByb2Nlc3NpbmdJbnN0cnVjdGlvbnMsCiAgICAgICAgICAgICAgICBpZ25vcmVXaGl0ZXNwYWNlOiAgICAgICAgICAgICAgIFhNTC5pZ25vcmVXaGl0ZXNwYWNlLAogICAgICAgICAgICAgICAgcHJldHR5UHJpbnRpbmc6ICAgICAgICAgICAgICAgICBYTUwucHJldHR5UHJpbnRpbmcsCiAgICAgICAgICAgICAgICBwcmV0dHlJbmRlbnQ6ICAgICAgICAgICAgICAgICAgIFhNTC5wcmV0dHlJbmRlbnQKICAgICAgICAgICAgfTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKiAgICBHZXQgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGRlZmF1bHQgc2V0dGluZ3MuCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHJldHVybnMgT2JqZWN0CiAgICAgICAgICovCiAgICAgICAgWE1MLmRlZmF1bHRTZXR0aW5ncyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgaWdub3JlQ29tbWVudHM6ICAgICAgICAgICAgICAgICB0cnVlLAogICAgICAgICAgICAgICAgaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9uczogICB0cnVlLAogICAgICAgICAgICAgICAgaWdub3JlV2hpdGVzcGFjZTogICAgICAgICAgICAgICB0cnVlLAogICAgICAgICAgICAgICAgcHJldHR5UHJpbnRpbmc6ICAgICAgICAgICAgICAgICB0cnVlLAogICAgICAgICAgICAgICAgcHJldHR5SW5kZW50OiAgICAgICAgICAgICAgICAgICAyCiAgICAgICAgICAgIH07CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICogICAgU2V0IFhNTCBzZXR0aW5ncyBmcm9tLCBlLmcuLCBhbiBvYmplY3QgcmV0dXJuZWQgYnkgWE1MLnNldHRpbmdzKCkuCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAcGFyYW0gT2JqZWN0IHNldHRpbmdzCiAgICAgICAgICogICAgQHJldHVybnMgdm9pZAogICAgICAgICAqLwogICAgICAgIFhNTC5zZXRTZXR0aW5ncyA9IGZ1bmN0aW9uIChzZXR0aW5ncykKICAgICAgICB7CiAgICAgICAgICAgIHZhciBwOwogICAgICAgICAgICBzZXR0aW5ncyA9IHNldHRpbmdzIHx8IFhNTC5zZXR0aW5ncygpOwogICAgICAgICAgICBmb3IgKHAgaW4gc2V0dGluZ3MpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAocCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJpZ25vcmVDb21tZW50cyI6ICAgICAgICAgICAgICAgICAgIFhNTC5pZ25vcmVDb21tZW50cyA9ICEhc2V0dGluZ3NbcF07CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucyI6ICAgICBYTUwuaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucyA9ICEhc2V0dGluZ3NbcF07CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiaWdub3JlV2hpdGVzcGFjZSI6ICAgICAgICAgICAgICAgICBYTUwuaWdub3JlV2hpdGVzcGFjZSA9ICEhc2V0dGluZ3NbcF07CiAgICAgICAgICAgICAgICAgICAgY2FzZSAicHJldHR5UHJpbnRpbmciOiAgICAgICAgICAgICAgICAgICBYTUwucHJldHR5UHJpbnRpbmcgPSAhIXNldHRpbmdzW3BdOwogICAgICAgICAgICAgICAgICAgIGNhc2UgInByZXR0eUluZGVudCI6ICAgICAgICAgICAgICAgICAgICAgWE1MLnByZXR0eUluZGVudCA9IHBhcnNlSW50KHNldHRpbmdzW3BdKSB8fCAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5oYXNPd25Qcm9wZXJ0eSA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRYTUxQcm9wZXJ0aWVzLmluZGV4T2YoIiwiICsgbmFtZSArICIsIikgPT09LTEKICAgICAgICAgICAgICAgICYmIGhhc093blByb3BlcnR5LmNhbGwoWE1MLCBuYW1lKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUwucHJvcGVydHlJc0VudW1lcmFibGUgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuYW1lICE9PSAicHJvdG90eXBlIgogICAgICAgICAgICAgICAgJiYgbmFtZSBpbiBYTUwKICAgICAgICAgICAgICAgICYmIHRvU3RyaW5nLmNhbGwoWE1MW25hbWVdKSAhPSAiW29iamVjdCBGdW5jdGlvbl0iCiAgICAgICAgICAgICAgICAmJiBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKFhNTCwgbmFtZSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBYTUwudG9TdHJpbmcgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICJmdW5jdGlvbiBYTUwoKSB7XG4gW25hdGl2ZSBjb2RlXSBcbn0iOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTmFtZXNwYWNlIG5hbWVzcGFjZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuYWRkTmFtZXNwYWNlID0gZnVuY3Rpb24gKG5hbWVzcGFjZSkKICAgICAgICB7CiAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbCh0aGlzLCBOYW1lc3BhY2UobmFtZXNwYWNlKSk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIGNoaWxkCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5hcHBlbmRDaGlsZCA9IGZ1bmN0aW9uIChjaGlsZCxpc0NoaWxkRWxlbWVudCkKICAgICAgICB7CiAgICAgICAgICAgIGlzQ2hpbGRFbGVtZW50ID0gaXNDaGlsZEVsZW1lbnQgIT09IHVuZGVmaW5lZCA/IGlzQ2hpbGRFbGVtZW50IDogZmFsc2U7CiAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IEdldC5jYWxsKHRoaXMsICIqIik7CiAgICAgICAgICAgIGNoaWxkcmVuLlB1dChjaGlsZHJlbi5sZW5ndGgoKSwgY2hpbGQsaXNDaGlsZEVsZW1lbnQpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IEF0dHJpYnV0ZU5hbWUgfCBRTmFtZSBhdHRyaWJ1dGVOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5hdHRyaWJ1dGUgPSBmdW5jdGlvbiAoYXR0cmlidXRlTmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBHZXQuY2FsbCh0aGlzLCBUb0F0dHJpYnV0ZU5hbWUoYXR0cmlidXRlTmFtZSksIHRydWUpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5hdHRyaWJ1dGVzID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBHZXQuY2FsbCh0aGlzLCBUb0F0dHJpYnV0ZU5hbWUoIioiKSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgcHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuY2hpbGQgPSBmdW5jdGlvbiAocHJvcGVydHlOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHRlbXBvcmFyeTsKCiAgICAgICAgICAgIGlmIChwYXJzZUludChwcm9wZXJ0eU5hbWUpKyIiID09IHByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGVtcG9yYXJ5ID0gR2V0LmNhbGwodGhpcywgIioiKTsKICAgICAgICAgICAgICAgIHRlbXBvcmFyeSA9IEdldExpc3QuY2FsbCh0ZW1wb3JhcnksIHByb3BlcnR5TmFtZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gdGVtcG9yYXJ5IHx8IG5ldyBYTUxMaXN0KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRlbXBvcmFyeSA9IFRvWE1MTGlzdCggR2V0LmNhbGwodGhpcywgcHJvcGVydHlOYW1lKSApOwoKICAgICAgICAgICAgcmV0dXJuIHRlbXBvcmFyeTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgTnVtYmVyCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5jaGlsZEluZGV4ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBwYXJlbnQgPSB0aGlzLl9QYXJlbnQsIHEsIGw7CgogICAgICAgICAgICBpZiAoIXBhcmVudCB8fCB0aGlzLl9DbGFzcyA9PT0gImF0dHJpYnV0ZSIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChxID0gMCwgbCA9IHBhcmVudC5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocGFyZW50Ll9DaGlsZHJlbltxXSA9PT0gdGhpcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5jaGlsZHJlbiA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gR2V0LmNhbGwodGhpcywgIioiKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuY29tbWVudHMgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgWE1MTGlzdCgpLCBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gdGhpczsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0UHJvcGVydHkgPSBudWxsOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJjb21tZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZCh0aGlzLl9DaGlsZHJlbltpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIHZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuY29udGFpbnMgPSBmdW5jdGlvbiAodmFsdWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdGhpcyA9PSB2YWx1ZTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBEZWVwQ29weS5jYWxsKHRoaXMpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmRlc2NlbmRhbnRzID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRGVzY2VuZGFudHMuY2FsbCh0aGlzLCBuYW1lIHx8ICIqIik7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSB8IEF0dHJpYnV0ZU5hbWUgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmVsZW1lbnRzID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICBuYW1lID0gVG9YTUxOYW1lKG5hbWUgfHwgIioiKTsKICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgWE1MTGlzdCgpLCBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gdGhpczsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0UHJvcGVydHkgPSBuYW1lOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJlbGVtZW50IgogICAgICAgICAgICAgICAgICAgICAgICAmJiAobmFtZS5sb2NhbE5hbWUgPT09ICIqIiB8fCBuYW1lLmxvY2FsTmFtZSA9PT0gdGhpcy5fQ2hpbGRyZW5baV0uX05hbWUubG9jYWxOYW1lKQogICAgICAgICAgICAgICAgICAgICAgICAmJiAobmFtZS51cmkgPT0gbnVsbCB8fCBuYW1lLnVyaSA9PT0gdGhpcy5fQ2hpbGRyZW5baV0uX05hbWUudXJpKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZCh0aGlzLl9DaGlsZHJlbltpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIEhhc1Byb3BlcnR5LmNhbGwodGhpcywgbmFtZSkgfHwgKGRlZmF1bHRYTUxQcm90b3R5cGUuaW5kZXhPZigiLCIgKyBuYW1lICsiLCIpID09PSAtMSAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMsIG5hbWUpKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuaGFzQ29tcGxleENvbnRlbnQgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgiLGF0dHJpYnV0ZSxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sdGV4dCwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5baV0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuaGFzU2ltcGxlQ29udGVudCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBBcnJheQogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuaW5TY29wZU5hbWVzcGFjZXMgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHkgPSB0aGlzLCBpblNjb3BlTlMgPSB7fSwgcCwgYSA9IFtdOwoKICAgICAgICAgICAgd2hpbGUgKHkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAocCBpbiB5Ll9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWluU2NvcGVOU1twXSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGluU2NvcGVOU1twXSA9IHkuX0luU2NvcGVOYW1lc3BhY2VzW3BdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB5ID0geS5wYXJlbnQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRoaXMuX0RlZmF1bHROYW1lc3BhY2UpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGluU2NvcGVOU1siIl0gPSB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHAgaW4gaW5TY29wZU5TKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhW2EubGVuZ3RoXSA9IGluU2NvcGVOU1twXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGE7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBYTUwgY2hpbGQxCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBjaGlsZDIKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwgfCBudWxsCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5pbnNlcnRDaGlsZEFmdGVyID0gZnVuY3Rpb24gKGNoaWxkMSwgY2hpbGQyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgiLGF0dHJpYnV0ZSxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sdGV4dCwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgIC8vdGhpcyBpcyBkaXNhYmxlZCwgYmVjYXVzZSBpdCBkb2Vzbid0IHdvcmsgaW4KICAgICAgICAgICAgIC8vRmlyZWZveCBhY2NvcmRpbmcgdG8gdGhlIHNwZWMKICAgICAgICAgICAgIGlmICghY2hpbGQyKQogICAgICAgICAgICAgewogICAgICAgICAgICAgSW5zZXJ0LmNhbGwodGhpcywgMCwgY2hpbGQxKTsKICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgZWxzZSBpZiAoIWNoaWxkMSkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIDAsIGNoaWxkMik7CiAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICovCgogICAgICAgICAgICBpZiAoIWNoaWxkMSl7CiAgICAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCAwLCBjaGlsZDIpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFjaGlsZDIpewogICAgICAgICAgICAgICAgSW5zZXJ0LmNhbGwodGhpcywgMCwgY2hpbGQxKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY2hpbGQxIGluc3RhbmNlb2YgWE1MKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCBjaGlsZDEuY2hpbGRJbmRleCgpICsgMSwgY2hpbGQyKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIGNoaWxkMQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgY2hpbGQyCiAgICAgICAgICogICAgQHJldHVybnMgWE1MIHwgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuaW5zZXJ0Q2hpbGRCZWZvcmUgPSBmdW5jdGlvbiAoY2hpbGQxLCBjaGlsZDIpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsYXR0cmlidXRlLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgLy90aGlzIGlzIGRpc2FibGVkLCBiZWNhdXNlIGl0IGRvZXNuJ3Qgd29yayBpbgogICAgICAgICAgICAgLy9GaXJlZm94IGFjY29yZGluZyB0byB0aGUgc3BlYwogICAgICAgICAgICAgaWYgKCFjaGlsZDEpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIGNoaWxkMik7CiAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIGVsc2UgaWYgKCFjaGlsZDIpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIGNoaWxkMSk7CiAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICovCgogICAgICAgICAgICBpZiAoY2hpbGQxIGluc3RhbmNlb2YgWE1MKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCBjaGlsZDEuY2hpbGRJbmRleCgpLCBjaGlsZDIpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBOdW1iZXIKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmxlbmd0aCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nIHwgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUubG9jYWxOYW1lID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9OYW1lID09PSBudWxsID8gbnVsbCA6IHRoaXMuX05hbWUubG9jYWxOYW1lOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICByZXR1cm4gUU5hbWUKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLm5hbWUgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX05hbWU7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgcHJlZml4CiAgICAgICAgICogICAgQHJldHVybnMgTmFtZXNwYWNlCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5uYW1lc3BhY2UgPSBmdW5jdGlvbiAocHJlZml4KQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHkgPSB0aGlzLCBpblNjb3BlTlMgPSB7fSwgcDsKCiAgICAgICAgICAgIHdoaWxlICh5KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKHAgaW4geS5fSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFpblNjb3BlTlNbcF0pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpblNjb3BlTlNbcF0gPSB5Ll9JblNjb3BlTmFtZXNwYWNlc1twXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgeSA9IHkucGFyZW50KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChwcmVmaXggPT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCgiLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIEdldE5hbWVzcGFjZSh0aGlzLl9OYW1lLCBpblNjb3BlTlMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBwcmVmaXggPSBUb1N0cmluZyhwcmVmaXgpOwoKICAgICAgICAgICAgZm9yIChwIGluIGluU2NvcGVOUykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGluU2NvcGVOU1twXS5wcmVmaXggPT09IHByZWZpeCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5TY29wZU5TW3BdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgQXJyYXkKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLm5hbWVzcGFjZURlY2xhcmF0aW9ucyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsYXR0cmlidXRlLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBbXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGEgPSBbXSwgeSA9IHRoaXMuX1BhcmVudCwgYW5jZXN0b3JOUyA9IHt9LCBwOwoKICAgICAgICAgICAgd2hpbGUgKHkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAocCBpbiB5Ll9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWFuY2VzdG9yTlNbcF0pCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhbmNlc3Rvck5TW3BdID0geS5fSW5TY29wZU5hbWVzcGFjZXNbcF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHkgPSB5Ll9QYXJlbnQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAocCBpbiB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHAgIT0gIiIgJiYgKCFhbmNlc3Rvck5TW3BdIHx8IGFuY2VzdG9yTlNbcF0udXJpICE9IHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBhW2EubGVuZ3RoXSA9IHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZihwID09PSAiIiAmJiAhdGhpcy5fUGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFbYS5sZW5ndGhdID0gdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbcF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBhOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLm5vZGVLaW5kID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9DbGFzczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5ub3JtYWxpemUgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldLm5vcm1hbGl6ZSgpOwogICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gInRleHQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHdoaWxlIChpKzEgPCB0aGlzLl9DaGlsZHJlbi5sZW5ndGggJiYgdGhpcy5fQ2hpbGRyZW5baSsxXS5fQ2xhc3MgPT09ICJ0ZXh0IikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldLl9WYWx1ZSA9ICh0aGlzLl9DaGlsZHJlbltpXS5fVmFsdWUgfHwgIiIpICsgKHRoaXMuX0NoaWxkcmVuW2krMV0uX1ZhbHVlIHx8ICIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgRGVsZXRlQnlJbmRleC5jYWxsKHRoaXMsIGkrMSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5baV0uX1ZhbHVlLmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZUJ5SW5kZXguY2FsbCh0aGlzLCBpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgKytpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICArK2k7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwgfCBudWxsCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5wYXJlbnQgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX1BhcmVudDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUucHJvY2Vzc2luZ0luc3RydWN0aW9ucyA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgbmFtZSA9IFRvWE1MTmFtZShuYW1lIHx8ICIqIik7CgogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRQcm9wZXJ0eSA9IG51bGw7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iCiAgICAgICAgICAgICAgICAgICAgJiYgKG5hbWUubG9jYWxOYW1lID09PSAiKiIgfHwgbmFtZS5sb2NhbE5hbWUgPT09IHRoaXMuX0NoaWxkcmVuW2ldLl9OYW1lLmxvY2FsTmFtZSkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQodGhpcy5fQ2hpbGRyZW5baV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFhNTCB2YWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUucHJlcGVuZENoaWxkID0gZnVuY3Rpb24gKHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgSW5zZXJ0LmNhbGwodGhpcywgMCwgdmFsdWUpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKCiAgICAgICAgWE1MLnByb3RvdHlwZS5maW5kRmlyc3RFbGVtZW50ID0gZnVuY3Rpb24gKHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGxpc3QgPSBbXTsKICAgICAgICAgICAgbGlzdCA9IHRoaXMuZWxlbWVudHModmFsdWUpLl9DaGlsZHJlbjsKICAgICAgICAgICAgaWYobGlzdC5sZW5ndGggPT0gMCl7CiAgICAgICAgICAgICAgICB2YXIgY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuKCk7CiAgICAgICAgICAgICAgICB2YXIgeG1sOwogICAgICAgICAgICAgICAgZm9yKHZhciBpPTA7aTxjaGlsZHJlbi5sZW5ndGgoKTtpKyspewogICAgICAgICAgICAgICAgICAgIHhtbCA9IGNoaWxkcmVuW2ldOwogICAgICAgICAgICAgICAgICAgIHZhciBzdWJsaXN0ID0geG1sLmZpbmRGaXJzdEVsZW1lbnQodmFsdWUpOwogICAgICAgICAgICAgICAgICAgIGlmKHN1Ymxpc3QubGVuZ3RoPjApCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWJsaXN0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuYW1lID09ICIwIjsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIE5hbWVzcGFjZSB8IFN0cmluZyBuYW1lc3BhY2UKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnJlbW92ZU5hbWVzcGFjZSA9IGZ1bmN0aW9uIChuYW1lc3BhY2UpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsYXR0cmlidXRlLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbnMgPSBOYW1lc3BhY2UobmFtZXNwYWNlKSwgdGhpc05TID0gR2V0TmFtZXNwYWNlKHRoaXMuX05hbWUsIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzKSwgcCwgbDsKCiAgICAgICAgICAgIGlmICh0aGlzTlMgPT0gbnMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgLy9maXJlZm94IGRvZXMgbm90IHJlbW92ZSB0aGUgcmVmZXJlbmNlcyB0byB0aGUKICAgICAgICAgICAgIC8vbmFtZXNwYWNlcyBpbiBhdHRyaWJ1dGVzIC0tIHNvIHdlIHdvbnQgZWl0aGVyCiAgICAgICAgICAgICBmb3IgKHAgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIGlmIChHZXROYW1lc3BhY2UodGhpcy5fQXR0cmlidXRlc1twXS5fTmFtZSwgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMpLnVyaSA9PSBucy51cmkpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzW3BdLl9OYW1lID0gbmV3IFFOYW1lKG5zLCB0aGlzLl9BdHRyaWJ1dGVzW3BdLmxvY2FsTmFtZSgpKTsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIH0KICAgICAgICAgICAgIC8vKi8KCiAgICAgICAgICAgIGlmIChucy5wcmVmaXggPT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKHAgaW4gdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdLnVyaSA9PT0gbnMudXJpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5ewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbcF0gPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdOwogICAgICAgICAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1tucy5wcmVmaXhdICYmIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW25zLnByZWZpeF0udXJpID09PSBucy51cmkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1tucy5wcmVmaXhdID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbbnMucHJlZml4XTsKICAgICAgICAgICAgICAgIH1jYXRjaChlKXt9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAocCA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IHAgPCBsOyArK3ApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltwXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltwXS5yZW1vdmVOYW1lc3BhY2UobnMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBwcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIHZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5yZXBsYWNlID0gZnVuY3Rpb24gKHByb3BlcnR5TmFtZSwgdmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsYXR0cmlidXRlLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgYyA9IHZhbHVlIGluc3RhbmNlb2YgWE1MID8gRGVlcENvcHkuY2FsbCh2YWx1ZSkgOiBUb1N0cmluZyh2YWx1ZSksIG4sIGksIGs7CgogICAgICAgICAgICBpZiAocGFyc2VJbnQocHJvcGVydHlOYW1lKSsiIiA9PSBwcm9wZXJ0eU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbCh0aGlzLCBwcm9wZXJ0eU5hbWUsIGMpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICBCYXNpY2FsbHkgRmlyZWZveCBkb2VzIG5vdCBhcHBlYXIgdG8gZm9sbG93IHRoZSBydWxlcyBzZXQgZm9ydGggaW4gdGhlIHNwZWMKICAgICAgICAgICAgIHNvLCB3ZSBhcmUganVzdCBnb2luZyB0byBmaXggdGhpcyBzbyB0aGF0IHdlIGRvIHdoYXQgZmlyZWZveCBkb2VzCiAgICAgICAgICAgICBpZiB0aGUgcHJvcGVydHlOYW1lIGlzIG5vdCBhbiBpbnRlZ2VyOgogICAgICAgICAgICAgaWYgdmFsdWUgaXMgYSBYTUxMaXN0IHNldENoaWxkcmVuCiAgICAgICAgICAgICBvdGhlcndpc2UgZG8gbm90aGluZwogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGlmIChjIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhpcy5zZXRDaGlsZHJlbihjKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgTGVhdmUgdGhlIHJlc3Qgb2YgdGhlc2UgcnVsZXMgaW4gcGxhY2UsIGp1c3QgaW4gY2FzZQogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIG4gPSBRTmFtZShwcm9wZXJ0eU5hbWUpOwogICAgICAgICAgICBrID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwoKICAgICAgICAgICAgd2hpbGUgKC0tayA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKG4ubG9jYWxOYW1lID09PSAiKiIgfHwgKHRoaXMuX0NoaWxkcmVuW2tdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLmxvY2FsTmFtZT09PW4ubG9jYWxOYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKG4udXJpID09IG51bGwgfHwgKHRoaXMuX0NoaWxkcmVuW2tdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIG4udXJpID09PSB0aGlzLl9DaGlsZHJlbltrXS5fTmFtZS51cmkgKSkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGkgIT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZUJ5SW5kZXguY2FsbCh0aGlzLCBpKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGkgPSBrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaSAhPT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZXBsYWNlLmNhbGwodGhpcywgaSwgYyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIHZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5zZXRDaGlsZHJlbiA9IGZ1bmN0aW9uICh2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIHRoaXMuUHV0KCIqIiwgdmFsdWUpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgdm9pZAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuc2V0TG9jYWxOYW1lID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsY29tbWVudCx0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLl9OYW1lLmxvY2FsTmFtZSA9IG5hbWUgaW5zdGFuY2VvZiBRTmFtZSA/IG5hbWUubG9jYWxOYW1lIDogVG9TdHJpbmcobmFtZSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBRTmFtZSB8IFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuc2V0TmFtZSA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgiLGNvbW1lbnQsdGV4dCwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG5hbWUgaW5zdGFuY2VvZiBRTmFtZSAmJiBuYW1lLnVyaSA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBuYW1lID0gbmFtZS5sb2NhbE5hbWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBuID0gUU5hbWUobmFtZSk7CgogICAgICAgICAgICBpZiAodGhpcy5fQ2xhc3MgPT09ICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbi51cmkgPSAiIjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSA9IG5ldyBOYW1lc3BhY2Uobi5wcmVmaXgsIG4udXJpKTsKCiAgICAgICAgICAgIHRoaXMuX05hbWUgPSBuOwoKICAgICAgICAgICAgaWYgKHRoaXMuX0NsYXNzID09PSAiYXR0cmlidXRlIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX1BhcmVudCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBBZGRJblNjb3BlTmFtZXNwYWNlLmNhbGwodGhpcy5fUGFyZW50LCB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBBZGRJblNjb3BlTmFtZXNwYWNlLmNhbGwodGhpcywgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoKCIsY29tbWVudCx0ZXh0LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX05hbWUgPSBuZXcgUU5hbWUodGhpcy5fRGVmYXVsdE5hbWVzcGFjZSwgdGhpcy5fTmFtZS5sb2NhbE5hbWUpOwoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBOYW1lc3BhY2UgfCBTdHJpbmcgbnMKICAgICAgICAgKiAgICBAcmV0dXJucyBudWxsCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5zZXROYW1lc3BhY2UgPSBmdW5jdGlvbiAobnMpCiAgICAgICAgewogICAgICAgICAgICAvL3Byb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sCiAgICAgICAgICAgIGlmICgoIixjb21tZW50LHRleHQsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX0RlZmF1bHROYW1lc3BhY2UgPSBOYW1lc3BhY2UobnMpOwoKICAgICAgICAgICAgdGhpcy5fTmFtZSA9IG5ldyBRTmFtZSh0aGlzLl9EZWZhdWx0TmFtZXNwYWNlLCB0aGlzLl9OYW1lLmxvY2FsTmFtZSk7CgogICAgICAgICAgICBpZiAodGhpcy5fQ2xhc3MgPT09ICJhdHRyaWJ1dGUiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fUGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbCh0aGlzLl9QYXJlbnQsIHRoaXMuX0RlZmF1bHROYW1lc3BhY2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbCh0aGlzLCB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnRleHQgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgWE1MTGlzdCgpLCBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gdGhpczsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0UHJvcGVydHkgPSBudWxsOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJ0ZXh0IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZCh0aGlzLl9DaGlsZHJlbltpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUb1N0cmluZyh0aGlzKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS50b1hNTFN0cmluZyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVG9YTUxTdHJpbmcodGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUudmFsdWVPZiA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHBhcmFtIFhNTCB8IFN0cmluZyBWYWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuUHV0ID0gZnVuY3Rpb24gKFByb3BlcnR5TmFtZSwgVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAocGFyc2VJbnQoUHJvcGVydHlOYW1lKSsiIiA9PSBQcm9wZXJ0eU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCgiLHRleHQsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLGF0dHJpYnV0ZSwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGMgPSAoIShWYWx1ZSBpbnN0YW5jZW9mIFhNTCkgfHwgKCIsdGV4dCxhdHRyaWJ1dGUsIikuaW5kZXhPZigiLCIgKyBWYWx1ZS5fQ2xhc3MrIiwiKSA+IC0xKQogICAgICAgICAgICAgICAgICAgID8gVG9TdHJpbmcoVmFsdWUpCiAgICAgICAgICAgICAgICAgICAgOiBEZWVwQ29weS5jYWxsKFZhbHVlKSwKICAgICAgICAgICAgICAgIG4gPSBUb1hNTE5hbWUoUHJvcGVydHlOYW1lKSwKICAgICAgICAgICAgICAgIHMsIGksIGwsIGEgPSBudWxsLCBwcmltaXRpdmVBc3NpZ24sIGs7CgogICAgICAgICAgICBpZiAobiBpbnN0YW5jZW9mIEF0dHJpYnV0ZU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghaXNYTUxOYW1lKG4uX05hbWUpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoYyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGMgPSAiIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcyA9IFRvU3RyaW5nKGNbMF0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMSwgbCA9IGMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiICIgKyBUb1N0cmluZyhjW2ldKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgYyA9IHM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGMgPSBUb1N0cmluZyhjKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmb3IgKGkgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgIChuLl9OYW1lLmxvY2FsTmFtZSA9PT0gdGhpcy5fQXR0cmlidXRlc1tpXS5fTmFtZS5sb2NhbE5hbWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAobi5fTmFtZS51cmkgPT09IG51bGwgfHwgbi5fTmFtZS51cmkgPT09IHRoaXMuX0F0dHJpYnV0ZXNbaV0uX05hbWUudXJpKQogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhID0gdGhpcy5fQXR0cmlidXRlc1tpXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuRGVsZXRlKHRoaXMuX0F0dHJpYnV0ZXNbaV0uX05hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChhID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYSA9IG5ldyBYTUwoKTsKICAgICAgICAgICAgICAgICAgICBhLl9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgIGEuX0NsYXNzID0gImF0dHJpYnV0ZSI7CiAgICAgICAgICAgICAgICAgICAgYS5fTmFtZSA9IG4uX05hbWUudXJpID09IG51bGwKICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgUU5hbWUobmV3IE5hbWVzcGFjZSgpLCBuLl9OYW1lKQogICAgICAgICAgICAgICAgICAgICAgICA6IG5ldyBRTmFtZShuZXcgTmFtZXNwYWNlKG4uX05hbWUudXJpKSwgbi5fTmFtZS5sb2NhbE5hbWUpOwoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzWyhhLl9OYW1lLl9QcmVmaXggPyBhLl9OYW1lLl9QcmVmaXggKyAiOiIgOiAiIikgKyBhLl9OYW1lLmxvY2FsTmFtZV0gPSBhOwoKICAgICAgICAgICAgICAgICAgICBBZGRJblNjb3BlTmFtZXNwYWNlLmNhbGwodGhpcywgR2V0TmFtZXNwYWNlKGEuX05hbWUpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBhLl9WYWx1ZSA9IGM7CgogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNYTUxOYW1lKG4pICYmIG4ubG9jYWxOYW1lICE9ICIqIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGkgPSB1bmRlZmluZWQ7CgogICAgICAgICAgICBwcmltaXRpdmVBc3NpZ24gPSAhKGMgaW5zdGFuY2VvZiBYTUwpICYmIG4ubG9jYWxOYW1lICE9ICIqIjsKCiAgICAgICAgICAgIGZvciAoayA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGsgPCBsOyArK2spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAobi5sb2NhbE5hbWUgPT09ICIqIiB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgdGhpcy5fQ2hpbGRyZW5ba10uX05hbWUubG9jYWxOYW1lPT09bi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgICAgICAgICAobi51cmkgPT0gbnVsbCB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgbi51cmkgPT09IHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLnVyaSkpCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChpICE9IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZUJ5SW5kZXguY2FsbCh0aGlzLCBUb1N0cmluZyhpKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGkgPSBrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGkgPT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwoKICAgICAgICAgICAgICAgIGlmIChwcmltaXRpdmVBc3NpZ24pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYSA9IG5ldyBYTUwoKTsKICAgICAgICAgICAgICAgICAgICBhLl9DbGFzcyA9ICJlbGVtZW50IjsKICAgICAgICAgICAgICAgICAgICBhLl9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgIGEuX05hbWUgPSBuLnVyaSA9PSBudWxsCiAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IFFOYW1lKEdldERlZmF1bHROYW1lc3BhY2UoKSwgbikKICAgICAgICAgICAgICAgICAgICAgICAgOiBuZXcgUU5hbWUobik7CgogICAgICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbCh0aGlzLCBUb1N0cmluZyhpKSwgYSk7CgogICAgICAgICAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbChhLCBHZXROYW1lc3BhY2UoYS5fTmFtZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocHJpbWl0aXZlQXNzaWduKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzID0gVG9TdHJpbmcoYyk7CgogICAgICAgICAgICAgICAgaWYgKHMgIT0gIiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgUmVwbGFjZS5jYWxsKHRoaXMuX0NoaWxkcmVuW2ldLCAiMCIsIHMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVwbGFjZS5jYWxsKHRoaXMsIFRvU3RyaW5nKGkpLCBjKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuRGVsZXRlID0gZnVuY3Rpb24gKFByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwYXJzZUludChQcm9wZXJ0eU5hbWUpKyIiID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbiA9IFRvWE1MTmFtZShQcm9wZXJ0eU5hbWUpLCBrLCBkcCA9IDAsIHEgPSAwLCBsOwoKICAgICAgICAgICAgaWYgKG4gaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGsgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgIChuLl9OYW1lLmxvY2FsTmFtZSA9PT0gIioiIHx8IG4uX05hbWUubG9jYWxOYW1lID09PSB0aGlzLl9BdHRyaWJ1dGVzW2tdLl9OYW1lLmxvY2FsTmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobi5fTmFtZS51cmkgPT0gbnVsbCB8fCBuLl9OYW1lLnVyaSA9PT0gdGhpcy5fQXR0cmlidXRlc1trXS5fTmFtZS51cmkpCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0F0dHJpYnV0ZXNba10uX1BhcmVudCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9BdHRyaWJ1dGVzW2tdOwogICAgICAgICAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKG4ubG9jYWxOYW1lID09PSAiKiIgfHwgKHRoaXMuX0NoaWxkcmVuW3FdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXMuX0NoaWxkcmVuW3FdLl9OYW1lLmxvY2FsTmFtZSA9PT0gbi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgICAgICAgICAobi51cmkgPT0gbnVsbCB8fCAodGhpcy5fQ2hpbGRyZW5bcV0uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgbi51cmkgPT09IHRoaXMuX0NoaWxkcmVuW3FdLl9OYW1lLnVyaSkpCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIERlbGV0ZUJ5SW5kZXguY2FsbCh0aGlzLCBxKTsKICAgICAgICAgICAgICAgICAgICArK2RwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoZHAgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW3EgLSBkcF0gPSB0aGlzLl9DaGlsZHJlbltxXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgVmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5FcXVhbHMgPSBmdW5jdGlvbiAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIShWYWx1ZSBpbnN0YW5jZW9mIFhNTCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhpcy5fQ2xhc3MgIT09IFZhbHVlLl9DbGFzcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggIT09IFZhbHVlLl9DaGlsZHJlbi5sZW5ndGgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhpcy5fVmFsdWUgIT09IFZhbHVlLl9WYWx1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLl9OYW1lICE9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoVmFsdWUuX05hbWUgPT09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKFZhbHVlLl9OYW1lLmxvY2FsTmFtZSAhPT0gdGhpcy5fTmFtZS5sb2NhbE5hbWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKFZhbHVlLl9OYW1lLnVyaSAhPT0gdGhpcy5fTmFtZS51cmkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKFZhbHVlLl9OYW1lICE9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb3VudCh0aGlzLl9BdHRyaWJ1dGVzKSAhPT0gY291bnQoVmFsdWUuX0F0dHJpYnV0ZXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBhLCBiLCBrLCBsOwoKICAgICAgICAgICAgZm9yIChrIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGEgPSB0aGlzLl9BdHRyaWJ1dGVzW2tdOwoKICAgICAgICAgICAgICAgIGIgPSBWYWx1ZS5fQXR0cmlidXRlc1trXTsKCiAgICAgICAgICAgICAgICBpZiAoIWIgfHwgYi5fTmFtZS5sb2NhbE5hbWUgIT09IGEuX05hbWUubG9jYWxOYW1lIHx8IGIuX05hbWUudXJpICE9PSBhLl9OYW1lLnVyaSB8fCBiLl9WYWx1ZSAhPT0gYS5fVmFsdWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGsgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBrIDwgbDsgKytrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhID0gdGhpcy5fQ2hpbGRyZW5ba107CgogICAgICAgICAgICAgICAgYiA9IFZhbHVlLl9DaGlsZHJlbltrXTsKCiAgICAgICAgICAgICAgICBpZiAoIWFyZ3VtZW50cy5jYWxsZWUuY2FsbChhLCBiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8vZXh0ZW5zaW9ucwoKICAgICAgICAvKgogICAgICAgICAqIGU0eC5qcwogICAgICAgICAqCiAgICAgICAgICogQSBKYXZhU2NyaXB0IGxpYnJhcnkgdGhhdCBpbXBsZW1lbnRzIHRoZSBvcHRpb25hbCBFNFggZmVhdHVyZXMgZGVzY3JpYmVkIGluCiAgICAgICAgICogRUNNQS0zNTcgMm5kIEVkaXRpb24gQW5uZXggQSBpZiB0aGV5IGFyZSBub3QgYWxyZWFkeSBpbXBsZW1lbnRlZC4KICAgICAgICAgKgogICAgICAgICAqIDIwMTAtMDMtMTMKICAgICAgICAgKgogICAgICAgICAqIEJ5IEVsaWphaCBHcmV5LCBodHRwOi8vZWxpZ3JleS5jb20KICAgICAgICAgKiBMaWNlbnNlOiBUaGUgWDExL01JVCBsaWNlbnNlIChzZWUgQ09QWUlORy5tZCkKICAgICAgICAgKgogICAgICAgICAqIENoYW5nZXM6CiAgICAgICAgICogICAgQnkgU2FtIFNodWxsLCBodHRwOi8vc2Ftc2h1bGwuYmxvZ3Nwb3QuY29tCiAgICAgICAgICogICAgSnVzdCBhIGxpdGxsZSBzaW1wbGlmeWluZyBmb3IgaW1wbGVtZW50YXRpb24KICAgICAgICAgKi8KCiAgICAgICAgLypnbG9iYWwgZG9jdW1lbnQsIFhNTCwgWE1MTGlzdCwgRE9NUGFyc2VyLCBYTUxTZXJpYWxpemVyLCBYUGF0aFJlc3VsdCAqLwoKICAgICAgICAvKmpzbGludCB1bmRlZjogdHJ1ZSwgbm9tZW46IHRydWUsIGVxZXFlcTogdHJ1ZSwgYml0d2lzZTogdHJ1ZSwgcmVnZXhwOiB0cnVlLAogICAgICAgICBuZXdjYXA6IHRydWUsIGltbWVkOiB0cnVlLCBtYXhlcnI6IDEwMDAsIG1heGxlbjogOTAgKi8KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5kb21Ob2RlID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBhZG9wdE5vZGUoZG9jdW1lbnQsIHhtbFRvRG9tTm9kZSh0aGlzKSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5kb21Ob2RlTGlzdCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcy5sZW5ndGgoKSA8IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gYWRvcHROb2RlKGRvY3VtZW50LCBjcmVhdGVEb2N1bWVudEZyb20odGhpcykuZG9jdW1lbnRFbGVtZW50KS5jaGlsZE5vZGVzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUueHBhdGggPSBmdW5jdGlvbiAoeHBhdGhFeHApCiAgICAgICAgewogICAgICAgICAgICB2YXIgcmVzID0gbmV3IFhNTExpc3QsCiAgICAgICAgICAgICAgICBpID0gMCwgbCA9IHRoaXMubGVuZ3RoKCksCiAgICAgICAgICAgICAgICB4cHI7CgogICAgICAgICAgICBpZiAobCAhPT0gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzLkFwcGVuZCh0aGlzW2ldLnhwYXRoKHhwYXRoRXhwKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgeHByID0gZXZhbHVhdGUoY3JlYXRlRG9jdW1lbnRGcm9tKHRoaXMpLCB4cGF0aEV4cCwgdGhpcyk7CgogICAgICAgICAgICBmb3IgKGw9eHByLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzLkFwcGVuZChUb1hNTCh4cHJbaV0pKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnRyYW5zZm9ybSA9IGZ1bmN0aW9uICh4c2x0LCBwYXJhbXMpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIXhzbHQgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGRvYywgcmVzLCBpLCBsID0gdGhpcy5sZW5ndGgoKSwgYzsKCiAgICAgICAgICAgIGlmIChsID4gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzID0gbmV3IFhNTExpc3QoKTsKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzLkFwcGVuZCh0aGlzW2ldLnRyYW5zZm9ybSh4c2x0LCBwYXJhbXMpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm0odGhpcywgeHNsdCwgcGFyYW1zKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFhNTExpc3QgKCRzdHJpbmcpCiAgICAgICAgewogICAgICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgWE1MTGlzdCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBUb1hNTExpc3QoJHN0cmluZyB8fCAiIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX0NsYXNzID0gIlhNTExpc3QiOwoKICAgICAgICAgICAgdGhpcy5fVmFsdWUgPSB1bmRlZmluZWQ7CgoKICAgICAgICAgICAgdGhpcy5fVGFyZ2V0T2JqZWN0ID0gbnVsbDsKCiAgICAgICAgICAgIHRoaXMuX1RhcmdldFByb3BlcnR5ID0gbnVsbDsKCiAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuID0gW107CgogICAgICAgICAgICB0aGlzWzBdID0gbnVsbDsKCiAgICAgICAgICAgIGlmICgkc3RyaW5nKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgbGlzdCA9IFRvWE1MTGlzdCgkc3RyaW5nKSwgaSA9IDAsIGwgPSBsaXN0Ll9DaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgICAgICB0aGlzLl9WYWx1ZSA9IGxpc3QuX1ZhbHVlOwoKICAgICAgICAgICAgICAgIGZvciAoO2kgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0gPSB0aGlzW2ldID0gbGlzdC5fQ2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnRvU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAiZnVuY3Rpb24gWE1MTGlzdCgpIHtcbiBbbmF0aXZlIGNvZGVdIFxufSI7CiAgICAgICAgfTsKCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUgPSBuZXcgWE1MKCk7CgogICAgICAgIHZhciBpZ25vcmUgPSB7eHBhdGg6MSxkb21Ob2RlTGlzdDoxLHRyYW5zZm9ybToxfTsKCiAgICAgICAgZm9yIChwIGluIFhNTExpc3QucHJvdG90eXBlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGlnbm9yZVtwXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFhNTExpc3QucHJvdG90eXBlW3BdID0gKGZ1bmN0aW9uKHApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggIT0gMSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoImNhbm5vdCBjYWxsICIgKyBwICsgIiBtZXRob2Qgb24gYW4gWE1MIGxpc3Qgd2l0aCAiICsgdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoICsgIiBlbGVtZW50cyIpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTC5wcm90b3R5cGVbcF0uYXBwbHkodGhpc1swXSwgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0pKHApOwogICAgICAgIH0KCiAgICAgICAgdHJ5ewogICAgICAgICAgICBkZWxldGUgWE1MTGlzdC5wcm90b3R5cGUuX0F0dHJpYnV0ZXM7CiAgICAgICAgICAgIGRlbGV0ZSBYTUxMaXN0LnByb3RvdHlwZS5fSW5TY29wZU5hbWVzcGFjZXM7CiAgICAgICAgfWNhdGNoKGUpe30KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBBdHRyaWJ1dGVOYW1lIGF0dHJpYnV0ZU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuYXR0cmlidXRlID0gZnVuY3Rpb24gKGF0dHJpYnV0ZU5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gR2V0TGlzdC5jYWxsKHRoaXMsIFRvQXR0cmlidXRlTmFtZShhdHRyaWJ1dGVOYW1lKSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5hdHRyaWJ1dGVzID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBHZXRMaXN0LmNhbGwodGhpcywgVG9BdHRyaWJ1dGVOYW1lKCIqIikpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgcHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLmNoaWxkID0gZnVuY3Rpb24gKHByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIHI7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHRoaXM7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgciA9IHRoaXNbaV0uY2hpbGQocHJvcGVydHlOYW1lKTsKCiAgICAgICAgICAgICAgICBpZiAoci5fQ2hpbGRyZW4ubGVuZ3RoID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5jaGlsZHJlbiA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gR2V0TGlzdC5jYWxsKHRoaXMsICIqIik7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5jb21tZW50cyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCByOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHIgPSB0aGlzW2ldLmNvbW1lbnRzKCk7CgogICAgICAgICAgICAgICAgICAgIGlmIChyLl9DaGlsZHJlbi5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQocik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFhNTCB2YWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uICh2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXSA9PSB2YWx1ZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRGVlcENvcHlMaXN0LmNhbGwodGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLmRlc2NlbmRhbnRzID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRGVzY2VuZGFudHNMaXN0LmNhbGwodGhpcywgbmFtZSB8fCAiKiIpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5lbGVtZW50cyA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgbmFtZSA9IFRvWE1MTmFtZShuYW1lIHx8ICIqIik7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIHI7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHRoaXM7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldFByb3BlcnR5ID0gbmFtZTsKCiAgICAgICAgICAgIGZvciAoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByID0gdGhpc1tpXS5lbGVtZW50cyhuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHIuX0NoaWxkcmVuLmxlbmd0aCA+IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBIYXNQcm9wZXJ0eS5jYWxsKHRoaXMsIG5hbWUpCiAgICAgICAgICAgICAgICB8fCAoZGVmYXVsdFhNTExpc3RQcm9wZXJ0aWVzLmluZGV4T2YoIiwiICsgbmFtZSArICIsIikgPT09IC0xICYmIGhhc093blByb3BlcnR5LmNhbGwodGhpcywgbmFtZSkpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuaGFzQ29tcGxleENvbnRlbnQgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW4ubGVuZ3RoID09PSAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpc1swXS5oYXNDb21wbGV4Q29udGVudCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5oYXNTaW1wbGVDb250ZW50ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggPT09IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzWzBdLmhhc1NpbXBsZUNvbnRlbnQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBOdW1iZXIKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzW2ldLm5vcm1hbGl6ZSgpOwogICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXNbaV0uX0NsYXNzID09PSAidGV4dCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGkrMSA8IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCAmJiB0aGlzW2krMV0uX0NsYXNzID09PSAidGV4dCIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2ldLl9WYWx1ZSA9ICh0aGlzW2ldLl9WYWx1ZSB8fCAiIikgKyAodGhpc1tpKzFdLl9WYWx1ZSB8fCAiIik7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuRGVsZXRlKGkrMSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fVmFsdWUubGVuZ3RoID09PSAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5EZWxldGUoaSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgKytpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MIHwgdW5kZWZpbmVkCiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUucGFyZW50ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggPT09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIHBhcmVudCA9IHRoaXNbMF0uX1BhcmVudCwgaSA9IDEsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9QYXJlbnQgIT0gcGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBwYXJlbnQ7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnByb2Nlc3NpbmdJbnN0cnVjdGlvbnMgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIG5hbWUgPSBUb1hNTE5hbWUobmFtZSB8fCAiKiIpOwogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCByOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHIgPSB0aGlzW2ldLnByb2Nlc3NpbmdJbnN0cnVjdGlvbnMobmFtZSk7CgogICAgICAgICAgICAgICAgICAgIGlmIChyLl9DaGlsZHJlbi5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQocik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IE51bWJlciBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQobmFtZSkgPiAwICYmIHBhcnNlSW50KG5hbWUpIDwgdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUudGV4dCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCByOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHIgPSB0aGlzW2ldLnRleHQoKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHIuX0NoaWxkcmVuLmxlbmd0aCA+IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVG9TdHJpbmcodGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnRvWE1MU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUb1hNTFN0cmluZyh0aGlzKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnZhbHVlT2YgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IE51bWJlciB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgVmFsdWUKICAgICAgICAgKiAgICBAcGFyYW0gaXNFbGVtZW50CiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLlB1dCA9IGZ1bmN0aW9uIChQcm9wZXJ0eU5hbWUsIFZhbHVlLGlzQ2hpbGRFbGVtZW50KQogICAgICAgIHsKICAgICAgICAgICAgaXNDaGlsZEVsZW1lbnQgPSBpc0NoaWxkRWxlbWVudCAhPT0gdW5kZWZpbmVkID8gaXNDaGlsZEVsZW1lbnQgOiBmYWxzZTsKICAgICAgICAgICAgdmFyIGkgPSBwYXJzZUludChQcm9wZXJ0eU5hbWUpLCByLCB5LCBsLCB6LCBwYXJlbnQsIGMsIGogPSAwLCBxLCB0OwoKICAgICAgICAgICAgaWYgKGkrIiIgPT0gUHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByID0gUmVzb2x2ZVZhbHVlLmNhbGwodGhpcy5fVGFyZ2V0T2JqZWN0KTsKICAgICAgICAgICAgICAgIC8qIEZpcmVmb3ggZG9lc24ndCBkbyB0aGlzCiAgICAgICAgICAgICAgICAgaWYgKHIgPT0gbnVsbCkKICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoaSA+PSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHIubGVuZ3RoKCkgIT0gMSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHIgPSByWzBdOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLyogRmlyZWZveCBkb2Vzbid0IGRvIHRoaXMKICAgICAgICAgICAgICAgICAgICAgaWYgKHIuX0NsYXNzICE9ICJlbGVtZW50IikKICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHkgPSBuZXcgWE1MKCk7CiAgICAgICAgICAgICAgICAgICAgeS5fUGFyZW50ID0gcjsKICAgICAgICAgICAgICAgICAgICB5Ll9OYW1lID0gdGhpcy5fVGFyZ2V0UHJvcGVydHk7CiAgICAgICAgICAgICAgICAgICAgeS5fQXR0cmlidXRlcyA9IHt9OwoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fVGFyZ2V0UHJvcGVydHkgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhciAmJiBHZXQuY2FsbChyLCB5Ll9OYW1lKS5sZW5ndGgoKSA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB5Ll9DbGFzcyA9ICJhdHRyaWJ1dGUiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghaXNDaGlsZEVsZW1lbnQgJiYgKHRoaXMuX1RhcmdldFByb3BlcnR5ID09IG51bGwgfHwgdGhpcy5fVGFyZ2V0UHJvcGVydHkubG9jYWxOYW1lID09PSAiKiIpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgeS5fTmFtZSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIHkuX0NsYXNzID0gInRleHQiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB5Ll9DbGFzcyA9ICJlbGVtZW50IjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh5Ll9DbGFzcyAhPSAiYXR0cmlidXRlIikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqID0gMDsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGogPCByLl9DaGlsZHJlbi5sZW5ndGgtMSAmJiByW2pdICE9PSB0aGlzW2ktMV0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArK2o7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGogPSByLl9DaGlsZHJlbi5sZW5ndGggLSAxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc2VydC5jYWxsKHIsIGorMSwgeSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChWYWx1ZSBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkuX05hbWUgPSBWYWx1ZS5fVGFyZ2V0UHJvcGVydHk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkuX05hbWUgPSBWYWx1ZS5fTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhpcy5BcHBlbmQoeSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCEoVmFsdWUgaW5zdGFuY2VvZiBYTUwpIHx8IFZhbHVlLl9DbGFzcyA9PT0gInRleHQiIHx8IFZhbHVlLl9DbGFzcyA9PT0gImF0dHJpYnV0ZSIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVmFsdWUgPSBUb1N0cmluZyhWYWx1ZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHRoaXNbaV0uX0NsYXNzID09PSAiYXR0cmlidXRlIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB6ID0gVG9BdHRyaWJ1dGVOYW1lKHRoaXNbaV0uX05hbWUpOwogICAgICAgICAgICAgICAgICAgIHRoaXNbaV0uX1BhcmVudC5QdXQoeiwgVmFsdWUpOwogICAgICAgICAgICAgICAgICAgIHRoaXNbaV0gPSB0aGlzW2ldLl9QYXJlbnQuYXR0cmlidXRlKHopWzBdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vc2hhbGxvdyBjb3B5PwogICAgICAgICAgICAgICAgICAgIGMgPSBWYWx1ZTsKICAgICAgICAgICAgICAgICAgICBwYXJlbnQgPSB0aGlzW2ldLl9QYXJlbnQ7CgogICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBxID0gdGhpc1tpXS5jaGlsZEluZGV4KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbChwYXJlbnQsIHEsIGMpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gYy5fQ2hpbGRyZW4ubGVuZ3RoOyBqIDwgbDsgKytqKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLl9DaGlsZHJlbltqXSA9IGNbal0gPSBwYXJlbnQuX0NoaWxkcmVuW3Eral07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChjLl9DaGlsZHJlbi5sZW5ndGggPT09IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSBpICsgMSwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaiA8IGw7ICsraikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bai0xXSA9IHRoaXNbai0xXSA9IHRoaXNbal0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGogPiBpOyAtLWopCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHogPSBUb1N0cmluZyhqICsgYy5fQ2hpbGRyZW4ubGVuZ3RoIC0gMSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlblt6XSA9IHRoaXNbel0gPSB0aGlzW2pdOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gYy5fQ2hpbGRyZW4ubGVuZ3RoOyBqIDwgbDsgKytqKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baStqXSA9IHRoaXNbaStqXSA9IGNbal07CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MIHx8ICgiLHRleHQsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uIikuaW5kZXhPZigiLCIgKyB0aGlzW2ldLl9DbGFzcysiLCIpID4gLTEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gISF0aGlzW2ldICYmIHRoaXNbaV0uX1BhcmVudDsKCiAgICAgICAgICAgICAgICAgICAgaWYocGFyZW50KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcSA9IHRoaXNbaV0uY2hpbGRJbmRleCgpOwogICAgICAgICAgICAgICAgICAgICAgICBSZXBsYWNlLmNhbGwocGFyZW50LCBxLCBWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlID0gcGFyZW50Ll9DaGlsZHJlbltxXTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh0b1N0cmluZy5jYWxsKFZhbHVlKSA9PT0gIltvYmplY3QgU3RyaW5nXSIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0ID0gVG9YTUwoVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0Ll9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXSA9IHRoaXNbaV0gPSB0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5BcHBlbmQoWE1MTGlzdChWYWx1ZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIEZpcmVmb3ggZG9lc24ndCBkbyB0aGlzCiAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLmxlbmd0aCgpIDw9IDEpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICBpZiAodGhpcy5sZW5ndGgoKSA9PT0gMCkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIHIgPSBSZXNvbHZlVmFsdWVMaXN0LmNhbGwodGhpcyk7CgogICAgICAgICAgICAgaWYgKHIgPT0gbnVsbCB8fCByLmxlbmd0aCgpICE9IDEpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICB0aGlzLkFwcGVuZChyKTsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIHRoaXNbMF0uUHV0KFByb3BlcnR5TmFtZSwgVmFsdWUpOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgfSovCgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTnVtYmVyIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLkRlbGV0ZSA9IGZ1bmN0aW9uIChQcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICB2YXIgaSA9IHBhcnNlSW50KFByb3BlcnR5TmFtZSksIHBhcmVudCwgcSwgbDsKCiAgICAgICAgICAgIGlmIChpKyIiID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGkgPj0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHBhcmVudCA9IHRoaXNbaV0uX1BhcmVudDsKCiAgICAgICAgICAgICAgICBpZiAocGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9ICJhdHRyaWJ1dGUiKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LkRlbGV0ZShUb0F0dHJpYnV0ZU5hbWUodGhpc1tpXS5fTmFtZSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBEZWxldGVCeUluZGV4LmNhbGwocGFyZW50LCB0aGlzW2ldLmNoaWxkSW5kZXgoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbi5zcGxpY2UoUHJvcGVydHlOYW1lLDEpOwogICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzW1Byb3BlcnR5TmFtZV07CiAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQoKICAgICAgICAgICAgICAgIGZvciAocSA9IGkgKyAxLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW3EtMV0gPSB0aGlzW3EtMV0gPSB0aGlzW3FdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogRmlyZWZveCB3b24ndCBkbyB0aGlzCiAgICAgICAgICAgICBmb3IgKHEgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICAgewogICAgICAgICAgICAgaWYgKHRoaXNbcV0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICB0aGlzW3FdLkRlbGV0ZShQcm9wZXJ0eU5hbWUpOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBWYWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5BcHBlbmQgPSBmdW5jdGlvbiAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIShWYWx1ZSBpbnN0YW5jZW9mIFhNTCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgaSA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCwgbiA9IDEsIGogPSAwOwoKICAgICAgICAgICAgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbiA9IFZhbHVlLl9DaGlsZHJlbi5sZW5ndGg7CgogICAgICAgICAgICAgICAgaWYgKG4gPT0gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLl9UYXJnZXRPYmplY3QgPSBWYWx1ZS5fVGFyZ2V0T2JqZWN0OwogICAgICAgICAgICAgICAgdGhpcy5fVGFyZ2V0UHJvcGVydHkgPSBWYWx1ZS5fVGFyZ2V0UHJvcGVydHk7CgogICAgICAgICAgICAgICAgZm9yICg7aiA8IG47ICsraikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpK2pdID0gdGhpc1tpK2pdID0gVmFsdWVbal07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXSA9IHRoaXNbaV0gPSBWYWx1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBWYWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5FcXVhbHMgPSBmdW5jdGlvbiAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoVmFsdWUgPT0gdW5kZWZpbmVkICYmIHRoaXMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUxMaXN0ICYmIFZhbHVlLl9DaGlsZHJlbi5sZW5ndGggPT09IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzW2ldLkVxdWFscyhWYWx1ZVtpXSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXNbMF0uRXF1YWxzKFZhbHVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBSZXNvbHZlVmFsdWVMaXN0ICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW4ubGVuZ3RoID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh0aGlzLl9UYXJnZXRPYmplY3QgPT0gbnVsbAogICAgICAgICAgICAgICAgfHwgdGhpcy5fVGFyZ2V0UHJvcGVydHkgPT0gbnVsbAogICAgICAgICAgICAgICAgfHwgdGhpcy5fVGFyZ2V0UHJvcGVydHkgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lCiAgICAgICAgICAgICAgICB8fCB0aGlzLl9UYXJnZXRQcm9wZXJ0eS5sb2NhbE5hbWUgPT09ICIqIgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGJhc2UgPSBSZXNvbHZlVmFsdWUuY2FsbCh0aGlzLl9UYXJnZXRPYmplY3QpLCB0YXJnZXQ7CgogICAgICAgICAgICBpZiAoYmFzZSA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGFyZ2V0ID0gR2V0LmNhbGwoYmFzZSwgdGhpcy5fVGFyZ2V0UHJvcGVydHkpOwoKICAgICAgICAgICAgaWYgKHRhcmdldC5fQ2hpbGRyZW4ubGVuZ3RoID09PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoYmFzZSBpbnN0YW5jZW9mIFhNTExpc3QgJiYgYmFzZS5fQ2hpbGRyZW4ubGVuZ3RoID4gMSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBiYXNlLlB1dCh0aGlzLl9UYXJnZXRQcm9wZXJ0eSwgIiIpOwoKICAgICAgICAgICAgICAgIHRhcmdldCA9IEdldC5jYWxsKGJhc2UsIHRoaXMuX1RhcmdldFByb3BlcnR5KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRhcmdldDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IE5hbWVzcGFjZSB8IFFOYW1lIHByZWZpeAogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgdXJpCiAgICAgICAgICogICAgQHJldHVybnMgTmFtZXNwYWNlCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBOYW1lc3BhY2UgKHByZWZpeCwgdXJpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIE5hbWVzcGFjZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBwcmVmaXggJiYgcHJlZml4IGluc3RhbmNlb2YgTmFtZXNwYWNlCiAgICAgICAgICAgICAgICAgICAgPyBwcmVmaXgKICAgICAgICAgICAgICAgICAgICA6IG5ldyBOYW1lc3BhY2UocHJlZml4LCB1cmkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodXJpID09PSB1bmRlZmluZWQgJiYgcHJlZml4ID09PSB1bmRlZmluZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRoaXMucHJlZml4ID0gIiI7CiAgICAgICAgICAgICAgICB0aGlzLnVyaSA9ICIiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHVyaSA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB1cmkgPSBwcmVmaXg7CiAgICAgICAgICAgICAgICBwcmVmaXggPSB1bmRlZmluZWQ7CgogICAgICAgICAgICAgICAgaWYgKHVyaSBpbnN0YW5jZW9mIE5hbWVzcGFjZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnByZWZpeCA9IHVyaS5wcmVmaXg7CiAgICAgICAgICAgICAgICAgICAgdGhpcy51cmkgPSB1cmkudXJpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAodXJpIGluc3RhbmNlb2YgUU5hbWUgJiYgdXJpLnVyaSAhPT0gbnVsbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVyaSA9IHVyaS51cmk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy51cmkgPSBUb1N0cmluZyh1cmkpOwoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy51cmkgPT0gIiIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZWZpeCA9ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh1cmkgaW5zdGFuY2VvZiBRTmFtZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVyaSA9IHVyaS51cmk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy51cmkgPSBUb1N0cmluZyh1cmkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICh0aGlzLnVyaSA9PT0gIiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHByZWZpeCA9PT0gdW5kZWZpbmVkIHx8IFRvU3RyaW5nKHByZWZpeCkgPT09ICIiKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmVmaXggPSAiIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigiY2Fubm90IGRlZmluZSB0aGUgcHJlZml4IGZvciBhbiBlbXB0eSB1cmkiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChwcmVmaXggPT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnByZWZpeCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnByZWZpeCA9IFRvU3RyaW5nKHByZWZpeCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAdmFyIFN0cmluZwogICAgICAgICAqLwogICAgICAgIE5hbWVzcGFjZS5wcm90b3R5cGUucHJlZml4ID0gdW5kZWZpbmVkOwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHZhciBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBOYW1lc3BhY2UucHJvdG90eXBlLnVyaSA9IHVuZGVmaW5lZDsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIE5hbWVzcGFjZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMudXJpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gTmFtZXNwYWNlIHwgU3RyaW5nIHwgUU5hbWUgTmFtZVNwYWNlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZwogICAgICAgICAqICAgIEByZXR1cm5zIFFOYW1lCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gUU5hbWUgKE5hbWVTcGFjZSwgTmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBRTmFtZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBOYW1lU3BhY2UgaW5zdGFuY2VvZiBRTmFtZQogICAgICAgICAgICAgICAgICAgID8gTmFtZVNwYWNlCiAgICAgICAgICAgICAgICAgICAgOiBuZXcgUU5hbWUoTmFtZVNwYWNlLCBOYW1lKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKE5hbWUgPT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTmFtZSA9IE5hbWVTcGFjZTsKICAgICAgICAgICAgICAgIE5hbWVTcGFjZSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKE5hbWVzcGFjZSBpbnN0YW5jZW9mIFFOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoTmFtZSA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE5hbWUgPSBOYW1lLmxvY2FsTmFtZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgTmFtZSA9IE5hbWUgPT09IHVuZGVmaW5lZCB8fCBOYW1lID09PSBudWxsCiAgICAgICAgICAgICAgICA/ICIiCiAgICAgICAgICAgICAgICA6IFRvU3RyaW5nKE5hbWUpOwoKICAgICAgICAgICAgaWYgKE5hbWVTcGFjZSA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBOYW1lU3BhY2UgPSBOYW1lID09PSAiKiIgPyBudWxsIDogR2V0RGVmYXVsdE5hbWVzcGFjZSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLmxvY2FsTmFtZSA9IE5hbWU7CgogICAgICAgICAgICBpZiAoTmFtZVNwYWNlID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRoaXMudXJpID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE5hbWVTcGFjZSA9IE5hbWVzcGFjZShOYW1lU3BhY2UpOwogICAgICAgICAgICAgICAgdGhpcy51cmkgPSBOYW1lU3BhY2UudXJpOwogICAgICAgICAgICAgICAgdGhpcy5fUHJlZml4ID0gTmFtZVNwYWNlLnByZWZpeDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEB2YXIgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgUU5hbWUucHJvdG90eXBlLmxvY2FsTmFtZSA9IHVuZGVmaW5lZDsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEB2YXIgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgUU5hbWUucHJvdG90eXBlLnVyaSA9IHVuZGVmaW5lZDsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBPYmplY3QgSW5TY29wZU5hbWVzcGFjZXMKICAgICAgICAgKiAgICBAcmV0dXJucyBOYW1lc3BhY2UKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEdldE5hbWVzcGFjZSAocSwgSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgewogICAgICAgICAgICBpZighcSkKICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE5hbWVzcGFjZSgpOwogICAgICAgICAgICBpZiAocS51cmkgPT09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSW5TY29wZU5hbWVzcGFjZXMgPSBJblNjb3BlTmFtZXNwYWNlcyB8fCB7fTsKCiAgICAgICAgICAgIHZhciBucywgcDsKCiAgICAgICAgICAgIGZvciAocCBpbiBJblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHEudXJpID09PSBJblNjb3BlTmFtZXNwYWNlc1twXS51cmkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbnMgPSBJblNjb3BlTmFtZXNwYWNlc1twXTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCEhcS5fUHJlZml4ICYmIHEuX1ByZWZpeCA9PT0gbnMucHJlZml4KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5zOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFucykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbnMgPSAhIXEuX1ByZWZpeAogICAgICAgICAgICAgICAgICAgID8gbmV3IE5hbWVzcGFjZShxLl9QcmVmaXgsIHEudXJpKQogICAgICAgICAgICAgICAgICAgIDogbmV3IE5hbWVzcGFjZShxLnVyaSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBuczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgUU5hbWUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMudXJpCiAgICAgICAgICAgICAgICA/IHRoaXMudXJpICsgIjo6IiArIHRoaXMubG9jYWxOYW1lCiAgICAgICAgICAgICAgICA6IHRoaXMubG9jYWxOYW1lOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gQXR0cmlidXRlTmFtZSB8IFFOYW1lIHwgU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBBdHRyaWJ1dGVOYW1lCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gQXR0cmlidXRlTmFtZSAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5hbWUgJiYgKG5hbWUgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lIHx8IG5hbWUgaW5zdGFuY2VvZiBRTmFtZSkKICAgICAgICAgICAgICAgICAgICA/IG5hbWUKICAgICAgICAgICAgICAgICAgICA6IG5ldyBBdHRyaWJ1dGVOYW1lKG5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLl9OYW1lID0gbmFtZSBpbnN0YW5jZW9mIFFOYW1lCiAgICAgICAgICAgICAgICA/IG5hbWUKICAgICAgICAgICAgICAgIDogbmV3IFFOYW1lKG5ldyBOYW1lc3BhY2UoR2V0RGVmYXVsdE5hbWVzcGFjZSgpfHx1bmRlZmluZWQpLCBuYW1lKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAdmFyIFN0cmluZwogICAgICAgICAqLwogICAgICAgIEF0dHJpYnV0ZU5hbWUucHJvdG90eXBlLmxvY2FsTmFtZSA9IHVuZGVmaW5lZDsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEB2YXIgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgQXR0cmlidXRlTmFtZS5wcm90b3R5cGUudXJpID0gdW5kZWZpbmVkOwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgQXR0cmlidXRlTmFtZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICJAIiArICghIXRoaXMuX05hbWUudXJpCiAgICAgICAgICAgICAgICA/IHRoaXMuX05hbWUudXJpICsgIjo6IiArIHRoaXMuX05hbWUubG9jYWxOYW1lCiAgICAgICAgICAgICAgICA6IHRoaXMuX05hbWUubG9jYWxOYW1lCiAgICAgICAgICAgICAgICApOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEFueU5hbWUgKCkKICAgICAgICB7CgogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBtaXhlZCB2YWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBpc1hNTE5hbWUgKHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgIHZhciBxID0gUU5hbWUodmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhdGNoIChlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAhIXEubG9jYWxOYW1lICYmICghIXEubG9jYWxOYW1lLm1hdGNoKC9eW1x3XC1dKyQvaSkgfHwgISFxLmxvY2FsTmFtZS5tYXRjaCgvXltcd1wtXDpdKyQvaSkpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBtaXhlZCB2YWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gVG9TdHJpbmcgKHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGkgPSAwLCBsLCBzOwoKICAgICAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHZhbHVlLmhhc1NpbXBsZUNvbnRlbnQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzID0gIiI7CgogICAgICAgICAgICAgICAgICAgIGZvciAobCA9IHZhbHVlLmxlbmd0aCgpOyBpIDwgbDsgKytpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlW2ldLl9DbGFzcyAhPSAiY29tbWVudCIgJiYgdmFsdWVbaV0uX0NsYXNzICE9ICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSBUb1N0cmluZyh2YWx1ZVtpXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBUb1hNTFN0cmluZyh2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5fQ2xhc3MgPT09ICJhdHRyaWJ1dGUiIHx8IHZhbHVlLl9DbGFzcyA9PT0gInRleHQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5fVmFsdWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHZhbHVlLmhhc1NpbXBsZUNvbnRlbnQoKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzID0gIiI7CgogICAgICAgICAgICAgICAgICAgIGZvciAobCA9IHZhbHVlLmxlbmd0aCgpOyBpIDwgbDsgKytpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmNoaWxkKGkpLl9DbGFzcyAhPSAiY29tbWVudCIgJiYgdmFsdWUuY2hpbGQoaSkuX0NsYXNzICE9ICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSBUb1N0cmluZyh2YWx1ZS5jaGlsZChpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBUb1hNTFN0cmluZyh2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gIkAiICsgVG9TdHJpbmcodmFsdWUuX05hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZAogICAgICAgICAgICAgICAgPyAiIgogICAgICAgICAgICAgICAgOiAiIiArIHZhbHVlOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBYTUwgaW5wdXQKICAgICAgICAgKiAgICBAcGFyYW0gT2JqZWN0IEFuY2VzdG9yTmFtZXNwYWNlcwogICAgICAgICAqICAgIEBwYXJhbSBOdW1iZXIgSW5kZW50TGV2ZWwKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBUb1hNTFN0cmluZyAoaW5wdXQsIEFuY2VzdG9yTmFtZXNwYWNlcywgSW5kZW50TGV2ZWwpCiAgICAgICAgewogICAgICAgICAgICB2YXIgcyA9ICIiLCBwID0gMCwgdGVtcCwgdGVtcDIsIG5hbWVzcGFjZSwgbmFtZXNwYWNlVW5pb24sCiAgICAgICAgICAgICAgICBuYW1lc3BhY2VEZWNsYXJhdGlvbnMgPSB7fSwgYXR0ckFuZE5hbWVzcGFjZXMsIHByZWZpeGVzLCBkZWZhdWx0U2V0OwoKICAgICAgICAgICAgQW5jZXN0b3JOYW1lc3BhY2VzID0gQW5jZXN0b3JOYW1lc3BhY2VzIHx8IHt9OwoKICAgICAgICAgICAgSW5kZW50TGV2ZWwgPSBOdW1iZXIoSW5kZW50TGV2ZWwgfHwgMCk7CgogICAgICAgICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0ZW1wID0gaW5wdXQuaGFzU2ltcGxlQ29udGVudCgpOwoKICAgICAgICAgICAgICAgIHRlbXAyID0gaW5wdXQubGVuZ3RoKCk7CgogICAgICAgICAgICAgICAgZm9yICg7IHAgPCB0ZW1wMjsgKytwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChwID4gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gIlxyXG4iOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcyArPSBUb1hNTFN0cmluZyhpbnB1dFtwXSwgQW5jZXN0b3JOYW1lc3BhY2VzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChpbnB1dCBpbnN0YW5jZW9mIFhNTCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKFhNTC5wcmV0dHlQcmludGluZykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvL3MgKz0gbmV3IEFycmF5KEluZGVudExldmVsKzEpLmpvaW4oIiAiKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKDsgcCA8IEluZGVudExldmVsOyArK3ApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzICs9ICIgIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgc3dpdGNoIChpbnB1dC5fQ2xhc3MpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAidGV4dCI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzICsgRXNjYXBlRWxlbWVudFZhbHVlKFhNTC5wcmV0dHlQcmludGluZyA/IHRyaW0oaW5wdXQuX1ZhbHVlKSA6IGlucHV0Ll9WYWx1ZSk7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgImF0dHJpYnV0ZSI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzICsgRXNjYXBlQXR0cmlidXRlVmFsdWUoaW5wdXQuX1ZhbHVlKTsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAiY29tbWVudCI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzICsgIjwhLS0iICsgaW5wdXQuX1ZhbHVlICsgIi0tPiI7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcyArICI8PyIgKyBpbnB1dC5fTmFtZS5sb2NhbE5hbWUgKyAiICIgKyBpbnB1dC5fVmFsdWUgKyAiPz4iOwoKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VVbmlvbiA9IGV4dGVuZCh7fSwgQW5jZXN0b3JOYW1lc3BhY2VzKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAocCBpbiBpbnB1dC5fSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAgPSBpbnB1dC5fSW5TY29wZU5hbWVzcGFjZXNbcF07CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFBbmNlc3Rvck5hbWVzcGFjZXNbKHRlbXAucHJlZml4fHwiIildIHx8IEFuY2VzdG9yTmFtZXNwYWNlc1sodGVtcC5wcmVmaXh8fCIiKV0udXJpICE9IHRlbXAudXJpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVuaW9uWyh0ZW1wLnByZWZpeHx8IiIpXSA9IG5hbWVzcGFjZURlY2xhcmF0aW9uc1sodGVtcC5wcmVmaXh8fCIiKV0gPSBuZXcgTmFtZXNwYWNlKHRlbXApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlucHV0Ll9QYXJlbnQpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVuaW9uWyhpbnB1dC5fRGVmYXVsdE5hbWVzcGFjZS5wcmVmaXh8fCIiKV0gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZURlY2xhcmF0aW9uc1soaW5wdXQuX0RlZmF1bHROYW1lc3BhY2UucHJlZml4fHwiIildID0gbmV3IE5hbWVzcGFjZShpbnB1dC5fRGVmYXVsdE5hbWVzcGFjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmlyZWZveCBkb2Vzbid0IGRvIHRoaXMKICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAocCBpbiBpbnB1dC5fQXR0cmlidXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSA9IEdldE5hbWVzcGFjZShpbnB1dC5fQXR0cmlidXRlc1twXS5fTmFtZSwgbmFtZXNwYWNlVW5pb24pOwoKICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2UucHJlZml4ID09PSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UucHJlZml4ID0gIW5hbWVzcGFjZVVuaW9uWyIiXSA/ICIiIDogbmV3UHJlZml4KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSghIW5hbWVzcGFjZVVuaW9uW25hbWVzcGFjZS5wcmVmaXhdKTsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VVbmlvbltuYW1lc3BhY2UucHJlZml4XSA9IG5hbWVzcGFjZURlY2xhcmF0aW9uc1tuYW1lc3BhY2UucHJlZml4XSA9IG5hbWVzcGFjZTsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgICAgICAgICBzICs9ICI8IjsKCiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSA9IEdldE5hbWVzcGFjZShpbnB1dC5fTmFtZSwgbmFtZXNwYWNlRGVjbGFyYXRpb25zKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lc3BhY2UucHJlZml4KQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9IG5hbWVzcGFjZS5wcmVmaXggKyAiOiI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gaW5wdXQuX05hbWUgPyBpbnB1dC5fTmFtZS5sb2NhbE5hbWUgOiAiIjsKCiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJBbmROYW1lc3BhY2VzID0gZXh0ZW5kKHt9LCBpbnB1dC5fQXR0cmlidXRlcywgbmFtZXNwYWNlRGVjbGFyYXRpb25zKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRTZXQgPSBmYWxzZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAocCBpbiBhdHRyQW5kTmFtZXNwYWNlcykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiICI7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJBbmROYW1lc3BhY2VzW3BdIGluc3RhbmNlb2YgWE1MKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAgPSBHZXROYW1lc3BhY2UoYXR0ckFuZE5hbWVzcGFjZXNbcF0uX05hbWUsIEFuY2VzdG9yTmFtZXNwYWNlcyk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wLnByZWZpeCA9PT0gdW5kZWZpbmVkICYmICFuYW1lc3BhY2VVbmlvblsiIl0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3sKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAucHJlZml4ID0gIW5hbWVzcGFjZVVuaW9uWyIiXSA/ICIiIDogbmV3UHJlZml4KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUobmFtZXNwYWNlVW5pb25bdGVtcC5wcmVmaXhdKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVuaW9uW3RlbXAucHJlZml4XSA9IG5hbWVzcGFjZURlY2xhcmF0aW9uc1t0ZW1wLnByZWZpeF0gPSBuZXcgTmFtZXNwYWNlKHRlbXApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAucHJlZml4KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSB0ZW1wLnByZWZpeCArICI6IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gYXR0ckFuZE5hbWVzcGFjZXNbcF0ubG9jYWxOYW1lKCkgKyAnPSInICsgRXNjYXBlQXR0cmlidXRlVmFsdWUoYXR0ckFuZE5hbWVzcGFjZXNbcF0uX1ZhbHVlKSArICciJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICJ4bWxucyI7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4ICYmIGRlZmF1bHRTZXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3sKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJBbmROYW1lc3BhY2VzW3BdLnByZWZpeCA9IG5ld1ByZWZpeCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlKCEhbmFtZXNwYWNlVW5pb25bYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4XSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VVbmlvblthdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXhdID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZURlY2xhcmF0aW9uc1thdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXhdID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTmFtZXNwYWNlKGF0dHJBbmROYW1lc3BhY2VzW3BdKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gIjoiICsgYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4ICYmICFkZWZhdWx0U2V0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFNldCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGF0dHJBbmROYW1lc3BhY2VzW3BdLnByZWZpeCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gIjoiICsgYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAnPSInICsgRXNjYXBlQXR0cmlidXRlVmFsdWUoYXR0ckFuZE5hbWVzcGFjZXNbcF0udXJpKSArICciJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGlucHV0Ll9DaGlsZHJlbi5sZW5ndGg7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRlbXApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzICsgIi8+IjsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiPiI7CgogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHRlbXAgPiAxIHx8ICh0ZW1wID09IDEgJiYgaW5wdXQuX0NsYXNzICE9PSAidGV4dCIpOwoKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXMgPSAoISFYTUwucHJldHR5UHJpbnRpbmcgJiYgISF0ZW1wMikgPyBJbmRlbnRMZXZlbCArIE51bWJlcihYTUwucHJldHR5SW5kZW50KSA6IDA7CgogICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXhlcyA9ICEhWE1MLnByZXR0eVByaW50aW5nICYmICEhdGVtcDI7CgogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHAgPSAwOyBwIDwgdGVtcDsgKytwKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJlZml4ZXMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiXHJcbiI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlucHV0Ll9DaGlsZHJlbltwXSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9IFRvWE1MU3RyaW5nKGlucHV0Ll9DaGlsZHJlbltwXSwgbmFtZXNwYWNlRGVjbGFyYXRpb25zLCBuYW1lcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVmaXhlcykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiXHJcbiI7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChwID0gMDsgcCA8IEluZGVudExldmVsOyArK3ApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiICI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzICsgIjwvIiArIChuYW1lc3BhY2UucHJlZml4ID8gbmFtZXNwYWNlLnByZWZpeCArICI6IiA6ICIiKSArIGlucHV0Ll9OYW1lLmxvY2FsTmFtZSArICI+IjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoaW5wdXQgPT09IHVuZGVmaW5lZCB8fCBpbnB1dCA9PT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHRvU3RyaW5nLmNhbGwoaW5wdXQpID09PSAiW29iamVjdCBPYmplY3RdIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIEVzY2FwZUVsZW1lbnRWYWx1ZSggaW5wdXQudmFsdWVPZigpLnRvU3RyaW5nKCkgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIFRvU3RyaW5nKGlucHV0KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gbWl4ZWQgcwogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqICAgIEB0aHJvd3MgU3ludGF4RXJyb3IgfCBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBUb1hNTCAocykKICAgICAgICB7CiAgICAgICAgICAgIHZhciB4LCBkaXY7CgogICAgICAgICAgICBpZiAocyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChzLmxlbmd0aCgpID09IDEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNbMF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocyBpbnN0YW5jZW9mIFhNTCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoKCIsc3RyaW5nLG51bWJlcixib29sZWFuLCIpLmluZGV4T2YoIiwiICsgdHlwZW9mKHMpKyIsIikgPiAtMSkKICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgIGRpdiA9IHBhcnNlKCc8cGFyZW50IHhtbG5zPSInICsgR2V0RGVmYXVsdE5hbWVzcGFjZSgpICsgJyI+JyArIHMgKyAnPC9wYXJlbnQ+Jyk7CgogICAgICAgICAgICAgICAgeCA9IFRvWE1MKGRpdi5kb2N1bWVudEVsZW1lbnQpCgogICAgICAgICAgICAgICAgaWYgKHgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHgubGVuZ3RoKCkgPT0gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgWE1MKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHgubGVuZ3RoKCkgPT0gMSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHguY2hpbGQoMCkuX1BhcmVudCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB4LmNoaWxkKDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCgogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCJGYWlsZWQgdG8gY29udmVydCBET00gb2JqZWN0IHRvIFhNTCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHMubm9kZVR5cGUgJiYgIWlzTmFOKHMubm9kZVR5cGUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gTWFwSW5mb0l0ZW1Ub1hNTChzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBET01Ob2RlIGkKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIE1hcEluZm9JdGVtVG9YTUwgKGksbikKICAgICAgICB7CiAgICAgICAgICAgIHZhciB4ID0gbmV3IFhNTCgpLCB0ZW1wLCB0ZW1wMiwgdGVtcDMsIGlzTlNjaGVjayA9IGlzTlNEZWYsIGosIGwsIHhtbENoaWxkOwoKICAgICAgICAgICAgeC5fUGFyZW50ID0gbnVsbDsKCiAgICAgICAgICAgIHN3aXRjaCAoaS5ub2RlVHlwZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSBURVhUX05PREU6CiAgICAgICAgICAgICAgICBjYXNlIENEQVRBX1NFQ1RJT05fTk9ERToKICAgICAgICAgICAgICAgICAgICB4Ll9DbGFzcyA9ICJ0ZXh0IjsKICAgICAgICAgICAgICAgICAgICB4Ll9WYWx1ZSA9ICIiOwogICAgICAgICAgICAgICAgICAgIHRlbXAgPSBpOwoKICAgICAgICAgICAgICAgICAgICB3aGlsZSAodGVtcCAmJiAodGVtcC5ub2RlVHlwZSA9PT0gVEVYVF9OT0RFIHx8IHRlbXAubm9kZVR5cGUgPT09IENEQVRBX1NFQ1RJT05fTk9ERSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB4Ll9WYWx1ZSArPSB0ZW1wLnRleHRDb250ZW50IHx8IHRlbXAudGV4dCB8fCB0ZW1wLmRhdGE7CiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAgPSB0ZW1wLm5leHRTaWJsaW5nOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobiAmJiAobi5uIHx8IG4ubiA9PSAwKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgKytuLm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgoKICAgICAgICAgICAgICAgICAgICBpZiAoWE1MLmlnbm9yZVdoaXRlc3BhY2UgJiYgIXguX1ZhbHVlLm1hdGNoKC9cUysvKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHg7CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBDT01NRU5UX05PREU6CiAgICAgICAgICAgICAgICAgICAgaWYgKFhNTC5pZ25vcmVDb21tZW50cykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeC5fQ2xhc3MgPSAiY29tbWVudCI7CiAgICAgICAgICAgICAgICAgICAgeC5fVmFsdWUgPSBpLmRhdGEgfHwgaS50ZXh0Q29udGVudCB8fCBpLnRleHQgfHwgIiI7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB4OwoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFOgogICAgICAgICAgICAgICAgICAgIGlmIChYTUwuaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeC5fQ2xhc3MgPSAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiI7CiAgICAgICAgICAgICAgICAgICAgeC5fTmFtZSA9IG5ldyBRTmFtZSgiIiwgaS50YXJnZXQpOwogICAgICAgICAgICAgICAgICAgIHguX1ZhbHVlID0gaS5kYXRhIHx8IGkudGV4dENvbnRlbnQgfHwgaS50ZXh0IHx8ICIiOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4geDsKCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEFUVFJJQlVURV9OT0RFOgogICAgICAgICAgICAgICAgICAgIHguX0NsYXNzID0gImF0dHJpYnV0ZSI7CgogICAgICAgICAgICAgICAgICAgIHRlbXAgPSBpLm5vZGVOYW1lLm1hdGNoKC8oKFtcd1wtXSspOik/KFtcd1wtXSspLyk7CgogICAgICAgICAgICAgICAgICAgIGlmICggdGVtcFsxXSApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWkubG9va3VwTmFtZXNwYWNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IGkubG9va3VwTmFtZXNwYWNlKHRlbXBbMl0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDMgPSBuOy8vaGFjayBmb3IgaWUgLS0gc3R1cGlkIGllCgogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCF0ZW1wMiAmJiAhIXRlbXAzICYmICEhdGVtcDMuYXR0cmlidXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gdGVtcDMuYXR0cmlidXRlcy5sZW5ndGg7IGogPCBsOyArK2opCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlTmFtZSA9PSAoInhtbG5zOiIgKyB0ZW1wWzJdKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDIgPSB0ZW1wMy5hdHRyaWJ1dGVzW2pdLnZhbHVlIHx8IHRlbXAzLmF0dHJpYnV0ZXNbal0ubm9kZVZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAzID0gdGVtcDMucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB4Ll9EZWZhdWx0TmFtZXNwYWNlID0gbmV3IE5hbWVzcGFjZSggdGVtcFsyXSwgdGVtcDIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgeC5fTmFtZSA9IG5ldyBRTmFtZSggeC5fRGVmYXVsdE5hbWVzcGFjZSwgdGVtcFszXSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWkubG9va3VwTmFtZXNwYWNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IGkubG9va3VwTmFtZXNwYWNlKCIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAzID0gaS5wYXJlbnROb2RlOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICghdGVtcDIgJiYgISF0ZW1wMyAmJiAhIXRlbXAzLmF0dHJpYnV0ZXMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChqID0gMCwgbCA9IHRlbXAzLmF0dHJpYnV0ZXMubGVuZ3RoOyBqIDwgbDsgKytqKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAzLmF0dHJpYnV0ZXNbal0ubm9kZU5hbWUgPT0gInhtbG5zIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDIgPSB0ZW1wMy5hdHRyaWJ1dGVzW2pdLnZhbHVlIHx8IHRlbXAzLmF0dHJpYnV0ZXNbal0ubm9kZVZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAzID0gdGVtcDMucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgeC5fRGVmYXVsdE5hbWVzcGFjZSA9IG5ldyBOYW1lc3BhY2UoIiIsIHRlbXAyKTsKICAgICAgICAgICAgICAgICAgICAgICAgeC5fTmFtZSA9IG5ldyBRTmFtZSggeC5fRGVmYXVsdE5hbWVzcGFjZSwgdGVtcFszXSApOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeC5fVmFsdWUgPSBpLnZhbHVlIHx8IG51bGw7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB4OwoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRUxFTUVOVF9OT0RFOgogICAgICAgICAgICAgICAgICAgIHguX0NsYXNzID0gImVsZW1lbnQiOwogICAgICAgICAgICAgICAgICAgIHRlbXAgPSBpLm5vZGVOYW1lLm1hdGNoKC8oKFtcd1wtXSspOik/KFtcd1wtXSspLyk7CgogICAgICAgICAgICAgICAgICAgIGlmICggdGVtcFsxXSApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWkubG9va3VwTmFtZXNwYWNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IGkubG9va3VwTmFtZXNwYWNlKHRlbXBbMl0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDMgPSBpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICghdGVtcDIgJiYgISF0ZW1wMyAmJiAhIXRlbXAzLmF0dHJpYnV0ZXMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChqID0gMCwgbCA9IHRlbXAzLmF0dHJpYnV0ZXMubGVuZ3RoOyBqIDwgbDsgKytqKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAzLmF0dHJpYnV0ZXNbal0ubm9kZU5hbWUgPT0gKCJ4bWxuczoiICsgdGVtcFsyXSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gdGVtcDMuYXR0cmlidXRlc1tqXS52YWx1ZSB8fCB0ZW1wMy5hdHRyaWJ1dGVzW2pdLm5vZGVWYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMyA9IHRlbXAzLnBhcmVudE5vZGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgeC5fRGVmYXVsdE5hbWVzcGFjZSA9IG5ldyBOYW1lc3BhY2UoIHRlbXBbMl0sIHRlbXAyICk7CiAgICAgICAgICAgICAgICAgICAgICAgIHguX05hbWUgPSBuZXcgUU5hbWUoIHguX0RlZmF1bHROYW1lc3BhY2UsIHRlbXBbM10gKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDIgPSB1bmRlZmluZWQ7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFpLmxvb2t1cE5hbWVzcGFjZSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDIgPSBpLmxvb2t1cE5hbWVzcGFjZSgiIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMyA9IGk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCF0ZW1wMiAmJiAhIXRlbXAzICYmICEhdGVtcDMuYXR0cmlidXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gdGVtcDMuYXR0cmlidXRlcy5sZW5ndGg7IGogPCBsOyArK2opCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlTmFtZSA9PSAieG1sbnMiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHRlbXAzLmF0dHJpYnV0ZXNbal0udmFsdWUgfHwgdGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDMgPSB0ZW1wMy5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB4Ll9EZWZhdWx0TmFtZXNwYWNlID0gbmV3IE5hbWVzcGFjZSgiIiwgdGVtcDIpOwoKICAgICAgICAgICAgICAgICAgICAgICAgeC5fTmFtZSA9IG5ldyBRTmFtZSggeC5fRGVmYXVsdE5hbWVzcGFjZSwgdGVtcFszXSApOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgZm9yICh0ZW1wID0gMCwgdGVtcDIgPSBpLmF0dHJpYnV0ZXMubGVuZ3RoOyB0ZW1wIDwgdGVtcDI7ICsrdGVtcCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wMyA9IGlzTlNjaGVjay5leGVjKGkuYXR0cmlidXRlc1t0ZW1wXS5ub2RlTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHguX0luU2NvcGVOYW1lc3BhY2VzW3RlbXAzWzFdXSA9IG5ldyBOYW1lc3BhY2UodGVtcDNbMV0sIGkuYXR0cmlidXRlc1t0ZW1wXS52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoaS5hdHRyaWJ1dGVzW3RlbXBdLm5vZGVOYW1lID09PSAieG1sbnMiKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4Ll9JblNjb3BlTmFtZXNwYWNlc1siIl0gPSBuZXcgTmFtZXNwYWNlKGkuYXR0cmlidXRlc1t0ZW1wXS52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4Ll9BdHRyaWJ1dGVzW2kuYXR0cmlidXRlc1t0ZW1wXS5ub2RlTmFtZV0gPSBNYXBJbmZvSXRlbVRvWE1MKGkuYXR0cmlidXRlc1t0ZW1wXSwgaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGogPSAwOwogICAgICAgICAgICAgICAgICAgIHhtbENoaWxkID0gMDsKICAgICAgICAgICAgICAgICAgICB0ZW1wID0gaS5jaGlsZE5vZGVzLmxlbmd0aDsKCiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGogPCB0ZW1wKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbiA9IHtuOi0xfTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAzID0gTWFwSW5mb0l0ZW1Ub1hNTChpLmNoaWxkTm9kZXNbal0sIG4pKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2V2ZW4gdGhvdWdoIGl0IGlzIG5vdCB3cml0dGVuIHRoaXMgd2F5IGluIHRoZSBzcGVjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RoaXMgaXMgaG93IGl0IHdvcmtzIGluIEZpcmVmb3gKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHguX0NoaWxkcmVuW3htbENoaWxkXSA9IHRlbXAzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgeC5fQ2hpbGRyZW5beG1sQ2hpbGRdLl9QYXJlbnQgPSB4OwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wMy5fQ2xhc3MgPT09ICJ0ZXh0IiAmJiBuLm4gPiAwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGogPSBqICsgbi5uOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICsreG1sQ2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICsrajsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHguX1ZhbHVlID0gaS50ZXh0Q29udGVudCB8fCBpLnRleHQgfHwgaS5kYXRhIHx8ICIiOwoKICAgICAgICAgICAgICAgICAgICB4Ll9MZW5ndGggPSB4bWxDaGlsZDsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHg7CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBET0NVTUVOVF9OT0RFOgogICAgICAgICAgICAgICAgLy9maXJlZm94IHdvbid0IGRvIHRoaXMKICAgICAgICAgICAgICAgIC8vcmV0dXJuIE1hcEluZm9JdGVtVG9YTUwoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KTsKICAgICAgICAgICAgICAgIC8vYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEVOVElUWV9SRUZFUkVOQ0VfTk9ERToKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIG1peGVkIHMKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFRvWE1MTGlzdCAocykKICAgICAgICB7CiAgICAgICAgICAgIHZhciBlLHgsbGlzdCxpLGw7CgogICAgICAgICAgICBpZiAocyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHMgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxpc3QgPSBuZXcgWE1MTGlzdCgpOwogICAgICAgICAgICAgICAgbGlzdC5fQ2hpbGRyZW5bMF0gPSBsaXN0WzBdID0gczsKICAgICAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHguX1BhcmVudDsKICAgICAgICAgICAgICAgIGxpc3QuX1RhcmdldFByb3BlcnR5ID0geC5fTmFtZTsKCiAgICAgICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICgoIixzdHJpbmcsYm9vbGVhbixudW1iZXIsIikuaW5kZXhPZigiLCIgKyB0eXBlb2YocykrIiwiKSA9PT0gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZSA9IHBhcnNlKCc8cGFyZW50IHhtbG5zPSInICsgR2V0RGVmYXVsdE5hbWVzcGFjZSgpICsgJyI+JyArIHMgKyAnPC9wYXJlbnQ+Jyk7CiAgICAgICAgICAgIHggPSBUb1hNTChlLmRvY3VtZW50RWxlbWVudCk7CiAgICAgICAgICAgIGxpc3QgPSBuZXcgWE1MTGlzdCgpOwogICAgICAgICAgICBpID0gMDsKICAgICAgICAgICAgbCA9IHguX0NoaWxkcmVuLmxlbmd0aDsKCiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IG51bGw7CgogICAgICAgICAgICBmb3IgKDtpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB4Ll9DaGlsZHJlbltpXS5fUGFyZW50ID0gbnVsbDsKICAgICAgICAgICAgICAgIGxpc3QuX0NoaWxkcmVuW2ldID0gbGlzdFtpXSA9IHguX0NoaWxkcmVuW2ldOwogICAgICAgICAgICB9CgoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIG1peGVkIHMKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBUb0F0dHJpYnV0ZU5hbWUgKHMpCiAgICAgICAgewogICAgICAgICAgICBpZiAocyA9PT0gIioiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZU5hbWUobmV3IFFOYW1lKG51bGwsICIqIikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHMgaW5zdGFuY2VvZiBRTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGVOYW1lKHMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHMgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3dpdGNoICh0eXBlb2YocykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgInVuZGVmaW5lZCI6CiAgICAgICAgICAgICAgICBjYXNlICJudWxsIjoKICAgICAgICAgICAgICAgIGNhc2UgImJvb2xlYW4iOgogICAgICAgICAgICAgICAgY2FzZSAibnVtYmVyIjoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJzdHJpbmciOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlTmFtZShuZXcgUU5hbWUobnVsbCwgKHMgKyAiIikucmVwbGFjZSgvXkAvLCIiKSkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAib2JqZWN0IjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZU5hbWUobmV3IFFOYW1lKG51bGwsIFRvU3RyaW5nKHMpKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gbWl4ZWQgcwogICAgICAgICAqICAgIEByZXR1cm5zIFFOYW1lIHwgQXR0cmlidXRlTmFtZQogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gVG9YTUxOYW1lIChzKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHMgaW5zdGFuY2VvZiBRTmFtZSB8fCBzIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocyA9PT0gIioiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFFOYW1lKCIqIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN3aXRjaCAodHlwZW9mKHMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlICJ1bmRlZmluZWQiOgogICAgICAgICAgICAgICAgY2FzZSAibnVsbCI6CiAgICAgICAgICAgICAgICBjYXNlICJib29sZWFuIjoKICAgICAgICAgICAgICAgIGNhc2UgIm51bWJlciI6CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAic3RyaW5nIjoKICAgICAgICAgICAgICAgICAgICBpZiAocy5jaGFyQXQoMCkgPT09ICJAIikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBUb0F0dHJpYnV0ZU5hbWUoIHMuc3Vic3RyKDApICk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFFOYW1lKHMpOwoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIm9iamVjdCI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRvWE1MTmFtZSggVG9TdHJpbmcocykgKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEdldERlZmF1bHROYW1lc3BhY2UgKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAhIWRlZmF1bHROYW1lc3BhY2UgJiYgZGVmYXVsdE5hbWVzcGFjZS51cmkgfHwgIiI7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBzCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gRXNjYXBlRWxlbWVudFZhbHVlIChzKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICgoc3x8IiIpKyIiKS5yZXBsYWNlKC8uL2csIGZ1bmN0aW9uIChjKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiPCI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiJmx0OyI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiPiI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiJmd0OyI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiJiI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiJmFtcDsiOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgcwogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEVzY2FwZUF0dHJpYnV0ZVZhbHVlIChzKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICgoc3x8IiIpKyIiKS5yZXBsYWNlKC8uL2csIGZ1bmN0aW9uIChjKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnIic6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiJnF1b3Q7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICI8IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImbHQ7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICI+IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImZ3Q7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICImIjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImYW1wOyI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiXHIiOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiYjeEE7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICJcbiI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiJiN4RDsiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIlx0IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImI3g5OyI7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gR2V0IChQcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBHZXRMaXN0LmNhbGwodGhpcywgUHJvcGVydHlOYW1lKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHBhcnNlSW50KFByb3BlcnR5TmFtZSkrIiIgPT0gUHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gR2V0TGlzdC5jYWxsKFRvWE1MTGlzdCh0aGlzKSwgUHJvcGVydHlOYW1lICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBuID0gVG9YTUxOYW1lKFByb3BlcnR5TmFtZSksCiAgICAgICAgICAgICAgICBsaXN0ID0gbmV3IFhNTExpc3QoKSwgcCwgbDsKCiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHRoaXM7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldFByb3BlcnR5ID0gbjsKCiAgICAgICAgICAgIGlmIChuIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChwIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAobi5fTmFtZS5sb2NhbE5hbWUgPT09ICIqIiB8fCBuLl9OYW1lLmxvY2FsTmFtZSA9PT0gdGhpcy5fQXR0cmlidXRlc1twXS5fTmFtZS5sb2NhbE5hbWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKG4uX05hbWUudXJpID09IG51bGwgfHwgbi5fTmFtZS51cmkgPT09IHRoaXMuX0F0dHJpYnV0ZXNbcF0uX05hbWUudXJpKQogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZCh0aGlzLl9BdHRyaWJ1dGVzW3BdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKHAgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBwIDwgbDsgKytwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgKG4ubG9jYWxOYW1lID09PSAiKiIgfHwgKHRoaXMuX0NoaWxkcmVuW3BdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXMuX0NoaWxkcmVuW3BdLl9OYW1lLmxvY2FsTmFtZSA9PT0gbi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuLnVyaSA9PSBudWxsIHx8ICh0aGlzLl9DaGlsZHJlbltwXS5fQ2xhc3MgPT09ICJlbGVtZW50IiAmJiBuLnVyaSA9PT0gdGhpcy5fQ2hpbGRyZW5bcF0uX05hbWUudXJpKSkKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQodGhpcy5fQ2hpbGRyZW5bcF0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgUAogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBIYXNQcm9wZXJ0eSAoUCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIEhhc1Byb3BlcnR5TGlzdC5jYWxsKHRoaXMsIFApOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocGFyc2VJbnQoUCkgPT0gUCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIFAgPT0gIjAiOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbiA9IFRvWE1MTmFtZShQKSwgaywgbDsKCiAgICAgICAgICAgIGlmIChuIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChrIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuLl9OYW1lLmxvY2FsTmFtZSA9PT0gIioiIHx8IG4uX05hbWUubG9jYWxOYW1lID09PSB0aGlzLl9BdHRyaWJ1dGVzW2tdLl9OYW1lLmxvY2FsTmFtZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4uX05hbWUudXJpID09IG51bGwgfHwgbi5fTmFtZS51cmkgPT09IHRoaXMuX0F0dHJpYnV0ZXNba10uX05hbWUudXJpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGsgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBrIDwgbDsgKytrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKG4ubG9jYWxOYW1lID09PSAiKiIgfHwgKHRoaXMuX0NoaWxkcmVuW2tdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLmxvY2FsTmFtZSA9PT0gbi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgICAgICAgICAobi51cmkgPT0gbnVsbCB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgbi51cmkgPT09IHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLnVyaSkpCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gRGVsZXRlQnlJbmRleCAoUHJvcGVydHlOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGkgPSBwYXJzZUludChQcm9wZXJ0eU5hbWUpOy8vLCBxID0gaSArIDEsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7CgogICAgICAgICAgICBpZiAoaSA9PSBQcm9wZXJ0eU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghIXRoaXMuX0NoaWxkcmVuW2ldKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldLl9QYXJlbnQgPSBudWxsOwoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXSA9IG51bGw7CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuLnNwbGljZShpLCAxKTsKCiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgZm9yICg7cSA8IGw7KytxKQogICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW3EtMV0gPSB0aGlzLl9DaGlsZHJlbltxXTsKICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBEZWVwQ29weSAoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gRGVlcENvcHlMaXN0LmNhbGwodGhpcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciB5ID0gbmV3IFhNTCgpLCBpLCBsOy8vLCBjLCB0OwoKICAgICAgICAgICAgeS5fQ2xhc3MgPSB0aGlzLl9DbGFzczsKICAgICAgICAgICAgeS5fTmFtZSA9IHRoaXMuX05hbWU7CiAgICAgICAgICAgIHkuX0RlZmF1bHROYW1lc3BhY2UgPSB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlID8gbmV3IE5hbWVzcGFjZSh0aGlzLl9EZWZhdWx0TmFtZXNwYWNlKSA6IG51bGw7CiAgICAgICAgICAgIHkuX1ZhbHVlID0gdGhpcy5fVmFsdWU7CiAgICAgICAgICAgIHkuX1BhcmVudCA9IG51bGw7CgogICAgICAgICAgICBmb3IgKGkgaW4gdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHkuX0luU2NvcGVOYW1lc3BhY2VzW2ldID0gbmV3IE5hbWVzcGFjZSh0aGlzLl9JblNjb3BlTmFtZXNwYWNlcy5wcmVmaXgsIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzLnVyaSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAobCBpbiB0aGlzLl9BdHRyaWJ1dGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvL3kuX0F0dHJpYnV0ZXNbaV0gPSBhcmd1bWVudHMuY2FsbGVlLmNhbGwodGhpcy5fQXR0cmlidXRlc1tpXSk7CiAgICAgICAgICAgICAgICAvL25vdCBwYXJ0IG9mIHRoZSBzcGVjCiAgICAgICAgICAgICAgICB5Ll9BdHRyaWJ1dGVzW2ldID0gdGhpcy5fQXR0cmlidXRlc1tsXS5jb3B5KCk7CiAgICAgICAgICAgICAgICB5Ll9BdHRyaWJ1dGVzW2ldLl9QYXJlbnQgPSB5OwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB5Ll9DaGlsZHJlbltpXSA9IHRoaXMuX0NoaWxkcmVuW2ldLmNvcHkoKTsKICAgICAgICAgICAgICAgIHkuX0NoaWxkcmVuW2ldLl9QYXJlbnQgPSB5OwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4geTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFJlc29sdmVWYWx1ZSAoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gUmVzb2x2ZVZhbHVlTGlzdC5jYWxsKHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgWE1MID8gdGhpcyA6IG51bGw7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIERlc2NlbmRhbnRzIChQcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBEZXNjZW5kYW50c0xpc3QuY2FsbCh0aGlzLCBQcm9wZXJ0eU5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbiA9IFRvWE1MTmFtZShQcm9wZXJ0eU5hbWUpLAogICAgICAgICAgICAgICAgbGlzdCA9IG5ldyBYTUxMaXN0KCksCiAgICAgICAgICAgICAgICBrLCBsLCBkcTsKCiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IG51bGw7CgogICAgICAgICAgICBpZiAobiBpbnN0YW5jZW9mIEF0dHJpYnV0ZU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoayBpbiB0aGlzLl9BdHRyaWJ1dGVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgKG4uX05hbWUubG9jYWxOYW1lID09PSAiKiIgfHwgbi5fTmFtZS5sb2NhbE5hbWUgPT09IHRoaXMuX0F0dHJpYnV0ZXNba10uX05hbWUubG9jYWxOYW1lKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuLl9OYW1lLnVyaSA9PSBudWxsIHx8IG4uX05hbWUudXJpID09PSB0aGlzLl9BdHRyaWJ1dGVzW2tdLl9OYW1lLnVyaSkKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQodGhpcy5fQXR0cmlidXRlc1trXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGsgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBrIDwgbDsgKytrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKG4ubG9jYWxOYW1lID09PSAiKiIgfHwgKHRoaXMuX0NoaWxkcmVuW2tdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLmxvY2FsTmFtZSA9PT0gbi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgICAgICAgICAobi51cmkgPT0gbnVsbCB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgbi51cmkgPT09IHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLnVyaSkpCiAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRoaXMuX0NoaWxkcmVuW2tdKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBkcSA9IHRoaXMuX0NoaWxkcmVuW2tdLmRlc2NlbmRhbnRzKG4pOwoKICAgICAgICAgICAgICAgIGlmIChkcS5sZW5ndGgoKSA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQoZHEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIFZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yIHwgRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBJbnNlcnQgKFByb3BlcnR5TmFtZSwgVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsdGV4dCxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sYXR0cmlidXRlLCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGkgPSBwYXJzZUludChQcm9wZXJ0eU5hbWUpLCBuLCBqOwoKICAgICAgICAgICAgaWYgKGkrIiIgIT0gUHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCInIiArIGkgKyAiJyAhPSAnIiArIFByb3BlcnR5TmFtZSArICInIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChWYWx1ZSA9PT0gdGhpcyB8fCBpbmRleE9mKCIsIiArIHRoaXMsIFZhbHVlLmRlc2NlbmRhbnRzKCIqIikpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBuID0gVmFsdWUubGVuZ3RoKCk7CgogICAgICAgICAgICBmb3IgKGogPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGggLSAxOyBqID49IGk7IC0taikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bIGogKyBuIF0gPSB0aGlzLl9DaGlsZHJlbltqXTsKICAgICAgICAgICAgfQoKCiAgICAgICAgICAgIGlmIChWYWx1ZSBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBuOyArK2opCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVmFsdWVbal0uX1BhcmVudCA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baSArIGpdID0gVmFsdWVbal07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZXBsYWNlLmNhbGwodGhpcywgaSwgVmFsdWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIFZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gUmVwbGFjZSAoUHJvcGVydHlOYW1lLCBWYWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIix0ZXh0LGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbixhdHRyaWJ1dGUsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBpID0gcGFyc2VJbnQoUHJvcGVydHlOYW1lKSwgdDsKCiAgICAgICAgICAgIGlmIChpKyIiICE9IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigiJyIgKyBpICsgIicgIT0gJyIgKyBQcm9wZXJ0eU5hbWUgKyAiJyIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaSA+PSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFByb3BlcnR5TmFtZSA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRGVsZXRlQnlJbmRleC5jYWxsKHRoaXMsIFByb3BlcnR5TmFtZSk7CiAgICAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCBQcm9wZXJ0eU5hbWUsIFZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChWYWx1ZSBpbnN0YW5jZW9mIFhNTAogICAgICAgICAgICAgICAgJiYgVmFsdWUuX0NsYXNzID09PSAiZWxlbWVudCIKICAgICAgICAgICAgICAgICYmICgiLGVsZW1lbnQsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLHRleHQiKS5pbmRleE9mKCIsIiArIFZhbHVlLl9DbGFzcyArICIsIikgPiAtMQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBWYWx1ZS5fUGFyZW50ID0gdGhpczsKCiAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5bUHJvcGVydHlOYW1lXSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltQcm9wZXJ0eU5hbWVdLl9QYXJlbnQgPSBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW1Byb3BlcnR5TmFtZV0gPSBWYWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHQgPSBuZXcgWE1MKCk7CiAgICAgICAgICAgICAgICB0Ll9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgdC5fVmFsdWUgPSBUb1N0cmluZyhWYWx1ZSk7CgogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW1Byb3BlcnR5TmFtZV0pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bUHJvcGVydHlOYW1lXS5fUGFyZW50ID0gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltQcm9wZXJ0eU5hbWVdID0gdDsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBOYW1lc3BhY2UgTmFtZVNwYWNlCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEFkZEluU2NvcGVOYW1lc3BhY2UgKE5hbWVTcGFjZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIix0ZXh0LGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbixhdHRyaWJ1dGUsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBtYXRjaCA9IG51bGwsIHA7CgogICAgICAgICAgICBpZiAoTmFtZVNwYWNlLnByZWZpeCA9PSAiIiAmJiB0aGlzLl9OYW1lLnVyaSA9PSAiIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAocCBpbiB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKE5hbWVTcGFjZS5wcmVmaXggPT09IHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdLnByZWZpeCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAobWF0Y2ggJiYgbWF0Y2gudXJpICE9IE5hbWVTcGFjZS51cmkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW21hdGNoLnByZWZpeF0gPSBudWxsOwogICAgICAgICAgICAgICAgdHJ5ewogICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1ttYXRjaC5wcmVmaXhdOwogICAgICAgICAgICAgICAgfWNhdGNoKGUpe30KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbTmFtZVNwYWNlLnByZWZpeF0gPSBOYW1lU3BhY2U7CgogICAgICAgICAgICBpZiAodGhpcy5fTmFtZS5wcmVmaXggPT09IE5hbWVTcGFjZS5wcmVmaXgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRoaXMuX05hbWUucHJlZml4ID0gdW5kZWZpbmVkOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHAgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0F0dHJpYnV0ZXNbcF0uX05hbWUucHJlZml4ID0gTmFtZVNwYWNlLnByZWZpeCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzW3BdLl9OYW1lLnByZWZpeCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9kbyB0aGlzIGluIG9yZGVyIHRvIGVuc3VyZSBuYW1lc3BhY2UgaW50ZWdyaXR5CiAgICAgICAgICAgIC8qbWF0Y2ggPSBwYXJzZSh0aGlzLnRvWE1MU3RyaW5nKCkpOwogICAgICAgICAgICAgdGhpcy5fTm9kZSA9ICEhdGhpcy5fTm9kZS5wYXJlbnROb2RlCiAgICAgICAgICAgICA/IHRoaXMuX05vZGUucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQobWF0Y2guZG9jdW1lbnRFbGVtZW50LCB0aGlzLl9Ob2RlKQogICAgICAgICAgICAgOiBtYXRjaDsqLwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBOdW1iZXIgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBIYXNQcm9wZXJ0eUxpc3QgKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoVG9TdHJpbmcoIHBhcnNlSW50KG5hbWUpICkgPT09IG5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludChuYW1lKSA8IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXNbaV0uaGFzT3duUHJvcGVydHkobmFtZSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBOdW1iZXIgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gR2V0TGlzdCAoUHJvcGVydHlOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHBhcnNlSW50KFByb3BlcnR5TmFtZSkrIiIgPT0gUHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpc1tQcm9wZXJ0eU5hbWVdOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCB0ZW1wOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRQcm9wZXJ0eSA9IFByb3BlcnR5TmFtZTsKCiAgICAgICAgICAgIGZvciAoO2kgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0ZW1wID0gR2V0LmNhbGwodGhpcy5fQ2hpbGRyZW5baV0sIFByb3BlcnR5TmFtZSk7CgogICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wLl9DaGlsZHJlbi5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQodGVtcCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBEZWVwQ29weUxpc3QgKCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7CgogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzLl9UYXJnZXRPYmplY3Q7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldFByb3BlcnR5ID0gdGhpcy5fVGFyZ2V0UHJvcGVydHk7CiAgICAgICAgICAgIGxpc3QuX0NsYXNzID0gdGhpcy5fQ2xhc3M7CiAgICAgICAgICAgIGxpc3QuX1ZhbHVlID0gdGhpcy5fVmFsdWU7CgogICAgICAgICAgICBmb3IgKDtpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChEZWVwQ29weS5jYWxsKHRoaXNbaV0pKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIERlc2NlbmRhbnRzTGlzdCAoUHJvcGVydHlOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgWE1MTGlzdCgpLCBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCwgdGVtcDsKCiAgICAgICAgICAgIGZvciAoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKHRlbXAgPSBEZXNjZW5kYW50cy5jYWxsKHRoaXNbaV0sICIqIikpICYmIHRlbXAubGVuZ3RoKCkgPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQodGVtcCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqICAgIGh0dHA6Ly9ibG9nLnN0ZXZlbmxldml0aGFuLmNvbS9hcmNoaXZlcy9mYXN0ZXItdHJpbS1qYXZhc2NyaXB0CiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgcwogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIHRyaW0gKHN0cikKICAgICAgICB7CiAgICAgICAgICAgIGlmKCFzdHIpCiAgICAgICAgICAgICAgICByZXR1cm4gc3RyOwogICAgICAgICAgICB2YXIgICAgc3RyID0gc3RyLnJlcGxhY2UoL15cc1xzKi8sICIiKSwKICAgICAgICAgICAgICAgIHdzID0gL1xzLywKICAgICAgICAgICAgICAgIGkgPSBzdHIubGVuZ3RoOwogICAgICAgICAgICB3aGlsZSAod3MudGVzdChzdHIuY2hhckF0KC0taSkpKTsKICAgICAgICAgICAgcmV0dXJuIHN0ci5zbGljZSgwLCBpICsgMSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiAgICBHZW5lcmF0ZXMgYSBwcmVmaXggZm9yIGEgUU5hbWUgdGhhdCBpcyBub3QgYWxyZWFkeQogICAgICAgICAqICAgIGEgcHJvcGVydHkgb2YgdGhlIG9wdGlvbmFsIGFyZ3VtZW50CiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gT2JqZWN0IHByZWZpeGVzCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gbmV3UHJlZml4IChwcmVmaXhlcykKICAgICAgICB7CiAgICAgICAgICAgIHByZWZpeGVzID0gcHJlZml4ZXMgfHwge307CgogICAgICAgICAgICB2YXIgbnVtID0gTWF0aC5yYW5kb20oKQogICAgICAgICAgICAgICAgLnRvU3RyaW5nKCkKICAgICAgICAgICAgICAgIC5zdWJzdHIoMikKICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8uezJ9L2csIGZ1bmN0aW9uIChhKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGEgPSBOdW1iZXIoYSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChhID4gOTAgPyA5MCA6IChhIDwgNjUgPyA2NSA6IGEpKSArICIiOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICBudW0gPSBTdHJpbmcuZnJvbUNoYXJDb2RlKAogICAgICAgICAgICAgICAgTnVtYmVyKG51bS5zdWJzdHIoMCwgMikpICYgMHhGRiwKICAgICAgICAgICAgICAgIE51bWJlcihudW0uc3Vic3RyKDIsIDIpKSAmIDB4RkYsCiAgICAgICAgICAgICAgICBOdW1iZXIobnVtLnN1YnN0cig0LCAyKSkgJiAweEZGLAogICAgICAgICAgICAgICAgTnVtYmVyKG51bS5zdWJzdHIoNiwgMikpICYgMHhGRiwKICAgICAgICAgICAgICAgIE51bWJlcihudW0uc3Vic3RyKDgsIDIpKSAmIDB4RkYsCiAgICAgICAgICAgICAgICBOdW1iZXIobnVtLnN1YnN0cigxMCwgMikpICYgMHhGRgogICAgICAgICAgICApLnRvTG93ZXJDYXNlKCk7CgogICAgICAgICAgICB3aGlsZSAobnVtIGluIHByZWZpeGVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBudW0gPSBhcmd1bWVudHMuY2FsbGVlKHByZWZpeGVzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHN0cgogICAgICAgICAqICAgIEByZXR1cm5zIERPTU5vZGUKICAgICAgICAgKiAgICBAdGhyb3dzIFN5bnRheEVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gcGFyc2UgKHN0cikKICAgICAgICB7CiAgICAgICAgICAgIHZhciB4bWxEb2MsIHN1Y2Nlc3MgPSB0cnVlOwoKICAgICAgICAgICAgaWYgKGlzQWN0aXZlWFN1cHBvcnRlZCgiTWljcm9zb2Z0LlhNTERPTSIpKSAvL0ludGVybmV0IEV4cGxvcmVyCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MgICAgICAgICAgICAgICAgICAgICAgPSBuZXcgQWN0aXZlWE9iamVjdCgiTWljcm9zb2Z0LlhNTERPTSIpOwogICAgICAgICAgICAgICAgICAgIHhtbERvYy5hc3luYyAgICAgICAgICAgICAgICA9ICdmYWxzZSc7CiAgICAgICAgICAgICAgICAgICAgeG1sRG9jLnByZXNlcnZlV2hpdGVTcGFjZSAgID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MucmVzb2x2ZUV4dGVybmFscyAgICAgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MudmFsaWRhdGVPblBhcnNlICAgICAgICAgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB4bWxEb2Muc2V0UHJvcGVydHkoJ1Byb2hpYml0RFREJywgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB4bWxEb2MubG9hZFhNTChzdHIpOwogICAgICAgICAgICAgICAgfWNhdGNoKGUpe30KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRyeXsvL0ZpcmVmb3gsIE1vemlsbGEsIE9wZXJhLCBldGMuCiAgICAgICAgICAgICAgICAgICAgeG1sRG9jID0gbmV3IERPTVBhcnNlcigpOwogICAgICAgICAgICAgICAgICAgIHhtbERvYyA9IHhtbERvYy5wYXJzZUZyb21TdHJpbmcoc3RyLCAidGV4dC94bWwiKTsKICAgICAgICAgICAgICAgIH1jYXRjaChlKXt9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghc3VjY2VzcyB8fCAheG1sRG9jIHx8IHhtbERvYy5kb2N1bWVudEVsZW1lbnQubm9kZU5hbWUgPT0gInBhcnNlcmVycm9yIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCEheG1sRG9jICYmIHhtbERvYy5kb2N1bWVudEVsZW1lbnQuY2hpbGROb2Rlc1swXS5ub2RlVmFsdWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4geG1sRG9jOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBPYmplY3Qgb2JqCiAgICAgICAgICogICAgQHJldHVybnMgTnVtYmVyCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gY291bnQgKG9iaikKICAgICAgICB7CiAgICAgICAgICAgIGlmICgiX19jb3VudF9fIiBpbiBvYmopCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBvYmouX19jb3VudF9fOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgaSA9IDAsIGs7CgogICAgICAgICAgICBmb3IgKGsgaW4gb2JqKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGspKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIE9iamVjdCBvYmoKICAgICAgICAgKiAgICBAcGFyYW0gWE1MTGlzdCBsaXN0CiAgICAgICAgICogICAgQHJldHVybnMgTnVtYmVyCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gaW5kZXhPZiAob2JqLCBsaXN0KQogICAgICAgIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBsaXN0Lmxlbmd0aCgpOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAobGlzdFtpXS5FcXVhbHMob2JqKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBtaXhlZCBvYmoKICAgICAgICAgKiAgICBAcGFyYW0gbWl4ZWQgLi4uCiAgICAgICAgICogICAgQHJldHVybnMgbWl4ZWQKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBleHRlbmQgKG9iaikKICAgICAgICB7CiAgICAgICAgICAgIGZvciAodmFyIHAsIGkgPSAxLCBsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChwIGluIGFyZ3VtZW50c1tpXSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBvYmpbcF0gPSBhcmd1bWVudHNbaV1bcF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBvYmo7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBjcmVhdGVEb2N1bWVudEZyb20gKHhtbCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBwYXJzZSh4bWwubGVuZ3RoKCkgPT0gMSA/IHhtbC50b1hNTFN0cmluZygpIDogIjx4PiIgKyB4bWwudG9YTUxTdHJpbmcoKSArICI8L3g+Iik7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiB4bWxUb0RvbU5vZGUgKHhtbCkKICAgICAgICB7CiAgICAgICAgICAgIHN3aXRjaCAoeG1sLm5vZGVLaW5kKCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgImVsZW1lbnQiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVEb2N1bWVudEZyb20oeG1sKS5kb2N1bWVudEVsZW1lbnQ7CgogICAgICAgICAgICAgICAgY2FzZSAidGV4dCI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHhtbERvYy5jcmVhdGVUZXh0Tm9kZSh4bWwudG9TdHJpbmcoKSk7CgogICAgICAgICAgICAgICAgY2FzZSAiY29tbWVudCI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHhtbERvYy5jcmVhdGVDb21tZW50KHhtbC50b1N0cmluZygpLnNsaWNlKDQsIC0zKSk7CgogICAgICAgICAgICAgICAgY2FzZSAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHhtbERvYy5jcmVhdGVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbC5sb2NhbE5hbWUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sLnRvU3RyaW5nKCkuc2xpY2UoMiwgLTIpLnJlcGxhY2UocGlOYW1lLCAiIikKICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgIGNhc2UgImF0dHJpYnV0ZSI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZU5TKHhtbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBhZG9wdE5vZGUgKGRvYywgbm9kZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghIWRvYy5hZG9wdE5vZGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBkb2MuYWRvcHROb2RlKG5vZGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgYiA9IGRvYy5kb2N1bWVudEVsZW1lbnQgfHwgZG9jLmJvZHk7CiAgICAgICAgICAgIHJldHVybiBiLnJlbW92ZUNoaWxkKGIuYXBwZW5kQ2hpbGQobm9kZSkpOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gZXZhbHVhdGUgKGRvYywgZXhwciwgeG1sKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHJlcywgbCwgbiA9ICIiOwoKICAgICAgICAgICAgaWYgKCEhZG9jLmV2YWx1YXRlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXMgPSBkb2MuZXZhbHVhdGUoCiAgICAgICAgICAgICAgICAgICAgZXhwciwKICAgICAgICAgICAgICAgICAgICBkb2MsCiAgICAgICAgICAgICAgICAgICAgZG9jLmNyZWF0ZU5TUmVzb2x2ZXIoZG9jKSwKICAgICAgICAgICAgICAgICAgICBYUGF0aFJlc3VsdC5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSwKICAgICAgICAgICAgICAgICAgICBudWxsCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgIGwgPSBbXTsKCiAgICAgICAgICAgICAgICB3aGlsZShuID0gcmVzLml0ZXJhdGVOZXh0KCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbFtsLmxlbmd0aF0gPSBuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoInNldFByb3BlcnR5IiBpbiBkb2MpewoKICAgICAgICAgICAgICAgIHJlcyA9IGFsbE5hbWVzcGFjZXMoeG1sKTsKCiAgICAgICAgICAgICAgICBpZiAoY291bnQocmVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKGwgaW4gcmVzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbiArPSAiIHhtbG5zOiIgKyBsICsgJz0iJyArIEVzY2FwZUF0dHJpYnV0ZVZhbHVlKHJlc1tsXSkgKyAnIic7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBkb2Muc2V0UHJvcGVydHkoJ1NlbGVjdGlvbk5hbWVzcGFjZXMnLCBuLnN1YnN0cigxKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZG9jLnNldFByb3BlcnR5KCJTZWxlY3Rpb25MYW5ndWFnZSIsICJYUGF0aCIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gaXNBY3RpdmVYU3VwcG9ydGVkKCJNaWNyb3NvZnQuWE1MRE9NIikgJiYgZG9jLnNlbGVjdE5vZGVzKGV4cHIpOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gaXNBY3RpdmVYU3VwcG9ydGVkKHR5cGUpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIG5ldyBBY3RpdmVYT2JqZWN0KHR5cGUpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gYWxsTmFtZXNwYWNlcyAoeG1sLCB1bikKICAgICAgICB7CiAgICAgICAgICAgIHZhciBucyA9IHVuIHx8IHt9LAogICAgICAgICAgICAgICAgaSA9IDAsCiAgICAgICAgICAgICAgICBjID0geG1sLmNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBsID0gYy5sZW5ndGgoKSwKICAgICAgICAgICAgICAgIG4gPSB1biA9PSB1bmRlZmluZWQKICAgICAgICAgICAgICAgICAgICA/IGluc2NvcGUoeG1sKQogICAgICAgICAgICAgICAgICAgIDogeG1sLl9JblNjb3BlTmFtZXNwYWNlcywKICAgICAgICAgICAgICAgIHA7CgogICAgICAgICAgICBmb3IgKDtpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBucyA9IGFyZ3VtZW50cy5jYWxsZWUoY1tpXSwgbnMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHAgaW4gbikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKG5bcF0ucHJlZml4KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG5zW25bcF0ucHJlZml4XSA9IG5bcF0udXJpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnM7CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBpbnNjb3BlICh4bWwpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbnMgPSB7fSwKICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgbiA9IHhtbC5pblNjb3BlTmFtZXNwYWNlcygpLAogICAgICAgICAgICAgICAgbCA9IG4ubGVuZ3RoOwoKICAgICAgICAgICAgZm9yICg7aSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKG5baV0ucHJlZml4KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG5zW25baV0ucHJlZml4XSA9IG5baV0udXJpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnM7CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBjcmVhdGVBdHRyaWJ1dGVOUyAoeG1sKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIG5zID0geG1sLm5hbWVzcGFjZSgpLAogICAgICAgICAgICAgICAgbm9kZSA9ICEheG1sRG9jLmNyZWF0ZUF0dHJpYnV0ZU5TCiAgICAgICAgICAgICAgICAgICAgPyB4bWxEb2MuY3JlYXRlQXR0cmlidXRlTlMobnMudXJpLCB4bWwubG9jYWxOYW1lKCkpCiAgICAgICAgICAgICAgICAgICAgOiB4bWxEb2MuY3JlYXRlQXR0cmlidXRlKChucy5wcmVmaXggPyBucy5wcmVmaXggKyAiOiIgOiAiIiApICsgeG1sLmxvY2FsTmFtZSgpKTsKCiAgICAgICAgICAgIG5vZGUubm9kZVZhbHVlID0geG1sLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gdHJhbnNmb3JtICh4bWwsIHN0eWxlLCBwYXJhbXMpCiAgICAgICAgewogICAgICAgICAgICB2YXIgeHNsLCByZXMsIGkgPSAwLCBsID0gKHBhcmFtc3x8W10pLmxlbmd0aDsKCiAgICAgICAgICAgIGlmICghd2luZG93LlhTTFRQcm9jZXNzb3IpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vVE9ETzogTmVlZCB0byBjcmVhdGUgYSB3YXkgdG8gc2V0IHBhcmFtZXRlcnMgb24gYW4gSUUgc3R5bGVzaGVldAogICAgICAgICAgICAgICAgLy9YU0xQcm9jZXNzb3IKICAgICAgICAgICAgICAgIC8vaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21zNzU3MDE1JTI4dj1WUy44NSUyOS5hc3B4CiAgICAgICAgICAgICAgICAvL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczc2MzY3OSUyOFZTLjg1JTI5LmFzcHgKICAgICAgICAgICAgICAgIC8vaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21zNzU0NTk0JTI4dj1WUy44NSUyOS5hc3B4CgogICAgICAgICAgICAgICAgcmVzID0gY3JlYXRlRG9jdW1lbnRGcm9tKHhtbCkudHJhbnNmb3JtTm9kZShjcmVhdGVEb2N1bWVudEZyb20oc3R5bGUpKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gISFyZXMgJiYgVG9YTUwocmVzKSB8fCBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB4c2wgPSBuZXcgWFNMVFByb2Nlc3NvcigpOwoKICAgICAgICAgICAgeHNsLmltcG9ydFN0eWxlU2hlZXQoY3JlYXRlRG9jdW1lbnRGcm9tKHN0eWxlKSk7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzID0gcGFyYW1zW2ldOwogICAgICAgICAgICAgICAgeHNsLnNldFBhcmFtZXRlcihyZXMubmFtZXNwYWNlVVJJLCByZXMubG9jYWxOYW1lLCByZXMudmFsdWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXMgPSB4c2wudHJhbnNmb3JtVG9Eb2N1bWVudChjcmVhdGVEb2N1bWVudEZyb20oZG9jKSkKCiAgICAgICAgICAgIHJldHVybiAhIXJlcyAmJiBUb1hNTChyZXMpIHx8IG51bGw7CiAgICAgICAgfQoKICAgICAgICBmb3IgKHAgaW4gWE1MLnByb3RvdHlwZSkKICAgICAgICB7CiAgICAgICAgICAgIGRlZmF1bHRYTUxQcm90b3R5cGUgKz0gcCArICIsIjsKICAgICAgICB9CgogICAgICAgIGZvciAocCBpbiBYTUxMaXN0LnByb3RvdHlwZSkKICAgICAgICB7CiAgICAgICAgICAgIGRlZmF1bHRYTUxMaXN0UHJvdG90eXBlICs9IHAgKyAiLCI7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICB3aW5kb3cuWE1MICAgICAgICAgICAgICA9IFhNTDsKICAgICAgICB3aW5kb3cuWE1MTGlzdCAgICAgICAgICA9IFhNTExpc3Q7CiAgICAgICAgd2luZG93LlFOYW1lICAgICAgICAgICAgPSBRTmFtZTsKICAgICAgICB3aW5kb3cuTmFtZXNwYWNlICAgICAgICA9IE5hbWVzcGFjZTsKICAgICAgICB3aW5kb3cuaXNYTUxOYW1lICAgICAgICA9IGlzWE1MTmFtZTsKICAgICAgICB3aW5kb3cuQXR0cmlidXRlTmFtZSAgICA9IEF0dHJpYnV0ZU5hbWU7CgogICAgfSkoKTsKfQooZnVuY3Rpb24oKXt2YXIgaD10aGlzOwpmdW5jdGlvbiBhYShhKXt2YXIgYj10eXBlb2YgYTtpZigib2JqZWN0Ij09YilpZihhKXtpZihhIGluc3RhbmNlb2YgQXJyYXkpcmV0dXJuImFycmF5IjtpZihhIGluc3RhbmNlb2YgT2JqZWN0KXJldHVybiBiO3ZhciBjPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhKTtpZigiW29iamVjdCBXaW5kb3ddIj09YylyZXR1cm4ib2JqZWN0IjtpZigiW29iamVjdCBBcnJheV0iPT1jfHwibnVtYmVyIj09dHlwZW9mIGEubGVuZ3RoJiYidW5kZWZpbmVkIiE9dHlwZW9mIGEuc3BsaWNlJiYidW5kZWZpbmVkIiE9dHlwZW9mIGEucHJvcGVydHlJc0VudW1lcmFibGUmJiFhLnByb3BlcnR5SXNFbnVtZXJhYmxlKCJzcGxpY2UiKSlyZXR1cm4iYXJyYXkiO2lmKCJbb2JqZWN0IEZ1bmN0aW9uXSI9PWN8fCJ1bmRlZmluZWQiIT10eXBlb2YgYS5jYWxsJiYidW5kZWZpbmVkIiE9dHlwZW9mIGEucHJvcGVydHlJc0VudW1lcmFibGUmJiFhLnByb3BlcnR5SXNFbnVtZXJhYmxlKCJjYWxsIikpcmV0dXJuImZ1bmN0aW9uIn1lbHNlIHJldHVybiJudWxsIjtlbHNlIGlmKCJmdW5jdGlvbiI9PQpiJiYidW5kZWZpbmVkIj09dHlwZW9mIGEuY2FsbClyZXR1cm4ib2JqZWN0IjtyZXR1cm4gYn1mdW5jdGlvbiBrKGEpe3JldHVybiJzdHJpbmciPT10eXBlb2YgYX1mdW5jdGlvbiBiYShhLGIsYyl7cmV0dXJuIGEuY2FsbC5hcHBseShhLmJpbmQsYXJndW1lbnRzKX1mdW5jdGlvbiBjYShhLGIsYyl7aWYoIWEpdGhyb3cgRXJyb3IoKTtpZigyPGFyZ3VtZW50cy5sZW5ndGgpe3ZhciBkPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywyKTtyZXR1cm4gZnVuY3Rpb24oKXt2YXIgYz1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO0FycmF5LnByb3RvdHlwZS51bnNoaWZ0LmFwcGx5KGMsZCk7cmV0dXJuIGEuYXBwbHkoYixjKX19cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGEuYXBwbHkoYixhcmd1bWVudHMpfX0KZnVuY3Rpb24gZGEoYSxiLGMpe2RhPUZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kJiYtMSE9RnVuY3Rpb24ucHJvdG90eXBlLmJpbmQudG9TdHJpbmcoKS5pbmRleE9mKCJuYXRpdmUgY29kZSIpP2JhOmNhO3JldHVybiBkYS5hcHBseShudWxsLGFyZ3VtZW50cyl9ZnVuY3Rpb24gZWEoYSxiKXt2YXIgYz1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMSk7cmV0dXJuIGZ1bmN0aW9uKCl7dmFyIGI9Yy5zbGljZSgpO2IucHVzaC5hcHBseShiLGFyZ3VtZW50cyk7cmV0dXJuIGEuYXBwbHkodGhpcyxiKX19CmZ1bmN0aW9uIG0oYSl7dmFyIGI9bjtmdW5jdGlvbiBjKCl7fWMucHJvdG90eXBlPWIucHJvdG90eXBlO2EudT1iLnByb3RvdHlwZTthLnByb3RvdHlwZT1uZXcgYzthLnByb3RvdHlwZS5jb25zdHJ1Y3Rvcj1hO2EudD1mdW5jdGlvbihhLGMsZil7cmV0dXJuIGIucHJvdG90eXBlW2NdLmFwcGx5KGEsQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDIpKX19O3ZhciBmYT1TdHJpbmcucHJvdG90eXBlLnRyaW0/ZnVuY3Rpb24oYSl7cmV0dXJuIGEudHJpbSgpfTpmdW5jdGlvbihhKXtyZXR1cm4gYS5yZXBsYWNlKC9eW1xzXHhhMF0rfFtcc1x4YTBdKyQvZywiIil9O2Z1bmN0aW9uIGdhKGEsYil7cmV0dXJuIGE8Yj8tMTphPmI/MTowfTt2YXIgcTthOnt2YXIgaGE9aC5uYXZpZ2F0b3I7aWYoaGEpe3ZhciBpYT1oYS51c2VyQWdlbnQ7aWYoaWEpe3E9aWE7YnJlYWsgYX19cT0iIn1mdW5jdGlvbiByKGEpe3JldHVybi0xIT1xLmluZGV4T2YoYSl9O3ZhciBzPUFycmF5LnByb3RvdHlwZSxqYT1zLmluZGV4T2Y/ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBzLmluZGV4T2YuY2FsbChhLGIsYyl9OmZ1bmN0aW9uKGEsYixjKXtjPW51bGw9PWM/MDowPmM/TWF0aC5tYXgoMCxhLmxlbmd0aCtjKTpjO2lmKGsoYSkpcmV0dXJuIGsoYikmJjE9PWIubGVuZ3RoP2EuaW5kZXhPZihiLGMpOi0xO2Zvcig7YzxhLmxlbmd0aDtjKyspaWYoYyBpbiBhJiZhW2NdPT09YilyZXR1cm4gYztyZXR1cm4tMX0sdD1zLmZvckVhY2g/ZnVuY3Rpb24oYSxiLGMpe3MuZm9yRWFjaC5jYWxsKGEsYixjKX06ZnVuY3Rpb24oYSxiLGMpe2Zvcih2YXIgZD1hLmxlbmd0aCxlPWsoYSk/YS5zcGxpdCgiIik6YSxmPTA7ZjxkO2YrKylmIGluIGUmJmIuY2FsbChjLGVbZl0sZixhKX0sa2E9cy5maWx0ZXI/ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBzLmZpbHRlci5jYWxsKGEsYixjKX06ZnVuY3Rpb24oYSxiLGMpe2Zvcih2YXIgZD1hLmxlbmd0aCxlPVtdLGY9MCxnPWsoYSk/CmEuc3BsaXQoIiIpOmEsbD0wO2w8ZDtsKyspaWYobCBpbiBnKXt2YXIgcD1nW2xdO2IuY2FsbChjLHAsbCxhKSYmKGVbZisrXT1wKX1yZXR1cm4gZX0sdT1zLnJlZHVjZT9mdW5jdGlvbihhLGIsYyxkKXtkJiYoYj1kYShiLGQpKTtyZXR1cm4gcy5yZWR1Y2UuY2FsbChhLGIsYyl9OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlPWM7dChhLGZ1bmN0aW9uKGMsZyl7ZT1iLmNhbGwoZCxlLGMsZyxhKX0pO3JldHVybiBlfSxsYT1zLnNvbWU/ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBzLnNvbWUuY2FsbChhLGIsYyl9OmZ1bmN0aW9uKGEsYixjKXtmb3IodmFyIGQ9YS5sZW5ndGgsZT1rKGEpP2Euc3BsaXQoIiIpOmEsZj0wO2Y8ZDtmKyspaWYoZiBpbiBlJiZiLmNhbGwoYyxlW2ZdLGYsYSkpcmV0dXJuITA7cmV0dXJuITF9OwpmdW5jdGlvbiBtYShhLGIpe3ZhciBjO2E6e2M9YS5sZW5ndGg7Zm9yKHZhciBkPWsoYSk/YS5zcGxpdCgiIik6YSxlPTA7ZTxjO2UrKylpZihlIGluIGQmJmIuY2FsbCh2b2lkIDAsZFtlXSxlLGEpKXtjPWU7YnJlYWsgYX1jPS0xfXJldHVybiAwPmM/bnVsbDprKGEpP2EuY2hhckF0KGMpOmFbY119ZnVuY3Rpb24gbmEoYSl7cmV0dXJuIHMuY29uY2F0LmFwcGx5KHMsYXJndW1lbnRzKX1mdW5jdGlvbiBvYShhLGIsYyl7cmV0dXJuIDI+PWFyZ3VtZW50cy5sZW5ndGg/cy5zbGljZS5jYWxsKGEsYik6cy5zbGljZS5jYWxsKGEsYixjKX07dmFyIHBhPXIoIk9wZXJhIil8fHIoIk9QUiIpLHY9cigiVHJpZGVudCIpfHxyKCJNU0lFIikscWE9cigiR2Vja28iKSYmLTE9PXEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCJ3ZWJraXQiKSYmIShyKCJUcmlkZW50Iil8fHIoIk1TSUUiKSkscmE9LTEhPXEudG9Mb3dlckNhc2UoKS5pbmRleE9mKCJ3ZWJraXQiKTtmdW5jdGlvbiBzYSgpe3ZhciBhPWguZG9jdW1lbnQ7cmV0dXJuIGE/YS5kb2N1bWVudE1vZGU6dm9pZCAwfQp2YXIgdGE9ZnVuY3Rpb24oKXt2YXIgYT0iIixiO2lmKHBhJiZoLm9wZXJhKXJldHVybiBhPWgub3BlcmEudmVyc2lvbiwiZnVuY3Rpb24iPT1hYShhKT9hKCk6YTtxYT9iPS9ydlw6KFteXCk7XSspKFwpfDspLzp2P2I9L1xiKD86TVNJRXxydilbOiBdKFteXCk7XSspKFwpfDspLzpyYSYmKGI9L1dlYktpdFwvKFxTKykvKTtiJiYoYT0oYT1iLmV4ZWMocSkpP2FbMV06IiIpO3JldHVybiB2JiYoYj1zYSgpLGI+cGFyc2VGbG9hdChhKSk/U3RyaW5nKGIpOmF9KCksdWE9e307CmZ1bmN0aW9uIHZhKGEpe2lmKCF1YVthXSl7Zm9yKHZhciBiPTAsYz1mYShTdHJpbmcodGEpKS5zcGxpdCgiLiIpLGQ9ZmEoU3RyaW5nKGEpKS5zcGxpdCgiLiIpLGU9TWF0aC5tYXgoYy5sZW5ndGgsZC5sZW5ndGgpLGY9MDswPT1iJiZmPGU7ZisrKXt2YXIgZz1jW2ZdfHwiIixsPWRbZl18fCIiLHA9UmVnRXhwKCIoXFxkKikoXFxEKikiLCJnIikseD1SZWdFeHAoIihcXGQqKShcXEQqKSIsImciKTtkb3t2YXIgQz1wLmV4ZWMoZyl8fFsiIiwiIiwiIl0sWD14LmV4ZWMobCl8fFsiIiwiIiwiIl07aWYoMD09Q1swXS5sZW5ndGgmJjA9PVhbMF0ubGVuZ3RoKWJyZWFrO2I9Z2EoMD09Q1sxXS5sZW5ndGg/MDpwYXJzZUludChDWzFdLDEwKSwwPT1YWzFdLmxlbmd0aD8wOnBhcnNlSW50KFhbMV0sMTApKXx8Z2EoMD09Q1syXS5sZW5ndGgsMD09WFsyXS5sZW5ndGgpfHxnYShDWzJdLFhbMl0pfXdoaWxlKDA9PWIpfXVhW2FdPTA8PWJ9fQp2YXIgd2E9aC5kb2N1bWVudCx4YT13YSYmdj9zYSgpfHwoIkNTUzFDb21wYXQiPT13YS5jb21wYXRNb2RlP3BhcnNlSW50KHRhLDEwKTo1KTp2b2lkIDA7IXFhJiYhdnx8diYmdiYmOTw9eGF8fHFhJiZ2YSgiMS45LjEiKTt2JiZ2YSgiOSIpO2Z1bmN0aW9uIHlhKGEsYil7aWYoYS5jb250YWlucyYmMT09Yi5ub2RlVHlwZSlyZXR1cm4gYT09Ynx8YS5jb250YWlucyhiKTtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24pcmV0dXJuIGE9PWJ8fEJvb2xlYW4oYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihiKSYxNik7Zm9yKDtiJiZhIT1iOyliPWIucGFyZW50Tm9kZTtyZXR1cm4gYj09YX0KZnVuY3Rpb24gemEoYSxiKXtpZihhPT1iKXJldHVybiAwO2lmKGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24pcmV0dXJuIGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oYikmMj8xOi0xO2lmKHYmJiEodiYmOTw9eGEpKXtpZig5PT1hLm5vZGVUeXBlKXJldHVybi0xO2lmKDk9PWIubm9kZVR5cGUpcmV0dXJuIDF9aWYoInNvdXJjZUluZGV4ImluIGF8fGEucGFyZW50Tm9kZSYmInNvdXJjZUluZGV4ImluIGEucGFyZW50Tm9kZSl7dmFyIGM9MT09YS5ub2RlVHlwZSxkPTE9PWIubm9kZVR5cGU7aWYoYyYmZClyZXR1cm4gYS5zb3VyY2VJbmRleC1iLnNvdXJjZUluZGV4O3ZhciBlPWEucGFyZW50Tm9kZSxmPWIucGFyZW50Tm9kZTtyZXR1cm4gZT09Zj9BYShhLGIpOiFjJiZ5YShlLGIpPy0xKkJhKGEsYik6IWQmJnlhKGYsYSk/QmEoYixhKTooYz9hLnNvdXJjZUluZGV4OmUuc291cmNlSW5kZXgpLShkP2Iuc291cmNlSW5kZXg6Zi5zb3VyY2VJbmRleCl9ZD05PT1hLm5vZGVUeXBlP2E6CmEub3duZXJEb2N1bWVudHx8YS5kb2N1bWVudDtjPWQuY3JlYXRlUmFuZ2UoKTtjLnNlbGVjdE5vZGUoYSk7Yy5jb2xsYXBzZSghMCk7ZD1kLmNyZWF0ZVJhbmdlKCk7ZC5zZWxlY3ROb2RlKGIpO2QuY29sbGFwc2UoITApO3JldHVybiBjLmNvbXBhcmVCb3VuZGFyeVBvaW50cyhoLlJhbmdlLlNUQVJUX1RPX0VORCxkKX1mdW5jdGlvbiBCYShhLGIpe3ZhciBjPWEucGFyZW50Tm9kZTtpZihjPT1iKXJldHVybi0xO2Zvcih2YXIgZD1iO2QucGFyZW50Tm9kZSE9YzspZD1kLnBhcmVudE5vZGU7cmV0dXJuIEFhKGQsYSl9ZnVuY3Rpb24gQWEoYSxiKXtmb3IodmFyIGM9YjtjPWMucHJldmlvdXNTaWJsaW5nOylpZihjPT1hKXJldHVybi0xO3JldHVybiAxfTtmdW5jdGlvbiB3KGEsYixjKXt0aGlzLmE9YTt0aGlzLmI9Ynx8MTt0aGlzLmQ9Y3x8MX07ZnVuY3Rpb24gQ2EoYSl7dGhpcy5iPWE7dGhpcy5hPTB9ZnVuY3Rpb24gRGEoYSl7YT1hLm1hdGNoKEVhKTtmb3IodmFyIGI9MDtiPGEubGVuZ3RoO2IrKylGYS50ZXN0KGFbYl0pJiZhLnNwbGljZShiLDEpO3JldHVybiBuZXcgQ2EoYSl9dmFyIEVhPVJlZ0V4cCgiXFwkPyg/Oig/IVswLTktXSlbXFx3LV0rOik/KD8hWzAtOS1dKVtcXHctXSt8XFwvXFwvfFxcLlxcLnw6OnxcXGQrKD86XFwuXFxkKik/fFxcLlxcZCt8XCJbXlwiXSpcInwnW14nXSonfFshPD5dPXxcXHMrfC4iLCJnIiksRmE9L15ccy87ZnVuY3Rpb24geShhLGIpe3JldHVybiBhLmJbYS5hKyhifHwwKV19ZnVuY3Rpb24geihhKXtyZXR1cm4gYS5iW2EuYSsrXX1mdW5jdGlvbiBHYShhKXtyZXR1cm4gYS5iLmxlbmd0aDw9YS5hfTtmdW5jdGlvbiBBKGEsYil7dGhpcy5oPWEudG9Mb3dlckNhc2UoKTt0aGlzLmM9Yj9iLnRvTG93ZXJDYXNlKCk6Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwifUEucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7dmFyIGI9YS5ub2RlVHlwZTtyZXR1cm4gMSE9YiYmMiE9Yj8hMToiKiIhPXRoaXMuaCYmdGhpcy5oIT1hLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk/ITE6dGhpcy5jPT0oYS5uYW1lc3BhY2VVUkk/YS5uYW1lc3BhY2VVUkkudG9Mb3dlckNhc2UoKToiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIpfTtBLnByb3RvdHlwZS5kPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaH07QS5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4iTmFtZSBUZXN0OiAiKygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI9PXRoaXMuYz8iIjp0aGlzLmMrIjoiKSt0aGlzLmh9O2Z1bmN0aW9uIEIoYSxiKXt0aGlzLmY9YTt0aGlzLmM9dm9pZCAwIT09Yj9iOm51bGw7dGhpcy5iPW51bGw7c3dpdGNoKGEpe2Nhc2UgImNvbW1lbnQiOnRoaXMuYj04O2JyZWFrO2Nhc2UgInRleHQiOnRoaXMuYj0zO2JyZWFrO2Nhc2UgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iOnRoaXMuYj03O2JyZWFrO2Nhc2UgIm5vZGUiOmJyZWFrO2RlZmF1bHQ6dGhyb3cgRXJyb3IoIlVuZXhwZWN0ZWQgYXJndW1lbnQiKTt9fWZ1bmN0aW9uIEhhKGEpe3JldHVybiJjb21tZW50Ij09YXx8InRleHQiPT1hfHwicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiI9PWF8fCJub2RlIj09YX1CLnByb3RvdHlwZS5hPWZ1bmN0aW9uKGEpe3JldHVybiBudWxsPT09dGhpcy5ifHx0aGlzLmI9PWEubm9kZVR5cGV9O0IucHJvdG90eXBlLmQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5mfTsKQi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXt2YXIgYT0iS2luZCBUZXN0OiAiK3RoaXMuZjtudWxsPT09dGhpcy5jfHwoYSs9RCh0aGlzLmMpKTtyZXR1cm4gYX07ZnVuY3Rpb24gSWEoYSl7c3dpdGNoKGEubm9kZVR5cGUpe2Nhc2UgMTpyZXR1cm4gZWEoSmEsYSk7Y2FzZSA5OnJldHVybiBJYShhLmRvY3VtZW50RWxlbWVudCk7Y2FzZSAxMTpjYXNlIDEwOmNhc2UgNjpjYXNlIDEyOnJldHVybiBLYTtkZWZhdWx0OnJldHVybiBhLnBhcmVudE5vZGU/SWEoYS5wYXJlbnROb2RlKTpLYX19ZnVuY3Rpb24gS2EoKXtyZXR1cm4gbnVsbH1mdW5jdGlvbiBKYShhLGIpe2lmKGEucHJlZml4PT1iKXJldHVybiBhLm5hbWVzcGFjZVVSSXx8Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiO3ZhciBjPWEuZ2V0QXR0cmlidXRlTm9kZSgieG1sbnM6IitiKTtyZXR1cm4gYyYmYy5zcGVjaWZpZWQ/Yy52YWx1ZXx8bnVsbDphLnBhcmVudE5vZGUmJjkhPWEucGFyZW50Tm9kZS5ub2RlVHlwZT9KYShhLnBhcmVudE5vZGUsYik6bnVsbH07dmFyIEU9diYmISh2JiY5PD14YSksTGE9diYmISh2JiY4PD14YSk7ZnVuY3Rpb24gRihhLGIsYyxkKXt0aGlzLmE9YTt0aGlzLm5vZGVOYW1lPWM7dGhpcy5ub2RlVmFsdWU9ZDt0aGlzLm5vZGVUeXBlPTI7dGhpcy5wYXJlbnROb2RlPXRoaXMub3duZXJFbGVtZW50PWJ9ZnVuY3Rpb24gTWEoYSxiKXt2YXIgYz1MYSYmImhyZWYiPT1iLm5vZGVOYW1lP2EuZ2V0QXR0cmlidXRlKGIubm9kZU5hbWUsMik6Yi5ub2RlVmFsdWU7cmV0dXJuIG5ldyBGKGIsYSxiLm5vZGVOYW1lLGMpfTtmdW5jdGlvbiBHKGEpe3ZhciBiPW51bGwsYz1hLm5vZGVUeXBlOzE9PWMmJihiPWEudGV4dENvbnRlbnQsYj12b2lkIDA9PWJ8fG51bGw9PWI/YS5pbm5lclRleHQ6YixiPXZvaWQgMD09Ynx8bnVsbD09Yj8iIjpiKTtpZigic3RyaW5nIiE9dHlwZW9mIGIpaWYoRSYmInRpdGxlIj09YS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpJiYxPT1jKWI9YS50ZXh0O2Vsc2UgaWYoOT09Y3x8MT09Yyl7YT05PT1jP2EuZG9jdW1lbnRFbGVtZW50OmEuZmlyc3RDaGlsZDtmb3IodmFyIGM9MCxkPVtdLGI9IiI7YTspe2RvIDEhPWEubm9kZVR5cGUmJihiKz1hLm5vZGVWYWx1ZSksRSYmInRpdGxlIj09YS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpJiYoYis9YS50ZXh0KSxkW2MrK109YTt3aGlsZShhPWEuZmlyc3RDaGlsZCk7Zm9yKDtjJiYhKGE9ZFstLWNdLm5leHRTaWJsaW5nKTspO319ZWxzZSBiPWEubm9kZVZhbHVlO3JldHVybiIiK2J9CmZ1bmN0aW9uIEgoYSxiLGMpe2lmKG51bGw9PT1iKXJldHVybiEwO3RyeXtpZighYS5nZXRBdHRyaWJ1dGUpcmV0dXJuITF9Y2F0Y2goZCl7cmV0dXJuITF9TGEmJiJjbGFzcyI9PWImJihiPSJjbGFzc05hbWUiKTtyZXR1cm4gbnVsbD09Yz8hIWEuZ2V0QXR0cmlidXRlKGIpOmEuZ2V0QXR0cmlidXRlKGIsMik9PWN9ZnVuY3Rpb24gSShhLGIsYyxkLGUpe3JldHVybihFP05hOk9hKS5jYWxsKG51bGwsYSxiLGsoYyk/YzpudWxsLGsoZCk/ZDpudWxsLGV8fG5ldyBKKX0KZnVuY3Rpb24gTmEoYSxiLGMsZCxlKXtpZihhIGluc3RhbmNlb2YgQXx8OD09YS5ifHxjJiZudWxsPT09YS5iKXt2YXIgZj1iLmFsbDtpZighZilyZXR1cm4gZTthPVBhKGEpO2lmKCIqIiE9YSYmKGY9Yi5nZXRFbGVtZW50c0J5VGFnTmFtZShhKSwhZikpcmV0dXJuIGU7aWYoYyl7Zm9yKHZhciBnPVtdLGw9MDtiPWZbbCsrXTspSChiLGMsZCkmJmcucHVzaChiKTtmPWd9Zm9yKGw9MDtiPWZbbCsrXTspIioiPT1hJiYiISI9PWIudGFnTmFtZXx8SyhlLGIpO3JldHVybiBlfVFhKGEsYixjLGQsZSk7cmV0dXJuIGV9CmZ1bmN0aW9uIE9hKGEsYixjLGQsZSl7Yi5nZXRFbGVtZW50c0J5TmFtZSYmZCYmIm5hbWUiPT1jJiYhdj8oYj1iLmdldEVsZW1lbnRzQnlOYW1lKGQpLHQoYixmdW5jdGlvbihiKXthLmEoYikmJksoZSxiKX0pKTpiLmdldEVsZW1lbnRzQnlDbGFzc05hbWUmJmQmJiJjbGFzcyI9PWM/KGI9Yi5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKGQpLHQoYixmdW5jdGlvbihiKXtiLmNsYXNzTmFtZT09ZCYmYS5hKGIpJiZLKGUsYil9KSk6YSBpbnN0YW5jZW9mIEI/UWEoYSxiLGMsZCxlKTpiLmdldEVsZW1lbnRzQnlUYWdOYW1lJiYoYj1iLmdldEVsZW1lbnRzQnlUYWdOYW1lKGEuZCgpKSx0KGIsZnVuY3Rpb24oYSl7SChhLGMsZCkmJksoZSxhKX0pKTtyZXR1cm4gZX0KZnVuY3Rpb24gUmEoYSxiLGMsZCxlKXt2YXIgZjtpZigoYSBpbnN0YW5jZW9mIEF8fDg9PWEuYnx8YyYmbnVsbD09PWEuYikmJihmPWIuY2hpbGROb2Rlcykpe3ZhciBnPVBhKGEpO2lmKCIqIiE9ZyYmKGY9a2EoZixmdW5jdGlvbihhKXtyZXR1cm4gYS50YWdOYW1lJiZhLnRhZ05hbWUudG9Mb3dlckNhc2UoKT09Z30pLCFmKSlyZXR1cm4gZTtjJiYoZj1rYShmLGZ1bmN0aW9uKGEpe3JldHVybiBIKGEsYyxkKX0pKTt0KGYsZnVuY3Rpb24oYSl7IioiPT1nJiYoIiEiPT1hLnRhZ05hbWV8fCIqIj09ZyYmMSE9YS5ub2RlVHlwZSl8fEsoZSxhKX0pO3JldHVybiBlfXJldHVybiBTYShhLGIsYyxkLGUpfWZ1bmN0aW9uIFNhKGEsYixjLGQsZSl7Zm9yKGI9Yi5maXJzdENoaWxkO2I7Yj1iLm5leHRTaWJsaW5nKUgoYixjLGQpJiZhLmEoYikmJksoZSxiKTtyZXR1cm4gZX0KZnVuY3Rpb24gUWEoYSxiLGMsZCxlKXtmb3IoYj1iLmZpcnN0Q2hpbGQ7YjtiPWIubmV4dFNpYmxpbmcpSChiLGMsZCkmJmEuYShiKSYmSyhlLGIpLFFhKGEsYixjLGQsZSl9ZnVuY3Rpb24gUGEoYSl7aWYoYSBpbnN0YW5jZW9mIEIpe2lmKDg9PWEuYilyZXR1cm4iISI7aWYobnVsbD09PWEuYilyZXR1cm4iKiJ9cmV0dXJuIGEuZCgpfTtmdW5jdGlvbiBKKCl7dGhpcy5iPXRoaXMuYT1udWxsO3RoaXMuaT0wfWZ1bmN0aW9uIFRhKGEpe3RoaXMuZD1hO3RoaXMuYT10aGlzLmI9bnVsbH1mdW5jdGlvbiBVYShhLGIpe2lmKCFhLmEpcmV0dXJuIGI7aWYoIWIuYSlyZXR1cm4gYTtmb3IodmFyIGM9YS5hLGQ9Yi5hLGU9bnVsbCxmPW51bGwsZz0wO2MmJmQ7KXt2YXIgZj1jLmQsbD1kLmQ7Zj09bHx8ZiBpbnN0YW5jZW9mIEYmJmwgaW5zdGFuY2VvZiBGJiZmLmE9PWwuYT8oZj1jLGM9Yy5hLGQ9ZC5hKTowPHphKGMuZCxkLmQpPyhmPWQsZD1kLmEpOihmPWMsYz1jLmEpOyhmLmI9ZSk/ZS5hPWY6YS5hPWY7ZT1mO2crK31mb3IoZj1jfHxkO2Y7KWYuYj1lLGU9ZS5hPWYsZysrLGY9Zi5hO2EuYj1lO2EuaT1nO3JldHVybiBhfWZ1bmN0aW9uIFZhKGEsYil7dmFyIGM9bmV3IFRhKGIpO2MuYT1hLmE7YS5iP2EuYS5iPWM6YS5hPWEuYj1jO2EuYT1jO2EuaSsrfQpmdW5jdGlvbiBLKGEsYil7dmFyIGM9bmV3IFRhKGIpO2MuYj1hLmI7YS5hP2EuYi5hPWM6YS5hPWEuYj1jO2EuYj1jO2EuaSsrfWZ1bmN0aW9uIFdhKGEpe3JldHVybihhPWEuYSk/YS5kOm51bGx9ZnVuY3Rpb24gWGEoYSl7cmV0dXJuKGE9V2EoYSkpP0coYSk6IiJ9ZnVuY3Rpb24gTChhLGIpe3JldHVybiBuZXcgWWEoYSwhIWIpfWZ1bmN0aW9uIFlhKGEsYil7dGhpcy5kPWE7dGhpcy5iPSh0aGlzLmM9Yik/YS5iOmEuYTt0aGlzLmE9bnVsbH1mdW5jdGlvbiBNKGEpe3ZhciBiPWEuYjtpZihudWxsPT1iKXJldHVybiBudWxsO3ZhciBjPWEuYT1iO2EuYj1hLmM/Yi5iOmIuYTtyZXR1cm4gYy5kfTtmdW5jdGlvbiBuKGEpe3RoaXMuZz1hO3RoaXMuYj10aGlzLmU9ITE7dGhpcy5kPW51bGx9ZnVuY3Rpb24gRChhKXtyZXR1cm4iXG4gICIrYS50b1N0cmluZygpLnNwbGl0KCJcbiIpLmpvaW4oIlxuICAiKX1mdW5jdGlvbiBaYShhLGIpe2EuZT1ifWZ1bmN0aW9uICRhKGEsYil7YS5iPWJ9ZnVuY3Rpb24gTihhLGIpe3ZhciBjPWEuYShiKTtyZXR1cm4gYyBpbnN0YW5jZW9mIEo/K1hhKGMpOitjfWZ1bmN0aW9uIE8oYSxiKXt2YXIgYz1hLmEoYik7cmV0dXJuIGMgaW5zdGFuY2VvZiBKP1hhKGMpOiIiK2N9ZnVuY3Rpb24gUChhLGIpe3ZhciBjPWEuYShiKTtyZXR1cm4gYyBpbnN0YW5jZW9mIEo/ISFjLmk6ISFjfTtmdW5jdGlvbiBRKGEsYixjKXtuLmNhbGwodGhpcyxhLmcpO3RoaXMuYz1hO3RoaXMuZj1iO3RoaXMuaz1jO3RoaXMuZT1iLmV8fGMuZTt0aGlzLmI9Yi5ifHxjLmI7dGhpcy5jPT1hYiYmKGMuYnx8Yy5lfHw0PT1jLmd8fDA9PWMuZ3x8IWIuZD9iLmJ8fGIuZXx8ND09Yi5nfHwwPT1iLmd8fCFjLmR8fCh0aGlzLmQ9e25hbWU6Yy5kLm5hbWUsbDpifSk6dGhpcy5kPXtuYW1lOmIuZC5uYW1lLGw6Y30pfW0oUSk7CmZ1bmN0aW9uIFIoYSxiLGMsZCxlKXtiPWIuYShkKTtjPWMuYShkKTt2YXIgZjtpZihiIGluc3RhbmNlb2YgSiYmYyBpbnN0YW5jZW9mIEope2U9TChiKTtmb3IoZD1NKGUpO2Q7ZD1NKGUpKWZvcihiPUwoYyksZj1NKGIpO2Y7Zj1NKGIpKWlmKGEoRyhkKSxHKGYpKSlyZXR1cm4hMDtyZXR1cm4hMX1pZihiIGluc3RhbmNlb2YgSnx8YyBpbnN0YW5jZW9mIEope2IgaW5zdGFuY2VvZiBKP2U9YjooZT1jLGM9Yik7ZT1MKGUpO2I9dHlwZW9mIGM7Zm9yKGQ9TShlKTtkO2Q9TShlKSl7c3dpdGNoKGIpe2Nhc2UgIm51bWJlciI6ZD0rRyhkKTticmVhaztjYXNlICJib29sZWFuIjpkPSEhRyhkKTticmVhaztjYXNlICJzdHJpbmciOmQ9RyhkKTticmVhaztkZWZhdWx0OnRocm93IEVycm9yKCJJbGxlZ2FsIHByaW1pdGl2ZSB0eXBlIGZvciBjb21wYXJpc29uLiIpO31pZihhKGQsYykpcmV0dXJuITB9cmV0dXJuITF9cmV0dXJuIGU/ImJvb2xlYW4iPT10eXBlb2YgYnx8ImJvb2xlYW4iPT10eXBlb2YgYz8KYSghIWIsISFjKToibnVtYmVyIj09dHlwZW9mIGJ8fCJudW1iZXIiPT10eXBlb2YgYz9hKCtiLCtjKTphKGIsYyk6YSgrYiwrYyl9US5wcm90b3R5cGUuYT1mdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5jLmoodGhpcy5mLHRoaXMuayxhKX07US5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXt2YXIgYT0iQmluYXJ5IEV4cHJlc3Npb246ICIrdGhpcy5jLGE9YStEKHRoaXMuZik7cmV0dXJuIGErPUQodGhpcy5rKX07ZnVuY3Rpb24gYmIoYSxiLGMsZCl7dGhpcy5hPWE7dGhpcy5wPWI7dGhpcy5nPWM7dGhpcy5qPWR9YmIucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYX07dmFyIGNiPXt9O2Z1bmN0aW9uIFMoYSxiLGMsZCl7aWYoY2IuaGFzT3duUHJvcGVydHkoYSkpdGhyb3cgRXJyb3IoIkJpbmFyeSBvcGVyYXRvciBhbHJlYWR5IGNyZWF0ZWQ6ICIrYSk7YT1uZXcgYmIoYSxiLGMsZCk7cmV0dXJuIGNiW2EudG9TdHJpbmcoKV09YX0KUygiZGl2Iiw2LDEsZnVuY3Rpb24oYSxiLGMpe3JldHVybiBOKGEsYykvTihiLGMpfSk7UygibW9kIiw2LDEsZnVuY3Rpb24oYSxiLGMpe3JldHVybiBOKGEsYyklTihiLGMpfSk7UygiKiIsNiwxLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gTihhLGMpKk4oYixjKX0pO1MoIisiLDUsMSxmdW5jdGlvbihhLGIsYyl7cmV0dXJuIE4oYSxjKStOKGIsYyl9KTtTKCItIiw1LDEsZnVuY3Rpb24oYSxiLGMpe3JldHVybiBOKGEsYyktTihiLGMpfSk7UygiPCIsNCwyLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gUihmdW5jdGlvbihhLGIpe3JldHVybiBhPGJ9LGEsYixjKX0pO1MoIj4iLDQsMixmdW5jdGlvbihhLGIsYyl7cmV0dXJuIFIoZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT5ifSxhLGIsYyl9KTtTKCI8PSIsNCwyLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gUihmdW5jdGlvbihhLGIpe3JldHVybiBhPD1ifSxhLGIsYyl9KTsKUygiPj0iLDQsMixmdW5jdGlvbihhLGIsYyl7cmV0dXJuIFIoZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT49Yn0sYSxiLGMpfSk7dmFyIGFiPVMoIj0iLDMsMixmdW5jdGlvbihhLGIsYyl7cmV0dXJuIFIoZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT09Yn0sYSxiLGMsITApfSk7UygiIT0iLDMsMixmdW5jdGlvbihhLGIsYyl7cmV0dXJuIFIoZnVuY3Rpb24oYSxiKXtyZXR1cm4gYSE9Yn0sYSxiLGMsITApfSk7UygiYW5kIiwyLDIsZnVuY3Rpb24oYSxiLGMpe3JldHVybiBQKGEsYykmJlAoYixjKX0pO1MoIm9yIiwxLDIsZnVuY3Rpb24oYSxiLGMpe3JldHVybiBQKGEsYyl8fFAoYixjKX0pO2Z1bmN0aW9uIGRiKGEsYil7aWYoYi5hLmxlbmd0aCYmNCE9YS5nKXRocm93IEVycm9yKCJQcmltYXJ5IGV4cHJlc3Npb24gbXVzdCBldmFsdWF0ZSB0byBub2Rlc2V0IGlmIGZpbHRlciBoYXMgcHJlZGljYXRlKHMpLiIpO24uY2FsbCh0aGlzLGEuZyk7dGhpcy5jPWE7dGhpcy5mPWI7dGhpcy5lPWEuZTt0aGlzLmI9YS5ifW0oZGIpO2RiLnByb3RvdHlwZS5hPWZ1bmN0aW9uKGEpe2E9dGhpcy5jLmEoYSk7cmV0dXJuIGViKHRoaXMuZixhKX07ZGIucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7dmFyIGE7YT0iRmlsdGVyOiIrRCh0aGlzLmMpO3JldHVybiBhKz1EKHRoaXMuZil9O2Z1bmN0aW9uIGZiKGEsYil7aWYoYi5sZW5ndGg8YS5vKXRocm93IEVycm9yKCJGdW5jdGlvbiAiK2EuaCsiIGV4cGVjdHMgYXQgbGVhc3QiK2EubysiIGFyZ3VtZW50cywgIitiLmxlbmd0aCsiIGdpdmVuIik7aWYobnVsbCE9PWEubiYmYi5sZW5ndGg+YS5uKXRocm93IEVycm9yKCJGdW5jdGlvbiAiK2EuaCsiIGV4cGVjdHMgYXQgbW9zdCAiK2EubisiIGFyZ3VtZW50cywgIitiLmxlbmd0aCsiIGdpdmVuIik7YS5zJiZ0KGIsZnVuY3Rpb24oYixkKXtpZig0IT1iLmcpdGhyb3cgRXJyb3IoIkFyZ3VtZW50ICIrZCsiIHRvIGZ1bmN0aW9uICIrYS5oKyIgaXMgbm90IG9mIHR5cGUgTm9kZXNldDogIitiKTt9KTtuLmNhbGwodGhpcyxhLmcpO3RoaXMuZj1hO3RoaXMuYz1iO1phKHRoaXMsYS5lfHxsYShiLGZ1bmN0aW9uKGEpe3JldHVybiBhLmV9KSk7JGEodGhpcyxhLnImJiFiLmxlbmd0aHx8YS5xJiYhIWIubGVuZ3RofHxsYShiLGZ1bmN0aW9uKGEpe3JldHVybiBhLmJ9KSl9bShmYik7CmZiLnByb3RvdHlwZS5hPWZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmYuai5hcHBseShudWxsLG5hKGEsdGhpcy5jKSl9O2ZiLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3ZhciBhPSJGdW5jdGlvbjogIit0aGlzLmY7aWYodGhpcy5jLmxlbmd0aCl2YXIgYj11KHRoaXMuYyxmdW5jdGlvbihhLGIpe3JldHVybiBhK0QoYil9LCJBcmd1bWVudHM6IiksYT1hK0QoYik7cmV0dXJuIGF9O2Z1bmN0aW9uIGdiKGEsYixjLGQsZSxmLGcsbCxwKXt0aGlzLmg9YTt0aGlzLmc9Yjt0aGlzLmU9Yzt0aGlzLnI9ZDt0aGlzLnE9ZTt0aGlzLmo9Zjt0aGlzLm89Zzt0aGlzLm49dm9pZCAwIT09bD9sOmc7dGhpcy5zPSEhcH1nYi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ofTt2YXIgaGI9e307CmZ1bmN0aW9uIFQoYSxiLGMsZCxlLGYsZyxsKXtpZihoYi5oYXNPd25Qcm9wZXJ0eShhKSl0aHJvdyBFcnJvcigiRnVuY3Rpb24gYWxyZWFkeSBjcmVhdGVkOiAiK2ErIi4iKTtoYlthXT1uZXcgZ2IoYSxiLGMsZCwhMSxlLGYsZyxsKX1UKCJib29sZWFuIiwyLCExLCExLGZ1bmN0aW9uKGEsYil7cmV0dXJuIFAoYixhKX0sMSk7VCgiY2VpbGluZyIsMSwhMSwhMSxmdW5jdGlvbihhLGIpe3JldHVybiBNYXRoLmNlaWwoTihiLGEpKX0sMSk7VCgiY29uY2F0IiwzLCExLCExLGZ1bmN0aW9uKGEsYil7cmV0dXJuIHUob2EoYXJndW1lbnRzLDEpLGZ1bmN0aW9uKGIsZCl7cmV0dXJuIGIrTyhkLGEpfSwiIil9LDIsbnVsbCk7VCgiY29udGFpbnMiLDIsITEsITEsZnVuY3Rpb24oYSxiLGMpe2I9TyhiLGEpO2E9TyhjLGEpO3JldHVybi0xIT1iLmluZGV4T2YoYSl9LDIpO1QoImNvdW50IiwxLCExLCExLGZ1bmN0aW9uKGEsYil7cmV0dXJuIGIuYShhKS5pfSwxLDEsITApOwpUKCJmYWxzZSIsMiwhMSwhMSxmdW5jdGlvbigpe3JldHVybiExfSwwKTtUKCJmbG9vciIsMSwhMSwhMSxmdW5jdGlvbihhLGIpe3JldHVybiBNYXRoLmZsb29yKE4oYixhKSl9LDEpO1QoImlkIiw0LCExLCExLGZ1bmN0aW9uKGEsYil7ZnVuY3Rpb24gYyhhKXtpZihFKXt2YXIgYj1lLmFsbFthXTtpZihiKXtpZihiLm5vZGVUeXBlJiZhPT1iLmlkKXJldHVybiBiO2lmKGIubGVuZ3RoKXJldHVybiBtYShiLGZ1bmN0aW9uKGIpe3JldHVybiBhPT1iLmlkfSl9cmV0dXJuIG51bGx9cmV0dXJuIGUuZ2V0RWxlbWVudEJ5SWQoYSl9dmFyIGQ9YS5hLGU9OT09ZC5ub2RlVHlwZT9kOmQub3duZXJEb2N1bWVudCxkPU8oYixhKS5zcGxpdCgvXHMrLyksZj1bXTt0KGQsZnVuY3Rpb24oYSl7YT1jKGEpOyFhfHwwPD1qYShmLGEpfHxmLnB1c2goYSl9KTtmLnNvcnQoemEpO3ZhciBnPW5ldyBKO3QoZixmdW5jdGlvbihhKXtLKGcsYSl9KTtyZXR1cm4gZ30sMSk7ClQoImxhbmciLDIsITEsITEsZnVuY3Rpb24oKXtyZXR1cm4hMX0sMSk7VCgibGFzdCIsMSwhMCwhMSxmdW5jdGlvbihhKXtpZigxIT1hcmd1bWVudHMubGVuZ3RoKXRocm93IEVycm9yKCJGdW5jdGlvbiBsYXN0IGV4cGVjdHMgKCkiKTtyZXR1cm4gYS5kfSwwKTtUKCJsb2NhbC1uYW1lIiwzLCExLCEwLGZ1bmN0aW9uKGEsYil7dmFyIGM9Yj9XYShiLmEoYSkpOmEuYTtyZXR1cm4gYz9jLmxvY2FsTmFtZXx8Yy5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpOiIifSwwLDEsITApO1QoIm5hbWUiLDMsITEsITAsZnVuY3Rpb24oYSxiKXt2YXIgYz1iP1dhKGIuYShhKSk6YS5hO3JldHVybiBjP2Mubm9kZU5hbWUudG9Mb3dlckNhc2UoKToiIn0sMCwxLCEwKTtUKCJuYW1lc3BhY2UtdXJpIiwzLCEwLCExLGZ1bmN0aW9uKCl7cmV0dXJuIiJ9LDAsMSwhMCk7ClQoIm5vcm1hbGl6ZS1zcGFjZSIsMywhMSwhMCxmdW5jdGlvbihhLGIpe3JldHVybihiP08oYixhKTpHKGEuYSkpLnJlcGxhY2UoL1tcc1x4YTBdKy9nLCIgIikucmVwbGFjZSgvXlxzK3xccyskL2csIiIpfSwwLDEpO1QoIm5vdCIsMiwhMSwhMSxmdW5jdGlvbihhLGIpe3JldHVybiFQKGIsYSl9LDEpO1QoIm51bWJlciIsMSwhMSwhMCxmdW5jdGlvbihhLGIpe3JldHVybiBiP04oYixhKTorRyhhLmEpfSwwLDEpO1QoInBvc2l0aW9uIiwxLCEwLCExLGZ1bmN0aW9uKGEpe3JldHVybiBhLmJ9LDApO1QoInJvdW5kIiwxLCExLCExLGZ1bmN0aW9uKGEsYil7cmV0dXJuIE1hdGgucm91bmQoTihiLGEpKX0sMSk7VCgic3RhcnRzLXdpdGgiLDIsITEsITEsZnVuY3Rpb24oYSxiLGMpe2I9TyhiLGEpO2E9TyhjLGEpO3JldHVybiAwPT1iLmxhc3RJbmRleE9mKGEsMCl9LDIpO1QoInN0cmluZyIsMywhMSwhMCxmdW5jdGlvbihhLGIpe3JldHVybiBiP08oYixhKTpHKGEuYSl9LDAsMSk7ClQoInN0cmluZy1sZW5ndGgiLDEsITEsITAsZnVuY3Rpb24oYSxiKXtyZXR1cm4oYj9PKGIsYSk6RyhhLmEpKS5sZW5ndGh9LDAsMSk7VCgic3Vic3RyaW5nIiwzLCExLCExLGZ1bmN0aW9uKGEsYixjLGQpe2M9TihjLGEpO2lmKGlzTmFOKGMpfHxJbmZpbml0eT09Y3x8LUluZmluaXR5PT1jKXJldHVybiIiO2Q9ZD9OKGQsYSk6SW5maW5pdHk7aWYoaXNOYU4oZCl8fC1JbmZpbml0eT09PWQpcmV0dXJuIiI7Yz1NYXRoLnJvdW5kKGMpLTE7dmFyIGU9TWF0aC5tYXgoYywwKTthPU8oYixhKTtpZihJbmZpbml0eT09ZClyZXR1cm4gYS5zdWJzdHJpbmcoZSk7Yj1NYXRoLnJvdW5kKGQpO3JldHVybiBhLnN1YnN0cmluZyhlLGMrYil9LDIsMyk7VCgic3Vic3RyaW5nLWFmdGVyIiwzLCExLCExLGZ1bmN0aW9uKGEsYixjKXtiPU8oYixhKTthPU8oYyxhKTtjPWIuaW5kZXhPZihhKTtyZXR1cm4tMT09Yz8iIjpiLnN1YnN0cmluZyhjK2EubGVuZ3RoKX0sMik7ClQoInN1YnN0cmluZy1iZWZvcmUiLDMsITEsITEsZnVuY3Rpb24oYSxiLGMpe2I9TyhiLGEpO2E9TyhjLGEpO2E9Yi5pbmRleE9mKGEpO3JldHVybi0xPT1hPyIiOmIuc3Vic3RyaW5nKDAsYSl9LDIpO1QoInN1bSIsMSwhMSwhMSxmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz1MKGIuYShhKSksZD0wLGU9TShjKTtlO2U9TShjKSlkKz0rRyhlKTtyZXR1cm4gZH0sMSwxLCEwKTtUKCJ0cmFuc2xhdGUiLDMsITEsITEsZnVuY3Rpb24oYSxiLGMsZCl7Yj1PKGIsYSk7Yz1PKGMsYSk7dmFyIGU9TyhkLGEpO2E9W107Zm9yKGQ9MDtkPGMubGVuZ3RoO2QrKyl7dmFyIGY9Yy5jaGFyQXQoZCk7ZiBpbiBhfHwoYVtmXT1lLmNoYXJBdChkKSl9Yz0iIjtmb3IoZD0wO2Q8Yi5sZW5ndGg7ZCsrKWY9Yi5jaGFyQXQoZCksYys9ZiBpbiBhP2FbZl06ZjtyZXR1cm4gY30sMyk7VCgidHJ1ZSIsMiwhMSwhMSxmdW5jdGlvbigpe3JldHVybiEwfSwwKTtmdW5jdGlvbiBpYihhKXtuLmNhbGwodGhpcywzKTt0aGlzLmM9YS5zdWJzdHJpbmcoMSxhLmxlbmd0aC0xKX1tKGliKTtpYi5wcm90b3R5cGUuYT1mdW5jdGlvbigpe3JldHVybiB0aGlzLmN9O2liLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiJMaXRlcmFsOiAiK3RoaXMuY307ZnVuY3Rpb24gamIoYSl7bi5jYWxsKHRoaXMsMSk7dGhpcy5jPWF9bShqYik7amIucHJvdG90eXBlLmE9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jfTtqYi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4iTnVtYmVyOiAiK3RoaXMuY307ZnVuY3Rpb24ga2IoYSxiKXtuLmNhbGwodGhpcyxhLmcpO3RoaXMuZj1hO3RoaXMuYz1iO3RoaXMuZT1hLmU7dGhpcy5iPWEuYjtpZigxPT10aGlzLmMubGVuZ3RoKXt2YXIgYz10aGlzLmNbMF07Yy5tfHxjLmMhPWxifHwoYz1jLmssIioiIT1jLmQoKSYmKHRoaXMuZD17bmFtZTpjLmQoKSxsOm51bGx9KSl9fW0oa2IpO2Z1bmN0aW9uIFUoKXtuLmNhbGwodGhpcyw0KX1tKFUpO1UucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IEo7YT1hLmE7OT09YS5ub2RlVHlwZT9LKGIsYSk6SyhiLGEub3duZXJEb2N1bWVudCk7cmV0dXJuIGJ9O1UucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIlJvb3QgSGVscGVyIEV4cHJlc3Npb24ifTtmdW5jdGlvbiBtYigpe24uY2FsbCh0aGlzLDQpfW0obWIpO21iLnByb3RvdHlwZS5hPWZ1bmN0aW9uKGEpe3ZhciBiPW5ldyBKO0soYixhLmEpO3JldHVybiBifTttYi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4iQ29udGV4dCBIZWxwZXIgRXhwcmVzc2lvbiJ9OwpmdW5jdGlvbiBuYihhKXtyZXR1cm4iLyI9PWF8fCIvLyI9PWF9a2IucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcy5mLmEoYSk7aWYoIShiIGluc3RhbmNlb2YgSikpdGhyb3cgRXJyb3IoIkZpbHRlciBleHByZXNzaW9uIG11c3QgZXZhbHVhdGUgdG8gbm9kZXNldC4iKTthPXRoaXMuYztmb3IodmFyIGM9MCxkPWEubGVuZ3RoO2M8ZCYmYi5pO2MrKyl7dmFyIGU9YVtjXSxmPUwoYixlLmMuYSksZztpZihlLmV8fGUuYyE9b2IpaWYoZS5lfHxlLmMhPXBiKWZvcihnPU0oZiksYj1lLmEobmV3IHcoZykpO251bGwhPShnPU0oZikpOylnPWUuYShuZXcgdyhnKSksYj1VYShiLGcpO2Vsc2UgZz1NKGYpLGI9ZS5hKG5ldyB3KGcpKTtlbHNle2ZvcihnPU0oZik7KGI9TShmKSkmJighZy5jb250YWluc3x8Zy5jb250YWlucyhiKSkmJmIuY29tcGFyZURvY3VtZW50UG9zaXRpb24oZykmODtnPWIpO2I9ZS5hKG5ldyB3KGcpKX19cmV0dXJuIGJ9OwprYi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXt2YXIgYTthPSJQYXRoIEV4cHJlc3Npb246IitEKHRoaXMuZik7aWYodGhpcy5jLmxlbmd0aCl7dmFyIGI9dSh0aGlzLmMsZnVuY3Rpb24oYSxiKXtyZXR1cm4gYStEKGIpfSwiU3RlcHM6Iik7YSs9RChiKX1yZXR1cm4gYX07ZnVuY3Rpb24gcWIoYSxiKXt0aGlzLmE9YTt0aGlzLmI9ISFifQpmdW5jdGlvbiBlYihhLGIsYyl7Zm9yKGM9Y3x8MDtjPGEuYS5sZW5ndGg7YysrKWZvcih2YXIgZD1hLmFbY10sZT1MKGIpLGY9Yi5pLGcsbD0wO2c9TShlKTtsKyspe3ZhciBwPWEuYj9mLWw6bCsxO2c9ZC5hKG5ldyB3KGcscCxmKSk7aWYoIm51bWJlciI9PXR5cGVvZiBnKXA9cD09ZztlbHNlIGlmKCJzdHJpbmciPT10eXBlb2YgZ3x8ImJvb2xlYW4iPT10eXBlb2YgZylwPSEhZztlbHNlIGlmKGcgaW5zdGFuY2VvZiBKKXA9MDxnLmk7ZWxzZSB0aHJvdyBFcnJvcigiUHJlZGljYXRlLmV2YWx1YXRlIHJldHVybmVkIGFuIHVuZXhwZWN0ZWQgdHlwZS4iKTtpZighcCl7cD1lO2c9cC5kO3ZhciB4PXAuYTtpZigheCl0aHJvdyBFcnJvcigiTmV4dCBtdXN0IGJlIGNhbGxlZCBhdCBsZWFzdCBvbmNlIGJlZm9yZSByZW1vdmUuIik7dmFyIEM9eC5iLHg9eC5hO0M/Qy5hPXg6Zy5hPXg7eD94LmI9QzpnLmI9QztnLmktLTtwLmE9bnVsbH19cmV0dXJuIGJ9CnFiLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB1KHRoaXMuYSxmdW5jdGlvbihhLGIpe3JldHVybiBhK0QoYil9LCJQcmVkaWNhdGVzOiIpfTtmdW5jdGlvbiBWKGEsYixjLGQpe24uY2FsbCh0aGlzLDQpO3RoaXMuYz1hO3RoaXMuaz1iO3RoaXMuZj1jfHxuZXcgcWIoW10pO3RoaXMubT0hIWQ7Yj10aGlzLmY7Yj0wPGIuYS5sZW5ndGg/Yi5hWzBdLmQ6bnVsbDthLmImJmImJihhPWIubmFtZSxhPUU/YS50b0xvd2VyQ2FzZSgpOmEsdGhpcy5kPXtuYW1lOmEsbDpiLmx9KTthOnthPXRoaXMuZjtmb3IoYj0wO2I8YS5hLmxlbmd0aDtiKyspaWYoYz1hLmFbYl0sYy5lfHwxPT1jLmd8fDA9PWMuZyl7YT0hMDticmVhayBhfWE9ITF9dGhpcy5lPWF9bShWKTsKVi5wcm90b3R5cGUuYT1mdW5jdGlvbihhKXt2YXIgYj1hLmEsYz1udWxsLGM9dGhpcy5kLGQ9bnVsbCxlPW51bGwsZj0wO2MmJihkPWMubmFtZSxlPWMubD9PKGMubCxhKTpudWxsLGY9MSk7aWYodGhpcy5tKWlmKHRoaXMuZXx8dGhpcy5jIT1yYilpZihhPUwoKG5ldyBWKHNiLG5ldyBCKCJub2RlIikpKS5hKGEpKSxiPU0oYSkpZm9yKGM9dGhpcy5qKGIsZCxlLGYpO251bGwhPShiPU0oYSkpOyljPVVhKGMsdGhpcy5qKGIsZCxlLGYpKTtlbHNlIGM9bmV3IEo7ZWxzZSBjPUkodGhpcy5rLGIsZCxlKSxjPWViKHRoaXMuZixjLGYpO2Vsc2UgYz10aGlzLmooYS5hLGQsZSxmKTtyZXR1cm4gY307Vi5wcm90b3R5cGUuaj1mdW5jdGlvbihhLGIsYyxkKXthPXRoaXMuYy5kKHRoaXMuayxhLGIsYyk7cmV0dXJuIGE9ZWIodGhpcy5mLGEsZCl9OwpWLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3ZhciBhO2E9IlN0ZXA6IitEKCJPcGVyYXRvcjogIisodGhpcy5tPyIvLyI6Ii8iKSk7dGhpcy5jLmgmJihhKz1EKCJBeGlzOiAiK3RoaXMuYykpO2ErPUQodGhpcy5rKTtpZih0aGlzLmYuYS5sZW5ndGgpe3ZhciBiPXUodGhpcy5mLmEsZnVuY3Rpb24oYSxiKXtyZXR1cm4gYStEKGIpfSwiUHJlZGljYXRlczoiKTthKz1EKGIpfXJldHVybiBhfTtmdW5jdGlvbiB0YihhLGIsYyxkKXt0aGlzLmg9YTt0aGlzLmQ9Yjt0aGlzLmE9Yzt0aGlzLmI9ZH10Yi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ofTt2YXIgdWI9e307ZnVuY3Rpb24gVyhhLGIsYyxkKXtpZih1Yi5oYXNPd25Qcm9wZXJ0eShhKSl0aHJvdyBFcnJvcigiQXhpcyBhbHJlYWR5IGNyZWF0ZWQ6ICIrYSk7Yj1uZXcgdGIoYSxiLGMsISFkKTtyZXR1cm4gdWJbYV09Yn0KVygiYW5jZXN0b3IiLGZ1bmN0aW9uKGEsYil7Zm9yKHZhciBjPW5ldyBKLGQ9YjtkPWQucGFyZW50Tm9kZTspYS5hKGQpJiZWYShjLGQpO3JldHVybiBjfSwhMCk7VygiYW5jZXN0b3Itb3Itc2VsZiIsZnVuY3Rpb24oYSxiKXt2YXIgYz1uZXcgSixkPWI7ZG8gYS5hKGQpJiZWYShjLGQpO3doaWxlKGQ9ZC5wYXJlbnROb2RlKTtyZXR1cm4gY30sITApOwp2YXIgbGI9VygiYXR0cmlidXRlIixmdW5jdGlvbihhLGIpe3ZhciBjPW5ldyBKLGQ9YS5kKCk7aWYoInN0eWxlIj09ZCYmYi5zdHlsZSYmRSlyZXR1cm4gSyhjLG5ldyBGKGIuc3R5bGUsYiwic3R5bGUiLGIuc3R5bGUuY3NzVGV4dCkpLGM7dmFyIGU9Yi5hdHRyaWJ1dGVzO2lmKGUpaWYoYSBpbnN0YW5jZW9mIEImJm51bGw9PT1hLmJ8fCIqIj09ZClmb3IodmFyIGQ9MCxmO2Y9ZVtkXTtkKyspRT9mLm5vZGVWYWx1ZSYmSyhjLE1hKGIsZikpOksoYyxmKTtlbHNlKGY9ZS5nZXROYW1lZEl0ZW0oZCkpJiYoRT9mLm5vZGVWYWx1ZSYmSyhjLE1hKGIsZikpOksoYyxmKSk7cmV0dXJuIGN9LCExKSxyYj1XKCJjaGlsZCIsZnVuY3Rpb24oYSxiLGMsZCxlKXtyZXR1cm4oRT9SYTpTYSkuY2FsbChudWxsLGEsYixrKGMpP2M6bnVsbCxrKGQpP2Q6bnVsbCxlfHxuZXcgSil9LCExLCEwKTtXKCJkZXNjZW5kYW50IixJLCExLCEwKTsKdmFyIHNiPVcoImRlc2NlbmRhbnQtb3Itc2VsZiIsZnVuY3Rpb24oYSxiLGMsZCl7dmFyIGU9bmV3IEo7SChiLGMsZCkmJmEuYShiKSYmSyhlLGIpO3JldHVybiBJKGEsYixjLGQsZSl9LCExLCEwKSxvYj1XKCJmb2xsb3dpbmciLGZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlPW5ldyBKO2RvIGZvcih2YXIgZj1iO2Y9Zi5uZXh0U2libGluZzspSChmLGMsZCkmJmEuYShmKSYmSyhlLGYpLGU9SShhLGYsYyxkLGUpO3doaWxlKGI9Yi5wYXJlbnROb2RlKTtyZXR1cm4gZX0sITEsITApO1coImZvbGxvd2luZy1zaWJsaW5nIixmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz1uZXcgSixkPWI7ZD1kLm5leHRTaWJsaW5nOylhLmEoZCkmJksoYyxkKTtyZXR1cm4gY30sITEpO1coIm5hbWVzcGFjZSIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEp9LCExKTsKdmFyIHZiPVcoInBhcmVudCIsZnVuY3Rpb24oYSxiKXt2YXIgYz1uZXcgSjtpZig5PT1iLm5vZGVUeXBlKXJldHVybiBjO2lmKDI9PWIubm9kZVR5cGUpcmV0dXJuIEsoYyxiLm93bmVyRWxlbWVudCksYzt2YXIgZD1iLnBhcmVudE5vZGU7YS5hKGQpJiZLKGMsZCk7cmV0dXJuIGN9LCExKSxwYj1XKCJwcmVjZWRpbmciLGZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlPW5ldyBKLGY9W107ZG8gZi51bnNoaWZ0KGIpO3doaWxlKGI9Yi5wYXJlbnROb2RlKTtmb3IodmFyIGc9MSxsPWYubGVuZ3RoO2c8bDtnKyspe3ZhciBwPVtdO2ZvcihiPWZbZ107Yj1iLnByZXZpb3VzU2libGluZzspcC51bnNoaWZ0KGIpO2Zvcih2YXIgeD0wLEM9cC5sZW5ndGg7eDxDO3grKyliPXBbeF0sSChiLGMsZCkmJmEuYShiKSYmSyhlLGIpLGU9SShhLGIsYyxkLGUpfXJldHVybiBlfSwhMCwhMCk7ClcoInByZWNlZGluZy1zaWJsaW5nIixmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz1uZXcgSixkPWI7ZD1kLnByZXZpb3VzU2libGluZzspYS5hKGQpJiZWYShjLGQpO3JldHVybiBjfSwhMCk7dmFyIHdiPVcoInNlbGYiLGZ1bmN0aW9uKGEsYil7dmFyIGM9bmV3IEo7YS5hKGIpJiZLKGMsYik7cmV0dXJuIGN9LCExKTtmdW5jdGlvbiB4YihhKXtuLmNhbGwodGhpcywxKTt0aGlzLmM9YTt0aGlzLmU9YS5lO3RoaXMuYj1hLmJ9bSh4Yik7eGIucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7cmV0dXJuLU4odGhpcy5jLGEpfTt4Yi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4iVW5hcnkgRXhwcmVzc2lvbjogLSIrRCh0aGlzLmMpfTtmdW5jdGlvbiB5YihhKXtuLmNhbGwodGhpcyw0KTt0aGlzLmM9YTtaYSh0aGlzLGxhKHRoaXMuYyxmdW5jdGlvbihhKXtyZXR1cm4gYS5lfSkpOyRhKHRoaXMsbGEodGhpcy5jLGZ1bmN0aW9uKGEpe3JldHVybiBhLmJ9KSl9bSh5Yik7eWIucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IEo7dCh0aGlzLmMsZnVuY3Rpb24oYyl7Yz1jLmEoYSk7aWYoIShjIGluc3RhbmNlb2YgSikpdGhyb3cgRXJyb3IoIlBhdGggZXhwcmVzc2lvbiBtdXN0IGV2YWx1YXRlIHRvIE5vZGVTZXQuIik7Yj1VYShiLGMpfSk7cmV0dXJuIGJ9O3liLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB1KHRoaXMuYyxmdW5jdGlvbihhLGIpe3JldHVybiBhK0QoYil9LCJVbmlvbiBFeHByZXNzaW9uOiIpfTtmdW5jdGlvbiB6YihhLGIpe3RoaXMuYT1hO3RoaXMuYj1ifWZ1bmN0aW9uIEFiKGEpe2Zvcih2YXIgYixjPVtdOzspe1koYSwiTWlzc2luZyByaWdodCBoYW5kIHNpZGUgb2YgYmluYXJ5IGV4cHJlc3Npb24uIik7Yj1CYihhKTt2YXIgZD16KGEuYSk7aWYoIWQpYnJlYWs7dmFyIGU9KGQ9Y2JbZF18fG51bGwpJiZkLnA7aWYoIWUpe2EuYS5hLS07YnJlYWt9Zm9yKDtjLmxlbmd0aCYmZTw9Y1tjLmxlbmd0aC0xXS5wOyliPW5ldyBRKGMucG9wKCksYy5wb3AoKSxiKTtjLnB1c2goYixkKX1mb3IoO2MubGVuZ3RoOyliPW5ldyBRKGMucG9wKCksYy5wb3AoKSxiKTtyZXR1cm4gYn1mdW5jdGlvbiBZKGEsYil7aWYoR2EoYS5hKSl0aHJvdyBFcnJvcihiKTt9ZnVuY3Rpb24gQ2IoYSxiKXt2YXIgYz16KGEuYSk7aWYoYyE9Yil0aHJvdyBFcnJvcigiQmFkIHRva2VuLCBleHBlY3RlZDogIitiKyIgZ290OiAiK2MpO30KZnVuY3Rpb24gRGIoYSl7YT16KGEuYSk7aWYoIikiIT1hKXRocm93IEVycm9yKCJCYWQgdG9rZW46ICIrYSk7fWZ1bmN0aW9uIEViKGEpe2E9eihhLmEpO2lmKDI+YS5sZW5ndGgpdGhyb3cgRXJyb3IoIlVuY2xvc2VkIGxpdGVyYWwgc3RyaW5nIik7cmV0dXJuIG5ldyBpYihhKX1mdW5jdGlvbiBGYihhKXt2YXIgYj16KGEuYSksYz1iLmluZGV4T2YoIjoiKTtpZigtMT09YylyZXR1cm4gbmV3IEEoYik7dmFyIGQ9Yi5zdWJzdHJpbmcoMCxjKTthPWEuYihkKTtpZighYSl0aHJvdyBFcnJvcigiTmFtZXNwYWNlIHByZWZpeCBub3QgZGVjbGFyZWQ6ICIrZCk7Yj1iLnN1YnN0cihjKzEpO3JldHVybiBuZXcgQShiLGEpfQpmdW5jdGlvbiBHYihhKXt2YXIgYixjPVtdLGQ7aWYobmIoeShhLmEpKSl7Yj16KGEuYSk7ZD15KGEuYSk7aWYoIi8iPT1iJiYoR2EoYS5hKXx8Ii4iIT1kJiYiLi4iIT1kJiYiQCIhPWQmJiIqIiE9ZCYmIS8oPyFbMC05XSlbXHddLy50ZXN0KGQpKSlyZXR1cm4gbmV3IFU7ZD1uZXcgVTtZKGEsIk1pc3NpbmcgbmV4dCBsb2NhdGlvbiBzdGVwLiIpO2I9SGIoYSxiKTtjLnB1c2goYil9ZWxzZXthOntiPXkoYS5hKTtkPWIuY2hhckF0KDApO3N3aXRjaChkKXtjYXNlICIkIjp0aHJvdyBFcnJvcigiVmFyaWFibGUgcmVmZXJlbmNlIG5vdCBhbGxvd2VkIGluIEhUTUwgWFBhdGgiKTtjYXNlICIoIjp6KGEuYSk7Yj1BYihhKTtZKGEsJ3VuY2xvc2VkICIoIicpO0NiKGEsIikiKTticmVhaztjYXNlICciJzpjYXNlICInIjpiPUViKGEpO2JyZWFrO2RlZmF1bHQ6aWYoaXNOYU4oK2IpKWlmKCFIYShiKSYmLyg/IVswLTldKVtcd10vLnRlc3QoZCkmJiIoIj09eShhLmEsMSkpe2I9eihhLmEpO2I9CmhiW2JdfHxudWxsO3ooYS5hKTtmb3IoZD1bXTsiKSIhPXkoYS5hKTspe1koYSwiTWlzc2luZyBmdW5jdGlvbiBhcmd1bWVudCBsaXN0LiIpO2QucHVzaChBYihhKSk7aWYoIiwiIT15KGEuYSkpYnJlYWs7eihhLmEpfVkoYSwiVW5jbG9zZWQgZnVuY3Rpb24gYXJndW1lbnQgbGlzdC4iKTtEYihhKTtiPW5ldyBmYihiLGQpfWVsc2V7Yj1udWxsO2JyZWFrIGF9ZWxzZSBiPW5ldyBqYigreihhLmEpKX0iWyI9PXkoYS5hKSYmKGQ9bmV3IHFiKEliKGEpKSxiPW5ldyBkYihiLGQpKX1pZihiKWlmKG5iKHkoYS5hKSkpZD1iO2Vsc2UgcmV0dXJuIGI7ZWxzZSBiPUhiKGEsIi8iKSxkPW5ldyBtYixjLnB1c2goYil9Zm9yKDtuYih5KGEuYSkpOyliPXooYS5hKSxZKGEsIk1pc3NpbmcgbmV4dCBsb2NhdGlvbiBzdGVwLiIpLGI9SGIoYSxiKSxjLnB1c2goYik7cmV0dXJuIG5ldyBrYihkLGMpfQpmdW5jdGlvbiBIYihhLGIpe3ZhciBjLGQsZTtpZigiLyIhPWImJiIvLyIhPWIpdGhyb3cgRXJyb3IoJ1N0ZXAgb3Agc2hvdWxkIGJlICIvIiBvciAiLy8iJyk7aWYoIi4iPT15KGEuYSkpcmV0dXJuIGQ9bmV3IFYod2IsbmV3IEIoIm5vZGUiKSkseihhLmEpLGQ7aWYoIi4uIj09eShhLmEpKXJldHVybiBkPW5ldyBWKHZiLG5ldyBCKCJub2RlIikpLHooYS5hKSxkO3ZhciBmO2lmKCJAIj09eShhLmEpKWY9bGIseihhLmEpLFkoYSwiTWlzc2luZyBhdHRyaWJ1dGUgbmFtZSIpO2Vsc2UgaWYoIjo6Ij09eShhLmEsMSkpe2lmKCEvKD8hWzAtOV0pW1x3XS8udGVzdCh5KGEuYSkuY2hhckF0KDApKSl0aHJvdyBFcnJvcigiQmFkIHRva2VuOiAiK3ooYS5hKSk7Yz16KGEuYSk7Zj11YltjXXx8bnVsbDtpZighZil0aHJvdyBFcnJvcigiTm8gYXhpcyB3aXRoIG5hbWU6ICIrYyk7eihhLmEpO1koYSwiTWlzc2luZyBub2RlIG5hbWUiKX1lbHNlIGY9cmI7Yz15KGEuYSk7aWYoLyg/IVswLTldKVtcd10vLnRlc3QoYy5jaGFyQXQoMCkpKWlmKCIoIj09CnkoYS5hLDEpKXtpZighSGEoYykpdGhyb3cgRXJyb3IoIkludmFsaWQgbm9kZSB0eXBlOiAiK2MpO2M9eihhLmEpO2lmKCFIYShjKSl0aHJvdyBFcnJvcigiSW52YWxpZCB0eXBlIG5hbWU6ICIrYyk7Q2IoYSwiKCIpO1koYSwiQmFkIG5vZGV0eXBlIik7ZT15KGEuYSkuY2hhckF0KDApO3ZhciBnPW51bGw7aWYoJyInPT1lfHwiJyI9PWUpZz1FYihhKTtZKGEsIkJhZCBub2RldHlwZSIpO0RiKGEpO2M9bmV3IEIoYyxnKX1lbHNlIGM9RmIoYSk7ZWxzZSBpZigiKiI9PWMpYz1GYihhKTtlbHNlIHRocm93IEVycm9yKCJCYWQgdG9rZW46ICIreihhLmEpKTtlPW5ldyBxYihJYihhKSxmLmEpO3JldHVybiBkfHxuZXcgVihmLGMsZSwiLy8iPT1iKX0KZnVuY3Rpb24gSWIoYSl7Zm9yKHZhciBiPVtdOyJbIj09eShhLmEpOyl7eihhLmEpO1koYSwiTWlzc2luZyBwcmVkaWNhdGUgZXhwcmVzc2lvbi4iKTt2YXIgYz1BYihhKTtiLnB1c2goYyk7WShhLCJVbmNsb3NlZCBwcmVkaWNhdGUgZXhwcmVzc2lvbi4iKTtDYihhLCJdIil9cmV0dXJuIGJ9ZnVuY3Rpb24gQmIoYSl7aWYoIi0iPT15KGEuYSkpcmV0dXJuIHooYS5hKSxuZXcgeGIoQmIoYSkpO3ZhciBiPUdiKGEpO2lmKCJ8IiE9eShhLmEpKWE9YjtlbHNle2ZvcihiPVtiXTsifCI9PXooYS5hKTspWShhLCJNaXNzaW5nIG5leHQgdW5pb24gbG9jYXRpb24gcGF0aC4iKSxiLnB1c2goR2IoYSkpO2EuYS5hLS07YT1uZXcgeWIoYil9cmV0dXJuIGF9O2Z1bmN0aW9uIEpiKGEsYil7aWYoIWEubGVuZ3RoKXRocm93IEVycm9yKCJFbXB0eSBYUGF0aCBleHByZXNzaW9uLiIpO3ZhciBjPURhKGEpO2lmKEdhKGMpKXRocm93IEVycm9yKCJJbnZhbGlkIFhQYXRoIGV4cHJlc3Npb24uIik7Yj8iZnVuY3Rpb24iPT1hYShiKXx8KGI9ZGEoYi5sb29rdXBOYW1lc3BhY2VVUkksYikpOmI9ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH07dmFyIGQ9QWIobmV3IHpiKGMsYikpO2lmKCFHYShjKSl0aHJvdyBFcnJvcigiQmFkIHRva2VuOiAiK3ooYykpO3RoaXMuZXZhbHVhdGU9ZnVuY3Rpb24oYSxiKXt2YXIgYz1kLmEobmV3IHcoYSkpO3JldHVybiBuZXcgWihjLGIpfX0KZnVuY3Rpb24gWihhLGIpe2lmKDA9PWIpaWYoYSBpbnN0YW5jZW9mIEopYj00O2Vsc2UgaWYoInN0cmluZyI9PXR5cGVvZiBhKWI9MjtlbHNlIGlmKCJudW1iZXIiPT10eXBlb2YgYSliPTE7ZWxzZSBpZigiYm9vbGVhbiI9PXR5cGVvZiBhKWI9MztlbHNlIHRocm93IEVycm9yKCJVbmV4cGVjdGVkIGV2YWx1YXRpb24gcmVzdWx0LiIpO2lmKDIhPWImJjEhPWImJjMhPWImJiEoYSBpbnN0YW5jZW9mIEopKXRocm93IEVycm9yKCJ2YWx1ZSBjb3VsZCBub3QgYmUgY29udmVydGVkIHRvIHRoZSBzcGVjaWZpZWQgdHlwZSIpO3RoaXMucmVzdWx0VHlwZT1iO3ZhciBjO3N3aXRjaChiKXtjYXNlIDI6dGhpcy5zdHJpbmdWYWx1ZT1hIGluc3RhbmNlb2YgSj9YYShhKToiIithO2JyZWFrO2Nhc2UgMTp0aGlzLm51bWJlclZhbHVlPWEgaW5zdGFuY2VvZiBKPytYYShhKTorYTticmVhaztjYXNlIDM6dGhpcy5ib29sZWFuVmFsdWU9YSBpbnN0YW5jZW9mIEo/MDxhLmk6ISFhO2JyZWFrO2Nhc2UgNDpjYXNlIDU6Y2FzZSA2OmNhc2UgNzp2YXIgZD0KTChhKTtjPVtdO2Zvcih2YXIgZT1NKGQpO2U7ZT1NKGQpKWMucHVzaChlIGluc3RhbmNlb2YgRj9lLmE6ZSk7dGhpcy5zbmFwc2hvdExlbmd0aD1hLmk7dGhpcy5pbnZhbGlkSXRlcmF0b3JTdGF0ZT0hMTticmVhaztjYXNlIDg6Y2FzZSA5OmQ9V2EoYSk7dGhpcy5zaW5nbGVOb2RlVmFsdWU9ZCBpbnN0YW5jZW9mIEY/ZC5hOmQ7YnJlYWs7ZGVmYXVsdDp0aHJvdyBFcnJvcigiVW5rbm93biBYUGF0aFJlc3VsdCB0eXBlLiIpO312YXIgZj0wO3RoaXMuaXRlcmF0ZU5leHQ9ZnVuY3Rpb24oKXtpZig0IT1iJiY1IT1iKXRocm93IEVycm9yKCJpdGVyYXRlTmV4dCBjYWxsZWQgd2l0aCB3cm9uZyByZXN1bHQgdHlwZSIpO3JldHVybiBmPj1jLmxlbmd0aD9udWxsOmNbZisrXX07dGhpcy5zbmFwc2hvdEl0ZW09ZnVuY3Rpb24oYSl7aWYoNiE9YiYmNyE9Yil0aHJvdyBFcnJvcigic25hcHNob3RJdGVtIGNhbGxlZCB3aXRoIHdyb25nIHJlc3VsdCB0eXBlIik7cmV0dXJuIGE+PWMubGVuZ3RofHwKMD5hP251bGw6Y1thXX19Wi5BTllfVFlQRT0wO1ouTlVNQkVSX1RZUEU9MTtaLlNUUklOR19UWVBFPTI7Wi5CT09MRUFOX1RZUEU9MztaLlVOT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEU9NDtaLk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFPTU7Wi5VTk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFPTY7Wi5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRT03O1ouQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEU9ODtaLkZJUlNUX09SREVSRURfTk9ERV9UWVBFPTk7ZnVuY3Rpb24gS2IoYSl7dGhpcy5sb29rdXBOYW1lc3BhY2VVUkk9SWEoYSl9CmZ1bmN0aW9uIExiKGEpe2E9YXx8aDt2YXIgYj1hLmRvY3VtZW50O2IuZXZhbHVhdGV8fChhLlhQYXRoUmVzdWx0PVosYi5ldmFsdWF0ZT1mdW5jdGlvbihhLGIsZSxmKXtyZXR1cm4obmV3IEpiKGEsZSkpLmV2YWx1YXRlKGIsZil9LGIuY3JlYXRlRXhwcmVzc2lvbj1mdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSmIoYSxiKX0sYi5jcmVhdGVOU1Jlc29sdmVyPWZ1bmN0aW9uKGEpe3JldHVybiBuZXcgS2IoYSl9KX12YXIgTWI9WyJ3Z3hwYXRoIiwiaW5zdGFsbCJdLCQ9aDtNYlswXWluICR8fCEkLmV4ZWNTY3JpcHR8fCQuZXhlY1NjcmlwdCgidmFyICIrTWJbMF0pO2Zvcih2YXIgTmI7TWIubGVuZ3RoJiYoTmI9TWIuc2hpZnQoKSk7KU1iLmxlbmd0aHx8dm9pZCAwPT09TGI/JFtOYl0/JD0kW05iXTokPSRbTmJdPXt9OiRbTmJdPUxiO30pKCkKCi8qKgogKiBAbGljZW5zZSB3eXNpaHRtbDUgdjAuNC4wcHJlCiAqIGh0dHBzOi8vZ2l0aHViLmNvbS94aW5nL3d5c2lodG1sNQogKgogKiBBdXRob3I6IENocmlzdG9waGVyIEJsdW0gKGh0dHBzOi8vZ2l0aHViLmNvbS90aWZmKQogKgogKiBDb3B5cmlnaHQgKEMpIDIwMTIgWElORyBBRwogKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgKE1JVCkKICoKICovCnZhciB3eXNpaHRtbDUgPSB7CiAgICB2ZXJzaW9uIDogIjAuNC4wcHJlIiwKCiAgICAvLyBuYW1lc3BhY2VzCiAgICBjb21tYW5kcyA6IHt9LAogICAgZG9tIDoge30sCiAgICBxdWlya3MgOiB7fSwKICAgIHRvb2xiYXIgOiB7fSwKICAgIGxhbmcgOiB7fSwKICAgIHNlbGVjdGlvbiA6IHt9LAogICAgdmlld3MgOiB7fSwKCiAgICBJTlZJU0lCTEVfU1BBQ0UgOiAiXHVGRUZGIiwKCiAgICBFTVBUWV9GVU5DVElPTiA6IGZ1bmN0aW9uICgpIHsKICAgIH0sCgogICAgRUxFTUVOVF9OT0RFIDogMSwKICAgIFRFWFRfTk9ERSA6IDMsCgogICAgQkFDS1NQQUNFX0tFWSA6IDgsCiAgICBFTlRFUl9LRVkgOiAxMywKICAgIEVTQ0FQRV9LRVkgOiAyNywKICAgIFNQQUNFX0tFWSA6IDMyLAogICAgREVMRVRFX0tFWSA6IDQ2LAogICAgVEFCX0tFWSA6IDksCiAgICBCTE9DS19FTEVNRU5UU19HUk9VUCA6IFsiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiLCAiUCJdCn07Ci8qKgogKiBAbGljZW5zZSBSYW5neSwgYSBjcm9zcy1icm93c2VyIEphdmFTY3JpcHQgcmFuZ2UgYW5kIHNlbGVjdGlvbiBsaWJyYXJ5CiAqIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9yYW5neS8KICoKICogQ29weXJpZ2h0IDIwMTEsIFRpbSBEb3duCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS4KICogVmVyc2lvbjogMS4yLjIKICogQnVpbGQgZGF0ZTogMTMgTm92ZW1iZXIgMjAxMQogKi8Kd2luZG93LnJhbmd5ID0gKGZ1bmN0aW9uICgpIHsKCiAgICB2YXIgT0JKRUNUID0gIm9iamVjdCIsIEZVTkNUSU9OID0gImZ1bmN0aW9uIiwgVU5ERUZJTkVEID0gInVuZGVmaW5lZCI7CgogICAgdmFyIGRvbVJhbmdlUHJvcGVydGllcyA9IFsic3RhcnRDb250YWluZXIiLCAic3RhcnRPZmZzZXQiLCAiZW5kQ29udGFpbmVyIiwgImVuZE9mZnNldCIsICJjb2xsYXBzZWQiLAogICAgICAgICJjb21tb25BbmNlc3RvckNvbnRhaW5lciIsICJTVEFSVF9UT19TVEFSVCIsICJTVEFSVF9UT19FTkQiLCAiRU5EX1RPX1NUQVJUIiwgIkVORF9UT19FTkQiXTsKCiAgICB2YXIgZG9tUmFuZ2VNZXRob2RzID0gWyJzZXRTdGFydCIsICJzZXRTdGFydEJlZm9yZSIsICJzZXRTdGFydEFmdGVyIiwgInNldEVuZCIsICJzZXRFbmRCZWZvcmUiLAogICAgICAgICJzZXRFbmRBZnRlciIsICJjb2xsYXBzZSIsICJzZWxlY3ROb2RlIiwgInNlbGVjdE5vZGVDb250ZW50cyIsICJjb21wYXJlQm91bmRhcnlQb2ludHMiLCAiZGVsZXRlQ29udGVudHMiLAogICAgICAgICJleHRyYWN0Q29udGVudHMiLCAiY2xvbmVDb250ZW50cyIsICJpbnNlcnROb2RlIiwgInN1cnJvdW5kQ29udGVudHMiLCAiY2xvbmVSYW5nZSIsICJ0b1N0cmluZyIsICJkZXRhY2giXTsKCiAgICB2YXIgdGV4dFJhbmdlUHJvcGVydGllcyA9IFsiYm91bmRpbmdIZWlnaHQiLCAiYm91bmRpbmdMZWZ0IiwgImJvdW5kaW5nVG9wIiwgImJvdW5kaW5nV2lkdGgiLCAiaHRtbFRleHQiLCAidGV4dCJdOwoKICAgIC8vIFN1YnNldCBvZiBUZXh0UmFuZ2UncyBmdWxsIHNldCBvZiBtZXRob2RzIHRoYXQgd2UncmUgaW50ZXJlc3RlZCBpbgogICAgdmFyIHRleHRSYW5nZU1ldGhvZHMgPSBbImNvbGxhcHNlIiwgImNvbXBhcmVFbmRQb2ludHMiLCAiZHVwbGljYXRlIiwgImdldEJvb2ttYXJrIiwgIm1vdmVUb0Jvb2ttYXJrIiwKICAgICAgICAibW92ZVRvRWxlbWVudFRleHQiLCAicGFyZW50RWxlbWVudCIsICJwYXN0ZUhUTUwiLCAic2VsZWN0IiwgInNldEVuZFBvaW50IiwgImdldEJvdW5kaW5nQ2xpZW50UmVjdCJdOwoKICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgogICAgLy8gVHJpbyBvZiBmdW5jdGlvbnMgdGFrZW4gZnJvbSBQZXRlciBNaWNoYXV4J3MgYXJ0aWNsZToKICAgIC8vIGh0dHA6Ly9wZXRlci5taWNoYXV4LmNhL2FydGljbGVzL2ZlYXR1cmUtZGV0ZWN0aW9uLXN0YXRlLW9mLXRoZS1hcnQtYnJvd3Nlci1zY3JpcHRpbmcKICAgIGZ1bmN0aW9uIGlzSG9zdE1ldGhvZChvLCBwKSB7CiAgICAgICAgdmFyIHQgPSB0eXBlb2Ygb1twXTsKICAgICAgICByZXR1cm4gdCA9PSBGVU5DVElPTiB8fCAoISEodCA9PSBPQkpFQ1QgJiYgb1twXSkpIHx8IHQgPT0gInVua25vd24iOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzSG9zdE9iamVjdChvLCBwKSB7CiAgICAgICAgcmV0dXJuICEhKHR5cGVvZiBvW3BdID09IE9CSkVDVCAmJiBvW3BdKTsKICAgIH0KCiAgICBmdW5jdGlvbiBpc0hvc3RQcm9wZXJ0eShvLCBwKSB7CiAgICAgICAgcmV0dXJuIHR5cGVvZiBvW3BdICE9IFVOREVGSU5FRDsKICAgIH0KCiAgICAvLyBDcmVhdGVzIGEgY29udmVuaWVuY2UgZnVuY3Rpb24gdG8gc2F2ZSB2ZXJib3NlIHJlcGVhdGVkIGNhbGxzIHRvIHRlc3RzIGZ1bmN0aW9ucwogICAgZnVuY3Rpb24gY3JlYXRlTXVsdGlwbGVQcm9wZXJ0eVRlc3QodGVzdEZ1bmMpIHsKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG8sIHByb3BzKSB7CiAgICAgICAgICAgIHZhciBpID0gcHJvcHMubGVuZ3RoOwogICAgICAgICAgICB3aGlsZSAoaS0tKSB7CiAgICAgICAgICAgICAgICBpZiAoIXRlc3RGdW5jKG8sIHByb3BzW2ldKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9OwogICAgfQoKICAgIC8vIE5leHQgdHJpbyBvZiBmdW5jdGlvbnMgYXJlIGEgY29udmVuaWVuY2UgdG8gc2F2ZSB2ZXJib3NlIHJlcGVhdGVkIGNhbGxzIHRvIHByZXZpb3VzIHR3byBmdW5jdGlvbnMKICAgIHZhciBhcmVIb3N0TWV0aG9kcyA9IGNyZWF0ZU11bHRpcGxlUHJvcGVydHlUZXN0KGlzSG9zdE1ldGhvZCk7CiAgICB2YXIgYXJlSG9zdE9iamVjdHMgPSBjcmVhdGVNdWx0aXBsZVByb3BlcnR5VGVzdChpc0hvc3RPYmplY3QpOwogICAgdmFyIGFyZUhvc3RQcm9wZXJ0aWVzID0gY3JlYXRlTXVsdGlwbGVQcm9wZXJ0eVRlc3QoaXNIb3N0UHJvcGVydHkpOwoKICAgIGZ1bmN0aW9uIGlzVGV4dFJhbmdlKHJhbmdlKSB7CiAgICAgICAgcmV0dXJuIHJhbmdlICYmIGFyZUhvc3RNZXRob2RzKHJhbmdlLCB0ZXh0UmFuZ2VNZXRob2RzKSAmJiBhcmVIb3N0UHJvcGVydGllcyhyYW5nZSwgdGV4dFJhbmdlUHJvcGVydGllcyk7CiAgICB9CgogICAgdmFyIGFwaSA9IHsKICAgICAgICB2ZXJzaW9uIDogIjEuMi4yIiwKICAgICAgICBpbml0aWFsaXplZCA6IGZhbHNlLAogICAgICAgIHN1cHBvcnRlZCA6IHRydWUsCgogICAgICAgIHV0aWwgOiB7CiAgICAgICAgICAgIGlzSG9zdE1ldGhvZCA6IGlzSG9zdE1ldGhvZCwKICAgICAgICAgICAgaXNIb3N0T2JqZWN0IDogaXNIb3N0T2JqZWN0LAogICAgICAgICAgICBpc0hvc3RQcm9wZXJ0eSA6IGlzSG9zdFByb3BlcnR5LAogICAgICAgICAgICBhcmVIb3N0TWV0aG9kcyA6IGFyZUhvc3RNZXRob2RzLAogICAgICAgICAgICBhcmVIb3N0T2JqZWN0cyA6IGFyZUhvc3RPYmplY3RzLAogICAgICAgICAgICBhcmVIb3N0UHJvcGVydGllcyA6IGFyZUhvc3RQcm9wZXJ0aWVzLAogICAgICAgICAgICBpc1RleHRSYW5nZSA6IGlzVGV4dFJhbmdlCiAgICAgICAgfSwKCiAgICAgICAgZmVhdHVyZXMgOiB7fSwKCiAgICAgICAgbW9kdWxlcyA6IHt9LAogICAgICAgIGNvbmZpZyA6IHsKICAgICAgICAgICAgYWxlcnRPbldhcm4gOiBmYWxzZSwKICAgICAgICAgICAgcHJlZmVyVGV4dFJhbmdlIDogZmFsc2UKICAgICAgICB9CiAgICB9OwoKICAgIGZ1bmN0aW9uIGZhaWwocmVhc29uKSB7CiAgICAgICAgd2luZG93LmFsZXJ0KCJSYW5neSBub3Qgc3VwcG9ydGVkIGluIHlvdXIgYnJvd3Nlci4gUmVhc29uOiAiICsgcmVhc29uKTsKICAgICAgICBhcGkuaW5pdGlhbGl6ZWQgPSB0cnVlOwogICAgICAgIGFwaS5zdXBwb3J0ZWQgPSBmYWxzZTsKICAgIH0KCiAgICBhcGkuZmFpbCA9IGZhaWw7CgogICAgZnVuY3Rpb24gd2Fybihtc2cpIHsKICAgICAgICB2YXIgd2FybmluZ01lc3NhZ2UgPSAiUmFuZ3kgd2FybmluZzogIiArIG1zZzsKICAgICAgICBpZiAoYXBpLmNvbmZpZy5hbGVydE9uV2FybikgewogICAgICAgICAgICB3aW5kb3cuYWxlcnQod2FybmluZ01lc3NhZ2UpOwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdy5jb25zb2xlICE9IFVOREVGSU5FRCAmJiB0eXBlb2Ygd2luZG93LmNvbnNvbGUubG9nICE9IFVOREVGSU5FRCkgewogICAgICAgICAgICB3aW5kb3cuY29uc29sZS5sb2cod2FybmluZ01lc3NhZ2UpOwogICAgICAgIH0KICAgIH0KCiAgICBhcGkud2FybiA9IHdhcm47CgogICAgaWYgKHt9Lmhhc093blByb3BlcnR5KSB7CiAgICAgICAgYXBpLnV0aWwuZXh0ZW5kID0gZnVuY3Rpb24gKG8sIHByb3BzKSB7CiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gcHJvcHMpIHsKICAgICAgICAgICAgICAgIGlmIChwcm9wcy5oYXNPd25Qcm9wZXJ0eShpKSkgewogICAgICAgICAgICAgICAgICAgIG9baV0gPSBwcm9wc1tpXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIGZhaWwoImhhc093blByb3BlcnR5IG5vdCBzdXBwb3J0ZWQiKTsKICAgIH0KCiAgICB2YXIgaW5pdExpc3RlbmVycyA9IFtdOwogICAgdmFyIG1vZHVsZUluaXRpYWxpemVycyA9IFtdOwoKICAgIC8vIEluaXRpYWxpemF0aW9uCiAgICBmdW5jdGlvbiBpbml0KCkgewogICAgICAgIGlmIChhcGkuaW5pdGlhbGl6ZWQpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICB2YXIgdGVzdFJhbmdlOwogICAgICAgIHZhciBpbXBsZW1lbnRzRG9tUmFuZ2UgPSBmYWxzZSwgaW1wbGVtZW50c1RleHRSYW5nZSA9IGZhbHNlOwoKICAgICAgICAvLyBGaXJzdCwgcGVyZm9ybSBiYXNpYyBmZWF0dXJlIHRlc3RzCgogICAgICAgIGlmIChpc0hvc3RNZXRob2QoZG9jdW1lbnQsICJjcmVhdGVSYW5nZSIpKSB7CiAgICAgICAgICAgIHRlc3RSYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgICAgIGlmIChhcmVIb3N0TWV0aG9kcyh0ZXN0UmFuZ2UsIGRvbVJhbmdlTWV0aG9kcykgJiYgYXJlSG9zdFByb3BlcnRpZXModGVzdFJhbmdlLCBkb21SYW5nZVByb3BlcnRpZXMpKSB7CiAgICAgICAgICAgICAgICBpbXBsZW1lbnRzRG9tUmFuZ2UgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRlc3RSYW5nZS5kZXRhY2goKTsKICAgICAgICB9CgogICAgICAgIHZhciBib2R5ID0gaXNIb3N0T2JqZWN0KGRvY3VtZW50LCAiYm9keSIpID8gZG9jdW1lbnQuYm9keSA6IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJib2R5IilbMF07CgogICAgICAgIC8qIEluIGNhc2UgY3JlYXRlUmFuZ2UgaXMgc3VwcG9ydGVkIHNraXBwaW5nIHZhbGlkYXRpb24gZm9yIGNyZWF0ZVRleHRSYW5nZSBBUEkKICAgICAgICAgKiBhcyBpdHMgbm90IHVzZWQgaW4gc3VjaCBzY2VuYXJpbyBhcyB3ZWxsIGFzIHJlZHVjZXMgcGVyZm9ybWFuY2UoQ1EtNDIyODE2NikgICovCiAgICAgICAgaWYgKCFpbXBsZW1lbnRzRG9tUmFuZ2UgJiYgYm9keSAmJiBpc0hvc3RNZXRob2QoYm9keSwgImNyZWF0ZVRleHRSYW5nZSIpKSB7CiAgICAgICAgICAgIHRlc3RSYW5nZSA9IGJvZHkuY3JlYXRlVGV4dFJhbmdlKCk7CiAgICAgICAgICAgIGlmIChpc1RleHRSYW5nZSh0ZXN0UmFuZ2UpKSB7CiAgICAgICAgICAgICAgICBpbXBsZW1lbnRzVGV4dFJhbmdlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFpbXBsZW1lbnRzRG9tUmFuZ2UgJiYgIWltcGxlbWVudHNUZXh0UmFuZ2UpIHsKICAgICAgICAgICAgZmFpbCgiTmVpdGhlciBSYW5nZSBub3IgVGV4dFJhbmdlIGFyZSBpbXBsZW1lbnRlZCIpOwogICAgICAgIH0KCiAgICAgICAgYXBpLmluaXRpYWxpemVkID0gdHJ1ZTsKICAgICAgICBhcGkuZmVhdHVyZXMgPSB7CiAgICAgICAgICAgIGltcGxlbWVudHNEb21SYW5nZSA6IGltcGxlbWVudHNEb21SYW5nZSwKICAgICAgICAgICAgaW1wbGVtZW50c1RleHRSYW5nZSA6IGltcGxlbWVudHNUZXh0UmFuZ2UKICAgICAgICB9OwoKICAgICAgICAvLyBJbml0aWFsaXplIG1vZHVsZXMgYW5kIGNhbGwgaW5pdCBsaXN0ZW5lcnMKICAgICAgICB2YXIgYWxsTGlzdGVuZXJzID0gbW9kdWxlSW5pdGlhbGl6ZXJzLmNvbmNhdChpbml0TGlzdGVuZXJzKTsKICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gYWxsTGlzdGVuZXJzLmxlbmd0aDsKICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGFsbExpc3RlbmVyc1tpXShhcGkpOwogICAgICAgICAgICB9IGNhdGNoIChleCkgewogICAgICAgICAgICAgICAgaWYgKGlzSG9zdE9iamVjdCh3aW5kb3csICJjb25zb2xlIikgJiYgaXNIb3N0TWV0aG9kKHdpbmRvdy5jb25zb2xlLCAibG9nIikpIHsKICAgICAgICAgICAgICAgICAgICB3aW5kb3cuY29uc29sZS5sb2coIkluaXQgbGlzdGVuZXIgdGhyZXcgYW4gZXhjZXB0aW9uLiBDb250aW51aW5nLiIsIGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvLyBBbGxvdyBleHRlcm5hbCBzY3JpcHRzIHRvIGluaXRpYWxpemUgdGhpcyBsaWJyYXJ5IGluIGNhc2UgaXQncyBsb2FkZWQgYWZ0ZXIgdGhlIGRvY3VtZW50IGhhcyBsb2FkZWQKICAgIGFwaS5pbml0ID0gaW5pdDsKCiAgICAvLyBFeGVjdXRlIGxpc3RlbmVyIGltbWVkaWF0ZWx5IGlmIGFscmVhZHkgaW5pdGlhbGl6ZWQKICAgIGFwaS5hZGRJbml0TGlzdGVuZXIgPSBmdW5jdGlvbiAobGlzdGVuZXIpIHsKICAgICAgICBpZiAoYXBpLmluaXRpYWxpemVkKSB7CiAgICAgICAgICAgIGxpc3RlbmVyKGFwaSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW5pdExpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTsKICAgICAgICB9CiAgICB9OwoKICAgIHZhciBjcmVhdGVNaXNzaW5nTmF0aXZlQXBpTGlzdGVuZXJzID0gW107CgogICAgYXBpLmFkZENyZWF0ZU1pc3NpbmdOYXRpdmVBcGlMaXN0ZW5lciA9IGZ1bmN0aW9uIChsaXN0ZW5lcikgewogICAgICAgIGNyZWF0ZU1pc3NpbmdOYXRpdmVBcGlMaXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7CiAgICB9OwoKICAgIGZ1bmN0aW9uIGNyZWF0ZU1pc3NpbmdOYXRpdmVBcGkod2luKSB7CiAgICAgICAgd2luID0gd2luIHx8IHdpbmRvdzsKICAgICAgICBpbml0KCk7CgogICAgICAgIC8vIE5vdGlmeSBsaXN0ZW5lcnMKICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gY3JlYXRlTWlzc2luZ05hdGl2ZUFwaUxpc3RlbmVycy5sZW5ndGg7CiAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgIGNyZWF0ZU1pc3NpbmdOYXRpdmVBcGlMaXN0ZW5lcnNbaV0od2luKTsKICAgICAgICB9CiAgICB9CgogICAgYXBpLmNyZWF0ZU1pc3NpbmdOYXRpdmVBcGkgPSBjcmVhdGVNaXNzaW5nTmF0aXZlQXBpOwoKICAgIC8qKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKi8KICAgIGZ1bmN0aW9uIE1vZHVsZShuYW1lKSB7CiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICB0aGlzLmluaXRpYWxpemVkID0gZmFsc2U7CiAgICAgICAgdGhpcy5zdXBwb3J0ZWQgPSBmYWxzZTsKICAgIH0KCiAgICBNb2R1bGUucHJvdG90eXBlLmZhaWwgPSBmdW5jdGlvbiAocmVhc29uKSB7CiAgICAgICAgdGhpcy5pbml0aWFsaXplZCA9IHRydWU7CiAgICAgICAgdGhpcy5zdXBwb3J0ZWQgPSBmYWxzZTsKCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJNb2R1bGUgJyIgKyB0aGlzLm5hbWUgKyAiJyBmYWlsZWQgdG8gbG9hZDogIiArIHJlYXNvbik7CiAgICB9OwoKICAgIE1vZHVsZS5wcm90b3R5cGUud2FybiA9IGZ1bmN0aW9uIChtc2cpIHsKICAgICAgICBhcGkud2FybigiTW9kdWxlICIgKyB0aGlzLm5hbWUgKyAiOiAiICsgbXNnKTsKICAgIH07CgogICAgTW9kdWxlLnByb3RvdHlwZS5jcmVhdGVFcnJvciA9IGZ1bmN0aW9uIChtc2cpIHsKICAgICAgICByZXR1cm4gbmV3IEVycm9yKCJFcnJvciBpbiBSYW5neSAiICsgdGhpcy5uYW1lICsgIiBtb2R1bGU6ICIgKyBtc2cpOwogICAgfTsKCiAgICBhcGkuY3JlYXRlTW9kdWxlID0gZnVuY3Rpb24gKG5hbWUsIGluaXRGdW5jKSB7CiAgICAgICAgdmFyIG1vZHVsZSA9IG5ldyBNb2R1bGUobmFtZSk7CiAgICAgICAgYXBpLm1vZHVsZXNbbmFtZV0gPSBtb2R1bGU7CgogICAgICAgIG1vZHVsZUluaXRpYWxpemVycy5wdXNoKGZ1bmN0aW9uIChhcGkpIHsKICAgICAgICAgICAgaW5pdEZ1bmMoYXBpLCBtb2R1bGUpOwogICAgICAgICAgICBtb2R1bGUuaW5pdGlhbGl6ZWQgPSB0cnVlOwogICAgICAgICAgICBtb2R1bGUuc3VwcG9ydGVkID0gdHJ1ZTsKICAgICAgICB9KTsKICAgIH07CgogICAgYXBpLnJlcXVpcmVNb2R1bGVzID0gZnVuY3Rpb24gKG1vZHVsZXMpIHsKICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gbW9kdWxlcy5sZW5ndGgsIG1vZHVsZSwgbW9kdWxlTmFtZTsKICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgbW9kdWxlTmFtZSA9IG1vZHVsZXNbaV07CiAgICAgICAgICAgIG1vZHVsZSA9IGFwaS5tb2R1bGVzW21vZHVsZU5hbWVdOwogICAgICAgICAgICBpZiAoIW1vZHVsZSB8fCAhKG1vZHVsZSBpbnN0YW5jZW9mIE1vZHVsZSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiTW9kdWxlICciICsgbW9kdWxlTmFtZSArICInIG5vdCBmb3VuZCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghbW9kdWxlLnN1cHBvcnRlZCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJNb2R1bGUgJyIgKyBtb2R1bGVOYW1lICsgIicgbm90IHN1cHBvcnRlZCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8vIFdhaXQgZm9yIGRvY3VtZW50IHRvIGxvYWQgYmVmb3JlIHJ1bm5pbmcgdGVzdHMKCiAgICB2YXIgZG9jUmVhZHkgPSBmYWxzZTsKCiAgICB2YXIgbG9hZEhhbmRsZXIgPSBmdW5jdGlvbiAoZSkgewoKICAgICAgICBpZiAoIWRvY1JlYWR5KSB7CiAgICAgICAgICAgIGRvY1JlYWR5ID0gdHJ1ZTsKICAgICAgICAgICAgaWYgKCFhcGkuaW5pdGlhbGl6ZWQpIHsKICAgICAgICAgICAgICAgIGluaXQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgLy8gVGVzdCB3aGV0aGVyIHdlIGhhdmUgd2luZG93IGFuZCBkb2N1bWVudCBvYmplY3RzIHRoYXQgd2Ugd2lsbCBuZWVkCiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PSBVTkRFRklORUQpIHsKICAgICAgICBmYWlsKCJObyB3aW5kb3cgZm91bmQiKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09IFVOREVGSU5FRCkgewogICAgICAgIGZhaWwoIk5vIGRvY3VtZW50IGZvdW5kIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChpc0hvc3RNZXRob2QoZG9jdW1lbnQsICJhZGRFdmVudExpc3RlbmVyIikpIHsKICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIiwgbG9hZEhhbmRsZXIsIGZhbHNlKTsKICAgIH0KCiAgICAvLyBBZGQgYSBmYWxsYmFjayBpbiBjYXNlIHRoZSBET01Db250ZW50TG9hZGVkIGV2ZW50IGlzbid0IHN1cHBvcnRlZAogICAgaWYgKGlzSG9zdE1ldGhvZCh3aW5kb3csICJhZGRFdmVudExpc3RlbmVyIikpIHsKICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigibG9hZCIsIGxvYWRIYW5kbGVyLCBmYWxzZSk7CiAgICB9IGVsc2UgaWYgKGlzSG9zdE1ldGhvZCh3aW5kb3csICJhdHRhY2hFdmVudCIpKSB7CiAgICAgICAgd2luZG93LmF0dGFjaEV2ZW50KCJvbmxvYWQiLCBsb2FkSGFuZGxlcik7CiAgICB9IGVsc2UgewogICAgICAgIGZhaWwoIldpbmRvdyBkb2VzIG5vdCBoYXZlIHJlcXVpcmVkIGFkZEV2ZW50TGlzdGVuZXIgb3IgYXR0YWNoRXZlbnQgbWV0aG9kIik7CiAgICB9CgogICAgcmV0dXJuIGFwaTsKfSkoKTsKcmFuZ3kuY3JlYXRlTW9kdWxlKCJEb21VdGlsIiwgZnVuY3Rpb24gKGFwaSwgbW9kdWxlKSB7CgogICAgdmFyIFVOREVGID0gInVuZGVmaW5lZCI7CiAgICB2YXIgdXRpbCA9IGFwaS51dGlsOwoKICAgIC8vIFBlcmZvcm0gZmVhdHVyZSB0ZXN0cwogICAgaWYgKCF1dGlsLmFyZUhvc3RNZXRob2RzKGRvY3VtZW50LCBbImNyZWF0ZURvY3VtZW50RnJhZ21lbnQiLCAiY3JlYXRlRWxlbWVudCIsICJjcmVhdGVUZXh0Tm9kZSJdKSkgewogICAgICAgIG1vZHVsZS5mYWlsKCJkb2N1bWVudCBtaXNzaW5nIGEgTm9kZSBjcmVhdGlvbiBtZXRob2QiKTsKICAgIH0KCiAgICBpZiAoIXV0aWwuaXNIb3N0TWV0aG9kKGRvY3VtZW50LCAiZ2V0RWxlbWVudHNCeVRhZ05hbWUiKSkgewogICAgICAgIG1vZHVsZS5mYWlsKCJkb2N1bWVudCBtaXNzaW5nIGdldEVsZW1lbnRzQnlUYWdOYW1lIG1ldGhvZCIpOwogICAgfQoKICAgIHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpOwogICAgaWYgKCF1dGlsLmFyZUhvc3RNZXRob2RzKGVsLCBbImluc2VydEJlZm9yZSIsICJhcHBlbmRDaGlsZCIsICJjbG9uZU5vZGUiXSB8fCAhdXRpbC5hcmVIb3N0T2JqZWN0cyhlbCwgWyJwcmV2aW91c1NpYmxpbmciLCAibmV4dFNpYmxpbmciLCAiY2hpbGROb2RlcyIsICJwYXJlbnROb2RlIl0pKSkgewogICAgICAgIG1vZHVsZS5mYWlsKCJJbmNvbXBsZXRlIEVsZW1lbnQgaW1wbGVtZW50YXRpb24iKTsKICAgIH0KCiAgICAvLyBpbm5lckhUTUwgaXMgcmVxdWlyZWQgZm9yIFJhbmdlJ3MgY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IG1ldGhvZAogICAgaWYgKCF1dGlsLmlzSG9zdFByb3BlcnR5KGVsLCAiaW5uZXJIVE1MIikpIHsKICAgICAgICBtb2R1bGUuZmFpbCgiRWxlbWVudCBpcyBtaXNzaW5nIGlubmVySFRNTCBwcm9wZXJ0eSIpOwogICAgfQoKICAgIHZhciB0ZXh0Tm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCJ0ZXN0Iik7CiAgICBpZiAoIXV0aWwuYXJlSG9zdE1ldGhvZHModGV4dE5vZGUsIFsic3BsaXRUZXh0IiwgImRlbGV0ZURhdGEiLCAiaW5zZXJ0RGF0YSIsICJhcHBlbmREYXRhIiwgImNsb25lTm9kZSJdIHx8ICF1dGlsLmFyZUhvc3RPYmplY3RzKGVsLCBbInByZXZpb3VzU2libGluZyIsICJuZXh0U2libGluZyIsICJjaGlsZE5vZGVzIiwgInBhcmVudE5vZGUiXSkgfHwgIXV0aWwuYXJlSG9zdFByb3BlcnRpZXModGV4dE5vZGUsIFsiZGF0YSJdKSkpIHsKICAgICAgICBtb2R1bGUuZmFpbCgiSW5jb21wbGV0ZSBUZXh0IE5vZGUgaW1wbGVtZW50YXRpb24iKTsKICAgIH0KCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8vIFJlbW92ZWQgdXNlIG9mIGluZGV4T2YgYmVjYXVzZSBvZiBhIGJpemFycmUgYnVnIGluIE9wZXJhIHRoYXQgaXMgdGhyb3duIGluIG9uZSBvZiB0aGUgQWNpZDMgdGVzdHMuIEkgaGF2ZW4ndCBiZWVuCiAgICAvLyBhYmxlIHRvIHJlcGxpY2F0ZSBpdCBvdXRzaWRlIG9mIHRoZSB0ZXN0LiBUaGUgYnVnIGlzIHRoYXQgaW5kZXhPZiByZXR1cm5zIC0xIHdoZW4gY2FsbGVkIG9uIGFuIEFycmF5IHRoYXQKICAgIC8vIGNvbnRhaW5zIGp1c3QgdGhlIGRvY3VtZW50IGFzIGEgc2luZ2xlIGVsZW1lbnQgYW5kIHRoZSB2YWx1ZSBzZWFyY2hlZCBmb3IgaXMgdGhlIGRvY3VtZW50LgogICAgdmFyIGFycmF5Q29udGFpbnMgPSAvKkFycmF5LnByb3RvdHlwZS5pbmRleE9mID8KICAgICBmdW5jdGlvbihhcnIsIHZhbCkgewogICAgIHJldHVybiBhcnIuaW5kZXhPZih2YWwpID4gLTE7CiAgICAgfToqLwoKICAgICAgICBmdW5jdGlvbiAoYXJyLCB2YWwpIHsKICAgICAgICAgICAgdmFyIGkgPSBhcnIubGVuZ3RoOwogICAgICAgICAgICB3aGlsZSAoaS0tKSB7CiAgICAgICAgICAgICAgICBpZiAoYXJyW2ldID09PSB2YWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfTsKCiAgICAvLyBPcGVyYSAxMSBwdXRzIEhUTUwgZWxlbWVudHMgaW4gdGhlIG51bGwgbmFtZXNwYWNlLCBpdCBzZWVtcywgYW5kIElFIDcgaGFzIHVuZGVmaW5lZCBuYW1lc3BhY2VVUkkKICAgIGZ1bmN0aW9uIGlzSHRtbE5hbWVzcGFjZShub2RlKSB7CiAgICAgICAgdmFyIG5zOwogICAgICAgIHJldHVybiB0eXBlb2Ygbm9kZS5uYW1lc3BhY2VVUkkgPT0gVU5ERUYgfHwgKChucyA9IG5vZGUubmFtZXNwYWNlVVJJKSA9PT0gbnVsbCB8fCBucyA9PSAiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIpOwogICAgfQoKICAgIGZ1bmN0aW9uIHBhcmVudEVsZW1lbnQobm9kZSkgewogICAgICAgIHZhciBwYXJlbnQgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgcmV0dXJuIChwYXJlbnQubm9kZVR5cGUgPT0gMSkgPyBwYXJlbnQgOiBudWxsOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldE5vZGVJbmRleChub2RlKSB7CiAgICAgICAgdmFyIGkgPSAwOwogICAgICAgIHdoaWxlICgobm9kZSA9IG5vZGUucHJldmlvdXNTaWJsaW5nKSkgewogICAgICAgICAgICBpKys7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldE5vZGVMZW5ndGgobm9kZSkgewogICAgICAgIHZhciBjaGlsZE5vZGVzOwogICAgICAgIHJldHVybiBpc0NoYXJhY3RlckRhdGFOb2RlKG5vZGUpID8gbm9kZS5sZW5ndGggOiAoKGNoaWxkTm9kZXMgPSBub2RlLmNoaWxkTm9kZXMpID8gY2hpbGROb2Rlcy5sZW5ndGggOiAwKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRDb21tb25BbmNlc3Rvcihub2RlMSwgbm9kZTIpIHsKICAgICAgICB2YXIgYW5jZXN0b3JzID0gW10sIG47CiAgICAgICAgZm9yIChuID0gbm9kZTE7CiAgICAgICAgICAgICBuOwogICAgICAgICAgICAgbiA9IG4ucGFyZW50Tm9kZSkgewogICAgICAgICAgICBhbmNlc3RvcnMucHVzaChuKTsKICAgICAgICB9CgogICAgICAgIGZvciAobiA9IG5vZGUyOwogICAgICAgICAgICAgbjsKICAgICAgICAgICAgIG4gPSBuLnBhcmVudE5vZGUpIHsKICAgICAgICAgICAgaWYgKGFycmF5Q29udGFpbnMoYW5jZXN0b3JzLCBuKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzQW5jZXN0b3JPZihhbmNlc3RvciwgZGVzY2VuZGFudCwgc2VsZklzQW5jZXN0b3IpIHsKICAgICAgICB2YXIgbiA9IHNlbGZJc0FuY2VzdG9yID8gZGVzY2VuZGFudCA6IGRlc2NlbmRhbnQucGFyZW50Tm9kZTsKICAgICAgICB3aGlsZSAobikgewogICAgICAgICAgICBpZiAobiA9PT0gYW5jZXN0b3IpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbiA9IG4ucGFyZW50Tm9kZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0Q2xvc2VzdEFuY2VzdG9ySW4obm9kZSwgYW5jZXN0b3IsIHNlbGZJc0FuY2VzdG9yKSB7CiAgICAgICAgdmFyIHAsIG4gPSBzZWxmSXNBbmNlc3RvciA/IG5vZGUgOiBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgd2hpbGUgKG4pIHsKICAgICAgICAgICAgcCA9IG4ucGFyZW50Tm9kZTsKICAgICAgICAgICAgaWYgKHAgPT09IGFuY2VzdG9yKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbjsKICAgICAgICAgICAgfQogICAgICAgICAgICBuID0gcDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgZnVuY3Rpb24gaXNDaGFyYWN0ZXJEYXRhTm9kZShub2RlKSB7CiAgICAgICAgdmFyIHQgPSBub2RlLm5vZGVUeXBlOwogICAgICAgIHJldHVybiB0ID09IDMgfHwgdCA9PSA0IHx8IHQgPT0gODsgLy8gVGV4dCwgQ0RhdGFTZWN0aW9uIG9yIENvbW1lbnQKICAgIH0KCiAgICBmdW5jdGlvbiBpbnNlcnRBZnRlcihub2RlLCBwcmVjZWRpbmdOb2RlKSB7CiAgICAgICAgdmFyIG5leHROb2RlID0gcHJlY2VkaW5nTm9kZS5uZXh0U2libGluZywgcGFyZW50ID0gcHJlY2VkaW5nTm9kZS5wYXJlbnROb2RlOwogICAgICAgIGlmIChuZXh0Tm9kZSkgewogICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKG5vZGUsIG5leHROb2RlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwYXJlbnQuYXBwZW5kQ2hpbGQobm9kZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBub2RlOwogICAgfQoKICAgIC8vIE5vdGUgdGhhdCB3ZSBjYW5ub3QgdXNlIHNwbGl0VGV4dCgpIGJlY2F1c2UgaXQgaXMgYnVncmlkZGVuIGluIElFIDkuCiAgICBmdW5jdGlvbiBzcGxpdERhdGFOb2RlKG5vZGUsIGluZGV4KSB7CiAgICAgICAgdmFyIG5ld05vZGUgPSBub2RlLmNsb25lTm9kZShmYWxzZSk7CiAgICAgICAgbmV3Tm9kZS5kZWxldGVEYXRhKDAsIGluZGV4KTsKICAgICAgICBub2RlLmRlbGV0ZURhdGEoaW5kZXgsIG5vZGUubGVuZ3RoIC0gaW5kZXgpOwogICAgICAgIGluc2VydEFmdGVyKG5ld05vZGUsIG5vZGUpOwogICAgICAgIHJldHVybiBuZXdOb2RlOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldERvY3VtZW50KG5vZGUpIHsKICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSA5KSB7CiAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG5vZGUub3duZXJEb2N1bWVudCAhPSBVTkRFRikgewogICAgICAgICAgICByZXR1cm4gbm9kZS5vd25lckRvY3VtZW50OwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG5vZGUuZG9jdW1lbnQgIT0gVU5ERUYpIHsKICAgICAgICAgICAgcmV0dXJuIG5vZGUuZG9jdW1lbnQ7CiAgICAgICAgfSBlbHNlIGlmIChub2RlLnBhcmVudE5vZGUpIHsKICAgICAgICAgICAgcmV0dXJuIGdldERvY3VtZW50KG5vZGUucGFyZW50Tm9kZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJnZXREb2N1bWVudDogbm8gZG9jdW1lbnQgZm91bmQgZm9yIG5vZGUiKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0V2luZG93KG5vZGUpIHsKICAgICAgICB2YXIgZG9jID0gZ2V0RG9jdW1lbnQobm9kZSk7CiAgICAgICAgaWYgKHR5cGVvZiBkb2MuZGVmYXVsdFZpZXcgIT0gVU5ERUYpIHsKICAgICAgICAgICAgcmV0dXJuIGRvYy5kZWZhdWx0VmlldzsKICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkb2MucGFyZW50V2luZG93ICE9IFVOREVGKSB7CiAgICAgICAgICAgIHJldHVybiBkb2MucGFyZW50V2luZG93OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiQ2Fubm90IGdldCBhIHdpbmRvdyBvYmplY3QgZm9yIG5vZGUiKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0SWZyYW1lRG9jdW1lbnQoaWZyYW1lRWwpIHsKICAgICAgICBpZiAodHlwZW9mIGlmcmFtZUVsLmNvbnRlbnREb2N1bWVudCAhPSBVTkRFRikgewogICAgICAgICAgICByZXR1cm4gaWZyYW1lRWwuY29udGVudERvY3VtZW50OwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGlmcmFtZUVsLmNvbnRlbnRXaW5kb3cgIT0gVU5ERUYpIHsKICAgICAgICAgICAgcmV0dXJuIGlmcmFtZUVsLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJnZXRJZnJhbWVXaW5kb3c6IE5vIERvY3VtZW50IG9iamVjdCBmb3VuZCBmb3IgaWZyYW1lIGVsZW1lbnQiKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0SWZyYW1lV2luZG93KGlmcmFtZUVsKSB7CiAgICAgICAgaWYgKHR5cGVvZiBpZnJhbWVFbC5jb250ZW50V2luZG93ICE9IFVOREVGKSB7CiAgICAgICAgICAgIHJldHVybiBpZnJhbWVFbC5jb250ZW50V2luZG93OwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGlmcmFtZUVsLmNvbnRlbnREb2N1bWVudCAhPSBVTkRFRikgewogICAgICAgICAgICByZXR1cm4gaWZyYW1lRWwuY29udGVudERvY3VtZW50LmRlZmF1bHRWaWV3OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiZ2V0SWZyYW1lV2luZG93OiBObyBXaW5kb3cgb2JqZWN0IGZvdW5kIGZvciBpZnJhbWUgZWxlbWVudCIpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBnZXRCb2R5KGRvYykgewogICAgICAgIHJldHVybiB1dGlsLmlzSG9zdE9iamVjdChkb2MsICJib2R5IikgPyBkb2MuYm9keSA6IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYm9keSIpWzBdOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldFJvb3RDb250YWluZXIobm9kZSkgewogICAgICAgIHZhciBwYXJlbnQ7CiAgICAgICAgd2hpbGUgKChwYXJlbnQgPSBub2RlLnBhcmVudE5vZGUpKSB7CiAgICAgICAgICAgIG5vZGUgPSBwYXJlbnQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBub2RlOwogICAgfQoKICAgIGZ1bmN0aW9uIGNvbXBhcmVQb2ludHMobm9kZUEsIG9mZnNldEEsIG5vZGVCLCBvZmZzZXRCKSB7CiAgICAgICAgLy8gU2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLVRyYXZlcnNhbC1SYW5nZS9yYW5nZXMuaHRtbCNMZXZlbC0yLVJhbmdlLUNvbXBhcmluZwogICAgICAgIHZhciBub2RlQywgcm9vdCwgY2hpbGRBLCBjaGlsZEIsIG47CiAgICAgICAgaWYgKG5vZGVBID09IG5vZGVCKSB7CgogICAgICAgICAgICAvLyBDYXNlIDE6IG5vZGVzIGFyZSB0aGUgc2FtZQogICAgICAgICAgICByZXR1cm4gb2Zmc2V0QSA9PT0gb2Zmc2V0QiA/IDAgOiAob2Zmc2V0QSA8IG9mZnNldEIpID8gLTEgOiAxOwogICAgICAgIH0gZWxzZSBpZiAoKG5vZGVDID0gZ2V0Q2xvc2VzdEFuY2VzdG9ySW4obm9kZUIsIG5vZGVBLCB0cnVlKSkpIHsKCiAgICAgICAgICAgIC8vIENhc2UgMjogbm9kZSBDIChjb250YWluZXIgQiBvciBhbiBhbmNlc3RvcikgaXMgYSBjaGlsZCBub2RlIG9mIEEKICAgICAgICAgICAgcmV0dXJuIG9mZnNldEEgPD0gZ2V0Tm9kZUluZGV4KG5vZGVDKSA/IC0xIDogMTsKICAgICAgICB9IGVsc2UgaWYgKChub2RlQyA9IGdldENsb3Nlc3RBbmNlc3RvckluKG5vZGVBLCBub2RlQiwgdHJ1ZSkpKSB7CgogICAgICAgICAgICAvLyBDYXNlIDM6IG5vZGUgQyAoY29udGFpbmVyIEEgb3IgYW4gYW5jZXN0b3IpIGlzIGEgY2hpbGQgbm9kZSBvZiBCCiAgICAgICAgICAgIHJldHVybiBnZXROb2RlSW5kZXgobm9kZUMpIDwgb2Zmc2V0QiA/IC0xIDogMTsKICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgLy8gQ2FzZSA0OiBjb250YWluZXJzIGFyZSBzaWJsaW5ncyBvciBkZXNjZW5kYW50cyBvZiBzaWJsaW5ncwogICAgICAgICAgICByb290ID0gZ2V0Q29tbW9uQW5jZXN0b3Iobm9kZUEsIG5vZGVCKTsKICAgICAgICAgICAgY2hpbGRBID0gKG5vZGVBID09PSByb290KSA/IHJvb3QgOiBnZXRDbG9zZXN0QW5jZXN0b3JJbihub2RlQSwgcm9vdCwgdHJ1ZSk7CiAgICAgICAgICAgIGNoaWxkQiA9IChub2RlQiA9PT0gcm9vdCkgPyByb290IDogZ2V0Q2xvc2VzdEFuY2VzdG9ySW4obm9kZUIsIHJvb3QsIHRydWUpOwoKICAgICAgICAgICAgaWYgKGNoaWxkQSA9PT0gY2hpbGRCKSB7CiAgICAgICAgICAgICAgICAvLyBUaGlzIHNob3VsZG4ndCBiZSBwb3NzaWJsZQoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiY29tcGFyZVBvaW50cyBnb3QgdG8gY2FzZSA0IGFuZCBjaGlsZEEgYW5kIGNoaWxkQiBhcmUgdGhlIHNhbWUhIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBuID0gcm9vdC5maXJzdENoaWxkOwogICAgICAgICAgICAgICAgd2hpbGUgKG4pIHsKICAgICAgICAgICAgICAgICAgICBpZiAobiA9PT0gY2hpbGRBKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG4gPT09IGNoaWxkQikgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbiA9IG4ubmV4dFNpYmxpbmc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlNob3VsZCBub3QgYmUgaGVyZSEiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBmcmFnbWVudEZyb21Ob2RlQ2hpbGRyZW4obm9kZSkgewogICAgICAgIHZhciBmcmFnbWVudCA9IGdldERvY3VtZW50KG5vZGUpLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSwgY2hpbGQ7CiAgICAgICAgd2hpbGUgKChjaGlsZCA9IG5vZGUuZmlyc3RDaGlsZCkpIHsKICAgICAgICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoY2hpbGQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZnJhZ21lbnQ7CiAgICB9CgogICAgZnVuY3Rpb24gaW5zcGVjdE5vZGUobm9kZSkgewogICAgICAgIGlmICghbm9kZSkgewogICAgICAgICAgICByZXR1cm4gIltObyBub2RlXSI7CiAgICAgICAgfQogICAgICAgIGlmIChpc0NoYXJhY3RlckRhdGFOb2RlKG5vZGUpKSB7CiAgICAgICAgICAgIHJldHVybiAnIicgKyBub2RlLmRhdGEgKyAnIic7CiAgICAgICAgfSBlbHNlIGlmIChub2RlLm5vZGVUeXBlID09IDEpIHsKICAgICAgICAgICAgdmFyIGlkQXR0ciA9IG5vZGUuaWQgPyAnIGlkPSInICsgbm9kZS5pZCArICciJyA6ICIiOwogICAgICAgICAgICByZXR1cm4gIjwiICsgbm9kZS5ub2RlTmFtZSArIGlkQXR0ciArICI+WyIgKyBub2RlLmNoaWxkTm9kZXMubGVuZ3RoICsgIl0iOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBub2RlLm5vZGVOYW1lOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEBjb25zdHJ1Y3RvcgogICAgICovCiAgICBmdW5jdGlvbiBOb2RlSXRlcmF0b3Iocm9vdCkgewogICAgICAgIHRoaXMucm9vdCA9IHJvb3Q7CiAgICAgICAgdGhpcy5fbmV4dCA9IHJvb3Q7CiAgICB9CgogICAgTm9kZUl0ZXJhdG9yLnByb3RvdHlwZSA9IHsKICAgICAgICBfY3VycmVudCA6IG51bGwsCgogICAgICAgIGhhc05leHQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMuX25leHQ7CiAgICAgICAgfSwKCiAgICAgICAgbmV4dCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIG4gPSB0aGlzLl9jdXJyZW50ID0gdGhpcy5fbmV4dDsKICAgICAgICAgICAgdmFyIGNoaWxkLCBuZXh0OwogICAgICAgICAgICBpZiAodGhpcy5fY3VycmVudCkgewogICAgICAgICAgICAgICAgY2hpbGQgPSBuLmZpcnN0Q2hpbGQ7CiAgICAgICAgICAgICAgICBpZiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9uZXh0ID0gY2hpbGQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIG5leHQgPSBudWxsOwogICAgICAgICAgICAgICAgICAgIHdoaWxlICgobiAhPT0gdGhpcy5yb290KSAmJiAhKG5leHQgPSBuLm5leHRTaWJsaW5nKSkgewogICAgICAgICAgICAgICAgICAgICAgICBuID0gbi5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aGlzLl9uZXh0ID0gbmV4dDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdGhpcy5fY3VycmVudDsKICAgICAgICB9LAoKICAgICAgICBkZXRhY2ggOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnQgPSB0aGlzLl9uZXh0ID0gdGhpcy5yb290ID0gbnVsbDsKICAgICAgICB9CiAgICB9OwoKICAgIGZ1bmN0aW9uIGNyZWF0ZUl0ZXJhdG9yKHJvb3QpIHsKICAgICAgICByZXR1cm4gbmV3IE5vZGVJdGVyYXRvcihyb290KTsKICAgIH0KCiAgICAvKioKICAgICAqIEBjb25zdHJ1Y3RvcgogICAgICovCiAgICBmdW5jdGlvbiBEb21Qb3NpdGlvbihub2RlLCBvZmZzZXQpIHsKICAgICAgICB0aGlzLm5vZGUgPSBub2RlOwogICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0OwogICAgfQoKICAgIERvbVBvc2l0aW9uLnByb3RvdHlwZSA9IHsKICAgICAgICBlcXVhbHMgOiBmdW5jdGlvbiAocG9zKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLm5vZGUgPT09IHBvcy5ub2RlICYgdGhpcy5vZmZzZXQgPT0gcG9zLm9mZnNldDsKICAgICAgICB9LAoKICAgICAgICBpbnNwZWN0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gIltEb21Qb3NpdGlvbigiICsgaW5zcGVjdE5vZGUodGhpcy5ub2RlKSArICI6IiArIHRoaXMub2Zmc2V0ICsgIildIjsKICAgICAgICB9CiAgICB9OwoKICAgIC8qKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKi8KICAgIGZ1bmN0aW9uIERPTUV4Y2VwdGlvbihjb2RlTmFtZSkgewogICAgICAgIHRoaXMuY29kZSA9IHRoaXNbY29kZU5hbWVdOwogICAgICAgIHRoaXMuY29kZU5hbWUgPSBjb2RlTmFtZTsKICAgICAgICB0aGlzLm1lc3NhZ2UgPSAiRE9NRXhjZXB0aW9uOiAiICsgdGhpcy5jb2RlTmFtZTsKICAgIH0KCiAgICBET01FeGNlcHRpb24ucHJvdG90eXBlID0gewogICAgICAgIElOREVYX1NJWkVfRVJSIDogMSwKICAgICAgICBISUVSQVJDSFlfUkVRVUVTVF9FUlIgOiAzLAogICAgICAgIFdST05HX0RPQ1VNRU5UX0VSUiA6IDQsCiAgICAgICAgTk9fTU9ESUZJQ0FUSU9OX0FMTE9XRURfRVJSIDogNywKICAgICAgICBOT1RfRk9VTkRfRVJSIDogOCwKICAgICAgICBOT1RfU1VQUE9SVEVEX0VSUiA6IDksCiAgICAgICAgSU5WQUxJRF9TVEFURV9FUlIgOiAxMQogICAgfTsKCiAgICBET01FeGNlcHRpb24ucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiB0aGlzLm1lc3NhZ2U7CiAgICB9OwoKICAgIGFwaS5kb20gPSB7CiAgICAgICAgYXJyYXlDb250YWlucyA6IGFycmF5Q29udGFpbnMsCiAgICAgICAgaXNIdG1sTmFtZXNwYWNlIDogaXNIdG1sTmFtZXNwYWNlLAogICAgICAgIHBhcmVudEVsZW1lbnQgOiBwYXJlbnRFbGVtZW50LAogICAgICAgIGdldE5vZGVJbmRleCA6IGdldE5vZGVJbmRleCwKICAgICAgICBnZXROb2RlTGVuZ3RoIDogZ2V0Tm9kZUxlbmd0aCwKICAgICAgICBnZXRDb21tb25BbmNlc3RvciA6IGdldENvbW1vbkFuY2VzdG9yLAogICAgICAgIGlzQW5jZXN0b3JPZiA6IGlzQW5jZXN0b3JPZiwKICAgICAgICBnZXRDbG9zZXN0QW5jZXN0b3JJbiA6IGdldENsb3Nlc3RBbmNlc3RvckluLAogICAgICAgIGlzQ2hhcmFjdGVyRGF0YU5vZGUgOiBpc0NoYXJhY3RlckRhdGFOb2RlLAogICAgICAgIGluc2VydEFmdGVyIDogaW5zZXJ0QWZ0ZXIsCiAgICAgICAgc3BsaXREYXRhTm9kZSA6IHNwbGl0RGF0YU5vZGUsCiAgICAgICAgZ2V0RG9jdW1lbnQgOiBnZXREb2N1bWVudCwKICAgICAgICBnZXRXaW5kb3cgOiBnZXRXaW5kb3csCiAgICAgICAgZ2V0SWZyYW1lV2luZG93IDogZ2V0SWZyYW1lV2luZG93LAogICAgICAgIGdldElmcmFtZURvY3VtZW50IDogZ2V0SWZyYW1lRG9jdW1lbnQsCiAgICAgICAgZ2V0Qm9keSA6IGdldEJvZHksCiAgICAgICAgZ2V0Um9vdENvbnRhaW5lciA6IGdldFJvb3RDb250YWluZXIsCiAgICAgICAgY29tcGFyZVBvaW50cyA6IGNvbXBhcmVQb2ludHMsCiAgICAgICAgaW5zcGVjdE5vZGUgOiBpbnNwZWN0Tm9kZSwKICAgICAgICBmcmFnbWVudEZyb21Ob2RlQ2hpbGRyZW4gOiBmcmFnbWVudEZyb21Ob2RlQ2hpbGRyZW4sCiAgICAgICAgY3JlYXRlSXRlcmF0b3IgOiBjcmVhdGVJdGVyYXRvciwKICAgICAgICBEb21Qb3NpdGlvbiA6IERvbVBvc2l0aW9uCiAgICB9OwoKICAgIGFwaS5ET01FeGNlcHRpb24gPSBET01FeGNlcHRpb247Cn0pOwpyYW5neS5jcmVhdGVNb2R1bGUoIkRvbVJhbmdlIiwgZnVuY3Rpb24gKGFwaSwgbW9kdWxlKSB7CiAgICBhcGkucmVxdWlyZU1vZHVsZXMoWyJEb21VdGlsIl0pOwoKICAgIHZhciBkb20gPSBhcGkuZG9tOwogICAgdmFyIERvbVBvc2l0aW9uID0gZG9tLkRvbVBvc2l0aW9uOwogICAgdmFyIERPTUV4Y2VwdGlvbiA9IGFwaS5ET01FeGNlcHRpb247CgogICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCiAgICAvLyBVdGlsaXR5IGZ1bmN0aW9ucwoKICAgIGZ1bmN0aW9uIGlzTm9uVGV4dFBhcnRpYWxseVNlbGVjdGVkKG5vZGUsIHJhbmdlKSB7CiAgICAgICAgcmV0dXJuIChub2RlLm5vZGVUeXBlICE9IDMpICYmIChkb20uaXNBbmNlc3Rvck9mKG5vZGUsIHJhbmdlLnN0YXJ0Q29udGFpbmVyLCB0cnVlKSB8fCBkb20uaXNBbmNlc3Rvck9mKG5vZGUsIHJhbmdlLmVuZENvbnRhaW5lciwgdHJ1ZSkpOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldFJhbmdlRG9jdW1lbnQocmFuZ2UpIHsKICAgICAgICByZXR1cm4gZG9tLmdldERvY3VtZW50KHJhbmdlLnN0YXJ0Q29udGFpbmVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBkaXNwYXRjaEV2ZW50KHJhbmdlLCB0eXBlLCBhcmdzKSB7CiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHJhbmdlLl9saXN0ZW5lcnNbdHlwZV07CiAgICAgICAgaWYgKGxpc3RlbmVycykgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsKICAgICAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgICAgICsraSkgewogICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmNhbGwocmFuZ2UsIHt0YXJnZXQgOiByYW5nZSwgYXJncyA6IGFyZ3N9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBnZXRCb3VuZGFyeUJlZm9yZU5vZGUobm9kZSkgewogICAgICAgIHJldHVybiBuZXcgRG9tUG9zaXRpb24obm9kZS5wYXJlbnROb2RlLCBkb20uZ2V0Tm9kZUluZGV4KG5vZGUpKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXRCb3VuZGFyeUFmdGVyTm9kZShub2RlKSB7CiAgICAgICAgcmV0dXJuIG5ldyBEb21Qb3NpdGlvbihub2RlLnBhcmVudE5vZGUsIGRvbS5nZXROb2RlSW5kZXgobm9kZSkgKyAxKTsKICAgIH0KCiAgICBmdW5jdGlvbiBpbnNlcnROb2RlQXRQb3NpdGlvbihub2RlLCBuLCBvKSB7CiAgICAgICAgdmFyIGZpcnN0Tm9kZUluc2VydGVkID0gbm9kZS5ub2RlVHlwZSA9PSAxMSA/IG5vZGUuZmlyc3RDaGlsZCA6IG5vZGU7CiAgICAgICAgaWYgKGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKG4pKSB7CiAgICAgICAgICAgIGlmIChvID09IG4ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBkb20uaW5zZXJ0QWZ0ZXIobm9kZSwgbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBuLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5vZGUsIG8gPT0gMCA/IG4gOiBkb20uc3BsaXREYXRhTm9kZShuLCBvKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKG8gPj0gbi5jaGlsZE5vZGVzLmxlbmd0aCkgewogICAgICAgICAgICBuLmFwcGVuZENoaWxkKG5vZGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG4uaW5zZXJ0QmVmb3JlKG5vZGUsIG4uY2hpbGROb2Rlc1tvXSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaXJzdE5vZGVJbnNlcnRlZDsKICAgIH0KCiAgICBmdW5jdGlvbiBjbG9uZVN1YnRyZWUoaXRlcmF0b3IpIHsKICAgICAgICB2YXIgcGFydGlhbGx5U2VsZWN0ZWQ7CiAgICAgICAgZm9yICh2YXIgbm9kZSwgZnJhZyA9IGdldFJhbmdlRG9jdW1lbnQoaXRlcmF0b3IucmFuZ2UpLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSwgc3ViSXRlcmF0b3I7CiAgICAgICAgICAgICBub2RlID0gaXRlcmF0b3IubmV4dCgpOykgewogICAgICAgICAgICBwYXJ0aWFsbHlTZWxlY3RlZCA9IGl0ZXJhdG9yLmlzUGFydGlhbGx5U2VsZWN0ZWRTdWJ0cmVlKCk7CgogICAgICAgICAgICBub2RlID0gbm9kZS5jbG9uZU5vZGUoIXBhcnRpYWxseVNlbGVjdGVkKTsKICAgICAgICAgICAgaWYgKHBhcnRpYWxseVNlbGVjdGVkKSB7CiAgICAgICAgICAgICAgICBzdWJJdGVyYXRvciA9IGl0ZXJhdG9yLmdldFN1YnRyZWVJdGVyYXRvcigpOwogICAgICAgICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChjbG9uZVN1YnRyZWUoc3ViSXRlcmF0b3IpKTsKICAgICAgICAgICAgICAgIHN1Ykl0ZXJhdG9yLmRldGFjaCh0cnVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMTApIHsvLyBEb2N1bWVudFR5cGUKICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIkhJRVJBUkNIWV9SRVFVRVNUX0VSUiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZyYWcuYXBwZW5kQ2hpbGQobm9kZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmcmFnOwogICAgfQoKICAgIGZ1bmN0aW9uIGl0ZXJhdGVTdWJ0cmVlKHJhbmdlSXRlcmF0b3IsIGZ1bmMsIGl0ZXJhdG9yU3RhdGUpIHsKICAgICAgICB2YXIgaXQsIG47CiAgICAgICAgaXRlcmF0b3JTdGF0ZSA9IGl0ZXJhdG9yU3RhdGUgfHwge3N0b3AgOiBmYWxzZX07CiAgICAgICAgZm9yICh2YXIgbm9kZSwgc3ViUmFuZ2VJdGVyYXRvcjsKICAgICAgICAgICAgIG5vZGUgPSByYW5nZUl0ZXJhdG9yLm5leHQoKTspIHsKICAgICAgICAgICAgLy9sb2cuZGVidWcoIml0ZXJhdGVTdWJ0cmVlLCBwYXJ0aWFsbHkgc2VsZWN0ZWQ6ICIgKyByYW5nZUl0ZXJhdG9yLmlzUGFydGlhbGx5U2VsZWN0ZWRTdWJ0cmVlKCksIG5vZGVUb1N0cmluZyhub2RlKSk7CiAgICAgICAgICAgIGlmIChyYW5nZUl0ZXJhdG9yLmlzUGFydGlhbGx5U2VsZWN0ZWRTdWJ0cmVlKCkpIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBub2RlIGlzIHBhcnRpYWxseSBzZWxlY3RlZCBieSB0aGUgUmFuZ2UsIHNvIHdlIGNhbiB1c2UgYSBuZXcgUmFuZ2VJdGVyYXRvciBvbiB0aGUgcG9ydGlvbiBvZiB0aGUKICAgICAgICAgICAgICAgIC8vIG5vZGUgc2VsZWN0ZWQgYnkgdGhlIFJhbmdlLgogICAgICAgICAgICAgICAgaWYgKGZ1bmMobm9kZSkgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgaXRlcmF0b3JTdGF0ZS5zdG9wID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHN1YlJhbmdlSXRlcmF0b3IgPSByYW5nZUl0ZXJhdG9yLmdldFN1YnRyZWVJdGVyYXRvcigpOwogICAgICAgICAgICAgICAgICAgIGl0ZXJhdGVTdWJ0cmVlKHN1YlJhbmdlSXRlcmF0b3IsIGZ1bmMsIGl0ZXJhdG9yU3RhdGUpOwogICAgICAgICAgICAgICAgICAgIHN1YlJhbmdlSXRlcmF0b3IuZGV0YWNoKHRydWUpOwogICAgICAgICAgICAgICAgICAgIGlmIChpdGVyYXRvclN0YXRlLnN0b3ApIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIFRoZSB3aG9sZSBub2RlIGlzIHNlbGVjdGVkLCBzbyB3ZSBjYW4gdXNlIGVmZmljaWVudCBET00gaXRlcmF0aW9uIHRvIGl0ZXJhdGUgb3ZlciB0aGUgbm9kZSBhbmQgaXRzCiAgICAgICAgICAgICAgICAvLyBkZXNjZW5kYW50CiAgICAgICAgICAgICAgICBpdCA9IGRvbS5jcmVhdGVJdGVyYXRvcihub2RlKTsKICAgICAgICAgICAgICAgIHdoaWxlICgobiA9IGl0Lm5leHQoKSkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZnVuYyhuKSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXRlcmF0b3JTdGF0ZS5zdG9wID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBkZWxldGVTdWJ0cmVlKGl0ZXJhdG9yKSB7CiAgICAgICAgdmFyIHN1Ykl0ZXJhdG9yOwogICAgICAgIHdoaWxlIChpdGVyYXRvci5uZXh0KCkpIHsKICAgICAgICAgICAgaWYgKGl0ZXJhdG9yLmlzUGFydGlhbGx5U2VsZWN0ZWRTdWJ0cmVlKCkpIHsKICAgICAgICAgICAgICAgIHN1Ykl0ZXJhdG9yID0gaXRlcmF0b3IuZ2V0U3VidHJlZUl0ZXJhdG9yKCk7CiAgICAgICAgICAgICAgICBkZWxldGVTdWJ0cmVlKHN1Ykl0ZXJhdG9yKTsKICAgICAgICAgICAgICAgIHN1Ykl0ZXJhdG9yLmRldGFjaCh0cnVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGl0ZXJhdG9yLnJlbW92ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGV4dHJhY3RTdWJ0cmVlKGl0ZXJhdG9yKSB7CgogICAgICAgIGZvciAodmFyIG5vZGUsIGZyYWcgPSBnZXRSYW5nZURvY3VtZW50KGl0ZXJhdG9yLnJhbmdlKS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksIHN1Ykl0ZXJhdG9yOwogICAgICAgICAgICAgbm9kZSA9IGl0ZXJhdG9yLm5leHQoKTspIHsKCiAgICAgICAgICAgIGlmIChpdGVyYXRvci5pc1BhcnRpYWxseVNlbGVjdGVkU3VidHJlZSgpKSB7CiAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5jbG9uZU5vZGUoZmFsc2UpOwogICAgICAgICAgICAgICAgc3ViSXRlcmF0b3IgPSBpdGVyYXRvci5nZXRTdWJ0cmVlSXRlcmF0b3IoKTsKICAgICAgICAgICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQoZXh0cmFjdFN1YnRyZWUoc3ViSXRlcmF0b3IpKTsKICAgICAgICAgICAgICAgIHN1Ykl0ZXJhdG9yLmRldGFjaCh0cnVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGl0ZXJhdG9yLnJlbW92ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDEwKSB7Ly8gRG9jdW1lbnRUeXBlCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKCJISUVSQVJDSFlfUkVRVUVTVF9FUlIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmcmFnLmFwcGVuZENoaWxkKG5vZGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZnJhZzsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXROb2Rlc0luUmFuZ2UocmFuZ2UsIG5vZGVUeXBlcywgZmlsdGVyKSB7CiAgICAgICAgLy9sb2cuaW5mbygiZ2V0Tm9kZXNJblJhbmdlLCAiICsgbm9kZVR5cGVzLmpvaW4oIiwiKSk7CiAgICAgICAgdmFyIGZpbHRlck5vZGVUeXBlcyA9ICEhKG5vZGVUeXBlcyAmJiBub2RlVHlwZXMubGVuZ3RoKSwgcmVnZXg7CiAgICAgICAgdmFyIGZpbHRlckV4aXN0cyA9ICEhZmlsdGVyOwogICAgICAgIGlmIChmaWx0ZXJOb2RlVHlwZXMpIHsKICAgICAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKCJeKCIgKyBub2RlVHlwZXMuam9pbigifCIpICsgIikkIik7CiAgICAgICAgfQoKICAgICAgICB2YXIgbm9kZXMgPSBbXTsKICAgICAgICBpdGVyYXRlU3VidHJlZShuZXcgUmFuZ2VJdGVyYXRvcihyYW5nZSwgZmFsc2UpLCBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICBpZiAoKCFmaWx0ZXJOb2RlVHlwZXMgfHwgcmVnZXgudGVzdChub2RlLm5vZGVUeXBlKSkgJiYgKCFmaWx0ZXJFeGlzdHMgfHwgZmlsdGVyKG5vZGUpKSkgewogICAgICAgICAgICAgICAgbm9kZXMucHVzaChub2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBub2RlczsKICAgIH0KCiAgICBmdW5jdGlvbiBpbnNwZWN0KHJhbmdlKSB7CiAgICAgICAgdmFyIG5hbWUgPSAodHlwZW9mIHJhbmdlLmdldE5hbWUgPT0gInVuZGVmaW5lZCIpID8gIlJhbmdlIiA6IHJhbmdlLmdldE5hbWUoKTsKICAgICAgICByZXR1cm4gIlsiICsgbmFtZSArICIoIiArIGRvbS5pbnNwZWN0Tm9kZShyYW5nZS5zdGFydENvbnRhaW5lcikgKyAiOiIgKyByYW5nZS5zdGFydE9mZnNldCArICIsICIgKwogICAgICAgICAgICBkb20uaW5zcGVjdE5vZGUocmFuZ2UuZW5kQ29udGFpbmVyKSArICI6IiArIHJhbmdlLmVuZE9mZnNldCArICIpXSI7CiAgICB9CgogICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCiAgICAvLyBSYW5nZUl0ZXJhdG9yIGNvZGUgcGFydGlhbGx5IGJvcnJvd3MgZnJvbSBJRVJhbmdlIGJ5IFRpbSBSeWFuIChodHRwOi8vZ2l0aHViLmNvbS90aW1jYW1lcm9ucnlhbi9JRVJhbmdlKQoKICAgIC8qKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKi8KICAgIGZ1bmN0aW9uIFJhbmdlSXRlcmF0b3IocmFuZ2UsIGNsb25lUGFydGlhbGx5U2VsZWN0ZWRUZXh0Tm9kZXMpIHsKICAgICAgICB0aGlzLnJhbmdlID0gcmFuZ2U7CiAgICAgICAgdGhpcy5jbG9uZVBhcnRpYWxseVNlbGVjdGVkVGV4dE5vZGVzID0gY2xvbmVQYXJ0aWFsbHlTZWxlY3RlZFRleHROb2RlczsKCiAgICAgICAgaWYgKCFyYW5nZS5jb2xsYXBzZWQpIHsKICAgICAgICAgICAgdGhpcy5zYyA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyOwogICAgICAgICAgICB0aGlzLnNvID0gcmFuZ2Uuc3RhcnRPZmZzZXQ7CiAgICAgICAgICAgIHRoaXMuZWMgPSByYW5nZS5lbmRDb250YWluZXI7CiAgICAgICAgICAgIHRoaXMuZW8gPSByYW5nZS5lbmRPZmZzZXQ7CiAgICAgICAgICAgIHZhciByb290ID0gcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXI7CgogICAgICAgICAgICBpZiAodGhpcy5zYyA9PT0gdGhpcy5lYyAmJiBkb20uaXNDaGFyYWN0ZXJEYXRhTm9kZSh0aGlzLnNjKSkgewogICAgICAgICAgICAgICAgdGhpcy5pc1NpbmdsZUNoYXJhY3RlckRhdGFOb2RlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHRoaXMuX2ZpcnN0ID0gdGhpcy5fbGFzdCA9IHRoaXMuX25leHQgPSB0aGlzLnNjOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5fZmlyc3QgPSB0aGlzLl9uZXh0ID0gKHRoaXMuc2MgPT09IHJvb3QgJiYgIWRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKHRoaXMuc2MpKSA/CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zYy5jaGlsZE5vZGVzW3RoaXMuc29dIDogZG9tLmdldENsb3Nlc3RBbmNlc3RvckluKHRoaXMuc2MsIHJvb3QsIHRydWUpOwogICAgICAgICAgICAgICAgdGhpcy5fbGFzdCA9ICh0aGlzLmVjID09PSByb290ICYmICFkb20uaXNDaGFyYWN0ZXJEYXRhTm9kZSh0aGlzLmVjKSkgPwogICAgICAgICAgICAgICAgICAgIHRoaXMuZWMuY2hpbGROb2Rlc1t0aGlzLmVvIC0gMV0gOiBkb20uZ2V0Q2xvc2VzdEFuY2VzdG9ySW4odGhpcy5lYywgcm9vdCwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgUmFuZ2VJdGVyYXRvci5wcm90b3R5cGUgPSB7CiAgICAgICAgX2N1cnJlbnQgOiBudWxsLAogICAgICAgIF9uZXh0IDogbnVsbCwKICAgICAgICBfZmlyc3QgOiBudWxsLAogICAgICAgIF9sYXN0IDogbnVsbCwKICAgICAgICBpc1NpbmdsZUNoYXJhY3RlckRhdGFOb2RlIDogZmFsc2UsCgogICAgICAgIHJlc2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLl9jdXJyZW50ID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5fbmV4dCA9IHRoaXMuX2ZpcnN0OwogICAgICAgIH0sCgogICAgICAgIGhhc05leHQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMuX25leHQ7CiAgICAgICAgfSwKCiAgICAgICAgbmV4dCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgLy8gTW92ZSB0byBuZXh0IG5vZGUKICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSB0aGlzLl9jdXJyZW50ID0gdGhpcy5fbmV4dDsKICAgICAgICAgICAgaWYgKGN1cnJlbnQpIHsKICAgICAgICAgICAgICAgIHRoaXMuX25leHQgPSAoY3VycmVudCAhPT0gdGhpcy5fbGFzdCkgPyBjdXJyZW50Lm5leHRTaWJsaW5nIDogbnVsbDsKCiAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgcGFydGlhbGx5IHNlbGVjdGVkIHRleHQgbm9kZXMKICAgICAgICAgICAgICAgIGlmIChkb20uaXNDaGFyYWN0ZXJEYXRhTm9kZShjdXJyZW50KSAmJiB0aGlzLmNsb25lUGFydGlhbGx5U2VsZWN0ZWRUZXh0Tm9kZXMpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudCA9PT0gdGhpcy5lYykgewoKICAgICAgICAgICAgICAgICAgICAgICAgKGN1cnJlbnQgPSBjdXJyZW50LmNsb25lTm9kZSh0cnVlKSkuZGVsZXRlRGF0YSh0aGlzLmVvLCBjdXJyZW50Lmxlbmd0aCAtIHRoaXMuZW8pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fY3VycmVudCA9PT0gdGhpcy5zYykgewoKICAgICAgICAgICAgICAgICAgICAgICAgKGN1cnJlbnQgPSBjdXJyZW50LmNsb25lTm9kZSh0cnVlKSkuZGVsZXRlRGF0YSgwLCB0aGlzLnNvKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBjdXJyZW50OwogICAgICAgIH0sCgogICAgICAgIHJlbW92ZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSB0aGlzLl9jdXJyZW50LCBzdGFydCwgZW5kOwoKICAgICAgICAgICAgaWYgKGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKGN1cnJlbnQpICYmIChjdXJyZW50ID09PSB0aGlzLnNjIHx8IGN1cnJlbnQgPT09IHRoaXMuZWMpKSB7CiAgICAgICAgICAgICAgICBzdGFydCA9IChjdXJyZW50ID09PSB0aGlzLnNjKSA/IHRoaXMuc28gOiAwOwogICAgICAgICAgICAgICAgZW5kID0gKGN1cnJlbnQgPT09IHRoaXMuZWMpID8gdGhpcy5lbyA6IGN1cnJlbnQubGVuZ3RoOwogICAgICAgICAgICAgICAgaWYgKHN0YXJ0ICE9IGVuZCkgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnQuZGVsZXRlRGF0YShzdGFydCwgZW5kIC0gc3RhcnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGN1cnJlbnQucGFyZW50Tm9kZSkgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChjdXJyZW50KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvLyBDaGVja3MgaWYgdGhlIGN1cnJlbnQgbm9kZSBpcyBwYXJ0aWFsbHkgc2VsZWN0ZWQKICAgICAgICBpc1BhcnRpYWxseVNlbGVjdGVkU3VidHJlZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGN1cnJlbnQgPSB0aGlzLl9jdXJyZW50OwogICAgICAgICAgICByZXR1cm4gaXNOb25UZXh0UGFydGlhbGx5U2VsZWN0ZWQoY3VycmVudCwgdGhpcy5yYW5nZSk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0U3VidHJlZUl0ZXJhdG9yIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgc3ViUmFuZ2U7CiAgICAgICAgICAgIGlmICh0aGlzLmlzU2luZ2xlQ2hhcmFjdGVyRGF0YU5vZGUpIHsKICAgICAgICAgICAgICAgIHN1YlJhbmdlID0gdGhpcy5yYW5nZS5jbG9uZVJhbmdlKCk7CiAgICAgICAgICAgICAgICBzdWJSYW5nZS5jb2xsYXBzZSgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc3ViUmFuZ2UgPSBuZXcgUmFuZ2UoZ2V0UmFuZ2VEb2N1bWVudCh0aGlzLnJhbmdlKSk7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudCA9IHRoaXMuX2N1cnJlbnQ7CiAgICAgICAgICAgICAgICB2YXIgc3RhcnRDb250YWluZXIgPSBjdXJyZW50LCBzdGFydE9mZnNldCA9IDAsIGVuZENvbnRhaW5lciA9IGN1cnJlbnQsCiAgICAgICAgICAgICAgICAgICAgZW5kT2Zmc2V0ID0gZG9tLmdldE5vZGVMZW5ndGgoY3VycmVudCk7CgogICAgICAgICAgICAgICAgaWYgKGRvbS5pc0FuY2VzdG9yT2YoY3VycmVudCwgdGhpcy5zYywgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICBzdGFydENvbnRhaW5lciA9IHRoaXMuc2M7CiAgICAgICAgICAgICAgICAgICAgc3RhcnRPZmZzZXQgPSB0aGlzLnNvOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGRvbS5pc0FuY2VzdG9yT2YoY3VycmVudCwgdGhpcy5lYywgdHJ1ZSkpIHsKICAgICAgICAgICAgICAgICAgICBlbmRDb250YWluZXIgPSB0aGlzLmVjOwogICAgICAgICAgICAgICAgICAgIGVuZE9mZnNldCA9IHRoaXMuZW87CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdXBkYXRlQm91bmRhcmllcyhzdWJSYW5nZSwgc3RhcnRDb250YWluZXIsIHN0YXJ0T2Zmc2V0LCBlbmRDb250YWluZXIsIGVuZE9mZnNldCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ldyBSYW5nZUl0ZXJhdG9yKHN1YlJhbmdlLCB0aGlzLmNsb25lUGFydGlhbGx5U2VsZWN0ZWRUZXh0Tm9kZXMpOwogICAgICAgIH0sCgogICAgICAgIGRldGFjaCA6IGZ1bmN0aW9uIChkZXRhY2hSYW5nZSkgewogICAgICAgICAgICBpZiAoZGV0YWNoUmFuZ2UpIHsKICAgICAgICAgICAgICAgIHRoaXMucmFuZ2UuZGV0YWNoKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5yYW5nZSA9IHRoaXMuX2N1cnJlbnQgPSB0aGlzLl9uZXh0ID0gdGhpcy5fZmlyc3QgPSB0aGlzLl9sYXN0ID0gdGhpcy5zYyA9IHRoaXMuc28gPSB0aGlzLmVjID0gdGhpcy5lbyA9IG51bGw7CiAgICAgICAgfQogICAgfTsKCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8vIEV4Y2VwdGlvbnMKCiAgICAvKioKICAgICAqIEBjb25zdHJ1Y3RvcgogICAgICovCiAgICBmdW5jdGlvbiBSYW5nZUV4Y2VwdGlvbihjb2RlTmFtZSkgewogICAgICAgIHRoaXMuY29kZSA9IHRoaXNbY29kZU5hbWVdOwogICAgICAgIHRoaXMuY29kZU5hbWUgPSBjb2RlTmFtZTsKICAgICAgICB0aGlzLm1lc3NhZ2UgPSAiUmFuZ2VFeGNlcHRpb246ICIgKyB0aGlzLmNvZGVOYW1lOwogICAgfQoKICAgIFJhbmdlRXhjZXB0aW9uLnByb3RvdHlwZSA9IHsKICAgICAgICBCQURfQk9VTkRBUllQT0lOVFNfRVJSIDogMSwKICAgICAgICBJTlZBTElEX05PREVfVFlQRV9FUlIgOiAyCiAgICB9OwoKICAgIFJhbmdlRXhjZXB0aW9uLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gdGhpcy5tZXNzYWdlOwogICAgfTsKCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8qKgogICAgICogQ3VycmVudGx5IGl0ZXJhdGVzIHRocm91Z2ggYWxsIG5vZGVzIGluIHRoZSByYW5nZSBvbiBjcmVhdGlvbiB1bnRpbCBJIHRoaW5rIG9mIGEgZGVjZW50IHdheSB0byBkbyBpdAogICAgICogVE9ETzogTG9vayBpbnRvIG1ha2luZyB0aGlzIGEgcHJvcGVyIGl0ZXJhdG9yLCBub3QgcmVxdWlyaW5nIHByZWxvYWRpbmcgZXZlcnl0aGluZyBmaXJzdAogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKi8KICAgIGZ1bmN0aW9uIFJhbmdlTm9kZUl0ZXJhdG9yKHJhbmdlLCBub2RlVHlwZXMsIGZpbHRlcikgewogICAgICAgIHRoaXMubm9kZXMgPSBnZXROb2Rlc0luUmFuZ2UocmFuZ2UsIG5vZGVUeXBlcywgZmlsdGVyKTsKICAgICAgICB0aGlzLl9uZXh0ID0gdGhpcy5ub2Rlc1swXTsKICAgICAgICB0aGlzLl9wb3NpdGlvbiA9IDA7CiAgICB9CgogICAgUmFuZ2VOb2RlSXRlcmF0b3IucHJvdG90eXBlID0gewogICAgICAgIF9jdXJyZW50IDogbnVsbCwKCiAgICAgICAgaGFzTmV4dCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICEhdGhpcy5fbmV4dDsKICAgICAgICB9LAoKICAgICAgICBuZXh0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLl9jdXJyZW50ID0gdGhpcy5fbmV4dDsKICAgICAgICAgICAgdGhpcy5fbmV4dCA9IHRoaXMubm9kZXNbKyt0aGlzLl9wb3NpdGlvbl07CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jdXJyZW50OwogICAgICAgIH0sCgogICAgICAgIGRldGFjaCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdGhpcy5fY3VycmVudCA9IHRoaXMuX25leHQgPSB0aGlzLm5vZGVzID0gbnVsbDsKICAgICAgICB9CiAgICB9OwoKICAgIHZhciBiZWZvcmVBZnRlck5vZGVUeXBlcyA9IFsxLCAzLCA0LCA1LCA3LCA4LCAxMF07CiAgICB2YXIgcm9vdENvbnRhaW5lck5vZGVUeXBlcyA9IFsyLCA5LCAxMV07CiAgICB2YXIgcmVhZG9ubHlOb2RlVHlwZXMgPSBbNSwgNiwgMTAsIDEyXTsKICAgIHZhciBpbnNlcnRhYmxlTm9kZVR5cGVzID0gWzEsIDMsIDQsIDUsIDcsIDgsIDEwLCAxMV07CiAgICB2YXIgc3Vycm91bmROb2RlVHlwZXMgPSBbMSwgMywgNCwgNSwgNywgOF07CgogICAgZnVuY3Rpb24gY3JlYXRlQW5jZXN0b3JGaW5kZXIobm9kZVR5cGVzKSB7CiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChub2RlLCBzZWxmSXNBbmNlc3RvcikgewogICAgICAgICAgICB2YXIgdCwgbiA9IHNlbGZJc0FuY2VzdG9yID8gbm9kZSA6IG5vZGUucGFyZW50Tm9kZTsKICAgICAgICAgICAgd2hpbGUgKG4pIHsKICAgICAgICAgICAgICAgIHQgPSBuLm5vZGVUeXBlOwogICAgICAgICAgICAgICAgaWYgKGRvbS5hcnJheUNvbnRhaW5zKG5vZGVUeXBlcywgdCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG4gPSBuLnBhcmVudE5vZGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKICAgIH0KCiAgICB2YXIgZ2V0Um9vdENvbnRhaW5lciA9IGRvbS5nZXRSb290Q29udGFpbmVyOwogICAgdmFyIGdldERvY3VtZW50T3JGcmFnbWVudENvbnRhaW5lciA9IGNyZWF0ZUFuY2VzdG9yRmluZGVyKFs5LCAxMV0pOwogICAgdmFyIGdldFJlYWRvbmx5QW5jZXN0b3IgPSBjcmVhdGVBbmNlc3RvckZpbmRlcihyZWFkb25seU5vZGVUeXBlcyk7CiAgICB2YXIgZ2V0RG9jVHlwZU5vdGF0aW9uRW50aXR5QW5jZXN0b3IgPSBjcmVhdGVBbmNlc3RvckZpbmRlcihbNiwgMTAsIDEyXSk7CgogICAgZnVuY3Rpb24gYXNzZXJ0Tm9Eb2NUeXBlTm90YXRpb25FbnRpdHlBbmNlc3Rvcihub2RlLCBhbGxvd1NlbGYpIHsKICAgICAgICBpZiAoZ2V0RG9jVHlwZU5vdGF0aW9uRW50aXR5QW5jZXN0b3Iobm9kZSwgYWxsb3dTZWxmKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFeGNlcHRpb24oIklOVkFMSURfTk9ERV9UWVBFX0VSUiIpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBhc3NlcnROb3REZXRhY2hlZChyYW5nZSkgewogICAgICAgIGlmICghcmFuZ2Uuc3RhcnRDb250YWluZXIpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigiSU5WQUxJRF9TVEFURV9FUlIiKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gYXNzZXJ0VmFsaWROb2RlVHlwZShub2RlLCBpbnZhbGlkVHlwZXMpIHsKICAgICAgICBpZiAoIWRvbS5hcnJheUNvbnRhaW5zKGludmFsaWRUeXBlcywgbm9kZS5ub2RlVHlwZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXhjZXB0aW9uKCJJTlZBTElEX05PREVfVFlQRV9FUlIiKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gYXNzZXJ0VmFsaWRPZmZzZXQobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gKGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKG5vZGUpID8gbm9kZS5sZW5ndGggOiBub2RlLmNoaWxkTm9kZXMubGVuZ3RoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKCJJTkRFWF9TSVpFX0VSUiIpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBhc3NlcnRTYW1lRG9jdW1lbnRPckZyYWdtZW50KG5vZGUxLCBub2RlMikgewogICAgICAgIGlmIChnZXREb2N1bWVudE9yRnJhZ21lbnRDb250YWluZXIobm9kZTEsIHRydWUpICE9PSBnZXREb2N1bWVudE9yRnJhZ21lbnRDb250YWluZXIobm9kZTIsIHRydWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIldST05HX0RPQ1VNRU5UX0VSUiIpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBhc3NlcnROb2RlTm90UmVhZE9ubHkobm9kZSkgewogICAgICAgIGlmIChnZXRSZWFkb25seUFuY2VzdG9yKG5vZGUsIHRydWUpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIk5PX01PRElGSUNBVElPTl9BTExPV0VEX0VSUiIpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBhc3NlcnROb2RlKG5vZGUsIGNvZGVOYW1lKSB7CiAgICAgICAgaWYgKCFub2RlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oY29kZU5hbWUpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBpc09ycGhhbihub2RlKSB7CiAgICAgICAgcmV0dXJuICFkb20uYXJyYXlDb250YWlucyhyb290Q29udGFpbmVyTm9kZVR5cGVzLCBub2RlLm5vZGVUeXBlKSAmJiAhZ2V0RG9jdW1lbnRPckZyYWdtZW50Q29udGFpbmVyKG5vZGUsIHRydWUpOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzVmFsaWRPZmZzZXQobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgcmV0dXJuIG9mZnNldCA8PSAoZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUobm9kZSkgPyBub2RlLmxlbmd0aCA6IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGgpOwogICAgfQoKICAgIGZ1bmN0aW9uIGFzc2VydFJhbmdlVmFsaWQocmFuZ2UpIHsKICAgICAgICBhc3NlcnROb3REZXRhY2hlZChyYW5nZSk7CiAgICAgICAgaWYgKGlzT3JwaGFuKHJhbmdlLnN0YXJ0Q29udGFpbmVyKSB8fCBpc09ycGhhbihyYW5nZS5lbmRDb250YWluZXIpIHx8ICFpc1ZhbGlkT2Zmc2V0KHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydE9mZnNldCkgfHwgIWlzVmFsaWRPZmZzZXQocmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiUmFuZ2UgZXJyb3I6IFJhbmdlIGlzIG5vIGxvbmdlciB2YWxpZCBhZnRlciBET00gbXV0YXRpb24gKCIgKyByYW5nZS5pbnNwZWN0KCkgKyAiKSIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8vIFRlc3QgdGhlIGJyb3dzZXIncyBpbm5lckhUTUwgc3VwcG9ydCB0byBkZWNpZGUgaG93IHRvIGltcGxlbWVudCBjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQKICAgIHZhciBzdHlsZUVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3R5bGUiKTsKICAgIHZhciBodG1sUGFyc2luZ0NvbmZvcm1zID0gZmFsc2U7CiAgICB0cnkgewogICAgICAgIHN0eWxlRWwuaW5uZXJIVE1MID0gIjxiPng8L2I+IjsKICAgICAgICBodG1sUGFyc2luZ0NvbmZvcm1zID0gKHN0eWxlRWwuZmlyc3RDaGlsZC5ub2RlVHlwZSA9PSAzKTsgLy8gT3BlcmEgaW5jb3JyZWN0bHkgY3JlYXRlcyBhbiBlbGVtZW50IG5vZGUKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAvLyBJRSA2IGFuZCA3IHRocm93CiAgICB9CgogICAgYXBpLmZlYXR1cmVzLmh0bWxQYXJzaW5nQ29uZm9ybXMgPSBodG1sUGFyc2luZ0NvbmZvcm1zOwoKICAgIHZhciBjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQgPSBodG1sUGFyc2luZ0NvbmZvcm1zID8KCiAgICAgICAgLy8gSW1wbGVtZW50YXRpb24gYXMgcGVyIEhUTUwgcGFyc2luZyBzcGVjLCB0cnVzdGluZyBpbiB0aGUgYnJvd3NlcidzIGltcGxlbWVudGF0aW9uIG9mIGlubmVySFRNTC4gU2VlCiAgICAgICAgLy8gZGlzY3Vzc2lvbiBhbmQgYmFzZSBjb2RlIGZvciB0aGlzIGltcGxlbWVudGF0aW9uIGF0IGlzc3VlIDY3LgogICAgICAgIC8vIFNwZWM6IGh0dHA6Ly9odG1sNS5vcmcvc3BlY3MvZG9tLXBhcnNpbmcuaHRtbCNleHRlbnNpb25zLXRvLXRoZS1yYW5nZS1pbnRlcmZhY2UKICAgICAgICAvLyBUaGFua3MgdG8gQWxla3MgV2lsbGlhbXMuCiAgICAgICAgZnVuY3Rpb24gKGZyYWdtZW50U3RyKSB7CiAgICAgICAgICAgIC8vICJMZXQgbm9kZSB0aGUgY29udGV4dCBvYmplY3QncyBzdGFydCdzIG5vZGUuIgogICAgICAgICAgICB2YXIgbm9kZSA9IHRoaXMuc3RhcnRDb250YWluZXI7CiAgICAgICAgICAgIHZhciBkb2MgPSBkb20uZ2V0RG9jdW1lbnQobm9kZSk7CgogICAgICAgICAgICAvLyAiSWYgdGhlIGNvbnRleHQgb2JqZWN0J3Mgc3RhcnQncyBub2RlIGlzIG51bGwsIHJhaXNlIGFuIElOVkFMSURfU1RBVEVfRVJSCiAgICAgICAgICAgIC8vIGV4Y2VwdGlvbiBhbmQgYWJvcnQgdGhlc2Ugc3RlcHMuIgogICAgICAgICAgICBpZiAoIW5vZGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIklOVkFMSURfU1RBVEVfRVJSIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vICJMZXQgZWxlbWVudCBiZSBhcyBmb2xsb3dzLCBkZXBlbmRpbmcgb24gbm9kZSdzIGludGVyZmFjZToiCiAgICAgICAgICAgIC8vIERvY3VtZW50LCBEb2N1bWVudCBGcmFnbWVudDogbnVsbAogICAgICAgICAgICB2YXIgZWwgPSBudWxsOwoKICAgICAgICAgICAgLy8gIkVsZW1lbnQ6IG5vZGUiCiAgICAgICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDEpIHsKICAgICAgICAgICAgICAgIGVsID0gbm9kZTsKCiAgICAgICAgICAgICAgICAvLyAiVGV4dCwgQ29tbWVudDogbm9kZSdzIHBhcmVudEVsZW1lbnQiCiAgICAgICAgICAgIH0gZWxzZSBpZiAoZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUobm9kZSkpIHsKICAgICAgICAgICAgICAgIGVsID0gZG9tLnBhcmVudEVsZW1lbnQobm9kZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vICJJZiBlaXRoZXIgZWxlbWVudCBpcyBudWxsIG9yIGVsZW1lbnQncyBvd25lckRvY3VtZW50IGlzIGFuIEhUTUwgZG9jdW1lbnQKICAgICAgICAgICAgLy8gYW5kIGVsZW1lbnQncyBsb2NhbCBuYW1lIGlzICJodG1sIiBhbmQgZWxlbWVudCdzIG5hbWVzcGFjZSBpcyB0aGUgSFRNTAogICAgICAgICAgICAvLyBuYW1lc3BhY2UiCiAgICAgICAgICAgIGlmIChlbCA9PT0gbnVsbCB8fCAoCiAgICAgICAgICAgICAgICAgICAgZWwubm9kZU5hbWUgPT0gIkhUTUwiICYmIGRvbS5pc0h0bWxOYW1lc3BhY2UoZG9tLmdldERvY3VtZW50KGVsKS5kb2N1bWVudEVsZW1lbnQpICYmIGRvbS5pc0h0bWxOYW1lc3BhY2UoZWwpCiAgICAgICAgICAgICAgICApKSB7CgogICAgICAgICAgICAgICAgLy8gImxldCBlbGVtZW50IGJlIGEgbmV3IEVsZW1lbnQgd2l0aCAiYm9keSIgYXMgaXRzIGxvY2FsIG5hbWUgYW5kIHRoZSBIVE1MCiAgICAgICAgICAgICAgICAvLyBuYW1lc3BhY2UgYXMgaXRzIG5hbWVzcGFjZS4iIgogICAgICAgICAgICAgICAgZWwgPSBkb2MuY3JlYXRlRWxlbWVudCgiYm9keSIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZWwgPSBlbC5jbG9uZU5vZGUoZmFsc2UpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyAiSWYgdGhlIG5vZGUncyBkb2N1bWVudCBpcyBhbiBIVE1MIGRvY3VtZW50OiBJbnZva2UgdGhlIEhUTUwgZnJhZ21lbnQgcGFyc2luZyBhbGdvcml0aG0uIgogICAgICAgICAgICAvLyAiSWYgdGhlIG5vZGUncyBkb2N1bWVudCBpcyBhbiBYTUwgZG9jdW1lbnQ6IEludm9rZSB0aGUgWE1MIGZyYWdtZW50IHBhcnNpbmcgYWxnb3JpdGhtLiIKICAgICAgICAgICAgLy8gIkluIGVpdGhlciBjYXNlLCB0aGUgYWxnb3JpdGhtIG11c3QgYmUgaW52b2tlZCB3aXRoIGZyYWdtZW50IGFzIHRoZSBpbnB1dAogICAgICAgICAgICAvLyBhbmQgZWxlbWVudCBhcyB0aGUgY29udGV4dCBlbGVtZW50LiIKICAgICAgICAgICAgZWwuaW5uZXJIVE1MID0gZnJhZ21lbnRTdHI7CgogICAgICAgICAgICAvLyAiSWYgdGhpcyByYWlzZXMgYW4gZXhjZXB0aW9uLCB0aGVuIGFib3J0IHRoZXNlIHN0ZXBzLiBPdGhlcndpc2UsIGxldCBuZXcKICAgICAgICAgICAgLy8gY2hpbGRyZW4gYmUgdGhlIG5vZGVzIHJldHVybmVkLiIKCiAgICAgICAgICAgIC8vICJMZXQgZnJhZ21lbnQgYmUgYSBuZXcgRG9jdW1lbnRGcmFnbWVudC4iCiAgICAgICAgICAgIC8vICJBcHBlbmQgYWxsIG5ldyBjaGlsZHJlbiB0byBmcmFnbWVudC4iCiAgICAgICAgICAgIC8vICJSZXR1cm4gZnJhZ21lbnQuIgogICAgICAgICAgICByZXR1cm4gZG9tLmZyYWdtZW50RnJvbU5vZGVDaGlsZHJlbihlbCk7CiAgICAgICAgfSA6CgogICAgICAgIC8vIEluIHRoaXMgY2FzZSwgaW5uZXJIVE1MIGNhbm5vdCBiZSB0cnVzdGVkLCBzbyBmYWxsIGJhY2sgdG8gYSBzaW1wbGVyLCBub24tY29uZm9ybWFudCBpbXBsZW1lbnRhdGlvbiB0aGF0CiAgICAgICAgLy8gcHJldmlvdXMgdmVyc2lvbnMgb2YgUmFuZ3kgdXNlZCAod2l0aCB0aGUgZXhjZXB0aW9uIG9mIHVzaW5nIGEgYm9keSBlbGVtZW50IHJhdGhlciB0aGFuIGEgZGl2KQogICAgICAgIGZ1bmN0aW9uIChmcmFnbWVudFN0cikgewogICAgICAgICAgICBhc3NlcnROb3REZXRhY2hlZCh0aGlzKTsKICAgICAgICAgICAgdmFyIGRvYyA9IGdldFJhbmdlRG9jdW1lbnQodGhpcyk7CiAgICAgICAgICAgIHZhciBlbCA9IGRvYy5jcmVhdGVFbGVtZW50KCJib2R5Iik7CiAgICAgICAgICAgIGVsLmlubmVySFRNTCA9IGZyYWdtZW50U3RyOwoKICAgICAgICAgICAgcmV0dXJuIGRvbS5mcmFnbWVudEZyb21Ob2RlQ2hpbGRyZW4oZWwpOwogICAgICAgIH07CgogICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCiAgICB2YXIgcmFuZ2VQcm9wZXJ0aWVzID0gWyJzdGFydENvbnRhaW5lciIsICJzdGFydE9mZnNldCIsICJlbmRDb250YWluZXIiLCAiZW5kT2Zmc2V0IiwgImNvbGxhcHNlZCIsCiAgICAgICAgImNvbW1vbkFuY2VzdG9yQ29udGFpbmVyIl07CgogICAgdmFyIHMycyA9IDAsIHMyZSA9IDEsIGUyZSA9IDIsIGUycyA9IDM7CiAgICB2YXIgbl9iID0gMCwgbl9hID0gMSwgbl9iX2EgPSAyLCBuX2kgPSAzOwoKICAgIGZ1bmN0aW9uIFJhbmdlUHJvdG90eXBlKCkgewogICAgfQoKICAgIFJhbmdlUHJvdG90eXBlLnByb3RvdHlwZSA9IHsKICAgICAgICBhdHRhY2hMaXN0ZW5lciA6IGZ1bmN0aW9uICh0eXBlLCBsaXN0ZW5lcikgewogICAgICAgICAgICB0aGlzLl9saXN0ZW5lcnNbdHlwZV0ucHVzaChsaXN0ZW5lcik7CiAgICAgICAgfSwKCiAgICAgICAgY29tcGFyZUJvdW5kYXJ5UG9pbnRzIDogZnVuY3Rpb24gKGhvdywgcmFuZ2UpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgYXNzZXJ0U2FtZURvY3VtZW50T3JGcmFnbWVudCh0aGlzLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydENvbnRhaW5lcik7CgogICAgICAgICAgICB2YXIgbm9kZUEsIG9mZnNldEEsIG5vZGVCLCBvZmZzZXRCOwogICAgICAgICAgICB2YXIgcHJlZml4QSA9IChob3cgPT0gZTJzIHx8IGhvdyA9PSBzMnMpID8gInN0YXJ0IiA6ICJlbmQiOwogICAgICAgICAgICB2YXIgcHJlZml4QiA9IChob3cgPT0gczJlIHx8IGhvdyA9PSBzMnMpID8gInN0YXJ0IiA6ICJlbmQiOwogICAgICAgICAgICBub2RlQSA9IHRoaXNbcHJlZml4QSArICJDb250YWluZXIiXTsKICAgICAgICAgICAgb2Zmc2V0QSA9IHRoaXNbcHJlZml4QSArICJPZmZzZXQiXTsKICAgICAgICAgICAgbm9kZUIgPSByYW5nZVtwcmVmaXhCICsgIkNvbnRhaW5lciJdOwogICAgICAgICAgICBvZmZzZXRCID0gcmFuZ2VbcHJlZml4QiArICJPZmZzZXQiXTsKICAgICAgICAgICAgcmV0dXJuIGRvbS5jb21wYXJlUG9pbnRzKG5vZGVBLCBvZmZzZXRBLCBub2RlQiwgb2Zmc2V0Qik7CiAgICAgICAgfSwKCiAgICAgICAgaW5zZXJ0Tm9kZSA6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgIGFzc2VydFJhbmdlVmFsaWQodGhpcyk7CiAgICAgICAgICAgIGFzc2VydFZhbGlkTm9kZVR5cGUobm9kZSwgaW5zZXJ0YWJsZU5vZGVUeXBlcyk7CiAgICAgICAgICAgIGFzc2VydE5vZGVOb3RSZWFkT25seSh0aGlzLnN0YXJ0Q29udGFpbmVyKTsKCiAgICAgICAgICAgIGlmIChkb20uaXNBbmNlc3Rvck9mKG5vZGUsIHRoaXMuc3RhcnRDb250YWluZXIsIHRydWUpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKCJISUVSQVJDSFlfUkVRVUVTVF9FUlIiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gTm8gY2hlY2sgZm9yIHdoZXRoZXIgdGhlIGNvbnRhaW5lciBvZiB0aGUgc3RhcnQgb2YgdGhlIFJhbmdlIGlzIG9mIGEgdHlwZSB0aGF0IGRvZXMgbm90IGFsbG93CiAgICAgICAgICAgIC8vIGNoaWxkcmVuIG9mIHRoZSB0eXBlIG9mIG5vZGU6IHRoZSBicm93c2VyJ3MgRE9NIGltcGxlbWVudGF0aW9uIHNob3VsZCBkbyB0aGlzIGZvciB1cyB3aGVuIHdlIGF0dGVtcHQKICAgICAgICAgICAgLy8gdG8gYWRkIHRoZSBub2RlCgogICAgICAgICAgICB2YXIgZmlyc3ROb2RlSW5zZXJ0ZWQgPSBpbnNlcnROb2RlQXRQb3NpdGlvbihub2RlLCB0aGlzLnN0YXJ0Q29udGFpbmVyLCB0aGlzLnN0YXJ0T2Zmc2V0KTsKICAgICAgICAgICAgdGhpcy5zZXRTdGFydEJlZm9yZShmaXJzdE5vZGVJbnNlcnRlZCk7CiAgICAgICAgfSwKCiAgICAgICAgY2xvbmVDb250ZW50cyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKCiAgICAgICAgICAgIHZhciBjbG9uZSwgZnJhZzsKICAgICAgICAgICAgaWYgKHRoaXMuY29sbGFwc2VkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0UmFuZ2VEb2N1bWVudCh0aGlzKS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGFydENvbnRhaW5lciA9PT0gdGhpcy5lbmRDb250YWluZXIgJiYgZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUodGhpcy5zdGFydENvbnRhaW5lcikpIHsKICAgICAgICAgICAgICAgICAgICBjbG9uZSA9IHRoaXMuc3RhcnRDb250YWluZXIuY2xvbmVOb2RlKHRydWUpOwogICAgICAgICAgICAgICAgICAgIGNsb25lLmRhdGEgPSBjbG9uZS5kYXRhLnNsaWNlKHRoaXMuc3RhcnRPZmZzZXQsIHRoaXMuZW5kT2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICBmcmFnID0gZ2V0UmFuZ2VEb2N1bWVudCh0aGlzKS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CiAgICAgICAgICAgICAgICAgICAgZnJhZy5hcHBlbmRDaGlsZChjbG9uZSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZyYWc7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHZhciBpdGVyYXRvciA9IG5ldyBSYW5nZUl0ZXJhdG9yKHRoaXMsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIGNsb25lID0gY2xvbmVTdWJ0cmVlKGl0ZXJhdG9yKTsKICAgICAgICAgICAgICAgICAgICBpdGVyYXRvci5kZXRhY2goKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBjbG9uZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNhblN1cnJvdW5kQ29udGVudHMgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGFzc2VydFJhbmdlVmFsaWQodGhpcyk7CiAgICAgICAgICAgIGFzc2VydE5vZGVOb3RSZWFkT25seSh0aGlzLnN0YXJ0Q29udGFpbmVyKTsKICAgICAgICAgICAgYXNzZXJ0Tm9kZU5vdFJlYWRPbmx5KHRoaXMuZW5kQ29udGFpbmVyKTsKCiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBjb250ZW50cyBjYW4gYmUgc3Vycm91bmRlZC4gU3BlY2lmaWNhbGx5LCB0aGlzIG1lYW5zIHdoZXRoZXIgdGhlIHJhbmdlIHBhcnRpYWxseSBzZWxlY3RzCiAgICAgICAgICAgIC8vIG5vIG5vbi10ZXh0IG5vZGVzLgogICAgICAgICAgICB2YXIgaXRlcmF0b3IgPSBuZXcgUmFuZ2VJdGVyYXRvcih0aGlzLCB0cnVlKTsKICAgICAgICAgICAgdmFyIGJvdW5kYXJpZXNJbnZhbGlkID0gKGl0ZXJhdG9yLl9maXJzdCAmJiAoaXNOb25UZXh0UGFydGlhbGx5U2VsZWN0ZWQoaXRlcmF0b3IuX2ZpcnN0LCB0aGlzKSkgfHwKICAgICAgICAgICAgKGl0ZXJhdG9yLl9sYXN0ICYmIGlzTm9uVGV4dFBhcnRpYWxseVNlbGVjdGVkKGl0ZXJhdG9yLl9sYXN0LCB0aGlzKSkpOwogICAgICAgICAgICBpdGVyYXRvci5kZXRhY2goKTsKICAgICAgICAgICAgcmV0dXJuICFib3VuZGFyaWVzSW52YWxpZDsKICAgICAgICB9LAoKICAgICAgICBzdXJyb3VuZENvbnRlbnRzIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgYXNzZXJ0VmFsaWROb2RlVHlwZShub2RlLCBzdXJyb3VuZE5vZGVUeXBlcyk7CgogICAgICAgICAgICBpZiAoIXRoaXMuY2FuU3Vycm91bmRDb250ZW50cygpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFeGNlcHRpb24oIkJBRF9CT1VOREFSWVBPSU5UU19FUlIiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gRXh0cmFjdCB0aGUgY29udGVudHMKICAgICAgICAgICAgdmFyIGNvbnRlbnQgPSB0aGlzLmV4dHJhY3RDb250ZW50cygpOwoKICAgICAgICAgICAgLy8gQ2xlYXIgdGhlIGNoaWxkcmVuIG9mIHRoZSBub2RlCiAgICAgICAgICAgIGlmIChub2RlLmhhc0NoaWxkTm9kZXMoKSkgewogICAgICAgICAgICAgICAgd2hpbGUgKG5vZGUubGFzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgbm9kZS5yZW1vdmVDaGlsZChub2RlLmxhc3RDaGlsZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEluc2VydCB0aGUgbmV3IG5vZGUgYW5kIGFkZCB0aGUgZXh0cmFjdGVkIGNvbnRlbnRzCiAgICAgICAgICAgIGluc2VydE5vZGVBdFBvc2l0aW9uKG5vZGUsIHRoaXMuc3RhcnRDb250YWluZXIsIHRoaXMuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICBub2RlLmFwcGVuZENoaWxkKGNvbnRlbnQpOwoKICAgICAgICAgICAgdGhpcy5zZWxlY3ROb2RlKG5vZGUpOwogICAgICAgIH0sCgogICAgICAgIGNsb25lUmFuZ2UgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGFzc2VydFJhbmdlVmFsaWQodGhpcyk7CiAgICAgICAgICAgIHZhciByYW5nZSA9IG5ldyBSYW5nZShnZXRSYW5nZURvY3VtZW50KHRoaXMpKTsKICAgICAgICAgICAgdmFyIGkgPSByYW5nZVByb3BlcnRpZXMubGVuZ3RoLCBwcm9wOwogICAgICAgICAgICB3aGlsZSAoaS0tKSB7CiAgICAgICAgICAgICAgICBwcm9wID0gcmFuZ2VQcm9wZXJ0aWVzW2ldOwogICAgICAgICAgICAgICAgcmFuZ2VbcHJvcF0gPSB0aGlzW3Byb3BdOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByYW5nZTsKICAgICAgICB9LAoKICAgICAgICB0b1N0cmluZyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgdmFyIHNjID0gdGhpcy5zdGFydENvbnRhaW5lcjsKICAgICAgICAgICAgaWYgKHNjID09PSB0aGlzLmVuZENvbnRhaW5lciAmJiBkb20uaXNDaGFyYWN0ZXJEYXRhTm9kZShzYykpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoc2Mubm9kZVR5cGUgPT0gMyB8fCBzYy5ub2RlVHlwZSA9PSA0KSA/IHNjLmRhdGEuc2xpY2UodGhpcy5zdGFydE9mZnNldCwgdGhpcy5lbmRPZmZzZXQpIDogIiI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgdGV4dEJpdHMgPSBbXSwgaXRlcmF0b3IgPSBuZXcgUmFuZ2VJdGVyYXRvcih0aGlzLCB0cnVlKTsKCiAgICAgICAgICAgICAgICBpdGVyYXRlU3VidHJlZShpdGVyYXRvciwgZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAvLyBBY2NlcHQgb25seSB0ZXh0IG9yIENEQVRBIG5vZGVzLCBub3QgY29tbWVudHMKCiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMyB8fCBub2RlLm5vZGVUeXBlID09IDQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEJpdHMucHVzaChub2RlLmRhdGEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgaXRlcmF0b3IuZGV0YWNoKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gdGV4dEJpdHMuam9pbigiIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvLyBUaGUgbWV0aG9kcyBiZWxvdyBhcmUgYWxsIG5vbi1zdGFuZGFyZC4gVGhlIGZvbGxvd2luZyBiYXRjaCB3ZXJlIGludHJvZHVjZWQgYnkgTW96aWxsYSBidXQgaGF2ZSBzaW5jZQogICAgICAgIC8vIGJlZW4gcmVtb3ZlZCBmcm9tIE1vemlsbGEuCgogICAgICAgIGNvbXBhcmVOb2RlIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKCiAgICAgICAgICAgIHZhciBwYXJlbnQgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgICAgIHZhciBub2RlSW5kZXggPSBkb20uZ2V0Tm9kZUluZGV4KG5vZGUpOwoKICAgICAgICAgICAgaWYgKCFwYXJlbnQpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIk5PVF9GT1VORF9FUlIiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHN0YXJ0Q29tcGFyaXNvbiA9IHRoaXMuY29tcGFyZVBvaW50KHBhcmVudCwgbm9kZUluZGV4KSwKICAgICAgICAgICAgICAgIGVuZENvbXBhcmlzb24gPSB0aGlzLmNvbXBhcmVQb2ludChwYXJlbnQsIG5vZGVJbmRleCArIDEpOwoKICAgICAgICAgICAgaWYgKHN0YXJ0Q29tcGFyaXNvbiA8IDApIHsvLyBOb2RlIHN0YXJ0cyBiZWZvcmUKICAgICAgICAgICAgICAgIHJldHVybiAoZW5kQ29tcGFyaXNvbiA+IDApID8gbl9iX2EgOiBuX2I7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKGVuZENvbXBhcmlzb24gPiAwKSA/IG5fYSA6IG5faTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNvbXBhcmVQb2ludCA6IGZ1bmN0aW9uIChub2RlLCBvZmZzZXQpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgYXNzZXJ0Tm9kZShub2RlLCAiSElFUkFSQ0hZX1JFUVVFU1RfRVJSIik7CiAgICAgICAgICAgIGFzc2VydFNhbWVEb2N1bWVudE9yRnJhZ21lbnQobm9kZSwgdGhpcy5zdGFydENvbnRhaW5lcik7CgogICAgICAgICAgICBpZiAoZG9tLmNvbXBhcmVQb2ludHMobm9kZSwgb2Zmc2V0LCB0aGlzLnN0YXJ0Q29udGFpbmVyLCB0aGlzLnN0YXJ0T2Zmc2V0KSA8IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfSBlbHNlIGlmIChkb20uY29tcGFyZVBvaW50cyhub2RlLCBvZmZzZXQsIHRoaXMuZW5kQ29udGFpbmVyLCB0aGlzLmVuZE9mZnNldCkgPiAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQgOiBjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQsCgogICAgICAgIHRvSHRtbCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgdmFyIGNvbnRhaW5lciA9IGdldFJhbmdlRG9jdW1lbnQodGhpcykuY3JlYXRlRWxlbWVudCgiZGl2Iik7CiAgICAgICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLmNsb25lQ29udGVudHMoKSk7CiAgICAgICAgICAgIHJldHVybiBjb250YWluZXIuaW5uZXJIVE1MOwogICAgICAgIH0sCgogICAgICAgIC8vIHRvdWNoaW5nSXNJbnRlcnNlY3RpbmcgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoaXMgbWV0aG9kIGNvbnNpZGVycyBhIG5vZGUgdGhhdCBib3JkZXJzIGEgcmFuZ2UgaW50ZXJzZWN0cwogICAgICAgIC8vIHdpdGggaXQgKGFzIGluIFdlYktpdCkgb3Igbm90IChhcyBpbiBHZWNrbyBwcmUtMS45LCBhbmQgdGhlIGRlZmF1bHQpCiAgICAgICAgaW50ZXJzZWN0c05vZGUgOiBmdW5jdGlvbiAobm9kZSwgdG91Y2hpbmdJc0ludGVyc2VjdGluZykgewogICAgICAgICAgICBhc3NlcnRSYW5nZVZhbGlkKHRoaXMpOwogICAgICAgICAgICBhc3NlcnROb2RlKG5vZGUsICJOT1RfRk9VTkRfRVJSIik7CiAgICAgICAgICAgIGlmIChkb20uZ2V0RG9jdW1lbnQobm9kZSkgIT09IGdldFJhbmdlRG9jdW1lbnQodGhpcykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHBhcmVudCA9IG5vZGUucGFyZW50Tm9kZSwgb2Zmc2V0ID0gZG9tLmdldE5vZGVJbmRleChub2RlKTsKICAgICAgICAgICAgYXNzZXJ0Tm9kZShwYXJlbnQsICJOT1RfRk9VTkRfRVJSIik7CgogICAgICAgICAgICB2YXIgc3RhcnRDb21wYXJpc29uID0gZG9tLmNvbXBhcmVQb2ludHMocGFyZW50LCBvZmZzZXQsIHRoaXMuZW5kQ29udGFpbmVyLCB0aGlzLmVuZE9mZnNldCksCiAgICAgICAgICAgICAgICBlbmRDb21wYXJpc29uID0gZG9tLmNvbXBhcmVQb2ludHMocGFyZW50LCBvZmZzZXQgKyAxLCB0aGlzLnN0YXJ0Q29udGFpbmVyLCB0aGlzLnN0YXJ0T2Zmc2V0KTsKCiAgICAgICAgICAgIHJldHVybiB0b3VjaGluZ0lzSW50ZXJzZWN0aW5nID8gc3RhcnRDb21wYXJpc29uIDw9IDAgJiYgZW5kQ29tcGFyaXNvbiA+PSAwIDogc3RhcnRDb21wYXJpc29uIDwgMCAmJiBlbmRDb21wYXJpc29uID4gMDsKICAgICAgICB9LAoKICAgICAgICBpc1BvaW50SW5SYW5nZSA6IGZ1bmN0aW9uIChub2RlLCBvZmZzZXQpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgYXNzZXJ0Tm9kZShub2RlLCAiSElFUkFSQ0hZX1JFUVVFU1RfRVJSIik7CiAgICAgICAgICAgIGFzc2VydFNhbWVEb2N1bWVudE9yRnJhZ21lbnQobm9kZSwgdGhpcy5zdGFydENvbnRhaW5lcik7CgogICAgICAgICAgICByZXR1cm4gKGRvbS5jb21wYXJlUG9pbnRzKG5vZGUsIG9mZnNldCwgdGhpcy5zdGFydENvbnRhaW5lciwgdGhpcy5zdGFydE9mZnNldCkgPj0gMCkgJiYgKGRvbS5jb21wYXJlUG9pbnRzKG5vZGUsIG9mZnNldCwgdGhpcy5lbmRDb250YWluZXIsIHRoaXMuZW5kT2Zmc2V0KSA8PSAwKTsKICAgICAgICB9LAoKICAgICAgICAvLyBUaGUgbWV0aG9kcyBiZWxvdyBhcmUgbm9uLXN0YW5kYXJkIGFuZCBpbnZlbnRlZCBieSBtZS4KCiAgICAgICAgLy8gU2hhcmluZyBhIGJvdW5kYXJ5IHN0YXJ0LXRvLWVuZCBvciBlbmQtdG8tc3RhcnQgZG9lcyBub3QgY291bnQgYXMgaW50ZXJzZWN0aW9uLgogICAgICAgIGludGVyc2VjdHNSYW5nZSA6IGZ1bmN0aW9uIChyYW5nZSwgdG91Y2hpbmdJc0ludGVyc2VjdGluZykgewogICAgICAgICAgICBhc3NlcnRSYW5nZVZhbGlkKHRoaXMpOwoKICAgICAgICAgICAgaWYgKGdldFJhbmdlRG9jdW1lbnQocmFuZ2UpICE9IGdldFJhbmdlRG9jdW1lbnQodGhpcykpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIldST05HX0RPQ1VNRU5UX0VSUiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgc3RhcnRDb21wYXJpc29uID0gZG9tLmNvbXBhcmVQb2ludHModGhpcy5zdGFydENvbnRhaW5lciwgdGhpcy5zdGFydE9mZnNldCwgcmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpLAogICAgICAgICAgICAgICAgZW5kQ29tcGFyaXNvbiA9IGRvbS5jb21wYXJlUG9pbnRzKHRoaXMuZW5kQ29udGFpbmVyLCB0aGlzLmVuZE9mZnNldCwgcmFuZ2Uuc3RhcnRDb250YWluZXIsIHJhbmdlLnN0YXJ0T2Zmc2V0KTsKCiAgICAgICAgICAgIHJldHVybiB0b3VjaGluZ0lzSW50ZXJzZWN0aW5nID8gc3RhcnRDb21wYXJpc29uIDw9IDAgJiYgZW5kQ29tcGFyaXNvbiA+PSAwIDogc3RhcnRDb21wYXJpc29uIDwgMCAmJiBlbmRDb21wYXJpc29uID4gMDsKICAgICAgICB9LAoKICAgICAgICBpbnRlcnNlY3Rpb24gOiBmdW5jdGlvbiAocmFuZ2UpIHsKICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJzZWN0c1JhbmdlKHJhbmdlKSkgewogICAgICAgICAgICAgICAgdmFyIHN0YXJ0Q29tcGFyaXNvbiA9IGRvbS5jb21wYXJlUG9pbnRzKHRoaXMuc3RhcnRDb250YWluZXIsIHRoaXMuc3RhcnRPZmZzZXQsIHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydE9mZnNldCksCiAgICAgICAgICAgICAgICAgICAgZW5kQ29tcGFyaXNvbiA9IGRvbS5jb21wYXJlUG9pbnRzKHRoaXMuZW5kQ29udGFpbmVyLCB0aGlzLmVuZE9mZnNldCwgcmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpOwoKICAgICAgICAgICAgICAgIHZhciBpbnRlcnNlY3Rpb25SYW5nZSA9IHRoaXMuY2xvbmVSYW5nZSgpOwoKICAgICAgICAgICAgICAgIGlmIChzdGFydENvbXBhcmlzb24gPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICBpbnRlcnNlY3Rpb25SYW5nZS5zZXRTdGFydChyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGVuZENvbXBhcmlzb24gPT0gMSkgewogICAgICAgICAgICAgICAgICAgIGludGVyc2VjdGlvblJhbmdlLnNldEVuZChyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gaW50ZXJzZWN0aW9uUmFuZ2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgdW5pb24gOiBmdW5jdGlvbiAocmFuZ2UpIHsKICAgICAgICAgICAgaWYgKHRoaXMuaW50ZXJzZWN0c1JhbmdlKHJhbmdlLCB0cnVlKSkgewogICAgICAgICAgICAgICAgdmFyIHVuaW9uUmFuZ2UgPSB0aGlzLmNsb25lUmFuZ2UoKTsKICAgICAgICAgICAgICAgIGlmIChkb20uY29tcGFyZVBvaW50cyhyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQsIHRoaXMuc3RhcnRDb250YWluZXIsIHRoaXMuc3RhcnRPZmZzZXQpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgdW5pb25SYW5nZS5zZXRTdGFydChyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGRvbS5jb21wYXJlUG9pbnRzKHJhbmdlLmVuZENvbnRhaW5lciwgcmFuZ2UuZW5kT2Zmc2V0LCB0aGlzLmVuZENvbnRhaW5lciwgdGhpcy5lbmRPZmZzZXQpID09IDEpIHsKICAgICAgICAgICAgICAgICAgICB1bmlvblJhbmdlLnNldEVuZChyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gdW5pb25SYW5nZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUV4Y2VwdGlvbigiUmFuZ2VzIGRvIG5vdCBpbnRlcnNlY3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNvbnRhaW5zTm9kZSA6IGZ1bmN0aW9uIChub2RlLCBhbGxvd1BhcnRpYWwpIHsKICAgICAgICAgICAgaWYgKGFsbG93UGFydGlhbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJzZWN0c05vZGUobm9kZSwgZmFsc2UpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZU5vZGUobm9kZSkgPT0gbl9pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgY29udGFpbnNOb2RlQ29udGVudHMgOiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5jb21wYXJlUG9pbnQobm9kZSwgMCkgPj0gMCAmJiB0aGlzLmNvbXBhcmVQb2ludChub2RlLCBkb20uZ2V0Tm9kZUxlbmd0aChub2RlKSkgPD0gMDsKICAgICAgICB9LAoKICAgICAgICBjb250YWluc1JhbmdlIDogZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmludGVyc2VjdGlvbihyYW5nZSkuZXF1YWxzKHJhbmdlKTsKICAgICAgICB9LAoKICAgICAgICBjb250YWluc05vZGVUZXh0IDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgdmFyIG5vZGVSYW5nZSA9IHRoaXMuY2xvbmVSYW5nZSgpOwogICAgICAgICAgICBub2RlUmFuZ2Uuc2VsZWN0Tm9kZShub2RlKTsKICAgICAgICAgICAgdmFyIHRleHROb2RlcyA9IG5vZGVSYW5nZS5nZXROb2RlcyhbM10pOwogICAgICAgICAgICBpZiAodGV4dE5vZGVzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIG5vZGVSYW5nZS5zZXRTdGFydCh0ZXh0Tm9kZXNbMF0sIDApOwogICAgICAgICAgICAgICAgdmFyIGxhc3RUZXh0Tm9kZSA9IHRleHROb2Rlcy5wb3AoKTsKICAgICAgICAgICAgICAgIG5vZGVSYW5nZS5zZXRFbmQobGFzdFRleHROb2RlLCBsYXN0VGV4dE5vZGUubGVuZ3RoKTsKICAgICAgICAgICAgICAgIHZhciBjb250YWlucyA9IHRoaXMuY29udGFpbnNSYW5nZShub2RlUmFuZ2UpOwogICAgICAgICAgICAgICAgbm9kZVJhbmdlLmRldGFjaCgpOwogICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRhaW5zOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGFpbnNOb2RlQ29udGVudHMobm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBjcmVhdGVOb2RlSXRlcmF0b3IgOiBmdW5jdGlvbiAobm9kZVR5cGVzLCBmaWx0ZXIpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBSYW5nZU5vZGVJdGVyYXRvcih0aGlzLCBub2RlVHlwZXMsIGZpbHRlcik7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0Tm9kZXMgOiBmdW5jdGlvbiAobm9kZVR5cGVzLCBmaWx0ZXIpIHsKICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgcmV0dXJuIGdldE5vZGVzSW5SYW5nZSh0aGlzLCBub2RlVHlwZXMsIGZpbHRlcik7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RG9jdW1lbnQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBnZXRSYW5nZURvY3VtZW50KHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIGNvbGxhcHNlQmVmb3JlIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgYXNzZXJ0Tm90RGV0YWNoZWQodGhpcyk7CgogICAgICAgICAgICB0aGlzLnNldEVuZEJlZm9yZShub2RlKTsKICAgICAgICAgICAgdGhpcy5jb2xsYXBzZShmYWxzZSk7CiAgICAgICAgfSwKCiAgICAgICAgY29sbGFwc2VBZnRlciA6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgIGFzc2VydE5vdERldGFjaGVkKHRoaXMpOwoKICAgICAgICAgICAgdGhpcy5zZXRTdGFydEFmdGVyKG5vZGUpOwogICAgICAgICAgICB0aGlzLmNvbGxhcHNlKHRydWUpOwogICAgICAgIH0sCgogICAgICAgIGdldE5hbWUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAiRG9tUmFuZ2UiOwogICAgICAgIH0sCgogICAgICAgIGVxdWFscyA6IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgICAgICByZXR1cm4gUmFuZ2UucmFuZ2VzRXF1YWwodGhpcywgcmFuZ2UpOwogICAgICAgIH0sCgogICAgICAgIGluc3BlY3QgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0KHRoaXMpOwogICAgICAgIH0KICAgIH07CgogICAgZnVuY3Rpb24gY29weUNvbXBhcmlzb25Db25zdGFudHNUb09iamVjdChvYmopIHsKICAgICAgICBvYmouU1RBUlRfVE9fU1RBUlQgPSBzMnM7CiAgICAgICAgb2JqLlNUQVJUX1RPX0VORCA9IHMyZTsKICAgICAgICBvYmouRU5EX1RPX0VORCA9IGUyZTsKICAgICAgICBvYmouRU5EX1RPX1NUQVJUID0gZTJzOwoKICAgICAgICBvYmouTk9ERV9CRUZPUkUgPSBuX2I7CiAgICAgICAgb2JqLk5PREVfQUZURVIgPSBuX2E7CiAgICAgICAgb2JqLk5PREVfQkVGT1JFX0FORF9BRlRFUiA9IG5fYl9hOwogICAgICAgIG9iai5OT0RFX0lOU0lERSA9IG5faTsKICAgIH0KCiAgICBmdW5jdGlvbiBjb3B5Q29tcGFyaXNvbkNvbnN0YW50cyhjb25zdHJ1Y3RvcikgewogICAgICAgIGNvcHlDb21wYXJpc29uQ29uc3RhbnRzVG9PYmplY3QoY29uc3RydWN0b3IpOwogICAgICAgIGNvcHlDb21wYXJpc29uQ29uc3RhbnRzVG9PYmplY3QoY29uc3RydWN0b3IucHJvdG90eXBlKTsKICAgIH0KCiAgICBmdW5jdGlvbiBjcmVhdGVSYW5nZUNvbnRlbnRSZW1vdmVyKHJlbW92ZXIsIGJvdW5kYXJ5VXBkYXRlcikgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGFzc2VydFJhbmdlVmFsaWQodGhpcyk7CgogICAgICAgICAgICB2YXIgc2MgPSB0aGlzLnN0YXJ0Q29udGFpbmVyLCBzbyA9IHRoaXMuc3RhcnRPZmZzZXQsIHJvb3QgPSB0aGlzLmNvbW1vbkFuY2VzdG9yQ29udGFpbmVyOwoKICAgICAgICAgICAgdmFyIGl0ZXJhdG9yID0gbmV3IFJhbmdlSXRlcmF0b3IodGhpcywgdHJ1ZSk7CgogICAgICAgICAgICAvLyBXb3JrIG91dCB3aGVyZSB0byBwb3NpdGlvbiB0aGUgcmFuZ2UgYWZ0ZXIgY29udGVudCByZW1vdmFsCiAgICAgICAgICAgIHZhciBub2RlLCBib3VuZGFyeTsKICAgICAgICAgICAgaWYgKHNjICE9PSByb290KSB7CiAgICAgICAgICAgICAgICBub2RlID0gZG9tLmdldENsb3Nlc3RBbmNlc3RvckluKHNjLCByb290LCB0cnVlKTsKICAgICAgICAgICAgICAgIGJvdW5kYXJ5ID0gZ2V0Qm91bmRhcnlBZnRlck5vZGUobm9kZSk7CiAgICAgICAgICAgICAgICBzYyA9IGJvdW5kYXJ5Lm5vZGU7CiAgICAgICAgICAgICAgICBzbyA9IGJvdW5kYXJ5Lm9mZnNldDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2hlY2sgbm9uZSBvZiB0aGUgcmFuZ2UgaXMgcmVhZC1vbmx5CiAgICAgICAgICAgIGl0ZXJhdGVTdWJ0cmVlKGl0ZXJhdG9yLCBhc3NlcnROb2RlTm90UmVhZE9ubHkpOwoKICAgICAgICAgICAgaXRlcmF0b3IucmVzZXQoKTsKCiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgY29udGVudAogICAgICAgICAgICB2YXIgcmV0dXJuVmFsdWUgPSByZW1vdmVyKGl0ZXJhdG9yKTsKICAgICAgICAgICAgaXRlcmF0b3IuZGV0YWNoKCk7CgogICAgICAgICAgICAvLyBNb3ZlIHRvIHRoZSBuZXcgcG9zaXRpb24KICAgICAgICAgICAgYm91bmRhcnlVcGRhdGVyKHRoaXMsIHNjLCBzbywgc2MsIHNvKTsKCiAgICAgICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTsKICAgICAgICB9OwogICAgfQoKICAgIGZ1bmN0aW9uIGNyZWF0ZVByb3RvdHlwZVJhbmdlKGNvbnN0cnVjdG9yLCBib3VuZGFyeVVwZGF0ZXIsIGRldGFjaGVyKSB7CiAgICAgICAgZnVuY3Rpb24gY3JlYXRlQmVmb3JlQWZ0ZXJOb2RlU2V0dGVyKGlzQmVmb3JlLCBpc1N0YXJ0KSB7CiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICAgICAgYXNzZXJ0Tm90RGV0YWNoZWQodGhpcyk7CiAgICAgICAgICAgICAgICBhc3NlcnRWYWxpZE5vZGVUeXBlKG5vZGUsIGJlZm9yZUFmdGVyTm9kZVR5cGVzKTsKICAgICAgICAgICAgICAgIGFzc2VydFZhbGlkTm9kZVR5cGUoZ2V0Um9vdENvbnRhaW5lcihub2RlKSwgcm9vdENvbnRhaW5lck5vZGVUeXBlcyk7CgogICAgICAgICAgICAgICAgdmFyIGJvdW5kYXJ5ID0gKGlzQmVmb3JlID8gZ2V0Qm91bmRhcnlCZWZvcmVOb2RlIDogZ2V0Qm91bmRhcnlBZnRlck5vZGUpKG5vZGUpOwogICAgICAgICAgICAgICAgKGlzU3RhcnQgPyBzZXRSYW5nZVN0YXJ0IDogc2V0UmFuZ2VFbmQpKHRoaXMsIGJvdW5kYXJ5Lm5vZGUsIGJvdW5kYXJ5Lm9mZnNldCk7CiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBzZXRSYW5nZVN0YXJ0KHJhbmdlLCBub2RlLCBvZmZzZXQpIHsKICAgICAgICAgICAgdmFyIGVjID0gcmFuZ2UuZW5kQ29udGFpbmVyLCBlbyA9IHJhbmdlLmVuZE9mZnNldDsKICAgICAgICAgICAgaWYgKG5vZGUgIT09IHJhbmdlLnN0YXJ0Q29udGFpbmVyIHx8IG9mZnNldCAhPT0gcmFuZ2Uuc3RhcnRPZmZzZXQpIHsKICAgICAgICAgICAgICAgIC8vIENoZWNrIHRoZSByb290IGNvbnRhaW5lcnMgb2YgdGhlIHJhbmdlIGFuZCB0aGUgbmV3IGJvdW5kYXJ5LCBhbmQgYWxzbyBjaGVjayB3aGV0aGVyIHRoZSBuZXcgYm91bmRhcnkKICAgICAgICAgICAgICAgIC8vIGlzIGFmdGVyIHRoZSBjdXJyZW50IGVuZC4gSW4gZWl0aGVyIGNhc2UsIGNvbGxhcHNlIHRoZSByYW5nZSB0byB0aGUgbmV3IHBvc2l0aW9uCiAgICAgICAgICAgICAgICBpZiAoZ2V0Um9vdENvbnRhaW5lcihub2RlKSAhPSBnZXRSb290Q29udGFpbmVyKGVjKSB8fCBkb20uY29tcGFyZVBvaW50cyhub2RlLCBvZmZzZXQsIGVjLCBlbykgPT0gMSkgewogICAgICAgICAgICAgICAgICAgIGVjID0gbm9kZTsKICAgICAgICAgICAgICAgICAgICBlbyA9IG9mZnNldDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJvdW5kYXJ5VXBkYXRlcihyYW5nZSwgbm9kZSwgb2Zmc2V0LCBlYywgZW8pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBzZXRSYW5nZUVuZChyYW5nZSwgbm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgICAgIHZhciBzYyA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyLCBzbyA9IHJhbmdlLnN0YXJ0T2Zmc2V0OwogICAgICAgICAgICBpZiAobm9kZSAhPT0gcmFuZ2UuZW5kQ29udGFpbmVyIHx8IG9mZnNldCAhPT0gcmFuZ2UuZW5kT2Zmc2V0KSB7CiAgICAgICAgICAgICAgICAvLyBDaGVjayB0aGUgcm9vdCBjb250YWluZXJzIG9mIHRoZSByYW5nZSBhbmQgdGhlIG5ldyBib3VuZGFyeSwgYW5kIGFsc28gY2hlY2sgd2hldGhlciB0aGUgbmV3IGJvdW5kYXJ5CiAgICAgICAgICAgICAgICAvLyBpcyBhZnRlciB0aGUgY3VycmVudCBlbmQuIEluIGVpdGhlciBjYXNlLCBjb2xsYXBzZSB0aGUgcmFuZ2UgdG8gdGhlIG5ldyBwb3NpdGlvbgogICAgICAgICAgICAgICAgaWYgKGdldFJvb3RDb250YWluZXIobm9kZSkgIT0gZ2V0Um9vdENvbnRhaW5lcihzYykgfHwgZG9tLmNvbXBhcmVQb2ludHMobm9kZSwgb2Zmc2V0LCBzYywgc28pID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgc2MgPSBub2RlOwogICAgICAgICAgICAgICAgICAgIHNvID0gb2Zmc2V0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYm91bmRhcnlVcGRhdGVyKHJhbmdlLCBzYywgc28sIG5vZGUsIG9mZnNldCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIHNldFJhbmdlU3RhcnRBbmRFbmQocmFuZ2UsIG5vZGUsIG9mZnNldCkgewogICAgICAgICAgICBpZiAobm9kZSAhPT0gcmFuZ2Uuc3RhcnRDb250YWluZXIgfHwgb2Zmc2V0ICE9PSByYW5nZS5zdGFydE9mZnNldCB8fCBub2RlICE9PSByYW5nZS5lbmRDb250YWluZXIgfHwgb2Zmc2V0ICE9PSByYW5nZS5lbmRPZmZzZXQpIHsKICAgICAgICAgICAgICAgIGJvdW5kYXJ5VXBkYXRlcihyYW5nZSwgbm9kZSwgb2Zmc2V0LCBub2RlLCBvZmZzZXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBuZXcgUmFuZ2VQcm90b3R5cGUoKTsKCiAgICAgICAgYXBpLnV0aWwuZXh0ZW5kKGNvbnN0cnVjdG9yLnByb3RvdHlwZSwgewogICAgICAgICAgICBzZXRTdGFydCA6IGZ1bmN0aW9uIChub2RlLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAgIGFzc2VydE5vdERldGFjaGVkKHRoaXMpOwogICAgICAgICAgICAgICAgYXNzZXJ0Tm9Eb2NUeXBlTm90YXRpb25FbnRpdHlBbmNlc3Rvcihub2RlLCB0cnVlKTsKICAgICAgICAgICAgICAgIGFzc2VydFZhbGlkT2Zmc2V0KG5vZGUsIG9mZnNldCk7CgogICAgICAgICAgICAgICAgc2V0UmFuZ2VTdGFydCh0aGlzLCBub2RlLCBvZmZzZXQpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2V0RW5kIDogZnVuY3Rpb24gKG5vZGUsIG9mZnNldCkgewogICAgICAgICAgICAgICAgYXNzZXJ0Tm90RGV0YWNoZWQodGhpcyk7CiAgICAgICAgICAgICAgICBhc3NlcnROb0RvY1R5cGVOb3RhdGlvbkVudGl0eUFuY2VzdG9yKG5vZGUsIHRydWUpOwogICAgICAgICAgICAgICAgYXNzZXJ0VmFsaWRPZmZzZXQobm9kZSwgb2Zmc2V0KTsKCiAgICAgICAgICAgICAgICBzZXRSYW5nZUVuZCh0aGlzLCBub2RlLCBvZmZzZXQpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2V0U3RhcnRCZWZvcmUgOiBjcmVhdGVCZWZvcmVBZnRlck5vZGVTZXR0ZXIodHJ1ZSwgdHJ1ZSksCiAgICAgICAgICAgIHNldFN0YXJ0QWZ0ZXIgOiBjcmVhdGVCZWZvcmVBZnRlck5vZGVTZXR0ZXIoZmFsc2UsIHRydWUpLAogICAgICAgICAgICBzZXRFbmRCZWZvcmUgOiBjcmVhdGVCZWZvcmVBZnRlck5vZGVTZXR0ZXIodHJ1ZSwgZmFsc2UpLAogICAgICAgICAgICBzZXRFbmRBZnRlciA6IGNyZWF0ZUJlZm9yZUFmdGVyTm9kZVNldHRlcihmYWxzZSwgZmFsc2UpLAoKICAgICAgICAgICAgY29sbGFwc2UgOiBmdW5jdGlvbiAoaXNTdGFydCkgewogICAgICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKICAgICAgICAgICAgICAgIGlmIChpc1N0YXJ0KSB7CiAgICAgICAgICAgICAgICAgICAgYm91bmRhcnlVcGRhdGVyKHRoaXMsIHRoaXMuc3RhcnRDb250YWluZXIsIHRoaXMuc3RhcnRPZmZzZXQsIHRoaXMuc3RhcnRDb250YWluZXIsIHRoaXMuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBib3VuZGFyeVVwZGF0ZXIodGhpcywgdGhpcy5lbmRDb250YWluZXIsIHRoaXMuZW5kT2Zmc2V0LCB0aGlzLmVuZENvbnRhaW5lciwgdGhpcy5lbmRPZmZzZXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2VsZWN0Tm9kZUNvbnRlbnRzIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgICAgIC8vIFRoaXMgZG9lc24ndCBzZWVtIHdlbGwgc3BlY2lmaWVkOiB0aGUgc3BlYyB0YWxrcyBvbmx5IGFib3V0IHNlbGVjdGluZyB0aGUgbm9kZSdzIGNvbnRlbnRzLCB3aGljaAogICAgICAgICAgICAgICAgLy8gY291bGQgYmUgdGFrZW4gdG8gbWVhbiBvbmx5IGl0cyBjaGlsZHJlbi4gSG93ZXZlciwgYnJvd3NlcnMgaW1wbGVtZW50IHRoaXMgdGhlIHNhbWUgYXMgc2VsZWN0Tm9kZSBmb3IKICAgICAgICAgICAgICAgIC8vIHRleHQgbm9kZXMsIHNvIEkgc2hhbGwgZG8gbGlrZXdpc2UKICAgICAgICAgICAgICAgIGFzc2VydE5vdERldGFjaGVkKHRoaXMpOwogICAgICAgICAgICAgICAgYXNzZXJ0Tm9Eb2NUeXBlTm90YXRpb25FbnRpdHlBbmNlc3Rvcihub2RlLCB0cnVlKTsKCiAgICAgICAgICAgICAgICBib3VuZGFyeVVwZGF0ZXIodGhpcywgbm9kZSwgMCwgbm9kZSwgZG9tLmdldE5vZGVMZW5ndGgobm9kZSkpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2VsZWN0Tm9kZSA6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICBhc3NlcnROb3REZXRhY2hlZCh0aGlzKTsKICAgICAgICAgICAgICAgIGFzc2VydE5vRG9jVHlwZU5vdGF0aW9uRW50aXR5QW5jZXN0b3Iobm9kZSwgZmFsc2UpOwogICAgICAgICAgICAgICAgYXNzZXJ0VmFsaWROb2RlVHlwZShub2RlLCBiZWZvcmVBZnRlck5vZGVUeXBlcyk7CgogICAgICAgICAgICAgICAgdmFyIHN0YXJ0ID0gZ2V0Qm91bmRhcnlCZWZvcmVOb2RlKG5vZGUpLCBlbmQgPSBnZXRCb3VuZGFyeUFmdGVyTm9kZShub2RlKTsKICAgICAgICAgICAgICAgIGJvdW5kYXJ5VXBkYXRlcih0aGlzLCBzdGFydC5ub2RlLCBzdGFydC5vZmZzZXQsIGVuZC5ub2RlLCBlbmQub2Zmc2V0KTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGV4dHJhY3RDb250ZW50cyA6IGNyZWF0ZVJhbmdlQ29udGVudFJlbW92ZXIoZXh0cmFjdFN1YnRyZWUsIGJvdW5kYXJ5VXBkYXRlciksCgogICAgICAgICAgICBkZWxldGVDb250ZW50cyA6IGNyZWF0ZVJhbmdlQ29udGVudFJlbW92ZXIoZGVsZXRlU3VidHJlZSwgYm91bmRhcnlVcGRhdGVyKSwKCiAgICAgICAgICAgIGNhblN1cnJvdW5kQ29udGVudHMgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBhc3NlcnRSYW5nZVZhbGlkKHRoaXMpOwogICAgICAgICAgICAgICAgYXNzZXJ0Tm9kZU5vdFJlYWRPbmx5KHRoaXMuc3RhcnRDb250YWluZXIpOwogICAgICAgICAgICAgICAgYXNzZXJ0Tm9kZU5vdFJlYWRPbmx5KHRoaXMuZW5kQ29udGFpbmVyKTsKCiAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgY29udGVudHMgY2FuIGJlIHN1cnJvdW5kZWQuIFNwZWNpZmljYWxseSwgdGhpcyBtZWFucyB3aGV0aGVyIHRoZSByYW5nZSBwYXJ0aWFsbHkgc2VsZWN0cwogICAgICAgICAgICAgICAgLy8gbm8gbm9uLXRleHQgbm9kZXMuCiAgICAgICAgICAgICAgICB2YXIgaXRlcmF0b3IgPSBuZXcgUmFuZ2VJdGVyYXRvcih0aGlzLCB0cnVlKTsKICAgICAgICAgICAgICAgIHZhciBib3VuZGFyaWVzSW52YWxpZCA9IChpdGVyYXRvci5fZmlyc3QgJiYgKGlzTm9uVGV4dFBhcnRpYWxseVNlbGVjdGVkKGl0ZXJhdG9yLl9maXJzdCwgdGhpcykpIHx8CiAgICAgICAgICAgICAgICAoaXRlcmF0b3IuX2xhc3QgJiYgaXNOb25UZXh0UGFydGlhbGx5U2VsZWN0ZWQoaXRlcmF0b3IuX2xhc3QsIHRoaXMpKSk7CiAgICAgICAgICAgICAgICBpdGVyYXRvci5kZXRhY2goKTsKICAgICAgICAgICAgICAgIHJldHVybiAhYm91bmRhcmllc0ludmFsaWQ7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBkZXRhY2ggOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBkZXRhY2hlcih0aGlzKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHNwbGl0Qm91bmRhcmllcyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGFzc2VydFJhbmdlVmFsaWQodGhpcyk7CgogICAgICAgICAgICAgICAgdmFyIHNjID0gdGhpcy5zdGFydENvbnRhaW5lciwgc28gPSB0aGlzLnN0YXJ0T2Zmc2V0LCBlYyA9IHRoaXMuZW5kQ29udGFpbmVyLCBlbyA9IHRoaXMuZW5kT2Zmc2V0OwogICAgICAgICAgICAgICAgdmFyIHN0YXJ0RW5kU2FtZSA9IChzYyA9PT0gZWMpOwoKICAgICAgICAgICAgICAgIGlmIChkb20uaXNDaGFyYWN0ZXJEYXRhTm9kZShlYykgJiYgZW8gPCBlYy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBkb20uc3BsaXREYXRhTm9kZShlYywgZW8pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChkb20uaXNDaGFyYWN0ZXJEYXRhTm9kZShzYykgJiYgc28gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgc2MgPSBkb20uc3BsaXREYXRhTm9kZShzYywgc28pOwogICAgICAgICAgICAgICAgICAgIGlmIChzdGFydEVuZFNhbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZW8gLT0gc287CiAgICAgICAgICAgICAgICAgICAgICAgIGVjID0gc2M7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlYyA9PSBzYy5wYXJlbnROb2RlICYmIGVvID49IGRvbS5nZXROb2RlSW5kZXgoc2MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVvKys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHNvID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJvdW5kYXJ5VXBkYXRlcih0aGlzLCBzYywgc28sIGVjLCBlbyk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBub3JtYWxpemVCb3VuZGFyaWVzIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgYXNzZXJ0UmFuZ2VWYWxpZCh0aGlzKTsKCiAgICAgICAgICAgICAgICB2YXIgc2MgPSB0aGlzLnN0YXJ0Q29udGFpbmVyLCBzbyA9IHRoaXMuc3RhcnRPZmZzZXQsIGVjID0gdGhpcy5lbmRDb250YWluZXIsIGVvID0gdGhpcy5lbmRPZmZzZXQ7CgogICAgICAgICAgICAgICAgdmFyIG1lcmdlRm9yd2FyZCA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHNpYmxpbmcgPSBub2RlLm5leHRTaWJsaW5nOwogICAgICAgICAgICAgICAgICAgIGlmIChzaWJsaW5nICYmIHNpYmxpbmcubm9kZVR5cGUgPT0gbm9kZS5ub2RlVHlwZSkgewogICAgICAgICAgICAgICAgICAgICAgICBlYyA9IG5vZGU7CiAgICAgICAgICAgICAgICAgICAgICAgIGVvID0gbm9kZS5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuYXBwZW5kRGF0YShzaWJsaW5nLmRhdGEpOwogICAgICAgICAgICAgICAgICAgICAgICBzaWJsaW5nLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc2libGluZyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICB2YXIgbWVyZ2VCYWNrd2FyZCA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHNpYmxpbmcgPSBub2RlLnByZXZpb3VzU2libGluZzsKICAgICAgICAgICAgICAgICAgICBpZiAoc2libGluZyAmJiBzaWJsaW5nLm5vZGVUeXBlID09IG5vZGUubm9kZVR5cGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2MgPSBub2RlOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZUxlbmd0aCA9IG5vZGUubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICBzbyA9IHNpYmxpbmcubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICBub2RlLmluc2VydERhdGEoMCwgc2libGluZy5kYXRhKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2libGluZy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHNpYmxpbmcpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2MgPT0gZWMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVvICs9IHNvOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWMgPSBzYzsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlYyA9PSBub2RlLnBhcmVudE5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlSW5kZXggPSBkb20uZ2V0Tm9kZUluZGV4KG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVvID09IG5vZGVJbmRleCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVjID0gbm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbyA9IG5vZGVMZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVvID4gbm9kZUluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW8tLTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgdmFyIG5vcm1hbGl6ZVN0YXJ0ID0gdHJ1ZTsKCiAgICAgICAgICAgICAgICBpZiAoZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUoZWMpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVjLmxlbmd0aCA9PSBlbykgewogICAgICAgICAgICAgICAgICAgICAgICBtZXJnZUZvcndhcmQoZWMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVvID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZW5kTm9kZSA9IGVjLmNoaWxkTm9kZXNbZW8gLSAxXTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVuZE5vZGUgJiYgZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUoZW5kTm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lcmdlRm9yd2FyZChlbmROb2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVTdGFydCA9ICF0aGlzLmNvbGxhcHNlZDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAobm9ybWFsaXplU3RhcnQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUoc2MpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzbyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXJnZUJhY2t3YXJkKHNjKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzbyA8IHNjLmNoaWxkTm9kZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RhcnROb2RlID0gc2MuY2hpbGROb2Rlc1tzb107CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhcnROb2RlICYmIGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKHN0YXJ0Tm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXJnZUJhY2t3YXJkKHN0YXJ0Tm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHNjID0gZWM7CiAgICAgICAgICAgICAgICAgICAgc28gPSBlbzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBib3VuZGFyeVVwZGF0ZXIodGhpcywgc2MsIHNvLCBlYywgZW8pOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgY29sbGFwc2VUb1BvaW50IDogZnVuY3Rpb24gKG5vZGUsIG9mZnNldCkgewogICAgICAgICAgICAgICAgYXNzZXJ0Tm90RGV0YWNoZWQodGhpcyk7CgogICAgICAgICAgICAgICAgYXNzZXJ0Tm9Eb2NUeXBlTm90YXRpb25FbnRpdHlBbmNlc3Rvcihub2RlLCB0cnVlKTsKICAgICAgICAgICAgICAgIGFzc2VydFZhbGlkT2Zmc2V0KG5vZGUsIG9mZnNldCk7CgogICAgICAgICAgICAgICAgc2V0UmFuZ2VTdGFydEFuZEVuZCh0aGlzLCBub2RlLCBvZmZzZXQpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIGNvcHlDb21wYXJpc29uQ29uc3RhbnRzKGNvbnN0cnVjdG9yKTsKICAgIH0KCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8vIFVwZGF0ZXMgY29tbW9uQW5jZXN0b3JDb250YWluZXIgYW5kIGNvbGxhcHNlZCBhZnRlciBib3VuZGFyeSBjaGFuZ2UKICAgIGZ1bmN0aW9uIHVwZGF0ZUNvbGxhcHNlZEFuZENvbW1vbkFuY2VzdG9yKHJhbmdlKSB7CiAgICAgICAgcmFuZ2UuY29sbGFwc2VkID0gKHJhbmdlLnN0YXJ0Q29udGFpbmVyID09PSByYW5nZS5lbmRDb250YWluZXIgJiYgcmFuZ2Uuc3RhcnRPZmZzZXQgPT09IHJhbmdlLmVuZE9mZnNldCk7CiAgICAgICAgcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIgPSByYW5nZS5jb2xsYXBzZWQgPwogICAgICAgICAgICByYW5nZS5zdGFydENvbnRhaW5lciA6IGRvbS5nZXRDb21tb25BbmNlc3RvcihyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2UuZW5kQ29udGFpbmVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiB1cGRhdGVCb3VuZGFyaWVzKHJhbmdlLCBzdGFydENvbnRhaW5lciwgc3RhcnRPZmZzZXQsIGVuZENvbnRhaW5lciwgZW5kT2Zmc2V0KSB7CiAgICAgICAgdmFyIHN0YXJ0TW92ZWQgPSAocmFuZ2Uuc3RhcnRDb250YWluZXIgIT09IHN0YXJ0Q29udGFpbmVyIHx8IHJhbmdlLnN0YXJ0T2Zmc2V0ICE9PSBzdGFydE9mZnNldCk7CiAgICAgICAgdmFyIGVuZE1vdmVkID0gKHJhbmdlLmVuZENvbnRhaW5lciAhPT0gZW5kQ29udGFpbmVyIHx8IHJhbmdlLmVuZE9mZnNldCAhPT0gZW5kT2Zmc2V0KTsKCiAgICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXIgPSBzdGFydENvbnRhaW5lcjsKICAgICAgICByYW5nZS5zdGFydE9mZnNldCA9IHN0YXJ0T2Zmc2V0OwogICAgICAgIHJhbmdlLmVuZENvbnRhaW5lciA9IGVuZENvbnRhaW5lcjsKICAgICAgICByYW5nZS5lbmRPZmZzZXQgPSBlbmRPZmZzZXQ7CgogICAgICAgIHVwZGF0ZUNvbGxhcHNlZEFuZENvbW1vbkFuY2VzdG9yKHJhbmdlKTsKICAgICAgICBkaXNwYXRjaEV2ZW50KHJhbmdlLCAiYm91bmRhcnljaGFuZ2UiLCB7c3RhcnRNb3ZlZCA6IHN0YXJ0TW92ZWQsIGVuZE1vdmVkIDogZW5kTW92ZWR9KTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZXRhY2gocmFuZ2UpIHsKICAgICAgICBhc3NlcnROb3REZXRhY2hlZChyYW5nZSk7CiAgICAgICAgcmFuZ2Uuc3RhcnRDb250YWluZXIgPSByYW5nZS5zdGFydE9mZnNldCA9IHJhbmdlLmVuZENvbnRhaW5lciA9IHJhbmdlLmVuZE9mZnNldCA9IG51bGw7CiAgICAgICAgcmFuZ2UuY29sbGFwc2VkID0gcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIgPSBudWxsOwogICAgICAgIGRpc3BhdGNoRXZlbnQocmFuZ2UsICJkZXRhY2giLCBudWxsKTsKICAgICAgICByYW5nZS5fbGlzdGVuZXJzID0gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIEBjb25zdHJ1Y3RvcgogICAgICovCiAgICBmdW5jdGlvbiBSYW5nZShkb2MpIHsKICAgICAgICB0aGlzLnN0YXJ0Q29udGFpbmVyID0gZG9jOwogICAgICAgIHRoaXMuc3RhcnRPZmZzZXQgPSAwOwogICAgICAgIHRoaXMuZW5kQ29udGFpbmVyID0gZG9jOwogICAgICAgIHRoaXMuZW5kT2Zmc2V0ID0gMDsKICAgICAgICB0aGlzLl9saXN0ZW5lcnMgPSB7CiAgICAgICAgICAgIGJvdW5kYXJ5Y2hhbmdlIDogW10sCiAgICAgICAgICAgIGRldGFjaCA6IFtdCiAgICAgICAgfTsKICAgICAgICB1cGRhdGVDb2xsYXBzZWRBbmRDb21tb25BbmNlc3Rvcih0aGlzKTsKICAgIH0KCiAgICBjcmVhdGVQcm90b3R5cGVSYW5nZShSYW5nZSwgdXBkYXRlQm91bmRhcmllcywgZGV0YWNoKTsKCiAgICBhcGkucmFuZ2VQcm90b3R5cGUgPSBSYW5nZVByb3RvdHlwZS5wcm90b3R5cGU7CgogICAgUmFuZ2UucmFuZ2VQcm9wZXJ0aWVzID0gcmFuZ2VQcm9wZXJ0aWVzOwogICAgUmFuZ2UuUmFuZ2VJdGVyYXRvciA9IFJhbmdlSXRlcmF0b3I7CiAgICBSYW5nZS5jb3B5Q29tcGFyaXNvbkNvbnN0YW50cyA9IGNvcHlDb21wYXJpc29uQ29uc3RhbnRzOwogICAgUmFuZ2UuY3JlYXRlUHJvdG90eXBlUmFuZ2UgPSBjcmVhdGVQcm90b3R5cGVSYW5nZTsKICAgIFJhbmdlLmluc3BlY3QgPSBpbnNwZWN0OwogICAgUmFuZ2UuZ2V0UmFuZ2VEb2N1bWVudCA9IGdldFJhbmdlRG9jdW1lbnQ7CiAgICBSYW5nZS5yYW5nZXNFcXVhbCA9IGZ1bmN0aW9uIChyMSwgcjIpIHsKICAgICAgICByZXR1cm4gcjEuc3RhcnRDb250YWluZXIgPT09IHIyLnN0YXJ0Q29udGFpbmVyICYmIHIxLnN0YXJ0T2Zmc2V0ID09PSByMi5zdGFydE9mZnNldCAmJiByMS5lbmRDb250YWluZXIgPT09IHIyLmVuZENvbnRhaW5lciAmJiByMS5lbmRPZmZzZXQgPT09IHIyLmVuZE9mZnNldDsKICAgIH07CgogICAgYXBpLkRvbVJhbmdlID0gUmFuZ2U7CiAgICBhcGkuUmFuZ2VFeGNlcHRpb24gPSBSYW5nZUV4Y2VwdGlvbjsKfSk7CnJhbmd5LmNyZWF0ZU1vZHVsZSgiV3JhcHBlZFJhbmdlIiwgZnVuY3Rpb24gKGFwaSwgbW9kdWxlKSB7CiAgICBhcGkucmVxdWlyZU1vZHVsZXMoWyJEb21VdGlsIiwgIkRvbVJhbmdlIl0pOwoKICAgIC8qKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKi8KICAgIHZhciBXcmFwcGVkUmFuZ2U7CiAgICB2YXIgZG9tID0gYXBpLmRvbTsKICAgIHZhciBEb21Qb3NpdGlvbiA9IGRvbS5Eb21Qb3NpdGlvbjsKICAgIHZhciBEb21SYW5nZSA9IGFwaS5Eb21SYW5nZTsKCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIC8qCiAgICAgVGhpcyBpcyBhIHdvcmthcm91bmQgZm9yIGEgYnVnIHdoZXJlIElFIHJldHVybnMgdGhlIHdyb25nIGNvbnRhaW5lciBlbGVtZW50IGZyb20gdGhlIFRleHRSYW5nZSdzIHBhcmVudEVsZW1lbnQoKQogICAgIG1ldGhvZC4gRm9yIGV4YW1wbGUsIGluIHRoZSBmb2xsb3dpbmcgKHdoZXJlIHBpcGVzIGRlbm90ZSB0aGUgc2VsZWN0aW9uIGJvdW5kYXJpZXMpOgoKICAgICA8dWwgaWQ9InVsIj48bGkgaWQ9ImEiPnwgYSA8L2xpPjxsaSBpZD0iYiI+IGIgfDwvbGk+PC91bD4KCiAgICAgdmFyIHJhbmdlID0gZG9jdW1lbnQuc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCk7CiAgICAgYWxlcnQocmFuZ2UucGFyZW50RWxlbWVudCgpLmlkKTsgLy8gU2hvdWxkIGFsZXJ0ICJ1bCIgYnV0IGFsZXJ0cyAiYiIKCiAgICAgVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgY29tbW9uIGFuY2VzdG9yIG5vZGUgb2YgdGhlIGZvbGxvd2luZzoKICAgICAtIHRoZSBwYXJlbnRFbGVtZW50KCkgb2YgdGhlIHRleHRSYW5nZQogICAgIC0gdGhlIHBhcmVudEVsZW1lbnQoKSBvZiB0aGUgdGV4dFJhbmdlIGFmdGVyIGNhbGxpbmcgY29sbGFwc2UodHJ1ZSkKICAgICAtIHRoZSBwYXJlbnRFbGVtZW50KCkgb2YgdGhlIHRleHRSYW5nZSBhZnRlciBjYWxsaW5nIGNvbGxhcHNlKGZhbHNlKQogICAgICovCiAgICBmdW5jdGlvbiBnZXRUZXh0UmFuZ2VDb250YWluZXJFbGVtZW50KHRleHRSYW5nZSkgewogICAgICAgIHZhciBwYXJlbnRFbCA9IHRleHRSYW5nZS5wYXJlbnRFbGVtZW50KCk7CgogICAgICAgIHZhciByYW5nZSA9IHRleHRSYW5nZS5kdXBsaWNhdGUoKTsKICAgICAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTsKICAgICAgICB2YXIgc3RhcnRFbCA9IHJhbmdlLnBhcmVudEVsZW1lbnQoKTsKICAgICAgICByYW5nZSA9IHRleHRSYW5nZS5kdXBsaWNhdGUoKTsKICAgICAgICByYW5nZS5jb2xsYXBzZShmYWxzZSk7CiAgICAgICAgdmFyIGVuZEVsID0gcmFuZ2UucGFyZW50RWxlbWVudCgpOwogICAgICAgIHZhciBzdGFydEVuZENvbnRhaW5lciA9IChzdGFydEVsID09IGVuZEVsKSA/IHN0YXJ0RWwgOiBkb20uZ2V0Q29tbW9uQW5jZXN0b3Ioc3RhcnRFbCwgZW5kRWwpOwoKICAgICAgICByZXR1cm4gc3RhcnRFbmRDb250YWluZXIgPT0gcGFyZW50RWwgPyBzdGFydEVuZENvbnRhaW5lciA6IGRvbS5nZXRDb21tb25BbmNlc3RvcihwYXJlbnRFbCwgc3RhcnRFbmRDb250YWluZXIpOwogICAgfQoKICAgIGZ1bmN0aW9uIHRleHRSYW5nZUlzQ29sbGFwc2VkKHRleHRSYW5nZSkgewogICAgICAgIHJldHVybiB0ZXh0UmFuZ2UuY29tcGFyZUVuZFBvaW50cygiU3RhcnRUb0VuZCIsIHRleHRSYW5nZSkgPT0gMDsKICAgIH0KCiAgICAvLyBHZXRzIHRoZSBib3VuZGFyeSBvZiBhIFRleHRSYW5nZSBleHByZXNzZWQgYXMgYSBub2RlIGFuZCBhbiBvZmZzZXQgd2l0aGluIHRoYXQgbm9kZS4gVGhpcyBmdW5jdGlvbiBzdGFydGVkIG91dCBhcwogICAgLy8gYW4gaW1wcm92ZWQgdmVyc2lvbiBvZiBjb2RlIGZvdW5kIGluIFRpbSBDYW1lcm9uIFJ5YW4ncyBJRVJhbmdlIChodHRwOi8vY29kZS5nb29nbGUuY29tL3AvaWVyYW5nZS8pIGJ1dCBoYXMKICAgIC8vIGdyb3duLCBmaXhpbmcgcHJvYmxlbXMgd2l0aCBsaW5lIGJyZWFrcyBpbiBwcmVmb3JtYXR0ZWQgdGV4dCwgYWRkaW5nIHdvcmthcm91bmQgZm9yIElFIFRleHRSYW5nZSBidWdzLCBoYW5kbGluZwogICAgLy8gZm9yIGlucHV0cyBhbmQgaW1hZ2VzLCBwbHVzIG9wdGltaXphdGlvbnMuCiAgICBmdW5jdGlvbiBnZXRUZXh0UmFuZ2VCb3VuZGFyeVBvc2l0aW9uKHRleHRSYW5nZSwgd2hvbGVSYW5nZUNvbnRhaW5lckVsZW1lbnQsIGlzU3RhcnQsIGlzQ29sbGFwc2VkKSB7CiAgICAgICAgdmFyIHdvcmtpbmdSYW5nZSA9IHRleHRSYW5nZS5kdXBsaWNhdGUoKTsKCiAgICAgICAgd29ya2luZ1JhbmdlLmNvbGxhcHNlKGlzU3RhcnQpOwogICAgICAgIHZhciBjb250YWluZXJFbGVtZW50ID0gd29ya2luZ1JhbmdlLnBhcmVudEVsZW1lbnQoKTsKCiAgICAgICAgLy8gU29tZXRpbWVzIGNvbGxhcHNpbmcgYSBUZXh0UmFuZ2UgdGhhdCdzIGF0IHRoZSBzdGFydCBvZiBhIHRleHQgbm9kZSBjYW4gbW92ZSBpdCBpbnRvIHRoZSBwcmV2aW91cyBub2RlLCBzbwogICAgICAgIC8vIGNoZWNrIGZvciB0aGF0CiAgICAgICAgLy8gVE9ETzogRmluZCBvdXQgd2hlbi4gV29ya2Fyb3VuZCBmb3Igd2hvbGVSYW5nZUNvbnRhaW5lckVsZW1lbnQgbWF5IGJyZWFrIHRoaXMKICAgICAgICBpZiAoIWRvbS5pc0FuY2VzdG9yT2Yod2hvbGVSYW5nZUNvbnRhaW5lckVsZW1lbnQsIGNvbnRhaW5lckVsZW1lbnQsIHRydWUpKSB7CiAgICAgICAgICAgIGNvbnRhaW5lckVsZW1lbnQgPSB3aG9sZVJhbmdlQ29udGFpbmVyRWxlbWVudDsKICAgICAgICB9CgogICAgICAgIC8vIERlYWwgd2l0aCBub2RlcyB0aGF0IGNhbm5vdCAiY29udGFpbiByaWNoIEhUTUwgbWFya3VwIi4gSW4gcHJhY3RpY2UsIHRoaXMgbWVhbnMgZm9ybSBpbnB1dHMsIGltYWdlcyBhbmQKICAgICAgICAvLyBzaW1pbGFyLiBTZWUgaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2FhNzAzOTUwJTI4VlMuODUlMjkuYXNweAogICAgICAgIGlmICghY29udGFpbmVyRWxlbWVudC5jYW5IYXZlSFRNTCkgewogICAgICAgICAgICByZXR1cm4gbmV3IERvbVBvc2l0aW9uKGNvbnRhaW5lckVsZW1lbnQucGFyZW50Tm9kZSwgZG9tLmdldE5vZGVJbmRleChjb250YWluZXJFbGVtZW50KSk7CiAgICAgICAgfQoKICAgICAgICB2YXIgd29ya2luZ05vZGUgPSBkb20uZ2V0RG9jdW1lbnQoY29udGFpbmVyRWxlbWVudCkuY3JlYXRlRWxlbWVudCgic3BhbiIpOwogICAgICAgIHZhciBjb21wYXJpc29uLCB3b3JraW5nQ29tcGFyaXNvblR5cGUgPSBpc1N0YXJ0ID8gIlN0YXJ0VG9TdGFydCIgOiAiU3RhcnRUb0VuZCI7CiAgICAgICAgdmFyIHByZXZpb3VzTm9kZSwgbmV4dE5vZGUsIGJvdW5kYXJ5UG9zaXRpb24sIGJvdW5kYXJ5Tm9kZTsKCiAgICAgICAgLy8gTW92ZSB0aGUgd29ya2luZyByYW5nZSB0aHJvdWdoIHRoZSBjb250YWluZXIncyBjaGlsZHJlbiwgc3RhcnRpbmcgYXQgdGhlIGVuZCBhbmQgd29ya2luZyBiYWNrd2FyZHMsIHVudGlsIHRoZQogICAgICAgIC8vIHdvcmtpbmcgcmFuZ2UgcmVhY2hlcyBvciBnb2VzIHBhc3QgdGhlIGJvdW5kYXJ5IHdlJ3JlIGludGVyZXN0ZWQgaW4KICAgICAgICBkbyB7CiAgICAgICAgICAgIGNvbnRhaW5lckVsZW1lbnQuaW5zZXJ0QmVmb3JlKHdvcmtpbmdOb2RlLCB3b3JraW5nTm9kZS5wcmV2aW91c1NpYmxpbmcpOwogICAgICAgICAgICB3b3JraW5nUmFuZ2UubW92ZVRvRWxlbWVudFRleHQod29ya2luZ05vZGUpOwogICAgICAgIH0gd2hpbGUgKChjb21wYXJpc29uID0gd29ya2luZ1JhbmdlLmNvbXBhcmVFbmRQb2ludHMod29ya2luZ0NvbXBhcmlzb25UeXBlLCB0ZXh0UmFuZ2UpKSA+IDAgJiYgd29ya2luZ05vZGUucHJldmlvdXNTaWJsaW5nKTsKCiAgICAgICAgLy8gV2UndmUgbm93IHJlYWNoZWQgb3IgZ29uZSBwYXN0IHRoZSBib3VuZGFyeSBvZiB0aGUgdGV4dCByYW5nZSB3ZSdyZSBpbnRlcmVzdGVkIGluCiAgICAgICAgLy8gc28gaGF2ZSBpZGVudGlmaWVkIHRoZSBub2RlIHdlIHdhbnQKICAgICAgICBib3VuZGFyeU5vZGUgPSB3b3JraW5nTm9kZS5uZXh0U2libGluZzsKCiAgICAgICAgaWYgKGNvbXBhcmlzb24gPT0gLTEgJiYgYm91bmRhcnlOb2RlICYmIGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKGJvdW5kYXJ5Tm9kZSkpIHsKICAgICAgICAgICAgLy8gVGhpcyBpcyBhIGNoYXJhY3RlciBkYXRhIG5vZGUgKHRleHQsIGNvbW1lbnQsIGNkYXRhKS4gVGhlIHdvcmtpbmcgcmFuZ2UgaXMgY29sbGFwc2VkIGF0IHRoZSBzdGFydCBvZiB0aGUKICAgICAgICAgICAgLy8gbm9kZSBjb250YWluaW5nIHRoZSB0ZXh0IHJhbmdlJ3MgYm91bmRhcnksIHNvIHdlIG1vdmUgdGhlIGVuZCBvZiB0aGUgd29ya2luZyByYW5nZSB0byB0aGUgYm91bmRhcnkgcG9pbnQKICAgICAgICAgICAgLy8gYW5kIG1lYXN1cmUgdGhlIGxlbmd0aCBvZiBpdHMgdGV4dCB0byBnZXQgdGhlIGJvdW5kYXJ5J3Mgb2Zmc2V0IHdpdGhpbiB0aGUgbm9kZS4KICAgICAgICAgICAgd29ya2luZ1JhbmdlLnNldEVuZFBvaW50KGlzU3RhcnQgPyAiRW5kVG9TdGFydCIgOiAiRW5kVG9FbmQiLCB0ZXh0UmFuZ2UpOwoKICAgICAgICAgICAgdmFyIG9mZnNldDsKCiAgICAgICAgICAgIGlmICgvW1xyXG5dLy50ZXN0KGJvdW5kYXJ5Tm9kZS5kYXRhKSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICBGb3IgdGhlIHBhcnRpY3VsYXIgY2FzZSBvZiBhIGJvdW5kYXJ5IHdpdGhpbiBhIHRleHQgbm9kZSBjb250YWluaW5nIGxpbmUgYnJlYWtzICh3aXRoaW4gYSA8cHJlPiBlbGVtZW50LAogICAgICAgICAgICAgICAgIGZvciBleGFtcGxlKSwgd2UgbmVlZCBhIHNsaWdodGx5IGNvbXBsaWNhdGVkIGFwcHJvYWNoIHRvIGdldCB0aGUgYm91bmRhcnkncyBvZmZzZXQgaW4gSUUuIFRoZSBmYWN0czoKCiAgICAgICAgICAgICAgICAgLSBFYWNoIGxpbmUgYnJlYWsgaXMgcmVwcmVzZW50ZWQgYXMgXHIgaW4gdGhlIHRleHQgbm9kZSdzIGRhdGEvbm9kZVZhbHVlIHByb3BlcnRpZXMKICAgICAgICAgICAgICAgICAtIEVhY2ggbGluZSBicmVhayBpcyByZXByZXNlbnRlZCBhcyBcclxuIGluIHRoZSBUZXh0UmFuZ2UncyAndGV4dCcgcHJvcGVydHkKICAgICAgICAgICAgICAgICAtIFRoZSAndGV4dCcgcHJvcGVydHkgb2YgdGhlIFRleHRSYW5nZSBkb2VzIG5vdCBjb250YWluIHRyYWlsaW5nIGxpbmUgYnJlYWtzCgogICAgICAgICAgICAgICAgIFRvIGdldCByb3VuZCB0aGUgcHJvYmxlbSBwcmVzZW50ZWQgYnkgdGhlIGZpbmFsIGZhY3QgYWJvdmUsIHdlIGNhbiB1c2UgdGhlIGZhY3QgdGhhdCBUZXh0UmFuZ2UncwogICAgICAgICAgICAgICAgIG1vdmVTdGFydCgpIGFuZCBtb3ZlRW5kKCkgbWV0aG9kcyByZXR1cm4gdGhlIGFjdHVhbCBudW1iZXIgb2YgY2hhcmFjdGVycyBtb3ZlZCwgd2hpY2ggaXMgbm90IG5lY2Vzc2FyaWx5CiAgICAgICAgICAgICAgICAgdGhlIHNhbWUgYXMgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGl0IHdhcyBpbnN0cnVjdGVkIHRvIG1vdmUuIFRoZSBzaW1wbGVzdCBhcHByb2FjaCBpcyB0byB1c2UgdGhpcyB0bwogICAgICAgICAgICAgICAgIHN0b3JlIHRoZSBjaGFyYWN0ZXJzIG1vdmVkIHdoZW4gbW92aW5nIGJvdGggdGhlIHN0YXJ0IGFuZCBlbmQgb2YgdGhlIHJhbmdlIHRvIHRoZSBzdGFydCBvZiB0aGUgZG9jdW1lbnQKICAgICAgICAgICAgICAgICBib2R5IGFuZCBzdWJ0cmFjdGluZyB0aGUgc3RhcnQgb2Zmc2V0IGZyb20gdGhlIGVuZCBvZmZzZXQgKHRoZSAibW92ZS1uZWdhdGl2ZS1nYXppbGxpb24iIG1ldGhvZCkuCiAgICAgICAgICAgICAgICAgSG93ZXZlciwgdGhpcyBpcyBleHRyZW1lbHkgc2xvdyB3aGVuIHRoZSBkb2N1bWVudCBpcyBsYXJnZSBhbmQgdGhlIHJhbmdlIGlzIG5lYXIgdGhlIGVuZCBvZiBpdC4gQ2xlYXJseQogICAgICAgICAgICAgICAgIGRvaW5nIHRoZSBtaXJyb3IgaW1hZ2UgKGkuZS4gbW92aW5nIHRoZSByYW5nZSBib3VuZGFyaWVzIHRvIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50KSBoYXMgdGhlIHNhbWUKICAgICAgICAgICAgICAgICBwcm9ibGVtLgoKICAgICAgICAgICAgICAgICBBbm90aGVyIGFwcHJvYWNoIHRoYXQgd29ya3MgaXMgdG8gdXNlIG1vdmVTdGFydCgpIHRvIG1vdmUgdGhlIHN0YXJ0IGJvdW5kYXJ5IG9mIHRoZSByYW5nZSB1cCB0byB0aGUgZW5kCiAgICAgICAgICAgICAgICAgYm91bmRhcnkgb25lIGNoYXJhY3RlciBhdCBhIHRpbWUgYW5kIGluY3JlbWVudGluZyBhIGNvdW50ZXIgd2l0aCB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIG1vdmVTdGFydCgpCiAgICAgICAgICAgICAgICAgY2FsbC4gSG93ZXZlciwgdGhlIGNoZWNrIGZvciB3aGV0aGVyIHRoZSBzdGFydCBib3VuZGFyeSBoYXMgcmVhY2hlZCB0aGUgZW5kIGJvdW5kYXJ5IGlzIGV4cGVuc2l2ZSwgc28KICAgICAgICAgICAgICAgICB0aGlzIG1ldGhvZCBpcyBzbG93IChhbHRob3VnaCB1bmxpa2UgIm1vdmUtbmVnYXRpdmUtZ2F6aWxsaW9uIiBpcyBsYXJnZWx5IHVuYWZmZWN0ZWQgYnkgdGhlIGxvY2F0aW9uIG9mCiAgICAgICAgICAgICAgICAgdGhlIHJhbmdlIHdpdGhpbiB0aGUgZG9jdW1lbnQpLgoKICAgICAgICAgICAgICAgICBUaGUgbWV0aG9kIGJlbG93IGlzIGEgaHlicmlkIG9mIHRoZSB0d28gbWV0aG9kcyBhYm92ZS4gSXQgdXNlcyB0aGUgZmFjdCB0aGF0IGEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlCiAgICAgICAgICAgICAgICAgVGV4dFJhbmdlJ3MgJ3RleHQnIHByb3BlcnR5IHdpdGggZWFjaCBcclxuIGNvbnZlcnRlZCB0byBhIHNpbmdsZSBcciBjaGFyYWN0ZXIgY2Fubm90IGJlIGxvbmdlciB0aGFuIHRoZQogICAgICAgICAgICAgICAgIHRleHQgb2YgdGhlIFRleHRSYW5nZSwgc28gdGhlIHN0YXJ0IG9mIHRoZSByYW5nZSBpcyBtb3ZlZCB0aGF0IGxlbmd0aCBpbml0aWFsbHkgYW5kIHRoZW4gYSBjaGFyYWN0ZXIgYXQKICAgICAgICAgICAgICAgICBhIHRpbWUgdG8gbWFrZSB1cCBmb3IgYW55IHRyYWlsaW5nIGxpbmUgYnJlYWtzIG5vdCBjb250YWluZWQgaW4gdGhlICd0ZXh0JyBwcm9wZXJ0eS4gVGhpcyBoYXMgZ29vZAogICAgICAgICAgICAgICAgIHBlcmZvcm1hbmNlIGluIG1vc3Qgc2l0dWF0aW9ucyBjb21wYXJlZCB0byB0aGUgcHJldmlvdXMgdHdvIG1ldGhvZHMuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHZhciB0ZW1wUmFuZ2UgPSB3b3JraW5nUmFuZ2UuZHVwbGljYXRlKCk7CiAgICAgICAgICAgICAgICB2YXIgcmFuZ2VMZW5ndGggPSB0ZW1wUmFuZ2UudGV4dC5yZXBsYWNlKC9cclxuL2csICJcciIpLmxlbmd0aDsKCiAgICAgICAgICAgICAgICBvZmZzZXQgPSB0ZW1wUmFuZ2UubW92ZVN0YXJ0KCJjaGFyYWN0ZXIiLCByYW5nZUxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoKGNvbXBhcmlzb24gPSB0ZW1wUmFuZ2UuY29tcGFyZUVuZFBvaW50cygiU3RhcnRUb0VuZCIsIHRlbXBSYW5nZSkpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0Kys7CiAgICAgICAgICAgICAgICAgICAgdGVtcFJhbmdlLm1vdmVTdGFydCgiY2hhcmFjdGVyIiwgMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBvZmZzZXQgPSB3b3JraW5nUmFuZ2UudGV4dC5sZW5ndGg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYm91bmRhcnlQb3NpdGlvbiA9IG5ldyBEb21Qb3NpdGlvbihib3VuZGFyeU5vZGUsIG9mZnNldCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gSWYgdGhlIGJvdW5kYXJ5IGltbWVkaWF0ZWx5IGZvbGxvd3MgYSBjaGFyYWN0ZXIgZGF0YSBub2RlIGFuZCB0aGlzIGlzIHRoZSBlbmQgYm91bmRhcnksIHdlIHNob3VsZCBmYXZvdXIKICAgICAgICAgICAgLy8gYSBwb3NpdGlvbiB3aXRoaW4gdGhhdCwgYW5kIGxpa2V3aXNlIGZvciBhIHN0YXJ0IGJvdW5kYXJ5IHByZWNlZGluZyBhIGNoYXJhY3RlciBkYXRhIG5vZGUKICAgICAgICAgICAgcHJldmlvdXNOb2RlID0gKGlzQ29sbGFwc2VkIHx8ICFpc1N0YXJ0KSAmJiB3b3JraW5nTm9kZS5wcmV2aW91c1NpYmxpbmc7CiAgICAgICAgICAgIG5leHROb2RlID0gKGlzQ29sbGFwc2VkIHx8IGlzU3RhcnQpICYmIHdvcmtpbmdOb2RlLm5leHRTaWJsaW5nOwoKICAgICAgICAgICAgaWYgKG5leHROb2RlICYmIGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKG5leHROb2RlKSkgewogICAgICAgICAgICAgICAgYm91bmRhcnlQb3NpdGlvbiA9IG5ldyBEb21Qb3NpdGlvbihuZXh0Tm9kZSwgMCk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAocHJldmlvdXNOb2RlICYmIGRvbS5pc0NoYXJhY3RlckRhdGFOb2RlKHByZXZpb3VzTm9kZSkpIHsKICAgICAgICAgICAgICAgIGJvdW5kYXJ5UG9zaXRpb24gPSBuZXcgRG9tUG9zaXRpb24ocHJldmlvdXNOb2RlLCBwcmV2aW91c05vZGUubGVuZ3RoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJvdW5kYXJ5UG9zaXRpb24gPSBuZXcgRG9tUG9zaXRpb24oY29udGFpbmVyRWxlbWVudCwgZG9tLmdldE5vZGVJbmRleCh3b3JraW5nTm9kZSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBDbGVhbiB1cAogICAgICAgIHdvcmtpbmdOb2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQod29ya2luZ05vZGUpOwoKICAgICAgICByZXR1cm4gYm91bmRhcnlQb3NpdGlvbjsKICAgIH0KCiAgICAvLyBSZXR1cm5zIGEgVGV4dFJhbmdlIHJlcHJlc2VudGluZyB0aGUgYm91bmRhcnkgb2YgYSBUZXh0UmFuZ2UgZXhwcmVzc2VkIGFzIGEgbm9kZSBhbmQgYW4gb2Zmc2V0IHdpdGhpbiB0aGF0IG5vZGUuCiAgICAvLyBUaGlzIGZ1bmN0aW9uIHN0YXJ0ZWQgb3V0IGFzIGFuIG9wdGltaXplZCB2ZXJzaW9uIG9mIGNvZGUgZm91bmQgaW4gVGltIENhbWVyb24gUnlhbidzIElFUmFuZ2UKICAgIC8vIChodHRwOi8vY29kZS5nb29nbGUuY29tL3AvaWVyYW5nZS8pCiAgICBmdW5jdGlvbiBjcmVhdGVCb3VuZGFyeVRleHRSYW5nZShib3VuZGFyeVBvc2l0aW9uLCBpc1N0YXJ0KSB7CiAgICAgICAgdmFyIGJvdW5kYXJ5Tm9kZSwgYm91bmRhcnlQYXJlbnQsIGJvdW5kYXJ5T2Zmc2V0ID0gYm91bmRhcnlQb3NpdGlvbi5vZmZzZXQ7CiAgICAgICAgdmFyIGRvYyA9IGRvbS5nZXREb2N1bWVudChib3VuZGFyeVBvc2l0aW9uLm5vZGUpOwogICAgICAgIHZhciB3b3JraW5nTm9kZSwgY2hpbGROb2Rlcywgd29ya2luZ1JhbmdlID0gZG9jLmJvZHkuY3JlYXRlVGV4dFJhbmdlKCk7CiAgICAgICAgdmFyIG5vZGVJc0RhdGFOb2RlID0gZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUoYm91bmRhcnlQb3NpdGlvbi5ub2RlKTsKCiAgICAgICAgaWYgKG5vZGVJc0RhdGFOb2RlKSB7CiAgICAgICAgICAgIGJvdW5kYXJ5Tm9kZSA9IGJvdW5kYXJ5UG9zaXRpb24ubm9kZTsKICAgICAgICAgICAgYm91bmRhcnlQYXJlbnQgPSBib3VuZGFyeU5vZGUucGFyZW50Tm9kZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjaGlsZE5vZGVzID0gYm91bmRhcnlQb3NpdGlvbi5ub2RlLmNoaWxkTm9kZXM7CiAgICAgICAgICAgIGJvdW5kYXJ5Tm9kZSA9IChib3VuZGFyeU9mZnNldCA8IGNoaWxkTm9kZXMubGVuZ3RoKSA/IGNoaWxkTm9kZXNbYm91bmRhcnlPZmZzZXRdIDogbnVsbDsKICAgICAgICAgICAgYm91bmRhcnlQYXJlbnQgPSBib3VuZGFyeVBvc2l0aW9uLm5vZGU7CiAgICAgICAgfQoKICAgICAgICAvLyBQb3NpdGlvbiB0aGUgcmFuZ2UgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBub2RlIGNvbnRhaW5pbmcgdGhlIGJvdW5kYXJ5CiAgICAgICAgd29ya2luZ05vZGUgPSBkb2MuY3JlYXRlRWxlbWVudCgic3BhbiIpOwoKICAgICAgICAvLyBNYWtpbmcgdGhlIHdvcmtpbmcgZWxlbWVudCBub24tZW1wdHkgZWxlbWVudCBwZXJzdWFkZXMgSUUgdG8gY29uc2lkZXIgdGhlIFRleHRSYW5nZSBib3VuZGFyeSB0byBiZSB3aXRoaW4gdGhlCiAgICAgICAgLy8gZWxlbWVudCByYXRoZXIgdGhhbiBpbW1lZGlhdGVseSBiZWZvcmUgb3IgYWZ0ZXIgaXQsIHdoaWNoIGlzIHdoYXQgd2Ugd2FudAogICAgICAgIHdvcmtpbmdOb2RlLmlubmVySFRNTCA9ICImI2ZlZmY7IjsKCiAgICAgICAgLy8gaW5zZXJ0QmVmb3JlIGlzIHN1cHBvc2VkIHRvIHdvcmsgbGlrZSBhcHBlbmRDaGlsZCBpZiB0aGUgc2Vjb25kIHBhcmFtZXRlciBpcyBudWxsLiBIb3dldmVyLCBhIGJ1ZyByZXBvcnQKICAgICAgICAvLyBmb3IgSUVSYW5nZSBzdWdnZXN0cyB0aGF0IGl0IGNhbiBjcmFzaCB0aGUgYnJvd3NlcjogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2llcmFuZ2UvaXNzdWVzL2RldGFpbD9pZD0xMgogICAgICAgIGlmIChib3VuZGFyeU5vZGUpIHsKICAgICAgICAgICAgYm91bmRhcnlQYXJlbnQuaW5zZXJ0QmVmb3JlKHdvcmtpbmdOb2RlLCBib3VuZGFyeU5vZGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGJvdW5kYXJ5UGFyZW50LmFwcGVuZENoaWxkKHdvcmtpbmdOb2RlKTsKICAgICAgICB9CgogICAgICAgIHdvcmtpbmdSYW5nZS5tb3ZlVG9FbGVtZW50VGV4dCh3b3JraW5nTm9kZSk7CiAgICAgICAgd29ya2luZ1JhbmdlLmNvbGxhcHNlKCFpc1N0YXJ0KTsKCiAgICAgICAgLy8gQ2xlYW4gdXAKICAgICAgICBib3VuZGFyeVBhcmVudC5yZW1vdmVDaGlsZCh3b3JraW5nTm9kZSk7CgogICAgICAgIC8vIE1vdmUgdGhlIHdvcmtpbmcgcmFuZ2UgdG8gdGhlIHRleHQgb2Zmc2V0LCBpZiByZXF1aXJlZAogICAgICAgIGlmIChub2RlSXNEYXRhTm9kZSkgewogICAgICAgICAgICB3b3JraW5nUmFuZ2VbaXNTdGFydCA/ICJtb3ZlU3RhcnQiIDogIm1vdmVFbmQiXSgiY2hhcmFjdGVyIiwgYm91bmRhcnlPZmZzZXQpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHdvcmtpbmdSYW5nZTsKICAgIH0KCiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgIGlmIChhcGkuZmVhdHVyZXMuaW1wbGVtZW50c0RvbVJhbmdlICYmICghYXBpLmZlYXR1cmVzLmltcGxlbWVudHNUZXh0UmFuZ2UgfHwgIWFwaS5jb25maWcucHJlZmVyVGV4dFJhbmdlKSkgewogICAgICAgIC8vIFRoaXMgaXMgYSB3cmFwcGVyIGFyb3VuZCB0aGUgYnJvd3NlcidzIG5hdGl2ZSBET00gUmFuZ2UuIEl0IGhhcyB0d28gYWltczoKICAgICAgICAvLyAtIFByb3ZpZGUgd29ya2Fyb3VuZHMgZm9yIHNwZWNpZmljIGJyb3dzZXIgYnVncwogICAgICAgIC8vIC0gcHJvdmlkZSBjb252ZW5pZW50IGV4dGVuc2lvbnMsIHdoaWNoIGFyZSBpbmhlcml0ZWQgZnJvbSBSYW5neSdzIERvbVJhbmdlCgogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciByYW5nZVByb3RvOwogICAgICAgICAgICB2YXIgcmFuZ2VQcm9wZXJ0aWVzID0gRG9tUmFuZ2UucmFuZ2VQcm9wZXJ0aWVzOwogICAgICAgICAgICB2YXIgY2FuU2V0UmFuZ2VTdGFydEFmdGVyRW5kOwoKICAgICAgICAgICAgZnVuY3Rpb24gdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHJhbmdlKSB7CiAgICAgICAgICAgICAgICB2YXIgaSA9IHJhbmdlUHJvcGVydGllcy5sZW5ndGgsIHByb3A7CiAgICAgICAgICAgICAgICB3aGlsZSAoaS0tKSB7CiAgICAgICAgICAgICAgICAgICAgcHJvcCA9IHJhbmdlUHJvcGVydGllc1tpXTsKICAgICAgICAgICAgICAgICAgICByYW5nZVtwcm9wXSA9IHJhbmdlLm5hdGl2ZVJhbmdlW3Byb3BdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBmdW5jdGlvbiB1cGRhdGVOYXRpdmVSYW5nZShyYW5nZSwgc3RhcnRDb250YWluZXIsIHN0YXJ0T2Zmc2V0LCBlbmRDb250YWluZXIsIGVuZE9mZnNldCkgewogICAgICAgICAgICAgICAgdmFyIHN0YXJ0TW92ZWQgPSAocmFuZ2Uuc3RhcnRDb250YWluZXIgIT09IHN0YXJ0Q29udGFpbmVyIHx8IHJhbmdlLnN0YXJ0T2Zmc2V0ICE9IHN0YXJ0T2Zmc2V0KTsKICAgICAgICAgICAgICAgIHZhciBlbmRNb3ZlZCA9IChyYW5nZS5lbmRDb250YWluZXIgIT09IGVuZENvbnRhaW5lciB8fCByYW5nZS5lbmRPZmZzZXQgIT0gZW5kT2Zmc2V0KTsKCiAgICAgICAgICAgICAgICAvLyBBbHdheXMgc2V0IGJvdGggYm91bmRhcmllcyBmb3IgdGhlIGJlbmVmaXQgb2YgSUU5IChzZWUgaXNzdWUgMzUpCiAgICAgICAgICAgICAgICBpZiAoc3RhcnRNb3ZlZCB8fCBlbmRNb3ZlZCkgewogICAgICAgICAgICAgICAgICAgIHJhbmdlLnNldEVuZChlbmRDb250YWluZXIsIGVuZE9mZnNldCk7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2Uuc2V0U3RhcnQoc3RhcnRDb250YWluZXIsIHN0YXJ0T2Zmc2V0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgZnVuY3Rpb24gZGV0YWNoKHJhbmdlKSB7CiAgICAgICAgICAgICAgICByYW5nZS5uYXRpdmVSYW5nZS5kZXRhY2goKTsKICAgICAgICAgICAgICAgIHJhbmdlLmRldGFjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHZhciBpID0gcmFuZ2VQcm9wZXJ0aWVzLmxlbmd0aCwgcHJvcDsKICAgICAgICAgICAgICAgIHdoaWxlIChpLS0pIHsKICAgICAgICAgICAgICAgICAgICBwcm9wID0gcmFuZ2VQcm9wZXJ0aWVzW2ldOwogICAgICAgICAgICAgICAgICAgIHJhbmdlW3Byb3BdID0gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGNyZWF0ZUJlZm9yZUFmdGVyTm9kZVNldHRlcjsKCiAgICAgICAgICAgIFdyYXBwZWRSYW5nZSA9IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgICAgICAgICAgaWYgKCFyYW5nZSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiUmFuZ2UgbXVzdCBiZSBzcGVjaWZpZWQiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlUmFuZ2UgPSByYW5nZTsKICAgICAgICAgICAgICAgIHVwZGF0ZVJhbmdlUHJvcGVydGllcyh0aGlzKTsKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIERvbVJhbmdlLmNyZWF0ZVByb3RvdHlwZVJhbmdlKFdyYXBwZWRSYW5nZSwgdXBkYXRlTmF0aXZlUmFuZ2UsIGRldGFjaCk7CgogICAgICAgICAgICByYW5nZVByb3RvID0gV3JhcHBlZFJhbmdlLnByb3RvdHlwZTsKCiAgICAgICAgICAgIHJhbmdlUHJvdG8uc2VsZWN0Tm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZVJhbmdlLnNlbGVjdE5vZGUobm9kZSk7CiAgICAgICAgICAgICAgICB1cGRhdGVSYW5nZVByb3BlcnRpZXModGhpcyk7CiAgICAgICAgICAgIH07CgogICAgICAgICAgICByYW5nZVByb3RvLmRlbGV0ZUNvbnRlbnRzID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZS5kZWxldGVDb250ZW50cygpOwogICAgICAgICAgICAgICAgdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHRoaXMpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgcmFuZ2VQcm90by5leHRyYWN0Q29udGVudHMgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgZnJhZyA9IHRoaXMubmF0aXZlUmFuZ2UuZXh0cmFjdENvbnRlbnRzKCk7CiAgICAgICAgICAgICAgICB1cGRhdGVSYW5nZVByb3BlcnRpZXModGhpcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gZnJhZzsKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHJhbmdlUHJvdG8uY2xvbmVDb250ZW50cyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5hdGl2ZVJhbmdlLmNsb25lQ29udGVudHMoKTsKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIC8vIFRPRE86IFVudGlsIEkgY2FuIGZpbmQgYSB3YXkgdG8gcHJvZ3JhbW1hdGljYWxseSB0cmlnZ2VyIHRoZSBGaXJlZm94IGJ1ZyAoYXBwYXJlbnRseSBsb25nLXN0YW5kaW5nLCBzdGlsbAogICAgICAgICAgICAvLyBwcmVzZW50IGluIDMuNi44KSB0aGF0IHRocm93cyAiSW5kZXggb3Igc2l6ZSBpcyBuZWdhdGl2ZSBvciBncmVhdGVyIHRoYW4gdGhlIGFsbG93ZWQgYW1vdW50IiBmb3IKICAgICAgICAgICAgLy8gaW5zZXJ0Tm9kZSBpbiBzb21lIGNpcmN1bXN0YW5jZXMsIGFsbCBicm93c2VycyB3aWxsIGhhdmUgdG8gdXNlIHRoZSBSYW5neSdzIG93biBpbXBsZW1lbnRhdGlvbiBvZgogICAgICAgICAgICAvLyBpbnNlcnROb2RlLCB3aGljaCB3b3JrcyBidXQgaXMgYWxtb3N0IGNlcnRhaW5seSBzbG93ZXIgdGhhbiB0aGUgbmF0aXZlIGltcGxlbWVudGF0aW9uLgogICAgICAgICAgICAvKgogICAgICAgICAgICAgcmFuZ2VQcm90by5pbnNlcnROb2RlID0gZnVuY3Rpb24obm9kZSkgewogICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZS5pbnNlcnROb2RlKG5vZGUpOwogICAgICAgICAgICAgdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHRoaXMpOwogICAgICAgICAgICAgfTsKICAgICAgICAgICAgICovCgogICAgICAgICAgICByYW5nZVByb3RvLnN1cnJvdW5kQ29udGVudHMgPSBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZS5zdXJyb3VuZENvbnRlbnRzKG5vZGUpOwogICAgICAgICAgICAgICAgdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHRoaXMpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgcmFuZ2VQcm90by5jb2xsYXBzZSA9IGZ1bmN0aW9uIChpc1N0YXJ0KSB7CiAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZVJhbmdlLmNvbGxhcHNlKGlzU3RhcnQpOwogICAgICAgICAgICAgICAgdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHRoaXMpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgcmFuZ2VQcm90by5jbG9uZVJhbmdlID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBXcmFwcGVkUmFuZ2UodGhpcy5uYXRpdmVSYW5nZS5jbG9uZVJhbmdlKCkpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgcmFuZ2VQcm90by5yZWZyZXNoID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHRoaXMpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgcmFuZ2VQcm90by50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5hdGl2ZVJhbmdlLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIH07CgogICAgICAgICAgICAvLyBDcmVhdGUgdGVzdCByYW5nZSBhbmQgbm9kZSBmb3IgZmVhdHVyZSBkZXRlY3Rpb24KCiAgICAgICAgICAgIHZhciB0ZXN0VGV4dE5vZGUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgidGVzdCIpOwogICAgICAgICAgICBkb20uZ2V0Qm9keShkb2N1bWVudCkuYXBwZW5kQ2hpbGQodGVzdFRleHROb2RlKTsKICAgICAgICAgICAgdmFyIHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTsKCiAgICAgICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgICAgICAgICAgLy8gVGVzdCBmb3IgRmlyZWZveCAyIGJ1ZyB0aGF0IHByZXZlbnRzIG1vdmluZyB0aGUgc3RhcnQgb2YgYSBSYW5nZSB0byBhIHBvaW50IGFmdGVyIGl0cyBjdXJyZW50IGVuZCBhbmQKICAgICAgICAgICAgLy8gY29ycmVjdCBmb3IgaXQKCiAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0KHRlc3RUZXh0Tm9kZSwgMCk7CiAgICAgICAgICAgIHJhbmdlLnNldEVuZCh0ZXN0VGV4dE5vZGUsIDApOwoKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0KHRlc3RUZXh0Tm9kZSwgMSk7CiAgICAgICAgICAgICAgICBjYW5TZXRSYW5nZVN0YXJ0QWZ0ZXJFbmQgPSB0cnVlOwoKICAgICAgICAgICAgICAgIHJhbmdlUHJvdG8uc2V0U3RhcnQgPSBmdW5jdGlvbiAobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZS5zZXRTdGFydChub2RlLCBvZmZzZXQpOwogICAgICAgICAgICAgICAgICAgIHVwZGF0ZVJhbmdlUHJvcGVydGllcyh0aGlzKTsKICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgcmFuZ2VQcm90by5zZXRFbmQgPSBmdW5jdGlvbiAobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZS5zZXRFbmQobm9kZSwgb2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICB1cGRhdGVSYW5nZVByb3BlcnRpZXModGhpcyk7CiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIGNyZWF0ZUJlZm9yZUFmdGVyTm9kZVNldHRlciA9IGZ1bmN0aW9uIChuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlUmFuZ2VbbmFtZV0obm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZVJhbmdlUHJvcGVydGllcyh0aGlzKTsKICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsKCiAgICAgICAgICAgICAgICBjYW5TZXRSYW5nZVN0YXJ0QWZ0ZXJFbmQgPSBmYWxzZTsKCiAgICAgICAgICAgICAgICByYW5nZVByb3RvLnNldFN0YXJ0ID0gZnVuY3Rpb24gKG5vZGUsIG9mZnNldCkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlUmFuZ2Uuc2V0U3RhcnQobm9kZSwgb2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZVJhbmdlLnNldEVuZChub2RlLCBvZmZzZXQpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZVJhbmdlLnNldFN0YXJ0KG5vZGUsIG9mZnNldCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHVwZGF0ZVJhbmdlUHJvcGVydGllcyh0aGlzKTsKICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgcmFuZ2VQcm90by5zZXRFbmQgPSBmdW5jdGlvbiAobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZS5zZXRFbmQobm9kZSwgb2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZVJhbmdlLnNldFN0YXJ0KG5vZGUsIG9mZnNldCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlUmFuZ2Uuc2V0RW5kKG5vZGUsIG9mZnNldCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHVwZGF0ZVJhbmdlUHJvcGVydGllcyh0aGlzKTsKICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgY3JlYXRlQmVmb3JlQWZ0ZXJOb2RlU2V0dGVyID0gZnVuY3Rpb24gKG5hbWUsIG9wcG9zaXRlTmFtZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVSYW5nZVtuYW1lXShub2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlUmFuZ2Vbb3Bwb3NpdGVOYW1lXShub2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlUmFuZ2VbbmFtZV0obm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlUmFuZ2VQcm9wZXJ0aWVzKHRoaXMpOwogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgICAgICByYW5nZVByb3RvLnNldFN0YXJ0QmVmb3JlID0gY3JlYXRlQmVmb3JlQWZ0ZXJOb2RlU2V0dGVyKCJzZXRTdGFydEJlZm9yZSIsICJzZXRFbmRCZWZvcmUiKTsKICAgICAgICAgICAgcmFuZ2VQcm90by5zZXRTdGFydEFmdGVyID0gY3JlYXRlQmVmb3JlQWZ0ZXJOb2RlU2V0dGVyKCJzZXRTdGFydEFmdGVyIiwgInNldEVuZEFmdGVyIik7CiAgICAgICAgICAgIHJhbmdlUHJvdG8uc2V0RW5kQmVmb3JlID0gY3JlYXRlQmVmb3JlQWZ0ZXJOb2RlU2V0dGVyKCJzZXRFbmRCZWZvcmUiLCAic2V0U3RhcnRCZWZvcmUiKTsKICAgICAgICAgICAgcmFuZ2VQcm90by5zZXRFbmRBZnRlciA9IGNyZWF0ZUJlZm9yZUFmdGVyTm9kZVNldHRlcigic2V0RW5kQWZ0ZXIiLCAic2V0U3RhcnRBZnRlciIpOwoKICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgogICAgICAgICAgICAvLyBUZXN0IGZvciBhbmQgY29ycmVjdCBGaXJlZm94IDIgYmVoYXZpb3VyIHdpdGggc2VsZWN0Tm9kZUNvbnRlbnRzIG9uIHRleHQgbm9kZXM6IGl0IGNvbGxhcHNlcyB0aGUgcmFuZ2UgdG8KICAgICAgICAgICAgLy8gdGhlIDB0aCBjaGFyYWN0ZXIgb2YgdGhlIHRleHQgbm9kZQogICAgICAgICAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHModGVzdFRleHROb2RlKTsKICAgICAgICAgICAgaWYgKHJhbmdlLnN0YXJ0Q29udGFpbmVyID09IHRlc3RUZXh0Tm9kZSAmJiByYW5nZS5lbmRDb250YWluZXIgPT0gdGVzdFRleHROb2RlICYmIHJhbmdlLnN0YXJ0T2Zmc2V0ID09IDAgJiYgcmFuZ2UuZW5kT2Zmc2V0ID09IHRlc3RUZXh0Tm9kZS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHJhbmdlUHJvdG8uc2VsZWN0Tm9kZUNvbnRlbnRzID0gZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLm5hdGl2ZVJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhub2RlKTsKICAgICAgICAgICAgICAgICAgICB1cGRhdGVSYW5nZVByb3BlcnRpZXModGhpcyk7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmFuZ2VQcm90by5zZWxlY3ROb2RlQ29udGVudHMgPSBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhcnQobm9kZSwgMCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRFbmQobm9kZSwgRG9tUmFuZ2UuZ2V0RW5kT2Zmc2V0KG5vZGUpKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKICAgICAgICAgICAgLy8gVGVzdCBmb3IgV2ViS2l0IGJ1ZyB0aGF0IGhhcyB0aGUgYmVhaHZpb3VyIG9mIGNvbXBhcmVCb3VuZGFyeVBvaW50cyByb3VuZCB0aGUgd3Jvbmcgd2F5IGZvciBjb25zdGFudHMKICAgICAgICAgICAgLy8gU1RBUlRfVE9fRU5EIGFuZCBFTkRfVE9fU1RBUlQ6IGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0yMDczOAoKICAgICAgICAgICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKHRlc3RUZXh0Tm9kZSk7CiAgICAgICAgICAgIHJhbmdlLnNldEVuZCh0ZXN0VGV4dE5vZGUsIDMpOwoKICAgICAgICAgICAgdmFyIHJhbmdlMiA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgICAgIHJhbmdlMi5zZWxlY3ROb2RlQ29udGVudHModGVzdFRleHROb2RlKTsKICAgICAgICAgICAgcmFuZ2UyLnNldEVuZCh0ZXN0VGV4dE5vZGUsIDQpOwogICAgICAgICAgICByYW5nZTIuc2V0U3RhcnQodGVzdFRleHROb2RlLCAyKTsKCiAgICAgICAgICAgIGlmIChyYW5nZS5jb21wYXJlQm91bmRhcnlQb2ludHMocmFuZ2UuU1RBUlRfVE9fRU5ELCByYW5nZTIpID09IC0xICYKICAgICAgICAgICAgICAgIHJhbmdlLmNvbXBhcmVCb3VuZGFyeVBvaW50cyhyYW5nZS5FTkRfVE9fU1RBUlQsIHJhbmdlMikgPT0gMSkgewogICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgd3Jvbmcgd2F5IHJvdW5kLCBzbyBjb3JyZWN0IGZvciBpdAoKICAgICAgICAgICAgICAgIHJhbmdlUHJvdG8uY29tcGFyZUJvdW5kYXJ5UG9pbnRzID0gZnVuY3Rpb24gKHR5cGUsIHJhbmdlKSB7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2UgPSByYW5nZS5uYXRpdmVSYW5nZSB8fCByYW5nZTsKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PSByYW5nZS5TVEFSVF9UT19FTkQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IHJhbmdlLkVORF9UT19TVEFSVDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gcmFuZ2UuRU5EX1RPX1NUQVJUKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSByYW5nZS5TVEFSVF9UT19FTkQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5hdGl2ZVJhbmdlLmNvbXBhcmVCb3VuZGFyeVBvaW50cyh0eXBlLCByYW5nZSk7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmFuZ2VQcm90by5jb21wYXJlQm91bmRhcnlQb2ludHMgPSBmdW5jdGlvbiAodHlwZSwgcmFuZ2UpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uYXRpdmVSYW5nZS5jb21wYXJlQm91bmRhcnlQb2ludHModHlwZSwgcmFuZ2UubmF0aXZlUmFuZ2UgfHwgcmFuZ2UpOwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgogICAgICAgICAgICAvLyBUZXN0IGZvciBleGlzdGVuY2Ugb2YgY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IGFuZCBkZWxlZ2F0ZSB0byBpdCBpZiBpdCBleGlzdHMKICAgICAgICAgICAgaWYgKGFwaS51dGlsLmlzSG9zdE1ldGhvZChyYW5nZSwgImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIpKSB7CiAgICAgICAgICAgICAgICByYW5nZVByb3RvLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCA9IGZ1bmN0aW9uIChmcmFnbWVudFN0cikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5hdGl2ZVJhbmdlLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChmcmFnbWVudFN0cik7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCiAgICAgICAgICAgIC8vIENsZWFuIHVwCiAgICAgICAgICAgIGRvbS5nZXRCb2R5KGRvY3VtZW50KS5yZW1vdmVDaGlsZCh0ZXN0VGV4dE5vZGUpOwogICAgICAgICAgICByYW5nZS5kZXRhY2goKTsKICAgICAgICAgICAgcmFuZ2UyLmRldGFjaCgpOwogICAgICAgIH0pKCk7CgogICAgICAgIGFwaS5jcmVhdGVOYXRpdmVSYW5nZSA9IGZ1bmN0aW9uIChkb2MpIHsKICAgICAgICAgICAgZG9jID0gZG9jIHx8IGRvY3VtZW50OwogICAgICAgICAgICByZXR1cm4gZG9jLmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgfTsKICAgIH0gZWxzZSBpZiAoYXBpLmZlYXR1cmVzLmltcGxlbWVudHNUZXh0UmFuZ2UpIHsKICAgICAgICAvLyBUaGlzIGlzIGEgd3JhcHBlciBhcm91bmQgYSBUZXh0UmFuZ2UsIHByb3ZpZGluZyBmdWxsIERPTSBSYW5nZSBmdW5jdGlvbmFsaXR5IHVzaW5nIHJhbmd5J3MgRG9tUmFuZ2UgYXMgYQogICAgICAgIC8vIHByb3RvdHlwZQoKICAgICAgICBXcmFwcGVkUmFuZ2UgPSBmdW5jdGlvbiAodGV4dFJhbmdlKSB7CiAgICAgICAgICAgIHRoaXMudGV4dFJhbmdlID0gdGV4dFJhbmdlOwogICAgICAgICAgICB0aGlzLnJlZnJlc2goKTsKICAgICAgICB9OwoKICAgICAgICBXcmFwcGVkUmFuZ2UucHJvdG90eXBlID0gbmV3IERvbVJhbmdlKGRvY3VtZW50KTsKCiAgICAgICAgV3JhcHBlZFJhbmdlLnByb3RvdHlwZS5yZWZyZXNoID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgc3RhcnQsIGVuZDsKCiAgICAgICAgICAgIC8vIFRleHRSYW5nZSdzIHBhcmVudEVsZW1lbnQoKSBtZXRob2QgY2Fubm90IGJlIHRydXN0ZWQuIGdldFRleHRSYW5nZUNvbnRhaW5lckVsZW1lbnQoKSB3b3JrcyBhcm91bmQgdGhhdC4KICAgICAgICAgICAgdmFyIHJhbmdlQ29udGFpbmVyRWxlbWVudCA9IGdldFRleHRSYW5nZUNvbnRhaW5lckVsZW1lbnQodGhpcy50ZXh0UmFuZ2UpOwoKICAgICAgICAgICAgaWYgKHRleHRSYW5nZUlzQ29sbGFwc2VkKHRoaXMudGV4dFJhbmdlKSkgewogICAgICAgICAgICAgICAgZW5kID0gc3RhcnQgPSBnZXRUZXh0UmFuZ2VCb3VuZGFyeVBvc2l0aW9uKHRoaXMudGV4dFJhbmdlLCByYW5nZUNvbnRhaW5lckVsZW1lbnQsIHRydWUsIHRydWUpOwogICAgICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgICAgIHN0YXJ0ID0gZ2V0VGV4dFJhbmdlQm91bmRhcnlQb3NpdGlvbih0aGlzLnRleHRSYW5nZSwgcmFuZ2VDb250YWluZXJFbGVtZW50LCB0cnVlLCBmYWxzZSk7CiAgICAgICAgICAgICAgICBlbmQgPSBnZXRUZXh0UmFuZ2VCb3VuZGFyeVBvc2l0aW9uKHRoaXMudGV4dFJhbmdlLCByYW5nZUNvbnRhaW5lckVsZW1lbnQsIGZhbHNlLCBmYWxzZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuc2V0U3RhcnQoc3RhcnQubm9kZSwgc3RhcnQub2Zmc2V0KTsKICAgICAgICAgICAgdGhpcy5zZXRFbmQoZW5kLm5vZGUsIGVuZC5vZmZzZXQpOwogICAgICAgIH07CgogICAgICAgIERvbVJhbmdlLmNvcHlDb21wYXJpc29uQ29uc3RhbnRzKFdyYXBwZWRSYW5nZSk7CgogICAgICAgIC8vIEFkZCBXcmFwcGVkUmFuZ2UgYXMgdGhlIFJhbmdlIHByb3BlcnR5IG9mIHRoZSBnbG9iYWwgb2JqZWN0IHRvIGFsbG93IGV4cHJlc3Npb24gbGlrZSBSYW5nZS5FTkRfVE9fRU5EIHRvIHdvcmsKICAgICAgICB2YXIgZ2xvYmFsT2JqID0gKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSkoKTsKICAgICAgICBpZiAodHlwZW9mIGdsb2JhbE9iai5SYW5nZSA9PSAidW5kZWZpbmVkIikgewogICAgICAgICAgICBnbG9iYWxPYmouUmFuZ2UgPSBXcmFwcGVkUmFuZ2U7CiAgICAgICAgfQoKICAgICAgICBhcGkuY3JlYXRlTmF0aXZlUmFuZ2UgPSBmdW5jdGlvbiAoZG9jKSB7CiAgICAgICAgICAgIGRvYyA9IGRvYyB8fCBkb2N1bWVudDsKICAgICAgICAgICAgcmV0dXJuIGRvYy5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpOwogICAgICAgIH07CiAgICB9CgogICAgaWYgKGFwaS5mZWF0dXJlcy5pbXBsZW1lbnRzVGV4dFJhbmdlKSB7CiAgICAgICAgV3JhcHBlZFJhbmdlLnJhbmdlVG9UZXh0UmFuZ2UgPSBmdW5jdGlvbiAocmFuZ2UpIHsKICAgICAgICAgICAgaWYgKHJhbmdlLmNvbGxhcHNlZCkgewogICAgICAgICAgICAgICAgdmFyIHRyID0gY3JlYXRlQm91bmRhcnlUZXh0UmFuZ2UobmV3IERvbVBvc2l0aW9uKHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydE9mZnNldCksIHRydWUpOwoKICAgICAgICAgICAgICAgIHJldHVybiB0cjsKCiAgICAgICAgICAgICAgICAvL3JldHVybiBjcmVhdGVCb3VuZGFyeVRleHRSYW5nZShuZXcgRG9tUG9zaXRpb24ocmFuZ2Uuc3RhcnRDb250YWluZXIsIHJhbmdlLnN0YXJ0T2Zmc2V0KSwgdHJ1ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgc3RhcnRSYW5nZSA9IGNyZWF0ZUJvdW5kYXJ5VGV4dFJhbmdlKG5ldyBEb21Qb3NpdGlvbihyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpLCB0cnVlKTsKICAgICAgICAgICAgICAgIHZhciBlbmRSYW5nZSA9IGNyZWF0ZUJvdW5kYXJ5VGV4dFJhbmdlKG5ldyBEb21Qb3NpdGlvbihyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCksIGZhbHNlKTsKICAgICAgICAgICAgICAgIHZhciB0ZXh0UmFuZ2UgPSBkb20uZ2V0RG9jdW1lbnQocmFuZ2Uuc3RhcnRDb250YWluZXIpLmJvZHkuY3JlYXRlVGV4dFJhbmdlKCk7CiAgICAgICAgICAgICAgICB0ZXh0UmFuZ2Uuc2V0RW5kUG9pbnQoIlN0YXJ0VG9TdGFydCIsIHN0YXJ0UmFuZ2UpOwogICAgICAgICAgICAgICAgdGV4dFJhbmdlLnNldEVuZFBvaW50KCJFbmRUb0VuZCIsIGVuZFJhbmdlKTsKICAgICAgICAgICAgICAgIHJldHVybiB0ZXh0UmFuZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfQoKICAgIFdyYXBwZWRSYW5nZS5wcm90b3R5cGUuZ2V0TmFtZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gIldyYXBwZWRSYW5nZSI7CiAgICB9OwoKICAgIGFwaS5XcmFwcGVkUmFuZ2UgPSBXcmFwcGVkUmFuZ2U7CgogICAgYXBpLmNyZWF0ZVJhbmdlID0gZnVuY3Rpb24gKGRvYykgewogICAgICAgIGRvYyA9IGRvYyB8fCBkb2N1bWVudDsKICAgICAgICByZXR1cm4gbmV3IFdyYXBwZWRSYW5nZShhcGkuY3JlYXRlTmF0aXZlUmFuZ2UoZG9jKSk7CiAgICB9OwoKICAgIGFwaS5jcmVhdGVSYW5neVJhbmdlID0gZnVuY3Rpb24gKGRvYykgewogICAgICAgIGRvYyA9IGRvYyB8fCBkb2N1bWVudDsKICAgICAgICByZXR1cm4gbmV3IERvbVJhbmdlKGRvYyk7CiAgICB9OwoKICAgIGFwaS5jcmVhdGVJZnJhbWVSYW5nZSA9IGZ1bmN0aW9uIChpZnJhbWVFbCkgewogICAgICAgIHJldHVybiBhcGkuY3JlYXRlUmFuZ2UoZG9tLmdldElmcmFtZURvY3VtZW50KGlmcmFtZUVsKSk7CiAgICB9OwoKICAgIGFwaS5jcmVhdGVJZnJhbWVSYW5neVJhbmdlID0gZnVuY3Rpb24gKGlmcmFtZUVsKSB7CiAgICAgICAgcmV0dXJuIGFwaS5jcmVhdGVSYW5neVJhbmdlKGRvbS5nZXRJZnJhbWVEb2N1bWVudChpZnJhbWVFbCkpOwogICAgfTsKCiAgICBhcGkuYWRkQ3JlYXRlTWlzc2luZ05hdGl2ZUFwaUxpc3RlbmVyKGZ1bmN0aW9uICh3aW4pIHsKICAgICAgICB2YXIgZG9jID0gd2luLmRvY3VtZW50OwogICAgICAgIGlmICh0eXBlb2YgZG9jLmNyZWF0ZVJhbmdlID09ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgIGRvYy5jcmVhdGVSYW5nZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhcGkuY3JlYXRlUmFuZ2UodGhpcyk7CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGRvYyA9IHdpbiA9IG51bGw7CiAgICB9KTsKfSk7CnJhbmd5LmNyZWF0ZU1vZHVsZSgiV3JhcHBlZFNlbGVjdGlvbiIsIGZ1bmN0aW9uIChhcGksIG1vZHVsZSkgewogICAgLy8gVGhpcyB3aWxsIGNyZWF0ZSBhIHNlbGVjdGlvbiBvYmplY3Qgd3JhcHBlciB0aGF0IGZvbGxvd3MgdGhlIFNlbGVjdGlvbiBvYmplY3QgZm91bmQgaW4gdGhlIFdIQVRXRyBkcmFmdCBET00gUmFuZ2UKICAgIC8vIHNwZWMgKGh0dHA6Ly9odG1sNS5vcmcvc3BlY3MvZG9tLXJhbmdlLmh0bWwpCgogICAgYXBpLnJlcXVpcmVNb2R1bGVzKFsiRG9tVXRpbCIsICJEb21SYW5nZSIsICJXcmFwcGVkUmFuZ2UiXSk7CgogICAgYXBpLmNvbmZpZy5jaGVja1NlbGVjdGlvblJhbmdlcyA9IHRydWU7CgogICAgdmFyIEJPT0xFQU4gPSAiYm9vbGVhbiIsCiAgICAgICAgd2luZG93UHJvcGVydHlOYW1lID0gIl9yYW5neVNlbGVjdGlvbiIsCiAgICAgICAgZG9tID0gYXBpLmRvbSwKICAgICAgICB1dGlsID0gYXBpLnV0aWwsCiAgICAgICAgRG9tUmFuZ2UgPSBhcGkuRG9tUmFuZ2UsCiAgICAgICAgV3JhcHBlZFJhbmdlID0gYXBpLldyYXBwZWRSYW5nZSwKICAgICAgICBET01FeGNlcHRpb24gPSBhcGkuRE9NRXhjZXB0aW9uLAogICAgICAgIERvbVBvc2l0aW9uID0gZG9tLkRvbVBvc2l0aW9uLAogICAgICAgIGdldFNlbGVjdGlvbiwKICAgICAgICBzZWxlY3Rpb25Jc0NvbGxhcHNlZCwKICAgICAgICBDT05UUk9MID0gIkNvbnRyb2wiOwoKICAgIGZ1bmN0aW9uIGdldFdpblNlbGVjdGlvbih3aW5QYXJhbSkgewogICAgICAgIHJldHVybiAod2luUGFyYW0gfHwgd2luZG93KS5nZXRTZWxlY3Rpb24oKTsKICAgIH0KCiAgICBmdW5jdGlvbiBnZXREb2NTZWxlY3Rpb24od2luUGFyYW0pIHsKICAgICAgICByZXR1cm4gKHdpblBhcmFtIHx8IHdpbmRvdykuZG9jdW1lbnQuc2VsZWN0aW9uOwogICAgfQoKICAgIC8vIFRlc3QgZm9yIHRoZSBSYW5nZS9UZXh0UmFuZ2UgYW5kIFNlbGVjdGlvbiBmZWF0dXJlcyByZXF1aXJlZAogICAgLy8gVGVzdCBmb3IgYWJpbGl0eSB0byByZXRyaWV2ZSBzZWxlY3Rpb24KICAgIHZhciBpbXBsZW1lbnRzV2luR2V0U2VsZWN0aW9uID0gYXBpLnV0aWwuaXNIb3N0TWV0aG9kKHdpbmRvdywgImdldFNlbGVjdGlvbiIpLAogICAgICAgIGltcGxlbWVudHNEb2NTZWxlY3Rpb24gPSBhcGkudXRpbC5pc0hvc3RPYmplY3QoZG9jdW1lbnQsICJzZWxlY3Rpb24iKTsKCiAgICB2YXIgdXNlRG9jdW1lbnRTZWxlY3Rpb24gPSBpbXBsZW1lbnRzRG9jU2VsZWN0aW9uICYmICghaW1wbGVtZW50c1dpbkdldFNlbGVjdGlvbiB8fCBhcGkuY29uZmlnLnByZWZlclRleHRSYW5nZSk7CgogICAgaWYgKHVzZURvY3VtZW50U2VsZWN0aW9uKSB7CiAgICAgICAgZ2V0U2VsZWN0aW9uID0gZ2V0RG9jU2VsZWN0aW9uOwogICAgICAgIGFwaS5pc1NlbGVjdGlvblZhbGlkID0gZnVuY3Rpb24gKHdpblBhcmFtKSB7CiAgICAgICAgICAgIHZhciBkb2MgPSAod2luUGFyYW0gfHwgd2luZG93KS5kb2N1bWVudCwgbmF0aXZlU2VsID0gZG9jLnNlbGVjdGlvbjsKCiAgICAgICAgICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIHNlbGVjdGlvbiBUZXh0UmFuZ2UgaXMgYWN0dWFsbHkgY29udGFpbmVkIHdpdGhpbiB0aGUgY29ycmVjdCBkb2N1bWVudAogICAgICAgICAgICByZXR1cm4gKG5hdGl2ZVNlbC50eXBlICE9ICJOb25lIiB8fCBkb20uZ2V0RG9jdW1lbnQobmF0aXZlU2VsLmNyZWF0ZVJhbmdlKCkucGFyZW50RWxlbWVudCgpKSA9PSBkb2MpOwogICAgICAgIH07CiAgICB9IGVsc2UgaWYgKGltcGxlbWVudHNXaW5HZXRTZWxlY3Rpb24pIHsKICAgICAgICBnZXRTZWxlY3Rpb24gPSBnZXRXaW5TZWxlY3Rpb247CiAgICAgICAgYXBpLmlzU2VsZWN0aW9uVmFsaWQgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIG1vZHVsZS5mYWlsKCJOZWl0aGVyIGRvY3VtZW50LnNlbGVjdGlvbiBvciB3aW5kb3cuZ2V0U2VsZWN0aW9uKCkgZGV0ZWN0ZWQuIik7CiAgICB9CgogICAgYXBpLmdldE5hdGl2ZVNlbGVjdGlvbiA9IGdldFNlbGVjdGlvbjsKCiAgICB2YXIgdGVzdFNlbGVjdGlvbiA9IGdldFNlbGVjdGlvbigpOwogICAgdmFyIHRlc3RSYW5nZSA9IGFwaS5jcmVhdGVOYXRpdmVSYW5nZShkb2N1bWVudCk7CiAgICB2YXIgYm9keSA9IGRvbS5nZXRCb2R5KGRvY3VtZW50KTsKCiAgICAvLyBPYnRhaW5pbmcgYSByYW5nZSBmcm9tIGEgc2VsZWN0aW9uCiAgICB2YXIgc2VsZWN0aW9uSGFzQW5jaG9yQW5kRm9jdXMgPSB1dGlsLmFyZUhvc3RPYmplY3RzKHRlc3RTZWxlY3Rpb24sIFsiYW5jaG9yTm9kZSIsICJmb2N1c05vZGUiXSAmJiB1dGlsLmFyZUhvc3RQcm9wZXJ0aWVzKHRlc3RTZWxlY3Rpb24sIFsiYW5jaG9yT2Zmc2V0IiwgImZvY3VzT2Zmc2V0Il0pKTsKICAgIGFwaS5mZWF0dXJlcy5zZWxlY3Rpb25IYXNBbmNob3JBbmRGb2N1cyA9IHNlbGVjdGlvbkhhc0FuY2hvckFuZEZvY3VzOwoKICAgIC8vIFRlc3QgZm9yIGV4aXN0ZW5jZSBvZiBuYXRpdmUgc2VsZWN0aW9uIGV4dGVuZCgpIG1ldGhvZAogICAgdmFyIHNlbGVjdGlvbkhhc0V4dGVuZCA9IHV0aWwuaXNIb3N0TWV0aG9kKHRlc3RTZWxlY3Rpb24sICJleHRlbmQiKTsKICAgIGFwaS5mZWF0dXJlcy5zZWxlY3Rpb25IYXNFeHRlbmQgPSBzZWxlY3Rpb25IYXNFeHRlbmQ7CgogICAgLy8gVGVzdCBpZiByYW5nZUNvdW50IGV4aXN0cwogICAgdmFyIHNlbGVjdGlvbkhhc1JhbmdlQ291bnQgPSAodHlwZW9mIHRlc3RTZWxlY3Rpb24ucmFuZ2VDb3VudCA9PSAibnVtYmVyIik7CiAgICBhcGkuZmVhdHVyZXMuc2VsZWN0aW9uSGFzUmFuZ2VDb3VudCA9IHNlbGVjdGlvbkhhc1JhbmdlQ291bnQ7CgogICAgdmFyIHNlbGVjdGlvblN1cHBvcnRzTXVsdGlwbGVSYW5nZXMgPSBmYWxzZTsKICAgIHZhciBjb2xsYXBzZWROb25FZGl0YWJsZVNlbGVjdGlvbnNTdXBwb3J0ZWQgPSB0cnVlOwoKICAgIGlmICh1dGlsLmFyZUhvc3RNZXRob2RzKHRlc3RTZWxlY3Rpb24sIFsiYWRkUmFuZ2UiLCAiZ2V0UmFuZ2VBdCIsICJyZW1vdmVBbGxSYW5nZXMiXSkgJiYgdHlwZW9mIHRlc3RTZWxlY3Rpb24ucmFuZ2VDb3VudCA9PSAibnVtYmVyIiAmJiBhcGkuZmVhdHVyZXMuaW1wbGVtZW50c0RvbVJhbmdlKSB7CgogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJpZnJhbWUiKTsKICAgICAgICAgICAgYm9keS5hcHBlbmRDaGlsZChpZnJhbWUpOwoKICAgICAgICAgICAgdmFyIGlmcmFtZURvYyA9IGRvbS5nZXRJZnJhbWVEb2N1bWVudChpZnJhbWUpOwogICAgICAgICAgICBpZnJhbWVEb2Mub3BlbigpOwogICAgICAgICAgICBpZnJhbWVEb2Mud3JpdGUoIjxodG1sPjxoZWFkPjwvaGVhZD48Ym9keT4xMjwvYm9keT48L2h0bWw+Iik7CiAgICAgICAgICAgIGlmcmFtZURvYy5jbG9zZSgpOwoKICAgICAgICAgICAgdmFyIHNlbCA9IGRvbS5nZXRJZnJhbWVXaW5kb3coaWZyYW1lKS5nZXRTZWxlY3Rpb24oKTsKICAgICAgICAgICAgdmFyIGRvY0VsID0gaWZyYW1lRG9jLmRvY3VtZW50RWxlbWVudDsKICAgICAgICAgICAgdmFyIGlmcmFtZUJvZHkgPSBkb2NFbC5sYXN0Q2hpbGQsIHRleHROb2RlID0gaWZyYW1lQm9keS5maXJzdENoaWxkOwoKICAgICAgICAgICAgLy8gVGVzdCB3aGV0aGVyIHRoZSBuYXRpdmUgc2VsZWN0aW9uIHdpbGwgYWxsb3cgYSBjb2xsYXBzZWQgc2VsZWN0aW9uIHdpdGhpbiBhIG5vbi1lZGl0YWJsZSBlbGVtZW50CiAgICAgICAgICAgIHZhciByMSA9IGlmcmFtZURvYy5jcmVhdGVSYW5nZSgpOwogICAgICAgICAgICByMS5zZXRTdGFydCh0ZXh0Tm9kZSwgMSk7CiAgICAgICAgICAgIHIxLmNvbGxhcHNlKHRydWUpOwogICAgICAgICAgICBzZWwuYWRkUmFuZ2UocjEpOwogICAgICAgICAgICBjb2xsYXBzZWROb25FZGl0YWJsZVNlbGVjdGlvbnNTdXBwb3J0ZWQgPSAoc2VsLnJhbmdlQ291bnQgPT0gMSk7CiAgICAgICAgICAgIHNlbC5yZW1vdmVBbGxSYW5nZXMoKTsKCiAgICAgICAgICAgIC8vIFRlc3Qgd2hldGhlciB0aGUgbmF0aXZlIHNlbGVjdGlvbiBpcyBjYXBhYmxlIG9mIHN1cHBvcnRpbmcgbXVsdGlwbGUgcmFuZ2VzCiAgICAgICAgICAgIHZhciByMiA9IHIxLmNsb25lUmFuZ2UoKTsKICAgICAgICAgICAgcjEuc2V0U3RhcnQodGV4dE5vZGUsIDApOwogICAgICAgICAgICByMi5zZXRFbmQodGV4dE5vZGUsIDIpOwogICAgICAgICAgICBzZWwuYWRkUmFuZ2UocjEpOwogICAgICAgICAgICBzZWwuYWRkUmFuZ2UocjIpOwoKICAgICAgICAgICAgc2VsZWN0aW9uU3VwcG9ydHNNdWx0aXBsZVJhbmdlcyA9IChzZWwucmFuZ2VDb3VudCA9PSAyKTsKCiAgICAgICAgICAgIC8vIENsZWFuIHVwCiAgICAgICAgICAgIHIxLmRldGFjaCgpOwogICAgICAgICAgICByMi5kZXRhY2goKTsKCiAgICAgICAgICAgIGJvZHkucmVtb3ZlQ2hpbGQoaWZyYW1lKTsKICAgICAgICB9KSgpOwogICAgfQoKICAgIGFwaS5mZWF0dXJlcy5zZWxlY3Rpb25TdXBwb3J0c011bHRpcGxlUmFuZ2VzID0gc2VsZWN0aW9uU3VwcG9ydHNNdWx0aXBsZVJhbmdlczsKICAgIGFwaS5mZWF0dXJlcy5jb2xsYXBzZWROb25FZGl0YWJsZVNlbGVjdGlvbnNTdXBwb3J0ZWQgPSBjb2xsYXBzZWROb25FZGl0YWJsZVNlbGVjdGlvbnNTdXBwb3J0ZWQ7CgogICAgLy8gQ29udHJvbFJhbmdlcwogICAgdmFyIGltcGxlbWVudHNDb250cm9sUmFuZ2UgPSBmYWxzZSwgdGVzdENvbnRyb2xSYW5nZTsKCiAgICBpZiAoYm9keSAmJiB1dGlsLmlzSG9zdE1ldGhvZChib2R5LCAiY3JlYXRlQ29udHJvbFJhbmdlIikpIHsKICAgICAgICB0ZXN0Q29udHJvbFJhbmdlID0gYm9keS5jcmVhdGVDb250cm9sUmFuZ2UoKTsKICAgICAgICBpZiAodXRpbC5hcmVIb3N0UHJvcGVydGllcyh0ZXN0Q29udHJvbFJhbmdlLCBbIml0ZW0iLCAiYWRkIl0pKSB7CiAgICAgICAgICAgIGltcGxlbWVudHNDb250cm9sUmFuZ2UgPSB0cnVlOwogICAgICAgIH0KICAgIH0KICAgIGFwaS5mZWF0dXJlcy5pbXBsZW1lbnRzQ29udHJvbFJhbmdlID0gaW1wbGVtZW50c0NvbnRyb2xSYW5nZTsKCiAgICAvLyBTZWxlY3Rpb24gY29sbGFwc2VkbmVzcwogICAgaWYgKHNlbGVjdGlvbkhhc0FuY2hvckFuZEZvY3VzKSB7CiAgICAgICAgc2VsZWN0aW9uSXNDb2xsYXBzZWQgPSBmdW5jdGlvbiAoc2VsKSB7CiAgICAgICAgICAgIHJldHVybiBzZWwuYW5jaG9yTm9kZSA9PT0gc2VsLmZvY3VzTm9kZSAmJiBzZWwuYW5jaG9yT2Zmc2V0ID09PSBzZWwuZm9jdXNPZmZzZXQ7CiAgICAgICAgfTsKICAgIH0gZWxzZSB7CiAgICAgICAgc2VsZWN0aW9uSXNDb2xsYXBzZWQgPSBmdW5jdGlvbiAoc2VsKSB7CiAgICAgICAgICAgIHJldHVybiBzZWwucmFuZ2VDb3VudCA/IHNlbC5nZXRSYW5nZUF0KHNlbC5yYW5nZUNvdW50IC0gMSkuY29sbGFwc2VkIDogZmFsc2U7CiAgICAgICAgfTsKICAgIH0KCiAgICBmdW5jdGlvbiB1cGRhdGVBbmNob3JBbmRGb2N1c0Zyb21SYW5nZShzZWwsIHJhbmdlLCBiYWNrd2FyZHMpIHsKICAgICAgICB2YXIgYW5jaG9yUHJlZml4ID0gYmFja3dhcmRzID8gImVuZCIgOiAic3RhcnQiLCBmb2N1c1ByZWZpeCA9IGJhY2t3YXJkcyA/ICJzdGFydCIgOiAiZW5kIjsKICAgICAgICBzZWwuYW5jaG9yTm9kZSA9IHJhbmdlW2FuY2hvclByZWZpeCArICJDb250YWluZXIiXTsKICAgICAgICBzZWwuYW5jaG9yT2Zmc2V0ID0gcmFuZ2VbYW5jaG9yUHJlZml4ICsgIk9mZnNldCJdOwogICAgICAgIHNlbC5mb2N1c05vZGUgPSByYW5nZVtmb2N1c1ByZWZpeCArICJDb250YWluZXIiXTsKICAgICAgICBzZWwuZm9jdXNPZmZzZXQgPSByYW5nZVtmb2N1c1ByZWZpeCArICJPZmZzZXQiXTsKICAgIH0KCiAgICBmdW5jdGlvbiB1cGRhdGVBbmNob3JBbmRGb2N1c0Zyb21OYXRpdmVTZWxlY3Rpb24oc2VsKSB7CiAgICAgICAgdmFyIG5hdGl2ZVNlbCA9IHNlbC5uYXRpdmVTZWxlY3Rpb247CiAgICAgICAgc2VsLmFuY2hvck5vZGUgPSBuYXRpdmVTZWwuYW5jaG9yTm9kZTsKICAgICAgICBzZWwuYW5jaG9yT2Zmc2V0ID0gbmF0aXZlU2VsLmFuY2hvck9mZnNldDsKICAgICAgICBzZWwuZm9jdXNOb2RlID0gbmF0aXZlU2VsLmZvY3VzTm9kZTsKICAgICAgICBzZWwuZm9jdXNPZmZzZXQgPSBuYXRpdmVTZWwuZm9jdXNPZmZzZXQ7CiAgICB9CgogICAgZnVuY3Rpb24gdXBkYXRlRW1wdHlTZWxlY3Rpb24oc2VsKSB7CiAgICAgICAgc2VsLmFuY2hvck5vZGUgPSBzZWwuZm9jdXNOb2RlID0gbnVsbDsKICAgICAgICBzZWwuYW5jaG9yT2Zmc2V0ID0gc2VsLmZvY3VzT2Zmc2V0ID0gMDsKICAgICAgICBzZWwucmFuZ2VDb3VudCA9IDA7CiAgICAgICAgc2VsLmlzQ29sbGFwc2VkID0gdHJ1ZTsKICAgICAgICBzZWwuX3Jhbmdlcy5sZW5ndGggPSAwOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldE5hdGl2ZVJhbmdlKHJhbmdlKSB7CiAgICAgICAgdmFyIG5hdGl2ZVJhbmdlOwogICAgICAgIGlmIChyYW5nZSBpbnN0YW5jZW9mIERvbVJhbmdlKSB7CiAgICAgICAgICAgIG5hdGl2ZVJhbmdlID0gcmFuZ2UuX3NlbGVjdGlvbk5hdGl2ZVJhbmdlOwogICAgICAgICAgICBpZiAoIW5hdGl2ZVJhbmdlKSB7CiAgICAgICAgICAgICAgICBuYXRpdmVSYW5nZSA9IGFwaS5jcmVhdGVOYXRpdmVSYW5nZShkb20uZ2V0RG9jdW1lbnQocmFuZ2Uuc3RhcnRDb250YWluZXIpKTsKICAgICAgICAgICAgICAgIG5hdGl2ZVJhbmdlLnNldEVuZChyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCk7CiAgICAgICAgICAgICAgICBuYXRpdmVSYW5nZS5zZXRTdGFydChyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICAgICAgcmFuZ2UuX3NlbGVjdGlvbk5hdGl2ZVJhbmdlID0gbmF0aXZlUmFuZ2U7CiAgICAgICAgICAgICAgICByYW5nZS5hdHRhY2hMaXN0ZW5lcigiZGV0YWNoIiwgZnVuY3Rpb24gKCkgewoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZWxlY3Rpb25OYXRpdmVSYW5nZSA9IG51bGw7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAocmFuZ2UgaW5zdGFuY2VvZiBXcmFwcGVkUmFuZ2UpIHsKICAgICAgICAgICAgbmF0aXZlUmFuZ2UgPSByYW5nZS5uYXRpdmVSYW5nZTsKICAgICAgICB9IGVsc2UgaWYgKGFwaS5mZWF0dXJlcy5pbXBsZW1lbnRzRG9tUmFuZ2UgJiYgKHJhbmdlIGluc3RhbmNlb2YgZG9tLmdldFdpbmRvdyhyYW5nZS5zdGFydENvbnRhaW5lcikuUmFuZ2UpKSB7CiAgICAgICAgICAgIG5hdGl2ZVJhbmdlID0gcmFuZ2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuYXRpdmVSYW5nZTsKICAgIH0KCiAgICBmdW5jdGlvbiByYW5nZUNvbnRhaW5zU2luZ2xlRWxlbWVudChyYW5nZU5vZGVzKSB7CiAgICAgICAgaWYgKCFyYW5nZU5vZGVzLmxlbmd0aCB8fCByYW5nZU5vZGVzWzBdLm5vZGVUeXBlICE9IDEpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmb3IgKHZhciBpID0gMSwgbGVuID0gcmFuZ2VOb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgIGlmICghZG9tLmlzQW5jZXN0b3JPZihyYW5nZU5vZGVzWzBdLCByYW5nZU5vZGVzW2ldKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldFNpbmdsZUVsZW1lbnRGcm9tUmFuZ2UocmFuZ2UpIHsKICAgICAgICB2YXIgbm9kZXMgPSByYW5nZS5nZXROb2RlcygpOwogICAgICAgIGlmICghcmFuZ2VDb250YWluc1NpbmdsZUVsZW1lbnQobm9kZXMpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiZ2V0U2luZ2xlRWxlbWVudEZyb21SYW5nZTogcmFuZ2UgIiArIHJhbmdlLmluc3BlY3QoKSArICIgZGlkIG5vdCBjb25zaXN0IG9mIGEgc2luZ2xlIGVsZW1lbnQiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5vZGVzWzBdOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzVGV4dFJhbmdlKHJhbmdlKSB7CiAgICAgICAgcmV0dXJuICEhcmFuZ2UgJiYgdHlwZW9mIHJhbmdlLnRleHQgIT0gInVuZGVmaW5lZCI7CiAgICB9CgogICAgZnVuY3Rpb24gdXBkYXRlRnJvbVRleHRSYW5nZShzZWwsIHJhbmdlKSB7CiAgICAgICAgLy8gQ3JlYXRlIGEgUmFuZ2UgZnJvbSB0aGUgc2VsZWN0ZWQgVGV4dFJhbmdlCiAgICAgICAgdmFyIHdyYXBwZWRSYW5nZSA9IG5ldyBXcmFwcGVkUmFuZ2UocmFuZ2UpOwogICAgICAgIHNlbC5fcmFuZ2VzID0gW3dyYXBwZWRSYW5nZV07CgogICAgICAgIHVwZGF0ZUFuY2hvckFuZEZvY3VzRnJvbVJhbmdlKHNlbCwgd3JhcHBlZFJhbmdlLCBmYWxzZSk7CiAgICAgICAgc2VsLnJhbmdlQ291bnQgPSAxOwogICAgICAgIHNlbC5pc0NvbGxhcHNlZCA9IHdyYXBwZWRSYW5nZS5jb2xsYXBzZWQ7CiAgICB9CgogICAgZnVuY3Rpb24gdXBkYXRlQ29udHJvbFNlbGVjdGlvbihzZWwpIHsKICAgICAgICAvLyBVcGRhdGUgdGhlIHdyYXBwZWQgc2VsZWN0aW9uIGJhc2VkIG9uIHdoYXQncyBub3cgaW4gdGhlIG5hdGl2ZSBzZWxlY3Rpb24KICAgICAgICBzZWwuX3Jhbmdlcy5sZW5ndGggPSAwOwogICAgICAgIGlmIChzZWwuZG9jU2VsZWN0aW9uLnR5cGUgPT0gIk5vbmUiKSB7CiAgICAgICAgICAgIHVwZGF0ZUVtcHR5U2VsZWN0aW9uKHNlbCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdmFyIGNvbnRyb2xSYW5nZSA9IHNlbC5kb2NTZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTsKICAgICAgICAgICAgaWYgKGlzVGV4dFJhbmdlKGNvbnRyb2xSYW5nZSkpIHsKICAgICAgICAgICAgICAgIC8vIFRoaXMgY2FzZSAod2hlcmUgdGhlIHNlbGVjdGlvbiB0eXBlIGlzICJDb250cm9sIiBhbmQgY2FsbGluZyBjcmVhdGVSYW5nZSgpIG9uIHRoZSBzZWxlY3Rpb24gcmV0dXJucwogICAgICAgICAgICAgICAgLy8gYSBUZXh0UmFuZ2UpIGNhbiBoYXBwZW4gaW4gSUUgOS4gSXQgaGFwcGVucywgZm9yIGV4YW1wbGUsIHdoZW4gYWxsIGVsZW1lbnRzIGluIHRoZSBzZWxlY3RlZAogICAgICAgICAgICAgICAgLy8gQ29udHJvbFJhbmdlIGhhdmUgYmVlbiByZW1vdmVkIGZyb20gdGhlIENvbnRyb2xSYW5nZSBhbmQgcmVtb3ZlZCBmcm9tIHRoZSBkb2N1bWVudC4KICAgICAgICAgICAgICAgIHVwZGF0ZUZyb21UZXh0UmFuZ2Uoc2VsLCBjb250cm9sUmFuZ2UpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2VsLnJhbmdlQ291bnQgPSBjb250cm9sUmFuZ2UubGVuZ3RoOwogICAgICAgICAgICAgICAgdmFyIHJhbmdlLCBkb2MgPSBkb20uZ2V0RG9jdW1lbnQoY29udHJvbFJhbmdlLml0ZW0oMCkpOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7CiAgICAgICAgICAgICAgICAgICAgIGkgPCBzZWwucmFuZ2VDb3VudDsKICAgICAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2UgPSBhcGkuY3JlYXRlUmFuZ2UoZG9jKTsKICAgICAgICAgICAgICAgICAgICByYW5nZS5zZWxlY3ROb2RlKGNvbnRyb2xSYW5nZS5pdGVtKGkpKTsKICAgICAgICAgICAgICAgICAgICBzZWwuX3Jhbmdlcy5wdXNoKHJhbmdlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNlbC5pc0NvbGxhcHNlZCA9IHNlbC5yYW5nZUNvdW50ID09IDEgJiYgc2VsLl9yYW5nZXNbMF0uY29sbGFwc2VkOwogICAgICAgICAgICAgICAgdXBkYXRlQW5jaG9yQW5kRm9jdXNGcm9tUmFuZ2Uoc2VsLCBzZWwuX3Jhbmdlc1tzZWwucmFuZ2VDb3VudCAtIDFdLCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gYWRkUmFuZ2VUb0NvbnRyb2xTZWxlY3Rpb24oc2VsLCByYW5nZSkgewogICAgICAgIHZhciBjb250cm9sUmFuZ2UgPSBzZWwuZG9jU2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgdmFyIHJhbmdlRWxlbWVudCA9IGdldFNpbmdsZUVsZW1lbnRGcm9tUmFuZ2UocmFuZ2UpOwoKICAgICAgICAvLyBDcmVhdGUgYSBuZXcgQ29udHJvbFJhbmdlIGNvbnRhaW5pbmcgYWxsIHRoZSBlbGVtZW50cyBpbiB0aGUgc2VsZWN0ZWQgQ29udHJvbFJhbmdlIHBsdXMgdGhlIGVsZW1lbnQKICAgICAgICAvLyBjb250YWluZWQgYnkgdGhlIHN1cHBsaWVkIHJhbmdlCiAgICAgICAgdmFyIGRvYyA9IGRvbS5nZXREb2N1bWVudChjb250cm9sUmFuZ2UuaXRlbSgwKSk7CiAgICAgICAgdmFyIG5ld0NvbnRyb2xSYW5nZSA9IGRvbS5nZXRCb2R5KGRvYykuY3JlYXRlQ29udHJvbFJhbmdlKCk7CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNvbnRyb2xSYW5nZS5sZW5ndGg7CiAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgIG5ld0NvbnRyb2xSYW5nZS5hZGQoY29udHJvbFJhbmdlLml0ZW0oaSkpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgICBuZXdDb250cm9sUmFuZ2UuYWRkKHJhbmdlRWxlbWVudCk7CiAgICAgICAgfSBjYXRjaCAoZXgpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJhZGRSYW5nZSgpOiBFbGVtZW50IHdpdGhpbiB0aGUgc3BlY2lmaWVkIFJhbmdlIGNvdWxkIG5vdCBiZSBhZGRlZCB0byBjb250cm9sIHNlbGVjdGlvbiAoZG9lcyBpdCBoYXZlIGxheW91dD8pIik7CiAgICAgICAgfQogICAgICAgIG5ld0NvbnRyb2xSYW5nZS5zZWxlY3QoKTsKCiAgICAgICAgLy8gVXBkYXRlIHRoZSB3cmFwcGVkIHNlbGVjdGlvbiBiYXNlZCBvbiB3aGF0J3Mgbm93IGluIHRoZSBuYXRpdmUgc2VsZWN0aW9uCiAgICAgICAgdXBkYXRlQ29udHJvbFNlbGVjdGlvbihzZWwpOwogICAgfQoKICAgIHZhciBnZXRTZWxlY3Rpb25SYW5nZUF0OwoKICAgIGlmICh1dGlsLmlzSG9zdE1ldGhvZCh0ZXN0U2VsZWN0aW9uLCAiZ2V0UmFuZ2VBdCIpKSB7CiAgICAgICAgZ2V0U2VsZWN0aW9uUmFuZ2VBdCA9IGZ1bmN0aW9uIChzZWwsIGluZGV4KSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsLmdldFJhbmdlQXQoaW5kZXgpOwogICAgICAgICAgICB9IGNhdGNoIChleCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfSBlbHNlIGlmIChzZWxlY3Rpb25IYXNBbmNob3JBbmRGb2N1cykgewogICAgICAgIGdldFNlbGVjdGlvblJhbmdlQXQgPSBmdW5jdGlvbiAoc2VsKSB7CiAgICAgICAgICAgIHZhciBkb2MgPSBkb20uZ2V0RG9jdW1lbnQoc2VsLmFuY2hvck5vZGUpOwogICAgICAgICAgICB2YXIgcmFuZ2UgPSBhcGkuY3JlYXRlUmFuZ2UoZG9jKTsKICAgICAgICAgICAgcmFuZ2Uuc2V0U3RhcnQoc2VsLmFuY2hvck5vZGUsIHNlbC5hbmNob3JPZmZzZXQpOwogICAgICAgICAgICByYW5nZS5zZXRFbmQoc2VsLmZvY3VzTm9kZSwgc2VsLmZvY3VzT2Zmc2V0KTsKCiAgICAgICAgICAgIC8vIEhhbmRsZSB0aGUgY2FzZSB3aGVuIHRoZSBzZWxlY3Rpb24gd2FzIHNlbGVjdGVkIGJhY2t3YXJkcyAoZnJvbSB0aGUgZW5kIHRvIHRoZSBzdGFydCBpbiB0aGUKICAgICAgICAgICAgLy8gZG9jdW1lbnQpCiAgICAgICAgICAgIGlmIChyYW5nZS5jb2xsYXBzZWQgIT09IHRoaXMuaXNDb2xsYXBzZWQpIHsKICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0KHNlbC5mb2N1c05vZGUsIHNlbC5mb2N1c09mZnNldCk7CiAgICAgICAgICAgICAgICByYW5nZS5zZXRFbmQoc2VsLmFuY2hvck5vZGUsIHNlbC5hbmNob3JPZmZzZXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gcmFuZ2U7CiAgICAgICAgfTsKICAgIH0KCiAgICAvKioKICAgICAqIEBjb25zdHJ1Y3RvcgogICAgICovCiAgICBmdW5jdGlvbiBXcmFwcGVkU2VsZWN0aW9uKHNlbGVjdGlvbiwgZG9jU2VsZWN0aW9uLCB3aW4pIHsKICAgICAgICB0aGlzLm5hdGl2ZVNlbGVjdGlvbiA9IHNlbGVjdGlvbjsKICAgICAgICB0aGlzLmRvY1NlbGVjdGlvbiA9IGRvY1NlbGVjdGlvbjsKICAgICAgICB0aGlzLl9yYW5nZXMgPSBbXTsKICAgICAgICB0aGlzLndpbiA9IHdpbjsKICAgICAgICB0aGlzLnJlZnJlc2goKTsKICAgIH0KCiAgICBhcGkuZ2V0U2VsZWN0aW9uID0gZnVuY3Rpb24gKHdpbikgewogICAgICAgIHdpbiA9IHdpbiB8fCB3aW5kb3c7CiAgICAgICAgdmFyIHNlbCA9IHdpblt3aW5kb3dQcm9wZXJ0eU5hbWVdOwogICAgICAgIHZhciBuYXRpdmVTZWwgPSBnZXRTZWxlY3Rpb24od2luKSwgZG9jU2VsID0gaW1wbGVtZW50c0RvY1NlbGVjdGlvbiA/IGdldERvY1NlbGVjdGlvbih3aW4pIDogbnVsbDsKICAgICAgICBpZiAoc2VsKSB7CiAgICAgICAgICAgIHNlbC5uYXRpdmVTZWxlY3Rpb24gPSBuYXRpdmVTZWw7CiAgICAgICAgICAgIHNlbC5kb2NTZWxlY3Rpb24gPSBkb2NTZWw7CiAgICAgICAgICAgIHNlbC5yZWZyZXNoKHdpbik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2VsID0gbmV3IFdyYXBwZWRTZWxlY3Rpb24obmF0aXZlU2VsLCBkb2NTZWwsIHdpbik7CiAgICAgICAgICAgIHdpblt3aW5kb3dQcm9wZXJ0eU5hbWVdID0gc2VsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsOwogICAgfTsKCiAgICBhcGkuZ2V0U2VsZWN0aW9uV2l0aG91dFJlZmVyc2ggPSBmdW5jdGlvbiAod2luKSB7CiAgICAgICAgd2luID0gd2luIHx8IHdpbmRvdzsKICAgICAgICB2YXIgc2VsID0gd2luW3dpbmRvd1Byb3BlcnR5TmFtZV07CiAgICAgICAgdmFyIG5hdGl2ZVNlbCA9IGdldFNlbGVjdGlvbih3aW4pLCBkb2NTZWwgPSBpbXBsZW1lbnRzRG9jU2VsZWN0aW9uID8gZ2V0RG9jU2VsZWN0aW9uKHdpbikgOiBudWxsOwogICAgICAgIGlmIChzZWwpIHsKICAgICAgICAgICAgc2VsLm5hdGl2ZVNlbGVjdGlvbiA9IG5hdGl2ZVNlbDsKICAgICAgICAgICAgc2VsLmRvY1NlbGVjdGlvbiA9IGRvY1NlbDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzZWwgPSBuZXcgV3JhcHBlZFNlbGVjdGlvbihuYXRpdmVTZWwsIGRvY1NlbCwgd2luKTsKICAgICAgICAgICAgd2luW3dpbmRvd1Byb3BlcnR5TmFtZV0gPSBzZWw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWw7CiAgICB9OwoKICAgIGFwaS5nZXRJZnJhbWVTZWxlY3Rpb24gPSBmdW5jdGlvbiAoaWZyYW1lRWwpIHsKICAgICAgICByZXR1cm4gYXBpLmdldFNlbGVjdGlvbihkb20uZ2V0SWZyYW1lV2luZG93KGlmcmFtZUVsKSk7CiAgICB9OwoKICAgIHZhciBzZWxQcm90byA9IFdyYXBwZWRTZWxlY3Rpb24ucHJvdG90eXBlOwoKICAgIGZ1bmN0aW9uIGNyZWF0ZUNvbnRyb2xTZWxlY3Rpb24oc2VsLCByYW5nZXMpIHsKICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGUgc2VsZWN0aW9uIGJlY29tZXMgb2YgdHlwZSAiQ29udHJvbCIKICAgICAgICB2YXIgZG9jID0gZG9tLmdldERvY3VtZW50KHJhbmdlc1swXS5zdGFydENvbnRhaW5lcik7CiAgICAgICAgdmFyIGNvbnRyb2xSYW5nZSA9IGRvbS5nZXRCb2R5KGRvYykuY3JlYXRlQ29udHJvbFJhbmdlKCk7CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGVsOwogICAgICAgICAgICAgaSA8IHJhbmdlQ291bnQ7CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgZWwgPSBnZXRTaW5nbGVFbGVtZW50RnJvbVJhbmdlKHJhbmdlc1tpXSk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBjb250cm9sUmFuZ2UuYWRkKGVsKTsKICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigic2V0UmFuZ2VzKCk6IEVsZW1lbnQgd2l0aGluIHRoZSBvbmUgb2YgdGhlIHNwZWNpZmllZCBSYW5nZXMgY291bGQgbm90IGJlIGFkZGVkIHRvIGNvbnRyb2wgc2VsZWN0aW9uIChkb2VzIGl0IGhhdmUgbGF5b3V0PykiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb250cm9sUmFuZ2Uuc2VsZWN0KCk7CgogICAgICAgIC8vIFVwZGF0ZSB0aGUgd3JhcHBlZCBzZWxlY3Rpb24gYmFzZWQgb24gd2hhdCdzIG5vdyBpbiB0aGUgbmF0aXZlIHNlbGVjdGlvbgogICAgICAgIHVwZGF0ZUNvbnRyb2xTZWxlY3Rpb24oc2VsKTsKICAgIH0KCiAgICAvLyBTZWxlY3RpbmcgYSByYW5nZQogICAgaWYgKCF1c2VEb2N1bWVudFNlbGVjdGlvbiAmJiBzZWxlY3Rpb25IYXNBbmNob3JBbmRGb2N1cyAmJiB1dGlsLmFyZUhvc3RNZXRob2RzKHRlc3RTZWxlY3Rpb24sIFsicmVtb3ZlQWxsUmFuZ2VzIiwgImFkZFJhbmdlIl0pKSB7CiAgICAgICAgc2VsUHJvdG8ucmVtb3ZlQWxsUmFuZ2VzID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLm5hdGl2ZVNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTsKICAgICAgICAgICAgdXBkYXRlRW1wdHlTZWxlY3Rpb24odGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgdmFyIGFkZFJhbmdlQmFja3dhcmRzID0gZnVuY3Rpb24gKHNlbCwgcmFuZ2UpIHsKICAgICAgICAgICAgdmFyIGRvYyA9IERvbVJhbmdlLmdldFJhbmdlRG9jdW1lbnQocmFuZ2UpOwogICAgICAgICAgICB2YXIgZW5kUmFuZ2UgPSBhcGkuY3JlYXRlUmFuZ2UoZG9jKTsKICAgICAgICAgICAgZW5kUmFuZ2UuY29sbGFwc2VUb1BvaW50KHJhbmdlLmVuZENvbnRhaW5lciwgcmFuZ2UuZW5kT2Zmc2V0KTsKICAgICAgICAgICAgc2VsLm5hdGl2ZVNlbGVjdGlvbi5hZGRSYW5nZShnZXROYXRpdmVSYW5nZShlbmRSYW5nZSkpOwogICAgICAgICAgICBzZWwubmF0aXZlU2VsZWN0aW9uLmV4dGVuZChyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICBzZWwucmVmcmVzaCgpOwogICAgICAgIH07CgogICAgICAgIGlmIChzZWxlY3Rpb25IYXNSYW5nZUNvdW50KSB7CiAgICAgICAgICAgIHNlbFByb3RvLmFkZFJhbmdlID0gZnVuY3Rpb24gKHJhbmdlLCBiYWNrd2FyZHMpIHsKICAgICAgICAgICAgICAgIGlmIChpbXBsZW1lbnRzQ29udHJvbFJhbmdlICYmIGltcGxlbWVudHNEb2NTZWxlY3Rpb24gJiYgdGhpcy5kb2NTZWxlY3Rpb24udHlwZSA9PSBDT05UUk9MKSB7CiAgICAgICAgICAgICAgICAgICAgYWRkUmFuZ2VUb0NvbnRyb2xTZWxlY3Rpb24odGhpcywgcmFuZ2UpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYmFja3dhcmRzICYmIHNlbGVjdGlvbkhhc0V4dGVuZCkgewogICAgICAgICAgICAgICAgICAgICAgICBhZGRSYW5nZUJhY2t3YXJkcyh0aGlzLCByYW5nZSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHByZXZpb3VzUmFuZ2VDb3VudDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvblN1cHBvcnRzTXVsdGlwbGVSYW5nZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzUmFuZ2VDb3VudCA9IHRoaXMucmFuZ2VDb3VudDsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlQWxsUmFuZ2VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c1JhbmdlQ291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmF0aXZlU2VsZWN0aW9uLmFkZFJhbmdlKGdldE5hdGl2ZVJhbmdlKHJhbmdlKSk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayB3aGV0aGVyIGFkZGluZyB0aGUgcmFuZ2Ugd2FzIHN1Y2Nlc3NmdWwKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yYW5nZUNvdW50ID0gdGhpcy5uYXRpdmVTZWxlY3Rpb24ucmFuZ2VDb3VudDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJhbmdlQ291bnQgPT0gcHJldmlvdXNSYW5nZUNvdW50ICsgMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHJhbmdlIHdhcyBhZGRlZCBzdWNjZXNzZnVsbHkKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSByYW5nZSB0aGF0IHdlIGFkZGVkIHRvIHRoZSBzZWxlY3Rpb24gaXMgcmVmbGVjdGVkIGluIHRoZSBsYXN0IHJhbmdlIGV4dHJhY3RlZCBmcm9tCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgc2VsZWN0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXBpLmNvbmZpZy5jaGVja1NlbGVjdGlvblJhbmdlcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuYXRpdmVSYW5nZSA9IGdldFNlbGVjdGlvblJhbmdlQXQodGhpcy5uYXRpdmVTZWxlY3Rpb24sIHRoaXMucmFuZ2VDb3VudCAtIDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVSYW5nZSAmJiAhRG9tUmFuZ2UucmFuZ2VzRXF1YWwobmF0aXZlUmFuZ2UsIHJhbmdlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBIYXBwZW5zIGluIFdlYktpdCB3aXRoLCBmb3IgZXhhbXBsZSwgYSBzZWxlY3Rpb24gcGxhY2VkIGF0IHRoZSBzdGFydCBvZiBhIHRleHQgbm9kZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYW5nZSA9IG5ldyBXcmFwcGVkUmFuZ2UobmF0aXZlUmFuZ2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Jhbmdlc1t0aGlzLnJhbmdlQ291bnQgLSAxXSA9IHJhbmdlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlQW5jaG9yQW5kRm9jdXNGcm9tUmFuZ2UodGhpcywgcmFuZ2UsIHNlbGVjdGlvbklzQmFja3dhcmRzKHRoaXMubmF0aXZlU2VsZWN0aW9uKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzQ29sbGFwc2VkID0gc2VsZWN0aW9uSXNDb2xsYXBzZWQodGhpcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgcmFuZ2Ugd2FzIG5vdCBhZGRlZCBzdWNjZXNzZnVsbHkuIFRoZSBzaW1wbGVzdCB0aGluZyBpcyB0byByZWZyZXNoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlZnJlc2goKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzZWxQcm90by5hZGRSYW5nZSA9IGZ1bmN0aW9uIChyYW5nZSwgYmFja3dhcmRzKSB7CiAgICAgICAgICAgICAgICBpZiAoYmFja3dhcmRzICYmIHNlbGVjdGlvbkhhc0V4dGVuZCkgewogICAgICAgICAgICAgICAgICAgIGFkZFJhbmdlQmFja3dhcmRzKHRoaXMsIHJhbmdlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5uYXRpdmVTZWxlY3Rpb24uYWRkUmFuZ2UoZ2V0TmF0aXZlUmFuZ2UocmFuZ2UpKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnJlZnJlc2goKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIHNlbFByb3RvLnNldFJhbmdlcyA9IGZ1bmN0aW9uIChyYW5nZXMpIHsKICAgICAgICAgICAgaWYgKGltcGxlbWVudHNDb250cm9sUmFuZ2UgJiYgcmFuZ2VzLmxlbmd0aCA+IDEpIHsKICAgICAgICAgICAgICAgIGNyZWF0ZUNvbnRyb2xTZWxlY3Rpb24odGhpcywgcmFuZ2VzKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlQWxsUmFuZ2VzKCk7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gcmFuZ2VzLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRSYW5nZShyYW5nZXNbaV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgIH0gZWxzZSBpZiAodXRpbC5pc0hvc3RNZXRob2QodGVzdFNlbGVjdGlvbiwgImVtcHR5IikgJiYgdXRpbC5pc0hvc3RNZXRob2QodGVzdFJhbmdlLCAic2VsZWN0IikgJiYgaW1wbGVtZW50c0NvbnRyb2xSYW5nZSAmJiB1c2VEb2N1bWVudFNlbGVjdGlvbikgewoKICAgICAgICBzZWxQcm90by5yZW1vdmVBbGxSYW5nZXMgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vIEFkZGVkIHRyeS9jYXRjaCBhcyBmaXggZm9yIGlzc3VlICMyMQogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5kb2NTZWxlY3Rpb24uZW1wdHkoKTsKCiAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgZW1wdHkoKSBub3Qgd29ya2luZyAoaXNzdWUgIzI0KQogICAgICAgICAgICAgICAgaWYgKHRoaXMuZG9jU2VsZWN0aW9uLnR5cGUgIT0gIk5vbmUiKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gV29yayBhcm91bmQgZmFpbHVyZSB0byBlbXB0eSBhIGNvbnRyb2wgc2VsZWN0aW9uIGJ5IGluc3RlYWQgc2VsZWN0aW5nIGEgVGV4dFJhbmdlIGFuZCB0aGVuCiAgICAgICAgICAgICAgICAgICAgLy8gY2FsbGluZyBlbXB0eSgpCiAgICAgICAgICAgICAgICAgICAgdmFyIGRvYzsKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5hbmNob3JOb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvYyA9IGRvbS5nZXREb2N1bWVudCh0aGlzLmFuY2hvck5vZGUpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5kb2NTZWxlY3Rpb24udHlwZSA9PSBDT05UUk9MKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250cm9sUmFuZ2UgPSB0aGlzLmRvY1NlbGVjdGlvbi5jcmVhdGVSYW5nZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29udHJvbFJhbmdlLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jID0gZG9tLmdldERvY3VtZW50KGNvbnRyb2xSYW5nZS5pdGVtKDApKS5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChkb2MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRSYW5nZSA9IGRvYy5ib2R5LmNyZWF0ZVRleHRSYW5nZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB0ZXh0UmFuZ2Uuc2VsZWN0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZG9jU2VsZWN0aW9uLmVtcHR5KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChleCkgewogICAgICAgICAgICB9CiAgICAgICAgICAgIHVwZGF0ZUVtcHR5U2VsZWN0aW9uKHRoaXMpOwogICAgICAgIH07CgogICAgICAgIHNlbFByb3RvLmFkZFJhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgICAgIGlmICh0aGlzLmRvY1NlbGVjdGlvbi50eXBlID09IENPTlRST0wpIHsKICAgICAgICAgICAgICAgIGFkZFJhbmdlVG9Db250cm9sU2VsZWN0aW9uKHRoaXMsIHJhbmdlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFdyYXBwZWRSYW5nZS5yYW5nZVRvVGV4dFJhbmdlKHJhbmdlKS5zZWxlY3QoKTsKICAgICAgICAgICAgICAgIHRoaXMuX3Jhbmdlc1swXSA9IHJhbmdlOwogICAgICAgICAgICAgICAgdGhpcy5yYW5nZUNvdW50ID0gMTsKICAgICAgICAgICAgICAgIHRoaXMuaXNDb2xsYXBzZWQgPSB0aGlzLl9yYW5nZXNbMF0uY29sbGFwc2VkOwogICAgICAgICAgICAgICAgdXBkYXRlQW5jaG9yQW5kRm9jdXNGcm9tUmFuZ2UodGhpcywgcmFuZ2UsIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIHNlbFByb3RvLnNldFJhbmdlcyA9IGZ1bmN0aW9uIChyYW5nZXMpIHsKICAgICAgICAgICAgdGhpcy5yZW1vdmVBbGxSYW5nZXMoKTsKICAgICAgICAgICAgdmFyIHJhbmdlQ291bnQgPSByYW5nZXMubGVuZ3RoOwogICAgICAgICAgICBpZiAocmFuZ2VDb3VudCA+IDEpIHsKICAgICAgICAgICAgICAgIGNyZWF0ZUNvbnRyb2xTZWxlY3Rpb24odGhpcywgcmFuZ2VzKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChyYW5nZUNvdW50KSB7CiAgICAgICAgICAgICAgICB0aGlzLmFkZFJhbmdlKHJhbmdlc1swXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfSBlbHNlIHsKICAgICAgICBtb2R1bGUuZmFpbCgiTm8gbWVhbnMgb2Ygc2VsZWN0aW5nIGEgUmFuZ2Ugb3IgVGV4dFJhbmdlIHdhcyBmb3VuZCIpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBzZWxQcm90by5nZXRSYW5nZUF0ID0gZnVuY3Rpb24gKGluZGV4KSB7CiAgICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSB0aGlzLnJhbmdlQ291bnQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IERPTUV4Y2VwdGlvbigiSU5ERVhfU0laRV9FUlIiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gdGhpcy5fcmFuZ2VzW2luZGV4XTsKICAgICAgICB9CiAgICB9OwoKICAgIHZhciByZWZyZXNoU2VsZWN0aW9uOwoKICAgIGlmICh1c2VEb2N1bWVudFNlbGVjdGlvbikgewogICAgICAgIHJlZnJlc2hTZWxlY3Rpb24gPSBmdW5jdGlvbiAoc2VsKSB7CiAgICAgICAgICAgIHZhciByYW5nZTsKICAgICAgICAgICAgaWYgKGFwaS5pc1NlbGVjdGlvblZhbGlkKHNlbC53aW4pKSB7CiAgICAgICAgICAgICAgICByYW5nZSA9IHNlbC5kb2NTZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJhbmdlID0gZG9tLmdldEJvZHkoc2VsLndpbi5kb2N1bWVudCkuY3JlYXRlVGV4dFJhbmdlKCk7CiAgICAgICAgICAgICAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHNlbC5kb2NTZWxlY3Rpb24udHlwZSA9PSBDT05UUk9MKSB7CiAgICAgICAgICAgICAgICB1cGRhdGVDb250cm9sU2VsZWN0aW9uKHNlbCk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNUZXh0UmFuZ2UocmFuZ2UpKSB7CiAgICAgICAgICAgICAgICB1cGRhdGVGcm9tVGV4dFJhbmdlKHNlbCwgcmFuZ2UpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdXBkYXRlRW1wdHlTZWxlY3Rpb24oc2VsKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9IGVsc2UgaWYgKHV0aWwuaXNIb3N0TWV0aG9kKHRlc3RTZWxlY3Rpb24sICJnZXRSYW5nZUF0IikgJiYgdHlwZW9mIHRlc3RTZWxlY3Rpb24ucmFuZ2VDb3VudCA9PSAibnVtYmVyIikgewogICAgICAgIHJlZnJlc2hTZWxlY3Rpb24gPSBmdW5jdGlvbiAoc2VsKSB7CiAgICAgICAgICAgIGlmIChpbXBsZW1lbnRzQ29udHJvbFJhbmdlICYmIGltcGxlbWVudHNEb2NTZWxlY3Rpb24gJiYgc2VsLmRvY1NlbGVjdGlvbi50eXBlID09IENPTlRST0wpIHsKICAgICAgICAgICAgICAgIHVwZGF0ZUNvbnRyb2xTZWxlY3Rpb24oc2VsKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNlbC5fcmFuZ2VzLmxlbmd0aCA9IHNlbC5yYW5nZUNvdW50ID0gc2VsLm5hdGl2ZVNlbGVjdGlvbiA/IHNlbC5uYXRpdmVTZWxlY3Rpb24ucmFuZ2VDb3VudCA6IG51bGw7CiAgICAgICAgICAgICAgICBpZiAoc2VsLnJhbmdlQ291bnQpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gc2VsLnJhbmdlQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbC5fcmFuZ2VzW2ldID0gbmV3IGFwaS5XcmFwcGVkUmFuZ2Uoc2VsLm5hdGl2ZVNlbGVjdGlvbi5nZXRSYW5nZUF0KGkpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdXBkYXRlQW5jaG9yQW5kRm9jdXNGcm9tUmFuZ2Uoc2VsLCBzZWwuX3Jhbmdlc1tzZWwucmFuZ2VDb3VudCAtIDFdLCBzZWxlY3Rpb25Jc0JhY2t3YXJkcyhzZWwubmF0aXZlU2VsZWN0aW9uKSk7CiAgICAgICAgICAgICAgICAgICAgc2VsLmlzQ29sbGFwc2VkID0gc2VsZWN0aW9uSXNDb2xsYXBzZWQoc2VsKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdXBkYXRlRW1wdHlTZWxlY3Rpb24oc2VsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9IGVsc2UgaWYgKHNlbGVjdGlvbkhhc0FuY2hvckFuZEZvY3VzICYmIHR5cGVvZiB0ZXN0U2VsZWN0aW9uLmlzQ29sbGFwc2VkID09IEJPT0xFQU4gJiYgdHlwZW9mIHRlc3RSYW5nZS5jb2xsYXBzZWQgPT0gQk9PTEVBTiAmJiBhcGkuZmVhdHVyZXMuaW1wbGVtZW50c0RvbVJhbmdlKSB7CiAgICAgICAgcmVmcmVzaFNlbGVjdGlvbiA9IGZ1bmN0aW9uIChzZWwpIHsKICAgICAgICAgICAgdmFyIHJhbmdlLCBuYXRpdmVTZWwgPSBzZWwubmF0aXZlU2VsZWN0aW9uOwogICAgICAgICAgICBpZiAobmF0aXZlU2VsLmFuY2hvck5vZGUpIHsKICAgICAgICAgICAgICAgIHJhbmdlID0gZ2V0U2VsZWN0aW9uUmFuZ2VBdChuYXRpdmVTZWwsIDApOwogICAgICAgICAgICAgICAgc2VsLl9yYW5nZXMgPSBbcmFuZ2VdOwogICAgICAgICAgICAgICAgc2VsLnJhbmdlQ291bnQgPSAxOwogICAgICAgICAgICAgICAgdXBkYXRlQW5jaG9yQW5kRm9jdXNGcm9tTmF0aXZlU2VsZWN0aW9uKHNlbCk7CiAgICAgICAgICAgICAgICBzZWwuaXNDb2xsYXBzZWQgPSBzZWxlY3Rpb25Jc0NvbGxhcHNlZChzZWwpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdXBkYXRlRW1wdHlTZWxlY3Rpb24oc2VsKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIG1vZHVsZS5mYWlsKCJObyBtZWFucyBvZiBvYnRhaW5pbmcgYSBSYW5nZSBvciBUZXh0UmFuZ2UgZnJvbSB0aGUgdXNlcidzIHNlbGVjdGlvbiB3YXMgZm91bmQiKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgc2VsUHJvdG8ucmVmcmVzaCA9IGZ1bmN0aW9uIChjaGVja0ZvckNoYW5nZXMpIHsKICAgICAgICB2YXIgb2xkUmFuZ2VzID0gY2hlY2tGb3JDaGFuZ2VzID8gdGhpcy5fcmFuZ2VzLnNsaWNlKDApIDogbnVsbDsKICAgICAgICByZWZyZXNoU2VsZWN0aW9uKHRoaXMpOwogICAgICAgIGlmIChjaGVja0ZvckNoYW5nZXMpIHsKICAgICAgICAgICAgdmFyIGkgPSBvbGRSYW5nZXMubGVuZ3RoOwogICAgICAgICAgICBpZiAoaSAhPSB0aGlzLl9yYW5nZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgd2hpbGUgKGktLSkgewogICAgICAgICAgICAgICAgaWYgKCFEb21SYW5nZS5yYW5nZXNFcXVhbChvbGRSYW5nZXNbaV0sIHRoaXMuX3Jhbmdlc1tpXSkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfTsKCiAgICAvLyBSZW1vdmFsIG9mIGEgc2luZ2xlIHJhbmdlCiAgICB2YXIgcmVtb3ZlUmFuZ2VNYW51YWxseSA9IGZ1bmN0aW9uIChzZWwsIHJhbmdlKSB7CiAgICAgICAgdmFyIHJhbmdlcyA9IHNlbC5nZXRBbGxSYW5nZXMoKSwgcmVtb3ZlZCA9IGZhbHNlOwogICAgICAgIHNlbC5yZW1vdmVBbGxSYW5nZXMoKTsKICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gcmFuZ2VzLmxlbmd0aDsKICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgaWYgKHJlbW92ZWQgfHwgcmFuZ2UgIT09IHJhbmdlc1tpXSkgewogICAgICAgICAgICAgICAgc2VsLmFkZFJhbmdlKHJhbmdlc1tpXSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBBY2NvcmRpbmcgdG8gdGhlIGRyYWZ0IFdIQVRXRyBSYW5nZSBzcGVjLCB0aGUgc2FtZSByYW5nZSBtYXkgYmUgYWRkZWQgdG8gdGhlIHNlbGVjdGlvbiBtdWx0aXBsZQogICAgICAgICAgICAgICAgLy8gdGltZXMuIHJlbW92ZVJhbmdlIHNob3VsZCBvbmx5IHJlbW92ZSB0aGUgZmlyc3QgaW5zdGFuY2UsIHNvIHRoZSBmb2xsb3dpbmcgZW5zdXJlcyBvbmx5IHRoZSBmaXJzdAogICAgICAgICAgICAgICAgLy8gaW5zdGFuY2UgaXMgcmVtb3ZlZAogICAgICAgICAgICAgICAgcmVtb3ZlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCFzZWwucmFuZ2VDb3VudCkgewogICAgICAgICAgICB1cGRhdGVFbXB0eVNlbGVjdGlvbihzZWwpOwogICAgICAgIH0KICAgIH07CgogICAgaWYgKGltcGxlbWVudHNDb250cm9sUmFuZ2UpIHsKICAgICAgICBzZWxQcm90by5yZW1vdmVSYW5nZSA9IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgICAgICBpZiAodGhpcy5kb2NTZWxlY3Rpb24udHlwZSA9PSBDT05UUk9MKSB7CiAgICAgICAgICAgICAgICB2YXIgY29udHJvbFJhbmdlID0gdGhpcy5kb2NTZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTsKICAgICAgICAgICAgICAgIHZhciByYW5nZUVsZW1lbnQgPSBnZXRTaW5nbGVFbGVtZW50RnJvbVJhbmdlKHJhbmdlKTsKCiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgQ29udHJvbFJhbmdlIGNvbnRhaW5pbmcgYWxsIHRoZSBlbGVtZW50cyBpbiB0aGUgc2VsZWN0ZWQgQ29udHJvbFJhbmdlIG1pbnVzIHRoZQogICAgICAgICAgICAgICAgLy8gZWxlbWVudCBjb250YWluZWQgYnkgdGhlIHN1cHBsaWVkIHJhbmdlCiAgICAgICAgICAgICAgICB2YXIgZG9jID0gZG9tLmdldERvY3VtZW50KGNvbnRyb2xSYW5nZS5pdGVtKDApKTsKICAgICAgICAgICAgICAgIHZhciBuZXdDb250cm9sUmFuZ2UgPSBkb20uZ2V0Qm9keShkb2MpLmNyZWF0ZUNvbnRyb2xSYW5nZSgpOwogICAgICAgICAgICAgICAgdmFyIGVsLCByZW1vdmVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gY29udHJvbFJhbmdlLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgZWwgPSBjb250cm9sUmFuZ2UuaXRlbShpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZWwgIT09IHJhbmdlRWxlbWVudCB8fCByZW1vdmVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0NvbnRyb2xSYW5nZS5hZGQoY29udHJvbFJhbmdlLml0ZW0oaSkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5ld0NvbnRyb2xSYW5nZS5zZWxlY3QoKTsKCiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgdGhlIHdyYXBwZWQgc2VsZWN0aW9uIGJhc2VkIG9uIHdoYXQncyBub3cgaW4gdGhlIG5hdGl2ZSBzZWxlY3Rpb24KICAgICAgICAgICAgICAgIHVwZGF0ZUNvbnRyb2xTZWxlY3Rpb24odGhpcyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZW1vdmVSYW5nZU1hbnVhbGx5KHRoaXMsIHJhbmdlKTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIHNlbFByb3RvLnJlbW92ZVJhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7CiAgICAgICAgICAgIHJlbW92ZVJhbmdlTWFudWFsbHkodGhpcywgcmFuZ2UpOwogICAgICAgIH07CiAgICB9CgogICAgLy8gRGV0ZWN0aW5nIGlmIGEgc2VsZWN0aW9uIGlzIGJhY2t3YXJkcwogICAgdmFyIHNlbGVjdGlvbklzQmFja3dhcmRzOwogICAgaWYgKCF1c2VEb2N1bWVudFNlbGVjdGlvbiAmJiBzZWxlY3Rpb25IYXNBbmNob3JBbmRGb2N1cyAmJiBhcGkuZmVhdHVyZXMuaW1wbGVtZW50c0RvbVJhbmdlKSB7CiAgICAgICAgc2VsZWN0aW9uSXNCYWNrd2FyZHMgPSBmdW5jdGlvbiAoc2VsKSB7CiAgICAgICAgICAgIHZhciBiYWNrd2FyZHMgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKHNlbC5hbmNob3JOb2RlKSB7CiAgICAgICAgICAgICAgICBiYWNrd2FyZHMgPSAoZG9tLmNvbXBhcmVQb2ludHMoc2VsLmFuY2hvck5vZGUsIHNlbC5hbmNob3JPZmZzZXQsIHNlbC5mb2N1c05vZGUsIHNlbC5mb2N1c09mZnNldCkgPT0gMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGJhY2t3YXJkczsKICAgICAgICB9OwoKICAgICAgICBzZWxQcm90by5pc0JhY2t3YXJkcyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGlvbklzQmFja3dhcmRzKHRoaXMpOwogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIHNlbGVjdGlvbklzQmFja3dhcmRzID0gc2VsUHJvdG8uaXNCYWNrd2FyZHMgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9OwogICAgfQoKICAgIC8vIFNlbGVjdGlvbiB0ZXh0CiAgICAvLyBUaGlzIGlzIGNvbmZvcm1hbnQgdG8gdGhlIG5ldyBXSEFUV0cgRE9NIFJhbmdlIGRyYWZ0IHNwZWMgYnV0IGRpZmZlcnMgZnJvbSBXZWJLaXQgYW5kIE1vemlsbGEncyBpbXBsZW1lbnRhdGlvbgogICAgc2VsUHJvdG8udG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7CgogICAgICAgIHZhciByYW5nZVRleHRzID0gW107CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRoaXMucmFuZ2VDb3VudDsKICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgcmFuZ2VUZXh0c1tpXSA9ICIiICsgdGhpcy5fcmFuZ2VzW2ldOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmFuZ2VUZXh0cy5qb2luKCIiKTsKICAgIH07CgogICAgZnVuY3Rpb24gYXNzZXJ0Tm9kZUluU2FtZURvY3VtZW50KHNlbCwgbm9kZSkgewogICAgICAgIGlmIChzZWwuYW5jaG9yTm9kZSAmJiAoZG9tLmdldERvY3VtZW50KHNlbC5hbmNob3JOb2RlKSAhPT0gZG9tLmdldERvY3VtZW50KG5vZGUpKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKCJXUk9OR19ET0NVTUVOVF9FUlIiKTsKICAgICAgICB9CiAgICB9CgogICAgLy8gTm8gY3VycmVudCBicm93c2VycyBjb25mb3JtIGZ1bGx5IHRvIHRoZSBIVE1MIDUgZHJhZnQgc3BlYyBmb3IgdGhpcyBtZXRob2QsIHNvIFJhbmd5J3Mgb3duIG1ldGhvZCBpcyBhbHdheXMgdXNlZAogICAgc2VsUHJvdG8uY29sbGFwc2UgPSBmdW5jdGlvbiAobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgYXNzZXJ0Tm9kZUluU2FtZURvY3VtZW50KHRoaXMsIG5vZGUpOwogICAgICAgIHZhciByYW5nZSA9IGFwaS5jcmVhdGVSYW5nZShkb20uZ2V0RG9jdW1lbnQobm9kZSkpOwogICAgICAgIHJhbmdlLmNvbGxhcHNlVG9Qb2ludChub2RlLCBvZmZzZXQpOwogICAgICAgIHRoaXMucmVtb3ZlQWxsUmFuZ2VzKCk7CiAgICAgICAgdGhpcy5hZGRSYW5nZShyYW5nZSk7CiAgICAgICAgdGhpcy5pc0NvbGxhcHNlZCA9IHRydWU7CiAgICB9OwoKICAgIHNlbFByb3RvLmNvbGxhcHNlVG9TdGFydCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAodGhpcy5yYW5nZUNvdW50KSB7CiAgICAgICAgICAgIHZhciByYW5nZSA9IHRoaXMuX3Jhbmdlc1swXTsKICAgICAgICAgICAgdGhpcy5jb2xsYXBzZShyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRocm93IG5ldyBET01FeGNlcHRpb24oIklOVkFMSURfU1RBVEVfRVJSIik7CiAgICAgICAgfQogICAgfTsKCiAgICBzZWxQcm90by5jb2xsYXBzZVRvRW5kID0gZnVuY3Rpb24gKCkgewogICAgICAgIGlmICh0aGlzLnJhbmdlQ291bnQpIHsKICAgICAgICAgICAgdmFyIHJhbmdlID0gdGhpcy5fcmFuZ2VzW3RoaXMucmFuZ2VDb3VudCAtIDFdOwogICAgICAgICAgICB0aGlzLmNvbGxhcHNlKHJhbmdlLmVuZENvbnRhaW5lciwgcmFuZ2UuZW5kT2Zmc2V0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aHJvdyBuZXcgRE9NRXhjZXB0aW9uKCJJTlZBTElEX1NUQVRFX0VSUiIpOwogICAgICAgIH0KICAgIH07CgogICAgLy8gVGhlIEhUTUwgNSBzcGVjIGlzIHZlcnkgc3BlY2lmaWMgb24gaG93IHNlbGVjdEFsbENoaWxkcmVuIHNob3VsZCBiZSBpbXBsZW1lbnRlZCBzbyB0aGUgbmF0aXZlIGltcGxlbWVudGF0aW9uIGlzCiAgICAvLyBuZXZlciB1c2VkIGJ5IFJhbmd5LgogICAgc2VsUHJvdG8uc2VsZWN0QWxsQ2hpbGRyZW4gPSBmdW5jdGlvbiAobm9kZSkgewogICAgICAgIGFzc2VydE5vZGVJblNhbWVEb2N1bWVudCh0aGlzLCBub2RlKTsKICAgICAgICB2YXIgcmFuZ2UgPSBhcGkuY3JlYXRlUmFuZ2UoZG9tLmdldERvY3VtZW50KG5vZGUpKTsKICAgICAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHMobm9kZSk7CiAgICAgICAgdGhpcy5yZW1vdmVBbGxSYW5nZXMoKTsKICAgICAgICB0aGlzLmFkZFJhbmdlKHJhbmdlKTsKICAgIH07CgogICAgc2VsUHJvdG8uZGVsZXRlRnJvbURvY3VtZW50ID0gZnVuY3Rpb24gKCkgewogICAgICAgIC8vIFNlcGNpYWwgYmVoYXZpb3VyIHJlcXVpcmVkIGZvciBDb250cm9sIHNlbGVjdGlvbnMKICAgICAgICBpZiAoaW1wbGVtZW50c0NvbnRyb2xSYW5nZSAmJiBpbXBsZW1lbnRzRG9jU2VsZWN0aW9uICYmIHRoaXMuZG9jU2VsZWN0aW9uLnR5cGUgPT0gQ09OVFJPTCkgewogICAgICAgICAgICB2YXIgY29udHJvbFJhbmdlID0gdGhpcy5kb2NTZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTsKICAgICAgICAgICAgdmFyIGVsZW1lbnQ7CiAgICAgICAgICAgIHdoaWxlIChjb250cm9sUmFuZ2UubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBlbGVtZW50ID0gY29udHJvbFJhbmdlLml0ZW0oMCk7CiAgICAgICAgICAgICAgICBjb250cm9sUmFuZ2UucmVtb3ZlKGVsZW1lbnQpOwogICAgICAgICAgICAgICAgZWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGVsZW1lbnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMucmVmcmVzaCgpOwogICAgICAgIH0gZWxzZSBpZiAodGhpcy5yYW5nZUNvdW50KSB7CiAgICAgICAgICAgIHZhciByYW5nZXMgPSB0aGlzLmdldEFsbFJhbmdlcygpOwogICAgICAgICAgICB0aGlzLnJlbW92ZUFsbFJhbmdlcygpOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gcmFuZ2VzLmxlbmd0aDsKICAgICAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgICAgICsraSkgewogICAgICAgICAgICAgICAgcmFuZ2VzW2ldLmRlbGV0ZUNvbnRlbnRzKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gVGhlIEhUTUw1IHNwZWMgc2F5cyBub3RoaW5nIGFib3V0IHdoYXQgdGhlIHNlbGVjdGlvbiBzaG91bGQgY29udGFpbiBhZnRlciBjYWxsaW5nIGRlbGV0ZUNvbnRlbnRzIG9uIGVhY2gKICAgICAgICAgICAgLy8gcmFuZ2UuIEZpcmVmb3ggbW92ZXMgdGhlIHNlbGVjdGlvbiB0byB3aGVyZSB0aGUgZmluYWwgc2VsZWN0ZWQgcmFuZ2Ugd2FzLCBzbyB3ZSBlbXVsYXRlIHRoYXQKICAgICAgICAgICAgdGhpcy5hZGRSYW5nZShyYW5nZXNbbGVuIC0gMV0pOwogICAgICAgIH0KICAgIH07CgogICAgLy8gVGhlIGZvbGxvd2luZyBhcmUgbm9uLXN0YW5kYXJkIGV4dGVuc2lvbnMKICAgIHNlbFByb3RvLmdldEFsbFJhbmdlcyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gdGhpcy5fcmFuZ2VzLnNsaWNlKDApOwogICAgfTsKCiAgICBzZWxQcm90by5zZXRTaW5nbGVSYW5nZSA9IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgIHRoaXMuc2V0UmFuZ2VzKFtyYW5nZV0pOwogICAgfTsKCiAgICBzZWxQcm90by5jb250YWluc05vZGUgPSBmdW5jdGlvbiAobm9kZSwgYWxsb3dQYXJ0aWFsKSB7CiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRoaXMuX3Jhbmdlcy5sZW5ndGg7CiAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgIGlmICh0aGlzLl9yYW5nZXNbaV0uY29udGFpbnNOb2RlKG5vZGUsIGFsbG93UGFydGlhbCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CgogICAgc2VsUHJvdG8udG9IdG1sID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBodG1sID0gIiI7CiAgICAgICAgaWYgKHRoaXMucmFuZ2VDb3VudCkgewogICAgICAgICAgICB2YXIgY29udGFpbmVyID0gRG9tUmFuZ2UuZ2V0UmFuZ2VEb2N1bWVudCh0aGlzLl9yYW5nZXNbMF0pLmNyZWF0ZUVsZW1lbnQoImRpdiIpOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gdGhpcy5fcmFuZ2VzLmxlbmd0aDsKICAgICAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgICAgICsraSkgewogICAgICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMuX3Jhbmdlc1tpXS5jbG9uZUNvbnRlbnRzKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGh0bWwgPSBjb250YWluZXIuaW5uZXJIVE1MOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaHRtbDsKICAgIH07CgogICAgZnVuY3Rpb24gaW5zcGVjdChzZWwpIHsKICAgICAgICB2YXIgcmFuZ2VJbnNwZWN0cyA9IFtdOwogICAgICAgIHZhciBhbmNob3IgPSBuZXcgRG9tUG9zaXRpb24oc2VsLmFuY2hvck5vZGUsIHNlbC5hbmNob3JPZmZzZXQpOwogICAgICAgIHZhciBmb2N1cyA9IG5ldyBEb21Qb3NpdGlvbihzZWwuZm9jdXNOb2RlLCBzZWwuZm9jdXNPZmZzZXQpOwogICAgICAgIHZhciBuYW1lID0gKHR5cGVvZiBzZWwuZ2V0TmFtZSA9PSAiZnVuY3Rpb24iKSA/IHNlbC5nZXROYW1lKCkgOiAiU2VsZWN0aW9uIjsKCiAgICAgICAgaWYgKHR5cGVvZiBzZWwucmFuZ2VDb3VudCAhPSAidW5kZWZpbmVkIikgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gc2VsLnJhbmdlQ291bnQ7CiAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgIHJhbmdlSW5zcGVjdHNbaV0gPSBEb21SYW5nZS5pbnNwZWN0KHNlbC5nZXRSYW5nZUF0KGkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gIlsiICsgbmFtZSArICIoUmFuZ2VzOiAiICsgcmFuZ2VJbnNwZWN0cy5qb2luKCIsICIpICsKICAgICAgICAgICAgIikoYW5jaG9yOiAiICsgYW5jaG9yLmluc3BlY3QoKSArICIsIGZvY3VzOiAiICsgZm9jdXMuaW5zcGVjdCgpICsgIl0iOwogICAgfQoKICAgIHNlbFByb3RvLmdldE5hbWUgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuICJXcmFwcGVkU2VsZWN0aW9uIjsKICAgIH07CgogICAgc2VsUHJvdG8uaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gaW5zcGVjdCh0aGlzKTsKICAgIH07CgogICAgc2VsUHJvdG8uZGV0YWNoID0gZnVuY3Rpb24gKCkgewogICAgICAgIHRoaXMud2luW3dpbmRvd1Byb3BlcnR5TmFtZV0gPSBudWxsOwogICAgICAgIHRoaXMud2luID0gdGhpcy5hbmNob3JOb2RlID0gdGhpcy5mb2N1c05vZGUgPSBudWxsOwogICAgfTsKCiAgICBXcmFwcGVkU2VsZWN0aW9uLmluc3BlY3QgPSBpbnNwZWN0OwoKICAgIGFwaS5TZWxlY3Rpb24gPSBXcmFwcGVkU2VsZWN0aW9uOwoKICAgIGFwaS5zZWxlY3Rpb25Qcm90b3R5cGUgPSBzZWxQcm90bzsKCiAgICBhcGkuYWRkQ3JlYXRlTWlzc2luZ05hdGl2ZUFwaUxpc3RlbmVyKGZ1bmN0aW9uICh3aW4pIHsKICAgICAgICBpZiAodHlwZW9mIHdpbi5nZXRTZWxlY3Rpb24gPT0gInVuZGVmaW5lZCIpIHsKICAgICAgICAgICAgd2luLmdldFNlbGVjdGlvbiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBhcGkuZ2V0U2VsZWN0aW9uKHRoaXMpOwogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICB3aW4gPSBudWxsOwogICAgfSk7Cn0pOwovKgogQmFzZS5qcywgdmVyc2lvbiAxLjFhCiBDb3B5cmlnaHQgMjAwNi0yMDEwLCBEZWFuIEVkd2FyZHMKIExpY2Vuc2U6IGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwCiAqLwoKdmFyIEJhc2UgPSBmdW5jdGlvbiAoKSB7CiAgICAvLyBkdW1teQp9OwoKQmFzZS5leHRlbmQgPSBmdW5jdGlvbiAoX2luc3RhbmNlLCBfc3RhdGljKSB7Ly8gc3ViY2xhc3MKICAgIHZhciBleHRlbmQgPSBCYXNlLnByb3RvdHlwZS5leHRlbmQ7CgogICAgLy8gYnVpbGQgdGhlIHByb3RvdHlwZQogICAgQmFzZS5fcHJvdG90eXBpbmcgPSB0cnVlOwogICAgdmFyIHByb3RvID0gbmV3IHRoaXM7CiAgICBleHRlbmQuY2FsbChwcm90bywgX2luc3RhbmNlKTsKICAgIHByb3RvLmJhc2UgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgLy8gY2FsbCB0aGlzIG1ldGhvZCBmcm9tIGFueSBvdGhlciBtZXRob2QgdG8gaW52b2tlIHRoYXQgbWV0aG9kJ3MgYW5jZXN0b3IKICAgIH07CiAgICBkZWxldGUgQmFzZS5fcHJvdG90eXBpbmc7CgogICAgLy8gY3JlYXRlIHRoZSB3cmFwcGVyIGZvciB0aGUgY29uc3RydWN0b3IgZnVuY3Rpb24KICAgIC8vdmFyIGNvbnN0cnVjdG9yID0gcHJvdG8uY29uc3RydWN0b3IudmFsdWVPZigpOyAvLy1kZWFuCiAgICB2YXIgY29uc3RydWN0b3IgPSBwcm90by5jb25zdHJ1Y3RvcjsKICAgIHZhciBrbGFzcyA9IHByb3RvLmNvbnN0cnVjdG9yID0gZnVuY3Rpb24gKCkgewogICAgICAgIGlmICghQmFzZS5fcHJvdG90eXBpbmcpIHsKICAgICAgICAgICAgaWYgKHRoaXMuX2NvbnN0cnVjdGluZyB8fCB0aGlzLmNvbnN0cnVjdG9yID09IGtsYXNzKSB7Ly8gaW5zdGFudGlhdGlvbgogICAgICAgICAgICAgICAgdGhpcy5fY29uc3RydWN0aW5nID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5fY29uc3RydWN0aW5nOwogICAgICAgICAgICB9IGVsc2UgaWYgKGFyZ3VtZW50c1swXSAhPSBudWxsKSB7Ly8gY2FzdGluZwogICAgICAgICAgICAgICAgcmV0dXJuIChhcmd1bWVudHNbMF0uZXh0ZW5kIHx8IGV4dGVuZCkuY2FsbChhcmd1bWVudHNbMF0sIHByb3RvKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgLy8gYnVpbGQgdGhlIGNsYXNzIGludGVyZmFjZQogICAga2xhc3MuYW5jZXN0b3IgPSB0aGlzOwogICAga2xhc3MuZXh0ZW5kID0gdGhpcy5leHRlbmQ7CiAgICBrbGFzcy5mb3JFYWNoID0gdGhpcy5mb3JFYWNoOwogICAga2xhc3MuaW1wbGVtZW50ID0gdGhpcy5pbXBsZW1lbnQ7CiAgICBrbGFzcy5wcm90b3R5cGUgPSBwcm90bzsKICAgIGtsYXNzLnRvU3RyaW5nID0gdGhpcy50b1N0cmluZzsKICAgIGtsYXNzLnZhbHVlT2YgPSBmdW5jdGlvbiAodHlwZSkgewogICAgICAgIC8vcmV0dXJuICh0eXBlID09ICJvYmplY3QiKSA/IGtsYXNzIDogY29uc3RydWN0b3I7IC8vLWRlYW4KICAgICAgICByZXR1cm4gKHR5cGUgPT0gIm9iamVjdCIpID8ga2xhc3MgOiBjb25zdHJ1Y3Rvci52YWx1ZU9mKCk7CiAgICB9OwogICAgZXh0ZW5kLmNhbGwoa2xhc3MsIF9zdGF0aWMpOwogICAgLy8gY2xhc3MgaW5pdGlhbGlzYXRpb24KICAgIGlmICh0eXBlb2Yga2xhc3MuaW5pdCA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAga2xhc3MuaW5pdCgpOwogICAgfQogICAgcmV0dXJuIGtsYXNzOwp9OwoKQmFzZS5wcm90b3R5cGUgPSB7CiAgICBleHRlbmQgOiBmdW5jdGlvbiAoc291cmNlLCB2YWx1ZSkgewogICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkgey8vIGV4dGVuZGluZyB3aXRoIGEgbmFtZS92YWx1ZSBwYWlyCiAgICAgICAgICAgIHZhciBhbmNlc3RvciA9IHRoaXNbc291cmNlXTsKICAgICAgICAgICAgaWYgKGFuY2VzdG9yICYmICh0eXBlb2YgdmFsdWUgPT0gImZ1bmN0aW9uIikgJiYgLy8gb3ZlcnJpZGluZyBhIG1ldGhvZD8KICAgICAgICAgICAgICAgIC8vIHRoZSB2YWx1ZU9mKCkgY29tcGFyaXNvbiBpcyB0byBhdm9pZCBjaXJjdWxhciByZWZlcmVuY2VzCiAgICAgICAgICAgICAgICAoIWFuY2VzdG9yLnZhbHVlT2YgfHwgYW5jZXN0b3IudmFsdWVPZigpICE9IHZhbHVlLnZhbHVlT2YoKSkgJiYgL1xiYmFzZVxiLy50ZXN0KHZhbHVlKSkgewogICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSB1bmRlcmx5aW5nIG1ldGhvZAogICAgICAgICAgICAgICAgdmFyIG1ldGhvZCA9IHZhbHVlLnZhbHVlT2YoKTsKICAgICAgICAgICAgICAgIC8vIG92ZXJyaWRlCiAgICAgICAgICAgICAgICB2YWx1ZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcHJldmlvdXMgPSB0aGlzLmJhc2UgfHwgQmFzZS5wcm90b3R5cGUuYmFzZTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmJhc2UgPSBhbmNlc3RvcjsKICAgICAgICAgICAgICAgICAgICB2YXIgcmV0dXJuVmFsdWUgPSBtZXRob2QuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmJhc2UgPSBwcmV2aW91czsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0dXJuVmFsdWU7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgLy8gcG9pbnQgdG8gdGhlIHVuZGVybHlpbmcgbWV0aG9kCiAgICAgICAgICAgICAgICB2YWx1ZS52YWx1ZU9mID0gZnVuY3Rpb24gKHR5cGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHR5cGUgPT0gIm9iamVjdCIpID8gdmFsdWUgOiBtZXRob2Q7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgdmFsdWUudG9TdHJpbmcgPSBCYXNlLnRvU3RyaW5nOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXNbc291cmNlXSA9IHZhbHVlOwogICAgICAgIH0gZWxzZSBpZiAoc291cmNlKSB7Ly8gZXh0ZW5kaW5nIHdpdGggYW4gb2JqZWN0IGxpdGVyYWwKICAgICAgICAgICAgdmFyIGV4dGVuZCA9IEJhc2UucHJvdG90eXBlLmV4dGVuZDsKICAgICAgICAgICAgLy8gaWYgdGhpcyBvYmplY3QgaGFzIGEgY3VzdG9taXNlZCBleHRlbmQgbWV0aG9kIHRoZW4gdXNlIGl0CiAgICAgICAgICAgIGlmICghQmFzZS5fcHJvdG90eXBpbmcgJiYgdHlwZW9mIHRoaXMgIT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICAgICAgZXh0ZW5kID0gdGhpcy5leHRlbmQgfHwgZXh0ZW5kOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBwcm90byA9IHt0b1NvdXJjZSA6IG51bGx9OwogICAgICAgICAgICAvLyBkbyB0aGUgInRvU3RyaW5nIiBhbmQgb3RoZXIgbWV0aG9kcyBtYW51YWxseQogICAgICAgICAgICB2YXIgaGlkZGVuID0gWyJjb25zdHJ1Y3RvciIsICJ0b1N0cmluZyIsICJ2YWx1ZU9mIl07CiAgICAgICAgICAgIC8vIGlmIHdlIGFyZSBwcm90b3R5cGluZyB0aGVuIGluY2x1ZGUgdGhlIGNvbnN0cnVjdG9yCiAgICAgICAgICAgIHZhciBpID0gQmFzZS5fcHJvdG90eXBpbmcgPyAwIDogMTsKICAgICAgICAgICAgd2hpbGUgKGtleSA9IGhpZGRlbltpKytdKSB7CiAgICAgICAgICAgICAgICBpZiAoc291cmNlW2tleV0gIT0gcHJvdG9ba2V5XSkgewogICAgICAgICAgICAgICAgICAgIGV4dGVuZC5jYWxsKHRoaXMsIGtleSwgc291cmNlW2tleV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGNvcHkgZWFjaCBvZiB0aGUgc291cmNlIG9iamVjdCdzIHByb3BlcnRpZXMgdG8gdGhpcyBvYmplY3QKICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgewogICAgICAgICAgICAgICAgaWYgKCFwcm90b1trZXldKSB7CiAgICAgICAgICAgICAgICAgICAgZXh0ZW5kLmNhbGwodGhpcywga2V5LCBzb3VyY2Vba2V5XSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICB9Cn07CgovLyBpbml0aWFsaXNlCkJhc2UgPSBCYXNlLmV4dGVuZCh7CiAgICBjb25zdHJ1Y3RvciA6IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLmV4dGVuZChhcmd1bWVudHNbMF0pOwogICAgfQp9LCB7CiAgICBhbmNlc3RvciA6IE9iamVjdCwKICAgIHZlcnNpb24gOiAiMS4xIiwKCiAgICBmb3JFYWNoIDogZnVuY3Rpb24gKG9iamVjdCwgYmxvY2ssIGNvbnRleHQpIHsKICAgICAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7CiAgICAgICAgICAgIGlmICh0aGlzLnByb3RvdHlwZVtrZXldID09PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgIGJsb2NrLmNhbGwoY29udGV4dCwgb2JqZWN0W2tleV0sIGtleSwgb2JqZWN0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sCgogICAgaW1wbGVtZW50IDogZnVuY3Rpb24gKCkgewogICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgaSA8IGFyZ3VtZW50cy5sZW5ndGg7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgaWYgKHR5cGVvZiBhcmd1bWVudHNbaV0gPT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICAgICAgLy8gaWYgaXQncyBhIGZ1bmN0aW9uLCBjYWxsIGl0CiAgICAgICAgICAgICAgICBhcmd1bWVudHNbaV0odGhpcy5wcm90b3R5cGUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gYWRkIHRoZSBpbnRlcmZhY2UgdXNpbmcgdGhlIGV4dGVuZCBtZXRob2QKICAgICAgICAgICAgICAgIHRoaXMucHJvdG90eXBlLmV4dGVuZChhcmd1bWVudHNbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgfSwKCiAgICB0b1N0cmluZyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICByZXR1cm4gU3RyaW5nKHRoaXMudmFsdWVPZigpKTsKICAgIH0KfSk7Ci8qKgogKiBEZXRlY3QgYnJvd3NlciBzdXBwb3J0IGZvciBzcGVjaWZpYyBmZWF0dXJlcwogKi8Kd3lzaWh0bWw1LmJyb3dzZXIgPSAoZnVuY3Rpb24gKCkgewogICAgdmFyIHVzZXJBZ2VudCA9IG5hdmlnYXRvci51c2VyQWdlbnQsCiAgICAgICAgdGVzdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKSwKICAgICAgICAvLyBCcm93c2VyIHNuaWZmaW5nIGlzIHVuZm9ydHVuYXRlbHkgbmVlZGVkIHNpbmNlIHNvbWUgYmVoYXZpb3JzIGFyZSBpbXBvc3NpYmxlIHRvIGZlYXR1cmUgZGV0ZWN0CiAgICAgICAgaXNHZWNrbyA9IHVzZXJBZ2VudC5pbmRleE9mKCJHZWNrbyIpICE9PSAtMSAmJiB1c2VyQWdlbnQuaW5kZXhPZigiS0hUTUwiKSA9PT0gLTEsCiAgICAgICAgaXNXZWJLaXQgPSB1c2VyQWdlbnQuaW5kZXhPZigiQXBwbGVXZWJLaXQvIikgIT09IC0xLAogICAgICAgIGlzQ2hyb21lID0gdXNlckFnZW50LmluZGV4T2YoIkNocm9tZS8iKSAhPT0gLTEsCiAgICAgICAgaXNPcGVyYSA9IHVzZXJBZ2VudC5pbmRleE9mKCJPcGVyYS8iKSAhPT0gLTE7CgogICAgZnVuY3Rpb24gZGV0ZWN0SUUoKSB7CiAgICAgICAgdmFyIHVhID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7CgogICAgICAgIHZhciBtc2llID0gdWEuaW5kZXhPZignTVNJRSAnKTsKICAgICAgICBpZiAobXNpZSA+IDApIHsKICAgICAgICAgICAgLy8gSUUgMTAgb3Igb2xkZXIgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyCiAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh1YS5zdWJzdHJpbmcobXNpZSArIDUsIHVhLmluZGV4T2YoJy4nLCBtc2llKSksIDEwKTsKICAgICAgICB9CgogICAgICAgIHZhciB0cmlkZW50ID0gdWEuaW5kZXhPZignVHJpZGVudC8nKTsKICAgICAgICBpZiAodHJpZGVudCA+IDApIHsKICAgICAgICAgICAgLy8gSUUgMTEgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyCiAgICAgICAgICAgIHZhciBydiA9IHVhLmluZGV4T2YoJ3J2OicpOwogICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodWEuc3Vic3RyaW5nKHJ2ICsgMywgdWEuaW5kZXhPZignLicsIHJ2KSksIDEwKTsKICAgICAgICB9CgogICAgICAgIHZhciBlZGdlID0gdWEuaW5kZXhPZignRWRnZS8nKTsKICAgICAgICBpZiAoZWRnZSA+IDApIHsKICAgICAgICAgICAgLy8gSUUgMTIgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyCiAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh1YS5zdWJzdHJpbmcoZWRnZSArIDUsIHVhLmluZGV4T2YoJy4nLCBlZGdlKSksIDEwKTsKICAgICAgICB9CgogICAgICAgIC8vIG90aGVyIGJyb3dzZXIKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgdmFyIGlzSUUgPSBkZXRlY3RJRSgpOwogICAgdmFyIGlzRmlyZUZveCA9IHVzZXJBZ2VudCA/ICh1c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xKSA6IDA7CgogICAgZnVuY3Rpb24gaW9zVmVyc2lvbih1c2VyQWdlbnQpIHsKICAgICAgICByZXR1cm4gKygoL2lwYWR8aXBob25lfGlwb2QvLnRlc3QodXNlckFnZW50KSAmJiB1c2VyQWdlbnQubWF0Y2goLyBvcyAoXGQrKS4rPyBsaWtlIG1hYyBvcyB4LykpIHx8IFssIDBdKVsxXTsKICAgIH0KCiAgICBmdW5jdGlvbiBhbmRyb2lkVmVyc2lvbih1c2VyQWdlbnQpIHsKICAgICAgICByZXR1cm4gKyh1c2VyQWdlbnQubWF0Y2goL2FuZHJvaWQgKFxkKykvKSB8fCBbLCAwXSlbMV07CiAgICB9CgogICAgcmV0dXJuIHsKICAgICAgICAvLyBTdGF0aWMgdmFyaWFibGUgbmVlZGVkLCBwdWJsaWNseSBhY2Nlc3NpYmxlLCB0byBiZSBhYmxlIG92ZXJyaWRlIGl0IGluIHVuaXQgdGVzdHMKICAgICAgICBVU0VSX0FHRU5UIDogdXNlckFnZW50LAoKICAgICAgICAvLyByZXR1cm4gdHJ1ZSBpZiBicm93c2VyIGlzIGZpcmVmb3gKICAgICAgICBpc0ZpcmVGb3ggOiBpc0ZpcmVGb3gsCgogICAgICAgIC8vIHJldHVybiB0cnVlIGlmIGJyb3dzZXIgaXMgSUUKICAgICAgICBpc0lFIDogaXNJRSwKICAgICAgICAvKioKICAgICAgICAgKiBFeGNsdWRlIGJyb3dzZXJzIHRoYXQgYXJlIG5vdCBjYXBhYmxlIG9mIGRpc3BsYXlpbmcgYW5kIGhhbmRsaW5nCiAgICAgICAgICogY29udGVudEVkaXRhYmxlIGFzIGRlc2lyZWQ6CiAgICAgICAgICogICAgLSBpUGhvbmUsIGlQYWQgKHRlc3RlZCBpT1MgNC4yLjIpIGFuZCBBbmRyb2lkICh0ZXN0ZWQgMi4yKSByZWZ1c2UgdG8gbWFrZSBjb250ZW50RWRpdGFibGVzIGZvY3VzYWJsZQogICAgICAgICAqICAgIC0gSUUgPCA4IGNyZWF0ZSBpbnZhbGlkIG1hcmt1cCBhbmQgY3Jhc2ggcmFuZG9tbHkgZnJvbSB0aW1lIHRvIHRpbWUKICAgICAgICAgKgogICAgICAgICAqIEByZXR1cm4ge0Jvb2xlYW59CiAgICAgICAgICovCiAgICAgICAgc3VwcG9ydGVkIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgdXNlckFnZW50ID0gdGhpcy5VU0VSX0FHRU5ULnRvTG93ZXJDYXNlKCksCiAgICAgICAgICAgICAgICAvLyBFc3NlbnRpYWwgZm9yIG1ha2luZyBodG1sIGVsZW1lbnRzIGVkaXRhYmxlCiAgICAgICAgICAgICAgICBoYXNDb250ZW50RWRpdGFibGVTdXBwb3J0ID0gImNvbnRlbnRFZGl0YWJsZSIgaW4gdGVzdEVsZW1lbnQsCiAgICAgICAgICAgICAgICAvLyBGb2xsb3dpbmcgbWV0aG9kcyBhcmUgbmVlZGVkIGluIG9yZGVyIHRvIGludGVyYWN0IHdpdGggdGhlIGNvbnRlbnRFZGl0YWJsZSBhcmVhCiAgICAgICAgICAgICAgICBoYXNFZGl0aW5nQXBpU3VwcG9ydCA9IGRvY3VtZW50LmV4ZWNDb21tYW5kICYmIGRvY3VtZW50LnF1ZXJ5Q29tbWFuZFN1cHBvcnRlZCAmJiBkb2N1bWVudC5xdWVyeUNvbW1hbmRTdGF0ZSwKICAgICAgICAgICAgICAgIC8vIGRvY3VtZW50IHNlbGVjdG9yIGFwaXMgYXJlIG9ubHkgc3VwcG9ydGVkIGJ5IElFIDgrLCBTYWZhcmkgNCssIENocm9tZSBhbmQgRmlyZWZveCAzLjUrCiAgICAgICAgICAgICAgICBoYXNRdWVyeVNlbGVjdG9yU3VwcG9ydCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IgJiYgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCwKICAgICAgICAgICAgICAgIC8vIGNvbnRlbnRFZGl0YWJsZSBpcyB1bnVzYWJsZSBpbiBtb2JpbGUgYnJvd3NlcnMgKHRlc3RlZCBpT1MgNC4yLjIsIEFuZHJvaWQgMi4yLCBPcGVyYSBNb2JpbGUsIFdlYk9TIDMuMDUpCiAgICAgICAgICAgICAgICBpc0luY29tcGF0aWJsZU1vYmlsZUJyb3dzZXIgPSAodGhpcy5pc0lvcygpICYmIGlvc1ZlcnNpb24odXNlckFnZW50KSA8IDUpIHx8ICh0aGlzLmlzQW5kcm9pZCgpICYmIGFuZHJvaWRWZXJzaW9uKHVzZXJBZ2VudCkgPCA0KSB8fCB1c2VyQWdlbnQuaW5kZXhPZigib3BlcmEgbW9iaSIpICE9PSAtMSB8fCB1c2VyQWdlbnQuaW5kZXhPZigiaHB3b3MvIikgIT09IC0xOwogICAgICAgICAgICByZXR1cm4gaGFzQ29udGVudEVkaXRhYmxlU3VwcG9ydCAmJiBoYXNFZGl0aW5nQXBpU3VwcG9ydCAmJiBoYXNRdWVyeVNlbGVjdG9yU3VwcG9ydCAmJiAhaXNJbmNvbXBhdGlibGVNb2JpbGVCcm93c2VyOwogICAgICAgIH0sCgogICAgICAgIGlzVG91Y2hEZXZpY2UgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnN1cHBvcnRzRXZlbnQoInRvdWNobW92ZSIpOwogICAgICAgIH0sCgogICAgICAgIGlzSW9zIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gKC9pcGFkfGlwaG9uZXxpcG9kL2kpLnRlc3QodGhpcy5VU0VSX0FHRU5UKTsKICAgICAgICB9LAoKICAgICAgICBpc0FuZHJvaWQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLlVTRVJfQUdFTlQuaW5kZXhPZigiQW5kcm9pZCIpICE9PSAtMTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBXaGV0aGVyIHRoZSBicm93c2VyIHN1cHBvcnRzIHNhbmRib3hlZCBpZnJhbWVzCiAgICAgICAgICogQ3VycmVudGx5IG9ubHkgSUUgNisgb2ZmZXJzIHN1Y2ggZmVhdHVyZSA8aWZyYW1lIHNlY3VyaXR5PSJyZXN0cmljdGVkIj4KICAgICAgICAgKgogICAgICAgICAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNDYyMih2PXZzLjg1KS5hc3B4CiAgICAgICAgICogaHR0cDovL2Jsb2dzLm1zZG4uY29tL2IvaWUvYXJjaGl2ZS8yMDA4LzAxLzE4L3VzaW5nLWZyYW1lcy1tb3JlLXNlY3VyZWx5LmFzcHgKICAgICAgICAgKgogICAgICAgICAqIEhUTUw1IHNhbmRib3hlZCBpZnJhbWVzIGFyZSBzdGlsbCBidWdneSBhbmQgdGhlaXIgRE9NIGlzIG5vdCByZWFjaGFibGUgZnJvbSB0aGUgb3V0c2lkZSAoZXhjZXB0IHdoZW4gdXNpbmcgcG9zdE1lc3NhZ2UpCiAgICAgICAgICovCiAgICAgICAgc3VwcG9ydHNTYW5kYm94ZWRJZnJhbWVzIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNJRTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBJRTYrNyB0aHJvdyBhIG1peGVkIGNvbnRlbnQgd2FybmluZyB3aGVuIHRoZSBzcmMgb2YgYW4gaWZyYW1lCiAgICAgICAgICogaXMgZW1wdHkvdW5zZXQgb3IgYWJvdXQ6YmxhbmsKICAgICAgICAgKiB3aW5kb3cucXVlcnlTZWxlY3RvciBpcyBpbXBsZW1lbnRlZCBhcyBvZiBJRTgKICAgICAgICAgKi8KICAgICAgICB0aHJvd3NNaXhlZENvbnRlbnRXYXJuaW5nV2hlbklmcmFtZVNyY0lzRW1wdHkgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAhKCJxdWVyeVNlbGVjdG9yIiBpbiBkb2N1bWVudCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV2hldGhlciB0aGUgY2FyZXQgaXMgY29ycmVjdGx5IGRpc3BsYXllZCBpbiBjb250ZW50RWRpdGFibGUgZWxlbWVudHMKICAgICAgICAgKiBGaXJlZm94IHNvbWV0aW1lcyBzaG93cyBhIGh1Z2UgY2FyZXQgaW4gdGhlIGJlZ2lubmluZyBhZnRlciBmb2N1c2luZwogICAgICAgICAqLwogICAgICAgIGRpc3BsYXlzQ2FyZXRJbkVtcHR5Q29udGVudEVkaXRhYmxlQ29ycmVjdGx5IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNJRTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBPcGVyYSBhbmQgSUUgYXJlIHRoZSBvbmx5IGJyb3dzZXJzIHdobyBvZmZlciB0aGUgY3NzIHZhbHVlCiAgICAgICAgICogaW4gdGhlIG9yaWdpbmFsIHVuaXQsIHRoeCB0byB0aGUgY3VycmVudFN0eWxlIG9iamVjdAogICAgICAgICAqIEFsbCBvdGhlciBicm93c2VycyBwcm92aWRlIHRoZSBjb21wdXRlZCBzdHlsZSBpbiBweCB2aWEgd2luZG93LmdldENvbXB1dGVkU3R5bGUKICAgICAgICAgKi8KICAgICAgICBoYXNDdXJyZW50U3R5bGVQcm9wZXJ0eSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICJjdXJyZW50U3R5bGUiIGluIHRlc3RFbGVtZW50OwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEZpcmVmb3ggb24gT1NYIG5hdmlnYXRlcyB0aHJvdWdoIGhpc3Rvcnkgd2hlbiBoaXR0aW5nIENNRCArIEFycm93IHJpZ2h0L2xlZnQKICAgICAgICAgKi8KICAgICAgICBoYXNIaXN0b3J5SXNzdWUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBpc0dlY2tvOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFdoZXRoZXIgdGhlIGJyb3dzZXIgaW5zZXJ0cyBhIDxicj4gd2hlbiBwcmVzc2luZyBlbnRlciBpbiBhIGNvbnRlbnRFZGl0YWJsZSBlbGVtZW50CiAgICAgICAgICovCiAgICAgICAgaW5zZXJ0c0xpbmVCcmVha3NPblJldHVybiA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIGlzR2Vja287CiAgICAgICAgfSwKCiAgICAgICAgc3VwcG9ydHNQbGFjZWhvbGRlckF0dHJpYnV0ZU9uIDogZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuICJwbGFjZWhvbGRlciIgaW4gZWxlbWVudDsKICAgICAgICB9LAoKICAgICAgICBzdXBwb3J0c0V2ZW50IDogZnVuY3Rpb24gKGV2ZW50TmFtZSkgewogICAgICAgICAgICByZXR1cm4gIm9uIiArIGV2ZW50TmFtZSBpbiB0ZXN0RWxlbWVudCB8fCAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHRlc3RFbGVtZW50LnNldEF0dHJpYnV0ZSgib24iICsgZXZlbnROYW1lLCAicmV0dXJuOyIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlb2YodGVzdEVsZW1lbnRbIm9uIiArIGV2ZW50TmFtZV0pID09PSAiZnVuY3Rpb24iOwogICAgICAgICAgICAgICAgfSkoKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBPcGVyYSBkb2Vzbid0IGNvcnJlY3RseSBmaXJlIGZvY3VzL2JsdXIgZXZlbnRzIHdoZW4gY2xpY2tpbmcgaW4tIGFuZCBvdXRzaWRlIG9mIGlmcmFtZQogICAgICAgICAqLwogICAgICAgIHN1cHBvcnRzRXZlbnRzSW5JZnJhbWVDb3JyZWN0bHkgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAhaXNPcGVyYTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBFdmVyeXRoaW5nIGJlbG93IElFOSBkb2Vzbid0IGtub3cgaG93IHRvIHRyZWF0IEhUTUw1IHRhZ3MKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0IFRoZSBkb2N1bWVudCBvYmplY3Qgb24gd2hpY2ggdG8gY2hlY2sgSFRNTDUgc3VwcG9ydAogICAgICAgICAqCiAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgKiAgICB3eXNpaHRtbDUuYnJvd3Nlci5zdXBwb3J0c0hUTUw1VGFncyhkb2N1bWVudCk7CiAgICAgICAgICovCiAgICAgICAgc3VwcG9ydHNIVE1MNVRhZ3MgOiBmdW5jdGlvbiAoY29udGV4dCkgewogICAgICAgICAgICB2YXIgZWxlbWVudCA9IGNvbnRleHQuY3JlYXRlRWxlbWVudCgiZGl2IiksCiAgICAgICAgICAgICAgICBodG1sNSA9ICI8YXJ0aWNsZT5mb288L2FydGljbGU+IjsKICAgICAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBodG1sNTsKICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQuaW5uZXJIVE1MLnRvTG93ZXJDYXNlKCkgPT09IGh0bWw1OwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrcyB3aGV0aGVyIGEgZG9jdW1lbnQgc3VwcG9ydHMgYSBjZXJ0YWluIHF1ZXJ5Q29tbWFuZAogICAgICAgICAqIEluIHBhcnRpY3VsYXIsIE9wZXJhIG5lZWRzIGEgcmVmZXJlbmNlIHRvIGEgZG9jdW1lbnQgdGhhdCBoYXMgYSBjb250ZW50RWRpdGFibGUgaW4gaXQncyBkb20gdHJlZQogICAgICAgICAqIGluIG9kZXIgdG8gcmVwb3J0IGNvcnJlY3QgcmVzdWx0cwogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGRvYyBEb2N1bWVudCBvYmplY3Qgb24gd2hpY2ggdG8gY2hlY2sgZm9yIGEgcXVlcnkgY29tbWFuZAogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBjb21tYW5kIFRoZSBxdWVyeSBjb21tYW5kIHRvIGNoZWNrIGZvcgogICAgICAgICAqIEByZXR1cm4ge0Jvb2xlYW59CiAgICAgICAgICoKICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAqICAgIHd5c2lodG1sNS5icm93c2VyLnN1cHBvcnRzQ29tbWFuZChkb2N1bWVudCwgImJvbGQiKTsKICAgICAgICAgKi8KICAgICAgICBzdXBwb3J0c0NvbW1hbmQgOiAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAvLyBGb2xsb3dpbmcgY29tbWFuZHMgYXJlIHN1cHBvcnRlZCBidXQgY29udGFpbiBidWdzIGluIHNvbWUgYnJvd3NlcnMKICAgICAgICAgICAgdmFyIGJ1Z2d5Q29tbWFuZHMgPSB7CiAgICAgICAgICAgICAgICAvLyBmb3JtYXRCbG9jayBmYWlscyB3aXRoIHNvbWUgdGFncyAoZWcuIDxibG9ja3F1b3RlPikKICAgICAgICAgICAgICAgICJmb3JtYXRCbG9jayIgOiBpc0lFLAogICAgICAgICAgICAgICAgLy8gV2hlbiBpbnNlcnRpbmcgdW5vcmRlcmVkIG9yIG9yZGVyZWQgbGlzdHMgaW4gRmlyZWZveCwgQ2hyb21lIG9yIFNhZmFyaSwgdGhlIGN1cnJlbnQgc2VsZWN0aW9uIG9yIGxpbmUgZ2V0cwogICAgICAgICAgICAgICAgLy8gY29udmVydGVkIGludG8gYSBsaXN0ICg8dWw+PGxpPi4uLjwvbGk+PC91bD4sIDxvbD48bGk+Li4uPC9saT48L29sPikKICAgICAgICAgICAgICAgIC8vIElFIGFuZCBPcGVyYSBhY3QgYSBiaXQgZGlmZmVyZW50IGhlcmUgYXMgdGhleSBjb252ZXJ0IHRoZSBlbnRpcmUgY29udGVudCBvZiB0aGUgY3VycmVudCBibG9jayBlbGVtZW50IGludG8gYSBsaXN0CiAgICAgICAgICAgICAgICAiaW5zZXJ0VW5vcmRlcmVkTGlzdCIgOiBpc0lFIHx8IGlzV2ViS2l0IHx8IGlzRmlyZUZveCwKICAgICAgICAgICAgICAgICJpbnNlcnRPcmRlcmVkTGlzdCIgOiBpc0lFIHx8IGlzV2ViS2l0CiAgICAgICAgICAgIH07CgogICAgICAgICAgICAvLyBGaXJlZm94IHRocm93cyBlcnJvcnMgZm9yIHF1ZXJ5Q29tbWFuZFN1cHBvcnRlZCwgc28gd2UgaGF2ZSB0byBidWlsZCB1cCBvdXIgb3duIG9iamVjdCBvZiBzdXBwb3J0ZWQgY29tbWFuZHMKICAgICAgICAgICAgdmFyIHN1cHBvcnRlZCA9IHsKICAgICAgICAgICAgICAgICJpbnNlcnRIVE1MIiA6IGlzR2Vja28KICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZG9jLCBjb21tYW5kKSB7CiAgICAgICAgICAgICAgICB2YXIgaXNCdWdneSA9IGJ1Z2d5Q29tbWFuZHNbY29tbWFuZF07CiAgICAgICAgICAgICAgICBpZiAoIWlzQnVnZ3kpIHsKICAgICAgICAgICAgICAgICAgICAvLyBGaXJlZm94IHRocm93cyBlcnJvcnMgd2hlbiBpbnZva2luZyBxdWVyeUNvbW1hbmRTdXBwb3J0ZWQgb3IgcXVlcnlDb21tYW5kRW5hYmxlZAogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkb2MucXVlcnlDb21tYW5kU3VwcG9ydGVkKGNvbW1hbmQpOwogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUxKSB7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9jLnF1ZXJ5Q29tbWFuZEVuYWJsZWQoY29tbWFuZCk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZTIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICEhc3VwcG9ydGVkW2NvbW1hbmRdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfTsKICAgICAgICB9KSgpLAoKICAgICAgICAvKioKICAgICAgICAgKiBJRTogVVJMcyBzdGFydGluZyB3aXRoOgogICAgICAgICAqICAgIHd3dy4sIGh0dHA6Ly8sIGh0dHBzOi8vLCBmdHA6Ly8sIGdvcGhlcjovLywgbWFpbHRvOiwgbmV3Oiwgc25ld3M6LCB0ZWxuZXQ6LCB3YXNpczosIGZpbGU6Ly8sCiAgICAgICAgICogICAgbm50cDovLywgbmV3c3JjOiwgbGRhcDovLywgbGRhcHM6Ly8sIG91dGxvb2s6LCBtaWM6Ly8gYW5kIHVybDoKICAgICAgICAgKiB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgYXV0by1saW5rZWQgd2hlbiBlaXRoZXIgdGhlIHVzZXIgaW5zZXJ0cyB0aGVtIHZpYSBjb3B5JnBhc3RlIG9yIHByZXNzZXMgdGhlCiAgICAgICAgICogc3BhY2UgYmFyIHdoZW4gdGhlIGNhcmV0IGlzIGRpcmVjdGx5IGFmdGVyIHN1Y2ggYW4gdXJsLgogICAgICAgICAqIFRoaXMgYmVoYXZpb3IgY2Fubm90IGVhc2lseSBiZSBhdm9pZGVkIGluIElFIDwgOSBzaW5jZSB0aGUgbG9naWMgaXMgaGFyZGNvZGVkIGluIHRoZSBtc2h0bWwuZGxsCiAgICAgICAgICogKHJlbGF0ZWQgYmxvZyBwb3N0IG9uIG1zZG4KICAgICAgICAgKiBodHRwOi8vYmxvZ3MubXNkbi5jb20vYi9pZWludGVybmFscy9hcmNoaXZlLzIwMDkvMDkvMTcvcHJldmVudC1hdXRvbWF0aWMtaHlwZXJsaW5raW5nLWluLWNvbnRlbnRlZGl0YWJsZS1odG1sLmFzcHgpLgogICAgICAgICAqLwogICAgICAgIGRvZXNBdXRvTGlua2luZ0luQ29udGVudEVkaXRhYmxlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNJRTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBBcyBzdGF0ZWQgYWJvdmUsIElFIGF1dG8gbGlua3MgdXJscyB0eXBlZCBpbnRvIGNvbnRlbnRFZGl0YWJsZSBlbGVtZW50cwogICAgICAgICAqIFNpbmNlIElFOSBpdCdzIHBvc3NpYmxlIHRvIHByZXZlbnQgdGhpcyBiZWhhdmlvcgogICAgICAgICAqLwogICAgICAgIGNhbkRpc2FibGVBdXRvTGlua2luZyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3VwcG9ydHNDb21tYW5kKGRvY3VtZW50LCAiQXV0b1VybERldGVjdCIpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIElFIGxlYXZlcyBhbiBlbXB0eSBwYXJhZ3JhcGggaW4gdGhlIGNvbnRlbnRFZGl0YWJsZSBlbGVtZW50IGFmdGVyIGNsZWFyaW5nIGl0CiAgICAgICAgICogQ2hyb21lL1NhZmFyaSBzb21ldGltZXMgYW4gZW1wdHkgPGRpdj4KICAgICAgICAgKi8KICAgICAgICBjbGVhcnNDb250ZW50RWRpdGFibGVDb3JyZWN0bHkgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBpc0dlY2tvIHx8IGlzT3BlcmEgfHwgaXNXZWJLaXQ7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogSUUgZ2l2ZXMgd3JvbmcgcmVzdWx0cyBmb3IgZ2V0QXR0cmlidXRlCiAgICAgICAgICovCiAgICAgICAgc3VwcG9ydHNHZXRBdHRyaWJ1dGVDb3JyZWN0bHkgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciB0ZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRkIik7CiAgICAgICAgICAgIHJldHVybiB0ZC5nZXRBdHRyaWJ1dGUoInJvd3NwYW4iKSAhPSAiMSI7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV2hlbiBjbGlja2luZyBvbiBpbWFnZXMgaW4gSUUsIE9wZXJhIGFuZCBGaXJlZm94LCB0aGV5IGFyZSBzZWxlY3RlZCwgd2hpY2ggbWFrZXMgaXQgZWFzeSB0byBpbnRlcmFjdCB3aXRoIHRoZW0uCiAgICAgICAgICogQ2hyb21lIGFuZCBTYWZhcmkgYm90aCBkb24ndCBzdXBwb3J0IHRoaXMKICAgICAgICAgKi8KICAgICAgICBjYW5TZWxlY3RJbWFnZXNJbkNvbnRlbnRFZGl0YWJsZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIGlzR2Vja28gfHwgaXNJRSB8fCBpc09wZXJhOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEFsbCBicm93c2VycyBleGNlcHQgU2FmYXJpIGFuZCBDaHJvbWUgYXV0b21hdGljYWxseSBzY3JvbGwgdGhlIHJhbmdlL2NhcmV0IHBvc2l0aW9uIGludG8gdmlldwogICAgICAgICAqLwogICAgICAgIGF1dG9TY3JvbGxzVG9DYXJldCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICFpc1dlYktpdDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBDaGVjayB3aGV0aGVyIHRoZSBicm93c2VyIGF1dG9tYXRpY2FsbHkgY2xvc2VzIHRhZ3MgdGhhdCBkb24ndCBuZWVkIHRvIGJlIG9wZW5lZAogICAgICAgICAqLwogICAgICAgIGF1dG9DbG9zZXNVbmNsb3NlZFRhZ3MgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBjbG9uZWRUZXN0RWxlbWVudCA9IHRlc3RFbGVtZW50LmNsb25lTm9kZShmYWxzZSksCiAgICAgICAgICAgICAgICByZXR1cm5WYWx1ZSwKICAgICAgICAgICAgICAgIGlubmVySFRNTDsKCiAgICAgICAgICAgIGNsb25lZFRlc3RFbGVtZW50LmlubmVySFRNTCA9ICI8cD48ZGl2PjwvZGl2PiI7CiAgICAgICAgICAgIGlubmVySFRNTCA9IGNsb25lZFRlc3RFbGVtZW50LmlubmVySFRNTC50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICByZXR1cm5WYWx1ZSA9IGlubmVySFRNTCA9PT0gIjxwPjwvcD48ZGl2PjwvZGl2PiIgfHwgaW5uZXJIVE1MID09PSAiPHA+PGRpdj48L2Rpdj48L3A+IjsKCiAgICAgICAgICAgIC8vIENhY2hlIHJlc3VsdCBieSBvdmVyd3JpdGluZyBjdXJyZW50IGZ1bmN0aW9uCiAgICAgICAgICAgIHRoaXMuYXV0b0Nsb3Nlc1VuY2xvc2VkVGFncyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTsKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBXaGV0aGVyIHRoZSBicm93c2VyIHN1cHBvcnRzIHRoZSBuYXRpdmUgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSB3aGljaCByZXR1cm5zIGxpdmUgTm9kZUxpc3RzCiAgICAgICAgICovCiAgICAgICAgc3VwcG9ydHNOYXRpdmVHZXRFbGVtZW50c0J5Q2xhc3NOYW1lIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gU3RyaW5nKGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUpLmluZGV4T2YoIltuYXRpdmUgY29kZV0iKSAhPT0gLTE7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQXMgb2Ygbm93ICgxOS4wNC4yMDExKSBvbmx5IHN1cHBvcnRlZCBieSBGaXJlZm94IDQgYW5kIENocm9tZQogICAgICAgICAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9ET00vU2VsZWN0aW9uL21vZGlmeQogICAgICAgICAqLwogICAgICAgIHN1cHBvcnRzU2VsZWN0aW9uTW9kaWZ5IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gImdldFNlbGVjdGlvbiIgaW4gd2luZG93ICYmICJtb2RpZnkiIGluIHdpbmRvdy5nZXRTZWxlY3Rpb24oKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBPcGVyYSBuZWVkcyBhIHdoaXRlIHNwYWNlIGFmdGVyIGEgPGJyPiBpbiBvcmRlciB0byBwb3NpdGlvbiB0aGUgY2FyZXQgY29ycmVjdGx5CiAgICAgICAgICovCiAgICAgICAgbmVlZHNTcGFjZUFmdGVyTGluZUJyZWFrIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNPcGVyYTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBXaGV0aGVyIHRoZSBicm93c2VyIHN1cHBvcnRzIHRoZSBzcGVlY2ggYXBpIG9uIHRoZSBnaXZlbiBlbGVtZW50CiAgICAgICAgICogU2VlIGh0dHA6Ly9taWtlcHVsdHouY29tLzIwMTEvMDMvYWNjZXNzaW5nLWdvb2dsZS1zcGVlY2gtYXBpLWNocm9tZS0xMS8KICAgICAgICAgKgogICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICogICAgdmFyIGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiaW5wdXQiKTsKICAgICAgICAgKiAgICBpZiAod3lzaWh0bWw1LmJyb3dzZXIuc3VwcG9ydHNTcGVlY2hBcGlPbihpbnB1dCkpIHsKICAgICAqICAgICAgLy8gLi4uCiAgICAgKiAgICB9CiAgICAgICAgICovCiAgICAgICAgc3VwcG9ydHNTcGVlY2hBcGlPbiA6IGZ1bmN0aW9uIChpbnB1dCkgewogICAgICAgICAgICB2YXIgY2hyb21lVmVyc2lvbiA9IHVzZXJBZ2VudC5tYXRjaCgvQ2hyb21lXC8oXGQrKS8pIHx8IFssIDBdOwogICAgICAgICAgICByZXR1cm4gY2hyb21lVmVyc2lvblsxXSA+PSAxMSAmJiAoIm9ud2Via2l0c3BlZWNoY2hhbmdlIiBpbiBpbnB1dCB8fCAic3BlZWNoIiBpbiBpbnB1dCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogSUU5IGNyYXNoZXMgd2hlbiBzZXR0aW5nIGEgZ2V0dGVyIHZpYSBPYmplY3QuZGVmaW5lUHJvcGVydHkgb24gWE1MSHR0cFJlcXVlc3Qgb3IgWERvbWFpblJlcXVlc3QKICAgICAgICAgKiBTZWUgaHR0cHM6Ly9jb25uZWN0Lm1pY3Jvc29mdC5jb20vaWUvZmVlZGJhY2svZGV0YWlscy82NTAxMTIKICAgICAgICAgKiBvciB0cnkgdGhlIFBPQyBodHRwOi8vdGlmZnRpZmYuZGUvaWU5X2NyYXNoLwogICAgICAgICAqLwogICAgICAgIGNyYXNoZXNXaGVuRGVmaW5lUHJvcGVydHkgOiBmdW5jdGlvbiAocHJvcGVydHkpIHsKICAgICAgICAgICAgcmV0dXJuIGlzSUUgJiYgKHByb3BlcnR5ID09PSAiWE1MSHR0cFJlcXVlc3QiIHx8IHByb3BlcnR5ID09PSAiWERvbWFpblJlcXVlc3QiKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBJRSBpcyB0aGUgb25seSBicm93c2VyIHdobyBmaXJlcyB0aGUgImZvY3VzIiBldmVudCBub3QgaW1tZWRpYXRlbHkgd2hlbiAuZm9jdXMoKSBpcyBjYWxsZWQgb24gYW4gZWxlbWVudAogICAgICAgICAqLwogICAgICAgIGRvZXNBc3luY0ZvY3VzIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNJRTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBJbiBJRSBpdCdzIGltcHNzaWJsZSBmb3IgdGhlIHVzZXIgYW5kIGZvciB0aGUgc2VsZWN0aW9uIGxpYnJhcnkgdG8gc2V0IHRoZSBjYXJldCBhZnRlciBhbiA8aW1nPiB3aGVuIGl0J3MgdGhlIGxhc3RDaGlsZCBpbiB0aGUgZG9jdW1lbnQKICAgICAgICAgKi8KICAgICAgICBoYXNQcm9ibGVtc1NldHRpbmdDYXJldEFmdGVySW1nIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNJRTsKICAgICAgICB9LAoKICAgICAgICBoYXNVbmRvSW5Db250ZXh0TWVudSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIGlzR2Vja28gfHwgaXNDaHJvbWUgfHwgaXNPcGVyYTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBPcGVyYSBzb21ldGltZXMgZG9lc24ndCBpbnNlcnQgdGhlIG5vZGUgYXQgdGhlIHJpZ2h0IHBvc2l0aW9uIHdoZW4gcmFuZ2UuaW5zZXJ0Tm9kZShzb21lTm9kZSkKICAgICAgICAgKiBpcyB1c2VkIChyZWdhcmRsZXNzIGlmIHJhbmd5IG9yIG5hdGl2ZSkKICAgICAgICAgKiBUaGlzIGVzcGVjaWFsbHkgaGFwcGVucyB3aGVuIHRoZSBjYXJldCBpcyBwb3NpdGlvbmVkIHJpZ2h0IGFmdGVyIGEgPGJyPiBiZWNhdXNlIHRoZW4KICAgICAgICAgKiBpbnNlcnROb2RlKCkgd2lsbCBpbnNlcnQgdGhlIG5vZGUgcmlnaHQgYmVmb3JlIHRoZSA8YnI+CiAgICAgICAgICovCiAgICAgICAgaGFzSW5zZXJ0Tm9kZUlzc3VlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gaXNPcGVyYTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBJRSA4KzkgZG9uJ3QgZmlyZSB0aGUgZm9jdXMgZXZlbnQgb2YgdGhlIDxib2R5PiB3aGVuIHRoZSBpZnJhbWUgZ2V0cyBmb2N1c2VkIChldmVuIHRob3VnaCB0aGUgY2FyZXQgZ2V0cyBzZXQgaW50byB0aGUgPGJvZHk+KQogICAgICAgICAqLwogICAgICAgIGhhc0lmcmFtZUZvY3VzSXNzdWUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBpc0lFOwogICAgICAgIH0KICAgIH07Cn0pKCk7Cnd5c2lodG1sNS5sYW5nLmFycmF5ID0gZnVuY3Rpb24gKGFycikgewogICAgcmV0dXJuIHsKICAgICAgICAvKioKICAgICAgICAgKiBDaGVjayB3aGV0aGVyIGEgZ2l2ZW4gb2JqZWN0IGV4aXN0cyBpbiBhbiBhcnJheQogICAgICAgICAqCiAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgKiAgICB3eXNpaHRtbDUubGFuZy5hcnJheShbMSwgMl0pLmNvbnRhaW5zKDEpOwogICAgICAgICAqICAgIC8vID0+IHRydWUKICAgICAgICAgKi8KICAgICAgICBjb250YWlucyA6IGZ1bmN0aW9uIChuZWVkbGUpIHsKICAgICAgICAgICAgaWYgKGFyci5pbmRleE9mKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gYXJyLmluZGV4T2YobmVlZGxlKSAhPT0gLTE7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gYXJyLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGFycltpXSA9PT0gbmVlZGxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFN1YnN0cmFjdCBvbmUgYXJyYXkgZnJvbSBhbm90aGVyCiAgICAgICAgICoKICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAqICAgIHd5c2lodG1sNS5sYW5nLmFycmF5KFsxLCAyLCAzLCA0XSkud2l0aG91dChbMywgNF0pOwogICAgICAgICAqICAgIC8vID0+IFsxLCAyXQogICAgICAgICAqLwogICAgICAgIHdpdGhvdXQgOiBmdW5jdGlvbiAoYXJyYXlUb1N1YnN0cmFjdCkgewogICAgICAgICAgICBhcnJheVRvU3Vic3RyYWN0ID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoYXJyYXlUb1N1YnN0cmFjdCk7CiAgICAgICAgICAgIHZhciBuZXdBcnIgPSBbXSwKICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgbGVuZ3RoID0gYXJyLmxlbmd0aDsKICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICBpZiAoIWFycmF5VG9TdWJzdHJhY3QuY29udGFpbnMoYXJyW2ldKSkgewogICAgICAgICAgICAgICAgICAgIG5ld0Fyci5wdXNoKGFycltpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ld0FycjsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm4gYSBjbGVhbiBuYXRpdmUgYXJyYXkKICAgICAgICAgKgogICAgICAgICAqIEZvbGxvd2luZyB3aWxsIGNvbnZlcnQgYSBMaXZlIE5vZGVMaXN0IHRvIGEgcHJvcGVyIEFycmF5CiAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgKiAgICB2YXIgY2hpbGROb2RlcyA9IHd5c2lodG1sNS5sYW5nLmFycmF5KGRvY3VtZW50LmJvZHkuY2hpbGROb2RlcykuZ2V0KCk7CiAgICAgICAgICovCiAgICAgICAgZ2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgaSA9IDAsCiAgICAgICAgICAgICAgICBsZW5ndGggPSBhcnIubGVuZ3RoLAogICAgICAgICAgICAgICAgbmV3QXJyYXkgPSBbXTsKICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICBuZXdBcnJheS5wdXNoKGFycltpXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ld0FycmF5OwogICAgICAgIH0KICAgIH07Cn07Cnd5c2lodG1sNS5sYW5nLkRpc3BhdGNoZXIgPSBCYXNlLmV4dGVuZCgKICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LmxhbmcuRGlhbG9nLnByb3RvdHlwZSAqLyB7CiAgICAgICAgb24gOiBmdW5jdGlvbiAoZXZlbnROYW1lLCBoYW5kbGVyKSB7CiAgICAgICAgICAgIHRoaXMuZXZlbnRzID0gdGhpcy5ldmVudHMgfHwge307CiAgICAgICAgICAgIHRoaXMuZXZlbnRzW2V2ZW50TmFtZV0gPSB0aGlzLmV2ZW50c1tldmVudE5hbWVdIHx8IFtdOwogICAgICAgICAgICB0aGlzLmV2ZW50c1tldmVudE5hbWVdLnB1c2goaGFuZGxlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCgogICAgICAgIG9mZiA6IGZ1bmN0aW9uIChldmVudE5hbWUsIGhhbmRsZXIpIHsKICAgICAgICAgICAgdGhpcy5ldmVudHMgPSB0aGlzLmV2ZW50cyB8fCB7fTsKICAgICAgICAgICAgdmFyIGkgPSAwLAogICAgICAgICAgICAgICAgaGFuZGxlcnMsCiAgICAgICAgICAgICAgICBuZXdIYW5kbGVyczsKICAgICAgICAgICAgaWYgKGV2ZW50TmFtZSkgewogICAgICAgICAgICAgICAgaGFuZGxlcnMgPSB0aGlzLmV2ZW50c1tldmVudE5hbWVdIHx8IFtdLAogICAgICAgICAgICAgICAgICAgIG5ld0hhbmRsZXJzID0gW107CiAgICAgICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgICAgICBpIDwgaGFuZGxlcnMubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyc1tpXSAhPT0gaGFuZGxlciAmJiBoYW5kbGVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0hhbmRsZXJzLnB1c2goaGFuZGxlcnNbaV0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzW2V2ZW50TmFtZV0gPSBuZXdIYW5kbGVyczsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIENsZWFuIHVwIGFsbCBldmVudHMKICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzID0ge307CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgZmlyZSA6IGZ1bmN0aW9uIChldmVudE5hbWUsIHBheWxvYWQpIHsKICAgICAgICAgICAgdGhpcy5ldmVudHMgPSB0aGlzLmV2ZW50cyB8fCB7fTsKICAgICAgICAgICAgdmFyIGhhbmRsZXJzID0gdGhpcy5ldmVudHNbZXZlbnROYW1lXSB8fCBbXSwKICAgICAgICAgICAgICAgIGkgPSAwOwogICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgIGkgPCBoYW5kbGVycy5sZW5ndGg7CiAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgIGhhbmRsZXJzW2ldLmNhbGwodGhpcywgcGF5bG9hZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgLy8gZGVwcmVjYXRlZCwgdXNlIC5vbigpCiAgICAgICAgb2JzZXJ2ZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMub24uYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICAvLyBkZXByZWNhdGVkLCB1c2UgLm9mZigpCiAgICAgICAgc3RvcE9ic2VydmluZyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMub2ZmLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfQogICAgfSk7Cnd5c2lodG1sNS5sYW5nLm9iamVjdCA9IGZ1bmN0aW9uIChvYmopIHsKICAgIHJldHVybiB7CiAgICAgICAgLyoqCiAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgKiAgICB3eXNpaHRtbDUubGFuZy5vYmplY3QoeyBmb286IDEsIGJhcjogMSB9KS5tZXJnZSh7IGJhcjogMiwgYmF6OiAzIH0pLmdldCgpOwogICAgICAgICAqICAgIC8vID0+IHsgZm9vOiAxLCBiYXI6IDIsIGJhejogMyB9CiAgICAgICAgICovCiAgICAgICAgbWVyZ2UgOiBmdW5jdGlvbiAob3RoZXJPYmopIHsKICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBvdGhlck9iaikgewogICAgICAgICAgICAgICAgb2JqW2ldID0gb3RoZXJPYmpbaV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gb2JqOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICogICAgd3lzaWh0bWw1Lmxhbmcub2JqZWN0KHsgZm9vOiAxIH0pLmNsb25lKCk7CiAgICAgICAgICogICAgLy8gPT4geyBmb286IDEgfQogICAgICAgICAqLwogICAgICAgIGNsb25lIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgbmV3T2JqID0ge30sCiAgICAgICAgICAgICAgICBpOwogICAgICAgICAgICBmb3IgKGkgaW4gb2JqKSB7CiAgICAgICAgICAgICAgICBuZXdPYmpbaV0gPSBvYmpbaV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ld09iajsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAqICAgIHd5c2lodG1sNS5sYW5nLm9iamVjdChbXSkuaXNBcnJheSgpOwogICAgICAgICAqICAgIC8vID0+IHRydWUKICAgICAgICAgKi8KICAgICAgICBpc0FycmF5IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgPT09ICJbb2JqZWN0IEFycmF5XSI7CiAgICAgICAgfQogICAgfTsKfTsKKGZ1bmN0aW9uICgpIHsKICAgIHZhciBXSElURV9TUEFDRV9TVEFSVCA9IC9eXHMrLywKICAgICAgICBXSElURV9TUEFDRV9FTkQgPSAvXHMrJC87CiAgICB3eXNpaHRtbDUubGFuZy5zdHJpbmcgPSBmdW5jdGlvbiAoc3RyKSB7CiAgICAgICAgc3RyID0gU3RyaW5nKHN0cik7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHd5c2lodG1sNS5sYW5nLnN0cmluZygiICAgZm9vICAgIikudHJpbSgpOwogICAgICAgICAgICAgKiAgICAvLyA9PiAiZm9vIgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdHJpbSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBzdHIucmVwbGFjZShXSElURV9TUEFDRV9TVEFSVCwgIiIpLnJlcGxhY2UoV0hJVEVfU1BBQ0VfRU5ELCAiIik7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICogICAgd3lzaWh0bWw1Lmxhbmcuc3RyaW5nKCJIZWxsbyAje25hbWV9IikuaW50ZXJwb2xhdGUoeyBuYW1lOiAiQ2hyaXN0b3BoZXIiIH0pOwogICAgICAgICAgICAgKiAgICAvLyA9PiAiSGVsbG8gQ2hyaXN0b3BoZXIiCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbnRlcnBvbGF0ZSA6IGZ1bmN0aW9uICh2YXJzKSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHZhcnMpIHsKICAgICAgICAgICAgICAgICAgICBzdHIgPSB0aGlzLnJlcGxhY2UoIiN7IiArIGkgKyAifSIpLmJ5KHZhcnNbaV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHN0cjsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKiAgICB3eXNpaHRtbDUubGFuZy5zdHJpbmcoIkhlbGxvIFRvbSIpLnJlcGxhY2UoIlRvbSIpLndpdGgoIkhhbnMiKTsKICAgICAgICAgICAgICogICAgLy8gPT4gIkhlbGxvIEhhbnMiCiAgICAgICAgICAgICAqLwogICAgICAgICAgICByZXBsYWNlIDogZnVuY3Rpb24gKHNlYXJjaCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICBieSA6IGZ1bmN0aW9uIChyZXBsYWNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHIuc3BsaXQoc2VhcmNoKS5qb2luKHJlcGxhY2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfTsKfSkoKTsKLyoqCiAqIEZpbmQgdXJscyBpbiBkZXNjZW5kYW50IHRleHQgbm9kZXMgb2YgYW4gZWxlbWVudCBhbmQgYXV0by1saW5rcyB0aGVtCiAqIEluc3BpcmVkIGJ5IGh0dHA6Ly9qYW1lcy5wYWRvbHNleS5jb20vamF2YXNjcmlwdC9maW5kLWFuZC1yZXBsYWNlLXRleHQtd2l0aC1qYXZhc2NyaXB0LwogKgogKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgQ29udGFpbmVyIGVsZW1lbnQgaW4gd2hpY2ggdG8gc2VhcmNoIGZvciB1cmxzCiAqCiAqIEBleGFtcGxlCiAqICAgIDxkaXYgaWQ9InRleHQtY29udGFpbmVyIj5QbGVhc2UgY2xpY2sgaGVyZTogd3d3Lmdvb2dsZS5jb208L2Rpdj4KICogICAgPHNjcmlwdD53eXNpaHRtbDUuZG9tLmF1dG9MaW5rKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ0ZXh0LWNvbnRhaW5lciIpKTs8L3NjcmlwdD4KICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgLyoqCiAgICAgICAgICogRG9uJ3QgYXV0by1saW5rIHVybHMgdGhhdCBhcmUgY29udGFpbmVkIGluIHRoZSBmb2xsb3dpbmcgZWxlbWVudHM6CiAgICAgICAgICovCiAgICAgICAgSUdOT1JFX1VSTFNfSU4gPSB3eXNpaHRtbDUubGFuZy5hcnJheShbIkNPREUiLCAiUFJFIiwgIkEiLCAiU0NSSVBUIiwgIkhFQUQiLCAiVElUTEUiLCAiU1RZTEUiXSksCiAgICAgICAgLyoqCiAgICAgICAgICogcmV2aXNpb24gMToKICAgICAgICAgKiAgICAvKFxTK1wuezF9W15cc1wsXC5cIV0rKS9nCiAgICAgICAgICoKICAgICAgICAgKiByZXZpc2lvbiAyOgogICAgICAgICAqICAgIC8oXGIoKChodHRwcz98ZnRwKTpcL1wvKXwod3d3XC4pKVstQS1aMC05KyZAI1wvJT89fl98ITosLjtcW1xdXSpbLUEtWjAtOSsmQCNcLyU9fl98XSkvZ2ltCiAgICAgICAgICoKICAgICAgICAgKiBwdXQgdGhpcyBpbiB0aGUgYmVnaW5uaW5nIGlmIHlvdSBkb24ndCB3YW4ndCB0byBtYXRjaCB3aXRoaW4gYSB3b3JkCiAgICAgICAgICogICAgKF58W1w+XChce1xbXHNcPl0pCiAgICAgICAqLwogICAgICAgIFVSTF9SRUdfRVhQID0gLygoaHR0cHM/OlwvXC98d3d3XC4pW15cczxdezMsfSkvZ2ksCiAgICAgICAgVFJBSUxJTkdfQ0hBUl9SRUdfRVhQID0gLyhbXlx3XC9cLV0oLD8pKSQvaSwKICAgICAgICBNQVhfRElTUExBWV9MRU5HVEggPSAxMDAsCiAgICAgICAgQlJBQ0tFVFMgPSB7IikiIDogIigiLCAiXSIgOiAiWyIsICJ9IiA6ICJ7In07CgogICAgZnVuY3Rpb24gYXV0b0xpbmsoZWxlbWVudCkgewogICAgICAgIGlmIChfaGFzUGFyZW50VGhhdFNob3VsZEJlSWdub3JlZChlbGVtZW50KSkgewogICAgICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgICAgICB9CgogICAgICAgIGlmIChlbGVtZW50ID09PSBlbGVtZW50Lm93bmVyRG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSB7CiAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50Lm93bmVyRG9jdW1lbnQuYm9keTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBfcGFyc2VOb2RlKGVsZW1lbnQpOwogICAgfQoKICAgIC8qKgogICAgICogVGhpcyBpcyBiYXNpY2FsbHkgYSByZWJ1aWxkIG9mCiAgICAgKiB0aGUgcmFpbHMgYXV0b19saW5rX3VybHMgdGV4dCBoZWxwZXIKICAgICAqLwogICAgZnVuY3Rpb24gX2NvbnZlcnRVcmxzVG9MaW5rcyhzdHIpIHsKICAgICAgICByZXR1cm4gc3RyLnJlcGxhY2UoVVJMX1JFR19FWFAsIGZ1bmN0aW9uIChtYXRjaCwgdXJsKSB7CiAgICAgICAgICAgIHZhciBwdW5jdHVhdGlvbiA9ICh1cmwubWF0Y2goVFJBSUxJTkdfQ0hBUl9SRUdfRVhQKSB8fCBbXSlbMV0gfHwgIiIsCiAgICAgICAgICAgICAgICBvcGVuaW5nID0gQlJBQ0tFVFNbcHVuY3R1YXRpb25dOwogICAgICAgICAgICB1cmwgPSB1cmwucmVwbGFjZShUUkFJTElOR19DSEFSX1JFR19FWFAsICIiKTsKCiAgICAgICAgICAgIGlmICh1cmwuc3BsaXQob3BlbmluZykubGVuZ3RoID4gdXJsLnNwbGl0KHB1bmN0dWF0aW9uKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHVybCA9IHVybCArIHB1bmN0dWF0aW9uOwogICAgICAgICAgICAgICAgcHVuY3R1YXRpb24gPSAiIjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgcmVhbFVybCA9IHVybCwKICAgICAgICAgICAgICAgIGRpc3BsYXlVcmwgPSB1cmw7CiAgICAgICAgICAgIGlmICh1cmwubGVuZ3RoID4gTUFYX0RJU1BMQVlfTEVOR1RIKSB7CiAgICAgICAgICAgICAgICBkaXNwbGF5VXJsID0gZGlzcGxheVVybC5zdWJzdHIoMCwgTUFYX0RJU1BMQVlfTEVOR1RIKSArICIuLi4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEFkZCBodHRwIHByZWZpeCBpZiBuZWNlc3NhcnkKICAgICAgICAgICAgaWYgKHJlYWxVcmwuc3Vic3RyKDAsIDQpID09PSAid3d3LiIpIHsKICAgICAgICAgICAgICAgIHJlYWxVcmwgPSAiaHR0cDovLyIgKyByZWFsVXJsOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gJzxhIGhyZWY9IicgKyByZWFsVXJsICsgJyI+JyArIGRpc3BsYXlVcmwgKyAnPC9hPicgKyBwdW5jdHVhdGlvbjsKICAgICAgICB9KTsKICAgIH0KCiAgICAvKioKICAgICAqIENyZWF0ZXMgb3IgKGlmIGFscmVhZHkgY2FjaGVkKSByZXR1cm5zIGEgdGVtcCBlbGVtZW50CiAgICAgKiBmb3IgdGhlIGdpdmVuIGRvY3VtZW50IG9iamVjdAogICAgICovCiAgICBmdW5jdGlvbiBfZ2V0VGVtcEVsZW1lbnQoY29udGV4dCkgewogICAgICAgIHZhciB0ZW1wRWxlbWVudCA9IGNvbnRleHQuX3d5c2lodG1sNV90ZW1wRWxlbWVudDsKICAgICAgICBpZiAoIXRlbXBFbGVtZW50KSB7CiAgICAgICAgICAgIHRlbXBFbGVtZW50ID0gY29udGV4dC5fd3lzaWh0bWw1X3RlbXBFbGVtZW50ID0gY29udGV4dC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRlbXBFbGVtZW50OwogICAgfQoKICAgIC8qKgogICAgICogUmVwbGFjZXMgdGhlIG9yaWdpbmFsIHRleHQgbm9kZXMgd2l0aCB0aGUgbmV3bHkgYXV0by1saW5rZWQgZG9tIHRyZWUKICAgICAqLwogICAgZnVuY3Rpb24gX3dyYXBNYXRjaGVzSW5Ob2RlKHRleHROb2RlKSB7CiAgICAgICAgdmFyIHBhcmVudE5vZGUgPSB0ZXh0Tm9kZS5wYXJlbnROb2RlLAogICAgICAgICAgICB0ZW1wRWxlbWVudCA9IF9nZXRUZW1wRWxlbWVudChwYXJlbnROb2RlLm93bmVyRG9jdW1lbnQpOwoKICAgICAgICAvLyBXZSBuZWVkIHRvIGluc2VydCBhbiBlbXB0eS90ZW1wb3JhcnkgPHNwYW4gLz4gdG8gZml4IElFIHF1aXJrcwogICAgICAgIC8vIEVsc2V3aXNlIElFIHdvdWxkIHN0cmlwIHdoaXRlIHNwYWNlIGluIHRoZSBiZWdpbm5pbmcKICAgICAgICB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPSAiPHNwYW4+PC9zcGFuPiIgKyBfY29udmVydFVybHNUb0xpbmtzKHRleHROb2RlLmRhdGEpOwogICAgICAgIHRlbXBFbGVtZW50LnJlbW92ZUNoaWxkKHRlbXBFbGVtZW50LmZpcnN0Q2hpbGQpOwoKICAgICAgICB3aGlsZSAodGVtcEVsZW1lbnQuZmlyc3RDaGlsZCkgewogICAgICAgICAgICAvLyBpbnNlcnRzIHRlbXBFbGVtZW50LmZpcnN0Q2hpbGQgYmVmb3JlIHRleHROb2RlCiAgICAgICAgICAgIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRlbXBFbGVtZW50LmZpcnN0Q2hpbGQsIHRleHROb2RlKTsKICAgICAgICB9CiAgICAgICAgcGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0ZXh0Tm9kZSk7CiAgICB9CgogICAgZnVuY3Rpb24gX2hhc1BhcmVudFRoYXRTaG91bGRCZUlnbm9yZWQobm9kZSkgewogICAgICAgIHZhciBub2RlTmFtZTsKICAgICAgICB3aGlsZSAobm9kZS5wYXJlbnROb2RlKSB7CiAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgICAgIG5vZGVOYW1lID0gbm9kZS5ub2RlTmFtZTsKICAgICAgICAgICAgaWYgKElHTk9SRV9VUkxTX0lOLmNvbnRhaW5zKG5vZGVOYW1lKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXd5c2lodG1sNS51dGlsLmlzRWRpdG9yTm9kZShub2RlKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcGFyc2VOb2RlKGVsZW1lbnQpIHsKICAgICAgICBpZiAoSUdOT1JFX1VSTFNfSU4uY29udGFpbnMoZWxlbWVudC5ub2RlTmFtZSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKGVsZW1lbnQubm9kZVR5cGUgPT09IHd5c2lodG1sNS5URVhUX05PREUgJiYgZWxlbWVudC5kYXRhLm1hdGNoKFVSTF9SRUdfRVhQKSkgewogICAgICAgICAgICBfd3JhcE1hdGNoZXNJbk5vZGUoZWxlbWVudCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHZhciBjaGlsZE5vZGVzID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoZWxlbWVudC5jaGlsZE5vZGVzKS5nZXQoKSwKICAgICAgICAgICAgY2hpbGROb2Rlc0xlbmd0aCA9IGNoaWxkTm9kZXMubGVuZ3RoLAogICAgICAgICAgICBpID0gMDsKCiAgICAgICAgZm9yICg7CiAgICAgICAgICAgIGkgPCBjaGlsZE5vZGVzTGVuZ3RoOwogICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgX3BhcnNlTm9kZShjaGlsZE5vZGVzW2ldKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBlbGVtZW50OwogICAgfQoKICAgIHd5c2lodG1sNS5kb20uYXV0b0xpbmsgPSBhdXRvTGluazsKCiAgICAvLyBSZXZlYWwgdXJsIHJlZyBleHAgdG8gdGhlIG91dHNpZGUKICAgIHd5c2lodG1sNS5kb20uYXV0b0xpbmsuVVJMX1JFR19FWFAgPSBVUkxfUkVHX0VYUDsKfSkod3lzaWh0bWw1KTsKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBhcGkgPSB3eXNpaHRtbDUuZG9tOwoKICAgIGFwaS5hZGRDbGFzcyA9IGZ1bmN0aW9uIChlbGVtZW50LCBjbGFzc05hbWUpIHsKICAgICAgICB2YXIgY2xhc3NMaXN0ID0gZWxlbWVudC5jbGFzc0xpc3Q7CiAgICAgICAgaWYgKGNsYXNzTGlzdCkgewogICAgICAgICAgICByZXR1cm4gY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpOwogICAgICAgIH0KICAgICAgICBpZiAoYXBpLmhhc0NsYXNzKGVsZW1lbnQsIGNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBlbGVtZW50LmNsYXNzTmFtZSArPSAiICIgKyBjbGFzc05hbWU7CiAgICB9OwoKICAgIGFwaS5yZW1vdmVDbGFzcyA9IGZ1bmN0aW9uIChlbGVtZW50LCBjbGFzc05hbWUpIHsKICAgICAgICB2YXIgY2xhc3NMaXN0ID0gZWxlbWVudC5jbGFzc0xpc3Q7CiAgICAgICAgaWYgKGNsYXNzTGlzdCkgewogICAgICAgICAgICByZXR1cm4gY2xhc3NMaXN0LnJlbW92ZShjbGFzc05hbWUpOwogICAgICAgIH0KCiAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50LmNsYXNzTmFtZS5yZXBsYWNlKG5ldyBSZWdFeHAoIihefFxccyspIiArIGNsYXNzTmFtZSArICIoXFxzK3wkKSIpLCAiICIpOwogICAgfTsKCiAgICBhcGkuaGFzQ2xhc3MgPSBmdW5jdGlvbiAoZWxlbWVudCwgY2xhc3NOYW1lKSB7CiAgICAgICAgdmFyIGNsYXNzTGlzdCA9IGVsZW1lbnQuY2xhc3NMaXN0OwogICAgICAgIGlmIChjbGFzc0xpc3QpIHsKICAgICAgICAgICAgcmV0dXJuIGNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpOwogICAgICAgIH0KCiAgICAgICAgdmFyIGVsZW1lbnRDbGFzc05hbWUgPSBlbGVtZW50LmNsYXNzTmFtZTsKICAgICAgICByZXR1cm4gKGVsZW1lbnRDbGFzc05hbWUubGVuZ3RoID4gMCAmJiAoZWxlbWVudENsYXNzTmFtZSA9PSBjbGFzc05hbWUgfHwgbmV3IFJlZ0V4cCgiKF58XFxzKSIgKyBjbGFzc05hbWUgKyAiKFxcc3wkKSIpLnRlc3QoZWxlbWVudENsYXNzTmFtZSkpKTsKICAgIH07Cn0pKHd5c2lodG1sNSk7Cnd5c2lodG1sNS5kb20uY29udGFpbnMgPSAoZnVuY3Rpb24gKCkgewogICAgdmFyIGRvY3VtZW50RWxlbWVudCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDsKICAgIGlmIChkb2N1bWVudEVsZW1lbnQuY29udGFpbnMpIHsKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGNvbnRhaW5lciwgZWxlbWVudCkgewogICAgICAgICAgICBpZiAoZWxlbWVudC5ub2RlVHlwZSAhPT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERSkgewogICAgICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY29udGFpbmVyICE9PSBlbGVtZW50ICYmIGNvbnRhaW5lci5jb250YWlucyhlbGVtZW50KTsKICAgICAgICB9OwogICAgfSBlbHNlIGlmIChkb2N1bWVudEVsZW1lbnQuY29tcGFyZURvY3VtZW50UG9zaXRpb24pIHsKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGNvbnRhaW5lciwgZWxlbWVudCkgewogICAgICAgICAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9ET00vTm9kZS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbgogICAgICAgICAgICByZXR1cm4gISEoY29udGFpbmVyLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGVsZW1lbnQpICYgMTYpOwogICAgICAgIH07CiAgICB9Cn0pKCk7Ci8qKgogKiBDb252ZXJ0cyBhbiBIVE1MIGZyYWdtZW50L2VsZW1lbnQgaW50byBhIHVub3JkZXJlZC9vcmRlcmVkIGxpc3QKICoKICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IHdoaWNoIHNob3VsZCBiZSB0dXJuZWQgaW50byBhIGxpc3QKICogQHBhcmFtIHtTdHJpbmd9IGxpc3RUeXBlIFRoZSBsaXN0IHR5cGUgaW4gd2hpY2ggdG8gY29udmVydCB0aGUgdHJlZSAoZWl0aGVyICJ1bCIgb3IgIm9sIikKICogQHJldHVybiB7RWxlbWVudH0gVGhlIGNyZWF0ZWQgbGlzdAogKgogKiBAZXhhbXBsZQogKiAgICA8IS0tIEFzc3VtZSB0aGUgZm9sbG93aW5nIGRvbTogLS0+CiAqICAgIDxzcGFuIGlkPSJwc2V1ZG8tbGlzdCI+CiAqICAgICAgZW1pbmVtPGJyPgogKiAgICAgIGRyLiBkcmUKICogICAgICA8ZGl2PjUwIENlbnQ8L2Rpdj4KICogICAgPC9zcGFuPgogKgogKiAgICA8c2NyaXB0PgogKiAgICAgIHd5c2lodG1sNS5kb20uY29udmVydFRvTGlzdChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicHNldWRvLWxpc3QiKSwgInVsIik7CiAqICAgIDwvc2NyaXB0PgogKgogKiAgICA8IS0tIFdpbGwgcmVzdWx0IGluOiAtLT4KICogICAgPHVsPgogKiAgICAgIDxsaT5lbWluZW08L2xpPgogKiAgICAgIDxsaT5kci4gZHJlPC9saT4KICogICAgICA8bGk+NTAgQ2VudDwvbGk+CiAqICAgIDwvdWw+CiAqLwp3eXNpaHRtbDUuZG9tLmNvbnZlcnRUb0xpc3QgPSAoZnVuY3Rpb24gKCkgewogICAgZnVuY3Rpb24gX2NyZWF0ZUxpc3RJdGVtKGRvYywgbGlzdCwgaXNCbG9ja0VsZW1lbnQpIHsKICAgICAgICB2YXIgbGlzdEl0ZW0gPSBkb2MuY3JlYXRlRWxlbWVudCgibGkiKTsKICAgICAgICBsaXN0LmFwcGVuZENoaWxkKGxpc3RJdGVtKTsKICAgICAgICBpZiAoaXNCbG9ja0VsZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGxpc3RJdGVtOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZhciBwYXJhID0gZG9jLmNyZWF0ZUVsZW1lbnQoInAiKTsKICAgICAgICAgICAgbGlzdEl0ZW0uYXBwZW5kQ2hpbGQocGFyYSk7CiAgICAgICAgICAgIHJldHVybiBwYXJhOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfY3JlYXRlTGlzdChkb2MsIHR5cGUsIGxpc3RUeXBlKSB7CiAgICAgICAgdmFyIGUgPSBkb2MuY3JlYXRlRWxlbWVudCh0eXBlKTsKICAgICAgICBpZiAobGlzdFR5cGUgJiYgbGlzdFR5cGUgIT0gIk9yZGVyZWQiKSB7CiAgICAgICAgICAgIGUuc2V0QXR0cmlidXRlKCJ0eXBlIiwgbGlzdFR5cGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZTsKICAgIH0KCiAgICBmdW5jdGlvbiBjb252ZXJ0VG9MaXN0KGVsZW1lbnQsIGxpc3RUeXBlLCB0eXBlKSB7CiAgICAgICAgaWYgKGVsZW1lbnQubm9kZU5hbWUgPT09ICJVTCIgfHwgZWxlbWVudC5ub2RlTmFtZSA9PT0gIk9MIiB8fCBlbGVtZW50Lm5vZGVOYW1lID09PSAiTUVOVSIpIHsKICAgICAgICAgICAgLy8gQWxyZWFkeSBhIGxpc3QKICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7CiAgICAgICAgfQogICAgICAgIHZhciBkb2MgPSBlbGVtZW50Lm93bmVyRG9jdW1lbnQsCiAgICAgICAgICAgIGxpc3QgPSBfY3JlYXRlTGlzdChkb2MsIGxpc3RUeXBlLCB0eXBlKSwKICAgICAgICAgICAgbGluZUJyZWFrcyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgiYnIiKSwKICAgICAgICAgICAgbGluZUJyZWFrc0xlbmd0aCA9IGxpbmVCcmVha3MubGVuZ3RoLAogICAgICAgICAgICBjaGlsZE5vZGVzLAogICAgICAgICAgICBjaGlsZE5vZGVzTGVuZ3RoLAogICAgICAgICAgICBjaGlsZE5vZGUsCiAgICAgICAgICAgIGxpbmVCcmVhaywKICAgICAgICAgICAgcGFyZW50Tm9kZSwKICAgICAgICAgICAgaXNCbG9ja0VsZW1lbnQsCiAgICAgICAgICAgIGlzTGluZUJyZWFrLAogICAgICAgICAgICBjdXJyZW50TGlzdEl0ZW0sCiAgICAgICAgICAgIGk7CgogICAgICAgIC8vIEZpcnN0IGZpbmQgPGJyPiBhdCB0aGUgZW5kIG9mIGlubGluZSBlbGVtZW50cyBhbmQgbW92ZSB0aGVtIGJlaGluZCB0aGVtCiAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgIGkgPCBsaW5lQnJlYWtzTGVuZ3RoOwogICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgIGxpbmVCcmVhayA9IGxpbmVCcmVha3NbaV07CiAgICAgICAgICAgIHdoaWxlICgocGFyZW50Tm9kZSA9IGxpbmVCcmVhay5wYXJlbnROb2RlKSAmJiBwYXJlbnROb2RlICE9PSBlbGVtZW50ICYmIHBhcmVudE5vZGUubGFzdENoaWxkID09PSBsaW5lQnJlYWspIHsKICAgICAgICAgICAgICAgIGlmICh3eXNpaHRtbDUuZG9tLmdldFN0eWxlKCJkaXNwbGF5IikuZnJvbShwYXJlbnROb2RlKSA9PT0gImJsb2NrIikgewogICAgICAgICAgICAgICAgICAgIHBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobGluZUJyZWFrKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHd5c2lodG1sNS5kb20uaW5zZXJ0KGxpbmVCcmVhaykuYWZ0ZXIobGluZUJyZWFrLnBhcmVudE5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBjaGlsZE5vZGVzID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoZWxlbWVudC5jaGlsZE5vZGVzKS5nZXQoKTsKICAgICAgICBjaGlsZE5vZGVzTGVuZ3RoID0gY2hpbGROb2Rlcy5sZW5ndGg7CiAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgIGkgPCBjaGlsZE5vZGVzTGVuZ3RoOwogICAgICAgICAgICAgaSsrKSB7CgogICAgICAgICAgICBjaGlsZE5vZGUgPSBjaGlsZE5vZGVzW2ldOwogICAgICAgICAgICBpc0Jsb2NrRWxlbWVudCA9IHd5c2lodG1sNS5kb20uZ2V0U3R5bGUoImRpc3BsYXkiKS5mcm9tKGNoaWxkTm9kZSkgPT09ICJibG9jayIgfHwgKGNoaWxkTm9kZSAmJiBjaGlsZE5vZGUucXVlcnlTZWxlY3RvciAmJiBjaGlsZE5vZGUucXVlcnlTZWxlY3Rvcih3eXNpaHRtbDUuQkxPQ0tfRUxFTUVOVFNfR1JPVVAuam9pbigiLCIpKSk7CiAgICAgICAgICAgIGlzTGluZUJyZWFrID0gY2hpbGROb2RlLm5vZGVOYW1lID09PSAiQlIiOwoKICAgICAgICAgICAgaWYgKGNoaWxkTm9kZSAmJiBjaGlsZE5vZGUuY2xhc3NOYW1lID09ICJfd3lzaWh0bWw1LXRlbXAtcGxhY2Vob2xkZXIiKSB7Ly8gaWdub3JlIGNoaWxkTm9kZSBjcmV0ZWQgYnkgZXhlY3V0ZUFuZFJlc3RvcmUKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNCbG9ja0VsZW1lbnQpIHsKICAgICAgICAgICAgICAgIGN1cnJlbnRMaXN0SXRlbSA9IF9jcmVhdGVMaXN0SXRlbShkb2MsIGxpc3QsIGlzQmxvY2tFbGVtZW50KTsKICAgICAgICAgICAgICAgIGN1cnJlbnRMaXN0SXRlbS5hcHBlbmRDaGlsZChjaGlsZE5vZGUpOwogICAgICAgICAgICAgICAgY3VycmVudExpc3RJdGVtID0gbnVsbDsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNMaW5lQnJlYWspIHsKICAgICAgICAgICAgICAgIC8vIE9ubHkgY3JlYXRlIGEgbmV3IGxpc3QgaXRlbSBpbiB0aGUgbmV4dCBpdGVyYXRpb24gd2hlbiB0aGUgY3VycmVudCBvbmUgaGFzIGFscmVhZHkgY29udGVudCwKICAgICAgICAgICAgICAgIGlmIChpICE9IGNoaWxkTm9kZXNMZW5ndGggLSAxKSB7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudExpc3RJdGVtID0gKGN1cnJlbnRMaXN0SXRlbSAmJiBjdXJyZW50TGlzdEl0ZW0uZmlyc3RDaGlsZCkgPyBudWxsIDogY3VycmVudExpc3RJdGVtOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJlbnRMaXN0SXRlbSA9IGN1cnJlbnRMaXN0SXRlbSB8fCBfY3JlYXRlTGlzdEl0ZW0oZG9jLCBsaXN0LCBpc0Jsb2NrRWxlbWVudCk7CiAgICAgICAgICAgIGN1cnJlbnRMaXN0SXRlbS5hcHBlbmRDaGlsZChjaGlsZE5vZGUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGNoaWxkTm9kZXMubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgIF9jcmVhdGVMaXN0SXRlbShkb2MsIGxpc3QpOwogICAgICAgIH0KCiAgICAgICAgZWxlbWVudC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChsaXN0LCBlbGVtZW50KTsKICAgICAgICByZXR1cm4gbGlzdDsKICAgIH0KCiAgICByZXR1cm4gY29udmVydFRvTGlzdDsKfSkoKTsKLyoqCiAqIENvcHkgYSBzZXQgb2YgYXR0cmlidXRlcyBmcm9tIG9uZSBlbGVtZW50IHRvIGFub3RoZXIKICoKICogQHBhcmFtIHtBcnJheX0gYXR0cmlidXRlc1RvQ29weSBMaXN0IG9mIGF0dHJpYnV0ZXMgd2hpY2ggc2hvdWxkIGJlIGNvcGllZAogKiBAcmV0dXJuIHtPYmplY3R9IFJldHVybnMgYW4gb2JqZWN0IHdoaWNoIG9mZmVycyB0aGUgImZyb20iIG1ldGhvZCB3aGljaCBjYW4gYmUgaW52b2tlZCB3aXRoIHRoZSBlbGVtZW50IHdoZXJlIHRvCiAqICAgIGNvcHkgdGhlIGF0dHJpYnV0ZXMgZnJvbS4sIHRoaXMgYWdhaW4gcmV0dXJucyBhbiBvYmplY3Qgd2hpY2ggcHJvdmlkZXMgYSBtZXRob2QgbmFtZWQgInRvIiB3aGljaCBjYW4gYmUgaW52b2tlZAogKiAgICB3aXRoIHRoZSBlbGVtZW50IHdoZXJlIHRvIGNvcHkgdGhlIGF0dHJpYnV0ZXMgdG8gKHNlZSBleGFtcGxlKQogKgogKiBAZXhhbXBsZQogKiAgICB2YXIgdGV4dGFyZWEgICAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJ0ZXh0YXJlYSIpLAogKiAgICAgICAgZGl2ICAgICAgICAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJkaXZbY29udGVudGVkaXRhYmxlPXRydWVdIiksCiAqICAgICAgICBhbm90aGVyRGl2ICA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImRpdi5wcmV2aWV3Iik7CiAqICAgIHd5c2lodG1sNS5kb20uY29weUF0dHJpYnV0ZXMoWyJzcGVsbGNoZWNrIiwgInZhbHVlIiwgInBsYWNlaG9sZGVyIl0pLmZyb20odGV4dGFyZWEpLnRvKGRpdikuYW5kVG8oYW5vdGhlckRpdik7CiAqCiAqLwp3eXNpaHRtbDUuZG9tLmNvcHlBdHRyaWJ1dGVzID0gZnVuY3Rpb24gKGF0dHJpYnV0ZXNUb0NvcHkpIHsKICAgIHJldHVybiB7CiAgICAgICAgZnJvbSA6IGZ1bmN0aW9uIChlbGVtZW50VG9Db3B5RnJvbSkgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgdG8gOiBmdW5jdGlvbiAoZWxlbWVudFRvQ29weVRvKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgaSA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IGF0dHJpYnV0ZXNUb0NvcHkubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgIGZvciAoOwogICAgICAgICAgICAgICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlID0gYXR0cmlidXRlc1RvQ29weVtpXTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZihlbGVtZW50VG9Db3B5RnJvbVthdHRyaWJ1dGVdKSAhPT0gInVuZGVmaW5lZCIgJiYgZWxlbWVudFRvQ29weUZyb21bYXR0cmlidXRlXSAhPT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRUb0NvcHlUb1thdHRyaWJ1dGVdID0gZWxlbWVudFRvQ29weUZyb21bYXR0cmlidXRlXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4ge2FuZFRvIDogYXJndW1lbnRzLmNhbGxlZX07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfTsKfTsKLyoqCiAqIENvcHkgYSBzZXQgb2Ygc3R5bGVzIGZyb20gb25lIGVsZW1lbnQgdG8gYW5vdGhlcgogKiBQbGVhc2Ugbm90ZSB0aGF0IHRoaXMgb25seSB3b3JrcyBwcm9wZXJseSBhY3Jvc3MgYnJvd3NlcnMgd2hlbiB0aGUgZWxlbWVudCBmcm9tIHdoaWNoIHRvIGNvcHkgdGhlIHN0eWxlcwogKiBpcyBpbiB0aGUgZG9tCiAqCiAqIEludGVyZXN0aW5nIGFydGljbGUgb24gaG93IHRvIGNvcHkgc3R5bGVzCiAqCiAqIEBwYXJhbSB7QXJyYXl9IHN0eWxlc1RvQ29weSBMaXN0IG9mIHN0eWxlcyB3aGljaCBzaG91bGQgYmUgY29waWVkCiAqIEByZXR1cm4ge09iamVjdH0gUmV0dXJucyBhbiBvYmplY3Qgd2hpY2ggb2ZmZXJzIHRoZSAiZnJvbSIgbWV0aG9kIHdoaWNoIGNhbiBiZSBpbnZva2VkIHdpdGggdGhlIGVsZW1lbnQgd2hlcmUgdG8KICogICAgY29weSB0aGUgc3R5bGVzIGZyb20uLCB0aGlzIGFnYWluIHJldHVybnMgYW4gb2JqZWN0IHdoaWNoIHByb3ZpZGVzIGEgbWV0aG9kIG5hbWVkICJ0byIgd2hpY2ggY2FuIGJlIGludm9rZWQKICogICAgd2l0aCB0aGUgZWxlbWVudCB3aGVyZSB0byBjb3B5IHRoZSBzdHlsZXMgdG8gKHNlZSBleGFtcGxlKQogKgogKiBAZXhhbXBsZQogKiAgICB2YXIgdGV4dGFyZWEgICAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJ0ZXh0YXJlYSIpLAogKiAgICAgICAgZGl2ICAgICAgICAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCJkaXZbY29udGVudGVkaXRhYmxlPXRydWVdIiksCiAqICAgICAgICBhbm90aGVyRGl2ICA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImRpdi5wcmV2aWV3Iik7CiAqICAgIHd5c2lodG1sNS5kb20uY29weVN0eWxlcyhbIm92ZXJmbG93LXkiLCAid2lkdGgiLCAiaGVpZ2h0Il0pLmZyb20odGV4dGFyZWEpLnRvKGRpdikuYW5kVG8oYW5vdGhlckRpdik7CiAqCiAqLwooZnVuY3Rpb24gKGRvbSkgewoKICAgIC8qKgogICAgICogTW96aWxsYSwgV2ViS2l0IGFuZCBPcGVyYSByZWNhbGN1bGF0ZSB0aGUgY29tcHV0ZWQgd2lkdGggd2hlbiBib3gtc2l6aW5nOiBib2Rlci1ib3g7IGlzIHNldAogICAgICogU28gaWYgYW4gZWxlbWVudCBoYXMgIndpZHRoOiAyMDBweDsgLW1vei1ib3gtc2l6aW5nOiBib3JkZXItYm94OyBib3JkZXI6IDFweDsiIHRoZW4KICAgICAqIGl0cyBjb21wdXRlZCBjc3Mgd2lkdGggd2lsbCBiZSAxOThweAogICAgICoKICAgICAqIFNlZSBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD01MjA5OTIKICAgICAqLwogICAgdmFyIEJPWF9TSVpJTkdfUFJPUEVSVElFUyA9IFsiLXdlYmtpdC1ib3gtc2l6aW5nIiwgIi1tb3otYm94LXNpemluZyIsICItbXMtYm94LXNpemluZyIsICJib3gtc2l6aW5nIl07CgogICAgdmFyIHNob3VsZElnbm9yZUJveFNpemluZ0JvcmRlckJveCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgICAgaWYgKGhhc0JveFNpemluZ0JvcmRlckJveChlbGVtZW50KSkgewogICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQoZG9tLmdldFN0eWxlKCJ3aWR0aCIpLmZyb20oZWxlbWVudCksIDEwKSA8IGVsZW1lbnQub2Zmc2V0V2lkdGg7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CgogICAgdmFyIGhhc0JveFNpemluZ0JvcmRlckJveCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgICAgdmFyIGkgPSAwLAogICAgICAgICAgICBsZW5ndGggPSBCT1hfU0laSU5HX1BST1BFUlRJRVMubGVuZ3RoOwogICAgICAgIGZvciAoOwogICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgaWYgKGRvbS5nZXRTdHlsZShCT1hfU0laSU5HX1BST1BFUlRJRVNbaV0pLmZyb20oZWxlbWVudCkgPT09ICJib3JkZXItYm94IikgewogICAgICAgICAgICAgICAgcmV0dXJuIEJPWF9TSVpJTkdfUFJPUEVSVElFU1tpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgZG9tLmNvcHlTdHlsZXMgPSBmdW5jdGlvbiAoc3R5bGVzVG9Db3B5KSB7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgZnJvbSA6IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgICAgICAgICAgICBpZiAoc2hvdWxkSWdub3JlQm94U2l6aW5nQm9yZGVyQm94KGVsZW1lbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgc3R5bGVzVG9Db3B5ID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoc3R5bGVzVG9Db3B5KS53aXRob3V0KEJPWF9TSVpJTkdfUFJPUEVSVElFUyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyIGNzc1RleHQgPSAiIiwKICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSBzdHlsZXNUb0NvcHkubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OwogICAgICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eSA9IHN0eWxlc1RvQ29weVtpXTsKICAgICAgICAgICAgICAgICAgICBjc3NUZXh0ICs9IHByb3BlcnR5ICsgIjoiICsgZG9tLmdldFN0eWxlKHByb3BlcnR5KS5mcm9tKGVsZW1lbnQpICsgIjsiOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAgICAgdG8gOiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBkb20uc2V0U3R5bGVzKGNzc1RleHQpLm9uKGVsZW1lbnQpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge2FuZFRvIDogYXJndW1lbnRzLmNhbGxlZX07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9Owp9KSh3eXNpaHRtbDUuZG9tKTsKLyoqCiAqIEV2ZW50IERlbGVnYXRpb24KICoKICogQGV4YW1wbGUKICogICAgd3lzaWh0bWw1LmRvbS5kZWxlZ2F0ZShkb2N1bWVudC5ib2R5LCAiYSIsICJjbGljayIsIGZ1bmN0aW9uKCkgewogKiAgICAgIC8vIGZvbwogKiAgICB9KTsKICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CgogICAgd3lzaWh0bWw1LmRvbS5kZWxlZ2F0ZSA9IGZ1bmN0aW9uIChjb250YWluZXIsIHNlbGVjdG9yLCBldmVudE5hbWUsIGhhbmRsZXIpIHsKICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmRvbS5vYnNlcnZlKGNvbnRhaW5lciwgZXZlbnROYW1lLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgdmFyIHRhcmdldCA9IGV2ZW50LnRhcmdldCwKICAgICAgICAgICAgICAgIG1hdGNoID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpKTsKCiAgICAgICAgICAgIHdoaWxlICh0YXJnZXQgJiYgdGFyZ2V0ICE9PSBjb250YWluZXIpIHsKICAgICAgICAgICAgICAgIGlmIChtYXRjaC5jb250YWlucyh0YXJnZXQpKSB7CiAgICAgICAgICAgICAgICAgICAgaGFuZGxlci5jYWxsKHRhcmdldCwgZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBSZXR1cm5zIHRoZSBnaXZlbiBodG1sIHdyYXBwZWQgaW4gYSBkaXYgZWxlbWVudAogKgogKiBGaXhpbmcgSUUncyBpbmFiaWxpdHkgdG8gdHJlYXQgdW5rbm93biBlbGVtZW50cyAoSFRNTDUgc2VjdGlvbiwgYXJ0aWNsZSwgLi4uKSBjb3JyZWN0bHkKICogd2hlbiBpbnNlcnRlZCB2aWEgaW5uZXJIVE1MCiAqCiAqIEBwYXJhbSB7U3RyaW5nfSBodG1sIFRoZSBodG1sIHdoaWNoIHNob3VsZCBiZSB3cmFwcGVkIGluIGEgZG9tIGVsZW1lbnQKICogQHBhcmFtIHtPYmVqY3R9IFtjb250ZXh0XSBEb2N1bWVudCBvYmplY3Qgb2YgdGhlIGNvbnRleHQgdGhlIGh0bWwgYmVsb25ncyB0bwogKgogKiBAZXhhbXBsZQogKiAgICB3eXNpaHRtbDUuZG9tLmdldEFzRG9tKCI8YXJ0aWNsZT5mb288L2FydGljbGU+Iik7CiAqLwp3eXNpaHRtbDUuZG9tLmdldEFzRG9tID0gKGZ1bmN0aW9uICgpIHsKCiAgICB2YXIgX2lubmVySFRNTFNoaXYgPSBmdW5jdGlvbiAoaHRtbCwgY29udGV4dCkgewogICAgICAgIHZhciB0ZW1wRWxlbWVudCA9IGNvbnRleHQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CiAgICAgICAgdGVtcEVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICJub25lIjsKICAgICAgICBjb250ZXh0LmJvZHkuYXBwZW5kQ2hpbGQodGVtcEVsZW1lbnQpOwogICAgICAgIC8vIElFIHRocm93cyBhbiBleGNlcHRpb24gd2hlbiB0cnlpbmcgdG8gaW5zZXJ0IDxmcmFtZXNldD48L2ZyYW1lc2V0PiB2aWEgaW5uZXJIVE1MCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdGVtcEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgfQogICAgICAgIGNvbnRleHQuYm9keS5yZW1vdmVDaGlsZCh0ZW1wRWxlbWVudCk7CiAgICAgICAgcmV0dXJuIHRlbXBFbGVtZW50OwogICAgfTsKCiAgICAvKioKICAgICAqIE1ha2Ugc3VyZSBJRSBzdXBwb3J0cyBIVE1MNSB0YWdzLCB3aGljaCBpcyBhY2NvbXBsaXNoZWQgYnkgc2ltcGx5IGNyZWF0aW5nIG9uZSBpbnN0YW5jZSBvZiBlYWNoIGVsZW1lbnQKICAgICAqLwogICAgdmFyIF9lbnN1cmVIVE1MNUNvbXBhdGliaWxpdHkgPSBmdW5jdGlvbiAoY29udGV4dCkgewogICAgICAgIGlmIChjb250ZXh0Ll93eXNpaHRtbDVfc3VwcG9ydHNIVE1MNVRhZ3MpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gSFRNTDVfRUxFTUVOVFMubGVuZ3RoOwogICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoSFRNTDVfRUxFTUVOVFNbaV0pOwogICAgICAgIH0KICAgICAgICBjb250ZXh0Ll93eXNpaHRtbDVfc3VwcG9ydHNIVE1MNVRhZ3MgPSB0cnVlOwogICAgfTsKCiAgICAvKioKICAgICAqIExpc3Qgb2YgaHRtbDUgdGFncwogICAgICogdGFrZW4gZnJvbSBodHRwOi8vc2ltb24uaHRtbDUub3JnL2h0bWw1LWVsZW1lbnRzCiAgICAgKi8KICAgIHZhciBIVE1MNV9FTEVNRU5UUyA9IFsKICAgICAgICAiYWJiciIsICJhcnRpY2xlIiwgImFzaWRlIiwgImF1ZGlvIiwgImJkaSIsICJjYW52YXMiLCAiY29tbWFuZCIsICJkYXRhbGlzdCIsICJkZXRhaWxzIiwgImZpZ2NhcHRpb24iLAogICAgICAgICJmaWd1cmUiLCAiZm9vdGVyIiwgImhlYWRlciIsICJoZ3JvdXAiLCAia2V5Z2VuIiwgIm1hcmsiLCAibWV0ZXIiLCAibmF2IiwgIm91dHB1dCIsICJwcm9ncmVzcyIsCiAgICAgICAgInJwIiwgInJ0IiwgInJ1YnkiLCAic3ZnIiwgInNlY3Rpb24iLCAic291cmNlIiwgInN1bW1hcnkiLCAidGltZSIsICJ0cmFjayIsICJ2aWRlbyIsICJ3YnIiCiAgICBdOwoKICAgIHJldHVybiBmdW5jdGlvbiAoaHRtbCwgY29udGV4dCkgewogICAgICAgIGNvbnRleHQgPSBjb250ZXh0IHx8IGRvY3VtZW50OwogICAgICAgIHZhciB0ZW1wRWxlbWVudDsKICAgICAgICBpZiAodHlwZW9mKGh0bWwpID09PSAib2JqZWN0IiAmJiBodG1sLm5vZGVUeXBlKSB7CiAgICAgICAgICAgIHRlbXBFbGVtZW50ID0gY29udGV4dC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKICAgICAgICAgICAgdGVtcEVsZW1lbnQuYXBwZW5kQ2hpbGQoaHRtbCk7CiAgICAgICAgfSBlbHNlIGlmICh3eXNpaHRtbDUuYnJvd3Nlci5zdXBwb3J0c0hUTUw1VGFncyhjb250ZXh0KSkgewogICAgICAgICAgICB0ZW1wRWxlbWVudCA9IGNvbnRleHQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CiAgICAgICAgICAgIHRlbXBFbGVtZW50LmlubmVySFRNTCA9IGh0bWw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgX2Vuc3VyZUhUTUw1Q29tcGF0aWJpbGl0eShjb250ZXh0KTsKICAgICAgICAgICAgdGVtcEVsZW1lbnQgPSBfaW5uZXJIVE1MU2hpdihodG1sLCBjb250ZXh0KTsKICAgICAgICB9CiAgICAgICAgdGVtcEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgid3lzaWh0bWw1LWVkaXRvciIpOwogICAgICAgIHJldHVybiB0ZW1wRWxlbWVudDsKICAgIH07Cn0pKCk7Ci8qKgogKiBXYWxrcyB0aGUgZG9tIHRyZWUgZnJvbSB0aGUgZ2l2ZW4gbm9kZSB1cCB1bnRpbCBpdCBmaW5kcyBhIG1hdGNoCiAqIERlc2lnbmVkIGZvciBvcHRpbWFsIHBlcmZvcm1hbmNlLgogKgogKiBAcGFyYW0ge0VsZW1lbnR9IG5vZGUgVGhlIGZyb20gd2hpY2ggdG8gY2hlY2sgdGhlIHBhcmVudCBub2RlcwogKiBAcGFyYW0ge09iamVjdH0gbWF0Y2hpbmdTZXQgT2JqZWN0IHRvIG1hdGNoIGFnYWluc3QgKHBvc3NpYmxlIHByb3BlcnRpZXM6IG5vZGVOYW1lLCBjbGFzc05hbWUsIGNsYXNzUmVnRXhwKQogKiBAcGFyYW0ge051bWJlcn0gW2xldmVsc10gSG93IG1hbnkgcGFyZW50cyBzaG91bGQgdGhlIGZ1bmN0aW9uIGNoZWNrIHVwIGZyb20gdGhlIGN1cnJlbnQgbm9kZSAoZGVmYXVsdHMgdG8gNTApCiAqIEByZXR1cm4ge251bGx8RWxlbWVudH0gUmV0dXJucyB0aGUgZmlyc3QgZWxlbWVudCB0aGF0IG1hdGNoZWQgdGhlIGRlc2lyZWROb2RlTmFtZShzKQogKiBAZXhhbXBsZQogKiAgICB2YXIgbGlzdEVsZW1lbnQgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQoZG9jdW1lbnQucXVlcnlTZWxlY3RvcigibGkiKSwgeyBub2RlTmFtZTogWyJNRU5VIiwgIlVMIiwgIk9MIl0gfSk7CiAqICAgIC8vIC4uLiBvciAuLi4KICogICAgdmFyIHVub3JkZXJlZExpc3RFbGVtZW50ID0gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoImxpIiksIHsgbm9kZU5hbWU6ICJVTCIgfSk7CiAqICAgIC8vIC4uLiBvciAuLi4KICogICAgdmFyIGNvbG9yZWRFbGVtZW50ID0gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KG15VGV4dE5vZGUsIHsgbm9kZU5hbWU6ICJTUEFOIiwgY2xhc3NOYW1lOiAid3lzaXd5Zy1jb2xvci1yZWQiLCBjbGFzc1JlZ0V4cDogL3d5c2l3eWctY29sb3ItW2Etel0vZyB9KTsKICovCnd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudCA9IChmdW5jdGlvbiAoKSB7CgogICAgZnVuY3Rpb24gX2lzU2FtZU5vZGVOYW1lKG5vZGVOYW1lLCBkZXNpcmVkTm9kZU5hbWVzKSB7CiAgICAgICAgaWYgKCFkZXNpcmVkTm9kZU5hbWVzIHx8ICFkZXNpcmVkTm9kZU5hbWVzLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmICh0eXBlb2YoZGVzaXJlZE5vZGVOYW1lcykgPT09ICJzdHJpbmciKSB7CiAgICAgICAgICAgIHJldHVybiBub2RlTmFtZSA9PT0gZGVzaXJlZE5vZGVOYW1lczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmxhbmcuYXJyYXkoZGVzaXJlZE5vZGVOYW1lcykuY29udGFpbnMobm9kZU5hbWUpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfaXNFbGVtZW50KG5vZGUpIHsKICAgICAgICByZXR1cm4gbm9kZS5ub2RlVHlwZSA9PT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERTsKICAgIH0KCiAgICBmdW5jdGlvbiBfaGFzQ2xhc3NOYW1lKGVsZW1lbnQsIGNsYXNzTmFtZSwgY2xhc3NSZWdFeHApIHsKICAgICAgICB2YXIgY2xhc3NOYW1lcyA9IChlbGVtZW50LmNsYXNzTmFtZSB8fCAiIikubWF0Y2goY2xhc3NSZWdFeHApIHx8IFtdOwogICAgICAgIGlmICghY2xhc3NOYW1lKSB7CiAgICAgICAgICAgIHJldHVybiAhIWNsYXNzTmFtZXMubGVuZ3RoOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY2xhc3NOYW1lc1tjbGFzc05hbWVzLmxlbmd0aCAtIDFdID09PSBjbGFzc05hbWU7CiAgICB9CgogICAgZnVuY3Rpb24gX2hhc0F0dHJpYnV0ZXMoZWwsIGF0dHJpYnV0ZXMpIHsKICAgICAgICBpZiAoZWwubm9kZVR5cGUgPT0gd3lzaWh0bWw1LlRFWFRfTk9ERSB8fCBlbC5ub2RlVHlwZSA9PSA5KSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgdmFyIHN0ID0gZWwuZ2V0QXR0cmlidXRlKCJzdHlsZSIpOwogICAgICAgIGlmICghc3QpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmb3IgKHZhciBhdHRyaWJ1dGUgaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICBpZiAoZWwuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShhdHRyaWJ1dGUpKSB7CiAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlc1thdHRyaWJ1dGVdICE9IG51bGwgJiYgYXR0cmlidXRlc1thdHRyaWJ1dGVdID09IGVsLnN0eWxlLmdldFByb3BlcnR5VmFsdWUoYXR0cmlidXRlKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhdHRyaWJ1dGVzW2F0dHJpYnV0ZV0gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBmdW5jdGlvbiBfZ2V0UGFyZW50RWxlbWVudFdpdGhOb2RlTmFtZShub2RlLCBub2RlTmFtZSwgbGV2ZWxzKSB7CiAgICAgICAgd2hpbGUgKGxldmVscy0tICYmIG5vZGUpIHsKICAgICAgICAgICAgaWYgKF9pc1NhbWVOb2RlTmFtZShub2RlLm5vZGVOYW1lLCBub2RlTmFtZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKG5vZGUucGFyZW50Tm9kZSkpIHsKICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBmdW5jdGlvbiBfZ2V0UGFyZW50RWxlbWVudFdpdGhOb2RlTmFtZUFuZENsYXNzTmFtZShub2RlLCBub2RlTmFtZSwgY2xhc3NOYW1lLCBjbGFzc1JlZ0V4cCwgbGV2ZWxzKSB7CiAgICAgICAgd2hpbGUgKGxldmVscy0tICYmIG5vZGUpIHsKICAgICAgICAgICAgaWYgKF9pc0VsZW1lbnQobm9kZSkgJiYgX2lzU2FtZU5vZGVOYW1lKG5vZGUubm9kZU5hbWUsIG5vZGVOYW1lKSAmJiBfaGFzQ2xhc3NOYW1lKG5vZGUsIGNsYXNzTmFtZSwgY2xhc3NSZWdFeHApKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIXd5c2lodG1sNS51dGlsLmlzRWRpdG9yTm9kZShub2RlLnBhcmVudE5vZGUpKSB7CiAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgZnVuY3Rpb24gX2dldFBhcmVudEVsZW1lbnRXaXRoTm9kZU5hbWVBbmRBdHRyaWJ1dGUobm9kZSwgbm9kZU5hbWUsIGF0dHJpYnV0ZXMsIGxldmVscykgewogICAgICAgIHdoaWxlIChsZXZlbHMtLSAmJiBub2RlKSB7CiAgICAgICAgICAgIGlmIChfaXNFbGVtZW50KG5vZGUpICYmIF9pc1NhbWVOb2RlTmFtZShub2RlLm5vZGVOYW1lLCBub2RlTmFtZSkgJiYgX2hhc0F0dHJpYnV0ZXMobm9kZSwgYXR0cmlidXRlcykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKG5vZGUucGFyZW50Tm9kZSkpIHsKICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICByZXR1cm4gZnVuY3Rpb24gKG5vZGUsIG1hdGNoaW5nU2V0LCBsZXZlbHMpIHsKICAgICAgICBsZXZlbHMgPSBsZXZlbHMgfHwgNTA7IC8vIEdvIG1heCA1MCBub2RlcyB1cHdhcmRzIGZyb20gY3VycmVudCBub2RlCiAgICAgICAgaWYgKG1hdGNoaW5nU2V0LmF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgcmV0dXJuIF9nZXRQYXJlbnRFbGVtZW50V2l0aE5vZGVOYW1lQW5kQXR0cmlidXRlKAogICAgICAgICAgICAgICAgbm9kZSwgbWF0Y2hpbmdTZXQubm9kZU5hbWUsIG1hdGNoaW5nU2V0LmF0dHJpYnV0ZXMsIGxldmVscwogICAgICAgICAgICApOwogICAgICAgIH0gZWxzZSBpZiAobWF0Y2hpbmdTZXQuY2xhc3NOYW1lIHx8IG1hdGNoaW5nU2V0LmNsYXNzUmVnRXhwKSB7CiAgICAgICAgICAgIHJldHVybiBfZ2V0UGFyZW50RWxlbWVudFdpdGhOb2RlTmFtZUFuZENsYXNzTmFtZSgKICAgICAgICAgICAgICAgIG5vZGUsIG1hdGNoaW5nU2V0Lm5vZGVOYW1lLCBtYXRjaGluZ1NldC5jbGFzc05hbWUsIG1hdGNoaW5nU2V0LmNsYXNzUmVnRXhwLCBsZXZlbHMKICAgICAgICAgICAgKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gX2dldFBhcmVudEVsZW1lbnRXaXRoTm9kZU5hbWUoCiAgICAgICAgICAgICAgICBub2RlLCBtYXRjaGluZ1NldC5ub2RlTmFtZSwgbGV2ZWxzCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfTsKfSkoKTsKLyoqCiAqIEdldCBlbGVtZW50J3Mgc3R5bGUgZm9yIGEgc3BlY2lmaWMgY3NzIHByb3BlcnR5CiAqCiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudCBvbiB3aGljaCB0byByZXRyaWV2ZSB0aGUgc3R5bGUKICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IFRoZSBDU1MgcHJvcGVydHkgdG8gcmV0cmlldmUgKCJmbG9hdCIsICJkaXNwbGF5IiwgInRleHQtYWxpZ24iLCAuLi4pCiAqCiAqIEBleGFtcGxlCiAqICAgIHd5c2lodG1sNS5kb20uZ2V0U3R5bGUoImRpc3BsYXkiKS5mcm9tKGRvY3VtZW50LmJvZHkpOwogKiAgICAvLyA9PiAiYmxvY2siCiAqLwp3eXNpaHRtbDUuZG9tLmdldFN0eWxlID0gKGZ1bmN0aW9uICgpIHsKICAgIHZhciBzdHlsZVByb3BlcnR5TWFwcGluZyA9IHsKICAgICAgICAgICAgImZsb2F0IiA6ICgic3R5bGVGbG9hdCIgaW4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iikuc3R5bGUpID8gInN0eWxlRmxvYXQiIDogImNzc0Zsb2F0IgogICAgICAgIH0sCiAgICAgICAgUkVHX0VYUF9DQU1FTElaRSA9IC9cLVthLXpdL2c7CgogICAgZnVuY3Rpb24gY2FtZWxpemUoc3RyKSB7CiAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKFJFR19FWFBfQ0FNRUxJWkUsIGZ1bmN0aW9uIChtYXRjaCkgewogICAgICAgICAgICByZXR1cm4gbWF0Y2guY2hhckF0KDEpLnRvVXBwZXJDYXNlKCk7CiAgICAgICAgfSk7CiAgICB9CgogICAgcmV0dXJuIGZ1bmN0aW9uIChwcm9wZXJ0eSkgewogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIGZyb20gOiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQubm9kZVR5cGUgIT09IHd5c2lodG1sNS5FTEVNRU5UX05PREUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyIGRvYyA9IGVsZW1lbnQub3duZXJEb2N1bWVudCwKICAgICAgICAgICAgICAgICAgICBjYW1lbGl6ZWRQcm9wZXJ0eSA9IHN0eWxlUHJvcGVydHlNYXBwaW5nW3Byb3BlcnR5XSB8fCBjYW1lbGl6ZShwcm9wZXJ0eSksCiAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBlbGVtZW50LnN0eWxlLAogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTdHlsZSA9IGVsZW1lbnQuY3VycmVudFN0eWxlLAogICAgICAgICAgICAgICAgICAgIHN0eWxlVmFsdWUgPSBzdHlsZVtjYW1lbGl6ZWRQcm9wZXJ0eV07CiAgICAgICAgICAgICAgICBpZiAoc3R5bGVWYWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHlsZVZhbHVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIGN1cnJlbnRTdHlsZSBpcyBubyBzdGFuZGFyZCBhbmQgb25seSBzdXBwb3J0ZWQgYnkgT3BlcmEgYW5kIElFIGJ1dCBpdCBoYXMgb25lIGltcG9ydGFudCBhZHZhbnRhZ2Ugb3ZlciB0aGUgc3RhbmRhcmQtY29tcGxpYW50CiAgICAgICAgICAgICAgICAvLyB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSwgc2luY2UgaXQgcmV0dXJucyBjc3MgcHJvcGVydHkgdmFsdWVzIGluIHRoZWlyIG9yaWdpbmFsIHVuaXQ6CiAgICAgICAgICAgICAgICAvLyBJZiB5b3Ugc2V0IGFuIGVsZW1lbnRzIHdpZHRoIHRvICI1MCUiLCB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSB3aWxsIGdpdmUgeW91IGl0J3MgY3VycmVudCB3aWR0aCBpbiBweCB3aGlsZSBjdXJyZW50U3R5bGUKICAgICAgICAgICAgICAgIC8vIGdpdmVzIHlvdSB0aGUgb3JpZ2luYWwgIjUwJSIuCiAgICAgICAgICAgICAgICAvLyBPcGVyYSBzdXBwb3J0cyBib3RoLCBjdXJyZW50U3R5bGUgYW5kIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlLCB0aGF0J3Mgd2h5IGNoZWNraW5nIGZvciBjdXJyZW50U3R5bGUgc2hvdWxkIGhhdmUgaGlnaGVyIHByaW8KICAgICAgICAgICAgICAgIGlmIChjdXJyZW50U3R5bGUpIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudFN0eWxlW2NhbWVsaXplZFByb3BlcnR5XTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWUgd2lsbCBvY2Nhc2lvbmFsbHkgZmFpbCBmb3IgdW5rbm93biByZWFzb25zLiBzd2FsbG93aW5nIGV4Y2VwdGlvbgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgd2luID0gZG9jLmRlZmF1bHRWaWV3IHx8IGRvYy5wYXJlbnRXaW5kb3csCiAgICAgICAgICAgICAgICAgICAgbmVlZHNPdmVyZmxvd1Jlc2V0ID0gKHByb3BlcnR5ID09PSAiaGVpZ2h0IiB8fCBwcm9wZXJ0eSA9PT0gIndpZHRoIikgJiYgZWxlbWVudC5ub2RlTmFtZSA9PT0gIlRFWFRBUkVBIiwKICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbE92ZXJmbG93LAogICAgICAgICAgICAgICAgICAgIHJldHVyblZhbHVlOwoKICAgICAgICAgICAgICAgIGlmICh3aW4uZ2V0Q29tcHV0ZWRTdHlsZSkgewogICAgICAgICAgICAgICAgICAgIC8vIENocm9tZSBhbmQgU2FmYXJpIGJvdGggY2FsY3VsYXRlIGEgd3Jvbmcgd2lkdGggYW5kIGhlaWdodCBmb3IgdGV4dGFyZWFzIHdoZW4gdGhleSBoYXZlIHNjcm9sbCBiYXJzCiAgICAgICAgICAgICAgICAgICAgLy8gdGhlcmZvcmUgd2UgcmVtb3ZlIGFuZCByZXN0b3JlIHRoZSBzY3JvbGxiYXIgYW5kIGNhbGN1bGF0ZSB0aGUgdmFsdWUgaW4gYmV0d2VlbgogICAgICAgICAgICAgICAgICAgIGlmIChuZWVkc092ZXJmbG93UmVzZXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxPdmVyZmxvdyA9IHN0eWxlLm92ZXJmbG93OwogICAgICAgICAgICAgICAgICAgICAgICBzdHlsZS5vdmVyZmxvdyA9ICJoaWRkZW4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHdpbi5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQsIG51bGwpLmdldFByb3BlcnR5VmFsdWUocHJvcGVydHkpOwogICAgICAgICAgICAgICAgICAgIGlmIChuZWVkc092ZXJmbG93UmVzZXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUub3ZlcmZsb3cgPSBvcmlnaW5hbE92ZXJmbG93IHx8ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0dXJuVmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfTsKfSkoKTsKLyoqCiAqIEhpZ2ggcGVyZm9ybWFudCB3YXkgdG8gY2hlY2sgd2hldGhlciBhbiBlbGVtZW50IHdpdGggYSBzcGVjaWZpYyB0YWcgbmFtZSBpcyBpbiB0aGUgZ2l2ZW4gZG9jdW1lbnQKICogT3B0aW1pemVkIGZvciBiZWluZyBoZWF2aWx5IGV4ZWN1dGVkCiAqIFVubGVhc2hlcyB0aGUgcG93ZXIgb2YgbGl2ZSBub2RlIGxpc3RzCiAqCiAqIEBwYXJhbSB7T2JqZWN0fSBkb2MgVGhlIGRvY3VtZW50IG9iamVjdCBvZiB0aGUgY29udGV4dCB3aGVyZSB0byBjaGVjawogKiBAcGFyYW0ge1N0cmluZ30gdGFnTmFtZSBVcHBlciBjYXNlZCB0YWcgbmFtZQogKiBAZXhhbXBsZQogKiAgICB3eXNpaHRtbDUuZG9tLmhhc0VsZW1lbnRXaXRoVGFnTmFtZShkb2N1bWVudCwgIklNRyIpOwogKi8Kd3lzaWh0bWw1LmRvbS5oYXNFbGVtZW50V2l0aFRhZ05hbWUgPSAoZnVuY3Rpb24gKCkgewogICAgdmFyIExJVkVfQ0FDSEUgPSB7fSwKICAgICAgICBET0NVTUVOVF9JREVOVElGSUVSID0gMTsKCiAgICBmdW5jdGlvbiBfZ2V0RG9jdW1lbnRJZGVudGlmaWVyKGRvYykgewogICAgICAgIHJldHVybiBkb2MuX3d5c2lodG1sNV9pZGVudGlmaWVyIHx8IChkb2MuX3d5c2lodG1sNV9pZGVudGlmaWVyID0gRE9DVU1FTlRfSURFTlRJRklFUisrKTsKICAgIH0KCiAgICByZXR1cm4gZnVuY3Rpb24gKGRvYywgdGFnTmFtZSkgewogICAgICAgIHZhciBrZXkgPSBfZ2V0RG9jdW1lbnRJZGVudGlmaWVyKGRvYykgKyAiOiIgKyB0YWdOYW1lLAogICAgICAgICAgICBjYWNoZUVudHJ5ID0gTElWRV9DQUNIRVtrZXldOwogICAgICAgIGlmICghY2FjaGVFbnRyeSkgewogICAgICAgICAgICBjYWNoZUVudHJ5ID0gTElWRV9DQUNIRVtrZXldID0gZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKHRhZ05hbWUpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGNhY2hlRW50cnkubGVuZ3RoID4gMDsKICAgIH07Cn0pKCk7Ci8qKgogKiBIaWdoIHBlcmZvcm1hbnQgd2F5IHRvIGNoZWNrIHdoZXRoZXIgYW4gZWxlbWVudCB3aXRoIGEgc3BlY2lmaWMgY2xhc3MgbmFtZSBpcyBpbiB0aGUgZ2l2ZW4gZG9jdW1lbnQKICogT3B0aW1pemVkIGZvciBiZWluZyBoZWF2aWx5IGV4ZWN1dGVkCiAqIFVubGVhc2hlcyB0aGUgcG93ZXIgb2YgbGl2ZSBub2RlIGxpc3RzCiAqCiAqIEBwYXJhbSB7T2JqZWN0fSBkb2MgVGhlIGRvY3VtZW50IG9iamVjdCBvZiB0aGUgY29udGV4dCB3aGVyZSB0byBjaGVjawogKiBAcGFyYW0ge1N0cmluZ30gdGFnTmFtZSBVcHBlciBjYXNlZCB0YWcgbmFtZQogKiBAZXhhbXBsZQogKiAgICB3eXNpaHRtbDUuZG9tLmhhc0VsZW1lbnRXaXRoQ2xhc3NOYW1lKGRvY3VtZW50LCAiZm9vYmFyIik7CiAqLwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgdmFyIExJVkVfQ0FDSEUgPSB7fSwKICAgICAgICBET0NVTUVOVF9JREVOVElGSUVSID0gMTsKCiAgICBmdW5jdGlvbiBfZ2V0RG9jdW1lbnRJZGVudGlmaWVyKGRvYykgewogICAgICAgIHJldHVybiBkb2MuX3d5c2lodG1sNV9pZGVudGlmaWVyIHx8IChkb2MuX3d5c2lodG1sNV9pZGVudGlmaWVyID0gRE9DVU1FTlRfSURFTlRJRklFUisrKTsKICAgIH0KCiAgICB3eXNpaHRtbDUuZG9tLmhhc0VsZW1lbnRXaXRoQ2xhc3NOYW1lID0gZnVuY3Rpb24gKGRvYywgY2xhc3NOYW1lKSB7CiAgICAgICAgLy8gZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSBpcyBub3Qgc3VwcG9ydGVkIGJ5IElFPDkKICAgICAgICAvLyBidXQgaXMgc29tZXRpbWVzIG1vY2tlZCB2aWEgbGlicmFyeSBjb2RlICh3aGljaCB0aGVuIGRvZXNuJ3QgcmV0dXJuIGxpdmUgbm9kZSBsaXN0cykKICAgICAgICBpZiAoIXd5c2lodG1sNS5icm93c2VyLnN1cHBvcnRzTmF0aXZlR2V0RWxlbWVudHNCeUNsYXNzTmFtZSgpKSB7CiAgICAgICAgICAgIHJldHVybiAhIWRvYy5xdWVyeVNlbGVjdG9yKCIuIiArIGNsYXNzTmFtZSk7CiAgICAgICAgfQoKICAgICAgICB2YXIga2V5ID0gX2dldERvY3VtZW50SWRlbnRpZmllcihkb2MpICsgIjoiICsgY2xhc3NOYW1lLAogICAgICAgICAgICBjYWNoZUVudHJ5ID0gTElWRV9DQUNIRVtrZXldOwogICAgICAgIGlmICghY2FjaGVFbnRyeSkgewogICAgICAgICAgICBjYWNoZUVudHJ5ID0gTElWRV9DQUNIRVtrZXldID0gZG9jLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoY2xhc3NOYW1lKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBjYWNoZUVudHJ5Lmxlbmd0aCA+IDA7CiAgICB9Owp9KSh3eXNpaHRtbDUpOwp3eXNpaHRtbDUuZG9tLmluc2VydCA9IGZ1bmN0aW9uIChlbGVtZW50VG9JbnNlcnQpIHsKICAgIHJldHVybiB7CiAgICAgICAgYWZ0ZXIgOiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICBlbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVsZW1lbnRUb0luc2VydCwgZWxlbWVudC5uZXh0U2libGluZyA/IGVsZW1lbnQubmV4dFNpYmxpbmcgOiBudWxsKTsKICAgICAgICB9LAoKICAgICAgICBiZWZvcmUgOiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICBlbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVsZW1lbnRUb0luc2VydCwgZWxlbWVudCk7CiAgICAgICAgfSwKCiAgICAgICAgaW50byA6IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoZWxlbWVudFRvSW5zZXJ0KTsKICAgICAgICB9CiAgICB9Owp9Owp3eXNpaHRtbDUuZG9tLmluc2VydENTUyA9IGZ1bmN0aW9uIChydWxlcykgewogICAgcnVsZXMgPSBydWxlcy5qb2luKCJcbiIpOwoKICAgIHJldHVybiB7CiAgICAgICAgaW50byA6IGZ1bmN0aW9uIChkb2MpIHsKICAgICAgICAgICAgdmFyIHN0eWxlRWxlbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCJzdHlsZSIpOwogICAgICAgICAgICBzdHlsZUVsZW1lbnQudHlwZSA9ICJ0ZXh0L2NzcyI7CgogICAgICAgICAgICBpZiAoc3R5bGVFbGVtZW50LnN0eWxlU2hlZXQpIHsKICAgICAgICAgICAgICAgIHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0LmNzc1RleHQgPSBydWxlczsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHN0eWxlRWxlbWVudC5hcHBlbmRDaGlsZChkb2MuY3JlYXRlVGV4dE5vZGUocnVsZXMpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGxpbmsgPSBkb2MucXVlcnlTZWxlY3RvcigiaGVhZCBsaW5rIik7CiAgICAgICAgICAgIGlmIChsaW5rKSB7CiAgICAgICAgICAgICAgICBsaW5rLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHN0eWxlRWxlbWVudCwgbGluayk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgaGVhZCA9IGRvYy5xdWVyeVNlbGVjdG9yKCJoZWFkIik7CiAgICAgICAgICAgICAgICBpZiAoaGVhZCkgewogICAgICAgICAgICAgICAgICAgIGhlYWQuYXBwZW5kQ2hpbGQoc3R5bGVFbGVtZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07Cn07Ci8qKgogKiBNZXRob2QgdG8gc2V0IGRvbSBldmVudHMKICoKICogQGV4YW1wbGUKICogICAgd3lzaWh0bWw1LmRvbS5vYnNlcnZlKGlmcmFtZS5jb250ZW50V2luZG93LmRvY3VtZW50LmJvZHksIFsiZm9jdXMiLCAiYmx1ciJdLCBmdW5jdGlvbigpIHsgLi4uIH0pOwogKi8Kd3lzaWh0bWw1LmRvbS5vYnNlcnZlID0gZnVuY3Rpb24gKGVsZW1lbnQsIGV2ZW50TmFtZXMsIGhhbmRsZXIpIHsKICAgIGV2ZW50TmFtZXMgPSB0eXBlb2YoZXZlbnROYW1lcykgPT09ICJzdHJpbmciID8gW2V2ZW50TmFtZXNdIDogZXZlbnROYW1lczsKCiAgICB2YXIgaGFuZGxlcldyYXBwZXIsCiAgICAgICAgZXZlbnROYW1lLAogICAgICAgIGkgPSAwLAogICAgICAgIGxlbmd0aCA9IGV2ZW50TmFtZXMubGVuZ3RoOwoKICAgIGZvciAoOwogICAgICAgIGkgPCBsZW5ndGg7CiAgICAgICAgaSsrKSB7CiAgICAgICAgZXZlbnROYW1lID0gZXZlbnROYW1lc1tpXTsKICAgICAgICBpZiAoZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKSB7CiAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGhhbmRsZXIsIGZhbHNlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBoYW5kbGVyV3JhcHBlciA9IGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgaWYgKCEoInRhcmdldCIgaW4gZXZlbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgZXZlbnQudGFyZ2V0ID0gZXZlbnQuc3JjRWxlbWVudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0ID0gZXZlbnQucHJldmVudERlZmF1bHQgfHwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJldHVyblZhbHVlID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbiA9IGV2ZW50LnN0b3BQcm9wYWdhdGlvbiB8fCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2FuY2VsQnViYmxlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgaGFuZGxlci5jYWxsKGVsZW1lbnQsIGV2ZW50KTsKICAgICAgICAgICAgfTsKICAgICAgICAgICAgZWxlbWVudC5hdHRhY2hFdmVudCgib24iICsgZXZlbnROYW1lLCBoYW5kbGVyV3JhcHBlcik7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiB7CiAgICAgICAgc3RvcCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGV2ZW50TmFtZSwKICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgbGVuZ3RoID0gZXZlbnROYW1lcy5sZW5ndGg7CiAgICAgICAgICAgIGZvciAoOwogICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgZXZlbnROYW1lID0gZXZlbnROYW1lc1tpXTsKICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIpIHsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBoYW5kbGVyLCBmYWxzZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuZGV0YWNoRXZlbnQoIm9uIiArIGV2ZW50TmFtZSwgaGFuZGxlcldyYXBwZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKfTsKLyoqCiAqIEhUTUwgU2FuaXRpemVyCiAqIFJld3JpdGVzIHRoZSBIVE1MIGJhc2VkIG9uIGdpdmVuIHJ1bGVzCiAqCiAqIEBwYXJhbSB7RWxlbWVudHxTdHJpbmd9IGVsZW1lbnRPckh0bWwgSFRNTCBTdHJpbmcgdG8gYmUgc2FuaXRpemVkIE9SIGVsZW1lbnQgd2hvc2UgY29udGVudCBzaG91bGQgYmUgc2FuaXRpemVkCiAqIEBwYXJhbSB7T2JqZWN0fSBbcnVsZXNdIExpc3Qgb2YgcnVsZXMgZm9yIHJld3JpdGluZyB0aGUgSFRNTCwgaWYgdGhlcmUncyBubyBydWxlIGZvciBhbiBlbGVtZW50IGl0IHdpbGwKICogICAgYmUgY29udmVydGVkIHRvIGEgInNwYW4iLiBFYWNoIHJ1bGUgaXMgYSBrZXkvdmFsdWUgcGFpciB3aGVyZSBrZXkgaXMgdGhlIHRhZyB0byBjb252ZXJ0LCBhbmQgdmFsdWUgdGhlCiAqICAgIGRlc2lyZWQgc3Vic3RpdHV0aW9uLgogKiBAcGFyYW0ge09iamVjdH0gY29udGV4dCBEb2N1bWVudCBvYmplY3QgaW4gd2hpY2ggdG8gcGFyc2UgdGhlIGh0bWwsIG5lZWRlZCB0byBzYW5kYm94IHRoZSBwYXJzaW5nCiAqCiAqIEByZXR1cm4ge0VsZW1lbnR8U3RyaW5nfSBEZXBlbmRzIG9uIHRoZSBlbGVtZW50T3JIdG1sIHBhcmFtZXRlci4gV2hlbiBodG1sIHRoZW4gdGhlIHNhbml0aXplZCBodG1sIGFzIHN0cmluZyBlbHNld2lzZSB0aGUgZWxlbWVudC4KICoKICogQGV4YW1wbGUKICogICAgdmFyIHVzZXJIVE1MID0gJzxkaXYgaWQ9ImZvbyIgb25jbGljaz0iYWxlcnQoMSk7Ij48cD48Zm9udCBjb2xvcj0icmVkIj5mb288L2ZvbnQ+PHNjcmlwdD5hbGVydCgxKTs8L3NjcmlwdD48L3A+PC9kaXY+JzsKICogICAgd3lzaWh0bWw1LmRvbS5wYXJzZSh1c2VySFRNTCwgewogKiAgICAgIHRhZ3MgewogKiAgICAgICAgcDogICAgICAiZGl2IiwgICAgICAvLyBSZW5hbWUgcCB0YWdzIHRvIGRpdiB0YWdzCiAqICAgICAgICBmb250OiAgICJzcGFuIiAgICAgIC8vIFJlbmFtZSBmb250IHRhZ3MgdG8gc3BhbiB0YWdzCiAqICAgICAgICBkaXY6ICAgIHRydWUsICAgICAgIC8vIEtlZXAgdGhlbSwgYWxzbyBwb3NzaWJsZSAoc2FtZSByZXN1bHQgd2hlbiBwYXNzaW5nOiAiZGl2IiBvciB0cnVlKQogKiAgICAgICAgc2NyaXB0OiB1bmRlZmluZWQgICAvLyBSZW1vdmUgc2NyaXB0IGVsZW1lbnRzCiAqICAgICAgfQogKiAgICB9KTsKICogICAgLy8gPT4gPGRpdj48ZGl2PjxzcGFuPmZvbyBiYXI8L3NwYW4+PC9kaXY+PC9kaXY+CiAqCiAqICAgIHZhciB1c2VySFRNTCA9ICc8dGFibGU+PHRib2R5Pjx0cj48dGQ+SSdtIGEgdGFibGUhPC90ZD48L3RyPjwvdGJvZHk+PC90YWJsZT4nOwogKiAgICB3eXNpaHRtbDUuZG9tLnBhcnNlKHVzZXJIVE1MKTsKICogICAgLy8gPT4gJzxzcGFuPjxzcGFuPjxzcGFuPjxzcGFuPkknbSBhIHRhYmxlITwvc3Bhbj48L3NwYW4+PC9zcGFuPjwvc3Bhbj4nCiAqCiAqICAgIHZhciB1c2VySFRNTCA9ICc8ZGl2PmZvb2Jhcjxicj5mb29iYXI8L2Rpdj4nOwogKiAgICB3eXNpaHRtbDUuZG9tLnBhcnNlKHVzZXJIVE1MLCB7CiAqICAgICAgdGFnczogewogKiAgICAgICAgZGl2OiB1bmRlZmluZWQsCiAqICAgICAgICBicjogIHRydWUKICogICAgICB9CiAqICAgIH0pOwogKiAgICAvLyA9PiAnJwogKgogKiAgICB2YXIgdXNlckhUTUwgPSAnPGRpdiBjbGFzcz0icmVkIj5mb288L2Rpdj48ZGl2IGNsYXNzPSJwaW5rIj5iYXI8L2Rpdj4nOwogKiAgICB3eXNpaHRtbDUuZG9tLnBhcnNlKHVzZXJIVE1MLCB7CiAqICAgICAgY2xhc3NlczogewogKiAgICAgICAgcmVkOiAgICAxLAogKiAgICAgICAgZ3JlZW46ICAxCiAqICAgICAgfSwKICogICAgICB0YWdzOiB7CiAqICAgICAgICBkaXY6IHsKICogICAgICAgICAgcmVuYW1lX3RhZzogICAgICJwIgogKiAgICAgICAgfQogKiAgICAgIH0KICogICAgfSk7CiAqICAgIC8vID0+ICc8cCBjbGFzcz0icmVkIj5mb288L3A+PHA+YmFyPC9wPicKICovCnd5c2lodG1sNS5kb20ucGFyc2UgPSAoZnVuY3Rpb24gKCkgewoKICAgIC8qKgogICAgICogSXQncyBub3QgcG9zc2libGUgdG8gdXNlIGEgWE1MUGFyc2VyL0RPTVBhcnNlciBhcyBIVE1MNSBpcyBub3QgYWx3YXlzIHdlbGwtZm9ybWVkIFhNTAogICAgICogbmV3IERPTVBhcnNlcigpLnBhcnNlRnJvbVN0cmluZygnPGltZyBzcmM9ImZvby5naWYiPicpIHdpbGwgY2F1c2UgYSBwYXJzZUVycm9yIHNpbmNlIHRoZQogICAgICogbm9kZSBpc24ndCBjbG9zZWQKICAgICAqCiAgICAgKiBUaGVyZWZvcmUgd2UndmUgdG8gdXNlIHRoZSBicm93c2VyJ3Mgb3JkaW5hcnkgSFRNTCBwYXJzZXIgaW52b2tlZCBieSBzZXR0aW5nIGlubmVySFRNTC4KICAgICAqLwogICAgdmFyIE5PREVfVFlQRV9NQVBQSU5HID0gewogICAgICAgICAgICAiMSIgOiBfaGFuZGxlRWxlbWVudCwKICAgICAgICAgICAgIjMiIDogX2hhbmRsZVRleHQKICAgICAgICB9LAogICAgICAgIC8vIFJlbmFtZSB1bmtub3duIHRhZ3MgdG8gdGhpcwogICAgICAgIERFRkFVTFRfTk9ERV9OQU1FID0gInNwYW4iLAogICAgICAgIFdISVRFX1NQQUNFX1JFR19FWFAgPSAvXHMrLywKICAgICAgICBkZWZhdWx0UnVsZXMgPSB7dGFncyA6IHt9LCBjbGFzc2VzIDoge319LAogICAgICAgIGN1cnJlbnRSdWxlcyA9IHt9LAogICAgICAgIHByZVByb2Nlc3NpbmdDb250ZW50ID0gZmFsc2U7CgogICAgLyoqCiAgICAgKiBJdGVyYXRlcyBvdmVyIGFsbCBjaGlsZHMgb2YgdGhlIGVsZW1lbnQsIHJlY3JlYXRlcyB0aGVtLCBhcHBlbmRzIHRoZW0gaW50byBhIGRvY3VtZW50IGZyYWdtZW50CiAgICAgKiB3aGljaCBsYXRlciByZXBsYWNlcyB0aGUgZW50aXJlIGJvZHkgY29udGVudAogICAgICovCiAgICBmdW5jdGlvbiBwYXJzZShlbGVtZW50T3JIdG1sLCBydWxlcywgY29udGV4dCwgY2xlYW5VcCwgcHJlUHJvY2VzcykgewogICAgICAgIHd5c2lodG1sNS5sYW5nLm9iamVjdChjdXJyZW50UnVsZXMpLm1lcmdlKGRlZmF1bHRSdWxlcykubWVyZ2UocnVsZXMpLmdldCgpOwoKICAgICAgICBjb250ZXh0ID0gY29udGV4dCB8fCBlbGVtZW50T3JIdG1sLm93bmVyRG9jdW1lbnQgfHwgZG9jdW1lbnQ7CiAgICAgICAgcHJlUHJvY2Vzc2luZ0NvbnRlbnQgPSAhIXByZVByb2Nlc3M7CiAgICAgICAgdmFyIGZyYWdtZW50ID0gY29udGV4dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksCiAgICAgICAgICAgIGlzU3RyaW5nID0gdHlwZW9mKGVsZW1lbnRPckh0bWwpID09PSAic3RyaW5nIiwKICAgICAgICAgICAgZWxlbWVudCwKICAgICAgICAgICAgbmV3Tm9kZSwKICAgICAgICAgICAgZmlyc3RDaGlsZDsKCiAgICAgICAgaWYgKGlzU3RyaW5nKSB7CiAgICAgICAgICAgIGVsZW1lbnQgPSB3eXNpaHRtbDUuZG9tLmdldEFzRG9tKGVsZW1lbnRPckh0bWwsIGNvbnRleHQpOwogICAgICAgICAgICBpZiAocHJlUHJvY2VzcykgewogICAgICAgICAgICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBlbGVtZW50LmlubmVySFRNTC5yZXBsYWNlKC9cci9nLCAiIik7CiAgICAgICAgICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IGVsZW1lbnQuaW5uZXJIVE1MLnJlcGxhY2UoL1xuL2csICIgIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgICAgICBjb250ZXh0LmJvZHkuYXBwZW5kQ2hpbGQoZWxlbWVudCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdmFyIGlubmVySFRNTCA9IGVsZW1lbnRPckh0bWwuaW5uZXJIVE1MOwogICAgICAgICAgICBlbGVtZW50ID0gZWxlbWVudE9ySHRtbDsKICAgICAgICAgICAgaWYgKHByZVByb2Nlc3MpIHsKICAgICAgICAgICAgICAgIGlubmVySFRNTCA9IGlubmVySFRNTC5yZXBsYWNlKC9cci9nLCAiIik7CiAgICAgICAgICAgICAgICBpbm5lckhUTUwgPSBpbm5lckhUTUwucmVwbGFjZSgvXG4vZywgIiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gaW5uZXJIVE1MOwogICAgICAgIH0KICAgICAgICB3aGlsZSAoZWxlbWVudC5maXJzdENoaWxkKSB7CiAgICAgICAgICAgIGZpcnN0Q2hpbGQgPSBlbGVtZW50LmZpcnN0Q2hpbGQ7CiAgICAgICAgICAgIG5ld05vZGUgPSBfY29udmVydChmaXJzdENoaWxkLCBjbGVhblVwLCAiYm9keSIpOwogICAgICAgICAgICBlbGVtZW50LnJlbW92ZUNoaWxkKGZpcnN0Q2hpbGQpOwogICAgICAgICAgICBpZiAobmV3Tm9kZSkgewogICAgICAgICAgICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQobmV3Tm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIENsZWFyIGVsZW1lbnQgY29udGVudHMKICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9ICIiOwoKICAgICAgICAvLyBJbnNlcnQgbmV3IERPTSB0cmVlCiAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChmcmFnbWVudCk7CgogICAgICAgIC8vIENsZWFudXAgdGhlIFdvcmQgVG8gSFRNTCBDYWNoZQogICAgICAgIF9jbGVhblVwV29yZFRvSFRNTENhY2hlKCk7CgogICAgICAgIGlmIChpc1N0cmluZykgewogICAgICAgICAgICBjb250ZXh0LmJvZHkucmVtb3ZlQ2hpbGQoZWxlbWVudCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpc1N0cmluZyA/IHd5c2lodG1sNS5xdWlya3MuZ2V0Q29ycmVjdElubmVySFRNTChlbGVtZW50KSA6IGVsZW1lbnQ7CiAgICB9CgogICAgZnVuY3Rpb24gX2NvbnZlcnQob2xkTm9kZSwgY2xlYW5VcCwgbmV3UGFyZW50Tm9kZU5hbWUpIHsKICAgICAgICB2YXIgb2xkTm9kZVR5cGUgPSBvbGROb2RlLm5vZGVUeXBlLAogICAgICAgICAgICBvbGRDaGlsZHMgPSBvbGROb2RlLmNoaWxkTm9kZXMsCiAgICAgICAgICAgIG1ldGhvZCA9IE5PREVfVFlQRV9NQVBQSU5HW29sZE5vZGVUeXBlXSwKICAgICAgICAgICAgaSA9IDAsCiAgICAgICAgICAgIG5ld05vZGUsCiAgICAgICAgICAgIG5ld0NoaWxkOwoKICAgICAgICAvLyBSZXR1cm4gbnVsbCBmb3IgI3RleHQgbm9kZXMgd2hpY2ggaGFzIG9ubHkgd2hpdGVzcGFjZXMKICAgICAgICBpZiAob2xkTm9kZVR5cGUgPT0gMyAmJiAhb2xkTm9kZS5kYXRhLnRyaW0oKS5sZW5ndGggJiYgb2xkTm9kZS5wYXJlbnROb2RlLmhhc0F0dHJpYnV0ZSgnY2xhc3MnLCAnd3lzaWh0bWw1LWVkaXRvcicpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgbmV3Tm9kZSA9IG1ldGhvZCAmJiBtZXRob2Qob2xkTm9kZSwgbmV3UGFyZW50Tm9kZU5hbWUpOwoKICAgICAgICBpZiAoIW5ld05vZGUpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICB2YXIgb2xkQ2hpbGRzTGVuZ3RoID0gb2xkQ2hpbGRzLmxlbmd0aDsKICAgICAgICBmb3IgKGkgPSAwOwogICAgICAgICAgICAgaSA8IG9sZENoaWxkc0xlbmd0aDsKICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICBuZXdDaGlsZCA9IF9jb252ZXJ0KG9sZENoaWxkc1tpXSwgY2xlYW5VcCwgbmV3Tm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKTsKICAgICAgICAgICAgaWYgKG5ld0NoaWxkKSB7CiAgICAgICAgICAgICAgICBuZXdOb2RlLmFwcGVuZENoaWxkKG5ld0NoaWxkKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gQ2xlYW51cCBzZW5zZWxlc3MgPHNwYW4+IGVsZW1lbnRzCiAgICAgICAgaWYgKGNsZWFuVXAgJiYgbmV3Tm9kZS5jaGlsZE5vZGVzLmxlbmd0aCA8PSAxICYmIG5ld05vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gREVGQVVMVF9OT0RFX05BTUUgJiYgIW5ld05vZGUuYXR0cmlidXRlcy5sZW5ndGgpIHsKICAgICAgICAgICAgcmV0dXJuIG5ld05vZGUuZmlyc3RDaGlsZDsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuZXdOb2RlOwogICAgfQoKICAgIGZ1bmN0aW9uIF9oYW5kbGVFbGVtZW50KG9sZE5vZGUsIG5ld1BhcmVudE5vZGVOYW1lKSB7CiAgICAgICAgdmFyIHJ1bGUsCiAgICAgICAgICAgIG5ld05vZGUsCiAgICAgICAgICAgIHRhZ1J1bGVzID0gY3VycmVudFJ1bGVzLnRhZ3MsCiAgICAgICAgICAgIHBzZXVkb1RhZ3MgPSBjdXJyZW50UnVsZXMucHNldWRvVGFncyB8fCBbXSwKICAgICAgICAgICAgbm9kZU5hbWUgPSBvbGROb2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCksCiAgICAgICAgICAgIHNjb3BlTmFtZSA9IG9sZE5vZGUuc2NvcGVOYW1lLAogICAgICAgICAgICB0YWJsZUVsZW1lbnRzID0gWyJ0YWJsZSIsICJ0aGVhZCIsICJ0Zm9vdCIsICJ0aCIsICJjb2xncm91cCIsICJjb2wiLCAidGJvZHkiLCAidHIiLCAidGQiXTsKCiAgICAgICAgLyoqCiAgICAgICAgICogV2UgYWxyZWFkeSBwYXJzZWQgdGhhdCBlbGVtZW50CiAgICAgICAgICogaWdub3JlIGl0ISAoeWVzLCB0aGlzIHNvbWV0aW1lcyBoYXBwZW5zIGluIElFOCB3aGVuIHRoZSBodG1sIGlzIGludmFsaWQpCiAgICAgICAgICovCiAgICAgICAgaWYgKG9sZE5vZGUuX3d5c2lodG1sNSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgICAgb2xkTm9kZS5fd3lzaWh0bWw1ID0gMTsKCiAgICAgICAgaWYgKG9sZE5vZGUuY2xhc3NOYW1lID09PSAid3lzaWh0bWw1LXRlbXAiKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICB2YXIgaXNUYWJsZUVsZW1lbnQgPSB0YWJsZUVsZW1lbnRzLmluZGV4T2Yobm9kZU5hbWUpID4gLTE7CiAgICAgICAgaWYgKCFpc1RhYmxlRWxlbWVudCAmJiAoIW9sZE5vZGUudGV4dENvbnRlbnQgfHwgIW9sZE5vZGUudGV4dENvbnRlbnQucmVwbGFjZSgvXG4vZywgIiIpKSAmJiBvbGROb2RlLm91dGVySFRNTC5zZWFyY2goIjxicj4iKSA9PSAtMSkgeyAvL0lmIGZpcnN0RWxlbWVudENoaWxkIGlzIG5vdCBmb3VuZCBhbmQgZmlyc3RFbGVtZW50IGlzIG5vdCBhIGJsYW5rIGxpbmUuCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKG9sZE5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PSAibGkiICYmICFvbGROb2RlLnRleHRDb250ZW50LnRyaW0oKSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIElFIGlzIHRoZSBvbmx5IGJyb3dzZXIgd2hvIGRvZXNuJ3QgaW5jbHVkZSB0aGUgbmFtZXNwYWNlIGluIHRoZQogICAgICAgICAqIG5vZGVOYW1lLCB0aGF0J3Mgd2h5IHdlIGhhdmUgdG8gcHJlcGVuZCBpdCBieSBvdXJzZWx2ZXMKICAgICAgICAgKiBzY29wZU5hbWUgaXMgYSBwcm9wcmlldGFyeSBJRSBmZWF0dXJlCiAgICAgICAgICogcmVhZCBtb3JlIGhlcmUgaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21zNTM0Mzg4KHY9dnMuODUpLmFzcHgKICAgICAgICAgKi8KICAgICAgICBpZiAoc2NvcGVOYW1lICYmIHNjb3BlTmFtZSAhPSAiSFRNTCIpIHsKICAgICAgICAgICAgbm9kZU5hbWUgPSBzY29wZU5hbWUgKyAiOiIgKyBub2RlTmFtZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJlcGFpciBub2RlCiAgICAgICAgICogSUUgaXMgYSBiaXQgYml0Y2h5IHdoZW4gaXQgY29tZXMgdG8gaW52YWxpZCBuZXN0ZWQgbWFya3VwIHdoaWNoIGluY2x1ZGVzIHVuY2xvc2VkIHRhZ3MKICAgICAgICAgKiBBIDxwPiBkb2Vzbid0IG5lZWQgdG8gYmUgY2xvc2VkIGFjY29yZGluZyBIVE1MNC01IHNwZWMsIHdlIHNpbXBseSByZXBsYWNlIGl0IHdpdGggYSA8ZGl2PiB0byBwcmVzZXJ2ZSBpdHMgY29udGVudCBhbmQgbGF5b3V0CiAgICAgICAgICovCiAgICAgICAgaWYgKCJvdXRlckhUTUwiIGluIG9sZE5vZGUpIHsKICAgICAgICAgICAgaWYgKCF3eXNpaHRtbDUuYnJvd3Nlci5hdXRvQ2xvc2VzVW5jbG9zZWRUYWdzKCkgJiYgb2xkTm9kZS5ub2RlTmFtZSA9PT0gIlAiICYmIG9sZE5vZGUub3V0ZXJIVE1MLnNsaWNlKC00KS50b0xvd2VyQ2FzZSgpICE9PSAiPC9wPiIpIHsKICAgICAgICAgICAgICAgIG5vZGVOYW1lID0gImRpdiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrIGlmIGN1cnJlbnROb2RlJ3MgY2hpbGQgaXMgdG8gYmUgcmVtb3ZlZCBhcyBwZXIgdGhlIHRhZ1J1bGVzCiAgICAgICAgICogYW5kIGlmIGN1cnJlbnROb2RlJ3MgY2hpbGQgY29udGFpbnMgaW5uZXJIVE1MIGRhdGEsCiAgICAgICAgICogdGhlbiBhc3NpZ24gY2hpbGQncyBIVE1MIGludG8gY3VycmVudE5vZGUncyBIVE1MLCB0byByZW1vdmUgdGhlIGNoaWxkIHRhZwogICAgICAgICAqLwogICAgICAgIGlmIChvbGROb2RlLmhhc0NoaWxkTm9kZXMoKSkgewogICAgICAgICAgICB2YXIgY2hpbGROb2RlTmFtZSA9IG9sZE5vZGUuZmlyc3RDaGlsZC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICBpZiAoY2hpbGROb2RlTmFtZSBpbiB0YWdSdWxlcykgewogICAgICAgICAgICAgICAgcnVsZSA9IHRhZ1J1bGVzW2NoaWxkTm9kZU5hbWVdOwogICAgICAgICAgICAgICAgaWYgKCghcnVsZSB8fCBydWxlLnJlbW92ZSkgJiYgb2xkTm9kZS5maXJzdENoaWxkLmlubmVySFRNTCkgewogICAgICAgICAgICAgICAgICAgIG9sZE5vZGUuaW5uZXJIVE1MID0gb2xkTm9kZS5maXJzdENoaWxkLmlubmVySFRNTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG5vZGVOYW1lIGluIHRhZ1J1bGVzKSB7CiAgICAgICAgICAgIHJ1bGUgPSB0YWdSdWxlc1tub2RlTmFtZV07CiAgICAgICAgICAgIGlmICghcnVsZSB8fCBydWxlLnJlbW92ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJ1bGUgPSB0eXBlb2YocnVsZSkgPT09ICJzdHJpbmciID8ge3JlbmFtZV90YWcgOiBydWxlfSA6IHJ1bGU7CiAgICAgICAgfSBlbHNlIGlmIChvbGROb2RlLmZpcnN0Q2hpbGQpIHsKICAgICAgICAgICAgcnVsZSA9IHtyZW5hbWVfdGFnIDogREVGQVVMVF9OT0RFX05BTUV9OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIFJlbW92ZSBlbXB0eSB1bmtub3duIGVsZW1lbnRzCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgdmFyIGxpc3RUeXBlcyA9IFsib2wiLCAidWwiLCAiZGlyIiwgIm1lbnUiXTsKICAgICAgICBpZiAobGlzdFR5cGVzLmluZGV4T2Yobm9kZU5hbWUpID49IDApIHsKICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gb2xkTm9kZS5jaGlsZE5vZGVzOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB2YXIgY2hpbGROb2RlTmFtZSA9IGNoaWxkcmVuW2ldICYmIGNoaWxkcmVuW2ldLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICBpZiAoY2hpbGROb2RlTmFtZSAmJiAoY2hpbGRyZW5baV0ubm9kZVR5cGUgPT0gMSB8fCBjaGlsZHJlbltpXS5ub2RlVHlwZSA9PSAzKSAmJiBjaGlsZHJlbltpXS50ZXh0Q29udGVudCAmJiBsaXN0VHlwZXMuaW5kZXhPZihjaGlsZE5vZGVOYW1lKSA9PSAtMSAmJiBjaGlsZE5vZGVOYW1lICE9ICJsaSIpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbGlOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiTEkiKTsKICAgICAgICAgICAgICAgICAgICBvbGROb2RlLmluc2VydEJlZm9yZShsaU5vZGUsIGNoaWxkcmVuW2ldKTsKICAgICAgICAgICAgICAgICAgICBsaU5vZGUuYXBwZW5kQ2hpbGQoY2hpbGRyZW5baSArIDFdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdmFyIGxpc3RUeXBlID0gX2lzTVNvTGlzdFBhcmFncmFwaENoaWxkKG9sZE5vZGUpOwogICAgICAgIHZhciB2YWxpZENoaWxkQ291bnQgPSBfdmFsaWRDaGlsZE5vZGVDb3VudChvbGROb2RlKTsKICAgICAgICBpZiAobGlzdFR5cGUgJiYgdmFsaWRDaGlsZENvdW50KSB7IC8vQ2hpbGQgRWxlbWVudCBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIHR3by4KICAgICAgICAgICAgbmV3Tm9kZSA9IF9jb252ZXJ0V29yZFRvSFRNTE5vZGUob2xkTm9kZSwgdGFnUnVsZXMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICgvTXNvTm9ybWFsL2kudGVzdChvbGROb2RlLmNsYXNzTmFtZSkgfHwgKGxpc3RUeXBlICYmICF2YWxpZENoaWxkQ291bnQpKSB7IC8vY2xlYW4gbGlzdCBjYWNoZSBpZiBhIHBhcmEgYXBwZWFycyBhZnRlciBsaXN0LgogICAgICAgICAgICAgICAgX2NsZWFuVXBXb3JkVG9IVE1MQ2FjaGUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgcmVuYW1lVGFnID0gcnVsZS5yZW5hbWVfdGFnIHx8IG5vZGVOYW1lOwogICAgICAgICAgICBpZiAocHJlUHJvY2Vzc2luZ0NvbnRlbnQpIHsKICAgICAgICAgICAgICAgIG5ld05vZGUgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudChyZW5hbWVUYWcpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIGJsb2NrRWxlbWVudHMgPSBbInAiLCAiaDEiLCAiaDIiLCAiaDMiLCAiaDQiLCAiaDUiLCAiaDYiLCAib2wiLCAidWwiXTsKICAgICAgICAgICAgICAgIHZhciBwYXJlbnROb2RlID0gb2xkTm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgd2hpbGUgKG5ld1BhcmVudE5vZGVOYW1lICYmIG5ld1BhcmVudE5vZGVOYW1lICE9ICJib2R5IiAmJiBwc2V1ZG9UYWdzLmluZGV4T2YobmV3UGFyZW50Tm9kZU5hbWUpID4gLTEpIHsKICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gcGFyZW50Tm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIGlmICh3eXNpaHRtbDUudXRpbC5pc0VkaXRvck5vZGUocGFyZW50Tm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3UGFyZW50Tm9kZU5hbWUgPSAiYm9keSI7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3UGFyZW50Tm9kZU5hbWUgPSAocGFyZW50Tm9kZSAmJiBwYXJlbnROb2RlLm5vZGVOYW1lKSA/IHBhcmVudE5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA6ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChwc2V1ZG9UYWdzLmluZGV4T2YocmVuYW1lVGFnKSA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgIC8vRm9yIFRhYmxlIGVsZW1lbnRzIGNyZWF0ZSB0aGUgc2FtZSBuZXcgbm9kZQogICAgICAgICAgICAgICAgICAgIGlmIChpc1RhYmxlRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdOb2RlID0gb2xkTm9kZS5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQocmVuYW1lVGFnKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5ld1BhcmVudE5vZGVOYW1lID09ICJib2R5IiAmJiBibG9ja0VsZW1lbnRzLmluZGV4T2YocmVuYW1lVGFnKSA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdOb2RlID0gb2xkTm9kZS5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInAiKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChuZXdQYXJlbnROb2RlTmFtZSA9PSAidWwiIHx8IG5ld1BhcmVudE5vZGVOYW1lID09ICJvbCIpICYmIHJlbmFtZVRhZyAhPSAibGkiICYmIHJlbmFtZVRhZyAhPSAib2wiICYmIHJlbmFtZVRhZyAhPSAidWwiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgibGkiKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5ld1BhcmVudE5vZGVOYW1lICE9ICJib2R5IiAmJiBuZXdQYXJlbnROb2RlTmFtZSAhPSAibGkiICYmIFsicCIsICJoMSIsICJoMiIsICJoMyIsICJoNCIsICJoNSIsICJoNiJdLmluZGV4T2YocmVuYW1lVGFnKSA+IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKG5ld1BhcmVudE5vZGVOYW1lICE9ICJib2R5IiAmJiBuZXdQYXJlbnROb2RlTmFtZSAhPSAib2wiICYmIG5ld1BhcmVudE5vZGVOYW1lICE9ICJ1bCIgJiYgbmV3UGFyZW50Tm9kZU5hbWUgIT0gImxpIikgJiYgWyJvbCIsICJ1bCIsICJsaSJdLmluZGV4T2YocmVuYW1lVGFnKSA+IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld05vZGUgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudChyZW5hbWVUYWcpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSA9IG9sZE5vZGUub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KHJlbmFtZVRhZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgX2hhbmRsZUF0dHJpYnV0ZXMob2xkTm9kZSwgbmV3Tm9kZSwgcnVsZSk7CiAgICAgICAgfQoKICAgICAgICBvbGROb2RlID0gbnVsbDsKICAgICAgICByZXR1cm4gbmV3Tm9kZTsKICAgIH0KCiAgICBmdW5jdGlvbiBfaGFuZGxlQXR0cmlidXRlcyhvbGROb2RlLCBuZXdOb2RlLCBydWxlKSB7CiAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7fSwgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZnJlc2ggbmV3IHNldCBvZiBhdHRyaWJ1dGVzIHRvIHNldCBvbiBuZXdOb2RlCiAgICAgICAgICAgIHNldENsYXNzID0gcnVsZS5zZXRfY2xhc3MsICAgICAgICAgICAgIC8vIGNsYXNzZXMgdG8gc2V0CiAgICAgICAgICAgIGFkZENsYXNzID0gcnVsZS5hZGRfY2xhc3MsICAgICAgICAgICAgIC8vIGFkZCBjbGFzc2VzIGJhc2VkIG9uIGV4aXN0aW5nIGF0dHJpYnV0ZXMKICAgICAgICAgICAgc2V0QXR0cmlidXRlcyA9IHJ1bGUuc2V0X2F0dHJpYnV0ZXMsICAgICAgICAvLyBhdHRyaWJ1dGVzIHRvIHNldCBvbiB0aGUgY3VycmVudCBub2RlCiAgICAgICAgICAgIGNoZWNrQXR0cmlidXRlcyA9IHJ1bGUuY2hlY2tfYXR0cmlidXRlcywgICAgICAvLyBjaGVjay9jb252ZXJ0IHZhbHVlcyBvZiBhdHRyaWJ1dGVzCiAgICAgICAgICAgIGFsbG93ZWRDbGFzc2VzID0gY3VycmVudFJ1bGVzLmNsYXNzZXMsCiAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICBjbGFzc2VzID0gW10sCiAgICAgICAgICAgIG5ld0NsYXNzZXMgPSBbXSwKICAgICAgICAgICAgbmV3VW5pcXVlQ2xhc3NlcyA9IFtdLAogICAgICAgICAgICBvbGRDbGFzc2VzID0gW10sCiAgICAgICAgICAgIGNsYXNzZXNMZW5ndGgsCiAgICAgICAgICAgIG5ld0NsYXNzZXNMZW5ndGgsCiAgICAgICAgICAgIGN1cnJlbnRDbGFzcywKICAgICAgICAgICAgbmV3Q2xhc3MsCiAgICAgICAgICAgIGF0dHJpYnV0ZU5hbWUsCiAgICAgICAgICAgIG5ld0F0dHJpYnV0ZVZhbHVlLAogICAgICAgICAgICBtZXRob2Q7CgogICAgICAgIHZhciBuZXdOb2RldGFnUnVsZXMgPSBjdXJyZW50UnVsZXMudGFnczsKICAgICAgICB2YXIgbmV3Tm9kZU5hbWUgPSBuZXdOb2RlID8gbmV3Tm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpIDogbnVsbDsKICAgICAgICB2YXIgbmV3Tm9kZVJ1bGVzOwogICAgICAgIGlmIChuZXdOb2RlTmFtZSAmJiAobmV3Tm9kZU5hbWUgaW4gbmV3Tm9kZXRhZ1J1bGVzKSkgewogICAgICAgICAgICBuZXdOb2RlUnVsZXMgPSBuZXdOb2RldGFnUnVsZXNbbmV3Tm9kZU5hbWVdOwogICAgICAgIH0KICAgICAgICB2YXIgcmVtb3ZlQXR0cmlidXRlcyA9IG5ld05vZGVSdWxlcyA/IG5ld05vZGVSdWxlcy5yZW1vdmVfYXR0cmlidXRlcyA6IG51bGw7IC8vIFJlbW92ZSBhdHRyaWJ1dGVzIGZyb20gb2xkIG5vZGUuCgogICAgICAgIGlmIChyZW1vdmVBdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVtb3ZlQXR0cmlidXRlcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIGF0dHIgPSByZW1vdmVBdHRyaWJ1dGVzW2ldOwogICAgICAgICAgICAgICAgaWYgKGF0dHIpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgYXR0ckFycmF5ID0gYXR0ci5zcGxpdCgiLCIpOwogICAgICAgICAgICAgICAgICAgIGlmIChhdHRyQXJyYXkubGVuZ3RoID09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb2xkTm9kZS5yZW1vdmVBdHRyaWJ1dGUocmVtb3ZlQXR0cmlidXRlc1tpXSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHIgPSBvbGROb2RlW2F0dHJBcnJheVswXV07CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZEF0dHIgPSBhdHRyW2F0dHJBcnJheVsxXV07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZEF0dHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyQXJyYXkubGVuZ3RoID4gMiAmJiAoY2hpbGRBdHRyLmluZGV4T2YoYXR0ckFycmF5WzJdKSAhPSAtMSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyLnJlbW92ZVByb3BlcnR5KGF0dHJBcnJheVsxXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGF0dHJBcnJheS5sZW5ndGggPD0gMikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHIucmVtb3ZlUHJvcGVydHkoYXR0ckFycmF5WzFdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHNldEF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgYXR0cmlidXRlcyA9IHd5c2lodG1sNS5sYW5nLm9iamVjdChzZXRBdHRyaWJ1dGVzKS5jbG9uZSgpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGNoZWNrQXR0cmlidXRlcykgewogICAgICAgICAgICBmb3IgKGF0dHJpYnV0ZU5hbWUgaW4gY2hlY2tBdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICBtZXRob2QgPSBhdHRyaWJ1dGVDaGVja01ldGhvZHNbY2hlY2tBdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdXTsKICAgICAgICAgICAgICAgIGlmICghbWV0aG9kKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBuZXdBdHRyaWJ1dGVWYWx1ZSA9IG1ldGhvZChfZ2V0QXR0cmlidXRlKG9sZE5vZGUsIGF0dHJpYnV0ZU5hbWUpKTsKICAgICAgICAgICAgICAgIGlmICh0eXBlb2YobmV3QXR0cmlidXRlVmFsdWUpID09PSAic3RyaW5nIikgewogICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNbYXR0cmlidXRlTmFtZV0gPSBuZXdBdHRyaWJ1dGVWYWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHNldENsYXNzKSB7CiAgICAgICAgICAgIGNsYXNzZXMucHVzaChzZXRDbGFzcyk7CiAgICAgICAgfQoKICAgICAgICBpZiAoYWRkQ2xhc3MpIHsKICAgICAgICAgICAgZm9yIChhdHRyaWJ1dGVOYW1lIGluIGFkZENsYXNzKSB7CiAgICAgICAgICAgICAgICBtZXRob2QgPSBhZGRDbGFzc01ldGhvZHNbYWRkQ2xhc3NbYXR0cmlidXRlTmFtZV1dOwogICAgICAgICAgICAgICAgaWYgKCFtZXRob2QpIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5ld0NsYXNzID0gbWV0aG9kKF9nZXRBdHRyaWJ1dGUob2xkTm9kZSwgYXR0cmlidXRlTmFtZSkpOwogICAgICAgICAgICAgICAgaWYgKHR5cGVvZihuZXdDbGFzcykgPT09ICJzdHJpbmciKSB7CiAgICAgICAgICAgICAgICAgICAgY2xhc3Nlcy5wdXNoKG5ld0NsYXNzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgd3lzaWh0bWw1IHRlbXAgY2xhc3MgZG9lc24ndCBnZXQgc3RyaXBwZWQgb3V0CiAgICAgICAgYWxsb3dlZENsYXNzZXNbIl93eXNpaHRtbDUtdGVtcC1wbGFjZWhvbGRlciJdID0gMTsKICAgICAgICBhbGxvd2VkQ2xhc3Nlc1siQXBwbGUtdGFiLXNwYW4iXSA9IDI7CgogICAgICAgIC8vIGFkZCBvbGQgY2xhc3NlcyBsYXN0CiAgICAgICAgb2xkQ2xhc3NlcyA9IG9sZE5vZGUuZ2V0QXR0cmlidXRlKCJjbGFzcyIpOwogICAgICAgIGlmIChvbGRDbGFzc2VzKSB7CiAgICAgICAgICAgIGNsYXNzZXMgPSBjbGFzc2VzLmNvbmNhdChvbGRDbGFzc2VzLnNwbGl0KFdISVRFX1NQQUNFX1JFR19FWFApKTsKICAgICAgICB9CiAgICAgICAgY2xhc3Nlc0xlbmd0aCA9IGNsYXNzZXMubGVuZ3RoOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBjbGFzc2VzTGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgY3VycmVudENsYXNzID0gY2xhc3Nlc1tpXTsKICAgICAgICAgICAgaWYgKGFsbG93ZWRDbGFzc2VzW2N1cnJlbnRDbGFzc10pIHsKICAgICAgICAgICAgICAgIG5ld0NsYXNzZXMucHVzaChjdXJyZW50Q2xhc3MpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyByZW1vdmUgZHVwbGljYXRlIGVudHJpZXMgYW5kIHByZXNlcnZlIGNsYXNzIHNwZWNpZmljaXR5CiAgICAgICAgbmV3Q2xhc3Nlc0xlbmd0aCA9IG5ld0NsYXNzZXMubGVuZ3RoOwogICAgICAgIHdoaWxlIChuZXdDbGFzc2VzTGVuZ3RoLS0pIHsKICAgICAgICAgICAgY3VycmVudENsYXNzID0gbmV3Q2xhc3Nlc1tuZXdDbGFzc2VzTGVuZ3RoXTsKICAgICAgICAgICAgaWYgKCF3eXNpaHRtbDUubGFuZy5hcnJheShuZXdVbmlxdWVDbGFzc2VzKS5jb250YWlucyhjdXJyZW50Q2xhc3MpKSB7CiAgICAgICAgICAgICAgICBuZXdVbmlxdWVDbGFzc2VzLnVuc2hpZnQoY3VycmVudENsYXNzKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG5ld1VuaXF1ZUNsYXNzZXMubGVuZ3RoKSB7CiAgICAgICAgICAgIGF0dHJpYnV0ZXNbImNsYXNzIl0gPSBuZXdVbmlxdWVDbGFzc2VzLmpvaW4oIiAiKTsKICAgICAgICB9CgogICAgICAgIC8vIHNldCBhdHRyaWJ1dGVzIG9uIG5ld05vZGUKICAgICAgICBmb3IgKGF0dHJpYnV0ZU5hbWUgaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICAvLyBTZXR0aW5nIGF0dHJpYnV0ZXMgY2FuIGNhdXNlIGEganMgZXJyb3IgaW4gSUUgdW5kZXIgY2VydGFpbiBjaXJjdW1zdGFuY2VzCiAgICAgICAgICAgIC8vIGVnLiBvbiBhIDxpbWc+IHVuZGVyIGh0dHBzIHdoZW4gaXQncyBuZXcgYXR0cmlidXRlIHZhbHVlIGlzIG5vbi1odHRwcwogICAgICAgICAgICAvLyBUT0RPOiBJbnZlc3RpZ2F0ZSB0aGlzIGZ1cnRoZXIgYW5kIGNoZWNrIGZvciBzbWFydGVyIGhhbmRsaW5nCiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBuZXdOb2RlLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCBhdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdKTsKICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBJRTggc29tZXRpbWVzIGxvc2VzIHRoZSB3aWR0aC9oZWlnaHQgYXR0cmlidXRlcyB3aGVuIHRob3NlIGFyZSBzZXQgYmVmb3JlIHRoZSAic3JjIgogICAgICAgIC8vIHNvIHdlIG1ha2Ugc3VyZSB0byBzZXQgdGhlbSBhZ2FpbgogICAgICAgIGlmIChhdHRyaWJ1dGVzLnNyYykgewogICAgICAgICAgICBpZiAodHlwZW9mKGF0dHJpYnV0ZXMud2lkdGgpICE9PSAidW5kZWZpbmVkIikgewogICAgICAgICAgICAgICAgbmV3Tm9kZS5zZXRBdHRyaWJ1dGUoIndpZHRoIiwgYXR0cmlidXRlcy53aWR0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHR5cGVvZihhdHRyaWJ1dGVzLmhlaWdodCkgIT09ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgICAgICBuZXdOb2RlLnNldEF0dHJpYnV0ZSgiaGVpZ2h0IiwgYXR0cmlidXRlcy5oZWlnaHQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBfY29weVN0eWxlVG9OZXdOb2RlKG9sZE5vZGUsIG5ld05vZGUpOwogICAgICAgIF9jb3B5TGlzdFR5cGVUb05ld05vZGUob2xkTm9kZSwgbmV3Tm9kZSk7CiAgICAgICAgX2NvcHlEYXRhQXR0cmlidXRlVG9OZXdOb2RlKG9sZE5vZGUsIG5ld05vZGUpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9jb3B5RGF0YUF0dHJpYnV0ZVRvTmV3Tm9kZShvbGROb2RlLCBuZXdOb2RlKSB7CiAgICAgICAgaWYgKG9sZE5vZGUgJiYgbmV3Tm9kZSkgewogICAgICAgICAgICB2YXIgZGF0YXNldCA9IG9sZE5vZGUuZGF0YXNldDsKICAgICAgICAgICAgZm9yICh2YXIgYXR0cmlidXRlIGluIGRhdGFzZXQpIHsKICAgICAgICAgICAgICAgICQobmV3Tm9kZSkuZGF0YShhdHRyaWJ1dGUsIGRhdGFzZXRbYXR0cmlidXRlXSk7CiAgICAgICAgICAgICAgICAkKG5ld05vZGUpLmF0dHIoJ2RhdGEtJyArIGF0dHJpYnV0ZSwgZGF0YXNldFthdHRyaWJ1dGVdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfY29weUxpc3RUeXBlVG9OZXdOb2RlKG9sZE5vZGUsIG5ld05vZGUpIHsKICAgICAgICBpZiAob2xkTm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09ICdvbCcpIHsKICAgICAgICAgICAgdmFyIGxpc3RUeXBlID0gb2xkTm9kZS5nZXRBdHRyaWJ1dGUoJ3R5cGUnKTsKICAgICAgICAgICAgaWYgKGxpc3RUeXBlKSB7CiAgICAgICAgICAgICAgICBuZXdOb2RlLnNldEF0dHJpYnV0ZSgndHlwZScsIGxpc3RUeXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfY29weVN0eWxlVG9OZXdOb2RlKG9sZE5vZGUsIG5ld05vZGUpIHsKICAgICAgICB2YXIgc3VwcG9ydGVkU3R5bGVzID0gY3VycmVudFJ1bGVzLnN0eWxlczsKICAgICAgICB2YXIgY29tcHV0ZWRTdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShvbGROb2RlKSwKICAgICAgICAgICAgYXBwbGllZFN0eWxlcyA9IG9sZE5vZGUuc3R5bGU7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcHBsaWVkU3R5bGVzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHZhciBzdHlsZUF0dHIgPSBhcHBsaWVkU3R5bGVzW2ldOwogICAgICAgICAgICB2YXIgdmFsdWUgPSBhcHBsaWVkU3R5bGVzLmdldFByb3BlcnR5VmFsdWUoc3R5bGVBdHRyKTsKICAgICAgICAgICAgaWYgKHN1cHBvcnRlZFN0eWxlcy5pbmRleE9mKHN0eWxlQXR0cikgPj0gMCkgewogICAgICAgICAgICAgICAgaWYgKHByZVByb2Nlc3NpbmdDb250ZW50ICYmIHN0eWxlQXR0ciA9PT0gImJhY2tncm91bmQtY29sb3IiICYmIHZhbHVlID09PSAicmdiKDI1NSwgMjU1LCAyNTUpIikgewogICAgICAgICAgICAgICAgICAgIC8qIFJlbW92ZSBiYWNrZ3JvdW5kIGNvbG9yIGlmIHdoaXRlIHNpbmNlIGl0cyByZWR1bmRhbnQgYXMgaXQgaXMgc2FtZSBhcyBkZWZhdWx0CiAgICAgICAgICAgICAgICAgICAgKiBGaXhlcyBidWcgQ1EtNDIwOTA0NyAqLwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIXZhbHVlIHx8ICF2YWx1ZS5tYXRjaCgvXlsuXGRdK3B0JC8pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IGNvbXB1dGVkU3R5bGVzLmdldFByb3BlcnR5VmFsdWUoc3R5bGVBdHRyKSB8fCAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgLyogUmVwbGFjZSBhbGwgcHggdmFsdWVzIHRvIHB0Ki8KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlZ0V4cCA9IG5ldyBSZWdFeHAoIl4oWy5cXGRdKylweCQiLCAiZyIpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gcmVnRXhwLmV4ZWModmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWVJblB4ID0gcGFyc2VGbG9hdChyZXN1bHRbMV0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlSW5QdCA9ICIiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFpc05hTih2YWx1ZUluUHgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVJblB0ID0gKHZhbHVlSW5QeCAqIDAuNzUpICsgInB0IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZShyZWdFeHAsIHZhbHVlSW5QdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBuZXdOb2RlLnN0eWxlLnNldFByb3BlcnR5KHN0eWxlQXR0ciwgdmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vSW4gZmlyZWZveCwgbm9kZS5jaGlsZEVsZW1lbnRDb3VudCBpcyBjaGlsZG5vZGVzIGNvdW50IHdoZXJlIGNoaWxkbm9kZXMgYXJlIG9mIGVsZW1lbnQgdHlwZSAoTm9kZS5FTEVNRU5UX05PREUgPT0gMSksIGl0IGRvZXMgbm90IGNvbnNpZGVyIHRleHQgdHlwZSBub2RlIGFzIGVsZW1lbnQgbm9kZS4KICAgIGZ1bmN0aW9uIF92YWxpZENoaWxkTm9kZUNvdW50KG9sZE5vZGUpIHsKICAgICAgICBpZiAob2xkTm9kZSkgewogICAgICAgICAgICB2YXIgY2hpbGROb2RlcyA9IG9sZE5vZGUuY2hpbGROb2RlczsKICAgICAgICAgICAgdmFyIGNoaWxkTm9kZSwgY291bnQgPSAwOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIGNoaWxkTm9kZSA9IGNoaWxkTm9kZXNbaV07CiAgICAgICAgICAgICAgICBpZiAoKGNoaWxkTm9kZS5ub2RlVHlwZSA9PSAxIHx8IGNoaWxkTm9kZS5ub2RlVHlwZSA9PSAzKSAmJiBjaGlsZE5vZGUudGV4dENvbnRlbnQgJiYgY2hpbGROb2RlLnRleHRDb250ZW50LnRyaW0oKSkgewogICAgICAgICAgICAgICAgICAgIGNvdW50Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNvdW50ID49IDIpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvLyBCdWcgRml4IC0gQ1EtOTUxMzAuIEluIGxpc3RpbmcgZXh0cmEgc3BhY2UgaXMgYWRkZWQuIFJlbW92aW5nIGFsbCBleHRyYSBzcGFjZSBmcm9tIGp1c3QgYmVmb3JlIGFuZCBhZnRlciBub2RlIG9mIHR5cGUgZGV0ZXJtaW5pbmcKICAgIC8vIG5vZGUgb2YgTXNvIGxpc3QuCiAgICBmdW5jdGlvbiBfcmVtb3ZlRXh0cmFTcGFjZShvbGROb2RlLCB0eXBlRGV0ZXJtaW5pZ05vZGUpIHsKICAgICAgICB2YXIgY2hpbGROb2RlcyA9IG9sZE5vZGUuY2hpbGROb2RlczsKICAgICAgICB2YXIgY2hpbGROb2RlLCBpOwogICAgICAgIGlmICghd3lzaWh0bWw1LmJyb3dzZXIuaXNGaXJlRm94KSB7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGNoaWxkTm9kZXNbaV0gIT0gdHlwZURldGVybWluaWdOb2RlOyBpKyspIHsKICAgICAgICAgICAgICAgIGNoaWxkTm9kZSA9IGNoaWxkTm9kZXNbaV07CiAgICAgICAgICAgICAgICBpZiAoY2hpbGROb2RlICYmIGNoaWxkTm9kZS50ZXh0Q29udGVudCkgewogICAgICAgICAgICAgICAgICAgIGNoaWxkTm9kZS50ZXh0Q29udGVudCA9IGNoaWxkTm9kZS50ZXh0Q29udGVudC50cmltKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaSsrOyAvLyBKdXN0IG5leHQgbm9kZSB0byBMaXN0IHR5cGUgZGV0ZXJtaW5pbmcgbm9kZQogICAgICAgICAgICBjaGlsZE5vZGUgPSBjaGlsZE5vZGVzW2ldOwogICAgICAgICAgICBpZiAoY2hpbGROb2RlICYmIGNoaWxkTm9kZS50ZXh0Q29udGVudCkgewogICAgICAgICAgICAgICAgY2hpbGROb2RlLnRleHRDb250ZW50ID0gY2hpbGROb2RlLnRleHRDb250ZW50LnRyaW0oKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gb2xkTm9kZTsKICAgIH0KCiAgICBmdW5jdGlvbiBfY29udmVydFdvcmRUb0hUTUxOb2RlKG9sZE5vZGUsIHRhZ1J1bGVzKSB7CiAgICAgICAgaWYgKG9sZE5vZGUpIHsKICAgICAgICAgICAgLyogY2hlY2sgaWYgaXRzIE1zb0xpc3RQYXJhZ3JhcGggdGhlbiBjcmVhdGUgbGkgYW5kIGlmIGl0cyBNc29MaXN0UGFyYWdyYXBoQ3hTcEZpcnN0IHRoZW4gY29udmVydCB0byBPTCBvciBVTAogICAgICAgICAgICAgKiBPTCBvciBVTCBpcyBkZWNpZGVkIGJhc2VkIG9uIGZpcnN0IFNwYW4gY29udGVudAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKC9Nc29MaXN0UGFyYWdyYXBoL2kudGVzdChvbGROb2RlLmNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgICAgIHZhciBpc05ld0NvbnRhaW5lciA9IF9zZXRDdXJyZW50TGlzdEVsZW1lbnQob2xkTm9kZSk7CiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgTEkgYW5kIGNvcHkgdGhlIGNoaWxkIG9mIG9sZCBub2RlIHRvIG5ldyBMSSBub2RlIHVzaW5nIHJ1bGUgd3JpdHRlbiBmb3IgcGFyc2luZwogICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgibGkiKSwKICAgICAgICAgICAgICAgICAgICBvbGRGb250RmFtaWx5ID0gb2xkTm9kZS5maXJzdEVsZW1lbnRDaGlsZC5zdHlsZS5mb250RmFtaWx5LAogICAgICAgICAgICAgICAgICAgIGZvbnRGYW1pbHlMaXN0ID0gQXJyYXkuZnJvbSgkKCIjdGV4dEVkaXRvcl9mb250RmFtaWx5X2NvbnRhaW5lciBjb3JhbC1zZWxlY3QtaXRlbSIpKS5tYXAoZnVuY3Rpb24gKGl0ZW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0udmFsdWU7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBjb3BpZWQgZm9udC1mYW1pbHkgaXMgcHJlc2V0IGluIHJ0ZS1lZGl0b3IgZm9udCBsaXN0LCBhZGQgZm9udC1mYW1pbHkgdG8gbGkgZWxlbWVudAogICAgICAgICAgICAgICAgaWYgKG9sZEZvbnRGYW1pbHkgIT0gbnVsbCAmJiBmb250RmFtaWx5TGlzdC5pbmNsdWRlcyhvbGRGb250RmFtaWx5LnNwbGl0KCIsIilbMF0pKSB7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5mb250RmFtaWx5ID0gb2xkRm9udEZhbWlseTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciBwYXJhRWxlbWVudCA9IG9sZE5vZGUub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KCJwIik7CiAgICAgICAgICAgICAgICBpZiAob2xkTm9kZS5maXJzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5ld05vZGUgPSBudWxsLCBmaXJzdENoaWxkID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBmaXJzdENoaWxkID0gX2dldFRleHRDaGlsZE5vZGUob2xkTm9kZSk7CiAgICAgICAgICAgICAgICAgICAgb2xkTm9kZSA9IF9yZW1vdmVFeHRyYVNwYWNlKG9sZE5vZGUsIGZpcnN0Q2hpbGQpOyAvLyBSZW1vdmUgZXh0cmEgc3BhY2UgZnJvbSBsaXN0LgogICAgICAgICAgICAgICAgICAgIGZpcnN0Q2hpbGQgPSBfZ2V0VGV4dENoaWxkTm9kZShvbGROb2RlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3RDaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICBvbGROb2RlLnJlbW92ZUNoaWxkKGZpcnN0Q2hpbGQpOwogICAgICAgICAgICAgICAgICAgIH0gLy8gUmVtb3ZlIHRoZSBmaXJzdENoaWxkIHdoaWNoIGhvbGQgdGhlIEJ1bGxldCBvciBudW1iZXIgdHlwZQogICAgICAgICAgICAgICAgICAgIHdoaWxlIChvbGROb2RlLmZpcnN0Q2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RDaGlsZCA9IG9sZE5vZGUuZmlyc3RDaGlsZDsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3Tm9kZSA9IF9jb252ZXJ0KGZpcnN0Q2hpbGQsIHRydWUsICJwIik7CiAgICAgICAgICAgICAgICAgICAgICAgIG9sZE5vZGUucmVtb3ZlQ2hpbGQoZmlyc3RDaGlsZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdOb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhRWxlbWVudC5hcHBlbmRDaGlsZChuZXdOb2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKHBhcmFFbGVtZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChjdXJyZW50TGlzdEVsZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGlzdEVsZW1lbnQuYXBwZW5kQ2hpbGQoZWxlbWVudCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGlzTmV3Q29udGFpbmVyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRMaXN0RWxlbWVudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICB2YXIgY3VycmVudExpc3RFbGVtZW50ID0gbnVsbDsKICAgIHZhciBsZXZlbExpc3RNYXAgPSB7fTsgLy8gVGhpcyBtYXAgd2lsbCBob2xkIHRoZSBDb250YWluZXIgKCBPTCBvciBVTCApIGZvciBlYWNoIGxldmVsICggbXVsdGktbGV2ZWwgbGlzdGluZykKICAgIHZhciBNU19MRVZFTDEgPSAibGV2ZWwxIjsKCiAgICBmdW5jdGlvbiBfc2V0Q3VycmVudExpc3RFbGVtZW50KG9sZE5vZGUpIHsKICAgICAgICBpZiAob2xkTm9kZSkgewogICAgICAgICAgICB2YXIgY29udGFpbmVyID0gX2NyZWF0ZUxpc3RDb250YWluZXIob2xkTm9kZSk7CiAgICAgICAgICAgIHZhciBsaXN0UHJvcGVydHkgPSBfZ2V0Q3VzdG9tQ3NzUHJvcGVydHkob2xkTm9kZSwgIm1zby1saXN0Iik7CiAgICAgICAgICAgIGxpc3RQcm9wZXJ0eSA9IGxpc3RQcm9wZXJ0eSA/IGxpc3RQcm9wZXJ0eS5zcGxpdCgiICIpIDogW107CiAgICAgICAgICAgIHZhciBsaXN0TGV2ZWwgPSBsaXN0UHJvcGVydHkgJiYgbGlzdFByb3BlcnR5Lmxlbmd0aCA+PSAyID8gbGlzdFByb3BlcnR5WzFdIDogTVNfTEVWRUwxOwogICAgICAgICAgICAvKiBDcmVhdGUgYSBPTCBvciBVTCBpbiBmb2xsb3dpbmcgY2FzZQogICAgICAgICAgICAgKiBhICAgIGlmIGN1cnJlbnRMaXN0RWxlbWVudCBpcyBub3QgZm91bmQgaW4gdGhlIG1hcCAoIGZpcnN0IExJKQogICAgICAgICAgICAgKiBiICAgIGVsc2UgaWYgYnVsbGV0IG9yIG51bWJlciB0eXBlIGlzIGNoYW5nZWQgaW4gbWlkZGxlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAobGV2ZWxMaXN0TWFwLmhhc093blByb3BlcnR5KGxpc3RMZXZlbCkpIHsvLyBjb250YWluZXIgaXMgYXZhaWxhYmxlIGluIGxldmVsTGlzdE1hcAogICAgICAgICAgICAgICAgY3VycmVudExpc3RFbGVtZW50ID0gbGV2ZWxMaXN0TWFwW2xpc3RMZXZlbF07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFjdXJyZW50TGlzdEVsZW1lbnQgfHwgKGNvbnRhaW5lciAmJiAoY3VycmVudExpc3RFbGVtZW50LnR5cGUgIT0gY29udGFpbmVyLnR5cGUgfHwgIWxldmVsTGlzdE1hcC5oYXNPd25Qcm9wZXJ0eShsaXN0TGV2ZWwpKSkpIHsgLy8gMm5kIGNvbmRpdGlvbiBpcyBpZiBsaXN0IHR5cGUgY2hhbmdlIG9yIGNvbXBvdW5kIGxpc3QgdGhlbiBjcmVhdGUgbmV3IGNvbnRhaW5lcgogICAgICAgICAgICAgICAgaWYgKE1TX0xFVkVMMSA9PSBsaXN0TGV2ZWwpIHsKICAgICAgICAgICAgICAgICAgICBsZXZlbExpc3RNYXAgPSB7fTsKICAgICAgICAgICAgICAgIH0gLy8gSWYgaXRzIGxldmVsIDEgdGhlbiByZXN0IHRoZSBNYXAKICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJlbnRMaXN0RWxlbWVudCAmJiBjdXJyZW50TGlzdEVsZW1lbnQubGFzdEVsZW1lbnRDaGlsZCkgey8vIGlmIG5leHQgbGV2ZWwgaXMgc3RhcnRpbmcgdGhlbiBhZGQgbmV3IGNvbnRhaW5lciB0byBwYXJlbnQgTGlzdCBjb250YWluZXIKICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGlzdEVsZW1lbnQubGFzdEVsZW1lbnRDaGlsZC5hcHBlbmRDaGlsZChjb250YWluZXIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGV2ZWxMaXN0TWFwW2xpc3RMZXZlbF0gPSBjb250YWluZXI7CiAgICAgICAgICAgICAgICBjdXJyZW50TGlzdEVsZW1lbnQgPSBjb250YWluZXI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKE1TX0xFVkVMMSA9PSBsaXN0TGV2ZWwpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9IC8vIHNlbmQgdHJ1ZSBpZiBmaXJzdCBsZXZlbCBjb250YWluZXIgaXMgYWRkZWQgYXMgaXQgbmVlZCB0byBiZSBhZGRlZCBpbiBET00gb3RoZXIgbGV2ZWwgY29udGFpbmVyIHdpbGwgYmUgZGlyZWN0bHkgYWRkZWQgdG8gcGFyZW50IGxpc3QgY29udGFpbmVyCiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBmdW5jdGlvbiBfY2xlYW5VcFdvcmRUb0hUTUxDYWNoZSgpIHsKICAgICAgICBsZXZlbExpc3RNYXAgPSB7fTsKICAgICAgICBjdXJyZW50TGlzdEVsZW1lbnQgPSBudWxsOwogICAgfQoKICAgIGZ1bmN0aW9uIF9jcmVhdGVMaXN0Q29udGFpbmVyKG9sZE5vZGUpIHsKICAgICAgICB2YXIgZWxlbWVudCA9IG51bGw7CiAgICAgICAgaWYgKG9sZE5vZGUpIHsKICAgICAgICAgICAgaWYgKC9Nc29MaXN0UGFyYWdyYXBoL2kudGVzdChvbGROb2RlLmNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgICAgIHZhciB0ZXh0Tm9kZSA9IF9nZXRUZXh0Q2hpbGROb2RlKG9sZE5vZGUpOwogICAgICAgICAgICAgICAgaWYgKHRleHROb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRDb250ZW50ID0gdGV4dE5vZGUudGV4dENvbnRlbnQgPyB0ZXh0Tm9kZS50ZXh0Q29udGVudC50cmltKCkgOiAiIjsKICAgICAgICAgICAgICAgICAgICB2YXIgc3BsaXRBcnJheSA9IHRleHRDb250ZW50LnNwbGl0KCIuIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKChzcGxpdEFycmF5Lmxlbmd0aCAtIDIpID49IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dENvbnRlbnQgPSBzcGxpdEFycmF5W3NwbGl0QXJyYXkubGVuZ3RoIC0gMl07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciB0eXBlID0gdGV4dENvbnRlbnQgPyBfZ2V0TGlzdENvbnRhaW5lclR5cGUodGV4dENvbnRlbnQpIDogbnVsbDsKICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSkgey8vIENoZWNrIHR5cGUgb2YgY29udGVudCBpbiBmaXJzdFNwYW4gKCB3aGljaCBjb250YWlucyBidWxsZXQgb3IgbnVtYmVyIHR5cGUpCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50TmFtZSA9IC9kaXNjfGNpcmNsZXxzcXVhcmUvLnRlc3QodHlwZSkgPyAidWwiIDogIm9sIjsKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IG9sZE5vZGUub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KGVsZW1lbnROYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC50eXBlID0gdHlwZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugey8vIGlmIHR5cGUgaXMgbm90IHJlY29nbml6ZWQgdGhlbiBjcmVhdGVkIFVMIHdpdGggdHlwZSBkaXNjCiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidWwiKTsKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC50eXBlID0gImRpc2MiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZWxlbWVudDsKICAgIH0KCiAgICBmdW5jdGlvbiBjaGVja0ZvckFscGhhYmV0TGlzdCh0ZXh0Q29udGVudCwgY3VycmVudExpc3RFbGVtZW50KSB7CiAgICAgICAgaWYgKGN1cnJlbnRMaXN0RWxlbWVudCAmJiAoY3VycmVudExpc3RFbGVtZW50LnR5cGUgPT0gImEiIHx8IGN1cnJlbnRMaXN0RWxlbWVudC50eXBlID09ICJBIikpIHsKICAgICAgICAgICAgdmFyIGFscGhhYmV0ID0gImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6IjsKICAgICAgICAgICAgdmFyIGNoYXJhY3RlckluQWxwaGFiZXRTZXQgPSBhbHBoYWJldC5jaGFyQXQoY3VycmVudExpc3RFbGVtZW50LmNoaWxkRWxlbWVudENvdW50KTsKICAgICAgICAgICAgaWYgKGN1cnJlbnRMaXN0RWxlbWVudC50eXBlID09ICJBIikgewogICAgICAgICAgICAgICAgY2hhcmFjdGVySW5BbHBoYWJldFNldCA9IGFscGhhYmV0LnRvVXBwZXJDYXNlKCkuY2hhckF0KGN1cnJlbnRMaXN0RWxlbWVudC5jaGlsZEVsZW1lbnRDb3VudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRleHRDb250ZW50ID09IGNoYXJhY3RlckluQWxwaGFiZXRTZXQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50TGlzdEVsZW1lbnQudHlwZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoY3VycmVudExpc3RFbGVtZW50ICYmIGN1cnJlbnRMaXN0RWxlbWVudC5wYXJlbnRFbGVtZW50ICYmIGN1cnJlbnRMaXN0RWxlbWVudC5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGNoZWNrRm9yQWxwaGFiZXRMaXN0KHRleHRDb250ZW50LCBjdXJyZW50TGlzdEVsZW1lbnQucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50KTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY2hlY2tGb3JOdW1lcmljTGlzdCh0ZXh0Q29udGVudCwgY3VycmVudExpc3RFbGVtZW50KSB7CiAgICAgICAgaWYgKGN1cnJlbnRMaXN0RWxlbWVudCAmJiAoY3VycmVudExpc3RFbGVtZW50LnR5cGUgPT0gIjEiKSkgewogICAgICAgICAgICB2YXIgY2hpbGRFbGVtZW50cyA9IGN1cnJlbnRMaXN0RWxlbWVudC5jaGlsZEVsZW1lbnRDb3VudDsKICAgICAgICAgICAgdmFyIGRlY2ltYWxWYWx1ZSA9IHBhcnNlSW50KHRleHRDb250ZW50KTsKICAgICAgICAgICAgaWYgKGNoaWxkRWxlbWVudHMgKyAxID09IGRlY2ltYWxWYWx1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRMaXN0RWxlbWVudC50eXBlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChjdXJyZW50TGlzdEVsZW1lbnQgJiYgY3VycmVudExpc3RFbGVtZW50LnBhcmVudEVsZW1lbnQgJiYgY3VycmVudExpc3RFbGVtZW50LnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudCkgewogICAgICAgICAgICByZXR1cm4gY2hlY2tGb3JOdW1lcmljTGlzdCh0ZXh0Q29udGVudCwgY3VycmVudExpc3RFbGVtZW50LnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudCk7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGNoZWNrRm9yUm9tYW5MaXN0KHRleHRDb250ZW50LCBjdXJyZW50TGlzdEVsZW1lbnQpIHsKICAgICAgICBpZiAoY3VycmVudExpc3RFbGVtZW50ICYmIChjdXJyZW50TGlzdEVsZW1lbnQudHlwZSA9PSAiaSIgfHwgY3VycmVudExpc3RFbGVtZW50LnR5cGUgPT0gIkkiKSkgewogICAgICAgICAgICB2YXIgY2hpbGRFbGVtZW50cyA9IGN1cnJlbnRMaXN0RWxlbWVudC5jaGlsZEVsZW1lbnRDb3VudDsKICAgICAgICAgICAgdmFyIHJvbWFuVmFsdWUgPSBfZ2V0Um9tYW5Ub0RlY2ltYWwodGV4dENvbnRlbnQpOwoKICAgICAgICAgICAgaWYgKGNoaWxkRWxlbWVudHMgKyAxID09IHJvbWFuVmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmICgodGV4dENvbnRlbnRbMF0udG9VcHBlckNhc2UoKSA9PSB0ZXh0Q29udGVudFswXSkgJiYgKGN1cnJlbnRMaXN0RWxlbWVudC50eXBlID09ICJJIikpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudExpc3RFbGVtZW50LnR5cGU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCh0ZXh0Q29udGVudFswXS50b0xvd2VyQ2FzZSgpID09IHRleHRDb250ZW50WzBdKSAmJiAoY3VycmVudExpc3RFbGVtZW50LnR5cGUgPT0gImkiKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50TGlzdEVsZW1lbnQudHlwZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoY3VycmVudExpc3RFbGVtZW50ICYmIGN1cnJlbnRMaXN0RWxlbWVudC5wYXJlbnRFbGVtZW50ICYmIGN1cnJlbnRMaXN0RWxlbWVudC5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGNoZWNrRm9yUm9tYW5MaXN0KHRleHRDb250ZW50LCBjdXJyZW50TGlzdEVsZW1lbnQucGFyZW50RWxlbWVudC5wYXJlbnRFbGVtZW50KTsKICAgICAgICB9CgogICAgfQoKICAgIGZ1bmN0aW9uIF9nZXRJbnRlZ2VyVmFsdWUocm9tYW5DaGFyKSB7CiAgICAgICAgdmFyIHJvbUFyciA9IFsiaSIsICJ2IiwgIngiLCAibCIsICJjIiwgImQiLCAibSJdOwogICAgICAgIHZhciBpbnRBcnIgPSBbMSwgNSwgMTAsIDUwLCAxMDAsIDUwMCwgMTAwMF07CiAgICAgICAgcmV0dXJuIGludEFycltyb21BcnIuaW5kZXhPZihyb21hbkNoYXIpXTsKICAgIH0KCiAgICBmdW5jdGlvbiBfZ2V0Um9tYW5Ub0RlY2ltYWwoc3RyKSB7CiAgICAgICAgdmFyIHJlcyA9IDAsIHJvbWFuRmlyc3RWYWwsIHJvbWFuU2Vjb25kVmFsOwogICAgICAgIHZhciBsb3dlclJvbWFuVHlwZVJlZyA9IC9ebXswLDR9KGNtfGNkfGQ/Y3swLDN9KSh4Y3x4bHxsP3h7MCwzfSkoaXh8aXZ8dj9pezAsM30pJC87CiAgICAgICAgaWYgKHN0ci50b0xvd2VyQ2FzZSgpLm1hdGNoKGxvd2VyUm9tYW5UeXBlUmVnKSkgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgcm9tYW5GaXJzdFZhbCA9IF9nZXRJbnRlZ2VyVmFsdWUoc3RyW2ldLnRvTG93ZXJDYXNlKCkpOwogICAgICAgICAgICAgICAgaWYgKGkgKyAxIDwgc3RyLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgIHJvbWFuU2Vjb25kVmFsID0gX2dldEludGVnZXJWYWx1ZShzdHJbaSArIDFdLnRvTG93ZXJDYXNlKCkpOwogICAgICAgICAgICAgICAgICAgIGlmIChyb21hbkZpcnN0VmFsID49IHJvbWFuU2Vjb25kVmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcyA9IHJlcyArIHJvbWFuRmlyc3RWYWw7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzID0gcmVzICsgcm9tYW5TZWNvbmRWYWwgLSByb21hbkZpcnN0VmFsOwogICAgICAgICAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXMgPSByZXMgKyByb21hbkZpcnN0VmFsOwogICAgICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfZ2V0TGlzdENvbnRhaW5lclR5cGUodGV4dENvbnRlbnRTdHIpIHsKICAgICAgICB2YXIgZGVjaW1hbFR5cGVSZWcgPSAvXGQrLywKICAgICAgICAgICAgbG93ZXJSb21hblR5cGVSZWcgPSAvXm17MCw0fShjbXxjZHxkP2N7MCwzfSkoeGN8eGx8bD94ezAsM30pKGl4fGl2fHY/aXswLDN9KSQvLAogICAgICAgICAgICB1cHBlclJvbWFuVHlwZVJlZyA9IC9eTXswLDR9KENNfENEfEQ/Q3swLDN9KShYQ3xYTHxMP1h7MCwzfSkoSVh8SVZ8Vj9JezAsM30pJC8sCiAgICAgICAgICAgIGxvd2VyQWxwaGFUeXBlUmVnID0gL15bYS16XSskLywKICAgICAgICAgICAgdXBwZXJBbHBoYVR5cGVSZWcgPSAvXltBLVpdKyQvOwogICAgICAgIHZhciBkaXNjVHlwZVJlZyA9IC9bbFx1MDBCN1x1MjAwMl0vLAogICAgICAgICAgICBjaXJjbGVUeXBlUmVnID0gL1tcdTAwNkZcdTAwRDhdLywKICAgICAgICAgICAgc3F1YXJlVHlwZVJlZyA9IC9bXHUwMDZFXHUyNUM2XHUwMEE3XS87CgogICAgICAgIHZhciB2YWxpZEFscGhhYmV0ID0gZmFsc2UsIHZhbGlkUm9tYW4gPSBmYWxzZSwgdmFsaWRJbnRlZ2VyID0gZmFsc2U7CiAgICAgICAgaWYgKHRleHRDb250ZW50U3RyKSB7CiAgICAgICAgICAgIGlmICh0ZXh0Q29udGVudFN0ci50b0xvd2VyQ2FzZSgpLm1hdGNoKGxvd2VyUm9tYW5UeXBlUmVnKSkgewogICAgICAgICAgICAgICAgdmFsaWRSb21hbiA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRleHRDb250ZW50U3RyLnRvTG93ZXJDYXNlKCkubWF0Y2gobG93ZXJBbHBoYVR5cGVSZWcpKSB7CiAgICAgICAgICAgICAgICB2YWxpZEFscGhhYmV0ID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGV4dENvbnRlbnRTdHIubWF0Y2goZGVjaW1hbFR5cGVSZWcpKSB7CiAgICAgICAgICAgICAgICB2YWxpZEludGVnZXIgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB2YXIgcm9tYW5MaXN0ID0gdmFsaWRSb21hbiA/IGNoZWNrRm9yUm9tYW5MaXN0KHRleHRDb250ZW50U3RyLCBjdXJyZW50TGlzdEVsZW1lbnQpIDogbnVsbDsKICAgICAgICBpZiAocm9tYW5MaXN0KSB7CiAgICAgICAgICAgIHJldHVybiByb21hbkxpc3Q7CiAgICAgICAgfQoKICAgICAgICB2YXIgdGV4dENvbnRlbnQgPSB0ZXh0Q29udGVudFN0ci5zdWJzdHIoMCwgMSk7CiAgICAgICAgdmFyIGFscGhhTGlzdCA9IHZhbGlkQWxwaGFiZXQgPyBjaGVja0ZvckFscGhhYmV0TGlzdCh0ZXh0Q29udGVudCwgY3VycmVudExpc3RFbGVtZW50KSA6IG51bGw7CiAgICAgICAgaWYgKGFscGhhTGlzdCkgewogICAgICAgICAgICByZXR1cm4gYWxwaGFMaXN0OwogICAgICAgIH0KCiAgICAgICAgdmFyIG51bWVyaWNMaXN0ID0gdmFsaWRJbnRlZ2VyID8gY2hlY2tGb3JOdW1lcmljTGlzdCh0ZXh0Q29udGVudFN0ciwgY3VycmVudExpc3RFbGVtZW50KSA6IG51bGw7CiAgICAgICAgaWYgKG51bWVyaWNMaXN0KSB7CiAgICAgICAgICAgIHJldHVybiBudW1lcmljTGlzdDsKICAgICAgICB9CgogICAgICAgIGlmICh0ZXh0Q29udGVudFN0ciAmJiAodGV4dENvbnRlbnRTdHIgPT0gImEiIHx8IHRleHRDb250ZW50U3RyID09ICJBIiB8fCB0ZXh0Q29udGVudFN0ciA9PSAiaSIgfHwgdGV4dENvbnRlbnRTdHIgPT0gIkkiIHx8IHRleHRDb250ZW50U3RyID09ICIxIikpIHsKICAgICAgICAgICAgcmV0dXJuIHRleHRDb250ZW50U3RyOwogICAgICAgIH0gZWxzZSBpZiAodGV4dENvbnRlbnQubWF0Y2goZGlzY1R5cGVSZWcpKSB7CiAgICAgICAgICAgIHJldHVybiAiZGlzYyI7CiAgICAgICAgfSBlbHNlIGlmICh0ZXh0Q29udGVudC5tYXRjaChjaXJjbGVUeXBlUmVnKSkgewogICAgICAgICAgICByZXR1cm4gImNpcmNsZSI7CiAgICAgICAgfSBlbHNlIGlmICh0ZXh0Q29udGVudC5tYXRjaChzcXVhcmVUeXBlUmVnKSkgewogICAgICAgICAgICByZXR1cm4gInNxdWFyZSI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8vIEFjdGlvbiBvbiAgTVNPIExpc3Qgbm9kZSB3aGljaCBmaXJzdCB0ZXh0IG5vZGUgaGFzIGxpc3QgdHlwZSBpbmZvcm1hdGlvbi4KICAgIGZ1bmN0aW9uIF9nZXRUZXh0Q2hpbGROb2RlKG9sZE5vZGUpIHsKICAgICAgICBpZiAob2xkTm9kZSkgewogICAgICAgICAgICB2YXIgY2hpbGROb2RlcyA9IG9sZE5vZGUuY2hpbGROb2RlczsKICAgICAgICAgICAgdmFyIHRleHRDb250ZW50LCBjaGlsZE5vZGU7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgY2hpbGROb2RlID0gY2hpbGROb2Rlc1tpXTsKICAgICAgICAgICAgICAgIHRleHRDb250ZW50ID0gY2hpbGROb2RlLnRleHRDb250ZW50ID8gY2hpbGROb2RlLnRleHRDb250ZW50LnRyaW0oKSA6ICIiOwogICAgICAgICAgICAgICAgaWYgKGNoaWxkTm9kZSAmJiAoY2hpbGROb2RlLm5vZGVUeXBlID09IDMgfHwgY2hpbGROb2RlLm5vZGVUeXBlID09IDEpICYmIHRleHRDb250ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkTm9kZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfaXNNU29MaXN0UGFyYWdyYXBoQ2hpbGQob2xkTm9kZSkgewogICAgICAgIC8vIFNpbmNlIGVhY2ggYW5kIHZlcnkgZWxlbWVudCBpcyBwYXNzZWQgd2h5IHBhcnNlciBjaGVjayBpZiBhbnkgZWxlbWVudCBpcyBwYXJ0IG9mIE1zb0xpc3RQYXJhZ3JhcGggaWYgc28gaWdub3JlIGl0IGFzIGl0cyBhbHJlYWR5IGhhbmRsZSB2aWEgY3JlYXRpbmcgTEkKICAgICAgICBpZiAob2xkTm9kZSkgewogICAgICAgICAgICBpZiAoL01zb0xpc3RQYXJhZ3JhcGgvaS50ZXN0KG9sZE5vZGUuY2xhc3NOYW1lKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIGZ1bmN0aW9uIF9nZXRDdXN0b21Dc3NQcm9wZXJ0eShlbGVtZW50LCBwcm9wZXJ0eU5hbWUpIHsKICAgICAgICBpZiAoZWxlbWVudCkgewogICAgICAgICAgICB2YXIgc3R5bGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgic3R5bGUiKTsKICAgICAgICAgICAgdmFyIGVudHJpZXMgPSBzdHlsZS5zcGxpdCgiOyIpOwoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7CiAgICAgICAgICAgICAgICAgaSA8IGVudHJpZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgdmFyIGVudHJ5ID0gZW50cmllc1tpXS5zcGxpdCgiOiIpOwogICAgICAgICAgICAgICAgaWYgKGVudHJ5WzBdID09IHByb3BlcnR5TmFtZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBlbnRyeVsxXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvKioKICAgICAqIElFIGdpdmVzIHdyb25nIHJlc3VsdHMgZm9yIGhhc0F0dHJpYnV0ZS9nZXRBdHRyaWJ1dGUsIGZvciBleGFtcGxlOgogICAgICogICAgdmFyIHRkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGQiKTsKICAgICAqICAgIHRkLmdldEF0dHJpYnV0ZSgicm93c3BhbiIpOyAvLyA9PiAiMSIgaW4gSUUKICAgICAqCiAgICAgKiBUaGVyZWZvcmUgd2UgaGF2ZSB0byBjaGVjayB0aGUgZWxlbWVudCdzIG91dGVySFRNTCBmb3IgdGhlIGF0dHJpYnV0ZQogICAgICovCiAgICB2YXIgSEFTX0dFVF9BVFRSSUJVVEVfQlVHID0gIXd5c2lodG1sNS5icm93c2VyLnN1cHBvcnRzR2V0QXR0cmlidXRlQ29ycmVjdGx5KCk7CgogICAgZnVuY3Rpb24gX2dldEF0dHJpYnV0ZShub2RlLCBhdHRyaWJ1dGVOYW1lKSB7CiAgICAgICAgYXR0cmlidXRlTmFtZSA9IGF0dHJpYnV0ZU5hbWUudG9Mb3dlckNhc2UoKTsKICAgICAgICB2YXIgbm9kZU5hbWUgPSBub2RlLm5vZGVOYW1lOwogICAgICAgIGlmIChub2RlTmFtZSA9PSAiSU1HIiAmJiBhdHRyaWJ1dGVOYW1lID09ICJzcmMiICYmIF9pc0xvYWRlZEltYWdlKG5vZGUpID09PSB0cnVlKSB7CiAgICAgICAgICAgIC8vIEdldCAnc3JjJyBhdHRyaWJ1dGUgdmFsdWUgdmlhIG9iamVjdCBwcm9wZXJ0eSBzaW5jZSB0aGlzIHdpbGwgYWx3YXlzIGNvbnRhaW4gdGhlCiAgICAgICAgICAgIC8vIGZ1bGwgYWJzb2x1dGUgdXJsIChodHRwOi8vLi4uKQogICAgICAgICAgICAvLyB0aGlzIGZpeGVzIGEgdmVyeSBhbm5veWluZyBidWcgaW4gZmlyZWZveCAodmVyIDMuNiAmIDQpIGFuZCBJRSA4IHdoZXJlIGltYWdlcyBjb3BpZWQgZnJvbSB0aGUgc2FtZSBob3N0CiAgICAgICAgICAgIC8vIHdpbGwgaGF2ZSByZWxhdGl2ZSBwYXRocywgd2hpY2ggdGhlIHNhbml0aXplciBzdHJpcHMgb3V0IChzZWUgYXR0cmlidXRlQ2hlY2tNZXRob2RzLnVybCkKICAgICAgICAgICAgcmV0dXJuIG5vZGUuc3JjOwogICAgICAgIH0gZWxzZSBpZiAoSEFTX0dFVF9BVFRSSUJVVEVfQlVHICYmICJvdXRlckhUTUwiIGluIG5vZGUpIHsKICAgICAgICAgICAgLy8gRG9uJ3QgdHJ1c3QgZ2V0QXR0cmlidXRlL2hhc0F0dHJpYnV0ZSBpbiBJRSA2LTgsIGluc3RlYWQgY2hlY2sgdGhlIGVsZW1lbnQncyBvdXRlckhUTUwKICAgICAgICAgICAgdmFyIG91dGVySFRNTCA9IG5vZGUub3V0ZXJIVE1MLnRvTG93ZXJDYXNlKCksCiAgICAgICAgICAgICAgICAvLyBUT0RPOiBUaGlzIG1pZ2h0IG5vdCB3b3JrIGZvciBhdHRyaWJ1dGVzIHdpdGhvdXQgdmFsdWU6IDxpbnB1dCBkaXNhYmxlZD4KICAgICAgICAgICAgICAgIGhhc0F0dHJpYnV0ZSA9IG91dGVySFRNTC5pbmRleE9mKCIgIiArIGF0dHJpYnV0ZU5hbWUgKyAiPSIpICE9IC0xOwoKICAgICAgICAgICAgcmV0dXJuIGhhc0F0dHJpYnV0ZSA/IG5vZGUuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUpIDogbnVsbDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbm9kZS5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qKgogICAgICogQ2hlY2sgd2hldGhlciB0aGUgZ2l2ZW4gbm9kZSBpcyBhIHByb3BlciBsb2FkZWQgaW1hZ2UKICAgICAqIEZJWE1FOiBSZXR1cm5zIHVuZGVmaW5lZCB3aGVuIHVua25vd24gKENocm9tZSwgU2FmYXJpKQogICAgICovCiAgICBmdW5jdGlvbiBfaXNMb2FkZWRJbWFnZShub2RlKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgcmV0dXJuIG5vZGUuY29tcGxldGUgJiYgIW5vZGUubW96TWF0Y2hlc1NlbGVjdG9yKCI6LW1vei1icm9rZW4iKTsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIGlmIChub2RlLmNvbXBsZXRlICYmIG5vZGUucmVhZHlTdGF0ZSA9PT0gImNvbXBsZXRlIikgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gX2hhbmRsZVRleHQob2xkTm9kZSkgewogICAgICAgIHJldHVybiBvbGROb2RlLm93bmVyRG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUob2xkTm9kZS5kYXRhKTsKICAgIH0KCiAgICAvLyAtLS0tLS0tLS0tLS0gYXR0cmlidXRlIGNoZWNrcyAtLS0tLS0tLS0tLS0gXFwKICAgIHZhciBhdHRyaWJ1dGVDaGVja01ldGhvZHMgPSB7CiAgICAgICAgYW55IDogKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChhdHRyaWJ1dGVWYWx1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZVZhbHVlOwogICAgICAgICAgICB9OwogICAgICAgIH0pKCksCgogICAgICAgIHVybCA6IChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBSRUdfRVhQID0gL15odHRwcz86XC9cLy9pOwogICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZVZhbHVlIHx8ICFhdHRyaWJ1dGVWYWx1ZS5tYXRjaChSRUdfRVhQKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoUkVHX0VYUCwgZnVuY3Rpb24gKG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfTsKICAgICAgICB9KSgpLAoKICAgICAgICBzcmMgOiAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgUkVHX0VYUCA9IC9eKFwvfGh0dHBzPzpcL1wvKS9pOwogICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZVZhbHVlIHx8ICFhdHRyaWJ1dGVWYWx1ZS5tYXRjaChSRUdfRVhQKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoUkVHX0VYUCwgZnVuY3Rpb24gKG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfTsKICAgICAgICB9KSgpLAoKICAgICAgICBocmVmIDogKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIFJFR19FWFAgPSAvXihcL3xodHRwcz86XC9cL3xtYWlsdG86KS9pOwogICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZVZhbHVlIHx8ICFhdHRyaWJ1dGVWYWx1ZS5tYXRjaChSRUdfRVhQKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoUkVHX0VYUCwgZnVuY3Rpb24gKG1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfTsKICAgICAgICB9KSgpLAoKICAgICAgICBhbHQgOiAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgUkVHX0VYUCA9IC9bXiBhLXowLTlfXC1dL2dpOwogICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoUkVHX0VYUCwgIiIpOwogICAgICAgICAgICB9OwogICAgICAgIH0pKCksCgogICAgICAgIG51bWJlcnMgOiAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgUkVHX0VYUCA9IC9cRC9nOwogICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVWYWx1ZSA9IChhdHRyaWJ1dGVWYWx1ZSB8fCAiIikucmVwbGFjZShSRUdfRVhQLCAiIik7CiAgICAgICAgICAgICAgICByZXR1cm4gYXR0cmlidXRlVmFsdWUgfHwgbnVsbDsKICAgICAgICAgICAgfTsKICAgICAgICB9KSgpCiAgICB9OwoKICAgIC8vIC0tLS0tLS0tLS0tLSBjbGFzcyBjb252ZXJ0ZXIgKGNvbnZlcnRzIGFuIGh0bWwgYXR0cmlidXRlIHRvIGEgY2xhc3MgbmFtZSkgLS0tLS0tLS0tLS0tIFxcCiAgICB2YXIgYWRkQ2xhc3NNZXRob2RzID0gewogICAgICAgIGFsaWduX2ltZyA6IChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBtYXBwaW5nID0gewogICAgICAgICAgICAgICAgbGVmdCA6ICJ3eXNpd3lnLWZsb2F0LWxlZnQiLAogICAgICAgICAgICAgICAgcmlnaHQgOiAid3lzaXd5Zy1mbG9hdC1yaWdodCIKICAgICAgICAgICAgfTsKICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChhdHRyaWJ1dGVWYWx1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG1hcHBpbmdbU3RyaW5nKGF0dHJpYnV0ZVZhbHVlKS50b0xvd2VyQ2FzZSgpXTsKICAgICAgICAgICAgfTsKICAgICAgICB9KSgpLAoKICAgICAgICBhbGlnbl90ZXh0IDogKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIG1hcHBpbmcgPSB7CiAgICAgICAgICAgICAgICBsZWZ0IDogInd5c2l3eWctdGV4dC1hbGlnbi1sZWZ0IiwKICAgICAgICAgICAgICAgIHJpZ2h0IDogInd5c2l3eWctdGV4dC1hbGlnbi1yaWdodCIsCiAgICAgICAgICAgICAgICBjZW50ZXIgOiAid3lzaXd5Zy10ZXh0LWFsaWduLWNlbnRlciIsCiAgICAgICAgICAgICAgICBqdXN0aWZ5IDogInd5c2l3eWctdGV4dC1hbGlnbi1qdXN0aWZ5IgogICAgICAgICAgICB9OwogICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbWFwcGluZ1tTdHJpbmcoYXR0cmlidXRlVmFsdWUpLnRvTG93ZXJDYXNlKCldOwogICAgICAgICAgICB9OwogICAgICAgIH0pKCksCgogICAgICAgIGNsZWFyX2JyIDogKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIG1hcHBpbmcgPSB7CiAgICAgICAgICAgICAgICBsZWZ0IDogInd5c2l3eWctY2xlYXItbGVmdCIsCiAgICAgICAgICAgICAgICByaWdodCA6ICJ3eXNpd3lnLWNsZWFyLXJpZ2h0IiwKICAgICAgICAgICAgICAgIGJvdGggOiAid3lzaXd5Zy1jbGVhci1ib3RoIiwKICAgICAgICAgICAgICAgIGFsbCA6ICJ3eXNpd3lnLWNsZWFyLWJvdGgiCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoYXR0cmlidXRlVmFsdWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBtYXBwaW5nW1N0cmluZyhhdHRyaWJ1dGVWYWx1ZSkudG9Mb3dlckNhc2UoKV07CiAgICAgICAgICAgIH07CiAgICAgICAgfSkoKSwKCiAgICAgICAgc2l6ZV9mb250IDogKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIG1hcHBpbmcgPSB7CiAgICAgICAgICAgICAgICAiMSIgOiAid3lzaXd5Zy1mb250LXNpemUteHgtc21hbGwiLAogICAgICAgICAgICAgICAgIjIiIDogInd5c2l3eWctZm9udC1zaXplLXNtYWxsIiwKICAgICAgICAgICAgICAgICIzIiA6ICJ3eXNpd3lnLWZvbnQtc2l6ZS1tZWRpdW0iLAogICAgICAgICAgICAgICAgIjQiIDogInd5c2l3eWctZm9udC1zaXplLWxhcmdlIiwKICAgICAgICAgICAgICAgICI1IiA6ICJ3eXNpd3lnLWZvbnQtc2l6ZS14LWxhcmdlIiwKICAgICAgICAgICAgICAgICI2IiA6ICJ3eXNpd3lnLWZvbnQtc2l6ZS14eC1sYXJnZSIsCiAgICAgICAgICAgICAgICAiNyIgOiAid3lzaXd5Zy1mb250LXNpemUteHgtbGFyZ2UiLAogICAgICAgICAgICAgICAgIi0iIDogInd5c2l3eWctZm9udC1zaXplLXNtYWxsZXIiLAogICAgICAgICAgICAgICAgIisiIDogInd5c2l3eWctZm9udC1zaXplLWxhcmdlciIKICAgICAgICAgICAgfTsKICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChhdHRyaWJ1dGVWYWx1ZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG1hcHBpbmdbU3RyaW5nKGF0dHJpYnV0ZVZhbHVlKS5jaGFyQXQoMCldOwogICAgICAgICAgICB9OwogICAgICAgIH0pKCkKICAgIH07CgogICAgcmV0dXJuIHBhcnNlOwp9KSgpOwovKioKICogQ2hlY2tzIGZvciBlbXB0eSB0ZXh0IG5vZGUgY2hpbGRzIGFuZCByZW1vdmVzIHRoZW0KICoKICogQHBhcmFtIHtFbGVtZW50fSBub2RlIFRoZSBlbGVtZW50IGluIHdoaWNoIHRvIGNsZWFudXAKICogQGV4YW1wbGUKICogICAgd3lzaWh0bWw1LmRvbS5yZW1vdmVFbXB0eVRleHROb2RlcyhlbGVtZW50KTsKICovCnd5c2lodG1sNS5kb20ucmVtb3ZlRW1wdHlUZXh0Tm9kZXMgPSBmdW5jdGlvbiAobm9kZSkgewogICAgdmFyIGNoaWxkTm9kZSwKICAgICAgICBjaGlsZE5vZGVzID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkobm9kZS5jaGlsZE5vZGVzKS5nZXQoKSwKICAgICAgICBjaGlsZE5vZGVzTGVuZ3RoID0gY2hpbGROb2Rlcy5sZW5ndGgsCiAgICAgICAgaSA9IDA7CiAgICBmb3IgKDsKICAgICAgICBpIDwgY2hpbGROb2Rlc0xlbmd0aDsKICAgICAgICBpKyspIHsKICAgICAgICBjaGlsZE5vZGUgPSBjaGlsZE5vZGVzW2ldOwogICAgICAgIGlmIChjaGlsZE5vZGUubm9kZVR5cGUgPT09IHd5c2lodG1sNS5URVhUX05PREUgJiYgY2hpbGROb2RlLmRhdGEgPT09ICIiKSB7CiAgICAgICAgICAgIGNoaWxkTm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGNoaWxkTm9kZSk7CiAgICAgICAgfQogICAgfQp9OwovKioKICogUmVuYW1lcyBhbiBlbGVtZW50IChlZy4gYSA8ZGl2PiB0byBhIDxwPikgYW5kIGtlZXBzIGl0cyBjaGlsZHMKICoKICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IFRoZSBsaXN0IGVsZW1lbnQgd2hpY2ggc2hvdWxkIGJlIHJlbmFtZWQKICogQHBhcmFtIHtFbGVtZW50fSBuZXdOb2RlTmFtZSBUaGUgZGVzaXJlZCB0YWcgbmFtZQogKgogKiBAZXhhbXBsZQogKiAgICA8IS0tIEFzc3VtZSB0aGUgZm9sbG93aW5nIGRvbTogLS0+CiAqICAgIDx1bCBpZD0ibGlzdCI+CiAqICAgICAgPGxpPmVtaW5lbTwvbGk+CiAqICAgICAgPGxpPmRyLiBkcmU8L2xpPgogKiAgICAgIDxsaT41MCBDZW50PC9saT4KICogICAgPC91bD4KICoKICogICAgPHNjcmlwdD4KICogICAgICB3eXNpaHRtbDUuZG9tLnJlbmFtZUVsZW1lbnQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImxpc3QiKSwgIm9sIik7CiAqICAgIDwvc2NyaXB0PgogKgogKiAgICA8IS0tIFdpbGwgcmVzdWx0IGluOiAtLT4KICogICAgPG9sPgogKiAgICAgIDxsaT5lbWluZW08L2xpPgogKiAgICAgIDxsaT5kci4gZHJlPC9saT4KICogICAgICA8bGk+NTAgQ2VudDwvbGk+CiAqICAgIDwvb2w+CiAqLwp3eXNpaHRtbDUuZG9tLnJlbmFtZUVsZW1lbnQgPSBmdW5jdGlvbiAoZWxlbWVudCwgbmV3Tm9kZU5hbWUpIHsKICAgIHZhciBuZXdFbGVtZW50ID0gZWxlbWVudC5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQobmV3Tm9kZU5hbWUpLAogICAgICAgIGZpcnN0Q2hpbGQ7CiAgICB3aGlsZSAoZmlyc3RDaGlsZCA9IGVsZW1lbnQuZmlyc3RDaGlsZCkgewogICAgICAgIG5ld0VsZW1lbnQuYXBwZW5kQ2hpbGQoZmlyc3RDaGlsZCk7CiAgICB9CiAgICB3eXNpaHRtbDUuZG9tLmNvcHlBdHRyaWJ1dGVzKFsiYWxpZ24iLCAiY2xhc3NOYW1lIl0pLmZyb20oZWxlbWVudCkudG8obmV3RWxlbWVudCk7CiAgICAvL3d5c2lodG1sNS5kb20uY29weVN0eWxlcyhbImxpbmUtaGVpZ2h0Il0pLmZyb20oZWxlbWVudCkudG8obmV3RWxlbWVudCk7CiAgICBlbGVtZW50LnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG5ld0VsZW1lbnQsIGVsZW1lbnQpOwogICAgcmV0dXJuIG5ld0VsZW1lbnQ7Cn07Ci8qKgogKiBUYWtlcyBhbiBlbGVtZW50LCByZW1vdmVzIGl0IGFuZCByZXBsYWNlcyBpdCB3aXRoIGl0J3MgY2hpbGRzCiAqCiAqIEBwYXJhbSB7T2JqZWN0fSBub2RlIFRoZSBub2RlIHdoaWNoIHRvIHJlcGxhY2Ugd2l0aCBpdCdzIGNoaWxkIG5vZGVzCiAqIEBleGFtcGxlCiAqICAgIDxkaXYgaWQ9ImZvbyI+CiAqICAgICAgPHNwYW4+aGVsbG88L3NwYW4+CiAqICAgIDwvZGl2PgogKiAgICA8c2NyaXB0PgogKiAgICAgIC8vIFJlbW92ZSAjZm9vIGFuZCByZXBsYWNlIHdpdGggaXQncyBjaGlsZHJlbgogKiAgICAgIHd5c2lodG1sNS5kb20ucmVwbGFjZVdpdGhDaGlsZE5vZGVzKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJmb28iKSk7CiAqICAgIDwvc2NyaXB0PgogKi8Kd3lzaWh0bWw1LmRvbS5yZXBsYWNlV2l0aENoaWxkTm9kZXMgPSBmdW5jdGlvbiAobm9kZSkgewogICAgaWYgKCFub2RlLnBhcmVudE5vZGUpIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCFub2RlLmZpcnN0Q2hpbGQpIHsKICAgICAgICBub2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIHZhciBmcmFnbWVudCA9IG5vZGUub3duZXJEb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7CiAgICB3aGlsZSAobm9kZS5maXJzdENoaWxkKSB7CiAgICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQobm9kZS5maXJzdENoaWxkKTsKICAgIH0KICAgIG5vZGUucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoZnJhZ21lbnQsIG5vZGUpOwogICAgbm9kZSA9IGZyYWdtZW50ID0gbnVsbDsKfTsKLyoqCiAqIFVud3JhcHMgYW4gdW5vcmRlcmVkL29yZGVyZWQgbGlzdAogKgogKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnQgVGhlIGxpc3QgZWxlbWVudCB3aGljaCBzaG91bGQgYmUgdW53cmFwcGVkCiAqCiAqIEBleGFtcGxlCiAqICAgIDwhLS0gQXNzdW1lIHRoZSBmb2xsb3dpbmcgZG9tOiAtLT4KICogICAgPHVsIGlkPSJsaXN0Ij4KICogICAgICA8bGk+ZW1pbmVtPC9saT4KICogICAgICA8bGk+ZHIuIGRyZTwvbGk+CiAqICAgICAgPGxpPjUwIENlbnQ8L2xpPgogKiAgICA8L3VsPgogKgogKiAgICA8c2NyaXB0PgogKiAgICAgIHd5c2lodG1sNS5kb20ucmVzb2x2ZUxpc3QoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImxpc3QiKSk7CiAqICAgIDwvc2NyaXB0PgogKgogKiAgICA8IS0tIFdpbGwgcmVzdWx0IGluOiAtLT4KICogICAgZW1pbmVtPGJyPgogKiAgICBkci4gZHJlPGJyPgogKiAgICA1MCBDZW50PGJyPgogKi8KKGZ1bmN0aW9uIChkb20pIHsKICAgIGZ1bmN0aW9uIF9pc0Jsb2NrRWxlbWVudChub2RlKSB7CiAgICAgICAgcmV0dXJuIGRvbS5nZXRTdHlsZSgiZGlzcGxheSIpLmZyb20obm9kZSkgPT09ICJibG9jayI7CiAgICB9CgogICAgZnVuY3Rpb24gX2lzTGluZUJyZWFrKG5vZGUpIHsKICAgICAgICByZXR1cm4gbm9kZS5ub2RlTmFtZSA9PT0gIkJSIjsKICAgIH0KCiAgICBmdW5jdGlvbiBfYXBwZW5kTGluZUJyZWFrKGVsZW1lbnQpIHsKICAgICAgICB2YXIgbGluZUJyZWFrID0gZWxlbWVudC5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImJyIik7CiAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChsaW5lQnJlYWspOwogICAgfQoKICAgIGZ1bmN0aW9uIHJlc29sdmVMaXN0KGxpc3QsIHVzZUxpbmVCcmVha3MpIHsKICAgICAgICBpZiAoIWxpc3Qubm9kZU5hbWUubWF0Y2goL14oTUVOVXxVTHxPTCkkLykpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdmFyIGRvYyA9IGxpc3Qub3duZXJEb2N1bWVudCwKICAgICAgICAgICAgZnJhZ21lbnQgPSBkb2MuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLAogICAgICAgICAgICBwcmV2aW91c1NpYmxpbmcgPSBsaXN0LnByZXZpb3VzRWxlbWVudFNpYmxpbmcgfHwgbGlzdC5wcmV2aW91c1NpYmxpbmcsCiAgICAgICAgICAgIGZpcnN0Q2hpbGQsCiAgICAgICAgICAgIGxhc3RDaGlsZCwKICAgICAgICAgICAgaXNMYXN0Q2hpbGQsCiAgICAgICAgICAgIHNob3VsZEFwcGVuZExpbmVCcmVhaywKICAgICAgICAgICAgcGFyYWdyYXBoLAogICAgICAgICAgICBsaXN0SXRlbTsKCiAgICAgICAgaWYgKHVzZUxpbmVCcmVha3MpIHsKICAgICAgICAgICAgLy8gSW5zZXJ0IGxpbmUgYnJlYWsgaWYgbGlzdCBpcyBhZnRlciBhIG5vbi1ibG9jayBlbGVtZW50CiAgICAgICAgICAgIGlmIChwcmV2aW91c1NpYmxpbmcgJiYgIV9pc0Jsb2NrRWxlbWVudChwcmV2aW91c1NpYmxpbmcpKSB7CiAgICAgICAgICAgICAgICBfYXBwZW5kTGluZUJyZWFrKGZyYWdtZW50KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgd2hpbGUgKGxpc3RJdGVtID0gKGxpc3QuZmlyc3RFbGVtZW50Q2hpbGQgfHwgbGlzdC5maXJzdENoaWxkKSkgewogICAgICAgICAgICAgICAgbGFzdENoaWxkID0gbGlzdEl0ZW0ubGFzdENoaWxkOwogICAgICAgICAgICAgICAgd2hpbGUgKGZpcnN0Q2hpbGQgPSBsaXN0SXRlbS5maXJzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgaXNMYXN0Q2hpbGQgPSBmaXJzdENoaWxkID09PSBsYXN0Q2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBuZWVkcyB0byBiZSBkb25lIGJlZm9yZSBhcHBlbmRpbmcgaXQgdG8gdGhlIGZyYWdtZW50LCBhcyBpdCBvdGhlcndpc2Ugd2lsbCBsb3NlIHN0eWxlIGluZm9ybWF0aW9uCiAgICAgICAgICAgICAgICAgICAgc2hvdWxkQXBwZW5kTGluZUJyZWFrID0gaXNMYXN0Q2hpbGQgJiYgIV9pc0Jsb2NrRWxlbWVudChmaXJzdENoaWxkKSAmJiAhX2lzTGluZUJyZWFrKGZpcnN0Q2hpbGQpOwogICAgICAgICAgICAgICAgICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKGZpcnN0Q2hpbGQpOwogICAgICAgICAgICAgICAgICAgIGlmIChzaG91bGRBcHBlbmRMaW5lQnJlYWspIHsKICAgICAgICAgICAgICAgICAgICAgICAgX2FwcGVuZExpbmVCcmVhayhmcmFnbWVudCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGxpc3RJdGVtLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobGlzdEl0ZW0pOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgd2hpbGUgKGxpc3RJdGVtID0gKGxpc3QuZmlyc3RFbGVtZW50Q2hpbGQgfHwgbGlzdC5maXJzdENoaWxkKSkgewogICAgICAgICAgICAgICAgaWYgKGxpc3RJdGVtLnF1ZXJ5U2VsZWN0b3IgJiYgbGlzdEl0ZW0ucXVlcnlTZWxlY3RvcigiZGl2LCBwLCB1bCwgb2wsIG1lbnUsIGJsb2NrcXVvdGUsIGgxLCBoMiwgaDMsIGg0LCBoNSwgaDYiKSkgewogICAgICAgICAgICAgICAgICAgIHdoaWxlIChmaXJzdENoaWxkID0gbGlzdEl0ZW0uZmlyc3RDaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICBmcmFnbWVudC5hcHBlbmRDaGlsZChmaXJzdENoaWxkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHBhcmFncmFwaCA9IGRvYy5jcmVhdGVFbGVtZW50KCJwIik7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGZpcnN0Q2hpbGQgPSBsaXN0SXRlbS5maXJzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFncmFwaC5hcHBlbmRDaGlsZChmaXJzdENoaWxkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQocGFyYWdyYXBoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGxpc3RJdGVtLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobGlzdEl0ZW0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBsaXN0LnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGZyYWdtZW50LCBsaXN0KTsKICAgIH0KCiAgICBkb20ucmVzb2x2ZUxpc3QgPSByZXNvbHZlTGlzdDsKfSkod3lzaWh0bWw1LmRvbSk7Ci8qKgogKiBTYW5kYm94IGZvciBleGVjdXRpbmcgamF2YXNjcmlwdCwgcGFyc2luZyBjc3Mgc3R5bGVzIGFuZCBkb2luZyBkb20gb3BlcmF0aW9ucyBpbiBhIHNlY3VyZSB3YXkKICoKICogQnJvd3NlciBDb21wYXRpYmlsaXR5OgogKiAgLSBTZWN1cmUgaW4gTVNJRSA2KywgYnV0IG9ubHkgd2hlbiB0aGUgdXNlciBoYXNuJ3QgbWFkZSBjaGFuZ2VzIHRvIGhpcyBzZWN1cml0eSBsZXZlbCAicmVzdHJpY3RlZCIKICogIC0gUGFydGlhbGx5IHNlY3VyZSBpbiBvdGhlciBicm93c2VycyAoRmlyZWZveCwgT3BlcmEsIFNhZmFyaSwgQ2hyb21lLCAuLi4pCiAqCiAqIFBsZWFzZSBub3RlIHRoYXQgdGhpcyBjbGFzcyBjYW4ndCBiZW5lZml0IGZyb20gdGhlIEhUTUw1IHNhbmRib3ggYXR0cmlidXRlIGZvciB0aGUgZm9sbG93aW5nIHJlYXNvbnM6CiAqICAgIC0gc2FuZGJveGluZyBkb2Vzbid0IHdvcmsgY29ycmVjdGx5IHdpdGggaW5saW5lZCBjb250ZW50IChzcmM9ImphdmFzY3JpcHQ6JzxodG1sPi4uLjwvaHRtbD4nIikKICogICAgLSBzYW5kYm94aW5nIG9mIHBoeXNpY2FsIGRvY3VtZW50cyBjYXVzZXMgdGhhdCB0aGUgZG9tIGlzbid0IGFjY2Vzc2libGUgYW55bW9yZSBmcm9tIHRoZSBvdXRzaWRlIChpZnJhbWUuY29udGVudFdpbmRvdywgLi4uKQogKiAgICAtIHNldHRpbmcgdGhlICJhbGxvdy1zYW1lLW9yaWdpbiIgZmxhZyB3b3VsZCBmaXggdGhhdCwgYnV0IHRoZW4gc3RpbGwgamF2YXNjcmlwdCBhbmQgZG9tIGV2ZW50cyByZWZ1c2UgdG8gZmlyZQogKiAgICAtIHRoZXJlZm9yZSB0aGUgImFsbG93LXNjcmlwdHMiIGZsYWcgaXMgbmVlZGVkLCB3aGljaCB0aGVuIHdvdWxkIGRlYWN0aXZhdGUgYW55IHNlY3VyaXR5LCBhcyB0aGUganMgZXhlY3V0ZWQgaW5zaWRlIHRoZSBpZnJhbWUKICogICAgICBjYW4gZG8gYW55dGhpbmcgYXMgaWYgdGhlIHNhbmRib3ggYXR0cmlidXRlIHdhc24ndCBzZXQKICoKICogQHBhcmFtIHtGdW5jdGlvbn0gW3JlYWR5Q2FsbGJhY2tdIE1ldGhvZCB0aGF0IGdldHMgaW52b2tlZCB3aGVuIHRoZSBzYW5kYm94IGlzIHJlYWR5CiAqIEBwYXJhbSB7T2JqZWN0fSBbY29uZmlnXSBPcHRpb25hbCBwYXJhbWV0ZXJzCiAqCiAqIEBleGFtcGxlCiAqICAgIG5ldyB3eXNpaHRtbDUuZG9tLlNhbmRib3goZnVuY3Rpb24oc2FuZGJveCkgewogKiAgICAgIHNhbmRib3guZ2V0V2luZG93KCkuZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPSAnPGltZyBzcmM9Zm9vLmdpZiBvbmVycm9yPSJhbGVydChkb2N1bWVudC5jb29raWUpIj4nOwogKiAgICB9KTsKICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgLyoqCiAgICAgICAgICogRGVmYXVsdCBjb25maWd1cmF0aW9uCiAgICAgICAgICovCiAgICAgICAgZG9jID0gZG9jdW1lbnQsCiAgICAgICAgLyoqCiAgICAgICAgICogUHJvcGVydGllcyB0byB1bnNldC9wcm90ZWN0IG9uIHRoZSB3aW5kb3cgb2JqZWN0CiAgICAgICAgICovCiAgICAgICAgd2luZG93UHJvcGVydGllcyA9IFsKICAgICAgICAgICAgInBhcmVudCIsICJ0b3AiLCAib3BlbmVyIiwgImZyYW1lRWxlbWVudCIsICJmcmFtZXMiLAogICAgICAgICAgICAibG9jYWxTdG9yYWdlIiwgImdsb2JhbFN0b3JhZ2UiLCAic2Vzc2lvblN0b3JhZ2UiLCAiaW5kZXhlZERCIgogICAgICAgIF0sCiAgICAgICAgLyoqCiAgICAgICAgICogUHJvcGVydGllcyBvbiB0aGUgd2luZG93IG9iamVjdCB3aGljaCBhcmUgc2V0IHRvIGFuIGVtcHR5IGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgd2luZG93UHJvcGVydGllczIgPSBbCiAgICAgICAgICAgICJvcGVuIiwgImNsb3NlIiwgIm9wZW5EaWFsb2ciLCAic2hvd01vZGFsRGlhbG9nIiwKICAgICAgICAgICAgImFsZXJ0IiwgImNvbmZpcm0iLCAicHJvbXB0IiwKICAgICAgICAgICAgIm9wZW5EYXRhYmFzZSIsICJwb3N0TWVzc2FnZSIsCiAgICAgICAgICAgICJYTUxIdHRwUmVxdWVzdCIsICJYRG9tYWluUmVxdWVzdCIKICAgICAgICBdLAogICAgICAgIC8qKgogICAgICAgICAqIFByb3BlcnRpZXMgdG8gdW5zZXQvcHJvdGVjdCBvbiB0aGUgZG9jdW1lbnQgb2JqZWN0CiAgICAgICAgICovCiAgICAgICAgZG9jdW1lbnRQcm9wZXJ0aWVzID0gWwogICAgICAgICAgICAicmVmZXJyZXIiLAogICAgICAgICAgICAid3JpdGUiLCAib3BlbiIsICJjbG9zZSIKICAgICAgICBdOwoKICAgIHd5c2lodG1sNS5kb20uU2FuZGJveCA9IEJhc2UuZXh0ZW5kKAogICAgICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LmRvbS5TYW5kYm94LnByb3RvdHlwZSAqLyB7CgogICAgICAgICAgICBjb25zdHJ1Y3RvciA6IGZ1bmN0aW9uIChjb25maWcpIHsKICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnID0gd3lzaWh0bWw1Lmxhbmcub2JqZWN0KHt9KS5tZXJnZShjb25maWcpLmdldCgpOwogICAgICAgICAgICAgICAgdGhpcy5jb250YWluZXIgPSB0aGlzLl9jcmVhdGVDb250YWluZXIoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGluc2VydEludG8gOiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICAgICAgaWYgKHR5cGVvZihlbGVtZW50KSA9PT0gInN0cmluZyIpIHsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gZG9jLmdldEVsZW1lbnRCeUlkKGVsZW1lbnQpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5jb250YWluZXIpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZ2V0Q29udGFpbmVyIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGFpbmVyOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZ2V0V2luZG93IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhpcy5fcmVhZHlFcnJvcigpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZ2V0RG9jdW1lbnQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9yZWFkeUVycm9yKCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBkZXN0cm95IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuZ2V0Q29udGFpbmVyKCk7CiAgICAgICAgICAgICAgICBpZiAoY29udGFpbmVyICYmIGNvbnRhaW5lci5wYXJlbnROb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY29udGFpbmVyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9yZWFkeUVycm9yIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJ3eXNpaHRtbDUuU2FuZGJveDogU2FuZGJveCBjb250YWluZXIgaXNuJ3QgbG9hZGVkIHlldCIpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENyZWF0ZXMgdGhlIHNhbmRib3ggY29udGFpbmVyCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFNvbWUgaW1wb3J0YW50IG5vdGVzOgogICAgICAgICAgICAgKiAgLSBXZSBjYW4ndCB1c2UgSFRNTDUgc2FuZGJveCBmb3Igbm93OgogICAgICAgICAgICAgKiAgICBzZXR0aW5nIGl0IGNhdXNlcyB0aGF0IHRoZSBpZnJhbWUncyBkb20gY2FuJ3QgYmUgYWNjZXNzZWQgZnJvbSB0aGUgb3V0c2lkZQogICAgICAgICAgICAgKiAgICBUaGVyZWZvcmUgd2UgbmVlZCB0byBzZXQgdGhlICJhbGxvdy1zYW1lLW9yaWdpbiIgZmxhZyB3aGljaCBlbmFibGVzIGFjY2Vzc2luZyB0aGUgaWZyYW1lJ3MgZG9tCiAgICAgICAgICAgICAqICAgIEJ1dCB0aGVuIHRoZXJlJ3MgYW5vdGhlciBwcm9ibGVtLCBET00gZXZlbnRzIChmb2N1cywgYmx1ciwgY2hhbmdlLCBrZXlwcmVzcywgLi4uKSBhcmVuJ3QgZmlyZWQuCiAgICAgICAgICAgICAqICAgIEluIG9yZGVyIHRvIG1ha2UgdGhpcyBoYXBwZW4gd2UgbmVlZCB0byBzZXQgdGhlICJhbGxvdy1zY3JpcHRzIiBmbGFnLgogICAgICAgICAgICAgKiAgICBBIGNvbWJpbmF0aW9uIG9mIGFsbG93LXNjcmlwdHMgYW5kIGFsbG93LXNhbWUtb3JpZ2luIGlzIGFsbW9zdCB0aGUgc2FtZSBhcyBzZXR0aW5nIG5vIHNhbmRib3ggYXR0cmlidXRlIGF0IGFsbC4KICAgICAgICAgICAgICogIC0gQ2hyb21lICYgU2FmYXJpLCBkb2Vzbid0IHNlZW0gdG8gc3VwcG9ydCBzYW5kYm94aW5nIGNvcnJlY3RseSB3aGVuIHRoZSBpZnJhbWUncyBodG1sIGlzIGlubGluZWQgKG5vIHBoeXNpY2FsIGRvY3VtZW50KQogICAgICAgICAgICAgKiAgLSBJRSBuZWVkcyB0byBoYXZlIHRoZSBzZWN1cml0eT0icmVzdHJpY3RlZCIgYXR0cmlidXRlIHNldCBiZWZvcmUgdGhlIGlmcmFtZSBpcwogICAgICAgICAgICAgKiAgICBpbnNlcnRlZCBpbnRvIHRoZSBkb20gdHJlZQogICAgICAgICAgICAgKiAgLSBCZWxpZXZlIGl0IG9yIG5vdCBidXQgaW4gSUUgInNlY3VyaXR5IiBpbiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJpZnJhbWUiKSBpcyBmYWxzZSwgZXZlbgogICAgICAgICAgICAgKiAgICB0aG91Z2ggaXQgc3VwcG9ydHMgaXQKICAgICAgICAgICAgICogIC0gV2hlbiBhbiBpZnJhbWUgaGFzIHNlY3VyaXR5PSJyZXN0cmljdGVkIiwgaW4gSUUgZXZhbCgpICYgZXhlY1NjcmlwdCgpIGRvbid0IHdvcmsgYW55bW9yZQogICAgICAgICAgICAgKiAgLSBJRSBkb2Vzbid0IGZpcmUgdGhlIG9ubG9hZCBldmVudCB3aGVuIHRoZSBjb250ZW50IGlzIGlubGluZWQgaW4gdGhlIHNyYyBhdHRyaWJ1dGUsIHRoZXJlZm9yZSB3ZSByZWx5CiAgICAgICAgICAgICAqICAgIG9uIHRoZSBvbnJlYWR5c3RhdGVjaGFuZ2UgZXZlbnQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIF9jcmVhdGVDb250YWluZXIgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgY29udGFpbmVyID0gZG9jLmNyZWF0ZUVsZW1lbnQoImRpdiIpOwogICAgICAgICAgICAgICAgdGhpcy5nZXRXaW5kb3cgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGRvYyA9IHRoaXMuZ2V0RG9jdW1lbnQoKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZG9jLmRlZmF1bHRWaWV3IHx8IGRvYy5wYXJlbnRXaW5kb3c7CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgdGhpcy5nZXREb2N1bWVudCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udGFpbmVyLm93bmVyRG9jdW1lbnQ7CiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIHJldHVybiBjb250YWluZXI7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfZ2V0SHRtbCA6IGZ1bmN0aW9uICh0ZW1wbGF0ZVZhcnMpIHsKICAgICAgICAgICAgICAgIHZhciBzdHlsZXNoZWV0cyA9IHRlbXBsYXRlVmFycy5zdHlsZXNoZWV0cywKICAgICAgICAgICAgICAgICAgICBodG1sID0gIiIsCiAgICAgICAgICAgICAgICAgICAgaSA9IDAsCiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoOwogICAgICAgICAgICAgICAgc3R5bGVzaGVldHMgPSB0eXBlb2Yoc3R5bGVzaGVldHMpID09PSAic3RyaW5nIiA/IFtzdHlsZXNoZWV0c10gOiBzdHlsZXNoZWV0czsKICAgICAgICAgICAgICAgIGlmIChzdHlsZXNoZWV0cykgewogICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IHN0eWxlc2hlZXRzLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGh0bWwgKz0gJzxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iJyArIHN0eWxlc2hlZXRzW2ldICsgJyI+JzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0ZW1wbGF0ZVZhcnMuc3R5bGVzaGVldHMgPSBodG1sOwoKICAgICAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUubGFuZy5zdHJpbmcoCiAgICAgICAgICAgICAgICAgICAgJzwhRE9DVFlQRSBodG1sPjxodG1sPjxoZWFkPicgKwogICAgICAgICAgICAgICAgICAgICc8bWV0YSBjaGFyc2V0PSIje2NoYXJzZXR9Ij4je3N0eWxlc2hlZXRzfTwvaGVhZD4nICsKICAgICAgICAgICAgICAgICAgICAnPGJvZHk+PC9ib2R5PjwvaHRtbD4nCiAgICAgICAgICAgICAgICApLmludGVycG9sYXRlKHRlbXBsYXRlVmFycyk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogTWV0aG9kIHRvIHVuc2V0L292ZXJyaWRlIGV4aXN0aW5nIHZhcmlhYmxlcwogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKiAgICAvLyBNYWtlIGNvb2tpZSB1bnJlYWRhYmxlIGFuZCB1bndyaXRhYmxlCiAgICAgICAgICAgICAqICAgIHRoaXMuX3Vuc2V0KGRvY3VtZW50LCAiY29va2llIiwgIiIsIHRydWUpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgX3Vuc2V0IDogZnVuY3Rpb24gKG9iamVjdCwgcHJvcGVydHksIHZhbHVlLCBzZXR0ZXIpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgb2JqZWN0W3Byb3BlcnR5XSA9IHZhbHVlOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgb2JqZWN0Ll9fZGVmaW5lR2V0dGVyX18ocHJvcGVydHksIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHNldHRlcikgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5fX2RlZmluZVNldHRlcl9fKHByb3BlcnR5LCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCF3eXNpaHRtbDUuYnJvd3Nlci5jcmFzaGVzV2hlbkRlZmluZVByb3BlcnR5KHByb3BlcnR5KSkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb25maWcgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2V0dGVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcuc2V0ID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wZXJ0eSwgY29uZmlnKTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAoKSB7CiAgICB2YXIgbWFwcGluZyA9IHsKICAgICAgICAiY2xhc3NOYW1lIiA6ICJjbGFzcyIKICAgIH07CiAgICB3eXNpaHRtbDUuZG9tLnNldEF0dHJpYnV0ZXMgPSBmdW5jdGlvbiAoYXR0cmlidXRlcykgewogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIG9uIDogZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKG1hcHBpbmdbaV0gfHwgaSwgYXR0cmlidXRlc1tpXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfTsKfSkoKTsKd3lzaWh0bWw1LmRvbS5zZXRTdHlsZXMgPSBmdW5jdGlvbiAoc3R5bGVzKSB7CiAgICByZXR1cm4gewogICAgICAgIG9uIDogZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgICAgICAgICAgdmFyIHN0eWxlID0gZWxlbWVudC5zdHlsZTsKICAgICAgICAgICAgaWYgKHR5cGVvZihzdHlsZXMpID09PSAic3RyaW5nIikgewogICAgICAgICAgICAgICAgc3R5bGUuY3NzVGV4dCArPSAiOyIgKyBzdHlsZXM7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBzdHlsZXMpIHsKICAgICAgICAgICAgICAgIGlmIChpID09PSAiZmxvYXQiKSB7CiAgICAgICAgICAgICAgICAgICAgc3R5bGUuY3NzRmxvYXQgPSBzdHlsZXNbaV07CiAgICAgICAgICAgICAgICAgICAgc3R5bGUuc3R5bGVGbG9hdCA9IHN0eWxlc1tpXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc3R5bGVbaV0gPSBzdHlsZXNbaV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Owp9OwovKioKICogU2ltdWxhdGUgSFRNTDUgcGxhY2Vob2xkZXIgYXR0cmlidXRlCiAqCiAqIE5lZWRlZCBzaW5jZQogKiAgICAtIGRpdltjb250ZW50RWRpdGFibGVdIGVsZW1lbnRzIGRvbid0IHN1cHBvcnQgaXQKICogICAgLSBvbGRlciBicm93c2VycyAoc3VjaCBhcyBJRTggYW5kIEZpcmVmb3ggMy42KSBkb24ndCBzdXBwb3J0IGl0IGF0IGFsbAogKgogKiBAcGFyYW0ge09iamVjdH0gcGFyZW50IEluc3RhbmNlIG9mIG1haW4gd3lzaWh0bWw1LkVkaXRvciBjbGFzcwogKiBAcGFyYW0ge0VsZW1lbnR9IHZpZXcgSW5zdGFuY2Ugb2Ygd3lzaWh0bWw1LnZpZXdzLiogY2xhc3MKICogQHBhcmFtIHtTdHJpbmd9IHBsYWNlaG9sZGVyVGV4dAogKgogKiBAZXhhbXBsZQogKiAgICB3eXNpaHRtbC5kb20uc2ltdWxhdGVQbGFjZWhvbGRlcih0aGlzLCBjb21wb3NlciwgIkZvb2JhciIpOwogKi8KKGZ1bmN0aW9uIChkb20pIHsKICAgIGRvbS5zaW11bGF0ZVBsYWNlaG9sZGVyID0gZnVuY3Rpb24gKGVkaXRvciwgdmlldywgcGxhY2Vob2xkZXJUZXh0KSB7CiAgICAgICAgdmFyIENMQVNTX05BTUUgPSAicGxhY2Vob2xkZXIiLAogICAgICAgICAgICB1bnNldCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGlmICh2aWV3Lmhhc1BsYWNlaG9sZGVyU2V0KCkpIHsKICAgICAgICAgICAgICAgICAgICB2aWV3LmNsZWFyKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2aWV3LnBsYWNlaG9sZGVyU2V0ID0gZmFsc2U7CiAgICAgICAgICAgICAgICBkb20ucmVtb3ZlQ2xhc3Modmlldy5lbGVtZW50LCBDTEFTU19OQU1FKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0ID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgaWYgKHZpZXcuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICAgICAgdmlldy5wbGFjZWhvbGRlclNldCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgdmlldy5zZXRWYWx1ZShwbGFjZWhvbGRlclRleHQpOwogICAgICAgICAgICAgICAgICAgIGRvbS5hZGRDbGFzcyh2aWV3LmVsZW1lbnQsIENMQVNTX05BTUUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgICBlZGl0b3IKICAgICAgICAgICAgLm9uKCJzZXRfcGxhY2Vob2xkZXIiLCBzZXQpCiAgICAgICAgICAgIC5vbigidW5zZXRfcGxhY2Vob2xkZXIiLCB1bnNldCkKICAgICAgICAgICAgLm9uKCJmb2N1czpjb21wb3NlciIsIHVuc2V0KQogICAgICAgICAgICAub24oImNsaWNrOmNvbXBvc2VyIiwgdW5zZXQpCiAgICAgICAgICAgIC5vbigicGFzdGU6Y29tcG9zZXIiLCB1bnNldCkKICAgICAgICAgICAgLm9uKCJibHVyOmNvbXBvc2VyIiwgc2V0KTsKCiAgICAgICAgc2V0KCk7CiAgICB9Owp9KSh3eXNpaHRtbDUuZG9tKTsKKGZ1bmN0aW9uIChkb20pIHsKICAgIHZhciBkb2N1bWVudEVsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7CiAgICBpZiAoInRleHRDb250ZW50IiBpbiBkb2N1bWVudEVsZW1lbnQpIHsKICAgICAgICBkb20uc2V0VGV4dENvbnRlbnQgPSBmdW5jdGlvbiAoZWxlbWVudCwgdGV4dCkgewogICAgICAgICAgICBlbGVtZW50LnRleHRDb250ZW50ID0gdGV4dDsKICAgICAgICB9OwoKICAgICAgICBkb20uZ2V0VGV4dENvbnRlbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICByZXR1cm4gZWxlbWVudC50ZXh0Q29udGVudDsKICAgICAgICB9OwogICAgfSBlbHNlIGlmICgiaW5uZXJUZXh0IiBpbiBkb2N1bWVudEVsZW1lbnQpIHsKICAgICAgICBkb20uc2V0VGV4dENvbnRlbnQgPSBmdW5jdGlvbiAoZWxlbWVudCwgdGV4dCkgewogICAgICAgICAgICBlbGVtZW50LmlubmVyVGV4dCA9IHRleHQ7CiAgICAgICAgfTsKCiAgICAgICAgZG9tLmdldFRleHRDb250ZW50ID0gZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQuaW5uZXJUZXh0OwogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIGRvbS5zZXRUZXh0Q29udGVudCA9IGZ1bmN0aW9uIChlbGVtZW50LCB0ZXh0KSB7CiAgICAgICAgICAgIGVsZW1lbnQubm9kZVZhbHVlID0gdGV4dDsKICAgICAgICB9OwoKICAgICAgICBkb20uZ2V0VGV4dENvbnRlbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICByZXR1cm4gZWxlbWVudC5ub2RlVmFsdWU7CiAgICAgICAgfTsKICAgIH0KfSkod3lzaWh0bWw1LmRvbSk7CgovKioKICogRml4IG1vc3QgY29tbW9uIGh0bWwgZm9ybWF0dGluZyBtaXNiZWhhdmlvcnMgb2YgYnJvd3NlcnMgaW1wbGVtZW50YXRpb24gd2hlbiBpbnNlcnRpbmcKICogY29udGVudCB2aWEgY29weSAmIHBhc3RlIGNvbnRlbnRFZGl0YWJsZQogKgogKiBAYXV0aG9yIENocmlzdG9waGVyIEJsdW0KICovCnd5c2lodG1sNS5xdWlya3MuY2xlYW5QYXN0ZWRIVE1MID0gKGZ1bmN0aW9uICgpIHsKICAgIC8vIFRPRE86IFdlIHByb2JhYmx5IG5lZWQgbW9yZSBydWxlcyBoZXJlCiAgICB2YXIgZGVmYXVsdFJ1bGVzID0gewogICAgICAgIC8vIFdoZW4gcGFzdGluZyB1bmRlcmxpbmVkIGxpbmtzIDxhPiBpbnRvIGEgY29udGVudEVkaXRhYmxlLCBJRSB0aGlua3MsIGl0IGhhcyB0byBpbnNlcnQgPHU+IHRvIGtlZXAgdGhlIHN0eWxpbmcKICAgICAgICAiYSB1IiA6IHd5c2lodG1sNS5kb20ucmVwbGFjZVdpdGhDaGlsZE5vZGVzCiAgICB9OwoKICAgIGZ1bmN0aW9uIGNsZWFuUGFzdGVkSFRNTChlbGVtZW50T3JIdG1sLCBydWxlcywgY29udGV4dCkgewogICAgICAgIHJ1bGVzID0gcnVsZXMgfHwgZGVmYXVsdFJ1bGVzOwogICAgICAgIGNvbnRleHQgPSBjb250ZXh0IHx8IGVsZW1lbnRPckh0bWwub3duZXJEb2N1bWVudCB8fCBkb2N1bWVudDsKCiAgICAgICAgdmFyIGVsZW1lbnQsCiAgICAgICAgICAgIGlzU3RyaW5nID0gdHlwZW9mKGVsZW1lbnRPckh0bWwpID09PSAic3RyaW5nIiwKICAgICAgICAgICAgbWV0aG9kLAogICAgICAgICAgICBtYXRjaGVzLAogICAgICAgICAgICBtYXRjaGVzTGVuZ3RoLAogICAgICAgICAgICBpLAogICAgICAgICAgICBqID0gMDsKICAgICAgICBpZiAoaXNTdHJpbmcpIHsKICAgICAgICAgICAgZWxlbWVudCA9IHd5c2lodG1sNS5kb20uZ2V0QXNEb20oZWxlbWVudE9ySHRtbCwgY29udGV4dCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnRPckh0bWw7CiAgICAgICAgfQoKICAgICAgICBmb3IgKGkgaW4gcnVsZXMpIHsKICAgICAgICAgICAgbWF0Y2hlcyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChpKTsKICAgICAgICAgICAgbWV0aG9kID0gcnVsZXNbaV07CiAgICAgICAgICAgIG1hdGNoZXNMZW5ndGggPSBtYXRjaGVzLmxlbmd0aDsKICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICBqIDwgbWF0Y2hlc0xlbmd0aDsKICAgICAgICAgICAgICAgIGorKykgewogICAgICAgICAgICAgICAgbWV0aG9kKG1hdGNoZXNbal0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBtYXRjaGVzID0gZWxlbWVudE9ySHRtbCA9IHJ1bGVzID0gbnVsbDsKCiAgICAgICAgcmV0dXJuIGlzU3RyaW5nID8gZWxlbWVudC5pbm5lckhUTUwgOiBlbGVtZW50OwogICAgfQoKICAgIHJldHVybiBjbGVhblBhc3RlZEhUTUw7Cn0pKCk7Ci8qKgogKiBJRSBhbmQgT3BlcmEgbGVhdmUgYW4gZW1wdHkgcGFyYWdyYXBoIGluIHRoZSBjb250ZW50RWRpdGFibGUgZWxlbWVudCBhZnRlciBjbGVhcmluZyBpdAogKgogKiBAcGFyYW0ge09iamVjdH0gY29udGVudEVkaXRhYmxlRWxlbWVudCBUaGUgY29udGVudEVkaXRhYmxlIGVsZW1lbnQgdG8gb2JzZXJ2ZSBmb3IgY2xlYXJpbmcgZXZlbnRzCiAqIEBleGFwbGUKICogICAgd3lzaWh0bWw1LnF1aXJrcy5lbnN1cmVQcm9wZXJDbGVhcmluZyhteUNvbnRlbnRFZGl0YWJsZUVsZW1lbnQpOwogKi8Kd3lzaWh0bWw1LnF1aXJrcy5lbnN1cmVQcm9wZXJDbGVhcmluZyA9IChmdW5jdGlvbiAoKSB7CiAgICB2YXIgY2xlYXJJZk5lY2Vzc2FyeSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgZWxlbWVudCA9IHRoaXM7CiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBpbm5lckhUTUwgPSBlbGVtZW50LmlubmVySFRNTC50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICBpZiAoaW5uZXJIVE1MID09ICI8cD4mbmJzcDs8L3A+IiB8fAogICAgICAgICAgICAgICAgaW5uZXJIVE1MID09ICI8cD4mbmJzcDs8L3A+PHA+Jm5ic3A7PC9wPiIpIHsKICAgICAgICAgICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9LCAwKTsKICAgIH07CgogICAgcmV0dXJuIGZ1bmN0aW9uIChjb21wb3NlcikgewogICAgICAgIHd5c2lodG1sNS5kb20ub2JzZXJ2ZShjb21wb3Nlci5lbGVtZW50LCBbImN1dCIsICJrZXlkb3duIl0sIGNsZWFySWZOZWNlc3NhcnkpOwogICAgfTsKfSkoKTsKLy8gU2VlIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY2NDM5OAovLwovLyBJbiBGaXJlZm94IHRoaXM6Ci8vICAgICAgdmFyIGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKTsKLy8gICAgICBkLmlubmVySFRNTCA9JzxhIGhyZWY9In4iPjwvYT4nOwovLyAgICAgIGQuaW5uZXJIVE1MOwovLyB3aWxsIHJlc3VsdCBpbjoKLy8gICAgICA8YSBocmVmPSIlN0UiPjwvYT4KLy8gd2hpY2ggaXMgd3JvbmcKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBUSUxERV9FU0NBUEVEID0gIiU3RSI7CiAgICB3eXNpaHRtbDUucXVpcmtzLmdldENvcnJlY3RJbm5lckhUTUwgPSBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgIHZhciBpbm5lckhUTUwgPSBlbGVtZW50LmlubmVySFRNTDsKICAgICAgICBpZiAoaW5uZXJIVE1MLmluZGV4T2YoVElMREVfRVNDQVBFRCkgPT09IC0xKSB7CiAgICAgICAgICAgIHJldHVybiBpbm5lckhUTUwudHJpbSgpOwogICAgICAgIH0KCiAgICAgICAgdmFyIGVsZW1lbnRzV2l0aFRpbGRlID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCJbaHJlZio9J34nXSwgW3NyYyo9J34nXSIpLAogICAgICAgICAgICB1cmwsCiAgICAgICAgICAgIHVybFRvU2VhcmNoLAogICAgICAgICAgICBsZW5ndGgsCiAgICAgICAgICAgIGk7CiAgICAgICAgZm9yIChpID0gMCwgbGVuZ3RoID0gZWxlbWVudHNXaXRoVGlsZGUubGVuZ3RoOwogICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICB1cmwgPSBlbGVtZW50c1dpdGhUaWxkZVtpXS5ocmVmIHx8IGVsZW1lbnRzV2l0aFRpbGRlW2ldLnNyYzsKICAgICAgICAgICAgdXJsVG9TZWFyY2ggPSB3eXNpaHRtbDUubGFuZy5zdHJpbmcodXJsKS5yZXBsYWNlKCJ+IikuYnkoVElMREVfRVNDQVBFRCk7CiAgICAgICAgICAgIGlubmVySFRNTCA9IHd5c2lodG1sNS5sYW5nLnN0cmluZyhpbm5lckhUTUwpLnJlcGxhY2UodXJsVG9TZWFyY2gpLmJ5KHVybCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbm5lckhUTUw7CiAgICB9Owp9KSh3eXNpaHRtbDUpOwovKioKICogRm9yY2UgcmVyZW5kZXJpbmcgb2YgYSBnaXZlbiBlbGVtZW50CiAqIE5lZWRlZCB0byBmaXggZGlzcGxheSBtaXNiZWhhdmlvcnMgb2YgSUUKICoKICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50IFRoZSBlbGVtZW50IG9iamVjdCB3aGljaCBuZWVkcyB0byBiZSByZXJlbmRlcmVkCiAqIEBleGFtcGxlCiAqICAgIHd5c2lodG1sNS5xdWlya3MucmVkcmF3KGRvY3VtZW50LmJvZHkpOwogKi8KKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBDTEFTU19OQU1FID0gInd5c2lodG1sNS1xdWlya3MtcmVkcmF3IjsKCiAgICB3eXNpaHRtbDUucXVpcmtzLnJlZHJhdyA9IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgICAgd3lzaWh0bWw1LmRvbS5hZGRDbGFzcyhlbGVtZW50LCBDTEFTU19OQU1FKTsKICAgICAgICB3eXNpaHRtbDUuZG9tLnJlbW92ZUNsYXNzKGVsZW1lbnQsIENMQVNTX05BTUUpOwoKICAgICAgICAvLyBGb2xsb3dpbmcgaGFjayBpcyBuZWVkZWQgZm9yIGZpcmVmb3ggdG8gbWFrZSBzdXJlIHRoYXQgaW1hZ2UgcmVzaXplIGhhbmRsZXMgYXJlIHByb3Blcmx5IHJlbW92ZWQKICAgICAgICB0cnkgewogICAgICAgICAgICB2YXIgZG9jID0gZWxlbWVudC5vd25lckRvY3VtZW50OwogICAgICAgICAgICBkb2MuZXhlY0NvbW1hbmQoIml0YWxpYyIsIGZhbHNlLCBudWxsKTsKICAgICAgICAgICAgZG9jLmV4ZWNDb21tYW5kKCJpdGFsaWMiLCBmYWxzZSwgbnVsbCk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBTZWxlY3Rpb24gQVBJCiAqCiAqIEBleGFtcGxlCiAqICAgIHZhciBzZWxlY3Rpb24gPSBuZXcgd3lzaWh0bWw1LlNlbGVjdGlvbihlZGl0b3IpOwogKi8KKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBkb20gPSB3eXNpaHRtbDUuZG9tOwoKICAgIGZ1bmN0aW9uIF9nZXRDdW11bGF0aXZlT2Zmc2V0VG9wKGVsZW1lbnQpIHsKICAgICAgICB2YXIgdG9wID0gMDsKICAgICAgICBpZiAoZWxlbWVudC5wYXJlbnROb2RlKSB7CiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIHRvcCArPSBlbGVtZW50Lm9mZnNldFRvcCB8fCAwOwogICAgICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQub2Zmc2V0UGFyZW50OwogICAgICAgICAgICB9IHdoaWxlIChlbGVtZW50KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRvcDsKICAgIH0KCiAgICB3eXNpaHRtbDUuU2VsZWN0aW9uID0gQmFzZS5leHRlbmQoCiAgICAgICAgLyoqIEBzY29wZSB3eXNpaHRtbDUuU2VsZWN0aW9uLnByb3RvdHlwZSAqLyB7CiAgICAgICAgICAgIGNvbnN0cnVjdG9yIDogZnVuY3Rpb24gKGVkaXRvcikgewogICAgICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgb3VyIGV4dGVybmFsIHJhbmdlIGxpYnJhcnkgaXMgaW5pdGlhbGl6ZWQKICAgICAgICAgICAgICAgIHdpbmRvdy5yYW5neS5pbml0KCk7CgogICAgICAgICAgICAgICAgdGhpcy5lZGl0b3IgPSBlZGl0b3I7CiAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyID0gZWRpdG9yLmNvbXBvc2VyOwogICAgICAgICAgICAgICAgdGhpcy5kb2MgPSB0aGlzLmNvbXBvc2VyLmRvYzsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBHZXQgdGhlIGN1cnJlbnQgc2VsZWN0aW9uIGFzIGEgYm9va21hcmsgdG8gYmUgYWJsZSB0byBsYXRlciByZXN0b3JlIGl0CiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gQW4gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBzZWxlY3Rpb24KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGdldEJvb2ttYXJrIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gdGhpcy5nZXRSYW5nZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIHJhbmdlICYmIHJhbmdlLmNsb25lUmFuZ2UoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBSZXN0b3JlIGEgc2VsZWN0aW9uIHJldHJpZXZlZCB2aWEgd3lzaWh0bWw1LlNlbGVjdGlvbi5wcm90b3R5cGUuZ2V0Qm9va21hcmsKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGJvb2ttYXJrIEFuIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgc2VsZWN0aW9uCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzZXRCb29rbWFyayA6IGZ1bmN0aW9uIChib29rbWFyaykgewogICAgICAgICAgICAgICAgaWYgKCFib29rbWFyaykgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLnNldFNlbGVjdGlvbihib29rbWFyayk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU2V0IHRoZSBjYXJldCBpbiBmcm9udCBvZiB0aGUgZ2l2ZW4gbm9kZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gbm9kZSBUaGUgZWxlbWVudCBvciB0ZXh0IG5vZGUgd2hlcmUgdG8gcG9zaXRpb24gdGhlIGNhcmV0IGluIGZyb250IG9mCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHNlbGVjdGlvbi5zZXRCZWZvcmUobXlFbGVtZW50KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNldEJlZm9yZSA6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICB2YXIgcmFuZ2UgPSByYW5neS5jcmVhdGVSYW5nZSh0aGlzLmRvYyk7CiAgICAgICAgICAgICAgICByYW5nZS5zZXRTdGFydEJlZm9yZShub2RlKTsKICAgICAgICAgICAgICAgIHJhbmdlLnNldEVuZEJlZm9yZShub2RlKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNldFNlbGVjdGlvbihyYW5nZSk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU2V0IHRoZSBjYXJldCBhZnRlciB0aGUgZ2l2ZW4gbm9kZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gbm9kZSBUaGUgZWxlbWVudCBvciB0ZXh0IG5vZGUgd2hlcmUgdG8gcG9zaXRpb24gdGhlIGNhcmV0IGluIGZyb250IG9mCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHNlbGVjdGlvbi5zZXRCZWZvcmUobXlFbGVtZW50KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNldEFmdGVyIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgICAgIHZhciByYW5nZSA9IHJhbmd5LmNyZWF0ZVJhbmdlKHRoaXMuZG9jKTsKICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobm9kZSk7CiAgICAgICAgICAgICAgICByYW5nZS5zZXRFbmRBZnRlcihub2RlKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNldFNlbGVjdGlvbihyYW5nZSk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQWJpbGl0eSB0byBzZWxlY3QvbWFyayBub2RlcwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IG5vZGUgVGhlIG5vZGUvZWxlbWVudCB0byBzZWxlY3QKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICogICAgc2VsZWN0aW9uLnNlbGVjdE5vZGUoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm15LWltYWdlIikpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2VsZWN0Tm9kZSA6IGZ1bmN0aW9uIChub2RlLCBhdm9pZEludmlzaWJsZVNwYWNlKSB7CiAgICAgICAgICAgICAgICB2YXIgcmFuZ2UgPSByYW5neS5jcmVhdGVSYW5nZSh0aGlzLmRvYyksCiAgICAgICAgICAgICAgICAgICAgaXNFbGVtZW50ID0gbm9kZS5ub2RlVHlwZSA9PT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERSwKICAgICAgICAgICAgICAgICAgICBjYW5IYXZlSFRNTCA9ICJjYW5IYXZlSFRNTCIgaW4gbm9kZSA/IG5vZGUuY2FuSGF2ZUhUTUwgOiAobm9kZS5ub2RlTmFtZSAhPT0gIklNRyIpLAogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBpc0VsZW1lbnQgPyBub2RlLmlubmVySFRNTCA6IG5vZGUuZGF0YSwKICAgICAgICAgICAgICAgICAgICBpc0VtcHR5ID0gKGNvbnRlbnQgPT09ICIiIHx8IGNvbnRlbnQgPT09IHd5c2lodG1sNS5JTlZJU0lCTEVfU1BBQ0UpLAogICAgICAgICAgICAgICAgICAgIGRpc3BsYXlTdHlsZSA9IGRvbS5nZXRTdHlsZSgiZGlzcGxheSIpLmZyb20obm9kZSksCiAgICAgICAgICAgICAgICAgICAgaXNCbG9ja0VsZW1lbnQgPSAoZGlzcGxheVN0eWxlID09PSAiYmxvY2siIHx8IGRpc3BsYXlTdHlsZSA9PT0gImxpc3QtaXRlbSIpOwoKICAgICAgICAgICAgICAgIGlmIChpc0VtcHR5ICYmIGlzRWxlbWVudCAmJiBjYW5IYXZlSFRNTCAmJiAhYXZvaWRJbnZpc2libGVTcGFjZSkgewogICAgICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IGNhcmV0IGlzIHZpc2libGUgaW4gbm9kZSBieSBpbnNlcnRpbmcgYSB6ZXJvIHdpZHRoIG5vIGJyZWFraW5nIHNwYWNlCiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5pbm5lckhUTUwgPSB3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFOwogICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGNhbkhhdmVIVE1MKSB7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKG5vZGUpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByYW5nZS5zZWxlY3ROb2RlKG5vZGUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChjYW5IYXZlSFRNTCAmJiBpc0VtcHR5ICYmIGlzRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgIHJhbmdlLmNvbGxhcHNlKGlzQmxvY2tFbGVtZW50KTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2FuSGF2ZUhUTUwgJiYgaXNFbXB0eSkgewogICAgICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2Uuc2V0RW5kQWZ0ZXIobm9kZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5zZXRTZWxlY3Rpb24ocmFuZ2UpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEdldCB0aGUgbm9kZSB3aGljaCBjb250YWlucyB0aGUgc2VsZWN0aW9uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gW2NvbnRyb2xSYW5nZV0gKG9ubHkgSUUpIFdoZXRoZXIgaXQgc2hvdWxkIHJldHVybiB0aGUgc2VsZWN0ZWQgQ29udHJvbFJhbmdlIGVsZW1lbnQgd2hlbiB0aGUgc2VsZWN0aW9uIHR5cGUgaXMgYSAiQ29udHJvbFJhbmdlIgogICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBub2RlIHRoYXQgY29udGFpbnMgdGhlIGNhcmV0CiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHZhciBub2RlVGhhdENvbnRhaW5zQ2FyZXQgPSBzZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKCk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBnZXRTZWxlY3RlZE5vZGUgOiBmdW5jdGlvbiAoY29udHJvbFJhbmdlLCBleGNsdWRlRWRpdG9yQ29udGFpbmVyKSB7CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0aW9uLAogICAgICAgICAgICAgICAgICAgIHJhbmdlLAogICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IG51bGw7CgogICAgICAgICAgICAgICAgaWYgKGNvbnRyb2xSYW5nZSAmJiB0aGlzLmRvYy5zZWxlY3Rpb24gJiYgdGhpcy5kb2Muc2VsZWN0aW9uLnR5cGUgPT09ICJDb250cm9sIikgewogICAgICAgICAgICAgICAgICAgIHJhbmdlID0gdGhpcy5kb2Muc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJhbmdlICYmIHJhbmdlLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZE5vZGUgPSByYW5nZS5pdGVtKDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBzZWxlY3Rpb24gPSB0aGlzLmdldFNlbGVjdGlvbih0aGlzLmRvYyk7CiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uLmZvY3VzTm9kZSA9PT0gc2VsZWN0aW9uLmFuY2hvck5vZGUpIHsKICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZE5vZGUgPSBzZWxlY3Rpb24uZm9jdXNOb2RlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByYW5nZSA9IHRoaXMuZ2V0UmFuZ2UodGhpcy5kb2MpOwogICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IHJhbmdlID8gcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXIgOiB0aGlzLmVkaXRvci5jb21wb3Nlci5zYW5kYm94LmdldENvbnRhaW5lcigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGV4Y2x1ZGVFZGl0b3JDb250YWluZXIgJiYgd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKHNlbGVjdGVkTm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZE5vZGUgPSBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGVkTm9kZTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGV4ZWN1dGVBbmRSZXN0b3JlIDogZnVuY3Rpb24gKG1ldGhvZCwgcmVzdG9yZVNjcm9sbFBvc2l0aW9uKSB7CiAgICAgICAgICAgICAgICB2YXIgYm9keSA9IHRoaXMuZG9jLmJvZHksCiAgICAgICAgICAgICAgICAgICAgb2xkU2Nyb2xsVG9wID0gcmVzdG9yZVNjcm9sbFBvc2l0aW9uICYmIGJvZHkuc2Nyb2xsVG9wLAogICAgICAgICAgICAgICAgICAgIG9sZFNjcm9sbExlZnQgPSByZXN0b3JlU2Nyb2xsUG9zaXRpb24gJiYgYm9keS5zY3JvbGxMZWZ0LAogICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSA9ICJfd3lzaWh0bWw1LXRlbXAtcGxhY2Vob2xkZXIiLAogICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVySHRtbCA9ICc8c3BhbiBjbGFzcz0iJyArIGNsYXNzTmFtZSArICciPicgKyB3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFICsgJzwvc3Bhbj4nLAogICAgICAgICAgICAgICAgICAgIHJhbmdlID0gdGhpcy5nZXRSYW5nZSh0aGlzLmRvYyksCiAgICAgICAgICAgICAgICAgICAgY2FyZXRQbGFjZWhvbGRlciwKICAgICAgICAgICAgICAgICAgICBuZXdDYXJldFBsYWNlaG9sZGVyLAogICAgICAgICAgICAgICAgICAgIG5leHRTaWJsaW5nLAogICAgICAgICAgICAgICAgICAgIG5vZGUsCiAgICAgICAgICAgICAgICAgICAgbmV3UmFuZ2U7CgogICAgICAgICAgICAgICAgLy8gTm90aGluZyBzZWxlY3RlZCwgZXhlY3V0ZSBhbmQgc2F5IGdvb2RieWUKICAgICAgICAgICAgICAgIGlmICghcmFuZ2UpIHsKICAgICAgICAgICAgICAgICAgICBtZXRob2QoYm9keSwgYm9keSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICh3eXNpaHRtbDUuYnJvd3Nlci5oYXNJbnNlcnROb2RlSXNzdWUoKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZG9jLmV4ZWNDb21tYW5kKCJpbnNlcnRIVE1MIiwgZmFsc2UsIHBsYWNlaG9sZGVySHRtbCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIG5vZGUgPSByYW5nZS5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQocGxhY2Vob2xkZXJIdG1sKTsKICAgICAgICAgICAgICAgICAgICByYW5nZS5pbnNlcnROb2RlKG5vZGUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IGEgcG90ZW50aWFsIGVycm9yIGRvZXNuJ3QgY2F1c2Ugb3VyIHBsYWNlaG9sZGVyIGVsZW1lbnQgdG8gYmUgbGVmdCBhcyBhIHBsYWNlaG9sZGVyCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIG1ldGhvZChyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2UuZW5kQ29udGFpbmVyKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTsKICAgICAgICAgICAgICAgICAgICB9LCAwKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjYXJldFBsYWNlaG9sZGVyID0gdGhpcy5kb2MucXVlcnlTZWxlY3RvcigiLiIgKyBjbGFzc05hbWUpOwogICAgICAgICAgICAgICAgaWYgKGNhcmV0UGxhY2Vob2xkZXIpIHsKICAgICAgICAgICAgICAgICAgICBuZXdSYW5nZSA9IHJhbmd5LmNyZWF0ZVJhbmdlKHRoaXMuZG9jKTsKICAgICAgICAgICAgICAgICAgICBuZXh0U2libGluZyA9IGNhcmV0UGxhY2Vob2xkZXIubmV4dFNpYmxpbmc7CiAgICAgICAgICAgICAgICAgICAgLy8gT3BlcmEgaXMgc28gZnVja2VkIHVwIHdoZW4geW91IHdhbm5hIHNldCBmb2N1cyBiZWZvcmUgYSA8YnI+CiAgICAgICAgICAgICAgICAgICAgaWYgKHd5c2lodG1sNS5icm93c2VyLmhhc0luc2VydE5vZGVJc3N1ZSgpICYmIG5leHRTaWJsaW5nICYmIG5leHRTaWJsaW5nLm5vZGVOYW1lID09PSAiQlIiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0NhcmV0UGxhY2Vob2xkZXIgPSB0aGlzLmRvYy5jcmVhdGVUZXh0Tm9kZSh3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFKTsKICAgICAgICAgICAgICAgICAgICAgICAgZG9tLmluc2VydChuZXdDYXJldFBsYWNlaG9sZGVyKS5hZnRlcihjYXJldFBsYWNlaG9sZGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV3UmFuZ2Uuc2V0U3RhcnRCZWZvcmUobmV3Q2FyZXRQbGFjZWhvbGRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1JhbmdlLnNldEVuZEJlZm9yZShuZXdDYXJldFBsYWNlaG9sZGVyKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBuZXdSYW5nZS5zZWxlY3ROb2RlKGNhcmV0UGxhY2Vob2xkZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBuZXdSYW5nZS5kZWxldGVDb250ZW50cygpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFNlbGVjdGlvbihuZXdSYW5nZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIGZhbGxiYWNrIGZvciB3aGVuIGFsbCBoZWxsIGJyZWFrcyBsb29zZQogICAgICAgICAgICAgICAgICAgIGJvZHkuZm9jdXMoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAocmVzdG9yZVNjcm9sbFBvc2l0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgYm9keS5zY3JvbGxUb3AgPSBvbGRTY3JvbGxUb3A7CiAgICAgICAgICAgICAgICAgICAgYm9keS5zY3JvbGxMZWZ0ID0gb2xkU2Nyb2xsTGVmdDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgaXQgYWdhaW4sIGp1c3QgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIHBsYWNlaG9sZGVyIGlzIGRlZmluaXRlbHkgb3V0IG9mIHRoZSBkb20gdHJlZQogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBjYXJldFBsYWNlaG9sZGVyLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY2FyZXRQbGFjZWhvbGRlcik7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChlMikgewogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIERpZmZlcmVudCBhcHByb2FjaCBvZiBwcmVzZXJ2aW5nIHRoZSBzZWxlY3Rpb24gKGRvZXNuJ3QgbW9kaWZ5IHRoZSBkb20pCiAgICAgICAgICAgICAqIFRha2VzIGFsbCB0ZXh0IG5vZGVzIGluIHRoZSBzZWxlY3Rpb24gYW5kIHNhdmVzIHRoZSBzZWxlY3Rpb24gcG9zaXRpb24gaW4gdGhlIGZpcnN0IGFuZCBsYXN0IG9uZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZXhlY3V0ZUFuZFJlc3RvcmVTaW1wbGUgOiBmdW5jdGlvbiAobWV0aG9kKSB7CiAgICAgICAgICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLmdldFJhbmdlKCksCiAgICAgICAgICAgICAgICAgICAgYm9keSA9IHRoaXMuZG9jLmJvZHksCiAgICAgICAgICAgICAgICAgICAgbmV3UmFuZ2UsCiAgICAgICAgICAgICAgICAgICAgZmlyc3ROb2RlLAogICAgICAgICAgICAgICAgICAgIGxhc3ROb2RlLAogICAgICAgICAgICAgICAgICAgIHRleHROb2RlcywKICAgICAgICAgICAgICAgICAgICByYW5nZUJhY2t1cDsKCiAgICAgICAgICAgICAgICAvLyBOb3RoaW5nIHNlbGVjdGVkLCBleGVjdXRlIGFuZCBzYXkgZ29vZGJ5ZQogICAgICAgICAgICAgICAgaWYgKCFyYW5nZSkgewogICAgICAgICAgICAgICAgICAgIG1ldGhvZChib2R5LCBib2R5KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGV4dE5vZGVzID0gcmFuZ2UuZ2V0Tm9kZXMoWzNdKTsKICAgICAgICAgICAgICAgIGZpcnN0Tm9kZSA9IHRleHROb2Rlc1swXSB8fCByYW5nZS5zdGFydENvbnRhaW5lcjsKICAgICAgICAgICAgICAgIGxhc3ROb2RlID0gdGV4dE5vZGVzW3RleHROb2Rlcy5sZW5ndGggLSAxXSB8fCByYW5nZS5lbmRDb250YWluZXI7CgogICAgICAgICAgICAgICAgcmFuZ2VCYWNrdXAgPSB7CiAgICAgICAgICAgICAgICAgICAgY29sbGFwc2VkIDogcmFuZ2UuY29sbGFwc2VkLAogICAgICAgICAgICAgICAgICAgIHN0YXJ0Q29udGFpbmVyIDogZmlyc3ROb2RlLAogICAgICAgICAgICAgICAgICAgIHN0YXJ0T2Zmc2V0IDogZmlyc3ROb2RlID09PSByYW5nZS5zdGFydENvbnRhaW5lciA/IHJhbmdlLnN0YXJ0T2Zmc2V0IDogMCwKICAgICAgICAgICAgICAgICAgICBlbmRDb250YWluZXIgOiBsYXN0Tm9kZSwKICAgICAgICAgICAgICAgICAgICBlbmRPZmZzZXQgOiBsYXN0Tm9kZSA9PT0gcmFuZ2UuZW5kQ29udGFpbmVyID8gcmFuZ2UuZW5kT2Zmc2V0IDogbGFzdE5vZGUubGVuZ3RoCiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgbWV0aG9kKHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5lbmRDb250YWluZXIpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgICAgICAgICAgIH0sIDApOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIG5ld1JhbmdlID0gcmFuZ3kuY3JlYXRlUmFuZ2UodGhpcy5kb2MpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBuZXdSYW5nZS5zZXRTdGFydChyYW5nZUJhY2t1cC5zdGFydENvbnRhaW5lciwgcmFuZ2VCYWNrdXAuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZTEpIHsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgbmV3UmFuZ2Uuc2V0RW5kKHJhbmdlQmFja3VwLmVuZENvbnRhaW5lciwgcmFuZ2VCYWNrdXAuZW5kT2Zmc2V0KTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUyKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U2VsZWN0aW9uKG5ld1JhbmdlKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUzKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbiAobm9kZSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgICB2YXIgbmV3UmFuZ2UgPSByYW5neS5jcmVhdGVSYW5nZSh0aGlzLmRvYyk7CiAgICAgICAgICAgICAgICBuZXdSYW5nZS5zZXRTdGFydChub2RlLCBvZmZzZXQgfHwgMCk7CiAgICAgICAgICAgICAgICB0aGlzLnNldFNlbGVjdGlvbihuZXdSYW5nZSk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogSW5zZXJ0IGh0bWwgYXQgdGhlIGNhcmV0IHBvc2l0aW9uIGFuZCBtb3ZlIHRoZSBjdXJzb3IgYWZ0ZXIgdGhlIGluc2VydGVkIGh0bWwKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGh0bWwgSFRNTCBzdHJpbmcgdG8gaW5zZXJ0CiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHNlbGVjdGlvbi5pbnNlcnRIVE1MKCI8cD5mb29iYXI8L3A+Iik7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbnNlcnRIVE1MIDogZnVuY3Rpb24gKGh0bWwpIHsKICAgICAgICAgICAgICAgIHZhciByYW5nZSA9IHJhbmd5LmNyZWF0ZVJhbmdlKHRoaXMuZG9jKSwKICAgICAgICAgICAgICAgICAgICBub2RlID0gcmFuZ2UuY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KGh0bWwpLAogICAgICAgICAgICAgICAgICAgIGxhc3RDaGlsZCA9IG5vZGUubGFzdENoaWxkOwogICAgICAgICAgICAgICAgdGhpcy5pbnNlcnROb2RlKG5vZGUpOwogICAgICAgICAgICAgICAgaWYgKGxhc3RDaGlsZCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0QWZ0ZXIobGFzdENoaWxkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBJbnNlcnQgYSBub2RlIGF0IHRoZSBjYXJldCBwb3NpdGlvbiBhbmQgbW92ZSB0aGUgY3Vyc29yIGJlaGluZCBpdAogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gbm9kZSBIVE1MIHN0cmluZyB0byBpbnNlcnQKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICogICAgc2VsZWN0aW9uLmluc2VydE5vZGUoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoImZvb2JhciIpKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGluc2VydE5vZGUgOiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gdGhpcy5nZXRSYW5nZSgpOwogICAgICAgICAgICAgICAgaWYgKHJhbmdlKSB7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZShub2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBXcmFwcyBjdXJyZW50IHNlbGVjdGlvbiB3aXRoIHRoZSBnaXZlbiBub2RlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBub2RlIFRoZSBub2RlIHRvIHN1cnJvdW5kIHRoZSBzZWxlY3RlZCBlbGVtZW50cyB3aXRoCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzdXJyb3VuZCA6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLmdldFJhbmdlKCk7CiAgICAgICAgICAgICAgICBpZiAoIXJhbmdlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBvbmx5IHdvcmtzIHdoZW4gdGhlIHJhbmdlIGJvdW5kYXJpZXMgYXJlIG5vdCBvdmVybGFwcGluZyBvdGhlciBlbGVtZW50cwogICAgICAgICAgICAgICAgICAgIHJhbmdlLnN1cnJvdW5kQ29udGVudHMobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3ROb2RlKG5vZGUpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgIC8vIGZhbGxiYWNrCiAgICAgICAgICAgICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChyYW5nZS5leHRyYWN0Q29udGVudHMoKSk7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZShub2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBTY3JvbGwgdGhlIGN1cnJlbnQgY2FyZXQgcG9zaXRpb24gaW50byB0aGUgdmlldwogICAgICAgICAgICAgKiBGSVhNRTogVGhpcyBpcyBhIGJpdCBoYWNreSwgdGhlcmUgbWlnaHQgYmUgYSBzbWFydGVyIHdheSBvZiBkb2luZyB0aGlzCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHNlbGVjdGlvbi5zY3JvbGxJbnRvVmlldygpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2Nyb2xsSW50b1ZpZXcgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWROb2RlcyA9IHRoaXMuY29tcG9zZXIuc2VsZWN0aW9uLmdldE5vZGVzKDMpOwogICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZXMgJiYgc2VsZWN0ZWROb2Rlcy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGZpcnN0Tm9kZSA9IHNlbGVjdGVkTm9kZXNbMF07CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGZpcnN0Tm9kZS5ub2RlVHlwZSA9PT0gMykgewogICAgICAgICAgICAgICAgICAgICAgICBmaXJzdE5vZGUgPSBmaXJzdE5vZGUucGFyZW50RWxlbWVudDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLyogVXNpbmcgc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZCBmb3IgQ2hyb21lIGFuZAogICAgICAgICAgICAgICAgICAgICAqIHNjcm9sbEludG9WaWV3IGZvciBvdGhlciBicm93c2VycyAqLwogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZmlyc3ROb2RlLnNjcm9sbEludG9WaWV3SWZOZWVkZWQgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3ROb2RlLnNjcm9sbEludG9WaWV3SWZOZWVkZWQoKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaXJzdE5vZGUuc2Nyb2xsSW50b1ZpZXcgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3ROb2RlLnNjcm9sbEludG9WaWV3KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFNlbGVjdCBsaW5lIHdoZXJlIHRoZSBjYXJldCBpcyBpbgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2VsZWN0TGluZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGlmICh3eXNpaHRtbDUuYnJvd3Nlci5zdXBwb3J0c1NlbGVjdGlvbk1vZGlmeSgpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2VsZWN0TGluZV9XM0MoKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5kb2Muc2VsZWN0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2VsZWN0TGluZV9NU0lFKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0RPTS9TZWxlY3Rpb24vbW9kaWZ5CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBfc2VsZWN0TGluZV9XM0MgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgd2luID0gdGhpcy5kb2MuZGVmYXVsdFZpZXcsCiAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uID0gd2luLmdldFNlbGVjdGlvbigpOwogICAgICAgICAgICAgICAgc2VsZWN0aW9uLm1vZGlmeSgiZXh0ZW5kIiwgImxlZnQiLCAibGluZWJvdW5kYXJ5Iik7CiAgICAgICAgICAgICAgICBzZWxlY3Rpb24ubW9kaWZ5KCJleHRlbmQiLCAicmlnaHQiLCAibGluZWJvdW5kYXJ5Iik7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfc2VsZWN0TGluZV9NU0lFIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gdGhpcy5kb2Muc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCksCiAgICAgICAgICAgICAgICAgICAgcmFuZ2VUb3AgPSByYW5nZS5ib3VuZGluZ1RvcCwKICAgICAgICAgICAgICAgICAgICByYW5nZUhlaWdodCA9IHJhbmdlLmJvdW5kaW5nSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgIHNjcm9sbFdpZHRoID0gdGhpcy5kb2MuYm9keS5zY3JvbGxXaWR0aCwKICAgICAgICAgICAgICAgICAgICByYW5nZUJvdHRvbSwKICAgICAgICAgICAgICAgICAgICByYW5nZUVuZCwKICAgICAgICAgICAgICAgICAgICBtZWFzdXJlTm9kZSwKICAgICAgICAgICAgICAgICAgICBpLAogICAgICAgICAgICAgICAgICAgIGo7CgogICAgICAgICAgICAgICAgaWYgKCFyYW5nZS5tb3ZlVG9Qb2ludCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAocmFuZ2VUb3AgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAvLyBEb24ndCBrbm93IHdoeSwgYnV0IHdoZW4gdGhlIHNlbGVjdGlvbiBlbmRzIGF0IHRoZSBlbmQgb2YgYSBsaW5lCiAgICAgICAgICAgICAgICAgICAgLy8gcmFuZ2UuYm91bmRpbmdUb3AgaXMgMAogICAgICAgICAgICAgICAgICAgIG1lYXN1cmVOb2RlID0gdGhpcy5kb2MuY3JlYXRlRWxlbWVudCgic3BhbiIpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0Tm9kZShtZWFzdXJlTm9kZSk7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2VUb3AgPSBtZWFzdXJlTm9kZS5vZmZzZXRUb3A7CiAgICAgICAgICAgICAgICAgICAgbWVhc3VyZU5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChtZWFzdXJlTm9kZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmFuZ2VUb3AgKz0gMTsKCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAtMTA7CiAgICAgICAgICAgICAgICAgICAgIGkgPCBzY3JvbGxXaWR0aDsKICAgICAgICAgICAgICAgICAgICAgaSArPSAyKSB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2UubW92ZVRvUG9pbnQoaSwgcmFuZ2VUb3ApOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlMSkgewogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBJbnZlc3RpZ2F0ZSB0aGUgZm9sbG93aW5nIGluIG9yZGVyIHRvIGhhbmRsZSBtdWx0aSBsaW5lIHNlbGVjdGlvbnMKICAgICAgICAgICAgICAgIHJhbmdlQm90dG9tID0gcmFuZ2VUb3AgKyAocmFuZ2VIZWlnaHQgPyAocmFuZ2VIZWlnaHQgLSAxKSA6IDApOwogICAgICAgICAgICAgICAgLy9yYW5nZUJvdHRvbSA9IHJhbmdlVG9wOwogICAgICAgICAgICAgICAgcmFuZ2VFbmQgPSB0aGlzLmRvYy5zZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTsKICAgICAgICAgICAgICAgIGZvciAoaiA9IHNjcm9sbFdpZHRoOwogICAgICAgICAgICAgICAgICAgICBqID49IDA7CiAgICAgICAgICAgICAgICAgICAgIGotLSkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlRW5kLm1vdmVUb1BvaW50KGosIHJhbmdlQm90dG9tKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZTIpIHsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmFuZ2Uuc2V0RW5kUG9pbnQoIkVuZFRvRW5kIiwgcmFuZ2VFbmQpOwogICAgICAgICAgICAgICAgcmFuZ2Uuc2VsZWN0KCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRUZXh0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGlvbiA9IHRoaXMuZ2V0U2VsZWN0aW9uKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0aW9uID8gc2VsZWN0aW9uLnRvU3RyaW5nKCkgOiAiIjsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGdldE5vZGVzIDogZnVuY3Rpb24gKG5vZGVUeXBlLCBmaWx0ZXIpIHsKICAgICAgICAgICAgICAgIHZhciByYW5nZSA9IHRoaXMuZ2V0UmFuZ2UoKTsKICAgICAgICAgICAgICAgIGlmIChyYW5nZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiByYW5nZS5nZXROb2Rlcyhbbm9kZVR5cGVdLCBmaWx0ZXIpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gW107CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRSYW5nZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3Rpb24gPSB0aGlzLmdldFNlbGVjdGlvbigpOwogICAgICAgICAgICAgICAgLyogQ2hlY2sgaWYgdGhlIGZvY3VzTm9kZSBpcyBlZGl0b3IgZGl2IGVsZW1lbnQgb3IgaXRzIGNoaWxkCiAgICAgICAgICAgICAgICAqICBGb3IgSUUsIG9uIHNlbGVjdGluZyB0ZXh0IHdpdGggQ3RybCtBIHRoZSBmb2N1cyBub2RlIGlzIGVkaXRvciBub2RlICovCiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0aW9uICYmIHNlbGVjdGlvbi5yYW5nZUNvdW50ICYmICh0aGlzLmNvbXBvc2VyLmNvbnRhaW5lciA9PT0gc2VsZWN0aW9uLmZvY3VzTm9kZSB8fCAkKHRoaXMuY29tcG9zZXIuY29udGFpbmVyKS5oYXMoc2VsZWN0aW9uLmZvY3VzTm9kZSkubGVuZ3RoID4gMCkgJiYgc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRTZWxlY3Rpb24gOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcmFuZ3kuZ2V0U2VsZWN0aW9uKHRoaXMuZG9jLmRlZmF1bHRWaWV3IHx8IHRoaXMuZG9jLnBhcmVudFdpbmRvdyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGdldEN1cnJlbnRSYW5nZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3Rpb24gPSByYW5neS5nZXRTZWxlY3Rpb25XaXRob3V0UmVmZXJzaCh0aGlzLmRvYy5kZWZhdWx0VmlldyB8fCB0aGlzLmRvYy5wYXJlbnRXaW5kb3cpOwogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGlvbiAmJiBzZWxlY3Rpb24ucmFuZ2VDb3VudCAmJiBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHNldFNlbGVjdGlvbiA6IGZ1bmN0aW9uIChyYW5nZSkgewogICAgICAgICAgICAgICAgdmFyIHdpbiA9IHRoaXMuZG9jLmRlZmF1bHRWaWV3IHx8IHRoaXMuZG9jLnBhcmVudFdpbmRvdywKICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb24gPSByYW5neS5nZXRTZWxlY3Rpb24od2luKTsKICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3Rpb24uc2V0U2luZ2xlUmFuZ2UocmFuZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBJbnNwaXJlZCBieSB0aGUgcmFuZ3kgQ1NTIEFwcGxpZXIgbW9kdWxlIHdyaXR0ZW4gYnkgVGltIERvd24gYW5kIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS4KICogaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL3Jhbmd5LwogKgogKiBjaGFuZ2VkIGluIG9yZGVyIHRvIGJlIGFibGUgLi4uCiAqICAgIC0gdG8gdXNlIGN1c3RvbSB0YWdzCiAqICAgIC0gdG8gZGV0ZWN0IGFuZCByZXBsYWNlIHNpbWlsYXIgY3NzIGNsYXNzZXMgdmlhIHJlZyBleHAKICovCihmdW5jdGlvbiAod3lzaWh0bWw1LCByYW5neSkgewogICAgdmFyIGRlZmF1bHRUYWdOYW1lID0gInNwYW4iOwoKICAgIHZhciBSRUdfRVhQX1dISVRFX1NQQUNFID0gL1xzKy9nOwoKICAgIGZ1bmN0aW9uIGhhc0NsYXNzKGVsLCBjc3NDbGFzcywgcmVnRXhwKSB7CiAgICAgICAgaWYgKCFlbC5jbGFzc05hbWUpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgdmFyIG1hdGNoaW5nQ2xhc3NOYW1lcyA9IGVsLmNsYXNzTmFtZS5tYXRjaChyZWdFeHApIHx8IFtdOwogICAgICAgIHJldHVybiBtYXRjaGluZ0NsYXNzTmFtZXNbbWF0Y2hpbmdDbGFzc05hbWVzLmxlbmd0aCAtIDFdID09PSBjc3NDbGFzczsKICAgIH0KCiAgICBmdW5jdGlvbiBoYXNBdHRyaWJ1dGUoZWwsIGF0dHJpYnV0ZXMpIHsKICAgICAgICBpZiAoZWwubm9kZVR5cGUgPT0gd3lzaWh0bWw1LlRFWFRfTk9ERSB8fCBlbC5ub2RlVHlwZSA9PSA5KSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgdmFyIHN0ID0gZWwuZ2V0QXR0cmlidXRlKCJzdHlsZSIpOwogICAgICAgIGlmICghc3QpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBmb3IgKHZhciBhdHRyaWJ1dGUgaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICBpZiAoZWwuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShhdHRyaWJ1dGUpKSB7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudEF0dHJpYnV0ZVZhbHVlID0gZWwuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShhdHRyaWJ1dGUpLnJlcGxhY2UoL3B4LywgIiIpOwogICAgICAgICAgICAgICAgY3VycmVudEF0dHJpYnV0ZVZhbHVlID0gY3VycmVudEF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoL3B0LywgIiIpOwogICAgICAgICAgICAgICAgY3VycmVudEF0dHJpYnV0ZVZhbHVlID0gY3VycmVudEF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoL1siJ10vZywgIiIpOwogICAgICAgICAgICAgICAgdmFyIG5ld0F0dHJpYnV0ZVZhbHVlID0gYXR0cmlidXRlc1thdHRyaWJ1dGVdID8gYXR0cmlidXRlc1thdHRyaWJ1dGVdLnJlcGxhY2UoL3B4LywgIiIpIDogbnVsbDsKICAgICAgICAgICAgICAgIG5ld0F0dHJpYnV0ZVZhbHVlID0gbmV3QXR0cmlidXRlVmFsdWUgPyBuZXdBdHRyaWJ1dGVWYWx1ZS5yZXBsYWNlKC9wdC8sICIiKSA6IG51bGw7CiAgICAgICAgICAgICAgICBpZiAobmV3QXR0cmlidXRlVmFsdWUgIT0gbnVsbCAmJiBjdXJyZW50QXR0cmlidXRlVmFsdWUgPT0gbmV3QXR0cmlidXRlVmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWF0dHJpYnV0ZXNbYXR0cmlidXRlXSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRDbGFzcyhlbCwgY3NzQ2xhc3MsIHJlZ0V4cCkgewogICAgICAgIGlmIChlbC5jbGFzc05hbWUpIHsKICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoZWwsIHJlZ0V4cCk7CiAgICAgICAgICAgIGVsLmNsYXNzTmFtZSArPSAiICIgKyBjc3NDbGFzczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbC5jbGFzc05hbWUgPSBjc3NDbGFzczsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gYWRkQXR0cmlidXRlKGVsLCBhdHRyaWJ1dGVzLCBjbGVhclByZVN0eWxlKSB7CiAgICAgICAgaWYgKGNsZWFyUHJlU3R5bGUgJiYgZWwpIHsKICAgICAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCJzdHlsZSIpOwogICAgICAgIH0KICAgICAgICBpZiAoYXR0cmlidXRlcyAhPSBudWxsKSB7CiAgICAgICAgICAgIGZvciAoYXR0cmlidXRlIGluIGF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICAgIGlmIChlbC5zdHlsZSkgewogICAgICAgICAgICAgICAgICAgIGVsLnN0eWxlLnJlbW92ZVByb3BlcnR5KGF0dHJpYnV0ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgc3QgPSBlbC5nZXRBdHRyaWJ1dGUoJ3N0eWxlJyk7CiAgICAgICAgICAgICAgICBpZiAoc3QgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IHN0LmluZGV4T2YoYXR0cmlidXRlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlID09ICJjb2xvciIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogSWYgc3BhbiBoYWQgImJhY2tncm91bmQtY29sb3IiIGluIHN0eWxlIGFuZCB3ZSBzZWFyY2ggZm9yICJjb2xvciIgdGhlbiBpdCByZXR1cm5zIHRoZSBpbmRleCBvZiBjb2xvcgogICAgICAgICAgICAgICAgICAgICAgICAgd2hpY2ggaXMgcHJlc2VudCBpbiAiYmFja2dyb3VuZC1jb2xvciIgc3RyaW5nLiBCZWNhdXNlIG9mIHRoaXMgYmFja2dyb3VuZC1jb2xvciB3aGljaCB3YXMgYXBwbGllZCBlYXJsaWVyIHdhcyBsb3N0LgogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgc3QgPSBzdC5yZXBsYWNlKCJiYWNrZ3JvdW5kLWNvbG9yIiwgImJhY2tncm91bmQtY3VzdG9tY2xyIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gc3QuaW5kZXhPZihhdHRyaWJ1dGUpOwogICAgICAgICAgICAgICAgICAgICAgICBzdCA9IHN0LnJlcGxhY2UoImJhY2tncm91bmQtY3VzdG9tY2xyIiwgImJhY2tncm91bmQtY29sb3IiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID49IDApIHsvLyBDb250YWlucyBjdXN0b20gU3R5bGUgYXR0cmlidXRlIHRyeSByZW1vdmUgaWYgYWxyZWFkeSBleGlzdHMgYW5kIGV4ZWNwZXRpbmcgY3VzdG9tIGF0dHJpYnV0ZSB0byBjb250YWluIHZhbHVlIHRydWUKICAgICAgICAgICAgICAgICAgICAgICAgc3QgPSBzdC5zdWJzdHIoMCwgaW5kZXgpICsgc3Quc3Vic3RyKGluZGV4ICsgYXR0cmlidXRlLmxlbmd0aCArIDYpOyAvLyBhZGRpbmcgKzYgY2hhcmN0ZXIgYXMgd2UgZXhlY3BldGluZyBjdXN0b20gYXR0cmlidXRlIHZhbHVlIHRvIHRydWUgb3IgZmFsc2UgZW5kIHdpdGggOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgYXR0cmlidXRlICsgIjoiICsgYXR0cmlidXRlc1thdHRyaWJ1dGVdICsgIjsiICsgc3QpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgYXR0cmlidXRlICsgIjoiICsgYXR0cmlidXRlc1thdHRyaWJ1dGVdICsgIjsiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBhZGREYXRhQXR0cmlidXRlKGVsLCBhdHRyaWJ1dGVzLCBjbGVhclByZURhdGFBdHRyKSB7CiAgICAgICAgaWYgKGVsKSB7CiAgICAgICAgICAgIGlmIChjbGVhclByZURhdGFBdHRyICYmICQoZWwpLmRhdGEoKSkgewogICAgICAgICAgICAgICAgdmFyIGRhdGEgPSAkKGVsKS5kYXRhKCk7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gZGF0YSkgewogICAgICAgICAgICAgICAgICAgICQoZWwpLnJlbW92ZURhdGEoa2V5KTsKICAgICAgICAgICAgICAgICAgICAkKGVsKS5yZW1vdmVBdHRyKCJkYXRhLSIgKyBrZXkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAodmFyIGF0dHJpYnV0ZSBpbiBhdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICAkKGVsKS5kYXRhKGF0dHJpYnV0ZSwgYXR0cmlidXRlc1thdHRyaWJ1dGVdKTsKICAgICAgICAgICAgICAgICQoZWwpLmF0dHIoJ2RhdGEtJyArIGF0dHJpYnV0ZSwgYXR0cmlidXRlc1thdHRyaWJ1dGVdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiByZW1vdmVDbGFzcyhlbCwgcmVnRXhwKSB7CiAgICAgICAgaWYgKGVsLmNsYXNzTmFtZSkgewogICAgICAgICAgICBlbC5jbGFzc05hbWUgPSBlbC5jbGFzc05hbWUucmVwbGFjZShyZWdFeHAsICIiKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gaGFzU2FtZUNsYXNzZXMoZWwxLCBlbDIpIHsKICAgICAgICByZXR1cm4gZWwxLmNsYXNzTmFtZS5yZXBsYWNlKFJFR19FWFBfV0hJVEVfU1BBQ0UsICIgIikgPT0gZWwyLmNsYXNzTmFtZS5yZXBsYWNlKFJFR19FWFBfV0hJVEVfU1BBQ0UsICIgIik7CiAgICB9CgogICAgZnVuY3Rpb24gcmVwbGFjZVdpdGhPd25DaGlsZHJlbihlbCkgewogICAgICAgIHZhciBwYXJlbnQgPSBlbC5wYXJlbnROb2RlOwogICAgICAgIHdoaWxlIChlbC5maXJzdENoaWxkKSB7CiAgICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoZWwuZmlyc3RDaGlsZCwgZWwpOwogICAgICAgIH0KICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoZWwpOwogICAgfQoKICAgIGZ1bmN0aW9uIGVsZW1lbnRzSGF2ZVNhbWVOb25DbGFzc0F0dHJpYnV0ZXMoZWwxLCBlbDIpIHsKICAgICAgICBpZiAoZWwxLmF0dHJpYnV0ZXMubGVuZ3RoICE9IGVsMi5hdHRyaWJ1dGVzLmxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBlbDEuYXR0cmlidXRlcy5sZW5ndGgsIGF0dHIxLCBhdHRyMiwgbmFtZTsKICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgYXR0cjEgPSBlbDEuYXR0cmlidXRlc1tpXTsKICAgICAgICAgICAgbmFtZSA9IGF0dHIxLm5hbWU7CiAgICAgICAgICAgIGlmIChuYW1lICE9ICJjbGFzcyIpIHsKICAgICAgICAgICAgICAgIGF0dHIyID0gZWwyLmF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKG5hbWUpOwogICAgICAgICAgICAgICAgaWYgKGF0dHIxLnNwZWNpZmllZCAhPSBhdHRyMi5zcGVjaWZpZWQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoYXR0cjEuc3BlY2lmaWVkICYmIGF0dHIxLm5vZGVWYWx1ZSAhPT0gYXR0cjIubm9kZVZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzU3BsaXRQb2ludChub2RlLCBvZmZzZXQpIHsKICAgICAgICBpZiAocmFuZ3kuZG9tLmlzQ2hhcmFjdGVyRGF0YU5vZGUobm9kZSkpIHsKICAgICAgICAgICAgaWYgKG9mZnNldCA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gISFub2RlLnByZXZpb3VzU2libGluZzsKICAgICAgICAgICAgfSBlbHNlIGlmIChvZmZzZXQgPT0gbm9kZS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHJldHVybiAhIW5vZGUubmV4dFNpYmxpbmc7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIG9mZnNldCA+IDAgJiYgb2Zmc2V0IDwgbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDsKICAgIH0KCiAgICBmdW5jdGlvbiBzcGxpdE5vZGVBdChub2RlLCBkZXNjZW5kYW50Tm9kZSwgZGVzY2VuZGFudE9mZnNldCkgewogICAgICAgIHZhciBuZXdOb2RlOwogICAgICAgIGlmIChyYW5neS5kb20uaXNDaGFyYWN0ZXJEYXRhTm9kZShkZXNjZW5kYW50Tm9kZSkpIHsKICAgICAgICAgICAgaWYgKGRlc2NlbmRhbnRPZmZzZXQgPT0gMCkgewogICAgICAgICAgICAgICAgZGVzY2VuZGFudE9mZnNldCA9IHJhbmd5LmRvbS5nZXROb2RlSW5kZXgoZGVzY2VuZGFudE5vZGUpOwogICAgICAgICAgICAgICAgZGVzY2VuZGFudE5vZGUgPSBkZXNjZW5kYW50Tm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICB9IGVsc2UgaWYgKGRlc2NlbmRhbnRPZmZzZXQgPT0gZGVzY2VuZGFudE5vZGUubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBkZXNjZW5kYW50T2Zmc2V0ID0gcmFuZ3kuZG9tLmdldE5vZGVJbmRleChkZXNjZW5kYW50Tm9kZSkgKyAxOwogICAgICAgICAgICAgICAgZGVzY2VuZGFudE5vZGUgPSBkZXNjZW5kYW50Tm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbmV3Tm9kZSA9IHJhbmd5LmRvbS5zcGxpdERhdGFOb2RlKGRlc2NlbmRhbnROb2RlLCBkZXNjZW5kYW50T2Zmc2V0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIW5ld05vZGUpIHsKICAgICAgICAgICAgbmV3Tm9kZSA9IGRlc2NlbmRhbnROb2RlLmNsb25lTm9kZShmYWxzZSk7CiAgICAgICAgICAgIGlmIChuZXdOb2RlLmlkKSB7CiAgICAgICAgICAgICAgICBuZXdOb2RlLnJlbW92ZUF0dHJpYnV0ZSgiaWQiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgY2hpbGQ7CiAgICAgICAgICAgIHdoaWxlICgoY2hpbGQgPSBkZXNjZW5kYW50Tm9kZS5jaGlsZE5vZGVzW2Rlc2NlbmRhbnRPZmZzZXRdKSkgewogICAgICAgICAgICAgICAgbmV3Tm9kZS5hcHBlbmRDaGlsZChjaGlsZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmFuZ3kuZG9tLmluc2VydEFmdGVyKG5ld05vZGUsIGRlc2NlbmRhbnROb2RlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChkZXNjZW5kYW50Tm9kZSA9PSBub2RlKSA/IG5ld05vZGUgOiBzcGxpdE5vZGVBdChub2RlLCBuZXdOb2RlLnBhcmVudE5vZGUsIHJhbmd5LmRvbS5nZXROb2RlSW5kZXgobmV3Tm9kZSkpOwogICAgfQoKICAgIGZ1bmN0aW9uIE1lcmdlKGZpcnN0Tm9kZSkgewogICAgICAgIHRoaXMuaXNFbGVtZW50TWVyZ2UgPSAoZmlyc3ROb2RlLm5vZGVUeXBlID09IHd5c2lodG1sNS5FTEVNRU5UX05PREUpOwogICAgICAgIHRoaXMuZmlyc3RUZXh0Tm9kZSA9IHRoaXMuaXNFbGVtZW50TWVyZ2UgPyBmaXJzdE5vZGUubGFzdENoaWxkIDogZmlyc3ROb2RlOwogICAgICAgIHRoaXMudGV4dE5vZGVzID0gW3RoaXMuZmlyc3RUZXh0Tm9kZV07CiAgICB9CgogICAgTWVyZ2UucHJvdG90eXBlID0gewogICAgICAgIGRvTWVyZ2UgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciB0ZXh0Qml0cyA9IFtdLCB0ZXh0Tm9kZSwgcGFyZW50LCB0ZXh0OwogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gdGhpcy50ZXh0Tm9kZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZSA9IHRoaXMudGV4dE5vZGVzW2ldOwogICAgICAgICAgICAgICAgcGFyZW50ID0gdGV4dE5vZGUucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgIHRleHRCaXRzW2ldID0gdGV4dE5vZGUuZGF0YTsKICAgICAgICAgICAgICAgIGlmIChpKSB7CiAgICAgICAgICAgICAgICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKHRleHROb2RlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXBhcmVudC5oYXNDaGlsZE5vZGVzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQocGFyZW50KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5maXJzdFRleHROb2RlLmRhdGEgPSB0ZXh0ID0gdGV4dEJpdHMuam9pbigiIik7CiAgICAgICAgICAgIHJldHVybiB0ZXh0OwogICAgICAgIH0sCgogICAgICAgIGdldExlbmd0aCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGkgPSB0aGlzLnRleHROb2Rlcy5sZW5ndGgsIGxlbiA9IDA7CiAgICAgICAgICAgIHdoaWxlIChpLS0pIHsKICAgICAgICAgICAgICAgIGxlbiArPSB0aGlzLnRleHROb2Rlc1tpXS5sZW5ndGg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGxlbjsKICAgICAgICB9LAoKICAgICAgICB0b1N0cmluZyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHRleHRCaXRzID0gW107CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB0aGlzLnRleHROb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgIHRleHRCaXRzW2ldID0gIiciICsgdGhpcy50ZXh0Tm9kZXNbaV0uZGF0YSArICInIjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gIltNZXJnZSgiICsgdGV4dEJpdHMuam9pbigiLCIpICsgIildIjsKICAgICAgICB9CiAgICB9OwoKICAgIGZ1bmN0aW9uIEhUTUxBcHBsaWVyKHRhZ05hbWVzLCBjc3NDbGFzcywgc2ltaWxhckNsYXNzUmVnRXhwLCBub3JtYWxpemUsIGF0dHJpYnV0ZXMsIGNsZWFyUHJlU3R5bGUsIGRhdGFBdHRyaWJ1dGVzLCBjbGVhclByZURhdGFBdHRyKSB7CiAgICAgICAgdGhpcy50YWdOYW1lcyA9IHRhZ05hbWVzIHx8IFtkZWZhdWx0VGFnTmFtZV07CiAgICAgICAgdGhpcy5jc3NDbGFzcyA9IGNzc0NsYXNzIHx8ICIiOwogICAgICAgIHRoaXMuc2ltaWxhckNsYXNzUmVnRXhwID0gc2ltaWxhckNsYXNzUmVnRXhwOwogICAgICAgIHRoaXMubm9ybWFsaXplID0gbm9ybWFsaXplOwogICAgICAgIHRoaXMuYXBwbHlUb0FueVRhZ05hbWUgPSBmYWxzZTsKICAgICAgICB0aGlzLmF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzOwogICAgICAgIHRoaXMuY2xlYXJQcmVTdHlsZSA9IGNsZWFyUHJlU3R5bGU7CiAgICAgICAgdGhpcy5kYXRhQXR0cmlidXRlcyA9IGRhdGFBdHRyaWJ1dGVzOwogICAgICAgIHRoaXMuY2xlYXJQcmVEYXRhQXR0ciA9IGNsZWFyUHJlRGF0YUF0dHI7CiAgICB9CgogICAgSFRNTEFwcGxpZXIucHJvdG90eXBlID0gewogICAgICAgIGdldEFuY2VzdG9yV2l0aENsYXNzQW5kQXR0cmlidXRlIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgdmFyIGNzc0NsYXNzTWF0Y2g7CgogICAgICAgICAgICB3aGlsZSAobm9kZSkgewogICAgICAgICAgICAgICAgY3NzQ2xhc3NNYXRjaCA9IHRoaXMuY3NzQ2xhc3MgPyBoYXNDbGFzcyhub2RlLCB0aGlzLmNzc0NsYXNzLCB0aGlzLnNpbWlsYXJDbGFzc1JlZ0V4cCkgOiB0cnVlOwogICAgICAgICAgICAgICAgdmFyIHRleHROb2RlID0gbm9kZTsKICAgICAgICAgICAgICAgIGlmICgodGV4dE5vZGUubm9kZVR5cGUgPT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERSkgJiYgdGhpcy5hdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB0aGlzLmF0dHJpYnV0ZXM7CiAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZU1hdGNoID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBhdHRyaWJ1dGUgaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cmlidXRlVmFsdWUgPSB0ZXh0Tm9kZS5zdHlsZVthdHRyaWJ1dGVdOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cmlidXRlVmFsdWUgIT0gYXR0cmlidXRlc1thdHRyaWJ1dGVdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVNYXRjaCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVNYXRjaCA9IHRoaXMuYXR0cmlidXRlcyA/IGF0dHJpYnV0ZU1hdGNoIDogdHJ1ZTsKCiAgICAgICAgICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSB3eXNpaHRtbDUuRUxFTUVOVF9OT0RFICYmIHJhbmd5LmRvbS5hcnJheUNvbnRhaW5zKHRoaXMudGFnTmFtZXMsIG5vZGUudGFnTmFtZS50b0xvd2VyQ2FzZSgpKSAmJiBjc3NDbGFzc01hdGNoICYmIGF0dHJpYnV0ZU1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAogICAgICAgIGdldEFuY2VzdG9yIDogZnVuY3Rpb24gKG5vZGUpIHsKICAgICAgICAgICAgaWYgKHRoaXMuYXR0cmlidXRlcyB8fCB0aGlzLmRhdGFBdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBbmNlc3RvcldpdGhBdHRyaWJ1dGVzKG5vZGUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QW5jZXN0b3JXaXRoQ2xhc3Mobm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGdldEFuY2VzdG9yV2l0aEF0dHJpYnV0ZXMgOiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlc01hdGNoOwogICAgICAgICAgICBpZiAoIXRoaXMuYXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHdoaWxlIChub2RlKSB7CiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzTWF0Y2ggPSB0aGlzLmF0dHJpYnV0ZXMgPyBoYXNBdHRyaWJ1dGUobm9kZSwgdGhpcy5hdHRyaWJ1dGVzKSA6IHRydWU7CiAgICAgICAgICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSB3eXNpaHRtbDUuRUxFTUVOVF9OT0RFICYmIChyYW5neS5kb20uYXJyYXlDb250YWlucyh0aGlzLnRhZ05hbWVzLCBub2RlLnRhZ05hbWUudG9Mb3dlckNhc2UoKSkgfHwgd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKG5vZGUpKSAmJiBhdHRyaWJ1dGVzTWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChub2RlICYmIG5vZGUuc3R5bGUgJiYgdGhpcy5hdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJFeGlzdHMgPSBub2RlLnN0eWxlLmdldFByb3BlcnR5VmFsdWUoKE9iamVjdC5rZXlzKHRoaXMuYXR0cmlidXRlcykpWzBdKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ckV4aXN0cykgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKICAgICAgICBnZXRBbmNlc3RvcldpdGhDbGFzcyA6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgIHZhciBjc3NDbGFzc01hdGNoOwoKICAgICAgICAgICAgd2hpbGUgKG5vZGUpIHsKICAgICAgICAgICAgICAgIGNzc0NsYXNzTWF0Y2ggPSB0aGlzLmNzc0NsYXNzID8gaGFzQ2xhc3Mobm9kZSwgdGhpcy5jc3NDbGFzcywgdGhpcy5zaW1pbGFyQ2xhc3NSZWdFeHApIDogdHJ1ZTsKICAgICAgICAgICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IHd5c2lodG1sNS5FTEVNRU5UX05PREUgJiYgcmFuZ3kuZG9tLmFycmF5Q29udGFpbnModGhpcy50YWdOYW1lcywgbm9kZS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpICYmIGNzc0NsYXNzTWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIC8vIE5vcm1hbGl6ZXMgbm9kZXMgYWZ0ZXIgYXBwbHlpbmcgYSBDU1MgY2xhc3MgdG8gYSBSYW5nZS4KICAgICAgICBwb3N0QXBwbHkgOiBmdW5jdGlvbiAodGV4dE5vZGVzLCByYW5nZSwgdGV4dE5vZGVOYW1lcykgewogICAgICAgICAgICB2YXIgZmlyc3ROb2RlID0gdGV4dE5vZGVzWzBdLCBsYXN0Tm9kZSA9IHRleHROb2Rlc1t0ZXh0Tm9kZXMubGVuZ3RoIC0gMV07CgogICAgICAgICAgICB2YXIgbWVyZ2VzID0gW10sIGN1cnJlbnRNZXJnZTsKCiAgICAgICAgICAgIHZhciByYW5nZVN0YXJ0Tm9kZSA9IGZpcnN0Tm9kZSwgcmFuZ2VFbmROb2RlID0gbGFzdE5vZGU7CiAgICAgICAgICAgIHZhciByYW5nZVN0YXJ0T2Zmc2V0ID0gMCwgcmFuZ2VFbmRPZmZzZXQgPSBsYXN0Tm9kZS5sZW5ndGg7CgogICAgICAgICAgICB2YXIgdGV4dE5vZGUsIHByZWNlZGluZ1RleHROb2RlOwoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRleHROb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgIHRleHROb2RlID0gdGV4dE5vZGVzW2ldOwogICAgICAgICAgICAgICAgcHJlY2VkaW5nVGV4dE5vZGUgPSB0aGlzLmdldEFkamFjZW50TWVyZ2VhYmxlVGV4dE5vZGUodGV4dE5vZGUucGFyZW50Tm9kZSwgZmFsc2UsIHRleHROb2RlTmFtZXMpOwogICAgICAgICAgICAgICAgaWYgKHByZWNlZGluZ1RleHROb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFjdXJyZW50TWVyZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE1lcmdlID0gbmV3IE1lcmdlKHByZWNlZGluZ1RleHROb2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgbWVyZ2VzLnB1c2goY3VycmVudE1lcmdlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY3VycmVudE1lcmdlLnRleHROb2Rlcy5wdXNoKHRleHROb2RlKTsKICAgICAgICAgICAgICAgICAgICBpZiAodGV4dE5vZGUgPT09IGZpcnN0Tm9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICByYW5nZVN0YXJ0Tm9kZSA9IGN1cnJlbnRNZXJnZS5maXJzdFRleHROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICByYW5nZVN0YXJ0T2Zmc2V0ID0gcmFuZ2VTdGFydE5vZGUubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAodGV4dE5vZGUgPT09IGxhc3ROb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlRW5kTm9kZSA9IGN1cnJlbnRNZXJnZS5maXJzdFRleHROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICByYW5nZUVuZE9mZnNldCA9IGN1cnJlbnRNZXJnZS5nZXRMZW5ndGgoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNZXJnZSA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFRlc3Qgd2hldGhlciB0aGUgZmlyc3Qgbm9kZSBhZnRlciB0aGUgcmFuZ2UgbmVlZHMgbWVyZ2luZwogICAgICAgICAgICB2YXIgbmV4dFRleHROb2RlID0gdGhpcy5nZXRBZGphY2VudE1lcmdlYWJsZVRleHROb2RlKGxhc3ROb2RlLnBhcmVudE5vZGUsIHRydWUpOwogICAgICAgICAgICBpZiAobmV4dFRleHROb2RlKSB7CiAgICAgICAgICAgICAgICBpZiAoIWN1cnJlbnRNZXJnZSkgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNZXJnZSA9IG5ldyBNZXJnZShsYXN0Tm9kZSk7CiAgICAgICAgICAgICAgICAgICAgbWVyZ2VzLnB1c2goY3VycmVudE1lcmdlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJlbnRNZXJnZS50ZXh0Tm9kZXMucHVzaChuZXh0VGV4dE5vZGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBEbyB0aGUgbWVyZ2VzCiAgICAgICAgICAgIGlmIChtZXJnZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBtZXJnZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICBpIDwgbGVuOwogICAgICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZXNbaV0uZG9NZXJnZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gU2V0IHRoZSByYW5nZSBib3VuZGFyaWVzCiAgICAgICAgICAgICAgICByYW5nZS5zZXRTdGFydChyYW5nZVN0YXJ0Tm9kZSwgcmFuZ2VTdGFydE9mZnNldCk7CiAgICAgICAgICAgICAgICByYW5nZS5zZXRFbmQocmFuZ2VFbmROb2RlLCByYW5nZUVuZE9mZnNldCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBnZXRBZGphY2VudE1lcmdlYWJsZVRleHROb2RlIDogZnVuY3Rpb24gKG5vZGUsIGZvcndhcmQsIHRleHROb2RlTmFtZXMpIHsKICAgICAgICAgICAgdmFyIGlzVGV4dE5vZGUgPSAobm9kZS5ub2RlVHlwZSA9PSB3eXNpaHRtbDUuVEVYVF9OT0RFKTsKICAgICAgICAgICAgdmFyIGVsID0gaXNUZXh0Tm9kZSA/IG5vZGUucGFyZW50Tm9kZSA6IG5vZGU7CiAgICAgICAgICAgIHZhciBhZGphY2VudE5vZGU7CiAgICAgICAgICAgIHZhciBwcm9wTmFtZSA9IGZvcndhcmQgPyAibmV4dFNpYmxpbmciIDogInByZXZpb3VzU2libGluZyI7CiAgICAgICAgICAgIGlmIChpc1RleHROb2RlKSB7CiAgICAgICAgICAgICAgICAvLyBDYW4gbWVyZ2UgaWYgdGhlIG5vZGUncyBwcmV2aW91cy9uZXh0IHNpYmxpbmcgaXMgYSB0ZXh0IG5vZGUKICAgICAgICAgICAgICAgIGFkamFjZW50Tm9kZSA9IG5vZGVbcHJvcE5hbWVdOwogICAgICAgICAgICAgICAgaWYgKGFkamFjZW50Tm9kZSAmJiBhZGphY2VudE5vZGUubm9kZVR5cGUgPT0gd3lzaWh0bWw1LlRFWFRfTk9ERSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBhZGphY2VudE5vZGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBDb21wYXJlIGVsZW1lbnQgd2l0aCBpdHMgc2libGluZwogICAgICAgICAgICAgICAgYWRqYWNlbnROb2RlID0gZWxbcHJvcE5hbWVdOwogICAgICAgICAgICAgICAgaWYgKGFkamFjZW50Tm9kZSAmJiB0aGlzLmFyZUVsZW1lbnRzTWVyZ2VhYmxlKG5vZGUsIGFkamFjZW50Tm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZSA9IGFkamFjZW50Tm9kZVtmb3J3YXJkID8gImZpcnN0Q2hpbGQiIDogImxhc3RDaGlsZCJdOwogICAgICAgICAgICAgICAgICAgIGlmICghdGV4dE5vZGVOYW1lcyB8fCB0ZXh0Tm9kZU5hbWVzLmluZGV4T2Yobm9kZS5ub2RlTmFtZSkgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICBhcmVFbGVtZW50c01lcmdlYWJsZSA6IGZ1bmN0aW9uIChlbDEsIGVsMikgewogICAgICAgICAgICByZXR1cm4gcmFuZ3kuZG9tLmFycmF5Q29udGFpbnModGhpcy50YWdOYW1lcywgKGVsMS50YWdOYW1lIHx8ICIiKS50b0xvd2VyQ2FzZSgpKSAmJiByYW5neS5kb20uYXJyYXlDb250YWlucyh0aGlzLnRhZ05hbWVzLCAoZWwyLnRhZ05hbWUgfHwgIiIpLnRvTG93ZXJDYXNlKCkpICYmIGhhc1NhbWVDbGFzc2VzKGVsMSwgZWwyKSAmJiBlbGVtZW50c0hhdmVTYW1lTm9uQ2xhc3NBdHRyaWJ1dGVzKGVsMSwgZWwyKTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVDb250YWluZXIgOiBmdW5jdGlvbiAoZG9jKSB7CiAgICAgICAgICAgIHZhciBlbCA9IGRvYy5jcmVhdGVFbGVtZW50KHRoaXMudGFnTmFtZXNbMF0pOwogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHRoaXMuYXR0cmlidXRlczsKICAgICAgICAgICAgdmFyIGRhdGFBdHRyaWJ1dGVzID0gdGhpcy5kYXRhQXR0cmlidXRlczsKICAgICAgICAgICAgaWYgKHRoaXMuY3NzQ2xhc3MpIHsKICAgICAgICAgICAgICAgIGVsLmNsYXNzTmFtZSA9IHRoaXMuY3NzQ2xhc3M7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIGF0dHJpYnV0ZSBpbiBhdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICBlbC5zdHlsZS5yZW1vdmVQcm9wZXJ0eShhdHRyaWJ1dGUpOwogICAgICAgICAgICAgICAgdmFyIHN0ID0gZWwuZ2V0QXR0cmlidXRlKCdzdHlsZScpOwogICAgICAgICAgICAgICAgaWYgKHN0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgYXR0cmlidXRlICsgIjoiICsgYXR0cmlidXRlc1thdHRyaWJ1dGVdICsgIjsiICsgc3QpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgYXR0cmlidXRlICsgIjoiICsgYXR0cmlidXRlc1thdHRyaWJ1dGVdICsgIjsiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGF0dHJpYnV0ZSBpbiBkYXRhQXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgJChlbCkuZGF0YShhdHRyaWJ1dGUsIGRhdGFBdHRyaWJ1dGVzW2F0dHJpYnV0ZV0pOwogICAgICAgICAgICAgICAgJChlbCkuYXR0cignZGF0YS0nICsgYXR0cmlidXRlLCBkYXRhQXR0cmlidXRlc1thdHRyaWJ1dGVdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZWw7CiAgICAgICAgfSwKCiAgICAgICAgYXBwbHlUb1RleHROb2RlIDogZnVuY3Rpb24gKHRleHROb2RlKSB7CiAgICAgICAgICAgIHZhciBwYXJlbnQgPSB0ZXh0Tm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICBpZiAocGFyZW50LmNoaWxkTm9kZXMubGVuZ3RoID09IDEgJiYgcmFuZ3kuZG9tLmFycmF5Q29udGFpbnModGhpcy50YWdOYW1lcywgcGFyZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSkpIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmNzc0NsYXNzKSB7CiAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MocGFyZW50LCB0aGlzLmNzc0NsYXNzLCB0aGlzLnNpbWlsYXJDbGFzc1JlZ0V4cCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhZGRBdHRyaWJ1dGUocGFyZW50LCB0aGlzLmF0dHJpYnV0ZXMsIHRoaXMuY2xlYXJQcmVTdHlsZSk7CiAgICAgICAgICAgICAgICBhZGREYXRhQXR0cmlidXRlKHBhcmVudCwgdGhpcy5kYXRhQXR0cmlidXRlcywgdGhpcy5jbGVhclByZURhdGFBdHRyKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBlbCA9IHRoaXMuY3JlYXRlQ29udGFpbmVyKHJhbmd5LmRvbS5nZXREb2N1bWVudCh0ZXh0Tm9kZSkpOwogICAgICAgICAgICAgICAgdGV4dE5vZGUucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZWwsIHRleHROb2RlKTsKICAgICAgICAgICAgICAgIGVsLmFwcGVuZENoaWxkKHRleHROb2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGlzUmVtb3ZhYmxlIDogZnVuY3Rpb24gKGVsKSB7CiAgICAgICAgICAgIHJldHVybiByYW5neS5kb20uYXJyYXlDb250YWlucyh0aGlzLnRhZ05hbWVzLCBlbC50YWdOYW1lLnRvTG93ZXJDYXNlKCkpICYmIHd5c2lodG1sNS5sYW5nLnN0cmluZyhlbC5jbGFzc05hbWUpLnRyaW0oKSA9PSB0aGlzLmNzc0NsYXNzOwogICAgICAgIH0sCgogICAgICAgIHVuZG9Ub1RleHROb2RlIDogZnVuY3Rpb24gKHRleHROb2RlLCByYW5nZSwgYW5jZXN0b3JXaXRoQ2xhc3MpIHsKICAgICAgICAgICAgaWYgKCFyYW5nZS5jb250YWluc05vZGUoYW5jZXN0b3JXaXRoQ2xhc3MpKSB7CiAgICAgICAgICAgICAgICAvLyBTcGxpdCBvdXQgdGhlIHBvcnRpb24gb2YgdGhlIGFuY2VzdG9yIGZyb20gd2hpY2ggd2UgY2FuIHJlbW92ZSB0aGUgQ1NTIGNsYXNzCiAgICAgICAgICAgICAgICB2YXIgYW5jZXN0b3JSYW5nZSA9IHJhbmdlLmNsb25lUmFuZ2UoKTsKICAgICAgICAgICAgICAgIGFuY2VzdG9yUmFuZ2Uuc2VsZWN0Tm9kZShhbmNlc3RvcldpdGhDbGFzcyk7CgogICAgICAgICAgICAgICAgaWYgKGFuY2VzdG9yUmFuZ2UuaXNQb2ludEluUmFuZ2UocmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpICYmIGlzU3BsaXRQb2ludChyYW5nZS5lbmRDb250YWluZXIsIHJhbmdlLmVuZE9mZnNldCkpIHsKICAgICAgICAgICAgICAgICAgICBzcGxpdE5vZGVBdChhbmNlc3RvcldpdGhDbGFzcywgcmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpOwogICAgICAgICAgICAgICAgICAgIHJhbmdlLnNldEVuZEFmdGVyKGFuY2VzdG9yV2l0aENsYXNzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChhbmNlc3RvclJhbmdlLmlzUG9pbnRJblJhbmdlKHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydE9mZnNldCkgJiYgaXNTcGxpdFBvaW50KHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydE9mZnNldCkpIHsKICAgICAgICAgICAgICAgICAgICBhbmNlc3RvcldpdGhDbGFzcyA9IHNwbGl0Tm9kZUF0KGFuY2VzdG9yV2l0aENsYXNzLCByYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5zaW1pbGFyQ2xhc3NSZWdFeHApIHsKICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKGFuY2VzdG9yV2l0aENsYXNzLCB0aGlzLnNpbWlsYXJDbGFzc1JlZ0V4cCk7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBhdHRyaWJ1dGUgaW4gdGhpcy5hdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3JXaXRoQ2xhc3Muc3R5bGUucmVtb3ZlUHJvcGVydHkoYXR0cmlidXRlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhpcy5pc1JlbW92YWJsZShhbmNlc3RvcldpdGhDbGFzcykpIHsKICAgICAgICAgICAgICAgIHJlcGxhY2VXaXRoT3duQ2hpbGRyZW4oYW5jZXN0b3JXaXRoQ2xhc3MpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgYXBwbHlUb1JhbmdlIDogZnVuY3Rpb24gKHJhbmdlLCBjb21wb3NlcikgewogICAgICAgICAgICB2YXIgYXBwbGllZCA9IHRoaXMuaGFuZGxlTGlzdFNlbGVjdGlvbihyYW5nZSwgY29tcG9zZXIpOwogICAgICAgICAgICB2YXIgdGV4dE5vZGVzID0gcmFuZ2UuZ2V0Tm9kZXMoW3d5c2lodG1sNS5URVhUX05PREVdKTsKICAgICAgICAgICAgaWYgKCF0ZXh0Tm9kZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHZhciBub2RlID0gdGhpcy5jcmVhdGVDb250YWluZXIocmFuZ2UuZW5kQ29udGFpbmVyLm93bmVyRG9jdW1lbnQpOwogICAgICAgICAgICAgICAgICAgIHJhbmdlLnN1cnJvdW5kQ29udGVudHMobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3ROb2RlKHJhbmdlLCBub2RlKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJhbmdlLnNwbGl0Qm91bmRhcmllcygpOwogICAgICAgICAgICB0ZXh0Tm9kZXMgPSByYW5nZS5nZXROb2Rlcyhbd3lzaWh0bWw1LlRFWFRfTk9ERV0pOwoKICAgICAgICAgICAgaWYgKHRleHROb2Rlcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHZhciB0ZXh0Tm9kZU5hbWVzID0gW107CiAgICAgICAgICAgICAgICBpZiAoY29tcG9zZXIuY29uZmlnLnBhcnNlclJ1bGVzICYmIGNvbXBvc2VyLmNvbmZpZy5wYXJzZXJSdWxlcy50ZXh0Tm9kZXMpIHsKICAgICAgICAgICAgICAgICAgICB0ZXh0Tm9kZU5hbWVzID0gY29tcG9zZXIuY29uZmlnLnBhcnNlclJ1bGVzLnRleHROb2RlczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciB0ZXh0Tm9kZTsKCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gdGV4dE5vZGVzLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgdGV4dE5vZGUgPSB0ZXh0Tm9kZXNbaV07CiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudEVsID0gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KHRleHROb2RlLCB7bm9kZU5hbWUgOiB0ZXh0Tm9kZU5hbWVzfSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudEVsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRleHROb2RlID0gcGFyZW50RWw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5nZXRBbmNlc3Rvcih0ZXh0Tm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBseVRvVGV4dE5vZGUodGV4dE5vZGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0KHRleHROb2Rlc1swXSwgMCk7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZSA9IHRleHROb2Rlc1t0ZXh0Tm9kZXMubGVuZ3RoIC0gMV07CiAgICAgICAgICAgICAgICByYW5nZS5zZXRFbmQodGV4dE5vZGUsIHRleHROb2RlLmxlbmd0aCk7CgogICAgICAgICAgICAgICAgaWYgKHRoaXMubm9ybWFsaXplKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3N0QXBwbHkodGV4dE5vZGVzLCByYW5nZSwgdGV4dE5vZGVOYW1lcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYW5kbGVMaXN0U2VsZWN0aW9uIDogZnVuY3Rpb24gKHJhbmdlLCBjb21wb3NlcikgewogICAgICAgICAgICBub2RlTGlzdCA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXROb2RlcygzKTsKICAgICAgICAgICAgdmFyIGhhbmRsZWRMaXN0U2VsZWN0aW9uID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChub2RlTGlzdC5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOwogICAgICAgICAgICAgICAgICAgICBpIDwgbm9kZUxpc3QubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZUxpc3RbaV07CiAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICBpZiAoKG5vZGUubm9kZU5hbWUgPT0gIkxJIikgJiYgKGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRUZXh0KCkudHJpbSgpID09IG5vZGUudGV4dENvbnRlbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlLmNoaWxkTm9kZXMubGVuZ3RoID09IDEgJiYgcmFuZ3kuZG9tLmFycmF5Q29udGFpbnModGhpcy50YWdOYW1lcywgbm9kZS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jc3NDbGFzcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKG5vZGUsIHRoaXMuY3NzQ2xhc3MsIHRoaXMuc2ltaWxhckNsYXNzUmVnRXhwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZEF0dHJpYnV0ZShub2RlLCB0aGlzLmF0dHJpYnV0ZXMsIHRoaXMuY2xlYXJQcmVTdHlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGREYXRhQXR0cmlidXRlKHBhcmVudCwgdGhpcy5kYXRhQXR0cmlidXRlcywgdGhpcy5jbGVhclByZURhdGFBdHRyKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCF3eXNpaHRtbDUudXRpbC5pc0VkaXRvck5vZGUobm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCEobm9kZS5ub2RlTmFtZSA9PSAiTEkiKSAmJiAhd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKG5vZGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5wYXJlbnRFbGVtZW50OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobm9kZS50ZXh0Q29udGVudCAmJiBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0VGV4dCgpLnRyaW0oKS5pbmRleE9mKG5vZGUudGV4dENvbnRlbnQudHJpbSgpKSA+IC0xKSAmJiAhd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKG5vZGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jc3NDbGFzcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKG5vZGUsIHRoaXMuY3NzQ2xhc3MsIHRoaXMuc2ltaWxhckNsYXNzUmVnRXhwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZEF0dHJpYnV0ZShub2RlLCB0aGlzLmF0dHJpYnV0ZXMsIHRoaXMuY2xlYXJQcmVTdHlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGREYXRhQXR0cmlidXRlKHBhcmVudCwgdGhpcy5kYXRhQXR0cmlidXRlcywgdGhpcy5jbGVhclByZURhdGFBdHRyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZWRMaXN0U2VsZWN0aW9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBzZWxlY3RlZE5vZGUgPSBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKCk7CiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWROb2RlICYmIHNlbGVjdGVkTm9kZSAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoIShzZWxlY3RlZE5vZGUubm9kZU5hbWUgPT0gIkxJIikgJiYgIXd5c2lodG1sNS51dGlsLmlzRWRpdG9yTm9kZShzZWxlY3RlZE5vZGUpICYmIHNlbGVjdGVkTm9kZS5ub2RlTmFtZSAhPSAiI3RleHQiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IHNlbGVjdGVkTm9kZS5wYXJlbnRFbGVtZW50OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvL0NRLTQyMjU2MTQKICAgICAgICAgICAgICAgICAgICBpZiAoY29tcG9zZXIuc2VsZWN0aW9uLmdldFRleHQoKS50cmltKCkuaW5kZXhPZihzZWxlY3RlZE5vZGUudGV4dENvbnRlbnQpID4gLTEgJiYgIXd5c2lodG1sNS51dGlsLmlzRWRpdG9yTm9kZShzZWxlY3RlZE5vZGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNzc0NsYXNzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhzZWxlY3RlZE5vZGUsIHRoaXMuY3NzQ2xhc3MsIHRoaXMuc2ltaWxhckNsYXNzUmVnRXhwKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBhZGRBdHRyaWJ1dGUoc2VsZWN0ZWROb2RlLCB0aGlzLmF0dHJpYnV0ZXMsIHRoaXMuY2xlYXJQcmVTdHlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGFkZERhdGFBdHRyaWJ1dGUocGFyZW50LCB0aGlzLmRhdGFBdHRyaWJ1dGVzLCB0aGlzLmNsZWFyUHJlRGF0YUF0dHIpOwogICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVkTGlzdFNlbGVjdGlvbiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBoYW5kbGVkTGlzdFNlbGVjdGlvbjsKICAgICAgICB9LAoKICAgICAgICB1bmRvVG9SYW5nZSA6IGZ1bmN0aW9uIChyYW5nZSwgY29tcG9zZXIpIHsKICAgICAgICAgICAgdmFyIHRleHROb2RlcyA9IHJhbmdlLmdldE5vZGVzKFt3eXNpaHRtbDUuVEVYVF9OT0RFXSksIHRleHROb2RlLCBhbmNlc3RvcldpdGhDbGFzczsKICAgICAgICAgICAgaWYgKHRleHROb2Rlcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHJhbmdlLnNwbGl0Qm91bmRhcmllcygpOwogICAgICAgICAgICAgICAgdGV4dE5vZGVzID0gcmFuZ2UuZ2V0Tm9kZXMoW3d5c2lodG1sNS5URVhUX05PREVdKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBkb2MgPSByYW5nZS5lbmRDb250YWluZXIub3duZXJEb2N1bWVudCwKICAgICAgICAgICAgICAgICAgICBub2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKHd5c2lodG1sNS5JTlZJU0lCTEVfU1BBQ0UpOwogICAgICAgICAgICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZShub2RlKTsKICAgICAgICAgICAgICAgIHJhbmdlLnNlbGVjdE5vZGUobm9kZSk7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZXMgPSBbbm9kZV07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB0ZXh0Tm9kZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICAgICAgKytpKSB7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZSA9IHRleHROb2Rlc1tpXTsKICAgICAgICAgICAgICAgIGFuY2VzdG9yV2l0aENsYXNzID0gdGhpcy5nZXRBbmNlc3Rvcih0ZXh0Tm9kZSk7CiAgICAgICAgICAgICAgICBpZiAoYW5jZXN0b3JXaXRoQ2xhc3MpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVuZG9Ub1RleHROb2RlKHRleHROb2RlLCByYW5nZSwgYW5jZXN0b3JXaXRoQ2xhc3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAobGVuID09IDEpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0Tm9kZShyYW5nZSwgdGV4dE5vZGVzWzBdKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0KHRleHROb2Rlc1swXSwgMCk7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZSA9IHRleHROb2Rlc1t0ZXh0Tm9kZXMubGVuZ3RoIC0gMV07CiAgICAgICAgICAgICAgICByYW5nZS5zZXRFbmQodGV4dE5vZGUsIHRleHROb2RlLmxlbmd0aCk7CgogICAgICAgICAgICAgICAgaWYgKHRoaXMubm9ybWFsaXplKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3N0QXBwbHkodGV4dE5vZGVzLCByYW5nZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBzZWxlY3ROb2RlIDogZnVuY3Rpb24gKHJhbmdlLCBub2RlKSB7CiAgICAgICAgICAgIHZhciBpc0VsZW1lbnQgPSBub2RlLm5vZGVUeXBlID09PSB3eXNpaHRtbDUuRUxFTUVOVF9OT0RFLAogICAgICAgICAgICAgICAgY2FuSGF2ZUhUTUwgPSAiY2FuSGF2ZUhUTUwiIGluIG5vZGUgPyBub2RlLmNhbkhhdmVIVE1MIDogdHJ1ZSwKICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBpc0VsZW1lbnQgPyBub2RlLmlubmVySFRNTCA6IG5vZGUuZGF0YSwKICAgICAgICAgICAgICAgIGlzRW1wdHkgPSAoY29udGVudCA9PT0gIiIgfHwgY29udGVudCA9PT0gd3lzaWh0bWw1LklOVklTSUJMRV9TUEFDRSk7CgogICAgICAgICAgICBpZiAoaXNFbXB0eSAmJiBpc0VsZW1lbnQgJiYgY2FuSGF2ZUhUTUwpIHsKICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IGNhcmV0IGlzIHZpc2libGUgaW4gbm9kZSBieSBpbnNlcnRpbmcgYSB6ZXJvIHdpZHRoIG5vIGJyZWFraW5nIHNwYWNlCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIG5vZGUuaW5uZXJIVE1MID0gd3lzaWh0bWw1LklOVklTSUJMRV9TUEFDRTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHMobm9kZSk7CiAgICAgICAgICAgIGlmIChpc0VtcHR5ICYmIGlzRWxlbWVudCkgewogICAgICAgICAgICAgICAgcmFuZ2UuY29sbGFwc2UoZmFsc2UpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGlzRW1wdHkpIHsKICAgICAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobm9kZSk7CiAgICAgICAgICAgICAgICByYW5nZS5zZXRFbmRBZnRlcihub2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGdldFRleHRTZWxlY3RlZEJ5UmFuZ2UgOiBmdW5jdGlvbiAodGV4dE5vZGUsIHJhbmdlKSB7CiAgICAgICAgICAgIHZhciB0ZXh0UmFuZ2UgPSByYW5nZS5jbG9uZVJhbmdlKCk7CiAgICAgICAgICAgIHRleHRSYW5nZS5zZWxlY3ROb2RlQ29udGVudHModGV4dE5vZGUpOwoKICAgICAgICAgICAgdmFyIGludGVyc2VjdGlvblJhbmdlID0gdGV4dFJhbmdlLmludGVyc2VjdGlvbihyYW5nZSk7CiAgICAgICAgICAgIHZhciB0ZXh0ID0gaW50ZXJzZWN0aW9uUmFuZ2UgPyBpbnRlcnNlY3Rpb25SYW5nZS50b1N0cmluZygpIDogIiI7CiAgICAgICAgICAgIHRleHRSYW5nZS5kZXRhY2goKTsKCiAgICAgICAgICAgIHJldHVybiB0ZXh0OwogICAgICAgIH0sCgogICAgICAgIGlzQXBwbGllZFRvUmFuZ2VCeUNsYXNzQW5kQXR0cmlidXRlIDogZnVuY3Rpb24gKHJhbmdlKSB7CgogICAgICAgICAgICB2YXIgdGV4dE5vZGVzID0gcmFuZ2UuZ2V0Tm9kZXMoW3d5c2lodG1sNS5URVhUX05PREVdKTsKICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB0aGlzLmF0dHJpYnV0ZXM7CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVWYWx1ZSA9IG5ldyBBcnJheSgpOwogICAgICAgICAgICBpZiAodGV4dE5vZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgdmFyIHRleHROb2RlOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRleHROb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgICAgIHRleHROb2RlID0gdGV4dE5vZGVzW2ldOwogICAgICAgICAgICAgICAgICAgIHdoaWxlICghd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKHRleHROb2RlKSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dE5vZGUgPSB0ZXh0Tm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgaiA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGF0dHJpYnV0ZSBpbiBhdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZVZhbHVlW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRleHROb2RlLnN0eWxlLmdldFByb3BlcnR5VmFsdWUoYXR0cmlidXRlKSA9PSBhdHRyaWJ1dGVzW2F0dHJpYnV0ZV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlVmFsdWVbaisrXSA9ICJ0cnVlIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGF0YUF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoYXR0cmlidXRlIGluIHRoaXMuZGF0YUF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZVZhbHVlW2pdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkKHRleHROb2RlKS5kYXRhKGF0dHJpYnV0ZSkgPT0gdGhpcy5kYXRhQXR0cmlidXRlc1thdHRyaWJ1dGVdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVWYWx1ZVtqKytdID0gInRydWUiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBpID0gMDsKICAgICAgICAgICAgZm9yIChhdHRyaWJ1dGUgaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgaWYgKCFhdHRyaWJ1dGVWYWx1ZVtpKytdKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBhbmNlc3RvcnMgPSBbXSwKICAgICAgICAgICAgICAgIGFuY2VzdG9yLAogICAgICAgICAgICAgICAgdGV4dE5vZGVzID0gcmFuZ2UuZ2V0Tm9kZXMoW3d5c2lodG1sNS5URVhUX05PREVdKTsKICAgICAgICAgICAgaWYgKCF0ZXh0Tm9kZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBhbmNlc3RvciA9IHRoaXMuZ2V0QW5jZXN0b3JXaXRoQXR0cmlidXRlcyhyYW5nZS5zdGFydENvbnRhaW5lcik7CiAgICAgICAgICAgICAgICByZXR1cm4gYW5jZXN0b3IgPyBbYW5jZXN0b3JdIDogZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB0ZXh0Tm9kZXMubGVuZ3RoLCBzZWxlY3RlZFRleHQ7CiAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgIHNlbGVjdGVkVGV4dCA9IHRoaXMuZ2V0VGV4dFNlbGVjdGVkQnlSYW5nZSh0ZXh0Tm9kZXNbaV0sIHJhbmdlKTsKICAgICAgICAgICAgICAgIGFuY2VzdG9yID0gdGhpcy5nZXRBbmNlc3RvcldpdGhBdHRyaWJ1dGVzKHRleHROb2Rlc1tpXSk7CiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWRUZXh0ICE9ICIiICYmICFhbmNlc3RvcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3JzLnB1c2goYW5jZXN0b3IpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBhbmNlc3RvcnM7CiAgICAgICAgfSwKCiAgICAgICAgaXNBcHBsaWVkVG9SYW5nZSA6IGZ1bmN0aW9uIChyYW5nZSkgewoKICAgICAgICAgICAgdmFyIGFuY2VzdG9ycyA9IFtdLAogICAgICAgICAgICAgICAgYW5jZXN0b3IsCiAgICAgICAgICAgICAgICB0ZXh0Tm9kZXMgPSByYW5nZS5nZXROb2Rlcyhbd3lzaWh0bWw1LlRFWFRfTk9ERV0pOwogICAgICAgICAgICBpZiAoIXRleHROb2Rlcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIGFuY2VzdG9yID0gdGhpcy5nZXRBbmNlc3RvcihyYW5nZS5zdGFydENvbnRhaW5lcik7CiAgICAgICAgICAgICAgICByZXR1cm4gYW5jZXN0b3IgPyBbYW5jZXN0b3JdIDogZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB0ZXh0Tm9kZXMubGVuZ3RoLCBzZWxlY3RlZFRleHQ7CiAgICAgICAgICAgICAgICAgaSA8IGxlbjsKICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgIHNlbGVjdGVkVGV4dCA9IHRoaXMuZ2V0VGV4dFNlbGVjdGVkQnlSYW5nZSh0ZXh0Tm9kZXNbaV0sIHJhbmdlKTsKICAgICAgICAgICAgICAgIGFuY2VzdG9yID0gdGhpcy5nZXRBbmNlc3Rvcih0ZXh0Tm9kZXNbaV0pOwogICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkVGV4dCAhPSAiIiAmJiAhYW5jZXN0b3IpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGFuY2VzdG9ycy5wdXNoKGFuY2VzdG9yKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYW5jZXN0b3JzOwogICAgICAgIH0sCgogICAgICAgIHRvZ2dsZVJhbmdlIDogZnVuY3Rpb24gKHJhbmdlLCBjb21wb3NlcikgewogICAgICAgICAgICB2YXIgaXNBcHBseSA9IGZhbHNlOwogICAgICAgICAgICBpZiAodGhpcy5hdHRyaWJ1dGVzIHx8IHRoaXMuZGF0YUF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICAgIGlzQXBwbHkgPSB0aGlzLmlzQXBwbGllZFRvUmFuZ2VCeUNsYXNzQW5kQXR0cmlidXRlKHJhbmdlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlzQXBwbHkgPSB0aGlzLmlzQXBwbGllZFRvUmFuZ2UocmFuZ2UpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXNBcHBseSkgewogICAgICAgICAgICAgICAgdGhpcy51bmRvVG9SYW5nZShyYW5nZSwgY29tcG9zZXIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5hcHBseVRvUmFuZ2UocmFuZ2UsIGNvbXBvc2VyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgd3lzaWh0bWw1LnNlbGVjdGlvbi5IVE1MQXBwbGllciA9IEhUTUxBcHBsaWVyOwp9KSh3eXNpaHRtbDUsIHJhbmd5KTsKLyoqCiAqIFJpY2ggVGV4dCBRdWVyeS9Gb3JtYXR0aW5nIENvbW1hbmRzCiAqCiAqIEBleGFtcGxlCiAqICAgIHZhciBjb21tYW5kcyA9IG5ldyB3eXNpaHRtbDUuQ29tbWFuZHMoZWRpdG9yKTsKICovCnd5c2lodG1sNS5Db21tYW5kcyA9IEJhc2UuZXh0ZW5kKAogICAgLyoqIEBzY29wZSB3eXNpaHRtbDUuQ29tbWFuZHMucHJvdG90eXBlICovIHsKICAgICAgICBjb25zdHJ1Y3RvciA6IGZ1bmN0aW9uIChlZGl0b3IpIHsKICAgICAgICAgICAgdGhpcy5lZGl0b3IgPSBlZGl0b3I7CiAgICAgICAgICAgIHRoaXMuY29tcG9zZXIgPSBlZGl0b3IuY29tcG9zZXI7CiAgICAgICAgICAgIHRoaXMuZG9jID0gdGhpcy5jb21wb3Nlci5kb2M7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2sgd2hldGhlciB0aGUgYnJvd3NlciBzdXBwb3J0cyB0aGUgZ2l2ZW4gY29tbWFuZAogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGNvbW1hbmQgVGhlIGNvbW1hbmQgc3RyaW5nIHdoaWNoIHRvIGNoZWNrIChlZy4gImJvbGQiLCAiaXRhbGljIiwgImluc2VydFVub3JkZXJlZExpc3QiKQogICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICogICAgY29tbWFuZHMuc3VwcG9ydHMoImNyZWF0ZUxpbmsiKTsKICAgICAgICAgKi8KICAgICAgICBzdXBwb3J0IDogZnVuY3Rpb24gKGNvbW1hbmQpIHsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5icm93c2VyLnN1cHBvcnRzQ29tbWFuZCh0aGlzLmRvYywgY29tbWFuZCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2sgd2hldGhlciB0aGUgYnJvd3NlciBzdXBwb3J0cyB0aGUgZ2l2ZW4gY29tbWFuZAogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGNvbW1hbmQgVGhlIGNvbW1hbmQgc3RyaW5nIHdoaWNoIHRvIGV4ZWN1dGUgKGVnLiAiYm9sZCIsICJpdGFsaWMiLCAiaW5zZXJ0VW5vcmRlcmVkTGlzdCIpCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IFt2YWx1ZV0gVGhlIGNvbW1hbmQgdmFsdWUgcGFyYW1ldGVyLCBuZWVkZWQgZm9yIHNvbWUgY29tbWFuZHMgKCJjcmVhdGVMaW5rIiwgImluc2VydEltYWdlIiwgLi4uKSwgb3B0aW9uYWwgZm9yIGNvbW1hbmRzIHRoYXQgZG9uJ3QgcmVxdWlyZSBvbmUgKCJib2xkIiwgInVuZGVybGluZSIsIC4uLikKICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAqICAgIGNvbW1hbmRzLmV4ZWMoImluc2VydEltYWdlIiwgImh0dHA6Ly9hMS50d2ltZy5jb20vcHJvZmlsZV9pbWFnZXMvMTEzODY4NjU1L3NjaHJlaV90d2l0dGVyX3JlYXNvbmFibHlfc21hbGwuanBnIik7CiAgICAgICAgICovCiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21tYW5kLCB2YWx1ZSwgYWxsb3dVbmRvKSB7CiAgICAgICAgICAgIHZhciBvYmogPSB3eXNpaHRtbDUuY29tbWFuZHNbY29tbWFuZF0sCiAgICAgICAgICAgICAgICBhcmdzID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoYXJndW1lbnRzKS5nZXQoKSwKICAgICAgICAgICAgICAgIG1ldGhvZCA9IG9iaiAmJiBvYmouZXhlYywKICAgICAgICAgICAgICAgIGZvY3VzID0gb2JqICYmIG9iai5mb2N1cywKICAgICAgICAgICAgICAgIHJlc3VsdCA9IG51bGw7CgogICAgICAgICAgICBpZiAoYWxsb3dVbmRvID09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgYWxsb3dVbmRvID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZm9jdXMgPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICBmb2N1cyA9IHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChhbGxvd1VuZG8pIHsKICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yLmZpcmUoImJlZm9yZWNvbW1hbmQ6Y29tcG9zZXIiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG1ldGhvZCkgewogICAgICAgICAgICAgICAgYXJncy51bnNoaWZ0KHRoaXMuY29tcG9zZXIpOwogICAgICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgY29tcG9zZXIgaXMgZm9jdXNzZWQgKGZhbHNlID0+IGRvbid0IG1vdmUgY2FyZXQgdG8gdGhlIGVuZCkKICAgICAgICAgICAgICAgIHZhciByYW5nZSA9IHRoaXMuY29tcG9zZXIuc2VsZWN0aW9uLmdldFJhbmdlKCk7CiAgICAgICAgICAgICAgICBpZiAoZm9jdXMpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmVkaXRvci5mb2N1cyhmYWxzZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZm9jdXMgJiYgdGhpcy5lZGl0b3Iuc2F2ZWRTZWxlY3Rpb24gJiYgIXJhbmdlKSB7Ly8gRml4aW5nIExDLTM5MTE5OTQKICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyLnNlbGVjdGlvbi5zZXRTZWxlY3Rpb24odGhpcy5lZGl0b3Iuc2F2ZWRTZWxlY3Rpb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmVzdWx0ID0gbWV0aG9kLmFwcGx5KG9iaiwgYXJncyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIC8vIHRyeS9jYXRjaCBmb3IgYnVnZ3kgZmlyZWZveAogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHRoaXMuZG9jLmV4ZWNDb21tYW5kKGNvbW1hbmQsIGZhbHNlLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuZWRpdG9yLmZpcmUoImFmdGVyY29tbWFuZDpjb21wb3NlciIpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrIHdoZXRoZXIgdGhlIGN1cnJlbnQgY29tbWFuZCBpcyBhY3RpdmUKICAgICAgICAgKiBJZiB0aGUgY2FyZXQgaXMgd2l0aGluIGEgYm9sZCB0ZXh0LCB0aGVuIGNhbGxpbmcgdGhpcyB3aXRoIGNvbW1hbmQgImJvbGQiIHNob3VsZCByZXR1cm4gdHJ1ZQogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGNvbW1hbmQgVGhlIGNvbW1hbmQgc3RyaW5nIHdoaWNoIHRvIGNoZWNrIChlZy4gImJvbGQiLCAiaXRhbGljIiwgImluc2VydFVub3JkZXJlZExpc3QiKQogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBbY29tbWFuZFZhbHVlXSBUaGUgY29tbWFuZCB2YWx1ZSBwYXJhbWV0ZXIgKGVnLiBmb3IgImluc2VydEltYWdlIiB0aGUgaW1hZ2Ugc3JjKQogICAgICAgICAqIEByZXR1cm4ge0Jvb2xlYW59IFdoZXRoZXIgdGhlIGNvbW1hbmQgaXMgYWN0aXZlCiAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgKiAgICB2YXIgaXNDdXJyZW50U2VsZWN0aW9uQm9sZCA9IGNvbW1hbmRzLnN0YXRlKCJib2xkIik7CiAgICAgICAgICovCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tbWFuZCwgY29tbWFuZFZhbHVlKSB7CiAgICAgICAgICAgIHZhciBvYmogPSB3eXNpaHRtbDUuY29tbWFuZHNbY29tbWFuZF0sCiAgICAgICAgICAgICAgICBhcmdzID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoYXJndW1lbnRzKS5nZXQoKSwKICAgICAgICAgICAgICAgIG1ldGhvZCA9IG9iaiAmJiBvYmouc3RhdGU7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmNhbGxTdGF0ZUZ1bmN0aW9uKG1ldGhvZCwgb2JqLCBhcmdzLCBjb21tYW5kKTsKICAgICAgICB9LAoKICAgICAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbW1hbmQsIGNvbW1hbmRWYWx1ZSwgaXNEZWZhdWx0KSB7CiAgICAgICAgICAgIHZhciBvYmogPSB3eXNpaHRtbDUuY29tbWFuZHNbY29tbWFuZF0sCiAgICAgICAgICAgICAgICBhcmdzID0gd3lzaWh0bWw1LmxhbmcuYXJyYXkoYXJndW1lbnRzKS5nZXQoKSwgbWV0aG9kOwogICAgICAgICAgICBpZiAob2JqICYmIG9iai5jYWxsYmFja1N0YXRlKSB7CiAgICAgICAgICAgICAgICBtZXRob2QgPSBvYmogJiYgb2JqLmNhbGxiYWNrU3RhdGU7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jYWxsU3RhdGVGdW5jdGlvbihtZXRob2QsIG9iaiwgYXJncywgY29tbWFuZCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZShjb21tYW5kLCBjb21tYW5kVmFsdWUsIGlzRGVmYXVsdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBjYWxsU3RhdGVGdW5jdGlvbiA6IGZ1bmN0aW9uIChtZXRob2QsIG9iaiwgYXJncywgY29tbWFuZCkgewogICAgICAgICAgICBpZiAobWV0aG9kKSB7CiAgICAgICAgICAgICAgICBhcmdzLnVuc2hpZnQodGhpcy5jb21wb3Nlcik7CiAgICAgICAgICAgICAgICByZXR1cm4gbWV0aG9kLmFwcGx5KG9iaiwgYXJncyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIC8vIHRyeS9jYXRjaCBmb3IgYnVnZ3kgZmlyZWZveAogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRvYy5xdWVyeUNvbW1hbmRTdGF0ZShjb21tYW5kKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKd3lzaWh0bWw1LmNvbW1hbmRzLmJvbGQgPSB7CiAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgImIiKTsKICAgIH0sCgogICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICAvLyBlbGVtZW50Lm93bmVyRG9jdW1lbnQucXVlcnlDb21tYW5kU3RhdGUoImJvbGQiKSByZXN1bHRzOgogICAgICAgIC8vIGZpcmVmb3g6IG9ubHkgPGI+CiAgICAgICAgLy8gY2hyb21lOiAgPGI+LCA8c3Ryb25nPiwgPGgxPiwgPGgyPiwgLi4uCiAgICAgICAgLy8gaWU6ICAgICAgPGI+LCA8c3Ryb25nPgogICAgICAgIC8vIG9wZXJhOiAgIDxiPiwgPHN0cm9uZz4KICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgImIiKTsKICAgIH0KfTsKCnd5c2lodG1sNS5jb21tYW5kcy5zdXBlclNjcmlwdCA9IHsKICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICB2YXIgZG9jID0gY29tcG9zZXIuZG9jLAogICAgICAgICAgICBzZWxlY3RlZE5vZGUgPSBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKCksCiAgICAgICAgICAgIHN1YnNjcmlwdCA9IHNlbGVjdGVkTm9kZS5wYXJlbnROb2RlLm5vZGVOYW1lOwogICAgICAgIGlmIChjb21wb3Nlci5jb21tYW5kcy5zdXBwb3J0KGNvbW1hbmQpKSB7CiAgICAgICAgICAgIGNvbXBvc2VyLmRvYy5leGVjQ29tbWFuZChjb21tYW5kLCBmYWxzZSwgbnVsbCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKHN1YnNjcmlwdCAmJiBzdWJzY3JpcHQgPT0gIlNVQiIpIHsKICAgICAgICAgICAgICAgIHZhciBlbCA9IGNvbXBvc2VyLnNlbGVjdGlvbi5leGVjdXRlQW5kUmVzdG9yZShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5yZW5hbWVFbGVtZW50KHNlbGVjdGVkTm9kZS5wYXJlbnROb2RlLCAic3VwIik7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgInN1cCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwKCiAgICBzdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAic3VwIik7CiAgICB9Cn07Cgp3eXNpaHRtbDUuY29tbWFuZHMuc3ViU2NyaXB0ID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgIHZhciBkb2MgPSBjb21wb3Nlci5kb2MsCiAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKSwKICAgICAgICAgICAgc3VwZXJzY3JpcHQgPSBzZWxlY3RlZE5vZGUucGFyZW50Tm9kZS5ub2RlTmFtZTsKICAgICAgICBpZiAoY29tcG9zZXIuY29tbWFuZHMuc3VwcG9ydChjb21tYW5kKSkgewogICAgICAgICAgICBjb21wb3Nlci5kb2MuZXhlY0NvbW1hbmQoY29tbWFuZCwgZmFsc2UsIG51bGwpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChzdXBlcnNjcmlwdCAmJiBzdXBlcnNjcmlwdCA9PSAiU1VQIikgewogICAgICAgICAgICAgICAgdmFyIGVsID0gY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUuZG9tLnJlbmFtZUVsZW1lbnQoc2VsZWN0ZWROb2RlLnBhcmVudE5vZGUsICJzdWIiKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5leGVjKGNvbXBvc2VyLCBjb21tYW5kLCAic3ViIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsICJzdWIiKTsKICAgIH0KfTsKCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgdW5kZWYsCiAgICAgICAgTk9ERV9OQU1FID0gIkEiLAogICAgICAgIGRvbSA9IHd5c2lodG1sNS5kb207CgogICAgZnVuY3Rpb24gX3JlbW92ZUZvcm1hdChjb21wb3NlciwgYW5jaG9ycykgewogICAgICAgIHZhciBsZW5ndGggPSBhbmNob3JzLmxlbmd0aCwKICAgICAgICAgICAgaSA9IDAsCiAgICAgICAgICAgIGFuY2hvciwKICAgICAgICAgICAgY29kZUVsZW1lbnQsCiAgICAgICAgICAgIHRleHRDb250ZW50OwogICAgICAgIGZvciAoOwogICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgYW5jaG9yID0gYW5jaG9yc1tpXTsKICAgICAgICAgICAgY29kZUVsZW1lbnQgPSBkb20uZ2V0UGFyZW50RWxlbWVudChhbmNob3IsIHtub2RlTmFtZSA6ICJjb2RlIn0pOwogICAgICAgICAgICB0ZXh0Q29udGVudCA9IGRvbS5nZXRUZXh0Q29udGVudChhbmNob3IpOwoKICAgICAgICAgICAgLy8gaWYgPGE+IGNvbnRhaW5zIHVybC1saWtlIHRleHQgY29udGVudCwgcmVuYW1lIGl0IHRvIDxjb2RlPiB0byBwcmV2ZW50IHJlLWF1dG9saW5raW5nCiAgICAgICAgICAgIC8vIGVsc2UgcmVwbGFjZSA8YT4gd2l0aCBpdHMgY2hpbGROb2RlcwogICAgICAgICAgICBpZiAodGV4dENvbnRlbnQubWF0Y2goZG9tLmF1dG9MaW5rLlVSTF9SRUdfRVhQKSAmJiAhY29kZUVsZW1lbnQpIHsKICAgICAgICAgICAgICAgIC8vIDxjb2RlPiBlbGVtZW50IGlzIHVzZWQgdG8gcHJldmVudCBsYXRlciBhdXRvLWxpbmtpbmcgb2YgdGhlIGNvbnRlbnQKICAgICAgICAgICAgICAgIGNvZGVFbGVtZW50ID0gZG9tLnJlbmFtZUVsZW1lbnQoYW5jaG9yLCAiY29kZSIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZG9tLnJlcGxhY2VXaXRoQ2hpbGROb2RlcyhhbmNob3IpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIF9mb3JtYXQoY29tcG9zZXIsIGF0dHJpYnV0ZXMpIHsKICAgICAgICB2YXIgZG9jID0gY29tcG9zZXIuZG9jLAogICAgICAgICAgICB0ZW1wQ2xhc3MgPSAiX3d5c2lodG1sNS10ZW1wLSIgKyAoK25ldyBEYXRlKCkpLAogICAgICAgICAgICB0ZW1wQ2xhc3NSZWdFeHAgPSAvbm9uLW1hdGNoaW5nLWNsYXNzL2csCiAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICBsZW5ndGgsCiAgICAgICAgICAgIGFuY2hvcnMsCiAgICAgICAgICAgIGFuY2hvciwKICAgICAgICAgICAgaGFzRWxlbWVudENoaWxkLAogICAgICAgICAgICBpc0VtcHR5LAogICAgICAgICAgICBlbGVtZW50VG9TZXRDYXJldEFmdGVyLAogICAgICAgICAgICB0ZXh0Q29udGVudCwKICAgICAgICAgICAgd2hpdGVTcGFjZSwKICAgICAgICAgICAgajsKICAgICAgICB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLmV4ZWMoY29tcG9zZXIsIHVuZGVmLCBOT0RFX05BTUUsIHRlbXBDbGFzcywgdGVtcENsYXNzUmVnRXhwKTsKCiAgICAgICAgdmFyIG5ld1RleHQgPSBudWxsOwogICAgICAgIGlmIChhdHRyaWJ1dGVzICYmIGF0dHJpYnV0ZXMuYWx0KSB7CiAgICAgICAgICAgIG5ld1RleHQgPSBhdHRyaWJ1dGVzLmFsdDsKICAgICAgICAgICAgZGVsZXRlIGF0dHJpYnV0ZXMuYWx0OwogICAgICAgIH0KCiAgICAgICAgYW5jaG9ycyA9IGRvYy5xdWVyeVNlbGVjdG9yQWxsKE5PREVfTkFNRSArICIuIiArIHRlbXBDbGFzcyk7CiAgICAgICAgbGVuZ3RoID0gYW5jaG9ycy5sZW5ndGg7CiAgICAgICAgZm9yICg7CiAgICAgICAgICAgIGkgPCBsZW5ndGg7CiAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICBhbmNob3IgPSBhbmNob3JzW2ldOwogICAgICAgICAgICBhbmNob3IucmVtb3ZlQXR0cmlidXRlKCJjbGFzcyIpOwogICAgICAgICAgICBmb3IgKGogaW4gYXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgYW5jaG9yLnNldEF0dHJpYnV0ZShqLCBhdHRyaWJ1dGVzW2pdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobmV3VGV4dCkgewogICAgICAgICAgICAgICAgYW5jaG9yLnRleHQgPSBuZXdUZXh0OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBlbGVtZW50VG9TZXRDYXJldEFmdGVyID0gYW5jaG9yOwogICAgICAgIGlmIChsZW5ndGggPT09IDEpIHsKICAgICAgICAgICAgdGV4dENvbnRlbnQgPSBkb20uZ2V0VGV4dENvbnRlbnQoYW5jaG9yKTsKICAgICAgICAgICAgaGFzRWxlbWVudENoaWxkID0gISFhbmNob3IucXVlcnlTZWxlY3RvcigiKiIpOwogICAgICAgICAgICBpc0VtcHR5ID0gdGV4dENvbnRlbnQgPT09ICIiIHx8IHRleHRDb250ZW50ID09PSB3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFOwogICAgICAgICAgICBpZiAoIWhhc0VsZW1lbnRDaGlsZCAmJiBpc0VtcHR5KSB7CiAgICAgICAgICAgICAgICBkb20uc2V0VGV4dENvbnRlbnQoYW5jaG9yLCBhdHRyaWJ1dGVzLnRleHQgfHwgYW5jaG9yLmhyZWYpOwogICAgICAgICAgICAgICAgd2hpdGVTcGFjZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSgiICIpOwogICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLnNldEFmdGVyKGFuY2hvcik7CiAgICAgICAgICAgICAgICBkb20uaW5zZXJ0KHdoaXRlU3BhY2UpLmFmdGVyKGFuY2hvcik7CiAgICAgICAgICAgICAgICBlbGVtZW50VG9TZXRDYXJldEFmdGVyID0gd2hpdGVTcGFjZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2V0QWZ0ZXIoZWxlbWVudFRvU2V0Q2FyZXRBZnRlcik7CiAgICB9CgogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmNyZWF0ZUxpbmsgPSB7CiAgICAgICAgLyoqCiAgICAgICAgICogVE9ETzogVXNlIEhUTUxBcHBsaWVyIG9yIGZvcm1hdElubGluZSBoZXJlCiAgICAgICAgICoKICAgICAgICAgKiBUdXJucyBzZWxlY3Rpb24gaW50byBhIGxpbmsKICAgICAgICAgKiBJZiBzZWxlY3Rpb24gaXMgYWxyZWFkeSBhIGxpbmssIGl0IHJlbW92ZXMgdGhlIGxpbmsgYW5kIHdyYXBzIGl0IHdpdGggYSA8Y29kZT4gZWxlbWVudAogICAgICAgICAqIFRoZSA8Y29kZT4gZWxlbWVudCBpcyBuZWVkZWQgdG8gYXZvaWQgYXV0byBsaW5raW5nCiAgICAgICAgICoKICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAqICAgIC8vIGVpdGhlciAuLi4KICAgICAgICAgKiAgICB3eXNpaHRtbDUuY29tbWFuZHMuY3JlYXRlTGluay5leGVjKGNvbXBvc2VyLCAiY3JlYXRlTGluayIsICJodHRwOi8vd3d3Lmdvb2dsZS5kZSIpOwogICAgICAgICAqICAgIC8vIC4uLiBvciAuLi4KICAgICAgICAgKiAgICB3eXNpaHRtbDUuY29tbWFuZHMuY3JlYXRlTGluay5leGVjKGNvbXBvc2VyLCAiY3JlYXRlTGluayIsIHsgaHJlZjogImh0dHA6Ly93d3cuZ29vZ2xlLmRlIiwgdGFyZ2V0OiAiX2JsYW5rIiB9KTsKICAgICAgICAgKi8KICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCB2YWx1ZSwgYWx0LCB0YXJnZXQpIHsKICAgICAgICAgICAgdmFyIGFuY2hvcnMgPSB0aGlzLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kKTsKICAgICAgICAgICAgLy8gaWYgKGFuY2hvcnMpIHsKICAgICAgICAgICAgLy8gU2VsZWN0aW9uIGNvbnRhaW5zIGxpbmtzCiAgICAgICAgICAgIC8vICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uKCkgewogICAgICAgICAgICAvLyAgICAgX3JlbW92ZUZvcm1hdChjb21wb3NlciwgYW5jaG9ycyk7CiAgICAgICAgICAgIC8vICAgfSk7CiAgICAgICAgICAgIC8vIH0KICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gIm9iamVjdCIpIHsKICAgICAgICAgICAgICAgIGFsdCA9IHZhbHVlLmFsdDsKICAgICAgICAgICAgICAgIHRhcmdldCA9IHZhbHVlLnRhcmdldCA/ICJfdGFyZ2V0IiA6ICIiOwogICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS51cmw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgICAgICAoYW5jaG9ycyAmJiAoaSA8IGFuY2hvcnMubGVuZ3RoKSk7CiAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICB2YXIgYW5jaG9yID0gYW5jaG9yc1tpXTsKICAgICAgICAgICAgICAgIGFuY2hvci5ocmVmID0gdmFsdWU7CiAgICAgICAgICAgICAgICBhbmNob3IudGl0bGUgPSAiTGluazogIiArIHZhbHVlOwogICAgICAgICAgICAgICAgYW5jaG9yLmFsdCA9IGFsdDsKICAgICAgICAgICAgICAgIGFuY2hvci50YXJnZXQgPSB0YXJnZXQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFhbmNob3JzKSB7CiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgbGlua3MKICAgICAgICAgICAgICAgIHZhbHVlID0gdHlwZW9mKHZhbHVlKSA9PT0gIm9iamVjdCIgPyB2YWx1ZSA6IHtocmVmIDogdmFsdWUsIGFsdCA6IGFsdCwgdGFyZ2V0IDogdGFyZ2V0fTsKICAgICAgICAgICAgICAgIF9mb3JtYXQoY29tcG9zZXIsIHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAiQSIpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBkb2N1bWVudC5leGVjQ29tbWFuZCgiZm9udFNpemUiKSB3aWxsIGNyZWF0ZSBlaXRoZXIgaW5saW5lIHN0eWxlcyAoZmlyZWZveCwgY2hyb21lKSBvciB1c2UgZm9udCB0YWdzCiAqIHdoaWNoIHdlIGRvbid0IHdhbnQKICogSW5zdGVhZCB3ZSBzZXQgYSBjc3MgY2xhc3MKICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgdW5kZWYsCiAgICAgICAgUkVHX0VYUCA9IC9mb250LXNpemUvZzsKCiAgICB3eXNpaHRtbDUuY29tbWFuZHMuZm9udFNpemUgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgc2l6ZSkgewogICAgICAgICAgICBzaXplID0gc2l6ZSArICJwdCI7CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJmb250LXNpemUiIDogc2l6ZX07CiAgICAgICAgICAgIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAiZm9udC1zaXplIiwgUkVHX0VYUCwgYXR0cmlidXRlcyk7CiAgICAgICAgICAgIHZhciBkb21FbGVtID0gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdEJsb2NrLnN0YXRlKGNvbXBvc2VyLCAnbGluZUhlaWdodCcsIGF0dHJpYnV0ZXMpOwogICAgICAgICAgICB2YXIgbGVhZGluZzsKICAgICAgICAgICAgaWYgKGRvbUVsZW0gJiYgZG9tRWxlbS5nZXRBdHRyaWJ1dGUpIHsKICAgICAgICAgICAgICAgIGxlYWRpbmcgPSAoZG9tRWxlbSkuZ2V0QXR0cmlidXRlKCJsZWFkaW5nIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgd3lzaWh0bWw1LnV0aWwuY2hhbmdlTGluZUhlaWdodChsZWFkaW5nLCBmYWxzZSwgJ1AnLCBjb21wb3Nlcik7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIHNpemUpIHsKICAgICAgICAgICAgaWYgKHNpemUpIHsKICAgICAgICAgICAgICAgIHNpemUgPSBzaXplICsgInB0IjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiZm9udC1zaXplIiA6IHNpemV9OwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAiZm9udC1zaXplIiwgUkVHX0VYUCwgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKICAgICAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBzaXplKSB7CiAgICAgICAgICAgIHZhciBkb21FbGVtID0gdGhpcy5zdGF0ZShjb21wb3NlciwgY29tbWFuZCk7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IFtdOwogICAgICAgICAgICAvLyBkb21FbGVtZW50IGkuZSBTZWxlY3RlZCB0ZXh0IG5vZGVzIGV4aXN0CiAgICAgICAgICAgIGlmIChkb21FbGVtICYmIGRvbUVsZW0ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRvbUVsZW0ubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAvLyBnZXR0aW5nIGRpZmZlcmVudCBmb250IHNpemVzIGFwcGxpZWQgdG8gc2VsZWN0ZWQgdGV4dHMKICAgICAgICAgICAgICAgICAgICB2YXIgZm9udFNpemUgPSAgd3lzaWh0bWw1LmhlbHBlckZuLmdldFByb3BlcnR5VmFsdWUoZG9tRWxlbVtpXSwgImZvbnQtc2l6ZSIpOwogICAgICAgICAgICAgICAgICAgIC8vIGZvbnQgc2l6ZSBpcyBub3QgYWxyZWFkeSByZXRyaWV2ZWQgZnJvbSBzZWxlY3RlZCB0ZXh0cywgYWRkIGZvbnQgc2l6ZQogICAgICAgICAgICAgICAgICAgIGlmICghdmFsdWUuaW5jbHVkZXMoZm9udFNpemUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLnB1c2goZm9udFNpemUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgfSwKICAgICAgICB2YWx1ZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHVuZGVmOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBkb2N1bWVudC5leGVjQ29tbWFuZCgiICAgICIpIHdpbGwgY3JlYXRlIGVpdGhlciBpbmxpbmUgc3R5bGVzIChmaXJlZm94LCBjaHJvbWUpIG9yIHVzZSBmb250IHRhZ3MKICogd2hpY2ggd2UgZG9uJ3Qgd2FudAogKiBJbnN0ZWFkIHdlIHNldCBhIGNzcyBjbGFzcwogKi8KKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBSRUdfRVhQID0gL3d5c2l3eWctY29sb3ItWzAtOWEtel0rL2c7CgogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmZvcmVDb2xvciA9IHsKICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBjb2xvcikgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiY29sb3IiIDogY29sb3J9OwoKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAid3lzaXd5Zy1jb2xvci0iICsgY29sb3IsIFJFR19FWFAsIGF0dHJpYnV0ZXMpOwogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBjb2xvcikgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiY29sb3IiIDogY29sb3J9OwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAid3lzaXd5Zy1jb2xvci0iICsgY29sb3IsIFJFR19FWFAsIGF0dHJpYnV0ZXMpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgZG9tID0gd3lzaWh0bWw1LmRvbSwKICAgICAgICAvLyBGb2xsb3dpbmcgZWxlbWVudHMgYXJlIGdyb3VwZWQKICAgICAgICAvLyB3aGVuIHRoZSBjYXJldCBpcyB3aXRoaW4gYSBIMSBhbmQgdGhlIEg0IGlzIGludm9rZWQsIHRoZSBIMSBzaG91bGQgdHVybiBpbnRvIEg0CiAgICAgICAgLy8gaW5zdGVhZCBvZiBjcmVhdGluZyBhIEg0IHdpdGhpbiBhIEgxIHdoaWNoIHdvdWxkIHJlc3VsdCBpbiBzZW1hbnRpY2FsbHkgaW52YWxpZCBodG1sCiAgICAgICAgQkxPQ0tfRUxFTUVOVFNfR1JPVVAgPSBbIkgxIiwgIkgyIiwgIkgzIiwgIkg0IiwgIkg1IiwgIkg2IiwgIlAiLCAiQkxPQ0tRVU9URSIsICJESVYiXTsKCiAgICAvKioKICAgICAqIFJlbW92ZSBzaW1pbGlhciBjbGFzc2VzIChiYXNlZCBvbiBjbGFzc1JlZ0V4cCkKICAgICAqIGFuZCBhZGQgdGhlIGRlc2lyZWQgY2xhc3MgbmFtZQogICAgICovCiAgICBmdW5jdGlvbiBfYWRkQ2xhc3MoZWxlbWVudCwgY2xhc3NOYW1lLCBjbGFzc1JlZ0V4cCkgewogICAgICAgIGlmIChlbGVtZW50LmNsYXNzTmFtZSkgewogICAgICAgICAgICBfcmVtb3ZlQ2xhc3MoZWxlbWVudCwgY2xhc3NSZWdFeHApOwogICAgICAgICAgICBlbGVtZW50LmNsYXNzTmFtZSArPSAiICIgKyBjbGFzc05hbWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSBjbGFzc05hbWU7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIF9hZGRBdHRyaWJ1dGUoZWxlbWVudCkgewogICAgICAgIHZhciBhdHRyaWJ1dGVzID0gdGhpcy5hdHRyaWJ1dGVzOwogICAgICAgIGlmIChlbGVtZW50KSB7CiAgICAgICAgICAgIGlmICh0aGlzLmNsZWFyUHJlU3R5bGUpIHsKICAgICAgICAgICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCJzdHlsZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAodmFyIGF0dHJpYnV0ZSBpbiBhdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5zdHlsZSkgewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUucmVtb3ZlUHJvcGVydHkoYXR0cmlidXRlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciBzdCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdzdHlsZScpOwogICAgICAgICAgICAgICAgaWYgKHN0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnc3R5bGUnLCBhdHRyaWJ1dGUgKyAiOiIgKyBhdHRyaWJ1dGVzW2F0dHJpYnV0ZV0gKyAiOyIgKyBzdCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdzdHlsZScsIGF0dHJpYnV0ZSArICI6IiArIGF0dHJpYnV0ZXNbYXR0cmlidXRlXSArICI7Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZERhdGFBdHRyaWJ1dGUoZWxlbWVudCkgewogICAgICAgIGlmIChlbGVtZW50KSB7CiAgICAgICAgICAgIHZhciBkYXRhQXR0cmlidXRlcyA9IHRoaXMuZGF0YUF0dHJpYnV0ZXM7CiAgICAgICAgICAgIGlmICh0aGlzLmNsZWFyUHJlRGF0YUF0dHIgJiYgJChlbGVtZW50KS5kYXRhKCkpIHsKICAgICAgICAgICAgICAgIHZhciBkYXRhID0gJChlbGVtZW50KS5kYXRhKCk7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gZGF0YSkgewogICAgICAgICAgICAgICAgICAgICQoZWxlbWVudCkucmVtb3ZlRGF0YShrZXkpOwogICAgICAgICAgICAgICAgICAgICQoZWwpLnJlbW92ZUF0dHIoImRhdGEtIiArIGtleSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yICh2YXIgYXR0cmlidXRlIGluIGRhdGFBdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgICAgICAkKGVsZW1lbnQpLmRhdGEoYXR0cmlidXRlLCBhdHRyaWJ1dGVzW2F0dHJpYnV0ZV0pOwogICAgICAgICAgICAgICAgJChlbGVtZW50KS5hdHRyKCdkYXRhLScgKyBhdHRyaWJ1dGUsIGF0dHJpYnV0ZXNbYXR0cmlidXRlXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gX3JlbW92ZUNsYXNzKGVsZW1lbnQsIGNsYXNzUmVnRXhwKSB7CiAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50LmNsYXNzTmFtZS5yZXBsYWNlKGNsYXNzUmVnRXhwLCAiIik7CiAgICB9CgogICAgLyoqCiAgICAgKiBDaGVjayB3aGV0aGVyIGdpdmVuIG5vZGUgaXMgYSB0ZXh0IG5vZGUgYW5kIHdoZXRoZXIgaXQncyBlbXB0eQogICAgICovCiAgICBmdW5jdGlvbiBfaXNCbGFua1RleHROb2RlKG5vZGUpIHsKICAgICAgICByZXR1cm4gbm9kZS5ub2RlVHlwZSA9PT0gd3lzaWh0bWw1LlRFWFRfTk9ERSAmJiAhd3lzaWh0bWw1Lmxhbmcuc3RyaW5nKG5vZGUuZGF0YSkudHJpbSgpOwogICAgfQoKICAgIC8qKgogICAgICogUmV0dXJucyBwcmV2aW91cyBzaWJsaW5nIG5vZGUgdGhhdCBpcyBub3QgYSBibGFuayB0ZXh0IG5vZGUKICAgICAqLwogICAgZnVuY3Rpb24gX2dldFByZXZpb3VzU2libGluZ1RoYXRJc05vdEJsYW5rKG5vZGUpIHsKICAgICAgICB2YXIgcHJldmlvdXNTaWJsaW5nID0gbm9kZS5wcmV2aW91c1NpYmxpbmc7CiAgICAgICAgd2hpbGUgKHByZXZpb3VzU2libGluZyAmJiBfaXNCbGFua1RleHROb2RlKHByZXZpb3VzU2libGluZykpIHsKICAgICAgICAgICAgcHJldmlvdXNTaWJsaW5nID0gcHJldmlvdXNTaWJsaW5nLnByZXZpb3VzU2libGluZzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHByZXZpb3VzU2libGluZzsKICAgIH0KCiAgICAvKioKICAgICAqIFJldHVybnMgbmV4dCBzaWJsaW5nIG5vZGUgdGhhdCBpcyBub3QgYSBibGFuayB0ZXh0IG5vZGUKICAgICAqLwogICAgZnVuY3Rpb24gX2dldE5leHRTaWJsaW5nVGhhdElzTm90Qmxhbmsobm9kZSkgewogICAgICAgIHZhciBuZXh0U2libGluZyA9IG5vZGUubmV4dFNpYmxpbmc7CiAgICAgICAgd2hpbGUgKG5leHRTaWJsaW5nICYmIF9pc0JsYW5rVGV4dE5vZGUobmV4dFNpYmxpbmcpKSB7CiAgICAgICAgICAgIG5leHRTaWJsaW5nID0gbmV4dFNpYmxpbmcubmV4dFNpYmxpbmc7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXh0U2libGluZzsKICAgIH0KCiAgICAvKioKICAgICAqIEFkZHMgbGluZSBicmVha3MgYmVmb3JlIGFuZCBhZnRlciB0aGUgZ2l2ZW4gbm9kZSBpZiB0aGUgcHJldmlvdXMgYW5kIG5leHQgc2libGluZ3MKICAgICAqIGFyZW4ndCBhbHJlYWR5IGNhdXNpbmcgYSB2aXN1YWwgbGluZSBicmVhayAoYmxvY2sgZWxlbWVudCBvciA8YnI+KQogICAgICovCiAgICBmdW5jdGlvbiBfYWRkTGluZUJyZWFrQmVmb3JlQW5kQWZ0ZXIobm9kZSkgewogICAgICAgIHZhciBkb2MgPSBub2RlLm93bmVyRG9jdW1lbnQsCiAgICAgICAgICAgIG5leHRTaWJsaW5nID0gX2dldE5leHRTaWJsaW5nVGhhdElzTm90Qmxhbmsobm9kZSksCiAgICAgICAgICAgIHByZXZpb3VzU2libGluZyA9IF9nZXRQcmV2aW91c1NpYmxpbmdUaGF0SXNOb3RCbGFuayhub2RlKTsKCiAgICAgICAgaWYgKG5leHRTaWJsaW5nICYmICFfaXNMaW5lQnJlYWtPckJsb2NrRWxlbWVudChuZXh0U2libGluZykpIHsKICAgICAgICAgICAgbm9kZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShkb2MuY3JlYXRlRWxlbWVudCgiYnIiKSwgbmV4dFNpYmxpbmcpOwogICAgICAgIH0KICAgICAgICBpZiAocHJldmlvdXNTaWJsaW5nICYmICFfaXNMaW5lQnJlYWtPckJsb2NrRWxlbWVudChwcmV2aW91c1NpYmxpbmcpKSB7CiAgICAgICAgICAgIG5vZGUucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZG9jLmNyZWF0ZUVsZW1lbnQoImJyIiksIG5vZGUpOwogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIFJlbW92ZXMgbGluZSBicmVha3MgYmVmb3JlIGFuZCBhZnRlciB0aGUgZ2l2ZW4gbm9kZQogICAgICovCiAgICBmdW5jdGlvbiBfcmVtb3ZlTGluZUJyZWFrQmVmb3JlQW5kQWZ0ZXIobm9kZSkgewogICAgICAgIHZhciBuZXh0U2libGluZyA9IF9nZXROZXh0U2libGluZ1RoYXRJc05vdEJsYW5rKG5vZGUpLAogICAgICAgICAgICBwcmV2aW91c1NpYmxpbmcgPSBfZ2V0UHJldmlvdXNTaWJsaW5nVGhhdElzTm90Qmxhbmsobm9kZSk7CgogICAgICAgIGlmIChuZXh0U2libGluZyAmJiBfaXNMaW5lQnJlYWsobmV4dFNpYmxpbmcpKSB7CiAgICAgICAgICAgIG5leHRTaWJsaW5nLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobmV4dFNpYmxpbmcpOwogICAgICAgIH0KICAgICAgICBpZiAocHJldmlvdXNTaWJsaW5nICYmIF9pc0xpbmVCcmVhayhwcmV2aW91c1NpYmxpbmcpKSB7CiAgICAgICAgICAgIHByZXZpb3VzU2libGluZy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHByZXZpb3VzU2libGluZyk7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIF9yZW1vdmVMYXN0Q2hpbGRJZkxpbmVCcmVhayhub2RlKSB7CiAgICAgICAgdmFyIGxhc3RDaGlsZCA9IG5vZGUubGFzdENoaWxkOwogICAgICAgIGlmIChsYXN0Q2hpbGQgJiYgX2lzTGluZUJyZWFrKGxhc3RDaGlsZCkpIHsKICAgICAgICAgICAgbGFzdENoaWxkLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobGFzdENoaWxkKTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gX2lzTGluZUJyZWFrKG5vZGUpIHsKICAgICAgICByZXR1cm4gbm9kZS5ub2RlTmFtZSA9PT0gIkJSIjsKICAgIH0KCiAgICAvKioKICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBlbG1lbnQgY2F1c2VzIGEgdmlzdWFsIGxpbmUgYnJlYWsKICAgICAqICg8YnI+IG9yIGJsb2NrIGVsZW1lbnRzKQogICAgICovCiAgICBmdW5jdGlvbiBfaXNMaW5lQnJlYWtPckJsb2NrRWxlbWVudChlbGVtZW50KSB7CiAgICAgICAgaWYgKF9pc0xpbmVCcmVhayhlbGVtZW50KSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIGlmIChkb20uZ2V0U3R5bGUoImRpc3BsYXkiKS5mcm9tKGVsZW1lbnQpID09PSAiYmxvY2siKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogRXhlY3V0ZSBuYXRpdmUgcXVlcnkgY29tbWFuZAogICAgICogYW5kIGlmIG5lY2Vzc2FyeSBtb2RpZnkgdGhlIGluc2VydGVkIG5vZGUncyBjbGFzc05hbWUKICAgICAqLwogICAgZnVuY3Rpb24gX2V4ZWNDb21tYW5kKGRvYywgY29tbWFuZCwgbm9kZU5hbWUsIGNsYXNzTmFtZSkgewogICAgICAgIGlmIChjbGFzc05hbWUpIHsKICAgICAgICAgICAgdmFyIGV2ZW50TGlzdGVuZXIgPSBkb20ub2JzZXJ2ZShkb2MsICJET01Ob2RlSW5zZXJ0ZWQiLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSBldmVudC50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgZGlzcGxheVN0eWxlOwogICAgICAgICAgICAgICAgaWYgKHRhcmdldC5ub2RlVHlwZSAhPT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRpc3BsYXlTdHlsZSA9IGRvbS5nZXRTdHlsZSgiZGlzcGxheSIpLmZyb20odGFyZ2V0KTsKICAgICAgICAgICAgICAgIGlmIChkaXNwbGF5U3R5bGUuc3Vic3RyKDAsIDYpICE9PSAiaW5saW5lIikgewogICAgICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IG9ubHkgYmxvY2sgZWxlbWVudHMgcmVjZWl2ZSB0aGUgZ2l2ZW4gY2xhc3MKICAgICAgICAgICAgICAgICAgICB0YXJnZXQuY2xhc3NOYW1lICs9ICIgIiArIGNsYXNzTmFtZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGRvYy5leGVjQ29tbWFuZChjb21tYW5kLCBmYWxzZSwgbm9kZU5hbWUpOwogICAgICAgIGlmIChldmVudExpc3RlbmVyKSB7CiAgICAgICAgICAgIGV2ZW50TGlzdGVuZXIuc3RvcCgpOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfc2VsZWN0TGluZUFuZFdyYXAoY29tcG9zZXIsIGVsZW1lbnQpIHsKICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2VsZWN0TGluZSgpOwogICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zdXJyb3VuZChlbGVtZW50KTsKICAgICAgICBfcmVtb3ZlTGluZUJyZWFrQmVmb3JlQW5kQWZ0ZXIoZWxlbWVudCk7CiAgICAgICAgX3JlbW92ZUxhc3RDaGlsZElmTGluZUJyZWFrKGVsZW1lbnQpOwogICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZWxlY3ROb2RlKGVsZW1lbnQsIHd5c2lodG1sNS5icm93c2VyLmRpc3BsYXlzQ2FyZXRJbkVtcHR5Q29udGVudEVkaXRhYmxlQ29ycmVjdGx5KCkpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9oYXNDbGFzc2VzKGVsZW1lbnQpIHsKICAgICAgICByZXR1cm4gISF3eXNpaHRtbDUubGFuZy5zdHJpbmcoZWxlbWVudC5jbGFzc05hbWUpLnRyaW0oKTsKICAgIH0KCiAgICB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0QmxvY2sgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgbm9kZU5hbWUsIGNsYXNzTmFtZSwgY2xhc3NSZWdFeHApIHsKICAgICAgICAgICAgdmFyIGRvYyA9IGNvbXBvc2VyLmRvYywKICAgICAgICAgICAgICAgIGJsb2NrRWxlbWVudCA9IHRoaXMuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsIG5vZGVOYW1lLCBjbGFzc05hbWUsIGNsYXNzUmVnRXhwKSwKICAgICAgICAgICAgICAgIHVzZUxpbmVCcmVha3MgPSBjb21wb3Nlci5jb25maWcudXNlTGluZUJyZWFrcywKICAgICAgICAgICAgICAgIGRlZmF1bHROb2RlTmFtZSA9IHVzZUxpbmVCcmVha3MgPyAiRElWIiA6ICJQIiwKICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZTsKCiAgICAgICAgICAgIG5vZGVOYW1lID0gdHlwZW9mKG5vZGVOYW1lKSA9PT0gInN0cmluZyIgPyBub2RlTmFtZS50b1VwcGVyQ2FzZSgpIDogbm9kZU5hbWU7CgogICAgICAgICAgICBpZiAoYmxvY2tFbGVtZW50KSB7CiAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmVTaW1wbGUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc1JlZ0V4cCkgewogICAgICAgICAgICAgICAgICAgICAgICBfcmVtb3ZlQ2xhc3MoYmxvY2tFbGVtZW50LCBjbGFzc1JlZ0V4cCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBoYXNDbGFzc2VzID0gX2hhc0NsYXNzZXMoYmxvY2tFbGVtZW50KTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWhhc0NsYXNzZXMgJiYgKHVzZUxpbmVCcmVha3MgfHwgbm9kZU5hbWUgPT09ICJQIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5zZXJ0IGEgbGluZSBicmVhayBhZnRlcndhcmRzIGFuZCBiZWZvcmV3YXJkcyB3aGVuIHRoZXJlIGFyZSBzaWJsaW5ncwogICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGF0IGFyZSBub3Qgb2YgdHlwZSBsaW5lIGJyZWFrIG9yIGJsb2NrIGVsZW1lbnQKICAgICAgICAgICAgICAgICAgICAgICAgX2FkZExpbmVCcmVha0JlZm9yZUFuZEFmdGVyKGJsb2NrRWxlbWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5yZXBsYWNlV2l0aENoaWxkTm9kZXMoYmxvY2tFbGVtZW50KTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCBzdHlsaW5nIGlzIGtlcHQgYnkgcmVuYW1pbmcgdGhlIGVsZW1lbnQgdG8gYSA8ZGl2PiBvciA8cD4gYW5kIGNvcHlpbmcgb3ZlciB0aGUgY2xhc3MgbmFtZQogICAgICAgICAgICAgICAgICAgICAgICBkb20ucmVuYW1lRWxlbWVudChibG9ja0VsZW1lbnQsIG5vZGVOYW1lID09PSAiUCIgPyAiRElWIiA6IGRlZmF1bHROb2RlTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEZpbmQgc2ltaWxpYXIgYmxvY2sgZWxlbWVudCBhbmQgcmVuYW1lIGl0ICg8aDIgY2xhc3M9ImZvbyI+PC9oMj4gID0+ICA8aDEgY2xhc3M9ImZvbyI+PC9oMT4pCiAgICAgICAgICAgIGlmIChub2RlTmFtZSA9PT0gbnVsbCB8fCB3eXNpaHRtbDUubGFuZy5hcnJheShCTE9DS19FTEVNRU5UU19HUk9VUCkuY29udGFpbnMobm9kZU5hbWUpKSB7CiAgICAgICAgICAgICAgICBzZWxlY3RlZE5vZGUgPSBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKHVuZGVmaW5lZCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICBibG9ja0VsZW1lbnQgPSBkb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHsKICAgICAgICAgICAgICAgICAgICBub2RlTmFtZSA6IEJMT0NLX0VMRU1FTlRTX0dST1VQCiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICBpZiAoYmxvY2tFbGVtZW50KSB7CiAgICAgICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVuYW1lIGN1cnJlbnQgYmxvY2sgZWxlbWVudCB0byBuZXcgYmxvY2sgZWxlbWVudCBhbmQgYWRkIGNsYXNzCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlTmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tFbGVtZW50ID0gZG9tLnJlbmFtZUVsZW1lbnQoYmxvY2tFbGVtZW50LCBub2RlTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX2FkZENsYXNzKGJsb2NrRWxlbWVudCwgY2xhc3NOYW1lLCBjbGFzc1JlZ0V4cCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYWRkQXR0cmlidXRlKGJsb2NrRWxlbWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYWRkRGF0YUF0dHJpYnV0ZShibG9ja0VsZW1lbnQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY29tcG9zZXIuY29tbWFuZHMuc3VwcG9ydChjb21tYW5kKSkgewogICAgICAgICAgICAgICAgX2V4ZWNDb21tYW5kKGRvYywgY29tbWFuZCwgbm9kZU5hbWUgfHwgZGVmYXVsdE5vZGVOYW1lLCBjbGFzc05hbWUpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBibG9ja0VsZW1lbnQgPSBkb2MuY3JlYXRlRWxlbWVudChub2RlTmFtZSB8fCBkZWZhdWx0Tm9kZU5hbWUpOwogICAgICAgICAgICBpZiAoY2xhc3NOYW1lKSB7CiAgICAgICAgICAgICAgICBibG9ja0VsZW1lbnQuY2xhc3NOYW1lID0gY2xhc3NOYW1lOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF9zZWxlY3RMaW5lQW5kV3JhcChjb21wb3NlciwgYmxvY2tFbGVtZW50KTsKICAgICAgICB9LAoKICAgICAgICBzdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgbm9kZU5hbWUsIGNsYXNzTmFtZSwgY2xhc3NSZWdFeHAsIGF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgbm9kZU5hbWUgPSB0eXBlb2Yobm9kZU5hbWUpID09PSAic3RyaW5nIiA/IG5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgOiBub2RlTmFtZTsKICAgICAgICAgICAgdmFyIG5vZGVMaXN0ID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldE5vZGVzKDMpOwogICAgICAgICAgICBpZiAobm9kZUxpc3QubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgICAgICAgICAgaSA8IG5vZGVMaXN0Lmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSBub2RlTGlzdFtpXTsKICAgICAgICAgICAgICAgICAgICBpZiAobm9kZS50ZXh0Q29udGVudC50cmltKCkgIT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBkb20uZ2V0UGFyZW50RWxlbWVudChub2RlLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlTmFtZSA6IG5vZGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lIDogY2xhc3NOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NSZWdFeHAgOiBjbGFzc1JlZ0V4cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgOiBhdHRyaWJ1dGVzCiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiBkb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHsKICAgICAgICAgICAgICAgICAgICBub2RlTmFtZSA6IG5vZGVOYW1lLAogICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSA6IGNsYXNzTmFtZSwKICAgICAgICAgICAgICAgICAgICBjbGFzc1JlZ0V4cCA6IGNsYXNzUmVnRXhwLAogICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMgOiBhdHRyaWJ1dGVzCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGVtcHR5IHRhZ3MgYmVmb3JlIGFuZCBhZnRlciB0aGUgZ2l2ZW4gbm9kZQogICAgICovCiAgICBmdW5jdGlvbiBfcmVtb3ZlRW1wdHlUYWdzQmVmb3JlQW5kQWZ0ZXIobm9kZSkgewogICAgICAgIHZhciBuZXh0U2libGluZyA9IF9nZXROZXh0U2libGluZ1RoYXRJc05vdEJsYW5rKG5vZGUpLAogICAgICAgICAgICBwcmV2aW91c1NpYmxpbmcgPSBfZ2V0UHJldmlvdXNTaWJsaW5nVGhhdElzTm90Qmxhbmsobm9kZSk7CgogICAgICAgIGlmIChuZXh0U2libGluZyAmJiAhbmV4dFNpYmxpbmcudGV4dENvbnRlbnQpIHsKICAgICAgICAgICAgbmV4dFNpYmxpbmcucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChuZXh0U2libGluZyk7CiAgICAgICAgfQogICAgICAgIGlmIChwcmV2aW91c1NpYmxpbmcgJiYgIXByZXZpb3VzU2libGluZy50ZXh0Q29udGVudCkgewogICAgICAgICAgICBwcmV2aW91c1NpYmxpbmcucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChwcmV2aW91c1NpYmxpbmcpOwogICAgICAgIH0KICAgIH0KCiAgICB3eXNpaHRtbDUuY29tbWFuZHMuc3Vycm91bmRDb250ZW50ID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGVsZW1lbnQsIGVtcHR5VGV4dCkgewogICAgICAgICAgICB2YXIgc2VsZWN0ZWROb2RlID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFNlbGVjdGVkTm9kZSgpLAogICAgICAgICAgICAgICAgaXNFbXB0eSA9ICFjb21wb3Nlci5zZWxlY3Rpb24uZ2V0VGV4dCgpLAogICAgICAgICAgICAgICAgdGV4dE5vZGVOYW1lcyA9IFtdOwogICAgICAgICAgICBpZiAoY29tcG9zZXIuY29uZmlnLnBhcnNlclJ1bGVzICYmIGNvbXBvc2VyLmNvbmZpZy5wYXJzZXJSdWxlcy50ZXh0Tm9kZXMpIHsKICAgICAgICAgICAgICAgIHRleHROb2RlTmFtZXMgPSBjb21wb3Nlci5jb25maWcucGFyc2VyUnVsZXMudGV4dE5vZGVzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciB0ZXh0Tm9kZSA9IHd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHtub2RlTmFtZSA6IHRleHROb2RlTmFtZXN9KTsKICAgICAgICAgICAgaWYgKHRleHROb2RlKSB7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZS5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZShlbGVtZW50LCB0ZXh0Tm9kZSk7CiAgICAgICAgICAgICAgICBlbGVtZW50LmFwcGVuZENoaWxkKHRleHROb2RlKTsKICAgICAgICAgICAgfSBlbHNlIGlmICghd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKHNlbGVjdGVkTm9kZSkgJiYgc2VsZWN0ZWROb2RlLnRleHRDb250ZW50ID09IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRUZXh0KCkpIHsKICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZS5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZShlbGVtZW50LCBzZWxlY3RlZE5vZGUpOwogICAgICAgICAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChzZWxlY3RlZE5vZGUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLnN1cnJvdW5kKGVsZW1lbnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF9yZW1vdmVFbXB0eVRhZ3NCZWZvcmVBbmRBZnRlcihlbGVtZW50KTsKICAgICAgICAgICAgaWYgKGlzRW1wdHkpIHsKICAgICAgICAgICAgICAgIC8qIElmIHRoZSBhZGRlZCBlbGVtZW50IGlzIGVtcHR5IGFkZCBhIHBsYWNlaG9sZGVyIHRleHQqLwogICAgICAgICAgICAgICAgdmFyIGZpcnN0Q2hpbGQgPSBlbGVtZW50OwogICAgICAgICAgICAgICAgd2hpbGUgKGZpcnN0Q2hpbGQuZmlyc3RDaGlsZCAmJiBmaXJzdENoaWxkLmZpcnN0Q2hpbGQubm9kZVR5cGUgPT0gMSAmJiBmaXJzdENoaWxkLmZpcnN0Q2hpbGQubm9kZU5hbWUgIT0gIkJSIikgewogICAgICAgICAgICAgICAgICAgIGZpcnN0Q2hpbGQgPSBmaXJzdENoaWxkLmZpcnN0Q2hpbGQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmaXJzdENoaWxkLnRleHRDb250ZW50ID0gZW1wdHlUZXh0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBjaGlsZDsKICAgICAgICAgICAgaWYgKCFlbGVtZW50Lm5leHRTaWJsaW5nIHx8ICFlbGVtZW50Lm5leHRTaWJsaW5nLnRleHRDb250ZW50KSB7CiAgICAgICAgICAgICAgICAvKiBJZiB0aGUgZWxlbWVudCBoYXMgbm8gbmV4dCBzaWJsaW5nIGFkZCBhbiBlbGVtZW50CiAgICAgICAgICAgICAgICAgKiB3aXRoIHNhbWUgc3R5bGUgYXMgbGFzdCBjaGlsZCBvZiB0aGUgZWxlbWVudCBhbmQgJm5ic3AKICAgICAgICAgICAgICAgICAqIHRvIGVuYWJsZSBjdXJzb3IgdG8gZW50ZXIgdGhlIGVsZW1lbnQgKi8KICAgICAgICAgICAgICAgIGlmIChlbGVtZW50Lm5leHRTaWJsaW5nICYmIGVsZW1lbnQubmV4dFNpYmxpbmcubm9kZVR5cGUgPT0gMSkgewogICAgICAgICAgICAgICAgICAgIGNoaWxkID0gZWxlbWVudC5uZXh0U2libGluZzsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hpbGQuZmlyc3RDaGlsZCAmJiBjaGlsZC5maXJzdENoaWxkLm5vZGVUeXBlID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuZmlyc3RDaGlsZDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHZhciBsYXN0Q2hpbGQgPSBlbGVtZW50Lmxhc3RDaGlsZDsKICAgICAgICAgICAgICAgICAgICB2YXIgc3VwcG9ydGVkVGFncyA9IFsiUCIsICJIMSIsICJIMiIsICJIMyIsICJINCIsICJINSIsICJINiIsICJTUEFOIiwgIkIiLCAiVSIsICJJIiwgIlNVUCIsICJTVUIiLCAiQSJdOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChsYXN0Q2hpbGQubm9kZVR5cGUgPT09IDEgJiYgc3VwcG9ydGVkVGFncy5pbmRleE9mKGxhc3RDaGlsZC5ub2RlTmFtZSkgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RDaGlsZCA9IGxhc3RDaGlsZC5sYXN0Q2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8qIElmIGxhc3QgY2hpbGQgdHlwZSBpcyBub3QgdGV4dCwgY2xvbmUgYWxsIHRoZSBjaGlsZCBub2RlcwogICAgICAgICAgICAgICAgICAgICAqIGVsc2UgYXBwZW5kIGEgc3BhbiB0YWcqLwogICAgICAgICAgICAgICAgICAgIGlmIChsYXN0Q2hpbGQubm9kZVR5cGUgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNsb25lTm9kZSA9IGxhc3RDaGlsZC5jbG9uZU5vZGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQubmV4dFNpYmxpbmcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUoY2xvbmVOb2RlLCBlbGVtZW50Lm5leHRTaWJsaW5nKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQucGFyZW50RWxlbWVudC5hcHBlbmRDaGlsZChjbG9uZU5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChsYXN0Q2hpbGQubGFzdENoaWxkICYmIGxhc3RDaGlsZC5sYXN0Q2hpbGQubm9kZVR5cGUgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RDaGlsZCA9IGxhc3RDaGlsZC5sYXN0Q2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBTa2lwIGFsbCBjb25kaXRpb24vcmVwZWF0IGFuZCBsaXN0IHRhZ3MqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1cHBvcnRlZFRhZ3MuaW5kZXhPZihsYXN0Q2hpbGQubm9kZU5hbWUpIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQgPSBsYXN0Q2hpbGQuY2xvbmVOb2RlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9uZU5vZGUuYXBwZW5kQ2hpbGQoY2hpbGQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvbmVOb2RlID0gY2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5wYXJlbnRFbGVtZW50LmFwcGVuZENoaWxkKGNoaWxkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICBjaGlsZC5pbm5lckhUTUwgPSAiJm5ic3AiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciByYW5nZSA9IHJhbmd5LmNyZWF0ZVJhbmdlKGNvbXBvc2VyLmRvYyk7CiAgICAgICAgICAgIHJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhlbGVtZW50KTsKICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLnNldFNlbGVjdGlvbihyYW5nZSk7CiAgICAgICAgfQogICAgfTsKfSkod3lzaWh0bWw1KTsKLyoqCiAqIGZvcm1hdElubGluZSBzY2VuYXJpb3MgZm9yIHRhZyAiQiIgKHwgPSBjYXJldCwgfGZvb3wgPSBzZWxlY3RlZCB0ZXh0KQogKgogKiAgICMxIGNhcmV0IGluIHVuZm9ybWF0dGVkIHRleHQ6CiAqICAgICAgYWJjZGVmZ3wKICogICBvdXRwdXQ6CiAqICAgICAgYWJjZGVmZzxiPnw8L2I+CiAqCiAqICAgIzIgdW5mb3JtYXR0ZWQgdGV4dCBzZWxlY3RlZDoKICogICAgICBhYmN8ZGVnfGgKICogICBvdXRwdXQ6CiAqICAgICAgYWJjPGI+fGRlZ3w8L2I+aAogKgogKiAgICMzIHVuZm9ybWF0dGVkIHRleHQgc2VsZWN0ZWQgYWNyb3NzIGJvdW5kYXJpZXM6CiAqICAgICAgYWJ8YyA8c3Bhbj5kZWZnfGg8L3NwYW4+CiAqICAgb3V0cHV0OgogKiAgICAgIGFiPGI+fGMgPC9iPjxzcGFuPjxiPmRlZmc8L2I+fGg8L3NwYW4+CiAqCiAqICAgIzQgZm9ybWF0dGVkIHRleHQgZW50aXJlbHkgc2VsZWN0ZWQKICogICAgICA8Yj58YWJjfDwvYj4KICogICBvdXRwdXQ6CiAqICAgICAgfGFiY3wKICoKICogICAjNSBmb3JtYXR0ZWQgdGV4dCBwYXJ0aWFsbHkgc2VsZWN0ZWQKICogICAgICA8Yj5hYnxjfDwvYj4KICogICBvdXRwdXQ6CiAqICAgICAgPGI+YWI8L2I+fGN8CiAqCiAqICAgIzYgZm9ybWF0dGVkIHRleHQgc2VsZWN0ZWQgYWNyb3NzIGJvdW5kYXJpZXMKICogICAgICA8c3Bhbj5hYnxjPC9zcGFuPiA8Yj5kZXxmZ2g8L2I+CiAqICAgb3V0cHV0OgogKiAgICAgIDxzcGFuPmFifGM8L3NwYW4+IGRlfDxiPmZnaDwvYj4KICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgLy8gVHJlYXQgPGI+IGFzIDxzdHJvbmc+IGFuZCB2aWNlIHZlcnNhCiAgICAgICAgQUxJQVNfTUFQUElORyA9IHsKICAgICAgICAgICAgInN0cm9uZyIgOiAiYiIsCiAgICAgICAgICAgICJlbSIgOiAiaSIsCiAgICAgICAgICAgICJiIiA6ICJzdHJvbmciLAogICAgICAgICAgICAiaSIgOiAiZW0iCiAgICAgICAgfSwKICAgICAgICBodG1sQXBwbGllciA9IHt9OwoKICAgIGZ1bmN0aW9uIF9nZXRUYWdOYW1lcyh0YWdOYW1lKSB7CiAgICAgICAgdmFyIGFsaWFzID0gQUxJQVNfTUFQUElOR1t0YWdOYW1lXTsKICAgICAgICBpZiAodGFnTmFtZS50b0xvd2VyQ2FzZSgpID09ICdzcGFuJykgewogICAgICAgICAgICByZXR1cm4gYWxpYXMgPyBbdGFnTmFtZS50b0xvd2VyQ2FzZSgpLCBhbGlhcy50b0xvd2VyQ2FzZSgpLCAibGkiLCAicCJdIDogW3RhZ05hbWUudG9Mb3dlckNhc2UoKSwgImxpIiwgInAiXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gYWxpYXMgPyBbdGFnTmFtZS50b0xvd2VyQ2FzZSgpLCBhbGlhcy50b0xvd2VyQ2FzZSgpXSA6IFt0YWdOYW1lLnRvTG93ZXJDYXNlKCldOwogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBfZ2V0QXBwbGllcih0YWdOYW1lLCBjbGFzc05hbWUsIGNsYXNzUmVnRXhwLCBhdHRyaWJ1dGVzLCBjbGVhclByZVN0eWxlLCBkYXRhQXR0cmlidXRlLCBjbGVhclByZURhdGFBdHRyaWJ1dGUpIHsKICAgICAgICB2YXIgaWRlbnRpZmllciA9ICIiOwogICAgICAgIGlmIChhdHRyaWJ1dGVzKSB7CiAgICAgICAgICAgIGZvciAoYXR0cmlidXRlIGluIGF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICAgIGlkZW50aWZpZXIgPSB0YWdOYW1lICsgIjoiICsgY2xhc3NOYW1lICsgIjoiICsgYXR0cmlidXRlc1thdHRyaWJ1dGVdOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGRhdGFBdHRyaWJ1dGUpIHsKICAgICAgICAgICAgZm9yIChhdHRyaWJ1dGUgaW4gZGF0YUF0dHJpYnV0ZSkgewogICAgICAgICAgICAgICAgaWRlbnRpZmllciArPSB0YWdOYW1lICsgIjoiICsgY2xhc3NOYW1lICsgIjoiICsgZGF0YUF0dHJpYnV0ZVthdHRyaWJ1dGVdOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChpZGVudGlmaWVyID09ICIiKSB7CiAgICAgICAgICAgIGlkZW50aWZpZXIgPSB0YWdOYW1lICsgIjoiICsgY2xhc3NOYW1lOwogICAgICAgIH0KICAgICAgICBpZiAoIWh0bWxBcHBsaWVyW2lkZW50aWZpZXJdKSB7CiAgICAgICAgICAgIGh0bWxBcHBsaWVyW2lkZW50aWZpZXJdID0gbmV3IHd5c2lodG1sNS5zZWxlY3Rpb24uSFRNTEFwcGxpZXIoX2dldFRhZ05hbWVzKHRhZ05hbWUpLCBjbGFzc05hbWUsIGNsYXNzUmVnRXhwLCB0cnVlLCBhdHRyaWJ1dGVzLCBjbGVhclByZVN0eWxlLCBkYXRhQXR0cmlidXRlLCBjbGVhclByZURhdGFBdHRyaWJ1dGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaHRtbEFwcGxpZXJbaWRlbnRpZmllcl07CiAgICB9CgogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZSA9IHsKICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCB0YWdOYW1lLCBjbGFzc05hbWUsIGNsYXNzUmVnRXhwLCBhdHRyaWJ1dGVzLCBjbGVhclByZVN0eWxlLCBkYXRhQXR0cmlidXRlLCBjbGVhclByZURhdGFBdHRyaWJ1dGUpIHsKICAgICAgICAgICAgdmFyIHJhbmdlID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFJhbmdlKCk7CiAgICAgICAgICAgIGlmICghcmFuZ2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBfZ2V0QXBwbGllcih0YWdOYW1lLCBjbGFzc05hbWUsIGNsYXNzUmVnRXhwLCBhdHRyaWJ1dGVzLCBjbGVhclByZVN0eWxlLCBkYXRhQXR0cmlidXRlLCBjbGVhclByZURhdGFBdHRyaWJ1dGUpLnRvZ2dsZVJhbmdlKHJhbmdlLCBjb21wb3Nlcik7CiAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZXRTZWxlY3Rpb24ocmFuZ2UpOwogICAgICAgIH0sCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIHRhZ05hbWUsIGNsYXNzTmFtZSwgY2xhc3NSZWdFeHAsIGF0dHJpYnV0ZXMsIGNsZWFyUHJlU3R5bGUsIGRhdGFBdHRyaWJ1dGUsIGNsZWFyUHJlRGF0YUF0dHJpYnV0ZSkgewogICAgICAgICAgICB2YXIgZG9jID0gY29tcG9zZXIuZG9jLAogICAgICAgICAgICAgICAgYWxpYXNUYWdOYW1lID0gQUxJQVNfTUFQUElOR1t0YWdOYW1lXSB8fCB0YWdOYW1lLAogICAgICAgICAgICAgICAgcmFuZ2U7CgogICAgICAgICAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSBkb2N1bWVudCBjb250YWlucyBhIG5vZGUgd2l0aCB0aGUgZGVzaXJlZCB0YWdOYW1lCiAgICAgICAgICAgIGlmICghd3lzaWh0bWw1LmRvbS5oYXNFbGVtZW50V2l0aFRhZ05hbWUoZG9jLCB0YWdOYW1lKSAmJiAhd3lzaWh0bWw1LmRvbS5oYXNFbGVtZW50V2l0aFRhZ05hbWUoZG9jLCBhbGlhc1RhZ05hbWUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIGRvY3VtZW50IGNvbnRhaW5zIGEgbm9kZSB3aXRoIHRoZSBkZXNpcmVkIGNsYXNzTmFtZQogICAgICAgICAgICAvL2lmIChjbGFzc05hbWUgJiYgIXd5c2lodG1sNS5kb20uaGFzRWxlbWVudFdpdGhDbGFzc05hbWUoZG9jLCBjbGFzc05hbWUpKSB7CiAgICAgICAgICAgIC8vICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAvL30KCiAgICAgICAgICAgIHJhbmdlID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFJhbmdlKCk7CiAgICAgICAgICAgIGlmICghcmFuZ2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gX2dldEFwcGxpZXIodGFnTmFtZSwgY2xhc3NOYW1lLCBjbGFzc1JlZ0V4cCwgYXR0cmlidXRlcywgY2xlYXJQcmVTdHlsZSwgZGF0YUF0dHJpYnV0ZSwgY2xlYXJQcmVEYXRhQXR0cmlidXRlKS5pc0FwcGxpZWRUb1JhbmdlKHJhbmdlKTsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwp3eXNpaHRtbDUuY29tbWFuZHMuaW5zZXJ0SFRNTCA9IHsKICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGh0bWwpIHsKICAgICAgICBpZiAoY29tcG9zZXIuY29tbWFuZHMuc3VwcG9ydChjb21tYW5kKSkgewogICAgICAgICAgICBjb21wb3Nlci5kb2MuZXhlY0NvbW1hbmQoY29tbWFuZCwgZmFsc2UsIGh0bWwpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5pbnNlcnRIVE1MKGh0bWwpOwogICAgICAgIH0KICAgIH0sCgogICAgc3RhdGUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9Owood3lzaWh0bWw1KTsKd3lzaWh0bWw1LmNvbW1hbmRzLmluc2VydFRleHQgPSB7CiAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCB0ZXh0KSB7CiAgICAgICAgaWYgKGNvbXBvc2VyLmNvbW1hbmRzLnN1cHBvcnQoY29tbWFuZCkpIHsKICAgICAgICAgICAgY29tcG9zZXIuZG9jLmV4ZWNDb21tYW5kKGNvbW1hbmQsIGZhbHNlLCB0ZXh0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoY29tcG9zZXIuc2VsZWN0aW9uICYmIGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRUZXh0KCkgIT0gIiIpIHsKICAgICAgICAgICAgICAgIGNvbXBvc2VyLmRvYy5leGVjQ29tbWFuZCgiZGVsZXRlIiwgZmFsc2UsIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEltcGxlbWVudGluZyBtdWx0aSBsaW5lIGluc2VydFRleHQgKCBpbmNhc2Ugb2YgcGFzdGUpCiAgICAgICAgICAgIGlmICh0ZXh0KSB7CiAgICAgICAgICAgICAgICB2YXIgbXVsdGlMaW5lcyA9IHRleHQuc3BsaXQoIlxyXG4iKTsgLy8gc3BsaXQgYnkgQ1IgKyBMRgogICAgICAgICAgICAgICAgdmFyIHRleHROb2RlOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOwogICAgICAgICAgICAgICAgICAgICBpbmRleCA8IG11bHRpTGluZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICBpbmRleCsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGV4dE5vZGUgPSBjb21wb3Nlci5zZWxlY3Rpb24uZG9jLmNyZWF0ZVRleHROb2RlKG11bHRpTGluZXNbaW5kZXhdKTsKICAgICAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uaW5zZXJ0Tm9kZSh0ZXh0Tm9kZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKG11bHRpTGluZXMubGVuZ3RoID4gMSAmJiBpbmRleCA8IG11bHRpTGluZXMubGVuZ3RoIC0gMSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uaW5zZXJ0Tm9kZShjb21wb3Nlci5zZWxlY3Rpb24uZG9jLmNyZWF0ZUVsZW1lbnQoImJyIikpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZXQodGV4dE5vZGUsIHRleHROb2RlLmxlbmd0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfTsKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBOT0RFX05BTUUgPSAiSU1HIjsKCiAgICB3eXNpaHRtbDUuY29tbWFuZHMuaW5zZXJ0SW1hZ2UgPSB7CiAgICAgICAgLyoqCiAgICAgICAgICogSW5zZXJ0cyBhbiA8aW1nPgogICAgICAgICAqIElmIHNlbGVjdGlvbiBpcyBhbHJlYWR5IGFuIGltYWdlIGxpbmssIGl0IHJlbW92ZXMgaXQKICAgICAgICAgKgogICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICogICAgLy8gZWl0aGVyIC4uLgogICAgICAgICAqICAgIHd5c2lodG1sNS5jb21tYW5kcy5pbnNlcnRJbWFnZS5leGVjKGNvbXBvc2VyLCAiaW5zZXJ0SW1hZ2UiLCAiaHR0cDovL3d3dy5nb29nbGUuZGUvbG9nby5qcGciKTsKICAgICAgICAgKiAgICAvLyAuLi4gb3IgLi4uCiAgICAgICAgICogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmluc2VydEltYWdlLmV4ZWMoY29tcG9zZXIsICJpbnNlcnRJbWFnZSIsIHsgc3JjOiAiaHR0cDovL3d3dy5nb29nbGUuZGUvbG9nby5qcGciLCB0aXRsZTogImZvbyIgfSk7CiAgICAgICAgICovCiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgdmFsdWUpIHsKICAgICAgICAgICAgdmFsdWUgPSB0eXBlb2YodmFsdWUpID09PSAib2JqZWN0IiA/IHZhbHVlIDoge3NyYyA6IHZhbHVlfTsKCiAgICAgICAgICAgIHZhciBkb2MgPSBjb21wb3Nlci5kb2MsCiAgICAgICAgICAgICAgICBpbWFnZSA9IHRoaXMuc3RhdGUoY29tcG9zZXIpLAogICAgICAgICAgICAgICAgdGV4dE5vZGUsCiAgICAgICAgICAgICAgICBpLAogICAgICAgICAgICAgICAgcGFyZW50OwoKICAgICAgICAgICAgaWYgKGltYWdlKSB7CiAgICAgICAgICAgICAgICAvLyBJbWFnZSBhbHJlYWR5IHNlbGVjdGVkLCBzZXQgdGhlIGNhcmV0IGJlZm9yZSBpdCBhbmQgZGVsZXRlIGl0CiAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2V0QmVmb3JlKGltYWdlKTsKICAgICAgICAgICAgICAgIHBhcmVudCA9IGltYWdlLnBhcmVudE5vZGU7CiAgICAgICAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoaW1hZ2UpOwoKICAgICAgICAgICAgICAgIC8vIGFuZCBpdCdzIHBhcmVudCA8YT4gdG9vIGlmIGl0IGhhc24ndCBnb3QgYW55IG90aGVyIHJlbGV2YW50IGNoaWxkIG5vZGVzCiAgICAgICAgICAgICAgICB3eXNpaHRtbDUuZG9tLnJlbW92ZUVtcHR5VGV4dE5vZGVzKHBhcmVudCk7CiAgICAgICAgICAgICAgICBpZiAocGFyZW50Lm5vZGVOYW1lID09PSAiQSIgJiYgIXBhcmVudC5maXJzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLnNldEFmdGVyKHBhcmVudCk7CiAgICAgICAgICAgICAgICAgICAgcGFyZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQocGFyZW50KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBmaXJlZm94IGFuZCBpZSBzb21ldGltZXMgZG9uJ3QgcmVtb3ZlIHRoZSBpbWFnZSBoYW5kbGVzLCBldmVuIHRob3VnaCB0aGUgaW1hZ2UgZ290IHJlbW92ZWQKICAgICAgICAgICAgICAgIHd5c2lodG1sNS5xdWlya3MucmVkcmF3KGNvbXBvc2VyLmVsZW1lbnQpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpbWFnZSA9IGRvYy5jcmVhdGVFbGVtZW50KE5PREVfTkFNRSk7CgogICAgICAgICAgICBmb3IgKGkgaW4gdmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmIChpID09PSAiY2xhc3NOYW1lIikgewogICAgICAgICAgICAgICAgICAgIGkgPSAiY2xhc3MiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW1hZ2Uuc2V0QXR0cmlidXRlKGksIHZhbHVlW2ldKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmluc2VydE5vZGUoaW1hZ2UpOwogICAgICAgICAgICBpZiAod3lzaWh0bWw1LmJyb3dzZXIuaGFzUHJvYmxlbXNTZXR0aW5nQ2FyZXRBZnRlckltZygpKSB7CiAgICAgICAgICAgICAgICB0ZXh0Tm9kZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSh3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFKTsKICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5pbnNlcnROb2RlKHRleHROb2RlKTsKICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZXRBZnRlcih0ZXh0Tm9kZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2V0QWZ0ZXIoaW1hZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIpIHsKICAgICAgICAgICAgdmFyIGRvYyA9IGNvbXBvc2VyLmRvYywKICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZSwKICAgICAgICAgICAgICAgIHRleHQsCiAgICAgICAgICAgICAgICBpbWFnZXNJblNlbGVjdGlvbjsKCiAgICAgICAgICAgIGlmICghd3lzaWh0bWw1LmRvbS5oYXNFbGVtZW50V2l0aFRhZ05hbWUoZG9jLCBOT0RFX05BTUUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKTsKICAgICAgICAgICAgaWYgKCFzZWxlY3RlZE5vZGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZS5ub2RlTmFtZSA9PT0gTk9ERV9OQU1FKSB7CiAgICAgICAgICAgICAgICAvLyBUaGlzIHdvcmtzIHBlcmZlY3RseSBpbiBJRQogICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGVkTm9kZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZS5ub2RlVHlwZSAhPT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0ZXh0ID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFRleHQoKTsKICAgICAgICAgICAgdGV4dCA9IHd5c2lodG1sNS5sYW5nLnN0cmluZyh0ZXh0KS50cmltKCk7CiAgICAgICAgICAgIGlmICh0ZXh0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGltYWdlc0luU2VsZWN0aW9uID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldE5vZGVzKHd5c2lodG1sNS5FTEVNRU5UX05PREUsIGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5ub2RlTmFtZSA9PT0gIklNRyI7CiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgaWYgKGltYWdlc0luU2VsZWN0aW9uLmxlbmd0aCAhPT0gMSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gaW1hZ2VzSW5TZWxlY3Rpb25bMF07CiAgICAgICAgfQogICAgfTsKfSkod3lzaWh0bWw1KTsKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBMSU5FX0JSRUFLID0gIjxicj4iICsgKHd5c2lodG1sNS5icm93c2VyLm5lZWRzU3BhY2VBZnRlckxpbmVCcmVhaygpID8gIiAiIDogIiIpOwoKICAgIHd5c2lodG1sNS5jb21tYW5kcy5pbnNlcnRMaW5lQnJlYWsgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgICAgICBpZiAoY29tcG9zZXIuY29tbWFuZHMuc3VwcG9ydChjb21tYW5kKSkgewogICAgICAgICAgICAgICAgY29tcG9zZXIuZG9jLmV4ZWNDb21tYW5kKGNvbW1hbmQsIGZhbHNlLCBudWxsKTsKICAgICAgICAgICAgICAgIGlmICghd3lzaWh0bWw1LmJyb3dzZXIuYXV0b1Njcm9sbHNUb0NhcmV0KCkpIHsKICAgICAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2Nyb2xsSW50b1ZpZXcoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvbXBvc2VyLmNvbW1hbmRzLmV4ZWMoImluc2VydEhUTUwiLCBMSU5FX0JSRUFLKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfTsKfSkod3lzaWh0bWw1KTsKd3lzaWh0bWw1LmNvbW1hbmRzLmluc2VydE9yZGVyZWRMaXN0ID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgbGlzdFR5cGUpIHsKICAgICAgICB2YXIgZG9jID0gY29tcG9zZXIuZG9jLAogICAgICAgICAgICBzZWxlY3RlZE5vZGUgPSBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKHVuZGVmaW5lZCwgdHJ1ZSksCiAgICAgICAgICAgIGxpc3QgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQoc2VsZWN0ZWROb2RlLCB7bm9kZU5hbWUgOiAiT0wifSksCiAgICAgICAgICAgIG90aGVyTGlzdCA9IHd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHtub2RlTmFtZSA6ICJVTCJ9KSwKICAgICAgICAgICAgdGVtcENsYXNzTmFtZSA9ICJfd3lzaWh0bWw1LXRlbXAtIiArIG5ldyBEYXRlKCkuZ2V0VGltZSgpLAogICAgICAgICAgICBpc0VtcHR5LAogICAgICAgICAgICB0ZW1wRWxlbWVudDsKICAgICAgICB2YXIgdXBwZXJSb21hbkxpc3Q7CiAgICAgICAgdmFyIGxvd2VyUm9tYW5MaXN0OwogICAgICAgIHZhciB1cHBlckFscGhhTGlzdDsKICAgICAgICB2YXIgbG93ZXJBbHBoYUxpc3Q7CgogICAgICAgIC8vaWYgKCFsaXN0ICYmICFvdGhlckxpc3QgJiYgY29tcG9zZXIuY29tbWFuZHMuc3VwcG9ydChjb21tYW5kKSkgewogICAgICAgIC8vICAgICAgZG9jLmV4ZWNDb21tYW5kKGNvbW1hbmQsIGZhbHNlLCBudWxsKTsKICAgICAgICAvLyAgICAgIHJldHVybjsKICAgICAgICAvL30KCiAgICAgICAgaWYgKGxpc3QgJiYgKGxpc3RUeXBlID09ICJOb25lIikpIHsKICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS5kb20ucmVzb2x2ZUxpc3QobGlzdCwgY29tcG9zZXIuY29uZmlnLnVzZUxpbmVCcmVha3MpOwogICAgICAgICAgICB9KTsKICAgICAgICB9IGVsc2UgaWYgKG90aGVyTGlzdCAmJiAobGlzdFR5cGUgPT0gIk5vbmUiKSkgewogICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5yZXNvbHZlTGlzdChvdGhlckxpc3QsIGNvbXBvc2VyLmNvbmZpZy51c2VMaW5lQnJlYWtzKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICBpZiAobGlzdCAhPSBudWxsICYmIGxpc3QuZ2V0QXR0cmlidXRlKCJ0eXBlIikgPT0gIkkiKSB7CiAgICAgICAgICAgIHVwcGVyUm9tYW5MaXN0ID0gbGlzdDsKICAgICAgICAgICAgbGlzdCA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChsaXN0ICE9IG51bGwgJiYgbGlzdC5nZXRBdHRyaWJ1dGUoInR5cGUiKSA9PSAiaSIpIHsKICAgICAgICAgICAgbG93ZXJSb21hbkxpc3QgPSBsaXN0OwogICAgICAgICAgICBsaXN0ID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKGxpc3QgIT0gbnVsbCAmJiBsaXN0LmdldEF0dHJpYnV0ZSgidHlwZSIpID09ICJBIikgewogICAgICAgICAgICB1cHBlckFscGhhTGlzdCA9IGxpc3Q7CiAgICAgICAgICAgIGxpc3QgPSBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAobGlzdCAhPSBudWxsICYmIGxpc3QuZ2V0QXR0cmlidXRlKCJ0eXBlIikgPT0gImEiKSB7CiAgICAgICAgICAgIGxvd2VyQWxwaGFMaXN0ID0gbGlzdDsKICAgICAgICAgICAgbGlzdCA9IG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZiAobGlzdCAmJiAobGlzdFR5cGUgPT0gIk9yZGVyZWQiKSkgewogICAgICAgICAgICAvLyBVbndyYXAgbGlzdAogICAgICAgICAgICAvLyA8b2w+PGxpPmZvbzwvbGk+PGxpPmJhcjwvbGk+PC9vbD4KICAgICAgICAgICAgLy8gYmVjb21lczoKICAgICAgICAgICAgLy8gZm9vPGJyPmJhcjxicj4KICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS5kb20ucmVzb2x2ZUxpc3QobGlzdCwgY29tcG9zZXIuY29uZmlnLnVzZUxpbmVCcmVha3MpOwogICAgICAgICAgICB9KTsKICAgICAgICB9IGVsc2UgaWYgKHVwcGVyUm9tYW5MaXN0ICYmIChsaXN0VHlwZSA9PSAiSSIpKSB7CiAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5leGVjdXRlQW5kUmVzdG9yZShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB3eXNpaHRtbDUuZG9tLnJlc29sdmVMaXN0KHVwcGVyUm9tYW5MaXN0LCBjb21wb3Nlci5jb25maWcudXNlTGluZUJyZWFrcyk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSBpZiAobG93ZXJSb21hbkxpc3QgJiYgKGxpc3RUeXBlID09ICJpIikpIHsKICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS5kb20ucmVzb2x2ZUxpc3QobG93ZXJSb21hbkxpc3QsIGNvbXBvc2VyLmNvbmZpZy51c2VMaW5lQnJlYWtzKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSBlbHNlIGlmICh1cHBlckFscGhhTGlzdCAmJiAobGlzdFR5cGUgPT0gIkEiKSkgewogICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5yZXNvbHZlTGlzdCh1cHBlckFscGhhTGlzdCwgY29tcG9zZXIuY29uZmlnLnVzZUxpbmVCcmVha3MpOwogICAgICAgICAgICB9KTsKICAgICAgICB9IGVsc2UgaWYgKGxvd2VyQWxwaGFMaXN0ICYmIChsaXN0VHlwZSA9PSAiYSIpKSB7CiAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5leGVjdXRlQW5kUmVzdG9yZShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB3eXNpaHRtbDUuZG9tLnJlc29sdmVMaXN0KGxvd2VyQWxwaGFMaXN0LCBjb21wb3Nlci5jb25maWcudXNlTGluZUJyZWFrcyk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSBpZiAob3RoZXJMaXN0KSB7CiAgICAgICAgICAgIC8vIFR1cm4gYW4gdW5vcmRlcmVkIGxpc3QgaW50byBhbiBvcmRlcmVkIGxpc3QKICAgICAgICAgICAgLy8gPHVsPjxsaT5mb288L2xpPjxsaT5iYXI8L2xpPjwvdWw+CiAgICAgICAgICAgIC8vIGJlY29tZXM6CiAgICAgICAgICAgIC8vIDxvbD48bGk+Zm9vPC9saT48bGk+YmFyPC9saT48L29sPgogICAgICAgICAgICB2YXIgZWwgPSBjb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSB3eXNpaHRtbDUuZG9tLnJlbmFtZUVsZW1lbnQob3RoZXJMaXN0LCAib2wiKTsKICAgICAgICAgICAgICAgIHZhciBhdHRyaWJ1dGUgPSB7fTsKICAgICAgICAgICAgICAgIGF0dHJpYnV0ZS50eXBlID0gbGlzdFR5cGU7CiAgICAgICAgICAgICAgICB3eXNpaHRtbDUuZG9tLnNldEF0dHJpYnV0ZXMoYXR0cmlidXRlKS5vbihlbGVtZW50KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlmIChlbCAhPSBudWxsICYmIGxpc3RUeXBlICE9ICJPcmRlcmVkIikgewogICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlKCJ0eXBlIiwgbGlzdFR5cGUpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChsb3dlclJvbWFuTGlzdCB8fCB1cHBlclJvbWFuTGlzdCB8fCBsb3dlckFscGhhTGlzdCB8fCB1cHBlckFscGhhTGlzdCkgewogICAgICAgICAgICB2YXIgZWwgPSB3eXNpaHRtbDUuY29tbWFuZHMuaW5zZXJ0T3JkZXJlZExpc3Quc3RhdGUoY29tcG9zZXIpOwogICAgICAgICAgICBpZiAoZWwgIT0gbnVsbCAmJiAobGlzdFR5cGUgPT0gIk9yZGVyZWQiKSkgewogICAgICAgICAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoInR5cGUiLCBsaXN0VHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGxpc3QpIHsKICAgICAgICAgICAgdmFyIGVsID0gd3lzaWh0bWw1LmNvbW1hbmRzLmluc2VydE9yZGVyZWRMaXN0LnN0YXRlKGNvbXBvc2VyKTsKICAgICAgICAgICAgaWYgKGVsICE9IG51bGwgJiYgKGxpc3RUeXBlICE9ICJPcmRlcmVkIikpIHsKICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZSgidHlwZSIsIGxpc3RUeXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAobGlzdFR5cGUgIT0gIk5vbmUiKSB7CiAgICAgICAgICAgIC8vIENyZWF0ZSBsaXN0CiAgICAgICAgICAgIGNvbXBvc2VyLmNvbW1hbmRzLmV4ZWMoImZvcm1hdEJsb2NrIiwgImRpdiIsIHRlbXBDbGFzc05hbWUpOwogICAgICAgICAgICAvLyBDaGVjayBpZiBtdWx0aXBsZSBlbGVtZW50IGFyZSBmb3VuZAogICAgICAgICAgICB2YXIgdGVtcEVsZW1lbnRzID0gZG9jLnF1ZXJ5U2VsZWN0b3JBbGwoIi4iICsgdGVtcENsYXNzTmFtZSk7CiAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudHMpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsKICAgICAgICAgICAgICAgICAgICAgaW5kZXggPCB0ZW1wRWxlbWVudHMubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICBpbmRleCsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGVtcEVsZW1lbnQgPSB0ZW1wRWxlbWVudHNbaW5kZXhdOwogICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ID0gd3lzaWh0bWw1LmRvbS5jb252ZXJ0VG9MaXN0KHRlbXBFbGVtZW50LCAib2wiLCBsaXN0VHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudC5ub2RlTmFtZSAhPSAiTEkiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcEVsZW1lbnQgPSB3eXNpaHRtbDUuZG9tLnJlbmFtZUVsZW1lbnQodGVtcEVsZW1lbnQsICJsaSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5yZW1vdmVDbGFzcyh0ZW1wRWxlbWVudCwgdGVtcENsYXNzTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRlbXBFbGVtZW50LnF1ZXJ5U2VsZWN0b3Iod3lzaWh0bWw1LkJMT0NLX0VMRU1FTlRTX0dST1VQLmpvaW4oIiwiKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPSAiPHA+IiArIHRlbXBFbGVtZW50LmlubmVySFRNTCArICI8L3A+IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuYXBwZW5kQ2hpbGQodGVtcEVsZW1lbnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlzRW1wdHkgPSB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPT09ICIiIHx8IHRlbXBFbGVtZW50LmlubmVySFRNTCA9PT0gd3lzaWh0bWw1LklOVklTSUJMRV9TUEFDRSB8fCB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPT09ICI8YnI+IjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRW1wdHkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZWxlY3ROb2RlKGxpc3QucXVlcnlTZWxlY3RvcigibGkiKSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyKSB7CiAgICAgICAgdmFyIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKTsKICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkTm9kZSwge25vZGVOYW1lIDogIk9MIn0pOwogICAgfSwKCiAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCB2YWx1ZSwgaXNEZWZhdWx0KSB7CiAgICAgICAgdmFyIGRvbUVsZW0gPSB0aGlzLnN0YXRlKGNvbXBvc2VyKTsKICAgICAgICBpZiAoZG9tRWxlbSkgewogICAgICAgICAgICB2YXIgYXR0clZhbCA9IGRvbUVsZW0uZ2V0QXR0cmlidXRlKCd0eXBlJyk7CiAgICAgICAgICAgIGlmIChhdHRyVmFsID09IG51bGwgJiYgdmFsdWUgPT0gJ09yZGVyZWQnKSB7Ly93aGVuIHZhbHVlIGlzICdPcmRlcmVkJywgZGVmYXVsdCBvcmRlcmVkIGxpc3QgbnVtYmVyaW5nIGlzIHVzZWQsIG5vIHR5cGUgYXR0cmlidXRlLgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGF0dHJWYWwgPT0gdmFsdWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9IGVsc2UgaWYgKGlzRGVmYXVsdCkgeyAgICAgICAgIC8vbm8gZG9tRWxlbSB3aXRoICJPTCIgd291bGQgYmUgZm91bmQgaWYgd2UgaGF2ZSBub25lIHR5cGUKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfTsKCnd5c2lodG1sNS5jb21tYW5kcy5pbnNlcnRVbm9yZGVyZWRMaXN0ID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgIHZhciBkb2MgPSBjb21wb3Nlci5kb2MsCiAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUodW5kZWZpbmVkLCB0cnVlKSwKICAgICAgICAgICAgbGlzdCA9IHd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHtub2RlTmFtZSA6ICJVTCJ9KSwKICAgICAgICAgICAgb3RoZXJMaXN0ID0gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkTm9kZSwge25vZGVOYW1lIDogIk9MIn0pLAogICAgICAgICAgICB0ZW1wQ2xhc3NOYW1lID0gIl93eXNpaHRtbDUtdGVtcC0iICsgbmV3IERhdGUoKS5nZXRUaW1lKCksCiAgICAgICAgICAgIGlzRW1wdHksCiAgICAgICAgICAgIHRlbXBFbGVtZW50OwoKICAgICAgICBpZiAoIWxpc3QgJiYgIW90aGVyTGlzdCAmJiBjb21wb3Nlci5jb21tYW5kcy5zdXBwb3J0KGNvbW1hbmQpKSB7CiAgICAgICAgICAgIGRvYy5leGVjQ29tbWFuZChjb21tYW5kLCBmYWxzZSwgbnVsbCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmIChsaXN0KSB7CiAgICAgICAgICAgIC8vIFVud3JhcCBsaXN0CiAgICAgICAgICAgIC8vIDx1bD48bGk+Zm9vPC9saT48bGk+YmFyPC9saT48L3VsPgogICAgICAgICAgICAvLyBiZWNvbWVzOgogICAgICAgICAgICAvLyBmb288YnI+YmFyPGJyPgogICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5yZXNvbHZlTGlzdChsaXN0LCBjb21wb3Nlci5jb25maWcudXNlTGluZUJyZWFrcyk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSBpZiAob3RoZXJMaXN0KSB7CiAgICAgICAgICAgIC8vIFR1cm4gYW4gb3JkZXJlZCBsaXN0IGludG8gYW4gdW5vcmRlcmVkIGxpc3QKICAgICAgICAgICAgLy8gPG9sPjxsaT5mb288L2xpPjxsaT5iYXI8L2xpPjwvb2w+CiAgICAgICAgICAgIC8vIGJlY29tZXM6CiAgICAgICAgICAgIC8vIDx1bD48bGk+Zm9vPC9saT48bGk+YmFyPC9saT48L3VsPgogICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5yZW5hbWVFbGVtZW50KG90aGVyTGlzdCwgInVsIik7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIENyZWF0ZSBsaXN0CiAgICAgICAgICAgIGNvbXBvc2VyLmNvbW1hbmRzLmV4ZWMoImZvcm1hdEJsb2NrIiwgImRpdiIsIHRlbXBDbGFzc05hbWUpOwogICAgICAgICAgICB2YXIgdGVtcEVsZW1lbnRzID0gZG9jLnF1ZXJ5U2VsZWN0b3JBbGwoIi4iICsgdGVtcENsYXNzTmFtZSk7CiAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudHMpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggPCB0ZW1wRWxlbWVudHMubGVuZ3RoOyBpbmRleCsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGVtcEVsZW1lbnQgPSB0ZW1wRWxlbWVudHNbaW5kZXhdOwogICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0ID0gd3lzaWh0bWw1LmRvbS5jb252ZXJ0VG9MaXN0KHRlbXBFbGVtZW50LCAidWwiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXBFbGVtZW50Lm5vZGVOYW1lICE9ICJMSSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wRWxlbWVudCA9IHd5c2lodG1sNS5kb20ucmVuYW1lRWxlbWVudCh0ZW1wRWxlbWVudCwgImxpIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUuZG9tLnJlbW92ZUNsYXNzKHRlbXBFbGVtZW50LCB0ZW1wQ2xhc3NOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFdyYXAgd2l0aGluIHBhcmEgdGFnIGlmIG5vIGJsb2NrIGVsZW1lbnQgcHJlc2VudCovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRlbXBFbGVtZW50LnF1ZXJ5U2VsZWN0b3Iod3lzaWh0bWw1LkJMT0NLX0VMRU1FTlRTX0dST1VQLmpvaW4oIiwiKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPSAiPHA+IiArIHRlbXBFbGVtZW50LmlubmVySFRNTCArICI8L3A+IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuYXBwZW5kQ2hpbGQodGVtcEVsZW1lbnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlzRW1wdHkgPSB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPT09ICIiIHx8IHRlbXBFbGVtZW50LmlubmVySFRNTCA9PT0gd3lzaWh0bWw1LklOVklTSUJMRV9TUEFDRSB8fCB0ZW1wRWxlbWVudC5pbm5lckhUTUwgPT09ICI8YnI+IjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRW1wdHkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZWxlY3ROb2RlKGxpc3QucXVlcnlTZWxlY3RvcigibGkiKSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyKSB7CiAgICAgICAgdmFyIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKTsKICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkTm9kZSwge25vZGVOYW1lIDogIlVMIn0pOwogICAgfSwKCiAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyKSB7CiAgICAgICAgdmFyIGRvbUVsZW0gPSB0aGlzLnN0YXRlKGNvbXBvc2VyKTsKICAgICAgICBpZiAoZG9tRWxlbSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9Owp3eXNpaHRtbDUuY29tbWFuZHMuaXRhbGljID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLmV4ZWMoY29tcG9zZXIsIGNvbW1hbmQsICJpIik7CiAgICAgICAgLy9yZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5leGVjKGNvbXBvc2VyLCBjb21tYW5kLCAiaSIpOwogICAgfSwKCiAgICBzdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgIC8vIGVsZW1lbnQub3duZXJEb2N1bWVudC5xdWVyeUNvbW1hbmRTdGF0ZSgiaXRhbGljIikgcmVzdWx0czoKICAgICAgICAvLyBmaXJlZm94OiBvbmx5IDxpPgogICAgICAgIC8vIGNocm9tZTogIDxpPiwgPGVtPiwgPGJsb2NrcXVvdGU+LCAuLi4KICAgICAgICAvLyBpZTogICAgICA8aT4sIDxlbT4KICAgICAgICAvLyBvcGVyYTogICBvbmx5IDxpPgogICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAiaSIpOwogICAgfQp9OwoKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHd5c2lodG1sNS5jb21tYW5kcy5pbmNyZWFzZUluZGVudCA9IHsKICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciByYW5nZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRSYW5nZSgpOwogICAgICAgICAgICB2YXIgdGV4dE5vZGVzID0gcmFuZ2UuZ2V0Tm9kZXMoW3d5c2lodG1sNS5URVhUX05PREVdKTsKICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZVZhbHVlOwogICAgICAgICAgICBpZiAodGV4dE5vZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgdmFyIHRleHROb2RlOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRleHROb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICAgICAgICAgICsraSkgewogICAgICAgICAgICAgICAgICAgIHRleHROb2RlID0gdGV4dE5vZGVzW2ldOwogICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnQgPSB0ZXh0Tm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZVZhbHVlID0gcGFyZW50LnN0eWxlWyJwYWRkaW5nLWxlZnQiXTsKICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVWYWx1ZSA9IGF0dHJpYnV0ZVZhbHVlLnJlcGxhY2UoL3B4LywgIiIpOwogICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZVZhbHVlID0gYXR0cmlidXRlVmFsdWUucmVwbGFjZSgvcHQvLCAiIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSBwYXJzZUludCg0MCkgKyBwYXJzZUludChhdHRyaWJ1dGVWYWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZSArICJwdCI7CgogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsidGV4dC1pbmRlbnQiIDogdmFsdWV9OwoKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAicGFkZGluZy1sZWZ0IiwgL3BhZGRpbmctbGVmdC9nLCBhdHRyaWJ1dGVzKTsKICAgICAgICB9LAoKICAgICAgICBzdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgdmFsdWUpIHsKICAgICAgICAgICAgLy8gZWxlbWVudC5vd25lckRvY3VtZW50LnF1ZXJ5Q29tbWFuZFN0YXRlKCJpdGFsaWMiKSByZXN1bHRzOgogICAgICAgICAgICAvLyBmaXJlZm94OiBvbmx5IDxpPgogICAgICAgICAgICAvLyBjaHJvbWU6ICA8aT4sIDxlbT4sIDxibG9ja3F1b3RlPiwgLi4uCiAgICAgICAgICAgIC8vIGllOiAgICAgIDxpPiwgPGVtPgogICAgICAgICAgICAvLyBvcGVyYTogICBvbmx5IDxpPgogICAgICAgICAgICAvL3JldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAic3BhbiIsImZvbnQtZmFtaWx5LSIrZm9udGZhbWlseSwnL2ZvbnQtZmFtaWx5LVswLTlhLXpdKy9nJywiZm9udC1mYW1pbHkiLGZvbnRmYW1pbHkpOwogICAgICAgICAgICB2YWx1ZSA9IHZhbHVlICsgInB0IjsKICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7InRleHQtaW5kZW50IiA6IHZhbHVlfTsKCiAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAic3BhbiIsICJwYWRkaW5nLWxlZnQiLCAvcGFkZGluZy1sZWZ0L2csIGF0dHJpYnV0ZXMpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CgooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmZvbnRGYW1pbHkgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgZm9udGZhbWlseSkgewoKICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7ImZvbnQtZmFtaWx5IiA6IGZvbnRmYW1pbHl9OwoKICAgICAgICAgICAgLy9yZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5leGVjKGNvbXBvc2VyLCBjb21tYW5kLCAicCIsImZvbnQtZmFtaWx5LSIrZm9udGZhbWlseSwvZm9udC1mYW1pbHktWzAtOWEtel0rL2csImZvbnQtZmFtaWx5Iixmb250ZmFtaWx5KTsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAiZm9udC1mYW1pbHkiLCAvZm9udC1mYW1pbHkvZywgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGZvbnRmYW1pbHkpIHsKICAgICAgICAgICAgLy8gZWxlbWVudC5vd25lckRvY3VtZW50LnF1ZXJ5Q29tbWFuZFN0YXRlKCJpdGFsaWMiKSByZXN1bHRzOgogICAgICAgICAgICAvLyBmaXJlZm94OiBvbmx5IDxpPgogICAgICAgICAgICAvLyBjaHJvbWU6ICA8aT4sIDxlbT4sIDxibG9ja3F1b3RlPiwgLi4uCiAgICAgICAgICAgIC8vIGllOiAgICAgIDxpPiwgPGVtPgogICAgICAgICAgICAvLyBvcGVyYTogICBvbmx5IDxpPgogICAgICAgICAgICAvL3JldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAic3BhbiIsImZvbnQtZmFtaWx5LSIrZm9udGZhbWlseSwnL2ZvbnQtZmFtaWx5LVswLTlhLXpdKy9nJywiZm9udC1mYW1pbHkiLGZvbnRmYW1pbHkpOwogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiZm9udC1mYW1pbHkiIDogZm9udGZhbWlseX07CgogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAiZm9udC1mYW1pbHkiLCAvZm9udC1mYW1pbHkvZywgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKICAgICAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciBkb21FbGVtID0gdGhpcy5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgbnVsbCk7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IFtdOwogICAgICAgICAgICAvLyBkb21FbGVtZW50IGkuZSBTZWxlY3RlZCB0ZXh0IG5vZGVzIGV4aXN0CiAgICAgICAgICAgIGlmIChkb21FbGVtICYmIGRvbUVsZW0ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB2YXIgZm9udEZhbWlseTsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZG9tRWxlbS5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIC8vIGRvbUVsZW1lbnQgaGFzIHN0eWxlIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgIGlmIChkb21FbGVtW2ldLnN0eWxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldHRpbmcgZGlmZmVyZW50IGZvbnQgZmFtaWxpZXMgYXBwbGllZCB0byBzZWxlY3RlZCB0ZXh0cwogICAgICAgICAgICAgICAgICAgICAgICBmb250RmFtaWx5ID0gZG9tRWxlbVtpXS5zdHlsZS5mb250RmFtaWx5OwogICAgICAgICAgICAgICAgICAgICAgICBmb250RmFtaWx5ID0gZm9udEZhbWlseS5zcGxpdCgiLCIpWzBdOwogICAgICAgICAgICAgICAgICAgICAgICBmb250RmFtaWx5ID0gZm9udEZhbWlseS5yZXBsYWNlKC9cIi9nLCAiIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnRGYW1pbHkgPSBmb250RmFtaWx5LnJlcGxhY2UoLycvZywgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBmb250IGZhbWlseSBpcyBub3QgYWxyZWFkeSByZXRyaWV2ZWQgZnJvbSBzZWxlY3RlZCB0ZXh0cywgYWRkIGZvbnQgZmFtaWx5CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmFsdWUuaW5jbHVkZXMoZm9udEZhbWlseSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLnB1c2goZm9udEZhbWlseSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMuY3VzdG9tU3R5bGUgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgY2xhc3NlcykgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiY3VzdG9tU3R5bGVBdHRyaWJ1dGUiIDogdHJ1ZX07CiAgICAgICAgICAgIHZhciBjbGFzc05hbWUgPSAiIHRleHRFZGl0b3ItY3VzdG9tU3R5bGUgIjsKICAgICAgICAgICAgdmFyIFJFR19FWFAgPSBuZXcgUmVnRXhwKGNsYXNzTmFtZSArICJjbS10ZXh0ZWRpdG9yLWN1c3RvbXN0eWxlLVthLXpdKyIsICJnIik7CiAgICAgICAgICAgIGlmIChjbGFzc2VzKSB7CiAgICAgICAgICAgICAgICBjbGFzc05hbWUgKz0gY2xhc3NlczsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5leGVjKGNvbXBvc2VyLCBjb21tYW5kLCAic3BhbiIsIGNsYXNzTmFtZSwgUkVHX0VYUCwgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGRhdGFBdHRyaWJ1dGUsIGNsZWFyUHJlRGF0YUF0dHJpYnV0ZSwgY2xhc3NlcykgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiY3VzdG9tU3R5bGVBdHRyaWJ1dGUiIDogdHJ1ZX07CiAgICAgICAgICAgIHZhciBjbGFzc05hbWUgPSAiIHRleHRFZGl0b3ItY3VzdG9tU3R5bGUgIjsKICAgICAgICAgICAgdmFyIFJFR19FWFAgPSBuZXcgUmVnRXhwKGNsYXNzTmFtZSArICJjbS10ZXh0ZWRpdG9yLWN1c3RvbXN0eWxlLVthLXpdKyIsICJnIik7CiAgICAgICAgICAgIGlmIChjbGFzc2VzKSB7CiAgICAgICAgICAgICAgICBjbGFzc05hbWUgKz0gY2xhc3NlczsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCBjbGFzc05hbWUsIFJFR19FWFAsIGF0dHJpYnV0ZXMpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMuZGF0YUF0dHJpYnV0ZSA9IHsKICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBkYXRhQXR0ciwgY2xlYXJQcmVEYXRhQXR0cmlidXRlKSB7CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJkYXRhQXR0cmlidXRlIiA6IHRydWV9OwogICAgICAgICAgICB2YXIgY2xhc3NOYW1lID0gInRleHRFZGl0b3ItY3VzdG9tRGF0YUF0dHIiOwogICAgICAgICAgICB2YXIgUkVHX0VYUCA9IG5ldyBSZWdFeHAoY2xhc3NOYW1lLCAiZyIpOwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5leGVjKGNvbXBvc2VyLCBjb21tYW5kLCAic3BhbiIsIGNsYXNzTmFtZSwgUkVHX0VYUCwgYXR0cmlidXRlcywgbnVsbCwgZGF0YUF0dHIsIGNsZWFyUHJlRGF0YUF0dHJpYnV0ZSk7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGRhdGFBdHRyaWJ1dGUsIGNsZWFyUHJlRGF0YUF0dHJpYnV0ZSkgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiZGF0YUF0dHJpYnV0ZSIgOiB0cnVlfTsKICAgICAgICAgICAgdmFyIGNsYXNzTmFtZSA9ICJ0ZXh0RWRpdG9yLWN1c3RvbURhdGFBdHRyIjsKICAgICAgICAgICAgdmFyIFJFR19FWFAgPSBuZXcgUmVnRXhwKGNsYXNzTmFtZSwgImciKTsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsICJzcGFuIiwgY2xhc3NOYW1lLCBSRUdfRVhQLCBhdHRyaWJ1dGVzLCBudWxsLCBkYXRhQXR0cmlidXRlLCBjbGVhclByZURhdGFBdHRyaWJ1dGUpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMuaGVhZGVyID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGhlYWRlclR5cGUpIHsKICAgICAgICAgICAgdmFyIGNsYXNzTmFtZSA9ICJ0ZXh0RWRpdG9yLWhlYWRlci0iOwogICAgICAgICAgICB2YXIgUkVHX0VYUCA9IG5ldyBSZWdFeHAoY2xhc3NOYW1lICsgIlteXHNdKiIsICJnIik7CiAgICAgICAgICAgIGNsYXNzTmFtZSArPSBoZWFkZXJUeXBlOwogICAgICAgICAgICB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0QmxvY2suZXhlYyhjb21wb3NlciwgY29tbWFuZCwgaGVhZGVyVHlwZSwgY2xhc3NOYW1lLCBSRUdfRVhQKTsKICAgICAgICAgICAgdmFyIGRvbUVsZW0gPSB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0QmxvY2suc3RhdGUoY29tcG9zZXIsICdsaW5lSGVpZ2h0JywgaGVhZGVyVHlwZSk7CiAgICAgICAgICAgIHd5c2lodG1sNS51dGlsLmNsZWFyRm9udFNpemUoZG9tRWxlbSk7CiAgICAgICAgICAgIHZhciBsZWFkaW5nOwogICAgICAgICAgICBpZiAoZG9tRWxlbSAmJiBkb21FbGVtLnN0eWxlICYmIGRvbUVsZW0uc3R5bGUubGluZUhlaWdodCkgewogICAgICAgICAgICAgICAgY29tcG9zZXIuc2VsZWN0aW9uLnNlbGVjdE5vZGUoZG9tRWxlbSk7CiAgICAgICAgICAgICAgICB2YXIgY29tcHV0ZWRTdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShkb21FbGVtKTsKICAgICAgICAgICAgICAgIHZhciBtYXhGb250U2l6ZSA9IDA7CiAgICAgICAgICAgICAgICBpZiAoY29tcHV0ZWRTdHlsZXMpIHsKICAgICAgICAgICAgICAgICAgICBtYXhGb250U2l6ZSA9IGNvbXB1dGVkU3R5bGVzLmZvbnRTaXplOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCFtYXhGb250U2l6ZSkgewogICAgICAgICAgICAgICAgICAgIG1heEZvbnRTaXplID0gY29tcG9zZXIuY29uZmlnLmRlZmF1bHRGb250U2l6ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChkb21FbGVtLmdldEF0dHJpYnV0ZSkgewogICAgICAgICAgICAgICAgICAgIGxlYWRpbmcgPSAoZG9tRWxlbSkuZ2V0QXR0cmlidXRlKCJsZWFkaW5nIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIWxlYWRpbmcpIHsKICAgICAgICAgICAgICAgICAgICBsZWFkaW5nID0gY29tcG9zZXIuY29uZmlnLmRlZmF1bHRMaW5lSGVpZ2h0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGxpbmVIZWlnaHRWYWx1ZSA9IHBhcnNlSW50KGxlYWRpbmcpICsgcGFyc2VJbnQobWF4Rm9udFNpemUpOwogICAgICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7bGluZUhlaWdodCA6IGxpbmVIZWlnaHRWYWx1ZSwgbGVhZGluZyA6IGxlYWRpbmd9OwogICAgICAgICAgICAgICAgLy8gYWRqdXN0aW5nIGxlYWRpbmcgYW5kIGxpbmVoZWlnaHQgZGVwZW5kaW5nIHVwb24gY2hhbmdlIGluIGZvbnRzaXplLCB0aGlzIGlzIHBhcnQgb2YgZm9udHNpemUgdHJhbnNhY3Rpb24sIHdlIHdvbid0IGFsbG93IHVuZG8gZm9yIHRoaXMuCiAgICAgICAgICAgICAgICBkb21FbGVtLnN0eWxlLnNldFByb3BlcnR5KCJsaW5lLWhlaWdodCIsIGxpbmVIZWlnaHRWYWx1ZSArICJwdCIpOwogICAgICAgICAgICAgICAgZG9tRWxlbS5zZXRBdHRyaWJ1dGUoImxlYWRpbmciLCBsZWFkaW5nKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBoZWFkZXJUeXBlKSB7CiAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0QmxvY2suc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsIGhlYWRlclR5cGUpOwogICAgICAgIH0sCiAgICAgICAgY2FsbGJhY2tTdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgICAgICB2YXIgZG9tRWxlbSA9IHRoaXMuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsIFsiUCIsICJIMSIsICJIMiIsICJIMyIsICJINCIsICJINSIsICJINiJdKTsKICAgICAgICAgICAgdmFyIHZhbHVlID0gIiI7CiAgICAgICAgICAgIGlmIChkb21FbGVtICYmIGRvbUVsZW0ubm9kZU5hbWUpIHsKICAgICAgICAgICAgICAgIHZhbHVlID0gZG9tRWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgaWYgKCF3eXNpaHRtbDUuaGVscGVyRm4pIHsKICAgICAgICB3eXNpaHRtbDUuaGVscGVyRm4gPSB7fTsKICAgIH0KCiAgICB3eXNpaHRtbDUuaGVscGVyRm4uZ2V0UHJvcGVydHlWYWx1ZSA9IGZ1bmN0aW9uIChkb21FbGVtLCBwcm9wZXJ0eU5hbWUpIHsKICAgICAgICBpZiAoZG9tRWxlbSAmJiBkb21FbGVtLnN0eWxlKSB7CiAgICAgICAgICAgIHJldHVybiBkb21FbGVtLnN0eWxlLmdldFByb3BlcnR5VmFsdWUocHJvcGVydHlOYW1lKS5yZXBsYWNlKCdwdCcsICcnKS5yZXBsYWNlKCdweCcsICcnKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwoKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHd5c2lodG1sNS5jb21tYW5kcy5tYXJnaW5MZWZ0ID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIHZhbHVlKSB7CiAgICAgICAgICAgIHZhciBtYXJnaW5WYWx1ZSA9IHZhbHVlICsgInB0IjsKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJtYXJnaW4tbGVmdCIgOiBtYXJnaW5WYWx1ZX0pOwogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBtYXJnaW5WYWx1ZSkgewogICAgICAgICAgICBpZiAobWFyZ2luVmFsdWUpIHsKICAgICAgICAgICAgICAgIG1hcmdpblZhbHVlID0gbWFyZ2luVmFsdWUgKyAicHQiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJtYXJnaW4tbGVmdCIgOiBtYXJnaW5WYWx1ZX07CiAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0QmxvY2suc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsIFsiUCIsICJMSSIsICJIMSIsICJIMiIsICJIMyIsICJINCIsICJINSIsICJINiJdLCAibWFyZ2luLWxlZnQiLCAvbWFyZ2luLWxlZnQvZywgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKCiAgICAgICAgY2FsbGJhY2tTdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgbWFyZ2luVmFsdWUpIHsKICAgICAgICAgICAgdmFyIGRvbUVsZW0gPSB0aGlzLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kKTsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5oZWxwZXJGbi5nZXRQcm9wZXJ0eVZhbHVlKGRvbUVsZW0sICJtYXJnaW4tbGVmdCIpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMubWFyZ2luUmlnaHQgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgdmFsdWUpIHsKICAgICAgICAgICAgdmFyIG1hcmdpblZhbHVlID0gdmFsdWUgKyAicHQiOwogICAgICAgICAgICBjb21wb3Nlci5hcHBseVN0eWxlKGNvbXBvc2VyLCB7Im1hcmdpbi1yaWdodCIgOiBtYXJnaW5WYWx1ZX0pOwogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBtYXJnaW5WYWx1ZSkgewogICAgICAgICAgICBpZiAobWFyZ2luVmFsdWUpIHsKICAgICAgICAgICAgICAgIG1hcmdpblZhbHVlID0gbWFyZ2luVmFsdWUgKyAicHQiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJtYXJnaW4tcmlnaHQiIDogbWFyZ2luVmFsdWV9OwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdEJsb2NrLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCBbIlAiLCAiTEkiLCAiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiXSwgIm1hcmdpbi1yaWdodCIsIC9tYXJnaW4tcmlnaHQvZywgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKCiAgICAgICAgY2FsbGJhY2tTdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgICAgICB2YXIgZG9tRWxlbSA9IHRoaXMuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQpOwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmhlbHBlckZuLmdldFByb3BlcnR5VmFsdWUoZG9tRWxlbSwgIm1hcmdpbi1yaWdodCIpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMubWFyZ2luVG9wID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIHZhbHVlKSB7CiAgICAgICAgICAgIHZhciBtYXJnaW5WYWx1ZSA9IHZhbHVlICsgInB0IjsKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJtYXJnaW4tdG9wIiA6IG1hcmdpblZhbHVlfSk7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIG1hcmdpblZhbHVlKSB7CiAgICAgICAgICAgIGlmIChtYXJnaW5WYWx1ZSkgewogICAgICAgICAgICAgICAgbWFyZ2luVmFsdWUgPSBtYXJnaW5WYWx1ZSArICJwdCI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7Im1hcmdpbi10b3AiIDogbWFyZ2luVmFsdWV9OwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdEJsb2NrLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCBbIlAiLCAiTEkiLCAiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiXSwgIm1hcmdpbi10b3AiLCAvbWFyZ2luLXRvcC9nLCBhdHRyaWJ1dGVzKTsKICAgICAgICB9LAoKICAgICAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciBkb21FbGVtID0gdGhpcy5zdGF0ZShjb21wb3NlciwgY29tbWFuZCk7CiAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUuaGVscGVyRm4uZ2V0UHJvcGVydHlWYWx1ZShkb21FbGVtLCAibWFyZ2luLXRvcCIpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMubWFyZ2luQm90dG9tID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIHZhbHVlKSB7CiAgICAgICAgICAgIHZhciBtYXJnaW5WYWx1ZSA9IHZhbHVlICsgInB0IjsKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJtYXJnaW4tYm90dG9tIiA6IG1hcmdpblZhbHVlfSk7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIG1hcmdpblZhbHVlKSB7CiAgICAgICAgICAgIGlmIChtYXJnaW5WYWx1ZSkgewogICAgICAgICAgICAgICAgbWFyZ2luVmFsdWUgPSBtYXJnaW5WYWx1ZSArICJwdCI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7Im1hcmdpbi1ib3R0b20iIDogbWFyZ2luVmFsdWV9OwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdEJsb2NrLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCBbIlAiLCAiTEkiLCAiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiXSwgIm1hcmdpbi1ib3R0b20iLCAvbWFyZ2luLWJvdHRvbS9nLCBhdHRyaWJ1dGVzKTsKICAgICAgICB9LAoKICAgICAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBtYXJnaW5WYWx1ZSkgewogICAgICAgICAgICB2YXIgZG9tRWxlbSA9IHRoaXMuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsIG51bGwpOwogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmhlbHBlckZuLmdldFByb3BlcnR5VmFsdWUoZG9tRWxlbSwgIm1hcmdpbi1ib3R0b20iKTsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwoKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHd5c2lodG1sNS5jb21tYW5kcy5sZXR0ZXJTcGFjaW5nID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIHZhbCkgewogICAgICAgICAgICB2YWwgPSB2YWwgKyAicHQiOwogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsibGV0dGVyLXNwYWNpbmciIDogdmFsfTsKCiAgICAgICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLmV4ZWMoY29tcG9zZXIsIGNvbW1hbmQsICJzcGFuIiwgImxldHRlci1zcGFjaW5nIiwgL2xldHRlci1zcGFjaW5nL2csIGF0dHJpYnV0ZXMpOwogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCB2YWwpIHsKICAgICAgICAgICAgaWYgKHZhbCkgewogICAgICAgICAgICAgICAgdmFsID0gdmFsICsgInB0IjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsibGV0dGVyLXNwYWNpbmciIDogdmFsfTsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsICJzcGFuIiwgImxldHRlci1zcGFjaW5nIiwgL2xldHRlci1zcGFjaW5nL2csIGF0dHJpYnV0ZXMpOwogICAgICAgIH0sCgogICAgICAgIGNhbGxiYWNrU3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICAgICAgdmFyIGRvbUVsZW0gPSB0aGlzLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCBudWxsKTsKICAgICAgICAgICAgdmFyIHZhbHVlID0gIiI7CiAgICAgICAgICAgIGlmIChkb21FbGVtKSB7CiAgICAgICAgICAgICAgICB2YWx1ZSA9IHd5c2lodG1sNS5oZWxwZXJGbi5nZXRQcm9wZXJ0eVZhbHVlKGRvbUVsZW1bMF0sICJsZXR0ZXItc3BhY2luZyIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmxpbmVIZWlnaHQgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgYXR0cmlidXRlcykgewogICAgICAgICAgICB2YXIgbGluZUhlaWdodFZhbHVlID0gYXR0cmlidXRlcy5saW5lSGVpZ2h0OwogICAgICAgICAgICBsaW5lSGVpZ2h0VmFsdWUgPSBsaW5lSGVpZ2h0VmFsdWUgKyAicHQiOwogICAgICAgICAgICB2YXIgbGVhZGluZ1ZhbHVlID0gYXR0cmlidXRlcy5sZWFkaW5nOwogICAgICAgICAgICBjb21wb3Nlci5hcHBseVN0eWxlKGNvbXBvc2VyLCB7ImxpbmUtaGVpZ2h0IiA6IGxpbmVIZWlnaHRWYWx1ZX0sIHsibGVhZGluZyIgOiBsZWFkaW5nVmFsdWV9KTsKICAgICAgICB9LAogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCB2YWwpIHsKICAgICAgICAgICAgaWYgKHZhbCkgewogICAgICAgICAgICAgICAgdmFsID0gdmFsICsgInB0IjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsibGluZS1oZWlnaHQiIDogdmFsfTsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRCbG9jay5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInAiLCAibGluZS1oZWlnaHQiLCAvbGluZS1oZWlnaHQvZywgYXR0cmlidXRlcyk7CiAgICAgICAgfSwKICAgICAgICBjYWxsYmFja1N0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciBkb21FbGVtID0gdGhpcy5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgbnVsbCk7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9ICIiOwogICAgICAgICAgICBpZiAoZG9tRWxlbSkgewogICAgICAgICAgICAgICAgdmFsdWUgPSAoZG9tRWxlbSkuZ2V0QXR0cmlidXRlKCJsZWFkaW5nIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMub3V0ZGVudCA9IHsKICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBhbGlnblZhbHVlKSB7CiAgICAgICAgICAgIGlmIChjb21wb3Nlci5jb21tYW5kcy5zdXBwb3J0KGNvbW1hbmQpKSB7CiAgICAgICAgICAgICAgICBjb21wb3Nlci5kb2MuZXhlY0NvbW1hbmQoY29tbWFuZCwgZmFsc2UsICcwcHQgNXB0IDBwdCAwcHQnKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBhbGlnblZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgd3lzaWh0bWw1LmNvbW1hbmRzLmp1c3RpZnlMZWZ0ID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJ0ZXh0LWFsaWduIiA6ICJsZWZ0In0pOwogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJ0ZXh0LWFsaWduIiA6ICJsZWZ0In07CgogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdEJsb2NrLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAicCIsICJ0ZXh0LWFsaWduIiwgL3RleHQtYWxpZ24vZywgYXR0cmlidXRlcyk7CiAgICAgICAgfQogICAgfTsKfSkod3lzaWh0bWw1KTsKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHd5c2lodG1sNS5jb21tYW5kcy5qdXN0aWZ5Q2VudGVyID0gewogICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJ0ZXh0LWFsaWduIiA6ICJjZW50ZXIifSk7CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7InRleHQtYWxpZ24iIDogImNlbnRlciJ9OwoKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRCbG9jay5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInAiLCAidGV4dC1hbGlnbiIsIC90ZXh0LWFsaWduL2csIGF0dHJpYnV0ZXMpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB3eXNpaHRtbDUuY29tbWFuZHMuanVzdGlmeUZ1bGwgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewoKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJ0ZXh0LWFsaWduIiA6ICJqdXN0aWZ5In0pOwogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJ0ZXh0LWFsaWduIiA6ICJqdXN0aWZ5In07CgogICAgICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdEJsb2NrLnN0YXRlKGNvbXBvc2VyLCBjb21tYW5kLCAicCIsICJ0ZXh0LWFsaWduIiwgL3RleHQtYWxpZ24vZywgYXR0cmlidXRlcyk7CiAgICAgICAgfQogICAgfTsKfSkod3lzaWh0bWw1KTsKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHd5c2lodG1sNS5jb21tYW5kcy5qdXN0aWZ5UmlnaHQgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewoKICAgICAgICAgICAgY29tcG9zZXIuYXBwbHlTdHlsZShjb21wb3NlciwgeyJ0ZXh0LWFsaWduIiA6ICJyaWdodCJ9KTsKICAgICAgICB9LAoKICAgICAgICBzdGF0ZSA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsidGV4dC1hbGlnbiIgOiAicmlnaHQifTsKICAgICAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRCbG9jay5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInAiLCAidGV4dC1hbGlnbiIsIC90ZXh0LWFsaWduL2csIGF0dHJpYnV0ZXMpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7Cgp3eXNpaHRtbDUudXRpbCA9IHt9OwovL0ZvciBmaXhpbmcgTEMtMzkxMTk1NQp3eXNpaHRtbDUudXRpbC5jbGVhckZvbnRTaXplID0gZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgIGlmIChlbGVtZW50ICYmIGVsZW1lbnQuY2hpbGRFbGVtZW50Q291bnQgPiAwKSB7CiAgICAgICAgZm9yICh2YXIgZWxlLCBpbmRleCA9IDA7CiAgICAgICAgICAgICBpbmRleCA8IGVsZW1lbnQuY2hpbGRFbGVtZW50Q291bnQ7CiAgICAgICAgICAgICBpbmRleCsrKSB7CiAgICAgICAgICAgIGVsZSA9IGVsZW1lbnQuY2hpbGRyZW5baW5kZXhdOwogICAgICAgICAgICBpZiAoZWxlICYmIGVsZS5zdHlsZSkgewogICAgICAgICAgICAgICAgZWxlLnN0eWxlLnNldFByb3BlcnR5KCJmb250LXNpemUiLCAiIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGVsZS5jaGlsZEVsZW1lbnRDb3VudCA+IDApIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS51dGlsLmNsZWFyRm9udFNpemUoZWxlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfTsKCnd5c2lodG1sNS51dGlsLmlzRWRpdG9yTm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICByZXR1cm4gbm9kZSAmJiBub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT0gImRpdiIgJiYgbm9kZS5jbGFzc0xpc3QuY29udGFpbnMoInd5c2lodG1sNS1lZGl0b3IiKTsKfTsKCnd5c2lodG1sNS51dGlsLmNoYW5nZUxpbmVIZWlnaHQgPSBmdW5jdGlvbiAobGVhZGluZywgYWxsb3dVbmRvLCBub2RlTmFtZSwgY29tcG9zZXIsIGZvcmNlQXBwbHkpIHsKICAgIGlmIChsZWFkaW5nID09IHVuZGVmaW5lZCkgewogICAgICAgIGxlYWRpbmcgPSBjb21wb3Nlci5jb25maWcuZGVmYXVsdExpbmVIZWlnaHQ7CiAgICB9CiAgICBpZiAoYWxsb3dVbmRvID09IHVuZGVmaW5lZCkgewogICAgICAgIGFsbG93VW5kbyA9IHRydWU7CiAgICB9CiAgICBpZiAobm9kZU5hbWUgPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgbm9kZU5hbWUgPSAiUCI7CiAgICB9CiAgICB2YXIgc2VsZWN0aW9uID0gY29tcG9zZXIuc2VsZWN0aW9uOwogICAgdmFyIGN1cnJlbnRTZWxlY3Rpb24gPSBzZWxlY3Rpb24uZ2V0UmFuZ2UoKTsKICAgIGlmICghY3VycmVudFNlbGVjdGlvbiAmJiBmb3JjZUFwcGx5KSB7Ly8gRml4aW5nIExDLTM5MTE5OTQKICAgICAgICBzZWxlY3Rpb24uc2V0U2VsZWN0aW9uKHNlbGVjdGlvbi5lZGl0b3Iuc2F2ZWRTZWxlY3Rpb24pOwogICAgICAgIGN1cnJlbnRTZWxlY3Rpb24gPSBzZWxlY3Rpb24uZ2V0UmFuZ2UoKTsKICAgIH0KICAgIGlmICghY3VycmVudFNlbGVjdGlvbikgewogICAgICAgIHdpbmRvdy5jb25zb2xlLmxvZygiVGhpcyBlcnJvciBpcyBkdWUgdG8gY2hhbmdlTGluZUhlaWdodCBmdW5jdGlvbi4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICAvKiBmaW5kIHRoZSBtYXhtaW11bSBmb250U2l6ZSBpbiBhIHBhcmFncmFwaCwgYXMgbGluZWhlaWdodCBpcyBhIGJsb2NrIGxldmVsIGF0dHJpYnV0ZSwgbmVlZCB0byBmaW5kIHRoZSBtYXhpbXVtIGZvbnQtc2l6ZSBiZWZvcmUgY2FsY3VsYXRpbmcgbmV3IGxpbmUgaGVpZ2h0Ki8KICAgIHZhciBtYXRjaGluZ1NldCA9IHtub2RlTmFtZSA6IG5vZGVOYW1lfTsKICAgIHZhciBzZWxlY3RlZFRleHRBcnIgPSBzZWxlY3Rpb24uZ2V0Tm9kZXMoMyk7CiAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICBzZWxlY3RlZFRleHRBcnIuZm9yRWFjaChmdW5jdGlvbiAodGV4dCkgewogICAgICAgIHZhciBwYXJlbnRQYXJhZ3JhcGggPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQodGV4dCwgbWF0Y2hpbmdTZXQpOwogICAgICAgIGlmICghcGFyZW50UGFyYWdyYXBoKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaWYgKChwYXJlbnRQYXJhZ3JhcGggJiYgcGFyZW50UGFyYWdyYXBoLnN0eWxlICYmIHBhcmVudFBhcmFncmFwaC5zdHlsZS5saW5lSGVpZ2h0KSB8fCBmb3JjZUFwcGx5KSB7CiAgICAgICAgICAgIHNlbGVjdGlvbi5zZWxlY3ROb2RlKHBhcmVudFBhcmFncmFwaCk7CiAgICAgICAgICAgIHZhciBmb250U2l6ZVNwYW5BcnIgPSB3eXNpaHRtbDUuY29tbWFuZHMuZm9udFNpemUuc3RhdGUoY29tcG9zZXIsICJmb250U2l6ZSIpOwogICAgICAgICAgICBmb250U2l6ZVNwYW5BcnIgPSBbXS5jb25jYXQoZm9udFNpemVTcGFuQXJyKTsgICAvLyBnZXRDb21tYW5kU3RhdGUgc29tZXRpbWVzIGNhbiByZXR1cm4gYSBzaW5nbGUgc3BhbiBvciBhbiBhcnJheSwgZm9yY2VmdWxseSBjb252ZXJ0aW5nIGludG8gYW4gYXJyYXkKICAgICAgICAgICAgdmFyIG1heEZvbnRTaXplID0gMDsKICAgICAgICAgICAgZm9udFNpemVTcGFuQXJyLmZvckVhY2goZnVuY3Rpb24gKHNwYW4pIHsKICAgICAgICAgICAgICAgIGlmIChzcGFuICYmIHNwYW4uc3R5bGUgJiYgc3Bhbi5zdHlsZS5mb250U2l6ZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBmb250U2l6ZSA9IHNwYW4uc3R5bGUuZm9udFNpemUucmVwbGFjZSgiL3B4LyIsICIiKTsKICAgICAgICAgICAgICAgICAgICBmb250U2l6ZSA9IGZvbnRTaXplLnJlcGxhY2UoIi9wdC8iLCAiIik7CiAgICAgICAgICAgICAgICAgICAgZm9udFNpemUgPSBwYXJzZUludChmb250U2l6ZSk7CiAgICAgICAgICAgICAgICAgICAgbWF4Rm9udFNpemUgPSBNYXRoLm1heChmb250U2l6ZSwgbWF4Rm9udFNpemUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIGlmIChtYXhGb250U2l6ZSA9PSAwKSB7CiAgICAgICAgICAgICAgICBtYXhGb250U2l6ZSA9IGNvbXBvc2VyLmNvbmZpZy5kZWZhdWx0Rm9udFNpemU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGxpbmVIZWlnaHRWYWx1ZSA9IHBhcnNlSW50KGxlYWRpbmcpICsgcGFyc2VJbnQobWF4Rm9udFNpemUpOwogICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHtsaW5lSGVpZ2h0IDogbGluZUhlaWdodFZhbHVlLCBsZWFkaW5nIDogbGVhZGluZ307CiAgICAgICAgICAgIC8vIGFkanVzdGluZyBsZWFkaW5nIGFuZCBsaW5laGVpZ2h0IGRlcGVuZGluZyB1cG9uIGNoYW5nZSBpbiBmb250c2l6ZSwgdGhpcyBpcyBwYXJ0IG9mIGZvbnRzaXplIHRyYW5zYWN0aW9uLCB3ZSB3b24ndCBhbGxvdyB1bmRvIGZvciB0aGlzLgogICAgICAgICAgICB3eXNpaHRtbDUuY29tbWFuZHMubGluZUhlaWdodC5leGVjKGNvbXBvc2VyLCAibGluZUhlaWdodCIsIGF0dHJpYnV0ZXMsIGFsbG93VW5kbyk7CiAgICAgICAgfQogICAgfSk7CiAgICBzZWxlY3Rpb24uc2V0U2VsZWN0aW9uKGN1cnJlbnRTZWxlY3Rpb24pOwp9Owp3eXNpaHRtbDUudXRpbC5nZXRUZXh0Tm9kZXMgPSBmdW5jdGlvbiAoc2VsZWN0aW9uKSB7CiAgICB2YXIgdGV4dE5vZGVzID0gc2VsZWN0aW9uLmdldE5vZGVzKHd5c2lodG1sNS5URVhUX05PREUpOwogICAgaWYgKHRleHROb2Rlcy5sZW5ndGggPT0gMCkgewogICAgICAgIHZhciBub2RlID0gc2VsZWN0aW9uLmdldFNlbGVjdGVkTm9kZSgpOwogICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IHd5c2lodG1sNS5URVhUX05PREUpIHsKICAgICAgICAgICAgdGV4dE5vZGVzLnB1c2gobm9kZSk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHRleHROb2RlczsKfTsKCnd5c2lodG1sNS51dGlsLmdldExJTm9kZXNGcm9tVGV4dE5vZGVzID0gZnVuY3Rpb24gKHRleHROb2RlcykgewogICAgdmFyIGxpTm9kZXMgPSBbXTsKICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICBpIDwgdGV4dE5vZGVzLmxlbmd0aDsKICAgICAgICAgKytpKSB7CiAgICAgICAgdmFyIGxpUGFyZW50ID0gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KHRleHROb2Rlc1tpXSwge25vZGVOYW1lIDogIkxJIn0pOwogICAgICAgIGlmIChsaVBhcmVudCkgewogICAgICAgICAgICBsaU5vZGVzLnB1c2gobGlQYXJlbnQpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBsaU5vZGVzOwp9OwoKd3lzaWh0bWw1LnV0aWwuc2V0SW5kZW50ID0gZnVuY3Rpb24gKG5vZGUpIHsKICAgIHZhciBtYXJnaW4gPSBub2RlLnN0eWxlLm1hcmdpbkxlZnQ7CiAgICBtYXJnaW4gPSBtYXJnaW4ucmVwbGFjZSgncHgnLCAnJykucmVwbGFjZSgncHQnLCAnJyk7CiAgICB2YXIgbmV3TWFyZ2luID0gKHBhcnNlSW50KG1hcmdpbikgKyA0MCkgKyAncHQnOwogICAgaWYgKG1hcmdpbiA9PSAiIikgewogICAgICAgIG5ld01hcmdpbiA9ICc0MHB0JzsKICAgIH0KICAgIG5vZGUuc3R5bGUubWFyZ2luTGVmdCA9IG5ld01hcmdpbjsKfTsKd3lzaWh0bWw1LnV0aWwuZGVjcmVhc2VJbmRlbnQgPSBmdW5jdGlvbiAobm9kZSkgewogICAgdmFyIG1hcmdpbiA9IG5vZGUuc3R5bGUubWFyZ2luTGVmdDsKICAgIG1hcmdpbiA9IG1hcmdpbi5yZXBsYWNlKCdweCcsICcnKS5yZXBsYWNlKCdwdCcsICcnKTsKICAgIHZhciBuZXdNYXJnaW4gPSAocGFyc2VJbnQobWFyZ2luKSAtIDQwKSArICdwdCc7CiAgICBub2RlLnN0eWxlLm1hcmdpbkxlZnQgPSBuZXdNYXJnaW47Cn07Cgp3eXNpaHRtbDUudXRpbC5nZXRJbW1lZGlhdGVDaGlsZHNCeVRhZ05hbWUgPSBmdW5jdGlvbiAobm9kZSwgdGFnTmFtZXMpIHsKICAgIHZhciBsaXN0Q2hpbGRzID0gW107CiAgICBpZiAobm9kZSAmJiBub2RlLmNoaWxkcmVuKSB7CiAgICAgICAgZm9yICh2YXIgaSA9IDA7CiAgICAgICAgICAgICBpIDwgbm9kZS5jaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgaWYgKHRhZ05hbWVzLmluZGV4T2Yobm9kZS5jaGlsZHJlbltpXS5ub2RlTmFtZSkgIT0gLTEpIHsKICAgICAgICAgICAgICAgIGxpc3RDaGlsZHMucHVzaChub2RlLmNoaWxkcmVuW2ldKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBsaXN0Q2hpbGRzOwp9OwoKd3lzaWh0bWw1LnV0aWwuZ2V0T2JqZWN0UHJvcGVydHkgPSBmdW5jdGlvbiAob2JqZWN0LCBwYXRoLCBkZWZhdWx0VmFsdWUpIHsKICAgIHZhciBjdXJyT2JqZWN0ID0gb2JqZWN0OwogICAgaWYgKHBhdGgpIHsKICAgICAgICB2YXIgcHJvcHMgPSBwYXRoLnNwbGl0KCIuIik7CiAgICAgICAgcHJvcHMuZm9yRWFjaChmdW5jdGlvbiAocHJvcCkgewogICAgICAgICAgICBpZiAoY3Vyck9iamVjdCAmJiBjdXJyT2JqZWN0Lmhhc093blByb3BlcnR5KHByb3ApKSB7CiAgICAgICAgICAgICAgICBjdXJyT2JqZWN0ID0gY3Vyck9iamVjdFtwcm9wXTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGN1cnJPYmplY3QgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0gZWxzZSB7CiAgICAgICAgY3Vyck9iamVjdCA9IHVuZGVmaW5lZDsKICAgIH0KICAgIGlmIChjdXJyT2JqZWN0KSB7CiAgICAgICAgcmV0dXJuIGN1cnJPYmplY3Q7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CiAgICB9Cn07CgooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgd3lzaWh0bWw1LmNvbW1hbmRzLm91dGRlbnQgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgYWxpZ25WYWx1ZSkgewoKICAgICAgICAgICAgdmFyIHJhbmdlID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFJhbmdlKCk7CgogICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCBzZWxlY3Rpb24gY29udGFpbnMgbGlzdCBvZiBvbmx5IG9uZSBsZXZlbCwgZG9uJ3QgZG8gYW55dGhpbmcgaW4gY2FzZSBvZiBtdWx0aSBsZXZlbCovCiAgICAgICAgICAgIHZhciBzdGFydENvbnRhaW5lclBhcmVudExpc3QgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQocmFuZ2Uuc3RhcnRDb250YWluZXIsIHtub2RlTmFtZSA6IFsiT0wiLCAiVUwiXX0pOwogICAgICAgICAgICB2YXIgZW5kQ29udGFpbmVyUGFyZW50TGlzdCA9IHd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudChyYW5nZS5lbmRDb250YWluZXIsIHtub2RlTmFtZSA6IFsiT0wiLCAiVUwiXX0pOwogICAgICAgICAgICBpZiAoc3RhcnRDb250YWluZXJQYXJlbnRMaXN0ICYmIHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCAhPSBlbmRDb250YWluZXJQYXJlbnRMaXN0KSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChzdGFydENvbnRhaW5lclBhcmVudExpc3QgJiYgc3RhcnRDb250YWluZXJQYXJlbnRMaXN0LnN0eWxlICYmIChzdGFydENvbnRhaW5lclBhcmVudExpc3Quc3R5bGUubWFyZ2luTGVmdCAmJiBzdGFydENvbnRhaW5lclBhcmVudExpc3Quc3R5bGUubWFyZ2luTGVmdCAhPSAiMHB4IiAmJiBzdGFydENvbnRhaW5lclBhcmVudExpc3Quc3R5bGUubWFyZ2luTGVmdCAhPSAiMHB0IikpIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS51dGlsLmRlY3JlYXNlSW5kZW50KHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCk7CiAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2VsZWN0Tm9kZShzdGFydENvbnRhaW5lclBhcmVudExpc3QpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9IGVsc2UgaWYgKCFzdGFydENvbnRhaW5lclBhcmVudExpc3QpIHsKICAgICAgICAgICAgICAgIHZhciBub2RlcyA9IGNvbXBvc2VyLnNlbGVjdGlvbiA/IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXROb2RlcygxKSA6IFtdOwogICAgICAgICAgICAgICAgaWYgKCFub2RlcyB8fCBub2Rlcy5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgICAgIG5vZGVzID0gd3lzaWh0bWw1LnV0aWwuZ2V0VGV4dE5vZGVzKGNvbXBvc2VyLnNlbGVjdGlvbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAobm9kZXMpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgIGkgPCBub2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVzW2ldICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnROb2RlID0gbm9kZXNbaV0ucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2Rlcy5pbmRleE9mKHBhcmVudE5vZGUpIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJhID0gd3lzaWh0bWw1LmRvbS5nZXRQYXJlbnRFbGVtZW50KG5vZGVzW2ldLCB7bm9kZU5hbWUgOiBbIlAiLCAiT0wiLCAiVUwiLCAiRElWIiwgIkgxIiwgIkgyIiwgIkgzIiwgIkg0IiwgIkg1IiwgIkg2Il19KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyYSAmJiBwYXJhLnN0eWxlICYmIHBhcmEuc3R5bGUubWFyZ2luTGVmdCAhPSB1bmRlZmluZWQgJiYgKHBhcmEuc3R5bGUubWFyZ2luTGVmdCAhPSAwICYmIHBhcmEuc3R5bGUubWFyZ2luTGVmdCAhPSAiMHB4IiAmJiBwYXJhLnN0eWxlLm1hcmdpbkxlZnQgIT0gIjBwdCIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHd5c2lodG1sNS51dGlsLmRlY3JlYXNlSW5kZW50KHBhcmEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNvbXBvc2VyLmNvbW1hbmRzLnN1cHBvcnQoY29tbWFuZCkpIHsKICAgICAgICAgICAgICAgIGNvbXBvc2VyLmRvYy5leGVjQ29tbWFuZChjb21tYW5kLCBmYWxzZSwgJzBwdCA1cHQgMHB0IDBwdCcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbGlOb2RlcyA9IHd5c2lodG1sNS51dGlsLmdldExJTm9kZXNGcm9tVGV4dE5vZGVzKHd5c2lodG1sNS51dGlsLmdldFRleHROb2Rlcyhjb21wb3Nlci5zZWxlY3Rpb24pKTsKCiAgICAgICAgICAgIGZvciAodmFyIGkgPSBsaU5vZGVzLmxlbmd0aCAtIDE7CiAgICAgICAgICAgICAgICAgaSA+PSAwOwogICAgICAgICAgICAgICAgIC0taSkgewogICAgICAgICAgICAgICAgdmFyIHBhcmVudExpc3QgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQobGlOb2Rlc1tpXSwge25vZGVOYW1lIDogWyJPTCIsICJVTCJdfSk7CiAgICAgICAgICAgICAgICBpZiAocGFyZW50TGlzdCAmJiBsaU5vZGVzW2ldLnBhcmVudEVsZW1lbnQgJiYgbGlOb2Rlc1tpXS5wYXJlbnRFbGVtZW50Lm5vZGVOYW1lID09ICdMSScpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobGlOb2Rlc1tpXS5wYXJlbnRFbGVtZW50Lm5leHRTaWJsaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudExpc3QuaW5zZXJ0QmVmb3JlKGxpTm9kZXNbaV0sIGxpTm9kZXNbaV0ucGFyZW50RWxlbWVudC5uZXh0U2libGluZyk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50TGlzdC5hcHBlbmRDaGlsZChsaU5vZGVzW2ldKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb21wb3Nlci5zZWxlY3Rpb24uc2VsZWN0Tm9kZShwYXJlbnRMaXN0KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBhbGlnblZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Owp9KSh3eXNpaHRtbDUpOwoKKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHd5c2lodG1sNS5jb21tYW5kcy5pbmRlbnQgPSB7CiAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCwgYWxpZ25WYWx1ZSkgewoKICAgICAgICAgICAgdmFyIHJhbmdlID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFJhbmdlKCk7CiAgICAgICAgICAgIHZhciBzdGFydENvbnRhaW5lclBhcmVudExpc3QgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQocmFuZ2Uuc3RhcnRDb250YWluZXIsIHtub2RlTmFtZSA6IFsiT0wiLCAiVUwiXX0pOwogICAgICAgICAgICBpZiAoc3RhcnRDb250YWluZXJQYXJlbnRMaXN0KSB7CiAgICAgICAgICAgICAgICB2YXIgc3RhcnRDb250YWluZXJQYXJlbnRMaXN0RWxlbWVudCA9IHd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudChyYW5nZS5zdGFydENvbnRhaW5lciwge25vZGVOYW1lIDogIkxJIn0pOwogICAgICAgICAgICAgICAgLyogd2Ugd2FudCB0byBpbnNlcnQgdGhlIG5ldyBPTC9VTCBlbGVtZW50cyBhZnRlciBpbmRlbnQgaW50byB0aGUgc2libGluZyBiZWZvcmUsCiAgICAgICAgICAgICAgICAgaW4gY2FzZSBmaXJzdCBlbGVtZW50IGlzIHNlbGVjdGVkIHRvbywgd2Ugd29uJ3QgaGF2ZSBhbnkgc2libGluZyB0byBpbnNlcnQgbmV3IE9ML1VMIGVsZW1lbnRzIGludG8uCiAgICAgICAgICAgICAgICAgaWYgc2VsZWN0aW9uIGNvbnRhaW5zIGZpcnN0IGVsZW1lbnQgb2YgdGhlIGxpc3Qsc2VsZWN0IHdob2xlIGxpc3QgYW5kIGluZGVudCovCiAgICAgICAgICAgICAgICBpZiAoKHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdEVsZW1lbnQgJiYgc3RhcnRDb250YWluZXJQYXJlbnRMaXN0LmZpcnN0Q2hpbGQgPT0gc3RhcnRDb250YWluZXJQYXJlbnRMaXN0RWxlbWVudCkgfHwgcmFuZ2Uuc3RhcnRDb250YWluZXIubm9kZU5hbWUgPT0gIk9MIikgewogICAgICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZWxlY3ROb2RlKHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCk7CiAgICAgICAgICAgICAgICAgICAgLy8gYXBwbHkgc3R5bGUgb24gdGhpcywgbWFyZ2luLWxlZnQgOiA0MHB4IGFuZCByZXR1cm4KICAgICAgICAgICAgICAgICAgICBpZiAoc3RhcnRDb250YWluZXJQYXJlbnRMaXN0LnN0eWxlICYmIHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdC5zdHlsZS5tYXJnaW5MZWZ0ICE9IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUudXRpbC5zZXRJbmRlbnQoc3RhcnRDb250YWluZXJQYXJlbnRMaXN0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCBzZWxlY3Rpb24gY29udGFpbnMgbGlzdCBvZiBvbmx5IG9uZSBsZXZlbCwgZG9uJ3QgZG8gYW55dGhpbmcgaW4gY2FzZSBvZiBtdWx0aSBsZXZlbCovCiAgICAgICAgICAgIHZhciBzdGFydENvbnRhaW5lclBhcmVudExpc3QgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQocmFuZ2Uuc3RhcnRDb250YWluZXIsIHtub2RlTmFtZSA6IFsiT0wiLCAiVUwiXX0pLAogICAgICAgICAgICAgICAgaW5kZW50VHlwZTsKICAgICAgICAgICAgaWYgKHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCkgewogICAgICAgICAgICAgICAgaW5kZW50VHlwZSA9IHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdC5nZXRBdHRyaWJ1dGUoInR5cGUiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgZW5kQ29udGFpbmVyUGFyZW50TGlzdCA9IHd5c2lodG1sNS5kb20uZ2V0UGFyZW50RWxlbWVudChyYW5nZS5lbmRDb250YWluZXIsIHtub2RlTmFtZSA6IFsiT0wiLCAiVUwiXX0pOwogICAgICAgICAgICBpZiAoc3RhcnRDb250YWluZXJQYXJlbnRMaXN0ICYmIHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCA9PSBlbmRDb250YWluZXJQYXJlbnRMaXN0KSB7CiAgICAgICAgICAgICAgICB2YXIgbGlOb2RlcyA9IHd5c2lodG1sNS51dGlsLmdldExJTm9kZXNGcm9tVGV4dE5vZGVzKHd5c2lodG1sNS51dGlsLmdldFRleHROb2Rlcyhjb21wb3Nlci5zZWxlY3Rpb24pKTsKICAgICAgICAgICAgICAgIGlmIChsaU5vZGVzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0TGlzdE5vZGUgPSBsaU5vZGVzWzBdLnByZXZpb3VzU2libGluZzsKICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0TGlzdE5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxpc3RDaGlsZHMgPSB3eXNpaHRtbDUudXRpbC5nZXRJbW1lZGlhdGVDaGlsZHNCeVRhZ05hbWUodGFyZ2V0TGlzdE5vZGUsIFsiT0wiLCAiVUwiXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPCBsaU5vZGVzLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICArK2kpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsaXN0Q2hpbGRzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0Q2hpbGRzWzBdLmFwcGVuZENoaWxkKGxpTm9kZXNbaV0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3TGlzdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoc3RhcnRDb250YWluZXJQYXJlbnRMaXN0Lm5vZGVOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdMaXN0LnNldEF0dHJpYnV0ZSgidHlwZSIsIGluZGVudFR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0xpc3QuYXBwZW5kQ2hpbGQobGlOb2Rlc1tpXSk7ICAgICAgICAvLyBpIG11c3QgYmUgMCBoZXJlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldExpc3ROb2RlLmFwcGVuZENoaWxkKG5ld0xpc3QpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RDaGlsZHNbMF0gPSBuZXdMaXN0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgd3lzaWh0bWw1LnV0aWwuc2V0SW5kZW50KHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNvbXBvc2VyLnNlbGVjdGlvbi5zZWxlY3ROb2RlKHN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXN0YXJ0Q29udGFpbmVyUGFyZW50TGlzdCkgewogICAgICAgICAgICAgICAgdmFyIG5vZGVzID0gY29tcG9zZXIuc2VsZWN0aW9uID8gY29tcG9zZXIuc2VsZWN0aW9uLmdldE5vZGVzKDEpIDogW107CiAgICAgICAgICAgICAgICBpZiAoIW5vZGVzIHx8IG5vZGVzLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgbm9kZXMgPSB3eXNpaHRtbDUudXRpbC5nZXRUZXh0Tm9kZXMoY29tcG9zZXIuc2VsZWN0aW9uKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChub2RlcykgewogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgaSA8IG5vZGVzLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgICAgICsraSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZXNbaV0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudE5vZGUgPSBub2Rlc1tpXS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVzLmluZGV4T2YocGFyZW50Tm9kZSkgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmEgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQobm9kZXNbaV0sIHtub2RlTmFtZSA6IFsiUCIsICJPTCIsICJVTCIsICJESVYiLCAiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiXX0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJhICYmIHBhcmEuc3R5bGUgJiYgcGFyYS5zdHlsZS5tYXJnaW5MZWZ0ICE9IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUudXRpbC5zZXRJbmRlbnQocGFyYSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGFsaWduVmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7CgooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgd3lzaWh0bWw1LmNvbW1hbmRzLnBhZ2VCcmVhayA9IHsKICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgICAgIHZhciByYW5nZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRSYW5nZSgpOwogICAgICAgICAgICB2YXIgdGV4dE5vZGVzOwogICAgICAgICAgICBpZiAocmFuZ2UpIHsKICAgICAgICAgICAgICAgIHRleHROb2RlcyA9IHJhbmdlLmdldE5vZGVzKFt3eXNpaHRtbDUuVEVYVF9OT0RFXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogRmFsbGJhY2sgaW4gY2FzZSB0aGUgdGV4dCBpcyBub3Qgc2VsZWN0ZWQgYnV0IGN1cnNvciBpcyBmb2N1c2VkIG9uIHRoZSB0ZXh0Ki8KICAgICAgICAgICAgaWYgKHRleHROb2RlcyA9PSBudWxsIHx8IHRleHROb2Rlcy5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkTm9kZSA9IGNvbXBvc2VyLnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKTsKICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZE5vZGUpIHsKICAgICAgICAgICAgICAgICAgICB0ZXh0Tm9kZXMgPSBbc2VsZWN0ZWROb2RlXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGV4dE5vZGVzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgdmFyIHRleHROb2RlOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRleHROb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgIGkgPCBsZW47CiAgICAgICAgICAgICAgICAgICAgICsraSkgewogICAgICAgICAgICAgICAgICAgIHRleHROb2RlID0gdGV4dE5vZGVzW2ldOwogICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnQgPSB3eXNpaHRtbDUuZG9tLmdldFBhcmVudEVsZW1lbnQodGV4dE5vZGUsIHtub2RlTmFtZSA6IFsiUCIsICJIMSIsICJIMiIsICJIMyIsICJINCIsICJINSIsICJINiJdfSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3R5bGVBdHRyaWJ1dGUgPSBwYXJlbnQuZ2V0QXR0cmlidXRlKCJzdHlsZSIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGVBdHRyaWJ1dGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZWdFeHAxID0gL3BhZ2UtYnJlYWstaW5zaWRlXHMqOlxzKmF2b2lkOy9nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ0V4cDIgPSAvcGFnZS1icmVhay1pbnNpZGVccyo6XHMqYXZvaWQvZzsgLy9DaGVjayBmb3IgYm90aCB3aXRoL3dpdGhvdXQgc2VtaS1jb2xvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlZ0V4cDEuZXhlYyhzdHlsZUF0dHJpYnV0ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZUF0dHJpYnV0ZSA9IHN0eWxlQXR0cmlidXRlLnJlcGxhY2UocmVnRXhwMSwgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZWdFeHAyLmV4ZWMoc3R5bGVBdHRyaWJ1dGUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGVBdHRyaWJ1dGUgPSBzdHlsZUF0dHJpYnV0ZS5yZXBsYWNlKHJlZ0V4cDIsICIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzdHlsZUF0dHJpYnV0ZS5lbmRzV2l0aCgiOyIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlQXR0cmlidXRlICs9ICI7IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGVBdHRyaWJ1dGUgKz0gInBhZ2UtYnJlYWstaW5zaWRlOiBhdm9pZDsiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGVBdHRyaWJ1dGUgPSAicGFnZS1icmVhay1pbnNpZGU6IGF2b2lkOyI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LnNldEF0dHJpYnV0ZSgic3R5bGUiLCBzdHlsZUF0dHJpYnV0ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc3RhdGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQpIHsKICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZXMgPSB7InBhZ2UtYnJlYWstaW5zaWRlIiA6ICJhdm9pZCIsCiAgICAgICAgICAgICAgICAiYnJlYWstaW5zaWRlIiA6ICJhdm9pZCJ9OwogICAgICAgICAgICByZXR1cm4gIXd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRCbG9jay5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgWyJQIiwgIkxJIiwgIkgxIiwgIkgyIiwgIkgzIiwgIkg0IiwgIkg1IiwgIkg2Il0sIG51bGwsIG51bGwsIGF0dHJpYnV0ZXMpOwogICAgICAgIH0KICAgIH07Cn0pKHd5c2lodG1sNSk7Cnd5c2lodG1sNS5jb21tYW5kcy5oaWxpdGVDb2xvciA9IHsKICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmQsIGNvbG9yKSB7CiAgICAgICAgLyogQWZ0ZXIgc3RhdGUgaW1wbGVtZW50YXRpb24gY2hhbmdlcywgdXNlIGZvbGxvd2luZyBicm93c2VyIGNvbW1hbmQuCiAgICAgICAgIGlmIChjb21wb3Nlci5jb21tYW5kcy5zdXBwb3J0KGNvbW1hbmQpKSB7CiAgICAgICAgIGNvbXBvc2VyLmRvYy5leGVjQ29tbWFuZChjb21tYW5kLCBmYWxzZSwgY29sb3IpOwogICAgICAgICB9Ki8KICAgICAgICB2YXIgYXR0cmlidXRlcyA9IHsiYmFja2dyb3VuZC1jb2xvciIgOiBjb2xvcn07CiAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuZXhlYyhjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAid3lzaXd5Zy1iZ2NvbG9yLSIgKyBjb2xvciwgL3d5c2l3eWctYmdjb2xvci1bMC05YS16XSsvZywgYXR0cmlidXRlcyk7CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kLCBjb2xvcikgewogICAgICAgIHZhciBhdHRyaWJ1dGVzID0geyJiYWNrZ3JvdW5kLWNvbG9yIiA6IGNvbG9yfTsKICAgICAgICByZXR1cm4gd3lzaWh0bWw1LmNvbW1hbmRzLmZvcm1hdElubGluZS5zdGF0ZShjb21wb3NlciwgY29tbWFuZCwgInNwYW4iLCAid3lzaXd5Zy1iZ2NvbG9yLSIgKyBjb2xvciwgL3d5c2l3eWctYmdjb2xvci1bMC05YS16XSsvZywgYXR0cmlidXRlcyk7CiAgICB9Cn07Cnd5c2lodG1sNS5jb21tYW5kcy5yZWRvID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlcikgewogICAgICAgIHJldHVybiBjb21wb3Nlci51bmRvTWFuYWdlci5yZWRvKCk7CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9Owp3eXNpaHRtbDUuY29tbWFuZHMudW5kZXJsaW5lID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZCkgewogICAgICAgIHJldHVybiB3eXNpaHRtbDUuY29tbWFuZHMuZm9ybWF0SW5saW5lLmV4ZWMoY29tcG9zZXIsIGNvbW1hbmQsICJ1Iik7CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kKSB7CiAgICAgICAgcmV0dXJuIHd5c2lodG1sNS5jb21tYW5kcy5mb3JtYXRJbmxpbmUuc3RhdGUoY29tcG9zZXIsIGNvbW1hbmQsICJ1Iik7CiAgICB9Cn07Cnd5c2lodG1sNS5jb21tYW5kcy51bmRvID0gewogICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlcikgewogICAgICAgIHJldHVybiBjb21wb3Nlci51bmRvTWFuYWdlci51bmRvKCk7CiAgICB9LAoKICAgIHN0YXRlIDogZnVuY3Rpb24gKGNvbXBvc2VyKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQp9OwovKioKICogVW5kbyBNYW5hZ2VyIGZvciB3eXNpaHRtbDUKICogc2xpZ2h0bHkgaW5zcGlyZWQgYnkgaHR0cDovL3JuaXdhLmNvbS9lZGl0aW5nL3VuZG9tYW5hZ2VyLmh0bWwjdGhlLXVuZG9tYW5hZ2VyLWludGVyZmFjZQogKi8KKGZ1bmN0aW9uICh3eXNpaHRtbDUpIHsKICAgIHZhciBaX0tFWSA9IDkwLAogICAgICAgIFlfS0VZID0gODksCiAgICAgICAgQkFDS1NQQUNFX0tFWSA9IDgsCiAgICAgICAgREVMRVRFX0tFWSA9IDQ2LAogICAgICAgIE1BWF9ISVNUT1JZX0VOVFJJRVMgPSAyNSwKICAgICAgICBEQVRBX0FUVFJfTk9ERSA9ICJkYXRhLXd5c2lodG1sNS1zZWxlY3Rpb24tbm9kZSIsCiAgICAgICAgREFUQV9BVFRSX09GRlNFVCA9ICJkYXRhLXd5c2lodG1sNS1zZWxlY3Rpb24tb2Zmc2V0IiwKICAgICAgICBVTkRPX0hUTUwgPSAnPHNwYW4gaWQ9Il93eXNpaHRtbDUtdW5kbyIgY2xhc3M9Il93eXNpaHRtbDUtdGVtcCI+JyArIHd5c2lodG1sNS5JTlZJU0lCTEVfU1BBQ0UgKyAnPC9zcGFuPicsCiAgICAgICAgUkVET19IVE1MID0gJzxzcGFuIGlkPSJfd3lzaWh0bWw1LXJlZG8iIGNsYXNzPSJfd3lzaWh0bWw1LXRlbXAiPicgKyB3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFICsgJzwvc3Bhbj4nLAogICAgICAgIGRvbSA9IHd5c2lodG1sNS5kb207CgogICAgZnVuY3Rpb24gY2xlYW5UZW1wRWxlbWVudHMoZG9jKSB7CiAgICAgICAgdmFyIHRlbXBFbGVtZW50OwogICAgICAgIHdoaWxlICh0ZW1wRWxlbWVudCA9IGRvYy5xdWVyeVNlbGVjdG9yKCIuX3d5c2lodG1sNS10ZW1wIikpIHsKICAgICAgICAgICAgdGVtcEVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0ZW1wRWxlbWVudCk7CiAgICAgICAgfQogICAgfQoKICAgIHd5c2lodG1sNS5VbmRvTWFuYWdlciA9IHd5c2lodG1sNS5sYW5nLkRpc3BhdGNoZXIuZXh0ZW5kKAogICAgICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LlVuZG9NYW5hZ2VyLnByb3RvdHlwZSAqLyB7CiAgICAgICAgICAgIGNvbnN0cnVjdG9yIDogZnVuY3Rpb24gKGVkaXRvcikgewogICAgICAgICAgICAgICAgdGhpcy5lZGl0b3IgPSBlZGl0b3I7CiAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyID0gZWRpdG9yLmNvbXBvc2VyOwogICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy5jb21wb3Nlci5lbGVtZW50OwoKICAgICAgICAgICAgICAgIHRoaXMucG9zaXRpb24gPSAwOwogICAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5U3RyID0gW107CiAgICAgICAgICAgICAgICB0aGlzLmhpc3RvcnlEb20gPSBbXTsKCiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zYWN0KCk7CgogICAgICAgICAgICAgICAgdGhpcy5fb2JzZXJ2ZSgpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBjbGVhckhpc3RvcnkgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLnBvc2l0aW9uID0gMDsKICAgICAgICAgICAgICAgIHRoaXMuaGlzdG9yeVN0ciA9IFtdOwogICAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5RG9tID0gW107CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfb2JzZXJ2ZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcywKICAgICAgICAgICAgICAgICAgICBkb2MgPSB0aGlzLmNvbXBvc2VyLnNhbmRib3guZ2V0RG9jdW1lbnQoKSwKICAgICAgICAgICAgICAgICAgICBsYXN0S2V5OwoKICAgICAgICAgICAgICAgIC8vIENhdGNoIENUUkwrWiBhbmQgQ1RSTCtZCiAgICAgICAgICAgICAgICBkb20ub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsICJrZXlkb3duIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50LmFsdEtleSB8fCAoIWV2ZW50LmN0cmxLZXkgJiYgIWV2ZW50Lm1ldGFLZXkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHZhciBrZXlDb2RlID0gZXZlbnQua2V5Q29kZSwKICAgICAgICAgICAgICAgICAgICAgICAgaXNVbmRvID0ga2V5Q29kZSA9PT0gWl9LRVkgJiYgIWV2ZW50LnNoaWZ0S2V5LAogICAgICAgICAgICAgICAgICAgICAgICBpc1JlZG8gPSAoa2V5Q29kZSA9PT0gWl9LRVkgJiYgZXZlbnQuc2hpZnRLZXkpIHx8IChrZXlDb2RlID09PSBZX0tFWSk7CgogICAgICAgICAgICAgICAgICAgIGlmIChpc1VuZG8pIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC51bmRvKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc1JlZG8pIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5yZWRvKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgLy8gQ2F0Y2ggZGVsZXRlIGFuZCBiYWNrc3BhY2UKICAgICAgICAgICAgICAgIGRvbS5vYnNlcnZlKHRoaXMuZWxlbWVudCwgImtleWRvd24iLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIga2V5Q29kZSA9IGV2ZW50LmtleUNvZGU7CiAgICAgICAgICAgICAgICAgICAgaWYgKGtleUNvZGUgPT09IGxhc3RLZXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgbGFzdEtleSA9IGtleUNvZGU7CgogICAgICAgICAgICAgICAgICAgIGlmIChrZXlDb2RlID09PSBCQUNLU1BBQ0VfS0VZIHx8IGtleUNvZGUgPT09IERFTEVURV9LRVkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC50cmFuc2FjdCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIC8vIE5vdyB0aGlzIGlzIHZlcnkgaGFja3k6CiAgICAgICAgICAgICAgICAvLyBUaGVzZSBkYXlzIGJyb3dzZXJzIGRvbid0IG9mZmVyIGEgdW5kby9yZWRvIGV2ZW50IHdoaWNoIHdlIGNvdWxkIGhvb2sgaW50bwogICAgICAgICAgICAgICAgLy8gdG8gYmUgbm90aWZpZWQgd2hlbiB0aGUgdXNlciBoaXRzIHVuZG8vcmVkbyBpbiB0aGUgY29udGV4dG1lbnUuCiAgICAgICAgICAgICAgICAvLyBUaGVyZWZvcmUgd2Ugc2ltcGx5IGluc2VydCB0d28gZWxlbWVudHMgYXMgc29vbiBhcyB0aGUgY29udGV4dG1lbnUgZ2V0cyBvcGVuZWQuCiAgICAgICAgICAgICAgICAvLyBUaGUgbGFzdCBlbGVtZW50IGJlaW5nIGluc2VydGVkIHdpbGwgYmUgaW1tZWRpYXRlbHkgYmUgcmVtb3ZlZCBhZ2FpbiBieSBhIGV4ZXhDb21tYW5kKCJ1bmRvIikKICAgICAgICAgICAgICAgIC8vICA9PiBXaGVuIHRoZSBzZWNvbmQgZWxlbWVudCBhcHBlYXJzIGluIHRoZSBkb20gdHJlZSB0aGVuIHdlIGtub3cgdGhlIHVzZXIgY2xpY2tlZCAicmVkbyIgaW4gdGhlIGNvbnRleHQgbWVudQogICAgICAgICAgICAgICAgLy8gID0+IFdoZW4gdGhlIGZpcnN0IGVsZW1lbnQgZGlzYXBwZWFycyBmcm9tIHRoZSBkb20gdHJlZSB0aGVuIHdlIGtub3cgdGhlIHVzZXIgY2xpY2tlZCAidW5kbyIgaW4gdGhlIGNvbnRleHQgbWVudQogICAgICAgICAgICAgICAgaWYgKHd5c2lodG1sNS5icm93c2VyLmhhc1VuZG9JbkNvbnRleHRNZW51KCkpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaW50ZXJ2YWwsIG9ic2VydmVkLCBjbGVhblVwID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICBjbGVhblRlbXBFbGVtZW50cyhkb2MpOwogICAgICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKGludGVydmFsKTsKICAgICAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgICAgICBkb20ub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsICJjb250ZXh0bWVudSIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2xlYW5VcCgpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmNvbXBvc2VyLnNlbGVjdGlvbi5leGVjdXRlQW5kUmVzdG9yZVNpbXBsZShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5lbGVtZW50Lmxhc3RDaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuY29tcG9zZXIuc2VsZWN0aW9uLnNldEFmdGVyKHRoYXQuZWxlbWVudC5sYXN0Q2hpbGQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVuYWJsZSB1bmRvIGJ1dHRvbiBpbiBjb250ZXh0IG1lbnUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvYy5leGVjQ29tbWFuZCgiaW5zZXJ0SFRNTCIsIGZhbHNlLCBVTkRPX0hUTUwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZW5hYmxlIHJlZG8gYnV0dG9uIGluIGNvbnRleHQgbWVudQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jLmV4ZWNDb21tYW5kKCJpbnNlcnRIVE1MIiwgZmFsc2UsIFJFRE9fSFRNTCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2MuZXhlY0NvbW1hbmQoInVuZG8iLCBmYWxzZSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9jLmdldEVsZW1lbnRCeUlkKCJfd3lzaWh0bWw1LXJlZG8iKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFuVXAoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnJlZG8oKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWRvYy5nZXRFbGVtZW50QnlJZCgiX3d5c2lodG1sNS11bmRvIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhblVwKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC51bmRvKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0sIDQwMCk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9ic2VydmVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb20ub2JzZXJ2ZShkb2N1bWVudCwgIm1vdXNlZG93biIsIGNsZWFuVXApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tLm9ic2VydmUoZG9jLCBbIm1vdXNlZG93biIsICJwYXN0ZSIsICJjdXQiLCAiY29weSJdLCBjbGVhblVwKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yCiAgICAgICAgICAgICAgICAgICAgLm9uKCJuZXd3b3JkOmNvbXBvc2VyIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnRyYW5zYWN0KCk7CiAgICAgICAgICAgICAgICAgICAgfSkKCiAgICAgICAgICAgICAgICAgICAgLm9uKCJiZWZvcmVjb21tYW5kOmNvbXBvc2VyIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnRyYW5zYWN0KCk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICB0cmFuc2FjdCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBwcmV2aW91c0h0bWwgPSB0aGlzLmhpc3RvcnlTdHJbdGhpcy5wb3NpdGlvbiAtIDFdLAogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRIdG1sID0gdGhpcy5jb21wb3Nlci5nZXRWYWx1ZSgpOwoKICAgICAgICAgICAgICAgIGlmIChjdXJyZW50SHRtbCA9PT0gcHJldmlvdXNIdG1sKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBsZW5ndGggPSB0aGlzLmhpc3RvcnlTdHIubGVuZ3RoID0gdGhpcy5oaXN0b3J5RG9tLmxlbmd0aCA9IHRoaXMucG9zaXRpb247CiAgICAgICAgICAgICAgICBpZiAobGVuZ3RoID4gTUFYX0hJU1RPUllfRU5UUklFUykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaGlzdG9yeVN0ci5zaGlmdCgpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuaGlzdG9yeURvbS5zaGlmdCgpOwogICAgICAgICAgICAgICAgICAgIHRoaXMucG9zaXRpb24tLTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLnBvc2l0aW9uKys7CgogICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gdGhpcy5jb21wb3Nlci5zZWxlY3Rpb24uZ2V0UmFuZ2UoKSwKICAgICAgICAgICAgICAgICAgICBub2RlID0gcmFuZ2Uuc3RhcnRDb250YWluZXIgfHwgdGhpcy5lbGVtZW50LAogICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IHJhbmdlLnN0YXJ0T2Zmc2V0IHx8IDAsCiAgICAgICAgICAgICAgICAgICAgZWxlbWVudCwKICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjsKCiAgICAgICAgICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gd3lzaWh0bWw1LkVMRU1FTlRfTk9ERSkgewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBub2RlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gbm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gdGhpcy5nZXRDaGlsZE5vZGVJbmRleChlbGVtZW50LCBub2RlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShEQVRBX0FUVFJfT0ZGU0VULCBvZmZzZXQpOwogICAgICAgICAgICAgICAgaWYgKHR5cGVvZihwb3NpdGlvbikgIT09ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoREFUQV9BVFRSX05PREUsIHBvc2l0aW9uKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgY2xvbmUgPSB0aGlzLmVsZW1lbnQuY2xvbmVOb2RlKCEhY3VycmVudEh0bWwpOwogICAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5RG9tLnB1c2goY2xvbmUpOwogICAgICAgICAgICAgICAgdGhpcy5oaXN0b3J5U3RyLnB1c2goY3VycmVudEh0bWwpOwoKICAgICAgICAgICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKERBVEFfQVRUUl9PRkZTRVQpOwogICAgICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoREFUQV9BVFRSX05PREUpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgdW5kbyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHRoaXMudHJhbnNhY3QoKTsKCiAgICAgICAgICAgICAgICBpZiAoIXRoaXMudW5kb1Bvc3NpYmxlKCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5zZXQodGhpcy5oaXN0b3J5RG9tWy0tdGhpcy5wb3NpdGlvbiAtIDFdKTsKICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yLmZpcmUoInVuZG86Y29tcG9zZXIiKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHJlZG8gOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBpZiAoIXRoaXMucmVkb1Bvc3NpYmxlKCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5zZXQodGhpcy5oaXN0b3J5RG9tWysrdGhpcy5wb3NpdGlvbiAtIDFdKTsKICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yLmZpcmUoInJlZG86Y29tcG9zZXIiKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHVuZG9Qb3NzaWJsZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uID4gMTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHJlZG9Qb3NzaWJsZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uIDwgdGhpcy5oaXN0b3J5U3RyLmxlbmd0aDsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uIChoaXN0b3J5RW50cnkpIHsKICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5pbm5lckhUTUwgPSAiIjsKCiAgICAgICAgICAgICAgICB2YXIgaSA9IDAsCiAgICAgICAgICAgICAgICAgICAgY2hpbGROb2RlcyA9IGhpc3RvcnlFbnRyeS5jaGlsZE5vZGVzLAogICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IGhpc3RvcnlFbnRyeS5jaGlsZE5vZGVzLmxlbmd0aDsKCiAgICAgICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZChjaGlsZE5vZGVzW2ldLmNsb25lTm9kZSh0cnVlKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gUmVzdG9yZSBzZWxlY3Rpb24KICAgICAgICAgICAgICAgIHZhciBvZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgbm9kZSwKICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbjsKCiAgICAgICAgICAgICAgICBpZiAoaGlzdG9yeUVudHJ5Lmhhc0F0dHJpYnV0ZShEQVRBX0FUVFJfT0ZGU0VUKSkgewogICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IGhpc3RvcnlFbnRyeS5nZXRBdHRyaWJ1dGUoREFUQV9BVFRSX09GRlNFVCk7CiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBoaXN0b3J5RW50cnkuZ2V0QXR0cmlidXRlKERBVEFfQVRUUl9OT0RFKTsKICAgICAgICAgICAgICAgICAgICBub2RlID0gdGhpcy5lbGVtZW50OwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBub2RlID0gdGhpcy5lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoIlsiICsgREFUQV9BVFRSX09GRlNFVCArICJdIikgfHwgdGhpcy5lbGVtZW50OwogICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IG5vZGUuZ2V0QXR0cmlidXRlKERBVEFfQVRUUl9PRkZTRVQpOwogICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gbm9kZS5nZXRBdHRyaWJ1dGUoREFUQV9BVFRSX05PREUpOwogICAgICAgICAgICAgICAgICAgIG5vZGUucmVtb3ZlQXR0cmlidXRlKERBVEFfQVRUUl9PRkZTRVQpOwogICAgICAgICAgICAgICAgICAgIG5vZGUucmVtb3ZlQXR0cmlidXRlKERBVEFfQVRUUl9OT0RFKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gIT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBub2RlID0gdGhpcy5nZXRDaGlsZE5vZGVCeUluZGV4KG5vZGUsICtwb3NpdGlvbik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5jb21wb3Nlci5zZWxlY3Rpb24uc2V0KG5vZGUsIG9mZnNldCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRDaGlsZE5vZGVJbmRleCA6IGZ1bmN0aW9uIChwYXJlbnQsIGNoaWxkKSB7CiAgICAgICAgICAgICAgICB2YXIgaSA9IDAsCiAgICAgICAgICAgICAgICAgICAgY2hpbGROb2RlcyA9IHBhcmVudC5jaGlsZE5vZGVzLAogICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IGNoaWxkTm9kZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGROb2Rlc1tpXSA9PT0gY2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZ2V0Q2hpbGROb2RlQnlJbmRleCA6IGZ1bmN0aW9uIChwYXJlbnQsIGluZGV4KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyZW50LmNoaWxkTm9kZXNbaW5kZXhdOwogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBUT0RPOiB0aGUgZm9sbG93aW5nIG1ldGhvZHMgc3RpbGwgbmVlZCB1bml0IHRlc3QgY292ZXJhZ2UKICovCnd5c2lodG1sNS52aWV3cy5WaWV3ID0gQmFzZS5leHRlbmQoCiAgICAvKiogQHNjb3BlIHd5c2lodG1sNS52aWV3cy5WaWV3LnByb3RvdHlwZSAqLyB7CiAgICAgICAgY29uc3RydWN0b3IgOiBmdW5jdGlvbiAocGFyZW50LCB0ZXh0YXJlYUVsZW1lbnQsIGNvbmZpZykgewogICAgICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDsKICAgICAgICAgICAgdGhpcy5lbGVtZW50ID0gdGV4dGFyZWFFbGVtZW50OwogICAgICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZzsKCiAgICAgICAgICAgIHRoaXMuX29ic2VydmVWaWV3Q2hhbmdlKCk7CiAgICAgICAgfSwKCiAgICAgICAgX29ic2VydmVWaWV3Q2hhbmdlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgIHRoaXMucGFyZW50Lm9uKCJiZWZvcmVsb2FkIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhhdC5wYXJlbnQub24oImNoYW5nZV92aWV3IiwgZnVuY3Rpb24gKHZpZXcpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodmlldyA9PT0gdGhhdC5uYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQucGFyZW50LmN1cnJlbnRWaWV3ID0gdGhhdDsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5zaG93KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVzaW5nIHRpbnkgZGVsYXkgaGVyZSB0byBtYWtlIHN1cmUgdGhhdCB0aGUgcGxhY2Vob2xkZXIgaXMgc2V0IGJlZm9yZSBmb2N1c2luZwogICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZm9jdXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5oaWRlKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIGZvY3VzIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBpZiAodGhpcy5lbGVtZW50Lm93bmVyRG9jdW1lbnQucXVlcnlTZWxlY3RvcigiOmZvY3VzIikgPT09IHRoaXMuZWxlbWVudCkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50LmZvY3VzKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGhpZGUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgIH0sCgogICAgICAgIHNob3cgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gIiI7CiAgICAgICAgfSwKCiAgICAgICAgZGlzYWJsZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgiZGlzYWJsZWQiLCAiZGlzYWJsZWQiKTsKICAgICAgICB9LAoKICAgICAgICBlbmFibGUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoImRpc2FibGVkIik7CiAgICAgICAgfQogICAgfSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgZG9tID0gd3lzaWh0bWw1LmRvbSwKICAgICAgICBicm93c2VyID0gd3lzaWh0bWw1LmJyb3dzZXI7CgogICAgd3lzaWh0bWw1LnZpZXdzLkNvbXBvc2VyID0gd3lzaWh0bWw1LnZpZXdzLlZpZXcuZXh0ZW5kKAogICAgICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LnZpZXdzLkNvbXBvc2VyLnByb3RvdHlwZSAqLyB7CiAgICAgICAgICAgIG5hbWUgOiAiY29tcG9zZXIiLAoKICAgICAgICAgICAgLy8gTmVlZGVkIGZvciBmaXJlZm94IGluIG9yZGVyIHRvIGRpc3BsYXkgYSBwcm9wZXIgY2FyZXQgaW4gYW4gZW1wdHkgY29udGVudEVkaXRhYmxlCiAgICAgICAgICAgIENBUkVUX0hBQ0sgOiAiPGJyPiIsCgogICAgICAgICAgICBjb25zdHJ1Y3RvciA6IGZ1bmN0aW9uIChwYXJlbnQsIHRleHRhcmVhRWxlbWVudCwgY29uZmlnKSB7CiAgICAgICAgICAgICAgICB0aGlzLmJhc2UocGFyZW50LCB0ZXh0YXJlYUVsZW1lbnQsIGNvbmZpZyk7CiAgICAgICAgICAgICAgICB0aGlzLnRleHRhcmVhID0gdGhpcy5wYXJlbnQudGV4dGFyZWE7CiAgICAgICAgICAgICAgICB0aGlzLl9pbml0U2FuZGJveChjb25maWcuaW5zZXJ0QWZ0ZXIpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgY2xlYXIgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQuaW5uZXJIVE1MID0gYnJvd3Nlci5kaXNwbGF5c0NhcmV0SW5FbXB0eUNvbnRlbnRFZGl0YWJsZUNvcnJlY3RseSgpID8gIiIgOiB0aGlzLkNBUkVUX0hBQ0s7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRWYWx1ZSA6IGZ1bmN0aW9uIChwYXJzZSkgewogICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5pc0VtcHR5KCkgPyAiIiA6IHd5c2lodG1sNS5xdWlya3MuZ2V0Q29ycmVjdElubmVySFRNTCh0aGlzLmVsZW1lbnQpOwoKICAgICAgICAgICAgICAgIGlmIChwYXJzZSkgewogICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5wYXJlbnQucGFyc2UodmFsdWUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFJlcGxhY2UgYWxsICJ6ZXJvIHdpZHRoIG5vIGJyZWFraW5nIHNwYWNlIiBjaGFycwogICAgICAgICAgICAgICAgLy8gd2hpY2ggYXJlIHVzZWQgYXMgaGFja3MgdG8gZW5hYmxlIHNvbWUgZnVuY3Rpb25hbGl0aWVzCiAgICAgICAgICAgICAgICAvLyBBbHNvIHJlbW92ZSBhbGwgQ0FSRVQgaGFja3MgdGhhdCBzb21laG93IGdvdCBsZWZ0CiAgICAgICAgICAgICAgICB2YWx1ZSA9IHd5c2lodG1sNS5sYW5nLnN0cmluZyh2YWx1ZSkucmVwbGFjZSh3eXNpaHRtbDUuSU5WSVNJQkxFX1NQQUNFKS5ieSgiIik7CgogICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2V0VmFsdWUgOiBmdW5jdGlvbiAoaHRtbCwgcGFyc2UpIHsKICAgICAgICAgICAgICAgIGlmIChwYXJzZSkgewogICAgICAgICAgICAgICAgICAgIGh0bWwgPSB0aGlzLnBhcmVudC5wYXJzZShodG1sKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5pbm5lckhUTUwgPSBodG1sOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5pbm5lclRleHQgPSBodG1sOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2hvdyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSB0aGlzLl9kaXNwbGF5U3R5bGUgfHwgIiI7CgogICAgICAgICAgICAgICAgaWYgKCF0aGlzLnRleHRhcmVhLmVsZW1lbnQuZGlzYWJsZWQpIHsKICAgICAgICAgICAgICAgICAgICAvLyBGaXJlZm94IG5lZWRzIHRoaXMsIG90aGVyd2lzZSBjb250ZW50RWRpdGFibGUgYmVjb21lcyB1bmVkaXRhYmxlCiAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbmFibGUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGhpZGUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9kaXNwbGF5U3R5bGUgPSBkb20uZ2V0U3R5bGUoImRpc3BsYXkiKS5mcm9tKHRoaXMuY29udGFpbmVyKTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9kaXNwbGF5U3R5bGUgPT09ICJub25lIikgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Rpc3BsYXlTdHlsZSA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZGlzYWJsZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHRoaXMucGFyZW50LmZpcmUoImRpc2FibGU6Y29tcG9zZXIiKTsKICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoImNvbnRlbnRFZGl0YWJsZSIpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZW5hYmxlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhpcy5wYXJlbnQuZmlyZSgiZW5hYmxlOmNvbXBvc2VyIik7CiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCJjb250ZW50RWRpdGFibGUiLCAidHJ1ZSIpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZm9jdXMgOiBmdW5jdGlvbiAoc2V0VG9FbmQpIHsKICAgICAgICAgICAgICAgIC8vIElFIDggZmlyZXMgdGhlIGZvY3VzIGV2ZW50IGFmdGVyIC5mb2N1cygpCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIG5lZWRlZCBieSBvdXIgc2ltdWxhdGVfcGxhY2Vob2xkZXIuanMgdG8gd29yawogICAgICAgICAgICAgICAgLy8gdGhlcmVmb3JlIHdlIGNsZWFyIGl0IG91cnNlbHZlcyB0aGlzIHRpbWUKICAgICAgICAgICAgICAgIGlmICh3eXNpaHRtbDUuYnJvd3Nlci5kb2VzQXN5bmNGb2N1cygpICYmIHRoaXMuaGFzUGxhY2Vob2xkZXJTZXQoKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYXIoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLmJhc2UoKTsKCiAgICAgICAgICAgICAgICB2YXIgbGFzdENoaWxkID0gdGhpcy5lbGVtZW50Lmxhc3RDaGlsZDsKICAgICAgICAgICAgICAgIGlmIChzZXRUb0VuZCAmJiBsYXN0Q2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobGFzdENoaWxkLm5vZGVOYW1lID09PSAiQlIiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uLnNldEJlZm9yZSh0aGlzLmVsZW1lbnQubGFzdENoaWxkKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGlvbi5zZXRBZnRlcih0aGlzLmVsZW1lbnQubGFzdENoaWxkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRUZXh0Q29udGVudCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBkb20uZ2V0VGV4dENvbnRlbnQodGhpcy5lbGVtZW50KTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGFwcGx5U3R5bGUgOiBmdW5jdGlvbiAoY29tcG9zZXIsIHN0eWxlUHJvcGVydGllcywgYXR0cmlidXRlcykgewogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkTm9kZXMgPSBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0Tm9kZXMoMSk7CiAgICAgICAgICAgICAgICB2YXIgYXBwbHlTdHlsZVRvTm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50Tm9kZSA9IGRvbS5nZXRQYXJlbnRFbGVtZW50KG5vZGUsIHtub2RlTmFtZSA6IFsiTEkiXX0pOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50Tm9kZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBQcmV2ZW50IGFwcGx5aW5nIHN0eWxlIHRvIGlubmVyIGxpc3RzKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsaXN0Tm9kZSA9IGRvbS5nZXRQYXJlbnRFbGVtZW50KG5vZGUsIHtub2RlTmFtZSA6IFsiT0wiLCAiVUwiXX0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3ROb2RlICE9IG51bGwgJiYgc2VsZWN0ZWROb2Rlcy5pbmRleE9mKGxpc3ROb2RlKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50TGlzdEl0ZW0gPSBkb20uZ2V0UGFyZW50RWxlbWVudChsaXN0Tm9kZSwge25vZGVOYW1lIDogWyJMSSJdfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudExpc3RJdGVtICE9IG51bGwgJiYgc2VsZWN0ZWROb2Rlcy5pbmRleE9mKHBhcmVudExpc3RJdGVtKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBwYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIHByb3BlcnR5IGluIHN0eWxlUHJvcGVydGllcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5zdHlsZS5zZXRQcm9wZXJ0eShwcm9wZXJ0eSwgc3R5bGVQcm9wZXJ0aWVzW3Byb3BlcnR5XSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgYXR0cmlidXRlIGluIGF0dHJpYnV0ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKGF0dHJpYnV0ZSwgYXR0cmlidXRlc1thdHRyaWJ1dGVdKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB2YXIgbm9kZUxpc3QgPSBjb21wb3Nlci5zZWxlY3Rpb24uZ2V0Tm9kZXMoMyk7CiAgICAgICAgICAgICAgICBpZiAobm9kZUxpc3QubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICBpIDwgbm9kZUxpc3QubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlID0gbm9kZUxpc3RbaV07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSAhPSBudWxsICYmIChub2RlLm5vZGVOYW1lID09ICJQIiB8fCBub2RlLm5vZGVOYW1lID09ICJMSSIgfHwgbm9kZS5ub2RlTmFtZS5tYXRjaCgvXkhbMS02XSQvKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBseVN0eWxlVG9Ob2RlKG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChub2RlICE9IG51bGwgJiYgIXd5c2lodG1sNS51dGlsLmlzRWRpdG9yTm9kZShub2RlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChub2RlICE9IG51bGwgJiYgbm9kZS5ub2RlTmFtZSAhPSAiUCIgJiYgbm9kZS5ub2RlTmFtZSAhPSAiTEkiICYmIG5vZGUubm9kZU5hbWUubWF0Y2goL15IWzEtNl0kLykgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5wYXJlbnRFbGVtZW50OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBseVN0eWxlVG9Ob2RlKG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWROb2RlID0gY29tcG9zZXIuc2VsZWN0aW9uLmdldFNlbGVjdGVkTm9kZSgpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChzZWxlY3RlZE5vZGUgIT0gbnVsbCAmJiBzZWxlY3RlZE5vZGUubm9kZU5hbWUgIT0gIlAiICYmIHNlbGVjdGVkTm9kZS5ub2RlTmFtZSAhPSBzZWxlY3RlZE5vZGUubm9kZU5hbWUubWF0Y2goL15IWzEtNl0kLykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWROb2RlID0gc2VsZWN0ZWROb2RlLnBhcmVudEVsZW1lbnQgPyBzZWxlY3RlZE5vZGUucGFyZW50RWxlbWVudCA6IHNlbGVjdGVkTm9kZS5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBhcHBseVN0eWxlVG9Ob2RlKHNlbGVjdGVkTm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGhhc1BsYWNlaG9sZGVyU2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VGV4dENvbnRlbnQoKSA9PSB0aGlzLnRleHRhcmVhLmVsZW1lbnQuZ2V0QXR0cmlidXRlKCJwbGFjZWhvbGRlciIpICYmIHRoaXMucGxhY2Vob2xkZXJTZXQ7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBpc0VtcHR5IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIGlubmVySFRNTCA9IHRoaXMuZWxlbWVudC5pbm5lckhUTUwudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgICAgIHJldHVybiBpbm5lckhUTUwgPT09ICIiIHx8CiAgICAgICAgICAgICAgICAgICAgaW5uZXJIVE1MID09PSAiPGJyPiIgfHwKICAgICAgICAgICAgICAgICAgICBpbm5lckhUTUwgPT09ICI8cD48L3A+IiB8fAogICAgICAgICAgICAgICAgICAgIGlubmVySFRNTCA9PT0gIjxwPjxicj48L3A+IiB8fAogICAgICAgICAgICAgICAgICAgIHRoaXMuaGFzUGxhY2Vob2xkZXJTZXQoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9pbml0U2FuZGJveCA6IGZ1bmN0aW9uIChpbnNlcnRBZnRlcikgewoKICAgICAgICAgICAgICAgIHRoaXMuc2FuZGJveCA9IG5ldyBkb20uU2FuZGJveCh7CiAgICAgICAgICAgICAgICAgICAgc3R5bGVzaGVldHMgOiB0aGlzLmNvbmZpZy5zdHlsZXNoZWV0cwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHRoaXMuc2FuZGJveC5nZXRDb250YWluZXIoKTsKCiAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFFbGVtZW50ID0gdGhpcy50ZXh0YXJlYS5lbGVtZW50OwogICAgICAgICAgICAgICAgaW5zZXJ0QWZ0ZXIgPSBpbnNlcnRBZnRlciB8fCB0ZXh0YXJlYUVsZW1lbnQ7CiAgICAgICAgICAgICAgICBkb20uaW5zZXJ0KHRoaXMuY29udGFpbmVyKS5hZnRlcihpbnNlcnRBZnRlcik7CgogICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGhpZGRlbiBmaWVsZCB3aGljaCB0ZWxscyB0aGUgc2VydmVyIGFmdGVyIHN1Ym1pdCwgdGhhdCB0aGUgdXNlciB1c2VkIGFuIHd5c2l3eWcgZWRpdG9yCiAgICAgICAgICAgICAgICBpZiAodGV4dGFyZWFFbGVtZW50LmZvcm0pIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaGlkZGVuRmllbGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJpbnB1dCIpOwogICAgICAgICAgICAgICAgICAgIGhpZGRlbkZpZWxkLnR5cGUgPSAiaGlkZGVuIjsKICAgICAgICAgICAgICAgICAgICBoaWRkZW5GaWVsZC5uYW1lID0gIl93eXNpaHRtbDVfbW9kZSI7CiAgICAgICAgICAgICAgICAgICAgaGlkZGVuRmllbGQudmFsdWUgPSAxOwogICAgICAgICAgICAgICAgICAgIGRvbS5pbnNlcnQoaGlkZGVuRmllbGQpLmFmdGVyKHRleHRhcmVhRWxlbWVudCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfY3JlYXRlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwoKICAgICAgICAgICAgICAgIHRoaXMuZG9jID0gdGhpcy5zYW5kYm94LmdldERvY3VtZW50KCk7CiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNvbnRhaW5lcjsKICAgICAgICAgICAgICAgIHRoaXMudGV4dGFyZWEgPSB0aGlzLnBhcmVudC50ZXh0YXJlYTsKICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLnRleHRhcmVhLmdldFZhbHVlKHRydWUpOwoKICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSBvdXIgc2VsZWN0aW9uIGhhbmRsZXIgaXMgcmVhZHkKICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uID0gbmV3IHd5c2lodG1sNS5TZWxlY3Rpb24odGhpcy5wYXJlbnQpOwoKICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSBjb21tYW5kcyBkaXNwYXRjaGVyIGlzIHJlYWR5CiAgICAgICAgICAgICAgICB0aGlzLmNvbW1hbmRzID0gbmV3IHd5c2lodG1sNS5Db21tYW5kcyh0aGlzLnBhcmVudCk7CgogICAgICAgICAgICAgICAgZG9tLmNvcHlBdHRyaWJ1dGVzKFsKICAgICAgICAgICAgICAgICAgICAiY2xhc3NOYW1lIiwgInNwZWxsY2hlY2siLCAidGl0bGUiLCAibGFuZyIsICJhY2Nlc3NLZXkiCiAgICAgICAgICAgICAgICBdKS5mcm9tKHRoaXMudGV4dGFyZWEuZWxlbWVudCkudG8odGhpcy5lbGVtZW50KTsKCiAgICAgICAgICAgICAgICBkb20uYWRkQ2xhc3ModGhpcy5lbGVtZW50LCB0aGlzLmNvbmZpZy5jb21wb3NlckNsYXNzTmFtZSk7CiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgLy8gLy8gTWFrZSB0aGUgZWRpdG9yIGxvb2sgbGlrZSB0aGUgb3JpZ2luYWwgdGV4dGFyZWEsIGJ5IHN5bmNpbmcgc3R5bGVzCiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25maWcuc3R5bGUpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnN0eWxlKCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5vYnNlcnZlKCk7CgogICAgICAgICAgICAgICAgdmFyIG5hbWUgPSB0aGlzLmNvbmZpZy5uYW1lOwogICAgICAgICAgICAgICAgaWYgKG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICBkb20uYWRkQ2xhc3ModGhpcy5lbGVtZW50LCBuYW1lKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLmVuYWJsZSgpOwoKICAgICAgICAgICAgICAgIGlmICh0aGlzLnRleHRhcmVhLmVsZW1lbnQuZGlzYWJsZWQpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGUoKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBTaW11bGF0ZSBodG1sNSBwbGFjZWhvbGRlciBhdHRyaWJ1dGUgb24gY29udGVudEVkaXRhYmxlIGVsZW1lbnQKICAgICAgICAgICAgICAgIHZhciBwbGFjZWhvbGRlclRleHQgPSB0eXBlb2YodGhpcy5jb25maWcucGxhY2Vob2xkZXIpID09PSAic3RyaW5nIiA/IHRoaXMuY29uZmlnLnBsYWNlaG9sZGVyIDogdGhpcy50ZXh0YXJlYS5lbGVtZW50LmdldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiKTsKICAgICAgICAgICAgICAgIGlmIChwbGFjZWhvbGRlclRleHQpIHsKICAgICAgICAgICAgICAgICAgICBkb20uc2ltdWxhdGVQbGFjZWhvbGRlcih0aGlzLnBhcmVudCwgdGhpcywgcGxhY2Vob2xkZXJUZXh0KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgYnJvd3NlciBhdm9pZHMgdXNpbmcgaW5saW5lIHN0eWxlcyB3aGVuZXZlciBwb3NzaWJsZQogICAgICAgICAgICAgICAgdGhpcy5jb21tYW5kcy5leGVjKCJzdHlsZVdpdGhDU1MiLCBmYWxzZSk7CgogICAgICAgICAgICAgICAgdGhpcy5faW5pdEF1dG9MaW5raW5nKCk7CiAgICAgICAgICAgICAgICB0aGlzLl9pbml0T2JqZWN0UmVzaXppbmcoKTsKICAgICAgICAgICAgICAgIHRoaXMuX2luaXRVbmRvTWFuYWdlcigpOwogICAgICAgICAgICAgICAgdGhpcy5faW5pdExpbmVCcmVha2luZygpOwoKICAgICAgICAgICAgICAgIC8vIFNpbXVsYXRlIGh0bWw1IGF1dG9mb2N1cyBvbiBjb250ZW50RWRpdGFibGUgZWxlbWVudAogICAgICAgICAgICAgICAgLy8gVGhpcyBkb2Vzbid0IHdvcmsgb24gSU9TICg1LjEuMSkKICAgICAgICAgICAgICAgIGlmICgodGhpcy50ZXh0YXJlYS5lbGVtZW50Lmhhc0F0dHJpYnV0ZSgiYXV0b2ZvY3VzIikgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiOmZvY3VzIikgPT0gdGhpcy50ZXh0YXJlYS5lbGVtZW50KSAmJiAhYnJvd3Nlci5pc0lvcygpKSB7CiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZm9jdXModHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBJRSBzb21ldGltZXMgbGVhdmVzIGEgc2luZ2xlIHBhcmFncmFwaCwgd2hpY2ggY2FuJ3QgYmUgcmVtb3ZlZCBieSB0aGUgdXNlcgogICAgICAgICAgICAgICAgaWYgKCFicm93c2VyLmNsZWFyc0NvbnRlbnRFZGl0YWJsZUNvcnJlY3RseSgpKSB7CiAgICAgICAgICAgICAgICAgICAgd3lzaWh0bWw1LnF1aXJrcy5lbnN1cmVQcm9wZXJDbGVhcmluZyh0aGlzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBTZXQgdXAgYSBzeW5jIHRoYXQgbWFrZXMgc3VyZSB0aGF0IHRleHRhcmVhIGFuZCBlZGl0b3IgaGF2ZSB0aGUgc2FtZSBjb250ZW50CiAgICAgICAgICAgICAgICBpZiAodGhpcy5pbml0U3luYyAmJiB0aGlzLmNvbmZpZy5zeW5jKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0U3luYygpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIE9rYXkgaGlkZSB0aGUgdGV4dGFyZWEsIHdlIGFyZSByZWFkeSB0byBnbwogICAgICAgICAgICAgICAgdGhpcy50ZXh0YXJlYS5oaWRlKCk7CgogICAgICAgICAgICAgICAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50OwogICAgICAgICAgICAgICAgLy8gRmlyZSBnbG9iYWwgKGJlZm9yZS0pbG9hZCBldmVudAogICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgcGFyZW50LmZpcmUoImJlZm9yZWxvYWQiKS5maXJlKCJsb2FkIik7CiAgICAgICAgICAgICAgICB9LCAwKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9pbml0QXV0b0xpbmtpbmcgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsCiAgICAgICAgICAgICAgICAgICAgc3VwcG9ydHNEaXNhYmxpbmdPZkF1dG9MaW5raW5nID0gYnJvd3Nlci5jYW5EaXNhYmxlQXV0b0xpbmtpbmcoKSwKICAgICAgICAgICAgICAgICAgICBzdXBwb3J0c0F1dG9MaW5raW5nID0gYnJvd3Nlci5kb2VzQXV0b0xpbmtpbmdJbkNvbnRlbnRFZGl0YWJsZSgpOwogICAgICAgICAgICAgICAgaWYgKHN1cHBvcnRzRGlzYWJsaW5nT2ZBdXRvTGlua2luZykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuY29tbWFuZHMuZXhlYygiYXV0b1VybERldGVjdCIsIGZhbHNlKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlnLmF1dG9MaW5rKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIE9ubHkgZG8gdGhlIGF1dG8gbGlua2luZyBieSBvdXJzZWx2ZXMgd2hlbiB0aGUgYnJvd3NlciBkb2Vzbid0IHN1cHBvcnQgYXV0byBsaW5raW5nCiAgICAgICAgICAgICAgICAvLyBPUiB3aGVuIGhlIHN1cHBvcnRzIGF1dG8gbGlua2luZyBidXQgd2Ugd2VyZSBhYmxlIHRvIHR1cm4gaXQgb2ZmIChJRTkrKQogICAgICAgICAgICAgICAgaWYgKCFzdXBwb3J0c0F1dG9MaW5raW5nIHx8IChzdXBwb3J0c0F1dG9MaW5raW5nICYmIHN1cHBvcnRzRGlzYWJsaW5nT2ZBdXRvTGlua2luZykpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnBhcmVudC5vbigibmV3d29yZDpjb21wb3NlciIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvbS5nZXRUZXh0Q29udGVudCh0aGF0LmVsZW1lbnQpLm1hdGNoKGRvbS5hdXRvTGluay5VUkxfUkVHX0VYUCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuc2VsZWN0aW9uLmV4ZWN1dGVBbmRSZXN0b3JlKGZ1bmN0aW9uIChzdGFydENvbnRhaW5lciwgZW5kQ29udGFpbmVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tLmF1dG9MaW5rKGVuZENvbnRhaW5lci5wYXJlbnROb2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgIGRvbS5vYnNlcnZlKHRoaXMuZWxlbWVudCwgImJsdXIiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5hdXRvTGluayh0aGF0LmVsZW1lbnQpOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIEFzc3VtaW5nIHdlIGhhdmUgdGhlIGZvbGxvd2luZzoKICAgICAgICAgICAgICAgIC8vICA8YSBocmVmPSJodHRwOi8vd3d3Lmdvb2dsZS5kZSI+aHR0cDovL3d3dy5nb29nbGUuZGU8L2E+CiAgICAgICAgICAgICAgICAvLyBJZiBhIHVzZXIgbm93IGNoYW5nZXMgdGhlIHVybCBpbiB0aGUgaW5uZXJIVE1MIHdlIHdhbnQgdG8gbWFrZSBzdXJlIHRoYXQKICAgICAgICAgICAgICAgIC8vIGl0J3Mgc3luY2hyb25pemVkIHdpdGggdGhlIGhyZWYgYXR0cmlidXRlIChhcyBsb25nIGFzIHRoZSBpbm5lckhUTUwgaXMgc3RpbGwgYSB1cmwpCiAgICAgICAgICAgICAgICB2YXIgLy8gVXNlIGEgbGl2ZSBOb2RlTGlzdCB0byBjaGVjayB3aGV0aGVyIHRoZXJlIGFyZSBhbnkgbGlua3MgaW4gdGhlIGRvY3VtZW50CiAgICAgICAgICAgICAgICAgICAgbGlua3MgPSB0aGlzLnNhbmRib3guZ2V0RG9jdW1lbnQoKS5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYSIpLAogICAgICAgICAgICAgICAgICAgIC8vIFRoZSBhdXRvTGluayBoZWxwZXIgbWV0aG9kIHJldmVhbHMgYSByZWcgZXhwIHRvIGRldGVjdCBjb3JyZWN0IHVybHMKICAgICAgICAgICAgICAgICAgICB1cmxSZWdFeHAgPSBkb20uYXV0b0xpbmsuVVJMX1JFR19FWFAsCiAgICAgICAgICAgICAgICAgICAgZ2V0VGV4dENvbnRlbnQgPSBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dENvbnRlbnQgPSB3eXNpaHRtbDUubGFuZy5zdHJpbmcoZG9tLmdldFRleHRDb250ZW50KGVsZW1lbnQpKS50cmltKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0Q29udGVudC5zdWJzdHIoMCwgNCkgPT09ICJ3d3cuIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dENvbnRlbnQgPSAiaHR0cDovLyIgKyB0ZXh0Q29udGVudDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGV4dENvbnRlbnQ7CiAgICAgICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICBkb20ub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsICJrZXlkb3duIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFsaW5rcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkTm9kZSA9IHRoYXQuc2VsZWN0aW9uLmdldFNlbGVjdGVkTm9kZShldmVudC50YXJnZXQub3duZXJEb2N1bWVudCksCiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmsgPSBkb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHtub2RlTmFtZSA6ICJBIn0sIDQpLAogICAgICAgICAgICAgICAgICAgICAgICB0ZXh0Q29udGVudDsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCFsaW5rKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRleHRDb250ZW50ID0gZ2V0VGV4dENvbnRlbnQobGluayk7CiAgICAgICAgICAgICAgICAgICAgLy8ga2V5ZG93biBpcyBmaXJlZCBiZWZvcmUgdGhlIGFjdHVhbCBjb250ZW50IGlzIGNoYW5nZWQKICAgICAgICAgICAgICAgICAgICAvLyB0aGVyZWZvcmUgd2Ugc2V0IGEgdGltZW91dCB0byBjaGFuZ2UgdGhlIGhyZWYKICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld1RleHRDb250ZW50ID0gZ2V0VGV4dENvbnRlbnQobGluayk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdUZXh0Q29udGVudCA9PT0gdGV4dENvbnRlbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBzZXQgaHJlZiB3aGVuIG5ldyBocmVmIGxvb2tzIGxpa2UgYSB2YWxpZCB1cmwKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld1RleHRDb250ZW50Lm1hdGNoKHVybFJlZ0V4cCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmsuc2V0QXR0cmlidXRlKCJocmVmIiwgbmV3VGV4dENvbnRlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9pbml0T2JqZWN0UmVzaXppbmcgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLmNvbW1hbmRzLmV4ZWMoImVuYWJsZU9iamVjdFJlc2l6aW5nIiwgdHJ1ZSk7CgogICAgICAgICAgICAgICAgLy8gSUUgc2V0cyBpbmxpbmUgc3R5bGVzIGFmdGVyIHJlc2l6aW5nIG9iamVjdHMKICAgICAgICAgICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgbGluZXMgbWFrZSBzdXJlIHRoYXQgdGhlIHdpZHRoL2hlaWdodCBjc3MgcHJvcGVydGllcwogICAgICAgICAgICAgICAgLy8gYXJlIGNvcGllZCBvdmVyIHRvIHRoZSB3aWR0aC9oZWlnaHQgYXR0cmlidXRlcwogICAgICAgICAgICAgICAgaWYgKGJyb3dzZXIuc3VwcG9ydHNFdmVudCgicmVzaXplZW5kIikpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcHJvcGVydGllcyA9IFsid2lkdGgiLCAiaGVpZ2h0Il0sCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnRpZXNMZW5ndGggPSBwcm9wZXJ0aWVzLmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IHRoaXMuZWxlbWVudDsKCiAgICAgICAgICAgICAgICAgICAgZG9tLm9ic2VydmUoZWxlbWVudCwgInJlc2l6ZWVuZCIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IHx8IGV2ZW50LnNyY0VsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZSA9IHRhcmdldC5zdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0Lm5vZGVOYW1lICE9PSAiSU1HIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPCBwcm9wZXJ0aWVzTGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eSA9IHByb3BlcnRpZXNbaV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGVbcHJvcGVydHldKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LnNldEF0dHJpYnV0ZShwcm9wZXJ0eSwgcGFyc2VJbnQoc3R5bGVbcHJvcGVydHldLCAxMCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlW3Byb3BlcnR5XSA9ICIiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBBZnRlciByZXNpemluZyBJRSBzb21ldGltZXMgZm9yZ2V0cyB0byByZW1vdmUgdGhlIG9sZCByZXNpemUgaGFuZGxlcwogICAgICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUucXVpcmtzLnJlZHJhdyhlbGVtZW50KTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9pbml0VW5kb01hbmFnZXIgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLnVuZG9NYW5hZ2VyID0gbmV3IHd5c2lodG1sNS5VbmRvTWFuYWdlcih0aGlzLnBhcmVudCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfaW5pdExpbmVCcmVha2luZyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcywKICAgICAgICAgICAgICAgICAgICBVU0VfTkFUSVZFX0xJTkVfQlJFQUtfSU5TSURFX1RBR1MgPSBbIkxJIiwgIlAiLCAiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiXSwKICAgICAgICAgICAgICAgICAgICBMSVNUX1RBR1MgPSBbIlVMIiwgIk9MIiwgIk1FTlUiXTsKCiAgICAgICAgICAgICAgICBmdW5jdGlvbiBhZGp1c3Qoc2VsZWN0ZWROb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudEVsZW1lbnQgPSBkb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHtub2RlTmFtZSA6IFsiUCIsICJESVYiLCAiSDEiLCAiSDIiLCAiSDMiLCAiSDQiLCAiSDUiLCAiSDYiXX0sIDIpOwogICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnRFbGVtZW50ICYmIChwYXJlbnRFbGVtZW50Lm5vZGVOYW1lID09ICJESVYiIHx8ICFwYXJlbnRFbGVtZW50LnRleHRDb250ZW50IHx8IHBhcmVudEVsZW1lbnQudGV4dENvbnRlbnQudHJpbSgpID09ICIiKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnNlbGVjdGlvbi5leGVjdXRlQW5kUmVzdG9yZShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5jb25maWcudXNlTGluZUJyZWFrcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5yZXBsYWNlV2l0aENoaWxkTm9kZXMocGFyZW50RWxlbWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmVudEVsZW1lbnQubm9kZU5hbWUgIT09ICJQIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5yZW5hbWVFbGVtZW50KHBhcmVudEVsZW1lbnQsICJwIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlnLnVzZUxpbmVCcmVha3MpIHsKICAgICAgICAgICAgICAgICAgICBkb20ub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsIFsiZm9jdXMiLCAia2V5ZG93biJdLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGF0LmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmFncmFwaCA9IHRoYXQuZG9jLmNyZWF0ZUVsZW1lbnQoIlAiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZWxlbWVudC5pbm5lckhUTUwgPSAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZWxlbWVudC5hcHBlbmRDaGlsZChwYXJhZ3JhcGgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNwYW4gPSB0aGF0LmRvYy5jcmVhdGVFbGVtZW50KCJzcGFuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhZ3JhcGguYXBwZW5kQ2hpbGQoc3Bhbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWJyb3dzZXIuZGlzcGxheXNDYXJldEluRW1wdHlDb250ZW50RWRpdGFibGVDb3JyZWN0bHkoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYW4uaW5uZXJIVE1MID0gIjxicj4iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5zZWxlY3Rpb24uc2VsZWN0Tm9kZShzcGFuLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGRvbS5vYnNlcnZlKHRoaXMuZWxlbWVudCwgImtleWRvd24iLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIga2V5Q29kZSA9IGV2ZW50LmtleUNvZGU7CgogICAgICAgICAgICAgICAgICAgIGlmIChldmVudC5zaGlmdEtleSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoa2V5Q29kZSAhPT0gd3lzaWh0bWw1LkVOVEVSX0tFWSAmJiBrZXlDb2RlICE9PSB3eXNpaHRtbDUuQkFDS1NQQUNFX0tFWSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB2YXIgYmxvY2tFbGVtZW50ID0gZG9tLmdldFBhcmVudEVsZW1lbnQodGhhdC5zZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKCksIHtub2RlTmFtZSA6IFVTRV9OQVRJVkVfTElORV9CUkVBS19JTlNJREVfVEFHU30pOwoKICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tFbGVtZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVW53cmFwIHBhcmFncmFwaCBhZnRlciBsZWF2aW5nIGEgbGlzdCBvciBhIEgxLTYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzZWxlY3RlZE5vZGUgPSB0aGF0LnNlbGVjdGlvbi5nZXRTZWxlY3RlZE5vZGUoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9GaXhpbmcgZm9yIExDLTM5MTA2ODIgOiBbVGV4dCBFZGl0b3JdIC0gTmV3ICdoZWxwIGNvbnRlbnQnIHN5bWJvbCBnZXRzIGFkZGVkIHdoZW4gdXNlciBwcmVzcyBlbnRlciBhZnRlciBhICdoZWxwIGNvbnRlbnQnIHN5bWJvbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSXRzIGhhY2t5IG1ldGhvZCBidXQgZGlkbnQgZmluZCB3aG8gaXMgY29weWluZyB0aGUgc3R5bGUgJiBjbGFzcyBuYW1lIG9uIGNyZWF0aW5nIG5ldyBub2RlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lID0gInRleHRFZGl0b3ItY3VzdG9tRGF0YUF0dHIiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZSAmJiBzZWxlY3RlZE5vZGUuY2xhc3NOYW1lICYmIHNlbGVjdGVkTm9kZS5jbGFzc05hbWUuaW5kZXhPZihjbGFzc05hbWUpICE9IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWROb2RlLmNsYXNzTmFtZSA9IHNlbGVjdGVkTm9kZS5jbGFzc05hbWUucmVwbGFjZShjbGFzc05hbWUsICIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YSA9ICQoc2VsZWN0ZWROb2RlKS5kYXRhKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIGRhdGEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJChzZWxlY3RlZE5vZGUpLnJlbW92ZURhdGEoa2V5KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJChzZWxlY3RlZE5vZGUpLnJlbW92ZUF0dHIoImRhdGEtIiArIGtleSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoYXQuY29uZmlnICYmIHRoYXQuY29uZmlnLnBhcnNlclJ1bGVzICYmIHRoYXQuY29uZmlnLnBhcnNlclJ1bGVzLnBzZXVkb1RhZ3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZU5hbWVzID0gdGhhdC5jb25maWcucGFyc2VyUnVsZXMucHNldWRvVGFncy5tYXAoZnVuY3Rpb24gKHRhZykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFnLnRvVXBwZXJDYXNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcHNldWRvTm9kZSA9IGRvbS5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkTm9kZSwge25vZGVOYW1lIDogbm9kZU5hbWVzfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBzZXVkb05vZGUgJiYgIXBzZXVkb05vZGUudGV4dENvbnRlbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHNldWRvTm9kZS5vdXRlckhUTUwgPSAiPHNwYW4+IiArIHBzZXVkb05vZGUuaW5uZXJIVE1MICsgIjwvc3Bhbj4iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tFbGVtZW50Lm5vZGVOYW1lID09PSAiTEkiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzZWxlY3RlZE5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdCA9IGRvbS5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkTm9kZSwge25vZGVOYW1lIDogTElTVF9UQUdTfSwgMik7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbGlzdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGp1c3Qoc2VsZWN0ZWROb2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleUNvZGUgPT09IHd5c2lodG1sNS5FTlRFUl9LRVkgJiYgYmxvY2tFbGVtZW50Lm5vZGVOYW1lLm1hdGNoKC9eSFsxLTZdJC8pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRqdXN0KHNlbGVjdGVkTm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVmZXRjaGluZyB0aGUgc2VsZWN0ZWQgbm9kZSBhcyBpdCBtYXkgYmUgbW9kaWZlZCBieSBhZGp1c3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZSA9IHRoYXQuc2VsZWN0aW9uLmdldFNlbGVjdGVkTm9kZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgZXZlcnkgcGFyYWdyYXBoICYgTEkgaGF2ZSBzcGFuIGVsZW1lbnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtYXRjaGluZ05vZGVzID0gWyJQIiwgIkxJIiwgIkRJViJdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbXB0TGlzdCA9IFtdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4IDwgbWF0Y2hpbmdOb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlTmFtZSA9IG1hdGNoaW5nTm9kZXNbaW5kZXhdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGFnTmFtZSA9IG5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZE5vZGUubm9kZU5hbWUgPT09IG5vZGVOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbXB0TGlzdCA9IFtdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1wdExpc3QucHVzaCgiPCIgKyB0YWdOYW1lICsgIj48LyIgKyB0YWdOYW1lICsgIj4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcHRMaXN0LnB1c2goIjwiICsgdGFnTmFtZSArICI+PGJyPjwvIiArIHRhZ05hbWUgKyAiPiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1wdExpc3QucHVzaCgiPCIgKyB0YWdOYW1lICsgIj48YnI+PC9icj48LyIgKyB0YWdOYW1lICsgIj4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIG5vZGUgaXMgZW1wdHkgKCBlbXB0eSBpbmNsdWRlIDxicj4gY2FzZSBhbHNvKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVtcHRMaXN0LmluZGV4T2Yoc2VsZWN0ZWROb2RlLm91dGVySFRNTCkgPiAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzcGFuID0gdGhhdC5kb2MuY3JlYXRlRWxlbWVudCgic3BhbiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYnJvd3Nlci5kaXNwbGF5c0NhcmV0SW5FbXB0eUNvbnRlbnRFZGl0YWJsZUNvcnJlY3RseSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYW4uaW5uZXJIVE1MID0gIjxicj4iOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmUgPEJSPiBpZiBhbnkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc2VsZWN0ZWROb2RlLmZpcnN0Q2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWROb2RlLnJlbW92ZUNoaWxkKHNlbGVjdGVkTm9kZS5maXJzdENoaWxkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWROb2RlLmFwcGVuZENoaWxkKHNwYW4pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZE5vZGUubm9kZU5hbWUgPT09ICJESVYiKSB7Ly8gTWFrZSBzdXJlIHdlIGhhdmUgb25seSBQIG9yIExJIHRhZ3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tLnJlbmFtZUVsZW1lbnQoc2VsZWN0ZWROb2RlLCAicCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnNlbGVjdGlvbi5zZWxlY3ROb2RlKHNwYW4pOy8vIEZvcmNpbmcgdG8gZm9jdXMgb24gc3BhbiBvdGhlciB0ZXh0IHdpbGwgYmUgaW5zZXJ0IGF0IHAgb3IgbGkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCBldmVyeSBMSSBoYXZlIHBhcmFncmFwaCtzcGFuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50TEkgPSBkb20uZ2V0UGFyZW50RWxlbWVudChzZWxlY3RlZE5vZGUsIHtub2RlTmFtZSA6ICJMSSJ9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudERJViA9IGRvbS5nZXRQYXJlbnRFbGVtZW50KHNlbGVjdGVkTm9kZSwge25vZGVOYW1lIDogIkRJViJ9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudExJKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmEgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgZmlzdCBjaGlsZCBub2RlIGlzIHBhcmFncmFwaCA6IGlmIHRydWUgc2ltcGxlIHJldHVybiBvciBlbHNlIG1vdmUgdGhlIExJIGNvbnRlbnQgdG8gcGFyYWdyYXBoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBhcmUgbm90IGNoZWNrIGFsbCB0aGUgY2hpbGQgYXMgc2hpZnQgZW50ZXIgaXMgdXNlZCBmb3IgbmV3IExpbmUgYW5kIGl0IHdpbGwgY3JlYXRlIHNwYW4gaW4gcGFyYWdyYXBoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50TEkuY2hpbGRFbGVtZW50Q291bnQgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGROb2RlID0gcGFyZW50TEkuY2hpbGROb2Rlc1swXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGROb2RlICYmIGNoaWxkTm9kZS5ub2RlTmFtZSA9PSAiUCIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmEgPSB0aGF0LmRvYy5jcmVhdGVFbGVtZW50KCJwIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudExJLmFwcGVuZENoaWxkKHBhcmEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGNoaWxkSW5kZXggPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZEluZGV4IDwgcGFyZW50TEkuY2hpbGRFbGVtZW50Q291bnQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkSW5kZXgrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkTm9kZSA9IHBhcmVudExJLmNoaWxkTm9kZXNbY2hpbGRJbmRleF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYS5hcHBlbmRDaGlsZChjaGlsZE5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuc2VsZWN0aW9uLnNlbGVjdE5vZGUoY2hpbGROb2RlKTsvLyBGb3JjaW5nIHRvIGZvY3VzIG9uIHNwYW4gb3RoZXIgdGV4dCB3aWxsIGJlIGluc2VydCBhdCBwIG9yIGxpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudERJViAmJiAhd3lzaWh0bWw1LnV0aWwuaXNFZGl0b3JOb2RlKHBhcmVudERJVikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJzZWRFbGVtID0gdGhhdC5wYXJlbnQucGFyc2UocGFyZW50RElWKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZWRFbGVtLmlubmVySFRNTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudERJVi5vdXRlckhUTUwgPSBwYXJzZWRFbGVtLmlubmVySFRNTDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh0aGF0LmNvbmZpZy51c2VMaW5lQnJlYWtzICYmIGtleUNvZGUgPT09IHd5c2lodG1sNS5FTlRFUl9LRVkgJiYgIXd5c2lodG1sNS5icm93c2VyLmluc2VydHNMaW5lQnJlYWtzT25SZXR1cm4oKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmNvbW1hbmRzLmV4ZWMoImluc2VydExpbmVCcmVhayIpOwogICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7CihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgZG9tID0gd3lzaWh0bWw1LmRvbSwKICAgICAgICBkb2MgPSBkb2N1bWVudCwKICAgICAgICB3aW4gPSB3aW5kb3csCiAgICAgICAgSE9TVF9URU1QTEFURSA9IGRvYy5jcmVhdGVFbGVtZW50KCJkaXYiKSwKICAgICAgICAvKioKICAgICAgICAgKiBTdHlsZXMgdG8gY29weSBmcm9tIHRleHRhcmVhIHRvIHRoZSBjb21wb3NlciBlbGVtZW50CiAgICAgICAgICovCiAgICAgICAgVEVYVF9GT1JNQVRUSU5HID0gWwogICAgICAgICAgICAiYmFja2dyb3VuZC1jb2xvciIsCiAgICAgICAgICAgICJjb2xvciIsICJjdXJzb3IiLAogICAgICAgICAgICAiZm9udC1mYW1pbHkiLCAiZm9udC1zaXplIiwgImZvbnQtc3R5bGUiLCAiZm9udC12YXJpYW50IiwgImZvbnQtd2VpZ2h0IiwKICAgICAgICAgICAgImxpbmUtaGVpZ2h0IiwgImxldHRlci1zcGFjaW5nIiwKICAgICAgICAgICAgInRleHQtYWxpZ24iLCAidGV4dC1kZWNvcmF0aW9uIiwgInRleHQtaW5kZW50IiwgInRleHQtcmVuZGVyaW5nIiwKICAgICAgICAgICAgIndvcmQtYnJlYWsiLCAid29yZC13cmFwIiwgIndvcmQtc3BhY2luZyIKICAgICAgICBdLAogICAgICAgIC8qKgogICAgICAgICAqIFN0eWxlcyB0byBjb3B5IGZyb20gdGV4dGFyZWEgdG8gdGhlIGlmcmFtZQogICAgICAgICAqLwogICAgICAgIEJPWF9GT1JNQVRUSU5HID0gWwogICAgICAgICAgICAiYmFja2dyb3VuZC1jb2xvciIsCiAgICAgICAgICAgICJib3JkZXItY29sbGFwc2UiLAogICAgICAgICAgICAiYm9yZGVyLWJvdHRvbS1jb2xvciIsICJib3JkZXItYm90dG9tLXN0eWxlIiwgImJvcmRlci1ib3R0b20td2lkdGgiLAogICAgICAgICAgICAiYm9yZGVyLWxlZnQtY29sb3IiLCAiYm9yZGVyLWxlZnQtc3R5bGUiLCAiYm9yZGVyLWxlZnQtd2lkdGgiLAogICAgICAgICAgICAiYm9yZGVyLXJpZ2h0LWNvbG9yIiwgImJvcmRlci1yaWdodC1zdHlsZSIsICJib3JkZXItcmlnaHQtd2lkdGgiLAogICAgICAgICAgICAiYm9yZGVyLXRvcC1jb2xvciIsICJib3JkZXItdG9wLXN0eWxlIiwgImJvcmRlci10b3Atd2lkdGgiLAogICAgICAgICAgICAiY2xlYXIiLCAiZGlzcGxheSIsICJmbG9hdCIsCiAgICAgICAgICAgICJtYXJnaW4tYm90dG9tIiwgIm1hcmdpbi1sZWZ0IiwgIm1hcmdpbi1yaWdodCIsICJtYXJnaW4tdG9wIiwKICAgICAgICAgICAgIm91dGxpbmUtY29sb3IiLCAib3V0bGluZS1vZmZzZXQiLCAib3V0bGluZS13aWR0aCIsICJvdXRsaW5lLXN0eWxlIiwKICAgICAgICAgICAgInBhZGRpbmctbGVmdCIsICJwYWRkaW5nLXJpZ2h0IiwgInBhZGRpbmctdG9wIiwgInBhZGRpbmctYm90dG9tIiwKICAgICAgICAgICAgInBvc2l0aW9uIiwgInRvcCIsICJsZWZ0IiwgInJpZ2h0IiwgImJvdHRvbSIsICJ6LWluZGV4IiwKICAgICAgICAgICAgInZlcnRpY2FsLWFsaWduIiwgInRleHQtYWxpZ24iLAogICAgICAgICAgICAiLXdlYmtpdC1ib3gtc2l6aW5nIiwgIi1tb3otYm94LXNpemluZyIsICItbXMtYm94LXNpemluZyIsICJib3gtc2l6aW5nIiwKICAgICAgICAgICAgIi13ZWJraXQtYm94LXNoYWRvdyIsICItbW96LWJveC1zaGFkb3ciLCAiLW1zLWJveC1zaGFkb3ciLCAiYm94LXNoYWRvdyIsCiAgICAgICAgICAgICItd2Via2l0LWJvcmRlci10b3AtcmlnaHQtcmFkaXVzIiwgIi1tb3otYm9yZGVyLXJhZGl1cy10b3ByaWdodCIsICJib3JkZXItdG9wLXJpZ2h0LXJhZGl1cyIsCiAgICAgICAgICAgICItd2Via2l0LWJvcmRlci1ib3R0b20tcmlnaHQtcmFkaXVzIiwgIi1tb3otYm9yZGVyLXJhZGl1cy1ib3R0b21yaWdodCIsICJib3JkZXItYm90dG9tLXJpZ2h0LXJhZGl1cyIsCiAgICAgICAgICAgICItd2Via2l0LWJvcmRlci1ib3R0b20tbGVmdC1yYWRpdXMiLCAiLW1vei1ib3JkZXItcmFkaXVzLWJvdHRvbWxlZnQiLCAiYm9yZGVyLWJvdHRvbS1sZWZ0LXJhZGl1cyIsCiAgICAgICAgICAgICItd2Via2l0LWJvcmRlci10b3AtbGVmdC1yYWRpdXMiLCAiLW1vei1ib3JkZXItcmFkaXVzLXRvcGxlZnQiLCAiYm9yZGVyLXRvcC1sZWZ0LXJhZGl1cyIsCiAgICAgICAgICAgICJ3aWR0aCIsICJoZWlnaHQiLCAid2hpdGUtc3BhY2UiCiAgICAgICAgXSwKICAgICAgICBBRERJVElPTkFMX0NTU19SVUxFUyA9IFsKICAgICAgICAgICAgImh0bWwgICAgICAgICAgICAgICAgIHsgaGVpZ2h0OiAxMDAlOyB9IiwKICAgICAgICAgICAgImJvZHkgICAgICAgICAgICAgICAgIHsgaGVpZ2h0OiAxMDAlOyBwYWRkaW5nOiAxcHggMCAwIDA7IG1hcmdpbjogLTFweCAwIDAgMDsgfSIsCiAgICAgICAgICAgICJib2R5ID4gcDpmaXJzdC1jaGlsZCB7IG1hcmdpbi10b3A6IDA7IH0iLAogICAgICAgICAgICAiLl93eXNpaHRtbDUtdGVtcCAgICAgeyBkaXNwbGF5OiBub25lOyB9IiwKICAgICAgICAgICAgd3lzaWh0bWw1LmJyb3dzZXIuaXNHZWNrbyA/CiAgICAgICAgICAgICAgICAiYm9keS5wbGFjZWhvbGRlciB7IGNvbG9yOiBncmF5dGV4dCAhaW1wb3J0YW50OyB9IiA6CiAgICAgICAgICAgICAgICAiYm9keS5wbGFjZWhvbGRlciB7IGNvbG9yOiAjYTlhOWE5ICFpbXBvcnRhbnQ7IH0iLAogICAgICAgICAgICAvLyBFbnN1cmUgdGhhdCB1c2VyIHNlZSdzIGJyb2tlbiBpbWFnZXMgYW5kIGNhbiBkZWxldGUgdGhlbQogICAgICAgICAgICAiaW1nOi1tb3otYnJva2VuICAgICAgeyAtbW96LWZvcmNlLWJyb2tlbi1pbWFnZS1pY29uOiAxOyBoZWlnaHQ6IDI0cHg7IHdpZHRoOiAyNHB4OyB9IgogICAgICAgIF07CgogICAgLyoqCiAgICAgKiBXaXRoICJzZXRBY3RpdmUiIElFIG9mZmVycyBhIHNtYXJ0IHdheSBvZiBmb2N1c2luZyBlbGVtZW50cyB3aXRob3V0IHNjcm9sbGluZyB0aGVtIGludG8gdmlldzoKICAgICAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNjczOCh2PXZzLjg1KS5hc3B4CiAgICAgKgogICAgICogT3RoZXIgYnJvd3NlcnMgbmVlZCBhIG1vcmUgaGFja3kgd2F5OiAocHNzc3QgZG9uJ3QgdGVsbCBteSBtYW1hKQogICAgICogSW4gb3JkZXIgdG8gcHJldmVudCB0aGUgZWxlbWVudCBiZWluZyBzY3JvbGxlZCBpbnRvIHZpZXcgd2hlbiBmb2N1c2luZyBpdCwgd2Ugc2ltcGx5CiAgICAgKiBtb3ZlIGl0IG91dCBvZiB0aGUgc2Nyb2xsYWJsZSBhcmVhLCBmb2N1cyBpdCwgYW5kIHJlc2V0IGl0J3MgcG9zaXRpb24KICAgICAqLwogICAgdmFyIGZvY3VzV2l0aG91dFNjcm9sbGluZyA9IGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgICAgaWYgKGVsZW1lbnQuc2V0QWN0aXZlKSB7CiAgICAgICAgICAgIC8vIEZvbGxvd2luZyBsaW5lIGNvdWxkIGNhdXNlIGEganMgZXJyb3Igd2hlbiB0aGUgdGV4dGFyZWEgaXMgaW52aXNpYmxlCiAgICAgICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20veGluZy93eXNpaHRtbDUvaXNzdWVzLzkKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QWN0aXZlKCk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZhciBlbGVtZW50U3R5bGUgPSBlbGVtZW50LnN0eWxlLAogICAgICAgICAgICAgICAgb3JpZ2luYWxTY3JvbGxUb3AgPSBkb2MuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBkb2MuYm9keS5zY3JvbGxUb3AsCiAgICAgICAgICAgICAgICBvcmlnaW5hbFNjcm9sbExlZnQgPSBkb2MuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQgfHwgZG9jLmJvZHkuc2Nyb2xsTGVmdCwKICAgICAgICAgICAgICAgIG9yaWdpbmFsU3R5bGVzID0gewogICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uIDogZWxlbWVudFN0eWxlLnBvc2l0aW9uLAogICAgICAgICAgICAgICAgICAgIHRvcCA6IGVsZW1lbnRTdHlsZS50b3AsCiAgICAgICAgICAgICAgICAgICAgbGVmdCA6IGVsZW1lbnRTdHlsZS5sZWZ0LAogICAgICAgICAgICAgICAgICAgIFdlYmtpdFVzZXJTZWxlY3QgOiBlbGVtZW50U3R5bGUuV2Via2l0VXNlclNlbGVjdAogICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIGRvbS5zZXRTdHlsZXMoewogICAgICAgICAgICAgICAgcG9zaXRpb24gOiAiYWJzb2x1dGUiLAogICAgICAgICAgICAgICAgdG9wIDogIi05OTk5OXB4IiwKICAgICAgICAgICAgICAgIGxlZnQgOiAiLTk5OTk5cHgiLAogICAgICAgICAgICAgICAgLy8gRG9uJ3QgYXNrIHdoeSBidXQgdGVtcG9yYXJpbHkgc2V0dGluZyAtd2Via2l0LXVzZXItc2VsZWN0IHRvIG5vbmUgbWFrZXMgdGhlIHdob2xlIHRoaW5nIHBlcmZvcm1pbmcgc21vb3RoZXIKICAgICAgICAgICAgICAgIFdlYmtpdFVzZXJTZWxlY3QgOiAibm9uZSIKICAgICAgICAgICAgfSkub24oZWxlbWVudCk7CgogICAgICAgICAgICBlbGVtZW50LmZvY3VzKCk7CgogICAgICAgICAgICBkb20uc2V0U3R5bGVzKG9yaWdpbmFsU3R5bGVzKS5vbihlbGVtZW50KTsKCiAgICAgICAgICAgIGlmICh3aW4uc2Nyb2xsVG8pIHsKICAgICAgICAgICAgICAgIC8vIFNvbWUgYnJvd3NlciBleHRlbnNpb25zIHVuc2V0IHRoaXMgbWV0aG9kIHRvIHByZXZlbnQgYW5ub3lhbmNlcwogICAgICAgICAgICAgICAgLy8gIkJldHRlciBQb3BVcCBCbG9ja2VyIiBmb3IgQ2hyb21lIGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9iZXR0ZXJwb3B1cGJsb2NrZXIvc291cmNlL2Jyb3dzZS90cnVuay9ibG9ja1N0YXJ0LmpzIzEwMAogICAgICAgICAgICAgICAgLy8gSXNzdWU6IGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9iZXR0ZXJwb3B1cGJsb2NrZXIvaXNzdWVzL2RldGFpbD9pZD0xCiAgICAgICAgICAgICAgICB3aW4uc2Nyb2xsVG8ob3JpZ2luYWxTY3JvbGxMZWZ0LCBvcmlnaW5hbFNjcm9sbFRvcCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwoKICAgIHd5c2lodG1sNS52aWV3cy5Db21wb3Nlci5wcm90b3R5cGUuc3R5bGUgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHRoYXQgPSB0aGlzLAogICAgICAgICAgICBvcmlnaW5hbEFjdGl2ZUVsZW1lbnQgPSBkb2MucXVlcnlTZWxlY3RvcigiOmZvY3VzIiksCiAgICAgICAgICAgIHRleHRhcmVhRWxlbWVudCA9IHRoaXMudGV4dGFyZWEuZWxlbWVudCwKICAgICAgICAgICAgaGFzUGxhY2Vob2xkZXIgPSB0ZXh0YXJlYUVsZW1lbnQuaGFzQXR0cmlidXRlKCJwbGFjZWhvbGRlciIpLAogICAgICAgICAgICBvcmlnaW5hbFBsYWNlaG9sZGVyID0gaGFzUGxhY2Vob2xkZXIgJiYgdGV4dGFyZWFFbGVtZW50LmdldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiKSwKICAgICAgICAgICAgb3JpZ2luYWxEaXNwbGF5VmFsdWUgPSB0ZXh0YXJlYUVsZW1lbnQuc3R5bGUuZGlzcGxheSwKICAgICAgICAgICAgb3JpZ2luYWxEaXNhYmxlZCA9IHRleHRhcmVhRWxlbWVudC5kaXNhYmxlZCwKICAgICAgICAgICAgZGlzcGxheVZhbHVlRm9yQ29weWluZzsKCiAgICAgICAgdGhpcy5mb2N1c1N0eWxlc0hvc3QgPSBIT1NUX1RFTVBMQVRFLmNsb25lTm9kZShmYWxzZSk7CiAgICAgICAgdGhpcy5ibHVyU3R5bGVzSG9zdCA9IEhPU1RfVEVNUExBVEUuY2xvbmVOb2RlKGZhbHNlKTsKICAgICAgICB0aGlzLmRpc2FibGVkU3R5bGVzSG9zdCA9IEhPU1RfVEVNUExBVEUuY2xvbmVOb2RlKGZhbHNlKTsKCiAgICAgICAgLy8gUmVtb3ZlIHBsYWNlaG9sZGVyIGJlZm9yZSBjb3B5aW5nIChhcyB0aGUgcGxhY2Vob2xkZXIgaGFzIGFuIGFmZmVjdCBvbiB0aGUgY29tcHV0ZWQgc3R5bGUpCiAgICAgICAgaWYgKGhhc1BsYWNlaG9sZGVyKSB7CiAgICAgICAgICAgIHRleHRhcmVhRWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIik7CiAgICAgICAgfQoKICAgICAgICBpZiAodGV4dGFyZWFFbGVtZW50ID09PSBvcmlnaW5hbEFjdGl2ZUVsZW1lbnQpIHsKICAgICAgICAgICAgdGV4dGFyZWFFbGVtZW50LmJsdXIoKTsKICAgICAgICB9CgogICAgICAgIC8vIGVuYWJsZSBmb3IgY29weWluZyBzdHlsZXMKICAgICAgICB0ZXh0YXJlYUVsZW1lbnQuZGlzYWJsZWQgPSBmYWxzZTsKCiAgICAgICAgLy8gc2V0IHRleHRhcmVhIHRvIGRpc3BsYXk9Im5vbmUiIHRvIGdldCBjYXNjYWRlZCBzdHlsZXMgdmlhIGdldENvbXB1dGVkU3R5bGUKICAgICAgICB0ZXh0YXJlYUVsZW1lbnQuc3R5bGUuZGlzcGxheSA9IGRpc3BsYXlWYWx1ZUZvckNvcHlpbmcgPSAibm9uZSI7CiAgICAgICAgdGV4dGFyZWFFbGVtZW50LnN0eWxlLnZpc2liaWxpdHkgPSAiaGlkZGVuIjsKCiAgICAgICAgaWYgKCh0ZXh0YXJlYUVsZW1lbnQuZ2V0QXR0cmlidXRlKCJyb3dzIikgJiYgZG9tLmdldFN0eWxlKCJoZWlnaHQiKS5mcm9tKHRleHRhcmVhRWxlbWVudCkgPT09ICJhdXRvIikgfHwKICAgICAgICAgICAgKHRleHRhcmVhRWxlbWVudC5nZXRBdHRyaWJ1dGUoImNvbHMiKSAmJiBkb20uZ2V0U3R5bGUoIndpZHRoIikuZnJvbSh0ZXh0YXJlYUVsZW1lbnQpID09PSAiYXV0byIpKSB7CiAgICAgICAgICAgIHRleHRhcmVhRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gZGlzcGxheVZhbHVlRm9yQ29weWluZyA9IG9yaWdpbmFsRGlzcGxheVZhbHVlOwogICAgICAgIH0KCiAgICAgICAgLy8gLS0tLS0tLS0tIGNvbnRhaW5lciBzdHlsZXMgKGhhcyB0byBiZSBzZXQgYmVmb3JlIGVkaXRvciBzdHlsZXMsIG90aGVyd2lzZSBJRTkgc2V0cyB3cm9uZyBmb250RmFtaWx5IG9uIGJsdXJTdHlsZXNIb3N0KSAtLS0tLS0tLS0KICAgICAgICBkb20uY29weVN0eWxlcyhCT1hfRk9STUFUVElORykuZnJvbSh0ZXh0YXJlYUVsZW1lbnQpLnRvKHRoaXMuY29udGFpbmVyKS5hbmRUbyh0aGlzLmJsdXJTdHlsZXNIb3N0KTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIGVkaXRvciBzdHlsZXMgLS0tLS0tLS0tCiAgICAgICAgZG9tLmNvcHlTdHlsZXMoVEVYVF9GT1JNQVRUSU5HKS5mcm9tKHRleHRhcmVhRWxlbWVudCkudG8odGhpcy5lbGVtZW50KS5hbmRUbyh0aGlzLmJsdXJTdHlsZXNIb3N0KTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIGFwcGx5IHN0YW5kYXJkIHJ1bGVzIC0tLS0tLS0tLQogICAgICAgIGRvbS5pbnNlcnRDU1MoQURESVRJT05BTF9DU1NfUlVMRVMpLmludG8odGhpcy5lbGVtZW50Lm93bmVyRG9jdW1lbnQpOwoKICAgICAgICAvLyAtLS0tLS0tLS0gOmRpc2FibGVkIHN0eWxlcyAtLS0tLS0tLS0KICAgICAgICB0ZXh0YXJlYUVsZW1lbnQuZGlzYWJsZWQgPSB0cnVlOwogICAgICAgIGRvbS5jb3B5U3R5bGVzKEJPWF9GT1JNQVRUSU5HKS5mcm9tKHRleHRhcmVhRWxlbWVudCkudG8odGhpcy5kaXNhYmxlZFN0eWxlc0hvc3QpOwogICAgICAgIGRvbS5jb3B5U3R5bGVzKFRFWFRfRk9STUFUVElORykuZnJvbSh0ZXh0YXJlYUVsZW1lbnQpLnRvKHRoaXMuZGlzYWJsZWRTdHlsZXNIb3N0KTsKICAgICAgICB0ZXh0YXJlYUVsZW1lbnQuZGlzYWJsZWQgPSBvcmlnaW5hbERpc2FibGVkOwoKICAgICAgICAvLyAtLS0tLS0tLS0gOmZvY3VzIHN0eWxlcyAtLS0tLS0tLS0KICAgICAgICB0ZXh0YXJlYUVsZW1lbnQuc3R5bGUuZGlzcGxheSA9IG9yaWdpbmFsRGlzcGxheVZhbHVlOwogICAgICAgIGZvY3VzV2l0aG91dFNjcm9sbGluZyh0ZXh0YXJlYUVsZW1lbnQpOwogICAgICAgIHRleHRhcmVhRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gZGlzcGxheVZhbHVlRm9yQ29weWluZzsKCiAgICAgICAgZG9tLmNvcHlTdHlsZXMoQk9YX0ZPUk1BVFRJTkcpLmZyb20odGV4dGFyZWFFbGVtZW50KS50byh0aGlzLmZvY3VzU3R5bGVzSG9zdCk7CiAgICAgICAgZG9tLmNvcHlTdHlsZXMoVEVYVF9GT1JNQVRUSU5HKS5mcm9tKHRleHRhcmVhRWxlbWVudCkudG8odGhpcy5mb2N1c1N0eWxlc0hvc3QpOwoKICAgICAgICAvLyByZXNldCB0ZXh0YXJlYQogICAgICAgIHRleHRhcmVhRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gb3JpZ2luYWxEaXNwbGF5VmFsdWU7CgogICAgICAgIGRvbS5jb3B5U3R5bGVzKFsiZGlzcGxheSJdKS5mcm9tKHRleHRhcmVhRWxlbWVudCkudG8odGhpcy5jb250YWluZXIpOwoKICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCB3ZSBkb24ndCBjaGFuZ2UgdGhlIGRpc3BsYXkgc3R5bGUgb2YgdGhlIGNvbnRhaW5lciB3aGVuIGNvcHlpbmcgc3R5bGVzIG9ibHVyL29uZm9jdXMKICAgICAgICAvLyB0aGlzIGlzIG5lZWRlZCBmb3Igd2hlbiB0aGUgY2hhbmdlX3ZpZXcgZXZlbnQgaXMgZmlyZWQgd2hlcmUgdGhlIGNvbnRhaW5lciBpcyBoaWRkZW4gYW5kIHRoZW4KICAgICAgICAvLyB0aGUgYmx1ciBldmVudCBmaXJlcyBhbmQgcmUtZGlzcGxheXMgaXQKICAgICAgICB2YXIgYm94Rm9ybWF0dGluZ1N0eWxlcyA9IHd5c2lodG1sNS5sYW5nLmFycmF5KEJPWF9GT1JNQVRUSU5HKS53aXRob3V0KFsiZGlzcGxheSJdKTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIHJlc3RvcmUgZm9jdXMgLS0tLS0tLS0tCiAgICAgICAgaWYgKG9yaWdpbmFsQWN0aXZlRWxlbWVudCkgewogICAgICAgICAgICBvcmlnaW5hbEFjdGl2ZUVsZW1lbnQuZm9jdXMoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0ZXh0YXJlYUVsZW1lbnQuYmx1cigpOwogICAgICAgIH0KCiAgICAgICAgLy8gLS0tLS0tLS0tIHJlc3RvcmUgcGxhY2Vob2xkZXIgLS0tLS0tLS0tCiAgICAgICAgaWYgKGhhc1BsYWNlaG9sZGVyKSB7CiAgICAgICAgICAgIHRleHRhcmVhRWxlbWVudC5zZXRBdHRyaWJ1dGUoInBsYWNlaG9sZGVyIiwgb3JpZ2luYWxQbGFjZWhvbGRlcik7CiAgICAgICAgfQoKICAgICAgICAvLyAtLS0tLS0tLS0gU3luYyBmb2N1cy9ibHVyIHN0eWxlcyAtLS0tLS0tLS0KCiAgICAgICAgdGhpcy5wYXJlbnQub24oImJsdXI6Y29tcG9zZXIiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vIEZpeGluZyBMQy0zOTExOTk0CiAgICAgICAgICAgIHRoaXMuc2F2ZWRTZWxlY3Rpb24gPSB0aGlzLmNvbXBvc2VyLnNlbGVjdGlvbi5nZXRDdXJyZW50UmFuZ2UoKTsKICAgICAgICB9KTsKCiAgICAgICAgdGhpcy5wYXJlbnQub2JzZXJ2ZSgiZGlzYWJsZTpjb21wb3NlciIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgZG9tLmNvcHlTdHlsZXMoYm94Rm9ybWF0dGluZ1N0eWxlcykuZnJvbSh0aGF0LmRpc2FibGVkU3R5bGVzSG9zdCkudG8odGhhdC5jb250YWluZXIpOwogICAgICAgICAgICBkb20uY29weVN0eWxlcyhURVhUX0ZPUk1BVFRJTkcpLmZyb20odGhhdC5kaXNhYmxlZFN0eWxlc0hvc3QpLnRvKHRoYXQuZWxlbWVudCk7CiAgICAgICAgfSk7CgogICAgICAgIHRoaXMucGFyZW50Lm9ic2VydmUoImVuYWJsZTpjb21wb3NlciIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgZG9tLmNvcHlTdHlsZXMoYm94Rm9ybWF0dGluZ1N0eWxlcykuZnJvbSh0aGF0LmJsdXJTdHlsZXNIb3N0KS50byh0aGF0LmNvbnRhaW5lcik7CiAgICAgICAgICAgIGRvbS5jb3B5U3R5bGVzKFRFWFRfRk9STUFUVElORykuZnJvbSh0aGF0LmJsdXJTdHlsZXNIb3N0KS50byh0aGF0LmVsZW1lbnQpOwogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gdGhpczsKICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBUYWtpbmcgY2FyZSBvZiBldmVudHMKICogIC0gU2ltdWxhdGluZyAnY2hhbmdlJyBldmVudCBvbiBjb250ZW50RWRpdGFibGUgZWxlbWVudAogKiAgLSBIYW5kbGluZyBkcmFnICYgZHJvcCBsb2dpYwogKiAgLSBDYXRjaCBwYXN0ZSBldmVudHMKICogIC0gRGlzcGF0Y2ggcHJvcHJpZXRhcnkgbmV3d29yZDpjb21wb3NlciBldmVudAogKiAgLSBLZXlib2FyZCBzaG9ydGN1dHMKICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgZG9tID0gd3lzaWh0bWw1LmRvbSwKICAgICAgICBicm93c2VyID0gd3lzaWh0bWw1LmJyb3dzZXIsCiAgICAgICAgLyoqCiAgICAgICAgICogTWFwIGtleUNvZGVzIHRvIHF1ZXJ5IGNvbW1hbmRzCiAgICAgICAgICovCiAgICAgICAgc2hvcnRjdXRzID0gewogICAgICAgICAgICAiNjYiIDogImJvbGQiLCAgICAgLy8gQgogICAgICAgICAgICAiNzMiIDogIml0YWxpYyIsICAgLy8gSQogICAgICAgICAgICAiODUiIDogInVuZGVybGluZSIgLy8gVQogICAgICAgIH07CgogICAgd3lzaWh0bWw1LnZpZXdzLkNvbXBvc2VyLnByb3RvdHlwZS5vYnNlcnZlID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciB0aGF0ID0gdGhpcywKICAgICAgICAgICAgc3RhdGUgPSB0aGlzLmdldFZhbHVlKCksCiAgICAgICAgICAgIGNvbnRhaW5lciA9IHRoaXMuc2FuZGJveC5nZXRDb250YWluZXIoKSwKICAgICAgICAgICAgZWxlbWVudCA9IHRoaXMuZWxlbWVudCwKICAgICAgICAgICAgZm9jdXNCbHVyRWxlbWVudCA9IGJyb3dzZXIuc3VwcG9ydHNFdmVudHNJbklmcmFtZUNvcnJlY3RseSgpID8gZWxlbWVudCA6IHRoaXMuc2FuZGJveC5nZXRXaW5kb3coKSwKICAgICAgICAgICAgcGFzdGVFdmVudHMgPSBbImRyb3AiLCAicGFzdGUiXTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIGRlc3Ryb3k6Y29tcG9zZXIgZXZlbnQgLS0tLS0tLS0tCiAgICAgICAgZG9tLm9ic2VydmUoY29udGFpbmVyLCAiRE9NTm9kZVJlbW92ZWQiLCBmdW5jdGlvbiAoZSkgewogICAgICAgICAgICBpZiAoZS50YXJnZXQgPT0gdGhpcykgeyAvL0Rlc3Ryb3kgY29tcG9zZXIgb25seSBpZiB0aGUgZW50aXJlIFJURSBjb250YWluZXIgaXMgcmVtb3ZlZAogICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChkb21Ob2RlUmVtb3ZlZEludGVydmFsKTsKICAgICAgICAgICAgICAgIHRoYXQucGFyZW50LmZpcmUoImRlc3Ryb3k6Y29tcG9zZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwoKICAgICAgICAvLyBET01Ob2RlUmVtb3ZlZCBldmVudCBpcyBub3Qgc3VwcG9ydGVkIGluIElFIDgKICAgICAgICB2YXIgZG9tTm9kZVJlbW92ZWRJbnRlcnZhbCA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKCFkb20uY29udGFpbnMoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCBjb250YWluZXIpKSB7CiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKGRvbU5vZGVSZW1vdmVkSW50ZXJ2YWwpOwogICAgICAgICAgICAgICAgdGhhdC5wYXJlbnQuZmlyZSgiZGVzdHJveTpjb21wb3NlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwgMjUwKTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIEZvY3VzICYgYmx1ciBsb2dpYyAtLS0tLS0tLS0KICAgICAgICBkb20ub2JzZXJ2ZShmb2N1c0JsdXJFbGVtZW50LCAiZm9jdXMiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoYXQucGFyZW50LmZpcmUoImZvY3VzIikuZmlyZSgiZm9jdXM6Y29tcG9zZXIiKTsKCiAgICAgICAgICAgIC8vIERlbGF5IHN0b3Jpbmcgb2Ygc3RhdGUgdW50aWwgYWxsIGZvY3VzIGhhbmRsZXIgYXJlIGZpcmVkCiAgICAgICAgICAgIC8vIGVzcGVjaWFsbHkgdGhlIG9uZSB3aGljaCByZXNldHMgdGhlIHBsYWNlaG9sZGVyCiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgc3RhdGUgPSB0aGF0LmdldFZhbHVlKCk7CiAgICAgICAgICAgIH0sIDApOwogICAgICAgIH0pOwoKICAgICAgICBkb20ub2JzZXJ2ZShmb2N1c0JsdXJFbGVtZW50LCAiY2xpY2siLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoYXQucGFyZW50LmZpcmUoImNsaWNrOmNvbXBvc2VyIik7CiAgICAgICAgfSk7CgogICAgICAgIGRvbS5vYnNlcnZlKGZvY3VzQmx1ckVsZW1lbnQsICJibHVyIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICBpZiAoc3RhdGUgIT09IHRoYXQuZ2V0VmFsdWUoKSkgewogICAgICAgICAgICAgICAgdGhhdC5wYXJlbnQuZmlyZSgiY2hhbmdlIikuZmlyZSgiY2hhbmdlOmNvbXBvc2VyIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhhdC5wYXJlbnQuZmlyZSgiYmx1ciIpLmZpcmUoImJsdXI6Y29tcG9zZXIiKTsKICAgICAgICB9KTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIERyYWcgJiBEcm9wIGxvZ2ljIC0tLS0tLS0tLQogICAgICAgIGRvbS5vYnNlcnZlKGVsZW1lbnQsICJkcmFnZW50ZXIiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoYXQucGFyZW50LmZpcmUoInVuc2V0X3BsYWNlaG9sZGVyIik7CiAgICAgICAgfSk7CgogICAgICAgIGlmICh3eXNpaHRtbDUuYnJvd3Nlci5pc0lFKSB7CiAgICAgICAgICAgIGRvbS5vYnNlcnZlKGVsZW1lbnQsICJiZWZvcmVwYXN0ZSIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGlvbiA9IHRoYXQucGFyZW50LmNvbXBvc2VyLnNlbGVjdGlvbi5nZXRDdXJyZW50UmFuZ2UoKTsKICAgICAgICAgICAgICAgIHZhciB0ZW1wQ29udGFpbmVyID0gJCgiPGRpdiBjbGFzcz0nd3lzaWh0bWw1LXRlbXBDb250YWluZXInIGNvbnRlbnRlZGl0YWJsZT0ndHJ1ZSc+PC9kaXY+IilbMF07CiAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRlbXBDb250YWluZXIpOwogICAgICAgICAgICAgICAgJCh0ZW1wQ29udGFpbmVyKS5vbmUoInBhc3RlIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnQgPSAiIjsKICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGF0LmNvbmZpZy5wYXN0ZUFzUGxhaW5UZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gc2VsZi50ZXh0Q29udGVudDsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQgPSBzZWxmLmlubmVySFRNTDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gdGhhdC5wYXJlbnQucGFyc2UoY29udGVudCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQucGFyZW50LmZvY3VzKGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5wYXJlbnQuY29tcG9zZXIuc2VsZWN0aW9uLnNldFNlbGVjdGlvbihzZWxlY3Rpb24pOwogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmNvbW1hbmRzLmV4ZWMoImRlbGV0ZSIpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnBhcmVudC5jb21wb3Nlci5zZWxlY3Rpb24uaW5zZXJ0SFRNTChjb250ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgJChzZWxmKS5yZW1vdmUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnBhcmVudC5maXJlKCJwYXN0ZSIpLmZpcmUoInBhc3RlOmNvbXBvc2VyIiwgZXZlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICB9LCAwKTsKICAgICAgICAgICAgICAgICAgICB9LCAwKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgdGVtcENvbnRhaW5lci5mb2N1cygpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICQodGhhdC5wYXJlbnQuY29tcG9zZXIuZG9jLmRlZmF1bHRWaWV3KS5vbignZm9jdXMnLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0aW9uID0gdGhhdC5wYXJlbnQuY29tcG9zZXIuZG9jLmdldFNlbGVjdGlvbigpOwogICAgICAgICAgICAgICAgaWYgKCFzZWxlY3Rpb24gfHwgIXNlbGVjdGlvbi5mb2N1c05vZGUpIHsKICAgICAgICAgICAgICAgICAgICB0aGF0LnBhcmVudC5jb21wb3Nlci5mb2N1cyhmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoYXQucGFyZW50LnNhdmVkU2VsZWN0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQucGFyZW50LmNvbXBvc2VyLnNlbGVjdGlvbi5zZXRTZWxlY3Rpb24odGhhdC5wYXJlbnQuc2F2ZWRTZWxlY3Rpb24pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICBkb20ub2JzZXJ2ZShlbGVtZW50LCBwYXN0ZUV2ZW50cywgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgIGlmICh0aGF0LmNvbmZpZy5wYXN0ZUFzUGxhaW5UZXh0KSB7CiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgdmFyIGNvbnRlbnQgPSAiIjsKICAgICAgICAgICAgICAgIGlmIChldmVudCAmJiBldmVudC5jbGlwYm9hcmREYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IChldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50KS5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQvcGxhaW4nKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAod2luZG93LmNsaXBib2FyZERhdGEpIHsKICAgICAgICAgICAgICAgICAgICBjb250ZW50ID0gd2luZG93LmNsaXBib2FyZERhdGEuZ2V0RGF0YSgnVGV4dCcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGNvbnRlbnQpIHsKICAgICAgICAgICAgICAgICAgICB0aGF0LmNvbW1hbmRzLmV4ZWMuY2FsbCh0aGF0LmNvbW1hbmRzLCAiaW5zZXJ0VGV4dCIsIGNvbnRlbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIGh0bWwgPSAiIjsKICAgICAgICAgICAgICAgIGlmIChldmVudCAmJiBldmVudC5jbGlwYm9hcmREYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgaHRtbCA9IChldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50KS5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQvaHRtbCcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGh0bWwpIHsKICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgICAgIGlmICh0aGF0LnNlbGVjdGlvbi5nZXRUZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5jb21tYW5kcy5leGVjKCJkZWxldGUiKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8qIEV4dHJhY3QgYm9keSBjb250ZW50IGlmIGJvZHkgcHJlc2VudCwgdG8gcmVtb3ZlIHVud2FudGVkIGRhdGEqLwogICAgICAgICAgICAgICAgICAgIHZhciByZSA9IFhSZWdFeHAoIjxib2R5W14+XSo+XFxzKiguKilcXHMqPFwvYm9keT4iLCAiZ3MiKTsKICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gcmUuZXhlYyhodG1sKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQubGVuZ3RoID4gMSkgewogICAgICAgICAgICAgICAgICAgICAgICBodG1sID0gcmVzdWx0WzFdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBodG1sID0gdGhhdC5wYXJlbnQucGFyc2UoaHRtbCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgdGhhdC5wYXJlbnQuY29tcG9zZXIuc2VsZWN0aW9uLmluc2VydEhUTUwoaHRtbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB0aGF0LnBhcmVudC5maXJlKCJwYXN0ZSIpLmZpcmUoInBhc3RlOmNvbXBvc2VyIiwgZXZlbnQpOwogICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKCiAgICAgICAgLy8gLS0tLS0tLS0tIG5ld29yZCBldmVudCAtLS0tLS0tLS0KICAgICAgICBkb20ub2JzZXJ2ZShlbGVtZW50LCAia2V5dXAiLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgdmFyIGtleUNvZGUgPSBldmVudC5rZXlDb2RlOwogICAgICAgICAgICBpZiAoa2V5Q29kZSA9PT0gd3lzaWh0bWw1LlNQQUNFX0tFWSB8fCBrZXlDb2RlID09PSB3eXNpaHRtbDUuRU5URVJfS0VZKSB7CiAgICAgICAgICAgICAgICB0aGF0LnBhcmVudC5maXJlKCJuZXd3b3JkOmNvbXBvc2VyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKCiAgICAgICAgdGhpcy5wYXJlbnQub24oInBhc3RlOmNvbXBvc2VyIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHRoYXQucGFyZW50LmZpcmUoIm5ld3dvcmQ6Y29tcG9zZXIiKTsKICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgfSk7CgogICAgICAgIC8vIC0tLS0tLS0tLSBNYWtlIHN1cmUgdGhhdCBpbWFnZXMgYXJlIHNlbGVjdGVkIHdoZW4gY2xpY2tpbmcgb24gdGhlbSAtLS0tLS0tLS0KICAgICAgICBpZiAoIWJyb3dzZXIuY2FuU2VsZWN0SW1hZ2VzSW5Db250ZW50RWRpdGFibGUoKSkgewogICAgICAgICAgICBkb20ub2JzZXJ2ZShlbGVtZW50LCAibW91c2Vkb3duIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0OwogICAgICAgICAgICAgICAgaWYgKHRhcmdldC5ub2RlTmFtZSA9PT0gIklNRyIpIHsKICAgICAgICAgICAgICAgICAgICB0aGF0LnNlbGVjdGlvbi5zZWxlY3ROb2RlKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICBpZiAoYnJvd3Nlci5oYXNIaXN0b3J5SXNzdWUoKSAmJiBicm93c2VyLnN1cHBvcnRzU2VsZWN0aW9uTW9kaWZ5KCkpIHsKICAgICAgICAgICAgZG9tLm9ic2VydmUoZWxlbWVudCwgImtleWRvd24iLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgIGlmICghZXZlbnQubWV0YUtleSAmJiAhZXZlbnQuY3RybEtleSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIga2V5Q29kZSA9IGV2ZW50LmtleUNvZGUsCiAgICAgICAgICAgICAgICAgICAgd2luID0gZWxlbWVudC5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3LAogICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbiA9IHdpbi5nZXRTZWxlY3Rpb24oKTsKCiAgICAgICAgICAgICAgICBpZiAoa2V5Q29kZSA9PT0gMzcgfHwga2V5Q29kZSA9PT0gMzkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoa2V5Q29kZSA9PT0gMzcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uLm1vZGlmeSgiZXh0ZW5kIiwgImxlZnQiLCAibGluZWJvdW5kYXJ5Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZXZlbnQuc2hpZnRLZXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbi5jb2xsYXBzZVRvU3RhcnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoa2V5Q29kZSA9PT0gMzkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uLm1vZGlmeSgiZXh0ZW5kIiwgInJpZ2h0IiwgImxpbmVib3VuZGFyeSIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWV2ZW50LnNoaWZ0S2V5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb24uY29sbGFwc2VUb0VuZCgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLy8gLS0tLS0tLS0tIFNob3J0Y3V0IGxvZ2ljIC0tLS0tLS0tLQogICAgICAgIGRvbS5vYnNlcnZlKGVsZW1lbnQsICJrZXlkb3duIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciBrZXlDb2RlID0gZXZlbnQua2V5Q29kZSwKICAgICAgICAgICAgICAgIGNvbW1hbmQgPSBzaG9ydGN1dHNba2V5Q29kZV07CiAgICAgICAgICAgIGlmICgoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5KSAmJiAhZXZlbnQuYWx0S2V5ICYmIGNvbW1hbmQpIHsKICAgICAgICAgICAgICAgIHRoYXQuY29tbWFuZHMuZXhlYyhjb21tYW5kKTsKICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKCiAgICAgICAgLyogSGFuZGluZyBUYWIga2V5IDogSW5zZXJ0IHRhYiBpbnRvIHRleHQgYW5kIHByZXZlbnQgbG9zaW5nIHRoZSBmb2N1cyBmcm9tIHRleHRhcmVhLiAqLwogICAgICAgIGRvbS5vYnNlcnZlKGVsZW1lbnQsICJrZXlkb3duIiwgZnVuY3Rpb24gKGV2ZW50KSB7CgogICAgICAgICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PSB3eXNpaHRtbDUuVEFCX0tFWSkgewogICAgICAgICAgICAgICAgdGhhdC5jb21tYW5kcy5leGVjLmNhbGwodGhhdC5jb21tYW5kcywgImluc2VydFRleHQiLCAnXHQnKTsKICAgICAgICAgICAgICAgIC8qIEZvciBoYW5kbGluZyBJRSAqLwogICAgICAgICAgICAgICAgaWYgKHd5c2lodG1sNS5icm93c2VyLmhhc0lmcmFtZUZvY3VzSXNzdWUoKSkgewogICAgICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSB0aGF0LnNlbGVjdGlvbiA/IHRoYXQuc2VsZWN0aW9uLmdldFNlbGVjdGVkTm9kZSgpIDogbnVsbDsKICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnQgPSB0YXJnZXQucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudCAmJiBwYXJlbnQuc3R5bGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5zdHlsZS53aGl0ZVNwYWNlID0gInByZSI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQuc2V0QXR0cmlidXRlKCJzdHlsZSIsICJ3aGl0ZS1zcGFjZTogcHJlIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIC8vIC0tLS0tLS0tLSBNYWtlIHN1cmUgdGhhdCB3aGVuIHByZXNzaW5nIGJhY2tzcGFjZS9kZWxldGUgb24gc2VsZWN0ZWQgaW1hZ2VzIGRlbGV0ZXMgdGhlIGltYWdlIGFuZCBpdCdzIGFuY2hvciAtLS0tLS0tLS0KICAgICAgICBkb20ub2JzZXJ2ZShlbGVtZW50LCAia2V5ZG93biIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICB2YXIgdGFyZ2V0ID0gdGhhdC5zZWxlY3Rpb24uZ2V0U2VsZWN0ZWROb2RlKHRydWUpLAogICAgICAgICAgICAgICAga2V5Q29kZSA9IGV2ZW50LmtleUNvZGUsCiAgICAgICAgICAgICAgICBwYXJlbnQ7CiAgICAgICAgICAgIGlmICh0YXJnZXQgJiYgKGtleUNvZGUgPT09IHd5c2lodG1sNS5CQUNLU1BBQ0VfS0VZIHx8IGtleUNvZGUgPT09IHd5c2lodG1sNS5ERUxFVEVfS0VZKSkgey8vIDggPT4gYmFja3NwYWNlLCA0NiA9PiBkZWxldGUKICAgICAgICAgICAgICAgIHZhciBub2RlTmFtZXMgPSBbXTsKICAgICAgICAgICAgICAgIC8qIERlbGV0ZSBjb25maWd1cmVkIHRleHQgbm9kZXMgYXMgdGhleSBhcmUgbm90IGVkaXRhYmxlIGFuZCB3b24ndCBiZSBkZWxldGVkICovCiAgICAgICAgICAgICAgICBpZiAodGhhdC5jb25maWcucGFyc2VyUnVsZXMgJiYgdGhhdC5jb25maWcucGFyc2VyUnVsZXMudGV4dE5vZGVzKSB7CiAgICAgICAgICAgICAgICAgICAgbm9kZU5hbWVzID0gdGhhdC5jb25maWcucGFyc2VyUnVsZXMudGV4dE5vZGVzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbm9kZU5hbWVzLnB1c2goIklNRyIpOwogICAgICAgICAgICAgICAgaWYgKG5vZGVOYW1lcy5pbmRleE9mKHRhcmdldC5ub2RlTmFtZSkgPiAtMSkgewogICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IHRhcmdldC5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZCh0YXJnZXQpOwogICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQubm9kZU5hbWUgPT09ICJJTUciKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCBpdCdzIHBhcmVudCA8YT4gdG9vIGlmIGl0IGhhc24ndCBnb3QgYW55IG90aGVyIGNoaWxkIG5vZGVzCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnQubm9kZU5hbWUgPT09ICJBIiAmJiAhcGFyZW50LmZpcnN0Q2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHBhcmVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3lzaWh0bWw1LnF1aXJrcy5yZWRyYXcoZWxlbWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0sIDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIC8vIC0tLS0tLS0tLSBJRSA4KzkgZm9jdXMgdGhlIGVkaXRvciB3aGVuIHRoZSBpZnJhbWUgaXMgY2xpY2tlZCAod2l0aG91dCBhY3R1YWxseSBmaXJpbmcgdGhlICdmb2N1cycgZXZlbnQgb24gdGhlIDxib2R5PikgLS0tLS0tLS0tCiAgICAgICAgaWYgKGJyb3dzZXIuaGFzSWZyYW1lRm9jdXNJc3N1ZSgpKSB7CiAgICAgICAgICAgIGRvbS5vYnNlcnZlKHRoaXMuY29udGFpbmVyLCAiZm9jdXMiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5kb2MucXVlcnlTZWxlY3RvcigiOmZvY3VzIikgIT09IHRoYXQuZWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmZvY3VzKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgZG9tLm9ic2VydmUodGhpcy5lbGVtZW50LCAiYmx1ciIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHRoYXQuc2VsZWN0aW9uLmdldFNlbGVjdGlvbigpLnJlbW92ZUFsbFJhbmdlcygpOwogICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLy8gLS0tLS0tLS0tIFNob3cgdXJsIGluIHRvb2x0aXAgd2hlbiBob3ZlcmluZyBsaW5rcyBvciBpbWFnZXMgLS0tLS0tLS0tCiAgICAgICAgdmFyIHRpdGxlUHJlZml4ZXMgPSB7CiAgICAgICAgICAgIElNRyA6ICJJbWFnZTogIiwKICAgICAgICAgICAgQSA6ICJMaW5rOiAiCiAgICAgICAgfTsKCiAgICAgICAgZG9tLm9ic2VydmUoZWxlbWVudCwgIm1vdXNlb3ZlciIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICB2YXIgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0LAogICAgICAgICAgICAgICAgbm9kZU5hbWUgPSB0YXJnZXQubm9kZU5hbWUsCiAgICAgICAgICAgICAgICB0aXRsZTsKICAgICAgICAgICAgaWYgKG5vZGVOYW1lICE9PSAiQSIgJiYgbm9kZU5hbWUgIT09ICJJTUciKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGhhc1RpdGxlID0gdGFyZ2V0Lmhhc0F0dHJpYnV0ZSgidGl0bGUiKTsKICAgICAgICAgICAgaWYgKCFoYXNUaXRsZSkgewogICAgICAgICAgICAgICAgdGl0bGUgPSB0aXRsZVByZWZpeGVzW25vZGVOYW1lXSArICh0YXJnZXQuZ2V0QXR0cmlidXRlKCJocmVmIikgfHwgdGFyZ2V0LmdldEF0dHJpYnV0ZSgic3JjIikpOwogICAgICAgICAgICAgICAgdGFyZ2V0LnNldEF0dHJpYnV0ZSgidGl0bGUiLCB0aXRsZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBDbGFzcyB0aGF0IHRha2VzIGNhcmUgdGhhdCB0aGUgdmFsdWUgb2YgdGhlIGNvbXBvc2VyIGFuZCB0aGUgdGV4dGFyZWEgaXMgYWx3YXlzIGluIHN5bmMKICovCihmdW5jdGlvbiAod3lzaWh0bWw1KSB7CiAgICB2YXIgSU5URVJWQUwgPSA0MDA7CgogICAgd3lzaWh0bWw1LnZpZXdzLlN5bmNocm9uaXplciA9IEJhc2UuZXh0ZW5kKAogICAgICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LnZpZXdzLlN5bmNocm9uaXplci5wcm90b3R5cGUgKi8gewoKICAgICAgICAgICAgY29uc3RydWN0b3IgOiBmdW5jdGlvbiAoZWRpdG9yLCB0ZXh0YXJlYSwgY29tcG9zZXIpIHsKICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yID0gZWRpdG9yOwogICAgICAgICAgICAgICAgdGhpcy50ZXh0YXJlYSA9IHRleHRhcmVhOwogICAgICAgICAgICAgICAgdGhpcy5jb21wb3NlciA9IGNvbXBvc2VyOwoKICAgICAgICAgICAgICAgIHRoaXMuX29ic2VydmUoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBTeW5jIGh0bWwgZnJvbSBjb21wb3NlciB0byB0ZXh0YXJlYQogICAgICAgICAgICAgKiBUYWtlcyBjYXJlIG9mIHBsYWNlaG9sZGVycwogICAgICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHNob3VsZFBhcnNlSHRtbCBXaGV0aGVyIHRoZSBodG1sIHNob3VsZCBiZSBzYW5pdGl6ZWQgYmVmb3JlIGluc2VydGluZyBpdCBpbnRvIHRoZSB0ZXh0YXJlYQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZnJvbUNvbXBvc2VyVG9UZXh0YXJlYSA6IGZ1bmN0aW9uIChzaG91bGRQYXJzZUh0bWwpIHsKICAgICAgICAgICAgICAgIHRoaXMudGV4dGFyZWEuc2V0VmFsdWUod3lzaWh0bWw1Lmxhbmcuc3RyaW5nKHRoaXMuY29tcG9zZXIuZ2V0VmFsdWUoKSkudHJpbSgpLCBzaG91bGRQYXJzZUh0bWwpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFN5bmMgdmFsdWUgb2YgdGV4dGFyZWEgdG8gY29tcG9zZXIKICAgICAgICAgICAgICogVGFrZXMgY2FyZSBvZiBwbGFjZWhvbGRlcnMKICAgICAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSBzaG91bGRQYXJzZUh0bWwgV2hldGhlciB0aGUgaHRtbCBzaG91bGQgYmUgc2FuaXRpemVkIGJlZm9yZSBpbnNlcnRpbmcgaXQgaW50byB0aGUgY29tcG9zZXIKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZyb21UZXh0YXJlYVRvQ29tcG9zZXIgOiBmdW5jdGlvbiAoc2hvdWxkUGFyc2VIdG1sKSB7CiAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFWYWx1ZSA9IHRoaXMudGV4dGFyZWEuZ2V0VmFsdWUoKTsKICAgICAgICAgICAgICAgIGlmICh0ZXh0YXJlYVZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wb3Nlci5zZXRWYWx1ZSh0ZXh0YXJlYVZhbHVlLCBzaG91bGRQYXJzZUh0bWwpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyLmNsZWFyKCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZGl0b3IuZmlyZSgic2V0X3BsYWNlaG9sZGVyIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogSW52b2tlIHN5bmNpbmcgYmFzZWQgb24gdmlldyBzdGF0ZQogICAgICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHNob3VsZFBhcnNlSHRtbCBXaGV0aGVyIHRoZSBodG1sIHNob3VsZCBiZSBzYW5pdGl6ZWQgYmVmb3JlIGluc2VydGluZyBpdCBpbnRvIHRoZSBjb21wb3Nlci90ZXh0YXJlYQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3luYyA6IGZ1bmN0aW9uIChzaG91bGRQYXJzZUh0bWwpIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmVkaXRvci5jdXJyZW50Vmlldy5uYW1lID09PSAidGV4dGFyZWEiKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5mcm9tVGV4dGFyZWFUb0NvbXBvc2VyKHNob3VsZFBhcnNlSHRtbCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZnJvbUNvbXBvc2VyVG9UZXh0YXJlYShzaG91bGRQYXJzZUh0bWwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGludGVydmFsLWJhc2VkIHN5bmNpbmcKICAgICAgICAgICAgICogYWxzbyBtYWtlcyBzdXJlIHRoYXQgb24tc3VibWl0IHRoZSBjb21wb3NlcidzIGNvbnRlbnQgaXMgc3luY2VkIHdpdGggdGhlIHRleHRhcmVhCiAgICAgICAgICAgICAqIGltbWVkaWF0ZWx5IHdoZW4gdGhlIGZvcm0gZ2V0cyBzdWJtaXR0ZWQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIF9vYnNlcnZlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIGludGVydmFsLAogICAgICAgICAgICAgICAgICAgIHRoYXQgPSB0aGlzLAogICAgICAgICAgICAgICAgICAgIGZvcm0gPSB0aGlzLnRleHRhcmVhLmVsZW1lbnQuZm9ybSwKICAgICAgICAgICAgICAgICAgICBzdGFydEludGVydmFsID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZnJvbUNvbXBvc2VyVG9UZXh0YXJlYSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9LCBJTlRFUlZBTCk7CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBzdG9wSW50ZXJ2YWwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpOwogICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICBzdGFydEludGVydmFsKCk7CgogICAgICAgICAgICAgICAgaWYgKGZvcm0pIHsKICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdGV4dGFyZWEgaXMgaW4gYSBmb3JtIG1ha2Ugc3VyZSB0aGF0IGFmdGVyIG9ucmVzZXQgYW5kIG9uc3VibWl0IHRoZSBjb21wb3NlcgogICAgICAgICAgICAgICAgICAgIC8vIGhhcyB0aGUgY29ycmVjdCBzdGF0ZQogICAgICAgICAgICAgICAgICAgIHd5c2lodG1sNS5kb20ub2JzZXJ2ZShmb3JtLCAic3VibWl0IiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnN5bmModHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5vYnNlcnZlKGZvcm0sICJyZXNldCIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmZyb21UZXh0YXJlYVRvQ29tcG9zZXIoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5lZGl0b3Iub24oImNoYW5nZV92aWV3IiwgZnVuY3Rpb24gKHZpZXcpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodmlldyA9PT0gImNvbXBvc2VyIiAmJiAhaW50ZXJ2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5mcm9tVGV4dGFyZWFUb0NvbXBvc2VyKHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICBzdGFydEludGVydmFsKCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh2aWV3ID09PSAidGV4dGFyZWEiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZnJvbUNvbXBvc2VyVG9UZXh0YXJlYSh0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3RvcEludGVydmFsKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgdGhpcy5lZGl0b3Iub24oImRlc3Ryb3k6Y29tcG9zZXIiLCBzdG9wSW50ZXJ2YWwpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7Cnd5c2lodG1sNS52aWV3cy5UZXh0YXJlYSA9IHd5c2lodG1sNS52aWV3cy5WaWV3LmV4dGVuZCgKICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LnZpZXdzLlRleHRhcmVhLnByb3RvdHlwZSAqLyB7CiAgICAgICAgbmFtZSA6ICJ0ZXh0YXJlYSIsCgogICAgICAgIGNvbnN0cnVjdG9yIDogZnVuY3Rpb24gKHBhcmVudCwgdGV4dGFyZWFFbGVtZW50LCBjb25maWcpIHsKICAgICAgICAgICAgdGhpcy5iYXNlKHBhcmVudCwgdGV4dGFyZWFFbGVtZW50LCBjb25maWcpOwoKICAgICAgICAgICAgdGhpcy5fb2JzZXJ2ZSgpOwogICAgICAgIH0sCgogICAgICAgIGNsZWFyIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLmVsZW1lbnQudmFsdWUgPSAiIjsKICAgICAgICB9LAoKICAgICAgICBnZXRWYWx1ZSA6IGZ1bmN0aW9uIChwYXJzZSkgewogICAgICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLmlzRW1wdHkoKSA/ICIiIDogdGhpcy5lbGVtZW50LnZhbHVlOwogICAgICAgICAgICBpZiAocGFyc2UgJiYgdmFsdWUpIHsKICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5wYXJlbnQucGFyc2UodmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9LAoKICAgICAgICBzZXRWYWx1ZSA6IGZ1bmN0aW9uIChodG1sLCBwYXJzZSkgewogICAgICAgICAgICBpZiAocGFyc2UpIHsKICAgICAgICAgICAgICAgIGh0bWwgPSB0aGlzLnBhcmVudC5wYXJzZShodG1sKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLmVsZW1lbnQudmFsdWUgPSBodG1sOwogICAgICAgIH0sCgogICAgICAgIGhhc1BsYWNlaG9sZGVyU2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgc3VwcG9ydHNQbGFjZWhvbGRlciA9IHd5c2lodG1sNS5icm93c2VyLnN1cHBvcnRzUGxhY2Vob2xkZXJBdHRyaWJ1dGVPbih0aGlzLmVsZW1lbnQpLAogICAgICAgICAgICAgICAgcGxhY2Vob2xkZXJUZXh0ID0gdGhpcy5lbGVtZW50LmdldEF0dHJpYnV0ZSgicGxhY2Vob2xkZXIiKSB8fCBudWxsLAogICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLmVsZW1lbnQudmFsdWUsCiAgICAgICAgICAgICAgICBpc0VtcHR5ID0gIXZhbHVlOwogICAgICAgICAgICByZXR1cm4gKHN1cHBvcnRzUGxhY2Vob2xkZXIgJiYgaXNFbXB0eSkgfHwgKHZhbHVlID09PSBwbGFjZWhvbGRlclRleHQpOwogICAgICAgIH0sCgogICAgICAgIGlzRW1wdHkgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAhdGhpcy5lbGVtZW50LnZhbHVlIHx8ICF3eXNpaHRtbDUubGFuZy5zdHJpbmcodGhpcy5lbGVtZW50LnZhbHVlKS50cmltKCkgfHwgdGhpcy5oYXNQbGFjZWhvbGRlclNldCgpOwogICAgICAgIH0sCgogICAgICAgIF9vYnNlcnZlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgZWxlbWVudCA9IHRoaXMuZWxlbWVudCwKICAgICAgICAgICAgICAgIHBhcmVudCA9IHRoaXMucGFyZW50LAogICAgICAgICAgICAgICAgZXZlbnRNYXBwaW5nID0gewogICAgICAgICAgICAgICAgICAgIGZvY3VzaW4gOiAiZm9jdXMiLAogICAgICAgICAgICAgICAgICAgIGZvY3Vzb3V0IDogImJsdXIiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAgICAgKiBDYWxsaW5nIGZvY3VzKCkgb3IgYmx1cigpIG9uIGFuIGVsZW1lbnQgZG9lc24ndCBzeW5jaHJvbm91c2x5IHRyaWdnZXIgdGhlIGF0dGFjaGVkIGZvY3VzL2JsdXIgZXZlbnRzCiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIHRoZSBjYXNlIGZvciBmb2N1c2luIGFuZCBmb2N1c291dCwgc28gbGV0J3MgdXNlIHRoZW0gd2hlbmV2ZXIgcG9zc2libGUsIGtrdGh4YmFpCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGV2ZW50cyA9IHd5c2lodG1sNS5icm93c2VyLnN1cHBvcnRzRXZlbnQoImZvY3VzaW4iKSA/IFsiZm9jdXNpbiIsICJmb2N1c291dCIsICJjaGFuZ2UiXSA6IFsiZm9jdXMiLCAiYmx1ciIsICJjaGFuZ2UiXTsKCiAgICAgICAgICAgIHBhcmVudC5vbigiYmVmb3JlbG9hZCIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHd5c2lodG1sNS5kb20ub2JzZXJ2ZShlbGVtZW50LCBldmVudHMsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgIHZhciBldmVudE5hbWUgPSBldmVudE1hcHBpbmdbZXZlbnQudHlwZV0gfHwgZXZlbnQudHlwZTsKICAgICAgICAgICAgICAgICAgICBwYXJlbnQuZmlyZShldmVudE5hbWUpLmZpcmUoZXZlbnROYW1lICsgIjp0ZXh0YXJlYSIpOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5vYnNlcnZlKGVsZW1lbnQsIFsicGFzdGUiLCAiZHJvcCJdLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5maXJlKCJwYXN0ZSIpLmZpcmUoInBhc3RlOnRleHRhcmVhIik7CiAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfSk7Ci8qKgogKiBUb29sYmFyIERpYWxvZwogKgogKiBAcGFyYW0ge0VsZW1lbnR9IGxpbmsgVGhlIHRvb2xiYXIgbGluayB3aGljaCBjYXVzZXMgdGhlIGRpYWxvZyB0byBzaG93IHVwCiAqIEBwYXJhbSB7RWxlbWVudH0gY29udGFpbmVyIFRoZSBkaWFsb2cgY29udGFpbmVyCiAqCiAqIEBleGFtcGxlCiAqICAgIDwhLS0gVG9vbGJhciBsaW5rIC0tPgogKiAgICA8YSBkYXRhLXd5c2lodG1sNS1jb21tYW5kPSJpbnNlcnRJbWFnZSI+aW5zZXJ0IGFuIGltYWdlPC9hPgogKgogKiAgICA8IS0tIERpYWxvZyAtLT4KICogICAgPGRpdiBkYXRhLXd5c2lodG1sNS1kaWFsb2c9Imluc2VydEltYWdlIiBzdHlsZT0iZGlzcGxheTogbm9uZTsiPgogKiAgICAgIDxsYWJlbD4KICogICAgICAgIFVSTDogPGlucHV0IGRhdGEtd3lzaWh0bWw1LWRpYWxvZy1maWVsZD0ic3JjIiB2YWx1ZT0iaHR0cDovLyI+CiAqICAgICAgPC9sYWJlbD4KICogICAgICA8bGFiZWw+CiAqICAgICAgICBBbHRlcm5hdGl2ZSB0ZXh0OiA8aW5wdXQgZGF0YS13eXNpaHRtbDUtZGlhbG9nLWZpZWxkPSJhbHQiIHZhbHVlPSIiPgogKiAgICAgIDwvbGFiZWw+CiAqICAgIDwvZGl2PgogKgogKiAgICA8c2NyaXB0PgogKiAgICAgIHZhciBkaWFsb2cgPSBuZXcgd3lzaWh0bWw1LnRvb2xiYXIuRGlhbG9nKAogKiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiW2RhdGEtd3lzaWh0bWw1LWNvbW1hbmQ9J2luc2VydEltYWdlJ10iKSwKICogICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIltkYXRhLXd5c2lodG1sNS1kaWFsb2c9J2luc2VydEltYWdlJ10iKQogKiAgICAgICk7CiAqICAgICAgZGlhbG9nLm9ic2VydmUoInNhdmUiLCBmdW5jdGlvbihhdHRyaWJ1dGVzKSB7CiAqICAgICAgICAvLyBkbyBzb21ldGhpbmcKICogICAgICB9KTsKICogICAgPC9zY3JpcHQ+CiAqLwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgdmFyIGRvbSA9IHd5c2lodG1sNS5kb20sCiAgICAgICAgQ0xBU1NfTkFNRV9PUEVORUQgPSAid3lzaWh0bWw1LWNvbW1hbmQtZGlhbG9nLW9wZW5lZCIsCiAgICAgICAgU0VMRUNUT1JfRk9STV9FTEVNRU5UUyA9ICJpbnB1dCwgc2VsZWN0LCB0ZXh0YXJlYSIsCiAgICAgICAgU0VMRUNUT1JfRklFTERTID0gIltkYXRhLXd5c2lodG1sNS1kaWFsb2ctZmllbGRdIiwKICAgICAgICBBVFRSSUJVVEVfRklFTERTID0gImRhdGEtd3lzaWh0bWw1LWRpYWxvZy1maWVsZCI7CgogICAgd3lzaWh0bWw1LnRvb2xiYXIuRGlhbG9nID0gd3lzaWh0bWw1LmxhbmcuRGlzcGF0Y2hlci5leHRlbmQoCiAgICAgICAgLyoqIEBzY29wZSB3eXNpaHRtbDUudG9vbGJhci5EaWFsb2cucHJvdG90eXBlICovIHsKICAgICAgICAgICAgY29uc3RydWN0b3IgOiBmdW5jdGlvbiAobGluaywgY29udGFpbmVyKSB7CiAgICAgICAgICAgICAgICB0aGlzLmxpbmsgPSBsaW5rOwogICAgICAgICAgICAgICAgdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfb2JzZXJ2ZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9vYnNlcnZlZCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsCiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tXcmFwcGVyID0gZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0gdGhhdC5fc2VyaWFsaXplKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVzID09IHRoYXQuZWxlbWVudFRvQ2hhbmdlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmZpcmUoImVkaXQiLCBhdHRyaWJ1dGVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZmlyZSgic2F2ZSIsIGF0dHJpYnV0ZXMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuaGlkZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIGRvbS5vYnNlcnZlKHRoYXQubGluaywgImNsaWNrIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIGlmIChkb20uaGFzQ2xhc3ModGhhdC5saW5rLCBDTEFTU19OQU1FX09QRU5FRCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmhpZGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgZG9tLm9ic2VydmUodGhpcy5jb250YWluZXIsICJrZXlkb3duIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGtleUNvZGUgPSBldmVudC5rZXlDb2RlOwogICAgICAgICAgICAgICAgICAgIGlmIChrZXlDb2RlID09PSB3eXNpaHRtbDUuRU5URVJfS0VZKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrV3JhcHBlcihldmVudCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChrZXlDb2RlID09PSB3eXNpaHRtbDUuRVNDQVBFX0tFWSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmhpZGUoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICBkb20uZGVsZWdhdGUodGhpcy5jb250YWluZXIsICJbZGF0YS13eXNpaHRtbDUtZGlhbG9nLWFjdGlvbj1zYXZlXSIsICJjbGljayIsIGNhbGxiYWNrV3JhcHBlcik7CgogICAgICAgICAgICAgICAgZG9tLmRlbGVnYXRlKHRoaXMuY29udGFpbmVyLCAiW2RhdGEtd3lzaWh0bWw1LWRpYWxvZy1hY3Rpb249Y2FuY2VsXSIsICJjbGljayIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgIHRoYXQuZmlyZSgiY2FuY2VsIik7CiAgICAgICAgICAgICAgICAgICAgdGhhdC5oaWRlKCk7CiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIHZhciBmb3JtRWxlbWVudHMgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFNFTEVDVE9SX0ZPUk1fRUxFTUVOVFMpLAogICAgICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IGZvcm1FbGVtZW50cy5sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgX2NsZWFySW50ZXJ2YWwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhhdC5pbnRlcnZhbCk7CiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIGZvciAoOwogICAgICAgICAgICAgICAgICAgIGkgPCBsZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgZG9tLm9ic2VydmUoZm9ybUVsZW1lbnRzW2ldLCAiY2hhbmdlIiwgX2NsZWFySW50ZXJ2YWwpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRoaXMuX29ic2VydmVkID0gdHJ1ZTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBHcmFicyBhbGwgZmllbGRzIGluIHRoZSBkaWFsb2cgYW5kIHB1dHMgdGhlbSBpbiBrZXk9PnZhbHVlIHN0eWxlIGluIGFuIG9iamVjdCB3aGljaAogICAgICAgICAgICAgKiB0aGVuIGdldHMgcmV0dXJuZWQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIF9zZXJpYWxpemUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuZWxlbWVudFRvQ2hhbmdlIHx8IHt9LAogICAgICAgICAgICAgICAgICAgIGZpZWxkcyA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoU0VMRUNUT1JfRklFTERTKSwKICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSBmaWVsZHMubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgIGkgPSAwOwogICAgICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgICAgICBkYXRhW2ZpZWxkc1tpXS5nZXRBdHRyaWJ1dGUoQVRUUklCVVRFX0ZJRUxEUyldID0gZmllbGRzW2ldLnZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGRhdGE7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogVGFrZXMgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlICJlbGVtZW50VG9DaGFuZ2UiCiAgICAgICAgICAgICAqIGFuZCBpbnNlcnRzIHRoZW0gaW4gdGhlaXIgY29ycmVzcG9uZGluZyBkaWFsb2cgaW5wdXQgZmllbGRzCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEFzc3VtZSB0aGUgImVsZW1lbnRUb0NoYW5nZSIgbG9va3MgbGlrZSB0aGlzOgogICAgICAgICAgICAgKiAgICA8YSBocmVmPSJodHRwOi8vd3d3Lmdvb2dsZS5jb20iIHRhcmdldD0iX2JsYW5rIj5mb288L2E+CiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIGFuZCB3ZSBoYXZlIHRoZSBmb2xsb3dpbmcgZGlhbG9nOgogICAgICAgICAgICAgKiAgICA8aW5wdXQgdHlwZT0idGV4dCIgZGF0YS13eXNpaHRtbDUtZGlhbG9nLWZpZWxkPSJocmVmIiB2YWx1ZT0iIj4KICAgICAgICAgICAgICogICAgPGlucHV0IHR5cGU9InRleHQiIGRhdGEtd3lzaWh0bWw1LWRpYWxvZy1maWVsZD0idGFyZ2V0IiB2YWx1ZT0iIj4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogYWZ0ZXIgY2FsbGluZyBfaW50ZXJwb2xhdGUoKSB0aGUgZGlhbG9nIHdpbGwgbG9vayBsaWtlIHRoaXMKICAgICAgICAgICAgICogICAgPGlucHV0IHR5cGU9InRleHQiIGRhdGEtd3lzaWh0bWw1LWRpYWxvZy1maWVsZD0iaHJlZiIgdmFsdWU9Imh0dHA6Ly93d3cuZ29vZ2xlLmNvbSI+CiAgICAgICAgICAgICAqICAgIDxpbnB1dCB0eXBlPSJ0ZXh0IiBkYXRhLXd5c2lodG1sNS1kaWFsb2ctZmllbGQ9InRhcmdldCIgdmFsdWU9Il9ibGFuayI+CiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEJhc2ljYWxseSBpdCBhZG9wdGVkIHRoZSBhdHRyaWJ1dGUgdmFsdWVzIGludG8gdGhlIGNvcnJlc3BvbmRpbmcgaW5wdXQgZmllbGRzCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBfaW50ZXJwb2xhdGUgOiBmdW5jdGlvbiAoYXZvaWRIaWRkZW5GaWVsZHMpIHsKICAgICAgICAgICAgICAgIHZhciBmaWVsZCwKICAgICAgICAgICAgICAgICAgICBmaWVsZE5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgZm9jdXNlZEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCI6Zm9jdXMiKSwKICAgICAgICAgICAgICAgICAgICBmaWVsZHMgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKFNFTEVDVE9SX0ZJRUxEUyksCiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID0gZmllbGRzLmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICBpID0gMDsKICAgICAgICAgICAgICAgIGZvciAoOwogICAgICAgICAgICAgICAgICAgIGkgPCBsZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgZmllbGQgPSBmaWVsZHNbaV07CgogICAgICAgICAgICAgICAgICAgIC8vIE5ldmVyIGNoYW5nZSBlbGVtZW50cyB3aGVyZSB0aGUgdXNlciBpcyBjdXJyZW50bHkgdHlwaW5nIGluCiAgICAgICAgICAgICAgICAgICAgaWYgKGZpZWxkID09PSBmb2N1c2VkRWxlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIERvbid0IHVwZGF0ZSBoaWRkZW4gZmllbGRzCiAgICAgICAgICAgICAgICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS94aW5nL3d5c2lodG1sNS9wdWxsLzE0CiAgICAgICAgICAgICAgICAgICAgaWYgKGF2b2lkSGlkZGVuRmllbGRzICYmIGZpZWxkLnR5cGUgPT09ICJoaWRkZW4iKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgZmllbGROYW1lID0gZmllbGQuZ2V0QXR0cmlidXRlKEFUVFJJQlVURV9GSUVMRFMpOwogICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlID0gdGhpcy5lbGVtZW50VG9DaGFuZ2UgPyAodGhpcy5lbGVtZW50VG9DaGFuZ2VbZmllbGROYW1lXSB8fCAiIikgOiBmaWVsZC5kZWZhdWx0VmFsdWU7CiAgICAgICAgICAgICAgICAgICAgZmllbGQudmFsdWUgPSBuZXdWYWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBTaG93IHRoZSBkaWFsb2cgZWxlbWVudAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2hvdyA6IGZ1bmN0aW9uIChlbGVtZW50VG9DaGFuZ2UpIHsKICAgICAgICAgICAgICAgIGlmIChkb20uaGFzQ2xhc3ModGhpcy5saW5rLCBDTEFTU19OQU1FX09QRU5FRCkpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzLAogICAgICAgICAgICAgICAgICAgIGZpcnN0RmllbGQgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKFNFTEVDVE9SX0ZPUk1fRUxFTUVOVFMpOwogICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50VG9DaGFuZ2UgPSBlbGVtZW50VG9DaGFuZ2U7CiAgICAgICAgICAgICAgICB0aGlzLl9vYnNlcnZlKCk7CiAgICAgICAgICAgICAgICB0aGlzLl9pbnRlcnBvbGF0ZSgpOwogICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRUb0NoYW5nZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuaW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX2ludGVycG9sYXRlKHRydWUpOwogICAgICAgICAgICAgICAgICAgIH0sIDUwMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkb20uYWRkQ2xhc3ModGhpcy5saW5rLCBDTEFTU19OQU1FX09QRU5FRCk7CiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gIiI7CiAgICAgICAgICAgICAgICB0aGlzLmZpcmUoInNob3ciKTsKICAgICAgICAgICAgICAgIGlmIChmaXJzdEZpZWxkICYmICFlbGVtZW50VG9DaGFuZ2UpIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICBmaXJzdEZpZWxkLmZvY3VzKCk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBIaWRlIHRoZSBkaWFsb2cgZWxlbWVudAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaGlkZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5pbnRlcnZhbCk7CiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnRUb0NoYW5nZSA9IG51bGw7CiAgICAgICAgICAgICAgICBkb20ucmVtb3ZlQ2xhc3ModGhpcy5saW5rLCBDTEFTU19OQU1FX09QRU5FRCk7CiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgICAgICAgICAgdGhpcy5maXJlKCJoaWRlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKfSkod3lzaWh0bWw1KTsKLyoqCiAqIENvbnZlcnRzIHNwZWVjaC10by10ZXh0IGFuZCBpbnNlcnRzIHRoaXMgaW50byB0aGUgZWRpdG9yCiAqIEFzIG9mIG5vdyAoMjAxMS8wMy8yNSkgdGhpcyBvbmx5IGlzIHN1cHBvcnRlZCBpbiBDaHJvbWUgPj0gMTEKICoKICogTm90ZSB0aGF0IGl0IHNlbmRzIHRoZSByZWNvcmRlZCBhdWRpbyB0byB0aGUgZ29vZ2xlIHNwZWVjaCByZWNvZ25pdGlvbiBhcGk6CiAqIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDM2MTgyNi9kb2VzLWNocm9tZS1oYXZlLWJ1aWwtaW4tc3BlZWNoLXJlY29nbml0aW9uLWZvci1pbnB1dC10eXBlLXRleHQteC13ZWJraXQtc3BlZWMKICoKICogQ3VycmVudCBIVE1MNSBkcmFmdCBjYW4gYmUgZm91bmQgaGVyZQogKiBodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy9wdWJsaWMteGctaHRtbHNwZWVjaC8yMDExRmViL2F0dC0wMDIwL2FwaS1kcmFmdC5odG1sCiAqCiAqICJBY2Nlc3NpbmcgR29vZ2xlIFNwZWVjaCBBUEkgQ2hyb21lIDExIgogKiBodHRwOi8vbWlrZXB1bHR6LmNvbS8yMDExLzAzL2FjY2Vzc2luZy1nb29nbGUtc3BlZWNoLWFwaS1jaHJvbWUtMTEvCiAqLwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgdmFyIGRvbSA9IHd5c2lodG1sNS5kb207CgogICAgdmFyIGxpbmtTdHlsZXMgPSB7CiAgICAgICAgcG9zaXRpb24gOiAicmVsYXRpdmUiCiAgICB9OwoKICAgIHZhciB3cmFwcGVyU3R5bGVzID0gewogICAgICAgIGxlZnQgOiAwLAogICAgICAgIG1hcmdpbiA6IDAsCiAgICAgICAgb3BhY2l0eSA6IDAsCiAgICAgICAgb3ZlcmZsb3cgOiAiaGlkZGVuIiwKICAgICAgICBwYWRkaW5nIDogMCwKICAgICAgICBwb3NpdGlvbiA6ICJhYnNvbHV0ZSIsCiAgICAgICAgdG9wIDogMCwKICAgICAgICB6SW5kZXggOiAxCiAgICB9OwoKICAgIHZhciBpbnB1dFN0eWxlcyA9IHsKICAgICAgICBjdXJzb3IgOiAiaW5oZXJpdCIsCiAgICAgICAgZm9udFNpemUgOiAiNTBweCIsCiAgICAgICAgaGVpZ2h0IDogIjUwcHgiLAogICAgICAgIG1hcmdpblRvcCA6ICItMjVweCIsCiAgICAgICAgb3V0bGluZSA6IDAsCiAgICAgICAgcGFkZGluZyA6IDAsCiAgICAgICAgcG9zaXRpb24gOiAiYWJzb2x1dGUiLAogICAgICAgIHJpZ2h0IDogIi00cHgiLAogICAgICAgIHRvcCA6ICI1MCUiCiAgICB9OwoKICAgIHZhciBpbnB1dEF0dHJpYnV0ZXMgPSB7CiAgICAgICAgIngtd2Via2l0LXNwZWVjaCIgOiAiIiwKICAgICAgICAic3BlZWNoIiA6ICIiCiAgICB9OwoKICAgIHd5c2lodG1sNS50b29sYmFyLlNwZWVjaCA9IGZ1bmN0aW9uIChwYXJlbnQsIGxpbmspIHsKICAgICAgICB2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJpbnB1dCIpOwogICAgICAgIGlmICghd3lzaWh0bWw1LmJyb3dzZXIuc3VwcG9ydHNTcGVlY2hBcGlPbihpbnB1dCkpIHsKICAgICAgICAgICAgbGluay5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIHZhciBsYW5nID0gcGFyZW50LmVkaXRvci50ZXh0YXJlYS5lbGVtZW50LmdldEF0dHJpYnV0ZSgibGFuZyIpOwogICAgICAgIGlmIChsYW5nKSB7CiAgICAgICAgICAgIGlucHV0QXR0cmlidXRlcy5sYW5nID0gbGFuZzsKICAgICAgICB9CgogICAgICAgIHZhciB3cmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CgogICAgICAgIHd5c2lodG1sNS5sYW5nLm9iamVjdCh3cmFwcGVyU3R5bGVzKS5tZXJnZSh7CiAgICAgICAgICAgIHdpZHRoIDogbGluay5vZmZzZXRXaWR0aCArICJweCIsCiAgICAgICAgICAgIGhlaWdodCA6IGxpbmsub2Zmc2V0SGVpZ2h0ICsgInB4IgogICAgICAgIH0pOwoKICAgICAgICBkb20uaW5zZXJ0KGlucHV0KS5pbnRvKHdyYXBwZXIpOwogICAgICAgIGRvbS5pbnNlcnQod3JhcHBlcikuaW50byhsaW5rKTsKCiAgICAgICAgZG9tLnNldFN0eWxlcyhpbnB1dFN0eWxlcykub24oaW5wdXQpOwogICAgICAgIGRvbS5zZXRBdHRyaWJ1dGVzKGlucHV0QXR0cmlidXRlcykub24oaW5wdXQpOwoKICAgICAgICBkb20uc2V0U3R5bGVzKHdyYXBwZXJTdHlsZXMpLm9uKHdyYXBwZXIpOwogICAgICAgIGRvbS5zZXRTdHlsZXMobGlua1N0eWxlcykub24obGluayk7CgogICAgICAgIHZhciBldmVudE5hbWUgPSAib253ZWJraXRzcGVlY2hjaGFuZ2UiIGluIGlucHV0ID8gIndlYmtpdHNwZWVjaGNoYW5nZSIgOiAic3BlZWNoY2hhbmdlIjsKICAgICAgICBkb20ub2JzZXJ2ZShpbnB1dCwgZXZlbnROYW1lLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHBhcmVudC5leGVjQ29tbWFuZCgiaW5zZXJ0VGV4dCIsIGlucHV0LnZhbHVlKTsKICAgICAgICAgICAgaW5wdXQudmFsdWUgPSAiIjsKICAgICAgICB9KTsKCiAgICAgICAgZG9tLm9ic2VydmUoaW5wdXQsICJjbGljayIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICBpZiAoZG9tLmhhc0NsYXNzKGxpbmssICJ3eXNpaHRtbDUtY29tbWFuZC1kaXNhYmxlZCIpKSB7CiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgICB9KTsKICAgIH07Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBUb29sYmFyCiAqCiAqIEBwYXJhbSB7T2JqZWN0fSBwYXJlbnQgUmVmZXJlbmNlIHRvIGluc3RhbmNlIG9mIEVkaXRvciBpbnN0YW5jZQogKiBAcGFyYW0ge0VsZW1lbnR9IGNvbnRhaW5lciBSZWZlcmVuY2UgdG8gdGhlIHRvb2xiYXIgY29udGFpbmVyIGVsZW1lbnQKICoKICogQGV4YW1wbGUKICogICAgPGRpdiBpZD0idG9vbGJhciI+CiAqICAgICAgPGEgZGF0YS13eXNpaHRtbDUtY29tbWFuZD0iY3JlYXRlTGluayI+aW5zZXJ0IGxpbms8L2E+CiAqICAgICAgPGEgZGF0YS13eXNpaHRtbDUtY29tbWFuZD0iZm9ybWF0QmxvY2siIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQtdmFsdWU9ImgxIj5pbnNlcnQgaDE8L2E+CiAqICAgIDwvZGl2PgogKgogKiAgICA8c2NyaXB0PgogKiAgICAgIHZhciB0b29sYmFyID0gbmV3IHd5c2lodG1sNS50b29sYmFyLlRvb2xiYXIoZWRpdG9yLCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgidG9vbGJhciIpKTsKICogICAgPC9zY3JpcHQ+CiAqLwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgdmFyIENMQVNTX05BTUVfQ09NTUFORF9ESVNBQkxFRCA9ICJ3eXNpaHRtbDUtY29tbWFuZC1kaXNhYmxlZCIsCiAgICAgICAgQ0xBU1NfTkFNRV9DT01NQU5EU19ESVNBQkxFRCA9ICJ3eXNpaHRtbDUtY29tbWFuZHMtZGlzYWJsZWQiLAogICAgICAgIENMQVNTX05BTUVfQ09NTUFORF9BQ1RJVkUgPSAid3lzaWh0bWw1LWNvbW1hbmQtYWN0aXZlIiwKICAgICAgICBDTEFTU19OQU1FX0FDVElPTl9BQ1RJVkUgPSAid3lzaWh0bWw1LWFjdGlvbi1hY3RpdmUiLAogICAgICAgIGRvbSA9IHd5c2lodG1sNS5kb207CgogICAgd3lzaWh0bWw1LnRvb2xiYXIuVG9vbGJhciA9IEJhc2UuZXh0ZW5kKAogICAgICAgIC8qKiBAc2NvcGUgd3lzaWh0bWw1LnRvb2xiYXIuVG9vbGJhci5wcm90b3R5cGUgKi8gewogICAgICAgICAgICBjb25zdHJ1Y3RvciA6IGZ1bmN0aW9uIChlZGl0b3IsIGNvbnRhaW5lcikgewogICAgICAgICAgICAgICAgdGhpcy5lZGl0b3IgPSBlZGl0b3I7CiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lciA9IHR5cGVvZihjb250YWluZXIpID09PSAic3RyaW5nIiA/IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGNvbnRhaW5lcikgOiBjb250YWluZXI7CiAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyID0gZWRpdG9yLmNvbXBvc2VyOwoKICAgICAgICAgICAgICAgIGlmICghdGhpcy5jb250YWluZXIuY2xhc3NMaXN0LmNvbnRhaW5zKCJ3eXNpaHRtbDUtdG9vbGJhciIpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZ2V0TGlua3MoImNvbW1hbmQiKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9nZXRMaW5rcygiYWN0aW9uIik7CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX29ic2VydmUoKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3coKTsKCiAgICAgICAgICAgICAgICAgICAgdmFyIHNwZWVjaElucHV0TGlua3MgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCJbZGF0YS13eXNpaHRtbDUtY29tbWFuZD1pbnNlcnRTcGVlY2hdIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IHNwZWVjaElucHV0TGlua3MubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICBpID0gMDsKICAgICAgICAgICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgICAgICAgICAgaSA8IGxlbmd0aDsKICAgICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyB3eXNpaHRtbDUudG9vbGJhci5TcGVlY2godGhpcywgc3BlZWNoSW5wdXRMaW5rc1tpXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5jb250YWluZXIuY2xhc3NMaXN0LmFkZCgid3lzaWh0bWw1LXRvb2xiYXIiKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9nZXRMaW5rcyA6IGZ1bmN0aW9uICh0eXBlKSB7CiAgICAgICAgICAgICAgICB2YXIgbGlua3MgPSB0aGlzW3R5cGUgKyAiTGlua3MiXSA9IHd5c2lodG1sNS5sYW5nLmFycmF5KHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoIltkYXRhLXd5c2lodG1sNS0iICsgdHlwZSArICJdIikpLmdldCgpLAogICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IGxpbmtzLmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICBpID0gMCwKICAgICAgICAgICAgICAgICAgICBtYXBwaW5nID0gdGhpc1t0eXBlICsgIk1hcHBpbmciXSA9IHt9LAogICAgICAgICAgICAgICAgICAgIGxpbmssCiAgICAgICAgICAgICAgICAgICAgZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgbmFtZSwKICAgICAgICAgICAgICAgICAgICB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICBkaWFsb2c7CiAgICAgICAgICAgICAgICBmb3IgKDsKICAgICAgICAgICAgICAgICAgICBpIDwgbGVuZ3RoOwogICAgICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgICAgIGxpbmsgPSBsaW5rc1tpXTsKICAgICAgICAgICAgICAgICAgICBuYW1lID0gbGluay5nZXRBdHRyaWJ1dGUoImRhdGEtd3lzaWh0bWw1LSIgKyB0eXBlKTsKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxpbmsuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS0iICsgdHlwZSArICItdmFsdWUiKTsKICAgICAgICAgICAgICAgICAgICBmdW5jID0gbGluay5nZXRBdHRyaWJ1dGUoImRhdGEtd3lzaWh0bWw1LSIgKyB0eXBlICsgIi1zdGF0ZUNhbGxiYWNrRm4iKTsKICAgICAgICAgICAgICAgICAgICBlbGVtZW50TmFtZSA9IGxpbmsuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS0iICsgdHlwZSArICItZWxlbWVudCIpOwogICAgICAgICAgICAgICAgICAgIGlzRGVmYXVsdCA9IGxpbmsuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS0iICsgdHlwZSArICItZGVmYXVsdCIpOwogICAgICAgICAgICAgICAgICAgIGdyb3VwID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvcigiW2RhdGEtd3lzaWh0bWw1LSIgKyB0eXBlICsgIi1ncm91cD0nIiArIG5hbWUgKyAiJ10iKTsKICAgICAgICAgICAgICAgICAgICBkaWFsb2cgPSB0aGlzLl9nZXREaWFsb2cobGluaywgbmFtZSk7CgogICAgICAgICAgICAgICAgICAgIG1hcHBpbmdbbmFtZSArICI6IiArIHZhbHVlXSA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgbGluayA6IGxpbmssCiAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwIDogZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgOiBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICBmdW5jIDogZnVuYywKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudE5hbWUgOiBlbGVtZW50TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgaXNEZWZhdWx0IDogaXNEZWZhdWx0ID09ICIiID8gdHJ1ZSA6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA6IHZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICBkaWFsb2cgOiBkaWFsb2csCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlIDogZmFsc2UKICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgX2dldERpYWxvZyA6IGZ1bmN0aW9uIChsaW5rLCBjb21tYW5kKSB7CiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsCiAgICAgICAgICAgICAgICAgICAgZGlhbG9nRWxlbWVudCA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoIltkYXRhLXd5c2lodG1sNS1kaWFsb2c9JyIgKyBjb21tYW5kICsgIiddIiksCiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLAogICAgICAgICAgICAgICAgICAgIGNhcmV0Qm9va21hcms7CgogICAgICAgICAgICAgICAgaWYgKGRpYWxvZ0VsZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICBkaWFsb2cgPSBuZXcgd3lzaWh0bWw1LnRvb2xiYXIuRGlhbG9nKGxpbmssIGRpYWxvZ0VsZW1lbnQpOwoKICAgICAgICAgICAgICAgICAgICBkaWFsb2cub24oInNob3ciLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhcmV0Qm9va21hcmsgPSB0aGF0LmNvbXBvc2VyLnNlbGVjdGlvbi5nZXRCb29rbWFyaygpOwoKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5lZGl0b3IuZmlyZSgic2hvdzpkaWFsb2ciLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kIDogY29tbWFuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWxvZ0NvbnRhaW5lciA6IGRpYWxvZ0VsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kTGluayA6IGxpbmsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgIGRpYWxvZy5vbigic2F2ZSIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNhcmV0Qm9va21hcmspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuY29tcG9zZXIuc2VsZWN0aW9uLnNldEJvb2ttYXJrKGNhcmV0Qm9va21hcmspOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX2V4ZWNDb21tYW5kKGNvbW1hbmQsIGF0dHJpYnV0ZXMpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmVkaXRvci5maXJlKCJzYXZlOmRpYWxvZyIsIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgOiBjb21tYW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhbG9nQ29udGFpbmVyIDogZGlhbG9nRWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmRMaW5rIDogbGluawogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgZGlhbG9nLm9uKCJzYXZlT25seSIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNhcmV0Qm9va21hcmspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuY29tcG9zZXIuc2VsZWN0aW9uLnNldEJvb2ttYXJrKGNhcmV0Qm9va21hcmspOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgIGRpYWxvZy5vbigiY2FuY2VsIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmVkaXRvci5mb2N1cyhmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZWRpdG9yLmZpcmUoImNhbmNlbDpkaWFsb2ciLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kIDogY29tbWFuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWxvZ0NvbnRhaW5lciA6IGRpYWxvZ0VsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kTGluayA6IGxpbmsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZGlhbG9nOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqICAgIHZhciB0b29sYmFyID0gbmV3IHd5c2lodG1sNS5Ub29sYmFyKCk7CiAgICAgICAgICAgICAqICAgIC8vIEluc2VydCBhIDxibG9ja3F1b3RlPiBlbGVtZW50IG9yIHdyYXAgY3VycmVudCBzZWxlY3Rpb24gaW4gPGJsb2NrcXVvdGU+CiAgICAgICAgICAgICAqICAgIHRvb2xiYXIuZXhlY0NvbW1hbmQoImZvcm1hdEJsb2NrIiwgImJsb2NrcXVvdGUiKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGV4ZWNDb21tYW5kIDogZnVuY3Rpb24gKGNvbW1hbmQsIGNvbW1hbmRWYWx1ZSkgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuY29tbWFuZHNEaXNhYmxlZCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgY29tbWFuZE9iaiA9IHRoaXMuY29tbWFuZE1hcHBpbmdbY29tbWFuZCArICI6IiArIGNvbW1hbmRWYWx1ZV07CgogICAgICAgICAgICAgICAgLy8gU2hvdyBkaWFsb2cgd2hlbiBhdmFpbGFibGUKICAgICAgICAgICAgICAgIGlmIChjb21tYW5kT2JqICYmIGNvbW1hbmRPYmouZGlhbG9nICYmICFjb21tYW5kT2JqLnN0YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgY29tbWFuZE9iai5kaWFsb2cuc2hvdygpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9leGVjQ29tbWFuZChjb21tYW5kLCBjb21tYW5kVmFsdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgX2V4ZWNDb21tYW5kIDogZnVuY3Rpb24gKGNvbW1hbmQsIGNvbW1hbmRWYWx1ZSkgewoKICAgICAgICAgICAgICAgIHRoaXMuY29tcG9zZXIuY29tbWFuZHMuZXhlYyhjb21tYW5kLCBjb21tYW5kVmFsdWUpOwogICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlTGlua1N0YXRlcygpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZXhlY0FjdGlvbiA6IGZ1bmN0aW9uIChhY3Rpb24pIHsKICAgICAgICAgICAgICAgIHZhciBlZGl0b3IgPSB0aGlzLmVkaXRvcjsKICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gPT09ICJjaGFuZ2VfdmlldyIpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZWRpdG9yLmN1cnJlbnRWaWV3ID09PSBlZGl0b3IudGV4dGFyZWEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZWRpdG9yLmZpcmUoImNoYW5nZV92aWV3IiwgImNvbXBvc2VyIik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgZWRpdG9yLmZpcmUoImNoYW5nZV92aWV3IiwgInRleHRhcmVhIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgX29ic2VydmUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXMsCiAgICAgICAgICAgICAgICAgICAgZWRpdG9yID0gdGhpcy5lZGl0b3IsCiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyID0gdGhpcy5jb250YWluZXIsCiAgICAgICAgICAgICAgICAgICAgbGlua3MgPSB0aGlzLmNvbW1hbmRMaW5rcy5jb25jYXQodGhpcy5hY3Rpb25MaW5rcyksCiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID0gbGlua3MubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgIGkgPSAwOwoKICAgICAgICAgICAgICAgIGZvciAoOwogICAgICAgICAgICAgICAgICAgIGkgPCBsZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gJ2phdmFzY3JpcHQ6OycgYW5kIHVuc2VsZWN0YWJsZT1vbiBOZWVkZWQgZm9yIElFLCBidXQgZG9uZSBpbiBhbGwgYnJvd3NlcnMgdG8gbWFrZSBzdXJlIHRoYXQgYWxsIGdldCB0aGUgc2FtZSBjc3MgYXBwbGllZAogICAgICAgICAgICAgICAgICAgIC8vICh5b3Uga25vdywgYTpsaW5rIHsuLi4gfSBkb2Vzbid0IG1hdGNoIGFuY2hvcnMgd2l0aCBtaXNzaW5nIGhyZWYgYXR0cmlidXRlKQogICAgICAgICAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0ge307CiAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlcy5ocmVmID0gImphdmFzY3JpcHQ6OyI7CiAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmtzW2ldICYmICFsaW5rc1tpXS5oYXNBdHRyaWJ1dGUoInVuc2VsZWN0YWJsZSIpICYmIGxpbmtzW2ldLnRhZ05hbWUudG9Mb3dlckNhc2UoKSAhPSAiaW5wdXQiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXMudW5zZWxlY3RhYmxlID0gIm9uIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZG9tLnNldEF0dHJpYnV0ZXMoYXR0cmlidXRlcykub24obGlua3NbaV0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIE5lZWRlZCBmb3Igb3BlcmEgYW5kIGNocm9tZQogICAgICAgICAgICAgICAgZG9tLmRlbGVnYXRlKGNvbnRhaW5lciwgIltkYXRhLXd5c2lodG1sNS1hY3Rpb25dIiwgIm1vdXNlZG93biIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICBkb20uZGVsZWdhdGUoY29udGFpbmVyLCAiW2RhdGEtd3lzaWh0bWw1LWNvbW1hbmRdIiwgIm1vdXNlZG93biIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgIHZhciBsaW5rID0gdGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZCA9IGxpbmsuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS1jb21tYW5kIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmRWYWx1ZSA9IGxpbmsuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS1jb21tYW5kLXZhbHVlIik7CgogICAgICAgICAgICAgICAgICAgIC8vVG8gYWxsb3cgZGVmYXVsdCBhY3Rpb24gaW4gY2FzZSBvZiBtYXJnaW4gZmllbGRzLgogICAgICAgICAgICAgICAgICAgIGlmICghbGluay5oYXNBdHRyaWJ1dGUoImRhdGEtd3lzaWh0bWw1LXNraXAiKSkgewogICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIGRvbS5kZWxlZ2F0ZShjb250YWluZXIsICJbZGF0YS13eXNpaHRtbDUtY29tbWFuZF0iLCAiY2xpY2siLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbGluayA9IHRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSBsaW5rLmdldEF0dHJpYnV0ZSgiZGF0YS13eXNpaHRtbDUtY29tbWFuZCIpLAogICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kVmFsdWUgPSBsaW5rLmdldEF0dHJpYnV0ZSgiZGF0YS13eXNpaHRtbDUtY29tbWFuZC12YWx1ZSIpLAogICAgICAgICAgICAgICAgICAgICAgICBmb3JtID0gbGluay5mb3JtOwogICAgICAgICAgICAgICAgICAgIGlmIChjb21tYW5kVmFsdWUgPT09IG51bGwgJiYgZm9ybSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kVmFsdWUgPSB7fTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvcm1JbnB1dHMgPSBmb3JtLnF1ZXJ5U2VsZWN0b3JBbGwoImlucHV0W25hbWVdLCB0ZXh0YXJlYVtuYW1lXSIpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZvcm1JbnB1dHMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gZm9ybUlucHV0c1tpXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IGVsZW1lbnQudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC50eXBlID09PSAiY2hlY2tib3giKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBlbGVtZW50LmNoZWNrZWQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kVmFsdWVbZWxlbWVudC5uYW1lXSA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoIWxpbmsuaGFzQXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS1za2lwIikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5leGVjQ29tbWFuZChjb21tYW5kLCBjb21tYW5kVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIGRvbS5kZWxlZ2F0ZShjb250YWluZXIsICJzZWxlY3RbZGF0YS13eXNpaHRtbDUtY29tbWFuZF0iLCAiY2hhbmdlIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGxpbmsgPSB0aGlzLAogICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kID0gbGluay5nZXRBdHRyaWJ1dGUoImRhdGEtd3lzaWh0bWw1LWNvbW1hbmQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZFZhbHVlID0gbGluay52YWx1ZTsKICAgICAgICAgICAgICAgICAgICB0aGF0LmV4ZWNDb21tYW5kKGNvbW1hbmQsIGNvbW1hbmRWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIGRvbS5kZWxlZ2F0ZShjb250YWluZXIsICJpbnB1dFtkYXRhLXd5c2lodG1sNS1jb21tYW5kXSIsICJjaGFuZ2UiLCBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbGluayA9IHRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSBsaW5rLmdldEF0dHJpYnV0ZSgiZGF0YS13eXNpaHRtbDUtY29tbWFuZCIpLAogICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kVmFsdWUgPSBsaW5rLnR5cGUgPT09ICJjaGVja2JveCIgPyBsaW5rLmNoZWNrZWQgOiBsaW5rLnZhbHVlOwogICAgICAgICAgICAgICAgICAgIHRoYXQuZXhlY0NvbW1hbmQoY29tbWFuZCwgY29tbWFuZFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgZG9tLmRlbGVnYXRlKGNvbnRhaW5lciwgIltkYXRhLXd5c2lodG1sNS1hY3Rpb25dIiwgImNsaWNrIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGFjdGlvbiA9IHRoaXMuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS1hY3Rpb24iKTsKICAgICAgICAgICAgICAgICAgICB0aGF0LmV4ZWNBY3Rpb24oYWN0aW9uKTsKICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgZWRpdG9yLm9uKCJmb2N1czpjb21wb3NlciIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB0aGF0LmJvb2ttYXJrID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKHRoYXQuaW50ZXJ2YWwpOwogICAgICAgICAgICAgICAgICAgIHRoYXQuaW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX3VwZGF0ZUxpbmtTdGF0ZXMoKTsKICAgICAgICAgICAgICAgICAgICB9LCA1MDApOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgZWRpdG9yLm9uKCJibHVyOmNvbXBvc2VyIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhhdC5pbnRlcnZhbCk7CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICBlZGl0b3Iub24oImRlc3Ryb3k6Y29tcG9zZXIiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGF0LmludGVydmFsKTsKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIGVkaXRvci5vbigiY2hhbmdlX3ZpZXciLCBmdW5jdGlvbiAoY3VycmVudFZpZXcpIHsKICAgICAgICAgICAgICAgICAgICAvLyBTZXQgdGltZW91dCBuZWVkZWQgaW4gb3JkZXIgdG8gbGV0IHRoZSBibHVyIGV2ZW50IGZpcmUgZmlyc3QKICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5jb21tYW5kc0Rpc2FibGVkID0gKGN1cnJlbnRWaWV3ICE9PSAiY29tcG9zZXIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fdXBkYXRlTGlua1N0YXRlcygpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5jb21tYW5kc0Rpc2FibGVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb20uYWRkQ2xhc3MoY29udGFpbmVyLCBDTEFTU19OQU1FX0NPTU1BTkRTX0RJU0FCTEVEKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5yZW1vdmVDbGFzcyhjb250YWluZXIsIENMQVNTX05BTUVfQ09NTUFORFNfRElTQUJMRUQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwgMCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF91cGRhdGVMaW5rU3RhdGVzIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIGNvbW1hbmRNYXBwaW5nID0gdGhpcy5jb21tYW5kTWFwcGluZywKICAgICAgICAgICAgICAgICAgICBhY3Rpb25NYXBwaW5nID0gdGhpcy5hY3Rpb25NYXBwaW5nLAogICAgICAgICAgICAgICAgICAgIGksCiAgICAgICAgICAgICAgICAgICAgc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgYWN0aW9uLAogICAgICAgICAgICAgICAgICAgIGNvbW1hbmQ7CiAgICAgICAgICAgICAgICAvLyBldmVyeSBtaWxsaXNlY29uZCBjb3VudHMuLi4gdGhpcyBpcyBleGVjdXRlZCBxdWl0ZSBvZnRlbgoKICAgICAgICAgICAgICAgIGZvciAoaSBpbiBjb21tYW5kTWFwcGluZykgewogICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSBjb21tYW5kTWFwcGluZ1tpXTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29tbWFuZHNEaXNhYmxlZCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZnVuYyA9IHd5c2lodG1sNS51dGlsLmdldE9iamVjdFByb3BlcnR5KHdpbmRvdywgY29tbWFuZC5mdW5jKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZ1bmMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gdGhpcy5jb21wb3Nlci5jb21tYW5kcy5jYWxsYmFja1N0YXRlKGNvbW1hbmQubmFtZSwgY29tbWFuZC52YWx1ZSwgY29tbWFuZC5pc0RlZmF1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHd5c2lodG1sNS5sYW5nLm9iamVjdChzdGF0ZSkuaXNBcnJheSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR3JhYiBmaXJzdCBhbmQgb25seSBvYmplY3QvZWxlbWVudCBpbiBzdGF0ZSBhcnJheSwgb3RoZXJ3aXNlIGNvbnZlcnQgc3RhdGUgaW50byBib29sZWFuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG8gYXZvaWQgc2hvd2luZyBhIGRpYWxvZyBmb3IgbXVsdGlwbGUgc2VsZWN0ZWQgZWxlbWVudHMgd2hpY2ggbWF5IGhhdmUgZGlmZmVyZW50IGF0dHJpYnV0ZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlZy4gd2hlbiB0d28gbGlua3Mgd2l0aCBkaWZmZXJlbnQgaHJlZiBhcmUgc2VsZWN0ZWQsIHRoZSBzdGF0ZSB3aWxsIGJlIGFuIGFycmF5IGNvbnNpc3Rpbmcgb2YgYm90aCBsaW5rIGVsZW1lbnRzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnV0IHRoZSBkaWFsb2cgaW50ZXJmYWNlIGNhbiBvbmx5IHVwZGF0ZSBvbmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IHN0YXRlLmxlbmd0aCA9PT0gMSA/IHN0YXRlWzBdIDogdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5yZW1vdmVDbGFzcyhjb21tYW5kLmxpbmssIENMQVNTX05BTUVfQ09NTUFORF9ESVNBQkxFRCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWFuZC5ncm91cCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbS5yZW1vdmVDbGFzcyhjb21tYW5kLmdyb3VwLCBDTEFTU19OQU1FX0NPTU1BTkRfRElTQUJMRUQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuYyhjb21tYW5kLmxpbmssIHN0YXRlLCBjb21tYW5kLmVsZW1lbnROYW1lLCBjb21tYW5kLm5hbWUsIGNvbW1hbmQudmFsdWUsIGNvbW1hbmQuaXNEZWZhdWx0KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmb3IgKGkgaW4gYWN0aW9uTWFwcGluZykgewogICAgICAgICAgICAgICAgICAgIGFjdGlvbiA9IGFjdGlvbk1hcHBpbmdbaV07CiAgICAgICAgICAgICAgICAgICAgaWYgKGFjdGlvbi5uYW1lID09PSAiY2hhbmdlX3ZpZXciKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbi5zdGF0ZSA9IHRoaXMuZWRpdG9yLmN1cnJlbnRWaWV3ID09PSB0aGlzLmVkaXRvci50ZXh0YXJlYTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFjdGlvbi5zdGF0ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tLmFkZENsYXNzKGFjdGlvbi5saW5rLCBDTEFTU19OQU1FX0FDVElPTl9BQ1RJVkUpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tLnJlbW92ZUNsYXNzKGFjdGlvbi5saW5rLCBDTEFTU19OQU1FX0FDVElPTl9BQ1RJVkUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2hvdyA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAiIjsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGhpZGUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7Ci8qKgogKiBXWVNJSFRNTDUgRWRpdG9yCiAqCiAqIEBwYXJhbSB7RWxlbWVudH0gdGV4dGFyZWFFbGVtZW50IFJlZmVyZW5jZSB0byB0aGUgdGV4dGFyZWEgd2hpY2ggc2hvdWxkIGJlIHR1cm5lZCBpbnRvIGEgcmljaCB0ZXh0IGludGVyZmFjZQogKiBAcGFyYW0ge09iamVjdH0gW2NvbmZpZ10gU2VlIGRlZmF1bHRDb25maWcgb2JqZWN0IGJlbG93IGZvciBleHBsYW5hdGlvbiBvZiBlYWNoIGluZGl2aWR1YWwgY29uZmlnIG9wdGlvbgogKgogKiBAZXZlbnRzCiAqICAgIGxvYWQKICogICAgYmVmb3JlbG9hZCAoZm9yIGludGVybmFsIHVzZSBvbmx5KQogKiAgICBmb2N1cwogKiAgICBmb2N1czpjb21wb3NlcgogKiAgICBjbGljazpjb21wb3NlcgogKiAgICBmb2N1czp0ZXh0YXJlYQogKiAgICBibHVyCiAqICAgIGJsdXI6Y29tcG9zZXIKICogICAgYmx1cjp0ZXh0YXJlYQogKiAgICBjaGFuZ2UKICogICAgY2hhbmdlOmNvbXBvc2VyCiAqICAgIGNoYW5nZTp0ZXh0YXJlYQogKiAgICBwYXN0ZQogKiAgICBwYXN0ZTpjb21wb3NlcgogKiAgICBwYXN0ZTp0ZXh0YXJlYQogKiAgICBuZXd3b3JkOmNvbXBvc2VyCiAqICAgIGRlc3Ryb3k6Y29tcG9zZXIKICogICAgdW5kbzpjb21wb3NlcgogKiAgICByZWRvOmNvbXBvc2VyCiAqICAgIGJlZm9yZWNvbW1hbmQ6Y29tcG9zZXIKICogICAgYWZ0ZXJjb21tYW5kOmNvbXBvc2VyCiAqICAgIGVuYWJsZTpjb21wb3NlcgogKiAgICBkaXNhYmxlOmNvbXBvc2VyCiAqICAgIGNoYW5nZV92aWV3CiAqLwooZnVuY3Rpb24gKHd5c2lodG1sNSkgewogICAgdmFyIHVuZGVmOwoKICAgIHZhciBkZWZhdWx0Q29uZmlnID0gewogICAgICAgIC8vIEdpdmUgdGhlIGVkaXRvciBhIG5hbWUsIHRoZSBuYW1lIHdpbGwgYWxzbyBiZSBzZXQgYXMgY2xhc3MgbmFtZSBvbiB0aGUgaWZyYW1lIGFuZCBvbiB0aGUgaWZyYW1lJ3MgYm9keQogICAgICAgIG5hbWUgOiB1bmRlZiwKICAgICAgICAvLyBXaGV0aGVyIHRoZSBlZGl0b3Igc2hvdWxkIGxvb2sgbGlrZSB0aGUgdGV4dGFyZWEgKGJ5IGFkb3B0aW5nIHN0eWxlcykKICAgICAgICBzdHlsZSA6IHRydWUsCiAgICAgICAgLy8gSWQgb2YgdGhlIHRvb2xiYXIgZWxlbWVudCwgcGFzcyBmYWxzZXkgdmFsdWUgaWYgeW91IGRvbid0IHdhbnQgYW55IHRvb2xiYXIgbG9naWMKICAgICAgICB0b29sYmFyIDogdW5kZWYsCiAgICAgICAgLy8gV2hldGhlciB1cmxzLCBlbnRlcmVkIGJ5IHRoZSB1c2VyIHNob3VsZCBhdXRvbWF0aWNhbGx5IGJlY29tZSBjbGlja2FibGUtbGlua3MKICAgICAgICBhdXRvTGluayA6IHRydWUsCiAgICAgICAgLy8gT2JqZWN0IHdoaWNoIGluY2x1ZGVzIHBhcnNlciBydWxlcyB0byBhcHBseSB3aGVuIGh0bWwgZ2V0cyBpbnNlcnRlZCB2aWEgY29weSAmIHBhc3RlCiAgICAgICAgLy8gU2VlIHBhcnNlcl9ydWxlcy8qLmpzIGZvciBleGFtcGxlcwogICAgICAgIHBhcnNlclJ1bGVzIDoge3RhZ3MgOiB7YnIgOiB7fSwgc3BhbiA6IHt9LCBkaXYgOiB7fSwgcCA6IHt9fSwgY2xhc3NlcyA6IHt9fSwKICAgICAgICAvLyBQYXJzZXIgbWV0aG9kIHRvIHVzZSB3aGVuIHRoZSB1c2VyIGluc2VydHMgY29udGVudCB2aWEgY29weSAmIHBhc3RlCiAgICAgICAgcGFyc2VyIDogd3lzaWh0bWw1LmRvbS5wYXJzZSwKICAgICAgICAvLyBDbGFzcyBuYW1lIHdoaWNoIHNob3VsZCBiZSBzZXQgb24gdGhlIGNvbnRlbnRFZGl0YWJsZSBlbGVtZW50IGluIHRoZSBjcmVhdGVkIHNhbmRib3ggaWZyYW1lLCBjYW4gYmUgc3R5bGVkIHZpYSB0aGUgJ3N0eWxlc2hlZXRzJyBvcHRpb24KICAgICAgICBjb21wb3NlckNsYXNzTmFtZSA6ICJ3eXNpaHRtbDUtZWRpdG9yIiwKICAgICAgICAvLyBDbGFzcyBuYW1lIHRvIGFkZCB0byB0aGUgYm9keSB3aGVuIHRoZSB3eXNpaHRtbDUgZWRpdG9yIGlzIHN1cHBvcnRlZAogICAgICAgIGJvZHlDbGFzc05hbWUgOiAid3lzaWh0bWw1LXN1cHBvcnRlZCIsCiAgICAgICAgLy8gQnkgZGVmYXVsdCB3eXNpaHRtbDUgd2lsbCBpbnNlcnQgYSA8YnI+IGZvciBsaW5lIGJyZWFrcywgc2V0IHRoaXMgdG8gZmFsc2UgdG8gdXNlIDxwPgogICAgICAgIHVzZUxpbmVCcmVha3MgOiB0cnVlLAogICAgICAgIHBhc3RlQXNQbGFpblRleHQgOiBmYWxzZSwKICAgICAgICAvLyBBcnJheSAob3Igc2luZ2xlIHN0cmluZykgb2Ygc3R5bGVzaGVldCB1cmxzIHRvIGJlIGxvYWRlZCBpbiB0aGUgZWRpdG9yJ3MgaWZyYW1lCiAgICAgICAgc3R5bGVzaGVldHMgOiBbXSwKICAgICAgICAvLyBQbGFjZWhvbGRlciB0ZXh0IHRvIHVzZSwgZGVmYXVsdHMgdG8gdGhlIHBsYWNlaG9sZGVyIGF0dHJpYnV0ZSBvbiB0aGUgdGV4dGFyZWEgZWxlbWVudAogICAgICAgIHBsYWNlaG9sZGVyVGV4dCA6IHVuZGVmLAogICAgICAgIC8vIFdoZXRoZXIgdGhlIHJpY2ggdGV4dCBlZGl0b3Igc2hvdWxkIGJlIHJlbmRlcmVkIG9uIHRvdWNoIGRldmljZXMgKHd5c2lodG1sNSA+PSAwLjMuMCBjb21lcyB3aXRoIGJhc2ljIHN1cHBvcnQgZm9yIGlPUyA1KQogICAgICAgIHN1cHBvcnRUb3VjaERldmljZXMgOiB0cnVlCiAgICB9OwoKICAgIHd5c2lodG1sNS5FZGl0b3IgPSB3eXNpaHRtbDUubGFuZy5EaXNwYXRjaGVyLmV4dGVuZCgKICAgICAgICAvKiogQHNjb3BlIHd5c2lodG1sNS5FZGl0b3IucHJvdG90eXBlICovIHsKICAgICAgICAgICAgY29uc3RydWN0b3IgOiBmdW5jdGlvbiAodGV4dGFyZWFFbGVtZW50LCBjb25maWcpIHsKICAgICAgICAgICAgICAgIHRoaXMudGV4dGFyZWFFbGVtZW50ID0gdHlwZW9mKHRleHRhcmVhRWxlbWVudCkgPT09ICJzdHJpbmciID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGV4dGFyZWFFbGVtZW50KSA6IHRleHRhcmVhRWxlbWVudDsKICAgICAgICAgICAgICAgIHRoaXMuY29uZmlnID0gd3lzaWh0bWw1Lmxhbmcub2JqZWN0KHt9KS5tZXJnZShkZWZhdWx0Q29uZmlnKS5tZXJnZShjb25maWcpLmdldCgpOwogICAgICAgICAgICAgICAgdGhpcy50ZXh0YXJlYSA9IG5ldyB3eXNpaHRtbDUudmlld3MuVGV4dGFyZWEodGhpcywgdGhpcy50ZXh0YXJlYUVsZW1lbnQsIHRoaXMuY29uZmlnKTsKICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFZpZXcgPSB0aGlzLnRleHRhcmVhOwogICAgICAgICAgICAgICAgdGhpcy5faXNDb21wYXRpYmxlID0gd3lzaWh0bWw1LmJyb3dzZXIuc3VwcG9ydGVkKCk7CgogICAgICAgICAgICAgICAgLy8gU29ydCBvdXQgdW5zdXBwb3J0ZWQvdW53YW50ZWQgYnJvd3NlcnMgaGVyZQogICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9pc0NvbXBhdGlibGUgfHwgKCF0aGlzLmNvbmZpZy5zdXBwb3J0VG91Y2hEZXZpY2VzICYmIHd5c2lodG1sNS5icm93c2VyLmlzVG91Y2hEZXZpY2UoKSkpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZmlyZSgiYmVmb3JlbG9hZCIpLmZpcmUoImxvYWQiKTsKICAgICAgICAgICAgICAgICAgICB9LCAwKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gQWRkIGNsYXNzIG5hbWUgdG8gYm9keSwgdG8gaW5kaWNhdGUgdGhhdCB0aGUgZWRpdG9yIGlzIHN1cHBvcnRlZAogICAgICAgICAgICAgICAgd3lzaWh0bWw1LmRvbS5hZGRDbGFzcyhkb2N1bWVudC5ib2R5LCB0aGlzLmNvbmZpZy5ib2R5Q2xhc3NOYW1lKTsKCiAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyID0gbmV3IHd5c2lodG1sNS52aWV3cy5Db21wb3Nlcih0aGlzLCB0aGlzLnRleHRhcmVhRWxlbWVudCwgdGhpcy5jb25maWcpOwogICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50VmlldyA9IHRoaXMuY29tcG9zZXI7CgogICAgICAgICAgICAgICAgaWYgKHR5cGVvZih0aGlzLmNvbmZpZy5wYXJzZXIpID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faW5pdFBhcnNlcigpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy5wYXJzZXJSdWxlcykgewogICAgICAgICAgICAgICAgICAgIHRoaXMucGFyc2VyUnVsZXMgPSB0aGlzLmNvbmZpZy5wYXJzZXJSdWxlczsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLm9uKCJiZWZvcmVsb2FkIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc3luY2hyb25pemVyID0gbmV3IHd5c2lodG1sNS52aWV3cy5TeW5jaHJvbml6ZXIodGhpcywgdGhpcy50ZXh0YXJlYSwgdGhpcy5jb21wb3Nlcik7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLnRvb2xiYXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b29sYmFyID0gbmV3IHd5c2lodG1sNS50b29sYmFyLlRvb2xiYXIodGhpcywgdGhpcy5jb25maWcudG9vbGJhcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB0aGlzLmNvbXBvc2VyLl9jcmVhdGUoKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coIkhleWEhIFRoaXMgcGFnZSBpcyB1c2luZyB3eXNpaHRtbDUgZm9yIHJpY2ggdGV4dCBlZGl0aW5nLiBDaGVjayBvdXQgaHR0cHM6Ly9naXRodWIuY29tL3hpbmcvd3lzaWh0bWw1Iik7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBzZXRUb29sYmFyIDogZnVuY3Rpb24gKHRvb2xiYXIpIHsKICAgICAgICAgICAgICAgIHRoaXMudG9vbGJhciA9IG5ldyB3eXNpaHRtbDUudG9vbGJhci5Ub29sYmFyKHRoaXMsIHRvb2xiYXIpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgaXNDb21wYXRpYmxlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2lzQ29tcGF0aWJsZTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGNsZWFyIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50Vmlldy5jbGVhcigpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBnZXRWYWx1ZSA6IGZ1bmN0aW9uIChwYXJzZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFZpZXcuZ2V0VmFsdWUocGFyc2UpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgc2V0VmFsdWUgOiBmdW5jdGlvbiAoaHRtbCwgcGFyc2UpIHsKICAgICAgICAgICAgICAgIHRoaXMuZmlyZSgidW5zZXRfcGxhY2Vob2xkZXIiKTsKCiAgICAgICAgICAgICAgICBpZiAoIWh0bWwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGVhcigpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFZpZXcuc2V0VmFsdWUoaHRtbCwgcGFyc2UpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBmb2N1cyA6IGZ1bmN0aW9uIChzZXRUb0VuZCkgewogICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50Vmlldy5mb2N1cyhzZXRUb0VuZCk7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBEZWFjdGl2YXRlIGVkaXRvciAobWFrZSBpdCByZWFkb25seSkKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGRpc2FibGUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRWaWV3LmRpc2FibGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEFjdGl2YXRlIGVkaXRvcgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZW5hYmxlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50Vmlldy5lbmFibGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgaXNFbXB0eSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRWaWV3LmlzRW1wdHkoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGhhc1BsYWNlaG9sZGVyU2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFZpZXcuaGFzUGxhY2Vob2xkZXJTZXQoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHBhcnNlIDogZnVuY3Rpb24gKGh0bWxPckVsZW1lbnQsIHByZVByb2Nlc3MpIHsKICAgICAgICAgICAgICAgIHZhciByZXR1cm5WYWx1ZSA9IHRoaXMuY29uZmlnLnBhcnNlcihodG1sT3JFbGVtZW50LCB0aGlzLmNvbmZpZy5wYXJzZXJSdWxlcywgdGhpcy5jb21wb3Nlci5zYW5kYm94LmdldERvY3VtZW50KCksIHRydWUsIHByZVByb2Nlc3MpOwogICAgICAgICAgICAgICAgaWYgKHR5cGVvZihodG1sT3JFbGVtZW50KSA9PT0gIm9iamVjdCIpIHsKICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUucXVpcmtzLnJlZHJhdyhodG1sT3JFbGVtZW50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBQcmVwYXJlIGh0bWwgcGFyc2VyIGxvZ2ljCiAgICAgICAgICAgICAqICAtIE9ic2VydmVzIGZvciBwYXN0ZSBhbmQgZHJvcAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgX2luaXRQYXJzZXIgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGlzLm9uKCJwYXN0ZTpjb21wb3NlciIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIga2VlcFNjcm9sbFBvc2l0aW9uID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgdGhhdC5jb21wb3Nlci5zZWxlY3Rpb24uZXhlY3V0ZUFuZFJlc3RvcmUoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICB3eXNpaHRtbDUucXVpcmtzLmNsZWFuUGFzdGVkSFRNTCh0aGF0LmNvbXBvc2VyLmVsZW1lbnQpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LnBhcnNlKHRoYXQuY29tcG9zZXIuZWxlbWVudCk7CiAgICAgICAgICAgICAgICAgICAgfSwga2VlcFNjcm9sbFBvc2l0aW9uKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfSk7Cn0pKHd5c2lodG1sNSk7CgovKioKICogVGhlc2UgcnVsZXMgZGVmaW5lIHdoaWNoIHRhZ3MgYW5kIGNzcyBjbGFzc2VzIGFyZSBzdXBwb3J0ZWQgYW5kIHdoaWNoIHRhZ3Mgc2hvdWxkIGJlIHNwZWNpYWxseSB0cmVhdGVkLgogKgogKiBFeGFtcGxlcyBiYXNlZCBvbiB0aGlzIHJ1bGUgc2V0OgogKgogKiAgICA8YSBocmVmPSJodHRwOi8vZm9vYmFyLmNvbSI+Zm9vPC9hPgogKiAgICAuLi4gYmVjb21lcyAuLi4KICogICAgPGEgaHJlZj0iaHR0cDovL2Zvb2Jhci5jb20iIHRhcmdldD0iX2JsYW5rIiByZWw9Im5vZm9sbG93Ij5mb288L2E+CiAqCiAqICAgIDxpbWcgYWxpZ249ImxlZnQiIHNyYz0iaHR0cDovL2Zvb2Jhci5jb20vaW1hZ2UucG5nIj4KICogICAgLi4uIGJlY29tZXMgLi4uCiAqICAgIDxpbWcgY2xhc3M9Ind5c2l3eWctZmxvYXQtbGVmdCIgc3JjPSJodHRwOi8vZm9vYmFyLmNvbS9pbWFnZS5wbmciIGFsdD0iIj4KICoKICogICAgPGRpdj5mb288c2NyaXB0PmFsZXJ0KGRvY3VtZW50LmNvb2tpZSk8L3NjcmlwdD48L2Rpdj4KICogICAgLi4uIGJlY29tZXMgLi4uCiAqICAgIDxkaXY+Zm9vPC9kaXY+CiAqCiAqICAgIDxtYXJxdWVlPmZvbzwvbWFycXVlZT4KICogICAgLi4uIGJlY29tZXMgLi4uCiAqICAgIDxzcGFuPmZvbzwvbWFycXVlZT4KICoKICogICAgZm9vIDxiciBjbGVhcj0iYm90aCI+IGJhcgogKiAgICAuLi4gYmVjb21lcyAuLi4KICogICAgZm9vIDxiciBjbGFzcz0id3lzaXd5Zy1jbGVhci1ib3RoIj4gYmFyCiAqCiAqICAgIDxkaXY+aGVsbG8gPGlmcmFtZSBzcmM9Imh0dHA6Ly9nb29nbGUuY29tIj48L2lmcmFtZT48L2Rpdj4KICogICAgLi4uIGJlY29tZXMgLi4uCiAqICAgIDxkaXY+aGVsbG8gPC9kaXY+CiAqCiAqICAgIDxjZW50ZXI+aGVsbG88L2NlbnRlcj4KICogICAgLi4uIGJlY29tZXMgLi4uCiAqICAgIDxkaXYgY2xhc3M9Ind5c2l3eWctdGV4dC1hbGlnbi1jZW50ZXIiPmhlbGxvPC9kaXY+CiAqLwp2YXIgd3lzaWh0bWw1U3VwcG9ydGVkUGFyc2VyUnVsZXMgPSB7CiAgICAvKioKICAgICAqIENTUyBDbGFzcyB3aGl0ZS1saXN0CiAgICAgKiBGb2xsb3dpbmcgY3NzIGNsYXNzZXMgd29uJ3QgYmUgcmVtb3ZlZCB3aGVuIHBhcnNlZCBieSB0aGUgd3lzaWh0bWw1IGh0bWwgcGFyc2VyCiAgICAgKi8KICAgICJjbGFzc2VzIiA6IHsKICAgICAgICAidGV4dEVkaXRvci1jdXN0b21EYXRhQXR0ciIgOiAxCiAgICB9LAogICAgLyoqCiAgICAgKiBUYWcgbGlzdAogICAgICoKICAgICAqIEZvbGxvd2luZyBvcHRpb25zIGFyZSBhdmFpbGFibGU6CiAgICAgKgogICAgICogICAgLSBhZGRfY2xhc3M6ICAgICAgICBjb252ZXJ0cyBhbmQgZGVsZXRlcyB0aGUgZ2l2ZW4gSFRNTDQgYXR0cmlidXRlIChhbGlnbiwgY2xlYXIsIC4uLikgdmlhIHRoZSBnaXZlbiBtZXRob2QgdG8gYSBjc3MgY2xhc3MKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgVGhlIGZvbGxvd2luZyBtZXRob2RzIGFyZSBpbXBsZW1lbnRlZCBpbiB3eXNpaHRtbDUuZG9tLnBhcnNlOgogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgIC0gYWxpZ25fdGV4dDogIGNvbnZlcnRzIGFsaWduIGF0dHJpYnV0ZSB2YWx1ZXMgKHJpZ2h0L2xlZnQvY2VudGVyL2p1c3RpZnkpIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgY3NzIGNsYXNzICJ3eXNpd3lnLXRleHQtYWxpZ24tKiIpCiAgICAgPHAgYWxpZ249ImNlbnRlciI+Zm9vPC9wPiAuLi4gYmVjb21lcyAuLi4gPHA+IGNsYXNzPSJ3eXNpd3lnLXRleHQtYWxpZ24tY2VudGVyIj5mb288L3A+CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgLSBjbGVhcl9icjogICAgY29udmVydHMgY2xlYXIgYXR0cmlidXRlIHZhbHVlcyBsZWZ0L3JpZ2h0L2FsbC9ib3RoIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgY3NzIGNsYXNzICJ3eXNpd3lnLWNsZWFyLSoiCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnIgY2xlYXI9ImFsbCI+IC4uLiBiZWNvbWVzIC4uLiA8YnIgY2xhc3M9Ind5c2l3eWctY2xlYXItYm90aCI+CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgLSBhbGlnbl9pbWc6ICAgIGNvbnZlcnRzIGFsaWduIGF0dHJpYnV0ZSB2YWx1ZXMgKHJpZ2h0L2xlZnQpIG9uIDxpbWc+IHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgY3NzIGNsYXNzICJ3eXNpd3lnLWZsb2F0LSoiCiAgICAgKgogICAgICogICAgLSByZW1vdmU6ICAgICAgICAgICAgIHJlbW92ZXMgdGhlIGVsZW1lbnQgYW5kIGl0J3MgY29udGVudAogICAgICoKICAgICAqICAgIC0gcmVuYW1lX3RhZzogICAgICAgICByZW5hbWVzIHRoZSBlbGVtZW50IHRvIHRoZSBnaXZlbiB0YWcKICAgICAqCiAgICAgKiAgICAtIHNldF9jbGFzczogICAgICAgICAgYWRkcyB0aGUgZ2l2ZW4gY2xhc3MgdG8gdGhlIGVsZW1lbnQgKG5vdGU6IG1ha2Ugc3VyZSB0aGF0IHRoZSBjbGFzcyBpcyBpbiB0aGUgImNsYXNzZXMiIHdoaXRlIGxpc3QgYWJvdmUpCiAgICAgKgogICAgICogICAgLSBzZXRfYXR0cmlidXRlczogICAgIHNldHMvb3ZlcnJpZGVzIHRoZSBnaXZlbiBhdHRyaWJ1dGVzCiAgICAgKgogICAgICogICAgLSByZW1vdmVfYXR0cmlidXRlczogIHJlbW92ZV9hdHRyaWJ1dGVzOiAgcmVtb3ZlIGdpdmVuIGF0dHJpYnV0ZXMuIFthdHRyLCBwcm9wZXJ0eSwgZW5kU3RyaW5nXSAtPiByZW1vdmUgYXR0cmlidXRlIHByb3BlcnR5IGlmIGl0IGVuZHMgd2l0aCBlbmRTdHJpbmcuCiAgICAgKgogICAgICogICAgLSBjaGVja19hdHRyaWJ1dGVzOiAgIGNoZWNrcyB0aGUgZ2l2ZW4gSFRNTCBhdHRyaWJ1dGUgdmlhIHRoZSBnaXZlbiBtZXRob2QKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gdXJsOiAgICAgIGNoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBzdHJpbmcgaXMgYW4gdXJsLCBkZWxldGVzIHRoZSBhdHRyaWJ1dGUgaWYgbm90CiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIGFsdDogICAgICBzdHJpcHMgdW53YW50ZWQgY2hhcmFjdGVycy4gaWYgdGhlIGF0dHJpYnV0ZSBpcyBub3Qgc2V0LCB0aGVuIGl0IGdldHMgc2V0ICh0byBlbnN1cmUgdmFsaWQgYW5kIGNvbXBhdGlibGUgSFRNTCkKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gbnVtYmVyczogIGVuc3VyZXMgdGhhdCB0aGUgYXR0cmlidXRlIG9ubHkgY29udGFpbnMgbnVtZXJpYyBjaGFyYWN0ZXJzCiAgICAgKi8KICAgICJ0YWdzIiA6IHsKICAgICAgICAidWwiIDoge30sCiAgICAgICAgIm9sIiA6IHt9LAogICAgICAgICJsaSIgOiB7fSwKICAgICAgICAiYiIgOiB7fSwKICAgICAgICAiaSIgOiB7fSwKICAgICAgICAidSIgOiB7fSwKICAgICAgICAic3VwIiA6IHt9LAogICAgICAgICJzdWIiIDoge30sCiAgICAgICAgImJyIiA6IHsKICAgICAgICAgICAgInJlbW92ZV9hdHRyaWJ1dGVzIiA6IFsic3R5bGUiXQogICAgICAgIH0sCiAgICAgICAgImgxIiA6IHt9LAogICAgICAgICJoMiIgOiB7fSwKICAgICAgICAiaDMiIDoge30sCiAgICAgICAgImg0IiA6IHt9LAogICAgICAgICJoNSIgOiB7fSwKICAgICAgICAiaDYiIDoge30sCiAgICAgICAgImEiIDogewogICAgICAgICAgICAiY2hlY2tfYXR0cmlidXRlcyIgOiB7CiAgICAgICAgICAgICAgICAiaHJlZiIgOiAidXJsIgogICAgICAgICAgICB9LAogICAgICAgICAgICAic2V0X2F0dHJpYnV0ZXMiIDogewogICAgICAgICAgICAgICAgInJlbCIgOiAibm9mb2xsb3ciLAogICAgICAgICAgICAgICAgInRhcmdldCIgOiAiX2JsYW5rIgogICAgICAgICAgICB9LAogICAgICAgICAgICAicmVtb3ZlX2F0dHJpYnV0ZXMiIDogWyJzdHlsZSxiYWNrZ3JvdW5kLWNvbG9yIl0KICAgICAgICB9LAogICAgICAgICJxIiA6IHsKICAgICAgICAgICAgImNoZWNrX2F0dHJpYnV0ZXMiIDogewogICAgICAgICAgICAgICAgImNpdGUiIDogInVybCIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImhyIiA6IHt9LAogICAgICAgICJwcmUiIDoge30sCiAgICAgICAgInNwYW4iIDogewogICAgICAgICAgICAicmVtb3ZlX2F0dHJpYnV0ZXMiIDogWyJzdHlsZSxsaW5lLWhlaWdodCIsICJzdHlsZSx0ZXh0LWFsaWduIiwgInN0eWxlLG1hcmdpbi1sZWZ0IiwgInN0eWxlLG1hcmdpbi1yaWdodCIsICJzdHlsZSxtYXJnaW4tdG9wIiwgInN0eWxlLG1hcmdpbi1ib3R0b20iLCAic3R5bGUsbWFyZ2luIl0KICAgICAgICB9LAogICAgICAgICJwIiA6IHt9LAogICAgICAgICJ0YWJsZSIgOiB7CiAgICAgICAgICAgICJjaGVja19hdHRyaWJ1dGVzIiA6IHsKICAgICAgICAgICAgICAgICJjZWxscGFkZGluZyIgOiAiYW55IiwKICAgICAgICAgICAgICAgICJjZWxsc3BhY2luZyIgOiAiYW55IiwKICAgICAgICAgICAgICAgICJib3JkZXIiIDogImFueSIsCiAgICAgICAgICAgICAgICAid2lkdGgiIDogImFueSIsCiAgICAgICAgICAgICAgICAiaGVpZ2h0IiA6ICJhbnkiCiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJ0aGVhZCIgOiB7fSwKICAgICAgICAidGZvb3QiIDoge30sCiAgICAgICAgInRoIiA6IHt9LAogICAgICAgICJjb2wiIDogewogICAgICAgICAgICAiY2hlY2tfYXR0cmlidXRlcyIgOiB7CiAgICAgICAgICAgICAgICAic3BhbiIgOiAibnVtYmVycyIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInRib2R5IiA6IHt9LAogICAgICAgICJ0ciIgOiB7fSwKICAgICAgICAidGQiIDoge30sCiAgICAgICAgImZvcm0iIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJjb2RlIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAidGl0bGUiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJhcmVhIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiY29tbWFuZCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImlmcmFtZSIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImltZyIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgIm5vZnJhbWVzIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiYmdzb3VuZCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImJhc2Vmb250IiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiYmFzZSIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgInZpZGVvIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiY2FudmFzIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiYXBwbGV0IiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAic3BhY2VyIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAic291cmNlIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiZnJhbWUiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJzdHlsZSIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImRldmljZSIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImVtYmVkIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAibm9lbWJlZCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgInhtbCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgInBhcmFtIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiYXVkaW8iIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJuZXh0aWQiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJsaW5rIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAic2NyaXB0IiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiY29sZ3JvdXAiIDoge30sCiAgICAgICAgIm86cCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImNvbW1lbnQiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJmcmFtZXNldCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImhlYWQiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJvYmplY3QiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJ0cmFjayIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgIndiciIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImJ1dHRvbiIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgIm5vc2NyaXB0IiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAic3ZnIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiaW5wdXQiIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJrZXlnZW4iIDogewogICAgICAgICAgICAicmVtb3ZlIiA6IDEKICAgICAgICB9LAogICAgICAgICJtZXRhIiA6IHsKICAgICAgICAgICAgInJlbW92ZSIgOiAxCiAgICAgICAgfSwKICAgICAgICAiaXNpbmRleCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImRlbCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgIm1hcCIgOiB7CiAgICAgICAgICAgICJyZW1vdmUiIDogMQogICAgICAgIH0sCiAgICAgICAgImFkZHJlc3MiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAicCIKICAgICAgICB9LAogICAgICAgICJuYXYiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAicCIKICAgICAgICB9LAogICAgICAgICJtdWx0aWNvbCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJwIgogICAgICAgIH0sCiAgICAgICAgImZpZ3VyZSIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJwIgogICAgICAgIH0sCiAgICAgICAgImZpZ2NhcHRpb24iIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAicCIKICAgICAgICB9LAogICAgICAgICJmb290ZXIiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAicCIKICAgICAgICB9LAogICAgICAgICJmaWVsZHNldCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJwIgogICAgICAgIH0sCiAgICAgICAgImRpdiIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgImFzaWRlIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInAiCiAgICAgICAgfSwKICAgICAgICAic2VjdGlvbiIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJwIgogICAgICAgIH0sCiAgICAgICAgImJvZHkiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAicCIKICAgICAgICB9LAogICAgICAgICJodG1sIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInAiCiAgICAgICAgfSwKICAgICAgICAiaGdyb3VwIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInAiCiAgICAgICAgfSwKICAgICAgICAiY2VudGVyIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInAiCiAgICAgICAgfSwKICAgICAgICAiYXJ0aWNsZSIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJwIgogICAgICAgIH0sCiAgICAgICAgImhlYWRlciIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJwIgogICAgICAgIH0sCiAgICAgICAgImRsIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInAiCiAgICAgICAgfSwKICAgICAgICAiZGQiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJkdCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgInhtcCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgInNtYWxsIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAidGltZSIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgInJ1YnkiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJydCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgInJwIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAicmIiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJhY3JvbnltIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAiZGV0YWlscyIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgInN1bW1hcnkiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJiZGkiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJwcm9ncmVzcyIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgImRmbiIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgImFiYnIiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJzIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAic3RyaWtlIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAib3B0aW9uIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAib3B0Z3JvdXAiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJzZWxlY3QiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJiaWciIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJtYXJrIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAiY2FwdGlvbiIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgIm91dHB1dCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgIm1hcnF1ZWUiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJub2JyIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAidmFyIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAibWV0ZXIiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJibG9ja3F1b3RlIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAidGV4dGFyZWEiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJmb250IiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAidHQiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJibGluayIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgInBsYWludGV4dCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgImxlZ2VuZCIgOiB7CiAgICAgICAgICAgICJyZW5hbWVfdGFnIiA6ICJzcGFuIgogICAgICAgIH0sCiAgICAgICAgImxhYmVsIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAia2JkIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAiZGF0YWxpc3QiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAic3BhbiIKICAgICAgICB9LAogICAgICAgICJzYW1wIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAiYmRvIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAiaW5zIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInNwYW4iCiAgICAgICAgfSwKICAgICAgICAic3Ryb25nIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogImIiCiAgICAgICAgfSwKICAgICAgICAiZW0iIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAiaSIKICAgICAgICB9LAogICAgICAgICJjaXRlIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogImkiCiAgICAgICAgfSwKICAgICAgICAiZGlyIiA6IHsKICAgICAgICAgICAgInJlbmFtZV90YWciIDogInVsIgogICAgICAgIH0sCiAgICAgICAgIm1lbnUiIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAidWwiCiAgICAgICAgfSwKICAgICAgICAibWVudWl0ZW0iIDogewogICAgICAgICAgICAicmVuYW1lX3RhZyIgOiAibGkiCiAgICAgICAgfQogICAgfSwKICAgIC8qKgogICAgICogQ1NTIHN0eWxlcyB3aGl0ZS1saXN0CiAgICAgKiBGb2xsb3dpbmcgY3NzIHN0eWxlcyB3b24ndCBiZSByZW1vdmVkIHdoZW4gcGFyc2VkIGJ5IHRoZSB3eXNpaHRtbDUgaHRtbCBwYXJzZXIKICAgICAqLwogICAgInN0eWxlcyIgOiBbCiAgICAgICAgICAgICAgICAiZm9udC1mYW1pbHkiLAogICAgICAgICAgICAgICAgImZvbnQtc2l6ZSIsCiAgICAgICAgICAgICAgICAiY29sb3IiLAogICAgICAgICAgICAgICAgImJhY2tncm91bmQtY29sb3IiLAogICAgICAgICAgICAgICAgImxldHRlci1zcGFjaW5nIiwKICAgICAgICAgICAgICAgICJsaW5lLWhlaWdodCIsCiAgICAgICAgICAgICAgICAidGV4dC1hbGlnbiIsCiAgICAgICAgICAgICAgICAibWFyZ2luLWxlZnQiLAogICAgICAgICAgICAgICAgIm1hcmdpbi1yaWdodCIsCiAgICAgICAgICAgICAgICAibWFyZ2luLXRvcCIsCiAgICAgICAgICAgICAgICAibWFyZ2luLWJvdHRvbSIsCiAgICAgICAgICAgICAgICAibGlzdC1zdHlsZS10eXBlIiwKICAgICAgICAgICAgICAgICJ3aGl0ZS1zcGFjZSIsCiAgICAgICAgICAgICAgICAiYm9yZGVyLWNvbGxhcHNlIgogICAgICAgICAgICAgICAgXQp9OwoKLyohCgogaGFuZGxlYmFycyB2NC4wLjUKCiBDb3B5cmlnaHQgKEMpIDIwMTEtMjAxNSBieSBZZWh1ZGEgS2F0egoKIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgoKIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KIFRIRSBTT0ZUV0FSRS4KCiBAbGljZW5zZQogKi8KKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHsKCWlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JykKCQltb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTsKCWVsc2UgaWYodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKQoJCWRlZmluZShbXSwgZmFjdG9yeSk7CgllbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JykKCQlleHBvcnRzWyJIYW5kbGViYXJzIl0gPSBmYWN0b3J5KCk7CgllbHNlCgkJcm9vdFsiSGFuZGxlYmFycyJdID0gZmFjdG9yeSgpOwp9KSh0aGlzLCBmdW5jdGlvbigpIHsKCXJldHVybiAvKioqKioqLyAoZnVuY3Rpb24obW9kdWxlcykgeyAvLyB3ZWJwYWNrQm9vdHN0cmFwCgkJLyoqKioqKi8gCS8vIFRoZSBtb2R1bGUgY2FjaGUKCQkvKioqKioqLyAJdmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTsKCgkJLyoqKioqKi8gCS8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uCgkJLyoqKioqKi8gCWZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHsKCgkJCS8qKioqKiovIAkJLy8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlCgkJCS8qKioqKiovIAkJaWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pCgkJCS8qKioqKiovIAkJCXJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzOwoKCQkJLyoqKioqKi8gCQkvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKQoJCQkvKioqKioqLyAJCXZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHsKCQkJCS8qKioqKiovIAkJCWV4cG9ydHM6IHt9LAoJCQkJLyoqKioqKi8gCQkJaWQ6IG1vZHVsZUlkLAoJCQkJLyoqKioqKi8gCQkJbG9hZGVkOiBmYWxzZQoJCQkJLyoqKioqKi8gCQl9OwoKCQkJLyoqKioqKi8gCQkvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb24KCQkJLyoqKioqKi8gCQltb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTsKCgkJCS8qKioqKiovIAkJLy8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZAoJCQkvKioqKioqLyAJCW1vZHVsZS5sb2FkZWQgPSB0cnVlOwoKCQkJLyoqKioqKi8gCQkvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZQoJCQkvKioqKioqLyAJCXJldHVybiBtb2R1bGUuZXhwb3J0czsKCQkJLyoqKioqKi8gCX0KCgoJCS8qKioqKiovIAkvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKQoJCS8qKioqKiovIAlfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzOwoKCQkvKioqKioqLyAJLy8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGUKCQkvKioqKioqLyAJX193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlczsKCgkJLyoqKioqKi8gCS8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fCgkJLyoqKioqKi8gCV9fd2VicGFja19yZXF1aXJlX18ucCA9ICIiOwoKCQkvKioqKioqLyAJLy8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzCgkJLyoqKioqKi8gCXJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKDApOwoJCS8qKioqKiovIH0pCgkJLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCQkvKioqKioqLyAoWwoJCS8qIDAgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHsKCgkJCSd1c2Ugc3RyaWN0JzsKCgkJCXZhciBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCA9IF9fd2VicGFja19yZXF1aXJlX18oMSlbJ2RlZmF1bHQnXTsKCgkJCXZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKVsnZGVmYXVsdCddOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCgkJCXZhciBfaGFuZGxlYmFyc0Jhc2UgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDMpOwoKCQkJdmFyIGJhc2UgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfaGFuZGxlYmFyc0Jhc2UpOwoKCQkJLy8gRWFjaCBvZiB0aGVzZSBhdWdtZW50IHRoZSBIYW5kbGViYXJzIG9iamVjdC4gTm8gbmVlZCB0byBzZXR1cCBoZXJlLgoJCQkvLyAoVGhpcyBpcyBkb25lIHRvIGVhc2lseSBzaGFyZSBjb2RlIGJldHdlZW4gY29tbW9uanMgYW5kIGJyb3dzZSBlbnZzKQoKCQkJdmFyIF9oYW5kbGViYXJzU2FmZVN0cmluZyA9IF9fd2VicGFja19yZXF1aXJlX18oMTcpOwoKCQkJdmFyIF9oYW5kbGViYXJzU2FmZVN0cmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9oYW5kbGViYXJzU2FmZVN0cmluZyk7CgoJCQl2YXIgX2hhbmRsZWJhcnNFeGNlcHRpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpOwoKCQkJdmFyIF9oYW5kbGViYXJzRXhjZXB0aW9uMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2hhbmRsZWJhcnNFeGNlcHRpb24pOwoKCQkJdmFyIF9oYW5kbGViYXJzVXRpbHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpOwoKCQkJdmFyIFV0aWxzID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoX2hhbmRsZWJhcnNVdGlscyk7CgoJCQl2YXIgX2hhbmRsZWJhcnNSdW50aW1lID0gX193ZWJwYWNrX3JlcXVpcmVfXygxOCk7CgoJCQl2YXIgcnVudGltZSA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF9oYW5kbGViYXJzUnVudGltZSk7CgoJCQl2YXIgX2hhbmRsZWJhcnNOb0NvbmZsaWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygxOSk7CgoJCQl2YXIgX2hhbmRsZWJhcnNOb0NvbmZsaWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2hhbmRsZWJhcnNOb0NvbmZsaWN0KTsKCgkJCS8vIEZvciBjb21wYXRpYmlsaXR5IGFuZCB1c2FnZSBvdXRzaWRlIG9mIG1vZHVsZSBzeXN0ZW1zLCBtYWtlIHRoZSBIYW5kbGViYXJzIG9iamVjdCBhIG5hbWVzcGFjZQoJCQlmdW5jdGlvbiBjcmVhdGUoKSB7CgkJCQl2YXIgaGIgPSBuZXcgYmFzZS5IYW5kbGViYXJzRW52aXJvbm1lbnQoKTsKCgkJCQlVdGlscy5leHRlbmQoaGIsIGJhc2UpOwoJCQkJaGIuU2FmZVN0cmluZyA9IF9oYW5kbGViYXJzU2FmZVN0cmluZzJbJ2RlZmF1bHQnXTsKCQkJCWhiLkV4Y2VwdGlvbiA9IF9oYW5kbGViYXJzRXhjZXB0aW9uMlsnZGVmYXVsdCddOwoJCQkJaGIuVXRpbHMgPSBVdGlsczsKCQkJCWhiLmVzY2FwZUV4cHJlc3Npb24gPSBVdGlscy5lc2NhcGVFeHByZXNzaW9uOwoKCQkJCWhiLlZNID0gcnVudGltZTsKCQkJCWhiLnRlbXBsYXRlID0gZnVuY3Rpb24gKHNwZWMpIHsKCQkJCQlyZXR1cm4gcnVudGltZS50ZW1wbGF0ZShzcGVjLCBoYik7CgkJCQl9OwoKCQkJCXJldHVybiBoYjsKCQkJfQoKCQkJdmFyIGluc3QgPSBjcmVhdGUoKTsKCQkJaW5zdC5jcmVhdGUgPSBjcmVhdGU7CgoJCQlfaGFuZGxlYmFyc05vQ29uZmxpY3QyWydkZWZhdWx0J10oaW5zdCk7CgoJCQlpbnN0WydkZWZhdWx0J10gPSBpbnN0OwoKCQkJZXhwb3J0c1snZGVmYXVsdCddID0gaW5zdDsKCQkJbW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107CgoJCQkvKioqLyB9LAoJCS8qIDEgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHsKCgkJCSJ1c2Ugc3RyaWN0IjsKCgkJCWV4cG9ydHNbImRlZmF1bHQiXSA9IGZ1bmN0aW9uIChvYmopIHsKCQkJCWlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsKCQkJCQlyZXR1cm4gb2JqOwoJCQkJfSBlbHNlIHsKCQkJCQl2YXIgbmV3T2JqID0ge307CgoJCQkJCWlmIChvYmogIT0gbnVsbCkgewoJCQkJCQlmb3IgKHZhciBrZXkgaW4gb2JqKSB7CgkJCQkJCQlpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgbmV3T2JqW2tleV0gPSBvYmpba2V5XTsKCQkJCQkJfQoJCQkJCX0KCgkJCQkJbmV3T2JqWyJkZWZhdWx0Il0gPSBvYmo7CgkJCQkJcmV0dXJuIG5ld09iajsKCQkJCX0KCQkJfTsKCgkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgoJCQkvKioqLyB9LAoJCS8qIDIgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHsKCgkJCSJ1c2Ugc3RyaWN0IjsKCgkJCWV4cG9ydHNbImRlZmF1bHQiXSA9IGZ1bmN0aW9uIChvYmopIHsKCQkJCXJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7CgkJCQkJImRlZmF1bHQiOiBvYmoKCQkJCX07CgkJCX07CgoJCQlleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOwoKCQkJLyoqKi8gfSwKCQkvKiAzICovCgkJLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7CgoJCQkndXNlIHN0cmljdCc7CgoJCQl2YXIgX2ludGVyb3BSZXF1aXJlRGVmYXVsdCA9IF9fd2VicGFja19yZXF1aXJlX18oMilbJ2RlZmF1bHQnXTsKCgkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgkJCWV4cG9ydHMuSGFuZGxlYmFyc0Vudmlyb25tZW50ID0gSGFuZGxlYmFyc0Vudmlyb25tZW50OwoKCQkJdmFyIF91dGlscyA9IF9fd2VicGFja19yZXF1aXJlX18oNCk7CgoJCQl2YXIgX2V4Y2VwdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oNSk7CgoJCQl2YXIgX2V4Y2VwdGlvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9leGNlcHRpb24pOwoKCQkJdmFyIF9oZWxwZXJzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg2KTsKCgkJCXZhciBfZGVjb3JhdG9ycyA9IF9fd2VicGFja19yZXF1aXJlX18oMTQpOwoKCQkJdmFyIF9sb2dnZXIgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDE2KTsKCgkJCXZhciBfbG9nZ2VyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2xvZ2dlcik7CgoJCQl2YXIgVkVSU0lPTiA9ICc0LjAuNSc7CgkJCWV4cG9ydHMuVkVSU0lPTiA9IFZFUlNJT047CgkJCXZhciBDT01QSUxFUl9SRVZJU0lPTiA9IDc7CgoJCQlleHBvcnRzLkNPTVBJTEVSX1JFVklTSU9OID0gQ09NUElMRVJfUkVWSVNJT047CgkJCXZhciBSRVZJU0lPTl9DSEFOR0VTID0gewoJCQkJMTogJzw9IDEuMC5yYy4yJywgLy8gMS4wLnJjLjIgaXMgYWN0dWFsbHkgcmV2MiBidXQgZG9lc24ndCByZXBvcnQgaXQKCQkJCTI6ICc9PSAxLjAuMC1yYy4zJywKCQkJCTM6ICc9PSAxLjAuMC1yYy40JywKCQkJCTQ6ICc9PSAxLngueCcsCgkJCQk1OiAnPT0gMi4wLjAtYWxwaGEueCcsCgkJCQk2OiAnPj0gMi4wLjAtYmV0YS4xJywKCQkJCTc6ICc+PSA0LjAuMCcKCQkJfTsKCgkJCWV4cG9ydHMuUkVWSVNJT05fQ0hBTkdFUyA9IFJFVklTSU9OX0NIQU5HRVM7CgkJCXZhciBvYmplY3RUeXBlID0gJ1tvYmplY3QgT2JqZWN0XSc7CgoJCQlmdW5jdGlvbiBIYW5kbGViYXJzRW52aXJvbm1lbnQoaGVscGVycywgcGFydGlhbHMsIGRlY29yYXRvcnMpIHsKCQkJCXRoaXMuaGVscGVycyA9IGhlbHBlcnMgfHwge307CgkJCQl0aGlzLnBhcnRpYWxzID0gcGFydGlhbHMgfHwge307CgkJCQl0aGlzLmRlY29yYXRvcnMgPSBkZWNvcmF0b3JzIHx8IHt9OwoKCQkJCV9oZWxwZXJzLnJlZ2lzdGVyRGVmYXVsdEhlbHBlcnModGhpcyk7CgkJCQlfZGVjb3JhdG9ycy5yZWdpc3RlckRlZmF1bHREZWNvcmF0b3JzKHRoaXMpOwoJCQl9CgoJCQlIYW5kbGViYXJzRW52aXJvbm1lbnQucHJvdG90eXBlID0gewoJCQkJY29uc3RydWN0b3I6IEhhbmRsZWJhcnNFbnZpcm9ubWVudCwKCgkJCQlsb2dnZXI6IF9sb2dnZXIyWydkZWZhdWx0J10sCgkJCQlsb2c6IF9sb2dnZXIyWydkZWZhdWx0J10ubG9nLAoKCQkJCXJlZ2lzdGVySGVscGVyOiBmdW5jdGlvbiByZWdpc3RlckhlbHBlcihuYW1lLCBmbikgewoJCQkJCWlmIChfdXRpbHMudG9TdHJpbmcuY2FsbChuYW1lKSA9PT0gb2JqZWN0VHlwZSkgewoJCQkJCQlpZiAoZm4pIHsKCQkJCQkJCXRocm93IG5ldyBfZXhjZXB0aW9uMlsnZGVmYXVsdCddKCdBcmcgbm90IHN1cHBvcnRlZCB3aXRoIG11bHRpcGxlIGhlbHBlcnMnKTsKCQkJCQkJfQoJCQkJCQlfdXRpbHMuZXh0ZW5kKHRoaXMuaGVscGVycywgbmFtZSk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJdGhpcy5oZWxwZXJzW25hbWVdID0gZm47CgkJCQkJfQoJCQkJfSwKCQkJCXVucmVnaXN0ZXJIZWxwZXI6IGZ1bmN0aW9uIHVucmVnaXN0ZXJIZWxwZXIobmFtZSkgewoJCQkJCWRlbGV0ZSB0aGlzLmhlbHBlcnNbbmFtZV07CgkJCQl9LAoKCQkJCXJlZ2lzdGVyUGFydGlhbDogZnVuY3Rpb24gcmVnaXN0ZXJQYXJ0aWFsKG5hbWUsIHBhcnRpYWwpIHsKCQkJCQlpZiAoX3V0aWxzLnRvU3RyaW5nLmNhbGwobmFtZSkgPT09IG9iamVjdFR5cGUpIHsKCQkJCQkJX3V0aWxzLmV4dGVuZCh0aGlzLnBhcnRpYWxzLCBuYW1lKTsKCQkJCQl9IGVsc2UgewoJCQkJCQlpZiAodHlwZW9mIHBhcnRpYWwgPT09ICd1bmRlZmluZWQnKSB7CgkJCQkJCQl0aHJvdyBuZXcgX2V4Y2VwdGlvbjJbJ2RlZmF1bHQnXSgnQXR0ZW1wdGluZyB0byByZWdpc3RlciBhIHBhcnRpYWwgY2FsbGVkICInICsgbmFtZSArICciIGFzIHVuZGVmaW5lZCcpOwoJCQkJCQl9CgkJCQkJCXRoaXMucGFydGlhbHNbbmFtZV0gPSBwYXJ0aWFsOwoJCQkJCX0KCQkJCX0sCgkJCQl1bnJlZ2lzdGVyUGFydGlhbDogZnVuY3Rpb24gdW5yZWdpc3RlclBhcnRpYWwobmFtZSkgewoJCQkJCWRlbGV0ZSB0aGlzLnBhcnRpYWxzW25hbWVdOwoJCQkJfSwKCgkJCQlyZWdpc3RlckRlY29yYXRvcjogZnVuY3Rpb24gcmVnaXN0ZXJEZWNvcmF0b3IobmFtZSwgZm4pIHsKCQkJCQlpZiAoX3V0aWxzLnRvU3RyaW5nLmNhbGwobmFtZSkgPT09IG9iamVjdFR5cGUpIHsKCQkJCQkJaWYgKGZuKSB7CgkJCQkJCQl0aHJvdyBuZXcgX2V4Y2VwdGlvbjJbJ2RlZmF1bHQnXSgnQXJnIG5vdCBzdXBwb3J0ZWQgd2l0aCBtdWx0aXBsZSBkZWNvcmF0b3JzJyk7CgkJCQkJCX0KCQkJCQkJX3V0aWxzLmV4dGVuZCh0aGlzLmRlY29yYXRvcnMsIG5hbWUpOwoJCQkJCX0gZWxzZSB7CgkJCQkJCXRoaXMuZGVjb3JhdG9yc1tuYW1lXSA9IGZuOwoJCQkJCX0KCQkJCX0sCgkJCQl1bnJlZ2lzdGVyRGVjb3JhdG9yOiBmdW5jdGlvbiB1bnJlZ2lzdGVyRGVjb3JhdG9yKG5hbWUpIHsKCQkJCQlkZWxldGUgdGhpcy5kZWNvcmF0b3JzW25hbWVdOwoJCQkJfQoJCQl9OwoKCQkJdmFyIGxvZyA9IF9sb2dnZXIyWydkZWZhdWx0J10ubG9nOwoKCQkJZXhwb3J0cy5sb2cgPSBsb2c7CgkJCWV4cG9ydHMuY3JlYXRlRnJhbWUgPSBfdXRpbHMuY3JlYXRlRnJhbWU7CgkJCWV4cG9ydHMubG9nZ2VyID0gX2xvZ2dlcjJbJ2RlZmF1bHQnXTsKCgkJCS8qKiovIH0sCgkJLyogNCAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCQkJZXhwb3J0cy5leHRlbmQgPSBleHRlbmQ7CgkJCWV4cG9ydHMuaW5kZXhPZiA9IGluZGV4T2Y7CgkJCWV4cG9ydHMuZXNjYXBlRXhwcmVzc2lvbiA9IGVzY2FwZUV4cHJlc3Npb247CgkJCWV4cG9ydHMuaXNFbXB0eSA9IGlzRW1wdHk7CgkJCWV4cG9ydHMuY3JlYXRlRnJhbWUgPSBjcmVhdGVGcmFtZTsKCQkJZXhwb3J0cy5ibG9ja1BhcmFtcyA9IGJsb2NrUGFyYW1zOwoJCQlleHBvcnRzLmFwcGVuZENvbnRleHRQYXRoID0gYXBwZW5kQ29udGV4dFBhdGg7CgkJCXZhciBlc2NhcGUgPSB7CgkJCQknJic6ICcmYW1wOycsCgkJCQknPCc6ICcmbHQ7JywKCQkJCSc+JzogJyZndDsnLAoJCQkJJyInOiAnJnF1b3Q7JywKCQkJCSInIjogJyYjeDI3OycsCgkJCQknYCc6ICcmI3g2MDsnLAoJCQkJJz0nOiAnJiN4M0Q7JwoJCQl9OwoKCQkJdmFyIGJhZENoYXJzID0gL1smPD4iJ2A9XS9nLAoJCQkJcG9zc2libGUgPSAvWyY8PiInYD1dLzsKCgkJCWZ1bmN0aW9uIGVzY2FwZUNoYXIoY2hyKSB7CgkJCQlyZXR1cm4gZXNjYXBlW2Nocl07CgkJCX0KCgkJCWZ1bmN0aW9uIGV4dGVuZChvYmogLyogLCAuLi5zb3VyY2UgKi8pIHsKCQkJCWZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7CgkJCQkJZm9yICh2YXIga2V5IGluIGFyZ3VtZW50c1tpXSkgewoJCQkJCQlpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGFyZ3VtZW50c1tpXSwga2V5KSkgewoJCQkJCQkJb2JqW2tleV0gPSBhcmd1bWVudHNbaV1ba2V5XTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCgkJCQlyZXR1cm4gb2JqOwoJCQl9CgoJCQl2YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nOwoKCQkJZXhwb3J0cy50b1N0cmluZyA9IHRvU3RyaW5nOwoJCQkvLyBTb3VyY2VkIGZyb20gbG9kYXNoCgkJCS8vIGh0dHBzOi8vZ2l0aHViLmNvbS9iZXN0aWVqcy9sb2Rhc2gvYmxvYi9tYXN0ZXIvTElDRU5TRS50eHQKCQkJLyogZXNsaW50LWRpc2FibGUgZnVuYy1zdHlsZSAqLwoJCQl2YXIgaXNGdW5jdGlvbiA9IGZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWUpIHsKCQkJCXJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbic7CgkJCX07CgkJCS8vIGZhbGxiYWNrIGZvciBvbGRlciB2ZXJzaW9ucyBvZiBDaHJvbWUgYW5kIFNhZmFyaQoJCQkvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLwoJCQlpZiAoaXNGdW5jdGlvbigveC8pKSB7CgkJCQlleHBvcnRzLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gKHZhbHVlKSB7CgkJCQkJcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0b1N0cmluZy5jYWxsKHZhbHVlKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJzsKCQkJCX07CgkJCX0KCQkJZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjsKCgkJCS8qIGVzbGludC1lbmFibGUgZnVuYy1zdHlsZSAqLwoKCQkJLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8KCQkJdmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uICh2YWx1ZSkgewoJCQkJcmV0dXJuIHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgPyB0b1N0cmluZy5jYWxsKHZhbHVlKSA9PT0gJ1tvYmplY3QgQXJyYXldJyA6IGZhbHNlOwoJCQl9OwoKCQkJZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTsKCQkJLy8gT2xkZXIgSUUgdmVyc2lvbnMgZG8gbm90IGRpcmVjdGx5IHN1cHBvcnQgaW5kZXhPZiBzbyB3ZSBtdXN0IGltcGxlbWVudCBvdXIgb3duLCBzYWRseS4KCgkJCWZ1bmN0aW9uIGluZGV4T2YoYXJyYXksIHZhbHVlKSB7CgkJCQlmb3IgKHZhciBpID0gMCwgbGVuID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHsKCQkJCQlpZiAoYXJyYXlbaV0gPT09IHZhbHVlKSB7CgkJCQkJCXJldHVybiBpOwoJCQkJCX0KCQkJCX0KCQkJCXJldHVybiAtMTsKCQkJfQoKCQkJZnVuY3Rpb24gZXNjYXBlRXhwcmVzc2lvbihzdHJpbmcpIHsKCQkJCWlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykgewoJCQkJCS8vIGRvbid0IGVzY2FwZSBTYWZlU3RyaW5ncywgc2luY2UgdGhleSdyZSBhbHJlYWR5IHNhZmUKCQkJCQlpZiAoc3RyaW5nICYmIHN0cmluZy50b0hUTUwpIHsKCQkJCQkJcmV0dXJuIHN0cmluZy50b0hUTUwoKTsKCQkJCQl9IGVsc2UgaWYgKHN0cmluZyA9PSBudWxsKSB7CgkJCQkJCXJldHVybiAnJzsKCQkJCQl9IGVsc2UgaWYgKCFzdHJpbmcpIHsKCQkJCQkJcmV0dXJuIHN0cmluZyArICcnOwoJCQkJCX0KCgkJCQkJLy8gRm9yY2UgYSBzdHJpbmcgY29udmVyc2lvbiBhcyB0aGlzIHdpbGwgYmUgZG9uZSBieSB0aGUgYXBwZW5kIHJlZ2FyZGxlc3MgYW5kCgkJCQkJLy8gdGhlIHJlZ2V4IHRlc3Qgd2lsbCBkbyB0aGlzIHRyYW5zcGFyZW50bHkgYmVoaW5kIHRoZSBzY2VuZXMsIGNhdXNpbmcgaXNzdWVzIGlmCgkJCQkJLy8gYW4gb2JqZWN0J3MgdG8gc3RyaW5nIGhhcyBlc2NhcGVkIGNoYXJhY3RlcnMgaW4gaXQuCgkJCQkJc3RyaW5nID0gJycgKyBzdHJpbmc7CgkJCQl9CgoJCQkJaWYgKCFwb3NzaWJsZS50ZXN0KHN0cmluZykpIHsKCQkJCQlyZXR1cm4gc3RyaW5nOwoJCQkJfQoJCQkJcmV0dXJuIHN0cmluZy5yZXBsYWNlKGJhZENoYXJzLCBlc2NhcGVDaGFyKTsKCQkJfQoKCQkJZnVuY3Rpb24gaXNFbXB0eSh2YWx1ZSkgewoJCQkJaWYgKCF2YWx1ZSAmJiB2YWx1ZSAhPT0gMCkgewoJCQkJCXJldHVybiB0cnVlOwoJCQkJfSBlbHNlIGlmIChpc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5sZW5ndGggPT09IDApIHsKCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCX0gZWxzZSB7CgkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoJCQl9CgoJCQlmdW5jdGlvbiBjcmVhdGVGcmFtZShvYmplY3QpIHsKCQkJCXZhciBmcmFtZSA9IGV4dGVuZCh7fSwgb2JqZWN0KTsKCQkJCWZyYW1lLl9wYXJlbnQgPSBvYmplY3Q7CgkJCQlyZXR1cm4gZnJhbWU7CgkJCX0KCgkJCWZ1bmN0aW9uIGJsb2NrUGFyYW1zKHBhcmFtcywgaWRzKSB7CgkJCQlwYXJhbXMucGF0aCA9IGlkczsKCQkJCXJldHVybiBwYXJhbXM7CgkJCX0KCgkJCWZ1bmN0aW9uIGFwcGVuZENvbnRleHRQYXRoKGNvbnRleHRQYXRoLCBpZCkgewoJCQkJcmV0dXJuIChjb250ZXh0UGF0aCA/IGNvbnRleHRQYXRoICsgJy4nIDogJycpICsgaWQ7CgkJCX0KCgkJCS8qKiovIH0sCgkJLyogNSAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCgkJCXZhciBlcnJvclByb3BzID0gWydkZXNjcmlwdGlvbicsICdmaWxlTmFtZScsICdsaW5lTnVtYmVyJywgJ21lc3NhZ2UnLCAnbmFtZScsICdudW1iZXInLCAnc3RhY2snXTsKCgkJCWZ1bmN0aW9uIEV4Y2VwdGlvbihtZXNzYWdlLCBub2RlKSB7CgkJCQl2YXIgbG9jID0gbm9kZSAmJiBub2RlLmxvYywKCQkJCQlsaW5lID0gdW5kZWZpbmVkLAoJCQkJCWNvbHVtbiA9IHVuZGVmaW5lZDsKCQkJCWlmIChsb2MpIHsKCQkJCQlsaW5lID0gbG9jLnN0YXJ0LmxpbmU7CgkJCQkJY29sdW1uID0gbG9jLnN0YXJ0LmNvbHVtbjsKCgkJCQkJbWVzc2FnZSArPSAnIC0gJyArIGxpbmUgKyAnOicgKyBjb2x1bW47CgkJCQl9CgoJCQkJdmFyIHRtcCA9IEVycm9yLnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsIG1lc3NhZ2UpOwoKCQkJCS8vIFVuZm9ydHVuYXRlbHkgZXJyb3JzIGFyZSBub3QgZW51bWVyYWJsZSBpbiBDaHJvbWUgKGF0IGxlYXN0KSwgc28gYGZvciBwcm9wIGluIHRtcGAgZG9lc24ndCB3b3JrLgoJCQkJZm9yICh2YXIgaWR4ID0gMDsgaWR4IDwgZXJyb3JQcm9wcy5sZW5ndGg7IGlkeCsrKSB7CgkJCQkJdGhpc1tlcnJvclByb3BzW2lkeF1dID0gdG1wW2Vycm9yUHJvcHNbaWR4XV07CgkJCQl9CgoJCQkJLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi8KCQkJCWlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkgewoJCQkJCUVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIEV4Y2VwdGlvbik7CgkJCQl9CgoJCQkJaWYgKGxvYykgewoJCQkJCXRoaXMubGluZU51bWJlciA9IGxpbmU7CgkJCQkJdGhpcy5jb2x1bW4gPSBjb2x1bW47CgkJCQl9CgkJCX0KCgkJCUV4Y2VwdGlvbi5wcm90b3R5cGUgPSBuZXcgRXJyb3IoKTsKCgkJCWV4cG9ydHNbJ2RlZmF1bHQnXSA9IEV4Y2VwdGlvbjsKCQkJbW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107CgoJCQkvKioqLyB9LAoJCS8qIDYgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHsKCgkJCSd1c2Ugc3RyaWN0JzsKCgkJCXZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKVsnZGVmYXVsdCddOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCQkJZXhwb3J0cy5yZWdpc3RlckRlZmF1bHRIZWxwZXJzID0gcmVnaXN0ZXJEZWZhdWx0SGVscGVyczsKCgkJCXZhciBfaGVscGVyc0Jsb2NrSGVscGVyTWlzc2luZyA9IF9fd2VicGFja19yZXF1aXJlX18oNyk7CgoJCQl2YXIgX2hlbHBlcnNCbG9ja0hlbHBlck1pc3NpbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaGVscGVyc0Jsb2NrSGVscGVyTWlzc2luZyk7CgoJCQl2YXIgX2hlbHBlcnNFYWNoID0gX193ZWJwYWNrX3JlcXVpcmVfXyg4KTsKCgkJCXZhciBfaGVscGVyc0VhY2gyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaGVscGVyc0VhY2gpOwoKCQkJdmFyIF9oZWxwZXJzSGVscGVyTWlzc2luZyA9IF9fd2VicGFja19yZXF1aXJlX18oOSk7CgoJCQl2YXIgX2hlbHBlcnNIZWxwZXJNaXNzaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2hlbHBlcnNIZWxwZXJNaXNzaW5nKTsKCgkJCXZhciBfaGVscGVyc0lmID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMCk7CgoJCQl2YXIgX2hlbHBlcnNJZjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9oZWxwZXJzSWYpOwoKCQkJdmFyIF9oZWxwZXJzTG9nID0gX193ZWJwYWNrX3JlcXVpcmVfXygxMSk7CgoJCQl2YXIgX2hlbHBlcnNMb2cyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaGVscGVyc0xvZyk7CgoJCQl2YXIgX2hlbHBlcnNMb29rdXAgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEyKTsKCgkJCXZhciBfaGVscGVyc0xvb2t1cDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9oZWxwZXJzTG9va3VwKTsKCgkJCXZhciBfaGVscGVyc1dpdGggPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEzKTsKCgkJCXZhciBfaGVscGVyc1dpdGgyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaGVscGVyc1dpdGgpOwoKCQkJZnVuY3Rpb24gcmVnaXN0ZXJEZWZhdWx0SGVscGVycyhpbnN0YW5jZSkgewoJCQkJX2hlbHBlcnNCbG9ja0hlbHBlck1pc3NpbmcyWydkZWZhdWx0J10oaW5zdGFuY2UpOwoJCQkJX2hlbHBlcnNFYWNoMlsnZGVmYXVsdCddKGluc3RhbmNlKTsKCQkJCV9oZWxwZXJzSGVscGVyTWlzc2luZzJbJ2RlZmF1bHQnXShpbnN0YW5jZSk7CgkJCQlfaGVscGVyc0lmMlsnZGVmYXVsdCddKGluc3RhbmNlKTsKCQkJCV9oZWxwZXJzTG9nMlsnZGVmYXVsdCddKGluc3RhbmNlKTsKCQkJCV9oZWxwZXJzTG9va3VwMlsnZGVmYXVsdCddKGluc3RhbmNlKTsKCQkJCV9oZWxwZXJzV2l0aDJbJ2RlZmF1bHQnXShpbnN0YW5jZSk7CgkJCX0KCgkJCS8qKiovIH0sCgkJLyogNyAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCgkJCXZhciBfdXRpbHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpOwoKCQkJZXhwb3J0c1snZGVmYXVsdCddID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7CgkJCQlpbnN0YW5jZS5yZWdpc3RlckhlbHBlcignYmxvY2tIZWxwZXJNaXNzaW5nJywgZnVuY3Rpb24gKGNvbnRleHQsIG9wdGlvbnMpIHsKCQkJCQl2YXIgaW52ZXJzZSA9IG9wdGlvbnMuaW52ZXJzZSwKCQkJCQkJZm4gPSBvcHRpb25zLmZuOwoKCQkJCQlpZiAoY29udGV4dCA9PT0gdHJ1ZSkgewoJCQkJCQlyZXR1cm4gZm4odGhpcyk7CgkJCQkJfSBlbHNlIGlmIChjb250ZXh0ID09PSBmYWxzZSB8fCBjb250ZXh0ID09IG51bGwpIHsKCQkJCQkJcmV0dXJuIGludmVyc2UodGhpcyk7CgkJCQkJfSBlbHNlIGlmIChfdXRpbHMuaXNBcnJheShjb250ZXh0KSkgewoJCQkJCQlpZiAoY29udGV4dC5sZW5ndGggPiAwKSB7CgkJCQkJCQlpZiAob3B0aW9ucy5pZHMpIHsKCQkJCQkJCQlvcHRpb25zLmlkcyA9IFtvcHRpb25zLm5hbWVdOwoJCQkJCQkJfQoKCQkJCQkJCXJldHVybiBpbnN0YW5jZS5oZWxwZXJzLmVhY2goY29udGV4dCwgb3B0aW9ucyk7CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQlyZXR1cm4gaW52ZXJzZSh0aGlzKTsKCQkJCQkJfQoJCQkJCX0gZWxzZSB7CgkJCQkJCWlmIChvcHRpb25zLmRhdGEgJiYgb3B0aW9ucy5pZHMpIHsKCQkJCQkJCXZhciBkYXRhID0gX3V0aWxzLmNyZWF0ZUZyYW1lKG9wdGlvbnMuZGF0YSk7CgkJCQkJCQlkYXRhLmNvbnRleHRQYXRoID0gX3V0aWxzLmFwcGVuZENvbnRleHRQYXRoKG9wdGlvbnMuZGF0YS5jb250ZXh0UGF0aCwgb3B0aW9ucy5uYW1lKTsKCQkJCQkJCW9wdGlvbnMgPSB7IGRhdGE6IGRhdGEgfTsKCQkJCQkJfQoKCQkJCQkJcmV0dXJuIGZuKGNvbnRleHQsIG9wdGlvbnMpOwoJCQkJCX0KCQkJCX0pOwoJCQl9OwoKCQkJbW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107CgoJCQkvKioqLyB9LAoJCS8qIDggKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHsKCgkJCSd1c2Ugc3RyaWN0JzsKCgkJCXZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKVsnZGVmYXVsdCddOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCgkJCXZhciBfdXRpbHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpOwoKCQkJdmFyIF9leGNlcHRpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpOwoKCQkJdmFyIF9leGNlcHRpb24yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZXhjZXB0aW9uKTsKCgkJCWV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZ1bmN0aW9uIChpbnN0YW5jZSkgewoJCQkJaW5zdGFuY2UucmVnaXN0ZXJIZWxwZXIoJ2VhY2gnLCBmdW5jdGlvbiAoY29udGV4dCwgb3B0aW9ucykgewoJCQkJCWlmICghb3B0aW9ucykgewoJCQkJCQl0aHJvdyBuZXcgX2V4Y2VwdGlvbjJbJ2RlZmF1bHQnXSgnTXVzdCBwYXNzIGl0ZXJhdG9yIHRvICNlYWNoJyk7CgkJCQkJfQoKCQkJCQl2YXIgZm4gPSBvcHRpb25zLmZuLAoJCQkJCQlpbnZlcnNlID0gb3B0aW9ucy5pbnZlcnNlLAoJCQkJCQlpID0gMCwKCQkJCQkJcmV0ID0gJycsCgkJCQkJCWRhdGEgPSB1bmRlZmluZWQsCgkJCQkJCWNvbnRleHRQYXRoID0gdW5kZWZpbmVkOwoKCQkJCQlpZiAob3B0aW9ucy5kYXRhICYmIG9wdGlvbnMuaWRzKSB7CgkJCQkJCWNvbnRleHRQYXRoID0gX3V0aWxzLmFwcGVuZENvbnRleHRQYXRoKG9wdGlvbnMuZGF0YS5jb250ZXh0UGF0aCwgb3B0aW9ucy5pZHNbMF0pICsgJy4nOwoJCQkJCX0KCgkJCQkJaWYgKF91dGlscy5pc0Z1bmN0aW9uKGNvbnRleHQpKSB7CgkJCQkJCWNvbnRleHQgPSBjb250ZXh0LmNhbGwodGhpcyk7CgkJCQkJfQoKCQkJCQlpZiAob3B0aW9ucy5kYXRhKSB7CgkJCQkJCWRhdGEgPSBfdXRpbHMuY3JlYXRlRnJhbWUob3B0aW9ucy5kYXRhKTsKCQkJCQl9CgoJCQkJCWZ1bmN0aW9uIGV4ZWNJdGVyYXRpb24oZmllbGQsIGluZGV4LCBsYXN0KSB7CgkJCQkJCWlmIChkYXRhKSB7CgkJCQkJCQlkYXRhLmtleSA9IGZpZWxkOwoJCQkJCQkJZGF0YS5pbmRleCA9IGluZGV4OwoJCQkJCQkJZGF0YS5maXJzdCA9IGluZGV4ID09PSAwOwoJCQkJCQkJZGF0YS5sYXN0ID0gISFsYXN0OwoKCQkJCQkJCWlmIChjb250ZXh0UGF0aCkgewoJCQkJCQkJCWRhdGEuY29udGV4dFBhdGggPSBjb250ZXh0UGF0aCArIGZpZWxkOwoJCQkJCQkJfQoJCQkJCQl9CgoJCQkJCQlyZXQgPSByZXQgKyBmbihjb250ZXh0W2ZpZWxkXSwgewoJCQkJCQkJZGF0YTogZGF0YSwKCQkJCQkJCWJsb2NrUGFyYW1zOiBfdXRpbHMuYmxvY2tQYXJhbXMoW2NvbnRleHRbZmllbGRdLCBmaWVsZF0sIFtjb250ZXh0UGF0aCArIGZpZWxkLCBudWxsXSkKCQkJCQkJfSk7CgkJCQkJfQoKCQkJCQlpZiAoY29udGV4dCAmJiB0eXBlb2YgY29udGV4dCA9PT0gJ29iamVjdCcpIHsKCQkJCQkJaWYgKF91dGlscy5pc0FycmF5KGNvbnRleHQpKSB7CgkJCQkJCQlmb3IgKHZhciBqID0gY29udGV4dC5sZW5ndGg7IGkgPCBqOyBpKyspIHsKCQkJCQkJCQlpZiAoaSBpbiBjb250ZXh0KSB7CgkJCQkJCQkJCWV4ZWNJdGVyYXRpb24oaSwgaSwgaSA9PT0gY29udGV4dC5sZW5ndGggLSAxKTsKCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQl2YXIgcHJpb3JLZXkgPSB1bmRlZmluZWQ7CgoJCQkJCQkJZm9yICh2YXIga2V5IGluIGNvbnRleHQpIHsKCQkJCQkJCQlpZiAoY29udGV4dC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7CgkJCQkJCQkJCS8vIFdlJ3JlIHJ1bm5pbmcgdGhlIGl0ZXJhdGlvbnMgb25lIHN0ZXAgb3V0IG9mIHN5bmMgc28gd2UgY2FuIGRldGVjdAoJCQkJCQkJCQkvLyB0aGUgbGFzdCBpdGVyYXRpb24gd2l0aG91dCBoYXZlIHRvIHNjYW4gdGhlIG9iamVjdCB0d2ljZSBhbmQgY3JlYXRlCgkJCQkJCQkJCS8vIGFuIGl0ZXJtZWRpYXRlIGtleXMgYXJyYXkuCgkJCQkJCQkJCWlmIChwcmlvcktleSAhPT0gdW5kZWZpbmVkKSB7CgkJCQkJCQkJCQlleGVjSXRlcmF0aW9uKHByaW9yS2V5LCBpIC0gMSk7CgkJCQkJCQkJCX0KCQkJCQkJCQkJcHJpb3JLZXkgPSBrZXk7CgkJCQkJCQkJCWkrKzsKCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCQlpZiAocHJpb3JLZXkgIT09IHVuZGVmaW5lZCkgewoJCQkJCQkJCWV4ZWNJdGVyYXRpb24ocHJpb3JLZXksIGkgLSAxLCB0cnVlKTsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCgkJCQkJaWYgKGkgPT09IDApIHsKCQkJCQkJcmV0ID0gaW52ZXJzZSh0aGlzKTsKCQkJCQl9CgoJCQkJCXJldHVybiByZXQ7CgkJCQl9KTsKCQkJfTsKCgkJCW1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOwoKCQkJLyoqKi8gfSwKCQkvKiA5ICovCgkJLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7CgoJCQkndXNlIHN0cmljdCc7CgoJCQl2YXIgX2ludGVyb3BSZXF1aXJlRGVmYXVsdCA9IF9fd2VicGFja19yZXF1aXJlX18oMilbJ2RlZmF1bHQnXTsKCgkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgoJCQl2YXIgX2V4Y2VwdGlvbiA9IF9fd2VicGFja19yZXF1aXJlX18oNSk7CgoJCQl2YXIgX2V4Y2VwdGlvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9leGNlcHRpb24pOwoKCQkJZXhwb3J0c1snZGVmYXVsdCddID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7CgkJCQlpbnN0YW5jZS5yZWdpc3RlckhlbHBlcignaGVscGVyTWlzc2luZycsIGZ1bmN0aW9uICgpIC8qIFthcmdzLCBdb3B0aW9ucyAqL3sKCQkJCQlpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkgewoJCQkJCQkvLyBBIG1pc3NpbmcgZmllbGQgaW4gYSB7e2Zvb319IGNvbnN0cnVjdC4KCQkJCQkJcmV0dXJuIHVuZGVmaW5lZDsKCQkJCQl9IGVsc2UgewoJCQkJCQkvLyBTb21lb25lIGlzIGFjdHVhbGx5IHRyeWluZyB0byBjYWxsIHNvbWV0aGluZywgYmxvdyB1cC4KCQkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJ01pc3NpbmcgaGVscGVyOiAiJyArIGFyZ3VtZW50c1thcmd1bWVudHMubGVuZ3RoIC0gMV0ubmFtZSArICciJyk7CgkJCQkJfQoJCQkJfSk7CgkJCX07CgoJCQltb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsKCgkJCS8qKiovIH0sCgkJLyogMTAgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHsKCgkJCSd1c2Ugc3RyaWN0JzsKCgkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgoJCQl2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTsKCgkJCWV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZ1bmN0aW9uIChpbnN0YW5jZSkgewoJCQkJaW5zdGFuY2UucmVnaXN0ZXJIZWxwZXIoJ2lmJywgZnVuY3Rpb24gKGNvbmRpdGlvbmFsLCBvcHRpb25zKSB7CgkJCQkJaWYgKF91dGlscy5pc0Z1bmN0aW9uKGNvbmRpdGlvbmFsKSkgewoJCQkJCQljb25kaXRpb25hbCA9IGNvbmRpdGlvbmFsLmNhbGwodGhpcyk7CgkJCQkJfQoKCQkJCQkvLyBEZWZhdWx0IGJlaGF2aW9yIGlzIHRvIHJlbmRlciB0aGUgcG9zaXRpdmUgcGF0aCBpZiB0aGUgdmFsdWUgaXMgdHJ1dGh5IGFuZCBub3QgZW1wdHkuCgkJCQkJLy8gVGhlIGBpbmNsdWRlWmVyb2Agb3B0aW9uIG1heSBiZSBzZXQgdG8gdHJlYXQgdGhlIGNvbmR0aW9uYWwgYXMgcHVyZWx5IG5vdCBlbXB0eSBiYXNlZCBvbiB0aGUKCQkJCQkvLyBiZWhhdmlvciBvZiBpc0VtcHR5LiBFZmZlY3RpdmVseSB0aGlzIGRldGVybWluZXMgaWYgMCBpcyBoYW5kbGVkIGJ5IHRoZSBwb3NpdGl2ZSBwYXRoIG9yIG5lZ2F0aXZlLgoJCQkJCWlmICghb3B0aW9ucy5oYXNoLmluY2x1ZGVaZXJvICYmICFjb25kaXRpb25hbCB8fCBfdXRpbHMuaXNFbXB0eShjb25kaXRpb25hbCkpIHsKCQkJCQkJcmV0dXJuIG9wdGlvbnMuaW52ZXJzZSh0aGlzKTsKCQkJCQl9IGVsc2UgewoJCQkJCQlyZXR1cm4gb3B0aW9ucy5mbih0aGlzKTsKCQkJCQl9CgkJCQl9KTsKCgkJCQlpbnN0YW5jZS5yZWdpc3RlckhlbHBlcigndW5sZXNzJywgZnVuY3Rpb24gKGNvbmRpdGlvbmFsLCBvcHRpb25zKSB7CgkJCQkJcmV0dXJuIGluc3RhbmNlLmhlbHBlcnNbJ2lmJ10uY2FsbCh0aGlzLCBjb25kaXRpb25hbCwgeyBmbjogb3B0aW9ucy5pbnZlcnNlLCBpbnZlcnNlOiBvcHRpb25zLmZuLCBoYXNoOiBvcHRpb25zLmhhc2ggfSk7CgkJCQl9KTsKCQkJfTsKCgkJCW1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOwoKCQkJLyoqKi8gfSwKCQkvKiAxMSAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCgkJCWV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZ1bmN0aW9uIChpbnN0YW5jZSkgewoJCQkJaW5zdGFuY2UucmVnaXN0ZXJIZWxwZXIoJ2xvZycsIGZ1bmN0aW9uICgpIC8qIG1lc3NhZ2UsIG9wdGlvbnMgKi97CgkJCQkJdmFyIGFyZ3MgPSBbdW5kZWZpbmVkXSwKCQkJCQkJb3B0aW9ucyA9IGFyZ3VtZW50c1thcmd1bWVudHMubGVuZ3RoIC0gMV07CgkJCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoIC0gMTsgaSsrKSB7CgkJCQkJCWFyZ3MucHVzaChhcmd1bWVudHNbaV0pOwoJCQkJCX0KCgkJCQkJdmFyIGxldmVsID0gMTsKCQkJCQlpZiAob3B0aW9ucy5oYXNoLmxldmVsICE9IG51bGwpIHsKCQkJCQkJbGV2ZWwgPSBvcHRpb25zLmhhc2gubGV2ZWw7CgkJCQkJfSBlbHNlIGlmIChvcHRpb25zLmRhdGEgJiYgb3B0aW9ucy5kYXRhLmxldmVsICE9IG51bGwpIHsKCQkJCQkJbGV2ZWwgPSBvcHRpb25zLmRhdGEubGV2ZWw7CgkJCQkJfQoJCQkJCWFyZ3NbMF0gPSBsZXZlbDsKCgkJCQkJaW5zdGFuY2UubG9nLmFwcGx5KGluc3RhbmNlLCBhcmdzKTsKCQkJCX0pOwoJCQl9OwoKCQkJbW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107CgoJCQkvKioqLyB9LAoJCS8qIDEyICovCgkJLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7CgoJCQkndXNlIHN0cmljdCc7CgoJCQlleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOwoKCQkJZXhwb3J0c1snZGVmYXVsdCddID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7CgkJCQlpbnN0YW5jZS5yZWdpc3RlckhlbHBlcignbG9va3VwJywgZnVuY3Rpb24gKG9iaiwgZmllbGQpIHsKCQkJCQlyZXR1cm4gb2JqICYmIG9ialtmaWVsZF07CgkJCQl9KTsKCQkJfTsKCgkJCW1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOwoKCQkJLyoqKi8gfSwKCQkvKiAxMyAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsKCgkJCXZhciBfdXRpbHMgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDQpOwoKCQkJZXhwb3J0c1snZGVmYXVsdCddID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7CgkJCQlpbnN0YW5jZS5yZWdpc3RlckhlbHBlcignd2l0aCcsIGZ1bmN0aW9uIChjb250ZXh0LCBvcHRpb25zKSB7CgkJCQkJaWYgKF91dGlscy5pc0Z1bmN0aW9uKGNvbnRleHQpKSB7CgkJCQkJCWNvbnRleHQgPSBjb250ZXh0LmNhbGwodGhpcyk7CgkJCQkJfQoKCQkJCQl2YXIgZm4gPSBvcHRpb25zLmZuOwoKCQkJCQlpZiAoIV91dGlscy5pc0VtcHR5KGNvbnRleHQpKSB7CgkJCQkJCXZhciBkYXRhID0gb3B0aW9ucy5kYXRhOwoJCQkJCQlpZiAob3B0aW9ucy5kYXRhICYmIG9wdGlvbnMuaWRzKSB7CgkJCQkJCQlkYXRhID0gX3V0aWxzLmNyZWF0ZUZyYW1lKG9wdGlvbnMuZGF0YSk7CgkJCQkJCQlkYXRhLmNvbnRleHRQYXRoID0gX3V0aWxzLmFwcGVuZENvbnRleHRQYXRoKG9wdGlvbnMuZGF0YS5jb250ZXh0UGF0aCwgb3B0aW9ucy5pZHNbMF0pOwoJCQkJCQl9CgoJCQkJCQlyZXR1cm4gZm4oY29udGV4dCwgewoJCQkJCQkJZGF0YTogZGF0YSwKCQkJCQkJCWJsb2NrUGFyYW1zOiBfdXRpbHMuYmxvY2tQYXJhbXMoW2NvbnRleHRdLCBbZGF0YSAmJiBkYXRhLmNvbnRleHRQYXRoXSkKCQkJCQkJfSk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJcmV0dXJuIG9wdGlvbnMuaW52ZXJzZSh0aGlzKTsKCQkJCQl9CgkJCQl9KTsKCQkJfTsKCgkJCW1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOwoKCQkJLyoqKi8gfSwKCQkvKiAxNCAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJdmFyIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDIpWydkZWZhdWx0J107CgoJCQlleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOwoJCQlleHBvcnRzLnJlZ2lzdGVyRGVmYXVsdERlY29yYXRvcnMgPSByZWdpc3RlckRlZmF1bHREZWNvcmF0b3JzOwoKCQkJdmFyIF9kZWNvcmF0b3JzSW5saW5lID0gX193ZWJwYWNrX3JlcXVpcmVfXygxNSk7CgoJCQl2YXIgX2RlY29yYXRvcnNJbmxpbmUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZGVjb3JhdG9yc0lubGluZSk7CgoJCQlmdW5jdGlvbiByZWdpc3RlckRlZmF1bHREZWNvcmF0b3JzKGluc3RhbmNlKSB7CgkJCQlfZGVjb3JhdG9yc0lubGluZTJbJ2RlZmF1bHQnXShpbnN0YW5jZSk7CgkJCX0KCgkJCS8qKiovIH0sCgkJLyogMTUgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pIHsKCgkJCSd1c2Ugc3RyaWN0JzsKCgkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgoJCQl2YXIgX3V0aWxzID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTsKCgkJCWV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZ1bmN0aW9uIChpbnN0YW5jZSkgewoJCQkJaW5zdGFuY2UucmVnaXN0ZXJEZWNvcmF0b3IoJ2lubGluZScsIGZ1bmN0aW9uIChmbiwgcHJvcHMsIGNvbnRhaW5lciwgb3B0aW9ucykgewoJCQkJCXZhciByZXQgPSBmbjsKCQkJCQlpZiAoIXByb3BzLnBhcnRpYWxzKSB7CgkJCQkJCXByb3BzLnBhcnRpYWxzID0ge307CgkJCQkJCXJldCA9IGZ1bmN0aW9uIChjb250ZXh0LCBvcHRpb25zKSB7CgkJCQkJCQkvLyBDcmVhdGUgYSBuZXcgcGFydGlhbHMgc3RhY2sgZnJhbWUgcHJpb3IgdG8gZXhlYy4KCQkJCQkJCXZhciBvcmlnaW5hbCA9IGNvbnRhaW5lci5wYXJ0aWFsczsKCQkJCQkJCWNvbnRhaW5lci5wYXJ0aWFscyA9IF91dGlscy5leHRlbmQoe30sIG9yaWdpbmFsLCBwcm9wcy5wYXJ0aWFscyk7CgkJCQkJCQl2YXIgcmV0ID0gZm4oY29udGV4dCwgb3B0aW9ucyk7CgkJCQkJCQljb250YWluZXIucGFydGlhbHMgPSBvcmlnaW5hbDsKCQkJCQkJCXJldHVybiByZXQ7CgkJCQkJCX07CgkJCQkJfQoKCQkJCQlwcm9wcy5wYXJ0aWFsc1tvcHRpb25zLmFyZ3NbMF1dID0gb3B0aW9ucy5mbjsKCgkJCQkJcmV0dXJuIHJldDsKCQkJCX0pOwoJCQl9OwoKCQkJbW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107CgoJCQkvKioqLyB9LAoJCS8qIDE2ICovCgkJLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7CgoJCQkndXNlIHN0cmljdCc7CgoJCQlleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOwoKCQkJdmFyIF91dGlscyA9IF9fd2VicGFja19yZXF1aXJlX18oNCk7CgoJCQl2YXIgbG9nZ2VyID0gewoJCQkJbWV0aG9kTWFwOiBbJ2RlYnVnJywgJ2luZm8nLCAnd2FybicsICdlcnJvciddLAoJCQkJbGV2ZWw6ICdpbmZvJywKCgkJCQkvLyBNYXBzIGEgZ2l2ZW4gbGV2ZWwgdmFsdWUgdG8gdGhlIGBtZXRob2RNYXBgIGluZGV4ZXMgYWJvdmUuCgkJCQlsb29rdXBMZXZlbDogZnVuY3Rpb24gbG9va3VwTGV2ZWwobGV2ZWwpIHsKCQkJCQlpZiAodHlwZW9mIGxldmVsID09PSAnc3RyaW5nJykgewoJCQkJCQl2YXIgbGV2ZWxNYXAgPSBfdXRpbHMuaW5kZXhPZihsb2dnZXIubWV0aG9kTWFwLCBsZXZlbC50b0xvd2VyQ2FzZSgpKTsKCQkJCQkJaWYgKGxldmVsTWFwID49IDApIHsKCQkJCQkJCWxldmVsID0gbGV2ZWxNYXA7CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQlsZXZlbCA9IHBhcnNlSW50KGxldmVsLCAxMCk7CgkJCQkJCX0KCQkJCQl9CgoJCQkJCXJldHVybiBsZXZlbDsKCQkJCX0sCgoJCQkJLy8gQ2FuIGJlIG92ZXJyaWRkZW4gaW4gdGhlIGhvc3QgZW52aXJvbm1lbnQKCQkJCWxvZzogZnVuY3Rpb24gbG9nKGxldmVsKSB7CgkJCQkJbGV2ZWwgPSBsb2dnZXIubG9va3VwTGV2ZWwobGV2ZWwpOwoKCQkJCQlpZiAodHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnICYmIGxvZ2dlci5sb29rdXBMZXZlbChsb2dnZXIubGV2ZWwpIDw9IGxldmVsKSB7CgkJCQkJCXZhciBtZXRob2QgPSBsb2dnZXIubWV0aG9kTWFwW2xldmVsXTsKCQkJCQkJaWYgKCFjb25zb2xlW21ldGhvZF0pIHsKCQkJCQkJCS8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tY29uc29sZQoJCQkJCQkJbWV0aG9kID0gJ2xvZyc7CgkJCQkJCX0KCgkJCQkJCWZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBtZXNzYWdlID0gQXJyYXkoX2xlbiA+IDEgPyBfbGVuIC0gMSA6IDApLCBfa2V5ID0gMTsgX2tleSA8IF9sZW47IF9rZXkrKykgewoJCQkJCQkJbWVzc2FnZVtfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07CgkJCQkJCX0KCgkJCQkJCWNvbnNvbGVbbWV0aG9kXS5hcHBseShjb25zb2xlLCBtZXNzYWdlKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1jb25zb2xlCgkJCQkJfQoJCQkJfQoJCQl9OwoKCQkJZXhwb3J0c1snZGVmYXVsdCddID0gbG9nZ2VyOwoJCQltb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsKCgkJCS8qKiovIH0sCgkJLyogMTcgKi8KCQkvKioqLyBmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHsKCgkJCS8vIEJ1aWxkIG91dCBvdXIgYmFzaWMgU2FmZVN0cmluZyB0eXBlCgkJCSd1c2Ugc3RyaWN0JzsKCgkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgkJCWZ1bmN0aW9uIFNhZmVTdHJpbmcoc3RyaW5nKSB7CgkJCQl0aGlzLnN0cmluZyA9IHN0cmluZzsKCQkJfQoKCQkJU2FmZVN0cmluZy5wcm90b3R5cGUudG9TdHJpbmcgPSBTYWZlU3RyaW5nLnByb3RvdHlwZS50b0hUTUwgPSBmdW5jdGlvbiAoKSB7CgkJCQlyZXR1cm4gJycgKyB0aGlzLnN0cmluZzsKCQkJfTsKCgkJCWV4cG9ydHNbJ2RlZmF1bHQnXSA9IFNhZmVTdHJpbmc7CgkJCW1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddOwoKCQkJLyoqKi8gfSwKCQkvKiAxOCAqLwoJCS8qKiovIGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykgewoKCQkJJ3VzZSBzdHJpY3QnOwoKCQkJdmFyIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkID0gX193ZWJwYWNrX3JlcXVpcmVfXygxKVsnZGVmYXVsdCddOwoKCQkJdmFyIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDIpWydkZWZhdWx0J107CgoJCQlleHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOwoJCQlleHBvcnRzLmNoZWNrUmV2aXNpb24gPSBjaGVja1JldmlzaW9uOwoJCQlleHBvcnRzLnRlbXBsYXRlID0gdGVtcGxhdGU7CgkJCWV4cG9ydHMud3JhcFByb2dyYW0gPSB3cmFwUHJvZ3JhbTsKCQkJZXhwb3J0cy5yZXNvbHZlUGFydGlhbCA9IHJlc29sdmVQYXJ0aWFsOwoJCQlleHBvcnRzLmludm9rZVBhcnRpYWwgPSBpbnZva2VQYXJ0aWFsOwoJCQlleHBvcnRzLm5vb3AgPSBub29wOwoKCQkJdmFyIF91dGlscyA9IF9fd2VicGFja19yZXF1aXJlX18oNCk7CgoJCQl2YXIgVXRpbHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfdXRpbHMpOwoKCQkJdmFyIF9leGNlcHRpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDUpOwoKCQkJdmFyIF9leGNlcHRpb24yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZXhjZXB0aW9uKTsKCgkJCXZhciBfYmFzZSA9IF9fd2VicGFja19yZXF1aXJlX18oMyk7CgoJCQlmdW5jdGlvbiBjaGVja1JldmlzaW9uKGNvbXBpbGVySW5mbykgewoJCQkJdmFyIGNvbXBpbGVyUmV2aXNpb24gPSBjb21waWxlckluZm8gJiYgY29tcGlsZXJJbmZvWzBdIHx8IDEsCgkJCQkJY3VycmVudFJldmlzaW9uID0gX2Jhc2UuQ09NUElMRVJfUkVWSVNJT047CgoJCQkJaWYgKGNvbXBpbGVyUmV2aXNpb24gIT09IGN1cnJlbnRSZXZpc2lvbikgewoJCQkJCWlmIChjb21waWxlclJldmlzaW9uIDwgY3VycmVudFJldmlzaW9uKSB7CgkJCQkJCXZhciBydW50aW1lVmVyc2lvbnMgPSBfYmFzZS5SRVZJU0lPTl9DSEFOR0VTW2N1cnJlbnRSZXZpc2lvbl0sCgkJCQkJCQljb21waWxlclZlcnNpb25zID0gX2Jhc2UuUkVWSVNJT05fQ0hBTkdFU1tjb21waWxlclJldmlzaW9uXTsKCQkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJ1RlbXBsYXRlIHdhcyBwcmVjb21waWxlZCB3aXRoIGFuIG9sZGVyIHZlcnNpb24gb2YgSGFuZGxlYmFycyB0aGFuIHRoZSBjdXJyZW50IHJ1bnRpbWUuICcgKyAnUGxlYXNlIHVwZGF0ZSB5b3VyIHByZWNvbXBpbGVyIHRvIGEgbmV3ZXIgdmVyc2lvbiAoJyArIHJ1bnRpbWVWZXJzaW9ucyArICcpIG9yIGRvd25ncmFkZSB5b3VyIHJ1bnRpbWUgdG8gYW4gb2xkZXIgdmVyc2lvbiAoJyArIGNvbXBpbGVyVmVyc2lvbnMgKyAnKS4nKTsKCQkJCQl9IGVsc2UgewoJCQkJCQkvLyBVc2UgdGhlIGVtYmVkZGVkIHZlcnNpb24gaW5mbyBzaW5jZSB0aGUgcnVudGltZSBkb2Vzbid0IGtub3cgYWJvdXQgdGhpcyByZXZpc2lvbiB5ZXQKCQkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJ1RlbXBsYXRlIHdhcyBwcmVjb21waWxlZCB3aXRoIGEgbmV3ZXIgdmVyc2lvbiBvZiBIYW5kbGViYXJzIHRoYW4gdGhlIGN1cnJlbnQgcnVudGltZS4gJyArICdQbGVhc2UgdXBkYXRlIHlvdXIgcnVudGltZSB0byBhIG5ld2VyIHZlcnNpb24gKCcgKyBjb21waWxlckluZm9bMV0gKyAnKS4nKTsKCQkJCQl9CgkJCQl9CgkJCX0KCgkJCWZ1bmN0aW9uIHRlbXBsYXRlKHRlbXBsYXRlU3BlYywgZW52KSB7CgkJCQkvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLwoJCQkJaWYgKCFlbnYpIHsKCQkJCQl0aHJvdyBuZXcgX2V4Y2VwdGlvbjJbJ2RlZmF1bHQnXSgnTm8gZW52aXJvbm1lbnQgcGFzc2VkIHRvIHRlbXBsYXRlJyk7CgkJCQl9CgkJCQlpZiAoIXRlbXBsYXRlU3BlYyB8fCAhdGVtcGxhdGVTcGVjLm1haW4pIHsKCQkJCQl0aHJvdyBuZXcgX2V4Y2VwdGlvbjJbJ2RlZmF1bHQnXSgnVW5rbm93biB0ZW1wbGF0ZSBvYmplY3Q6ICcgKyB0eXBlb2YgdGVtcGxhdGVTcGVjKTsKCQkJCX0KCgkJCQl0ZW1wbGF0ZVNwZWMubWFpbi5kZWNvcmF0b3IgPSB0ZW1wbGF0ZVNwZWMubWFpbl9kOwoKCQkJCS8vIE5vdGU6IFVzaW5nIGVudi5WTSByZWZlcmVuY2VzIHJhdGhlciB0aGFuIGxvY2FsIHZhciByZWZlcmVuY2VzIHRocm91Z2hvdXQgdGhpcyBzZWN0aW9uIHRvIGFsbG93CgkJCQkvLyBmb3IgZXh0ZXJuYWwgdXNlcnMgdG8gb3ZlcnJpZGUgdGhlc2UgYXMgcHN1ZWRvLXN1cHBvcnRlZCBBUElzLgoJCQkJZW52LlZNLmNoZWNrUmV2aXNpb24odGVtcGxhdGVTcGVjLmNvbXBpbGVyKTsKCgkJCQlmdW5jdGlvbiBpbnZva2VQYXJ0aWFsV3JhcHBlcihwYXJ0aWFsLCBjb250ZXh0LCBvcHRpb25zKSB7CgkJCQkJaWYgKG9wdGlvbnMuaGFzaCkgewoJCQkJCQljb250ZXh0ID0gVXRpbHMuZXh0ZW5kKHt9LCBjb250ZXh0LCBvcHRpb25zLmhhc2gpOwoJCQkJCQlpZiAob3B0aW9ucy5pZHMpIHsKCQkJCQkJCW9wdGlvbnMuaWRzWzBdID0gdHJ1ZTsKCQkJCQkJfQoJCQkJCX0KCgkJCQkJcGFydGlhbCA9IGVudi5WTS5yZXNvbHZlUGFydGlhbC5jYWxsKHRoaXMsIHBhcnRpYWwsIGNvbnRleHQsIG9wdGlvbnMpOwoJCQkJCXZhciByZXN1bHQgPSBlbnYuVk0uaW52b2tlUGFydGlhbC5jYWxsKHRoaXMsIHBhcnRpYWwsIGNvbnRleHQsIG9wdGlvbnMpOwoKCQkJCQlpZiAocmVzdWx0ID09IG51bGwgJiYgZW52LmNvbXBpbGUpIHsKCQkJCQkJb3B0aW9ucy5wYXJ0aWFsc1tvcHRpb25zLm5hbWVdID0gZW52LmNvbXBpbGUocGFydGlhbCwgdGVtcGxhdGVTcGVjLmNvbXBpbGVyT3B0aW9ucywgZW52KTsKCQkJCQkJcmVzdWx0ID0gb3B0aW9ucy5wYXJ0aWFsc1tvcHRpb25zLm5hbWVdKGNvbnRleHQsIG9wdGlvbnMpOwoJCQkJCX0KCQkJCQlpZiAocmVzdWx0ICE9IG51bGwpIHsKCQkJCQkJaWYgKG9wdGlvbnMuaW5kZW50KSB7CgkJCQkJCQl2YXIgbGluZXMgPSByZXN1bHQuc3BsaXQoJ1xuJyk7CgkJCQkJCQlmb3IgKHZhciBpID0gMCwgbCA9IGxpbmVzLmxlbmd0aDsgaSA8IGw7IGkrKykgewoJCQkJCQkJCWlmICghbGluZXNbaV0gJiYgaSArIDEgPT09IGwpIHsKCQkJCQkJCQkJYnJlYWs7CgkJCQkJCQkJfQoKCQkJCQkJCQlsaW5lc1tpXSA9IG9wdGlvbnMuaW5kZW50ICsgbGluZXNbaV07CgkJCQkJCQl9CgkJCQkJCQlyZXN1bHQgPSBsaW5lcy5qb2luKCdcbicpOwoJCQkJCQl9CgkJCQkJCXJldHVybiByZXN1bHQ7CgkJCQkJfSBlbHNlIHsKCQkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJ1RoZSBwYXJ0aWFsICcgKyBvcHRpb25zLm5hbWUgKyAnIGNvdWxkIG5vdCBiZSBjb21waWxlZCB3aGVuIHJ1bm5pbmcgaW4gcnVudGltZS1vbmx5IG1vZGUnKTsKCQkJCQl9CgkJCQl9CgoJCQkJLy8gSnVzdCBhZGQgd2F0ZXIKCQkJCXZhciBjb250YWluZXIgPSB7CgkJCQkJc3RyaWN0OiBmdW5jdGlvbiBzdHJpY3Qob2JqLCBuYW1lKSB7CgkJCQkJCWlmICghKG5hbWUgaW4gb2JqKSkgewoJCQkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJyInICsgbmFtZSArICciIG5vdCBkZWZpbmVkIGluICcgKyBvYmopOwoJCQkJCQl9CgkJCQkJCXJldHVybiBvYmpbbmFtZV07CgkJCQkJfSwKCQkJCQlsb29rdXA6IGZ1bmN0aW9uIGxvb2t1cChkZXB0aHMsIG5hbWUpIHsKCQkJCQkJdmFyIGxlbiA9IGRlcHRocy5sZW5ndGg7CgkJCQkJCWZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKCQkJCQkJCWlmIChkZXB0aHNbaV0gJiYgZGVwdGhzW2ldW25hbWVdICE9IG51bGwpIHsKCQkJCQkJCQlyZXR1cm4gZGVwdGhzW2ldW25hbWVdOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfSwKCQkJCQlsYW1iZGE6IGZ1bmN0aW9uIGxhbWJkYShjdXJyZW50LCBjb250ZXh0KSB7CgkJCQkJCXJldHVybiB0eXBlb2YgY3VycmVudCA9PT0gJ2Z1bmN0aW9uJyA/IGN1cnJlbnQuY2FsbChjb250ZXh0KSA6IGN1cnJlbnQ7CgkJCQkJfSwKCgkJCQkJZXNjYXBlRXhwcmVzc2lvbjogVXRpbHMuZXNjYXBlRXhwcmVzc2lvbiwKCQkJCQlpbnZva2VQYXJ0aWFsOiBpbnZva2VQYXJ0aWFsV3JhcHBlciwKCgkJCQkJZm46IGZ1bmN0aW9uIGZuKGkpIHsKCQkJCQkJdmFyIHJldCA9IHRlbXBsYXRlU3BlY1tpXTsKCQkJCQkJcmV0LmRlY29yYXRvciA9IHRlbXBsYXRlU3BlY1tpICsgJ19kJ107CgkJCQkJCXJldHVybiByZXQ7CgkJCQkJfSwKCgkJCQkJcHJvZ3JhbXM6IFtdLAoJCQkJCXByb2dyYW06IGZ1bmN0aW9uIHByb2dyYW0oaSwgZGF0YSwgZGVjbGFyZWRCbG9ja1BhcmFtcywgYmxvY2tQYXJhbXMsIGRlcHRocykgewoJCQkJCQl2YXIgcHJvZ3JhbVdyYXBwZXIgPSB0aGlzLnByb2dyYW1zW2ldLAoJCQkJCQkJZm4gPSB0aGlzLmZuKGkpOwoJCQkJCQlpZiAoZGF0YSB8fCBkZXB0aHMgfHwgYmxvY2tQYXJhbXMgfHwgZGVjbGFyZWRCbG9ja1BhcmFtcykgewoJCQkJCQkJcHJvZ3JhbVdyYXBwZXIgPSB3cmFwUHJvZ3JhbSh0aGlzLCBpLCBmbiwgZGF0YSwgZGVjbGFyZWRCbG9ja1BhcmFtcywgYmxvY2tQYXJhbXMsIGRlcHRocyk7CgkJCQkJCX0gZWxzZSBpZiAoIXByb2dyYW1XcmFwcGVyKSB7CgkJCQkJCQlwcm9ncmFtV3JhcHBlciA9IHRoaXMucHJvZ3JhbXNbaV0gPSB3cmFwUHJvZ3JhbSh0aGlzLCBpLCBmbik7CgkJCQkJCX0KCQkJCQkJcmV0dXJuIHByb2dyYW1XcmFwcGVyOwoJCQkJCX0sCgoJCQkJCWRhdGE6IGZ1bmN0aW9uIGRhdGEodmFsdWUsIGRlcHRoKSB7CgkJCQkJCXdoaWxlICh2YWx1ZSAmJiBkZXB0aC0tKSB7CgkJCQkJCQl2YWx1ZSA9IHZhbHVlLl9wYXJlbnQ7CgkJCQkJCX0KCQkJCQkJcmV0dXJuIHZhbHVlOwoJCQkJCX0sCgkJCQkJbWVyZ2U6IGZ1bmN0aW9uIG1lcmdlKHBhcmFtLCBjb21tb24pIHsKCQkJCQkJdmFyIG9iaiA9IHBhcmFtIHx8IGNvbW1vbjsKCgkJCQkJCWlmIChwYXJhbSAmJiBjb21tb24gJiYgcGFyYW0gIT09IGNvbW1vbikgewoJCQkJCQkJb2JqID0gVXRpbHMuZXh0ZW5kKHt9LCBjb21tb24sIHBhcmFtKTsKCQkJCQkJfQoKCQkJCQkJcmV0dXJuIG9iajsKCQkJCQl9LAoKCQkJCQlub29wOiBlbnYuVk0ubm9vcCwKCQkJCQljb21waWxlckluZm86IHRlbXBsYXRlU3BlYy5jb21waWxlcgoJCQkJfTsKCgkJCQlmdW5jdGlvbiByZXQoY29udGV4dCkgewoJCQkJCXZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8ge30gOiBhcmd1bWVudHNbMV07CgoJCQkJCXZhciBkYXRhID0gb3B0aW9ucy5kYXRhOwoKCQkJCQlyZXQuX3NldHVwKG9wdGlvbnMpOwoJCQkJCWlmICghb3B0aW9ucy5wYXJ0aWFsICYmIHRlbXBsYXRlU3BlYy51c2VEYXRhKSB7CgkJCQkJCWRhdGEgPSBpbml0RGF0YShjb250ZXh0LCBkYXRhKTsKCQkJCQl9CgkJCQkJdmFyIGRlcHRocyA9IHVuZGVmaW5lZCwKCQkJCQkJYmxvY2tQYXJhbXMgPSB0ZW1wbGF0ZVNwZWMudXNlQmxvY2tQYXJhbXMgPyBbXSA6IHVuZGVmaW5lZDsKCQkJCQlpZiAodGVtcGxhdGVTcGVjLnVzZURlcHRocykgewoJCQkJCQlpZiAob3B0aW9ucy5kZXB0aHMpIHsKCQkJCQkJCWRlcHRocyA9IGNvbnRleHQgIT09IG9wdGlvbnMuZGVwdGhzWzBdID8gW2NvbnRleHRdLmNvbmNhdChvcHRpb25zLmRlcHRocykgOiBvcHRpb25zLmRlcHRoczsKCQkJCQkJfSBlbHNlIHsKCQkJCQkJCWRlcHRocyA9IFtjb250ZXh0XTsKCQkJCQkJfQoJCQkJCX0KCgkJCQkJZnVuY3Rpb24gbWFpbihjb250ZXh0IC8qLCBvcHRpb25zKi8pIHsKCQkJCQkJcmV0dXJuICcnICsgdGVtcGxhdGVTcGVjLm1haW4oY29udGFpbmVyLCBjb250ZXh0LCBjb250YWluZXIuaGVscGVycywgY29udGFpbmVyLnBhcnRpYWxzLCBkYXRhLCBibG9ja1BhcmFtcywgZGVwdGhzKTsKCQkJCQl9CgkJCQkJbWFpbiA9IGV4ZWN1dGVEZWNvcmF0b3JzKHRlbXBsYXRlU3BlYy5tYWluLCBtYWluLCBjb250YWluZXIsIG9wdGlvbnMuZGVwdGhzIHx8IFtdLCBkYXRhLCBibG9ja1BhcmFtcyk7CgkJCQkJcmV0dXJuIG1haW4oY29udGV4dCwgb3B0aW9ucyk7CgkJCQl9CgkJCQlyZXQuaXNUb3AgPSB0cnVlOwoKCQkJCXJldC5fc2V0dXAgPSBmdW5jdGlvbiAob3B0aW9ucykgewoJCQkJCWlmICghb3B0aW9ucy5wYXJ0aWFsKSB7CgkJCQkJCWNvbnRhaW5lci5oZWxwZXJzID0gY29udGFpbmVyLm1lcmdlKG9wdGlvbnMuaGVscGVycywgZW52LmhlbHBlcnMpOwoKCQkJCQkJaWYgKHRlbXBsYXRlU3BlYy51c2VQYXJ0aWFsKSB7CgkJCQkJCQljb250YWluZXIucGFydGlhbHMgPSBjb250YWluZXIubWVyZ2Uob3B0aW9ucy5wYXJ0aWFscywgZW52LnBhcnRpYWxzKTsKCQkJCQkJfQoJCQkJCQlpZiAodGVtcGxhdGVTcGVjLnVzZVBhcnRpYWwgfHwgdGVtcGxhdGVTcGVjLnVzZURlY29yYXRvcnMpIHsKCQkJCQkJCWNvbnRhaW5lci5kZWNvcmF0b3JzID0gY29udGFpbmVyLm1lcmdlKG9wdGlvbnMuZGVjb3JhdG9ycywgZW52LmRlY29yYXRvcnMpOwoJCQkJCQl9CgkJCQkJfSBlbHNlIHsKCQkJCQkJY29udGFpbmVyLmhlbHBlcnMgPSBvcHRpb25zLmhlbHBlcnM7CgkJCQkJCWNvbnRhaW5lci5wYXJ0aWFscyA9IG9wdGlvbnMucGFydGlhbHM7CgkJCQkJCWNvbnRhaW5lci5kZWNvcmF0b3JzID0gb3B0aW9ucy5kZWNvcmF0b3JzOwoJCQkJCX0KCQkJCX07CgoJCQkJcmV0Ll9jaGlsZCA9IGZ1bmN0aW9uIChpLCBkYXRhLCBibG9ja1BhcmFtcywgZGVwdGhzKSB7CgkJCQkJaWYgKHRlbXBsYXRlU3BlYy51c2VCbG9ja1BhcmFtcyAmJiAhYmxvY2tQYXJhbXMpIHsKCQkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJ211c3QgcGFzcyBibG9jayBwYXJhbXMnKTsKCQkJCQl9CgkJCQkJaWYgKHRlbXBsYXRlU3BlYy51c2VEZXB0aHMgJiYgIWRlcHRocykgewoJCQkJCQl0aHJvdyBuZXcgX2V4Y2VwdGlvbjJbJ2RlZmF1bHQnXSgnbXVzdCBwYXNzIHBhcmVudCBkZXB0aHMnKTsKCQkJCQl9CgoJCQkJCXJldHVybiB3cmFwUHJvZ3JhbShjb250YWluZXIsIGksIHRlbXBsYXRlU3BlY1tpXSwgZGF0YSwgMCwgYmxvY2tQYXJhbXMsIGRlcHRocyk7CgkJCQl9OwoJCQkJcmV0dXJuIHJldDsKCQkJfQoKCQkJZnVuY3Rpb24gd3JhcFByb2dyYW0oY29udGFpbmVyLCBpLCBmbiwgZGF0YSwgZGVjbGFyZWRCbG9ja1BhcmFtcywgYmxvY2tQYXJhbXMsIGRlcHRocykgewoJCQkJZnVuY3Rpb24gcHJvZyhjb250ZXh0KSB7CgkJCQkJdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyB7fSA6IGFyZ3VtZW50c1sxXTsKCgkJCQkJdmFyIGN1cnJlbnREZXB0aHMgPSBkZXB0aHM7CgkJCQkJaWYgKGRlcHRocyAmJiBjb250ZXh0ICE9PSBkZXB0aHNbMF0pIHsKCQkJCQkJY3VycmVudERlcHRocyA9IFtjb250ZXh0XS5jb25jYXQoZGVwdGhzKTsKCQkJCQl9CgoJCQkJCXJldHVybiBmbihjb250YWluZXIsIGNvbnRleHQsIGNvbnRhaW5lci5oZWxwZXJzLCBjb250YWluZXIucGFydGlhbHMsIG9wdGlvbnMuZGF0YSB8fCBkYXRhLCBibG9ja1BhcmFtcyAmJiBbb3B0aW9ucy5ibG9ja1BhcmFtc10uY29uY2F0KGJsb2NrUGFyYW1zKSwgY3VycmVudERlcHRocyk7CgkJCQl9CgoJCQkJcHJvZyA9IGV4ZWN1dGVEZWNvcmF0b3JzKGZuLCBwcm9nLCBjb250YWluZXIsIGRlcHRocywgZGF0YSwgYmxvY2tQYXJhbXMpOwoKCQkJCXByb2cucHJvZ3JhbSA9IGk7CgkJCQlwcm9nLmRlcHRoID0gZGVwdGhzID8gZGVwdGhzLmxlbmd0aCA6IDA7CgkJCQlwcm9nLmJsb2NrUGFyYW1zID0gZGVjbGFyZWRCbG9ja1BhcmFtcyB8fCAwOwoJCQkJcmV0dXJuIHByb2c7CgkJCX0KCgkJCWZ1bmN0aW9uIHJlc29sdmVQYXJ0aWFsKHBhcnRpYWwsIGNvbnRleHQsIG9wdGlvbnMpIHsKCQkJCWlmICghcGFydGlhbCkgewoJCQkJCWlmIChvcHRpb25zLm5hbWUgPT09ICdAcGFydGlhbC1ibG9jaycpIHsKCQkJCQkJcGFydGlhbCA9IG9wdGlvbnMuZGF0YVsncGFydGlhbC1ibG9jayddOwoJCQkJCX0gZWxzZSB7CgkJCQkJCXBhcnRpYWwgPSBvcHRpb25zLnBhcnRpYWxzW29wdGlvbnMubmFtZV07CgkJCQkJfQoJCQkJfSBlbHNlIGlmICghcGFydGlhbC5jYWxsICYmICFvcHRpb25zLm5hbWUpIHsKCQkJCQkvLyBUaGlzIGlzIGEgZHluYW1pYyBwYXJ0aWFsIHRoYXQgcmV0dXJuZWQgYSBzdHJpbmcKCQkJCQlvcHRpb25zLm5hbWUgPSBwYXJ0aWFsOwoJCQkJCXBhcnRpYWwgPSBvcHRpb25zLnBhcnRpYWxzW3BhcnRpYWxdOwoJCQkJfQoJCQkJcmV0dXJuIHBhcnRpYWw7CgkJCX0KCgkJCWZ1bmN0aW9uIGludm9rZVBhcnRpYWwocGFydGlhbCwgY29udGV4dCwgb3B0aW9ucykgewoJCQkJb3B0aW9ucy5wYXJ0aWFsID0gdHJ1ZTsKCQkJCWlmIChvcHRpb25zLmlkcykgewoJCQkJCW9wdGlvbnMuZGF0YS5jb250ZXh0UGF0aCA9IG9wdGlvbnMuaWRzWzBdIHx8IG9wdGlvbnMuZGF0YS5jb250ZXh0UGF0aDsKCQkJCX0KCgkJCQl2YXIgcGFydGlhbEJsb2NrID0gdW5kZWZpbmVkOwoJCQkJaWYgKG9wdGlvbnMuZm4gJiYgb3B0aW9ucy5mbiAhPT0gbm9vcCkgewoJCQkJCW9wdGlvbnMuZGF0YSA9IF9iYXNlLmNyZWF0ZUZyYW1lKG9wdGlvbnMuZGF0YSk7CgkJCQkJcGFydGlhbEJsb2NrID0gb3B0aW9ucy5kYXRhWydwYXJ0aWFsLWJsb2NrJ10gPSBvcHRpb25zLmZuOwoKCQkJCQlpZiAocGFydGlhbEJsb2NrLnBhcnRpYWxzKSB7CgkJCQkJCW9wdGlvbnMucGFydGlhbHMgPSBVdGlscy5leHRlbmQoe30sIG9wdGlvbnMucGFydGlhbHMsIHBhcnRpYWxCbG9jay5wYXJ0aWFscyk7CgkJCQkJfQoJCQkJfQoKCQkJCWlmIChwYXJ0aWFsID09PSB1bmRlZmluZWQgJiYgcGFydGlhbEJsb2NrKSB7CgkJCQkJcGFydGlhbCA9IHBhcnRpYWxCbG9jazsKCQkJCX0KCgkJCQlpZiAocGFydGlhbCA9PT0gdW5kZWZpbmVkKSB7CgkJCQkJdGhyb3cgbmV3IF9leGNlcHRpb24yWydkZWZhdWx0J10oJ1RoZSBwYXJ0aWFsICcgKyBvcHRpb25zLm5hbWUgKyAnIGNvdWxkIG5vdCBiZSBmb3VuZCcpOwoJCQkJfSBlbHNlIGlmIChwYXJ0aWFsIGluc3RhbmNlb2YgRnVuY3Rpb24pIHsKCQkJCQlyZXR1cm4gcGFydGlhbChjb250ZXh0LCBvcHRpb25zKTsKCQkJCX0KCQkJfQoKCQkJZnVuY3Rpb24gbm9vcCgpIHsKCQkJCXJldHVybiAnJzsKCQkJfQoKCQkJZnVuY3Rpb24gaW5pdERhdGEoY29udGV4dCwgZGF0YSkgewoJCQkJaWYgKCFkYXRhIHx8ICEoJ3Jvb3QnIGluIGRhdGEpKSB7CgkJCQkJZGF0YSA9IGRhdGEgPyBfYmFzZS5jcmVhdGVGcmFtZShkYXRhKSA6IHt9OwoJCQkJCWRhdGEucm9vdCA9IGNvbnRleHQ7CgkJCQl9CgkJCQlyZXR1cm4gZGF0YTsKCQkJfQoKCQkJZnVuY3Rpb24gZXhlY3V0ZURlY29yYXRvcnMoZm4sIHByb2csIGNvbnRhaW5lciwgZGVwdGhzLCBkYXRhLCBibG9ja1BhcmFtcykgewoJCQkJaWYgKGZuLmRlY29yYXRvcikgewoJCQkJCXZhciBwcm9wcyA9IHt9OwoJCQkJCXByb2cgPSBmbi5kZWNvcmF0b3IocHJvZywgcHJvcHMsIGNvbnRhaW5lciwgZGVwdGhzICYmIGRlcHRoc1swXSwgZGF0YSwgYmxvY2tQYXJhbXMsIGRlcHRocyk7CgkJCQkJVXRpbHMuZXh0ZW5kKHByb2csIHByb3BzKTsKCQkJCX0KCQkJCXJldHVybiBwcm9nOwoJCQl9CgoJCQkvKioqLyB9LAoJCS8qIDE5ICovCgkJLyoqKi8gZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzKSB7CgoJCQkvKiBXRUJQQUNLIFZBUiBJTkpFQ1RJT04gKi8oZnVuY3Rpb24oZ2xvYmFsKSB7LyogZ2xvYmFsIHdpbmRvdyAqLwoJCQkJJ3VzZSBzdHJpY3QnOwoKCQkJCWV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7CgoJCQkJZXhwb3J0c1snZGVmYXVsdCddID0gZnVuY3Rpb24gKEhhbmRsZWJhcnMpIHsKCQkJCQkvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLwoJCQkJCXZhciByb290ID0gdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWwgOiB3aW5kb3csCgkJCQkJCSRIYW5kbGViYXJzID0gcm9vdC5IYW5kbGViYXJzOwoJCQkJCS8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovCgkJCQkJSGFuZGxlYmFycy5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkgewoJCQkJCQlpZiAocm9vdC5IYW5kbGViYXJzID09PSBIYW5kbGViYXJzKSB7CgkJCQkJCQlyb290LkhhbmRsZWJhcnMgPSAkSGFuZGxlYmFyczsKCQkJCQkJfQoJCQkJCQlyZXR1cm4gSGFuZGxlYmFyczsKCQkJCQl9OwoJCQkJfTsKCgkJCQltb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTsKCQkJCS8qIFdFQlBBQ0sgVkFSIElOSkVDVElPTiAqL30uY2FsbChleHBvcnRzLCAoZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KCkpKSkKCgkJCS8qKiovIH0KCQkvKioqKioqLyBdKQp9KTsKOwovKioKICogICAgeGJlNHggaXMgamF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgb3JpZ2luYWwgRUNNQVNjcmlwdCBmb3IgWE1MIChFNFgpCiAqICAgIFNwZWNpZmljYXRpb24gKEVDTUEtMzU3KSBEZWNlbWJlciAyMDA1LiBUaGlzIGltcGxlbWVudGF0aW9uIGlzIGRlc2lnbmVkIHRvIGVtdWxhdGUKICogICAgdGhlIGltcGxlbWVudGF0aW9uIHRoYXQgaXMgdXNlZCBpbiBTcGlkZXJNb25rZXkgKE1vemlsbGEncyBKYXZhU2NyaXB0KFRNKSBFbmdpbmUpCiAqICAgIGFuZCB0aGVyZWZvcmUgRmlyZWZveCwgVGh1bmRlcmJpcmQsIGFuZCBtb3N0IG90aGVyIEdlY2tvIGJhc2VkIGFwcGxpY2F0aW9ucy4KICogICAgQmVjYXVzZSB0aGUgTW96aWxsYSBpbXBsZW1lbnRhdGlvbiBsZWF2ZXMgb3V0IGNlcnRhaW4gZmVhdHVyZXMgb2YgdGhlCiAqICAgIHNwZWNpZmljYXRpb24sIHNvIGRvZXMgeGJlNHguIFBsZWFzZSByZWFkIHRoZSBSRUFETUUgZmlsZSBmb3IgYSBmdXJ0aGVyCiAqICAgIGV4cGxhbmF0aW9uIG9mIHRoZXNlIGlzc3Vlcy4KICoKICoKICogICAgQGF1dGhvciBTYW0gU2h1bGwgPGh0dHA6Ly9zYW1zaHVsbC5ibG9nc3BvdC5jb20vPgogKiAgICBAdmVyc2lvbiAwLjEKICoKICogICAgQGNvcHlyaWdodCBDb3B5cmlnaHQgKGMpIDIwMDkgU2FtIFNodWxsIDxodHRwOi8vc2Ftc2h1bGwuYmxvZ3Nwb3QuY29tLz4KICogICAgQGxpY2Vuc2UgPGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UuaHRtbD4KICoKICogICAgUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQogKiAgICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAogKiAgICBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCiAqICAgIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKICogICAgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCiAqICAgIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiAqCiAqICAgIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCiAqICAgIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgogKgogKiAgICBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgogKiAgICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogICAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiAqICAgIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKICogICAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKICogICAgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgogKiAgICBUSEUgU09GVFdBUkUuCiAqCiAqCiAqICAgIENIQU5HRVM6CiAqLwoKLy90aGlzIGRvZXNuJ3QgbG9hZCBpZiB3aW5kb3cuWE1MIGlzIGFscmVhZHkgZGVmaW5lZAppZiAoIXRoaXMuWE1MKQp7CiAgICAoZnVuY3Rpb24gKCkKICAgIHsKICAgICAgICAvKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICB2YXIgdW5kZWZpbmVkLCBwLAogICAgICAgICAgICB3aW5kb3cgICAgICAgICAgICAgICAgICAgICAgID0gdGhpcywKICAgICAgICAgICAgZG5zICAgICAgICAgICAgICAgICAgICAgICAgICA9IFtdLAogICAgICAgICAgICBkZWZhdWx0TmFtZXNwYWNlICAgICAgICAgICAgID0gIiIsCiAgICAgICAgICAgIEVMRU1FTlRfTk9ERSAgICAgICAgICAgICAgICAgPSAxLAogICAgICAgICAgICBBVFRSSUJVVEVfTk9ERSAgICAgICAgICAgICAgID0gMiwKICAgICAgICAgICAgVEVYVF9OT0RFICAgICAgICAgICAgICAgICAgICA9IDMsCiAgICAgICAgICAgIENEQVRBX1NFQ1RJT05fTk9ERSAgICAgICAgICAgPSA0LAogICAgICAgICAgICBFTlRJVFlfUkVGRVJFTkNFX05PREUgICAgICAgID0gNSwKICAgICAgICAgICAgRU5USVRZX05PREUgICAgICAgICAgICAgICAgICA9IDYsCiAgICAgICAgICAgIFBST0NFU1NJTkdfSU5TVFJVQ1RJT05fTk9ERSAgPSA3LAogICAgICAgICAgICBDT01NRU5UX05PREUgICAgICAgICAgICAgICAgID0gOCwKICAgICAgICAgICAgRE9DVU1FTlRfTk9ERSAgICAgICAgICAgICAgICA9IDksCiAgICAgICAgICAgIERPQ1VNRU5UX1RZUEVfTk9ERSAgICAgICAgICAgPSAxMCwKICAgICAgICAgICAgRE9DVU1FTlRfRlJBR01FTlRfTk9ERSAgICAgICA9IDExLAogICAgICAgICAgICBOT1RBVElPTl9OT0RFICAgICAgICAgICAgICAgID0gMTIsCiAgICAgICAgICAgIGlzTlNEZWYgICAgICAgICAgICAgICAgICAgICAgPSAvXnhtbG5zOihbXHdcLV0rKS9pLAogICAgICAgICAgICB0b1N0cmluZyAgICAgICAgICAgICAgICAgICAgID0gKHt9KS50b1N0cmluZywKICAgICAgICAgICAgcHJvcGVydHlJc0VudW1lcmFibGUgICAgICAgICA9ICh7fSkucHJvcGVydHlJc0VudW1lcmFibGUsCiAgICAgICAgICAgIGhhc093blByb3BlcnR5ICAgICAgICAgICAgICAgPSAoe30pLmhhc093blByb3BlcnR5LAogICAgICAgICAgICBkZWZhdWx0WE1MUHJvcGVydGllcyAgICAgICAgID0gIixwcm90b3R5cGUsaWdub3JlQ29tbWVudHMsaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucyxpZ25vcmVXaGl0ZXNwYWNlLCIgKwogICAgICAgICAgICAgICAgInByZXR0eVByaW50aW5nLHByZXR0eUluZGVudCxzZXR0aW5ncyxkZWZhdWx0U2V0dGluZ3Msc2V0U2V0dGluZ3Msc2V0dGluZ3MsIiArCiAgICAgICAgICAgICAgICAicHJvcGVydHlJc0VudW1lcmFibGUsaGFzT3duUHJvcGVydHksX3NldERlZmF1bHROYW1lc3BhY2UsIiwKICAgICAgICAgICAgZGVmYXVsdFhNTFByb3RvdHlwZSAgICAgICAgICA9ICIsX0NsYXNzLF9OYW1lLF9QYXJlbnQsX1ZhbHVlLF9JblNjb3BlTmFtZXNwYWNlcyxfQXR0cmlidXRlcyxfQ2hpbGRyZW4sX05vZGUiLAogICAgICAgICAgICBkZWZhdWx0WE1MTGlzdFByb3RvdHlwZSAgICAgID0gIixfQ2xhc3MsX1ZhbHVlLF9DaGlsZHJlbixfVGFyZ2V0T2JqZWN0LF9UYXJnZXRQcm9wZXJ0eSIsCiAgICAgICAgICAgIHhtbERvYyAgICAgICAgICAgICAgICAgICAgICAgPSBwYXJzZSgiPHgvPiIpLAogICAgICAgICAgICBwaU5hbWUgICAgICAgICAgICAgICAgICAgICAgID0gL15bXHdcLV0rXHMqLywKICAgICAgICAgICAgWFNMVF9OUyAgICAgICAgICAgICAgICAgICAgICA9ICJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0iOwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFhNTCAkc3RyaW5nCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICogICAgQHRocm93cyBTeW50YXhFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFhNTCAoJHN0cmluZykKICAgICAgICB7CiAgICAgICAgICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBYTUwpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gVG9YTUwoJHN0cmluZyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciB4LCBpLCBsOwoKICAgICAgICAgICAgdGhpcy5fQ2xhc3MgPSAidGV4dCI7CgogICAgICAgICAgICB0aGlzLl9OYW1lID0gbnVsbDsKCiAgICAgICAgICAgIHRoaXMuX1ZhbHVlID0gbnVsbDsKCiAgICAgICAgICAgIHRoaXMuX1BhcmVudCA9IG51bGw7CgogICAgICAgICAgICB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcyA9IHt9OwoKICAgICAgICAgICAgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSA9IG51bGw7CgogICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzID0ge307CgogICAgICAgICAgICB0aGlzLl9DaGlsZHJlbiA9IFtdOwoKICAgICAgICAgICAgdGhpc1swXSA9IHRoaXM7CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICoKICAgICAgICAgICAgICoKICAgICAgICAgICAgICoKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHN3aXRjaCAodHlwZW9mKCRzdHJpbmcpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlICJ1bmRlZmluZWQiOgogICAgICAgICAgICAgICAgY2FzZSAibnVsbCI6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJudW1iZXIiOgogICAgICAgICAgICAgICAgY2FzZSAiYm9vbGVhbiI6ICAgICRzdHJpbmcgPSBUb1N0cmluZygkc3RyaW5nKTsKICAgICAgICAgICAgICAgIGNhc2UgInN0cmluZyI6CgogICAgICAgICAgICAgICAgICAgIHggPSBUb1hNTCh0cmltKCRzdHJpbmcpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoeCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4Lmxlbmd0aCgpID09PTEpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NsYXNzID0geC5fQ2xhc3M7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9OYW1lID0geC5fTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX1ZhbHVlID0geC5fVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcyA9IHguX0luU2NvcGVOYW1lc3BhY2VzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSA9IHguX0RlZmF1bHROYW1lc3BhY2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzID0geC5fQXR0cmlidXRlczsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0geC5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldID0geC5fQ2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0uX1BhcmVudCA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcigpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBpZiAoJHN0cmluZyBpbnN0YW5jZW9mIFhNTCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkc3RyaW5nLmxlbmd0aCgpID09PTEpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAkc3RyaW5nOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2xhc3MgPSB4Ll9DbGFzczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX05hbWUgPSB4Ll9OYW1lOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fVmFsdWUgPSB4Ll9WYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzID0geC5fSW5TY29wZU5hbWVzcGFjZXM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlID0geC5fRGVmYXVsdE5hbWVzcGFjZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0F0dHJpYnV0ZXMgPSB4Ll9BdHRyaWJ1dGVzOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSB4Ll9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0gPSB4Ll9DaGlsZHJlbltpXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXS5fUGFyZW50ID0gdGhpczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogICAgSWdub3JlIFhNTCBjb21tZW50cy4gKERlZmF1bHQ6IHRydWUuKQogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEBwYXJhbSBOYW1lc3BhY2UgbnMKICAgICAgICAgKiAgICBAcmV0dXJucyB2b2lkCiAgICAgICAgICovCiAgICAgICAgWE1MLnNldERlZmF1bHROYW1lc3BhY2UgPSBmdW5jdGlvbiAobnMpCiAgICAgICAgewogICAgICAgICAgICBkbnMudW5zaGlmdChkZWZhdWx0TmFtZXNwYWNlIHx8ICIiKTsKICAgICAgICAgICAgZGVmYXVsdE5hbWVzcGFjZSA9IE5hbWVzcGFjZShucyk7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqICBVc2UgdGhpcyBmdW5jdGlvbiB0byByZXN0b3JlIHRoZSBkZWZhdWx0IG5hbWVzcGFjZQogICAgICAgICAqICB0byB0aGUgcHJldmlvdXMgbmFtZXNwYWNlCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICBYTUwucmVzdG9yZURlZmF1bHROYW1lc3BhY2UgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgZGVmYXVsdE5hbWVzcGFjZSA9IGRucy5zaGlmdCgpIHx8ICIiOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICBYTUwubG9hZCA9IGZ1bmN0aW9uIChwYXRoVG9GaWxlLCBvbmxvYWQpCiAgICAgICAgewogICAgICAgICAgICB2YXIgeGhyID0gaXNBY3RpdmVYU3VwcG9ydGVkKCJNaWNyb3NvZnQuWE1MSFRUUCIpICYmIG5ldyBBY3RpdmVYT2JqZWN0KCJNaWNyb3NvZnQuWE1MSFRUUCIpIHx8IG5ldyBYTUxIdHRwUmVxdWVzdCgpLAogICAgICAgICAgICAgICAgYXN5bmMgPSAoe30pLnRvU3RyaW5nLmNhbGwob25sb2FkIHx8IHt9KSA9PSAiW29iamVjdCBGdW5jdGlvbl0iOwoKICAgICAgICAgICAgeGhyLm9wZW4oIkdFVCIsIHBhdGhUb0ZpbGUsIGFzeW5jKTsKCiAgICAgICAgICAgIGlmIChhc3luYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCEheGhyLmFkZEV2ZW50TGlzdGVuZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeGhyLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLCBsb2FkZWQsIGZhbHNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PSA0ICYmIHhoci5zdGF0dXMgPT0gMjAwKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2FkZWQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHhoci5zZW5kKG51bGwpOwoKICAgICAgICAgICAgcmV0dXJuIGFzeW5jID8geGhyIDogbG9hZGVkKDEpOwoKICAgICAgICAgICAgZnVuY3Rpb24gbG9hZGVkIChyZXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciB4ID0gbmV3IFhNTCgoeGhyLnJlc3BvbnNlVGV4dHx8IiIpLnJlcGxhY2UoL1xzKjxcP3htbC4qP1w/Pi8sIiIpKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXQgPyB4IDogb25sb2FkKHgpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICogICAgSWdub3JlIFhNTCBjb21tZW50cy4gKERlZmF1bHQ6IHRydWUuKQogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEB2YXIgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5pZ25vcmVDb21tZW50cyA9IHRydWU7CgogICAgICAgIC8qKgogICAgICAgICAqICAgIElnbm9yZSBYTUwgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMuIChEZWZhdWx0OiB0cnVlLikKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAdmFyIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUwuaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucyA9IHRydWU7CgogICAgICAgIC8qKgogICAgICAgICAqICAgIElnbm9yZSB3aGl0ZXNwYWNlLiAoRGVmYXVsdDogdHJ1ZS4pCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHZhciBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLmlnbm9yZVdoaXRlc3BhY2UgPSB0cnVlOwoKICAgICAgICAvKioKICAgICAgICAgKiAgICBQcmV0dHktcHJpbnQgWE1MIG91dHB1dCB3aXRoIHRvWE1MU3RyaW5nKCkgZXRjLiAoRGVmYXVsdDogdHJ1ZS4pCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHZhciBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByZXR0eVByaW50aW5nID0gdHJ1ZTsKCiAgICAgICAgLyoqCiAgICAgICAgICogICAgUHJldHR5IGluZGVudCBsZXZlbCBmb3IgY2hpbGQgbm9kZXMuIChEZWZhdWx0OiAyLikKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAdmFyIE51bWJlcgogICAgICAgICAqLwogICAgICAgIFhNTC5wcmV0dHlJbmRlbnQgPSAyOwoKICAgICAgICAvL1RoZXJlIGFyZSBhbHNvIHRocmVlIG1ldGhvZHMgdG8gbW9yZSBlYXNpbHkgYXBwbHkgYW5kIHJlc3RvcmUgc2V0dGluZ3MgZm9yIHVzZSwgc2F5LCB3aXRoaW4gYSBmdW5jdGlvbi4KCiAgICAgICAgLyoqCiAgICAgICAgICogICAgR2V0IGFuIE9iamVjdCBjb250YWluaW5nIHRoZSBhYm92ZSBzZXR0aW5ncy4KICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAcmV0dXJucyBPYmplY3QKICAgICAgICAgKi8KICAgICAgICBYTUwuc2V0dGluZ3MgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgIGlnbm9yZUNvbW1lbnRzOiAgICAgICAgICAgICAgICAgWE1MLmlnbm9yZUNvbW1lbnRzLAogICAgICAgICAgICAgICAgaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9uczogICBYTUwuaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucywKICAgICAgICAgICAgICAgIGlnbm9yZVdoaXRlc3BhY2U6ICAgICAgICAgICAgICAgWE1MLmlnbm9yZVdoaXRlc3BhY2UsCiAgICAgICAgICAgICAgICBwcmV0dHlQcmludGluZzogICAgICAgICAgICAgICAgIFhNTC5wcmV0dHlQcmludGluZywKICAgICAgICAgICAgICAgIHByZXR0eUluZGVudDogICAgICAgICAgICAgICAgICAgWE1MLnByZXR0eUluZGVudAogICAgICAgICAgICB9OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqICAgIEdldCBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgZGVmYXVsdCBzZXR0aW5ncy4KICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAcmV0dXJucyBPYmplY3QKICAgICAgICAgKi8KICAgICAgICBYTUwuZGVmYXVsdFNldHRpbmdzID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICBpZ25vcmVDb21tZW50czogICAgICAgICAgICAgICAgIHRydWUsCiAgICAgICAgICAgICAgICBpZ25vcmVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25zOiAgIHRydWUsCiAgICAgICAgICAgICAgICBpZ25vcmVXaGl0ZXNwYWNlOiAgICAgICAgICAgICAgIHRydWUsCiAgICAgICAgICAgICAgICBwcmV0dHlQcmludGluZzogICAgICAgICAgICAgICAgIHRydWUsCiAgICAgICAgICAgICAgICBwcmV0dHlJbmRlbnQ6ICAgICAgICAgICAgICAgICAgIDIKICAgICAgICAgICAgfTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKiAgICBTZXQgWE1MIHNldHRpbmdzIGZyb20sIGUuZy4sIGFuIG9iamVjdCByZXR1cm5lZCBieSBYTUwuc2V0dGluZ3MoKS4KICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEBwYXJhbSBPYmplY3Qgc2V0dGluZ3MKICAgICAgICAgKiAgICBAcmV0dXJucyB2b2lkCiAgICAgICAgICovCiAgICAgICAgWE1MLnNldFNldHRpbmdzID0gZnVuY3Rpb24gKHNldHRpbmdzKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHA7CiAgICAgICAgICAgIHNldHRpbmdzID0gc2V0dGluZ3MgfHwgWE1MLnNldHRpbmdzKCk7CiAgICAgICAgICAgIGZvciAocCBpbiBzZXR0aW5ncykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3dpdGNoIChwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhc2UgImlnbm9yZUNvbW1lbnRzIjogICAgICAgICAgICAgICAgICAgWE1MLmlnbm9yZUNvbW1lbnRzID0gISFzZXR0aW5nc1twXTsKICAgICAgICAgICAgICAgICAgICBjYXNlICJpZ25vcmVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25zIjogICAgIFhNTC5pZ25vcmVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25zID0gISFzZXR0aW5nc1twXTsKICAgICAgICAgICAgICAgICAgICBjYXNlICJpZ25vcmVXaGl0ZXNwYWNlIjogICAgICAgICAgICAgICAgIFhNTC5pZ25vcmVXaGl0ZXNwYWNlID0gISFzZXR0aW5nc1twXTsKICAgICAgICAgICAgICAgICAgICBjYXNlICJwcmV0dHlQcmludGluZyI6ICAgICAgICAgICAgICAgICAgIFhNTC5wcmV0dHlQcmludGluZyA9ICEhc2V0dGluZ3NbcF07CiAgICAgICAgICAgICAgICAgICAgY2FzZSAicHJldHR5SW5kZW50IjogICAgICAgICAgICAgICAgICAgICBYTUwucHJldHR5SW5kZW50ID0gcGFyc2VJbnQoc2V0dGluZ3NbcF0pIHx8IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBzdGF0aWMKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLmhhc093blByb3BlcnR5ID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZGVmYXVsdFhNTFByb3BlcnRpZXMuaW5kZXhPZigiLCIgKyBuYW1lICsgIiwiKSA9PT0tMQogICAgICAgICAgICAgICAgJiYgaGFzT3duUHJvcGVydHkuY2FsbChYTUwsIG5hbWUpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm9wZXJ0eUlzRW51bWVyYWJsZSA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5hbWUgIT09ICJwcm90b3R5cGUiCiAgICAgICAgICAgICAgICAmJiBuYW1lIGluIFhNTAogICAgICAgICAgICAgICAgJiYgdG9TdHJpbmcuY2FsbChYTUxbbmFtZV0pICE9ICJbb2JqZWN0IEZ1bmN0aW9uXSIKICAgICAgICAgICAgICAgICYmIHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwoWE1MLCBuYW1lKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHN0YXRpYwogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIFhNTC50b1N0cmluZyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gImZ1bmN0aW9uIFhNTCgpIHtcbiBbbmF0aXZlIGNvZGVdIFxufSI7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBOYW1lc3BhY2UgbmFtZXNwYWNlCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5hZGROYW1lc3BhY2UgPSBmdW5jdGlvbiAobmFtZXNwYWNlKQogICAgICAgIHsKICAgICAgICAgICAgQWRkSW5TY29wZU5hbWVzcGFjZS5jYWxsKHRoaXMsIE5hbWVzcGFjZShuYW1lc3BhY2UpKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgY2hpbGQKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmFwcGVuZENoaWxkID0gZnVuY3Rpb24gKGNoaWxkLGlzQ2hpbGRFbGVtZW50KQogICAgICAgIHsKICAgICAgICAgICAgaXNDaGlsZEVsZW1lbnQgPSBpc0NoaWxkRWxlbWVudCAhPT0gdW5kZWZpbmVkID8gaXNDaGlsZEVsZW1lbnQgOiBmYWxzZTsKICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gR2V0LmNhbGwodGhpcywgIioiKTsKICAgICAgICAgICAgY2hpbGRyZW4uUHV0KGNoaWxkcmVuLmxlbmd0aCgpLCBjaGlsZCxpc0NoaWxkRWxlbWVudCk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgQXR0cmlidXRlTmFtZSB8IFFOYW1lIGF0dHJpYnV0ZU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmF0dHJpYnV0ZSA9IGZ1bmN0aW9uIChhdHRyaWJ1dGVOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIEdldC5jYWxsKHRoaXMsIFRvQXR0cmlidXRlTmFtZShhdHRyaWJ1dGVOYW1lKSwgdHJ1ZSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmF0dHJpYnV0ZXMgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIEdldC5jYWxsKHRoaXMsIFRvQXR0cmlidXRlTmFtZSgiKiIpKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBwcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5jaGlsZCA9IGZ1bmN0aW9uIChwcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICB2YXIgdGVtcG9yYXJ5OwoKICAgICAgICAgICAgaWYgKHBhcnNlSW50KHByb3BlcnR5TmFtZSkrIiIgPT0gcHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0ZW1wb3JhcnkgPSBHZXQuY2FsbCh0aGlzLCAiKiIpOwogICAgICAgICAgICAgICAgdGVtcG9yYXJ5ID0gR2V0TGlzdC5jYWxsKHRlbXBvcmFyeSwgcHJvcGVydHlOYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiB0ZW1wb3JhcnkgfHwgbmV3IFhNTExpc3QoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGVtcG9yYXJ5ID0gVG9YTUxMaXN0KCBHZXQuY2FsbCh0aGlzLCBwcm9wZXJ0eU5hbWUpICk7CgogICAgICAgICAgICByZXR1cm4gdGVtcG9yYXJ5OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBOdW1iZXIKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmNoaWxkSW5kZXggPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHBhcmVudCA9IHRoaXMuX1BhcmVudCwgcSwgbDsKCiAgICAgICAgICAgIGlmICghcGFyZW50IHx8IHRoaXMuX0NsYXNzID09PSAiYXR0cmlidXRlIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHEgPSAwLCBsID0gcGFyZW50Ll9DaGlsZHJlbi5sZW5ndGg7IHEgPCBsOyArK3EpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwYXJlbnQuX0NoaWxkcmVuW3FdID09PSB0aGlzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmNoaWxkcmVuID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBHZXQuY2FsbCh0aGlzLCAiKiIpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5jb21tZW50cyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRQcm9wZXJ0eSA9IG51bGw7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gImNvbW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRoaXMuX0NoaWxkcmVuW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBYTUwgdmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uICh2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0aGlzID09IHZhbHVlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIERlZXBDb3B5LmNhbGwodGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuZGVzY2VuZGFudHMgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBEZXNjZW5kYW50cy5jYWxsKHRoaXMsIG5hbWUgfHwgIioiKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIHwgQXR0cmlidXRlTmFtZSBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuZWxlbWVudHMgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIG5hbWUgPSBUb1hNTE5hbWUobmFtZSB8fCAiKiIpOwogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRQcm9wZXJ0eSA9IG5hbWU7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiCiAgICAgICAgICAgICAgICAgICAgJiYgKG5hbWUubG9jYWxOYW1lID09PSAiKiIgfHwgbmFtZS5sb2NhbE5hbWUgPT09IHRoaXMuX0NoaWxkcmVuW2ldLl9OYW1lLmxvY2FsTmFtZSkKICAgICAgICAgICAgICAgICAgICAmJiAobmFtZS51cmkgPT0gbnVsbCB8fCBuYW1lLnVyaSA9PT0gdGhpcy5fQ2hpbGRyZW5baV0uX05hbWUudXJpKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRoaXMuX0NoaWxkcmVuW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmhhc093blByb3BlcnR5ID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gSGFzUHJvcGVydHkuY2FsbCh0aGlzLCBuYW1lKSB8fCAoZGVmYXVsdFhNTFByb3RvdHlwZS5pbmRleE9mKCIsIiArIG5hbWUgKyIsIikgPT09IC0xICYmIGhhc093blByb3BlcnR5LmNhbGwodGhpcywgbmFtZSkpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5oYXNDb21wbGV4Q29udGVudCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsYXR0cmlidXRlLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5oYXNTaW1wbGVDb250ZW50ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIixjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIEFycmF5CiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5pblNjb3BlTmFtZXNwYWNlcyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgeSA9IHRoaXMsIGluU2NvcGVOUyA9IHt9LCBwLCBhID0gW107CgogICAgICAgICAgICB3aGlsZSAoeSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChwIGluIHkuX0luU2NvcGVOYW1lc3BhY2VzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICghaW5TY29wZU5TW3BdKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaW5TY29wZU5TW3BdID0geS5fSW5TY29wZU5hbWVzcGFjZXNbcF07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHkgPSB5LnBhcmVudCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5fRGVmYXVsdE5hbWVzcGFjZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW5TY29wZU5TWyIiXSA9IHRoaXMuX0RlZmF1bHROYW1lc3BhY2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAocCBpbiBpblNjb3BlTlMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGFbYS5sZW5ndGhdID0gaW5TY29wZU5TW3BdOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gYTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBjaGlsZDEKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIGNoaWxkMgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTCB8IG51bGwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLmluc2VydENoaWxkQWZ0ZXIgPSBmdW5jdGlvbiAoY2hpbGQxLCBjaGlsZDIpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsYXR0cmlidXRlLGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbix0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgLy90aGlzIGlzIGRpc2FibGVkLCBiZWNhdXNlIGl0IGRvZXNuJ3Qgd29yayBpbgogICAgICAgICAgICAgLy9GaXJlZm94IGFjY29yZGluZyB0byB0aGUgc3BlYwogICAgICAgICAgICAgaWYgKCFjaGlsZDIpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCAwLCBjaGlsZDEpOwogICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICBlbHNlIGlmICghY2hpbGQxKQogICAgICAgICAgICAgewogICAgICAgICAgICAgSW5zZXJ0LmNhbGwodGhpcywgMCwgY2hpbGQyKTsKICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGlmICghY2hpbGQxKXsKICAgICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIDAsIGNoaWxkMik7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWNoaWxkMil7CiAgICAgICAgICAgICAgICBJbnNlcnQuY2FsbCh0aGlzLCAwLCBjaGlsZDEpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjaGlsZDEgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIGNoaWxkMS5jaGlsZEluZGV4KCkgKyAxLCBjaGlsZDIpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBYTUwgY2hpbGQxCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBjaGlsZDIKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwgfCBudWxsCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5pbnNlcnRDaGlsZEJlZm9yZSA9IGZ1bmN0aW9uIChjaGlsZDEsIGNoaWxkMikKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIixhdHRyaWJ1dGUsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLHRleHQsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAvL3RoaXMgaXMgZGlzYWJsZWQsIGJlY2F1c2UgaXQgZG9lc24ndCB3b3JrIGluCiAgICAgICAgICAgICAvL0ZpcmVmb3ggYWNjb3JkaW5nIHRvIHRoZSBzcGVjCiAgICAgICAgICAgICBpZiAoIWNoaWxkMSkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIHRoaXMuX0NoaWxkcmVuLmxlbmd0aCwgY2hpbGQyKTsKICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgZWxzZSBpZiAoIWNoaWxkMikKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIHRoaXMuX0NoaWxkcmVuLmxlbmd0aCwgY2hpbGQxKTsKICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGlmIChjaGlsZDEgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIGNoaWxkMS5jaGlsZEluZGV4KCksIGNoaWxkMik7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIE51bWJlcgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUubGVuZ3RoID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcgfCBudWxsCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5sb2NhbE5hbWUgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX05hbWUgPT09IG51bGwgPyBudWxsIDogdGhpcy5fTmFtZS5sb2NhbE5hbWU7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIHJldHVybiBRTmFtZQogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUubmFtZSA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdGhpcy5fTmFtZTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBwcmVmaXgKICAgICAgICAgKiAgICBAcmV0dXJucyBOYW1lc3BhY2UKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLm5hbWVzcGFjZSA9IGZ1bmN0aW9uIChwcmVmaXgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgeSA9IHRoaXMsIGluU2NvcGVOUyA9IHt9LCBwOwoKICAgICAgICAgICAgd2hpbGUgKHkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAocCBpbiB5Ll9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWluU2NvcGVOU1twXSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGluU2NvcGVOU1twXSA9IHkuX0luU2NvcGVOYW1lc3BhY2VzW3BdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB5ID0geS5wYXJlbnQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHByZWZpeCA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoKCIsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLHRleHQsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gR2V0TmFtZXNwYWNlKHRoaXMuX05hbWUsIGluU2NvcGVOUyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByZWZpeCA9IFRvU3RyaW5nKHByZWZpeCk7CgogICAgICAgICAgICBmb3IgKHAgaW4gaW5TY29wZU5TKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoaW5TY29wZU5TW3BdLnByZWZpeCA9PT0gcHJlZml4KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpblNjb3BlTlNbcF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBBcnJheQogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUubmFtZXNwYWNlRGVjbGFyYXRpb25zID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIixhdHRyaWJ1dGUsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLHRleHQsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIFtdOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgYSA9IFtdLCB5ID0gdGhpcy5fUGFyZW50LCBhbmNlc3Rvck5TID0ge30sIHA7CgogICAgICAgICAgICB3aGlsZSAoeSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChwIGluIHkuX0luU2NvcGVOYW1lc3BhY2VzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICghYW5jZXN0b3JOU1twXSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFuY2VzdG9yTlNbcF0gPSB5Ll9JblNjb3BlTmFtZXNwYWNlc1twXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgeSA9IHkuX1BhcmVudDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChwIGluIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocCAhPSAiIiAmJiAoIWFuY2VzdG9yTlNbcF0gfHwgYW5jZXN0b3JOU1twXS51cmkgIT0gdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbcF0pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFbYS5sZW5ndGhdID0gdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbcF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKHAgPT09ICIiICYmICF0aGlzLl9QYXJlbnQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYVthLmxlbmd0aF0gPSB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1twXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGE7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUubm9kZUtpbmQgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX0NsYXNzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5baV0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0ubm9ybWFsaXplKCk7CiAgICAgICAgICAgICAgICAgICAgKytpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fQ2hpbGRyZW5baV0uX0NsYXNzID09PSAidGV4dCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGkrMSA8IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCAmJiB0aGlzLl9DaGlsZHJlbltpKzFdLl9DbGFzcyA9PT0gInRleHQiKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0uX1ZhbHVlID0gKHRoaXMuX0NoaWxkcmVuW2ldLl9WYWx1ZSB8fCAiIikgKyAodGhpcy5fQ2hpbGRyZW5baSsxXS5fVmFsdWUgfHwgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICBEZWxldGVCeUluZGV4LmNhbGwodGhpcywgaSsxKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fVmFsdWUubGVuZ3RoID09PSAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgRGVsZXRlQnlJbmRleC5jYWxsKHRoaXMsIGkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICArK2k7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTCB8IG51bGwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnBhcmVudCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdGhpcy5fUGFyZW50OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb25zID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICBuYW1lID0gVG9YTUxOYW1lKG5hbWUgfHwgIioiKTsKCiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHRoaXM7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldFByb3BlcnR5ID0gbnVsbDsKCiAgICAgICAgICAgIGZvciAoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5baV0uX0NsYXNzID09PSAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiIKICAgICAgICAgICAgICAgICAgICAmJiAobmFtZS5sb2NhbE5hbWUgPT09ICIqIiB8fCBuYW1lLmxvY2FsTmFtZSA9PT0gdGhpcy5fQ2hpbGRyZW5baV0uX05hbWUubG9jYWxOYW1lKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRoaXMuX0NoaWxkcmVuW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBYTUwgdmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnByZXBlbmRDaGlsZCA9IGZ1bmN0aW9uICh2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIDAsIHZhbHVlKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCgogICAgICAgIFhNTC5wcm90b3R5cGUuZmluZEZpcnN0RWxlbWVudCA9IGZ1bmN0aW9uICh2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gW107CiAgICAgICAgICAgIGxpc3QgPSB0aGlzLmVsZW1lbnRzKHZhbHVlKS5fQ2hpbGRyZW47CiAgICAgICAgICAgIGlmKGxpc3QubGVuZ3RoID09IDApewogICAgICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlbigpOwogICAgICAgICAgICAgICAgdmFyIHhtbDsKICAgICAgICAgICAgICAgIGZvcih2YXIgaT0wO2k8Y2hpbGRyZW4ubGVuZ3RoKCk7aSsrKXsKICAgICAgICAgICAgICAgICAgICB4bWwgPSBjaGlsZHJlbltpXTsKICAgICAgICAgICAgICAgICAgICB2YXIgc3VibGlzdCA9IHhtbC5maW5kRmlyc3RFbGVtZW50KHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICBpZihzdWJsaXN0Lmxlbmd0aD4wKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VibGlzdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9OwoKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmFtZSA9PSAiMCI7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBOYW1lc3BhY2UgfCBTdHJpbmcgbmFtZXNwYWNlCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5yZW1vdmVOYW1lc3BhY2UgPSBmdW5jdGlvbiAobmFtZXNwYWNlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgiLGF0dHJpYnV0ZSxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sdGV4dCwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIG5zID0gTmFtZXNwYWNlKG5hbWVzcGFjZSksIHRoaXNOUyA9IEdldE5hbWVzcGFjZSh0aGlzLl9OYW1lLCB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcyksIHAsIGw7CgogICAgICAgICAgICBpZiAodGhpc05TID09IG5zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgIC8vZmlyZWZveCBkb2VzIG5vdCByZW1vdmUgdGhlIHJlZmVyZW5jZXMgdG8gdGhlCiAgICAgICAgICAgICAvL25hbWVzcGFjZXMgaW4gYXR0cmlidXRlcyAtLSBzbyB3ZSB3b250IGVpdGhlcgogICAgICAgICAgICAgZm9yIChwIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICBpZiAoR2V0TmFtZXNwYWNlKHRoaXMuX0F0dHJpYnV0ZXNbcF0uX05hbWUsIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzKS51cmkgPT0gbnMudXJpKQogICAgICAgICAgICAgewogICAgICAgICAgICAgdGhpcy5fQXR0cmlidXRlc1twXS5fTmFtZSA9IG5ldyBRTmFtZShucywgdGhpcy5fQXR0cmlidXRlc1twXS5sb2NhbE5hbWUoKSk7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICAvLyovCgogICAgICAgICAgICBpZiAobnMucHJlZml4ID09IHVuZGVmaW5lZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChwIGluIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1twXS51cmkgPT09IG5zLnVyaSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW3BdID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1twXTsKICAgICAgICAgICAgICAgICAgICAgICAgfWNhdGNoKGUpe30KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbbnMucHJlZml4XSAmJiB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1tucy5wcmVmaXhdLnVyaSA9PT0gbnMudXJpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0cnl7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbbnMucHJlZml4XSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW25zLnByZWZpeF07CiAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHAgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBwIDwgbDsgKytwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5bcF0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bcF0ucmVtb3ZlTmFtZXNwYWNlKG5zKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgcHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHBhcmFtIFhNTCB2YWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUucmVwbGFjZSA9IGZ1bmN0aW9uIChwcm9wZXJ0eU5hbWUsIHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgiLGF0dHJpYnV0ZSxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sdGV4dCwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGMgPSB2YWx1ZSBpbnN0YW5jZW9mIFhNTCA/IERlZXBDb3B5LmNhbGwodmFsdWUpIDogVG9TdHJpbmcodmFsdWUpLCBuLCBpLCBrOwoKICAgICAgICAgICAgaWYgKHBhcnNlSW50KHByb3BlcnR5TmFtZSkrIiIgPT0gcHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSZXBsYWNlLmNhbGwodGhpcywgcHJvcGVydHlOYW1lLCBjKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgQmFzaWNhbGx5IEZpcmVmb3ggZG9lcyBub3QgYXBwZWFyIHRvIGZvbGxvdyB0aGUgcnVsZXMgc2V0IGZvcnRoIGluIHRoZSBzcGVjCiAgICAgICAgICAgICBzbywgd2UgYXJlIGp1c3QgZ29pbmcgdG8gZml4IHRoaXMgc28gdGhhdCB3ZSBkbyB3aGF0IGZpcmVmb3ggZG9lcwogICAgICAgICAgICAgaWYgdGhlIHByb3BlcnR5TmFtZSBpcyBub3QgYW4gaW50ZWdlcjoKICAgICAgICAgICAgIGlmIHZhbHVlIGlzIGEgWE1MTGlzdCBzZXRDaGlsZHJlbgogICAgICAgICAgICAgb3RoZXJ3aXNlIGRvIG5vdGhpbmcKICAgICAgICAgICAgICovCgogICAgICAgICAgICBpZiAoYyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0Q2hpbGRyZW4oYyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0aGlzOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgIExlYXZlIHRoZSByZXN0IG9mIHRoZXNlIHJ1bGVzIGluIHBsYWNlLCBqdXN0IGluIGNhc2UKICAgICAgICAgICAgICovCgogICAgICAgICAgICBuID0gUU5hbWUocHJvcGVydHlOYW1lKTsKICAgICAgICAgICAgayA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKCiAgICAgICAgICAgIHdoaWxlICgtLWsgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgIChuLmxvY2FsTmFtZSA9PT0gIioiIHx8ICh0aGlzLl9DaGlsZHJlbltrXS5fQ2xhc3MgPT09ICJlbGVtZW50IiAmJiB0aGlzLl9DaGlsZHJlbltrXS5fTmFtZS5sb2NhbE5hbWU9PT1uLmxvY2FsTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgJiYgKG4udXJpID09IG51bGwgfHwgKHRoaXMuX0NoaWxkcmVuW2tdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIG4udXJpID09PSB0aGlzLl9DaGlsZHJlbltrXS5fTmFtZS51cmkgKSkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaSAhPT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgRGVsZXRlQnlJbmRleC5jYWxsKHRoaXMsIGkpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaSA9IGs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpICE9PSB1bmRlZmluZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbCh0aGlzLCBpLCBjKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBYTUwgdmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnNldENoaWxkcmVuID0gZnVuY3Rpb24gKHZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgdGhpcy5QdXQoIioiLCB2YWx1ZSk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyB2b2lkCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5zZXRMb2NhbE5hbWUgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIixjb21tZW50LHRleHQsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX05hbWUubG9jYWxOYW1lID0gbmFtZSBpbnN0YW5jZW9mIFFOYW1lID8gbmFtZS5sb2NhbE5hbWUgOiBUb1N0cmluZyhuYW1lKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFFOYW1lIHwgU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBudWxsCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5zZXROYW1lID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsY29tbWVudCx0ZXh0LCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAobmFtZSBpbnN0YW5jZW9mIFFOYW1lICYmIG5hbWUudXJpID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lLmxvY2FsTmFtZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIG4gPSBRTmFtZShuYW1lKTsKCiAgICAgICAgICAgIGlmICh0aGlzLl9DbGFzcyA9PT0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBuLnVyaSA9ICIiOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlID0gbmV3IE5hbWVzcGFjZShuLnByZWZpeCwgbi51cmkpOwoKICAgICAgICAgICAgdGhpcy5fTmFtZSA9IG47CgogICAgICAgICAgICBpZiAodGhpcy5fQ2xhc3MgPT09ICJhdHRyaWJ1dGUiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fUGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbCh0aGlzLl9QYXJlbnQsIHRoaXMuX0RlZmF1bHROYW1lc3BhY2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbCh0aGlzLCB0aGlzLl9EZWZhdWx0TmFtZXNwYWNlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICgoIixjb21tZW50LHRleHQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbiwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fTmFtZSA9IG5ldyBRTmFtZSh0aGlzLl9EZWZhdWx0TmFtZXNwYWNlLCB0aGlzLl9OYW1lLmxvY2FsTmFtZSk7CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIE5hbWVzcGFjZSB8IFN0cmluZyBucwogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnNldE5hbWVzcGFjZSA9IGZ1bmN0aW9uIChucykKICAgICAgICB7CiAgICAgICAgICAgIC8vcHJvY2Vzc2luZy1pbnN0cnVjdGlvbiwKICAgICAgICAgICAgaWYgKCgiLGNvbW1lbnQsdGV4dCwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSA9IE5hbWVzcGFjZShucyk7CgogICAgICAgICAgICB0aGlzLl9OYW1lID0gbmV3IFFOYW1lKHRoaXMuX0RlZmF1bHROYW1lc3BhY2UsIHRoaXMuX05hbWUubG9jYWxOYW1lKTsKCiAgICAgICAgICAgIGlmICh0aGlzLl9DbGFzcyA9PT0gImF0dHJpYnV0ZSIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9QYXJlbnQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgQWRkSW5TY29wZU5hbWVzcGFjZS5jYWxsKHRoaXMuX1BhcmVudCwgdGhpcy5fRGVmYXVsdE5hbWVzcGFjZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQWRkSW5TY29wZU5hbWVzcGFjZS5jYWxsKHRoaXMsIHRoaXMuX0RlZmF1bHROYW1lc3BhY2UpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUudGV4dCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRQcm9wZXJ0eSA9IG51bGw7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gInRleHQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRoaXMuX0NoaWxkcmVuW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRvU3RyaW5nKHRoaXMpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnRvWE1MU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUb1hNTFN0cmluZyh0aGlzKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS52YWx1ZU9mID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcGFyYW0gWE1MIHwgU3RyaW5nIFZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5QdXQgPSBmdW5jdGlvbiAoUHJvcGVydHlOYW1lLCBWYWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwYXJzZUludChQcm9wZXJ0eU5hbWUpKyIiID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoKCIsdGV4dCxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sYXR0cmlidXRlLCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgYyA9ICghKFZhbHVlIGluc3RhbmNlb2YgWE1MKSB8fCAoIix0ZXh0LGF0dHJpYnV0ZSwiKS5pbmRleE9mKCIsIiArIFZhbHVlLl9DbGFzcysiLCIpID4gLTEpCiAgICAgICAgICAgICAgICAgICAgPyBUb1N0cmluZyhWYWx1ZSkKICAgICAgICAgICAgICAgICAgICA6IERlZXBDb3B5LmNhbGwoVmFsdWUpLAogICAgICAgICAgICAgICAgbiA9IFRvWE1MTmFtZShQcm9wZXJ0eU5hbWUpLAogICAgICAgICAgICAgICAgcywgaSwgbCwgYSA9IG51bGwsIHByaW1pdGl2ZUFzc2lnbiwgazsKCiAgICAgICAgICAgIGlmIChuIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFpc1hNTE5hbWUobi5fTmFtZSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChjIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYy5fQ2hpbGRyZW4ubGVuZ3RoID09PSAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYyA9ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzID0gVG9TdHJpbmcoY1swXSk7CgogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAxLCBsID0gYy5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICIgIiArIFRvU3RyaW5nKGNbaV0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBjID0gczsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYyA9IFRvU3RyaW5nKGMpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZvciAoaSBpbiB0aGlzLl9BdHRyaWJ1dGVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAgICAgKG4uX05hbWUubG9jYWxOYW1lID09PSB0aGlzLl9BdHRyaWJ1dGVzW2ldLl9OYW1lLmxvY2FsTmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgJiYgKG4uX05hbWUudXJpID09PSBudWxsIHx8IG4uX05hbWUudXJpID09PSB0aGlzLl9BdHRyaWJ1dGVzW2ldLl9OYW1lLnVyaSkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhID0gdGhpcy5fQXR0cmlidXRlc1tpXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuRGVsZXRlKHRoaXMuX0F0dHJpYnV0ZXNbaV0uX05hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChhID09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYSA9IG5ldyBYTUwoKTsKICAgICAgICAgICAgICAgICAgICBhLl9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgIGEuX0NsYXNzID0gImF0dHJpYnV0ZSI7CiAgICAgICAgICAgICAgICAgICAgYS5fTmFtZSA9IG4uX05hbWUudXJpID09IG51bGwKICAgICAgICAgICAgICAgICAgICAgICAgPyBuZXcgUU5hbWUobmV3IE5hbWVzcGFjZSgpLCBuLl9OYW1lKQogICAgICAgICAgICAgICAgICAgICAgICA6IG5ldyBRTmFtZShuZXcgTmFtZXNwYWNlKG4uX05hbWUudXJpKSwgbi5fTmFtZS5sb2NhbE5hbWUpOwoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9BdHRyaWJ1dGVzWyhhLl9OYW1lLl9QcmVmaXggPyBhLl9OYW1lLl9QcmVmaXggKyAiOiIgOiAiIikgKyBhLl9OYW1lLmxvY2FsTmFtZV0gPSBhOwoKICAgICAgICAgICAgICAgICAgICBBZGRJblNjb3BlTmFtZXNwYWNlLmNhbGwodGhpcywgR2V0TmFtZXNwYWNlKGEuX05hbWUpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBhLl9WYWx1ZSA9IGM7CgogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghaXNYTUxOYW1lKG4pICYmIG4ubG9jYWxOYW1lICE9ICIqIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGkgPSB1bmRlZmluZWQ7CgogICAgICAgICAgICBwcmltaXRpdmVBc3NpZ24gPSAhKGMgaW5zdGFuY2VvZiBYTUwpICYmIG4ubG9jYWxOYW1lICE9ICIqIjsKCiAgICAgICAgICAgIGZvciAoayA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGsgPCBsOyArK2spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAobi5sb2NhbE5hbWUgPT09ICIqIiB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgdGhpcy5fQ2hpbGRyZW5ba10uX05hbWUubG9jYWxOYW1lPT09bi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICAgICAgKG4udXJpID09IG51bGwgfHwgKHRoaXMuX0NoaWxkcmVuW2tdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIG4udXJpID09PSB0aGlzLl9DaGlsZHJlbltrXS5fTmFtZS51cmkpKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChpICE9IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIERlbGV0ZUJ5SW5kZXguY2FsbCh0aGlzLCBUb1N0cmluZyhpKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGkgPSBrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGkgPT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwoKICAgICAgICAgICAgICAgIGlmIChwcmltaXRpdmVBc3NpZ24pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYSA9IG5ldyBYTUwoKTsKICAgICAgICAgICAgICAgICAgICBhLl9DbGFzcyA9ICJlbGVtZW50IjsKICAgICAgICAgICAgICAgICAgICBhLl9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgIGEuX05hbWUgPSBuLnVyaSA9PSBudWxsCiAgICAgICAgICAgICAgICAgICAgICAgID8gbmV3IFFOYW1lKEdldERlZmF1bHROYW1lc3BhY2UoKSwgbikKICAgICAgICAgICAgICAgICAgICAgICAgOiBuZXcgUU5hbWUobik7CgogICAgICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbCh0aGlzLCBUb1N0cmluZyhpKSwgYSk7CgogICAgICAgICAgICAgICAgICAgIEFkZEluU2NvcGVOYW1lc3BhY2UuY2FsbChhLCBHZXROYW1lc3BhY2UoYS5fTmFtZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocHJpbWl0aXZlQXNzaWduKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzID0gVG9TdHJpbmcoYyk7CgogICAgICAgICAgICAgICAgaWYgKHMgIT0gIiIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgUmVwbGFjZS5jYWxsKHRoaXMuX0NoaWxkcmVuW2ldLCAiMCIsIHMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUmVwbGFjZS5jYWxsKHRoaXMsIFRvU3RyaW5nKGkpLCBjKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUuRGVsZXRlID0gZnVuY3Rpb24gKFByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwYXJzZUludChQcm9wZXJ0eU5hbWUpKyIiID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbiA9IFRvWE1MTmFtZShQcm9wZXJ0eU5hbWUpLCBrLCBkcCA9IDAsIHEgPSAwLCBsOwoKICAgICAgICAgICAgaWYgKG4gaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGsgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgIChuLl9OYW1lLmxvY2FsTmFtZSA9PT0gIioiIHx8IG4uX05hbWUubG9jYWxOYW1lID09PSB0aGlzLl9BdHRyaWJ1dGVzW2tdLl9OYW1lLmxvY2FsTmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKG4uX05hbWUudXJpID09IG51bGwgfHwgbi5fTmFtZS51cmkgPT09IHRoaXMuX0F0dHJpYnV0ZXNba10uX05hbWUudXJpKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX0F0dHJpYnV0ZXNba10uX1BhcmVudCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9BdHRyaWJ1dGVzW2tdOwogICAgICAgICAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgKG4ubG9jYWxOYW1lID09PSAiKiIgfHwgKHRoaXMuX0NoaWxkcmVuW3FdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIHRoaXMuX0NoaWxkcmVuW3FdLl9OYW1lLmxvY2FsTmFtZSA9PT0gbi5sb2NhbE5hbWUpKQogICAgICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICAgICAgKG4udXJpID09IG51bGwgfHwgKHRoaXMuX0NoaWxkcmVuW3FdLl9DbGFzcyA9PT0gImVsZW1lbnQiICYmIG4udXJpID09PSB0aGlzLl9DaGlsZHJlbltxXS5fTmFtZS51cmkpKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIERlbGV0ZUJ5SW5kZXguY2FsbCh0aGlzLCBxKTsKICAgICAgICAgICAgICAgICAgICArK2RwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoZHAgPiAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW3EgLSBkcF0gPSB0aGlzLl9DaGlsZHJlbltxXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgVmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5FcXVhbHMgPSBmdW5jdGlvbiAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIShWYWx1ZSBpbnN0YW5jZW9mIFhNTCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhpcy5fQ2xhc3MgIT09IFZhbHVlLl9DbGFzcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggIT09IFZhbHVlLl9DaGlsZHJlbi5sZW5ndGgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhpcy5fVmFsdWUgIT09IFZhbHVlLl9WYWx1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLl9OYW1lICE9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoVmFsdWUuX05hbWUgPT09IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKFZhbHVlLl9OYW1lLmxvY2FsTmFtZSAhPT0gdGhpcy5fTmFtZS5sb2NhbE5hbWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKFZhbHVlLl9OYW1lLnVyaSAhPT0gdGhpcy5fTmFtZS51cmkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKFZhbHVlLl9OYW1lICE9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjb3VudCh0aGlzLl9BdHRyaWJ1dGVzKSAhPT0gY291bnQoVmFsdWUuX0F0dHJpYnV0ZXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBhLCBiLCBrLCBsOwoKICAgICAgICAgICAgZm9yIChrIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGEgPSB0aGlzLl9BdHRyaWJ1dGVzW2tdOwoKICAgICAgICAgICAgICAgIGIgPSBWYWx1ZS5fQXR0cmlidXRlc1trXTsKCiAgICAgICAgICAgICAgICBpZiAoIWIgfHwgYi5fTmFtZS5sb2NhbE5hbWUgIT09IGEuX05hbWUubG9jYWxOYW1lIHx8IGIuX05hbWUudXJpICE9PSBhLl9OYW1lLnVyaSB8fCBiLl9WYWx1ZSAhPT0gYS5fVmFsdWUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGsgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBrIDwgbDsgKytrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhID0gdGhpcy5fQ2hpbGRyZW5ba107CgogICAgICAgICAgICAgICAgYiA9IFZhbHVlLl9DaGlsZHJlbltrXTsKCiAgICAgICAgICAgICAgICBpZiAoIWFyZ3VtZW50cy5jYWxsZWUuY2FsbChhLCBiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8vZXh0ZW5zaW9ucwoKICAgICAgICAvKgogICAgICAgICAqIGU0eC5qcwogICAgICAgICAqCiAgICAgICAgICogQSBKYXZhU2NyaXB0IGxpYnJhcnkgdGhhdCBpbXBsZW1lbnRzIHRoZSBvcHRpb25hbCBFNFggZmVhdHVyZXMgZGVzY3JpYmVkIGluCiAgICAgICAgICogRUNNQS0zNTcgMm5kIEVkaXRpb24gQW5uZXggQSBpZiB0aGV5IGFyZSBub3QgYWxyZWFkeSBpbXBsZW1lbnRlZC4KICAgICAgICAgKgogICAgICAgICAqIDIwMTAtMDMtMTMKICAgICAgICAgKgogICAgICAgICAqIEJ5IEVsaWphaCBHcmV5LCBodHRwOi8vZWxpZ3JleS5jb20KICAgICAgICAgKiBMaWNlbnNlOiBUaGUgWDExL01JVCBsaWNlbnNlIChzZWUgQ09QWUlORy5tZCkKICAgICAgICAgKgogICAgICAgICAqIENoYW5nZXM6CiAgICAgICAgICogICAgQnkgU2FtIFNodWxsLCBodHRwOi8vc2Ftc2h1bGwuYmxvZ3Nwb3QuY29tCiAgICAgICAgICogICAgSnVzdCBhIGxpdGxsZSBzaW1wbGlmeWluZyBmb3IgaW1wbGVtZW50YXRpb24KICAgICAgICAgKi8KCiAgICAgICAgLypnbG9iYWwgZG9jdW1lbnQsIFhNTCwgWE1MTGlzdCwgRE9NUGFyc2VyLCBYTUxTZXJpYWxpemVyLCBYUGF0aFJlc3VsdCAqLwoKICAgICAgICAvKmpzbGludCB1bmRlZjogdHJ1ZSwgbm9tZW46IHRydWUsIGVxZXFlcTogdHJ1ZSwgYml0d2lzZTogdHJ1ZSwgcmVnZXhwOiB0cnVlLAogICAgICAgICBuZXdjYXA6IHRydWUsIGltbWVkOiB0cnVlLCBtYXhlcnI6IDEwMDAsIG1heGxlbjogOTAgKi8KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5kb21Ob2RlID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBhZG9wdE5vZGUoZG9jdW1lbnQsIHhtbFRvRG9tTm9kZSh0aGlzKSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgWE1MLnByb3RvdHlwZS5kb21Ob2RlTGlzdCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcy5sZW5ndGgoKSA8IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gYWRvcHROb2RlKGRvY3VtZW50LCBjcmVhdGVEb2N1bWVudEZyb20odGhpcykuZG9jdW1lbnRFbGVtZW50KS5jaGlsZE5vZGVzOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqLwogICAgICAgIFhNTC5wcm90b3R5cGUueHBhdGggPSBmdW5jdGlvbiAoeHBhdGhFeHApCiAgICAgICAgewogICAgICAgICAgICB2YXIgcmVzID0gbmV3IFhNTExpc3QsCiAgICAgICAgICAgICAgICBpID0gMCwgbCA9IHRoaXMubGVuZ3RoKCksCiAgICAgICAgICAgICAgICB4cHI7CgogICAgICAgICAgICBpZiAobCAhPT0gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzLkFwcGVuZCh0aGlzW2ldLnhwYXRoKHhwYXRoRXhwKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgeHByID0gZXZhbHVhdGUoY3JlYXRlRG9jdW1lbnRGcm9tKHRoaXMpLCB4cGF0aEV4cCwgdGhpcyk7CgogICAgICAgICAgICBmb3IgKGw9eHByLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzLkFwcGVuZChUb1hNTCh4cHJbaV0pKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHJlczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICBYTUwucHJvdG90eXBlLnRyYW5zZm9ybSA9IGZ1bmN0aW9uICh4c2x0LCBwYXJhbXMpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIXhzbHQgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGRvYywgcmVzLCBpLCBsID0gdGhpcy5sZW5ndGgoKSwgYzsKCiAgICAgICAgICAgIGlmIChsID4gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzID0gbmV3IFhNTExpc3QoKTsKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzLkFwcGVuZCh0aGlzW2ldLnRyYW5zZm9ybSh4c2x0LCBwYXJhbXMpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm0odGhpcywgeHNsdCwgcGFyYW1zKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFhNTExpc3QgKCRzdHJpbmcpCiAgICAgICAgewogICAgICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgWE1MTGlzdCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBUb1hNTExpc3QoJHN0cmluZyB8fCAiIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX0NsYXNzID0gIlhNTExpc3QiOwoKICAgICAgICAgICAgdGhpcy5fVmFsdWUgPSB1bmRlZmluZWQ7CgoKICAgICAgICAgICAgdGhpcy5fVGFyZ2V0T2JqZWN0ID0gbnVsbDsKCiAgICAgICAgICAgIHRoaXMuX1RhcmdldFByb3BlcnR5ID0gbnVsbDsKCiAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuID0gW107CgogICAgICAgICAgICB0aGlzWzBdID0gbnVsbDsKCiAgICAgICAgICAgIGlmICgkc3RyaW5nKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgbGlzdCA9IFRvWE1MTGlzdCgkc3RyaW5nKSwgaSA9IDAsIGwgPSBsaXN0Ll9DaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgICAgICB0aGlzLl9WYWx1ZSA9IGxpc3QuX1ZhbHVlOwoKICAgICAgICAgICAgICAgIGZvciAoO2kgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0gPSB0aGlzW2ldID0gbGlzdC5fQ2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAc3RhdGljCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnRvU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAiZnVuY3Rpb24gWE1MTGlzdCgpIHtcbiBbbmF0aXZlIGNvZGVdIFxufSI7CiAgICAgICAgfTsKCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUgPSBuZXcgWE1MKCk7CgogICAgICAgIHZhciBpZ25vcmUgPSB7eHBhdGg6MSxkb21Ob2RlTGlzdDoxLHRyYW5zZm9ybToxfTsKCiAgICAgICAgZm9yIChwIGluIFhNTExpc3QucHJvdG90eXBlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGlnbm9yZVtwXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFhNTExpc3QucHJvdG90eXBlW3BdID0gKGZ1bmN0aW9uKHApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggIT0gMSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoImNhbm5vdCBjYWxsICIgKyBwICsgIiBtZXRob2Qgb24gYW4gWE1MIGxpc3Qgd2l0aCAiICsgdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoICsgIiBlbGVtZW50cyIpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFhNTC5wcm90b3R5cGVbcF0uYXBwbHkodGhpc1swXSwgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0pKHApOwogICAgICAgIH0KCiAgICAgICAgdHJ5ewogICAgICAgICAgICBkZWxldGUgWE1MTGlzdC5wcm90b3R5cGUuX0F0dHJpYnV0ZXM7CiAgICAgICAgICAgIGRlbGV0ZSBYTUxMaXN0LnByb3RvdHlwZS5fSW5TY29wZU5hbWVzcGFjZXM7CiAgICAgICAgfWNhdGNoKGUpe30KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBBdHRyaWJ1dGVOYW1lIGF0dHJpYnV0ZU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuYXR0cmlidXRlID0gZnVuY3Rpb24gKGF0dHJpYnV0ZU5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gR2V0TGlzdC5jYWxsKHRoaXMsIFRvQXR0cmlidXRlTmFtZShhdHRyaWJ1dGVOYW1lKSk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5hdHRyaWJ1dGVzID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBHZXRMaXN0LmNhbGwodGhpcywgVG9BdHRyaWJ1dGVOYW1lKCIqIikpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgcHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLmNoaWxkID0gZnVuY3Rpb24gKHByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIHI7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHRoaXM7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgciA9IHRoaXNbaV0uY2hpbGQocHJvcGVydHlOYW1lKTsKCiAgICAgICAgICAgICAgICBpZiAoci5fQ2hpbGRyZW4ubGVuZ3RoID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5jaGlsZHJlbiA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gR2V0TGlzdC5jYWxsKHRoaXMsICIqIik7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5jb21tZW50cyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCByOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHIgPSB0aGlzW2ldLmNvbW1lbnRzKCk7CgogICAgICAgICAgICAgICAgICAgIGlmIChyLl9DaGlsZHJlbi5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQocik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFhNTCB2YWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uICh2YWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXSA9PSB2YWx1ZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRGVlcENvcHlMaXN0LmNhbGwodGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLmRlc2NlbmRhbnRzID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRGVzY2VuZGFudHNMaXN0LmNhbGwodGhpcywgbmFtZSB8fCAiKiIpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgUU5hbWUgbmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5lbGVtZW50cyA9IGZ1bmN0aW9uIChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgbmFtZSA9IFRvWE1MTmFtZShuYW1lIHx8ICIqIik7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIHI7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldE9iamVjdCA9IHRoaXM7CiAgICAgICAgICAgIGxpc3QuX1RhcmdldFByb3BlcnR5ID0gbmFtZTsKCiAgICAgICAgICAgIGZvciAoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByID0gdGhpc1tpXS5lbGVtZW50cyhuYW1lKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHIuX0NoaWxkcmVuLmxlbmd0aCA+IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBIYXNQcm9wZXJ0eS5jYWxsKHRoaXMsIG5hbWUpCiAgICAgICAgICAgICAgICB8fCAoZGVmYXVsdFhNTExpc3RQcm9wZXJ0aWVzLmluZGV4T2YoIiwiICsgbmFtZSArICIsIikgPT09IC0xICYmIGhhc093blByb3BlcnR5LmNhbGwodGhpcywgbmFtZSkpOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUuaGFzQ29tcGxleENvbnRlbnQgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW4ubGVuZ3RoID09PSAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpc1swXS5oYXNDb21wbGV4Q29udGVudCgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5oYXNTaW1wbGVDb250ZW50ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggPT09IDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzWzBdLmhhc1NpbXBsZUNvbnRlbnQoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBOdW1iZXIKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaSA8IGw7KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fQ2xhc3MgPT09ICJlbGVtZW50IikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzW2ldLm5vcm1hbGl6ZSgpOwogICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXNbaV0uX0NsYXNzID09PSAidGV4dCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGkrMSA8IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCAmJiB0aGlzW2krMV0uX0NsYXNzID09PSAidGV4dCIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2ldLl9WYWx1ZSA9ICh0aGlzW2ldLl9WYWx1ZSB8fCAiIikgKyAodGhpc1tpKzFdLl9WYWx1ZSB8fCAiIik7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuRGVsZXRlKGkrMSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fVmFsdWUubGVuZ3RoID09PSAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5EZWxldGUoaSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICsraTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgKytpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MIHwgdW5kZWZpbmVkCiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUucGFyZW50ID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbi5sZW5ndGggPT09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIHBhcmVudCA9IHRoaXNbMF0uX1BhcmVudCwgaSA9IDEsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9QYXJlbnQgIT0gcGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBwYXJlbnQ7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnByb2Nlc3NpbmdJbnN0cnVjdGlvbnMgPSBmdW5jdGlvbiAobmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIG5hbWUgPSBUb1hNTE5hbWUobmFtZSB8fCAiKiIpOwogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCByOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHIgPSB0aGlzW2ldLnByb2Nlc3NpbmdJbnN0cnVjdGlvbnMobmFtZSk7CgogICAgICAgICAgICAgICAgICAgIGlmIChyLl9DaGlsZHJlbi5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQocik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IE51bWJlciBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlID0gZnVuY3Rpb24gKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQobmFtZSkgPiAwICYmIHBhcnNlSW50KG5hbWUpIDwgdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgWE1MTGlzdC5wcm90b3R5cGUudGV4dCA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoLCByOwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRPYmplY3QgPSB0aGlzOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9PT0gImVsZW1lbnQiKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHIgPSB0aGlzW2ldLnRleHQoKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHIuX0NoaWxkcmVuLmxlbmd0aCA+IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVG9TdHJpbmcodGhpcyk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnRvWE1MU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUb1hNTFN0cmluZyh0aGlzKTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLnZhbHVlT2YgPSBmdW5jdGlvbiAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IE51bWJlciB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgVmFsdWUKICAgICAgICAgKiAgICBAcGFyYW0gaXNFbGVtZW50CiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLlB1dCA9IGZ1bmN0aW9uIChQcm9wZXJ0eU5hbWUsIFZhbHVlLGlzQ2hpbGRFbGVtZW50KQogICAgICAgIHsKICAgICAgICAgICAgaXNDaGlsZEVsZW1lbnQgPSBpc0NoaWxkRWxlbWVudCAhPT0gdW5kZWZpbmVkID8gaXNDaGlsZEVsZW1lbnQgOiBmYWxzZTsKICAgICAgICAgICAgdmFyIGkgPSBwYXJzZUludChQcm9wZXJ0eU5hbWUpLCByLCB5LCBsLCB6LCBwYXJlbnQsIGMsIGogPSAwLCBxLCB0OwoKICAgICAgICAgICAgaWYgKGkrIiIgPT0gUHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByID0gUmVzb2x2ZVZhbHVlLmNhbGwodGhpcy5fVGFyZ2V0T2JqZWN0KTsKICAgICAgICAgICAgICAgIC8qIEZpcmVmb3ggZG9lc24ndCBkbyB0aGlzCiAgICAgICAgICAgICAgICAgaWYgKHIgPT0gbnVsbCkKICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoaSA+PSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHIubGVuZ3RoKCkgIT0gMSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHIgPSByWzBdOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLyogRmlyZWZveCBkb2Vzbid0IGRvIHRoaXMKICAgICAgICAgICAgICAgICAgICAgaWYgKHIuX0NsYXNzICE9ICJlbGVtZW50IikKICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHkgPSBuZXcgWE1MKCk7CiAgICAgICAgICAgICAgICAgICAgeS5fUGFyZW50ID0gcjsKICAgICAgICAgICAgICAgICAgICB5Ll9OYW1lID0gdGhpcy5fVGFyZ2V0UHJvcGVydHk7CiAgICAgICAgICAgICAgICAgICAgeS5fQXR0cmlidXRlcyA9IHt9OwoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fVGFyZ2V0UHJvcGVydHkgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhciAmJiBHZXQuY2FsbChyLCB5Ll9OYW1lKS5sZW5ndGgoKSA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB5Ll9DbGFzcyA9ICJhdHRyaWJ1dGUiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghaXNDaGlsZEVsZW1lbnQgJiYgKHRoaXMuX1RhcmdldFByb3BlcnR5ID09IG51bGwgfHwgdGhpcy5fVGFyZ2V0UHJvcGVydHkubG9jYWxOYW1lID09PSAiKiIpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgeS5fTmFtZSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIHkuX0NsYXNzID0gInRleHQiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB5Ll9DbGFzcyA9ICJlbGVtZW50IjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh5Ll9DbGFzcyAhPSAiYXR0cmlidXRlIikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqID0gMDsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGogPCByLl9DaGlsZHJlbi5sZW5ndGgtMSAmJiByW2pdICE9PSB0aGlzW2ktMV0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArK2o7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGogPSByLl9DaGlsZHJlbi5sZW5ndGggLSAxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluc2VydC5jYWxsKHIsIGorMSwgeSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChWYWx1ZSBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkuX05hbWUgPSBWYWx1ZS5fVGFyZ2V0UHJvcGVydHk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkuX05hbWUgPSBWYWx1ZS5fTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhpcy5BcHBlbmQoeSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCEoVmFsdWUgaW5zdGFuY2VvZiBYTUwpIHx8IFZhbHVlLl9DbGFzcyA9PT0gInRleHQiIHx8IFZhbHVlLl9DbGFzcyA9PT0gImF0dHJpYnV0ZSIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVmFsdWUgPSBUb1N0cmluZyhWYWx1ZSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHRoaXNbaV0uX0NsYXNzID09PSAiYXR0cmlidXRlIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB6ID0gVG9BdHRyaWJ1dGVOYW1lKHRoaXNbaV0uX05hbWUpOwogICAgICAgICAgICAgICAgICAgIHRoaXNbaV0uX1BhcmVudC5QdXQoeiwgVmFsdWUpOwogICAgICAgICAgICAgICAgICAgIHRoaXNbaV0gPSB0aGlzW2ldLl9QYXJlbnQuYXR0cmlidXRlKHopWzBdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vc2hhbGxvdyBjb3B5PwogICAgICAgICAgICAgICAgICAgIGMgPSBWYWx1ZTsKICAgICAgICAgICAgICAgICAgICBwYXJlbnQgPSB0aGlzW2ldLl9QYXJlbnQ7CgogICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBxID0gdGhpc1tpXS5jaGlsZEluZGV4KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbChwYXJlbnQsIHEsIGMpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gYy5fQ2hpbGRyZW4ubGVuZ3RoOyBqIDwgbDsgKytqKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjLl9DaGlsZHJlbltqXSA9IGNbal0gPSBwYXJlbnQuX0NoaWxkcmVuW3Eral07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmIChjLl9DaGlsZHJlbi5sZW5ndGggPT09IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSBpICsgMSwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsgaiA8IGw7ICsraikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bai0xXSA9IHRoaXNbai0xXSA9IHRoaXNbal0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGogPiBpOyAtLWopCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHogPSBUb1N0cmluZyhqICsgYy5fQ2hpbGRyZW4ubGVuZ3RoIC0gMSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlblt6XSA9IHRoaXNbel0gPSB0aGlzW2pdOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gYy5fQ2hpbGRyZW4ubGVuZ3RoOyBqIDwgbDsgKytqKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baStqXSA9IHRoaXNbaStqXSA9IGNbal07CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MIHx8ICgiLHRleHQsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uIikuaW5kZXhPZigiLCIgKyB0aGlzW2ldLl9DbGFzcysiLCIpID4gLTEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gISF0aGlzW2ldICYmIHRoaXNbaV0uX1BhcmVudDsKCiAgICAgICAgICAgICAgICAgICAgaWYocGFyZW50KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcSA9IHRoaXNbaV0uY2hpbGRJbmRleCgpOwogICAgICAgICAgICAgICAgICAgICAgICBSZXBsYWNlLmNhbGwocGFyZW50LCBxLCBWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlID0gcGFyZW50Ll9DaGlsZHJlbltxXTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh0b1N0cmluZy5jYWxsKFZhbHVlKSA9PT0gIltvYmplY3QgU3RyaW5nXSIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0ID0gVG9YTUwoVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0Ll9QYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXSA9IHRoaXNbaV0gPSB0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5BcHBlbmQoWE1MTGlzdChWYWx1ZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIEZpcmVmb3ggZG9lc24ndCBkbyB0aGlzCiAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLmxlbmd0aCgpIDw9IDEpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICBpZiAodGhpcy5sZW5ndGgoKSA9PT0gMCkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIHIgPSBSZXNvbHZlVmFsdWVMaXN0LmNhbGwodGhpcyk7CgogICAgICAgICAgICAgaWYgKHIgPT0gbnVsbCB8fCByLmxlbmd0aCgpICE9IDEpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICB0aGlzLkFwcGVuZChyKTsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIHRoaXNbMF0uUHV0KFByb3BlcnR5TmFtZSwgVmFsdWUpOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgfSovCgogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTnVtYmVyIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgbnVsbAogICAgICAgICAqLwogICAgICAgIFhNTExpc3QucHJvdG90eXBlLkRlbGV0ZSA9IGZ1bmN0aW9uIChQcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICB2YXIgaSA9IHBhcnNlSW50KFByb3BlcnR5TmFtZSksIHBhcmVudCwgcSwgbDsKCiAgICAgICAgICAgIGlmIChpKyIiID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGkgPj0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHBhcmVudCA9IHRoaXNbaV0uX1BhcmVudDsKCiAgICAgICAgICAgICAgICBpZiAocGFyZW50KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzW2ldLl9DbGFzcyA9ICJhdHRyaWJ1dGUiKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LkRlbGV0ZShUb0F0dHJpYnV0ZU5hbWUodGhpc1tpXS5fTmFtZSkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBEZWxldGVCeUluZGV4LmNhbGwocGFyZW50LCB0aGlzW2ldLmNoaWxkSW5kZXgoKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbi5zcGxpY2UoUHJvcGVydHlOYW1lLDEpOwogICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzW1Byb3BlcnR5TmFtZV07CiAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQoKICAgICAgICAgICAgICAgIGZvciAocSA9IGkgKyAxLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW3EtMV0gPSB0aGlzW3EtMV0gPSB0aGlzW3FdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogRmlyZWZveCB3b24ndCBkbyB0aGlzCiAgICAgICAgICAgICBmb3IgKHEgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBxIDwgbDsgKytxKQogICAgICAgICAgICAgewogICAgICAgICAgICAgaWYgKHRoaXNbcV0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICB0aGlzW3FdLkRlbGV0ZShQcm9wZXJ0eU5hbWUpOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBWYWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5BcHBlbmQgPSBmdW5jdGlvbiAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIShWYWx1ZSBpbnN0YW5jZW9mIFhNTCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgaSA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCwgbiA9IDEsIGogPSAwOwoKICAgICAgICAgICAgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbiA9IFZhbHVlLl9DaGlsZHJlbi5sZW5ndGg7CgogICAgICAgICAgICAgICAgaWYgKG4gPT0gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLl9UYXJnZXRPYmplY3QgPSBWYWx1ZS5fVGFyZ2V0T2JqZWN0OwogICAgICAgICAgICAgICAgdGhpcy5fVGFyZ2V0UHJvcGVydHkgPSBWYWx1ZS5fVGFyZ2V0UHJvcGVydHk7CgogICAgICAgICAgICAgICAgZm9yICg7aiA8IG47ICsraikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpK2pdID0gdGhpc1tpK2pdID0gVmFsdWVbal07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpXSA9IHRoaXNbaV0gPSBWYWx1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBWYWx1ZQogICAgICAgICAqICAgIEByZXR1cm5zIEJvb2xlYW4KICAgICAgICAgKi8KICAgICAgICBYTUxMaXN0LnByb3RvdHlwZS5FcXVhbHMgPSBmdW5jdGlvbiAoVmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoVmFsdWUgPT0gdW5kZWZpbmVkICYmIHRoaXMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUxMaXN0ICYmIFZhbHVlLl9DaGlsZHJlbi5sZW5ndGggPT09IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzW2ldLkVxdWFscyhWYWx1ZVtpXSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX0NoaWxkcmVuLmxlbmd0aCA9PT0gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXNbMF0uRXF1YWxzKFZhbHVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBSZXNvbHZlVmFsdWVMaXN0ICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW4ubGVuZ3RoID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh0aGlzLl9UYXJnZXRPYmplY3QgPT0gbnVsbAogICAgICAgICAgICAgICAgfHwgdGhpcy5fVGFyZ2V0UHJvcGVydHkgPT0gbnVsbAogICAgICAgICAgICAgICAgfHwgdGhpcy5fVGFyZ2V0UHJvcGVydHkgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lCiAgICAgICAgICAgICAgICB8fCB0aGlzLl9UYXJnZXRQcm9wZXJ0eS5sb2NhbE5hbWUgPT09ICIqIgogICAgICAgICAgICApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgYmFzZSA9IFJlc29sdmVWYWx1ZS5jYWxsKHRoaXMuX1RhcmdldE9iamVjdCksIHRhcmdldDsKCiAgICAgICAgICAgIGlmIChiYXNlID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0YXJnZXQgPSBHZXQuY2FsbChiYXNlLCB0aGlzLl9UYXJnZXRQcm9wZXJ0eSk7CgogICAgICAgICAgICBpZiAodGFyZ2V0Ll9DaGlsZHJlbi5sZW5ndGggPT09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChiYXNlIGluc3RhbmNlb2YgWE1MTGlzdCAmJiBiYXNlLl9DaGlsZHJlbi5sZW5ndGggPiAxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGJhc2UuUHV0KHRoaXMuX1RhcmdldFByb3BlcnR5LCAiIik7CgogICAgICAgICAgICAgICAgdGFyZ2V0ID0gR2V0LmNhbGwoYmFzZSwgdGhpcy5fVGFyZ2V0UHJvcGVydHkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gdGFyZ2V0OwogICAgICAgIH07CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTmFtZXNwYWNlIHwgUU5hbWUgcHJlZml4CiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB1cmkKICAgICAgICAgKiAgICBAcmV0dXJucyBOYW1lc3BhY2UKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIE5hbWVzcGFjZSAocHJlZml4LCB1cmkpCiAgICAgICAgewogICAgICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTmFtZXNwYWNlKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHByZWZpeCAmJiBwcmVmaXggaW5zdGFuY2VvZiBOYW1lc3BhY2UKICAgICAgICAgICAgICAgICAgICA/IHByZWZpeAogICAgICAgICAgICAgICAgICAgIDogbmV3IE5hbWVzcGFjZShwcmVmaXgsIHVyaSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICh1cmkgPT09IHVuZGVmaW5lZCAmJiBwcmVmaXggPT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhpcy5wcmVmaXggPSAiIjsKICAgICAgICAgICAgICAgIHRoaXMudXJpID0gIiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodXJpID09PSB1bmRlZmluZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHVyaSA9IHByZWZpeDsKICAgICAgICAgICAgICAgIHByZWZpeCA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgICAgICBpZiAodXJpIGluc3RhbmNlb2YgTmFtZXNwYWNlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMucHJlZml4ID0gdXJpLnByZWZpeDsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVyaSA9IHVyaS51cmk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICh1cmkgaW5zdGFuY2VvZiBRTmFtZSAmJiB1cmkudXJpICE9PSBudWxsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMudXJpID0gdXJpLnVyaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVyaSA9IFRvU3RyaW5nKHVyaSk7CgogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnVyaSA9PSAiIikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJlZml4ID0gIiI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHVyaSBpbnN0YW5jZW9mIFFOYW1lKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMudXJpID0gdXJpLnVyaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVyaSA9IFRvU3RyaW5nKHVyaSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKHRoaXMudXJpID09PSAiIikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocHJlZml4ID09PSB1bmRlZmluZWQgfHwgVG9TdHJpbmcocHJlZml4KSA9PT0gIiIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZWZpeCA9ICIiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCJjYW5ub3QgZGVmaW5lIHRoZSBwcmVmaXggZm9yIGFuIGVtcHR5IHVyaSIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHByZWZpeCA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMucHJlZml4ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMucHJlZml4ID0gVG9TdHJpbmcocHJlZml4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEB2YXIgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgTmFtZXNwYWNlLnByb3RvdHlwZS5wcmVmaXggPSB1bmRlZmluZWQ7CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAdmFyIFN0cmluZwogICAgICAgICAqLwogICAgICAgIE5hbWVzcGFjZS5wcm90b3R5cGUudXJpID0gdW5kZWZpbmVkOwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgTmFtZXNwYWNlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdGhpcy51cmk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBOYW1lc3BhY2UgfCBTdHJpbmcgfCBRTmFtZSBOYW1lU3BhY2UKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nCiAgICAgICAgICogICAgQHJldHVybnMgUU5hbWUKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBRTmFtZSAoTmFtZVNwYWNlLCBOYW1lKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFFOYW1lKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIE5hbWVTcGFjZSBpbnN0YW5jZW9mIFFOYW1lCiAgICAgICAgICAgICAgICAgICAgPyBOYW1lU3BhY2UKICAgICAgICAgICAgICAgICAgICA6IG5ldyBRTmFtZShOYW1lU3BhY2UsIE5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoTmFtZSA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBOYW1lID0gTmFtZVNwYWNlOwogICAgICAgICAgICAgICAgTmFtZVNwYWNlID0gdW5kZWZpbmVkOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoTmFtZXNwYWNlIGluc3RhbmNlb2YgUU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChOYW1lID09PSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTmFtZSA9IE5hbWUubG9jYWxOYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBOYW1lID0gTmFtZSA9PT0gdW5kZWZpbmVkIHx8IE5hbWUgPT09IG51bGwKICAgICAgICAgICAgICAgID8gIiIKICAgICAgICAgICAgICAgIDogVG9TdHJpbmcoTmFtZSk7CgogICAgICAgICAgICBpZiAoTmFtZVNwYWNlID09PSB1bmRlZmluZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE5hbWVTcGFjZSA9IE5hbWUgPT09ICIqIiA/IG51bGwgOiBHZXREZWZhdWx0TmFtZXNwYWNlKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMubG9jYWxOYW1lID0gTmFtZTsKCiAgICAgICAgICAgIGlmIChOYW1lU3BhY2UgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhpcy51cmkgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTmFtZVNwYWNlID0gTmFtZXNwYWNlKE5hbWVTcGFjZSk7CiAgICAgICAgICAgICAgICB0aGlzLnVyaSA9IE5hbWVTcGFjZS51cmk7CiAgICAgICAgICAgICAgICB0aGlzLl9QcmVmaXggPSBOYW1lU3BhY2UucHJlZml4OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHZhciBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBRTmFtZS5wcm90b3R5cGUubG9jYWxOYW1lID0gdW5kZWZpbmVkOwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHZhciBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBRTmFtZS5wcm90b3R5cGUudXJpID0gdW5kZWZpbmVkOwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIE9iamVjdCBJblNjb3BlTmFtZXNwYWNlcwogICAgICAgICAqICAgIEByZXR1cm5zIE5hbWVzcGFjZQogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gR2V0TmFtZXNwYWNlIChxLCBJblNjb3BlTmFtZXNwYWNlcykKICAgICAgICB7CiAgICAgICAgICAgIGlmKCFxKQogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBOYW1lc3BhY2UoKTsKICAgICAgICAgICAgaWYgKHEudXJpID09PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEluU2NvcGVOYW1lc3BhY2VzID0gSW5TY29wZU5hbWVzcGFjZXMgfHwge307CgogICAgICAgICAgICB2YXIgbnMsIHA7CgogICAgICAgICAgICBmb3IgKHAgaW4gSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChxLnVyaSA9PT0gSW5TY29wZU5hbWVzcGFjZXNbcF0udXJpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG5zID0gSW5TY29wZU5hbWVzcGFjZXNbcF07CgogICAgICAgICAgICAgICAgICAgIGlmICghIXEuX1ByZWZpeCAmJiBxLl9QcmVmaXggPT09IG5zLnByZWZpeCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuczsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghbnMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG5zID0gISFxLl9QcmVmaXgKICAgICAgICAgICAgICAgICAgICA/IG5ldyBOYW1lc3BhY2UocS5fUHJlZml4LCBxLnVyaSkKICAgICAgICAgICAgICAgICAgICA6IG5ldyBOYW1lc3BhY2UocS51cmkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbnM7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIFFOYW1lLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gISF0aGlzLnVyaQogICAgICAgICAgICAgICAgPyB0aGlzLnVyaSArICI6OiIgKyB0aGlzLmxvY2FsTmFtZQogICAgICAgICAgICAgICAgOiB0aGlzLmxvY2FsTmFtZTsKICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIEF0dHJpYnV0ZU5hbWUgfCBRTmFtZSB8IFN0cmluZyBuYW1lCiAgICAgICAgICogICAgQHJldHVybnMgQXR0cmlidXRlTmFtZQogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEF0dHJpYnV0ZU5hbWUgKG5hbWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBuYW1lICYmIChuYW1lIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSB8fCBuYW1lIGluc3RhbmNlb2YgUU5hbWUpCiAgICAgICAgICAgICAgICAgICAgPyBuYW1lCiAgICAgICAgICAgICAgICAgICAgOiBuZXcgQXR0cmlidXRlTmFtZShuYW1lKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fTmFtZSA9IG5hbWUgaW5zdGFuY2VvZiBRTmFtZQogICAgICAgICAgICAgICAgPyBuYW1lCiAgICAgICAgICAgICAgICA6IG5ldyBRTmFtZShuZXcgTmFtZXNwYWNlKEdldERlZmF1bHROYW1lc3BhY2UoKXx8dW5kZWZpbmVkKSwgbmFtZSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHZhciBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBBdHRyaWJ1dGVOYW1lLnByb3RvdHlwZS5sb2NhbE5hbWUgPSB1bmRlZmluZWQ7CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAdmFyIFN0cmluZwogICAgICAgICAqLwogICAgICAgIEF0dHJpYnV0ZU5hbWUucHJvdG90eXBlLnVyaSA9IHVuZGVmaW5lZDsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIEF0dHJpYnV0ZU5hbWUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiAiQCIgKyAoISF0aGlzLl9OYW1lLnVyaQogICAgICAgICAgICAgICAgICAgICAgICA/IHRoaXMuX05hbWUudXJpICsgIjo6IiArIHRoaXMuX05hbWUubG9jYWxOYW1lCiAgICAgICAgICAgICAgICAgICAgICAgIDogdGhpcy5fTmFtZS5sb2NhbE5hbWUKICAgICAgICAgICAgICAgICk7CiAgICAgICAgfTsKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gQW55TmFtZSAoKQogICAgICAgIHsKCiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIG1peGVkIHZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIGlzWE1MTmFtZSAodmFsdWUpCiAgICAgICAgewogICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdHJ5ewogICAgICAgICAgICAgICAgdmFyIHEgPSBRTmFtZSh2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2ggKGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuICEhcS5sb2NhbE5hbWUgJiYgKCEhcS5sb2NhbE5hbWUubWF0Y2goL15bXHdcLV0rJC9pKSB8fCAhIXEubG9jYWxOYW1lLm1hdGNoKC9eW1x3XC1cOl0rJC9pKSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIG1peGVkIHZhbHVlCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBUb1N0cmluZyAodmFsdWUpCiAgICAgICAgewogICAgICAgICAgICB2YXIgaSA9IDAsIGwsIHM7CgogICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodmFsdWUuaGFzU2ltcGxlQ29udGVudCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHMgPSAiIjsKCiAgICAgICAgICAgICAgICAgICAgZm9yIChsID0gdmFsdWUubGVuZ3RoKCk7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWVbaV0uX0NsYXNzICE9ICJjb21tZW50IiAmJiB2YWx1ZVtpXS5fQ2xhc3MgIT0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9IFRvU3RyaW5nKHZhbHVlW2ldKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIFRvWE1MU3RyaW5nKHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFhNTCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHZhbHVlLl9DbGFzcyA9PT0gImF0dHJpYnV0ZSIgfHwgdmFsdWUuX0NsYXNzID09PSAidGV4dCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLl9WYWx1ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAodmFsdWUuaGFzU2ltcGxlQ29udGVudCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHMgPSAiIjsKCiAgICAgICAgICAgICAgICAgICAgZm9yIChsID0gdmFsdWUubGVuZ3RoKCk7IGkgPCBsOyArK2kpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUuY2hpbGQoaSkuX0NsYXNzICE9ICJjb21tZW50IiAmJiB2YWx1ZS5jaGlsZChpKS5fQ2xhc3MgIT0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9IFRvU3RyaW5nKHZhbHVlLmNoaWxkKGkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIFRvWE1MU3RyaW5nKHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEF0dHJpYnV0ZU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiAiQCIgKyBUb1N0cmluZyh2YWx1ZS5fTmFtZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkCiAgICAgICAgICAgICAgICA/ICIiCiAgICAgICAgICAgICAgICA6ICIiICsgdmFsdWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFhNTCBpbnB1dAogICAgICAgICAqICAgIEBwYXJhbSBPYmplY3QgQW5jZXN0b3JOYW1lc3BhY2VzCiAgICAgICAgICogICAgQHBhcmFtIE51bWJlciBJbmRlbnRMZXZlbAogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFRvWE1MU3RyaW5nIChpbnB1dCwgQW5jZXN0b3JOYW1lc3BhY2VzLCBJbmRlbnRMZXZlbCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBzID0gIiIsIHAgPSAwLCB0ZW1wLCB0ZW1wMiwgbmFtZXNwYWNlLCBuYW1lc3BhY2VVbmlvbiwKICAgICAgICAgICAgICAgIG5hbWVzcGFjZURlY2xhcmF0aW9ucyA9IHt9LCBhdHRyQW5kTmFtZXNwYWNlcywgcHJlZml4ZXMsIGRlZmF1bHRTZXQ7CgogICAgICAgICAgICBBbmNlc3Rvck5hbWVzcGFjZXMgPSBBbmNlc3Rvck5hbWVzcGFjZXMgfHwge307CgogICAgICAgICAgICBJbmRlbnRMZXZlbCA9IE51bWJlcihJbmRlbnRMZXZlbCB8fCAwKTsKCiAgICAgICAgICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRlbXAgPSBpbnB1dC5oYXNTaW1wbGVDb250ZW50KCk7CgogICAgICAgICAgICAgICAgdGVtcDIgPSBpbnB1dC5sZW5ndGgoKTsKCiAgICAgICAgICAgICAgICBmb3IgKDsgcCA8IHRlbXAyOyArK3ApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHAgPiAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiXHJcbiI7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBzICs9IFRvWE1MU3RyaW5nKGlucHV0W3BdLCBBbmNlc3Rvck5hbWVzcGFjZXMpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGlucHV0IGluc3RhbmNlb2YgWE1MKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoWE1MLnByZXR0eVByaW50aW5nKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vcyArPSBuZXcgQXJyYXkoSW5kZW50TGV2ZWwrMSkuam9pbigiICIpOwogICAgICAgICAgICAgICAgICAgIGZvciAoOyBwIDwgSW5kZW50TGV2ZWw7ICsrcCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gIiAiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBzd2l0Y2ggKGlucHV0Ll9DbGFzcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJ0ZXh0IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMgKyBFc2NhcGVFbGVtZW50VmFsdWUoWE1MLnByZXR0eVByaW50aW5nID8gdHJpbShpbnB1dC5fVmFsdWUpIDogaW5wdXQuX1ZhbHVlKTsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAiYXR0cmlidXRlIjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMgKyBFc2NhcGVBdHRyaWJ1dGVWYWx1ZShpbnB1dC5fVmFsdWUpOwoKICAgICAgICAgICAgICAgICAgICBjYXNlICJjb21tZW50IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMgKyAiPCEtLSIgKyBpbnB1dC5fVmFsdWUgKyAiLS0+IjsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAicHJvY2Vzc2luZy1pbnN0cnVjdGlvbiI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzICsgIjw/IiArIGlucHV0Ll9OYW1lLmxvY2FsTmFtZSArICIgIiArIGlucHV0Ll9WYWx1ZSArICI/PiI7CgogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVuaW9uID0gZXh0ZW5kKHt9LCBBbmNlc3Rvck5hbWVzcGFjZXMpOwoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChwIGluIGlucHV0Ll9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGlucHV0Ll9JblNjb3BlTmFtZXNwYWNlc1twXTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUFuY2VzdG9yTmFtZXNwYWNlc1sodGVtcC5wcmVmaXh8fCIiKV0gfHwgQW5jZXN0b3JOYW1lc3BhY2VzWyh0ZW1wLnByZWZpeHx8IiIpXS51cmkgIT0gdGVtcC51cmkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlVW5pb25bKHRlbXAucHJlZml4fHwiIildID0gbmFtZXNwYWNlRGVjbGFyYXRpb25zWyh0ZW1wLnByZWZpeHx8IiIpXSA9IG5ldyBOYW1lc3BhY2UodGVtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaW5wdXQuX1BhcmVudCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlVW5pb25bKGlucHV0Ll9EZWZhdWx0TmFtZXNwYWNlLnByZWZpeHx8IiIpXSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlRGVjbGFyYXRpb25zWyhpbnB1dC5fRGVmYXVsdE5hbWVzcGFjZS5wcmVmaXh8fCIiKV0gPSBuZXcgTmFtZXNwYWNlKGlucHV0Ll9EZWZhdWx0TmFtZXNwYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgLy9maXJlZm94IGRvZXNuJ3QgZG8gdGhpcwogICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChwIGluIGlucHV0Ll9BdHRyaWJ1dGVzKQogICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlID0gR2V0TmFtZXNwYWNlKGlucHV0Ll9BdHRyaWJ1dGVzW3BdLl9OYW1lLCBuYW1lc3BhY2VVbmlvbik7CgogICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZS5wcmVmaXggPT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZS5wcmVmaXggPSAhbmFtZXNwYWNlVW5pb25bIiJdID8gIiIgOiBuZXdQcmVmaXgoKTsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlKCEhbmFtZXNwYWNlVW5pb25bbmFtZXNwYWNlLnByZWZpeF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVuaW9uW25hbWVzcGFjZS5wcmVmaXhdID0gbmFtZXNwYWNlRGVjbGFyYXRpb25zW25hbWVzcGFjZS5wcmVmaXhdID0gbmFtZXNwYWNlOwogICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgKi8KCiAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gIjwiOwoKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlID0gR2V0TmFtZXNwYWNlKGlucHV0Ll9OYW1lLCBuYW1lc3BhY2VEZWNsYXJhdGlvbnMpOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZS5wcmVmaXgpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gbmFtZXNwYWNlLnByZWZpeCArICI6IjsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgcyArPSBpbnB1dC5fTmFtZSA/IGlucHV0Ll9OYW1lLmxvY2FsTmFtZSA6ICIiOwoKICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckFuZE5hbWVzcGFjZXMgPSBleHRlbmQoe30sIGlucHV0Ll9BdHRyaWJ1dGVzLCBuYW1lc3BhY2VEZWNsYXJhdGlvbnMpOwoKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFNldCA9IGZhbHNlOwoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChwIGluIGF0dHJBbmROYW1lc3BhY2VzKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICIgIjsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ckFuZE5hbWVzcGFjZXNbcF0gaW5zdGFuY2VvZiBYTUwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IEdldE5hbWVzcGFjZShhdHRyQW5kTmFtZXNwYWNlc1twXS5fTmFtZSwgQW5jZXN0b3JOYW1lc3BhY2VzKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAucHJlZml4ID09PSB1bmRlZmluZWQgJiYgIW5hbWVzcGFjZVVuaW9uWyIiXSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcC5wcmVmaXggPSAhbmFtZXNwYWNlVW5pb25bIiJdID8gIiIgOiBuZXdQcmVmaXgoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZShuYW1lc3BhY2VVbmlvblt0ZW1wLnByZWZpeF0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlVW5pb25bdGVtcC5wcmVmaXhdID0gbmFtZXNwYWNlRGVjbGFyYXRpb25zW3RlbXAucHJlZml4XSA9IG5ldyBOYW1lc3BhY2UodGVtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcC5wcmVmaXgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9IHRlbXAucHJlZml4ICsgIjoiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSBhdHRyQW5kTmFtZXNwYWNlc1twXS5sb2NhbE5hbWUoKSArICc9IicgKyBFc2NhcGVBdHRyaWJ1dGVWYWx1ZShhdHRyQW5kTmFtZXNwYWNlc1twXS5fVmFsdWUpICsgJyInOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gInhtbG5zIjsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXggJiYgZGVmYXVsdFNldCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4ID0gbmV3UHJlZml4KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUoISFuYW1lc3BhY2VVbmlvblthdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXhdKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZVVuaW9uW2F0dHJBbmROYW1lc3BhY2VzW3BdLnByZWZpeF0gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlRGVjbGFyYXRpb25zW2F0dHJBbmROYW1lc3BhY2VzW3BdLnByZWZpeF0gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBOYW1lc3BhY2UoYXR0ckFuZE5hbWVzcGFjZXNbcF0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiOiIgKyBhdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFhdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXggJiYgIWRlZmF1bHRTZXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0U2V0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoYXR0ckFuZE5hbWVzcGFjZXNbcF0ucHJlZml4KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyArPSAiOiIgKyBhdHRyQW5kTmFtZXNwYWNlc1twXS5wcmVmaXg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICc9IicgKyBFc2NhcGVBdHRyaWJ1dGVWYWx1ZShhdHRyQW5kTmFtZXNwYWNlc1twXS51cmkpICsgJyInOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wID0gaW5wdXQuX0NoaWxkcmVuLmxlbmd0aDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGVtcCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMgKyAiLz4iOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBzICs9ICI+IjsKCiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gdGVtcCA+IDEgfHwgKHRlbXAgPT0gMSAmJiBpbnB1dC5fQ2xhc3MgIT09ICJ0ZXh0Iik7CgogICAgICAgICAgICAgICAgICAgICAgICBuYW1lcyA9ICghIVhNTC5wcmV0dHlQcmludGluZyAmJiAhIXRlbXAyKSA/IEluZGVudExldmVsICsgTnVtYmVyKFhNTC5wcmV0dHlJbmRlbnQpIDogMDsKCiAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeGVzID0gISFYTUwucHJldHR5UHJpbnRpbmcgJiYgISF0ZW1wMjsKCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAocCA9IDA7IHAgPCB0ZW1wOyArK3ApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmVmaXhlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICJcclxuIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXQuX0NoaWxkcmVuW3BdKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gVG9YTUxTdHJpbmcoaW5wdXQuX0NoaWxkcmVuW3BdLCBuYW1lc3BhY2VEZWNsYXJhdGlvbnMsIG5hbWVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZWZpeGVzKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICJcclxuIjsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHAgPSAwOyBwIDwgSW5kZW50TGV2ZWw7ICsrcCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzICs9ICIgIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHMgKyAiPC8iICsgKG5hbWVzcGFjZS5wcmVmaXggPyBuYW1lc3BhY2UucHJlZml4ICsgIjoiIDogIiIpICsgaW5wdXQuX05hbWUubG9jYWxOYW1lICsgIj4iOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChpbnB1dCA9PT0gdW5kZWZpbmVkIHx8IGlucHV0ID09PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICJbb2JqZWN0IE9iamVjdF0iKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gRXNjYXBlRWxlbWVudFZhbHVlKCBpbnB1dC52YWx1ZU9mKCkudG9TdHJpbmcoKSApOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gVG9TdHJpbmcoaW5wdXQpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBtaXhlZCBzCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICogICAgQHRocm93cyBTeW50YXhFcnJvciB8IFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFRvWE1MIChzKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHgsIGRpdjsKCiAgICAgICAgICAgIGlmIChzIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHMubGVuZ3RoKCkgPT0gMSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc1swXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChzIGluc3RhbmNlb2YgWE1MKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICgoIixzdHJpbmcsbnVtYmVyLGJvb2xlYW4sIikuaW5kZXhPZigiLCIgKyB0eXBlb2YocykrIiwiKSA+IC0xKQogICAgICAgICAgICB7CgogICAgICAgICAgICAgICAgZGl2ID0gcGFyc2UoJzxwYXJlbnQgeG1sbnM9IicgKyBHZXREZWZhdWx0TmFtZXNwYWNlKCkgKyAnIj4nICsgcyArICc8L3BhcmVudD4nKTsKCiAgICAgICAgICAgICAgICB4ID0gVG9YTUwoZGl2LmRvY3VtZW50RWxlbWVudCkKCiAgICAgICAgICAgICAgICBpZiAoeCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoeC5sZW5ndGgoKSA9PSAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBYTUwoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoeC5sZW5ndGgoKSA9PSAxKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgeC5jaGlsZCgwKS5fUGFyZW50ID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHguY2hpbGQoMCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoIkZhaWxlZCB0byBjb252ZXJ0IERPTSBvYmplY3QgdG8gWE1MIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocy5ub2RlVHlwZSAmJiAhaXNOYU4ocy5ub2RlVHlwZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBNYXBJbmZvSXRlbVRvWE1MKHMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIERPTU5vZGUgaQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gTWFwSW5mb0l0ZW1Ub1hNTCAoaSxuKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHggPSBuZXcgWE1MKCksIHRlbXAsIHRlbXAyLCB0ZW1wMywgaXNOU2NoZWNrID0gaXNOU0RlZiwgaiwgbCwgeG1sQ2hpbGQ7CgogICAgICAgICAgICB4Ll9QYXJlbnQgPSBudWxsOwoKICAgICAgICAgICAgc3dpdGNoIChpLm5vZGVUeXBlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIFRFWFRfTk9ERToKICAgICAgICAgICAgICAgIGNhc2UgQ0RBVEFfU0VDVElPTl9OT0RFOgogICAgICAgICAgICAgICAgICAgIHguX0NsYXNzID0gInRleHQiOwogICAgICAgICAgICAgICAgICAgIHguX1ZhbHVlID0gIiI7CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGk7CgogICAgICAgICAgICAgICAgICAgIHdoaWxlICh0ZW1wICYmICh0ZW1wLm5vZGVUeXBlID09PSBURVhUX05PREUgfHwgdGVtcC5ub2RlVHlwZSA9PT0gQ0RBVEFfU0VDVElPTl9OT0RFKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHguX1ZhbHVlICs9IHRlbXAudGV4dENvbnRlbnQgfHwgdGVtcC50ZXh0IHx8IHRlbXAuZGF0YTsKICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IHRlbXAubmV4dFNpYmxpbmc7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuICYmIChuLm4gfHwgbi5uID09IDApKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICArK24ubjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCgogICAgICAgICAgICAgICAgICAgIGlmIChYTUwuaWdub3JlV2hpdGVzcGFjZSAmJiAheC5fVmFsdWUubWF0Y2goL1xTKy8pKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICByZXR1cm4geDsKCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIENPTU1FTlRfTk9ERToKICAgICAgICAgICAgICAgICAgICBpZiAoWE1MLmlnbm9yZUNvbW1lbnRzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB4Ll9DbGFzcyA9ICJjb21tZW50IjsKICAgICAgICAgICAgICAgICAgICB4Ll9WYWx1ZSA9IGkuZGF0YSB8fCBpLnRleHRDb250ZW50IHx8IGkudGV4dCB8fCAiIjsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHg7CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBQUk9DRVNTSU5HX0lOU1RSVUNUSU9OX05PREU6CiAgICAgICAgICAgICAgICAgICAgaWYgKFhNTC5pZ25vcmVQcm9jZXNzaW5nSW5zdHJ1Y3Rpb25zKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB4Ll9DbGFzcyA9ICJwcm9jZXNzaW5nLWluc3RydWN0aW9uIjsKICAgICAgICAgICAgICAgICAgICB4Ll9OYW1lID0gbmV3IFFOYW1lKCIiLCBpLnRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgeC5fVmFsdWUgPSBpLmRhdGEgfHwgaS50ZXh0Q29udGVudCB8fCBpLnRleHQgfHwgIiI7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB4OwoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgQVRUUklCVVRFX05PREU6CiAgICAgICAgICAgICAgICAgICAgeC5fQ2xhc3MgPSAiYXR0cmlidXRlIjsKCiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGkubm9kZU5hbWUubWF0Y2goLygoW1x3XC1dKyk6KT8oW1x3XC1dKykvKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCB0ZW1wWzFdICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhaS5sb29rdXBOYW1lc3BhY2UpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gaS5sb29rdXBOYW1lc3BhY2UodGVtcFsyXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMyA9IG47Ly9oYWNrIGZvciBpZSAtLSBzdHVwaWQgaWUKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoIXRlbXAyICYmICEhdGVtcDMgJiYgISF0ZW1wMy5hdHRyaWJ1dGVzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDAsIGwgPSB0ZW1wMy5hdHRyaWJ1dGVzLmxlbmd0aDsgaiA8IGw7ICsraikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wMy5hdHRyaWJ1dGVzW2pdLm5vZGVOYW1lID09ICgieG1sbnM6IiArIHRlbXBbMl0pKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHRlbXAzLmF0dHJpYnV0ZXNbal0udmFsdWUgfHwgdGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDMgPSB0ZW1wMy5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHguX0RlZmF1bHROYW1lc3BhY2UgPSBuZXcgTmFtZXNwYWNlKCB0ZW1wWzJdLCB0ZW1wMiApOwogICAgICAgICAgICAgICAgICAgICAgICB4Ll9OYW1lID0gbmV3IFFOYW1lKCB4Ll9EZWZhdWx0TmFtZXNwYWNlLCB0ZW1wWzNdICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhaS5sb29rdXBOYW1lc3BhY2UpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gaS5sb29rdXBOYW1lc3BhY2UoIiIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDMgPSBpLnBhcmVudE5vZGU7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCF0ZW1wMiAmJiAhIXRlbXAzICYmICEhdGVtcDMuYXR0cmlidXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gdGVtcDMuYXR0cmlidXRlcy5sZW5ndGg7IGogPCBsOyArK2opCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlTmFtZSA9PSAieG1sbnMiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHRlbXAzLmF0dHJpYnV0ZXNbal0udmFsdWUgfHwgdGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDMgPSB0ZW1wMy5wYXJlbnROb2RlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB4Ll9EZWZhdWx0TmFtZXNwYWNlID0gbmV3IE5hbWVzcGFjZSgiIiwgdGVtcDIpOwogICAgICAgICAgICAgICAgICAgICAgICB4Ll9OYW1lID0gbmV3IFFOYW1lKCB4Ll9EZWZhdWx0TmFtZXNwYWNlLCB0ZW1wWzNdICk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB4Ll9WYWx1ZSA9IGkudmFsdWUgfHwgbnVsbDsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHg7CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBFTEVNRU5UX05PREU6CiAgICAgICAgICAgICAgICAgICAgeC5fQ2xhc3MgPSAiZWxlbWVudCI7CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGkubm9kZU5hbWUubWF0Y2goLygoW1x3XC1dKyk6KT8oW1x3XC1dKykvKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCB0ZW1wWzFdICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gdW5kZWZpbmVkOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhaS5sb29rdXBOYW1lc3BhY2UpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gaS5sb29rdXBOYW1lc3BhY2UodGVtcFsyXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMyA9IGk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCF0ZW1wMiAmJiAhIXRlbXAzICYmICEhdGVtcDMuYXR0cmlidXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAwLCBsID0gdGVtcDMuYXR0cmlidXRlcy5sZW5ndGg7IGogPCBsOyArK2opCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcDMuYXR0cmlidXRlc1tqXS5ub2RlTmFtZSA9PSAoInhtbG5zOiIgKyB0ZW1wWzJdKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcDIgPSB0ZW1wMy5hdHRyaWJ1dGVzW2pdLnZhbHVlIHx8IHRlbXAzLmF0dHJpYnV0ZXNbal0ubm9kZVZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAzID0gdGVtcDMucGFyZW50Tm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB4Ll9EZWZhdWx0TmFtZXNwYWNlID0gbmV3IE5hbWVzcGFjZSggdGVtcFsyXSwgdGVtcDIgKTsKICAgICAgICAgICAgICAgICAgICAgICAgeC5fTmFtZSA9IG5ldyBRTmFtZSggeC5fRGVmYXVsdE5hbWVzcGFjZSwgdGVtcFszXSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IHVuZGVmaW5lZDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWkubG9va3VwTmFtZXNwYWNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMiA9IGkubG9va3VwTmFtZXNwYWNlKCIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAzID0gaTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoIXRlbXAyICYmICEhdGVtcDMgJiYgISF0ZW1wMy5hdHRyaWJ1dGVzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDAsIGwgPSB0ZW1wMy5hdHRyaWJ1dGVzLmxlbmd0aDsgaiA8IGw7ICsraikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wMy5hdHRyaWJ1dGVzW2pdLm5vZGVOYW1lID09ICJ4bWxucyIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAyID0gdGVtcDMuYXR0cmlidXRlc1tqXS52YWx1ZSB8fCB0ZW1wMy5hdHRyaWJ1dGVzW2pdLm5vZGVWYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wMyA9IHRlbXAzLnBhcmVudE5vZGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHguX0RlZmF1bHROYW1lc3BhY2UgPSBuZXcgTmFtZXNwYWNlKCIiLCB0ZW1wMik7CgogICAgICAgICAgICAgICAgICAgICAgICB4Ll9OYW1lID0gbmV3IFFOYW1lKCB4Ll9EZWZhdWx0TmFtZXNwYWNlLCB0ZW1wWzNdICk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBmb3IgKHRlbXAgPSAwLCB0ZW1wMiA9IGkuYXR0cmlidXRlcy5sZW5ndGg7IHRlbXAgPCB0ZW1wMjsgKyt0ZW1wKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAzID0gaXNOU2NoZWNrLmV4ZWMoaS5hdHRyaWJ1dGVzW3RlbXBdLm5vZGVOYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeC5fSW5TY29wZU5hbWVzcGFjZXNbdGVtcDNbMV1dID0gbmV3IE5hbWVzcGFjZSh0ZW1wM1sxXSwgaS5hdHRyaWJ1dGVzW3RlbXBdLnZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChpLmF0dHJpYnV0ZXNbdGVtcF0ubm9kZU5hbWUgPT09ICJ4bWxucyIpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHguX0luU2NvcGVOYW1lc3BhY2VzWyIiXSA9IG5ldyBOYW1lc3BhY2UoaS5hdHRyaWJ1dGVzW3RlbXBdLnZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHguX0F0dHJpYnV0ZXNbaS5hdHRyaWJ1dGVzW3RlbXBdLm5vZGVOYW1lXSA9IE1hcEluZm9JdGVtVG9YTUwoaS5hdHRyaWJ1dGVzW3RlbXBdLCBpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaiA9IDA7CiAgICAgICAgICAgICAgICAgICAgeG1sQ2hpbGQgPSAwOwogICAgICAgICAgICAgICAgICAgIHRlbXAgPSBpLmNoaWxkTm9kZXMubGVuZ3RoOwoKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaiA8IHRlbXApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuID0ge246LTF9OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcDMgPSBNYXBJbmZvSXRlbVRvWE1MKGkuY2hpbGROb2Rlc1tqXSwgbikpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZXZlbiB0aG91Z2ggaXQgaXMgbm90IHdyaXR0ZW4gdGhpcyB3YXkgaW4gdGhlIHNwZWMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcyBpcyBob3cgaXQgd29ya3MgaW4gRmlyZWZveAogICAgICAgICAgICAgICAgICAgICAgICAgICAgeC5fQ2hpbGRyZW5beG1sQ2hpbGRdID0gdGVtcDM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4Ll9DaGlsZHJlblt4bWxDaGlsZF0uX1BhcmVudCA9IHg7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAzLl9DbGFzcyA9PT0gInRleHQiICYmIG4ubiA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaiA9IGogKyBuLm47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKyt4bWxDaGlsZDsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgKytqOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgeC5fVmFsdWUgPSBpLnRleHRDb250ZW50IHx8IGkudGV4dCB8fCBpLmRhdGEgfHwgIiI7CgogICAgICAgICAgICAgICAgICAgIHguX0xlbmd0aCA9IHhtbENoaWxkOwoKICAgICAgICAgICAgICAgICAgICByZXR1cm4geDsKCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIERPQ1VNRU5UX05PREU6CiAgICAgICAgICAgICAgICAvL2ZpcmVmb3ggd29uJ3QgZG8gdGhpcwogICAgICAgICAgICAgICAgLy9yZXR1cm4gTWFwSW5mb0l0ZW1Ub1hNTChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpOwogICAgICAgICAgICAgICAgLy9icmVhazsKICAgICAgICAgICAgICAgIGNhc2UgRU5USVRZX1JFRkVSRU5DRV9OT0RFOgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gbWl4ZWQgcwogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqICAgIEB0aHJvd3MgVHlwZUVycm9yCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gVG9YTUxMaXN0IChzKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGUseCxsaXN0LGksbDsKCiAgICAgICAgICAgIGlmIChzIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocyBpbnN0YW5jZW9mIFhNTCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbGlzdCA9IG5ldyBYTUxMaXN0KCk7CiAgICAgICAgICAgICAgICBsaXN0Ll9DaGlsZHJlblswXSA9IGxpc3RbMF0gPSBzOwogICAgICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0geC5fUGFyZW50OwogICAgICAgICAgICAgICAgbGlzdC5fVGFyZ2V0UHJvcGVydHkgPSB4Ll9OYW1lOwoKICAgICAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKCgiLHN0cmluZyxib29sZWFuLG51bWJlciwiKS5pbmRleE9mKCIsIiArIHR5cGVvZihzKSsiLCIpID09PSAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBlID0gcGFyc2UoJzxwYXJlbnQgeG1sbnM9IicgKyBHZXREZWZhdWx0TmFtZXNwYWNlKCkgKyAnIj4nICsgcyArICc8L3BhcmVudD4nKTsKICAgICAgICAgICAgeCA9IFRvWE1MKGUuZG9jdW1lbnRFbGVtZW50KTsKICAgICAgICAgICAgbGlzdCA9IG5ldyBYTUxMaXN0KCk7CiAgICAgICAgICAgIGkgPSAwOwogICAgICAgICAgICBsID0geC5fQ2hpbGRyZW4ubGVuZ3RoOwoKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gbnVsbDsKCiAgICAgICAgICAgIGZvciAoO2kgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHguX0NoaWxkcmVuW2ldLl9QYXJlbnQgPSBudWxsOwogICAgICAgICAgICAgICAgbGlzdC5fQ2hpbGRyZW5baV0gPSBsaXN0W2ldID0geC5fQ2hpbGRyZW5baV07CiAgICAgICAgICAgIH0KCgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gbWl4ZWQgcwogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKiAgICBAdGhyb3dzIFR5cGVFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIFRvQXR0cmlidXRlTmFtZSAocykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChzID09PSAiKiIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlTmFtZShuZXcgUU5hbWUobnVsbCwgIioiKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocyBpbnN0YW5jZW9mIFFOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZU5hbWUocyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocyBpbnN0YW5jZW9mIEF0dHJpYnV0ZU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzd2l0Y2ggKHR5cGVvZihzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSAidW5kZWZpbmVkIjoKICAgICAgICAgICAgICAgIGNhc2UgIm51bGwiOgogICAgICAgICAgICAgICAgY2FzZSAiYm9vbGVhbiI6CiAgICAgICAgICAgICAgICBjYXNlICJudW1iZXIiOgogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInN0cmluZyI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGVOYW1lKG5ldyBRTmFtZShudWxsLCAocyArICIiKS5yZXBsYWNlKC9eQC8sIiIpKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJvYmplY3QiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlTmFtZShuZXcgUU5hbWUobnVsbCwgVG9TdHJpbmcocykpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBtaXhlZCBzCiAgICAgICAgICogICAgQHJldHVybnMgUU5hbWUgfCBBdHRyaWJ1dGVOYW1lCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBUb1hNTE5hbWUgKHMpCiAgICAgICAgewogICAgICAgICAgICBpZiAocyBpbnN0YW5jZW9mIFFOYW1lIHx8IHMgaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChzID09PSAiKiIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUU5hbWUoIioiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3dpdGNoICh0eXBlb2YocykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgInVuZGVmaW5lZCI6CiAgICAgICAgICAgICAgICBjYXNlICJudWxsIjoKICAgICAgICAgICAgICAgIGNhc2UgImJvb2xlYW4iOgogICAgICAgICAgICAgICAgY2FzZSAibnVtYmVyIjoKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJzdHJpbmciOgogICAgICAgICAgICAgICAgICAgIGlmIChzLmNoYXJBdCgwKSA9PT0gIkAiKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFRvQXR0cmlidXRlTmFtZSggcy5zdWJzdHIoMCkgKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUU5hbWUocyk7CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAib2JqZWN0IjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVG9YTUxOYW1lKCBUb1N0cmluZyhzKSApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gR2V0RGVmYXVsdE5hbWVzcGFjZSAoKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuICEhZGVmYXVsdE5hbWVzcGFjZSAmJiBkZWZhdWx0TmFtZXNwYWNlLnVyaSB8fCAiIjsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHMKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBFc2NhcGVFbGVtZW50VmFsdWUgKHMpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gKChzfHwiIikrIiIpLnJlcGxhY2UoLy4vZywgZnVuY3Rpb24gKGMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICI8IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImbHQ7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICI+IjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImZ3Q7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICImIjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImYW1wOyI7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBzCiAgICAgICAgICogICAgQHJldHVybnMgU3RyaW5nCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gRXNjYXBlQXR0cmlidXRlVmFsdWUgKHMpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gKChzfHwiIikrIiIpLnJlcGxhY2UoLy4vZywgZnVuY3Rpb24gKGMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN3aXRjaCAoYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICciJzoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImcXVvdDsiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIjwiOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiZsdDsiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIj4iOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiZndDsiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIiYiOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiZhbXA7IjsKICAgICAgICAgICAgICAgICAgICBjYXNlICJcciI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiJiN4QTsiOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIlxuIjoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICImI3hEOyI7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiXHQiOgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIiYjeDk7IjsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBHZXQgKFByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIEdldExpc3QuY2FsbCh0aGlzLCBQcm9wZXJ0eU5hbWUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocGFyc2VJbnQoUHJvcGVydHlOYW1lKSsiIiA9PSBQcm9wZXJ0eU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBHZXRMaXN0LmNhbGwoVG9YTUxMaXN0KHRoaXMpLCBQcm9wZXJ0eU5hbWUgKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIG4gPSBUb1hNTE5hbWUoUHJvcGVydHlOYW1lKSwKICAgICAgICAgICAgICAgIGxpc3QgPSBuZXcgWE1MTGlzdCgpLCBwLCBsOwoKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gdGhpczsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0UHJvcGVydHkgPSBuOwoKICAgICAgICAgICAgaWYgKG4gaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKHAgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgIChuLl9OYW1lLmxvY2FsTmFtZSA9PT0gIioiIHx8IG4uX05hbWUubG9jYWxOYW1lID09PSB0aGlzLl9BdHRyaWJ1dGVzW3BdLl9OYW1lLmxvY2FsTmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKG4uX05hbWUudXJpID09IG51bGwgfHwgbi5fTmFtZS51cmkgPT09IHRoaXMuX0F0dHJpYnV0ZXNbcF0uX05hbWUudXJpKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRoaXMuX0F0dHJpYnV0ZXNbcF0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAocCA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IHAgPCBsOyArK3ApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAobi5sb2NhbE5hbWUgPT09ICIqIiB8fCAodGhpcy5fQ2hpbGRyZW5bcF0uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgdGhpcy5fQ2hpbGRyZW5bcF0uX05hbWUubG9jYWxOYW1lID09PSBuLmxvY2FsTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChuLnVyaSA9PSBudWxsIHx8ICh0aGlzLl9DaGlsZHJlbltwXS5fQ2xhc3MgPT09ICJlbGVtZW50IiAmJiBuLnVyaSA9PT0gdGhpcy5fQ2hpbGRyZW5bcF0uX05hbWUudXJpKSkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZCh0aGlzLl9DaGlsZHJlbltwXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQCiAgICAgICAgICogICAgQHJldHVybnMgQm9vbGVhbgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEhhc1Byb3BlcnR5IChQKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gSGFzUHJvcGVydHlMaXN0LmNhbGwodGhpcywgUCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChwYXJzZUludChQKSA9PSBQKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gUCA9PSAiMCI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBuID0gVG9YTUxOYW1lKFApLCBrLCBsOwoKICAgICAgICAgICAgaWYgKG4gaW5zdGFuY2VvZiBBdHRyaWJ1dGVOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGsgaW4gdGhpcy5fQXR0cmlidXRlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAgICAgICAgICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG4uX05hbWUubG9jYWxOYW1lID09PSAiKiIgfHwgbi5fTmFtZS5sb2NhbE5hbWUgPT09IHRoaXMuX0F0dHJpYnV0ZXNba10uX05hbWUubG9jYWxOYW1lCiAgICAgICAgICAgICAgICAgICAgICAgICkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbi5fTmFtZS51cmkgPT0gbnVsbCB8fCBuLl9OYW1lLnVyaSA9PT0gdGhpcy5fQXR0cmlidXRlc1trXS5fTmFtZS51cmkKICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoayA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGsgPCBsOyArK2spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAobi5sb2NhbE5hbWUgPT09ICIqIiB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgdGhpcy5fQ2hpbGRyZW5ba10uX05hbWUubG9jYWxOYW1lID09PSBuLmxvY2FsTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICAgICAobi51cmkgPT0gbnVsbCB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgbi51cmkgPT09IHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLnVyaSkpCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBEZWxldGVCeUluZGV4IChQcm9wZXJ0eU5hbWUpCiAgICAgICAgewogICAgICAgICAgICB2YXIgaSA9IHBhcnNlSW50KFByb3BlcnR5TmFtZSk7Ly8sIHEgPSBpICsgMSwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aDsKCiAgICAgICAgICAgIGlmIChpID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5fQ2hpbGRyZW5baV0pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5baV0uX1BhcmVudCA9IG51bGw7CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW2ldID0gbnVsbDsKCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW4uc3BsaWNlKGksIDEpOwoKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICBmb3IgKDtxIDwgbDsrK3EpCiAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bcS0xXSA9IHRoaXMuX0NoaWxkcmVuW3FdOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIERlZXBDb3B5ICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBEZWVwQ29weUxpc3QuY2FsbCh0aGlzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHkgPSBuZXcgWE1MKCksIGksIGw7Ly8sIGMsIHQ7CgogICAgICAgICAgICB5Ll9DbGFzcyA9IHRoaXMuX0NsYXNzOwogICAgICAgICAgICB5Ll9OYW1lID0gdGhpcy5fTmFtZTsKICAgICAgICAgICAgeS5fRGVmYXVsdE5hbWVzcGFjZSA9IHRoaXMuX0RlZmF1bHROYW1lc3BhY2UgPyBuZXcgTmFtZXNwYWNlKHRoaXMuX0RlZmF1bHROYW1lc3BhY2UpIDogbnVsbDsKICAgICAgICAgICAgeS5fVmFsdWUgPSB0aGlzLl9WYWx1ZTsKICAgICAgICAgICAgeS5fUGFyZW50ID0gbnVsbDsKCiAgICAgICAgICAgIGZvciAoaSBpbiB0aGlzLl9JblNjb3BlTmFtZXNwYWNlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgeS5fSW5TY29wZU5hbWVzcGFjZXNbaV0gPSBuZXcgTmFtZXNwYWNlKHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzLnByZWZpeCwgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMudXJpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChsIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8veS5fQXR0cmlidXRlc1tpXSA9IGFyZ3VtZW50cy5jYWxsZWUuY2FsbCh0aGlzLl9BdHRyaWJ1dGVzW2ldKTsKICAgICAgICAgICAgICAgIC8vbm90IHBhcnQgb2YgdGhlIHNwZWMKICAgICAgICAgICAgICAgIHkuX0F0dHJpYnV0ZXNbaV0gPSB0aGlzLl9BdHRyaWJ1dGVzW2xdLmNvcHkoKTsKICAgICAgICAgICAgICAgIHkuX0F0dHJpYnV0ZXNbaV0uX1BhcmVudCA9IHk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHkuX0NoaWxkcmVuW2ldID0gdGhpcy5fQ2hpbGRyZW5baV0uY29weSgpOwogICAgICAgICAgICAgICAgeS5fQ2hpbGRyZW5baV0uX1BhcmVudCA9IHk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB5OwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHJldHVybnMgWE1MCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gUmVzb2x2ZVZhbHVlICgpCiAgICAgICAgewogICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIFhNTExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBSZXNvbHZlVmFsdWVMaXN0LmNhbGwodGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBYTUwgPyB0aGlzIDogbnVsbDsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBhY2Nlc3MgcHJpdmF0ZQogICAgICAgICAqICAgIEBwYXJhbSBTdHJpbmcgfCBRTmFtZSBQcm9wZXJ0eU5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gRGVzY2VuZGFudHMgKFByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIERlc2NlbmRhbnRzTGlzdC5jYWxsKHRoaXMsIFByb3BlcnR5TmFtZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBuID0gVG9YTUxOYW1lKFByb3BlcnR5TmFtZSksCiAgICAgICAgICAgICAgICBsaXN0ID0gbmV3IFhNTExpc3QoKSwKICAgICAgICAgICAgICAgIGssIGwsIGRxOwoKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gbnVsbDsKCiAgICAgICAgICAgIGlmIChuIGluc3RhbmNlb2YgQXR0cmlidXRlTmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChrIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgICAgICAgICAobi5fTmFtZS5sb2NhbE5hbWUgPT09ICIqIiB8fCBuLl9OYW1lLmxvY2FsTmFtZSA9PT0gdGhpcy5fQXR0cmlidXRlc1trXS5fTmFtZS5sb2NhbE5hbWUpCiAgICAgICAgICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChuLl9OYW1lLnVyaSA9PSBudWxsIHx8IG4uX05hbWUudXJpID09PSB0aGlzLl9BdHRyaWJ1dGVzW2tdLl9OYW1lLnVyaSkKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZCh0aGlzLl9BdHRyaWJ1dGVzW2tdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoayA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7IGsgPCBsOyArK2spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICAgICAobi5sb2NhbE5hbWUgPT09ICIqIiB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgdGhpcy5fQ2hpbGRyZW5ba10uX05hbWUubG9jYWxOYW1lID09PSBuLmxvY2FsTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICAgICAobi51cmkgPT0gbnVsbCB8fCAodGhpcy5fQ2hpbGRyZW5ba10uX0NsYXNzID09PSAiZWxlbWVudCIgJiYgbi51cmkgPT09IHRoaXMuX0NoaWxkcmVuW2tdLl9OYW1lLnVyaSkpCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQodGhpcy5fQ2hpbGRyZW5ba10pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGRxID0gdGhpcy5fQ2hpbGRyZW5ba10uZGVzY2VuZGFudHMobik7CgogICAgICAgICAgICAgICAgaWYgKGRxLmxlbmd0aCgpID4gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBsaXN0LkFwcGVuZChkcSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgVmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBudWxsCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IgfCBFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEluc2VydCAoUHJvcGVydHlOYW1lLCBWYWx1ZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoIix0ZXh0LGNvbW1lbnQscHJvY2Vzc2luZy1pbnN0cnVjdGlvbixhdHRyaWJ1dGUsIikuaW5kZXhPZigiLCIgKyB0aGlzLl9DbGFzcyArICIsIikgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgaSA9IHBhcnNlSW50KFByb3BlcnR5TmFtZSksIG4sIGo7CgogICAgICAgICAgICBpZiAoaSsiIiAhPSBQcm9wZXJ0eU5hbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoIiciICsgaSArICInICE9ICciICsgUHJvcGVydHlOYW1lICsgIiciKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKFZhbHVlID09PSB0aGlzIHx8IGluZGV4T2YoIiwiICsgdGhpcywgVmFsdWUuZGVzY2VuZGFudHMoIioiKSkgPiAtMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG4gPSBWYWx1ZS5sZW5ndGgoKTsKCiAgICAgICAgICAgIGZvciAoaiA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCAtIDE7IGogPj0gaTsgLS1qKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlblsgaiArIG4gXSA9IHRoaXMuX0NoaWxkcmVuW2pdOwogICAgICAgICAgICB9CgoKICAgICAgICAgICAgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IG47ICsraikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBWYWx1ZVtqXS5fUGFyZW50ID0gdGhpczsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltpICsgal0gPSBWYWx1ZVtqXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJlcGxhY2UuY2FsbCh0aGlzLCBpLCBWYWx1ZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEBwYXJhbSBYTUwgVmFsdWUKICAgICAgICAgKiAgICBAcmV0dXJucyBudWxsCiAgICAgICAgICogICAgQHRocm93cyBUeXBlRXJyb3IKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBSZXBsYWNlIChQcm9wZXJ0eU5hbWUsIFZhbHVlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCgiLHRleHQsY29tbWVudCxwcm9jZXNzaW5nLWluc3RydWN0aW9uLGF0dHJpYnV0ZSwiKS5pbmRleE9mKCIsIiArIHRoaXMuX0NsYXNzICsgIiwiKSA+IC0xKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGkgPSBwYXJzZUludChQcm9wZXJ0eU5hbWUpLCB0OwoKICAgICAgICAgICAgaWYgKGkrIiIgIT0gUHJvcGVydHlOYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCInIiArIGkgKyAiJyAhPSAnIiArIFByb3BlcnR5TmFtZSArICInIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpID49IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUHJvcGVydHlOYW1lID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoVmFsdWUgaW5zdGFuY2VvZiBYTUxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBEZWxldGVCeUluZGV4LmNhbGwodGhpcywgUHJvcGVydHlOYW1lKTsKICAgICAgICAgICAgICAgIEluc2VydC5jYWxsKHRoaXMsIFByb3BlcnR5TmFtZSwgVmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKFZhbHVlIGluc3RhbmNlb2YgWE1MCiAgICAgICAgICAgICAgICAmJiBWYWx1ZS5fQ2xhc3MgPT09ICJlbGVtZW50IgogICAgICAgICAgICAgICAgJiYgKCIsZWxlbWVudCxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sdGV4dCIpLmluZGV4T2YoIiwiICsgVmFsdWUuX0NsYXNzICsgIiwiKSA+IC0xCiAgICAgICAgICAgICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVmFsdWUuX1BhcmVudCA9IHRoaXM7CgogICAgICAgICAgICAgICAgaWYgKHRoaXMuX0NoaWxkcmVuW1Byb3BlcnR5TmFtZV0pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bUHJvcGVydHlOYW1lXS5fUGFyZW50ID0gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB0aGlzLl9DaGlsZHJlbltQcm9wZXJ0eU5hbWVdID0gVmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0ID0gbmV3IFhNTCgpOwogICAgICAgICAgICAgICAgdC5fUGFyZW50ID0gdGhpczsKICAgICAgICAgICAgICAgIHQuX1ZhbHVlID0gVG9TdHJpbmcoVmFsdWUpOwoKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9DaGlsZHJlbltQcm9wZXJ0eU5hbWVdKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX0NoaWxkcmVuW1Byb3BlcnR5TmFtZV0uX1BhcmVudCA9IG51bGw7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5fQ2hpbGRyZW5bUHJvcGVydHlOYW1lXSA9IHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTmFtZXNwYWNlIE5hbWVTcGFjZQogICAgICAgICAqICAgIEByZXR1cm5zIG51bGwKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBBZGRJblNjb3BlTmFtZXNwYWNlIChOYW1lU3BhY2UpCiAgICAgICAgewogICAgICAgICAgICBpZiAoKCIsdGV4dCxjb21tZW50LHByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24sYXR0cmlidXRlLCIpLmluZGV4T2YoIiwiICsgdGhpcy5fQ2xhc3MgKyAiLCIpID4gLTEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbWF0Y2ggPSBudWxsLCBwOwoKICAgICAgICAgICAgaWYgKE5hbWVTcGFjZS5wcmVmaXggPT0gIiIgJiYgdGhpcy5fTmFtZS51cmkgPT0gIiIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKHAgaW4gdGhpcy5fSW5TY29wZU5hbWVzcGFjZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChOYW1lU3BhY2UucHJlZml4ID09PSB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1twXS5wcmVmaXgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggPSB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1twXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG1hdGNoICYmIG1hdGNoLnVyaSAhPSBOYW1lU3BhY2UudXJpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aGlzLl9JblNjb3BlTmFtZXNwYWNlc1ttYXRjaC5wcmVmaXhdID0gbnVsbDsKICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5fSW5TY29wZU5hbWVzcGFjZXNbbWF0Y2gucHJlZml4XTsKICAgICAgICAgICAgICAgIH1jYXRjaChlKXt9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX0luU2NvcGVOYW1lc3BhY2VzW05hbWVTcGFjZS5wcmVmaXhdID0gTmFtZVNwYWNlOwoKICAgICAgICAgICAgaWYgKHRoaXMuX05hbWUucHJlZml4ID09PSBOYW1lU3BhY2UucHJlZml4KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aGlzLl9OYW1lLnByZWZpeCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChwIGluIHRoaXMuX0F0dHJpYnV0ZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9BdHRyaWJ1dGVzW3BdLl9OYW1lLnByZWZpeCA9IE5hbWVTcGFjZS5wcmVmaXgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fQXR0cmlidXRlc1twXS5fTmFtZS5wcmVmaXggPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vZG8gdGhpcyBpbiBvcmRlciB0byBlbnN1cmUgbmFtZXNwYWNlIGludGVncml0eQogICAgICAgICAgICAvKm1hdGNoID0gcGFyc2UodGhpcy50b1hNTFN0cmluZygpKTsKICAgICAgICAgICAgIHRoaXMuX05vZGUgPSAhIXRoaXMuX05vZGUucGFyZW50Tm9kZQogICAgICAgICAgICAgPyB0aGlzLl9Ob2RlLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG1hdGNoLmRvY3VtZW50RWxlbWVudCwgdGhpcy5fTm9kZSkKICAgICAgICAgICAgIDogbWF0Y2g7Ki8KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTnVtYmVyIG5hbWUKICAgICAgICAgKiAgICBAcmV0dXJucyBCb29sZWFuCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gSGFzUHJvcGVydHlMaXN0IChuYW1lKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKFRvU3RyaW5nKCBwYXJzZUludChuYW1lKSApID09PSBuYW1lKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQobmFtZSkgPCB0aGlzLl9DaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOyBpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpc1tpXS5fQ2xhc3MgPT09ICJlbGVtZW50IiAmJiB0aGlzW2ldLmhhc093blByb3BlcnR5KG5hbWUpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHwgTnVtYmVyIHwgUU5hbWUgUHJvcGVydHlOYW1lCiAgICAgICAgICogICAgQHJldHVybnMgWE1MTGlzdAogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIEdldExpc3QgKFByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwYXJzZUludChQcm9wZXJ0eU5hbWUpKyIiID09IFByb3BlcnR5TmFtZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXNbUHJvcGVydHlOYW1lXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgWE1MTGlzdCgpLCBpID0gMCwgbCA9IHRoaXMuX0NoaWxkcmVuLmxlbmd0aCwgdGVtcDsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gdGhpczsKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0UHJvcGVydHkgPSBQcm9wZXJ0eU5hbWU7CgogICAgICAgICAgICBmb3IgKDtpIDwgbDsgKytpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fQ2hpbGRyZW5baV0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IEdldC5jYWxsKHRoaXMuX0NoaWxkcmVuW2ldLCBQcm9wZXJ0eU5hbWUpOwoKICAgICAgICAgICAgICAgICAgICBpZiAodGVtcC5fQ2hpbGRyZW4ubGVuZ3RoID4gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRlbXApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAYWNjZXNzIHByaXZhdGUKICAgICAgICAgKiAgICBAcmV0dXJucyBYTUxMaXN0CiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gRGVlcENvcHlMaXN0ICgpCiAgICAgICAgewogICAgICAgICAgICB2YXIgbGlzdCA9IG5ldyBYTUxMaXN0KCksIGkgPSAwLCBsID0gdGhpcy5fQ2hpbGRyZW4ubGVuZ3RoOwoKICAgICAgICAgICAgbGlzdC5fVGFyZ2V0T2JqZWN0ID0gdGhpcy5fVGFyZ2V0T2JqZWN0OwogICAgICAgICAgICBsaXN0Ll9UYXJnZXRQcm9wZXJ0eSA9IHRoaXMuX1RhcmdldFByb3BlcnR5OwogICAgICAgICAgICBsaXN0Ll9DbGFzcyA9IHRoaXMuX0NsYXNzOwogICAgICAgICAgICBsaXN0Ll9WYWx1ZSA9IHRoaXMuX1ZhbHVlOwoKICAgICAgICAgICAgZm9yICg7aSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbGlzdC5BcHBlbmQoRGVlcENvcHkuY2FsbCh0aGlzW2ldKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQGFjY2VzcyBwcml2YXRlCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyB8IFFOYW1lIFByb3BlcnR5TmFtZQogICAgICAgICAqICAgIEByZXR1cm5zIFhNTExpc3QKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBEZXNjZW5kYW50c0xpc3QgKFByb3BlcnR5TmFtZSkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IFhNTExpc3QoKSwgaSA9IDAsIGwgPSB0aGlzLl9DaGlsZHJlbi5sZW5ndGgsIHRlbXA7CgogICAgICAgICAgICBmb3IgKDsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHRoaXNbaV0uX0NsYXNzID09PSAiZWxlbWVudCIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCh0ZW1wID0gRGVzY2VuZGFudHMuY2FsbCh0aGlzW2ldLCAiKiIpKSAmJiB0ZW1wLmxlbmd0aCgpID4gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuQXBwZW5kKHRlbXApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiAgICBodHRwOi8vYmxvZy5zdGV2ZW5sZXZpdGhhbi5jb20vYXJjaGl2ZXMvZmFzdGVyLXRyaW0tamF2YXNjcmlwdAogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gU3RyaW5nIHMKICAgICAgICAgKiAgICBAcmV0dXJucyBTdHJpbmcKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiB0cmltIChzdHIpCiAgICAgICAgewogICAgICAgICAgICBpZighc3RyKQogICAgICAgICAgICAgICAgcmV0dXJuIHN0cjsKICAgICAgICAgICAgdmFyICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9eXHNccyovLCAiIiksCiAgICAgICAgICAgICAgICB3cyA9IC9ccy8sCiAgICAgICAgICAgICAgICBpID0gc3RyLmxlbmd0aDsKICAgICAgICAgICAgd2hpbGUgKHdzLnRlc3Qoc3RyLmNoYXJBdCgtLWkpKSk7CiAgICAgICAgICAgIHJldHVybiBzdHIuc2xpY2UoMCwgaSArIDEpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogICAgR2VuZXJhdGVzIGEgcHJlZml4IGZvciBhIFFOYW1lIHRoYXQgaXMgbm90IGFscmVhZHkKICAgICAgICAgKiAgICBhIHByb3BlcnR5IG9mIHRoZSBvcHRpb25hbCBhcmd1bWVudAogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIE9iamVjdCBwcmVmaXhlcwogICAgICAgICAqICAgIEByZXR1cm5zIFN0cmluZwogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIG5ld1ByZWZpeCAocHJlZml4ZXMpCiAgICAgICAgewogICAgICAgICAgICBwcmVmaXhlcyA9IHByZWZpeGVzIHx8IHt9OwoKICAgICAgICAgICAgdmFyIG51bSA9IE1hdGgucmFuZG9tKCkKICAgICAgICAgICAgICAgIC50b1N0cmluZygpCiAgICAgICAgICAgICAgICAuc3Vic3RyKDIpCiAgICAgICAgICAgICAgICAucmVwbGFjZSgvLnsyfS9nLCBmdW5jdGlvbiAoYSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBhID0gTnVtYmVyKGEpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAoYSA+IDkwID8gOTAgOiAoYSA8IDY1ID8gNjUgOiBhKSkgKyAiIjsKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgbnVtID0gU3RyaW5nLmZyb21DaGFyQ29kZSgKICAgICAgICAgICAgICAgIE51bWJlcihudW0uc3Vic3RyKDAsIDIpKSAmIDB4RkYsCiAgICAgICAgICAgICAgICBOdW1iZXIobnVtLnN1YnN0cigyLCAyKSkgJiAweEZGLAogICAgICAgICAgICAgICAgTnVtYmVyKG51bS5zdWJzdHIoNCwgMikpICYgMHhGRiwKICAgICAgICAgICAgICAgIE51bWJlcihudW0uc3Vic3RyKDYsIDIpKSAmIDB4RkYsCiAgICAgICAgICAgICAgICBOdW1iZXIobnVtLnN1YnN0cig4LCAyKSkgJiAweEZGLAogICAgICAgICAgICAgICAgTnVtYmVyKG51bS5zdWJzdHIoMTAsIDIpKSAmIDB4RkYKICAgICAgICAgICAgKS50b0xvd2VyQ2FzZSgpOwoKICAgICAgICAgICAgd2hpbGUgKG51bSBpbiBwcmVmaXhlcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbnVtID0gYXJndW1lbnRzLmNhbGxlZShwcmVmaXhlcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBudW07CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICogICAgQHBhcmFtIFN0cmluZyBzdHIKICAgICAgICAgKiAgICBAcmV0dXJucyBET01Ob2RlCiAgICAgICAgICogICAgQHRocm93cyBTeW50YXhFcnJvcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIHBhcnNlIChzdHIpCiAgICAgICAgewogICAgICAgICAgICB2YXIgeG1sRG9jLCBzdWNjZXNzID0gdHJ1ZTsKCiAgICAgICAgICAgIGlmIChpc0FjdGl2ZVhTdXBwb3J0ZWQoIk1pY3Jvc29mdC5YTUxET00iKSkgLy9JbnRlcm5ldCBFeHBsb3JlcgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0cnl7CiAgICAgICAgICAgICAgICAgICAgeG1sRG9jICAgICAgICAgICAgICAgICAgICAgID0gbmV3IEFjdGl2ZVhPYmplY3QoIk1pY3Jvc29mdC5YTUxET00iKTsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MuYXN5bmMgICAgICAgICAgICAgICAgPSAnZmFsc2UnOwogICAgICAgICAgICAgICAgICAgIHhtbERvYy5wcmVzZXJ2ZVdoaXRlU3BhY2UgICA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgeG1sRG9jLnJlc29sdmVFeHRlcm5hbHMgICAgID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgeG1sRG9jLnZhbGlkYXRlT25QYXJzZSAgICAgICAgID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgeG1sRG9jLnNldFByb3BlcnR5KCdQcm9oaWJpdERURCcsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0geG1sRG9jLmxvYWRYTUwoc3RyKTsKICAgICAgICAgICAgICAgIH1jYXRjaChlKXt9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0cnl7Ly9GaXJlZm94LCBNb3ppbGxhLCBPcGVyYSwgZXRjLgogICAgICAgICAgICAgICAgICAgIHhtbERvYyA9IG5ldyBET01QYXJzZXIoKTsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MgPSB4bWxEb2MucGFyc2VGcm9tU3RyaW5nKHN0ciwgInRleHQveG1sIik7CiAgICAgICAgICAgICAgICB9Y2F0Y2goZSl7fQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIXN1Y2Nlc3MgfHwgIXhtbERvYyB8fCB4bWxEb2MuZG9jdW1lbnRFbGVtZW50Lm5vZGVOYW1lID09ICJwYXJzZXJlcnJvciIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcighIXhtbERvYyAmJiB4bWxEb2MuZG9jdW1lbnRFbGVtZW50LmNoaWxkTm9kZXNbMF0ubm9kZVZhbHVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHhtbERvYzsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gT2JqZWN0IG9iagogICAgICAgICAqICAgIEByZXR1cm5zIE51bWJlcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIGNvdW50IChvYmopCiAgICAgICAgewogICAgICAgICAgICBpZiAoIl9fY291bnRfXyIgaW4gb2JqKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gb2JqLl9fY291bnRfXzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGkgPSAwLCBrOwoKICAgICAgICAgICAgZm9yIChrIGluIG9iaikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICArK2k7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqICAgIEBwYXJhbSBPYmplY3Qgb2JqCiAgICAgICAgICogICAgQHBhcmFtIFhNTExpc3QgbGlzdAogICAgICAgICAqICAgIEByZXR1cm5zIE51bWJlcgogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIGluZGV4T2YgKG9iaiwgbGlzdCkKICAgICAgICB7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gbGlzdC5sZW5ndGgoKTsgaSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGxpc3RbaV0uRXF1YWxzKG9iaikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKiAgICBAcGFyYW0gbWl4ZWQgb2JqCiAgICAgICAgICogICAgQHBhcmFtIG1peGVkIC4uLgogICAgICAgICAqICAgIEByZXR1cm5zIG1peGVkCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gZXh0ZW5kIChvYmopCiAgICAgICAgewogICAgICAgICAgICBmb3IgKHZhciBwLCBpID0gMSwgbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAocCBpbiBhcmd1bWVudHNbaV0pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgb2JqW3BdID0gYXJndW1lbnRzW2ldW3BdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gb2JqOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gY3JlYXRlRG9jdW1lbnRGcm9tICh4bWwpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gcGFyc2UoeG1sLmxlbmd0aCgpID09IDEgPyB4bWwudG9YTUxTdHJpbmcoKSA6ICI8eD4iICsgeG1sLnRvWE1MU3RyaW5nKCkgKyAiPC94PiIpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24geG1sVG9Eb21Ob2RlICh4bWwpCiAgICAgICAgewogICAgICAgICAgICBzd2l0Y2ggKHhtbC5ub2RlS2luZCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlICJlbGVtZW50IjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlRG9jdW1lbnRGcm9tKHhtbCkuZG9jdW1lbnRFbGVtZW50OwoKICAgICAgICAgICAgICAgIGNhc2UgInRleHQiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiB4bWxEb2MuY3JlYXRlVGV4dE5vZGUoeG1sLnRvU3RyaW5nKCkpOwoKICAgICAgICAgICAgICAgIGNhc2UgImNvbW1lbnQiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiB4bWxEb2MuY3JlYXRlQ29tbWVudCh4bWwudG9TdHJpbmcoKS5zbGljZSg0LCAtMykpOwoKICAgICAgICAgICAgICAgIGNhc2UgInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iOgogICAgICAgICAgICAgICAgICAgIHJldHVybiB4bWxEb2MuY3JlYXRlUHJvY2Vzc2luZ0luc3RydWN0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICB4bWwubG9jYWxOYW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbC50b1N0cmluZygpLnNsaWNlKDIsIC0yKS5yZXBsYWNlKHBpTmFtZSwgIiIpCiAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBjYXNlICJhdHRyaWJ1dGUiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVOUyh4bWwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gYWRvcHROb2RlIChkb2MsIG5vZGUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoISFkb2MuYWRvcHROb2RlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZG9jLmFkb3B0Tm9kZShub2RlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGIgPSBkb2MuZG9jdW1lbnRFbGVtZW50IHx8IGRvYy5ib2R5OwogICAgICAgICAgICByZXR1cm4gYi5yZW1vdmVDaGlsZChiLmFwcGVuZENoaWxkKG5vZGUpKTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIGV2YWx1YXRlIChkb2MsIGV4cHIsIHhtbCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciByZXMsIGwsIG4gPSAiIjsKCiAgICAgICAgICAgIGlmICghIWRvYy5ldmFsdWF0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzID0gZG9jLmV2YWx1YXRlKAogICAgICAgICAgICAgICAgICAgIGV4cHIsCiAgICAgICAgICAgICAgICAgICAgZG9jLAogICAgICAgICAgICAgICAgICAgIGRvYy5jcmVhdGVOU1Jlc29sdmVyKGRvYyksCiAgICAgICAgICAgICAgICAgICAgWFBhdGhSZXN1bHQuT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUsCiAgICAgICAgICAgICAgICAgICAgbnVsbAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBsID0gW107CgogICAgICAgICAgICAgICAgd2hpbGUobiA9IHJlcy5pdGVyYXRlTmV4dCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxbbC5sZW5ndGhdID0gbjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCJzZXRQcm9wZXJ0eSIgaW4gZG9jKXsKCiAgICAgICAgICAgICAgICByZXMgPSBhbGxOYW1lc3BhY2VzKHhtbCk7CgogICAgICAgICAgICAgICAgaWYgKGNvdW50KHJlcykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChsIGluIHJlcykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG4gKz0gIiB4bWxuczoiICsgbCArICc9IicgKyBFc2NhcGVBdHRyaWJ1dGVWYWx1ZShyZXNbbF0pICsgJyInOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgZG9jLnNldFByb3BlcnR5KCdTZWxlY3Rpb25OYW1lc3BhY2VzJywgbi5zdWJzdHIoMSkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGRvYy5zZXRQcm9wZXJ0eSgiU2VsZWN0aW9uTGFuZ3VhZ2UiLCAiWFBhdGgiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGlzQWN0aXZlWFN1cHBvcnRlZCgiTWljcm9zb2Z0LlhNTERPTSIpICYmIGRvYy5zZWxlY3ROb2RlcyhleHByKTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIGlzQWN0aXZlWFN1cHBvcnRlZCh0eXBlKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBuZXcgQWN0aXZlWE9iamVjdCh0eXBlKTsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIGFsbE5hbWVzcGFjZXMgKHhtbCwgdW4pCiAgICAgICAgewogICAgICAgICAgICB2YXIgbnMgPSB1biB8fCB7fSwKICAgICAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICAgICAgYyA9IHhtbC5jaGlsZHJlbigpLAogICAgICAgICAgICAgICAgbCA9IGMubGVuZ3RoKCksCiAgICAgICAgICAgICAgICBuID0gdW4gPT0gdW5kZWZpbmVkCiAgICAgICAgICAgICAgICAgICAgPyBpbnNjb3BlKHhtbCkKICAgICAgICAgICAgICAgICAgICA6IHhtbC5fSW5TY29wZU5hbWVzcGFjZXMsCiAgICAgICAgICAgICAgICBwOwoKICAgICAgICAgICAgZm9yICg7aSA8IGw7ICsraSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbnMgPSBhcmd1bWVudHMuY2FsbGVlKGNbaV0sIG5zKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIChwIGluIG4pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChuW3BdLnByZWZpeCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBuc1tuW3BdLnByZWZpeF0gPSBuW3BdLnVyaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG5zOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gaW5zY29wZSAoeG1sKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIG5zID0ge30sCiAgICAgICAgICAgICAgICBpID0gMCwKICAgICAgICAgICAgICAgIG4gPSB4bWwuaW5TY29wZU5hbWVzcGFjZXMoKSwKICAgICAgICAgICAgICAgIGwgPSBuLmxlbmd0aDsKCiAgICAgICAgICAgIGZvciAoO2kgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChuW2ldLnByZWZpeCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBuc1tuW2ldLnByZWZpeF0gPSBuW2ldLnVyaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG5zOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gY3JlYXRlQXR0cmlidXRlTlMgKHhtbCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBucyA9IHhtbC5uYW1lc3BhY2UoKSwKICAgICAgICAgICAgICAgIG5vZGUgPSAhIXhtbERvYy5jcmVhdGVBdHRyaWJ1dGVOUwogICAgICAgICAgICAgICAgICAgID8geG1sRG9jLmNyZWF0ZUF0dHJpYnV0ZU5TKG5zLnVyaSwgeG1sLmxvY2FsTmFtZSgpKQogICAgICAgICAgICAgICAgICAgIDogeG1sRG9jLmNyZWF0ZUF0dHJpYnV0ZSgobnMucHJlZml4ID8gbnMucHJlZml4ICsgIjoiIDogIiIgKSArIHhtbC5sb2NhbE5hbWUoKSk7CgogICAgICAgICAgICBub2RlLm5vZGVWYWx1ZSA9IHhtbC50b1N0cmluZygpOwogICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIHRyYW5zZm9ybSAoeG1sLCBzdHlsZSwgcGFyYW1zKQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHhzbCwgcmVzLCBpID0gMCwgbCA9IChwYXJhbXN8fFtdKS5sZW5ndGg7CgogICAgICAgICAgICBpZiAoIXdpbmRvdy5YU0xUUHJvY2Vzc29yKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvL1RPRE86IE5lZWQgdG8gY3JlYXRlIGEgd2F5IHRvIHNldCBwYXJhbWV0ZXJzIG9uIGFuIElFIHN0eWxlc2hlZXQKICAgICAgICAgICAgICAgIC8vWFNMUHJvY2Vzc29yCiAgICAgICAgICAgICAgICAvL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczc1NzAxNSUyOHY9VlMuODUlMjkuYXNweAogICAgICAgICAgICAgICAgLy9odHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM3NjM2NzklMjhWUy44NSUyOS5hc3B4CiAgICAgICAgICAgICAgICAvL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczc1NDU5NCUyOHY9VlMuODUlMjkuYXNweAoKICAgICAgICAgICAgICAgIHJlcyA9IGNyZWF0ZURvY3VtZW50RnJvbSh4bWwpLnRyYW5zZm9ybU5vZGUoY3JlYXRlRG9jdW1lbnRGcm9tKHN0eWxlKSk7CgogICAgICAgICAgICAgICAgcmV0dXJuICEhcmVzICYmIFRvWE1MKHJlcykgfHwgbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgeHNsID0gbmV3IFhTTFRQcm9jZXNzb3IoKTsKCiAgICAgICAgICAgIHhzbC5pbXBvcnRTdHlsZVNoZWV0KGNyZWF0ZURvY3VtZW50RnJvbShzdHlsZSkpOwoKICAgICAgICAgICAgZm9yICg7IGkgPCBsOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJlcyA9IHBhcmFtc1tpXTsKICAgICAgICAgICAgICAgIHhzbC5zZXRQYXJhbWV0ZXIocmVzLm5hbWVzcGFjZVVSSSwgcmVzLmxvY2FsTmFtZSwgcmVzLnZhbHVlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmVzID0geHNsLnRyYW5zZm9ybVRvRG9jdW1lbnQoY3JlYXRlRG9jdW1lbnRGcm9tKGRvYykpCgogICAgICAgICAgICByZXR1cm4gISFyZXMgJiYgVG9YTUwocmVzKSB8fCBudWxsOwogICAgICAgIH0KCiAgICAgICAgZm9yIChwIGluIFhNTC5wcm90b3R5cGUpCiAgICAgICAgewogICAgICAgICAgICBkZWZhdWx0WE1MUHJvdG90eXBlICs9IHAgKyAiLCI7CiAgICAgICAgfQoKICAgICAgICBmb3IgKHAgaW4gWE1MTGlzdC5wcm90b3R5cGUpCiAgICAgICAgewogICAgICAgICAgICBkZWZhdWx0WE1MTGlzdFByb3RvdHlwZSArPSBwICsgIiwiOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgd2luZG93LlhNTCAgICAgICAgICAgICAgPSBYTUw7CiAgICAgICAgd2luZG93LlhNTExpc3QgICAgICAgICAgPSBYTUxMaXN0OwogICAgICAgIHdpbmRvdy5RTmFtZSAgICAgICAgICAgID0gUU5hbWU7CiAgICAgICAgd2luZG93Lk5hbWVzcGFjZSAgICAgICAgPSBOYW1lc3BhY2U7CiAgICAgICAgd2luZG93LmlzWE1MTmFtZSAgICAgICAgPSBpc1hNTE5hbWU7CiAgICAgICAgd2luZG93LkF0dHJpYnV0ZU5hbWUgICAgPSBBdHRyaWJ1dGVOYW1lOwoKICAgIH0pKCk7Cn0KCi8qKioqKiB4cmVnZXhwLmpzICoqKioqLwoKLyohCiAqIFhSZWdFeHAgdjIuMC4wCiAqIChjKSAyMDA3LTIwMTIgU3RldmVuIExldml0aGFuIDxodHRwOi8veHJlZ2V4cC5jb20vPgogKiBNSVQgTGljZW5zZQogKi8KCi8qKgogKiBYUmVnRXhwIHByb3ZpZGVzIGF1Z21lbnRlZCwgZXh0ZW5zaWJsZSBKYXZhU2NyaXB0IHJlZ3VsYXIgZXhwcmVzc2lvbnMuIFlvdSBnZXQgbmV3IHN5bnRheCwKICogZmxhZ3MsIGFuZCBtZXRob2RzIGJleW9uZCB3aGF0IGJyb3dzZXJzIHN1cHBvcnQgbmF0aXZlbHkuIFhSZWdFeHAgaXMgYWxzbyBhIHJlZ2V4IHV0aWxpdHkgYmVsdAogKiB3aXRoIHRvb2xzIHRvIG1ha2UgeW91ciBjbGllbnQtc2lkZSBncmVwcGluZyBzaW1wbGVyIGFuZCBtb3JlIHBvd2VyZnVsLCB3aGlsZSBmcmVlaW5nIHlvdSBmcm9tCiAqIHdvcnJ5aW5nIGFib3V0IHBlc2t5IGNyb3NzLWJyb3dzZXIgaW5jb25zaXN0ZW5jaWVzIGFuZCB0aGUgZHViaW91cyBgbGFzdEluZGV4YCBwcm9wZXJ0eS4gU2VlCiAqIFhSZWdFeHAncyBkb2N1bWVudGF0aW9uIChodHRwOi8veHJlZ2V4cC5jb20vKSBmb3IgbW9yZSBkZXRhaWxzLgogKiBAbW9kdWxlIHhyZWdleHAKICogQHJlcXVpcmVzIE4vQQogKi8KdmFyIFhSZWdFeHA7CgovLyBBdm9pZCBydW5uaW5nIHR3aWNlOyB0aGF0IHdvdWxkIHJlc2V0IHRva2VucyBhbmQgY291bGQgYnJlYWsgcmVmZXJlbmNlcyB0byBuYXRpdmUgZ2xvYmFscwpYUmVnRXhwID0gWFJlZ0V4cCB8fCAoZnVuY3Rpb24gKHVuZGVmKSB7CiAgICAidXNlIHN0cmljdCI7CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqICBQcml2YXRlIHZhcmlhYmxlcwogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgogICAgdmFyIHNlbGYsCiAgICAgICAgYWRkVG9rZW4sCiAgICAgICAgYWRkLAoKLy8gT3B0aW9uYWwgZmVhdHVyZXM7IGNhbiBiZSBpbnN0YWxsZWQgYW5kIHVuaW5zdGFsbGVkCiAgICAgICAgZmVhdHVyZXMgPSB7CiAgICAgICAgICAgIG5hdGl2ZXM6IGZhbHNlLAogICAgICAgICAgICBleHRlbnNpYmlsaXR5OiBmYWxzZQogICAgICAgIH0sCgovLyBTdG9yZSBuYXRpdmUgbWV0aG9kcyB0byB1c2UgYW5kIHJlc3RvcmUgKCJuYXRpdmUiIGlzIGFuIEVTMyByZXNlcnZlZCBrZXl3b3JkKQogICAgICAgIG5hdGl2ID0gewogICAgICAgICAgICBleGVjOiBSZWdFeHAucHJvdG90eXBlLmV4ZWMsCiAgICAgICAgICAgIHRlc3Q6IFJlZ0V4cC5wcm90b3R5cGUudGVzdCwKICAgICAgICAgICAgbWF0Y2g6IFN0cmluZy5wcm90b3R5cGUubWF0Y2gsCiAgICAgICAgICAgIHJlcGxhY2U6IFN0cmluZy5wcm90b3R5cGUucmVwbGFjZSwKICAgICAgICAgICAgc3BsaXQ6IFN0cmluZy5wcm90b3R5cGUuc3BsaXQKICAgICAgICB9LAoKLy8gU3RvcmFnZSBmb3IgZml4ZWQvZXh0ZW5kZWQgbmF0aXZlIG1ldGhvZHMKICAgICAgICBmaXhlZCA9IHt9LAoKLy8gU3RvcmFnZSBmb3IgY2FjaGVkIHJlZ2V4ZXMKICAgICAgICBjYWNoZSA9IHt9LAoKLy8gU3RvcmFnZSBmb3IgYWRkb24gdG9rZW5zCiAgICAgICAgdG9rZW5zID0gW10sCgovLyBUb2tlbiBzY29wZXMKICAgICAgICBkZWZhdWx0U2NvcGUgPSAiZGVmYXVsdCIsCiAgICAgICAgY2xhc3NTY29wZSA9ICJjbGFzcyIsCgovLyBSZWdleGVzIHRoYXQgbWF0Y2ggbmF0aXZlIHJlZ2V4IHN5bnRheAogICAgICAgIG5hdGl2ZVRva2VucyA9IHsKICAgICAgICAgICAgLy8gQW55IG5hdGl2ZSBtdWx0aWNoYXJhY3RlciB0b2tlbiBpbiBkZWZhdWx0IHNjb3BlIChpbmNsdWRlcyBvY3RhbHMsIGV4Y2x1ZGVzIGNoYXJhY3RlciBjbGFzc2VzKQogICAgICAgICAgICAiZGVmYXVsdCI6IC9eKD86XFwoPzowKD86WzAtM11bMC03XXswLDJ9fFs0LTddWzAtN10/KT98WzEtOV1cZCp8eFtcZEEtRmEtZl17Mn18dVtcZEEtRmEtZl17NH18Y1tBLVphLXpdfFtcc1xTXSl8XChcP1s6PSFdfFs/KitdXD98e1xkKyg/OixcZCopP31cPz8pLywKICAgICAgICAgICAgLy8gQW55IG5hdGl2ZSBtdWx0aWNoYXJhY3RlciB0b2tlbiBpbiBjaGFyYWN0ZXIgY2xhc3Mgc2NvcGUgKGluY2x1ZGVzIG9jdGFscykKICAgICAgICAgICAgImNsYXNzIjogL14oPzpcXCg/OlswLTNdWzAtN117MCwyfXxbNC03XVswLTddP3x4W1xkQS1GYS1mXXsyfXx1W1xkQS1GYS1mXXs0fXxjW0EtWmEtel18W1xzXFNdKSkvCiAgICAgICAgfSwKCi8vIEFueSBiYWNrcmVmZXJlbmNlIGluIHJlcGxhY2VtZW50IHN0cmluZ3MKICAgICAgICByZXBsYWNlbWVudFRva2VuID0gL1wkKD86eyhbXHckXSspfXwoXGRcZD98W1xzXFNdKSkvZywKCi8vIEFueSBjaGFyYWN0ZXIgd2l0aCBhIGxhdGVyIGluc3RhbmNlIGluIHRoZSBzdHJpbmcKICAgICAgICBkdXBsaWNhdGVGbGFncyA9IC8oW1xzXFNdKSg/PVtcc1xTXSpcMSkvZywKCi8vIEFueSBncmVlZHkvbGF6eSBxdWFudGlmaWVyCiAgICAgICAgcXVhbnRpZmllciA9IC9eKD86Wz8qK118e1xkKyg/OixcZCopP30pXD8/LywKCi8vIENoZWNrIGZvciBjb3JyZWN0IGBleGVjYCBoYW5kbGluZyBvZiBub25wYXJ0aWNpcGF0aW5nIGNhcHR1cmluZyBncm91cHMKICAgICAgICBjb21wbGlhbnRFeGVjTnBjZyA9IG5hdGl2LmV4ZWMuY2FsbCgvKCk/Py8sICIiKVsxXSA9PT0gdW5kZWYsCgovLyBDaGVjayBmb3IgZmxhZyB5IHN1cHBvcnQgKEZpcmVmb3ggMyspCiAgICAgICAgaGFzTmF0aXZlWSA9IFJlZ0V4cC5wcm90b3R5cGUuc3RpY2t5ICE9PSB1bmRlZiwKCi8vIFVzZWQgdG8ga2lsbCBpbmZpbml0ZSByZWN1cnNpb24gZHVyaW5nIFhSZWdFeHAgY29uc3RydWN0aW9uCiAgICAgICAgaXNJbnNpZGVDb25zdHJ1Y3RvciA9IGZhbHNlLAoKLy8gU3RvcmFnZSBmb3Iga25vd24gZmxhZ3MsIGluY2x1ZGluZyBhZGRvbiBmbGFncwogICAgICAgIHJlZ2lzdGVyZWRGbGFncyA9ICJnaW0iICsgKGhhc05hdGl2ZVkgPyAieSIgOiAiIik7CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqICBQcml2YXRlIGhlbHBlciBmdW5jdGlvbnMKICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKLyoqCiAqIEF0dGFjaGVzIFhSZWdFeHAucHJvdG90eXBlIHByb3BlcnRpZXMgYW5kIG5hbWVkIGNhcHR1cmUgc3VwcG9ydGluZyBkYXRhIHRvIGEgcmVnZXggb2JqZWN0LgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge1JlZ0V4cH0gcmVnZXggUmVnZXggdG8gYXVnbWVudC4KICogQHBhcmFtIHtBcnJheX0gY2FwdHVyZU5hbWVzIEFycmF5IHdpdGggY2FwdHVyZSBuYW1lcywgb3IgbnVsbC4KICogQHBhcmFtIHtCb29sZWFufSBbaXNOYXRpdmVdIFdoZXRoZXIgdGhlIHJlZ2V4IHdhcyBjcmVhdGVkIGJ5IGBSZWdFeHBgIHJhdGhlciB0aGFuIGBYUmVnRXhwYC4KICogQHJldHVybnMge1JlZ0V4cH0gQXVnbWVudGVkIHJlZ2V4LgogKi8KICAgIGZ1bmN0aW9uIGF1Z21lbnQocmVnZXgsIGNhcHR1cmVOYW1lcywgaXNOYXRpdmUpIHsKICAgICAgICB2YXIgcDsKICAgICAgICAvLyBDYW4ndCBhdXRvLWluaGVyaXQgdGhlc2Ugc2luY2UgdGhlIFhSZWdFeHAgY29uc3RydWN0b3IgcmV0dXJucyBhIG5vbnByaW1pdGl2ZSB2YWx1ZQogICAgICAgIGZvciAocCBpbiBzZWxmLnByb3RvdHlwZSkgewogICAgICAgICAgICBpZiAoc2VsZi5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkocCkpIHsKICAgICAgICAgICAgICAgIHJlZ2V4W3BdID0gc2VsZi5wcm90b3R5cGVbcF07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmVnZXgueHJlZ2V4cCA9IHtjYXB0dXJlTmFtZXM6IGNhcHR1cmVOYW1lcywgaXNOYXRpdmU6ICEhaXNOYXRpdmV9OwogICAgICAgIHJldHVybiByZWdleDsKICAgIH0KCi8qKgogKiBSZXR1cm5zIG5hdGl2ZSBgUmVnRXhwYCBmbGFncyB1c2VkIGJ5IGEgcmVnZXggb2JqZWN0LgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge1JlZ0V4cH0gcmVnZXggUmVnZXggdG8gY2hlY2suCiAqIEByZXR1cm5zIHtTdHJpbmd9IE5hdGl2ZSBmbGFncyBpbiB1c2UuCiAqLwogICAgZnVuY3Rpb24gZ2V0TmF0aXZlRmxhZ3MocmVnZXgpIHsKICAgICAgICAvL3JldHVybiBuYXRpdi5leGVjLmNhbGwoL1wvKFthLXpdKikkL2ksIFN0cmluZyhyZWdleCkpWzFdOwogICAgICAgIHJldHVybiAocmVnZXguZ2xvYmFsICAgICA/ICJnIiA6ICIiKSArCiAgICAgICAgICAgICAgIChyZWdleC5pZ25vcmVDYXNlID8gImkiIDogIiIpICsKICAgICAgICAgICAgICAgKHJlZ2V4Lm11bHRpbGluZSAgPyAibSIgOiAiIikgKwogICAgICAgICAgICAgICAocmVnZXguZXh0ZW5kZWQgICA/ICJ4IiA6ICIiKSArIC8vIFByb3Bvc2VkIGZvciBFUzYsIGluY2x1ZGVkIGluIEFTMwogICAgICAgICAgICAgICAocmVnZXguc3RpY2t5ICAgICA/ICJ5IiA6ICIiKTsgLy8gUHJvcG9zZWQgZm9yIEVTNiwgaW5jbHVkZWQgaW4gRmlyZWZveCAzKwogICAgfQoKLyoqCiAqIENvcGllcyBhIHJlZ2V4IG9iamVjdCB3aGlsZSBwcmVzZXJ2aW5nIHNwZWNpYWwgcHJvcGVydGllcyBmb3IgbmFtZWQgY2FwdHVyZSBhbmQgYXVnbWVudGluZyB3aXRoCiAqIGBYUmVnRXhwLnByb3RvdHlwZWAgbWV0aG9kcy4gVGhlIGNvcHkgaGFzIGEgZnJlc2ggYGxhc3RJbmRleGAgcHJvcGVydHkgKHNldCB0byB6ZXJvKS4gQWxsb3dzCiAqIGFkZGluZyBhbmQgcmVtb3ZpbmcgZmxhZ3Mgd2hpbGUgY29weWluZyB0aGUgcmVnZXguCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7UmVnRXhwfSByZWdleCBSZWdleCB0byBjb3B5LgogKiBAcGFyYW0ge1N0cmluZ30gW2FkZEZsYWdzXSBGbGFncyB0byBiZSBhZGRlZCB3aGlsZSBjb3B5aW5nIHRoZSByZWdleC4KICogQHBhcmFtIHtTdHJpbmd9IFtyZW1vdmVGbGFnc10gRmxhZ3MgdG8gYmUgcmVtb3ZlZCB3aGlsZSBjb3B5aW5nIHRoZSByZWdleC4KICogQHJldHVybnMge1JlZ0V4cH0gQ29weSBvZiB0aGUgcHJvdmlkZWQgcmVnZXgsIHBvc3NpYmx5IHdpdGggbW9kaWZpZWQgZmxhZ3MuCiAqLwogICAgZnVuY3Rpb24gY29weShyZWdleCwgYWRkRmxhZ3MsIHJlbW92ZUZsYWdzKSB7CiAgICAgICAgaWYgKCFzZWxmLmlzUmVnRXhwKHJlZ2V4KSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCJ0eXBlIFJlZ0V4cCBleHBlY3RlZCIpOwogICAgICAgIH0KICAgICAgICB2YXIgZmxhZ3MgPSBuYXRpdi5yZXBsYWNlLmNhbGwoZ2V0TmF0aXZlRmxhZ3MocmVnZXgpICsgKGFkZEZsYWdzIHx8ICIiKSwgZHVwbGljYXRlRmxhZ3MsICIiKTsKICAgICAgICBpZiAocmVtb3ZlRmxhZ3MpIHsKICAgICAgICAgICAgLy8gV291bGQgbmVlZCB0byBlc2NhcGUgYHJlbW92ZUZsYWdzYCBpZiB0aGlzIHdhcyBwdWJsaWMKICAgICAgICAgICAgZmxhZ3MgPSBuYXRpdi5yZXBsYWNlLmNhbGwoZmxhZ3MsIG5ldyBSZWdFeHAoIlsiICsgcmVtb3ZlRmxhZ3MgKyAiXSsiLCAiZyIpLCAiIik7CiAgICAgICAgfQogICAgICAgIGlmIChyZWdleC54cmVnZXhwICYmICFyZWdleC54cmVnZXhwLmlzTmF0aXZlKSB7CiAgICAgICAgICAgIC8vIENvbXBpbGluZyB0aGUgY3VycmVudCAocmF0aGVyIHRoYW4gcHJlY29tcGlsYXRpb24pIHNvdXJjZSBwcmVzZXJ2ZXMgdGhlIGVmZmVjdHMgb2Ygbm9ubmF0aXZlIHNvdXJjZSBmbGFncwogICAgICAgICAgICByZWdleCA9IGF1Z21lbnQoc2VsZihyZWdleC5zb3VyY2UsIGZsYWdzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2V4LnhyZWdleHAuY2FwdHVyZU5hbWVzID8gcmVnZXgueHJlZ2V4cC5jYXB0dXJlTmFtZXMuc2xpY2UoMCkgOiBudWxsKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBBdWdtZW50IHdpdGggYFhSZWdFeHAucHJvdG90eXBlYCBtZXRob2RzLCBidXQgdXNlIG5hdGl2ZSBgUmVnRXhwYCAoYXZvaWQgc2VhcmNoaW5nIGZvciBzcGVjaWFsIHRva2VucykKICAgICAgICAgICAgcmVnZXggPSBhdWdtZW50KG5ldyBSZWdFeHAocmVnZXguc291cmNlLCBmbGFncyksIG51bGwsIHRydWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVnZXg7CiAgICB9CgovKgogKiBSZXR1cm5zIHRoZSBsYXN0IGluZGV4IGF0IHdoaWNoIGEgZ2l2ZW4gdmFsdWUgY2FuIGJlIGZvdW5kIGluIGFuIGFycmF5LCBvciBgLTFgIGlmIGl0J3Mgbm90CiAqIHByZXNlbnQuIFRoZSBhcnJheSBpcyBzZWFyY2hlZCBiYWNrd2FyZHMuCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IEFycmF5IHRvIHNlYXJjaC4KICogQHBhcmFtIHsqfSB2YWx1ZSBWYWx1ZSB0byBsb2NhdGUgaW4gdGhlIGFycmF5LgogKiBAcmV0dXJucyB7TnVtYmVyfSBMYXN0IHplcm8tYmFzZWQgaW5kZXggYXQgd2hpY2ggdGhlIGl0ZW0gaXMgZm91bmQsIG9yIC0xLgogKi8KICAgIGZ1bmN0aW9uIGxhc3RJbmRleE9mKGFycmF5LCB2YWx1ZSkgewogICAgICAgIHZhciBpID0gYXJyYXkubGVuZ3RoOwogICAgICAgIGlmIChBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YpIHsKICAgICAgICAgICAgcmV0dXJuIGFycmF5Lmxhc3RJbmRleE9mKHZhbHVlKTsgLy8gVXNlIHRoZSBuYXRpdmUgbWV0aG9kIGlmIGF2YWlsYWJsZQogICAgICAgIH0KICAgICAgICB3aGlsZSAoaS0tKSB7CiAgICAgICAgICAgIGlmIChhcnJheVtpXSA9PT0gdmFsdWUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiAtMTsKICAgIH0KCi8qKgogKiBEZXRlcm1pbmVzIHdoZXRoZXIgYW4gb2JqZWN0IGlzIG9mIHRoZSBzcGVjaWZpZWQgdHlwZS4KICogQHByaXZhdGUKICogQHBhcmFtIHsqfSB2YWx1ZSBPYmplY3QgdG8gY2hlY2suCiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIFR5cGUgdG8gY2hlY2sgZm9yLCBpbiBsb3dlcmNhc2UuCiAqIEByZXR1cm5zIHtCb29sZWFufSBXaGV0aGVyIHRoZSBvYmplY3QgbWF0Y2hlcyB0aGUgdHlwZS4KICovCiAgICBmdW5jdGlvbiBpc1R5cGUodmFsdWUsIHR5cGUpIHsKICAgICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKS50b0xvd2VyQ2FzZSgpID09PSAiW29iamVjdCAiICsgdHlwZSArICJdIjsKICAgIH0KCi8qKgogKiBQcmVwYXJlcyBhbiBvcHRpb25zIG9iamVjdCBmcm9tIHRoZSBnaXZlbiB2YWx1ZS4KICogQHByaXZhdGUKICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSB2YWx1ZSBWYWx1ZSB0byBjb252ZXJ0IHRvIGFuIG9wdGlvbnMgb2JqZWN0LgogKiBAcmV0dXJucyB7T2JqZWN0fSBPcHRpb25zIG9iamVjdC4KICovCiAgICBmdW5jdGlvbiBwcmVwYXJlT3B0aW9ucyh2YWx1ZSkgewogICAgICAgIHZhbHVlID0gdmFsdWUgfHwge307CiAgICAgICAgaWYgKHZhbHVlID09PSAiYWxsIiB8fCB2YWx1ZS5hbGwpIHsKICAgICAgICAgICAgdmFsdWUgPSB7bmF0aXZlczogdHJ1ZSwgZXh0ZW5zaWJpbGl0eTogdHJ1ZX07CiAgICAgICAgfSBlbHNlIGlmIChpc1R5cGUodmFsdWUsICJzdHJpbmciKSkgewogICAgICAgICAgICB2YWx1ZSA9IHNlbGYuZm9yRWFjaCh2YWx1ZSwgL1teXHMsXSsvLCBmdW5jdGlvbiAobSkgewogICAgICAgICAgICAgICAgdGhpc1ttXSA9IHRydWU7CiAgICAgICAgICAgIH0sIHt9KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgfQoKLyoqCiAqIFJ1bnMgYnVpbHQtaW4vY3VzdG9tIHRva2VucyBpbiByZXZlcnNlIGluc2VydGlvbiBvcmRlciwgdW50aWwgYSBtYXRjaCBpcyBmb3VuZC4KICogQHByaXZhdGUKICogQHBhcmFtIHtTdHJpbmd9IHBhdHRlcm4gT3JpZ2luYWwgcGF0dGVybiBmcm9tIHdoaWNoIGFuIFhSZWdFeHAgb2JqZWN0IGlzIGJlaW5nIGJ1aWx0LgogKiBAcGFyYW0ge051bWJlcn0gcG9zIFBvc2l0aW9uIHRvIHNlYXJjaCBmb3IgdG9rZW5zIHdpdGhpbiBgcGF0dGVybmAuCiAqIEBwYXJhbSB7TnVtYmVyfSBzY29wZSBDdXJyZW50IHJlZ2V4IHNjb3BlLgogKiBAcGFyYW0ge09iamVjdH0gY29udGV4dCBDb250ZXh0IG9iamVjdCBhc3NpZ25lZCB0byB0b2tlbiBoYW5kbGVyIGZ1bmN0aW9ucy4KICogQHJldHVybnMge09iamVjdH0gT2JqZWN0IHdpdGggcHJvcGVydGllcyBgb3V0cHV0YCAodGhlIHN1YnN0aXR1dGlvbiBzdHJpbmcgcmV0dXJuZWQgYnkgdGhlCiAqICAgc3VjY2Vzc2Z1bCB0b2tlbiBoYW5kbGVyKSBhbmQgYG1hdGNoYCAodGhlIHRva2VuJ3MgbWF0Y2ggYXJyYXkpLCBvciBudWxsLgogKi8KICAgIGZ1bmN0aW9uIHJ1blRva2VucyhwYXR0ZXJuLCBwb3MsIHNjb3BlLCBjb250ZXh0KSB7CiAgICAgICAgdmFyIGkgPSB0b2tlbnMubGVuZ3RoLAogICAgICAgICAgICByZXN1bHQgPSBudWxsLAogICAgICAgICAgICBtYXRjaCwKICAgICAgICAgICAgdDsKICAgICAgICAvLyBQcm90ZWN0IGFnYWluc3QgY29uc3RydWN0aW5nIFhSZWdFeHBzIHdpdGhpbiB0b2tlbiBoYW5kbGVyIGFuZCB0cmlnZ2VyIGZ1bmN0aW9ucwogICAgICAgIGlzSW5zaWRlQ29uc3RydWN0b3IgPSB0cnVlOwogICAgICAgIC8vIE11c3QgcmVzZXQgYGlzSW5zaWRlQ29uc3RydWN0b3JgLCBldmVuIGlmIGEgYHRyaWdnZXJgIG9yIGBoYW5kbGVyYCB0aHJvd3MKICAgICAgICB0cnkgewogICAgICAgICAgICB3aGlsZSAoaS0tKSB7IC8vIFJ1biBpbiByZXZlcnNlIG9yZGVyCiAgICAgICAgICAgICAgICB0ID0gdG9rZW5zW2ldOwogICAgICAgICAgICAgICAgaWYgKCh0LnNjb3BlID09PSAiYWxsIiB8fCB0LnNjb3BlID09PSBzY29wZSkgJiYgKCF0LnRyaWdnZXIgfHwgdC50cmlnZ2VyLmNhbGwoY29udGV4dCkpKSB7CiAgICAgICAgICAgICAgICAgICAgdC5wYXR0ZXJuLmxhc3RJbmRleCA9IHBvczsKICAgICAgICAgICAgICAgICAgICBtYXRjaCA9IGZpeGVkLmV4ZWMuY2FsbCh0LnBhdHRlcm4sIHBhdHRlcm4pOyAvLyBGaXhlZCBgZXhlY2AgaGVyZSBhbGxvd3MgdXNlIG9mIG5hbWVkIGJhY2tyZWZlcmVuY2VzLCBldGMuCiAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoICYmIG1hdGNoLmluZGV4ID09PSBwb3MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0OiB0LmhhbmRsZXIuY2FsbChjb250ZXh0LCBtYXRjaCwgc2NvcGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2g6IG1hdGNoCiAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICB0aHJvdyBlcnI7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgaXNJbnNpZGVDb25zdHJ1Y3RvciA9IGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKLyoqCiAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgWFJlZ0V4cCBzeW50YXggYW5kIGZsYWcgZXh0ZW5zaWJpbGl0eS4KICogQHByaXZhdGUKICogQHBhcmFtIHtCb29sZWFufSBvbiBgdHJ1ZWAgdG8gZW5hYmxlOyBgZmFsc2VgIHRvIGRpc2FibGUuCiAqLwogICAgZnVuY3Rpb24gc2V0RXh0ZW5zaWJpbGl0eShvbikgewogICAgICAgIHNlbGYuYWRkVG9rZW4gPSBhZGRUb2tlbltvbiA/ICJvbiIgOiAib2ZmIl07CiAgICAgICAgZmVhdHVyZXMuZXh0ZW5zaWJpbGl0eSA9IG9uOwogICAgfQoKLyoqCiAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgbmF0aXZlIG1ldGhvZCBvdmVycmlkZXMuCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7Qm9vbGVhbn0gb24gYHRydWVgIHRvIGVuYWJsZTsgYGZhbHNlYCB0byBkaXNhYmxlLgogKi8KICAgIGZ1bmN0aW9uIHNldE5hdGl2ZXMob24pIHsKICAgICAgICBSZWdFeHAucHJvdG90eXBlLmV4ZWMgPSAob24gPyBmaXhlZCA6IG5hdGl2KS5leGVjOwogICAgICAgIFJlZ0V4cC5wcm90b3R5cGUudGVzdCA9IChvbiA/IGZpeGVkIDogbmF0aXYpLnRlc3Q7CiAgICAgICAgU3RyaW5nLnByb3RvdHlwZS5tYXRjaCA9IChvbiA/IGZpeGVkIDogbmF0aXYpLm1hdGNoOwogICAgICAgIFN0cmluZy5wcm90b3R5cGUucmVwbGFjZSA9IChvbiA/IGZpeGVkIDogbmF0aXYpLnJlcGxhY2U7CiAgICAgICAgU3RyaW5nLnByb3RvdHlwZS5zcGxpdCA9IChvbiA/IGZpeGVkIDogbmF0aXYpLnNwbGl0OwogICAgICAgIGZlYXR1cmVzLm5hdGl2ZXMgPSBvbjsKICAgIH0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogIENvbnN0cnVjdG9yCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCi8qKgogKiBDcmVhdGVzIGFuIGV4dGVuZGVkIHJlZ3VsYXIgZXhwcmVzc2lvbiBvYmplY3QgZm9yIG1hdGNoaW5nIHRleHQgd2l0aCBhIHBhdHRlcm4uIERpZmZlcnMgZnJvbSBhCiAqIG5hdGl2ZSByZWd1bGFyIGV4cHJlc3Npb24gaW4gdGhhdCBhZGRpdGlvbmFsIHN5bnRheCBhbmQgZmxhZ3MgYXJlIHN1cHBvcnRlZC4gVGhlIHJldHVybmVkIG9iamVjdAogKiBpcyBpbiBmYWN0IGEgbmF0aXZlIGBSZWdFeHBgIGFuZCB3b3JrcyB3aXRoIGFsbCBuYXRpdmUgbWV0aG9kcy4KICogQGNsYXNzIFhSZWdFeHAKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gcGF0dGVybiBSZWdleCBwYXR0ZXJuIHN0cmluZywgb3IgYW4gZXhpc3RpbmcgYFJlZ0V4cGAgb2JqZWN0IHRvIGNvcHkuCiAqIEBwYXJhbSB7U3RyaW5nfSBbZmxhZ3NdIEFueSBjb21iaW5hdGlvbiBvZiBmbGFnczoKICogICA8bGk+YGdgIC0gZ2xvYmFsCiAqICAgPGxpPmBpYCAtIGlnbm9yZSBjYXNlCiAqICAgPGxpPmBtYCAtIG11bHRpbGluZSBhbmNob3JzCiAqICAgPGxpPmBuYCAtIGV4cGxpY2l0IGNhcHR1cmUKICogICA8bGk+YHNgIC0gZG90IG1hdGNoZXMgYWxsIChha2Egc2luZ2xlbGluZSkKICogICA8bGk+YHhgIC0gZnJlZS1zcGFjaW5nIGFuZCBsaW5lIGNvbW1lbnRzIChha2EgZXh0ZW5kZWQpCiAqICAgPGxpPmB5YCAtIHN0aWNreSAoRmlyZWZveCAzKyBvbmx5KQogKiAgIEZsYWdzIGNhbm5vdCBiZSBwcm92aWRlZCB3aGVuIGNvbnN0cnVjdGluZyBvbmUgYFJlZ0V4cGAgZnJvbSBhbm90aGVyLgogKiBAcmV0dXJucyB7UmVnRXhwfSBFeHRlbmRlZCByZWd1bGFyIGV4cHJlc3Npb24gb2JqZWN0LgogKiBAZXhhbXBsZQogKgogKiAvLyBXaXRoIG5hbWVkIGNhcHR1cmUgYW5kIGZsYWcgeAogKiBkYXRlID0gWFJlZ0V4cCgnKD88eWVhcj4gIFswLTldezR9KSAtPyAgIyB5ZWFyICBcblwKICogICAgICAgICAgICAgICAgICg/PG1vbnRoPiBbMC05XXsyfSkgLT8gICMgbW9udGggXG5cCiAqICAgICAgICAgICAgICAgICAoPzxkYXk+ICAgWzAtOV17Mn0pICAgICAjIGRheSAgICcsICd4Jyk7CiAqCiAqIC8vIFBhc3NpbmcgYSByZWdleCBvYmplY3QgdG8gY29weSBpdC4gVGhlIGNvcHkgbWFpbnRhaW5zIHNwZWNpYWwgcHJvcGVydGllcyBmb3IgbmFtZWQgY2FwdHVyZSwKICogLy8gaXMgYXVnbWVudGVkIHdpdGggYFhSZWdFeHAucHJvdG90eXBlYCBtZXRob2RzLCBhbmQgaGFzIGEgZnJlc2ggYGxhc3RJbmRleGAgcHJvcGVydHkgKHNldCB0bwogKiAvLyB6ZXJvKS4gTmF0aXZlIHJlZ2V4ZXMgYXJlIG5vdCByZWNvbXBpbGVkIHVzaW5nIFhSZWdFeHAgc3ludGF4LgogKiBYUmVnRXhwKC9yZWdleC8pOwogKi8KICAgIHNlbGYgPSBmdW5jdGlvbiAocGF0dGVybiwgZmxhZ3MpIHsKICAgICAgICBpZiAoc2VsZi5pc1JlZ0V4cChwYXR0ZXJuKSkgewogICAgICAgICAgICBpZiAoZmxhZ3MgIT09IHVuZGVmKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCJjYW4ndCBzdXBwbHkgZmxhZ3Mgd2hlbiBjb25zdHJ1Y3Rpbmcgb25lIFJlZ0V4cCBmcm9tIGFub3RoZXIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY29weShwYXR0ZXJuKTsKICAgICAgICB9CiAgICAgICAgLy8gVG9rZW5zIGJlY29tZSBwYXJ0IG9mIHRoZSByZWdleCBjb25zdHJ1Y3Rpb24gcHJvY2Vzcywgc28gcHJvdGVjdCBhZ2FpbnN0IGluZmluaXRlIHJlY3Vyc2lvbgogICAgICAgIC8vIHdoZW4gYW4gWFJlZ0V4cCBpcyBjb25zdHJ1Y3RlZCB3aXRoaW4gYSB0b2tlbiBoYW5kbGVyIGZ1bmN0aW9uCiAgICAgICAgaWYgKGlzSW5zaWRlQ29uc3RydWN0b3IpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJjYW4ndCBjYWxsIHRoZSBYUmVnRXhwIGNvbnN0cnVjdG9yIHdpdGhpbiB0b2tlbiBkZWZpbml0aW9uIGZ1bmN0aW9ucyIpOwogICAgICAgIH0KCiAgICAgICAgdmFyIG91dHB1dCA9IFtdLAogICAgICAgICAgICBzY29wZSA9IGRlZmF1bHRTY29wZSwKICAgICAgICAgICAgdG9rZW5Db250ZXh0ID0gewogICAgICAgICAgICAgICAgaGFzTmFtZWRDYXB0dXJlOiBmYWxzZSwKICAgICAgICAgICAgICAgIGNhcHR1cmVOYW1lczogW10sCiAgICAgICAgICAgICAgICBoYXNGbGFnOiBmdW5jdGlvbiAoZmxhZykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmbGFncy5pbmRleE9mKGZsYWcpID4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHBvcyA9IDAsCiAgICAgICAgICAgIHRva2VuUmVzdWx0LAogICAgICAgICAgICBtYXRjaCwKICAgICAgICAgICAgY2hyOwogICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuID09PSB1bmRlZiA/ICIiIDogU3RyaW5nKHBhdHRlcm4pOwogICAgICAgIGZsYWdzID0gZmxhZ3MgPT09IHVuZGVmID8gIiIgOiBTdHJpbmcoZmxhZ3MpOwoKICAgICAgICBpZiAobmF0aXYubWF0Y2guY2FsbChmbGFncywgZHVwbGljYXRlRmxhZ3MpKSB7IC8vIERvbid0IHVzZSB0ZXN0L2V4ZWMgYmVjYXVzZSB0aGV5IHdvdWxkIHVwZGF0ZSBsYXN0SW5kZXgKICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCJpbnZhbGlkIGR1cGxpY2F0ZSByZWd1bGFyIGV4cHJlc3Npb24gZmxhZyIpOwogICAgICAgIH0KICAgICAgICAvLyBTdHJpcC9hcHBseSBsZWFkaW5nIG1vZGUgbW9kaWZpZXIgd2l0aCBhbnkgY29tYmluYXRpb24gb2YgZmxhZ3MgZXhjZXB0IGcgb3IgeTogKD9pbW5zeCkKICAgICAgICBwYXR0ZXJuID0gbmF0aXYucmVwbGFjZS5jYWxsKHBhdHRlcm4sIC9eXChcPyhbXHckXSspXCkvLCBmdW5jdGlvbiAoJDAsICQxKSB7CiAgICAgICAgICAgIGlmIChuYXRpdi50ZXN0LmNhbGwoL1tneV0vLCAkMSkpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcigiY2FuJ3QgdXNlIGZsYWcgZyBvciB5IGluIG1vZGUgbW9kaWZpZXIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmbGFncyA9IG5hdGl2LnJlcGxhY2UuY2FsbChmbGFncyArICQxLCBkdXBsaWNhdGVGbGFncywgIiIpOwogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfSk7CiAgICAgICAgc2VsZi5mb3JFYWNoKGZsYWdzLCAvW1xzXFNdLywgZnVuY3Rpb24gKG0pIHsKICAgICAgICAgICAgaWYgKHJlZ2lzdGVyZWRGbGFncy5pbmRleE9mKG1bMF0pIDwgMCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCJpbnZhbGlkIHJlZ3VsYXIgZXhwcmVzc2lvbiBmbGFnICIgKyBtWzBdKTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwoKICAgICAgICB3aGlsZSAocG9zIDwgcGF0dGVybi5sZW5ndGgpIHsKICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGN1c3RvbSB0b2tlbnMgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24KICAgICAgICAgICAgdG9rZW5SZXN1bHQgPSBydW5Ub2tlbnMocGF0dGVybiwgcG9zLCBzY29wZSwgdG9rZW5Db250ZXh0KTsKICAgICAgICAgICAgaWYgKHRva2VuUmVzdWx0KSB7CiAgICAgICAgICAgICAgICBvdXRwdXQucHVzaCh0b2tlblJlc3VsdC5vdXRwdXQpOwogICAgICAgICAgICAgICAgcG9zICs9ICh0b2tlblJlc3VsdC5tYXRjaFswXS5sZW5ndGggfHwgMSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBDaGVjayBmb3IgbmF0aXZlIHRva2VucyAoZXhjZXB0IGNoYXJhY3RlciBjbGFzc2VzKSBhdCB0aGUgY3VycmVudCBwb3NpdGlvbgogICAgICAgICAgICAgICAgbWF0Y2ggPSBuYXRpdi5leGVjLmNhbGwobmF0aXZlVG9rZW5zW3Njb3BlXSwgcGF0dGVybi5zbGljZShwb3MpKTsKICAgICAgICAgICAgICAgIGlmIChtYXRjaCkgewogICAgICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKG1hdGNoWzBdKTsKICAgICAgICAgICAgICAgICAgICBwb3MgKz0gbWF0Y2hbMF0ubGVuZ3RoOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjaHIgPSBwYXR0ZXJuLmNoYXJBdChwb3MpOwogICAgICAgICAgICAgICAgICAgIGlmIChjaHIgPT09ICJbIikgewogICAgICAgICAgICAgICAgICAgICAgICBzY29wZSA9IGNsYXNzU2NvcGU7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaHIgPT09ICJdIikgewogICAgICAgICAgICAgICAgICAgICAgICBzY29wZSA9IGRlZmF1bHRTY29wZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gQWR2YW5jZSBwb3NpdGlvbiBieSBvbmUgY2hhcmFjdGVyCiAgICAgICAgICAgICAgICAgICAgb3V0cHV0LnB1c2goY2hyKTsKICAgICAgICAgICAgICAgICAgICArK3BvczsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGF1Z21lbnQobmV3IFJlZ0V4cChvdXRwdXQuam9pbigiIiksIG5hdGl2LnJlcGxhY2UuY2FsbChmbGFncywgL1teZ2lteV0rL2csICIiKSksCiAgICAgICAgICAgICAgICAgICAgICAgdG9rZW5Db250ZXh0Lmhhc05hbWVkQ2FwdHVyZSA/IHRva2VuQ29udGV4dC5jYXB0dXJlTmFtZXMgOiBudWxsKTsKICAgIH07CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqICBQdWJsaWMgbWV0aG9kcy9wcm9wZXJ0aWVzCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCi8vIEluc3RhbGxlZCBhbmQgdW5pbnN0YWxsZWQgc3RhdGVzIGZvciBgWFJlZ0V4cC5hZGRUb2tlbmAKICAgIGFkZFRva2VuID0gewogICAgICAgIG9uOiBmdW5jdGlvbiAocmVnZXgsIGhhbmRsZXIsIG9wdGlvbnMpIHsKICAgICAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgICAgICAgICAgIGlmIChyZWdleCkgewogICAgICAgICAgICAgICAgdG9rZW5zLnB1c2goewogICAgICAgICAgICAgICAgICAgIHBhdHRlcm46IGNvcHkocmVnZXgsICJnIiArIChoYXNOYXRpdmVZID8gInkiIDogIiIpKSwKICAgICAgICAgICAgICAgICAgICBoYW5kbGVyOiBoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgIHNjb3BlOiBvcHRpb25zLnNjb3BlIHx8IGRlZmF1bHRTY29wZSwKICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyOiBvcHRpb25zLnRyaWdnZXIgfHwgbnVsbAogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gUHJvdmlkaW5nIGBjdXN0b21GbGFnc2Agd2l0aCBudWxsIGByZWdleGAgYW5kIGBoYW5kbGVyYCBhbGxvd3MgYWRkaW5nIGZsYWdzIHRoYXQgZG8KICAgICAgICAgICAgLy8gbm90aGluZywgYnV0IGRvbid0IHRocm93IGFuIGVycm9yCiAgICAgICAgICAgIGlmIChvcHRpb25zLmN1c3RvbUZsYWdzKSB7CiAgICAgICAgICAgICAgICByZWdpc3RlcmVkRmxhZ3MgPSBuYXRpdi5yZXBsYWNlLmNhbGwocmVnaXN0ZXJlZEZsYWdzICsgb3B0aW9ucy5jdXN0b21GbGFncywgZHVwbGljYXRlRmxhZ3MsICIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgb2ZmOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiZXh0ZW5zaWJpbGl0eSBtdXN0IGJlIGluc3RhbGxlZCBiZWZvcmUgdXNpbmcgYWRkVG9rZW4iKTsKICAgICAgICB9CiAgICB9OwoKLyoqCiAqIEV4dGVuZHMgb3IgY2hhbmdlcyBYUmVnRXhwIHN5bnRheCBhbmQgYWxsb3dzIGN1c3RvbSBmbGFncy4gVGhpcyBpcyB1c2VkIGludGVybmFsbHkgYW5kIGNhbiBiZQogKiB1c2VkIHRvIGNyZWF0ZSBYUmVnRXhwIGFkZG9ucy4gYFhSZWdFeHAuaW5zdGFsbCgnZXh0ZW5zaWJpbGl0eScpYCBtdXN0IGJlIHJ1biBiZWZvcmUgY2FsbGluZwogKiB0aGlzIGZ1bmN0aW9uLCBvciBhbiBlcnJvciBpcyB0aHJvd24uIElmIG1vcmUgdGhhbiBvbmUgdG9rZW4gY2FuIG1hdGNoIHRoZSBzYW1lIHN0cmluZywgdGhlIGxhc3QKICogYWRkZWQgd2lucy4KICogQG1lbWJlck9mIFhSZWdFeHAKICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4IFJlZ2V4IG9iamVjdCB0aGF0IG1hdGNoZXMgdGhlIG5ldyB0b2tlbi4KICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlciBGdW5jdGlvbiB0aGF0IHJldHVybnMgYSBuZXcgcGF0dGVybiBzdHJpbmcgKHVzaW5nIG5hdGl2ZSByZWdleCBzeW50YXgpCiAqICAgdG8gcmVwbGFjZSB0aGUgbWF0Y2hlZCB0b2tlbiB3aXRoaW4gYWxsIGZ1dHVyZSBYUmVnRXhwIHJlZ2V4ZXMuIEhhcyBhY2Nlc3MgdG8gcGVyc2lzdGVudAogKiAgIHByb3BlcnRpZXMgb2YgdGhlIHJlZ2V4IGJlaW5nIGJ1aWx0LCB0aHJvdWdoIGB0aGlzYC4gSW52b2tlZCB3aXRoIHR3byBhcmd1bWVudHM6CiAqICAgPGxpPlRoZSBtYXRjaCBhcnJheSwgd2l0aCBuYW1lZCBiYWNrcmVmZXJlbmNlIHByb3BlcnRpZXMuCiAqICAgPGxpPlRoZSByZWdleCBzY29wZSB3aGVyZSB0aGUgbWF0Y2ggd2FzIGZvdW5kLgogKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIE9wdGlvbnMgb2JqZWN0IHdpdGggb3B0aW9uYWwgcHJvcGVydGllczoKICogICA8bGk+YHNjb3BlYCB7U3RyaW5nfSBTY29wZXMgd2hlcmUgdGhlIHRva2VuIGFwcGxpZXM6ICdkZWZhdWx0JywgJ2NsYXNzJywgb3IgJ2FsbCcuCiAqICAgPGxpPmB0cmlnZ2VyYCB7RnVuY3Rpb259IEZ1bmN0aW9uIHRoYXQgcmV0dXJucyBgdHJ1ZWAgd2hlbiB0aGUgdG9rZW4gc2hvdWxkIGJlIGFwcGxpZWQ7IGUuZy4sCiAqICAgICBpZiBhIGZsYWcgaXMgc2V0LiBJZiBgZmFsc2VgIGlzIHJldHVybmVkLCB0aGUgbWF0Y2hlZCBzdHJpbmcgY2FuIGJlIG1hdGNoZWQgYnkgb3RoZXIgdG9rZW5zLgogKiAgICAgSGFzIGFjY2VzcyB0byBwZXJzaXN0ZW50IHByb3BlcnRpZXMgb2YgdGhlIHJlZ2V4IGJlaW5nIGJ1aWx0LCB0aHJvdWdoIGB0aGlzYCAoaW5jbHVkaW5nCiAqICAgICBmdW5jdGlvbiBgdGhpcy5oYXNGbGFnYCkuCiAqICAgPGxpPmBjdXN0b21GbGFnc2Age1N0cmluZ30gTm9ubmF0aXZlIGZsYWdzIHVzZWQgYnkgdGhlIHRva2VuJ3MgaGFuZGxlciBvciB0cmlnZ2VyIGZ1bmN0aW9ucy4KICogICAgIFByZXZlbnRzIFhSZWdFeHAgZnJvbSB0aHJvd2luZyBhbiBpbnZhbGlkIGZsYWcgZXJyb3Igd2hlbiB0aGUgc3BlY2lmaWVkIGZsYWdzIGFyZSB1c2VkLgogKiBAZXhhbXBsZQogKgogKiAvLyBCYXNpYyB1c2FnZTogQWRkcyBcYSBmb3IgQUxFUlQgY2hhcmFjdGVyCiAqIFhSZWdFeHAuYWRkVG9rZW4oCiAqICAgL1xcYS8sCiAqICAgZnVuY3Rpb24gKCkge3JldHVybiAnXFx4MDcnO30sCiAqICAge3Njb3BlOiAnYWxsJ30KICogKTsKICogWFJlZ0V4cCgnXFxhW1xcYS1cXG5dKycpLnRlc3QoJ1x4MDdcblx4MDcnKTsgLy8gLT4gdHJ1ZQogKi8KICAgIHNlbGYuYWRkVG9rZW4gPSBhZGRUb2tlbi5vZmY7CgovKioKICogQ2FjaGVzIGFuZCByZXR1cm5zIHRoZSByZXN1bHQgb2YgY2FsbGluZyBgWFJlZ0V4cChwYXR0ZXJuLCBmbGFncylgLiBPbiBhbnkgc3Vic2VxdWVudCBjYWxsIHdpdGgKICogdGhlIHNhbWUgcGF0dGVybiBhbmQgZmxhZyBjb21iaW5hdGlvbiwgdGhlIGNhY2hlZCBjb3B5IGlzIHJldHVybmVkLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gcGF0dGVybiBSZWdleCBwYXR0ZXJuIHN0cmluZy4KICogQHBhcmFtIHtTdHJpbmd9IFtmbGFnc10gQW55IGNvbWJpbmF0aW9uIG9mIFhSZWdFeHAgZmxhZ3MuCiAqIEByZXR1cm5zIHtSZWdFeHB9IENhY2hlZCBYUmVnRXhwIG9iamVjdC4KICogQGV4YW1wbGUKICoKICogd2hpbGUgKG1hdGNoID0gWFJlZ0V4cC5jYWNoZSgnLicsICdncycpLmV4ZWMoc3RyKSkgewogKiAgIC8vIFRoZSByZWdleCBpcyBjb21waWxlZCBvbmNlIG9ubHkKICogfQogKi8KICAgIHNlbGYuY2FjaGUgPSBmdW5jdGlvbiAocGF0dGVybiwgZmxhZ3MpIHsKICAgICAgICB2YXIga2V5ID0gcGF0dGVybiArICIvIiArIChmbGFncyB8fCAiIik7CiAgICAgICAgcmV0dXJuIGNhY2hlW2tleV0gfHwgKGNhY2hlW2tleV0gPSBzZWxmKHBhdHRlcm4sIGZsYWdzKSk7CiAgICB9OwoKLyoqCiAqIEVzY2FwZXMgYW55IHJlZ3VsYXIgZXhwcmVzc2lvbiBtZXRhY2hhcmFjdGVycywgZm9yIHVzZSB3aGVuIG1hdGNoaW5nIGxpdGVyYWwgc3RyaW5ncy4gVGhlIHJlc3VsdAogKiBjYW4gc2FmZWx5IGJlIHVzZWQgYXQgYW55IHBvaW50IHdpdGhpbiBhIHJlZ2V4IHRoYXQgdXNlcyBhbnkgZmxhZ3MuCiAqIEBtZW1iZXJPZiBYUmVnRXhwCiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGVzY2FwZS4KICogQHJldHVybnMge1N0cmluZ30gU3RyaW5nIHdpdGggcmVnZXggbWV0YWNoYXJhY3RlcnMgZXNjYXBlZC4KICogQGV4YW1wbGUKICoKICogWFJlZ0V4cC5lc2NhcGUoJ0VzY2FwZWQ/IDwuPicpOwogKiAvLyAtPiAnRXNjYXBlZFw/XCA8XC4+JwogKi8KICAgIHNlbGYuZXNjYXBlID0gZnVuY3Rpb24gKHN0cikgewogICAgICAgIHJldHVybiBuYXRpdi5yZXBsYWNlLmNhbGwoc3RyLCAvWy1bXF17fSgpKis/LixcXF4kfCNcc10vZywgIlxcJCYiKTsKICAgIH07CgovKioKICogRXhlY3V0ZXMgYSByZWdleCBzZWFyY2ggaW4gYSBzcGVjaWZpZWQgc3RyaW5nLiBSZXR1cm5zIGEgbWF0Y2ggYXJyYXkgb3IgYG51bGxgLiBJZiB0aGUgcHJvdmlkZWQKICogcmVnZXggdXNlcyBuYW1lZCBjYXB0dXJlLCBuYW1lZCBiYWNrcmVmZXJlbmNlIHByb3BlcnRpZXMgYXJlIGluY2x1ZGVkIG9uIHRoZSBtYXRjaCBhcnJheS4KICogT3B0aW9uYWwgYHBvc2AgYW5kIGBzdGlja3lgIGFyZ3VtZW50cyBzcGVjaWZ5IHRoZSBzZWFyY2ggc3RhcnQgcG9zaXRpb24sIGFuZCB3aGV0aGVyIHRoZSBtYXRjaAogKiBtdXN0IHN0YXJ0IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gb25seS4gVGhlIGBsYXN0SW5kZXhgIHByb3BlcnR5IG9mIHRoZSBwcm92aWRlZCByZWdleCBpcyBub3QKICogdXNlZCwgYnV0IGlzIHVwZGF0ZWQgZm9yIGNvbXBhdGliaWxpdHkuIEFsc28gZml4ZXMgYnJvd3NlciBidWdzIGNvbXBhcmVkIHRvIHRoZSBuYXRpdmUKICogYFJlZ0V4cC5wcm90b3R5cGUuZXhlY2AgYW5kIGNhbiBiZSB1c2VkIHJlbGlhYmx5IGNyb3NzLWJyb3dzZXIuCiAqIEBtZW1iZXJPZiBYUmVnRXhwCiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIHNlYXJjaC4KICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4IFJlZ2V4IHRvIHNlYXJjaCB3aXRoLgogKiBAcGFyYW0ge051bWJlcn0gW3Bvcz0wXSBaZXJvLWJhc2VkIGluZGV4IGF0IHdoaWNoIHRvIHN0YXJ0IHRoZSBzZWFyY2guCiAqIEBwYXJhbSB7Qm9vbGVhbnxTdHJpbmd9IFtzdGlja3k9ZmFsc2VdIFdoZXRoZXIgdGhlIG1hdGNoIG11c3Qgc3RhcnQgYXQgdGhlIHNwZWNpZmllZCBwb3NpdGlvbgogKiAgIG9ubHkuIFRoZSBzdHJpbmcgYCdzdGlja3knYCBpcyBhY2NlcHRlZCBhcyBhbiBhbHRlcm5hdGl2ZSB0byBgdHJ1ZWAuCiAqIEByZXR1cm5zIHtBcnJheX0gTWF0Y2ggYXJyYXkgd2l0aCBuYW1lZCBiYWNrcmVmZXJlbmNlIHByb3BlcnRpZXMsIG9yIG51bGwuCiAqIEBleGFtcGxlCiAqCiAqIC8vIEJhc2ljIHVzZSwgd2l0aCBuYW1lZCBiYWNrcmVmZXJlbmNlCiAqIHZhciBtYXRjaCA9IFhSZWdFeHAuZXhlYygnVSsyNjIwJywgWFJlZ0V4cCgnVVxcKyg/PGhleD5bMC05QS1GXXs0fSknKSk7CiAqIG1hdGNoLmhleDsgLy8gLT4gJzI2MjAnCiAqCiAqIC8vIFdpdGggcG9zIGFuZCBzdGlja3ksIGluIGEgbG9vcAogKiB2YXIgcG9zID0gMiwgcmVzdWx0ID0gW10sIG1hdGNoOwogKiB3aGlsZSAobWF0Y2ggPSBYUmVnRXhwLmV4ZWMoJzwxPjwyPjwzPjw0PjU8Nj4nLCAvPChcZCk+LywgcG9zLCAnc3RpY2t5JykpIHsKICogICByZXN1bHQucHVzaChtYXRjaFsxXSk7CiAqICAgcG9zID0gbWF0Y2guaW5kZXggKyBtYXRjaFswXS5sZW5ndGg7CiAqIH0KICogLy8gcmVzdWx0IC0+IFsnMicsICczJywgJzQnXQogKi8KICAgIHNlbGYuZXhlYyA9IGZ1bmN0aW9uIChzdHIsIHJlZ2V4LCBwb3MsIHN0aWNreSkgewogICAgICAgIHZhciByMiA9IGNvcHkocmVnZXgsICJnIiArIChzdGlja3kgJiYgaGFzTmF0aXZlWSA/ICJ5IiA6ICIiKSwgKHN0aWNreSA9PT0gZmFsc2UgPyAieSIgOiAiIikpLAogICAgICAgICAgICBtYXRjaDsKICAgICAgICByMi5sYXN0SW5kZXggPSBwb3MgPSBwb3MgfHwgMDsKICAgICAgICBtYXRjaCA9IGZpeGVkLmV4ZWMuY2FsbChyMiwgc3RyKTsgLy8gRml4ZWQgYGV4ZWNgIHJlcXVpcmVkIGZvciBgbGFzdEluZGV4YCBmaXgsIGV0Yy4KICAgICAgICBpZiAoc3RpY2t5ICYmIG1hdGNoICYmIG1hdGNoLmluZGV4ICE9PSBwb3MpIHsKICAgICAgICAgICAgbWF0Y2ggPSBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAocmVnZXguZ2xvYmFsKSB7CiAgICAgICAgICAgIHJlZ2V4Lmxhc3RJbmRleCA9IG1hdGNoID8gcjIubGFzdEluZGV4IDogMDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hdGNoOwogICAgfTsKCi8qKgogKiBFeGVjdXRlcyBhIHByb3ZpZGVkIGZ1bmN0aW9uIG9uY2UgcGVyIHJlZ2V4IG1hdGNoLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBzZWFyY2guCiAqIEBwYXJhbSB7UmVnRXhwfSByZWdleCBSZWdleCB0byBzZWFyY2ggd2l0aC4KICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgRnVuY3Rpb24gdG8gZXhlY3V0ZSBmb3IgZWFjaCBtYXRjaC4gSW52b2tlZCB3aXRoIGZvdXIgYXJndW1lbnRzOgogKiAgIDxsaT5UaGUgbWF0Y2ggYXJyYXksIHdpdGggbmFtZWQgYmFja3JlZmVyZW5jZSBwcm9wZXJ0aWVzLgogKiAgIDxsaT5UaGUgemVyby1iYXNlZCBtYXRjaCBpbmRleC4KICogICA8bGk+VGhlIHN0cmluZyBiZWluZyB0cmF2ZXJzZWQuCiAqICAgPGxpPlRoZSByZWdleCBvYmplY3QgYmVpbmcgdXNlZCB0byB0cmF2ZXJzZSB0aGUgc3RyaW5nLgogKiBAcGFyYW0geyp9IFtjb250ZXh0XSBPYmplY3QgdG8gdXNlIGFzIGB0aGlzYCB3aGVuIGV4ZWN1dGluZyBgY2FsbGJhY2tgLgogKiBAcmV0dXJucyB7Kn0gUHJvdmlkZWQgYGNvbnRleHRgIG9iamVjdC4KICogQGV4YW1wbGUKICoKICogLy8gRXh0cmFjdHMgZXZlcnkgb3RoZXIgZGlnaXQgZnJvbSBhIHN0cmluZwogKiBYUmVnRXhwLmZvckVhY2goJzFhMjM0NScsIC9cZC8sIGZ1bmN0aW9uIChtYXRjaCwgaSkgewogKiAgIGlmIChpICUgMikgdGhpcy5wdXNoKCttYXRjaFswXSk7CiAqIH0sIFtdKTsKICogLy8gLT4gWzIsIDRdCiAqLwogICAgc2VsZi5mb3JFYWNoID0gZnVuY3Rpb24gKHN0ciwgcmVnZXgsIGNhbGxiYWNrLCBjb250ZXh0KSB7CiAgICAgICAgdmFyIHBvcyA9IDAsCiAgICAgICAgICAgIGkgPSAtMSwKICAgICAgICAgICAgbWF0Y2g7CiAgICAgICAgd2hpbGUgKChtYXRjaCA9IHNlbGYuZXhlYyhzdHIsIHJlZ2V4LCBwb3MpKSkgewogICAgICAgICAgICBjYWxsYmFjay5jYWxsKGNvbnRleHQsIG1hdGNoLCArK2ksIHN0ciwgcmVnZXgpOwogICAgICAgICAgICBwb3MgPSBtYXRjaC5pbmRleCArIChtYXRjaFswXS5sZW5ndGggfHwgMSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb250ZXh0OwogICAgfTsKCi8qKgogKiBDb3BpZXMgYSByZWdleCBvYmplY3QgYW5kIGFkZHMgZmxhZyBgZ2AuIFRoZSBjb3B5IG1haW50YWlucyBzcGVjaWFsIHByb3BlcnRpZXMgZm9yIG5hbWVkCiAqIGNhcHR1cmUsIGlzIGF1Z21lbnRlZCB3aXRoIGBYUmVnRXhwLnByb3RvdHlwZWAgbWV0aG9kcywgYW5kIGhhcyBhIGZyZXNoIGBsYXN0SW5kZXhgIHByb3BlcnR5CiAqIChzZXQgdG8gemVybykuIE5hdGl2ZSByZWdleGVzIGFyZSBub3QgcmVjb21waWxlZCB1c2luZyBYUmVnRXhwIHN5bnRheC4KICogQG1lbWJlck9mIFhSZWdFeHAKICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4IFJlZ2V4IHRvIGdsb2JhbGl6ZS4KICogQHJldHVybnMge1JlZ0V4cH0gQ29weSBvZiB0aGUgcHJvdmlkZWQgcmVnZXggd2l0aCBmbGFnIGBnYCBhZGRlZC4KICogQGV4YW1wbGUKICoKICogdmFyIGdsb2JhbENvcHkgPSBYUmVnRXhwLmdsb2JhbGl6ZSgvcmVnZXgvKTsKICogZ2xvYmFsQ29weS5nbG9iYWw7IC8vIC0+IHRydWUKICovCiAgICBzZWxmLmdsb2JhbGl6ZSA9IGZ1bmN0aW9uIChyZWdleCkgewogICAgICAgIHJldHVybiBjb3B5KHJlZ2V4LCAiZyIpOwogICAgfTsKCi8qKgogKiBJbnN0YWxscyBvcHRpb25hbCBmZWF0dXJlcyBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCBvcHRpb25zLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IG9wdGlvbnMgT3B0aW9ucyBvYmplY3Qgb3Igc3RyaW5nLgogKiBAZXhhbXBsZQogKgogKiAvLyBXaXRoIGFuIG9wdGlvbnMgb2JqZWN0CiAqIFhSZWdFeHAuaW5zdGFsbCh7CiAqICAgLy8gT3ZlcnJpZGVzIG5hdGl2ZSByZWdleCBtZXRob2RzIHdpdGggZml4ZWQvZXh0ZW5kZWQgdmVyc2lvbnMgdGhhdCBzdXBwb3J0IG5hbWVkCiAqICAgLy8gYmFja3JlZmVyZW5jZXMgYW5kIGZpeCBudW1lcm91cyBjcm9zcy1icm93c2VyIGJ1Z3MKICogICBuYXRpdmVzOiB0cnVlLAogKgogKiAgIC8vIEVuYWJsZXMgZXh0ZW5zaWJpbGl0eSBvZiBYUmVnRXhwIHN5bnRheCBhbmQgZmxhZ3MKICogICBleHRlbnNpYmlsaXR5OiB0cnVlCiAqIH0pOwogKgogKiAvLyBXaXRoIGFuIG9wdGlvbnMgc3RyaW5nCiAqIFhSZWdFeHAuaW5zdGFsbCgnbmF0aXZlcyBleHRlbnNpYmlsaXR5Jyk7CiAqCiAqIC8vIFVzaW5nIGEgc2hvcnRjdXQgdG8gaW5zdGFsbCBhbGwgb3B0aW9uYWwgZmVhdHVyZXMKICogWFJlZ0V4cC5pbnN0YWxsKCdhbGwnKTsKICovCiAgICBzZWxmLmluc3RhbGwgPSBmdW5jdGlvbiAob3B0aW9ucykgewogICAgICAgIG9wdGlvbnMgPSBwcmVwYXJlT3B0aW9ucyhvcHRpb25zKTsKICAgICAgICBpZiAoIWZlYXR1cmVzLm5hdGl2ZXMgJiYgb3B0aW9ucy5uYXRpdmVzKSB7CiAgICAgICAgICAgIHNldE5hdGl2ZXModHJ1ZSk7CiAgICAgICAgfQogICAgICAgIGlmICghZmVhdHVyZXMuZXh0ZW5zaWJpbGl0eSAmJiBvcHRpb25zLmV4dGVuc2liaWxpdHkpIHsKICAgICAgICAgICAgc2V0RXh0ZW5zaWJpbGl0eSh0cnVlKTsKICAgICAgICB9CiAgICB9OwoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGFuIGluZGl2aWR1YWwgb3B0aW9uYWwgZmVhdHVyZSBpcyBpbnN0YWxsZWQuCiAqIEBtZW1iZXJPZiBYUmVnRXhwCiAqIEBwYXJhbSB7U3RyaW5nfSBmZWF0dXJlIE5hbWUgb2YgdGhlIGZlYXR1cmUgdG8gY2hlY2suIE9uZSBvZjoKICogICA8bGk+YG5hdGl2ZXNgCiAqICAgPGxpPmBleHRlbnNpYmlsaXR5YAogKiBAcmV0dXJucyB7Qm9vbGVhbn0gV2hldGhlciB0aGUgZmVhdHVyZSBpcyBpbnN0YWxsZWQuCiAqIEBleGFtcGxlCiAqCiAqIFhSZWdFeHAuaXNJbnN0YWxsZWQoJ25hdGl2ZXMnKTsKICovCiAgICBzZWxmLmlzSW5zdGFsbGVkID0gZnVuY3Rpb24gKGZlYXR1cmUpIHsKICAgICAgICByZXR1cm4gISEoZmVhdHVyZXNbZmVhdHVyZV0pOwogICAgfTsKCi8qKgogKiBSZXR1cm5zIGB0cnVlYCBpZiBhbiBvYmplY3QgaXMgYSByZWdleDsgYGZhbHNlYCBpZiBpdCBpc24ndC4gVGhpcyB3b3JrcyBjb3JyZWN0bHkgZm9yIHJlZ2V4ZXMKICogY3JlYXRlZCBpbiBhbm90aGVyIGZyYW1lLCB3aGVuIGBpbnN0YW5jZW9mYCBhbmQgYGNvbnN0cnVjdG9yYCBjaGVja3Mgd291bGQgZmFpbC4KICogQG1lbWJlck9mIFhSZWdFeHAKICogQHBhcmFtIHsqfSB2YWx1ZSBPYmplY3QgdG8gY2hlY2suCiAqIEByZXR1cm5zIHtCb29sZWFufSBXaGV0aGVyIHRoZSBvYmplY3QgaXMgYSBgUmVnRXhwYCBvYmplY3QuCiAqIEBleGFtcGxlCiAqCiAqIFhSZWdFeHAuaXNSZWdFeHAoJ3N0cmluZycpOyAvLyAtPiBmYWxzZQogKiBYUmVnRXhwLmlzUmVnRXhwKC9yZWdleC9pKTsgLy8gLT4gdHJ1ZQogKiBYUmVnRXhwLmlzUmVnRXhwKFJlZ0V4cCgnXicsICdtJykpOyAvLyAtPiB0cnVlCiAqIFhSZWdFeHAuaXNSZWdFeHAoWFJlZ0V4cCgnKD9zKS4nKSk7IC8vIC0+IHRydWUKICovCiAgICBzZWxmLmlzUmVnRXhwID0gZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGlzVHlwZSh2YWx1ZSwgInJlZ2V4cCIpOwogICAgfTsKCi8qKgogKiBSZXRyaWV2ZXMgdGhlIG1hdGNoZXMgZnJvbSBzZWFyY2hpbmcgYSBzdHJpbmcgdXNpbmcgYSBjaGFpbiBvZiByZWdleGVzIHRoYXQgc3VjY2Vzc2l2ZWx5IHNlYXJjaAogKiB3aXRoaW4gcHJldmlvdXMgbWF0Y2hlcy4gVGhlIHByb3ZpZGVkIGBjaGFpbmAgYXJyYXkgY2FuIGNvbnRhaW4gcmVnZXhlcyBhbmQgb2JqZWN0cyB3aXRoIGByZWdleGAKICogYW5kIGBiYWNrcmVmYCBwcm9wZXJ0aWVzLiBXaGVuIGEgYmFja3JlZmVyZW5jZSBpcyBzcGVjaWZpZWQsIHRoZSBuYW1lZCBvciBudW1iZXJlZCBiYWNrcmVmZXJlbmNlCiAqIGlzIHBhc3NlZCBmb3J3YXJkIHRvIHRoZSBuZXh0IHJlZ2V4IG9yIHJldHVybmVkLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBzZWFyY2guCiAqIEBwYXJhbSB7QXJyYXl9IGNoYWluIFJlZ2V4ZXMgdGhhdCBlYWNoIHNlYXJjaCBmb3IgbWF0Y2hlcyB3aXRoaW4gcHJlY2VkaW5nIHJlc3VsdHMuCiAqIEByZXR1cm5zIHtBcnJheX0gTWF0Y2hlcyBieSB0aGUgbGFzdCByZWdleCBpbiB0aGUgY2hhaW4sIG9yIGFuIGVtcHR5IGFycmF5LgogKiBAZXhhbXBsZQogKgogKiAvLyBCYXNpYyB1c2FnZTsgbWF0Y2hlcyBudW1iZXJzIHdpdGhpbiA8Yj4gdGFncwogKiBYUmVnRXhwLm1hdGNoQ2hhaW4oJzEgPGI+MjwvYj4gMyA8Yj40IGEgNTY8L2I+JywgWwogKiAgIFhSZWdFeHAoJyg/aXMpPGI+Lio/PC9iPicpLAogKiAgIC9cZCsvCiAqIF0pOwogKiAvLyAtPiBbJzInLCAnNCcsICc1NiddCiAqCiAqIC8vIFBhc3NpbmcgZm9yd2FyZCBhbmQgcmV0dXJuaW5nIHNwZWNpZmljIGJhY2tyZWZlcmVuY2VzCiAqIGh0bWwgPSAnPGEgaHJlZj0iaHR0cDovL3hyZWdleHAuY29tL2FwaS8iPlhSZWdFeHA8L2E+XAogKiAgICAgICAgIDxhIGhyZWY9Imh0dHA6Ly93d3cuZ29vZ2xlLmNvbS8iPkdvb2dsZTwvYT4nOwogKiBYUmVnRXhwLm1hdGNoQ2hhaW4oaHRtbCwgWwogKiAgIHtyZWdleDogLzxhIGhyZWY9IihbXiJdKykiPi9pLCBiYWNrcmVmOiAxfSwKICogICB7cmVnZXg6IFhSZWdFeHAoJyg/aSleaHR0cHM/Oi8vKD88ZG9tYWluPlteLz8jXSspJyksIGJhY2tyZWY6ICdkb21haW4nfQogKiBdKTsKICogLy8gLT4gWyd4cmVnZXhwLmNvbScsICd3d3cuZ29vZ2xlLmNvbSddCiAqLwogICAgc2VsZi5tYXRjaENoYWluID0gZnVuY3Rpb24gKHN0ciwgY2hhaW4pIHsKICAgICAgICByZXR1cm4gKGZ1bmN0aW9uIHJlY3Vyc2VDaGFpbih2YWx1ZXMsIGxldmVsKSB7CiAgICAgICAgICAgIHZhciBpdGVtID0gY2hhaW5bbGV2ZWxdLnJlZ2V4ID8gY2hhaW5bbGV2ZWxdIDoge3JlZ2V4OiBjaGFpbltsZXZlbF19LAogICAgICAgICAgICAgICAgbWF0Y2hlcyA9IFtdLAogICAgICAgICAgICAgICAgYWRkTWF0Y2ggPSBmdW5jdGlvbiAobWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICBtYXRjaGVzLnB1c2goaXRlbS5iYWNrcmVmID8gKG1hdGNoW2l0ZW0uYmFja3JlZl0gfHwgIiIpIDogbWF0Y2hbMF0pOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGk7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIHNlbGYuZm9yRWFjaCh2YWx1ZXNbaV0sIGl0ZW0ucmVnZXgsIGFkZE1hdGNoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gKChsZXZlbCA9PT0gY2hhaW4ubGVuZ3RoIC0gMSkgfHwgIW1hdGNoZXMubGVuZ3RoKSA/CiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlcyA6CiAgICAgICAgICAgICAgICAgICAgcmVjdXJzZUNoYWluKG1hdGNoZXMsIGxldmVsICsgMSk7CiAgICAgICAgfShbc3RyXSwgMCkpOwogICAgfTsKCi8qKgogKiBSZXR1cm5zIGEgbmV3IHN0cmluZyB3aXRoIG9uZSBvciBhbGwgbWF0Y2hlcyBvZiBhIHBhdHRlcm4gcmVwbGFjZWQuIFRoZSBwYXR0ZXJuIGNhbiBiZSBhIHN0cmluZwogKiBvciByZWdleCwgYW5kIHRoZSByZXBsYWNlbWVudCBjYW4gYmUgYSBzdHJpbmcgb3IgYSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgZm9yIGVhY2ggbWF0Y2guIFRvCiAqIHBlcmZvcm0gYSBnbG9iYWwgc2VhcmNoIGFuZCByZXBsYWNlLCB1c2UgdGhlIG9wdGlvbmFsIGBzY29wZWAgYXJndW1lbnQgb3IgaW5jbHVkZSBmbGFnIGBnYCBpZgogKiB1c2luZyBhIHJlZ2V4LiBSZXBsYWNlbWVudCBzdHJpbmdzIGNhbiB1c2UgYCR7bn1gIGZvciBuYW1lZCBhbmQgbnVtYmVyZWQgYmFja3JlZmVyZW5jZXMuCiAqIFJlcGxhY2VtZW50IGZ1bmN0aW9ucyBjYW4gdXNlIG5hbWVkIGJhY2tyZWZlcmVuY2VzIHZpYSBgYXJndW1lbnRzWzBdLm5hbWVgLiBBbHNvIGZpeGVzIGJyb3dzZXIKICogYnVncyBjb21wYXJlZCB0byB0aGUgbmF0aXZlIGBTdHJpbmcucHJvdG90eXBlLnJlcGxhY2VgIGFuZCBjYW4gYmUgdXNlZCByZWxpYWJseSBjcm9zcy1icm93c2VyLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBzZWFyY2guCiAqIEBwYXJhbSB7UmVnRXhwfFN0cmluZ30gc2VhcmNoIFNlYXJjaCBwYXR0ZXJuIHRvIGJlIHJlcGxhY2VkLgogKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gcmVwbGFjZW1lbnQgUmVwbGFjZW1lbnQgc3RyaW5nIG9yIGEgZnVuY3Rpb24gaW52b2tlZCB0byBjcmVhdGUgaXQuCiAqICAgUmVwbGFjZW1lbnQgc3RyaW5ncyBjYW4gaW5jbHVkZSBzcGVjaWFsIHJlcGxhY2VtZW50IHN5bnRheDoKICogICAgIDxsaT4kJCAtIEluc2VydHMgYSBsaXRlcmFsICckJy4KICogICAgIDxsaT4kJiwgJDAgLSBJbnNlcnRzIHRoZSBtYXRjaGVkIHN1YnN0cmluZy4KICogICAgIDxsaT4kYCAtIEluc2VydHMgdGhlIHN0cmluZyB0aGF0IHByZWNlZGVzIHRoZSBtYXRjaGVkIHN1YnN0cmluZyAobGVmdCBjb250ZXh0KS4KICogICAgIDxsaT4kJyAtIEluc2VydHMgdGhlIHN0cmluZyB0aGF0IGZvbGxvd3MgdGhlIG1hdGNoZWQgc3Vic3RyaW5nIChyaWdodCBjb250ZXh0KS4KICogICAgIDxsaT4kbiwgJG5uIC0gV2hlcmUgbi9ubiBhcmUgZGlnaXRzIHJlZmVyZW5jaW5nIGFuIGV4aXN0ZW50IGNhcHR1cmluZyBncm91cCwgaW5zZXJ0cwogKiAgICAgICBiYWNrcmVmZXJlbmNlIG4vbm4uCiAqICAgICA8bGk+JHtufSAtIFdoZXJlIG4gaXMgYSBuYW1lIG9yIGFueSBudW1iZXIgb2YgZGlnaXRzIHRoYXQgcmVmZXJlbmNlIGFuIGV4aXN0ZW50IGNhcHR1cmluZwogKiAgICAgICBncm91cCwgaW5zZXJ0cyBiYWNrcmVmZXJlbmNlIG4uCiAqICAgUmVwbGFjZW1lbnQgZnVuY3Rpb25zIGFyZSBpbnZva2VkIHdpdGggdGhyZWUgb3IgbW9yZSBhcmd1bWVudHM6CiAqICAgICA8bGk+VGhlIG1hdGNoZWQgc3Vic3RyaW5nIChjb3JyZXNwb25kcyB0byAkJiBhYm92ZSkuIE5hbWVkIGJhY2tyZWZlcmVuY2VzIGFyZSBhY2Nlc3NpYmxlIGFzCiAqICAgICAgIHByb3BlcnRpZXMgb2YgdGhpcyBmaXJzdCBhcmd1bWVudC4KICogICAgIDxsaT4wLi5uIGFyZ3VtZW50cywgb25lIGZvciBlYWNoIGJhY2tyZWZlcmVuY2UgKGNvcnJlc3BvbmRpbmcgdG8gJDEsICQyLCBldGMuIGFib3ZlKS4KICogICAgIDxsaT5UaGUgemVyby1iYXNlZCBpbmRleCBvZiB0aGUgbWF0Y2ggd2l0aGluIHRoZSB0b3RhbCBzZWFyY2ggc3RyaW5nLgogKiAgICAgPGxpPlRoZSB0b3RhbCBzdHJpbmcgYmVpbmcgc2VhcmNoZWQuCiAqIEBwYXJhbSB7U3RyaW5nfSBbc2NvcGU9J29uZSddIFVzZSAnb25lJyB0byByZXBsYWNlIHRoZSBmaXJzdCBtYXRjaCBvbmx5LCBvciAnYWxsJy4gSWYgbm90CiAqICAgZXhwbGljaXRseSBzcGVjaWZpZWQgYW5kIHVzaW5nIGEgcmVnZXggd2l0aCBmbGFnIGBnYCwgYHNjb3BlYCBpcyAnYWxsJy4KICogQHJldHVybnMge1N0cmluZ30gTmV3IHN0cmluZyB3aXRoIG9uZSBvciBhbGwgbWF0Y2hlcyByZXBsYWNlZC4KICogQGV4YW1wbGUKICoKICogLy8gUmVnZXggc2VhcmNoLCB1c2luZyBuYW1lZCBiYWNrcmVmZXJlbmNlcyBpbiByZXBsYWNlbWVudCBzdHJpbmcKICogdmFyIG5hbWUgPSBYUmVnRXhwKCcoPzxmaXJzdD5cXHcrKSAoPzxsYXN0PlxcdyspJyk7CiAqIFhSZWdFeHAucmVwbGFjZSgnSm9obiBTbWl0aCcsIG5hbWUsICcke2xhc3R9LCAke2ZpcnN0fScpOwogKiAvLyAtPiAnU21pdGgsIEpvaG4nCiAqCiAqIC8vIFJlZ2V4IHNlYXJjaCwgdXNpbmcgbmFtZWQgYmFja3JlZmVyZW5jZXMgaW4gcmVwbGFjZW1lbnQgZnVuY3Rpb24KICogWFJlZ0V4cC5yZXBsYWNlKCdKb2huIFNtaXRoJywgbmFtZSwgZnVuY3Rpb24gKG1hdGNoKSB7CiAqICAgcmV0dXJuIG1hdGNoLmxhc3QgKyAnLCAnICsgbWF0Y2guZmlyc3Q7CiAqIH0pOwogKiAvLyAtPiAnU21pdGgsIEpvaG4nCiAqCiAqIC8vIEdsb2JhbCBzdHJpbmcgc2VhcmNoL3JlcGxhY2VtZW50CiAqIFhSZWdFeHAucmVwbGFjZSgnUmVnRXhwIGJ1aWxkcyBSZWdFeHBzJywgJ1JlZ0V4cCcsICdYUmVnRXhwJywgJ2FsbCcpOwogKiAvLyAtPiAnWFJlZ0V4cCBidWlsZHMgWFJlZ0V4cHMnCiAqLwogICAgc2VsZi5yZXBsYWNlID0gZnVuY3Rpb24gKHN0ciwgc2VhcmNoLCByZXBsYWNlbWVudCwgc2NvcGUpIHsKICAgICAgICB2YXIgaXNSZWdleCA9IHNlbGYuaXNSZWdFeHAoc2VhcmNoKSwKICAgICAgICAgICAgc2VhcmNoMiA9IHNlYXJjaCwKICAgICAgICAgICAgcmVzdWx0OwogICAgICAgIGlmIChpc1JlZ2V4KSB7CiAgICAgICAgICAgIGlmIChzY29wZSA9PT0gdW5kZWYgJiYgc2VhcmNoLmdsb2JhbCkgewogICAgICAgICAgICAgICAgc2NvcGUgPSAiYWxsIjsgLy8gRm9sbG93IGZsYWcgZyB3aGVuIGBzY29wZWAgaXNuJ3QgZXhwbGljaXQKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBOb3RlIHRoYXQgc2luY2UgYSBjb3B5IGlzIHVzZWQsIGBzZWFyY2hgJ3MgYGxhc3RJbmRleGAgaXNuJ3QgdXBkYXRlZCAqZHVyaW5nKiByZXBsYWNlbWVudCBpdGVyYXRpb25zCiAgICAgICAgICAgIHNlYXJjaDIgPSBjb3B5KHNlYXJjaCwgc2NvcGUgPT09ICJhbGwiID8gImciIDogIiIsIHNjb3BlID09PSAiYWxsIiA/ICIiIDogImciKTsKICAgICAgICB9IGVsc2UgaWYgKHNjb3BlID09PSAiYWxsIikgewogICAgICAgICAgICBzZWFyY2gyID0gbmV3IFJlZ0V4cChzZWxmLmVzY2FwZShTdHJpbmcoc2VhcmNoKSksICJnIik7CiAgICAgICAgfQogICAgICAgIHJlc3VsdCA9IGZpeGVkLnJlcGxhY2UuY2FsbChTdHJpbmcoc3RyKSwgc2VhcmNoMiwgcmVwbGFjZW1lbnQpOyAvLyBGaXhlZCBgcmVwbGFjZWAgcmVxdWlyZWQgZm9yIG5hbWVkIGJhY2tyZWZlcmVuY2VzLCBldGMuCiAgICAgICAgaWYgKGlzUmVnZXggJiYgc2VhcmNoLmdsb2JhbCkgewogICAgICAgICAgICBzZWFyY2gubGFzdEluZGV4ID0gMDsgLy8gRml4ZXMgSUUsIFNhZmFyaSBidWcgKGxhc3QgdGVzdGVkIElFIDksIFNhZmFyaSA1LjEpCiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9OwoKLyoqCiAqIFNwbGl0cyBhIHN0cmluZyBpbnRvIGFuIGFycmF5IG9mIHN0cmluZ3MgdXNpbmcgYSByZWdleCBvciBzdHJpbmcgc2VwYXJhdG9yLiBNYXRjaGVzIG9mIHRoZQogKiBzZXBhcmF0b3IgYXJlIG5vdCBpbmNsdWRlZCBpbiB0aGUgcmVzdWx0IGFycmF5LiBIb3dldmVyLCBpZiBgc2VwYXJhdG9yYCBpcyBhIHJlZ2V4IHRoYXQgY29udGFpbnMKICogY2FwdHVyaW5nIGdyb3VwcywgYmFja3JlZmVyZW5jZXMgYXJlIHNwbGljZWQgaW50byB0aGUgcmVzdWx0IGVhY2ggdGltZSBgc2VwYXJhdG9yYCBpcyBtYXRjaGVkLgogKiBGaXhlcyBicm93c2VyIGJ1Z3MgY29tcGFyZWQgdG8gdGhlIG5hdGl2ZSBgU3RyaW5nLnByb3RvdHlwZS5zcGxpdGAgYW5kIGNhbiBiZSB1c2VkIHJlbGlhYmx5CiAqIGNyb3NzLWJyb3dzZXIuCiAqIEBtZW1iZXJPZiBYUmVnRXhwCiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIHNwbGl0LgogKiBAcGFyYW0ge1JlZ0V4cHxTdHJpbmd9IHNlcGFyYXRvciBSZWdleCBvciBzdHJpbmcgdG8gdXNlIGZvciBzZXBhcmF0aW5nIHRoZSBzdHJpbmcuCiAqIEBwYXJhbSB7TnVtYmVyfSBbbGltaXRdIE1heGltdW0gbnVtYmVyIG9mIGl0ZW1zIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3VsdCBhcnJheS4KICogQHJldHVybnMge0FycmF5fSBBcnJheSBvZiBzdWJzdHJpbmdzLgogKiBAZXhhbXBsZQogKgogKiAvLyBCYXNpYyB1c2UKICogWFJlZ0V4cC5zcGxpdCgnYSBiIGMnLCAnICcpOwogKiAvLyAtPiBbJ2EnLCAnYicsICdjJ10KICoKICogLy8gV2l0aCBsaW1pdAogKiBYUmVnRXhwLnNwbGl0KCdhIGIgYycsICcgJywgMik7CiAqIC8vIC0+IFsnYScsICdiJ10KICoKICogLy8gQmFja3JlZmVyZW5jZXMgaW4gcmVzdWx0IGFycmF5CiAqIFhSZWdFeHAuc3BsaXQoJy4ud29yZDEuLicsIC8oW2Etel0rKShcZCspL2kpOwogKiAvLyAtPiBbJy4uJywgJ3dvcmQnLCAnMScsICcuLiddCiAqLwogICAgc2VsZi5zcGxpdCA9IGZ1bmN0aW9uIChzdHIsIHNlcGFyYXRvciwgbGltaXQpIHsKICAgICAgICByZXR1cm4gZml4ZWQuc3BsaXQuY2FsbChzdHIsIHNlcGFyYXRvciwgbGltaXQpOwogICAgfTsKCi8qKgogKiBFeGVjdXRlcyBhIHJlZ2V4IHNlYXJjaCBpbiBhIHNwZWNpZmllZCBzdHJpbmcuIFJldHVybnMgYHRydWVgIG9yIGBmYWxzZWAuIE9wdGlvbmFsIGBwb3NgIGFuZAogKiBgc3RpY2t5YCBhcmd1bWVudHMgc3BlY2lmeSB0aGUgc2VhcmNoIHN0YXJ0IHBvc2l0aW9uLCBhbmQgd2hldGhlciB0aGUgbWF0Y2ggbXVzdCBzdGFydCBhdCB0aGUKICogc3BlY2lmaWVkIHBvc2l0aW9uIG9ubHkuIFRoZSBgbGFzdEluZGV4YCBwcm9wZXJ0eSBvZiB0aGUgcHJvdmlkZWQgcmVnZXggaXMgbm90IHVzZWQsIGJ1dCBpcwogKiB1cGRhdGVkIGZvciBjb21wYXRpYmlsaXR5LiBBbHNvIGZpeGVzIGJyb3dzZXIgYnVncyBjb21wYXJlZCB0byB0aGUgbmF0aXZlCiAqIGBSZWdFeHAucHJvdG90eXBlLnRlc3RgIGFuZCBjYW4gYmUgdXNlZCByZWxpYWJseSBjcm9zcy1icm93c2VyLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBzZWFyY2guCiAqIEBwYXJhbSB7UmVnRXhwfSByZWdleCBSZWdleCB0byBzZWFyY2ggd2l0aC4KICogQHBhcmFtIHtOdW1iZXJ9IFtwb3M9MF0gWmVyby1iYXNlZCBpbmRleCBhdCB3aGljaCB0byBzdGFydCB0aGUgc2VhcmNoLgogKiBAcGFyYW0ge0Jvb2xlYW58U3RyaW5nfSBbc3RpY2t5PWZhbHNlXSBXaGV0aGVyIHRoZSBtYXRjaCBtdXN0IHN0YXJ0IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24KICogICBvbmx5LiBUaGUgc3RyaW5nIGAnc3RpY2t5J2AgaXMgYWNjZXB0ZWQgYXMgYW4gYWx0ZXJuYXRpdmUgdG8gYHRydWVgLgogKiBAcmV0dXJucyB7Qm9vbGVhbn0gV2hldGhlciB0aGUgcmVnZXggbWF0Y2hlZCB0aGUgcHJvdmlkZWQgdmFsdWUuCiAqIEBleGFtcGxlCiAqCiAqIC8vIEJhc2ljIHVzZQogKiBYUmVnRXhwLnRlc3QoJ2FiYycsIC9jLyk7IC8vIC0+IHRydWUKICoKICogLy8gV2l0aCBwb3MgYW5kIHN0aWNreQogKiBYUmVnRXhwLnRlc3QoJ2FiYycsIC9jLywgMCwgJ3N0aWNreScpOyAvLyAtPiBmYWxzZQogKi8KICAgIHNlbGYudGVzdCA9IGZ1bmN0aW9uIChzdHIsIHJlZ2V4LCBwb3MsIHN0aWNreSkgewogICAgICAgIC8vIERvIHRoaXMgdGhlIGVhc3kgd2F5IDotKQogICAgICAgIHJldHVybiAhIXNlbGYuZXhlYyhzdHIsIHJlZ2V4LCBwb3MsIHN0aWNreSk7CiAgICB9OwoKLyoqCiAqIFVuaW5zdGFsbHMgb3B0aW9uYWwgZmVhdHVyZXMgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgb3B0aW9ucy4KICogQG1lbWJlck9mIFhSZWdFeHAKICogQHBhcmFtIHtPYmplY3R8U3RyaW5nfSBvcHRpb25zIE9wdGlvbnMgb2JqZWN0IG9yIHN0cmluZy4KICogQGV4YW1wbGUKICoKICogLy8gV2l0aCBhbiBvcHRpb25zIG9iamVjdAogKiBYUmVnRXhwLnVuaW5zdGFsbCh7CiAqICAgLy8gUmVzdG9yZXMgbmF0aXZlIHJlZ2V4IG1ldGhvZHMKICogICBuYXRpdmVzOiB0cnVlLAogKgogKiAgIC8vIERpc2FibGVzIGFkZGl0aW9uYWwgc3ludGF4IGFuZCBmbGFnIGV4dGVuc2lvbnMKICogICBleHRlbnNpYmlsaXR5OiB0cnVlCiAqIH0pOwogKgogKiAvLyBXaXRoIGFuIG9wdGlvbnMgc3RyaW5nCiAqIFhSZWdFeHAudW5pbnN0YWxsKCduYXRpdmVzIGV4dGVuc2liaWxpdHknKTsKICoKICogLy8gVXNpbmcgYSBzaG9ydGN1dCB0byB1bmluc3RhbGwgYWxsIG9wdGlvbmFsIGZlYXR1cmVzCiAqIFhSZWdFeHAudW5pbnN0YWxsKCdhbGwnKTsKICovCiAgICBzZWxmLnVuaW5zdGFsbCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7CiAgICAgICAgb3B0aW9ucyA9IHByZXBhcmVPcHRpb25zKG9wdGlvbnMpOwogICAgICAgIGlmIChmZWF0dXJlcy5uYXRpdmVzICYmIG9wdGlvbnMubmF0aXZlcykgewogICAgICAgICAgICBzZXROYXRpdmVzKGZhbHNlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZlYXR1cmVzLmV4dGVuc2liaWxpdHkgJiYgb3B0aW9ucy5leHRlbnNpYmlsaXR5KSB7CiAgICAgICAgICAgIHNldEV4dGVuc2liaWxpdHkoZmFsc2UpOwogICAgICAgIH0KICAgIH07CgovKioKICogUmV0dXJucyBhbiBYUmVnRXhwIG9iamVjdCB0aGF0IGlzIHRoZSB1bmlvbiBvZiB0aGUgZ2l2ZW4gcGF0dGVybnMuIFBhdHRlcm5zIGNhbiBiZSBwcm92aWRlZCBhcwogKiByZWdleCBvYmplY3RzIG9yIHN0cmluZ3MuIE1ldGFjaGFyYWN0ZXJzIGFyZSBlc2NhcGVkIGluIHBhdHRlcm5zIHByb3ZpZGVkIGFzIHN0cmluZ3MuCiAqIEJhY2tyZWZlcmVuY2VzIGluIHByb3ZpZGVkIHJlZ2V4IG9iamVjdHMgYXJlIGF1dG9tYXRpY2FsbHkgcmVudW1iZXJlZCB0byB3b3JrIGNvcnJlY3RseS4gTmF0aXZlCiAqIGZsYWdzIHVzZWQgYnkgcHJvdmlkZWQgcmVnZXhlcyBhcmUgaWdub3JlZCBpbiBmYXZvciBvZiB0aGUgYGZsYWdzYCBhcmd1bWVudC4KICogQG1lbWJlck9mIFhSZWdFeHAKICogQHBhcmFtIHtBcnJheX0gcGF0dGVybnMgUmVnZXhlcyBhbmQgc3RyaW5ncyB0byBjb21iaW5lLgogKiBAcGFyYW0ge1N0cmluZ30gW2ZsYWdzXSBBbnkgY29tYmluYXRpb24gb2YgWFJlZ0V4cCBmbGFncy4KICogQHJldHVybnMge1JlZ0V4cH0gVW5pb24gb2YgdGhlIHByb3ZpZGVkIHJlZ2V4ZXMgYW5kIHN0cmluZ3MuCiAqIEBleGFtcGxlCiAqCiAqIFhSZWdFeHAudW5pb24oWydhK2IqYycsIC8oZG9ncylcMS8sIC8oY2F0cylcMS9dLCAnaScpOwogKiAvLyAtPiAvYVwrYlwqY3woZG9ncylcMXwoY2F0cylcMi9pCiAqCiAqIFhSZWdFeHAudW5pb24oW1hSZWdFeHAoJyg/PHBldD5kb2dzKVxcazxwZXQ+JyksIFhSZWdFeHAoJyg/PHBldD5jYXRzKVxcazxwZXQ+JyldKTsKICogLy8gLT4gWFJlZ0V4cCgnKD88cGV0PmRvZ3MpXFxrPHBldD58KD88cGV0PmNhdHMpXFxrPHBldD4nKQogKi8KICAgIHNlbGYudW5pb24gPSBmdW5jdGlvbiAocGF0dGVybnMsIGZsYWdzKSB7CiAgICAgICAgdmFyIHBhcnRzID0gLyhcKCkoPyFcPyl8XFwoWzEtOV1cZCopfFxcW1xzXFNdfFxbKD86W15cXFxdXXxcXFtcc1xTXSkqXS9nLAogICAgICAgICAgICBudW1DYXB0dXJlcyA9IDAsCiAgICAgICAgICAgIG51bVByaW9yQ2FwdHVyZXMsCiAgICAgICAgICAgIGNhcHR1cmVOYW1lcywKICAgICAgICAgICAgcmV3cml0ZSA9IGZ1bmN0aW9uIChtYXRjaCwgcGFyZW4sIGJhY2tyZWYpIHsKICAgICAgICAgICAgICAgIHZhciBuYW1lID0gY2FwdHVyZU5hbWVzW251bUNhcHR1cmVzIC0gbnVtUHJpb3JDYXB0dXJlc107CiAgICAgICAgICAgICAgICBpZiAocGFyZW4pIHsgLy8gQ2FwdHVyaW5nIGdyb3VwCiAgICAgICAgICAgICAgICAgICAgKytudW1DYXB0dXJlczsKICAgICAgICAgICAgICAgICAgICBpZiAobmFtZSkgeyAvLyBJZiB0aGUgY3VycmVudCBjYXB0dXJlIGhhcyBhIG5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICIoPzwiICsgbmFtZSArICI+IjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJhY2tyZWYpIHsgLy8gQmFja3JlZmVyZW5jZQogICAgICAgICAgICAgICAgICAgIHJldHVybiAiXFwiICsgKCtiYWNrcmVmICsgbnVtUHJpb3JDYXB0dXJlcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2g7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIG91dHB1dCA9IFtdLAogICAgICAgICAgICBwYXR0ZXJuLAogICAgICAgICAgICBpOwogICAgICAgIGlmICghKGlzVHlwZShwYXR0ZXJucywgImFycmF5IikgJiYgcGF0dGVybnMubGVuZ3RoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCJwYXR0ZXJucyBtdXN0IGJlIGEgbm9uZW1wdHkgYXJyYXkiKTsKICAgICAgICB9CiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBhdHRlcm5zLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuc1tpXTsKICAgICAgICAgICAgaWYgKHNlbGYuaXNSZWdFeHAocGF0dGVybikpIHsKICAgICAgICAgICAgICAgIG51bVByaW9yQ2FwdHVyZXMgPSBudW1DYXB0dXJlczsKICAgICAgICAgICAgICAgIGNhcHR1cmVOYW1lcyA9IChwYXR0ZXJuLnhyZWdleHAgJiYgcGF0dGVybi54cmVnZXhwLmNhcHR1cmVOYW1lcykgfHwgW107CiAgICAgICAgICAgICAgICAvLyBSZXdyaXRlIGJhY2tyZWZlcmVuY2VzLiBQYXNzaW5nIHRvIFhSZWdFeHAgZGllcyBvbiBvY3RhbHMgYW5kIGVuc3VyZXMgcGF0dGVybnMKICAgICAgICAgICAgICAgIC8vIGFyZSBpbmRlcGVuZGVudGx5IHZhbGlkOyBoZWxwcyBrZWVwIHRoaXMgc2ltcGxlLiBOYW1lZCBjYXB0dXJlcyBhcmUgcHV0IGJhY2sKICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKHNlbGYocGF0dGVybi5zb3VyY2UpLnNvdXJjZS5yZXBsYWNlKHBhcnRzLCByZXdyaXRlKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBvdXRwdXQucHVzaChzZWxmLmVzY2FwZShwYXR0ZXJuKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNlbGYob3V0cHV0LmpvaW4oInwiKSwgZmxhZ3MpOwogICAgfTsKCi8qKgogKiBUaGUgWFJlZ0V4cCB2ZXJzaW9uIG51bWJlci4KICogQHN0YXRpYwogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAdHlwZSBTdHJpbmcKICovCiAgICBzZWxmLnZlcnNpb24gPSAiMi4wLjAiOwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiAgRml4ZWQvZXh0ZW5kZWQgbmF0aXZlIG1ldGhvZHMKICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKLyoqCiAqIEFkZHMgbmFtZWQgY2FwdHVyZSBzdXBwb3J0ICh3aXRoIGJhY2tyZWZlcmVuY2VzIHJldHVybmVkIGFzIGByZXN1bHQubmFtZWApLCBhbmQgZml4ZXMgYnJvd3NlcgogKiBidWdzIGluIHRoZSBuYXRpdmUgYFJlZ0V4cC5wcm90b3R5cGUuZXhlY2AuIENhbGxpbmcgYFhSZWdFeHAuaW5zdGFsbCgnbmF0aXZlcycpYCB1c2VzIHRoaXMgdG8KICogb3ZlcnJpZGUgdGhlIG5hdGl2ZSBtZXRob2QuIFVzZSB2aWEgYFhSZWdFeHAuZXhlY2Agd2l0aG91dCBvdmVycmlkaW5nIG5hdGl2ZXMuCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIHNlYXJjaC4KICogQHJldHVybnMge0FycmF5fSBNYXRjaCBhcnJheSB3aXRoIG5hbWVkIGJhY2tyZWZlcmVuY2UgcHJvcGVydGllcywgb3IgbnVsbC4KICovCiAgICBmaXhlZC5leGVjID0gZnVuY3Rpb24gKHN0cikgewogICAgICAgIHZhciBtYXRjaCwgbmFtZSwgcjIsIG9yaWdMYXN0SW5kZXgsIGk7CiAgICAgICAgaWYgKCF0aGlzLmdsb2JhbCkgewogICAgICAgICAgICBvcmlnTGFzdEluZGV4ID0gdGhpcy5sYXN0SW5kZXg7CiAgICAgICAgfQogICAgICAgIG1hdGNoID0gbmF0aXYuZXhlYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIGlmIChtYXRjaCkgewogICAgICAgICAgICAvLyBGaXggYnJvd3NlcnMgd2hvc2UgYGV4ZWNgIG1ldGhvZHMgZG9uJ3QgY29uc2lzdGVudGx5IHJldHVybiBgdW5kZWZpbmVkYCBmb3IKICAgICAgICAgICAgLy8gbm9ucGFydGljaXBhdGluZyBjYXB0dXJpbmcgZ3JvdXBzCiAgICAgICAgICAgIGlmICghY29tcGxpYW50RXhlY05wY2cgJiYgbWF0Y2gubGVuZ3RoID4gMSAmJiBsYXN0SW5kZXhPZihtYXRjaCwgIiIpID4gLTEpIHsKICAgICAgICAgICAgICAgIHIyID0gbmV3IFJlZ0V4cCh0aGlzLnNvdXJjZSwgbmF0aXYucmVwbGFjZS5jYWxsKGdldE5hdGl2ZUZsYWdzKHRoaXMpLCAiZyIsICIiKSk7CiAgICAgICAgICAgICAgICAvLyBVc2luZyBgc3RyLnNsaWNlKG1hdGNoLmluZGV4KWAgcmF0aGVyIHRoYW4gYG1hdGNoWzBdYCBpbiBjYXNlIGxvb2thaGVhZCBhbGxvd2VkCiAgICAgICAgICAgICAgICAvLyBtYXRjaGluZyBkdWUgdG8gY2hhcmFjdGVycyBvdXRzaWRlIHRoZSBtYXRjaAogICAgICAgICAgICAgICAgbmF0aXYucmVwbGFjZS5jYWxsKFN0cmluZyhzdHIpLnNsaWNlKG1hdGNoLmluZGV4KSwgcjIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaTsKICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aCAtIDI7ICsraSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzW2ldID09PSB1bmRlZikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hbaV0gPSB1bmRlZjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEF0dGFjaCBuYW1lZCBjYXB0dXJlIHByb3BlcnRpZXMKICAgICAgICAgICAgaWYgKHRoaXMueHJlZ2V4cCAmJiB0aGlzLnhyZWdleHAuY2FwdHVyZU5hbWVzKSB7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgbWF0Y2gubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICBuYW1lID0gdGhpcy54cmVnZXhwLmNhcHR1cmVOYW1lc1tpIC0gMV07CiAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hbbmFtZV0gPSBtYXRjaFtpXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gRml4IGJyb3dzZXJzIHRoYXQgaW5jcmVtZW50IGBsYXN0SW5kZXhgIGFmdGVyIHplcm8tbGVuZ3RoIG1hdGNoZXMKICAgICAgICAgICAgaWYgKHRoaXMuZ2xvYmFsICYmICFtYXRjaFswXS5sZW5ndGggJiYgKHRoaXMubGFzdEluZGV4ID4gbWF0Y2guaW5kZXgpKSB7CiAgICAgICAgICAgICAgICB0aGlzLmxhc3RJbmRleCA9IG1hdGNoLmluZGV4OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICghdGhpcy5nbG9iYWwpIHsKICAgICAgICAgICAgdGhpcy5sYXN0SW5kZXggPSBvcmlnTGFzdEluZGV4OyAvLyBGaXhlcyBJRSwgT3BlcmEgYnVnIChsYXN0IHRlc3RlZCBJRSA5LCBPcGVyYSAxMS42KQogICAgICAgIH0KICAgICAgICByZXR1cm4gbWF0Y2g7CiAgICB9OwoKLyoqCiAqIEZpeGVzIGJyb3dzZXIgYnVncyBpbiB0aGUgbmF0aXZlIGBSZWdFeHAucHJvdG90eXBlLnRlc3RgLiBDYWxsaW5nIGBYUmVnRXhwLmluc3RhbGwoJ25hdGl2ZXMnKWAKICogdXNlcyB0aGlzIHRvIG92ZXJyaWRlIHRoZSBuYXRpdmUgbWV0aG9kLgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBzZWFyY2guCiAqIEByZXR1cm5zIHtCb29sZWFufSBXaGV0aGVyIHRoZSByZWdleCBtYXRjaGVkIHRoZSBwcm92aWRlZCB2YWx1ZS4KICovCiAgICBmaXhlZC50ZXN0ID0gZnVuY3Rpb24gKHN0cikgewogICAgICAgIC8vIERvIHRoaXMgdGhlIGVhc3kgd2F5IDotKQogICAgICAgIHJldHVybiAhIWZpeGVkLmV4ZWMuY2FsbCh0aGlzLCBzdHIpOwogICAgfTsKCi8qKgogKiBBZGRzIG5hbWVkIGNhcHR1cmUgc3VwcG9ydCAod2l0aCBiYWNrcmVmZXJlbmNlcyByZXR1cm5lZCBhcyBgcmVzdWx0Lm5hbWVgKSwgYW5kIGZpeGVzIGJyb3dzZXIKICogYnVncyBpbiB0aGUgbmF0aXZlIGBTdHJpbmcucHJvdG90eXBlLm1hdGNoYC4gQ2FsbGluZyBgWFJlZ0V4cC5pbnN0YWxsKCduYXRpdmVzJylgIHVzZXMgdGhpcyB0bwogKiBvdmVycmlkZSB0aGUgbmF0aXZlIG1ldGhvZC4KICogQHByaXZhdGUKICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4IFJlZ2V4IHRvIHNlYXJjaCB3aXRoLgogKiBAcmV0dXJucyB7QXJyYXl9IElmIGByZWdleGAgdXNlcyBmbGFnIGcsIGFuIGFycmF5IG9mIG1hdGNoIHN0cmluZ3Mgb3IgbnVsbC4gV2l0aG91dCBmbGFnIGcsIHRoZQogKiAgIHJlc3VsdCBvZiBjYWxsaW5nIGByZWdleC5leGVjKHRoaXMpYC4KICovCiAgICBmaXhlZC5tYXRjaCA9IGZ1bmN0aW9uIChyZWdleCkgewogICAgICAgIGlmICghc2VsZi5pc1JlZ0V4cChyZWdleCkpIHsKICAgICAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKHJlZ2V4KTsgLy8gVXNlIG5hdGl2ZSBgUmVnRXhwYAogICAgICAgIH0gZWxzZSBpZiAocmVnZXguZ2xvYmFsKSB7CiAgICAgICAgICAgIHZhciByZXN1bHQgPSBuYXRpdi5tYXRjaC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICByZWdleC5sYXN0SW5kZXggPSAwOyAvLyBGaXhlcyBJRSBidWcKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZpeGVkLmV4ZWMuY2FsbChyZWdleCwgdGhpcyk7CiAgICB9OwoKLyoqCiAqIEFkZHMgc3VwcG9ydCBmb3IgYCR7bn1gIHRva2VucyBmb3IgbmFtZWQgYW5kIG51bWJlcmVkIGJhY2tyZWZlcmVuY2VzIGluIHJlcGxhY2VtZW50IHRleHQsIGFuZAogKiBwcm92aWRlcyBuYW1lZCBiYWNrcmVmZXJlbmNlcyB0byByZXBsYWNlbWVudCBmdW5jdGlvbnMgYXMgYGFyZ3VtZW50c1swXS5uYW1lYC4gQWxzbyBmaXhlcwogKiBicm93c2VyIGJ1Z3MgaW4gcmVwbGFjZW1lbnQgdGV4dCBzeW50YXggd2hlbiBwZXJmb3JtaW5nIGEgcmVwbGFjZW1lbnQgdXNpbmcgYSBub25yZWdleCBzZWFyY2gKICogdmFsdWUsIGFuZCB0aGUgdmFsdWUgb2YgYSByZXBsYWNlbWVudCByZWdleCdzIGBsYXN0SW5kZXhgIHByb3BlcnR5IGR1cmluZyByZXBsYWNlbWVudCBpdGVyYXRpb25zCiAqIGFuZCB1cG9uIGNvbXBsZXRpb24uIE5vdGUgdGhhdCB0aGlzIGRvZXNuJ3Qgc3VwcG9ydCBTcGlkZXJNb25rZXkncyBwcm9wcmlldGFyeSB0aGlyZCAoYGZsYWdzYCkKICogYXJndW1lbnQuIENhbGxpbmcgYFhSZWdFeHAuaW5zdGFsbCgnbmF0aXZlcycpYCB1c2VzIHRoaXMgdG8gb3ZlcnJpZGUgdGhlIG5hdGl2ZSBtZXRob2QuIFVzZSB2aWEKICogYFhSZWdFeHAucmVwbGFjZWAgd2l0aG91dCBvdmVycmlkaW5nIG5hdGl2ZXMuCiAqIEBwcml2YXRlCiAqIEBwYXJhbSB7UmVnRXhwfFN0cmluZ30gc2VhcmNoIFNlYXJjaCBwYXR0ZXJuIHRvIGJlIHJlcGxhY2VkLgogKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gcmVwbGFjZW1lbnQgUmVwbGFjZW1lbnQgc3RyaW5nIG9yIGEgZnVuY3Rpb24gaW52b2tlZCB0byBjcmVhdGUgaXQuCiAqIEByZXR1cm5zIHtTdHJpbmd9IE5ldyBzdHJpbmcgd2l0aCBvbmUgb3IgYWxsIG1hdGNoZXMgcmVwbGFjZWQuCiAqLwogICAgZml4ZWQucmVwbGFjZSA9IGZ1bmN0aW9uIChzZWFyY2gsIHJlcGxhY2VtZW50KSB7CiAgICAgICAgdmFyIGlzUmVnZXggPSBzZWxmLmlzUmVnRXhwKHNlYXJjaCksIGNhcHR1cmVOYW1lcywgcmVzdWx0LCBzdHIsIG9yaWdMYXN0SW5kZXg7CiAgICAgICAgaWYgKGlzUmVnZXgpIHsKICAgICAgICAgICAgaWYgKHNlYXJjaC54cmVnZXhwKSB7CiAgICAgICAgICAgICAgICBjYXB0dXJlTmFtZXMgPSBzZWFyY2gueHJlZ2V4cC5jYXB0dXJlTmFtZXM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFzZWFyY2guZ2xvYmFsKSB7CiAgICAgICAgICAgICAgICBvcmlnTGFzdEluZGV4ID0gc2VhcmNoLmxhc3RJbmRleDsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNlYXJjaCArPSAiIjsKICAgICAgICB9CiAgICAgICAgaWYgKGlzVHlwZShyZXBsYWNlbWVudCwgImZ1bmN0aW9uIikpIHsKICAgICAgICAgICAgcmVzdWx0ID0gbmF0aXYucmVwbGFjZS5jYWxsKFN0cmluZyh0aGlzKSwgc2VhcmNoLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cywgaTsKICAgICAgICAgICAgICAgIGlmIChjYXB0dXJlTmFtZXMpIHsKICAgICAgICAgICAgICAgICAgICAvLyBDaGFuZ2UgdGhlIGBhcmd1bWVudHNbMF1gIHN0cmluZyBwcmltaXRpdmUgdG8gYSBgU3RyaW5nYCBvYmplY3QgdGhhdCBjYW4gc3RvcmUgcHJvcGVydGllcwogICAgICAgICAgICAgICAgICAgIGFyZ3NbMF0gPSBuZXcgU3RyaW5nKGFyZ3NbMF0pOwogICAgICAgICAgICAgICAgICAgIC8vIFN0b3JlIG5hbWVkIGJhY2tyZWZlcmVuY2VzIG9uIHRoZSBmaXJzdCBhcmd1bWVudAogICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjYXB0dXJlTmFtZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNhcHR1cmVOYW1lc1tpXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1swXVtjYXB0dXJlTmFtZXNbaV1dID0gYXJnc1tpICsgMV07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgYGxhc3RJbmRleGAgYmVmb3JlIGNhbGxpbmcgYHJlcGxhY2VtZW50YC4KICAgICAgICAgICAgICAgIC8vIEZpeGVzIElFLCBDaHJvbWUsIEZpcmVmb3gsIFNhZmFyaSBidWcgKGxhc3QgdGVzdGVkIElFIDksIENocm9tZSAxNywgRmlyZWZveCAxMSwgU2FmYXJpIDUuMSkKICAgICAgICAgICAgICAgIGlmIChpc1JlZ2V4ICYmIHNlYXJjaC5nbG9iYWwpIHsKICAgICAgICAgICAgICAgICAgICBzZWFyY2gubGFzdEluZGV4ID0gYXJnc1thcmdzLmxlbmd0aCAtIDJdICsgYXJnc1swXS5sZW5ndGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gcmVwbGFjZW1lbnQuYXBwbHkobnVsbCwgYXJncyk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN0ciA9IFN0cmluZyh0aGlzKTsgLy8gRW5zdXJlIGBhcmdzW2FyZ3MubGVuZ3RoIC0gMV1gIHdpbGwgYmUgYSBzdHJpbmcgd2hlbiBnaXZlbiBub25zdHJpbmcgYHRoaXNgCiAgICAgICAgICAgIHJlc3VsdCA9IG5hdGl2LnJlcGxhY2UuY2FsbChzdHIsIHNlYXJjaCwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7IC8vIEtlZXAgdGhpcyBmdW5jdGlvbidzIGBhcmd1bWVudHNgIGF2YWlsYWJsZSB0aHJvdWdoIGNsb3N1cmUKICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdi5yZXBsYWNlLmNhbGwoU3RyaW5nKHJlcGxhY2VtZW50KSwgcmVwbGFjZW1lbnRUb2tlbiwgZnVuY3Rpb24gKCQwLCAkMSwgJDIpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbjsKICAgICAgICAgICAgICAgICAgICAvLyBOYW1lZCBvciBudW1iZXJlZCBiYWNrcmVmZXJlbmNlIHdpdGggY3VybHkgYnJhY2tldHMKICAgICAgICAgICAgICAgICAgICBpZiAoJDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogWFJlZ0V4cCBiZWhhdmlvciBmb3IgYCR7bn1gOgogICAgICAgICAgICAgICAgICAgICAgICAgKiAxLiBCYWNrcmVmZXJlbmNlIHRvIG51bWJlcmVkIGNhcHR1cmUsIHdoZXJlIGBuYCBpcyAxKyBkaWdpdHMuIGAwYCwgYDAwYCwgZXRjLiBpcyB0aGUgZW50aXJlIG1hdGNoLgogICAgICAgICAgICAgICAgICAgICAgICAgKiAyLiBCYWNrcmVmZXJlbmNlIHRvIG5hbWVkIGNhcHR1cmUgYG5gLCBpZiBpdCBleGlzdHMgYW5kIGlzIG5vdCBhIG51bWJlciBvdmVycmlkZGVuIGJ5IG51bWJlcmVkIGNhcHR1cmUuCiAgICAgICAgICAgICAgICAgICAgICAgICAqIDMuIE90aGVyd2lzZSwgaXQncyBhbiBlcnJvci4KICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgIG4gPSArJDE7IC8vIFR5cGUtY29udmVydDsgZHJvcCBsZWFkaW5nIHplcm9zCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuIDw9IGFyZ3MubGVuZ3RoIC0gMykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFyZ3Nbbl0gfHwgIiI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgbiA9IGNhcHR1cmVOYW1lcyA/IGxhc3RJbmRleE9mKGNhcHR1cmVOYW1lcywgJDEpIDogLTE7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCJiYWNrcmVmZXJlbmNlIHRvIHVuZGVmaW5lZCBncm91cCAiICsgJDApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhcmdzW24gKyAxXSB8fCAiIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gRWxzZSwgc3BlY2lhbCB2YXJpYWJsZSBvciBudW1iZXJlZCBiYWNrcmVmZXJlbmNlICh3aXRob3V0IGN1cmx5IGJyYWNrZXRzKQogICAgICAgICAgICAgICAgICAgIGlmICgkMiA9PT0gIiQiKSByZXR1cm4gIiQiOwogICAgICAgICAgICAgICAgICAgIGlmICgkMiA9PT0gIiYiIHx8ICskMiA9PT0gMCkgcmV0dXJuIGFyZ3NbMF07IC8vICQmLCAkMCAobm90IGZvbGxvd2VkIGJ5IDEtOSksICQwMAogICAgICAgICAgICAgICAgICAgIGlmICgkMiA9PT0gImAiKSByZXR1cm4gYXJnc1thcmdzLmxlbmd0aCAtIDFdLnNsaWNlKDAsIGFyZ3NbYXJncy5sZW5ndGggLSAyXSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCQyID09PSAiJyIpIHJldHVybiBhcmdzW2FyZ3MubGVuZ3RoIC0gMV0uc2xpY2UoYXJnc1thcmdzLmxlbmd0aCAtIDJdICsgYXJnc1swXS5sZW5ndGgpOwogICAgICAgICAgICAgICAgICAgIC8vIEVsc2UsIG51bWJlcmVkIGJhY2tyZWZlcmVuY2UgKHdpdGhvdXQgY3VybHkgYnJhY2tldHMpCiAgICAgICAgICAgICAgICAgICAgJDIgPSArJDI7IC8vIFR5cGUtY29udmVydDsgZHJvcCBsZWFkaW5nIHplcm8KICAgICAgICAgICAgICAgICAgICAvKiBYUmVnRXhwIGJlaGF2aW9yOgogICAgICAgICAgICAgICAgICAgICAqIC0gQmFja3JlZmVyZW5jZXMgd2l0aG91dCBjdXJseSBicmFja2V0cyBlbmQgYWZ0ZXIgMSBvciAyIGRpZ2l0cy4gVXNlIGAkey4ufWAgZm9yIG1vcmUgZGlnaXRzLgogICAgICAgICAgICAgICAgICAgICAqIC0gYCQxYCBpcyBhbiBlcnJvciBpZiB0aGVyZSBhcmUgbm8gY2FwdHVyaW5nIGdyb3Vwcy4KICAgICAgICAgICAgICAgICAgICAgKiAtIGAkMTBgIGlzIGFuIGVycm9yIGlmIHRoZXJlIGFyZSBsZXNzIHRoYW4gMTAgY2FwdHVyaW5nIGdyb3Vwcy4gVXNlIGAkezF9MGAgaW5zdGVhZC4KICAgICAgICAgICAgICAgICAgICAgKiAtIGAkMDFgIGlzIGVxdWl2YWxlbnQgdG8gYCQxYCBpZiBhIGNhcHR1cmluZyBncm91cCBleGlzdHMsIG90aGVyd2lzZSBpdCdzIGFuIGVycm9yLgogICAgICAgICAgICAgICAgICAgICAqIC0gYCQwYCAobm90IGZvbGxvd2VkIGJ5IDEtOSksIGAkMDBgLCBhbmQgYCQmYCBhcmUgdGhlIGVudGlyZSBtYXRjaC4KICAgICAgICAgICAgICAgICAgICAgKiBOYXRpdmUgYmVoYXZpb3IsIGZvciBjb21wYXJpc29uOgogICAgICAgICAgICAgICAgICAgICAqIC0gQmFja3JlZmVyZW5jZXMgZW5kIGFmdGVyIDEgb3IgMiBkaWdpdHMuIENhbm5vdCB1c2UgYmFja3JlZmVyZW5jZSB0byBjYXB0dXJpbmcgZ3JvdXAgMTAwKy4KICAgICAgICAgICAgICAgICAgICAgKiAtIGAkMWAgaXMgYSBsaXRlcmFsIGAkMWAgaWYgdGhlcmUgYXJlIG5vIGNhcHR1cmluZyBncm91cHMuCiAgICAgICAgICAgICAgICAgICAgICogLSBgJDEwYCBpcyBgJDFgIGZvbGxvd2VkIGJ5IGEgbGl0ZXJhbCBgMGAgaWYgdGhlcmUgYXJlIGxlc3MgdGhhbiAxMCBjYXB0dXJpbmcgZ3JvdXBzLgogICAgICAgICAgICAgICAgICAgICAqIC0gYCQwMWAgaXMgZXF1aXZhbGVudCB0byBgJDFgIGlmIGEgY2FwdHVyaW5nIGdyb3VwIGV4aXN0cywgb3RoZXJ3aXNlIGl0J3MgYSBsaXRlcmFsIGAkMDFgLgogICAgICAgICAgICAgICAgICAgICAqIC0gYCQwYCBpcyBhIGxpdGVyYWwgYCQwYC4gYCQmYCBpcyB0aGUgZW50aXJlIG1hdGNoLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGlmICghaXNOYU4oJDIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgkMiA+IGFyZ3MubGVuZ3RoIC0gMykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCJiYWNrcmVmZXJlbmNlIHRvIHVuZGVmaW5lZCBncm91cCAiICsgJDApOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhcmdzWyQyXSB8fCAiIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCJpbnZhbGlkIHRva2VuICIgKyAkMCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGlmIChpc1JlZ2V4KSB7CiAgICAgICAgICAgIGlmIChzZWFyY2guZ2xvYmFsKSB7CiAgICAgICAgICAgICAgICBzZWFyY2gubGFzdEluZGV4ID0gMDsgLy8gRml4ZXMgSUUsIFNhZmFyaSBidWcgKGxhc3QgdGVzdGVkIElFIDksIFNhZmFyaSA1LjEpCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzZWFyY2gubGFzdEluZGV4ID0gb3JpZ0xhc3RJbmRleDsgLy8gRml4ZXMgSUUsIE9wZXJhIGJ1ZyAobGFzdCB0ZXN0ZWQgSUUgOSwgT3BlcmEgMTEuNikKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfTsKCi8qKgogKiBGaXhlcyBicm93c2VyIGJ1Z3MgaW4gdGhlIG5hdGl2ZSBgU3RyaW5nLnByb3RvdHlwZS5zcGxpdGAuIENhbGxpbmcgYFhSZWdFeHAuaW5zdGFsbCgnbmF0aXZlcycpYAogKiB1c2VzIHRoaXMgdG8gb3ZlcnJpZGUgdGhlIG5hdGl2ZSBtZXRob2QuIFVzZSB2aWEgYFhSZWdFeHAuc3BsaXRgIHdpdGhvdXQgb3ZlcnJpZGluZyBuYXRpdmVzLgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge1JlZ0V4cHxTdHJpbmd9IHNlcGFyYXRvciBSZWdleCBvciBzdHJpbmcgdG8gdXNlIGZvciBzZXBhcmF0aW5nIHRoZSBzdHJpbmcuCiAqIEBwYXJhbSB7TnVtYmVyfSBbbGltaXRdIE1heGltdW0gbnVtYmVyIG9mIGl0ZW1zIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3VsdCBhcnJheS4KICogQHJldHVybnMge0FycmF5fSBBcnJheSBvZiBzdWJzdHJpbmdzLgogKi8KICAgIGZpeGVkLnNwbGl0ID0gZnVuY3Rpb24gKHNlcGFyYXRvciwgbGltaXQpIHsKICAgICAgICBpZiAoIXNlbGYuaXNSZWdFeHAoc2VwYXJhdG9yKSkgewogICAgICAgICAgICByZXR1cm4gbmF0aXYuc3BsaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gdXNlIGZhc3RlciBuYXRpdmUgbWV0aG9kCiAgICAgICAgfQogICAgICAgIHZhciBzdHIgPSBTdHJpbmcodGhpcyksCiAgICAgICAgICAgIG9yaWdMYXN0SW5kZXggPSBzZXBhcmF0b3IubGFzdEluZGV4LAogICAgICAgICAgICBvdXRwdXQgPSBbXSwKICAgICAgICAgICAgbGFzdExhc3RJbmRleCA9IDAsCiAgICAgICAgICAgIGxhc3RMZW5ndGg7CiAgICAgICAgLyogVmFsdWVzIGZvciBgbGltaXRgLCBwZXIgdGhlIHNwZWM6CiAgICAgICAgICogSWYgdW5kZWZpbmVkOiBwb3coMiwzMikgLSAxCiAgICAgICAgICogSWYgMCwgSW5maW5pdHksIG9yIE5hTjogMAogICAgICAgICAqIElmIHBvc2l0aXZlIG51bWJlcjogbGltaXQgPSBmbG9vcihsaW1pdCk7IGlmIChsaW1pdCA+PSBwb3coMiwzMikpIGxpbWl0IC09IHBvdygyLDMyKTsKICAgICAgICAgKiBJZiBuZWdhdGl2ZSBudW1iZXI6IHBvdygyLDMyKSAtIGZsb29yKGFicyhsaW1pdCkpCiAgICAgICAgICogSWYgb3RoZXI6IFR5cGUtY29udmVydCwgdGhlbiB1c2UgdGhlIGFib3ZlIHJ1bGVzCiAgICAgICAgICovCiAgICAgICAgbGltaXQgPSAobGltaXQgPT09IHVuZGVmID8gLTEgOiBsaW1pdCkgPj4+IDA7CiAgICAgICAgc2VsZi5mb3JFYWNoKHN0ciwgc2VwYXJhdG9yLCBmdW5jdGlvbiAobWF0Y2gpIHsKICAgICAgICAgICAgaWYgKChtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aCkgPiBsYXN0TGFzdEluZGV4KSB7IC8vICE9IGBpZiAobWF0Y2hbMF0ubGVuZ3RoKWAKICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKHN0ci5zbGljZShsYXN0TGFzdEluZGV4LCBtYXRjaC5pbmRleCkpOwogICAgICAgICAgICAgICAgaWYgKG1hdGNoLmxlbmd0aCA+IDEgJiYgbWF0Y2guaW5kZXggPCBzdHIubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkob3V0cHV0LCBtYXRjaC5zbGljZSgxKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsYXN0TGVuZ3RoID0gbWF0Y2hbMF0ubGVuZ3RoOwogICAgICAgICAgICAgICAgbGFzdExhc3RJbmRleCA9IG1hdGNoLmluZGV4ICsgbGFzdExlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIGlmIChsYXN0TGFzdEluZGV4ID09PSBzdHIubGVuZ3RoKSB7CiAgICAgICAgICAgIGlmICghbmF0aXYudGVzdC5jYWxsKHNlcGFyYXRvciwgIiIpIHx8IGxhc3RMZW5ndGgpIHsKICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKCIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG91dHB1dC5wdXNoKHN0ci5zbGljZShsYXN0TGFzdEluZGV4KSk7CiAgICAgICAgfQogICAgICAgIHNlcGFyYXRvci5sYXN0SW5kZXggPSBvcmlnTGFzdEluZGV4OwogICAgICAgIHJldHVybiBvdXRwdXQubGVuZ3RoID4gbGltaXQgPyBvdXRwdXQuc2xpY2UoMCwgbGltaXQpIDogb3V0cHV0OwogICAgfTsKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogIEJ1aWx0LWluIHRva2VucwogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgovLyBTaG9ydGN1dAogICAgYWRkID0gYWRkVG9rZW4ub247CgovKiBMZXR0ZXIgaWRlbnRpdHkgZXNjYXBlcyB0aGF0IG5hdGl2ZWx5IG1hdGNoIGxpdGVyYWwgY2hhcmFjdGVyczogXHAsIFxQLCBldGMuCiAqIFNob3VsZCBiZSBTeW50YXhFcnJvcnMgYnV0IGFyZSBhbGxvd2VkIGluIHdlYiByZWFsaXR5LiBYUmVnRXhwIG1ha2VzIHRoZW0gZXJyb3JzIGZvciBjcm9zcy0KICogYnJvd3NlciBjb25zaXN0ZW5jeSBhbmQgdG8gcmVzZXJ2ZSB0aGVpciBzeW50YXgsIGJ1dCBsZXRzIHRoZW0gYmUgc3VwZXJzZWRlZCBieSBYUmVnRXhwIGFkZG9ucy4KICovCiAgICBhZGQoL1xcKFtBQkNFLVJUVVZYWVphZWctbW9wcXl6XXxjKD8hW0EtWmEtel0pfHUoPyFbXGRBLUZhLWZdezR9KXx4KD8hW1xkQS1GYS1mXXsyfSkpLywKICAgICAgICBmdW5jdGlvbiAobWF0Y2gsIHNjb3BlKSB7CiAgICAgICAgICAgIC8vIFxCIGlzIGFsbG93ZWQgaW4gZGVmYXVsdCBzY29wZSBvbmx5CiAgICAgICAgICAgIGlmIChtYXRjaFsxXSA9PT0gIkIiICYmIHNjb3BlID09PSBkZWZhdWx0U2NvcGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaFswXTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImludmFsaWQgZXNjYXBlICIgKyBtYXRjaFswXSk7CiAgICAgICAgfSwKICAgICAgICB7c2NvcGU6ICJhbGwifSk7CgovKiBFbXB0eSBjaGFyYWN0ZXIgY2xhc3M6IFtdIG9yIFteXQogKiBGaXhlcyBhIGNyaXRpY2FsIGNyb3NzLWJyb3dzZXIgc3ludGF4IGluY29uc2lzdGVuY3kuIFVubGVzcyB0aGlzIGlzIHN0YW5kYXJkaXplZCAocGVyIHRoZSBzcGVjKSwKICogcmVnZXggc3ludGF4IGNhbid0IGJlIGFjY3VyYXRlbHkgcGFyc2VkIGJlY2F1c2UgY2hhcmFjdGVyIGNsYXNzIGVuZGluZ3MgY2FuJ3QgYmUgZGV0ZXJtaW5lZC4KICovCiAgICBhZGQoL1xbKFxePyldLywKICAgICAgICBmdW5jdGlvbiAobWF0Y2gpIHsKICAgICAgICAgICAgLy8gRm9yIGNyb3NzLWJyb3dzZXIgY29tcGF0aWJpbGl0eSB3aXRoIEVTMywgY29udmVydCBbXSB0byBcYlxCIGFuZCBbXl0gdG8gW1xzXFNdLgogICAgICAgICAgICAvLyAoPyEpIHNob3VsZCB3b3JrIGxpa2UgXGJcQiwgYnV0IGlzIHVucmVsaWFibGUgaW4gRmlyZWZveAogICAgICAgICAgICByZXR1cm4gbWF0Y2hbMV0gPyAiW1xcc1xcU10iIDogIlxcYlxcQiI7CiAgICAgICAgfSk7CgovKiBDb21tZW50IHBhdHRlcm46ICg/IyApCiAqIElubGluZSBjb21tZW50cyBhcmUgYW4gYWx0ZXJuYXRpdmUgdG8gdGhlIGxpbmUgY29tbWVudHMgYWxsb3dlZCBpbiBmcmVlLXNwYWNpbmcgbW9kZSAoZmxhZyB4KS4KICovCiAgICBhZGQoLyg/OlwoXD8jW14pXSpcKSkrLywKICAgICAgICBmdW5jdGlvbiAobWF0Y2gpIHsKICAgICAgICAgICAgLy8gS2VlcCB0b2tlbnMgc2VwYXJhdGVkIHVubGVzcyB0aGUgZm9sbG93aW5nIHRva2VuIGlzIGEgcXVhbnRpZmllcgogICAgICAgICAgICByZXR1cm4gbmF0aXYudGVzdC5jYWxsKHF1YW50aWZpZXIsIG1hdGNoLmlucHV0LnNsaWNlKG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoKSkgPyAiIiA6ICIoPzopIjsKICAgICAgICB9KTsKCi8qIE5hbWVkIGJhY2tyZWZlcmVuY2U6IFxrPG5hbWU+CiAqIEJhY2tyZWZlcmVuY2UgbmFtZXMgY2FuIHVzZSB0aGUgY2hhcmFjdGVycyBBLVosIGEteiwgMC05LCBfLCBhbmQgJCBvbmx5LgogKi8KICAgIGFkZCgvXFxrPChbXHckXSspPi8sCiAgICAgICAgZnVuY3Rpb24gKG1hdGNoKSB7CiAgICAgICAgICAgIHZhciBpbmRleCA9IGlzTmFOKG1hdGNoWzFdKSA/IChsYXN0SW5kZXhPZih0aGlzLmNhcHR1cmVOYW1lcywgbWF0Y2hbMV0pICsgMSkgOiArbWF0Y2hbMV0sCiAgICAgICAgICAgICAgICBlbmRJbmRleCA9IG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoOwogICAgICAgICAgICBpZiAoIWluZGV4IHx8IGluZGV4ID4gdGhpcy5jYXB0dXJlTmFtZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImJhY2tyZWZlcmVuY2UgdG8gdW5kZWZpbmVkIGdyb3VwICIgKyBtYXRjaFswXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gS2VlcCBiYWNrcmVmZXJlbmNlcyBzZXBhcmF0ZSBmcm9tIHN1YnNlcXVlbnQgbGl0ZXJhbCBudW1iZXJzCiAgICAgICAgICAgIHJldHVybiAiXFwiICsgaW5kZXggKyAoCiAgICAgICAgICAgICAgICBlbmRJbmRleCA9PT0gbWF0Y2guaW5wdXQubGVuZ3RoIHx8IGlzTmFOKG1hdGNoLmlucHV0LmNoYXJBdChlbmRJbmRleCkpID8gIiIgOiAiKD86KSIKICAgICAgICAgICAgKTsKICAgICAgICB9KTsKCi8qIFdoaXRlc3BhY2UgYW5kIGxpbmUgY29tbWVudHMsIGluIGZyZWUtc3BhY2luZyBtb2RlIChha2EgZXh0ZW5kZWQgbW9kZSwgZmxhZyB4KSBvbmx5LgogKi8KICAgIGFkZCgvKD86XHMrfCMuKikrLywKICAgICAgICBmdW5jdGlvbiAobWF0Y2gpIHsKICAgICAgICAgICAgLy8gS2VlcCB0b2tlbnMgc2VwYXJhdGVkIHVubGVzcyB0aGUgZm9sbG93aW5nIHRva2VuIGlzIGEgcXVhbnRpZmllcgogICAgICAgICAgICByZXR1cm4gbmF0aXYudGVzdC5jYWxsKHF1YW50aWZpZXIsIG1hdGNoLmlucHV0LnNsaWNlKG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoKSkgPyAiIiA6ICIoPzopIjsKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgdHJpZ2dlcjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaGFzRmxhZygieCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBjdXN0b21GbGFnczogIngiCiAgICAgICAgfSk7CgovKiBEb3QsIGluIGRvdGFsbCBtb2RlIChha2Egc2luZ2xlbGluZSBtb2RlLCBmbGFnIHMpIG9ubHkuCiAqLwogICAgYWRkKC9cLi8sCiAgICAgICAgZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gIltcXHNcXFNdIjsKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgdHJpZ2dlcjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaGFzRmxhZygicyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBjdXN0b21GbGFnczogInMiCiAgICAgICAgfSk7CgovKiBOYW1lZCBjYXB0dXJpbmcgZ3JvdXA7IG1hdGNoIHRoZSBvcGVuaW5nIGRlbGltaXRlciBvbmx5OiAoPzxuYW1lPgogKiBDYXB0dXJlIG5hbWVzIGNhbiB1c2UgdGhlIGNoYXJhY3RlcnMgQS1aLCBhLXosIDAtOSwgXywgYW5kICQgb25seS4gTmFtZXMgY2FuJ3QgYmUgaW50ZWdlcnMuCiAqIFN1cHBvcnRzIFB5dGhvbi1zdHlsZSAoP1A8bmFtZT4gYXMgYW4gYWx0ZXJuYXRlIHN5bnRheCB0byBhdm9pZCBpc3N1ZXMgaW4gcmVjZW50IE9wZXJhICh3aGljaAogKiBuYXRpdmVseSBzdXBwb3J0cyB0aGUgUHl0aG9uLXN0eWxlIHN5bnRheCkuIE90aGVyd2lzZSwgWFJlZ0V4cCBtaWdodCB0cmVhdCBudW1iZXJlZAogKiBiYWNrcmVmZXJlbmNlcyB0byBQeXRob24tc3R5bGUgbmFtZWQgY2FwdHVyZSBhcyBvY3RhbHMuCiAqLwogICAgYWRkKC9cKFw/UD88KFtcdyRdKyk+LywKICAgICAgICBmdW5jdGlvbiAobWF0Y2gpIHsKICAgICAgICAgICAgaWYgKCFpc05hTihtYXRjaFsxXSkpIHsKICAgICAgICAgICAgICAgIC8vIEF2b2lkIGluY29ycmVjdCBsb29rdXBzLCBzaW5jZSBuYW1lZCBiYWNrcmVmZXJlbmNlcyBhcmUgYWRkZWQgdG8gbWF0Y2ggYXJyYXlzCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImNhbid0IHVzZSBpbnRlZ2VyIGFzIGNhcHR1cmUgbmFtZSAiICsgbWF0Y2hbMF0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuY2FwdHVyZU5hbWVzLnB1c2gobWF0Y2hbMV0pOwogICAgICAgICAgICB0aGlzLmhhc05hbWVkQ2FwdHVyZSA9IHRydWU7CiAgICAgICAgICAgIHJldHVybiAiKCI7CiAgICAgICAgfSk7CgovKiBOdW1iZXJlZCBiYWNrcmVmZXJlbmNlIG9yIG9jdGFsLCBwbHVzIGFueSBmb2xsb3dpbmcgZGlnaXRzOiBcMCwgXDExLCBldGMuCiAqIE9jdGFscyBleGNlcHQgXDAgbm90IGZvbGxvd2VkIGJ5IDAtOSBhbmQgYmFja3JlZmVyZW5jZXMgdG8gdW5vcGVuZWQgY2FwdHVyZSBncm91cHMgdGhyb3cgYW4KICogZXJyb3IuIE90aGVyIG1hdGNoZXMgYXJlIHJldHVybmVkIHVuYWx0ZXJlZC4gSUUgPD0gOCBkb2Vzbid0IHN1cHBvcnQgYmFja3JlZmVyZW5jZXMgZ3JlYXRlciB0aGFuCiAqIFw5OSBpbiByZWdleCBzeW50YXguCiAqLwogICAgYWRkKC9cXChcZCspLywKICAgICAgICBmdW5jdGlvbiAobWF0Y2gsIHNjb3BlKSB7CiAgICAgICAgICAgIGlmICghKHNjb3BlID09PSBkZWZhdWx0U2NvcGUgJiYgL15bMS05XS8udGVzdChtYXRjaFsxXSkgJiYgK21hdGNoWzFdIDw9IHRoaXMuY2FwdHVyZU5hbWVzLmxlbmd0aCkgJiYKICAgICAgICAgICAgICAgICAgICBtYXRjaFsxXSAhPT0gIjAiKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImNhbid0IHVzZSBvY3RhbCBlc2NhcGUgb3IgYmFja3JlZmVyZW5jZSB0byB1bmRlZmluZWQgZ3JvdXAgIiArIG1hdGNoWzBdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbWF0Y2hbMF07CiAgICAgICAgfSwKICAgICAgICB7c2NvcGU6ICJhbGwifSk7CgovKiBDYXB0dXJpbmcgZ3JvdXA7IG1hdGNoIHRoZSBvcGVuaW5nIHBhcmVudGhlc2lzIG9ubHkuCiAqIFJlcXVpcmVkIGZvciBzdXBwb3J0IG9mIG5hbWVkIGNhcHR1cmluZyBncm91cHMuIEFsc28gYWRkcyBleHBsaWNpdCBjYXB0dXJlIG1vZGUgKGZsYWcgbikuCiAqLwogICAgYWRkKC9cKCg/IVw/KS8sCiAgICAgICAgZnVuY3Rpb24gKCkgewogICAgICAgICAgICBpZiAodGhpcy5oYXNGbGFnKCJuIikpIHsKICAgICAgICAgICAgICAgIHJldHVybiAiKD86IjsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLmNhcHR1cmVOYW1lcy5wdXNoKG51bGwpOwogICAgICAgICAgICByZXR1cm4gIigiOwogICAgICAgIH0sCiAgICAgICAge2N1c3RvbUZsYWdzOiAibiJ9KTsKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogIEV4cG9zZSBYUmVnRXhwCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCi8vIEZvciBDb21tb25KUyBlbnZpcm9tZW50cwogICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAidW5kZWZpbmVkIikgewogICAgICAgIGV4cG9ydHMuWFJlZ0V4cCA9IHNlbGY7CiAgICB9CgogICAgcmV0dXJuIHNlbGY7Cgp9KCkpOwoKCi8qKioqKiB1bmljb2RlLWJhc2UuanMgKioqKiovCgovKiEKICogWFJlZ0V4cCBVbmljb2RlIEJhc2UgdjEuMC4wCiAqIChjKSAyMDA4LTIwMTIgU3RldmVuIExldml0aGFuIDxodHRwOi8veHJlZ2V4cC5jb20vPgogKiBNSVQgTGljZW5zZQogKiBVc2VzIFVuaWNvZGUgNi4xIDxodHRwOi8vdW5pY29kZS5vcmcvPgogKi8KCi8qKgogKiBBZGRzIHN1cHBvcnQgZm9yIHRoZSBgXHB7TH1gIG9yIGBccHtMZXR0ZXJ9YCBVbmljb2RlIGNhdGVnb3J5LiBBZGRvbiBwYWNrYWdlcyBmb3Igb3RoZXIgVW5pY29kZQogKiBjYXRlZ29yaWVzLCBzY3JpcHRzLCBibG9ja3MsIGFuZCBwcm9wZXJ0aWVzIGFyZSBhdmFpbGFibGUgc2VwYXJhdGVseS4gQWxsIFVuaWNvZGUgdG9rZW5zIGNhbiBiZQogKiBpbnZlcnRlZCB1c2luZyBgXFB7Li59YCBvciBgXHB7Xi4ufWAuIFRva2VuIG5hbWVzIGFyZSBjYXNlIGluc2Vuc2l0aXZlLCBhbmQgYW55IHNwYWNlcywgaHlwaGVucywKICogYW5kIHVuZGVyc2NvcmVzIGFyZSBpZ25vcmVkLgogKiBAcmVxdWlyZXMgWFJlZ0V4cAogKi8KKGZ1bmN0aW9uIChYUmVnRXhwKSB7CiAgICAidXNlIHN0cmljdCI7CgogICAgdmFyIHVuaWNvZGUgPSB7fTsKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogIFByaXZhdGUgaGVscGVyIGZ1bmN0aW9ucwogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgovLyBHZW5lcmF0ZXMgYSBzdGFuZGFyZGl6ZWQgdG9rZW4gbmFtZSAobG93ZXJjYXNlLCB3aXRoIGh5cGhlbnMsIHNwYWNlcywgYW5kIHVuZGVyc2NvcmVzIHJlbW92ZWQpCiAgICBmdW5jdGlvbiBzbHVnKG5hbWUpIHsKICAgICAgICByZXR1cm4gbmFtZS5yZXBsYWNlKC9bLSBfXSsvZywgIiIpLnRvTG93ZXJDYXNlKCk7CiAgICB9CgovLyBFeHBhbmRzIGEgbGlzdCBvZiBVbmljb2RlIGNvZGUgcG9pbnRzIGFuZCByYW5nZXMgdG8gYmUgdXNhYmxlIGluIGEgcmVnZXggY2hhcmFjdGVyIGNsYXNzCiAgICBmdW5jdGlvbiBleHBhbmQoc3RyKSB7CiAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKC9cd3s0fS9nLCAiXFx1JCYiKTsKICAgIH0KCi8vIEFkZHMgbGVhZGluZyB6ZXJvcyBpZiBzaG9ydGVyIHRoYW4gZm91ciBjaGFyYWN0ZXJzCiAgICBmdW5jdGlvbiBwYWQ0KHN0cikgewogICAgICAgIHdoaWxlIChzdHIubGVuZ3RoIDwgNCkgewogICAgICAgICAgICBzdHIgPSAiMCIgKyBzdHI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHI7CiAgICB9CgovLyBDb252ZXJ0cyBhIGhleGFkZWNpbWFsIG51bWJlciB0byBkZWNpbWFsCiAgICBmdW5jdGlvbiBkZWMoaGV4KSB7CiAgICAgICAgcmV0dXJuIHBhcnNlSW50KGhleCwgMTYpOwogICAgfQoKLy8gQ29udmVydHMgYSBkZWNpbWFsIG51bWJlciB0byBoZXhhZGVjaW1hbAogICAgZnVuY3Rpb24gaGV4KGRlYykgewogICAgICAgIHJldHVybiBwYXJzZUludChkZWMsIDEwKS50b1N0cmluZygxNik7CiAgICB9CgovLyBJbnZlcnRzIGEgbGlzdCBvZiBVbmljb2RlIGNvZGUgcG9pbnRzIGFuZCByYW5nZXMKICAgIGZ1bmN0aW9uIGludmVydChyYW5nZSkgewogICAgICAgIHZhciBvdXRwdXQgPSBbXSwKICAgICAgICAgICAgbGFzdEVuZCA9IC0xLAogICAgICAgICAgICBzdGFydDsKICAgICAgICBYUmVnRXhwLmZvckVhY2gocmFuZ2UsIC9cXHUoXHd7NH0pKD86LVxcdShcd3s0fSkpPy8sIGZ1bmN0aW9uIChtKSB7CiAgICAgICAgICAgIHN0YXJ0ID0gZGVjKG1bMV0pOwogICAgICAgICAgICBpZiAoc3RhcnQgPiAobGFzdEVuZCArIDEpKSB7CiAgICAgICAgICAgICAgICBvdXRwdXQucHVzaCgiXFx1IiArIHBhZDQoaGV4KGxhc3RFbmQgKyAxKSkpOwogICAgICAgICAgICAgICAgaWYgKHN0YXJ0ID4gKGxhc3RFbmQgKyAyKSkgewogICAgICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKCItXFx1IiArIHBhZDQoaGV4KHN0YXJ0IC0gMSkpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBsYXN0RW5kID0gZGVjKG1bMl0gfHwgbVsxXSk7CiAgICAgICAgfSk7CiAgICAgICAgaWYgKGxhc3RFbmQgPCAweEZGRkYpIHsKICAgICAgICAgICAgb3V0cHV0LnB1c2goIlxcdSIgKyBwYWQ0KGhleChsYXN0RW5kICsgMSkpKTsKICAgICAgICAgICAgaWYgKGxhc3RFbmQgPCAweEZGRkUpIHsKICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKCItXFx1RkZGRiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBvdXRwdXQuam9pbigiIik7CiAgICB9CgovLyBHZW5lcmF0ZXMgYW4gaW52ZXJ0ZWQgdG9rZW4gb24gZmlyc3QgdXNlCiAgICBmdW5jdGlvbiBjYWNoZUludmVyc2lvbihpdGVtKSB7CiAgICAgICAgcmV0dXJuIHVuaWNvZGVbIl4iICsgaXRlbV0gfHwgKHVuaWNvZGVbIl4iICsgaXRlbV0gPSBpbnZlcnQodW5pY29kZVtpdGVtXSkpOwogICAgfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiAgQ29yZSBmdW5jdGlvbmFsaXR5CiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCiAgICBYUmVnRXhwLmluc3RhbGwoImV4dGVuc2liaWxpdHkiKTsKCi8qKgogKiBBZGRzIHRvIHRoZSBsaXN0IG9mIFVuaWNvZGUgcHJvcGVydGllcyB0aGF0IFhSZWdFeHAgcmVnZXhlcyBjYW4gbWF0Y2ggdmlhIFxwey4ufSBvciBcUHsuLn0uCiAqIEBtZW1iZXJPZiBYUmVnRXhwCiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrIE5hbWVkIHNldHMgb2YgVW5pY29kZSBjb2RlIHBvaW50cyBhbmQgcmFuZ2VzLgogKiBAcGFyYW0ge09iamVjdH0gW2FsaWFzZXNdIEFsaWFzZXMgZm9yIHRoZSBwcmltYXJ5IHRva2VuIG5hbWVzLgogKiBAZXhhbXBsZQogKgogKiBYUmVnRXhwLmFkZFVuaWNvZGVQYWNrYWdlKHsKICogICBYRGlnaXQ6ICcwMDMwLTAwMzkwMDQxLTAwNDYwMDYxLTAwNjYnIC8vIDAtOUEtRmEtZgogKiB9LCB7CiAqICAgWERpZ2l0OiAnSGV4YWRlY2ltYWwnCiAqIH0pOwogKi8KICAgIFhSZWdFeHAuYWRkVW5pY29kZVBhY2thZ2UgPSBmdW5jdGlvbiAocGFjaywgYWxpYXNlcykgewogICAgICAgIHZhciBwOwogICAgICAgIGlmICghWFJlZ0V4cC5pc0luc3RhbGxlZCgiZXh0ZW5zaWJpbGl0eSIpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiZXh0ZW5zaWJpbGl0eSBtdXN0IGJlIGluc3RhbGxlZCBiZWZvcmUgYWRkaW5nIFVuaWNvZGUgcGFja2FnZXMiKTsKICAgICAgICB9CiAgICAgICAgaWYgKHBhY2spIHsKICAgICAgICAgICAgZm9yIChwIGluIHBhY2spIHsKICAgICAgICAgICAgICAgIGlmIChwYWNrLmhhc093blByb3BlcnR5KHApKSB7CiAgICAgICAgICAgICAgICAgICAgdW5pY29kZVtzbHVnKHApXSA9IGV4cGFuZChwYWNrW3BdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoYWxpYXNlcykgewogICAgICAgICAgICBmb3IgKHAgaW4gYWxpYXNlcykgewogICAgICAgICAgICAgICAgaWYgKGFsaWFzZXMuaGFzT3duUHJvcGVydHkocCkpIHsKICAgICAgICAgICAgICAgICAgICB1bmljb2RlW3NsdWcoYWxpYXNlc1twXSldID0gdW5pY29kZVtzbHVnKHApXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgovKiBBZGRzIGRhdGEgZm9yIHRoZSBVbmljb2RlIGBMZXR0ZXJgIGNhdGVnb3J5LiBBZGRvbiBwYWNrYWdlcyBpbmNsdWRlIG90aGVyIGNhdGVnb3JpZXMsIHNjcmlwdHMsCiAqIGJsb2NrcywgYW5kIHByb3BlcnRpZXMuCiAqLwogICAgWFJlZ0V4cC5hZGRVbmljb2RlUGFja2FnZSh7CiAgICAgICAgTDogIjAwNDEtMDA1QTAwNjEtMDA3QTAwQUEwMEI1MDBCQTAwQzAtMDBENjAwRDgtMDBGNjAwRjgtMDJDMTAyQzYtMDJEMTAyRTAtMDJFNDAyRUMwMkVFMDM3MC0wMzc0MDM3NjAzNzcwMzdBLTAzN0QwMzg2MDM4OC0wMzhBMDM4QzAzOEUtMDNBMTAzQTMtMDNGNTAzRjctMDQ4MTA0OEEtMDUyNzA1MzEtMDU1NjA1NTkwNTYxLTA1ODcwNUQwLTA1RUEwNUYwLTA1RjIwNjIwLTA2NEEwNjZFMDY2RjA2NzEtMDZEMzA2RDUwNkU1MDZFNjA2RUUwNkVGMDZGQS0wNkZDMDZGRjA3MTAwNzEyLTA3MkYwNzRELTA3QTUwN0IxMDdDQS0wN0VBMDdGNDA3RjUwN0ZBMDgwMC0wODE1MDgxQTA4MjQwODI4MDg0MC0wODU4MDhBMDA4QTItMDhBQzA5MDQtMDkzOTA5M0QwOTUwMDk1OC0wOTYxMDk3MS0wOTc3MDk3OS0wOTdGMDk4NS0wOThDMDk4RjA5OTAwOTkzLTA5QTgwOUFBLTA5QjAwOUIyMDlCNi0wOUI5MDlCRDA5Q0UwOURDMDlERDA5REYtMDlFMTA5RjAwOUYxMEEwNS0wQTBBMEEwRjBBMTAwQTEzLTBBMjgwQTJBLTBBMzAwQTMyMEEzMzBBMzUwQTM2MEEzODBBMzkwQTU5LTBBNUMwQTVFMEE3Mi0wQTc0MEE4NS0wQThEMEE4Ri0wQTkxMEE5My0wQUE4MEFBQS0wQUIwMEFCMjBBQjMwQUI1LTBBQjkwQUJEMEFEMDBBRTAwQUUxMEIwNS0wQjBDMEIwRjBCMTAwQjEzLTBCMjgwQjJBLTBCMzAwQjMyMEIzMzBCMzUtMEIzOTBCM0QwQjVDMEI1RDBCNUYtMEI2MTBCNzEwQjgzMEI4NS0wQjhBMEI4RS0wQjkwMEI5Mi0wQjk1MEI5OTBCOUEwQjlDMEI5RTBCOUYwQkEzMEJBNDBCQTgtMEJBQTBCQUUtMEJCOTBCRDAwQzA1LTBDMEMwQzBFLTBDMTAwQzEyLTBDMjgwQzJBLTBDMzMwQzM1LTBDMzkwQzNEMEM1ODBDNTkwQzYwMEM2MTBDODUtMEM4QzBDOEUtMEM5MDBDOTItMENBODBDQUEtMENCMzBDQjUtMENCOTBDQkQwQ0RFMENFMDBDRTEwQ0YxMENGMjBEMDUtMEQwQzBEMEUtMEQxMDBEMTItMEQzQTBEM0QwRDRFMEQ2MDBENjEwRDdBLTBEN0YwRDg1LTBEOTYwRDlBLTBEQjEwREIzLTBEQkIwREJEMERDMC0wREM2MEUwMS0wRTMwMEUzMjBFMzMwRTQwLTBFNDYwRTgxMEU4MjBFODQwRTg3MEU4ODBFOEEwRThEMEU5NC0wRTk3MEU5OS0wRTlGMEVBMS0wRUEzMEVBNTBFQTcwRUFBMEVBQjBFQUQtMEVCMDBFQjIwRUIzMEVCRDBFQzAtMEVDNDBFQzYwRURDLTBFREYwRjAwMEY0MC0wRjQ3MEY0OS0wRjZDMEY4OC0wRjhDMTAwMC0xMDJBMTAzRjEwNTAtMTA1NTEwNUEtMTA1RDEwNjExMDY1MTA2NjEwNkUtMTA3MDEwNzUtMTA4MTEwOEUxMEEwLTEwQzUxMEM3MTBDRDEwRDAtMTBGQTEwRkMtMTI0ODEyNEEtMTI0RDEyNTAtMTI1NjEyNTgxMjVBLTEyNUQxMjYwLTEyODgxMjhBLTEyOEQxMjkwLTEyQjAxMkIyLTEyQjUxMkI4LTEyQkUxMkMwMTJDMi0xMkM1MTJDOC0xMkQ2MTJEOC0xMzEwMTMxMi0xMzE1MTMxOC0xMzVBMTM4MC0xMzhGMTNBMC0xM0Y0MTQwMS0xNjZDMTY2Ri0xNjdGMTY4MS0xNjlBMTZBMC0xNkVBMTcwMC0xNzBDMTcwRS0xNzExMTcyMC0xNzMxMTc0MC0xNzUxMTc2MC0xNzZDMTc2RS0xNzcwMTc4MC0xN0IzMTdENzE3REMxODIwLTE4NzcxODgwLTE4QTgxOEFBMThCMC0xOEY1MTkwMC0xOTFDMTk1MC0xOTZEMTk3MC0xOTc0MTk4MC0xOUFCMTlDMS0xOUM3MUEwMC0xQTE2MUEyMC0xQTU0MUFBNzFCMDUtMUIzMzFCNDUtMUI0QjFCODMtMUJBMDFCQUUxQkFGMUJCQS0xQkU1MUMwMC0xQzIzMUM0RC0xQzRGMUM1QS0xQzdEMUNFOS0xQ0VDMUNFRS0xQ0YxMUNGNTFDRjYxRDAwLTFEQkYxRTAwLTFGMTUxRjE4LTFGMUQxRjIwLTFGNDUxRjQ4LTFGNEQxRjUwLTFGNTcxRjU5MUY1QjFGNUQxRjVGLTFGN0QxRjgwLTFGQjQxRkI2LTFGQkMxRkJFMUZDMi0xRkM0MUZDNi0xRkNDMUZEMC0xRkQzMUZENi0xRkRCMUZFMC0xRkVDMUZGMi0xRkY0MUZGNi0xRkZDMjA3MTIwN0YyMDkwLTIwOUMyMTAyMjEwNzIxMEEtMjExMzIxMTUyMTE5LTIxMUQyMTI0MjEyNjIxMjgyMTJBLTIxMkQyMTJGLTIxMzkyMTNDLTIxM0YyMTQ1LTIxNDkyMTRFMjE4MzIxODQyQzAwLTJDMkUyQzMwLTJDNUUyQzYwLTJDRTQyQ0VCLTJDRUUyQ0YyMkNGMzJEMDAtMkQyNTJEMjcyRDJEMkQzMC0yRDY3MkQ2RjJEODAtMkQ5NjJEQTAtMkRBNjJEQTgtMkRBRTJEQjAtMkRCNjJEQjgtMkRCRTJEQzAtMkRDNjJEQzgtMkRDRTJERDAtMkRENjJERDgtMkRERTJFMkYzMDA1MzAwNjMwMzEtMzAzNTMwM0IzMDNDMzA0MS0zMDk2MzA5RC0zMDlGMzBBMS0zMEZBMzBGQy0zMEZGMzEwNS0zMTJEMzEzMS0zMThFMzFBMC0zMUJBMzFGMC0zMUZGMzQwMC00REI1NEUwMC05RkNDQTAwMC1BNDhDQTREMC1BNEZEQTUwMC1BNjBDQTYxMC1BNjFGQTYyQUE2MkJBNjQwLUE2NkVBNjdGLUE2OTdBNkEwLUE2RTVBNzE3LUE3MUZBNzIyLUE3ODhBNzhCLUE3OEVBNzkwLUE3OTNBN0EwLUE3QUFBN0Y4LUE4MDFBODAzLUE4MDVBODA3LUE4MEFBODBDLUE4MjJBODQwLUE4NzNBODgyLUE4QjNBOEYyLUE4RjdBOEZCQTkwQS1BOTI1QTkzMC1BOTQ2QTk2MC1BOTdDQTk4NC1BOUIyQTlDRkFBMDAtQUEyOEFBNDAtQUE0MkFBNDQtQUE0QkFBNjAtQUE3NkFBN0FBQTgwLUFBQUZBQUIxQUFCNUFBQjZBQUI5LUFBQkRBQUMwQUFDMkFBREItQUFEREFBRTAtQUFFQUFBRjItQUFGNEFCMDEtQUIwNkFCMDktQUIwRUFCMTEtQUIxNkFCMjAtQUIyNkFCMjgtQUIyRUFCQzAtQUJFMkFDMDAtRDdBM0Q3QjAtRDdDNkQ3Q0ItRDdGQkY5MDAtRkE2REZBNzAtRkFEOUZCMDAtRkIwNkZCMTMtRkIxN0ZCMURGQjFGLUZCMjhGQjJBLUZCMzZGQjM4LUZCM0NGQjNFRkI0MEZCNDFGQjQzRkI0NEZCNDYtRkJCMUZCRDMtRkQzREZENTAtRkQ4RkZEOTItRkRDN0ZERjAtRkRGQkZFNzAtRkU3NEZFNzYtRkVGQ0ZGMjEtRkYzQUZGNDEtRkY1QUZGNjYtRkZCRUZGQzItRkZDN0ZGQ0EtRkZDRkZGRDItRkZEN0ZGREEtRkZEQyIKICAgIH0sIHsKICAgICAgICBMOiAiTGV0dGVyIgogICAgfSk7CgovKiBBZGRzIFVuaWNvZGUgcHJvcGVydHkgc3ludGF4IHRvIFhSZWdFeHA6IFxwey4ufSwgXFB7Li59LCBccHteLi59CiAqLwogICAgWFJlZ0V4cC5hZGRUb2tlbigKICAgICAgICAvXFwoW3BQXSl7KFxePykoW159XSopfS8sCiAgICAgICAgZnVuY3Rpb24gKG1hdGNoLCBzY29wZSkgewogICAgICAgICAgICB2YXIgaW52ID0gKG1hdGNoWzFdID09PSAiUCIgfHwgbWF0Y2hbMl0pID8gIl4iIDogIiIsCiAgICAgICAgICAgICAgICBpdGVtID0gc2x1ZyhtYXRjaFszXSk7CiAgICAgICAgICAgIC8vIFRoZSBkb3VibGUgbmVnYXRpdmUgXFB7Xi4ufSBpcyBpbnZhbGlkCiAgICAgICAgICAgIGlmIChtYXRjaFsxXSA9PT0gIlAiICYmIG1hdGNoWzJdKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImludmFsaWQgZG91YmxlIG5lZ2F0aW9uIFxcUHteIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCF1bmljb2RlLmhhc093blByb3BlcnR5KGl0ZW0pKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImludmFsaWQgb3IgdW5rbm93biBVbmljb2RlIHByb3BlcnR5ICIgKyBtYXRjaFswXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHNjb3BlID09PSAiY2xhc3MiID8KICAgICAgICAgICAgICAgICAgICAoaW52ID8gY2FjaGVJbnZlcnNpb24oaXRlbSkgOiB1bmljb2RlW2l0ZW1dKSA6CiAgICAgICAgICAgICAgICAgICAgIlsiICsgaW52ICsgdW5pY29kZVtpdGVtXSArICJdIjsKICAgICAgICB9LAogICAgICAgIHtzY29wZTogImFsbCJ9CiAgICApOwoKfShYUmVnRXhwKSk7CgoKLyoqKioqIHVuaWNvZGUtY2F0ZWdvcmllcy5qcyAqKioqKi8KCi8qIQogKiBYUmVnRXhwIFVuaWNvZGUgQ2F0ZWdvcmllcyB2MS4yLjAKICogKGMpIDIwMTAtMjAxMiBTdGV2ZW4gTGV2aXRoYW4gPGh0dHA6Ly94cmVnZXhwLmNvbS8+CiAqIE1JVCBMaWNlbnNlCiAqIFVzZXMgVW5pY29kZSA2LjEgPGh0dHA6Ly91bmljb2RlLm9yZy8+CiAqLwoKLyoqCiAqIEFkZHMgc3VwcG9ydCBmb3IgYWxsIFVuaWNvZGUgY2F0ZWdvcmllcyAoYWthIHByb3BlcnRpZXMpIEUuZy4sIGBccHtMdX1gIG9yCiAqIGBccHtVcHBlcmNhc2UgTGV0dGVyfWAuIFRva2VuIG5hbWVzIGFyZSBjYXNlIGluc2Vuc2l0aXZlLCBhbmQgYW55IHNwYWNlcywgaHlwaGVucywgYW5kCiAqIHVuZGVyc2NvcmVzIGFyZSBpZ25vcmVkLgogKiBAcmVxdWlyZXMgWFJlZ0V4cCwgWFJlZ0V4cCBVbmljb2RlIEJhc2UKICovCihmdW5jdGlvbiAoWFJlZ0V4cCkgewogICAgInVzZSBzdHJpY3QiOwoKICAgIGlmICghWFJlZ0V4cC5hZGRVbmljb2RlUGFja2FnZSkgewogICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigiVW5pY29kZSBCYXNlIG11c3QgYmUgbG9hZGVkIGJlZm9yZSBVbmljb2RlIENhdGVnb3JpZXMiKTsKICAgIH0KCiAgICBYUmVnRXhwLmluc3RhbGwoImV4dGVuc2liaWxpdHkiKTsKCiAgICBYUmVnRXhwLmFkZFVuaWNvZGVQYWNrYWdlKHsKICAgICAgICAvL0w6ICIiLCAvLyBJbmNsdWRlZCBpbiB0aGUgVW5pY29kZSBCYXNlIGFkZG9uCiAgICAgICAgTGw6ICIwMDYxLTAwN0EwMEI1MDBERi0wMEY2MDBGOC0wMEZGMDEwMTAxMDMwMTA1MDEwNzAxMDkwMTBCMDEwRDAxMEYwMTExMDExMzAxMTUwMTE3MDExOTAxMUIwMTFEMDExRjAxMjEwMTIzMDEyNTAxMjcwMTI5MDEyQjAxMkQwMTJGMDEzMTAxMzMwMTM1MDEzNzAxMzgwMTNBMDEzQzAxM0UwMTQwMDE0MjAxNDQwMTQ2MDE0ODAxNDkwMTRCMDE0RDAxNEYwMTUxMDE1MzAxNTUwMTU3MDE1OTAxNUIwMTVEMDE1RjAxNjEwMTYzMDE2NTAxNjcwMTY5MDE2QjAxNkQwMTZGMDE3MTAxNzMwMTc1MDE3NzAxN0EwMTdDMDE3RS0wMTgwMDE4MzAxODUwMTg4MDE4QzAxOEQwMTkyMDE5NTAxOTktMDE5QjAxOUUwMUExMDFBMzAxQTUwMUE4MDFBQTAxQUIwMUFEMDFCMDAxQjQwMUI2MDFCOTAxQkEwMUJELTAxQkYwMUM2MDFDOTAxQ0MwMUNFMDFEMDAxRDIwMUQ0MDFENjAxRDgwMURBMDFEQzAxREQwMURGMDFFMTAxRTMwMUU1MDFFNzAxRTkwMUVCMDFFRDAxRUYwMUYwMDFGMzAxRjUwMUY5MDFGQjAxRkQwMUZGMDIwMTAyMDMwMjA1MDIwNzAyMDkwMjBCMDIwRDAyMEYwMjExMDIxMzAyMTUwMjE3MDIxOTAyMUIwMjFEMDIxRjAyMjEwMjIzMDIyNTAyMjcwMjI5MDIyQjAyMkQwMjJGMDIzMTAyMzMtMDIzOTAyM0MwMjNGMDI0MDAyNDIwMjQ3MDI0OTAyNEIwMjREMDI0Ri0wMjkzMDI5NS0wMkFGMDM3MTAzNzMwMzc3MDM3Qi0wMzdEMDM5MDAzQUMtMDNDRTAzRDAwM0QxMDNENS0wM0Q3MDNEOTAzREIwM0REMDNERjAzRTEwM0UzMDNFNTAzRTcwM0U5MDNFQjAzRUQwM0VGLTAzRjMwM0Y1MDNGODAzRkIwM0ZDMDQzMC0wNDVGMDQ2MTA0NjMwNDY1MDQ2NzA0NjkwNDZCMDQ2RDA0NkYwNDcxMDQ3MzA0NzUwNDc3MDQ3OTA0N0IwNDdEMDQ3RjA0ODEwNDhCMDQ4RDA0OEYwNDkxMDQ5MzA0OTUwNDk3MDQ5OTA0OUIwNDlEMDQ5RjA0QTEwNEEzMDRBNTA0QTcwNEE5MDRBQjA0QUQwNEFGMDRCMTA0QjMwNEI1MDRCNzA0QjkwNEJCMDRCRDA0QkYwNEMyMDRDNDA0QzYwNEM4MDRDQTA0Q0MwNENFMDRDRjA0RDEwNEQzMDRENTA0RDcwNEQ5MDREQjA0REQwNERGMDRFMTA0RTMwNEU1MDRFNzA0RTkwNEVCMDRFRDA0RUYwNEYxMDRGMzA0RjUwNEY3MDRGOTA0RkIwNEZEMDRGRjA1MDEwNTAzMDUwNTA1MDcwNTA5MDUwQjA1MEQwNTBGMDUxMTA1MTMwNTE1MDUxNzA1MTkwNTFCMDUxRDA1MUYwNTIxMDUyMzA1MjUwNTI3MDU2MS0wNTg3MUQwMC0xRDJCMUQ2Qi0xRDc3MUQ3OS0xRDlBMUUwMTFFMDMxRTA1MUUwNzFFMDkxRTBCMUUwRDFFMEYxRTExMUUxMzFFMTUxRTE3MUUxOTFFMUIxRTFEMUUxRjFFMjExRTIzMUUyNTFFMjcxRTI5MUUyQjFFMkQxRTJGMUUzMTFFMzMxRTM1MUUzNzFFMzkxRTNCMUUzRDFFM0YxRTQxMUU0MzFFNDUxRTQ3MUU0OTFFNEIxRTREMUU0RjFFNTExRTUzMUU1NTFFNTcxRTU5MUU1QjFFNUQxRTVGMUU2MTFFNjMxRTY1MUU2NzFFNjkxRTZCMUU2RDFFNkYxRTcxMUU3MzFFNzUxRTc3MUU3OTFFN0IxRTdEMUU3RjFFODExRTgzMUU4NTFFODcxRTg5MUU4QjFFOEQxRThGMUU5MTFFOTMxRTk1LTFFOUQxRTlGMUVBMTFFQTMxRUE1MUVBNzFFQTkxRUFCMUVBRDFFQUYxRUIxMUVCMzFFQjUxRUI3MUVCOTFFQkIxRUJEMUVCRjFFQzExRUMzMUVDNTFFQzcxRUM5MUVDQjFFQ0QxRUNGMUVEMTFFRDMxRUQ1MUVENzFFRDkxRURCMUVERDFFREYxRUUxMUVFMzFFRTUxRUU3MUVFOTFFRUIxRUVEMUVFRjFFRjExRUYzMUVGNTFFRjcxRUY5MUVGQjFFRkQxRUZGLTFGMDcxRjEwLTFGMTUxRjIwLTFGMjcxRjMwLTFGMzcxRjQwLTFGNDUxRjUwLTFGNTcxRjYwLTFGNjcxRjcwLTFGN0QxRjgwLTFGODcxRjkwLTFGOTcxRkEwLTFGQTcxRkIwLTFGQjQxRkI2MUZCNzFGQkUxRkMyLTFGQzQxRkM2MUZDNzFGRDAtMUZEMzFGRDYxRkQ3MUZFMC0xRkU3MUZGMi0xRkY0MUZGNjFGRjcyMTBBMjEwRTIxMEYyMTEzMjEyRjIxMzQyMTM5MjEzQzIxM0QyMTQ2LTIxNDkyMTRFMjE4NDJDMzAtMkM1RTJDNjEyQzY1MkM2NjJDNjgyQzZBMkM2QzJDNzEyQzczMkM3NDJDNzYtMkM3QjJDODEyQzgzMkM4NTJDODcyQzg5MkM4QjJDOEQyQzhGMkM5MTJDOTMyQzk1MkM5NzJDOTkyQzlCMkM5RDJDOUYyQ0ExMkNBMzJDQTUyQ0E3MkNBOTJDQUIyQ0FEMkNBRjJDQjEyQ0IzMkNCNTJDQjcyQ0I5MkNCQjJDQkQyQ0JGMkNDMTJDQzMyQ0M1MkNDNzJDQzkyQ0NCMkNDRDJDQ0YyQ0QxMkNEMzJDRDUyQ0Q3MkNEOTJDREIyQ0REMkNERjJDRTEyQ0UzMkNFNDJDRUMyQ0VFMkNGMzJEMDAtMkQyNTJEMjcyRDJEQTY0MUE2NDNBNjQ1QTY0N0E2NDlBNjRCQTY0REE2NEZBNjUxQTY1M0E2NTVBNjU3QTY1OUE2NUJBNjVEQTY1RkE2NjFBNjYzQTY2NUE2NjdBNjY5QTY2QkE2NkRBNjgxQTY4M0E2ODVBNjg3QTY4OUE2OEJBNjhEQTY4RkE2OTFBNjkzQTY5NUE2OTdBNzIzQTcyNUE3MjdBNzI5QTcyQkE3MkRBNzJGLUE3MzFBNzMzQTczNUE3MzdBNzM5QTczQkE3M0RBNzNGQTc0MUE3NDNBNzQ1QTc0N0E3NDlBNzRCQTc0REE3NEZBNzUxQTc1M0E3NTVBNzU3QTc1OUE3NUJBNzVEQTc1RkE3NjFBNzYzQTc2NUE3NjdBNzY5QTc2QkE3NkRBNzZGQTc3MS1BNzc4QTc3QUE3N0NBNzdGQTc4MUE3ODNBNzg1QTc4N0E3OENBNzhFQTc5MUE3OTNBN0ExQTdBM0E3QTVBN0E3QTdBOUE3RkFGQjAwLUZCMDZGQjEzLUZCMTdGRjQxLUZGNUEiLAogICAgICAgIEx1OiAiMDA0MS0wMDVBMDBDMC0wMEQ2MDBEOC0wMERFMDEwMDAxMDIwMTA0MDEwNjAxMDgwMTBBMDEwQzAxMEUwMTEwMDExMjAxMTQwMTE2MDExODAxMUEwMTFDMDExRTAxMjAwMTIyMDEyNDAxMjYwMTI4MDEyQTAxMkMwMTJFMDEzMDAxMzIwMTM0MDEzNjAxMzkwMTNCMDEzRDAxM0YwMTQxMDE0MzAxNDUwMTQ3MDE0QTAxNEMwMTRFMDE1MDAxNTIwMTU0MDE1NjAxNTgwMTVBMDE1QzAxNUUwMTYwMDE2MjAxNjQwMTY2MDE2ODAxNkEwMTZDMDE2RTAxNzAwMTcyMDE3NDAxNzYwMTc4MDE3OTAxN0IwMTdEMDE4MTAxODIwMTg0MDE4NjAxODcwMTg5LTAxOEIwMThFLTAxOTEwMTkzMDE5NDAxOTYtMDE5ODAxOUMwMTlEMDE5RjAxQTAwMUEyMDFBNDAxQTYwMUE3MDFBOTAxQUMwMUFFMDFBRjAxQjEtMDFCMzAxQjUwMUI3MDFCODAxQkMwMUM0MDFDNzAxQ0EwMUNEMDFDRjAxRDEwMUQzMDFENTAxRDcwMUQ5MDFEQjAxREUwMUUwMDFFMjAxRTQwMUU2MDFFODAxRUEwMUVDMDFFRTAxRjEwMUY0MDFGNi0wMUY4MDFGQTAxRkMwMUZFMDIwMDAyMDIwMjA0MDIwNjAyMDgwMjBBMDIwQzAyMEUwMjEwMDIxMjAyMTQwMjE2MDIxODAyMUEwMjFDMDIxRTAyMjAwMjIyMDIyNDAyMjYwMjI4MDIyQTAyMkMwMjJFMDIzMDAyMzIwMjNBMDIzQjAyM0QwMjNFMDI0MTAyNDMtMDI0NjAyNDgwMjRBMDI0QzAyNEUwMzcwMDM3MjAzNzYwMzg2MDM4OC0wMzhBMDM4QzAzOEUwMzhGMDM5MS0wM0ExMDNBMy0wM0FCMDNDRjAzRDItMDNENDAzRDgwM0RBMDNEQzAzREUwM0UwMDNFMjAzRTQwM0U2MDNFODAzRUEwM0VDMDNFRTAzRjQwM0Y3MDNGOTAzRkEwM0ZELTA0MkYwNDYwMDQ2MjA0NjQwNDY2MDQ2ODA0NkEwNDZDMDQ2RTA0NzAwNDcyMDQ3NDA0NzYwNDc4MDQ3QTA0N0MwNDdFMDQ4MDA0OEEwNDhDMDQ4RTA0OTAwNDkyMDQ5NDA0OTYwNDk4MDQ5QTA0OUMwNDlFMDRBMDA0QTIwNEE0MDRBNjA0QTgwNEFBMDRBQzA0QUUwNEIwMDRCMjA0QjQwNEI2MDRCODA0QkEwNEJDMDRCRTA0QzAwNEMxMDRDMzA0QzUwNEM3MDRDOTA0Q0IwNENEMDREMDA0RDIwNEQ0MDRENjA0RDgwNERBMDREQzA0REUwNEUwMDRFMjA0RTQwNEU2MDRFODA0RUEwNEVDMDRFRTA0RjAwNEYyMDRGNDA0RjYwNEY4MDRGQTA0RkMwNEZFMDUwMDA1MDIwNTA0MDUwNjA1MDgwNTBBMDUwQzA1MEUwNTEwMDUxMjA1MTQwNTE2MDUxODA1MUEwNTFDMDUxRTA1MjAwNTIyMDUyNDA1MjYwNTMxLTA1NTYxMEEwLTEwQzUxMEM3MTBDRDFFMDAxRTAyMUUwNDFFMDYxRTA4MUUwQTFFMEMxRTBFMUUxMDFFMTIxRTE0MUUxNjFFMTgxRTFBMUUxQzFFMUUxRTIwMUUyMjFFMjQxRTI2MUUyODFFMkExRTJDMUUyRTFFMzAxRTMyMUUzNDFFMzYxRTM4MUUzQTFFM0MxRTNFMUU0MDFFNDIxRTQ0MUU0NjFFNDgxRTRBMUU0QzFFNEUxRTUwMUU1MjFFNTQxRTU2MUU1ODFFNUExRTVDMUU1RTFFNjAxRTYyMUU2NDFFNjYxRTY4MUU2QTFFNkMxRTZFMUU3MDFFNzIxRTc0MUU3NjFFNzgxRTdBMUU3QzFFN0UxRTgwMUU4MjFFODQxRTg2MUU4ODFFOEExRThDMUU4RTFFOTAxRTkyMUU5NDFFOUUxRUEwMUVBMjFFQTQxRUE2MUVBODFFQUExRUFDMUVBRTFFQjAxRUIyMUVCNDFFQjYxRUI4MUVCQTFFQkMxRUJFMUVDMDFFQzIxRUM0MUVDNjFFQzgxRUNBMUVDQzFFQ0UxRUQwMUVEMjFFRDQxRUQ2MUVEODFFREExRURDMUVERTFFRTAxRUUyMUVFNDFFRTYxRUU4MUVFQTFFRUMxRUVFMUVGMDFFRjIxRUY0MUVGNjFFRjgxRUZBMUVGQzFFRkUxRjA4LTFGMEYxRjE4LTFGMUQxRjI4LTFGMkYxRjM4LTFGM0YxRjQ4LTFGNEQxRjU5MUY1QjFGNUQxRjVGMUY2OC0xRjZGMUZCOC0xRkJCMUZDOC0xRkNCMUZEOC0xRkRCMUZFOC0xRkVDMUZGOC0xRkZCMjEwMjIxMDcyMTBCLTIxMEQyMTEwLTIxMTIyMTE1MjExOS0yMTFEMjEyNDIxMjYyMTI4MjEyQS0yMTJEMjEzMC0yMTMzMjEzRTIxM0YyMTQ1MjE4MzJDMDAtMkMyRTJDNjAyQzYyLTJDNjQyQzY3MkM2OTJDNkIyQzZELTJDNzAyQzcyMkM3NTJDN0UtMkM4MDJDODIyQzg0MkM4NjJDODgyQzhBMkM4QzJDOEUyQzkwMkM5MjJDOTQyQzk2MkM5ODJDOUEyQzlDMkM5RTJDQTAyQ0EyMkNBNDJDQTYyQ0E4MkNBQTJDQUMyQ0FFMkNCMDJDQjIyQ0I0MkNCNjJDQjgyQ0JBMkNCQzJDQkUyQ0MwMkNDMjJDQzQyQ0M2MkNDODJDQ0EyQ0NDMkNDRTJDRDAyQ0QyMkNENDJDRDYyQ0Q4MkNEQTJDREMyQ0RFMkNFMDJDRTIyQ0VCMkNFRDJDRjJBNjQwQTY0MkE2NDRBNjQ2QTY0OEE2NEFBNjRDQTY0RUE2NTBBNjUyQTY1NEE2NTZBNjU4QTY1QUE2NUNBNjVFQTY2MEE2NjJBNjY0QTY2NkE2NjhBNjZBQTY2Q0E2ODBBNjgyQTY4NEE2ODZBNjg4QTY4QUE2OENBNjhFQTY5MEE2OTJBNjk0QTY5NkE3MjJBNzI0QTcyNkE3MjhBNzJBQTcyQ0E3MkVBNzMyQTczNEE3MzZBNzM4QTczQUE3M0NBNzNFQTc0MEE3NDJBNzQ0QTc0NkE3NDhBNzRBQTc0Q0E3NEVBNzUwQTc1MkE3NTRBNzU2QTc1OEE3NUFBNzVDQTc1RUE3NjBBNzYyQTc2NEE3NjZBNzY4QTc2QUE3NkNBNzZFQTc3OUE3N0JBNzdEQTc3RUE3ODBBNzgyQTc4NEE3ODZBNzhCQTc4REE3OTBBNzkyQTdBMEE3QTJBN0E0QTdBNkE3QThBN0FBRkYyMS1GRjNBIiwKICAgICAgICBMdDogIjAxQzUwMUM4MDFDQjAxRjIxRjg4LTFGOEYxRjk4LTFGOUYxRkE4LTFGQUYxRkJDMUZDQzFGRkMiLAogICAgICAgIExtOiAiMDJCMC0wMkMxMDJDNi0wMkQxMDJFMC0wMkU0MDJFQzAyRUUwMzc0MDM3QTA1NTkwNjQwMDZFNTA2RTYwN0Y0MDdGNTA3RkEwODFBMDgyNDA4MjgwOTcxMEU0NjBFQzYxMEZDMTdENzE4NDMxQUE3MUM3OC0xQzdEMUQyQy0xRDZBMUQ3ODFEOUItMURCRjIwNzEyMDdGMjA5MC0yMDlDMkM3QzJDN0QyRDZGMkUyRjMwMDUzMDMxLTMwMzUzMDNCMzA5RDMwOUUzMEZDLTMwRkVBMDE1QTRGOC1BNEZEQTYwQ0E2N0ZBNzE3LUE3MUZBNzcwQTc4OEE3RjhBN0Y5QTlDRkFBNzBBQUREQUFGM0FBRjRGRjcwRkY5RUZGOUYiLAogICAgICAgIExvOiAiMDBBQTAwQkEwMUJCMDFDMC0wMUMzMDI5NDA1RDAtMDVFQTA1RjAtMDVGMjA2MjAtMDYzRjA2NDEtMDY0QTA2NkUwNjZGMDY3MS0wNkQzMDZENTA2RUUwNkVGMDZGQS0wNkZDMDZGRjA3MTAwNzEyLTA3MkYwNzRELTA3QTUwN0IxMDdDQS0wN0VBMDgwMC0wODE1MDg0MC0wODU4MDhBMDA4QTItMDhBQzA5MDQtMDkzOTA5M0QwOTUwMDk1OC0wOTYxMDk3Mi0wOTc3MDk3OS0wOTdGMDk4NS0wOThDMDk4RjA5OTAwOTkzLTA5QTgwOUFBLTA5QjAwOUIyMDlCNi0wOUI5MDlCRDA5Q0UwOURDMDlERDA5REYtMDlFMTA5RjAwOUYxMEEwNS0wQTBBMEEwRjBBMTAwQTEzLTBBMjgwQTJBLTBBMzAwQTMyMEEzMzBBMzUwQTM2MEEzODBBMzkwQTU5LTBBNUMwQTVFMEE3Mi0wQTc0MEE4NS0wQThEMEE4Ri0wQTkxMEE5My0wQUE4MEFBQS0wQUIwMEFCMjBBQjMwQUI1LTBBQjkwQUJEMEFEMDBBRTAwQUUxMEIwNS0wQjBDMEIwRjBCMTAwQjEzLTBCMjgwQjJBLTBCMzAwQjMyMEIzMzBCMzUtMEIzOTBCM0QwQjVDMEI1RDBCNUYtMEI2MTBCNzEwQjgzMEI4NS0wQjhBMEI4RS0wQjkwMEI5Mi0wQjk1MEI5OTBCOUEwQjlDMEI5RTBCOUYwQkEzMEJBNDBCQTgtMEJBQTBCQUUtMEJCOTBCRDAwQzA1LTBDMEMwQzBFLTBDMTAwQzEyLTBDMjgwQzJBLTBDMzMwQzM1LTBDMzkwQzNEMEM1ODBDNTkwQzYwMEM2MTBDODUtMEM4QzBDOEUtMEM5MDBDOTItMENBODBDQUEtMENCMzBDQjUtMENCOTBDQkQwQ0RFMENFMDBDRTEwQ0YxMENGMjBEMDUtMEQwQzBEMEUtMEQxMDBEMTItMEQzQTBEM0QwRDRFMEQ2MDBENjEwRDdBLTBEN0YwRDg1LTBEOTYwRDlBLTBEQjEwREIzLTBEQkIwREJEMERDMC0wREM2MEUwMS0wRTMwMEUzMjBFMzMwRTQwLTBFNDUwRTgxMEU4MjBFODQwRTg3MEU4ODBFOEEwRThEMEU5NC0wRTk3MEU5OS0wRTlGMEVBMS0wRUEzMEVBNTBFQTcwRUFBMEVBQjBFQUQtMEVCMDBFQjIwRUIzMEVCRDBFQzAtMEVDNDBFREMtMEVERjBGMDAwRjQwLTBGNDcwRjQ5LTBGNkMwRjg4LTBGOEMxMDAwLTEwMkExMDNGMTA1MC0xMDU1MTA1QS0xMDVEMTA2MTEwNjUxMDY2MTA2RS0xMDcwMTA3NS0xMDgxMTA4RTEwRDAtMTBGQTEwRkQtMTI0ODEyNEEtMTI0RDEyNTAtMTI1NjEyNTgxMjVBLTEyNUQxMjYwLTEyODgxMjhBLTEyOEQxMjkwLTEyQjAxMkIyLTEyQjUxMkI4LTEyQkUxMkMwMTJDMi0xMkM1MTJDOC0xMkQ2MTJEOC0xMzEwMTMxMi0xMzE1MTMxOC0xMzVBMTM4MC0xMzhGMTNBMC0xM0Y0MTQwMS0xNjZDMTY2Ri0xNjdGMTY4MS0xNjlBMTZBMC0xNkVBMTcwMC0xNzBDMTcwRS0xNzExMTcyMC0xNzMxMTc0MC0xNzUxMTc2MC0xNzZDMTc2RS0xNzcwMTc4MC0xN0IzMTdEQzE4MjAtMTg0MjE4NDQtMTg3NzE4ODAtMThBODE4QUExOEIwLTE4RjUxOTAwLTE5MUMxOTUwLTE5NkQxOTcwLTE5NzQxOTgwLTE5QUIxOUMxLTE5QzcxQTAwLTFBMTYxQTIwLTFBNTQxQjA1LTFCMzMxQjQ1LTFCNEIxQjgzLTFCQTAxQkFFMUJBRjFCQkEtMUJFNTFDMDAtMUMyMzFDNEQtMUM0RjFDNUEtMUM3NzFDRTktMUNFQzFDRUUtMUNGMTFDRjUxQ0Y2MjEzNS0yMTM4MkQzMC0yRDY3MkQ4MC0yRDk2MkRBMC0yREE2MkRBOC0yREFFMkRCMC0yREI2MkRCOC0yREJFMkRDMC0yREM2MkRDOC0yRENFMkREMC0yREQ2MkREOC0yRERFMzAwNjMwM0MzMDQxLTMwOTYzMDlGMzBBMS0zMEZBMzBGRjMxMDUtMzEyRDMxMzEtMzE4RTMxQTAtMzFCQTMxRjAtMzFGRjM0MDAtNERCNTRFMDAtOUZDQ0EwMDAtQTAxNEEwMTYtQTQ4Q0E0RDAtQTRGN0E1MDAtQTYwQkE2MTAtQTYxRkE2MkFBNjJCQTY2RUE2QTAtQTZFNUE3RkItQTgwMUE4MDMtQTgwNUE4MDctQTgwQUE4MEMtQTgyMkE4NDAtQTg3M0E4ODItQThCM0E4RjItQThGN0E4RkJBOTBBLUE5MjVBOTMwLUE5NDZBOTYwLUE5N0NBOTg0LUE5QjJBQTAwLUFBMjhBQTQwLUFBNDJBQTQ0LUFBNEJBQTYwLUFBNkZBQTcxLUFBNzZBQTdBQUE4MC1BQUFGQUFCMUFBQjVBQUI2QUFCOS1BQUJEQUFDMEFBQzJBQURCQUFEQ0FBRTAtQUFFQUFBRjJBQjAxLUFCMDZBQjA5LUFCMEVBQjExLUFCMTZBQjIwLUFCMjZBQjI4LUFCMkVBQkMwLUFCRTJBQzAwLUQ3QTNEN0IwLUQ3QzZEN0NCLUQ3RkJGOTAwLUZBNkRGQTcwLUZBRDlGQjFERkIxRi1GQjI4RkIyQS1GQjM2RkIzOC1GQjNDRkIzRUZCNDBGQjQxRkI0M0ZCNDRGQjQ2LUZCQjFGQkQzLUZEM0RGRDUwLUZEOEZGRDkyLUZEQzdGREYwLUZERkJGRTcwLUZFNzRGRTc2LUZFRkNGRjY2LUZGNkZGRjcxLUZGOURGRkEwLUZGQkVGRkMyLUZGQzdGRkNBLUZGQ0ZGRkQyLUZGRDdGRkRBLUZGREMiLAogICAgICAgIE06ICIwMzAwLTAzNkYwNDgzLTA0ODkwNTkxLTA1QkQwNUJGMDVDMTA1QzIwNUM0MDVDNTA1QzcwNjEwLTA2MUEwNjRCLTA2NUYwNjcwMDZENi0wNkRDMDZERi0wNkU0MDZFNzA2RTgwNkVBLTA2RUQwNzExMDczMC0wNzRBMDdBNi0wN0IwMDdFQi0wN0YzMDgxNi0wODE5MDgxQi0wODIzMDgyNS0wODI3MDgyOS0wODJEMDg1OS0wODVCMDhFNC0wOEZFMDkwMC0wOTAzMDkzQS0wOTNDMDkzRS0wOTRGMDk1MS0wOTU3MDk2MjA5NjMwOTgxLTA5ODMwOUJDMDlCRS0wOUM0MDlDNzA5QzgwOUNCLTA5Q0QwOUQ3MDlFMjA5RTMwQTAxLTBBMDMwQTNDMEEzRS0wQTQyMEE0NzBBNDgwQTRCLTBBNEQwQTUxMEE3MDBBNzEwQTc1MEE4MS0wQTgzMEFCQzBBQkUtMEFDNTBBQzctMEFDOTBBQ0ItMEFDRDBBRTIwQUUzMEIwMS0wQjAzMEIzQzBCM0UtMEI0NDBCNDcwQjQ4MEI0Qi0wQjREMEI1NjBCNTcwQjYyMEI2MzBCODIwQkJFLTBCQzIwQkM2LTBCQzgwQkNBLTBCQ0QwQkQ3MEMwMS0wQzAzMEMzRS0wQzQ0MEM0Ni0wQzQ4MEM0QS0wQzREMEM1NTBDNTYwQzYyMEM2MzBDODIwQzgzMENCQzBDQkUtMENDNDBDQzYtMENDODBDQ0EtMENDRDBDRDUwQ0Q2MENFMjBDRTMwRDAyMEQwMzBEM0UtMEQ0NDBENDYtMEQ0ODBENEEtMEQ0RDBENTcwRDYyMEQ2MzBEODIwRDgzMERDQTBEQ0YtMERENDBERDYwREQ4LTBEREYwREYyMERGMzBFMzEwRTM0LTBFM0EwRTQ3LTBFNEUwRUIxMEVCNC0wRUI5MEVCQjBFQkMwRUM4LTBFQ0QwRjE4MEYxOTBGMzUwRjM3MEYzOTBGM0UwRjNGMEY3MS0wRjg0MEY4NjBGODcwRjhELTBGOTcwRjk5LTBGQkMwRkM2MTAyQi0xMDNFMTA1Ni0xMDU5MTA1RS0xMDYwMTA2Mi0xMDY0MTA2Ny0xMDZEMTA3MS0xMDc0MTA4Mi0xMDhEMTA4RjEwOUEtMTA5RDEzNUQtMTM1RjE3MTItMTcxNDE3MzItMTczNDE3NTIxNzUzMTc3MjE3NzMxN0I0LTE3RDMxN0REMTgwQi0xODBEMThBOTE5MjAtMTkyQjE5MzAtMTkzQjE5QjAtMTlDMDE5QzgxOUM5MUExNy0xQTFCMUE1NS0xQTVFMUE2MC0xQTdDMUE3RjFCMDAtMUIwNDFCMzQtMUI0NDFCNkItMUI3MzFCODAtMUI4MjFCQTEtMUJBRDFCRTYtMUJGMzFDMjQtMUMzNzFDRDAtMUNEMjFDRDQtMUNFODFDRUQxQ0YyLTFDRjQxREMwLTFERTYxREZDLTFERkYyMEQwLTIwRjAyQ0VGLTJDRjEyRDdGMkRFMC0yREZGMzAyQS0zMDJGMzA5OTMwOUFBNjZGLUE2NzJBNjc0LUE2N0RBNjlGQTZGMEE2RjFBODAyQTgwNkE4MEJBODIzLUE4MjdBODgwQTg4MUE4QjQtQThDNEE4RTAtQThGMUE5MjYtQTkyREE5NDctQTk1M0E5ODAtQTk4M0E5QjMtQTlDMEFBMjktQUEzNkFBNDNBQTRDQUE0REFBN0JBQUIwQUFCMi1BQUI0QUFCN0FBQjhBQUJFQUFCRkFBQzFBQUVCLUFBRUZBQUY1QUFGNkFCRTMtQUJFQUFCRUNBQkVERkIxRUZFMDAtRkUwRkZFMjAtRkUyNiIsCiAgICAgICAgTW46ICIwMzAwLTAzNkYwNDgzLTA0ODcwNTkxLTA1QkQwNUJGMDVDMTA1QzIwNUM0MDVDNTA1QzcwNjEwLTA2MUEwNjRCLTA2NUYwNjcwMDZENi0wNkRDMDZERi0wNkU0MDZFNzA2RTgwNkVBLTA2RUQwNzExMDczMC0wNzRBMDdBNi0wN0IwMDdFQi0wN0YzMDgxNi0wODE5MDgxQi0wODIzMDgyNS0wODI3MDgyOS0wODJEMDg1OS0wODVCMDhFNC0wOEZFMDkwMC0wOTAyMDkzQTA5M0MwOTQxLTA5NDgwOTREMDk1MS0wOTU3MDk2MjA5NjMwOTgxMDlCQzA5QzEtMDlDNDA5Q0QwOUUyMDlFMzBBMDEwQTAyMEEzQzBBNDEwQTQyMEE0NzBBNDgwQTRCLTBBNEQwQTUxMEE3MDBBNzEwQTc1MEE4MTBBODIwQUJDMEFDMS0wQUM1MEFDNzBBQzgwQUNEMEFFMjBBRTMwQjAxMEIzQzBCM0YwQjQxLTBCNDQwQjREMEI1NjBCNjIwQjYzMEI4MjBCQzAwQkNEMEMzRS0wQzQwMEM0Ni0wQzQ4MEM0QS0wQzREMEM1NTBDNTYwQzYyMEM2MzBDQkMwQ0JGMENDNjBDQ0MwQ0NEMENFMjBDRTMwRDQxLTBENDQwRDREMEQ2MjBENjMwRENBMEREMi0wREQ0MERENjBFMzEwRTM0LTBFM0EwRTQ3LTBFNEUwRUIxMEVCNC0wRUI5MEVCQjBFQkMwRUM4LTBFQ0QwRjE4MEYxOTBGMzUwRjM3MEYzOTBGNzEtMEY3RTBGODAtMEY4NDBGODYwRjg3MEY4RC0wRjk3MEY5OS0wRkJDMEZDNjEwMkQtMTAzMDEwMzItMTAzNzEwMzkxMDNBMTAzRDEwM0UxMDU4MTA1OTEwNUUtMTA2MDEwNzEtMTA3NDEwODIxMDg1MTA4NjEwOEQxMDlEMTM1RC0xMzVGMTcxMi0xNzE0MTczMi0xNzM0MTc1MjE3NTMxNzcyMTc3MzE3QjQxN0I1MTdCNy0xN0JEMTdDNjE3QzktMTdEMzE3REQxODBCLTE4MEQxOEE5MTkyMC0xOTIyMTkyNzE5MjgxOTMyMTkzOS0xOTNCMUExNzFBMTgxQTU2MUE1OC0xQTVFMUE2MDFBNjIxQTY1LTFBNkMxQTczLTFBN0MxQTdGMUIwMC0xQjAzMUIzNDFCMzYtMUIzQTFCM0MxQjQyMUI2Qi0xQjczMUI4MDFCODExQkEyLTFCQTUxQkE4MUJBOTFCQUIxQkU2MUJFODFCRTkxQkVEMUJFRi0xQkYxMUMyQy0xQzMzMUMzNjFDMzcxQ0QwLTFDRDIxQ0Q0LTFDRTAxQ0UyLTFDRTgxQ0VEMUNGNDFEQzAtMURFNjFERkMtMURGRjIwRDAtMjBEQzIwRTEyMEU1LTIwRjAyQ0VGLTJDRjEyRDdGMkRFMC0yREZGMzAyQS0zMDJEMzA5OTMwOUFBNjZGQTY3NC1BNjdEQTY5RkE2RjBBNkYxQTgwMkE4MDZBODBCQTgyNUE4MjZBOEM0QThFMC1BOEYxQTkyNi1BOTJEQTk0Ny1BOTUxQTk4MC1BOTgyQTlCM0E5QjYtQTlCOUE5QkNBQTI5LUFBMkVBQTMxQUEzMkFBMzVBQTM2QUE0M0FBNENBQUIwQUFCMi1BQUI0QUFCN0FBQjhBQUJFQUFCRkFBQzFBQUVDQUFFREFBRjZBQkU1QUJFOEFCRURGQjFFRkUwMC1GRTBGRkUyMC1GRTI2IiwKICAgICAgICBNYzogIjA5MDMwOTNCMDkzRS0wOTQwMDk0OS0wOTRDMDk0RTA5NEYwOTgyMDk4MzA5QkUtMDlDMDA5QzcwOUM4MDlDQjA5Q0MwOUQ3MEEwMzBBM0UtMEE0MDBBODMwQUJFLTBBQzAwQUM5MEFDQjBBQ0MwQjAyMEIwMzBCM0UwQjQwMEI0NzBCNDgwQjRCMEI0QzBCNTcwQkJFMEJCRjBCQzEwQkMyMEJDNi0wQkM4MEJDQS0wQkNDMEJENzBDMDEtMEMwMzBDNDEtMEM0NDBDODIwQzgzMENCRTBDQzAtMENDNDBDQzcwQ0M4MENDQTBDQ0IwQ0Q1MENENjBEMDIwRDAzMEQzRS0wRDQwMEQ0Ni0wRDQ4MEQ0QS0wRDRDMEQ1NzBEODIwRDgzMERDRi0wREQxMEREOC0wRERGMERGMjBERjMwRjNFMEYzRjBGN0YxMDJCMTAyQzEwMzExMDM4MTAzQjEwM0MxMDU2MTA1NzEwNjItMTA2NDEwNjctMTA2RDEwODMxMDg0MTA4Ny0xMDhDMTA4RjEwOUEtMTA5QzE3QjYxN0JFLTE3QzUxN0M3MTdDODE5MjMtMTkyNjE5MjktMTkyQjE5MzAxOTMxMTkzMy0xOTM4MTlCMC0xOUMwMTlDODE5QzkxQTE5LTFBMUIxQTU1MUE1NzFBNjExQTYzMUE2NDFBNkQtMUE3MjFCMDQxQjM1MUIzQjFCM0QtMUI0MTFCNDMxQjQ0MUI4MjFCQTExQkE2MUJBNzFCQUExQkFDMUJBRDFCRTcxQkVBLTFCRUMxQkVFMUJGMjFCRjMxQzI0LTFDMkIxQzM0MUMzNTFDRTExQ0YyMUNGMzMwMkUzMDJGQTgyM0E4MjRBODI3QTg4MEE4ODFBOEI0LUE4QzNBOTUyQTk1M0E5ODNBOUI0QTlCNUE5QkFBOUJCQTlCRC1BOUMwQUEyRkFBMzBBQTMzQUEzNEFBNERBQTdCQUFFQkFBRUVBQUVGQUFGNUFCRTNBQkU0QUJFNkFCRTdBQkU5QUJFQUFCRUMiLAogICAgICAgIE1lOiAiMDQ4ODA0ODkyMERELTIwRTAyMEUyLTIwRTRBNjcwLUE2NzIiLAogICAgICAgIE46ICIwMDMwLTAwMzkwMEIyMDBCMzAwQjkwMEJDLTAwQkUwNjYwLTA2NjkwNkYwLTA2RjkwN0MwLTA3QzkwOTY2LTA5NkYwOUU2LTA5RUYwOUY0LTA5RjkwQTY2LTBBNkYwQUU2LTBBRUYwQjY2LTBCNkYwQjcyLTBCNzcwQkU2LTBCRjIwQzY2LTBDNkYwQzc4LTBDN0UwQ0U2LTBDRUYwRDY2LTBENzUwRTUwLTBFNTkwRUQwLTBFRDkwRjIwLTBGMzMxMDQwLTEwNDkxMDkwLTEwOTkxMzY5LTEzN0MxNkVFLTE2RjAxN0UwLTE3RTkxN0YwLTE3RjkxODEwLTE4MTkxOTQ2LTE5NEYxOUQwLTE5REExQTgwLTFBODkxQTkwLTFBOTkxQjUwLTFCNTkxQkIwLTFCQjkxQzQwLTFDNDkxQzUwLTFDNTkyMDcwMjA3NC0yMDc5MjA4MC0yMDg5MjE1MC0yMTgyMjE4NS0yMTg5MjQ2MC0yNDlCMjRFQS0yNEZGMjc3Ni0yNzkzMkNGRDMwMDczMDIxLTMwMjkzMDM4LTMwM0EzMTkyLTMxOTUzMjIwLTMyMjkzMjQ4LTMyNEYzMjUxLTMyNUYzMjgwLTMyODkzMkIxLTMyQkZBNjIwLUE2MjlBNkU2LUE2RUZBODMwLUE4MzVBOEQwLUE4RDlBOTAwLUE5MDlBOUQwLUE5RDlBQTUwLUFBNTlBQkYwLUFCRjlGRjEwLUZGMTkiLAogICAgICAgIE5kOiAiMDAzMC0wMDM5MDY2MC0wNjY5MDZGMC0wNkY5MDdDMC0wN0M5MDk2Ni0wOTZGMDlFNi0wOUVGMEE2Ni0wQTZGMEFFNi0wQUVGMEI2Ni0wQjZGMEJFNi0wQkVGMEM2Ni0wQzZGMENFNi0wQ0VGMEQ2Ni0wRDZGMEU1MC0wRTU5MEVEMC0wRUQ5MEYyMC0wRjI5MTA0MC0xMDQ5MTA5MC0xMDk5MTdFMC0xN0U5MTgxMC0xODE5MTk0Ni0xOTRGMTlEMC0xOUQ5MUE4MC0xQTg5MUE5MC0xQTk5MUI1MC0xQjU5MUJCMC0xQkI5MUM0MC0xQzQ5MUM1MC0xQzU5QTYyMC1BNjI5QThEMC1BOEQ5QTkwMC1BOTA5QTlEMC1BOUQ5QUE1MC1BQTU5QUJGMC1BQkY5RkYxMC1GRjE5IiwKICAgICAgICBObDogIjE2RUUtMTZGMDIxNjAtMjE4MjIxODUtMjE4ODMwMDczMDIxLTMwMjkzMDM4LTMwM0FBNkU2LUE2RUYiLAogICAgICAgIE5vOiAiMDBCMjAwQjMwMEI5MDBCQy0wMEJFMDlGNC0wOUY5MEI3Mi0wQjc3MEJGMC0wQkYyMEM3OC0wQzdFMEQ3MC0wRDc1MEYyQS0wRjMzMTM2OS0xMzdDMTdGMC0xN0Y5MTlEQTIwNzAyMDc0LTIwNzkyMDgwLTIwODkyMTUwLTIxNUYyMTg5MjQ2MC0yNDlCMjRFQS0yNEZGMjc3Ni0yNzkzMkNGRDMxOTItMzE5NTMyMjAtMzIyOTMyNDgtMzI0RjMyNTEtMzI1RjMyODAtMzI4OTMyQjEtMzJCRkE4MzAtQTgzNSIsCiAgICAgICAgUDogIjAwMjEtMDAyMzAwMjUtMDAyQTAwMkMtMDAyRjAwM0EwMDNCMDAzRjAwNDAwMDVCLTAwNUQwMDVGMDA3QjAwN0QwMEExMDBBNzAwQUIwMEI2MDBCNzAwQkIwMEJGMDM3RTAzODcwNTVBLTA1NUYwNTg5MDU4QTA1QkUwNUMwMDVDMzA1QzYwNUYzMDVGNDA2MDkwNjBBMDYwQzA2MEQwNjFCMDYxRTA2MUYwNjZBLTA2NkQwNkQ0MDcwMC0wNzBEMDdGNy0wN0Y5MDgzMC0wODNFMDg1RTA5NjQwOTY1MDk3MDBBRjAwREY0MEU0RjBFNUEwRTVCMEYwNC0wRjEyMEYxNDBGM0EtMEYzRDBGODUwRkQwLTBGRDQwRkQ5MEZEQTEwNEEtMTA0RjEwRkIxMzYwLTEzNjgxNDAwMTY2RDE2NkUxNjlCMTY5QzE2RUItMTZFRDE3MzUxNzM2MTdENC0xN0Q2MTdEOC0xN0RBMTgwMC0xODBBMTk0NDE5NDUxQTFFMUExRjFBQTAtMUFBNjFBQTgtMUFBRDFCNUEtMUI2MDFCRkMtMUJGRjFDM0ItMUMzRjFDN0UxQzdGMUNDMC0xQ0M3MUNEMzIwMTAtMjAyNzIwMzAtMjA0MzIwNDUtMjA1MTIwNTMtMjA1RTIwN0QyMDdFMjA4RDIwOEUyMzI5MjMyQTI3NjgtMjc3NTI3QzUyN0M2MjdFNi0yN0VGMjk4My0yOTk4MjlEOC0yOURCMjlGQzI5RkQyQ0Y5LTJDRkMyQ0ZFMkNGRjJENzAyRTAwLTJFMkUyRTMwLTJFM0IzMDAxLTMwMDMzMDA4LTMwMTEzMDE0LTMwMUYzMDMwMzAzRDMwQTAzMEZCQTRGRUE0RkZBNjBELUE2MEZBNjczQTY3RUE2RjItQTZGN0E4NzQtQTg3N0E4Q0VBOENGQThGOC1BOEZBQTkyRUE5MkZBOTVGQTlDMS1BOUNEQTlERUE5REZBQTVDLUFBNUZBQURFQUFERkFBRjBBQUYxQUJFQkZEM0VGRDNGRkUxMC1GRTE5RkUzMC1GRTUyRkU1NC1GRTYxRkU2M0ZFNjhGRTZBRkU2QkZGMDEtRkYwM0ZGMDUtRkYwQUZGMEMtRkYwRkZGMUFGRjFCRkYxRkZGMjBGRjNCLUZGM0RGRjNGRkY1QkZGNURGRjVGLUZGNjUiLAogICAgICAgIFBkOiAiMDAyRDA1OEEwNUJFMTQwMDE4MDYyMDEwLTIwMTUyRTE3MkUxQTJFM0EyRTNCMzAxQzMwMzAzMEEwRkUzMUZFMzJGRTU4RkU2M0ZGMEQiLAogICAgICAgIFBzOiAiMDAyODAwNUIwMDdCMEYzQTBGM0MxNjlCMjAxQTIwMUUyMDQ1MjA3RDIwOEQyMzI5Mjc2ODI3NkEyNzZDMjc2RTI3NzAyNzcyMjc3NDI3QzUyN0U2MjdFODI3RUEyN0VDMjdFRTI5ODMyOTg1Mjk4NzI5ODkyOThCMjk4RDI5OEYyOTkxMjk5MzI5OTUyOTk3MjlEODI5REEyOUZDMkUyMjJFMjQyRTI2MkUyODMwMDgzMDBBMzAwQzMwMEUzMDEwMzAxNDMwMTYzMDE4MzAxQTMwMURGRDNFRkUxN0ZFMzVGRTM3RkUzOUZFM0JGRTNERkUzRkZFNDFGRTQzRkU0N0ZFNTlGRTVCRkU1REZGMDhGRjNCRkY1QkZGNUZGRjYyIiwKICAgICAgICBQZTogIjAwMjkwMDVEMDA3RDBGM0IwRjNEMTY5QzIwNDYyMDdFMjA4RTIzMkEyNzY5Mjc2QjI3NkQyNzZGMjc3MTI3NzMyNzc1MjdDNjI3RTcyN0U5MjdFQjI3RUQyN0VGMjk4NDI5ODYyOTg4Mjk4QTI5OEMyOThFMjk5MDI5OTIyOTk0Mjk5NjI5OTgyOUQ5MjlEQjI5RkQyRTIzMkUyNTJFMjcyRTI5MzAwOTMwMEIzMDBEMzAwRjMwMTEzMDE1MzAxNzMwMTkzMDFCMzAxRTMwMUZGRDNGRkUxOEZFMzZGRTM4RkUzQUZFM0NGRTNFRkU0MEZFNDJGRTQ0RkU0OEZFNUFGRTVDRkU1RUZGMDlGRjNERkY1REZGNjBGRjYzIiwKICAgICAgICBQaTogIjAwQUIyMDE4MjAxQjIwMUMyMDFGMjAzOTJFMDIyRTA0MkUwOTJFMEMyRTFDMkUyMCIsCiAgICAgICAgUGY6ICIwMEJCMjAxOTIwMUQyMDNBMkUwMzJFMDUyRTBBMkUwRDJFMUQyRTIxIiwKICAgICAgICBQYzogIjAwNUYyMDNGMjA0MDIwNTRGRTMzRkUzNEZFNEQtRkU0RkZGM0YiLAogICAgICAgIFBvOiAiMDAyMS0wMDIzMDAyNS0wMDI3MDAyQTAwMkMwMDJFMDAyRjAwM0EwMDNCMDAzRjAwNDAwMDVDMDBBMTAwQTcwMEI2MDBCNzAwQkYwMzdFMDM4NzA1NUEtMDU1RjA1ODkwNUMwMDVDMzA1QzYwNUYzMDVGNDA2MDkwNjBBMDYwQzA2MEQwNjFCMDYxRTA2MUYwNjZBLTA2NkQwNkQ0MDcwMC0wNzBEMDdGNy0wN0Y5MDgzMC0wODNFMDg1RTA5NjQwOTY1MDk3MDBBRjAwREY0MEU0RjBFNUEwRTVCMEYwNC0wRjEyMEYxNDBGODUwRkQwLTBGRDQwRkQ5MEZEQTEwNEEtMTA0RjEwRkIxMzYwLTEzNjgxNjZEMTY2RTE2RUItMTZFRDE3MzUxNzM2MTdENC0xN0Q2MTdEOC0xN0RBMTgwMC0xODA1MTgwNy0xODBBMTk0NDE5NDUxQTFFMUExRjFBQTAtMUFBNjFBQTgtMUFBRDFCNUEtMUI2MDFCRkMtMUJGRjFDM0ItMUMzRjFDN0UxQzdGMUNDMC0xQ0M3MUNEMzIwMTYyMDE3MjAyMC0yMDI3MjAzMC0yMDM4MjAzQi0yMDNFMjA0MS0yMDQzMjA0Ny0yMDUxMjA1MzIwNTUtMjA1RTJDRjktMkNGQzJDRkUyQ0ZGMkQ3MDJFMDAyRTAxMkUwNi0yRTA4MkUwQjJFMEUtMkUxNjJFMTgyRTE5MkUxQjJFMUUyRTFGMkUyQS0yRTJFMkUzMC0yRTM5MzAwMS0zMDAzMzAzRDMwRkJBNEZFQTRGRkE2MEQtQTYwRkE2NzNBNjdFQTZGMi1BNkY3QTg3NC1BODc3QThDRUE4Q0ZBOEY4LUE4RkFBOTJFQTkyRkE5NUZBOUMxLUE5Q0RBOURFQTlERkFBNUMtQUE1RkFBREVBQURGQUFGMEFBRjFBQkVCRkUxMC1GRTE2RkUxOUZFMzBGRTQ1RkU0NkZFNDktRkU0Q0ZFNTAtRkU1MkZFNTQtRkU1N0ZFNUYtRkU2MUZFNjhGRTZBRkU2QkZGMDEtRkYwM0ZGMDUtRkYwN0ZGMEFGRjBDRkYwRUZGMEZGRjFBRkYxQkZGMUZGRjIwRkYzQ0ZGNjFGRjY0RkY2NSIsCiAgICAgICAgUzogIjAwMjQwMDJCMDAzQy0wMDNFMDA1RTAwNjAwMDdDMDA3RTAwQTItMDBBNjAwQTgwMEE5MDBBQzAwQUUtMDBCMTAwQjQwMEI4MDBENzAwRjcwMkMyLTAyQzUwMkQyLTAyREYwMkU1LTAyRUIwMkVEMDJFRi0wMkZGMDM3NTAzODQwMzg1MDNGNjA0ODIwNThGMDYwNi0wNjA4MDYwQjA2MEUwNjBGMDZERTA2RTkwNkZEMDZGRTA3RjYwOUYyMDlGMzA5RkEwOUZCMEFGMTBCNzAwQkYzLTBCRkEwQzdGMEQ3OTBFM0YwRjAxLTBGMDMwRjEzMEYxNS0wRjE3MEYxQS0wRjFGMEYzNDBGMzYwRjM4MEZCRS0wRkM1MEZDNy0wRkNDMEZDRTBGQ0YwRkQ1LTBGRDgxMDlFMTA5RjEzOTAtMTM5OTE3REIxOTQwMTlERS0xOUZGMUI2MS0xQjZBMUI3NC0xQjdDMUZCRDFGQkYtMUZDMTFGQ0QtMUZDRjFGREQtMUZERjFGRUQtMUZFRjFGRkQxRkZFMjA0NDIwNTIyMDdBLTIwN0MyMDhBLTIwOEMyMEEwLTIwQjkyMTAwMjEwMTIxMDMtMjEwNjIxMDgyMTA5MjExNDIxMTYtMjExODIxMUUtMjEyMzIxMjUyMTI3MjEyOTIxMkUyMTNBMjEzQjIxNDAtMjE0NDIxNEEtMjE0RDIxNEYyMTkwLTIzMjgyMzJCLTIzRjMyNDAwLTI0MjYyNDQwLTI0NEEyNDlDLTI0RTkyNTAwLTI2RkYyNzAxLTI3NjcyNzk0LTI3QzQyN0M3LTI3RTUyN0YwLTI5ODIyOTk5LTI5RDcyOURDLTI5RkIyOUZFLTJCNEMyQjUwLTJCNTkyQ0U1LTJDRUEyRTgwLTJFOTkyRTlCLTJFRjMyRjAwLTJGRDUyRkYwLTJGRkIzMDA0MzAxMjMwMTMzMDIwMzAzNjMwMzczMDNFMzAzRjMwOUIzMDlDMzE5MDMxOTEzMTk2LTMxOUYzMUMwLTMxRTMzMjAwLTMyMUUzMjJBLTMyNDczMjUwMzI2MC0zMjdGMzI4QS0zMkIwMzJDMC0zMkZFMzMwMC0zM0ZGNERDMC00REZGQTQ5MC1BNEM2QTcwMC1BNzE2QTcyMEE3MjFBNzg5QTc4QUE4MjgtQTgyQkE4MzYtQTgzOUFBNzctQUE3OUZCMjlGQkIyLUZCQzFGREZDRkRGREZFNjJGRTY0LUZFNjZGRTY5RkYwNEZGMEJGRjFDLUZGMUVGRjNFRkY0MEZGNUNGRjVFRkZFMC1GRkU2RkZFOC1GRkVFRkZGQ0ZGRkQiLAogICAgICAgIFNtOiAiMDAyQjAwM0MtMDAzRTAwN0MwMDdFMDBBQzAwQjEwMEQ3MDBGNzAzRjYwNjA2LTA2MDgyMDQ0MjA1MjIwN0EtMjA3QzIwOEEtMjA4QzIxMTgyMTQwLTIxNDQyMTRCMjE5MC0yMTk0MjE5QTIxOUIyMUEwMjFBMzIxQTYyMUFFMjFDRTIxQ0YyMUQyMjFENDIxRjQtMjJGRjIzMDgtMjMwQjIzMjAyMzIxMjM3QzIzOUItMjNCMzIzREMtMjNFMTI1QjcyNUMxMjVGOC0yNUZGMjY2RjI3QzAtMjdDNDI3QzctMjdFNTI3RjAtMjdGRjI5MDAtMjk4MjI5OTktMjlENzI5REMtMjlGQjI5RkUtMkFGRjJCMzAtMkI0NDJCNDctMkI0Q0ZCMjlGRTYyRkU2NC1GRTY2RkYwQkZGMUMtRkYxRUZGNUNGRjVFRkZFMkZGRTktRkZFQyIsCiAgICAgICAgU2M6ICIwMDI0MDBBMi0wMEE1MDU4RjA2MEIwOUYyMDlGMzA5RkIwQUYxMEJGOTBFM0YxN0RCMjBBMC0yMEI5QTgzOEZERkNGRTY5RkYwNEZGRTBGRkUxRkZFNUZGRTYiLAogICAgICAgIFNrOiAiMDA1RTAwNjAwMEE4MDBBRjAwQjQwMEI4MDJDMi0wMkM1MDJEMi0wMkRGMDJFNS0wMkVCMDJFRDAyRUYtMDJGRjAzNzUwMzg0MDM4NTFGQkQxRkJGLTFGQzExRkNELTFGQ0YxRkRELTFGREYxRkVELTFGRUYxRkZEMUZGRTMwOUIzMDlDQTcwMC1BNzE2QTcyMEE3MjFBNzg5QTc4QUZCQjItRkJDMUZGM0VGRjQwRkZFMyIsCiAgICAgICAgU286ICIwMEE2MDBBOTAwQUUwMEIwMDQ4MjA2MEUwNjBGMDZERTA2RTkwNkZEMDZGRTA3RjYwOUZBMEI3MDBCRjMtMEJGODBCRkEwQzdGMEQ3OTBGMDEtMEYwMzBGMTMwRjE1LTBGMTcwRjFBLTBGMUYwRjM0MEYzNjBGMzgwRkJFLTBGQzUwRkM3LTBGQ0MwRkNFMEZDRjBGRDUtMEZEODEwOUUxMDlGMTM5MC0xMzk5MTk0MDE5REUtMTlGRjFCNjEtMUI2QTFCNzQtMUI3QzIxMDAyMTAxMjEwMy0yMTA2MjEwODIxMDkyMTE0MjExNjIxMTcyMTFFLTIxMjMyMTI1MjEyNzIxMjkyMTJFMjEzQTIxM0IyMTRBMjE0QzIxNEQyMTRGMjE5NS0yMTk5MjE5Qy0yMTlGMjFBMTIxQTIyMUE0MjFBNTIxQTctMjFBRDIxQUYtMjFDRDIxRDAyMUQxMjFEMzIxRDUtMjFGMzIzMDAtMjMwNzIzMEMtMjMxRjIzMjItMjMyODIzMkItMjM3QjIzN0QtMjM5QTIzQjQtMjNEQjIzRTItMjNGMzI0MDAtMjQyNjI0NDAtMjQ0QTI0OUMtMjRFOTI1MDAtMjVCNjI1QjgtMjVDMDI1QzItMjVGNzI2MDAtMjY2RTI2NzAtMjZGRjI3MDEtMjc2NzI3OTQtMjdCRjI4MDAtMjhGRjJCMDAtMkIyRjJCNDUyQjQ2MkI1MC0yQjU5MkNFNS0yQ0VBMkU4MC0yRTk5MkU5Qi0yRUYzMkYwMC0yRkQ1MkZGMC0yRkZCMzAwNDMwMTIzMDEzMzAyMDMwMzYzMDM3MzAzRTMwM0YzMTkwMzE5MTMxOTYtMzE5RjMxQzAtMzFFMzMyMDAtMzIxRTMyMkEtMzI0NzMyNTAzMjYwLTMyN0YzMjhBLTMyQjAzMkMwLTMyRkUzMzAwLTMzRkY0REMwLTRERkZBNDkwLUE0QzZBODI4LUE4MkJBODM2QTgzN0E4MzlBQTc3LUFBNzlGREZERkZFNEZGRThGRkVERkZFRUZGRkNGRkZEIiwKICAgICAgICBaOiAiMDAyMDAwQTAxNjgwMTgwRTIwMDAtMjAwQTIwMjgyMDI5MjAyRjIwNUYzMDAwIiwKICAgICAgICBaczogIjAwMjAwMEEwMTY4MDE4MEUyMDAwLTIwMEEyMDJGMjA1RjMwMDAiLAogICAgICAgIFpsOiAiMjAyOCIsCiAgICAgICAgWnA6ICIyMDI5IiwKICAgICAgICBDOiAiMDAwMC0wMDFGMDA3Ri0wMDlGMDBBRDAzNzgwMzc5MDM3Ri0wMzgzMDM4QjAzOEQwM0EyMDUyOC0wNTMwMDU1NzA1NTgwNTYwMDU4ODA1OEItMDU4RTA1OTAwNUM4LTA1Q0YwNUVCLTA1RUYwNUY1LTA2MDUwNjFDMDYxRDA2REQwNzBFMDcwRjA3NEIwNzRDMDdCMi0wN0JGMDdGQi0wN0ZGMDgyRTA4MkYwODNGMDg1QzA4NUQwODVGLTA4OUYwOEExMDhBRC0wOEUzMDhGRjA5NzgwOTgwMDk4NDA5OEQwOThFMDk5MTA5OTIwOUE5MDlCMTA5QjMtMDlCNTA5QkEwOUJCMDlDNTA5QzYwOUM5MDlDQTA5Q0YtMDlENjA5RDgtMDlEQjA5REUwOUU0MDlFNTA5RkMtMEEwMDBBMDQwQTBCLTBBMEUwQTExMEExMjBBMjkwQTMxMEEzNDBBMzcwQTNBMEEzQjBBM0QwQTQzLTBBNDYwQTQ5MEE0QTBBNEUtMEE1MDBBNTItMEE1ODBBNUQwQTVGLTBBNjUwQTc2LTBBODAwQTg0MEE4RTBBOTIwQUE5MEFCMTBBQjQwQUJBMEFCQjBBQzYwQUNBMEFDRTBBQ0YwQUQxLTBBREYwQUU0MEFFNTBBRjItMEIwMDBCMDQwQjBEMEIwRTBCMTEwQjEyMEIyOTBCMzEwQjM0MEIzQTBCM0IwQjQ1MEI0NjBCNDkwQjRBMEI0RS0wQjU1MEI1OC0wQjVCMEI1RTBCNjQwQjY1MEI3OC0wQjgxMEI4NDBCOEItMEI4RDBCOTEwQjk2LTBCOTgwQjlCMEI5RDBCQTAtMEJBMjBCQTUtMEJBNzBCQUItMEJBRDBCQkEtMEJCRDBCQzMtMEJDNTBCQzkwQkNFMEJDRjBCRDEtMEJENjBCRDgtMEJFNTBCRkItMEMwMDBDMDQwQzBEMEMxMTBDMjkwQzM0MEMzQS0wQzNDMEM0NTBDNDkwQzRFLTBDNTQwQzU3MEM1QS0wQzVGMEM2NDBDNjUwQzcwLTBDNzcwQzgwMEM4MTBDODQwQzhEMEM5MTBDQTkwQ0I0MENCQTBDQkIwQ0M1MENDOTBDQ0UtMENENDBDRDctMENERDBDREYwQ0U0MENFNTBDRjAwQ0YzLTBEMDEwRDA0MEQwRDBEMTEwRDNCMEQzQzBENDUwRDQ5MEQ0Ri0wRDU2MEQ1OC0wRDVGMEQ2NDBENjUwRDc2LTBENzgwRDgwMEQ4MTBEODQwRDk3LTBEOTkwREIyMERCQzBEQkUwREJGMERDNy0wREM5MERDQi0wRENFMERENTBERDcwREUwLTBERjEwREY1LTBFMDAwRTNCLTBFM0UwRTVDLTBFODAwRTgzMEU4NTBFODYwRTg5MEU4QjBFOEMwRThFLTBFOTMwRTk4MEVBMDBFQTQwRUE2MEVBODBFQTkwRUFDMEVCQTBFQkUwRUJGMEVDNTBFQzcwRUNFMEVDRjBFREEwRURCMEVFMC0wRUZGMEY0ODBGNkQtMEY3MDBGOTgwRkJEMEZDRDBGREItMEZGRjEwQzYxMEM4LTEwQ0MxMENFMTBDRjEyNDkxMjRFMTI0RjEyNTcxMjU5MTI1RTEyNUYxMjg5MTI4RTEyOEYxMkIxMTJCNjEyQjcxMkJGMTJDMTEyQzYxMkM3MTJENzEzMTExMzE2MTMxNzEzNUIxMzVDMTM3RC0xMzdGMTM5QS0xMzlGMTNGNS0xM0ZGMTY5RC0xNjlGMTZGMS0xNkZGMTcwRDE3MTUtMTcxRjE3MzctMTczRjE3NTQtMTc1RjE3NkQxNzcxMTc3NC0xNzdGMTdERTE3REYxN0VBLTE3RUYxN0ZBLTE3RkYxODBGMTgxQS0xODFGMTg3OC0xODdGMThBQi0xOEFGMThGNi0xOEZGMTkxRC0xOTFGMTkyQy0xOTJGMTkzQy0xOTNGMTk0MS0xOTQzMTk2RTE5NkYxOTc1LTE5N0YxOUFDLTE5QUYxOUNBLTE5Q0YxOURCLTE5REQxQTFDMUExRDFBNUYxQTdEMUE3RTFBOEEtMUE4RjFBOUEtMUE5RjFBQUUtMUFGRjFCNEMtMUI0RjFCN0QtMUI3RjFCRjQtMUJGQjFDMzgtMUMzQTFDNEEtMUM0QzFDODAtMUNCRjFDQzgtMUNDRjFDRjctMUNGRjFERTctMURGQjFGMTYxRjE3MUYxRTFGMUYxRjQ2MUY0NzFGNEUxRjRGMUY1ODFGNUExRjVDMUY1RTFGN0UxRjdGMUZCNTFGQzUxRkQ0MUZENTFGREMxRkYwMUZGMTFGRjUxRkZGMjAwQi0yMDBGMjAyQS0yMDJFMjA2MC0yMDZGMjA3MjIwNzMyMDhGMjA5RC0yMDlGMjBCQS0yMENGMjBGMS0yMEZGMjE4QS0yMThGMjNGNC0yM0ZGMjQyNy0yNDNGMjQ0Qi0yNDVGMjcwMDJCNEQtMkI0RjJCNUEtMkJGRjJDMkYyQzVGMkNGNC0yQ0Y4MkQyNjJEMjgtMkQyQzJEMkUyRDJGMkQ2OC0yRDZFMkQ3MS0yRDdFMkQ5Ny0yRDlGMkRBNzJEQUYyREI3MkRCRjJEQzcyRENGMkRENzJEREYyRTNDLTJFN0YyRTlBMkVGNC0yRUZGMkZENi0yRkVGMkZGQy0yRkZGMzA0MDMwOTczMDk4MzEwMC0zMTA0MzEyRS0zMTMwMzE4RjMxQkItMzFCRjMxRTQtMzFFRjMyMUYzMkZGNERCNi00REJGOUZDRC05RkZGQTQ4RC1BNDhGQTRDNy1BNENGQTYyQy1BNjNGQTY5OC1BNjlFQTZGOC1BNkZGQTc4RkE3OTQtQTc5RkE3QUItQTdGN0E4MkMtQTgyRkE4M0EtQTgzRkE4NzgtQTg3RkE4QzUtQThDREE4REEtQThERkE4RkMtQThGRkE5NTQtQTk1RUE5N0QtQTk3RkE5Q0VBOURBLUE5RERBOUUwLUE5RkZBQTM3LUFBM0ZBQTRFQUE0RkFBNUFBQTVCQUE3Qy1BQTdGQUFDMy1BQURBQUFGNy1BQjAwQUIwN0FCMDhBQjBGQUIxMEFCMTctQUIxRkFCMjdBQjJGLUFCQkZBQkVFQUJFRkFCRkEtQUJGRkQ3QTQtRDdBRkQ3QzctRDdDQUQ3RkMtRjhGRkZBNkVGQTZGRkFEQS1GQUZGRkIwNy1GQjEyRkIxOC1GQjFDRkIzN0ZCM0RGQjNGRkI0MkZCNDVGQkMyLUZCRDJGRDQwLUZENEZGRDkwRkQ5MUZEQzgtRkRFRkZERkVGREZGRkUxQS1GRTFGRkUyNy1GRTJGRkU1M0ZFNjdGRTZDLUZFNkZGRTc1RkVGRC1GRjAwRkZCRi1GRkMxRkZDOEZGQzlGRkQwRkZEMUZGRDhGRkQ5RkZERC1GRkRGRkZFN0ZGRUYtRkZGQkZGRkVGRkZGIiwKICAgICAgICBDYzogIjAwMDAtMDAxRjAwN0YtMDA5RiIsCiAgICAgICAgQ2Y6ICIwMEFEMDYwMC0wNjA0MDZERDA3MEYyMDBCLTIwMEYyMDJBLTIwMkUyMDYwLTIwNjQyMDZBLTIwNkZGRUZGRkZGOS1GRkZCIiwKICAgICAgICBDbzogIkUwMDAtRjhGRiIsCiAgICAgICAgQ3M6ICJEODAwLURGRkYiLAogICAgICAgIENuOiAiMDM3ODAzNzkwMzdGLTAzODMwMzhCMDM4RDAzQTIwNTI4LTA1MzAwNTU3MDU1ODA1NjAwNTg4MDU4Qi0wNThFMDU5MDA1QzgtMDVDRjA1RUItMDVFRjA1RjUtMDVGRjA2MDUwNjFDMDYxRDA3MEUwNzRCMDc0QzA3QjItMDdCRjA3RkItMDdGRjA4MkUwODJGMDgzRjA4NUMwODVEMDg1Ri0wODlGMDhBMTA4QUQtMDhFMzA4RkYwOTc4MDk4MDA5ODQwOThEMDk4RTA5OTEwOTkyMDlBOTA5QjEwOUIzLTA5QjUwOUJBMDlCQjA5QzUwOUM2MDlDOTA5Q0EwOUNGLTA5RDYwOUQ4LTA5REIwOURFMDlFNDA5RTUwOUZDLTBBMDAwQTA0MEEwQi0wQTBFMEExMTBBMTIwQTI5MEEzMTBBMzQwQTM3MEEzQTBBM0IwQTNEMEE0My0wQTQ2MEE0OTBBNEEwQTRFLTBBNTAwQTUyLTBBNTgwQTVEMEE1Ri0wQTY1MEE3Ni0wQTgwMEE4NDBBOEUwQTkyMEFBOTBBQjEwQUI0MEFCQTBBQkIwQUM2MEFDQTBBQ0UwQUNGMEFEMS0wQURGMEFFNDBBRTUwQUYyLTBCMDAwQjA0MEIwRDBCMEUwQjExMEIxMjBCMjkwQjMxMEIzNDBCM0EwQjNCMEI0NTBCNDYwQjQ5MEI0QTBCNEUtMEI1NTBCNTgtMEI1QjBCNUUwQjY0MEI2NTBCNzgtMEI4MTBCODQwQjhCLTBCOEQwQjkxMEI5Ni0wQjk4MEI5QjBCOUQwQkEwLTBCQTIwQkE1LTBCQTcwQkFCLTBCQUQwQkJBLTBCQkQwQkMzLTBCQzUwQkM5MEJDRTBCQ0YwQkQxLTBCRDYwQkQ4LTBCRTUwQkZCLTBDMDAwQzA0MEMwRDBDMTEwQzI5MEMzNDBDM0EtMEMzQzBDNDUwQzQ5MEM0RS0wQzU0MEM1NzBDNUEtMEM1RjBDNjQwQzY1MEM3MC0wQzc3MEM4MDBDODEwQzg0MEM4RDBDOTEwQ0E5MENCNDBDQkEwQ0JCMENDNTBDQzkwQ0NFLTBDRDQwQ0Q3LTBDREQwQ0RGMENFNDBDRTUwQ0YwMENGMy0wRDAxMEQwNDBEMEQwRDExMEQzQjBEM0MwRDQ1MEQ0OTBENEYtMEQ1NjBENTgtMEQ1RjBENjQwRDY1MEQ3Ni0wRDc4MEQ4MDBEODEwRDg0MEQ5Ny0wRDk5MERCMjBEQkMwREJFMERCRjBEQzctMERDOTBEQ0ItMERDRTBERDUwREQ3MERFMC0wREYxMERGNS0wRTAwMEUzQi0wRTNFMEU1Qy0wRTgwMEU4MzBFODUwRTg2MEU4OTBFOEIwRThDMEU4RS0wRTkzMEU5ODBFQTAwRUE0MEVBNjBFQTgwRUE5MEVBQzBFQkEwRUJFMEVCRjBFQzUwRUM3MEVDRTBFQ0YwRURBMEVEQjBFRTAtMEVGRjBGNDgwRjZELTBGNzAwRjk4MEZCRDBGQ0QwRkRCLTBGRkYxMEM2MTBDOC0xMENDMTBDRTEwQ0YxMjQ5MTI0RTEyNEYxMjU3MTI1OTEyNUUxMjVGMTI4OTEyOEUxMjhGMTJCMTEyQjYxMkI3MTJCRjEyQzExMkM2MTJDNzEyRDcxMzExMTMxNjEzMTcxMzVCMTM1QzEzN0QtMTM3RjEzOUEtMTM5RjEzRjUtMTNGRjE2OUQtMTY5RjE2RjEtMTZGRjE3MEQxNzE1LTE3MUYxNzM3LTE3M0YxNzU0LTE3NUYxNzZEMTc3MTE3NzQtMTc3RjE3REUxN0RGMTdFQS0xN0VGMTdGQS0xN0ZGMTgwRjE4MUEtMTgxRjE4NzgtMTg3RjE4QUItMThBRjE4RjYtMThGRjE5MUQtMTkxRjE5MkMtMTkyRjE5M0MtMTkzRjE5NDEtMTk0MzE5NkUxOTZGMTk3NS0xOTdGMTlBQy0xOUFGMTlDQS0xOUNGMTlEQi0xOUREMUExQzFBMUQxQTVGMUE3RDFBN0UxQThBLTFBOEYxQTlBLTFBOUYxQUFFLTFBRkYxQjRDLTFCNEYxQjdELTFCN0YxQkY0LTFCRkIxQzM4LTFDM0ExQzRBLTFDNEMxQzgwLTFDQkYxQ0M4LTFDQ0YxQ0Y3LTFDRkYxREU3LTFERkIxRjE2MUYxNzFGMUUxRjFGMUY0NjFGNDcxRjRFMUY0RjFGNTgxRjVBMUY1QzFGNUUxRjdFMUY3RjFGQjUxRkM1MUZENDFGRDUxRkRDMUZGMDFGRjExRkY1MUZGRjIwNjUtMjA2OTIwNzIyMDczMjA4RjIwOUQtMjA5RjIwQkEtMjBDRjIwRjEtMjBGRjIxOEEtMjE4RjIzRjQtMjNGRjI0MjctMjQzRjI0NEItMjQ1RjI3MDAyQjRELTJCNEYyQjVBLTJCRkYyQzJGMkM1RjJDRjQtMkNGODJEMjYyRDI4LTJEMkMyRDJFMkQyRjJENjgtMkQ2RTJENzEtMkQ3RTJEOTctMkQ5RjJEQTcyREFGMkRCNzJEQkYyREM3MkRDRjJERDcyRERGMkUzQy0yRTdGMkU5QTJFRjQtMkVGRjJGRDYtMkZFRjJGRkMtMkZGRjMwNDAzMDk3MzA5ODMxMDAtMzEwNDMxMkUtMzEzMDMxOEYzMUJCLTMxQkYzMUU0LTMxRUYzMjFGMzJGRjREQjYtNERCRjlGQ0QtOUZGRkE0OEQtQTQ4RkE0QzctQTRDRkE2MkMtQTYzRkE2OTgtQTY5RUE2RjgtQTZGRkE3OEZBNzk0LUE3OUZBN0FCLUE3RjdBODJDLUE4MkZBODNBLUE4M0ZBODc4LUE4N0ZBOEM1LUE4Q0RBOERBLUE4REZBOEZDLUE4RkZBOTU0LUE5NUVBOTdELUE5N0ZBOUNFQTlEQS1BOUREQTlFMC1BOUZGQUEzNy1BQTNGQUE0RUFBNEZBQTVBQUE1QkFBN0MtQUE3RkFBQzMtQUFEQUFBRjctQUIwMEFCMDdBQjA4QUIwRkFCMTBBQjE3LUFCMUZBQjI3QUIyRi1BQkJGQUJFRUFCRUZBQkZBLUFCRkZEN0E0LUQ3QUZEN0M3LUQ3Q0FEN0ZDLUQ3RkZGQTZFRkE2RkZBREEtRkFGRkZCMDctRkIxMkZCMTgtRkIxQ0ZCMzdGQjNERkIzRkZCNDJGQjQ1RkJDMi1GQkQyRkQ0MC1GRDRGRkQ5MEZEOTFGREM4LUZERUZGREZFRkRGRkZFMUEtRkUxRkZFMjctRkUyRkZFNTNGRTY3RkU2Qy1GRTZGRkU3NUZFRkRGRUZFRkYwMEZGQkYtRkZDMUZGQzhGRkM5RkZEMEZGRDFGRkQ4RkZEOUZGREQtRkZERkZGRTdGRkVGLUZGRjhGRkZFRkZGRiIKICAgIH0sIHsKICAgICAgICAvL0w6ICJMZXR0ZXIiLCAvLyBJbmNsdWRlZCBpbiB0aGUgVW5pY29kZSBCYXNlIGFkZG9uCiAgICAgICAgTGw6ICJMb3dlcmNhc2VfTGV0dGVyIiwKICAgICAgICBMdTogIlVwcGVyY2FzZV9MZXR0ZXIiLAogICAgICAgIEx0OiAiVGl0bGVjYXNlX0xldHRlciIsCiAgICAgICAgTG06ICJNb2RpZmllcl9MZXR0ZXIiLAogICAgICAgIExvOiAiT3RoZXJfTGV0dGVyIiwKICAgICAgICBNOiAiTWFyayIsCiAgICAgICAgTW46ICJOb25zcGFjaW5nX01hcmsiLAogICAgICAgIE1jOiAiU3BhY2luZ19NYXJrIiwKICAgICAgICBNZTogIkVuY2xvc2luZ19NYXJrIiwKICAgICAgICBOOiAiTnVtYmVyIiwKICAgICAgICBOZDogIkRlY2ltYWxfTnVtYmVyIiwKICAgICAgICBObDogIkxldHRlcl9OdW1iZXIiLAogICAgICAgIE5vOiAiT3RoZXJfTnVtYmVyIiwKICAgICAgICBQOiAiUHVuY3R1YXRpb24iLAogICAgICAgIFBkOiAiRGFzaF9QdW5jdHVhdGlvbiIsCiAgICAgICAgUHM6ICJPcGVuX1B1bmN0dWF0aW9uIiwKICAgICAgICBQZTogIkNsb3NlX1B1bmN0dWF0aW9uIiwKICAgICAgICBQaTogIkluaXRpYWxfUHVuY3R1YXRpb24iLAogICAgICAgIFBmOiAiRmluYWxfUHVuY3R1YXRpb24iLAogICAgICAgIFBjOiAiQ29ubmVjdG9yX1B1bmN0dWF0aW9uIiwKICAgICAgICBQbzogIk90aGVyX1B1bmN0dWF0aW9uIiwKICAgICAgICBTOiAiU3ltYm9sIiwKICAgICAgICBTbTogIk1hdGhfU3ltYm9sIiwKICAgICAgICBTYzogIkN1cnJlbmN5X1N5bWJvbCIsCiAgICAgICAgU2s6ICJNb2RpZmllcl9TeW1ib2wiLAogICAgICAgIFNvOiAiT3RoZXJfU3ltYm9sIiwKICAgICAgICBaOiAiU2VwYXJhdG9yIiwKICAgICAgICBaczogIlNwYWNlX1NlcGFyYXRvciIsCiAgICAgICAgWmw6ICJMaW5lX1NlcGFyYXRvciIsCiAgICAgICAgWnA6ICJQYXJhZ3JhcGhfU2VwYXJhdG9yIiwKICAgICAgICBDOiAiT3RoZXIiLAogICAgICAgIENjOiAiQ29udHJvbCIsCiAgICAgICAgQ2Y6ICJGb3JtYXQiLAogICAgICAgIENvOiAiUHJpdmF0ZV9Vc2UiLAogICAgICAgIENzOiAiU3Vycm9nYXRlIiwKICAgICAgICBDbjogIlVuYXNzaWduZWQiCiAgICB9KTsKCn0oWFJlZ0V4cCkpOwoKCi8qKioqKiB1bmljb2RlLXNjcmlwdHMuanMgKioqKiovCgovKiEKICogWFJlZ0V4cCBVbmljb2RlIFNjcmlwdHMgdjEuMi4wCiAqIChjKSAyMDEwLTIwMTIgU3RldmVuIExldml0aGFuIDxodHRwOi8veHJlZ2V4cC5jb20vPgogKiBNSVQgTGljZW5zZQogKiBVc2VzIFVuaWNvZGUgNi4xIDxodHRwOi8vdW5pY29kZS5vcmcvPgogKi8KCi8qKgogKiBBZGRzIHN1cHBvcnQgZm9yIGFsbCBVbmljb2RlIHNjcmlwdHMgaW4gdGhlIEJhc2ljIE11bHRpbGluZ3VhbCBQbGFuZSAoVSswMDAwLVUrRkZGRikuCiAqIEUuZy4sIGBccHtMYXRpbn1gLiBUb2tlbiBuYW1lcyBhcmUgY2FzZSBpbnNlbnNpdGl2ZSwgYW5kIGFueSBzcGFjZXMsIGh5cGhlbnMsIGFuZCB1bmRlcnNjb3JlcwogKiBhcmUgaWdub3JlZC4KICogQHJlcXVpcmVzIFhSZWdFeHAsIFhSZWdFeHAgVW5pY29kZSBCYXNlCiAqLwooZnVuY3Rpb24gKFhSZWdFeHApIHsKICAgICJ1c2Ugc3RyaWN0IjsKCiAgICBpZiAoIVhSZWdFeHAuYWRkVW5pY29kZVBhY2thZ2UpIHsKICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoIlVuaWNvZGUgQmFzZSBtdXN0IGJlIGxvYWRlZCBiZWZvcmUgVW5pY29kZSBTY3JpcHRzIik7CiAgICB9CgogICAgWFJlZ0V4cC5pbnN0YWxsKCJleHRlbnNpYmlsaXR5Iik7CgogICAgWFJlZ0V4cC5hZGRVbmljb2RlUGFja2FnZSh7CiAgICAgICAgQXJhYmljOiAiMDYwMC0wNjA0MDYwNi0wNjBCMDYwRC0wNjFBMDYxRTA2MjAtMDYzRjA2NDEtMDY0QTA2NTYtMDY1RTA2NkEtMDY2RjA2NzEtMDZEQzA2REUtMDZGRjA3NTAtMDc3RjA4QTAwOEEyLTA4QUMwOEU0LTA4RkVGQjUwLUZCQzFGQkQzLUZEM0RGRDUwLUZEOEZGRDkyLUZEQzdGREYwLUZERkNGRTcwLUZFNzRGRTc2LUZFRkMiLAogICAgICAgIEFybWVuaWFuOiAiMDUzMS0wNTU2MDU1OS0wNTVGMDU2MS0wNTg3MDU4QTA1OEZGQjEzLUZCMTciLAogICAgICAgIEJhbGluZXNlOiAiMUIwMC0xQjRCMUI1MC0xQjdDIiwKICAgICAgICBCYW11bTogIkE2QTAtQTZGNyIsCiAgICAgICAgQmF0YWs6ICIxQkMwLTFCRjMxQkZDLTFCRkYiLAogICAgICAgIEJlbmdhbGk6ICIwOTgxLTA5ODMwOTg1LTA5OEMwOThGMDk5MDA5OTMtMDlBODA5QUEtMDlCMDA5QjIwOUI2LTA5QjkwOUJDLTA5QzQwOUM3MDlDODA5Q0ItMDlDRTA5RDcwOURDMDlERDA5REYtMDlFMzA5RTYtMDlGQiIsCiAgICAgICAgQm9wb21vZm86ICIwMkVBMDJFQjMxMDUtMzEyRDMxQTAtMzFCQSIsCiAgICAgICAgQnJhaWxsZTogIjI4MDAtMjhGRiIsCiAgICAgICAgQnVnaW5lc2U6ICIxQTAwLTFBMUIxQTFFMUExRiIsCiAgICAgICAgQnVoaWQ6ICIxNzQwLTE3NTMiLAogICAgICAgIENhbmFkaWFuX0Fib3JpZ2luYWw6ICIxNDAwLTE2N0YxOEIwLTE4RjUiLAogICAgICAgIENoYW06ICJBQTAwLUFBMzZBQTQwLUFBNERBQTUwLUFBNTlBQTVDLUFBNUYiLAogICAgICAgIENoZXJva2VlOiAiMTNBMC0xM0Y0IiwKICAgICAgICBDb21tb246ICIwMDAwLTAwNDAwMDVCLTAwNjAwMDdCLTAwQTkwMEFCLTAwQjkwMEJCLTAwQkYwMEQ3MDBGNzAyQjktMDJERjAyRTUtMDJFOTAyRUMtMDJGRjAzNzQwMzdFMDM4NTAzODcwNTg5MDYwQzA2MUIwNjFGMDY0MDA2NjAtMDY2OTA2REQwOTY0MDk2NTBFM0YwRkQ1LTBGRDgxMEZCMTZFQi0xNkVEMTczNTE3MzYxODAyMTgwMzE4MDUxQ0QzMUNFMTFDRTktMUNFQzFDRUUtMUNGMzFDRjUxQ0Y2MjAwMC0yMDBCMjAwRS0yMDY0MjA2QS0yMDcwMjA3NC0yMDdFMjA4MC0yMDhFMjBBMC0yMEI5MjEwMC0yMTI1MjEyNy0yMTI5MjEyQy0yMTMxMjEzMy0yMTREMjE0Ri0yMTVGMjE4OTIxOTAtMjNGMzI0MDAtMjQyNjI0NDAtMjQ0QTI0NjAtMjZGRjI3MDEtMjdGRjI5MDAtMkI0QzJCNTAtMkI1OTJFMDAtMkUzQjJGRjAtMkZGQjMwMDAtMzAwNDMwMDYzMDA4LTMwMjAzMDMwLTMwMzczMDNDLTMwM0YzMDlCMzA5QzMwQTAzMEZCMzBGQzMxOTAtMzE5RjMxQzAtMzFFMzMyMjAtMzI1RjMyN0YtMzJDRjMzNTgtMzNGRjREQzAtNERGRkE3MDAtQTcyMUE3ODgtQTc4QUE4MzAtQTgzOUZEM0VGRDNGRkRGREZFMTAtRkUxOUZFMzAtRkU1MkZFNTQtRkU2NkZFNjgtRkU2QkZFRkZGRjAxLUZGMjBGRjNCLUZGNDBGRjVCLUZGNjVGRjcwRkY5RUZGOUZGRkUwLUZGRTZGRkU4LUZGRUVGRkY5LUZGRkQiLAogICAgICAgIENvcHRpYzogIjAzRTItMDNFRjJDODAtMkNGMzJDRjktMkNGRiIsCiAgICAgICAgQ3lyaWxsaWM6ICIwNDAwLTA0ODQwNDg3LTA1MjcxRDJCMUQ3ODJERTAtMkRGRkE2NDAtQTY5N0E2OUYiLAogICAgICAgIERldmFuYWdhcmk6ICIwOTAwLTA5NTAwOTUzLTA5NjMwOTY2LTA5NzcwOTc5LTA5N0ZBOEUwLUE4RkIiLAogICAgICAgIEV0aGlvcGljOiAiMTIwMC0xMjQ4MTI0QS0xMjREMTI1MC0xMjU2MTI1ODEyNUEtMTI1RDEyNjAtMTI4ODEyOEEtMTI4RDEyOTAtMTJCMDEyQjItMTJCNTEyQjgtMTJCRTEyQzAxMkMyLTEyQzUxMkM4LTEyRDYxMkQ4LTEzMTAxMzEyLTEzMTUxMzE4LTEzNUExMzVELTEzN0MxMzgwLTEzOTkyRDgwLTJEOTYyREEwLTJEQTYyREE4LTJEQUUyREIwLTJEQjYyREI4LTJEQkUyREMwLTJEQzYyREM4LTJEQ0UyREQwLTJERDYyREQ4LTJEREVBQjAxLUFCMDZBQjA5LUFCMEVBQjExLUFCMTZBQjIwLUFCMjZBQjI4LUFCMkUiLAogICAgICAgIEdlb3JnaWFuOiAiMTBBMC0xMEM1MTBDNzEwQ0QxMEQwLTEwRkExMEZDLTEwRkYyRDAwLTJEMjUyRDI3MkQyRCIsCiAgICAgICAgR2xhZ29saXRpYzogIjJDMDAtMkMyRTJDMzAtMkM1RSIsCiAgICAgICAgR3JlZWs6ICIwMzcwLTAzNzMwMzc1LTAzNzcwMzdBLTAzN0QwMzg0MDM4NjAzODgtMDM4QTAzOEMwMzhFLTAzQTEwM0EzLTAzRTEwM0YwLTAzRkYxRDI2LTFEMkExRDVELTFENjExRDY2LTFENkExREJGMUYwMC0xRjE1MUYxOC0xRjFEMUYyMC0xRjQ1MUY0OC0xRjREMUY1MC0xRjU3MUY1OTFGNUIxRjVEMUY1Ri0xRjdEMUY4MC0xRkI0MUZCNi0xRkM0MUZDNi0xRkQzMUZENi0xRkRCMUZERC0xRkVGMUZGMi0xRkY0MUZGNi0xRkZFMjEyNiIsCiAgICAgICAgR3VqYXJhdGk6ICIwQTgxLTBBODMwQTg1LTBBOEQwQThGLTBBOTEwQTkzLTBBQTgwQUFBLTBBQjAwQUIyMEFCMzBBQjUtMEFCOTBBQkMtMEFDNTBBQzctMEFDOTBBQ0ItMEFDRDBBRDAwQUUwLTBBRTMwQUU2LTBBRjEiLAogICAgICAgIEd1cm11a2hpOiAiMEEwMS0wQTAzMEEwNS0wQTBBMEEwRjBBMTAwQTEzLTBBMjgwQTJBLTBBMzAwQTMyMEEzMzBBMzUwQTM2MEEzODBBMzkwQTNDMEEzRS0wQTQyMEE0NzBBNDgwQTRCLTBBNEQwQTUxMEE1OS0wQTVDMEE1RTBBNjYtMEE3NSIsCiAgICAgICAgSGFuOiAiMkU4MC0yRTk5MkU5Qi0yRUYzMkYwMC0yRkQ1MzAwNTMwMDczMDIxLTMwMjkzMDM4LTMwM0IzNDAwLTREQjU0RTAwLTlGQ0NGOTAwLUZBNkRGQTcwLUZBRDkiLAogICAgICAgIEhhbmd1bDogIjExMDAtMTFGRjMwMkUzMDJGMzEzMS0zMThFMzIwMC0zMjFFMzI2MC0zMjdFQTk2MC1BOTdDQUMwMC1EN0EzRDdCMC1EN0M2RDdDQi1EN0ZCRkZBMC1GRkJFRkZDMi1GRkM3RkZDQS1GRkNGRkZEMi1GRkQ3RkZEQS1GRkRDIiwKICAgICAgICBIYW51bm9vOiAiMTcyMC0xNzM0IiwKICAgICAgICBIZWJyZXc6ICIwNTkxLTA1QzcwNUQwLTA1RUEwNUYwLTA1RjRGQjFELUZCMzZGQjM4LUZCM0NGQjNFRkI0MEZCNDFGQjQzRkI0NEZCNDYtRkI0RiIsCiAgICAgICAgSGlyYWdhbmE6ICIzMDQxLTMwOTYzMDlELTMwOUYiLAogICAgICAgIEluaGVyaXRlZDogIjAzMDAtMDM2RjA0ODUwNDg2MDY0Qi0wNjU1MDY1RjA2NzAwOTUxMDk1MjFDRDAtMUNEMjFDRDQtMUNFMDFDRTItMUNFODFDRUQxQ0Y0MURDMC0xREU2MURGQy0xREZGMjAwQzIwMEQyMEQwLTIwRjAzMDJBLTMwMkQzMDk5MzA5QUZFMDAtRkUwRkZFMjAtRkUyNiIsCiAgICAgICAgSmF2YW5lc2U6ICJBOTgwLUE5Q0RBOUNGLUE5RDlBOURFQTlERiIsCiAgICAgICAgS2FubmFkYTogIjBDODIwQzgzMEM4NS0wQzhDMEM4RS0wQzkwMEM5Mi0wQ0E4MENBQS0wQ0IzMENCNS0wQ0I5MENCQy0wQ0M0MENDNi0wQ0M4MENDQS0wQ0NEMENENTBDRDYwQ0RFMENFMC0wQ0UzMENFNi0wQ0VGMENGMTBDRjIiLAogICAgICAgIEthdGFrYW5hOiAiMzBBMS0zMEZBMzBGRC0zMEZGMzFGMC0zMUZGMzJEMC0zMkZFMzMwMC0zMzU3RkY2Ni1GRjZGRkY3MS1GRjlEIiwKICAgICAgICBLYXlhaF9MaTogIkE5MDAtQTkyRiIsCiAgICAgICAgS2htZXI6ICIxNzgwLTE3REQxN0UwLTE3RTkxN0YwLTE3RjkxOUUwLTE5RkYiLAogICAgICAgIExhbzogIjBFODEwRTgyMEU4NDBFODcwRTg4MEU4QTBFOEQwRTk0LTBFOTcwRTk5LTBFOUYwRUExLTBFQTMwRUE1MEVBNzBFQUEwRUFCMEVBRC0wRUI5MEVCQi0wRUJEMEVDMC0wRUM0MEVDNjBFQzgtMEVDRDBFRDAtMEVEOTBFREMtMEVERiIsCiAgICAgICAgTGF0aW46ICIwMDQxLTAwNUEwMDYxLTAwN0EwMEFBMDBCQTAwQzAtMDBENjAwRDgtMDBGNjAwRjgtMDJCODAyRTAtMDJFNDFEMDAtMUQyNTFEMkMtMUQ1QzFENjItMUQ2NTFENkItMUQ3NzFENzktMURCRTFFMDAtMUVGRjIwNzEyMDdGMjA5MC0yMDlDMjEyQTIxMkIyMTMyMjE0RTIxNjAtMjE4ODJDNjAtMkM3RkE3MjItQTc4N0E3OEItQTc4RUE3OTAtQTc5M0E3QTAtQTdBQUE3RjgtQTdGRkZCMDAtRkIwNkZGMjEtRkYzQUZGNDEtRkY1QSIsCiAgICAgICAgTGVwY2hhOiAiMUMwMC0xQzM3MUMzQi0xQzQ5MUM0RC0xQzRGIiwKICAgICAgICBMaW1idTogIjE5MDAtMTkxQzE5MjAtMTkyQjE5MzAtMTkzQjE5NDAxOTQ0LTE5NEYiLAogICAgICAgIExpc3U6ICJBNEQwLUE0RkYiLAogICAgICAgIE1hbGF5YWxhbTogIjBEMDIwRDAzMEQwNS0wRDBDMEQwRS0wRDEwMEQxMi0wRDNBMEQzRC0wRDQ0MEQ0Ni0wRDQ4MEQ0QS0wRDRFMEQ1NzBENjAtMEQ2MzBENjYtMEQ3NTBENzktMEQ3RiIsCiAgICAgICAgTWFuZGFpYzogIjA4NDAtMDg1QjA4NUUiLAogICAgICAgIE1lZXRlaV9NYXllazogIkFBRTAtQUFGNkFCQzAtQUJFREFCRjAtQUJGOSIsCiAgICAgICAgTW9uZ29saWFuOiAiMTgwMDE4MDExODA0MTgwNi0xODBFMTgxMC0xODE5MTgyMC0xODc3MTg4MC0xOEFBIiwKICAgICAgICBNeWFubWFyOiAiMTAwMC0xMDlGQUE2MC1BQTdCIiwKICAgICAgICBOZXdfVGFpX0x1ZTogIjE5ODAtMTlBQjE5QjAtMTlDOTE5RDAtMTlEQTE5REUxOURGIiwKICAgICAgICBOa286ICIwN0MwLTA3RkEiLAogICAgICAgIE9naGFtOiAiMTY4MC0xNjlDIiwKICAgICAgICBPbF9DaGlraTogIjFDNTAtMUM3RiIsCiAgICAgICAgT3JpeWE6ICIwQjAxLTBCMDMwQjA1LTBCMEMwQjBGMEIxMDBCMTMtMEIyODBCMkEtMEIzMDBCMzIwQjMzMEIzNS0wQjM5MEIzQy0wQjQ0MEI0NzBCNDgwQjRCLTBCNEQwQjU2MEI1NzBCNUMwQjVEMEI1Ri0wQjYzMEI2Ni0wQjc3IiwKICAgICAgICBQaGFnc19QYTogIkE4NDAtQTg3NyIsCiAgICAgICAgUmVqYW5nOiAiQTkzMC1BOTUzQTk1RiIsCiAgICAgICAgUnVuaWM6ICIxNkEwLTE2RUExNkVFLTE2RjAiLAogICAgICAgIFNhbWFyaXRhbjogIjA4MDAtMDgyRDA4MzAtMDgzRSIsCiAgICAgICAgU2F1cmFzaHRyYTogIkE4ODAtQThDNEE4Q0UtQThEOSIsCiAgICAgICAgU2luaGFsYTogIjBEODIwRDgzMEQ4NS0wRDk2MEQ5QS0wREIxMERCMy0wREJCMERCRDBEQzAtMERDNjBEQ0EwRENGLTBERDQwREQ2MEREOC0wRERGMERGMi0wREY0IiwKICAgICAgICBTdW5kYW5lc2U6ICIxQjgwLTFCQkYxQ0MwLTFDQzciLAogICAgICAgIFN5bG90aV9OYWdyaTogIkE4MDAtQTgyQiIsCiAgICAgICAgU3lyaWFjOiAiMDcwMC0wNzBEMDcwRi0wNzRBMDc0RC0wNzRGIiwKICAgICAgICBUYWdhbG9nOiAiMTcwMC0xNzBDMTcwRS0xNzE0IiwKICAgICAgICBUYWdiYW53YTogIjE3NjAtMTc2QzE3NkUtMTc3MDE3NzIxNzczIiwKICAgICAgICBUYWlfTGU6ICIxOTUwLTE5NkQxOTcwLTE5NzQiLAogICAgICAgIFRhaV9UaGFtOiAiMUEyMC0xQTVFMUE2MC0xQTdDMUE3Ri0xQTg5MUE5MC0xQTk5MUFBMC0xQUFEIiwKICAgICAgICBUYWlfVmlldDogIkFBODAtQUFDMkFBREItQUFERiIsCiAgICAgICAgVGFtaWw6ICIwQjgyMEI4MzBCODUtMEI4QTBCOEUtMEI5MDBCOTItMEI5NTBCOTkwQjlBMEI5QzBCOUUwQjlGMEJBMzBCQTQwQkE4LTBCQUEwQkFFLTBCQjkwQkJFLTBCQzIwQkM2LTBCQzgwQkNBLTBCQ0QwQkQwMEJENzBCRTYtMEJGQSIsCiAgICAgICAgVGVsdWd1OiAiMEMwMS0wQzAzMEMwNS0wQzBDMEMwRS0wQzEwMEMxMi0wQzI4MEMyQS0wQzMzMEMzNS0wQzM5MEMzRC0wQzQ0MEM0Ni0wQzQ4MEM0QS0wQzREMEM1NTBDNTYwQzU4MEM1OTBDNjAtMEM2MzBDNjYtMEM2RjBDNzgtMEM3RiIsCiAgICAgICAgVGhhYW5hOiAiMDc4MC0wN0IxIiwKICAgICAgICBUaGFpOiAiMEUwMS0wRTNBMEU0MC0wRTVCIiwKICAgICAgICBUaWJldGFuOiAiMEYwMC0wRjQ3MEY0OS0wRjZDMEY3MS0wRjk3MEY5OS0wRkJDMEZCRS0wRkNDMEZDRS0wRkQ0MEZEOTBGREEiLAogICAgICAgIFRpZmluYWdoOiAiMkQzMC0yRDY3MkQ2RjJENzAyRDdGIiwKICAgICAgICBWYWk6ICJBNTAwLUE2MkIiLAogICAgICAgIFlpOiAiQTAwMC1BNDhDQTQ5MC1BNEM2IgogICAgfSk7Cgp9KFhSZWdFeHApKTsKCgovKioqKiogdW5pY29kZS1ibG9ja3MuanMgKioqKiovCgovKiEKICogWFJlZ0V4cCBVbmljb2RlIEJsb2NrcyB2MS4yLjAKICogKGMpIDIwMTAtMjAxMiBTdGV2ZW4gTGV2aXRoYW4gPGh0dHA6Ly94cmVnZXhwLmNvbS8+CiAqIE1JVCBMaWNlbnNlCiAqIFVzZXMgVW5pY29kZSA2LjEgPGh0dHA6Ly91bmljb2RlLm9yZy8+CiAqLwoKLyoqCiAqIEFkZHMgc3VwcG9ydCBmb3IgYWxsIFVuaWNvZGUgYmxvY2tzIGluIHRoZSBCYXNpYyBNdWx0aWxpbmd1YWwgUGxhbmUgKFUrMDAwMC1VK0ZGRkYpLiBVbmljb2RlCiAqIGJsb2NrcyB1c2UgdGhlIHByZWZpeCAiSW4iLiBFLmcuLCBgXHB7SW5CYXNpY0xhdGlufWAuIFRva2VuIG5hbWVzIGFyZSBjYXNlIGluc2Vuc2l0aXZlLCBhbmQgYW55CiAqIHNwYWNlcywgaHlwaGVucywgYW5kIHVuZGVyc2NvcmVzIGFyZSBpZ25vcmVkLgogKiBAcmVxdWlyZXMgWFJlZ0V4cCwgWFJlZ0V4cCBVbmljb2RlIEJhc2UKICovCihmdW5jdGlvbiAoWFJlZ0V4cCkgewogICAgInVzZSBzdHJpY3QiOwoKICAgIGlmICghWFJlZ0V4cC5hZGRVbmljb2RlUGFja2FnZSkgewogICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcigiVW5pY29kZSBCYXNlIG11c3QgYmUgbG9hZGVkIGJlZm9yZSBVbmljb2RlIEJsb2NrcyIpOwogICAgfQoKICAgIFhSZWdFeHAuaW5zdGFsbCgiZXh0ZW5zaWJpbGl0eSIpOwoKICAgIFhSZWdFeHAuYWRkVW5pY29kZVBhY2thZ2UoewogICAgICAgIEluQmFzaWNfTGF0aW46ICIwMDAwLTAwN0YiLAogICAgICAgIEluTGF0aW5fMV9TdXBwbGVtZW50OiAiMDA4MC0wMEZGIiwKICAgICAgICBJbkxhdGluX0V4dGVuZGVkX0E6ICIwMTAwLTAxN0YiLAogICAgICAgIEluTGF0aW5fRXh0ZW5kZWRfQjogIjAxODAtMDI0RiIsCiAgICAgICAgSW5JUEFfRXh0ZW5zaW9uczogIjAyNTAtMDJBRiIsCiAgICAgICAgSW5TcGFjaW5nX01vZGlmaWVyX0xldHRlcnM6ICIwMkIwLTAyRkYiLAogICAgICAgIEluQ29tYmluaW5nX0RpYWNyaXRpY2FsX01hcmtzOiAiMDMwMC0wMzZGIiwKICAgICAgICBJbkdyZWVrX2FuZF9Db3B0aWM6ICIwMzcwLTAzRkYiLAogICAgICAgIEluQ3lyaWxsaWM6ICIwNDAwLTA0RkYiLAogICAgICAgIEluQ3lyaWxsaWNfU3VwcGxlbWVudDogIjA1MDAtMDUyRiIsCiAgICAgICAgSW5Bcm1lbmlhbjogIjA1MzAtMDU4RiIsCiAgICAgICAgSW5IZWJyZXc6ICIwNTkwLTA1RkYiLAogICAgICAgIEluQXJhYmljOiAiMDYwMC0wNkZGIiwKICAgICAgICBJblN5cmlhYzogIjA3MDAtMDc0RiIsCiAgICAgICAgSW5BcmFiaWNfU3VwcGxlbWVudDogIjA3NTAtMDc3RiIsCiAgICAgICAgSW5UaGFhbmE6ICIwNzgwLTA3QkYiLAogICAgICAgIEluTktvOiAiMDdDMC0wN0ZGIiwKICAgICAgICBJblNhbWFyaXRhbjogIjA4MDAtMDgzRiIsCiAgICAgICAgSW5NYW5kYWljOiAiMDg0MC0wODVGIiwKICAgICAgICBJbkFyYWJpY19FeHRlbmRlZF9BOiAiMDhBMC0wOEZGIiwKICAgICAgICBJbkRldmFuYWdhcmk6ICIwOTAwLTA5N0YiLAogICAgICAgIEluQmVuZ2FsaTogIjA5ODAtMDlGRiIsCiAgICAgICAgSW5HdXJtdWtoaTogIjBBMDAtMEE3RiIsCiAgICAgICAgSW5HdWphcmF0aTogIjBBODAtMEFGRiIsCiAgICAgICAgSW5Pcml5YTogIjBCMDAtMEI3RiIsCiAgICAgICAgSW5UYW1pbDogIjBCODAtMEJGRiIsCiAgICAgICAgSW5UZWx1Z3U6ICIwQzAwLTBDN0YiLAogICAgICAgIEluS2FubmFkYTogIjBDODAtMENGRiIsCiAgICAgICAgSW5NYWxheWFsYW06ICIwRDAwLTBEN0YiLAogICAgICAgIEluU2luaGFsYTogIjBEODAtMERGRiIsCiAgICAgICAgSW5UaGFpOiAiMEUwMC0wRTdGIiwKICAgICAgICBJbkxhbzogIjBFODAtMEVGRiIsCiAgICAgICAgSW5UaWJldGFuOiAiMEYwMC0wRkZGIiwKICAgICAgICBJbk15YW5tYXI6ICIxMDAwLTEwOUYiLAogICAgICAgIEluR2VvcmdpYW46ICIxMEEwLTEwRkYiLAogICAgICAgIEluSGFuZ3VsX0phbW86ICIxMTAwLTExRkYiLAogICAgICAgIEluRXRoaW9waWM6ICIxMjAwLTEzN0YiLAogICAgICAgIEluRXRoaW9waWNfU3VwcGxlbWVudDogIjEzODAtMTM5RiIsCiAgICAgICAgSW5DaGVyb2tlZTogIjEzQTAtMTNGRiIsCiAgICAgICAgSW5VbmlmaWVkX0NhbmFkaWFuX0Fib3JpZ2luYWxfU3lsbGFiaWNzOiAiMTQwMC0xNjdGIiwKICAgICAgICBJbk9naGFtOiAiMTY4MC0xNjlGIiwKICAgICAgICBJblJ1bmljOiAiMTZBMC0xNkZGIiwKICAgICAgICBJblRhZ2Fsb2c6ICIxNzAwLTE3MUYiLAogICAgICAgIEluSGFudW5vbzogIjE3MjAtMTczRiIsCiAgICAgICAgSW5CdWhpZDogIjE3NDAtMTc1RiIsCiAgICAgICAgSW5UYWdiYW53YTogIjE3NjAtMTc3RiIsCiAgICAgICAgSW5LaG1lcjogIjE3ODAtMTdGRiIsCiAgICAgICAgSW5Nb25nb2xpYW46ICIxODAwLTE4QUYiLAogICAgICAgIEluVW5pZmllZF9DYW5hZGlhbl9BYm9yaWdpbmFsX1N5bGxhYmljc19FeHRlbmRlZDogIjE4QjAtMThGRiIsCiAgICAgICAgSW5MaW1idTogIjE5MDAtMTk0RiIsCiAgICAgICAgSW5UYWlfTGU6ICIxOTUwLTE5N0YiLAogICAgICAgIEluTmV3X1RhaV9MdWU6ICIxOTgwLTE5REYiLAogICAgICAgIEluS2htZXJfU3ltYm9sczogIjE5RTAtMTlGRiIsCiAgICAgICAgSW5CdWdpbmVzZTogIjFBMDAtMUExRiIsCiAgICAgICAgSW5UYWlfVGhhbTogIjFBMjAtMUFBRiIsCiAgICAgICAgSW5CYWxpbmVzZTogIjFCMDAtMUI3RiIsCiAgICAgICAgSW5TdW5kYW5lc2U6ICIxQjgwLTFCQkYiLAogICAgICAgIEluQmF0YWs6ICIxQkMwLTFCRkYiLAogICAgICAgIEluTGVwY2hhOiAiMUMwMC0xQzRGIiwKICAgICAgICBJbk9sX0NoaWtpOiAiMUM1MC0xQzdGIiwKICAgICAgICBJblN1bmRhbmVzZV9TdXBwbGVtZW50OiAiMUNDMC0xQ0NGIiwKICAgICAgICBJblZlZGljX0V4dGVuc2lvbnM6ICIxQ0QwLTFDRkYiLAogICAgICAgIEluUGhvbmV0aWNfRXh0ZW5zaW9uczogIjFEMDAtMUQ3RiIsCiAgICAgICAgSW5QaG9uZXRpY19FeHRlbnNpb25zX1N1cHBsZW1lbnQ6ICIxRDgwLTFEQkYiLAogICAgICAgIEluQ29tYmluaW5nX0RpYWNyaXRpY2FsX01hcmtzX1N1cHBsZW1lbnQ6ICIxREMwLTFERkYiLAogICAgICAgIEluTGF0aW5fRXh0ZW5kZWRfQWRkaXRpb25hbDogIjFFMDAtMUVGRiIsCiAgICAgICAgSW5HcmVla19FeHRlbmRlZDogIjFGMDAtMUZGRiIsCiAgICAgICAgSW5HZW5lcmFsX1B1bmN0dWF0aW9uOiAiMjAwMC0yMDZGIiwKICAgICAgICBJblN1cGVyc2NyaXB0c19hbmRfU3Vic2NyaXB0czogIjIwNzAtMjA5RiIsCiAgICAgICAgSW5DdXJyZW5jeV9TeW1ib2xzOiAiMjBBMC0yMENGIiwKICAgICAgICBJbkNvbWJpbmluZ19EaWFjcml0aWNhbF9NYXJrc19mb3JfU3ltYm9sczogIjIwRDAtMjBGRiIsCiAgICAgICAgSW5MZXR0ZXJsaWtlX1N5bWJvbHM6ICIyMTAwLTIxNEYiLAogICAgICAgIEluTnVtYmVyX0Zvcm1zOiAiMjE1MC0yMThGIiwKICAgICAgICBJbkFycm93czogIjIxOTAtMjFGRiIsCiAgICAgICAgSW5NYXRoZW1hdGljYWxfT3BlcmF0b3JzOiAiMjIwMC0yMkZGIiwKICAgICAgICBJbk1pc2NlbGxhbmVvdXNfVGVjaG5pY2FsOiAiMjMwMC0yM0ZGIiwKICAgICAgICBJbkNvbnRyb2xfUGljdHVyZXM6ICIyNDAwLTI0M0YiLAogICAgICAgIEluT3B0aWNhbF9DaGFyYWN0ZXJfUmVjb2duaXRpb246ICIyNDQwLTI0NUYiLAogICAgICAgIEluRW5jbG9zZWRfQWxwaGFudW1lcmljczogIjI0NjAtMjRGRiIsCiAgICAgICAgSW5Cb3hfRHJhd2luZzogIjI1MDAtMjU3RiIsCiAgICAgICAgSW5CbG9ja19FbGVtZW50czogIjI1ODAtMjU5RiIsCiAgICAgICAgSW5HZW9tZXRyaWNfU2hhcGVzOiAiMjVBMC0yNUZGIiwKICAgICAgICBJbk1pc2NlbGxhbmVvdXNfU3ltYm9sczogIjI2MDAtMjZGRiIsCiAgICAgICAgSW5EaW5nYmF0czogIjI3MDAtMjdCRiIsCiAgICAgICAgSW5NaXNjZWxsYW5lb3VzX01hdGhlbWF0aWNhbF9TeW1ib2xzX0E6ICIyN0MwLTI3RUYiLAogICAgICAgIEluU3VwcGxlbWVudGFsX0Fycm93c19BOiAiMjdGMC0yN0ZGIiwKICAgICAgICBJbkJyYWlsbGVfUGF0dGVybnM6ICIyODAwLTI4RkYiLAogICAgICAgIEluU3VwcGxlbWVudGFsX0Fycm93c19COiAiMjkwMC0yOTdGIiwKICAgICAgICBJbk1pc2NlbGxhbmVvdXNfTWF0aGVtYXRpY2FsX1N5bWJvbHNfQjogIjI5ODAtMjlGRiIsCiAgICAgICAgSW5TdXBwbGVtZW50YWxfTWF0aGVtYXRpY2FsX09wZXJhdG9yczogIjJBMDAtMkFGRiIsCiAgICAgICAgSW5NaXNjZWxsYW5lb3VzX1N5bWJvbHNfYW5kX0Fycm93czogIjJCMDAtMkJGRiIsCiAgICAgICAgSW5HbGFnb2xpdGljOiAiMkMwMC0yQzVGIiwKICAgICAgICBJbkxhdGluX0V4dGVuZGVkX0M6ICIyQzYwLTJDN0YiLAogICAgICAgIEluQ29wdGljOiAiMkM4MC0yQ0ZGIiwKICAgICAgICBJbkdlb3JnaWFuX1N1cHBsZW1lbnQ6ICIyRDAwLTJEMkYiLAogICAgICAgIEluVGlmaW5hZ2g6ICIyRDMwLTJEN0YiLAogICAgICAgIEluRXRoaW9waWNfRXh0ZW5kZWQ6ICIyRDgwLTJEREYiLAogICAgICAgIEluQ3lyaWxsaWNfRXh0ZW5kZWRfQTogIjJERTAtMkRGRiIsCiAgICAgICAgSW5TdXBwbGVtZW50YWxfUHVuY3R1YXRpb246ICIyRTAwLTJFN0YiLAogICAgICAgIEluQ0pLX1JhZGljYWxzX1N1cHBsZW1lbnQ6ICIyRTgwLTJFRkYiLAogICAgICAgIEluS2FuZ3hpX1JhZGljYWxzOiAiMkYwMC0yRkRGIiwKICAgICAgICBJbklkZW9ncmFwaGljX0Rlc2NyaXB0aW9uX0NoYXJhY3RlcnM6ICIyRkYwLTJGRkYiLAogICAgICAgIEluQ0pLX1N5bWJvbHNfYW5kX1B1bmN0dWF0aW9uOiAiMzAwMC0zMDNGIiwKICAgICAgICBJbkhpcmFnYW5hOiAiMzA0MC0zMDlGIiwKICAgICAgICBJbkthdGFrYW5hOiAiMzBBMC0zMEZGIiwKICAgICAgICBJbkJvcG9tb2ZvOiAiMzEwMC0zMTJGIiwKICAgICAgICBJbkhhbmd1bF9Db21wYXRpYmlsaXR5X0phbW86ICIzMTMwLTMxOEYiLAogICAgICAgIEluS2FuYnVuOiAiMzE5MC0zMTlGIiwKICAgICAgICBJbkJvcG9tb2ZvX0V4dGVuZGVkOiAiMzFBMC0zMUJGIiwKICAgICAgICBJbkNKS19TdHJva2VzOiAiMzFDMC0zMUVGIiwKICAgICAgICBJbkthdGFrYW5hX1Bob25ldGljX0V4dGVuc2lvbnM6ICIzMUYwLTMxRkYiLAogICAgICAgIEluRW5jbG9zZWRfQ0pLX0xldHRlcnNfYW5kX01vbnRoczogIjMyMDAtMzJGRiIsCiAgICAgICAgSW5DSktfQ29tcGF0aWJpbGl0eTogIjMzMDAtMzNGRiIsCiAgICAgICAgSW5DSktfVW5pZmllZF9JZGVvZ3JhcGhzX0V4dGVuc2lvbl9BOiAiMzQwMC00REJGIiwKICAgICAgICBJbllpamluZ19IZXhhZ3JhbV9TeW1ib2xzOiAiNERDMC00REZGIiwKICAgICAgICBJbkNKS19VbmlmaWVkX0lkZW9ncmFwaHM6ICI0RTAwLTlGRkYiLAogICAgICAgIEluWWlfU3lsbGFibGVzOiAiQTAwMC1BNDhGIiwKICAgICAgICBJbllpX1JhZGljYWxzOiAiQTQ5MC1BNENGIiwKICAgICAgICBJbkxpc3U6ICJBNEQwLUE0RkYiLAogICAgICAgIEluVmFpOiAiQTUwMC1BNjNGIiwKICAgICAgICBJbkN5cmlsbGljX0V4dGVuZGVkX0I6ICJBNjQwLUE2OUYiLAogICAgICAgIEluQmFtdW06ICJBNkEwLUE2RkYiLAogICAgICAgIEluTW9kaWZpZXJfVG9uZV9MZXR0ZXJzOiAiQTcwMC1BNzFGIiwKICAgICAgICBJbkxhdGluX0V4dGVuZGVkX0Q6ICJBNzIwLUE3RkYiLAogICAgICAgIEluU3lsb3RpX05hZ3JpOiAiQTgwMC1BODJGIiwKICAgICAgICBJbkNvbW1vbl9JbmRpY19OdW1iZXJfRm9ybXM6ICJBODMwLUE4M0YiLAogICAgICAgIEluUGhhZ3NfcGE6ICJBODQwLUE4N0YiLAogICAgICAgIEluU2F1cmFzaHRyYTogIkE4ODAtQThERiIsCiAgICAgICAgSW5EZXZhbmFnYXJpX0V4dGVuZGVkOiAiQThFMC1BOEZGIiwKICAgICAgICBJbktheWFoX0xpOiAiQTkwMC1BOTJGIiwKICAgICAgICBJblJlamFuZzogIkE5MzAtQTk1RiIsCiAgICAgICAgSW5IYW5ndWxfSmFtb19FeHRlbmRlZF9BOiAiQTk2MC1BOTdGIiwKICAgICAgICBJbkphdmFuZXNlOiAiQTk4MC1BOURGIiwKICAgICAgICBJbkNoYW06ICJBQTAwLUFBNUYiLAogICAgICAgIEluTXlhbm1hcl9FeHRlbmRlZF9BOiAiQUE2MC1BQTdGIiwKICAgICAgICBJblRhaV9WaWV0OiAiQUE4MC1BQURGIiwKICAgICAgICBJbk1lZXRlaV9NYXlla19FeHRlbnNpb25zOiAiQUFFMC1BQUZGIiwKICAgICAgICBJbkV0aGlvcGljX0V4dGVuZGVkX0E6ICJBQjAwLUFCMkYiLAogICAgICAgIEluTWVldGVpX01heWVrOiAiQUJDMC1BQkZGIiwKICAgICAgICBJbkhhbmd1bF9TeWxsYWJsZXM6ICJBQzAwLUQ3QUYiLAogICAgICAgIEluSGFuZ3VsX0phbW9fRXh0ZW5kZWRfQjogIkQ3QjAtRDdGRiIsCiAgICAgICAgSW5IaWdoX1N1cnJvZ2F0ZXM6ICJEODAwLURCN0YiLAogICAgICAgIEluSGlnaF9Qcml2YXRlX1VzZV9TdXJyb2dhdGVzOiAiREI4MC1EQkZGIiwKICAgICAgICBJbkxvd19TdXJyb2dhdGVzOiAiREMwMC1ERkZGIiwKICAgICAgICBJblByaXZhdGVfVXNlX0FyZWE6ICJFMDAwLUY4RkYiLAogICAgICAgIEluQ0pLX0NvbXBhdGliaWxpdHlfSWRlb2dyYXBoczogIkY5MDAtRkFGRiIsCiAgICAgICAgSW5BbHBoYWJldGljX1ByZXNlbnRhdGlvbl9Gb3JtczogIkZCMDAtRkI0RiIsCiAgICAgICAgSW5BcmFiaWNfUHJlc2VudGF0aW9uX0Zvcm1zX0E6ICJGQjUwLUZERkYiLAogICAgICAgIEluVmFyaWF0aW9uX1NlbGVjdG9yczogIkZFMDAtRkUwRiIsCiAgICAgICAgSW5WZXJ0aWNhbF9Gb3JtczogIkZFMTAtRkUxRiIsCiAgICAgICAgSW5Db21iaW5pbmdfSGFsZl9NYXJrczogIkZFMjAtRkUyRiIsCiAgICAgICAgSW5DSktfQ29tcGF0aWJpbGl0eV9Gb3JtczogIkZFMzAtRkU0RiIsCiAgICAgICAgSW5TbWFsbF9Gb3JtX1ZhcmlhbnRzOiAiRkU1MC1GRTZGIiwKICAgICAgICBJbkFyYWJpY19QcmVzZW50YXRpb25fRm9ybXNfQjogIkZFNzAtRkVGRiIsCiAgICAgICAgSW5IYWxmd2lkdGhfYW5kX0Z1bGx3aWR0aF9Gb3JtczogIkZGMDAtRkZFRiIsCiAgICAgICAgSW5TcGVjaWFsczogIkZGRjAtRkZGRiIKICAgIH0pOwoKfShYUmVnRXhwKSk7CgoKLyoqKioqIHVuaWNvZGUtcHJvcGVydGllcy5qcyAqKioqKi8KCi8qIQogKiBYUmVnRXhwIFVuaWNvZGUgUHJvcGVydGllcyB2MS4wLjAKICogKGMpIDIwMTIgU3RldmVuIExldml0aGFuIDxodHRwOi8veHJlZ2V4cC5jb20vPgogKiBNSVQgTGljZW5zZQogKiBVc2VzIFVuaWNvZGUgNi4xIDxodHRwOi8vdW5pY29kZS5vcmcvPgogKi8KCi8qKgogKiBBZGRzIFVuaWNvZGUgcHJvcGVydGllcyBuZWNlc3NhcnkgdG8gbWVldCBMZXZlbCAxIFVuaWNvZGUgc3VwcG9ydCAoZGV0YWlsZWQgaW4gVVRTIzE4IFJMMS4yKS4KICogSW5jbHVkZXMgY29kZSBwb2ludHMgZnJvbSB0aGUgQmFzaWMgTXVsdGlsaW5ndWFsIFBsYW5lIChVKzAwMDAtVStGRkZGKSBvbmx5LiBUb2tlbiBuYW1lcyBhcmUKICogY2FzZSBpbnNlbnNpdGl2ZSwgYW5kIGFueSBzcGFjZXMsIGh5cGhlbnMsIGFuZCB1bmRlcnNjb3JlcyBhcmUgaWdub3JlZC4KICogQHJlcXVpcmVzIFhSZWdFeHAsIFhSZWdFeHAgVW5pY29kZSBCYXNlCiAqLwooZnVuY3Rpb24gKFhSZWdFeHApIHsKICAgICJ1c2Ugc3RyaWN0IjsKCiAgICBpZiAoIVhSZWdFeHAuYWRkVW5pY29kZVBhY2thZ2UpIHsKICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoIlVuaWNvZGUgQmFzZSBtdXN0IGJlIGxvYWRlZCBiZWZvcmUgVW5pY29kZSBQcm9wZXJ0aWVzIik7CiAgICB9CgogICAgWFJlZ0V4cC5pbnN0YWxsKCJleHRlbnNpYmlsaXR5Iik7CgogICAgWFJlZ0V4cC5hZGRVbmljb2RlUGFja2FnZSh7CiAgICAgICAgQWxwaGFiZXRpYzogIjAwNDEtMDA1QTAwNjEtMDA3QTAwQUEwMEI1MDBCQTAwQzAtMDBENjAwRDgtMDBGNjAwRjgtMDJDMTAyQzYtMDJEMTAyRTAtMDJFNDAyRUMwMkVFMDM0NTAzNzAtMDM3NDAzNzYwMzc3MDM3QS0wMzdEMDM4NjAzODgtMDM4QTAzOEMwMzhFLTAzQTEwM0EzLTAzRjUwM0Y3LTA0ODEwNDhBLTA1MjcwNTMxLTA1NTYwNTU5MDU2MS0wNTg3MDVCMC0wNUJEMDVCRjA1QzEwNUMyMDVDNDA1QzUwNUM3MDVEMC0wNUVBMDVGMC0wNUYyMDYxMC0wNjFBMDYyMC0wNjU3MDY1OS0wNjVGMDY2RS0wNkQzMDZENS0wNkRDMDZFMS0wNkU4MDZFRC0wNkVGMDZGQS0wNkZDMDZGRjA3MTAtMDczRjA3NEQtMDdCMTA3Q0EtMDdFQTA3RjQwN0Y1MDdGQTA4MDAtMDgxNzA4MUEtMDgyQzA4NDAtMDg1ODA4QTAwOEEyLTA4QUMwOEU0LTA4RTkwOEYwLTA4RkUwOTAwLTA5M0IwOTNELTA5NEMwOTRFLTA5NTAwOTU1LTA5NjMwOTcxLTA5NzcwOTc5LTA5N0YwOTgxLTA5ODMwOTg1LTA5OEMwOThGMDk5MDA5OTMtMDlBODA5QUEtMDlCMDA5QjIwOUI2LTA5QjkwOUJELTA5QzQwOUM3MDlDODA5Q0IwOUNDMDlDRTA5RDcwOURDMDlERDA5REYtMDlFMzA5RjAwOUYxMEEwMS0wQTAzMEEwNS0wQTBBMEEwRjBBMTAwQTEzLTBBMjgwQTJBLTBBMzAwQTMyMEEzMzBBMzUwQTM2MEEzODBBMzkwQTNFLTBBNDIwQTQ3MEE0ODBBNEIwQTRDMEE1MTBBNTktMEE1QzBBNUUwQTcwLTBBNzUwQTgxLTBBODMwQTg1LTBBOEQwQThGLTBBOTEwQTkzLTBBQTgwQUFBLTBBQjAwQUIyMEFCMzBBQjUtMEFCOTBBQkQtMEFDNTBBQzctMEFDOTBBQ0IwQUNDMEFEMDBBRTAtMEFFMzBCMDEtMEIwMzBCMDUtMEIwQzBCMEYwQjEwMEIxMy0wQjI4MEIyQS0wQjMwMEIzMjBCMzMwQjM1LTBCMzkwQjNELTBCNDQwQjQ3MEI0ODBCNEIwQjRDMEI1NjBCNTcwQjVDMEI1RDBCNUYtMEI2MzBCNzEwQjgyMEI4MzBCODUtMEI4QTBCOEUtMEI5MDBCOTItMEI5NTBCOTkwQjlBMEI5QzBCOUUwQjlGMEJBMzBCQTQwQkE4LTBCQUEwQkFFLTBCQjkwQkJFLTBCQzIwQkM2LTBCQzgwQkNBLTBCQ0MwQkQwMEJENzBDMDEtMEMwMzBDMDUtMEMwQzBDMEUtMEMxMDBDMTItMEMyODBDMkEtMEMzMzBDMzUtMEMzOTBDM0QtMEM0NDBDNDYtMEM0ODBDNEEtMEM0QzBDNTUwQzU2MEM1ODBDNTkwQzYwLTBDNjMwQzgyMEM4MzBDODUtMEM4QzBDOEUtMEM5MDBDOTItMENBODBDQUEtMENCMzBDQjUtMENCOTBDQkQtMENDNDBDQzYtMENDODBDQ0EtMENDQzBDRDUwQ0Q2MENERTBDRTAtMENFMzBDRjEwQ0YyMEQwMjBEMDMwRDA1LTBEMEMwRDBFLTBEMTAwRDEyLTBEM0EwRDNELTBENDQwRDQ2LTBENDgwRDRBLTBENEMwRDRFMEQ1NzBENjAtMEQ2MzBEN0EtMEQ3RjBEODIwRDgzMEQ4NS0wRDk2MEQ5QS0wREIxMERCMy0wREJCMERCRDBEQzAtMERDNjBEQ0YtMERENDBERDYwREQ4LTBEREYwREYyMERGMzBFMDEtMEUzQTBFNDAtMEU0NjBFNEQwRTgxMEU4MjBFODQwRTg3MEU4ODBFOEEwRThEMEU5NC0wRTk3MEU5OS0wRTlGMEVBMS0wRUEzMEVBNTBFQTcwRUFBMEVBQjBFQUQtMEVCOTBFQkItMEVCRDBFQzAtMEVDNDBFQzYwRUNEMEVEQy0wRURGMEYwMDBGNDAtMEY0NzBGNDktMEY2QzBGNzEtMEY4MTBGODgtMEY5NzBGOTktMEZCQzEwMDAtMTAzNjEwMzgxMDNCLTEwM0YxMDUwLTEwNjIxMDY1LTEwNjgxMDZFLTEwODYxMDhFMTA5QzEwOUQxMEEwLTEwQzUxMEM3MTBDRDEwRDAtMTBGQTEwRkMtMTI0ODEyNEEtMTI0RDEyNTAtMTI1NjEyNTgxMjVBLTEyNUQxMjYwLTEyODgxMjhBLTEyOEQxMjkwLTEyQjAxMkIyLTEyQjUxMkI4LTEyQkUxMkMwMTJDMi0xMkM1MTJDOC0xMkQ2MTJEOC0xMzEwMTMxMi0xMzE1MTMxOC0xMzVBMTM1RjEzODAtMTM4RjEzQTAtMTNGNDE0MDEtMTY2QzE2NkYtMTY3RjE2ODEtMTY5QTE2QTAtMTZFQTE2RUUtMTZGMDE3MDAtMTcwQzE3MEUtMTcxMzE3MjAtMTczMzE3NDAtMTc1MzE3NjAtMTc2QzE3NkUtMTc3MDE3NzIxNzczMTc4MC0xN0IzMTdCNi0xN0M4MTdENzE3REMxODIwLTE4NzcxODgwLTE4QUExOEIwLTE4RjUxOTAwLTE5MUMxOTIwLTE5MkIxOTMwLTE5MzgxOTUwLTE5NkQxOTcwLTE5NzQxOTgwLTE5QUIxOUIwLTE5QzkxQTAwLTFBMUIxQTIwLTFBNUUxQTYxLTFBNzQxQUE3MUIwMC0xQjMzMUIzNS0xQjQzMUI0NS0xQjRCMUI4MC0xQkE5MUJBQy0xQkFGMUJCQS0xQkU1MUJFNy0xQkYxMUMwMC0xQzM1MUM0RC0xQzRGMUM1QS0xQzdEMUNFOS0xQ0VDMUNFRS0xQ0YzMUNGNTFDRjYxRDAwLTFEQkYxRTAwLTFGMTUxRjE4LTFGMUQxRjIwLTFGNDUxRjQ4LTFGNEQxRjUwLTFGNTcxRjU5MUY1QjFGNUQxRjVGLTFGN0QxRjgwLTFGQjQxRkI2LTFGQkMxRkJFMUZDMi0xRkM0MUZDNi0xRkNDMUZEMC0xRkQzMUZENi0xRkRCMUZFMC0xRkVDMUZGMi0xRkY0MUZGNi0xRkZDMjA3MTIwN0YyMDkwLTIwOUMyMTAyMjEwNzIxMEEtMjExMzIxMTUyMTE5LTIxMUQyMTI0MjEyNjIxMjgyMTJBLTIxMkQyMTJGLTIxMzkyMTNDLTIxM0YyMTQ1LTIxNDkyMTRFMjE2MC0yMTg4MjRCNi0yNEU5MkMwMC0yQzJFMkMzMC0yQzVFMkM2MC0yQ0U0MkNFQi0yQ0VFMkNGMjJDRjMyRDAwLTJEMjUyRDI3MkQyRDJEMzAtMkQ2NzJENkYyRDgwLTJEOTYyREEwLTJEQTYyREE4LTJEQUUyREIwLTJEQjYyREI4LTJEQkUyREMwLTJEQzYyREM4LTJEQ0UyREQwLTJERDYyREQ4LTJEREUyREUwLTJERkYyRTJGMzAwNS0zMDA3MzAyMS0zMDI5MzAzMS0zMDM1MzAzOC0zMDNDMzA0MS0zMDk2MzA5RC0zMDlGMzBBMS0zMEZBMzBGQy0zMEZGMzEwNS0zMTJEMzEzMS0zMThFMzFBMC0zMUJBMzFGMC0zMUZGMzQwMC00REI1NEUwMC05RkNDQTAwMC1BNDhDQTREMC1BNEZEQTUwMC1BNjBDQTYxMC1BNjFGQTYyQUE2MkJBNjQwLUE2NkVBNjc0LUE2N0JBNjdGLUE2OTdBNjlGLUE2RUZBNzE3LUE3MUZBNzIyLUE3ODhBNzhCLUE3OEVBNzkwLUE3OTNBN0EwLUE3QUFBN0Y4LUE4MDFBODAzLUE4MDVBODA3LUE4MEFBODBDLUE4MjdBODQwLUE4NzNBODgwLUE4QzNBOEYyLUE4RjdBOEZCQTkwQS1BOTJBQTkzMC1BOTUyQTk2MC1BOTdDQTk4MC1BOUIyQTlCNC1BOUJGQTlDRkFBMDAtQUEzNkFBNDAtQUE0REFBNjAtQUE3NkFBN0FBQTgwLUFBQkVBQUMwQUFDMkFBREItQUFEREFBRTAtQUFFRkFBRjItQUFGNUFCMDEtQUIwNkFCMDktQUIwRUFCMTEtQUIxNkFCMjAtQUIyNkFCMjgtQUIyRUFCQzAtQUJFQUFDMDAtRDdBM0Q3QjAtRDdDNkQ3Q0ItRDdGQkY5MDAtRkE2REZBNzAtRkFEOUZCMDAtRkIwNkZCMTMtRkIxN0ZCMUQtRkIyOEZCMkEtRkIzNkZCMzgtRkIzQ0ZCM0VGQjQwRkI0MUZCNDNGQjQ0RkI0Ni1GQkIxRkJEMy1GRDNERkQ1MC1GRDhGRkQ5Mi1GREM3RkRGMC1GREZCRkU3MC1GRTc0RkU3Ni1GRUZDRkYyMS1GRjNBRkY0MS1GRjVBRkY2Ni1GRkJFRkZDMi1GRkM3RkZDQS1GRkNGRkZEMi1GRkQ3RkZEQS1GRkRDIiwKICAgICAgICBVcHBlcmNhc2U6ICIwMDQxLTAwNUEwMEMwLTAwRDYwMEQ4LTAwREUwMTAwMDEwMjAxMDQwMTA2MDEwODAxMEEwMTBDMDEwRTAxMTAwMTEyMDExNDAxMTYwMTE4MDExQTAxMUMwMTFFMDEyMDAxMjIwMTI0MDEyNjAxMjgwMTJBMDEyQzAxMkUwMTMwMDEzMjAxMzQwMTM2MDEzOTAxM0IwMTNEMDEzRjAxNDEwMTQzMDE0NTAxNDcwMTRBMDE0QzAxNEUwMTUwMDE1MjAxNTQwMTU2MDE1ODAxNUEwMTVDMDE1RTAxNjAwMTYyMDE2NDAxNjYwMTY4MDE2QTAxNkMwMTZFMDE3MDAxNzIwMTc0MDE3NjAxNzgwMTc5MDE3QjAxN0QwMTgxMDE4MjAxODQwMTg2MDE4NzAxODktMDE4QjAxOEUtMDE5MTAxOTMwMTk0MDE5Ni0wMTk4MDE5QzAxOUQwMTlGMDFBMDAxQTIwMUE0MDFBNjAxQTcwMUE5MDFBQzAxQUUwMUFGMDFCMS0wMUIzMDFCNTAxQjcwMUI4MDFCQzAxQzQwMUM3MDFDQTAxQ0QwMUNGMDFEMTAxRDMwMUQ1MDFENzAxRDkwMURCMDFERTAxRTAwMUUyMDFFNDAxRTYwMUU4MDFFQTAxRUMwMUVFMDFGMTAxRjQwMUY2LTAxRjgwMUZBMDFGQzAxRkUwMjAwMDIwMjAyMDQwMjA2MDIwODAyMEEwMjBDMDIwRTAyMTAwMjEyMDIxNDAyMTYwMjE4MDIxQTAyMUMwMjFFMDIyMDAyMjIwMjI0MDIyNjAyMjgwMjJBMDIyQzAyMkUwMjMwMDIzMjAyM0EwMjNCMDIzRDAyM0UwMjQxMDI0My0wMjQ2MDI0ODAyNEEwMjRDMDI0RTAzNzAwMzcyMDM3NjAzODYwMzg4LTAzOEEwMzhDMDM4RTAzOEYwMzkxLTAzQTEwM0EzLTAzQUIwM0NGMDNEMi0wM0Q0MDNEODAzREEwM0RDMDNERTAzRTAwM0UyMDNFNDAzRTYwM0U4MDNFQTAzRUMwM0VFMDNGNDAzRjcwM0Y5MDNGQTAzRkQtMDQyRjA0NjAwNDYyMDQ2NDA0NjYwNDY4MDQ2QTA0NkMwNDZFMDQ3MDA0NzIwNDc0MDQ3NjA0NzgwNDdBMDQ3QzA0N0UwNDgwMDQ4QTA0OEMwNDhFMDQ5MDA0OTIwNDk0MDQ5NjA0OTgwNDlBMDQ5QzA0OUUwNEEwMDRBMjA0QTQwNEE2MDRBODA0QUEwNEFDMDRBRTA0QjAwNEIyMDRCNDA0QjYwNEI4MDRCQTA0QkMwNEJFMDRDMDA0QzEwNEMzMDRDNTA0QzcwNEM5MDRDQjA0Q0QwNEQwMDREMjA0RDQwNEQ2MDREODA0REEwNERDMDRERTA0RTAwNEUyMDRFNDA0RTYwNEU4MDRFQTA0RUMwNEVFMDRGMDA0RjIwNEY0MDRGNjA0RjgwNEZBMDRGQzA0RkUwNTAwMDUwMjA1MDQwNTA2MDUwODA1MEEwNTBDMDUwRTA1MTAwNTEyMDUxNDA1MTYwNTE4MDUxQTA1MUMwNTFFMDUyMDA1MjIwNTI0MDUyNjA1MzEtMDU1NjEwQTAtMTBDNTEwQzcxMENEMUUwMDFFMDIxRTA0MUUwNjFFMDgxRTBBMUUwQzFFMEUxRTEwMUUxMjFFMTQxRTE2MUUxODFFMUExRTFDMUUxRTFFMjAxRTIyMUUyNDFFMjYxRTI4MUUyQTFFMkMxRTJFMUUzMDFFMzIxRTM0MUUzNjFFMzgxRTNBMUUzQzFFM0UxRTQwMUU0MjFFNDQxRTQ2MUU0ODFFNEExRTRDMUU0RTFFNTAxRTUyMUU1NDFFNTYxRTU4MUU1QTFFNUMxRTVFMUU2MDFFNjIxRTY0MUU2NjFFNjgxRTZBMUU2QzFFNkUxRTcwMUU3MjFFNzQxRTc2MUU3ODFFN0ExRTdDMUU3RTFFODAxRTgyMUU4NDFFODYxRTg4MUU4QTFFOEMxRThFMUU5MDFFOTIxRTk0MUU5RTFFQTAxRUEyMUVBNDFFQTYxRUE4MUVBQTFFQUMxRUFFMUVCMDFFQjIxRUI0MUVCNjFFQjgxRUJBMUVCQzFFQkUxRUMwMUVDMjFFQzQxRUM2MUVDODFFQ0ExRUNDMUVDRTFFRDAxRUQyMUVENDFFRDYxRUQ4MUVEQTFFREMxRURFMUVFMDFFRTIxRUU0MUVFNjFFRTgxRUVBMUVFQzFFRUUxRUYwMUVGMjFFRjQxRUY2MUVGODFFRkExRUZDMUVGRTFGMDgtMUYwRjFGMTgtMUYxRDFGMjgtMUYyRjFGMzgtMUYzRjFGNDgtMUY0RDFGNTkxRjVCMUY1RDFGNUYxRjY4LTFGNkYxRkI4LTFGQkIxRkM4LTFGQ0IxRkQ4LTFGREIxRkU4LTFGRUMxRkY4LTFGRkIyMTAyMjEwNzIxMEItMjEwRDIxMTAtMjExMjIxMTUyMTE5LTIxMUQyMTI0MjEyNjIxMjgyMTJBLTIxMkQyMTMwLTIxMzMyMTNFMjEzRjIxNDUyMTYwLTIxNkYyMTgzMjRCNi0yNENGMkMwMC0yQzJFMkM2MDJDNjItMkM2NDJDNjcyQzY5MkM2QjJDNkQtMkM3MDJDNzIyQzc1MkM3RS0yQzgwMkM4MjJDODQyQzg2MkM4ODJDOEEyQzhDMkM4RTJDOTAyQzkyMkM5NDJDOTYyQzk4MkM5QTJDOUMyQzlFMkNBMDJDQTIyQ0E0MkNBNjJDQTgyQ0FBMkNBQzJDQUUyQ0IwMkNCMjJDQjQyQ0I2MkNCODJDQkEyQ0JDMkNCRTJDQzAyQ0MyMkNDNDJDQzYyQ0M4MkNDQTJDQ0MyQ0NFMkNEMDJDRDIyQ0Q0MkNENjJDRDgyQ0RBMkNEQzJDREUyQ0UwMkNFMjJDRUIyQ0VEMkNGMkE2NDBBNjQyQTY0NEE2NDZBNjQ4QTY0QUE2NENBNjRFQTY1MEE2NTJBNjU0QTY1NkE2NThBNjVBQTY1Q0E2NUVBNjYwQTY2MkE2NjRBNjY2QTY2OEE2NkFBNjZDQTY4MEE2ODJBNjg0QTY4NkE2ODhBNjhBQTY4Q0E2OEVBNjkwQTY5MkE2OTRBNjk2QTcyMkE3MjRBNzI2QTcyOEE3MkFBNzJDQTcyRUE3MzJBNzM0QTczNkE3MzhBNzNBQTczQ0E3M0VBNzQwQTc0MkE3NDRBNzQ2QTc0OEE3NEFBNzRDQTc0RUE3NTBBNzUyQTc1NEE3NTZBNzU4QTc1QUE3NUNBNzVFQTc2MEE3NjJBNzY0QTc2NkE3NjhBNzZBQTc2Q0E3NkVBNzc5QTc3QkE3N0RBNzdFQTc4MEE3ODJBNzg0QTc4NkE3OEJBNzhEQTc5MEE3OTJBN0EwQTdBMkE3QTRBN0E2QTdBOEE3QUFGRjIxLUZGM0EiLAogICAgICAgIExvd2VyY2FzZTogIjAwNjEtMDA3QTAwQUEwMEI1MDBCQTAwREYtMDBGNjAwRjgtMDBGRjAxMDEwMTAzMDEwNTAxMDcwMTA5MDEwQjAxMEQwMTBGMDExMTAxMTMwMTE1MDExNzAxMTkwMTFCMDExRDAxMUYwMTIxMDEyMzAxMjUwMTI3MDEyOTAxMkIwMTJEMDEyRjAxMzEwMTMzMDEzNTAxMzcwMTM4MDEzQTAxM0MwMTNFMDE0MDAxNDIwMTQ0MDE0NjAxNDgwMTQ5MDE0QjAxNEQwMTRGMDE1MTAxNTMwMTU1MDE1NzAxNTkwMTVCMDE1RDAxNUYwMTYxMDE2MzAxNjUwMTY3MDE2OTAxNkIwMTZEMDE2RjAxNzEwMTczMDE3NTAxNzcwMTdBMDE3QzAxN0UtMDE4MDAxODMwMTg1MDE4ODAxOEMwMThEMDE5MjAxOTUwMTk5LTAxOUIwMTlFMDFBMTAxQTMwMUE1MDFBODAxQUEwMUFCMDFBRDAxQjAwMUI0MDFCNjAxQjkwMUJBMDFCRC0wMUJGMDFDNjAxQzkwMUNDMDFDRTAxRDAwMUQyMDFENDAxRDYwMUQ4MDFEQTAxREMwMUREMDFERjAxRTEwMUUzMDFFNTAxRTcwMUU5MDFFQjAxRUQwMUVGMDFGMDAxRjMwMUY1MDFGOTAxRkIwMUZEMDFGRjAyMDEwMjAzMDIwNTAyMDcwMjA5MDIwQjAyMEQwMjBGMDIxMTAyMTMwMjE1MDIxNzAyMTkwMjFCMDIxRDAyMUYwMjIxMDIyMzAyMjUwMjI3MDIyOTAyMkIwMjJEMDIyRjAyMzEwMjMzLTAyMzkwMjNDMDIzRjAyNDAwMjQyMDI0NzAyNDkwMjRCMDI0RDAyNEYtMDI5MzAyOTUtMDJCODAyQzAwMkMxMDJFMC0wMkU0MDM0NTAzNzEwMzczMDM3NzAzN0EtMDM3RDAzOTAwM0FDLTAzQ0UwM0QwMDNEMTAzRDUtMDNENzAzRDkwM0RCMDNERDAzREYwM0UxMDNFMzAzRTUwM0U3MDNFOTAzRUIwM0VEMDNFRi0wM0YzMDNGNTAzRjgwM0ZCMDNGQzA0MzAtMDQ1RjA0NjEwNDYzMDQ2NTA0NjcwNDY5MDQ2QjA0NkQwNDZGMDQ3MTA0NzMwNDc1MDQ3NzA0NzkwNDdCMDQ3RDA0N0YwNDgxMDQ4QjA0OEQwNDhGMDQ5MTA0OTMwNDk1MDQ5NzA0OTkwNDlCMDQ5RDA0OUYwNEExMDRBMzA0QTUwNEE3MDRBOTA0QUIwNEFEMDRBRjA0QjEwNEIzMDRCNTA0QjcwNEI5MDRCQjA0QkQwNEJGMDRDMjA0QzQwNEM2MDRDODA0Q0EwNENDMDRDRTA0Q0YwNEQxMDREMzA0RDUwNEQ3MDREOTA0REIwNEREMDRERjA0RTEwNEUzMDRFNTA0RTcwNEU5MDRFQjA0RUQwNEVGMDRGMTA0RjMwNEY1MDRGNzA0RjkwNEZCMDRGRDA0RkYwNTAxMDUwMzA1MDUwNTA3MDUwOTA1MEIwNTBEMDUwRjA1MTEwNTEzMDUxNTA1MTcwNTE5MDUxQjA1MUQwNTFGMDUyMTA1MjMwNTI1MDUyNzA1NjEtMDU4NzFEMDAtMURCRjFFMDExRTAzMUUwNTFFMDcxRTA5MUUwQjFFMEQxRTBGMUUxMTFFMTMxRTE1MUUxNzFFMTkxRTFCMUUxRDFFMUYxRTIxMUUyMzFFMjUxRTI3MUUyOTFFMkIxRTJEMUUyRjFFMzExRTMzMUUzNTFFMzcxRTM5MUUzQjFFM0QxRTNGMUU0MTFFNDMxRTQ1MUU0NzFFNDkxRTRCMUU0RDFFNEYxRTUxMUU1MzFFNTUxRTU3MUU1OTFFNUIxRTVEMUU1RjFFNjExRTYzMUU2NTFFNjcxRTY5MUU2QjFFNkQxRTZGMUU3MTFFNzMxRTc1MUU3NzFFNzkxRTdCMUU3RDFFN0YxRTgxMUU4MzFFODUxRTg3MUU4OTFFOEIxRThEMUU4RjFFOTExRTkzMUU5NS0xRTlEMUU5RjFFQTExRUEzMUVBNTFFQTcxRUE5MUVBQjFFQUQxRUFGMUVCMTFFQjMxRUI1MUVCNzFFQjkxRUJCMUVCRDFFQkYxRUMxMUVDMzFFQzUxRUM3MUVDOTFFQ0IxRUNEMUVDRjFFRDExRUQzMUVENTFFRDcxRUQ5MUVEQjFFREQxRURGMUVFMTFFRTMxRUU1MUVFNzFFRTkxRUVCMUVFRDFFRUYxRUYxMUVGMzFFRjUxRUY3MUVGOTFFRkIxRUZEMUVGRi0xRjA3MUYxMC0xRjE1MUYyMC0xRjI3MUYzMC0xRjM3MUY0MC0xRjQ1MUY1MC0xRjU3MUY2MC0xRjY3MUY3MC0xRjdEMUY4MC0xRjg3MUY5MC0xRjk3MUZBMC0xRkE3MUZCMC0xRkI0MUZCNjFGQjcxRkJFMUZDMi0xRkM0MUZDNjFGQzcxRkQwLTFGRDMxRkQ2MUZENzFGRTAtMUZFNzFGRjItMUZGNDFGRjYxRkY3MjA3MTIwN0YyMDkwLTIwOUMyMTBBMjEwRTIxMEYyMTEzMjEyRjIxMzQyMTM5MjEzQzIxM0QyMTQ2LTIxNDkyMTRFMjE3MC0yMTdGMjE4NDI0RDAtMjRFOTJDMzAtMkM1RTJDNjEyQzY1MkM2NjJDNjgyQzZBMkM2QzJDNzEyQzczMkM3NDJDNzYtMkM3RDJDODEyQzgzMkM4NTJDODcyQzg5MkM4QjJDOEQyQzhGMkM5MTJDOTMyQzk1MkM5NzJDOTkyQzlCMkM5RDJDOUYyQ0ExMkNBMzJDQTUyQ0E3MkNBOTJDQUIyQ0FEMkNBRjJDQjEyQ0IzMkNCNTJDQjcyQ0I5MkNCQjJDQkQyQ0JGMkNDMTJDQzMyQ0M1MkNDNzJDQzkyQ0NCMkNDRDJDQ0YyQ0QxMkNEMzJDRDUyQ0Q3MkNEOTJDREIyQ0REMkNERjJDRTEyQ0UzMkNFNDJDRUMyQ0VFMkNGMzJEMDAtMkQyNTJEMjcyRDJEQTY0MUE2NDNBNjQ1QTY0N0E2NDlBNjRCQTY0REE2NEZBNjUxQTY1M0E2NTVBNjU3QTY1OUE2NUJBNjVEQTY1RkE2NjFBNjYzQTY2NUE2NjdBNjY5QTY2QkE2NkRBNjgxQTY4M0E2ODVBNjg3QTY4OUE2OEJBNjhEQTY4RkE2OTFBNjkzQTY5NUE2OTdBNzIzQTcyNUE3MjdBNzI5QTcyQkE3MkRBNzJGLUE3MzFBNzMzQTczNUE3MzdBNzM5QTczQkE3M0RBNzNGQTc0MUE3NDNBNzQ1QTc0N0E3NDlBNzRCQTc0REE3NEZBNzUxQTc1M0E3NTVBNzU3QTc1OUE3NUJBNzVEQTc1RkE3NjFBNzYzQTc2NUE3NjdBNzY5QTc2QkE3NkRBNzZGLUE3NzhBNzdBQTc3Q0E3N0ZBNzgxQTc4M0E3ODVBNzg3QTc4Q0E3OEVBNzkxQTc5M0E3QTFBN0EzQTdBNUE3QTdBN0E5QTdGOC1BN0ZBRkIwMC1GQjA2RkIxMy1GQjE3RkY0MS1GRjVBIiwKICAgICAgICBXaGl0ZV9TcGFjZTogIjAwMDktMDAwRDAwMjAwMDg1MDBBMDE2ODAxODBFMjAwMC0yMDBBMjAyODIwMjkyMDJGMjA1RjMwMDAiLAogICAgICAgIE5vbmNoYXJhY3Rlcl9Db2RlX1BvaW50OiAiRkREMC1GREVGRkZGRUZGRkYiLAogICAgICAgIERlZmF1bHRfSWdub3JhYmxlX0NvZGVfUG9pbnQ6ICIwMEFEMDM0RjExNUYxMTYwMTdCNDE3QjUxODBCLTE4MEQyMDBCLTIwMEYyMDJBLTIwMkUyMDYwLTIwNkYzMTY0RkUwMC1GRTBGRkVGRkZGQTBGRkYwLUZGRjgiLAogICAgICAgIC8vIFxwe0FueX0gbWF0Y2hlcyBhIGNvZGUgdW5pdC4gVG8gbWF0Y2ggYW55IGNvZGUgcG9pbnQgdmlhIHN1cnJvZ2F0ZSBwYWlycywgdXNlICg/OltcMC1cdUQ3RkZcdURDMDAtXHVGRkZGXXxbXHVEODAwLVx1REJGRl1bXHVEQzAwLVx1REZGRl18W1x1RDgwMC1cdURCRkZdKQogICAgICAgIEFueTogIjAwMDAtRkZGRiIsIC8vIFxwe15Bbnl9IGNvbXBpbGVzIHRvIFteXHUwMDAwLVx1RkZGRl07IFtccHteQW55fV0gdG8gW10KICAgICAgICBBc2NpaTogIjAwMDAtMDA3RiIsCiAgICAgICAgLy8gXHB7QXNzaWduZWR9IGlzIGVxdWl2YWxlbnQgdG8gXHB7XkNufQogICAgICAgIC8vQXNzaWduZWQ6IFhSZWdFeHAoIltcXHB7XkNufV0iKS5zb3VyY2UucmVwbGFjZSgvW1tcXV18XFx1L2csICIiKSAvLyBOZWdhdGlvbiBpbnNpZGUgYSBjaGFyYWN0ZXIgY2xhc3MgdHJpZ2dlcnMgaW52ZXJzaW9uCiAgICAgICAgQXNzaWduZWQ6ICIwMDAwLTAzNzcwMzdBLTAzN0UwMzg0LTAzOEEwMzhDMDM4RS0wM0ExMDNBMy0wNTI3MDUzMS0wNTU2MDU1OS0wNTVGMDU2MS0wNTg3MDU4OTA1OEEwNThGMDU5MS0wNUM3MDVEMC0wNUVBMDVGMC0wNUY0MDYwMC0wNjA0MDYwNi0wNjFCMDYxRS0wNzBEMDcwRi0wNzRBMDc0RC0wN0IxMDdDMC0wN0ZBMDgwMC0wODJEMDgzMC0wODNFMDg0MC0wODVCMDg1RTA4QTAwOEEyLTA4QUMwOEU0LTA4RkUwOTAwLTA5NzcwOTc5LTA5N0YwOTgxLTA5ODMwOTg1LTA5OEMwOThGMDk5MDA5OTMtMDlBODA5QUEtMDlCMDA5QjIwOUI2LTA5QjkwOUJDLTA5QzQwOUM3MDlDODA5Q0ItMDlDRTA5RDcwOURDMDlERDA5REYtMDlFMzA5RTYtMDlGQjBBMDEtMEEwMzBBMDUtMEEwQTBBMEYwQTEwMEExMy0wQTI4MEEyQS0wQTMwMEEzMjBBMzMwQTM1MEEzNjBBMzgwQTM5MEEzQzBBM0UtMEE0MjBBNDcwQTQ4MEE0Qi0wQTREMEE1MTBBNTktMEE1QzBBNUUwQTY2LTBBNzUwQTgxLTBBODMwQTg1LTBBOEQwQThGLTBBOTEwQTkzLTBBQTgwQUFBLTBBQjAwQUIyMEFCMzBBQjUtMEFCOTBBQkMtMEFDNTBBQzctMEFDOTBBQ0ItMEFDRDBBRDAwQUUwLTBBRTMwQUU2LTBBRjEwQjAxLTBCMDMwQjA1LTBCMEMwQjBGMEIxMDBCMTMtMEIyODBCMkEtMEIzMDBCMzIwQjMzMEIzNS0wQjM5MEIzQy0wQjQ0MEI0NzBCNDgwQjRCLTBCNEQwQjU2MEI1NzBCNUMwQjVEMEI1Ri0wQjYzMEI2Ni0wQjc3MEI4MjBCODMwQjg1LTBCOEEwQjhFLTBCOTAwQjkyLTBCOTUwQjk5MEI5QTBCOUMwQjlFMEI5RjBCQTMwQkE0MEJBOC0wQkFBMEJBRS0wQkI5MEJCRS0wQkMyMEJDNi0wQkM4MEJDQS0wQkNEMEJEMDBCRDcwQkU2LTBCRkEwQzAxLTBDMDMwQzA1LTBDMEMwQzBFLTBDMTAwQzEyLTBDMjgwQzJBLTBDMzMwQzM1LTBDMzkwQzNELTBDNDQwQzQ2LTBDNDgwQzRBLTBDNEQwQzU1MEM1NjBDNTgwQzU5MEM2MC0wQzYzMEM2Ni0wQzZGMEM3OC0wQzdGMEM4MjBDODMwQzg1LTBDOEMwQzhFLTBDOTAwQzkyLTBDQTgwQ0FBLTBDQjMwQ0I1LTBDQjkwQ0JDLTBDQzQwQ0M2LTBDQzgwQ0NBLTBDQ0QwQ0Q1MENENjBDREUwQ0UwLTBDRTMwQ0U2LTBDRUYwQ0YxMENGMjBEMDIwRDAzMEQwNS0wRDBDMEQwRS0wRDEwMEQxMi0wRDNBMEQzRC0wRDQ0MEQ0Ni0wRDQ4MEQ0QS0wRDRFMEQ1NzBENjAtMEQ2MzBENjYtMEQ3NTBENzktMEQ3RjBEODIwRDgzMEQ4NS0wRDk2MEQ5QS0wREIxMERCMy0wREJCMERCRDBEQzAtMERDNjBEQ0EwRENGLTBERDQwREQ2MEREOC0wRERGMERGMi0wREY0MEUwMS0wRTNBMEUzRi0wRTVCMEU4MTBFODIwRTg0MEU4NzBFODgwRThBMEU4RDBFOTQtMEU5NzBFOTktMEU5RjBFQTEtMEVBMzBFQTUwRUE3MEVBQTBFQUIwRUFELTBFQjkwRUJCLTBFQkQwRUMwLTBFQzQwRUM2MEVDOC0wRUNEMEVEMC0wRUQ5MEVEQy0wRURGMEYwMC0wRjQ3MEY0OS0wRjZDMEY3MS0wRjk3MEY5OS0wRkJDMEZCRS0wRkNDMEZDRS0wRkRBMTAwMC0xMEM1MTBDNzEwQ0QxMEQwLTEyNDgxMjRBLTEyNEQxMjUwLTEyNTYxMjU4MTI1QS0xMjVEMTI2MC0xMjg4MTI4QS0xMjhEMTI5MC0xMkIwMTJCMi0xMkI1MTJCOC0xMkJFMTJDMDEyQzItMTJDNTEyQzgtMTJENjEyRDgtMTMxMDEzMTItMTMxNTEzMTgtMTM1QTEzNUQtMTM3QzEzODAtMTM5OTEzQTAtMTNGNDE0MDAtMTY5QzE2QTAtMTZGMDE3MDAtMTcwQzE3MEUtMTcxNDE3MjAtMTczNjE3NDAtMTc1MzE3NjAtMTc2QzE3NkUtMTc3MDE3NzIxNzczMTc4MC0xN0REMTdFMC0xN0U5MTdGMC0xN0Y5MTgwMC0xODBFMTgxMC0xODE5MTgyMC0xODc3MTg4MC0xOEFBMThCMC0xOEY1MTkwMC0xOTFDMTkyMC0xOTJCMTkzMC0xOTNCMTk0MDE5NDQtMTk2RDE5NzAtMTk3NDE5ODAtMTlBQjE5QjAtMTlDOTE5RDAtMTlEQTE5REUtMUExQjFBMUUtMUE1RTFBNjAtMUE3QzFBN0YtMUE4OTFBOTAtMUE5OTFBQTAtMUFBRDFCMDAtMUI0QjFCNTAtMUI3QzFCODAtMUJGMzFCRkMtMUMzNzFDM0ItMUM0OTFDNEQtMUM3RjFDQzAtMUNDNzFDRDAtMUNGNjFEMDAtMURFNjFERkMtMUYxNTFGMTgtMUYxRDFGMjAtMUY0NTFGNDgtMUY0RDFGNTAtMUY1NzFGNTkxRjVCMUY1RDFGNUYtMUY3RDFGODAtMUZCNDFGQjYtMUZDNDFGQzYtMUZEMzFGRDYtMUZEQjFGREQtMUZFRjFGRjItMUZGNDFGRjYtMUZGRTIwMDAtMjA2NDIwNkEtMjA3MTIwNzQtMjA4RTIwOTAtMjA5QzIwQTAtMjBCOTIwRDAtMjBGMDIxMDAtMjE4OTIxOTAtMjNGMzI0MDAtMjQyNjI0NDAtMjQ0QTI0NjAtMjZGRjI3MDEtMkI0QzJCNTAtMkI1OTJDMDAtMkMyRTJDMzAtMkM1RTJDNjAtMkNGMzJDRjktMkQyNTJEMjcyRDJEMkQzMC0yRDY3MkQ2RjJENzAyRDdGLTJEOTYyREEwLTJEQTYyREE4LTJEQUUyREIwLTJEQjYyREI4LTJEQkUyREMwLTJEQzYyREM4LTJEQ0UyREQwLTJERDYyREQ4LTJEREUyREUwLTJFM0IyRTgwLTJFOTkyRTlCLTJFRjMyRjAwLTJGRDUyRkYwLTJGRkIzMDAwLTMwM0YzMDQxLTMwOTYzMDk5LTMwRkYzMTA1LTMxMkQzMTMxLTMxOEUzMTkwLTMxQkEzMUMwLTMxRTMzMUYwLTMyMUUzMjIwLTMyRkUzMzAwLTREQjU0REMwLTlGQ0NBMDAwLUE0OENBNDkwLUE0QzZBNEQwLUE2MkJBNjQwLUE2OTdBNjlGLUE2RjdBNzAwLUE3OEVBNzkwLUE3OTNBN0EwLUE3QUFBN0Y4LUE4MkJBODMwLUE4MzlBODQwLUE4NzdBODgwLUE4QzRBOENFLUE4RDlBOEUwLUE4RkJBOTAwLUE5NTNBOTVGLUE5N0NBOTgwLUE5Q0RBOUNGLUE5RDlBOURFQTlERkFBMDAtQUEzNkFBNDAtQUE0REFBNTAtQUE1OUFBNUMtQUE3QkFBODAtQUFDMkFBREItQUFGNkFCMDEtQUIwNkFCMDktQUIwRUFCMTEtQUIxNkFCMjAtQUIyNkFCMjgtQUIyRUFCQzAtQUJFREFCRjAtQUJGOUFDMDAtRDdBM0Q3QjAtRDdDNkQ3Q0ItRDdGQkQ4MDAtRkE2REZBNzAtRkFEOUZCMDAtRkIwNkZCMTMtRkIxN0ZCMUQtRkIzNkZCMzgtRkIzQ0ZCM0VGQjQwRkI0MUZCNDNGQjQ0RkI0Ni1GQkMxRkJEMy1GRDNGRkQ1MC1GRDhGRkQ5Mi1GREM3RkRGMC1GREZERkUwMC1GRTE5RkUyMC1GRTI2RkUzMC1GRTUyRkU1NC1GRTY2RkU2OC1GRTZCRkU3MC1GRTc0RkU3Ni1GRUZDRkVGRkZGMDEtRkZCRUZGQzItRkZDN0ZGQ0EtRkZDRkZGRDItRkZEN0ZGREEtRkZEQ0ZGRTAtRkZFNkZGRTgtRkZFRUZGRjktRkZGRCIKICAgIH0pOwoKfShYUmVnRXhwKSk7CgoKLyoqKioqIG1hdGNocmVjdXJzaXZlLmpzICoqKioqLwoKLyohCiAqIFhSZWdFeHAubWF0Y2hSZWN1cnNpdmUgdjAuMi4wCiAqIChjKSAyMDA5LTIwMTIgU3RldmVuIExldml0aGFuIDxodHRwOi8veHJlZ2V4cC5jb20vPgogKiBNSVQgTGljZW5zZQogKi8KCihmdW5jdGlvbiAoWFJlZ0V4cCkgewogICAgInVzZSBzdHJpY3QiOwoKLyoqCiAqIFJldHVybnMgYSBtYXRjaCBkZXRhaWwgb2JqZWN0IGNvbXBvc2VkIG9mIHRoZSBwcm92aWRlZCB2YWx1ZXMuCiAqIEBwcml2YXRlCiAqLwogICAgZnVuY3Rpb24gcm93KHZhbHVlLCBuYW1lLCBzdGFydCwgZW5kKSB7CiAgICAgICAgcmV0dXJuIHt2YWx1ZTp2YWx1ZSwgbmFtZTpuYW1lLCBzdGFydDpzdGFydCwgZW5kOmVuZH07CiAgICB9CgovKioKICogUmV0dXJucyBhbiBhcnJheSBvZiBtYXRjaCBzdHJpbmdzIGJldHdlZW4gb3V0ZXJtb3N0IGxlZnQgYW5kIHJpZ2h0IGRlbGltaXRlcnMsIG9yIGFuIGFycmF5IG9mCiAqIG9iamVjdHMgd2l0aCBkZXRhaWxlZCBtYXRjaCBwYXJ0cyBhbmQgcG9zaXRpb24gZGF0YS4gQW4gZXJyb3IgaXMgdGhyb3duIGlmIGRlbGltaXRlcnMgYXJlCiAqIHVuYmFsYW5jZWQgd2l0aGluIHRoZSBkYXRhLgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBzZWFyY2guCiAqIEBwYXJhbSB7U3RyaW5nfSBsZWZ0IExlZnQgZGVsaW1pdGVyIGFzIGFuIFhSZWdFeHAgcGF0dGVybi4KICogQHBhcmFtIHtTdHJpbmd9IHJpZ2h0IFJpZ2h0IGRlbGltaXRlciBhcyBhbiBYUmVnRXhwIHBhdHRlcm4uCiAqIEBwYXJhbSB7U3RyaW5nfSBbZmxhZ3NdIEZsYWdzIGZvciB0aGUgbGVmdCBhbmQgcmlnaHQgZGVsaW1pdGVycy4gVXNlIGFueSBvZjogYGdpbW5zeHlgLgogKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIExldHMgeW91IHNwZWNpZnkgYHZhbHVlTmFtZXNgIGFuZCBgZXNjYXBlQ2hhcmAgb3B0aW9ucy4KICogQHJldHVybnMge0FycmF5fSBBcnJheSBvZiBtYXRjaGVzLCBvciBhbiBlbXB0eSBhcnJheS4KICogQGV4YW1wbGUKICoKICogLy8gQmFzaWMgdXNhZ2UKICogdmFyIHN0ciA9ICcodCgoZSkpcyl0KCkoaW5nKSc7CiAqIFhSZWdFeHAubWF0Y2hSZWN1cnNpdmUoc3RyLCAnXFwoJywgJ1xcKScsICdnJyk7CiAqIC8vIC0+IFsndCgoZSkpcycsICcnLCAnaW5nJ10KICoKICogLy8gRXh0ZW5kZWQgaW5mb3JtYXRpb24gbW9kZSB3aXRoIHZhbHVlTmFtZXMKICogc3RyID0gJ0hlcmUgaXMgPGRpdj4gPGRpdj5hbjwvZGl2PjwvZGl2PiBleGFtcGxlJzsKICogWFJlZ0V4cC5tYXRjaFJlY3Vyc2l2ZShzdHIsICc8ZGl2XFxzKj4nLCAnPC9kaXY+JywgJ2dpJywgewogKiAgIHZhbHVlTmFtZXM6IFsnYmV0d2VlbicsICdsZWZ0JywgJ21hdGNoJywgJ3JpZ2h0J10KICogfSk7CiAqIC8vIC0+IFsKICogLy8ge25hbWU6ICdiZXR3ZWVuJywgdmFsdWU6ICdIZXJlIGlzICcsICAgICAgIHN0YXJ0OiAwLCAgZW5kOiA4fSwKICogLy8ge25hbWU6ICdsZWZ0JywgICAgdmFsdWU6ICc8ZGl2PicsICAgICAgICAgIHN0YXJ0OiA4LCAgZW5kOiAxM30sCiAqIC8vIHtuYW1lOiAnbWF0Y2gnLCAgIHZhbHVlOiAnIDxkaXY+YW48L2Rpdj4nLCBzdGFydDogMTMsIGVuZDogMjd9LAogKiAvLyB7bmFtZTogJ3JpZ2h0JywgICB2YWx1ZTogJzwvZGl2PicsICAgICAgICAgc3RhcnQ6IDI3LCBlbmQ6IDMzfSwKICogLy8ge25hbWU6ICdiZXR3ZWVuJywgdmFsdWU6ICcgZXhhbXBsZScsICAgICAgIHN0YXJ0OiAzMywgZW5kOiA0MX0KICogLy8gXQogKgogKiAvLyBPbWl0dGluZyB1bm5lZWRlZCBwYXJ0cyB3aXRoIG51bGwgdmFsdWVOYW1lcywgYW5kIHVzaW5nIGVzY2FwZUNoYXIKICogc3RyID0gJy4uLnsxfVxce3tmdW5jdGlvbih4LHkpe3JldHVybiB5K3g7fX0nOwogKiBYUmVnRXhwLm1hdGNoUmVjdXJzaXZlKHN0ciwgJ3snLCAnfScsICdnJywgewogKiAgIHZhbHVlTmFtZXM6IFsnbGl0ZXJhbCcsIG51bGwsICd2YWx1ZScsIG51bGxdLAogKiAgIGVzY2FwZUNoYXI6ICdcXCcKICogfSk7CiAqIC8vIC0+IFsKICogLy8ge25hbWU6ICdsaXRlcmFsJywgdmFsdWU6ICcuLi4nLCBzdGFydDogMCwgZW5kOiAzfSwKICogLy8ge25hbWU6ICd2YWx1ZScsICAgdmFsdWU6ICcxJywgICBzdGFydDogNCwgZW5kOiA1fSwKICogLy8ge25hbWU6ICdsaXRlcmFsJywgdmFsdWU6ICdcXHsnLCBzdGFydDogNiwgZW5kOiA4fSwKICogLy8ge25hbWU6ICd2YWx1ZScsICAgdmFsdWU6ICdmdW5jdGlvbih4LHkpe3JldHVybiB5K3g7fScsIHN0YXJ0OiA5LCBlbmQ6IDM1fQogKiAvLyBdCiAqCiAqIC8vIFN0aWNreSBtb2RlIHZpYSBmbGFnIHkKICogc3RyID0gJzwxPjw8PDI+Pj48Mz40PDU+JzsKICogWFJlZ0V4cC5tYXRjaFJlY3Vyc2l2ZShzdHIsICc8JywgJz4nLCAnZ3knKTsKICogLy8gLT4gWycxJywgJzw8Mj4+JywgJzMnXQogKi8KICAgIFhSZWdFeHAubWF0Y2hSZWN1cnNpdmUgPSBmdW5jdGlvbiAoc3RyLCBsZWZ0LCByaWdodCwgZmxhZ3MsIG9wdGlvbnMpIHsKICAgICAgICBmbGFncyA9IGZsYWdzIHx8ICIiOwogICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogICAgICAgIHZhciBnbG9iYWwgPSBmbGFncy5pbmRleE9mKCJnIikgPiAtMSwKICAgICAgICAgICAgc3RpY2t5ID0gZmxhZ3MuaW5kZXhPZigieSIpID4gLTEsCiAgICAgICAgICAgIGJhc2ljRmxhZ3MgPSBmbGFncy5yZXBsYWNlKC95L2csICIiKSwgLy8gRmxhZyB5IGNvbnRyb2xsZWQgaW50ZXJuYWxseQogICAgICAgICAgICBlc2NhcGVDaGFyID0gb3B0aW9ucy5lc2NhcGVDaGFyLAogICAgICAgICAgICB2TiA9IG9wdGlvbnMudmFsdWVOYW1lcywKICAgICAgICAgICAgb3V0cHV0ID0gW10sCiAgICAgICAgICAgIG9wZW5Ub2tlbnMgPSAwLAogICAgICAgICAgICBkZWxpbVN0YXJ0ID0gMCwKICAgICAgICAgICAgZGVsaW1FbmQgPSAwLAogICAgICAgICAgICBsYXN0T3V0ZXJFbmQgPSAwLAogICAgICAgICAgICBvdXRlclN0YXJ0LAogICAgICAgICAgICBpbm5lclN0YXJ0LAogICAgICAgICAgICBsZWZ0TWF0Y2gsCiAgICAgICAgICAgIHJpZ2h0TWF0Y2gsCiAgICAgICAgICAgIGVzYzsKICAgICAgICBsZWZ0ID0gWFJlZ0V4cChsZWZ0LCBiYXNpY0ZsYWdzKTsKICAgICAgICByaWdodCA9IFhSZWdFeHAocmlnaHQsIGJhc2ljRmxhZ3MpOwoKICAgICAgICBpZiAoZXNjYXBlQ2hhcikgewogICAgICAgICAgICBpZiAoZXNjYXBlQ2hhci5sZW5ndGggPiAxKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoImNhbid0IHVzZSBtb3JlIHRoYW4gb25lIGVzY2FwZSBjaGFyYWN0ZXIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlc2NhcGVDaGFyID0gWFJlZ0V4cC5lc2NhcGUoZXNjYXBlQ2hhcik7CiAgICAgICAgICAgIC8vIFVzaW5nIFhSZWdFeHAudW5pb24gc2FmZWx5IHJld3JpdGVzIGJhY2tyZWZlcmVuY2VzIGluIGBsZWZ0YCBhbmQgYHJpZ2h0YAogICAgICAgICAgICBlc2MgPSBuZXcgUmVnRXhwKAogICAgICAgICAgICAgICAgIig/OiIgKyBlc2NhcGVDaGFyICsgIltcXFNcXHNdfCg/Oig/ISIgKyBYUmVnRXhwLnVuaW9uKFtsZWZ0LCByaWdodF0pLnNvdXJjZSArICIpW14iICsgZXNjYXBlQ2hhciArICJdKSspKyIsCiAgICAgICAgICAgICAgICBmbGFncy5yZXBsYWNlKC9bXmltXSsvZywgIiIpIC8vIEZsYWdzIGd5IG5vdCBuZWVkZWQgaGVyZTsgZmxhZ3MgbnN4IGhhbmRsZWQgYnkgWFJlZ0V4cAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgICAgLy8gSWYgdXNpbmcgYW4gZXNjYXBlIGNoYXJhY3RlciwgYWR2YW5jZSB0byB0aGUgZGVsaW1pdGVyJ3MgbmV4dCBzdGFydGluZyBwb3NpdGlvbiwKICAgICAgICAgICAgLy8gc2tpcHBpbmcgYW55IGVzY2FwZWQgY2hhcmFjdGVycyBpbiBiZXR3ZWVuCiAgICAgICAgICAgIGlmIChlc2NhcGVDaGFyKSB7CiAgICAgICAgICAgICAgICBkZWxpbUVuZCArPSAoWFJlZ0V4cC5leGVjKHN0ciwgZXNjLCBkZWxpbUVuZCwgInN0aWNreSIpIHx8IFsiIl0pWzBdLmxlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgICAgICBsZWZ0TWF0Y2ggPSBYUmVnRXhwLmV4ZWMoc3RyLCBsZWZ0LCBkZWxpbUVuZCk7CiAgICAgICAgICAgIHJpZ2h0TWF0Y2ggPSBYUmVnRXhwLmV4ZWMoc3RyLCByaWdodCwgZGVsaW1FbmQpOwogICAgICAgICAgICAvLyBLZWVwIHRoZSBsZWZ0bW9zdCBtYXRjaCBvbmx5CiAgICAgICAgICAgIGlmIChsZWZ0TWF0Y2ggJiYgcmlnaHRNYXRjaCkgewogICAgICAgICAgICAgICAgaWYgKGxlZnRNYXRjaC5pbmRleCA8PSByaWdodE1hdGNoLmluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgcmlnaHRNYXRjaCA9IG51bGw7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGxlZnRNYXRjaCA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogUGF0aHMgKExNOmxlZnRNYXRjaCwgUk06cmlnaHRNYXRjaCwgT1Q6b3BlblRva2Vucyk6CiAgICAgICAgICAgIExNIHwgUk0gfCBPVCB8IFJlc3VsdAogICAgICAgICAgICAxICB8IDAgIHwgMSAgfCBsb29wCiAgICAgICAgICAgIDEgIHwgMCAgfCAwICB8IGxvb3AKICAgICAgICAgICAgMCAgfCAxICB8IDEgIHwgbG9vcAogICAgICAgICAgICAwICB8IDEgIHwgMCAgfCB0aHJvdwogICAgICAgICAgICAwICB8IDAgIHwgMSAgfCB0aHJvdwogICAgICAgICAgICAwICB8IDAgIHwgMCAgfCBicmVhawogICAgICAgICAgICAqIERvZXNuJ3QgaW5jbHVkZSB0aGUgc3RpY2t5IG1vZGUgc3BlY2lhbCBjYXNlCiAgICAgICAgICAgICogTG9vcCBlbmRzIGFmdGVyIHRoZSBmaXJzdCBjb21wbGV0ZWQgbWF0Y2ggaWYgYCFnbG9iYWxgICovCiAgICAgICAgICAgIGlmIChsZWZ0TWF0Y2ggfHwgcmlnaHRNYXRjaCkgewogICAgICAgICAgICAgICAgZGVsaW1TdGFydCA9IChsZWZ0TWF0Y2ggfHwgcmlnaHRNYXRjaCkuaW5kZXg7CiAgICAgICAgICAgICAgICBkZWxpbUVuZCA9IGRlbGltU3RhcnQgKyAobGVmdE1hdGNoIHx8IHJpZ2h0TWF0Y2gpWzBdLmxlbmd0aDsKICAgICAgICAgICAgfSBlbHNlIGlmICghb3BlblRva2VucykgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHN0aWNreSAmJiAhb3BlblRva2VucyAmJiBkZWxpbVN0YXJ0ID4gbGFzdE91dGVyRW5kKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobGVmdE1hdGNoKSB7CiAgICAgICAgICAgICAgICBpZiAoIW9wZW5Ub2tlbnMpIHsKICAgICAgICAgICAgICAgICAgICBvdXRlclN0YXJ0ID0gZGVsaW1TdGFydDsKICAgICAgICAgICAgICAgICAgICBpbm5lclN0YXJ0ID0gZGVsaW1FbmQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICArK29wZW5Ub2tlbnM7CiAgICAgICAgICAgIH0gZWxzZSBpZiAocmlnaHRNYXRjaCAmJiBvcGVuVG9rZW5zKSB7CiAgICAgICAgICAgICAgICBpZiAoIS0tb3BlblRva2VucykgewogICAgICAgICAgICAgICAgICAgIGlmICh2TikgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAodk5bMF0gJiYgb3V0ZXJTdGFydCA+IGxhc3RPdXRlckVuZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0LnB1c2gocm93KHZOWzBdLCBzdHIuc2xpY2UobGFzdE91dGVyRW5kLCBvdXRlclN0YXJ0KSwgbGFzdE91dGVyRW5kLCBvdXRlclN0YXJ0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZOWzFdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQucHVzaChyb3codk5bMV0sIHN0ci5zbGljZShvdXRlclN0YXJ0LCBpbm5lclN0YXJ0KSwgb3V0ZXJTdGFydCwgaW5uZXJTdGFydCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2TlsyXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0LnB1c2gocm93KHZOWzJdLCBzdHIuc2xpY2UoaW5uZXJTdGFydCwgZGVsaW1TdGFydCksIGlubmVyU3RhcnQsIGRlbGltU3RhcnQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAodk5bM10pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKHJvdyh2TlszXSwgc3RyLnNsaWNlKGRlbGltU3RhcnQsIGRlbGltRW5kKSwgZGVsaW1TdGFydCwgZGVsaW1FbmQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKHN0ci5zbGljZShpbm5lclN0YXJ0LCBkZWxpbVN0YXJ0KSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGxhc3RPdXRlckVuZCA9IGRlbGltRW5kOwogICAgICAgICAgICAgICAgICAgIGlmICghZ2xvYmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigic3RyaW5nIGNvbnRhaW5zIHVuYmFsYW5jZWQgZGVsaW1pdGVycyIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIElmIHRoZSBkZWxpbWl0ZXIgbWF0Y2hlZCBhbiBlbXB0eSBzdHJpbmcsIGF2b2lkIGFuIGluZmluaXRlIGxvb3AKICAgICAgICAgICAgaWYgKGRlbGltU3RhcnQgPT09IGRlbGltRW5kKSB7CiAgICAgICAgICAgICAgICArK2RlbGltRW5kOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoZ2xvYmFsICYmICFzdGlja3kgJiYgdk4gJiYgdk5bMF0gJiYgc3RyLmxlbmd0aCA+IGxhc3RPdXRlckVuZCkgewogICAgICAgICAgICBvdXRwdXQucHVzaChyb3codk5bMF0sIHN0ci5zbGljZShsYXN0T3V0ZXJFbmQpLCBsYXN0T3V0ZXJFbmQsIHN0ci5sZW5ndGgpKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBvdXRwdXQ7CiAgICB9OwoKfShYUmVnRXhwKSk7CgoKLyoqKioqIGJ1aWxkLmpzICoqKioqLwoKLyohCiAqIFhSZWdFeHAuYnVpbGQgdjAuMS4wCiAqIChjKSAyMDEyIFN0ZXZlbiBMZXZpdGhhbiA8aHR0cDovL3hyZWdleHAuY29tLz4KICogTUlUIExpY2Vuc2UKICogSW5zcGlyZWQgYnkgUmVnRXhwLmNyZWF0ZSBieSBMZWEgVmVyb3UgPGh0dHA6Ly9sZWEudmVyb3UubWUvPgogKi8KCihmdW5jdGlvbiAoWFJlZ0V4cCkgewogICAgInVzZSBzdHJpY3QiOwoKICAgIHZhciBzdWJwYXJ0cyA9IC8oXCgpKD8hXD8pfFxcKFsxLTldXGQqKXxcXFtcc1xTXXxcWyg/OlteXFxcXV18XFxbXHNcU10pKl0vZywKICAgICAgICBwYXJ0cyA9IFhSZWdFeHAudW5pb24oWy9cKHt7KFtcdyRdKyl9fVwpfHt7KFtcdyRdKyl9fS8sIHN1YnBhcnRzXSwgImciKTsKCi8qKgogKiBTdHJpcHMgYSBsZWFkaW5nIGBeYCBhbmQgdHJhaWxpbmcgdW5lc2NhcGVkIGAkYCwgaWYgYm90aCBhcmUgcHJlc2VudC4KICogQHByaXZhdGUKICogQHBhcmFtIHtTdHJpbmd9IHBhdHRlcm4gUGF0dGVybiB0byBwcm9jZXNzLgogKiBAcmV0dXJucyB7U3RyaW5nfSBQYXR0ZXJuIHdpdGggZWRnZSBhbmNob3JzIHJlbW92ZWQuCiAqLwogICAgZnVuY3Rpb24gZGVhbmNob3IocGF0dGVybikgewogICAgICAgIHZhciBzdGFydEFuY2hvciA9IC9eKD86XChcPzpcKSk/XF4vLCAvLyBMZWFkaW5nIGBeYCBvciBgKD86KV5gIChoYW5kbGVzIC94IGNydWZ0KQogICAgICAgICAgICBlbmRBbmNob3IgPSAvXCQoPzpcKFw/OlwpKT8kLzsgLy8gVHJhaWxpbmcgYCRgIG9yIGAkKD86KWAgKGhhbmRsZXMgL3ggY3J1ZnQpCiAgICAgICAgaWYgKGVuZEFuY2hvci50ZXN0KHBhdHRlcm4ucmVwbGFjZSgvXFxbXHNcU10vZywgIiIpKSkgeyAvLyBFbnN1cmUgdHJhaWxpbmcgYCRgIGlzbid0IGVzY2FwZWQKICAgICAgICAgICAgcmV0dXJuIHBhdHRlcm4ucmVwbGFjZShzdGFydEFuY2hvciwgIiIpLnJlcGxhY2UoZW5kQW5jaG9yLCAiIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwYXR0ZXJuOwogICAgfQoKLyoqCiAqIENvbnZlcnRzIHRoZSBwcm92aWRlZCB2YWx1ZSB0byBhbiBYUmVnRXhwLgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IHZhbHVlIFZhbHVlIHRvIGNvbnZlcnQuCiAqIEByZXR1cm5zIHtSZWdFeHB9IFhSZWdFeHAgb2JqZWN0IHdpdGggWFJlZ0V4cCBzeW50YXggYXBwbGllZC4KICovCiAgICBmdW5jdGlvbiBhc1hSZWdFeHAodmFsdWUpIHsKICAgICAgICByZXR1cm4gWFJlZ0V4cC5pc1JlZ0V4cCh2YWx1ZSkgPwogICAgICAgICAgICAgICAgKHZhbHVlLnhyZWdleHAgJiYgIXZhbHVlLnhyZWdleHAuaXNOYXRpdmUgPyB2YWx1ZSA6IFhSZWdFeHAodmFsdWUuc291cmNlKSkgOgogICAgICAgICAgICAgICAgWFJlZ0V4cCh2YWx1ZSk7CiAgICB9CgovKioKICogQnVpbGRzIHJlZ2V4ZXMgdXNpbmcgbmFtZWQgc3VicGF0dGVybnMsIGZvciByZWFkYWJpbGl0eSBhbmQgcGF0dGVybiByZXVzZS4gQmFja3JlZmVyZW5jZXMgaW4gdGhlCiAqIG91dGVyIHBhdHRlcm4gYW5kIHByb3ZpZGVkIHN1YnBhdHRlcm5zIGFyZSBhdXRvbWF0aWNhbGx5IHJlbnVtYmVyZWQgdG8gd29yayBjb3JyZWN0bHkuIE5hdGl2ZQogKiBmbGFncyB1c2VkIGJ5IHByb3ZpZGVkIHN1YnBhdHRlcm5zIGFyZSBpZ25vcmVkIGluIGZhdm9yIG9mIHRoZSBgZmxhZ3NgIGFyZ3VtZW50LgogKiBAbWVtYmVyT2YgWFJlZ0V4cAogKiBAcGFyYW0ge1N0cmluZ30gcGF0dGVybiBYUmVnRXhwIHBhdHRlcm4gdXNpbmcgYHt7bmFtZX19YCBmb3IgZW1iZWRkZWQgc3VicGF0dGVybnMuIEFsbG93cwogKiAgIGAoe3tuYW1lfX0pYCBhcyBzaG9ydGhhbmQgZm9yIGAoPzxuYW1lPnt7bmFtZX19KWAuIFBhdHRlcm5zIGNhbm5vdCBiZSBlbWJlZGRlZCB3aXRoaW4KICogICBjaGFyYWN0ZXIgY2xhc3Nlcy4KICogQHBhcmFtIHtPYmplY3R9IHN1YnMgTG9va3VwIG9iamVjdCBmb3IgbmFtZWQgc3VicGF0dGVybnMuIFZhbHVlcyBjYW4gYmUgc3RyaW5ncyBvciByZWdleGVzLiBBCiAqICAgbGVhZGluZyBgXmAgYW5kIHRyYWlsaW5nIHVuZXNjYXBlZCBgJGAgYXJlIHN0cmlwcGVkIGZyb20gc3VicGF0dGVybnMsIGlmIGJvdGggYXJlIHByZXNlbnQuCiAqIEBwYXJhbSB7U3RyaW5nfSBbZmxhZ3NdIEFueSBjb21iaW5hdGlvbiBvZiBYUmVnRXhwIGZsYWdzLgogKiBAcmV0dXJucyB7UmVnRXhwfSBSZWdleCB3aXRoIGludGVycG9sYXRlZCBzdWJwYXR0ZXJucy4KICogQGV4YW1wbGUKICoKICogdmFyIHRpbWUgPSBYUmVnRXhwLmJ1aWxkKCcoP3gpXiB7e2hvdXJzfX0gKHt7bWludXRlc319KSAkJywgewogKiAgIGhvdXJzOiBYUmVnRXhwLmJ1aWxkKCd7e2gxMn19IDogfCB7e2gyNH19JywgewogKiAgICAgaDEyOiAvMVswLTJdfDA/WzEtOV0vLAogKiAgICAgaDI0OiAvMlswLTNdfFswMV1bMC05XS8KICogICB9LCAneCcpLAogKiAgIG1pbnV0ZXM6IC9eWzAtNV1bMC05XSQvCiAqIH0pOwogKiB0aW1lLnRlc3QoJzEwOjU5Jyk7IC8vIC0+IHRydWUKICogWFJlZ0V4cC5leGVjKCcxMDo1OScsIHRpbWUpLm1pbnV0ZXM7IC8vIC0+ICc1OScKICovCiAgICBYUmVnRXhwLmJ1aWxkID0gZnVuY3Rpb24gKHBhdHRlcm4sIHN1YnMsIGZsYWdzKSB7CiAgICAgICAgdmFyIGlubGluZUZsYWdzID0gL15cKFw/KFtcdyRdKylcKS8uZXhlYyhwYXR0ZXJuKSwKICAgICAgICAgICAgZGF0YSA9IHt9LAogICAgICAgICAgICBudW1DYXBzID0gMCwgLy8gQ2FwcyBpcyBzaG9ydCBmb3IgY2FwdHVyZXMKICAgICAgICAgICAgbnVtUHJpb3JDYXBzLAogICAgICAgICAgICBudW1PdXRlckNhcHMgPSAwLAogICAgICAgICAgICBvdXRlckNhcHNNYXAgPSBbMF0sCiAgICAgICAgICAgIG91dGVyQ2FwTmFtZXMsCiAgICAgICAgICAgIHN1YiwKICAgICAgICAgICAgcDsKCiAgICAgICAgLy8gQWRkIGZsYWdzIHdpdGhpbiBhIGxlYWRpbmcgbW9kZSBtb2RpZmllciB0byB0aGUgb3ZlcmFsbCBwYXR0ZXJuJ3MgZmxhZ3MKICAgICAgICBpZiAoaW5saW5lRmxhZ3MpIHsKICAgICAgICAgICAgZmxhZ3MgPSBmbGFncyB8fCAiIjsKICAgICAgICAgICAgaW5saW5lRmxhZ3NbMV0ucmVwbGFjZSgvLi9nLCBmdW5jdGlvbiAoZmxhZykgewogICAgICAgICAgICAgICAgZmxhZ3MgKz0gKGZsYWdzLmluZGV4T2YoZmxhZykgPiAtMSA/ICIiIDogZmxhZyk7IC8vIERvbid0IGFkZCBkdXBsaWNhdGVzCiAgICAgICAgICAgIH0pOwogICAgICAgIH0KCiAgICAgICAgZm9yIChwIGluIHN1YnMpIHsKICAgICAgICAgICAgaWYgKHN1YnMuaGFzT3duUHJvcGVydHkocCkpIHsKICAgICAgICAgICAgICAgIC8vIFBhc3NpbmcgdG8gWFJlZ0V4cCBlbmFibGVzIGVudGVuZGVkIHN5bnRheCBmb3Igc3VicGF0dGVybnMgcHJvdmlkZWQgYXMgc3RyaW5ncwogICAgICAgICAgICAgICAgLy8gYW5kIGVuc3VyZXMgaW5kZXBlbmRlbnQgdmFsaWRpdHksIGxlc3QgYW4gdW5lc2NhcGVkIGAoYCwgYClgLCBgW2AsIG9yIHRyYWlsaW5nCiAgICAgICAgICAgICAgICAvLyBgXGAgYnJlYWtzIHRoZSBgKD86KWAgd3JhcHBlci4gRm9yIHN1YnBhdHRlcm5zIHByb3ZpZGVkIGFzIHJlZ2V4ZXMsIGl0IGRpZXMgb24KICAgICAgICAgICAgICAgIC8vIG9jdGFscyBhbmQgYWRkcyB0aGUgYHhyZWdleHBgIHByb3BlcnR5LCBmb3Igc2ltcGxpY2l0eQogICAgICAgICAgICAgICAgc3ViID0gYXNYUmVnRXhwKHN1YnNbcF0pOwogICAgICAgICAgICAgICAgLy8gRGVhbmNob3JpbmcgYWxsb3dzIGVtYmVkZGluZyBpbmRlcGVuZGVudGx5IHVzZWZ1bCBhbmNob3JlZCByZWdleGVzLiBJZiB5b3UKICAgICAgICAgICAgICAgIC8vIHJlYWxseSBuZWVkIHRvIGtlZXAgeW91ciBhbmNob3JzLCBkb3VibGUgdGhlbSAoaS5lLiwgYF5eLi4uJCRgKQogICAgICAgICAgICAgICAgZGF0YVtwXSA9IHtwYXR0ZXJuOiBkZWFuY2hvcihzdWIuc291cmNlKSwgbmFtZXM6IHN1Yi54cmVnZXhwLmNhcHR1cmVOYW1lcyB8fCBbXX07CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIFBhc3NpbmcgdG8gWFJlZ0V4cCBkaWVzIG9uIG9jdGFscyBhbmQgZW5zdXJlcyB0aGUgb3V0ZXIgcGF0dGVybiBpcyBpbmRlcGVuZGVudGx5IHZhbGlkOwogICAgICAgIC8vIGhlbHBzIGtlZXAgdGhpcyBzaW1wbGUuIE5hbWVkIGNhcHR1cmVzIHdpbGwgYmUgcHV0IGJhY2sKICAgICAgICBwYXR0ZXJuID0gYXNYUmVnRXhwKHBhdHRlcm4pOwogICAgICAgIG91dGVyQ2FwTmFtZXMgPSBwYXR0ZXJuLnhyZWdleHAuY2FwdHVyZU5hbWVzIHx8IFtdOwogICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuLnNvdXJjZS5yZXBsYWNlKHBhcnRzLCBmdW5jdGlvbiAoJDAsICQxLCAkMiwgJDMsICQ0KSB7CiAgICAgICAgICAgIHZhciBzdWJOYW1lID0gJDEgfHwgJDIsIGNhcE5hbWUsIGludHJvOwogICAgICAgICAgICBpZiAoc3ViTmFtZSkgeyAvLyBOYW1lZCBzdWJwYXR0ZXJuCiAgICAgICAgICAgICAgICBpZiAoIWRhdGEuaGFzT3duUHJvcGVydHkoc3ViTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoInVuZGVmaW5lZCBwcm9wZXJ0eSAiICsgJDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCQxKSB7IC8vIE5hbWVkIHN1YnBhdHRlcm4gd2FzIHdyYXBwZWQgaW4gYSBjYXB0dXJpbmcgZ3JvdXAKICAgICAgICAgICAgICAgICAgICBjYXBOYW1lID0gb3V0ZXJDYXBOYW1lc1tudW1PdXRlckNhcHNdOwogICAgICAgICAgICAgICAgICAgIG91dGVyQ2Fwc01hcFsrK251bU91dGVyQ2Fwc10gPSArK251bUNhcHM7CiAgICAgICAgICAgICAgICAgICAgLy8gSWYgaXQncyBhIG5hbWVkIGdyb3VwLCBwcmVzZXJ2ZSB0aGUgbmFtZS4gT3RoZXJ3aXNlLCB1c2UgdGhlIHN1YnBhdHRlcm4gbmFtZQogICAgICAgICAgICAgICAgICAgIC8vIGFzIHRoZSBjYXB0dXJlIG5hbWUKICAgICAgICAgICAgICAgICAgICBpbnRybyA9ICIoPzwiICsgKGNhcE5hbWUgfHwgc3ViTmFtZSkgKyAiPiI7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGludHJvID0gIig/OiI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBudW1QcmlvckNhcHMgPSBudW1DYXBzOwogICAgICAgICAgICAgICAgcmV0dXJuIGludHJvICsgZGF0YVtzdWJOYW1lXS5wYXR0ZXJuLnJlcGxhY2Uoc3VicGFydHMsIGZ1bmN0aW9uIChtYXRjaCwgcGFyZW4sIGJhY2tyZWYpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW4pIHsgLy8gQ2FwdHVyaW5nIGdyb3VwCiAgICAgICAgICAgICAgICAgICAgICAgIGNhcE5hbWUgPSBkYXRhW3N1Yk5hbWVdLm5hbWVzW251bUNhcHMgLSBudW1QcmlvckNhcHNdOwogICAgICAgICAgICAgICAgICAgICAgICArK251bUNhcHM7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYXBOYW1lKSB7IC8vIElmIHRoZSBjdXJyZW50IGNhcHR1cmUgaGFzIGEgbmFtZSwgcHJlc2VydmUgdGhlIG5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAiKD88IiArIGNhcE5hbWUgKyAiPiI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJhY2tyZWYpIHsgLy8gQmFja3JlZmVyZW5jZQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlxcIiArICgrYmFja3JlZiArIG51bVByaW9yQ2Fwcyk7IC8vIFJld3JpdGUgdGhlIGJhY2tyZWZlcmVuY2UKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoOwogICAgICAgICAgICAgICAgfSkgKyAiKSI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCQzKSB7IC8vIENhcHR1cmluZyBncm91cAogICAgICAgICAgICAgICAgY2FwTmFtZSA9IG91dGVyQ2FwTmFtZXNbbnVtT3V0ZXJDYXBzXTsKICAgICAgICAgICAgICAgIG91dGVyQ2Fwc01hcFsrK251bU91dGVyQ2Fwc10gPSArK251bUNhcHM7CiAgICAgICAgICAgICAgICBpZiAoY2FwTmFtZSkgeyAvLyBJZiB0aGUgY3VycmVudCBjYXB0dXJlIGhhcyBhIG5hbWUsIHByZXNlcnZlIHRoZSBuYW1lCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICIoPzwiICsgY2FwTmFtZSArICI+IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmICgkNCkgeyAvLyBCYWNrcmVmZXJlbmNlCiAgICAgICAgICAgICAgICByZXR1cm4gIlxcIiArIG91dGVyQ2Fwc01hcFsrJDRdOyAvLyBSZXdyaXRlIHRoZSBiYWNrcmVmZXJlbmNlCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICQwOwogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gWFJlZ0V4cChwYXR0ZXJuLCBmbGFncyk7CiAgICB9OwoKfShYUmVnRXhwKSk7CgoKLyoqKioqIHByb3RvdHlwZXMuanMgKioqKiovCgovKiEKICogWFJlZ0V4cCBQcm90b3R5cGUgTWV0aG9kcyB2MS4wLjAKICogKGMpIDIwMTIgU3RldmVuIExldml0aGFuIDxodHRwOi8veHJlZ2V4cC5jb20vPgogKiBNSVQgTGljZW5zZQogKi8KCi8qKgogKiBBZGRzIGEgY29sbGVjdGlvbiBvZiBtZXRob2RzIHRvIGBYUmVnRXhwLnByb3RvdHlwZWAuIFJlZ0V4cCBvYmplY3RzIGNvcGllZCBieSBYUmVnRXhwIGFyZSBhbHNvCiAqIGF1Z21lbnRlZCB3aXRoIGFueSBgWFJlZ0V4cC5wcm90b3R5cGVgIG1ldGhvZHMuIEhlbmNlLCB0aGUgZm9sbG93aW5nIHdvcmsgZXF1aXZhbGVudGx5OgogKgogKiBYUmVnRXhwKCdbYS16XScsICdpZycpLnhleGVjKCdhYmMnKTsKICogWFJlZ0V4cCgvW2Etel0vaWcpLnhleGVjKCdhYmMnKTsKICogWFJlZ0V4cC5nbG9iYWxpemUoL1thLXpdL2kpLnhleGVjKCdhYmMnKTsKICovCihmdW5jdGlvbiAoWFJlZ0V4cCkgewogICAgInVzZSBzdHJpY3QiOwoKLyoqCiAqIENvcHkgcHJvcGVydGllcyBvZiBgYmAgdG8gYGFgLgogKiBAcHJpdmF0ZQogKiBAcGFyYW0ge09iamVjdH0gYSBPYmplY3QgdGhhdCB3aWxsIHJlY2VpdmUgbmV3IHByb3BlcnRpZXMuCiAqIEBwYXJhbSB7T2JqZWN0fSBiIE9iamVjdCB3aG9zZSBwcm9wZXJ0aWVzIHdpbGwgYmUgY29waWVkLgogKi8KICAgIGZ1bmN0aW9uIGV4dGVuZChhLCBiKSB7CiAgICAgICAgZm9yICh2YXIgcCBpbiBiKSB7CiAgICAgICAgICAgIGlmIChiLmhhc093blByb3BlcnR5KHApKSB7CiAgICAgICAgICAgICAgICBhW3BdID0gYltwXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvL3JldHVybiBhOwogICAgfQoKICAgIGV4dGVuZChYUmVnRXhwLnByb3RvdHlwZSwgewoKLyoqCiAqIEltcGxpY2l0bHkgY2FsbHMgdGhlIHJlZ2V4J3MgYHRlc3RgIG1ldGhvZCB3aXRoIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgcHJvdmlkZWQgYXJndW1lbnRzIGFycmF5LgogKiBAbWVtYmVyT2YgWFJlZ0V4cC5wcm90b3R5cGUKICogQHBhcmFtIHsqfSBjb250ZXh0IElnbm9yZWQuIEFjY2VwdGVkIG9ubHkgZm9yIGNvbmdydWl0eSB3aXRoIGBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHlgLgogKiBAcGFyYW0ge0FycmF5fSBhcmdzIEFycmF5IHdpdGggdGhlIHN0cmluZyB0byBzZWFyY2ggYXMgaXRzIGZpcnN0IHZhbHVlLgogKiBAcmV0dXJucyB7Qm9vbGVhbn0gV2hldGhlciB0aGUgcmVnZXggbWF0Y2hlZCB0aGUgcHJvdmlkZWQgdmFsdWUuCiAqIEBleGFtcGxlCiAqCiAqIFhSZWdFeHAoJ1thLXpdJykuYXBwbHkobnVsbCwgWydhYmMnXSk7IC8vIC0+IHRydWUKICovCiAgICAgICAgYXBwbHk6IGZ1bmN0aW9uIChjb250ZXh0LCBhcmdzKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnRlc3QoYXJnc1swXSk7CiAgICAgICAgfSwKCi8qKgogKiBJbXBsaWNpdGx5IGNhbGxzIHRoZSByZWdleCdzIGB0ZXN0YCBtZXRob2Qgd2l0aCB0aGUgcHJvdmlkZWQgc3RyaW5nLgogKiBAbWVtYmVyT2YgWFJlZ0V4cC5wcm90b3R5cGUKICogQHBhcmFtIHsqfSBjb250ZXh0IElnbm9yZWQuIEFjY2VwdGVkIG9ubHkgZm9yIGNvbmdydWl0eSB3aXRoIGBGdW5jdGlvbi5wcm90b3R5cGUuY2FsbGAuCiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIHNlYXJjaC4KICogQHJldHVybnMge0Jvb2xlYW59IFdoZXRoZXIgdGhlIHJlZ2V4IG1hdGNoZWQgdGhlIHByb3ZpZGVkIHZhbHVlLgogKiBAZXhhbXBsZQogKgogKiBYUmVnRXhwKCdbYS16XScpLmNhbGwobnVsbCwgJ2FiYycpOyAvLyAtPiB0cnVlCiAqLwogICAgICAgIGNhbGw6IGZ1bmN0aW9uIChjb250ZXh0LCBzdHIpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMudGVzdChzdHIpOwogICAgICAgIH0sCgovKioKICogSW1wbGljaXRseSBjYWxscyB7QGxpbmsgI1hSZWdFeHAuZm9yRWFjaH0uCiAqIEBtZW1iZXJPZiBYUmVnRXhwLnByb3RvdHlwZQogKiBAZXhhbXBsZQogKgogKiBYUmVnRXhwKCdcXGQnKS5mb3JFYWNoKCcxYTIzNDUnLCBmdW5jdGlvbiAobWF0Y2gsIGkpIHsKICogICBpZiAoaSAlIDIpIHRoaXMucHVzaCgrbWF0Y2hbMF0pOwogKiB9LCBbXSk7CiAqIC8vIC0+IFsyLCA0XQogKi8KICAgICAgICBmb3JFYWNoOiBmdW5jdGlvbiAoc3RyLCBjYWxsYmFjaywgY29udGV4dCkgewogICAgICAgICAgICByZXR1cm4gWFJlZ0V4cC5mb3JFYWNoKHN0ciwgdGhpcywgY2FsbGJhY2ssIGNvbnRleHQpOwogICAgICAgIH0sCgovKioKICogSW1wbGljaXRseSBjYWxscyB7QGxpbmsgI1hSZWdFeHAuZ2xvYmFsaXplfS4KICogQG1lbWJlck9mIFhSZWdFeHAucHJvdG90eXBlCiAqIEBleGFtcGxlCiAqCiAqIHZhciBnbG9iYWxDb3B5ID0gWFJlZ0V4cCgncmVnZXgnKS5nbG9iYWxpemUoKTsKICogZ2xvYmFsQ29weS5nbG9iYWw7IC8vIC0+IHRydWUKICovCiAgICAgICAgZ2xvYmFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBYUmVnRXhwLmdsb2JhbGl6ZSh0aGlzKTsKICAgICAgICB9LAoKLyoqCiAqIEltcGxpY2l0bHkgY2FsbHMge0BsaW5rICNYUmVnRXhwLmV4ZWN9LgogKiBAbWVtYmVyT2YgWFJlZ0V4cC5wcm90b3R5cGUKICogQGV4YW1wbGUKICoKICogdmFyIG1hdGNoID0gWFJlZ0V4cCgnVVxcKyg/PGhleD5bMC05QS1GXXs0fSknKS54ZXhlYygnVSsyNjIwJyk7CiAqIG1hdGNoLmhleDsgLy8gLT4gJzI2MjAnCiAqLwogICAgICAgIHhleGVjOiBmdW5jdGlvbiAoc3RyLCBwb3MsIHN0aWNreSkgewogICAgICAgICAgICByZXR1cm4gWFJlZ0V4cC5leGVjKHN0ciwgdGhpcywgcG9zLCBzdGlja3kpOwogICAgICAgIH0sCgovKioKICogSW1wbGljaXRseSBjYWxscyB7QGxpbmsgI1hSZWdFeHAudGVzdH0uCiAqIEBtZW1iZXJPZiBYUmVnRXhwLnByb3RvdHlwZQogKiBAZXhhbXBsZQogKgogKiBYUmVnRXhwKCdjJykueHRlc3QoJ2FiYycpOyAvLyAtPiB0cnVlCiAqLwogICAgICAgIHh0ZXN0OiBmdW5jdGlvbiAoc3RyLCBwb3MsIHN0aWNreSkgewogICAgICAgICAgICByZXR1cm4gWFJlZ0V4cC50ZXN0KHN0ciwgdGhpcywgcG9zLCBzdGlja3kpOwogICAgICAgIH0KCiAgICB9KTsKCn0oWFJlZ0V4cCkpOwoKLy8gVGlueUNvbG9yIHYwLjkuMTUKLy8gaHR0cHM6Ly9naXRodWIuY29tL2Jncmlucy9UaW55Q29sb3IKLy8gMjAxMy0wNy0wNCwgQnJpYW4gR3JpbnN0ZWFkLCBNSVQgTGljZW5zZQooZnVuY3Rpb24ocm9vdCl7ZnVuY3Rpb24gdGlueWNvbG9yKGNvbG9yLG9wdHMpe2lmKGNvbG9yPWNvbG9yP2NvbG9yOiIiLG9wdHM9b3B0c3x8e30sIm9iamVjdCI9PXR5cGVvZiBjb2xvciYmY29sb3IuaGFzT3duUHJvcGVydHkoIl90Y19pZCIpKXJldHVybiBjb2xvcjt2YXIgcmdiPWlucHV0VG9SR0IoY29sb3IpLHI9cmdiLnIsZz1yZ2IuZyxiPXJnYi5iLGE9cmdiLmEscm91bmRBPW1hdGhSb3VuZCgxMDAqYSkvMTAwLGZvcm1hdD1vcHRzLmZvcm1hdHx8cmdiLmZvcm1hdDtyZXR1cm4gMT5yJiYocj1tYXRoUm91bmQocikpLDE+ZyYmKGc9bWF0aFJvdW5kKGcpKSwxPmImJihiPW1hdGhSb3VuZChiKSkse29rOnJnYi5vayxmb3JtYXQ6Zm9ybWF0LF90Y19pZDp0aW55Q291bnRlcisrLGFscGhhOmEsdG9Ic3Y6ZnVuY3Rpb24oKXt2YXIgaHN2PXJnYlRvSHN2KHIsZyxiKTtyZXR1cm57aDozNjAqaHN2Lmgsczpoc3Yucyx2Omhzdi52LGE6YX19LHRvSHN2U3RyaW5nOmZ1bmN0aW9uKCl7dmFyIGhzdj1yZ2JUb0hzdihyLGcsYiksaD1tYXRoUm91bmQoMzYwKmhzdi5oKSxzPW1hdGhSb3VuZCgxMDAqaHN2LnMpLHY9bWF0aFJvdW5kKDEwMCpoc3Yudik7cmV0dXJuIDE9PWE/ImhzdigiK2grIiwgIitzKyIlLCAiK3YrIiUpIjoiaHN2YSgiK2grIiwgIitzKyIlLCAiK3YrIiUsICIrcm91bmRBKyIpIn0sdG9Ic2w6ZnVuY3Rpb24oKXt2YXIgaHNsPXJnYlRvSHNsKHIsZyxiKTtyZXR1cm57aDozNjAqaHNsLmgsczpoc2wucyxsOmhzbC5sLGE6YX19LHRvSHNsU3RyaW5nOmZ1bmN0aW9uKCl7dmFyIGhzbD1yZ2JUb0hzbChyLGcsYiksaD1tYXRoUm91bmQoMzYwKmhzbC5oKSxzPW1hdGhSb3VuZCgxMDAqaHNsLnMpLGw9bWF0aFJvdW5kKDEwMCpoc2wubCk7cmV0dXJuIDE9PWE/ImhzbCgiK2grIiwgIitzKyIlLCAiK2wrIiUpIjoiaHNsYSgiK2grIiwgIitzKyIlLCAiK2wrIiUsICIrcm91bmRBKyIpIn0sdG9IZXg6ZnVuY3Rpb24oYWxsb3czQ2hhcil7cmV0dXJuIHJnYlRvSGV4KHIsZyxiLGFsbG93M0NoYXIpfSx0b0hleFN0cmluZzpmdW5jdGlvbihhbGxvdzNDaGFyKXtyZXR1cm4iIyIrcmdiVG9IZXgocixnLGIsYWxsb3czQ2hhcil9LHRvUmdiOmZ1bmN0aW9uKCl7cmV0dXJue3I6bWF0aFJvdW5kKHIpLGc6bWF0aFJvdW5kKGcpLGI6bWF0aFJvdW5kKGIpLGE6YX19LHRvUmdiU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIDE9PWE/InJnYigiK21hdGhSb3VuZChyKSsiLCAiK21hdGhSb3VuZChnKSsiLCAiK21hdGhSb3VuZChiKSsiKSI6InJnYmEoIittYXRoUm91bmQocikrIiwgIittYXRoUm91bmQoZykrIiwgIittYXRoUm91bmQoYikrIiwgIityb3VuZEErIikifSx0b1BlcmNlbnRhZ2VSZ2I6ZnVuY3Rpb24oKXtyZXR1cm57cjptYXRoUm91bmQoMTAwKmJvdW5kMDEociwyNTUpKSsiJSIsZzptYXRoUm91bmQoMTAwKmJvdW5kMDEoZywyNTUpKSsiJSIsYjptYXRoUm91bmQoMTAwKmJvdW5kMDEoYiwyNTUpKSsiJSIsYTphfX0sdG9QZXJjZW50YWdlUmdiU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIDE9PWE/InJnYigiK21hdGhSb3VuZCgxMDAqYm91bmQwMShyLDI1NSkpKyIlLCAiK21hdGhSb3VuZCgxMDAqYm91bmQwMShnLDI1NSkpKyIlLCAiK21hdGhSb3VuZCgxMDAqYm91bmQwMShiLDI1NSkpKyIlKSI6InJnYmEoIittYXRoUm91bmQoMTAwKmJvdW5kMDEociwyNTUpKSsiJSwgIittYXRoUm91bmQoMTAwKmJvdW5kMDEoZywyNTUpKSsiJSwgIittYXRoUm91bmQoMTAwKmJvdW5kMDEoYiwyNTUpKSsiJSwgIityb3VuZEErIikifSx0b05hbWU6ZnVuY3Rpb24oKXtyZXR1cm4gMD09PWE/InRyYW5zcGFyZW50IjpoZXhOYW1lc1tyZ2JUb0hleChyLGcsYiwhMCldfHwhMX0sdG9GaWx0ZXI6ZnVuY3Rpb24oc2Vjb25kQ29sb3Ipe3ZhciBoZXg9cmdiVG9IZXgocixnLGIpLHNlY29uZEhleD1oZXgsYWxwaGFIZXg9TWF0aC5yb3VuZCgyNTUqcGFyc2VGbG9hdChhKSkudG9TdHJpbmcoMTYpLHNlY29uZEFscGhhSGV4PWFscGhhSGV4LGdyYWRpZW50VHlwZT1vcHRzJiZvcHRzLmdyYWRpZW50VHlwZT8iR3JhZGllbnRUeXBlID0gMSwgIjoiIjtpZihzZWNvbmRDb2xvcil7dmFyIHM9dGlueWNvbG9yKHNlY29uZENvbG9yKTtzZWNvbmRIZXg9cy50b0hleCgpLHNlY29uZEFscGhhSGV4PU1hdGgucm91bmQoMjU1KnBhcnNlRmxvYXQocy5hbHBoYSkpLnRvU3RyaW5nKDE2KX1yZXR1cm4icHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0LmdyYWRpZW50KCIrZ3JhZGllbnRUeXBlKyJzdGFydENvbG9yc3RyPSMiK3BhZDIoYWxwaGFIZXgpK2hleCsiLGVuZENvbG9yc3RyPSMiK3BhZDIoc2Vjb25kQWxwaGFIZXgpK3NlY29uZEhleCsiKSJ9LHRvU3RyaW5nOmZ1bmN0aW9uKGZvcm1hdCl7dmFyIGZvcm1hdFNldD0hIWZvcm1hdDtmb3JtYXQ9Zm9ybWF0fHx0aGlzLmZvcm1hdDt2YXIgZm9ybWF0dGVkU3RyaW5nPSExLGhhc0FscGhhQW5kRm9ybWF0Tm90U2V0PSFmb3JtYXRTZXQmJjE+YSYmYT4wLGZvcm1hdFdpdGhBbHBoYT1oYXNBbHBoYUFuZEZvcm1hdE5vdFNldCYmKCJoZXgiPT09Zm9ybWF0fHwiaGV4NiI9PT1mb3JtYXR8fCJoZXgzIj09PWZvcm1hdHx8Im5hbWUiPT09Zm9ybWF0KTtyZXR1cm4icmdiIj09PWZvcm1hdCYmKGZvcm1hdHRlZFN0cmluZz10aGlzLnRvUmdiU3RyaW5nKCkpLCJwcmdiIj09PWZvcm1hdCYmKGZvcm1hdHRlZFN0cmluZz10aGlzLnRvUGVyY2VudGFnZVJnYlN0cmluZygpKSwoImhleCI9PT1mb3JtYXR8fCJoZXg2Ij09PWZvcm1hdCkmJihmb3JtYXR0ZWRTdHJpbmc9dGhpcy50b0hleFN0cmluZygpKSwiaGV4MyI9PT1mb3JtYXQmJihmb3JtYXR0ZWRTdHJpbmc9dGhpcy50b0hleFN0cmluZyghMCkpLCJuYW1lIj09PWZvcm1hdCYmKGZvcm1hdHRlZFN0cmluZz10aGlzLnRvTmFtZSgpKSwiaHNsIj09PWZvcm1hdCYmKGZvcm1hdHRlZFN0cmluZz10aGlzLnRvSHNsU3RyaW5nKCkpLCJoc3YiPT09Zm9ybWF0JiYoZm9ybWF0dGVkU3RyaW5nPXRoaXMudG9Ic3ZTdHJpbmcoKSksZm9ybWF0V2l0aEFscGhhP3RoaXMudG9SZ2JTdHJpbmcoKTpmb3JtYXR0ZWRTdHJpbmd8fHRoaXMudG9IZXhTdHJpbmcoKX19fWZ1bmN0aW9uIGlucHV0VG9SR0IoY29sb3Ipe3ZhciByZ2I9e3I6MCxnOjAsYjowfSxhPTEsb2s9ITEsZm9ybWF0PSExO3JldHVybiJzdHJpbmciPT10eXBlb2YgY29sb3ImJihjb2xvcj1zdHJpbmdJbnB1dFRvT2JqZWN0KGNvbG9yKSksIm9iamVjdCI9PXR5cGVvZiBjb2xvciYmKGNvbG9yLmhhc093blByb3BlcnR5KCJyIikmJmNvbG9yLmhhc093blByb3BlcnR5KCJnIikmJmNvbG9yLmhhc093blByb3BlcnR5KCJiIik/KHJnYj1yZ2JUb1JnYihjb2xvci5yLGNvbG9yLmcsY29sb3IuYiksb2s9ITAsZm9ybWF0PSIlIj09PShjb2xvci5yKyIiKS5zdWJzdHIoLTEpPyJwcmdiIjoicmdiIik6Y29sb3IuaGFzT3duUHJvcGVydHkoImgiKSYmY29sb3IuaGFzT3duUHJvcGVydHkoInMiKSYmY29sb3IuaGFzT3duUHJvcGVydHkoInYiKT8oY29sb3Iucz1jb252ZXJ0VG9QZXJjZW50YWdlKGNvbG9yLnMpLGNvbG9yLnY9Y29udmVydFRvUGVyY2VudGFnZShjb2xvci52KSxyZ2I9aHN2VG9SZ2IoY29sb3IuaCxjb2xvci5zLGNvbG9yLnYpLG9rPSEwLGZvcm1hdD0iaHN2Iik6Y29sb3IuaGFzT3duUHJvcGVydHkoImgiKSYmY29sb3IuaGFzT3duUHJvcGVydHkoInMiKSYmY29sb3IuaGFzT3duUHJvcGVydHkoImwiKSYmKGNvbG9yLnM9Y29udmVydFRvUGVyY2VudGFnZShjb2xvci5zKSxjb2xvci5sPWNvbnZlcnRUb1BlcmNlbnRhZ2UoY29sb3IubCkscmdiPWhzbFRvUmdiKGNvbG9yLmgsY29sb3Iucyxjb2xvci5sKSxvaz0hMCxmb3JtYXQ9ImhzbCIpLGNvbG9yLmhhc093blByb3BlcnR5KCJhIikmJihhPWNvbG9yLmEpKSxhPXBhcnNlRmxvYXQoYSksKGlzTmFOKGEpfHwwPmF8fGE+MSkmJihhPTEpLHtvazpvayxmb3JtYXQ6Y29sb3IuZm9ybWF0fHxmb3JtYXQscjptYXRoTWluKDI1NSxtYXRoTWF4KHJnYi5yLDApKSxnOm1hdGhNaW4oMjU1LG1hdGhNYXgocmdiLmcsMCkpLGI6bWF0aE1pbigyNTUsbWF0aE1heChyZ2IuYiwwKSksYTphfX1mdW5jdGlvbiByZ2JUb1JnYihyLGcsYil7cmV0dXJue3I6MjU1KmJvdW5kMDEociwyNTUpLGc6MjU1KmJvdW5kMDEoZywyNTUpLGI6MjU1KmJvdW5kMDEoYiwyNTUpfX1mdW5jdGlvbiByZ2JUb0hzbChyLGcsYil7cj1ib3VuZDAxKHIsMjU1KSxnPWJvdW5kMDEoZywyNTUpLGI9Ym91bmQwMShiLDI1NSk7dmFyIGgscyxtYXg9bWF0aE1heChyLGcsYiksbWluPW1hdGhNaW4ocixnLGIpLGw9KG1heCttaW4pLzI7aWYobWF4PT1taW4paD1zPTA7ZWxzZXt2YXIgZD1tYXgtbWluO3N3aXRjaChzPWw+LjU/ZC8oMi1tYXgtbWluKTpkLyhtYXgrbWluKSxtYXgpe2Nhc2UgcjpoPShnLWIpL2QrKGI+Zz82OjApO2JyZWFrO2Nhc2UgZzpoPShiLXIpL2QrMjticmVhaztjYXNlIGI6aD0oci1nKS9kKzR9aC89Nn1yZXR1cm57aDpoLHM6cyxsOmx9fWZ1bmN0aW9uIGhzbFRvUmdiKGgscyxsKXtmdW5jdGlvbiBodWUycmdiKHAscSx0KXtyZXR1cm4gMD50JiYodCs9MSksdD4xJiYodC09MSksMS82PnQ/cCs2KihxLXApKnQ6LjU+dD9xOjIvMz50P3ArNioocS1wKSooMi8zLXQpOnB9dmFyIHIsZyxiO2lmKGg9Ym91bmQwMShoLDM2MCkscz1ib3VuZDAxKHMsMTAwKSxsPWJvdW5kMDEobCwxMDApLDA9PT1zKXI9Zz1iPWw7ZWxzZXt2YXIgcT0uNT5sP2wqKDErcyk6bCtzLWwqcyxwPTIqbC1xO3I9aHVlMnJnYihwLHEsaCsxLzMpLGc9aHVlMnJnYihwLHEsaCksYj1odWUycmdiKHAscSxoLTEvMyl9cmV0dXJue3I6MjU1KnIsZzoyNTUqZyxiOjI1NSpifX1mdW5jdGlvbiByZ2JUb0hzdihyLGcsYil7cj1ib3VuZDAxKHIsMjU1KSxnPWJvdW5kMDEoZywyNTUpLGI9Ym91bmQwMShiLDI1NSk7dmFyIGgscyxtYXg9bWF0aE1heChyLGcsYiksbWluPW1hdGhNaW4ocixnLGIpLHY9bWF4LGQ9bWF4LW1pbjtpZihzPTA9PT1tYXg/MDpkL21heCxtYXg9PW1pbiloPTA7ZWxzZXtzd2l0Y2gobWF4KXtjYXNlIHI6aD0oZy1iKS9kKyhiPmc/NjowKTticmVhaztjYXNlIGc6aD0oYi1yKS9kKzI7YnJlYWs7Y2FzZSBiOmg9KHItZykvZCs0fWgvPTZ9cmV0dXJue2g6aCxzOnMsdjp2fX1mdW5jdGlvbiBoc3ZUb1JnYihoLHMsdil7aD02KmJvdW5kMDEoaCwzNjApLHM9Ym91bmQwMShzLDEwMCksdj1ib3VuZDAxKHYsMTAwKTt2YXIgaT1tYXRoLmZsb29yKGgpLGY9aC1pLHA9diooMS1zKSxxPXYqKDEtZipzKSx0PXYqKDEtKDEtZikqcyksbW9kPWklNixyPVt2LHEscCxwLHQsdl1bbW9kXSxnPVt0LHYsdixxLHAscF1bbW9kXSxiPVtwLHAsdCx2LHYscV1bbW9kXTtyZXR1cm57cjoyNTUqcixnOjI1NSpnLGI6MjU1KmJ9fWZ1bmN0aW9uIHJnYlRvSGV4KHIsZyxiLGFsbG93M0NoYXIpe3ZhciBoZXg9W3BhZDIobWF0aFJvdW5kKHIpLnRvU3RyaW5nKDE2KSkscGFkMihtYXRoUm91bmQoZykudG9TdHJpbmcoMTYpKSxwYWQyKG1hdGhSb3VuZChiKS50b1N0cmluZygxNikpXTtyZXR1cm4gYWxsb3czQ2hhciYmaGV4WzBdLmNoYXJBdCgwKT09aGV4WzBdLmNoYXJBdCgxKSYmaGV4WzFdLmNoYXJBdCgwKT09aGV4WzFdLmNoYXJBdCgxKSYmaGV4WzJdLmNoYXJBdCgwKT09aGV4WzJdLmNoYXJBdCgxKT9oZXhbMF0uY2hhckF0KDApK2hleFsxXS5jaGFyQXQoMCkraGV4WzJdLmNoYXJBdCgwKTpoZXguam9pbigiIil9ZnVuY3Rpb24gZmxpcChvKXt2YXIgZmxpcHBlZD17fTtmb3IodmFyIGkgaW4gbylvLmhhc093blByb3BlcnR5KGkpJiYoZmxpcHBlZFtvW2ldXT1pKTtyZXR1cm4gZmxpcHBlZH1mdW5jdGlvbiBib3VuZDAxKG4sbWF4KXtpc09uZVBvaW50WmVybyhuKSYmKG49IjEwMCUiKTt2YXIgcHJvY2Vzc1BlcmNlbnQ9aXNQZXJjZW50YWdlKG4pO3JldHVybiBuPW1hdGhNaW4obWF4LG1hdGhNYXgoMCxwYXJzZUZsb2F0KG4pKSkscHJvY2Vzc1BlcmNlbnQmJihuPXBhcnNlSW50KG4qbWF4LDEwKS8xMDApLDFlLTY+bWF0aC5hYnMobi1tYXgpPzE6biVtYXgvcGFyc2VGbG9hdChtYXgpfWZ1bmN0aW9uIGNsYW1wMDEodmFsKXtyZXR1cm4gbWF0aE1pbigxLG1hdGhNYXgoMCx2YWwpKX1mdW5jdGlvbiBwYXJzZUhleCh2YWwpe3JldHVybiBwYXJzZUludCh2YWwsMTYpfWZ1bmN0aW9uIGlzT25lUG9pbnRaZXJvKG4pe3JldHVybiJzdHJpbmciPT10eXBlb2YgbiYmLTEhPW4uaW5kZXhPZigiLiIpJiYxPT09cGFyc2VGbG9hdChuKX1mdW5jdGlvbiBpc1BlcmNlbnRhZ2Uobil7cmV0dXJuInN0cmluZyI9PXR5cGVvZiBuJiYtMSE9bi5pbmRleE9mKCIlIil9ZnVuY3Rpb24gcGFkMihjKXtyZXR1cm4gMT09Yy5sZW5ndGg/IjAiK2M6IiIrY31mdW5jdGlvbiBjb252ZXJ0VG9QZXJjZW50YWdlKG4pe3JldHVybiAxPj1uJiYobj0xMDAqbisiJSIpLG59ZnVuY3Rpb24gc3RyaW5nSW5wdXRUb09iamVjdChjb2xvcil7Y29sb3I9Y29sb3IucmVwbGFjZSh0cmltTGVmdCwiIikucmVwbGFjZSh0cmltUmlnaHQsIiIpLnRvTG93ZXJDYXNlKCk7dmFyIG5hbWVkPSExO2lmKG5hbWVzW2NvbG9yXSljb2xvcj1uYW1lc1tjb2xvcl0sbmFtZWQ9ITA7ZWxzZSBpZigidHJhbnNwYXJlbnQiPT1jb2xvcilyZXR1cm57cjowLGc6MCxiOjAsYTowLGZvcm1hdDoibmFtZSJ9O3ZhciBtYXRjaDtyZXR1cm4obWF0Y2g9bWF0Y2hlcnMucmdiLmV4ZWMoY29sb3IpKT97cjptYXRjaFsxXSxnOm1hdGNoWzJdLGI6bWF0Y2hbM119OihtYXRjaD1tYXRjaGVycy5yZ2JhLmV4ZWMoY29sb3IpKT97cjptYXRjaFsxXSxnOm1hdGNoWzJdLGI6bWF0Y2hbM10sYTptYXRjaFs0XX06KG1hdGNoPW1hdGNoZXJzLmhzbC5leGVjKGNvbG9yKSk/e2g6bWF0Y2hbMV0sczptYXRjaFsyXSxsOm1hdGNoWzNdfToobWF0Y2g9bWF0Y2hlcnMuaHNsYS5leGVjKGNvbG9yKSk/e2g6bWF0Y2hbMV0sczptYXRjaFsyXSxsOm1hdGNoWzNdLGE6bWF0Y2hbNF19OihtYXRjaD1tYXRjaGVycy5oc3YuZXhlYyhjb2xvcikpP3toOm1hdGNoWzFdLHM6bWF0Y2hbMl0sdjptYXRjaFszXX06KG1hdGNoPW1hdGNoZXJzLmhleDYuZXhlYyhjb2xvcikpP3tyOnBhcnNlSGV4KG1hdGNoWzFdKSxnOnBhcnNlSGV4KG1hdGNoWzJdKSxiOnBhcnNlSGV4KG1hdGNoWzNdKSxmb3JtYXQ6bmFtZWQ/Im5hbWUiOiJoZXgifToobWF0Y2g9bWF0Y2hlcnMuaGV4My5leGVjKGNvbG9yKSk/e3I6cGFyc2VIZXgobWF0Y2hbMV0rIiIrbWF0Y2hbMV0pLGc6cGFyc2VIZXgobWF0Y2hbMl0rIiIrbWF0Y2hbMl0pLGI6cGFyc2VIZXgobWF0Y2hbM10rIiIrbWF0Y2hbM10pLGZvcm1hdDpuYW1lZD8ibmFtZSI6ImhleCJ9OiExfXZhciB0cmltTGVmdD0vXltccywjXSsvLHRyaW1SaWdodD0vXHMrJC8sdGlueUNvdW50ZXI9MCxtYXRoPU1hdGgsbWF0aFJvdW5kPW1hdGgucm91bmQsbWF0aE1pbj1tYXRoLm1pbixtYXRoTWF4PW1hdGgubWF4LG1hdGhSYW5kb209bWF0aC5yYW5kb207dGlueWNvbG9yLmZyb21SYXRpbz1mdW5jdGlvbihjb2xvcixvcHRzKXtpZigib2JqZWN0Ij09dHlwZW9mIGNvbG9yKXt2YXIgbmV3Q29sb3I9e307Zm9yKHZhciBpIGluIGNvbG9yKWNvbG9yLmhhc093blByb3BlcnR5KGkpJiYobmV3Q29sb3JbaV09ImEiPT09aT9jb2xvcltpXTpjb252ZXJ0VG9QZXJjZW50YWdlKGNvbG9yW2ldKSk7Y29sb3I9bmV3Q29sb3J9cmV0dXJuIHRpbnljb2xvcihjb2xvcixvcHRzKX0sdGlueWNvbG9yLmVxdWFscz1mdW5jdGlvbihjb2xvcjEsY29sb3IyKXtyZXR1cm4gY29sb3IxJiZjb2xvcjI/dGlueWNvbG9yKGNvbG9yMSkudG9SZ2JTdHJpbmcoKT09dGlueWNvbG9yKGNvbG9yMikudG9SZ2JTdHJpbmcoKTohMX0sdGlueWNvbG9yLnJhbmRvbT1mdW5jdGlvbigpe3JldHVybiB0aW55Y29sb3IuZnJvbVJhdGlvKHtyOm1hdGhSYW5kb20oKSxnOm1hdGhSYW5kb20oKSxiOm1hdGhSYW5kb20oKX0pfSx0aW55Y29sb3IuZGVzYXR1cmF0ZT1mdW5jdGlvbihjb2xvcixhbW91bnQpe2Ftb3VudD0wPT09YW1vdW50PzA6YW1vdW50fHwxMDt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKTtyZXR1cm4gaHNsLnMtPWFtb3VudC8xMDAsaHNsLnM9Y2xhbXAwMShoc2wucyksdGlueWNvbG9yKGhzbCl9LHRpbnljb2xvci5zYXR1cmF0ZT1mdW5jdGlvbihjb2xvcixhbW91bnQpe2Ftb3VudD0wPT09YW1vdW50PzA6YW1vdW50fHwxMDt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKTtyZXR1cm4gaHNsLnMrPWFtb3VudC8xMDAsaHNsLnM9Y2xhbXAwMShoc2wucyksdGlueWNvbG9yKGhzbCl9LHRpbnljb2xvci5ncmV5c2NhbGU9ZnVuY3Rpb24oY29sb3Ipe3JldHVybiB0aW55Y29sb3IuZGVzYXR1cmF0ZShjb2xvciwxMDApfSx0aW55Y29sb3IubGlnaHRlbj1mdW5jdGlvbihjb2xvcixhbW91bnQpe2Ftb3VudD0wPT09YW1vdW50PzA6YW1vdW50fHwxMDt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKTtyZXR1cm4gaHNsLmwrPWFtb3VudC8xMDAsaHNsLmw9Y2xhbXAwMShoc2wubCksdGlueWNvbG9yKGhzbCl9LHRpbnljb2xvci5kYXJrZW49ZnVuY3Rpb24oY29sb3IsYW1vdW50KXthbW91bnQ9MD09PWFtb3VudD8wOmFtb3VudHx8MTA7dmFyIGhzbD10aW55Y29sb3IoY29sb3IpLnRvSHNsKCk7cmV0dXJuIGhzbC5sLT1hbW91bnQvMTAwLGhzbC5sPWNsYW1wMDEoaHNsLmwpLHRpbnljb2xvcihoc2wpfSx0aW55Y29sb3IuY29tcGxlbWVudD1mdW5jdGlvbihjb2xvcil7dmFyIGhzbD10aW55Y29sb3IoY29sb3IpLnRvSHNsKCk7cmV0dXJuIGhzbC5oPShoc2wuaCsxODApJTM2MCx0aW55Y29sb3IoaHNsKX0sdGlueWNvbG9yLnRyaWFkPWZ1bmN0aW9uKGNvbG9yKXt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKSxoPWhzbC5oO3JldHVyblt0aW55Y29sb3IoY29sb3IpLHRpbnljb2xvcih7aDooaCsxMjApJTM2MCxzOmhzbC5zLGw6aHNsLmx9KSx0aW55Y29sb3Ioe2g6KGgrMjQwKSUzNjAsczpoc2wucyxsOmhzbC5sfSldfSx0aW55Y29sb3IudGV0cmFkPWZ1bmN0aW9uKGNvbG9yKXt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKSxoPWhzbC5oO3JldHVyblt0aW55Y29sb3IoY29sb3IpLHRpbnljb2xvcih7aDooaCs5MCklMzYwLHM6aHNsLnMsbDpoc2wubH0pLHRpbnljb2xvcih7aDooaCsxODApJTM2MCxzOmhzbC5zLGw6aHNsLmx9KSx0aW55Y29sb3Ioe2g6KGgrMjcwKSUzNjAsczpoc2wucyxsOmhzbC5sfSldfSx0aW55Y29sb3Iuc3BsaXRjb21wbGVtZW50PWZ1bmN0aW9uKGNvbG9yKXt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKSxoPWhzbC5oO3JldHVyblt0aW55Y29sb3IoY29sb3IpLHRpbnljb2xvcih7aDooaCs3MiklMzYwLHM6aHNsLnMsbDpoc2wubH0pLHRpbnljb2xvcih7aDooaCsyMTYpJTM2MCxzOmhzbC5zLGw6aHNsLmx9KV19LHRpbnljb2xvci5hbmFsb2dvdXM9ZnVuY3Rpb24oY29sb3IscmVzdWx0cyxzbGljZXMpe3Jlc3VsdHM9cmVzdWx0c3x8NixzbGljZXM9c2xpY2VzfHwzMDt2YXIgaHNsPXRpbnljb2xvcihjb2xvcikudG9Ic2woKSxwYXJ0PTM2MC9zbGljZXMscmV0PVt0aW55Y29sb3IoY29sb3IpXTtmb3IoaHNsLmg9KGhzbC5oLShwYXJ0KnJlc3VsdHM+PjEpKzcyMCklMzYwOy0tcmVzdWx0czspaHNsLmg9KGhzbC5oK3BhcnQpJTM2MCxyZXQucHVzaCh0aW55Y29sb3IoaHNsKSk7cmV0dXJuIHJldH0sdGlueWNvbG9yLm1vbm9jaHJvbWF0aWM9ZnVuY3Rpb24oY29sb3IscmVzdWx0cyl7cmVzdWx0cz1yZXN1bHRzfHw2O2Zvcih2YXIgaHN2PXRpbnljb2xvcihjb2xvcikudG9Ic3YoKSxoPWhzdi5oLHM9aHN2LnMsdj1oc3YudixyZXQ9W10sbW9kaWZpY2F0aW9uPTEvcmVzdWx0cztyZXN1bHRzLS07KXJldC5wdXNoKHRpbnljb2xvcih7aDpoLHM6cyx2OnZ9KSksdj0odittb2RpZmljYXRpb24pJTE7cmV0dXJuIHJldH0sdGlueWNvbG9yLnJlYWRhYmlsaXR5PWZ1bmN0aW9uKGNvbG9yMSxjb2xvcjIpe3ZhciBhPXRpbnljb2xvcihjb2xvcjEpLnRvUmdiKCksYj10aW55Y29sb3IoY29sb3IyKS50b1JnYigpLGJyaWdodG5lc3NBPSgyOTkqYS5yKzU4NyphLmcrMTE0KmEuYikvMWUzLGJyaWdodG5lc3NCPSgyOTkqYi5yKzU4NypiLmcrMTE0KmIuYikvMWUzLGNvbG9yRGlmZj1NYXRoLm1heChhLnIsYi5yKS1NYXRoLm1pbihhLnIsYi5yKStNYXRoLm1heChhLmcsYi5nKS1NYXRoLm1pbihhLmcsYi5nKStNYXRoLm1heChhLmIsYi5iKS1NYXRoLm1pbihhLmIsYi5iKTtyZXR1cm57YnJpZ2h0bmVzczpNYXRoLmFicyhicmlnaHRuZXNzQS1icmlnaHRuZXNzQiksY29sb3I6Y29sb3JEaWZmfX0sdGlueWNvbG9yLnJlYWRhYmxlPWZ1bmN0aW9uKGNvbG9yMSxjb2xvcjIpe3ZhciByZWFkYWJpbGl0eT10aW55Y29sb3IucmVhZGFiaWxpdHkoY29sb3IxLGNvbG9yMik7cmV0dXJuIHJlYWRhYmlsaXR5LmJyaWdodG5lc3M+MTI1JiZyZWFkYWJpbGl0eS5jb2xvcj41MDB9LHRpbnljb2xvci5tb3N0UmVhZGFibGU9ZnVuY3Rpb24oYmFzZUNvbG9yLGNvbG9yTGlzdCl7Zm9yKHZhciBiZXN0Q29sb3I9bnVsbCxiZXN0U2NvcmU9MCxiZXN0SXNSZWFkYWJsZT0hMSxpPTA7Y29sb3JMaXN0Lmxlbmd0aD5pO2krKyl7dmFyIHJlYWRhYmlsaXR5PXRpbnljb2xvci5yZWFkYWJpbGl0eShiYXNlQ29sb3IsY29sb3JMaXN0W2ldKSxyZWFkYWJsZT1yZWFkYWJpbGl0eS5icmlnaHRuZXNzPjEyNSYmcmVhZGFiaWxpdHkuY29sb3I+NTAwLHNjb3JlPTMqKHJlYWRhYmlsaXR5LmJyaWdodG5lc3MvMTI1KStyZWFkYWJpbGl0eS5jb2xvci81MDA7KHJlYWRhYmxlJiYhYmVzdElzUmVhZGFibGV8fHJlYWRhYmxlJiZiZXN0SXNSZWFkYWJsZSYmc2NvcmU+YmVzdFNjb3JlfHwhcmVhZGFibGUmJiFiZXN0SXNSZWFkYWJsZSYmc2NvcmU+YmVzdFNjb3JlKSYmKGJlc3RJc1JlYWRhYmxlPXJlYWRhYmxlLGJlc3RTY29yZT1zY29yZSxiZXN0Q29sb3I9dGlueWNvbG9yKGNvbG9yTGlzdFtpXSkpfXJldHVybiBiZXN0Q29sb3J9O3ZhciBuYW1lcz10aW55Y29sb3IubmFtZXM9e2FsaWNlYmx1ZToiZjBmOGZmIixhbnRpcXVld2hpdGU6ImZhZWJkNyIsYXF1YToiMGZmIixhcXVhbWFyaW5lOiI3ZmZmZDQiLGF6dXJlOiJmMGZmZmYiLGJlaWdlOiJmNWY1ZGMiLGJpc3F1ZToiZmZlNGM0IixibGFjazoiMDAwIixibGFuY2hlZGFsbW9uZDoiZmZlYmNkIixibHVlOiIwMGYiLGJsdWV2aW9sZXQ6IjhhMmJlMiIsYnJvd246ImE1MmEyYSIsYnVybHl3b29kOiJkZWI4ODciLGJ1cm50c2llbm5hOiJlYTdlNWQiLGNhZGV0Ymx1ZToiNWY5ZWEwIixjaGFydHJldXNlOiI3ZmZmMDAiLGNob2NvbGF0ZToiZDI2OTFlIixjb3JhbDoiZmY3ZjUwIixjb3JuZmxvd2VyYmx1ZToiNjQ5NWVkIixjb3Juc2lsazoiZmZmOGRjIixjcmltc29uOiJkYzE0M2MiLGN5YW46IjBmZiIsZGFya2JsdWU6IjAwMDA4YiIsZGFya2N5YW46IjAwOGI4YiIsZGFya2dvbGRlbnJvZDoiYjg4NjBiIixkYXJrZ3JheToiYTlhOWE5IixkYXJrZ3JlZW46IjAwNjQwMCIsZGFya2dyZXk6ImE5YTlhOSIsZGFya2toYWtpOiJiZGI3NmIiLGRhcmttYWdlbnRhOiI4YjAwOGIiLGRhcmtvbGl2ZWdyZWVuOiI1NTZiMmYiLGRhcmtvcmFuZ2U6ImZmOGMwMCIsZGFya29yY2hpZDoiOTkzMmNjIixkYXJrcmVkOiI4YjAwMDAiLGRhcmtzYWxtb246ImU5OTY3YSIsZGFya3NlYWdyZWVuOiI4ZmJjOGYiLGRhcmtzbGF0ZWJsdWU6IjQ4M2Q4YiIsZGFya3NsYXRlZ3JheToiMmY0ZjRmIixkYXJrc2xhdGVncmV5OiIyZjRmNGYiLGRhcmt0dXJxdW9pc2U6IjAwY2VkMSIsZGFya3Zpb2xldDoiOTQwMGQzIixkZWVwcGluazoiZmYxNDkzIixkZWVwc2t5Ymx1ZToiMDBiZmZmIixkaW1ncmF5OiI2OTY5NjkiLGRpbWdyZXk6IjY5Njk2OSIsZG9kZ2VyYmx1ZToiMWU5MGZmIixmaXJlYnJpY2s6ImIyMjIyMiIsZmxvcmFsd2hpdGU6ImZmZmFmMCIsZm9yZXN0Z3JlZW46IjIyOGIyMiIsZnVjaHNpYToiZjBmIixnYWluc2Jvcm86ImRjZGNkYyIsZ2hvc3R3aGl0ZToiZjhmOGZmIixnb2xkOiJmZmQ3MDAiLGdvbGRlbnJvZDoiZGFhNTIwIixncmF5OiI4MDgwODAiLGdyZWVuOiIwMDgwMDAiLGdyZWVueWVsbG93OiJhZGZmMmYiLGdyZXk6IjgwODA4MCIsaG9uZXlkZXc6ImYwZmZmMCIsaG90cGluazoiZmY2OWI0IixpbmRpYW5yZWQ6ImNkNWM1YyIsaW5kaWdvOiI0YjAwODIiLGl2b3J5OiJmZmZmZjAiLGtoYWtpOiJmMGU2OGMiLGxhdmVuZGVyOiJlNmU2ZmEiLGxhdmVuZGVyYmx1c2g6ImZmZjBmNSIsbGF3bmdyZWVuOiI3Y2ZjMDAiLGxlbW9uY2hpZmZvbjoiZmZmYWNkIixsaWdodGJsdWU6ImFkZDhlNiIsbGlnaHRjb3JhbDoiZjA4MDgwIixsaWdodGN5YW46ImUwZmZmZiIsbGlnaHRnb2xkZW5yb2R5ZWxsb3c6ImZhZmFkMiIsbGlnaHRncmF5OiJkM2QzZDMiLGxpZ2h0Z3JlZW46IjkwZWU5MCIsbGlnaHRncmV5OiJkM2QzZDMiLGxpZ2h0cGluazoiZmZiNmMxIixsaWdodHNhbG1vbjoiZmZhMDdhIixsaWdodHNlYWdyZWVuOiIyMGIyYWEiLGxpZ2h0c2t5Ymx1ZToiODdjZWZhIixsaWdodHNsYXRlZ3JheToiNzg5IixsaWdodHNsYXRlZ3JleToiNzg5IixsaWdodHN0ZWVsYmx1ZToiYjBjNGRlIixsaWdodHllbGxvdzoiZmZmZmUwIixsaW1lOiIwZjAiLGxpbWVncmVlbjoiMzJjZDMyIixsaW5lbjoiZmFmMGU2IixtYWdlbnRhOiJmMGYiLG1hcm9vbjoiODAwMDAwIixtZWRpdW1hcXVhbWFyaW5lOiI2NmNkYWEiLG1lZGl1bWJsdWU6IjAwMDBjZCIsbWVkaXVtb3JjaGlkOiJiYTU1ZDMiLG1lZGl1bXB1cnBsZToiOTM3MGRiIixtZWRpdW1zZWFncmVlbjoiM2NiMzcxIixtZWRpdW1zbGF0ZWJsdWU6IjdiNjhlZSIsbWVkaXVtc3ByaW5nZ3JlZW46IjAwZmE5YSIsbWVkaXVtdHVycXVvaXNlOiI0OGQxY2MiLG1lZGl1bXZpb2xldHJlZDoiYzcxNTg1IixtaWRuaWdodGJsdWU6IjE5MTk3MCIsbWludGNyZWFtOiJmNWZmZmEiLG1pc3R5cm9zZToiZmZlNGUxIixtb2NjYXNpbjoiZmZlNGI1IixuYXZham93aGl0ZToiZmZkZWFkIixuYXZ5OiIwMDAwODAiLG9sZGxhY2U6ImZkZjVlNiIsb2xpdmU6IjgwODAwMCIsb2xpdmVkcmFiOiI2YjhlMjMiLG9yYW5nZToiZmZhNTAwIixvcmFuZ2VyZWQ6ImZmNDUwMCIsb3JjaGlkOiJkYTcwZDYiLHBhbGVnb2xkZW5yb2Q6ImVlZThhYSIscGFsZWdyZWVuOiI5OGZiOTgiLHBhbGV0dXJxdW9pc2U6ImFmZWVlZSIscGFsZXZpb2xldHJlZDoiZGI3MDkzIixwYXBheWF3aGlwOiJmZmVmZDUiLHBlYWNocHVmZjoiZmZkYWI5IixwZXJ1OiJjZDg1M2YiLHBpbms6ImZmYzBjYiIscGx1bToiZGRhMGRkIixwb3dkZXJibHVlOiJiMGUwZTYiLHB1cnBsZToiODAwMDgwIixyZWQ6ImYwMCIscm9zeWJyb3duOiJiYzhmOGYiLHJveWFsYmx1ZToiNDE2OWUxIixzYWRkbGVicm93bjoiOGI0NTEzIixzYWxtb246ImZhODA3MiIsc2FuZHlicm93bjoiZjRhNDYwIixzZWFncmVlbjoiMmU4YjU3IixzZWFzaGVsbDoiZmZmNWVlIixzaWVubmE6ImEwNTIyZCIsc2lsdmVyOiJjMGMwYzAiLHNreWJsdWU6Ijg3Y2VlYiIsc2xhdGVibHVlOiI2YTVhY2QiLHNsYXRlZ3JheToiNzA4MDkwIixzbGF0ZWdyZXk6IjcwODA5MCIsc25vdzoiZmZmYWZhIixzcHJpbmdncmVlbjoiMDBmZjdmIixzdGVlbGJsdWU6IjQ2ODJiNCIsdGFuOiJkMmI0OGMiLHRlYWw6IjAwODA4MCIsdGhpc3RsZToiZDhiZmQ4Iix0b21hdG86ImZmNjM0NyIsdHVycXVvaXNlOiI0MGUwZDAiLHZpb2xldDoiZWU4MmVlIix3aGVhdDoiZjVkZWIzIix3aGl0ZToiZmZmIix3aGl0ZXNtb2tlOiJmNWY1ZjUiLHllbGxvdzoiZmYwIix5ZWxsb3dncmVlbjoiOWFjZDMyIn0saGV4TmFtZXM9dGlueWNvbG9yLmhleE5hbWVzPWZsaXAobmFtZXMpLG1hdGNoZXJzPWZ1bmN0aW9uKCl7dmFyIENTU19JTlRFR0VSPSJbLVxcK10/XFxkKyU/IixDU1NfTlVNQkVSPSJbLVxcK10/XFxkKlxcLlxcZCslPyIsQ1NTX1VOSVQ9Iig/OiIrQ1NTX05VTUJFUisiKXwoPzoiK0NTU19JTlRFR0VSKyIpIixQRVJNSVNTSVZFX01BVENIMz0iW1xcc3xcXChdKygiK0NTU19VTklUKyIpWyx8XFxzXSsoIitDU1NfVU5JVCsiKVssfFxcc10rKCIrQ1NTX1VOSVQrIilcXHMqXFwpPyIsUEVSTUlTU0lWRV9NQVRDSDQ9IltcXHN8XFwoXSsoIitDU1NfVU5JVCsiKVssfFxcc10rKCIrQ1NTX1VOSVQrIilbLHxcXHNdKygiK0NTU19VTklUKyIpWyx8XFxzXSsoIitDU1NfVU5JVCsiKVxccypcXCk/IjtyZXR1cm57cmdiOlJlZ0V4cCgicmdiIitQRVJNSVNTSVZFX01BVENIMykscmdiYTpSZWdFeHAoInJnYmEiK1BFUk1JU1NJVkVfTUFUQ0g0KSxoc2w6UmVnRXhwKCJoc2wiK1BFUk1JU1NJVkVfTUFUQ0gzKSxoc2xhOlJlZ0V4cCgiaHNsYSIrUEVSTUlTU0lWRV9NQVRDSDQpLGhzdjpSZWdFeHAoImhzdiIrUEVSTUlTU0lWRV9NQVRDSDMpLGhleDM6L14oWzAtOWEtZkEtRl17MX0pKFswLTlhLWZBLUZdezF9KShbMC05YS1mQS1GXXsxfSkkLyxoZXg2Oi9eKFswLTlhLWZBLUZdezJ9KShbMC05YS1mQS1GXXsyfSkoWzAtOWEtZkEtRl17Mn0pJC99fSgpOyJ1bmRlZmluZWQiIT10eXBlb2YgbW9kdWxlJiZtb2R1bGUuZXhwb3J0cz9tb2R1bGUuZXhwb3J0cz10aW55Y29sb3I6InVuZGVmaW5lZCIhPXR5cGVvZiBkZWZpbmU/ZGVmaW5lKGZ1bmN0aW9uKCl7cmV0dXJuIHRpbnljb2xvcn0pOnJvb3QudGlueWNvbG9yPXRpbnljb2xvcn0pKHRoaXMpOwovKgogICAgKiBQaWNrLWEtQ29sb3IgSlMgdjEuMi4zCiAgICAqIENvcHlyaWdodCAyMDEzIExhdXJlbiBTcGVyYmVyIGFuZCBCcm9hZHN0cmVldCBBZHMKICAgICogaHR0cHM6Ly9naXRodWIuY29tL2xhdXJlbi9waWNrLWEtY29sb3IvYmxvYi9tYXN0ZXIvTElDRU5TRQoqLwohZnVuY3Rpb24obyl7InVzZSBzdHJpY3QiO28uZm4ucGlja0FDb2xvcj1mdW5jdGlvbih0KXt2b2lkIDA9PT10LnRvdWNoT25seU1vZGUmJih0LnRvdWNoT25seU1vZGU9ITEpO3ZhciBlPSJvbnRvdWNoc3RhcnQiaW4gd2luZG93JiZ0LnRvdWNoT25seU1vZGUsYT0ocGFyc2VJbnQobyh3aW5kb3cpLndpZHRoKCksMTApPDc2Nz8hMDohMSwibG9jYWxTdG9yYWdlImluIHdpbmRvdyYmbnVsbCE9PXdpbmRvdy5sb2NhbFN0b3JhZ2UmJiJvYmplY3QiPT10eXBlb2YgSlNPTiksbj1kb2N1bWVudC5hbGwmJiF3aW5kb3cuYXRvYixyPWU/InRvdWNoc3RhcnQucGlja0FDb2xvciI6Im1vdXNlZG93bi5waWNrQUNvbG9yIixzPWU/InRvdWNobW92ZS5waWNrQUNvbG9yIjoibW91c2Vtb3ZlLnBpY2tBQ29sb3IiLGk9ZT8idG91Y2hlbmQucGlja0FDb2xvciI6Im1vdXNldXAucGlja0FDb2xvciIsbD1lPyJ0b3VjaGVuZC5waWNrQUNvbG9yIjoiY2xpY2sucGlja0FDb2xvciIsZD0iZHJhZ2dpbmcucGlja0FDb2xvciIsYz0iZW5kRHJhZy5waWNrQUNvbG9yIixwPW8uZXh0ZW5kKHtzaG93U3BlY3RydW06ITAsc2hvd1NhdmVkQ29sb3JzOiEwLHNhdmVDb2xvcnNQZXJFbGVtZW50OiExLGZhZGVNZW51VG9nZ2xlOiEwLHNob3dBZHZhbmNlZDohMCxzaG93QmFzaWNDb2xvcnM6ITAsc2hvd0hleElucHV0OiEwLGFsbG93Qmxhbms6ITEsaW5saW5lRHJvcGRvd246ITEsYmFzaWNDb2xvcnM6e3doaXRlOiJmZmYiLHJlZDoiZjAwIixvcmFuZ2U6ImY2MCIseWVsbG93OiJmZjAiLGdyZWVuOiIwMDgwMDAiLGJsdWU6IjAwZiIscHVycGxlOiI4MDAwODAiLGJsYWNrOiIwMDAifX0sdCk7cC5zaG93QWR2YW5jZWR8fHAuc2hvd0Jhc2ljQ29sb3JzfHwocC5zaG93QmFzaWNDb2xvcnM9ITApO3ZhciB1PXAuc2hvd1NhdmVkQ29sb3JzJiZwLnNob3dBZHZhbmNlZHx8cC5zaG93QmFzaWNDb2xvcnMmJnAuc2hvd1NhdmVkQ29sb3JzfHxwLnNob3dCYXNpY0NvbG9ycyYmcC5zaG93QWR2YW5jZWQsaD1mdW5jdGlvbigpe3ZhciB0PW8oIjxkaXY+IikuYWRkQ2xhc3MoImlucHV0LWdyb3VwLWJ0biIpLGU9bygiPGJ1dHRvbiB0eXBlPSdidXR0b24nPiIpLmFkZENsYXNzKCJidG4gYnRuLWRlZmF1bHQgY29sb3ItZHJvcGRvd24gZHJvcGRvd24tdG9nZ2xlIiksYT1vKCI8c3Bhbj4iKS5hZGRDbGFzcygiY29sb3ItcHJldmlldyBjdXJyZW50LWNvbG9yIikscj1vKCI8c3Bhbj4iKS5hZGRDbGFzcygiY2FyZXQiKSxzPW8oIjxkaXY+IikuYWRkQ2xhc3MoImNvbG9yLW1lbnUgZHJvcGRvd24tbWVudSIpO2lmKHAuaW5saW5lRHJvcGRvd24mJnMuYWRkQ2xhc3MoImNvbG9yLW1lbnUtLWlubGluZSIpLHAuc2hvd0hleElucHV0fHwoZS5hZGRDbGFzcygibm8taGV4Iikscy5hZGRDbGFzcygibm8taGV4IikpLHQuYXBwZW5kKGUuYXBwZW5kKGEpLmFwcGVuZChyKSksdXx8cC5zaG93U3BlY3RydW18fHMuYWRkQ2xhc3MoInNtYWxsIiksdSl7dmFyIGk9bygiPGRpdj4iKS5hZGRDbGFzcygiY29sb3ItbWVudS10YWJzIiksbD1wLnNob3dCYXNpY0NvbG9ycz8ic2F2ZWRDb2xvcnMtdGFiIHRhYiI6InNhdmVkQ29sb3JzLXRhYiB0YWIgdGFiLWFjdGl2ZSI7cC5zaG93QmFzaWNDb2xvcnMmJmkuYXBwZW5kKG8oIjxzcGFuPiIpLmFkZENsYXNzKCJiYXNpY0NvbG9ycy10YWIgdGFiIHRhYi1hY3RpdmUiKS5hcHBlbmQobygiPGE+IikudGV4dCgiQmFzaWMgQ29sb3JzIikpKSxwLnNob3dTYXZlZENvbG9ycyYmaS5hcHBlbmQobygiPHNwYW4+IikuYWRkQ2xhc3MobCkuYXBwZW5kKG8oIjxhPiIpLnRleHQoIlNhdmVkIENvbG9ycyIpKSkscC5zaG93QWR2YW5jZWQmJmkuYXBwZW5kKG8oIjxzcGFuPiIpLmFkZENsYXNzKCJhZHZhbmNlZC10YWIgdGFiIikuYXBwZW5kKG8oIjxhPiIpLnRleHQoIkFkdmFuY2VkIikpKSxzLmFwcGVuZChpKX1pZihwLnNob3dCYXNpY0NvbG9ycyl7dmFyIGQ9bygiPGRpdj4iKS5hZGRDbGFzcygiYmFzaWNDb2xvcnMtY29udGVudCBhY3RpdmUtY29udGVudCIpO3Auc2hvd1NwZWN0cnVtJiZkLmFwcGVuZChvKCI8aDY+IikuYWRkQ2xhc3MoImNvbG9yLW1lbnUtaW5zdHJ1Y3Rpb25zIikudGV4dCgiVGFwIHNwZWN0cnVtIG9yIGRyYWcgYmFuZCB0byBjaGFuZ2UgY29sb3IiKSk7dmFyIGM9bygiPHVsPiIpLmFkZENsYXNzKCJiYXNpYy1jb2xvcnMtbGlzdCIpO28uZWFjaChwLmJhc2ljQ29sb3JzLGZ1bmN0aW9uKHQsZSl7dmFyIGE9bygiPGxpPiIpLmFkZENsYXNzKCJjb2xvci1pdGVtIikscj1vKCI8YT4iKS5hZGRDbGFzcyh0KyIgY29sb3ItbGluayIpLHM9bygiPHNwYW4+IikuYWRkQ2xhc3MoImNvbG9yLXByZXZpZXcgIit0KSxpPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJjb2xvci1sYWJlbCIpLnRleHQodCk7aWYoci5hcHBlbmQocyxpKSxzLmFwcGVuZCgpLCIjIiE9PWVbMF0mJihlPSIjIitlKSxzLmNzcygiYmFja2dyb3VuZC1jb2xvciIsZSkscC5zaG93U3BlY3RydW0pe3ZhciBsPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJjb2xvci1ib3ggc3BlY3RydW0tIit0KTtuJiZvLmVhY2goWzAsMV0sZnVuY3Rpb24oYSl7ImZmZiIhPT1lJiYiMDAwIiE9PXQmJmwuYXBwZW5kKG8oIjxzcGFuPiIpLmFkZENsYXNzKHQrIi1zcGVjdHJ1bS0iK2ErIiBpZS1zcGVjdHJ1bSIpKX0pO3ZhciBkPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJoaWdobGlnaHQtYmFuZCIpO28uZWFjaChbMCwxLDJdLGZ1bmN0aW9uKCl7ZC5hcHBlbmQobygiPHNwYW4+IikuYWRkQ2xhc3MoImhpZ2hsaWdodC1iYW5kLXN0cmlwZSIpKX0pLHIuYXBwZW5kKGwuYXBwZW5kKGQpKX1jLmFwcGVuZChhLmFwcGVuZChyKSl9KSxzLmFwcGVuZChkLmFwcGVuZChjKSl9aWYocC5zaG93U2F2ZWRDb2xvcnMpe3ZhciBoPXAuc2hvd0Jhc2ljQ29sb3JzPyJpbmFjdGl2ZS1jb250ZW50IjoiYWN0aXZlLWNvbnRlbnQiLGc9bygiPGRpdj4iKS5hZGRDbGFzcygic2F2ZWRDb2xvcnMtY29udGVudCIpLmFkZENsYXNzKGgpO2cuYXBwZW5kKG8oIjxwPiIpLmFkZENsYXNzKCJzYXZlZC1jb2xvcnMtaW5zdHJ1Y3Rpb25zIikudGV4dCgiVHlwZSBpbiBhIGNvbG9yIG9yIHVzZSB0aGUgc3BlY3RydW1zIHRvIGxpZ2h0ZW4gb3IgZGFya2VuIGFuIGV4aXN0aW5nIGNvbG9yLiIpKSxzLmFwcGVuZChnKX1pZihwLnNob3dBZHZhbmNlZCl7dmFyIHY9cC5zaG93QmFzaWNDb2xvcnN8fHAuc2hvd1NhdmVkQ29sb3JzPyJpbmFjdGl2ZS1jb250ZW50IjoiYWN0aXZlLWNvbnRlbnQiLGY9bygiPGRpdj4iKS5hZGRDbGFzcygiYWR2YW5jZWQtY29udGVudCIpLmFkZENsYXNzKHYpLmFwcGVuZChvKCI8aDY+IikuYWRkQ2xhc3MoImFkdmFuY2VkLWluc3RydWN0aW9ucyIpLnRleHQoIlRhcCBzcGVjdHJ1bSBvciBkcmFnIGJhbmQgdG8gY2hhbmdlIGNvbG9yIikpLEM9bygiPHVsPiIpLmFkZENsYXNzKCJhZHZhbmNlZC1saXN0IiksbT1vKCI8bGk+IikuYWRkQ2xhc3MoImh1ZS1pdGVtIiksYj1vKCI8c3Bhbj4iKS5hZGRDbGFzcygiaHVlLXRleHQiKS50ZXh0KCJIdWU6ICIpLmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygiaHVlLXZhbHVlIikudGV4dCgiMCIpKSx3PW8oIjxzcGFuPiIpLmFkZENsYXNzKCJjb2xvci1ib3ggc3BlY3RydW0taHVlIik7biYmby5lYWNoKFswLDEsMiwzLDQsNSw2XSxmdW5jdGlvbih0KXt3LmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygiaHVlLXNwZWN0cnVtLSIrdCsiIGllLXNwZWN0cnVtIGh1ZSIpKX0pO3ZhciBTPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJoaWdobGlnaHQtYmFuZCIpO28uZWFjaChbMCwxLDJdLGZ1bmN0aW9uKCl7Uy5hcHBlbmQobygiPHNwYW4+IikuYWRkQ2xhc3MoImhpZ2hsaWdodC1iYW5kLXN0cmlwZSIpKX0pLEMuYXBwZW5kKG0uYXBwZW5kKGIpLmFwcGVuZCh3LmFwcGVuZChTKSkpO3ZhciB5PW8oIjxsaT4iKS5hZGRDbGFzcygibGlnaHRuZXNzLWl0ZW0iKSxrPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJjb2xvci1ib3ggc3BlY3RydW0tbGlnaHRuZXNzIikseD1vKCI8c3Bhbj4iKS5hZGRDbGFzcygibGlnaHRuZXNzLXRleHQiKS50ZXh0KCJMaWdodG5lc3M6ICIpLmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygibGlnaHRuZXNzLXZhbHVlIikudGV4dCgiNTAlIikpO24mJm8uZWFjaChbMCwxXSxmdW5jdGlvbih0KXtrLmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygibGlnaHRuZXNzLXNwZWN0cnVtLSIrdCsiIGllLXNwZWN0cnVtIikpfSk7dmFyIEg9bygiPHNwYW4+IikuYWRkQ2xhc3MoImhpZ2hsaWdodC1iYW5kIik7by5lYWNoKFswLDEsMl0sZnVuY3Rpb24oKXtILmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygiaGlnaGxpZ2h0LWJhbmQtc3RyaXBlIikpfSksQy5hcHBlbmQoeS5hcHBlbmQoeCkuYXBwZW5kKGsuYXBwZW5kKEgpKSk7dmFyIEE9bygiPGxpPiIpLmFkZENsYXNzKCJzYXR1cmF0aW9uLWl0ZW0iKSxCPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJjb2xvci1ib3ggc3BlY3RydW0tc2F0dXJhdGlvbiIpO24mJm8uZWFjaChbMCwxXSxmdW5jdGlvbih0KXtCLmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygic2F0dXJhdGlvbi1zcGVjdHJ1bS0iK3QrIiBpZS1zcGVjdHJ1bSIpKX0pO3ZhciBNPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJoaWdobGlnaHQtYmFuZCIpO28uZWFjaChbMCwxLDJdLGZ1bmN0aW9uKCl7TS5hcHBlbmQobygiPHNwYW4+IikuYWRkQ2xhc3MoImhpZ2hsaWdodC1iYW5kLXN0cmlwZSIpKX0pO3ZhciBJPW8oIjxzcGFuPiIpLmFkZENsYXNzKCJzYXR1cmF0aW9uLXRleHQiKS50ZXh0KCJTYXR1cmF0aW9uOiAiKS5hcHBlbmQobygiPHNwYW4+IikuYWRkQ2xhc3MoInNhdHVyYXRpb24tdmFsdWUiKS50ZXh0KCIxMDAlIikpO0MuYXBwZW5kKEEuYXBwZW5kKEkpLmFwcGVuZChCLmFwcGVuZChNKSkpO3ZhciBUPW8oIjxsaT4iKS5hZGRDbGFzcygicHJldmlldy1pdGVtIikuYXBwZW5kKG8oIjxzcGFuPiIpLmFkZENsYXNzKCJwcmV2aWV3LXRleHQiKS50ZXh0KCJQcmV2aWV3IikpLFA9bygiPHNwYW4+IikuYWRkQ2xhc3MoImNvbG9yLXByZXZpZXcgYWR2YW5jZWQiKS5hcHBlbmQoIjxidXR0b24gY2xhc3M9J2NvbG9yLXNlbGVjdCBidG4gYnRuLW1pbmkgYWR2YW5jZWQnIHR5cGU9J2J1dHRvbic+U2VsZWN0PC9idXR0b24+Iik7Qy5hcHBlbmQoVC5hcHBlbmQoUCkpLHMuYXBwZW5kKGYuYXBwZW5kKEMpKX1yZXR1cm4gdC5hcHBlbmQocyksdH0sZz17fSx2PXtyb3dzSW5Ecm9wZG93bjo4LG1heENvbHNJbkRyb3Bkb3duOjJ9O2lmKHAuc2hvd1NhdmVkQ29sb3JzKXt2YXIgZj1bXTtpZihhJiZsb2NhbFN0b3JhZ2UuYWxsU2F2ZWRDb2xvcnMpZj1KU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5hbGxTYXZlZENvbG9ycyk7ZWxzZSBpZihkb2N1bWVudC5jb29raWUubWF0Y2goInBpY2tBQ29sb3JTYXZlZENvbG9ycy1hbGxTYXZlZENvbG9ycz0iKSl7dmFyIEM9ZG9jdW1lbnQuY29va2llLnNwbGl0KCI7Iik7by5lYWNoKEMsZnVuY3Rpb24obyl7Q1tvXS5tYXRjaCgicGlja0FDb2xvclNhdmVkQ29sb3JzLWFsbFNhdmVkQ29sb3JzPSIpJiYoZj1DW29dLnNwbGl0KCI9IilbMV0uc3BsaXQoIiwiKSl9KX19dmFyIG09e2luaXRpYWxpemU6ZnVuY3Rpb24odCl7dmFyIGUsYSxuPW8odGhpcyk7bi5hdHRyKCJuYW1lIil8fG4uYXR0cigibmFtZSIsInBpY2stYS1jb2xvci0iK3QpLGE9bi5hdHRyKCJuYW1lIiksbi5hZGRDbGFzcygicGljay1hLWNvbG9yIikscC5hbGxvd0JsYW5rP24udmFsKCkubWF0Y2goL15ccyskfF4kLyl8fChnLmRlZmF1bHRDb2xvcj10aW55Y29sb3Iobi52YWwoKSkudG9IZXgoKSxnLnR5cGVkQ29sb3I9Zy5kZWZhdWx0Q29sb3Isbi52YWwoZy5kZWZhdWx0Q29sb3IpKTooZy5kZWZhdWx0Q29sb3I9dGlueWNvbG9yKG4udmFsKCkpLnRvSGV4KCksZy50eXBlZENvbG9yPWcuZGVmYXVsdENvbG9yLG4udmFsKGcuZGVmYXVsdENvbG9yKSksbyhuKS53cmFwKCc8ZGl2IGNsYXNzPSJpbnB1dC1ncm91cCBwaWNrLWEtY29sb3ItbWFya3VwIiBpZD0iJythKyciPicpLGU9byhuLnBhcmVudCgpKSxwLnNob3dIZXhJbnB1dD9lLnByZXBlbmQoJzxzcGFuIGNsYXNzPSJoZXgtcG91bmQgaW5wdXQtZ3JvdXAtYWRkb24iPiM8L3NwYW4+JykuYXBwZW5kKGgoKSk6ZS5hcHBlbmQoaCgpKSxwLnNob3dIZXhJbnB1dHx8bi5hdHRyKCJ0eXBlIiwiaGlkZGVuIil9LHVwZGF0ZVByZXZpZXc6ZnVuY3Rpb24obyl7cC5hbGxvd0JsYW5rPyhnLnR5cGVkQ29sb3I9by52YWwoKS5tYXRjaCgvXlxzKyR8XiQvKT8iIjp0aW55Y29sb3Ioby52YWwoKSkudG9IZXgoKSwiIj09PWcudHlwZWRDb2xvcj9vLnNpYmxpbmdzKCIuaW5wdXQtZ3JvdXAtYnRuIikuZmluZCgiLmN1cnJlbnQtY29sb3IiKS5jc3MoImJhY2tncm91bmQiLCJub25lIik6by5zaWJsaW5ncygiLmlucHV0LWdyb3VwLWJ0biIpLmZpbmQoIi5jdXJyZW50LWNvbG9yIikuY3NzKCJiYWNrZ3JvdW5kLWNvbG9yIiwiIyIrZy50eXBlZENvbG9yKSk6KGcudHlwZWRDb2xvcj10aW55Y29sb3Ioby52YWwoKSkudG9IZXgoKSxvLnNpYmxpbmdzKCIuaW5wdXQtZ3JvdXAtYnRuIikuZmluZCgiLmN1cnJlbnQtY29sb3IiKS5jc3MoImJhY2tncm91bmQtY29sb3IiLCIjIitnLnR5cGVkQ29sb3IpKX0scHJlc3NQcmV2aWV3QnV0dG9uOmZ1bmN0aW9uKCl7dmFyIG89YXJndW1lbnRzWzBdLnRoaXNFdmVudDtvLnN0b3BQcm9wYWdhdGlvbigpLG0udG9nZ2xlRHJvcGRvd24oby50YXJnZXQpfSxvcGVuRHJvcGRvd246ZnVuY3Rpb24odCxhKXtvKCIuY29sb3ItbWVudSIpLmVhY2goZnVuY3Rpb24oKXt2YXIgdD1vKHRoaXMpO2lmKCJibG9jayI9PT10LmNzcygiZGlzcGxheSIpKXt2YXIgZT10LnBhcmVudHMoIi5pbnB1dC1ncm91cC1idG4iKTttLmNsb3NlRHJvcGRvd24oZSx0KX19KSxwLmZhZGVNZW51VG9nZ2xlJiYhZT9vKGEpLmZhZGVJbigiZmFzdCIpOm8oYSkuc2hvdygpLG8odCkuYWRkQ2xhc3MoIm9wZW4iKX0sY2xvc2VEcm9wZG93bjpmdW5jdGlvbih0LGEpe3AuZmFkZU1lbnVUb2dnbGUmJiFlP28oYSkuZmFkZU91dCgiZmFzdCIpOm8oYSkuY3NzKCJkaXNwbGF5Iiwibm9uZSIpLG8odCkucmVtb3ZlQ2xhc3MoIm9wZW4iKX0sY2xvc2VEcm9wZG93bklmT3BlbjpmdW5jdGlvbigpe3ZhciBvPWFyZ3VtZW50c1swXS5idXR0b24sdD1hcmd1bWVudHNbMF0ubWVudTsiYmxvY2siPT09dC5jc3MoImRpc3BsYXkiKSYmbS5jbG9zZURyb3Bkb3duKG8sdCl9LHRvZ2dsZURyb3Bkb3duOmZ1bmN0aW9uKHQpe3ZhciBlPW8odCkucGFyZW50cygiLnBpY2stYS1jb2xvci1tYXJrdXAiKSxhPWUuZmluZCgiaW5wdXQiKSxuPWUuZmluZCgiLmlucHV0LWdyb3VwLWJ0biIpLHI9ZS5maW5kKCIuY29sb3ItbWVudSIpO2EuaXMoIjpkaXNhYmxlZCIpfHwibm9uZSIhPT1yLmNzcygiZGlzcGxheSIpP20uY2xvc2VEcm9wZG93bihuLHIpOm0ub3BlbkRyb3Bkb3duKG4scil9LHRhYmJhYmxlOmZ1bmN0aW9uKCl7dmFyIHQ9byh0aGlzKSxlPXQucGFyZW50cygiLnBpY2stYS1jb2xvci1tYXJrdXAiKTt0LmNsaWNrKGZ1bmN0aW9uKCl7dmFyIHQ9byh0aGlzKSxhPXQuYXR0cigiY2xhc3MiKS5zcGxpdCgiICIpWzBdLnNwbGl0KCItIilbMF0rIi1jb250ZW50IixuPXQucGFyZW50cygiLmRyb3Bkb3duLW1lbnUiKS5maW5kKCIuIithKTt0Lmhhc0NsYXNzKCJ0YWItYWN0aXZlIil8fChlLmZpbmQoIi50YWItYWN0aXZlIikucmVtb3ZlQ2xhc3MoInRhYi1hY3RpdmUiKSxlLmZpbmQoIi5hY3RpdmUtY29udGVudCIpLnJlbW92ZUNsYXNzKCJhY3RpdmUtY29udGVudCIpLmFkZENsYXNzKCJpbmFjdGl2ZS1jb250ZW50IiksdC5hZGRDbGFzcygidGFiLWFjdGl2ZSIpLG8obikuYWRkQ2xhc3MoImFjdGl2ZS1jb250ZW50IikucmVtb3ZlQ2xhc3MoImluYWN0aXZlLWNvbnRlbnQiKSl9KX0sZ2V0Q29sb3JNdWx0aXBsaWVyOmZ1bmN0aW9uKHQsYSxuKXt2YXIgcj0iYmFzaWMiPT09bj9wYXJzZUludChvKCIuY29sb3ItYm94IikuZmlyc3QoKS53aWR0aCgpLDEwKTpwYXJzZUludChvKCIuYWR2YW5jZWQtbGlzdCIpLmZpbmQoIi5jb2xvci1ib3giKS5maXJzdCgpLndpZHRoKCksMTApOzA9PT1yJiYocj0iYmFzaWMiPT09bj9lPzE2MDoyMDA6ZT8xNjA6MzAwKTt2YXIgcz1yLzIsaT1hL3I7cmV0dXJuImJpZGlyZWN0aW9uYWwiPT09dD8uNT49aT8oMS1hL3MpLzI6LSgoYS1zKS9zKS8yOiJkYXJrZW5SaWdodCI9PT10Py0oaS8yKTppLzJ9LG1vZGlmeUhTTExpZ2h0bmVzczpmdW5jdGlvbihvLHQpe3ZhciBlPW87cmV0dXJuIGUubCs9dCxlLmw9TWF0aC5taW4oTWF0aC5tYXgoMCxlLmwpLDEpLHRpbnljb2xvcihlKS50b0hzbFN0cmluZygpfSxnZXRNb3ZlYWJsZUFyZWE6ZnVuY3Rpb24obyl7dmFyIHQ9e30sZT1vLnBhcmVudCgpLGE9by5vdXRlcldpZHRoKCksbj1lLndpZHRoKCkscj1lLm9mZnNldCgpO3JldHVybiB0Lm1pblg9ci5sZWZ0LHQubWF4WD1uLWEsdH0sbW92ZUhpZ2hsaWdodEJhbmQ6ZnVuY3Rpb24odCxhLG4pe3ZhciByPW8oIi5oaWdobGlnaHQtYmFuZCIpLmZpcnN0KCkub3V0ZXJXaWR0aCgpLHM9Ljc1KnIsaT1lP24ub3JpZ2luYWxFdmVudC5wYWdlWDpuLnBhZ2VYLGw9aS1hLm1pblgtcztsPU1hdGgubWF4KDAsTWF0aC5taW4obCxhLm1heFgpKSx0LmNzcygicG9zaXRpb24iLCJhYnNvbHV0ZSIpLHQuY3NzKCJsZWZ0IixsKX0saG9yaXpvbnRhbGx5RHJhZ2dhYmxlOmZ1bmN0aW9uKCl7byh0aGlzKS5vbihyLGZ1bmN0aW9uKHQpe3QucHJldmVudERlZmF1bHQoKTt2YXIgZT1vKHQuZGVsZWdhdGVUYXJnZXQpO2UuY3NzKCJjdXJzb3IiLCItd2Via2l0LWdyYWJiaW5nIiksZS5jc3MoImN1cnNvciIsIi1tb3otZ3JhYmJpbmciKTt2YXIgYT1tLmdldE1vdmVhYmxlQXJlYShlKTtvKGRvY3VtZW50KS5vbihzLGZ1bmN0aW9uKG8pe2UudHJpZ2dlcihkKSxtLm1vdmVIaWdobGlnaHRCYW5kKGUsYSxvKX0pLm9uKGksZnVuY3Rpb24odCl7byhkb2N1bWVudCkub2ZmKHMpLG8oZG9jdW1lbnQpLm9mZihkKSxlLmNzcygiY3Vyc29yIiwiLXdlYmtpdC1ncmFiIiksZS5jc3MoImN1cnNvciIsIi1tb3otZ3JhYiIpLGUudHJpZ2dlcihjKSxvKGRvY3VtZW50KS5vZmYoaSl9KX0pLm9uKGksZnVuY3Rpb24odCl7dC5zdG9wUHJvcGFnYXRpb24oKSxvKGRvY3VtZW50KS5vZmYocyksbyhkb2N1bWVudCkub2ZmKGQpfSl9LG1vZGlmeUhpZ2hsaWdodEJhbmQ6ZnVuY3Rpb24obyx0LGUpe3ZhciBhPXtoOjAsczowLGw6LjA1fSxuPXtoOjAsczowLGw6LjV9LHI9LXQscz1vLmZpbmQoIi5oaWdobGlnaHQtYmFuZC1zdHJpcGUiKSxpPSJsaWdodGVuUmlnaHQiPT09ZT9tLm1vZGlmeUhTTExpZ2h0bmVzcyhuLHIpOm0ubW9kaWZ5SFNMTGlnaHRuZXNzKGEscik7by5jc3MoImJvcmRlci1jb2xvciIsaSkscy5jc3MoImJhY2tncm91bmQtY29sb3IiLGkpfSxjYWxjdWxhdGVIaWdobGlnaHRlZENvbG9yOmZ1bmN0aW9uKCl7dmFyIHQsZSxhLG4scixzLGksbCxkPW8odGhpcyksYz1kLnBhcmVudCgpLHU9bygiLmhpZ2hsaWdodC1iYW5kIikuZmlyc3QoKS5vdXRlcldpZHRoKCksaD11LzIsZz1hcmd1bWVudHNbMF0udHlwZTtpZigiYmFzaWMiPT09Zyl7dmFyIHY9Yy5hdHRyKCJjbGFzcyIpLnNwbGl0KCItIilbMl0sZj1wLmJhc2ljQ29sb3JzW3ZdO3N3aXRjaChlPXRpbnljb2xvcihmKS50b0hzbCgpLGYpe2Nhc2UiZmZmIjp0PSJkYXJrZW5SaWdodCI7YnJlYWs7Y2FzZSIwMDAiOnQ9ImxpZ2h0ZW5SaWdodCI7YnJlYWs7ZGVmYXVsdDp0PSJiaWRpcmVjdGlvbmFsIn19ZWxzZXt2YXIgQz1kLnBhcmVudHMoIi5hZHZhbmNlZC1saXN0Iik7bj1hcmd1bWVudHNbMF0uaHNsLnMsaT1DLmZpbmQoIi5zcGVjdHJ1bS1odWUiKSxhPWFyZ3VtZW50c1swXS5oc2wuaCxzPUMuZmluZCgiLnNwZWN0cnVtLXNhdHVyYXRpb24iKSxsPUMuZmluZCgiLmxpZ2h0bmVzcy12YWx1ZSIpLHI9Qy5maW5kKCIuY29sb3ItcHJldmlldyIpLGU9e2g6YXJndW1lbnRzWzBdLmhzbC5oLGw6LjUsczphcmd1bWVudHNbMF0uaHNsLnN9LHQ9ImJpZGlyZWN0aW9uYWwifXZhciBiPXBhcnNlSW50KGQuY3NzKCJsZWZ0IiksMTApK2gsdz1tLmdldENvbG9yTXVsdGlwbGllcih0LGIsZyksUz1tLm1vZGlmeUhTTExpZ2h0bmVzcyhlLHcpLHk9IiMiK3Rpbnljb2xvcihTKS50b0hleCgpLGs9Uy5zcGxpdCgiKCIpWzFdLnNwbGl0KCIpIilbMF0uc3BsaXQoIiwiKVsyXSx4PXBhcnNlSW50KGsuc3BsaXQoIiUiKVswXSwxMCkvMTAwO3JldHVybiJiYXNpYyI9PT1nPyhjLnNpYmxpbmdzKCIuY29sb3ItcHJldmlldyIpLmNzcygiYmFja2dyb3VuZC1jb2xvciIseSksYy5wcmV2KCIuY29sb3ItbGFiZWwiKS5yZXBsYWNlV2l0aCgnPGJ1dHRvbiBjbGFzcz0iY29sb3Itc2VsZWN0IGJ0biBidG4tbWluaSIgdHlwZT0iYnV0dG9uIj5TZWxlY3Q8L2J1dHRvbj4nKSwiZGFya2VuUmlnaHQiIT09dCYmbS5tb2RpZnlIaWdobGlnaHRCYW5kKGQsdyx0KSk6KHIuY3NzKCJiYWNrZ3JvdW5kLWNvbG9yIix5KSxsLnRleHQoayksbS51cGRhdGVTYXR1cmF0aW9uU3R5bGVzKHMsYSx4KSxtLnVwZGF0ZUh1ZVN0eWxlcyhpLG4seCksbS5tb2RpZnlIaWdobGlnaHRCYW5kKG8oIi5hZHZhbmNlZC1jb250ZW50IC5oaWdobGlnaHQtYmFuZCIpLHcsdCkpLCJiYXNpYyI9PT1nP3Rpbnljb2xvcihTKS50b0hleCgpOnh9LHVwZGF0ZVNhdmVkQ29sb3JQcmV2aWV3OmZ1bmN0aW9uKHQpe28uZWFjaCh0LGZ1bmN0aW9uKGUpe3ZhciBhPW8odFtlXSksbj1hLmF0dHIoImNsYXNzIik7YS5maW5kKCIuY29sb3ItcHJldmlldyIpLmNzcygiYmFja2dyb3VuZC1jb2xvciIsbil9KX0sdXBkYXRlU2F2ZWRDb2xvck1hcmt1cDpmdW5jdGlvbih0LGUpe2lmKGU9ZT9lOmYscC5zaG93U2F2ZWRDb2xvcnMmJmUubGVuZ3RoPjApe3Auc2F2ZUNvbG9yc1BlckVsZW1lbnR8fCh0PW8oIi5zYXZlZENvbG9ycy1jb250ZW50IiksZT1mKTt2YXIgYT12LnJvd3NJbkRyb3Bkb3duKnYubWF4Q29sc0luRHJvcGRvd247ZT1lLnNsaWNlKDAsYSk7dmFyIG49bygiPHVsPiIpLmFkZENsYXNzKCJzYXZlZC1jb2xvci1jb2wgMCIpLHI9bygiPHVsPiIpLmFkZENsYXNzKCJzYXZlZC1jb2xvci1jb2wgMSIpO28uZWFjaChlLGZ1bmN0aW9uKHQsZSl7dmFyIGE9bygiPGxpPiIpLmFkZENsYXNzKCJjb2xvci1pdGVtIikscz1vKCI8YT4iKS5hZGRDbGFzcyhlKTtzLmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygiY29sb3ItcHJldmlldyIpKSxzLmFwcGVuZChvKCI8c3Bhbj4iKS5hZGRDbGFzcygiY29sb3ItbGFiZWwiKS50ZXh0KGUpKSxhLmFwcGVuZChzKSx0JTI9PT0wP24uYXBwZW5kKGEpOnIuYXBwZW5kKGEpfSksdC5odG1sKG4pLHQuYXBwZW5kKHIpO3ZhciBzPW8odCkuZmluZCgiYSIpO20udXBkYXRlU2F2ZWRDb2xvclByZXZpZXcocyl9fSxzZXRTYXZlZENvbG9yc0Nvb2tpZTpmdW5jdGlvbihvLHQpe3ZhciBlPW5ldyBEYXRlLGE9MzE1MzZlNyxuPW5ldyBEYXRlKGUuZ2V0VGltZSgpK2EpO249bi50b0dNVFN0cmluZygpLCJ1bmRlZmluZWQiPT10eXBlb2YgdD9kb2N1bWVudC5jb29raWU9InBpY2tBQ29sb3JTYXZlZENvbG9ycy1hbGxTYXZlZENvbG9ycz0iK28rIjtleHBpcmVzPSIrbjpkb2N1bWVudC5jb29raWU9InBpY2tBQ29sb3JTYXZlZENvbG9ycy0iK3QrIj0iK28rIjsgZXhwaXJlcz0iK259LHNhdmVDb2xvcnNUb0xvY2FsU3RvcmFnZTpmdW5jdGlvbihvLHQpe2lmKGEpaWYoInVuZGVmaW5lZCI9PXR5cGVvZiB0KXRyeXtsb2NhbFN0b3JhZ2UuYWxsU2F2ZWRDb2xvcnM9SlNPTi5zdHJpbmdpZnkobyl9Y2F0Y2goZSl7bG9jYWxTdG9yYWdlLmNsZWFyKCl9ZWxzZSB0cnl7bG9jYWxTdG9yYWdlWyJwaWNrQUNvbG9yU2F2ZWRDb2xvcnMtIit0XT1KU09OLnN0cmluZ2lmeShvKX1jYXRjaChlKXtsb2NhbFN0b3JhZ2UuY2xlYXIoKX1lbHNlIG0uc2V0U2F2ZWRDb2xvcnNDb29raWUobyx0KX0scmVtb3ZlRnJvbUFycmF5OmZ1bmN0aW9uKHQsZSl7LTEhPT1vLmluQXJyYXkoZSx0KSYmdC5zcGxpY2Uoby5pbkFycmF5KGUsdCksMSl9LHVwZGF0ZVNhdmVkQ29sb3JzOmZ1bmN0aW9uKG8sdCxlKXttLnJlbW92ZUZyb21BcnJheSh0LG8pLHQudW5zaGlmdChvKSxtLnNhdmVDb2xvcnNUb0xvY2FsU3RvcmFnZSh0LGUpfSxhZGRUb1NhdmVkQ29sb3JzOmZ1bmN0aW9uKG8sdCxlKXtpZihwLnNob3dTYXZlZENvbG9ycyYmdm9pZCAwIT09bylpZigiIyIhPW9bMF0mJihvPSIjIitvKSxtLnVwZGF0ZVNhdmVkQ29sb3JzKG8sZikscC5zYXZlQ29sb3JzUGVyRWxlbWVudCl7dmFyIGE9dC5jb2xvcnMsbj10LmRhdGFBdHRyO20udXBkYXRlU2F2ZWRDb2xvcnMobyxhLG4pLG0udXBkYXRlU2F2ZWRDb2xvck1hcmt1cChlLGEpfWVsc2UgbS51cGRhdGVTYXZlZENvbG9yTWFya3VwKGUsZil9LHNlbGVjdEZyb21CYXNpY0NvbG9yczpmdW5jdGlvbigpe3ZhciB0PW8odGhpcykuZmluZCgic3BhbjpmaXJzdCIpLmNzcygiYmFja2dyb3VuZC1jb2xvciIpLGU9YXJndW1lbnRzWzBdLmVscyxhPWFyZ3VtZW50c1swXS5zYXZlZENvbG9yc0luZm87dD10aW55Y29sb3IodCkudG9IZXgoKSxvKGUudGhpc0VsKS52YWwodCksbyhlLnRoaXNFbCkudHJpZ2dlcigiY2hhbmdlIiksbS51cGRhdGVQcmV2aWV3KGUudGhpc0VsKSxtLmFkZFRvU2F2ZWRDb2xvcnModCxhLGUuc2F2ZWRDb2xvcnNDb250ZW50KSxtLmNsb3NlRHJvcGRvd24oZS5jb2xvclByZXZpZXdCdXR0b24sZS5jb2xvck1lbnUpfSx0YXBTcGVjdHJ1bTpmdW5jdGlvbigpe3ZhciB0PWFyZ3VtZW50c1swXS50aGlzRXZlbnQsYT1hcmd1bWVudHNbMF0uc2F2ZWRDb2xvcnNJbmZvLG49YXJndW1lbnRzWzBdLmVscyxyPWFyZ3VtZW50c1swXS5tb3N0UmVjZW50Q2xpY2s7dC5zdG9wUHJvcGFnYXRpb24oKTt2YXIgcz1vKHRoaXMpLmZpbmQoIi5oaWdobGlnaHQtYmFuZCIpLGk9bS5nZXRNb3ZlYWJsZUFyZWEocyk7ZT9tLm1vdmVIaWdobGlnaHRCYW5kKHMsaSxyKTptLm1vdmVIaWdobGlnaHRCYW5kKHMsaSx0KTt2YXIgbD1tLmNhbGN1bGF0ZUhpZ2hsaWdodGVkQ29sb3IuYXBwbHkocyxbe3R5cGU6ImJhc2ljIn1dKTttLmFkZFRvU2F2ZWRDb2xvcnMobCxhLG4uc2F2ZWRDb2xvcnNDb250ZW50KSxuLnRvdWNoSW5zdHJ1Y3Rpb25zLmh0bWwoIlByZXNzICdzZWxlY3QnIHRvIGNob29zZSB0aGlzIGNvbG9yIil9LGV4ZWN1dGVVbmxlc3NTY3JvbGxlZDpmdW5jdGlvbigpe3ZhciB0LGEsbj1hcmd1bWVudHNbMF0udGhpc0Z1bmN0aW9uLHM9YXJndW1lbnRzWzBdLnRoZXNlQXJndW1lbnRzO28odGhpcykub24ocixmdW5jdGlvbihlKXt0PW8od2luZG93KS5zY3JvbGxUb3AoKSxhPWV9KS5vbihsLGZ1bmN0aW9uKHIpe3ZhciBpPXQtbyh3aW5kb3cpLnNjcm9sbFRvcCgpO3JldHVybiBlJiZNYXRoLmFicyhpKT4wPyExOihzLnRoaXNFdmVudD1yLHMubW9zdFJlY2VudENsaWNrPWEsbi5hcHBseShvKHRoaXMpLFtzXSksdm9pZCAwKX0pfSx1cGRhdGVTYXR1cmF0aW9uU3R5bGVzOmZ1bmN0aW9uKHQsZSxhKXt2YXIgcj0oMTAwKmEpLnRvU3RyaW5nKCkrIiUiLHM9IiMiK3Rpbnljb2xvcigiaHNsKCIrZSsiLDAlLCIrcikudG9IZXgoKSxpPSIjIit0aW55Y29sb3IoImhzbCgiK2UrIiw1MCUsIityKS50b0hleCgpLGw9IiMiK3Rpbnljb2xvcigiaHNsKCIrZSsiLDEwMCUsIityKS50b0hleCgpLGQ9IiIsYz0oby5lYWNoKFsiLXdlYmtpdC1saW5lYXItZ3JhZGllbnQiLCItby1saW5lYXItZ3JhZGllbnQiXSxmdW5jdGlvbihvLHQpe2QrPSJiYWNrZ3JvdW5kLWltYWdlOiAiK3QrIihsZWZ0LCAiK3MrIiAwJSwgIitpKyIgNTAlLCAiK2wrIiAxMDAlKTsifSksInByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5ncmFkaWVudChzdGFydENvbG9yc3RyPSciK3MrIicsIGVuZENvbG9yc3RyPSciK2krIicsIEdyYWRpZW50VHlwZT0xKSIpLHA9InByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5ncmFkaWVudChzdGFydENvbG9yc3RyPSciK2krIicsIGVuZENvbG9yc3RyPSciK2wrIicsIEdyYWRpZW50VHlwZT0xKSI7aWYoZD0iYmFja2dyb3VuZC1pbWFnZTogLW1vei1saW5lYXItZ3JhZGllbnQobGVmdCBjZW50ZXIsICIrcysiIDAlLCAiK2krIiA1MCUsICIrbCsiIDEwMCUpO2JhY2tncm91bmQtaW1hZ2U6IGxpbmVhci1ncmFkaWVudCh0byByaWdodCwgIitzKyIgMCUsICIraSsiIDUwJSwgIitsKyIgMTAwJSk7IGJhY2tncm91bmQtaW1hZ2U6IC13ZWJraXQtZ3JhZGllbnQobGluZWFyLCBsZWZ0IHRvcCwgcmlnaHQgdG9wLGNvbG9yLXN0b3AoMCwgIitzKyIpLGNvbG9yLXN0b3AoMC41LCAiK2krIiksY29sb3Itc3RvcCgxLCAiK2wrIikpOyIrZCxuKXt2YXIgdT1vKHQpLmZpbmQoIi5zYXR1cmF0aW9uLXNwZWN0cnVtLTAiKSxoPW8odCkuZmluZCgiLnNhdHVyYXRpb24tc3BlY3RydW0tMSIpO3UuY3NzKCJmaWx0ZXIiLGMpLGguY3NzKCJmaWx0ZXIiLHApfWVsc2UgdC5hdHRyKCJzdHlsZSIsZCl9LHVwZGF0ZUxpZ2h0bmVzc1N0eWxlczpmdW5jdGlvbih0LGUsYSl7dmFyIHI9KDEwMCphKS50b1N0cmluZygpKyIlIixzPSIjIit0aW55Y29sb3IoImhzbCgiK2UrIiwiK3IrIiwxMDAlKSIpLnRvSGV4KCksaT0iIyIrdGlueWNvbG9yKCJoc2woIitlKyIsIityKyIsNTAlKSIpLnRvSGV4KCksbD0iIyIrdGlueWNvbG9yKCJoc2woIitlKyIsIityKyIsMCUpIikudG9IZXgoKSxkPSIiLGM9KG8uZWFjaChbIi13ZWJraXQtbGluZWFyLWdyYWRpZW50IiwiLW8tbGluZWFyLWdyYWRpZW50Il0sZnVuY3Rpb24obyx0KXtkKz0iYmFja2dyb3VuZC1pbWFnZTogIit0KyIobGVmdCwgIitzKyIgMCUsICIraSsiIDUwJSwgIitsKyIgMTAwJSk7In0pLCJwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuZ3JhZGllbnQoc3RhcnRDb2xvcnN0cj0nIitzKyInLCBlbmRDb2xvcnN0cj0nIitpKyInLCBHcmFkaWVudFR5cGU9MSkiKSxwPSJwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuZ3JhZGllbnQoc3RhcnRDb2xvcnN0cj0nIitpKyInLCBlbmRDb2xvcnN0cj0nIitsKyInLCBHcmFkaWVudFR5cGU9MSkiO2lmKGQ9ImJhY2tncm91bmQtaW1hZ2U6IC1tb3otbGluZWFyLWdyYWRpZW50KGxlZnQgY2VudGVyLCAiK3MrIiAwJSwgIitpKyIgNTAlLCAiK2wrIiAxMDAlKTsgYmFja2dyb3VuZC1pbWFnZTogbGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCAiK3MrIiAwJSwgIitpKyIgNTAlLCAiK2wrIiAxMDAlKTsgYmFja2dyb3VuZC1pbWFnZTogLXdlYmtpdC1ncmFkaWVudChsaW5lYXIsIGxlZnQgdG9wLCByaWdodCB0b3AsIGNvbG9yLXN0b3AoMCwgIitzKyIpLCBjb2xvci1zdG9wKDAuNSwgIitpKyIpLCBjb2xvci1zdG9wKDEsICIrbCsiKSk7ICIrZCxuKXt2YXIgdT1vKHQpLmZpbmQoIi5saWdodG5lc3Mtc3BlY3RydW0tMCIpLGg9byh0KS5maW5kKCIubGlnaHRuZXNzLXNwZWN0cnVtLTEiKTt1LmNzcygiZmlsdGVyIixjKSxoLmNzcygiZmlsdGVyIixwKX1lbHNlIHQuYXR0cigic3R5bGUiLGQpfSx1cGRhdGVIdWVTdHlsZXM6ZnVuY3Rpb24odCxlLGEpe3ZhciByPSgxMDAqZSkudG9TdHJpbmcoKSsiJSIscz0oMTAwKmEpLnRvU3RyaW5nKCkrIiUiLGk9IiMiK3Rpbnljb2xvcigiaHNsKDAsIityKyIsIitzKyIpIikudG9IZXgoKSxsPSIjIit0aW55Y29sb3IoImhzbCg2MCwiK3IrIiwiK3MrIikiKS50b0hleCgpLGQ9IiMiK3Rpbnljb2xvcigiaHNsKDEyMCwiK3IrIiwiK3MrIikiKS50b0hleCgpLGM9IiMiK3Rpbnljb2xvcigiaHNsKDE4MCwiK3IrIiwiK3MrIikiKS50b0hleCgpLHA9IiMiK3Rpbnljb2xvcigiaHNsKDI0MCwiK3IrIiwiK3MrIikiKS50b0hleCgpLHU9IiMiK3Rpbnljb2xvcigiaHNsKDMwMCwiK3IrIiwiK3MrIikiKS50b0hleCgpLGg9IiMiK3Rpbnljb2xvcigiaHNsKDAsIityKyIsIitzKyIpIikudG9IZXgoKSxnPSJwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuZ3JhZGllbnQoc3RhcnRDb2xvcnN0cj0nIitpKyInLCBlbmRDb2xvcnN0cj0nIitsKyInLCBHcmFkaWVudFR5cGU9MSkiLHY9InByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5ncmFkaWVudChzdGFydENvbG9yc3RyPSciK2wrIicsIGVuZENvbG9yc3RyPSciK2QrIicsIEdyYWRpZW50VHlwZT0xKSIsZj0icHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0LmdyYWRpZW50KHN0YXJ0Q29sb3JzdHI9JyIrZCsiJywgZW5kQ29sb3JzdHI9JyIrYysiJywgR3JhZGllbnRUeXBlPTEpIixDPSJwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuZ3JhZGllbnQoc3RhcnRDb2xvcnN0cj0nIitjKyInLCBlbmRDb2xvcnN0cj0nIitwKyInLCBHcmFkaWVudFR5cGU9MSkiLG09InByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5ncmFkaWVudChzdGFydENvbG9yc3RyPSciK3ArIicsIGVuZENvbG9yc3RyPSciK3UrIicsIEdyYWRpZW50VHlwZT0xKSIsYj0icHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0LmdyYWRpZW50KHN0YXJ0Q29sb3JzdHI9JyIrdSsiJywgZW5kQ29sb3JzdHI9JyIraCsiJywgR3JhZGllbnRUeXBlPTEpIix3PSIiO28uZWFjaChbIi13ZWJraXQtbGluZWFyLWdyYWRpZW50IiwiLW8tbGluZWFyLWdyYWRpZW50Il0sZnVuY3Rpb24obyx0KXt3Kz0iYmFja2dyb3VuZC1pbWFnZTogIit0KyIobGVmdCwgIitpKyIgMCUsICIrbCsiIDE3JSwgIitkKyIgMjQlLCAiK2MrIiA1MSUsICIrcCsiIDY4JSwgIit1KyIgODUlLCAiK2grIiAxMDAlKTsifSk7aWYodys9ImJhY2tncm91bmQtaW1hZ2U6IC13ZWJraXQtZ3JhZGllbnQobGluZWFyLCBsZWZ0IHRvcCwgcmlnaHQgdG9wLGNvbG9yLXN0b3AoMCUsICIraSsiKSxjb2xvci1zdG9wKDE3JSwgIitsKyIpLGNvbG9yLXN0b3AoMzQlLCAiK2QrIiksY29sb3Itc3RvcCg1MSUsICIrYysiKSxjb2xvci1zdG9wKDY4JSwgIitwKyIpLGNvbG9yLXN0b3AoODUlLCAiK3UrIiksY29sb3Itc3RvcCgxMDAlLCAiK2grIikpO2JhY2tncm91bmQtaW1hZ2U6IGxpbmVhci1ncmFkaWVudCh0byByaWdodCwgIitpKyIgMCUsICIrbCsiIDE3JSwgIitkKyIgMjQlLCIrYysiIDUxJSwiK3ArIiA2OCUsIit1KyIgODUlLCIraCsiIDEwMCUpOyBiYWNrZ3JvdW5kLWltYWdlOiAtbW96LWxpbmVhci1ncmFkaWVudChsZWZ0IGNlbnRlciwgIitpKyIgMCUsICIrbCsiIDE3JSwgIitkKyIgMjQlLCAiK2MrIiA1MSUsICIrcCsiIDY4JSwgIit1KyIgODUlLCAiK2grIiAxMDAlKTsiLG4pe3ZhciBTPW8odCkuZmluZCgiLmh1ZS1zcGVjdHJ1bS0wIikseT1vKHQpLmZpbmQoIi5odWUtc3BlY3RydW0tMSIpLGs9byh0KS5maW5kKCIuaHVlLXNwZWN0cnVtLTIiKSx4PW8odCkuZmluZCgiLmh1ZS1zcGVjdHJ1bS0zIiksSD1vKHQpLmZpbmQoIi5odWUtc3BlY3RydW0tNCIpLEE9byh0KS5maW5kKCIuaHVlLXNwZWN0cnVtLTUiKTtTLmNzcygiZmlsdGVyIixnKSx5LmNzcygiZmlsdGVyIix2KSxrLmNzcygiZmlsdGVyIixmKSx4LmNzcygiZmlsdGVyIixDKSxILmNzcygiZmlsdGVyIixtKSxBLmNzcygiZmlsdGVyIixiKX1lbHNlIHQuYXR0cigic3R5bGUiLHcpfSxnZXRIaWdobGlnaHRlZEh1ZTpmdW5jdGlvbigpe3ZhciB0PW8odGhpcyksYT10Lm91dGVyV2lkdGgoKSxuPWEvMixyPXBhcnNlSW50KHQuY3NzKCJsZWZ0IiksMTApK24scz10LnBhcmVudHMoIi5hZHZhbmNlZC1saXN0IiksaT1zLmZpbmQoIi5jb2xvci1wcmV2aWV3IiksbD1zLmZpbmQoIi5zcGVjdHJ1bS1saWdodG5lc3MiKSxkPXMuZmluZCgiLnNwZWN0cnVtLXNhdHVyYXRpb24iKSxjPXBhcnNlSW50KHMuZmluZCgiLmNvbG9yLWJveCIpLmZpcnN0KCkud2lkdGgoKSwxMCkscD1zLmZpbmQoIi5odWUtdmFsdWUiKSx1PWFyZ3VtZW50c1swXS5sLGg9YXJndW1lbnRzWzBdLnMsZz0oMTAwKmgpLnRvU3RyaW5nKCkrIiUiLHY9KDEwMCp1KS50b1N0cmluZygpKyIlIjswPT09YyYmKGM9ZT8xNjA6MzAwKTt2YXIgZj1NYXRoLmZsb29yKHIvYyozNjApLEM9ImhzbCgiK2YrIiwiK2crIiwiK3YrIikiO3JldHVybiBDPSIjIit0aW55Y29sb3IoQykudG9IZXgoKSxpLmNzcygiYmFja2dyb3VuZC1jb2xvciIsQykscC50ZXh0KGYpLG0udXBkYXRlTGlnaHRuZXNzU3R5bGVzKGwsZixoKSxtLnVwZGF0ZVNhdHVyYXRpb25TdHlsZXMoZCxmLHUpLGZ9LGdldEhpZ2hsaWdodGVkU2F0dXJhdGlvbjpmdW5jdGlvbigpe3ZhciB0PW8odGhpcyksYT10Lm91dGVyV2lkdGgoKSxuPWEvMixyPXBhcnNlSW50KHQuY3NzKCJsZWZ0IiksMTApK24scz10LnBhcmVudHMoIi5hZHZhbmNlZC1saXN0IiksaT1zLmZpbmQoIi5jb2xvci1wcmV2aWV3IiksbD1zLmZpbmQoIi5zcGVjdHJ1bS1saWdodG5lc3MiKSxkPXMuZmluZCgiLnNwZWN0cnVtLWh1ZSIpLGM9cy5maW5kKCIuc2F0dXJhdGlvbi12YWx1ZSIpLHA9cGFyc2VJbnQocy5maW5kKCIuY29sb3ItYm94IikuZmlyc3QoKS53aWR0aCgpLDEwKSx1PWFyZ3VtZW50c1swXS5sLGg9KDEwMCp1KS50b1N0cmluZygpKyIlIixnPWFyZ3VtZW50c1swXS5oOzA9PT1wJiYocD1lPzE2MDozMDApO3ZhciB2PXIvcCxmPU1hdGgucm91bmQoMTAwKnYpLnRvU3RyaW5nKCkrIiUiLEM9ImhzbCgiK2crIiwiK2YrIiwiK2grIikiO3JldHVybiBDPSIjIit0aW55Y29sb3IoQykudG9IZXgoKSxpLmNzcygiYmFja2dyb3VuZC1jb2xvciIsQyksYy50ZXh0KGYpLG0udXBkYXRlTGlnaHRuZXNzU3R5bGVzKGwsZyx2KSxtLnVwZGF0ZUh1ZVN0eWxlcyhkLHYsdSksdn0sdXBkYXRlQWR2YW5jZWRJbnN0cnVjdGlvbnM6ZnVuY3Rpb24obyl7by5odG1sKCJQcmVzcyB0aGUgY29sb3IgcHJldmlldyB0byBjaG9vc2UgdGhpcyBjb2xvciIpfX07cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbih0KXttLmluaXRpYWxpemUuYXBwbHkodGhpcyxbdF0pO3ZhciBlLG4scj17dGhpc0VsOm8odGhpcyksdGhpc1dyYXBwZXI6byh0aGlzKS5wYXJlbnQoKSxjb2xvclRleHRJbnB1dDpvKHRoaXMpLmZpbmQoImlucHV0IiksY29sb3JNZW51TGlua3M6byh0aGlzKS5wYXJlbnQoKS5maW5kKCIuY29sb3ItbWVudSBsaSBhIiksY29sb3JQcmV2aWV3QnV0dG9uOm8odGhpcykucGFyZW50KCkuZmluZCgiLmlucHV0LWdyb3VwLWJ0biIpLGNvbG9yTWVudTpvKHRoaXMpLnBhcmVudCgpLmZpbmQoIi5jb2xvci1tZW51IiksY29sb3JTcGVjdHJ1bXM6byh0aGlzKS5wYXJlbnQoKS5maW5kKCIuY29sb3ItYm94IiksYmFzaWNTcGVjdHJ1bXM6byh0aGlzKS5wYXJlbnQoKS5maW5kKCIuYmFzaWNDb2xvcnMtY29udGVudCAuY29sb3ItYm94IiksdG91Y2hJbnN0cnVjdGlvbnM6byh0aGlzKS5wYXJlbnQoKS5maW5kKCIuY29sb3ItbWVudS1pbnN0cnVjdGlvbnMiKSxhZHZhbmNlZEluc3RydWN0aW9uczpvKHRoaXMpLnBhcmVudCgpLmZpbmQoIi5hZHZhbmNlZC1pbnN0cnVjdGlvbnMiKSxoaWdobGlnaHRCYW5kczpvKHRoaXMpLnBhcmVudCgpLmZpbmQoIi5oaWdobGlnaHQtYmFuZCIpLGJhc2ljSGlnaGxpZ2h0QmFuZHM6byh0aGlzKS5wYXJlbnQoKS5maW5kKCIuYmFzaWNDb2xvcnMtY29udGVudCAuaGlnaGxpZ2h0LWJhbmQiKX07aWYodSYmKHIudGFicz1yLnRoaXNXcmFwcGVyLmZpbmQoIi50YWIiKSkscC5zaG93U2F2ZWRDb2xvcnMmJihyLnNhdmVkQ29sb3JzQ29udGVudD1yLnRoaXNXcmFwcGVyLmZpbmQoIi5zYXZlZENvbG9ycy1jb250ZW50IikscC5zYXZlQ29sb3JzUGVyRWxlbWVudCkpaWYobj17Y29sb3JzOltdLGRhdGFPYmo6byh0aGlzKS5kYXRhKCl9LG8uZWFjaChuLmRhdGFPYmosZnVuY3Rpb24obyl7bi5kYXRhQXR0cj1vfSksYSYmbG9jYWxTdG9yYWdlWyJwaWNrQUNvbG9yU2F2ZWRDb2xvcnMtIituLmRhdGFBdHRyXSluLmNvbG9ycz1KU09OLnBhcnNlKGxvY2FsU3RvcmFnZVsicGlja0FDb2xvclNhdmVkQ29sb3JzLSIrbi5kYXRhQXR0cl0pO2Vsc2UgaWYoZG9jdW1lbnQuY29va2llLm1hdGNoKCJwaWNrQUNvbG9yU2F2ZWRDb2xvcnMtIituLmRhdGFBdHRyKSlmb3IodmFyIHM9ZG9jdW1lbnQuY29va2llLnNwbGl0KCI7IiksaD0wO2g8cy5sZW5ndGg7aCsrKXNbaF0ubWF0Y2gobi5kYXRhQXR0cikmJihuLmNvbG9ycz1zW2hdLnNwbGl0KCI9IilbMV0uc3BsaXQoIiwiKSk7ZWxzZSBuLmNvbG9ycz1mO3Auc2hvd0FkdmFuY2VkJiYoZT17aDowLHM6MSxsOi41fSxyLmFkdmFuY2VkU3BlY3RydW1zPXIudGhpc1dyYXBwZXIuZmluZCgiLmFkdmFuY2VkLWxpc3QiKS5maW5kKCIuY29sb3ItYm94Iiksci5hZHZhbmNlZEhpZ2hsaWdodEJhbmRzPXIudGhpc1dyYXBwZXIuZmluZCgiLmFkdmFuY2VkLWxpc3QiKS5maW5kKCIuaGlnaGxpZ2h0LWJhbmQiKSxyLmh1ZVNwZWN0cnVtPXIudGhpc1dyYXBwZXIuZmluZCgiLnNwZWN0cnVtLWh1ZSIpLHIubGlnaHRuZXNzU3BlY3RydW09ci50aGlzV3JhcHBlci5maW5kKCIuc3BlY3RydW0tbGlnaHRuZXNzIiksci5zYXR1cmF0aW9uU3BlY3RydW09ci50aGlzV3JhcHBlci5maW5kKCIuc3BlY3RydW0tc2F0dXJhdGlvbiIpLHIuaHVlSGlnaGxpZ2h0QmFuZD1yLnRoaXNXcmFwcGVyLmZpbmQoIi5zcGVjdHJ1bS1odWUgLmhpZ2hsaWdodC1iYW5kIiksci5saWdodG5lc3NIaWdobGlnaHRCYW5kPXIudGhpc1dyYXBwZXIuZmluZCgiLnNwZWN0cnVtLWxpZ2h0bmVzcyAuaGlnaGxpZ2h0LWJhbmQiKSxyLnNhdHVyYXRpb25IaWdobGlnaHRCYW5kPXIudGhpc1dyYXBwZXIuZmluZCgiLnNwZWN0cnVtLXNhdHVyYXRpb24gLmhpZ2hsaWdodC1iYW5kIiksci5hZHZhbmNlZFByZXZpZXc9ci50aGlzV3JhcHBlci5maW5kKCIuYWR2YW5jZWQtY29udGVudCAuY29sb3ItcHJldmlldyIpKSxtLmFkZFRvU2F2ZWRDb2xvcnMoZy5kZWZhdWx0Q29sb3IsbixyLnNhdmVkQ29sb3JzQ29udGVudCksbS51cGRhdGVQcmV2aWV3KHIudGhpc0VsKSxyLnRoaXNFbC5mb2N1cyhmdW5jdGlvbigpe3ZhciB0PW8odGhpcyk7Zy50eXBlZENvbG9yPXQudmFsKCkscC5hbGxvd0JsYW5rfHx0LnZhbCgiIiksbS50b2dnbGVEcm9wZG93bihyLmNvbG9yUHJldmlld0J1dHRvbixyLkNvbG9yTWVudSl9KS5ibHVyKGZ1bmN0aW9uKCl7dmFyIHQ9byh0aGlzKTtnLm5ld1ZhbHVlPXQudmFsKCksZy5uZXdWYWx1ZS5tYXRjaCgvXlxzKyR8XiQvKT9wLmFsbG93Qmxhbmt8fHQudmFsKGcudHlwZWRDb2xvcik6KGcubmV3VmFsdWU9dGlueWNvbG9yKGcubmV3VmFsdWUpLnRvSGV4KCksdC52YWwoZy5uZXdWYWx1ZSksbS5hZGRUb1NhdmVkQ29sb3JzKGcubmV3VmFsdWUsbixyLnNhdmVkQ29sb3JzQ29udGVudCkpLG0udG9nZ2xlRHJvcGRvd24oci5jb2xvclByZXZpZXdCdXR0b24sci5Db2xvck1lbnUpLG0udXBkYXRlUHJldmlldyh0KX0pLG0uZXhlY3V0ZVVubGVzc1Njcm9sbGVkLmFwcGx5KHIuY29sb3JQcmV2aWV3QnV0dG9uLFt7dGhpc0Z1bmN0aW9uOm0ucHJlc3NQcmV2aWV3QnV0dG9uLHRoZXNlQXJndW1lbnRzOnt9fV0pLG0uZXhlY3V0ZVVubGVzc1Njcm9sbGVkLmFwcGx5KG8oZG9jdW1lbnQpLFt7dGhpc0Z1bmN0aW9uOm0uY2xvc2VEcm9wZG93bklmT3Blbix0aGVzZUFyZ3VtZW50czp7YnV0dG9uOnIuY29sb3JQcmV2aWV3QnV0dG9uLG1lbnU6ci5jb2xvck1lbnV9fV0pLHIuY29sb3JNZW51Lm9uKGwsZnVuY3Rpb24obyl7by5zdG9wUHJvcGFnYXRpb24oKX0pLHIudGhpc0VsLm9uKGwsZnVuY3Rpb24obyl7by5zdG9wUHJvcGFnYXRpb24oKX0pLG0uZXhlY3V0ZVVubGVzc1Njcm9sbGVkLmFwcGx5KHIuY29sb3JNZW51TGlua3MsW3t0aGlzRnVuY3Rpb246bS5zZWxlY3RGcm9tQmFzaWNDb2xvcnMsdGhlc2VBcmd1bWVudHM6e2VsczpyLHNhdmVkQ29sb3JzSW5mbzpufX1dKSx1JiZtLnRhYmJhYmxlLmFwcGx5KHIudGFicyksKHAuc2hvd1NwZWN0cnVtfHxwLnNob3dBZHZhbmNlZCkmJm0uaG9yaXpvbnRhbGx5RHJhZ2dhYmxlLmFwcGx5KHIuaGlnaGxpZ2h0QmFuZHMpLHAuc2hvd1NwZWN0cnVtJiYobS5leGVjdXRlVW5sZXNzU2Nyb2xsZWQuYXBwbHkoci5iYXNpY1NwZWN0cnVtcyxbe3RoaXNGdW5jdGlvbjptLnRhcFNwZWN0cnVtLHRoZXNlQXJndW1lbnRzOntzYXZlZENvbG9yc0luZm86bixlbHM6cn19XSksbyhyLmJhc2ljSGlnaGxpZ2h0QmFuZHMpLm9uKGQsZnVuY3Rpb24obyl7by50YXJnZXQ7bS5jYWxjdWxhdGVIaWdobGlnaHRlZENvbG9yLmFwcGx5KHRoaXMsW3t0eXBlOiJiYXNpYyJ9XSl9KS5vbihjLGZ1bmN0aW9uKG8pe3ZhciB0PW8uZGVsZWdhdGVUYXJnZXQsZT1tLmNhbGN1bGF0ZUhpZ2hsaWdodGVkQ29sb3IuYXBwbHkodCxbe3R5cGU6ImJhc2ljIn1dKTttLmFkZFRvU2F2ZWRDb2xvcnMoZSxuLHIuc2F2ZWRDb2xvcnNDb250ZW50KX0pKSxwLnNob3dBZHZhbmNlZCYmKG8oci5odWVIaWdobGlnaHRCYW5kKS5vbihkLGZ1bmN0aW9uKG8pe2UuaD1tLmdldEhpZ2hsaWdodGVkSHVlLmFwcGx5KHRoaXMsW2VdKX0pLG8oci5saWdodG5lc3NIaWdobGlnaHRCYW5kKS5vbihkLGZ1bmN0aW9uKCl7bS5jYWxjdWxhdGVIaWdobGlnaHRlZENvbG9yLmFwcGx5KHRoaXMsW3t0eXBlOiJhZHZhbmNlZCIsaHNsOmV9XSl9KS5vbihpLGZ1bmN0aW9uKCl7ZS5sPW0uY2FsY3VsYXRlSGlnaGxpZ2h0ZWRDb2xvci5hcHBseSh0aGlzLFt7dHlwZToiYWR2YW5jZWQiLGhzbDplfV0pfSksbyhyLnNhdHVyYXRpb25IaWdobGlnaHRCYW5kKS5vbihkLGZ1bmN0aW9uKCl7bS5nZXRIaWdobGlnaHRlZFNhdHVyYXRpb24uYXBwbHkodGhpcyxbZV0pfSkub24oYyxmdW5jdGlvbigpe2Uucz1tLmdldEhpZ2hsaWdodGVkU2F0dXJhdGlvbi5hcHBseSh0aGlzLFtlXSl9KSxvKHIuYWR2YW5jZWRIaWdobGlnaHRCYW5kKS5vbihjLGZ1bmN0aW9uKCl7bS51cGRhdGVBZHZhbmNlZEluc3RydWN0aW9ucyhyLmFkdmFuY2VkSW5zdHJ1Y3Rpb25zKX0pLG8oci5saWdodG5lc3NTcGVjdHJ1bSkuY2xpY2soZnVuY3Rpb24odCl7dC5zdG9wUHJvcGFnYXRpb24oKTt2YXIgYT1vKHRoaXMpLmZpbmQoIi5oaWdobGlnaHQtYmFuZCIpLG49bS5nZXRNb3ZlYWJsZUFyZWEoYSk7bS5tb3ZlSGlnaGxpZ2h0QmFuZChhLG4sdCksZS5sPW0uY2FsY3VsYXRlSGlnaGxpZ2h0ZWRDb2xvci5hcHBseShhLFt7dHlwZToiYWR2YW5jZWQiLGhzbDplfV0pfSksbyhyLmh1ZVNwZWN0cnVtKS5jbGljayhmdW5jdGlvbih0KXt0LnN0b3BQcm9wYWdhdGlvbigpO3ZhciBhPW8odGhpcykuZmluZCgiLmhpZ2hsaWdodC1iYW5kIiksbj1tLmdldE1vdmVhYmxlQXJlYShhKTttLm1vdmVIaWdobGlnaHRCYW5kKGEsbix0KSxlLmg9bS5nZXRIaWdobGlnaHRlZEh1ZS5hcHBseShhLFtlXSl9KSxvKHIuc2F0dXJhdGlvblNwZWN0cnVtKS5jbGljayhmdW5jdGlvbih0KXt0LnN0b3BQcm9wYWdhdGlvbigpO3ZhciBhPW8odGhpcykuZmluZCgiLmhpZ2hsaWdodC1iYW5kIiksbj1tLmdldE1vdmVhYmxlQXJlYShhKTttLm1vdmVIaWdobGlnaHRCYW5kKGEsbix0KSxlLnM9bS5nZXRIaWdobGlnaHRlZFNhdHVyYXRpb24uYXBwbHkoYSxbZV0pfSksbyhyLmFkdmFuY2VkU3BlY3RydW1zKS5jbGljayhmdW5jdGlvbigpe20udXBkYXRlQWR2YW5jZWRJbnN0cnVjdGlvbnMoci5hZHZhbmNlZEluc3RydWN0aW9ucyl9KSxvKHIuYWR2YW5jZWRQcmV2aWV3KS5jbGljayhmdW5jdGlvbigpe3ZhciB0PXRpbnljb2xvcihvKHRoaXMpLmNzcygiYmFja2dyb3VuZC1jb2xvciIpKS50b0hleCgpO28oci50aGlzRWwpLnZhbCh0KSxvKHIudGhpc0VsKS50cmlnZ2VyKCJjaGFuZ2UiKSxtLnVwZGF0ZVByZXZpZXcoci50aGlzRWwpLG0uYWRkVG9TYXZlZENvbG9ycyh0LG4sci5zYXZlZENvbG9yc0NvbnRlbnQpLG0uY2xvc2VEcm9wZG93bihyLmNvbG9yUHJldmlld0J1dHRvbixyLmNvbG9yTWVudSl9KSkscC5zaG93U2F2ZWRDb2xvcnMmJihvKHIuc2F2ZWRDb2xvcnNDb250ZW50KS5jbGljayhmdW5jdGlvbih0KXt2YXIgZT1vKHQudGFyZ2V0KTtpZihlLmlzKCJTUEFOIil8fGUuaXMoIkEiKSl7dmFyIGE9ZS5pcygiU1BBTiIpP2UucGFyZW50KCkuYXR0cigiY2xhc3MiKS5zcGxpdCgiIyIpWzFdOmUuYXR0cigiY2xhc3MiKS5zcGxpdCgiIyIpWzFdO28oci50aGlzRWwpLnZhbChhKSxvKHIudGhpc0VsKS50cmlnZ2VyKCJjaGFuZ2UiKSxtLnVwZGF0ZVByZXZpZXcoci50aGlzRWwpLG0uY2xvc2VEcm9wZG93bihyLmNvbG9yUHJldmlld0J1dHRvbixyLmNvbG9yTWVudSksbS5hZGRUb1NhdmVkQ29sb3JzKGEsbixyLnNhdmVkQ29sb3JzQ29udGVudCl9fSkscC5zYXZlQ29sb3JzUGVyRWxlbWVudD9wLnNhdmVDb2xvcnNQZXJFbGVtZW50JiZtLnVwZGF0ZVNhdmVkQ29sb3JNYXJrdXAoci5zYXZlZENvbG9yc0NvbnRlbnQsbi5jb2xvcnMpOm0udXBkYXRlU2F2ZWRDb2xvck1hcmt1cChyLnNhdmVkQ29sb3JzQ29udGVudCxmKSl9KX19KGpRdWVyeSk7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDI0LzEwLzIwMTYuCiAqLwoKd2luZG93LkZvcm0gPSB3aW5kb3cuRm9ybSB8fCB7fTsKCkZvcm0ucnRlID0gRm9ybS5ydGUgfHwge307CgooZnVuY3Rpb24gKG5zKSB7CgogICAgdmFyIGxvY2FsZSA9ICJlbiI7CgogICAgdmFyIEkxOG4gPSBucy5JMThuID0ge307CgogICAgSTE4bi5zZXRMb2NhbGUgPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUpIHsKICAgICAgICAgICAgaWYgKHZhbHVlLmluZGV4T2YoIi0iKSA+IC0xKSB7CiAgICAgICAgICAgICAgICB2YXIgc3BsaXRMb2NhbGUgPSB2YWx1ZS5zcGxpdCgiLSIpOwogICAgICAgICAgICAgICAgdmFsdWUgPSBzcGxpdExvY2FsZVswXS50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICAgICAgaWYgKHNwbGl0TG9jYWxlLmxlbmd0aCA+IDEpIHsKICAgICAgICAgICAgICAgICAgICB2YWx1ZSArPSBzcGxpdExvY2FsZVsxXS50b1VwcGVyQ2FzZSgpOyAgLy8gaWYgbG9jYWxlIGhhcyBjb3VudHJ5IGluY2x1ZGUgdGhhdAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGxvY2FsZSA9IHZhbHVlOwogICAgICAgIH0KICAgIH07CgogICAgSTE4bi5nZXQgPSBmdW5jdGlvbiAoc3RyLCBzbmlwcGV0cykgewogICAgICAgIGlmICghc3RyKSB7CiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9CiAgICAgICAgdmFyIGxvY2FsZUZpbGUgPSBJMThuW2xvY2FsZV0gfHwgSTE4bi5lbjsKICAgICAgICB2YXIgc3RyaW5ncyA9IGxvY2FsZUZpbGUuc3RyaW5ncyB8fCB7fTsKICAgICAgICBpZiAoc3RyaW5ncy5oYXNPd25Qcm9wZXJ0eShzdHIpKSB7CiAgICAgICAgICAgIHN0ciA9IHN0cmluZ3Nbc3RyXTsKICAgICAgICB9CiAgICAgICAgaWYgKHNuaXBwZXRzICYmIHNuaXBwZXRzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgdmFyIHBhdHRlcm4gPSAveyhcZCspfS9nOwogICAgICAgICAgICB2YXIgcmVzdWx0ID0gcGF0dGVybi5leGVjKHN0cik7CiAgICAgICAgICAgIHdoaWxlIChyZXN1bHQpIHsKICAgICAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHJlc3VsdFswXSwgc25pcHBldHNbcmVzdWx0WzFdXSk7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBwYXR0ZXJuLmV4ZWMoc3RyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RyOwogICAgfTsKfSkoRm9ybS5ydGUpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTYuIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKgogKiBDcmVhdGVkIGJ5IHJhbW5hbmkgb24gMjQvMTAvMjAxNi4KICovCgooZnVuY3Rpb24gKEkxOG4pIHsKCiAgICB2YXIgZW4gPSBJMThuLmVuID0ge307CgogICAgZW4uc3RyaW5ncyA9IHsKICAgICAgICAiVW5kbyIgOiAiVW5kbyIsCiAgICAgICAgIlJlZG8iIDogIlJlZG8iLAogICAgICAgICJCb2xkIiA6ICJCb2xkIiwKICAgICAgICAiSXRhbGljIiA6ICJJdGFsaWMiLAogICAgICAgICJVbmRlcmxpbmUiIDogIlVuZGVybGluZSIsCiAgICAgICAgIlN1cGVyLXNjcmlwdCIgOiAiU3VwZXItc2NyaXB0IiwKICAgICAgICAiU3ViLXNjcmlwdCIgOiAiU3ViLXNjcmlwdCIsCiAgICAgICAgIlRleHQgQ29sb3IiIDogIlRleHQgQ29sb3IiLAogICAgICAgICJIaWdobGlnaHQgQ29sb3IiIDogIkhpZ2hsaWdodCBDb2xvciIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICJGb250IEZhbWlseSIsCiAgICAgICAgIkZvbnQgU2l6ZSIgOiAiRm9udCBTaXplIiwKICAgICAgICAiTGluZSBIZWlnaHQiIDogIkxpbmUgSGVpZ2h0IiwKICAgICAgICAiTGV0dGVyIFNwYWNpbmciIDogIkxldHRlciBTcGFjaW5nIiwKICAgICAgICAiUGFyYWdyYXBoIEZvcm1hdCIgOiAiUGFyYWdyYXBoIEZvcm1hdCIsCiAgICAgICAgIkp1c3RpZnkgTGVmdCIgOiAiSnVzdGlmeSBMZWZ0IiwKICAgICAgICAiSnVzdGlmeSBDZW50ZXIiIDogIkp1c3RpZnkgQ2VudGVyIiwKICAgICAgICAiSnVzdGlmeSBGdWxsIiA6ICJKdXN0aWZ5IEZ1bGwiLAogICAgICAgICJKdXN0aWZ5IFJpZ2h0IiA6ICJKdXN0aWZ5IFJpZ2h0IiwKICAgICAgICAiTWFyZ2luIExlZnQiIDogIk1hcmdpbiBMZWZ0IiwKICAgICAgICAiTWFyZ2luIFJpZ2h0IiA6ICJNYXJnaW4gUmlnaHQiLAogICAgICAgICJNYXJnaW4gVG9wIiA6ICJNYXJnaW4gVG9wIiwKICAgICAgICAiTWFyZ2luIEJvdHRvbSIgOiAiTWFyZ2luIEJvdHRvbSIsCiAgICAgICAgIkJ1bGxldGVkIExpc3QiIDogIkJ1bGxldGVkIExpc3QiLAogICAgICAgICJOdW1iZXJlZCBMaXN0IiA6ICJOdW1iZXJlZCBMaXN0IiwKICAgICAgICAiVXBwZXItY2FzZSBBbHBoYWJldCBMaXN0IiA6ICJVcHBlci1jYXNlIEFscGhhYmV0IExpc3QiLAogICAgICAgICJMb3dlci1jYXNlIEFscGhhYmV0IExpc3QiIDogIkxvd2VyLWNhc2UgQWxwaGFiZXQgTGlzdCIsCiAgICAgICAgIlVwcGVyLWNhc2UgUm9tYW4gTGlzdCIgOiAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiwKICAgICAgICAiTG93ZXItY2FzZSBSb21hbiBMaXN0IiA6ICJMb3dlci1jYXNlIFJvbWFuIExpc3QiLAogICAgICAgICJJbmRlbnQiIDogIkluZGVudCIsCiAgICAgICAgIk91dGRlbnQiIDogIk91dGRlbnQiLAogICAgICAgICJGaW5kICYgUmVwbGFjZSIgOiAiRmluZCAmIFJlcGxhY2UiLAogICAgICAgICJJbnNlcnQgTGluayIgOiAiSW5zZXJ0IExpbmsiLAogICAgICAgICJGaW5kIiA6ICJGaW5kIiwKICAgICAgICAiUmVwbGFjZSIgOiAiUmVwbGFjZSIsCiAgICAgICAgIlJlcGxhY2UgYWxsIiA6ICJSZXBsYWNlIGFsbCIsCiAgICAgICAgIk1hdGNoIGNhc2UiIDogIk1hdGNoIGNhc2UiLAogICAgICAgICJXaG9sZSB3b3JkIiA6ICJXaG9sZSB3b3JkIiwKICAgICAgICAiUmVnIEV4IiA6ICJSZWcgRXgiLAogICAgICAgICJJbmZvIiA6ICJJbmZvIiwKICAgICAgICAiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIgOiAiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIsCiAgICAgICAgIk1hdGNoIE5vdCBGb3VuZCIgOiAiTWF0Y2ggTm90IEZvdW5kIiwKICAgICAgICAiezB9IG1hdGNoZXMgcmVwbGFjZWQiIDogInswfSBtYXRjaGVzIHJlcGxhY2VkIiwKICAgICAgICAiVGltZXMgTmV3IFJvbWFuIiA6ICJUaW1lcyBOZXcgUm9tYW4iLAogICAgICAgICJBcmlhbCIgOiAiQXJpYWwiLAogICAgICAgICJDb3VyaWVyIiA6ICJDb3VyaWVyIiwKICAgICAgICAiQ291cmllciBOZXciIDogIkNvdXJpZXIgTmV3IiwKICAgICAgICAiR2VuZXZhIiA6ICJHZW5ldmEiLAogICAgICAgICJHZW9yZ2lhIiA6ICJHZW9yZ2lhIiwKICAgICAgICAiSGVsdmV0aWNhIiA6ICJIZWx2ZXRpY2EiLAogICAgICAgICJUYWhvbWEiIDogIlRhaG9tYSIsCiAgICAgICAgIlRpbWVzIiA6ICJUaW1lcyIsCiAgICAgICAgIlZlcmRhbmEiIDogIlZlcmRhbmEiLAogICAgICAgICJOb25lIiA6ICJOb25lIiwKICAgICAgICAiSGVhZGVyIDEiIDogIkhlYWRlciAxIiwKICAgICAgICAiSGVhZGVyIDIiIDogIkhlYWRlciAyIiwKICAgICAgICAiSGVhZGVyIDMiIDogIkhlYWRlciAzIiwKICAgICAgICAiSGVhZGVyIDQiIDogIkhlYWRlciA0IiwKICAgICAgICAiSGVhZGVyIDUiIDogIkhlYWRlciA1IiwKICAgICAgICAiSGVhZGVyIDYiIDogIkhlYWRlciA2IiwKICAgICAgICAiU2VsZWN0IiA6ICJTZWxlY3QiLAogICAgICAgICJCYXNpYyBWaWV3IiA6ICJCYXNpYyBWaWV3IiwKICAgICAgICAiRnVsbFNjcmVlbiIgOiAiRnVsbFNjcmVlbiIsCiAgICAgICAgIkV4cGFuZCIgOiAiRXhwYW5kIiwKICAgICAgICAiQ29sbGFwc2UiIDogIkNvbGxhcHNlIiwKICAgICAgICAiTGlzdCBUeXBlIiA6ICJMaXN0IFR5cGUiLAogICAgICAgICJVUkwiIDogIlVSTCIsCiAgICAgICAgIkFsdCBUZXh0IiA6ICJBbHQgVGV4dCIsCiAgICAgICAgIk9wZW4gaW4gbmV3IHBhZ2UiIDogIk9wZW4gaW4gbmV3IHBhZ2UiCiAgICB9Owp9KShGb3JtLnJ0ZS5JMThuKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDI0LzEwLzIwMTYuCiAqLwoKKGZ1bmN0aW9uIChJMThuKSB7CgogICAgdmFyIGRlID0gSTE4bi5kZSA9IHt9OwoKICAgIGRlLnN0cmluZ3MgPSB7CiAgICAgICAgIlVuZG8iIDogIlLDvGNrZ8OkbmdpZyIsCiAgICAgICAgIlJlZG8iIDogIldpZWRlcmhvbGVuIiwKICAgICAgICAiQm9sZCIgOiAiRmV0dCIsCiAgICAgICAgIkl0YWxpYyIgOiAiS3Vyc2l2IiwKICAgICAgICAiVW5kZXJsaW5lIiA6ICJVbnRlcnN0cmljaGVuIiwKICAgICAgICAiU3VwZXItc2NyaXB0IiA6ICJIb2NoZ2VzdGVsbHQiLAogICAgICAgICJTdWItc2NyaXB0IiA6ICJUaWVmZ2VzdGVsbHQiLAogICAgICAgICJUZXh0IENvbG9yIiA6ICJUZXh0ZmFyYmUiLAogICAgICAgICJIaWdobGlnaHQgQ29sb3IiIDogIkhlcnZvcmhlYnVuZ3NmYXJiZSIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICJTY2hyaWZ0ZmFtaWxpZSIsCiAgICAgICAgIkZvbnQgU2l6ZSIgOiAiU2NocmlmdGdyYWQiLAogICAgICAgICJMaW5lIEhlaWdodCIgOiAiWmVpbGVuaMO2aGUiLAogICAgICAgICJMZXR0ZXIgU3BhY2luZyIgOiAiQnVjaHN0YWJlbmFic3RhbmQiLAogICAgICAgICJQYXJhZ3JhcGggRm9ybWF0IiA6ICJBYnNhdHpmb3JtYXQiLAogICAgICAgICJKdXN0aWZ5IExlZnQiIDogIkxpbmtzIGF1c3JpY2h0ZW4iLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAiWmVudHJpZXJ0IGF1c3JpY2h0ZW4iLAogICAgICAgICJKdXN0aWZ5IEZ1bGwiIDogIkJsb2Nrc2F0eiIsCiAgICAgICAgIkp1c3RpZnkgUmlnaHQiIDogIlJlY2h0cyBhdXNyaWNodGVuIiwKICAgICAgICAiTWFyZ2luIExlZnQiIDogIlJhbmQgbGlua3MiLAogICAgICAgICJNYXJnaW4gUmlnaHQiIDogIlJhbmQgcmVjaHRzIiwKICAgICAgICAiTWFyZ2luIFRvcCIgOiAiUmFuZCBvYmVuIiwKICAgICAgICAiTWFyZ2luIEJvdHRvbSIgOiAiUmFuZCB1bnRlbiIsCiAgICAgICAgIkJ1bGxldGVkIExpc3QiIDogIkxpc3RlIG1pdCBBdWZ6w6RobHVuZ3N6ZWljaGVuIiwKICAgICAgICAiTnVtYmVyZWQgTGlzdCIgOiAiTnVtbWVyaWVydGUgTGlzdGUiLAogICAgICAgICJVcHBlci1jYXNlIEFscGhhYmV0IExpc3QiIDogIkFscGhhYmV0bGlzdGUgbWl0IEdyb8OfYnVjaHN0YWJlbiIsCiAgICAgICAgIkxvd2VyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAiQWxwaGFiZXRsaXN0ZSBtaXQgS2xlaW5idWNoc3RhYmVuIiwKICAgICAgICAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiA6ICJMaXN0ZSBtaXQgZ3Jvw59nZXNjaHJpZWJlbmVuIHLDtm1pc2NoZW4gWmVpY2hlbiIsCiAgICAgICAgIkxvd2VyLWNhc2UgUm9tYW4gTGlzdCIgOiAiS2xlaW5nZXNjaHJpZWJlbmUgcsO2bWlzY2hlIExpc3RlIiwKICAgICAgICAiSW5kZW50IiA6ICJFaW56dWciLAogICAgICAgICJPdXRkZW50IiA6ICJBdXNyw7xja2VuIiwKICAgICAgICAiRmluZCAmIFJlcGxhY2UiIDogIlN1Y2hlbiB1bmQgRXJzZXR6ZW4iLAogICAgICAgICJJbnNlcnQgTGluayIgOiAiTGluayBlaW5mw7xnZW4iLAogICAgICAgICJGaW5kIiA6ICJTdWNoZW4iLAogICAgICAgICJSZXBsYWNlIiA6ICJFcnNldHplbiIsCiAgICAgICAgIlJlcGxhY2UgYWxsIiA6ICJBbGxlIGVyc2V0emVuIiwKICAgICAgICAiTWF0Y2ggY2FzZSIgOiAiR3Jvw58tL0tsZWluc2NocmVpYnVuZyBiZWFjaHRlbiIsCiAgICAgICAgIldob2xlIHdvcmQiIDogIkdhbnplcyBXb3J0IiwKICAgICAgICAiUmVnIEV4IiA6ICJSZWd1bMOkcmVyIEF1c2RydWNrIiwKICAgICAgICAiSW5mbyIgOiAiSW5mb3JtYXRpb24iLAogICAgICAgICJSZWFjaGVkIGVuZCBvZiBtb2R1bGUuIiA6ICJFbmRlIGRlcyBNb2R1bHMgd3VyZGUgZXJyZWljaHQuIiwKICAgICAgICAiTWF0Y2ggTm90IEZvdW5kIiA6ICJLZWluZSDDnGJlcmVpbnN0aW1tdW5nIGdlZnVuZGVuIiwKICAgICAgICAiezB9IG1hdGNoZXMgcmVwbGFjZWQiIDogInswfSDDnGJlcmVpbnN0aW1tdW5nZW4gZXJzZXR6dCIsCiAgICAgICAgIlRpbWVzIE5ldyBSb21hbiIgOiAiVGltZXMgTmV3IFJvbWFuIiwKICAgICAgICAiQXJpYWwiIDogIkFyaWFsIiwKICAgICAgICAiQ291cmllciIgOiAiQ291cmllciIsCiAgICAgICAgIkNvdXJpZXIgTmV3IiA6ICJDb3VyaWVyIE5ldyIsCiAgICAgICAgIkdlbmV2YSIgOiAiR2VuZXZhIiwKICAgICAgICAiR2VvcmdpYSIgOiAiR2VvcmdpYSIsCiAgICAgICAgIkhlbHZldGljYSIgOiAiSGVsdmV0aWNhIiwKICAgICAgICAiVGFob21hIiA6ICJUYWhvbWEiLAogICAgICAgICJUaW1lcyIgOiAiVGltZXMiLAogICAgICAgICJWZXJkYW5hIiA6ICJWZXJkYW5hIiwKICAgICAgICAiTm9uZSIgOiAiS2VpbmUiLAogICAgICAgICJIZWFkZXIgMSIgOiAiw5xiZXJzY2hyaWZ0IDEiLAogICAgICAgICJIZWFkZXIgMiIgOiAiw5xiZXJzY2hyaWZ0IDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAiw5xiZXJzY2hyaWZ0IDMiLAogICAgICAgICJIZWFkZXIgNCIgOiAiw5xiZXJzY2hyaWZ0IDQiLAogICAgICAgICJIZWFkZXIgNSIgOiAiw5xiZXJzY2hyaWZ0IDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAiw5xiZXJzY2hyaWZ0IDYiLAogICAgICAgICJTZWxlY3QiIDogIkF1c3fDpGhsZW4iLAogICAgICAgICJCYXNpYyBWaWV3IiA6ICJFaW5mYWNoZSBBbnNpY2h0IiwKICAgICAgICAiRnVsbFNjcmVlbiIgOiAiVm9sbGJpbGQiLAogICAgICAgICJFeHBhbmQiIDogIkVyd2VpdGVybiIsCiAgICAgICAgIkNvbGxhcHNlIiA6ICJSZWR1emllcmVuIiwKICAgICAgICAiTGlzdCBUeXBlIiA6ICJMaXN0ZW50eXAiLAogICAgICAgICJVUkwiIDogIlVSTCIsCiAgICAgICAgIkFsdCBUZXh0IiA6ICJBbHQtVGV4dCIsCiAgICAgICAgIk9wZW4gaW4gbmV3IHBhZ2UiIDogIkF1ZiBuZXVlciBTZWl0ZSDDtmZmbmVuIgogICAgfTsKfSkoRm9ybS5ydGUuSTE4bik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiAyNC8xMC8yMDE2LgogKi8KCihmdW5jdGlvbiAoSTE4bikgewoKICAgIHZhciBlcyA9IEkxOG4uZXMgPSB7fTsKCiAgICBlcy5zdHJpbmdzID0gewogICAgICAgICJVbmRvIiA6ICJEZXNoYWNlciIsCiAgICAgICAgIlJlZG8iIDogIlJlaGFjZXIiLAogICAgICAgICJCb2xkIiA6ICJOZWdyaXRhIiwKICAgICAgICAiSXRhbGljIiA6ICJDdXJzaXZhIiwKICAgICAgICAiVW5kZXJsaW5lIiA6ICJTdWJyYXlhZG8iLAogICAgICAgICJTdXBlci1zY3JpcHQiIDogIlN1cGVyw61uZGljZSIsCiAgICAgICAgIlN1Yi1zY3JpcHQiIDogIlN1YsOtbmRpY2UiLAogICAgICAgICJUZXh0IENvbG9yIiA6ICJDb2xvciBkZWwgdGV4dG8iLAogICAgICAgICJIaWdobGlnaHQgQ29sb3IiIDogIkNvbG9yIGRlIHJlc2FsdGFkbyIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICJGYW1pbGlhIGRlIGZ1ZW50ZXMiLAogICAgICAgICJGb250IFNpemUiIDogIlRhbWHDsW8gZGUgZnVlbnRlIiwKICAgICAgICAiTGluZSBIZWlnaHQiIDogIkFsdHVyYSBkZSBsYSBsw61uZWEiLAogICAgICAgICJMZXR0ZXIgU3BhY2luZyIgOiAiRXNwYWNpYWRvIGVudHJlIGxldHJhcyIsCiAgICAgICAgIlBhcmFncmFwaCBGb3JtYXQiIDogIkZvcm1hdG8gZGUgcMOhcnJhZm8iLAogICAgICAgICJKdXN0aWZ5IExlZnQiIDogIkp1c3RpZmljYXIgYSBsYSBpenF1aWVyZGEiLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAiSnVzdGlmaWNhciBhbCBjZW50cm8iLAogICAgICAgICJKdXN0aWZ5IEZ1bGwiIDogIkp1c3RpZmljYXIgdG9kbyIsCiAgICAgICAgIkp1c3RpZnkgUmlnaHQiIDogIkp1c3RpZmljYXIgYSBsYSBkZXJlY2hhIiwKICAgICAgICAiTWFyZ2luIExlZnQiIDogIk1hcmdlbiBpenF1aWVyZG8iLAogICAgICAgICJNYXJnaW4gUmlnaHQiIDogIk1hcmdlbiBkZXJlY2hvIiwKICAgICAgICAiTWFyZ2luIFRvcCIgOiAiTWFyZ2VuIHN1cGVyaW9yIiwKICAgICAgICAiTWFyZ2luIEJvdHRvbSIgOiAiTWFyZ2VuIGluZmVyaW9yIiwKICAgICAgICAiQnVsbGV0ZWQgTGlzdCIgOiAiTGlzdGEgY29uIHZpw7FldGFzIiwKICAgICAgICAiTnVtYmVyZWQgTGlzdCIgOiAiTGlzdGEgbnVtZXJhZGEiLAogICAgICAgICJVcHBlci1jYXNlIEFscGhhYmV0IExpc3QiIDogIkxpc3RhIGRlIGxldHJhcyBkZWwgYWxmYWJldG8gZW4gbWF5w7pzY3VsYSIsCiAgICAgICAgIkxvd2VyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAiTGlzdGEgZGUgbGV0cmFzIGRlbCBhbGZhYmV0byBlbiBtaW7DunNjdWxhIiwKICAgICAgICAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiA6ICJMaXN0YSBkZSBjYXJhY3RlcmVzIHJvbWFub3MgZW4gbWluw7pzY3VsYSIsCiAgICAgICAgIkxvd2VyLWNhc2UgUm9tYW4gTGlzdCIgOiAiTGlzdGEgZGUgY2FyYWN0ZXJlcyByb21hbm9zIGVuIG1pbsO6c2N1bGEiLAogICAgICAgICJJbmRlbnQiIDogIlNhbmdyw61hIiwKICAgICAgICAiT3V0ZGVudCIgOiAiQW51bGFyIHNhbmdyw61hIiwKICAgICAgICAiRmluZCAmIFJlcGxhY2UiIDogIkJ1c2NhciB5IHJlZW1wbGF6YXIiLAogICAgICAgICJJbnNlcnQgTGluayIgOiAiSW5zZXJ0YXIgdsOtbmN1bG8iLAogICAgICAgICJGaW5kIiA6ICJCdXNjYXIiLAogICAgICAgICJSZXBsYWNlIiA6ICJSZWVtcGxhemFyIiwKICAgICAgICAiUmVwbGFjZSBhbGwiIDogIlJlZW1wbGF6YXIgdG9kbyIsCiAgICAgICAgIk1hdGNoIGNhc2UiIDogIkNvaW5jaWRpciBtYXnDunNjdWxhcyB5IG1pbsO6c2N1bGFzIiwKICAgICAgICAiV2hvbGUgd29yZCIgOiAiUGFsYWJyYSBjb21wbGV0YSIsCiAgICAgICAgIlJlZyBFeCIgOiAiUmVnIGV4IiwKICAgICAgICAiSW5mbyIgOiAiSW5mb3JtYWNpw7NuIiwKICAgICAgICAiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIgOiAiRmluIGRlbCBtw7NkdWxvIGFsY2FuemFkby4iLAogICAgICAgICJNYXRjaCBOb3QgRm91bmQiIDogIkNvaW5jaWRlbmNpYSBubyBlbmNvbnRyYWRhIiwKICAgICAgICAiezB9IG1hdGNoZXMgcmVwbGFjZWQiIDogInswfSBjb2luY2lkZW5jaWFzIHJlZW1wbGF6YWRhcyIsCiAgICAgICAgIlRpbWVzIE5ldyBSb21hbiIgOiAiVGltZXMgTmV3IFJvbWFuIiwKICAgICAgICAiQXJpYWwiIDogIkFyaWFsIiwKICAgICAgICAiQ291cmllciIgOiAiQ291cmllciIsCiAgICAgICAgIkNvdXJpZXIgTmV3IiA6ICJDb3VyaWVyIE5ldyIsCiAgICAgICAgIkdlbmV2YSIgOiAiR2VuZXZhIiwKICAgICAgICAiR2VvcmdpYSIgOiAiR2VvcmdpYSIsCiAgICAgICAgIkhlbHZldGljYSIgOiAiSGVsdmV0aWNhIiwKICAgICAgICAiVGFob21hIiA6ICJUYWhvbWEiLAogICAgICAgICJUaW1lcyIgOiAiVGltZXMiLAogICAgICAgICJWZXJkYW5hIiA6ICJWZXJkYW5hIiwKICAgICAgICAiTm9uZSIgOiAiTmluZ3VubyIsCiAgICAgICAgIkhlYWRlciAxIiA6ICJDYWJlY2VyYSAxIiwKICAgICAgICAiSGVhZGVyIDIiIDogIkNhYmVjZXJhIDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAiQ2FiZWNlcmEgMyIsCiAgICAgICAgIkhlYWRlciA0IiA6ICJDYWJlY2VyYSA0IiwKICAgICAgICAiSGVhZGVyIDUiIDogIkNhYmVjZXJhIDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAiQ2FiZWNlcmEgNiIsCiAgICAgICAgIlNlbGVjdCIgOiAiU2VsZWNjaW9uYXIiLAogICAgICAgICJCYXNpYyBWaWV3IiA6ICJWaXN0YSBiw6FzaWNhIiwKICAgICAgICAiRnVsbFNjcmVlbiIgOiAiUGFudGFsbGEgY29tcGxldGEiLAogICAgICAgICJFeHBhbmQiIDogIkV4cGFuZGlyIiwKICAgICAgICAiQ29sbGFwc2UiIDogIkNvbnRyYWVyIiwKICAgICAgICAiTGlzdCBUeXBlIiA6ICJUaXBvIGRlIGxpc3RhIiwKICAgICAgICAiVVJMIiA6ICJVUkwiLAogICAgICAgICJBbHQgVGV4dCIgOiAiVGV4dG8gYWx0ZXJuYXRpdm8iLAogICAgICAgICJPcGVuIGluIG5ldyBwYWdlIiA6ICJBYnJpciBlbiBudWV2YSBww6FnaW5hIgogICAgfTsKfSkoRm9ybS5ydGUuSTE4bik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiAyNC8xMC8yMDE2LgogKi8KCihmdW5jdGlvbiAoSTE4bikgewoKICAgIHZhciBmciA9IEkxOG4uZnIgPSB7fTsKCiAgICBmci5zdHJpbmdzID0gewogICAgICAgICJVbmRvIiA6ICJBbm51bGVyIiwKICAgICAgICAiUmVkbyIgOiAiUsOpdGFibGlyIiwKICAgICAgICAiQm9sZCIgOiAiR3JhcyIsCiAgICAgICAgIkl0YWxpYyIgOiAiSXRhbGlxdWUiLAogICAgICAgICJVbmRlcmxpbmUiIDogIlNvdWxpZ27DqSIsCiAgICAgICAgIlN1cGVyLXNjcmlwdCIgOiAiRXhwb3NhbnQiLAogICAgICAgICJTdWItc2NyaXB0IiA6ICJJbmRpY2UiLAogICAgICAgICJUZXh0IENvbG9yIiA6ICJDb3VsZXVyIGR1IHRleHRlIiwKICAgICAgICAiSGlnaGxpZ2h0IENvbG9yIiA6ICJDb3VsZXVyIGRlIHN1cmJyaWxsYW5jZSIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICJGYW1pbGxlIGRlIHBvbGljZXMiLAogICAgICAgICJGb250IFNpemUiIDogIlRhaWxsZSBkZSBsYSBwb2xpY2UiLAogICAgICAgICJMaW5lIEhlaWdodCIgOiAiSGF1dGV1ciBkZSBsaWduZSIsCiAgICAgICAgIkxldHRlciBTcGFjaW5nIiA6ICJJbnRlcmxldHRyYWdlIiwKICAgICAgICAiUGFyYWdyYXBoIEZvcm1hdCIgOiAiRm9ybWF0IGRlIHBhcmFncmFwaGUiLAogICAgICAgICJKdXN0aWZ5IExlZnQiIDogIkp1c3RpZmllciDDoCBnYXVjaGUiLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAiSnVzdGlmaWVyIGF1IGNlbnRyZSIsCiAgICAgICAgIkp1c3RpZnkgRnVsbCIgOiAiSnVzdGlmaWVyIGVudGnDqHJlbWVudCIsCiAgICAgICAgIkp1c3RpZnkgUmlnaHQiIDogIkp1c3RpZmllciDDoCBkcm9pdGUiLAogICAgICAgICJNYXJnaW4gTGVmdCIgOiAiTWFyZ2UgZ2F1Y2hlIiwKICAgICAgICAiTWFyZ2luIFJpZ2h0IiA6ICJNYXJnZSBkcm9pdGUiLAogICAgICAgICJNYXJnaW4gVG9wIiA6ICJNYXJnZSBzdXDDqXJpZXVyZSIsCiAgICAgICAgIk1hcmdpbiBCb3R0b20iIDogIk1hcmdlIGluZsOpcmlldXJlIiwKICAgICAgICAiQnVsbGV0ZWQgTGlzdCIgOiAiTGlzdGUgw6AgcHVjZXMiLAogICAgICAgICJOdW1iZXJlZCBMaXN0IiA6ICJMaXN0ZSBudW3DqXJvdMOpZSIsCiAgICAgICAgIlVwcGVyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAiTGlzdGUgYWxwaGFiw6l0aXF1ZSBlbiBtYWp1c2N1bGVzIiwKICAgICAgICAiTG93ZXItY2FzZSBBbHBoYWJldCBMaXN0IiA6ICJMaXN0ZSBhbHBoYWLDqXRpcXVlIGVuIG1pbnVzY3VsZXMiLAogICAgICAgICJVcHBlci1jYXNlIFJvbWFuIExpc3QiIDogIkxpc3RlIGVuIG1hanVzY3VsZXMgcm9tYWluZXMiLAogICAgICAgICJMb3dlci1jYXNlIFJvbWFuIExpc3QiIDogIkxpc3RlIGVuIGNhcmFjdMOocmVzIHJvbWFpbnMgbWludXNjdWxlcyIsCiAgICAgICAgIkluZGVudCIgOiAiUmV0cmFpdCIsCiAgICAgICAgIk91dGRlbnQiIDogIlJldHJhaXQgbsOpZ2F0aWYiLAogICAgICAgICJGaW5kICYgUmVwbGFjZSIgOiAiUmVjaGVyY2hlciBldCByZW1wbGFjZXIiLAogICAgICAgICJJbnNlcnQgTGluayIgOiAiSW5zw6lyZXIgdW4gbGllbiIsCiAgICAgICAgIkZpbmQiIDogIlJlY2hlcmNoZSIsCiAgICAgICAgIlJlcGxhY2UiIDogIlJlbXBsYWNlciIsCiAgICAgICAgIlJlcGxhY2UgYWxsIiA6ICJSZW1wbGFjZXIgdG91dCIsCiAgICAgICAgIk1hdGNoIGNhc2UiIDogIlJlc3BlY3RlciBsYSBjYXNzZSIsCiAgICAgICAgIldob2xlIHdvcmQiIDogIk1vdCBlbnRpZXIiLAogICAgICAgICJSZWcgRXgiIDogIkV4cC4gcsOpZy4iLAogICAgICAgICJJbmZvIiA6ICJJbmZvcyIsCiAgICAgICAgIlJlYWNoZWQgZW5kIG9mIG1vZHVsZS4iIDogIkF0dGVpbmRyZSBsYSBmaW4gZHUgbW9kdWxlLiIsCiAgICAgICAgIk1hdGNoIE5vdCBGb3VuZCIgOiAiQXVjdW5lIGNvcnJlc3BvbmRhbmNlIHRyb3V2w6llIiwKICAgICAgICAiezB9IG1hdGNoZXMgcmVwbGFjZWQiIDogInswfcKgY29ycmVzcG9uZGFuY2VzIHJlbXBsYWPDqWVzIiwKICAgICAgICAiVGltZXMgTmV3IFJvbWFuIiA6ICJUaW1lcyBOZXcgUm9tYW4iLAogICAgICAgICJBcmlhbCIgOiAiQXJpYWwiLAogICAgICAgICJDb3VyaWVyIiA6ICJDb3VyaWVyIiwKICAgICAgICAiQ291cmllciBOZXciIDogIkNvdXJpZXIgTmV3IiwKICAgICAgICAiR2VuZXZhIiA6ICJHZW5ldmEiLAogICAgICAgICJHZW9yZ2lhIiA6ICJHZW9yZ2lhIiwKICAgICAgICAiSGVsdmV0aWNhIiA6ICJIZWx2ZXRpY2EiLAogICAgICAgICJUYWhvbWEiIDogIlRhaG9tYSIsCiAgICAgICAgIlRpbWVzIiA6ICJUaW1lcyIsCiAgICAgICAgIlZlcmRhbmEiIDogIlZlcmRhbmEiLAogICAgICAgICJOb25lIiA6ICJBdWN1bmUiLAogICAgICAgICJIZWFkZXIgMSIgOiAiRW4tdMOqdGXCoDEiLAogICAgICAgICJIZWFkZXIgMiIgOiAiRW4tdMOqdGXCoDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAiRW4tdMOqdGXCoDMiLAogICAgICAgICJIZWFkZXIgNCIgOiAiRW4tdMOqdGXCoDQiLAogICAgICAgICJIZWFkZXIgNSIgOiAiRW4tdMOqdGXCoDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAiRW4tdMOqdGXCoDYiLAogICAgICAgICJTZWxlY3QiIDogIlPDqWxlY3Rpb25uZXIiLAogICAgICAgICJCYXNpYyBWaWV3IiA6ICJWdWUgZGUgYmFzZSIsCiAgICAgICAgIkZ1bGxTY3JlZW4iIDogIlBsZWluIMOpY3JhbiIsCiAgICAgICAgIkV4cGFuZCIgOiAiRMOpdmVsb3BwZXIiLAogICAgICAgICJDb2xsYXBzZSIgOiAiUsOpZHVpcmUiLAogICAgICAgICJMaXN0IFR5cGUiIDogIlR5cGUgZGUgbGlzdGUiLAogICAgICAgICJVUkwiIDogIlVSTCIsCiAgICAgICAgIkFsdCBUZXh0IiA6ICJBdXRyZSB0ZXh0ZSIsCiAgICAgICAgIk9wZW4gaW4gbmV3IHBhZ2UiIDogIk91dnJpciBkYW5zIHVuZSBub3V2ZWxsZSBwYWdlIgogICAgfTsKfSkoRm9ybS5ydGUuSTE4bik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiAyNC8xMC8yMDE2LgogKi8KCihmdW5jdGlvbiAoSTE4bikgewoKICAgIHZhciBpdCA9IEkxOG4uaXQgPSB7fTsKCiAgICBpdC5zdHJpbmdzID0gewogICAgICAgICJVbmRvIiA6ICJBbm51bGxhIiwKICAgICAgICAiUmVkbyIgOiAiUmlwZXRpIiwKICAgICAgICAiQm9sZCIgOiAiR3Jhc3NldHRvIiwKICAgICAgICAiSXRhbGljIiA6ICJDb3JzaXZvIiwKICAgICAgICAiVW5kZXJsaW5lIiA6ICJTb3R0b2xpbmVhIiwKICAgICAgICAiU3VwZXItc2NyaXB0IiA6ICJBcGljZSIsCiAgICAgICAgIlN1Yi1zY3JpcHQiIDogIlBlZGljZSIsCiAgICAgICAgIlRleHQgQ29sb3IiIDogIkNvbG9yZSB0ZXN0byIsCiAgICAgICAgIkhpZ2hsaWdodCBDb2xvciIgOiAiQ29sb3JlIGV2aWRlbnppYXppb25lIiwKICAgICAgICAiRm9udCBGYW1pbHkiIDogIkZhbWlnbGlhIGRpIGZvbnQiLAogICAgICAgICJGb250IFNpemUiIDogIkRpbWVuc2lvbmUgZm9udCIsCiAgICAgICAgIkxpbmUgSGVpZ2h0IiA6ICJBbHRlenphIHJpZ2EiLAogICAgICAgICJMZXR0ZXIgU3BhY2luZyIgOiAiU3BhemlhdHVyYSB0cmEgbGV0dGVyZSIsCiAgICAgICAgIlBhcmFncmFwaCBGb3JtYXQiIDogIkZvcm1hdG8gcGFyYWdyYWZvIiwKICAgICAgICAiSnVzdGlmeSBMZWZ0IiA6ICJHaXVzdGlmaWNhIGEgc2luaXN0cmEiLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAiR2l1c3RpZmljYSBhbCBjZW50cm8iLAogICAgICAgICJKdXN0aWZ5IEZ1bGwiIDogIkdpdXN0aWZpY2EiLAogICAgICAgICJKdXN0aWZ5IFJpZ2h0IiA6ICJHaXVzdGlmaWNhIGEgZGVzdHJhIiwKICAgICAgICAiTWFyZ2luIExlZnQiIDogIk1hcmdpbmUgc2luaXN0cm8iLAogICAgICAgICJNYXJnaW4gUmlnaHQiIDogIk1hcmdpbmUgZGVzdHJvIiwKICAgICAgICAiTWFyZ2luIFRvcCIgOiAiTWFyZ2luZSBzdXBlcmlvcmUiLAogICAgICAgICJNYXJnaW4gQm90dG9tIiA6ICJNYXJnaW5lIGluZmVyaW9yZSIsCiAgICAgICAgIkJ1bGxldGVkIExpc3QiIDogIkVsZW5jbyBwdW50YXRvIiwKICAgICAgICAiTnVtYmVyZWQgTGlzdCIgOiAiRWxlbmNvIG51bWVyYXRvIiwKICAgICAgICAiVXBwZXItY2FzZSBBbHBoYWJldCBMaXN0IiA6ICJFbGVuY28gYWxmYWJldG8gbWFpdXNjb2xvIiwKICAgICAgICAiTG93ZXItY2FzZSBBbHBoYWJldCBMaXN0IiA6ICJFbGVuY28gYWxmYWJldG8gbWludXNjb2xvIiwKICAgICAgICAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiA6ICJFbGVuY28gUm9tYW4gbWFpdXNjb2xvIiwKICAgICAgICAiTG93ZXItY2FzZSBSb21hbiBMaXN0IiA6ICJFbGVuY28gUm9tYW4gbWludXNjb2xvIiwKICAgICAgICAiSW5kZW50IiA6ICJSaWVudHJvIiwKICAgICAgICAiT3V0ZGVudCIgOiAiUmllbnRybyBuZWdhdGl2byIsCiAgICAgICAgIkZpbmQgJiBSZXBsYWNlIiA6ICJUcm92YSBlIHNvc3RpdHVpc2NpIiwKICAgICAgICAiSW5zZXJ0IExpbmsiIDogIkluc2VyaXNjaSBjb2xsZWdhbWVudG8iLAogICAgICAgICJGaW5kIiA6ICJUcm92YSIsCiAgICAgICAgIlJlcGxhY2UiIDogIlNvc3RpdHVpc2NpIiwKICAgICAgICAiUmVwbGFjZSBhbGwiIDogIlNvc3RpdHVpc2NpIHR1dHRvIiwKICAgICAgICAiTWF0Y2ggY2FzZSIgOiAiTWFpdXNjb2xlL21pbnVzY29sZSIsCiAgICAgICAgIldob2xlIHdvcmQiIDogIlBhcm9sYSBpbnRlcmEiLAogICAgICAgICJSZWcgRXgiIDogIlJlZyBlc2VnIiwKICAgICAgICAiSW5mbyIgOiAiSW5mb3JtYXppb25pIiwKICAgICAgICAiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIgOiAiRmluZSBkZWwgbW9kdWxvLiIsCiAgICAgICAgIk1hdGNoIE5vdCBGb3VuZCIgOiAiQ29ycmlzcG9uZGVuemEgbm9uIHRyb3ZhdGEiLAogICAgICAgICJ7MH0gbWF0Y2hlcyByZXBsYWNlZCIgOiAiezB9IGNvcnJpc3BvbmRlbnplIHNvc3RpdHVpdGUiLAogICAgICAgICJUaW1lcyBOZXcgUm9tYW4iIDogIlRpbWVzIE5ldyBSb21hbiIsCiAgICAgICAgIkFyaWFsIiA6ICJBcmlhbCIsCiAgICAgICAgIkNvdXJpZXIiIDogIkNvdXJpZXIiLAogICAgICAgICJDb3VyaWVyIE5ldyIgOiAiQ291cmllciBOZXciLAogICAgICAgICJHZW5ldmEiIDogIkdlbmV2YSIsCiAgICAgICAgIkdlb3JnaWEiIDogIkdlb3JnaWEiLAogICAgICAgICJIZWx2ZXRpY2EiIDogIkhlbHZldGljYSIsCiAgICAgICAgIlRhaG9tYSIgOiAiVGFob21hIiwKICAgICAgICAiVGltZXMiIDogIlRpbWVzIiwKICAgICAgICAiVmVyZGFuYSIgOiAiVmVyZGFuYSIsCiAgICAgICAgIk5vbmUiIDogIk5lc3N1bm8iLAogICAgICAgICJIZWFkZXIgMSIgOiAiSW50ZXN0YXppb25lIDEiLAogICAgICAgICJIZWFkZXIgMiIgOiAiSW50ZXN0YXppb25lIDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAiSW50ZXN0YXppb25lIDMiLAogICAgICAgICJIZWFkZXIgNCIgOiAiSW50ZXN0YXppb25lIDQiLAogICAgICAgICJIZWFkZXIgNSIgOiAiSW50ZXN0YXppb25lIDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAiSW50ZXN0YXppb25lIDYiLAogICAgICAgICJTZWxlY3QiIDogIlNlbGV6aW9uYSIsCiAgICAgICAgIkJhc2ljIFZpZXciIDogIlZpc3RhIGRpIGJhc2UiLAogICAgICAgICJGdWxsU2NyZWVuIiA6ICJTY2hlcm1vIGludGVybyIsCiAgICAgICAgIkV4cGFuZCIgOiAiRXNwYW5kaSIsCiAgICAgICAgIkNvbGxhcHNlIiA6ICJDb21wcmltaSIsCiAgICAgICAgIkxpc3QgVHlwZSIgOiAiVGlwbyBkaSBsaXN0YSIsCiAgICAgICAgIlVSTCIgOiAiVVJMIiwKICAgICAgICAiQWx0IFRleHQiIDogIlRlc3RvIGFsdGVybmF0aXZvIiwKICAgICAgICAiT3BlbiBpbiBuZXcgcGFnZSIgOiAiQXByaSBpbiBudW92YSBwYWdpbmEiCiAgICB9Owp9KShGb3JtLnJ0ZS5JMThuKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDI0LzEwLzIwMTYuCiAqLwoKKGZ1bmN0aW9uIChJMThuKSB7CgogICAgdmFyIGphID0gSTE4bi5qYSA9IHt9OwoKICAgIGphLnN0cmluZ3MgPSB7CiAgICAgICAgIlVuZG8iIDogIuWPluOCiua2iOOBlyIsCiAgICAgICAgIlJlZG8iIDogIuOChOOCiuebtOOBlyIsCiAgICAgICAgIkJvbGQiIDogIuWkquWtlyIsCiAgICAgICAgIkl0YWxpYyIgOiAi44Kk44K/44Oq44OD44KvIiwKICAgICAgICAiVW5kZXJsaW5lIiA6ICLkuIvnt5oiLAogICAgICAgICJTdXBlci1zY3JpcHQiIDogIuS4iuS7mOOBjeaWh+WtlyIsCiAgICAgICAgIlN1Yi1zY3JpcHQiIDogIuS4i+S7mOOBjeaWh+WtlyIsCiAgICAgICAgIlRleHQgQ29sb3IiIDogIuODhuOCreOCueODiOOCq+ODqeODvCIsCiAgICAgICAgIkhpZ2hsaWdodCBDb2xvciIgOiAi44OP44Kk44Op44Kk44OI6KGo56S644Gu6ImyIiwKICAgICAgICAiRm9udCBGYW1pbHkiIDogIuODleOCqeODs+ODiOODleOCoeODn+ODquODvCIsCiAgICAgICAgIkZvbnQgU2l6ZSIgOiAi44OV44Kp44Oz44OI44K144Kk44K6IiwKICAgICAgICAiTGluZSBIZWlnaHQiIDogIuihjOOBrumrmOOBlSIsCiAgICAgICAgIkxldHRlciBTcGFjaW5nIiA6ICLmloflrZfplpPpmpQiLAogICAgICAgICJQYXJhZ3JhcGggRm9ybWF0IiA6ICLmrrXokL3mm7jlvI8iLAogICAgICAgICJKdXN0aWZ5IExlZnQiIDogIuW3puaPg+OBiCIsCiAgICAgICAgIkp1c3RpZnkgQ2VudGVyIiA6ICLkuK3lpK7mj4PjgYgiLAogICAgICAgICJKdXN0aWZ5IEZ1bGwiIDogIuS4oeerr+aPg+OBiCIsCiAgICAgICAgIkp1c3RpZnkgUmlnaHQiIDogIuWPs+aPg+OBiCIsCiAgICAgICAgIk1hcmdpbiBMZWZ0IiA6ICLlt6bjg57jg7zjgrjjg7MiLAogICAgICAgICJNYXJnaW4gUmlnaHQiIDogIuWPs+ODnuODvOOCuOODsyIsCiAgICAgICAgIk1hcmdpbiBUb3AiIDogIuS4iuODnuODvOOCuOODsyIsCiAgICAgICAgIk1hcmdpbiBCb3R0b20iIDogIuS4i+ODnuODvOOCuOODsyIsCiAgICAgICAgIkJ1bGxldGVkIExpc3QiIDogIuODkOODrOODg+ODiOODquOCueODiCIsCiAgICAgICAgIk51bWJlcmVkIExpc3QiIDogIueVquWPt+S7mOOBjeODquOCueODiCIsCiAgICAgICAgIlVwcGVyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAi5aSn5paH5a2X44Ki44Or44OV44Kh44OZ44OD44OI44Oq44K544OIIiwKICAgICAgICAiTG93ZXItY2FzZSBBbHBoYWJldCBMaXN0IiA6ICLlsI/mloflrZfjgqLjg6vjg5XjgqHjg5njg4Pjg4jjg6rjgrnjg4giLAogICAgICAgICJVcHBlci1jYXNlIFJvbWFuIExpc3QiIDogIuWkp+aWh+Wtl+ODreODvOODnuODs+ODquOCueODiCIsCiAgICAgICAgIkxvd2VyLWNhc2UgUm9tYW4gTGlzdCIgOiAi5bCP5paH5a2X44Ot44O844Oe44Oz44Oq44K544OIIiwKICAgICAgICAiSW5kZW50IiA6ICLjgqTjg7Pjg4fjg7Pjg4giLAogICAgICAgICJPdXRkZW50IiA6ICLjgqLjgqbjg4jjg4fjg7Pjg4giLAogICAgICAgICJGaW5kICYgUmVwbGFjZSIgOiAi5qSc57Si44Go572u5o+bIiwKICAgICAgICAiSW5zZXJ0IExpbmsiIDogIuODquODs+OCr+OCkuaMv+WFpSIsCiAgICAgICAgIkZpbmQiIDogIuaknOe0oiIsCiAgICAgICAgIlJlcGxhY2UiIDogIue9ruaPmyIsCiAgICAgICAgIlJlcGxhY2UgYWxsIiA6ICLjgZnjgbnjgabnva7mj5siLAogICAgICAgICJNYXRjaCBjYXNlIiA6ICLlpKfmloflrZcgLyDlsI/mloflrZfjgpLkuIDoh7QiLAogICAgICAgICJXaG9sZSB3b3JkIiA6ICLljZjoqp7lhajkvZMiLAogICAgICAgICJSZWcgRXgiIDogIuato+imj+ihqOePviIsCiAgICAgICAgIkluZm8iIDogIuaDheWgsSIsCiAgICAgICAgIlJlYWNoZWQgZW5kIG9mIG1vZHVsZS4iIDogIuODouOCuOODpeODvOODq+OBruacgOW+jOOBq+mBlOOBl+OBvuOBl+OBn+OAgiIsCiAgICAgICAgIk1hdGNoIE5vdCBGb3VuZCIgOiAi5LiA6Ie044GM6KaL44Gk44GL44KK44G+44Gb44KT44Gn44GX44GfIiwKICAgICAgICAiezB9IG1hdGNoZXMgcmVwbGFjZWQiIDogInswfSDlgIvjga7kuIDoh7TjgYznva7mj5vjgZXjgozjgb7jgZfjgZ8iLAogICAgICAgICJUaW1lcyBOZXcgUm9tYW4iIDogIlRpbWVzIE5ldyBSb21hbiIsCiAgICAgICAgIkFyaWFsIiA6ICJBcmlhbCIsCiAgICAgICAgIkNvdXJpZXIiIDogIkNvdXJpZXIiLAogICAgICAgICJDb3VyaWVyIE5ldyIgOiAiQ291cmllciBOZXciLAogICAgICAgICJHZW5ldmEiIDogIkdlbmV2YSIsCiAgICAgICAgIkdlb3JnaWEiIDogIkdlb3JnaWEiLAogICAgICAgICJIZWx2ZXRpY2EiIDogIkhlbHZldGljYSIsCiAgICAgICAgIlRhaG9tYSIgOiAiVGFob21hIiwKICAgICAgICAiVGltZXMiIDogIlRpbWVzIiwKICAgICAgICAiVmVyZGFuYSIgOiAiVmVyZGFuYSIsCiAgICAgICAgIk5vbmUiIDogIumBqeeUqOOBquOBlyIsCiAgICAgICAgIkhlYWRlciAxIiA6ICLjg5jjg4Pjg4Djg7wgMSIsCiAgICAgICAgIkhlYWRlciAyIiA6ICLjg5jjg4Pjg4Djg7wgMiIsCiAgICAgICAgIkhlYWRlciAzIiA6ICLjg5jjg4Pjg4Djg7wgMyIsCiAgICAgICAgIkhlYWRlciA0IiA6ICLjg5jjg4Pjg4Djg7wgNCIsCiAgICAgICAgIkhlYWRlciA1IiA6ICLjg5jjg4Pjg4Djg7wgNSIsCiAgICAgICAgIkhlYWRlciA2IiA6ICLjg5jjg4Pjg4Djg7wgNiIsCiAgICAgICAgIlNlbGVjdCIgOiAi6YG45oqeIiwKICAgICAgICAiQmFzaWMgVmlldyIgOiAi5Z+65pys6KGo56S6IiwKICAgICAgICAiRnVsbFNjcmVlbiIgOiAi44OV44Or44K544Kv44Oq44O844OzIiwKICAgICAgICAiRXhwYW5kIiA6ICLlsZXplosiLAogICAgICAgICJDb2xsYXBzZSIgOiAi6Zqg44GZIiwKICAgICAgICAiTGlzdCBUeXBlIiA6ICLjg6rjgrnjg4jjgr/jgqTjg5ciLAogICAgICAgICJVUkwiIDogIlVSTCIsCiAgICAgICAgIkFsdCBUZXh0IiA6ICLku6Pmm7/jg4bjgq3jgrnjg4giLAogICAgICAgICJPcGVuIGluIG5ldyBwYWdlIiA6ICLmlrDjgZfjgYTjg5rjg7zjgrjjgafplovjgY8iCiAgICB9Owp9KShGb3JtLnJ0ZS5JMThuKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDI0LzEwLzIwMTYuCiAqLwoKKGZ1bmN0aW9uIChJMThuKSB7CgogICAgdmFyIGtvS1IgPSBJMThuLmtvS1IgPSB7fTsKCiAgICBrb0tSLnN0cmluZ3MgPSB7CiAgICAgICAgIlVuZG8iIDogIuyLpO2WiSDst6jshowiLAogICAgICAgICJSZWRvIiA6ICLri6Tsi5wg7Iuk7ZaJIiwKICAgICAgICAiQm9sZCIgOiAi67O865Oc7LK0IiwKICAgICAgICAiSXRhbGljIiA6ICLsnbTtg6Trpq3ssrQiLAogICAgICAgICJVbmRlcmxpbmUiIDogIuuwkeykhCIsCiAgICAgICAgIlN1cGVyLXNjcmlwdCIgOiAi7JyEIOyyqOyekCIsCiAgICAgICAgIlN1Yi1zY3JpcHQiIDogIuyVhOuemCDssqjsnpAiLAogICAgICAgICJUZXh0IENvbG9yIiA6ICLthY3siqTtirgg7IOJ7IOBIiwKICAgICAgICAiSGlnaGxpZ2h0IENvbG9yIiA6ICLqsJXsobAg7IOJ7IOBIiwKICAgICAgICAiRm9udCBGYW1pbHkiIDogIuq4gOq8tCDrqqjsnYwiLAogICAgICAgICJGb250IFNpemUiIDogIuq4gOq8tCDtgazquLAiLAogICAgICAgICJMaW5lIEhlaWdodCIgOiAi7ISgIOuGkuydtCIsCiAgICAgICAgIkxldHRlciBTcGFjaW5nIiA6ICLrrLjsnpAg6rCE6rKpIiwKICAgICAgICAiUGFyYWdyYXBoIEZvcm1hdCIgOiAi64uo6529IO2YleyLnSIsCiAgICAgICAgIkp1c3RpZnkgTGVmdCIgOiAi7Jm87Kq9IOunnuy2pCIsCiAgICAgICAgIkp1c3RpZnkgQ2VudGVyIiA6ICLqsIDsmrTrjbAg66ee7LakIiwKICAgICAgICAiSnVzdGlmeSBGdWxsIiA6ICLsoITssrQg66ee7LakIiwKICAgICAgICAiSnVzdGlmeSBSaWdodCIgOiAi7Jik66W47Kq9IOunnuy2pCIsCiAgICAgICAgIk1hcmdpbiBMZWZ0IiA6ICLsmbzsqr0g7Jes67CxIiwKICAgICAgICAiTWFyZ2luIFJpZ2h0IiA6ICLsmKTrpbjsqr0g7Jes67CxIiwKICAgICAgICAiTWFyZ2luIFRvcCIgOiAi7IOB64uoIOyXrOuwsSIsCiAgICAgICAgIk1hcmdpbiBCb3R0b20iIDogIu2VmOuLqCDsl6zrsLEiLAogICAgICAgICJCdWxsZXRlZCBMaXN0IiA6ICLquIDrqLjrpqwg6riw7Zi4IOuqqeuhnSIsCiAgICAgICAgIk51bWJlcmVkIExpc3QiIDogIuuyiO2YuCDrp6TquLDquLAg66qp66GdIiwKICAgICAgICAiVXBwZXItY2FzZSBBbHBoYWJldCBMaXN0IiA6ICLrjIDrrLjsnpAg7JWM7YyM67KzIOuqqeuhnSIsCiAgICAgICAgIkxvd2VyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAi7IaM66y47J6QIOyVjO2MjOuysyDrqqnroZ0iLAogICAgICAgICJVcHBlci1jYXNlIFJvbWFuIExpc3QiIDogIuuMgOusuOyekCDroZzrp4jsnpAg66qp66GdIiwKICAgICAgICAiTG93ZXItY2FzZSBSb21hbiBMaXN0IiA6ICLshozrrLjsnpAg66Gc66eI7J6QIOuqqeuhnSIsCiAgICAgICAgIkluZGVudCIgOiAi65Ok7Jes7JOw6riwIiwKICAgICAgICAiT3V0ZGVudCIgOiAi64K07Ja07JOw6riwIiwKICAgICAgICAiRmluZCAmIFJlcGxhY2UiIDogIuywvuq4sCDrsI8g67CU6r646riwIiwKICAgICAgICAiSW5zZXJ0IExpbmsiIDogIuunge2BrCDsgr3snoUiLAogICAgICAgICJGaW5kIiA6ICLssL7quLAiLAogICAgICAgICJSZXBsYWNlIiA6ICLrsJTqvrjquLAiLAogICAgICAgICJSZXBsYWNlIGFsbCIgOiAi66qo65GQIOuwlOq+uOq4sCIsCiAgICAgICAgIk1hdGNoIGNhc2UiIDogIuuMgOyGjOusuOyekCDsnbzsuZgiLAogICAgICAgICJXaG9sZSB3b3JkIiA6ICLri6jslrQg64uo7JyE66Gc66eMIiwKICAgICAgICAiUmVnIEV4IiA6ICLsnbzrsJgg7ZGc7ZiE7IudIiwKICAgICAgICAiSW5mbyIgOiAi7KCV67O0IiwKICAgICAgICAiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIgOiAi66qo65OIIOuBneyXkCDrj4Tri6ztlojsirXri4jri6QuIiwKICAgICAgICAiTWF0Y2ggTm90IEZvdW5kIiA6ICLsnbzsuZjtlZjripQg7ZWt66qp7J2EIOywvuydhCDsiJgg7JeG7Iq164uI64ukLiIsCiAgICAgICAgInswfSBtYXRjaGVzIHJlcGxhY2VkIiA6ICJ7MH3qsJzsnZgg7J287LmYIO2VreuqqeydtCDrjIDssrTrkJjsl4jsirXri4jri6QuIiwKICAgICAgICAiVGltZXMgTmV3IFJvbWFuIiA6ICJUaW1lcyBOZXcgUm9tYW4iLAogICAgICAgICJBcmlhbCIgOiAiQXJpYWwiLAogICAgICAgICJDb3VyaWVyIiA6ICJDb3VyaWVyIiwKICAgICAgICAiQ291cmllciBOZXciIDogIkNvdXJpZXIgTmV3IiwKICAgICAgICAiR2VuZXZhIiA6ICJHZW5ldmEiLAogICAgICAgICJHZW9yZ2lhIiA6ICJHZW9yZ2lhIiwKICAgICAgICAiSGVsdmV0aWNhIiA6ICJIZWx2ZXRpY2EiLAogICAgICAgICJUYWhvbWEiIDogIlRhaG9tYSIsCiAgICAgICAgIlRpbWVzIiA6ICJUaW1lcyIsCiAgICAgICAgIlZlcmRhbmEiIDogIlZlcmRhbmEiLAogICAgICAgICJOb25lIiA6ICLsl4bsnYwiLAogICAgICAgICJIZWFkZXIgMSIgOiAi66i466as6riAIDEiLAogICAgICAgICJIZWFkZXIgMiIgOiAi66i466as6riAIDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAi66i466as6riAIDMiLAogICAgICAgICJIZWFkZXIgNCIgOiAi66i466as6riAIDQiLAogICAgICAgICJIZWFkZXIgNSIgOiAi66i466as6riAIDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAi66i466as6riAIDYiLAogICAgICAgICJTZWxlY3QiIDogIuyEoO2DnSIsCiAgICAgICAgIkJhc2ljIFZpZXciIDogIuq4sOuzuCDrt7AiLAogICAgICAgICJGdWxsU2NyZWVuIiA6ICLsoITssrTtmZTrqbQiLAogICAgICAgICJFeHBhbmQiIDogIu2ZleyepSIsCiAgICAgICAgIkNvbGxhcHNlIiA6ICLstpXshowiLAogICAgICAgICJMaXN0IFR5cGUiIDogIuuqqeuhnSDsnKDtmJUiLAogICAgICAgICJVUkwiIDogIlVSTCIsCiAgICAgICAgIkFsdCBUZXh0IiA6ICJBbHQg7IaN7ISxIiwKICAgICAgICAiT3BlbiBpbiBuZXcgcGFnZSIgOiAi7IOIIO2OmOydtOyngOyXkOyEnCDsl7TquLAiCiAgICB9Owp9KShGb3JtLnJ0ZS5JMThuKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDI0LzEwLzIwMTYuCiAqLwoKKGZ1bmN0aW9uIChJMThuKSB7CgogICAgdmFyIHB0QlIgPSBJMThuLnB0QlIgPSB7fTsKCiAgICBwdEJSLnN0cmluZ3MgPSB7CiAgICAgICAgIlVuZG8iIDogIkRlc2ZhemVyIiwKICAgICAgICAiUmVkbyIgOiAiUmVmYXplciIsCiAgICAgICAgIkJvbGQiIDogIk5lZ3JpdG8iLAogICAgICAgICJJdGFsaWMiIDogIkl0w6FsaWNvIiwKICAgICAgICAiVW5kZXJsaW5lIiA6ICJTdWJsaW5oYWRvIiwKICAgICAgICAiU3VwZXItc2NyaXB0IiA6ICJTb2JyZXNjcml0byIsCiAgICAgICAgIlN1Yi1zY3JpcHQiIDogIlN1YnNjcml0byIsCiAgICAgICAgIlRleHQgQ29sb3IiIDogIkNvciBkbyB0ZXh0byIsCiAgICAgICAgIkhpZ2hsaWdodCBDb2xvciIgOiAiQ29yIGRlIHJlYWxjZSIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICJGYW3DrWxpYSBkZSBmb250ZXMiLAogICAgICAgICJGb250IFNpemUiIDogIlRhbWFuaG8gZGEgZm9udGUiLAogICAgICAgICJMaW5lIEhlaWdodCIgOiAiQWx0dXJhIGRhIGxpbmhhIiwKICAgICAgICAiTGV0dGVyIFNwYWNpbmciIDogIkVzcGHDp2FtZW50byBlbnRyZSBMZXRyYXMiLAogICAgICAgICJQYXJhZ3JhcGggRm9ybWF0IiA6ICJGb3JtYXRvIGRlIHBhcsOhZ3JhZm8iLAogICAgICAgICJKdXN0aWZ5IExlZnQiIDogIkp1c3RpZmljYXIgw6AgZXNxdWVyZGEiLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAiSnVzdGlmaWNhciBubyBjZW50cm8iLAogICAgICAgICJKdXN0aWZ5IEZ1bGwiIDogIkp1c3RpZmljYXIgdHVkbyIsCiAgICAgICAgIkp1c3RpZnkgUmlnaHQiIDogIkp1c3RpZmljYXIgw6AgZGlyZWl0YSIsCiAgICAgICAgIk1hcmdpbiBMZWZ0IiA6ICJNYXJnZW0gZXNxdWVyZGEiLAogICAgICAgICJNYXJnaW4gUmlnaHQiIDogIk1hcmdlbSBkaXJlaXRhIiwKICAgICAgICAiTWFyZ2luIFRvcCIgOiAiTWFyZ2VtIHN1cGVyaW9yIiwKICAgICAgICAiTWFyZ2luIEJvdHRvbSIgOiAiTWFyZ2VtIGluZmVyaW9yIiwKICAgICAgICAiQnVsbGV0ZWQgTGlzdCIgOiAiTGlzdGEgY29tIG1hcmNhZG9yZXMiLAogICAgICAgICJOdW1iZXJlZCBMaXN0IiA6ICJMaXN0YSBudW1lcmFkYSIsCiAgICAgICAgIlVwcGVyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAiTGlzdGEgYWxmYWLDqXRpY2EgZW0gbWFpw7pzY3VsYXMiLAogICAgICAgICJMb3dlci1jYXNlIEFscGhhYmV0IExpc3QiIDogIkxpc3RhIGFsZmFiw6l0aWNhIGVtIG1pbsO6c2N1bGFzIiwKICAgICAgICAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiA6ICJMaXN0YSBkZSBhbGdhcmlzbW9zIHJvbWFub3MgbWFpw7pzY3Vsb3MiLAogICAgICAgICJMb3dlci1jYXNlIFJvbWFuIExpc3QiIDogIkFsZ2FyaXNtb3MgUm9tYW5vcyBNaW7DunNjdWxvcyIsCiAgICAgICAgIkluZGVudCIgOiAiUmVjdW8iLAogICAgICAgICJPdXRkZW50IiA6ICJSZWN1byBwYXJhIGEgZXNxdWVyZGEiLAogICAgICAgICJGaW5kICYgUmVwbGFjZSIgOiAiTG9jYWxpemFyIGUgc3Vic3RpdHVpciIsCiAgICAgICAgIkluc2VydCBMaW5rIiA6ICJJbnNlcmlyIGxpbmsiLAogICAgICAgICJGaW5kIiA6ICJMb2NhbGl6YXIiLAogICAgICAgICJSZXBsYWNlIiA6ICJTdWJzdGl0dWlyIiwKICAgICAgICAiUmVwbGFjZSBhbGwiIDogIlN1YnN0aXR1aXIgdHVkbyIsCiAgICAgICAgIk1hdGNoIGNhc2UiIDogIkRpZmVyZW5jaWFyIG1hacO6c2N1bGFzIGRlIG1pbsO6c2N1bGFzIiwKICAgICAgICAiV2hvbGUgd29yZCIgOiAiUGFsYXZyYSBpbnRlaXJhIiwKICAgICAgICAiUmVnIEV4IiA6ICJSZWcgRXgiLAogICAgICAgICJJbmZvIiA6ICJJbmZvcm1hw6fDtWVzIiwKICAgICAgICAiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIgOiAiQXRpbmdpdSBvIGZpbSBkbyBtw7NkdWxvLiIsCiAgICAgICAgIk1hdGNoIE5vdCBGb3VuZCIgOiAiQ29ycmVzcG9uZMOqbmNpYSBuw6NvIGVuY29udHJhZGEiLAogICAgICAgICJ7MH0gbWF0Y2hlcyByZXBsYWNlZCIgOiAiezB9IGNvcnJlc3BvbmTDqm5jaWFzIHN1YnN0aXR1w61kYXMiLAogICAgICAgICJUaW1lcyBOZXcgUm9tYW4iIDogIlRpbWVzIE5ldyBSb21hbiIsCiAgICAgICAgIkFyaWFsIiA6ICJBcmlhbCIsCiAgICAgICAgIkNvdXJpZXIiIDogIkNvdXJpZXIiLAogICAgICAgICJDb3VyaWVyIE5ldyIgOiAiQ291cmllciBOZXciLAogICAgICAgICJHZW5ldmEiIDogIkdlbmVicmEiLAogICAgICAgICJHZW9yZ2lhIiA6ICJHZcOzcmdpYSIsCiAgICAgICAgIkhlbHZldGljYSIgOiAiSGVsdmV0aWNhIiwKICAgICAgICAiVGFob21hIiA6ICJUYWhvbWEiLAogICAgICAgICJUaW1lcyIgOiAiVGltZXMiLAogICAgICAgICJWZXJkYW5hIiA6ICJWZXJkYW5hIiwKICAgICAgICAiTm9uZSIgOiAiTmVuaHVtIiwKICAgICAgICAiSGVhZGVyIDEiIDogIkNhYmXDp2FsaG8gMSIsCiAgICAgICAgIkhlYWRlciAyIiA6ICJDYWJlw6dhbGhvIDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAiQ2FiZcOnYWxobyAzIiwKICAgICAgICAiSGVhZGVyIDQiIDogIkNhYmXDp2FsaG8gNCIsCiAgICAgICAgIkhlYWRlciA1IiA6ICJDYWJlw6dhbGhvIDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAiQ2FiZcOnYWxobyA2IiwKICAgICAgICAiU2VsZWN0IiA6ICJTZWxlY2lvbmFyIiwKICAgICAgICAiQmFzaWMgVmlldyIgOiAiRXhpYmnDp8OjbyBiw6FzaWNhIiwKICAgICAgICAiRnVsbFNjcmVlbiIgOiAiVGVsYSBpbnRlaXJhIiwKICAgICAgICAiRXhwYW5kIiA6ICJFeHBhbmRpciIsCiAgICAgICAgIkNvbGxhcHNlIiA6ICJDb250cmFpciIsCiAgICAgICAgIkxpc3QgVHlwZSIgOiAiVGlwbyBkZSBsaXN0YSIsCiAgICAgICAgIlVSTCIgOiAiVVJMIiwKICAgICAgICAiQWx0IFRleHQiIDogIlRleHRvIGFsdGVybmF0aXZvIiwKICAgICAgICAiT3BlbiBpbiBuZXcgcGFnZSIgOiAiQWJyaXIgZW0gbm92YSBww6FnaW5hIgogICAgfTsKfSkoRm9ybS5ydGUuSTE4bik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiAyNC8xMC8yMDE2LgogKi8KCihmdW5jdGlvbiAoSTE4bikgewoKICAgIHZhciB6aENOID0gSTE4bi56aENOID0ge307CgogICAgemhDTi5zdHJpbmdzID0gewogICAgICAgICJVbmRvIiA6ICLmkqTmtogiLAogICAgICAgICJSZWRvIiA6ICLmgaLlpI0iLAogICAgICAgICJCb2xkIiA6ICLnspfkvZMiLAogICAgICAgICJJdGFsaWMiIDogIuaWnOS9kyIsCiAgICAgICAgIlVuZGVybGluZSIgOiAi5LiL5YiS57q/IiwKICAgICAgICAiU3VwZXItc2NyaXB0IiA6ICLkuIrmoIciLAogICAgICAgICJTdWItc2NyaXB0IiA6ICLkuIvmoIciLAogICAgICAgICJUZXh0IENvbG9yIiA6ICLmlofmnKzpopzoibIiLAogICAgICAgICJIaWdobGlnaHQgQ29sb3IiIDogIueqgeWHuuaYvuekuuminOiJsiIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICLlrZfkvZPns7vliJciLAogICAgICAgICJGb250IFNpemUiIDogIuWtl+S9k+Wkp+WwjyIsCiAgICAgICAgIkxpbmUgSGVpZ2h0IiA6ICLooYzpq5giLAogICAgICAgICJMZXR0ZXIgU3BhY2luZyIgOiAi5a2X5q+N6Ze06LedIiwKICAgICAgICAiUGFyYWdyYXBoIEZvcm1hdCIgOiAi5q616JC95qC85byPIiwKICAgICAgICAiSnVzdGlmeSBMZWZ0IiA6ICLlt6blr7npvZAiLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAi5bGF5Lit5a+56b2QIiwKICAgICAgICAiSnVzdGlmeSBGdWxsIiA6ICLlhajpg6jkuKTnq6/lr7npvZAiLAogICAgICAgICJKdXN0aWZ5IFJpZ2h0IiA6ICLlj7Plr7npvZAiLAogICAgICAgICJNYXJnaW4gTGVmdCIgOiAi5bem6L656LedIiwKICAgICAgICAiTWFyZ2luIFJpZ2h0IiA6ICLlj7Povrnot50iLAogICAgICAgICJNYXJnaW4gVG9wIiA6ICLkuIrovrnot50iLAogICAgICAgICJNYXJnaW4gQm90dG9tIiA6ICLkuIvovrnot50iLAogICAgICAgICJCdWxsZXRlZCBMaXN0IiA6ICLpobnnm67nrKblj7fliJfooagiLAogICAgICAgICJOdW1iZXJlZCBMaXN0IiA6ICLnvJblj7fliJfooagiLAogICAgICAgICJVcHBlci1jYXNlIEFscGhhYmV0IExpc3QiIDogIuWkp+WGmeWtl+avjeWIl+ihqCIsCiAgICAgICAgIkxvd2VyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAi5bCP5YaZ5a2X5q+N5YiX6KGoIiwKICAgICAgICAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiA6ICLlpKflhpnnvZfpqazlrZfmr43liJfooagiLAogICAgICAgICJMb3dlci1jYXNlIFJvbWFuIExpc3QiIDogIuWwj+WGmee9l+mprOWtl+avjeWIl+ihqCIsCiAgICAgICAgIkluZGVudCIgOiAi57yp6L+bIiwKICAgICAgICAiT3V0ZGVudCIgOiAi5Y2H57qnIiwKICAgICAgICAiRmluZCAmIFJlcGxhY2UiIDogIuafpeaJvuWSjOabv+aNoiIsCiAgICAgICAgIkluc2VydCBMaW5rIiA6ICLmj5LlhaXpk77mjqUiLAogICAgICAgICJGaW5kIiA6ICLmn6Xmib4iLAogICAgICAgICJSZXBsYWNlIiA6ICLmm7/mjaIiLAogICAgICAgICJSZXBsYWNlIGFsbCIgOiAi5YWo6YOo5pu/5o2iIiwKICAgICAgICAiTWF0Y2ggY2FzZSIgOiAi5Yy65YiG5aSn5bCP5YaZIiwKICAgICAgICAiV2hvbGUgd29yZCIgOiAi5YWo5a2XIiwKICAgICAgICAiUmVnIEV4IiA6ICLmraPliJnooajovr7lvI8iLAogICAgICAgICJJbmZvIiA6ICLkv6Hmga8iLAogICAgICAgICJSZWFjaGVkIGVuZCBvZiBtb2R1bGUuIiA6ICLlt7LliLDmqKHlnZfmnKvlsL7jgIIiLAogICAgICAgICJNYXRjaCBOb3QgRm91bmQiIDogIuacquaJvuWIsOWMuemFjemhuSIsCiAgICAgICAgInswfSBtYXRjaGVzIHJlcGxhY2VkIiA6ICJ7MH0g5Liq5Yy56YWN6aG55bey5pu/5o2iIiwKICAgICAgICAiVGltZXMgTmV3IFJvbWFuIiA6ICJUaW1lcyBOZXcgUm9tYW4iLAogICAgICAgICJBcmlhbCIgOiAiQXJpYWwiLAogICAgICAgICJDb3VyaWVyIiA6ICJDb3VyaWVyIiwKICAgICAgICAiQ291cmllciBOZXciIDogIkNvdXJpZXIgTmV3IiwKICAgICAgICAiR2VuZXZhIiA6ICJHZW5ldmEiLAogICAgICAgICJHZW9yZ2lhIiA6ICJHZW9yZ2lhIiwKICAgICAgICAiSGVsdmV0aWNhIiA6ICJIZWx2ZXRpY2EiLAogICAgICAgICJUYWhvbWEiIDogIlRhaG9tYSIsCiAgICAgICAgIlRpbWVzIiA6ICJUaW1lcyIsCiAgICAgICAgIlZlcmRhbmEiIDogIlZlcmRhbmEiLAogICAgICAgICJOb25lIiA6ICLml6AiLAogICAgICAgICJIZWFkZXIgMSIgOiAi5qCH6aKYIDEiLAogICAgICAgICJIZWFkZXIgMiIgOiAi5qCH6aKYIDIiLAogICAgICAgICJIZWFkZXIgMyIgOiAi5qCH6aKYIDMiLAogICAgICAgICJIZWFkZXIgNCIgOiAi5qCH6aKYIDQiLAogICAgICAgICJIZWFkZXIgNSIgOiAi5qCH6aKYIDUiLAogICAgICAgICJIZWFkZXIgNiIgOiAi5qCH6aKYIDYiLAogICAgICAgICJTZWxlY3QiIDogIumAieaLqSIsCiAgICAgICAgIkJhc2ljIFZpZXciIDogIuWfuuacrOinhuWbviIsCiAgICAgICAgIkZ1bGxTY3JlZW4iIDogIuWFqOWxjyIsCiAgICAgICAgIkV4cGFuZCIgOiAi5bGV5byAIiwKICAgICAgICAiQ29sbGFwc2UiIDogIuaKmOWPoCIsCiAgICAgICAgIkxpc3QgVHlwZSIgOiAi5YiX6KGo57G75Z6LIiwKICAgICAgICAiVVJMIiA6ICJVUkwiLAogICAgICAgICJBbHQgVGV4dCIgOiAi5YiH5o2i5paH5pysIiwKICAgICAgICAiT3BlbiBpbiBuZXcgcGFnZSIgOiAi5Zyo5paw6aG16Z2i5Lit5omT5byAIgogICAgfTsKfSkoRm9ybS5ydGUuSTE4bik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiAyNC8xMC8yMDE2LgogKi8KCihmdW5jdGlvbiAoSTE4bikgewoKICAgIHZhciB6aFRXID0gSTE4bi56aFRXID0ge307CgogICAgemhUVy5zdHJpbmdzID0gewogICAgICAgICJVbmRvIiA6ICLlvqnljp8iLAogICAgICAgICJSZWRvIiA6ICLph43lgZoiLAogICAgICAgICJCb2xkIiA6ICLnspfpq5QiLAogICAgICAgICJJdGFsaWMiIDogIuaWnOmrlCIsCiAgICAgICAgIlVuZGVybGluZSIgOiAi5bqV57eaIiwKICAgICAgICAiU3VwZXItc2NyaXB0IiA6ICLkuIrmqJkiLAogICAgICAgICJTdWItc2NyaXB0IiA6ICLkuIvmqJkiLAogICAgICAgICJUZXh0IENvbG9yIiA6ICLmloflrZfoibLlvakiLAogICAgICAgICJIaWdobGlnaHQgQ29sb3IiIDogIuS6rumhr+mhj+iJsiIsCiAgICAgICAgIkZvbnQgRmFtaWx5IiA6ICLlrZflnovns7vliJciLAogICAgICAgICJGb250IFNpemUiIDogIuWtl+Wei+Wkp+WwjyIsCiAgICAgICAgIkxpbmUgSGVpZ2h0IiA6ICLooYzpq5giLAogICAgICAgICJMZXR0ZXIgU3BhY2luZyIgOiAi5a2X5q+N6ZaT6ZqUIiwKICAgICAgICAiUGFyYWdyYXBoIEZvcm1hdCIgOiAi5q616JC95qC85byPIiwKICAgICAgICAiSnVzdGlmeSBMZWZ0IiA6ICLlkJHlt6blsI3pvYoiLAogICAgICAgICJKdXN0aWZ5IENlbnRlciIgOiAi572u5Lit5bCN6b2KIiwKICAgICAgICAiSnVzdGlmeSBGdWxsIiA6ICLlt6blj7PlsI3pvYoiLAogICAgICAgICJKdXN0aWZ5IFJpZ2h0IiA6ICLlkJHlj7PlsI3pvYoiLAogICAgICAgICJNYXJnaW4gTGVmdCIgOiAi5bem6YKK6LedIiwKICAgICAgICAiTWFyZ2luIFJpZ2h0IiA6ICLlj7Ppgorot50iLAogICAgICAgICJNYXJnaW4gVG9wIiA6ICLkuIrpgorot50iLAogICAgICAgICJNYXJnaW4gQm90dG9tIiA6ICLkuIvpgorot50iLAogICAgICAgICJCdWxsZXRlZCBMaXN0IiA6ICLpoIXnm67nrKbomZ/muIXllq4iLAogICAgICAgICJOdW1iZXJlZCBMaXN0IiA6ICLnt6jomZ/muIXllq4iLAogICAgICAgICJVcHBlci1jYXNlIEFscGhhYmV0IExpc3QiIDogIuWkp+Wvq+Wtl+avjea4heWWriIsCiAgICAgICAgIkxvd2VyLWNhc2UgQWxwaGFiZXQgTGlzdCIgOiAi5bCP5a+r5a2X5q+N5riF5ZauIiwKICAgICAgICAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiA6ICLlpKflr6sgUm9tYW4g5a2X5riF5ZauIiwKICAgICAgICAiTG93ZXItY2FzZSBSb21hbiBMaXN0IiA6ICLlsI/lr6sgUm9tYW4g5riF5ZauIiwKICAgICAgICAiSW5kZW50IiA6ICLnuK7mjpIiLAogICAgICAgICJPdXRkZW50IiA6ICLlh7jmjpIiLAogICAgICAgICJGaW5kICYgUmVwbGFjZSIgOiAi5bCL5om+5ZKM5Y+W5LujIiwKICAgICAgICAiSW5zZXJ0IExpbmsiIDogIuaPkuWFpemAo+e1kCIsCiAgICAgICAgIkZpbmQiIDogIuWwi+aJviIsCiAgICAgICAgIlJlcGxhY2UiIDogIuabv+aPmyIsCiAgICAgICAgIlJlcGxhY2UgYWxsIiA6ICLlhajpg6jlj5bku6MiLAogICAgICAgICJNYXRjaCBjYXNlIiA6ICLnrKblkIjlpKflsI/lr6siLAogICAgICAgICJXaG9sZSB3b3JkIiA6ICLlhajlrZciLAogICAgICAgICJSZWcgRXgiIDogIuimj+WJh+mBi+eul+W8jyIsCiAgICAgICAgIkluZm8iIDogIuizh+ioiiIsCiAgICAgICAgIlJlYWNoZWQgZW5kIG9mIG1vZHVsZS4iIDogIuWIsOmBlOaooee1hOe1gum7nuOAgiIsCiAgICAgICAgIk1hdGNoIE5vdCBGb3VuZCIgOiAi5om+5LiN5Yiw55u456ym55qEIiwKICAgICAgICAiezB9IG1hdGNoZXMgcmVwbGFjZWQiIDogIuWPluS7o3swfeespuWQiOeahOmgheebriIsCiAgICAgICAgIlRpbWVzIE5ldyBSb21hbiIgOiAiVGltZXMgTmV3IFJvbWFuIiwKICAgICAgICAiQXJpYWwiIDogIkFyaWFsIiwKICAgICAgICAiQ291cmllciIgOiAiQ291cmllciIsCiAgICAgICAgIkNvdXJpZXIgTmV3IiA6ICJDb3VyaWVyIE5ldyIsCiAgICAgICAgIkdlbmV2YSIgOiAiR2VuZXZhIiwKICAgICAgICAiR2VvcmdpYSIgOiAiR2VvcmdpYSIsCiAgICAgICAgIkhlbHZldGljYSIgOiAiSGVsdmV0aWNhIiwKICAgICAgICAiVGFob21hIiA6ICJUYWhvbWEiLAogICAgICAgICJUaW1lcyIgOiAiVGltZXMiLAogICAgICAgICJWZXJkYW5hIiA6ICJWZXJkYW5hIiwKICAgICAgICAiTm9uZSIgOiAi54ShIiwKICAgICAgICAiSGVhZGVyIDEiIDogIumggemmliAxIiwKICAgICAgICAiSGVhZGVyIDIiIDogIumggemmliAyIiwKICAgICAgICAiSGVhZGVyIDMiIDogIumggemmliAzIiwKICAgICAgICAiSGVhZGVyIDQiIDogIumggemmliA0IiwKICAgICAgICAiSGVhZGVyIDUiIDogIumggemmliA1IiwKICAgICAgICAiSGVhZGVyIDYiIDogIumggemmliA2IiwKICAgICAgICAiU2VsZWN0IiA6ICLpgbjlj5YiLAogICAgICAgICJCYXNpYyBWaWV3IiA6ICLln7rmnKzmqqLoppYiLAogICAgICAgICJGdWxsU2NyZWVuIiA6ICLlhajonqLluZUiLAogICAgICAgICJFeHBhbmQiIDogIuWxlemWiyIsCiAgICAgICAgIkNvbGxhcHNlIiA6ICLmlLbnuK4iLAogICAgICAgICJMaXN0IFR5cGUiIDogIuWIl+ihqOmhnuWeiyIsCiAgICAgICAgIlVSTCIgOiAi57ay5Z2AIiwKICAgICAgICAiQWx0IFRleHQiIDogIuabv+S7o+aWh+WtlyIsCiAgICAgICAgIk9wZW4gaW4gbmV3IHBhZ2UiIDogIuWcqOaWsOeahOmggemdouS4remWi+WVnyIKICAgIH07Cn0pKEZvcm0ucnRlLkkxOG4pOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTYuIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKgogKiBDcmVhdGVkIGJ5IHJhbW5hbmkgb24gNy8yOC8yMDE2LgogKi8KCndpbmRvdy5Gb3JtID0gd2luZG93LkZvcm0gfHwge307CgpGb3JtLnJ0ZSA9IEZvcm0ucnRlIHx8IHt9OwoKRm9ybS5ydGUudXRpbCA9IEZvcm0ucnRlLnV0aWwgfHwge307CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiA4LzEvMjAxNi4KICovCihmdW5jdGlvbiAobnMpIHsKCiAgICB2YXIgUlRFVXRpbHMgPSBucy5SVEVVdGlscyA9IHt9OwoKICAgIFJURVV0aWxzLmlzSUUgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHVhID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7CiAgICAgICAgdmFyIG1zaWUgPSB1YS5pbmRleE9mKCdNU0lFICcpOwogICAgICAgIGlmIChtc2llID4gMCkgewogICAgICAgICAgICAvLyBJRSAxMCBvciBvbGRlciA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXIKICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KHVhLnN1YnN0cmluZyhtc2llICsgNSwgdWEuaW5kZXhPZignLicsIG1zaWUpKSwgMTApOwogICAgICAgIH0KICAgICAgICB2YXIgdHJpZGVudCA9IHVhLmluZGV4T2YoJ1RyaWRlbnQvJyk7CiAgICAgICAgaWYgKHRyaWRlbnQgPiAwKSB7CiAgICAgICAgICAgIC8vIElFIDExID0+IHJldHVybiB2ZXJzaW9uIG51bWJlcgogICAgICAgICAgICB2YXIgcnYgPSB1YS5pbmRleE9mKCdydjonKTsKICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KHVhLnN1YnN0cmluZyhydiArIDMsIHVhLmluZGV4T2YoJy4nLCBydikpLCAxMCk7CiAgICAgICAgfQogICAgICAgIHZhciBlZGdlID0gdWEuaW5kZXhPZignRWRnZS8nKTsKICAgICAgICBpZiAoZWRnZSA+IDApIHsKICAgICAgICAgICAgLy8gSUUgMTIgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyCiAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh1YS5zdWJzdHJpbmcoZWRnZSArIDUsIHVhLmluZGV4T2YoJy4nLCBlZGdlKSksIDEwKTsKICAgICAgICB9CiAgICAgICAgLy8gb3RoZXIgYnJvd3NlcgogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CiAgICBSVEVVdGlscy5hZGRTcGVjdHJ1bUdyYWRpZW50ID0gZnVuY3Rpb24gKHNlbGVjdG9yLCBjb2xvclZhbHVlKSB7CiAgICAgICAgaWYgKHNlbGVjdG9yKSB7CiAgICAgICAgICAgICQoc2VsZWN0b3IpLmNzcyh7ImJhY2tncm91bmQtaW1hZ2UiIDogIi13ZWJraXQtZ3JhZGllbnQobGluZWFyLCBsZWZ0IHRvcCwgcmlnaHQgdG9wLCBjb2xvci1zdG9wKDAsICNmZmYpLCBjb2xvci1zdG9wKC41LCAjIiArIGNvbG9yVmFsdWUgKyAiKSwgY29sb3Itc3RvcCgxLCAjMDAwKSkifSk7CiAgICAgICAgICAgICQoc2VsZWN0b3IpLmNzcyh7ImJhY2tncm91bmQtaW1hZ2UiIDogIi1tb3otbGluZWFyLWdyYWRpZW50KGxlZnQgY2VudGVyLCAjZmZmIDAsICMiICsgY29sb3JWYWx1ZSArICIgNTAlLCAjMDAwIDEwMCUpIn0pOwogICAgICAgICAgICAkKHNlbGVjdG9yKS5jc3MoeyJiYWNrZ3JvdW5kLWltYWdlIiA6ICItd2Via2l0LWxpbmVhci1ncmFkaWVudChsZWZ0LCAjZmZmIDAsICMiICsgY29sb3JWYWx1ZSArICIgNTAlLCAjMDAwIDEwMCUpIn0pOwogICAgICAgICAgICAkKHNlbGVjdG9yKS5jc3MoeyJiYWNrZ3JvdW5kLWltYWdlIiA6ICItby1saW5lYXItZ3JhZGllbnQobGVmdCwgI2ZmZiAwLCAjIiArIGNvbG9yVmFsdWUgKyAiIDUwJSwgIzAwMCAxMDAlKSJ9KTsKICAgICAgICAgICAgJChzZWxlY3RvcikuY3NzKHsiYmFja2dyb3VuZC1pbWFnZSIgOiAibGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCAjZmZmIDAsICMiICsgY29sb3JWYWx1ZSArICIgNTAlLCAjMDAwIDEwMCUpIn0pOwogICAgICAgICAgICAkKHNlbGVjdG9yKS5jc3MoeyJiYWNrZ3JvdW5kLXJlcGVhdCIgOiAicmVwZWF0LXgifSk7CiAgICAgICAgfQogICAgfTsKCn0pKEZvcm0ucnRlLnV0aWwpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTYuIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgooZnVuY3Rpb24gKG5zKSB7CiAgICB2YXIgU3RyaW5nSGVscGVyID0gbnMuU3RyaW5nSGVscGVyID0ge307CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGFueSBsZWFkaW5nIGFuZCB0cmFpbGluZyBzbGFzaGVzLCBlaXRoZXIgJy8nIG9yICdcJywgb24gdGhlIHNwZWNpZmllZCBzdHJpbmcuCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cmluZyBmcm9tIHdoaWNoIHNsYXNoZXMgYXJlIHRvIGJlIHRyaW1tZWQuCiAgICAgKiBAcmV0dXJuIFRoZSBvcmlnaW5hbCBzdHJpbmcgbGVzcyBhbnkgdHJhaWxpbmcgc2xhc2hlcy4KICAgICAqLwogICAgU3RyaW5nSGVscGVyLnRyaW1TbGFzaGVzID0gZnVuY3Rpb24gKHZhbHVlKSB7CgogICAgICAgIGlmICghdmFsdWUpIHsvLyBpZiBudWxsIG9yIGVtcHR5CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9CgogICAgICAgIHZhciBsZW4gPSB2YWx1ZS5sZW5ndGg7CgogICAgICAgIC8vIHJlbW92ZSBsZWFkaW5nIHNsYXNoZXMKICAgICAgICB2YXIgc3RhcnQgPSAwOyAvLyBtdXN0IGJlIGluZGV4IG9mIGZpcnN0IGNoYXJhY3RlciB0byBpbmNsdWRlCiAgICAgICAgdmFyIGMgPSB2YWx1ZS5jaGFyQXQoc3RhcnQpOwogICAgICAgIHdoaWxlIChjID09ICcvJyB8fCBjID09ICdcXCcpIHsKICAgICAgICAgICAgc3RhcnQrKzsKICAgICAgICAgICAgaWYgKHN0YXJ0ID49IGxlbikgewogICAgICAgICAgICAgICAgc3RhcnQgPSBsZW47CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjID0gdmFsdWUuY2hhckF0KHN0YXJ0KTsKICAgICAgICB9CiAgICAgICAgaWYgKHN0YXJ0ID49IGxlbikgey8vIGFsbCBzbGFzaGVzCiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9CgogICAgICAgIC8vIGF0IHRoaXMgcG9pbnQsIHRoZXJlJ3MgYXQgbGVhc3Qgb25lIGNoYXJhY3RlciB3ZSB3YW50IHRvIHJldGFpbgoKICAgICAgICAvLyByZW1vdmUgdHJhaWxpbmcgc2xhc2hlcwogICAgICAgIHZhciBlbmQgPSBsZW47IC8vIG11c3QgYmUgMSBtb3JlIHRoYW4gdGhlIGxhc3QgY2hhcmFjdGVyIHdlIHdhbnQgdG8gaW5jbHVkZQogICAgICAgIGMgPSB2YWx1ZS5jaGFyQXQoZW5kIC0gMSk7CiAgICAgICAgd2hpbGUgKGMgPT0gJy8nIHx8IGMgPT0gJ1xcJykgewogICAgICAgICAgICBlbmQtLTsKICAgICAgICAgICAgaWYgKGVuZCA8IDApIHsKICAgICAgICAgICAgICAgIGVuZCA9IDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYyA9IHZhbHVlLmNoYXJBdChlbmQgLSAxKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlLnN1YnN0cmluZyhzdGFydCwgZW5kKTsKICAgIH07CiAgICBTdHJpbmdIZWxwZXIucmVwZWF0ID0gZnVuY3Rpb24gKGMsIGNvdW50KSB7CiAgICAgICAgdmFyIHMgPSAiIjsKICAgICAgICBpZiAoYyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0KCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CiAgICAgICAgICAgIHMgKz0gYzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICB9OwogICAgLyoqCiAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGhhcyB0aGUgc3BlY2lmaWVkIHBvc3RmaXguCiAgICAgKiBAcGFyYW0gc3RyIFRoZSBzdHJpbmcgdG8gYmUgdmVyaWZpZWQuCiAgICAgKiBAcGFyYW0gcG9zdEZpeCBUaGUgcG9zdGZpeCB0byBzZWFyY2ggZm9yLgogICAgICogQHJldHVybiBUcnVlIGlmIHN0ciBoYXMgdGhlIHBvc3RmaXggc3BlY2lmaWVkOyB0cnVlIGlmIHBvc3RmaXggaXMgbnVsbC9lbXB0eSBzaW5jZSBhbnkgbm9uLW51bGwgc3RyaW5nIGNhbiBoYXZlIGFuIGVtcHR5IHBvc3RmaXg7CiAgICAgKiAgZmFsc2UgaWYgc3RyIGlzIG51bGwgb3IgZG9lcyBub3QgaGF2ZSB0aGUgc3BlY2lmaWVkIHBvc3RmaXguCiAgICAgKi8KICAgIFN0cmluZ0hlbHBlci5oYXNQb3N0Rml4ID0gZnVuY3Rpb24gKHN0ciwgcG9zdEZpeCkgewogICAgICAgIGlmIChzdHIgPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBpZiAoIXBvc3RGaXgpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSAvLyBhbnkgc3RyaW5nIGhhcyBhbiBlbXB0eSBwb3N0Zml4IQogICAgICAgIHJldHVybiAoc3RyLmluZGV4T2YocG9zdEZpeCkgPT0gKHN0ci5sZW5ndGggLSBwb3N0Rml4Lmxlbmd0aCkpOwogICAgfTsKCiAgICAvKioKICAgICAqIFRlc3RzIHRoZSBzdHJpbmcgdG8gc2VlIGlmIGl0IG9ubHkgY29udGFpbnMgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzLiBUaGlzIGlzIHNsaWdodGx5IGRpZmZlcmVudCBmcm9tCiAgICAgKiAgPGNvZGU+U3RyaW5nVXRpbC5pc1doaXRlc3BhY2UoKTwvY29kZT4gaW4gdGhhdCBpdCB0ZXN0cyBhbGwgY2hhcmFjdGVycywgbm90IGp1c3Qgb25lLgogICAgICogQHBhcmFtIHN0ciBUaGUgc3RyaW5nIHRvIHRlc3QuCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIHN0ciBpcyBtYWRlLXVwIGVudGlyZWx5IG9mIHdoaXRlc3BhY2U7IGZhbHNlIGlmIG5vdC4gTnVsbCBzdHJpbmdzIHdpbGwgcmVzdWx0IGluIHRydWUuCiAgICAgKi8KICAgIFN0cmluZ0hlbHBlci5pc1doaXRlc3BhY2UgPSBmdW5jdGlvbiAoc3RyKSB7CiAgICAgICAgaWYgKHN0ciA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RyLm1hdGNoKC9bXlxzXSsvZykgPT0gbnVsbDsgLy8gbWF0Y2hlcyBhdCBsZWFzdCBvbmUgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyIHNvIGlmIHRoZXJlJ3Mgbm8gbWF0Y2gsIGl0J3MgZW50aXJlbHkgd2hpdGVzcGFjZQogICAgfTsKCiAgICAvKioKICAgICAqIFN0cmV0Y2hlcyB0aGUgc3BlY2lmaWVkIHN0cmluZyB0byB0aGUgc3BlY2lmaWVkIGxlbmd0aCB1c2luZyB0aGUgc3BlY2lmaWVkIHBhZCBjaGFyYWN0ZXIuCiAgICAgKiBAcGFyYW0gc3RyIFRoZSBzdHJpbmcgdG8gc3RyZXRjaC4KICAgICAqIEBwYXJhbSBwYWQgVGhlIChzaW5nbGUpIGNoYXJhY3RlciB0byB1c2Ugd2hlbiBzdHJldGNoaW5nLgogICAgICogQHBhcmFtIGxlbmd0aCBUaGUgbGVuZ3RoIHRvIHN0cmV0Y2ggdG8uCiAgICAgKiBAcGFyYW0gcHJlZml4IFRydWUgaWYgdGhlIHBhZCBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIGxlZnQgKGJlZm9yZSB0aGUgY29udGVudHMgb2YgdGhlIHN0cmluZyk7IGZhbHNlIGlmIGl0IHNob3VsZCBiZSBhcHBlbmRlZAogICAgICogIHRvIHRoZSBlbmQgb2YgdGhlIGNvbnRlbnRzIG9mIHRoZSBzdHJpbmcuCiAgICAgKiBAcmV0dXJuIFRoZSBzdHJldGNoZWQgc3RyaW5nLiBJZiA8Y29kZT5zdHI8L2NvZGU+IGlzIG51bGwgb3IgZW1wdHksIGl0IHNpbXBseSBiZWNvbWVzIGEgc3RyaW5nIG9mIDxjb2RlPnBhZDwvY29kZT4gY2hhcmFjdGVycwogICAgICogIG9mIHRoZSBzcGVjaWZpZWQgPGNvZGU+bGVuZ3RoPC9jb2RlPi4KICAgICAqIEB0aHJvd3MgRXJyb3IgUGFkIG11c3QgYmUgYSBzaW5nbGUgY2hhcmFjdGVyLgogICAgICovCiAgICBTdHJpbmdIZWxwZXIuc3RyZXRjaCA9IGZ1bmN0aW9uIChzdHIsIHBhZCwgbGVuZ3RoLCBwcmVmaXgpIHsKICAgICAgICBpZiAoIXBhZCB8fCBsZW5ndGggPD0gMCkgewogICAgICAgICAgICByZXR1cm4gc3RyOwogICAgICAgIH0KCiAgICAgICAgaWYgKHBhZC5sZW5ndGggIT0gMSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoInBhZCBtdXN0IGJlIGEgc2luZ2xlIGNoYXJhY3RlcjogIiArIHBhZCk7CiAgICAgICAgfSAvLyBhc3NlcnQKICAgICAgICB2YXIgaSA9IDA7CiAgICAgICAgaWYgKHN0ciA9PSBudWxsKSB7CiAgICAgICAgICAgIHN0ciA9ICIiOwogICAgICAgICAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICBzdHIgKz0gcGFkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzdHI7CiAgICAgICAgfQogICAgICAgIGlmIChzdHIubGVuZ3RoID49IGxlbmd0aCkgewogICAgICAgICAgICByZXR1cm4gc3RyOwogICAgICAgIH0KICAgICAgICB2YXIgY291bnQgPSBsZW5ndGggLSBzdHIubGVuZ3RoOwogICAgICAgIGZvciAoOyBpIDwgY291bnQ7IGkrKykgewogICAgICAgICAgICBpZiAocHJlZml4KSB7CiAgICAgICAgICAgICAgICBzdHIgPSBwYWQgKyBzdHI7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzdHIgPSBzdHIgKyBwYWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN0cjsKICAgIH07CgogICAgLyoqCiAgICAgKiBSZXBsYWNlcyB0aGUgYWxsIHRoZSBvY2N1cmFuY2Ugb2YgdGFyZ2V0IHN0cmluZyB3aXRoIHJlcGxhY2VtZW50IHN0cmluZyBmb3IgYSBnaXZlbiBpbnB1dCBzdHJpbmcKICAgICAqIEBwYXJhbSBpbnB1dFN0cmluZyBUaGUgSW5wdXQgU3RyaW5nCiAgICAgKiBAcGFyYW0gdGFyZ2V0CiAgICAgKiBAcGFyYW0gcmVwbGFjZW1lbnQKICAgICAqIEByZXR1cm4KICAgICAqCiAgICAgKi8KICAgIFN0cmluZ0hlbHBlci5yZXBsYWNlQWxsID0gZnVuY3Rpb24gKGlucHV0U3RyaW5nLCB0YXJnZXQsIHJlcGxhY2VtZW50KSB7CiAgICAgICAgaWYgKGlucHV0U3RyaW5nID09IG51bGwgfHwgdGFyZ2V0ID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGlucHV0U3RyaW5nOwogICAgICAgIH0KICAgICAgICB2YXIgZXNjYXBlZFRhcmdldCA9IFN0cmluZ0hlbHBlci5lc2NhcGVSZWdleENoYXJzKHRhcmdldCk7CiAgICAgICAgdmFyIHBhdHRlcm4gPSBuZXcgUmVnRXhwKGVzY2FwZWRUYXJnZXQsICJnIik7CiAgICAgICAgdmFyIG5ld1N0cmluZyA9IGlucHV0U3RyaW5nLnJlcGxhY2UocGF0dGVybiwgcmVwbGFjZW1lbnQpOwogICAgICAgIHJldHVybiBuZXdTdHJpbmc7CiAgICB9OwoKICAgIFN0cmluZ0hlbHBlci5lc2NhcGVSZWdleENoYXJzID0gZnVuY3Rpb24gKHMpIHsKICAgICAgICB2YXIgbmV3U3RyaW5nID0gcy5yZXBsYWNlKG5ldyBSZWdFeHAoIihbe31cKFwpXF4kJi5cKlw/XC9cK1x8XFtcXFxcXXxcXXxcLSkiLCAiZyIpLCAiXFwkMSIpOwogICAgICAgIHJldHVybiBuZXdTdHJpbmc7CiAgICB9OwoKICAgIFN0cmluZ0hlbHBlci5yZXN0cmljdCA9IGZ1bmN0aW9uIChzdHIsIHJlc3RyaWN0KSB7CiAgICAgICAgLy8gQSBudWxsICdyZXN0cmljdCcgc3RyaW5nIG1lYW5zIGFsbCBjaGFyYWN0ZXJzIGFyZSBhbGxvd2VkLgogICAgICAgIGlmIChyZXN0cmljdCA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBzdHI7CiAgICAgICAgfQoKICAgICAgICAvLyBBbiBlbXB0eSAncmVzdHJpY3QnIHN0cmluZyBtZWFucyBubyBjaGFyYWN0ZXJzIGFyZSBhbGxvd2VkLgogICAgICAgIGlmIChyZXN0cmljdCA9PSAiIikgewogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQogICAgICAgIC8vIE90aGVyd2lzZSwgd2UgbmVlZCB0byB0ZXN0IGVhY2ggY2hhcmFjdGVyIGluICdzdHInCiAgICAgICAgLy8gdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlICdyZXN0cmljdCcgc3RyaW5nIGFsbG93cyBpdC4KICAgICAgICB2YXIgY2hhckNvZGVzID0gW107CgogICAgICAgIHZhciBuID0gc3RyLmxlbmd0aDsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG47IGkrKykgewogICAgICAgICAgICB2YXIgY2hhckNvZGUgPSBzdHIuY2hhckNvZGVBdChpKTsKICAgICAgICAgICAgaWYgKFN0cmluZ0hlbHBlci50ZXN0Q2hhcmFjdGVyKGNoYXJDb2RlLCByZXN0cmljdCkpIHsKICAgICAgICAgICAgICAgIGNoYXJDb2Rlcy5wdXNoKGNoYXJDb2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBjaGFyQ29kZXMpOwogICAgfTsKCiAgICBTdHJpbmdIZWxwZXIudGVzdENoYXJhY3RlciA9IGZ1bmN0aW9uIChjaGFyQ29kZSwgcmVzdHJpY3QpIHsKICAgICAgICB2YXIgYWxsb3dJdCA9IGZhbHNlOwogICAgICAgIHZhciBpbkJhY2tTbGFzaCA9IGZhbHNlOwogICAgICAgIHZhciBpblJhbmdlID0gZmFsc2U7CiAgICAgICAgdmFyIHNldEZsYWcgPSB0cnVlOwogICAgICAgIHZhciBsYXN0Q29kZSA9IDA7CiAgICAgICAgdmFyIG4gPSByZXN0cmljdC5sZW5ndGg7CiAgICAgICAgdmFyIGNvZGU7CgogICAgICAgIGlmIChuID4gMCkgewogICAgICAgICAgICBjb2RlID0gcmVzdHJpY3QuY2hhckNvZGVBdCgwKTsKICAgICAgICAgICAgaWYgKGNvZGUgPT0gOTQpIHsvLyBjYXJldAogICAgICAgICAgICAgICAgYWxsb3dJdCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICAgICAgY29kZSA9IHJlc3RyaWN0LmNoYXJDb2RlQXQoaSk7CiAgICAgICAgICAgIHZhciBhY2NlcHRDb2RlID0gZmFsc2U7CiAgICAgICAgICAgIGlmICghaW5CYWNrU2xhc2gpIHsKICAgICAgICAgICAgICAgIGlmIChjb2RlID09IDQ1KSB7Ly8gaHlwaGVuCiAgICAgICAgICAgICAgICAgICAgaW5SYW5nZSA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvZGUgPT0gOTQpIHsvLyBjYXJldAogICAgICAgICAgICAgICAgICAgIHNldEZsYWcgPSAhc2V0RmxhZzsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY29kZSA9PSA5Mikgey8vIGJhY2tzbGFzaAogICAgICAgICAgICAgICAgICAgIGluQmFja1NsYXNoID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYWNjZXB0Q29kZSA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhY2NlcHRDb2RlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGluQmFja1NsYXNoID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGFjY2VwdENvZGUpIHsKICAgICAgICAgICAgICAgIGlmIChpblJhbmdlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RDb2RlIDw9IGNoYXJDb2RlICYmIGNoYXJDb2RlIDw9IGNvZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWxsb3dJdCA9IHNldEZsYWc7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGluUmFuZ2UgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBsYXN0Q29kZSA9IDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSBjb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93SXQgPSBzZXRGbGFnOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBsYXN0Q29kZSA9IGNvZGU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFsbG93SXQ7CiAgICB9OwoKICAgIFN0cmluZ0hlbHBlci5lbmRzV2l0aCA9IGZ1bmN0aW9uIChzdHIsIHN1ZmZpeCkgewogICAgICAgIGlmIChzdHIgJiYgc3VmZml4ICYmIHN0ci5pbmRleE9mKHN1ZmZpeCwgc3RyLmxlbmd0aCAtIHN1ZmZpeC5sZW5ndGgpICE9PSAtMSkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfTsKCiAgICBTdHJpbmdIZWxwZXIuc3RhcnRzV2l0aCA9IGZ1bmN0aW9uIChzdHIsIHByZWZpeCkgewogICAgICAgIGlmIChzdHIgJiYgcHJlZml4ICYmIHN0ci5pbmRleE9mKHByZWZpeCkgPT09IDApIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH07Cgp9KShGb3JtLnJ0ZS51dGlsKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdmFyIFhmYUVsZW0sIFhmYVhodG1sLCBYZmFTY2hlbWEsIFhmYUF0dCwgWGZhVmFsOwoKdmFyIFhmYURhdGE7Cgp2YXIgWGZhTWltZVR5cGU7Cgp2YXIgWGZhRGF0YUVsZW07CgpYZmFEYXRhRWxlbSA9IEZvcm0ucnRlLnV0aWwuWGZhRGF0YUVsZW0gPSB7fTsKWGZhRGF0YUVsZW0uREFUQVNFVFMgPSAiZGF0YXNldHMiOwpYZmFEYXRhRWxlbS5EQVRBID0gImRhdGEiOwpYZmFEYXRhRWxlbS5fZWxlbVRhZ01hcCA9IG51bGw7ClhmYURhdGFFbGVtLmlzRWxlbWVudCA9IGZ1bmN0aW9uIChlbGVtVGFnKSB7CiAgICAvLyBjcmVhdGUgb24gZmlyc3QgdXNlCiAgICBpZiAoIVhmYURhdGFFbGVtLl9lbGVtVGFnTWFwKSB7CgogICAgICAgIFhmYURhdGFFbGVtLl9lbGVtVGFnTWFwID0ge307CiAgICAgICAgdmFyIGVsZW1lbnQsIHN0YXRpY0NvbnN0TGlzdCA9IE9iamVjdC5rZXlzKFhmYURhdGFFbGVtKTsKCiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IHN0YXRpY0NvbnN0TGlzdC5sZW5ndGg7IGluZGV4KyspIHsKICAgICAgICAgICAgZWxlbWVudCA9IHN0YXRpY0NvbnN0TGlzdFtpbmRleF07CiAgICAgICAgICAgIC8vIGVsZW1lbnQgbWVtYmVycyBhcmUgZXhwZWN0ZWQgbm90IHRvIGhhdmUgYW55IHVuZGVyc2NvcmVzIGluIHRoZWlyIG5hbWVzCiAgICAgICAgICAgIGlmIChlbGVtZW50LmluZGV4T2YoIl8iKSA8IDAgJiYgdHlwZW9mIFhmYURhdGFFbGVtW2VsZW1lbnRdID09ICJzdHJpbmciKSB7CiAgICAgICAgICAgICAgICBYZmFEYXRhRWxlbS5fZWxlbVRhZ01hcFtYZmFEYXRhRWxlbVtlbGVtZW50XV0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIChlbGVtVGFnIGluIFhmYURhdGFFbGVtLl9lbGVtVGFnTWFwKTsKfTsKClhmYURhdGEgPSBGb3JtLnJ0ZS51dGlsLlhmYURhdGEgPSB7fTsKWGZhRGF0YS5YRkFEQVRBTlNVUkkgPSAiaHR0cDovL3d3dy54ZmEub3JnL3NjaGVtYS94ZmEtZGF0YS8xLjAvIjsKClhmYU1pbWVUeXBlID0gRm9ybS5ydGUudXRpbC5YZmFNaW1lVHlwZSA9IHt9OwpYZmFNaW1lVHlwZS5KUEVHID0gImltYWdlL2pwZyI7Ci8qKiBNSU1FIHR5cGUgZm9yIFRJRkYgaW1hZ2VzLiAqLwpYZmFNaW1lVHlwZS5USUZGID0gImltYWdlL3RpZiI7Ci8qKiBNSU1FIHR5cGUgZm9yIEdJRiBpbWFnZXMuICovClhmYU1pbWVUeXBlLkdJRiA9ICJpbWFnZS9naWYiOwovKiogTUlNRSB0eXBlIGZvciBiaXRtYXAgaW1hZ2VzLiAqLwpYZmFNaW1lVHlwZS5CTVAgPSAiaW1hZ2UvYm1wIjsKLyoqIE1JTUUgdHlwZSBmb3IgUE5HIGltYWdlcyAob25seSBpbmRleGVkIFBOR3Mgd2l0aCBvbmUgdHJhbnNwYXJlbnQgY29sb3IgYXJlIHN1cHBvcnRlZCBpbiBYRkEgZm9ybXMpLiAqLwpYZmFNaW1lVHlwZS5QTkcgPSAiaW1hZ2UvcG5nIjsKLyoqIE1JTUUgdHlwZSBmb3IgcGxhaW4gdGV4dC4gKi8KWGZhTWltZVR5cGUuUExBSU5URVhUID0gInRleHQvcGxhaW4iOwovKiogTUlNRSB0eXBlIGZvciByaWNoIHRleHQuICovClhmYU1pbWVUeXBlLlJJQ0hURVhUID0gInRleHQvaHRtbCI7Ci8qKiBNSU1FIHR5cGUgZm9yIHhtbCB0ZXh0LiAqLwpYZmFNaW1lVHlwZS5YTUxURVhUID0gInRleHQveG1sIjsKClhmYVhodG1sID0gRm9ybS5ydGUudXRpbC5YZmFYaHRtbCA9IHt9OwpYZmFYaHRtbC5YSFRNTE5TVVJJID0gImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwiOwovKiogQVhURSBBUEkgVmVyc2lvbiB1c2VkIGluIFhGQSBYSFRNTCAmbHQ7Ym9keSZndDsgdGFnIChjdXJyZW50bHkgc2V0IHRvIHRoYXQgd2hpY2ggaXMgdXNlZCB3aXRoIExpdmVDeWNsZSBFUyBVcGRhdGUgMSAoRGVzaWduZXIgOC4yKSkuICovClhmYVhodG1sLkFYVEVBUElWRVJTSU9OID0gIjIuNy4wLjAiOwoKLyoqIFRoZSByb290IG5vZGUgb2YgWEZBIHJpY2ggdGV4dCAoWEhUTUwpIGFzIHNldCBpbiByaWNoIHRleHQgZHJhd3MgYW5kIGZpZWxkcy4gVGhlIGVudGlyZSByaWNoIHRleHQgdmFsdWUgaXMgY29udGFpbmVkIHdpdGhpbiBhICZsdDtib2R5Jmd0OyBlbGVtZW50LiAqLwpYZmFYaHRtbC5CT0RZID0gImJvZHkiOwoKLyoqIFNwYWNlcnVuIHN0eWxlIG5hbWUuICovClhmYVhodG1sLlNQQUNFUlVOU1RZTEVOQU1FID0gInhmYS1zcGFjZXJ1biI7Ci8qKiBTcGFjZXJ1biBzdHlsZSB2YWx1ZS4gKi8KWGZhWGh0bWwuU1BBQ0VSVU5TVFlMRVZBTFVFID0gInllcyI7Ci8qKiBTcGFjZXJ1biBzdHlsZSAobmFtZTp2YWx1ZSkuICovClhmYVhodG1sLlNQQUNFUlVOU1RZTEUgPSBYZmFYaHRtbC5TUEFDRVJVTlNUWUxFTkFNRSArICc6JyArIFhmYVhodG1sLlNQQUNFUlVOU1RZTEVWQUxVRTsKLyoqIFNwYWNlcnVuIG9wZW5pbmcgdGFnLiAqLwpYZmFYaHRtbC5TUEFDRVJVTk9QRU4gPSAnPHNwYW4gc3R5bGU9IicgKyBYZmFYaHRtbC5TUEFDRVJVTlNUWUxFICsgJyI+JzsKLyoqIFNwYWNlcnVuIGNsb3NpbmcgdGFnLiAqLwpYZmFYaHRtbC5TUEFDRVJVTkNMT1NFID0gJzwvc3Bhbj4nOwpYZmFFbGVtID0gRm9ybS5ydGUudXRpbC5YZmFFbGVtID0ge307ClhmYUVsZW0uQVBQRUFSQU5DRUZJTFRFUiA9ICJhcHBlYXJhbmNlRmlsdGVyIjsKWGZhRWxlbS5BUkMgPSAiYXJjIjsKWGZhRWxlbS5BUkVBID0gImFyZWEiOwpYZmFFbGVtLkJBUkNPREUgPSAiYmFyY29kZSI7ClhmYUVsZW0uQklORCA9ICJiaW5kIjsKWGZhRWxlbS5CT09MRUFOID0gImJvb2xlYW4iOwpYZmFFbGVtLkJPUkRFUiA9ICJib3JkZXIiOwpYZmFFbGVtLkJVVFRPTiA9ICJidXR0b24iOwpYZmFFbGVtLkNBUFRJT04gPSAiY2FwdGlvbiI7ClhmYUVsZW0uQ0VSVElGSUNBVEUgPSAiY2VydGlmaWNhdGUiOwpYZmFFbGVtLkNIRUNLQlVUVE9OID0gImNoZWNrQnV0dG9uIjsKWGZhRWxlbS5DSE9JQ0VMSVNUID0gImNob2ljZUxpc3QiOwpYZmFFbGVtLkNPTE9SID0gImNvbG9yIjsKWGZhRWxlbS5DT05URU5UQVJFQSA9ICJjb250ZW50QXJlYSI7ClhmYUVsZW0uREFURSA9ICJkYXRlIjsKWGZhRWxlbS5EQVRFVElNRSA9ICJkYXRlVGltZSI7ClhmYUVsZW0uREFURVRJTUVFRElUID0gImRhdGVUaW1lRWRpdCI7ClhmYUVsZW0uREVDSU1BTCA9ICJkZWNpbWFsIjsKWGZhRWxlbS5ERUZBVUxUVUkgPSAiZGVmYXVsdFVpIjsKWGZhRWxlbS5ESUdFU1RNRVRIT0QgPSAiZGlnZXN0TWV0aG9kIjsKWGZhRWxlbS5EUkFXID0gImRyYXciOwpYZmFFbGVtLkVER0UgPSAiZWRnZSI7ClhmYUVsZW0uRU5DT0RJTkcgPSAiZW5jb2RpbmciOwpYZmFFbGVtLkVYQ0xHUk9VUCA9ICJleGNsR3JvdXAiOwpYZmFFbGVtLkVYREFUQSA9ICJleERhdGEiOwpYZmFFbGVtLkVYT0JKRUNUID0gImV4T2JqZWN0IjsKWGZhRWxlbS5FVkVOVCA9ICJldmVudCI7ClhmYUVsZW0uRVhFQ1VURSA9ICJleGVjdXRlIjsKWGZhRWxlbS5GSUVMRCA9ICJmaWVsZCI7ClhmYUVsZW0uRklMTCA9ICJmaWxsIjsKWGZhRWxlbS5GTE9BVCA9ICJmbG9hdCI7ClhmYUVsZW0uRk9OVCA9ICJmb250IjsKWGZhRWxlbS5IQU5ETEVSID0gImhhbmRsZXIiOwpYZmFFbGVtLklNQUdFID0gImltYWdlIjsKWGZhRWxlbS5JTUFHRUVESVQgPSAiaW1hZ2VFZGl0IjsKWGZhRWxlbS5JTlRFR0VSID0gImludGVnZXIiOwpYZmFFbGVtLklURU1TID0gIml0ZW1zIjsKWGZhRWxlbS5LRUVQID0gImtlZXAiOwpYZmFFbGVtLkxJTkUgPSAibGluZSI7ClhmYUVsZW0uTElORUFSID0gImxpbmVhciI7ClhmYUVsZW0uTE9DS0RPQ1VNRU5UID0gImxvY2tEb2N1bWVudCI7ClhmYUVsZW0uTUFSR0lOID0gIm1hcmdpbiI7ClhmYUVsZW0uTUVESVVNID0gIm1lZGl1bSI7ClhmYUVsZW0uTlVNRVJJQ0VESVQgPSAibnVtZXJpY0VkaXQiOwpYZmFFbGVtLk9JRCA9ICJvaWQiOwpYZmFFbGVtLlBBR0VBUkVBID0gInBhZ2VBcmVhIjsKWGZhRWxlbS5QQUdFU0VUID0gInBhZ2VTZXQiOwpYZmFFbGVtLlBBUkEgPSAicGFyYSI7ClhmYUVsZW0uUEFTU1dPUkRFRElUID0gInBhc3N3b3JkRWRpdCI7ClhmYUVsZW0uUEFUVEVSTiA9ICJwYXR0ZXJuIjsKWGZhRWxlbS5QSUNUVVJFID0gInBpY3R1cmUiOwpYZmFFbGVtLlJBRElBTCA9ICJyYWRpYWwiOwpYZmFFbGVtLlJFQ1RBTkdMRSA9ICJyZWN0YW5nbGUiOwpYZmFFbGVtLlJFQVNPTiA9ICJyZWFzb24iOwpYZmFFbGVtLlJFRiA9ICJyZWYiOwpYZmFFbGVtLlNDUklQVCA9ICJzY3JpcHQiOwpYZmFFbGVtLlNJR05BVFVSRSA9ICJzaWduYXR1cmUiOwpYZmFFbGVtLlNJR05EQVRBID0gInNpZ25EYXRhIjsKWGZhRWxlbS5TT0xJRCA9ICJzb2xpZCI7ClhmYUVsZW0uU1BFQUsgPSAic3BlYWsiOwpYZmFFbGVtLlNUSVBQTEUgPSAic3RpcHBsZSI7ClhmYUVsZW0uU1VCRk9STSA9ICJzdWJmb3JtIjsKWGZhRWxlbS5TVUJGT1JNU0VUID0gInN1YmZvcm1TZXQiOwpYZmFFbGVtLlNVQkpFQ1RETiA9ICJzdWJqZWN0RE4iOwpYZmFFbGVtLlNVQk1JVCA9ICJzdWJtaXQiOwpYZmFFbGVtLlRFTVBMQVRFID0gInRlbXBsYXRlIjsKWGZhRWxlbS5URVhUID0gInRleHQiOwpYZmFFbGVtLlRFWFRFRElUID0gInRleHRFZGl0IjsKWGZhRWxlbS5USU1FID0gInRpbWUiOwpYZmFFbGVtLlRPT0xUSVAgPSAidG9vbFRpcCI7ClhmYUVsZW0uVUkgPSAidWkiOwpYZmFFbGVtLlZBTFVFID0gInZhbHVlIjsKWGZhRWxlbS5WQVJJQUJMRVMgPSAidmFyaWFibGVzIjsKWGZhRWxlbS5fZWxlbVRhZ01hcCA9IG51bGw7CgovKioKICogRGV0ZXJtaW5lcyBpZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgbmFtZSBpcyBhIHZhbGlkIFhGQSBUZW1wbGF0ZSBlbGVtZW50IG5hbWUuCiAqIEBwYXJhbSBlbGVtVGFnIFRoZSBuYW1lIHRvIHRlc3QuCiAqIEByZXR1cm4gVHJ1ZSBpZiBpdCdzIGFuIFhGQSBUZW1wbGF0ZSBlbGVtZW50IG5hbWU7IGZhbHNlIGlmIG5vdC4KICovClhmYUVsZW0uaXNFbGVtZW50ID0gZnVuY3Rpb24gKGVsZW1UYWcpIHsKICAgIC8vIGNyZWF0ZSBvbiBmaXJzdCB1c2UKICAgIGlmICghWGZhRWxlbS5fZWxlbVRhZ01hcCkgewogICAgICAgIFhmYUVsZW0uX2VsZW1UYWdNYXAgPSB7fTsKICAgICAgICB2YXIgZWxlbWVudCwgc3RhdGljQ29uc3RMaXN0ID0gT2JqZWN0LmtleXMoWGZhRWxlbSk7CiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IHN0YXRpY0NvbnN0TGlzdC5sZW5ndGg7IGluZGV4KyspIHsKICAgICAgICAgICAgZWxlbWVudCA9IHN0YXRpY0NvbnN0TGlzdFtpbmRleF07CiAgICAgICAgICAgIC8vIGVsZW1lbnQgbWVtYmVycyBhcmUgZXhwZWN0ZWQgbm90IHRvIGhhdmUgYW55IHVuZGVyc2NvcmVzIGluIHRoZWlyIG5hbWVzCiAgICAgICAgICAgIGlmIChlbGVtZW50LmluZGV4T2YoIl8iKSA8IDAgJiYgdHlwZW9mIFhmYUVsZW1bZWxlbWVudF0gPT0gInN0cmluZyIpIHsKICAgICAgICAgICAgICAgIFhmYUVsZW0uX2VsZW1UYWdNYXBbWGZhRWxlbVtlbGVtZW50XV0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIChlbGVtVGFnIGluIFhmYUVsZW0uX2VsZW1UYWdNYXApOwp9OwoKWGZhQXR0ID0gRm9ybS5ydGUudXRpbC5YZmFBdHQgPSB7fTsKClhmYUF0dC5BQ1RJVklUWSA9ICJhY3Rpdml0eSI7ClhmYUF0dC5BU1BFQ1QgPSAiYXNwZWN0IjsKWGZhQXR0LkFMTE9XUklDSFRFWFQgPSAiYWxsb3dSaWNoVGV4dCI7ClhmYUF0dC5CT1RUT01JTlNFVCA9ICJib3R0b21JbnNldCI7ClhmYUF0dC5DT01NSVRPTiA9ICJjb21taXRPbiI7ClhmYUF0dC5DT05URU5UVFlQRSA9ICJjb250ZW50VHlwZSI7ClhmYUF0dC5IID0gImgiOwpYZmFBdHQuSFJFRiA9ICJocmVmIjsKWGZhQXR0LklEID0gImlkIjsKWGZhQXR0LklOVEFDVCA9ICJpbnRhY3QiOwpYZmFBdHQuTEFZT1VUID0gImxheW91dCI7ClhmYUF0dC5MRUZUSU5TRVQgPSAibGVmdEluc2V0IjsKWGZhQXR0LkxPTkcgPSAibG9uZyI7ClhmYUF0dC5NQVJHSU5MRUZUID0gIm1hcmdpbkxlZnQiOwpYZmFBdHQuTUFSR0lOUklHSFQgPSAibWFyZ2luUmlnaHQiOwpYZmFBdHQuTUFUQ0ggPSAibWF0Y2giOwpYZmFBdHQuTUFYQ0hBUlMgPSAibWF4Q2hhcnMiOwpYZmFBdHQuTUFYSCA9ICJtYXhIIjsKWGZhQXR0Lk1BWExFTkdUSCA9ICJtYXhMZW5ndGgiOwpYZmFBdHQuTUFYVyA9ICJtYXhXIjsKWGZhQXR0Lk1JTkggPSAibWluSCI7ClhmYUF0dC5NSU5XID0gIm1pblciOwpYZmFBdHQuTVVMVElMSU5FID0gIm11bHRpTGluZSI7ClhmYUF0dC5OQU1FID0gIm5hbWUiOwpYZmFBdHQuT1BFTiA9ICJvcGVuIjsKWGZhQXR0Lk9SSUVOVEFUSU9OID0gIm9yaWVudGF0aW9uIjsKWGZhQXR0LlBBR0VQT1NJVElPTiA9ICJwYWdlUG9zaXRpb24iOwpYZmFBdHQuUExBQ0VNRU5UID0gInBsYWNlbWVudCI7ClhmYUF0dC5QUkVTRU5DRSA9ICJwcmVzZW5jZSI7ClhmYUF0dC5SRUYgPSAicmVmIjsKWGZhQXR0LlJFTEFUSU9OID0gInJlbGF0aW9uIjsKWGZhQXR0LlJFU0VSVkUgPSAicmVzZXJ2ZSI7ClhmYUF0dC5SSUdIVElOU0VUID0gInJpZ2h0SW5zZXQiOwpYZmFBdHQuUlVOQVQgPSAicnVuQXQiOwpYZmFBdHQuU0FWRSA9ICJzYXZlIjsKWGZhQXR0LlNIT1JUID0gInNob3J0IjsKWGZhQXR0LlNJWkUgPSAic2l6ZSI7ClhmYUF0dC5TUEFDRUFCT1ZFID0gInNwYWNlQWJvdmUiOwpYZmFBdHQuU1BBQ0VCRUxPVyA9ICJzcGFjZUJlbG93IjsKWGZhQXR0LlNUT0NLID0gInN0b2NrIjsKWGZhQXR0LlNUUk9LRSA9ICJzdHJva2UiOwpYZmFBdHQuVEVYVEVOVFJZID0gInRleHRFbnRyeSI7ClhmYUF0dC5UT1BJTlNFVCA9ICJ0b3BJbnNldCI7ClhmYUF0dC5UWVBFRkFDRSA9ICJ0eXBlZmFjZSI7ClhmYUF0dC5VU0UgPSAidXNlIjsKWGZhQXR0LlVTRUhSRUYgPSAidXNlaHJlZiI7ClhmYUF0dC5WQUxJR04gPSAidkFsaWduIjsKWGZhQXR0LlZBTFVFID0gInZhbHVlIjsKWGZhQXR0LldFSUdIVCA9ICJ3ZWlnaHQiOwpYZmFBdHQuVyA9ICJ3IjsKWGZhQXR0LlggPSAieCI7ClhmYUF0dC5ZID0gInkiOwovKiogTWFwIG9mIGF0dHJpYnV0ZSBuYW1lcyAoc3RyaW5nIHZhbHVlcyBvZiBzdGF0aWMgYXR0cmlidXRlIGNvbnN0YW50IG1lbWJlcnMgb2YgWGZhQXR0KSB0byBhbiBhcy15ZXQgdW51c2VkIHZhbHVlLiAqLwpYZmFBdHQuX2F0dFRhZ01hcCA9IG51bGw7ClhmYUF0dC5pc0F0dHJpYnV0ZSA9IGZ1bmN0aW9uIChhdHRUYWcpIHsKICAgIC8vIGNyZWF0ZSBvbiBmaXJzdCB1c2UKICAgIGlmICghWGZhQXR0Ll9hdHRUYWdNYXApIHsKICAgICAgICBYZmFBdHQuX2F0dFRhZ01hcCA9IHt9OwogICAgICAgIHZhciBlbGVtZW50LCBzdGF0aWNDb25zdExpc3QgPSBPYmplY3Qua2V5cyhYZmFBdHQpOwogICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggPCBzdGF0aWNDb25zdExpc3QubGVuZ3RoOyBpbmRleCsrKSB7CiAgICAgICAgICAgIGVsZW1lbnQgPSBzdGF0aWNDb25zdExpc3RbaW5kZXhdOwogICAgICAgICAgICAvLyBlbGVtZW50IG1lbWJlcnMgYXJlIGV4cGVjdGVkIG5vdCB0byBoYXZlIGFueSB1bmRlcnNjb3JlcyBpbiB0aGVpciBuYW1lcwogICAgICAgICAgICBpZiAoZWxlbWVudC5pbmRleE9mKCJfIikgPCAwICYmIHR5cGVvZiBYZmFBdHRbZWxlbWVudF0gPT0gInN0cmluZyIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2F0dFRhZ01hcFtYZmFBdHRbZWxlbWVudF1dID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAoYXR0VGFnIGluIHRoaXMuX2F0dFRhZ01hcCk7Cn07CgpYZmFWYWwgPSBGb3JtLnJ0ZS51dGlsLlhmYVZhbCA9IHt9OwoKWGZhVmFsLkFDVFVBTCA9ICJhY3R1YWwiOwpYZmFWYWwuQUxXQVlTID0gImFsd2F5cyI7ClhmYVZhbC5BTlkgPSAiYW55IjsKWGZhVmFsLkFQUFhGT1JNQ0FMQyA9ICJhcHBsaWNhdGlvbi94LWZvcm1jYWxjIjsKWGZhVmFsLkFQUFhKQVZBU0NSSVBUID0gImFwcGxpY2F0aW9uL3gtamF2YXNjcmlwdCI7ClhmYVZhbC5CT0xEID0gImJvbGQiOwpYZmFWYWwuQk9USCA9ICJib3RoIjsKWGZhVmFsLkJPVFRPTSA9ICJib3R0b20iOwpYZmFWYWwuQ0hBTkdFID0gImNoYW5nZSI7ClhmYVZhbC5DTElDSyA9ICJjbGljayI7ClhmYVZhbC5DTElFTlQgPSAiY2xpZW50IjsKWGZhVmFsLkNPTlRFTlRBUkVBID0gImNvbnRlbnRBcmVhIjsKWGZhVmFsLkRBU0hET1QgPSAiZGFzaERvdCI7ClhmYVZhbC5EQVNIRE9URE9UID0gImRhc2hEb3REb3QiOwpYZmFWYWwuREFTSEVEID0gImRhc2hlZCI7ClhmYVZhbC5EQVRBUkVGID0gImRhdGFSZWYiOwpYZmFWYWwuRE9DQ0xPU0UgPSAiZG9jQ2xvc2UiOwpYZmFWYWwuRE9DUkVBRFkgPSAiZG9jUmVhZHkiOwpYZmFWYWwuRE9UVEVEID0gImRvdHRlZCI7ClhmYVZhbC5FTUJPU1NFRCA9ICJlbWJvc3NlZCI7ClhmYVZhbC5FTlRFUiA9ICJlbnRlciI7ClhmYVZhbC5FVENIRUQgPSAiZXRjaGVkIjsKWGZhVmFsLkVYSVQgPSAiZXhpdCI7ClhmYVZhbC5GSVJTVCA9ICJmaXJzdCI7ClhmYVZhbC5GSVQgPSAiZml0IjsKWGZhVmFsLkZVTEwgPSAiZnVsbCI7ClhmYVZhbC5HTE9CQUwgPSAiZ2xvYmFsIjsKWGZhVmFsLkhFSUdIVCA9ICJoZWlnaHQiOwpYZmFWYWwuSElEREVOID0gImhpZGRlbiI7ClhmYVZhbC5JTkRFWENIQU5HRSA9ICJpbmRleENoYW5nZSI7ClhmYVZhbC5JTklUSUFMSVpFID0gImluaXRpYWxpemUiOwpYZmFWYWwuSU5MSU5FID0gImlubGluZSI7ClhmYVZhbC5JTlZJU0lCTEUgPSAiaW52aXNpYmxlIjsKWGZhVmFsLkxBTkRTQ0FQRSA9ICJsYW5kc2NhcGUiOwpYZmFWYWwuTEFTVCA9ICJsYXN0IjsKWGZhVmFsLkxFRlQgPSAibGVmdCI7ClhmYVZhbC5MRVRURVIgPSAibGV0dGVyIjsKWGZhVmFsLkxPV0VSRUQgPSAibG93ZXJlZCI7ClhmYVZhbC5MUlRCID0gImxyLXRiIjsKWGZhVmFsLk1JRERMRSA9ICJtaWRkbGUiOwpYZmFWYWwuTU9VU0VET1dOID0gIm1vdXNlRG93biI7ClhmYVZhbC5NT1VTRUVOVEVSID0gIm1vdXNlRW50ZXIiOwpYZmFWYWwuTU9VU0VFWElUID0gIm1vdXNlRXhpdCI7ClhmYVZhbC5NT1VTRVVQID0gIm1vdXNlVXAiOwpYZmFWYWwuTVVMVElTRUxFQ1QgPSAibXVsdGlTZWxlY3QiOwpYZmFWYWwuTk9ORSA9ICJub25lIjsKWGZhVmFsLk5PUk1BTCA9ICJub3JtYWwiOwpYZmFWYWwuT05DRSA9ICJvbmNlIjsKWGZhVmFsLk9ORU5UUlkgPSAib25FbnRyeSI7ClhmYVZhbC5PTkxZID0gIm9ubHkiOwpYZmFWYWwuT1JERVJFRE9DQ1VSUkVOQ0UgPSAib3JkZXJlZE9jY3VycmVuY2UiOwpYZmFWYWwuUEFHRUFSRUEgPSAicGFnZUFyZWEiOwpYZmFWYWwuUE9SVFJBSVQgPSAicG9ydHJhaXQiOwpYZmFWYWwuUE9TSVRJT04gPSAicG9zaXRpb24iOwpYZmFWYWwuUE9TVEVYRUNVVEUgPSAicG9zdEV4ZWN1dGUiOwpYZmFWYWwuUE9TVE9QRU4gPSAicG9zdE9wZW4iOwpYZmFWYWwuUE9TVFBSSU5UID0gInBvc3RQcmludCI7ClhmYVZhbC5QT1NUU0FWRSA9ICJwb3N0U2F2ZSI7ClhmYVZhbC5QT1NUU0lHTiA9ICJwb3N0U2lnbiI7ClhmYVZhbC5QT1NUU1VCTUlUID0gInBvc3RTdWJtaXQiOwpYZmFWYWwuUFJFRVhFQ1VURSA9ICJwcmVFeGVjdXRlIjsKWGZhVmFsLlBSRU9QRU4gPSAicHJlT3BlbiI7ClhmYVZhbC5QUkVQUklOVCA9ICJwcmVQcmludCI7ClhmYVZhbC5QUkVTQVZFID0gInByZVNhdmUiOwpYZmFWYWwuUFJFU0lHTiA9ICJwcmVTaWduIjsKWGZhVmFsLlBSRVNVQk1JVCA9ICJwcmVTdWJtaXQiOwpYZmFWYWwuUkFJU0VEID0gInJhaXNlZCI7ClhmYVZhbC5SRUFEWSA9ICJyZWFkeSI7ClhmYVZhbC5SRVNUID0gInJlc3QiOwpYZmFWYWwuUklHSFQgPSAicmlnaHQiOwpYZmFWYWwuUkxUQiA9ICJybC10YiI7ClhmYVZhbC5ST1cgPSAicm93IjsKWGZhVmFsLlNFTEVDVCA9ICJzZWxlY3QiOwpYZmFWYWwuU0VSVkVSID0gInNlcnZlciI7ClhmYVZhbC5TT0xJRCA9ICJzb2xpZCI7ClhmYVZhbC5UQUJMRSA9ICJ0YWJsZSI7ClhmYVZhbC5UQiA9ICJ0YiI7ClhmYVZhbC5UT1AgPSAidG9wIjsKWGZhVmFsLlVTRVJDT05UUk9MID0gInVzZXJDb250cm9sIjsKWGZhVmFsLlZJU0lCTEUgPSAidmlzaWJsZSI7ClhmYVZhbC5XSURUSCA9ICJ3aWR0aCI7CgpYZmFTY2hlbWEgPSBGb3JtLnJ0ZS51dGlsLlhmYVNjaGVtYSA9IHt9OwovKiogWEZBIG5hbWVzcGFjZSBwcmVmaXguICovClhmYVNjaGVtYS5YRkFOUyA9ICJ4ZmEiOwoKLyoqIFhGQSAyLjggbmFtZXNwYWNlIFVSSS4gKi8KWGZhU2NoZW1hLlhGQVZFUlNJT04yOCA9ICJodHRwOi8vd3d3LnhmYS5vcmcvc2NoZW1hL3hmYS10ZW1wbGF0ZS8yLjgvIjsKLyoqIFhGQSB2ZXJzaW9uIGZvciBhbGwgbmV3IHRlbXBsYXRlcy4gKi8KWGZhU2NoZW1hLlRFTVBMQVRFVkVSU0lPTiA9IFhmYVNjaGVtYS5YRkFWRVJTSU9OMjg7CgovKiogRGVmYXVsdCBmb3Igc2NoZW1hIHZhbHVlcyB0aGF0IGFyZSB0aGUgbnVtYmVyIHplcm8uICovClhmYVNjaGVtYS5aRVJPID0gIjAiOwovKiogRGVmYXVsdCBmb3Igc2NoZW1hIHZhbHVlcyB0aGF0IGFyZSB0aGUgbnVtYmVyIG9uZS4gKi8KWGZhU2NoZW1hLk9ORSA9ICIxIjsKLyoqIERlZmF1bHQgZm9yIHNjaGVtYSB2YWx1ZXMgdGhhdCBhcmUgdGhlIG51bWJlciBtaW51cyBvbmUuICovClhmYVNjaGVtYS5NSU5VU09ORSA9ICItMSI7Ci8qKiBQb2ludCB1bml0cy4gKi8KWGZhU2NoZW1hLlVOSVRQT0lOVCA9ICJwdCI7Ci8qKiBNaWxsaW1ldGVyIHVuaXRzLiAqLwpYZmFTY2hlbWEuVU5JVE1JTExJID0gIm1tIjsKLyoqIENlbnRpbWV0ZXIgdW5pdHMuICovClhmYVNjaGVtYS5VTklUQ0VOVEkgPSAiY20iOwovKiogSW5jaCB1bml0cy4gKi8KWGZhU2NoZW1hLlVOSVRJTkNIID0gImluIjsKLyoqIERlZmF1bHQgdW5pdHMgZm9yIHNjaGVtYSB2YWx1ZXMgdGhhdCBhcmUgbWVhc3VyZW1lbnRzLiAqLwpYZmFTY2hlbWEuREVGQVVMVFVOSVRTID0gWGZhU2NoZW1hLlVOSVRJTkNIOwovKiogRGVmYXVsdCBvdXRwdXQgdW5pdHMgd2hlbSBlZGl0aW5nIG1lYXN1cmVtZW50IHZhbHVlcy4gTWlsbGltZXRlcnMgYXJlIG1vcmUgcHJlY2lzZS4gKi8KWGZhU2NoZW1hLldSSVRFVU5JVFMgPSBYZmFTY2hlbWEuVU5JVE1JTExJOwovKiogRGVmYXVsdCBmb3Igc2NoZW1hIHZhbHVlcyB0aGF0IGFyZSAiY2RhdGEiLiAqLwpYZmFTY2hlbWEuQ0RBVEEgPSAiIjsKLyoqIERlZmF1bHQgZm9yIHNjaGVtYSB2YWx1ZXMgdGhhdCBhcmUgInhtbC1pZCIuICovClhmYVNjaGVtYS5YTUxJRCA9ICIiOwovKiogRGVmYXVsdCBmb250IGZvciB0eXBlZmFjZSBwcm9wZXJ0aWVzLiBBY3R1YWwgZGVmYXVsdCBpcyAiQ291cmllciBTdGQiIGhvd2V2ZXIgIk15cmlhZCBQcm8iIGlzIHRoZSBBZG9iZSBzdGFuZGFyZCBmb250LiAqLwpYZmFTY2hlbWEuREVGQVVMVEZPTlQgPSAiTXlyaWFkIFBybyI7Ci8qKiBCbGFjayBjb2xvci4gKi8KWGZhU2NoZW1hLkJMQUNLID0gIjAsMCwwIjsKCi8vIFRPRE86IENvbnNpZGVyIG1vdmluZyBYZmFTY2hlbWEuWEZBRk9STURPTSBpbnRvIG5ldyBYZmFTY3JpcHRpbmcgb3Igc2NyaXAuWGZhRm9ybURvbSBvciBzb21ldGhpbmcgYWxvbmcgdGhvc2UgbGluZXMuCi8qIFhGQSBGb3JtIERPTSBzY3JpcHRpbmcgcHJlZml4LiAqLwovL1hmYVNjaGVtYS5YRkFGT1JNRE9NID0gInhmYS5mb3JtIjsKCi8vIFRPRE86IFdvcmthcm91bmQgZm9yIGh0dHBzOi8vYnVncy5hZG9iZS5jb20vamlyYS9icm93c2UvQVNDLTIyMzEgKG5vdCB0ZWNobmljYWxseSBwYXJ0IG9mIHRoZSBYRkEgU2NoZW1hIGJ1dAovLyAgc29tZWhvdyB1c2luZyB0aGUgY29uc3QgZnJvbSBYZmFTY2hlbWEgcmF0aGVyIHRoYW4gWGZhRnJhZ1V0aWxzIHdvcmtzIGJldHRlciB3aGVuIHNldHRpbmcgaXQgYXMgdGhlCi8vICBkZWZhdWx0IHZhbHVlIGZvciBhIGZ1bmN0aW9uIHBhcmFtZXRlcikuCi8qKiBEZWZhdWx0IG5hbWUgZm9yIGEgbmV3IGZyYWdtZW50LiAqLwpYZmFTY2hlbWEuREVGQVVMVEZSQUdOQU1FID0gIkZyYWdtZW50MSI7Ci8qKiBEZWZhdWx0IG5hbWUgZm9yIGEgbmV3IGZvcm0gb2JqZWN0IChmaWVsZCwgZHJhdywgc3ViZm9ybSwgZXRjLikuICovClhmYVNjaGVtYS5ERUZBVUxUT0JKTkFNRSA9ICJGb3JtT2JqZWN0IjsKLyoqIERlZmF1bHQgbmFtZSBmb3IgYSByb290IHN1YmZvcm0uICovClhmYVNjaGVtYS5ERUZBVUxUUk9PVE5BTUUgPSAiZm9ybTEiOwoKLyoqIERlZmF1bHQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBkb21haW4gZm9yIFBJcyBnZW5lcmF0ZWQgYW5kIHJlYWQgYnkgTEMgRGVzaWduZXIuICovClhmYVNjaGVtYS5QSURFU0RPTUFJTiA9ICJ0ZW1wbGF0ZURlc2lnbmVyIjsKCi8qKiBQcm9jZXNzaW5nIGluc3RydWN0aW9uIHRoYXQgaWRlbnRpZmllcyBhIGZvcm0gb2JqZWN0IGFzIGEgZnJhZ21lbnQuIFRoaXMgUEkgb2JqZWN0IGFsc28gZGVmaW5lcyBhICJ2YWx1ZSIgcHJvcGVydHkgdGhhdCBob2xkcyB0aGUgUEkncyBleHBlY3RlZCAoYW5kIG9ubHkpIHZhbHVlLiAqLwpYZmFTY2hlbWEuUElGUkFHSVNGUkFHID0ge2RvbWFpbiA6IFhmYVNjaGVtYS5QSURFU0RPTUFJTiwga2V5IDogImlzRnJhZ21lbnQiLCB2YWx1ZSA6ICJ5ZXMifTsKLyoqIFByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdGhhdCBjb250YWlucyB0aGUgdGl0bGUgbWV0YWRhdGEgZm9yIGEgZnJhZ21lbnQuICovClhmYVNjaGVtYS5QSUZSQUdUSVRMRSA9IHtkb21haW4gOiBYZmFTY2hlbWEuUElERVNET01BSU4sIGtleSA6ICJmcmFnbWVudFRpdGxlIn07Ci8qKiBQcm9jZXNzaW5nIGluc3RydWN0aW9uIHRoYXQgY29udGFpbnMgdGhlIGRlc2NyaXB0aW9uIG1ldGFkYXRhIGZvciBhIGZyYWdtZW50LiAqLwpYZmFTY2hlbWEuUElGUkFHREVTQyA9IHtkb21haW4gOiBYZmFTY2hlbWEuUElERVNET01BSU4sIGtleSA6ICJmcmFnbWVudERlc2NyaXB0aW9uIn07CgovKioKICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgWEZBIGVsZW1lbnQgdGFnIGlzIGEgY29udGFpbmVyIG5vZGUgKG1heSBjb250YWluIG90aGVyIGNvbnRhaW5lcnMgb3IgZmllbGRzL2RyYXdzKS4gUHJvdG9zIGFyZSBleGNsdWRlZC4KICogQHBhcmFtIGVsZW1UYWcgVGhlIFhGQSBlbGVtZW50IHRhZyB0byBjaGVjayBhcyBiZWluZyBhIGNvbnRhaW5lci4KICogQHBhcmFtIGluY2x1ZGVFeEdycCBJZiB0cnVlLCB0aGUgJmx0O2V4Y2xHcm91cCZndDsgbm9kZSBpcyBjb25zaWRlcmVkIGEgY29udGFpbmVyLiBPdGhlcndpc2UsIGl0IGlzIG5vdC4gTm90ZSB0aGF0IGluIHRlcm1zIG9mCiAqICAiY29udGVudCIsIGV4Y2x1c2lvbiBncm91cCBub2RlcyBtYXkgb25seSBjb250YWluICZsdDtmaWVsZCZndDsgbm9kZXMgd2hpY2ggaXMgbW9yZSByZXN0cmljdGl2ZSB0aGFuIG90aGVyIGNvbnRhaW5lciB0eXBlcy4KICovClhmYVNjaGVtYS5pc0NvbnRhaW5lckVsZW0gPSBmdW5jdGlvbiAoZWxlbVRhZywgaW5jbHVkZUV4R3JwKSB7CiAgICBpbmNsdWRlRXhHcnAgPSBpbmNsdWRlRXhHcnAgIT09IHVuZGVmaW5lZCA/IGluY2x1ZGVFeEdycCA6IHRydWU7CgogICAgc3dpdGNoIChlbGVtVGFnKSB7CiAgICAgICAgY2FzZSBYZmFFbGVtLlNVQkZPUk06CiAgICAgICAgY2FzZSBYZmFFbGVtLlNVQkZPUk1TRVQ6CiAgICAgICAgY2FzZSBYZmFFbGVtLkFSRUE6CiAgICAgICAgY2FzZSBYZmFFbGVtLlBBR0VBUkVBOgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgWGZhRWxlbS5FWENMR1JPVVA6CiAgICAgICAgICAgIHJldHVybiBpbmNsdWRlRXhHcnA7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICByZXR1cm4gZmFsc2U7Cn07CgovKiogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgWEZBIGVsZW1lbnQgdGFnIGRlZmluZXMgZm9ybSBjb250ZW50IChjb3VsZCBiZSBhIGZpZWxkLCBkcmF3IG9yIHNvbWUgdHlwZSBvZiBjb250YWluZXIgbm9kZSkuIFByb3RvcyBhcmUgZXhjbHVkZWQuICovClhmYVNjaGVtYS5pc0NvbnRlbnRFbGVtID0gZnVuY3Rpb24gKGVsZW1UYWcpIHsKICAgIHN3aXRjaCAoZWxlbVRhZykgewogICAgICAgIGNhc2UgWGZhRWxlbS5EUkFXOgogICAgICAgIGNhc2UgWGZhRWxlbS5GSUVMRDoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIFhmYVNjaGVtYS5pc0NvbnRhaW5lckVsZW0oZWxlbVRhZyk7Cn07CgovKioKICogUmV0dXJucyB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgYSBnaXZlbiBhdHRyaWJ1dGUgdGFnLiBJZiB0aGUgYXR0cmlidXRlIGlzIGludmFsaWQgb3IgdW5rbm93biwgbnVsbCBpcyByZXR1cm5lZC4gSWYgdGhlcmUgaXNuJ3QgZW5vdWdoIGNvbnRleHQgdG8gZGV0ZXJtaW5lCiAqICB0aGUgZGVmYXVsdCwgbnVsbCBpcyByZXR1cm5lZCAoZS5nLiB0aGUgbm9kZSBtYXkgYmUgb3JwaGFuZWQgYW5kIGEgcGFydGljdWxhciBwYXJlbnQgdHlwZSBpcyByZXF1aXJlZCwgbGlrZSB0aGUgZGVmYXVsdCBmb3IgdGhlICJhbGxvd1JpY2hUZXh0IiBjYW4ndCBiZQogKiAgZGV0ZXJtaW5lZCBpZiB0aGUgPGNvZGU+dGV4dEVkaXQ8L2NvZGU+IG5vZGUgaXMgb3JwaGFuZWQgYmVjYXVzZSBhIDxjb2RlPmZpZWxkPC9jb2RlPiBvciA8Y29kZT5kcmF3PC9jb2RlPiBwYXJlbnQgY29udGFpbmluZyBhIDxjb2RlPnZhbHVlPC9jb2RlPiBpcyByZXF1aXJlZCkuCiAqIEBwYXJhbSBhdHRUYWcgVGhlIGF0dHJpYnV0ZSBuYW1lIGZvciB3aGljaCB0byByZXRyaWV2ZSB0aGUgZGVmYXVsdC4KICogQHBhcmFtIGNvbnRleHROb2RlIFhGQSBub2RlIHRoYXQgcHJvdmlkZXMgbmVjZXNzYXJ5IGNvbnRleHQgZm9yIHRoZSBkZWZhdWx0IHZhbHVlLiBGb3IgZXhhbXBsZSwgdGhlICJhbGxvd1JpY2hUZXh0IiBhdHRyaWJ1dGUgaGFzIGRpZmZlcmVudCBkZWZhdWx0IHZhbHVlcwogKiAgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIHRleHQgZmllbGQvZHJhdyBoYXMgJmx0O2V4RGF0YSZndDsgYXMgaXRzIHZhbHVlIHR5cGUgb3Igbm90LiBUaGlzIGlzIGV4cGVjdGVkIHRvIGJlIHRoZSBub2RlIG9uIHdoaWNoIHRoZSBhdHRyaWJ1dGUgd291bGQgYmUgc2V0IChpLmUuCiAqICB3aGVuIGF0dFRhZyBpcyAiYWxsb3dSaWNoVGV4dCIsIGNvbnRleHROb2RlIGlzIGV4cGVjdGVkIHRvIGJlIGEgJmx0O3RleHRFZGl0Jmd0OyBub2RlKS4KICogQHJldHVybiBUaGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIGF0dHJpYnV0ZSBvciBudWxsIGlmIHRoZSBhdHRyaWJ1dGUgaXMgdW5rbm93bi4gV2lsbCBhbHNvIHJldHVybiBudWxsIGlmIGNvbnRleHROb2RlIGlzIHNwZWNpZmllZCBidXQgY291bGQgbm90IGJlIHVzZWQKICogIHRvIGRldGVybWluZSB0aGUgYXBwcm9wcmlhdGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUuCiAqIEB0aHJvd3MgY29tLmFkb2JlLnhmYS54ZmF1dGlsLkVycm9yIEF0dHJpYnV0ZSBkZWZhdWx0IGNhbm5vdCBiZSBjb3JyZWN0bHkgZGV0ZXJtaW5lZCB3aXRob3V0IGJvdGggdGhlIGF0dHJpYnV0ZSB0YWcgYW5kIHRoZSBjb250ZXh0IG5vZGUuCiAqLwpYZmFTY2hlbWEuYXR0RGVmYXVsdCA9IGZ1bmN0aW9uIChhdHRUYWcsIGNvbnRleHROb2RlKSB7CiAgICBpZiAoIWF0dFRhZyB8fCAhY29udGV4dE5vZGUpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkF0dHJpYnV0ZSBkZWZhdWx0IGNhbm5vdCBiZSBjb3JyZWN0bHkgZGV0ZXJtaW5lZCB3aXRob3V0IGJvdGggdGhlIGF0dHJpYnV0ZSB0YWcgYW5kIHRoZSBjb250ZXh0IG5vZGUuIik7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLy8gVE9ETzogU0NIRU1BIFZBTElEQVRJT046IEV2ZW50dWFsbHksIHdlJ2xsIG5lZWQgdG8gdmFsaWRhdGUgdGhhdCB0aGUgYXR0cmlidXRlIHNvdWdodCBpcyB2YWxpZCBvbiB0aGUgZ2l2ZW4gY29udGV4dCBub2RlLgogICAgdmFyIGRlZiA9IG51bGw7CiAgICBzd2l0Y2ggKGF0dFRhZykgewogICAgICAgIC8vIE5PVEU6IEFuIGF1dG8tZ2VuZXJhdGVkIChmcm9tIFhURydzIG1haW4gY29kZSBiYXNlKSBYRkEgc3BlYyBzaG91bGQgYmUgYXZhaWxhYmxlIGhlcmUgZm9yIHJlZmVyZW5jZToKICAgICAgICAvLyBodHRwOi8veHRnd2luMS5jYW4uYWRvYmUuY29tL21haW5fYnVpbGQveHRnL2RvY3Mvc2NoZW1hL3RlbXBsYXRlLXN5bnRheC5odG1sCgogICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgICAgICAvLyBpbiBhbHBoYWJldGljYWwgb3JkZXIKICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAgICAgY2FzZSBYZmFBdHQuQUNUSVZJVFk6CiAgICAgICAgICAgIGRlZiA9IFhmYVZhbC5DTElDSzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuQVNQRUNUOgogICAgICAgICAgICBkZWYgPSBYZmFWYWwuRklUOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5BTExPV1JJQ0hURVhUOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuX2dldEFsbG93UmljaFRleHREZWZhdWx0KGNvbnRleHROb2RlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuQk9UVE9NSU5TRVQ6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPICsgWGZhU2NoZW1hLkRFRkFVTFRVTklUUzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuQ09NTUlUT046CiAgICAgICAgICAgIGRlZiA9IFhmYVZhbC5TRUxFQ1Q7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LkNPTlRFTlRUWVBFOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuX2dldENvbnRlbnRUeXBlRGVmYXVsdChjb250ZXh0Tm9kZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Lkg6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPICsgWGZhU2NoZW1hLkRFRkFVTFRVTklUUzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuSFJFRjoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLkNEQVRBOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5JRDoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlhNTElEOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5JTlRBQ1Q6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5fZ2V0SW50YWN0RGVmYXVsdChjb250ZXh0Tm9kZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LkxBWU9VVDoKICAgICAgICAgICAgZGVmID0gWGZhVmFsLlBPU0lUSU9OOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5MRUZUSU5TRVQ6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPICsgWGZhU2NoZW1hLkRFRkFVTFRVTklUUzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuTE9ORzoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlpFUk8gKyBYZmFTY2hlbWEuREVGQVVMVFVOSVRTOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5NQVJHSU5MRUZUOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Lk1BUkdJTlJJR0hUOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Lk1BVENIOgogICAgICAgICAgICBkZWYgPSBYZmFWYWwuT05DRTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuTUFYQ0hBUlM6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5NQVhIOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Lk1BWExFTkdUSDoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLk1JTlVTT05FOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5NQVhXOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Lk1JTkg6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPICsgWGZhU2NoZW1hLkRFRkFVTFRVTklUUzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuTUlOVzoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlpFUk8gKyBYZmFTY2hlbWEuREVGQVVMVFVOSVRTOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5NVUxUSUxJTkU6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5fZ2V0TXVsdGlMaW5lRGVmYXVsdChjb250ZXh0Tm9kZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Lk5BTUU6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5YTUxJRDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuT1BFTjoKICAgICAgICAgICAgZGVmID0gWGZhVmFsLlVTRVJDT05UUk9MOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5PUklFTlRBVElPTjoKICAgICAgICAgICAgZGVmID0gWGZhVmFsLlBPUlRSQUlUOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5QQUdFUE9TSVRJT046CiAgICAgICAgICAgIGRlZiA9IFhmYVZhbC5BTlk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlBMQUNFTUVOVDoKICAgICAgICAgICAgZGVmID0gWGZhVmFsLkxFRlQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlBSRVNFTkNFOgogICAgICAgICAgICBkZWYgPSBYZmFWYWwuVklTSUJMRTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuUkVGOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuQ0RBVEE7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlJFTEFUSU9OOgogICAgICAgICAgICBkZWYgPSBYZmFWYWwuT1JERVJFRE9DQ1VSUkVOQ0U7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlJFU0VSVkU6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5NSU5VU09ORTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuUklHSFRJTlNFVDoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlpFUk8gKyBYZmFTY2hlbWEuREVGQVVMVFVOSVRTOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5SVU5BVDoKICAgICAgICAgICAgZGVmID0gWGZhVmFsLkNMSUVOVDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuU0FWRToKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlpFUk87CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlNIT1JUOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlNJWkU6CiAgICAgICAgICAgIGRlZiA9ICIxMCIgKyBYZmFTY2hlbWEuVU5JVFBPSU5UOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5TUEFDRUFCT1ZFOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlNQQUNFQkVMT1c6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPICsgWGZhU2NoZW1hLkRFRkFVTFRVTklUUzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuU1RPQ0s6CiAgICAgICAgICAgIGRlZiA9IFhmYVZhbC5MRVRURVI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlNUUk9LRToKICAgICAgICAgICAgZGVmID0gWGZhVmFsLlNPTElEOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5URVhURU5UUlk6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5UT1BJTlNFVDoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlpFUk8gKyBYZmFTY2hlbWEuREVGQVVMVFVOSVRTOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5UWVBFRkFDRToKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLkRFRkFVTFRGT05UOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5VU0U6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5DREFUQTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuVVNFSFJFRjoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLkNEQVRBOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5WQUxJR046CiAgICAgICAgICAgIGRlZiA9IFhmYVZhbC5UT1A7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LlZBTFVFOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuQkxBQ0s7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0LldFSUdIVDoKICAgICAgICAgICAgZGVmID0gWGZhVmFsLk5PUk1BTDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYZmFBdHQuVzoKICAgICAgICAgICAgZGVmID0gWGZhU2NoZW1hLlpFUk8gKyBYZmFTY2hlbWEuREVGQVVMVFVOSVRTOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhmYUF0dC5YOgogICAgICAgICAgICBkZWYgPSBYZmFTY2hlbWEuWkVSTyArIFhmYVNjaGVtYS5ERUZBVUxUVU5JVFM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWGZhQXR0Llk6CiAgICAgICAgICAgIGRlZiA9IFhmYVNjaGVtYS5aRVJPICsgWGZhU2NoZW1hLkRFRkFVTFRVTklUUzsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFdpbmRvdy5jb25zb2xlLmVycm9yKCJubyBkZWZhdWx0IGF0dHJpYnV0ZSB2YWx1ZSBmb3IgJyIgKyBhdHRUYWcgKyAiJyB0YWciKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gZGVmOwp9OwoKLyoqCiAqIFJldHVybnMgdGhlIGRlZmF1bHQgY2hpbGQgZWxlbWVudCBjbGFzcyBuYW1lIGdpdmVuIGEgdGFnIHRoYXQgY29udGFpbnMgYSBvbmUtb2YgZWxlbWVudCBwcm9wZXJ0eS4KICogPHA+Rm9yIGV4YW1wbGUsIHRoZSA8Y29kZT4vL2ZpZWxkL3VpPC9jb2RlPiBlbGVtZW50IGNvbnRhaW5zIGEgb25lLW9mIHByb3BlcnR5IHdoaWNoIHNwZWNpZmllcyB0aGUgZmllbGQncyBVSSB0eXBlIGZvciB3aGljaCB0aGUgZGVmYXVsdCBpcyA8Y29kZT50ZXh0RmllbGQ8L2NvZGU+LgogKiAgVGhlcmVmb3JlLCBjYWxsaW5nIDxjb2RlPm9uZU9mRGVmYXVsdCgmbHQ7ZmllbGQmZ3Q7Jmx0O3VpLyZndDsmbHQ7L2ZpZWxkJmd0Oyk8L2NvZGU+IHdvdWxkIHJldHVybiBYZmFFbGVtLlRFWFRGSUVMRC48L3A+CiAqIEBwYXJhbSBjb250ZXh0Tm9kZSBUaGUgbm9kZSB3aG9zZSBvbmUtb2YgcHJvcGVydHkgZGVmYXVsdCBpcyBzb3VnaHQuCiAqIEByZXR1cm4gQW4gWEZBIGVsZW1lbnQgbmFtZSwgZnJvbSBYZmFFbGVtLCB3aGljaCBpZGVudGlmaWVzIHRoZSBjbGFzcyBuYW1lIG9mIHRoZSBkZWZhdWx0IG9uZS1vZiBwcm9wZXJ0eSBvZiB0aGUgY29udGV4dCBub2RlLiBSZXR1cm5zIG51bGwgaWYgbm8gZGVmYXVsdCBpcyBkZWZpbmVkLgogKiAgVG8gZGV0ZXJtaW5lIGlmIHRoZSBhbiBlbGVtZW50IGhhcyBhIG9uZS1vZiBwcm9wZXJ0eSwgeW91IHNob3VsZCB1c2UgWGZhU2NoZW1hLmhhc09uZU9mUHJvcCgpLgogKiBAc2VlIGNvbS5hZG9iZS54ZmEuWGZhRWxlbQogKiBAc2VlICNoYXNPbmVPZlByb3AoKQogKiBAdGhyb3dzIGNvbS5hZG9iZS54ZmEueGZhdXRpbC5FcnJvciBPbmUtb2YgZGVmYXVsdCBjYW5ub3QgYmUgY29ycmVjdGx5IGRldGVybWluZWQgd2l0aG91dCB0aGUgY29udGV4dCBub2RlLgogKi8KWGZhU2NoZW1hLm9uZU9mRGVmYXVsdCA9IGZ1bmN0aW9uIChjb250ZXh0Tm9kZSkgewogICAgaWYgKCFjb250ZXh0Tm9kZSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiT25lLW9mIGRlZmF1bHQgY2Fubm90IGJlIGNvcnJlY3RseSBkZXRlcm1pbmVkIHdpdGhvdXQgdGhlIGNvbnRleHQgbm9kZS4iKTsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIHZhciBkZWYgPSBudWxsOwogICAgc3dpdGNoIChjb250ZXh0Tm9kZS5jbGFzc05hbWUpIHsKICAgICAgICAvLyBOT1RFOiBBbiBhdXRvLWdlbmVyYXRlZCAoZnJvbSBYVEcncyBtYWluIGNvZGUgYmFzZSkgWEZBIHNwZWMgc2hvdWxkIGJlIGF2YWlsYWJsZSBoZXJlIGZvciByZWZlcmVuY2U6CiAgICAgICAgLy8gaHR0cDovL3h0Z3dpbjEuY2FuLmFkb2JlLmNvbS9tYWluX2J1aWxkL3h0Zy9kb2NzL3NjaGVtYS90ZW1wbGF0ZS1zeW50YXguaHRtbAoKICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAgICAgLy8gaW4gYWxwaGFiZXRpY2FsIG9yZGVyCiAgICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwogICAgICAgIGNhc2UgWGZhRWxlbS5FVkVOVDoKICAgICAgICAgICAgZGVmID0gWGZhRWxlbS5TQ1JJUFQ7CiAgICAgICAgICAgIGJyZWFrOyAvLyBubyBhY3R1YWwgZGVmYXVsdCAtLSBvdXIgZGVmYXVsdCwgYXMgdGhlICJYRkEgYXBwbGljYXRpb24iIGlzIDxzY3JpcHQ+IChtYXRjaGVzIFhURyBkZWZhdWx0KQogICAgICAgIGNhc2UgWGZhRWxlbS5GSUxMOgogICAgICAgICAgICBkZWYgPSBYZmFFbGVtLlNPTElEOwogICAgICAgICAgICBicmVhazsgLy8gbm8gYWN0dWFsIGRlZmF1bHQgLS0gb3VyIGRlZmF1bHQsIGFzIHRoZSAiWEZBIGFwcGxpY2F0aW9uIiBpcyA8c29saWQ+IChtYXRjaGVzIFhURyBkZWZhdWx0KQogICAgICAgIGNhc2UgWGZhRWxlbS5VSToKICAgICAgICAgICAgZGVmID0gWGZhRWxlbS5URVhURURJVDsKICAgICAgICAgICAgYnJlYWs7IC8vIG5vIGFjdHVhbCBkZWZhdWx0IC0tIG91ciBkZWZhdWx0LCBhcyB0aGUgIlhGQSBhcHBsaWNhdGlvbiIgaXMgPHRleHRFZGl0PiAobWF0Y2hlcyBYVEcgZGVmYXVsdCkKICAgICAgICBjYXNlIFhmYUVsZW0uVkFMVUU6CiAgICAgICAgICAgIGRlZiA9IFhmYUVsZW0uVEVYVDsKICAgICAgICAgICAgYnJlYWs7IC8vIG5vIGFjdHVhbCBkZWZhdWx0IC0tIG91ciBkZWZhdWx0LCBhcyB0aGUgIlhGQSBhcHBsaWNhdGlvbiIgaXMgPHRleHQ+IChtYXRjaGVzIFhURyBkZWZhdWx0KQoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB3aW5kb3cuY29uc29sZS5lcnJvcigibm8gZGVmYXVsdCBvbmUtb2YgZWxlbWVudCBwcm9wZXJ0eSBmb3IgJyIgKyBjb250ZXh0Tm9kZS5jbGFzc05hbWUgKyAiJyB0YWciKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gZGVmOwp9OwoKLyoqCiAqIERldGVybWluZXMgaWYgdGhlIHNwZWNpZmllZCBYRkEgZWxlbWVudCBoYXMgYSBvbmUtb2YgcHJvcGVydHkuCiAqIEBwYXJhbSBlbGVtVGFnIFRoZSBYRkEgZWxlbWVudCB0byBjaGVjayBmb3IgYSBvbmUtb2YgcHJvcGVydHkuCiAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgWEZBIGVsZW1lbnQgaGFzIGEgb25lLW9mIHByb3BlcnR5OyBmYWxzZSBpZiBub3QuCiAqLwpYZmFTY2hlbWEuaGFzT25lT2ZQcm9wID0gZnVuY3Rpb24gKGVsZW1UYWcpIHsKICAgIHZhciBoYXNPbmVPZiA9IGZhbHNlOwoKICAgIHN3aXRjaCAoZWxlbVRhZykgewogICAgICAgIC8vIE5PVEU6IEFuIGF1dG8tZ2VuZXJhdGVkIChmcm9tIFhURydzIG1haW4gY29kZSBiYXNlKSBYRkEgc3BlYyBzaG91bGQgYmUgYXZhaWxhYmxlIGhlcmUgZm9yIHJlZmVyZW5jZToKICAgICAgICAvLyBodHRwOi8veHRnd2luMS5jYW4uYWRvYmUuY29tL21haW5fYnVpbGQveHRnL2RvY3Mvc2NoZW1hL3RlbXBsYXRlLXN5bnRheC5odG1sCgogICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgICAgICAvLyBpbiBhbHBoYWJldGljYWwgb3JkZXIKICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAgICAgY2FzZSBYZmFFbGVtLkVWRU5UOgogICAgICAgIGNhc2UgWGZhRWxlbS5GSUxMOgogICAgICAgIGNhc2UgWGZhRWxlbS5VSToKICAgICAgICBjYXNlIFhmYUVsZW0uVkFMVUU6CiAgICAgICAgICAgIGhhc09uZU9mID0gdHJ1ZTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gaGFzT25lT2Y7Cn07CgovKioKICogRGV0ZXJtaW5lcyBpZiB0aGUgc3BlY2lmaWVkIFhGQSBlbGVtZW50IGNsYXNzIG5hbWUgaXMgYSBvbmUtb2YgcHJvcGVydHkgb2YgdGhlIHNwZWNpZmllZCBjb250ZXh0IG5vZGUuCiAqIDxwPkZvciBleGFtcGxlLCBjYWxsaW5nIDxjb2RlPmlzT25lT2ZQcm9wKFhmYUVsZW0uVEVYVEVESVQsICZsdDtmaWVsZCZndDsmbHQ7dWkvJmd0OyZsdDsvZmllbGQmZ3Q7KTwvY29kZT4gd291bGQgcmV0dXJuIHRydWUuPC9wPgogKiBAcGFyYW0gZWxlbVRhZyBUaGUgWEZBIGVsZW1lbnQgY2xhc3MgbmFtZSwgZnJvbSBYZmFFbGVtLCB3aGljaCBpcyB0aGUgdGFnIHRvIHRlc3QgYXMgYSBvbmUtb2YgcHJvcGVydHkgb2YgdGhlIGNvbnRleHQgbm9kZS4KICogQHBhcmFtIGNvbnRleHROb2RlIFRoZSBYRkEgbm9kZSB0aGF0IHByb3ZpZGVzIGNvbnRleHQgdG8gdGhlIHRlc3Qgc2luY2Ugc29tZSBlbGVtZW50cyBtYXkgYmUgb25lLW9mIHByb3BlcnRpZXMgb2Ygc29tZSBvdGhlciBlbGVtZW50cyB3aGlsZQogKiAgdGhleSBtYXkgbm90IGJlIG9mIG90aGVycy4gRm9yIGV4YW1wbGUsIHRoZSAmbHQ7dGV4dCZndDsgZWxlbWVudCBpcyBhIG9uZS1vZiBwcm9wZXJ0eSBvZiAmbHQ7dmFsdWUmZ3Q7IGJ1dCBhIDEvbiBwcm9wZXJ0eSBvZiAmbHQ7dmFyaWFibGVzJmd0Oy4KICogQHRocm93cyBjb20uYWRvYmUueGZhLnhmYXV0aWwuRXJyb3IgT25lLW9mIHByb3BlcnR5IGNhbm5vdCBiZSBjb3JyZWN0bHkgaWRlbnRpZmllZCB3aXRob3V0IHRoZSBlbGVtZW50IHRhZyBhbmQgdGhlIGNvbnRleHQgbm9kZS4KICovClhmYVNjaGVtYS5pc09uZU9mUHJvcCA9IGZ1bmN0aW9uIChlbGVtVGFnLCBjb250ZXh0Tm9kZSkgewogICAgaWYgKCFlbGVtVGFnIHx8ICFjb250ZXh0Tm9kZSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiT25lLW9mIHByb3BlcnR5IGNhbm5vdCBiZSBjb3JyZWN0bHkgaWRlbnRpZmllZCB3aXRob3V0IHRoZSBlbGVtZW50IHRhZyBhbmQgdGhlIGNvbnRleHQgbm9kZS4iKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgdmFyIGlzT25lT2YgPSBmYWxzZTsKCiAgICBzd2l0Y2ggKGNvbnRleHROb2RlLmNsYXNzTmFtZSkgewogICAgICAgIC8vIE5PVEU6IEFuIGF1dG8tZ2VuZXJhdGVkIChmcm9tIFhURydzIG1haW4gY29kZSBiYXNlKSBYRkEgc3BlYyBzaG91bGQgYmUgYXZhaWxhYmxlIGhlcmUgZm9yIHJlZmVyZW5jZToKICAgICAgICAvLyBodHRwOi8veHRnd2luMS5jYW4uYWRvYmUuY29tL21haW5fYnVpbGQveHRnL2RvY3Mvc2NoZW1hL3RlbXBsYXRlLXN5bnRheC5odG1sCgogICAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KICAgICAgICAvLyBpbiBhbHBoYWJldGljYWwgb3JkZXIKICAgICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCiAgICAgICAgY2FzZSBYZmFFbGVtLkVWRU5UOiB7CiAgICAgICAgICAgIHN3aXRjaCAoZWxlbVRhZykgewogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkVYRUNVVEU6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uU0NSSVBUOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLlNJR05EQVRBOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLlNVQk1JVDoKICAgICAgICAgICAgICAgICAgICBpc09uZU9mID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgWGZhRWxlbS5GSUxMOiB7CiAgICAgICAgICAgIHN3aXRjaCAoZWxlbVRhZykgewogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkxJTkVBUjoKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5QQVRURVJOOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLlJBRElBTDoKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5TT0xJRDoKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5TVElQUExFOgogICAgICAgICAgICAgICAgICAgIGlzT25lT2YgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBYZmFFbGVtLlVJOiB7CiAgICAgICAgICAgIHN3aXRjaCAoZWxlbVRhZykgewogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkJBUkNPREU6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uQlVUVE9OOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkNIRUNLQlVUVE9OOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkNIT0lDRUxJU1Q6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uREFURVRJTUVFRElUOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkRFRkFVTFRVSToKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5FWE9CSkVDVDoKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5JTUFHRUVESVQ6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uTlVNRVJJQ0VESVQ6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uUEFTU1dPUkRFRElUOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLlNJR05BVFVSRToKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5URVhURURJVDoKICAgICAgICAgICAgICAgICAgICBpc09uZU9mID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgWGZhRWxlbS5WQUxVRTogewogICAgICAgICAgICBzd2l0Y2ggKGVsZW1UYWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5BUkM6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uQk9PTEVBTjoKICAgICAgICAgICAgICAgIGNhc2UgWGZhRWxlbS5EQVRFOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkRBVEVUSU1FOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkRFQ0lNQUw6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uRVhEQVRBOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkZMT0FUOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLklNQUdFOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLkxJTkU6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uUkVDVEFOR0xFOgogICAgICAgICAgICAgICAgY2FzZSBYZmFFbGVtLlRFWFQ6CiAgICAgICAgICAgICAgICBjYXNlIFhmYUVsZW0uVElNRToKICAgICAgICAgICAgICAgICAgICBpc09uZU9mID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gaXNPbmVPZjsKfTsKCi8qKgogKiBEZXRlcm1pbmVzIGlmIHRoZSBzcGVjaWZpZWQgWEZBIGVsZW1lbnQgY29udGFpbnMgQ0RBVEEgb3IgUENEQVRBIGNvbnRlbnQuIElmIGl0IGRvZXMsIGl0IG1lYW5zIHRoZSBub2RlIGRvZXMgbm90IGNvbnRhaW4gYW55IFhGQSBlbGVtZW50cy4KICogQHBhcmFtIGVsZW1UYWcgVGhlIFhGQSBlbGVtZW50IHRvIGNoZWNrIGZvciBDREFUQSBjb250ZW50LgogKiBAcmV0dXJuIFRydWUgaWYgdGhlIFhGQSBlbGVtZW50IGhhcyBDREFUQSBjb250ZW50OyBmYWxzZSBpZiBub3QuCiAqLwpYZmFTY2hlbWEuY29udGFpbnNDRGF0YSA9IGZ1bmN0aW9uIChlbGVtVGFnKSB7CiAgICB2YXIgaGFzQ0RhdGEgPSBmYWxzZTsKICAgIHN3aXRjaCAoZWxlbVRhZykgewogICAgICAgIGNhc2UgWGZhRWxlbS5BUFBFQVJBTkNFRklMVEVSOgogICAgICAgIGNhc2UgWGZhRWxlbS5CT09MRUFOOgogICAgICAgIGNhc2UgWGZhRWxlbS5DRVJUSUZJQ0FURToKICAgICAgICBjYXNlIFhmYUVsZW0uREFURToKICAgICAgICBjYXNlIFhmYUVsZW0uREFURVRJTUU6CiAgICAgICAgY2FzZSBYZmFFbGVtLkRFQ0lNQUw6CiAgICAgICAgY2FzZSBYZmFFbGVtLkRJR0VTVE1FVEhPRDoKICAgICAgICBjYXNlIFhmYUVsZW0uRU5DT0RJTkc6CiAgICAgICAgY2FzZSBYZmFFbGVtLkVYREFUQToKICAgICAgICBjYXNlIFhmYUVsZW0uRkxPQVQ6CiAgICAgICAgY2FzZSBYZmFFbGVtLkhBTkRMRVI6CiAgICAgICAgY2FzZSBYZmFFbGVtLklNQUdFOgogICAgICAgIGNhc2UgWGZhRWxlbS5JTlRFR0VSOgogICAgICAgIGNhc2UgWGZhRWxlbS5MT0NLRE9DVU1FTlQ6CiAgICAgICAgY2FzZSBYZmFFbGVtLk9JRDoKICAgICAgICBjYXNlIFhmYUVsZW0uUElDVFVSRToKICAgICAgICBjYXNlIFhmYUVsZW0uUkVBU09OOgogICAgICAgIGNhc2UgWGZhRWxlbS5SRUY6CiAgICAgICAgY2FzZSBYZmFFbGVtLlNDUklQVDoKICAgICAgICBjYXNlIFhmYUVsZW0uU1BFQUs6CiAgICAgICAgY2FzZSBYZmFFbGVtLlNVQkpFQ1RETjoKICAgICAgICBjYXNlIFhmYUVsZW0uVEVYVDoKICAgICAgICBjYXNlIFhmYUVsZW0uVElNRToKICAgICAgICBjYXNlIFhmYUVsZW0uVE9PTFRJUDoKICAgICAgICAgICAgaGFzQ0RhdGEgPSB0cnVlOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICByZXR1cm4gaGFzQ0RhdGE7Cn07CgovKioKICogUmV0dXJucyB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgWGZhQXR0LkFMTE9XUklDSFRFWFQuIFJldHVybnMgbnVsbCBpZiB0aGVyZSBpc24ndCBlbm91Z2ggY29udGV4dC4KICogQHRocm93cyBjb20uYWRvYmUueGZhLnhmYXV0aWwuRXJyb3IgQ29udGV4dCBub2RlIG11c3QgYmUgc3BlY2lmaWVkLgogKiBAdGhyb3dzIGNvbS5hZG9iZS54ZmEueGZhdXRpbC5FcnJvciBBdHRyaWJ1dGUgaXMgbm90IHZhbGlkIG9uIHRoZSBzcGVjaWZpZWQgY29udGV4dCBub2RlLgogKi8KWGZhU2NoZW1hLl9nZXRBbGxvd1JpY2hUZXh0RGVmYXVsdCA9IGZ1bmN0aW9uIChjb250ZXh0Tm9kZSkgewogICAgaWYgKCFjb250ZXh0Tm9kZSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiQ29udGV4dCBub2RlIG11c3QgYmUgc3BlY2lmaWVkIGluIG9yZGVyIHRvIGRldGVybWluZSAiICsgWGZhQXR0LkFMTE9XUklDSFRFWFQgKyAiIGRlZmF1bHQuIik7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgaWYgKGNvbnRleHROb2RlLmNsYXNzTmFtZSAhPSBYZmFFbGVtLlRFWFRFRElUKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFhmYUF0dC5BTExPV1JJQ0hURVhUICsgIiBpcyBub3QgYSB2YWxpZCBhdHRyaWJ1dGUgb24gY29udGV4dCBub2RlIDwiICsgY29udGV4dE5vZGUuY2xhc3NOYW1lICsgIj4uIik7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgLy8gQWN0dWFsIGRlZmF1bHQgZGVwZW5kcyBvbiAvL3ZhbHVlL3t0ZXh0fGV4RGF0YX0KCiAgICAvLyBnZXQgPHVpPiBub2RlCiAgICB2YXIgcGFyZW50ID0gY29udGV4dE5vZGUucGFyZW50OwogICAgaWYgKCFwYXJlbnQpIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICAvLyBnZXQgZmllbGQvZHJhdyBub2RlCiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50OwogICAgaWYgKCFwYXJlbnQgfHwgKCEocGFyZW50IGluc3RhbmNlb2YgWGZhRmllbGQpICYmICEocGFyZW50IGluc3RhbmNlb2YgWGZhRHJhdykpKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgaWYgKChwYXJlbnQgaW5zdGFuY2VvZiBYZmFGaWVsZCAmJiBwYXJlbnQudmFsdWVUeXBlID09IFhmYUVsZW0uRVhEQVRBKSB8fAogICAgICAgIChwYXJlbnQgaW5zdGFuY2VvZiBYZmFEcmF3ICYmIHBhcmVudC52YWx1ZVR5cGUgPT0gWGZhRWxlbS5FWERBVEEpKSB7CiAgICAgICAgcmV0dXJuIFhmYVNjaGVtYS5PTkU7CiAgICB9CiAgICByZXR1cm4gWGZhU2NoZW1hLlpFUk87Cn07CgovKioKICogUmV0dXJucyB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgWGZhQXR0LkNPTlRFTlRUWVBFLgogKiBAdGhyb3dzIGNvbS5hZG9iZS54ZmEueGZhdXRpbC5FcnJvciBDb250ZXh0IG5vZGUgbXVzdCBiZSBzcGVjaWZpZWQuCiAqIEB0aHJvd3MgY29tLmFkb2JlLnhmYS54ZmF1dGlsLkVycm9yIEF0dHJpYnV0ZSBpcyBub3QgdmFsaWQgb24gdGhlIHNwZWNpZmllZCBjb250ZXh0IG5vZGUuCiAqLwpYZmFTY2hlbWEuX2dldENvbnRlbnRUeXBlRGVmYXVsdCA9IGZ1bmN0aW9uIChjb250ZXh0Tm9kZSkgewogICAgaWYgKCFjb250ZXh0Tm9kZSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigiQ29udGV4dCBub2RlIG11c3QgYmUgc3BlY2lmaWVkIGluIG9yZGVyIHRvIGRldGVybWluZSAiICsgWGZhQXR0LkNPTlRFTlRUWVBFICsgIiBkZWZhdWx0LiIpOwogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHN3aXRjaCAoY29udGV4dE5vZGUuY2xhc3NOYW1lKSB7CiAgICAgICAgY2FzZSBYZmFFbGVtLkVYREFUQToKICAgICAgICAgICAgcmV0dXJuIFhmYU1pbWVUeXBlLlBMQUlOVEVYVDsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgWGZhRWxlbS5JTUFHRToKICAgICAgICAgICAgcmV0dXJuIFhmYVNjaGVtYS5DREFUQTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgWGZhRWxlbS5TQ1JJUFQ6CiAgICAgICAgICAgIHJldHVybiBYZmFWYWwuQVBQWEZPUk1DQUxDOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICB0aHJvdyBuZXcgRXJyb3IoWGZhQXR0LkNPTlRFTlRUWVBFICsgIiBpcyBub3QgYSB2YWxpZCBhdHRyaWJ1dGUgb24gY29udGV4dCBub2RlIDwiICsgY29udGV4dE5vZGUuY2xhc3NOYW1lICsgIj4uIik7CiAgICByZXR1cm4gbnVsbDsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHZhbHVlIGZvciBYZmFBdHQuSU5UQUNULgogKiBAdGhyb3dzIGNvbS5hZG9iZS54ZmEueGZhdXRpbC5FcnJvciBDb250ZXh0IG5vZGUgbXVzdCBiZSBzcGVjaWZpZWQuCiAqIEB0aHJvd3MgY29tLmFkb2JlLnhmYS54ZmF1dGlsLkVycm9yIEF0dHJpYnV0ZSBpcyBub3QgdmFsaWQgb24gdGhlIHNwZWNpZmllZCBjb250ZXh0IG5vZGUuCiAqLwpYZmFTY2hlbWEuX2dldEludGFjdERlZmF1bHQgPSBmdW5jdGlvbiAoY29udGV4dE5vZGUpIHsKICAgIGlmICghY29udGV4dE5vZGUpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkNvbnRleHQgbm9kZSBtdXN0IGJlIHNwZWNpZmllZCBpbiBvcmRlciB0byBkZXRlcm1pbmUgIiArIFhmYUF0dC5JTlRBQ1QgKyAiIGRlZmF1bHQuIik7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgaWYgKGNvbnRleHROb2RlLmNsYXNzTmFtZSAhPSBYZmFFbGVtLktFRVApIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoWGZhQXR0LklOVEFDVCArICIgaXMgbm90IGEgdmFsaWQgYXR0cmlidXRlIG9uIGNvbnRleHQgbm9kZSA8IiArIGNvbnRleHROb2RlLmNsYXNzTmFtZSArICI+LiIpOwogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8vIEZyb20gdGhlIFhGQSBTY2hlbWE6IFdoZW4gdGhlIHBhcmVudCBjb250YWluZXIgaXMgYSBzdWJmb3JtIGFuZCB0aGUgc3ViZm9ybSdzIGxheW91dCBpcyBmbG93aW5nIG9yIHRhYmxlIHRoZSBkZWZhdWx0IHZhbHVlIGlzIG5vbmUuCiAgICAvLyAgV2hlbiB0aGUgcGFyZW50IHN1YmZvcm0ncyBsYXlvdXQgaXMgcG9zaXRpb25lZCBvciByb3cgdGhlIGRlZmF1bHQgdmFsdWUgaXMgY29udGVudEFyZWEuIEhvd2V2ZXIgd2hlbiB0aGUgcGFyZW50IGNvbnRhaW5lciBpcyBhIGRyYXcKICAgIC8vICB0aGUgZGVmYXVsdCBpcyBhbHdheXMgY29udGVudEFyZWEgYW5kIHdoZW4gdGhlIHBhcmVudCBpcyBhIGZpZWxkIHRoZSBkZWZhdWx0IGlzIGFsd2F5cyBub25lLgoKICAgIHZhciBwYXJlbnQgPSBjb250ZXh0Tm9kZS5wYXJlbnQ7CgogICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFhmYVN1YmZvcm0pIHsKICAgICAgICB2YXIgbGF5b3V0ID0gcGFyZW50LmdldFByb3BlcnR5KG51bGwsICJAIiArIFhmYUF0dC5MQVlPVVQpOwogICAgICAgIHN3aXRjaCAobGF5b3V0KSB7CiAgICAgICAgICAgIGNhc2UgWGZhVmFsLlRCOgogICAgICAgICAgICBjYXNlIFhmYVZhbC5MUlRCOgogICAgICAgICAgICBjYXNlIFhmYVZhbC5STFRCOgogICAgICAgICAgICBjYXNlIFhmYVZhbC5UQUJMRToKICAgICAgICAgICAgICAgIHJldHVybiBYZmFWYWwuTk9ORTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBYZmFWYWwuUE9TSVRJT046CiAgICAgICAgICAgIGNhc2UgWGZhVmFsLlJPVzoKICAgICAgICAgICAgICAgIHJldHVybiBYZmFWYWwuQ09OVEVOVEFSRUE7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvLyBpbnZhbGlkIGxheW91dCBhdHRyaWJ1dGUgdmFsdWUKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAocGFyZW50IGluc3RhbmNlb2YgWGZhRmllbGQpIHsKICAgICAgICByZXR1cm4gWGZhVmFsLk5PTkU7CiAgICB9IGVsc2UgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFhmYURyYXcpIHsKICAgICAgICByZXR1cm4gWGZhVmFsLkNPTlRFTlRBUkVBOwogICAgfQoKICAgIC8vIHVuYWJsZSB0byBkZXRlcm1pbmUgZGVmYXVsdCBmcm9tIGNvbnRleHQgbm9kZQogICAgcmV0dXJuIG51bGw7Cn07CgovKioKICogUmV0dXJucyB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgWGZhQXR0Lk1VTFRJTElORS4KICogQHRocm93cyBjb20uYWRvYmUueGZhLnhmYXV0aWwuRXJyb3IgQ29udGV4dCBub2RlIG11c3QgYmUgc3BlY2lmaWVkLgogKiBAdGhyb3dzIGNvbS5hZG9iZS54ZmEueGZhdXRpbC5FcnJvciBBdHRyaWJ1dGUgaXMgbm90IHZhbGlkIG9uIHRoZSBzcGVjaWZpZWQgY29udGV4dCBub2RlLgogKi8KWGZhU2NoZW1hLl9nZXRNdWx0aUxpbmVEZWZhdWx0ID0gZnVuY3Rpb24gKGNvbnRleHROb2RlKSB7CiAgICBpZiAoIWNvbnRleHROb2RlKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJDb250ZXh0IG5vZGUgbXVzdCBiZSBzcGVjaWZpZWQgaW4gb3JkZXIgdG8gZGV0ZXJtaW5lICIgKyBYZmFBdHQuQUxMT1dSSUNIVEVYVCArICIgZGVmYXVsdC4iKTsKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBpZiAoY29udGV4dE5vZGUuY2xhc3NOYW1lICE9IFhmYUVsZW0uVEVYVEVESVQpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoWGZhQXR0Lk1VTFRJTElORSArICIgaXMgbm90IGEgdmFsaWQgYXR0cmlidXRlIG9uIGNvbnRleHQgbm9kZSA8IiArIGNvbnRleHROb2RlLmNsYXNzTmFtZSArICI+LiIpOwogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8vIE9uZSBpcyB0aGUgdHJ1ZSBkZWZhdWx0IGJ1dCBhY3R1YWwgZGVmYXVsdCBkZXBlbmRzIG9uIC8vZmllbGQgdnMgLy9kcmF3IGNvbnRhaW5lciBlbGVtZW50IChzZWUgdGhlIHNwZWMpLgoKICAgIC8vIGdldCA8dWk+IG5vZGUKICAgIHZhciBwYXJlbnQgPSBjb250ZXh0Tm9kZS5wYXJlbnQ7CiAgICBpZiAoIXBhcmVudCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIC8vIGdldCA8ZmllbGQ+IG9yIDxkcmF3PiBub2RlCiAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50OwoKICAgIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBYZmFGaWVsZCkgewogICAgICAgIHJldHVybiBYZmFTY2hlbWEuWkVSTzsKICAgIH0gZWxzZSBpZiAocGFyZW50IGluc3RhbmNlb2YgWGZhRHJhdykgewogICAgICAgIHJldHVybiBYZmFTY2hlbWEuT05FOwogICAgfQogICAgLy8gdW5hYmxlIHRvIGRldGVybWluZSBkZWZhdWx0IGZyb20gY29udGV4dCBub2RlCiAgICByZXR1cm4gbnVsbDsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKKGZ1bmN0aW9uIChucykgewogICAgdmFyIFhtbFV0aWwgPSBucy5YbWxVdGlsID0ge307CgogICAgWG1sVXRpbC5zZWxlY3RTaW5nbGVOb2RlID0gZnVuY3Rpb24gKHBhcmVudCwgbG9jYWxOYW1lLCBkZWVwLCBvY2N1cnJlbmNlKSB7CiAgICAgICAgZGVlcCA9IGRlZXAgIT09IHVuZGVmaW5lZCA/IGRlZXAgOiBmYWxzZTsKICAgICAgICBvY2N1cnJlbmNlID0gaXNOYU4ob2NjdXJyZW5jZSkgPyAwIDogb2NjdXJyZW5jZTsKICAgICAgICAvLyBSZXR1cm5zIHRoZSBmaXJzdCBjaGlsZCBub2RlIGZvdW5kIHdpdGggdGhlIGdpdmVuIGxvY2FsIG5hbWUuCiAgICAgICAgdmFyIGxpc3QgPSBYbWxVdGlsLnNlbGVjdE5vZGVzKHBhcmVudCwgbG9jYWxOYW1lLCBkZWVwKTsKICAgICAgICBpZiAobGlzdCAmJiBsaXN0Lmxlbmd0aCgpID4gb2NjdXJyZW5jZSkgewogICAgICAgICAgICByZXR1cm4gbGlzdFtvY2N1cnJlbmNlXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICB9OwogICAgWG1sVXRpbC5zZWxlY3ROb2RlcyA9IGZ1bmN0aW9uIChwYXJlbnQsIGxvY2FsTmFtZSwgZGVlcCwgYXR0cmlidXRlVmFsdWUsIGF0dHJpYnV0ZU5hbWUsIGJFeGFjdE1hdGNoKSB7CiAgICAgICAgZGVlcCA9IGRlZXAgIT09IHVuZGVmaW5lZCA/IGRlZXAgOiBmYWxzZTsKICAgICAgICBhdHRyaWJ1dGVWYWx1ZSA9IGF0dHJpYnV0ZVZhbHVlIHx8IG51bGw7CiAgICAgICAgYXR0cmlidXRlTmFtZSA9IGF0dHJpYnV0ZU5hbWUgfHwgIm5hbWUiOwogICAgICAgIGJFeGFjdE1hdGNoID0gYkV4YWN0TWF0Y2ggIT09IHVuZGVmaW5lZCA/IGJFeGFjdE1hdGNoIDogdHJ1ZTsKICAgICAgICBpZiAocGFyZW50ID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBYTUxMaXN0KCk7CiAgICAgICAgfQogICAgICAgIHZhciBmdWxsTGlzdDsKICAgICAgICBpZiAoZGVlcCkgewogICAgICAgICAgICBmdWxsTGlzdCA9IHBhcmVudC5kZXNjZW5kYW50cygpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZ1bGxMaXN0ID0gcGFyZW50LmVsZW1lbnRzKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdGhpcy5maWx0ZXJMaXN0KGZ1bGxMaXN0LCBsb2NhbE5hbWUsIGF0dHJpYnV0ZVZhbHVlLCBhdHRyaWJ1dGVOYW1lLCBiRXhhY3RNYXRjaCk7CiAgICB9OwogICAgWG1sVXRpbC5maWx0ZXJMaXN0ID0gZnVuY3Rpb24gKGZ1bGxMaXN0LCBsb2NhbE5hbWUsIGF0dHJpYnV0ZVZhbHVlLCBhdHRyaWJ1dGVOYW1lLCBiRXhhY3RNYXRjaCkgewogICAgICAgIGF0dHJpYnV0ZVZhbHVlID0gYXR0cmlidXRlVmFsdWUgfHwgbnVsbDsKICAgICAgICBhdHRyaWJ1dGVOYW1lID0gYXR0cmlidXRlTmFtZSB8fCAibmFtZSI7CiAgICAgICAgYkV4YWN0TWF0Y2ggPSBiRXhhY3RNYXRjaCAhPT0gdW5kZWZpbmVkID8gYkV4YWN0TWF0Y2ggOiB0cnVlOwogICAgICAgIHZhciBvTGlzdCA9IG5ldyBYTUxMaXN0KCk7CgogICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgaSA8IGZ1bGxMaXN0Lmxlbmd0aCgpOwogICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgIHZhciBlbGVtID0gZnVsbExpc3RbaV07CiAgICAgICAgICAgIGlmIChsb2NhbE5hbWUgPT0gbnVsbCB8fCAoZWxlbS5sb2NhbE5hbWUoKSAhPSBudWxsICYmIFN0cmluZyhlbGVtLmxvY2FsTmFtZSgpKSA9PSBsb2NhbE5hbWUpKSB7CiAgICAgICAgICAgICAgICAvLyBFbGVtZW50IG5hbWUgbWF0Y2hlcyAtIG5vdyBjaGVjayB0byBzZWUgaWYgYW4gYXR0cmlidXRlIG5lZWRzIHRvIGJlIG1hdGNoZWQgYXMgd2VsbC4KICAgICAgICAgICAgICAgIHZhciBiQWRkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVWYWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBhdHRyTWF0Y2ggPSBYbWxVdGlsLmdldEF0dHJpYnV0ZShlbGVtLCBhdHRyaWJ1dGVOYW1lKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIWF0dHJNYXRjaCkgewogICAgICAgICAgICAgICAgICAgICAgICBiQWRkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJFeGFjdE1hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ck1hdGNoICE9IGF0dHJpYnV0ZVZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9hdHRyaWJ1dGUgdmFsdWVzIGRvIG5vdCBtYXRjaAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJBZGQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyTWF0Y2guaW5kZXhPZihhdHRyaWJ1dGVWYWx1ZSkgPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2F0dHJpYnV0ZSB2YWx1ZSBub3QgZm91bmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiQWRkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoYkFkZCkgewogICAgICAgICAgICAgICAgICAgIC8vYWRkIHRvIGxpc3QKICAgICAgICAgICAgICAgICAgICBvTGlzdC5BcHBlbmQoZWxlbSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9MaXN0OwogICAgfTsKICAgIFhtbFV0aWwuZ2V0WG1sT2JqZWN0ID0gZnVuY3Rpb24gKHhtbG9iaiwgaWdub3JlV2hpdGUsIGlnbm9yZUNvbW1lbnRzLCBpZ25vcmVQSXMpIHsKICAgICAgICBpZ25vcmVXaGl0ZSA9IGlnbm9yZVdoaXRlICE9PSB1bmRlZmluZWQgPyBpZ25vcmVXaGl0ZSA6IGZhbHNlOwogICAgICAgIGlnbm9yZUNvbW1lbnRzID0gaWdub3JlQ29tbWVudHMgIT09IHVuZGVmaW5lZCA/IGlnbm9yZUNvbW1lbnRzIDogZmFsc2U7CiAgICAgICAgaWdub3JlUElzID0gaWdub3JlUElzICE9PSB1bmRlZmluZWQgPyBpZ25vcmVQSXMgOiBmYWxzZTsKICAgICAgICB2YXIgZWxlbSA9IG51bGw7CgogICAgICAgIGlmICgheG1sb2JqKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKHhtbG9iaiBpbnN0YW5jZW9mIFhNTExpc3QpIHsKICAgICAgICAgICAgaWYgKFhNTExpc3QoeG1sb2JqKS5sZW5ndGgoKSA+IDApIHsKICAgICAgICAgICAgICAgIGVsZW0gPSB4bWxvYmpbMF07CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKHhtbG9iaiBpbnN0YW5jZW9mIFhNTCkgewogICAgICAgICAgICBlbGVtID0geG1sb2JqOwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHhtbG9iaiA9PSAic3RyaW5nIikgewogICAgICAgICAgICAvLyBzYXZlIHNldHRpbmdzCiAgICAgICAgICAgIHZhciB4bWxTZXR0aW5ncyA9IFhNTC5zZXR0aW5ncygpOwoKICAgICAgICAgICAgLy8gYXBwbHkgb3VyIG93bgogICAgICAgICAgICBYTUwuaWdub3JlV2hpdGVzcGFjZSA9IGlnbm9yZVdoaXRlOwogICAgICAgICAgICBYTUwuaWdub3JlQ29tbWVudHMgPSBpZ25vcmVDb21tZW50czsKICAgICAgICAgICAgWE1MLmlnbm9yZVByb2Nlc3NpbmdJbnN0cnVjdGlvbnMgPSBpZ25vcmVQSXM7CgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgZWxlbSA9IG5ldyBYTUwoeG1sb2JqKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgLy90cnkgd3JhcHBpbmcgd2l0aCBzb21lIHJvb3QgWE1MIG5vZGVzCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGVsZW0gPSBuZXcgWE1MKCI8cm9vdD4iICsgeG1sb2JqICsgIjwvcm9vdD4iKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICAvL3RoZSBzdHJpbmcgbXVzdCBjb250YWluIGluY29tcGxldGUgWE1MIHNvIHRoZXJlCiAgICAgICAgICAgICAgICAgICAgLy9pcyBubyB3YXkgdG8gY29udmVydCBpdCB0byBhbiBYTUwgb2JqZWN0CiAgICAgICAgICAgICAgICAgICAgZWxlbSA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHJlc3RvcmUgb3JpZ2luYWwgc2V0dGluZ3MKICAgICAgICAgICAgWE1MLnNldFNldHRpbmdzKHhtbFNldHRpbmdzKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBlbGVtOwogICAgfTsKICAgIC8qKgogICAgICogQnVpbGRzIGEgcGF0aCBmcm9tIGEgc2VyaWVzIG9mIHN0cmluZyBhcmd1bWVudHMgYW5kIGNhbGxzIHNlbGVjdE5lc3RlZE5vZGUoKSB3aXRoIHRoZSByZXN1bHRpbmcgcGF0aC4KICAgICAqIDxwPlRoaXMgaXMgZXNwZWNpYWxseSB1c2VmdWwgd2hlbiB5b3UgaGF2ZSBzdHJpbmcgY29uc3RhbnRzIHRoYXQgeW91IG5lZWQgdG8gdXNlIGluc3RlYWQgb2YgaGFyZGNvZGVkCiAgICAgKiAgc3RyaW5ncy4gVHlwaW5nIDxjb2RlPmEsYixjPC9jb2RlPiBpcyBtdWNoIGVhc2llciB0aGFuIHR5cGluZyA8Y29kZT4iLyIgKyBDT05TVF9BICsgIi8iICsgQ09OU1RfQiArICIvIiArIENPTlNUX0M8L2NvZGU+LgogICAgICogIFdpdGggdGhpcyBmdW5jdGlvbiwgeW91IHNpbXBseSBjYWxsIDxjb2RlPnNlbGVjdEZyb21QYXRoKHBhcmVudFhtbCwgQ09OU1RfQSwgQ09OU1RfQiwgQ09OU1RfQyk7PC9jb2RlPjwvcD4KICAgICAqIEBwYXJhbSBwYXJlbnRYbWwgVGhlIGVsZW1lbnQgd2hvc2UgY2hpbGRyZW4gYW5kIGJleW9uZCB3aWxsIGJlIHNlYXJjaGVkLgogICAgICogIHBhcmFtIGFyZ3VtZW50cyBUaGUgc3RyaW5nIGFyZ3VtZW50cyB0aGF0IG1ha2UtdXAgdGhlIHBhdGguIFRoZSByZXN1bHQgaXMgaW4gdGhlIGZvcm0gb2YgPGNvZGU+Ii9hcmcxL2FyZzIvLi4uL2FyZ04iPC9jb2RlPi4gQXJncwogICAgICogIG5hbWVzIG1heSBiZSBxdWFsaWZpZWQgd2l0aCBhIG5hbWVzcGFjZSBwcmVmaXggYXMgaW4gPGNvZGU+InByZWZpeDE6bm9kZTEiLCAicHJlZml4Mjpub2RlMiIsICJub2RlMyI8L2NvZGU+LgogICAgICogQHJldHVybiBBbiBYTUwgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgbm9kZSByZWZlcmVuY2VkIGJ5IHRoZSBwYXRoIG9yIG51bGwgaWYgYSBtYXRjaCB3YXNuJ3QgbWFkZS4KICAgICAqIEBzZWUgI3NlbGVjdE5lc3RlZE5vZGUoKQogICAgICovCiAgICBYbWxVdGlsLnNlbGVjdEZyb21QYXRoID0gZnVuY3Rpb24gKHBhcmVudFhtbCkgewogICAgICAgIHBhcmVudFhtbCA9IGFyZ3VtZW50c1swXTsKICAgICAgICBpZiAoIXBhcmVudFhtbCkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHZhciBwYXRoID0gIiI7CgogICAgICAgIGZvciAodmFyIGkgPSAxOwogICAgICAgICAgICAgaSA8IGFyZ3VtZW50cy5sZW5ndGg7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgcGF0aCArPSAiLyIgKyBhcmd1bWVudHNbaV0udG9TdHJpbmcoKTsKICAgICAgICB9CgogICAgICAgIGlmIChwYXRoKSB7CiAgICAgICAgICAgIHJldHVybiBYbWxVdGlsLnNlbGVjdE5lc3RlZE5vZGUocGFyZW50WG1sLCBwYXRoKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBudWxsOwogICAgfTsKICAgIFhtbFV0aWwuc2VsZWN0TmVzdGVkTm9kZSA9IGZ1bmN0aW9uIChvUGFyZW50RWxlbWVudCwgc1BhdGgpIHsKICAgICAgICBpZiAob1BhcmVudEVsZW1lbnQgPT0gbnVsbCB8fCBzUGF0aCA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNQYXRoLnN1YnN0cigwLCAxKSA9PSAiLyIpIHsgLy8gc3VwcG9ydCBvcHRpb25hbCBsZWFkaW5nICIvIgogICAgICAgICAgICBzUGF0aCA9IHNQYXRoLnN1YnN0cigxKTsKICAgICAgICB9CgogICAgICAgIHZhciB0b2tzID0gc1BhdGguc3BsaXQoIi8iKTsKCiAgICAgICAgaWYgKHRva3MubGVuZ3RoID4gMCkgewogICAgICAgICAgICB2YXIgdG9rID0gdG9rc1swXTsgLy8gaXMgZWl0aGVyICJuYW1lIiBvciAicHJlZml4Om5hbWUiCgogICAgICAgICAgICB2YXIgdG9rUGFydHMgPSB0b2suc3BsaXQoIjoiKTsgLy8gaGFuZGxlIG5hbWVzcGFjZSBwcmVmaXggaWYgc3BlY2lmaWVkCiAgICAgICAgICAgIHZhciB0b2tOc1ByZWZpeCA9ICh0b2tQYXJ0cy5sZW5ndGggPT0gMiA/IHRva1BhcnRzWzBdIDogbnVsbCk7CiAgICAgICAgICAgIHZhciB0b2tOYW1lID0gKHRva1BhcnRzLmxlbmd0aCA9PSAxID8gdG9rUGFydHNbMF0gOiAodG9rUGFydHMubGVuZ3RoID09IDIgPyB0b2tQYXJ0c1sxXSA6IG51bGwpKTsKICAgICAgICAgICAgaWYgKG51bGwgPT0gdG9rTmFtZSkgewogICAgICAgICAgICAgICAgRGVidWcuZXJyb3IoImludmFsaWQgdG9rZW46ICIgKyB0b2spOwogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBlbGVtTGlzdCA9IG9QYXJlbnRFbGVtZW50LmVsZW1lbnRzKCk7CiAgICAgICAgICAgIHZhciBpdGVtLCBpID0gMDsKICAgICAgICAgICAgZm9yICg7CiAgICAgICAgICAgICAgICBpIDwgZWxlbUxpc3QubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgIGl0ZW0gPSBlbGVtTGlzdFtpXTsKICAgICAgICAgICAgICAgIGlmIChpdGVtLmxvY2FsTmFtZSgpID09IHRva05hbWUgJiYgKCF0b2tOc1ByZWZpeCB8fCBpdGVtLm5hbWVzcGFjZSh0b2tOc1ByZWZpeCkpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRva3MubGVuZ3RoID09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW07CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9Ob2RlID0gWG1sVXRpbC5zZWxlY3ROZXN0ZWROb2RlKGl0ZW0sIHNQYXRoLnN1YnN0cmluZyhzUGF0aC5pbmRleE9mKHRvaykgKyB0b2subGVuZ3RoICsgMSkpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAob05vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9Ob2RlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH07CiAgICBYbWxVdGlsLmRlY29kZVhtbENoYXJzID0gZnVuY3Rpb24gKHN0ciwgc3RyaWN0KSB7CiAgICAgICAgc3RyaWN0ID0gc3RyaWN0ICE9PSB1bmRlZmluZWQgPyBzdHJpY3QgOiBmYWxzZTsKICAgICAgICBpZiAoc3RyID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICBpZiAoc3RyLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9CgogICAgICAgIHZhciBkZWMgPSBzdHI7IC8vIHRoZSBkZWNvZGVkIHN0cmluZwoKICAgICAgICBkZWMgPSBkZWMucmVwbGFjZShuZXcgUmVnRXhwKCImbHQ7IiwgImciKSwgIjwiKTsKICAgICAgICBkZWMgPSBkZWMucmVwbGFjZShuZXcgUmVnRXhwKCImZ3Q7IiwgImciKSwgIj4iKTsKCiAgICAgICAgaWYgKHN0cmljdCkgewogICAgICAgICAgICBkZWMgPSBkZWMucmVwbGFjZShuZXcgUmVnRXhwKCImYXBvczsiLCAiZyIpLCAiJyIpOwogICAgICAgICAgICBkZWMgPSBkZWMucmVwbGFjZShuZXcgUmVnRXhwKCImcXVvdDsiLCAiZyIpLCAiXCIiKTsKICAgICAgICB9CgogICAgICAgIGRlYyA9IGRlYy5yZXBsYWNlKG5ldyBSZWdFeHAoIiZhbXA7IiwgImciKSwgIiYiKTsgLy8gZG8gdGhpcyAqbGFzdCogc28gdGhhdCB0aGUgYW1wZXJzYW5kcyBpbiB0aGUgcHJldmlvdXMgY29kZXMgZG9uJ3QgZ2V0IGNvbnZlcnRlZC4uLgogICAgICAgIHJldHVybiBkZWM7CiAgICB9OwogICAgWG1sVXRpbC5lbmNvZGVYbWxDaGFycyA9IGZ1bmN0aW9uIChzdHIsIHN0cmljdCkgewogICAgICAgIHN0cmljdCA9IHN0cmljdCAhPT0gdW5kZWZpbmVkID8gc3RyaWN0IDogZmFsc2U7CiAgICAgICAgaWYgKHN0ciA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKHN0ci5sZW5ndGggPT0gMCkgewogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQoKICAgICAgICB2YXIgZW5jID0gc3RyOyAvLyBlbmNvZGVkIHN0cmluZwoKICAgICAgICBlbmMgPSBlbmMucmVwbGFjZShuZXcgUmVnRXhwKCImIiwgImciKSwgIiZhbXA7Iik7IC8vIGRvIHRoaXMgKmZpcnN0KiBzbyB0aGF0IHRoZSBhbXBlcnNhbmRzIGluIHRoZSBmb2xsb3dpbmcgaW5zZXJ0ZWQgY29kZXMgZG9uJ3QgZ2V0IGNvbnZlcnRlZC4uLgogICAgICAgIGVuYyA9IGVuYy5yZXBsYWNlKG5ldyBSZWdFeHAoIjwiLCAiZyIpLCAiJmx0OyIpOwogICAgICAgIGVuYyA9IGVuYy5yZXBsYWNlKG5ldyBSZWdFeHAoIj4iLCAiZyIpLCAiJmd0OyIpOwoKICAgICAgICBpZiAoc3RyaWN0KSB7CiAgICAgICAgICAgIGVuYyA9IGVuYy5yZXBsYWNlKG5ldyBSZWdFeHAoIiciLCAiZyIpLCAiJmFwb3M7Iik7CiAgICAgICAgICAgIGVuYyA9IGVuYy5yZXBsYWNlKG5ldyBSZWdFeHAoJyInLCAiZyIpLCAiJnF1b3Q7Iik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZW5jOwogICAgfTsKICAgIFhtbFV0aWwuZ2V0Tm9kZVRleHQgPSBmdW5jdGlvbiAoeG1sb2JqLCBkZWVwLCBkZWNvZGUpIHsKICAgICAgICBkZWVwID0gZGVlcCAhPT0gdW5kZWZpbmVkID8gZGVlcCA6IHRydWU7CiAgICAgICAgZGVjb2RlID0gZGVjb2RlICE9PSB1bmRlZmluZWQgPyBkZWNvZGUgOiB0cnVlOwogICAgICAgIHZhciBub2RlID0gWG1sVXRpbC5nZXRYbWxPYmplY3QoeG1sb2JqKTsKCiAgICAgICAgaWYgKCFub2RlKSB7CiAgICAgICAgICAgIGlmICh0eXBlb2YgeG1sb2JqID09ICJzdHJpbmciKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZGVjb2RlID8gWG1sVXRpbC5kZWNvZGVYbWxDaGFycyhTdHJpbmcoeG1sb2JqKSkgOiBTdHJpbmcoeG1sb2JqKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG5vZGUuaGFzU2ltcGxlQ29udGVudCgpKSB7CiAgICAgICAgICAgIC8vIGFsd2F5cyB1c2UgWE1MLnRvU3RyaW5nKCksIGV2ZW4gaWYgaXQgZGVjb2RlcyB3aGVuIHdlIG1pZ2h0IG5vdCB3YW50IGl0IHRvLCBiZWNhdXNlIGl0J2xsIGVuc3VyZSB0aGF0IHdlIGdldCBldmVyeXRoaW5nLCBpbmNsdWRpbmcgc3BhY2VzLAogICAgICAgICAgICAvLyAgZXZlbiBpZiB0aGUgY29udGVudCBvZiB0aGUgbm9kZSBpcyBvbmx5IHdoaXRlc3BhY2UKICAgICAgICAgICAgdmFyIHNpbXBsZUNvbnRlbnQgPSBub2RlLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIGlmICghZGVjb2RlKSB7CiAgICAgICAgICAgICAgICBzaW1wbGVDb250ZW50ID0gWG1sVXRpbC5lbmNvZGVYbWxDaGFycyhzaW1wbGVDb250ZW50KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHNpbXBsZUNvbnRlbnQ7CiAgICAgICAgfQoKICAgICAgICAvL2dldCBhbGwgdGhlIG5vZGUncyBjaGlsZHJlbgogICAgICAgIHZhciBjaGlsZE5vZGUsIHNUZXh0ID0gIiI7CiAgICAgICAgdmFyIGxpc3QgPSBub2RlLmNoaWxkcmVuKCk7CgogICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgaSA8IGxpc3QubGVuZ3RoKCk7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgY2hpbGROb2RlID0gbGlzdFtpXTsKICAgICAgICAgICAgc3dpdGNoIChjaGlsZE5vZGUubm9kZUtpbmQoKSkgewogICAgICAgICAgICAgICAgY2FzZSBYbWxVdGlsLk5PREVLSU5EX1RFWFQgOgogICAgICAgICAgICAgICAgICAgIHNUZXh0ICs9IChkZWNvZGUgPyBjaGlsZE5vZGUudG9TdHJpbmcoKSA6IGNoaWxkTm9kZS50b1hNTFN0cmluZygpKTsgLy8gWE1MLnRvU3RyaW5nKCkgZGVjb2RlcyBlbmNvZGVkIFhNTCBjaGFyYWN0ZXJzCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBYbWxVdGlsLk5PREVLSU5EX0VMRU1FTlQgOgogICAgICAgICAgICAgICAgICAgIGlmIChkZWVwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNUZXh0ICs9IFhtbFV0aWwuZ2V0Tm9kZVRleHQoY2hpbGROb2RlLCBkZWVwLCBkZWNvZGUpOyAvLyByZWN1cnNpdmUgY2FsbAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHNUZXh0OwogICAgfTsKCiAgICBYbWxVdGlsLnNldE5vZGVUZXh0ID0gZnVuY3Rpb24gKG5vZGUsIHRleHQsIGtlZXBUZXh0LCBrZWVwRWxlbWVudHMsIGtlZXBDb21tZW50cywga2VlcFBJcykgewoKICAgICAgICBrZWVwVGV4dCA9IGtlZXBUZXh0ICE9PSB1bmRlZmluZWQgPyBrZWVwVGV4dCA6IGZhbHNlOwogICAgICAgIGtlZXBFbGVtZW50cyA9IGtlZXBFbGVtZW50cyAhPT0gdW5kZWZpbmVkID8ga2VlcEVsZW1lbnRzIDogZmFsc2U7CiAgICAgICAga2VlcENvbW1lbnRzID0ga2VlcENvbW1lbnRzICE9PSB1bmRlZmluZWQgPyBrZWVwQ29tbWVudHMgOiBmYWxzZTsKICAgICAgICBrZWVwUElzID0ga2VlcFBJcyAhPT0gdW5kZWZpbmVkID8ga2VlcFBJcyA6IGZhbHNlOwogICAgICAgIGlmICghbm9kZSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICAvLyBCZWZvcmUgYXNzaWduaW5nIHRoZSBuZXcgY29kZSwgd2UgaGF2ZSB0byBleHRyYWN0IGFsbCBjaGlsZCBlbGVtZW50cyB3ZSB3YW50IHRvIHByZXNlcnZlCiAgICAgICAgLy8gIG90aGVyd2lzZSB0aGV5IHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBub2RlJ3MgY29udGVudC4gV2hpbGUgdGhleSBnZXQgcmVtb3ZlZCBmcm9tIHRoZQogICAgICAgIC8vICBjb250ZW50IGFmdGVyIHNldHRpbmcgdGhlIHRleHQsIHRoZSBub2RlcyB0aGVtc2VsdmVzIGRvbid0IGdldCBkZWxldGVkICh0aGV5IGp1c3QgZ2V0CiAgICAgICAgLy8gIGRlLXJlZmVyZW5jZWQsIEkgc3VwcG9zZSkgc28gdGhleSBjYW4gZWFzaWx5IGJlIHJlLWFkZGVkIGFzIGNoaWxkcmVuLgoKICAgICAgICB2YXIgY29udGVudCA9IGtlZXBUZXh0ID8gWG1sVXRpbC5nZXROb2RlVGV4dChub2RlLCBmYWxzZSkgOiAiIjsKICAgICAgICB2YXIgZWxlbWVudHMgPSBrZWVwRWxlbWVudHMgPyBub2RlLmVsZW1lbnRzKCkgOiBuZXcgWE1MTGlzdCgpOwogICAgICAgIHZhciBjb21tZW50cyA9IGtlZXBDb21tZW50cyA/IG5vZGUuY29tbWVudHMoKSA6IG5ldyBYTUxMaXN0KCk7CiAgICAgICAgdmFyIHBpcyA9IGtlZXBQSXMgPyBub2RlLnByb2Nlc3NpbmdJbnN0cnVjdGlvbnMoKSA6IG5ldyBYTUxMaXN0KCk7CgogICAgICAgIC8vIHJlbW92ZSBldmVyeXRoaW5nIChzYW1lIHRoaW5nIHlvdSB3b3VsZCBnZXQgaWYgeW91IHVzZWQgRTRYIHRvIGFzc2lnbiB0aGUgdGV4dCB2YWx1ZSB0byB0aGUgbm9kZSdzIGNvbnRlbnQpCiAgICAgICAgWG1sVXRpbC5yZW1vdmVDaGlsZHJlbihub2RlKTsKCiAgICAgICAgdmFyIHhtbFNldHRpbmdzID0gWE1MLnNldHRpbmdzKCk7CgogICAgICAgIFhNTC5pZ25vcmVXaGl0ZXNwYWNlID0gZmFsc2U7CiAgICAgICAgWE1MLmlnbm9yZUNvbW1lbnRzID0gZmFsc2U7CiAgICAgICAgWE1MLmlnbm9yZVByb2Nlc3NpbmdJbnN0cnVjdGlvbnMgPSBmYWxzZTsKCiAgICAgICAgLy8gc2V0IHRoZSB0ZXh0IGNvbnRlbnQgKGluIEU0WCwgZXZlbiB0aG91Z2ggdGhlcmUgYXJlIG5vIGNoaWxkcmVuLCB5b3UgY2FuIHN0aWxsIGFjY2VzcyB0aGUgZmlyc3QgY2hpbGQpCiAgICAgICAgaWYgKG51bGwgIT0gdGV4dCkgewogICAgICAgICAgICBub2RlLnNldENoaWxkcmVuKGNvbnRlbnQgKyB0ZXh0KTsKICAgICAgICB9CiAgICAgICAgLy9ub2RlLmNoaWxkcmVuKClbMF0gPSBjb250ZW50ICsgdGV4dDsgLy8gdGhlIFhNTCBjbGFzcyB3aWxsIGF1dG9tYXRpY2FsbHkgZW5jb2RlIGFueSBYTUwgY2hhcmFjdGVycyBpbiB0aGUgdGV4dCAoZXhjZXB0IGZvciBhcG9zdHJvcGhlcyBhbmQgcXVvdGF0aW9uIG1hcmtzKQoKICAgICAgICB2YXIgaSwgZSwgYywgcDsKICAgICAgICBmb3IgKGkgPSAwOwogICAgICAgICAgICAgaSA8IGVsZW1lbnRzLmxlbmd0aCgpOwogICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgIGUgPSBlbGVtZW50c1tpXTsKICAgICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChlLCB0cnVlKTsKICAgICAgICB9CiAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgIGkgPCBjb21tZW50cy5sZW5ndGg7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgYyA9IGNvbW1lbnRzW2ldOwogICAgICAgICAgICBub2RlLmFwcGVuZENoaWxkKGMsIHRydWUpOwogICAgICAgIH0KICAgICAgICBmb3IgKGkgPSAwOwogICAgICAgICAgICAgaSA8IHBpcy5sZW5ndGg7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgcCA9IHBpc1tpXTsKICAgICAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChwLCB0cnVlKTsKICAgICAgICB9CgogICAgICAgIFhNTC5zZXRTZXR0aW5ncyh4bWxTZXR0aW5ncyk7CiAgICB9OwogICAgWG1sVXRpbC5yZW1vdmVDaGlsZHJlbiA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgWG1sVXRpbC5yZW1vdmVJdGVtcyhub2RlLmNoaWxkcmVuKCkpOwogICAgfTsKICAgIFhtbFV0aWwucmVtb3ZlTm9kZSA9IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgaWYgKCFub2RlKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgdmFyIG5vZGVMaXN0ID0gbmV3IFhNTExpc3Qobm9kZSk7CiAgICAgICAgWG1sVXRpbC5yZW1vdmVJdGVtcyhub2RlTGlzdCk7CiAgICB9OwogICAgWG1sVXRpbC5yZW1vdmVJdGVtcyA9IGZ1bmN0aW9uIChpdGVtcykgewogICAgICAgIHZhciB4bWxMaXN0OwogICAgICAgIGlmIChpdGVtcyBpbnN0YW5jZW9mIFhNTCB8fCBpdGVtcyBpbnN0YW5jZW9mIFhNTExpc3QpIHsKICAgICAgICAgICAgeG1sTGlzdCA9IGl0ZW1zOwogICAgICAgIH0KICAgICAgICBpZiAodHlwZW9mIGl0ZW1zID09ICJzdHJpbmciKSB7CiAgICAgICAgICAgIHhtbExpc3QgPSBuZXcgWE1MKGl0ZW1zKTsKICAgICAgICB9CiAgICAgICAgaWYgKHhtbExpc3QpIHsKICAgICAgICAgICAgZm9yICh2YXIgaiA9IGl0ZW1zLmxlbmd0aCgpIC0gMTsKICAgICAgICAgICAgICAgICBqID49IDA7CiAgICAgICAgICAgICAgICAgai0tKSB7CiAgICAgICAgICAgICAgICBpdGVtcy5EZWxldGUoaik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwogICAgWG1sVXRpbC5nZXRQYXJlbnQgPSBmdW5jdGlvbiAobm9kZVhtbCkgewogICAgICAgIHJldHVybiAobm9kZVhtbCA/IFhtbFV0aWwuZ2V0WG1sT2JqZWN0KG5vZGVYbWwucGFyZW50KCkpIDogbnVsbCk7CiAgICB9OwogICAgLyoqCiAgICAgKiBTZXQgYW4gWE1MIG9iamVjdCdzIGF0dHJpYnV0ZSB2YWx1ZS4gVGhlIGF0dHJpYnV0ZSB3aWxsIGJlIHJlbW92ZWQKICAgICAqIHdoZW4gdGhlIHZhbHVlIGlzIG51bGwuCiAgICAgKi8KICAgIFhtbFV0aWwuc2V0QXR0cmlidXRlID0gZnVuY3Rpb24gKHhtbG9iaiwgbmFtZSwgdmFsdWUpIHsKICAgICAgICBpZiAoIXhtbG9iaiB8fCAhbmFtZSkgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICB2YXIgZWxlbSA9IFhtbFV0aWwuZ2V0WG1sT2JqZWN0KHhtbG9iaik7CiAgICAgICAgaWYgKGVsZW0gIT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgZWxlbS5QdXQoJ0AnICsgbmFtZSwgdmFsdWUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIGxpc3QgPSBlbGVtLmF0dHJpYnV0ZShuYW1lKTsKICAgICAgICAgICAgICAgIGlmIChsaXN0ICYmIGxpc3QubGVuZ3RoKCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGxpc3RbMF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBYTUwgb2JqZWN0J3MgYXR0cmlidXRlIHZhbHVlLiBBbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQgaWYgdGhlIGF0dHJpYnV0ZSBpcyBub3QgZm91bmQgdW5sZXNzIGFuIGV4aXN0ZW5jZSBjaGVjayBpcyBwZXJmb3JtZWQuCiAgICAgKiBAcGFyYW0geG1sb2JqCiAgICAgKiBAcGFyYW0gYXR0ck5hbWUgQ2FuIGJlIHRoZSBsb2NhbCBuYW1lIChubyBuYW1lc3BhY2UpIG9ubHkgb3IgYSBuYW1lc3BhY2UgcXVhbGlmaWVyIG1heSBiZSBzcGVjaWZpZWQgKGUuZy4gZWl0aGVyICJuYW1lIiBvciAibnM6bmFtZSIpLgogICAgICogQHBhcmFtIGV4aXN0ZW5jZUNoZWNrIElmIHRydWUsIG51bGwgaXMgcmV0dXJuZWQgd2hlbiB0aGUgYXR0cmlidXRlIGlzbid0IHNwZWNpZmllZCAocmF0aGVyIHRoYW4gYW4gZW1wdHkgc3RyaW5nKS4KICAgICAqLwogICAgWG1sVXRpbC5nZXRBdHRyaWJ1dGUgPSBmdW5jdGlvbiAoeG1sb2JqLCBhdHRyTmFtZSwgZXhpc3RlbmNlQ2hlY2spIHsKICAgICAgICBleGlzdGVuY2VDaGVjayA9IGV4aXN0ZW5jZUNoZWNrICE9PSB1bmRlZmluZWQgPyBleGlzdGVuY2VDaGVjayA6IGZhbHNlOwogICAgICAgIHZhciBlbGVtID0gWG1sVXRpbC5nZXRYbWxPYmplY3QoeG1sb2JqKTsKCiAgICAgICAgaWYgKGVsZW0gJiYgYXR0ck5hbWUpIHsKICAgICAgICAgICAgdmFyIHBhcnRzID0gYXR0ck5hbWUuc3BsaXQoIjoiKTsKICAgICAgICAgICAgdmFyIG5zUHJlZml4ID0gKHBhcnRzLmxlbmd0aCA9PSAyID8gcGFydHNbMF0gOiBudWxsKTsKICAgICAgICAgICAgdmFyIGxvY2FsTmFtZSA9IChwYXJ0cy5sZW5ndGggPT0gMSA/IHBhcnRzWzBdIDogKHBhcnRzLmxlbmd0aCA9PSAyID8gcGFydHNbMV0gOiBudWxsKSk7CiAgICAgICAgICAgIHZhciBhdHRyLCBlbGVtZW50QXR0cmlidXRlcyA9IGVsZW0uYXR0cmlidXRlcygpOwoKICAgICAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOwogICAgICAgICAgICAgICAgIGluZGV4IDwgZWxlbWVudEF0dHJpYnV0ZXMubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICAgaW5kZXgrKykgewogICAgICAgICAgICAgICAgYXR0ciA9IGVsZW1lbnRBdHRyaWJ1dGVzW2luZGV4XTsKICAgICAgICAgICAgICAgIGlmIChhdHRyLmxvY2FsTmFtZSgpID09IGxvY2FsTmFtZSAmJiAoIW5zUHJlZml4IHx8IGF0dHIuaW5TY29wZU5hbWVzcGFjZXMobnNQcmVmaXgpKSkgewogICAgICAgICAgICAgICAgICAgIC8vIEF0dHJpYnV0ZSBmb3VuZAogICAgICAgICAgICAgICAgICAgIHJldHVybiBhdHRyLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLy8gQXR0cmlidXRlIG5vdCBmb3VuZAogICAgICAgIHJldHVybiBleGlzdGVuY2VDaGVjayA/IG51bGwgOiAiIjsKICAgIH07CiAgICBYbWxVdGlsLmdldFBJWG1sID0gZnVuY3Rpb24gKHBhcmVudCwgZG9tYWluLCBrZXksIHZhbHVlKSB7CiAgICAgICAgdmFsdWUgPSB2YWx1ZSB8fCBudWxsOwogICAgICAgIGlmICghcGFyZW50IHx8ICFrZXkgfHwgIWRvbWFpbikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHZhciBwaUxpc3QgPSBwYXJlbnQucHJvY2Vzc2luZ0luc3RydWN0aW9ucygpOwogICAgICAgIHZhciBwaSA9IG51bGw7CgogICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgaSA8IHBpTGlzdC5sZW5ndGg7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgdmFyIHBpU3RyID0gcGlMaXN0W2ldLnRvU3RyaW5nKCk7CiAgICAgICAgICAgIHZhciByZSA9IG5ldyBSZWdFeHAoWG1sVXRpbC5QSV9SRUdFWFAsIFhtbFV0aWwuUElfUkVHRVhQX0ZMQUdTKTsKICAgICAgICAgICAgdmFyIG1hdGNoZXMgPSByZS5leGVjKHBpU3RyKTsKCiAgICAgICAgICAgIC8vdG9kbwogICAgICAgICAgICBpZiAobWF0Y2hlcyAmJiBtYXRjaGVzLnBpRG9tYWluID09IGRvbWFpbiAmJiBtYXRjaGVzLnBpS2V5ID09IGtleSkgewogICAgICAgICAgICAgICAgaWYgKCF2YWx1ZSB8fCBtYXRjaGVzLnBpVmFsdWUgPT0gdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICBwaSA9IHBpTGlzdFtpXTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcGk7CiAgICB9OwoKICAgIFhtbFV0aWwuZ2V0UElYbWxQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKHBpKSB7CiAgICAgICAgaWYgKCFwaSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHZhciBwaVN0ciA9IHBpLnRvU3RyaW5nKCk7CiAgICAgICAgdmFyIHJlID0gbmV3IFJlZ0V4cChYbWxVdGlsLlBJX1JFR0VYUCwgWG1sVXRpbC5QSV9SRUdFWFBfRkxBR1MpOwogICAgICAgIHZhciBtYXRjaGVzID0gcmUuZXhlYyhwaVN0cik7CgogICAgICAgIGlmIChtYXRjaGVzKSB7CiAgICAgICAgICAgIHZhciBwcm9wcyA9IHt9OwogICAgICAgICAgICBwcm9wcy5kb21haW4gPSBtYXRjaGVzLnBpRG9tYWluOwogICAgICAgICAgICBwcm9wcy5rZXkgPSBtYXRjaGVzLnBpS2V5OwogICAgICAgICAgICBpZiAobWF0Y2hlcy5waVZhbHVlKSB7CiAgICAgICAgICAgICAgICBwcm9wcy52YWx1ZSA9IG1hdGNoZXMucGlWYWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcHJvcHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfTsKCiAgICAvKioKICAgICAqIFNlYXJjaGVzIHRoZSBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBvbiB0aGUgc3BlY2lmaWVkIG5vZGUgZm9yIGEgUEkgdGhhdCBoYXMgYSBtYXRjaGluZyBkb21haW4gYW5kIGtleS4gSWYgYSB2YWx1ZSBpcyBwcm92aWRlZCwgdGhlIHZhbHVlIHdpbGwgYmUgbWF0Y2hlZCBhcyB3ZWxsLgogICAgICogIFRoZSBzZWFyY2ggaXMgY2FzZS1zZW5zaXRpdmUuCiAgICAgKiBAcGFyYW0gcGFyZW50IFhNTCBub2RlIHRoYXQgY29udGFpbnMgdGhlIFBJcyB0byBiZSBzZWFyY2hlZC4KICAgICAqIEBwYXJhbSBwaSBEeW5hbWljIG9iamVjdCB3aXRoIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczogImRvbWFpbiIgKFJlcXVpcmVkL1N0cmluZywgdGhlIFBJJ3MgZG9tYWluKSwgImtleSIgKFJlcXVpcmVkL1N0cmluZywgdGhlIFBJJ3Mga2V5KS4KICAgICAqIEBwYXJhbSB2YWx1ZU1hdGNoIE9wdGlvbmFsIHZhbHVlIHRvIG1hdGNoIGFzIHdlbGwuIElmIHNwZWNpZmllZCwgYSAmbHQ7P2RvbWFpbiBrZXkgdmFsdWVNYXRjaD8mZ3Q7IFBJIG11c3QgZXhpc3QgZm9yIHRoZSBzZWFyY2ggdG8gc3VjY2VlZC4gU3BlY2lmeWluZwogICAgICogIGFuIGVtcHR5IHN0cmluZyBmb3IgdGhpcyBwYXJhbWV0ZXIgd2lsbCB5aWVsZCB0aGUgc2FtZSByZXN1bHRzIGFzIHNwZWNpZnlpbmcgbnVsbC4KICAgICAqIEByZXR1cm4gVGhlIFBJJ3MgdmFsdWUgKGNvdWxkIGJlIGFuIGVtcHR5IHN0cmluZykgaWYgYSBtYXRjaGluZyBQSSB3YXMgbG9jYXRlZCwgbnVsbCBvdGhlcndpc2UuCiAgICAgKi8KICAgIFhtbFV0aWwuZmluZFBJT2JqID0gZnVuY3Rpb24gKHBhcmVudCwgcGksIHZhbHVlTWF0Y2gpIHsKICAgICAgICB2YWx1ZU1hdGNoID0gdmFsdWVNYXRjaCB8fCBudWxsOwogICAgICAgIGlmICghcGFyZW50KSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFwaS5oYXNPd25Qcm9wZXJ0eSgiZG9tYWluIikgfHwgIXBpLmhhc093blByb3BlcnR5KCJrZXkiKSkgewogICAgICAgICAgICBEZWJ1Zy5lcnJvcigibWlzc2luZyByZXF1aXJlZCBwcm9wZXJ0aWVzIGluIHBpIG9iamVjdDogJ2RvbWFpbicgYW5kICdrZXknIik7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgdmFyIHBpWG1sID0gWG1sVXRpbC5nZXRQSVhtbChwYXJlbnQsIHBpLmRvbWFpbiwgcGkua2V5LCB2YWx1ZU1hdGNoKTsKICAgICAgICBpZiAocGlYbWwpIHsKICAgICAgICAgICAgcmV0dXJuIFhtbFV0aWwuZ2V0UElYbWxWYWx1ZShwaVhtbCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH07CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgJmx0Oz9kb21haW4ga2V5IHZhbHVlPyZndDsgUEkuIFRoZSB2YWx1ZSBtYXkgY29udGFpbiAob3IgYmUpIHdoaXRlc3BhY2UgYnV0IHRoZSBkb21haW4gYW5kIGtleSBtdXN0IG5vdC4KICAgICAqIEBwYXJhbSBwaSBYTUwgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgUEkgd2hvc2UgdmFsdWUgaXMgdG8gYmUgcmV0dXJuZWQuCiAgICAgKiBAcmV0dXJuIFRoZSBQSSdzIHZhbHVlIGFzIGEgc3RyaW5nLiBJZiB0aGUgUEkgZG9lc24ndCBoYXZlIGEgdmFsdWUsIGFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZC4gSWYgdGhlIFBJIGRvZXNuJ3QgaGF2ZSBhIGRvbWFpbiBhbmQga2V5LCBudWxsIGlzIHJldHVybmVkLgogICAgICovCiAgICBYbWxVdGlsLmdldFBJWG1sVmFsdWUgPSBmdW5jdGlvbiAocGkpIHsKICAgICAgICBpZiAoIXBpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICB2YXIgcHJvcHMgPSBYbWxVdGlsLmdldFBJWG1sUHJvcGVydGllcyhwaSk7CiAgICAgICAgaWYgKHByb3BzKSB7CiAgICAgICAgICAgIHJldHVybiBwcm9wcy5oYXNPd25Qcm9wZXJ0eSgidmFsdWUiKSA/IHByb3BzLnZhbHVlIDogIiI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH07CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhICZsdDs/ZG9tYWluIGtleSB2YWx1ZT8mZ3Q7IFBJLiBUaGUgdmFsdWUgbWF5IGNvbnRhaW4gKG9yIGJlKSB3aGl0ZXNwYWNlIGJ1dCB0aGUgZG9tYWluIGFuZCBrZXkgbXVzdCBub3QuCiAgICAgKiBAcGFyYW0gcGkgWE1MIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIFBJIHdob3NlIHZhbHVlIGlzIHRvIGJlIHJldHVybmVkLgogICAgICogQHJldHVybiBUaGUgUEkncyB2YWx1ZSBhcyBhIHN0cmluZy4gSWYgdGhlIFBJIGRvZXNuJ3QgaGF2ZSBhIHZhbHVlLCBhbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQuIElmIHRoZSBQSSBkb2Vzbid0IGhhdmUgYSBkb21haW4gYW5kIGtleSwgbnVsbCBpcyByZXR1cm5lZC4KICAgICAqLwogICAgWG1sVXRpbC5nZXRQSVhtbFZhbHVlZnVuY3Rpb24gPSBmdW5jdGlvbiAocGkpIHsKICAgICAgICBpZiAoIXBpKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgICB2YXIgcHJvcHMgPSBYbWxVdGlsLmdldFBJWG1sUHJvcGVydGllcyhwaSk7CiAgICAgICAgaWYgKHByb3BzKSB7CiAgICAgICAgICAgIHJldHVybiBwcm9wcy5oYXNPd25Qcm9wZXJ0eSgidmFsdWUiKSA/IHByb3BzLnZhbHVlIDogIiI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH07CgogICAgLyoqCiAgICAgKiBEZXRlcm1pbmVzIHRoZSBxdWFsaWZpZWQgbmFtZSBvZiB0aGUgbm9kZSAobmFtZXNwYWNlIDxiPnByZWZpeDwvYj4gYWRkZWQgaWYgdGhlIG5vZGUgaGFzIGEgbmFtZXNwYWNlKS4gVGhpcyBkaWZmZXJzIGZyb20gdGhlIFFOYW1lIG9iamVjdAogICAgICogIHdoaWNoIHByaW50cyBVUkk6OmxvY2FsTmFtZSAocHJpbnRzIHRoZSBVUkkgcmF0aGVyIHRoYW4gdGhlIHByZWZpeCBhbmQgdXNlcyBkb3VibGUgY29sb25zIHJhdGhlciB0aGFuIGEgc2luZ2xlKS4KICAgICAqIEBwYXJhbSBub2RlWG1sIFRoZSBub2RlIHdob3NlIHF1YWxpZmllZCBuYW1lIGlzIHRvIGJlIHByaW50ZWQuCiAgICAgKiBAcmV0dXJuIFRoZSBxdWFsaWZpZWQgbmFtZSAoaW5jbHVkZXMgbmFtZXNwYWNlIHByZWZpeCBpZiBub2RlIGhhcyBuYW1lc3BhY2UpIG9yIGVtcHR5IHN0cmluZyBpZiBub2RlIGlzIG51bGwgb3IgaXNuJ3QgYW4gZWxlbWVudCBvciBhdHRyaWJ1dGUuCiAgICAgKi8KICAgIFhtbFV0aWwucXVhbGlmaWVkTmFtZSA9IGZ1bmN0aW9uIChub2RlWG1sKSB7CiAgICAgICAgaWYgKCFub2RlWG1sIHx8IChub2RlWG1sLm5vZGVLaW5kKCkgIT0gWG1sVXRpbC5OT0RFS0lORF9FTEVNRU5UICYmIG5vZGVYbWwubm9kZUtpbmQoKSAhPSBYbWxVdGlsLk5PREVLSU5EX0FUVFJJQlVURSkpIHsKICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0KCiAgICAgICAgdmFyIG5hbWUgPSAiIjsKICAgICAgICB2YXIgbnMgPSBub2RlWG1sLm5hbWVzcGFjZSgpOwoKICAgICAgICBpZiAobnMpIHsKICAgICAgICAgICAgaWYgKHR5cGVvZiBucy5wcmVmaXggPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICAgICAgICAgIC8vIEl0IHNlZW1zIHRoYXQgdGhlcmUgYXJlIGNhc2VzIHdoZW4gYW4gZWxlbWVudCBvciBhdHRyaWJ1dGUgbWF5IGhhdmUgYSBuYW1lc3BhY2UgcHJlZml4IGJ1dCB0aGUgbmFtZXNwYWNlIGlzbid0IGRlZmluZWQgYW55d2hlcmUgaW4gdGhlIFhNTCBkb2N1bWVudC4KICAgICAgICAgICAgICAgIC8vICBTdHJhbmdlIGJ1dCB0cnVlLiBQZXJoYXBzIGl0J3MgT0sgd2hlbiB0aGUgbmFtZXNwYWNlIHByZWZpeCBpcyBhIHdlbGwta25vdyBwcmVmaXggbGlrZSAieG1sIiB3aGljaCBpcyB3aHkgdGhlIE5hbWVzcGFjZSBvYmplY3QsIGluIHRoYXQgY2FzZSwKICAgICAgICAgICAgICAgIC8vICBjb250YWlucyBhbiB1bmRlZmluZWQgcHJlZml4IGJ1dCBtYW5hZ2VzIHRvIHByb2R1Y2UgYSB1cmkgb2YgImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIuCiAgICAgICAgICAgICAgICAvLyBFeGFtcGxlOiBJbiBhbiBYTVAgcGFja2V0IGluc2lkZSBhbiBYRFAsIHlvdSdsbCBmaW5kIDxyZGY6bGkgeG1sOmxhbmc9IngtZGVmYXVsdCI+e3RpdGxlfTwvcmRmOmxpPiB3aGVyZSAieG1sIiBpcyBub3QgZGVmaW5lZCBpbiB0aGUgWERQIGRvYy4KICAgICAgICAgICAgICAgIGlmIChucy51cmkgPT0gImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSIpIHsKICAgICAgICAgICAgICAgICAgICBuYW1lICs9ICJ4bWw6IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmIChucy5wcmVmaXggIT0gIiIpIHsKICAgICAgICAgICAgICAgIG5hbWUgKz0gbnMucHJlZml4ICsgIjoiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIG5hbWUgKz0gbm9kZVhtbC5sb2NhbE5hbWUoKTsKICAgICAgICByZXR1cm4gbmFtZTsKICAgIH07CgogICAgLyoqCiAgICAgKiBQcmludHMgdGhlIGF0dHJpYnV0ZXMgc3BlY2lmaWVkIG9uIHRoZSBYTUwgbm9kZS4KICAgICAqIEBwYXJhbSBub2RlWG1sIFRoZSBlbGVtZW50IHdob3NlIGF0dHJpYnV0ZXMgYXJlIHRvIGJlIHByaW50ZWQuCiAgICAgKiBAcmV0dXJuIFRoZSBwcmludGVkIHZlcnNpb24gb2YgdGhlIFhNTCBub2RlJ3MgYXR0cmlidXRlcywgYWxsIG9uIGEgc2luZ2xlIGxpbmUuIElmIHRoZSBub2RlIGhhcyBubyBhdHRyaWJ1dGVzLCBhbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQuCiAgICAgKi8KICAgIFhtbFV0aWwuX3ByaW50WG1sQXR0cmlidXRlcyA9IGZ1bmN0aW9uIChub2RlWG1sKSB7CiAgICAgICAgaWYgKCFub2RlWG1sIHx8IG5vZGVYbWwubm9kZUtpbmQoKSAhPSBYbWxVdGlsLk5PREVLSU5EX0VMRU1FTlQpIHsKICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0KCiAgICAgICAgdmFyIHByaW50ID0gIiI7CiAgICAgICAgdmFyIGF0dExpc3QgPSBub2RlWG1sLmF0dHJpYnV0ZXMoKTsKCiAgICAgICAgZm9yICh2YXIgaSA9IDA7CiAgICAgICAgICAgICBpIDwgYXR0TGlzdC5sZW5ndGgoKTsKICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICB2YXIgYXR0WG1sID0gYXR0TGlzdFtpXTsKICAgICAgICAgICAgaWYgKHByaW50Lmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIHByaW50ICs9ICIgIjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHJpbnQgKz0gWG1sVXRpbC5xdWFsaWZpZWROYW1lKGF0dFhtbCk7CiAgICAgICAgICAgIC8vIHN0cmljdD10cnVlIGluIHRoZSBmb2xsb3dpbmcgZW5jb2RpbmcgZnVuY3Rpb24gc28gdGhhdCBpdCBlbmNvZGVzIGZvciBhbGwgZml2ZSBjaGFyYWN0ZXJzICgmLCcsIiw8LD4pCiAgICAgICAgICAgIC8vIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdG9TdHJpbmcoKSBmdW5jdGlvbiBkZWNvZGVzIGFsbCBmaXZlIGNoYXJhY3RlcnMuCiAgICAgICAgICAgIHZhciB2YWx1ZSA9IG51bGw7CiAgICAgICAgICAgIGlmIChhdHRYbWwpIHsKICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYXR0WG1sLnRvWE1MU3RyaW5nID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBhdHRYbWwudG9YTUxTdHJpbmcoKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBhdHRYbWwudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCArPSAnPSInICsgWG1sVXRpbC5lbmNvZGVYbWxDaGFycyhYbWxVdGlsLmRlY29kZVhtbENoYXJzKHZhbHVlLCB0cnVlKSwgdHJ1ZSkgKyAnIic7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwcmludDsKICAgIH07CgogICAgLyoqCiAgICAgKiBQcmludHMgYW4gWE1MIGVsZW1lbnQuCiAgICAgKiBAcGFyYW0gbm9kZVhtbCBUaGUgZWxlbWVudCB0byBwcmludC4KICAgICAqIEBwYXJhbSBpbmRlbnRTdHIgVGhlIGluZGVudGF0aW9uIHN0cmluZyB0byBwcmVwZW5kIHRvIHRoZSBwcmludGVkIG91dHB1dC4KICAgICAqIEBwYXJhbSBwcmludE9wZW4gVHJ1ZSBpZiB0aGUgb3BlbmluZyBvZiB0aGUgZWxlbWVudCBzaG91bGQgYmUgcHJpbnRlZDsgZmFsc2UgaWYgdGhlIGNsb3Npbmcgc2hvdWxkIGJlIHByaW50ZWQuIElmIHRydWUgYW5kIHRoZSBub2RlCiAgICAgKiAgaGFzIG5vIGNoaWxkcmVuLCB0aGUgbm9kZSBpcyBwcmludGVkIGFzIGEgY2xvc2VkIGVsZW1lbnQgKGUuZy4gJmx0O2VsZW0vJmd0OykuCiAgICAgKiBAcmV0dXJuIFRoZSBwcmludGVkIHZlcnNpb24gb2YgdGhlIFhNTCBlbGVtZW50LiBJZiB0aGUgbm9kZSBpcyBudWxsLCBhbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQuCiAgICAgKi8KICAgIFhtbFV0aWwuX3ByaW50WG1sRWxlbWVudCA9IGZ1bmN0aW9uIChub2RlWG1sLCBpbmRlbnRTdHIsIHByaW50T3BlbikgewogICAgICAgIGlmICghbm9kZVhtbCB8fCBub2RlWG1sLm5vZGVLaW5kKCkgIT0gWG1sVXRpbC5OT0RFS0lORF9FTEVNRU5UKSB7CiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9CiAgICAgICAgdmFyIHByaW50ID0gIjwiOwogICAgICAgIGlmICghcHJpbnRPcGVuKSB7CiAgICAgICAgICAgIHByaW50ICs9ICIvIjsKICAgICAgICB9CiAgICAgICAgLy8gLS0gcHJpbnQgdGhlIHF1YWxpZmllZCBuYW1lCiAgICAgICAgcHJpbnQgKz0gWG1sVXRpbC5xdWFsaWZpZWROYW1lKG5vZGVYbWwpOwoKICAgICAgICBpZiAocHJpbnRPcGVuKSB7CgogICAgICAgICAgICAvL0FkZGluZyBkZWZhdWx0IG5hbWVzcGFjZQogICAgICAgICAgICB2YXIgbnMgPSBub2RlWG1sLl9EZWZhdWx0TmFtZXNwYWNlOwogICAgICAgICAgICBpZiAobnMgJiYgbnMudXJpICYmIFhtbFV0aWwucXVhbGlmaWVkTmFtZShub2RlWG1sKSA9PSAiYm9keSIpIHsKICAgICAgICAgICAgICAgIHByaW50ICs9ICIgeG1sbnM9XCIiICsgbnMudXJpICsgIlwiICI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHByaW50IHRoZSBvcGVuaW5nIG9mIHRoZSBlbGVtZW50CiAgICAgICAgICAgIC8vIC0tIHByaW50IHRoZSBuYW1lc3BhY2VzCiAgICAgICAgICAgIC8vIHRoaXMgd2lsbCBsaXN0IG9ubHkgbmV3IG5hbWVzcGFjZXM7IGluLXNjb3BlIG5hbWVzcGFjZXMgd2lsbCBub3QgYmUgaW4gdGhpcyBsaXN0CiAgICAgICAgICAgIHZhciBuc0xpc3QgPSBub2RlWG1sLm5hbWVzcGFjZURlY2xhcmF0aW9ucygpOwogICAgICAgICAgICB2YXIgbnNTY29wZUxpc3QgPSBub2RlWG1sLmluU2NvcGVOYW1lc3BhY2VzKCk7CgogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsKICAgICAgICAgICAgICAgICBpIDwgbnNMaXN0Lmxlbmd0aDsKICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBucyA9IG5zTGlzdFtpXTsKICAgICAgICAgICAgICAgIC8vIGFkZCBuYW1lc3BhY2UgZGVjbGFyYXRpb24KICAgICAgICAgICAgICAgIHByaW50ICs9ICIgeG1sbnMiOwogICAgICAgICAgICAgICAgLy8gY2hlY2sgZm9yIGRlZmF1bHQgbmFtZXNwYWNlCiAgICAgICAgICAgICAgICBpZiAobnMucHJlZml4ICE9ICIiKSB7CiAgICAgICAgICAgICAgICAgICAgcHJpbnQgKz0gIjoiICsgbnMucHJlZml4OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcHJpbnQgKz0gJz0iJyArIG5zLnVyaSArICciJzsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyAtLSBwcmludCB0aGUgYXR0cmlidXRlcwogICAgICAgICAgICB2YXIgYXR0cyA9IFhtbFV0aWwuX3ByaW50WG1sQXR0cmlidXRlcyhub2RlWG1sKTsKICAgICAgICAgICAgaWYgKGF0dHMubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgcHJpbnQgKz0gIiAiICsgYXR0czsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyAtLSBwb3N0Zml4CiAgICAgICAgICAgIC8vIGlmIG5vIGNoaWxkcmVuLCBjbG9zZSB0aGUgbm9kZQogICAgICAgICAgICBpZiAobm9kZVhtbC5jaGlsZHJlbigpLmxlbmd0aCgpID09IDApIHsKICAgICAgICAgICAgICAgIHByaW50ICs9ICIvIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludCArPSAiPiI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gcHJpbnQgdGhlIGNsb3Npbmcgb2YgdGhlIGVsZW1lbnQKICAgICAgICAgICAgcHJpbnQgKz0gIj4iOwogICAgICAgIH0KICAgICAgICByZXR1cm4gaW5kZW50U3RyICsgcHJpbnQ7CiAgICB9OwoKICAgIC8qKgogICAgICogUmVjdXJzaXZlIGhlbHBlciBmdW5jdGlvbiB0byBYbWxVdGlsLnByaW50KCkuCiAgICAgKiBAcGFyYW0gbm9kZVhtbCBUaGUgWE1MIG5vZGUgdG8gcHJpbnQuCiAgICAgKiBAcGFyYW0gb3B0aW9ucyBQcmludCBvcHRpb25zLiBFeHBlY3RlZCBwcm9wZXJ0aWVzIGFyZSBhcyBmb2xsb3dzOgogICAgICogIDxwPnByZXR0eTogQm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdG8gcHJldHR5LXByaW50IG9yIG5vdC48L3A+CiAgICAgKiAgPHA+aW5kZW50OiBpbnQgc3BlY2lmeWluZyB0aGUgZGVwdGggdG8gaW5kZW50IHdoZW4gcHJldHR5LXByaW50aW5nLjwvcD4KICAgICAqICA8cD5sZXZlbDogaW50IHNwZWNpZnlpbmcgdGhlIGN1cnJlbnQgbGV2ZWwgb2YgcmVjdXJzaW9uLjwvcD4KICAgICAqICA8cD5maWx0ZXI6IEZ1bmN0aW9uIHRvIGNhbGwgdG8gZmlsdGVyIG5vZGVzLiBDYW4gYmUgbnVsbC48L3A+CiAgICAgKiBAcmV0dXJuIFRoZSBwcmludGVkIHZlcnNpb24gb2YgdGhlIFhNTCBub2RlIChjb3VsZCBiZSBhbiBlbXB0eSBzdHJpbmcpLiBOdWxsIGlmIHRoZSBub2RlIHdhcyBmaWx0ZXJlZC1vdXQuIEVtcHR5IHN0cmluZyBpZiBub2RlWG1sIHdhcyBudWxsLgogICAgICogQHNlZSAjcHJpbnQoKQogICAgICovCiAgICBYbWxVdGlsLl9wcmludFhtbE5vZGUgPSBmdW5jdGlvbiAobm9kZVhtbCwgb3B0aW9ucykgewogICAgICAgIGlmICghbm9kZVhtbCkgewogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQoKICAgICAgICB2YXIgcHJpbnQgPSAiIjsKICAgICAgICB2YXIgaW5kZW50U3RyID0gb3B0aW9ucy5wcmV0dHkgPyBYbWxVdGlsLnJlcGVhdChYbWxVdGlsLl9QUkVUVFlQUklOVF9JTkRFTlRfQ0hBUiwgb3B0aW9ucy5pbmRlbnQgKiBvcHRpb25zLmxldmVsKSA6ICIiOwogICAgICAgIHZhciBwcmV0dHlJbnNpZGUgPSBvcHRpb25zLnByZXR0eTsKICAgICAgICB2YXIgZmlsdGVyT3B0aW9ucyA9IG51bGw7CgogICAgICAgIGlmIChvcHRpb25zLmZpbHRlciAhPSBudWxsKSB7CiAgICAgICAgICAgIGZpbHRlck9wdGlvbnMgPSB7cHJldHR5SW5zaWRlIDogcHJldHR5SW5zaWRlLCBrZWVwIDogdHJ1ZX07CgogICAgICAgICAgICBpZiAob3B0aW9ucy5maWx0ZXIuY2FsbChudWxsLCBub2RlWG1sLCBmaWx0ZXJPcHRpb25zKSA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICBpZiAoIWZpbHRlck9wdGlvbnMua2VlcCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcHJldHR5SW5zaWRlID0gZmlsdGVyT3B0aW9ucy5wcmV0dHlJbnNpZGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmaWx0ZXJPcHRpb25zID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc3dpdGNoIChub2RlWG1sLm5vZGVLaW5kKCkpIHsKICAgICAgICAgICAgY2FzZSBYbWxVdGlsLk5PREVLSU5EX0VMRU1FTlQgOgogICAgICAgICAgICAgICAgLy8gdXNlIHRoaXMgbm9kZSdzIHByZXR0eSBzZXR0aW5nCiAgICAgICAgICAgICAgICBwcmludCArPSAoKHByaW50Lmxlbmd0aCA+IDAgJiYgb3B0aW9ucy5wcmV0dHkpID8gIlxuIiA6ICIiKSArIFhtbFV0aWwuX3ByaW50WG1sRWxlbWVudChub2RlWG1sLCBpbmRlbnRTdHIsIHRydWUpOwoKICAgICAgICAgICAgICAgIC8vIHVzZSB0aGUgY2hpbGRyZW4ncyBwcmV0dHkgc2V0dGluZyAocHJldHR5SW5zaWRlKQogICAgICAgICAgICAgICAgaWYgKG5vZGVYbWwuY2hpbGRyZW4oKS5sZW5ndGgoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICBpZiAobm9kZVhtbC5jaGlsZHJlbigpLmxlbmd0aCgpID09IDEgJiYgbm9kZVhtbC5jaGlsZHJlbigpWzBdLm5vZGVLaW5kKCkgPT0gWG1sVXRpbC5OT0RFS0lORF9URVhUICYmIGZpbHRlck9wdGlvbnMgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBPdmVycmlkZSB0aGUgcHJldHR5IHNldHRpbmcgZm9yIGNoaWxkcmVuIGlmIHRoZXJlJ3Mgb25seSBvbmUsIGl0J3MgYSB0ZXh0IG5vZGUgYW5kIHRoZSBmaWx0ZXIgZnVuY3Rpb24gZGlkbid0IGV4cGxpY2l0bHkKICAgICAgICAgICAgICAgICAgICAgICAgLy8gIHJlcXVlc3QgdGhhdCB0aGUgY29udGVudHMgb2YgdGhpcyBub2RlIGJlIHByZXR0eS1wcmludGVkLgogICAgICAgICAgICAgICAgICAgICAgICAvLyBYTUwgcGFyc2VycyB0eXBpY2FsbHkgb3V0cHV0IGVsZW1lbnRzIHdpdGggYSBzaW5nbGUgdGV4dCBub2RlIGFsbCBvbiBhIHNpbmdsZSBsaW5lLiBUaGlzIGVuc3VyZXMgdGhhdCB3aGl0ZXNwYWNlIHdpdGhpbiB0ZXh0IG5vZGVzIHJlbWFpbnMgaW50YWN0LgogICAgICAgICAgICAgICAgICAgICAgICAvLyBXQVJOSU5HOiBEaXNhYmxpbmcgdGhpcyB3aWxsIGxlYWQgdG8gdW5leHBlY3RlZCBiZWhhdmlvdXIuIEZvciBleGFtcGxlLCBEZXNpZ25lciBjcmFzaGVzIHdoZW4gInBhc3RpbmcgdGhlIHByaW50LW91dCBpbnRvIFhNTCBTb3VyY2UsIGdvaW5nIHRvIERlc2lnbgogICAgICAgICAgICAgICAgICAgICAgICAvLyAgVmlldyBhbmQgdGhlbiBiYWNrIHRvIFhNTCBTb3VyY2UiIGlmIHRoaXMgb3ZlcnJpZGUgaXMgbm90IGFwcGxpZWQuCiAgICAgICAgICAgICAgICAgICAgICAgIHByZXR0eUluc2lkZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gTWFrZSBhIGNvcHkgYW5kIGFwcGx5IHNldHRpbmdzIGZvciBjaGlsZHJlbiBvbiB0aGUgY29weSBzaW5jZSBvYmplY3RzIGFyZSBwYXNzZWQgYnkgcmVmZXJlbmNlLgogICAgICAgICAgICAgICAgICAgIC8vIFdBUk5JTkc6IERvIG5vdCB1c2UgT2JqZWN0VXRpbC5jb3B5KCkgYmVjYXVzZSBpdCB3b24ndCBjb3B5IHRoZSBmaWx0ZXIgcHJvcGVydHkgZm9yIHNvbWUgcmVhc29uIChwZXJoYXBzIGl0IG9ubHkgY2xvbmVzIHByb3BlcnRpZXMgdGhhdCBhcmUgcHJpbWl0aXZlIHR5cGVzPykuCiAgICAgICAgICAgICAgICAgICAgdmFyIGluc2lkZU9wdGlvbnMgPSB7cHJldHR5IDogcHJldHR5SW5zaWRlLCBpbmRlbnQgOiBvcHRpb25zLmluZGVudCwgbGV2ZWwgOiBvcHRpb25zLmxldmVsICsgMSwgZmlsdGVyIDogb3B0aW9ucy5maWx0ZXJ9OwoKICAgICAgICAgICAgICAgICAgICB2YXIgaW5zaWRlUHJpbnQgPSAiIjsKICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRFbGVtZW50cyA9IG5vZGVYbWwuY2hpbGRyZW4oKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgIGkgPCBjaGlsZEVsZW1lbnRzLmxlbmd0aCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IGNoaWxkRWxlbWVudHNbaV07CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZFByaW50ID0gWG1sVXRpbC5fcHJpbnRYbWxOb2RlKGNoaWxkLCBpbnNpZGVPcHRpb25zKTsgLy8gcmVjdXJzaXZlIGNhbGwKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkUHJpbnQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zaWRlUHJpbnQgKz0gKChpbnNpZGVQcmludC5sZW5ndGggPiAwICYmIHByZXR0eUluc2lkZSkgPyAiXG4iIDogIiIpICsgY2hpbGRQcmludDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gYWRkIHRoZSBpbnNpZGUgcHJpbnRlZCBjb250ZW50IChpZiBhbnkpIHRvIHRoZSBwcmludCBjb250ZW50LCBjbG9zaW5nIG5vZGUgdGhlIGFwcHJvcHJpYXRlIHdheQogICAgICAgICAgICAgICAgICAgIGlmIChpbnNpZGVQcmludC5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFkZCBpbnNpZGUgY29udGVudCBhbmQgY2xvc2Ugd2l0aCA8L25vZGU+IHN5bnRheAogICAgICAgICAgICAgICAgICAgICAgICBwcmludCArPSAoKHByaW50Lmxlbmd0aCA+IDAgJiYgcHJldHR5SW5zaWRlKSA/ICJcbiIgOiAiIikgKyBpbnNpZGVQcmludDsKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQgKz0gKChwcmludC5sZW5ndGggPiAwICYmIHByZXR0eUluc2lkZSkgPyAiXG4iIDogIiIpICsgWG1sVXRpbC5fcHJpbnRYbWxFbGVtZW50KG5vZGVYbWwsIHByZXR0eUluc2lkZSA/IGluZGVudFN0ciA6ICIiLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gY2hpbGRyZW4gd2VyZSBwcmludGVkIC0tIGNsb3NlIHdpdGggPG5vZGUvPiBzeW50YXgKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQgPSBwcmludC5zdWJzdHJpbmcoMCwgcHJpbnQubGVuZ3RoIC0gMSkgKyAiLz4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBYbWxVdGlsLk5PREVLSU5EX0FUVFJJQlVURSA6CiAgICAgICAgICAgICAgICBEZWJ1Zy53YXJuaW5nKCJza2lwcGluZyBhdHRyaWJ1dGUgbm9kZSAnIiArIFhtbFV0aWwucXVhbGlmaWVkTmFtZShub2RlWG1sKSArICInOiB0aGVzZSBzaG91bGQgYmUgaGFuZGxlZCB3aGVuIHByaW50aW5nIGVsZW1lbnRzIiwgbnVsbCk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgWG1sVXRpbC5OT0RFS0lORF9DT01NRU5UIDoKICAgICAgICAgICAgICAgIHByaW50ICs9ICgocHJpbnQubGVuZ3RoID4gMCAmJiBvcHRpb25zLnByZXR0eSkgPyAiXG4iIDogIiIpICsgWG1sVXRpbC5fcHJpbnRYbWxDb21tZW50KG5vZGVYbWwsIGluZGVudFN0cik7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgWG1sVXRpbC5OT0RFS0lORF9QSSA6CiAgICAgICAgICAgICAgICBwcmludCArPSAoKHByaW50Lmxlbmd0aCA+IDAgJiYgb3B0aW9ucy5wcmV0dHkpID8gIlxuIiA6ICIiKSArIFhtbFV0aWwuX3ByaW50WG1sUEkobm9kZVhtbCwgaW5kZW50U3RyKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBYbWxVdGlsLk5PREVLSU5EX1RFWFQgOgogICAgICAgICAgICAgICAgcHJpbnQgKz0gKChwcmludC5sZW5ndGggPiAwICYmIG9wdGlvbnMucHJldHR5KSA/ICJcbiIgOiAiIikgKyBYbWxVdGlsLl9wcmludFhtbFRleHQobm9kZVhtbCwgaW5kZW50U3RyKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIERlYnVnLndhcm5pbmcoInNraXBwaW5nIHVuc3VwcG9ydGVkIG5vZGUga2luZDogIiArIG5vZGVYbWwubm9kZUtpbmQoKSwgbnVsbCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHByaW50OwogICAgfTsKCiAgICAvKioKICAgICAqIFByaW50cyBhbiBYTUwgY29tbWVudC4KICAgICAqIEBwYXJhbSBub2RlWG1sIFRoZSBjb21tZW50IHRvIHByaW50LgogICAgICogQHBhcmFtIGluZGVudFN0ciBUaGUgaW5kZW50YXRpb24gc3RyaW5nIHRvIHByZXBlbmQgdG8gdGhlIHByaW50ZWQgb3V0cHV0LgogICAgICogQHJldHVybiBUaGUgcHJpbnRlZCB2ZXJzaW9uIG9mIHRoZSBYTUwgY29tbWVudC4gSWYgdGhlIG5vZGUgaXMgbnVsbCwgYW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkLgogICAgICovCiAgICBYbWxVdGlsLl9wcmludFhtbENvbW1lbnQgPSBmdW5jdGlvbiAobm9kZVhtbCwgaW5kZW50U3RyKSB7CiAgICAgICAgaWYgKCFub2RlWG1sIHx8IG5vZGVYbWwubm9kZUtpbmQoKSAhPSBYbWxVdGlsLk5PREVLSU5EX0NPTU1FTlQpIHsKICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0KCiAgICAgICAgLy8gdXNlIHRvWE1MU3RyaW5nKCkgdG8gZ2V0IHRoZSBmdWxsIG1hcmstdXAKICAgICAgICB2YXIgcHJpbnQgPSBub2RlWG1sLnRvWE1MU3RyaW5nKCk7CiAgICAgICAgcmV0dXJuIGluZGVudFN0ciArIHByaW50OwogICAgfTsKICAgIC8qKgogICAgICogUHJpbnRzIGFuIFhNTCBwcm9jZXNzaW5nIGluc3RydWN0aW9uLgogICAgICogQHBhcmFtIG5vZGVYbWwgVGhlIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gdG8gcHJpbnQuCiAgICAgKiBAcGFyYW0gaW5kZW50U3RyIFRoZSBpbmRlbnRhdGlvbiBzdHJpbmcgdG8gcHJlcGVuZCB0byB0aGUgcHJpbnRlZCBvdXRwdXQuCiAgICAgKiBAcmV0dXJuIFRoZSBwcmludGVkIHZlcnNpb24gb2YgdGhlIFhNTCBwcm9jZXNzaW5nIGluc3RydWN0aW9uLiBJZiB0aGUgbm9kZSBpcyBudWxsLCBhbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQuCiAgICAgKi8KICAgIFhtbFV0aWwuX3ByaW50WG1sUEkgPSBmdW5jdGlvbiAobm9kZVhtbCwgaW5kZW50U3RyKSB7CiAgICAgICAgaWYgKCFub2RlWG1sIHx8IG5vZGVYbWwubm9kZUtpbmQoKSAhPSBOT0RFS0lORF9QSSkgewogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQoKICAgICAgICAvLyB1c2UgdG9YTUxTdHJpbmcoKSB0byBnZXQgdGhlIGZ1bGwgbWFyay11cAogICAgICAgIHZhciBwcmludCA9IG5vZGVYbWwudG9YTUxTdHJpbmcoKTsKICAgICAgICByZXR1cm4gaW5kZW50U3RyICsgcHJpbnQ7CiAgICB9OwogICAgLyoqCiAgICAgKiBQcmludHMgWE1MIHRleHQuCiAgICAgKiBAcGFyYW0gbm9kZVhtbCBUaGUgdGV4dCB0byBwcmludC4KICAgICAqIEBwYXJhbSBpbmRlbnRTdHIgVGhlIGluZGVudGF0aW9uIHN0cmluZyB0byBwcmVwZW5kIHRvIHRoZSBwcmludGVkIG91dHB1dC4KICAgICAqIEByZXR1cm4gVGhlIHByaW50ZWQgdmVyc2lvbiBvZiB0aGUgWE1MIHRleHQuIElmIHRoZSBub2RlIGlzIG51bGwsIGFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZC4KICAgICAqLwogICAgWG1sVXRpbC5fcHJpbnRYbWxUZXh0ID0gZnVuY3Rpb24gKG5vZGVYbWwsIGluZGVudFN0cikgewogICAgICAgIGlmICghbm9kZVhtbCB8fCAhbm9kZVhtbC50b1N0cmluZygpIHx8IG5vZGVYbWwubm9kZUtpbmQoKSAhPSBYbWxVdGlsLk5PREVLSU5EX1RFWFQpIHsKICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0KCiAgICAgICAgLy8gdXNlIHRvU3RyaW5nKCkgdG8gZ2V0IGp1c3QgdGhlIHRleHQsIGluY2x1ZGluZyBzcGFjZXMsIHRoZW4gcmUtZW5jb2RlIHRoZSB0ZXh0CiAgICAgICAgdmFyIHByaW50ID0gWG1sVXRpbC5lbmNvZGVYbWxDaGFycyhub2RlWG1sLnRvU3RyaW5nKCkpOwogICAgICAgIC8vIGZpeC11cCBjYXNlcyB3aGVyZSB3ZSBoYXZlIENSTEYgc2VxdWVuY2VzIHNpbmNlIG91dHB1dHRpbmcgdGhvc2UgY2F1c2VzIGRvdWJsZS1zcGFjZWQgdGV4dAogICAgICAgIHByaW50ID0gcHJpbnQucmVwbGFjZSgiXHJcbiIsICJcbiIpOwogICAgICAgIHJldHVybiBpbmRlbnRTdHIgKyBwcmludDsKICAgIH07CiAgICAvKioKICAgICAqIEZpbmRzIHRoZSBjaGlsZCBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgb2NjdXJyZW5jZS4KICAgICAqIEBwYXJhbSBwYXJlbnRYbWwgVGhlIHBhcmVudCBYTUwgbm9kZSB3aG9zZSBpbW1lZGlhdGUgY2hpbGRyZW4gKG9ubHkpIHdpbGwgYmUgc2VhcmNoZWQuCiAgICAgKiBAcGFyYW0gZWxlbU5hbWUgQ2xhc3MgbmFtZSBvZiB0aGUgY2hpbGQgZWxlbWVudCBzb3VnaHQuCiAgICAgKiBAcGFyYW0gb2NjdXJyZW5jZSBUaGUgb2NjdXJyZW5jZSBvZiB0aGUgY2hpbGQgZWxlbWVudCBzb3VnaHQuCiAgICAgKiBAcGFyYW0gY3JlYXRlIElmIHRydWUgYW5kIHRoZXJlIGFyZSBsZXNzIGV4aXN0aW5nIG9jY3VycmVuY2VzIG9mIHRoZSBzcGVjaWZpZWQgY2hpbGQgdGhhbiB0aGUgb2NjdXJyZW5jZSBzcGVjaWZpZWQsIHRoZQogICAgICogIG1pc3NpbmcgY2hpbGQgZWxlbWVudHMgd2lsbCBiZSBjcmVhdGVkIGFuZCBhcHBlbmRlZCB0byB0aGUgcGFyZW50IG5vZGUuCiAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZCBlbGVtZW50IHNvdWdodCAobWF5IGJlIGEgbmV3IGNoaWxkIG9mIHRoZSBwYXJlbnQgaWYgPGNvZGU+Y3JlYXRlPC9jb2RlPiB3YXMgdHJ1ZSkuIElmIDxjb2RlPmNyZWF0ZTwvY29kZT4gd2FzIGZhbHNlCiAgICAgKiAgYW5kIHRoZSBvY2N1cnJlbmNlIHdhc24ndCBmb3VuZCwgbnVsbC4KICAgICAqLwogICAgWG1sVXRpbC5nZXRDaGlsZE9jY3VycmVuY2UgPSBmdW5jdGlvbiAocGFyZW50WG1sLCBlbGVtTmFtZSwgb2NjdXJyZW5jZSwgY3JlYXRlKSB7CiAgICAgICAgb2NjdXJyZW5jZSA9IG9jY3VycmVuY2UgIT09IHVuZGVmaW5lZCA/IG9jY3VycmVuY2UgOiAwOwogICAgICAgIGNyZWF0ZSA9IGNyZWF0ZSAhPT0gdW5kZWZpbmVkID8gY3JlYXRlIDogZmFsc2U7CiAgICAgICAgaWYgKG9jY3VycmVuY2UgPCAwKSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgdmFyIGVsZW1YbWwgPSBudWxsOwoKICAgICAgICB2YXIgb2NjdXIgPSAtMTsgLy8gY3VycmVudCBvY2N1cnJlbmNlIG9mIGV4aXN0aW5nIGVsZW1lbnRzIHdpdGggY2xhc3MgbmFtZXMgdGhhdCBtYXRjaCBlbGVtTmFtZQogICAgICAgIHZhciBjaGlsZHJlbiA9IHBhcmVudFhtbC5lbGVtZW50cygpOwogICAgICAgIGZvciAodmFyIGkgPSAwOwogICAgICAgICAgICAgaSA8IGNoaWxkcmVuLmxlbmd0aCgpOwogICAgICAgICAgICAgaSsrKSB7CiAgICAgICAgICAgIHZhciBjaGlsZFhtbCA9IGNoaWxkcmVuW2ldOwogICAgICAgICAgICBpZiAoY2hpbGRYbWwubG9jYWxOYW1lKCkgPT0gZWxlbU5hbWUpIHsKICAgICAgICAgICAgICAgIG9jY3VyKys7CiAgICAgICAgICAgICAgICBpZiAob2NjdXIgPT0gb2NjdXJyZW5jZSkgewogICAgICAgICAgICAgICAgICAgIC8vIGZvdW5kIG5vZGUgc291Z2h0CiAgICAgICAgICAgICAgICAgICAgZWxlbVhtbCA9IGNoaWxkWG1sOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIWVsZW1YbWwgJiYgY3JlYXRlKSB7CiAgICAgICAgICAgIC8vIGFkZCBtaXNzaW5nIG9jY3VycmVuY2VzCiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOwogICAgICAgICAgICAgICAgIGogPCAob2NjdXJyZW5jZSAtIG9jY3VyKTsKICAgICAgICAgICAgICAgICBqKyspIHsKICAgICAgICAgICAgICAgIGVsZW1YbWwgPSBYbWxVdGlsLmFkZENoaWxkRWxlbWVudChwYXJlbnRYbWwsIGVsZW1OYW1lKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZWxlbVhtbDsKICAgIH07CiAgICAvKioKICAgICAqIFJldHVybnMgYSBjaGlsZCBlbGVtZW50IGZyb20gaXRzIHBhcmVudCBvcHRpb25hbGx5IGNyZWF0aW5nIGFuZCBwYXJlbnRpbmcgaXQgaWYgaXQgZG9lc24ndCBleGlzdC4KICAgICAqIEBwYXJhbSBsb2NhbG5hbWVPckluZGV4IENhbiBlaXRoZXIgYmUgYSBzdHJpbmcgb3IgYSBudW1iZXIuICBXaGVuIGl0J3MgaXMgYSBudW1iZXIgYW4gaW5kZXhlZCBzZWFyY2ggaXMgcGVyZm9ybWVkIG90aGVyd2lzZSB0aGUgZmlyc3QgZWxlbWVudCB3aG9zZSBsb2NhbAogICAgICogIG5hbWUgbWF0Y2hlcyBsb2NhbG5hbWVPckluZGV4IGlzIHJldHVybmVkLgogICAgICogIEBwYXJhbSBwYXJlbnQKICAgICAqIEBwYXJhbSBjcmVhdGUgSWYgdHJ1ZSBhbmQgdGhlIGVsZW1lbnQgaXMgbm90IGZvdW5kIGFuZCBsb2NhbG5hbWVPckluZGV4IGlzIGEgc3RyaW5nLCBhIG5ldyBlbGVtZW50IHdpdGggbG9jYWxuYW1lT3JJbmRleCBhcyB0aGUgbG9jYWwgbmFtZSBpcyBjcmVhdGVkIGFuZAogICAgICogIGFwcGVuZGVkIHRvIHRoZSBwYXJlbnQgb2JqZWN0LgogICAgICovCiAgICBYbWxVdGlsLmdldENoaWxkRWxlbWVudCA9IGZ1bmN0aW9uIChwYXJlbnQsIGxvY2FsbmFtZU9ySW5kZXgsIGNyZWF0ZSkgewogICAgICAgIGNyZWF0ZSA9IGNyZWF0ZSAhPT0gdW5kZWZpbmVkID8gY3JlYXRlIDogZmFsc2U7CiAgICAgICAgdmFyIHhtbFBhcmVudCA9IFhtbFV0aWwuZ2V0WG1sT2JqZWN0KHBhcmVudCk7CgogICAgICAgIGlmICgheG1sUGFyZW50KSB7CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0KCiAgICAgICAgdmFyIG9Ob2RlID0gbnVsbDsKCiAgICAgICAgaWYgKHR5cGVvZiBsb2NhbG5hbWVPckluZGV4ID09ICJudW1iZXIiKSB7CiAgICAgICAgICAgIC8vU2VhcmNoIGJ5IGluZGV4CiAgICAgICAgICAgIHZhciBpbmRleCA9IE51bWJlcihsb2NhbG5hbWVPckluZGV4KTsKICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0geG1sUGFyZW50LmVsZW1lbnRzKCk7CiAgICAgICAgICAgIGlmIChpbmRleCA8IGNoaWxkcmVuLmxlbmd0aCgpICYmIGluZGV4ID49IDApIHsKICAgICAgICAgICAgICAgIG9Ob2RlID0gY2hpbGRyZW5baW5kZXhdOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy9TZWFyY2ggYnkgZWxlbWVudCBuYW1lCiAgICAgICAgICAgIG9Ob2RlID0gWG1sVXRpbC5zZWxlY3RTaW5nbGVOb2RlKHhtbFBhcmVudCwgbG9jYWxuYW1lT3JJbmRleCk7CiAgICAgICAgICAgIGlmICghb05vZGUgJiYgY3JlYXRlKSB7CiAgICAgICAgICAgICAgICBvTm9kZSA9IFhtbFV0aWwuYWRkQ2hpbGRFbGVtZW50KHhtbFBhcmVudCwgbG9jYWxuYW1lT3JJbmRleCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9Ob2RlOwogICAgfTsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBYTUwgZWxlbWVudCB3aXRoIGFuIG9wdGlvbmFsIG5hbWUgYXR0cmlidXRlIGFuZAogICAgICogYXBwZW5kcyBpdCB0byB0aGUgcGFyZW50IGVsZW1lbnQuCiAgICAgKi8KICAgIFhtbFV0aWwuYWRkQ2hpbGRFbGVtZW50ID0gZnVuY3Rpb24gKHBhcmVudCwgZWxlbU5hbWUsIG5hbWUpIHsKICAgICAgICBpZiAoIXBhcmVudCB8fCAhZWxlbU5hbWUpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICB2YXIgb05vZGU7CiAgICAgICAgaWYgKG5hbWUpIHsKICAgICAgICAgICAgb05vZGUgPSBYbWxVdGlsLmNyZWF0ZVRhZyhlbGVtTmFtZSwge25hbWUgOiBuYW1lfSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb05vZGUgPSBYbWxVdGlsLmNyZWF0ZVRhZyhlbGVtTmFtZSwgbnVsbCk7CiAgICAgICAgfQogICAgICAgIHBhcmVudC5hcHBlbmRDaGlsZChvTm9kZSwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIG9Ob2RlOwogICAgfTsKICAgIFhtbFV0aWwuY3JlYXRlVGFnID0gZnVuY3Rpb24gKGVsZW1lbnQsIHBhcmFtYXRlcnMpIHsKICAgICAgICB2YXIgbmFtZSwgeG1sLCB4bWxTdHJpbmcgPSAiPCIgKyBlbGVtZW50OwogICAgICAgIGlmIChwYXJhbWF0ZXJzKSB7CiAgICAgICAgICAgIGZvciAobmFtZSBpbgogICAgICAgICAgICAgICAgcGFyYW1hdGVycykgewogICAgICAgICAgICAgICAgeG1sU3RyaW5nICs9ICIgIiArIG5hbWUgKyAiPVwiIiArIHBhcmFtYXRlcnNbbmFtZV0gKyAiXCIiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHhtbFN0cmluZyArPSAiIC8+IjsKICAgICAgICB4bWwgPSBuZXcgWE1MKHhtbFN0cmluZyk7CiAgICAgICAgcmV0dXJuIHhtbDsKICAgIH07CgogICAgLyoqCiAgICAgKiBQcmludHMgdGhlIHNwZWNpZmllZCBYTUwgbm9kZS4gVGhpcyBmdW5jdGlvbiBkaWZmZXJzIGZyb20gQVMzJ3MgPGNvZGU+WE1MLnRvWE1MU3RyaW5nKCk8L2NvZGU+IGZ1bmN0aW9uIGluIHRoYXQgaXQgaGFzIHNwZWNpYWwgaGFuZGxpbmcgZm9yIGNlcnRhaW4KICAgICAqICBjYXNlcyBsaWtlIHVucXVhbGlmaWVkIG5hbWVzcGFjZSBwcmVmaXhlcyAod2hlcmUgYSBuYW1lc3BhY2UgcHJlZml4IGlzIHVzZWQgd2hlbiB0aGVyZSdzIG5vIGRlZmluaXRpb24gZm9yIHRoYXQgcHJlZml4IGluIHRoZSBYTUwgZG9jdW1lbnQpLiBXaGl0ZXNwYWNlLAogICAgICogIGNvbW1lbnRzIGFuZCBwcm9jZXNzaW5nIGluc3RydWN0aW9ucyBhcmUgYWx3YXlzIHByZXNlcnZlZC4KICAgICAqIEBwYXJhbSByb290WG1sIFRoZSBYTUwgbm9kZSB0byBwcmludC4KICAgICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbmFsIG9iamVjdCBzcGVjaWZ5aW5nIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczoKICAgICAqICA8cD5wcmV0dHk6IEJvb2xlYW4uIFRydWUgaWYgdGhlIHByaW50aW5nIHNob3VsZCBiZSBwcmV0dHk7IGZhbHNlIGlmIGl0IHNob3VsZCBiZSBvbiBhIHNpbmdsZSBsaW5lLiBEZWZhdWx0OiBmYWxzZS48L3A+CiAgICAgKiAgPHA+aW5kZW50OiBpbnQuIFRoZSBkZXB0aCB0byBpbmRlbnQgbmV3IGNoaWxkIGxpbmVzIHdoZW4gcHJldHR5LXByaW50aW5nLiBEZWZhdWx0OiAyLjwvcD4KICAgICAqICA8cD5maWx0ZXI6IEZ1bmN0aW9uLiBEZWZhdWx0OiBudWxsLiBGdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCBwcmlvciB0byBwcm9jZXNzaW5nIGFueSB0eXBlIG9mIG5vZGUgcHJvdmlkaW5nIHRoZSBhYmlsaXR5IHRvIGRpcmVjdCB0aGUgYWxnb3JpdGhtIG9uCiAgICAgKiAgIHNwZWNpZmljIG5vZGVzLiBUaGUgZnVuY3Rpb24ncyBzaWduYXR1cmUgaXMgZXhwZWN0ZWQgdG8gYmUgPGNvZGU+ZnVuY3Rpb24obm9kZTpYTUwsIG9wdGlvbnM6T2JqZWN0KTwvY29kZT4gd2hlcmUgbm9kZSBpcyB0aGUgWE1MIG5vZGUgYWJvdXQKICAgICAqICAgdG8gYmUgcHJvY2Vzc2VkIGFuZCBvcHRpb25zIGlzIGEgZHluYW1pYyBvYmplY3QgdXNlZCB0byBwYXNzIGluIHRoZSBjdXJyZW50IHN0YXRlIGFuZCB0byBwYXNzIG91dCBhbnkgc3RhdGUgbW9kaWZpY2F0aW9ucy4gSWYgdGhlIGZpbHRlciBmdW5jdGlvbgogICAgICogICByZXR1cm5zIHRydWUsIHRoZSBvcHRpb25zIHdpbGwgYmUgY29uc2lkZXJlZCwgb3RoZXJ3aXNlIHRoZXkgd2lsbCBiZSBpZ25vcmVkIGFuZCB0aGUgYWxnb3JpdGhtIHdpbGwgY29udGludWUgaXRzIGRlZmF1bHQgcHJvY2Vzc2luZy4gVGhlIG9wdGlvbnMKICAgICAqICAgb2JqZWN0IGhhcyB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6IDxjb2RlPnByZXR0eUluc2lkZTwvY29kZT4gKEJvb2xlYW4gc2V0IHRvIHRoZSBjdXJyZW50IHN0YXRlIG9mIDxjb2RlPnByZXR0eTwvY29kZT4pLCA8Y29kZT5rZWVwPC9jb2RlPgogICAgICogICAoQm9vbGVhbiB0aGF0IGRlZmF1bHRzIHRvIHRydWUgYW5kIGRldGVybWluZXMgd2hldGhlciB0aGUgbm9kZSBzaG91bGQgYmUgaW5jbHVkZWQgaW4gdGhlIHByaW50LW91dCBvciBub3QpLiBEZWZhdWx0OiBudWxsLjwvcD4KICAgICAqIEByZXR1cm4gVGhlIChwcmV0dHkpIHByaW50ZWQgdmVyc2lvbiBvZiB0aGUgWE1MIG5vZGUuIElmIHJvb3RYbWwgaXMgbnVsbCwgYW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkLgogICAgICovCiAgICBYbWxVdGlsLnByaW50ID0gZnVuY3Rpb24gKHJvb3RYbWwsIG9wdGlvbnMpIHsKICAgICAgICAvLyBUaGVyZSdzIGEgcHJvYmxlbSB3aXRoIHRoZSB3YXkgdGhlIEZsZXggWE1MIGNsYXNzIGhhbmRsZXMgbmFtZXNwYWNlcyB3aGljaCBhcmVuJ3QgcXVhbGlmaWVkLiBUaGUgb3V0cHV0IGlzIHZhbGlkIGJ1dCBEZXNpZ25lciA4LjErIGNyYXNoZXMKICAgICAgICAvLyAgYXMgYSByZXN1bHQgb2YgcGFyc2luZyBpdC4gRGVzaWduZXIgOC4yIHdpbGwgY29udGFpbiBhIGZpeCBmb3IgdGhpcy4KICAgICAgICAvLyBJbiB0aGUgWE1QIE1ldGFkYXRhIHBhY2tldCwgdGhlIGZvbGxvd2luZyBub2RlIGlzIGRlZmluZWQ6CiAgICAgICAgLy8gIDxyZGY6bGkgbGFuZz0ieC1kZWZhdWx0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlIj4KICAgICAgICAvLyBEZWZpbmluZyB0aGlzIHdheSByZXN1bHRzIGluIGludmFsaWQgWE1MIChhdCBsZWFzdCBtb3N0IFhNTCBwYXJzZXJzIGRvbid0IGxpa2UgaXQpLiBJdCdzIGV4cGVjdGluZyBpdCB0byBiZSBkZWZpbmVkIGluIHRoaXMgd2F5OgogICAgICAgIC8vICA8cmRmOmxpIHhtbDpsYW5nPSJ4LWRlZmF1bHQiPgogICAgICAgIC8vIChOb3RpY2UgdGhhdCB0aGUgRmxleCBYTUwgY2xhc3MgaXMgYXV0b21hdGljYWxseSBxdWFsaWZ5aW5nIHRoZSAieG1sIiBuYW1lc3BhY2Ugd2l0aCBzb21lIGRlZmF1bHQgd2hpY2ggdGhlIG90aGVyIHBhcnNlciBkb2Vzbid0IGxpa2UuKQogICAgICAgIC8vIFRoaXMgaXMgb25lIGRpZmZlcmVuY2UgaW4gdGhlIHdheSB0aGlzIHByaW50IGZ1bmN0aW9uIG91dHB1dHMgdGhlIFhNTCBhcyBvcHBvc2VkIHRvIGhvdyBBUzMncyBYTUwudG9YTUxTdHJpbmcoKSBkb2VzIGl0LgoKICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCBudWxsOwoKICAgICAgICAvLyBpbml0aWFsaXplIHRvIGRlZmF1bHQgdmFsdWVzCiAgICAgICAgdmFyIHByaW50T3B0aW9ucyA9IHtwcmV0dHkgOiBmYWxzZSwgaW5kZW50IDogMiwgZmlsdGVyIDogbnVsbCwgbGV2ZWwgOiAwfTsKCiAgICAgICAgaWYgKG9wdGlvbnMpIHsKICAgICAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoInByZXR0eSIpKSB7CiAgICAgICAgICAgICAgICBwcmludE9wdGlvbnMucHJldHR5ID0gb3B0aW9ucy5wcmV0dHk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KCJpbmRlbnQiKSkgewogICAgICAgICAgICAgICAgcHJpbnRPcHRpb25zLmluZGVudCA9IG9wdGlvbnMuaW5kZW50OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAob3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgiZmlsdGVyIikpIHsKICAgICAgICAgICAgICAgIHByaW50T3B0aW9ucy5maWx0ZXIgPSBvcHRpb25zLmZpbHRlcjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdmFyIHByaW50ID0gWG1sVXRpbC5fcHJpbnRYbWxOb2RlKHJvb3RYbWwsIHByaW50T3B0aW9ucyk7CgogICAgICAgIC8vIGFsd2F5cyByZXR1cm4gYSBzdHJpbmcKICAgICAgICByZXR1cm4gcHJpbnQgPyBwcmludCA6ICIiOwogICAgfTsKCiAgICAvKiogUmV0dXJucyBhIHN0cmluZyB3aG9zZSBjb250ZW50IGlzIHRoZSBzdHJpbmcgYyByZXBlYXRlZCBjb3VudCB0aW1lcy4gSWYgYyBpcyBudWxsLCB0aGUgcmV0dXJuZWQgc3RyaW5nIGlzIG51bGwuICovCiAgICBYbWxVdGlsLnJlcGVhdCA9IGZ1bmN0aW9uIChjLCBjb3VudCkgewogICAgICAgIHZhciBzID0gIiI7CiAgICAgICAgaWYgKGMgPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9CiAgICAgICAgZm9yICh2YXIgaSA9IDA7CiAgICAgICAgICAgICBpIDwgY291bnQ7CiAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgcyArPSBjOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgIH07CgogICAgWG1sVXRpbC5nZXRBbGxDaGlsZHJlbiA9IGZ1bmN0aW9uIChwYXJlbnRYTUwpIHsKICAgICAgICBpZiAocGFyZW50WE1MICE9IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIHBhcmVudFhNTC5fQ2hpbGRyZW47CiAgICAgICAgfQogICAgfTsKCiAgICBYbWxVdGlsLlhIVE1MTlNVUkkgPSAiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCI7CiAgICBYbWxVdGlsLk5PREVLSU5EX1RFWFQgPSAidGV4dCI7CiAgICBYbWxVdGlsLk5PREVLSU5EX0VMRU1FTlQgPSAiZWxlbWVudCI7CiAgICBYbWxVdGlsLk5PREVLSU5EX0NPTU1FTlQgPSAiY29tbWVudCI7CiAgICBYbWxVdGlsLk5PREVLSU5EX1BJID0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iOwogICAgWG1sVXRpbC5OT0RFS0lORF9BVFRSSUJVVEUgPSAiYXR0cmlidXRlIjsKICAgIFhtbFV0aWwuUElfUkVHRVhQID0gIjxcXD8oP1A8cGlEb21haW4+XFxTKylcXHMrKD9QPHBpS2V5PlxcUyspKD86XFxzPykoP1A8cGlWYWx1ZT4uKilcXD8+IjsKICAgIFhtbFV0aWwuUElfUkVHRVhQX0ZMQUdTID0gImdzIjsKICAgIFhtbFV0aWwuX1BSRVRUWVBSSU5UX0lOREVOVF9DSEFSID0gIiAiOwp9KShGb3JtLnJ0ZS51dGlsKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE1LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKKGZ1bmN0aW9uIChucykgewogICAgdmFyIFhmYVV0aWwgPSBucy5YZmFVdGlsID0ge307CgogICAgLyoqCiAgICAgKiBQcmludHMgdGhlIHNwZWNpZmllZCBYRkEgbm9kZSBwcm9kaXZpbmcgc3BlY2lhbCBoYW5kbGluZyBmb3Igc3BlY2lmaWMgWEZBIG5vZGVzIHRvIHByZXNlcnZlIHdoaXRlIHNwYWNlIHdoZXJlIGl0J3MgbmVlZGVkIChlLmcuIFhIVE1MKS4KICAgICAqIEBwYXJhbSByb290WGZhIFRoZSBYRkEgWE1MIG5vZGUgdG8gcHJpbnQuCiAgICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25hbCBvYmplY3Qgc3BlY2lmeWluZyB0aGUgZm9sbG93aW5nIG9wdGlvbmFsIHByb3BlcnRpZXM6CiAgICAgKiAgPHA+cHJldHR5OiBCb29sZWFuLiBUcnVlIGlmIHRoZSBwcmludGluZyBzaG91bGQgYmUgcHJldHR5OyBmYWxzZSBpZiBpdCBzaG91bGQgYmUgb24gYSBzaW5nbGUgbGluZS4gRGVmYXVsdDogZmFsc2UuPC9wPgogICAgICogIDxwPmluZGVudDogaW50LiBUaGUgZGVwdGggdG8gaW5kZW50IG5ldyBjaGlsZCBsaW5lcyB3aGVuIHByZXR0eS1wcmludGluZy4gRGVmYXVsdDogMi48L3A+CiAgICAgKiBAcmV0dXJuIFRoZSAocHJldHR5KSBwcmludGVkIHZlcnNpb24gb2YgdGhlIFhGQSBub2RlLiBJZiByb290WG1sIGlzIG51bGwsIGFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZC4KICAgICAqLwogICAgWGZhVXRpbC5wcmludCA9IGZ1bmN0aW9uIChyb290WGZhLCBvcHRpb25zKSB7CiAgICAgICAgdmFyIHByaW50T3B0aW9ucyA9IHtwcmV0dHkgOiBmYWxzZSwgaW5kZW50IDogMiwgZmlsdGVyIDogdGhpcy5fcHJpbnRYZmFGaWx0ZXJ9OwogICAgICAgIGlmIChvcHRpb25zKSB7CiAgICAgICAgICAgIGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KCJwcmV0dHkiKSkgewogICAgICAgICAgICAgICAgcHJpbnRPcHRpb25zLnByZXR0eSA9IG9wdGlvbnMucHJldHR5OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KCJpbmRlbnQiKSkgewogICAgICAgICAgICAgICAgcHJpbnRPcHRpb25zLmluZGVudCA9IG9wdGlvbnMuaW5kZW50OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBucy5YbWxVdGlsLnByaW50KHJvb3RYZmEsIHByaW50T3B0aW9ucyk7CiAgICB9OwoKICAgIFhmYVV0aWwuX3ByaW50WGZhRmlsdGVyID0gZnVuY3Rpb24gKG5vZGVYbWwsIG9wdGlvbnMpIHsKICAgICAgICB2YXIgYXBwbHlPcHRpb25zID0gZmFsc2U7CgogICAgICAgIGlmIChub2RlWG1sICYmIG5vZGVYbWwubm9kZUtpbmQoKSA9PSBucy5YbWxVdGlsLk5PREVLSU5EX0VMRU1FTlQpIHsKICAgICAgICAgICAgaWYgKG5zLlhtbFV0aWwuZmluZFBJT2JqKG5vZGVYbWwsIHtkb21haW4gOiBYZmFVdGlsLlBJX0RPTUFJTiwga2V5IDogInRyYW5zaWVudE5vZGUifSwgbnVsbCkgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgLy8gbm9kZSBpcyB0cmFuc2llbnQgLS0gZG9uJ3Qga2VlcCBpdAogICAgICAgICAgICAgICAgb3B0aW9ucy5rZWVwID0gZmFsc2U7CiAgICAgICAgICAgICAgICBhcHBseU9wdGlvbnMgPSB0cnVlOwogICAgICAgICAgICB9IGVsc2UgaWYgKG5vZGVYbWwubG9jYWxOYW1lKCkgPT0gJ2JvZHknKSB7CiAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdE5zID0gbm9kZVhtbC5uYW1lc3BhY2UoKTsKCiAgICAgICAgICAgICAgICBpZiAoZGVmYXVsdE5zICYmIGRlZmF1bHROcy5wcmVmaXggPT0gIiIgJiYgZGVmYXVsdE5zLnVyaSA9PSBucy5YbWxVdGlsLlhIVE1MTlNVUkkgJiYgbm9kZVhtbC5uYW1lc3BhY2UoJ3hmYScpICE9ICd1bmRlZmluZWQnKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gbmV2ZXIgcHJldHR5LXByaW50IHRoZSBYSFRNTAogICAgICAgICAgICAgICAgICAgIG9wdGlvbnMucHJldHR5SW5zaWRlID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgYXBwbHlPcHRpb25zID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGFwcGx5T3B0aW9uczsKICAgIH07CiAgICAvKioKICAgICAqIFByb3Blcmx5IGhhbmRsZXMgbG9hZGluZyBhbiBYRkEgWE1MIHN0cmluZyBpbnRvIEFTMydzIEU0WCBYTUwgb2JqZWN0LiBYRkEgZG9jdW1lbnRzIGFyZSB1c3VhbGx5IHByZXR0eS1wcmludGVkIHdoaWNoIG1lYW5zIHdoaXRlc3BhY2UgbXVzdCBiZSBpZ25vcmVkIGhvd2V2ZXIKICAgICAqICB0aGV5IG1heSBjb250YWluIHNvbWUgWEhUTUwgaW4gd2hpY2ggc3BhY2VzIG11c3QgYmUgcHJlc2VydmVkLiBBUzMncyBYTUwgb2JqZWN0IHByb3ZpZGVzIGEgd2F5IHRvIGlnbm9yZSB3aGl0ZXNwYWNlIGhvd2V2ZXIgaXQgY2F1c2VzIHRoZSB3aGl0ZXNwYWNlIHdpdGhpbgogICAgICogIHRoZSBYSFRNTCB0byBiZSBpZ25vcmVkIHdoZW4gaXQncyBjcml0aWNhbCB0byBwcmVzZXJ2ZSBpdC4gVGhpcyBmdW5jdGlvbiBoYW5kbGVzIHRoZSB0d28gZGlmZmVyZW50IGtpbmRzIG9mIHdoaXRlc3BhY2UgYXBwcm9wcmlhdGVseSwgbWFraW5nIHN1cmUgdGhhdCB0aGUKICAgICAqICB3aGl0ZXNwYWNlIHdlIGRvbid0IHdhbnQgaXMgZGlzY2FyZGVkIGFuZCB0aGUgd2hpdGVzcGFjZSB3ZSBkbyB3YW50IGlzIHByZXNlcnZlZC4KICAgICAqIEBwYXJhbSBzb3VyY2VTdHIgVGhlIHN0cmluZyBjb250YWluaW5nIHRoZSAoWEZBKSBYTUwgZGVmaW5pdGlvbiAobWF5IGJlIGFuIGVudGlyZSBkb2N1bWVudCAoaS5lLiBhbiBYRFApLCBhIHBpZWNlIG9mIFhGQSwgb3Igc29tZSBhcmJpdHJhcnkgWE1MKS4gTm90ZSB0aGF0CiAgICAgKiAgdGhpcyBldmVuIHdvcmtzIHdpdGggc291cmNlIHN0cmluZ3Mgd2hpY2ggYXJlIG5vdCBYTUwuIElmIGEgbm9uLVhNTCBzb3VyY2Ugc3RyaW5nIGlzIHByb3ZpZGVkLCB0aGUgcmVzdWx0IHdpbGwgYmUgYW4gWE1MIG9iamVjdCB3aXRoIHRoZSBzdHJpbmcgYXMgaXRzIHRleHQKICAgICAqICAoYSB0ZXh0IG5vZGUsIGVzc2VudGlhbGx5LCBhcyBwZXIgdGhlIHRvcC1sZXZlbCBYTUwgb2JqZWN0J3MgY29uc3RydWN0b3Igb3V0cHV0KS4KICAgICAqIEByZXR1cm4gVGhlIFhNTCBvYmplY3QgYmFzZWQgb24gdGhlIHNwZWNpZmllZCBzdHJpbmcgb3IgbnVsbCBpZiBhbiBlcnJvciBvY2N1cnJlZC4KICAgICAqLwogICAgWGZhVXRpbC5sb2FkID0gZnVuY3Rpb24gKHNvdXJjZVN0cikgewogICAgICAgIHZhciB4ZmFTdHIgPSBzb3VyY2VTdHI7IC8vIGluZGlyZWN0aW9uIHNpbXBseSB0byBjaGFuZ2UgdGhlIGV4cG9zZWQgcGFyYW1ldGVyIG5hbWUgd2l0aG91dCB0b3VjaGluZyB0aGUgY29kZSBpbnNpZGUKICAgICAgICBpZiAoIXhmYVN0cikgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vIHNwYWNlIHN1YnN0aXR1dGlvbiBjaGFyYWN0ZXIKICAgICAgICB2YXIgc3BhY2VTdWJDaGFyID0gJ3gnOwoKICAgICAgICAvLwogICAgICAgIC8vIFN0ZXAgMTogUmVwbGFjZSBlYWNoIHNwYWNlIGluIHNwYWNlcnVucyB3aXRoICJ4IiBjaGFyYWN0ZXJzLgogICAgICAgIC8vCiAgICAgICAgdmFyIHNwYWNlcnVuU3R5bGUgPSAieGZhLXNwYWNlcnVuIDogeWVzIjsKICAgICAgICB2YXIgc3BhY2VydW5TdGFydCA9ICc8c3BhbiBzdHlsZT0iJyArIHNwYWNlcnVuU3R5bGUgKyAnIj4nOwogICAgICAgIHZhciBzcGFjZXJ1bkVuZCA9ICc8L3NwYW4+JzsKCiAgICAgICAgLy8gdXNlIGdsb2JhbCBmbGFnIHNvIHdlIGNhbiBpdGVyYXRlIG92ZXIgbWF0Y2hlcyB1c2luZyByZS5sYXN0SW5kZXggYXMgc3RhcnQgZm9yIG5leHQgc2VhcmNoCiAgICAgICAgLy8gaGFuZGxlIGV4dHJhIHdoaXRlc3BhY2UgaW4gYmV0d2VlbiBlbGVtZW50IG5hbWUgYW5kIGF0dHJpYnV0ZSBvbiBvcGVuIGFuZCBjbG9zZSB0YWdzCiAgICAgICAgdmFyIHNwYWNlcnVuUkUgPSBYUmVnRXhwKCcvPFxccyo/c3Bhblxccyo/c3R5bGU9InhmYS1zcGFjZXJ1bjp5ZXMiXFxzKj8+KFxccyspPFwvXFxzKj9zcGFuXFxzKj8+LycsICdnaXMnKTsKICAgICAgICB2YXIgc3BhY2VydW5NYXRjaCA9IHNwYWNlcnVuUkUuZXhlYyh4ZmFTdHIpOwogICAgICAgIHZhciBzcGFjZXJ1bkNvdW50ID0gMDsKCiAgICAgICAgd2hpbGUgKHNwYWNlcnVuTWF0Y2gpIHsKICAgICAgICAgICAgc3BhY2VydW5Db3VudCsrOwogICAgICAgICAgICAvLyByZXBsYWNlIHRoZSBzcGFjZXMgaW4gdGhlIG1hdGNoIHdpdGggdGhlIHNhbWUgbnVtYmVyIG9mICJ4IiBjaGFyYWN0ZXJzCiAgICAgICAgICAgIHhmYVN0ciA9IHhmYVN0ci5zdWJzdHJpbmcoMCwgc3BhY2VydW5NYXRjaC5pbmRleCkgKyBzcGFjZXJ1blN0YXJ0ICsgU3RyaW5nSGVscGVyLnJlcGVhdChzcGFjZVN1YkNoYXIsIHNwYWNlcnVuTWF0Y2hbMV0ubGVuZ3RoKSArIHNwYWNlcnVuRW5kICsgeGZhU3RyLnN1YnN0cihzcGFjZXJ1blJFLmxhc3RJbmRleCk7CiAgICAgICAgICAgIC8vIGxvb2sgZm9yIG1vcmUgbWF0Y2hlcwogICAgICAgICAgICBzcGFjZXJ1bk1hdGNoID0gc3BhY2VydW5SRS5leGVjKHhmYVN0cik7CiAgICAgICAgfQoKICAgICAgICAvLwogICAgICAgIC8vIFN0ZXAgMjogUHJvdGVjdCBzaW5nbGUgc3BhY2VzIGF0IHRoZSBzdGFydCBhbmQgZW5kIG9mIHRleHQgbm9kZXMuIFRoZXNlIGFyZW4ndCBtYXJrZWQgYXMgc3BhY2VydW5zICh3aGljaCBjb250YWluIDIgb3IgbW9yZSBjb25zZWN1dGl2ZSBzcGFjZXMgb3IsIGluIHNvbWUgZXhjZXB0aW9ucywKICAgICAgICAvLyAgICAgICAgIGEgc2luZ2xlIHNwYWNlLCBlLmcuIHRvIGluZGljYXRlIGFuIGVtcHR5IHBhcmFncmFwaCkgYW5kIHRoZXknbGwgYmUgcmVtb3ZlZCB3aGVuIHdlIGxvYWQgaWdub3Jpbmcgd2hpdGVzcGFjZSBpbiB0aGUgbmV4dCBzdGVwLgogICAgICAgIC8vCgogICAgICAgIC8vIHRoaXMgaXNuJ3QgYW4gb2ZmaWNpYWwgc3R5bGUgLS0gSSBqdXN0IG1hZGUgdGhpcyB1cCBob3BpbmcgaXQncyB1bmlxdWUKICAgICAgICB2YXIgc2luZ2xlcnVuU3R5bGUgPSBzcGFjZXJ1blN0eWxlICsgIjtsb2FkZXItc2luZ2xlcnVuOnllcyI7CiAgICAgICAgdmFyIHNpbmdsZXJ1blN0ciA9ICc8c3BhbiBzdHlsZT0iJyArIHNpbmdsZXJ1blN0eWxlICsgJyI+JyArIHNwYWNlU3ViQ2hhciArICc8L3NwYW4+JzsKCiAgICAgICAgdmFyIHNpbmdsZXJ1blJFID0gbmV3IFJlZ0V4cCgpOwogICAgICAgIHZhciBib2R5U3RhcnRSRSA9IFhSZWdFeHAoJzxcXHMqP2JvZHlcXHMuKz8+JywgJ2dpcycpOyAvLyBoYW5kbGUgd2hpdGVzcGFjZSBiZWZvcmUgImJvZHkiIGFuZCByZXF1aXJlIDEgd2hpdGVzcGFjZSBjaGFyIGFmdGVyIGFuZCB0aGVuIHNvbWUgY29udGVudCAobmFtZXNwYWNlcykgYmVmb3JlIGNsb3NpbmcgJz4nCiAgICAgICAgdmFyIGJvZHlFbmRSRSA9IFhSZWdFeHAoJzxcL1xccyo/Ym9keVxccyo/PicsICdnaXMnKTsgLy8gaGFuZGxlIHdoaXRlc3BhY2UgYmVmb3JlIGFuZCBhZnRlciAiYm9keSIKICAgICAgICB2YXIgYm9keVN0YXJ0TWF0Y2ggPSBib2R5U3RhcnRSRS5leGVjKHhmYVN0cik7CiAgICAgICAgdmFyIGJvZHlFbmRNYXRjaCA9IGJvZHlFbmRSRS5leGVjKHhmYVN0cik7CiAgICAgICAgdmFyIHNpbmdsZXJ1bkNvdW50ID0gMDsKCiAgICAgICAgd2hpbGUgKGJvZHlTdGFydE1hdGNoICYmIGJvZHlFbmRNYXRjaCAmJiBib2R5U3RhcnRSRS5sYXN0SW5kZXggPCBib2R5RW5kTWF0Y2guaW5kZXgpIHsKICAgICAgICAgICAgLy8gZm91bmQgYSBib2R5IG5vZGUgd2l0aCBjb250ZW50cwogICAgICAgICAgICAvLyB1cCB0byBhbmQgaW5jbHVkaW5nIDxib2R5IC4uLj4KICAgICAgICAgICAgdmFyIHByZUJvZHlTdHIgPSB4ZmFTdHIuc3Vic3RyaW5nKDAsIGJvZHlTdGFydFJFLmxhc3RJbmRleCk7CiAgICAgICAgICAgIC8vIGNvbnRlbnQgYmV0d2VlbiA8Ym9keSAuLi4+IGFuZCA8L2JvZHk+CiAgICAgICAgICAgIHZhciBjb250ZW50U3RyID0geGZhU3RyLnN1YnN0cmluZyhib2R5U3RhcnRSRS5sYXN0SW5kZXgsIGJvZHlFbmRNYXRjaC5pbmRleCk7CiAgICAgICAgICAgIC8vIDwvYm9keT4gYW5kIHRoZSByZXN0CiAgICAgICAgICAgIHZhciBwb3N0Qm9keVN0ciA9IHhmYVN0ci5zdWJzdHIoYm9keUVuZE1hdGNoLmluZGV4KTsKCiAgICAgICAgICAgIC8vIHNwYWNlIGF0IHN0YXJ0IG9mIHRleHQgbm9kZQogICAgICAgICAgICB2YXIgc3RhcnRSRSA9IG5ldyBSZWdFeHAoJz4gXFMnLCAnZ2knKTsKCiAgICAgICAgICAgIC8vIG1hdGNoIHNpbmdsZSBzcGFjZXMgYXQgc3RhcnQgb2YgdGV4dCBub2RlcwogICAgICAgICAgICB2YXIgc3RhcnRNYXRjaCA9IHN0YXJ0UkUuZXhlYyhjb250ZW50U3RyKTsKICAgICAgICAgICAgdmFyIHNwYWNlQ291bnRlciA9IDA7IC8vIENvdW50IG5vLiBvZiBzcGFjZSByZXBsYWNlZAogICAgICAgICAgICB3aGlsZSAoc3RhcnRNYXRjaCkgewogICAgICAgICAgICAgICAgc2luZ2xlcnVuQ291bnQrKzsKICAgICAgICAgICAgICAgIHNwYWNlQ291bnRlcisrOwogICAgICAgICAgICAgICAgLy8gcGF0dGVybiB3aWxsIG1hdGNoIG9uZSBjaGFyYWN0ZXIgcHJlY2VkaW5nIGFuZCBvbmUgZm9sbG93aW5nIHRoZSBzaW5nbGUgc3BhY2Ugd2hpY2ggbXVzdCBiZSBwcmVzZXJ2ZWQKICAgICAgICAgICAgICAgIGNvbnRlbnRTdHIgPSBjb250ZW50U3RyLnN1YnN0cmluZygwLCBzdGFydE1hdGNoLmluZGV4ICsgMSkgKyBzaW5nbGVydW5TdHIgKyBjb250ZW50U3RyLnN1YnN0cihzdGFydFJFLmxhc3RJbmRleCAtIDEpOwogICAgICAgICAgICAgICAgc3RhcnRNYXRjaCA9IHN0YXJ0UkUuZXhlYyhjb250ZW50U3RyKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gc3BhY2UgYXQgZW5kIG9mIHRleHQgbm9kZQogICAgICAgICAgICB2YXIgZW5kUkUgPSBuZXcgUmVnRXhwKCdcUyA8JywgJ2dpJyk7CgogICAgICAgICAgICAvLyBtYXRjaCBzaW5nbGUgc3BhY2VzIGF0IGVuZCBvZiB0ZXh0IG5vZGVzCiAgICAgICAgICAgIHZhciBlbmRNYXRjaCA9IGVuZFJFLmV4ZWMoY29udGVudFN0cik7CiAgICAgICAgICAgIHdoaWxlIChlbmRNYXRjaCkgewogICAgICAgICAgICAgICAgc2luZ2xlcnVuQ291bnQrKzsKICAgICAgICAgICAgICAgIHNwYWNlQ291bnRlcisrOwogICAgICAgICAgICAgICAgLy8gcGF0dGVybiB3aWxsIG1hdGNoIG9uZSBjaGFyYWN0ZXIgcHJlY2VkaW5nIGFuZCBvbmUgZm9sbG93aW5nIHRoZSBzaW5nbGUgc3BhY2Ugd2hpY2ggbXVzdCBiZSBwcmVzZXJ2ZWQKICAgICAgICAgICAgICAgIGNvbnRlbnRTdHIgPSBjb250ZW50U3RyLnN1YnN0cmluZygwLCBlbmRNYXRjaC5pbmRleCArIDEpICsgc2luZ2xlcnVuU3RyICsgY29udGVudFN0ci5zdWJzdHIoZW5kUkUubGFzdEluZGV4IC0gMSk7CiAgICAgICAgICAgICAgICBlbmRNYXRjaCA9IGVuZFJFLmV4ZWMoY29udGVudFN0cik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gcmVidWlsZCB0aGUgWEZBIHN0cmluZyB3aXRoIHRoZSBuZXcgY29udGVudHMgY29udGFpbmluZyB0aGUgc3Vic3RpdHV0aW9ucwogICAgICAgICAgICB4ZmFTdHIgPSBwcmVCb2R5U3RyICsgY29udGVudFN0ciArIHBvc3RCb2R5U3RyOwogICAgICAgICAgICBib2R5U3RhcnRSRS5sYXN0SW5kZXggKz0gKHNwYWNlQ291bnRlciAqIHNpbmdsZXJ1blN0ci5sZW5ndGgpIC0gc3BhY2VDb3VudGVyOwogICAgICAgICAgICBib2R5RW5kUkUubGFzdEluZGV4ICs9IChzcGFjZUNvdW50ZXIgKiBzaW5nbGVydW5TdHIubGVuZ3RoKSAtIHNwYWNlQ291bnRlcjsKICAgICAgICAgICAgLy8gbG9vayBmb3IgbW9yZSA8Ym9keSAuLi4+Li4uPC9ib2R5PiBtYXRjaGVzCiAgICAgICAgICAgIGJvZHlTdGFydE1hdGNoID0gYm9keVN0YXJ0UkUuZXhlYyh4ZmFTdHIpOwogICAgICAgICAgICBib2R5RW5kTWF0Y2ggPSBib2R5RW5kUkUuZXhlYyh4ZmFTdHIpOwogICAgICAgIH0KICAgICAgICAvLwogICAgICAgIC8vIFN0ZXAgMzogTG9hZCB0aGUgWEZBIGlnbm9yaW5nIHdoaXRlc3BhY2UuCiAgICAgICAgLy8KICAgICAgICAvLyBzYXZlIGN1cnJlbnQgc2V0dGluZ3MKICAgICAgICB2YXIgeG1sU2V0dGluZ3MgPSBYTUwuc2V0dGluZ3MoKTsKICAgICAgICBYTUwuaWdub3JlQ29tbWVudHMgPSBmYWxzZTsKICAgICAgICBYTUwuaWdub3JlUHJvY2Vzc2luZ0luc3RydWN0aW9ucyA9IGZhbHNlOwogICAgICAgIFhNTC5pZ25vcmVXaGl0ZXNwYWNlID0gdHJ1ZTsKICAgICAgICB2YXIgeGZhWG1sID0gbnVsbDsKICAgICAgICB0cnkgewogICAgICAgICAgICAvLyBSZW1vdmluZyB2ZXJzaW9uIGRldGFpbHMgdG8gcmVzb2x2ZSBFcnJvciAoRXJyb3IgOiBYTUwgZGVjbGFyYXRpb24gYWxsb3dlZCBvbmx5IGF0IHRoZSBzdGFydCBvZiB0aGUgZG9jdW1lbnQpCiAgICAgICAgICAgIHhmYVN0ciA9IHhmYVN0ci5yZXBsYWNlKC9ccypcPFw/eG1sLio/XD9cPi9pLCAiIik7CiAgICAgICAgICAgIC8vIFJlcGxhY2UgYWxsIG5vbi1icmVha2FibGUgc3BhY2UgdG8gc3BhY2UgdW5pY29kZSBpbiBjYXNlIG9mIElFMTAgYXMgQWN0aXZlWCBsb2FkWG1sIGlzIGZhaWxpbmcgaW4geGJlNHgKICAgICAgICAgICAgaWYgKG5zLlJURVV0aWxzLmlzSUUoKSkgewogICAgICAgICAgICAgICAgeGZhU3RyID0geGZhU3RyLnJlcGxhY2UoL1wmbmJzcFw7L2csICImIzE2MDsiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB4ZmFYbWwgPSBuZXcgWE1MKHhmYVN0cik7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChlcnIpIHsKICAgICAgICAgICAgYWxlcnQoImV4Y2VwdGlvbiAiICsgZXJyKTsKICAgICAgICAgICAgLy8gZmFpbCBzaWxlbnRseSBzaW5jZSBjYWxsZXIgbWF5IGJlIHRlc3Rpbmcgc3RyaW5nIGFzIGJlaW5nIHZhbGlkIFhNTAogICAgICAgIH0KICAgICAgICAvLyByZXN0b3JlIHByZXZpb3VzIHNldHRpbmdzCiAgICAgICAgWE1MLnNldFNldHRpbmdzKHhtbFNldHRpbmdzKTsKICAgICAgICAvLwogICAgICAgIC8vIFN0ZXAgMzogUmVzdG9yZSB0aGUgc3Vic3RpdHV0ZWQgc3BhY2VzIGluIHRoZSBYTUwuCiAgICAgICAgdmFyIGk7CiAgICAgICAgaWYgKHhmYVhtbCkgewogICAgICAgICAgICB2YXIgcnVuWG1sID0gbnVsbDsKICAgICAgICAgICAgLy8gcmVzdG9yZSBzcGFjZXJ1bnMKICAgICAgICAgICAgaWYgKHNwYWNlcnVuQ291bnQgPiAwKSB7CiAgICAgICAgICAgICAgICB2YXIgc3BhY2VydW5MaXN0ID0gbnMuWG1sVXRpbC5zZWxlY3ROb2Rlcyh4ZmFYbWwsICJzcGFuIiwgdHJ1ZSwgc3BhY2VydW5TdHlsZSwgInN0eWxlIiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICBpZiAoc3BhY2VydW5MaXN0Lmxlbmd0aCgpICE9IHNwYWNlcnVuQ291bnQpIHsKICAgICAgICAgICAgICAgICAgICB3aW5kb3cuY29uc29sZS53YXJuKCJmb3VuZCAiICsgc3BhY2VydW5Db3VudCArICIgc3BhY2VydW4gbWF0Y2hlcyBidXQgZm91bmQgIiArIHNwYWNlcnVuTGlzdC5sZW5ndGgoKSArICIgc3BhY2VydW4gbm9kZXMiLCBudWxsKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOwogICAgICAgICAgICAgICAgICAgICBpIDwgc3BhY2VydW5MaXN0Lmxlbmd0aCgpOwogICAgICAgICAgICAgICAgICAgICBpKyspIHsKICAgICAgICAgICAgICAgICAgICBydW5YbWwgPSBzcGFjZXJ1bkxpc3RbaV07CiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHQgPSBucy5YbWxVdGlsLmdldE5vZGVUZXh0KHJ1blhtbCk7CiAgICAgICAgICAgICAgICAgICAgbnMuWG1sVXRpbC5zZXROb2RlVGV4dChydW5YbWwsIFN0cmluZ0hlbHBlci5yZXBlYXQoIiAiLCB0ZXh0Lmxlbmd0aCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyByZXN0b3JlIG91ciBjdXN0b20gInNpbmdsZXJ1bnMiCiAgICAgICAgICAgIGlmIChzaW5nbGVydW5Db3VudCA+IDApIHsKICAgICAgICAgICAgICAgIHZhciBzaW5nbGVydW5MaXN0ID0gbnMuWG1sVXRpbC5zZWxlY3ROb2Rlcyh4ZmFYbWwsICJzcGFuIiwgdHJ1ZSwgc2luZ2xlcnVuU3R5bGUsICJzdHlsZSIsIHRydWUpOwogICAgICAgICAgICAgICAgaWYgKHNpbmdsZXJ1bkxpc3QubGVuZ3RoKCkgIT0gc2luZ2xlcnVuQ291bnQpIHsKICAgICAgICAgICAgICAgICAgICB3aW5kb3cuY29uc29sZS53YXJuKCJmb3VuZCAiICsgc2luZ2xlcnVuQ291bnQgKyAiIHNpbmdsZXJ1biBtYXRjaGVzIGJ1dCBmb3VuZCBvbmx5ICIgKyBzaW5nbGVydW5MaXN0Lmxlbmd0aCgpICsgIiBzaW5nbGVydW4gbm9kZXMiLCBudWxsKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgaWdub3JlV2hpdGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgIFhNTC5pZ25vcmVXaGl0ZXNwYWNlID0gZmFsc2U7CiAgICAgICAgICAgICAgICAvLyB0ZXh0IG5vZGUgd2l0aCBhIHNpbmdsZSBzcGFjZQogICAgICAgICAgICAgICAgdmFyIHNpbmdsZVhtbCA9IG5ldyBYTUwoIjxzcGFuPiA8L3NwYW4+Iik7CiAgICAgICAgICAgICAgICAvLyBpbnNlcnQgc2luZ2xlIHNwYWNlIHRleHQgbm9kZSBhcyBhIHNpYmxpbmcgb2YgZWFjaCBzaW5nbGVydW4gbm9kZQogICAgICAgICAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgICAgICAgICAgaSA8IHNpbmdsZXJ1bkxpc3QubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgICAgIHJ1blhtbCA9IHNpbmdsZXJ1bkxpc3RbaV07CiAgICAgICAgICAgICAgICAgICAgdmFyIHJ1blBhcmVudFhtbCA9IG5zLlhtbFV0aWwuZ2V0UGFyZW50KHJ1blhtbCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJ1blBhcmVudFhtbCkgewogICAgICAgICAgICAgICAgICAgICAgICBydW5QYXJlbnRYbWwuaW5zZXJ0Q2hpbGRBZnRlcihydW5YbWwsIHNpbmdsZVhtbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBzaW5nbGVydW4gbm9kZQogICAgICAgICAgICAgICAgZm9yIChpID0gMDsKICAgICAgICAgICAgICAgICAgICAgaSA8IHNpbmdsZXJ1bkxpc3QubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICAgICAgICAgIHJ1blhtbCA9IHNpbmdsZXJ1bkxpc3RbaV07CiAgICAgICAgICAgICAgICAgICAgbGV0IGNoaWxkcmVuID0gbnMuWG1sVXRpbC5nZXRBbGxDaGlsZHJlbihydW5QYXJlbnRYbWwpOwogICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSBjaGlsZHJlbi5sZW5ndGggLSAxOyBqID49IDAgOyBqLS0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkcmVuW2pdICE9IG51bGwgJiYgcnVuWG1sID09PSBjaGlsZHJlbltqXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGNoaWxkcmVuW2pdOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gcmVtb3ZlIGFsbCBzaW5nbGVydW5zIGZyb20gdGhlIFhNTAogICAgICAgICAgICAgICAgLy8gbnMuWG1sVXRpbC5yZW1vdmVJdGVtcyhzaW5nbGVydW5MaXN0KTsKICAgICAgICAgICAgICAgICQoc2luZ2xlcnVuTGlzdCkuZW1wdHkoKTsKCiAgICAgICAgICAgICAgICAvLyByZXN0b3JlIG9yaWdpbmFsIHdoaXRlc3BhY2UgZmxhZwogICAgICAgICAgICAgICAgWE1MLmlnbm9yZVdoaXRlc3BhY2UgPSBpZ25vcmVXaGl0ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4geGZhWG1sOwogICAgfTsKICAgIFhmYVV0aWwuZ2V0Tm9kZVRleHQgPSBmdW5jdGlvbiAoeG1sb2JqLCBkZWVwLCBkZWNvZGUpIHsKICAgICAgICBkZWVwID0gZGVlcCAhPT0gdW5kZWZpbmVkID8gZGVlcCA6IHRydWU7CiAgICAgICAgZGVjb2RlID0gZGVjb2RlICE9PSB1bmRlZmluZWQgPyBkZWNvZGUgOiB0cnVlOwoKICAgICAgICB2YXIgbm9kZSA9IHRoaXMuZ2V0WG1sT2JqZWN0KHhtbG9iaik7CgogICAgICAgIGlmICghbm9kZSkgewogICAgICAgICAgICBpZiAodHlwZW9mIHhtbG9iaiA9PSAic3RyaW5nIikgewogICAgICAgICAgICAgICAgcmV0dXJuIGRlY29kZSA/IG5zLlhtbFV0aWwuZGVjb2RlWG1sQ2hhcnMoU3RyaW5nKHhtbG9iaikpIDogU3RyaW5nKHhtbG9iaik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChub2RlLmhhc1NpbXBsZUNvbnRlbnQoKSkgewogICAgICAgICAgICAvLyBhbHdheXMgdXNlIFhNTC50b1N0cmluZygpLCBldmVuIGlmIGl0IGRlY29kZXMgd2hlbiB3ZSBtaWdodCBub3Qgd2FudCBpdCB0bywgYmVjYXVzZSBpdCdsbCBlbnN1cmUgdGhhdCB3ZSBnZXQgZXZlcnl0aGluZywgaW5jbHVkaW5nIHNwYWNlcywKICAgICAgICAgICAgLy8gIGV2ZW4gaWYgdGhlIGNvbnRlbnQgb2YgdGhlIG5vZGUgaXMgb25seSB3aGl0ZXNwYWNlCiAgICAgICAgICAgIHZhciBzaW1wbGVDb250ZW50ID0gbm9kZS50b1N0cmluZygpOwogICAgICAgICAgICBpZiAoIWRlY29kZSkgewogICAgICAgICAgICAgICAgc2ltcGxlQ29udGVudCA9IG5zLlhtbFV0aWwuZW5jb2RlWG1sQ2hhcnMoc2ltcGxlQ29udGVudCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBzaW1wbGVDb250ZW50OwogICAgICAgIH0KCiAgICAgICAgLy9nZXQgYWxsIHRoZSBub2RlJ3MgY2hpbGRyZW4KICAgICAgICB2YXIgY2hpbGROb2RlLCBzVGV4dCA9ICIiOwogICAgICAgIHZhciBsaXN0ID0gbm9kZS5jaGlsZHJlbigpOwoKICAgICAgICBmb3IgKHZhciBpID0gMDsKICAgICAgICAgICAgIGkgPCBsaXN0Lmxlbmd0aDsKICAgICAgICAgICAgIGkrKykgewogICAgICAgICAgICBjaGlsZE5vZGUgPSBsaXN0W2ldOwogICAgICAgICAgICBzd2l0Y2ggKGNoaWxkTm9kZS5ub2RlS2luZCgpKSB7CiAgICAgICAgICAgICAgICBjYXNlIG5zLlhtbFV0aWwuTk9ERUtJTkRfVEVYVDoKICAgICAgICAgICAgICAgICAgICBzVGV4dCArPSAoZGVjb2RlID8gY2hpbGROb2RlLnRvU3RyaW5nKCkgOiBjaGlsZE5vZGUudG9YTUxTdHJpbmcoKSk7IC8vIFhNTC50b1N0cmluZygpIGRlY29kZXMgZW5jb2RlZCBYTUwgY2hhcmFjdGVycwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgbnMuWG1sVXRpbC5OT0RFS0lORF9FTEVNRU5UOgogICAgICAgICAgICAgICAgICAgIGlmIChkZWVwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNUZXh0ICs9IG5zLlhtbFV0aWwuZ2V0Tm9kZVRleHQoY2hpbGROb2RlLCBkZWVwLCBkZWNvZGUpOyAvLyByZWN1cnNpdmUgY2FsbAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc1RleHQ7CiAgICB9OwoKICAgIFhmYVV0aWwuUElfRE9NQUlOID0gInhmYWxpYiI7CiAgICBYZmFVdGlsLk5PREVLSU5EX1RFWFQgPSAidGV4dCI7CiAgICBYZmFVdGlsLk5PREVLSU5EX0VMRU1FTlQgPSAiZWxlbWVudCI7CiAgICBYZmFVdGlsLk5PREVLSU5EX0NPTU1FTlQgPSAiY29tbWVudCI7CiAgICBYZmFVdGlsLk5PREVLSU5EX1BJID0gInByb2Nlc3NpbmctaW5zdHJ1Y3Rpb24iOwogICAgWGZhVXRpbC5OT0RFS0lORF9BVFRSSUJVVEUgPSAiYXR0cmlidXRlIjsKICAgIFhmYVV0aWwuUElfUkVHRVhQID0gIjxcXD8oP1A8cGlEb21haW4+XFxTKylcXHMrKD9QPHBpS2V5PlxcUyspKD86XFxzPykoP1A8cGlWYWx1ZT4uKilcXD8+IjsKICAgIFhmYVV0aWwuUElfUkVHRVhQX0ZMQUdTID0gImdzIjsKICAgIFhmYVV0aWwuX1BSRVRUWVBSSU5UX0lOREVOVF9DSEFSID0gIiAiOwoKfSkoRm9ybS5ydGUudXRpbCk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCihmdW5jdGlvbiAobnMpIHsKICAgIHZhciBYZmFSaWNoVGV4dFV0aWwgPSBucy5YZmFSaWNoVGV4dFV0aWwgPSBmdW5jdGlvbiAoKSB7CgogICAgICAgIHRoaXMuZXJyb3IgPSBudWxsOwogICAgfTsKCiAgICAvKioKICAgICAqIFRlc3RzIHRoZSBzdXBwbGllZCBzdHJpbmcgdG8gZGV0ZXJtaW5lIGlmIGl0IG9ubHkgY29udGFpbnMgcGxhaW4gdGV4dCBhbmQgbm8gWE1MIGVsZW1lbnRzLCBjb21tZW50cywgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMsIGV0Yy4KICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyaW5nIHRvIHRlc3QgZm9yIHBsYWluIHRleHQuCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgPGNvZGU+dmFsdWU8L2NvZGU+IGlzIHBsYWluIHRleHQ7IGZhbHNlIGlmIG5vdC4KICAgICAqLwogICAgWGZhUmljaFRleHRVdGlsLmlzUGxhaW5UZXh0ID0gZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgdmFyIHBsYWluID0gbnMuWG1sVXRpbC5nZXRYbWxPYmplY3QodmFsdWUpOwoKICAgICAgICBpZiAocGxhaW4pIHsKICAgICAgICAgICAgcmV0dXJuIChwbGFpbi5ub2RlS2luZCgpID09IG5zLlhtbFV0aWwuTk9ERUtJTkRfVEVYVCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CgogICAgLyoqCiAgICAgKiBUZXN0cyB0aGUgc3VwcGxpZWQgc3RyaW5nIHRvIGRldGVybWluZSBpZiBpdCBpcyB2YWxpZCBYRkEgcmljaCB0ZXh0LiBBbGwgWEZBIHJpY2ggdGV4dCBtdXN0IGJlIHZhbGlkIFhNTCBhbmQgaGF2ZSBvbmUgb2YgdGhlIGZvbGxvd2luZwogICAgICogIHRvcC1sZXZlbCBjb250YWluZXIgbm9kZXM6CiAgICAgKiA8dWw+CiAgICAgKiA8bGk+ZXhEYXRhIC0tIG9ubHkgaWYgaW5jbHVkZUV4RGF0YSBpcyB0cnVlIChYRkEgbm9kZSwgaW4gWE1MIGZvcm0sIGV4cGVjdGVkIHRvIGNvbnRhaW4gcmljaCB0ZXh0IGNvbnRlbnQpPC9saT4KICAgICAqIDxsaT5odG1sPC9saT4KICAgICAqIDxsaT5ib2R5PC9saT4KICAgICAqIDxsaT5wPC9saT4KICAgICAqIDwvdWw+CiAgICAgKiBAcGFyYW0gdmFsdWUgQ2FuIGJlIGVpdGhlciBhIFN0cmluZyAod2hpY2ggaXMgY29udmVydGVkIHRvIFhNTCkgb3IgWE1MLgogICAgICogQHBhcmFtIGluY2x1ZGVFeERhdGEgSWYgdHJ1ZSwgJmx0O2V4RGF0YSZndDsgWE1MIG5vZGVzIGFyZSBjb25zaWRlcmVkIGFzIHJpY2ggdGV4dC4KICAgICAqIEByZXR1cm4gVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYXNzdW1lZCB0byBiZSAob3IgY29udGFpbiwgaW4gdGhlIGNhc2Ugb2YgJmx0O2V4RGF0YSZndDspIHJpY2ggdGV4dDsgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBYZmFSaWNoVGV4dFV0aWwuaXNYZmFSaWNoVGV4dCA9IGZ1bmN0aW9uICh2YWx1ZSwgaW5jbHVkZUV4RGF0YSkgewogICAgICAgIGluY2x1ZGVFeERhdGEgPSBpbmNsdWRlRXhEYXRhICE9PSB1bmRlZmluZWQgPyBpbmNsdWRlRXhEYXRhIDogdHJ1ZTsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwgfHwgISh0eXBlb2YgdmFsdWUgPT0gInN0cmluZyIgfHwgdmFsdWUgaW5zdGFuY2VvZiBYTUwpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CgogICAgICAgIHZhciB4ZmEgPSAodmFsdWUgaW5zdGFuY2VvZiBYTUwpID8gdmFsdWUgOiBucy5YZmFVdGlsLmxvYWQodmFsdWUpOwoKICAgICAgICBpZiAoeGZhICYmIHhmYS5ub2RlS2luZCgpID09IG5zLlhtbFV0aWwuTk9ERUtJTkRfRUxFTUVOVCkgewogICAgICAgICAgICBpZiAoKHhmYS5sb2NhbE5hbWUoKSA9PSBYZmFFbGVtLkVYREFUQSAmJiBpbmNsdWRlRXhEYXRhKSB8fAogICAgICAgICAgICAgICAgeGZhLmxvY2FsTmFtZSgpID09ICJodG1sIiB8fAogICAgICAgICAgICAgICAgeGZhLmxvY2FsTmFtZSgpID09IFhmYVhodG1sLkJPRFkgfHwgeGZhLmxvY2FsTmFtZSgpID09ICJwIikgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfTsKCiAgICAvKioKICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygc3R5bGUgb2JqZWN0cyBmb3JtIGEgZ2l2ZW4gQ1NTIHN0cmluZy4KICAgICAqIEBwYXJhbSBzdHlsZVN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuCiAgICAgKiBAcmV0dXJuIEFuIGFycmF5IHdoZXJlIGVhY2ggZWxlbWVudCBpcyBhbiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIGR5bmFtaWMgcHJvcGVydGllczoKICAgICAqICA8dWw+CiAgICAgKiAgIDxsaT5zdHlsZU5hbWUgKFN0cmluZyk6IFRoZSBuYW1lIG9mIHRoZSBzdHlsZS48L2xpPgogICAgICogICA8bGk+c3R5bGVWYWx1ZSAoU3RyaW5nKTogVGhlIHZhbHVlIG9mIHRoZSBzdHlsZS48L2xpPgogICAgICogIDwvdWw+CiAgICAgKi8KICAgIFhmYVJpY2hUZXh0VXRpbC5jcmVhdGVTdHlsZUFycmF5ID0gZnVuY3Rpb24gKHN0eWxlU3RyaW5nKSB7CiAgICAgICAgaWYgKCFzdHlsZVN0cmluZykgewogICAgICAgICAgICByZXR1cm4gW107CiAgICAgICAgfQoKICAgICAgICB2YXIgc1N0eWxlQXJyYXkgPSBzdHlsZVN0cmluZy5zcGxpdCgiOyIpOwogICAgICAgIHZhciBzdHlsZU9iakFycmF5ID0gW107CgogICAgICAgIGZvciAodmFyIGogPSAwOwogICAgICAgICAgICAgaiA8IHNTdHlsZUFycmF5Lmxlbmd0aDsKICAgICAgICAgICAgIGorKykgewogICAgICAgICAgICB2YXIgc1N0eWxlID0gc1N0eWxlQXJyYXlbal07CiAgICAgICAgICAgIC8vIFNraXAgZW1wdHkgc3R5bGUKICAgICAgICAgICAgaWYgKCFzU3R5bGUpIHsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbmFtZVZhbHVlID0gc1N0eWxlLnNwbGl0KCI6Iik7CiAgICAgICAgICAgIGlmIChuYW1lVmFsdWUubGVuZ3RoICE9IDIpIHsKICAgICAgICAgICAgICAgIHdpbmRvdy5jb25zb2xlLndhcm4oc1N0eWxlICsgIiBpcyBub3QgZm9ybWF0dGVkIGNvcnJlY3RseTogc2tpcHBlZCIsIG51bGwpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHNTdHlsZU5hbWUgPSBuYW1lVmFsdWVbMF07CiAgICAgICAgICAgIHZhciBzU3R5bGVWYWx1ZSA9IG5hbWVWYWx1ZVsxXTsKCiAgICAgICAgICAgIHZhciBvU3R5bGUgPSB7fTsKICAgICAgICAgICAgb1N0eWxlLnN0eWxlTmFtZSA9IHNTdHlsZU5hbWU7CiAgICAgICAgICAgIG9TdHlsZS5zdHlsZVZhbHVlID0gc1N0eWxlVmFsdWU7CiAgICAgICAgICAgIHN0eWxlT2JqQXJyYXkucHVzaChvU3R5bGUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3R5bGVPYmpBcnJheTsKICAgIH07CgogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3ICZsdDtib2R5IC4uLi8mZ3Q7IGVsZW1lbnQgd2hpY2ggaXMgdGhlIGNvbnRhaW5lciBmb3IgWEZBIFJpY2ggVGV4dC4KICAgICAqIEByZXR1cm4gVGhlIG5ldyAmbHQ7Ym9keSAuLi4vJmd0OyBlbGVtZW50IGFzIGFuIFhNTCBvYmplY3QuCiAgICAgKi8KICAgIFhmYVJpY2hUZXh0VXRpbC5jcmVhdGVCb2R5RWxlbWVudCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAvLyBYSFRNTCBpcyB0aGUgZGVmYXVsdCBuYW1lc3BhY2UgLS0gbWFrZSBzdXJlIHlvdSBzcGVjaWZ5IGFuIGVtcHR5IHN0cmluZyBwcmVmaXggb3RoZXJ3aXNlIGxhdGVyIGNvZGUgdGhhdCBjYWxscyBuYW1lc3BhY2VEZWNsYXJhdGlvbnMoKQogICAgICAgIC8vICBvbiB0aGlzIG5vZGUgd2lsbCBub3Qgc2VlIHRoZSBkZWZhdWx0IG5hbWVzcGFjZSEKICAgICAgICB2YXIgbnNYaHRtbCA9IG5ldyBOYW1lc3BhY2UoIiIsIFhmYVhodG1sLlhIVE1MTlNVUkkpOwogICAgICAgIHZhciBuc1hmYSA9IG5ldyBOYW1lc3BhY2UoWGZhU2NoZW1hLlhGQU5TLCBYZmFEYXRhLlhGQURBVEFOU1VSSSk7CgogICAgICAgIHZhciB4ZmFCb2R5ID0gbnMuWG1sVXRpbC5jcmVhdGVUYWcoWGZhWGh0bWwuQk9EWSk7CiAgICAgICAgeGZhQm9keS5zZXROYW1lc3BhY2UobnNYaHRtbCk7CiAgICAgICAgeGZhQm9keS5hZGROYW1lc3BhY2UobnNYZmEpOwogICAgICAgIHZhciBhdHRyaWJ1dGUgPSBuZXcgQXR0cmlidXRlTmFtZShRTmFtZShuc1hmYSwgInhmYTpBUElWZXJzaW9uIikpOwogICAgICAgIHhmYUJvZHkuUHV0KCJAeGZhOkFQSVZlcnNpb24iLCBYZmFYaHRtbC5BWFRFQVBJVkVSU0lPTik7CgogICAgICAgIHJldHVybiB4ZmFCb2R5OwogICAgfTsKCn0pKEZvcm0ucnRlLnV0aWwpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTYuIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgooZnVuY3Rpb24gKG5zKSB7CiAgICB2YXIgUGxhaW5UZXh0Rm9ybWF0dGVyID0gbnMuUGxhaW5UZXh0Rm9ybWF0dGVyID0gZnVuY3Rpb24gKCkgewoKICAgICAgICB0aGlzLmVycm9yID0gbnVsbDsKICAgIH07CgogICAgUGxhaW5UZXh0Rm9ybWF0dGVyLnByb3RvdHlwZS5mb3JtYXQgPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICBpZiAodGhpcy5lcnJvcikgewogICAgICAgICAgICB0aGlzLmVycm9yID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIGlmICghdmFsdWUgfHwgU3RyaW5nKHZhbHVlKS5sZW5ndGggPT0gMCkgewogICAgICAgICAgICB0aGlzLmVycm9yID0gIkludmFsaWQgdmFsdWUiOwogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzLmZvcm1hdEFzUGxhaW4odmFsdWUpOwogICAgfTsKCiAgICBQbGFpblRleHRGb3JtYXR0ZXIucHJvdG90eXBlLmZvcm1hdEFzUGxhaW4gPSBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICB2YXIgaW5wdXRUZXh0OwoKICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBYTUwpIHsKICAgICAgICAgICAgLy8gYXNzdW1lIHRoaXMgY291bGQgYmUgWEZBIGFuZCBiZSBjYXJlZnVsIHdpdGggd2hpdGVzcGFjZQogICAgICAgICAgICBpbnB1dFRleHQgPSBucy5YZmFVdGlsLnByaW50KHZhbHVlKTsKICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PSAic3RyaW5nIikgewogICAgICAgICAgICAvLyBjb3VsZCBiZSBYRkEgUmljaCBUZXh0IFhNTCBpbiBzdHJpbmcgZm9ybWF0IG9yIGNvdWxkIGJlIHBsYWluIHRleHQKICAgICAgICAgICAgaW5wdXRUZXh0ID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhpcy5lcnJvciA9ICJJbnZhbGlkIHR5cGUiOwogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQoKICAgICAgICBpZiAobnMuWGZhUmljaFRleHRVdGlsLmlzUGxhaW5UZXh0KGlucHV0VGV4dCkpIHsKICAgICAgICAgICAgLy8gdmFsdWUgaXMgYWxyZWFkeSBmb3JtYXR0ZWQgYXMgcGxhaW4gdGV4dAogICAgICAgICAgICByZXR1cm4gaW5wdXRUZXh0OwogICAgICAgIH0KCiAgICAgICAgaWYgKG5zLlhmYVJpY2hUZXh0VXRpbC5pc1hmYVJpY2hUZXh0KGlucHV0VGV4dCkpIHsKICAgICAgICAgICAgdmFyIHhmYU5vZGUgPSBucy5YZmFVdGlsLmxvYWQoaW5wdXRUZXh0KTsKICAgICAgICAgICAgdmFyIHhmYVBsYWluVGV4dCA9IHt9OwogICAgICAgICAgICB0aGlzLmZvcm1hdFhmYVBsYWluVGV4dCh4ZmFOb2RlLCB4ZmFQbGFpblRleHQpOwoKICAgICAgICAgICAgaWYgKHhmYVBsYWluVGV4dC5oYXNPd25Qcm9wZXJ0eSgiZXJyb3IiKSkgewogICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IHhmYVBsYWluVGV4dC5lcnJvcjsKICAgICAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiB4ZmFQbGFpblRleHQudGV4dDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLmVycm9yID0gIkludmFsaWQgdmFsdWUiOwogICAgICAgIHJldHVybiAiIjsKICAgIH07CiAgICAvKioKICAgICAqIFRha2VzIGEgbm9kZSByZXByZXNlbnRpbmcgWEZBIFhIVE1MIG1hcmt1cCBhbmQgY29udmVydHMgaXQgaW50byBwbGFpbiB0ZXh0IHdpdGhvdXQgYW55IGZvcm1hdGluZy4KICAgICAqIEBwYXJhbSB4ZmFOb2RlIFtpbl0gWE1MIG5vZGUgcmVwcmVzZW50aW5nIFhGQSByaWNoIHRleHQgbWFya3VwLgogICAgICogQHBhcmFtIHJlc3VsdCBbb3V0XSBEeW5hbWljIG9iamVjdCB3aGljaCwgdXBvbiByZXR1cm4sIGhhcyBhICJ0ZXh0IiBwcm9wZXJ0eSBjb250YWluaW5nIHRoZSBwbGFpbiB0ZXh0IHN0cmluZyBhbmQsCiAgICAgKiAgaWYgYW4gZXJyb3Igb2NjdXJyZWQsIGFuICJlcnJvciIgcHJvcGVydHkgY29udGFpbmluZyB0aGUgZXJyb3IgbWVzc2FnZS4KICAgICAqLwogICAgUGxhaW5UZXh0Rm9ybWF0dGVyLnByb3RvdHlwZS5mb3JtYXRYZmFQbGFpblRleHQgPSBmdW5jdGlvbiAoeGZhTm9kZSwgcmVzdWx0KSB7CiAgICAgICAgaWYgKCF4ZmFOb2RlKSB7CiAgICAgICAgICAgIHJlc3VsdC5lcnJvciA9ICJJbnZhbGlkIFhGQSByaWNoIHRleHQgbWFya3VwIjsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdmFyIGNoaWxkWG1sLCBjaGlsZExpc3QgPSB4ZmFOb2RlLmNoaWxkcmVuKCk7CgogICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsKICAgICAgICAgICAgIGluZGV4IDwgY2hpbGRMaXN0Lmxlbmd0aCgpOwogICAgICAgICAgICAgaW5kZXgrKykgewogICAgICAgICAgICBjaGlsZFhtbCA9IGNoaWxkTGlzdFtpbmRleF07CiAgICAgICAgICAgIGlmIChjaGlsZFhtbC5ub2RlS2luZCgpID09IG5zLlhtbFV0aWwuTk9ERUtJTkRfRUxFTUVOVCkgewogICAgICAgICAgICAgICAgdmFyIGxvb2tJbnNpZGUgPSB0cnVlOwogICAgICAgICAgICAgICAgdmFyIGNsYXNzTmFtZSA9IGNoaWxkWG1sLmxvY2FsTmFtZSgpOwoKICAgICAgICAgICAgICAgIHN3aXRjaCAoY2xhc3NOYW1lLnRvVXBwZXJDYXNlKCkpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJQIjoKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb252ZXJ0UGFyYVRhZyhyZXN1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSAiQlIiOgogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnZlcnRCcmVha1RhZyhyZXN1bHQpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRoZSBjb252ZXJzaW9ucyBhcmUgT0sKICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuaGFzT3duUHJvcGVydHkoImVycm9yIikpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGxvb2tJbnNpZGUpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm1hdFhmYVBsYWluVGV4dChjaGlsZFhtbCwgcmVzdWx0KTsKICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0Lmhhc093blByb3BlcnR5KCJlcnJvciIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hpbGRYbWwubm9kZUtpbmQoKSA9PSBucy5YbWxVdGlsLk5PREVLSU5EX1RFWFQpIHsKICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuaGFzT3duUHJvcGVydHkoInRleHQiKSkgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdC50ZXh0ICs9IG5zLlhtbFV0aWwuZ2V0Tm9kZVRleHQoY2hpbGRYbWwpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXN1bHQudGV4dCA9IG5zLlhtbFV0aWwuZ2V0Tm9kZVRleHQoY2hpbGRYbWwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIGVsc2UsIGlnbm9yZSBhdHRyaWJ1dGVzLCBQSXMgYW5kIGNvbW1lbnRzCiAgICAgICAgfQogICAgfTsKCiAgICAvKiogQ29udmVydHMgYSAmbHQ7cCZndDsgdGFnIHRvIHBsYWluIHRleHQuIEFwcGVuZHMgdGhlIHJlc3VsdCB0byB0aGUgcmVzdWx0IG9iamVjdCdzICJ0ZXh0IiBwcm9wZXJ0eS4gKi8KICAgIFBsYWluVGV4dEZvcm1hdHRlci5wcm90b3R5cGUuY29udmVydFBhcmFUYWcgPSBmdW5jdGlvbiAocmVzdWx0KSB7CiAgICAgICAgLy8gaWYgaXQncyBub3QgdGhlIHZlcnkgZmlyc3QgcGFyYWdyYXBoLCBhIHBhcmFncmFwaCBlcXVhbHMgdHdvIG5ldyBsaW5lcwogICAgICAgIGlmIChyZXN1bHQuaGFzT3duUHJvcGVydHkoInRleHQiKSkgewogICAgICAgICAgICByZXN1bHQudGV4dCArPSAiXG5cbiI7CiAgICAgICAgfQogICAgfTsKCiAgICAvKiogQ29udmVydHMgYSAmbHQ7YnImZ3Q7IHRhZyB0byBwbGFpbiB0ZXh0LiBBcHBlbmRzIHRoZSByZXN1bHQgdG8gdGhlIHJlc3VsdCBvYmplY3QncyAidGV4dCIgcHJvcGVydHkuICovCiAgICBQbGFpblRleHRGb3JtYXR0ZXIucHJvdG90eXBlLmNvbnZlcnRCcmVha1RhZyA9IGZ1bmN0aW9uIChyZXN1bHQpIHsKICAgICAgICAvLyBhIGxpbmUgYnJlYWsgaXMgYWx3YXlzIGVxdWFsIHRvIGEgc2luZ2xlIG5ldyBsaW5lCiAgICAgICAgdmFyIG5ld0xpbmUgPSAiXG4iOwoKICAgICAgICBpZiAocmVzdWx0Lmhhc093blByb3BlcnR5KCJ0ZXh0IikpIHsKICAgICAgICAgICAgcmVzdWx0LnRleHQgKz0gbmV3TGluZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHQudGV4dCA9IG5ld0xpbmU7CiAgICAgICAgfQogICAgfTsKfSkoRm9ybS5ydGUudXRpbCk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCihmdW5jdGlvbiAobnMpIHsKICAgIHZhciBIdG1sVXRpbHMgPSBucy5IdG1sVXRpbHMgPSBmdW5jdGlvbiAoKSB7CiAgICB9OwoKICAgIEh0bWxVdGlscy5jYWxjdWxhdGVIdG1sUG9zaXRpb24gPSBmdW5jdGlvbiAoaHRtbHN0ciwgcG9zKSB7CiAgICAgICAgLy8gd2UgcmV0dXJuIC0xIChub3QgZm91bmQpIGlmIHRoZSBwb3NpdGlvbiBpcyBiYWQKICAgICAgICBpZiAocG9zIDw9IC0xKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgICAgIC8vIGNoYXJhY3RlcnMgdGhhdCBhcHBlYXJzIHdoZW4gYSB0YWcgc3RhcnRzCiAgICAgICAgdmFyIG9wZW5UYWdzID0gWyI8IiwgIiYiXTsKICAgICAgICAvLyBjaGFyYWN0ZXJzIHRoYXQgYXBwZWFycyB3aGVuIGEgdGFnIGVuZHMKICAgICAgICB2YXIgY2xvc2VUYWdzID0gWyI+IiwgIjsiXTsKICAgICAgICAvLyB0aGUgdGFnIHNob3VsZCBiZSByZXBsYWNlZCB3aXRoCiAgICAgICAgLy8gZXg6ICZhbXA7IGlzICYgYW5kIGhhcyAxIGFzIGxlbmd0aCBidXQgbm9ybWFsCiAgICAgICAgLy8gdGFncyBoYXZlIDAgbGVuZ3RoCiAgICAgICAgdmFyIHRhZ1JlcGxhY2VMZW5ndGggPSBbMCwgMV07CiAgICAgICAgLy8gZmxhZyB0byBrbm93IHdoZW4gd2UgYXJlIGluc2lkZSBhIHRhZwogICAgICAgIHZhciBpc0luc2lkZVRhZyA9IGZhbHNlOwogICAgICAgIHZhciBjbnQgPSAwOwogICAgICAgIC8vIHRoZSBpZCBvZiB0aGUgdGFnIG9wZW5pbmcgZm91bmQKICAgICAgICB2YXIgdGFnSWQgPSAtMTsKICAgICAgICB2YXIgdGFnQ29udGVudCA9ICIiOwoKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGh0bWxzdHIubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgLy8gaWYgdGhlIGNvdW50ZXIgcGFzc2VzIHRoZSBwb3NpdGlvbiBzcGVjaWZpZWQKICAgICAgICAgICAgLy8gbWVhbnMgdGhhdCB3ZSByZWFjaCB0aGUgdGV4dCBwb3NpdGlvbgogICAgICAgICAgICBpZiAoY250ID49IHBvcykgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gY3VycmVudCBjaGFyCiAgICAgICAgICAgIHZhciBjdXJyZW50Q2hhciA9IGh0bWxzdHIuY2hhckF0KGkpOwogICAgICAgICAgICAvLyBjaGVja2luZyBpZiB0aGUgY3VycmVudCBjaGFyIGlzIGluIHRoZSBvcGVuIHRhZyBhcnJheQogICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG9wZW5UYWdzLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICBpZiAoY3VycmVudENoYXIgPT0gb3BlblRhZ3Nbal0pIHsKICAgICAgICAgICAgICAgICAgICAvLyBzZXQgZmxhZwogICAgICAgICAgICAgICAgICAgIGlzSW5zaWRlVGFnID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAvLyBzdG9yZSB0aGUgdGFnIG9wZW4gaWQKICAgICAgICAgICAgICAgICAgICB0YWdJZCA9IGo7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpc0luc2lkZVRhZykgewogICAgICAgICAgICAgICAgLy8gaW5jcmVtZW50IHRoZSBjb3VudGVyCiAgICAgICAgICAgICAgICBjbnQrKzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIHN0b3JlIHRoZSB0YWcgY29udGVudAogICAgICAgICAgICAgICAgLy8gbmVlZGVkIGFmdGVyd2FyZHMgdG8gZmluZCBuZXcgbGluZXMKICAgICAgICAgICAgICAgIHRhZ0NvbnRlbnQgKz0gY3VycmVudENoYXI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGN1cnJlbnRDaGFyID09IGNsb3NlVGFnc1t0YWdJZF0pIHsKICAgICAgICAgICAgICAgIC8vIHdlIGFkIHRoZSByZXBsYWNlIGxlbmd0aAogICAgICAgICAgICAgICAgaWYgKHRhZ0lkID4gLTEpIHsKICAgICAgICAgICAgICAgICAgICBjbnQgKz0gdGFnUmVwbGFjZUxlbmd0aFt0YWdJZF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBpZiB3ZSBlbmNvdW50ZXIgdGhlIDwvUD4gdGFnIHdlIGluY3JlbWVudCB0aGUgY291bnRlcgogICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBvZiBuZXcgbGluZSBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgIGlmICh0YWdDb250ZW50ID09ICI8L1A+IikgewogICAgICAgICAgICAgICAgICAgIGNudCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gc2V0IGZsYWcKICAgICAgICAgICAgICAgIGlzSW5zaWRlVGFnID0gZmFsc2U7CiAgICAgICAgICAgICAgICAvLyByZXNldCB0YWcgY29udGVudAogICAgICAgICAgICAgICAgdGFnQ29udGVudCA9ICIiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIHJldHVybiB0aGUgcG9zaXRpb24gaW4gaHRtbCB0ZXh0CiAgICAgICAgcmV0dXJuIGk7CiAgICB9OwoKICAgIC8qKgogICAgICogR2l2ZW4gVExGIEh0bWwgVGV4dCwgd2hpY2ggbWVhbnMgdGhlIHN0cmluZyBoYXMgdGhlIGZvcm1hdCA8Y29kZT4mbHQ7aHRtbCZndDsmbHQ7Ym9keSAuLi4mZ3Q7e0hUTUx9Jmx0Oy9ib2R5Jmd0OyZsdDsvaHRtbCZndDs8L2NvZGU+LCByZW1vdmUKICAgICAqICB0aGUgPGNvZGU+Jmx0O2h0bWwmZ3Q7Jmx0O2JvZHkmZ3Q7PC9jb2RlPiByb290IGVsZW1lbnQgYW5kIHJldHVybiB0aGUgY29udGVudC4KICAgICAqIEBwYXJhbSB0bGZIdG1sIFRMRiBleHBvcnRlZCBIdG1sLgogICAgICogQHJldHVybiBUaGUgWEhUTUwgY29udGVudCBvZiB0aGUgVExGIFRleHQuIElmIHRoZSBwcm92aWRlZCBzdHJpbmcgd2Fzbid0IHdyYXBwZWQgaW4gdGhlIGJvZHkgZWxlbWVudCwgdGhlIG9yaWdpbmFsCiAgICAgKiAgc3RyaW5nIGlzIHJldHVybmVkLgogICAgICovCiAgICBIdG1sVXRpbHMuZXh0cmFjdFhodG1sQ29udGVudCA9IGZ1bmN0aW9uICh0bGZIdG1sKSB7CiAgICAgICAgaWYgKCF0bGZIdG1sKSB7CiAgICAgICAgICAgIHJldHVybiB0bGZIdG1sOwogICAgICAgIH0gLy8gbnVsbCBvciBlbXB0eSBzdHJpbmcKCiAgICAgICAgdmFyIFJlZ0V4cHIgPSBYUmVnRXhwKCdePEhUTUw+PEJPRFlbXj5dKj5cXHMqKC4qKVxccyo8XC9CT0RZPjxcL0hUTUw+JywgImdpcyIpOwogICAgICAgIHZhciByZXN1bHQgPSBSZWdFeHByLmV4ZWModGxmSHRtbCk7CiAgICAgICAgaWYgKHJlc3VsdCkgewogICAgICAgICAgICByZXR1cm4gcmVzdWx0WzFdOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHRsZkh0bWw7CiAgICB9OwogICAgSHRtbFV0aWxzLnNlYXJjaEJhY2t3YXJkcyA9IGZ1bmN0aW9uIChzb3VyY2UsIHNlYXJjaFRleHQsIGluZGV4UG9zaXRpb24pIHsKICAgICAgICBmb3IgKHZhciBpID0gaW5kZXhQb3NpdGlvbjsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgdmFyIGluZGV4ID0gc291cmNlLmluZGV4T2Yoc2VhcmNoVGV4dCwgaSk7CiAgICAgICAgICAgIGlmIChpbmRleCA9PSBpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gLTE7CiAgICB9OwoKICAgIEh0bWxVdGlscy5zZWFyY2hGb3J3YXJkID0gZnVuY3Rpb24gKHNvdXJjZSwgc2VhcmNoVGV4dCwgaW5kZXhQb3NpdGlvbikgewogICAgICAgIGZvciAodmFyIGkgPSBpbmRleFBvc2l0aW9uOyBpIDwgc291cmNlLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHZhciBpbmRleCA9IHNvdXJjZS5pbmRleE9mKHNlYXJjaFRleHQsIGkpOwogICAgICAgICAgICBpZiAoaW5kZXggPT0gaSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIC0xOwogICAgfTsKCiAgICAvKioKICAgICAqIENvbnZlcnRzIEhUTUwgdG8gWEZBIFhIVE1MLgogICAgICogQHBhcmFtIHN0ciBIVE1MIHRleHQgdG8gY29udmVydC4KICAgICAqIEByZXR1cm4gWEZBIFhIVE1MIGVxdWl2YWxlbnQgYXMgYSA8Y29kZT5TdHJpbmc8L2NvZGU+LiBOb3RlIHRoYXQgd2hpbGUgdGhlIHN0cmluZyBjb250YWlucyBYTUwsIGl0IHdpbGwgYmUgYSBzZXJpZXMgb2YgZWxlbWVudHMgd2l0aG91dAogICAgICogIGEgcm9vdCBub2RlIHdoaWNoIG1lYW5zIGl0IHNob3VsZCBiZSB3cmFwcGVkIGluIGEgcm9vdCBub2RlIGluIG9yZGVyIHRvIGxvYWQgaXQgYXMgdmFsaWQgWE1MLgogICAgICovCgogICAgSHRtbFV0aWxzLnJpY2hUZXh0RWRpdG9yVG9IdG1sID0gZnVuY3Rpb24gKHN0ciwgY29uZmlnKSB7CiAgICAgICAgdmFyIHhtbFNldHRpbmdzID0gWE1MLnNldHRpbmdzKCk7CiAgICAgICAgWE1MLnByZXR0eVByaW50aW5nID0gZmFsc2U7CiAgICAgICAgWE1MLmlnbm9yZVdoaXRlc3BhY2UgPSBmYWxzZTsKCiAgICAgICAgLy9SZW1vdmUgdGhlICI8aHRtbD48Ym9keT4iIHdyYXBwZXIgdGFncyB0aGF0IG1pZ2h0IGhhdmUgYmVlbiBpbnRyb2R1Y2VkIGR1ZSB0byBUTEYgZXhwb3J0ZWQgaHRtbC4KICAgICAgICBzdHIgPSBIdG1sVXRpbHMuZXh0cmFjdFhodG1sQ29udGVudChzdHIpOwoKICAgICAgICAvLyBDb2RlIHRvIGNvbnZlcnQgPGJyPiA8L2JyPiB0byA8YnIvPiBhcyBvdGhlcndpc2UgaXQgZ2V0cyBjb252ZXJ0ZWQgdG8gPGJyPiA8YnI+IGJ5IGlubmVySFRNTAogICAgICAgIHZhciBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPGJyPjxcL2JyPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8YnIvPiIpOwoKICAgICAgICAvLyBDcmVhdGUgWE1MIGRvY3VtZW50CiAgICAgICAgdmFyIFhNTE9iaiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIkJPRFkiKTsKICAgICAgICBYTUxPYmouaW5uZXJIVE1MID0gc3RyOwogICAgICAgIC8vIHRlbXBvcmFyeQogICAgICAgIHZhciB0MTsKICAgICAgICB2YXIgdDI7CiAgICAgICAgLy8gcmVtb3ZlIHRoZSBUQUJTVE9QUyBBdHRyaWJ1dGUKICAgICAgICAvL3ZhciBlbGVtZW50cyA9ICQoeG1sT2JqKTsKICAgICAgICAkKFhNTE9iaikuZmluZCgnKicpLnJlbW92ZUF0dHIoJ1RBQlNUT1BTJyk7CgogICAgICAgIC8vIHJlbW92ZSB0aGUgVEFSR0VUIEF0dHJpYnV0ZSBFeGNlcHQgZm9yIEFuY2hvciB0YWcKICAgICAgICAvL3ZhciBlbGVtZW50cyA9ICQoeG1sT2JqKTsKICAgICAgICAkKFhNTE9iaikuZmluZCgnKicpLm5vdCgiYSIpLnJlbW92ZUF0dHIoJ1RBUkdFVCcpOwoKICAgICAgICAvLyBGaW5kIHRoZSBURVhURk9STUFUIExFQURJTkcgQXR0cmlidXRlCiAgICAgICAgJChYTUxPYmopLmZpbmQoJypbTEVBRElOR10nKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHQyID0gJCh0aGlzKTsKICAgICAgICAgICAgdmFyIGxlYWRpbmcgPSBwYXJzZUZsb2F0KHQyLmF0dHIoImxlYWRpbmciKSk7CiAgICAgICAgICAgIHZhciB0MzsKICAgICAgICAgICAgdmFyIHQ0OwogICAgICAgICAgICB2YXIgdDU7CiAgICAgICAgICAgICQodDIpLmZpbmQoJ1AnKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHQ0ID0gJCh0aGlzKTsKICAgICAgICAgICAgICAgIHZhciBzaXplID0gcGFyc2VGbG9hdChsZWFkaW5nKTsKICAgICAgICAgICAgICAgICQodDQpLmZpbmQoJ0ZPTlQnKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB0NSA9ICQodGhpcyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHQ1ICE9IG51bGwgJiYgdDUubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZm9udFNpemUgPSBwYXJzZUZsb2F0KHQ1LmF0dHIoIlNJWkUiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZm9udFNpemUgKyBsZWFkaW5nKSA+IHNpemUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSBmb250U2l6ZSArIGxlYWRpbmc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHZhciBzdHlsZTEgPSAkKHQ0KS5hdHRyKCJzdHlsZSIpOwogICAgICAgICAgICAgICAgaWYgKHN0eWxlMSAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICAvL3JlbW92aW5nIHRoZSBvbGQgbGluZS1oZWlnaHQgaWYgZXhpc3RzIHRvIHVwZGF0ZSB3aXRoIG5ldyBsaW5lLWhlaWdodAogICAgICAgICAgICAgICAgICAgIC8vYXMgY3VycmVudGx5IG5ldyBsaW5lLWhlaWdodCBpcyBhcHBlbmRlZCB0byBzdHlsZSBidXQgbm90IGhvbm91cmVkIGJlY2F1c2Ugb2Ygb2xkIGxpbmUtaGVpZ2h0IHN0aWxsIHByZXNlbnQKICAgICAgICAgICAgICAgICAgICB2YXIgcmVnID0gLyhsaW5lLWhlaWdodDouKj9wdDspL2dpOwogICAgICAgICAgICAgICAgICAgIHN0eWxlMSA9IHN0eWxlMS5yZXBsYWNlKHJlZywgIiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJCh0NCkuYXR0cignc3R5bGUnLCAnbGluZS1oZWlnaHQ6JyArIHNpemUgKyAncHQ7JyArICgodHlwZW9mIHN0eWxlMSA9PSAndW5kZWZpbmVkJykgPyAnJyA6IHN0eWxlMSkpOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgJCh0MikucmVtb3ZlQXR0cignTEVBRElORycpOwogICAgICAgIH0pOwoKICAgICAgICAvLyBGaW5kIGFsbCBMRUZUTUFSR0lOIGluIFRFWFRGT1JNQVQKICAgICAgICAkKFhNTE9iaikuZmluZCgnKltMRUZUTUFSR0lOXScpLmVhY2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgdDIgPSAkKHRoaXMpOwogICAgICAgICAgICB2YXIgbGVmdE1hcmdpbiA9IHBhcnNlRmxvYXQodDIuYXR0cignTEVGVE1BUkdJTicpKTsKICAgICAgICAgICAgJCh0MikuZmluZCgnUCcpLmVhY2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHQ0ID0gKHRoaXMpOwogICAgICAgICAgICAgICAgdmFyIHN0eWxlID0gdDQuYXR0cignc3R5bGUnKTsKICAgICAgICAgICAgICAgIHQ0LmF0dHIoJ3N0eWxlJywgJ21hcmdpbi1sZWZ0OiAnICsgbGVmdE1hcmdpbiArICdwdDsnICsgKCh0eXBlb2Ygc3R5bGUgPT0gJ3VuZGVmaW5lZCcpID8gJycgOiBzdHlsZSkpOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgJCh0MikucmVtb3ZlQXR0cignTEVGVE1BUkdJTicpOwogICAgICAgIH0pOwoKICAgICAgICAvLyBGaW5kIGFsbCBJTkRFTlQgaW4gVEVYVEZPUk1BdAogICAgICAgICQoWE1MT2JqKS5maW5kKCcqW0lOREVOVF0nKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHQyID0gJCh0aGlzKTsKICAgICAgICAgICAgdmFyIGluZGVudCA9IHBhcnNlRmxvYXQodDIuYXR0cignSU5ERU5UJykpOwogICAgICAgICAgICAkKHQyKS5maW5kKCdQJykuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgdDQgPSAkKHRoaXMpOwogICAgICAgICAgICAgICAgdmFyIHN0eWxlID0gdDQuYXR0cignc3R5bGUnKTsKICAgICAgICAgICAgICAgIC8vICBhbGVydCgic3R5bGUxIGluZGVudCIrc3R5bGUpOwogICAgICAgICAgICAgICAgdDQuYXR0cignc3R5bGUnLCAndGV4dC1pbmRlbnQ6ICcgKyBpbmRlbnQgKyAncHQ7JyArICgodHlwZW9mIHN0eWxlID09ICd1bmRlZmluZWQnKSA/ICcnIDogc3R5bGUpKTsKICAgICAgICAgICAgICAgIC8vYWxlcnQoJCh0NCkuYXR0cignc3R5bGUnKSk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICAkKHQyKS5yZW1vdmVBdHRyKCdJTkRFTlQnKTsKICAgICAgICB9KTsKCiAgICAgICAgLy8gRmluZCBhbGwgQUxJR04KICAgICAgICAkKFhNTE9iaikuZmluZCgnKltBTElHTl0nKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHQyID0gJCh0aGlzKTsKICAgICAgICAgICAgdmFyIGFsaWduID0gdDIuYXR0cignQUxJR04nKTsKICAgICAgICAgICAgdmFyIHN0eWxlID0gdDIuYXR0cignc3R5bGUnKTsKICAgICAgICAgICAgLy9hbGVydCgic3R5bGUxIGFsaWduIitzdHlsZSk7CiAgICAgICAgICAgIHQyLmF0dHIoJ3N0eWxlJywgJ3RleHQtYWxpZ246ICcgKyBhbGlnbiArICc7JyArICgodHlwZW9mIHN0eWxlID09ICd1bmRlZmluZWQnKSA/ICcnIDogc3R5bGUpKTsKICAgICAgICAgICAgLy9hbGVydCgkKHQyKS5hdHRyKCdzdHlsZScpKTsKICAgICAgICAgICAgJCh0MikucmVtb3ZlQXR0cignQUxJR04nKTsKICAgICAgICB9KTsKCiAgICAgICAgLy8gRmluZCBhbGwgRkFDRQogICAgICAgICQoWE1MT2JqKS5maW5kKCcqW0ZBQ0VdJykuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciB0MiA9ICQodGhpcyk7CiAgICAgICAgICAgIHZhciBmYWNlID0gdDIuYXR0cignRkFDRScpOwogICAgICAgICAgICB2YXIgc3R5bGUgPSB0Mi5hdHRyKCdzdHlsZScpOwogICAgICAgICAgICAvLyAgYWxlcnQoInN0eWxlMSBmYWNlIitzdHlsZSk7CiAgICAgICAgICAgIHQyLmF0dHIoJ3N0eWxlJywgJ2ZvbnQtZmFtaWx5OiAnICsgZmFjZSArICc7JyArICgodHlwZW9mIHN0eWxlID09ICd1bmRlZmluZWQnKSA/ICcnIDogc3R5bGUpKTsKICAgICAgICAgICAgLy8JYWxlcnQoJCh0MikuYXR0cignc3R5bGUnKSk7CiAgICAgICAgICAgICQodDIpLnJlbW92ZUF0dHIoJ0ZBQ0UnKTsKICAgICAgICB9KTsKICAgICAgICAvLyBGaW5kIGFsbCBTSVpFCiAgICAgICAgJChYTUxPYmopLmZpbmQoJypbU0laRV0nKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHQyID0gJCh0aGlzKTsKICAgICAgICAgICAgdmFyIHNpemUgPSBwYXJzZUZsb2F0KHQyLmF0dHIoJ1NJWkUnKSk7CiAgICAgICAgICAgIHZhciBzdHlsZSA9IHQyLmF0dHIoJ3N0eWxlJyk7CiAgICAgICAgICAgIC8vYWxlcnQoInN0eWxlMSBzaXplIitzdHlsZSk7CiAgICAgICAgICAgIHQyLmF0dHIoJ3N0eWxlJywgJ2ZvbnQtc2l6ZTogJyArIHNpemUgKyAncHQ7JyArICgodHlwZW9mIHN0eWxlID09ICd1bmRlZmluZWQnKSA/ICcnIDogc3R5bGUpKTsKICAgICAgICAgICAgLy9hbGVydCgkKHQyKS5hdHRyKCdzdHlsZScpKTsKICAgICAgICAgICAgJCh0MikucmVtb3ZlQXR0cignU0laRScpOwogICAgICAgIH0pOwoKICAgICAgICAvLyBGaW5kIGFsbCBDT0xPUgogICAgICAgICQoWE1MT2JqKS5maW5kKCcqW0NPTE9SXScpLmVhY2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgdDIgPSAkKHRoaXMpOwogICAgICAgICAgICB2YXIgY29sb3IgPSB0Mi5hdHRyKCdDT0xPUicpOwogICAgICAgICAgICB2YXIgc3R5bGUgPSB0Mi5hdHRyKCdzdHlsZScpOwogICAgICAgICAgICAvL2FsZXJ0KCJzdHlsZTEgY29sb3IgIitzdHlsZSk7CiAgICAgICAgICAgIHQyLmF0dHIoJ3N0eWxlJywgJ2NvbG9yOiAnICsgY29sb3IgKyAnOycgKyAoKHR5cGVvZiBzdHlsZSA9PSAndW5kZWZpbmVkJykgPyAnJyA6IHN0eWxlKSk7CiAgICAgICAgICAgIC8vYWxlcnQoJCh0MikuYXR0cignc3R5bGUnKSk7CiAgICAgICAgICAgICQodDIpLnJlbW92ZUF0dHIoJ0NPTE9SJyk7CiAgICAgICAgfSk7CiAgICAgICAgLy8gRmluZCBhbGwgTEVUVEVSU1BBQ0lORwogICAgICAgICQoWE1MT2JqKS5maW5kKCcqW0xFVFRFUlNQQUNJTkddJykuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciB0MiA9ICQodGhpcyk7CiAgICAgICAgICAgIHZhciBsZXR0ZXJTcGFjaW5nID0gdDIuYXR0cignTEVUVEVSU1BBQ0lORycpOwogICAgICAgICAgICB2YXIgc3R5bGUgPSB0Mi5hdHRyKCdzdHlsZScpOwogICAgICAgICAgICAvL2FsZXJ0KCJzdHlsZTEgbGV0dGVyU3BhY2luZyAiK3N0eWxlKTsKICAgICAgICAgICAgdDIuYXR0cignc3R5bGUnLCAnbGV0dGVyLXNwYWNpbmc6ICcgKyBsZXR0ZXJTcGFjaW5nICsgJ3B0OycgKyAoKHR5cGVvZiBzdHlsZSA9PSAndW5kZWZpbmVkJykgPyAnJyA6IHN0eWxlKSk7CiAgICAgICAgICAgIC8vYWxlcnQoJCh0MikuYXR0cignc3R5bGUnKSk7CiAgICAgICAgICAgICQodDIpLnJlbW92ZUF0dHIoJ0xFVFRFUlNQQUNJTkcnKTsKICAgICAgICB9KTsKICAgICAgICAvLyBGaW5kIGFsbCBLRVJOSU5HCiAgICAgICAgJChYTUxPYmopLmZpbmQoJypbS0VSTklOR10nKS5lYWNoKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHQyID0gJCh0aGlzKTsKCiAgICAgICAgICAgICQodDIpLnJlbW92ZUF0dHIoJ0tFUk5JTkcnKTsKICAgICAgICB9KTsKCiAgICAgICAgdmFyIGNsZWFuSHRtbCA9IHRoaXMuY2xlYW5IVE1MKFhNTE9iai5pbm5lckhUTUwsIGNvbmZpZyk7CgogICAgICAgIFhNTC5zZXRTZXR0aW5ncyh4bWxTZXR0aW5ncyk7IC8vIHJlc3RvcmUgb3JpZ2luYWwgc2V0dGluZ3MKICAgICAgICByZXR1cm4gY2xlYW5IdG1sOwogICAgfTsKICAgIEh0bWxVdGlscy53cmFwSW5Cb2R5ID0gZnVuY3Rpb24gKGh0bWwpIHsKICAgICAgICBpZiAoaHRtbC5tYXRjaCgvPGJvZHlbXj5dKj5bXHNcU10qPFwvYm9keT4vZ2kpID09IG51bGwpIHsKICAgICAgICAgICAgaHRtbCA9ICc8Ym9keSB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgeG1sbnM6eGZhPSJodHRwOi8vd3d3LnhmYS5vcmcvc2NoZW1hL3hmYS1kYXRhLzEuMC8iIHhmYTpBUElWZXJzaW9uPSIyLjcuMC4wIj4nICsgaHRtbCArICc8L2JvZHk+JzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGh0bWw7CiAgICB9OwoKICAgIC8qKgogICAgICogR2l2ZW4gYSBzdHJpbmcgd2l0aCB0aGUgZm9ybWF0IDxib2R5IC4uLj57WEhUTUx9PC9ib2R5PiwgcmVtb3ZlIHRoZSA8Ym9keT4gcm9vdCBlbGVtZW50IGFuZCBzdXJyb3VuZGluZyB3aGl0ZXNwYWNlIGFuZCByZXR1cm4gdGhlIGNvbnRlbnQKICAgICAqIEBwYXJhbSBodG1sCiAgICAgKi8KICAgIEh0bWxVdGlscy5leHRyYWN0Qm9keUNvbnRlbnQgPSBmdW5jdGlvbiAoaHRtbCkgewogICAgICAgIGlmICghaHRtbCkgewogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfQogICAgICAgIC8vIGdpdmVuIGEgc3RyaW5nIHdpdGggdGhlIGZvcm1hdCA8Ym9keSAuLi4+e1hIVE1MfTwvYm9keT4sIHJlbW92ZSB0aGUgPGJvZHk+IHJvb3QgZWxlbWVudCBhbmQgc3Vycm91bmRpbmcgd2hpdGVzcGFjZSBhbmQgcmV0dXJuIHRoZSBjb250ZW50CiAgICAgICAgdmFyIHJlID0gWFJlZ0V4cCgiXlxccyo8Ym9keVtePl0qPlxccyooLiopXFxzKjxcL2JvZHk+XFxzKiQiLCAiZ3MiKTsKICAgICAgICB2YXIgcmVzdWx0ID0gcmUuZXhlYyhodG1sKTsgLy8gd2lsbCByZXR1cm4gbnVsbCBpZiB0aGUgYm9keSBub2RlIGlzIDxib2R5IC4uLi8+CgogICAgICAgIHZhciBjb250ZW50ID0gIiI7CiAgICAgICAgaWYgKHJlc3VsdCAhPSBudWxsICYmIHJlc3VsdC5sZW5ndGggPiAxKSB7CiAgICAgICAgICAgIGNvbnRlbnQgPSByZXN1bHRbMV07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gY29udGVudDsKICAgIH07CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIHRoZSBSaWNoIFRleHQgYW5kIGFkZHMgYWxsIGNvbnRlbnQgaW5zaWRlIDxwPjxzcGFuPjwvc3Bhbj48L3A+CiAgICAgKiBAcGFyYW0gc3RyCiAgICAgKiBAcmV0dXJucyByZXR1cm5zIHRoZSBmb3JtYXR0ZWQgc3RyaW5nCiAgICAgKi8KICAgIEh0bWxVdGlscy5jbGVhblJpY2hUZXh0ID0gZnVuY3Rpb24gKHN0ciwgY29uZmlnKSB7CgogICAgICAgIC8vUmVwbGFjZSBEaXYncyB3aXRoIHBhcmEgdGFnCiAgICAgICAgdmFyIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8ZGl2JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgJzxwJyk7CgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8L2Rpdj4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAnPC9wPicpOwoKICAgICAgICAvL01vdmUgYWxsIG91dHNpZGUgY29udGVudCBhZnRlciA8L3A+IGluc2lkZSBwID4gc3BhbgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCdcL3A+KFtePF0rfDxicj48L2JyPikoPHB8W148XSokKScsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICJcL3A+PHA+PHNwYW4+JDE8L3NwYW4+PFwvcD4kMiIpOwoKICAgICAgICAvL01vdmUgYWxsIG91dHNpZGUgY29udGVudCBiZWZvcmUgPHA+IGluc2lkZSBwID4gc3BhbgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCcoXltePF0rfDxicj48L2JyPikoPHB8W148XSokKScsICdpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxwPjxzcGFuPiQxPC9zcGFuPjxcL3A+JDIiKTsKCiAgICAgICAgLy9Nb3ZlIHBhcmEgY29udGVudCB3aXRob3V0IGFueSBzcGFuIHdpdGhpbiBzcGFuCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJyg8cFtePF0qPikoKCg/ISgoPHNwYW4pfCg8XC9wPikpKS4pKik8XC9wPicsJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiQxPHNwYW4+JDI8XC9zcGFuPjxcL3A+Iik7CgogICAgICAgIC8vIGVtcHR5IGxpbmVzIHdpbGwgZ2V0IGxvc3QgaWYgdGhleSBkb24ndCBjb250YWluIGF0IGxlYXN0IG9uZSBzcGFjZQogICAgICAgIC8vIGFuIGVtcHR5IGxpbmUgd2lsbCBtYXkgbG9vayBsaWtlIDxwIC4uLj48c3BhbiAuLi4+PHNwYW4gLi4uPjwvc3BhbiAuLi4+PC9zcGFuIC4uLj48L3A+IHNvIHJlcGxhY2UgaXQgd2l0aCA8cCAuLi4+PHNwYW4gLi4uPjxzcGFuIC4uLj48L3NwYW4gLi4uPjwvc3BhbiAuLi4+PC9wPgogICAgICAgIC8vKGF0IGxlYXN0IG9uZSBzcGFuIHNob3VsZCBoYXZlIHNpbmdsZSBzcGFjZSBhcyBjb250ZW50KQogICAgICAgIC8vICBzbyB0aGF0IHdoZW4gd2UgYWRkICd4ZmEtc3BhY2VydW46eWVzJyB0byBhbGwgc3BhbiBzdHlsZXMgKGxhdGVyKSwgdGhlIHNwYWNlIGlzIHJldGFpbmVkIGFuZCB0aGUgQWRvYmUgVGV4dCBFbmdpbmUgcmVuZGVycyB0aGUgZW1wdHkgbGluZQoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPHAoW14+XSopPiguKj8pPFwvcD4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCBIdG1sVXRpbHMuY29udmVydEVtcHR5UGFyYVRvWGh0bWwpOwoKICAgICAgICAvL1JlbW92ZSBFbXB0eSBQYXJhCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxwKFtePl0qKT48XC9wPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICcnKTsKCiAgICAgICAgLy9BZGQgZGVmYXVsdCBzdHlsZXMgdG8gbGkgYWxyZWFkeSBjb250YWluaW5nIHN0eWxlIGF0dHJpYnV0ZQogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8bGkoW148XSopIHN0eWxlPSIoW148Il0qKSIoW148XSopPicsICdnaScpOwogICAgICAgIHZhciByZXN1bHQgPSBwYXR0ZXJuLmV4ZWMoc3RyKTsKICAgICAgICB3aGlsZSAocmVzdWx0ICYmIHJlc3VsdC5sZW5ndGggPiAzKSB7CiAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHJlc3VsdFswXSwgJzxsaScgKyByZXN1bHRbMV0gKyAnIHN0eWxlPSInICsgSHRtbFV0aWxzLmdldE1pc3NpbmdQYXJhU3R5bGUocmVzdWx0WzJdLCBjb25maWcpICsgJyInICsgcmVzdWx0WzNdICsgJz4nKTsKICAgICAgICAgICAgcmVzdWx0ID0gcGF0dGVybi5leGVjKHN0cik7CiAgICAgICAgfQoKICAgICAgICAvL0FkZCBkZWZhdWx0IHN0eWxlIHRvIGxpCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxsaSgoKD8hc3R5bGU9IilbXj5dKSopPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICc8bGkgc3R5bGU9IicgKyBIdG1sVXRpbHMuZ2V0RGVmYXVsdFBhcmFTdHlsZShjb25maWcpICsgJyI+Jyk7CgogICAgICAgIC8vUmVwbGFjaW5nIGFsbCBwYXJhIGluc2lkZSBsaSB0byB0ZW1wIHRhZyB0byBhdm9pZCBkZWZhdWx0IHN0eWxlIHRvIGJlIGFkZGVkLgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8bGkoW14+XSopPihbXjxdKik8cChbXj5dKik+KCgoPyE8cCkuKSopPC9wPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICc8bGkkMT4kMjx0ZW1wJDM+JDQ8L3RlbXA+Jyk7CgogICAgICAgIC8vQWRkIGRlZmF1bHQgc3R5bGVzIHRvIHBhcmEgYWxyZWFkeSBjb250YWluaW5nIHN0eWxlIGF0dHJpYnV0ZQogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8cChbXjxdKikgc3R5bGU9IihbXjwiXSopIihbXjxdKik+JywgJ2dpJyk7CiAgICAgICAgdmFyIHJlc3VsdCA9IHBhdHRlcm4uZXhlYyhzdHIpOwogICAgICAgIHdoaWxlIChyZXN1bHQgJiYgcmVzdWx0Lmxlbmd0aCA+IDMpIHsKICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocmVzdWx0WzBdLCAnPHAnICsgcmVzdWx0WzFdICsgJyBzdHlsZT0iJyArIEh0bWxVdGlscy5nZXRNaXNzaW5nUGFyYVN0eWxlKHJlc3VsdFsyXSwgY29uZmlnKSArICciJyArIHJlc3VsdFszXSArICc+Jyk7CiAgICAgICAgICAgIHJlc3VsdCA9IHBhdHRlcm4uZXhlYyhzdHIpOwogICAgICAgIH0KCiAgICAgICAgLy9BZGQgZGVmYXVsdCBzdHlsZSB0byBwYXJhCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxwKCgoPyFzdHlsZT0iKVtePl0pKik+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgJzxwIHN0eWxlPSInICsgSHRtbFV0aWxzLmdldERlZmF1bHRQYXJhU3R5bGUoY29uZmlnKSArICciPicpOwoKICAgICAgICAvL0NoYW5naW5nIHRlbXAgdGFnIGJhY2sgdG8gcGFyYQogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8dGVtcChbXj5dKik+KCgoPyE8dGVtcCkuKSopPC90ZW1wPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICc8cCQxPiQyPC9wPicpOwoKICAgICAgICByZXR1cm4gc3RyOwogICAgfTsKCiAgICAvKioKICAgICAqIENsZWFucyBhbiBhbHJlYWR5IHNvbWV3aGF0IGZvcm1hdHRlZCBYSFRNTCBzdHJpbmcgY29udmVydGVkIGZyb20gSFRNTC4KICAgICAqIEBwYXJhbSBzdHIgUGFydGlhbGx5LWNvbnZlcnRlZCBYRkEgWEhUTUwgY29udGVudCBmcm9tIEhUTUwgc291cmNlLiBUaGUgc3RyaW5nIGlzIGV4cGVjdGVkIHRvIGNvbnRhaW4gbXVsdGlwbGUKICAgICAqICBlbGVtZW50cyB3aXRob3V0IGEgcm9vdCBub2RlLgogICAgICogQHJldHVybiBYRkEgWEhUTUwgY29udGVudCwgZnVsbHktY29udmVydGVkLCBjb250YWluaW5nIG11bHRpcGxlIGVsZW1lbnRzIHdpdGhvdXQgYSByb290IG5vZGUuCiAgICAgKi8KICAgIEh0bWxVdGlscy5jbGVhbkhUTUwgPSBmdW5jdGlvbiAoc3RyLCBjb25maWcpIHsKCiAgICAgICAgaWYgKHN0ciA9PSAiIikgewogICAgICAgICAgICByZXR1cm4gc3RyOwogICAgICAgIH0KCiAgICAgICAgLy9UT0RPOiBXaHkgd2UgbmVlZCB0byByZXBsYWNlIHRoZXNlLiBUaGVuIHdlIHNob3VsZCBjb3JyZWN0IHRoZSByZWdleAogICAgICAgIC8qIHJlcGxhY2UgYWxsIGVtcHR5IGxpbmVzIHRoYXQgYXJlIGZvcm1hdHRlZCB3aXRoIGJ1bGxldCBzdHlsZQogICAgICAgICB2YXIgcGF0dGVybjpSZWdFeHAgPSAvKDxURVhURk9STUFULio/Pik/PExJPjxGT05UXHNbXj5dKj9cLz8+KDwoQnxJfFUpPikqPyg8XC8oQnxJfFUpPikqPyg8XC9GT05UPik/PFwvTEk+KDxcL1RFWFRGT1JNQVQ+KT8vaWc7CiAgICAgICAgIHZhciBzdHI6U3RyaW5nID0gc3RyaW5nLnJlcGxhY2UocGF0dGVybiwgIjxwLz4iKTsgKi8KICAgICAgICAvLyBmb3JtYXQgPGluZGVudD4gdGFnCgogICAgICAgIHZhciBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnVEVYVEZPUk1BVCcsICJnaSIpOwoKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiU1BBTiIpOwogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCdDT0xPUj1cIiguKj8pXCInLCAnZ2knKTsKCiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgImNvbG9yOiQxOyIpOwogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCdTSVpFPVwiKC4qPylcIicsICdnaScpOwoKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiZm9udC1zaXplOiQxcHQ7Iik7CiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJ0ZBQ0U9IiguKj8pXCIvJywgJ2dpJyk7CgogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICJmb250LWZhbWlseTokMTsiKTsKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnQUxJR049XCIoLio/KVwiJywgJ2dpJyk7CgogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICJ0ZXh0LWFsaWduOiQxOyIpOwoKICAgICAgICAvLyBmb3JtYXQgPGluZGVudD4gdGFnCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJ0lOREVOVD1cIiguKj8pXCInLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAidGV4dC1pbmRlbnQ6JDE7Iik7CgogICAgICAgIC8vZm9ybWF0IDxmb250PiB0YWcKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPEZPTlQgU1RZTEUnLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPHNwYW4gc3R5bGUiKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxGT05UPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8c3Bhbj4iKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxcL0ZPTlQ+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxcL3NwYW4+Iik7CgogICAgICAgIC8vTEs6IHJlcGxhY2UgZW1wdHkgPEZPTlQvPiB0YWdzCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxGT05UXC8+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiIpOwoKICAgICAgICAvL2Zvcm1hdCA8cD4gdGFnCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxQIFNUWUxFJywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxwIHN0eWxlIik7CgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8XC9QPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8XC9wPiIpOwoKICAgICAgICAvL2Zvcm1hdCA8YT4gdGFnCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxBIEhSRUYnLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPGEgaHJlZiIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPFwvQT4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPFwvYT4iKTsKCiAgICAgICAgLy9mb3JtYXQgPHNwYW4+IHRhZwogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8U1BBTiBTVFlMRScsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8c3BhbiBzdHlsZSIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPFNQQU4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPHNwYW4iKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxcL1NQQU4+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxcL3NwYW4+Iik7CgogICAgICAgIHZhciBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPGJyPig/ITxcL2JyPiknLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPGJyPjxcL2JyPiIpOwoKICAgICAgICAvLyByZW1vdmUgYW55IGJ1bGxldHMgd2UgbWlnaHQgZmluZCBzaW5jZSB3ZSBkb24ndCBzdXBwb3J0IGJ1bGxldGluZyBpbiBhIHRleHQgbW9kdWxlCiAgICAgICAgLy8gcGF0dGVybiA9IC88TEk+L2dpOwogICAgICAgIC8vIHZhciBidWxsZXRGb3JtYXQ6U3RyaW5nID0gIjxwPiI7CiAgICAgICAgLy8gc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgYnVsbGV0Rm9ybWF0KTsKICAgICAgICAvLyBwYXR0ZXJuPSAvPFwvTEk+L2dpOwogICAgICAgIC8vIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8L3A+Iik7CgogICAgICAgIC8vVE9ETzogY291bnQgY29ubmVjdGVkIFx0IG9jY3VycmVuY2VzIGFuZCBhZGQgb25seSBvbmUgc3BhbiB0YWcgd2l0aCB0aGUgcmlnaHQgdGFiLWNvdW50IHByb3BlcnR5CiAgICAgICAgLy9yZXBsYWNlIGFsbCBcdCBlc2NhcGUgY2hhcmFjdGVycyB3aXRoIFx0IGFuZCB4ZmEgdGFiIHNpbmNlIFx0IGlzIG5vdCBob25vdXJlZCB3aGlsZSBwcmV2aWV3aW5nIGxldHRlciBpbiBDQ1IKICAgICAgICAvLyBhbmQgeGZhIHRhYiBpcyBub3QgaG9ub3VyZWQgaW4gSFRNTCB0ZXh0IGVkaXRvci4KICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnXHQoPyEoPHNwYW4gc3R5bGU9InhmYS10YWItY291bnQ6MSI+PFwvc3Bhbj4pKScsICdnJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIlx0PHNwYW4gc3R5bGU9XCJ4ZmEtdGFiLWNvdW50OjFcIj48L3NwYW4+Iik7CgogICAgICAgIC8vZG8gVmFyaWFibGUgcmVwbGFjZW1lbnQKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnKFx7XCQoLio/KVwkXH0pJywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxzcGFuIHhmYTplbWJlZFR5cGU9XCJ1cmlcIiB4ZmE6ZW1iZWRNb2RlPVwicmF3XCIgeGZhOmVtYmVkPVwiJDJcIj4kMTwvc3Bhbj4iKTsKCiAgICAgICAgLy8gZm9ybWF0IDx1bD4gdGFnIC0tIHdlIGRvbid0IHN1cHBvcnQgbGlzdHMsIHNvIHJlbW92ZSB0aGVzZSB0YWdzIHNpbmNlIGVhY2ggbGlzdCBpdGVtIHdlIG1heSBoYXZlIGZvdW5kIHdpbGwgbm93IGJlIGl0cyBvd24gcGFyYWdyYXBoCiAgICAgICAgLy8gcGF0dGVybj0gLzxVTD4vZ2k7CiAgICAgICAgLy8gc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiIpOwogICAgICAgIC8vIHBhdHRlcm49IC88XC9VTD4vZ2k7CiAgICAgICAgLy8gc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiIpOwogICAgICAgIC8vIGZvcm1hdCA8b2w+IHRhZyAtLSB3ZSBkb24ndCBzdXBwb3J0IGxpc3RzLCBzbyByZW1vdmUgdGhlc2UgdGFncyBzaW5jZSBlYWNoIGxpc3QgaXRlbSB3ZSBtYXkgaGF2ZSBmb3VuZCB3aWxsIG5vdyBiZSBpdHMgb3duIHBhcmFncmFwaAogICAgICAgIC8vIHBhdHRlcm49IC88T0w+L2dpOwogICAgICAgIC8vIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICIiKTsKICAgICAgICAvLyBwYXR0ZXJuPSAvPFwvT0w+L2dpOwogICAgICAgIC8vIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICIiKTsKCiAgICAgICAgLy9mb3JtYXQgYWxpZ25tZW50IGluIHN0eWxlcyB0YWcKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgndGV4dC1hbGlnbjogUklHSFQnLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAidGV4dC1hbGlnbjogcmlnaHQiKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJ3RleHQtYWxpZ246IExFRlQnLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAidGV4dC1hbGlnbjogbGVmdCIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgndGV4dC1hbGlnbjogQ0VOVEVSJywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgInRleHQtYWxpZ246IGNlbnRlciIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgndGV4dC1hbGlnbjogSlVTVElGWScsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICJ0ZXh0LWFsaWduOiBqdXN0aWZ5Iik7CgogICAgICAgIC8vdGhpcyBpcyB0byBmaXggYSBidWcKICAgICAgICAvL2ZvciBzb21lIHJlYXNvbiB0aGVyZSBpcyBhIFUvQi9JLyB0YWcgc2hvd2luZyB1cD8KCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxVXC8+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPFU+PFwvVT4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiIik7CgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8VT48YnI+PC9VPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8YnI+PC9icj4iKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxVPjxicj48XC9icj48L1U+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxicj48L2JyPiIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPEJcLz4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiIik7CgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8Qj48XC9CPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICIiKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxCPjxicj48L0I+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIjxicj48L2JyPiIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPEI+PGJyPjxcL2JyPjwvQj4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPGJyPjwvYnI+Iik7CgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8SVwvPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICIiKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxJPjxcL0k+JywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiIpOwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPEk+PGJyPjwvST4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPGJyPjwvYnI+Iik7CgogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc8ST48YnI+PFwvYnI+PC9JPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8YnI+PC9icj4iKTsKCiAgICAgICAgLy9MSzogcCBpbiBzcGFuIHNob3VsZCBub3QgaGFwcGVuLi4uCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxzcGFuPlxzKjxwICcsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8cCAiKTsKCiAgICAgICAgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxcL3A+XHMqPFwvc3Bhbj4nLCAnZ2knKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPC9wPiIpOwoKICAgICAgICAvL0xLIGF2b2lkIGJsYW5rcyBhdCBiZWdpbm5pbmcgb2YgbGluZXMKICAgICAgICAvLyB3ZSBuZWVkIHRvIGFzc2VtYmxlIHNwYW4gdGFncwogICAgICAgIC8vcGF0dGVybiA9IC88c3BhbiBzdHlsZT0iKFteIl0qKSI+W148XSo8c3BhbiBzdHlsZT0iKFteIl0qKSI+KFtePF0qKTxcL3NwYW4+XHMqPFwvc3Bhbj4vZ2k7CiAgICAgICAgLy9TU1QgMDkuMDUuMDggOiBBc3NlbWJsZSBzcGFuIHRhZ3MgaW4gY2FzZSB0aGVyZSBpcyBubyBvdGhlciB0ZXh0IGJldHdlZW4gdGhlIHNwYW4gdGFncwoKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPHNwYW4gc3R5bGU9IihbXiJdKikiPjxzcGFuIHN0eWxlPSIoW14iXSopIj4oW148XSopPFwvc3Bhbj5ccyo8XC9zcGFuPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sIEh0bWxVdGlscy5tZXJnZVhodG1sU3BhblN0eWxlcyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgSHRtbFV0aWxzLm1lcmdlWGh0bWxTcGFuU3R5bGVzKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCBIdG1sVXRpbHMubWVyZ2VYaHRtbFNwYW5TdHlsZXMpOwoKICAgICAgICAvLyBSZXBsYWNlIG11bHRpcGxlIHNwYWNlcyB3aXRoICYjMTYwOwogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCcgICcsICdnJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIiYjMTYwOyYjMTYwOyIpOwoKICAgICAgICAvLyByZXBsYWNpbmcgYWxsICZuYnNwOyB0byAmIzE2MDsKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnJm5ic3A7JywgJ2cnKTsKICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiJiMxNjA7Iik7CgogICAgICAgIHN0ciA9IEh0bWxVdGlscy5jbGVhblJpY2hUZXh0KHN0ciwgY29uZmlnKTsKCiAgICAgICAgLy9uZXh0IGFsbCBzcGFucyB3aXRoIHhmYS1zcGFjZXJ1bjp5ZXM6CiAgICAgICAgLy9wYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPHNwYW4gc3R5bGU9IihbXiJdKikiPicsJ2dpJyk7CiAgICAgICAgLy9zdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPHNwYW4gc3R5bGU9XCIkMTsgeGZhLXNwYWNlcnVuOnllc1wiPiIpOwogICAgICAgIC8vU3BhY2VzIGJldHdlZW4gdGhlIHRhZ3Mgd2lsbCBnZXQgbG9zdCBpZiB0aGV5IGRvbid0IG93biBTcGFucwogICAgICAgIC8vTW92aW5nIHRhYnMvd2hpdGUtc3BhY2VzIG91dHNpZGUgaHRtbCB0YWdzIGluc2lkZSBzcGFuIHRhZwogICAgICAgIHBhdHRlcm4gPSBuZXcgUmVnRXhwKCc+KFsgXHRdKyk8PyEoXC8pJywgJ2dpJyk7CiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocGF0dGVybiwgIj48c3BhbiBzdHlsZT1cInhmYS1zcGFjZXJ1bjp5ZXNcIj4kMTwvc3Bhbj48Iik7CgogICAgICAgIC8vTEs6IEZvcm1hdHRpbmcgb2YgdmFyaWFibGVzIG11c3QgYmUgY2hvc2VuLCBvdGhlcndpc2UgaXQgd2lsbCBiZSBsb3N0IHdoZW4gcmVwbGFjaW5nCiAgICAgICAgLy8gICAgdGhlIHZhcmlhYmxlcyBieSBpdHMgdmFsdWUKICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPHNwYW4geGZhOmVtYmVkVHlwZT0idXJpIiB4ZmE6ZW1iZWRNb2RlPSJyYXciIHhmYTplbWJlZD0iKFteIl0qKSI+XHMqPHNwYW4gc3R5bGU9KFtePl0qKT4oW148XSopPFwvc3Bhbj5ccyo8XC9zcGFuPicsICdnaScpOwogICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8c3BhbiBzdHlsZT0kMj48c3BhbiB4ZmE6ZW1iZWRUeXBlPVwidXJpXCIgeGZhOmVtYmVkTW9kZT1cInJhd1wiIHhmYTplbWJlZD1cIiQxXCI+JDM8L3NwYW4+PC9zcGFuPiIpOwoKICAgICAgICByZXR1cm4gc3RyOwogICAgfTsKCiAgICAvKioKICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBhcyByZXBsYWNlbWVudCBmdW5jdGlvbiB0byBhc3NlbWJsZSBzcGFuIHRhZ3MgaW4gY2FzZSB0aGVyZSBpcyBubyBvdGhlciB0ZXh0IGJldHdlZW4gdGhlIHNwYW4gdGFncwogICAgICogcGF0dGVybiA9IC88c3BhbiBzdHlsZT0iKFteIl0qKSI+W148XSo8c3BhbiBzdHlsZT0iKFteIl0qKSI+KFtePF0qKTxcL3NwYW4+XHMqPFwvc3Bhbj4vZ2k7CiAgICAgKiBwYXJhbSBhcmd1bWVudHMKICAgICAqIEByZXR1cm4KICAgICAqCiAgICAgKi8KICAgIEh0bWxVdGlscy5tZXJnZVhodG1sU3BhblN0eWxlcyA9IGZ1bmN0aW9uICgpIHsKCiAgICAgICAgLy9UaGVyZSBzaG91bGQgYmUgdGhyZWUgZ3JvdXBzIGluIG1hdGNoZWQgc3RyaW5nczogb3V0ZXIgc3BhbiBzdHlsZXMsIGlubmVyIHNwYW4gc3R5bGVzLCBpbm5lciBzcGFuIGNvbnRlbnRzLiBJZiB0aGF0J3Mgbm90IHRoZSBjYXNlLCByZXR1cm4gdGhlIG9yaWdpbmFsIHN0cmluZwoKICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCAhPSA2KSB7CiAgICAgICAgICAgIHJldHVybiBhcmd1bWVudHNbMF07CiAgICAgICAgfQoKICAgICAgICB2YXIgb3V0ZXJTdHlsZXNTdHIgPSBhcmd1bWVudHNbMV07CiAgICAgICAgdmFyIGlubmVyU3R5bGVzID0gYXJndW1lbnRzWzJdOwogICAgICAgIHZhciBzcGFuQ29udGVudCA9IGFyZ3VtZW50c1szXTsKCiAgICAgICAgdmFyIG1hcmdlZFN0eWxlcyA9IChpbm5lclN0eWxlcyAhPSBudWxsKSA/IGlubmVyU3R5bGVzIDogIiI7CiAgICAgICAgdmFyIG91dGVyU3R5bGVzID0gb3V0ZXJTdHlsZXNTdHIuc3BsaXQoIjsiKTsKCiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvdXRlclN0eWxlcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICB2YXIgb3V0ZXJTdHlsZSA9IG91dGVyU3R5bGVzW2ldOwogICAgICAgICAgICBpZiAob3V0ZXJTdHlsZS5pbmRleE9mKCI6IikgPiAwKSB7CiAgICAgICAgICAgICAgICB2YXIgc3R5bGVOYW1lID0gb3V0ZXJTdHlsZS5zdWJzdHJpbmcoMCwgb3V0ZXJTdHlsZS5pbmRleE9mKCI6IikpOwogICAgICAgICAgICAgICAgc3R5bGVOYW1lID0gc3R5bGVOYW1lLnRyaW0oKTsKICAgICAgICAgICAgICAgIGlmIChtYXJnZWRTdHlsZXMudG9Mb3dlckNhc2UoKS5pbmRleE9mKHN0eWxlTmFtZS50b0xvd2VyQ2FzZSgpKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICBtYXJnZWRTdHlsZXMgPSBtYXJnZWRTdHlsZXMgKyAiOyAiICsgb3V0ZXJTdHlsZS50cmltKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuICI8c3BhbiBzdHlsZT1cIiIgKyBtYXJnZWRTdHlsZXMgKyAiXCI+IiArIHNwYW5Db250ZW50ICsgIjwvc3Bhbj4iOwogICAgfTsKCiAgICAvKioKICAgICAqIEhhbmRsZXMgdGhlIHBhcmFncmFwaCB0aGF0IGRvZXMgbm90IGhhdmUgYW55IGNvbnRlbnQgdG8gaW5zZXJ0IGEgZW1wdHkgc3BhY2Ugc28gdGhhdCBjYW4gYmUgdXNlZCB3aXRoIHNwYWNlIHJ1bgogICAgICogdG8gc2hvdyBuZXcgbGluZXMgaW4geGZhIGZvciBlbXB0eSBwYXJhLgogICAgICogTm90ZTogdGhpcyBkb2VzIG5vdCBleHBsaWNpdGx5IGFkZHMgeGZhLXNwYWNlcnVuIHRvIHNwYW4gdGFncwogICAgICogcGFyYW0gYXJndW1lbnRzCiAgICAgKiBAcmV0dXJuCiAgICAgKi8KCiAgICBIdG1sVXRpbHMuY29udmVydEVtcHR5UGFyYVRvWGh0bWwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHN0ciA9IFN0cmluZyhhcmd1bWVudHNbMF0pOwogICAgICAgIHZhciBwbGFpblRleHRGb3JtYXR0ZXIgPSBuZXcgbnMuUGxhaW5UZXh0Rm9ybWF0dGVyKCk7CiAgICAgICAgdmFyIHBsYWluVGV4dCA9IHBsYWluVGV4dEZvcm1hdHRlci5mb3JtYXQoc3RyKTsKICAgICAgICAvL2lmKCEocGxhaW5UZXh0KSAmJiAhKGVycm9yKSl7CiAgICAgICAgaWYgKCEocGxhaW5UZXh0KSkgewogICAgICAgICAgICB2YXIgc3RyMSA9IHN0cjsKICAgICAgICAgICAgLy9IYW5kbGUgYm90aCBleHBhbmRlZCBhbmQgbm9uIGV4cGFuZGVkIHNwYW4uCgogICAgICAgICAgICB2YXIgcGF0dGVybiA9IG5ldyBSZWdFeHAoJzxzcGFuKFtePl0qKVwvPicsICdpJyk7CiAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8c3BhbiQxPiA8L3NwYW4+Iik7CgogICAgICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPHNwYW4oW14+XSopXD48XC9zcGFuPicsICdpJyk7CiAgICAgICAgICAgIHN0ciA9IHN0ci5yZXBsYWNlKHBhdHRlcm4sICI8c3BhbiQxPiA8L3NwYW4+Iik7CgogICAgICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPHNwYW4oW14+XSopPltccyBdKjwvc3Bhbj4nLCAnaScpOwogICAgICAgICAgICBzdHIgPSBzdHIucmVwbGFjZShwYXR0ZXJuLCAiPHNwYW4kMT48YnI+PC9icj48L3NwYW4+Iik7CgogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHN0cjsKICAgIH07CgogICAgSHRtbFV0aWxzLmdldERlZmF1bHRQYXJhU3R5bGUgPSBmdW5jdGlvbiAoY29uZmlnKSB7CiAgICAgICAgdmFyIHN0eWxlID0gIiI7CiAgICAgICAgaWYgKGNvbmZpZykgewogICAgICAgICAgICBzdHlsZSArPSAnZm9udC1mYW1pbHk6JyArIGNvbmZpZy5mb250RmFtaWx5LmRlZmF1bHRWYWx1ZSArICc7JzsKICAgICAgICAgICAgc3R5bGUgKz0gJ2ZvbnQtc2l6ZTonICsgY29uZmlnLmZvbnRTaXplLmRlZmF1bHRWYWx1ZSArICdwdDsnOwogICAgICAgICAgICBzdHlsZSArPSAnbGV0dGVyLXNwYWNpbmc6JyArIGNvbmZpZy5sZXR0ZXJTcGFjaW5nLmRlZmF1bHRWYWx1ZSArICdwdDsnOwogICAgICAgICAgICBzdHlsZSArPSAnY29sb3I6IzAwMDAwMDsnOwogICAgICAgICAgICBzdHlsZSArPSAndGV4dC1hbGlnbjpsZWZ0Oyc7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gc3R5bGU7CiAgICB9OwoKICAgIEh0bWxVdGlscy5nZXRNaXNzaW5nUGFyYVN0eWxlID0gZnVuY3Rpb24gKHN0eWxlLCBjb25maWcpIHsKICAgICAgICBpZiAoc3R5bGUgJiYgc3R5bGUubGVuZ3RoID4gMCkgewogICAgICAgICAgICBpZiAoY29uZmlnKSB7CiAgICAgICAgICAgICAgICBpZiAoIW5zLlN0cmluZ0hlbHBlci5lbmRzV2l0aChzdHlsZSwgIjsiKSkgewogICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICI7IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChzdHlsZS5pbmRleE9mKCJmb250LWZhbWlseSIpIDwgMCkgewogICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdmb250LWZhbWlseTonICsgY29uZmlnLmZvbnRGYW1pbHkuZGVmYXVsdFZhbHVlICsgJzsnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHN0eWxlLmluZGV4T2YoImZvbnQtc2l6ZSIpIDwgMCkgewogICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdmb250LXNpemU6JyArIGNvbmZpZy5mb250U2l6ZS5kZWZhdWx0VmFsdWUgKyAncHQ7JzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChzdHlsZS5pbmRleE9mKCJsZXR0ZXItc3BhY2luZyIpIDwgMCkgewogICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdsZXR0ZXItc3BhY2luZzonICsgY29uZmlnLmxldHRlclNwYWNpbmcuZGVmYXVsdFZhbHVlICsgJ3B0Oyc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoc3R5bGUuaW5kZXhPZigiY29sb3IiKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICBzdHlsZSArPSAnY29sb3I6IzAwMDAwMDsnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHN0eWxlLmluZGV4T2YoInRleHQtYWxpZ24iKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICBzdHlsZSArPSAndGV4dC1hbGlnbjpsZWZ0Oyc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdHlsZSA9IEh0bWxVdGlscy5nZXREZWZhdWx0UGFyYVN0eWxlKGNvbmZpZyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHlsZTsKICAgIH07Cgp9KShGb3JtLnJ0ZS51dGlsKTsKCihmdW5jdGlvbiAoKSB7Ci8vIFNvdXJjZTogL2FwcHMvam5rbi93b3Jrc3BhY2UvZ3JlZW5TaG9vdHMtUlRFLVJlcG9fcmVsZWFzZV82NjAvbWFpbi90YXJnZXQvY2hlY2tvdXQvY29udGVudC9zcmMvbWFpbi90ZW1wbGF0ZXMvYnV0dG9uLmhhbmRsZWJhcnMKCiAgdmFyIHRlbXBsYXRlID0gSGFuZGxlYmFycy50ZW1wbGF0ZSh7ImNvbXBpbGVyIjpbNywiPj0gNC4wLjAiXSwibWFpbiI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHsKICAgIHZhciBzdGFjazEsIGhlbHBlcjsKCiAgcmV0dXJuICI8YnV0dG9uIGNsYXNzPVwicnRlLWJ1dHRvbiBydGUtYnV0dG9uLXF1aWV0ICIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5lbGVtZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbGVtZW50IDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImVsZW1lbnQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICIgIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzWyJjbGFzcyJdIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFsiY2xhc3MiXSA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjbGFzcyIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIiAiCiAgICArICgoc3RhY2sxID0gaGVscGVyc1siaWYiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNlbGVjdGVkIDogZGVwdGgwKSx7Im5hbWUiOiJpZiIsImhhc2giOnt9LCJmbiI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksImludmVyc2UiOmNvbnRhaW5lci5ub29wLCJkYXRhIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiAiIikKICAgICsgIlwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQ9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuY29tbWFuZCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY29tbWFuZCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjb21tYW5kIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiXCIgZGF0YS13eXNpaHRtbDUtY29tbWFuZC1zdGF0ZWNhbGxiYWNrZm49XCJGb3JtLnJ0ZS5Db21tYW5kU3RhdGVDYWxsYmFja3Muc2V0QnV0dG9uU3RhdGVcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kLWVsZW1lbnQ9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuZWxlbWVudCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZWxlbWVudCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJlbGVtZW50IiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiXCIgdHlwZT1cImJ1dHRvblwiIG5hbWU9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuY29tbWFuZCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY29tbWFuZCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjb21tYW5kIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiXCIgZGF0YS13eXNpaHRtbDUtY29tbWFuZC12YWx1ZT1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy52YWx1ZSB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWUgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoidmFsdWUiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiB0aXRsZT1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudGl0bGUgOiBkZXB0aDApLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiXCIgaHJlZj1cImphdmFzY3JpcHQ6O1wiIHVuc2VsZWN0YWJsZT1cIm9uXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJpY29uLSIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5pY29uIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pY29uIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6Imljb24iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L3NwYW4+XG4gICAgIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50ZXh0IDogZGVwdGgwKSx7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIlxuPC9idXR0b24+IjsKfSwiMSI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHsKICAgIHJldHVybiAiYWN0aXZlIjsKfSwidXNlRGF0YSI6dHJ1ZX0pOwogIHZhciB0ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzIHx8IHt9OwogIHRlbXBsYXRlc1snYnV0dG9uJ10gPSB0ZW1wbGF0ZTsKICB2YXIgcGFydGlhbHMgPSBIYW5kbGViYXJzLnBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyB8fCB7fTsKICBwYXJ0aWFsc1snYnV0dG9uJ10gPSB0ZW1wbGF0ZTsKCgovLyBTb3VyY2U6IC9hcHBzL2pua24vd29ya3NwYWNlL2dyZWVuU2hvb3RzLVJURS1SZXBvX3JlbGVhc2VfNjYwL21haW4vdGFyZ2V0L2NoZWNrb3V0L2NvbnRlbnQvc3JjL21haW4vdGVtcGxhdGVzL2NvbG9ySW5wdXQuaGFuZGxlYmFycwoKICB2YXIgdGVtcGxhdGUgPSBIYW5kbGViYXJzLnRlbXBsYXRlKHsiY29tcGlsZXIiOls3LCI+PSA0LjAuMCJdLCJtYWluIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkgewogICAgdmFyIGhlbHBlcjsKCiAgcmV0dXJuICI8ZGl2IGNsYXNzPVwicnRlLWNvbG9ySW5wdXQgIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzWyJjbGFzcyJdIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFsiY2xhc3MiXSA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjbGFzcyIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIHRpdGxlPVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50aXRsZSA6IGRlcHRoMCkseyJuYW1lIjoiSTE4biIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkpCiAgICArICJcIj5cbiAgICA8c3Bhbj4iCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKChoZWxwZXJzLkkxOG4gfHwgKGRlcHRoMCAmJiBkZXB0aDAuSTE4bikgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmxhYmVsIDogZGVwdGgwKSx7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIjwvc3Bhbj5cbiAgICA8aW5wdXQgY2xhc3M9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuZWxlbWVudCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZWxlbWVudCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJlbGVtZW50IiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiIHJ0ZS1jb2xvcklucHV0LWNvbnRyb2xcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kPVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLmNvbW1hbmQgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmNvbW1hbmQgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoiY29tbWFuZCIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQtc3RhdGVDYWxsYmFja0ZuPVwiRm9ybS5ydGUuQ29tbWFuZFN0YXRlQ2FsbGJhY2tzLnNldENvbG9ySW5wdXRWYWx1ZVwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQtZWxlbWVudD1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5lbGVtZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbGVtZW50IDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImVsZW1lbnQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBkYXRhLXd5c2lodG1sNS1za2lwPlxuPC9kaXY+IjsKfSwidXNlRGF0YSI6dHJ1ZX0pOwogIHZhciB0ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzIHx8IHt9OwogIHRlbXBsYXRlc1snY29sb3JJbnB1dCddID0gdGVtcGxhdGU7CiAgdmFyIHBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyA9IEhhbmRsZWJhcnMucGFydGlhbHMgfHwge307CiAgcGFydGlhbHNbJ2NvbG9ySW5wdXQnXSA9IHRlbXBsYXRlOwoKCi8vIFNvdXJjZTogL2FwcHMvam5rbi93b3Jrc3BhY2UvZ3JlZW5TaG9vdHMtUlRFLVJlcG9fcmVsZWFzZV82NjAvbWFpbi90YXJnZXQvY2hlY2tvdXQvY29udGVudC9zcmMvbWFpbi90ZW1wbGF0ZXMvZmluZEFuZFJlcGxhY2UuaGFuZGxlYmFycwoKICB2YXIgdGVtcGxhdGUgPSBIYW5kbGViYXJzLnRlbXBsYXRlKHsiY29tcGlsZXIiOls3LCI+PSA0LjAuMCJdLCJtYWluIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkgewogICAgcmV0dXJuICI8Zm9ybSBjbGFzcz1cInJ0ZV9maW5kQW5kUmVwbGFjZV9kaWFsb2dcIj5cbiAgICA8aW5wdXQgbmFtZT1cImZpbmRUZXh0XCIgdHlwZT1cInRleHRcIiBwbGFjZWhvbGRlcj1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwiRmluZCIseyJuYW1lIjoiSTE4biIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkpCiAgICArICJcIiBjbGFzcz1cInJ0ZS1pbnB1dFwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQ9XCJjaGFuZ2VGaW5kVGV4dFwiIGRhdGEtd3lzaWh0bWw1LXNraXA+XG4gICAgPGlucHV0IG5hbWU9XCJyZXBsYWNlVGV4dFwiIHR5cGU9XCJ0ZXh0XCIgcGxhY2Vob2xkZXI9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKChoZWxwZXJzLkkxOG4gfHwgKGRlcHRoMCAmJiBkZXB0aDAuSTE4bikgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIlJlcGxhY2UiLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiXCIgY2xhc3M9XCJydGUtaW5wdXRcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kPVwiY2hhbmdlUmVwbGFjZVRleHRcIiBkYXRhLXd5c2lodG1sNS1za2lwPlxuICAgIDxkaXYgY2xhc3M9XCJydGUtYmxvY2stZ3JvdXBcIj5cbiAgICAgICAgPGxhYmVsPlxuICAgICAgICAgICAgPGlucHV0IG5hbWU9XCJtYXRjaENhc2VcIiB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cInJ0ZV9tYXRjaENhc2VcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kPVwiY2hhbmdlTWF0Y2hDYXNlXCIgZGF0YS13eXNpaHRtbDUtc2tpcD5cbiAgICAgICAgICAgICIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwiTWF0Y2ggY2FzZSIseyJuYW1lIjoiSTE4biIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkpCiAgICArICJcbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGxhYmVsPlxuICAgICAgICAgICAgPGlucHV0IG5hbWU9XCJ3aG9sZVdvcmRcIiB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cInJ0ZV93aG9sZVdvcmRcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kPVwiY2hhbmdlV2hvbGVXb3JkXCIgZGF0YS13eXNpaHRtbDUtc2tpcD5cbiAgICAgICAgICAgICIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwiV2hvbGUgd29yZCIseyJuYW1lIjoiSTE4biIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkpCiAgICArICJcbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGxhYmVsPlxuICAgICAgICAgICAgPGlucHV0IG5hbWU9XCJyZWdFeHBcIiBvbmNoYW5nZT1cInRoaXMuZm9ybS53aG9sZVdvcmQuZGlzYWJsZWQgPSB0aGlzLmNoZWNrZWRcIiB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cInJ0ZV9yZWdFeHBcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kPVwiY2hhbmdlUmVnRXhwXCIgZGF0YS13eXNpaHRtbDUtc2tpcD5cbiAgICAgICAgICAgICIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwiUmVnIEV4Iix7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIlxuICAgICAgICA8L2xhYmVsPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJydGUtYmxvY2stZ3JvdXBcIj5cbiAgICA8YnV0dG9uIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQ9XCJmaW5kXCIgY2xhc3M9XCJydGUtYnV0dG9uXCIgdGFiaW5kZXg9XCItMVwiIHR5cGU9XCJidXR0b25cIj4iCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKChoZWxwZXJzLkkxOG4gfHwgKGRlcHRoMCAmJiBkZXB0aDAuSTE4bikgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIkZpbmQiLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiPC9idXR0b24+XG4gICAgPGJ1dHRvbiB0YWJpbmRleD1cIi0xXCIgZGF0YS13eXNpaHRtbDUtY29tbWFuZD1cInJlcGxhY2VcIiBjbGFzcz1cInJ0ZS1idXR0b25cIiB0eXBlPVwiYnV0dG9uXCI+IgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCJSZXBsYWNlIix7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIjwvYnV0dG9uPlxuICAgIDxidXR0b24gZGF0YS13eXNpaHRtbDUtY29tbWFuZD1cInJlcGxhY2VBbGxcIiBjbGFzcz1cInJ0ZS1idXR0b25cIiB0YWJpbmRleD1cIi0xXCIgdHlwZT1cImJ1dHRvblwiPiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwiUmVwbGFjZSBhbGwiLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiPC9idXR0b24+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInJ0ZV9maW5kTlJlcGxhY2VfYWxlcnQgYWxlcnQgYWxlcnQtaW5mbyBhbGVydC1kaXNtaXNzYWJsZVwiPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImNsb3NlXCIgZGF0YS1kaXNtaXNzPVwiYWxlcnRcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICZ0aW1lcztcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxzdHJvbmc+IgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCJJbmZvIix7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIjwvc3Ryb25nPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInJ0ZV9maW5kTlJlcGxhY2VfbWVzc2FnZVwiPjwvc3Bhbj5cbiAgICA8L2Rpdj5cbjwvZm9ybT5cbiI7Cn0sInVzZURhdGEiOnRydWV9KTsKICB2YXIgdGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyB8fCB7fTsKICB0ZW1wbGF0ZXNbJ2ZpbmRBbmRSZXBsYWNlJ10gPSB0ZW1wbGF0ZTsKICB2YXIgcGFydGlhbHMgPSBIYW5kbGViYXJzLnBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyB8fCB7fTsKICBwYXJ0aWFsc1snZmluZEFuZFJlcGxhY2UnXSA9IHRlbXBsYXRlOwoKCi8vIFNvdXJjZTogL2FwcHMvam5rbi93b3Jrc3BhY2UvZ3JlZW5TaG9vdHMtUlRFLVJlcG9fcmVsZWFzZV82NjAvbWFpbi90YXJnZXQvY2hlY2tvdXQvY29udGVudC9zcmMvbWFpbi90ZW1wbGF0ZXMvZ3JvdXAuaGFuZGxlYmFycwoKICB2YXIgdGVtcGxhdGUgPSBIYW5kbGViYXJzLnRlbXBsYXRlKHsiY29tcGlsZXIiOls3LCI+PSA0LjAuMCJdLCJtYWluIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkgewogICAgdmFyIHN0YWNrMSwgaGVscGVyOwoKICByZXR1cm4gIjxkaXYgY2xhc3M9XCJydGUtZ3JvdXAgIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzWyJjbGFzcyJdIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFsiY2xhc3MiXSA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjbGFzcyIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIHJvbGU9XCJncm91cFwiPlxuIgogICAgKyAoKHN0YWNrMSA9ICgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuY29udGVudCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY29udGVudCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjb250ZW50IiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKSAhPSBudWxsID8gc3RhY2sxIDogIiIpCiAgICArICJcbjwvZGl2PiI7Cn0sInVzZURhdGEiOnRydWV9KTsKICB2YXIgdGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyB8fCB7fTsKICB0ZW1wbGF0ZXNbJ2dyb3VwJ10gPSB0ZW1wbGF0ZTsKICB2YXIgcGFydGlhbHMgPSBIYW5kbGViYXJzLnBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyB8fCB7fTsKICBwYXJ0aWFsc1snZ3JvdXAnXSA9IHRlbXBsYXRlOwoKCi8vIFNvdXJjZTogL2FwcHMvam5rbi93b3Jrc3BhY2UvZ3JlZW5TaG9vdHMtUlRFLVJlcG9fcmVsZWFzZV82NjAvbWFpbi90YXJnZXQvY2hlY2tvdXQvY29udGVudC9zcmMvbWFpbi90ZW1wbGF0ZXMvbGluay5oYW5kbGViYXJzCgogIHZhciB0ZW1wbGF0ZSA9IEhhbmRsZWJhcnMudGVtcGxhdGUoeyJjb21waWxlciI6WzcsIj49IDQuMC4wIl0sIm1haW4iOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7CiAgICByZXR1cm4gIjxmb3JtIGNsYXNzPVwicnRlX2luc2VydExpbmtfZGlhbG9nXCIgcm9sZT1cImZvcm1cIj5cbiAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBwbGFjZWhvbGRlcj1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwiVVJMIix7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIlwiIGNsYXNzPVwicnRlLWlucHV0XCIgbmFtZT1cInVybFwiPlxuICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIHBsYWNlaG9sZGVyPVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCJBbHQgVGV4dCIseyJuYW1lIjoiSTE4biIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkpCiAgICArICJcIiB2YWx1ZT1cIlwiIG5hbWU9XCJhbHRcIiBjbGFzcz1cInJ0ZS1pbnB1dFwiPlxuICAgIDxzcGFuPlxuICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgbmFtZT1cInRhcmdldFwiIHZhbHVlPVwiZmFsc2VcIj5cbiAgICAgICAgIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCJPcGVuIGluIG5ldyBwYWdlIix7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIlxuICAgIDwvc3Bhbj5cbiAgICA8YnV0dG9uIG5hbWU9XCJzdWJtaXRcIiB0YWJpbmRleD1cIi0xXCIgY2xhc3M9XCJydGUtYnV0dG9uIHJ0ZS1idXR0b24tc3F1YXJlXCIgdHlwZT1cImJ1dHRvblwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQ9XCJjcmVhdGVMaW5rXCIgcnRlLWNsb3NlPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImljb24tb2tcIj48L3NwYW4+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvbiB0YWJpbmRleD1cIi0xXCIgY2xhc3M9XCJydGUtYnV0dG9uIHJ0ZS1idXR0b24tc3F1YXJlXCIgdHlwZT1cImJ1dHRvblwiIHJ0ZS1jbG9zZT5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJpY29uLWNhbmNlbFwiPjwvc3Bhbj5cbiAgICA8L2J1dHRvbj5cbjwvZm9ybT4iOwp9LCJ1c2VEYXRhIjp0cnVlfSk7CiAgdmFyIHRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgfHwge307CiAgdGVtcGxhdGVzWydsaW5rJ10gPSB0ZW1wbGF0ZTsKICB2YXIgcGFydGlhbHMgPSBIYW5kbGViYXJzLnBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyB8fCB7fTsKICBwYXJ0aWFsc1snbGluayddID0gdGVtcGxhdGU7CgoKLy8gU291cmNlOiAvYXBwcy9qbmtuL3dvcmtzcGFjZS9ncmVlblNob290cy1SVEUtUmVwb19yZWxlYXNlXzY2MC9tYWluL3RhcmdldC9jaGVja291dC9jb250ZW50L3NyYy9tYWluL3RlbXBsYXRlcy9udW1iZXJJbnB1dC5oYW5kbGViYXJzCgogIHZhciB0ZW1wbGF0ZSA9IEhhbmRsZWJhcnMudGVtcGxhdGUoeyJjb21waWxlciI6WzcsIj49IDQuMC4wIl0sIm1haW4iOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7CiAgICB2YXIgaGVscGVyOwoKICByZXR1cm4gIjxkaXYgY2xhc3M9XCJydGUtbnVtYmVySW5wdXQgIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzWyJjbGFzcyJdIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFsiY2xhc3MiXSA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjbGFzcyIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIHRpdGxlPVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50aXRsZSA6IGRlcHRoMCkseyJuYW1lIjoiSTE4biIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkpCiAgICArICJcIj5cbiAgICA8c3Bhbj4iCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKChoZWxwZXJzLkkxOG4gfHwgKGRlcHRoMCAmJiBkZXB0aDAuSTE4bikgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmxhYmVsIDogZGVwdGgwKSx7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIjwvc3Bhbj5cbiAgICA8aW5wdXQgY2xhc3M9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuZWxlbWVudCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZWxlbWVudCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJlbGVtZW50IiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiXCIgdmFsdWU9XCIwXCIgbmFtZT1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5jb21tYW5kIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb21tYW5kIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImNvbW1hbmQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiB0eXBlPVwibnVtYmVyXCIgZGF0YS13eXNpaHRtbDUtY29tbWFuZD1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5jb21tYW5kIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb21tYW5kIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImNvbW1hbmQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kLXN0YXRlQ2FsbGJhY2tGbj1cIkZvcm0ucnRlLkNvbW1hbmRTdGF0ZUNhbGxiYWNrcy5zZXROdW1iZXJJbnB1dFZhbHVlXCIgZGF0YS13eXNpaHRtbDUtY29tbWFuZC1lbGVtZW50PVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLmVsZW1lbnQgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmVsZW1lbnQgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoiZWxlbWVudCIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIHVuc2VsZWN0YWJsZT1cIm9mZlwiIGRhdGEtd3lzaWh0bWw1LXNraXAgbWluPVwiMFwiIHN0ZXA9XCJhbnlcIj5cbjwvZGl2PiI7Cn0sInVzZURhdGEiOnRydWV9KTsKICB2YXIgdGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyB8fCB7fTsKICB0ZW1wbGF0ZXNbJ251bWJlcklucHV0J10gPSB0ZW1wbGF0ZTsKICB2YXIgcGFydGlhbHMgPSBIYW5kbGViYXJzLnBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyB8fCB7fTsKICBwYXJ0aWFsc1snbnVtYmVySW5wdXQnXSA9IHRlbXBsYXRlOwoKCi8vIFNvdXJjZTogL2FwcHMvam5rbi93b3Jrc3BhY2UvZ3JlZW5TaG9vdHMtUlRFLVJlcG9fcmVsZWFzZV82NjAvbWFpbi90YXJnZXQvY2hlY2tvdXQvY29udGVudC9zcmMvbWFpbi90ZW1wbGF0ZXMvcG9wb3Zlci5oYW5kbGViYXJzCgogIHZhciB0ZW1wbGF0ZSA9IEhhbmRsZWJhcnMudGVtcGxhdGUoeyJjb21waWxlciI6WzcsIj49IDQuMC4wIl0sIm1haW4iOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7CiAgICB2YXIgc3RhY2sxLCBoZWxwZXI7CgogIHJldHVybiAiPGRpdiBjbGFzcz1cInJ0ZS1wb3BvdmVyXCI+XG4gICAgPGJ1dHRvbiBjbGFzcz1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5lbGVtZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbGVtZW50IDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImVsZW1lbnQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICIgcnRlLWJ1dHRvbiBydGUtYnV0dG9uLXF1aWV0ICIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVyc1siY2xhc3MiXSB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbImNsYXNzIl0gOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoiY2xhc3MiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1wbGFjZW1lbnQ9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMucGxhY2VtZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wbGFjZW1lbnQgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoicGxhY2VtZW50IiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiXCIgbmFtZT1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5jb21tYW5kIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb21tYW5kIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImNvbW1hbmQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kPVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLmNvbW1hbmQgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmNvbW1hbmQgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoiY29tbWFuZCIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQtc3RhdGVjYWxsYmFja2ZuPVwiIgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLmNhbGxiYWNrIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jYWxsYmFjayA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJjYWxsYmFjayIsImhhc2giOnt9LCJkYXRhIjpkYXRhfSkgOiBoZWxwZXIpKSkKICAgICsgIlwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQtZWxlbWVudD1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5lbGVtZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbGVtZW50IDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImVsZW1lbnQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBocmVmPVwiamF2YXNjcmlwdDo7XCIgdW5zZWxlY3RhYmxlPVwib25cIiB0aXRsZT1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudGl0bGUgOiBkZXB0aDApLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaWNvbi0iCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuaWNvbiB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWNvbiA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJpY29uIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9zcGFuPlxuICAgICAgICAiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKChoZWxwZXJzLkkxOG4gfHwgKGRlcHRoMCAmJiBkZXB0aDAuSTE4bikgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnRleHQgOiBkZXB0aDApLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiXG4gICAgPC9idXR0b24+XG4gICAgPGRpdiBjbGFzcz1cInBvcG92ZXJcIj4iCiAgICArICgoc3RhY2sxID0gKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5jb250ZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb250ZW50IDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImNvbnRlbnQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpICE9IG51bGwgPyBzdGFjazEgOiAiIikKICAgICsgIjwvZGl2PlxuPC9kaXY+IjsKfSwidXNlRGF0YSI6dHJ1ZX0pOwogIHZhciB0ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzIHx8IHt9OwogIHRlbXBsYXRlc1sncG9wb3ZlciddID0gdGVtcGxhdGU7CiAgdmFyIHBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyA9IEhhbmRsZWJhcnMucGFydGlhbHMgfHwge307CiAgcGFydGlhbHNbJ3BvcG92ZXInXSA9IHRlbXBsYXRlOwoKCi8vIFNvdXJjZTogL2FwcHMvam5rbi93b3Jrc3BhY2UvZ3JlZW5TaG9vdHMtUlRFLVJlcG9fcmVsZWFzZV82NjAvbWFpbi90YXJnZXQvY2hlY2tvdXQvY29udGVudC9zcmMvbWFpbi90ZW1wbGF0ZXMvcnRldG9vbGJhci5oYW5kbGViYXJzCgogIHZhciB0ZW1wbGF0ZSA9IEhhbmRsZWJhcnMudGVtcGxhdGUoeyJjb21waWxlciI6WzcsIj49IDQuMC4wIl0sIm1haW4iOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7CiAgICB2YXIgc3RhY2sxOwoKICByZXR1cm4gIjxkaXYgY2xhc3M9XCJydGVfdG9vbEJhclwiIHJvbGU9XCJ0b29sYmFyXCI+IgogICAgKyAoKHN0YWNrMSA9IGNvbnRhaW5lci5sYW1iZGEoZGVwdGgwLCBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxIDogIiIpCiAgICArICI8L2Rpdj4iOwp9LCJ1c2VEYXRhIjp0cnVlfSk7CiAgdmFyIHRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgfHwge307CiAgdGVtcGxhdGVzWydydGV0b29sYmFyJ10gPSB0ZW1wbGF0ZTsKICB2YXIgcGFydGlhbHMgPSBIYW5kbGViYXJzLnBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyB8fCB7fTsKICBwYXJ0aWFsc1sncnRldG9vbGJhciddID0gdGVtcGxhdGU7CgoKLy8gU291cmNlOiAvYXBwcy9qbmtuL3dvcmtzcGFjZS9ncmVlblNob290cy1SVEUtUmVwb19yZWxlYXNlXzY2MC9tYWluL3RhcmdldC9jaGVja291dC9jb250ZW50L3NyYy9tYWluL3RlbXBsYXRlcy9zZWxlY3QuaGFuZGxlYmFycwoKICB2YXIgdGVtcGxhdGUgPSBIYW5kbGViYXJzLnRlbXBsYXRlKHsiY29tcGlsZXIiOls3LCI+PSA0LjAuMCJdLCJtYWluIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkgewogICAgdmFyIHN0YWNrMSwgaGVscGVyOwoKICByZXR1cm4gIjxkaXYgY2xhc3M9XCJydGUtc2VsZWN0XCIgdGl0bGU9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKChoZWxwZXJzLkkxOG4gfHwgKGRlcHRoMCAmJiBkZXB0aDAuSTE4bikgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnRpdGxlIDogZGVwdGgwKSx7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSkKICAgICsgIlwiPlxuICAgIDxzZWxlY3QgY2xhc3M9XCIiCiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuZWxlbWVudCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZWxlbWVudCA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLCh0eXBlb2YgaGVscGVyID09PSAiZnVuY3Rpb24iID8gaGVscGVyLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSx7Im5hbWUiOiJlbGVtZW50IiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKQogICAgKyAiICIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVyc1siY2xhc3MiXSB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbImNsYXNzIl0gOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogaGVscGVycy5oZWxwZXJNaXNzaW5nKSwodHlwZW9mIGhlbHBlciA9PT0gImZ1bmN0aW9uIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30seyJuYW1lIjoiY2xhc3MiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBkYXRhLXd5c2lodG1sNS1za2lwPVwiXCIgZGF0YS13eXNpaHRtbDUtY29tbWFuZD1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5jb21tYW5kIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb21tYW5kIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImNvbW1hbmQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIiBkYXRhLXd5c2lodG1sNS1jb21tYW5kLXN0YXRlQ2FsbGJhY2tGbj1cIkZvcm0ucnRlLkNvbW1hbmRTdGF0ZUNhbGxiYWNrcy5zZXRTZWxlY3RTdGF0ZVwiIGRhdGEtd3lzaWh0bWw1LWNvbW1hbmQtZWxlbWVudD1cIiIKICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5lbGVtZW50IHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbGVtZW50IDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6ImVsZW1lbnQiLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pIDogaGVscGVyKSkpCiAgICArICJcIj5cbiAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiIHN0eWxlPVwiZGlzcGxheTpub25lXCI+IgogICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCJTZWxlY3QiLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKQogICAgKyAiPC9vcHRpb24+XG4iCiAgICArICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAub3B0aW9ucyA6IGRlcHRoMCkseyJuYW1lIjoiZWFjaCIsImhhc2giOnt9LCJmbiI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksImludmVyc2UiOmNvbnRhaW5lci5ub29wLCJkYXRhIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiAiIikKICAgICsgIiAgICA8L3NlbGVjdD5cbiAgICA8aSBjbGFzcz1cInJ0ZS10b2dnbGVTZWxlY3QgaWNvbi1kb3duLW9wZW5cIj48L2k+XG48L2Rpdj5cbiI7Cn0sIjEiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7CiAgICB2YXIgc3RhY2sxOwoKICByZXR1cm4gIiAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCIiCiAgICArICgoc3RhY2sxID0gaGVscGVyc1siaWYiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlIDogZGVwdGgwKSx7Im5hbWUiOiJpZiIsImhhc2giOnt9LCJmbiI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksImludmVyc2UiOmNvbnRhaW5lci5wcm9ncmFtKDQsIGRhdGEsIDApLCJkYXRhIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiAiIikKICAgICsgIlwiPiIKICAgICsgKChzdGFjazEgPSBoZWxwZXJzWyJpZiJdLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubGFiZWwgOiBkZXB0aDApLHsibmFtZSI6ImlmIiwiaGFzaCI6e30sImZuIjpjb250YWluZXIucHJvZ3JhbSg2LCBkYXRhLCAwKSwiaW52ZXJzZSI6Y29udGFpbmVyLnByb2dyYW0oOCwgZGF0YSwgMCksImRhdGEiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6ICIiKQogICAgKyAiPC9vcHRpb24+XG4iOwp9LCIyIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkgewogICAgdmFyIGhlbHBlcjsKCiAgcmV0dXJuIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMudmFsdWUgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09ICJmdW5jdGlvbiIgPyBoZWxwZXIuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LHsibmFtZSI6InZhbHVlIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSA6IGhlbHBlcikpKTsKfSwiNCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHsKICAgIHJldHVybiBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbihjb250YWluZXIubGFtYmRhKGRlcHRoMCwgZGVwdGgwKSk7Cn0sIjYiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7CiAgICByZXR1cm4gY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKGhlbHBlcnMuSTE4biB8fCAoZGVwdGgwICYmIGRlcHRoMC5JMThuKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubGFiZWwgOiBkZXB0aDApLHsibmFtZSI6IkkxOG4iLCJoYXNoIjp7fSwiZGF0YSI6ZGF0YX0pKTsKfSwiOCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHsKICAgIHJldHVybiBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5JMThuIHx8IChkZXB0aDAgJiYgZGVwdGgwLkkxOG4pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LGRlcHRoMCx7Im5hbWUiOiJJMThuIiwiaGFzaCI6e30sImRhdGEiOmRhdGF9KSk7Cn0sInVzZURhdGEiOnRydWV9KTsKICB2YXIgdGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgPSBIYW5kbGViYXJzLnRlbXBsYXRlcyB8fCB7fTsKICB0ZW1wbGF0ZXNbJ3NlbGVjdCddID0gdGVtcGxhdGU7CiAgdmFyIHBhcnRpYWxzID0gSGFuZGxlYmFycy5wYXJ0aWFscyA9IEhhbmRsZWJhcnMucGFydGlhbHMgfHwge307CiAgcGFydGlhbHNbJ3NlbGVjdCddID0gdGVtcGxhdGU7CgoKCn0pKCk7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDcvMjkvMjAxNi4KICovCgooZnVuY3Rpb24gKG5zKSB7CgogICAgLyogT3V0IG9mIHRoZSBib3ggcHJvdmlkZWQgQ29tbWFuZHMqLwogICAgdmFyIENvbW1hbmRzID0gbnMuQ29tbWFuZHMgPSB7fTsKCiAgICBDb21tYW5kcy5VTkRPID0gInVuZG8iOwogICAgQ29tbWFuZHMuUkVETyA9ICJyZWRvIjsKCiAgICBDb21tYW5kcy5CT0xEID0gImJvbGQiOwogICAgQ29tbWFuZHMuSVRBTElDID0gIml0YWxpYyI7CiAgICBDb21tYW5kcy5VTkRFUkxJTkUgPSAidW5kZXJsaW5lIjsKICAgIENvbW1hbmRzLlNVUEVSU0NSSVBUID0gInN1cGVyc2NyaXB0IjsKICAgIENvbW1hbmRzLlNVQlNDUklQVCA9ICJzdWJzY3JpcHQiOwogICAgQ29tbWFuZHMuRk9SRV9DT0xPUiA9ICJmb3JlQ29sb3IiOwogICAgQ29tbWFuZHMuSElMSVRFX0NPTE9SID0gImhpbGl0ZUNvbG9yIjsKCiAgICBDb21tYW5kcy5GT05UX0ZBTUlMWSA9ICJmb250RmFtaWx5IjsKICAgIENvbW1hbmRzLkZPTlRfU0laRSA9ICJmb250U2l6ZSI7CiAgICBDb21tYW5kcy5MSU5FX0hFSUdIVCA9ICJsaW5lSGVpZ2h0IjsKICAgIENvbW1hbmRzLkxFVFRFUl9TUEFDSU5HID0gImxldHRlclNwYWNpbmciOwogICAgQ29tbWFuZHMuSEVBREVSID0gImhlYWRlciI7CgogICAgQ29tbWFuZHMuSlVTVElGWV9MRUZUID0gImp1c3RpZnlMZWZ0IjsKICAgIENvbW1hbmRzLkpVU1RJRllfQ0VOVEVSID0gImp1c3RpZnlDZW50ZXIiOwogICAgQ29tbWFuZHMuSlVTVElGWV9GVUxMID0gImp1c3RpZnlGdWxsIjsKICAgIENvbW1hbmRzLkpVU1RJRllfUklHSFQgPSAianVzdGlmeVJpZ2h0IjsKCiAgICBDb21tYW5kcy5NQVJHSU5fTEVGVCA9ICJtYXJnaW5MZWZ0IjsKICAgIENvbW1hbmRzLk1BUkdJTl9SSUdIVCA9ICJtYXJnaW5SaWdodCI7CiAgICBDb21tYW5kcy5NQVJHSU5fVE9QID0gIm1hcmdpblRvcCI7CiAgICBDb21tYW5kcy5NQVJHSU5fQk9UVE9NID0gIm1hcmdpbkJvdHRvbSI7CgogICAgQ29tbWFuZHMuSU5TRVJUX1VOT1JERVJFRF9MSVNUID0gImluc2VydFVub3JkZXJlZExpc3QiOwogICAgQ29tbWFuZHMuSU5TRVJUX09SREVSRURfTElTVCA9ICJpbnNlcnRPcmRlcmVkTGlzdCI7CiAgICBDb21tYW5kcy5JTlNFUlRfVVBQRVJDQVNFX0FMUEhBQkVUX0xJU1QgPSAiaW5zZXJ0VXBwZXJjYXNlQWxwaGFiZXRMaXN0IjsKICAgIENvbW1hbmRzLklOU0VSVF9MT1dFUkNBU0VfQUxQSEFCRVRfTElTVCA9ICJpbnNlcnRMb3dlcmNhc2VBbHBoYWJldExpc3QiOwogICAgQ29tbWFuZHMuSU5TRVJUX1VQUEVSQ0FTRV9ST01BTl9MSVNUID0gImluc2VydFVwcGVyY2FzZVJvbWFuTGlzdCI7CiAgICBDb21tYW5kcy5JTlNFUlRfTE9XRVJDQVNFX1JPTUFOX0xJU1QgPSAiaW5zZXJ0TG93ZXJjYXNlUm9tYW5MaXN0IjsKCiAgICBDb21tYW5kcy5JTkRFTlQgPSAiaW5kZW50IjsKICAgIENvbW1hbmRzLk9VVERFTlQgPSAib3V0ZGVudCI7CgogICAgQ29tbWFuZHMuTU9ERSA9ICJtb2RlIjsKICAgIENvbW1hbmRzLkZJTkRfQU5EX1JFUExBQ0UgPSAiZmluZEFuZFJlcGxhY2UiOwogICAgQ29tbWFuZHMuTElOSyA9ICJsaW5rIjsKICAgIENvbW1hbmRzLklOU0VSVF9URVhUID0gImluc2VydFRleHQiOwoKICAgIC8qIFRvb2xiYXIgTW9kZXMqLwogICAgdmFyIFRvb2xiYXJNb2RlID0gbnMuVG9vbGJhck1vZGUgPSB7fTsKICAgIFRvb2xiYXJNb2RlLkJBU0lDID0gImJhc2ljIjsKICAgIFRvb2xiYXJNb2RlLkZVTEwgPSAiZnVsbCI7CgogICAgdmFyIEtleWJvYXJkID0gbnMuS2V5Ym9hcmQgPSB7fTsKCiAgICBLZXlib2FyZC5LRVlDT0RFX0IgPSA2NjsKICAgIEtleWJvYXJkLktFWUNPREVfSSA9IDczOwogICAgS2V5Ym9hcmQuS0VZQ09ERV9VID0gODU7CiAgICBLZXlib2FyZC5LRVlDT0RFX1MgPSA4MzsKICAgIEtleWJvYXJkLktFWUNPREVfRSA9IDY5OwogICAgS2V5Ym9hcmQuS0VZQ09ERV9MID0gNzY7CiAgICBLZXlib2FyZC5LRVlDT0RFX1IgPSA4MjsKICAgIEtleWJvYXJkLktFWUNPREVfSiA9IDc0OwogICAgS2V5Ym9hcmQuS0VZQ09ERV9HUkVBVEVSX1RIQU4gPSAxOTA7CiAgICBLZXlib2FyZC5LRVlDT0RFX0xFU1NfVEhBTiA9IDE4ODsKCn0pKEZvcm0ucnRlKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKKGZ1bmN0aW9uIChucykgewogICAgInVzZSBzdHJpY3QiOwoKICAgIC8qIERlZmF1bHQgRWRpdG9yIGNvbmZpZ3VyYXRpb25zKi8KICAgIG5zLkRlZmF1bHRDb25maWcgPSB7CiAgICAgICAgZm9udEZhbWlseSA6IHsKICAgICAgICAgICAgZGVmYXVsdFZhbHVlIDogIlRpbWVzIE5ldyBSb21hbiIsCiAgICAgICAgICAgIG9wdGlvbnMgOiBbIlRpbWVzIE5ldyBSb21hbiIsICJBcmlhbCIsICJDb3VyaWVyIiwgIkNvdXJpZXIgTmV3IiwgIkdlbmV2YSIsICJHZW9yZ2lhIiwgIkhlbHZldGljYSIsICJUYWhvbWEiLCAiVGltZXMiLCAiVmVyZGFuYSJdCiAgICAgICAgfSwKICAgICAgICBmb250U2l6ZSA6IHsKICAgICAgICAgICAgZGVmYXVsdFZhbHVlIDogMTIsCiAgICAgICAgICAgIG9wdGlvbnMgOiBbOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNiwgMTgsIDIwLCAyMiwgMjQsIDI2LCAyOCwgMzYsIDQ4LCA3Ml0KICAgICAgICB9LAogICAgICAgIGxpbmVIZWlnaHQgOiB7CiAgICAgICAgICAgIG9wdGlvbnMgOiBbMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwgMTZdCiAgICAgICAgfSwKICAgICAgICBsZXR0ZXJTcGFjaW5nIDogewogICAgICAgICAgICBkZWZhdWx0VmFsdWUgOiAiMCIsCiAgICAgICAgICAgIG9wdGlvbnMgOiBbIjAiLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LCAxNl0KICAgICAgICB9LAogICAgICAgIGhlYWRlciA6IHsKICAgICAgICAgICAgZGVmYXVsdFZhbHVlIDogInAiLAogICAgICAgICAgICBvcHRpb25zIDogWwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhbHVlIDogInAiLAogICAgICAgICAgICAgICAgICAgIGxhYmVsIDogIk5vbmUiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhbHVlIDogImgxIiwKICAgICAgICAgICAgICAgICAgICBsYWJlbCA6ICJIZWFkZXIgMSIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgOiAiaDIiLAogICAgICAgICAgICAgICAgICAgIGxhYmVsIDogIkhlYWRlciAyIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA6ICJoMyIsCiAgICAgICAgICAgICAgICAgICAgbGFiZWwgOiAiSGVhZGVyIDMiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhbHVlIDogImg0IiwKICAgICAgICAgICAgICAgICAgICBsYWJlbCA6ICJIZWFkZXIgNCIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgOiAiaDUiLAogICAgICAgICAgICAgICAgICAgIGxhYmVsIDogIkhlYWRlciA1IgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YWx1ZSA6ICJoNiIsCiAgICAgICAgICAgICAgICAgICAgbGFiZWwgOiAiSGVhZGVyIDYiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICB9LAogICAgICAgIGNvbG9yIDogewogICAgICAgICAgICB3aGl0ZSA6ICdmZmYnLAogICAgICAgICAgICByZWQgOiAnZjAwJywKICAgICAgICAgICAgb3JhbmdlIDogJ2Y2MCcsCiAgICAgICAgICAgIHllbGxvdyA6ICdmZjAnLAogICAgICAgICAgICBncmVlbiA6ICcwMDgwMDAnLAogICAgICAgICAgICBibHVlIDogJzAwZicsCiAgICAgICAgICAgIHB1cnBsZSA6ICc4MDAwODAnLAogICAgICAgICAgICBibGFjayA6ICcwMDAnCiAgICAgICAgfQogICAgICAgIC8vVE9ETyA6IGFkZCBjb25maWd1cmF0aW9uIGZvciBDdXN0b20gY2xhc3NlcwogICAgfTsKCiAgICAvKiBPdXQgb2YgdGhlIGJveCB0b29sYmFyIGNvbmZpZ3VyYXRpb24gcHJvdmlkZWQgKi8KICAgIG5zLlRvb2xiYXJDb25maWcgPSB7CiAgICAgICAgZGVmYXVsdE1vZGUgOiAnYmFzaWMnLAogICAgICAgIHRvb2xiYXJzIDogewogICAgICAgICAgICBiYXNpYyA6IHsKICAgICAgICAgICAgICAgIGxheW91dCA6IFsKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgOiAiSGVhZGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMgOiBbbnMuQ29tbWFuZHMuSEVBREVSXQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuYW1lIDogIlBhcmFncmFwaCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zIDogW25zLkNvbW1hbmRzLkJPTEQsIG5zLkNvbW1hbmRzLklUQUxJQywgbnMuQ29tbWFuZHMuVU5ERVJMSU5FXQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kIDogJ2xpc3RzJywKICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgOiAiTGlzdCBUeXBlIiwKICAgICAgICAgICAgICAgICAgICAgICAgaWNvbiA6ICdsaXN0JywKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA6ICdwb3BvdmVyJywKICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2VtZW50IDogJ2JvdHRvbScsCiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zIDogW25zLkNvbW1hbmRzLklOU0VSVF9VTk9SREVSRURfTElTVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLklOU0VSVF9PUkRFUkVEX0xJU1QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBucy5Db21tYW5kcy5JTlNFUlRfTE9XRVJDQVNFX0FMUEhBQkVUX0xJU1RdCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlIDogJ0V4cGFuZCcsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgOiBucy5Db21tYW5kcy5NT0RFLAogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA6IG5zLlRvb2xiYXJNb2RlLkZVTEwsCiAgICAgICAgICAgICAgICAgICAgICAgIGljb24gOiAncmVzaXplLWZ1bGwnCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAgIGZsb2F0aW5nIDogdHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICBmdWxsIDogewogICAgICAgICAgICAgICAgbGF5b3V0IDogWwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMgOiBbbnMuQ29tbWFuZHMuVU5ETywgbnMuQ29tbWFuZHMuUkVETywgbnMuQ29tbWFuZHMuTElOSywgbnMuQ29tbWFuZHMuRklORF9BTkRfUkVQTEFDRV0KICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA6ICJQYXJhZ3JhcGgiLAogICAgICAgICAgICAgICAgICAgICAgICBpdGVtcyA6IFsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLkhFQURFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLkZPTlRfRkFNSUxZLG5zLkNvbW1hbmRzLkZPTlRfU0laRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLkJPTEQsIG5zLkNvbW1hbmRzLklUQUxJQywgbnMuQ29tbWFuZHMuVU5ERVJMSU5FLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMuQ29tbWFuZHMuU1VQRVJTQ1JJUFQsIG5zLkNvbW1hbmRzLlNVQlNDUklQVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLkxFVFRFUl9TUEFDSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMuQ29tbWFuZHMuTElORV9IRUlHSFQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBucy5Db21tYW5kcy5GT1JFX0NPTE9SLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMuQ29tbWFuZHMuSElMSVRFX0NPTE9SCiAgICAgICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA6ICJBbGlnbm1lbnQiLAogICAgICAgICAgICAgICAgICAgICAgICBpdGVtcyA6IFsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLkpVU1RJRllfTEVGVCwgbnMuQ29tbWFuZHMuSlVTVElGWV9DRU5URVIsIG5zLkNvbW1hbmRzLkpVU1RJRllfRlVMTCwgbnMuQ29tbWFuZHMuSlVTVElGWV9SSUdIVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLk1BUkdJTl9MRUZULCBucy5Db21tYW5kcy5NQVJHSU5fUklHSFQsIG5zLkNvbW1hbmRzLk1BUkdJTl9UT1AsIG5zLkNvbW1hbmRzLk1BUkdJTl9CT1RUT00KICAgICAgICAgICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBuYW1lIDogIkxpc3RpbmciLAogICAgICAgICAgICAgICAgICAgICAgICBpdGVtcyA6IFtucy5Db21tYW5kcy5JTlNFUlRfVU5PUkRFUkVEX0xJU1QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMuQ29tbWFuZHMuSU5TRVJUX09SREVSRURfTElTVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBucy5Db21tYW5kcy5JTlNFUlRfVVBQRVJDQVNFX0FMUEhBQkVUX0xJU1QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMuQ29tbWFuZHMuSU5TRVJUX0xPV0VSQ0FTRV9BTFBIQUJFVF9MSVNULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zLkNvbW1hbmRzLklOU0VSVF9VUFBFUkNBU0VfUk9NQU5fTElTVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBucy5Db21tYW5kcy5JTlNFUlRfTE9XRVJDQVNFX1JPTUFOX0xJU1QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnMuQ29tbWFuZHMuSU5ERU5ULCBucy5Db21tYW5kcy5PVVRERU5UCiAgICAgICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgOiAnQ29sbGFwc2UnLAogICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kIDogbnMuQ29tbWFuZHMuTU9ERSwKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgOiBucy5Ub29sYmFyTW9kZS5CQVNJQywKICAgICAgICAgICAgICAgICAgICAgICAgaWNvbiA6ICdyZXNpemUtc21hbGwnLAogICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZCA6IHRydWUKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Owp9KShGb3JtLnJ0ZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiA3LzI5LzIwMTYuCiAqLwoKKGZ1bmN0aW9uIChucykgewoKICAgIHZhciBGaW5kQW5kUmVwbGFjZSA9IG5zLkZpbmRBbmRSZXBsYWNlID0gZnVuY3Rpb24gKHRleHRFZGl0b3IpIHsKICAgICAgICB0aGlzLnRleHRFZGl0b3IgPSB0ZXh0RWRpdG9yOwogICAgICAgIHRoaXMuX21lc3NhZ2UgPSAiIjsKICAgICAgICB0aGlzLl93aG9sZVdvcmRFbmFibGVkID0gdHJ1ZTsKICAgICAgICB0aGlzLmlzRGlydHkgPSB0cnVlOwogICAgICAgIHRoaXMuaXNWYWxpZCA9IHRydWU7CiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcywgeyJzb3VyY2UiIDogeyJnZXQiIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy50ZXh0RWRpdG9yICYmIHRoaXMudGV4dEVkaXRvci5lZGl0b3IgJiYgdGhpcy50ZXh0RWRpdG9yLmVkaXRvci5jb21wb3NlciAmJiB0aGlzLnRleHRFZGl0b3IuZWRpdG9yLmNvbXBvc2VyLmNvbnRhaW5lciA/IHRoaXMudGV4dEVkaXRvci5lZGl0b3IuY29tcG9zZXIuY29udGFpbmVyLnRleHRDb250ZW50IHx8IHRoaXMudGV4dEVkaXRvci5lZGl0b3IuY29tcG9zZXIuY29udGFpbmVyLm91dGVyVGV4dCA6ICIiOwogICAgICAgIH19fSk7CiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcywgeyJtZXNzYWdlIiA6IHsiZ2V0IiA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21lc3NhZ2U7CiAgICAgICAgfSwgInNldCIgOiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgdGhpcy5fbWVzc2FnZSA9IHZhbHVlOwogICAgICAgIH19fSk7CiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcywgeyJ3aG9sZVdvcmRFbmFibGVkIiA6IHsiZ2V0IiA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dob2xlV29yZEVuYWJsZWQ7CiAgICAgICAgfSwgInNldCIgOiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgdGhpcy5fd2hvbGVXb3JkRW5hYmxlZCA9IHZhbHVlOwogICAgICAgIH19fSk7CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5zZXRTZWxlY3Rpb25BbmRIaWdobGlnaHQgPSBmdW5jdGlvbiAoY29udGFpbmVyLCByZWxhdGl2ZVN0YXJ0LCByZWxhdGl2ZUVuZCkgewogICAgICAgIGlmIChjb250YWluZXIgPT0gbnVsbCkgewogICAgICAgICAgICBjb250YWluZXIgPSB0aGlzLnRleHRFZGl0b3IuY29udGFpbmVyOwogICAgICAgICAgICBpZiAoIWNvbnRhaW5lcikgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHZhciBjaGFySW5kZXggPSAwLCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7CiAgICAgICAgcmFuZ2Uuc2V0U3RhcnQoZG9jdW1lbnQsIDApOwogICAgICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpOwogICAgICAgIHZhciBub2RlU3RhY2sgPSBbY29udGFpbmVyXSwgbm9kZSwgZm91bmRTdGFydCA9IGZhbHNlLCBzdG9wID0gZmFsc2U7CiAgICAgICAgdmFyIG5ld0xpbmVDb3VudCA9IDA7CiAgICAgICAgd2hpbGUgKCFzdG9wICYmIChub2RlID0gbm9kZVN0YWNrLnBvcCgpKSkgewogICAgICAgICAgICBpZiAobm9kZSAmJiBub2RlLm5vZGVUeXBlID09IDMpIHsKICAgICAgICAgICAgICAgIHZhciBuZXh0Q2hhckluZGV4ID0gY2hhckluZGV4ICsgbm9kZS5ub2RlVmFsdWUubGVuZ3RoOwogICAgICAgICAgICAgICAgaWYgKHRoaXMucmVsYXRpdmVTdGFydCA+PSBjaGFySW5kZXggJiYgdGhpcy5yZWxhdGl2ZVN0YXJ0IDw9IG5leHRDaGFySW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICByYW5nZS5zZXRTdGFydChub2RlLCB0aGlzLnJlbGF0aXZlU3RhcnQgLSBjaGFySW5kZXgpOwogICAgICAgICAgICAgICAgICAgIGZvdW5kU3RhcnQgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGZvdW5kU3RhcnQgJiYgdGhpcy5yZWxhdGl2ZUVuZCA+PSBjaGFySW5kZXggJiYgdGhpcy5yZWxhdGl2ZUVuZCA8PSBuZXh0Q2hhckluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2Uuc2V0RW5kKG5vZGUsIHRoaXMucmVsYXRpdmVFbmQgLSBjaGFySW5kZXgpOwogICAgICAgICAgICAgICAgICAgIHN0b3AgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2hhckluZGV4ID0gbmV4dENoYXJJbmRleDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBpID0gbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDsKICAgICAgICAgICAgICAgIHdoaWxlIChpLS0pIHsKICAgICAgICAgICAgICAgICAgICBub2RlU3RhY2sucHVzaChub2RlLmNoaWxkTm9kZXNbaV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB2YXIgc2VsID0gZG9jdW1lbnQuZ2V0U2VsZWN0aW9uKCk7CiAgICAgICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpOwogICAgICAgIHNlbC5hZGRSYW5nZShyYW5nZSk7CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5vblJlZ0V4cFNlbGVjdGlvbkNoYW5nZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlKCk7CiAgICAgICAgdGhpcy5zZXRXaG9sZVdvcmRFbmFibGVkKCk7CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5vbkZpbmRWYWx1ZUNoYW5nZSA9IGZ1bmN0aW9uIChmaW5kVmFsKSB7CiAgICAgICAgaWYgKGZpbmRWYWwgIT0gdGhpcy5maW5kVGV4dCkgewogICAgICAgICAgICB0aGlzLmZpbmRUZXh0ID0gZmluZFZhbDsKICAgICAgICB9CiAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZSgpOwogICAgICAgIHRoaXMuc2V0V2hvbGVXb3JkRW5hYmxlZCgpOwogICAgfTsKCiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUub25SZXBsYWNlVmFsdWVDaGFuZ2UgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZSgpOwogICAgfTsKCiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUuc2V0V2hvbGVXb3JkRW5hYmxlZCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAodGhpcy5maW5kVGV4dCkgewogICAgICAgICAgICB2YXIgcmVzdWx0ID0gbnMudXRpbC5TdHJpbmdIZWxwZXIucmVzdHJpY3QodGhpcy5maW5kVGV4dCwgIl5gfiFAIyUmKigpPStbXXt9L1x8J1wiOzovPy4+PCwiKTsKICAgICAgICAgICAgaWYgKHRoaXMuZmluZFRleHQgIT0gcmVzdWx0KSB7CiAgICAgICAgICAgICAgICB0aGlzLndob2xlV29yZEVuYWJsZWQgPSBmYWxzZTsKICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmlzUmVnRXgpIHsKICAgICAgICAgICAgICAgIHRoaXMud2hvbGVXb3JkRW5hYmxlZCA9ICF0aGlzLmlzUmVnRXg7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLndob2xlV29yZEVuYWJsZWQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghdGhpcy53aG9sZVdvcmRFbmFibGVkKSB7CiAgICAgICAgICAgICAgICB0aGlzLmlzV2hvbGVXb3JkID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5vblNlbGVjdGlvbkNoYW5nZSA9IGZ1bmN0aW9uIChpc0Nhc2VTZW5zaXRpdmVWYWwsIGlzV2hvbGVXb3JkVmFsLCBpc1JlZ0V4VmFsKSB7CiAgICAgICAgdGhpcy5pc0RpcnR5ID0gdHJ1ZTsKICAgICAgICB0aGlzLnJlbGF0aXZlU3RhcnQgPSAtMTsKICAgICAgICB0aGlzLnJlbGF0aXZlRW5kID0gLTE7CiAgICAgICAgdGhpcy5tZXNzYWdlID0gIiI7CgogICAgICAgIGlmIChpc1dob2xlV29yZFZhbCAhPT0gdW5kZWZpbmVkICYmIGlzV2hvbGVXb3JkVmFsICE9IG51bGwpIHsKICAgICAgICAgICAgdGhpcy5pc1dob2xlV29yZCA9IGlzV2hvbGVXb3JkVmFsOwogICAgICAgIH0KICAgICAgICBpZiAoaXNSZWdFeFZhbCAhPT0gdW5kZWZpbmVkICYmIGlzUmVnRXhWYWwgIT0gbnVsbCAmJiB0aGlzLmlzUmVnRXggIT09IGlzUmVnRXhWYWwpIHsKICAgICAgICAgICAgdGhpcy5pc1JlZ0V4ID0gaXNSZWdFeFZhbDsKICAgICAgICAgICAgdGhpcy5zZXRXaG9sZVdvcmRFbmFibGVkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChpc0Nhc2VTZW5zaXRpdmVWYWwgIT09IHVuZGVmaW5lZCAmJiBpc0Nhc2VTZW5zaXRpdmVWYWwgIT0gbnVsbCkgewogICAgICAgICAgICB0aGlzLmlzQ2FzZVNlbnNpdGl2ZSA9IGlzQ2FzZVNlbnNpdGl2ZVZhbDsKICAgICAgICB9CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLmlzVmFsaWQgPSB0aGlzLmZpbmRUZXh0ID8gdHJ1ZSA6IGZhbHNlOwogICAgICAgIHRoaXMuaXNEaXJ0eSA9IHRydWU7CiAgICAgICAgdGhpcy5tZXNzYWdlID0gIiI7CiAgICAgICAgdGhpcy5yZWxhdGl2ZVN0YXJ0ID0gLTE7CiAgICAgICAgdGhpcy5yZWxhdGl2ZUVuZCA9IC0xOwogICAgfTsKCiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUuZXhlY3V0ZUZpbmQgPSBmdW5jdGlvbiAoZmluZFZhbCkgewogICAgICAgIHRoaXMuZmluZFRleHQgPSBmaW5kVmFsOwogICAgICAgIGlmICh0aGlzLmZpbmRUZXh0KSB7CiAgICAgICAgICAgIHRoaXMuZmluZFBvc2l0aW9uKHRoaXMuZmluZFRleHQpOwogICAgICAgICAgICB0aGlzLnNldFNlbGVjdGlvbkFuZEhpZ2hsaWdodChudWxsLCB0aGlzLnJlbGF0aXZlU3RhcnQsIHRoaXMucmVsYXRpdmVFbmQsIHRydWUpOwogICAgICAgIH0KICAgIH07CgogICAgRmluZEFuZFJlcGxhY2UucHJvdG90eXBlLmFkanVzdFNlYXJjaFBvc2l0aW9uQWZ0ZXJSZXBsYWNlID0gZnVuY3Rpb24gKG5ld1ZhbCkgewogICAgICAgIGlmICh0aGlzLnJlbGF0aXZlRW5kICE9IC0xIHx8IHRoaXMucmVsYXRpdmVTdGFydCAhPSAtMSkgewogICAgICAgICAgICB0aGlzLnJlbGF0aXZlRW5kID0gdGhpcy5yZWxhdGl2ZVN0YXJ0ICsgbmV3VmFsLmxlbmd0aDsKICAgICAgICB9CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5leGVjdXRlUmVwbGFjZSA9IGZ1bmN0aW9uIChmaW5kVmFsLCByZXBsYWNlVmFsKSB7CiAgICAgICAgdGhpcy5maW5kVGV4dCA9IGZpbmRWYWw7CiAgICAgICAgaWYgKGZpbmRWYWwpIHsKICAgICAgICAgICAgdGhpcy5yZXBsYWNlKGZpbmRWYWwsIHJlcGxhY2VWYWwpOwogICAgICAgICAgICB0aGlzLmV4ZWN1dGVGaW5kKGZpbmRWYWwpOwogICAgICAgIH0KICAgIH07CgogICAgRmluZEFuZFJlcGxhY2UucHJvdG90eXBlLmV4ZWN1dGVSZXBsYWNlQWxsID0gZnVuY3Rpb24gKGZpbmRWYWwsIHJlcGxhY2VWYWwpIHsKICAgICAgICB0aGlzLmZpbmRUZXh0ID0gZmluZFZhbDsKICAgICAgICBpZiAoZmluZFZhbCkgewogICAgICAgICAgICB0aGlzLnJlcGxhY2VBbGwoZmluZFZhbCwgcmVwbGFjZVZhbCk7CiAgICAgICAgfQogICAgfTsKCiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUuY3JlYXRlUmVnRXhwID0gZnVuY3Rpb24gKHNlYXJjaFRleHQpIHsKICAgICAgICBpZiAodGhpcy5pc0RpcnR5IHx8ICF0aGlzLnJlZ0V4cCkgewogICAgICAgICAgICBpZiAodGhpcy5pc1JlZ0V4ICYmIHRoaXMuaXNDYXNlU2Vuc2l0aXZlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnJlZ0V4cCA9IG5ldyBSZWdFeHAoc2VhcmNoVGV4dCwgImciKTsKICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmlzV2hvbGVXb3JkICYmIHRoaXMuaXNDYXNlU2Vuc2l0aXZlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnJlZ0V4cCA9IG5ldyBSZWdFeHAoIlxcYiIgKyBzZWFyY2hUZXh0ICsgIlxcYiIsICJnIik7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1dob2xlV29yZCkgewogICAgICAgICAgICAgICAgdGhpcy5yZWdFeHAgPSBuZXcgUmVnRXhwKCJcXGIiICsgc2VhcmNoVGV4dCArICJcXGIiLCAiaWciKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMucmVnRXhwID0gbmV3IFJlZ0V4cChzZWFyY2hUZXh0LCAiaWciKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLmlzRGlydHkgPSBmYWxzZTsKICAgICAgICB9CiAgICB9OwogICAgRmluZEFuZFJlcGxhY2UucHJvdG90eXBlLmZpbmRQb3NpdGlvbiA9IGZ1bmN0aW9uIChzZWFyY2gpIHsKICAgICAgICBpZiAodGhpcy5pc1JlZ0V4IHx8IHRoaXMuaXNXaG9sZVdvcmQpIHsKICAgICAgICAgICAgdGhpcy5maW5kUG9zaXRpb25XaXRoUmVnRXhwKHNlYXJjaCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhpcy5maW5kUG9zaXRpb25XaXRoSW5kZXhPZihzZWFyY2gpOwogICAgICAgIH0KICAgIH07CiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUuZmluZFBvc2l0aW9uV2l0aFJlZ0V4cCA9IGZ1bmN0aW9uIChzZWFyY2gpIHsKICAgICAgICBpZiAodGhpcy5pc0RpcnR5IHx8ICF0aGlzLnJlZ0V4cCkgewogICAgICAgICAgICB0aGlzLmNyZWF0ZVJlZ0V4cChzZWFyY2gpOwogICAgICAgIH0KICAgICAgICB2YXIgcmVzdWx0ID0gdGhpcy5yZWdFeHAuZXhlYyh0aGlzLnNvdXJjZSk7CiAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQuaGFzT3duUHJvcGVydHkoImluZGV4IikpIHsKICAgICAgICAgICAgdGhpcy5zZXRQb3NpdGlvbihyZXN1bHQuaW5kZXgsIHJlc3VsdC5pbmRleCArIHJlc3VsdFswXS5sZW5ndGgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRoaXMuc2V0UG9zaXRpb24oLTEsIC0xKTsKICAgICAgICB9CiAgICB9OwoKICAgIEZpbmRBbmRSZXBsYWNlLnByb3RvdHlwZS5maW5kUG9zaXRpb25XaXRoSW5kZXhPZiA9IGZ1bmN0aW9uIChzZWFyY2gpIHsKICAgICAgICB2YXIgbW9kaWZpZWRTb3VyY2UgPSB0aGlzLnNvdXJjZTsKICAgICAgICB2YXIgc3RhcnRGcm9tID0gMDsKICAgICAgICBpZiAodGhpcy5pc0RpcnR5KSB7CiAgICAgICAgICAgIHN0YXJ0RnJvbSA9IDA7CiAgICAgICAgICAgIHRoaXMuaXNEaXJ0eSA9IGZhbHNlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN0YXJ0RnJvbSA9IHRoaXMucmVsYXRpdmVFbmQ7CiAgICAgICAgfQogICAgICAgIGlmICghdGhpcy5pc0Nhc2VTZW5zaXRpdmUpIHsKICAgICAgICAgICAgbW9kaWZpZWRTb3VyY2UgPSB0aGlzLnNvdXJjZS50b0xvY2FsZUxvd2VyQ2FzZSgpOwogICAgICAgICAgICBzZWFyY2ggPSBzZWFyY2gudG9Mb2NhbGVMb3dlckNhc2UoKTsKICAgICAgICB9CiAgICAgICAgdmFyIHN0YXJ0ID0gbW9kaWZpZWRTb3VyY2UuaW5kZXhPZihzZWFyY2gsIHN0YXJ0RnJvbSk7CiAgICAgICAgdmFyIGVuZCA9IHN0YXJ0ICE9IC0xID8gc3RhcnQgKyBzZWFyY2gubGVuZ3RoIDogLTE7CiAgICAgICAgdGhpcy5zZXRQb3NpdGlvbihzdGFydCwgZW5kKTsKICAgIH07CiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUuc2V0UG9zaXRpb24gPSBmdW5jdGlvbiAoc3RhcnQsIGVuZCkgewogICAgICAgIGlmICgoc3RhcnQgPT0gLTEgfHwgZW5kID09IC0xKSAmJiB0aGlzLnJlbGF0aXZlRW5kID4gMCkgewogICAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSBucy5JMThuLmdldCgiUmVhY2hlZCBlbmQgb2YgbW9kdWxlLiIpOwogICAgICAgIH0gZWxzZSBpZiAoc3RhcnQgPT0gLTEgfHwgZW5kID09IC0xKSB7CiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9IG5zLkkxOG4uZ2V0KCJNYXRjaCBOb3QgRm91bmQiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSAiIjsKICAgICAgICB9CiAgICAgICAgdGhpcy5yZWxhdGl2ZVN0YXJ0ID0gc3RhcnQ7CiAgICAgICAgdGhpcy5yZWxhdGl2ZUVuZCA9IGVuZDsKICAgIH07CiAgICBGaW5kQW5kUmVwbGFjZS5wcm90b3R5cGUucmVwbGFjZSA9IGZ1bmN0aW9uIChzZWFyY2gsIHJlcGxhY2VXaXRoKSB7CiAgICAgICAgaWYgKHRoaXMucmVsYXRpdmVTdGFydCA9PSAtMSB8fCB0aGlzLnJlbGF0aXZlRW5kID09IC0xKSB7CiAgICAgICAgICAgIHRoaXMuZmluZFBvc2l0aW9uKHNlYXJjaCk7CiAgICAgICAgfQogICAgICAgIHRoaXMucmVwbGFjZVZhbHVlKHJlcGxhY2VXaXRoKTsKICAgIH07CgogICAgRmluZEFuZFJlcGxhY2UucHJvdG90eXBlLnJlcGxhY2VBbGwgPSBmdW5jdGlvbiAoc2VhcmNoLCByZXBsYWNlV2l0aCkgewogICAgICAgIHZhciByZXBsYWNlQ291bnQgPSAwOwogICAgICAgIHRoaXMucmVsYXRpdmVTdGFydCA9IHRoaXMucmVsYXRpdmVFbmQgPSAtMTsKICAgICAgICB0aGlzLmZpbmRQb3NpdGlvbihzZWFyY2gpOwogICAgICAgIHdoaWxlICh0aGlzLnJlbGF0aXZlU3RhcnQgIT0gLTEpIHsKICAgICAgICAgICAgcmVwbGFjZUNvdW50Kys7CiAgICAgICAgICAgIHRoaXMucmVwbGFjZVZhbHVlKHJlcGxhY2VXaXRoKTsKICAgICAgICAgICAgdGhpcy5maW5kUG9zaXRpb24oc2VhcmNoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXNzYWdlID0gcmVwbGFjZUNvdW50ID09IDAgPyBucy5JMThuLmdldCgiTWF0Y2ggTm90IEZvdW5kIikgOiBucy5JMThuLmdldCgiezB9IG1hdGNoZXMgcmVwbGFjZWQiLCBbcmVwbGFjZUNvdW50XSk7CiAgICB9OwogICAgRmluZEFuZFJlcGxhY2UucHJvdG90eXBlLnJlcGxhY2VWYWx1ZSA9IGZ1bmN0aW9uIChyZXBsYWNlV2l0aCkgewogICAgICAgIGlmICh0aGlzLnRleHRFZGl0b3IpIHsKICAgICAgICAgICAgdGhpcy5zZXRTZWxlY3Rpb25BbmRIaWdobGlnaHQobnVsbCwgdGhpcy5yZWxhdGl2ZVN0YXJ0LCB0aGlzLnJlbGF0aXZlRW5kLCBmYWxzZSk7CiAgICAgICAgICAgIHRoaXMudGV4dEVkaXRvci5leGVjdXRlQ29tbWFuZCgiaW5zZXJ0VGV4dCIsIHJlcGxhY2VXaXRoKTsKICAgICAgICAgICAgdGhpcy5hZGp1c3RTZWFyY2hQb3NpdGlvbkFmdGVyUmVwbGFjZShyZXBsYWNlV2l0aCk7CiAgICAgICAgfQogICAgfTsKCn0pKEZvcm0ucnRlKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKioKICogQ3JlYXRlZCBieSByYW1uYW5pIG9uIDcvMjcvMjAxNi4KICovCgooZnVuY3Rpb24gKCQsIG5zKSB7CiAgICAidXNlIHN0cmljdCI7CgogICAgSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcignSTE4bicsIGZ1bmN0aW9uIChvYmplY3QpIHsKICAgICAgICByZXR1cm4gbmV3IEhhbmRsZWJhcnMuU2FmZVN0cmluZyhucy5JMThuLmdldChvYmplY3QpKTsKICAgIH0pOwoKICAgIHZhciBjb21tYW5kcyA9IHsKICAgICAgICB1bmRvIDogewogICAgICAgICAgICB0aXRsZSA6ICdVbmRvJywKICAgICAgICAgICAgdGV4dCA6ICdVbmRvJywKICAgICAgICAgICAgaWNvbiA6ICdjY3cnCiAgICAgICAgfSwKICAgICAgICByZWRvIDogewogICAgICAgICAgICB0aXRsZSA6ICdSZWRvJywKICAgICAgICAgICAgdGV4dCA6ICdSZWRvJywKICAgICAgICAgICAgaWNvbiA6ICdjdycKICAgICAgICB9LAogICAgICAgIGJvbGQgOiB7CiAgICAgICAgICAgIHRpdGxlIDogJ0JvbGQnLAogICAgICAgICAgICBpY29uIDogJ2JvbGQnCiAgICAgICAgfSwKICAgICAgICBpdGFsaWMgOiB7CiAgICAgICAgICAgIHRpdGxlIDogJ0l0YWxpYycsCiAgICAgICAgICAgIGljb24gOiAnaXRhbGljJwogICAgICAgIH0sCiAgICAgICAgdW5kZXJsaW5lIDogewogICAgICAgICAgICB0aXRsZSA6ICdVbmRlcmxpbmUnLAogICAgICAgICAgICBpY29uIDogJ3VuZGVybGluZScsCiAgICAgICAgICAgICdjbGFzcycgOiAncnRlLWN1c3RvbS1pY29uJwogICAgICAgIH0sCiAgICAgICAgc3VwZXJzY3JpcHQgOiB7CiAgICAgICAgICAgIHRpdGxlIDogJ1N1cGVyLXNjcmlwdCcsCiAgICAgICAgICAgIGljb24gOiAnc3VwZXJzY3JpcHQnCiAgICAgICAgfSwKICAgICAgICBzdWJzY3JpcHQgOiB7CiAgICAgICAgICAgIHRpdGxlIDogJ1N1Yi1zY3JpcHQnLAogICAgICAgICAgICBpY29uIDogJ3N1YnNjcmlwdCcKICAgICAgICB9LAogICAgICAgIGZvcmVDb2xvciA6IHsKICAgICAgICAgICAgdGl0bGUgOiAnVGV4dCBDb2xvcicsCiAgICAgICAgICAgIHR5cGUgOiAnY29sb3JJbnB1dCcsCiAgICAgICAgICAgIGljb24gOiAndGV4dC1jb2xvcicKICAgICAgICB9LAogICAgICAgIGhpbGl0ZUNvbG9yIDogewogICAgICAgICAgICB0aXRsZSA6ICdIaWdobGlnaHQgQ29sb3InLAogICAgICAgICAgICB0eXBlIDogJ2NvbG9ySW5wdXQnCiAgICAgICAgfSwKICAgICAgICBmb250RmFtaWx5IDogewogICAgICAgICAgICB0eXBlIDogJ3NlbGVjdCcsCiAgICAgICAgICAgIHRpdGxlIDogJ0ZvbnQgRmFtaWx5JwogICAgICAgIH0sCiAgICAgICAgZm9udFNpemUgOiB7CiAgICAgICAgICAgIHR5cGUgOiAnc2VsZWN0JywKICAgICAgICAgICAgdGl0bGUgOiAnRm9udCBTaXplJwogICAgICAgIH0sCiAgICAgICAgbGluZUhlaWdodCA6IHsKICAgICAgICAgICAgdHlwZSA6ICdzZWxlY3QnLAogICAgICAgICAgICBjb21tYW5kIDogJ2NoYW5nZUxpbmVIZWlnaHQnLAogICAgICAgICAgICB0aXRsZSA6ICdMaW5lIEhlaWdodCcKICAgICAgICB9LAogICAgICAgIGxldHRlclNwYWNpbmcgOiB7CiAgICAgICAgICAgIHR5cGUgOiAnc2VsZWN0JywKICAgICAgICAgICAgdGl0bGUgOiAnTGV0dGVyIFNwYWNpbmcnCiAgICAgICAgfSwKICAgICAgICBoZWFkZXIgOiB7CiAgICAgICAgICAgIHR5cGUgOiAnc2VsZWN0JywKICAgICAgICAgICAgdGl0bGUgOiAnUGFyYWdyYXBoIEZvcm1hdCcKICAgICAgICB9LAogICAgICAgIGp1c3RpZnlMZWZ0IDogewogICAgICAgICAgICB0aXRsZSA6ICdKdXN0aWZ5IExlZnQnLAogICAgICAgICAgICBpY29uIDogJ2FsaWduLWxlZnQnCiAgICAgICAgfSwKICAgICAgICBqdXN0aWZ5Q2VudGVyIDogewogICAgICAgICAgICB0aXRsZSA6ICdKdXN0aWZ5IENlbnRlcicsCiAgICAgICAgICAgIGljb24gOiAnYWxpZ24tY2VudGVyJwogICAgICAgIH0sCiAgICAgICAganVzdGlmeUZ1bGwgOiB7CiAgICAgICAgICAgIHRpdGxlIDogJ0p1c3RpZnkgRnVsbCcsCiAgICAgICAgICAgIGljb24gOiAnYWxpZ24tanVzdGlmeScKICAgICAgICB9LAogICAgICAgIGp1c3RpZnlSaWdodCA6IHsKICAgICAgICAgICAgdGl0bGUgOiAnSnVzdGlmeSBSaWdodCcsCiAgICAgICAgICAgIGljb24gOiAnYWxpZ24tcmlnaHQnCiAgICAgICAgfSwKICAgICAgICBtYXJnaW5MZWZ0IDogewogICAgICAgICAgICB0eXBlIDogJ251bWJlcklucHV0JywKICAgICAgICAgICAgdGl0bGUgOiAnTWFyZ2luIExlZnQnCiAgICAgICAgfSwKICAgICAgICBtYXJnaW5SaWdodCA6IHsKICAgICAgICAgICAgdHlwZSA6ICdudW1iZXJJbnB1dCcsCiAgICAgICAgICAgIHRpdGxlIDogJ01hcmdpbiBSaWdodCcKICAgICAgICB9LAogICAgICAgIG1hcmdpblRvcCA6IHsKICAgICAgICAgICAgdHlwZSA6ICdudW1iZXJJbnB1dCcsCiAgICAgICAgICAgIHRpdGxlIDogJ01hcmdpbiBUb3AnCiAgICAgICAgfSwKICAgICAgICBtYXJnaW5Cb3R0b20gOiB7CiAgICAgICAgICAgIHR5cGUgOiAnbnVtYmVySW5wdXQnLAogICAgICAgICAgICB0aXRsZSA6ICdNYXJnaW4gQm90dG9tJwogICAgICAgIH0sCiAgICAgICAgaW5zZXJ0VW5vcmRlcmVkTGlzdCA6IHsKICAgICAgICAgICAgdGl0bGUgOiAnQnVsbGV0ZWQgTGlzdCcsCiAgICAgICAgICAgIGljb24gOiAibGlzdCIKICAgICAgICB9LAogICAgICAgIGluc2VydE9yZGVyZWRMaXN0IDogewogICAgICAgICAgICBjb21tYW5kIDogImluc2VydE9yZGVyZWRMaXN0IiwKICAgICAgICAgICAgdmFsdWUgOiAiT3JkZXJlZCIsCiAgICAgICAgICAgIHRpdGxlIDogIk51bWJlcmVkIExpc3QiLAogICAgICAgICAgICBpY29uIDogInRleHROdW1iZXJlZCIsCiAgICAgICAgICAgICdjbGFzcycgOiAicnRlLWN1c3RvbS1pY29uIgogICAgICAgIH0sCiAgICAgICAgaW5zZXJ0VXBwZXJjYXNlQWxwaGFiZXRMaXN0IDogewogICAgICAgICAgICBjb21tYW5kIDogImluc2VydE9yZGVyZWRMaXN0IiwKICAgICAgICAgICAgZWxlbWVudCA6ICJydGVfY2Fwc19hbHBoYV9saXN0X2NvbW1hbmQiLAogICAgICAgICAgICB2YWx1ZSA6ICJBIiwKICAgICAgICAgICAgdGl0bGUgOiAiVXBwZXItY2FzZSBBbHBoYWJldCBMaXN0IiwKICAgICAgICAgICAgaWNvbiA6ICJ0ZXh0TGV0dGVyZWRVcHBlcmNhc2UiLAogICAgICAgICAgICAnY2xhc3MnIDogInJ0ZS1jdXN0b20taWNvbiIKICAgICAgICB9LAogICAgICAgIGluc2VydExvd2VyY2FzZUFscGhhYmV0TGlzdCA6IHsKICAgICAgICAgICAgY29tbWFuZCA6ICJpbnNlcnRPcmRlcmVkTGlzdCIsCiAgICAgICAgICAgIGVsZW1lbnQgOiAicnRlX2FscGhhX2xpc3RfY29tbWFuZCIsCiAgICAgICAgICAgIHZhbHVlIDogImEiLAogICAgICAgICAgICB0aXRsZSA6ICJMb3dlci1jYXNlIEFscGhhYmV0IExpc3QiLAogICAgICAgICAgICBpY29uIDogInRleHRMZXR0ZXJlZExvd2VyY2FzZSIsCiAgICAgICAgICAgICdjbGFzcycgOiAicnRlLWN1c3RvbS1pY29uIgogICAgICAgIH0sCiAgICAgICAgaW5zZXJ0VXBwZXJjYXNlUm9tYW5MaXN0IDogewogICAgICAgICAgICBjb21tYW5kIDogImluc2VydE9yZGVyZWRMaXN0IiwKICAgICAgICAgICAgZWxlbWVudCA6ICJydGVfY2Fwc19yb21hbl9saXN0X2NvbW1hbmQiLAogICAgICAgICAgICB2YWx1ZSA6ICJJIiwKICAgICAgICAgICAgdGl0bGUgOiAiVXBwZXItY2FzZSBSb21hbiBMaXN0IiwKICAgICAgICAgICAgaWNvbiA6ICJ0ZXh0Um9tYW5VcHBlcmNhc2UiLAogICAgICAgICAgICAnY2xhc3MnIDogInJ0ZS1jdXN0b20taWNvbiIKICAgICAgICB9LAogICAgICAgIGluc2VydExvd2VyY2FzZVJvbWFuTGlzdCA6IHsKICAgICAgICAgICAgY29tbWFuZCA6ICJpbnNlcnRPcmRlcmVkTGlzdCIsCiAgICAgICAgICAgIGVsZW1lbnQgOiAicnRlX3JvbWFuX2xpc3RfY29tbWFuZCIsCiAgICAgICAgICAgIHZhbHVlIDogImkiLAogICAgICAgICAgICB0aXRsZSA6ICJMb3dlci1jYXNlIFJvbWFuIExpc3QiLAogICAgICAgICAgICBpY29uIDogInRleHRSb21hbkxvd2VyY2FzZSIsCiAgICAgICAgICAgICdjbGFzcycgOiAicnRlLWN1c3RvbS1pY29uIgogICAgICAgIH0sCiAgICAgICAgaW5kZW50IDogewogICAgICAgICAgICB0aXRsZSA6ICdJbmRlbnQnLAogICAgICAgICAgICBpY29uIDogImluZGVudC1sZWZ0IgogICAgICAgIH0sCiAgICAgICAgb3V0ZGVudCA6IHsKICAgICAgICAgICAgdGl0bGUgOiAnT3V0ZGVudCcsCiAgICAgICAgICAgIGljb24gOiAiaW5kZW50LXJpZ2h0IgogICAgICAgIH0sCiAgICAgICAgZmluZEFuZFJlcGxhY2UgOiB7CiAgICAgICAgICAgIHRleHQgOiAiRmluZCAmIFJlcGxhY2UiLAogICAgICAgICAgICBpY29uIDogJ3NlYXJjaCcsCiAgICAgICAgICAgIHR5cGUgOiAncG9wb3ZlcicsCiAgICAgICAgICAgIGNvbnRlbnQgOiBIYW5kbGViYXJzLnRlbXBsYXRlcy5maW5kQW5kUmVwbGFjZSgpLAogICAgICAgICAgICBjYWxsYmFjayA6ICJGb3JtLnJ0ZS5Db21tYW5kU3RhdGVDYWxsYmFja3Muc2V0RmluZEFuZFJlcGxhY2VNZXNzYWdlIiwKICAgICAgICAgICAgcGxhY2VtZW50IDogJ2JvdHRvbScKICAgICAgICB9LAogICAgICAgIGxpbmsgOiB7CiAgICAgICAgICAgIHRpdGxlIDogIkluc2VydCBMaW5rIiwKICAgICAgICAgICAgaWNvbiA6ICdsaW5rJywKICAgICAgICAgICAgdHlwZSA6ICdwb3BvdmVyJywKICAgICAgICAgICAgY29udGVudCA6IEhhbmRsZWJhcnMudGVtcGxhdGVzLmxpbmsoKSwKICAgICAgICAgICAgcGxhY2VtZW50IDogJ2JvdHRvbScKICAgICAgICB9CiAgICB9OwoKICAgIG5zLlRvb2xiYXIgPSBmdW5jdGlvbiAob3B0aW9ucywgY29uZmlnKSB7CiAgICAgICAgdGhpcy50b29sYmFycyA9IChvcHRpb25zICYmIG9wdGlvbnMudG9vbGJhcnMpIHx8IG5zLlRvb2xiYXJDb25maWcudG9vbGJhcnM7CiAgICAgICAgdGhpcy5tb2RlcyA9IHt9OwogICAgICAgIHRoaXMubW9kZSA9IChvcHRpb25zICYmIG9wdGlvbnMuZGVmYXVsdE1vZGUpIHx8IG5zLlRvb2xiYXJDb25maWcuZGVmYXVsdE1vZGU7CiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7CiAgICB9OwoKICAgIC8qKgogICAgICogUmVuZGVycyB0aGUgdG9vbGJhciBzcGVjaWZpYyB0byBjdXJyZW50IG1vZGUKICAgICAqIEByZXR1cm5zIHsqfQogICAgICovCiAgICBucy5Ub29sYmFyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIG1vZGUgPSB0aGlzLm1vZGU7CiAgICAgICAgdmFyIGNvbmZpZyA9IHRoaXMuY29uZmlnOwogICAgICAgIGlmICghdGhpcy5tb2Rlcy5oYXNPd25Qcm9wZXJ0eShtb2RlKSkgewogICAgICAgICAgICB2YXIgdG9vbGJhckhUTUwgPSAiIjsKICAgICAgICAgICAgdmFyIG1vZGVDb25maWcgPSB0aGlzLnRvb2xiYXJzW21vZGVdOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdmFyIGxheW91dCA9IG1vZGVDb25maWcubGF5b3V0OwogICAgICAgICAgICAgICAgaWYgKGxheW91dCBpbnN0YW5jZW9mIEFycmF5KSB7CiAgICAgICAgICAgICAgICAgICAgbGF5b3V0LmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgdG9vbGJhckhUTUwgKz0gcmVuZGVyQ29tbWFuZHMoaXRlbSwgY29uZmlnKTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMubW9kZXNbbW9kZV0gPSAgJChIYW5kbGViYXJzLnRlbXBsYXRlcy5ydGV0b29sYmFyKHRvb2xiYXJIVE1MKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoIkVycm9yIGluIGNvbnN0cnVjdGluZyBUb29sYmFyIDogIiArIGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzLm1vZGVzW21vZGVdOwogICAgfTsKCiAgICAvKioKICAgICAqIFNldCBjdXJyZW50IG1vZGUgb2YgdGhlIFRvb2xiYXIKICAgICAqIEBwYXJhbSBtb2RlCiAgICAgKi8KICAgIG5zLlRvb2xiYXIucHJvdG90eXBlLnNldE1vZGUgPSBmdW5jdGlvbiAobW9kZSkgewogICAgICAgIHRoaXMubW9kZSA9IG1vZGU7CiAgICAgICAgcmV0dXJuIHRoaXMucmVuZGVyKCk7CiAgICB9OwoKICAgIC8qKgogICAgICogUmV0dXJucyBjdXJyZW50IG1vZGUgb2YgdGhlIFRvb2xiYXIKICAgICAqIEByZXR1cm5zIEN1cnJlbnQgbW9kZQogICAgICovCiAgICBucy5Ub29sYmFyLnByb3RvdHlwZS5nZXRNb2RlID0gZnVuY3Rpb24gKCkgewogICAgICAgIHJldHVybiB0aGlzLm1vZGU7CiAgICB9OwoKICAgIG5zLlRvb2xiYXIucHJvdG90eXBlLl90b2dnbGVGbG9hdGluZ1Rvb2xiYXIgPSBmdW5jdGlvbiAocnRlLCB0b29sYmFyLCBlLCBzaG93KSB7CiAgICAgICAgdmFyIGVkaXRvciA9IHJ0ZS4kZWxlbWVudC5maW5kKCIud3lzaWh0bWw1LWVkaXRvciIpWzBdLAogICAgICAgICAgICBlZGl0b3JGb2N1c2VkID0gc2hvdyB8fCBlZGl0b3IuY29udGFpbnMoZS50YXJnZXQpIHx8IGVkaXRvciA9PSBlLnRhcmdldCwKICAgICAgICAgICAgdG9vbGJhckZvY3VzZWQgPSBlICYmIHRvb2xiYXIuaGFzKGUudGFyZ2V0KTsKICAgICAgICBpZiAoZWRpdG9yRm9jdXNlZCkgewogICAgICAgICAgICB0b29sYmFyLnNob3coKTsKICAgICAgICAgICAgdmFyIG9mZnNldCA9ICQoZWRpdG9yKS5vZmZzZXQoKTsKICAgICAgICAgICAgdG9vbGJhci5vZmZzZXQoewogICAgICAgICAgICAgICAgdG9wIDogb2Zmc2V0LnRvcCAtIHRvb2xiYXIuaGVpZ2h0KCkgLSA0LAogICAgICAgICAgICAgICAgbGVmdCA6IG9mZnNldC5sZWZ0CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSBpZiAoIXRvb2xiYXJGb2N1c2VkIHx8IHRvb2xiYXJGb2N1c2VkLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIHRvb2xiYXIuaGlkZSgpOwogICAgICAgIH0KICAgIH07CgogICAgbnMuVG9vbGJhci5wcm90b3R5cGUuaW5pdGlhbGl6ZVRvb2xiYXJFdmVudHMgPSBmdW5jdGlvbiAocnRlKSB7CiAgICAgICAgdmFyIG1vZGUgPSB0aGlzLm1vZGU7CiAgICAgICAgaWYgKHRoaXMubW9kZXMuaGFzT3duUHJvcGVydHkobW9kZSkpIHsKICAgICAgICAgICAgdmFyIHRvb2xiYXIgPSB0aGlzLm1vZGVzW21vZGVdOwogICAgICAgICAgICBpZiAodGhpcy50b29sYmFycyAmJiB0aGlzLnRvb2xiYXJzW21vZGVdICYmIHRoaXMudG9vbGJhcnNbbW9kZV0uZmxvYXRpbmcgJiYgIXRoaXMudG9nZ2xlVG9vbGJhcikgewogICAgICAgICAgICAgICAgLyogQWRkIGZvY3VzIGhhbmRsZXIgdG8gZWRpdG9yIGlmIHRoZSB0b29sYmFyIGlzIG9mIGZsb2F0aW5nIG5hdHVyZSAqLwogICAgICAgICAgICAgICAgdGhpcy50b2dnbGVUb29sYmFyID0gJC5wcm94eSh0aGlzLl90b2dnbGVGbG9hdGluZ1Rvb2xiYXIsIHRoaXMsIHJ0ZSwgdG9vbGJhcik7CiAgICAgICAgICAgICAgICAkKGRvY3VtZW50KS5vbigibW91c2V1cCIsIHRoaXMudG9nZ2xlVG9vbGJhcik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzOwogICAgICAgICAgICAvKiBMaXN0ZW4gZm9yIG1vZGUgY2hhbmdlIG9uIHRvb2xiYXIgKi8KICAgICAgICAgICAgaWYgKHRvb2xiYXIuaGFzQ2xhc3MoImluaXRpYWxpemVkIikpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICB0b29sYmFyLmZpbmQoIltkYXRhLXd5c2lodG1sNS1jb21tYW5kPSdtb2RlJ10iKS5vbigiY2xpY2siLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgbW9kZSA9IHRoaXMuZ2V0QXR0cmlidXRlKCJkYXRhLXd5c2lodG1sNS1jb21tYW5kLXZhbHVlIik7CiAgICAgICAgICAgICAgICAkKHNlbGYpLnRyaWdnZXIoIm1vZGVDaGFuZ2VkIiwgbW9kZSk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICB2YXIgY29sb3JzID0gcnRlLmVkaXRvckNvbmZpZyA/IHJ0ZS5lZGl0b3JDb25maWcuY29sb3IgOiB7fTsKICAgICAgICAgICAgdG9vbGJhci5maW5kKCIucnRlLWNvbG9ySW5wdXQtY29udHJvbDpub3QoLnBpY2stYS1jb2xvcikiKS5waWNrQUNvbG9yKHsKICAgICAgICAgICAgICAgIHRvdWNoT25seU1vZGUgOiBmYWxzZSwgLy8gZm9yIHRvdWNoLW9ubHkgZGV2aWNlcyBbdGFibGV0LCBzbWFydHBob25lLCBldGMuXQogICAgICAgICAgICAgICAgc2hvd1NwZWN0cnVtIDogdHJ1ZSwKICAgICAgICAgICAgICAgIHNob3dTYXZlZENvbG9ycyA6IGZhbHNlLAogICAgICAgICAgICAgICAgc2F2ZUNvbG9yc1BlckVsZW1lbnQgOiBmYWxzZSwKICAgICAgICAgICAgICAgIGZhZGVNZW51VG9nZ2xlIDogdHJ1ZSwKICAgICAgICAgICAgICAgIHNob3dBZHZhbmNlZCA6IHRydWUsCiAgICAgICAgICAgICAgICBzaG93QmFzaWNDb2xvcnMgOiB0cnVlLAogICAgICAgICAgICAgICAgc2hvd0hleElucHV0IDogZmFsc2UsCiAgICAgICAgICAgICAgICBiYXNpY0NvbG9ycyA6IGNvbG9ycwogICAgICAgICAgICB9KS5vbignY2hhbmdlJywgZnVuY3Rpb24gKGUpIHsKICAgICAgICAgICAgICAgIHJ0ZS5leGVjdXRlQ29tbWFuZChlLnRhcmdldC5nZXRBdHRyaWJ1dGUoImRhdGEtd3lzaWh0bWw1LWNvbW1hbmQiKSwgIiMiICsgZS50YXJnZXQudmFsdWUpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIGZvciAodmFyIGNvbG9yIGluIGNvbG9ycykgewogICAgICAgICAgICAgICAgaWYgKGNvbG9ycy5oYXNPd25Qcm9wZXJ0eShjb2xvcikpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0b3IgPSB0b29sYmFyLmZpbmQoIi5waWNrLWEtY29sb3ItbWFya3VwIC5zcGVjdHJ1bS0iICsgY29sb3IpOwogICAgICAgICAgICAgICAgICAgIG5zLnV0aWwuUlRFVXRpbHMuYWRkU3BlY3RydW1HcmFkaWVudChzZWxlY3RvciwgY29sb3JzW2NvbG9yXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdG9vbGJhci5vbigiY2xpY2siLCAiLnJ0ZS1wb3BvdmVyID4gYnV0dG9uIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHBvcG92ZXIgPSAkKHRoaXMpLnNpYmxpbmdzKCIucG9wb3ZlciIpOwogICAgICAgICAgICAgICAgdmFyIG9mZnNldCA9ICQodGhpcykub2Zmc2V0KCk7CiAgICAgICAgICAgICAgICBvZmZzZXQudG9wICs9IHRoaXMuY2xpZW50SGVpZ2h0OwogICAgICAgICAgICAgICAgcG9wb3Zlci50b2dnbGUoKTsKICAgICAgICAgICAgICAgIHBvcG92ZXIub2Zmc2V0KG9mZnNldCk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICB0b29sYmFyLm9uKCJjbGljayIsICIucnRlLXBvcG92ZXIgPiAucnRlX2xpbmtfY29tbWFuZCIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBwb3BvdmVyID0gJCh0aGlzKS5zaWJsaW5ncygiLnBvcG92ZXIiKTsKICAgICAgICAgICAgICAgIGlmIChwb3BvdmVyKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHQgPSBydGUuY29tcG9zZXIgJiYgcnRlLmNvbXBvc2VyLnNlbGVjdGlvbiA/IHJ0ZS5jb21wb3Nlci5zZWxlY3Rpb24uZ2V0VGV4dCgpIDogIiI7CiAgICAgICAgICAgICAgICAgICAgcG9wb3Zlci5maW5kKCJpbnB1dFtuYW1lPSdhbHQnXSIpLnZhbCh0ZXh0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CgogICAgICAgICAgICB0b29sYmFyLm9uKCJjbGljayIsICIucnRlLXBvcG92ZXIgLnBvcG92ZXIgW3J0ZS1jbG9zZV0iLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgcG9wb3ZlciA9ICQodGhpcykuY2xvc2VzdCgiLnBvcG92ZXIiKTsKICAgICAgICAgICAgICAgIHBvcG92ZXIuaGlkZSgpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIHRoaXMuX3RvZ2dsZUZsb2F0aW5nVG9vbGJhcihydGUsIHRvb2xiYXIsIG51bGwsIHRydWUpOwogICAgICAgICAgICB0b29sYmFyLmFkZENsYXNzKCJpbml0aWFsaXplZCIpOwogICAgICAgIH0KICAgIH07CgogICAgdmFyIHJlbmRlckNvbW1hbmRzID0gZnVuY3Rpb24gKGNvbW1hbmRPYmosIGNvbmZpZykgewogICAgICAgIHZhciBodG1sID0gIiI7CiAgICAgICAgdmFyIGl0ZW1Db25maWc7CiAgICAgICAgaWYgKHR5cGVvZiBjb21tYW5kT2JqID09ICJzdHJpbmciKSB7CiAgICAgICAgICAgIC8qIEZldGNoIGNvbmZpZ3VyYXRpb24gZnJvbSBPT1RCIGNvbW1hbmQgaWYgcHJlc2VudCAqLwogICAgICAgICAgICBpZiAoY29tbWFuZHMgJiYgY29tbWFuZHMuaGFzT3duUHJvcGVydHkoY29tbWFuZE9iaikpIHsKICAgICAgICAgICAgICAgIGl0ZW1Db25maWcgPSBjb21tYW5kc1tjb21tYW5kT2JqXTsKICAgICAgICAgICAgICAgIGl0ZW1Db25maWcuY29tbWFuZCA9IGl0ZW1Db25maWcuY29tbWFuZCB8fCBjb21tYW5kT2JqOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgY29tbWFuZE9iaiA9PSAib2JqZWN0IikgewogICAgICAgICAgICAvKiBGZXRjaCBjb25maWd1cmF0aW9uIGZyb20gT09UQiBjb21tYW5kIGlmIHByZXNlbnQgKi8KICAgICAgICAgICAgaXRlbUNvbmZpZyA9ICQuZXh0ZW5kKGNvbW1hbmRzW2NvbW1hbmRPYmouY29tbWFuZF0sIGNvbW1hbmRPYmopOwogICAgICAgIH0KICAgICAgICBpZiAoaXRlbUNvbmZpZykgewogICAgICAgICAgICBpZiAoY29uZmlnICYmIGNvbmZpZy5oYXNPd25Qcm9wZXJ0eShjb21tYW5kT2JqKSkgewogICAgICAgICAgICAgICAgaXRlbUNvbmZpZyA9ICQuZXh0ZW5kKGl0ZW1Db25maWcsIGNvbmZpZ1tjb21tYW5kT2JqXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGl0ZW1Db25maWcuaXRlbXMpIHsKICAgICAgICAgICAgICAgIGl0ZW1Db25maWcudHlwZSA9IGl0ZW1Db25maWcudHlwZSB8fCAgImdyb3VwIjsKICAgICAgICAgICAgICAgIGl0ZW1Db25maWcuY29udGVudCA9ICIiOwogICAgICAgICAgICAgICAgaXRlbUNvbmZpZy5pdGVtcy5mb3JFYWNoKGZ1bmN0aW9uIChpKSB7CiAgICAgICAgICAgICAgICAgICAgaXRlbUNvbmZpZy5jb250ZW50ICs9IHJlbmRlckNvbW1hbmRzKGksIGNvbmZpZyk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiB0ZW1wbGF0ZVR5cGUgZGVmYXVsdHMgdG8gZ3JvdXAgaWYgaXQgY29udGFpbnMgYW55IGl0ZW1zIGVsc2UgZGVmYXVsdHMgdG8gYnV0dG9uKi8KICAgICAgICAgICAgaXRlbUNvbmZpZy50eXBlID0gaXRlbUNvbmZpZy50eXBlIHx8ICJidXR0b24iOwogICAgICAgICAgICBpdGVtQ29uZmlnLmVsZW1lbnQgPSBpdGVtQ29uZmlnLmVsZW1lbnQgfHwgInJ0ZV8iICsgaXRlbUNvbmZpZy5jb21tYW5kICsgIl9jb21tYW5kIjsKICAgICAgICAgICAgaWYgKEhhbmRsZWJhcnMudGVtcGxhdGVzLmhhc093blByb3BlcnR5KGl0ZW1Db25maWcudHlwZSkpIHsKICAgICAgICAgICAgICAgIGh0bWwgKz0gSGFuZGxlYmFycy50ZW1wbGF0ZXNbaXRlbUNvbmZpZy50eXBlXShpdGVtQ29uZmlnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoIlVuYWJsZSB0byByZXRyaWV2ZSB0ZW1wbGF0ZSBmb3IgIiArIGl0ZW1Db25maWcudHlwZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGh0bWw7CiAgICB9Owp9KSgkLCBGb3JtLnJ0ZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxNi4gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqCiAqIENyZWF0ZWQgYnkgcmFtbmFuaSBvbiA3LzI3LzIwMTYuCiAqLwoKKGZ1bmN0aW9uIChkb2N1bWVudCwgbnMpIHsKCiAgICB2YXIgY2FsbGJhY2tGdW5jdGlvbnMgPSBucy5Db21tYW5kU3RhdGVDYWxsYmFja3MgPSB7fTsKCiAgICAvKioKICAgICAqIENhbGxiYWNrIHRvIHNldCBCdXR0b24gc3RhdGUgY29ycmVzcG9uZGluZyB0byBjb21tYW5kCiAgICAgKiBAcGFyYW0gZG9tRWxlbSBlbGVtZW50IHRvIHNldCBzdGF0ZSBvbgogICAgICogQHBhcmFtIHN0YXRlIHdoZXRoZXIgY29tbWFuZCBleGVjdXRlZCBvciBub3QKICAgICAqLwogICAgY2FsbGJhY2tGdW5jdGlvbnMuc2V0QnV0dG9uU3RhdGUgPSBmdW5jdGlvbiAoZG9tRWxlbWVudCwgc3RhdGUpIHsKICAgICAgICBzdGF0ZSA9ICEoc3RhdGUgPT0gdW5kZWZpbmVkIHx8IHN0YXRlID09IGZhbHNlKTsKICAgICAgICBpZiAoZG9tRWxlbWVudCkgewogICAgICAgICAgICBpZiAoc3RhdGUpIHsKICAgICAgICAgICAgICAgIGRvbUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgiYWN0aXZlIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBkb21FbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoImFjdGl2ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKCiAgICAvKioKICAgICAqIENhbGxiYWNrIHRvIHNldCBEcm9wZG93biBzdGF0ZSBjb3JyZXNwb25kaW5nIHRvIGNvbW1hbmQKICAgICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSBvZiB0aGUgZHJvcGRvd24gdG8gc2V0CiAgICAgKiBAcGFyYW0gZG9tRWxlbWVudCBlbGVtZW50IHRvIHNldCBzdGF0ZSBvbgogICAgICovCiAgICBjYWxsYmFja0Z1bmN0aW9ucy5zZXRTZWxlY3RTdGF0ZSA9IGZ1bmN0aW9uIChkb21FbGVtZW50LCB2YWx1ZSkgewogICAgICAgIGlmIChkb21FbGVtZW50KSB7CiAgICAgICAgICAgIHZhciBvcHRpb25zID0gZG9tRWxlbWVudC5vcHRpb25zLAogICAgICAgICAgICAgICAgaXNPcHRpb25QcmVzZW50ID0gZmFsc2U7CiAgICAgICAgICAgIGlmIChvcHRpb25zKSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9wdGlvbnMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9uc1tpXS52YWx1ZSA9PSB2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBpc09wdGlvblByZXNlbnQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCFpc09wdGlvblByZXNlbnQpIHsKICAgICAgICAgICAgICAgIHZhbHVlID0gIiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZG9tRWxlbWVudC52YWx1ZSA9IHZhbHVlOwogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBDYWxsYmFjayB0byBzZXQgTnVtYmVyIElucHV0IHN0YXRlIGNvcnJlc3BvbmRpbmcgdG8gY29tbWFuZAogICAgICogQHBhcmFtIHZhbHVlIHZhbHVlIHRvIHNldAogICAgICogQHBhcmFtIG51bWJlcklucHV0IGVsZW1lbnQgdG8gc2V0IHZhbHVlIHRvCiAgICAgKi8KICAgIGNhbGxiYWNrRnVuY3Rpb25zLnNldE51bWJlcklucHV0VmFsdWUgPSBmdW5jdGlvbiAobnVtYmVySW5wdXQsIHZhbHVlKSB7CiAgICAgICAgaWYgKG51bWJlcklucHV0KSB7CiAgICAgICAgICAgIG51bWJlcklucHV0LnZhbHVlID0gdmFsdWU7CiAgICAgICAgfQogICAgfTsKCiAgICAvKioKICAgICAqIENhbGxiYWNrIHRvIHNldCBGaW5kICYgUmVwbGFjZSBtZXNzYWdlCiAgICAgKiBAcGFyYW0gbWVzc2FnZSBtZXNzYWdlIHRvIHNldAogICAgICogQHBhcmFtIGZpbmRSZXBsYWNlQnV0dG9uCiAgICAgKi8KICAgIGNhbGxiYWNrRnVuY3Rpb25zLnNldEZpbmRBbmRSZXBsYWNlTWVzc2FnZSA9IGZ1bmN0aW9uIChmaW5kUmVwbGFjZUJ1dHRvbiwgbWVzc2FnZSkgewogICAgICAgIHZhciBwb3BvdmVyID0gJChmaW5kUmVwbGFjZUJ1dHRvbikuc2libGluZ3MoIi5wb3BvdmVyIilbMF07CiAgICAgICAgaWYgKHBvcG92ZXIpIHsKICAgICAgICAgICAgdmFyIG1lc3NhZ2VFbCA9IHBvcG92ZXIucXVlcnlTZWxlY3RvcigiLnJ0ZV9maW5kTlJlcGxhY2VfbWVzc2FnZSIpOwogICAgICAgICAgICB2YXIgYWxlcnQgPSBwb3BvdmVyLnF1ZXJ5U2VsZWN0b3IoIi5ydGVfZmluZE5SZXBsYWNlX2FsZXJ0Iik7CiAgICAgICAgICAgIGlmIChtZXNzYWdlRWwgJiYgYWxlcnQpIHsKICAgICAgICAgICAgICAgIG1lc3NhZ2VFbC5pbm5lckhUTUwgPSBtZXNzYWdlOwogICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UgJiYgbWVzc2FnZS50cmltKCkgIT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICAkKGFsZXJ0KS5zaG93KCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICQoYWxlcnQpLmhpZGUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgY2FsbGJhY2tGdW5jdGlvbnMuc2V0Q29sb3JJbnB1dFZhbHVlID0gZnVuY3Rpb24gKGRvbUVsZW1lbnQsIHN0YXRlLCBkb21FbGVtZW50TmFtZSwgY21kKSB7CiAgICAgICAgaWYgKGRvbUVsZW1lbnQpIHsKICAgICAgICAgICAgdmFyIGNvbG9yID0gInJnYigwLCAwLCAwKSI7CiAgICAgICAgICAgIGlmIChzdGF0ZSAmJiBzdGF0ZS5zdHlsZSkgewogICAgICAgICAgICAgICAgaWYgKGNtZCA9PSBGb3JtLnJ0ZS5Db21tYW5kcy5GT1JFX0NPTE9SKSB7CiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBzdGF0ZS5zdHlsZS5jb2xvcjsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY21kID09IEZvcm0ucnRlLkNvbW1hbmRzLkhJTElURV9DT0xPUikgewogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gc3RhdGUuc3R5bGUuYmFja2dyb3VuZENvbG9yOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICQoZG9tRWxlbWVudCkuY2xvc2VzdCgiLnBpY2stYS1jb2xvci1tYXJrdXAiKS5maW5kKCIuY3VycmVudC1jb2xvciIpLmNzcygiYmFja2dyb3VuZC1jb2xvciIsIGNvbG9yKTsKICAgICAgICB9CiAgICB9Owp9KShkb2N1bWVudCwgRm9ybS5ydGUpOwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDE2LiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKKGZ1bmN0aW9uIChkb2N1bWVudCwgbnMpIHsKICAgICJ1c2Ugc3RyaWN0IjsKCiAgICB2YXIgU2hvcnRjdXRLZXlzQ3RybCA9IG5zLlNob3J0Y3V0S2V5c0N0cmwgPSB7fTsKCiAgICB2YXIgZ2V0Rm9udFNpemUgPSBmdW5jdGlvbiAobmV4dCwgY29tcG9zZXIsIGZvbnRTaXplTGlzdCkgewogICAgICAgIHZhciBmb250U2l6ZSA9IGNvbXBvc2VyLmNvbW1hbmRzLmNhbGxiYWNrU3RhdGUoImZvbnRTaXplIik7CiAgICAgICAgaWYgKHR5cGVvZiBmb250U2l6ZSA9PT0gInN0cmluZyIpIHsKICAgICAgICAgICAgZm9udFNpemUgPSBwYXJzZUZsb2F0KGZvbnRTaXplKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZvbnRTaXplTGlzdCAmJiBmb250U2l6ZUxpc3QubGVuZ3RoID4gMCkgewogICAgICAgICAgICB2YXIgZm9udEluZGV4ID0gLTEsCiAgICAgICAgICAgICAgICBpID0gMCwKICAgICAgICAgICAgICAgIHZhbHVlID0gcGFyc2VGbG9hdChmb250U2l6ZUxpc3RbaV0pOwogICAgICAgICAgICB3aGlsZSAoaSA8IGZvbnRTaXplTGlzdC5sZW5ndGggJiYgdmFsdWUgPCBmb250U2l6ZSkgewogICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZUZsb2F0KGZvbnRTaXplTGlzdFsrK2ldKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodmFsdWUgPT0gZm9udFNpemUpIHsKICAgICAgICAgICAgICAgIGZvbnRJbmRleCA9IG5leHQgPyBpICsgMSA6IGkgLSAxOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZm9udEluZGV4ID0gbmV4dCA/IGkgOiBpIC0gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZm9udEluZGV4ID4gLTEgJiYgZm9udEluZGV4IDwgZm9udFNpemVMaXN0Lmxlbmd0aCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZvbnRTaXplTGlzdFtmb250SW5kZXhdOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfTsKCiAgICBTaG9ydGN1dEtleXNDdHJsLm9ua2V5ZG93biA9IGZ1bmN0aW9uIChldmVudCwgY29tcG9zZXIsIGNvbmZpZykgewogICAgICAgIHZhciBpc0N0cmwgPSBldmVudC5jdHJsS2V5LAogICAgICAgICAgICBpc0FsdCA9IGV2ZW50LmFsdEtleSwKICAgICAgICAgICAgaXNTaGlmdCA9IGV2ZW50LnNoaWZ0S2V5LAogICAgICAgICAgICB3aGljaCA9IGV2ZW50LndoaWNoOwogICAgICAgIGlmIChpc0N0cmwgJiYgaXNTaGlmdCkgewogICAgICAgICAgICB2YXIgZm9udFNpemUgPSBudWxsLAogICAgICAgICAgICAgICAgZm9udFNpemVPcHRpb25zID0gY29uZmlnLmZvbnRTaXplID8gY29uZmlnLmZvbnRTaXplLm9wdGlvbnMgOiBbXTsKICAgICAgICAgICAgaWYgKHdoaWNoID09IG5zLktleWJvYXJkLktFWUNPREVfR1JFQVRFUl9USEFOKSB7Ly8gQ3RybCArIFNoaWZ0ICsgPiB0byBJbmNyZWFzZSBmb250IHNpemUKICAgICAgICAgICAgICAgIGZvbnRTaXplID0gZ2V0Rm9udFNpemUodHJ1ZSwgY29tcG9zZXIsIGZvbnRTaXplT3B0aW9ucyk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAod2hpY2ggPT0gbnMuS2V5Ym9hcmQuS0VZQ09ERV9MRVNTX1RIQU4pIHsvLyBDdHJsICsgU2hpZnQgKyA8IHRvIERlY3JlYXNlIGZvbnQgc2l6ZQogICAgICAgICAgICAgICAgZm9udFNpemUgPSBnZXRGb250U2l6ZShmYWxzZSwgY29tcG9zZXIsIGZvbnRTaXplT3B0aW9ucyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGZvbnRTaXplKSB7CiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgY29tcG9zZXIuY29tbWFuZHMuZXhlYygiZm9udFNpemUiLCBmb250U2l6ZSwgZmFsc2UpOwogICAgICAgICAgICB9CiAgICAgICAgfSBpZiAoaXNDdHJsKSB7CiAgICAgICAgICAgIHZhciBjb21tYW5kID0gIiI7CiAgICAgICAgICAgIGlmIChpc0FsdCkgewogICAgICAgICAgICAgICAgaWYgKHdoaWNoID09IG5zLktleWJvYXJkLktFWUNPREVfQikgey8vIEN0cmwgKyBBbHQgKyBCIGZvciBCb2xkCiAgICAgICAgICAgICAgICAgICAgY29tbWFuZCA9ICJib2xkIjsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAod2hpY2ggPT0gbnMuS2V5Ym9hcmQuS0VZQ09ERV9JKSB7Ly8gQ3RybCArIEFsdCArIEkgZm9yIEl0YWxpYwogICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSAiaXRhbGljIjsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAod2hpY2ggPT0gbnMuS2V5Ym9hcmQuS0VZQ09ERV9VKSB7Ly8gQ3RybCArIEFsdCArIFUgZm9yIFVuZGVybGluZQogICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSAidW5kZXJsaW5lIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICh3aGljaCA9PSBucy5LZXlib2FyZC5LRVlDT0RFX0UpIHsvLyBDdHJsICsgRSBmb3IgQ2VudGVyLUFsaWduZWQgVGV4dAogICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSAianVzdGlmeUNlbnRlciI7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHdoaWNoID09IG5zLktleWJvYXJkLktFWUNPREVfTCkgey8vQ3RybCArIEwgZm9yIExlZnQtQWxpZ25lZCBUZXh0CiAgICAgICAgICAgICAgICAgICAgY29tbWFuZCA9ICJqdXN0aWZ5TGVmdCI7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHdoaWNoID09IG5zLktleWJvYXJkLktFWUNPREVfUikgey8vQ3RybCArIFIgZm9yIFJpZ2h0LUFsaWduZWQgVGV4dAogICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSAianVzdGlmeVJpZ2h0IjsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAod2hpY2ggPT0gbnMuS2V5Ym9hcmQuS0VZQ09ERV9KKSB7Ly9DdHJsICsgSiBmb3IgRnVsbHktSnVzdGlmaWVkIFRleHQKICAgICAgICAgICAgICAgICAgICBjb21tYW5kID0gImp1c3RpZnlGdWxsIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY29tbWFuZCAhPSAiIikgewogICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgIGNvbXBvc2VyLmNvbW1hbmRzLmV4ZWMoY29tbWFuZCwgdW5kZWZpbmVkLCB0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07Cgp9KShkb2N1bWVudCwgRm9ybS5ydGUpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTYuIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgooZnVuY3Rpb24gKGRvY3VtZW50LCAkLCBucykgewogICAgInVzZSBzdHJpY3QiOwoKICAgIC8qKgogICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBSaWNoIFRleHQgRWRpdG9yIHdoaWNoIHRha2VzIG9iamVjdCB3aXRoIGZvbGxvd2luZyBjb25maWd1cmF0aW9ucyA6CiAgICAgKiBTZWxlY3RvciA6IHNlbGVjdG9yIG9yIERPTSBlbGVtZW50IG9mIEVsZW1lbnQgZm9yIHdoaWNoIFJURSBuZWVkcyB0byBiZSBsaW5rZWQKICAgICAqIFRvb2xiYXIgOiBzZWxlY3RvciBvZiBUb29sYmFyIG9yIGNvbmZpZyB0byB1c2UgY3VzdG9tIFRvb2xiYXIKICAgICAqIGRhdGEgOiBIVE1MIHRvIGJlIHNldCB3aGlsZSBpbnN0YW50aWF0aW5nCiAgICAgKgogICAgICogQHR5cGUge1JpY2hUZXh0RWRpdG9yfQogICAgICovCiAgICB2YXIgUmljaFRleHRFZGl0b3IgPSBucy5SaWNoVGV4dEVkaXRvciA9IGZ1bmN0aW9uIChvcHRpb25zKSB7CgogICAgICAgIHZhciBzZWxlY3RvciA9IHR5cGVvZiBvcHRpb25zLnNlbGVjdG9yID09PSAic3RyaW5nIiA/IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG9wdGlvbnMuc2VsZWN0b3IpIDogb3B0aW9ucy5zZWxlY3RvcjsKICAgICAgICB2YXIgdG9vbGJhciA9IG9wdGlvbnMudG9vbGJhcjsKICAgICAgICBucy5JMThuLnNldExvY2FsZShvcHRpb25zLmxvY2FsZSk7CiAgICAgICAgdGhpcy5lZGl0b3JDb25maWcgPSAkLmV4dGVuZChucy5EZWZhdWx0Q29uZmlnLCBvcHRpb25zLmNvbmZpZyk7CgogICAgICAgIHZhciBpbnNlcnRBZnRlcjsKICAgICAgICB2YXIgcmljaFRleHRFZGl0b3IgPSAkKCI8ZGl2IGNsYXNzPSdmb3Jtcy1yaWNoVGV4dEVkaXRvcic+PC9kaXY+Iik7CiAgICAgICAgaWYgKCEodG9vbGJhciBpbnN0YW5jZW9mIEhUTUxFbGVtZW50IHx8IHR5cGVvZiB0b29sYmFyID09ICJzdHJpbmciKSkgewogICAgICAgICAgICAvKiBDcmVhdGUgb3V0IG9mIHRoZSBib3ggdG9vbGJhciBpcyBubyB0b29sYmFyIERPTSBlbGVtZW50IG9yIHNlbGVjdG9yIGlzIHByb3ZpZGVyKi8KICAgICAgICAgICAgdGhpcy50b29sYmFyID0gbmV3IG5zLlRvb2xiYXIodG9vbGJhciwgdGhpcy5lZGl0b3JDb25maWcpOwogICAgICAgICAgICB0aGlzLiR0b29sYmFyID0gdGhpcy50b29sYmFyLnJlbmRlcigpOwogICAgICAgICAgICBpbnNlcnRBZnRlciA9IHRvb2xiYXIgPSB0aGlzLiR0b29sYmFyWzBdOwogICAgICAgICAgICByaWNoVGV4dEVkaXRvci5hcHBlbmQodGhpcy4kdG9vbGJhcik7CiAgICAgICAgICAgIHJpY2hUZXh0RWRpdG9yLmFkZENsYXNzKCJydGUtbW9kZS0iICsgdGhpcy50b29sYmFyLmdldE1vZGUoKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW5zZXJ0QWZ0ZXIgPSAkKCI8ZGl2PjwvZGl2PiIpWzBdOwogICAgICAgICAgICByaWNoVGV4dEVkaXRvci5hcHBlbmQoaW5zZXJ0QWZ0ZXIpOwogICAgICAgIH0KCiAgICAgICAgcmljaFRleHRFZGl0b3IuaW5zZXJ0QWZ0ZXIoJChzZWxlY3RvcikpOwogICAgICAgIHRoaXMuJGVsZW1lbnQgPSByaWNoVGV4dEVkaXRvcjsKCiAgICAgICAgdmFyIHBhcnNlclJ1bGVzID0gd3lzaWh0bWw1U3VwcG9ydGVkUGFyc2VyUnVsZXM7CiAgICAgICAgaWYgKG9wdGlvbnMucGFyc2VyUnVsZXMpIHsKICAgICAgICAgICAgaWYgKG9wdGlvbnMucGFyc2VyUnVsZXMudGFncykgewogICAgICAgICAgICAgICAgcGFyc2VyUnVsZXMudGFncyA9ICQuZXh0ZW5kKHBhcnNlclJ1bGVzLnRhZ3MsIG9wdGlvbnMucGFyc2VyUnVsZXMudGFncyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG9wdGlvbnMucGFyc2VyUnVsZXMuY2xhc3NlcykgewogICAgICAgICAgICAgICAgcGFyc2VyUnVsZXMuY2xhc3NlcyA9ICQuZXh0ZW5kKHBhcnNlclJ1bGVzLmNsYXNzZXMsIG9wdGlvbnMucGFyc2VyUnVsZXMuY2xhc3Nlcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG9wdGlvbnMucGFyc2VyUnVsZXMuc3R5bGVzKSB7CiAgICAgICAgICAgICAgICBwYXJzZXJSdWxlcy5zdHlsZXMgPSBwYXJzZXJSdWxlcy5zdHlsZXMuY29uY2F0KG9wdGlvbnMucGFyc2VyUnVsZXMuc3R5bGVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAob3B0aW9ucy5wYXJzZXJSdWxlcy5wc2V1ZG9UYWdzKSB7CiAgICAgICAgICAgICAgICBwYXJzZXJSdWxlcy5wc2V1ZG9UYWdzID0gb3B0aW9ucy5wYXJzZXJSdWxlcy5wc2V1ZG9UYWdzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChvcHRpb25zLnBhcnNlclJ1bGVzLnRleHROb2RlcykgewogICAgICAgICAgICAgICAgcGFyc2VyUnVsZXMudGV4dE5vZGVzID0gb3B0aW9ucy5wYXJzZXJSdWxlcy50ZXh0Tm9kZXMubWFwKGZ1bmN0aW9uIChub2RlTmFtZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlTmFtZS50b1VwcGVyQ2FzZSgpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICh3aW5kb3cuaGFzT3duUHJvcGVydHkoInd5c2lodG1sNSIpICYmIHdpbmRvdy53eXNpaHRtbDUpIHsKICAgICAgICAgICAgaWYgKCF0aGlzLmVkaXRvcikgewogICAgICAgICAgICAgICAgdGhpcy5lZGl0b3IgPSBuZXcgd3lzaWh0bWw1LkVkaXRvcihzZWxlY3RvciwgewogICAgICAgICAgICAgICAgICAgIHRvb2xiYXIgOiB0b29sYmFyLAogICAgICAgICAgICAgICAgICAgIGluc2VydEFmdGVyIDogaW5zZXJ0QWZ0ZXIsCiAgICAgICAgICAgICAgICAgICAgdXNlTGluZUJyZWFrcyA6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIHBhc3RlQXNQbGFpblRleHQgOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBzdHlsZXNoZWV0cyA6IG9wdGlvbnMuY3NzUGF0aCwKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0Rm9udFNpemUgOiB0aGlzLmVkaXRvckNvbmZpZy5mb250U2l6ZS5kZWZhdWx0VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgcGFyc2VyUnVsZXMgOiBwYXJzZXJSdWxlcwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5lZGl0b3IuY29tcG9zZXIpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY29tcG9zZXIgPSB0aGlzLmVkaXRvci5jb21wb3NlciwKICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyID0gY29tcG9zZXIuY29udGFpbmVyLAogICAgICAgICAgICAgICAgICAgICAgICBkb2MgPSBjb21wb3Nlci5kb2MsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZyA9IHRoaXMuZWRpdG9yQ29uZmlnOwogICAgICAgICAgICAgICAgICAgIGlmIChjb250YWluZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgc3R5bGUgaW4gdGhpcy5lZGl0b3JDb25maWcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmVkaXRvckNvbmZpZy5oYXNPd25Qcm9wZXJ0eShzdHlsZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250YWluZXIuc3R5bGVbc3R5bGVdID0gdGhpcy5lZGl0b3JDb25maWdbc3R5bGVdLmRlZmF1bHRWYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkKGRvYykub24oImtleWRvd24iLCBmdW5jdGlvbiAoZSkgewogICAgICAgICAgICAgICAgICAgICAgICBucy5TaG9ydGN1dEtleXNDdHJsLm9ua2V5ZG93bihlLCBjb21wb3NlciwgY29uZmlnKTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmRhdGEpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFJpY2hUZXh0RWRpdG9yQ29udGVudChvcHRpb25zLmRhdGEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGZpbmRBbmRSZXBsYWNlID0gdGhpcy5maW5kQW5kUmVwbGFjZSA9IG5ldyBucy5GaW5kQW5kUmVwbGFjZSh0aGlzKTsKICAgICAgICAgICAgICAgIFJpY2hUZXh0RWRpdG9yLmFkZENvbW1hbmQoImNoYW5nZUxpbmVIZWlnaHQiLCB7CiAgICAgICAgICAgICAgICAgICAgZXhlYyA6IGZ1bmN0aW9uIChjb21wb3NlciwgY29tbWFuZE5hbWUsIHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHd5c2lodG1sNS51dGlsLmNoYW5nZUxpbmVIZWlnaHQodmFsdWUsIHRydWUsIG51bGwsIGNvbXBvc2VyLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHN0YXRlIDogd3lzaWh0bWw1LmNvbW1hbmRzLmxpbmVIZWlnaHQuc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tTdGF0ZSA6IHd5c2lodG1sNS5jb21tYW5kcy5saW5lSGVpZ2h0LmNhbGxiYWNrU3RhdGUKCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIFJpY2hUZXh0RWRpdG9yLmFkZENvbW1hbmQoImZpbmRBbmRSZXBsYWNlIiwgewogICAgICAgICAgICAgICAgICAgIHN0YXRlIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmluZEFuZFJlcGxhY2UubWVzc2FnZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIFJpY2hUZXh0RWRpdG9yLmFkZENvbW1hbmQoImZpbmQiLCB7CiAgICAgICAgICAgICAgICAgICAgZm9jdXMgOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kTmFtZSwgdmFsdWVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmRBbmRSZXBsYWNlLmV4ZWN1dGVGaW5kKHZhbHVlcy5maW5kVGV4dCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIFJpY2hUZXh0RWRpdG9yLmFkZENvbW1hbmQoInJlcGxhY2UiLCB7CiAgICAgICAgICAgICAgICAgICAgZm9jdXMgOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kTmFtZSwgdmFsdWVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmRBbmRSZXBsYWNlLmV4ZWN1dGVSZXBsYWNlKHZhbHVlcy5maW5kVGV4dCwgdmFsdWVzLnJlcGxhY2VUZXh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgUmljaFRleHRFZGl0b3IuYWRkQ29tbWFuZCgicmVwbGFjZUFsbCIsIHsKICAgICAgICAgICAgICAgICAgICBmb2N1cyA6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmROYW1lLCB2YWx1ZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluZEFuZFJlcGxhY2UuZXhlY3V0ZVJlcGxhY2VBbGwodmFsdWVzLmZpbmRUZXh0LCB2YWx1ZXMucmVwbGFjZVRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBSaWNoVGV4dEVkaXRvci5hZGRDb21tYW5kKCJjaGFuZ2VGaW5kVGV4dCIsIHsKICAgICAgICAgICAgICAgICAgICBmb2N1cyA6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmROYW1lLCB2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5kQW5kUmVwbGFjZS5vbkZpbmRWYWx1ZUNoYW5nZSh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBSaWNoVGV4dEVkaXRvci5hZGRDb21tYW5kKCJjaGFuZ2VSZXBsYWNlVGV4dCIsIHsKICAgICAgICAgICAgICAgICAgICBmb2N1cyA6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmROYW1lLCB2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5kQW5kUmVwbGFjZS5vblJlcGxhY2VWYWx1ZUNoYW5nZSh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBSaWNoVGV4dEVkaXRvci5hZGRDb21tYW5kKCJjaGFuZ2VXaG9sZVdvcmQiLCB7CiAgICAgICAgICAgICAgICAgICAgZm9jdXMgOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kTmFtZSwgdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluZEFuZFJlcGxhY2Uub25TZWxlY3Rpb25DaGFuZ2UodW5kZWZpbmVkLCB2YWx1ZSwgdW5kZWZpbmVkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIFJpY2hUZXh0RWRpdG9yLmFkZENvbW1hbmQoImNoYW5nZU1hdGNoQ2FzZSIsIHsKICAgICAgICAgICAgICAgICAgICBmb2N1cyA6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGV4ZWMgOiBmdW5jdGlvbiAoY29tcG9zZXIsIGNvbW1hbmROYW1lLCB2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5kQW5kUmVwbGFjZS5vblNlbGVjdGlvbkNoYW5nZSh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBSaWNoVGV4dEVkaXRvci5hZGRDb21tYW5kKCJjaGFuZ2VSZWdFeHAiLCB7CiAgICAgICAgICAgICAgICAgICAgZm9jdXMgOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBleGVjIDogZnVuY3Rpb24gKGNvbXBvc2VyLCBjb21tYW5kTmFtZSwgdmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluZEFuZFJlcGxhY2Uub25TZWxlY3Rpb25DaGFuZ2UodW5kZWZpbmVkLCB1bmRlZmluZWQsIHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLnRvb2xiYXIpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnRvb2xiYXIuaW5pdGlhbGl6ZVRvb2xiYXJFdmVudHModGhpcyk7CiAgICAgICAgICAgICAgICAgICAgJCh0aGlzLnRvb2xiYXIpLm9uKCJtb2RlQ2hhbmdlZCIsICQucHJveHkodGhpcy50b2dnbGVUb29sYmFyTW9kZSwgdGhpcykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIHsiY29tcG9zZXIiIDogeyJnZXQiIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gKHRoaXMuZWRpdG9yICYmIHRoaXMuZWRpdG9yLmNvbXBvc2VyKSA/IHRoaXMuZWRpdG9yLmNvbXBvc2VyIDogbnVsbDsKICAgICAgICB9fX0pOwogICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRoaXMsIHsiY29udGFpbmVyIiA6IHsiZ2V0IiA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICh0aGlzLmVkaXRvciAmJiB0aGlzLmVkaXRvci5jb21wb3NlcikgPyB0aGlzLmVkaXRvci5jb21wb3Nlci5jb250YWluZXIgOiBudWxsOwogICAgICAgIH19fSk7CiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXModGhpcywgeyJkb2MiIDogeyJnZXQiIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gZG9jdW1lbnQ7CiAgICAgICAgfX19KTsKICAgIH07CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSBodG1sIHByb3ZpZGVkIHRvIHRoZSBSaWNoIFRleHQgRWRpdG9yCiAgICAgKiBAcGFyYW0gaHRtbERhdGEgSHRtbCB0byBiZSBpbnNlcnRlZAogICAgICovCiAgICBSaWNoVGV4dEVkaXRvci5wcm90b3R5cGUuc2V0UmljaFRleHRFZGl0b3JDb250ZW50ID0gZnVuY3Rpb24gKGh0bWxEYXRhKSB7CiAgICAgICAgaWYgKGh0bWxEYXRhICE9PSB0aGlzLmdldFJpY2hUZXh0RWRpdG9yQ29udGVudCgpKSB7CiAgICAgICAgICAgIGh0bWxEYXRhID0gaHRtbERhdGEgfHwgIiI7CiAgICAgICAgICAgIHZhciBwYXR0ZXJuID0gbmV3IFJlZ0V4cCgnPGJyPjxcL2JyPicsICdnaScpOwogICAgICAgICAgICBodG1sRGF0YSA9IGh0bWxEYXRhLnJlcGxhY2UocGF0dGVybiwgIjxicj4iKTsKICAgICAgICAgICAgaWYgKGh0bWxEYXRhLmluZGV4T2YoIjxib2R5IikgPiAtMSkgewogICAgICAgICAgICAgICAgaHRtbERhdGEgPSBucy51dGlsLkh0bWxVdGlscy5leHRyYWN0Qm9keUNvbnRlbnQoaHRtbERhdGEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuZWRpdG9yLnNldFZhbHVlKGh0bWxEYXRhKTsKICAgICAgICAgICAgaWYgKHRoaXMuZWRpdG9yLmNvbXBvc2VyICYmIHRoaXMuZWRpdG9yLmNvbXBvc2VyLnVuZG9NYW5hZ2VyKSB7CiAgICAgICAgICAgICAgICB0aGlzLmVkaXRvci5jb21wb3Nlci51bmRvTWFuYWdlci5jbGVhckhpc3RvcnkoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBGZXRjaGVzIHRoZSBjdXJyZW50IGh0bWwgZnJvbSBSaWNoIFRleHQgRWRpdG9yCiAgICAgKiBAcmV0dXJucyBodG1sIGZyb20gUmljaCBUZXh0IEVkaXRvcgogICAgICovCiAgICBSaWNoVGV4dEVkaXRvci5wcm90b3R5cGUuZ2V0UmljaFRleHRFZGl0b3JDb250ZW50ID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBodG1sID0gbnMudXRpbC5IdG1sVXRpbHMucmljaFRleHRFZGl0b3JUb0h0bWwodGhpcy5lZGl0b3IuZ2V0VmFsdWUoKSwgdGhpcy5lZGl0b3JDb25maWcpOwogICAgICAgIHJldHVybiBucy51dGlsLkh0bWxVdGlscy53cmFwSW5Cb2R5KGh0bWwpOwogICAgfTsKCiAgICAvKioKICAgICAqIEV4ZWN1dGVzIGNvbW1hbmQoYm9sZCxpdGFsaWNzLGV0Yykgb24gdGhlIEVkaXRvcgogICAgICogQHBhcmFtIGNvbW1hbmQgTmFtZSBvZiB0aGUgY29tbWFuZAogICAgICogQHBhcmFtIHZhbHVlIHZhbHVlIGZvciB0aGUgY29tbWFuZAogICAgICogQHBhcmFtIGFsbG93VW5kbyB3aGV0aGVyIHVuZG8gdG8gYmUgZW5hYmxlZCBmb3IgdGhlIGNvbW1hbmQgb3Igbm90CiAgICAgKi8KICAgIFJpY2hUZXh0RWRpdG9yLnByb3RvdHlwZS5leGVjdXRlQ29tbWFuZCA9IGZ1bmN0aW9uIChjb21tYW5kLCB2YWx1ZSwgYWxsb3dVbmRvKSB7CiAgICAgICAgaWYgKGFyZ3VtZW50cyAmJiBhcmd1bWVudHMubGVuZ3RoID4gMCkgewogICAgICAgICAgICBpZiAodGhpcy5lZGl0b3IgJiYgdGhpcy5lZGl0b3IuY29tcG9zZXIpIHsKICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yLmNvbXBvc2VyLmNvbW1hbmRzLmV4ZWMuYXBwbHkodGhpcywgYXJndW1lbnRzLCBhbGxvd1VuZG8pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgd2luZG93LmNvbnNvbGUuZXJyb3IoIlVuYWJsZSB0byBmaW5kIHRoZSBFZGl0b3IgaW5zdGFuY2UiKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHdpbmRvdy5jb25zb2xlLmVycm9yKCJJbnZhbGlkIGNvbW1hbmQgIik7CiAgICAgICAgfQogICAgfTsKCiAgICAvKioKICAgICAqIENoYW5nZXMgdGhlIHRvb2xiYXIgbW9kZQogICAgICogQHBhcmFtIGUgVG9vbGJhciBtb2RlIGNoYW5nZSBFdmVudAogICAgICogQHBhcmFtIG1vZGUgTW9kZSBmb3IgdGhlIHRvb2xiYXIgdG8gYmUgZW5hYmxlZAogICAgICovCiAgICBSaWNoVGV4dEVkaXRvci5wcm90b3R5cGUudG9nZ2xlVG9vbGJhck1vZGUgPSBmdW5jdGlvbiAoZSwgbW9kZSkgewogICAgICAgIHRoaXMuJGVsZW1lbnQucmVtb3ZlQ2xhc3MoInJ0ZS1tb2RlLSIgKyB0aGlzLnRvb2xiYXIuZ2V0TW9kZSgpKTsKICAgICAgICBpZiAodGhpcy4kdG9vbGJhcikgewogICAgICAgICAgICAkKHRoaXMudG9vbGJhcikub2ZmKCJtb2RlQ2hhbmdlZCIpOwogICAgICAgICAgICB0aGlzLiR0b29sYmFyLmRldGFjaCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLiR0b29sYmFyID0gdGhpcy50b29sYmFyLnNldE1vZGUobW9kZSk7CiAgICAgICAgdGhpcy4kZWxlbWVudC5wcmVwZW5kKHRoaXMuJHRvb2xiYXIpOwogICAgICAgIHRoaXMuJGVsZW1lbnQuYWRkQ2xhc3MoInJ0ZS1tb2RlLSIgKyB0aGlzLnRvb2xiYXIuZ2V0TW9kZSgpKTsKICAgICAgICB0aGlzLmVkaXRvci5zZXRUb29sYmFyKHRoaXMuJHRvb2xiYXJbMF0pOwogICAgICAgIHRoaXMudG9vbGJhci5pbml0aWFsaXplVG9vbGJhckV2ZW50cyh0aGlzKTsKICAgICAgICAkKHRoaXMudG9vbGJhcikub24oIm1vZGVDaGFuZ2VkIiwgJC5wcm94eSh0aGlzLnRvZ2dsZVRvb2xiYXJNb2RlLCB0aGlzKSk7CiAgICB9OwoKICAgIFJpY2hUZXh0RWRpdG9yLmFkZENvbW1hbmQgPSBmdW5jdGlvbiAoY29tbWFuZE5hbWUsIG9wdGlvbnMpIHsKICAgICAgICB3eXNpaHRtbDUuY29tbWFuZHNbY29tbWFuZE5hbWVdID0gb3B0aW9uczsKICAgIH07Cgp9KShkb2N1bWVudCwgJCwgRm9ybS5ydGUpOwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX18KICoKICogIENvcHlyaWdodCAyMDE2IEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiBzdXBwbGllcnMgYW5kIG1heSBiZSBjb3ZlcmVkIGJ5IFUuUy4gYW5kIEZvcmVpZ24gUGF0ZW50cywKICogcGF0ZW50cyBpbiBwcm9jZXNzLCBhbmQgYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCndpbmRvdy54ZmFsaWIuJCA9IHdpbmRvdy4kOwp3aW5kb3cueGZhbGliLmpRdWVyeSA9IHdpbmRvdy5qUXVlcnk7CndpbmRvdy54ZmFsaWIuXyA9IHdpbmRvdy5fOwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgIENvcHlyaWdodCAyMDEzIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCjsoZnVuY3Rpb24gKCQpIHsKICAgIC8qCiAgICAgKiBGb3JtIEJyaWRnZSBBUEkKICAgICAqIFRoZSBBUEkgcHJvdmlkZXMgYSBtZXRob2QgZm9yIGV4dGVybmFsIGFwcGxpY2F0aW9ucyB0byBjb25uZWN0IHdpdGggWGZhIGFuZCBmb3JtRG9tLiBUaGUgQVBJcyBhcmUgZGl2aWRlZCBpbnRvIHR3byBjYXRlZ29yaWVzLCBzeW5jaHJvbm91cyBhbmQgYXN5bmNocm9ub3VzLgogICAgICoKICAgICAqIEFsbCB0aGUgQVBJcyB0aGF0IGFyZSBpbnRlcm5hbCB0byB1cyBtdXN0IGdvIGludG8gRm9ybUJyaWRnZUludGVybmFsLmpzIGFuZCBub3QgaGVyZQogICAgICoKICAgICAqIEVhY2ggU3luY2hyb25vdXMgZ2V0dGVyIEFQSSByZXR1cm5zIGEgWEZBUmVzdWx0T2JqZWN0IHdoaWNoIHJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiB0aGUgQVBJIHdoZXJlYXMgZWFjaCBzZXR0ZXIgQVBJIHRocm93cyBhbiBleGNlcHRpb24gaW4gY2FzZSBvZiBlcnJvciBhbmQKICAgICAqIGl0IGlzIHRoZSByZXNwb25zaWJpbGl0eSBvZiB0aGUgQVBJIHRvIGNhdGNoIHRob3NlIGV4Y2VwdGlvbnMuIFRoZSBYRkFSZXN1bHRPYmplY3QgZWl0aGVyIGNvbnRhaW5zIGVycm9yIG9yIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIEFQSSBhbmQgcHJvdmlkZXMgZWFzeQogICAgICogbWVjaGFuaXNtIHRvIGFjY2VzcyBlYWNoIG9mIHRoZW0uCiAgICAgKgogICAgICogRWFjaCBBc3luY2hyb25vdXMgQVBJIHByb3ZpZGVzIGNhbGxiYWNrIG1lY2hhbmlzbSB0byByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgQVBJLiBFYWNoIEFQSSB0YWtlcyBhIEphdmFzY3JpcHQgT2JqZWN0IGNvbnRhaW5pbmcgZXJyb3IsIHN1Y2Nlc3MgSGFuZGxlcnMgYW5kIGEKICAgICAqIGNvbnRleHQgaW4gd2hpY2ggdG8gaW52b2tlIHRob3NlIGZ1bmN0aW9ucy4gVGhlIHN5bnRheCBvZiB0aGUgb2JqZWN0IGlzCiAgICAgKiB7IGVycm9yOiBlcnJvckhhbmRsZXJGdW5jLAogICAgICogICBzdWNjZXNzOiBzdWNjZXNzSGFuZGxlckZ1bmMsCiAgICAgKiAgIGNvbnRleHQ6IE9iamVjdENvbnRleHQKICAgICAqIH0KICAgICAqIFRoZSBzaWduYXR1cmUgb2YgdGhlIGZ1bmN0aW9ucyBpcwogICAgICogZnVuY3Rpb24oWEZBUmVzdWx0T2JqZWN0KSB7CiAgICAgKgogICAgICogIH0KICAgICAqIEVhY2ggb2YgdGhlIGZ1bmN0aW9ucyBpcyBwYXNzZWQgYSBYRkFSZXN1bHRPYmplY3QgY29udGFpbmluZyBlaXRoZXIgdGhlIGRhdGEgb2YgdGhlIG9wZXJhdGlvbiBvciB0aGUgZXJyb3JzLgogICAgICoKICAgICAqLwoKICAgIEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgfHwgZnVuY3Rpb24gKGN0eCkgewogICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGF0LmNhbGwoY3R4LCBhcmd1bWVudHMpOwogICAgICAgIH0KICAgIH07CgogICAgLyogcHVibGljIGludGVyZmFjZSBYRkFSZXN1bHRPYmplY3QKICAgICBwdWJsaWMgc3RyaW5nW10gbWVzc2FnZSAgICAgICAgICAvLyBlcnJvciBtZXNzYWdlcwogICAgIHB1YmxpYyBzdHJpbmdbXSBzb21FeHByZXNzaW9uICAgIC8vIHNvbUV4cHJlc3Npb25zIHRoYXQgY2F1c2VkIHRoZSBlcnJvcnMKICAgICBwdWJsaWMgc3RyaW5nW10gZXJyb3JDb2RlICAgICAgICAvLyBpbnRlcm5hbAogICAgIHB1YmxpYyBib29sIGVycm9ycyAgICAgICAgICAgICAgIC8vIHdoZXRoZXIgdGhlIHJlc3VsdCBvYmplY3QgaGFzIGVycm9ycyBvciBub3QKICAgICBwdWJsaWMgT2JqZWN0IGRhdGEgICAgICAgICAgICAgICAvLyBkYXRhIHJldHVybmVkIGJ5IHRoZSBmdW5jdGlvbgoKICAgICBwdWJsaWMgZ2V0TmV4dE1lc3NhZ2UgICAgICAgICAgICAvLyByZXR1cm5zIGEgbWVzc2FnZSBPYmplY3Qge2NvZGUsc29tRXhwcmVzc2lvbixtZXNzYWdlfSBvciBudWxsIGlmIG5vIGVycm9yIG1lc3NhZ2UgaXMgcHJlc2VudAogICAgICovCiAgICB2YXIgWEZBUmVzdWx0T2JqZWN0ID0gZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIF9tZXNzYWdlID0gW10sCiAgICAgICAgICAgIF9lcnJvckNvZGUgPSBbXSwKICAgICAgICAgICAgX3NvbUV4cHJlc3Npb24gPSBbXTsKICAgICAgICB0aGlzLmVycm9ycyA9IGZhbHNlOwoKICAgICAgICB0aGlzLmFkZE1lc3NhZ2UgPSBmdW5jdGlvbiAoY29kZSwgbXNnLCBzb20pIHsKICAgICAgICAgICAgdGhpcy5lcnJvcnMgPSB0cnVlOwogICAgICAgICAgICBfbWVzc2FnZS5wdXNoKG1zZyk7CiAgICAgICAgICAgIF9zb21FeHByZXNzaW9uLnB1c2goc29tKTsKICAgICAgICAgICAgX2Vycm9yQ29kZS5wdXNoKGNvZGUpOwogICAgICAgIH07CgogICAgICAgIHRoaXMuZ2V0TmV4dE1lc3NhZ2UgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmIChfZXJyb3JDb2RlLmxlbmd0aCA9PSAwKQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICBjb2RlOiBfZXJyb3JDb2RlLnBvcCgpLAogICAgICAgICAgICAgICAgc29tRXhwcmVzc2lvbjogX3NvbUV4cHJlc3Npb24ucG9wKCksCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBfbWVzc2FnZS5wb3AoKQogICAgICAgICAgICB9OwogICAgICAgIH07CiAgICB9OwoKICAgIHZhciBGT1JNX0JSSURHRV9WRVJTSU9OID0gIjguMS4zNiI7CiAgICB2YXIgRm9ybUJyaWRnZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLl94ZmEgPSBudWxsOwogICAgICAgIHRoaXMuX3ZlcnNpb24gPSBGT1JNX0JSSURHRV9WRVJTSU9OOwogICAgICAgIHRoaXMuX3hmYUluaXRIYW5kbGVyID0ge307CiAgICAgICAgdGhpcy5fJHRhcmdldCA9IG51bGw7CiAgICAgICAgdGhpcy5pc0FuYWx5dGljc0VuYWJsZWQgPSBmYWxzZTsKICAgICAgICAkKHdpbmRvdykub24oIlhmYUluaXRpYWxpemVkIiwgdGhpcy5feGZhSW5pdGlhbGl6ZWQuYmluZCh0aGlzKSk7CiAgICAgICAgJCh3aW5kb3cpLm9uKCJYZmFJbml0aWFsaXphdGlvbkVycm9yIiwgdGhpcy5feGZhRXJyb3IpOwogICAgICAgIHRoaXMuX2Zvcm1Eb2MgPSB3aW5kb3cuZG9jdW1lbnQ7CiAgICAgICAgdGhpcy51c2VyQ29uZmlnID0ge307CiAgICAgICAgLy8gaW5kaWNhdGVzIGlmIGFqYXggY2FsbCBpcyBleGVjdXRlZCBpbiBjbGllbnQgb3Igc2VydmVyCiAgICAgICAgLy8gbm90ZTogdGhpcyBzaG91bGQgbm90IGJlIG1vZGlmaWVkIGluIGNsaWVudAogICAgICAgIHRoaXMuYWpheENhbGxNb2RlID0gImNsaWVudCI7CiAgICAgICAgdGhpcy5fUFJPRklMRV9SRVNPVVJDRV9QQVRIID0gIi9jb250ZW50L3hmYWZvcm1zL3Byb2ZpbGVzL2RlZmF1bHQiOwogICAgfTsKCiAgICAvKgogICAgICogRGVmYXVsdCBlcnJvciBoYW5kbGVyIGZvciBmdW5jdGlvbnMgaW4gY2FzZSBub25lIGlzIHByb3ZpZGVkIGJ5IHRoZSBjYWxsZXIKICAgICAqIFRPRE8gOiBtYWtlIHRoZSBzdHJpbmcgbG9jYWxpemVkIGFuZCBjYWxsIHRoZSB4ZmEgTG9nZ2VyCiAgICAgKi8KICAgIHZhciBkZWZhdWx0RXJyb3JIYW5kbGVyID0gZnVuY3Rpb24gKG9iaikgewogICAgICAgIGlmICh0eXBlb2YoY29uc29sZSkgPT0gInVuZGVmaW5lZCIpCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB2YXIgZCA9IG51bGw7CiAgICAgICAgd2hpbGUgKGQgPSBvYmouZ2V0TmV4dE1lc3NhZ2UoKSkKICAgICAgICAgICAgY29uc29sZS5lcnJvcihkLm1lc3NhZ2UpOwogICAgfTsKCiAgICB2YXIgX2lzRmlyc3RUZW1wU3RvcmFnZUNyZWF0aW9uUGVuZGluZyA9IGZhbHNlLAogICAgICAgIFRFTVBfU1RPUkFHRV9QQVRIID0gIi90bXAvZmQveGZhZm9ybXMiOwogICAgdmFyIGNyZWF0ZVVVSURTdG9yYWdlICA9IGZ1bmN0aW9uKHV1aWQpewogICAgICAgIGlmKCFmb3JtQnJpZGdlLl9pc0xvZ2luQW5vbnltb3VzKCkpIHsKICAgICAgICAgICAgdmFyIHN1Y2Nlc3NGbGFnID0gdHJ1ZTsKICAgICAgICAgICAgJC5hamF4KHsKICAgICAgICAgICAgdXJsOiBmb3JtQnJpZGdlLl9nZXRQYXRoVXJsKCIuZmQudGVtcHN0b3JhZ2Vwcm92aWRlci5qc3AiKSwKICAgICAgICAgICAgICAgIHR5cGU6ICJQT1NUIiwKICAgICAgICAgICAgICAgIGFzeW5jOiBmYWxzZSwKICAgICAgICAgICAgICAgIGRhdGE6IHsidXVpZFBhdGgiOiBURU1QX1NUT1JBR0VfUEFUSCArICIvIiArIHV1aWR9LAogICAgICAgICAgICAgICAgZXJyb3IgOiBmdW5jdGlvbiAobWVzc2FnZSkgewogICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NGbGFnID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICByZXR1cm4gc3VjY2Vzc0ZsYWc7CiAgICAgICAgfQoKICAgIH07CgogICAgLyoKICAgICAqIERlZmF1bHQgZnVuY3Rpb24gdG8gY2hlY2sgVmFsaWRhdGlvbnMgZXJyb3JzIGFmdGVyIGdldHRpbmcgdGhlIGRhdGEgZnJvbSB0aGUKICAgICAqIHNlcnZlciB3aXRoIGdldERhdGFYTUwgY2FsbC4KICAgICAqLwogICAgdmFyIGRlZmF1bHRWYWxpZGF0aW9uQ2hlY2tlciA9IGZ1bmN0aW9uICh2YWxpZGF0aW9ucywgb2JqKSB7CiAgICAgICAgaWYgKHZhbGlkYXRpb25zICYmIHZhbGlkYXRpb25zLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWxpZGF0aW9ucy5sZW5ndGg7IGkrKykKICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDAsIHZhbGlkYXRpb25zW2ldLCAiIik7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9OwoKICAgICQuZXh0ZW5kKEZvcm1CcmlkZ2UucHJvdG90eXBlLCB7CiAgICAgICAgLyoKICAgICAgICAgKiBSZXR1cm5zIHdoZXRoZXIgRm9ybSBEb20gaXMgaW5pdGlhbGl6ZWQgb3Igbm90LgogICAgICAgICAqLwogICAgICAgIGlzQ29ubmVjdGVkOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAhIXRoaXMuX3hmYTsKICAgICAgICB9LAogICAgICAgIC8qCiAgICAgICAgICogQHB1YmxpYwogICAgICAgICAqIFNwZWNpZnkgYSBmdW5jdGlvbiB0byBleGVjdXRlIGFmdGVyIG1ha2luZyBhIGNvbm5lY3Rpb24gd2l0aCBGb3JtQnJpZGdlCiAgICAgICAgICogaGFuZGxlcjogaGFuZGxlciB0byBleGVjdXRlCiAgICAgICAgICogY29udGV4dDogdmFyaWFibGUgJ3RoaXMnIHdpbGwgcmVmZXIgdG8gY29udGV4dCBpbiB0aGUgaGFuZGxlci4KICAgICAgICAgKi8KICAgICAgICBjb25uZWN0OiBmdW5jdGlvbiAoaGFuZGxlciwgY29udGV4dCkgewogICAgICAgICAgICBjb250ZXh0ID0gY29udGV4dCB8fCBmb3JtQnJpZGdlOwogICAgICAgICAgICBpZiAodGhpcy5pc0Nvbm5lY3RlZCgpKQogICAgICAgICAgICAgICAgaGFuZGxlci5jYWxsKGNvbnRleHQpOwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMuX3hmYUluaXRIYW5kbGVyLmhhbmRsZXIgPSB0aGlzLl94ZmFJbml0SGFuZGxlci5oYW5kbGVyIHx8IFtdOwogICAgICAgICAgICAgICAgdGhpcy5feGZhSW5pdEhhbmRsZXIuaGFuZGxlci5wdXNoKGhhbmRsZXIpOwogICAgICAgICAgICAgICAgdGhpcy5feGZhSW5pdEhhbmRsZXIuY29udGV4dCA9IHRoaXMuX3hmYUluaXRIYW5kbGVyLmNvbnRleHQgfHwgW107CiAgICAgICAgICAgICAgICB0aGlzLl94ZmFJbml0SGFuZGxlci5jb250ZXh0LnB1c2goY29udGV4dCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIC8qCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBIYW5kbGVyIGZvciBYZmFJbml0aWFsaXplZCBldmVudCB3aGljaCBpcyBmaXJlZCBieSBYRkEgbGlicmFyeSBhZnRlciBGb3JtIERvbSBpcyBpbml0aWFsaXplZAogICAgICAgICAqLwogICAgICAgIF94ZmFJbml0aWFsaXplZDogZnVuY3Rpb24gKGUpIHsKICAgICAgICAgICAgdGhpcy5feGZhID0geGZhbGliLnJ1bnRpbWUueGZhOwogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwogICAgICAgICAgICBpZiAodGhpcy5zdG9yYWdlKSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdG9yYWdlLmZvcm1TdGF0ZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYS5ob3N0LnBsYXlKc29uKEpTT04ucGFyc2UodGhpcy5zdG9yYWdlLmZvcm1TdGF0ZS54ZmFEb20pKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2Uuc3VjY2Vzcy5jYWxsKHRoaXMuc3RvcmFnZS5jb250ZXh0KTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UgPSBudWxsOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnN0b3JhZ2Uuc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5zdWNjZXNzLmNhbGwodGhpcy5zdG9yYWdlLmNvbnRleHQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHRoaXMueG1sU3RvcmFnZSAmJiB0aGlzLnhtbFN0b3JhZ2UueG1sRG9jdW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEuTG9nZ2VyLmRlYnVnKCJ4ZmEiLCAiUmVzdG9yaW5nIERhdGEgWE1MIGFmdGVyIGluaXRpYWlsemF0aW9uIik7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYS5ob3N0LnBsYXlEYXRhWG1sKHRoaXMueG1sU3RvcmFnZS54bWxEb2N1bWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMueG1sU3RvcmFnZS5zdWNjZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnhtbFN0b3JhZ2Uuc3VjY2Vzcy5jYWxsKHRoaXMueG1sU3RvcmFnZS5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMueG1sU3RvcmFnZS5lcnJvcikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMiwgIlVuZXhwZWN0ZWQgRXhjZXB0aW9uOiBVbmFibGUgdG8gcGxheSBEYXRhIFhNTCAiICsgZSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnhtbFN0b3JhZ2UuZXJyb3IuY2FsbCh0aGlzLnhtbFN0b3JhZ2UuY29udGV4dCwgb2JqKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy54bWxTdG9yYWdlICYmIHRoaXMueG1sU3RvcmFnZS5zdWNjZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy54bWxTdG9yYWdlLnN1Y2Nlc3MuY2FsbCh0aGlzLnhtbFN0b3JhZ2UuY29udGV4dCwgb2JqKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMueG1sU3RvcmFnZSA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRoaXMuX3hmYUluaXRIYW5kbGVyLmhhbmRsZXIpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5feGZhSW5pdEhhbmRsZXIuaGFuZGxlci5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYUluaXRIYW5kbGVyLmhhbmRsZXJbaV0uY2FsbCh0aGlzLl94ZmFJbml0SGFuZGxlci5jb250ZXh0W2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX3hmYUluaXRIYW5kbGVyID0ge307CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIEBwdWJsaWMKICAgICAgICAgKiBTcGVjaWZ5IGEgZnVuY3Rpb24gdG8gZGVjaWRlIHdoZXRoZXIgdGhlIGFuYWx5dGljcyB3aWxsIGJlIGVuYWJsZWQgb3IgZGlzYWJsZWQKICAgICAgICAgKiBwdWJsaWMgQm9vbGVhbiBpc0FuYWx5dGljc0VuYWJsZWQ6IHRoaXMgYXJndW1lbnQgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBhbmFseXRpY3Mgd2lsbCBiZSBlbmFibGVkIG9yIG5vdAogICAgICAgICAqLwogICAgICAgIGVuYWJsZUFuYWx5dGljczogZnVuY3Rpb24oc3RhdGUpewogICAgICAgICAgICB0aGlzLmlzQW5hbHl0aWNzRW5hYmxlZCA9IHN0YXRlOwogICAgICAgIH0sCgogICAgICAgIF94ZmFFcnJvcjogZnVuY3Rpb24gKGUpIHsKICAgICAgICAgICAgdGhpcy5feGZhID0gd2luZG93LnhmYTsKICAgICAgICAgICAgdmFyIG9iaiA9IG5ldyBYRkFSZXN1bHRPYmplY3QoKTsKICAgICAgICAgICAgLy8gc2luY2UgdGhlcmUgaXMgeGZhIGluaXQgZXJyb3IsIHdoeSBzaG91bGQgd2UgY2FsbCBwbGF5SnNvbgogICAgICAgICAgICBpZiAodGhpcy5zdG9yYWdlLmZvcm1TdGF0ZSkgewogICAgICAgICAgICAgICAgdGhpcy5feGZhLmhvc3QucGxheUpzb24oSlNPTi5wYXJzZSh0aGlzLnN0b3JhZ2UuZm9ybVN0YXRlLnhmYURvbSkpOwogICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlID0gbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0b3JhZ2UuZXJyb3IpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLmVycm9yLmNhbGwodGhpcy5zdG9yYWdlLmNvbnRleHQsIGUubWVzc2FnZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRoaXMueG1sU3RvcmFnZS5lcnJvcikgewogICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMiwgZS5tZXNzYWdlLCBudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMueG1sU3RvcmFnZS5lcnJvci5jYWxsKHRoaXMueG1sU3RvcmFnZS5jb250ZXh0LCBvYmopOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldFJlc3VsdE9iamVjdDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgWEZBUmVzdWx0T2JqZWN0KCk7CiAgICAgICAgfSwKCiAgICAgICAgX2NoZWNrWGZhOiBmdW5jdGlvbiAob2JqKSB7CiAgICAgICAgICAgIGlmICghdGhpcy5feGZhKSB7CiAgICAgICAgICAgICAgICBvYmouYWRkTWVzc2FnZSgxLCAiWGZhIERvbSBub3QgSW5pdGlhbGl6ZWQiLCAiIik7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSwKICAgICAgICAvKgogICAgICAgICAqIHJldHVybnMgdGhlIHZlcnNpb24gb2YgbGlicmFyeQogICAgICAgICAqLwogICAgICAgIGdldEJyaWRnZVZlcnNpb246IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZlcnNpb247CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBSZWdpc3RlcnMgdXNlci9wb3J0YWwgc3BlY2lmaWMgY29uZmlndXJhdGlvbnMgdG8gRm9ybUJyaWRnZS4KICAgICAgICAgKiBDdXJyZW50bHkgc3VwcG9ydGVkIGNvbmZpZ3VyYXRpb25zIGFyZToKICAgICAgICAgKiB7d2lkZ2V0Q29uZmlnIDoge3NlbGVjdG9yOiBqcVdpZGdldE5hbWV9fQogICAgICAgICAqIHtwYWdpbmdDb25maWcgOiB7cGFnaW5nRW5hYmxlZDogdHJ1ZX19CiAgICAgICAgICoge0xvZ2dlckNvbmZpZyA6IHt7Im9uIjoidHJ1ZSIsICJjYXRlZ29yeSI6InhmYSIsICJsZXZlbCI6IjUiLCAidHlwZSI6ImNvbnNvbGUifX0KICAgICAgICAgKiB7cG9zdEV4dGVybmFsTWVzc2FnZUNvbmZpZyA6IHtwb3N0RXh0ZXJuYWxIYW5kbGVyOiBmbn19CiAgICAgICAgICoge2NvbnRleHRQYXRoIDogY29udGV4dFBhdGh9CiAgICAgICAgICoge3ZpZXdwb3J0V2lkdGggOiA8MTAwMD59CiAgICAgICAgICogZS5nLjogZm9ybUJyaWRnZS5yZWdpc3RlckNvbmZpZygid2lkZ2V0Q29uZmlnIiwgeyIuaW1hZ2VmaWVsZCIgOiAic2lnSW1hZ2VGaWVsZCJ9KTsKICAgICAgICAgKgogICAgICAgICAqIHJldHVybnMgYSBYRkFSZXN1bHRPYmplY3QuIE9sZCBjb25maWcgYWdhaW5zdCBzYW1lIGtleSBpcyBzdG9yZWQgaW4gb2JqLmRhdGFbMF0KICAgICAgICAgKi8KICAgICAgICByZWdpc3RlckNvbmZpZzogZnVuY3Rpb24gKGtleSwgY29uZmlnKSB7CiAgICAgICAgICAgIHZhciBvYmogPSBuZXcgWEZBUmVzdWx0T2JqZWN0KCk7CiAgICAgICAgICAgIG9iai5kYXRhID0gdGhpcy51c2VyQ29uZmlnW2tleV07CiAgICAgICAgICAgIHRoaXMudXNlckNvbmZpZ1trZXldID0gY29uZmlnOwogICAgICAgICAgICBvYmouY29tcGxldGVkID0gdHJ1ZTsKICAgICAgICAgICAgcmV0dXJuIG9iajsKICAgICAgICB9LAoKCiAgICAgICAgLyoKICAgICAgICAgKiBSZXR1cm5zIHRoZSBwYWdpbmdNYW5hZ2VyIGhhbmRsZSBmb3IgdGhlIGN1cnJlbnQgeGZhIHZpZXcuCiAgICAgICAgICogU2hvdWxkIGJlIGNhbGxlZCBhZnRlciBGb3JtQnJpZGdlIGlzIGluIGNvbm5lY3RlZCBtb2RlIGVsc2UgcGFnaW5NYW5hZ2VyIGhhbmRsZSB3b3VsZCBiZSBudWxsCiAgICAgICAgICovCiAgICAgICAgcGFnaW5nTWFuYWdlcjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBpZiAodGhpcy5feGZhICYmIHRoaXMuX3hmYS5ob3N0KQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3hmYS5ob3N0LnBhZ2luZ01hbmFnZXI7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogaGlkZSB0aGUgZmllbGRzIHdob3NlIHNvbSBpcyBwcm92aWRlZCBpbiB0aGUgZmllbGRBcnJheQogICAgICAgICAqIGZpZWxkQXJyYXk6IGFycmF5IG9mIHNvbUV4cHJlc3Npb25zCiAgICAgICAgICovCiAgICAgICAgaGlkZUZpZWxkczogZnVuY3Rpb24gKGZpZWxkQXJyYXkpIHsKICAgICAgICAgICAgdGhpcy5zZXRGaWVsZFByb3BlcnRpZXMoZmllbGRBcnJheSwgInByZXNlbmNlIiwgImludmlzaWJsZSIpOwogICAgICAgIH0sCiAgICAgICAgLyoKICAgICAgICAgKiBNYWtlIHRoZSBmaWVsZHMsIHdob3NlIHNvbSBpcyBwcm92aWRlZCBpbiB0aGUgZmllbGRBcnJheSwgdmlzaWJsZQogICAgICAgICAqIGZpZWxkQXJyYXk6IGFycmF5IG9mIHNvbUV4cHJlc3Npb25zCiAgICAgICAgICovCiAgICAgICAgc2hvd0ZpZWxkczogZnVuY3Rpb24gKGZpZWxkQXJyYXkpIHsKICAgICAgICAgICAgdGhpcy5zZXRGaWVsZFByb3BlcnRpZXMoZmllbGRBcnJheSwgInByZXNlbmNlIiwgInZpc2libGUiKTsKICAgICAgICB9LAogICAgICAgIC8qCiAgICAgICAgICogc2V0IHRoZSB2YWx1ZSBvZiB0aGUgZmllbGQuIFRocm93cyBhbiBleGNlcHRpb24gaWYgdGhlIHNvbUV4cHJlc3Npb24gaXMgaW5jb3JyZWN0CiAgICAgICAgICogZmllbGQ6IHNvbUV4cHJlc3Npb25zIG9mIHRoZSBmaWVsZAogICAgICAgICAqLwogICAgICAgIHNldEZpZWxkVmFsdWU6IGZ1bmN0aW9uIChmaWVsZCwgdmFsdWUpIHsKICAgICAgICAgICAgdGhpcy5zZXRGaWVsZFByb3BlcnRpZXMoZmllbGQsICJyYXdWYWx1ZSIsIHZhbHVlKTsKICAgICAgICB9LAogICAgICAgIC8qCiAgICAgICAgICogZ2V0IHRoZSB2YWx1ZSBvZiB0aGUgZmllbGRzLCB3aG9zZSBzb20gaXMgcHJvdmlkZWQgaW4gdGhlIGZpZWxkQXJyYXkKICAgICAgICAgKiBmaWVsZEFycmF5OiBhcnJheSBvZiBzb21FeHByZXNzaW9ucwogICAgICAgICAqCiAgICAgICAgICogcmV0dXJucyBhIFhGQVJlc3VsdE9iamVjdC4gVGhlIHJlc3VsdCBpcyBzdG9yZWQgaW4gb2JqLmRhdGFbMF0KICAgICAgICAgKi8KICAgICAgICBnZXRGaWVsZFZhbHVlOiBmdW5jdGlvbiAoZmllbGQpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RmllbGRQcm9wZXJ0aWVzKGZpZWxkLCAicmF3VmFsdWUiKTsKICAgICAgICB9LAogICAgICAgIC8qCiAgICAgICAgICogc2V0IHRoZSBwcm9wZXJ0eSBvZiB0aGUgZmllbGRzLCB3aG9zZSBzb20gaXMgcHJvdmlkZWQgaW4gdGhlIGZpZWxkQXJyYXksIHdpdGggdGhlIHZhbHVlcyBwcm92aWRlZAogICAgICAgICAqIGZpZWxkQXJyYXk6IGFycmF5IG9mIHNvbUV4cHJlc3Npb25zCiAgICAgICAgICogcHJvcDogcHJvcGVydHkgdG8gc2V0CiAgICAgICAgICogdmFsdWVzOiBhcnJheSBvZiB2YWx1ZXMuCiAgICAgICAgICovCiAgICAgICAgc2V0RmllbGRQcm9wZXJ0aWVzOiBmdW5jdGlvbiAoZmllbGRBcnJheSwgcHJvcCwgdmFsdWVzKSB7CiAgICAgICAgICAgIHZhciBvYmogPSBuZXcgWEZBUmVzdWx0T2JqZWN0KCk7CiAgICAgICAgICAgIGlmICghdGhpcy5fY2hlY2tYZmEob2JqKSkKICAgICAgICAgICAgICAgIHRocm93IG9iai5nZXROZXh0TWVzc2FnZSgpLm1lc3NhZ2U7CgogICAgICAgICAgICBpZiAoIV8uaXNBcnJheShmaWVsZEFycmF5KSkgewogICAgICAgICAgICAgICAgZmllbGRBcnJheSA9IFtmaWVsZEFycmF5XTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFfLmlzQXJyYXkodmFsdWVzKSl7CiAgICAgICAgICAgICAgICB2YWx1ZXMgPSBbdmFsdWVzXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWVsZEFycmF5Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB2YXIgZmllbGQgPSB0aGlzLl94ZmEucmVzb2x2ZU5vZGUoZmllbGRBcnJheVtpXSk7CiAgICAgICAgICAgICAgICBpZiAoZmllbGQgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB0aHJvdyAiTm8gZmllbGQgIiArIGZpZWxkQXJyYXlbaV0gKyAiIGV4aXN0cyIKICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIG9iai5jb21wbGV0ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGZpZWxkW3Byb3BdID0gdmFsdWVzW2ldIHx8IHZhbHVlc1swXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBjaGFuZ2UgbWFkZSB0byByZS1ldmFsdWF0ZSBmbG9hdGluZyBmaWVsZCB0ZXh0IGluIGRyYXcKICAgICAgICAgICAgaWYocHJvcCAmJiBwcm9wID09PSAicmF3VmFsdWUiICYmIHRoaXMuX3hmYS5tb0NvbnRleHROb2Rlcy5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgdGhpcy5feGZhLnJ1bkNhbGNBbmRWYWxpZGF0ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAvKgogICAgICAgICAqIGdldCB0aGUgcHJvcGVydHkgdmFsdWUgb2YgdGhlIGZpZWxkcywgd2hvc2Ugc29tIGlzIHByb3ZpZGVkIGluIHRoZSBmaWVsZEFycmF5CiAgICAgICAgICogZmllbGRBcnJheTogYXJyYXkgb2Ygc29tRXhwcmVzc2lvbnMKICAgICAgICAgKiBwcm9wOiBwcm9wZXJ0eSB0byBnZXQKICAgICAgICAgKgogICAgICAgICAqIHJldHVybnMgYSBYRkFSZXN1bHRPYmplY3Qgd2hvc2UgZGF0YSBtZW1iZXIgaXMgdGhlIGFycmF5IG9mIHJldHVybmVkIHZhbHVlcy4gSWYgYQogICAgICAgICAqIHNvbUV4cHJlc3Npb24gcHJvdmlkZWQgZG9lc24ndCBleGlzdHMgbnVsbCBpcyByZXR1cm5lZCBmb3IgdGhhdCBlbGVtZW50IGluIHRoZSBkYXRhCiAgICAgICAgICovCiAgICAgICAgZ2V0RmllbGRQcm9wZXJ0aWVzOiBmdW5jdGlvbiAoZmllbGRBcnJheSwgcHJvcCkgewogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwogICAgICAgICAgICBpZiAoIXRoaXMuX2NoZWNrWGZhKG9iaikpCiAgICAgICAgICAgICAgICByZXR1cm4gb2JqOwoKICAgICAgICAgICAgaWYgKCFfLmlzQXJyYXkoZmllbGRBcnJheSkpIHsKICAgICAgICAgICAgICAgIGZpZWxkQXJyYXkgPSBbZmllbGRBcnJheV07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG9iai5kYXRhID0gW107CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZmllbGRBcnJheS5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIGZpZWxkID0gdGhpcy5feGZhLnJlc29sdmVOb2RlKGZpZWxkQXJyYXlbaV0pOwogICAgICAgICAgICAgICAgaWYgKGZpZWxkID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBvYmouYWRkTWVzc2FnZSgwLCAiTm8gZmllbGQgIiArIGZpZWxkQXJyYXlbaV0gKyAiIGV4aXN0cyIsIGZpZWxkQXJyYXlbaV0pCiAgICAgICAgICAgICAgICAgICAgb2JqLmRhdGEucHVzaChudWxsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIG9iai5jb21wbGV0ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIG9iai5kYXRhLnB1c2goZmllbGRbcHJvcF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBvYmo7CiAgICAgICAgfSwKICAgICAgICBoaWRlU3VibWl0QnV0dG9uczogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwogICAgICAgICAgICBpZiAoIXRoaXMuX2NoZWNrWGZhKG9iaikpCiAgICAgICAgICAgICAgICB0aHJvdyBvYmouZ2V0TmV4dE1lc3NhZ2UoKS5tZXNzYWdlOwogICAgICAgICAgICB0aGlzLl94ZmEuX2hpZGVTdWJtaXRCdXR0b25zKCk7CiAgICAgICAgfSwKICAgICAgICBfZ2V0UGF0aFVybDogZnVuY3Rpb24gKHVybFN1ZmZpeCkgewogICAgICAgICAgICB2YXIgdXJsID0gdGhpcy5fUFJPRklMRV9SRVNPVVJDRV9QQVRIICsgKHVybFN1ZmZpeCB8fCAiIik7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRVcmwodXJsKTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0RmlsZVdpZGdldElmUHJlc2VudDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4geGZhbGliLnJ1bnRpbWUuZmlsZVVwbG9hZFdpZGdldDsKCiAgICAgICAgfSwKICAgICAgICBfZ2V0RmlsZUxpc3RGcm9tRmlsZVdpZGdldDogIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGZpbGVXaWRnZXQgPSB0aGlzLl9nZXRGaWxlV2lkZ2V0SWZQcmVzZW50KCk7CiAgICAgICAgICAgIGlmKGZpbGVXaWRnZXQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmaWxlV2lkZ2V0Ll9nZXRGaWxlTGlzdCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCiAgICAgICAgX2dldENvbW1pdFZhbHVlRnJvbUZpbGVXaWRnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGZpbGVXaWRnZXQgPSB0aGlzLl9nZXRGaWxlV2lkZ2V0SWZQcmVzZW50KCk7CiAgICAgICAgICAgIGlmKGZpbGVXaWRnZXQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmaWxlV2lkZ2V0LmdldENvbW1pdFZhbHVlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gb3B0aW1pemV7Ym9vbGVhbn0gZmxhZyB0byB0dXJuIG9wdGltaXphdGlvbiBvbjsgaWYgZmFsc2UsIGVudGlyZSBqc29uTW9kZWwgaXMgcmV0dXJuZWQsCiAgICAgICAgICogZWxzZSBkaWZmIG9mIGluaXRpYWwgYW5kIGN1cnJlbnQgbW9kZWwgcmV0dXJuZWQuCiAgICAgICAgICogQHBhcmFtIG9wdGltaXplX2xldmVsezAsMSBvciAyfSA6IGRldGVybWluZXMgdGhlIGFnZ3Jlc3NpdmVuZXNzIGxldmVsIG9mIHNpemUgb3B0aW1pemF0aW9ucyB1c2VkCiAgICAgICAgICogIDA6IHJldHVybnMgYWxsIHByb3BlcnRpZXMgd2hpY2ggY2hhbmdlZCBiZXR3ZWVuIGluaXRpYWwgYW5kIGN1cnJlbnQgbW9kZWwuCiAgICAgICAgICogIDE6IGpzb25Nb2RlbERpZmYgd2l0aCBhY2Nlc3MgJiBwcmVzZW5jZSwgbXVzdCBiZSByZXBheWFibGUgdmlhIHBsYXlKc29uIG9uIGNhbGxpbmcgcmVzdG9yZUZvcm1TdGF0ZS4gYnV0IHRvIGtlZXAgZGlmZiBzeiB0byBtaW4uCiAgICAgICAgICogICAgICByZW1vdmUgdW5wbGF5ZWQgaXRlbXMgZnJvbSB0aGUgZGlmZi4gQWxzbyB0byBtYWludGFpbiBoaWVyYXJjaHkgbXVzdCBoYXZlIGFsbCBpbnN0YW5jZSBtYW5hZ2VycywgYW5kIHVuYmluZGVkIGZpZWxkcy4KICAgICAgICAgKiAgMjogbWluaW1hbCBqc29uTW9kZWxEaWZmIHdpdGggb25seSBoaWVyYXJjaHkgc2tlbGV0b24gYW5kIGNsYXNzLCBuYW1lIGFuZCAndmFsdWUncyBwcmVzZXJ2ZWQgZm9yIHRyYW5zZmVyIGR1cmluZyBzdWJtaXQuCiAgICAgICAgICoKICAgICAgICAgKiBAcmV0dXJucyB7WEZBUmVzdWx0T2JqZWN0fQogICAgICAgICAqIHJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgWEZBIEZvcm0gRE9NIGFuZCBpbmNsdWRlcyBhbGwgdGhlIFhGQSBwYWNrZXRzCiAgICAgICAgICogcmV0dXJucyBhIFhGQVJlc3VsdE9iamVjdCB3aG9zZSAnZGF0YScgbWVtYmVyIGlzIHRoZSBmb3JtU3RhdGUKICAgICAgICAgKi8KICAgICAgICBnZXRGb3JtU3RhdGU6IGZ1bmN0aW9uIChvcHRpbWl6ZSwgb3B0aW1pemVfbGV2ZWwpIHsKICAgICAgICAgICAgdmFyIG9iaiA9IG5ldyBYRkFSZXN1bHRPYmplY3QoKTsKICAgICAgICAgICAgaWYgKCF0aGlzLl9jaGVja1hmYShvYmopKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb2JqOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBiZWhhdmlvckNvbmZpZyA9IG5ldyB4ZmFsaWIudXQuVmVyc2lvbihmb3JtQnJpZGdlLnVzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl0pOwogICAgICAgICAgICAvL1RvIG1haW50YWluIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkKICAgICAgICAgICAgaWYgKGJlaGF2aW9yQ29uZmlnLmlzT24oJ2Rpc2FibGVMZWFuU3VibWl0JykgfHwgYmVoYXZpb3JDb25maWcuaXNPbignbWZEaXNhYmxlTGVhblN1Ym1pdCcpKSB7CiAgICAgICAgICAgICAgICBvcHRpbWl6ZV9sZXZlbCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHhmYURvbSA9IG9wdGltaXplID09PSB0cnVlID8gdGhpcy5feGZhLl9jb21wdXRlSnNvbkRpZmYob3B0aW1pemVfbGV2ZWwpLmpzb25EaWZmZXJlbmNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRoaXMuX3hmYS5qc29uTW9kZWw7CgogICAgICAgICAgICB4ZmFEb20uaXNDb21wbGV0ZSA9ICFvcHRpbWl6ZTsKCiAgICAgICAgICAgIC8vYWRkIHRoZSBpbmZvcm1hdGlvbiByZXF1aXJlZCBmcm9tIERPTSBkdXJpbmcgc3VibWl0IGluIHRoZSBmb3JtIHN0YXRlCiAgICAgICAgICAgIHZhciBmb3JtQXR0cmlidXRlc0RhdGEgPSB7fSwKICAgICAgICAgICAgICAgIGZvcm1FbGVtZW50ID0gJCgiI2xjZm9ybXNfeGZhZm9ybV9jb250YWluZXIiKVswXTsKICAgICAgICAgICAgaWYoZm9ybUVsZW1lbnQpewogICAgICAgICAgICAgICAgXy5lYWNoKGZvcm1FbGVtZW50LmF0dHJpYnV0ZXMsZnVuY3Rpb24oYXR0cmliKXsKICAgICAgICAgICAgICAgICAgICBmb3JtQXR0cmlidXRlc0RhdGFbYXR0cmliLm5hbWVdID0gYXR0cmliLnZhbHVlOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBhZGRpdGlvbmFsU3VibWl0SW5mb3JtYXRpb24gPSB7CiAgICAgICAgICAgICAgICAiZm9ybUF0dHJpYnV0ZXNEYXRhIjogZm9ybUF0dHJpYnV0ZXNEYXRhLAogICAgICAgICAgICAgICAgInVzZXJDb25maWciOiBmb3JtQnJpZGdlLnVzZXJDb25maWcKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHZhciB4ZmFEb21TdHJpbmcgPSBKU09OLnN0cmluZ2lmeSh4ZmFEb20pOwogICAgICAgICAgICBvYmouZGF0YSA9IHsKICAgICAgICAgICAgICAgIHhmYURvbTogeGZhRG9tU3RyaW5nLAogICAgICAgICAgICAgICAgLy9zYXZlIHJlbmRlckNvbnRleHQgaW4gZm9ybSBzdGF0ZSB0byBlbmFibGUgZGVmZXJyZWQgc3VibWl0IGV2ZW4gaWYgZm9ybSBpcyBub3Qgb3BlbgogICAgICAgICAgICAgICAgcmVuZGVyQ29udGV4dDogeGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dCwKICAgICAgICAgICAgICAgIGN1c3RvbVByb3BlcnR5TWFwOiB4ZmFsaWIucnVudGltZS5jdXN0b21Qcm9wZXJ0eU1hcCwKICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxTdWJtaXRJbmZvcm1hdGlvbjogYWRkaXRpb25hbFN1Ym1pdEluZm9ybWF0aW9uCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHJldHVybiBvYmo7CiAgICAgICAgfSwKICAgICAgICAvKgogICAgICAgICAqIHNldHMgdGhlIGZpZWxkIG9uIGZvY3VzIHdob3NlIHNvbUV4cHJlc3Npb24gaXMgcHJvdmlkZWQKICAgICAgICAgKgogICAgICAgICAqIHRocm93cyBhbiBleGNlcHRpb24gaW4gY2FzZSBvZiBlcnJvci4KICAgICAgICAgKi8KICAgICAgICBzZXRGb2N1czogZnVuY3Rpb24gKHNvbSkgewogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwogICAgICAgICAgICBpZiAoIXRoaXMuX2NoZWNrWGZhKG9iaikpCiAgICAgICAgICAgICAgICB0aHJvdyBvYmouZ2V0TmV4dE1lc3NhZ2UoKS5tZXNzYWdlOwogICAgICAgICAgICB2YXIgbm9kZSA9IHRoaXMuX3hmYS5yZXNvbHZlTm9kZShzb20pOwogICAgICAgICAgICBpZiAobm9kZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICB0aHJvdyAiTm8gZmllbGQgIiArIHNvbSArICIgZXhpc3RzICI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmEuaG9zdC5fc2V0Rm9jdXMoc29tKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogIEhlbHBlciBmdW5jdGlvbiB0byBnZXIgc3VibWl0IHNlcnZpY2UgcHJveHkgdXJsCiAgICAgICAgICovCiAgICAgICAgX2dldFN1Ym1pdFNlcnZpY2VQcm94eVVybDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgc3VibWl0U2VydmljZVByb3h5Q29uZmlnID0gdGhpcy51c2VyQ29uZmlnWyJzdWJtaXRTZXJ2aWNlUHJveHlDb25maWciXSwKICAgICAgICAgICAgICAgIHN1Ym1pdFNlcnZpY2VQcm94eVVybCA9ICIiLAogICAgICAgICAgICAgICAgY29udGV4dFBhdGggPSB0aGlzLnVzZXJDb25maWdbImNvbnRleHRQYXRoIl07CiAgICAgICAgICAgIGlmIChzdWJtaXRTZXJ2aWNlUHJveHlDb25maWcgJiYgc3VibWl0U2VydmljZVByb3h5Q29uZmlnWyJzdWJtaXRTZXJ2aWNlUHJveHkiXSkgewogICAgICAgICAgICAgICAgc3VibWl0U2VydmljZVByb3h5VXJsICs9IHN1Ym1pdFNlcnZpY2VQcm94eUNvbmZpZ1sic3VibWl0U2VydmljZVByb3h5Il07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAvL2ZpbmFsbHkgaGFyZCBjb2RlIGl0CiAgICAgICAgICAgICAgICBzdWJtaXRTZXJ2aWNlUHJveHlVcmwgKz0gKChjb250ZXh0UGF0aCAmJiBjb250ZXh0UGF0aCAhPT0gIi8iKSA/IGNvbnRleHRQYXRoIDogIiIpICsgIi9jb250ZW50L3hmYWZvcm1zL3Byb2ZpbGVzL2RlZmF1bHQuc3VibWl0Lmh0bWwiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzdWJtaXRTZXJ2aWNlUHJveHlVcmw7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiByZW1vdGUgaW52b2NhdGlvbiAtLS0tCiAgICAgICAgICogVGhpcyBtZXRob2QgcG9zdCBmb3JtIGRvbSB0byBMQ0Zvcm1zU2VydmljZSBhbmQgcnVuIHRoZSBzdWNjZXNzIGhhbmRsZXJzCiAgICAgICAgICogSXQgYWNjZXB0cyB0aGUgb2JqZWN0IHdpdGggZm9sbG93aW5nIHBhcmFtczoKICAgICAgICAgKiB7CiAgICAgICAgICogIHVybDogJycsCiAgICAgICAgICogIHR5cGU6ICcnLAogICAgICAgICAqICBjb250ZW50VHlwZTogJycsCiAgICAgICAgICogIGRhdGE6ICcnLAogICAgICAgICAqICBzdWNjZXNzOiAnJywKICAgICAgICAgKiAgZXJyb3I6ICcnCiAgICAgICAgICogIH0KICAgICAgICAgKiAgVGhlIGNhbGxlZCBjYW4gY2hvb3NlIHRvIG92ZXJyaWRlIG9uZSBvZiBtb3JlIHBhcmFtZXRlcnMgb2YgJC5hamF4IEFQSSBvZiBKUXVlcnkKICAgICAgICAgKi8KCiAgICAgICAgX2ludm9rZUF0U2VydmVyOiBmdW5jdGlvbiAob3B0aW9ucykgewogICAgICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICAgICAgICAgICAgdmFyIHN1Ym1pdFNlcnZpY2VQcm94eVVybCA9IHRoaXMuX2dldFN1Ym1pdFNlcnZpY2VQcm94eVVybCgpLAogICAgICAgICAgICAgICAgaXNTZXJ2ZXJBamF4Q2FsbE1vZGUgPSB0aGlzLmFqYXhDYWxsTW9kZSA9PT0gInNlcnZlciI7CgogICAgICAgICAgICBpZiAob3B0aW9ucy5kYXRhICYmICFvcHRpb25zLmRhdGFbIl9jaGFyc2V0XyJdKSB7CiAgICAgICAgICAgICAgICBvcHRpb25zLmRhdGFbIl9jaGFyc2V0XyJdID0gIlVURi04IjsgLy90byBsZXQgc2xpbmcga25vdyBkYXRhIGVuY29kaW5nCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKGlzU2VydmVyQWpheENhbGxNb2RlKXsKICAgICAgICAgICAgICAgIHZhciBtZXJnZWRGb3JtRG9tID0gIiI7CiAgICAgICAgICAgICAgICAvLyBEb25lIHRvIGZpeDogTEMtOTIwNAogICAgICAgICAgICAgICAgLy8gTm90IGludm9raW5nIEhUVFAgcmVxdWVzdCBpbnN0ZWFkIG1ha2luZyB1c2Ugb2Ygc2VydmVyIHNlc3Npb24KICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgbWVyZ2VkRm9ybURvbSA9IGdldE1lcmdlZEZvcm1Eb21Gcm9tUmhpbm8ob3B0aW9ucy5kYXRhKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2goZXhjZXB0aW9uKXsKICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmVycm9yKCJ4ZmEiLCBleGNlcHRpb24ubWVzc2FnZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBJZiBzdWNjZXNzIGhhbmRsZXIgaXMgcHJlc2VudCwgaW52b2tlIGl0LCBjb250ZXh0IGlzIHByb3ZpZGVkIGJ5IHRoZSBjYWxsZXIKICAgICAgICAgICAgICAgIGlmKF8uaXNGdW5jdGlvbihvcHRpb25zLnN1Y2Nlc3MpICYmIG1lcmdlZEZvcm1Eb20pIHsKICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnN1Y2Nlc3MoSlNPTi5wYXJzZShtZXJnZWRGb3JtRG9tKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgc3RyQ29udGVudCA9IHRoaXMuZ2V0TXVsdGlwYXJ0RGF0YShvcHRpb25zLmRhdGEpOyAgLy8gVE9ETyA6IG1heWJlIHVzZSB0aGUgYnJvd3NlcidzIEZvcm1EYXRhIG9iamVjdCwgYW5kIGhhbmRsZSBJRSBhcyB3ZSBhcmUgZG9pbmcgbm93CiAgICAgICAgICAgICAgICBvcHRpb25zLmRhdGEgPSBzdHJDb250ZW50WzFdOwogICAgICAgICAgICAgICAgdmFyIHBhcmFtcyA9IF8uZXh0ZW5kKHsKICAgICAgICAgICAgICAgICAgICAgICAgYmVmb3JlU2VuZDogZm9ybUJyaWRnZS51aUZyZWV6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGU6IGZvcm1CcmlkZ2UudWlVbkZyZWV6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgYXN5bmM6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICB1cmw6IHN1Ym1pdFNlcnZpY2VQcm94eVVybCwKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ1BPU1QnLAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzRGF0YTogZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFR5cGU6ICJtdWx0aXBhcnQvZm9ybS1kYXRhOyBjaGFyc2V0PVVURi04OyBib3VuZGFyeT0iICsgc3RyQ29udGVudFswXQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyk7CgogICAgICAgICAgICAgICAgJC5hamF4KHBhcmFtcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqIFRoaXMgZnVuY3Rpb24gZG9lcyBmb2xsb3dpbmc6CiAgICAgICAgICogYSkgT24gZmlyc3QgY2FsbCwgaXQgY3JlYXRlcyB0aGUgdXVpZCBzdG9yYWdlIGFuZCByZXR1cm5zIHRoZSBVVUlECiAgICAgICAgICogYikgT24gc3Vic2VxdWVudCBjYWxscywgaXQganVzdCByZXR1cm5zIHRoZSB1dWlkCiAgICAgICAgICogYykgaWYgdXVpZCBpcyBub3QgY3JlYXRlZCB0aGVuIGl0IHJldHVybnMgbnVsbAogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgX2dldFVVSUQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYodGhpcy5fZm9ybUluc3RhbmNlVVVJRCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Zvcm1JbnN0YW5jZVVVSUQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9HZW5lcmF0ZSB0aGUgVVVJRCBmb3IgdGhlIGZvcm0gaW5zdGFuY2Ugb24gY2xpZW50IHNpZGUKICAgICAgICAgICAgdmFyIHV1aWQgPSAkKCdib2R5I2Zvcm1Cb2R5JykuZGF0YSgidG1wcm9vdCIpLAogICAgICAgICAgICAgICAgdXVpZFN1ZmZpeCA9IE1hdGguZmxvb3IoKE1hdGgucmFuZG9tKCkgKiAxMDAwMCkgKyAxKSwKICAgICAgICAgICAgICAgIHV1aWRDdXJyZW50VGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpLAogICAgICAgICAgICAgICAgc3VjY2Vzc0ZsYWcgPSB0cnVlOwogICAgICAgICAgICB0aGlzLl9mb3JtSW5zdGFuY2VVVUlEID0gdXVpZCArICJfIiArIHV1aWRDdXJyZW50VGltZSArIHV1aWRTdWZmaXg7CiAgICAgICAgICAgIHN1Y2Nlc3NGbGFnID0gY3JlYXRlVVVJRFN0b3JhZ2UodGhpcy5fZm9ybUluc3RhbmNlVVVJRCk7CiAgICAgICAgICAgIGlmKHN1Y2Nlc3NGbGFnKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9mb3JtSW5zdGFuY2VVVUlEOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIF9nZXRVcmw6IGZ1bmN0aW9uICh1cmwpIHsKICAgICAgICAgICAgLy91cmwgcHJvdmlkZWQgY2FuIGNvbnRhaW4gdGhlIGhvc3RuYW1lIGFuZCBwb3J0IHRvbywgaW4gdGhhdCBjYXNlIHJldHVybiB0aGUgdXJsIGFzIGl0IGlzCiAgICAgICAgICAgIGlmICh1cmwuaW5kZXhPZigiaHR0cDoiKSA9PSAwIHx8IHVybC5pbmRleE9mKCJodHRwczoiKSA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdXJsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBiYXNlVXJsID0gdGhpcy51c2VyQ29uZmlnWyJiYXNlVXJsIl0sCiAgICAgICAgICAgICAgICBjb250ZXh0UGF0aCA9IHRoaXMudXNlckNvbmZpZ1siY29udGV4dFBhdGgiXTsKICAgICAgICAgICAgaWYgKGJhc2VVcmwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBiYXNlVXJsICsgdXJsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKGNvbnRleHRQYXRoICYmIGNvbnRleHRQYXRoIT09ICIvIiAmJiB1cmwuaW5kZXhPZihjb250ZXh0UGF0aCkhPT0gMCAmJih1cmwubGVuZ3RoID09PTAgfHwgdXJsLmluZGV4T2YoIi8iKSA9PT0gMCkpewogICAgICAgICAgICAgICAgLy9pZiB1cmwgZG9lcyBub3QgaGF2ZSBjb250ZXh0UGF0aCBhbmQgc3RhcnRzIHdpdGggLywgcHJlLXBlbmQgY29udGV4dFBhdGgKICAgICAgICAgICAgICAgIC8vIEFsc28gdXJsLmxlbmd0aCBjaGVjayBiZWNhdXNlIEkgbmVlZCB0byBwYXNzICIiIHRvIGdldFVybCBhbmQgZ2V0IGNvbnRleHQgcGF0aAogICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHRQYXRoICsgdXJsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB1cmw7CiAgICAgICAgfSwKICAgICAgICBnZXRGaWxlQXR0YWNobWVudHNJbmZvOiBmdW5jdGlvbiAob3B0aW9ucykgewogICAgICAgICAgICB2YXIgZmlsZUF0dGFjaG1lbnRzTGlzdCA9IFtdLAogICAgICAgICAgICAgICAgbGlzdDsKCgogICAgICAgICAgICBmdW5jdGlvbiBjb2xsZWN0RmlsZVVybHMoZXZlbnQpIHsKICAgICAgICAgICAgICAgIGxpc3QgPSBbXTsKICAgICAgICAgICAgICAgIC8vVE9ETzogbmVlZCB0byBtb2R1bGFyaXplIGNvbGxlY3RGaWxlVXJzKCkKICAgICAgICAgICAgICAgIC8vIGhlcmUgdGhpcyBpcyB0aGUgY29udGV4dCBvZiB0aGUgZnVuY3Rpb24gd2hvIGNhbGxzIGl0CiAgICAgICAgICAgICAgICBfLmVhY2godGhpcy5hdHRhY2htZW50cywgZnVuY3Rpb24gKGF0dCkgewogICAgICAgICAgICAgICAgICAgIC8vdGhpcy5maWxlVXJsIGlzIG51bGwgd2hlbiBubyBmaWxlIGlzIHVwbG9hZGVkLiBhdHQgY29udGFpbnMgcGF0aCAtICJmaWxldXBsb2FkL+KEomEuanBnIiBpZiBub3QgdXBsb2FkZWQKICAgICAgICAgICAgICAgICAgICAvLyBpZiBhdHQgc3RhcnRzIHdpdGggIi8iLCB0aGlzIG1lYW5zIHRoYXQgdGhlIGF0dGFjaG1lbnQgaGFzIGFscmVhZHkgYmVlbiB1cGxvYWRlZC4KICAgICAgICAgICAgICAgICAgICBpZighXy5pc0VtcHR5KHRoaXMuZmlsZVVybCkgJiYgYXR0LmluZGV4T2YoIi8iKSE9MCApIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5wdXNoKHtuYW1lOiBhdHQuc3BsaXQoIi8iKVsxXSwgcGF0aDogdGhpcy5maWxlVXJsICsgIi8iICsgYXR0fSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGlzdC5wdXNoKHtuYW1lOiBhdHQuc3Vic3RyaW5nKGF0dC5sYXN0SW5kZXhPZigiLyIpKzEpLCBwYXRoOiBhdHR9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5zdWNjZXNzLmNhbGwodGhpcy5vcHRpb25zLmNvbnRleHQsIGxpc3QpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLl9nZXRBdHRhY2htZW50cyhmaWxlQXR0YWNobWVudHNMaXN0LCBvcHRpb25zLmZpbGVVcGxvYWRQYXRoIHx8IHRoaXMuZ2V0VGVtcFBhdGgoKSwgY29sbGVjdEZpbGVVcmxzLCBvcHRpb25zKTsKCiAgICAgICAgfSwKCiAgICAgICAgX2dldEF0dGFjaG1lbnRzOiBmdW5jdGlvbiAoZmlsZUF0dGFjaG1lbnREb21FbGVtZW50LCBmaWxlVXBsb2FkUGF0aCwgY2FsbGJhY2ssIG9wdGlvbnMpIHsKCiAgICAgICAgICAgIHZhciBhbGxGaWxlcyA9IFtdLAogICAgICAgICAgICAgICAgYXR0YWNobWVudHMgPSBbXSwKICAgICAgICAgICAgICAgIGZpbGVVcmwgPSBudWxsLAogICAgICAgICAgICAgICAgZmlsZUNvdW50ID0gMCwKICAgICAgICAgICAgICAgIGRpZFN1Ym1pdCA9IGZhbHNlLAogICAgICAgICAgICAgICAgY29udGV4dFJvb3QgPSB0aGlzLl9nZXRDb250ZXh0Um9vdCgpLAogICAgICAgICAgICAgICAgRklMRV9DT01QT05FTlRfTkFNRSA9ICJmaWxldXBsb2FkIjsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEluIHRoZSBjYXNlIG9mIGRyYWZ0LCB1cmwgY29tZXMgd2l0aCBjb250ZXh0IHJvb3QuIE5lZWQgdG8gcmVtb3ZlIGl0IHNvIHRoYXQgY29ycmVjdCB2YWx1ZSBnZXRzIHN0b3JlZCBpbiBtb2RlbAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKGNvbnRleHRSb290KSB7CiAgICAgICAgICAgICAgICBpZiAoZmlsZVVwbG9hZFBhdGguaW5kZXhPZihjb250ZXh0Um9vdCkgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICBmaWxlVXBsb2FkUGF0aCA9IGZpbGVVcGxvYWRQYXRoLnN1YnN0cmluZyhjb250ZXh0Um9vdC5sZW5ndGgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgY3VycmVudENvdW50ID0gMDsKICAgICAgICAgICAgdmFyIGZpbGVOYW1lTGlzdCA9IGZvcm1CcmlkZ2UuX2dldENvbW1pdFZhbHVlRnJvbUZpbGVXaWRnZXQoKTsKCiAgICAgICAgICAgIGlmIChmaWxlTmFtZUxpc3QubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgdmFyIGZpbGVOYW1lcyA9IGZpbGVOYW1lTGlzdDsKICAgICAgICAgICAgICAgIHZhciBmaWxlTGlzdCA9ICQuZXh0ZW5kKHRydWUsIFtdLCBmb3JtQnJpZGdlLl9nZXRGaWxlTGlzdEZyb21GaWxlV2lkZ2V0KCkpOwogICAgICAgICAgICAgICAgXy5lYWNoKGZpbGVMaXN0LCBmdW5jdGlvbiAoZmlsZSwgaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZU9mRmlsZSA9IGZpbGVOYW1lc1tpbmRleF0sCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlTmFtZU9mRmlsZSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWVPZkZpbGUgIT0gbnVsbCAmJiBmaWxlICE9IG51bGwpIHsgLy9maWxlIGNhbiBiZSBudWxsIHdoZW4geW91IGNsaWNrIHNhdmUgdHdvIHRpbWVzIGNvbnRpbnVvdXNseSB3aXRob3V0IGNoYW5nZSBpbiBndWlkZSBjb250ZXh0CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlTmFtZU9mRmlsZSA9IEZJTEVfQ09NUE9ORU5UX05BTUUgKyAiLyIgKyBuYW1lT2ZGaWxlOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBjYXNlOiBpZiB0aGVyZSBpcyBhIGZpbGUgZG9tZQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV8uaXNTdHJpbmcoZmlsZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSB2YWx1ZSBleGlzdCBpbiB0aGUgZmlsZSwgdGhpcyBpcyBkb25lIGJlY2F1c2UgaW4gSUU5IGFuZCBJRTEwIHRoZSBsaXN0IHdpbGwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGhhdmUgYW4gZXh0cmEgZW1wdHkgZG9tCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJChmaWxlKS52YWwoKS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJChmaWxlKS5hdHRyKCduYW1lJywgY29tcGxldGVOYW1lT2ZGaWxlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRhY2htZW50c1tmaWxlQ291bnRdID0gY29tcGxldGVOYW1lT2ZGaWxlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbEZpbGVzW2ZpbGVDb3VudCsrXSA9ICQoZmlsZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaW5jZSB0aGVyZSBpcyBubyBmaWxlIGRvbSBpbiBjYXNlIG9mIGRyYWZ0IHVzZWNhc2UsIG1ha2UgaXQgbnVsbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0YWNobWVudHNbZmlsZUNvdW50XSA9IGZpbGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxGaWxlc1tmaWxlQ291bnQrK10gPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwgdGhpcyk7CgoKICAgICAgICAgICAgICAgIGlmIChhbGxGaWxlcy5sZW5ndGggPiAwKSB7CgogICAgICAgICAgICAgICAgICAgIC8vIHNpbmNlIHRoZXJlIGNhbiBiZSBhIGRvbSBlbGVtZW50IHdoaWNoIGlzIG51bGwsIGluIGNhc2Ugb2YgZHJhZnQgdXNlY2FzZQogICAgICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgZmlyc3Qgbm9uIG51bGwgZmlsZSBkb20KICAgICAgICAgICAgICAgICAgICB2YXIgZmlyc3ROb25OdWxsRmlsZURvbSA9IF8uaW5kZXhPZihhbGxGaWxlcywgXy5maW5kKGFsbEZpbGVzLCBmdW5jdGlvbiAoaXRlbSkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlbSAhPT0gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9KSk7CiAgICAgICAgICAgICAgICAgICAgdmFyIHVwbG9hZGVyUGx1Z2luTmFtZSA9IGZvcm1CcmlkZ2UudXNlckNvbmZpZy51cGxvYWRlclBsdWdpbk5hbWUgfHwgImFkb2JlRmlsZVVwbG9hZGVyIjsKICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3ROb25OdWxsRmlsZURvbSAhPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVVybCA9IGFsbEZpbGVzW2ZpcnN0Tm9uTnVsbEZpbGVEb21dW3VwbG9hZGVyUGx1Z2luTmFtZV0oInVwbG9hZEZpbGUiLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZmlsZU5hbWUnOiBhdHRhY2htZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmaWxlRG9tJzogYWxsRmlsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZmlsZVVwbG9hZFBhdGgnOiBmaWxlVXBsb2FkUGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdtdWx0aXBsZSc6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnX3V1aWRHZW5lcmF0b3InOiBmdW5jdGlvbiAoKSB7IHJldHVybiBmb3JtQnJpZGdlLl9nZXRVVUlELmFwcGx5KHRoaXMpOyB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgX2dldFVybDogZm9ybUJyaWRnZS5fZ2V0VXJsKCIiKQogICAgICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8qVGhlIGZpbGUgdXJsIHJldHVybmVkIGJ5IGZpbGUgdXBsb2FkIHdpZGdldCBjYW4gY29udGFpbiBjb250ZXh0IHJvb3QuIFJlbW92ZSBpdCBzbyB0aGF0IGNvcnJlY3QgdmFsdWUgZ2V0cyBzdG9yZWQgaW4gbW9kZWwuKi8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRleHRSb290KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZVVybC5pbmRleE9mKGNvbnRleHRSb290KSA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVVcmwgPSBmaWxlVXJsLnN1YnN0cmluZyhjb250ZXh0Um9vdC5sZW5ndGgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBhbGxGaWxlc1tmaXJzdE5vbk51bGxGaWxlRG9tXS5vbmUoImFkb2JlRmlsZVVwbG9hZGVyLm11bHRpcGxlRmlsZVVwbG9hZGVkIiwgJC5wcm94eShjYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYXR0YWNobWVudHMiOiBhdHRhY2htZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlsZVVybCI6IGZpbGVVcmwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9wdGlvbnMiOiBvcHRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfdXVpZEdlbmVyYXRvciI6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZvcm1CcmlkZ2UuX2dldFVVSUQuYXBwbHkodGhpcyk7IH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRpZFN1Ym1pdCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFkaWRTdWJtaXQpIHsKICAgICAgICAgICAgICAgIC8vIGlmIHRoZXJlIGFyZSBubyBmaWxlcyBhdHRhY2hlZCwgc3RpbGwgY2FsbCB0aGUgY2FsbGJhY2sgdG8gc3VibWl0IHRoZSBqc29uIGNvbnRlbnRzCiAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBvbmx5IG9uZSBmaWxlIGF0dGFjaG1lbnQgY29tcG9uZW50IHdpdGggbm8gZmlsZXMsIGluIHRoaXMgY2FzZSBlbHNlIGlzIGltcG9ydGFudAogICAgICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkoewogICAgICAgICAgICAgICAgICAgICJhdHRhY2htZW50cyI6IGF0dGFjaG1lbnRzLAogICAgICAgICAgICAgICAgICAgICJmaWxlVXJsIjogZmlsZVVybCwKICAgICAgICAgICAgICAgICAgICAib3B0aW9ucyI6IG9wdGlvbnMKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgfQoKICAgICAgICB9LAogICAgICAgIF9pc0ZpbGVBdHRhY2htZW50RW5hYmxlZDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4geGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dC5tZkFsbG93QXR0YWNobWVudHMgPT09ICd0cnVlJzsKICAgICAgICB9LAogICAgICAgIF9pc0xvZ2luQW5vbnltb3VzOiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgdmFyIGZsYWc7CiAgICAgICAgICAgICAgICBpZih4ZmFsaWIucnVudGltZSkgewogICAgICAgICAgICAgICAgICAgIGZsYWcgPSB4ZmFsaWIucnVudGltZS5faXNBbm9ueW1vdXM7CiAgICAgICAgICAgICAgICAgICAgaWYoXy5pc1VuZGVmaW5lZCh2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZsYWc7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLl9pc0Fub255bW91cyA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBmbGFnOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9nZXRDb250ZXh0Um9vdDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnVzZXJDb25maWdbImNvbnRleHRQYXRoIl07CiAgICAgICAgfSwKCiAgICAgICAgZ2V0VGVtcFBhdGg6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gIi90bXAvZmQveGZhZm9ybXMvIiArIHRoaXMuX2dldFVVSUQoKTsKICAgICAgICB9LAogICAgICAgIF9nZXRGaWxlTmFtZVBhdGhNYXA6IGZ1bmN0aW9uKHZhbHVlTGlzdCkgewogICAgICAgICAgICB2YXIgZmlsZVdpZGdldCA9IHRoaXMuX2dldEZpbGVXaWRnZXRJZlByZXNlbnQoKTsKICAgICAgICAgICAgaWYoZmlsZVdpZGdldCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZpbGVXaWRnZXQuX2dldEZpbGVOYW1lUGF0aE1hcCh2YWx1ZUxpc3QpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB7fTsKICAgICAgICB9LAoKCgoKCgogICAgICAgIGdldE11bHRpcGFydERhdGE6IGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgICAgIC8vU3RhcnQgbXVsdGlwYXJ0IGZvcm1hdHRpbmcKICAgICAgICAgICAgdmFyIGluaXRCb3VuZGFyeSA9IHRoaXMucmFuZG9tU3RyaW5nKCk7CiAgICAgICAgICAgIHZhciBzdHJCb3VuZGFyeSA9ICItLSIgKyBpbml0Qm91bmRhcnk7CiAgICAgICAgICAgIHZhciBzdHJNdWx0aXBhcnRCb2R5ID0gIiI7CiAgICAgICAgICAgIHZhciBzdHJDUkxGID0gIlxyXG4iOwoKICAgICAgICAgICAgLy9DcmVhdGUgbXVsdGlwYXJ0IGZvciBlYWNoIGVsZW1lbnQgb2YgdGhlIGZvcm0KICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIGRhdGEpIHsKICAgICAgICAgICAgICAgIGlmIChkYXRhLmhhc093blByb3BlcnR5KGtleSkpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSB0eXBlb2YgZGF0YVtrZXldID09ICJzdHJpbmciID8gZGF0YVtrZXldIDogSlNPTi5zdHJpbmdpZnkoZGF0YVtrZXldKTsKICAgICAgICAgICAgICAgICAgICBzdHJNdWx0aXBhcnRCb2R5ICs9CiAgICAgICAgICAgICAgICAgICAgICAgIHN0ckJvdW5kYXJ5CiAgICAgICAgICAgICAgICAgICAgICAgICsgc3RyQ1JMRgogICAgICAgICAgICAgICAgICAgICAgICArICJDb250ZW50LURpc3Bvc2l0aW9uOiBmb3JtLWRhdGE7IG5hbWU9XCIiICsga2V5ICsgIlwiIgogICAgICAgICAgICAgICAgICAgICAgICArIHN0ckNSTEYKICAgICAgICAgICAgICAgICAgICAgICAgKyBzdHJDUkxGCiAgICAgICAgICAgICAgICAgICAgICAgICsgdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgKyBzdHJDUkxGOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vRW5kIHRoZSBib2R5IGJ5IGRlbGltaXRpbmcgaXQKICAgICAgICAgICAgc3RyTXVsdGlwYXJ0Qm9keSArPSBzdHJCb3VuZGFyeSArICItLSIgKyBzdHJDUkxGOwogICAgICAgICAgICAvL1JldHVybiBib3VuZGFyeSB3aXRob3V0IC0tIGFuZCB0aGUgbXVsdGlwYXJ0IGNvbnRlbnQKICAgICAgICAgICAgcmV0dXJuIFtpbml0Qm91bmRhcnksIHN0ck11bHRpcGFydEJvZHldOwogICAgICAgIH0sCgogICAgICAgIHJhbmRvbVN0cmluZzogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgY2hhcnMgPSAiMDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFRaYWJjZGVmZ2hpa2xtbm9wcXJzdHV2d3h5eiI7CiAgICAgICAgICAgIHZhciBzdHJpbmdfbGVuZ3RoID0gODsKICAgICAgICAgICAgdmFyIHJhbmRvbVN0cmluZyA9ICcnOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZ19sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIHJudW0gPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBjaGFycy5sZW5ndGgpOwogICAgICAgICAgICAgICAgcmFuZG9tU3RyaW5nICs9IGNoYXJzLnN1YnN0cmluZyhybnVtLCBybnVtICsgMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJhbmRvbVN0cmluZzsKICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIHJldHVybnMgdGhlIGlucHV0IGRhdGEgaW4gWE1MIEZvcm0uIFRoZSBjYWxsIGlzIGFzeW5jaHJvbm91cyBhbmQgcmVjaWV2ZXMgdGhlIGZvbGxvd2luZyBvcHRpb25zIGFwYXJ0IGZyb20gdGhlIGRlZmF1bHQKICAgICAgICAgKiBvbmVzIHByb3ZpZGVkIGVhcmxpZXIKICAgICAgICAgKiAgICAgIHZhbGlkYXRpb25DaGVja2VyIC8vZnVuY3Rpb24gdG8gY2FsbCBmb3IgY2hlY2tpbmcgdmFsaWRhdGlvbiBlcnJvcnMgcmVjZWl2ZWQgZnJvbSBzZXJ2ZXIKICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgVGhlIHNpZ25hdHVyZSBmb3IgdGhlIGZ1bmN0aW9ucyBpcwogICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24odmFsaWRhdGlvbnMpCiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFsaWRhdGlvbnMgaXMgYW4gYXJyYXkgb2YgZXJyb3Igc3RyaW5ncy4KICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgKiAgICAgIGZvcm1TdGF0ZSAgICAgICAvLyBUaGUgc3RhdGUgb2YgdGhlIFhGQSBGb3JtLCBpZiBzYXZlZCBieSB0aGUgdXNlciwgb3RoZXJ3aXNlIHRoZSBjdXJyZW50IG9uZQogICAgICAgICAqLwogICAgICAgIGdldERhdGFYTUw6IGZ1bmN0aW9uIChvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwogICAgICAgICAgICBpZiAoIW9wdGlvbnMuZm9ybVN0YXRlICYmICF0aGlzLl9jaGVja1hmYShvYmopKSB7CiAgICAgICAgICAgICAgICBvcHRpb25zLmVycm9yLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKCFvcHRpb25zLmZvcm1TdGF0ZSAmJiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0T3JFbHNlKHhmYWxpYi5ydW50aW1lLCAiY3VzdG9tUHJvcGVydHlNYXAueG1sT25DbGllbnQiLCAiMCIpID09PSAiMSIpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHhtbCA9IHRoaXMuZ2VuZXJhdGVEYXRhWE1MKCk7CiAgICAgICAgICAgICAgICAgICAgb2JqLmRhdGEgPSB4bWw7CiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnN1Y2Nlc3MuY2FsbChvcHRpb25zLmNvbnRleHQsIG9iaik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaChleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbXNnID0gIlVuYWJsZSB0byBnZW5lcmF0ZSB4bWwgb24gY2xpZW50LiBVc2UgU2VydmVyIG9wdGlvbiB0byBnZW5lcmF0ZSB0aGUgeG1sLiAiICsgZXhjZXB0aW9uOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYS5Mb2dnZXIuZXJyb3IoInhmYSIsIG1zZyk7CiAgICAgICAgICAgICAgICAgICAgb2JqLmNvbXBsZXRlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDIsIG1zZywgIiIpOwogICAgICAgICAgICAgICAgICAgIGlmKG9wdGlvbnMuZXJyb3IpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5lcnJvci5hcHBseShvcHRpb25zLmNvbnRleHQsIFtvYmpdKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGZvcm1TdGF0ZSA9IG9wdGlvbnMuZm9ybVN0YXRlIHx8IHRoaXMuZ2V0Rm9ybVN0YXRlKHRydWUsIDIpLmRhdGE7CiAgICAgICAgICAgIC8vY2xvbmUgdGhlIG9iamVjdCB0byBhdm9pZCBwb2xsdXRpbmcgdGhlIG9sZCBjb3B5CiAgICAgICAgICAgIHZhciBwYXJhbXMgPSBfLmV4dGVuZCh7Zm9ybURvbTogZm9ybVN0YXRlLnhmYURvbSwgcmVxdWVzdERhdGFYbWwgOiAidHJ1ZSJ9LCBmb3JtU3RhdGUucmVuZGVyQ29udGV4dCk7CiAgICAgICAgICAgIHRoaXMuX2ludm9rZUF0U2VydmVyKHsKICAgICAgICAgICAgICAgIGRhdGE6IHBhcmFtcywKICAgICAgICAgICAgICAgIGRhdGFUeXBlOiAndGV4dCcsCiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAocmVzdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgb2JqLmNvbXBsZXRlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFyZXN1bHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMCwgIlRoZXJlIHdhcyBhbiBlcnJvciBpbiBnZXR0aW5nIGRhdGEgeG1sIiwgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmVycm9yLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG9iai5kYXRhID0gcmVzdWx0OwogICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnZhbGlkYXRpb25DaGVja2VyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghb3B0aW9ucy52YWxpZGF0aW9uQ2hlY2tlci5jYWxsKG9wdGlvbnMuY29udGV4dCwgcmVzdWx0LnZhbGlkYXRpb25FcnJvcnMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmVycm9yLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnN1Y2Nlc3MpCiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuc3VjY2Vzcy5jYWxsKG9wdGlvbnMuY29udGV4dCwgb2JqLGZvcm1TdGF0ZSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICh4aHIsIHR4dFN0YXR1cywgZXJyb3JUaHJvd24pIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbXNnID0gZm9ybUJyaWRnZS5fZ2V0RGF0YVhNTEVycm9yKHhociwgdHh0U3RhdHVzLCBlcnJvclRocm93bik7CiAgICAgICAgICAgICAgICAgICAgb2JqLmNvbXBsZXRlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDIsIG1zZywgIiIpOwogICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmVycm9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuZXJyb3IuY2FsbChvcHRpb25zLmNvbnRleHQsIG9iaik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChmb3JtQnJpZGdlLl94ZmEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUJyaWRnZS5feGZhLmhvc3QubWVzc2FnZUJveChtc2cpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldERhdGFYTUxFcnJvcjogZnVuY3Rpb24gKHhociwgdHh0U3RhdHVzLCBlcnJvclRocm93bikgewogICAgICAgICAgICB2YXIgbXNnOwogICAgICAgICAgICBzd2l0Y2ggKHhoci5zdGF0dXMpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgICBtc2cgPSB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDgiXTsKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl94ZmEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhLkxvZ2dlci5lcnJvcigieGZhIiwgbXNnICsgIiAiICsgeGhyLnN0YXR1c1RleHQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgbXNnID0geGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDE2Il07CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5feGZhKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYS5Mb2dnZXIuZXJyb3IoInhmYSIsIG1zZyArICIgIiArIHhoci5zdGF0dXNUZXh0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG1zZzsKCiAgICAgICAgfSwKCiAgICAgICAgX2lkZW50aWZ5Q29ubmVjdGlvbkVycm9yOiBmdW5jdGlvbiAoeGhyLCB0eHRTdGF0dXMpIHsKICAgICAgICAgICAgdmFyIG1zZyA9ICIiOwogICAgICAgICAgICBzd2l0Y2ggKHhoci5zdGF0dXMpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgICBtc2cgPSB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDgiXTsKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl94ZmEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhLkxvZ2dlci5lcnJvcigieGZhIiwgbXNnICsgIiAiICsgeGhyLnN0YXR1c1RleHQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgNDA0OgogICAgICAgICAgICAgICAgICAgIG1zZyA9IHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAwOCJdOwogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX3hmYSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEuTG9nZ2VyLmVycm9yKCJ4ZmEiLCBtc2cgKyAiICIgKyB4aHIuc3RhdHVzVGV4dCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBtc2c7CgoKICAgICAgICB9LAoKICAgICAgICBfZ2V0QWxsb3dBdHRhY2htZW50c0Zyb21Gb3JtU3RhdGU6IGZ1bmN0aW9uIChmb3JtU3RhdGUpIHsKICAgICAgICAgICAgcmV0dXJuIGZvcm1TdGF0ZS5yZW5kZXJDb250ZXh0Lm1mQWxsb3dBdHRhY2htZW50cyA9PT0gJ3RydWUnOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwdWJsaWMKICAgICAgICAgKiBUaGlzIHBlcmZvcm1zIGFuIGFqYXggc3VibWl0IHRvIGEgdXJsLgogICAgICAgICAqIFRoaXMgQVBJIGNyZWF0ZXMgYSBmb3JtIGRhdGEgb2JqZWN0IGFuZCBzdWJtaXRzIHRoaXMgb2JqZWN0LgogICAgICAgICAqIEBwYXJhbSBvcHRpb25zCiAgICAgICAgICovCiAgICAgICAgZG9BamF4U3VibWl0OiBmdW5jdGlvbihvcHRpb25zKXsKCiAgICAgICAgICAgIGlmKHdpbmRvdy5Gb3JtRGF0YSl7CgogICAgICAgICAgICAgICAgdmFyIHBzdWVkb0Zvcm0gPSAkKCI8Zm9ybT4iKSwKICAgICAgICAgICAgICAgICAgICBmb3JtU3RhdGUgPSBvcHRpb25zLmZvcm1TdGF0ZSB8fCB0aGlzLmdldEZvcm1TdGF0ZSh0cnVlLCAyKS5kYXRhLAogICAgICAgICAgICAgICAgICAgIHN1Ym1pdFNlcnZpY2VQcm94eUNvbmZpZyA9IGZvcm1TdGF0ZS5hZGRpdGlvbmFsU3VibWl0SW5mb3JtYXRpb24udXNlckNvbmZpZ1sic3VibWl0U2VydmljZVByb3h5Q29uZmlnIl0sCiAgICAgICAgICAgICAgICAgICAgYWN0aW9uID0gb3B0aW9ucy5hY3Rpb24gfHwgdGhpcy5fZ2V0U3VibWl0U2VydmljZVByb3h5VXJsKCk7CgogICAgICAgICAgICAgICAgXy5lYWNoKGZvcm1TdGF0ZS5hZGRpdGlvbmFsU3VibWl0SW5mb3JtYXRpb24uZm9ybUF0dHJpYnV0ZXNEYXRhLCBmdW5jdGlvbiAodmFsdWUsIGtleSkgewogICAgICAgICAgICAgICAgICAgIHBzdWVkb0Zvcm0uYXR0cihrZXksIHZhbHVlKTsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwoKICAgICAgICAgICAgICAgIHBzdWVkb0Zvcm0uYXR0cigiYWN0aW9uIiwgYWN0aW9uKTsKICAgICAgICAgICAgICAgIHZhciAkY2hhclNldEZpZWxkID0gJCgiPGlucHV0PiIpLmF0dHIoeyJ0eXBlIjogImhpZGRlbiIsICJuYW1lIjogIl9jaGFyc2V0XyIsICJ2YWx1ZSI6ICJVVEYtOCJ9KTsKICAgICAgICAgICAgICAgICQocHN1ZWRvRm9ybSkuYXBwZW5kKCRjaGFyU2V0RmllbGQpOwoKICAgICAgICAgICAgICAgIF8uZWFjaChzdWJtaXRTZXJ2aWNlUHJveHlDb25maWcsIGZ1bmN0aW9uIChmaWVsZFZhbHVlLCBmaWVsZE5hbWUpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbmV3RmllbGQgPSAkKCI8aW5wdXQ+IikuYXR0cigidHlwZSIsICJoaWRkZW4iKQogICAgICAgICAgICAgICAgICAgICAgICAuYXR0cigibmFtZSIsIGZpZWxkTmFtZSkKICAgICAgICAgICAgICAgICAgICAgICAgLnZhbChmaWVsZFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAkKHBzdWVkb0Zvcm0pLmFwcGVuZCgkKG5ld0ZpZWxkKSk7CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAvL2Nsb25lIHRoZSBvYmplY3QgdG8gYXZvaWQgcG9sbHV0aW5nIHRoZSBvbGQgY29weQogICAgICAgICAgICAgICAgdmFyIHBhcmFtcyA9IF8uZXh0ZW5kKHt9LCBmb3JtU3RhdGUuY3VzdG9tUHJvcGVydHlNYXAsIHtmb3JtRG9tOiBmb3JtU3RhdGUueGZhRG9tfSwgZm9ybVN0YXRlLnJlbmRlckNvbnRleHQpOwoKICAgICAgICAgICAgICAgIGZvciAodmFyIHBhcmFtIGluIHBhcmFtcykgewogICAgICAgICAgICAgICAgICAgIGlmIChwYXJhbXMuaGFzT3duUHJvcGVydHkocGFyYW0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0ZpZWxkID0gJCgiPGlucHV0PiIpLmF0dHIoInR5cGUiLCAiaGlkZGVuIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJuYW1lIiwgcGFyYW0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudmFsKHBhcmFtc1twYXJhbV0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgJChwc3VlZG9Gb3JtKS5hcHBlbmQoJChuZXdGaWVsZCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgZmlsZUF0dGFjaG1lbnRFbmFibGVkID0gZm9ybUJyaWRnZS5fZ2V0QWxsb3dBdHRhY2htZW50c0Zyb21Gb3JtU3RhdGUoZm9ybVN0YXRlKTsKICAgICAgICAgICAgICAgIGlmIChmaWxlQXR0YWNobWVudEVuYWJsZWQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5maWxlQXR0YWNobWVudE1hcCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmlsZUF0dGFjaG1lbnRNYXBJbnB1dCA9ICQoIjxpbnB1dD4iKS5hdHRyKCJ0eXBlIiwgImhpZGRlbiIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYXR0cigibmFtZSIsICJmaWxlQXR0YWNobWVudE1hcCIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudmFsKEpTT04uc3RyaW5naWZ5KG9wdGlvbnMuZmlsZUF0dGFjaG1lbnRNYXApKTsKICAgICAgICAgICAgICAgICAgICAgICAgJChwc3VlZG9Gb3JtKS5hcHBlbmQoJChmaWxlQXR0YWNobWVudE1hcElucHV0KSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZpbGVBdHRhY2htZW50TWFwID0gZm9ybUJyaWRnZS5fZ2V0RmlsZU5hbWVQYXRoTWFwKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlQXR0YWNobWVudElucHV0cyA9IGZvcm1CcmlkZ2UuX2dldEZpbGVMaXN0RnJvbUZpbGVXaWRnZXQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVBdHRhY2htZW50TWFwSW5wdXQ7CgogICAgICAgICAgICAgICAgICAgICAgICBfLmVhY2goZm9ybUJyaWRnZS5fZ2V0Q29tbWl0VmFsdWVGcm9tRmlsZVdpZGdldCgpLCBmdW5jdGlvbiAobmFtZU9mRmlsZSwgaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfLmlzT2JqZWN0KGZpbGVBdHRhY2htZW50SW5wdXRzW2luZGV4XSkgJiYgXy5pc1N0cmluZyhuYW1lT2ZGaWxlKSAmJiAhbmFtZU9mRmlsZS5tYXRjaCgvXC8vZykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlQXR0YWNobWVudElucHV0c1tpbmRleF0uYXR0cigibmFtZSIsIG5hbWVPZkZpbGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZmlsZUF0dGFjaG1lbnRNYXBbbmFtZU9mRmlsZV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUF0dGFjaG1lbnRNYXBbbmFtZU9mRmlsZV0gPSAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJChwc3VlZG9Gb3JtKS5hcHBlbmQoZmlsZUF0dGFjaG1lbnRJbnB1dHNbaW5kZXhdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICBmaWxlQXR0YWNobWVudE1hcElucHV0ID0gJCgiPGlucHV0PiIpLmF0dHIoInR5cGUiLCAiaGlkZGVuIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJuYW1lIiwgImZpbGVBdHRhY2htZW50TWFwIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC52YWwoSlNPTi5zdHJpbmdpZnkoZmlsZUF0dGFjaG1lbnRNYXApKTsKICAgICAgICAgICAgICAgICAgICAgICAgJChwc3VlZG9Gb3JtKS5hcHBlbmQoJChmaWxlQXR0YWNobWVudE1hcElucHV0KSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy90aGUgWEZBUmVzdWx0T2JqZWN0IHRoYXQgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIHN1Y2Nlc3MgYW5kIGVycm9yIGhhbmRsZXIKICAgICAgICAgICAgICAgIHZhciBvYmogPSBuZXcgWEZBUmVzdWx0T2JqZWN0KCk7CgogICAgICAgICAgICAgICAgdmFyIGZkID0gbmV3IEZvcm1EYXRhKHBzdWVkb0Zvcm1bMF0pOwogICAgICAgICAgICAgICAgLy9zZXQgY29udGVudFR5cGUgdG8gZmFsc2UgdG8gcHJldmVudCBqcXVlcnkgZnJvbSBzZXR0aW5nIGl0IHRvIGRlZmF1bHQgdmFsdWUKICAgICAgICAgICAgICAgIC8vU2V0dGluZyBwcm9jZXNzRGF0YSB0byBmYWxzZSB0byBwcmV2ZW50IGpRdWVyeSBmcm9tIGF1dG9tYXRpY2FsbHkgdHJhbnNmb3JtaW5nIHRoZSBkYXRhIGludG8gYSBxdWVyeSBzdHJpbmcKICAgICAgICAgICAgICAgIC8vIHNldCBkYXRhVHlwZSB0byAidGV4dCIgdG8gcmV0cmlldmUgdGhlIHhtbCBhcyBzdHJpbmcuCiAgICAgICAgICAgICAgICAvLyBUaGUgYWpheCBjYWxsIHJldHVybnMgZGF0YVhtbCB0aGF0IGlzIHBhc3NlZCBpbnNpZGUgWEZBUmVzdWx0T2JqZWN0LgogICAgICAgICAgICAgICAgJC5hamF4KHsKICAgICAgICAgICAgICAgICAgICB1cmw6IGZvcm1CcmlkZ2UuX2dldFVybChhY3Rpb24pLAogICAgICAgICAgICAgICAgICAgIGRhdGE6IGZkLAogICAgICAgICAgICAgICAgICAgIHByb2Nlc3NEYXRhOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTondGV4dCcsCiAgICAgICAgICAgICAgICAgICAgY29udGVudFR5cGU6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIHR5cGU6ICdQT1NUJywKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAocmVzdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9iai5jb21wbGV0ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMCwgIlRoZXJlIHdhcyBhbiBlcnJvciBpbiBzdWJtaXR0aW5nIHRoZSBmb3JtIiwgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5lcnJvci5jYWxsKG9wdGlvbnMuY29udGV4dCwgb2JqKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBvYmouZGF0YSA9IHJlc3VsdDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMudmFsaWRhdGlvbkNoZWNrZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghb3B0aW9ucy52YWxpZGF0aW9uQ2hlY2tlci5jYWxsKG9wdGlvbnMuY29udGV4dCwgcmVzdWx0LnZhbGlkYXRpb25FcnJvcnMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5lcnJvci5jYWxsKG9wdGlvbnMuY29udGV4dCwgb2JqKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zdWNjZXNzLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKHhociwgdHh0U3RhdHVzLCBlcnJvclRocm93bikgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXNnID0gZm9ybUJyaWRnZS5fZ2V0RGF0YVhNTEVycm9yKHhociwgdHh0U3RhdHVzLCBlcnJvclRocm93bik7CiAgICAgICAgICAgICAgICAgICAgICAgIG9iai5jb21wbGV0ZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMiwgbXNnLCAiIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmVycm9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmVycm9yLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3JtQnJpZGdlLl94ZmEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1CcmlkZ2UuX3hmYS5ob3N0Lm1lc3NhZ2VCb3gobXNnKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG9wdGlvbnMuZXJyb3IuY2FsbChvcHRpb25zLmNvbnRleHQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBzdWJtaXRzIHRoZSBmb3JtIGRhdGEgdG8gYSB1cmwgcHJvdmlkZWQgaW4gQ29uZmlnIG9yIEZvcm0gVGVtcGxhdGUKICAgICAgICAgKiBUaGUgQVBJIGNhbGxzIGdldERhdGFYTUwsIGNoZWNrcyB2YWxpZGF0aW9uIGVycm9ycyBhbmQgZWl0aGVyIHN1Ym1pdHMgdGhlIGRhdGEgaXRzZWxmCiAgICAgICAgICogb3IgcGFzc2VzIHRoZSBkYXRhIHRvIHRoZSBzdWNjZXNzIGhhbmRsZXIgcHJvdmlkZWQgYnkgdGhlIGNhbGxlcgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgc3VibWl0Rm9ybTogZnVuY3Rpb24gKG9wdGlvbnMpIHsKICAgICAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CgkJCW9wdGlvbnMuZXJyb3IgPSBvcHRpb25zLmVycm9yIHx8IGRlZmF1bHRFcnJvckhhbmRsZXI7CiAgICAgICAgICAgIG9wdGlvbnMuY29udGV4dCA9IG9wdGlvbnMuY29udGV4dCB8fCBmb3JtQnJpZGdlOwogICAgICAgICAgICBvcHRpb25zLnZhbGlkYXRpb25DaGVja2VyID0gb3B0aW9ucy52YWxpZGF0aW9uQ2hlY2tlciB8fCBkZWZhdWx0VmFsaWRhdGlvbkNoZWNrZXI7CiAgICAgICAgICAgIC8vZm9ybUJyaWRnZS5rZXlWYWx1ZVBhaXJTdWJtaXNzaW9uID0gdHJ1ZTsKCiAgICAgICAgICAgIHRoaXMudWlGcmVlemUoKTsgICAvLyBCdWc6IExDLTYwNjggVG8gc2hvdyBjdXJzb3IgaW4gd2FpdCBzdGF0ZSBhbmQgYWxzbyBmcmVlemluZyB0aGUgdWkgYnkgbWFya2luZyByb290IHN1YmZvcm0gYWNjZXNzIGFzIHJlYWRPbmx5LgogICAgICAgICAgICB2YXIgb3JpZ2luYWxTdWNjZXNzID0gb3B0aW9ucy5zdWNjZXNzOwogICAgICAgICAgICB2YXIgb3JpZ2luYWxFcnJvciA9IG9wdGlvbnMuZXJyb3IgfHwgZGVmYXVsdEVycm9ySGFuZGxlcjsKICAgICAgICAgICAgdmFyIG9yaWdpbmFsQ29udGV4dCA9IG9wdGlvbnMuY29udGV4dDsKICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwoKICAgICAgICAgICAgb3B0aW9ucy5lcnJvciA9IChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHRoYXQudWlVbkZyZWV6ZSgpOyAgLy8gQnVnOiBMQy02MDY4IFRvIHJlc3RvcmUgY3Vyc29yIGZyb20gd2FpdCBzdGF0ZSBhbmQgYWxzbyByZXN0b3JpbmcgdGhlIHVpIGJ5IG1hcmtpbmcgcm9vdCBzdWJmb3JtIGFjY2VzcyBhcyBpdHMgb2xkIGFjY2Vzcy4KICAgICAgICAgICAgICAgICAgICBpZiAob3JpZ2luYWxFcnJvcikgewogICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbEVycm9yLmFwcGx5KG9yaWdpbmFsQ29udGV4dCwgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9KSgpOwogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwoKICAgICAgICAgICAgLy8gaWYgY2FuY2VsQWN0aW9uIHByb3BlcnR5IGlzIHNldCB0byB0cnVlIGluIHByZVN1Ym1pdCwgZXhlY1ByZVN1Ym1pdCByZXR1cm4gZmFsc2UKICAgICAgICAgICAgaWYgKHRoaXMuX3hmYSAmJiB0aGlzLl94ZmEuZm9ybS5leGVjUHJlU3VibWl0KCkgPT0gZmFsc2UgKSB7CiAgICAgICAgICAgICAgICB2YXIgbXNnID0gIlN1Ym1pdCBjYW5jZWxsZWQiOwogICAgICAgICAgICAgICAgdGhpcy5feGZhLmhvc3QubWVzc2FnZUJveChtc2cpOwogICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMCwgbXNnLCAieGZhIik7CiAgICAgICAgICAgICAgICBvcHRpb25zLmVycm9yLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5feGZhICYmIHRoaXMuX3hmYS5ob3N0Ll92YWxpZGF0ZSgpID09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICBvYmouYWRkTWVzc2FnZSgwLCAiY2xpZW50IHNpZGUgdmFsaWRhdGlvbnMgZmFpbGVkIiwgInhmYSIpOyAvL1RPRE86IGhhbmRsZXNvbUV4cHJlc3Npb24gcGFzc2luZwogICAgICAgICAgICAgICAgb3B0aW9ucy5lcnJvci5jYWxsKG9wdGlvbnMuY29udGV4dCwgb2JqKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5fdHJpZ2dlck9uQnJpZGdlKCJzdWJtaXRTdGFydCIsIHRoaXMsICJzdWJtaXQiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAob3B0aW9ucy5zdWNjZXNzIC8qfHwgZm9ybUJyaWRnZS5rZXlWYWx1ZVBhaXJTdWJtaXNzaW9uKi8pIHsKICAgICAgICAgICAgICAgIC8qdmFyIGRlZmF1bHRTdWNjZXNzSGFuZGxlciA9IGZ1bmN0aW9uKG9iaikgewogICAgICAgICAgICAgICAgIHZhciBmb3JtU3RhdGUgPSBvcHRpb25zLmZvcm1TdGF0ZSB8fCB0aGlzLmdldEZvcm1TdGF0ZSgpLmRhdGE7CiAgICAgICAgICAgICAgICAgLy9jbG9uZSB0aGUgb2JqZWN0IHRvIGF2b2lkIHBvbGx1dGluZyB0aGUgb2xkIGNvcHkKICAgICAgICAgICAgICAgICB2YXIgcGFyYW1zID0gXy5leHRlbmQoe2Zvcm1Eb206IGZvcm1TdGF0ZS54ZmFEb219LCBmb3JtU3RhdGUucmVuZGVyQ29udGV4dCk7CgogICAgICAgICAgICAgICAgIGZvcih2YXIgcCBpbiBwYXJhbXMpIHsKICAgICAgICAgICAgICAgICB2YXIgZmllbGQgPSAkKCI8aW5wdXQ+IikuYXR0cigidHlwZSIsICJoaWRkZW4iKS5hdHRyKCJuYW1lIixwKS52YWwocGFyYW1zW3BdKTsKICAgICAgICAgICAgICAgICAkKCIjbGNmb3Jtc194ZmFmb3JtX2NvbnRhaW5lciIpLmFwcGVuZCgkKGZpZWxkKSk7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIHZhciBkYXRhRmllbGQgPSAkKCI8aW5wdXQ+IikuYXR0cigidHlwZSIsICJoaWRkZW4iKS5hdHRyKCJuYW1lIiwiZGF0YSIpLnZhbChvYmouZGF0YSk7CiAgICAgICAgICAgICAgICAgJCgiI2xjZm9ybXNfeGZhZm9ybV9jb250YWluZXIiKS5hcHBlbmQoJChkYXRhRmllbGQpKTsKCiAgICAgICAgICAgICAgICAgdmFyIHN1Ym1pdFNlcnZpY2VQcm94eUNvbmZpZyA9IHRoaXMudXNlckNvbmZpZ1sic3VibWl0U2VydmljZVByb3h5Q29uZmlnIl07CiAgICAgICAgICAgICAgICAgdmFyIHN1Ym1pdFVybCA9IG9wdGlvbnMuYWN0aW9uIHx8IHN1Ym1pdFNlcnZpY2VQcm94eUNvbmZpZy5zdWJtaXRVcmw7CiAgICAgICAgICAgICAgICAgJCgiI2xjZm9ybXNfeGZhZm9ybV9jb250YWluZXIiKS5hdHRyKCJhY3Rpb24iLCBzdWJtaXRVcmwpOwogICAgICAgICAgICAgICAgICQoIiNsY2Zvcm1zX3hmYWZvcm1fY29udGFpbmVyIikuc3VibWl0KCk7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIG9wdGlvbnMuc3VjY2VzcyA9IG9wdGlvbnMuc3VjY2VzcyB8fCBkZWZhdWx0U3VjY2Vzc0hhbmRsZXIqLwogICAgICAgICAgICAgICAgLy9TdWJtaXQgZnJvbSBmb3JtIGJyaWRnZSBhcGkKCiAgICAgICAgICAgICAgICBvcHRpb25zLnN1Y2Nlc3MgPSAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQudWlVbkZyZWV6ZSgpOyAgLy8gQnVnOiBMQy02MDY4IFRvIHJlc3RvcmUgY3Vyc29yIGZyb20gd2FpdCBzdGF0ZSBhbmQgYWxzbyByZXN0b3JpbmcgdGhlIHVpIGJ5IG1hcmtpbmcgcm9vdCBzdWJmb3JtIGFjY2VzcyBhcyBpdHMgb2xkIGFjY2Vzcy4KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9yaWdpbmFsU3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxTdWNjZXNzLmFwcGx5KG9yaWdpbmFsQ29udGV4dCwgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgfSkoKTsKICAgICAgICAgICAgICAgIGZvcm1CcmlkZ2UuZG9BamF4U3VibWl0KG9wdGlvbnMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgLy9BbHdheXMgc3VibWl0IGZvcm0gc3RhdGUgdG8gc3VibWl0U2VydmljZVByb3h5IGFuZCB0aGVuIHRoZSBwcm94eSB3aWxsIGluLXR1cm4gc3VibWl0IHRoZSBkYXRhIHhtbCB0byB0aGUgc3VibWl0VXJsIG9uIGJlaGFsZiBvZiBNb2JpbGVGb3JtCiAgICAgICAgICAgICAgICAvL2NyZWF0ZSBhIHBzdWVkbyBmb3JtIGVsZW1lbnQgYW5kIGRvIHN1Ym1pc3Npb24KICAgICAgICAgICAgICAgIHZhciBjb250ID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHZhciBiZWhhdmlvckNvbmZpZyA9IG5ldyB4ZmFsaWIudXQuVmVyc2lvbihmb3JtQnJpZGdlLnVzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl0pOwogICAgICAgICAgICAgICAgLy9UbyBtYWludGFpbiBiYWNrd2FyZCBjb21wYXRpYmlsaXR5CiAgICAgICAgICAgICAgICBpZiAoIWJlaGF2aW9yQ29uZmlnLmlzT24oJ2Rpc2FibGVIZWFkUmVxdWVzdCcpICYmICFiZWhhdmlvckNvbmZpZy5pc09uKCdtZkRpc2FibGVIZWFkUmVxdWVzdCcpKSB7CiAgICAgICAgICAgICAgICAgICAgJC5hamF4KHsKICAgICAgICAgICAgICAgICAgICAgICAgYXN5bmM6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICB1cmw6IHRoaXMuX2dldFN1Ym1pdFNlcnZpY2VQcm94eVVybCgpLAogICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnSEVBRCcsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOiBmdW5jdGlvbiAoeGhyLCB0eHRTdGF0dXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtc2cgPSBmb3JtQnJpZGdlLl9pZGVudGlmeUNvbm5lY3Rpb25FcnJvcih4aHIsIHR4dFN0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobXNnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmNvbXBsZXRlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDIsIG1zZywgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmVycm9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuZXJyb3IuY2FsbChvcHRpb25zLmNvbnRleHQsIG9iaik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3JtQnJpZGdlLl94ZmEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUJyaWRnZS5feGZhLmhvc3QubWVzc2FnZUJveChtc2cpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ID0gZmFsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChjb250KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGFjdGlvbiA9IHRoaXMuX2dldFN1Ym1pdFNlcnZpY2VQcm94eVVybCgpOwoKICAgICAgICAgICAgICAgICAgICB2YXIgc3VibWl0U2VydmljZVByb3h5Q29uZmlnID0gdGhpcy51c2VyQ29uZmlnWyJzdWJtaXRTZXJ2aWNlUHJveHlDb25maWciXTsKCiAgICAgICAgICAgICAgICAgICAgdmFyIHBzdWVkb0Zvcm0gPSAkKCI8Zm9ybT4iKTsKCiAgICAgICAgICAgICAgICAgICAgdmFyIGZvcm1TdGF0ZSA9IG9wdGlvbnMuZm9ybVN0YXRlIHx8IHRoaXMuZ2V0Rm9ybVN0YXRlKHRydWUsIDMpLmRhdGE7CgogICAgICAgICAgICAgICAgICAgIC8vYWRkIHRoZSBhZGRpdGlvbmFsSW5mb3JtYXRpb24KICAgICAgICAgICAgICAgICAgICBfLmVhY2goZm9ybVN0YXRlLmFkZGl0aW9uYWxTdWJtaXRJbmZvcm1hdGlvbi5mb3JtQXR0cmlidXRlc0RhdGEsZnVuY3Rpb24odmFsdWUsa2V5KXsKICAgICAgICAgICAgICAgICAgICAgICAgcHN1ZWRvRm9ybS5hdHRyKGtleSwgdmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0sdGhpcyk7CgogICAgICAgICAgICAgICAgICAgIC8vb3ZlcnJpZGUgYWN0aW9uCiAgICAgICAgICAgICAgICAgICAgcHN1ZWRvRm9ybS5hdHRyKCJhY3Rpb24iLCBhY3Rpb24pOwoKICAgICAgICAgICAgICAgICAgICAvL0FkZCBfY2hhcnNldF8gdG8gbGV0IHNsaW5nIGtub3cgdGhhdCBpdCBzaG91bGQgZGVjb2RlIGluIFVURi04CiAgICAgICAgICAgICAgICAgICAgdmFyICRjaGFyU2V0RmllbGQgPSAkKCI8aW5wdXQ+IikuYXR0cigidHlwZSIsICJoaWRkZW4iKS5hdHRyKCJuYW1lIiwgIl9jaGFyc2V0XyIpLnZhbCgiVVRGLTgiKTsKICAgICAgICAgICAgICAgICAgICAkKHBzdWVkb0Zvcm0pLmFwcGVuZCgkY2hhclNldEZpZWxkKTsKCiAgICAgICAgICAgICAgICAgICAgYmVoYXZpb3JDb25maWcgPSB0aGlzLnVzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl07CgogICAgICAgICAgICAgICAgICAgIC8vYWRkIHN1cHBvcnRpbmcgZmllbGRzIHRvIHBzdWVkbyBmb3JtCiAgICAgICAgICAgICAgICAgICAgc3VibWl0U2VydmljZVByb3h5Q29uZmlnLnN1Ym1pdFVybCA9IG9wdGlvbnMuYWN0aW9uIHx8IHN1Ym1pdFNlcnZpY2VQcm94eUNvbmZpZy5zdWJtaXRVcmw7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgZmllbGROYW1lIGluIHN1Ym1pdFNlcnZpY2VQcm94eUNvbmZpZykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3VibWl0U2VydmljZVByb3h5Q29uZmlnW2ZpZWxkTmFtZV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdGaWVsZCA9ICQoIjxpbnB1dD4iKS5hdHRyKCJ0eXBlIiwgImhpZGRlbiIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoIm5hbWUiLCBmaWVsZE5hbWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnZhbChzdWJtaXRTZXJ2aWNlUHJveHlDb25maWdbZmllbGROYW1lXSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJChwc3VlZG9Gb3JtKS5hcHBlbmQoJChuZXdGaWVsZCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBmaWxlQXR0YWNobWVudEVuYWJsZWQgPSBmb3JtQnJpZGdlLl9pc0ZpbGVBdHRhY2htZW50RW5hYmxlZCgpOwogICAgICAgICAgICAgICAgICAgIGlmICghZmlsZUF0dGFjaG1lbnRFbmFibGVkKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAvL2Nsb25lIHRoZSBvYmplY3QgdG8gYXZvaWQgcG9sbHV0aW5nIHRoZSBvbGQgY29weQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyYW1zID0gXy5leHRlbmQoe30sIGZvcm1TdGF0ZS5jdXN0b21Qcm9wZXJ0eU1hcCwge2Zvcm1Eb206IGZvcm1TdGF0ZS54ZmFEb219LCBmb3JtU3RhdGUucmVuZGVyQ29udGV4dCk7CgogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBwYXJhbSBpbiBwYXJhbXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJhbXNbcGFyYW1dKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld0ZpZWxkID0gJCgiPGlucHV0PiIpLmF0dHIoInR5cGUiLCAiaGlkZGVuIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoIm5hbWUiLCBwYXJhbSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnZhbChwYXJhbXNbcGFyYW1dKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJChwc3VlZG9Gb3JtKS5hcHBlbmQoJChuZXdGaWVsZCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvL2ZvciBJRSBhcyB5b3UgY2Fubm90IHN1Ym1pdCBhIGZvcm0gd2l0aG91dCBhdHRhY2hpbmcgaXQgdG8gZG9jdW1lbnQuCiAgICAgICAgICAgICAgICAgICAgICAgICQoIiNsY2Zvcm1zX3hmYWZvcm1fY29udGFpbmVyIikuYXBwZW5kKCQocHN1ZWRvRm9ybSkpOwogICAgICAgICAgICAgICAgICAgICAgICAkKHBzdWVkb0Zvcm0pLnN1Ym1pdCgpOwoKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZpbGVBdHRhY2htZW50TWFwID0gZm9ybUJyaWRnZS5fZ2V0RmlsZU5hbWVQYXRoTWFwKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlQXR0YWNobWVudElucHV0cyA9IGZvcm1CcmlkZ2UuX2dldEZpbGVMaXN0RnJvbUZpbGVXaWRnZXQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVBdHRhY2htZW50TWFwSW5wdXQgOwogICAgICAgICAgICAgICAgICAgICAgICAvL2Nsb25lIHRoZSBvYmplY3QgdG8gYXZvaWQgcG9sbHV0aW5nIHRoZSBvbGQgY29weQogICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBfLmV4dGVuZCh7fSwgZm9ybVN0YXRlLmN1c3RvbVByb3BlcnR5TWFwLCB7Zm9ybURvbTogZm9ybVN0YXRlLnhmYURvbX0sIGZvcm1TdGF0ZS5yZW5kZXJDb250ZXh0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAocGFyYW0gaW4gcGFyYW1zKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyYW1zW3BhcmFtXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdGaWVsZCA9ICQoIjxpbnB1dD4iKS5hdHRyKCJ0eXBlIiwgImhpZGRlbiIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJuYW1lIiwgcGFyYW0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC52YWwocGFyYW1zW3BhcmFtXSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQocHN1ZWRvRm9ybSkuYXBwZW5kKCQobmV3RmllbGQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBfLmVhY2goZm9ybUJyaWRnZS5fZ2V0Q29tbWl0VmFsdWVGcm9tRmlsZVdpZGdldCgpLCBmdW5jdGlvbiAobmFtZU9mRmlsZSwgaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBfLmlzT2JqZWN0KGZpbGVBdHRhY2htZW50SW5wdXRzW2luZGV4XSkgJiYgXy5pc1N0cmluZyhuYW1lT2ZGaWxlKSAmJiAhbmFtZU9mRmlsZS5tYXRjaCgvXC8vZykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlQXR0YWNobWVudElucHV0c1tpbmRleF0uYXR0cigibmFtZSIsIG5hbWVPZkZpbGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCFmaWxlQXR0YWNobWVudE1hcFtuYW1lT2ZGaWxlXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlQXR0YWNobWVudE1hcFtuYW1lT2ZGaWxlXSA9IiI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQocHN1ZWRvRm9ybSkuYXBwZW5kKGZpbGVBdHRhY2htZW50SW5wdXRzW2luZGV4XSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgZmlsZUF0dGFjaG1lbnRNYXBJbnB1dCA9ICAkKCI8aW5wdXQ+IikuYXR0cigidHlwZSIsICJoaWRkZW4iKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoIm5hbWUiLCAiZmlsZUF0dGFjaG1lbnRNYXAiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLnZhbChKU09OLnN0cmluZ2lmeShmaWxlQXR0YWNobWVudE1hcCkpOwogICAgICAgICAgICAgICAgICAgICAgICAkKHBzdWVkb0Zvcm0pLmFwcGVuZCgkKGZpbGVBdHRhY2htZW50TWFwSW5wdXQpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vZm9yIElFIGFzIHlvdSBjYW5ub3Qgc3VibWl0IGEgZm9ybSB3aXRob3V0IGF0dGFjaGluZyBpdCB0byBkb2N1bWVudC4KICAgICAgICAgICAgICAgICAgICAgICAgJCgiI2xjZm9ybXNfeGZhZm9ybV9jb250YWluZXIiKS5hcHBlbmQoJChwc3VlZG9Gb3JtKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICQocHN1ZWRvRm9ybSkuc3VibWl0KCk7CgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvL2lmIHN1Ym1pdCBpcyBzdWNjZXNzZnVsLCB3ZSBuYXZpZ2F0ZSB0byBhbm90aGVyIHBhZ2Ugc28gbm8gbmVlZCB0byBjYWxsIHVpVW5GcmVlemUuCiAgICAgICAgfSwKCiAgICAgICAgdWlGcmVlemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyICR4ZmFfdWlfZnJlZXplID0gJCgnI2xjZm9ybXNfeGZhZm9ybV9jb250YWluZXIgPiAjeGZhX3VpX2ZyZWV6ZScpOwogICAgICAgICAgICBpZiAoJHhmYV91aV9mcmVlemUubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgJHhmYV91aV9mcmVlemUuc2hvdygpCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkKCcjbGNmb3Jtc194ZmFmb3JtX2NvbnRhaW5lcicpLmFwcGVuZCgnPGRpdiBpZD0ieGZhX3VpX2ZyZWV6ZSI+PC9kaXY+Jyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICB1aVVuRnJlZXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICQoJyNsY2Zvcm1zX3hmYWZvcm1fY29udGFpbmVyID4gI3hmYV91aV9mcmVlemUnKS5oaWRlKCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0IGFsbCB0aGUgZmllbGRzIGluIHRoZSBmb3JtLgogICAgICAgICAqIEBwYXJhbSBmaWx0ZXIgZmlsdGVyIGZ1bmN0aW9uIHRvIHRlbGwgd2hpY2ggZmllbGRzIHRvIHJldHVybi4gVGhlCiAgICAgICAgICogICAgICAgICAgICAgICBmdW5jdGlvbiB3aWxsIGJlIHBhc3NlZCBlYWNoIGZpZWxkIGluIHRoZSBmb3JtIGFuZCBpZgogICAgICAgICAqICAgICAgICAgICAgICAgaXQgcmV0dXJucyB0cnVlIHRoZSBmaWVsZCB3aWxsIGJlIHJldHVybmVkIG90aGVyd2lzZSBub3QuCiAgICAgICAgICogICAgICAgICAgICAgICAqKkRvZXNuJ3QgcmV0dXJuIE1hc3RlciBQYWdlIEZpZWxkcyoqCiAgICAgICAgICogICAgICAgICAgICAgICAqKlJlbmRlcnMgYWxsIHBhZ2VzIGluIHRoZSBwcm9jZXNzKioKICAgICAgICAgKiBAcmV0dXJuIHtBcnJheX0KICAgICAgICAgKi8KICAgICAgICBnZXRBbGxGaWVsZHM6IGZ1bmN0aW9uIChmaWx0ZXIpIHsKICAgICAgICAgICAgdmFyIGFsbEZpZWxkcyA9IFtdOwogICAgICAgICAgICBmb3IgKHZhciBwYWdlID0gMDsgcGFnZSA8IHRoaXMuX3hmYS5sYXlvdXQucGFnZUNvdW50KCk7IHBhZ2UrKykgewogICAgICAgICAgICAgICAgdmFyIHBhZ2VGaWVsZHMgPSB0aGlzLl94ZmEubGF5b3V0LnBhZ2VDb250ZW50KHBhZ2UsICJmaWVsZCIpOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYWdlRmllbGRzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGZpZWxkID0gcGFnZUZpZWxkcy5pdGVtKGkpOwogICAgICAgICAgICAgICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKGZpbHRlcikgfHwgXy5pc051bGwoZmlsdGVyKSB8fCBmaWx0ZXIuYXBwbHkod2luZG93LCBbZmllbGRdKSA9PT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBhbGxGaWVsZHMucHVzaChmaWVsZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBhbGxGaWVsZHM7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0IHRoZSBjdXJyZW50IGZpZWxkIGluIGZvY3VzLgogICAgICAgICAqIEByZXR1cm4geyp9CiAgICAgICAgICovCiAgICAgICAgZ2V0Rm9jdXM6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKHRoaXMuX3hmYS5ob3N0LmdldEZvY3VzKSB7CiAgICAgICAgICAgICAgICB2YXIgb2JqID0gdGhpcy5feGZhLmhvc3QuZ2V0Rm9jdXMoKTsKICAgICAgICAgICAgICAgIGlmIChvYmopCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3hmYS5ob3N0LmdldEZvY3VzKCkuc29tRXhwcmVzc2lvbjsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiAidW5zdXBwb3J0ZWQiOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogVmFsaWRhdGUgdGhlIGZvcm0uCiAgICAgICAgICogUnVuIGNsaWVudCBzaWRlIHZhbGlkYXRpb25zLgogICAgICAgICAqCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICB2YWxpZGF0ZUZvcm06IGZ1bmN0aW9uIChvcHRpb25zKSB7CiAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogICAgICAgICAgICBvcHRpb25zLmVycm9yID0gb3B0aW9ucy5lcnJvciB8fCBkZWZhdWx0RXJyb3JIYW5kbGVyOwogICAgICAgICAgICBvcHRpb25zLmNvbnRleHQgPSBvcHRpb25zLmNvbnRleHQgfHwgdGhpczsKICAgICAgICAgICAgdmFyIHZhbE1lc3NhZ2VzID0gW107CiAgICAgICAgICAgIHZhciB2YWxpZGF0aW9uc1ZhbHVlID0gdGhpcy5feGZhLmhvc3QuX3ZhbGlkYXRlKHsKICAgICAgICAgICAgICAgIHZhbE1lc3NhZ2VzOiB2YWxNZXNzYWdlcwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIHZhciBvYmogPSBuZXcgWEZBUmVzdWx0T2JqZWN0KCk7CiAgICAgICAgICAgIGlmICghdGhpcy5fY2hlY2tYZmEob2JqKSkKICAgICAgICAgICAgICAgIHRocm93IG9iai5nZXROZXh0TWVzc2FnZSgpLm1lc3NhZ2U7CgogICAgICAgICAgICBpZiAodmFsaWRhdGlvbnNWYWx1ZSA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMCwgImNsaWVudCBzaWRlIHZhbGlkYXRpb25zIGZhaWxlZCIsICJ4ZmEiKTsKICAgICAgICAgICAgICAgIF8uZWFjaCgKICAgICAgICAgICAgICAgICAgICBfLmZpbHRlcih2YWxNZXNzYWdlcywgZnVuY3Rpb24gKG1zZykgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbXNnLnNldmVyaXR5ID09PSAiZXJyb3IiCiAgICAgICAgICAgICAgICAgICAgfSksCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKG1zZykgewogICAgICAgICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDEsIG1zZy5tZXNzYWdlLCBtc2cucmVmKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBvcHRpb25zLmVycm9yLmNhbGwob3B0aW9ucy5jb250ZXh0LCBvYmopOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKG9wdGlvbnMuc3VjY2VzcykKICAgICAgICAgICAgICAgIG9wdGlvbnMuc3VjY2Vzcy5jYWxsKG9wdGlvbnMuY29udGV4dCwgb2JqKTsKCiAgICAgICAgICAgIHJldHVybiB2YWxpZGF0aW9uc1ZhbHVlOwogICAgICAgIH0sCiAgICAgICAgLy8tLWNoZWNraW5nIGZvciBicm93c2VyIGNvbXBhdGliaWxpdHkKICAgICAgICBfaXNCcm93c2VyQ29tcGF0aWJsZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgaXNXaW4gPSBmYWxzZTsKICAgICAgICAgICAgdmFyIGlzTWFjID0gZmFsc2U7CiAgICAgICAgICAgIHZhciBpc2lQYWQgPSBmYWxzZTsKICAgICAgICAgICAgdmFyIGlzQW5kcm9pZCA9IGZhbHNlOwogICAgICAgICAgICB2YXIgaXNXZWJLaXQgPSBmYWxzZTsKICAgICAgICAgICAgaWYgKG5hdmlnYXRvci5hcHBWZXJzaW9uLmluZGV4T2YoIldpbiIpICE9IC0xKQogICAgICAgICAgICAgICAgaXNXaW4gPSB0cnVlOwogICAgICAgICAgICBlbHNlIGlmIChuYXZpZ2F0b3IuYXBwVmVyc2lvbi5pbmRleE9mKCJNYWMiKSAhPSAtMSkKICAgICAgICAgICAgICAgIGlzTWFjID0gdHJ1ZTsKICAgICAgICAgICAgZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBhZC9pKSAhPSBudWxsKQogICAgICAgICAgICAgICAgaXNpUGFkID0gdHJ1ZTsKICAgICAgICAgICAgZWxzZSBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpLmluZGV4T2YoImFuZHJvaWQiKSA+IC0xKQogICAgICAgICAgICAgICAgaXNBbmRyb2lkID0gdHJ1ZTsKICAgICAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5pbmRleE9mKCJ3ZWJraXQiKSA+IC0xKQogICAgICAgICAgICAgICAgaXNXZWJLaXQgPSB0cnVlOwoKICAgICAgICAgICAgdmFyIGJyb3dzZXJWZXJzaW9uID0gcGFyc2VJbnQoJC5icm93c2VyLnZlcnNpb24sIDEwKTsKICAgICAgICAgICAgaWYgKGlzV2luICYmICgkLmJyb3dzZXIubXNpZSAmJiAoYnJvd3NlclZlcnNpb24gPT0gNiB8fCBicm93c2VyVmVyc2lvbiA9PSA3IHx8IGJyb3dzZXJWZXJzaW9uID09IDgpKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgZWxzZSBpZiAoaXNXaW4gJiYgKGlzV2ViS2l0IHx8ICQuYnJvd3Nlci5tb3ppbGxhIHx8ICgkLmJyb3dzZXIubXNpZSAmJiAoYnJvd3NlclZlcnNpb24gPT0gOSB8fCBicm93c2VyVmVyc2lvbiA9PSAxMCkpKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoKGlzTWFjIHx8IGlzaVBhZCB8fCBpc0FuZHJvaWQpICYmIGlzV2ViS2l0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgLyoKICAgICAgICAgKiBSZXN0b3JlcyB0aGUgRm9ybSBTdGF0ZSB0byBhIHByZXZpb3VzIHN0YXRlLiBUaGlzIGlzIGEgQXN5bmNocm9ub3VzIGNhbGwgYW5kIHJlY2lldmVzIGEgZm9ybVN0YXRlIGZyb20gdGhlCiAgICAgICAgICogY2FsbGVyLiBUaGUgc3RhdGUgd2lsbCBiZSBhcHBsaWVkIGFuZCBzdWNjZXNzIG9yIGVycm9yIGhhbmRsZXJzIHdpbGwgYmUgY2FsbGVkIGFmdGVyIHRoZSBvcGVyYXRpb24gaXMKICAgICAgICAgKiBjb21wbGV0ZWQuCiAgICAgICAgICovCiAgICAgICAgcmVzdG9yZUZvcm1TdGF0ZTogZnVuY3Rpb24gKG9wdGlvbnMpIHsKICAgICAgICAgICAgaWYgKHdpbmRvdy5hdG9iICYmIG9wdGlvbnMuYmFzZTY0Rm9ybVN0YXRlICE9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgIC8vIERlY29kZSBiYXNlIDY0IGVuY29kZWQgc3RyaW5nIHRvIGZvcm0gdGhlIGZvcm0gRE9NIG9iamVjdC4KICAgICAgICAgICAgICAgIHZhciB1dGZ0ZXh0ID0gYXRvYihvcHRpb25zLmJhc2U2NEZvcm1TdGF0ZSksCiAgICAgICAgICAgICAgICAgICAgc3RyaW5nID0gIiIsCiAgICAgICAgICAgICAgICAgICAgaSA9IDAsCiAgICAgICAgICAgICAgICAgICAgYyA9IDAsCiAgICAgICAgICAgICAgICAgICAgYzEgPSAwLAogICAgICAgICAgICAgICAgICAgIGMyID0gMCwKICAgICAgICAgICAgICAgICAgICBjMyA9IDA7CiAgICAgICAgICAgICAgICB3aGlsZSAoIGkgPCB1dGZ0ZXh0Lmxlbmd0aCApIHsKICAgICAgICAgICAgICAgICAgICBjID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkpOwogICAgICAgICAgICAgICAgICAgIGlmIChjIDwgMTI4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpOwogICAgICAgICAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoKGMgPiAxOTEpICYmIChjIDwgMjI0KSkgewogICAgICAgICAgICAgICAgICAgICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpKzEpOwogICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgJiAzMSkgPDwgNikgfCAoYzIgJiA2MykpOwogICAgICAgICAgICAgICAgICAgICAgICBpICs9IDI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpKzEpOwogICAgICAgICAgICAgICAgICAgICAgICBjMyA9IHV0ZnRleHQuY2hhckNvZGVBdChpKzIpOwogICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgJiAxNSkgPDwgMTIpIHwgKChjMiAmIDYzKSA8PCA2KSB8IChjMyAmIDYzKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGkgKz0gMzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB1dGZ0ZXh0ID0gc3RyaW5nOwogICAgICAgICAgICAgICAgdmFyIGZvcm1Eb20gPSBKU09OLnBhcnNlKHV0ZnRleHQpOwogICAgICAgICAgICAgICAgb3B0aW9ucy5mb3JtU3RhdGUgPSBmb3JtRG9tOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBXZSBoYXZlIHRvIG1lcmdlIHRoZSBydW50aW1lIHJlbmRlckNvbnRleHQgd2l0aCB0aGUgcmVuZGVyQ29udGV4dCBvZiB0aGUgZm9ybVN0YXRlIHBhc3NlZAogICAgICAgICAgICAgKiBzbyB0aGF0IG5vIGN1c3RvbSBwcm9wZXJ0aWVzIHRoYXQgd2VyZSBzZXQgaW4gdGhlIGNvbnRleHQocHJlc2VudCBpbiB0aGUgZm9ybSBzdGF0ZSkgYXJlIGlnbm9yZWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB4ZmFsaWIucnVudGltZS5yZW5kZXJDb250ZXh0ID0geGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dCB8fCB7fTsKICAgICAgICAgICAgXy5leHRlbmQoeGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dCwgb3B0aW9ucy5mb3JtU3RhdGUucmVuZGVyQ29udGV4dCk7CiAgICAgICAgICAgIGlmICghdGhpcy5feGZhKSB7CiAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UgPSB7fTsKICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5mb3JtU3RhdGUgPSBvcHRpb25zLmZvcm1TdGF0ZTsKICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5lcnJvciA9IG9wdGlvbnMuZXJyb3I7CiAgICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2Uuc3VjY2VzcyA9IG9wdGlvbnMuc3VjY2VzczsKICAgICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5jb250ZXh0ID0gb3B0aW9ucy5jb250ZXh0OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5feGZhLmhvc3QucGxheUpzb24oSlNPTi5wYXJzZShvcHRpb25zLmZvcm1TdGF0ZS54ZmFEb20pKTsKICAgICAgICAgICAgICAgIHRoaXMuY3VzdG9tQ29udGV4dFByb3BlcnR5KG9wdGlvbnMuZm9ybVN0YXRlLmN1c3RvbVByb3BlcnR5TWFwKTsKICAgICAgICAgICAgICAgIGlmKF8uaXNGdW5jdGlvbihvcHRpb25zLnN1Y2Nlc3MpKSB7CiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zdWNjZXNzLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGN1c3RvbUNvbnRleHRQcm9wZXJ0eTogZnVuY3Rpb24ocHJvcGVydHksdmFsdWUpIHsKICAgICAgICAgICAgdmFyIGN1c3RvbVByb3BlcnR5TWFwID0geGZhbGliLnJ1bnRpbWUuY3VzdG9tUHJvcGVydHlNYXAgfHwge307CiAgICAgICAgICAgIGlmKF8uaXNVbmRlZmluZWQodmFsdWUpKSB7CiAgICAgICAgICAgICAgICBpZihfLmlzT2JqZWN0KHByb3BlcnR5KSkgewogICAgICAgICAgICAgICAgICAgIF8uZXh0ZW5kKGN1c3RvbVByb3BlcnR5TWFwLCBwcm9wZXJ0eSk7CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuY3VzdG9tUHJvcGVydHlNYXA9Y3VzdG9tUHJvcGVydHlNYXA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGN1c3RvbVByb3BlcnR5TWFwW3Byb3BlcnR5XTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBvbGRWYWx1ZSA9IGN1c3RvbVByb3BlcnR5TWFwW3Byb3BlcnR5XTsKICAgICAgICAgICAgICAgIGN1c3RvbVByb3BlcnR5TWFwW3Byb3BlcnR5XT1lbmNvZGVVUklDb21wb25lbnQodmFsdWUpOwogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuY3VzdG9tUHJvcGVydHlNYXA9Y3VzdG9tUHJvcGVydHlNYXA7CiAgICAgICAgICAgICAgICByZXR1cm4gb2xkVmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIC8qCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfZ2V0U3RvcmFnZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgcyA9IG51bGw7CiAgICAgICAgICAgIGlmICh0aGlzLnN0b3JhZ2UpIHsKICAgICAgICAgICAgICAgIHZhciBzID0gdGhpcy5zdG9yYWdlLmZvcm1TdGF0ZQogICAgICAgICAgICAgICAgdGhpcy5zdG9yYWdlLmZvcm1TdGF0ZSA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSwKCiAgICAgICAgX2dldFhtbFN0b3JhZ2U6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHMgPSBudWxsOwogICAgICAgICAgICBpZiAodGhpcy54bWxTdG9yYWdlKSB7CiAgICAgICAgICAgICAgICB2YXIgcyA9IHRoaXMueG1sU3RvcmFnZS54bWxEb2N1bWVudDsKICAgICAgICAgICAgICAgIHRoaXMueG1sU3RvcmFnZS54bWxEb2N1bWVudCA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9nZXRIVE1MRWxlbWVudDogZnVuY3Rpb24gKHNvbUV4cHJlc3Npb24sIGZ1bGwpIHsKICAgICAgICAgICAgdmFyIG9iaiA9IHRoaXMuX2dldEhUTUxFbGVtZW50SW50ZXJuYWwoc29tRXhwcmVzc2lvbiwgZnVsbCx0aGlzLl9mb3JtRG9jKTsKICAgICAgICAgICAgcmV0dXJuIG9iajsKICAgICAgICB9LAoKICAgICAgICBfZ2V0SFRNTEVsZW1lbnRJbnRlcm5hbDogZnVuY3Rpb24oc29tRXhwcmVzc2lvbiwgZnVsbCxyZWZlcmVuY2VEb2N1bWVudCl7CiAgICAgICAgICAgIHNvbUV4cHJlc3Npb24gPSBmdWxsID09PSB0cnVlID8gc29tRXhwcmVzc2lvbiA6ICJ4ZmFbMF0uZm9ybVswXS4iICsgc29tRXhwcmVzc2lvbjsKICAgICAgICAgICAgdmFyIG9iaiA9IG5ldyBYRkFSZXN1bHRPYmplY3QoKTsKICAgICAgICAgICAgaWYgKCF0aGlzLl9jaGVja1hmYShvYmopKQogICAgICAgICAgICAgICAgcmV0dXJuIG9iajsKICAgICAgICAgICAgdmFyIGVsZW0gPSB0aGlzLl94ZmEucmVzb2x2ZU5vZGUoc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgIGlmIChfLmlzRW1wdHkoZWxlbSkpewogICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMCwgc29tRXhwcmVzc2lvbiArICIgbm90IGZvdW5kIiwgc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgZWxlbUlkID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmpxSWQoZWxlbS5odG1sSWQpOwogICAgICAgICAgICAgICAgJChlbGVtSWQsIHJlZmVyZW5jZURvY3VtZW50KS5jaGlsZHJlbigpOwogICAgICAgICAgICAgICAgc3dpdGNoIChlbGVtLmNsYXNzTmFtZSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgImluc3RhbmNlTWFuYWdlciI6CiAgICAgICAgICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDAsICJObyBIVE1MIEVsZW1lbnQgZXhpc3RzIGZvciBpbnN0YW5jZU1hbmFnZXJzIiwgc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgInN1YmZvcm0iOgogICAgICAgICAgICAgICAgICAgICAgICBvYmouZGF0YSA9IHtlbGVtOiAkKGVsZW1JZCwgcmVmZXJlbmNlRG9jdW1lbnQpWzBdfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJmaWVsZCI6CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkYXRhID0gJChlbGVtSWQsIHJlZmVyZW5jZURvY3VtZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gZGF0YS5jaGlsZHJlbigpOwoKICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmRhdGEgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtOiBkYXRhWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwdGlvbjogY2hpbGRbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWRnZXQ6IHsgZWxlbTogY2hpbGRbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQ6ICQoImlucHV0LHNlbGVjdCIsIGNoaWxkWzFdKVswXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9iai5kYXRhLndpZGdldCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmRhdGEud2lkZ2V0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW06IGNoaWxkWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkOiAkKCJpbnB1dCxzZWxlY3QiLCBjaGlsZFswXSkgWzBdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmRhdGEgPSB7ZWxlbTogJChlbGVtSWQsIHJlZmVyZW5jZURvY3VtZW50KVswXX07CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBvYmo7CiAgICAgICAgfSwKCiAgICAgICAgX3Bvc3RFeHRlcm5hbE1lc3NhZ2U6IGZ1bmN0aW9uIChtZXNzYWdlKSB7CiAgICAgICAgICAgIGlmICh0aGlzLnVzZXJDb25maWdbInBvc3RFeHRlcm5hbE1lc3NhZ2VDb25maWciXSAmJiBfLmlzRnVuY3Rpb24odGhpcy51c2VyQ29uZmlnWyJwb3N0RXh0ZXJuYWxNZXNzYWdlQ29uZmlnIl1bInBvc3RFeHRlcm5hbEhhbmRsZXIiXSkpIHsKICAgICAgICAgICAgICAgIHZhciBleHRlcm5hbEhhbmRsZXIgPSB0aGlzLnVzZXJDb25maWdbInBvc3RFeHRlcm5hbE1lc3NhZ2VDb25maWciXVsicG9zdEV4dGVybmFsSGFuZGxlciJdOwogICAgICAgICAgICAgICAgZXh0ZXJuYWxIYW5kbGVyKG1lc3NhZ2UpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc2NhbGVGb3JtOiBmdW5jdGlvbiAodmlld3BvcnRXaWR0aCkgewogICAgICAgICAgICBpZiAodmlld3BvcnRXaWR0aCkgewogICAgICAgICAgICAgICAgdGhpcy51c2VyQ29uZmlnWyJ2aWV3cG9ydFdpZHRoIl0gPSB2aWV3cG9ydFdpZHRoOwogICAgICAgICAgICAgICAgd2luZG93LnhmYVZpZXdSZWdpc3RyeS5zY2FsZUZvcm0oKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFRoaXMgZnVuY3Rpb24gaGlkZXMgdGhlIHRvb2xiYXIgd2hlcmUgcmVxdWlyZWQuCiAgICAgICAgICogQG1lbWJlcm9mIEZvcm1CcmlkZ2UKICAgICAgICAgKi8KICAgICAgICBoaWRlVG9vbGJhcjogZnVuY3Rpb24oKXsKICAgICAgICAgICQoIi50b29sYmFyaGVhZGVyIikuaGlkZSgpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFVzZWQgdG8gUmVnaXN0ZXIgYW4gZXZlbnQgbGlzdGVuZXIgZm9yIHNwZWNpZmljIEZvcm0gQnJpZGdlIEV2ZW50LgogICAgICAgICAqIEBwYXJhbSBldmVudE5hbWUge3N0cmluZ30gbmFtZSBvZiB0aGUgZXZlbnQgZm9yIHdoaWNoIGxpc3RlbmVyIGhhcyB0byBiZSBhZGRlZC4gSXQgbXVzdCBiZSBvbmUgb2YgdGhlIGV2ZW50cwogICAgICAgICAqIG1lbnRpb25lZCBpbiB0aGUgZG9jdW1lbnRhdGlvbi4KICAgICAgICAgKiBAcGFyYW0gaGFuZGxlciB7ZnVuY3Rpb259IGV2ZW50IGxpc3RlbmVyIHdoaWNoIGlzIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyB0cmlnZ2VyZWQuCiAgICAgICAgICogQHBhcmFtIFtjb250ZXh0XSB7b2JqZWN0fSBjb250ZXh0IGlzIHVzZWQgYXMgdGhlIDxpPnRoaXM8L2k+IG9iamVjdCBpbnNpZGUgaGFuZGxlciBmdW5jdGlvbgogICAgICAgICAqLwoKICAgICAgICBvbjogZnVuY3Rpb24gKGV2ZW50TmFtZSwgaGFuZGxlciwgY29udGV4dCkgewogICAgICAgICAgICB0aGlzLl8kdGFyZ2V0Lm9uKGV2ZW50TmFtZSwgaGFuZGxlciwgY29udGV4dCk7CiAgICAgICAgfSwKCgogICAgICAgIC8qKgogICAgICAgICAqIFVucmVnaXN0ZXIgdGhlIGV2ZW50IHJlZ2lzdGVyZWQgdXNpbmcgdGhlIHtAbGluayBGb3JtQnJpZGdlLm9ufG9ufSBmdW5jdGlvbgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGV2ZW50TmFtZSB7c3RyaW5nfSBuYW1lIG9mIHRoZSBldmVudCB0byB1bi1yZWdpc3Rlci4KICAgICAgICAgKiBAcGFyYW0gW3NlbGVjdG9yXSB7c3RyaW5nfSBzZWxlY3RvciB3aGljaCBzaG91bGQgbWF0Y2ggdGhlIG9uZSBvcmlnaW5hbGx5IHBhc3NlZCB0byBGb3JtQnJpZGdlJ3Mgb24oKSB3aGlsZSByZWdpc3RlcmluZyBoYW5kbGVycwogICAgICAgICAqIEBwYXJhbSBbaGFuZGxlcl0ge2Z1bmN0aW9ufSBoYW5kbGVyIHdoaWNoIG5lZWRzIHRvIHVuLXJlZ2lzdGVyZWQuIElmIG5vdCBwcm92aWRlZCBhbGwgdGhlIGV2ZW50IGxpc3RlbmVycwogICAgICAgICAqIHdpbGwgYmUgdW5yZWdpc3RlcmVkCiAgICAgICAgICovCgogICAgICAgIG9mZjogZnVuY3Rpb24gKGV2ZW50TmFtZSwgc2VsZWN0b3IsIGhhbmRsZXIpIHsKICAgICAgICAgICAgdGhpcy5fJHRhcmdldC5vZmYoZXZlbnROYW1lLCBzZWxlY3RvciwgaGFuZGxlcik7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogSW50ZXJuYWwgQVBJCiAgICAgICAgICoKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwoKICAgICAgICB0cmlnZ2VyOiBmdW5jdGlvbiAoZXZlbnROYW1lLCBleHRyYVBhcmFtZXJ0cykgewogICAgICAgICAgICBpZih0aGlzLmlzQW5hbHl0aWNzRW5hYmxlZCB8fCBldmVudE5hbWUgPT0geGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5zY3JpYmJsZUNoYW5nZUV2ZW50KSB7CiAgICAgICAgICAgICAgICB0aGlzLl8kdGFyZ2V0LnRyaWdnZXIoZXZlbnROYW1lLCBleHRyYVBhcmFtZXJ0cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBjb25zdHJ1Y3RzIHRoZSBkYXRhU29tTWFwIGFuZCByZXR1cm5zIHRoYXQuIElmIGEgdmFsaWQgb2JqZWN0IGlzIHByb3ZpZGVkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCB0aGVuIGl0CiAgICAgICAgICogbW9kaWZpZXMgYW5kIGFkZHMgZW50cmllcyBpbiB0aGF0IG1hcCBvbmx5LCBvdGhlcndpc2UgY29uc3RydWN0cyBhIG5ldyBtYXAuCiAgICAgICAgICogQHBhcmFtIG1hcCB7b2JqZWN0fQogICAgICAgICAqIEByZXR1cm5zIHtYRkFSZXN1bHRPYmplY3R9IHdpdGggdGhlIGRhdGEgcGFyYW1ldGVyIGFzIHRoZSBkYXRhU29tTWFwCiAgICAgICAgICovCiAgICAgICAgZ2V0RGF0YVNvbU1hcDogZnVuY3Rpb24gKG1hcCkgewogICAgICAgICAgICB2YXIgb2JqID0gbmV3IFhGQVJlc3VsdE9iamVjdCgpOwogICAgICAgICAgICBpZiAoIXRoaXMuX2NoZWNrWGZhKG9iaikpIHsKICAgICAgICAgICAgICAgIHJldHVybiBvYmo7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIF9tYXAgPSBtYXA7CiAgICAgICAgICAgIGlmKCFfLmlzT2JqZWN0KG1hcCkpIHsKICAgICAgICAgICAgICAgIF9tYXAgPSB7fTsKICAgICAgICAgICAgfQogICAgICAgICAgICBfbWFwID0gdGhpcy5feGZhLmZvcm0uX2dldERhdGFTb21NYXAoX21hcCk7CiAgICAgICAgICAgIG9iai5kYXRhID0gX21hcDsKICAgICAgICAgICAgcmV0dXJuIG9iajsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBVcGRhdGVzIHRoZSBmaWVsZCB2YWx1ZXMgd2l0aCB0aGUgdmFsdWVzIHByb3ZpZGVkIGluIHRoZSBtYXAuIElmIG1hcCBpcyBub3QgYW4gb2JqZWN0LCByZXR1cm5zIGFuIGVycm9yLgogICAgICAgICAqIEBwYXJhbSBtYXAge29iamVjdH0KICAgICAgICAgKiBAcmV0dXJuIHtYRkFSZXN1bHRPYmplY3R9IHdpdGggdGhlIGRhdGEgcGFyYW1ldGVyIGFzIG51bGwuCiAgICAgICAgICovCiAgICAgICAgcmVzdG9yZURhdGFTb21NYXA6IGZ1bmN0aW9uIChtYXApIHsKICAgICAgICAgICAgdmFyIG9iaiA9IG5ldyBYRkFSZXN1bHRPYmplY3QoKTsKICAgICAgICAgICAgaWYgKCF0aGlzLl9jaGVja1hmYShvYmopKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gb2JqOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKCFfLmlzT2JqZWN0KG1hcCkpIHsKICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDAsICJJbnZhbGlkIEFyZ3VtZW50IHBhc3NlZC4gRmlyc3QgYXJndW1lbnQgaGFzIHRvIGJlIGFuIG9iamVjdCIsIG51bGwpOwogICAgICAgICAgICAgICAgcmV0dXJuIG9iajsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl94ZmEuZm9ybS5fcmVzdG9yZURhdGFTb21NYXAobWFwKTsKICAgICAgICAgICAgb2JqLmRhdGEgPSBudWxsOwogICAgICAgICAgICByZXR1cm4gb2JqOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIE5hbWVzcGFjZSByZXNvbHZlciBuZWVkZWQgZm9yIHhwYXRoIHJlc29sdXRpb24uIFdlIG5lZWQgdG8gYWRkIG1vcmUgbmFtZXBzYWNlcwogICAgICAgICAqIEBwYXJhbSBwcmVmaXgKICAgICAgICAgKiBAcmV0dXJucyB7KnxudWxsfQogICAgICAgICAqLwogICAgICAgIG5zUmVzb2x2ZXIgOiBmdW5jdGlvbiAocHJlZml4KSB7CiAgICAgICAgICAgIHZhciBucyA9IHsKICAgICAgICAgICAgICAgICd4ZmEnIDogJ2h0dHA6Ly93d3cueGZhLm9yZy9zY2hlbWEveGZhLWRhdGEvMS4wLycsCiAgICAgICAgICAgICAgICAneGRwJyA6ICdodHRwOi8vbnMuYWRvYmUuY29tL3hkcC8nCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHJldHVybiBuc1twcmVmaXhdIHx8IG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogbWVyZ2VzIHRoZSBGb3JtIHdpdGggdGhlIHhtbERvY3VtZW50IHByb3ZpZGVkCiAgICAgICAgICogQHBhcmFtIG9wdGlvbnMge29iamVjdH0gd2l0aCB0aGUgZm9sbGxvd2luZyBzeW50YXgKICAgICAgICAgKiAgewogICAgICAgICAqICAgeG1sRG9jdW1lbnQKICAgICAgICAgKiAgIHN1Y2Nlc3M6IGZ1bmN0aW9uKCkge30KICAgICAgICAgKiAgIGVycm9yOiBmdW5jdGlvbih4ZmFSZXN1bHRPYmplY3QpIHt9CiAgICAgICAgICogICBjb250ZXh0OgogICAgICAgICAqICB9CiAgICAgICAgICogQHJldHVybiB7WEZBUmVzdWx0T2JqZWN0fSB3aXRoIHRoZSBkYXRhIHBhcmFtZXRlciBhcyBudWxsLgogICAgICAgICAqLwogICAgICAgIHBsYXlEYXRhWE1MOiBmdW5jdGlvbihvcHRpb25zKSB7CiAgICAgICAgICAgIGlmICghdGhpcy5feGZhKSB7CiAgICAgICAgICAgICAgICB0aGlzLnhtbFN0b3JhZ2UgPSB7fTsKICAgICAgICAgICAgICAgIHRoaXMueG1sU3RvcmFnZS54bWxEb2N1bWVudCA9IG9wdGlvbnMueG1sRG9jdW1lbnQ7CiAgICAgICAgICAgICAgICB0aGlzLnhtbFN0b3JhZ2UuZXJyb3IgPSBvcHRpb25zLmVycm9yIHx8IGRlZmF1bHRFcnJvckhhbmRsZXI7CiAgICAgICAgICAgICAgICB0aGlzLnhtbFN0b3JhZ2Uuc3VjY2VzcyA9IG9wdGlvbnMuc3VjY2VzczsKICAgICAgICAgICAgICAgIHRoaXMueG1sU3RvcmFnZS5jb250ZXh0ID0gb3B0aW9ucy5jb250ZXh0OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIG9iaiA9IG5ldyBYRkFSZXN1bHRPYmplY3QoKSwKICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fSwKICAgICAgICAgICAgICAgICAgICBlcnJvciA9IG9wdGlvbnMuZXJyb3IgfHwgZGVmYXVsdEVycm9ySGFuZGxlciwKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gb3B0aW9ucy5zdWNjZXNzLAogICAgICAgICAgICAgICAgICAgIHhtbERvY3VtZW50ID0gb3B0aW9ucy54bWxEb2N1bWVudCwKICAgICAgICAgICAgICAgICAgICByb290RWxlbWVudDsKICAgICAgICAgICAgICAgIGlmKHhtbERvY3VtZW50ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBvYmouYWRkTWVzc2FnZSgwLCAiSW52YWxpZCBBcmd1bWVudCBFcnJvci4gWE1MIERvY3VtZW50IGlzIG5vdCBkZWZpbmVkIiwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IuYXBwbHkob3B0aW9ucy5jb250ZXh0LCBbb2JqXSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYoXy5pc1N0cmluZyh4bWxEb2N1bWVudCkpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEuTG9nZ2VyLmluZm8oInhmYSIsICJ4bWxEb2N1bWVudCBpcyBvZiB0eXBlIHN0cmluZy4gY29udmVydGluZyBpdCB0byBkb2N1bWVudCIpOwogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbERvY3VtZW50ID0gJC5wYXJzZVhNTCh4bWxEb2N1bWVudCk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9iai5hZGRNZXNzYWdlKDIsICJVbmFibGUgdG8gcGFyc2UgRGF0YSBYTUwgIiArIGUsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5hcHBseShvcHRpb25zLmNvbnRleHQsIFtvYmpdKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKCEoeG1sRG9jdW1lbnQgaW5zdGFuY2VvZiBEb2N1bWVudCkgJiYgISh4bWxEb2N1bWVudCBpbnN0YW5jZW9mIEVsZW1lbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMSwgIkludmFsaWQgQXJndW1lbnQgRXJyb3IuIFhNTCBEb2N1bWVudCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgRG9jdW1lbnQgb3IgRWxlbWVudCIsIG51bGwpOwogICAgICAgICAgICAgICAgICAgIGVycm9yLmFwcGx5KG9wdGlvbnMuY29udGV4dCwgW29ial0pOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhLmhvc3QucGxheURhdGFYbWwoeG1sRG9jdW1lbnQpOwogICAgICAgICAgICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgICAgICAgICAgICAgb2JqLmFkZE1lc3NhZ2UoMiwgIlVuZXhwZWN0ZWQgRXhjZXB0aW9uOiBVbmFibGUgdG8gcGxheSBEYXRhIFhNTCAiICsgZSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IuYXBwbHkob3B0aW9ucy5jb250ZXh0LCBbb2JqXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihzdWNjZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzcy5hcHBseShvcHRpb25zLmNvbnRleHQsW29ial0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyBEYXRhIFhNTCBvZiB0aGUgRm9ybS4gSWYgZGF0YVhNTCBpcyBwYXNzZWQsIGl0IGlzIG1lcmdlZCB3aXRoCiAgICAgICAgICogdGhlIERhdGEgWE1MLgogICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8Tm9kZX0gSWYgZGF0YVhNTCBpbnB1dCBpcyBTdHJpbmcsIGl0IHJldHVybnMgc3RyaW5nLCBvdGhlcndpc2UKICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFYTUwgaXMgdXBkYXRlZCBhbmQgcmV0dXJuZWQKICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgIFJldHVybnMgbnVsbCBpbiBjYXNlIGl0IGZhaWxzIHRvIGdlbmVyYXRlIGRhdGEgeG1sLgogICAgICAgICAqIEBwYXJhbSBiR2VuZXJhdGVYRFBSb290IHdoZXRoZXIgdG8gZ2VuZXJhdGUgdGhlIHhkcCByb290IGlmIGl0IGRvZXNuJ3QgZXhpc3RzCiAgICAgICAgICogQHBhcmFtIGRhdGFYTUwge0VsZW1lbnR8RG9jdW1lbnR8U3RyaW5nfSBJZiBkYXRhWE1MIHBhc3NlZCBpcyBkb2N1bWVudCBvciBFbGVtZW50LCBpdCB1cGRhdGVzIHRoYXQgYW5kCiAgICAgICAgICogcmV0dXJucyBpdC4gSW4gY2FzZSBvZiBzdHJpbmcgYSBuZXcgc3RyaW5nIGlzIHJldHVybmVkLgogICAgICAgICAqLwogICAgICAgIGdlbmVyYXRlRGF0YVhNTDogZnVuY3Rpb24gKGRhdGFYTUwsIGJHZW5lcmF0ZVhEUFJvb3QpIHsKICAgICAgICAgICAgaWYoXy5pc1VuZGVmaW5lZChkb2N1bWVudC5ldmFsdWF0ZSkpIHsKICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gZG8gaXQgaGVyZSBzaW5jZSBYUGF0aFJlc3VsdCBpcyBhbHNvIHVuZGVmaW5lZCBpbiBJRQogICAgICAgICAgICAgICAgd2d4cGF0aC5pbnN0YWxsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHZhciBwcmVmaWxsWE1MID0gZGF0YVhNTCB8fCB4ZmFsaWIucnVudGltZS5yZW5kZXJDb250ZXh0LmRhdGEsCiAgICAgICAgICAgICAgICAgICAgcm9vdFN1YmZvcm0gPSB0aGlzLl94ZmEuZm9ybS5fZ2V0Um9vdFN1YmZvcm0oKSwKICAgICAgICAgICAgICAgICAgICBiQWRkWERQUm9vdCA9ICEoYkdlbmVyYXRlWERQUm9vdCA9PT0gZmFsc2UpLAogICAgICAgICAgICAgICAgICAgIGltcGwsIHhtbERvYywgeGRwRWxlbWVudCwgZGF0YXNldHMsIGRhdGEsIHJvb3ROb2RlLCB4UGF0aFJlc3VsdCwgbmV3WG1sRG9jOwogICAgICAgICAgICAgICAgaWYgKHByZWZpbGxYTUwgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGltcGwgICAgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbjsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MgID0gaW1wbC5jcmVhdGVEb2N1bWVudCAoJ2h0dHA6Ly9ucy5hZG9iZS5jb20veGRwLycsICd4ZHA6eGRwJywgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgZGF0YXNldHMgPSB4bWxEb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnhmYS5vcmcvc2NoZW1hL3hmYS1kYXRhLzEuMC8iLCAieGZhOmRhdGFzZXRzIik7CiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHhtbERvYy5jcmVhdGVFbGVtZW50KCJ4ZmE6ZGF0YSIpOwogICAgICAgICAgICAgICAgICAgIHJvb3ROb2RlID0geG1sRG9jLmNyZWF0ZUVsZW1lbnQocm9vdFN1YmZvcm0uZ2V0QXR0cmlidXRlKCJuYW1lIikpOwogICAgICAgICAgICAgICAgICAgIGRhdGEuYXBwZW5kQ2hpbGQocm9vdE5vZGUpOwogICAgICAgICAgICAgICAgICAgIGRhdGFzZXRzLmFwcGVuZENoaWxkKGRhdGEpOwogICAgICAgICAgICAgICAgICAgIHhtbERvYy5kb2N1bWVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoZGF0YXNldHMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MgPSBwcmVmaWxsWE1MOwogICAgICAgICAgICAgICAgICAgIGlmKF8uaXNTdHJpbmcoeG1sRG9jKSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEuTG9nZ2VyLmluZm8oInhmYSIsICJ4bWxEb2N1bWVudCBpcyBvZiB0eXBlIHN0cmluZy4gY29udmVydGluZyBpdCB0byBkb2N1bWVudCIpCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbERvYyA9ICQucGFyc2VYTUwoeG1sRG9jKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcm9vdE5vZGUgPSB4ZmFsaWIudXQuWE1MVXRpbHMuZ2V0WEZBUm9vdEZvcm1FbGVtZW50RnJvbVhNTCh4bWxEb2MpOwogICAgICAgICAgICAgICAgICAgIHZhciB4bWxEb2NFbGVtZW50ID0geG1sRG9jIGluc3RhbmNlb2YgRWxlbWVudCA/IHhtbERvYyA6IHhtbERvYy5kb2N1bWVudEVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJBZGRYRFBSb290ICYmIHhtbERvY0VsZW1lbnQubm9kZU5hbWUgIT09ICJ4ZHA6eGRwIikgewogICAgICAgICAgICAgICAgICAgICAgICBpbXBsICAgID0gZG9jdW1lbnQuaW1wbGVtZW50YXRpb247CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbERvYyAgPSBpbXBsLmNyZWF0ZURvY3VtZW50ICgnaHR0cDovL25zLmFkb2JlLmNvbS94ZHAvJywgJ3hkcDp4ZHAnLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YXNldHMgPSB4bWxEb2MuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnhmYS5vcmcvc2NoZW1hL3hmYS1kYXRhLzEuMC8iLCAieGZhOmRhdGFzZXRzIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSB4bWxEb2MuY3JlYXRlRWxlbWVudCgieGZhOmRhdGEiKTsKICAgICAgICAgICAgICAgICAgICAgICAgcm9vdE5vZGUgPSB4bWxEb2MuaW1wb3J0Tm9kZShyb290Tm9kZSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEuYXBwZW5kQ2hpbGQocm9vdE5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICBkYXRhc2V0cy5hcHBlbmRDaGlsZChkYXRhKTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sRG9jLmRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZChkYXRhc2V0cyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcm9vdFN1YmZvcm0uZ2VuZXJhdGVEYXRhWE1MKHJvb3ROb2RlLCByb290Tm9kZSk7CiAgICAgICAgICAgICAgICBpZihwcmVmaWxsWE1MID09IG51bGwgfHwgXy5pc1N0cmluZyhwcmVmaWxsWE1MKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgWE1MU2VyaWFsaXplcigpLnNlcmlhbGl6ZVRvU3RyaW5nKHhtbERvYy5kb2N1bWVudEVsZW1lbnQpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4geG1sRG9jOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgICAgICAgIHRoaXMuX3hmYS5Mb2dnZXIuZXJyb3IoInhmYSIsICJFcnJvciBpbiBHZW5lcmF0aW5nIERhdGEgWE1MIG9uIENsaWVudCAiICsgZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIERlc3Ryb3kgTW9iaWxlIEZvcm0gc28gdGhhdCBhbm90aGVyIGZvcm0gY2FuIGJlIHJlbmRlcmVkLiBpZiBiRnVsbCBwYXJhbWV0ZXIKICAgICAgICAgKiBpcyBwYXNzZWQgYXMgdHJ1ZSwgdGhlbiBhbGwgdGhlIHNjcmlwdHMgYXJlIGRlc3Ryb3llZCBhcyB3ZWxsLgogICAgICAgICAqIEBwYXJhbSBiRnVsbAogICAgICAgICAqLwogICAgICAgIGRlc3Ryb3lGb3JtOiBmdW5jdGlvbiAoYkZ1bGwpIHsKICAgICAgICAgICAgJCgiI21mc3R5bGUiKS5yZW1vdmUoKTsKICAgICAgICAgICAgdmFyIG9sZE1hcCA9IHhmYWxpYi5ydW50aW1lLmN1c3RvbVByb3BlcnR5TWFwOwogICAgICAgICAgICAvLyBJbiBhZGFwdGl2ZSBmb3JtLCB3ZSBuZXZlciB1c2UgdGhlIHZpZXcgbGF5ZXIgb2YgbW9iaWxlIGZvcm1zLCBoZW5jZSBhZGRpbmcgbnVsbCBjaGVjawogICAgICAgICAgICBpZih4ZmFWaWV3UmVnaXN0cnkgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgeGZhVmlld1JlZ2lzdHJ5LnJvb3RTdWJmb3JtVmlldyA9IG51bGw7CiAgICAgICAgICAgICAgICB4ZmFWaWV3UmVnaXN0cnkuY2xlYXJUZW1wbGF0ZUNhY2hlKCk7CiAgICAgICAgICAgICAgICB4ZmFWaWV3UmVnaXN0cnkucmVzZXRMYXlvdXRNYW5hZ2VyKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUgPSB7CiAgICAgICAgICAgICAgICB4ZmE6IG51bGwsCiAgICAgICAgICAgICAgICBhcHA6IG51bGwsCiAgICAgICAgICAgICAgICBEb2N1bWVudDogbnVsbCwKICAgICAgICAgICAgICAgIGZvcm06IG51bGwsCiAgICAgICAgICAgICAgICByZW5kZXJDb250ZXh0OiBudWxsLAogICAgICAgICAgICAgICAgX3ByaXZhdGU6IHt9LAogICAgICAgICAgICAgICAgY3VzdG9tUHJvcGVydHlNYXA6IG9sZE1hcAogICAgICAgICAgICB9OwogICAgICAgICAgICBpZih4ZmFsaWIucnVudGltZS5jb25zb2xlKSB7CiAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS5jb25zb2xlID0gdW5kZWZpbmVkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuX3hmYSA9IG51bGw7CiAgICAgICAgICAgIHhmYWxpYi5zY3JpcHQuWGZhLkluc3RhbmNlID0gbnVsbDsKICAgICAgICAgICAgJCh3aW5kb3cpLnRyaWdnZXIoImRlc3Ryb3kueGZhIik7CiAgICAgICAgICAgICQod2luZG93KS5vZmYoIi54ZmEiKTsKICAgICAgICAgICAgeGZhbGliLnZpZXcudXRpbC5UZXh0TWV0cmljcy5fZGVzdHJveSgpOwogICAgICAgICAgICB4ZmFsaWIudmlldy51dGlsLnRyYXZlcnNhbE1hbmFnZXIuX2Rlc3Ryb3koKTsKICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fY2xlYXJGb2N1c0luZm8oKTsKICAgICAgICAgICAgaWYoYkZ1bGwgPT09IHRydWUpIHsKICAgICAgICAgICAgICAgICQod2luZG93KS5vZmYoKTsKICAgICAgICAgICAgICAgICQoImJvZHkiKS5lbXB0eSgpOwogICAgICAgICAgICAgICAgLy90aGlzIGlzIGFkZGVkIGJ5IEZpbGVBdHRhY2htZW50LiBJdCBzaG91bGQgaGF2ZSBiZWVuCiAgICAgICAgICAgICAgICAvLyBhIG5hbWVzcGFjZSBldmVudAogICAgICAgICAgICAgICAgJChkb2N1bWVudCkub2ZmKCJtb3VzZWRvd24iKTsKICAgICAgICAgICAgICAgIF8uZWFjaCh4ZmFsaWIsIGZ1bmN0aW9uIChvYmosIGtleSkgewogICAgICAgICAgICAgICAgICAgeGZhbGliW2tleV0gPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHhmYWxpYiA9IG51bGw7CiAgICAgICAgICAgICAgICB3Z3hwYXRoID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgRm9ybUNhbGMgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAvLyBJbiBhZGFwdGl2ZSBmb3JtLCB3ZSBuZXZlciB1c2UgdGhlIHZpZXcgbGF5ZXIgb2YgbW9iaWxlIGZvcm1zLCBoZW5jZSBhZGRpbmcgbnVsbCBjaGVjawogICAgICAgICAgICAgICAgaWYoeGZhVmlld1JlZ2lzdHJ5ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB4ZmFWaWV3UmVnaXN0cnkuZGVzdHJveSgpOwogICAgICAgICAgICAgICAgICAgIHhmYVZpZXdSZWdpc3RyeSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICQuV2lkZ2V0ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC53aWRnZXQgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnhmYVdpZGdldCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgICQuZm4gPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnByb3RvdHlwZS5hYnN0cmFjdFdpZGdldCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgICQucHJvdG90eXBlLmFkb2JlRGF0ZVRpbWVQaWNrZXIgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnByb3RvdHlwZS5hZG9iZUZpbGVBdHRhY2htZW50ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUuYWRvYmVGaWxlVXBsb2FkZXIgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnByb3RvdHlwZS5kYXRlVGltZUVkaXQgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnByb3RvdHlwZS5kcm9wRG93bkxpc3QgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnByb3RvdHlwZS5kZWZhdWx0V2lkZ2V0ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUuZmlsZVVwbG9hZCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgICQucHJvdG90eXBlLmltYWdlRmllbGQgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLnByb3RvdHlwZS5saXN0Qm94ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUubndrTGlzdEJveCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgICQucHJvdG90eXBlLm51bWVyaWNJbnB1dCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgICQucHJvdG90eXBlLnNpZ25hdHVyZUZpZWxkID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUuU2NyaWJibGVJbWFnZUZpZWxkID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUudGV4dEZpZWxkID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUueGZhQnV0dG9uID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJC5wcm90b3R5cGUuWGZhQ2hlY2tCb3ggPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAkLmV4cHIgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB3aW5kb3cuZm9ybUJyaWRnZSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIEZvcm1CcmlkZ2UgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB3aW5kb3cucmVuZGVyTmV4dFBhZ2UgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB3aW5kb3cuaGFuZGxlRm9vdGVyTG9naWMgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICB3aW5kb3cuaGFuZGxlU2Nyb2xsID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgb3B0aW9uc0Zyb21Qcm9maWxlTm9kZSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICBGRCA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIHdpbmRvdy5fID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgJHBsdWdGaWxlV2lkZ2V0RG9tID0gdW5kZWZpbmVkOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgd2luZG93LmZvcm1CcmlkZ2UgPSBuZXcgRm9ybUJyaWRnZSgpOwogICAgd2luZG93LmZvcm1CcmlkZ2UuXyR0YXJnZXQgPSAkKHdpbmRvdy5mb3JtQnJpZGdlKTsKICAgIHRyeSB7CiAgICAgICAgdmFyIGV2bnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgiQ3VzdG9tRXZlbnQiKTsKICAgICAgICBldm50LmluaXRDdXN0b21FdmVudCgiRm9ybUJyaWRnZUluaXRpYWxpemVkIiwgdHJ1ZSwgdHJ1ZSwgeyJmb3JtQnJpZGdlIjogd2luZG93LmZvcm1CcmlkZ2V9KTsKICAgICAgICB3aW5kb3cuZGlzcGF0Y2hFdmVudChldm50KTsKICAgIH0KCiAgICBjYXRjaCAoZXhjZXB0aW9uKSB7CiAgICAgICAgLy8gd3JpdHRlbiBmb3IgZW52IHJoaW5vIHRvIGV4ZWN1dGUoZm9yIHNlcnZlciBzaWRlIHZhbGlkYXRpb24pCiAgICB9CgogICAgaWYgKCF3aW5kb3cuZm9ybUJyaWRnZS51c2VyQ29uZmlnWyJwb3N0RXh0ZXJuYWxNZXNzYWdlQ29uZmlnIl0pIHsKICAgICAgICBpZiAod2luZG93ICE9PSB3aW5kb3cucGFyZW50KSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB3aW5kb3cucGFyZW50LmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHdpbmRvdy5uYW1lKTsKICAgICAgICAgICAgICAgIC8vV2UgYXJlIGhlcmUgbWVhbnMgbm8gY3Jvc3MgZG9tYWluIGlzc3VlLiBTbyBpZiB1c2VyIGhhcyBub3QgZGVmaW5lZCBjdXN0b20gcG9zdEV4dGVybmFsTWVzc2FnZUNvbmZpZyBhbmQKICAgICAgICAgICAgICAgIC8vIHRoZW4gd2UnbGwgY3JlYXRlIG9uZSB3aGljaCB3b3VsZCBqdXN0IHNlbmQgZXZlbnQgb24gcGFyZW50LgogICAgICAgICAgICAgICAgd2luZG93LmZvcm1CcmlkZ2UucmVnaXN0ZXJDb25maWcoInBvc3RFeHRlcm5hbE1lc3NhZ2VDb25maWciLCB7CiAgICAgICAgICAgICAgICAgICAgInBvc3RFeHRlcm5hbEhhbmRsZXIiOiBmdW5jdGlvbiAobWVzc2FnZSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG1wRXZlbnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgiQ3VzdG9tRXZlbnQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgdG1wRXZlbnQuaW5pdEN1c3RvbUV2ZW50KG1lc3NhZ2UubmFtZSwgdHJ1ZSwgdHJ1ZSwgbWVzc2FnZS5kYXRhKTsKICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LnBhcmVudC5kaXNwYXRjaEV2ZW50KHRtcEV2ZW50KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgLy9pZ25vcmUgdGhlIGVycm9yCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICB3aW5kb3cuZm9ybUJyaWRnZS5fcG9zdEV4dGVybmFsTWVzc2FnZSh7CiAgICAgICAgbmFtZTogIkZvcm1CcmlkZ2VJbml0aWFsaXplZCIsCiAgICAgICAgZGF0YTogewogICAgICAgICAgICAiZm9ybUJyaWRnZSI6IHdpbmRvdy5mb3JtQnJpZGdlCiAgICAgICAgfQogICAgfSk7Cn0pKCQpOwoKLyoqCiAqIFRoaXMgc2hvdWxkIGhvdXNlIGFsbCB0aGUgaW50ZXJuYWwgQVBJcyBhZGRlZCB0cCBGb3JtQnJpZGdlCiAqIENyZWF0ZWQgYnkgc2FzZHV0dGEgb24gMTIvMjMvMjAxNC4KICovCgooZnVuY3Rpb24gKCQsIF8sIGZvcm1CcmlkZ2UpIHsKICAgIGZvcm1CcmlkZ2UuaW50ZXJuYWwgPSB7CgogICAgICAgIC8qKgogICAgICAgICAqIEdldCBTT00gZXhwcmVzc2lvbnMgb2YgYWxsIHRoZSBmaWVsZHMgaW4gdGhlIGZvcm0sIGluY2x1ZGluZyBtYXN0ZXIgcGFnZSBmaWVsZHMKICAgICAgICAgKgogICAgICAgICAqIEByZXR1cm4ge0FycmF5fSBvZiBzb20gZXhwcmVzc2lvbnMgYXMgc3RyaW5ncy4KICAgICAgICAgKi8KICAgICAgICBnZXRBbGxGaWVsZHNTb206IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGZpZWxkc1NvbSA9IFtdOwogICAgICAgICAgICBmdW5jdGlvbiBnZXRBbGxGaWVsZHNTb21WaXNpdG9yKHRhcmdldCkgewogICAgICAgICAgICAgICAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIHhmYWxpYi5zY3JpcHQuRmllbGQpIHsKICAgICAgICAgICAgICAgICAgICBmaWVsZHNTb20ucHVzaCh0YXJnZXQuc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcm1CcmlkZ2UuX3hmYS5mb3JtLl9nZXRSb290U3ViZm9ybSgpLl92aXNpdEFsbG1vQ2hpbGRyZW4oZ2V0QWxsRmllbGRzU29tVmlzaXRvcik7CiAgICAgICAgICAgIHJldHVybiBmaWVsZHNTb207CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHBhcmFtIHBhZ2VOdW0ge2ludH0gc2Nyb2xsIHRvIHNwZWNpZmllZCBwZyBubyBpZiBhdmFpbGFibGUKICAgICAgICAgKiBAcmV0dXJucyBub3RoaW5nCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBzY3JvbGxUb1BhZ2U6IGZ1bmN0aW9uIChwYWdlTnVtKSB7CiAgICAgICAgICAgIGlmIChwYWdlTnVtID4gMCAmJiBwYWdlTnVtIDw9IGZvcm1CcmlkZ2UucGFnaW5nTWFuYWdlcigpLnBhZ2VDb3VudCgpKSB7CiAgICAgICAgICAgICAgICBmb3JtQnJpZGdlLnBhZ2luZ01hbmFnZXIoKS5fbWFrZVBhZ2UocGFnZU51bSk7CgogICAgICAgICAgICAgICAgdmFyICR0YXJnZXRQZyA9ICQoIiNsY2Zvcm1zX3hmYWZvcm1fY29udGFpbmVyIC5wYWdlIikuZXEocGFnZU51bSAtIDEpOyAvLyB6ZXJvIGJhc2VkIGluZGV4IGluIEpRCgogICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgJCh3aW5kb3cpLnNjcm9sbFRvcCgkdGFyZ2V0UGcub2Zmc2V0KCkudG9wKTsgLy8gbmV3bHkgYWRkZWQgcGFnZXMgbmVlZCB0aW1lIHRvIHJlbmRlcgogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICByZXNvbHZlTm9kZTogZnVuY3Rpb24gKHNvbUV4cHJlc3Npb24pIHsKICAgICAgICAgICAgcmV0dXJuIGZvcm1CcmlkZ2UuX3hmYS5yZXNvbHZlTm9kZShzb21FeHByZXNzaW9uKTsKICAgICAgICB9LAoKICAgICAgICBwYWdlQ291bnQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIGZvcm1CcmlkZ2UucGFnaW5nTWFuYWdlcigpLnBhZ2VDb3VudCgpOwogICAgICAgIH0sCgogICAgICAgIHBhZ2U6IGZ1bmN0aW9uIChmaWVsZE5vZGUpIHsKICAgICAgICAgICAgcmV0dXJuIGZvcm1CcmlkZ2UuX3hmYS4kbGF5b3V0LnBhZ2UoZmllbGROb2RlKTsKICAgICAgICB9LAoKICAgICAgICBub3JtYWxpemVTb206IGZ1bmN0aW9uIChzb20pIHsKICAgICAgICAgICAgLy8gYWRkaW5nIGluZGV4IGFuZCBwcmVmaXggdG8gdGhlIHNvbSBleHByZXNzaW9uIGFzIG9idGFpbmVkIGZyb20gZGVzaWduZXIKICAgICAgICAgICAgaWYoIV8uaXNTdHJpbmcoc29tKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc29tID0gc29tLnJlcGxhY2UoL1xzL2csICcnKTsKICAgICAgICAgICAgdmFyIHhmYVByZWZpeCA9ICJ4ZmFbMF0uZm9ybVswXS4iLAogICAgICAgICAgICAgICAgbm9ybWFsaXplZFNvbSA9IChzb20gKyAiLiIpLnJlcGxhY2UoLyhcXSk/XC4vZywgZnVuY3Rpb24gKCQwLCAkMSkgeyByZXR1cm4gJDEgPyAkMCA6ICdbMF0uJzsgfSkuc2xpY2UoMCwgLTEpOwoKICAgICAgICAgICAgaWYobm9ybWFsaXplZFNvbS5zbGljZSgwLHhmYVByZWZpeC5sZW5ndGgpICE9PSB4ZmFQcmVmaXgpIHsKICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRTb20gPSB4ZmFQcmVmaXggKyBub3JtYWxpemVkU29tOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBub3JtYWxpemVkU29tOwogICAgICAgIH0KICAgIH07Cn0oJCwgXywgd2luZG93LmZvcm1CcmlkZ2UpKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiAgX19fX19fX19fX19fX19fX19fXwogKgogKiAgIENvcHlyaWdodCAyMDEzIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiAgdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiAgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiAgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqICBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsIHByb3BlcnR5CiAqICBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiAgaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogVGhpcyBvYmplY3QgaG9zdHMgRm9ybUNhbGMgYnVpbGQtaW4gZnVuY3Rpb25zCiAqLwpGb3JtQ2FsYyA9IGZ1bmN0aW9uKCl7fTsKCgpGb3JtQ2FsYy5jb252ZXJ0QXJndW1lbnRzVG9BcnJheSA9IGZ1bmN0aW9uKCkgewogICAgdmFyIGFyZ3M9IFtdOwogICAgZm9yICh2YXIgaSA9IDA7aTxhcmd1bWVudHMubGVuZ3RoO2krKykgewogICAgICAgIGlmKGFyZ3VtZW50c1tpXSBpbnN0YW5jZW9mIEFycmF5KSB7CiAgICAgICAgICAgIGFyZ3MgPSBhcmdzLmNvbmNhdChhcmd1bWVudHNbaV0pCiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBhcmdzLnB1c2goYXJndW1lbnRzW2ldKQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBhcmdzOwp9CgovLy8vQXJpdGhtZXRpYyBCdWlsdC1pbiBGdW5jdGlvbnMKLyoqCiAqIFJldHVybnMgdGhlIGF2ZXJhZ2Ugb2YgdGhlIG5vbi1udWxsIGVsZW1lbnRzIG9mIGEgZ2l2ZW4gc2V0IG9mIG51bWJlcnMuCiAqLwpGb3JtQ2FsYy5hdmcgPSBmdW5jdGlvbigpewogICAgdmFyIGFyZ3MgPSB0aGlzLmNvbnZlcnRBcmd1bWVudHNUb0FycmF5LmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKCXJldHVybiBGb3JtQ2FsYy5ydW5XaXRoTnVtZXJpY0FyZ3MoZnVuY3Rpb24oKXsKICAgICAgICB2YXIgc3VtID0gMCA7CiAgICAgICAgdmFyIHZhbGlkX2NvdW50ID0gMDsKICAgICAgICBmb3IodmFyIGlkeD0wOyBpZHg8YXJndW1lbnRzLmxlbmd0aDsgaWR4KysgKXsKICAgICAgICAJCXN1bSArPSBhcmd1bWVudHNbaWR4XTsKICAgICAgICAJCXZhbGlkX2NvdW50Kys7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2YWxpZF9jb3VudCA/IHN1bS92YWxpZF9jb3VudCA6bnVsbDsKCX0sIGFyZ3MpOwp9OwoKLyoqCiAqIFJldHVybnMgdGhlIGNvdW50IG9mIHRoZSBub24tbnVsbCBlbGVtZW50cyBvZiBhIGdpdmVuIHNldCBvZiBudW1iZXJzLgogKi8KRm9ybUNhbGMuY291bnQgPSBmdW5jdGlvbigpewogICAgdmFyIGFyZ3MgPSB0aGlzLmNvbnZlcnRBcmd1bWVudHNUb0FycmF5LmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgIHZhciBhcmd1cyA9IEZvcm1DYWxjLmxpbWl0QWxsTnVsbEFyZ3MoYXJncyk7CglyZXR1cm4gYXJndXMubGVuZ3RoID8gYXJndXMubGVuZ3RoIDogMAp9OwoKLyoqCiAqIFJldHVybnMgdGhlIG1heCBvZiB0aGUgbm9uLW51bGwgZWxlbWVudHMgb2YgYSBnaXZlbiBzZXQgb2YgbnVtYmVycy4KICovCkZvcm1DYWxjLm1heCA9IGZ1bmN0aW9uKCl7CiAgICB2YXIgYXJncyA9IHRoaXMuY29udmVydEFyZ3VtZW50c1RvQXJyYXkuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgcmV0dXJuIEZvcm1DYWxjLnJ1bldpdGhOdW1lcmljQXJncyhNYXRoLm1heCwgYXJncyk7Cn07CgovKioKICogUmV0dXJucyB0aGUgbWluIG9mIHRoZSBub24tbnVsbCBlbGVtZW50cyBvZiBhIGdpdmVuIHNldCBvZiBudW1iZXJzLgogKi8KRm9ybUNhbGMubWluID0gZnVuY3Rpb24oKXsKICAgIHZhciBhcmdzID0gdGhpcy5jb252ZXJ0QXJndW1lbnRzVG9BcnJheS5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICByZXR1cm4gRm9ybUNhbGMucnVuV2l0aE51bWVyaWNBcmdzKE1hdGgubWluLCBhcmdzKTsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBtb2R1bHVzIG9mIG9uZSBudW1iZXIgZGl2aWRlZCBieSBhbm90aGVyLi4KICovCkZvcm1DYWxjLm1vZCA9IGZ1bmN0aW9uKGEsYil7CglpZihiPT0wICl7CgkJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwoJfQoJcmV0dXJuIGElYjsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBzdW0gb2YgdGhlIG5vbi1udWxsIGVsZW1lbnRzIG9mIGEgZ2l2ZW4gc2V0IG9mIG51bWJlcnMuCiAqLwpGb3JtQ2FsYy5zdW0gPSBmdW5jdGlvbigpewogICAgdmFyIGFyZ3MgPSB0aGlzLmNvbnZlcnRBcmd1bWVudHNUb0FycmF5LmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgIHJldHVybiBGb3JtQ2FsYy5ydW5XaXRoTnVtZXJpY0FyZ3MoZnVuY3Rpb24oKXsKICAgIAl2YXIgcmVzdWx0ID0gMDsKICAgICAgICBmb3IodmFyIGlkeD0wO2lkeDxhcmd1bWVudHMubGVuZ3RoO2lkeCsrICl7CiAgICAgICAgCXJlc3VsdCArPSBhcmd1bWVudHNbaWR4XTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKCX0sIGFyZ3MpOwp9OwoKLyoqCiAqIFJldHVybnMgYSBudW1iZXIgcm91bmRlZCB0byBhIGdpdmVuIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlcwogKi8KRm9ybUNhbGMucm91bmQgPSBmdW5jdGlvbihuMSxuMil7CglpZighRm9ybUNhbGMuaXNOdW1lcmljKG4xKSl7CgkJcmV0dXJuIDA7Cgl9CglpZihhcmd1bWVudHMubGVuZ3RoID09IDEpIHsKICAgICAgICByZXR1cm4gTWF0aC5yb3VuZChuMSk7CiAgICB9ZWxzZSBpZihhcmd1bWVudHMubGVuZ3RoID09IDIpewogICAgCWlmKG4yPT1udWxsKXsKICAgIAkJcmV0dXJuIG51bGw7CiAgICAJfQogICAgCQogICAgCW4xID0gcGFyc2VGbG9hdChuMSk7CiAgICAJaWYobjIgPiAxMil7CiAgICAJCW4yID0gMTI7CiAgICAJfQogICAgCWlmKGlzTmFOKG4xKSB8fCAhaXNGaW5pdGUobjEpKXsKICAgIAkJcmV0dXJuIG4xOwogICAgCX1lbHNlewogICAgCQlyZXR1cm4gbjEudG9GaXhlZChuMik7ICAgIAkJCiAgICAJfQkKICAgIH0KfTsKCi8qKgogKiBSZXR1cm5zIHRoZSByYWRpYW4gdmFsdWUgb2YgYSBnaXZlbiBudW1iZXIuCiAqLwpGb3JtQ2FsYy5kZWcyUmFkID0gZnVuY3Rpb24oYW5nbGUpewoJcmV0dXJuIEZvcm1DYWxjLmlzTnVtZXJpYyhhbmdsZSkgPyAoYW5nbGUgLyAxODApICogTWF0aC5QSSA6bnVsbDsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBkZWdyZWUgdmFsdWUgb2YgYSBnaXZlbiBudW1iZXIuCiAqLwpGb3JtQ2FsYy5yYWQyRGVnID0gZnVuY3Rpb24ocmFkaW8pewoJcmV0dXJuIEZvcm1DYWxjLmlzTnVtZXJpYyhyYWRpbykgPyByYWRpbyAqIDE4MCAvIE1hdGguUEkgOiBudWxsOwkKfTsKLy8vL1N0cmluZyBCdWlsdC1pbiBGdW5jdGlvbnMgCi8qKgogKiBMb2NhdGVzIHRoZSBzdGFydGluZyBjaGFyYWN0ZXIgcG9zaXRpb24gb2Ygc3RyaW5nIHMyIHdpdGhpbiBzdHJpbmcgczEuCiAqLwpGb3JtQ2FsYy5hdCA9IGZ1bmN0aW9uKG4xLG4yKXsKCXJldHVybiBuMS5pbmRleE9mKG4yKSArIDE7Cn07CgovKioKICogUmV0dXJucyB0aGUgc3RyaW5nIGNvbmNhdGVuYXRpb24gb2YgYSBnaXZlbiBzZXQgb2Ygc3RyaW5ncy4KICovCkZvcm1DYWxjLmNvbmNhdCA9IGZ1bmN0aW9uKCl7Cgl2YXIgc0FycmF5ID0gbmV3IEFycmF5KCk7Cglmb3IodmFyIGk9MDtpPGFyZ3VtZW50cy5sZW5ndGg7aSsrKXsKCQlpZihhcmd1bWVudHNbaV0hPW51bGwpewoJCQlzQXJyYXlbc0FycmF5Lmxlbmd0aF0gPSBhcmd1bWVudHNbaV0udG9TdHJpbmcoKTsKCQl9Cgl9CgoJaWYoc0FycmF5Lmxlbmd0aCA9PSAwKXsKCQlyZXR1cm4gbnVsbDsKCX1lbHNlewoJCXJldHVybiBzQXJyYXkuam9pbigiIik7Cgl9Cn07CgovKioKICogRXh0cmFjdHMgYSBudW1iZXIgb2YgY2hhcmFjdGVycyBmcm9tIGEgZ2l2ZW4gc3RyaW5nLCAKICogc3RhcnRpbmcgd2l0aCB0aGUgZmlyc3QgY2hhcmFjdGVyIG9uIHRoZSBsZWZ0LgogKi8KRm9ybUNhbGMubGVmdCA9IGZ1bmN0aW9uKHMsbil7CglpZihzPT1udWxsKXsKCQlyZXR1cm4gbnVsbDsKCX0KCXJldHVybiBzLnN1YnN0cmluZygwLG4pOwp9OwoKLyoqCiAqIEV4dHJhY3RzIGEgbnVtYmVyIG9mIGNoYXJhY3RlcnMgZnJvbSBhIGdpdmVuIHN0cmluZywgCiAqIGJlZ2lubmluZyB3aXRoIHRoZSBsYXN0IGNoYXJhY3RlciBvbiB0aGVyaWdodC4KICovCgpGb3JtQ2FsYy5yaWdodCA9IGZ1bmN0aW9uKHMsbil7CglpZihzPT1udWxsKXsKCQlyZXR1cm4gbnVsbDsKCX0KCXJldHVybiBzLnN1YnN0cmluZyhzLmxlbmd0aC1uLHMubGVuZ3RoKTsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBhIGdpdmVuIHN0cmluZy4KICovCkZvcm1DYWxjLmxlbiA9IGZ1bmN0aW9uKHMpewoJaWYocz09bnVsbCl7CgkJcmV0dXJuIDA7Cgl9ZWxzZXsKCQlyZXR1cm4gcy50b1N0cmluZygpLmxlbmd0aDsJCQoJfQp9OwoKLyoqCiAqIFJldHVybnMgYSBzdHJpbmcgd2l0aCBhbGwgbGVhZGluZyB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXJzIHJlbW92ZWQuCiAqLwpGb3JtQ2FsYy5sdHJpbSA9IGZ1bmN0aW9uKHMpewoJaWYocz09bnVsbCl7CgkJcmV0dXJuIG51bGw7Cgl9CglyZXR1cm4gcy5yZXBsYWNlKC9eXHMrLywiIik7Cn07CgovKioKICogUmV0dXJucyBhIHN0cmluZyB3aXRoIGFsbCB0cmFpbGluZyB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXJzIHJlbW92ZWQuCiAqLwpGb3JtQ2FsYy5ydHJpbSA9IGZ1bmN0aW9uKHMpewoJaWYocyA9PSBudWxsKXsKCQlyZXR1cm4gbnVsbDsKCX0KCXJldHVybiBzLnJlcGxhY2UoL1xzKyQvLCIiKTsKfTsKCi8qKgogKiBSZXBsYWNlcyBhbGwgb2NjdXJyZW5jZXMgb2Ygb25lIHN0cmluZyB3aXRoIGFub3RoZXIgd2l0aGluIGEgZ2l2ZW4gc3RyaW5nLgogKi8KRm9ybUNhbGMucmVwbGFjZSA9IGZ1bmN0aW9uKHMxLCBzMiwgczMpIHsKCWlmKHMxID09IG51bGwpewoJCXJldHVybiBudWxsOwoJfQoJaWYgKHVuZGVmaW5lZCA9PSBzMykgewoJCXMzID0gIiI7Cgl9CglyZXR1cm4gczEucmVwbGFjZShzMiwgczMpOwp9OwoKLyoqCiAqIHJldHVybnMgYSBzdHJpbmcgY29uc2lzdGluZyBvZiBhIGdpdmVuIG51bWJlciBvZiBibGFuayBzcGFjZXMuCiAqLwpGb3JtQ2FsYy5zcGFjZSA9IGZ1bmN0aW9uKG4pewoJdmFyIHNBcnJheSA9IG5ldyBBcnJheSgpOwoJdmFyIG51bSA9IE1hdGguZmxvb3Iobik7Cglmb3IodmFyIGk9MDtpPG51bTtpKyspewoJCXNBcnJheVtzQXJyYXkubGVuZ3RoXT0iICI7Cgl9CglyZXR1cm4gc0FycmF5LmpvaW4oIiIpOwp9OwoKLyoqCiAqIEV4dHJhY3RzIGEgcG9ydGlvbiBvZiBhIGdpdmVuIHN0cmluZy4KICogCiAqLwpGb3JtQ2FsYy5zdWJzdHIgPSBmdW5jdGlvbihzMSxuMSxuMil7CiAgICBpZihuMjw9MCl7CiAgICAJcmV0dXJuICIiOwogICAgfQogICAgaWYobjEgPCAxKXsKICAgIAluMSA9IDE7CiAgICB9IGVsc2UgaWYobjEgPiBzMS5sZW5ndGgpewogICAgCW4xID0gczEubGVuZ3RoOwogICAgfQoJcmV0dXJuIHMxLnN1YnN0cmluZyhuMS0xLG4xLTErbjIpOwp9OwoKLyoqCiAqIEluc2VydHMgYSBzdHJpbmcgaW50byBhbm90aGVyIHN0cmluZy4KICogCiAqLwpGb3JtQ2FsYy5zdHVmZiA9IGZ1bmN0aW9uKHMxLCBuMSwgbjIsIHMyKXsKICAgIGlmKG4yPDApewogICAgCW4yPTA7CiAgICB9CiAgICBpZihuMSA8IDEpewogICAgCW4xID0gMTsKICAgIH0gZWxzZSBpZihuMSA+IHMxLmxlbmd0aCl7CiAgICAJbjEgPSBzMS5sZW5ndGg7CiAgICB9CiAgICBpZihzMiA9PSB1bmRlZmluZWQpewogICAgCXMyPSIiOwogICAgfQoJcmV0dXJuIHMxLnN1YnN0cmluZygwLCBuMS0xKSArIHMyICsgczEuc3Vic3RyaW5nKG4xICsgbjItMSxzMS5sZW5ndGgpOwp9OwoKLyoqCiAqIFJldHVybnMgYSBzdHJpbmcgd2hlcmUgYWxsIGdpdmVuIHVwcGVyY2FzZSBjaGFyYWN0ZXJzIGFyZSBjb252ZXJ0ZWQgdG8gbG93ZXJjYXNlLgogKi8KRm9ybUNhbGMubG93ZXIgPSBmdW5jdGlvbihzMSl7CglpZihzMT09bnVsbCl7CgkJcmV0dXJuIG51bGw7Cgl9ZWxzZXsKCQlyZXR1cm4gczEudG9Mb3dlckNhc2UoKTsJCQoJfQp9OwoKLyoqCiAqIFJldHVybnMgYSBzdHJpbmcgd2l0aCBhbGwgZ2l2ZW4gbG93ZXJjYXNlIGNoYXJhY3RlcnMgY29udmVydGVkIHRvIHVwcGVyY2FzZS4KICovCkZvcm1DYWxjLnVwcGVyID0gZnVuY3Rpb24oczEpewoJaWYoczE9PW51bGwpewoJCXJldHVybiBudWxsOwoJfWVsc2V7CgkJcmV0dXJuIHMxLnRvVXBwZXJDYXNlKCk7CQkKCX0KfTsKCi8qKgogKiBTZWxlY3RzIGEgdmFsdWUgZnJvbSBhIGdpdmVuIHNldCBvZiBwYXJhbWV0ZXJzLgogKi8KRm9ybUNhbGMuY2hvb3NlID0gZnVuY3Rpb24objEsczEpewoJaWYobjEgPCAxKXsKCQlyZXR1cm4gIiI7Cgl9CglpZihuMSA8IGFyZ3VtZW50cy5sZW5ndGgpewoJCXJldHVybiBhcmd1bWVudHNbbjFdOwoJfSBlbHNlIHsKCQlyZXR1cm4gIiI7Cgl9Cn07CgkKLyoqCiAqIFJldHVybnMgdHJ1ZSBpZiBhIHZhbHVlIGlzIGluIGEgZ2l2ZW4gc2V0LgogKi8KRm9ybUNhbGMub25lb2YgPSBmdW5jdGlvbihzMSwgczIpewoJZm9yKHZhciBpZHggPSAxOyBpZHggPCBhcmd1bWVudHMubGVuZ3RoOyBpZHgrKyl7CgkJaWYoczEgPT0gYXJndW1lbnRzW2lkeF0pewoJCQlyZXR1cm4gdHJ1ZTsKCQl9Cgl9CglyZXR1cm4gZmFsc2U7Cn07CgovKioKICogVGhpcyBsb2dpY2FsIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSBpZiBhIHZhbHVlIGlzIHdpdGhpbiBhIGdpdmVuIHJhbmdlLgogKi8KRm9ybUNhbGMud2l0aGluID0gZnVuY3Rpb24oczEsIHMyLCBzMyl7CglyZXR1cm4gKHMxPj1zMiAmJiBzMTw9czMpOwp9CgovKioKICogCiAqLwpGb3JtQ2FsYy5pZmZ1biA9IGZ1bmN0aW9uKHMxLCBzMiwgczMpewoJRm9ybUNhbGMuY2hlY2tNaW5BcmdzKGFyZ3VtZW50cy5sZW5ndGgsIDIpOwoJRm9ybUNhbGMuY2hlY2tNYXhBcmdzKGFyZ3VtZW50cy5sZW5ndGgsIDMpOwoJaWYoczEpewoJCXJldHVybiBzMjsKCX1lbHNlewoJCXJldHVybiBzMzsKCX0KfTsKCgovKioKICogUmV0dXJucyB0aGUgYW5udWFsIHBlcmNlbnRhZ2UgcmF0ZSBmb3IgYSBsb2FuLgogKi8KRm9ybUNhbGMuYXByID0gZnVuY3Rpb24oblByaW5jaXBhbCwgblBheW1lbnQsIG5QZXJpb2RzKSB7CglGb3JtQ2FsYy5jaGVja01pbkFyZ3MoYXJndW1lbnRzLmxlbmd0aCwgMyk7CglGb3JtQ2FsYy5jaGVja01heEFyZ3MoYXJndW1lbnRzLmxlbmd0aCwgMyk7CglpZiAoblByaW5jaXBhbCA8PSAwIHx8IG5QYXltZW50IDw9IDAgfHwgblBlcmlvZHMgPCAwKSB7CgkJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwoJfQoJCgl2YXIgbWF4SXRlcmF0aW9ucyA9IDUwMDsKCXZhciBlcHMgPSAwLjAwNTsKCXZhciBkZWx0YSA9IDAuMDAwMDAwMTsKCXZhciBuSW50ZXJlc3QgPSAwLjA1OwoJdmFyIG5QbXRaZXJvID0gblByaW5jaXBhbCAvIG5QZXJpb2RzOwoJdmFyIG5QbXRDdXIgPSBGb3JtQ2FsYy5sb2FuUG10KG5QcmluY2lwYWwsIG5JbnRlcmVzdCwgblBlcmlvZHMpOwoJdmFyIGkgPSAxOwoKCWRvIHsKCQlpZiAoTWF0aC5hYnMoblBtdEN1ciAtIG5QbXRaZXJvKSA8IGRlbHRhKQoJCQlicmVhazsKCQluSW50ZXJlc3QgKj0gKG5QYXltZW50IC0gblBtdFplcm8pIC8gKG5QbXRDdXIgLSBuUG10WmVybyk7CgkJblBtdEN1ciA9IEZvcm1DYWxjLmxvYW5QbXQoblByaW5jaXBhbCwgbkludGVyZXN0LCBuUGVyaW9kcyk7Cgl9IHdoaWxlICghKCsraSA+IG1heEl0ZXJhdGlvbnMgfHwgTWF0aC5hYnMoblBheW1lbnQgLSBuUG10Q3VyKSA8IGVwcykpOwoJdmFyIG5SYXRlID0gKE1hdGguYWJzKG5QbXRDdXIgLSBuUG10WmVybykgPCBkZWx0YSkgPyAwIDogMTIgKiBuSW50ZXJlc3Q7CglyZXR1cm4gRm9ybUNhbGMuY2hlY2tSZXN1bHQoblJhdGUpOwp9OwoKLyoqCiAqIFJldHVybnMgdGhlIG51bWJlciBvZiBwZXJpb2RzIG5lZWRlZCBmb3IgYW4gaW52ZXN0bWVudCBlYXJuaW5nIGEgZml4ZWQsIGJ1dCBjb21wb3VuZGVkLAogKiBpbnRlcmVzdCByYXRlIHRvIGdyb3cgdG8gYSBmdXR1cmUgdmFsdWUuCiAqLwpGb3JtQ2FsYy5jdGVybSA9IGZ1bmN0aW9uKG5JbnRlcmVzdCwgbkZ1dHVyZSwgblByZXNlbnQpIHsKCUZvcm1DYWxjLmNoZWNrTWluQXJncyhhcmd1bWVudHMubGVuZ3RoLCAzKTsKCUZvcm1DYWxjLmNoZWNrTWF4QXJncyhhcmd1bWVudHMubGVuZ3RoLCAzKTsKCWlmIChuSW50ZXJlc3QgPD0gMCB8fCBuRnV0dXJlIDw9IDAgfHwgblByZXNlbnQgPCAwKSB7CgkJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwoJfQoJdmFyIG5QZXJpb2RzID0gTWF0aC5sb2cobkZ1dHVyZSAvIG5QcmVzZW50KSAvIE1hdGgubG9nKDEgKyBuSW50ZXJlc3QpOwoJcmV0dXJuIEZvcm1DYWxjLmNoZWNrUmVzdWx0KG5QZXJpb2RzKTsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBmdXR1cmUgdmFsdWUgb2YgcGVyaW9kaWMgY29uc3RhbnQgcGF5bWVudHMgYXQgYSBjb25zdGFudCBpbnRlcmVzdCByYXRlLgogKi8KRm9ybUNhbGMuZnYgPSBmdW5jdGlvbihuUGF5bWVudCwgbkludGVyZXN0LCBwblBlcmlvZHMpIHsKCUZvcm1DYWxjLmNoZWNrTWluQXJncyhhcmd1bWVudHMubGVuZ3RoLCAzKTsKCUZvcm1DYWxjLmNoZWNrTWF4QXJncyhhcmd1bWVudHMubGVuZ3RoLCAzKTsKCXZhciBuUGVyaW9kcyA9IHBhcnNlSW50KHBuUGVyaW9kcyk7CglpZiAoblBlcmlvZHMgPD0gMCB8fCBuUGF5bWVudCA8PSAwIHx8IG5JbnRlcmVzdCA8IDApIHsKCQl0aHJvdyAiPG1pc3Npbmcgb3IgaWxsZWdhbCBwYXJhbWV0ZXIocykuPiI7Cgl9CgoJdmFyIG5WYWw7CglpZiAobkludGVyZXN0ID09IDApIHsKCQluVmFsID0gblBheW1lbnQgKiBuUGVyaW9kczsKCX0gZWxzZSB7CgkJblZhbCA9IG5QYXltZW50ICogKDEgKyBuSW50ZXJlc3QpCgkJCQkqIChGb3JtQ2FsYy5pbnRSYXRlKG5JbnRlcmVzdCwgblBlcmlvZHMgLSAxKSAtIDEpIC8gbkludGVyZXN0ICsgblBheW1lbnQ7Cgl9CgoJcmV0dXJuIEZvcm1DYWxjLmNoZWNrUmVzdWx0KG5WYWwpOwp9OwoKLyoqCiAqIFJldHVybnMgdGhlIGFtb3VudCBvZiBpbnRlcmVzdCBwYWlkIG9uIGEgbG9hbiBvdmVyIGEgcGVyaW9kIG9mIHRpbWUuCiAqCiAqLwpGb3JtQ2FsYy5pcG10ID0gZnVuY3Rpb24oblByaW5jaXBhbCwgbkludGVyZXN0LCBuUGF5bWVudCwgblN0YXJ0LCBuTW9udGhzKSB7CglGb3JtQ2FsYy5jaGVja01pbkFyZ3MoYXJndW1lbnRzLmxlbmd0aCwgNSk7CglGb3JtQ2FsYy5jaGVja01heEFyZ3MoYXJndW1lbnRzLmxlbmd0aCwgNSk7CiAgICBpZihuUHJpbmNpcGFsIDw9MCB8fCBuSW50ZXJlc3QgPD0wIHx8blBheW1lbnQgPD0wICB8fG5TdGFydDwxIHx8bk1vbnRoczwxKXsKICAgIAl0aHJvdyAiPG1pc3Npbmcgb3IgaWxsZWdhbCBwYXJhbWV0ZXIocykuPiI7CiAgICB9CgkKCW5JbnRlcmVzdCAvPSAxMjsKCW5TdGFydCA9IHBhcnNlRmxvYXQoblN0YXJ0KTsKCW5Nb250aHMgPSBwYXJzZUZsb2F0KG5Nb250aHMpOwoJaWYgKG5QYXltZW50IDw9IG5QcmluY2lwYWwgKiBuSW50ZXJlc3QpIHsKCQlyZXR1cm4gMDsKCX0gZWxzZSBpZiAobk1vbnRocyArIG5TdGFydCAtIDEgPiBGb3JtQ2FsYy5sb2FuVGVybShuUHJpbmNpcGFsLCBuSW50ZXJlc3QsIG5QYXltZW50KSkgewoJCXJldHVybiAwOwoJfSBlbHNlIHsKCQl2YXIgblByaW5jaXBhbFJlbWFpbmluZyA9IG5QcmluY2lwYWw7CgkJdmFyIG5QcmluY2lwYWxQYWlkSW5QZXJpb2QgPSAwOwoJCXZhciBuSW50ZXJlc3RQYWlkSW5QZXJpb2QgPSAwOwoJCWZvciAoIHZhciBpID0gMTsgaSA8IG5TdGFydDsgaSsrKSB7CgkJCW5JbnRlcmVzdFBhaWRJblBlcmlvZCA9IG5QcmluY2lwYWxSZW1haW5pbmcgKiBuSW50ZXJlc3Q7CgkJCW5QcmluY2lwYWxQYWlkSW5QZXJpb2QgPSBuUGF5bWVudCAtIG5JbnRlcmVzdFBhaWRJblBlcmlvZDsKCQkJblByaW5jaXBhbFJlbWFpbmluZyAtPSBuUHJpbmNpcGFsUGFpZEluUGVyaW9kOwoJCQlpZiAoblByaW5jaXBhbFJlbWFpbmluZyA8PSAwKQoJCQkJYnJlYWs7CgkJfQoJCXZhciBuSW50ZXJlc3RQYWlkID0gMC47CgkJZm9yICggdmFyIGkgPSBuU3RhcnQ7IGkgPCBuU3RhcnQgKyBuTW9udGhzOyBpKyspIHsKCQkJbkludGVyZXN0UGFpZEluUGVyaW9kID0gblByaW5jaXBhbFJlbWFpbmluZyAqIG5JbnRlcmVzdDsKCQkJblByaW5jaXBhbFBhaWRJblBlcmlvZCA9IG5QYXltZW50IC0gbkludGVyZXN0UGFpZEluUGVyaW9kOwoJCQluUHJpbmNpcGFsUmVtYWluaW5nIC09IG5QcmluY2lwYWxQYWlkSW5QZXJpb2Q7CgkJCW5JbnRlcmVzdFBhaWQgKz0gbkludGVyZXN0UGFpZEluUGVyaW9kOwoJCQlpZiAoblByaW5jaXBhbFJlbWFpbmluZyA8PSAwKQoJCQkJYnJlYWs7CgkJfQoJCXJldHVybiBGb3JtQ2FsYy5jaGVja1Jlc3VsdChuSW50ZXJlc3RQYWlkKTsKCX0KfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBuZXQgcHJlc2VudCB2YWx1ZSBvZiBhbiBpbnZlc3RtZW50IGJhc2VkIG9uIGEgZGlzY291bnQgcmF0ZSwgYW5kIGEgc2VyaWVzIG9mCiAqIHBlcmlvZGljIGZ1dHVyZSBjYXNoIGZsb3dzLgogKgogKi8KRm9ybUNhbGMubnB2ID0gZnVuY3Rpb24oKXsKCUZvcm1DYWxjLmNoZWNrTWluQXJncyhhcmd1bWVudHMubGVuZ3RoLCAxKTsKCgl2YXIgbkRpc2NvdW50UmF0ZSA9IEZvcm1DYWxjLnBhcnNlRmxvYXQoYXJndW1lbnRzWzBdKTsKICAgIGlmKG5EaXNjb3VudFJhdGU8PTApewogICAgCXRocm93ICI8bWlzc2luZyBvciBpbGxlZ2FsIHBhcmFtZXRlcihzKS4+IjsKICAgIH0JCgkKCXZhciBuVmFsID0gMDsKCXZhciBuRGVub20gPSAxOwoJZm9yICggdmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7CgkJaWYobnVsbCA9PSBhcmd1bWVudHNbaV0pewoJCQlyZXR1cm4gbnVsbDsKCQl9CgkJbkRlbm9tICo9ICgxICsgbkRpc2NvdW50UmF0ZSk7CgkJblZhbCArPSBGb3JtQ2FsYy5wYXJzZUZsb2F0KGFyZ3VtZW50c1tpXSkgLyBuRGVub207Cgl9CglyZXR1cm4gRm9ybUNhbGMuY2hlY2tSZXN1bHQoblZhbCk7Cgp9OwoKLyoqCiAqIFJldHVybnMgdGhlIHBheW1lbnQgZm9yIGEgbG9hbiBiYXNlZCBvbiBjb25zdGFudCBwYXltZW50cyBhbmQgYSBjb25zdGFudCBpbnRlcmVzdCByYXRlLgogKi8KRm9ybUNhbGMucG10ID0gZnVuY3Rpb24oblByaW5jaXBhbCwgbkludGVyZXN0LCBuUGVyaW9kcykgewoJRm9ybUNhbGMuY2hlY2tNaW5BcmdzKGFyZ3VtZW50cy5sZW5ndGgsIDMpOwoJRm9ybUNhbGMuY2hlY2tNYXhBcmdzKGFyZ3VtZW50cy5sZW5ndGgsIDMpOwoJaWYoblByaW5jaXBhbCA8PTAgfHwgbkludGVyZXN0PD0wIHx8IG5QZXJpb2RzIDw9MCl7CiAgICAJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwogICAgfQoJdmFyIG5QYXltZW50ID0gRm9ybUNhbGMubG9hblBtdChwYXJzZUZsb2F0KG5QcmluY2lwYWwpLCBwYXJzZUZsb2F0KG5JbnRlcmVzdCksCgkJCXBhcnNlSW50KG5QZXJpb2RzKSk7CglyZXR1cm4gRm9ybUNhbGMuY2hlY2tSZXN1bHQoblBheW1lbnQpOwoKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBhbW91bnQgb2YgcHJpbmNpcGFsIHBhaWQgb24gYSBsb2FuIG92ZXIgYSBwZXJpb2Qgb2YgdGltZS4KICogCiAqLwpGb3JtQ2FsYy5wcG10ID0gZnVuY3Rpb24oblByaW5jaXBhbCwgbkludGVyZXN0LCBuUGF5bWVudCwgblN0YXJ0LCBuTW9udGhzKSB7CglGb3JtQ2FsYy5jaGVja01pbkFyZ3MoYXJndW1lbnRzLmxlbmd0aCwgNSk7CglGb3JtQ2FsYy5jaGVja01heEFyZ3MoYXJndW1lbnRzLmxlbmd0aCwgNSk7CiAgICBpZihuUHJpbmNpcGFsIDw9MCB8fCBuSW50ZXJlc3QgPD0wIHx8blBheW1lbnQgPD0wICB8fG5TdGFydDwxIHx8bk1vbnRoczwxKXsKICAgIAl0aHJvdyAiPG1pc3Npbmcgb3IgaWxsZWdhbCBwYXJhbWV0ZXIocykuPiI7CiAgICB9CgkKCW5QcmluY2lwYWwgPSBwYXJzZUZsb2F0KG5QcmluY2lwYWwpOwoJbkludGVyZXN0ID0gcGFyc2VGbG9hdChuSW50ZXJlc3QpOwoJblBheW1lbnQgPSBwYXJzZUZsb2F0KG5QYXltZW50KTsKCW5TdGFydCA9IHBhcnNlSW50KG5TdGFydCk7CgluTW9udGhzID0gcGFyc2VJbnQobk1vbnRocyk7CgoJbkludGVyZXN0IC89IDEyOwoJaWYgKG5QYXltZW50IDw9IG5QcmluY2lwYWwgKiBuSW50ZXJlc3QpIHsKCQlyZXR1cm4gMDsKCX0gZWxzZSBpZiAobk1vbnRocyArIG5TdGFydCAtIDEgPiBGb3JtQ2FsYy5sb2FuVGVybShuUHJpbmNpcGFsLCBuSW50ZXJlc3QsIG5QYXltZW50KSkgewoJCXJldHVybiAwOwoJfSBlbHNlIHsKCQl2YXIgblByaW5jaXBhbFJlbWFpbmluZyA9IG5QcmluY2lwYWw7CgkJdmFyIG5QcmluY2lwYWxQYWlkSW5QZXJpb2QgPSAwOwoJCXZhciBuSW50ZXJlc3RQYWlkSW5QZXJpb2QgPSAwOwoJCWZvciAoIHZhciBpID0gMTsgaSA8IG5TdGFydDsgaSsrKSB7CgkJCW5JbnRlcmVzdFBhaWRJblBlcmlvZCA9IG5QcmluY2lwYWxSZW1haW5pbmcgKiBuSW50ZXJlc3Q7CgkJCW5QcmluY2lwYWxQYWlkSW5QZXJpb2QgPSBuUGF5bWVudCAtIG5JbnRlcmVzdFBhaWRJblBlcmlvZDsKCQkJblByaW5jaXBhbFJlbWFpbmluZyAtPSBuUHJpbmNpcGFsUGFpZEluUGVyaW9kOwoJCQlpZiAoblByaW5jaXBhbFJlbWFpbmluZyA8PSAwKQoJCQkJYnJlYWs7CgkJfQoJCXZhciBuUHJpbmNpcGxlUGFpZCA9IDA7CgkJZm9yICggdmFyIGkgPSBuU3RhcnQ7IGkgPCBuU3RhcnQgKyBuTW9udGhzOyBpKyspIHsKCQkJbkludGVyZXN0UGFpZEluUGVyaW9kID0gblByaW5jaXBhbFJlbWFpbmluZyAqIG5JbnRlcmVzdDsKCQkJblByaW5jaXBhbFBhaWRJblBlcmlvZCA9IG5QYXltZW50IC0gbkludGVyZXN0UGFpZEluUGVyaW9kOwoJCQluUHJpbmNpcGFsUmVtYWluaW5nIC09IG5QcmluY2lwYWxQYWlkSW5QZXJpb2Q7CgkJCW5QcmluY2lwbGVQYWlkICs9IG5QcmluY2lwYWxQYWlkSW5QZXJpb2Q7CgkJCWlmIChuUHJpbmNpcGFsUmVtYWluaW5nIDw9IDApCgkJCQlicmVhazsKCQl9CgkJcmV0dXJuIEZvcm1DYWxjLmNoZWNrUmVzdWx0KG5QcmluY2lwbGVQYWlkKTsKCX0KfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBwcmVzZW50IHZhbHVlIG9mIGFuIGludmVzdG1lbnQgb2YgcGVyaW9kaWMgY29uc3RhbnQgcGF5bWVudHMgYXQgYSBjb25zdGFudCAKICogaW50ZXJlc3QgcmF0ZS4KICoKICovCkZvcm1DYWxjLnB2ID0gZnVuY3Rpb24oblBheW1lbnQsIG5JbnRlcmVzdCwgblBlcmlvZHMpIHsKCUZvcm1DYWxjLmNoZWNrTWluQXJncyhhcmd1bWVudHMubGVuZ3RoLCAzKTsKCUZvcm1DYWxjLmNoZWNrTWF4QXJncyhhcmd1bWVudHMubGVuZ3RoLCAzKTsKCWlmIChuUGF5bWVudCA8PSAwIHx8IG5QZXJpb2RzIDw9IDAgKSB7CgkJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwoJfQoJaWYoblBheW1lbnQ9PW51bGwgfHwgbkludGVyZXN0PT1udWxsKXsKCQlyZXR1cm4gbnVsbDsKCX0KCXZhciBuUGF5bWVudCA9IHBhcnNlRmxvYXQoblBheW1lbnQpOwoJdmFyIG5JbnRlcmVzdCA9IHBhcnNlRmxvYXQobkludGVyZXN0KTsKCXZhciBuUGVyaW9kcyA9IHBhcnNlSW50KG5QZXJpb2RzKTsKCgl2YXIgblZhbDsKCWlmIChuSW50ZXJlc3QgPT0gMCkgewoJCW5WYWwgPSBuUGF5bWVudCAqIG5QZXJpb2RzOwoJfSBlbHNlIHsKCQluVmFsID0gblBheW1lbnQgKiAoMSAtIDEgLyBGb3JtQ2FsYy5pbnRSYXRlKG5JbnRlcmVzdCwgblBlcmlvZHMpKSAvIG5JbnRlcmVzdDsKCX0KCXJldHVybiBGb3JtQ2FsYy5jaGVja1Jlc3VsdChuVmFsKTsKfTsKCi8qKgogKiBSZXR1cm5zIHRoZSBjb21wb3VuZCBpbnRlcmVzdCByYXRlIHBlciBwZXJpb2QgcmVxdWlyZWQgZm9yIGFuIGludmVzdG1lbnQgdG8gZ3JvdyBmcm9tCiAqIHByZXNlbnQgdG8gZnV0dXJlIHZhbHVlIGluIGEgZ2l2ZW4gcGVyaW9kLgogKiAKICovCkZvcm1DYWxjLnJhdGUgPSBmdW5jdGlvbihuRnV0dXJlLCBuUHJlc2VudCwgblBlcmlvZHMpIHsKCWlmIChuRnV0dXJlIDw9IDAuIHx8IG5QcmVzZW50IDw9IDAuIHx8IG5QZXJpb2RzIDw9IDApIHsKCQl0aHJvdyAiPG1pc3Npbmcgb3IgaWxsZWdhbCBwYXJhbWV0ZXIocykuPiI7Cgl9CgoJdmFyIG5GdXR1cmUgPSBwYXJzZUZsb2F0KG5GdXR1cmUpOwoJdmFyIG5QcmVzZW50ID0gcGFyc2VGbG9hdChuUHJlc2VudCk7Cgl2YXIgblBlcmlvZHMgPSBwYXJzZUludChuUGVyaW9kcyk7CgoJdmFyIG5SYXRlID0gTWF0aC5leHAoTWF0aC5sb2cobkZ1dHVyZSAvIG5QcmVzZW50KSAvIG5QZXJpb2RzKSAtIDE7CglyZXR1cm4gRm9ybUNhbGMuY2hlY2tSZXN1bHQoblJhdGUpOwp9OwoKLyoKICogVGVybSBUaGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIG51bWJlciBvZiBwZXJpb2RzIG5lZWRlZCBmb3IgYW4gaW52ZXN0bWVudAogKiBlYXJuaW5nIGEgZml4ZWQsIGJ1dCBjb21wb3VuZGVkIGludGVyZXN0IHJhdGUgdG8gZ3JvdyB0byBhIGZ1dHVyZSB2YWx1ZS4KICovCkZvcm1DYWxjLnRlcm0gPSBmdW5jdGlvbihuUGF5bWVudCwgbkludGVyZXN0LCBuRnV0dXJlKSB7Cgl2YXIgblBheW1lbnQgPSBGb3JtQ2FsYy5wYXJzZUZsb2F0T3JUaHJvd0Vycm9yKG5QYXltZW50KTsKCXZhciBuSW50ZXJlc3QgPSBGb3JtQ2FsYy5wYXJzZUZsb2F0T3JUaHJvd0Vycm9yKG5JbnRlcmVzdCk7Cgl2YXIgbkZ1dHVyZSA9IEZvcm1DYWxjLnBhcnNlRmxvYXRPclRocm93RXJyb3IobkZ1dHVyZSk7CgoJaWYgKG5QYXltZW50IDw9IDAuIHx8IG5JbnRlcmVzdCA8PSAwLiB8fCBuRnV0dXJlIDw9IDAuKSB7CgkJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwoJfQoJCgl2YXIgblBlcmlvZHM7CglpZiAobkZ1dHVyZSA8PSBuUGF5bWVudCkgewoJCW5QZXJpb2RzID0gMTsKCX0gZWxzZSB7CgkJblBlcmlvZHMgPSBNYXRoLmxvZygobkZ1dHVyZSAtIG5QYXltZW50KSAvIG5QYXltZW50ICogbkludGVyZXN0CgkJCQkrICgxICsgbkludGVyZXN0KSkKCQkJCS8gTWF0aC5sb2coMSArIG5JbnRlcmVzdCk7Cgl9CglyZXR1cm4gRm9ybUNhbGMuY2hlY2tSZXN1bHQoblBlcmlvZHMpOwp9OwoKRm9ybUNhbGMubG9hblRlcm0gPSBmdW5jdGlvbihuUHJpbmNpcGFsLCBuSW50ZXJlc3QsIG5QYXltZW50KSB7Cgl2YXIgblJlbWFpbmluZyA9IG5QcmluY2lwYWw7Cgl2YXIgbk1vbnRocyA9IDA7Cgl3aGlsZSAoblJlbWFpbmluZyA+IDAuMCkgewoJCW5SZW1haW5pbmcgPSBuUmVtYWluaW5nIC0gblBheW1lbnQgKyBuUmVtYWluaW5nICogbkludGVyZXN0OwoJCW5Nb250aHMrKzsKCX0KCXJldHVybiBGb3JtQ2FsYy5jaGVja1Jlc3VsdChuTW9udGhzKTsKfTsKLyoqCiAqIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBhIFVuaXZlcnNhbGx5IFVuaXF1ZSBJZGVudGlmaWVyIChVVUlEKS4KICovCkZvcm1DYWxjLnV1aWQgPSBmdW5jdGlvbihuMSkgewogICAgdmFyIFM0ID0gZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuICgoKDErTWF0aC5yYW5kb20oKSkqMHgxMDAwMCl8MCkudG9TdHJpbmcoMTYpLnN1YnN0cmluZygxKTsKICAgIH07CiAgICBpZihuMT09MSl7CiAgICAgICAgcmV0dXJuIChTNCgpK1M0KCkrIi0iK1M0KCkrIi0iK1M0KCkrIi0iK1M0KCkrIi0iK1M0KCkrUzQoKStTNCgpKTsKICAgIH1lbHNlewogICAgCXJldHVybiAoUzQoKStTNCgpK1M0KCkrUzQoKStTNCgpK1M0KCkrUzQoKStTNCgpKTsKICAgIH0KfTsKLy8gUHJpdmF0ZSBmdW5jdGlvbnMKCkZvcm1DYWxjLmxvYW5QbXQgPSBmdW5jdGlvbihuUHJpbmNpcGFsLCBuSW50ZXJlc3QsIG5QZXJpb2RzKSB7CglyZXR1cm4gKG5QcmluY2lwYWwgKiBuSW50ZXJlc3QgLyAoKDEgLSAxIC8gRm9ybUNhbGMuaW50UmF0ZShuSW50ZXJlc3QsIG5QZXJpb2RzKSkpKTsKfTsKCkZvcm1DYWxjLmludFJhdGUgPSBmdW5jdGlvbihuSW50ZXJlc3QsIG5QZXJpb2RzKSB7CglyZXR1cm4gTWF0aC5wb3coKDEgKyBuSW50ZXJlc3QpLCBuUGVyaW9kcykKfTsKCkZvcm1DYWxjLnBhcnNlRmxvYXRPclRocm93RXJyb3IgPSBmdW5jdGlvbihvYmopIHsKCXZhciBudW0gPSBOdW1iZXIob2JqKTsKCWlmKGlzTmFOKG51bSkpewoJCXRocm93ICI8bWlzc2luZyBvciBpbGxlZ2FsIHBhcmFtZXRlcihzKS4+IjsKCX1lbHNlewoJCXJldHVybiBudW07Cgl9Cn07CgpGb3JtQ2FsYy5wYXJzZUZsb2F0ID0gZnVuY3Rpb24ob2JqKSB7Cgl2YXIgbnVtID0gTnVtYmVyKG9iaik7CglpZihpc05hTihudW0pKXsKCQlyZXR1cm4gMDsKCX1lbHNlewoJCXJldHVybiBudW07Cgl9Cn07CgpGb3JtQ2FsYy5jaGVja1Jlc3VsdCA9IGZ1bmN0aW9uKHJlc3VsdCkgewoJaWYgKHJlc3VsdCA9PSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgfHwgcmVzdWx0ID09IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSl7CgkgICB0aHJvdyAiPGFyaXRobWV0aWMgb3Zlci91bmRlcmZsb3cuPiI7Cgl9ZWxzZXsKCQlyZXR1cm4gcmVzdWx0OwoJfQp9OwoKRm9ybUNhbGMuaXNOdW1lcmljID0gZnVuY3Rpb24oaW5wdXQpewoJcmV0dXJuIGlucHV0IT1udWxsICYmICFpc05hTihOdW1iZXIoaW5wdXQpKTsKfTsKCkZvcm1DYWxjLmNoZWNrTWluQXJncyA9IGZ1bmN0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpIHsKCWlmKGFjdHVhbCA8IGV4cGVjdGVkKXsKCQl0aHJvdyAiPG1pc3Npbmcgb3IgaWxsZWdhbCBwYXJhbWV0ZXIocykuPiI7Cgl9Cn07CgpGb3JtQ2FsYy5jaGVja01heEFyZ3MgPSBmdW5jdGlvbihhY3R1YWwsIGV4cGVjdGVkKSB7CglpZihhY3R1YWwgPiBleHBlY3RlZCl7CgkJdGhyb3cgIjxtaXNzaW5nIG9yIGlsbGVnYWwgcGFyYW1ldGVyKHMpLj4iOwoJfQp9OwoKRm9ybUNhbGMubGltaXRBbGxOdWxsQXJncyA9IGZ1bmN0aW9uKGFycmF5QXJndXMpIHsKCXZhciByZXN1bHQgPSBuZXcgQXJyYXkoKTsKCWZvcih2YXIgaT0wO2k8YXJyYXlBcmd1cy5sZW5ndGg7aSsrKXsKCQlpZihhcnJheUFyZ3VzW2ldIT1udWxsKXsKCQkJcmVzdWx0LnB1c2goYXJyYXlBcmd1c1tpXSk7CgkJfQoJfQoJcmV0dXJuIHJlc3VsdDsKfTsKCkZvcm1DYWxjLnJ1bldpdGhvdXROdWxsQXJncyA9IGZ1bmN0aW9uKGZ1bmMsIGFycmF5QXJndXMpIHsKCXZhciBhcmd1cyA9IEZvcm1DYWxjLmxpbWl0QWxsTnVsbEFyZ3MoYXJyYXlBcmd1cyk7CglyZXR1cm4gYXJndXMubGVuZ3RoID8gZnVuYy5hcHBseShudWxsLGFyZ3VzKSA6IG51bGw7CQp9OwoKRm9ybUNhbGMucnVuV2l0aE51bWVyaWNBcmdzID0gZnVuY3Rpb24oZnVuYywgYXJyYXlBcmd1cykgewoJdmFyIGFyZ3VzID0gbmV3IEFycmF5KCk7Cglmb3IodmFyIGk9MDtpPGFycmF5QXJndXMubGVuZ3RoO2krKyl7CgkJaWYoYXJyYXlBcmd1c1tpXSE9bnVsbCl7CiAgICAgICAgCXZhciBlbCA9IHBhcnNlRmxvYXQoYXJyYXlBcmd1c1tpXSk7CiAgICAgICAgCWlmKCFpc05hTihlbCkpewogICAgICAgIAkJYXJndXMucHVzaChlbCk7CiAgICAgICAgCX0KCQl9Cgl9CgoJcmV0dXJuIGFyZ3VzLmxlbmd0aCA/IGZ1bmMuYXBwbHkobnVsbCxhcmd1cykgOiBudWxsOwkKfTsKCi8qKgogKiBUaGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIEVuZ2xpc2ggdGV4dCBlcXVpdmFsZW50IG9mIGEgZ2l2ZW4gbnVtYmVyLgogKiAKICovCkZvcm1DYWxjLldvcmROdW09ZnVuY3Rpb24oKXsKCXZhciBPbmVzPSBuZXcgQXJyYXkoIlplcm8iLCJPbmUiLCJUd28iLCJUaHJlZSIsIkZvdXIiLCJGaXZlIiwKCQkJIlNpeCIsIlNldmVuIiwiRWlnaHQiLCJOaW5lIik7Cgl2YXIgVGVlbnMgPW5ldyBBcnJheSAoIlRlbiIsIkVsZXZlbiIsIlR3ZWx2ZSIsIlRoaXJ0ZWVuIiwiRm91cnRlZW4iLAoJCQkiRmlmdGVlbiIsICJTaXh0ZWVuIiwgIlNldmVudGVlbiIsICJFaWdodGVlbiIsICJOaW5ldGVlbiIpOwoJdmFyIFRlbnM9IG5ldyBBcnJheSAoCgkJCSJaZXJvIiwgICJUZW4iLCAgICJUd2VudHkiLCAgIlRoaXJ0eSIsICJGb3J0eSIsCgkJCSJGaWZ0eSIsICJTaXh0eSIsICJTZXZlbnR5IiwgIkVpZ2h0eSIsICJOaW5ldHkiLCAiSHVuZHJlZCIgKTsKCXZhciBUaG91c2FuZHMgPSBuZXcgQXJyYXkgKAoJCQkiVGhvdXNhbmQiLCAiTWlsbGlvbiIsICAgICAiQmlsbGlvbiIsCgkJCSJUcmlsbGlvbiIsICJRdWFkcmlsbGlvbiIsICJRdWludGlsbGlvbiIgKTsKCXZhciBDZW50cyA9IG5ldyBBcnJheSgiQ2VudCIpOyAKCXZhciBDb21tYT1uZXcgQXJyYXkoIiIpOwoJdmFyIEFuZHMgID1uZXcgQXJyYXkgKCIiLCAiQW5kICIgLyogdXNlZCBieSBGRjk5ICovICk7Cgl2YXIgRG9sbGFycz1uZXcgQXJyYXkgKCAiRG9sbGFyIiApOwoJdmFyIFNwYWNlID0gIiAiOwoJdmFyIEh5cGhlbiA9ICItIjsKCXZhciBRVUlOVElMTElPTiA9IDEwMDAwMDAwMDAwMDAwMDAwMDA7Cgl2YXIgbj1hcmd1bWVudHNbMF07Cgl2YXIgZj1hcmd1bWVudHNbMV07CglpZihuID09PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICBpZihpc05hTihuKXx8IWlzRmluaXRlKG4pfHxuPDApewoJCXJldHVybiAiKioqKioqKioqKioqKioiOyAKCX0KCQoJaWYgKGYgPCAwIHx8IDIgPCBmKSB7CgkJZiA9IDA7Cgl9CgkKCXZhciBkb2xsYXJzID0gICBuOwoJdmFyIGNlbnRzID0gICAgTWF0aC5mbG9vcigoKG4gLSAgTWF0aC5mbG9vcihkb2xsYXJzKSsgMC4wMDUpICogMTAwKSk7ICAKCWlmIChjZW50cyA+PSAxMDApIHsKCQlkb2xsYXJzICs9IDE7CgkJY2VudHMgLT0gMTAwOwoJfQoJCgl2YXIgcz0gbmV3IEFycmF5KCk7Cgl2YXIgdGhvdXNhbmRzID0gNjsKCWZvciAodmFyIGRpdiA9IFFVSU5USUxMSU9OOyBkaXYgPj0gMSA7IGRpdi89MTAwMCkgeyAKCQl2YXIgbnVtYmVyID0gTWF0aC5mbG9vcihkb2xsYXJzIC8gZGl2KSA7IAoJCXZhciBodW5kcmVkcyA9IE1hdGguZmxvb3IobnVtYmVyLyAxMDApIDsKCQl2YXIgdGVucyA9IE1hdGguZmxvb3IoKG51bWJlci0gaHVuZHJlZHMgKiAxMDApIC8gMTApOwoJCXZhciBvbmVzID0gTWF0aC5mbG9vcihudW1iZXItIGh1bmRyZWRzICogMTAwIC0gdGVucyAqIDEwKTsgIAogICAgICAgICAgICAgICAgaWYobnVtYmVyPj0xKXsKICAgICAgICAgICAgICAgICAgICBkb2xsYXJzIC09IChkaXYgKiBudW1iZXIgKTsgCiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAKCQlpZiAoaHVuZHJlZHMgPj0xKSB7CgkJCXMucHVzaChPbmVzW2h1bmRyZWRzXSk7CgkJCXMucHVzaChTcGFjZSk7CgkJCXMucHVzaChUZW5zWzEwXSk7CgkJCXMucHVzaChTcGFjZSk7CgkJCWlmICh0ZW5zID4gMCB8fCBvbmVzID4gMCkKCQkJCXMucHVzaChBbmRzWzBdKTsKCQl9CgkJaWYgKHRlbnMgPj0xICkgewoJCQlzLnB1c2goKHRlbnMgPT0gMSkgPyBUZWVuc1tvbmVzXSA6IFRlbnNbdGVuc10pOwoJCQlzLnB1c2goKG9uZXMgPiAwICYmIHRlbnMgIT0gMSkgPyBIeXBoZW4gOiBTcGFjZSk7CgkJfQoJCWlmIChvbmVzID49MSAmJiB0ZW5zICE9IDEpIHsgCgkJCWlmICh0ZW5zID4gMCAmJiBvbmVzID4gMCkgewoJCQkJLy8gc2FmZSBzaW5jZSBPbmVzIGNvbnRhaW5zIHRydWUgbGl0ZXJhbCBjb25zdGFudHMKCQkJCXZhciBvID0gT25lc1tvbmVzXTsKCQkJCS8vcys9Rm9ybUNhbGMuTXlsb3dlckNhc2Uobyk7ICAKCQkJCXMucHVzaChvLnRvTG93ZXJDYXNlKCkpOyAKCQkJfQoJCQllbHNlIHsKCQkJCXMucHVzaChPbmVzW29uZXNdKTsKCQkJfQoJCQlzLnB1c2goU3BhY2UpOwoJCX0KCQl0aG91c2FuZHMtLTsKCQlpZiAodGhvdXNhbmRzID49IDAgJiYgbnVtYmVyID49IDEpIHsKCQkJcy5wdXNoKFRob3VzYW5kc1t0aG91c2FuZHNdKTsKCQkJcy5wdXNoKENvbW1hWzBdKTsKCQkJcy5wdXNoKFNwYWNlKTsKCQl9CiAKICAKCX0KCS8vCgkvLyBJZiBsZXNzIHRoYW4gb25lIHRoZW4gdXNlIHplcm8uCgkvLwoJaWYgKG4gPCAxLikgewoJCXMucHVzaChPbmVzWzBdKTsKCQlzLnB1c2goU3BhY2UpOwoJfQoJLy8KCS8vIEZhY3RvciBpbiBmb3JtYXQ6CgkvLyAgICAgMCA9PiAiT25lIEh1bmRyZWQgVHdlbnR5LXRocmVlIgoJLy8gICAgIDEgPT4gIk9uZSBIdW5kcmVkIFR3ZW50eS10aHJlZSBEb2xsYXJzIgoJLy8gICAgIDIgPT4gIk9uZSBIdW5kcmVkIFR3ZW50eS10aHJlZSBEb2xsYXJzIEFuZCBGb3J0eSBDZW50cyIKCS8vCglpZiAoZiA9PSAxIHx8IGYgPT0gMikgewoJCS8vCgkJLy8gQXBwZW5kIGRvbGxhciBDYWxjU3ltYm9sLgoJCS8vCgkJcy5wdXNoKERvbGxhcnNbMF0pOwoJCWlmICggTWF0aC5mbG9vcihuKSAhPSAxKQoJCQlzLnB1c2goJ3MnKTsKCQkvLwoJCS8vIEFwcGVuZCBjZW50cy4KCQkvLwoJCWlmIChmID09IDIpIHsKCQkJcy5wdXNoKFNwYWNlKTsKCQkJcy5wdXNoKEFuZHNbMV0pOwoJCQl2YXIgdGVucyA9ICBNYXRoLmZsb29yKGNlbnRzIC8gMTApOwoJCQl2YXIgb25lcyA9ICBNYXRoLmZsb29yKGNlbnRzIC0gdGVucyAqIDEwKTsKCQkJaWYgKHRlbnMgPiAwKSB7CgkJCQlzLnB1c2goKHRlbnMgPT0gMSkgPyBUZWVuc1tvbmVzXSA6IFRlbnNbdGVuc10pOwoJCQl9CgkJCWlmICh0ZW5zICE9IDEpIHsKCQkJCWlmICh0ZW5zID4gMCAmJiBvbmVzID4gMCkgewoJCQkJCS8vIHNhZmUgc2luY2UgT25lcyBjb250YWlucyB0cnVlIGxpdGVyYWwgY29uc3RhbnRzCgkJCQkJdmFyIG8gPSBPbmVzW29uZXNdOwoJCQkJCXMucHVzaChIeXBoZW4pOwoJCQkJCXMucHVzaChvLnRvTG93ZXJDYXNlKCkpOwoJCQkJfQoJCQkJZWxzZSBpZiAodGVucyA9PSAwKSB7CgkJCQkJcy5wdXNoKE9uZXNbb25lc10pOwoJCQkJfQoJCQl9CgkJCXMucHVzaChTcGFjZSk7CgkJCXMucHVzaChDZW50c1swXSk7CgkJCWlmIChjZW50cyAhPSAxLikKCQkJCXMucHVzaCgncycpOwoJCX0KCX0KCWlmKHNbcy5sZW5ndGgtMV0gPT0gJyAnKXsKCQlzLnBvcCgpOwkJCgl9CglyZXR1cm4gcy5qb2luKCIiKTsKfTsKCkZvcm1DYWxjLl9BY2Nlc3NvciA9IGZ1bmN0aW9uKGEpIHsKICAgIGlmKGEgJiYgdHlwZW9mKGEpID09PSAib2JqZWN0IikgewogICAgICAgIGlmKGEuY2xhc3NOYW1lID09PSAiZmllbGQiIHx8IGEuY2xhc3NOYW1lID09PSAiZXhjbEdyb3VwIikKICAgICAgICAgICAgcmV0dXJuIGEucmF3VmFsdWU7CiAgICB9CiAgICByZXR1cm4gYTsKfTsKCkZvcm1DYWxjLl9BcnJheUFjY2Vzc29yID0gZnVuY3Rpb24oYSkgewogICAgaWYodHlwZW9mKGEpID09ICJzdHJpbmciKSB7CiAgICAgICAgdmFyIGluZGV4QXJyYXkgPSBhLmxhc3RJbmRleE9mKCJdIikrIDEsCiAgICAgICAgICAgIG5vZGUgPSBhLnN1YnN0cigwLCBpbmRleEFycmF5KSwKICAgICAgICAgICAgcHJvcEluZGV4ID0gYS5pbmRleE9mKCIuIixpbmRleEFycmF5KSwKICAgICAgICAgICAgcHJvcCA9IHByb3BJbmRleCA9PSAtMSA/ICIiIDogYS5zdWJzdHIocHJvcEluZGV4ICsgMSwgYS5sZW5ndGgpLAogICAgICAgICAgICBjdHhOb2RlID0geGZhbGliLnJ1bnRpbWUueGZhLl9jb250ZXh0Tm9kZSgpLAogICAgICAgICAgICBsaXN0ID0gY3R4Tm9kZS5yZXNvbHZlTm9kZXMobm9kZSksCiAgICAgICAgICAgIHJldEFycmF5ID0gW10KICAgICAgICBmb3IodmFyIGkgPSAwO2k8bGlzdC5sZW5ndGg7aSsrKSB7CiAgICAgICAgICAgIHZhciBpdGVtID0gbGlzdC5pdGVtKGkpLAogICAgICAgICAgICAgICAgdmFsID0gcHJvcC5sZW5ndGggPyB0aGlzLl9BY2Nlc3NvcihpdGVtW3Byb3BdKSA6dGhpcy5fQWNjZXNzb3IoaXRlbSk7CiAgICAgICAgICAgIHJldEFycmF5LnB1c2godmFsKTsKICAgICAgICB9CiAgICAgICAgaWYocmV0QXJyYXkubGVuZ3RoID09IDEpCiAgICAgICAgICAgIHJldHVybiByZXRBcnJheVswXQogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuIHJldEFycmF5OwogICAgfQogICAgcmV0dXJuIGE7Cn07CgpGb3JtQ2FsYy5lcG9jaCA9IG5ldyBEYXRlKDE5MDAsMCwxKQpGb3JtQ2FsYy5lcG9jaFRpbWUgPSBGb3JtQ2FsYy5lcG9jaC5nZXRUaW1lKCkKRm9ybUNhbGMubnVtTWlsbGlzSW5EYXkgPSAyNCo2MCo2MCoxMDAwCkZvcm1DYWxjLkRhdGVGb3JtYXRzPSBbIm1lZCIsInNob3J0IiwibWVkIiwibG9uZyIsImZ1bGwiXQoKRm9ybUNhbGMubnVtMmRhdGUgPSBmdW5jdGlvbihuLGZtdCxsb2NhbGUpIHsKICAgIGZ1bmN0aW9uIHBhZDIobnVtKSB7CiAgICAgICAgcmV0dXJuICgrbnVtKT45ID8gbnVtKyIiIDogIjAiK251bTsKICAgIH0KICAgIGxvY2FsZSA9IGxvY2FsZSB8fCAiZW5fVVMiCiAgICBmbXQgPSBmbXQgfHwgRm9ybUNhbGMuRGF0ZUZtdCgwLGxvY2FsZSk7CiAgICB2YXIgZXBvY2ggPSBuZXcgRGF0ZSgxOTAwLDAsMSkKICAgIGVwb2NoLnNldERhdGUobik7CiAgICB2YXIgaW5wdXREYXRlID0gZXBvY2guZ2V0RnVsbFllYXIoKSsiLSIrcGFkMigoZXBvY2guZ2V0TW9udGgoKSsxKSkrIi0iK3BhZDIoZXBvY2guZ2V0RGF0ZSgpKTsKICAgIHJldHVybiB4ZmFsaWIudXQuUGljdHVyZUZtdC5mb3JtYXREYXRlKGlucHV0RGF0ZSxmbXQsbG9jYWxlKTsKfQoKRm9ybUNhbGMuZGF0ZSA9IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIE1hdGguY2VpbCgobmV3IERhdGUoKS5nZXRUaW1lKCkgLSB0aGlzLmVwb2NoVGltZSkvdGhpcy5udW1NaWxsaXNJbkRheSkKfQoKRm9ybUNhbGMuRGF0ZUZtdCA9IGZ1bmN0aW9uKHN5bWJvbCxsb2NhbGUpIHsKICAgIHN5bWJvbCA9IHN5bWJvbCB8fCAwCiAgICBsb2NhbGUgPSBsb2NhbGUgfHwgImVuX1VTIgogICAgcmV0dXJuIHhmYWxpYi5zY3JpcHQuWGZhLkluc3RhbmNlLl9nZXRMb2NhbGVTeW1ib2xzKGxvY2FsZSwiZGF0ZVBhdHRlcm5zLiIrRm9ybUNhbGMuRGF0ZUZvcm1hdHNbc3ltYm9sXSkKfTsKLyoKICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqIF9fX19fX19fX19fX19fX19fXwogKgogKiBDb3B5cmlnaHQgMjAxNSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiBzdXBwbGllcnMgYW5kIG1heSBiZSBjb3ZlcmVkIGJ5IFUuUy4gYW5kIEZvcmVpZ24gUGF0ZW50cywKICogcGF0ZW50cyBpbiBwcm9jZXNzLCBhbmQgYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqLwoKKGZ1bmN0aW9uICgkKSB7CiAgICAkLnVhTWF0Y2ggPSBmdW5jdGlvbiggdWEgKSB7CiAgICAgICAgdWEgPSB1YS50b0xvd2VyQ2FzZSgpOwogICAgICAgIHZhciBtYXRjaCA9IC8oY2hyb21lKVsgXC9dKFtcdy5dKykvLmV4ZWMoIHVhICkgfHwKICAgICAgICAgICAgLyh3ZWJraXQpWyBcL10oW1x3Ll0rKS8uZXhlYyggdWEgKSB8fAogICAgICAgICAgICAvKG9wZXJhKSg/Oi4qdmVyc2lvbnwpWyBcL10oW1x3Ll0rKS8uZXhlYyggdWEgKSB8fAogICAgICAgICAgICAvKG1zaWUpIChbXHcuXSspLy5leGVjKCB1YSApIHx8CiAgICAgICAgICAgIHVhLmluZGV4T2YoImNvbXBhdGlibGUiKSA8IDAgJiYgLyhtb3ppbGxhKSg/Oi4qPyBydjooW1x3Ll0rKXwpLy5leGVjKCB1YSApIHx8IFtdOwogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIGJyb3dzZXI6IG1hdGNoWyAxIF0gfHwgIiIsCiAgICAgICAgICAgIHZlcnNpb246IG1hdGNoWyAyIF0gfHwgIjAiCiAgICAgICAgfTsKICAgIH07CiAgICAvLyBOb3QgY2xvYmJlcmluZyBhbnkgZXhpc3RpbmcgJC5icm93c2VyCiAgICBpZiAoICEkLmJyb3dzZXIgKSB7CiAgICAgICAgdmFyCiAgICAgICAgICAgIG1hdGNoZWQgPSAkLnVhTWF0Y2goIG5hdmlnYXRvci51c2VyQWdlbnQgKSwKICAgICAgICAgICAgYnJvd3NlciA9IHt9OwogICAgICAgIGlmICggbWF0Y2hlZC5icm93c2VyICkgewogICAgICAgICAgICBicm93c2VyWyBtYXRjaGVkLmJyb3dzZXIgXSA9IHRydWU7CiAgICAgICAgICAgIGJyb3dzZXIudmVyc2lvbiA9IG1hdGNoZWQudmVyc2lvbjsKICAgICAgICB9CiAgICAgICAgLy8gQ2hyb21lIGlzIFdlYmtpdCwgYnV0IFdlYmtpdCBpcyBhbHNvIFNhZmFyaS4KICAgICAgICBpZiAoIGJyb3dzZXIuY2hyb21lICkgewogICAgICAgICAgICBicm93c2VyLndlYmtpdCA9IHRydWU7CiAgICAgICAgfSBlbHNlIGlmICggYnJvd3Nlci53ZWJraXQgKSB7CiAgICAgICAgICAgIGJyb3dzZXIuc2FmYXJpID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgJC5icm93c2VyID0gYnJvd3NlcjsKICAgIH0KfSkoJCk7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX19fCiAqCiAqICBDb3B5cmlnaHQgMjAxMyBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LkNsYXNzCiAqLwooZnVuY3Rpb24oXywgeGZhbGliKXsKCiAgICB4ZmFsaWIubnMgPSB4ZmFsaWIubnMgfHwgZnVuY3Rpb24gKG5hbWVzcGFjZVN0cmluZykgewogICAgICAgIHZhciBwYXJ0cyA9IG5hbWVzcGFjZVN0cmluZy5zcGxpdCgnLicpLAogICAgICAgICAgICBwYXJlbnQgPSB3aW5kb3csCiAgICAgICAgICAgIGN1cnJlbnRQYXJ0ID0gJyc7CgogICAgICAgIGZvcih2YXIgaSA9IDAsIGxlbmd0aCA9IHBhcnRzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGN1cnJlbnRQYXJ0ID0gcGFydHNbaV07CiAgICAgICAgICAgIHBhcmVudFtjdXJyZW50UGFydF0gPSBwYXJlbnRbY3VycmVudFBhcnRdIHx8IHt9OwogICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnRbY3VycmVudFBhcnRdOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHBhcmVudDsKICAgIH07CgogICAgdmFyIENsYXNzID0geGZhbGliLnV0LkNsYXNzID0gZnVuY3Rpb24ob3B0aW9ucykgewogICAgICAgIHRoaXMub3B0aW9ucyA9IF8uZXh0ZW5kKHt9LCB0aGlzLm9wdGlvbnMsIG9wdGlvbnMpOwogICAgICAgIGlmKCF0aGlzLm9wdGlvbnMuanNvbk1vZGVsKQogICAgICAgICAgICB0aGlzLm9wdGlvbnMuanNvbk1vZGVsID0ge307CiAgICAgICAgLy9Gb3IgcGVyZiByZWFzb24sIHdlIGFyZSBzZXR0aW5nIGpzb25Nb2RlbCBhcyBkaXJlY3QgcHJvcGVydHkgaW5zdGVhZCBvZiB1c2luZyBwcm9wZXJ0eSBkZXNjcmlwdG9yCiAgICAgICAgdGhpcy5qc29uTW9kZWwgPSB0aGlzLm9wdGlvbnMuanNvbk1vZGVsOwogICAgICAgIHRoaXMuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgfTsKCiAgICBfLmV4dGVuZChDbGFzcy5wcm90b3R5cGUsIHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICB9LAoKICAgICAgICB4ZmFVdGlsIDpmdW5jdGlvbigpewogICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZTsKICAgICAgICB9LAoKICAgICAgICBjb3B5QXJyYXkgOiBmdW5jdGlvbihzcmMsZHN0LG9wdGlvbnMpIHsKICAgICAgICAgICAgdmFyIGtlZXBSZWZlcmVuY2UgPSB0aGlzLmdldE9yRWxzZShvcHRpb25zLCAia2VlcFJlZmVyZW5jZSIsIHRydWUpOwogICAgICAgICAgICBpZihzcmMgaW5zdGFuY2VvZiBBcnJheSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7aTxzcmMubGVuZ3RoO2krKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgb2JqOwogICAgICAgICAgICAgICAgICAgIGlmKHNyY1tpXSBpbnN0YW5jZW9mIEFycmF5KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgb2JqID0gdGhpcy5fY3JlYXRlRGVzdGluYXRpb24oZHN0LCBpLCBrZWVwUmVmZXJlbmNlLCBbXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29weUFycmF5KHNyY1tpXSxvYmosb3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYodHlwZW9mIHNyY1tpXSA9PSAib2JqZWN0IikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9iaiA9IHRoaXMuX2NyZWF0ZURlc3RpbmF0aW9uKGRzdCwgaSwga2VlcFJlZmVyZW5jZSwge30pOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvcHlPYmplY3Qoc3JjW2ldLG9iaixvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBvYmogPSBzcmNbaV07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRzdFtpXSA9IG9iajsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGRzdC5sZW5ndGggPiBzcmMubGVuZ3RoKXsKICAgICAgICAgICAgICAgICAgICBkc3Quc3BsaWNlKHNyYy5sZW5ndGgsIChkc3QubGVuZ3RoIC0gc3JjLmxlbmd0aCkpOyAgLy9SZW1vdmUgdGhzIHJlc3Qgb2YgdGhlIGV4dHJhIGRlc3RpbmF0aW9uIGl0ZW1zCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBzcmMKICAgICAgICAgKiBAcGFyYW0gZHN0CiAgICAgICAgICogQHBhcmFtIG9wdGlvbnMgZS5nLiB7a2VlcFJlZmVyZW5jZTogdHJ1ZSwgZXhjZXB0aW9uczpbImh0bWxJZCJdLCB0cmFuc2Zvcm1NYXBzOiB7ImRhdGFJZCIsIGZ1bmN0aW9uKHNyYywgb3B0aW9ucyl7IHJldHVybiBzcmMgIjMzIitzcmM7IH19fQogICAgICAgICAqLwogICAgICAgIGNvcHlPYmplY3QgOiBmdW5jdGlvbihzcmMsZHN0LG9wdGlvbnMpIHsKICAgICAgICAgICAgdmFyIGtlZXBSZWZlcmVuY2UgPSB0aGlzLmdldE9yRWxzZShvcHRpb25zLCAia2VlcFJlZmVyZW5jZSIsIHRydWUpOwogICAgICAgICAgICB2YXIgZXhjZXB0aW9ucyA9IHRoaXMuZ2V0T3JFbHNlKG9wdGlvbnMsICJleGNlcHRpb25zIiwgW10pOwogICAgICAgICAgICB2YXIgdHJhbnNmb3JtTWFwcyA9IHRoaXMuZ2V0T3JFbHNlKG9wdGlvbnMsICJ0cmFuc2Zvcm1NYXBzIiwge30pOwogICAgICAgICAgICBpZih0eXBlb2Ygc3JjID09ICJvYmplY3QiKSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBjaGlsZCBpbiBzcmMpIHsKICAgICAgICAgICAgICAgICAgICBpZihleGNlcHRpb25zLmluZGV4T2YoY2hpbGQpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHNyY1tjaGlsZF0gaW5zdGFuY2VvZiBBcnJheSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0W2NoaWxkXSA9IHRoaXMuX2NyZWF0ZURlc3RpbmF0aW9uKGRzdCwgY2hpbGQsIGtlZXBSZWZlcmVuY2UsIFtdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29weUFycmF5KHNyY1tjaGlsZF0sZHN0W2NoaWxkXSxvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKHR5cGVvZiBzcmNbY2hpbGRdID09ICJvYmplY3QiICYmIHNyY1tjaGlsZF0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0W2NoaWxkXSA9IHRoaXMuX2NyZWF0ZURlc3RpbmF0aW9uKGRzdCwgY2hpbGQsIGtlZXBSZWZlcmVuY2UsIHt9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29weU9iamVjdChzcmNbY2hpbGRdLGRzdFtjaGlsZF0sb3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCFfLmlzVW5kZWZpbmVkKHRyYW5zZm9ybU1hcHNbY2hpbGRdKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0W2NoaWxkXSA9IHRyYW5zZm9ybU1hcHNbY2hpbGRdKHNyY1tjaGlsZF0sIG9wdGlvbnMsIHNyYyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0W2NoaWxkXSA9IHNyY1tjaGlsZF07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlRGVzdGluYXRpb24gOiBmdW5jdGlvbihvYmosIHByb3BlcnR5LCBrZWVwUmVmZXJlbmNlLCBkZWZhdWx0VmFsdWUpIHsKICAgICAgICAgICAgaWYoIWtlZXBSZWZlcmVuY2UpCiAgICAgICAgICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlOwogICAgICAgICAgICBlbHNlIGlmKF8uaXNPYmplY3Qob2JqKSAmJiAhb2JqLmhhc093blByb3BlcnR5KHByb3BlcnR5KSkKICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBvYmpbcHJvcGVydHldIHx8IGRlZmF1bHRWYWx1ZSA7ICAvL1dvdWxkIGhhbmRsZSBib3RoLCBBcnJheSBhbmQgb2JqZWN0cwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIHdpbGwgcmVwbGFjZSBmdW5jdGlvbnMgaW4gdGhlIG9iamVjdCB3aXRoIG5vb3AgZnVuY3Rpb24gYmFzZWQgb24gYSBwcmVkaWNhdGUgZnVuY3Rpb24ncyByZXN1bHQuCiAgICAgICAgICogSWYgbm8gcHJlZGljYXRlIGlzIHBhc3NlZCBhbGwgZnVuY3Rpb25zIHdpbGwgYmUgZGlzYWJsZWQuCiAgICAgICAgICogV2FybmluZyBvbmNlIGRpc2FibGVkIG9iamVjdCBjYW50IGJlIHJlLWVuYWJsZWQuCiAgICAgICAgICoKICAgICAgICAgKiBzYW1wbGUgcHJlZGljYXRlIHRvIGRpc2FibGUgYWxsICdwdWJsaWMnIGZ1bmN0aW9ucyA6IGZ1bmN0aW9uIChmdW5jTmFtZSkgeyByZXR1cm4gZnVuY05hbWVbMF0gIT0gJ18nfQogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHByZWRpY2F0ZQogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2Rpc2FibGVGdW5jdGlvbnM6IGZ1bmN0aW9uIChwcmVkaWNhdGUpIHsKICAgICAgICAgICAgdmFyIG5vb3AgPSBmdW5jdGlvbiAoKSB7fSwKICAgICAgICAgICAgICAgIGRpc2FibGVBbGwgPSAhXy5pc0Z1bmN0aW9uKHByZWRpY2F0ZSk7CgogICAgICAgICAgICBfLmVhY2goXy5mdW5jdGlvbnModGhpcyksIGZ1bmN0aW9uIChmdW5jTmFtZSkgewogICAgICAgICAgICAgICAgaWYgKGRpc2FibGVBbGwgfHwgcHJlZGljYXRlKGZ1bmNOYW1lKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXNbZnVuY05hbWVdID0gbm9vcDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogZ2V0T3JFbHNlIGNhbiB0YWtlIG11bHRpcGxlIGFyZ3VtZW50cy4KICAgICAgICAgKiBhcmcxKG9iaik6IGJhc2UgT2JqZWN0CiAgICAgICAgICogYXJnMjogc3RyaW5nIHJlcHJlc2VudGluZyBwcm9wZXJ0eSBjaGFpbiB3aGVyZSBwcm9wZXJ0aWVzIGFyZSBjb25jYXRlbmF0ZWQgdmlhIGRvdAogICAgICAgICAqIGFyZzM6IGRlZmF1bHQgdmFsdWUKICAgICAgICAgKiovCgogICAgICAgIGdldE9yRWxzZSA6IGZ1bmN0aW9uKG9iail7CiAgICAgICAgICAgIHZhciBjdXJyT2JqZWN0ID0gb2JqOwogICAgICAgICAgICBpZihhcmd1bWVudHMubGVuZ3RoIDwgMikKICAgICAgICAgICAgICAgIHJldHVybiBjdXJyT2JqZWN0OwogICAgICAgICAgICBlbHNlIGlmKGFyZ3VtZW50cy5sZW5ndGggPT0gMikgewogICAgICAgICAgICAgICAgaWYoIV8uaXNVbmRlZmluZWQoY3Vyck9iamVjdCkpewogICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyT2JqZWN0OwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gXy5jbG9uZShhcmd1bWVudHNbMV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgdmFyIHByb3BDaGFpbiA9IChhcmd1bWVudHNbMV0gfHwgIiIpLnNwbGl0KCIuIik7CiAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdFZhbHVlID0gYXJndW1lbnRzWzJdOwogICAgICAgICAgICAgICAgXy5lYWNoKHByb3BDaGFpbiwgZnVuY3Rpb24ocHJvcCl7CiAgICAgICAgICAgICAgICAgICAgaWYoXy5pc09iamVjdChjdXJyT2JqZWN0KSkKICAgICAgICAgICAgICAgICAgICAgICAgY3Vyck9iamVjdCA9IGN1cnJPYmplY3RbcHJvcF07CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBjdXJyT2JqZWN0ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICAgICAgaWYoIV8uaXNVbmRlZmluZWQoY3Vyck9iamVjdCkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJPYmplY3Q7CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gXy5jbG9uZShkZWZhdWx0VmFsdWUpIDsgLy9NYXkgaGF2ZSB0byBkbyBkZWVwIGNsb25lIGluIGZ1dHVyZS4gVE9ETzogc3VwcG9ydCBmb3IgY29uZGl0aW9uYWwgY2xvbmUKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGpxSWQ6IGZ1bmN0aW9uIChpZCkgewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmpxSWQoaWQpOwogICAgICAgIH0sCgogICAgICAgIGxvZ2dlciA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnhmYVV0aWwoKS5nZXRMb2dnZXIoKTsKICAgICAgICB9LAoKICAgICAgICB2YWxpZGF0ZUlucHV0IDogZnVuY3Rpb24ocGFyYW0sIGRhdGFUeXBlLGZhbGxiYWNrKXsKICAgICAgICAJaWYodHlwZW9mIHBhcmFtICE9PSAidW5kZWZpbmVkIiAmJiBwYXJhbSAhPT0gbnVsbCkgewogICAgICAgIAkJc3dpdGNoKGRhdGFUeXBlKSB7CiAgICAgICAgCQljYXNlICJzdHJpbmciOgogICAgICAgIAkJCXBhcmFtID0gcGFyYW0rIiI7CiAgICAgICAgCQkJYnJlYWs7CiAgICAgICAgCQljYXNlICJvYmplY3QiOgogICAgICAgIAkJCWlmKHR5cGVvZiBwYXJhbSAhPT0gIm9iamVjdCIpCiAgICAgICAgCQkJCXBhcmFtID0gZmFsbGJhY2s7CiAgICAgICAgCQkJYnJlYWs7CiAgICAgICAgCSAgICBjYXNlICJpbnRlZ2VyIjoKICAgICAgICAgICAgICAgICAgICBwYXJhbSA9IHBhcnNlSW50KHBhcmFtKTsKICAgICAgICAgICAgICAgICAgICBpZihpc05hTihwYXJhbSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtID0gZmFsbGJhY2s7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgIGNhc2UgIm1lYXN1cmVtZW50IjoKICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgCQlkZWZhdWx0OgogICAgICAgIAkJCWlmKGRhdGFUeXBlIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIX5kYXRhVHlwZS5pbmRleE9mKHBhcmFtKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtID0gZmFsbGJhY2sKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgCQl9CiAgICAgICAgCX0KICAgICAgICAJcmV0dXJuIHBhcmFtOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBfLmV4dGVuZChDbGFzcywgewogICAgICAgIGRlZmluZVByb3BzIDogZnVuY3Rpb24ocHJvcHNNYXApewogICAgICAgICAgICBfLmVhY2gocHJvcHNNYXAsIGZ1bmN0aW9uKHByb3BEZXNjLCBwcm9wTmFtZSl7CiAgICAgICAgICAgICAgICAvL0NoZWNrIHByb3BlcnR5IGNhbiBiZSByZXNvbHZlZCB1c2luZyByZXNvbHZlTm9kZQogICAgICAgICAgICAgICAgaWYocHJvcERlc2MucmVzb2x2ZSkgewogICAgICAgICAgICAgICAgICAgIC8vQ2hlY2sgd2hldGhlciBwcm90b3R5cGUgb3ducyB0aGUgb2JqZWN0IHJlc29sdmVQcm9wZXJ0aWVzCiAgICAgICAgICAgICAgICAgICAgaWYoIXRoaXMucHJvdG90eXBlLmhhc093blByb3BlcnR5KCJyZXNvbHZlUHJvcGVydGllcyIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vY2hlY2sgd2hldGhlciBwcm90b3R5cGUgaW5oZXJpdHMgdGhlIG9iamVjdCByZXNvbHZlUHJvcGVydGllcwogICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLnByb3RvdHlwZS5yZXNvbHZlUHJvcGVydGllcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9jbG9uZSB0aGUgb2JqZWN0IHNpbmNlIHdlIGRvIG5vdCB3YW50IHRvIG1vZGlmeSBwYXJlbnQncyBwcm90b3R5cGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvdG90eXBlLnJlc29sdmVQcm9wZXJ0aWVzID0gXy5jbG9uZSh0aGlzLnByb3RvdHlwZS5yZXNvbHZlUHJvcGVydGllcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm90b3R5cGUucmVzb2x2ZVByb3BlcnRpZXMgPSBbXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm90b3R5cGUucmVzb2x2ZVByb3BlcnRpZXMucHVzaChwcm9wTmFtZSkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLnByb3RvdHlwZSwgcHJvcE5hbWUsIHByb3BEZXNjKTsKCiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgIH0sCiAgICAgICAgZXh0ZW5kIDogZnVuY3Rpb24ocHJvcHMpewogICAgICAgICAgICB2YXIgY2hpbGQgPSBpbmhlcml0cyh0aGlzLCBwcm9wcyk7CiAgICAgICAgICAgIGNoaWxkLmV4dGVuZCA9IHRoaXMuZXh0ZW5kOwogICAgICAgICAgICByZXR1cm4gY2hpbGQ7CiAgICAgICAgfSwKICAgICAgICBhZGRNaXhpbnMgOiBmdW5jdGlvbihtaXhpbkJha2Vycyl7CiAgICAgICAgICAgIGlmKCFfLmlzQXJyYXkobWl4aW5CYWtlcnMpKXsKICAgICAgICAgICAgICAgIG1peGluQmFrZXJzID0gW21peGluQmFrZXJzXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBfLmVhY2gobWl4aW5CYWtlcnMsIGZ1bmN0aW9uKG1peGluQmFrZXIpewogICAgICAgICAgICAgICAgaWYobWl4aW5CYWtlci5ub3JtYWxQcm9wZXJ0aWVzKXsKICAgICAgICAgICAgICAgICAgICBfLmV4dGVuZCh0aGlzLnByb3RvdHlwZSwgbWl4aW5CYWtlci5ub3JtYWxQcm9wZXJ0aWVzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKG1peGluQmFrZXIucHJvcGVydHlEZXNjcmlwdG9ycyl7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWZpbmVQcm9wcyhtaXhpbkJha2VyLnByb3BlcnR5RGVzY3JpcHRvcnMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICB9CiAgICB9KTsKCiAgICAvLyBTaGFyZWQgZW1wdHkgY29uc3RydWN0b3IgZnVuY3Rpb24gdG8gYWlkIGluIHByb3RvdHlwZS1jaGFpbiBjcmVhdGlvbi4KICAgIHZhciBjdG9yID0gZnVuY3Rpb24oKXt9OwoKICAgIC8vIEhlbHBlciBmdW5jdGlvbiB0byBjb3JyZWN0bHkgc2V0IHVwIHRoZSBwcm90b3R5cGUgY2hhaW4sIGZvciBzdWJjbGFzc2VzLgogICAgLy8gU2ltaWxhciB0byBgZ29vZy5pbmhlcml0c2AsIGJ1dCB1c2VzIGEgaGFzaCBvZiBwcm90b3R5cGUgcHJvcGVydGllcyBhbmQKICAgIC8vIGNsYXNzIHByb3BlcnRpZXMgdG8gYmUgZXh0ZW5kZWQuCiAgICBmdW5jdGlvbiBpbmhlcml0cyhwYXJlbnQsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7CiAgICAgICAgdmFyIGNoaWxkOwogICAgICAgIHZhciBfc3VwZXIgPSBwYXJlbnQucHJvdG90eXBlOwogICAgICAgIC8vIFRoZSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBmb3IgdGhlIG5ldyBzdWJjbGFzcyBpcyBlaXRoZXIgZGVmaW5lZCBieSB5b3UKICAgICAgICAvLyAodGhlICJjb25zdHJ1Y3RvciIgcHJvcGVydHkgaW4geW91ciBgZXh0ZW5kYCBkZWZpbml0aW9uKSwgb3IgZGVmYXVsdGVkCiAgICAgICAgLy8gYnkgdXMgdG8gc2ltcGx5IGNhbGwgdGhlIHBhcmVudCdzIGNvbnN0cnVjdG9yLgogICAgICAgIGlmIChwcm90b1Byb3BzICYmIHByb3RvUHJvcHMuaGFzT3duUHJvcGVydHkoJ2NvbnN0cnVjdG9yJykpIHsKICAgICAgICAgICAgY2hpbGQgPSBwcm90b1Byb3BzLmNvbnN0cnVjdG9yOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNoaWxkID0gZnVuY3Rpb24oKXsgcGFyZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07CiAgICAgICAgfQoKICAgICAgICAvLyBJbmhlcml0IGNsYXNzIChzdGF0aWMpIHByb3BlcnRpZXMgZnJvbSBwYXJlbnQuCiAgICAgICAgXy5leHRlbmQoY2hpbGQsIHBhcmVudCk7CgogICAgICAgIC8vIFNldCB0aGUgcHJvdG90eXBlIGNoYWluIHRvIGluaGVyaXQgZnJvbSBgcGFyZW50YCwgd2l0aG91dCBjYWxsaW5nCiAgICAgICAgLy8gYHBhcmVudGAncyBjb25zdHJ1Y3RvciBmdW5jdGlvbi4KICAgICAgICBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7CiAgICAgICAgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsKICAgICAgICBjaGlsZC5fc3VwZXIgPSBwYXJlbnQucHJvdG90eXBlOwogICAgICAgIGNoaWxkLl9zdXBlckNsYXNzID0gcGFyZW50OwoKICAgICAgICAvLyBBZGQgcHJvdG90eXBlIHByb3BlcnRpZXMgKGluc3RhbmNlIHByb3BlcnRpZXMpIHRvIHRoZSBzdWJjbGFzcywKICAgICAgICAvLyBpZiBzdXBwbGllZC4KICAgICAgICBpZiAocHJvdG9Qcm9wcykgeyAvL18uZXh0ZW5kKGNoaWxkLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7CiAgICAgICAgICAgIC8vIENvcHkgdGhlIHByb3BlcnRpZXMgb3ZlciBvbnRvIHRoZSBuZXcgcHJvdG90eXBlCiAgICAgICAgICAgIGZvciAodmFyIG5hbWUgaW4gcHJvdG9Qcm9wcykgewogICAgICAgICAgICAgICAgaWYobmFtZSA9PSAiX2RlZmF1bHRzIil7CiAgICAgICAgICAgICAgICAgICAgcHJvdG9Qcm9wc1tuYW1lXSA9IF8uZXh0ZW5kKHt9LCBfc3VwZXJbbmFtZV0sIHByb3RvUHJvcHNbbmFtZV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2hpbGQucHJvdG90eXBlW25hbWVdID0gcHJvdG9Qcm9wc1tuYW1lXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCgogICAgICAgIC8vIEFkZCBzdGF0aWMgcHJvcGVydGllcyB0byB0aGUgY29uc3RydWN0b3IgZnVuY3Rpb24sIGlmIHN1cHBsaWVkLgogICAgICAgIGlmIChzdGF0aWNQcm9wcykgXy5leHRlbmQoY2hpbGQsIHN0YXRpY1Byb3BzKTsKCiAgICAgICAgLy8gQ29ycmVjdGx5IHNldCBjaGlsZCdzIGBwcm90b3R5cGUuY29uc3RydWN0b3JgLgogICAgICAgIGNoaWxkLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGNoaWxkOwoKICAgICAgICAvLyBTZXQgYSBjb252ZW5pZW5jZSBwcm9wZXJ0eSBpbiBjYXNlIHRoZSBwYXJlbnQncyBwcm90b3R5cGUgaXMgbmVlZGVkIGxhdGVyLgogICAgICAgIGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7CgogICAgICAgIHJldHVybiBjaGlsZDsKICAgIH07Cn0pKF8sIHdpbmRvdy54ZmFsaWIpOwovKioKICogQ3JlYXRlZCBieSB2ZHVhIG9uIDIvMTgvMjAxNS4KICovCihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgWE1MVXRpbHMgPSB7CiAgICAgICAgZGF0YVNvbTJ4cGF0aDogZnVuY3Rpb24gKGRhdGFTb20pIHsKICAgICAgICAgICAgdmFyIHhwYXRoID0gIiI7CgogICAgICAgICAgICBpZiAoIV8uaXNFbXB0eShkYXRhU29tKSkgewogICAgICAgICAgICAgICAgLy8gYW55IGRvdCBwcmVjZWRlZCBieSBdLCB0YWtlcyBjYXJlIG9mIGRvdC1zIGluIG5hbWUsCiAgICAgICAgICAgICAgICAvLyBhbmQgcmVtb3ZlIGNvbnN0YW50IHByZWZpeCAieGZhWzBdLmRhdGFzZXRzWzBdLmRhdGFbMF0iIGFuZCBmb3JtIHJvb3QgbmFtZSwgdGhlbiBqb2luIHVzaW5nICcvJwogICAgICAgICAgICAgICAgXy5lYWNoKGRhdGFTb20uc3BsaXQoL1xdXC4vKS5zbGljZSg0KSwKICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAocGFydCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3BlbkJyYWNrZXRQb3MgPSBwYXJ0Lmxhc3RJbmRleE9mKCdbJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHhwYXRoICs9IHBhcnQuc3Vic3RyaW5nKDAsIG9wZW5CcmFja2V0UG9zICsgMSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBhcnNlSW50KHBhcnQuc3Vic3RyaW5nKG9wZW5CcmFja2V0UG9zICsgMSkpICsgMSkgKyAvLyBpbmNyZW1lbnQgaW5kZXggYnkgMSBmb3IgeHBhdGggcXVlcnkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJdLyI7CiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgaWYgKF8uaXNFbXB0eSh4cGF0aCkpIHsKICAgICAgICAgICAgICAgICAgICB4cGF0aCA9IGRhdGFTb207CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHhwYXRoW3hwYXRoLmxlbmd0aCAtIDFdID09PSAnLycpIHsKICAgICAgICAgICAgICAgICAgICB4cGF0aCA9IHhwYXRoLnNsaWNlKDAsIC0xKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHhwYXRoOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIENvbnZlcnRzIGFuIHhQYXRoUmVzdWx0IG9mIHR5cGUgaXRlcmF0b3IgdG8gYW4gYXJyYXkKICAgICAgICAgKiBAcGFyYW0geFBhdGhSZXN1bHQKICAgICAgICAgKiBAcmV0dXJucyB7QXJyYXl9CiAgICAgICAgICovCiAgICAgICAgaXRlcmF0b3JUb0FycmF5OiBmdW5jdGlvbiAoeFBhdGhSZXN1bHQpIHsKICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFtdOwogICAgICAgICAgICAvLyBpbiBzb21lIGJyb3dzZXJzLCBpZiB4cGF0aCBpcyBpbnZhbGlkIHhQYXRoIHJlc3VsdCBpcyBudWxsIHdoZXJlYXMgc29tZSBicm93c2VycyByZXR1cm4gWHBhdGhSZXN1bHQgd2l0aCBlbXB0eSBpdGVyYXRvcgogICAgICAgICAgICB2YXIgbm9kZSA9IHhQYXRoUmVzdWx0ID8geFBhdGhSZXN1bHQuaXRlcmF0ZU5leHQoKSA6IG51bGw7CiAgICAgICAgICAgIHdoaWxlIChub2RlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgbm9kZSA9IHhQYXRoUmVzdWx0Lml0ZXJhdGVOZXh0KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9LAogICAgICAgIC8qKgogICAgICAgICAqIFdyYXBwZXIgQVBJIGZvciBkb2N1bWVudC5ldmFsdWF0ZSB0byBwcm92aWRlIGNyb3NzLWJyb3dzZXIgc3VwcG9ydC4KICAgICAgICAgKiBAcGFyYW0geHBhdGgKICAgICAgICAgKiBAcGFyYW0gbm9kZQogICAgICAgICAqIEBwYXJhbSBuc1Jlc29sdmVyCiAgICAgICAgICogQHBhcmFtIHJlc3VsdFR5cGUKICAgICAgICAgKiBAcGFyYW0gcmVzdWx0CiAgICAgICAgICogQHJldHVybnMge09iamVjdHwqfQogICAgICAgICAqLwogICAgICAgIGV2YWx1YXRlWFBhdGg6IGZ1bmN0aW9uICh4cGF0aCwgbm9kZSwgbnNSZXNvbHZlciwgcmVzdWx0VHlwZSwgcmVzdWx0KSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBpZihfLmlzRW1wdHkoeHBhdGgpIHx8ICFfLmlzU3RyaW5nKHhwYXRoKSB8fCAhKG5vZGUgaW5zdGFuY2VvZiBOb2RlKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIERldGVybWluZSB0aGUgYXBwcm9wcmlhdGUgZG9jdW1lbnQgY29udGV4dCBmb3Igc2VhcmNoaW5nLgogICAgICAgICAgICAgICAgdmFyIHNlYXJjaENvbnRleHQgPSBub2RlIGluc3RhbmNlb2YgRG9jdW1lbnQgPyBub2RlIDogbm9kZS5vd25lckRvY3VtZW50OwogICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGRvY3VtZW50LmV2YWx1YXRlIGZ1bmN0aW9uIGlzIHVuZGVmaW5lZCBvciBpZiB3ZSdyZSBpbiBhIHNlcnZlci1zaWRlIGNvbnRleHQuCiAgICAgICAgICAgICAgICB2YXIgaXNFdmFsdWF0ZVVuZGVmaW5lZCA9IHR5cGVvZiBzZWFyY2hDb250ZXh0LmV2YWx1YXRlID09PSAndW5kZWZpbmVkJzsKICAgICAgICAgICAgICAgIHZhciBpc1NlcnZlclNpZGUgPSB3aW5kb3cuZ3VpZGVCcmlkZ2UgJiYgd2luZG93Lmd1aWRlQnJpZGdlLmhvc3ROYW1lID09PSAic2VydmVyIjsKICAgICAgICAgICAgICAgIHZhciBuZWVkc1hQYXRoUG9seWZpbGwgPSBpc0V2YWx1YXRlVW5kZWZpbmVkIHx8IGlzU2VydmVyU2lkZTsKICAgICAgICAgICAgICAgIGlmIChuZWVkc1hQYXRoUG9seWZpbGwpIHsKICAgICAgICAgICAgICAgICAgICAvLyBJbnN0YWxsIHRoZSB3Z3hwYXRoIHBvbHlmaWxsIHRvIHByb3ZpZGUgZXZhbHVhdGUgZnVuY3Rpb25hbGl0eS4KICAgICAgICAgICAgICAgICAgICB3Z3hwYXRoLmluc3RhbGwod2luZG93LCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAvLyBBc3NpZ24gdGhlIG5ld2x5IGluc3RhbGxlZCBldmFsdWF0ZSBmdW5jdGlvbiB0byB0aGUgc2VhcmNoIGNvbnRleHQuCiAgICAgICAgICAgICAgICAgICAgc2VhcmNoQ29udGV4dC5ldmFsdWF0ZSA9IHdpbmRvdy5kb2N1bWVudC5ldmFsdWF0ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgZG9jdW1lbnRUb0V2YWwgPSBzZWFyY2hDb250ZXh0LmV2YWx1YXRlID8gc2VhcmNoQ29udGV4dCA6IGRvY3VtZW50OwogICAgICAgICAgICAgICAgeHBhdGggPSB0aGlzLnNhbml0aXplWFBhdGgoeHBhdGgpOwoKICAgICAgICAgICAgICAgIHJldHVybiBkb2N1bWVudFRvRXZhbC5ldmFsdWF0ZSh4cGF0aCwgbm9kZSwgbnNSZXNvbHZlciwgcmVzdWx0VHlwZSwgcmVzdWx0KTsKCiAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmdldExvZ2dlcigpLmVycm9yKCJDb3VsZCBub3QgZXZhbHVhdGUgeHBhdGg6ICIgKyB4cGF0aCAgKyBleGNlcHRpb24pOwoKICAgICAgICAgICAgfQoKICAgICAgICB9LAogICAgICAgICAvKioKICAgICAgICAgKlJlbW92ZXMgYWxsIFsqXSBvdGhlciB0aGFuIFsnbnVtZXJpYyddIGZyb20geHBhdGgKICAgICAgICAgKkBwYXJhbSB4cGF0aAogICAgICAgICAqQHJldHVybnMgeHBhdGggYWZ0ZXIgcmVtb3ZpbmcgIlsqXSIKICAgICAgICAgKi8KICAgICAgICAgc2FuaXRpemVYUGF0aDogZnVuY3Rpb24oeHBhdGgpIHsKICAgICAgICAgICAgIHZhciB4cGF0aEFycmF5PXhwYXRoLnNwbGl0KCIvIiksCiAgICAgICAgICAgICAgICAgcmVzdWx0WHBhdGggPSBfLm1hcCh4cGF0aEFycmF5LCBmdW5jdGlvbiAocGF0aCkgewogICAgICAgICAgICAgICAgIHJldHVybiBwYXRoLnJlcGxhY2UoL1xbKC4qXEQrLiopXF18XFtcXS9nLCIiKTsKICAgICAgICAgICAgIH0pLmpvaW4oIi8iKTsKICAgICAgICAgICAgIHJldHVybiByZXN1bHRYcGF0aDsKICAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlcyBhbGwgdGhlIEVsZW1lbnRzIChpZiB0aGV5IGRvbid0IGV4aXN0KSBpbiB0aGUgeHBhdGggbGVhZGluZyB0byB0aGUgbm9kZSBiZWluZyBzZWFyY2hlZCBmb3IgaW4gdGhlCiAgICAgICAgICogeHBhdGggcmVsYXRpdmUgdG8gdGhlIGVsZW1lbnQuIE9wdGlvbmFsbHkgY3JlYXRlcyB0aGUgbm9kZSBhcyB3ZWxsIGlmIGJQYXJlbnRzT25seSBpcyBmYWxzZQogICAgICAgICAqIEBwYXJhbSB4cGF0aAogICAgICAgICAqIEBwYXJhbSBlbGVtZW50CiAgICAgICAgICogQHBhcmFtIGJQYXJlbnRzT25seSB3aGV0aGVyIHRvIGNyZWF0ZSBvbmx5IHRoZSBwYXJlbnRzIG9yIHRoZSBub2RlIGFzIHdlbGwKICAgICAgICAgKiBAcmV0dXJucyBub2RlIHRoYXQgaXMgYmVpbmcgcmVwcmVzZW50ZWQgYnkgdGhlIHhwYXRoIHJlbGF0aXZlIHRvIHRoZSBlbGVtZW50LgogICAgICAgICAqLwogICAgICAgIGNyZWF0ZUVsZW1lbnRzRnJvbVhQYXRoOiBmdW5jdGlvbiAoeHBhdGgsIGVsZW1lbnQsIGJQYXJlbnRzT25seSkgewogICAgICAgICAgICBpZiAoeHBhdGggIT0gbnVsbCB8fCBlbGVtZW50ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHZhciBwYXJ0cyA9IHhwYXRoLnNwbGl0KCIvIiksCiAgICAgICAgICAgICAgICAgICAgYWN0dWFsUGFydHMgPSBiUGFyZW50c09ubHkgPyBfLmluaXRpYWwocGFydHMpIDogcGFydHMsCiAgICAgICAgICAgICAgICAgICAgZWwgPSBlbGVtZW50OwogICAgICAgICAgICAgICAgXy5lYWNoKGFjdHVhbFBhcnRzLCBmdW5jdGlvbiAocGFydCwgaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgc29tID0gcGFydC5tYXRjaCgvXihbXltdKykoXFsoXGQrKVxdKT8vKSwKICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRFbDsKICAgICAgICAgICAgICAgICAgICBpZiAoc29tID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmdldExvZ2dlcigpLmVycm9yKCJVbnN1cHBvcnRlZCBleHByZXNzaW9uIGluIEJpbmRyZWYgIiArIHBhcnQpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy9vbmx5IHRoZSBsYXN0IGVsZW1lbnQgY2FuIGJlIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgIGNoaWxkRWwgPSB0aGlzLmZpbmRPckNyZWF0ZUVsZW1lbnQocGFydCwgZWwsIGluZGV4ID09PSBhY3R1YWxQYXJ0cy5sZW5ndGggLSAxKTsKICAgICAgICAgICAgICAgICAgICBlbCA9IGNoaWxkRWw7CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIHJldHVybiBlbDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBGb3JtIGFuIHhwYXRoIHBhcnQgcmV0dXJucyB0aGUgaW5kZXggYXMgd2VsbCBhcyB0aGUgdGFnTmFtZS4gSW5kZXggY2FuIGJlICogYXMgd2VsbAogICAgICAgICAqIEBwYXJhbSB4cGF0aE5hbWUKICAgICAgICAgKiBAcmV0dXJucyB7Kn0KICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9nZXRFbGVtZW50TmFtZUFuZEluZGV4RnJvbVhQYXRoUGFydDogZnVuY3Rpb24gKHhwYXRoTmFtZSkgewogICAgICAgICAgICB2YXIgc29tICA9ICB4cGF0aE5hbWUubWF0Y2goL14oW15bXSspKD86XFsoXGQrfFwqKVxdKT8vKTsKICAgICAgICAgICAgaWYgKHNvbSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICBuYW1lOiBzb21bMV0sCiAgICAgICAgICAgICAgICAgICAgaW5kZXg6IHNvbVsyXSB8fCAwCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIGNyZWF0ZSBhbiBlbGVtZW50IHdpdGggdGhlIHRhZ05hbWUgZWxlbWVudE5hbWUgZm9yIHRoZSBvd25lckRvY3VtZW50IG9mIGVsZW1lbnQuCiAgICAgICAgICogQHBhcmFtIGVsZW1lbnROYW1lCiAgICAgICAgICogQHBhcmFtIGVsZW1lbnQKICAgICAgICAgKiBAcmV0dXJucyB7SFRNTEVsZW1lbnR9CiAgICAgICAgICovCiAgICAgICAgY3JlYXRlRWxlbWVudDogZnVuY3Rpb24gKGVsZW1lbnROYW1lLCBlbGVtZW50KSB7CiAgICAgICAgICAgIHZhciBlbCA9IGVsZW1lbnQub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KGVsZW1lbnROYW1lKTsKICAgICAgICAgICAgcmV0dXJuIGVsOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFNlYXJjaGVzIGZvciB0aGUgbm9kZVhwYXRoIHJlbGF0aXZlIHRvIGVsZW1lbnQuIElmIGl0IGRvZXNuJ3QgZXhpc3RzIGNyZWF0ZXMgaXQgYW5kIHJldHVybnMgdGhlIG5vZGUKICAgICAgICAgKiBAcGFyYW0gZWxlbWVudAogICAgICAgICAqIEBwYXJhbSBub2RlWHBhdGgKICAgICAgICAgKiBAcGFyYW0gYkF0dHJpYnV0ZSBpZiB0cnVlIHRoZW4gY2hlY2sgZm9yIGF0dHJpYnV0ZSBvdGhlcndpc2Ugbm90LgogICAgICAgICAqIEByZXR1cm5zIHtOb2RlfCp9CiAgICAgICAgICovCiAgICAgICAgZmluZE9yQ3JlYXRlRWxlbWVudDogZnVuY3Rpb24gKG5vZGVYcGF0aCwgZWxlbWVudCwgYkF0dHJpYnV0ZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHRoaXMuZXZhbHVhdGVYUGF0aChub2RlWHBhdGgsIGVsZW1lbnQsIG51bGwsIFhQYXRoUmVzdWx0Lk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFLCBudWxsKSwKICAgICAgICAgICAgICAgICAgICBlbCA9IHJlc3VsdC5pdGVyYXRlTmV4dCgpLAogICAgICAgICAgICAgICAgICAgIHJlczsKICAgICAgICAgICAgICAgIGlmIChlbCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzID0gdGhpcy5fZ2V0RWxlbWVudE5hbWVBbmRJbmRleEZyb21YUGF0aFBhcnQobm9kZVhwYXRoKTsKICAgICAgICAgICAgICAgICAgICBpZiAocmVzICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJBdHRyaWJ1dGUgJiYgcmVzLm5hbWUubWF0Y2goL15ALykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRyTmFtZSA9IHJlcy5uYW1lLnJlcGxhY2UoL15ALywgIiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSBlbGVtZW50Lm93bmVyRG9jdW1lbnQuY3JlYXRlQXR0cmlidXRlKGF0dHJOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTm9kZShlbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbCA9IGVsZW1lbnQub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KHJlcy5uYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoZWwpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGVsOwoKICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0TG9nZ2VyKCkuZXJyb3IoIkZvbGxvd2luZyBleGNlcHRpb24gIgogICAgICAgICAgICAgICAgICAgICsgICJvY2N1cnJlZCB3aGlsZSBleGVjdXRpbmcgZmluZE9yQ3JlYXRlRWxlbWVudCAiICsgZXhjZXB0aW9uKTsKICAgICAgICAgICAgfQoKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRoZSBSb290IEZvcm0gRWxtZW50IGZyb20gdGhlIHhtbERvY3VtZW50RWxlbWVudAogICAgICAgICAqIEBwYXJhbSB4bWxEb2N1bWVudEVsZW1lbnQgSXQgY2FuIGJlIGEgZG9jdW1lbnQgb3IgRWxlbWVudC4gSWYgdGhlIHJvb3QgZWxlbWVudCBpcyB4ZHAgZWxlbWVudCwgaXQgcmV0dXJucwogICAgICAgICAqICAgICAgICB0aGUgZ3JhbmQgZ3JhbmQgY2hpbGQgb2YgdGhhdCBlbGVtZW50LiBvdGhlcndpc2UgdGhlIHJvb3QgZWxlbWVudCBpcyByZXR1cm5lZC4gVGhlIHJvb3QKICAgICAgICAgKiAgICAgICAgRWxlbWVudCBjYW4gYmUgZWl0aGVyIHRoZSBlbGVtZW50IGl0c2VsZiBvciBkb2N1bWVudEVsZW1lbnQgb2YgdGhlIGVsZW1lbnQuCiAgICAgICAgICovCiAgICAgICAgZ2V0WEZBUm9vdEZvcm1FbGVtZW50RnJvbVhNTDogZnVuY3Rpb24gKHhtbERvY3VtZW50RWxlbWVudCkgewogICAgICAgICAgICBpZihfLmlzVW5kZWZpbmVkKGRvY3VtZW50LmV2YWx1YXRlKSkgewogICAgICAgICAgICAgICAgd2d4cGF0aC5pbnN0YWxsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGlzRWxlbWVudCA9IHhtbERvY3VtZW50RWxlbWVudCBpbnN0YW5jZW9mIEVsZW1lbnQsCiAgICAgICAgICAgICAgICBkb2NFbGVtTmFtZSA9IGlzRWxlbWVudCA/IHhtbERvY3VtZW50RWxlbWVudC5ub2RlTmFtZSA6IHhtbERvY3VtZW50RWxlbWVudC5kb2N1bWVudEVsZW1lbnQubm9kZU5hbWUsCiAgICAgICAgICAgICAgICByb290RWxlbWVudCA9IGlzRWxlbWVudCA/IHhtbERvY3VtZW50RWxlbWVudCA6IHhtbERvY3VtZW50RWxlbWVudC5kb2N1bWVudEVsZW1lbnQsCiAgICAgICAgICAgICAgICBub2RlTGlzdDsKCiAgICAgICAgICAgIGlmICgieGRwOnhkcCIgPT09IGRvY0VsZW1OYW1lIHx8ICJ4ZHAiID09PSBkb2NFbGVtTmFtZSkgewogICAgICAgICAgICAgICAgaWYgKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5pc0lFKCkpIHsKICAgICAgICAgICAgICAgICAgICAvL0lFIGRvZXNuJ3Qgc3VwcG9ydCBldmFsdWF0aW5nIG5hbWVzcGFjZSBlbGVtZW50cwogICAgICAgICAgICAgICAgICAgIHZhciBkYXRhc2V0cyA9IHJvb3RFbGVtZW50LmZpcnN0RWxlbWVudENoaWxkLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YXNldHMuZmlyc3RFbGVtZW50Q2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgcm9vdEVsZW1lbnQgPSBkYXRhLmZpcnN0RWxlbWVudENoaWxkOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLyBhc3N1bXB0aW9uIGlzIHRoYXQgdGhlIHhtbCB3aWxsIGJlIG9mIGZvcm1hdCA8eGRwPjxkYXRhc2V0cz48ZGF0YT48Zm9ybTE+CiAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogY2hhbmdlIGZpcnN0ICogdG8geGZhOmRhdGFzZXRzCiAgICAgICAgICAgICAgICAgICAgbm9kZUxpc3QgPSB0aGlzLmV2YWx1YXRlWFBhdGgoIioveGZhOmRhdGEvKiIsIHJvb3RFbGVtZW50LCBmb3JtQnJpZGdlLm5zUmVzb2x2ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBhdGhSZXN1bHQuT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUsIG51bGwpOwogICAgICAgICAgICAgICAgICAgIHJvb3RFbGVtZW50ID0gbm9kZUxpc3QuaXRlcmF0ZU5leHQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcm9vdEVsZW1lbnQ7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgcHJlZml4IGFuZCBuYW1lc3BhY2VzIHByZXNlbnQgaW4gdGhlIHJvb3RFbGVtZW50LiBGb3IgZGVmYXVsdCBuYW1lc3BhY2UgdGhlCiAgICAgICAgICogcHJlZml4IGlzICJfZGVmYXVsdCIKICAgICAgICAgKiBAcGFyYW0gcm9vdEVsZW1lbnQge0VsZW1lbnR9IHhtbCBlbGVtZW50IHdoaWNoIGhhcyB0byBiZSBsb29rZWQgZm9yIG5hbWVzcGFjZXMKICAgICAgICAgKiBAcmV0dXJucyB7b2JqZWN0fSBvYmplY3Qgd2hvc2Uga2V5cyBhcmUgdGhlIHByZWZpeCBhbmQgdmFsdWVzIGFyZSB0aGUgbmFtZXNwYWNlCiAgICAgICAgICovCiAgICAgICAgZ2V0TmFtZXNwYWNlczogZnVuY3Rpb24gKHJvb3RFbGVtZW50KSB7CiAgICAgICAgICAgIHZhciBuYW1lc3BhY2VzID0gewogICAgICAgICAgICAgICAgIl9kZWZhdWx0IiA6IG51bGwKICAgICAgICAgICAgfTsKICAgICAgICAgICAgXy5lYWNoKHJvb3RFbGVtZW50LmF0dHJpYnV0ZXMsIGZ1bmN0aW9uIChhdHRyKSB7CiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IGF0dHIubmFtZSwKICAgICAgICAgICAgICAgICAgICBwYXJzZWRBdHRyTmFtZSA9IG5hbWUubWF0Y2goL154bWxucyg/Olw6KC4qKSk/LyksCiAgICAgICAgICAgICAgICAgICAgaXNOYW1lc3BhY2UgPSBwYXJzZWRBdHRyTmFtZSAhPSBudWxsLAogICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZU5hbWUgPSBpc05hbWVzcGFjZSA/IHBhcnNlZEF0dHJOYW1lWzFdIHx8ICJfZGVmYXVsdCIgOiBudWxsOwogICAgICAgICAgICAgICAgaWYgKG5hbWVzcGFjZU5hbWUpIHsKICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2VzW25hbWVzcGFjZU5hbWVdID0gYXR0ci52YWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHJldHVybiBuYW1lc3BhY2VzOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgYSBuYW1lc3BhY2UgcmVzb2x2ZXIgZ2l2ZW4gYSBlbGVtZW50LiBUaGUgbnNSZXNvbHZlciByZXR1cm5zIHRoZSBuYW1lc3BhY2UgZ2l2ZW4gYSBwcmVmaXggYnkKICAgICAgICAgKiB1c2luZyB0aGUgbmFtZXNwYWNlcyBtZW50aW9uZWQgaW4gdGhlIGVsZW1lbnQuCiAgICAgICAgICogQHBhcmFtIHJvb3RFbGVtZW50IGVsZW1lbnQgZnJvbSB3aGljaCB0byBjcmVhdGUgdGhlIG5zUmVzb2x2ZXIKICAgICAgICAgKiBAcmV0dXJucyB7ZnVuY3Rpb259IHRoZSBmdW5jdGlvbiByZXR1cm5zIHRoZSBuYW1lc3BhY2UgZ2l2ZW4gYSBwcmVmaXguCiAgICAgICAgICovCiAgICAgICAgZ2V0TnNSZXNvbHZlcjogZnVuY3Rpb24gKHJvb3RFbGVtZW50KSB7CiAgICAgICAgICAgIHZhciBuYW1lc3BhY2VzID0gdGhpcy5nZXROYW1lc3BhY2VzKHJvb3RFbGVtZW50KSwKICAgICAgICAgICAgICAgIG5zUmVzb2x2ZXIgPSAoZnVuY3Rpb24gKG5hbWVzcGFjZXMpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG5zUHJlZml4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuYW1lc3BhY2UgPSBmb3JtQnJpZGdlLm5zUmVzb2x2ZXIobnNQcmVmaXgpIHx8IG5hbWVzcGFjZXNbbnNQcmVmaXhdOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmFtZXNwYWNlOwogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9KG5hbWVzcGFjZXMpKTsKICAgICAgICAgICAgcmV0dXJuIG5zUmVzb2x2ZXI7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogUmVtb3ZlcyBkZWZhdWx0IG5hbWVzcGFjZXMgZnJvbSB4bWwsIGJhc2ljYWxseSB0aGUgbmFtZXNwYWNlIGRlZmluZWQgYXMgeG1sbnM9InNvbWUgbmFtZXNwYWNlIi4gVGhlCiAgICAgICAgICogc2lkZS1lZmZlY3Qgb2YgdGhlIEFQSSBpcyBpdCByZW1vdmVzIHRoZSBzdHJpbmcgInhtbG5zPSdzb21lIG5hbWVzcGFjZSciIGZyb20gYW55IGF0dHJpYnV0ZSB2YWx1ZSBhcyB3ZWxsLgogICAgICAgICAqIEBwYXJhbSB4bWwge3N0cmluZ30KICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfQogICAgICAgICAqLwogICAgICAgIHJlbW92ZURlZmF1bHROYW1lc3BhY2U6IGZ1bmN0aW9uICh4bWwpIHsKICAgICAgICAgICAgdmFyIHN0cmluZ1JlZ2V4ID0gIihcXHMrKSIgKyAvLyBhbnkgbnVtYmVyIG9mIHNwYWNlcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoeG1sbnM9IiArIC8vIHRoZW4geG1sbnM9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKCdbXiddKid8XCJbXlwiXSpcIikpIiArIC8vIHRoZW4gdmFsdWUgaW4gc2luZ2xlIHF1b3RlcyAoJ1teJ10nKSBvcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICAgICAgICAgIGRvdWJsZSBxdW90ZXMgKCJbXiJdIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoPz1bXjw+XSo+KSIsICAvLyBmb2xsb3dlZCBieSBjbG9zaW5nIHRhZyAoaW1wbGllcyBhdHRyaWJ1dGUpIGFuZCBiZWZvcmUgYW5vdGhlcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3BlbmluZyB0YWcoaW1wbGllcyB0ZXh0KQogICAgICAgICAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKHN0cmluZ1JlZ2V4LCAiZyIpOwogICAgICAgICAgICByZXR1cm4geG1sLnJlcGxhY2UocmVnZXgsICIkMSIpOwogICAgICAgIH0KICAgIH07CiAgICB4ZmFsaWIudXQuWE1MVXRpbHMgPSBYTUxVdGlsczsKfShfLCB4ZmFsaWIpKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5Mb2dnZXIKICogQGltcG9ydCB4ZmFsaWIudXQuQ2xhc3MKICovCgooZnVuY3Rpb24oXywgeGZhbGliLCAkKXsKICAgIHZhciBjYXRlZ29yeUFjcm9ueW1zID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgImEiOiAieGZhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiIjogInhmYVZpZXciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImMiOiAieGZhUGVyZiIKICAgICAgICB9LAogICAgICAgIGxvZ2dlclR5cGVzID0gWyJvZmYiLCAiY29uc29sZSIsICJzZXJ2ZXIiLCAiY29uc29sZVNlcnZlciJdOwogICAgdmFyIExvZ2dlciA9IHhmYWxpYi51dC5Mb2dnZXIgPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKCi8vICAgICAgQ291bnQgb2YgbG9nIG1lc3NhZ2VzIHNvIGZhci4KICAgICAgICBMT0dfQ09VTlQgOiB7CiAgICAgICAgICAgIGxldmVsIDogewogICAgICAgICAgICAgICAgIkZBVEFMIiA6IDAsCiAgICAgICAgICAgICAgICAiRVJST1IiIDogMCwKICAgICAgICAgICAgICAgICJXQVJOIiA6IDAsCiAgICAgICAgICAgICAgICAiSU5GTyIgOiAwLAogICAgICAgICAgICAgICAgIkRFQlVHIiA6IDAsCiAgICAgICAgICAgICAgICAiVFJBQ0UiIDogMCwKICAgICAgICAgICAgICAgICJBTEwiIDogMAogICAgICAgICAgICB9LAogICAgICAgICAgICBjYXRlZ29yeSA6IHsKICAgICAgICAgICAgICAgICJ4ZmEiIDogMCwKICAgICAgICAgICAgICAgICJ4ZmFWaWV3IiA6IDAsCiAgICAgICAgICAgICAgICAieGZhUGVyZiIgOiAwLAogICAgICAgICAgICAgICAgIlVua25vd24iIDogMAogICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBMb2cgbGV2ZWwgdG8gdHVybiBsb2dnaW5nIG9mZiAoZGVmYXVsdCkuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEBmaW5hbAogICAgICAgICAqIEB0eXBlIE51bWJlcgogICAgICAgICAqLwogICAgICAgIE9GRiA6IDAsCgogICAgICAgIC8qKgogICAgICAgICAqIExvZyBsZXZlbCBmb3IgZmF0YWwgZXJyb3IgbWVzc2FnZXMuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEBmaW5hbAogICAgICAgICAqIEB0eXBlIE51bWJlcgogICAgICAgICAqLwogICAgICAgIEZBVEFMIDogMSwKCiAgICAgICAgLyoqCiAgICAgICAgICogTG9nIGxldmVsIGZvciBlcnJvciBtZXNzYWdlcy4KICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICogQHR5cGUgTnVtYmVyCiAgICAgICAgICogQGZpbmFsCiAgICAgICAgICovCiAgICAgICAgRVJST1IgOiAyLAoKICAgICAgICAvKioKICAgICAgICAgKiBMb2cgbGV2ZWwgZm9yIHdhcm5pbmcgbWVzc2FnZXMuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEB0eXBlIE51bWJlcgogICAgICAgICAqIEBmaW5hbAogICAgICAgICAqLwogICAgICAgIFdBUk4gOiAzLAoKICAgICAgICAvKioKICAgICAgICAgKiBMb2cgbGV2ZWwgZm9yIGluZm8gbWVzc2FnZXMuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEB0eXBlIE51bWJlcgogICAgICAgICAqIEBmaW5hbAogICAgICAgICAqLwogICAgICAgIElORk8gOiA0LAoKICAgICAgICAvKioKICAgICAgICAgKiBMb2cgbGV2ZWwgZm9yIGRlYnVnIG1lc3NhZ2VzLgogICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgKiBAdHlwZSBOdW1iZXIKICAgICAgICAgKiBAZmluYWwKICAgICAgICAgKi8KICAgICAgICBERUJVRyA6IDUsCgogICAgICAgIC8qKgogICAgICAgICAqIExvZyBsZXZlbCBmb3IgdHJhY2UgbWVzc2FnZXMuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEB0eXBlIE51bWJlcgogICAgICAgICAqIEBmaW5hbAogICAgICAgICAqLwogICAgICAgIFRSQUNFIDogNiwKCiAgICAgICAgLyoqCiAgICAgICAgICogTG9nIGxldmVsIGZvciBhbGwgbWVzc2FnZXMuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEB0eXBlIE51bWJlcgogICAgICAgICAqIEBmaW5hbAogICAgICAgICAqLwogICAgICAgIEFMTCA6IDcsCgoKICAgICAgICBsb2dMZXZlbE5hbWVzIDogWyJPRkYiLCAiRkFUQUwiLCAiRVJST1IiLCAiV0FSTiIsICJJTkZPIiwgIkRFQlVHIiwgIlRSQUNFIiwgIkFMTCJdLAoKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIHN0ciA9ICIiLAogICAgICAgICAgICAgICAgdGhhdCA9dGhpczsKICAgICAgICAgICAgTG9nZ2VyLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMubG9ncyA9IHt9OwogICAgICAgICAgICB0aGlzLmxvZ01lc3NhZ2VzID0gIiI7CiAgICAgICAgICAgIHRoaXMubG9nU2VydmljZVByb3h5ID0gdGhpcy5vcHRpb25zLmxvZ1NlcnZpY2VQcm94eTsKICAgICAgICAgICAgdGhpcy5jb250ZXh0UGF0aCA9IHRoaXMub3B0aW9ucy5jb250ZXh0UGF0aDsKICAgICAgICAgICAgdGhpcy5yZW5kZXJDb250ZXh0ID0gIHRoaXMub3B0aW9ucy5yZW5kZXJDb250ZXh0OwogICAgICAgICAgICBpZih0aGlzLmpzb25Nb2RlbC5sb2dDb25maWdTdHJpbmcpIHsKICAgICAgICAgICAgICAgIF8uZXh0ZW5kKHRoaXMuanNvbk1vZGVsLCB0aGlzLnBhcnNlKHRoaXMuanNvbk1vZGVsLmxvZ0NvbmZpZ1N0cmluZykpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIF8uZWFjaCh0aGlzLmpzb25Nb2RlbC5jYXRlZ29yeSwgZnVuY3Rpb24oY2F0ZWdvcnkpIHsKICAgICAgICAgICAgICAgIHRoYXQuTE9HX0NPVU5ULmNhdGVnb3J5W2NhdGVnb3J5XSA9IDA7CiAgICAgICAgICAgIH0pCiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogcGFyc2VzIGEgbG9nIGNvbmZpZyBzdHJpbmcgb2YgdGhlIGZvcm0gPDAsMSwyLDM+LTxjYXRlZ29yeSBzdHJpbmc+PGxldmVsIGludGVnZXI+LTxjYXRlZ29yeSBzdHJpbmc+PGxldmVsIGludGVnZXI+Li4KICAgICAgICAgKiBhbmQgcmV0dXJucyBhbiBhIGNvbmZpZyBvYmplY3QgdGhhdCBsb2dnZXIgdXNlcy4gVGhlIGZ1bmN0aW9uIGlzIGEgcHJpdmF0ZSBhbmQgbm90IHRvIGJlIGNhbGxlZCBvdXRzaWRlCiAgICAgICAgICogdGhpcyBmdW5jdGlvbgogICAgICAgICAqCiAgICAgICAgICogY2F0ZWdvcnkgY2FuIG5vdCBjb250YWluIG51bWJlcnMgYW5kIG9ubHkgdmFsaWQgY2hhcmFjdGVycyBhcmUgYS16QS1aCiAgICAgICAgICogbGV2ZWwgY2FuIGJlIGFueSBpbnRlZ2VyLgogICAgICAgICAqCiAgICAgICAgICogY2F0ZWdvcnkgc3RyaW5nIGlzIGNvbnZlcnRlZCBpbnRvIGFjdHVhbCBjYXRlZ29yeSBmb3IgdGhlIGxvZ2dlciBieSB1c2luZyBkZWZhdWx0IGNhdGVnb3J5QWNyb255bXMKICAgICAgICAgKiBbYSA6IHhmYSwgYjogeGZhVmlldywgYzogeGZhUGVyZn0gYW5kIHRoZSBjYXRlZ29yeUFjcm9ueW1zIHBhc3NlZCB0byB0aGUgb3B0aW9ucyB3aGlsZSBpbnN0YW50aWF0aW5nIHRoZQogICAgICAgICAqIG9iamVjdC4gSWYgbm90IGZvdW5kIGluIGJvdGggdGhlIGFjcm9ueW1zIHRoZW4gdGhlIHZhbHVlIGNhdGVnb3J5IHN0cmluZyBpcyB1c2VkIGFzIGFjdHVhbCBjYXRlZ29yeQogICAgICAgICAqCiAgICAgICAgICogRm9yIGV4YW1wbGUgZm9yIHRoZSBpbnB1dCBzdHJpbmcgMS1hOS1iOS1jOSByZXR1cm4gb2JqZWN0IGlzCiAgICAgICAgICoge29uOiB0cnVlLCBjYXRlZ29yeTogW3hmYSx4ZmFWaWV3LCB4ZmFQZXJmXSwgbGV2ZWw6IFs5LCA5LCA5XSwgdHlwZTogY29uc29sZX0KICAgICAgICAgKgogICAgICAgICAqIEZvciB0aGUgaW5wdXQgc3RyaW5nIDEtYTktYjktYzktZDktZTExIHdpdGggb3B0aW9ucy5jYXRlZ29yeUFjcm9ueW1zIHthOmEsIGQ6QUZ9IHJldHVybiBvYmplY3QgaXMKICAgICAgICAgKiB7b246IHRydWUsIGNhdGVnb3J5OiBbeGZhLHhmYVZpZXcsIHhmYVBlcmYsIEFGLCBlXSwgbGV2ZWw6IFs5LCA5LCA5LCA5LCAxMV0sIHR5cGU6IGNvbnNvbGV9CiAgICAgICAgICovCiAgICAgICAgcGFyc2UgOiBmdW5jdGlvbihjb25maWdTdHJpbmcpIHsKICAgICAgICAgICAgdmFyIGFyciA9IGNvbmZpZ1N0cmluZy5zcGxpdCgiLSIpLAogICAgICAgICAgICAgICAgbG9nVHlwZSA9IF8uZmlyc3QoYXJyKSwKICAgICAgICAgICAgICAgIGxvZ0NvbmZpZyA9IF8ucmVzdChhcnIpLAogICAgICAgICAgICAgICAgcmVzID0gewogICAgICAgICAgICAgICAgICAgIG9uOiBsb2dUeXBlID09PSAiMCIgPyAiZmFsc2UiOiAidHJ1ZSIsCiAgICAgICAgICAgICAgICAgICAgY2F0ZWdvcnk6IFtdLAogICAgICAgICAgICAgICAgICAgIGxldmVsOltdLAogICAgICAgICAgICAgICAgICAgIHR5cGU6bG9nZ2VyVHlwZXNbcGFyc2VJbnQobG9nVHlwZSldCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgIF8uZWFjaChsb2dDb25maWcsIGZ1bmN0aW9uKGl0ZW0sIGluZGV4KSB7CiAgICAgICAgICAgICAgICB2YXIgY29uZmlnID0gaXRlbS5tYXRjaCgvXihbQS1aYS16XSspKFxkKykkLyksCiAgICAgICAgICAgICAgICAgICAgY2F0ZWdvcnk7CiAgICAgICAgICAgICAgICBpZiAoY29uZmlnICYmIGNvbmZpZy5sZW5ndGggPT09IDMpIHsKICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeSA9IHRoaXMuZ2V0T3JFbHNlKGNhdGVnb3J5QWNyb255bXMsIGNvbmZpZ1sxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwsICJjYXRlZ29yeUFjcm9ueW1zLiIgKyBjb25maWdbMV0sIGNvbmZpZ1sxXSkpOwogICAgICAgICAgICAgICAgICAgIHJlcy5jYXRlZ29yeS5wdXNoKGNhdGVnb3J5KTsKICAgICAgICAgICAgICAgICAgICByZXMubGV2ZWwucHVzaChwYXJzZUludChjb25maWdbMl0pKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy9jYWxsaW5nIHRoaXMgYmVjYXVzZSBsb2dnZXIgaXMgbm90IGluaXRpYWxpemVkIGFzIG9mIG5vdwogICAgICAgICAgICAgICAgICAgIHRoaXMuY29uc29sZUhhbmRsZXIodGhpcy5yZXNvbHZlTWVzc2FnZSh4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMjAiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpdGVtLCBjb25maWdTdHJpbmddKSkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgIHJldHVybiByZXM7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKgogICAgICAgICAqLwogICAgICAgIHJlc29sdmVNZXNzYWdlIDogZnVuY3Rpb24obWVzc2FnZSwgc25pcHBldHMpIHsKICAgICAgICAgICAgc25pcHBldHMgPSBzbmlwcGV0cyB8fCBbXTsKICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2UucmVwbGFjZSgveyhcZCspfS9nLCBmdW5jdGlvbihtYXRjaCwgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZW9mIHNuaXBwZXRzW251bWJlcl0gIT0gJ3VuZGVmaW5lZCcKICAgICAgICAgICAgICAgICAgICA/IHNuaXBwZXRzW251bWJlcl0KICAgICAgICAgICAgICAgICAgICA6IG1hdGNoCiAgICAgICAgICAgICAgICAgICAgOwogICAgICAgICAgICB9KTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBXcml0ZXMgYSBtZXNzYWdlIHRvIHRoZSBjb25zb2xlLgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IGxldmVsIFRoZSBsb2cgbGV2ZWwKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBUaGUgbG9nIG1lc3NhZ2UKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZy9TdHJpbmdbXX0gc25pcHBldHMgKG9wdGlvbmFsKSBUaGUgdGV4dHMgcmVwbGFjaW5nCiAgICAgICAgICogICAgICAgIDxjb2RlPntufTwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBsb2cgbWVzc2FnZQogICAgICAgICAqIEB0eXBlIFN0cmluZwogICAgICAgICAqLwogICAgICAgIGxvZyA6IGZ1bmN0aW9uKGNhdGVnb3J5LCBsZXZlbCwgbWVzc2FnZSwgc25pcHBldHMpIHsKICAgICAgICAgICAgdmFyIGQ9IG5ldyBEYXRlKCk7CiAgICAgICAgICAgIHZhciBkYXkgPSBkLmdldERhdGUoKTsKICAgICAgICAgICAgdmFyIG1vbnRoID0gZC5nZXRNb250aCgpICsgMTsKICAgICAgICAgICAgdmFyIHllYXIgPSBkLmdldEZ1bGxZZWFyKCk7CiAgICAgICAgICAgIHZhciBtaWxpID0gZC5nZXRNaWxsaXNlY29uZHMoKTsKICAgICAgICAgICAgdmFyIHNlYyA9IGQuZ2V0U2Vjb25kcygpOwogICAgICAgICAgICB2YXIgbWluID0gZC5nZXRNaW51dGVzKCk7CiAgICAgICAgICAgIHZhciBob3VyID0gZC5nZXRIb3VycygpOwogICAgICAgICAgICB2YXIgZGF0ZSA9IGRheSArICIuIiArIG1vbnRoICsgIi4iICsgeWVhciArIiAiICsgaG91ciArICI6IiArIG1pbiArICI6IiArIHNlYyArICI6IiArIG1pbGk7CiAgICAgICAgICAgIGlmKHRoaXMuanNvbk1vZGVsICYmIHRoaXMuanNvbk1vZGVsLmNhdGVnb3J5KSB7CiAgICAgICAgICAgICAgICBmb3IodmFyIGkgPSAwOyBpPHRoaXMuanNvbk1vZGVsLmNhdGVnb3J5Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGxldmVsICE9IDAgJiYgdGhpcy5qc29uTW9kZWwubGV2ZWxbaV0gPj0gbGV2ZWwgJiYgdGhpcy5qc29uTW9kZWwuY2F0ZWdvcnlbaV0gPT0gY2F0ZWdvcnkgJiYgdGhpcy5qc29uTW9kZWwub24gPT0gInRydWUiKSB7CgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzb2x2ZWRNZXNzYWdlID0gbWVzc2FnZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoc25pcHBldHMpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9yZXNvbHZlIG1lc3NhZ2Ugd2l0aCBzbmlwcGV0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlZE1lc3NhZ2UgPSB0aGlzLnJlc29sdmVNZXNzYWdlKG1lc3NhZ2UsIHNuaXBwZXRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRleHQgPSAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCArPSBkYXRlIDsKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCArPSAiICoiICsgdGhpcy5sb2dMZXZlbE5hbWVzW2xldmVsXSArICIqIjsKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCArPSAiIFsiICsgIGNhdGVnb3J5ICsgIl0iIDsKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCArPSAiICAiICsgcmVzb2x2ZWRNZXNzYWdlICsgIlxyXG4iIDsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2dNZXNzYWdlcyArPSB0ZXh0IDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5qc29uTW9kZWwudHlwZSA9PSAiY29uc29sZSIgfHwgdGhpcy5qc29uTW9kZWwudHlwZSA9PSAiY29uc29sZVNlcnZlciIgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICArK3RoaXMuTE9HX0NPVU5ULmNhdGVnb3J5W2NhdGVnb3J5IHx8ICdVbmtub3duJ107CiAgICAgICAgICAgICAgICAgICAgICAgICAgICArK3RoaXMuTE9HX0NPVU5ULmxldmVsW3RoaXMubG9nTGV2ZWxOYW1lc1twYXJzZUludChsZXZlbCkgPCA4PyBsZXZlbDo3XV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnNvbGVIYW5kbGVyKHRleHQsIGxldmVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNvbnNvbGVIYW5kbGVyIDogZnVuY3Rpb24odGV4dCwgbGV2ZWwpewogICAgICAgICAgICBpZih0eXBlb2YgY29uc29sZSAhPSAidW5kZWZpbmVkIikgewogICAgICAgICAgICAgICAgdmFyIGxldmVsTmFtZSA9IHR5cGVvZiB0aGlzLmxvZ0xldmVsTmFtZXNbbGV2ZWxdID09PSAic3RyaW5nIgogICAgICAgICAgICAgICAgICAgID8gdGhpcy5sb2dMZXZlbE5hbWVzW2xldmVsXS50b0xvd2VyQ2FzZSgpCiAgICAgICAgICAgICAgICAgICAgOiAibG9nIiwKICAgICAgICAgICAgICAgICAgICBsb2dGdW5jdGlvbiA9IGNvbnNvbGUubG9nOwogICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlW2xldmVsTmFtZV0gPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgICAgICAgICBsb2dGdW5jdGlvbiA9IGNvbnNvbGVbbGV2ZWxOYW1lXQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbG9nRnVuY3Rpb24uY2FsbChjb25zb2xlLCAiXG5cblxuIiArIHRleHQpOwogICAgICAgICAgICAgICAgLy9FcnJvciBsb2cgYWxyZWFkeSBzaG93cyB0aGUgY2FsbCBzdGFjayBmb3IgZGVidWdnaW5nLgogICAgICAgICAgICAgICAgaWYobGV2ZWxOYW1lICE9PSAiZXJyb3IiKSB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgbi50ZXN0CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChleGNlcHRpb24uc3RhY2spIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ0Z1bmN0aW9uLmNhbGwoY29uc29sZSwgZXhjZXB0aW9uLnN0YWNrLnJlcGxhY2UoIlJlZmVyZW5jZUVycm9yOiBuIGlzIG5vdCBkZWZpbmVkIiwgIiIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqICBIZWxwZXIgZnVuY3Rpb24gdG8gZ2VyIHN1Ym1pdCBzZXJ2aWNlIHByb3h5IHVybAogICAgICAgICAqLwogICAgICAgIF9nZXRMb2dTZXJ2aWNlUHJveHlVcmw6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgbG9nU2VydmljZVByb3h5VXJsID0gIiI7CiAgICAgICAgICAgIGlmKHRoaXMubG9nU2VydmljZVByb3h5KQogICAgICAgICAgICAgICAgbG9nU2VydmljZVByb3h5VXJsICs9IHRoaXMubG9nU2VydmljZVByb3h5OwogICAgICAgICAgICBlbHNlIC8vZmluYWxseSBoYXJkIGNvZGUgaXQKICAgICAgICAgICAgICAgIGxvZ1NlcnZpY2VQcm94eVVybCArPSAoKHRoaXMuY29udGV4dFBhdGggJiYgdGhpcy5jb250ZXh0UGF0aCAhPSAiLyIpID8gdGhpcy5jb250ZXh0UGF0aCA6ICIiKSArICIvY29udGVudC94ZmFmb3Jtcy9wcm9maWxlcy9kZWZhdWx0LmxvZy5odG1sIjsKICAgICAgICAgICAgcmV0dXJuIGxvZ1NlcnZpY2VQcm94eVVybDsKICAgICAgICB9LAoKICAgICAgICBfaW52b2tlQXRTZXJ2ZXI6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgdmFyIGxvY2FsU3VibWl0VXJsID0gIHRoaXMuX2dldExvZ1NlcnZpY2VQcm94eVVybCgpOwogICAgICAgICAgICB2YXIgcGFyYW1zID0gewogICAgICAgICAgICAgICAgICAgIGFzeW5jOiB0cnVlLAogICAgICAgICAgICAgICAgICAgIHVybDogbG9jYWxTdWJtaXRVcmwsCiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ1BPU1QnLAogICAgICAgICAgICAgICAgICAgIGNvbnRlbnRUeXBlOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04JywKICAgICAgICAgICAgICAgICAgICBkYXRhOiBvcHRpb25zCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAkLmFqYXgocGFyYW1zKTsKICAgICAgICB9LAoKICAgICAgICBpc1NlcnZlckxvZ2dpbmdFbmFibGVkIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgaWYoKHRoaXMuanNvbk1vZGVsLm9uID09ICJ0cnVlIikgJiYgKHRoaXMuanNvbk1vZGVsLnR5cGUgPT0gInNlcnZlciIgfHwgdGhpcy5qc29uTW9kZWwudHlwZSA9PSAiY29uc29sZVNlcnZlciIpKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBzZXJ2ZXJIYW5kbGVyIDpmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIG9wdGlvbnMgPSB7J2xvZ01lc3NhZ2VzJyA6IHRoaXMubG9nTWVzc2FnZXMsICdyZW5kZXJDb250ZXh0JyA6IHRoaXMucmVuZGVyQ29udGV4dH07CiAgICAgICAgICAgIHRoaXMuX2ludm9rZUF0U2VydmVyKG9wdGlvbnMpOwogICAgICAgICAgICB0aGlzLmxvZ01lc3NhZ2VzID0gIiIgOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFdyaXRlcyBhIG1lc3NhZ2UgdG8gdGhlIGNvbnNvbGUgaWYgbG9nIGxldmVsIGlzIHNldCB0bwogICAgICAgICAqIHtAbGluayAjRkFUQUx9IG9yIGhpZ2hlci4KICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgVGhlIGxvZyBtZXNzYWdlCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmcvU3RyaW5nW119IHNuaXBwZXRzIChvcHRpb25hbCkgVGhlIHRleHRzIHJlcGxhY2luZwogICAgICAgICAqICAgICAgICA8Y29kZT57bn08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgZmF0YWwgOiBmdW5jdGlvbihjYXRlZ29yeSwgbWVzc2FnZSwgc25pcHBldHMpIHsKICAgICAgICAgICAgdGhpcy5sb2coY2F0ZWdvcnksIHRoaXMuRkFUQUwsIG1lc3NhZ2UsIHNuaXBwZXRzKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBXcml0ZXMgYSBtZXNzYWdlIHRvIHRoZSBjb25zb2xlIGlmIGxvZyBsZXZlbCBpcyBzZXQgdG8KICAgICAgICAgKiB7QGxpbmsgI0VSUk9SfSBvciBoaWdoZXIuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIFRoZSBsb2cgbWVzc2FnZQogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nL1N0cmluZ1tdfSBzbmlwcGV0cyAob3B0aW9uYWwpIFRoZSB0ZXh0cyByZXBsYWNpbmcKICAgICAgICAgKiAgICAgICAgPGNvZGU+e259PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIGVycm9yIDogZnVuY3Rpb24oY2F0ZWdvcnksIG1lc3NhZ2UsIHNuaXBwZXRzKSB7CiAgICAgICAgICAgIHRoaXMubG9nKGNhdGVnb3J5LCB0aGlzLkVSUk9SLCBtZXNzYWdlLCBzbmlwcGV0cyk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV3JpdGVzIGEgbWVzc2FnZSB0byB0aGUgY29uc29sZSBpZiBsb2cgbGV2ZWwgaXMgc2V0IHRvCiAgICAgICAgICoge0BsaW5rICNXQVJOfSBvciBoaWdoZXIuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIFRoZSBsb2cgbWVzc2FnZQogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nL1N0cmluZ1tdfSBzbmlwcGV0cyAob3B0aW9uYWwpIFRoZSB0ZXh0cyByZXBsYWNpbmcKICAgICAgICAgKiAgICAgICAgPGNvZGU+e259PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHdhcm4gOiBmdW5jdGlvbihjYXRlZ29yeSwgbWVzc2FnZSwgc25pcHBldHMpIHsKICAgICAgICAgICAgdGhpcy5sb2coY2F0ZWdvcnksIHRoaXMuV0FSTiwgbWVzc2FnZSwgc25pcHBldHMpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFdyaXRlcyBhIG1lc3NhZ2UgdG8gdGhlIGNvbnNvbGUgaWYgbG9nIGxldmVsIGlzIHNldCB0bwogICAgICAgICAqIHtAbGluayAjSU5GT30gb3IgaGlnaGVyLgogICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBUaGUgbG9nIG1lc3NhZ2UKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZy9TdHJpbmdbXX0gc25pcHBldHMgKG9wdGlvbmFsKSBUaGUgdGV4dHMgcmVwbGFjaW5nCiAgICAgICAgICogICAgICAgIDxjb2RlPntufTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBpbmZvIDogZnVuY3Rpb24oY2F0ZWdvcnksIG1lc3NhZ2UsIHNuaXBwZXRzKSB7CiAgICAgICAgICAgIHRoaXMubG9nKGNhdGVnb3J5LCB0aGlzLklORk8sIG1lc3NhZ2UsIHNuaXBwZXRzKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBXcml0ZXMgYSBtZXNzYWdlIHRvIHRoZSBjb25zb2xlIGlmIGxvZyBsZXZlbCBpcyBzZXQgdG8KICAgICAgICAgKiB7QGxpbmsgI0RFQlVHfSBvciBoaWdoZXIuCiAgICAgICAgICogQHN0YXRpYwogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIFRoZSBsb2cgbWVzc2FnZQogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nL1N0cmluZ1tdfSBzbmlwcGV0cyAob3B0aW9uYWwpIFRoZSB0ZXh0cyByZXBsYWNpbmcKICAgICAgICAgKiAgICAgICAgPGNvZGU+e259PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIGRlYnVnIDogZnVuY3Rpb24oY2F0ZWdvcnksIG1lc3NhZ2UsIHNuaXBwZXRzKSB7CiAgICAgICAgICAgIHRoaXMubG9nKGNhdGVnb3J5LCB0aGlzLkRFQlVHLCBtZXNzYWdlLCBzbmlwcGV0cyk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogV3JpdGVzIGEgbWVzc2FnZSB0byB0aGUgY29uc29sZSBpZiBsb2cgbGV2ZWwgaXMgc2V0IHRvCiAgICAgICAgICoge0BsaW5rICNUUkFDRX0gb3IgaGlnaGVyLgogICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBUaGUgbG9nIG1lc3NhZ2UKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZy9TdHJpbmdbXX0gc25pcHBldHMgKG9wdGlvbmFsKSBUaGUgdGV4dHMgcmVwbGFjaW5nCiAgICAgICAgICogICAgICAgIDxjb2RlPntufTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICB0cmFjZSA6ICBmdW5jdGlvbihjYXRlZ29yeSwgbWVzc2FnZSwgc25pcHBldHMpIHsKICAgICAgICAgICAgdGhpcy5sb2coY2F0ZWdvcnksIHRoaXMuVFJBQ0UsIG1lc3NhZ2UsIHNuaXBwZXRzKTsKICAgICAgICB9LAoKICAgICAgICBpc0xvZ0VuYWJsZWQgOiBmdW5jdGlvbihjYXRlZ29yeSwgbGV2ZWwpIHsKICAgICAgICAgICAgaWYodGhpcy5qc29uTW9kZWwub24gPT0gInRydWUiKSB7CiAgICAgICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5qc29uTW9kZWwuY2F0ZWdvcnkuaW5kZXhPZihjYXRlZ29yeSkgOwogICAgICAgICAgICAgICAgaWYodGhpcy5qc29uTW9kZWwubGV2ZWxbcG9zXSA+PSBsZXZlbCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCB4ZmFsaWIsICQpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LkV2ZW50Q2xhc3MKICogQGltcG9ydCB4ZmFsaWIudXQuQ2xhc3MKICovCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgLy8gUmVndWxhciBleHByZXNzaW9uIHVzZWQgdG8gc3BsaXQgZXZlbnQgc3RyaW5ncwogICAgLy8gUmVndWxhciBleHByZXNzaW9uIHVzZWQgdG8gc3BsaXQgZXZlbnQgc3RyaW5ncwogICAgdmFyIGV2ZW50U3BsaXR0ZXIgPSAvXHMrLzsKCiAgICAvLyBBIG1vZHVsZSB0aGF0IGNhbiBiZSBtaXhlZCBpbiB0byAqYW55IG9iamVjdCogaW4gb3JkZXIgdG8gcHJvdmlkZSBpdCB3aXRoCiAgICAvLyBjdXN0b20gZXZlbnRzLiBZb3UgbWF5IGJpbmQgd2l0aCBgb25gIG9yIHJlbW92ZSB3aXRoIGBvZmZgIGNhbGxiYWNrIGZ1bmN0aW9ucwogICAgLy8gdG8gYW4gZXZlbnQ7IHRyaWdnZXJgLWluZyBhbiBldmVudCBmaXJlcyBhbGwgY2FsbGJhY2tzIGluIHN1Y2Nlc3Npb24uCiAgICAvLwogICAgdmFyIEV2ZW50Q2xhc3MgPSB4ZmFsaWIudXQuRXZlbnRDbGFzcyA9ICB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKCiAgICAgICAgLy8gQmluZCBvbmUgb3IgbW9yZSBzcGFjZSBzZXBhcmF0ZWQgZXZlbnRzLCBgZXZlbnRzYCwgdG8gYSBgbGlzdGVuZXJgCiAgICAgICAgLy8gb2JqZWN0LiBUaGUgb2JqZWN0IHNob3VsZCBpbXBsZW1lbnQgYGhhbmRsZUV2ZW50YCBmdW5jdGlvbiB3aGljaCB3aWxsIGJlCiAgICAgICAgLy8gY2FsbGVkIG9uIGV2ZW50IGRpc3BhdGNoCiAgICAgICAgb246IGZ1bmN0aW9uKGV2ZW50LCBsaXN0ZW5lciwgY29udGV4dCkgewoKICAgICAgICAgICAgdmFyIGNhbGxzLCBsaXN0LHJldFZhbCA9IHRydWU7CiAgICAgICAgICAgIHZhciBmbkNhbGxiYWNrID0gXy5pc0Z1bmN0aW9uKGxpc3RlbmVyKSA/IGxpc3RlbmVyIDogbnVsbDsKICAgICAgICAgICAgaWYgKCFsaXN0ZW5lciB8fCAoIWxpc3RlbmVyWyJoYW5kbGVFdmVudCJdICYmICFmbkNhbGxiYWNrKSkgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgY2FsbHMgPSB0aGlzLl9jYWxsYmFja3MgfHwgKHRoaXMuX2NhbGxiYWNrcyA9IHt9KTsKCiAgICAgICAgICAgIGxpc3QgPSBjYWxsc1tldmVudF0gfHwgKGNhbGxzW2V2ZW50XSA9IFtdKTsKICAgICAgICAgICAgaWYoZm5DYWxsYmFjayl7CiAgICAgICAgICAgICAgICBjb250ZXh0ID0gY29udGV4dCB8fCB0aGlzOwogICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gXy5maW5kKGxpc3QsIGZ1bmN0aW9uKGNhbGxiYWNrKXsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGNhbGxiYWNrLmZuID09IGZuQ2FsbGJhY2sgJiYgY2FsbGJhY2suY29udGV4dCA9PSBjb250ZXh0KTsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICAgICAgaWYoZm91bmQpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbGlzdC5wdXNoKHsiZm4iIDogZm5DYWxsYmFjaywgImNvbnRleHQiOiBjb250ZXh0fSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZXsKICAgICAgICAgICAgICAgIGlmKH5saXN0LmluZGV4T2YobGlzdGVuZXIpKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBsaXN0LnB1c2gobGlzdGVuZXIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gIHRydWU7CiAgICAgICAgfSwKCiAgICAgICAgLy8gUmVtb3ZlIG9uZSBvciBtYW55IGNhbGxiYWNrcy4gSWYgYGxpc3RlbmVyYCBpcyBudWxsLCByZW1vdmVzIGFsbCBsaXN0ZW5lciBmb3IgdGhlCiAgICAgICAgLy8gZXZlbnQuIElmIGBldmVudHNgIGlzIG51bGwsIHJlbW92ZXMgYWxsIGJvdW5kIGNhbGxiYWNrcyBmb3IgYWxsIGV2ZW50cy4KICAgICAgICBvZmY6IGZ1bmN0aW9uKGV2ZW50cywgbGlzdGVuZXIsIGNvbnRleHQpIHsKICAgICAgICAgICAgdmFyIGV2ZW50LCBjYWxscywgbm9kZTsKCiAgICAgICAgICAgIC8vIE5vIGV2ZW50cywgb3IgcmVtb3ZpbmcgKmFsbCogZXZlbnRzLgogICAgICAgICAgICBpZiAoIShjYWxscyA9IHRoaXMuX2NhbGxiYWNrcykpIHJldHVybjsKICAgICAgICAgICAgaWYgKCEoZXZlbnRzIHx8IGxpc3RlbmVyKSkgewogICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2NhbGxiYWNrczsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgZm5DYWxsYmFjayA9IF8uaXNGdW5jdGlvbihsaXN0ZW5lcikgPyBsaXN0ZW5lciA6IG51bGw7CiAgICAgICAgICAgIC8vIExvb3AgdGhyb3VnaCB0aGUgbGlzdGVkIGV2ZW50cyBhbmQgY29udGV4dHMgYW5kIHJlbW92ZSB0aGUgcmVxdWlyZWQgb25lcy4KICAgICAgICAgICAgZXZlbnRzID0gZXZlbnRzID8gZXZlbnRzLnNwbGl0KGV2ZW50U3BsaXR0ZXIpIDogXy5rZXlzKGNhbGxzKTsKICAgICAgICAgICAgd2hpbGUgKGV2ZW50ID0gZXZlbnRzLnNoaWZ0KCkpIHsKICAgICAgICAgICAgICAgIG5vZGUgPSBjYWxsc1tldmVudF07CiAgICAgICAgICAgICAgICBjYWxsc1tldmVudF0gPSBfLmZpbHRlcihjYWxsc1tldmVudF0sZnVuY3Rpb24oZWxlbSkgewogICAgICAgICAgICAgICAgICAgIGlmKHR5cGVvZihsaXN0ZW5lcikgIT09ICJ1bmRlZmluZWQiKXsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoZm5DYWxsYmFjayAmJiBlbGVtLmZuID09IGZuQ2FsbGJhY2sgJiYgZWxlbS5jb250ZXh0ID09IGNvbnRleHQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoIWZuQ2FsbGJhY2sgJiYgbGlzdGVuZXIgPT09IGVsZW0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGlmKCFjYWxsc1tldmVudF0ubGVuZ3RoKQogICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBjYWxsc1tldmVudF07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCgogICAgICAgIC8vIFRyaWdnZXIgb25lIG9yIG1hbnkgZXZlbnRzLCBmaXJpbmcgYWxsIGJvdW5kIGNhbGxiYWNrcy4gQ2FsbGJhY2tzIGFyZQogICAgICAgIC8vIHBhc3NlZCB0aGUgc2FtZSBhcmd1bWVudHMgYXMgYHRyaWdnZXJgIGV4Y2VwdCB0aGUgZmlyc3QKICAgICAgICB0cmlnZ2VyOiBmdW5jdGlvbihldmVudHMpIHsKICAgICAgICAgICAgdmFyIGV2ZW50LCBjYWxscywgcmVzdDsKICAgICAgICAgICAgaWYgKCEoY2FsbHMgPSB0aGlzLl9jYWxsYmFja3MpKSByZXR1cm4gdGhpczsKICAgICAgICAgICAgZXZlbnRzID0gZXZlbnRzLnNwbGl0KGV2ZW50U3BsaXR0ZXIpOwogICAgICAgICAgICB2YXIgcGF5TG9hZCA9IF8ucmVzdChhcmd1bWVudHMpOwogICAgICAgICAgICB3aGlsZSAoZXZlbnQgPSBldmVudHMuc2hpZnQoKSkgewogICAgICAgICAgICAgICAgXy5lYWNoKGNhbGxzW2V2ZW50XSxmdW5jdGlvbihjYWxsYmFjaykgewogICAgICAgICAgICAgICAgICAgIGlmKGNhbGxiYWNrLmZuICYmIGNhbGxiYWNrLmNvbnRleHQpewogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5mbi5hcHBseShjYWxsYmFjay5jb250ZXh0LCBwYXlMb2FkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoXy5pc0Z1bmN0aW9uKGNhbGxiYWNrLmhhbmRsZUV2ZW50KSl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmhhbmRsZUV2ZW50LmFwcGx5KGNhbGxiYWNrLCBwYXlMb2FkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgIH0pOwoKCn0pKF8sIHhmYWxpYik7CgoKKGZ1bmN0aW9uIChfLCAkLCB4ZmFsaWIpIHsKICAgIHZhciBYZmFVdGlsID0geGZhbGliLnV0LlhmYVV0aWwgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgfSwKICAgICAgICByZWdpc3RlcmVkTG9jYWxlUHJvcGVydGllcyA9IG51bGwsCiAgICAgICAgdGltZW91dExpc3RlbmVyQXR0YWNoZWQgPSBmYWxzZSwKICAgICAgICB0aW1lb3V0cyA9IFtdLAogICAgICAgIGF0dGFjaENsZWFyVGltZW91dExpc3RlbmVyID0gZnVuY3Rpb24gKHRpbWVvdXQpIHsKICAgICAgICAgICAgdGltZW91dHMucHVzaCh0aW1lb3V0KTsKICAgICAgICAgICAgaWYgKHRpbWVvdXRMaXN0ZW5lckF0dGFjaGVkID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJCh3aW5kb3cpLm9uZSgiZGVzdHJveS54ZmEiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgXy5lYWNoKHRpbWVvdXRzLCBmdW5jdGlvbiAoX3RpbWVvdXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF90aW1lb3V0KTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB0aW1lb3V0cyA9IFtdOwogICAgICAgICAgICAgICAgICAgIHRpbWVvdXRMaXN0ZW5lckF0dGFjaGVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHRpbWVvdXRMaXN0ZW5lckF0dGFjaGVkID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICBfLmV4dGVuZChYZmFVdGlsLnByb3RvdHlwZSwgewogICAgICAgIF9nbG9iYWxVbmlxdWVJZDogKG5ldyBEYXRlKCkpLmdldFRpbWUoKSwKICAgICAgICBsb2dnZXI6IG51bGwsCgogICAgICAgIGZvcm1TY2FsZUZhY3RvcjogMSwgICAgICAvLyB1c2VkIHRvIGFwcHJvcHJpYXRlbHkgc2NhbGUgdGhlIGZvcm0gd2hlbiBjb250YWluZWQgaW5zaWRlIGFuIGlmcmFtZQoKICAgICAgICBnZXRPckVsc2U6IHhmYWxpYi51dC5DbGFzcy5wcm90b3R5cGUuZ2V0T3JFbHNlLAogICAgICAgIC8vbWFwIG9mIGV2ZW50IG5hbWVzIGJldHdlZW4gWFRHIGFuZCBNb2JpbGUgRm9ybQogICAgICAgIC8vTW9iaWxlIEZvcm0gdXNlcyBkaWZmZXJlbnQgbmFtZXMgZm9yIHNvbWUgdGhlIGV2ZW50IGFuZCBsZXQncyBmaXggdGhvc2UgbmFtZXMgYmVmb3JlIHNlbmRpbmcgdGhlbSB0byBYVEcuCiAgICAgICAgX3h0Z0V2ZW50TmFtZTogewogICAgICAgICAgICAiJGZvcm1yZWFkeSI6ICJyZWFkeSIsCiAgICAgICAgICAgICIkbGF5b3V0cmVhZHkiOiAicmVhZHkiCiAgICAgICAgfSwKCiAgICAgICAgZ2VuZXJhdGVVSUQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICJVSUQiICsgKCsrWGZhVXRpbC5wcm90b3R5cGUuX2dsb2JhbFVuaXF1ZUlkKTsKICAgICAgICB9LAoKICAgICAgICBtYXRjaEpzb25UeXBlOiBmdW5jdGlvbiAoanNvbk1vZGVsLCBfY2xhc3MpIHsgICAvL1RPRE86IGhhbmRsZSBnZXRPckVsc2UKICAgICAgICAgICAgcmV0dXJuIChqc29uTW9kZWwgJiYgX2NsYXNzICYmIFhmYVV0aWwucHJvdG90eXBlLmdldE9yRWxzZShqc29uTW9kZWwuX2NsYXNzLCAiIikudG9Mb3dlckNhc2UoKSA9PSAoIiIgKyBfY2xhc3MpLnRvTG93ZXJDYXNlKCkpOwogICAgICAgIH0sCgogICAgICAgICRkYXRhOiBmdW5jdGlvbiAoZWxlbSwgbmFtZSwgZGF0YSkgewogICAgICAgICAgICBpZiAoISQuZGF0YShlbGVtLCAiX3hmYUluaXRpYWxpemVkIikpIHsKICAgICAgICAgICAgICAgIC8vSW5pdGlhbGl6ZWQgZGF0YS0gYXR0cmlidXRlcyBwYXJzZSBmb3Igb25jZSB1c2luZyB0aGlzIGNhbGwuCiAgICAgICAgICAgICAgICAvLyBOZXh0IG9ud2FyZCBkb24ndCB1c2UgdGhpcy4gSW5zdGVhZCB1c2UgJC5kYXRhIHdoaWNoIGlzIGNoZWFwLwogICAgICAgICAgICAgICAgJChlbGVtKS5kYXRhKCk7CiAgICAgICAgICAgICAgICAkLmRhdGEoZWxlbSwgIl94ZmFJbml0aWFsaXplZCIsIHRydWUpOyAvL01hcmsgdGhlIGVsZW1lbnQgdG8gc2F5IHRoYXQgZGF0YSBoYXMgYmVlbiBpbml0aWFsaXplZC4KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gJC5kYXRhKGVsZW0sIG5hbWUsIGRhdGEpOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogYWx0ZXJuYXRpdmUgdG8galF1ZXJ5LmNzcyB3aGljaCBzZXRzIHN0eWxlIHByb3BlcnRpZXMgZGlyZWN0bHkgdGhyb3VnaCBlbGVtZW50LnN0eWxlLiBUaGlzIGlzIG11Y2ggZmFzdGVyIHRoZW4KICAgICAgICAgKiBjb3JyZXNwb25kaW5nIGpRdWVyeS5jc3MgYWx0ZXJuYXRpdmUuCiAgICAgICAgICoKICAgICAgICAgKiBXYXJuaW5nOiB0aGlzIG9ubHkgc3VwcG9ydHMgc3RhbmRhcmQgY3NzIHByb3BlcnR5IG5hbWVzIGFuZCBkb2VzIG5vdCBkbyBhbnkgcHJlLXByb2Nlc3Npbmcgb2YgbmFtZSBhbmQgdmFsdWUuCiAgICAgICAgICogU28gY2FsbGluZyB0aGlzLCBtYWtlIHN1cmUgdGhlIHN0eWxlIG5hbWVzIGFyZSBjb21wYXRpYmxlLgogICAgICAgICAqLwogICAgICAgICRjc3M6IGZ1bmN0aW9uIChlbGVtLCBzdHlsZXNPYmopIHsKICAgICAgICAgICAgLy8gRXhjbHVkZSB0aGUgZm9sbG93aW5nIGNzcyBwcm9wZXJ0aWVzIHRvIGFkZCBweC4gY29waWVkIGZyb20ganF1ZXJ5LmNzc051bWJlciB0byBhZGQgaHlwaGVuYXRlZCBzdHlsZSBuYW1lcwogICAgICAgICAgICB2YXIgY3NzTnVtYmVyID0gewogICAgICAgICAgICAgICAgImZpbGxPcGFjaXR5IjogdHJ1ZSwKICAgICAgICAgICAgICAgICJmaWxsLW9wYWNpdHkiOiB0cnVlLAogICAgICAgICAgICAgICAgImZvbnRXZWlnaHQiOiB0cnVlLAogICAgICAgICAgICAgICAgImZvbnQtd2VpZ2h0IjogdHJ1ZSwKICAgICAgICAgICAgICAgICJsaW5lSGVpZ2h0IjogdHJ1ZSwKICAgICAgICAgICAgICAgICJsaW5lLWhlaWdodCI6IHRydWUsCiAgICAgICAgICAgICAgICAiekluZGV4IjogdHJ1ZSwKICAgICAgICAgICAgICAgICJ6LWluZGV4IjogdHJ1ZSwKICAgICAgICAgICAgICAgICJvcGFjaXR5IjogdHJ1ZSwKICAgICAgICAgICAgICAgICJvcnBoYW5zIjogdHJ1ZSwKICAgICAgICAgICAgICAgICJ3aWRvd3MiOiB0cnVlLAogICAgICAgICAgICAgICAgInpvb20iOiB0cnVlCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBmb3IgKHZhciBwcm9wIGluIHN0eWxlc09iaikgewogICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gc3R5bGVzT2JqW3Byb3BdOwogICAgICAgICAgICAgICAgLy8gSWYgYSBudW1iZXIgd2FzIHBhc3NlZCBpbiwgYWRkICdweCcgdG8gdGhlIChleGNlcHQgZm9yIGNlcnRhaW4gQ1NTIHByb3BlcnRpZXMpCiAgICAgICAgICAgICAgICBpZiAoXy5pc051bWJlcih2YWx1ZSkgJiYgIWNzc051bWJlclsgcHJvcCBdKSB7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgKz0gInB4IjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsZW0uc3R5bGVbcHJvcF0gPSB2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGlzVGFibGVIRjogZnVuY3Rpb24gKGlDaGlsZE5vZGUpIHsKICAgICAgICAgICAgLy9tb2RlbCBjYW4gYmUgYSBOb2RlIG9iamVjdCBvciBzaW1wbHkgYSBqc29uCiAgICAgICAgICAgIHZhciBhc3Npc3RKc29uID0gXy5maW5kKGlDaGlsZE5vZGUuY2hpbGRyZW4sIGZ1bmN0aW9uIChqQ2hpbGQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBqQ2hpbGQuX2NsYXNzID09ICJhc3Npc3QiOwogICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgdmFyIGNoaWxkUm9sZSA9IChhc3Npc3RKc29uIHx8IHt9KS5yb2xlOwogICAgICAgICAgICBpZiAoY2hpbGRSb2xlID09ICJUSCIgfHwgY2hpbGRSb2xlID09ICJURiIpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIGdldFVpT25lT2ZDaGlsZFRhZzogZnVuY3Rpb24gKHVpUGFyZW50KSB7CiAgICAgICAgICAgIHZhciB1aUVsID0gXy5maW5kKHVpUGFyZW50LmNoaWxkcmVuLCBmdW5jdGlvbiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZC5fY2xhc3MgPT0gInVpIjsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlmICghdWlFbCkKICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgIHZhciB1aU9uZU9mQ2hpbGRNYXAgPSB4ZmFsaWIucnVudGltZS54ZmEuX3RlbXBsYXRlU2NoZW1hLl9nZXRPbmVPZkNoaWxkKCJ1aSIpOwogICAgICAgICAgICB2YXIgdWlPbmVPZkNoaWxkID0gXy5maW5kKHVpRWwuY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHVpT25lT2ZDaGlsZE1hcFtjaGlsZC5fY2xhc3NdID09IHRydWU7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBpZiAoIXVpT25lT2ZDaGlsZCkKICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgIHJldHVybiB1aU9uZU9mQ2hpbGQuX2NsYXNzOwogICAgICAgIH0sCgogICAgICAgIC8vVE9ETzogdGhpcyBzaG91bGQgYmUgcmVtb3ZlZC4gT25lIG9mIHRoZSB3b3JzdCBmdW5jdGlvbi4KICAgICAgICBkSW5kZXhPZjogZnVuY3Rpb24gKHNlYXJjaEFycmF5LCBpdGVtMkZpbmQpIHsKICAgICAgICAgICAgdmFyIGluZCA9IC0xOwogICAgICAgICAgICBfLmZpbmQoc2VhcmNoQXJyYXksIGZ1bmN0aW9uIChpdGVtLCBpbmRleCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT0gaXRlbTJGaW5kICYmIChpbmQgPSBpbmRleCkKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHJldHVybiBpbmQ7CiAgICAgICAgfSwKCiAgICAgICAgc3BsaXRTdHJpbmdCeVdpZHRoOiBmdW5jdGlvbiAodmFsdWUsIHdpZHRoLCByZWZFbCkgewogICAgICAgICAgICB2YXIgaSA9IHZhbHVlLmxlbmd0aCAsIGV4cGVjdGVkV2lkdGg7CiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIGV4cGVjdGVkV2lkdGggPSB4ZmFsaWIudmlldy51dGlsLlRleHRNZXRyaWNzLm1lYXN1cmVFeHRlbnQodmFsdWUuc2xpY2UoMCwgaSksIHsicmVmRWwiOiByZWZFbCwgbWF4V2lkdGg6IC0xfSkud2lkdGg7CiAgICAgICAgICAgICAgICBpLS07CiAgICAgICAgICAgIH0gd2hpbGUgKGV4cGVjdGVkV2lkdGggPiB3aWR0aCkKICAgICAgICAgICAgaWYgKGkgIT0gdmFsdWUubGVuZ3RoIC0gMSkKICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5zbGljZSgwLCBpICsgMSk7CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9LAoKICAgICAgICBpc1JlcGVhdGFiZUVsOiBmdW5jdGlvbiAoZWxUYWcpIHsKICAgICAgICAgICAgaWYgKGVsVGFnID09ICJzdWJmb3JtIiB8fCBlbFRhZyA9PSAic3ViZm9ybVNldCIpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqIHN0cmlwT3JDYWxsKHRvU3RyaXAsIGRpZmZGdW5jLCBmQXJncykKICAgICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICAgKiBjb21tb24gdXRpbGl0eSBmdW5jdGlvbiB0byBoYW5kbGUgZmluYWwgc3VibWlzc2lvbiBwYXlsb2FkIHN0cmlwcGluZwogICAgICAgICAqIEBwYXJhbSB7Ym9vbH0gdG9TdHJpcCA6IGZsYWcgdG8gc2lnbmlmeSB3aGV0aGVyIHRvIG9wdGltaXplIGpzb25Nb2RlbERpZmYgc2l6ZSwgYnkgc3RyaXBwaW5nIG9mZiB1bm5lY2Vzc2FyeSBwcm9wZXJ0aWVzCiAgICAgICAgICogQHBhcmFtIHtmdW5jdGlvbn0gZGlmZkZ1bmMgOiBjYWxsYmFjayBmdW5jLiBjYWxsIGluIGNhc2Ugc3VibWl0IGlzIG5vdCBvbgogICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGZBcmdzIDogYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byB0aGUgZGlmZiBmdW5jLgogICAgICAgICAqIEByZXR1cm5zIHtvYmplY3R9IG9iamVjdCBjb250YWluaW5nIHRoZSBqc29uRGlmZgogICAgICAgICAqLwogICAgICAgIC8vIHNob3VsZCBBTFdBWVMgYmUgY2FsbGVkIHdpdGggYSBmbGFnIHNpZ25pZnlpbmcgaWYgYSBzdWJtaXNzaW9uIGlzIGluIHByb2dyZXNzLAogICAgICAgIC8vIGFuZCBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGNvbXB1dGUgdGhlIGpzb24gdG8gYmUgc2VudCBiYWNrIGR1cmluZyBzdWJtaXNzaW9uLCB1c3VhbGx5IGFuIGFwdCAnX2NvbXB1dGVKc29uRGlmZicKICAgICAgICBzdHJpcE9yQ2FsbDogZnVuY3Rpb24gKHRvU3RyaXAsIGRpZmZGdW5jLCBmQXJncykgewogICAgICAgICAgICBpZiAodG9TdHJpcCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICAiY2hhbmdlZCI6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICJqc29uRGlmZmVyZW5jZSI6IHt9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKF8uaXNGdW5jdGlvbihkaWZmRnVuYykpIHsKICAgICAgICAgICAgICAgIHJldHVybiBkaWZmRnVuYy5hcHBseSh0aGlzLCBmQXJncyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBwYXJ0aWFsU3RyaXBPckNhbGwoc3RyaXBMdmwsIGRpZmZGdW5jLCBmQXJncykKICAgICAgICAgKiBAZGVzY3JpcHRpb24KICAgICAgICAgKiBjb21tb24gdXRpbGl0eSBmdW5jdGlvbiB0byBoYW5kbGUgZmluYWwgc3VibWlzc2lvbiBwYXlsb2FkIHN0cmlwcGluZyBvciBmb3Igb3V0cHV0IG9mIGdldEZvcm1TdGF0ZS4KICAgICAgICAgKiBAcGFyYW0ge2ludH0gZGlmZl9sZXZlbCA6IGZsYWcgdG8gc2lnbmlmeSB3aGV0aGVyIHRvIG9wdGltaXplIGpzb25Nb2RlbERpZmYgc2l6ZSwgYnkgc3RyaXBwaW5nIG9mZiB1bm5lY2Vzc2FyeSBwcm9wZXJ0aWVzCiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICAgICBtdXN0IGJlIDAsMSwgb3IgMiwgYXMgd2l0aCAiZGlmZl9sZXZlbCIgcGFyYW0gb2YgX2NvbXB1dGVKc29uRGlmZi4KICAgICAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBkaWZmRnVuYyA6IGNhbGxiYWNrIGZ1bmMuIGNhbGwgaW4gY2FzZSBzdWJtaXQgaXMgbm90IG9uCiAgICAgICAgICogQHJldHVybnMge29iamVjdH0gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGpzb25EaWZmCiAgICAgICAgICovCiAgICAgICAgcGFydGlhbFN0cmlwT3JDYWxsOiBmdW5jdGlvbiAoZGlmZl9sZXZlbCwgZGlmZkZ1bmMpIHsKICAgICAgICAgICAgdmFyIGRpZmZPYmogPSBkaWZmRnVuYy5jYWxsKHRoaXMsIGRpZmZfbGV2ZWwpOwoKICAgICAgICAgICAgaWYgKCFkaWZmT2JqLmNoYW5nZWQpIHsKICAgICAgICAgICAgICAgIGlmKGRpZmZfbGV2ZWwgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICBkaWZmT2JqID0gewogICAgICAgICAgICAgICAgICAgICAgICAiY2hhbmdlZCI6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICJqc29uRGlmZmVyZW5jZSI6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfY2xhc3MiOiB0aGlzLmpzb25Nb2RlbC5fY2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibmFtZSI6IHRoaXMuanNvbk1vZGVsLm5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGRpZmZPYmouanNvbkRpZmZlcmVuY2UgPSB7fTsgIC8vIGRvbid0IG5lZWQgc3R1ZmYgZm9yIG90aGVyIGNhc2VzCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBkaWZmT2JqOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqIHN0cmlwT2JqZWN0KG9iaiwgZXhjZXB0aW9uTmFtZXMpCiAgICAgICAgICogQGRlc2NyaXB0aW9uCiAgICAgICAgICogVXRpbGl0eSBmdW5jdGlvbiB0byBzdHJpcCB1bm5lY2Vzc2FyeSBwcm9wZXJ0aWVzIGZyb20gYW4gb2JqZWN0CiAgICAgICAgICogQHBhcmFtIHtvYmplY3R9IG9iaiA6IHRoZSBvYmplY3QgdG8gc3RyaXAKICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBleGNlcHRpb25OYW1lcyA6IGFycmF5IGhvbGRpbmcgbmFtZXMgb2YgaW1wb3J0YW50IHByb3BlcnRpZXMgdG8gcHJlc2VydmUKICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gOiB0cnVlIGlmIHRoaXMgb2JqLCBvciBhbnkgb2YgaXQncyBkZXNjZW5kYW50IGlzIHJldHVybmVkIHVuLXN0cmlwcGVkCiAgICAgICAgICovCiAgICAgICAgc3RyaXBPYmplY3Q6IGZ1bmN0aW9uIChvYmosIGV4Y2VwdGlvbk5hbWVzKSB7CiAgICAgICAgICAgIGlmIChfLmlzRW1wdHkob2JqKSB8fCAhXy5pc09iamVjdChvYmopKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBkb250U3RyaXAgPSBmYWxzZTsKICAgICAgICAgICAgICAgIF8uZWFjaChfLmtleXMob2JqKSwgZnVuY3Rpb24gKHByb3BOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGtlZXBQcm9wID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFfLmNvbnRhaW5zKGV4Y2VwdGlvbk5hbWVzLCBwcm9wTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF8uaXNBcnJheShvYmpbcHJvcE5hbWVdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5lYWNoKG9ialtwcm9wTmFtZV0sIGZ1bmN0aW9uIChhcnJFbGVtKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzVW5TdHJpcHBlZCA9IFhmYVV0aWwucHJvdG90eXBlLnN0cmlwT2JqZWN0KGFyckVsZW0sIGV4Y2VwdGlvbk5hbWVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwUHJvcCA9IGtlZXBQcm9wIHx8IGlzVW5TdHJpcHBlZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKF8uaXNPYmplY3Qob2JqW3Byb3BOYW1lXSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXBQcm9wID0gWGZhVXRpbC5wcm90b3R5cGUuc3RyaXBPYmplY3Qob2JqW3Byb3BOYW1lXSwgZXhjZXB0aW9uTmFtZXMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWtlZXBQcm9wKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgb2JqW3Byb3BOYW1lXTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbnRTdHJpcCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBkb250U3RyaXAgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgcmV0dXJuIGRvbnRTdHJpcDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNvbXB1dGVEb21Kc29uRGlmZjogZnVuY3Rpb24gKGRvbU5vZGUsIGRpZmZfbGV2ZWwpIHsKICAgICAgICAgICAgdmFyIGNoYW5nZWQgPSB0cnVlOwogICAgICAgICAgICBpZiAoZG9tTm9kZS5oYXNPd25Qcm9wZXJ0eSgiX21vZGVsQ2hhbmdlZCIpKSB7CiAgICAgICAgICAgICAgICBjaGFuZ2VkID0gZG9tTm9kZS5fbW9kZWxDaGFuZ2VkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBqc29uRGlmZiA9IHt9OwogICAgICAgICAgICBpZiAoY2hhbmdlZCkgewogICAgICAgICAgICAgICAgdGhpcy5jb3B5T2JqZWN0KGRvbU5vZGUuanNvbk1vZGVsLCBqc29uRGlmZiwgeyJleGNlcHRpb25zIjogWyJjaGlsZHJlbiIsICJ7ZGVmYXVsdH0iLCAiZXh0cmFzIl19KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGpzb25EaWZmID0ge19jbGFzczogZG9tTm9kZS5jbGFzc05hbWV9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghY2hhbmdlZCAmJiBkb21Ob2RlLmpzb25Nb2RlbC5oYXNPd25Qcm9wZXJ0eSgibmFtZSIpKSB7CiAgICAgICAgICAgICAgICBqc29uRGlmZi5uYW1lID0gZG9tTm9kZS5qc29uTW9kZWwubmFtZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZG9tTm9kZS5uYW1lID09PSAiRlNfRVhUUkFTIiAmJiBkaWZmX2xldmVsID09PSAzKSB7CiAgICAgICAgICAgICAgICBkb21Ob2RlLl9jaGlsZE1vZGlmaWVkID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgImNoYW5nZWQiOiBjaGFuZ2VkLAogICAgICAgICAgICAgICAganNvbkRpZmZlcmVuY2U6IGpzb25EaWZmCiAgICAgICAgICAgIH07CiAgICAgICAgfSwKCiAgICAgICAgZ2V0TG9nZ2VyOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBYZmFVdGlsLnByb3RvdHlwZS5sb2dnZXIgfHwgWGZhVXRpbC5wcm90b3R5cGUuZ2V0T3JFbHNlKHhmYWxpYiwgInJ1bnRpbWUueGZhLkxvZ2dlciIsIG51bGwpOwogICAgICAgIH0sCgogICAgICAgIGdldEVycm9yTWFuYWdlcjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gWGZhVXRpbC5wcm90b3R5cGUuZ2V0T3JFbHNlKHhmYWxpYiwgInJ1bnRpbWUueGZhLkVycm9yTWFuYWdlciIsIG51bGwpOwogICAgICAgIH0sCgogICAgICAgIFhGQV9DTElDS19FVkVOVDogInhmYWNsaWNrIiwKICAgICAgICBYRkFfRVhJVF9FVkVOVDogInhmYWV4aXQiLAogICAgICAgIFhGQV9FTlRFUl9FVkVOVDogInhmYWVudGVyIiwKICAgICAgICBYRkFfQ0hBTkdFX0VWRU5UOiAieGZhY2hhbmdlIiwKICAgICAgICBYRkFfUFJFT1BFTl9FVkVOVDogInhmYXByZW9wZW4iLAoKICAgICAgICBidHduOiBmdW5jdGlvbiAodmFsLCBhLCBiKSB7CiAgICAgICAgICAgIHJldHVybiB2YWwgPiBhICYmIHZhbCA8IGI7CiAgICAgICAgfSwKCiAgICAgICAgLy8gZnVuY3Rpb24gdG8gZGV0ZWN0IGlmIEJyb3dzZXIgaXMgY2hyb21lIC8gc2FmYXJpICh3ZWJraXQpCiAgICAgICAgaXNXZWJraXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICAhISQuYnJvd3Nlci53ZWJraXQgfHwgL3dlYmtpdC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkpIHx8ICEhd2luZG93LmNocm9tZSB8fCAhISQuYnJvd3Nlci5jaHJvbWUgfHwgL2Nocm9tKGV8aXVtKS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkpIHx8ICEhJC5icm93c2VyLnNhZmFyaSB8fCAhIXdpbmRvdy53ZWJraXRVUkwgfHwKICAgICAgICAgICAgICAgICggL3NhZmFyaS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkpICYmCiAgICAgICAgICAgICAgICAgICAgL2FwcGxlIGNvbXB1dGVyLy50ZXN0KG5hdmlnYXRvci52ZW5kb3IudG9Mb3dlckNhc2UoKSkgKTsKCiAgICAgICAgICAgIC8vIFRPRE8gOiBmaW5kIGEgYmV0dGVyIHdheSB0byBkbyB0aGlzIGFzICQuYnJvd3NlciBpcyBkZXByZWNhdGVkIGFuZAogICAgICAgICAgICAvLyB1c2VyQWdlbnQgbWF5IGJlIHNwb29mZWQKICAgICAgICB9LAoKICAgICAgICBjbGVhclRpbWVvdXRPbkRlc3Ryb3k6IGZ1bmN0aW9uICh0aW1lb3V0KSB7CiAgICAgICAgICAgIGF0dGFjaENsZWFyVGltZW91dExpc3RlbmVyKHRpbWVvdXQpOwogICAgICAgIH0sCgogICAgICAgIC8vIGZ1bmN0aW9uIHRvIGRldGVjdCBpZiBCcm93c2VyIGlzICBzYWZhcmkKICAgICAgICBpc1NhZmFyaTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gKCAvc2FmYXJpLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKSkgJiYKICAgICAgICAgICAgICAgICAgICAvYXBwbGUgY29tcHV0ZXIvLnRlc3QobmF2aWdhdG9yLnZlbmRvci50b0xvd2VyQ2FzZSgpKSApOwogICAgICAgIH0sCgogICAgICAgIGdldExvY2FsZVN0cmluZ3M6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi5sb2NhbGUuU3RyaW5nczsKICAgICAgICB9LAoKICAgICAgICBnZXRMb2dNZXNzYWdlczogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4geGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlczsKICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIFRoaXMgZnVuY3Rpb24gc2hvdWxkIG5vdCBiZSBhZGRlZCBpbiB0aGUgcHJvdG90eXBlIG9mIGFueSBPYmplY3QKICAgICAgICAgKiBhcyBpbiB0aGUgY2FzZSBvZiBvdGhlciBmdW5jdGlvbnMKICAgICAgICAgKi8KICAgICAgICByZWdpc3RlckxvY2FsZVByb3BlcnRpZXM6IGZ1bmN0aW9uIChwcm9wcykgewogICAgICAgICAgICByZWdpc3RlcmVkTG9jYWxlUHJvcGVydGllcyA9IHByb3BzOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogVGhpcyBmdW5jdGlvbiBzaG91bGQgbm90IGJlIGFkZGVkIGluIHRoZSBwcm90b3R5cGUgb2YgYW55IE9iamVjdAogICAgICAgICAqIGFzIGluIHRoZSBjYXNlIG9mIG90aGVyIGZ1bmN0aW9ucwogICAgICAgICAqLwogICAgICAgIGdldERlZmF1bHRMb2NhbGVQcm9wZXJ0eTogZnVuY3Rpb24gKHByb3BlcnR5KSB7CiAgICAgICAgICAgIHZhciBsb2NhbGVQcm9wcyA9IHJlZ2lzdGVyZWRMb2NhbGVQcm9wZXJ0aWVzIHx8IHRoaXMuZ2V0T3JFbHNlKHhmYWxpYiwgInNjcmlwdC5YZmEuX2RlZmF1bHRMb2NhbGUiLCBudWxsKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JFbHNlKGxvY2FsZVByb3BzLCBwcm9wZXJ0eSwgbnVsbCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogRW5jb2RlcyA8c2NyaXB0PiBhbmQgPC9zY3JpcHQ+IHdpdGggJmx0O3NjcmlwdCZndDsgYW5kICZsdDsvc2NyaXB0Jmd0OwogICAgICAgICAqIERvZXMgc2FtZSB3aXRoIGltZywgdmlkZW8gYW5kIGF1ZGlvIHRhZ3MgYWxzby4KICAgICAgICAgKiBUaGVzZSB0YWdzIGFyZSBiZWluZyByZW1vdmVkIHNpbmNlIHNjcmlwdHMgY2FuIGJlIHJ1biB0aHJvdWdoCiAgICAgICAgICogPGltZyBvbmVycm9yPSJzY3JpcHQiIC8+IChzYW1lIGZvciBhdWRpbyBhbmQgdmlkZW8pLgogICAgICAgICAqLwogICAgICAgIGVuY29kZVNjcmlwdGFibGVUYWdzOiBmdW5jdGlvbiAoc3RyKSB7CiAgICAgICAgICAgIHZhciBpbmRleDsKICAgICAgICAgICAgaWYgKF8uaXNTdHJpbmcoc3RyKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKC88KFwvPykoc2NyaXB0W148Pl0qKT4vZ2ksICcmbHQ7JDEkMiZndDsnKQogICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC88KFwvPykoaW1nW148Pl0qKT4vZ2ksICcmbHQ7JDEkMiZndDsnKQogICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC88KFwvPykodmlkZW9bXjw+XSopPi9naSwgJyZsdDskMSQyJmd0OycpCiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLzwoXC8/KShhdWRpb1tePD5dKik+L2dpLCAnJmx0OyQxJDImZ3Q7JykKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGlkIDogYSBzdHJpbmcgcmVwcmVzZW50aW5nIGFuIEhUTUwgZWxlbWVudCBpZC4KICAgICAgICAgKgogICAgICAgICAqIHJldHVybiBhZnRlciBhcHBseWluZyBhbiBlc2NhcGluZyAnXCcgYmVmb3JlIGVhY2ggIyAuIDogWyBdCiAgICAgICAgICovCiAgICAgICAganFJZDogZnVuY3Rpb24oaWQpIHsKICAgICAgICAgICAgcmV0dXJuICIjIiArIGlkLnJlcGxhY2UoLygjfDp8XC58XFt8XF0pL2csICJcXCQxIik7CiAgICAgICAgfSwKCiAgICAgICAgX3RyaWdnZXJPbkJyaWRnZTogZnVuY3Rpb24gKGV2ZW50TmFtZSwgdGFyZ2V0LCBwcm9wZXJ0eSwgb2xkVmFsLCBuZXdWYWwpIHsKICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoZXZlbnROYW1lLCB0YXJnZXQsCiAgICAgICAgICAgICAgICBwcm9wZXJ0eSwgb2xkVmFsLCBuZXdWYWwpOwogICAgICAgICAgICBpZihmb3JtQnJpZGdlKXsKICAgICAgICAgICAgICAgIHdpbmRvdy5mb3JtQnJpZGdlLnRyaWdnZXIoZXZlbnROYW1lLCBldm50KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogcGFkcyB0aGUgcGFzc2VkIGluIFN0cmluZyBzdHIgYnkgcHJlLXBlbmRpbmcgcGFkQ2hhcnMgdG8gY29udmVydCBpdCB0byBhIHN0cmluZyBvZiBnaXZlbiB3aWR0aC4KICAgICAgICAgKiBJZiBzdHJpbmcgbGVuZ3RoIGlzIGFscmVhZHkgZ3JlYXRlciB0aGF0IGVxdWFsIHRvIGdpdmVuIHdpZHRoLCBvcmlnaW5hbCBzdHJpbmcgaXMgcmV0dXJuZWQuCiAgICAgICAgICovCiAgICAgICAgcGFkU3RyaW5nIDogZnVuY3Rpb24gKHN0ciwgd2lkdGgsIHBhZENoYXIpIHsKICAgICAgICAgICAgcGFkQ2hhciA9IHBhZENoYXIgfHwgJzAnOwogICAgICAgICAgICBzdHIgPSBzdHIgKyAnJzsKICAgICAgICAgICAgcmV0dXJuIHN0ci5sZW5ndGggPj0gd2lkdGggPyBzdHIgOiBuZXcgQXJyYXkod2lkdGggLSBzdHIubGVuZ3RoICsgMSkuam9pbihwYWRDaGFyKSArIHN0cjsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiByZXR1cm5zIHRydWUgaWYgdGhlIGJyb3dzZXIgaXMgSUUgb3RoZXJ3aXNlIGZhbHNlCiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59CiAgICAgICAgICovCiAgICAgICAgaXNJRTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gJC5icm93c2VyLm1zaWUgfHwgKG5hdmlnYXRvci5hcHBOYW1lID09PSAiTmV0c2NhcGUiICYmIG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL1RyaWRlbnRcLy8pKQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIHJldHVybnMgZmFsc2UgaWYgb3RoZXIgYnJvd3NlcgogICAgICAgICAqIGlmIGllIHRyaWVzIHRvIHJldHVybiBicm93c2VyIHZlcnNpb24gKG5vbiBmYWxzeSkKICAgICAgICAgKiBAcmV0dXJucyB7Kn0KICAgICAgICAgKi8KCiAgICAgICAgZGV0ZWN0SUU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgLy8gMXN0IHRyeSBqcQogICAgICAgICAgICBpZigkLmJyb3dzZXIubXNpZSkgewogICAgICAgICAgICAgICAgaWYoJC5icm93c2VyLnZlcnNpb24gJiYgcGFyc2VJbnQoJC5icm93c2VyLnZlcnNpb24sIDEwKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludCgkLmJyb3dzZXIudmVyc2lvbiwgMTApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgdWEgPSB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDsKCiAgICAgICAgICAgIC8vIElFIDEwCiAgICAgICAgICAgIC8vIHVhID0gJ01vemlsbGEvNS4wIChjb21wYXRpYmxlOyBNU0lFIDEwLjA7IFdpbmRvd3MgTlQgNi4yOyBUcmlkZW50LzYuMCknOwoKICAgICAgICAgICAgLy8gSUUgMTEKICAgICAgICAgICAgLy8gdWEgPSAnTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgNi4zOyBUcmlkZW50LzcuMDsgcnY6MTEuMCkgbGlrZSBHZWNrbyc7CgogICAgICAgICAgICAvLyBJRSAxMiAvIFNwYXJ0YW4KICAgICAgICAgICAgLy8gdWEgPSAnTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV09XNjQpIEFwcGxlV2ViS2l0LzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZS8zOS4wLjIxNzEuNzEgU2FmYXJpLzUzNy4zNiBFZGdlLzEyLjAnOwoKICAgICAgICAgICAgLy8gRWRnZSAoSUUgMTIrKQogICAgICAgICAgICAvLyB1YSA9ICdNb3ppbGxhLzUuMCAoV2luZG93cyBOVCAxMC4wOyBXaW42NDsgeDY0KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvNDYuMC4yNDg2LjAgU2FmYXJpLzUzNy4zNiBFZGdlLzEzLjEwNTg2JzsKCiAgICAgICAgICAgIHZhciBtc2llID0gdWEuaW5kZXhPZignTVNJRSAnKTsKICAgICAgICAgICAgaWYgKG1zaWUgPiAwKSB7CiAgICAgICAgICAgICAgICAvLyBJRSAxMCBvciBvbGRlciA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXIKICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh1YS5zdWJzdHJpbmcobXNpZSArIDUsIHVhLmluZGV4T2YoJy4nLCBtc2llKSksIDEwKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHRyaWRlbnQgPSB1YS5pbmRleE9mKCdUcmlkZW50LycpOwogICAgICAgICAgICBpZiAodHJpZGVudCA+IDApIHsKICAgICAgICAgICAgICAgIC8vIElFIDExID0+IHJldHVybiB2ZXJzaW9uIG51bWJlcgogICAgICAgICAgICAgICAgdmFyIHJ2ID0gdWEuaW5kZXhPZigncnY6Jyk7CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodWEuc3Vic3RyaW5nKHJ2ICsgMywgdWEuaW5kZXhPZignLicsIHJ2KSksIDEwKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGVkZ2UgPSB1YS5pbmRleE9mKCdFZGdlLycpOwogICAgICAgICAgICBpZiAoZWRnZSA+IDApIHsKICAgICAgICAgICAgICAgIC8vIEVkZ2UgKElFIDEyKykgPT4gcmV0dXJuIHZlcnNpb24gbnVtYmVyCiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodWEuc3Vic3RyaW5nKGVkZ2UgKyA1LCB1YS5pbmRleE9mKCcuJywgZWRnZSkpLCAxMCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIG90aGVyIGJyb3dzZXIKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCiAgICAgICAgLyoqCiAgICAgICAgICogcmV0dXJucyB0cnVlIGlmIHRoZSBicm93c2VyIGlzIGNocm9tZSBvdGhlcndpc2UgZmFsc2UKICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0KICAgICAgICAgKi8KICAgICAgICBkZXRlY3RDaHJvbWUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAoISF3aW5kb3cuY2hyb21lIHx8ICEhJC5icm93c2VyLmNocm9tZSB8fCAvY2hyb20oZXxpdW0pLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKSkpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHZhbDogdmFsdWUgdG8gYmUgdmVyaWZpZWQKICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufQogICAgICAgICogcmV0dXJucyB0cnVlIGlmIHRoZSBwcm92aWRlZCBzdHJpbmcgY29udGFpbnMgRE9NIGVsZW1lbnQKICAgICAgICAqLwogICAgICAgIGlzSFRNTDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIC8vY2hlY2sgd2hldGhlciBzdHJpbmcgY29udGFpbnMgdGFncywgc28gdGhhdCAkdmFsIGRvZXMgbm90IGNvbnRhaW4gcmVzdWx0IG9mIHRoZSB2YWwgdXNlZCBhcyBzZWxlY3RvcgogICAgICAgICAgICAvLyBlZzogdmFsID0gImEiIHdpbGwgcmV0dXJuIHJlc3VsdCBmb3IgJCh2YWwpIHdoaWNoIGlzIG5vdCByZXF1aXJlZAogICAgICAgICAgICBpZih2YWwgJiYgLzxbYS16XVtcc1xTXSo+Ly50ZXN0KHZhbCkpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgdmFyICR2YWwgPSAkKHZhbCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICR2YWwubGVuZ3RoID4gMDsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgIC8vIGlmIGpxdWVyeSB0aHJvd3MgZXhjZXB0aW9uIHRoYXQgbWVhbnMgc3RyaW5nIGlzIG5vdCBhIHByb3BlciBIVE1MCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogcmV0dXJucyB0cnVlIGlmIHBhc3NlZCBrZXkgaXMgbm9uIHByaW50YWJsZSwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgZXZlbnQua2V5IHByb3BlcnR5IG9mIGEgS2V5Ym9hcmQgZXZlbnQKICAgICAgICAgKi8KICAgICAgICBpc05vblByaW50YWJsZUtleSA6IGZ1bmN0aW9uIChrZXkpIHsKICAgICAgICAgICAgcmV0dXJuIChrZXkgICAvLyBJbiBJRSwgZXZlbnQua2V5IHJldHVybnMgd29yZHMgaW5zdGVhZCBvZiBhY3R1YWwgY2hhcmFjdGVycyBmb3Igc29tZSBrZXlzLgogICAgICAgICAgICAgICAmJiAhXy5jb250YWlucyhbJ01velByaW50YWJsZUtleScsJ0RpdmlkZScsJ011bHRpcGx5JywnU3VidHJhY3QnLCdBZGQnLCdFbnRlcicsJ0RlY2ltYWwnLCdTcGFjZWJhcicsJ0RlbCddLGtleSkKICAgICAgICAgICAgICAgJiYga2V5Lmxlbmd0aCAhPSAxICkKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAqIHJldHVybnMgdHJ1ZSBmb3IgaXBhZAogICAgICAgICogQHJldHVybnMge2Jvb2xlYW59CiAgICAgICAgKi8KICAgICAgICBfaXNJcGFkIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBhZC9pKSAhPSBudWxsOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICogcmV0dXJucyB0cnVlIGlmIHRoZSBzdWJmb3JtIGlzIHRhYmxlIG9yIGhhdmluZyByb2xlIHRhYmxlIGVsc2UgZmFsc2UKICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSB2aWV3CiAgICAgICAgKi8KICAgICAgICBfdGFibGVDaGVja0ZvckFjY2Vzc2liaWxpdHkgOiBmdW5jdGlvbiAodmlldykgewogICAgICAgICAgICB2YXIgYXNzaXN0ID0gdmlldy5tb2RlbC5nZXRFbGVtZW50KCJhc3Npc3QiLCAwLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JFbHNlKHZpZXcsICJsYXlvdXRNb2RlbC5sYXlvdXQiLCBudWxsKSA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfVEFCTEUKICAgICAgICAgICAgICAgIHx8IHRoaXMuZ2V0T3JFbHNlKGFzc2lzdCwgInJvbGUiLCBudWxsKSA9PSAiVGFibGUiOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICogcmV0dXJucyB2YWx1ZSBvZiB0b29sdGlwIHRvIGJlIGFzc2lnbmVkIGFzIHRpdGxlIGJhc2VkIG9uIHZhbHVlcyBwcm92aWRlZCBpbiBhY2Nlc3NpYmlsaXR5CiAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gbW9kZWwKICAgICAgICAqIEByZXR1cm5zIHRvb2xUaXBUZXh0CiAgICAgICAgKi8KICAgICAgICBfZ2V0VG9vbFRpcFRleHQgOiBmdW5jdGlvbiAobW9kZWwpIHsKICAgICAgICAgICAgdmFyIGFzc2lzdCA9IG1vZGVsLmdldEVsZW1lbnQoImFzc2lzdCIsIDAsIHRydWUpLAogICAgICAgICAgICAgICAgdG9vbFRpcFRleHQgPSAiIjsKICAgICAgICAgICAgLy8gZ29pbmcgYWdhaW5zdCB4ZmEgc3BlYywgb24gaG92ZXIgc2hvdyB0b29sdGlwIG9yIHNwZWFrIHRleHQgb3IgZWxlbWVudCBuYW1lLCBkb24ndCBzaG93IGNhcHRpb24gYXMgaXQncyBhbHJlYWR5IHZpc2libGUKICAgICAgICAgICAgLy8gYXNzaXN0IHByaW9yaXR5IGRvZXNuJ3QgbWF0dGVyLCBidXQgc2VsZWN0aW5nIG5vbmUgd2lsbCBkaXNhYmxlIHRvb2x0aXAgb24gaG92ZXIKICAgICAgICAgICAgaWYgKHRoaXMuZ2V0T3JFbHNlKGFzc2lzdCwgInNwZWFrLmRpc2FibGUiLCAwKSAhPSAxKSB7IC8vIGxvb3NlIGNvbXBhcmUgc3RyaW5nIHZhbHVlCiAgICAgICAgICAgICAgICB0b29sVGlwVGV4dCA9IHRoaXMuZ2V0T3JFbHNlKGFzc2lzdCwgInRvb2xUaXAudmFsdWUiLCAiIikgfHwKICAgICAgICAgICAgICAgICAgICB0aGlzLmdldE9yRWxzZShhc3Npc3QsICJzcGVhay52YWx1ZSIsICIiKSAgIHx8CiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRPckVsc2UobW9kZWwsICJqc29uTW9kZWwubmFtZSIsICIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdG9vbFRpcFRleHQ7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgKiByZXR1cm5zIHZhbHVlIG9mIG1hbmRhdG9yeSBtZXNzYWdlCiAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gbW9kZWwKICAgICAgICAqIEByZXR1cm5zIG1hbmRhdG9yeU1lc3NhZ2UKICAgICAgICAqLwogICAgICAgIF9nZXRNYW5kYXRvcnlNZXNzYWdlIDogZnVuY3Rpb24gKG1vZGVsKSB7CiAgICAgICAgICAgIHZhciBkZWZhdWx0TWVzc2FnZSA9IG1vZGVsLl9kZWZhdWx0cy52YWxpZGF0ZS5tZXNzYWdlLmRlZmF1bHRNZXNzYWdlLAogICAgICAgICAgICAgICAgbXNnID0gdGhpcy5nZXRPckVsc2UobW9kZWwsICJ2YWxpZGF0ZS5tZXNzYWdlLm51bGxUZXN0IiwgZGVmYXVsdE1lc3NhZ2UpOwogICAgICAgICAgICByZXR1cm4gKG1zZyAmJiBtc2cudmFsdWUpID8gbXNnLnZhbHVlIDogZGVmYXVsdE1lc3NhZ2UudmFsdWU7CiAgICAgICAgfSwKICAgICAgICAvKioKICAgICAgICAqIHJldHVybnMgYm9vbGVhbiBiYXNlZCBvbiB2YWwxLCB2YWwyLCBjaGVja0VxdWFsCiAgICAgICAgKiBGb3IgY29tcGFyaW5nIGRhdGUsIHVzZSBkYXRlIG9iamVjdAogICAgICAgICovCiAgICAgICAgX2NvbXBhcmVWYWwgOiBmdW5jdGlvbiAodmFsMSwgdmFsMiwgY2hlY2tFcXVhbCkgewogICAgICAgICAgICBpZighdmFsMSB8fCAhdmFsMikgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihjaGVja0VxdWFsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdmFsMSA+PSB2YWwyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHZhbDEgPiB2YWwyOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgLy9TcGVjaWFsIGhhbmRsaW5nIGZvciBJRS4KICAgIGlmICgkLmJyb3dzZXIubXNpZSB8fCAkLmJyb3dzZXIubW96aWxsYSkgewogICAgICAgIFhmYVV0aWwucHJvdG90eXBlLiRjc3MgPSBmdW5jdGlvbiAoZWxlbSwgc3R5bGVzT2JqKSB7CiAgICAgICAgICAgICQoZWxlbSkuY3NzKHN0eWxlc09iaik7CiAgICAgICAgfQogICAgfQp9KShfLCAkLCB4ZmFsaWIpOwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogX19fX19fX19fX19fX19fX19fXwogKgogKiAgQ29weXJpZ2h0IDIwMTMgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKKGZ1bmN0aW9uIChfLCAkLCB4ZmFsaWIpIHsKICAgIHhmYWxpYi51dC5VdGlsaXRpZXMgPSB7CgogICAgICAgIGlzSUUxMTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gISFuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9UcmlkZW50Lipydlw6MTFcLi8pOwogICAgICAgIH0sCgogICAgICAgIGNoZWNrTWluTW96aWxsYVZlcnNpb246IGZ1bmN0aW9uICh2ZXJzaW9uKSB7CiAgICAgICAgICAgIHJldHVybiAoIXRoaXMuaXNJRTExKCkgJiYgJC5icm93c2VyLm1vemlsbGEgJiYgcGFyc2VJbnQoJC5icm93c2VyLnZlcnNpb24pID49IHZlcnNpb24pOwogICAgICAgIH0sCgogICAgICAgIGdldE9iamVjdEZyb21LZXlWYWx1ZVN0cmluZ0xpc3Q6IGZ1bmN0aW9uIChsaXN0KSB7CiAgICAgICAgICAgIHZhciBrZXksIHZhbHVlLCBvYmplY3QgPSB7fSwgdGVtcEFycmF5OwogICAgICAgICAgICBfLmVhY2gobGlzdCwgZnVuY3Rpb24gKGtleVZhbHVlUGFpciwgaW5kZXgpIHsKICAgICAgICAgICAgICAgIHRlbXBBcnJheSA9IGtleVZhbHVlUGFpci5zcGxpdCgiPSIpOwogICAgICAgICAgICAgICAgaWYgKHRlbXBBcnJheSAmJiB0ZW1wQXJyYXkubGVuZ3RoID4gMSkgewogICAgICAgICAgICAgICAgICAgIG9iamVjdFt0ZW1wQXJyYXlbMF1dID0gdGVtcEFycmF5WzFdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgcmV0dXJuIG9iamVjdDsKICAgICAgICB9LAoKICAgICAgICBfZ2V0TmFtZVdpdGhvdXRNYXJrZXI6IGZ1bmN0aW9uIChmaWxlTmFtZSkgewogICAgICAgICAgICB2YXIgbWFya2VySW5kZXggPSBmaWxlTmFtZS5pbmRleE9mKCJfX2FmQXR0YWNobWVudF9fIik7CiAgICAgICAgICAgIGlmIChtYXJrZXJJbmRleCAhPT0gLTEpIHsKICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gZmlsZU5hbWUuc3Vic3RyaW5nKG1hcmtlckluZGV4ICsgIl9fYWZBdHRhY2htZW50X18iLmxlbmd0aCwgZmlsZU5hbWUubGVuZ3RoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmlsZU5hbWU7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBUaGlzIGlzIHRvIGNoZWNrIHN1cHBvcnQgb2YgbXVsdGlwbGUgZmlsZXMgc2VsZWN0aW9uIGluIG9uZSBhZGQgbmV3IGRpYWxvZwogICAgICAgICAqLwogICAgICAgIF9pc0RhdGFDb250YWluZXJTdXBwb3J0ZWQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB2YXIgZGF0YUNvbnRhaW5lciA9IG5ldyBEYXRhVHJhbnNmZXIoKSB8fCAobmV3IENsaXBib2FyZEV2ZW50KCIiKSkuY2xpcGJvYXJkRGF0YTsKICAgICAgICAgICAgICAgIGlmIChkYXRhQ29udGFpbmVyICYmIGRhdGFDb250YWluZXIuaXRlbXMpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaChlcnIpIHsKICAgICAgICAgICAgICAgIC8vIGlmIGVyciBjb21lcyB0aGVuIGRhdGFDb250YWluZXIgaXMgbm90IHN1cHBvcnRlZAogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Owp9KShfLCAkLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlNjYW5uZXIKICogQGZpbGVPdmVydmlldyBoZWxwZXIgY2xhc3MgdG8gc2NhbiBvdmVyIGEgc3RyaW5nLgogKiBAdmVyc2lvbiAwLjAuMQogKi8KCi8qKgogKiBAY29uc3RydWN0b3IKICogQHBhcmFtIE9iamVjdCB7anNvbk1vZGVsOntfc3RyOiBTdHJpbmd9fQogKi8KCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgU2Nhbm5lciA9IHhmYWxpYi51dC5TY2FubmVyID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB0aGlzLl9wb3MgPSAwOwogICAgICAgIH0sCgogICAgICAgIGlzRU9GIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuICh0aGlzLmpzb25Nb2RlbC5fc3RyLmxlbmd0aCA8PSB0aGlzLl9wb3MpOwogICAgICAgIH0sCgogICAgICAgIHBlZWsgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gKHRoaXMuaXNFT0YoKSkgPyBudWxsIDogdGhpcy5qc29uTW9kZWwuX3N0ci5jaGFyQXQodGhpcy5fcG9zKTsKICAgICAgICB9LAoKICAgICAgICBvcHRpb25hbENvbnN1bWVDaGFyIDogZnVuY3Rpb24oYUNoYXIpewogICAgICAgICAgICBpZih0aGlzLmpzb25Nb2RlbC5fc3RyLmNoYXJBdCh0aGlzLl9wb3MpID09IGFDaGFyKXsKICAgICAgICAgICAgICAgIHRoaXMuX3BvcysrOwogICAgICAgICAgICAgICAgcmV0dXJuIGFDaGFyOwogICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0cyBuZXh0IGNoYXIgaWdub3JlIHF1b3RlZCBzdHJpbmcuCiAgICAgICAgICogICAgfAogICAgICAgICAqICAgYWJjIHJldHVybnMgYy4KICAgICAgICAgKiAgICAgfAogICAgICAgICAqICAgYWJjJ2RlJ2YgcmV0dXJucyBmLgogICAgICAgICAqIEBwYXJhbSBhQ2hhcgogICAgICAgICAqLwogICAgICAgIGdldE5DaGFySVFTIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdGhpcy5fcG9zKys7CiAgICAgICAgICAgIGlmKHRoaXMuanNvbk1vZGVsLl9zdHIubGVuZ3RoIDw9IHRoaXMuX3Bvcyl7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudCA9IHRoaXMuanNvbk1vZGVsLl9zdHIuY2hhckF0KHRoaXMuX3Bvcyk7CiAgICAgICAgICAgICAgICBpZihjdXJyZW50ICE9ICdcJycpewogICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50OwogICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgaWYobW92ZU5leHRFeHBlY3RlZENoYXIoJ1wnJykpewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwuX3N0ci5jaGFyQXQodGhpcy5fcG9zKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgbW92ZU5leHRFeHBlY3RlZENoYXIgOiBmdW5jdGlvbihhQ2hhcil7CiAgICAgICAgICAgIHRoaXMuX3BvcysrOy8vIGN1cnJlbnRseSBwb2ludCB0byAnCiAgICAgICAgICAgIHdoaWxlKHRoaXMuX3BvczwgdGhpcy5qc29uTW9kZWwuX3N0ci5sZW5ndGggJiYgdGhpcy5qc29uTW9kZWwuX3N0ci5jaGFyQXQodGhpcy5fcG9zKSAhPSBhQ2hhcil7CiAgICAgICAgICAgICAgICB0aGlzLl9wb3MrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdGhpcy5fcG9zIDwgdGhpcy5qc29uTW9kZWwuX3N0ci5sZW5ndGg7CiAgICAgICAgfSwKCiAgICAgICAgcmVhZEludGVnZXIgOiBmdW5jdGlvbihsZW4pewogICAgICAgICAgICBpZih0aGlzLnBvcytsZW4gPnRoaXMuanNvbk1vZGVsLl9zdHIubGVuZ3RoKXsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBpbnRlZ2VyID0geGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYXJzZUludEV4YWN0KHRoaXMuanNvbk1vZGVsLl9zdHIsdGhpcy5fcG9zLGxlbik7CiAgICAgICAgICAgIHRoaXMuX3Bvcys9bGVuOwogICAgICAgICAgICByZXR1cm4gaW50ZWdlcjsKICAgICAgICB9CiAgICB9KTsKCiAgICBTY2FubmVyLmxvb2t1cE5leHQgPSBmdW5jdGlvbihwYXQsIHBhdFBvcywgZmlsdGVyKXsKICAgICAgICB2YXIgcGF0TGVuID0gcGF0Lmxlbmd0aDsKICAgICAgICBpZihwYXRQb3MgPj0gcGF0TGVuKXsKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfQoKICAgICAgICB2YXIgdG9rZW4gPSB7fTsKICAgICAgICB0b2tlbi5zdGFydFBvcyA9IHBhdFBvczsKCiAgICAgICAgdmFyIGZpcnN0Q2hhciA9IHBhdC5jaGFyQXQocGF0UG9zKTsKICAgICAgICB2YXIgcGF0VmFsaWQgPSBmYWxzZTsKICAgICAgICAvLwogICAgICAgIGlmIChmaXJzdENoYXIgPT0gJ1wnJyl7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSBwYXRQb3MrMTsgaSA8IHBhdExlbjtpKysgKXsKICAgICAgICAgICAgICAgIHZhciBjaHIgPSBwYXQuY2hhckF0KGkpOwogICAgICAgICAgICAgICAgaWYoY2hyID09J1wnJyl7CiAgICAgICAgICAgICAgICAgICAgdG9rZW4udHlwZT0xOwogICAgICAgICAgICAgICAgICAgIHRva2VuLmxlbiA9IGkgLSBwYXRQb3MgKyAxOwogICAgICAgICAgICAgICAgICAgIHBhdFZhbGlkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICB9ZWxzZSBpZiggKCdhJyA8PSBmaXJzdENoYXIgJiYgZmlyc3RDaGFyIDw9ICd6JyB8fCAnQScgPD0gZmlyc3RDaGFyICYmIGZpcnN0Q2hhciA8PSAnWicpIHx8IGZpbHRlci5jYWxsKG51bGwsIGZpcnN0Q2hhcikpewogICAgICAgICAgICB2YXIgZW5kUG9zID0gcGF0TGVuOy8vZW5kIGlzIGV4Y2x1c2l2ZQogICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgcGF0UG9zK2kgPCBwYXRMZW47aSsrICl7CiAgICAgICAgICAgICAgICBpZihwYXQuY2hhckF0KHBhdFBvcytpKSE9Zmlyc3RDaGFyKXsKICAgICAgICAgICAgICAgICAgICBlbmRQb3MgPSBwYXRQb3MraTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0b2tlbi50eXBlPTI7CiAgICAgICAgICAgIHRva2VuLmxlbiA9IGVuZFBvcyAtIHBhdFBvczsKICAgICAgICAgICAgdG9rZW4ucGF0Q2hhciA9IGZpcnN0Q2hhcjsKICAgICAgICAgICAgdG9rZW4ucGF0UG9zID0gcGF0UG9zOwogICAgICAgICAgICBwYXRWYWxpZCA9IHRydWU7CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIGlmIChmaXJzdENoYXIgPT0gJz8nIHx8IGZpcnN0Q2hhciA9PSAnKycgfHwgZmlyc3RDaGFyID09ICcqJykgewogICAgICAgICAgICAgICAgdG9rZW4udHlwZT0zOwogICAgICAgICAgICAgICAgdG9rZW4ubGVuID0gMTsKICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICB0b2tlbi50eXBlPTQ7CiAgICAgICAgICAgICAgICB0b2tlbi5sZW4gPSAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHBhdFZhbGlkID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYocGF0VmFsaWQpewogICAgICAgICAgICByZXR1cm4gdG9rZW47CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIHRocm93ICJQaWN0dXJlIGlzIGludmFsaWQuIjsKICAgICAgICB9CiAgICB9Cn0pKF8seGZhbGliKTsKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlBpY3R1cmVGbXQKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBkZWZpbmVzIG1ldGhvZHMgdG8gcGFyc2UgYW5kIGZvcm1hdCBkYXRhCiAqIGFjY29yZGluZyB0byBYRkEgcGljdHVyZSBwYXR0ZXJucy4KICogQHZlcnNpb24gMC4wLjEKICovCihmdW5jdGlvbihfLHhmYWxpYikgewoKICAgIHZhciBQaWN0dXJlRm10ID0geGZhbGliLnV0LlBpY3R1cmVGbXQgPSBmdW5jdGlvbigpIHt9OwogICAgUGljdHVyZUZtdC5EYXRlUGljdHVyZVBhdHRlcm4gPSAgL15kYXRlKD86XChbYS16QS1aXSpfW2EtekEtWl0qXCkpP1x7KFtcd1xXXSo/KVx9JC87CiAgICBQaWN0dXJlRm10LlRpbWVQaWN0dXJlUGF0dGVybiA9ICAvXnRpbWUoPzpcKFthLXpBLVpdKl9bYS16QS1aXSpcKSk/XHsoW1x3XFddKj8pXH0kLzsKICAgIFBpY3R1cmVGbXQuVGV4dFBpY3R1cmVQYXR0ZXJuID0gIC9edGV4dFx7KFtcd1xXXSo/KVx9JC87CiAgICBQaWN0dXJlRm10Lk51bVBpY3R1cmVQYXR0ZXJuID0gIC9ebnVtXHsoW1x3XFddKj8pXH0kLzsKCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGdpdmVuIGRhdGEgc291cmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gcGljdHVyZS4KICAgICAqIEBwYXJhbSBzU291cmNlIHtzdHJpbmd9CiAgICAgKiBAcGFyYW0gc1BpY3R1cmUge3N0cmluZ30KICAgICAqIEBwYXJhbSBzTG9jYWxlIHtzdHJpbmd9CiAgICAgKiBAcmV0dXJucyB7b2JqZWN0fQogICAgICovCiAgICBQaWN0dXJlRm10LnBhcnNlICA9IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLHNMb2NhbGUpewogICAgICAgIHZhciBQaWN0dXJlRW5naW5lID0gbmV3IHhmYWxpYi51dC5QaWN0dXJlRW5naW5lKHtqc29uTW9kZWw6e2xvY2FsZTpzTG9jYWxlfX0pOwoKICAgICAgICB2YXIgbWF0Y2ggPSBQaWN0dXJlRm10LkRhdGVQaWN0dXJlUGF0dGVybi5leGVjKHNQaWN0dXJlKTsKICAgICAgICBpZihtYXRjaCAmJiBtYXRjaFsxXSl7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLnBhcnNlRGF0ZShzU291cmNlLCBtYXRjaFsxXSk7CiAgICAgICAgfQogICAgICAgIG1hdGNoID0gUGljdHVyZUZtdC5UaW1lUGljdHVyZVBhdHRlcm4uZXhlYyhzUGljdHVyZSk7CiAgICAgICAgaWYobWF0Y2ggJiYgbWF0Y2hbMV0pewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5wYXJzZVRpbWUoc1NvdXJjZSwgbWF0Y2hbMV0pOwogICAgICAgIH0KICAgICAgICBtYXRjaCA9IFBpY3R1cmVGbXQuVGV4dFBpY3R1cmVQYXR0ZXJuLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUucGFyc2VUZXh0KHNTb3VyY2UsIG1hdGNoWzFdKTsKICAgICAgICB9CiAgICAgICAgbWF0Y2ggPSBQaWN0dXJlRm10Lk51bVBpY3R1cmVQYXR0ZXJuLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUucGFyc2VOdW1lcmljKHNTb3VyY2UsIG1hdGNoWzFdKTsKICAgICAgICB9CiAgICAgICAgdGhyb3cgIkludmFsaWQgcGljdHVyZSBjbGF1c2UgIitzUGljdHVyZTsKICAgIH07CgogICAgLyoqCiAgICAgKiBGb3JtYXRzIGEgZ2l2ZW4gZGF0YSBzb3VyY2UgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBwaWN0dXJlLgogICAgICogQHBhcmFtIGRhdGUge29iamVjdH0KICAgICAqIEBwYXJhbSBzUGljdHVyZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNMb2NhbGUge3N0cmluZ30KICAgICAqIEByZXR1cm5zIHtzdHJpbmd9CiAgICAgKi8KICAgIFBpY3R1cmVGbXQuZm9ybWF0ICA9IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLCBzTG9jYWxlLGJSZWxheGVkLGJGb3JtYXROdW1iZXJGcm9tYXNEZWZhdWx0UEMpewogICAgICAgIHZhciBQaWN0dXJlRW5naW5lID0gbmV3IHhmYWxpYi51dC5QaWN0dXJlRW5naW5lKHtqc29uTW9kZWw6e2xvY2FsZTpzTG9jYWxlfX0pOwoKICAgICAgICB2YXIgbWF0Y2ggPSBQaWN0dXJlRm10LkRhdGVQaWN0dXJlUGF0dGVybi5leGVjKHNQaWN0dXJlKTsKICAgICAgICBpZihtYXRjaCAmJiBtYXRjaFsxXSl7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLmZvcm1hdERhdGUoc1NvdXJjZSwgbWF0Y2hbMV0pOwogICAgICAgIH0KICAgICAgICBtYXRjaCA9IFBpY3R1cmVGbXQuVGltZVBpY3R1cmVQYXR0ZXJuLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUuZm9ybWF0VGltZShzU291cmNlLCBtYXRjaFsxXSk7CiAgICAgICAgfQogICAgICAgIG1hdGNoID0gUGljdHVyZUZtdC5UZXh0UGljdHVyZVBhdHRlcm4uZXhlYyhzUGljdHVyZSk7CiAgICAgICAgaWYobWF0Y2ggJiYgbWF0Y2hbMV0pewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5mb3JtYXRUZXh0KHNTb3VyY2UsIG1hdGNoWzFdLGJSZWxheGVkKTsKICAgICAgICB9CiAgICAgICAgbWF0Y2ggPSBQaWN0dXJlRm10Lk51bVBpY3R1cmVQYXR0ZXJuLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUuZm9ybWF0TnVtZXJpYyhzU291cmNlLCBtYXRjaFsxXSxzTG9jYWxlLGJSZWxheGVkLGJGb3JtYXROdW1iZXJGcm9tYXNEZWZhdWx0UEMpOwogICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgIkludmFsaWQgcGljdHVyZSBjbGF1c2UgIitzUGljdHVyZTsKICAgIH07CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgYSBnaXZlbiBkYXRhIHNvdXJjZSBpcyBmb3JtYXR0ZWQgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBwaWN0dXJlLgogICAgICogQHBhcmFtIGRhdGUge29iamVjdH0KICAgICAqIEBwYXJhbSBzUGljdHVyZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNMb2NhbGUge3N0cmluZ30KICAgICAqIEByZXR1cm5zIHtib29sZWFufQogICAgICovCiAgICBQaWN0dXJlRm10LmZvcm1hdFRlc3QgPSBmdW5jdGlvbiAoc1NvdXJjZSwgc1BpY3R1cmUsIHNMb2NhbGUsIGJSZWxheGVkLCBiRm9ybWF0TnVtYmVyRnJvbWFzRGVmYXVsdFBDKSB7CiAgICAgICAgdmFyIGZvcm1hdHRlZERhdGE7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgZm9ybWF0dGVkRGF0YSA9IFBpY3R1cmVGbXQuZm9ybWF0KHNTb3VyY2UsIHNQaWN0dXJlLCBzTG9jYWxlLCBiUmVsYXhlZCwgYkZvcm1hdE51bWJlckZyb21hc0RlZmF1bHRQQyk7CiAgICAgICAgfWNhdGNoKGUpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgaWYoIV8uaXNTdHJpbmcoZm9ybWF0dGVkRGF0YSkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHZhciBwYXJzZWREYXRhOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcGFyc2VkRGF0YSA9IFBpY3R1cmVGbXQucGFyc2UoZm9ybWF0dGVkRGF0YSwgc1BpY3R1cmUsIHNMb2NhbGUpOwogICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoIV8uaXNTdHJpbmcocGFyc2VkRGF0YSkgJiYgcGFyc2VkRGF0YSAhPT0gZm9ybWF0dGVkRGF0YSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgfTsKCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGdpdmVuIGRhdGEgc291cmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gZGF0ZSBwaWN0dXJlCiAgICAgKiB1bmRlciB0aGUgZ2l2ZW4gc0xvY2FsZS4KICAgICAqIEBwYXJhbSBzU291cmNlIHtzdHJpbmd9CiAgICAgKiBAcGFyYW0gc1BpY3R1cmUge3N0cmluZ30KICAgICAqIEBwYXJhbSBzTG9jYWxlIHtzdHJpbmd9CiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfQogICAgICovCiAgICBQaWN0dXJlRm10LnBhcnNlRGF0ZSAgPSBmdW5jdGlvbihzU291cmNlLCBzUGljdHVyZSxzTG9jYWxlKXsKICAgICAgICB2YXIgcGljUmVnZXhwID0gUGljdHVyZUZtdC5EYXRlUGljdHVyZVBhdHRlcm47CiAgICAgICAgdmFyIG1hdGNoID0gcGljUmVnZXhwLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIHZhciBQaWN0dXJlRW5naW5lID0gbmV3IHhmYWxpYi51dC5QaWN0dXJlRW5naW5lKHtqc29uTW9kZWw6e2xvY2FsZTpzTG9jYWxlfX0pOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUucGFyc2VEYXRlKHNTb3VyY2UsIG1hdGNoWzFdKTsKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUucGFyc2VEYXRlKHNTb3VyY2UsIHNQaWN0dXJlKTsKICAgICAgICB9CiAgICB9OwoKCiAgICAvKioKICAgICAqIEZvcm1hdHMgYSBnaXZlbiBkYXRhIHNvdXJjZSBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIGRhdGUgcGljdHVyZQogICAgICogKiB1bmRlciB0aGUgZ2l2ZW4gc0xvY2FsZS4KICAgICAqIEBwYXJhbSBkYXRlIHtzdHJpbmd9CiAgICAgKiBAcGFyYW0gc1BpY3R1cmUge3N0cmluZ30KICAgICAqIEBwYXJhbSBzTG9jYWxlIHtzdHJpbmd9CiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfQogICAgICovCiAgICBQaWN0dXJlRm10LmZvcm1hdERhdGUgID0gZnVuY3Rpb24oZGF0ZSwgc1BpY3R1cmUsIHNMb2NhbGUpewogICAgICAgIHZhciBwaWNSZWdleHAgPSAgUGljdHVyZUZtdC5EYXRlUGljdHVyZVBhdHRlcm47CiAgICAgICAgdmFyIG1hdGNoID0gcGljUmVnZXhwLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIHZhciBQaWN0dXJlRW5naW5lID0gbmV3IHhmYWxpYi51dC5QaWN0dXJlRW5naW5lKHtqc29uTW9kZWw6e2xvY2FsZTpzTG9jYWxlfX0pOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUuZm9ybWF0RGF0ZShkYXRlLCBtYXRjaFsxXSk7CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLmZvcm1hdERhdGUoZGF0ZSwgc1BpY3R1cmUpOwogICAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBQYXJzZXMgYSBnaXZlbiBkYXRhIHNvdXJjZSBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIGRhdGUgcGljdHVyZQogICAgICogdW5kZXIgdGhlIGdpdmVuIHNMb2NhbGUuCiAgICAgKiBAcGFyYW0gc1NvdXJjZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNQaWN0dXJlIHtzdHJpbmd9CiAgICAgKiBAcGFyYW0gc0xvY2FsZSB7c3RyaW5nfQogICAgICogQHJldHVybnMge2RhdGV9CiAgICAgKi8KICAgIFBpY3R1cmVGbXQucGFyc2VUaW1lICA9IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLHNMb2NhbGUpewogICAgICAgIHZhciBwaWNSZWdleHAgPSBQaWN0dXJlRm10LlRpbWVQaWN0dXJlUGF0dGVybjsKICAgICAgICB2YXIgbWF0Y2ggPSBwaWNSZWdleHAuZXhlYyhzUGljdHVyZSk7CiAgICAgICAgdmFyIFBpY3R1cmVFbmdpbmUgPSBuZXcgeGZhbGliLnV0LlBpY3R1cmVFbmdpbmUoe2pzb25Nb2RlbDp7bG9jYWxlOnNMb2NhbGV9fSk7CiAgICAgICAgaWYobWF0Y2ggJiYgbWF0Y2hbMV0pewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5wYXJzZVRpbWUoc1NvdXJjZSwgbWF0Y2hbMV0pOwogICAgICAgIH1lbHNlewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5wYXJzZVRpbWUoc1NvdXJjZSwgc1BpY3R1cmUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH07CgoKICAgIC8qKgogICAgICogRm9ybWF0cyBhIGdpdmVuIGRhdGEgc291cmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gZGF0ZSBwaWN0dXJlCiAgICAgKiAqIHVuZGVyIHRoZSBnaXZlbiBzTG9jYWxlLgogICAgICogQHBhcmFtIGRhdGUge3N0cmluZ30KICAgICAqIEBwYXJhbSBzUGljdHVyZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNMb2NhbGUge3N0cmluZ30KICAgICAqIEByZXR1cm5zIHtzdHJpbmd9CiAgICAgKi8KICAgIFBpY3R1cmVGbXQuZm9ybWF0VGltZSAgPSBmdW5jdGlvbihkYXRlLCBzUGljdHVyZSwgc0xvY2FsZSl7CiAgICAgICAgdmFyIHBpY1JlZ2V4cCA9ICBQaWN0dXJlRm10LlRpbWVQaWN0dXJlUGF0dGVybjsKICAgICAgICB2YXIgbWF0Y2ggPSBwaWNSZWdleHAuZXhlYyhzUGljdHVyZSk7CiAgICAgICAgdmFyIFBpY3R1cmVFbmdpbmUgPSBuZXcgeGZhbGliLnV0LlBpY3R1cmVFbmdpbmUoe2pzb25Nb2RlbDp7bG9jYWxlOnNMb2NhbGV9fSk7CiAgICAgICAgaWYobWF0Y2ggJiYgbWF0Y2hbMV0pewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5mb3JtYXRUaW1lKGRhdGUsIG1hdGNoWzFdKTsKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUuZm9ybWF0VGltZShkYXRlLCBzUGljdHVyZSk7CiAgICAgICAgfQogICAgfTsKCiAgICAvKioKICAgICAqIFBhcnNlcyBhIGdpdmVuIGRhdGEgc291cmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gdGV4dCBwaWN0dXJlCiAgICAgKiB1bmRlciB0aGUgZ2l2ZW4gc0xvY2FsZS4KICAgICAqIEBwYXJhbSBzU291cmNlIHtzdHJpbmd9CiAgICAgKiBAcGFyYW0gc1BpY3R1cmUge3N0cmluZ30KICAgICAqIEBwYXJhbSBzTG9jYWxlIHtzdHJpbmd9CiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfQogICAgICovCiAgICBQaWN0dXJlRm10LnBhcnNlVGV4dCAgPSBmdW5jdGlvbihzU291cmNlLCBzUGljdHVyZSxzTG9jYWxlKXsKICAgICAgICB2YXIgcGljUmVnZXhwID0gUGljdHVyZUZtdC5UZXh0UGljdHVyZVBhdHRlcm47CiAgICAgICAgdmFyIG1hdGNoID0gcGljUmVnZXhwLmV4ZWMoc1BpY3R1cmUpOwogICAgICAgIHZhciBQaWN0dXJlRW5naW5lID0gbmV3IHhmYWxpYi51dC5QaWN0dXJlRW5naW5lKHtqc29uTW9kZWw6e2xvY2FsZTpzTG9jYWxlfX0pOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoWzFdKXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUucGFyc2VUZXh0KHNTb3VyY2UsIG1hdGNoWzFdKTsKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgcmV0dXJuIFBpY3R1cmVFbmdpbmUucGFyc2VUZXh0KHNTb3VyY2UsIHNQaWN0dXJlKTsKICAgICAgICB9CiAgICB9OwoKICAgIC8qKgogICAgICogRm9ybWF0cyBhIGdpdmVuIGRhdGEgc291cmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gdGV4dCBwaWN0dXJlCiAgICAgKiAgdW5kZXIgdGhlIGdpdmVuIHNMb2NhbGUuCiAgICAgKiBAcGFyYW0gc1NvdXJjZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNQaWN0dXJlIHtzdHJpbmd9CiAgICAgKiBAcGFyYW0gc0xvY2FsZSB7c3RyaW5nfQogICAgICogQHJldHVybnMge3N0cmluZ30KICAgICAqLwogICAgUGljdHVyZUZtdC5mb3JtYXRUZXh0ICA9IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLCBzTG9jYWxlLGJSZWxheGVkKXsKICAgICAgICB2YXIgcGljUmVnZXhwID0gIFBpY3R1cmVGbXQuVGV4dFBpY3R1cmVQYXR0ZXJuOwogICAgICAgIHZhciBtYXRjaCA9IHBpY1JlZ2V4cC5leGVjKHNQaWN0dXJlKTsKICAgICAgICB2YXIgUGljdHVyZUVuZ2luZSA9IG5ldyB4ZmFsaWIudXQuUGljdHVyZUVuZ2luZSh7anNvbk1vZGVsOntsb2NhbGU6c0xvY2FsZX19KTsKICAgICAgICBpZihtYXRjaCAmJiBtYXRjaFsxXSl7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLmZvcm1hdFRleHQoc1NvdXJjZSwgbWF0Y2hbMV0sYlJlbGF4ZWQpOwogICAgICAgIH1lbHNlewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5mb3JtYXRUZXh0KHNTb3VyY2UsIHNQaWN0dXJlLGJSZWxheGVkKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9OwoKICAgIC8qKgogICAgICogUGFyc2VzIGEgZ2l2ZW4gZGF0YSBzb3VyY2UgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBudW1lcmljIHBpY3R1cmUKICAgICAqIHVuZGVyIHRoZSBnaXZlbiBzTG9jYWxlLgogICAgICogQHBhcmFtIHNTb3VyY2Uge3N0cmluZ30KICAgICAqIEBwYXJhbSBzUGljdHVyZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNMb2NhbGUge3N0cmluZ30KICAgICAqIEByZXR1cm5zIHtzdHJpbmd9CiAgICAgKi8KICAgIFBpY3R1cmVGbXQucGFyc2VOdW1lcmljICA9IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLHNMb2NhbGUpewogICAgICAgIHZhciBwaWNSZWdleHAgPSBQaWN0dXJlRm10Lk51bVBpY3R1cmVQYXR0ZXJuOwogICAgICAgIHZhciBtYXRjaCA9IHBpY1JlZ2V4cC5leGVjKHNQaWN0dXJlKTsKICAgICAgICB2YXIgUGljdHVyZUVuZ2luZSA9IG5ldyB4ZmFsaWIudXQuUGljdHVyZUVuZ2luZSh7anNvbk1vZGVsOntsb2NhbGU6c0xvY2FsZX19KTsKICAgICAgICBpZihtYXRjaCAmJiBtYXRjaFsxXSl7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLnBhcnNlTnVtZXJpYyhzU291cmNlLCBtYXRjaFsxXSk7CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLnBhcnNlTnVtZXJpYyhzU291cmNlLCBzUGljdHVyZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfTsKCiAgICAvKioKICAgICAqIEZvcm1hdHMgYSBnaXZlbiBkYXRhIHNvdXJjZSBhY2NvcmRpbmcgdG8gdGhlIGdpdmVuIG51bWVyaWMgcGljdHVyZQogICAgICogIHVuZGVyIHRoZSBnaXZlbiBzTG9jYWxlLgogICAgICogQHBhcmFtIHNTb3VyY2Uge3N0cmluZ30KICAgICAqIEBwYXJhbSBzUGljdHVyZSB7c3RyaW5nfQogICAgICogQHBhcmFtIHNMb2NhbGUge3N0cmluZ30KICAgICAqIEByZXR1cm5zIHtzdHJpbmd9CiAgICAgKi8KICAgIFBpY3R1cmVGbXQuZm9ybWF0TnVtZXJpYyAgPSBmdW5jdGlvbihzU291cmNlLCBzUGljdHVyZSwgc0xvY2FsZSl7CiAgICAgICAgdmFyIHBpY1JlZ2V4cCA9ICBQaWN0dXJlRm10Lk51bVBpY3R1cmVQYXR0ZXJuOwogICAgICAgIHZhciBtYXRjaCA9IHBpY1JlZ2V4cC5leGVjKHNQaWN0dXJlKTsKICAgICAgICB2YXIgUGljdHVyZUVuZ2luZSA9IG5ldyB4ZmFsaWIudXQuUGljdHVyZUVuZ2luZSh7anNvbk1vZGVsOntsb2NhbGU6c0xvY2FsZX19KTsKICAgICAgICBpZihtYXRjaCAmJiBtYXRjaFsxXSl7CiAgICAgICAgICAgIHJldHVybiBQaWN0dXJlRW5naW5lLmZvcm1hdE51bWVyaWMoc1NvdXJjZSwgbWF0Y2hbMV0pOwogICAgICAgIH1lbHNlewogICAgICAgICAgICByZXR1cm4gUGljdHVyZUVuZ2luZS5mb3JtYXROdW1lcmljKHNTb3VyY2UsIHNQaWN0dXJlKTsKICAgICAgICB9CiAgICB9OwoKCgoKICAgIC8qKgogICAgICogUGFyc2VzIGEgZ2l2ZW4gZGF0YSBzb3VyY2UgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBkYXRldGltZSBwaWN0dXJlCiAgICAgKiB1bmRlciB0aGUgZ2l2ZW4gc0xvY2FsZS4KICAgICAqIEBwYXJhbSBzU291cmNlIHtzdHJpbmd9CiAgICAgKiAgICAgICAgICAgIHRoZSBzb3VyY2UgZGF0YS4KICAgICAqIEBwYXJhbSBzUGljdHVyZSB7c3RyaW5nfQogICAgICogICAgICAgICAgICB0aGUgZGF0ZXRpbWUgcGljdHVyZS4KICAgICAqIEBwYXJhbSBzRGF0ZU1hc2sge3N0cmluZ30KICAgICAqICAgICAgICAgICAgdGhlIGRhdGUgc3ViLXBpY3R1cmUuCiAgICAgKiBAcGFyYW0gc1RpbWVNYXNrIHtzdHJpbmd9CiAgICAgKiAgICAgICAgICAgIHRoZSB0aW1lIHN1Yi1waWN0dXJlLgogICAgICogQHBhcmFtIHNMb2NhbGUKICAgICAqICAgICAgICAgICAgdGhlIGxvY2FsZSBuYW1lLgogICAgICoKICAgICAqLwogICAgUGljdHVyZUZtdC5wYXJzZURhdGVUaW1lICA9IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLCBzRGF0ZU1hc2ssIHNUaW1lTWFzaywgc0xvY2FsZSl7CgogICAgfTsKICAgIC8qKgogICAgICogRm9ybWF0cyBhIGdpdmVuIGRhdGEgc291cmNlIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gZGF0ZXRpbWUgcGljdHVyZQogICAgICogdW5kZXIgdGhlIGdpdmVuIGxvY2FsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gc1NvdXJjZSB7c3RyaW5nfQogICAgICogICAgICAgICAgICB0aGUgc291cmNlIGRhdGEuCiAgICAgKiBAcGFyYW0gc1BpY3R1cmUge3N0cmluZ30KICAgICAqICAgICAgICAgICAgdGhlIGRhdGV0aW1lIHBpY3R1cmUuCiAgICAgKiBAcGFyYW0gc0RhdGVNYXNrIHtzdHJpbmd9CiAgICAgKiAgICAgICAgICAgIHRoZSBkYXRlIHN1Yi1waWN0dXJlLgogICAgICogQHBhcmFtIHNUaW1lTWFzayB7c3RyaW5nfQogICAgICogICAgICAgICAgICB0aGUgdGltZSBzdWItcGljdHVyZS4KICAgICAqIEBwYXJhbSBzTG9jYWxlIHtzdHJpbmd9CiAgICAgKiAgICAgICAgICAgIHRoZSBsb2NhbGUgbmFtZS4KICAgICAqLwogICAgUGljdHVyZUZtdC5mb3JtYXREYXRlVGltZSAgPSBmdW5jdGlvbihzU291cmNlLCBzUGljdHVyZSwgc0RhdGVNYXNrLCBzVGltZU1hc2ssIHNMb2NhbGUpewoKICAgIH07Cgp9KShfLHhmYWxpYik7Ci8qKgogKiBAcGFja2FnZSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgZGVmaW5lcyBzdGF0aWMgdXRpbGl0aWVzIG1ldGhvZHMuCiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHZhciBQaWN0dXJlVXRpbHMgPSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzID0gZnVuY3Rpb24oKSB7fQoKICAgIFBpY3R1cmVVdGlscy5wYWRkaW5nID0gZnVuY3Rpb24obnVtYmVyLCBkaWdpdHMsIGlzRncsIHplcm8pewogICAgICAgIHZhciBsZWFkaW5nID0gWyIwIiwiMDAiLCIwMDAiLCIwMDAwIl07CiAgICAgICAgdmFyIG51bVN0ciA9IGxlYWRpbmdbZGlnaXRzLTFdICsgbnVtYmVyOwogICAgICAgIHJldHVybiBudW1TdHIuc2xpY2UoLSBkaWdpdHMpOwogICAgfTsKCiAgICBQaWN0dXJlVXRpbHMucGFyc2VJbnRBZ2dyZXNzaXZlID0gZnVuY3Rpb24oZGF0ZVN0cmluZywgc3RhcnRQb3MsbGVuKXsKICAgICAgICB2YXIgcmVzdWx0ID0gbmV3IE9iamVjdCgpOwogICAgICAgIHZhciBwYXJzZWROdW0gPSAwOyAvL1RoZSBudW1iZXIgdmFsdWUgcGFyc2VkIGZyb20gZGF0ZVN0cmluZwogICAgICAgIHZhciBwYXJzZWRMZW4gPSAtMTsgLy9Ib3cgbWFueSBjaGFycyBwYXJzZWQgYWNjb3JkaW5nIHRvIHRoaXMgcGF0dGVybjsKICAgICAgICBmb3IodmFyIGlkeD0wOyBpZHg8bGVuICYmIChzdGFydFBvcyArIGlkeCkgPCBkYXRlU3RyaW5nLmxlbmd0aDsgaWR4KyspewogICAgICAgICAgICB2YXIgY2hyID0gZGF0ZVN0cmluZy5jaGFyQXQoc3RhcnRQb3MgKyBpZHgpOwogICAgICAgICAgICBpZihjaHIgPj0nMCcgJiYgY2hyIDw9JzknKXsKICAgICAgICAgICAgICAgIHBhcnNlZE51bSA9IHBhcnNlZE51bSAqMTAgKyAoY2hyLSAnMCcpOwogICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgIHBhcnNlZExlbiA9IGlkeDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmKHBhcnNlZExlbiA9PSAtMSkgewogICAgICAgICAgICBwYXJzZWRMZW4gPSBsZW47CiAgICAgICAgfQogICAgICAgIHJlc3VsdC52YWx1ZSA9IHBhcnNlZE51bTsKICAgICAgICByZXN1bHQubGVuID0gcGFyc2VkTGVuOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9OwoKICAgIFBpY3R1cmVVdGlscy5wYXJzZUludEV4YWN0ID0gZnVuY3Rpb24oZGF0ZVN0cmluZywgc3RhcnRQb3MsbGVuKXsKICAgICAgICB2YXIgcmVzdWx0ID0gMDsKICAgICAgICBQaWN0dXJlVXRpbHMuYXNzZXJ0KHN0YXJ0UG9zKyBsZW4gPD0gZGF0ZVN0cmluZy5sZW5ndGgsICJtaXNtYXRjaCIpOwogICAgICAgIGZvcih2YXIgaWR4PTA7IGlkeDxsZW4gOyBpZHgrKyl7CiAgICAgICAgICAgIHZhciBjaHIgPSBkYXRlU3RyaW5nLmNoYXJBdChzdGFydFBvcyArIGlkeCk7CiAgICAgICAgICAgIGlmKGNociA+PScwJyAmJiBjaHIgPD0nOScpewogICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0ICoxMCArIChjaHItICcwJyk7CiAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgdGhyb3cgInVuZXhwZWN0ZWQgY3VycmVudENoYXIgaW4gUGljdHVyZVV0aWxzLnBhcnNlSW50IjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfTsKCiAgICBQaWN0dXJlVXRpbHMuaXNEaWdpdCA9IGZ1bmN0aW9uKGNocil7CiAgICAgICAgcmV0dXJuIC9bMC05XS8udGVzdChjaHIpIDsKICAgIH07CgogICAgUGljdHVyZVV0aWxzLmluU3RyaW5nID0gZnVuY3Rpb24oY2hyLGFTdHJpbmcpewogICAgICAgIHJldHVybiAoYVN0cmluZy5pbmRleE9mKGNocikgPj0wKSA7CiAgICB9OwoKCiAgICB2YXIgcmVnRXhwSXNMZXR0ZXIgPSAvW1x1MDA0MS1cdTAwNWFcdTAwNjEtXHUwMDdhXHUwMGFhLVx1MDBhYVx1MDBiNS1cdTAwYjVcdTAwYmEtXHUwMGJhXHUwMGMwLVx1MDBkNlx1MDBkOC1cdTAwZjZcdTAwZjgtXHUwMjM2XHUwMjUwLVx1MDJjMVx1MDJjNi1cdTAyZDFcdTAyZTAtXHUwMmU0XHUwMmVlLVx1MDJlZVx1MDM3YS1cdTAzN2FcdTAzODYtXHUwMzg2XHUwMzg4LVx1MDM4YVx1MDM4Yy1cdTAzOGNcdTAzOGUtXHUwM2ExXHUwM2EzLVx1MDNjZVx1MDNkMC1cdTAzZjVcdTAzZjctXHUwM2ZiXHUwNDAwLVx1MDQ4MVx1MDQ4YS1cdTA0Y2VcdTA0ZDAtXHUwNGY1XHUwNGY4LVx1MDRmOVx1MDUwMC1cdTA1MGZcdTA1MzEtXHUwNTU2XHUwNTU5LVx1MDU1OVx1MDU2MS1cdTA1ODdcdTA1ZDAtXHUwNWVhXHUwNWYwLVx1MDVmMlx1MDYyMS1cdTA2M2FcdTA2NDAtXHUwNjRhXHUwNjZlLVx1MDY2Zlx1MDY3MS1cdTA2ZDNcdTA2ZDUtXHUwNmQ1XHUwNmU1LVx1MDZlNlx1MDZlZS1cdTA2ZWZcdTA2ZmEtXHUwNmZjXHUwNmZmLVx1MDZmZlx1MDcxMC1cdTA3MTBcdTA3MTItXHUwNzJmXHUwNzRkLVx1MDc0Zlx1MDc4MC1cdTA3YTVcdTA3YjEtXHUwN2IxXHUwOTA0LVx1MDkzOVx1MDkzZC1cdTA5M2RcdTA5NTAtXHUwOTUwXHUwOTU4LVx1MDk2MVx1MDk4NS1cdTA5OGNcdTA5OGYtXHUwOTkwXHUwOTkzLVx1MDlhOFx1MDlhYS1cdTA5YjBcdTA5YjItXHUwOWIyXHUwOWI2LVx1MDliOVx1MDliZC1cdTA5YmRcdTA5ZGMtXHUwOWRkXHUwOWRmLVx1MDllMVx1MDlmMC1cdTA5ZjFcdTBhMDUtXHUwYTBhXHUwYTBmLVx1MGExMFx1MGExMy1cdTBhMjhcdTBhMmEtXHUwYTMwXHUwYTMyLVx1MGEzM1x1MGEzNS1cdTBhMzZcdTBhMzgtXHUwYTM5XHUwYTU5LVx1MGE1Y1x1MGE1ZS1cdTBhNWVcdTBhNzItXHUwYTc0XHUwYTg1LVx1MGE4ZFx1MGE4Zi1cdTBhOTFcdTBhOTMtXHUwYWE4XHUwYWFhLVx1MGFiMFx1MGFiMi1cdTBhYjNcdTBhYjUtXHUwYWI5XHUwYWJkLVx1MGFiZFx1MGFkMC1cdTBhZDBcdTBhZTAtXHUwYWUxXHUwYjA1LVx1MGIwY1x1MGIwZi1cdTBiMTBcdTBiMTMtXHUwYjI4XHUwYjJhLVx1MGIzMFx1MGIzMi1cdTBiMzNcdTBiMzUtXHUwYjM5XHUwYjNkLVx1MGIzZFx1MGI1Yy1cdTBiNWRcdTBiNWYtXHUwYjYxXHUwYjcxLVx1MGI3MVx1MGI4My1cdTBiODNcdTBiODUtXHUwYjhhXHUwYjhlLVx1MGI5MFx1MGI5Mi1cdTBiOTVcdTBiOTktXHUwYjlhXHUwYjljLVx1MGI5Y1x1MGI5ZS1cdTBiOWZcdTBiYTMtXHUwYmE0XHUwYmE4LVx1MGJhYVx1MGJhZS1cdTBiYjVcdTBiYjctXHUwYmI5XHUwYzA1LVx1MGMwY1x1MGMwZS1cdTBjMTBcdTBjMTItXHUwYzI4XHUwYzJhLVx1MGMzM1x1MGMzNS1cdTBjMzlcdTBjNjAtXHUwYzYxXHUwYzg1LVx1MGM4Y1x1MGM4ZS1cdTBjOTBcdTBjOTItXHUwY2E4XHUwY2FhLVx1MGNiM1x1MGNiNS1cdTBjYjlcdTBjYmQtXHUwY2JkXHUwY2RlLVx1MGNkZVx1MGNlMC1cdTBjZTFcdTBkMDUtXHUwZDBjXHUwZDBlLVx1MGQxMFx1MGQxMi1cdTBkMjhcdTBkMmEtXHUwZDM5XHUwZDYwLVx1MGQ2MVx1MGQ4NS1cdTBkOTZcdTBkOWEtXHUwZGIxXHUwZGIzLVx1MGRiYlx1MGRiZC1cdTBkYmRcdTBkYzAtXHUwZGM2XHUwZTAxLVx1MGUzMFx1MGUzMi1cdTBlMzNcdTBlNDAtXHUwZTQ2XHUwZTgxLVx1MGU4Mlx1MGU4NC1cdTBlODRcdTBlODctXHUwZTg4XHUwZThhLVx1MGU4YVx1MGU4ZC1cdTBlOGRcdTBlOTQtXHUwZTk3XHUwZTk5LVx1MGU5Zlx1MGVhMS1cdTBlYTNcdTBlYTUtXHUwZWE1XHUwZWE3LVx1MGVhN1x1MGVhYS1cdTBlYWJcdTBlYWQtXHUwZWIwXHUwZWIyLVx1MGViM1x1MGViZC1cdTBlYmRcdTBlYzAtXHUwZWM0XHUwZWM2LVx1MGVjNlx1MGVkYy1cdTBlZGRcdTBmMDAtXHUwZjAwXHUwZjQwLVx1MGY0N1x1MGY0OS1cdTBmNmFcdTBmODgtXHUwZjhiXHUxMDAwLVx1MTAyMVx1MTAyMy1cdTEwMjdcdTEwMjktXHUxMDJhXHUxMDUwLVx1MTA1NVx1MTBhMC1cdTEwYzVcdTEwZDAtXHUxMGY4XHUxMTAwLVx1MTE1OVx1MTE1Zi1cdTExYTJcdTExYTgtXHUxMWY5XHUxMjAwLVx1MTIwNlx1MTIwOC1cdTEyNDZcdTEyNDgtXHUxMjQ4XHUxMjRhLVx1MTI0ZFx1MTI1MC1cdTEyNTZcdTEyNTgtXHUxMjU4XHUxMjVhLVx1MTI1ZFx1MTI2MC1cdTEyODZcdTEyODgtXHUxMjg4XHUxMjhhLVx1MTI4ZFx1MTI5MC1cdTEyYWVcdTEyYjAtXHUxMmIwXHUxMmIyLVx1MTJiNVx1MTJiOC1cdTEyYmVcdTEyYzAtXHUxMmMwXHUxMmMyLVx1MTJjNVx1MTJjOC1cdTEyY2VcdTEyZDAtXHUxMmQ2XHUxMmQ4LVx1MTJlZVx1MTJmMC1cdTEzMGVcdTEzMTAtXHUxMzEwXHUxMzEyLVx1MTMxNVx1MTMxOC1cdTEzMWVcdTEzMjAtXHUxMzQ2XHUxMzQ4LVx1MTM1YVx1MTNhMC1cdTEzZjRcdTE0MDEtXHUxNjZjXHUxNjZmLVx1MTY3Nlx1MTY4MS1cdTE2OWFcdTE2YTAtXHUxNmVhXHUxNzAwLVx1MTcwY1x1MTcwZS1cdTE3MTFcdTE3MjAtXHUxNzMxXHUxNzQwLVx1MTc1MVx1MTc2MC1cdTE3NmNcdTE3NmUtXHUxNzcwXHUxNzgwLVx1MTdiM1x1MTdkNy1cdTE3ZDdcdTE3ZGMtXHUxN2RjXHUxODIwLVx1MTg3N1x1MTg4MC1cdTE4YThcdTE5MDAtXHUxOTFjXHUxOTUwLVx1MTk2ZFx1MTk3MC1cdTE5NzRcdTFkMDAtXHUxZDZiXHUxZTAwLVx1MWU5Ylx1MWVhMC1cdTFlZjlcdTFmMDAtXHUxZjE1XHUxZjE4LVx1MWYxZFx1MWYyMC1cdTFmNDVcdTFmNDgtXHUxZjRkXHUxZjUwLVx1MWY1N1x1MWY1OS1cdTFmNTlcdTFmNWItXHUxZjViXHUxZjVkLVx1MWY1ZFx1MWY1Zi1cdTFmN2RcdTFmODAtXHUxZmI0XHUxZmI2LVx1MWZiY1x1MWZiZS1cdTFmYmVcdTFmYzItXHUxZmM0XHUxZmM2LVx1MWZjY1x1MWZkMC1cdTFmZDNcdTFmZDYtXHUxZmRiXHUxZmUwLVx1MWZlY1x1MWZmMi1cdTFmZjRcdTFmZjYtXHUxZmZjXHUyMDcxLVx1MjA3MVx1MjA3Zi1cdTIwN2ZcdTIxMDItXHUyMTAyXHUyMTA3LVx1MjEwN1x1MjEwYS1cdTIxMTNcdTIxMTUtXHUyMTE1XHUyMTE5LVx1MjExZFx1MjEyNC1cdTIxMjRcdTIxMjYtXHUyMTI2XHUyMTI4LVx1MjEyOFx1MjEyYS1cdTIxMmRcdTIxMmYtXHUyMTMxXHUyMTMzLVx1MjEzOVx1MjEzZC1cdTIxM2ZcdTIxNDUtXHUyMTQ5XHUzMDA1LVx1MzAwNlx1MzAzMS1cdTMwMzVcdTMwM2ItXHUzMDNjXHUzMDQxLVx1MzA5Nlx1MzA5ZC1cdTMwOWZcdTMwYTEtXHUzMGZhXHUzMGZjLVx1MzBmZlx1MzEwNS1cdTMxMmNcdTMxMzEtXHUzMThlXHUzMWEwLVx1MzFiN1x1MzFmMC1cdTMxZmZcdTM0MDAtXHU0ZGI1XHU0ZTAwLVx1OWZhNVx1YTAwMC1cdWE0OGNcdWFjMDAtXHVkN2EzXHVmOTAwLVx1ZmEyZFx1ZmEzMC1cdWZhNmFcdWZiMDAtXHVmYjA2XHVmYjEzLVx1ZmIxN1x1ZmIxZC1cdWZiMWRcdWZiMWYtXHVmYjI4XHVmYjJhLVx1ZmIzNlx1ZmIzOC1cdWZiM2NcdWZiM2UtXHVmYjNlXHVmYjQwLVx1ZmI0MVx1ZmI0My1cdWZiNDRcdWZiNDYtXHVmYmIxXHVmYmQzLVx1ZmQzZFx1ZmQ1MC1cdWZkOGZcdWZkOTItXHVmZGM3XHVmZGYwLVx1ZmRmYlx1ZmU3MC1cdWZlNzRcdWZlNzYtXHVmZWZjXHVmZjIxLVx1ZmYzYVx1ZmY0MS1cdWZmNWFcdWZmNjYtXHVmZmJlXHVmZmMyLVx1ZmZjN1x1ZmZjYS1cdWZmY2ZcdWZmZDItXHVmZmQ3XHVmZmRhLVx1ZmZkY10vCgogICAgLyoqCiAgICAgKiBUT0RPIEltcGxlbWVudCBtZXRob2QgZXF1aXZhbGVudCB0byBDaGFyYWN0ZXIuaXNMZXR0ZXIuCiAgICAgKi8KICAgIFBpY3R1cmVVdGlscy5pc0xldHRlciA9IGZ1bmN0aW9uKGNocil7CiAgICAgICAgcmV0dXJuIHJlZ0V4cElzTGV0dGVyLnRlc3QoY2hyKTsKICAgIH07CgogICAgUGljdHVyZVV0aWxzLmlzTGV0dGVyT3JEaWdpdCA9IGZ1bmN0aW9uKGNocil7CiAgICAgICAgcmV0dXJuIHRoaXMuaXNMZXR0ZXIoY2hyKSB8fCB0aGlzLmlzRGlnaXQoY2hyKTsKICAgIH07CgogICAgLyoqCiAgICAgKiBTY2FuIHRoaXMgc3RyaW5nIGZvciB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHRoZSBnaXZlbiBzZXQuIFNpbWlsYXIgdG8KICAgICAqIHN0cmNzcG4oKS4KICAgICAqCiAgICAgKiBAcGFyYW0gc3Jje1N0cmluZ30KICAgICAqICAgICAgICAgICAgdGhlIHN0cmluZyB0byBzY2FuCiAgICAgKiBAcGFyYW0gc1NraXB7U3RyaW5nfQogICAgICogICAgICAgICAgICB0aGUgY2hhcmFjdGVycyB0byBzY2FuIGZvcgogICAgICogQHBhcmFtIG5PZmZzZXR7bnVtYmVyfQogICAgICogICAgICAgICAgICB0aGUgcG9zaXRpb24gd2hlcmUgdG8gc3RhcnQgdGhlIHNjYW4uIERlZmF1bHQgPSAwLgogICAgICogQHJldHVybiBUaGUgcG9zaXRpb24sIHJlbGF0aXZlIHRvIG5PZmZzZXQsIGZvciB0aGUgZmlyc3QgY2hhcmFjdGVyIGZvdW5kCiAgICAgKiAgICAgICAgIGluIHRoZSBnaXZlbiBzZXQKICAgICAqLwogICAgUGljdHVyZVV0aWxzLnNraXBVbnRpbCA9IGZ1bmN0aW9uKHNyY1N0ciwgc1NraXAsIG5PZmZzZXQpIHsKICAgICAgICB2YXIgbkNoYXJzU2tpcHBlZCA9IG5PZmZzZXQ7CgogICAgICAgIC8vIHN0YXJ0aW5nIGF0IHRoZSBvZmZzZXQgcG9zaXRpb24sIHNjYW4gdGhlIGNoYXJhY3RlcnMgaW4gdGhpcyBzdHJpbmcKICAgICAgICAvLyB1bnRpbCBpdCBtYXRjaGVzIG9uZSBvZiB0aGUgY2hhcmFjdGVycyBpbiB0aGUgZ2l2ZW4gc2V0LgogICAgICAgIHdoaWxlIChuQ2hhcnNTa2lwcGVkIDwgc3JjU3RyLmxlbmd0aCkgewogICAgICAgICAgICB2YXIgaSA9IG5DaGFyc1NraXBwZWQ7CiAgICAgICAgICAgIGlmIChzU2tpcC5pbmRleE9mKHNyY1N0ci5jaGFyQXQoaSsrKSkgPj0gMCkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBuQ2hhcnNTa2lwcGVkID0gaTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBuQ2hhcnNTa2lwcGVkIC0gbk9mZnNldDsKICAgIH07CgogICAgUGljdHVyZVV0aWxzLm1hdGNoU3RyaW5nID0gZnVuY3Rpb24oc3RyLCBzdGFydFBvcywgdGFyZ2V0KXsKICAgICAgICBpZihzdGFydFBvcyArIHRhcmdldC5sZW5ndGggPiBzdHIubGVuZ3RoKXsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH1lbHNlewogICAgICAgICAgICBmb3IodmFyIGlkeCA9IDA7IGlkeDx0YXJnZXQubGVuZ3RoOyBpZHgrKyl7CiAgICAgICAgICAgICAgICBpZih0YXJnZXQuY2hhckF0KGlkeCkgIT0gc3RyLmNoYXJBdChzdGFydFBvcyArIGlkeCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9OwoKICAgIFBpY3R1cmVVdGlscy5hc3NlcnQgPSBmdW5jdGlvbihjb25kaXRpb24sIG1lc3NhZ2UpewogICAgICAgIGlmKCFjb25kaXRpb24pewogICAgICAgICAgICB0aHJvdyBtZXNzYWdlOwogICAgICAgIH0KICAgIH07CgogICAgUGljdHVyZVV0aWxzLmdldExvY2FsZU9iamVjdCA9IGZ1bmN0aW9uKGxvY2FsZSxwcm9wZXJ0eSkgewogICAgICAgIGlmKGxvY2FsZSAhPT0gbnVsbCAmJiB4ZmFsaWIucnVudGltZS54ZmEpIHsKICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi5ydW50aW1lLnhmYS5fZ2V0TG9jYWxlU3ltYm9scyhsb2NhbGUsIHByb3BlcnR5KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmdldERlZmF1bHRMb2NhbGVQcm9wZXJ0eShwcm9wZXJ0eSkKICAgICAgICB9CiAgICB9CgogICAgUGljdHVyZVV0aWxzLmdldEhhc2hPZkxvY2FsZU9iamVjdCA9IGZ1bmN0aW9uKGxvY2FsZSxwcm9wZXJ0eSkgewogICAgICAgICAgaWYoIVBpY3R1cmVVdGlscy5nZXRIYXNoT2ZMb2NhbGVPYmplY3RbbG9jYWxlKyJfIitwcm9wZXJ0eV0pIHsKICAgICAgICAgICAgICB2YXIgaGFzaE9iaiA9IHt9OwogICAgICAgICAgICAgIF8uZWFjaChQaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KGxvY2FsZSxwcm9wZXJ0eSksIGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAgICAgICB2YXIgc1ZhbCA9ICh2YWwrIiIpLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgICAgICAgIHZhciBoYXNoID0gMDsKICAgICAgICAgICAgICAgICAgZm9yKHZhciBpID0wO2k8c1ZhbC5sZW5ndGg7aSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICBoYXNoKz0oaSsxKSpzVmFsLmNoYXJDb2RlQXQoaSkKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBoYXNoT2JqW2hhc2hdID0gaGFzaE9ialtoYXNoXSB8fCBbXTsKICAgICAgICAgICAgICAgICAgaGFzaE9ialtoYXNoXS5wdXNoKHNWYWwpOwogICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgUGljdHVyZVV0aWxzLmdldEhhc2hPZkxvY2FsZU9iamVjdFtsb2NhbGUrIl8iK3Byb3BlcnR5XSA9IGhhc2hPYmo7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gUGljdHVyZVV0aWxzLmdldEhhc2hPZkxvY2FsZU9iamVjdFtsb2NhbGUrIl8iK3Byb3BlcnR5XQogICAgfQoKICAgIFBpY3R1cmVVdGlscy5jb252ZXJ0TnVtYmVyVG9Mb2NhbGUgPSBmdW5jdGlvbihsb2NhbGUsbnVtYmVyKSB7CiAgICAgICAgdmFyIHplcm8gPSBQaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KGxvY2FsZSwibnVtYmVyU3ltYm9scy56ZXJvIik7CiAgICAgICAgdmFyIHplcm9Db2RlID0gemVyby5jaGFyQ29kZUF0KDApOwogICAgICAgIG51bWJlciArPSAiIjsKICAgICAgICB2YXIgbmV3TnVtYmVyID0gW107CiAgICAgICAgZm9yKHZhciBpID0gMDtpIDwgbnVtYmVyLmxlbmd0aDtpKyspIHsKICAgICAgICAgICAgbmV3TnVtYmVyLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZSh6ZXJvQ29kZSArIHBhcnNlSW50KG51bWJlci5jaGFyQXQoaSkpKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXdOdW1iZXIuam9pbigiIik7CiAgICB9CgogICAgUGljdHVyZVV0aWxzLnBhcnNlUGljdHVyZUNsYXVzZSA9IGZ1bmN0aW9uIChjbGF1c2UpewogICAgICAgIGlmKGNsYXVzZSA9PT0gbnVsbCB8fCBjbGF1c2UgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICByZXR1cm4gW107CiAgICAgICAgfQogICAgICAgIHZhciBpbnNpZGVQYXR0ZXJuID0gZmFsc2UsCiAgICAgICAgICAgIGluc2lkZVF1b3RlPWZhbHNlLAogICAgICAgICAgICBpbnNpZGVMb2NhbGUgPSBmYWxzZSwKICAgICAgICAgICAgbG9jYWxlID0gIiIsCiAgICAgICAgICAgIHR5cGUgPSAiIiwKICAgICAgICAgICAgcGF0dGVybiA9ICIiLAogICAgICAgICAgICBmbGFnID0gZmFsc2UsCiAgICAgICAgICAgIGN1cnJlbnRDaGFyID0gIiIsCiAgICAgICAgICAgIHJlc3VsdCA9IFtdLAogICAgICAgICAgICBtYXRjaFR5cGUgPSAvXm51bSR8XnRleHQkfF5kYXRlJC8sCiAgICAgICAgICAgIG1hdGNoTG9jYWxlID0gL15bYS16QS1aXSpfW2EtekEtWl0qJC8sCiAgICAgICAgICAgIGkgPSAwLAogICAgICAgICAgICBicmFja2V0T3BlbkNvdW50ID0gMDsKICAgICAgICBmb3IoO2k8Y2xhdXNlLmxlbmd0aDtpKyspIHsKICAgICAgICAgICAgY3VycmVudENoYXIgPSBjbGF1c2UuY2hhckF0KGkpOwogICAgICAgICAgICBpZihpbnNpZGVRdW90ZSAmJiBjdXJyZW50Q2hhciAhPT0gIiciKSB7CiAgICAgICAgICAgICAgICBwYXR0ZXJuICs9IGN1cnJlbnRDaGFyOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3dpdGNoKGN1cnJlbnRDaGFyKSB7CiAgICAgICAgICAgICAgIGNhc2UgIiciOgogICAgICAgICAgICAgICAgICAgaWYoIWluc2lkZVBhdHRlcm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAvLyAnIGlzIG5vdCBhbGxvd2VkIGV4Y2VwdCBpbnNpZGVQYXR0ZXJuCiAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICBpbnNpZGVRdW90ZSA9ICFpbnNpZGVRdW90ZTsKICAgICAgICAgICAgICAgICAgIHBhdHRlcm4gKz0gY3VycmVudENoYXI7CiAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgY2FzZSAieyI6CiAgICAgICAgICAgICAgICAgICAgaWYoaW5zaWRlUGF0dGVybiB8fCBpbnNpZGVMb2NhbGUgfHwgdHlwZSA9PT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8geyBpcyBub3QgYWxsb3dlZCBpbnNpZGVQYXR0ZXJuIG9yIGluc2lkZUxvY2FsZQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICBpbnNpZGVQYXR0ZXJuID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIn0iOgogICAgICAgICAgICAgICAgICAgIGlmKCFpbnNpZGVQYXR0ZXJuIHx8IChpbnNpZGVMb2NhbGUgJiYgcGF0dGVybiA9PT0gIiIpIHx8IHR5cGUgPT09ICIiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHsgaXMgYWxsb3dlZCBvbmx5IGluc2lkZVBhdHRlcm4gYW5kIG5vdCBpbnNpZGVMb2NhbGUKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJhY2tldE9wZW5Db3VudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGluc2lkZVBhdHRlcm4gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYobWF0Y2hUeXBlLmV4ZWModHlwZSkgPT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGxvY2FsZSAhPT0gIiIgJiYgbWF0Y2hMb2NhbGUuZXhlYyhsb2NhbGUpID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaCh7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeTogdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hc2s6IHBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbGU6IGxvY2FsZQogICAgICAgICAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInwiOgogICAgICAgICAgICAgICAgICAgIGlmKHR5cGUgPT09ICIiIHx8IGluc2lkZVBhdHRlcm4gfHwgaW5zaWRlTG9jYWxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSBwYXR0ZXJuID0gbG9jYWxlID0gIiI7CiAgICAgICAgICAgICAgICAgICAgICAgIGluc2lkZVBhdHRlcm4gPSBpbnNpZGVMb2NhbGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICIoIiA6CiAgICAgICAgICAgICAgICAgICAgaWYodHlwZSA9PT0gIiIgfHwgYnJhY2tldE9wZW5Db3VudCA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyAoIGlzIG5vdCBhbGxvd2VkIGluc2lkZSBMb2NhbGUKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIWluc2lkZVBhdHRlcm4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc2lkZUxvY2FsZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuICs9IGN1cnJlbnRDaGFyOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyYWNrZXRPcGVuQ291bnQrKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICIpIiA6CiAgICAgICAgICAgICAgICAgICAgaWYoKCFpbnNpZGVMb2NhbGUgJiYgIWluc2lkZVBhdHRlcm4pIHx8IGJyYWNrZXRPcGVuQ291bnQgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoaW5zaWRlUGF0dGVybikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybiArPSBjdXJyZW50Q2hhcjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpbnNpZGVMb2NhbGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJhY2tldE9wZW5Db3VudC0tOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYoaW5zaWRlUGF0dGVybikgewogICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuICs9IGN1cnJlbnRDaGFyOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZihpbnNpZGVMb2NhbGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlICs9IGN1cnJlbnRDaGFyOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZih0eXBlICE9PSAiIiAmJiAocGF0dGVybiAhPT0gIiIgfHwgbG9jYWxlICE9PSAiIikpewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0eXBlICs9IGN1cnJlbnRDaGFyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICB9CiAgICAgICB9CiAgICAgICBpZihpbnNpZGVQYXR0ZXJuIHx8IGluc2lkZUxvY2FsZSB8fCBpbnNpZGVRdW90ZSB8fCBicmFja2V0T3BlbkNvdW50ICE9PSAwKSB7CiAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICB9CiAgICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKfSkoXyx4ZmFsaWIpOwoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5WaXNpdG9yQmFzZQogKiBAaW1wb3J0IHhmYWxpYi51dC5DbGFzcwogKiBAZmlsZU92ZXJ2aWV3IEJhc2UgY2xhc3MgZm9yIHZpc2l0b3IKICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nfX0KICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpIHsKICAgIHZhciBWaXNpdG9yQmFzZSA9IHhmYWxpYi51dC5WaXNpdG9yQmFzZSA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewogICAgICAgIGNvbnN1bWUgOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgICAgIHN3aXRjaCAodG9rZW4udHlwZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgIHRoaXMuY29uc3VtZVN0cmluZ0xpdGVyYWwodG9rZW4pOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgICAgIHRoaXMuY29uc3VtZVN1YlBhdHRlcm4odG9rZW4pOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgICAgIHRoaXMuY29uc3VtZVN0cmluZ1dpbGRDYXJkKHRva2VuKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnN1bWVDaGFyTGl0ZXJhbCh0b2tlbik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGFjY2VwdFBhdHRlcm5DaGFyIDogZnVuY3Rpb24oY2hyKXsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCiAgICAgICAgZ2V0UGljdHVyZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmU7CiAgICAgICAgfSwKICAgICAgICBhYnN0cmFjdE1ldGhvZCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHRocm93ICJOb3QgaW1wbGVtZW50ZWQiOwogICAgICAgIH0sCiAgICAgICAgY29uc3VtZVN0cmluZ1dpbGRDYXJkIDogdGhpcy5hYnN0cmFjdE1ldGhvZCwKICAgICAgICBjb25zdW1lU3RyaW5nTGl0ZXJhbDogdGhpcy5hYnN0cmFjdE1ldGhvZCwKICAgICAgICBjb25zdW1lQ2hhckxpdGVyYWw6IHRoaXMuYWJzdHJhY3RNZXRob2QsCiAgICAgICAgY29uc3VtZVN1YlBhdHRlcm46IHRoaXMuYWJzdHJhY3RNZXRob2QsCiAgICAgICAgZ2V0UmVzdWx0OiB0aGlzLmFic3RyYWN0TWV0aG9kCiAgICB9KTsKfSkoXyx4ZmFsaWIpOwoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYwogKiBAaW1wb3J0IHhmYWxpYi51dC5DbGFzcwogKiBAZmlsZU92ZXJ2aWV3IFByZS1wcm9jZXNzIE51bWVyaWMgUGljdHVyZS4KICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nfX0KICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgdmFyIE51bVBpY3R1cmVEZXNjID0geGZhbGliLnV0Lk51bVBpY3R1cmVEZXNjID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB0aGlzLmhhc1JhZGl4ID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuaGFzRXhwb24gPSBmYWxzZTsKICAgICAgICAgICAgdGhpcy5oYXNTaWduID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuaGFzUGVyY2VudCA9IGZhbHNlOwogICAgICAgICAgICB0aGlzLmZyYWNEaWdpdCA9IDA7CiAgICAgICAgICAgIHRoaXMuaW50RGlnaXQgPSAwOwoKICAgICAgICAgICAgdGhpcy5fbWJMZWZ0UGFyZW5TZWVuID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuX21iUmlnaHRQYXJlblNlZW4gPSBmYWxzZTsKICAgICAgICAgICAgdGhpcy5fY29tcGFjdFBhdHRlcm4oKTsKICAgICAgICAgICAgdGhpcy5feGxhdGVQYXR0ZXJuKCk7CiAgICAgICAgICAgIE51bVBpY3R1cmVEZXNjLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgfSwKICAgICAgICAKICAgICAgICBnZXRQaWN0dXJlIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZTsKICAgICAgICB9LAoKICAgICAgICBfbWF0Y2gyQ2hhciA6IGZ1bmN0aW9uIChjaGFyMSwgY2hhcjIsIGlkeCl7CiAgICAgICAgICAgIGlmKGlkeCsxIDwgdGhpcy5qc29uTW9kZWwuX3NQaWN0dXJlLmxlbmd0aCl7CiAgICAgICAgICAgICAgICByZXR1cm4gKHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5jaGFyQXQoaWR4KSA9PWNoYXIxICYmIHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5jaGFyQXQoaWR4KzEpID09Y2hhcjIpOwogICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF94bGF0ZVBhdHRlcm4gOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgcGF0UG9zID0gMDsKICAgICAgICAgICAgZm9yKHZhciB0b2tlbiA9IHhmYWxpYi51dC5TY2FubmVyLmxvb2t1cE5leHQodGhpcy5qc29uTW9kZWwuX3NQaWN0dXJlLCBwYXRQb3MsIHRoaXMuX2FjY2VwdFBhdHRlcm5DaGFyKTsgdG9rZW4gIT0gbnVsbDsgICl7CiAgICAgICAgICAgICAgICB0aGlzLl9jb25zdW1lKHRva2VuKTsKICAgICAgICAgICAgICAgIHBhdFBvcyA9IHBhdFBvcyArIHRva2VuLmxlbjsKICAgICAgICAgICAgICAgIHRva2VuID0geGZhbGliLnV0LlNjYW5uZXIubG9va3VwTmV4dCh0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmUsIHBhdFBvcywgdGhpcy5fYWNjZXB0UGF0dGVybkNoYXIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAKICAgICAgICBfY29tcGFjdFBhdHRlcm4gOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgYnVmID0gbmV3IEFycmF5KCk7CiAgICAgICAgICAgIGZvcih2YXIgaW5kZXggPTAsIGxlbiA9IHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5sZW5ndGg7IGluZGV4IDxsZW47IGluZGV4KyspewogICAgICAgICAgICAgICAgaWYodGhpcy5fbWF0Y2gyQ2hhcignRCcsJ0InLGluZGV4KSl7CiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goJ0QnKTsKICAgICAgICAgICAgICAgICAgICBpbmRleCsrOwogICAgICAgICAgICAgICAgfWVsc2UgaWYodGhpcy5fbWF0Y2gyQ2hhcignZCcsJ2InLGluZGV4KSl7CiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goJ2QnKTsKICAgICAgICAgICAgICAgICAgICBpbmRleCsrOwogICAgICAgICAgICAgICAgfWVsc2UgaWYodGhpcy5fbWF0Y2gyQ2hhcignQycsJ1InLGluZGV4KSl7CiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goJ0MnKTsKICAgICAgICAgICAgICAgICAgICBpbmRleCsrOwogICAgICAgICAgICAgICAgfWVsc2UgaWYodGhpcy5fbWF0Y2gyQ2hhcignYycsJ3InLGluZGV4KSl7CiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goJ2MnKTsKICAgICAgICAgICAgICAgICAgICBpbmRleCsrOwogICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2godGhpcy5qc29uTW9kZWwuX3NQaWN0dXJlLmNoYXJBdChpbmRleCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZSA9IGJ1Zi5qb2luKCIiKTsKICAgICAgICB9LAoKICAgICAgICBfYWNjZXB0UGF0dGVybkNoYXIgOiBmdW5jdGlvbihjaHIpewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlBpY3R1cmVVdGlscy5pblN0cmluZyhjaHIsICIoJSQsLik4OUJDREVSU1ZaYmNkcnN2enQiKTsKICAgICAgICB9LAoKICAgICAgICBfY29uc3VtZSA6IGZ1bmN0aW9uKHRva2VuKXsKICAgICAgICAgICAgaWYodG9rZW4udHlwZSA9PSAyKXsKICAgICAgICAgICAgICAgIHRoaXMuX3N1YkNvbnN1bWUodG9rZW4ucGF0Q2hhciwgdG9rZW4ubGVuKTsKICAgICAgICAgICAgfS8vIGVsc2Ugbm90IGEgcGF0dGVybgogICAgICAgIH0sCgogICAgICAgIF9zdWJDb25zdW1lIDogZnVuY3Rpb24oY2hyLCBjaHJDbnQpewogICAgICAgICAgICBzd2l0Y2ggKGNocikgewogICAgICAgICAgICAgICAgY2FzZSdFJyA6CiAgICAgICAgICAgICAgICAgICAgaWYgKGNockNudCA+IDEgfHwgdGhpcy5oYXNFeHBvbiB8fCAodGhpcy5mcmFjRGlnaXQgKyB0aGlzLmludERpZ2l0KT09MCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIklsbGVnYWwgTnVtZXJpYyBQaWN0dXJlOiBtb3JlIHRoYW4gb25lIEV4cG9uIjsKICAgICAgICAgICAgICAgICAgICB0aGlzLmhhc0V4cG9uID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJygnOgogICAgICAgICAgICAgICAgICAgIGlmIChjaHJDbnQgPiAxIHx8IHRoaXMuX21iTGVmdFBhcmVuU2Vlbgl8fCB0aGlzLmZyYWNEaWdpdCArIHRoaXMuaW50RGlnaXQgPjAgKQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiSWxsZWdhbCBOdW1lcmljIFBpY3R1cmU6ICAoKSI7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJMZWZ0UGFyZW5TZWVuID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICcpJzoKICAgICAgICAgICAgICAgICAgICBpZiAoY2hyQ250ID4gMSB8fCAhIHRoaXMuX21iTGVmdFBhcmVuU2VlbiB8fCB0aGlzLl9tYlJpZ2h0UGFyZW5TZWVuKQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiSWxsZWdhbCBOdW1lcmljIFBpY3R1cmU6ICAoKSI7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJSaWdodFBhcmVuU2VlbiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5mcmFjRGlnaXQgKyB0aGlzLmludERpZ2l0ID4wKSB0aGlzLmhhc1NpZ24gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnUyc6CiAgICAgICAgICAgICAgICBjYXNlICdzJzoKICAgICAgICAgICAgICAgIGNhc2UgJ0MnOiAvL0NSCiAgICAgICAgICAgICAgICBjYXNlICdjJzogLy9jcgogICAgICAgICAgICAgICAgY2FzZSAnRCc6IC8vREIKICAgICAgICAgICAgICAgIGNhc2UgJ2QnOiAvL2RiCiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYXNTaWduID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJyUnIDoKICAgICAgICAgICAgICAgICAgICB0aGlzLmhhc1BlcmNlbnQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnLic6CiAgICAgICAgICAgICAgICBjYXNlICdWJzoKICAgICAgICAgICAgICAgIGNhc2UgJ3YnOgogICAgICAgICAgICAgICAgICAgIGlmIChjaHJDbnQgPiAxIHx8IHRoaXMuaGFzUmFkaXgpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJJbGxlZ2FsIE51bWVyaWMgUGljdHVyZTogdG9vIG1hbnkgdlYuIjsKICAgICAgICAgICAgICAgICAgICB0aGlzLmhhc1JhZGl4ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYkZyYWNTdGFydFNlZW4gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnOCcgOgogICAgICAgICAgICAgICAgY2FzZSAnOScgOgogICAgICAgICAgICAgICAgY2FzZSAnWic6CiAgICAgICAgICAgICAgICBjYXNlICd6JzoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5oYXNSYWRpeCl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZnJhY0RpZ2l0ICs9IGNockNudDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW50RGlnaXQgKz0gY2hyQ250OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHBhcnNlTnVtYmVySW5mbyA6IGZ1bmN0aW9uKG1zVGV4dCl7CiAgICAgICAgICAgIHZhciB0ZXh0PW1zVGV4dCwKICAgICAgICAgICAgICAgIG51bSA9IE51bWJlcih0ZXh0KSwKICAgICAgICAgICAgICAgIG5lZ2F0aXZlID0gZmFsc2UKICAgICAgICAgICAgaWYobnVtIDwgMCl7CiAgICAgICAgICAgICAgICBuZWdhdGl2ZSA9IHRydWU7CiAgICAgICAgICAgICAgICBudW0gPSAtbnVtOwogICAgICAgICAgICAgICAgdGV4dCA9IHRleHQucmVwbGFjZSgiLSIsIiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKHRoaXMuaGFzUGVyY2VudCl7CiAgICAgICAgICAgICAgICBudW0gKj0gMTAwOwogICAgICAgICAgICAgICAgdGV4dCA9ICIiK251bTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgc2hpZnQgPSAwOwogICAgICAgICAgICBpZih0aGlzLmhhc0V4cG9uKXsKICAgICAgICAgICAgICAgIHZhciB0aHJlc2hvbGQgPSBNYXRoLnBvdygxMCx0aGlzLmludERpZ2l0KTsKICAgICAgICAgICAgICAgIGlmKG51bSA8IHRocmVzaG9sZCl7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUobnVtKjEwIDwgdGhyZXNob2xkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG51bSAqPSAxMDsKICAgICAgICAgICAgICAgICAgICAgICAgc2hpZnQtLTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgICAgICB3aGlsZShudW0gPiB0aHJlc2hvbGQpewogICAgICAgICAgICAgICAgICAgICAgICBudW0gLz0gMTA7CiAgICAgICAgICAgICAgICAgICAgICAgIHNoaWZ0Kys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGV4dCA9IG51bSsiIjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgcmFkaXhQb3MgPSB0ZXh0LmluZGV4T2YoIi4iLCAwKSwKICAgICAgICAgICAgICAgIGZyYWN0aW9uRGlnaXQgPSByYWRpeFBvczwwID8gMCA6IHRleHQubGVuZ3RoIC0gcmFkaXhQb3MgLSAxCgogICAgICAgICAgICBpZih0aGlzLmZyYWNEaWdpdCA8IGZyYWN0aW9uRGlnaXQpIHsKICAgICAgICAgICAgICAgIG51bSA9IG51bS50b0ZpeGVkKHRoaXMuZnJhY0RpZ2l0KTsKICAgICAgICAgICAgICAgIHRleHQgPSBudW0gKyIiCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHRleHQuaW5kZXhPZigiMCIpID09IDAgJiYgbXNUZXh0LmluZGV4T2YoIjAiKSAhPSAwKSB7CiAgICAgICAgICAgICAgICB0ZXh0ID0gdGV4dC5zdWJzdHJpbmcoMSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJhZGl4UG9zID0gdGV4dC5pbmRleE9mKCIuIiwgMCkKICAgICAgICAgICAgdmFyIGludGVnZXJEaWdpdCA9IHJhZGl4UG9zIDwgMCA/IHRleHQubGVuZ3RoIDogcmFkaXhQb3MsCiAgICAgICAgICAgICAgICBvZmZzZXQgPSB0aGlzLmludERpZ2l0IC0gaW50ZWdlckRpZ2l0CgogICAgICAgICAgICBpZihvZmZzZXQgPDAgKXsKICAgICAgICAgICAgICAgIHRocm93ICJFeGl0OiBtb3N0IHNpZ25pZmljYW50ICIgKyBvZmZzZXQgKyIgZGlnaXQgbG9zdCI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICJpbnRlZ2VyRGlnaXQiIDogaW50ZWdlckRpZ2l0LAogICAgICAgICAgICAgICAgInJhZGl4UG9zIiA6IHJhZGl4UG9zICwKICAgICAgICAgICAgICAgICJmcmFjdGlvbkRpZ2l0IiA6ICByYWRpeFBvczwwID8gMCA6IHRleHQubGVuZ3RoIC0gcmFkaXhQb3MgLSAxLAogICAgICAgICAgICAgICAgIm1zVGV4dCIgOiB0ZXh0LAogICAgICAgICAgICAgICAgInNoaWZ0IiA6IHNoaWZ0LAogICAgICAgICAgICAgICAgImlzTmVnYXRpdmUiIDogbmVnYXRpdmUsCiAgICAgICAgICAgICAgICAicGFkZGluZyIgOm9mZnNldAogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0pOwoKICAgIE51bVBpY3R1cmVEZXNjLmdzREIgPSAiREIiOwogICAgTnVtUGljdHVyZURlc2MuZ3NDUiA9ICJDUiI7CiAgICBOdW1QaWN0dXJlRGVzYy5nc0UgPSAiRSI7CiAgICBOdW1QaWN0dXJlRGVzYy5nc0RTUCA9ICIgICI7CiAgICBOdW1QaWN0dXJlRGVzYy5nc1NTUCA9ICIgIjsKCn0pKF8seGZhbGliKTsKCgoKCgoKCgoKCgogICAgLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5UaW1lSW5mbwogKiBAaW1wb3J0IHhmYWxpYi51dC5DbGFzcwogKiBAZmlsZU92ZXJ2aWV3IEEgd3JhcHBlciBjbGFzcyBmb3IgZGF0ZSByZWxhdGVkIGluZm9ybWF0aW9uLgogKiBAdmVyc2lvbiAwLjAuMQogKi8KCi8qKgogKiBAY29uc3RydWN0b3IKICovCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgVGltZUluZm8gPSB4ZmFsaWIudXQuVGltZUluZm8gPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHRoaXMubUhvdXJPZk1lcmlEaWVtID0gLTE7CiAgICAgICAgICAgIHRoaXMubUhvdXJPZkRheSA9IC0xOwogICAgICAgICAgICB0aGlzLm1NaW51dGVPZkhvdXIgPSAtMTsKICAgICAgICAgICAgdGhpcy5tU2Vjb25kT2ZNaW51dGUgPSAtMTsKICAgICAgICAgICAgdGhpcy5tVGhvdXNhbmR0aE9mU2Vjb25kID0gLTE7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0SVNPVGltZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciB0aW1lU3RyID0gIiI7CiAgICAgICAgICAgIGlmKHRoaXMubVRob3VzYW5kdGhPZlNlY29uZD4wKXsKICAgICAgICAgICAgICAgIHRpbWVTdHIgPSAiLSIgKyB0aGlzLmZvcm1hdE51bSh0aGlzLm1UaG91c2FuZHRoT2ZTZWNvbmQsMyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYodGhpcy5tU2Vjb25kT2ZNaW51dGU+MCB8fCB0aW1lU3RyIT0iIil7CiAgICAgICAgICAgICAgICB0aW1lU3RyID0gdGhpcy5mb3JtYXROdW0odGhpcy5tU2Vjb25kT2ZNaW51dGUsMikrdGltZVN0cjsKICAgICAgICAgICAgICAgIHRpbWVTdHIgPSAiOiIrdGltZVN0cjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZih0aGlzLm1NaW51dGVPZkhvdXI+MCB8fCB0aW1lU3RyIT0iIil7CiAgICAgICAgICAgICAgICB0aW1lU3RyID0gdGhpcy5mb3JtYXROdW0odGhpcy5tTWludXRlT2ZIb3VyLDIpK3RpbWVTdHI7CiAgICAgICAgICAgICAgICB0aW1lU3RyID0gIjoiK3RpbWVTdHI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGltZVN0ciA9IHRoaXMuZm9ybWF0TnVtKHRoaXMubUhvdXJPZkRheSwyKSArIHRpbWVTdHI7CgogICAgICAgICAgICByZXR1cm4gdGltZVN0cjsKICAgICAgICB9LAoKICAgICAgICBmb3JtYXROdW0gOiBmdW5jdGlvbihudW0sIGRpZ2l0cyl7CiAgICAgICAgICAgIGlmKG51bTwwKXsKICAgICAgICAgICAgICAgIG51bSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5QaWN0dXJlVXRpbHMucGFkZGluZyhudW0sIGRpZ2l0cyk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RGF0ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciBkYXRlID0gbmV3IERhdGUoKTsKICAgICAgICAgICAgdGhpcy5zZXRUaW1lKGRhdGUpOwogICAgICAgICAgICByZXR1cm4gZGF0ZTsKICAgICAgICB9LAoKICAgICAgICBzZXRUaW1lIDogZnVuY3Rpb24oZGF0ZSl7CiAgICAgICAgICAgIGRhdGUuc2V0SG91cnModGhpcy5tSG91ck9mRGF5KTsKICAgICAgICAgICAgZGF0ZS5zZXRNaW51dGVzKHRoaXMubU1pbnV0ZU9mSG91cik7CiAgICAgICAgICAgIGRhdGUuc2V0U2Vjb25kcyh0aGlzLm1TZWNvbmRPZk1pbnV0ZSk7CiAgICAgICAgICAgIGRhdGUuc2V0TWlsbGlzZWNvbmRzKHRoaXMubVRob3VzYW5kdGhPZlNlY29uZCk7CiAgICAgICAgfQogICAgfSk7CgogICAgLyoqCiAgICAgKgogICAgICogPHA+VmFsaWQgSVNPODYwMS9YRkEgdGltZSBzdHJpbmdzIGFyZSBpbiBhbnkgb25lCiAgICAgKiBvZiB0aGUgZm9sbG93aW5nIHRpbWUgcGF0dGVybnM6CiAgICAgKiA8dWw+CiAgICAgKiA8bGk+IEhIW01NW1NTWy5GRkZdW3pdXV0KICAgICAqIDxsaT4gSEhbTU1bU1NbLkZGRl1bK0hIW01NXV1dXQogICAgICogPGxpPiBISFtNTVtTU1suRkZGXVstSEhbTU1dXV1dCiAgICAgKiA8bGk+IEhIWzpNTVs6U1NbLkZGRl1bel1dXQogICAgICogPGxpPiBISFs6TU1bOlNTWy5GRkZdWytISFs6TU1dXV1dCiAgICAgKiA8bGk+IEhIWzpNTVs6U1NbLkZGRl1bLUhIWzpNTV1dXV0KICAgICAqIDwvdWw+CiAgICAgKi8KICAgIFRpbWVJbmZvLlBhcnNlID0gZnVuY3Rpb24oaXNvRGF0ZVN0ciwgbG9jYWxlKXsKICAgICAgICB2YXIgc2Nhbm5lciA9IG5ldyB4ZmFsaWIudXQuU2Nhbm5lcih7anNvbk1vZGVsOntfc3RyOmlzb0RhdGVTdHJ9fSk7CiAgICAgICAgdmFyIGhvdXJzID0gc2Nhbm5lci5yZWFkSW50ZWdlcigyKTsKICAgICAgICB2YXIgbWluaXR1ZXMgPSAtMTsKICAgICAgICBpZighc2Nhbm5lci5pc0VPRigpKXsKICAgICAgICAgICAgc2Nhbm5lci5vcHRpb25hbENvbnN1bWVDaGFyKCc6Jyk7CiAgICAgICAgICAgIG1pbml0dWVzID0gc2Nhbm5lci5yZWFkSW50ZWdlcigyKTsKICAgICAgICB9CiAgICAgICAgdmFyIHNlY29uZHMgPSAtMTsKICAgICAgICBpZighc2Nhbm5lci5pc0VPRigpKXsKICAgICAgICAgICAgc2Nhbm5lci5vcHRpb25hbENvbnN1bWVDaGFyKCc6Jyk7CiAgICAgICAgICAgIHNlY29uZHMgPSBzY2FubmVyLnJlYWRJbnRlZ2VyKDIpOwogICAgICAgIH0KICAgICAgICB2YXIgbWlsbGlzZWNvbmRzID0gLTE7CiAgICAgICAgaWYoIXNjYW5uZXIuaXNFT0YoKSl7CiAgICAgICAgICAgIHNjYW5uZXIub3B0aW9uYWxDb25zdW1lQ2hhcignLScpOwogICAgICAgICAgICBtaWxsaXNlY29uZHMgPSBzY2FubmVyLnJlYWRJbnRlZ2VyKDMpOwogICAgICAgIH0KICAgICAgICAvL1RPRE8gdGltZXpvbmUKICAgICAgICB2YXIgaW5mbyA9IG5ldyB4ZmFsaWIudXQuVGltZUluZm8oKTsKICAgICAgIFRpbWVJbmZvLnNldFByb3BlcnR5SWZOb3ROdWxsKGluZm8saG91cnMsIm1Ib3VyT2ZEYXkiKTsKICAgICAgIFRpbWVJbmZvLnNldFByb3BlcnR5SWZOb3ROdWxsKGluZm8sbWluaXR1ZXMsIm1NaW51dGVPZkhvdXIiKTsKICAgICAgIFRpbWVJbmZvLnNldFByb3BlcnR5SWZOb3ROdWxsKGluZm8sc2Vjb25kcywibVNlY29uZE9mTWludXRlIik7CiAgICAgICBUaW1lSW5mby5zZXRQcm9wZXJ0eUlmTm90TnVsbChpbmZvLG1pbGxpc2Vjb25kcywibVRob3VzYW5kdGhPZlNlY29uZCIpOwogICAgICAgIHJldHVybiBpbmZvOwogICAgfTsKCiAgICAvKioKICAgICAqCiAgICAgKiBzdGF0aWMgbWV0aG9kCiAgICAgKi8KICAgIFRpbWVJbmZvLnNldFByb3BlcnR5SWZOb3ROdWxsID0gZnVuY3Rpb24ob2JqZWN0LCB2YWx1ZSwgcHJvTmFtZSl7CiAgICAgICAgaWYodmFsdWUhPW51bGwpewogICAgICAgICAgICB2YXIgZCA9IE51bWJlcih2YWx1ZSk7CiAgICAgICAgICAgIGlmKCFpc05hTihkKSl7CiAgICAgICAgICAgICAgICBvYmplY3RbcHJvTmFtZV0gPSBkOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfTsKCn0pKF8seGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5EYXRlSW5mbwogKiBAaW1wb3J0IHhmYWxpYi51dC5DbGFzcwogKiBAZmlsZU92ZXJ2aWV3IEEgd3JhcHBlciBjbGFzcyBmb3IgZGF0ZSByZWxhdGVkIGluZm9ybWF0aW9uLgogKiBAdmVyc2lvbiAwLjAuMQogKi8KCi8qKgogKiBAY29uc3RydWN0b3IKICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpIHsKICAgIHZhciBEYXRlSW5mbyA9IHhmYWxpYi51dC5EYXRlSW5mbyA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRpb25zKSB7CiAgICAgICAgICAgIGlmIChvcHRpb25zICYmICFvcHRpb25zLmlzUGFyc2luZ0NhbGwgKSB7IC8vIHNraXAgc2V0dGluZyBpbnRlcm5hbCB2YWx1ZXMgd2hlbiBjYWxsZWQgd2hpbGUgcGFyc2luZyBkYXRlIGZvcm1hdHMKICAgICAgICAgICAgICAgIHRoaXMuZGF0ZSA9IG5ldyBEYXRlKCk7CiAgICAgICAgICAgICAgICB0aGlzLl95ZWFyID0gdGhpcy5kYXRlLmdldEZ1bGxZZWFyKCk7CiAgICAgICAgICAgICAgICB0aGlzLl9tb250aCA9IHRoaXMuZGF0ZS5nZXRNb250aCgpICsgMTsKICAgICAgICAgICAgICAgIHRoaXMuX2RheSA9IHRoaXMuZGF0ZS5nZXREYXkoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBEYXRlSW5mby5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIGZvcm1hdE51bSA6IGZ1bmN0aW9uKG51bSwgZGlnaXRzKXsKICAgICAgICAgICAgaWYobnVtPDApCiAgICAgICAgICAgICAgICBudW0gPSAwOwogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYWRkaW5nKG51bSwgZGlnaXRzKTsKICAgICAgICB9LAoKICAgICAgICBnZXREYXRlIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0ZTsKICAgICAgICB9LAogICAgICAgIHNldERhdGUgOiBmdW5jdGlvbigpIHsKICAgICAgICAgIHRoaXMuZGF0ZSA9IG5ldyBEYXRlKHRoaXMuX3llYXIsdGhpcy5fbW9udGgtMSx0aGlzLl9kYXkpCiAgICAgICAgfSwKICAgICAgICBnZXRJU09EYXRlIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIGlzb0RhdGUgPSBbXTsKCiAgICAgICAgICAgIGlzb0RhdGUucHVzaCh0aGlzLmZvcm1hdE51bSh0aGlzLl95ZWFyLCA0KSk7CiAgICAgICAgICAgIGlzb0RhdGUucHVzaCgiLSIpOwogICAgICAgICAgICBpc29EYXRlLnB1c2godGhpcy5mb3JtYXROdW0odGhpcy5fbW9udGgsIDIpKTsKICAgICAgICAgICAgaXNvRGF0ZS5wdXNoKCItIik7CiAgICAgICAgICAgIGlzb0RhdGUucHVzaCh0aGlzLmZvcm1hdE51bSh0aGlzLl9kYXksIDIpKTsKCiAgICAgICAgICAgIHJldHVybiBpc29EYXRlLmpvaW4oIiIpOwogICAgICAgIH0sCgogICAgICAgIHllYXIgOiBmdW5jdGlvbih5KSB7CiAgICAgICAgICAgIGlmKHkgJiYgeSA+IDAgJiYgeSA8PSA5OTk5KQogICAgICAgICAgICAgICAgdGhpcy5feWVhciA9IHk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHRocm93ICJ1bmRlZmluZWQgeWVhciI7CiAgICAgICAgfSwKCiAgICAgICAgbW9udGggOiBmdW5jdGlvbihtKSB7CiAgICAgICAgICAgIGlmKG0gJiYgbT4wICYmIG0gPCAxMykgewogICAgICAgICAgICAgICB0aGlzLl9tb250aCA9IG07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgdGhyb3cgIkludmFsaWQgbW9udGggIiArIG07CiAgICAgICAgfSwKCiAgICAgICAgX2xlYXBZZWFyIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB5ZWFyID0gdGhpcy5feWVhcjsKICAgICAgICAgICAgcmV0dXJuIHllYXIgJSA0MDAgPT0gMCB8fCAoeWVhciAlIDEwMCAhPSAwICYmIHllYXIgJSA0ID09IDApOwogICAgICAgIH0sCgogICAgICAgIF9tYXhEYXRlIDogZnVuY3Rpb24obSkgewogICAgICAgICAgICAgIGlmKHRoaXMuX2xlYXBZZWFyKCkgJiYgbSA9PSAyKQogICAgICAgICAgICAgICAgIHJldHVybiAyOTsKICAgICAgICAgICAgICBlbHNlIHJldHVybiBEYXRlSW5mby5kYXRlc1ttLTFdOwogICAgICAgIH0sCgogICAgICAgIGRheSA6IGZ1bmN0aW9uKGQpIHsKICAgICAgICAgICAgaWYoZCAmJiBkID4gMCAmJiBkIDw9IHRoaXMuX21heERhdGUodGhpcy5fbW9udGggfHwgMCkpCiAgICAgICAgICAgICAgICB0aGlzLl9kYXkgPSBkOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB0aHJvdyAiSW52YWxpZCBEYXRlICIrIGQgKyAiIGZvciB0aGUgbW9udGggIisodGhpcy5fbW9udGgpOwogICAgICAgIH0sCgogICAgICAgIHZhbGlkYXRlIDogZnVuY3Rpb24oeSwgbSwgZCkgewogICAgICAgICAgICAgICAgdGhpcy55ZWFyKHkpOwogICAgICAgICAgICAgICAgdGhpcy5tb250aChtKTsKICAgICAgICAgICAgICAgIHRoaXMuZGF5KGQpOwogICAgICAgIH0KICAgIH0pOwoKICAgIERhdGVJbmZvLlBhcnNlSXNvU3RyaW5nID0gZnVuY3Rpb24oaXNvRGF0ZVN0ciwgbG9jYWxlKXsKCQl2YXIgaXNEYXRlUmVnZXhwID0gL14oXGR7NH0pKD86LT8oXGR7MSwyfSkoPzotPyhcZHsxLDJ9KSk/KT8oPzpUKChcZHsyfSk6KFxkezJ9KTooXGR7Mn0pKVopPyQvOwogICAgICAgIHZhciBtYXRjaCA9IGlzRGF0ZVJlZ2V4cC5leGVjKGlzb0RhdGVTdHIpOwogICAgICAgIGlmKG1hdGNoICYmIG1hdGNoLmxlbmd0aCA+PSA0KXsKICAgICAgICAgICAgdmFyIGRhdGVJbmZvID0gbmV3IERhdGVJbmZvKCk7CiAgICAgICAgICAgIHZhciBkYXRlID0gbmV3IERhdGUoaXNvRGF0ZVN0cik7CiAgICAgICAgICAgIC8vIFRPRE8gLSBjaGVjayBpZiBkYXRlIGlzIGludmFsaWQuCiAgICAgICAgICAgIGlmKG1hdGNoWzRdICYmIGRhdGUgIT0gbnVsbCkgeyAvLyBpZiB0aW1lIGlzIGF2YWlsYWJsZSB0aGVuIHVzZSBkYXRlIG9iamVjdCBmb3IgY29udmVyc2lvbiBvdGhlcndpc2UgdXNlIHByZXZpb3VzIGFwcHJvYWNoIHRvIHN1cHBvcnQgaW52YWxpZCBkYXRlIGxpa2UgMjAxMi0xMC0xMDEsIDIwMTAtMDItMjkgZXRjIGZvciBSVEMgQ1EtNDIwMTI3NAogICAgICAgICAgICAgICAgZGF0ZUluZm8ueWVhcihkYXRlLmdldEZ1bGxZZWFyKCkpOwogICAgICAgICAgICAgICAgZGF0ZUluZm8ubW9udGgoZGF0ZS5nZXRNb250aCgpKzEpOwogICAgICAgICAgICAgICAgZGF0ZUluZm8uZGF5KGRhdGUuZ2V0RGF0ZSgpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgZGF0ZUluZm8ueWVhcihOdW1iZXIobWF0Y2hbMV0pKTsKICAgICAgICAgICAgICAgICAgICBkYXRlSW5mby5tb250aChOdW1iZXIobWF0Y2hbMl0pKTsKICAgICAgICAgICAgICAgICAgICBkYXRlSW5mby5kYXkoTnVtYmVyKG1hdGNoWzNdKSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBkYXRlSW5mby5zZXREYXRlKCk7CiAgICAgICAgICAgIHJldHVybiBkYXRlSW5mbzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9OwoKICAgIERhdGVJbmZvLlBhcnNlID0gZnVuY3Rpb24oZGF0ZVN0ciwgbG9jYWxlLCB2YWxpZGF0ZVdpdGhEZWZhdWx0UGF0dGVybnMpewogICAgICAgIGxvY2FsZSA9IGxvY2FsZSB8fCAiZW5fVVMiOwogICAgICAgIHZhciBwYXR0ZXJucyA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KGxvY2FsZSwiZGF0ZVBhdHRlcm5zIiksCiAgICAgICAgICAgIGlzb0RhdGUgPSB0aGlzLlBhcnNlSXNvU3RyaW5nKGRhdGVTdHIsIGxvY2FsZSk7CiAgICAgICAgaWYoIV8uaXNFbXB0eShpc29EYXRlKSkgewogICAgICAgICAgICByZXR1cm4gaXNvRGF0ZTsgIC8vIGluIGNhc2UgZWRpdCBwYXR0ZXJuIGlzIHByZXNlbnQsIGl0J2xsIGJlIHBhcnNlZCBieSB0aGUgd2lkZ2V0IGR1cmluZyBpbnB1dCBhbmQgcmV0dXJuIGFuIGlzbyBkYXRlIHN0cmluZy4KICAgICAgICB9CiAgICAgICAgLy9pZiBlZGl0IHBhdHRlcm4gaXMgcHJlc2VudCB0aGVuIGRvbid0IHRyeSB0byBtYXRjaCBpdCBmcm9tIGRlZmF1bHQgbG9jYWxlIHBhdHRlcm5zLgogICAgICAgIGlmKHZhbGlkYXRlV2l0aERlZmF1bHRQYXR0ZXJucyA9PT0gZmFsc2UpewogICAgICAgICAgICBfLmZpbmQocGF0dGVybnMsIGZ1bmN0aW9uKHBhdHRlcm4pIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgaXNvRGF0ZSA9IHhmYWxpYi51dC5QaWN0dXJlRm10LnBhcnNlRGF0ZShkYXRlU3RyLHBhdHRlcm4sbG9jYWxlKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gY2F0Y2goZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgaXNvRGF0ZSA9IGlzb0RhdGUgfHwgZGF0ZVN0cjsKICAgICAgICByZXR1cm4gRGF0ZUluZm8uUGFyc2VJc29TdHJpbmcoaXNvRGF0ZSk7CiAgICB9OwoKICAgIERhdGVJbmZvLmRhdGVzID0gWzMxLDI4LDMxLDMwLDMxLDMwLDMxLDMxLDMwLDMxLDMwLDMxXTsKICAgIERhdGVJbmZvLmRheXNPZldlZWsgPSBbIlN1bmRheSIsIk1vbmRheSIsIlR1ZXNkYXkiLCJXZWRuZXNkYXkiLCJUaHVyc2RheSIsIkZyaWRheSIsIlNhdHVyZGF5Il07Cn0pKF8seGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5QaWN0dXJlRW5naW5lCiAqIEBpbXBvcnQgeGZhbGliLnV0LlNjYW5uZXIKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBpcyBhIGZhY2FkZSB0byBhc3NlbWJseSBhbGwgY29tcG9uZW50cyB0b2dldGhlci4KICogQHZlcnNpb24gMC4wLjEKICovCihmdW5jdGlvbihfLHhmYWxpYikgewoKICAgIHZhciBQaWN0dXJlRW5naW5lID0geGZhbGliLnV0LlBpY3R1cmVFbmdpbmUgPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKCiAgICAgICAgX2xvb2t1cE5leHQ6IHhmYWxpYi51dC5TY2FubmVyLmxvb2t1cE5leHQsCgogICAgICAgIE1BWF9YRkFfUFJFQwk6IDgsCQkvLyBNYXggbm8uIG9mIGZyYWN0aW9uYWwgZGlnaXRzIGluIFhGQS4KICAgICAgICBNQVhfREJMX0RJRwk6MTgsCQkvLyBNYXggbm8uIG9mIHNpZ25pZmljYW50IGRpZ2l0cyBpbiBhIGRvdWJsZS4KICAgICAgICBNQVhfSU5UX0RJRwk6MTAsCQkvLyBNYXggbm8uIG9mIHNpZ25pZmljYW50IGRpZ2l0cyBpbiBhbiBpbnRlZ2VyLgogICAgICAgIE1BWF9EQkxfV0lEVEgJOjE1LAkJLy8gTWF4IHdpZHRoIGJlZm9yZSBwcmVjaXNpb24gbG9zcyBpbiBhIGRvdWJsZS4KICAgICAgICBJTlRFR1JBTF9GTVQgOiAgMCwKICAgICAgICBERUNJTUFMX0ZNVCA6IDEsCiAgICAgICAgQ1VSUkVOQ1lfRk1UIDogMiwKICAgICAgICBQRVJDRU5UX0ZNVCA6IDMsCgogICAgICAgIHBhcnNlRGF0ZSA6IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLCBsb2NhbGUpewogICAgICAgICAgICByZXR1cm4gdGhpcy5fYWNjZXB0VmlzaXRvcihuZXcgeGZhbGliLnV0LkRhdGVQYXJzaW5nVmlzaXRvcih7anNvbk1vZGVsOntfc1BpY3R1cmU6c1BpY3R1cmUsX2RhdGFTdHJpbmc6c1NvdXJjZSxfbG9jYWxlOnRoaXMuanNvbk1vZGVsLmxvY2FsZX19KSk7CiAgICAgICAgfSwKCiAgICAgICAgZm9ybWF0RGF0ZSA6IGZ1bmN0aW9uKGREYXRlLCBzUGljdHVyZSl7CiAgICAgICAgICAgIHZhciB2YWxpZGF0ZVdpdGhEZWZhdWx0UGF0dGVybnMgPSB0eXBlb2Ygc1BpY3R1cmUgIT09ICd1bmRlZmluZWQnOwogICAgICAgICAgICB2YXIgZGF0ZUluZm8gPSB4ZmFsaWIudXQuRGF0ZUluZm8uUGFyc2UoZERhdGUsIHRoaXMuanNvbk1vZGVsLmxvY2FsZSwgdmFsaWRhdGVXaXRoRGVmYXVsdFBhdHRlcm5zKTsKICAgICAgICAgICAgaWYoZGF0ZUluZm8gPT0gbnVsbCl7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYWNjZXB0VmlzaXRvcihuZXcgeGZhbGliLnV0LkRhdGVGb3JtYXR0aW5nVmlzaXRvcih7anNvbk1vZGVsOntfc1BpY3R1cmU6c1BpY3R1cmUsX2RhdGVJbmZvOmRhdGVJbmZvLF9sb2NhbGU6dGhpcy5qc29uTW9kZWwubG9jYWxlfX0pKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHBhcnNlVGltZSA6IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2FjY2VwdFZpc2l0b3IobmV3IHhmYWxpYi51dC5UaW1lUGFyc2luZ1Zpc2l0b3Ioe2pzb25Nb2RlbDp7X3NQaWN0dXJlOnNQaWN0dXJlLF9kYXRhU3RyaW5nOnNTb3VyY2V9fSkpOwogICAgICAgIH0sCgogICAgICAgIGZvcm1hdFRpbWUgOiBmdW5jdGlvbihkRGF0ZSwgc1BpY3R1cmUpewogICAgICAgICAgICB2YXIgdGltZUluZm8gPSB4ZmFsaWIudXQuVGltZUluZm8uUGFyc2UoZERhdGUsIHRoaXMuanNvbk1vZGVsLmxvY2FsZSk7CiAgICAgICAgICAgIGlmKHRpbWVJbmZvID09IG51bGwpewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2FjY2VwdFZpc2l0b3IobmV3IHhmYWxpYi51dC5UaW1lRm9ybWF0dGluZ1Zpc2l0b3Ioe2pzb25Nb2RlbDp7X3NQaWN0dXJlOnNQaWN0dXJlLF90aW1lSW5mbzp0aW1lSW5mb319KSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBwYXJzZVRleHQgOiBmdW5jdGlvbihzU291cmNlLCBzUGljdHVyZSl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hY2NlcHRWaXNpdG9yKG5ldyB4ZmFsaWIudXQuVGV4dFBhcnNpbmdWaXNpdG9yKHtqc29uTW9kZWw6e19zUGljdHVyZTpzUGljdHVyZSxfZGF0YVN0cmluZzpzU291cmNlfX0pKTsKICAgICAgICB9LAoKICAgICAgICBmb3JtYXRUZXh0IDogZnVuY3Rpb24oc1NvdXJjZSwgc1BpY3R1cmUsYlJlbGF4ZWQpewogICAgICAgICAgICByZXR1cm4gdGhpcy5fYWNjZXB0VmlzaXRvcihuZXcgeGZhbGliLnV0LlRleHRGb3JtYXR0aW5nVmlzaXRvcih7anNvbk1vZGVsOntfc1BpY3R1cmU6c1BpY3R1cmUsX3RleHQ6c1NvdXJjZSxyZWxheGVkOmJSZWxheGVkfX0pKTsKICAgICAgICB9LAoKICAgICAgICBwYXJzZU51bWVyaWMgOiBmdW5jdGlvbihzU291cmNlLCBzUGljdHVyZSl7CiAgICAgICAgICAgIHZhciB2aXNpdG9yID0gbmV3IHhmYWxpYi51dC5OdW1QYXJzaW5nVmlzaXRvcih7anNvbk1vZGVsOntfc1BpY3R1cmU6c1BpY3R1cmUsX2RhdGFTdHJpbmc6c1NvdXJjZSxfbG9jYWxlOnRoaXMuanNvbk1vZGVsLmxvY2FsZX19KTsgLy8gVE9ETyA6IElzIGxvY2FsZSByZXF1aXJlZAogICAgICAgICAgICB2aXNpdG9yLnBhcnNlKCk7CiAgICAgICAgICAgIHJldHVybiB2aXNpdG9yLmdldFJlc3VsdCgpOwogICAgICAgIH0sCgogICAgICAgZm9ybWF0TnVtZXJpYyA6IGZ1bmN0aW9uKHNTb3VyY2UsIHNQaWN0dXJlLGxvY2FsZSxiUmVsYXhlZCxiRm9ybWF0TnVtYmVyRnJvbWFzRGVmYXVsdFBDKXsKCiAgICAgICAgICAgICB2YXIgc0Zvcm1hdFBpY3R1cmUgPXNQaWN0dXJlOwogICAgICAgICAgICAgaWYoIGJSZWxheGVkICYmIGJGb3JtYXROdW1iZXJGcm9tYXNEZWZhdWx0UEMpewogICAgICAgICAgICAgICAgIHNGb3JtYXRQaWN0dXJlID0gdGhpcy5nZXROdW1iZXJGb3JtYXQoc1BpY3R1cmUsMSwge2Zvcm1hdE9wdGlvbjogIldJVEhfR1JPVVBJTkdTIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicHJlY2lzaW9uIiAgOiB0aGlzLmdldE51bWJlclByZWNpc2lvbihzU291cmNlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndpZHRoIiAgICAgIDogc1NvdXJjZS5sZW5ndGgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIHJldHVybiB0aGlzLl9hY2NlcHRWaXNpdG9yKG5ldyB4ZmFsaWIudXQuTnVtRm9ybWF0dGluZ1Zpc2l0b3Ioe2pzb25Nb2RlbDp7X3NQaWN0dXJlOnNGb3JtYXRQaWN0dXJlLF9sb2NhbGU6dGhpcy5qc29uTW9kZWwubG9jYWxlfSx0ZXh0OnNTb3VyY2V9KSk7CiAgICAgICAgfSwKCiAgICAgICAgX2FjY2VwdFZpc2l0b3IgOiBmdW5jdGlvbih2aXNpdG9yKXsKICAgICAgICAgICAgdGhpcy5fc2NhblBhdHRlcm4odmlzaXRvcik7CiAgICAgICAgICAgIHJldHVybiB2aXNpdG9yLmdldFJlc3VsdCgpOwogICAgICAgIH0sCgogICAgICAgIF9zY2FuUGF0dGVybiA6IGZ1bmN0aW9uKHZpc2l0b3IpewogICAgICAgICAgICB2YXIgcGF0UG9zID0gMDsKICAgICAgICAgICAgdmFyIHNQaWN0dXJlID0gdmlzaXRvci5nZXRQaWN0dXJlKCk7CiAgICAgICAgICAgIGZvcih2YXIgdG9rZW4gPSB0aGlzLl9sb29rdXBOZXh0KHNQaWN0dXJlLCBwYXRQb3MsIHZpc2l0b3IuYWNjZXB0UGF0dGVybkNoYXIpOyB0b2tlbiAhPSBudWxsOyAgKXsKICAgICAgICAgICAgICAgIHZpc2l0b3IuY29uc3VtZSh0b2tlbik7CiAgICAgICAgICAgICAgICBwYXRQb3MgPSBwYXRQb3MgKyB0b2tlbi5sZW47CiAgICAgICAgICAgICAgICB0b2tlbiA9IHRoaXMuX2xvb2t1cE5leHQoc1BpY3R1cmUsIHBhdFBvcywgdmlzaXRvci5hY2NlcHRQYXR0ZXJuQ2hhcik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgIC8qKgogICAgICAgICAgKiBSZW1vdmVzIG4gYnl0ZXMgZnJvbSB0aGlzIHN0cmluZyBzdGFydGluZyBhdCBwb3NpdGlvbiBuT2Zmc2V0LgogICAgICAgICAqCiAgICAgICAgICAqIEBwYXJhbSBuT2Zmc2V0IC0gc3RhcnQgcG9zaXRpb24gZm9yIHRoZSByZW1vdmUKICAgICAgICAgICogQHBhcmFtIG5MZW5ndGggLSB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gcmVtb3ZlCiAgICAgICAgICAqIEByZXR1cm4gVGhpcyBzdHJpbmcKICAgICAgICAgICovCgogICAgICAgICBfc3dhbGxvdyA6IGZ1bmN0aW9uKHNTdHJpbmcgLCBuT2Zmc2V0LCBuTGVuVG9Td2FsbG93KQogICAgICAgICB7CiAgICAgICAgICAgICBpZihfLmlzRW1wdHkoc1N0cmluZykgfHwgbkxlblRvU3dhbGxvdyA9PTApewogICAgICAgICAgICAgICAgIHJldHVybiBzU3RyaW5nOwogICAgICAgICAgICAgfQoKICAgICAgICAgICAgIGlmKCAobk9mZnNldCArIG5MZW5Ub1N3YWxsb3cpPiBzU3RyaW5nLmxlbmd0aCApIHsKICAgICAgICAgICAgICAgICBuTGVuVG9Td2FsbG93ID0gKG5PZmZzZXQgKyBuTGVuVG9Td2FsbG93KSAtIHNTdHJpbmcubGVuZ3RoOwogICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgc3ViU3RyID0gc1N0cmluZy5zdWJzdHIoMCxuT2Zmc2V0KSArIHNTdHJpbmcuc3Vic3RyKG9mZnNldCArIG5MZW5Ub1N3YWxsb3cpOwoKICAgICAgICAgICAgIHJldHVybiBzdWJTdHIKICAgICAgICAgfSwKICAgICAgICAgLyoqCiAgICAgICAgICogUmVwbGFjZSBzb21lIHBvcnRpb24gb2Ygb25lIHN0cmluZyB3aXRoIGFub3RoZXIgU3RyaW5nLgogICAgICAgICAgKiBAcGFyYW0gc1N0cmluZyAtIHRoZSBTdHJpbmcgd2hlcmUgaXQgaGFzIHRvIGJlIHJlcGxhY2VkLgogICAgICAgICAgKiBAcGFyYW0gc1JlcGxhY2VtZW50IC0gdGhlIHJlcGxhY2VtZW50IHN0cmluZy4KICAgICAgICAgICogQHBhcmFtIG5PZmZzZXQgLSBzdGFydCBwb3NpdGlvbiBmb3IgdGhlIHJlcGxhY2VtZW50LiBEZWZhdWx0IHZhbHVlID0gMC4KICAgICAgICAgICogQHBhcmFtIG5DdXRMZW5ndGggLSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHJlbW92ZSBmcm9tIHRoZQogICAgICAgICAgKiBvcmlnaW5hbCBzdHJpbmcuCiAgICAgICAgICAqLwoKICAgICAgICAgX3JlcGxhY2VBbGwgOiBmdW5jdGlvbihzU3RyaW5nICxzUmVwbGFjZW1lbnQgLCBuT2Zmc2V0ICxuQ3V0bGVuZ3RoKSB7CiAgICAgICAgICAgICByZXR1cm4gc1N0cmluZy5zdWJzdHIoMCxuT2Zmc2V0KSArIHNSZXBsYWNlbWVudCAgKyBzU3RyaW5nLnN1YnN0cihuT2Zmc2V0ICsgbkN1dGxlbmd0aCkKICAgICAgICAgfSwKCiAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAvLyBTa2lwT3ZlcgogICAgICAgICAvLwogICAgICAgICAvLyBTY2FuIHRoaXMgc3RyaW5nIGZvciB0aGUgZmlyc3QgYnl0ZSBvZiB0aGUgY2hhcmFjdGVyIG5vdCBpbiB0aGUgZ2l2ZW4gc2V0LgogICAgICAgICAvLyBTaW1pbGFyIHRvIHN0cnNwbigpLgogICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgX3NraXBPdmVyIDogZnVuY3Rpb24oZnJvbVN0cmluZyxzU2tpcCwgbk9mZnNldCkKICAgICAgICAgewogICAgICAgICAgICAgLy8gc3RhcnRpbmcgYXQgdGhlIG9mZnNldCBwb3NpdGlvbiwgc2NhbiB0aGUgY2hhcmFjdGVycyBpbiB0aGlzIHN0cmluZwogICAgICAgICAgICAgLy8gdW50aWwgaXQgZG9lcyBub3QgbWF0Y2ggYW55IG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBnaXZlbiBzZXQuCiAgICAgICAgICAgIHZhciBuQ2hhcnNTa2lwcGVkID0gbk9mZnNldDsKICAgICAgICAgICAgIHZhciBpID0gMDsKICAgICAgICAgICAgIHdoaWxlIChuQ2hhcnNTa2lwcGVkIDwgZnJvbVN0cmluZy5sZW5ndGgpCiAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgaSA9IG5DaGFyc1NraXBwZWQ7CiAgICAgICAgICAgICAgICAgaWYgKHNTa2lwLmluZGV4T2YoZnJvbVN0cmluZ1tpXSkgPT0tMSkgewogICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgaSsrOwogICAgICAgICAgICAgICAgIG5DaGFyc1NraXBwZWQgPSBpOwogICAgICAgICAgICAgfQoKICAgICAgICAgICAgIHJldHVybiBuQ2hhcnNTa2lwcGVkIC0gbk9mZnNldDsKICAgICAgICAgfSwKCiAgICAgICAgIC8qCiAgICAgICAgICAqIEdldCB0aGUgbnVtZXJpYyBmb3JtYXQgaW4gdGhlIGdpdmVuIHN0eWxlLgogICAgICAgICAgKiBAcGFyYW0gc3R5bGUgaW4gdGhlIHJhbmdlIG9mIHZhbHVlcyAwLTIsCiAgICAgICAgICAqIHdoZXJlICgwID0gaW50ZWdyYWwsIDEgPSBkZWNpbWFsLCAyID0gY3VycmVuY3kpLgogICAgICAgICAgKiBAcGFyYW0gb3B0aW9uIGluIHRoZSBzZXQgb2YgZm9ybWF0IG9wdGlvbnM6CiAgICAgICAgICAqLwogICAgICAgICBnZXROdW1iZXJGb3JtYXQgOiBmdW5jdGlvbihmb3JtYXQgLCBzdHlsZSwgb3B0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgIGlmIChzdHlsZSA8IHRoaXMuSU5URUdSQUxfRk1UIHx8IHRoaXMuUEVSQ0VOVF9GTVQgPCBzdHlsZSkgewogICAgICAgICAgICAgICAgIHN0eWxlID0gdGhpcy5ERUNJTUFMX0ZNVDsKICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICB2YXIgc0Zvcm1hdCA9IGZvcm1hdDsKCiAgICAgICAgICAgICAvLwogICAgICAgICAgICAgLy8gVXNlIGFueSBhbHRlcm5hdGUgcGFydCBiZWNhdXNlIHRoZXkgaGFuZGxlIG5lZ2F0aXZlIHZhbHVlcy4KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICB2YXIgIG5CYXIgPSAwOwogICAgICAgICAgICAgaWYgKChuQmFyID0gc0Zvcm1hdC5pbmRleE9mKCd8JykpICE9IC0xKSB7CiAgICAgICAgICAgICAgICAgc0Zvcm1hdCA9IHRoaXMuX3N3YWxsb3coc0Zvcm1hdCwgMCwgbkJhciArIDEpOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgLy8KICAgICAgICAgICAgIC8vIERldGVybWluZSBwb3NpdGlvbiBvZiByYWRpeCAob3IgYW55dGhpbmcgbGlrZSBpdCkKICAgICAgICAgICAgIC8vIGFuZCB0aGUgcmVwbGljYXRpbmcgcGFydCBvZiB0aGUgcGF0dGVybiwgaS5lLiwgZnJvbQogICAgICAgICAgICAgLy8gdGhlIHNlcGFyYXRvciB0byB0aGlzIHJhZGl4LgogICAgICAgICAgICAvLwogICAgICAgICAgICAgdmFyIG5Eb3Q7CiAgICAgICAgICAgICBpZiAoIChuRG90ID0gc0Zvcm1hdC5pbmRleE9mKCcuJykpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgaWYgKChuRG90ID0gc0Zvcm1hdC5pbmRleE9mKCd2JykpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgIGlmICgobkRvdCA9IHNGb3JtYXQuaW5kZXhPZignVicpKSA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChuRG90ID0gc0Zvcm1hdC5pbmRleE9mKCdFJykpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChuRG90ID0gc0Zvcm1hdC5pbmRleE9mKCcgJykpID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgobkRvdCA9IHNGb3JtYXQuaW5kZXhPZignJScpKSA9PSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkRvdCA9IHNGb3JtYXQubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgICAgaWYgKG5Eb3QpIHsKICAgICAgICAgICAgICAgICBpZiAodGhpcy5fc2tpcE92ZXIoc0Zvcm1hdCwiODl6WiIsIG5Eb3QgLSAxKSAhPSAxKSB7CiAgICAgICAgICAgICAgICAgICAgIG5Eb3QgPSBzRm9ybWF0Lmxlbmd0aDsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICB2YXIgc1paWjsKICAgICAgICAgICAgIHZhciBuWmVkOwogICAgICAgICAgICAgaWYgKCAoblplZCA9IHNGb3JtYXQuaW5kZXhPZigieiwiKSkgIT0gLTEpIHsKICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgIC8vIFdhdHNvbiAxMjMwNzY4LiAgSGFuZGxlIGxvY2FsZXMsIGxpa2UgSW5kaWEsIHRoYXQgaGF2ZQogICAgICAgICAgICAgICAgIC8vIHBpY3R1cmVzIHdpdGggbW9yZSB0aGFuIG9uZSBncm91cGluZyBzeW1ib2wuCiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgIHZhciBuU2VwID0gbkRvdDsKICAgICAgICAgICAgICAgICB2YXIgbkNvbW1hOwogICAgICAgICAgICAgICAgIGlmICgobkNvbW1hID0gc0Zvcm1hdC5pbmRleE9mKCcsJywgblplZCArIDIpKSAhPS0xKSB7CiAgICAgICAgICAgICAgICAgICAgblNlcCA9IG5Db21tYTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgaWYgKG5TZXAgPiBuWmVkICsgMikgewogICAgICAgICAgICAgICAgICAgICBzWlpaID0gQXJyYXkoblNlcCAtIG5aZWQpLmpvaW4oJ3onKTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgIHNaWlogPSBBcnJheSgxKS5qb2luKCd6Jyk7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBuWmVkID0gMDsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAvLyBJZiBub24taW50ZWdyYWwgc3R5bGVzIFRoZW4gZGV0ZXJtaW5lIHdpZHRoIGFuZCBwcmVjaXNpb24uCiAgICAgICAgICAgICAvLwogICAgICAgICAgICAgdmFyIG5QcmVjID0gMDsKICAgICAgICAgICAgIHZhciBuV2lkdGggPSB0aGlzLk1BWF9JTlRfRElHOwogICAgICAgICAgICAgaWYgKHN0eWxlICE9IHRoaXMuSU5URUdSQUxfRk1UKSB7CiAgICAgICAgICAgICAgICAgblByZWMgPSBvcHRpb24ucHJlY2lzaW9uOyAvLyAob3B0aW9uID4+IDgpICYgMHhmZjsKICAgICAgICAgICAgICAgICB2YXIgdHJpbSA9ICgoblByZWMgJiAweDgwKSA9PSAwKTsKICAgICAgICAgICAgICAgICBuUHJlYyAmPSAweDdmOwogICAgICAgICAgICAgICAgIGlmIChuUHJlYyA9PSAweDdmKSB7CiAgICAgICAgICAgICAgICAgICAgIG5QcmVjID0gdGhpcy5fc2tpcE92ZXIoc0Zvcm1hdCwgIjg5eloiLCBuRG90ICsgMSk7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIGlmICgob3B0aW9uLndpZHRoKSAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICAgbldpZHRoID0gb3B0aW9uLndpZHRoOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgbldpZHRoID0gdGhpcy5NQVhfREJMX0RJRzsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAvLyBGaXggZm9yIFdhdHNvbiAxMjI5NDIzLiAgSWYgdGhlIGxvY2FsZSdzIGZvcm1hdCBjb250YWlucwogICAgICAgICAgICAgICAgIC8vIGFueSBzaWduIHBpY3R1cmVzIFRoZW4gd2lkZW4gYWNjb3JkaW5nbHkuICBBbHNvIHdpZGVuIGlmCiAgICAgICAgICAgICAgICAgLy8gcHJlY2lzaW9uIG9mIGxvY2FsZSdzIHBpY3R1cmUgZm9ybWF0IGlzIGdyZWF0ZXIgdGhhbiByZXF1ZXN0ZWQuCiAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICBpZiAoc0Zvcm1hdC5pbmRleE9mKCdzJykhPS0xKSB7CiAgICAgICAgICAgICAgICAgICAgIG5XaWR0aCArPSAxOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICBpZiAoc0Zvcm1hdC5pbmRleE9mKCcoJykhPS0xKSB7CiAgICAgICAgICAgICAgICAgICAgIG5XaWR0aCArPSAxOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICBpZiAoc0Zvcm1hdC5pbmRleE9mKCcpJykgIT0tMSkgewogICAgICAgICAgICAgICAgICAgICBuV2lkdGggKz0gMTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgbkZtdFByZWMgPSB0aGlzLl9za2lwT3ZlcihzRm9ybWF0LCI4OXpaIiwgbkRvdCArIDEpOwogICAgICAgICAgICAgICAgIGlmICgwIDwgblByZWMgJiYgblByZWMgPCBuRm10UHJlYykgewogICAgICAgICAgICAgICAgICAgICBuV2lkdGggKz0gbkZtdFByZWMgLSBuUHJlYzsKICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgLy8gUGFyZSBkb3duIHRoZSBwcmVjaXNpb24gaWYgdGhlIHdpZHRoIGlzIGJpZyBlbm91Z2ggdG8geWllbGQKICAgICAgICAgICAgICAgICAvLyBJRUVFIDc1NCA2NC1iaXQgZG91YmxlIHByZWNpc2lvbiBlcnJvcnMsIHdoaWNoIGFwcGVhcnMgdG8gYmUKICAgICAgICAgICAgICAgICAvLyBhbnl0aGluZyBvdmVyIDE0IHNpZ25pZmljYW50IGRpZ2l0cy4KICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgIGlmICh0cmltICYmIG5QcmVjID4gMCAmJiBuV2lkdGggPiBuUHJlYykgewogICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgICAvLyBGaXggZm9yIFdhdHNvbiAxMjExNDgxLiAgSWYgdGhlIGdpdmVuIHByZWNpc2lvbiBpcyBsZXNzCiAgICAgICAgICAgICAgICAgICAgIC8vIHRoYW4gd2hhdCB0aGUgbG9jYWxlJ3MgZm9ybWF0IGRpY3RhdGVzIHRoZW4gd2lkZW4gdGhlIGdpdmVuCiAgICAgICAgICAgICAgICAgICAgIC8vIHdpZHRoLgogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgIGlmIChuUHJlYyA8PSBzRm9ybWF0Lmxlbmd0aCAtIDEgLSBuRG90KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICBuV2lkdGggKz0gc0Zvcm1hdC5sZW5ndGggLSAxIC0gbkRvdCAtIG5QcmVjOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSBuV2lkdGggLSAxOyBpID4gdGhpcy5NQVhfREJMX1dJRFRIOyBpLS0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgICAgICAvLyBOZXZlciBwYXJlIGRvd24gdGhlIHByZWNpc2lvbiBiZWxvdyB3aGF0IHRoZSBsb2NhbGUncwogICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9ybWF0IGRpY3RhdGVzLgogICAgICAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuUHJlYyA8PSBzRm9ybWF0Lmxlbmd0aCAtIDEgLSBuRG90KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICBuUHJlYy0tOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgICAgLy9XYXRzb24gMTQ4MzY3NSAtIElmIHRoZSBsb2NhbGUncyBmb3JtYXQgY29udGFpbnMKICAgICAgICAgICAgIC8vIGEgZG9sbGFyIHNpZ24gb3IgYSBzcGFjZSB0aGVuIHdpZGVuIGFjY29yZGluZ2x5LgogICAgICAgICAgICAgaWYgKHN0eWxlID09IHRoaXMuQ1VSUkVOQ1lfRk1UKSB7CiAgICAgICAgICAgICAgICAgaWYgKHNGb3JtYXQuaW5kZXhPZignJCcpIT0tMSkgewogICAgICAgICAgICAgICAgICAgICBuV2lkdGgrKzsKICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIGlmIChzRm9ybWF0LmluZGV4T2YoJyAnKSE9LTEpIHsKICAgICAgICAgICAgICAgICAgICAgbldpZHRoICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CgogICAgICAgICAgICAgLy8KICAgICAgICAgICAgIC8vIElmIHBlcmNlbnQgc3R5bGUgd2FzIHdhbnRlZCBUaGVuIHRydW5jYXRlIGFmdGVyIHRoZSBwZXJjZW50IGNoYXJhY3Rlci4KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICBpZiAoc3R5bGUgPT0gdGhpcy5QRVJDRU5UX0ZNVCkgewogICAgICAgICAgICAgICAgIHZhciBuVHJpbSA9IHRoaXMuX3NraXBPdmVyKHNGb3JtYXQsIjg5eloiLCBuRG90ICsgMSk7CiAgICAgICAgICAgICAgICAgc0Zvcm1hdCA9IHRoaXMuX3JlcGxhY2VBbGwoc0Zvcm1hdCwiIixuVHJpbSwwKQogICAgICAgICAgICAgICAgIC8vc0Zvcm1hdC5SZXBsYWNlKGpmU3RyaW5nOjpFbXB0eVN0cmluZygpLCBuRG90ICsgMSwgblRyaW0pOwoKICAgICAgICAgICAgICAgICAvL1dhdHNvbiAxNDgzNjc1IC0gSWYgdGhlIGxvY2FsZSdzIGZvcm1hdCBjb250YWlucwogICAgICAgICAgICAgICAgIC8vIGEgcGVyY2VudCBzaWduIHRoZW4gd2lkZW4gYWNjb3JkaW5nbHkuCiAgICAgICAgICAgICAgICAgaWYgKHNGb3JtYXQuaW5kZXhPZignJScpIT0tMSkgewogICAgICAgICAgICAgICAgICAgICBuV2lkdGgrKzsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICAvLwogICAgICAgICAgICAgLy8gRWxzZSBpZiBpbnRlZ3JhbCBzdHlsZSB3YXMgd2FudGVkIFRoZW4gdHJ1bmNhdGUgYXQgdGhlIHJhZGl4IGNoYXJhY3Rlci4KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAvLwogICAgICAgICAgICAgLy8gSWYgaW50ZWdyYWwgc3R5bGUgd2FzIHdhbnRlZCBUaGVuIHRydW5jYXRlIGF0IHRoZSByYWRpeCBjaGFyYWN0ZXIuCiAgICAgICAgICAgICAvLwogICAgICAgICAgICAgZWxzZSBpZiAoc3R5bGUgPT0gdGhpcy5JTlRFR1JBTF9GTVQgfHwgblByZWMgPT0gMCl7Ly8gJiYgb3B0aW9uLmZvcm1hdE9wdGlvbiA9PSAiV0lUSE9VVF9SQURJWCIpIHsKICAgICAgICAgICAgICAgICB2YXIgblRyaW0gPSB0aGlzLl9za2lwT3ZlcihzRm9ybWF0LCI4OXpaIiwgbkRvdCArIDEpOwogICAgICAgICAgICAgICAgIHNGb3JtYXQgPSB0aGlzLl9yZXBsYWNlQWxsKHNGb3JtYXQsIiIsbkRvdCxuVHJpbSsxKTsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAvLyBPdGhlcndpc2UgZm9yIGRlY2ltYWwgYW5kIGN1cnJlbmN5IHN0eWxlcyBEbwogICAgICAgICAgICAgLy8gcmVwbGFjZSBmcmFjdGlvbmFsICd6JyBwaWN0dXJlcyB3aXRoICc4J3MgdG8gcmVxdWVzdGVkIHByZWNpc2lvbiwKICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICBlbHNlIGlmIChvcHRpb24uZm9ybWF0T3B0aW9uID09ICJXSVRIX0VJR0hUUyIpIHsKICAgICAgICAgICAgICAgICB2YXIgbkVpZ2h0ID0gbkRvdCArIDE7CiAgICAgICAgICAgICAgICAgd2hpbGUgKChuRWlnaHQgPXNGb3JtYXQuaW5kZXhPZigneicpKSE9LTEpIHsKICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVwbGFjZUFsbChzRm9ybWF0LCAnOCcsIG5FaWdodCwnOCcubGVuZ3RoKTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgd2hpbGUgKHNGb3JtYXQuTGVuZ3RoKCkgLSBuRG90IDw9IG5QcmVjKSB7CiAgICAgICAgICAgICAgICAgICAgIHNGb3JtYXQgPSB0aGlzLl9yZXBsYWNlQWxsKHNGb3JtYXQsICI4IiwgbkRvdCArIDEsIDApOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgIH0KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAvLyBPciByZXBsYWNlIGZyYWN0aW9uYWwgJzknIHBpY3R1cmVzIHdpdGggJ3oncyB0byByZXF1ZXN0ZWQgcHJlY2lzaW9uCiAgICAgICAgICAgICAvLyBXYXRzb24gMTMyMjg1MCAtIGFkZCBvcHRpb24gdG8ga2VlcCBuaW5lcywgcHJldmlvdXNseSB0aGlzIGZ1bmN0aW9uCiAgICAgICAgICAgICAvLyB3b3VsZCBmb3JjZSBmcmFjLiBkaWdpdHMgdG8gYmUgZWl0aGVyIHoncyBvciA4J3Mgd2l0aCBubyBvcHRpb24gZm9yIDkncy4KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICBlbHNlIGlmICgob3B0aW9uLmZvcm1hdE9wdGlvbikgPT0gIldJVEhfWkVEUyIgJiYgISgob3B0aW9uLmZvcm1hdE9wdGlvbikgPT0gIktFRVBfTklORVMiKSkgewogICAgICAgICAgICAgICAgIHZhciBuTmluZSA9IG5Eb3QgKyAxOwogICAgICAgICAgICAgICAgIHdoaWxlICgobk5pbmUgPSBzRm9ybWF0LmluZGV4T2YoJzknKSkhPS0xKSB7CiAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlcGxhY2VBbGwoc0Zvcm1hdCwgJ3onLCBuTmluZSwxKTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgd2hpbGUgKHNGb3JtYXQuTGVuZ3RoKCkgLSBuRG90IDw9IG5QcmVjKSB7CiAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlcGxhY2VBbGwoc0Zvcm1hdCwgInoiLCBuRG90ICsgMSwgMCk7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgICAgLy8KICAgICAgICAgICAgIC8vIFJlcGxpY2F0ZSBzZWN0aW9uIGZyb20gc2VwYXJhdG9yIHRvIHJhZGl4IHRvIHJlcXVlc3RlZCB3aWR0aC4KICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICBpZiAoIXNaWlopIHsKICAgICAgICAgICAgICAgICBzWlpaID0gInoiOwogICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICgob3B0aW9uLmZvcm1hdE9wdGlvbikgPT0gIldJVEhPVVRfR1JPVVBJTkdTIiApIHsKICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgIC8vIFdhdHNvbiAxMjMwNzY4LiAgSGFuZGxlIGxvY2FsZXMsIGxpa2UgSW5kaWEsIHRoYXQgaGF2ZQogICAgICAgICAgICAgICAgIC8vIHBpY3R1cmVzIHdpdGggbW9yZSB0aGFuIG9uZSBncm91cGluZyBzeW1ib2wuCiAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICB2YXIgbkNvbW1hID0gblplZCArIDEgOwogICAgICAgICAgICAgICAgIHRoaXMuX3JlcGxhY2VBbGwoc0Zvcm1hdCwgJ3onICxuQ29tbWEsMSk7CiAgICAgICAgICAgICAgICAgd2hpbGUgKCBuQ29tbWEhPSAtMSAmJiAobkNvbW1hIDwgbkRvdCkpIHsKICAgICAgICAgICAgICAgICAgICAgbkNvbW1hID0gc0Zvcm1hdC5pbmRleE9mKCcsJyk7CiAgICAgICAgICAgICAgICAgICAgIHNGb3JtYXQgPSB0aGlzLl9yZXBsYWNlQWxsKHNGb3JtYXQsJ3onLG5Db21tYSwxKTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICBlbHNlIGlmICgob3B0aW9uLmZvcm1hdE9wdGlvbiA9PSAiV0lUSF9HUk9VUElOR1MiKSkgewogICAgICAgICAgICAgICAgIHNaWlogPSB0aGlzLl9yZXBsYWNlQWxsKHNaWlosJywnLDAsMSk7CiAgICAgICAgICAgICAgICAgbldpZHRoICs9IChuV2lkdGggKyBzWlpaLmxlbmd0aCkgLyBzWlpaLmxlbmd0aDsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIHdoaWxlIChzRm9ybWF0Lmxlbmd0aCA8IG5XaWR0aCkgewogICAgICAgICAgICAgICAgIHNGb3JtYXQgPSB0aGlzLl9yZXBsYWNlQWxsKHNGb3JtYXQsIHNaWlosIG5aZWQgKyAxLCAwKTsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIHJldHVybiBzRm9ybWF0OwogICAgICAgICB9LAoKICAgICAgICAgLyoqCiAgICAgICAgICAqIEdldCB0aGUgZGVjaW1hbCBwcmVjaXNpb24gb2YgdGhlIGdpdmVuIG51bWVyaWMgc3RyaW5nLgogICAgICAgICAgKiBAcmV0dXJuIHRoZSBkZWNpbWFsIHByZWNpc2lvbiBvciAwIGZvciBpbnRlZ3JhbCB2YWx1ZXMuCiAgICAgICAgICAqLwogICAgICAgICBnZXROdW1iZXJQcmVjaXNpb246IGZ1bmN0aW9uKHNWYWwpCiAgICAgICAgIHsKICAgICAgICAgICAgIHZhciBuUmFkaXggPSAwOwogICAgICAgICAgICAgdmFyIGkgPSAtMTsKICAgICAgICAgICAgIC8vIFJlYXNvbiBmb3Igbm90IHVzaW5nIHRoZSBjb21tZW50ZWQgbGluZS4gV2UgYXJlIGFsd2F5cyBzdG9yaW5nIHRoZSB2YWx1ZSBpbiBtb2RlbCB3aXRoIC4gYXMgZGVjaW1hbCBzZXBhcmF0b3IKICAgICAgICAgICAgIC8vIFBhc3NpbmcgZmllbGQgbG9jYWxlLyBicm93c2VyIGxvY2FsZSB3b3VsZCBsZWFkIHRvIHByZWNpc2lvbiB3aWR0aCBiZWluZyB6ZXJvIGZvciBub24tZW5nbGlzaCBsb2NhbGVzIHdoZXJlCiAgICAgICAgICAgICAvLyBkZWNpbWFsIHNlcGFyYXRlciBtYXkgYmUgZGlmZmVyZW50LgogICAgICAgICAgICAgLy8gdmFyIHJJbmRleCA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KHRoaXMuanNvbk1vZGVsLmxvY2FsZSwibnVtYmVyU3ltYm9scyIpLmRlY2ltYWw7CiAgICAgICAgICAgICAvLyBzbyBoYXJkY29kaW5nIC4gZm9yIG5vdwogICAgICAgICAgICAgdmFyIHJJbmRleCA9ICIuIjsKICAgICAgICAgICAgIGlmKCAoblJhZGl4ID0gc1ZhbC5pbmRleE9mKHJJbmRleCkpIT0tMSkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgZm9yKDsgblJhZGl4IDw9c1ZhbC5sZW5ndGggO25SYWRpeCsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgIH0KICAgIH0pCn0pKF8seGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5Gb3JtYXR0aW5nVmlzaXRvckJhc2UKICogQGltcG9ydCB4ZmFsaWIudXQuVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBCYXNlIGNsYXNzIGZvciB2aXNpdG9yCiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKLyoqCiAqIEBjb25zdHJ1Y3RvcgogKiBAcGFyYW0gT2JqZWN0IHtqc29uTW9kZWw6IHtfc1BpY3R1cmU6IFN0cmluZ119CiAqLwoKKGZ1bmN0aW9uKF8seGZhbGliKSB7CiAgICB2YXIgRm9ybWF0dGluZ1Zpc2l0b3JCYXNlID0geGZhbGliLnV0LkZvcm1hdHRpbmdWaXNpdG9yQmFzZSA9IHhmYWxpYi51dC5WaXNpdG9yQmFzZS5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdGhpcy5fYnVmZmVyID0gW107IC8vVE9ETzogQVNLIFJlbiB3aGVyZSBkb2VzIHRoaXMgX2J1ZmZlciBjb21lcyBmcm9tCiAgICAgICAgICAgIEZvcm1hdHRpbmdWaXNpdG9yQmFzZS5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIGNvbnN1bWVTdHJpbmdXaWxkQ2FyZCA6IGZ1bmN0aW9uKHRva2VuKXsKICAgICAgICAgICAgLy8nPycgJyonICcrCiAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKCIgIik7CiAgICAgICAgfSwKCiAgICAgICAgY29uc3VtZVN0cmluZ0xpdGVyYWwgOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5zdWJzdHIodG9rZW4uc3RhcnRQb3MrMSx0b2tlbi5sZW4tMikpOwogICAgICAgIH0sCgogICAgICAgIGNvbnN1bWVDaGFyTGl0ZXJhbCA6IGZ1bmN0aW9uKHRva2VuKXsKICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goIiIrIHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5jaGFyQXQodG9rZW4uc3RhcnRQb3MpKTsKICAgICAgICB9CiAgICB9KQoKfSkoXyx4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlBhcnNpbmdWaXNpdG9yQmFzZQogKiBAaW1wb3J0IHhmYWxpYi51dC5WaXNpdG9yQmFzZQogKiBAZmlsZU92ZXJ2aWV3IEJhc2UgY2xhc3MgZm9yIHZpc2l0b3IKICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nLF9kYXRhU3RyaW5nOiBTdHJpbmd9fQogKi8KCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgUGFyc2luZ1Zpc2l0b3JCYXNlID0geGZhbGliLnV0LlBhcnNpbmdWaXNpdG9yQmFzZSA9IHhmYWxpYi51dC5WaXNpdG9yQmFzZS5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdGhpcy5fc3RyTGVuID0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcubGVuZ3RoOwogICAgICAgICAgICB0aGlzLl9zdHJQb3MgPSAwOwogICAgICAgICAgICBQYXJzaW5nVmlzaXRvckJhc2UuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICB9LAoKICAgICAgICBjb25zdW1lU3RyaW5nV2lsZENhcmQgOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgICAgIGlmIChjaHIgPT0gJz8nKSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RyUG9zIDwgdGhpcy5fc3RyTGVuKS8vJiYgQ2hhcmFjdGVyLmlzRGVmaW5lZChzdHIuY2hhckF0KHN0clBvcykpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RyUG9zICs9IDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hyID09ICcrJykgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX3N0clBvcyA+PSB0aGlzLl9zdHJMZW4pLy8gfHwgISBDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKHN0ci5jaGFyQXQoc3RyUG9zKSkpCiAgICAgICAgICAgICAgICAgICAgdGhyb3cgIk1pc21hdGNoIjsKICAgICAgICAgICAgICAgIHRoaXMuX3N0clBvcyArPSAxOwogICAgICAgICAgICAgICAgd2hpbGUgKHRoaXMuX3N0clBvcyA8IHRoaXMuX3N0ckxlbikvLyAmJiBDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKHN0ci5jaGFyQXQoc3RyUG9zKSkpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RyUG9zICs9IDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hyID09ICcqJykgewogICAgICAgICAgICAgICAgd2hpbGUgKHRoaXMuX3N0clBvcyA8IHRoaXMuX3N0ckxlbikvLyAmJiBDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKHN0ci5jaGFyQXQoc3RyUG9zKSkpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RyUG9zICs9IDE7CiAgICAgICAgICAgIH0KCiAgICAgICAgfSwKCiAgICAgICAgY29uc3VtZVN0cmluZ0xpdGVyYWwgOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgICAgIGZvcih2YXIgb2Zmc2V0PTA7IG9mZnNldDx0b2tlbi5sZW4tMiA7b2Zmc2V0KyspeyAvLy0yLCBoZWFkaW5nIGFuZCB0cmFpbGluZyBxdW90ZQogICAgICAgICAgICAgICAgaWYodGhpcy5qc29uTW9kZWwuX3NQaWN0dXJlLmNoYXJBdCh0b2tlbi5zdGFydFBvcytvZmZzZXQrMSkgIT0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcuY2hhckF0KHRoaXMuX3N0clBvcytvZmZzZXQpKXsKICAgICAgICAgICAgICAgICAgICB0aHJvdyAoIk1pc21hdGNoIiArIHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5zdWJzdHIodG9rZW4uc3RhcnRQb3MsIHRva2VuLmxlbikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuX3N0clBvcyArPSB0b2tlbi5sZW4tMjsKCiAgICAgICAgfSwKCiAgICAgICAgY29uc3VtZUNoYXJMaXRlcmFsIDogZnVuY3Rpb24odG9rZW4pewogICAgICAgICAgICBpZih0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmUuY2hhckF0KHRva2VuLnN0YXJ0UG9zKSA9PSB0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy5jaGFyQXQodGhpcy5fc3RyUG9zKSl7CiAgICAgICAgICAgICAgICB0aGlzLl9zdHJQb3MgKz0gMTsKICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICB0aHJvdyAiTWlzbWF0Y2giOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSkKfSkoXyx4ZmFsaWIpOwoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5EYXRlRm9ybWF0dGluZ1Zpc2l0b3IKICogQGltcG9ydCB4ZmFsaWIudXQuRm9ybWF0dGluZ1Zpc2l0b3JCYXNlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgcHJvdmlkZXMgZm9ybWF0aW5nIGxvZ2ljIG9uIGRhdGUgcGF0dGVybiBjaGFyYWN0ZXJzLgogKiBAdmVyc2lvbiAwLjAuMQogKi8KCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBvYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTpTdHJpbmcsX2RhdGVJbmZvOiB4ZmFsaWIudXQuRGF0ZUluZm99fQogKi8KCihmdW5jdGlvbihfLHhmYWxpYikgewogICAgdmFyIFBpY3R1cmVVdGlscyA9ICB4ZmFsaWIudXQuUGljdHVyZVV0aWxzOwogICAgdmFyIERhdGVGb3JtYXR0aW5nVmlzaXRvciA9IHhmYWxpYi51dC5EYXRlRm9ybWF0dGluZ1Zpc2l0b3IgPSB4ZmFsaWIudXQuRm9ybWF0dGluZ1Zpc2l0b3JCYXNlLmV4dGVuZCh7CgogICAgICAgIGNvbnN1bWVTdWJQYXR0ZXJuIDogZnVuY3Rpb24odG9rZW4pewogICAgICAgICAgICB2YXIgY2hyID0gdG9rZW4ucGF0Q2hhcjsKICAgICAgICAgICAgdmFyIGNockNudCA9IHRva2VuLmxlbjsKCiAgICAgICAgICAgIHN3aXRjaCAoY2hyKSB7CiAgICAgICAgICAgICAgICBjYXNlICdEJzoKICAgICAgICAgICAgICAgICAgICB2YXIgZGF5T2ZNb250aD10aGlzLmpzb25Nb2RlbC5fZGF0ZUluZm8uZGF0ZS5nZXREYXRlKCk7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXlPZk1vbnRoID0gUGljdHVyZVV0aWxzLnBhZGRpbmcoZGF5T2ZNb250aCwyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChQaWN0dXJlVXRpbHMuY29udmVydE51bWJlclRvTG9jYWxlKHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsZGF5T2ZNb250aCkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnSic6CgogICAgICAgICAgICAgICAgICAgIC8vdGhpcy5fbURheU9mWWVhcjsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ00nOgogICAgICAgICAgICAgICAgICAgIHZhciBtb250aE9mWWVhciA9IHRoaXMuanNvbk1vZGVsLl9kYXRlSW5mby5kYXRlLmdldE1vbnRoKCk7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKFBpY3R1cmVVdGlscy5jb252ZXJ0TnVtYmVyVG9Mb2NhbGUodGhpcy5qc29uTW9kZWwuX2xvY2FsZSxtb250aE9mWWVhcisxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goUGljdHVyZVV0aWxzLmNvbnZlcnROdW1iZXJUb0xvY2FsZSh0aGlzLmpzb25Nb2RlbC5fbG9jYWxlLFBpY3R1cmVVdGlscy5wYWRkaW5nKG1vbnRoT2ZZZWFyKzEsMikpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbW9udGhOYW1lcyA9IFBpY3R1cmVVdGlscy5nZXRMb2NhbGVPYmplY3QodGhpcy5qc29uTW9kZWwuX2xvY2FsZSwiY2FsZW5kYXJTeW1ib2xzLmFiYnJtb250aE5hbWVzIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChtb250aE5hbWVzW21vbnRoT2ZZZWFyXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1vbnRoTmFtZXMgPSBQaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsImNhbGVuZGFyU3ltYm9scy5tb250aE5hbWVzIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChtb250aE5hbWVzW21vbnRoT2ZZZWFyXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnRSc6CiAgICAgICAgICAgICAgICAgICAgdmFyIGRheU9mV2VlayA9IHRoaXMuanNvbk1vZGVsLl9kYXRlSW5mby5kYXRlLmdldERheSgpOwogICAgICAgICAgICAgICAgICAgIHZhciBkYXlOYW1lczsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2goY2hyQ250KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKGRheU9mV2Vlayk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF5TmFtZXMgPSAgUGljdHVyZVV0aWxzLmdldExvY2FsZU9iamVjdCh0aGlzLmpzb25Nb2RlbC5fbG9jYWxlLCJjYWxlbmRhclN5bWJvbHMuYWJicmRheU5hbWVzIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChkYXlOYW1lc1tkYXlPZldlZWtdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXlOYW1lcyA9ICAgUGljdHVyZVV0aWxzLmdldExvY2FsZU9iamVjdCh0aGlzLmpzb25Nb2RlbC5fbG9jYWxlLCJjYWxlbmRhclN5bWJvbHMuZGF5TmFtZXMiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKGRheU5hbWVzW2RheU9mV2Vla10pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAidW5zdXBwb3J0ZWQgUGljdHVyZSBDbGF1c2UgIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdlJzoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ0cnOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnWSc6CgogICAgICAgICAgICAgICAgICAgIHZhciB5ZWFyT2ZFcmEgPSB0aGlzLmpzb25Nb2RlbC5fZGF0ZUluZm8uZGF0ZS5nZXRGdWxsWWVhcigpCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHllYXJPZkVyYT4yMDI5IHx8IHllYXJPZkVyYSA8IDE5MzApewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJ1bnN1cHBvcnRlZCAiICsgeWVhck9mRXJhICsgIiBieSBwYXR0ZXJuIFlZIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJPZkVyYSA9IFBpY3R1cmVVdGlscy5wYWRkaW5nKHllYXJPZkVyYSAlIDEwMCwgMik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhck9mRXJhID0gUGljdHVyZVV0aWxzLnBhZGRpbmcoeWVhck9mRXJhLCA0KTsgLy8gMiBkaWdpdCgwMDAwLTk5OTkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goUGljdHVyZVV0aWxzLmNvbnZlcnROdW1iZXJUb0xvY2FsZSh0aGlzLmpzb25Nb2RlbC5fbG9jYWxlLHllYXJPZkVyYSkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAndyc6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdXJzoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93ICJVbnN1cHBvcnRlZCBwYXR0ZXJuIjsKICAgICAgICAgICAgfQoKICAgICAgICB9LAogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgZ2V0UmVzdWx0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5qb2luKCIiKTsKICAgICAgICB9CgogICAgfSk7Cn0pKF8seGZhbGliKTsKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlRleHRGb3JtYXR0aW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5Gb3JtYXR0aW5nVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBGb3JtYXRzIGEgc3RyaW5nIGFjY29yZGluZyB0byBUZXh0IFBpY3R1cmUuCiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKLyoqCiAqIEBjb25zdHJ1Y3RvcgogKiBAcGFyYW0gT2JqZWN0IHsganNvbk1vZGVsOntfc1BpY3R1cmU6IFN0cmluZywgX3RleHQ6IFN0cmluZ319CiAqLwooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgdmFyIFRleHRGb3JtYXR0aW5nVmlzaXRvciA9IHhmYWxpYi51dC5UZXh0Rm9ybWF0dGluZ1Zpc2l0b3IgPSB4ZmFsaWIudXQuRm9ybWF0dGluZ1Zpc2l0b3JCYXNlLmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB0aGlzLl90ZXh0UG9zID0gMDsKICAgICAgICAgICAgdGhpcy5fcmVsYXhlZCA9IHR5cGVvZiB0aGlzLmpzb25Nb2RlbC5yZWxheGVkID09PSAidW5kZWZpbmVkIiA/IHRydWU6IHRoaXMuanNvbk1vZGVsLnJlbGF4ZWQ7CiAgICAgICAgICAgIFRleHRGb3JtYXR0aW5nVmlzaXRvci5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIGNvbnN1bWVTdWJQYXR0ZXJuIDogZnVuY3Rpb24odG9rZW4pewogICAgICAgICAgICB2YXIgY2hyID0gdG9rZW4ucGF0Q2hhcjsKICAgICAgICAgICAgdmFyIGNockNudCA9IHRva2VuLmxlbjsKICAgICAgICAgICAgZm9yKHZhciBpbmRleCA9IDA7IGluZGV4IDwgY2hyQ250ICYmICghdGhpcy5fcmVsYXhlZCB8fCB0aGlzLl90ZXh0UG9zIDwgdGhpcy5qc29uTW9kZWwuX3RleHQubGVuZ3RoKTsgaW5kZXgrKyl7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGNocikgewogICAgICAgICAgICAgICAgICAgIGNhc2UgJzknOiAvLyBOdW1lcmljCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjVW5pID0gdGhpcy5qc29uTW9kZWwuX3RleHQuY2hhckF0KHRoaXMuX3RleHRQb3MrKyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCF4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmlzRGlnaXQoY1VuaSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRGb3JtYXR0aW5nOiBub3QgYSBkaWdpdCBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goY1VuaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ0EnOiAvLyBBbHBoZWJldGljCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjVW5pID0gdGhpcy5qc29uTW9kZWwuX3RleHQuY2hhckF0KHRoaXMuX3RleHRQb3MrKyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCF4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmlzTGV0dGVyKGNVbmkpKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJUZXh0Rm9ybWF0dGluZzogbm90IGEgY2hhcmFjdGVyIGFzIGV4cGVjdGVkIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChjVW5pKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnTyc6IC8vIEFscGhhbnVtZXJpYwogICAgICAgICAgICAgICAgICAgIGNhc2UgJzAnOgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY1VuaSA9IHRoaXMuanNvbk1vZGVsLl90ZXh0LmNoYXJBdCh0aGlzLl90ZXh0UG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBjVW5pID09PSAiIiBpcyBhIGhhY2sgZm9yIExDLTYxNTIKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVG8gcHJldmVudCBleHRyYSBsb29wW29uZSBtb3JlIHRpbWUgdGhhbiB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmddIGZvciB3aGljaCBjVW5pIHdhcyAiIgogICAgICAgICAgICAgICAgICAgICAgICAvLyB3aGljaCB3YXMgbmVpdGhlciBhIGxldHRlciBub3IgYSBkaWdpdAogICAgICAgICAgICAgICAgICAgICAgICAvLyBzbyB3ZSB3ZXJlIGdldHRpbmcgdGV4dGZvcm1hdHRpbmcgZXJyb3IKICAgICAgICAgICAgICAgICAgICAgICAgLy93aGljaCBjYXVzZWQgZW1haWwgaWQgdmFsaWRhdGlvbiB0byBmYWlsIGZvciBjaGFycyBsZXNzIHRoYW4gcGljdHVyZSBjbGF1c2UKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIShjVW5pID09PSIiIHx8IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuaXNMZXR0ZXIoY1VuaSkgfHwgeGZhbGliLnV0LlBpY3R1cmVVdGlscy5pc0RpZ2l0KGNVbmkpKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dEZvcm1hdHRpbmc6IG5vdCBhIGNoYXJhY3RlciBvciBkaWdpdCBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goY1VuaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ1gnOgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY1VuaSA9IHRoaXMuanNvbk1vZGVsLl90ZXh0LmNoYXJBdCh0aGlzLl90ZXh0UG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChjVW5pKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAndCc6CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKCJcdCIpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB0aGlzLl9idWZmZXIucHVzaChjaHIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgZ2V0UmVzdWx0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgaWYodGhpcy5fdGV4dFBvcyA8IHRoaXMuanNvbk1vZGVsLl90ZXh0Lmxlbmd0aCkKICAgICAgICAgICAgICAgIHRocm93ICJUZXh0Rm9ybWF0dGluZzogcGljdHVyZSBjbGF1c2Ugc21hbGxlciB0aGFuIGlucHV0IFRleHQiOwogICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLmpvaW4oIiIpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgYWNjZXB0UGF0dGVybkNoYXIgOiBmdW5jdGlvbihjaHIpewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlBpY3R1cmVVdGlscy5pblN0cmluZyhjaHIsICI5QU8wWHQiKTsKICAgICAgICB9LAoKICAgICAgICBjb25zdW1lQ2hhckxpdGVyYWwgOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKCIiKyB0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmUuY2hhckF0KHRva2VuLnN0YXJ0UG9zKSk7CiAgICAgICAgIC8vIExDLTM4NjkgOiBmb3J3YXJkIHRoZSB0ZXh0IHBvaW50ZXIgYWZ0ZXIgbGl0ZXJhbCBpcyBwcmVzZW50IGFuZCBtYXRjaGVkIHdpdGggdGhlIHBpY3R1cmUuCiAgICAgICAgIGlmKHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZS5jaGFyQXQodG9rZW4uc3RhcnRQb3MpID09IHRoaXMuanNvbk1vZGVsLl90ZXh0LmNoYXJBdCh0b2tlbi5zdGFydFBvcykpCiAgICAgICAgICAgICB0aGlzLl90ZXh0UG9zKys7CiAgICAgICAgfQogICAgfSkKCn0pKF8seGZhbGliKTsKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlRleHRGb3JtYXR0aW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5Gb3JtYXR0aW5nVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBwcm92aWRlcyBmb3JtYXRpbmcgbG9naWMgb24gZGF0ZSBwYXR0ZXJuIGNoYXJhY3RlcnMuCiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKLyoqCiAqIEBjb25zdHJ1Y3RvcgogKiBAcGFyYW0gb2JqZWN0IHtqc29uTW9kZWw6IHtfc1BpY3R1cmU6U3RyaW5nLF90aW1lSW5mbzogeGZhbGliLnV0LlRpbWVJbmZvfX0KICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgdmFyIFRpbWVGb3JtYXR0aW5nVmlzaXRvciA9IHhmYWxpYi51dC5UaW1lRm9ybWF0dGluZ1Zpc2l0b3I9ICB4ZmFsaWIudXQuRm9ybWF0dGluZ1Zpc2l0b3JCYXNlLmV4dGVuZCh7CgogICAgICAgIGNvbnN1bWVTdWJQYXR0ZXJuIDogZnVuY3Rpb24odG9rZW4pewogICAgICAgICAgICB2YXIgY2hyID0gdG9rZW4ucGF0Q2hhcjsKICAgICAgICAgICAgdmFyIGNockNudCA9IHRva2VuLmxlbjsKCiAgICAgICAgICAgIHN3aXRjaCAoY2hyKSB7CiAgICAgICAgICAgICAgICBjYXNlICdIJzoKICAgICAgICAgICAgICAgIGNhc2UgJ0snOgogICAgICAgICAgICAgICAgICAgIHZhciBob3VyT2ZEYXkgPSB0aGlzLmpzb25Nb2RlbC5fdGltZUluZm8ubUhvdXJPZkRheTsKICAgICAgICAgICAgICAgICAgICBpZihjaHI9PSdLJyl7CiAgICAgICAgICAgICAgICAgICAgICAgIGhvdXJPZkRheSArPSAxOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzd2l0Y2goY2hyQ250KXsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goaG91ck9mRGF5KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCh4ZmFsaWIudXQuUGljdHVyZVV0aWxzLnBhZGRpbmcoaG91ck9mRGF5LDIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdNJzoKICAgICAgICAgICAgICAgICAgICB2YXIgbWludXRlT2ZIb3VyID0gdGhpcy5qc29uTW9kZWwuX3RpbWVJbmZvLm1NaW51dGVPZkhvdXI7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKG1pbnV0ZU9mSG91cik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goeGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYWRkaW5nKG1pbnV0ZU9mSG91ciwyKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnUyc6CiAgICAgICAgICAgICAgICAgICAgdmFyIHNlY29uZE9mTWludXRlID0gdGhpcy5qc29uTW9kZWwuX3RpbWVJbmZvLm1TZWNvbmRPZk1pbnV0ZTsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2goY2hyQ250KXsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goc2Vjb25kT2ZNaW51dGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHhmYWxpYi51dC5QaWN0dXJlVXRpbHMucGFkZGluZyhzZWNvbmRPZk1pbnV0ZSwyKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdGJzoKICAgICAgICAgICAgICAgICAgICB2YXIgTWlsbGlzZWNvbmRzID10aGlzLmpzb25Nb2RlbC5fdGltZUluZm8ubVRob3VzYW5kdGhPZlNlY29uZDsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCh4ZmFsaWIudXQuUGljdHVyZVV0aWxzLnBhZGRpbmcoTWlsbGlzZWNvbmRzLDMpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0aHJvdyAiVW5zdXBwb3J0ZWQgcGF0dGVybiI7CiAgICAgICAgICAgIH07CgogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgZ2V0UmVzdWx0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5qb2luKCIiKTsKICAgICAgICB9CgogICAgfSk7Cgp9KShfLHhmYWxpYik7CgoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5OdW1Gb3JtYXR0aW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5Gb3JtYXR0aW5nVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBGb3JtYXRzIGEgc3RyaW5nIGFjY29yZGluZyB0byBUZXh0IFBpY3R1cmUuCiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKLyoqCiAqIEBjb25zdHJ1Y3RvcgogKiBAcGFyYW0gT2JqZWN0IHsganNvbk1vZGVsOntfc1BpY3R1cmU6IFN0cmluZ30sIHRleHQ6IFN0cmluZ30KICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgdmFyIFBpY3R1cmVVdGlscyA9ICB4ZmFsaWIudXQuUGljdHVyZVV0aWxzOwogICAgdmFyIE51bUZvcm1hdHRpbmdWaXNpdG9yID0geGZhbGliLnV0Lk51bUZvcm1hdHRpbmdWaXNpdG9yID0geGZhbGliLnV0LkZvcm1hdHRpbmdWaXNpdG9yQmFzZS5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRpb25zKSB7CiAgICAgICAgICAgIE51bUZvcm1hdHRpbmdWaXNpdG9yLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX3RleHRQb3MgPSAwOwoKICAgICAgICAgICAgLy9ib29sZWFuIHZhbHVlIHVzZWQgZm9yIGludGVybmFsIHN0YXRlIHRyYWNrCiAgICAgICAgICAgIHRoaXMuX21iRGlnaXRBZGRlZFRvT3V0cHV0ID0gZmFsc2U7IC8vIGF0IGxlYXN0IG9uZSBkaWdpdCBoYXMgYmVlbiBhZGRlZCB0byBvdXRwdXQKICAgICAgICAgICAgdGhpcy5fbWJTaWduQWRkZWRUb091dHB1dCA9IGZhbHNlOwogICAgICAgICAgICB0aGlzLl9uU2Nhbm5lZFBhdHRlcm5EaWdpdCA9IDA7IC8vaG93IG1hbnkgZGlnaXQoOThaeikgY2hhcmFjdGVycyBzY2FubmVkIGluIHBhdHRlcm4sIHJlc2V0IHRvIDAgYWZ0ZXIgJy5WdicKICAgICAgICAgICAgdGhpcy5fbWJSYWRpeFNlZW4gPSBmYWxzZTsKCiAgICAgICAgICAgIHRoaXMuX3BpY3R1cmVEZXNjID0gbmV3IHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYyh7anNvbk1vZGVsOntfc1BpY3R1cmU6dGhpcy5qc29uTW9kZWwuX3NQaWN0dXJlfX0pOwogICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmU9IHRoaXMuX3BpY3R1cmVEZXNjLmdldFBpY3R1cmUoKTsKICAgICAgICAgICAgdGhpcy5fbnVtYmVySW5mbyA9IHRoaXMuX3BpY3R1cmVEZXNjLnBhcnNlTnVtYmVySW5mbyhvcHRpb25zLnRleHQpOwoKICAgICAgICAgICAgdGhpcy5fbWJOZWdhdGl2ZSA9IHRoaXMuX251bWJlckluZm8uaXNOZWdhdGl2ZTsKICAgICAgICAgICAgdGhpcy5fbXNUZXh0ID0gdGhpcy5fbnVtYmVySW5mby5tc1RleHQ7CiAgICAgICAgICAgIHRoaXMuX2xlYWRpbmdQYWRkaW5nID0gdGhpcy5fbnVtYmVySW5mby5wYWRkaW5nOwogICAgICAgICAgICAvLwogICAgICAgICAgICB0aGlzLl9tTnVtYmVyU3ltYm9scyA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsIm51bWJlclN5bWJvbHMiKTsKICAgICAgICAgICAgdGhpcy5fbUN1cnJlbmN5U3ltYm9scyA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsImN1cnJlbmN5U3ltYm9scyIpOwogICAgICAgIH0sCgogICAgICAgIF9jaGVja0FuZEFkZERlY2ltYWxQb2ludDogZnVuY3Rpb24oZncpIHsKICAgICAgICAgICAgaWYodGhpcy5fbUFkZFJhZGl4KSB7CiAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCh0aGlzLl9mbXRTdHIodGhpcy5fbU51bWJlclN5bWJvbHMuZGVjaW1hbCwgZncpKTsKICAgICAgICAgICAgICAgIHRoaXMuX21BZGRSYWRpeCA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgY29uc3VtZVN1YlBhdHRlcm4gOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgICAgIHZhciBjaHIgPSB0b2tlbi5wYXRDaGFyLAogICAgICAgICAgICAgICAgY2hyQ250ID0gdG9rZW4ubGVuOwogICAgICAgICAgICBzd2l0Y2ggKGNocikgewogICAgICAgICAgICAgICAgY2FzZSAnOSc6CiAgICAgICAgICAgICAgICBjYXNlICc4JzoKICAgICAgICAgICAgICAgIGNhc2UgJ1onOiAvLyBEaWdpdCBvciBzcGFjZSBpZiB6ZXJvLgogICAgICAgICAgICAgICAgY2FzZSAneic6Ly8gRGlnaXQgb3Igbm90aGluZyBpZiB6ZXJvLgogICAgICAgICAgICAgICAgICAgIGlmKCF0aGlzLl9tYlNpZ25BZGRlZFRvT3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9lbnN1cmVTaWduSXNBZGRlZCgpOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaHJDbnQtLSA+IDAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCF0aGlzLl9tYlJhZGl4U2Vlbil7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl9sZWFkaW5nUGFkZGluZyA+IHRoaXMuX25TY2FubmVkUGF0dGVybkRpZ2l0KyspewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwbGFjZUhvbGRlciA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fbWJEaWdpdEFkZGVkVG9PdXRwdXQpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZUhvbGRlciA9IHRoaXMuX21OdW1iZXJTeW1ib2xzLnplcm87CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNociA9PSAnOScgfHwgY2hyID09JzgnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZUhvbGRlciA9IHRoaXMuX21OdW1iZXJTeW1ib2xzLnplcm87CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYkRpZ2l0QWRkZWRUb091dHB1dCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlIGlmKGNociA9PSAnWicpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2VIb2xkZXIgPSAiICI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYocGxhY2VIb2xkZXIpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCh0aGlzLl9tYXRjaENocihwbGFjZUhvbGRlcikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY1ZhbHVlID0gdGhpcy5fbXNUZXh0LmNoYXJBdCh0aGlzLl90ZXh0UG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2Vuc3VyZUNoYXJJc0RpZ2l0KGNWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goUGljdHVyZVV0aWxzLmNvbnZlcnROdW1iZXJUb0xvY2FsZSh0aGlzLmpzb25Nb2RlbC5fbG9jYWxlLGNWYWx1ZSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iRGlnaXRBZGRlZFRvT3V0cHV0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7ICAvL2hhbmRsaW5nIGZyYWN0aW9uYWwgcGFydAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fblNjYW5uZWRQYXR0ZXJuRGlnaXQrKyAgPCB0aGlzLl9udW1iZXJJbmZvLmZyYWN0aW9uRGlnaXQgKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY1ZhbHVlID0gdGhpcy5fbXNUZXh0LmNoYXJBdCh0aGlzLl90ZXh0UG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2Vuc3VyZUNoYXJJc0RpZ2l0KGNWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2hlY2tBbmRBZGREZWNpbWFsUG9pbnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChQaWN0dXJlVXRpbHMuY29udmVydE51bWJlclRvTG9jYWxlKHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsY1ZhbHVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJEaWdpdEFkZGVkVG9PdXRwdXQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2hyID09ICc5J3x8IGNociA9PSdaJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGVja0FuZEFkZERlY2ltYWxQb2ludCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCh0aGlzLl9tYXRjaENocih0aGlzLl9tTnVtYmVyU3ltYm9scy56ZXJvKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmKGNociA9PSAnOCcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNWYWx1ZSA9IHRoaXMuX21zVGV4dC5jaGFyQXQodGhpcy5fdGV4dFBvcysrKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY1ZhbHVlICE9ICcnICYmIHRoaXMuX2Vuc3VyZUNoYXJJc0RpZ2l0KGNWYWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NoZWNrQW5kQWRkRGVjaW1hbFBvaW50KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChQaWN0dXJlVXRpbHMuY29udmVydE51bWJlclRvTG9jYWxlKHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsY1ZhbHVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYkRpZ2l0QWRkZWRUb091dHB1dCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ0UnOiAvLyBFeHBvbmVudC4KICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCgnRScpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKCIiICsgdGhpcy5fbnVtYmVySW5mby5zaGlmdCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdDJzogLy8gQ1Igc3ltYm9sIGlmIG5lZ2F0aXZlIGFuZCBzcGFjZXMgaWYgcG9zaXRpdmUuCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goKHRoaXMuX21iTmVnYXRpdmUpID8geGZhbGliLnV0Lk51bVBpY3R1cmVEZXNjLmdzQ1IgOiB4ZmFsaWIudXQuTnVtUGljdHVyZURlc2MuZ3NEU1ApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnYyc6IC8vIENSIHN5bWJvbCBpZiBuZWdhdGl2ZSBhbmQgbm90aGluZyBpZiBwb3NpdGl2ZS4KICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbWJOZWdhdGl2ZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYy5nc0NSKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdEJzogLy8gREIgc3ltYm9sIGlmIG5lZ2F0aXZlIGFuZCBzcGFjZXMgaWYgcG9zaXRpdmUuCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goKHRoaXMuX21iTmVnYXRpdmUpID8geGZhbGliLnV0Lk51bVBpY3R1cmVEZXNjLmdzREIgOiB4ZmFsaWIudXQuTnVtUGljdHVyZURlc2MuZ3NEU1ApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnZCc6IC8vIERCIHN5bWJvbCBpZiBuZWdhdGl2ZSBhbmQgbm90aGluZyBpZiBwb3NpdGl2ZS4KICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbWJOZWdhdGl2ZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYy5nc0RCKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdTJzogLy8gTWludXMgc2lnbiBpZiBuZWdhdGl2ZSBhbmQgYSBzcGFjZSBpZiBwb3NpdGl2ZS4KICAgICAgICAgICAgICAgIGNhc2UgJ3MnOgogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9tYk5lZ2F0aXZlKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2godGhpcy5fZm10U3RyKAl0aGlzLl9tTnVtYmVyU3ltYm9scy5taW51cykpOwogICAgICAgICAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgICAgICAgICBpZignUycgPT0gY2hyKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHRoaXMuX21hdGNoQ2hyKCcgJykpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnVic6IC8vIEltcGxpZWQgZGVjaW1hbCBzaWduIGlmIHBhcnNpbmcuCiAgICAgICAgICAgICAgICBjYXNlICcuJzoKICAgICAgICAgICAgICAgIGNhc2UgJ3YnOiAvLyBJbXBsaWVkIGRlY2ltYWwgc2lnbi4KICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fdGV4dFBvcyA8IHRoaXMuX21zVGV4dC5sZW5ndGggJiYgdGhpcy5fbXNUZXh0LmNoYXJBdCh0aGlzLl90ZXh0UG9zKSA9PSAnLicpewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl90ZXh0UG9zKys7IC8vY29uc3VtZSBhICcuJwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoY2hyID09ICdWJyB8fCBjaHIgPT0gJy4nKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbUFkZFJhZGl4ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzLl9idWZmZXIucHVzaCh0aGlzLl9mbXRTdHIodGhpcy5fbU51bWJlclN5bWJvbHMuZGVjaW1hbCwgKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHRoaXMuX21iUmFkaXhTZWVuID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9uU2Nhbm5lZFBhdHRlcm5EaWdpdCA9IDA7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAweEZGMEM6IC8vIEZ1bGx3aWR0aCAnLCcuCiAgICAgICAgICAgICAgICBjYXNlICcsJzogLy8gR3JvdXBpbmcgc2VwYXJhdG9yLgogICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaHJDbnQtLSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX21iRGlnaXRBZGRlZFRvT3V0cHV0KXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHRoaXMuX2ZtdFN0cigJdGhpcy5fbU51bWJlclN5bWJvbHMuZ3JvdXBpbmcgKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJDb21tYVNlZW4gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMHhGRjA0OiAvLyBGdWxsd2lkdGggJyQnLgogICAgICAgICAgICAgICAgY2FzZSAnJCc6IC8vIEN1cnJlbmN5IG5hbWUgb3Igc3ltYm9sLgogICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaHJDbnQtLSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2godGhpcy5fZm10U3RyKAl0aGlzLl9tQ3VycmVuY3lTeW1ib2xzLnN5bWJvbCApKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDB4RkYwNTogLy8gRnVsbHdpZHRoICclJy4KICAgICAgICAgICAgICAgIGNhc2UgJyUnOiAvLyBQZXJjZW50IHN5bWJvbC4KICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hyQ250LS0gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKHRoaXMuX2ZtdFN0cigJdGhpcy5fbU51bWJlclN5bWJvbHMucGVyY2VudCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMHhGRjA4OiAvLyBGdWxsd2lkdGggJygnLgogICAgICAgICAgICAgICAgY2FzZSAweEZGMDk6IC8vIEZ1bGx3aWR0aCAnKScuCiAgICAgICAgICAgICAgICBjYXNlICcoJzogLy8gTGVmdCBwYXJlbnRoZXNpcy4KICAgICAgICAgICAgICAgIGNhc2UgJyknOiAvLyBSaWdodCBwYXJlbnRoZXNpcy4KICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaCh0aGlzLl9tYXRjaENocigodGhpcy5fbWJOZWdhdGl2ZSkgPyBjaHIgOiAnICcpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZW5zdXJlQ2hhcklzRGlnaXQgOiBmdW5jdGlvbihjVmFsdWUpewogICAgICAgICAgICBpZiAoJzAnID4gY1ZhbHVlIHx8IGNWYWx1ZSA+ICc5Jyl7CiAgICAgICAgICAgICAgICB0aHJvdyAiTnViZXJpYyBGb3JtYXR0aW5nOiBub3QgYSBkaWdpdCBhcyBleHBlY3RlZCAiICsgY1ZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCgogICAgICAgIF9mbXRTdHIgOiBmdW5jdGlvbihzdHIpewogICAgICAgICAgICByZXR1cm4gc3RyOwogICAgICAgIH0sCgogICAgICAgIF9tYXRjaFN0ciA6IGZ1bmN0aW9uKHN0cil7CiAgICAgICAgICAgIHJldHVybiBzdHI7CiAgICAgICAgfSwKCiAgICAgICAgX21hdGNoQ2hyIDogZnVuY3Rpb24oc3RyKXsKICAgICAgICAgICAgcmV0dXJuIHN0cjsKICAgICAgICB9LAoKICAgICAgICBfZW5zdXJlU2lnbklzQWRkZWQgOiBmdW5jdGlvbigpewogICAgICAgICAgICBpZiAodGhpcy5fbWJOZWdhdGl2ZSAmJiAhIHRoaXMuX21iRGlnaXRBZGRlZFRvT3V0cHV0ICYmICEgdGhpcy5fcGljdHVyZURlc2MuaGFzU2lnbikgewogICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2godGhpcy5fbU51bWJlclN5bWJvbHMubWludXMpOwogICAgICAgICAgICAgICAgdGhpcy5fbWJTaWduQWRkZWRUb091dHB1dCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqIEBvdmVycmlkZQogICAgICAgICAqLwogICAgICAgIGdldFJlc3VsdCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIuam9pbigiIik7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKiBAb3ZlcnJpZGUKICAgICAgICAgKi8KICAgICAgICBhY2NlcHRQYXR0ZXJuQ2hhciA6IGZ1bmN0aW9uKGNocil7CiAgICAgICAgICAgIHJldHVybiB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmluU3RyaW5nKGNociwgIiglJCwuKTg5QkNERVJTVlpiY2Ryc3Z6dCIpOwogICAgICAgIH0KCiAgICB9KTsKCn0pKF8seGZhbGliKTsKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlRpbWVQYXJzaW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5QYXJzaW5nVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBwcm92aWRlcyBwYXJzaW5nL2Zvcm1hdGluZyBsb2dpYyBvbiBkYXRlIHBhdHRlcm4gY2hhcmFjdGVycy4KICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nLCBfZGF0YVN0cmluZzogU3RyaW5nXX0KICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgdmFyIFRpbWVQYXJzaW5nVmlzaXRvciA9IHhmYWxpYi51dC5UaW1lUGFyc2luZ1Zpc2l0b3IgPSB4ZmFsaWIudXQuUGFyc2luZ1Zpc2l0b3JCYXNlLmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB0aGlzLl90aW1lSW5mbyA9IG5ldyB4ZmFsaWIudXQuVGltZUluZm8oKTsKICAgICAgICAgICAgVGltZVBhcnNpbmdWaXNpdG9yLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgfSwKCiAgICAgICAgY29uc3VtZVN1YlBhdHRlcm4gOiBmdW5jdGlvbih0b2tlbil7CiAgICAgICAgICAgIHZhciBjaHIgPSB0b2tlbi5wYXRDaGFyOwogICAgICAgICAgICB2YXIgY2hyQ250ID0gdG9rZW4ubGVuOwogICAgICAgICAgICB2YXIgY3VyUG9zID0gdGhpcy5fc3RyUG9zOwogICAgICAgICAgICB2YXIgc2Nhbm5lZENoYXIgPSBjaHJDbnQ7CiAgICAgICAgICAgIHRoaXMuX2Fzc2VydChjdXJQb3MrY2hyQ250IDw9dGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcubGVuZ3RoLCAiTWlzbWF0Y2giKTsKCiAgICAgICAgICAgIHN3aXRjaCAoY2hyKSB7CiAgICAgICAgICAgICAgICBjYXNlICdoJzoKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl90aW1lSW5mby5tSG91ck9mTWVyaURpZW0gIT0gLTEgfHwgdGhpcy5fdGltZUluZm8ubUhvdXJPZkRheSAhPSAtMSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJhbWJpZ3VpdHkgdGltZSBzdHJpbmciOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgaG91ck9mTWVyaURpZW09LTE7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJzZWQgPSB0aGlzLnBhcnNlSW50QWdncmVzc2l2ZSh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDEtMTIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyT2ZNZXJpRGllbSA9IHBhcnNlZC52YWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5uZWRDaGFyID0gcGFyc2VkLmxlbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyT2ZNZXJpRGllbSA9IHRoaXMucGFyc2VJbnRFeGFjdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDEtMTIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVJbmZvLm1Ib3VyT2ZNZXJpRGllbSA9IGhvdXJPZk1lcmlEaWVtIC0xOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Fzc2VydCh0aGlzLl90aW1lSW5mby5tSG91ck9mTWVyaURpZW0+PTAgJiYgdGhpcy5fdGltZUluZm8ubUhvdXJPZk1lcmlEaWVtPD0xMSwgIkludmFsaWQgSG91ciBPZiBNZXJpRGllbSB2YWx1ZS4iKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdrJzoKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl90aW1lSW5mby5tSG91ck9mTWVyaURpZW0gIT0gLTEgfHwgdGhpcy5fdGltZUluZm8ubUhvdXJPZkRheSAhPSAtMSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJhbWJpZ3VpdHkgdGltZSBzdHJpbmciOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgaG91ck9mTWVyaURpZW09LTE7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJzZWQgPSB0aGlzLnBhcnNlSW50QWdncmVzc2l2ZSh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDAtMTEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyT2ZNZXJpRGllbSA9IHBhcnNlZC52YWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5uZWRDaGFyID0gcGFyc2VkLmxlbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyT2ZNZXJpRGllbSA9IHRoaXMucGFyc2VJbnRFeGFjdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDAtMTEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVJbmZvLm1Ib3VyT2ZNZXJpRGllbSA9IGhvdXJPZk1lcmlEaWVtOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Fzc2VydCh0aGlzLl90aW1lSW5mby5tSG91ck9mTWVyaURpZW0+PTAgJiYgdGhpcy5fdGltZUluZm8ubUhvdXJPZk1lcmlEaWVtPD0xMSwgIkludmFsaWQgaG91ciBvZiBtZXJpRGllbSB2YWx1ZS4iKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlICdIJzoKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl90aW1lSW5mby5tSG91ck9mTWVyaURpZW0gIT0gLTEgfHwgdGhpcy5fdGltZUluZm8ubUhvdXJPZkRheSAhPSAtMSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJhbWJpZ3VpdHkgdGltZSBzdHJpbmciOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgaG91ck9mRGF5PS0xOwogICAgICAgICAgICAgICAgICAgIHN3aXRjaChjaHJDbnQpewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyc2VkID0gdGhpcy5wYXJzZUludEFnZ3Jlc3NpdmUodGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcsIGN1clBvcywgMik7IC8vIDEtMiBkaWdpdCgwLTIzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91ck9mRGF5ID0gcGFyc2VkLnZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbm5lZENoYXIgPSBwYXJzZWQubGVuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvdXJPZkRheSA9IHRoaXMucGFyc2VJbnRFeGFjdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDAtMjMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVJbmZvLm1Ib3VyT2ZEYXkgPSBob3VyT2ZEYXk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXNzZXJ0KHRoaXMuX3RpbWVJbmZvLm1Ib3VyT2ZEYXk+PTAgJiYgdGhpcy5fdGltZUluZm8ubUhvdXJPZkRheTw9MjMsICJJbnZhbGlkIGhvdXIgb2YgZGF5IHZhbHVlLiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ0snOgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX3RpbWVJbmZvLm1Ib3VyT2ZNZXJpRGllbSAhPSAtMSB8fCB0aGlzLl90aW1lSW5mby5tSG91ck9mRGF5ICE9IC0xKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgImFtYmlndWl0eSB0aW1lIHN0cmluZyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBob3VyT2ZEYXk9LTE7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXJzZWQgPSB0aGlzLnBhcnNlSW50QWdncmVzc2l2ZSh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDAtMjMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VyT2ZEYXkgPSBwYXJzZWQudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FubmVkQ2hhciA9IHBhcnNlZC5sZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91ck9mRGF5ID0gdGhpcy5wYXJzZUludEV4YWN0KHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCBjdXJQb3MsIDIpOyAvLyAxLTIgZGlnaXQoMC0yMykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGltZUluZm8ubUhvdXJPZkRheSA9IGhvdXJPZkRheSAtIDE7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXNzZXJ0KHRoaXMuX3RpbWVJbmZvLm1Ib3VyT2ZEYXk+PTAgJiYgdGhpcy5fdGltZUluZm8ubUhvdXJPZkRheTw9MjMsICJJbnZhbGlkIGhvdXIgb2YgZGF5IHZhbHVlLiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnTSc6CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fdGltZUluZm8ubU1pbnV0ZU9mSG91ciAhPSAtMSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJhbWJpZ3VpdHkgdGltZSBzdHJpbmciOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgbWludXRlT2ZIb3VyPS0xOwogICAgICAgICAgICAgICAgICAgIHN3aXRjaChjaHJDbnQpewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyc2VkID0gdGhpcy5wYXJzZUludEFnZ3Jlc3NpdmUodGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcsIGN1clBvcywgMik7IC8vIDEtMiBkaWdpdCgwLTU5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlT2ZIb3VyID0gcGFyc2VkLnZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbm5lZENoYXIgPSBwYXJzZWQubGVuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZU9mSG91ciA9IHRoaXMucGFyc2VJbnRFeGFjdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDAtNTkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVJbmZvLm1NaW51dGVPZkhvdXIgPSBtaW51dGVPZkhvdXI7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXNzZXJ0KHRoaXMuX3RpbWVJbmZvLm1NaW51dGVPZkhvdXI+PTAgJiYgdGhpcy5fdGltZUluZm8ubU1pbnV0ZU9mSG91cjw9NTksICJJbnZhbGlkIG1pbnV0ZSBvZiBob3VyLiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnUyc6CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fdGltZUluZm8ubVNlY29uZE9mTWludXRlICE9IC0xKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgImFtYmlndWl0eSB0aW1lIHN0cmluZyI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBzZWNvbmRPZk1pbnV0ZT0tMTsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2goY2hyQ250KXsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcnNlZCA9IHRoaXMucGFyc2VJbnRBZ2dyZXNzaXZlKHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCBjdXJQb3MsIDIpOyAvLyAxLTIgZGlnaXQoMC01OSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZE9mTWludXRlID0gcGFyc2VkLnZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbm5lZENoYXIgPSBwYXJzZWQubGVuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZE9mTWludXRlID0gdGhpcy5wYXJzZUludEV4YWN0KHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCBjdXJQb3MsIDIpOyAvLyAxLTIgZGlnaXQoMC01OSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGltZUluZm8ubVNlY29uZE9mTWludXRlID0gc2Vjb25kT2ZNaW51dGU7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXNzZXJ0KHRoaXMuX3RpbWVJbmZvLm1TZWNvbmRPZk1pbnV0ZT49MCAmJiB0aGlzLl90aW1lSW5mby5tU2Vjb25kT2ZNaW51dGU8PTU5LCAiSW52YWxpZCBzZWNvbmQgb2YgbWludXRlLiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnRic6CgogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Fzc2VydChjaHJDbnQ9PTMsICJJbnZhbGlkIHBhdHRlcm4gRi4iKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl90aW1lSW5mby5tVGhvdXNhbmR0aE9mU2Vjb25kID0gdGhpcy5wYXJzZUludEV4YWN0KHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCBjdXJQb3MsIDMpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Fzc2VydCh0aGlzLl90aW1lSW5mby5tVGhvdXNhbmR0aE9mU2Vjb25kPj0wICYmIHRoaXMuX3RpbWVJbmZvLm1UaG91c2FuZHRoT2ZTZWNvbmQ8PTk5OSwgIkludmFsaWQgdGhvdXNhbmQgb2Ygc2Vjb25kLiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93ICJVbnN1cHBvcnRlZCBwYXR0ZXJuIjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5fc3RyUG9zICs9IHNjYW5uZWRDaGFyOwogICAgICAgIH0sCgogICAgICAgIHBhcnNlSW50QWdncmVzc2l2ZSA6IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMucGFyc2VJbnRBZ2dyZXNzaXZlLAoKICAgICAgICBwYXJzZUludEV4YWN0IDogeGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYXJzZUludEV4YWN0LAoKICAgICAgICBnZXRSZXN1bHQgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZUluZm8uZ2V0SVNPVGltZSgpOwogICAgICAgIH0sCgogICAgICAgIGdldFRpbWVJbmZvIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVJbmZvOwogICAgICAgIH0sCgogICAgICAgIF9hc3NlcnQgOiBmdW5jdGlvbihjb25kaXRpb24sIG1lc3NhZ2UpewogICAgICAgICAgICBpZighY29uZGl0aW9uKXsKICAgICAgICAgICAgICAgIHRocm93IG1lc3NhZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKfSkoXyx4ZmFsaWIpOwoKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LlRleHRQYXJzaW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5QYXJzaW5nVmlzaXRvckJhc2UKICoKICogQGZpbGVPdmVydmlldyBQYXJzZXMgYSBzdHJpbmcgYWNjb3JkaW5nIHRvIFRleHQgUGljdHVyZS4KICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nLCBfZGF0YVN0cmluZzogU3RyaW5nXX0KICovCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgVGV4dFBhcnNpbmdWaXNpdG9yID0geGZhbGliLnV0LlRleHRQYXJzaW5nVmlzaXRvciA9IHhmYWxpYi51dC5QYXJzaW5nVmlzaXRvckJhc2UuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIFRleHRQYXJzaW5nVmlzaXRvci5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLl9idWZmZXIgPSBbXTsKICAgICAgICB9LAoKICAgICAgICBjb25zdW1lU3ViUGF0dGVybiA6IGZ1bmN0aW9uKHRva2VuKXsKICAgICAgICAgICAgdmFyIGNociA9IHRva2VuLnBhdENoYXI7CiAgICAgICAgICAgIHZhciBjaHJDbnQgPSB0b2tlbi5sZW47CiAgICAgICAgICAgIGZvcih2YXIgaW5kZXggPSAwOyBpbmRleCA8IGNockNudDsgaW5kZXgrKyl7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKGNocikgewogICAgICAgICAgICAgICAgICAgIGNhc2UgJzknOiAvLyBOdW1lcmljCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjVW5pID0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcuY2hhckF0KHRoaXMuX3N0clBvcysrKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIXhmYWxpYi51dC5QaWN0dXJlVXRpbHMuaXNEaWdpdChjVW5pKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCBhIGRpZ2l0IGFzIGV4cGVjdGVkIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChjVW5pKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAnQSc6IC8vIEFscGhlYmV0aWMKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNVbmkgPSB0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy5jaGFyQXQodGhpcy5fc3RyUG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICBpZigheGZhbGliLnV0LlBpY3R1cmVVdGlscy5pc0xldHRlcihjVW5pKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCBhIGNoYXJhY3RlciBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goY1VuaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgJ08nOiAvLyBBbHBoYW51bWVyaWMKICAgICAgICAgICAgICAgICAgICBjYXNlICcwJzoKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNVbmkgPSB0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy5jaGFyQXQodGhpcy5fc3RyUG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICBpZigheGZhbGliLnV0LlBpY3R1cmVVdGlscy5pc0xldHRlck9yRGlnaXQoY1VuaSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBjaGFyYWN0ZXIgb3IgZGlnaXQgYXMgZXhwZWN0ZWQiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKGNVbmkpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICdYJzoKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNVbmkgPSB0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy5jaGFyQXQodGhpcy5fc3RyUG9zKyspOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChjVW5pKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAndCc6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLmNoYXJBdCh0aGlzLl9zdHJQb3MrKyk9PSJcdCIpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goIlx0Iik7CiAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBUYWIgYXMgZXhwZWN0ZWQiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLmNoYXJBdCh0aGlzLl9zdHJQb3MrKyk9PSBjaHIpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goY2hyKTsKICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCAnIiArIGNocisiJyBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICB9LAogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgZ2V0UmVzdWx0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgaWYodGhpcy5fc3RyUG9zIDwgdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcubGVuZ3RoKQogICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBwaWN0dXJlIGNsYXVzZSBzbWFsbGVyIHRoYW4gaW5wdXQgVGV4dCI7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIuam9pbigiIik7CiAgICAgICAgfSwKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqIEBvdmVycmlkZQogICAgICAgICAqLwogICAgICAgIGFjY2VwdFBhdHRlcm5DaGFyIDogZnVuY3Rpb24oY2hyKXsKICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuaW5TdHJpbmcoY2hyLCAiOUFPMFh0Iik7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLHhmYWxpYik7CgoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5OdW1QYXJzaW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5QYXJzaW5nVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBQYXJzZXMgYSBzdHJpbmcgYWNjb3JkaW5nIHRvIFRleHQgUGljdHVyZS4KICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nLF9kYXRhU3RyaW5nOiBTdHJpbmd9fQogKi8KCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgTnVtUGFyc2luZ1Zpc2l0b3IgPSB4ZmFsaWIudXQuTnVtUGFyc2luZ1Zpc2l0b3IgPSB4ZmFsaWIudXQuUGFyc2luZ1Zpc2l0b3JCYXNlLmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgdGhpcy5fcGljdHVyZURlc2MgPSBuZXcgeGZhbGliLnV0Lk51bVBpY3R1cmVEZXNjKHtqc29uTW9kZWw6e19zUGljdHVyZTp0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmV9fSk7CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLl9zUGljdHVyZSA9IHRoaXMuX3BpY3R1cmVEZXNjLmdldFBpY3R1cmUoKTsKICAgICAgICAgICAgdGhpcy5fYnVmZmVyID0gW107CiAgICAgICAgICAgIHRoaXMuX3N0clBvcyA9IDA7CiAgICAgICAgICAgIHRoaXMuX2hhc1JhZGl4ID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuX21iTmVnYXRpdmUgPSBmYWxzZTsKICAgICAgICAgICAgdGhpcy5fbWJEaWdpdFNlZW4gPSBmYWxzZTsgLy8gYXQgbGVhc3Qgb25lIGRpZ2l0IGhhcyBiZWVuIGFkZGVkIHRvIG91dHB1dAogICAgICAgICAgICB0aGlzLl9tYlNpZ25TZWVuID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuX21CYWNrdHJhY2sgPSBudWxsOwogICAgICAgICAgICB0aGlzLl9oYXNQZXJjZW50ID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuX21iRXhwb25TZWVuID0gZmFsc2U7CgogICAgICAgICAgICB0aGlzLl9tTnVtYmVyU3ltYm9scyA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KHRoaXMub3B0aW9ucy5fbG9jYWxlLCJudW1iZXJTeW1ib2xzIik7CiAgICAgICAgICAgIHRoaXMuX21DdXJyZW5jeVN5bWJvbHMgPSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmdldExvY2FsZU9iamVjdCh0aGlzLm9wdGlvbnMuX2xvY2FsZSwiY3VycmVuY3lTeW1ib2xzIik7CiAgICAgICAgfSwKCiAgICAgICAgX2xvb2t1cE5leHQgOiB4ZmFsaWIudXQuU2Nhbm5lci5sb29rdXBOZXh0LAoKICAgICAgICBwYXJzZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciBwYXRQb3MgPSAwOwogICAgICAgICAgICB3aGlsZSh0cnVlKXsKICAgICAgICAgICAgICAgIHRyeXsKICAgICAgICAgICAgICAgICAgICBmb3IodmFyIHRva2VuID0gdGhpcy5fbG9va3VwTmV4dCh0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmUsIHBhdFBvcywgdGhpcy5hY2NlcHRQYXR0ZXJuQ2hhcik7IHRva2VuICE9IG51bGw7ICApewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnN1bWUodG9rZW4pOwogICAgICAgICAgICAgICAgICAgICAgICBwYXRQb3MgPSBwYXRQb3MgKyB0b2tlbi5sZW47CiAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuID0gdGhpcy5fbG9va3VwTmV4dCh0aGlzLmpzb25Nb2RlbC5fc1BpY3R1cmUsIHBhdFBvcywgdGhpcy5hY2NlcHRQYXR0ZXJuQ2hhcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfWNhdGNoKGUpewogICAgICAgICAgICAgICAgICAgIC8vbWlzbWF0Y2gsIHRyeSBhZ2FpbiEKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl9tQmFja3RyYWNrKXsKICAgICAgICAgICAgICAgICAgICAgICAgcGF0UG9zID0gdGhpcy5fbUJhY2t0cmFjay5wYXRQb3M7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5sZW5ndGggPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdHJQb3MgPSB0aGlzLl9tQmFja3RyYWNrLnN0clBvczsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJEaWdpdFNlZW4gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbUJhY2t0cmFjayA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb25zdW1lU3ViUGF0dGVybiA6IGZ1bmN0aW9uKHRva2VuKXsKCiAgICAgICAgICAgIHZhciBjaHIgPSB0b2tlbi5wYXRDaGFyOwogICAgICAgICAgICB2YXIgY2hyQ250ID0gdG9rZW4ubGVuOwogICAgICAgICAgICB2YXIgZncgPSBmYWxzZTsKICAgICAgICAgICAgc3dpdGNoIChjaHIpIHsKICAgICAgICAgICAgICAgIGNhc2UgJzknOgogICAgICAgICAgICAgICAgY2FzZSAnOCc6CiAgICAgICAgICAgICAgICBjYXNlICdaJzogLy8gRGlnaXQgb3Igc3BhY2UgaWYgemVyby4KICAgICAgICAgICAgICAgIGNhc2UgJ3onOi8vIERpZ2l0IG9yIG5vdGhpbmcgaWYgemVyby4KICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hyQ250LS0gPiAwICkgewogICAgICAgICAgICAgICAgICAgICAgICBpZighdGhpcy5fbWJEaWdpdFNlZW4pewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNVbmkgPSB0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy5jaGFyQXQodGhpcy5fc3RyUG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNVbmkgPT0gJy0nKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYk5lZ2F0aXZlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjVW5pID0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcuY2hhckF0KCsrdGhpcy5fc3RyUG9zKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNocj09ICc5JyB8fCBjaHIgPT0gJzgnKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZigheGZhbGliLnV0LlBpY3R1cmVVdGlscy5pc0RpZ2l0KGNVbmkpKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBkaWdpdCBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKGNVbmkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iRGlnaXRTZWVuID10cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2UgaWYoY2hyID09J1onKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZih4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmlzRGlnaXQoY1VuaSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIucHVzaChjVW5pKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJEaWdpdFNlZW4gPXRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2UgaWYoY1VuaSAhPSAnICcpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCBhIGRpZ2l0IG9yIHNwYWNlIGFzIGV4cGVjdGVkIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaGFzIHRvIGJlICd6JywgZWFnZXJseSB0cnkgdG8gbWF0Y2ggYSBkaWdpdCwgaWYgYSBtaXNtYXRjaCBpcyBsYXR0ZXJseSBmb3VuZCwgYmFja3RyYWNrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoeGZhbGliLnV0LlBpY3R1cmVVdGlscy5pc0RpZ2l0KGNVbmkpKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2goY1VuaSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iRGlnaXRTZWVuID10cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tQmFja3RyYWNrID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInBhdFBvcyIgOiB0b2tlbi5wYXRQb3MgKyB0b2tlbi5sZW4gLSBjaHJDbnQsIC8vbmV3IHBvc2l0aW9uIGZyb20gbmV4dCBjaGFyIGFmdGVyICd6JwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInN0clBvcyIgOiB0aGlzLl9zdHJQb3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJUZXh0UGFyc2luZzogbm90IGEgZGlnaXQgb3Igc3BhY2UgYXMgZXhwZWN0ZWQiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICsrdGhpcy5fc3RyUG9zOwogICAgICAgICAgICAgICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjVW5pID0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcuY2hhckF0KHRoaXMuX3N0clBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZih4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmlzRGlnaXQoY1VuaSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKGNVbmkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsrdGhpcy5fc3RyUG9zOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2hyICE9J3onKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBkaWdpdCBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsrdGhpcy5fc3RyUG9zOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdWJyA6CiAgICAgICAgICAgICAgICBjYXNlICd2JyA6CiAgICAgICAgICAgICAgICBjYXNlICcuJyA6CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fbWF0Y2hTdHIodGhpcy5fbU51bWJlclN5bWJvbHMuZGVjaW1hbCkpewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYXNSYWRpeCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKCcuJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iRGlnaXRTZWVuID10cnVlOwogICAgICAgICAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCBhIHJhZGl4IGFzIGV4cGVjdGVkIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdFJzogLy8gRXhwb25lbnQuCiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fbWF0Y2hTdHIoJ0UnKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5wdXNoKCdFJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX21hdGNoU3RyKCcrJykpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2UgaWYodGhpcy5fbWF0Y2hTdHIoJy0nKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC5fYnVmZmVyLnB1c2goJy0nKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyTGVuID0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSh0aGlzLl9zdHJQb3MgPCBzdHJMZW4gJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuaXNEaWdpdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy5jaGFyQXQodGhpcy5fc3RyUG9zKSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnB1c2godGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcuY2hhckF0KHRoaXMuX3N0clBvcysrKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSAnQyc6IC8vIENSIHN5bWJvbCBpZiBuZWdhdGl2ZSBhbmQgc3BhY2VzIGlmIHBvc2l0aXZlLgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX21hdGNoU3RyKHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYy5nc0NSKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iTmVnYXRpdmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH1lbHNlIGlmKCF0aGlzLl9tYXRjaFN0cih4ZmFsaWIudXQuTnVtUGljdHVyZURlc2MuZ3NEU1ApKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBDUiBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnYyc6IC8vIENSIHN5bWJvbCBpZiBuZWdhdGl2ZSBhbmQgbm90aGluZyBpZiBwb3NpdGl2ZS4KICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl9tYXRjaFN0cih4ZmFsaWIudXQuTnVtUGljdHVyZURlc2MuZ3NDUikpewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYk5lZ2F0aXZlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdEJzogLy8gREIgc3ltYm9sIGlmIG5lZ2F0aXZlIGFuZCBzcGFjZXMgaWYgcG9zaXRpdmUuCiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fbWF0Y2hTdHIoeGZhbGliLnV0Lk51bVBpY3R1cmVEZXNjLmdzREIpKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJOZWdhdGl2ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfWVsc2UgaWYoIXRoaXMuX21hdGNoU3RyKHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYy5nc0RTUCkpewogICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCBhIENSIGFzIGV4cGVjdGVkIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdkJzogLy8gREIgc3ltYm9sIGlmIG5lZ2F0aXZlIGFuZCBub3RoaW5nIGlmIHBvc2l0aXZlLgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX21hdGNoU3RyKHhmYWxpYi51dC5OdW1QaWN0dXJlRGVzYy5nc0RCKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iTmVnYXRpdmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ1MnOiAvLyBNaW51cyBzaWduIGlmIG5lZ2F0aXZlIGFuZCBhIHNwYWNlIGlmIHBvc2l0aXZlLgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX21hdGNoU3RyKHRoaXMuX21OdW1iZXJTeW1ib2xzLm5lZ2F0aXZlLGZ3KSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21iTmVnYXRpdmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH1lbHNlIGlmKCF0aGlzLl9tYXRjaFN0cigiICIpKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBDUiBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAncyc6CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fbWF0Y2hTdHIodGhpcy5fbU51bWJlclN5bWJvbHMubmVnYXRpdmUsZncpKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWJOZWdhdGl2ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAweEZGMEM6IC8vIEZ1bGx3aWR0aCAnLCcuCiAgICAgICAgICAgICAgICBjYXNlICcsJzogLy8gR3JvdXBpbmcgc2VwYXJhdG9yLgogICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaHJDbnQtLSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIXRoaXMuX21hdGNoU3RyKHRoaXMuX21OdW1iZXJTeW1ib2xzLmdyb3VwaW5nLCBmdykpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBncm91cGluZyBzeW1ib2wgYXMgZXhwZWN0ZWQiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAweEZGMDQ6IC8vIEZ1bGx3aWR0aCAnJCcuCiAgICAgICAgICAgICAgICBjYXNlICckJzogLy8gQ3VycmVuY3kgbmFtZSBvciBzeW1ib2wuCiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNockNudC0tID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZighdGhpcy5fbWF0Y2hTdHIodGhpcy5fbUN1cnJlbmN5U3ltYm9scy5zeW1ib2wsIGZ3KSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAiVGV4dFBhcnNpbmc6IG5vdCBhIGdyb3VwaW5nIHN5bWJvbCBhcyBleHBlY3RlZCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDB4RkYwNTogLy8gRnVsbHdpZHRoICclJy4KICAgICAgICAgICAgICAgIGNhc2UgJyUnOiAvLyBQZXJjZW50IHN5bWJvbC4KICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hyQ250LS0gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCF0aGlzLl9tYXRjaFN0cih0aGlzLl9tTnVtYmVyU3ltYm9scy5wZXJjZW50LCBmdykpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgIlRleHRQYXJzaW5nOiBub3QgYSBncm91cGluZyBzeW1ib2wgYXMgZXhwZWN0ZWQiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhc1BlcmNlbnQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAweEZGMDg6IC8vIEZ1bGx3aWR0aCAnKCcuCiAgICAgICAgICAgICAgICBjYXNlIDB4RkYwOTogLy8gRnVsbHdpZHRoICcpJy4KICAgICAgICAgICAgICAgIGNhc2UgJygnOiAvLyBMZWZ0IHBhcmVudGhlc2lzLgogICAgICAgICAgICAgICAgY2FzZSAnKSc6IC8vIFJpZ2h0IHBhcmVudGhlc2lzLgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX21hdGNoU3RyKGNocixmdykpewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYk5lZ2F0aXZlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9ZWxzZSBpZighdGhpcy5fbWF0Y2hTdHIoIiAiKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICJUZXh0UGFyc2luZzogbm90IHBhcmVudGVzaXMgYXMgZXhwZWN0ZWQiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ3QnOiAvLyB0YWIuCiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNockNudC0tID4gMCkgdGhpcy5fbWF0Y2hTdHIoJ1x0Jyxmdyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGdldFJlc3VsdCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciBzdHJpbmdOdW0gPSAgdGhpcy5fYnVmZmVyLmpvaW4oIiIpOwogICAgICAgICAgICBpZih0aGlzLl9oYXNQZXJjZW50KSB7CiAgICAgICAgICAgICAgICB2YXIgYnVmID0gbmV3IEFycmF5KCk7CiAgICAgICAgICAgICAgICBzdHJpbmdOdW0gPSBOdW1iZXIoc3RyaW5nTnVtKS50b1N0cmluZygpOwogICAgICAgICAgICAgICAgdmFyIGRvdCA9IHN0cmluZ051bS5pbmRleE9mKCcuJyk7CgogICAgICAgICAgICAgICAgdmFyIHBvcyA9IGRvdC0yOwogICAgICAgICAgICAgICAgaWYocG9zID09MCkgYnVmLnB1c2goIjAiKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYocG9zID09LTEpIGJ1Zi5wdXNoKCIwLjAiKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYocG9zID09LTMpIHBvcyA9IHN0cmluZ051bS5sZW5ndGggLSAyOwogICAgICAgICAgICAgICAgZm9yKHZhciBpbmRleD0wO2luZGV4IDwgc3RyaW5nTnVtLmxlbmd0aDsgaW5kZXgrKyl7CiAgICAgICAgICAgICAgICAgICAgaWYoaW5kZXggPT0gcG9zKXsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goIi4iKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYoaW5kZXggIT0gZG90KXsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLnB1c2goc3RyaW5nTnVtLmNoYXJBdChpbmRleCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHN0cmluZ051bSA9IGJ1Zi5qb2luKCIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgbnVtYmVyID0gTnVtYmVyKHN0cmluZ051bSk7CiAgICAgICAgICAgIGlmKHRoaXMuX21iTmVnYXRpdmUpIG51bWJlciA9IC1udW1iZXI7CiAgICAgICAgICAgIHJldHVybiBudW1iZXIudG9TdHJpbmcoKTsKICAgICAgICB9LAoKICAgICAgICBfbWF0Y2hTdHIgOiBmdW5jdGlvbih0YXJnZXQpewogICAgICAgICAgICBpZih4ZmFsaWIudXQuUGljdHVyZVV0aWxzLm1hdGNoU3RyaW5nKHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCB0aGlzLl9zdHJQb3MsIHRhcmdldCkpewogICAgICAgICAgICAgICAgdGhpcy5fc3RyUG9zKz0gdGFyZ2V0Lmxlbmd0aDsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgYWNjZXB0UGF0dGVybkNoYXIgOiBmdW5jdGlvbihjaHIpewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlBpY3R1cmVVdGlscy5pblN0cmluZyhjaHIsICIoJSQsLik4OUJDREVSU1ZaYmNkcnN2enQiKTsKICAgICAgICB9CiAgICB9KTsKfSkoXyx4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnV0LkRhdGVQYXJzaW5nVmlzaXRvcgogKiBAaW1wb3J0IHhmYWxpYi51dC5QYXJzaW5nVmlzaXRvckJhc2UKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBwcm92aWRlcyBwYXJzaW5nL2Zvcm1hdGluZyBsb2dpYyBvbiBkYXRlIHBhdHRlcm4gY2hhcmFjdGVycy4KICogQHZlcnNpb24gMC4wLjEKICovCgovKioKICogQGNvbnN0cnVjdG9yCiAqIEBwYXJhbSBPYmplY3Qge2pzb25Nb2RlbDoge19zUGljdHVyZTogU3RyaW5nLCBfZGF0YVN0cmluZzogU3RyaW5nXX0KICovCgooZnVuY3Rpb24oXyx4ZmFsaWIpIHsKICAgIHZhciBEYXRlUGFyc2luZ1Zpc2l0b3IgPSB4ZmFsaWIudXQuRGF0ZVBhcnNpbmdWaXNpdG9yID0geGZhbGliLnV0LlBhcnNpbmdWaXNpdG9yQmFzZS5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdGhpcy5fZGF0ZUluZm8gPSBuZXcgeGZhbGliLnV0LkRhdGVJbmZvKHtpc1BhcnNpbmdDYWxsIDogdHJ1ZX0pOwogICAgICAgICAgICB0aGlzLl9kYXlPZk1vbnRoID0gdGhpcy5fbW9udGhPZlllYXIgPSB0aGlzLl95ZWFyT2ZFcmEgPSBudWxsOyAvLyB1c2VkIHRvIHZhbGlkYXRlIGRhdGUgb25jZSBhbGwgc3ViIHBhdHRlcm5zIGFyZSBjb25zdW1lZAogICAgICAgICAgICBEYXRlUGFyc2luZ1Zpc2l0b3IuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICB9LAoKICAgICAgICBjb25zdW1lU3ViUGF0dGVybiA6IGZ1bmN0aW9uKHRva2VuKXsKICAgICAgICAgICAgdmFyIGNociA9IHRva2VuLnBhdENoYXI7CiAgICAgICAgICAgIHZhciBjaHJDbnQgPSB0b2tlbi5sZW47CiAgICAgICAgICAgIHZhciBjdXJQb3MgPSB0aGlzLl9zdHJQb3M7CiAgICAgICAgICAgIHZhciBzY2FubmVkQ2hhciA9IGNockNudDsKCiAgICAgICAgICAgIC8vVE9ETzogbmVlZCB0byByZW1vdmUgdGhpcyBhc3NlcnQuCiAgICAgICAgICAgIHRoaXMuX2Fzc2VydChjdXJQb3MrY2hyQ250IDw9dGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcubGVuZ3RoLCAiTWlzbWF0Y2giKTsKCiAgICAgICAgICAgIHN3aXRjaCAoY2hyKSB7CiAgICAgICAgICAgICAgICBjYXNlICdEJzoKICAgICAgICAgICAgICAgICAgICBzd2l0Y2goY2hyQ250KXsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcnNlZCA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMucGFyc2VJbnRBZ2dyZXNzaXZlKHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCBjdXJQb3MsIDIpOyAvLyAxLTIgZGlnaXQoMS0zMSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2RheU9mTW9udGggPSBwYXJzZWQudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FubmVkQ2hhciA9IHBhcnNlZC5sZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGF5T2ZNb250aCA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMucGFyc2VJbnRFeGFjdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMS0yIGRpZ2l0KDEtMzEpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXNzZXJ0KHRoaXMuX2RheU9mTW9udGggPD0gMzEgJiYgdGhpcy5fZGF5T2ZNb250aCA+MCwgIkludmFsaWQgZGF0ZSBzdHJpbmcxIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdKJzoKCiAgICAgICAgICAgICAgICAgICAgLy90aGlzLl9tRGF5T2ZZZWFyOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnTSc6CiAgICAgICAgICAgICAgICAgICAgdmFyIHN5bWJvbCA9ICIiOwogICAgICAgICAgICAgICAgICAgIHN3aXRjaChjaHJDbnQpewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyc2VkID0geGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYXJzZUludEFnZ3Jlc3NpdmUodGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcsIGN1clBvcywgMik7IC8vIDEtMiBkaWdpdCgxLTEyKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbW9udGhPZlllYXIgPSBwYXJzZWQudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FubmVkQ2hhciA9IHBhcnNlZC5sZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbW9udGhPZlllYXIgPSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLnBhcnNlSW50RXhhY3QodGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcsIGN1clBvcywgMik7IC8vIDIgZGlnaXQoMDEtMTIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltYm9sID0gImNhbGVuZGFyU3ltYm9scy5hYmJybW9udGhOYW1lcyI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltYm9sID0gImNhbGVuZGFyU3ltYm9scy5tb250aE5hbWVzIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZihzeW1ib2wpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2hPYmogPSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLmdldEhhc2hPZkxvY2FsZU9iamVjdCh0aGlzLmpzb25Nb2RlbC5fbG9jYWxlLHN5bWJvbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIgPSB0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZy50b0xvd2VyQ2FzZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzaCA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJTdHIgPSAiIgogICAgICAgICAgICAgICAgICAgICAgICBzY2FubmVkQ2hhciA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlKGN1clBvcytzY2FubmVkQ2hhciA8IHN0ci5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc2ggKz0gKHNjYW5uZWRDaGFyKzEpKnN0ci5jaGFyQ29kZUF0KGN1clBvcytzY2FubmVkQ2hhcikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1clN0cis9IHN0ci5jaGFyQXQoY3VyUG9zK3NjYW5uZWRDaGFyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5uZWRDaGFyKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihoYXNoT2JqW2hhc2hdICYmIGhhc2hPYmpbaGFzaF0uaW5kZXhPZihjdXJTdHIpID4gLTEgKSBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbW9udGhOYW1lcyA9IF8ubWFwKHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0TG9jYWxlT2JqZWN0KHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsIHN5bWJvbCksIGZ1bmN0aW9uIChzdHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdHIudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoT2ZZZWFyID0gbW9udGhOYW1lcy5pbmRleE9mKGN1clN0cikgKyAxOyAvLyBtb250aHMgYXJlIGZyb20gMSB0byAxMgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvL1RPRE86IHJlbW92ZSB0aGlzIGFzc2VydAogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Fzc2VydCh0aGlzLl9tb250aE9mWWVhciA8PSAxMiAmJiB0aGlzLl9tb250aE9mWWVhciA+MCwgIkludmFsaWQgZGF0ZSBzdHJpbmcyIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdFJzoKICAgICAgICAgICAgICAgICAgICB2YXIgc3ltYm9sID0gIiIKICAgICAgICAgICAgICAgICAgICBzd2l0Y2goY2hyQ250KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5uZWRDaGFyID0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW1ib2wgPSAiY2FsZW5kYXJTeW1ib2xzLmFiYnJkYXlOYW1lcyI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ltYm9sID0gImNhbGVuZGFyU3ltYm9scy5kYXlOYW1lcyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgInVuc3VwcG9ydGVkIFBpY3R1cmUgQ2xhdXNlICI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmKHN5bWJvbCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGFzaE9iaiA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMuZ2V0SGFzaE9mTG9jYWxlT2JqZWN0KHRoaXMuanNvbk1vZGVsLl9sb2NhbGUsc3ltYm9sKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbm5lZENoYXIgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyID0gdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2ggPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyU3RyID0gIiI7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlKGN1clBvcytzY2FubmVkQ2hhciA8IHN0ci5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc2ggKz0gKHNjYW5uZWRDaGFyKzEpKnN0ci5jaGFyQ29kZUF0KGN1clBvcytzY2FubmVkQ2hhcikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1clN0cis9IHN0ci5jaGFyQXQoY3VyUG9zK3NjYW5uZWRDaGFyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5uZWRDaGFyKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihoYXNoT2JqW2hhc2hdICYmIGhhc2hPYmpbaGFzaF0uaW5kZXhPZihjdXJTdHIpID4gLTEpIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgJ2UnOgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAnRyc6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdZJzoKCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGNockNudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3llYXJPZkVyYSA9IHhmYWxpYi51dC5QaWN0dXJlVXRpbHMucGFyc2VJbnRFeGFjdCh0aGlzLmpzb25Nb2RlbC5fZGF0YVN0cmluZywgY3VyUG9zLCAyKTsgLy8gMiBkaWdpdCgwMC05OSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3llYXJPZkVyYSs9MjAwMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX3llYXJPZkVyYSA+PSAyMDI5KXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl95ZWFyT2ZFcmEgLT0xMDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feWVhck9mRXJhID0geGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYXJzZUludEV4YWN0KHRoaXMuanNvbk1vZGVsLl9kYXRhU3RyaW5nLCBjdXJQb3MsIDQpOyAvLyAyIGRpZ2l0KDAwMDAtOTk5OSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYXNzZXJ0KHRoaXMuX3llYXJPZkVyYSA8PSA5OTk5ICYmIHRoaXMuX3llYXJPZkVyYSA+PTAsICJJbnZhbGlkIGRhdGUgc3RyaW5nMyIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAndyc6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICdXJzoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93ICJVbnN1cHBvcnRlZCBwYXR0ZXJuIjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYodGhpcy5feWVhck9mRXJhICYmIHRoaXMuX21vbnRoT2ZZZWFyICYmIHRoaXMuX2RheU9mTW9udGgpewogICAgICAgICAgICAgICAgdGhpcy5fZGF0ZUluZm8udmFsaWRhdGUodGhpcy5feWVhck9mRXJhLCB0aGlzLl9tb250aE9mWWVhciwgdGhpcy5fZGF5T2ZNb250aCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX3N0clBvcyArPSBzY2FubmVkQ2hhcjsKICAgICAgICB9LAoKICAgICAgICBnZXREYXRlIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGVJbmZvLmRhdGU7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0UmVzdWx0OiBmdW5jdGlvbigpewogICAgICAgICAgICBpZiAodGhpcy5fc3RyUG9zIDwgdGhpcy5qc29uTW9kZWwuX2RhdGFTdHJpbmcubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB0aHJvdyAiRGF0ZVBhcnNpbmc6IHBpY3R1cmUgY2xhdXNlIHNtYWxsZXIgdGhhbiBpbnB1dCBEYXRlIjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdGhpcy5fZGF0ZUluZm8uZ2V0SVNPRGF0ZSgpOwogICAgICAgIH0sCgogICAgICAgIF9hc3NlcnQgOiBmdW5jdGlvbihjb25kaXRpb24sIG1lc3NhZ2UpewogICAgICAgICAgICBpZighY29uZGl0aW9uKXsKICAgICAgICAgICAgICAgIHRocm93IG1lc3NhZ2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKfSkoXyx4ZmFsaWIpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogQURPQkUgQ09ORklERU5USUFMCiAqIF9fX19fX19fX19fX19fX19fX18KICoKICogIENvcHlyaWdodCAyMDEzIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuCiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewoKICAgIHZhciBMb2NhbGl6YXRpb25VdGlsID0geGZhbGliLnV0LkxvY2FsaXphdGlvblV0aWwgPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKCiAgICAgICAgZ2V0TG9jYWxpemVkTWVzc2FnZTogZnVuY3Rpb24oY2F0ZWdvcnksIG1lc3NhZ2UsIHNuaXBwZXRzKXsKICAgICAgICAgICAgdmFyIHJlc29sdmVkTWVzc2FnZSA9IG1lc3NhZ2U7CiAgICAgICAgICAgIGlmKHNuaXBwZXRzKXsKICAgICAgICAgICAgICAgIC8vcmVzb2x2ZSBtZXNzYWdlIHdpdGggc25pcHBldAogICAgICAgICAgICAgICAgcmVzb2x2ZWRNZXNzYWdlID0gcmVzb2x2ZWRNZXNzYWdlLnJlcGxhY2UoL3soXGQrKX0vZywgZnVuY3Rpb24obWF0Y2gsIG51bWJlcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlb2Ygc25pcHBldHNbbnVtYmVyXSAhPSAndW5kZWZpbmVkJwogICAgICAgICAgICAgICAgICAgICAgICA/IHNuaXBwZXRzW251bWJlcl0KICAgICAgICAgICAgICAgICAgICAgICAgOiBtYXRjaAogICAgICAgICAgICAgICAgICAgICAgICA7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgdGV4dCA9ICIiOwogICAgICAgICAgICBpZiAoY2F0ZWdvcnkpIHsKICAgICAgICAgICAgICAgIHRleHQgKz0gIiBbIiArIGNhdGVnb3J5ICsgIl0iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRleHQgKz0gIiAgIiArIHJlc29sdmVkTWVzc2FnZSArICJcclxuIiA7CiAgICAgICAgICAgIHJldHVybiB0ZXh0OwogICAgICAgIH0KCiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogX19fX19fX19fX19fX19fX19fXwogKgogKiAgQ29weXJpZ2h0IDIwMTMgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LnV0aWwuVGV4dE1ldHJpY3MgPSB7CiAgICAgICAgeGZhVXRpbCA6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZSwKICAgICAgICBFUlJPUl9NQVJHSU4gOiAxLAogICAgICAgICRtZWFzdXJlRWwgOiBudWxsLAogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbihkaXZFbCl7CiAgICAgICAgICAgIGlmKCFkaXZFbCl7CiAgICAgICAgICAgICAgICB2YXIgJGRpdiA9ICQoIjxkaXY+PC9kaXY+Iik7CiAgICAgICAgICAgICAgICAkZGl2LmF0dHIoImlkIiwgInRleHRNZXRyaWNzIik7CiAgICAgICAgICAgICAgICB2YXIgZGl2U3R5bGVzID0ge307CiAgICAgICAgICAgICAgICBkaXZTdHlsZXMubGVmdCA9IC0xMDAwOwogICAgICAgICAgICAgICAgZGl2U3R5bGVzLnRvcCA9IC0xMDAwOwogICAgICAgICAgICAgICAgZGl2U3R5bGVzLnBvc2l0aW9uID0gImFic29sdXRlIjsKICAgICAgICAgICAgICAgIGRpdlN0eWxlcy52aXNpYmlsaXR5ID0gImhpZGRlbiI7CiAgICAgICAgICAgICAgICB0aGlzLnhmYVV0aWwuJGNzcygkZGl2LmdldCgwKSwgZGl2U3R5bGVzKTsKICAgICAgICAgICAgICAgIHRoaXMuJG1lYXN1cmVFbCA9ICRkaXY7CiAgICAgICAgICAgICAgICAkKCJib2R5IikuYXBwZW5kKHRoaXMuJG1lYXN1cmVFbCk7CiAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgdGhpcy4kbWVhc3VyZUVsID0gZGl2RWw7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBtZWFzdXJlRXh0ZW50IDogZnVuY3Rpb24odGV4dCwgb3B0aW9ucyl7CiAgICAgICAgICAgIHRleHQgPSB0ZXh0ICsgIiAiOwogICAgICAgICAgICBpZighdGhpcy4kbWVhc3VyZUVsKXsKICAgICAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogICAgICAgICAgICB2YXIgdGV4dFN0eWxlcyA9IHt9OwogICAgICAgICAgICB2YXIgJHJlZkVsID0gICQob3B0aW9ucy5yZWZFbCB8fCAiPGRpdj48L2Rpdj4iKSA7CiAgICAgICAgICAgIHZhciByZWZFbCA9ICRyZWZFbC5nZXQoMCk7CiAgICAgICAgICAgIHRleHRTdHlsZXMuZm9udFNpemUgPSAkcmVmRWwuY3NzKCJmb250U2l6ZSIpIHx8IG9wdGlvbnNbImZvbnQtc2l6ZSJdIHx8IG9wdGlvbnNbImZvbnRTaXplIl07CiAgICAgICAgICAgIHRleHRTdHlsZXMuZm9udFN0eWxlID0gJHJlZkVsLmNzcygiZm9udFN0eWxlIikgfHwgb3B0aW9uc1siZm9udC1zdHlsZSJdIHx8IG9wdGlvbnNbImZvbnRTdHlsZSJdOwogICAgICAgICAgICB0ZXh0U3R5bGVzLmZvbnRXZWlnaHQgPSAkcmVmRWwuY3NzKCJmb250V2VpZ2h0IikgfHwgb3B0aW9uc1siZm9udC13ZWlnaHQiXSB8fCBvcHRpb25zWyJmb250V2VpZ2h0Il07CiAgICAgICAgICAgIHRleHRTdHlsZXMuZm9udEZhbWlseSA9ICRyZWZFbC5jc3MoImZvbnRGYW1pbHkiKSB8fCBvcHRpb25zWyJmb250LWZhbWlseSJdIHx8IG9wdGlvbnNbImZvbnRGYW1pbHkiXTsKICAgICAgICAgICAgdGV4dFN0eWxlcy5saW5lSGVpZ2h0ID0gcmVmRWwuc3R5bGUubGluZUhlaWdodCB8fCBvcHRpb25zWyJsaW5lLWhlaWdodCJdIHx8IG9wdGlvbnNbImxpbmVIZWlnaHQiXTsKICAgICAgICAgICAgdGV4dFN0eWxlcy5sZXR0ZXJTcGFjaW5nID0gJHJlZkVsLmNzcygibGV0dGVyU3BhY2luZyIpIHx8IG9wdGlvbnNbImxldHRlci1zcGFjaW5nIl0gfHwgb3B0aW9uc1sibGV0dGVyU3BhY2luZyJdOwogICAgICAgICAgICB0ZXh0U3R5bGVzLndoaXRlU3BhY2UgPSAgJHJlZkVsLmNzcygid2hpdGVTcGFjZSIpIHx8IG9wdGlvbnNbIndoaXRlLXNwYWNlIl0gfHwgb3B0aW9uc1sid2hpdGVTcGFjZSJdIHx8ICJwcmUtd3JhcCI7CiAgICAgICAgICAgIGlmKCAkLmJyb3dzZXIubW96aWxsYSAmJiAkcmVmRWwuaXMoInRleHRhcmVhIikpICAgICAgLy8gZm9yIEJ1ZyAjMzYyMTE4MAogICAgICAgICAgICAgICAgdGV4dFN0eWxlcy53aGl0ZVNwYWNlID0gInByZS13cmFwIjsKICAgICAgICAgICAgdGV4dFN0eWxlcy53b3JkQnJlYWsgPSAgJHJlZkVsLmNzcygid29yZEJyZWFrIikgfHwgb3B0aW9uc1sid29yZC1icmVhayJdIHx8IG9wdGlvbnNbIndvcmRCcmVhayJdIHx8ICJicmVhay1hbGwiOwogICAgICAgICAgICB0ZXh0U3R5bGVzLndvcmRXcmFwID0gICRyZWZFbC5jc3MoIndvcmRXcmFwIikgfHwgb3B0aW9uc1sid29yZC13cmFwIl0gfHwgb3B0aW9uc1sid29yZFdyYXAiXSB8fCAiYnJlYWstd29yZCI7CiAgICAgICAgICAgIHRleHRTdHlsZXMud2lkdGggPSB0aGlzLl9lbFdpZHRoKHJlZkVsLCBvcHRpb25zKTsKICAgICAgICAgICAgdGV4dFN0eWxlcy5oZWlnaHQgPSB0aGlzLl9lbEhlaWdodChyZWZFbCwgb3B0aW9ucyk7CiAgICAgICAgICAgIHRleHRTdHlsZXMubWluV2lkdGggPSB0aGlzLl9lbE1pbldpZHRoKHJlZkVsLCBvcHRpb25zKTsKICAgICAgICAgICAgdGV4dFN0eWxlcy5taW5IZWlnaHQgPSB0aGlzLl9lbE1pbkhlaWdodChyZWZFbCwgb3B0aW9ucyk7CiAgICAgICAgICAgIHRleHRTdHlsZXMubWF4V2lkdGggPSB0aGlzLl9lbE1heFdpZHRoKHJlZkVsLCBvcHRpb25zKTsKICAgICAgICAgICAgdGV4dFN0eWxlcy5tYXhIZWlnaHQgPSB0aGlzLl9lbE1heEhlaWdodChyZWZFbCwgb3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMueGZhVXRpbC4kY3NzKHRoaXMuJG1lYXN1cmVFbC5nZXQoMCksIHRleHRTdHlsZXMpOwogICAgICAgICAgICAvLyBmb3IgdGV4dCBmaWVsZHMvYXJlYXMgYW5kIGRyYXcgcmVxdWlyaW5nIHJpY2ggdGV4dCBzdXBwb3J0CiAgICAgICAgICAgIGlmKG9wdGlvbnMuY29udGVudFR5cGUgPT09ICJ0ZXh0L2h0bWwiKXsKICAgICAgICAgICAgICAvLyByZXRhaW5pbmcgZm9yIGZ1dHVyZSB1c2UgLiBJZiB3ZSB1c2UgdGhlIGFib3ZlIHByb3BlcnR5IGZvciBvdGhlciByaWNoIHRleHQKICAgICAgICAgICAgICAgaWYob3B0aW9ucy5za2lwWFNTUHJvdGVjdGlvbikgewogICAgICAgICAgICAgICAgIHRoaXMuJG1lYXN1cmVFbC5odG1sKHRleHQpOwogICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgIHRoaXMuJG1lYXN1cmVFbC5odG1sKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5lbmNvZGVTY3JpcHRhYmxlVGFncyh0ZXh0KSk7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfWVsc2UgewogICAgICAgICAgICAgICB0ZXh0ID0gdGV4dC5yZXBsYWNlKC9cblxyL2csIlxuIikucmVwbGFjZSgvXHJcbi9nLCJcbiIpLnJlcGxhY2UoL1xyL2csICJcbiIpOwogICAgICAgICAgICAgICB0aGlzLiRtZWFzdXJlRWwudGV4dCh0ZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgbWVhc3VyZWRXaWR0aCA9ICB0aGlzLiRtZWFzdXJlRWwud2lkdGgoKTsKICAgICAgICAgICAgdmFyIG1lYXN1cmVkSGVpZ2h0ID0gIHRoaXMuJG1lYXN1cmVFbC5oZWlnaHQoKTsKCiAgICAgICAgICAgIGlmKG1lYXN1cmVkV2lkdGggPT0gTWF0aC5jZWlsKG9wdGlvbnNbIndpZHRoIl0pIHx8IG1lYXN1cmVkV2lkdGggPT0gTWF0aC5mbG9vcihvcHRpb25zWyJ3aWR0aCJdKSl7CiAgICAgICAgICAgICAgICBtZWFzdXJlZFdpZHRoID0gb3B0aW9uc1sid2lkdGgiXTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKgogICAgICAgICAgICAgRk9STVMtMTEzNjMgOiBmaXggZm9yIGhlaWdodCBjYWxjdWxhdGlvbiBvZiB0YWJsZSBjZWxsCiAgICAgICAgICAgICBFbmFibGUgdGhpcyB0b2dnbGUgZm9yIG9sZCBiZWhhdmlvdXIgKGlmIGFueSByZWdyZXNzaW9uIGNvbWVzKQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZWxzZSBpZiAoKHdpbmRvdy5GRCAmJiB3aW5kb3cuRkQuaXNUb2dnbGVFbmFibGVkKCJGVF9GT1JNUy0xMTM2MyIpKSAmJiAob3B0aW9uc1sibWF4V2lkdGgiXSA+IG1lYXN1cmVkV2lkdGggfHwgKG1lYXN1cmVkV2lkdGggPiBvcHRpb25zWyJtaW5XaWR0aCJdID4gMCAmJiAob3B0aW9uc1sibWF4V2lkdGgiXSB8fCAtMSkgPCAwKSkpIHsKICAgICAgICAgICAgICAgIC8vY29tcGxpY2F0ZWQsIHBsZWFzZSBzaW1wbGlmeSBpZiBiZWxvdyBodXJ0cyB5b3U6ICBBZGQgZXJyb3IgbWFyZ2luIGlmIHRoZXJlIGlzIHNjb3BlIG9mIGZ1cnRoZXIgZXh0ZW5zaW9uIG9mIGV4dGVudAogICAgICAgICAgICAgICAgbWVhc3VyZWRXaWR0aCA9IG1lYXN1cmVkV2lkdGggKyAxOwogICAgICAgICAgICB9IGVsc2UgaWYgKG9wdGlvbnNbIm1heFdpZHRoIl0gPiBtZWFzdXJlZFdpZHRoIHx8IChtZWFzdXJlZFdpZHRoID4gb3B0aW9uc1sibWluV2lkdGgiXSA+IDAgJiYgKG9wdGlvbnNbIm1heFdpZHRoIl0gfHwgLTEpIDwgMCkpIHsKICAgICAgICAgICAgICAgIC8vY29tcGxpY2F0ZWQsIHBsZWFzZSBzaW1wbGlmeSBpZiBiZWxvdyBodXJ0cyB5b3U6ICBBZGQgZXJyb3IgbWFyZ2luIGlmIHRoZXJlIGlzIHNjb3BlIG9mIGZ1cnRoZXIgZXh0ZW5zaW9uIG9mIGV4dGVudAogICAgICAgICAgICAgICAgbWVhc3VyZWRXaWR0aCA9IG1lYXN1cmVkV2lkdGg7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKG1lYXN1cmVkSGVpZ2h0ID09IE1hdGguY2VpbChvcHRpb25zWyJoZWlnaHQiXSkgfHwgbWVhc3VyZWRIZWlnaHQgPT0gTWF0aC5mbG9vcihvcHRpb25zWyJoZWlnaHQiXSkpewogICAgICAgICAgICAgICAgbWVhc3VyZWRIZWlnaHQgPSBvcHRpb25zWyJoZWlnaHQiXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKCAkcmVmRWwuaXMoInRleHRhcmVhIikgJiYgKG9wdGlvbnNbIm1heEhlaWdodCJdID4gbWVhc3VyZWRIZWlnaHQgfHwgKG1lYXN1cmVkSGVpZ2h0ID4gb3B0aW9uc1sibWluSGVpZ2h0Il0gPiAwICYmIChvcHRpb25zWyJtYXhIZWlnaHQiXSB8fCAtMSkgPCAwKSkpewogICAgICAgICAgICAgICAgbWVhc3VyZWRIZWlnaHQgPSBtZWFzdXJlZEhlaWdodCArMTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLiRtZWFzdXJlRWwuZW1wdHkoKTsKICAgICAgICAgICAgcmV0dXJuIHt3aWR0aCA6IG1lYXN1cmVkV2lkdGgsIGhlaWdodCA6IG1lYXN1cmVkSGVpZ2h0fTsKICAgICAgICB9LAoKICAgICAgICBfZWxXaWR0aCA6IGZ1bmN0aW9uKHJlZkVsLCBvcHRpb25zKXsKICAgICAgICAgICAgaWYob3B0aW9uc1sibWluV2lkdGgiXSAmJiBvcHRpb25zWyJtaW5XaWR0aCJdID4gLTEpCiAgICAgICAgICAgICAgICByZXR1cm4gImF1dG8iOwogICAgICAgICAgICBlbHNlIGlmKG9wdGlvbnNbIm1heFdpZHRoIl0gJiYgb3B0aW9uc1sibWF4V2lkdGgiXSA+IC0xKQogICAgICAgICAgICAgICAgcmV0dXJuICJhdXRvIjsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnNbIndpZHRoIl0gfHwgImF1dG8iOwogICAgICAgIH0sCgogICAgICAgIF9lbEhlaWdodCA6IGZ1bmN0aW9uKHJlZkVsLCBvcHRpb25zKXsKICAgICAgICAgICAgLy8gVE9ETzogY2hlY2sgZm9yIGNhbGN1bGF0aW9ucyBoZXJlIGZvciBmbG9hdGluZyBmaWVsZCBhbmQgb3RoZXIgY2FzZXMuCiAgICAgICAgICAgIGlmKG9wdGlvbnNbImNvbnRlbnRUeXBlIl0gPT09ICJ0ZXh0L2h0bWwiKQogICAgICAgICAgICAgICAgcmV0dXJuICJhdXRvIjsKICAgICAgICAgICAgaWYob3B0aW9ucy5pc0RyYXcpIHsgLy8gZm9yIGhhbmRsaW5nIHRoZSBjYXNlIG9mIGRyYXcgaGF2aW5nIGZsb2F0aW5nIGZpZWxkcwogICAgICAgICAgICAgICAgcmV0dXJuICJhdXRvIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZighJChyZWZFbCkuaXMoInRleHRhcmVhIikpCiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9uc1siaGVpZ2h0Il0gfHwgImF1dG8iOwogICAgICAgICAgICBpZihvcHRpb25zWyJtaW5IZWlnaHQiXSAmJiBvcHRpb25zWyJtaW5IZWlnaHQiXSA+IC0xKQogICAgICAgICAgICAgICAgcmV0dXJuICJhdXRvIjsKICAgICAgICAgICAgZWxzZSBpZihvcHRpb25zWyJtYXhIZWlnaHQiXSAmJiBvcHRpb25zWyJtYXhIZWlnaHQiXSA+IC0xKQogICAgICAgICAgICAgICAgcmV0dXJuICJhdXRvIjsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnNbImhlaWdodCJdIHx8ICJhdXRvIjsKICAgICAgICB9LAoKICAgICAgICBfZWxNaW5XaWR0aCA6IGZ1bmN0aW9uKHJlZkVsLCBvcHRpb25zKXsKICAgICAgICAgICAgaWYob3B0aW9uc1sibWluV2lkdGgiXSAmJiBvcHRpb25zWyJtaW5XaWR0aCJdID4gLTEpCiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9uc1sibWluV2lkdGgiXTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuICIwIjsgLy9kZWZhdWx0IGNzcyB2YWx1ZQogICAgICAgIH0sCgogICAgICAgIF9lbE1pbkhlaWdodCA6IGZ1bmN0aW9uKHJlZkVsLCBvcHRpb25zKXsKICAgICAgICAgICAgaWYob3B0aW9uc1sibWluSGVpZ2h0Il0gJiYgb3B0aW9uc1sibWluSGVpZ2h0Il0gPiAtMSkKICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zWyJtaW5IZWlnaHQiXTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuICIwIjsgLy9kZWZhdWx0IGNzcyB2YWx1ZQogICAgICAgIH0sCgogICAgICAgIF9lbE1heFdpZHRoIDogZnVuY3Rpb24ocmVmRWwsIG9wdGlvbnMpewogICAgICAgICAgICBpZihvcHRpb25zWyJtYXhXaWR0aCJdICYmIG9wdGlvbnNbIm1heFdpZHRoIl0gPiAtMSkKICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zWyJtYXhXaWR0aCJdOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gIm5vbmUiOyAvL2RlZmF1bHQgY3NzIHZhbHVlCiAgICAgICAgfSwKCiAgICAgICAgX2VsTWF4SGVpZ2h0IDogZnVuY3Rpb24ocmVmRWwsIG9wdGlvbnMpewogICAgICAgICAgICBpZihvcHRpb25zWyJtYXhIZWlnaHQiXSAmJiBvcHRpb25zWyJtYXhIZWlnaHQiXSA+IC0xKQogICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnNbIm1heEhlaWdodCJdOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gIm5vbmUiOyAvL2RlZmF1bHQgY3NzIHZhbHVlCiAgICAgICAgfSwKCiAgICAgICAgX2Rlc3Ryb3kgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgJCgiI3RleHRNZXRyaWNzIikucmVtb3ZlKCk7CiAgICAgICAgICAgIHRoaXMuJG1lYXN1cmVFbCA9IG51bGw7CiAgICAgICAgfQogICAgfQp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oJCwgXykgewoKCSQuYWxlcnRCb3ggPSB7CgoJCXZlcnRpY2FsT2Zmc2V0OiAtNzUsCgkJaG9yaXpvbnRhbE9mZnNldDogMCwKCQlyZXBvc2l0aW9uT25SZXNpemU6IHRydWUsCgkJb3ZlcmxheU9wYWNpdHk6IDAuMDEsCgkJb3ZlcmxheUNvbG9yOiAnI0ZGRicsCgkJZHJhZ2dhYmxlOiBmYWxzZSwKCQlkaWFsb2dDbGFzczogbnVsbCwKCQlpbWFnZURpcmVjdG9yeTogIi4uIiwKCQlpbWFnZXM6IFsiQV9XYXJuaW5nX0xnX04ucG5nIiwgIkFfQWxlcnQyX0xnX04ucG5nIiwgIkNfUXVlc3Rpb25CdWJibGVfWGxfTi5wbmciLCAiQV9JbmZvQmx1ZV8zMngzMl9OLnBuZyJdLAoKCQlhbGVydDogZnVuY3Rpb24oaW1nLCBtZXNzYWdlLCB0aXRsZSwgY2FsbGJhY2spIHsKCQkJdGhpcy5fc2hvdyhpbWcsIHRpdGxlLCBtZXNzYWdlLCBudWxsLCAnT0snLCBmdW5jdGlvbihyZXN1bHQpIHsKCQkJCWlmKCBjYWxsYmFjayApIGNhbGxiYWNrKHJlc3VsdCk7CgkJCX0pOwoJCX0sCgoJCW9rQ2FuY2VsOiBmdW5jdGlvbihpbWcsIG1lc3NhZ2UsIHRpdGxlLCBjYWxsYmFjaykgewoJCQl0aGlzLl9zaG93KGltZywgdGl0bGUsIG1lc3NhZ2UsIG51bGwsICdPSy1DYW5jZWwnLCBmdW5jdGlvbihyZXN1bHQpIHsKCQkJCWlmKCBjYWxsYmFjayApIGNhbGxiYWNrKHJlc3VsdCk7CgkJCX0pOwoJCX0sCgkJeWVzTm86IGZ1bmN0aW9uKGltZywgbWVzc2FnZSwgdGl0bGUsIGNhbGxiYWNrKSB7CgkJCXRoaXMuX3Nob3coaW1nLCB0aXRsZSwgbWVzc2FnZSwgbnVsbCwgJ1llcy1ObycsIGZ1bmN0aW9uKHJlc3VsdCkgewoJCQkJaWYoIGNhbGxiYWNrICkgY2FsbGJhY2socmVzdWx0KTsKCQkJfSk7CgkJfSwKCgkJeWVzTm9DYW5jZWw6IGZ1bmN0aW9uKGltZywgbWVzc2FnZSwgdGl0bGUsIGNhbGxiYWNrKSB7CgkJCXRoaXMuX3Nob3coaW1nLCB0aXRsZSwgbWVzc2FnZSwgbnVsbCwgJ1llcy1Oby1DYW5jZWwnLCBmdW5jdGlvbihyZXN1bHQpIHsKCQkJCWlmKCBjYWxsYmFjayApIGNhbGxiYWNrKHJlc3VsdCk7CgkJCX0pOwoJCX0sCgoJCV9jcmVhdGVCb3g6IGZ1bmN0aW9uKG1zZ0JveF9tZXNzYWdlLGJ1dHRvbnMsY2FsbGJhY2spIHsKCQkJdmFyIHRoYXQgPSB0aGlzOwoJCQkkKCIjIittc2dCb3hfbWVzc2FnZSkuYWZ0ZXIoIjxkaXYgaWQ9J21zZ0JveF9wYW5lbCc+Iik7CgkJCV8uZWFjaChidXR0b25zLnNwbGl0KCItIiksZnVuY3Rpb24odmFsLGkpIHsKICAgICAgICAgICAgICAgIHZhciBkaXNwdmFsID0geGZhbGliLmxvY2FsZS5TdHJpbmdzW3ZhbC50b0xvd2VyQ2FzZSgpXSA/IHhmYWxpYi5sb2NhbGUuU3RyaW5nc1t2YWwudG9Mb3dlckNhc2UoKV0gOiB2YWw7ICAvLyBrZXlzIGluIGxvYWNsaXphdGlvbiBmaWxlcyBhcmUgaW4gbG93ZXItY2FzZQogICAgICAgICAgICAgICAgJCgiI21zZ0JveF9wYW5lbCIpLmFwcGVuZCgiPGlucHV0IHR5cGU9J2J1dHRvbicgdmFsdWU9JyIrZGlzcHZhbCsiJyBpZCA9ICdtc2dCb3hfIit2YWwrIicgY2xhc3M9bXNnYm94X2lucHV0IC8+Iik7CgkJCQkkKCIjbXNnQm94XyIrdmFsKS5jbGljayggZnVuY3Rpb24oKSB7CgkJCQkJdGhhdC5faGlkZSgpOwoJCQkJCWNhbGxiYWNrKCFpKTsKCQkJCX0pOwoJCQkJaWYoIWkpICQoIm1zZ0JveF8iK3ZhbCkuZm9jdXMoKTsKCQkJfSk7CgkJfSwKCgkJX3Nob3c6IGZ1bmN0aW9uKGltZywgdGl0bGUsIG1zZywgdmFsdWUsIHR5cGUsIGNhbGxiYWNrKSB7CgoJCQl0aGlzLl9oaWRlKCk7CgkJCXRoaXMuX292ZXJsYXkoJ3Nob3cnKTsKCgkJCSQoIkJPRFkiKS5hcHBlbmQoCgkJCSAgJzxkaXYgaWQ9Im1zZ0JveF9jb250YWluZXIiPicgKwoJCQkgICAgJzxoMSBpZD0ibXNnQm94X3RpdGxlIj48L2gxPicgKwoJCQkgICAgJzxkaXYgaWQ9Im1zZ0JveF9jb250ZW50Ij4nICsKCQkJICAgICAgJzxkaXYgaWQ9Im1zZ0JveF9tZXNzYWdlIj48L2Rpdj4nICsKCQkJCSc8L2Rpdj4nICsKCQkJICAnPC9kaXY+Jyk7CgoJCQlpZiggdGhpcy5kaWFsb2dDbGFzcyApICQoIiNtc2dCb3hfY29udGFpbmVyIikuYWRkQ2xhc3MoJC5hbGVydEJveC5kaWFsb2dDbGFzcyk7CgoJCQkkKCIjbXNnQm94X2NvbnRhaW5lciIpLmNzcyh7CgkJCQlwb3NpdGlvbjogJ2Fic29sdXRlJywKCQkJCXpJbmRleDogOTk5OTksCgkJCQlwYWRkaW5nOiAwLAoJCQkJbWFyZ2luOiAwCgkJCX0pOwoKCQkJJCgiI21zZ0JveF90aXRsZSIpLnRleHQodGl0bGUpOwoJCQkkKCIjbXNnQm94X2NvbnRlbnQiKS5hZGRDbGFzcygibXNnQm94VHlwZSIraW1nKTsvL2NzcygiYmFja2dyb3VuZC1pbWFnZSIsInVybCgiK3RoaXMuaW1hZ2VEaXJlY3RvcnkrIHRoaXMuaW1hZ2VzW2ltZ10rIikiKTsKCQkJbXNnID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmVuY29kZVNjcmlwdGFibGVUYWdzKG1zZy5yZXBsYWNlKC9cbi9nLCAnPGJyIC8+JykpOwogICAgICAgICAgICAkKCIjbXNnQm94X21lc3NhZ2UiKS5odG1sKG1zZyk7CgoJCQkkKCIjbXNnQm94X2NvbnRhaW5lciIpLmNzcyh7CgkJCQltaW5XaWR0aDogJCgiI21zZ0JveF9jb250YWluZXIiKS5vdXRlcldpZHRoKCksCgkJCQltYXhXaWR0aDogJCgiI21zZ0JveF9jb250YWluZXIiKS5vdXRlcldpZHRoKCkKCQkJfSk7CgoJCQl0aGlzLl9yZXBvc2l0aW9uKCk7CgkJCXRoaXMuX21haW50YWluUG9zaXRpb24odHJ1ZSk7CgoJCQl0aGlzLl9jcmVhdGVCb3goIm1zZ0JveF9tZXNzYWdlIix0eXBlLGNhbGxiYWNrKTsKCgkJCS8vVE9ETzogTWFrZSBrZXlib2FyZCBpbnB1dCB3b3JrCgkJCS8qJCgiI21zZ0JveF9vayIpLmtleXByZXNzKCBmdW5jdGlvbihlKSB7CgkJCQlpZiggZS5rZXlDb2RlID09IDEzIHx8IGUua2V5Q29kZSA9PSAyNyApICQoIiNtc2dCb3hfb2siKS50cmlnZ2VyKCdjbGljaycpOwoJCQl9KTsKCQkJJCgiI21zZ0JveF9jYW5jZWwiKS5rZXlwcmVzcyggZnVuY3Rpb24oZSkgewoJCQkJaWYoIGUua2V5Q29kZSA9PSAxMyApICQoIiNtc2dCb3hfb2siKS50cmlnZ2VyKCdjbGljaycpOwoJCQkJaWYoIGUua2V5Q29kZSA9PSAyNyApICQoIiNtc2dCb3hfY2FuY2VsIikudHJpZ2dlcignY2xpY2snKTsKCQkJfSk7CgkJCSQoIiNtc2dCb3hfeWVzLCAjbXNnQm94X25vIikua2V5cHJlc3MoIGZ1bmN0aW9uKGUpIHsKCQkJCWlmKCBlLmtleUNvZGUgPT0gMTMgKSAkKCIjbXNnQm94X3llcyIpLnRyaWdnZXIoJ2NsaWNrJyk7CgkJCQkJaWYoIGUua2V5Q29kZSA9PSAyNyApICQoIiNtc2dCb3hfbm8iKS50cmlnZ2VyKCdjbGljaycpOwoJCQkJfSk7Ki8KCgkJfSwKCgkJX2hpZGU6IGZ1bmN0aW9uKCkgewoJCQkkKCIjbXNnQm94X2NvbnRhaW5lciIpLnJlbW92ZSgpOwoJCQl0aGlzLl9vdmVybGF5KCdoaWRlJyk7CgkJCXRoaXMuX21haW50YWluUG9zaXRpb24oZmFsc2UpOwoJCX0sCgoJCV9vdmVybGF5OiBmdW5jdGlvbihzdGF0dXMpIHsKCQkJc3dpdGNoKCBzdGF0dXMgKSB7CgkJCQljYXNlICdzaG93JzoKCQkJCQl0aGlzLl9vdmVybGF5KCdoaWRlJyk7CgkJCQkJJCgiQk9EWSIpLmFwcGVuZCgnPGRpdiBpZD0ibXNnQm94X292ZXJsYXkiPjwvZGl2PicpOwoJCQkJCSQoIiNtc2dCb3hfb3ZlcmxheSIpLmNzcyh7CgkJCQkJCXBvc2l0aW9uOiAnYWJzb2x1dGUnLAoJCQkJCQl6SW5kZXg6IDk5OTk4LAoJCQkJCQl0b3A6ICcwcHgnLAoJCQkJCQlsZWZ0OiAnMHB4JywKCQkJCQkJd2lkdGg6ICcxMDAlJywKCQkJCQkJaGVpZ2h0OiAkKGRvY3VtZW50KS5oZWlnaHQoKSwKCQkJCQkJYmFja2dyb3VuZDogdGhpcy5vdmVybGF5Q29sb3IsCgkJCQkJCW9wYWNpdHk6IHRoaXMub3ZlcmxheU9wYWNpdHkKCQkJCQl9KTsKCQkJCWJyZWFrOwoJCQkJY2FzZSAnaGlkZSc6CgkJCQkJJCgiI21zZ0JveF9vdmVybGF5IikucmVtb3ZlKCk7CgkJCQlicmVhazsKCQkJfQoJCX0sCgoJCV9yZXBvc2l0aW9uOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHdpbmRvd0hlaWdodCA9ICQod2luZG93KS5oZWlnaHQoKSAvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IsCiAgICAgICAgICAgICAgICB3aW5kb3dXaWR0aCA9ICQod2luZG93KS53aWR0aCgpIC8geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmZvcm1TY2FsZUZhY3RvciwKICAgICAgICAgICAgICAgIHdpbmRvd1Njcm9sbFRvcCA9ICAkKHdpbmRvdykuc2Nyb2xsVG9wKCkgLyB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZm9ybVNjYWxlRmFjdG9yLAogICAgICAgICAgICAgICAgd2luZG93U2Nyb2xsTGVmdCA9ICAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpIC8geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmZvcm1TY2FsZUZhY3RvciwKCQkJICAgIHRvcCA9ICgod2luZG93SGVpZ2h0IC8gMikgLSAoJCgiI21zZ0JveF9jb250YWluZXIiKS5vdXRlckhlaWdodCgpIC8gMikpICsgdGhpcy52ZXJ0aWNhbE9mZnNldCwKCQkJICAgIGxlZnQgPSAoKHdpbmRvd1dpZHRoIC8gMikgLSAoJCgiI21zZ0JveF9jb250YWluZXIiKS5vdXRlcldpZHRoKCkgLyAyKSkgKyB0aGlzLmhvcml6b250YWxPZmZzZXQ7CgkJCWlmKCB0b3AgPCAwICkgdG9wID0gMDsKCQkJaWYoIGxlZnQgPCAwICkgbGVmdCA9IDA7CgoJCQkvLyBJRTYgZml4CgkJCWlmKCAkLmJyb3dzZXIubXNpZSAmJiBwYXJzZUludCgkLmJyb3dzZXIudmVyc2lvbikgPD0gNiApIHRvcCA9IHRvcCArIHdpbmRvd1Njcm9sbFRvcDsKCgkJCSQoIiNtc2dCb3hfY29udGFpbmVyIikuY3NzKHsKCQkJCXRvcDogdG9wICsgd2luZG93U2Nyb2xsVG9wICsgJ3B4JywKCQkJCWxlZnQ6ICBsZWZ0ICsgd2luZG93U2Nyb2xsTGVmdCArICdweCcKCQkJfSk7CgkJCSQoIiNtc2dCb3hfb3ZlcmxheSIpLmhlaWdodCggJChkb2N1bWVudCkuaGVpZ2h0KCkgKTsKCQl9LAoKCQlfbWFpbnRhaW5Qb3NpdGlvbjogZnVuY3Rpb24oc3RhdHVzKSB7CgkJCWlmKCB0aGlzLnJlcG9zaXRpb25PblJlc2l6ZSApIHsKCQkJCXN3aXRjaChzdGF0dXMpIHsKCQkJCQljYXNlIHRydWU6CgkJCQkJCSQod2luZG93KS5vbigncmVzaXplJywgdGhpcy5fcmVwb3NpdGlvbik7CgkJCQkJYnJlYWs7CgkJCQkJY2FzZSBmYWxzZToKCQkJCQkJJCh3aW5kb3cpLm9mZigncmVzaXplJywgdGhpcy5fcmVwb3NpdGlvbik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9CgoJfTsKfSkoJCwgd2luZG93Ll8pOy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX19fCiAqCiAqICBDb3B5cmlnaHQgMjAxNiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiBsYXdzLCBpbmNsdWRpbmcgdHJhZGUgc2VjcmV0IGFuZCBjb3B5cmlnaHQgbGF3cy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LnV0aWwuSHRtbFV0aWwgPSB7CiAgICAgICAgLyoKICAgICAgICAqIE1vc3Qgb2YgdGhlIHRpbWUgaXQgcmV0dXJucyB1bmRlZmluZWQgd2hpbGUgYWNjZXNzaW5nIGFuIHVuZGVmaW5lZCBhdHRyaWJ1dGUgb2YgYSBkb20gZWxlbWVudC4KICAgICAgICAqIEJ1dCBzb21lIGJyb3dzZXJzIGNhbiB0aHJvdyBzcGVjaWZpYyBleGNlcHRpb25zIHdoaWxlIGFjY2Vzc2luZyBhbiBhdHRyaWJ1dGUgd2hpY2ggaXMgdW4tc3VwcG9ydGVkIGZvciBhIHNwZWNpZmljIGNhc2UuCiAgICAgICAgKiBUaGlzIEFQSSBpcyB0byBtYWtlIHRoaXMgYmVoYXZpb3VyIGNvbnNpc3RlbnQgYWNyb3NzIGJyb3dzZXJzIGFuZCByZXR1cm4gdW5kZWZpbmVkIGZvciB1bi1zdXBwb3J0ZWQgYXR0cmlidXRlcy4KICAgICAgICAqICovCiAgICAgICAgZ2V0SFRNTFN1cHBvcnRlZEF0dHIgOiBmdW5jdGlvbigkZG9tRWxlbWVudCwgYXR0cil7CiAgICAgICAgICAgdHJ5ewogICAgICAgICAgICAgICByZXR1cm4gJGRvbUVsZW1lbnRbYXR0cl07CiAgICAgICAgICAgIH0KICAgICAgICAgICBjYXRjaCAoZXJyKXsKICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrcyBpZiB0aGUgYXR0cmlidXRlIGlzIHN1cHBvcnRlZCBmb3IgdGhlIGdpdmVuIEhUTUwgZWxlbWVudC4KICAgICAgICAgKiBUaGlzIGlzIHByaW1hcmlseSB1c2VmdWwgdG8gc3VwcG9ydCBIVE1MNSBmZWF0dXJlcyBpbiB3aWRnZXRzCiAgICAgICAgICogQHBhcmFtIGVsZW1lbnQgICAgICAgbmFtZSBvZiBIVE1MIGVsZW1lbnQKICAgICAgICAgKiBAcGFyYW0gYXR0cmlidXRlICAgICBhdHRyaWJ1dGUgdG8gY2hlY2sgb24gdGhlIGVsZW1lbnQKICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0KICAgICAgICAgKi8KICAgICAgICBlbGVtZW50U3VwcG9ydHNBdHRyaWJ1dGUgOiBmdW5jdGlvbiAoZWxlbWVudCwgYXR0cmlidXRlKSB7CiAgICAgICAgICAgIHZhciB0ZXN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChlbGVtZW50KTsKICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZSBpbiB0ZXN0KSB7CiAgICAgICAgICAgICAgICAkKHRlc3QpLnJlbW92ZSgpOwogICAgICAgICAgICAgICAgdGVzdCA9IG51bGw7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICQodGVzdCkucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICB0ZXN0ID0gbnVsbDsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfSkoXywgJCwgeGZhbGliKTsKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKgoqIEFET0JFIENPTkZJREVOVElBTAoqIF9fX19fX19fX19fX19fX19fX18KKgoqICBDb3B5cmlnaHQgMjAxMyBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAoqICBBbGwgUmlnaHRzIFJlc2VydmVkLgoqCiogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAoqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKKiBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuCiogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiogaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy51dGlsLlN0eWxlcyA9IHsKICAgICAgICB4ZmFVdGlsIDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLAogICAgICAgIF9kZXZpY2VSZXNvbHV0aW9uIDogIDE0NC4wLCAvL0RQSQogICAgICAgIF9pbjJtbUZhY3RvciA6IDI1LjQsCiAgICAgICAgX3BkZlJlc29sdXRpb24gOiA3Mi4wICwKICAgICAgICBnZXRTdHlsZUZvckVkZ2UgOiBmdW5jdGlvbiAoZWRnZUVsZW1lbnQsIHN0ciwgY3NzU3R5bGVPYmopewogICAgICAgICAgICB2YXIgc3R5bGUgPSB7ICJyYWlzZWQiIDogIm91dHNldCIgLAogICAgICAgICAgICAgICAgImRhc2hEb3QiIDogImRhc2hlZCIgLAogICAgICAgICAgICAgICAgImRhc2hEb3REb3QiIDogImRhc2hlZCIgLAogICAgICAgICAgICAgICAgImRhc2hlZCIgOiAiZGFzaGVkIiAsCiAgICAgICAgICAgICAgICAiZG90dGVkIiA6ICJkb3R0ZWQiICwKICAgICAgICAgICAgICAgICJlbWJvc3NlZCIgOiAiZ3Jvb3ZlIiAsCiAgICAgICAgICAgICAgICAiZXRjaGVkIiA6ICJpbnNldCIgLAogICAgICAgICAgICAgICAgImxvd2VyZWQiIDogInJpZGdlIiwKICAgICAgICAgICAgICAgICJzb2xpZCIgOiAic29saWQifTsKICAgICAgICAgICAgaWYoZWRnZUVsZW1lbnQgJiYgZWRnZUVsZW1lbnQuanNvbk1vZGVsLnByZXNlbmNlICE9ICJoaWRkZW4iICYmIGVkZ2VFbGVtZW50Lmpzb25Nb2RlbC5wcmVzZW5jZSAhPSJpbnZpc2libGUiKSB7CiAgICAgICAgICAgICAgICBjc3NTdHlsZU9ialsnYm9yZGVyJytzdHIrJ3dpZHRoJ10gPSB0aGlzLl9zdWJQaXhlbFZhbHVlKHRoaXMuX2NvbnZlcnRUb1B4KGVkZ2VFbGVtZW50LmdldEF0dHJpYnV0ZSgndGhpY2tuZXNzJykpKSB8fCAiMXB4IjsKICAgICAgICAgICAgICAgIGlmKGVkZ2VFbGVtZW50LmdldEVsZW1lbnQoImNvbG9yIikgJiYgZWRnZUVsZW1lbnQuZ2V0RWxlbWVudCgiY29sb3IiKS5nZXRBdHRyaWJ1dGUoInZhbHVlIikgIT0iIikgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY29sb3IgPSAgIGVkZ2VFbGVtZW50LmdldEVsZW1lbnQoImNvbG9yIikuZ2V0QXR0cmlidXRlKCJ2YWx1ZSIpOwogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gInJnYigiICsgY29sb3IgKyAiKSI7CiAgICAgICAgICAgICAgICAgICAgY3NzU3R5bGVPYmpbJ2JvcmRlcicrc3RyKydjb2xvciddICAgPSBjb2xvciAgOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY3NzU3R5bGVPYmpbJ2JvcmRlcicrc3RyKydjb2xvciddID0gInJnYigwLDAsMCkiICA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjc3NTdHlsZU9ialsnYm9yZGVyJytzdHIrJ3N0eWxlJ10gICA9IHN0eWxlW2VkZ2VFbGVtZW50LmdldEF0dHJpYnV0ZSgnc3Ryb2tlJyldIHx8ICJzb2xpZCIgOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY3NzU3R5bGVPYmpbJ2JvcmRlcicrc3RyKyd3aWR0aCddID0gICIwcHgiOwogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0KCiAgICAgICAgfSwKCiAgICAgICAgZ2V0U3R5bGVGb3JCb3JkZXIgOiBmdW5jdGlvbiAoYm9yZGVyKSB7CiAgICAgICAgICAgIGlmKGJvcmRlcikgewogICAgICAgICAgICAgICAgdmFyIGVkZ2UgID0gIGJvcmRlci5nZXRFbGVtZW50KCdlZGdlJywgMCwgdHJ1ZSksCiAgICAgICAgICAgICAgICAgICAgZWRnZTEgPSBib3JkZXIuZ2V0RWxlbWVudCgnZWRnZScsIDEsIHRydWUpLAogICAgICAgICAgICAgICAgICAgIGVkZ2UyID0gYm9yZGVyLmdldEVsZW1lbnQoJ2VkZ2UnLCAyLCB0cnVlKSwKICAgICAgICAgICAgICAgICAgICBlZGdlMyA9IGJvcmRlci5nZXRFbGVtZW50KCdlZGdlJywgMywgdHJ1ZSk7CiAgICAgICAgICAgICAgICBpZihlZGdlIHx8IGVkZ2UxIHx8IGVkZ2UyIHx8IGVkZ2UzKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNzc1N0eWxlT2JqID0ge30gOwogICAgICAgICAgICAgICAgICAgIHZhciBlMCA9IHRoaXMuZ2V0U3R5bGVGb3JFZGdlKGVkZ2UsICItdG9wLSIsY3NzU3R5bGVPYmopOwogICAgICAgICAgICAgICAgICAgIHZhciBlMSA9IHRoaXMuZ2V0U3R5bGVGb3JFZGdlKGVkZ2UxIHx8IGVkZ2UsIi1yaWdodC0iLGNzc1N0eWxlT2JqKTsKICAgICAgICAgICAgICAgICAgICB2YXIgZTIgPSB0aGlzLmdldFN0eWxlRm9yRWRnZShlZGdlMnx8IGVkZ2UsIi1ib3R0b20tIixjc3NTdHlsZU9iaik7CiAgICAgICAgICAgICAgICAgICAgdmFyIGUzID0gdGhpcy5nZXRTdHlsZUZvckVkZ2UoZWRnZTMgfHwgZWRnZSwiLWxlZnQtIixjc3NTdHlsZU9iaik7CiAgICAgICAgICAgICAgICAgICAgaWYoZTAgIT0xfHwgZTEgIT0xfHwgZTIgIT0xfHwgZTMhPTEpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjc3NTdHlsZU9iaiA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIF9jb252ZXJ0VG9QeCA6IGZ1bmN0aW9uKHNpemUpewogICAgICAgICAgICBpZighc2l6ZSkKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICBzaXplID0gIiIgKyBzaXplOwogICAgICAgICAgICB2YXIgcHhTaXplID0gc2l6ZTsKICAgICAgICAgICAgaWYoc2l6ZS5pbmRleE9mKCJpbiIpID49MCl7CiAgICAgICAgICAgICAgICBweFNpemUgPSB0aGlzLl9tbTJweChwYXJzZUZsb2F0KHNpemUpICogdGhpcy5faW4ybW1GYWN0b3IpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYoc2l6ZS5pbmRleE9mKCJtbSIpID49MCl7CiAgICAgICAgICAgICAgICBweFNpemUgPSB0aGlzLl9tbTJweChzaXplKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKHNpemUuaW5kZXhPZigiY20iKSA+PTApewogICAgICAgICAgICAgICAgcHhTaXplID0gdGhpcy5fbW0ycHgocGFyc2VGbG9hdChzaXplKSAqIDEwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKHNpemUuaW5kZXhPZigicHQiKSA+PTApewogICAgICAgICAgICAgICAgcHhTaXplID0gcGFyc2VGbG9hdChzaXplKSAqICh0aGlzLl9kZXZpY2VSZXNvbHV0aW9uL3RoaXMuX3BkZlJlc29sdXRpb24pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYoc2l6ZS5pbmRleE9mKCJweCIpID49MCl7CiAgICAgICAgICAgICAgICBweFNpemUgPSBwYXJzZUZsb2F0KHNpemUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBweFNpemU7CiAgICAgICAgfSwKCiAgICAgICAgX21tMnB4IDogZnVuY3Rpb24obW1TaXplKXsKICAgICAgICAgICAgdmFyIG1tU2l6ZU51bSA9IDA7CiAgICAgICAgICAgIGlmKF8uaXNOdW1iZXIobW1TaXplKSkKICAgICAgICAgICAgICAgIG1tU2l6ZU51bSA9IG1tU2l6ZTsKICAgICAgICAgICAgZWxzZXsKICAgICAgICAgICAgICAgIG1tU2l6ZU51bSA9IHBhcnNlRmxvYXQobW1TaXplKQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBtbTJpbiA9IDEvMjUuNCA7CiAgICAgICAgICAgIHZhciBweFNpemUgPSBtbVNpemVOdW0qbW0yaW4qdGhpcy5fZGV2aWNlUmVzb2x1dGlvbjsKICAgICAgICAgICAgcmV0dXJuIHB4U2l6ZTsKICAgICAgICB9LAoKICAgICAgICBfc3ViUGl4ZWxWYWx1ZSA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgaWYodmFsdWUgPiAwLjAxKQogICAgICAgICAgICAgICAgcmV0dXJuIE1hdGgubWF4KHZhbHVlLCAxLjApOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgfQogICAgfQp9KShfLCAkLCB4ZmFsaWIpOwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogX19fX19fX19fX19fX19fX19fXwogKgogKiAgQ29weXJpZ2h0IDIwMTcgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LnV0aWwudHJhdmVyc2FsTWFuYWdlciA9IHsKCiAgICAgICAgLy8gY29tcHV0ZSB0YWJJbmRleCBmb3IgdGhlIHByb3ZpZGVkIHBhZ2UKICAgICAgICBfY29tcHV0VGFiSW5kZXggOiBmdW5jdGlvbiAocGFnZVZpZXcpIHsKICAgICAgICAgICAgdmFyIHBhZ2VOdW0gPSBwYWdlVmlldy5fcGFnZU51bWJlcigpLAogICAgICAgICAgICAgICAgdGFiSW5kZXggPSB0aGlzLl90YWJJbmRleEJhc2VkT25SYW5nZShwYWdlTnVtKTsKICAgICAgICAgICAgdGhpcy5nZW9ncmFwaGljYWxPcmRlciA9IFtdOwogICAgICAgICAgICB0aGlzLl9jcmVhdGVHZW9ncmFwaGljYWxPcmRlcihwYWdlVmlldyk7CiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUZpbmFsVHJhdmVyc2FsT3JkZXIodGFiSW5kZXgpOyAvLyBhc3NpZ24gdGFiIGluZGV4IHVzaW5nIHRyYXZlcnNhbCBlbGVtZW50IGFuZCBnZW9ncmFwaGljYWxPcmRlcgogICAgICAgICAgICAvLyBrZWVwIHRyYWNrcyBvZiB0aGUgbGFzdCBmaWVsZCBvbiB0aGUgcGFnZSB0byBnZXQgdGFiIGluZGV4IHNvIHRoYXQgaGFuZGxlciB0byByZW5kZXIgbmV4dCBwYWdlIGNhbiBiZSBhZGRlZCBvbiBnZXR0aW5nIGZvY3VzIHRocm91Z2ggdGFiYmluZwogICAgICAgICAgICB0aGlzLl9sYXN0RmllbGRUYWJiZWQgPSBudWxsOwogICAgICAgIH0sCgogICAgICAgIF90YWJJbmRleEJhc2VkT25SYW5nZSA6IGZ1bmN0aW9uIChwYWdlTnVtKSB7CiAgICAgICAgICAgIHZhciBiZWhhdmlvckNvbmZpZyA9IG5ldyB4ZmFsaWIudXQuVmVyc2lvbihmb3JtQnJpZGdlLnVzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl0pLAogICAgICAgICAgICAgICAgdGFiSW5kZXhDb25maWcgPSAoYmVoYXZpb3JDb25maWcuaXNPbignbWZSYW5nZVRhYkluZGV4Jyl8fCBiZWhhdmlvckNvbmZpZy5pc09uKCdyYW5nZVRhYkluZGV4JykpLAogICAgICAgICAgICAgICAgLyphc3N1bWluZyBzaW5nbGUgcGFnZSBjYW4gbm90IGhhdmUgbW9yZSB0aGFuIDEwMDAgZmllbGRzLltpbmRleCAtPiAwIHRvIDk5OV0KICAgICAgICAgICAgICAgICAgdGhpcyBpcyBhbHNvIGNvbmZpZ3VyYWJsZSBieSBwYXNzaW5nIHRoZSBtYXhpbXVtIG51bWJlciBvZiBmaWVsZHMgYWxsb3dhYmxlIGluIHRoZSBwYWdlCiAgICAgICAgICAgICAgICAgIGluIHRoZSBjb25maWcgcGFyYW1ldGVyICovCiAgICAgICAgICAgICAgICBtYXhGaWVsZEluUGFnZUZvclRhYkluZGV4ID0gdGFiSW5kZXhDb25maWc/IHBhcnNlSW50KHRhYkluZGV4Q29uZmlnKToxMDAwOwoKICAgICAgICAgICAgcmV0dXJuIHBhZ2VOdW0gKiBtYXhGaWVsZEluUGFnZUZvclRhYkluZGV4OwogICAgICAgIH0sCgogICAgICAgIC8vIHRvIGNyZWF0ZSBnZW9ncmFwaGljYWwgb3JkZXIgYXJyYXkgd2hpY2ggd2lsbCBiZSBjb250YWluaW5nIGFsbCB0aGUgdmlld3MgaW4gdGhlIGdlb2dyYXBoaWNhbCBvcmRlcgogICAgICAgIF9jcmVhdGVHZW9ncmFwaGljYWxPcmRlciA6IGZ1bmN0aW9uIChjdXJyZW50VmlldykgewogICAgICAgICAgICB2YXIgc29ydGVkQ2hpbGRWaWV3V3JhcHBlciA9IHRoaXMuX3NvcnRWaWV3R2VvZ3JhcGhpY2FsbHkoY3VycmVudFZpZXcuY2hpbGRWaWV3cyk7CiAgICAgICAgICAgIF8uZWFjaChzb3J0ZWRDaGlsZFZpZXdXcmFwcGVyLCBmdW5jdGlvbiAod3JhcHBlcikgewogICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRWaWV3ID0gd3JhcHBlci52aWV3LAogICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQ2hlY2tNYXAgPSB0aGlzLl9nZXRNYXBPZkluc3RhbmNlQ2hlY2soY3VycmVudFZpZXcpLAogICAgICAgICAgICAgICAgICAgIGlzVmlld0VsaWdpYmxlRm9yVGFiYmluZyA9IHRoaXMuX2lzVmlld0VsaWdpYmxlRm9yVGFiYmluZyhjdXJyZW50Vmlldyk7CiAgICAgICAgICAgICAgICAvLyAgSWYgdGhlIGNoaWxkIHZpZXcgaXMgZmllbGRWaWV3LCBkcmF3VmlldywgZXhjbEdyb3VwVmlldyBvciBzdWJmb3JtVmlldyB0aGVuIHdlIHdpbGwgcHVzaCB0aGVzZSB2aWV3cyBpbiB0aGlzLmdlb2dyYXBoaWNhbE9yZGVyIGFycmF5LAogICAgICAgICAgICAgICAgLy8gIGFzIHdlIG5lZWQgdGhlaXIgdHJhdmVyc2Ugb2JqZWN0IGR1cmluZyBmaW5hbCB0cmF2ZXJzaW5nCiAgICAgICAgICAgICAgICBpZiAoKChpbnN0YW5jZUNoZWNrTWFwLmlzRmllbGQgJiYgIWluc3RhbmNlQ2hlY2tNYXAuaXNDaGlsZE9mRXhjbEdyb3VwKSB8fCBpbnN0YW5jZUNoZWNrTWFwLmlzU3ViZm9ybSB8fCBpbnN0YW5jZUNoZWNrTWFwLmlzRHJhdwogICAgICAgICAgICAgICAgICAgIHx8IGluc3RhbmNlQ2hlY2tNYXAuaXNFeGNsR3JvdXApICYmIGlzVmlld0VsaWdpYmxlRm9yVGFiYmluZykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuZ2VvZ3JhcGhpY2FsT3JkZXIucHVzaCh7CiAgICAgICAgICAgICAgICAgICAgICAgIHZpZXcgOiBjdXJyZW50VmlldywKICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXRlZCA6IGZhbHNlCiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2VDaGVja01hcC5pc0NvbnRhaW5lciAmJiBpc1ZpZXdFbGlnaWJsZUZvclRhYmJpbmcpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVHZW9ncmFwaGljYWxPcmRlcihjdXJyZW50Vmlldyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIC8vIHRvIHNvcnQgcHJvdmlkZWQgdmlld3MgaW4gZ2VvZ3JhcGhpY2FsIG9yZGVyCiAgICAgICAgX3NvcnRWaWV3R2VvZ3JhcGhpY2FsbHkgOiBmdW5jdGlvbiAodmlld3MpIHsKICAgICAgICAgICAgdmFyIHZpZXdzV3JhcHBlciA9IFtdOyAgIC8vIHdyYXBwZXIgb2YgdmlldyBhbmQgdGhlaXIgZ2VvZ3JhcGhpY2FsIHJlZmVyZW5jZQogICAgICAgICAgICBfLmVhY2godmlld3MsIGZ1bmN0aW9uKHZpZXcpIHsKICAgICAgICAgICAgICAgIHZhciBwb3NpdGlvbiA9IHZpZXcuJGVsLm9mZnNldCgpLAogICAgICAgICAgICAgICAgICAgIHBhZGRlZFggPSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUucGFkU3RyaW5nKHBhcnNlSW50KHBvc2l0aW9uLmxlZnQpLCA1LCAnMCcpLAogICAgICAgICAgICAgICAgICAgIG1hcmdpblRvcCA9IHZpZXcuX21hcmdpblRvcCgpLAogICAgICAgICAgICAgICAgICAgIHBhZGRlZFkgPSBwb3NpdGlvbi50b3AgLSBwYXJzZUZsb2F0KG1hcmdpblRvcCksCiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25hbFJlZmVyZW5jZSA9IHBhcnNlSW50KCIiICsgcGFyc2VJbnQocGFkZGVkWSkgKyBwYWRkZWRYKTsKICAgICAgICAgICAgICAgIHZpZXdzV3JhcHBlci5wdXNoKHsKICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbmFsUmVmZXJlbmNlOiBwb3NpdGlvbmFsUmVmZXJlbmNlLAogICAgICAgICAgICAgICAgICAgIHZpZXc6IHZpZXcKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgcmV0dXJuIF8uc29ydEJ5KHZpZXdzV3JhcHBlciwgZnVuY3Rpb24odmlld1dyYXBwZXIpeyByZXR1cm4gdmlld1dyYXBwZXIucG9zaXRpb25hbFJlZmVyZW5jZTsgfSk7CiAgICAgICAgfSwKCiAgICAgICAgLy8gV2FsayB0aHJvdWdoIHZpZXdzIGluIGdlb2dyYXBoaWNhbCBvcmRlciBhbmQgYXNzaWduIHRhYiBpbmRleCBob25vdXJpbmcgdHJhdmVyc2FsIG9iamVjdCBpZiBwcmVzZW50CiAgICAgICAgX2NyZWF0ZUZpbmFsVHJhdmVyc2FsT3JkZXIgOiBmdW5jdGlvbiAodGFiSW5kZXgpIHsKICAgICAgICAgICAgdmFyIGdlb2dyYXBoaWNhbE9yZGVyTGVuZ3RoID0gdGhpcy5nZW9ncmFwaGljYWxPcmRlci5sZW5ndGgsCiAgICAgICAgICAgICAgICBjdXJyZW50V3JhcHBlZE9iaiA9IG51bGwsCiAgICAgICAgICAgICAgICBpbmRleCA9IC0xLAogICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXggPSAwLCAgLy8gaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gYmUgdHJhdmVyc2VkCiAgICAgICAgICAgICAgICB2aWV3VHJhdmVyc2VkID0gMDsgIC8vIGNvdW50ZXIgb2YgdmlldyB0cmF2ZXJzZWQKCiAgICAgICAgICAgIHdoaWxlICgxKSB7CiAgICAgICAgICAgICAgICBpZiAodHJhdmVyc2FsSW5kZXggPj0gZ2VvZ3JhcGhpY2FsT3JkZXJMZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0cmF2ZXJzYWxJbmRleCA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdXJyZW50V3JhcHBlZE9iaiA9IHRoaXMuZ2VvZ3JhcGhpY2FsT3JkZXJbdHJhdmVyc2FsSW5kZXhdOwoKICAgICAgICAgICAgICAgIGlmICghY3VycmVudFdyYXBwZWRPYmogfHwgY3VycmVudFdyYXBwZWRPYmoudmlzaXRlZCkgeyAgLy8gaWYgdGhlIHdyYXBwZWQgb2JqZWN0IGRvZXMgbm90IGV4aXN0IG9yIGl0IGhhcyBiZWVuIHZpc2l0ZWQgbW92ZSB0byB0aGUgbmV4dCBvbmUKICAgICAgICAgICAgICAgICAgICB0cmF2ZXJzYWxJbmRleCsrOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50V3JhcHBlZE9iai52aXNpdGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB2aWV3VHJhdmVyc2VkKys7CiAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRWaWV3ID0gY3VycmVudFdyYXBwZWRPYmoudmlldywKICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VDaGVja01hcCA9IHRoaXMuX2dldE1hcE9mSW5zdGFuY2VDaGVjayhjdXJyZW50VmlldyksCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNb2RlbCA9IGN1cnJlbnRWaWV3Lm1vZGVsLAogICAgICAgICAgICAgICAgICAgICAgICBuZXh0VmlldyA9IG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgIG5leHRWaWV3U29tID0gbnVsbDsKCiAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBmaXJzdCB0cmF2ZXJzYWwgb2YgdGhlIHN1YmZvcm0gaWYgdHJhdmVyc2FsIG9iamVjdCBpcyBwcmVzZW50LCBlbHNlIG1vdmUgdG8gdGhlIG5leHQgZ2VvZ3JhcGhpY2FsIGVsZW1lbnQKICAgICAgICAgICAgICAgICAgICAvLyBuZXh0IG9mIHRoZSBzdWJmb3JtIHdpbGwgYmUgdGFrZW4gY2FyZSB3aGVuIHdlIHdpbGwgYmUgZmluZGluZyB0aGUgbmV4dCB2aWV3IHRvIGJlIHRyYXZlcnNlZCwKICAgICAgICAgICAgICAgICAgICAvLyBhcyB3ZSB3aWxsIGJlIGNoZWNraW5nIGlmIHRoZSBhbmNlc3RvciBjb250YWluIG5leHQgYmVmb3JlIG1vdmluZyB0byBnZW9ncmFwaGljYWxseSBuZXh0IHZpZXcKICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2VDaGVja01hcC5pc1N1YmZvcm0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRNb2RlbCAmJiBjdXJyZW50TW9kZWwuZ2V0VHJhdmVyc2FsT2JqZWN0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgZmlyc3QgZWxlbWVudCB0byBiZSB0cmF2ZXJzZWQgYW5kIHVwZGF0ZSB0cmF2ZXJzYWxJbmRleAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dFZpZXdTb20gPSBjdXJyZW50TW9kZWwuZ2V0TmV4dFRyYXZlcnNhbFNvbSh4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmZpcnN0VHJhdmVyc2FsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5fZmluZFZpZXdJbkdlb2dyYXBoaWNhbE9yZGVyQXJyYXkobmV4dFZpZXdTb20pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXggPSBpbmRleCAhPSAtMSA/IGluZGV4IDogdHJhdmVyc2FsSW5kZXggKyAxOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXgrKzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgbmV4dCB0cmF2ZXJzYWwgZm9yIHRoZSBmaWVsZC9kcmF3IGlmIHRyYXZlcnNhbCBvYmplY3QgaXMgcHJlc2VudCwgZWxzZSBtb3ZlIHRvIHRoZSBuZXh0IGdlb2dyYXBoaWNhbCBlbGVtZW50CiAgICAgICAgICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSB0YWJpbmRleCBmb3IgdGhlIGZpZWxkCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbnN0YW5jZUNoZWNrTWFwLmlzRmllbGQgfHwgaW5zdGFuY2VDaGVja01hcC5pc0RyYXcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlQ2hlY2tNYXAuaXNGaWVsZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudFZpZXcudXBkYXRlVGFiSW5kZXgodGFiSW5kZXgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbGFzdEZpZWxkVGFiYmVkID0gY3VycmVudFZpZXc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJJbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50TW9kZWwgJiYgY3VycmVudE1vZGVsLmdldFRyYXZlcnNhbE9iamVjdCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2dldCBuZXh0IGVsZW1lbnQgdG8gYmUgdHJhdmVyc2VkIGFuZCB1cGRhdGUgdHJhdmVyc2FsSW5kZXgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRWaWV3U29tID0gY3VycmVudE1vZGVsLmdldE5leHRUcmF2ZXJzYWxTb20oeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5uZXh0VHJhdmVyc2FsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5fZmluZFZpZXdJbkdlb2dyYXBoaWNhbE9yZGVyQXJyYXkobmV4dFZpZXdTb20pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXggPSBpbmRleCAhPSAtMSA/IGluZGV4IDogdHJhdmVyc2FsSW5kZXggKyAxOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXggPSB0aGlzLl9maW5kTmV4dFZpZXdUb0JlVHJhdmVyc2VkKHRyYXZlcnNhbEluZGV4KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIGlmIHRyYXZlcnNhbCBvYmplY3QgcHJlc2VudCBnZXQgdGhlIG5leHQgZWxlbWVudCB0byBiZSB0cmF2ZXJzZWQsIGlmIGZpcnN0IGlzIGFsc28gcHJlc2VudCB0aGVuIHVwZGF0ZSB0YWIgaW5kZXggb2YgdGhlIGZpcnN0IGVsZW1lbnQKICAgICAgICAgICAgICAgICAgICAvLyBlbHNlIGxvb2sgZm9yIHRoZSB0cmF2ZXJzYWwgZWxlbWVudCBpbiB0aGUgY2hpbGRyZW4KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluc3RhbmNlQ2hlY2tNYXAuaXNFeGNsR3JvdXApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRNb2RlbCAmJiBjdXJyZW50TW9kZWwuZ2V0VHJhdmVyc2FsT2JqZWN0KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldCBuZXh0IGVsZW1lbnQgdG8gYmUgdHJhdmVyc2VkIGFuZCB1cGRhdGUgdHJhdmVyc2FsSW5kZXgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRWaWV3U29tID0gY3VycmVudE1vZGVsLmdldE5leHRUcmF2ZXJzYWxTb20oeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5uZXh0VHJhdmVyc2FsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5fZmluZFZpZXdJbkdlb2dyYXBoaWNhbE9yZGVyQXJyYXkobmV4dFZpZXdTb20pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXggPSBpbmRleCAhPSAtMSA/IGluZGV4IDogdHJhdmVyc2FsSW5kZXggKyAxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgZmlyc3QgaXMgYWxzbyBwcmVzZW50IGFzc2lnbiB0YWIgaW5kZXggdG8gdGhhdCByZWZlcnJlZCBjaGlsZCBlbHNlIGFzc2lnbiBzYW1lIHRhYiBpbmRleCB0byBhbGwgY2hpbGQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRWaWV3U29tID0gY3VycmVudE1vZGVsLmdldE5leHRUcmF2ZXJzYWxTb20oeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5maXJzdFRyYXZlcnNhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJJbmRleCA9IHRoaXMuX3VwZGF0ZVRhYkluZGV4T2ZFeGNsR3JvdXBDaGlsZHJlbihjdXJyZW50VmlldywgdGFiSW5kZXgsIG5leHRWaWV3U29tKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYkluZGV4ID0gdGhpcy5fdXBkYXRlVGFiSW5kZXhPZkV4Y2xHcm91cENoaWxkcmVuKGN1cnJlbnRWaWV3LCB0YWJJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmF2ZXJzYWxJbmRleCA9IHRoaXMuX2ZpbmRUcmF2ZXJzYWxJbkV4Y2xHcm91cENoaWxkcmVuKGN1cnJlbnRWaWV3LCB0cmF2ZXJzYWxJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0cmF2ZXJzYWxJbmRleCsrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBpZiBhbGwgdGhlIHZpZXcgYXJlIHRyYXZlcnNlZCwgd2UgaGF2ZSBhc3NpZ25lZCB0YWIgaW5kZXggdG8gYWxsIHRoZSB2aWV3cwogICAgICAgICAgICAgICAgaWYgKHZpZXdUcmF2ZXJzZWQgPj0gZ2VvZ3JhcGhpY2FsT3JkZXJMZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZW5kZXJOZXh0UGFnZUZ1dHVyZSgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG5leHRWaWV3IGlzIGEgc2libGluZyBvZiB0aGUgY3VycmVudFZpZXcgKHNoYXJlcyB0aGUgc2FtZSBwYXJlbnQpCiAgICAgICAgLy8gaWYgaXQgaXMgbm90IGEgc2libGluZywgY2hlY2sgaWYgdGhlIHBhcmVudCBoYXMgYSBORVhUIHRyYXZlcnNhbC4KICAgICAgICAvLyBpZiBzbyBnZXQgdGhlIG5vZGUgdHJhdmVyc2VkIHRvIGVsc2UgcmVjdXJzZSB0byBzZWUgaWYgbmV4dFZpZXcgaXMgYSBzaWJsaW5nIG9mIG91ciBwYXJlbnQKICAgICAgICAvLyByZXR1cm4gLTEgaWYgdGhlIHByb3ZpZGVkIG5leHQgbm9kZSBpcyBzaWJsaW5nIG9mIGN1cnJlbnQgbm9kZSBvciBpZiBubyBhbmNlc3RvciBjb250YWluIG5leHQgdHJhdmVyc2FsCiAgICAgICAgLy8gZWxzZSByZXR1cm4gaW5kZXggb2YgdGhlIG5leHQgdHJhdmVyc2FsIG9iamVjdCBvZiBwYXJlbnQKICAgICAgICBfZ2V0UGFyZW50TmV4dFRyYXZlcnNhbCA6IGZ1bmN0aW9uIChjdXJyZW50VmlldywgbmV4dFZpZXcsIHRyYXZlcnNhbEluZGV4KSB7CiAgICAgICAgICAgIHZhciBwYXJlbnRWaWV3ID0gY3VycmVudFZpZXcucGFyZW50VmlldywKICAgICAgICAgICAgICAgIHBhcmVudE1vZGVsID0gcGFyZW50Vmlldy5tb2RlbCwKICAgICAgICAgICAgICAgIG5leHRWaWV3UGFyZW50TW9kZWwgPSBuZXh0Vmlldy5wYXJlbnRWaWV3Lm1vZGVsLAogICAgICAgICAgICAgICAgdHJhdmVyc2FsT2JqID0gbnVsbCwKICAgICAgICAgICAgICAgIG5leHRJbmRleCA9IC0xOwoKICAgICAgICAgICAgaWYgKHBhcmVudE1vZGVsICYmIG5leHRWaWV3UGFyZW50TW9kZWwgJiYgcGFyZW50TW9kZWwuc29tRXhwcmVzc2lvbiAhPSBuZXh0Vmlld1BhcmVudE1vZGVsLnNvbUV4cHJlc3Npb24pIHsKICAgICAgICAgICAgICAgIGlmKHBhcmVudFZpZXcgJiYgcGFyZW50VmlldyBpbnN0YW5jZW9mIHhmYWxpYi52aWV3LlN1YmZvcm1WaWV3KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudE1vZGVsLmdldFRyYXZlcnNhbE9iamVjdCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXh0Vmlld1NvbSA9IHBhcmVudE1vZGVsLmdldE5leHRUcmF2ZXJzYWxTb20oeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5uZXh0VHJhdmVyc2FsKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV4dEluZGV4ID0gdGhpcy5fZmluZFZpZXdJbkdlb2dyYXBoaWNhbE9yZGVyQXJyYXkobmV4dFZpZXdTb20pOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dEluZGV4ICE9IC0xICYmICF0aGlzLmdlb2dyYXBoaWNhbE9yZGVyW25leHRJbmRleF0udmlzaXRlZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5leHRJbmRleDsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cmF2ZXJzYWxJbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZ2V0UGFyZW50TmV4dFRyYXZlcnNhbChwYXJlbnRWaWV3LCBuZXh0VmlldywgdHJhdmVyc2FsSW5kZXgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7ICAvLyBwYXJlbnRWaWV3IGlzIG5vdCBhIHN1YmZvcm0gc28gc2tpcCB1cCBhIGxldmVsIGFuZCByZS1jaGVjayBzaWJsaW5nCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZ2V0UGFyZW50TmV4dFRyYXZlcnNhbChwYXJlbnRWaWV3LCBuZXh0VmlldywgdHJhdmVyc2FsSW5kZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOyAgLy9wcm92aWRlZCBjdXJyZW50VmlldyBhbmQgbmV4dFZpZXcgYXJlIHNpYmxpbmcKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHJhdmVyc2FsSW5kZXgrKzsKICAgICAgICB9LAoKICAgICAgICAvLyByZXR1cm4gdGhlIGluZGV4IG9mIHRoZSB2aWV3IGhhdmluZyBwcm92aWRlZCBzb21FeHByZXNzaW9uIGluIHRoZSBnZW9ncmFwaGljYWxPcmRlciBhcnJheQogICAgICAgIF9maW5kVmlld0luR2VvZ3JhcGhpY2FsT3JkZXJBcnJheSA6IGZ1bmN0aW9uIChzb21FeHByZXNzaW9uKSB7CiAgICAgICAgICAgIHJldHVybiBfLmZpbmRJbmRleCh0aGlzLmdlb2dyYXBoaWNhbE9yZGVyLCBmdW5jdGlvbiAodmlld1dyYXBwZXIpIHsKICAgICAgICAgICAgICAgIHZhciBjdXJyZW50Vmlld01vZGVsID0gdmlld1dyYXBwZXIudmlldy5tb2RlbDsKICAgICAgICAgICAgICAgIHJldHVybiAoY3VycmVudFZpZXdNb2RlbCAmJiBjdXJyZW50Vmlld01vZGVsLnNvbUV4cHJlc3Npb24gPT0gc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIC8vIGZpbmQgdGhlIG5leHQgZWxlbWVudCB0byBiZSB0cmF2ZXJzZWQgYmFzZWQgb24gdGhlIHByb3ZpZGVkIHRyYXZlcnNhbEluZGV4CiAgICAgICAgX2ZpbmROZXh0Vmlld1RvQmVUcmF2ZXJzZWQgOiBmdW5jdGlvbiAodHJhdmVyc2FsSW5kZXgpIHsKICAgICAgICAgICAgdmFyIGN1cnJlbnRWaWV3ID0gdGhpcy5nZW9ncmFwaGljYWxPcmRlclt0cmF2ZXJzYWxJbmRleF0udmlldywKICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5fZ2V0TmV4dFVudmlzaXRlZCh0cmF2ZXJzYWxJbmRleCksICAgLy9nZXQgbmV4dCB1bnZpc2l0ZWQgYmFzZWQgb24gZ2VvZ3JhcGhpY2FsIGxvY2F0aW9uCiAgICAgICAgICAgICAgICBuZXh0VmlldyA9IG51bGwsCiAgICAgICAgICAgICAgICBuZXh0SW5kZXggPSAtMTsKCiAgICAgICAgICAgIGlmIChpbmRleCAhPSAtMSkgewogICAgICAgICAgICAgICAgbmV4dFZpZXcgPSB0aGlzLmdlb2dyYXBoaWNhbE9yZGVyW2luZGV4XS52aWV3OwogICAgICAgICAgICAgICAgLy9jaGVjayBpZiBib3RoIGFyZSBzaWJsaW5nIGFuZCBpZiBub3QgZmluZCB0aGUgbmV4dCBvZiB0aGUgcGFyZW50IGFuZCB1cGRhdGUgdHJhdmVyc2FsSW5kZXgKICAgICAgICAgICAgICAgIG5leHRJbmRleCA9IHRoaXMuX2dldFBhcmVudE5leHRUcmF2ZXJzYWwoY3VycmVudFZpZXcsIG5leHRWaWV3LCB0cmF2ZXJzYWxJbmRleCk7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV4dEluZGV4ICE9IC0xID8gbmV4dEluZGV4IDogaW5kZXg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNhbEluZGV4Kys7CiAgICAgICAgfSwKCiAgICAgICAgLy8gcmV0dXJuIHRoZSBuZXh0IHVudmlzaXRlZCBub2RlIGJhc2VkIG9uIGdlb2dyYXBoaWNhbCBsb2NhdGlvbgogICAgICAgIC8vIHN0YXJ0aW5nIGZyb20gdGhlIHRyYXZlcnNhbEluZGV4IGFuZCB3cmFwcyBhcm91bmQgdG8gY2hlY2sgYWxsIHRoZSB2aWV3cwogICAgICAgIF9nZXROZXh0VW52aXNpdGVkIDogZnVuY3Rpb24gKHRyYXZlcnNhbEluZGV4KSB7CiAgICAgICAgICAgIHZhciBnZW9ncmFwaGljYWxPcmRlckxlbmd0aCA9IHRoaXMuZ2VvZ3JhcGhpY2FsT3JkZXIubGVuZ3RoLAogICAgICAgICAgICAgICAgaW5kZXggPSAwLAogICAgICAgICAgICAgICAgYWN0dWFsSW5kZXggPSAwOwogICAgICAgICAgICB3aGlsZShpbmRleCA8IGdlb2dyYXBoaWNhbE9yZGVyTGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBhY3R1YWxJbmRleCA9IChpbmRleCArIHRyYXZlcnNhbEluZGV4KSAlIGdlb2dyYXBoaWNhbE9yZGVyTGVuZ3RoOwogICAgICAgICAgICAgICAgaWYoIXRoaXMuZ2VvZ3JhcGhpY2FsT3JkZXJbYWN0dWFsSW5kZXhdLnZpc2l0ZWQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWN0dWFsSW5kZXg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbmRleCsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9LAoKICAgICAgICAvLyBhc3NpZ24gc2FtZSB0YWIgaW5kZXggdG8gYWxsIHRoZSBjaGlsZCBvZiBleGNsdWRlIGdyb3VwCiAgICAgICAgLy8gaWYgZXhjbHVkZSBncm91cCBjb250YWluIGZpcnN0IHRyYXZlcnNlIG9iamVjdCwgdGhlbiB0aGUgY2hpbGQgYmVpbmcgcmVmZXJyZWQgYXMgZmlyc3Qgc2hvdWxkIGhhdmUgbGVzcyB0YWJpbmRleAogICAgICAgIC8vIGNvbXBhcmVkIHRvIG90aGVyIGNoaWxkCiAgICAgICAgX3VwZGF0ZVRhYkluZGV4T2ZFeGNsR3JvdXBDaGlsZHJlbiA6IGZ1bmN0aW9uIChleGNsR3JvdXBWaWV3LCB0YWJJbmRleCwgZmlyc3RDaGlsZFNvbSkgewogICAgICAgICAgICBfLmVhY2goZXhjbEdyb3VwVmlldy5jaGlsZFZpZXdzLCBmdW5jdGlvbihjaGlsZCl7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5faXNWaWV3RWxpZ2libGVGb3JUYWJiaW5nKGNoaWxkKSkgewogICAgICAgICAgICAgICAgICAgIGlmKGZpcnN0Q2hpbGRTb20gJiYgY2hpbGQubW9kZWwuc29tRXhwcmVzc2lvbiA9PSBmaXJzdENoaWxkU29tKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhYkluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLnVwZGF0ZVRhYkluZGV4KHRhYkluZGV4LTEpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9sYXN0RmllbGRUYWJiZWQgPSBjaGlsZDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC51cGRhdGVUYWJJbmRleCh0YWJJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgaWYgKCFmaXJzdENoaWxkU29tKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9sYXN0RmllbGRUYWJiZWQgPSBleGNsR3JvdXBWaWV3LmNoaWxkVmlld3NbMF07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICsrdGFiSW5kZXg7CiAgICAgICAgfSwKCiAgICAgICAgLy8gZmluZCBpZiBhbnkgY2hpbGQgY29udGFpbnMgbmV4dCBwb2ludGVyIGFuZCB1cGRhdGUgdHJhdmVyc2FsIGluZGV4CiAgICAgICAgLy8gc3RhcnQgd2l0aCB0aGUgbGFzdCBpbiB0aGUgZ2VvZ3JhcGhpY2FsIG9yZGVyIG9mIHRoZSBjaGlsZHJlbiBhbmQgZmluZCBjaGlsZCB3aGljaCBoYXZlIG5leHQgdHJhdmVyc2FsCiAgICAgICAgX2ZpbmRUcmF2ZXJzYWxJbkV4Y2xHcm91cENoaWxkcmVuIDogZnVuY3Rpb24gKGV4Y2xHcm91cFZpZXcsIHRyYXZlcnNhbEluZGV4KSB7CiAgICAgICAgICAgIHZhciBzb3J0ZWRDaGlsZFZpZXcgPSB0aGlzLl9zb3J0Vmlld0dlb2dyYXBoaWNhbGx5KGV4Y2xHcm91cFZpZXcuY2hpbGRWaWV3cyksCiAgICAgICAgICAgICAgICB0ZW1wT2JqID0gbnVsbCwKICAgICAgICAgICAgICAgIGNoaWxkVmlldyA9IG51bGwsCiAgICAgICAgICAgICAgICBjaGlsZE1vZGVsID0gbnVsbCwKICAgICAgICAgICAgICAgIHRyYXZlcnNhbE9iaiA9IG51bGwsCiAgICAgICAgICAgICAgICBuZXh0Vmlld1NvbSA9IG51bGwsCiAgICAgICAgICAgICAgICBpbmRleCA9IC0xOwoKICAgICAgICAgICAgc29ydGVkQ2hpbGRWaWV3LnJldmVyc2UoKTsKICAgICAgICAgICAgdGVtcE9iaiA9IF8uZmluZChzb3J0ZWRDaGlsZFZpZXcsIGZ1bmN0aW9uKGNoaWxkKSB7CiAgICAgICAgICAgICAgICBjaGlsZFZpZXcgPSBjaGlsZC52aWV3OwogICAgICAgICAgICAgICAgY2hpbGRNb2RlbCA9IGNoaWxkVmlldy5tb2RlbDsKICAgICAgICAgICAgICAgIGlmKGNoaWxkTW9kZWwgJiYgKHRyYXZlcnNhbE9iaiA9IGNoaWxkTW9kZWwuZ2V0VHJhdmVyc2FsT2JqZWN0KCkpKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNhbE9iai5sZW5ndGggPiAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIGlmICh0ZW1wT2JqKSB7CiAgICAgICAgICAgICAgICBuZXh0Vmlld1NvbSA9IHRlbXBPYmoubW9kZWwuZ2V0TmV4dFRyYXZlcnNhbFNvbSh4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLm5leHRUcmF2ZXJzYWwpOwogICAgICAgICAgICAgICAgaW5kZXggPSB0aGlzLl9maW5kVmlld0luR2VvZ3JhcGhpY2FsT3JkZXJBcnJheShuZXh0Vmlld1NvbSk7CiAgICAgICAgICAgICAgICB0cmF2ZXJzYWxJbmRleCA9IGluZGV4ICE9IC0xID8gaW5kZXggOiB0cmF2ZXJzYWxJbmRleCArIDE7CiAgICAgICAgICAgIH0gZWxzZSB7IC8vIGVsc2UgZ2V0IG5leHQgdW52aXNpdGVkIGJhc2VkIG9uIGdlb2dyYXBoaWNhbCBsb2NhdGlvbgogICAgICAgICAgICAgICAgdHJhdmVyc2FsSW5kZXggPSB0aGlzLl9maW5kTmV4dFZpZXdUb0JlVHJhdmVyc2VkKHRyYXZlcnNhbEluZGV4KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHJhdmVyc2FsSW5kZXg7CiAgICAgICAgfSwKCiAgICAgICAgLy8gY2hlY2sgaWYgdGhlIHZpZXcgaXMgaW5pdGlhbGl6ZWQgYW5kIHZpc2libGUKICAgICAgICBfaXNWaWV3RWxpZ2libGVGb3JUYWJiaW5nIDogZnVuY3Rpb24gKHZpZXcpIHsKICAgICAgICAgICAgaWYgKHZpZXcuX2luaXRpYWxpemVkICYmIHZpZXcuJGVsLmNzcygidmlzaWJpbGl0eSIpICE9ICJoaWRkZW4iKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgLy8gcmV0dXJuIG1hcCBvZiB3aGV0aHRlciBwcm92aWRlZCB2aWV3IGlzIGluc3RhbmNlIG9mIHRoZSB2YXJpb3VzIHZpZXdzCiAgICAgICAgX2dldE1hcE9mSW5zdGFuY2VDaGVjayA6IGZ1bmN0aW9uICh2aWV3KSB7CiAgICAgICAgICAgIHZhciBpbnN0YW5jZUNoZWNrTWFwID0ge307CiAgICAgICAgICAgIGluc3RhbmNlQ2hlY2tNYXAuaXNTdWJmb3JtID0gdmlldyBpbnN0YW5jZW9mIHhmYWxpYi52aWV3LlN1YmZvcm1WaWV3OwogICAgICAgICAgICBpbnN0YW5jZUNoZWNrTWFwLmlzRmllbGQgPSB2aWV3IGluc3RhbmNlb2YgeGZhbGliLnZpZXcuRmllbGRWaWV3OwogICAgICAgICAgICBpbnN0YW5jZUNoZWNrTWFwLmlzRHJhdyA9IHZpZXcgaW5zdGFuY2VvZiB4ZmFsaWIudmlldy5YZmFEcmF3VmlldzsKICAgICAgICAgICAgaW5zdGFuY2VDaGVja01hcC5pc0V4Y2xHcm91cCA9IHZpZXcgaW5zdGFuY2VvZiB4ZmFsaWIudmlldy5FeGNsR3JvdXBWaWV3OwogICAgICAgICAgICBpbnN0YW5jZUNoZWNrTWFwLmlzQ2hpbGRPZkV4Y2xHcm91cCA9IHZpZXcucGFyZW50VmlldyBpbnN0YW5jZW9mIHhmYWxpYi52aWV3LkV4Y2xHcm91cFZpZXc7CiAgICAgICAgICAgIGluc3RhbmNlQ2hlY2tNYXAuaXNDb250YWluZXIgPSB2aWV3IGluc3RhbmNlb2YgeGZhbGliLnZpZXcuQ29udGFpbmVyVmlldzsKCiAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZUNoZWNrTWFwOwogICAgICAgIH0sCgogICAgICAgIC8vIGFkZCBldmVudCBoYW5kbGVyIGZvciByZW5kZXJpbmcgbmV4dCBwYWdlIG9uIHRhYmJpbmcgb24gbGFzdCBmaWVsZCBvZiB0aGUgcGFnZQogICAgICAgIF9yZW5kZXJOZXh0UGFnZUZ1dHVyZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKHRoaXMuX2xhc3RGaWVsZFRhYmJlZCkgewogICAgICAgICAgICAgICAgdGhpcy5fbGFzdEZpZWxkVGFiYmVkLiRlbC5vbmUoJ2ZvY3VzaW4udHJhdmVyc2FsTWFuYWdlcicsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHZhciBwYWdpbmdNYW5hZ2VyID0gd2luZG93LmZvcm1CcmlkZ2UgPyB3aW5kb3cuZm9ybUJyaWRnZS5wYWdpbmdNYW5hZ2VyKCkgOiBudWxsOwogICAgICAgICAgICAgICAgICAgICQod2luZG93KS5vbiggImtleXVwLnRyYXZlcnNhbE1hbmFnZXIiLCBmdW5jdGlvbiAoZSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29kZSA9IChlLmtleUNvZGUgPyBlLmtleUNvZGUgOiBlLndoaWNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvZGUgPT0gOSAmJiBwYWdpbmdNYW5hZ2VyICYmIHBhZ2luZ01hbmFnZXIuaGFzTW9yZVBhZ2VzKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2luZ01hbmFnZXIucmVuZGVyTmV4dFBhZ2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQod2luZG93KS5vZmYoImtleXVwLnRyYXZlcnNhbE1hbmFnZXIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIF9kZXN0cm95IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHRoaXMuZ2VvZ3JhcGhpY2FsT3JkZXIgPSBudWxsOwogICAgICAgIH0KICAgIH0KfSkoXywgJCwgeGZhbGliKTsKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKgoqIEFET0JFIENPTkZJREVOVElBTAoqIF9fX19fX19fX19fX19fX19fX18KKgoqICBDb3B5cmlnaHQgMjAxMyBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAoqICBBbGwgUmlnaHRzIFJlc2VydmVkLgoqCiogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAoqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKKiBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuCiogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiogaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CgogICAgdmFyIEVycm9yTWFuYWdlciA9IHhmYWxpYi52aWV3LnV0aWwuRXJyb3JNYW5hZ2VyID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CgogICAgICAgIG9wdGlvbnM6IHsKICAgICAgICAgICAgd2FybmluZ01lc3NhZ2VWaXNpYmxlOmZhbHNlLAogICAgICAgICAgICBlcnJvck1lc3NhZ2VWaXNpYmxlOiBmYWxzZQogICAgICAgIH0sCgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgJCh3aW5kb3cpLm9uKCJkZXN0cm95LnhmYSIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICQoIiNlcnJvci1tc2ciKS5oaWRlKCk7CiAgICAgICAgICAgICAgICAkKCIjd2FybmluZy1tc2ciKS5oaWRlKCk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIG9uRmllbGRFbnRlcjogZnVuY3Rpb24gKGpxV2lkZ2V0KSB7CiAgICAgICAgICAgIHZhciBlbGVtZW50ID0ganFXaWRnZXQuZWxlbWVudDsKICAgICAgICAgICAgaWYgKGpxV2lkZ2V0Lm9wdGlvbigiZXJyb3JNZXNzYWdlIil8fCBqcVdpZGdldC5vcHRpb24oIndhcm5pbmdNZXNzYWdlIikpIHsKICAgICAgICAgICAgICAgIHZhciBwb3MgPSAkKGVsZW1lbnQpLm9mZnNldCgpLAogICAgICAgICAgICAgICAgICAgIHN0eWxlcyA9IHt9OwogICAgICAgICAgICAgICAgc3R5bGVzLmxlZnQgPSAocG9zLmxlZnQgKiAoMSAvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IpICsgZWxlbWVudC53aWR0aCgpICsgNSkgKyAicHgiOwogICAgICAgICAgICAgICAgc3R5bGVzLnRvcCA9IHBvcy50b3AgKiAoMSAvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IpICsgInB4IjsKICAgICAgICAgICAgICAgIGlmIChqcVdpZGdldC5vcHRpb24oImVycm9yTWVzc2FnZSIpKSB7CiAgICAgICAgICAgICAgICAgICAganFXaWRnZXQuJGNzcygkKCIjZXJyb3ItbXNnIikuZ2V0KDApLCBzdHlsZXMpOwogICAgICAgICAgICAgICAgICAgICQoIiNlcnJvci1tc2ciKS50ZXh0KGpxV2lkZ2V0Lm9wdGlvbigiZXJyb3JNZXNzYWdlIikpLnNob3coKTsKICAgICAgICAgICAgICAgICAgICBqcVdpZGdldC5vcHRpb24oImVycm9yTWVzc2FnZVZpc2libGUiLHRydWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoanFXaWRnZXQub3B0aW9uKCJ3YXJuaW5nTWVzc2FnZSIpKSB7CiAgICAgICAgICAgICAgICAgICAganFXaWRnZXQuJGNzcygkKCIjd2FybmluZy1tc2ciKS5nZXQoMCksIHN0eWxlcyk7CiAgICAgICAgICAgICAgICAgICAgJCgiI3dhcm5pbmctbXNnIikudGV4dChqcVdpZGdldC5vcHRpb24oIndhcm5pbmdNZXNzYWdlIikpLnNob3coKTsKICAgICAgICAgICAgICAgICAgICBqcVdpZGdldC5vcHRpb24oIndhcm5pbmdNZXNzYWdlVmlzaWJsZSIsdHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBvbkZpZWxkRXhpdDogZnVuY3Rpb24gKGpxV2lkZ2V0KSB7CiAgICAgICAgICAgIGlmIChqcVdpZGdldC5vcHRpb24oImVycm9yTWVzc2FnZVZpc2libGUiKSkgewogICAgICAgICAgICAgICAgJCgiI2Vycm9yLW1zZyIpLmhpZGUoKTsKICAgICAgICAgICAgICAgIGpxV2lkZ2V0Lm9wdGlvbigiZXJyb3JNZXNzYWdlVmlzaWJsZSIsZmFsc2UpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGpxV2lkZ2V0Lm9wdGlvbigid2FybmluZ01lc3NhZ2VWaXNpYmxlIikpIHsKICAgICAgICAgICAgICAgICQoIiN3YXJuaW5nLW1zZyIpLmhpZGUoKTsKICAgICAgICAgICAgICAgIGpxV2lkZ2V0Lm9wdGlvbigid2FybmluZ01lc3NhZ2VWaXNpYmxlIixmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBtYXJrRXJyb3I6IGZ1bmN0aW9uIChqcVdpZGdldCwgbXNnLCB0eXBlKSB7CiAgICAgICAgICAgIC8vIGFzc2lnbmluZyByb2xlPSJhbGVydCIgc28gdGhhdCBKQVdTIHJlYWRzLW91dCB0aGUgdmFsaWRhdGlvbiBtZXNzYWdlCiAgICAgICAgICAgIGlmICh0eXBlICE9ICJ3YXJuaW5nIikgewogICAgICAgICAgICAgICAgaWYgKCQoIiNlcnJvci1tc2ciKS5sZW5ndGggPCAxKQogICAgICAgICAgICAgICAgICAgICQoIjxkaXYgaWQ9J2Vycm9yLW1zZycgcm9sZT0nYWxlcnQnPjwvZGl2PiIpLmFwcGVuZFRvKCdib2R5Jyk7CiAgICAgICAgICAgICAgICBqcVdpZGdldC5vcHRpb24oImVycm9yTWVzc2FnZSIsbXNnKTsKICAgICAgICAgICAgICAgIGpxV2lkZ2V0LmVsZW1lbnQuYWRkQ2xhc3MoImRhdGFJbnZhbGlkIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoJCgiI3dhcm5pbmctbXNnIikubGVuZ3RoIDwgMSkKICAgICAgICAgICAgICAgICAgICAkKCI8ZGl2IGlkPSd3YXJuaW5nLW1zZycgcm9sZT0nYWxlcnQnPjwvZGl2PiIpLmFwcGVuZFRvKCdib2R5Jyk7CiAgICAgICAgICAgICAgICBqcVdpZGdldC5vcHRpb24oIndhcm5pbmdNZXNzYWdlIixtc2cpOwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIGNsZWFyRXJyb3I6IGZ1bmN0aW9uIChqcVdpZGdldCkgewogICAgICAgICAgICB0aGlzLm9uRmllbGRFeGl0KGpxV2lkZ2V0KTsKICAgICAgICAgICAganFXaWRnZXQuZWxlbWVudC5yZW1vdmVDbGFzcygiZGF0YUludmFsaWQiKTsKICAgICAgICAgICAganFXaWRnZXQub3B0aW9uKCJlcnJvck1lc3NhZ2UiLG51bGwpOwogICAgICAgICAgICBqcVdpZGdldC5vcHRpb24oIndhcm5pbmdNZXNzYWdlIixudWxsKTsKICAgICAgICB9CiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sJCwgeGZhbGliKSB7CiAgICB2YXIgeGZhVXRpbCA9IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZSwKICAgICAgICBCVUZGRVJfU1BDID0gMjA7CgogICAgLyogdGVtcGxhdGUgZm9yIHRoZSBjbGVhciBCdXR0b24gKi8KICAgIHZhciBjbGVhckJ1dHRvblRlbXBsYXRlID0gJzxkaXYgY2xhc3M9ImRwLWNsZWFyIj4nICsKICAgICAgICAnPGE+PC9hPicgKwogICAgICAgICc8L2Rpdj4nOwoKICAgIC8qIHRlbXBsYXRlIGZvciB0aGUgY2FsZW5kYXIKICAgICogaGVhZGVyIGNvbnRhaW5zIHRoZSBuYXZpZ2F0aW9uIGljb25zIChsZWZ0IGFuZCByaWdodCBhcnJvd3MpCiAgICAqIGFuZCB0aGUgY3VycmVudCBjYXB0aW9uICh3aGljaCBjYW4gYmUgZGF0ZSwgeWVhciBvciBtb250aCkKICAgICoKICAgICogbW9udGh2aWV3IGRpc3BsYXlzIHRoZSBncmlkIGZvciBzaG93aW5nIHRoZSBkYXRlcyBmb3IgYSBwYXJ0aWN1bGFyCiAgICAqIG1vbnRoCiAgICAqCiAgICAqIHllYXJ2aWV3IGRpc3BsYXlzIGFsbCB0aGUgbW9udGhzIG9mIHRoYXQgeWVhcgogICAgKgogICAgKiB5ZWFyc2V0dmlldyBkaXNwbGF5cyBhIGdyaWQgb2YgMTYgeWVhcnMuIFRoaXMgY2FuIGJlIGNvbmZpZ3VyZWQKICAgICogdGhyb3VnaCB0aGUgb3B0aW9uOiB5ZWFyc1BlclZpZXcKICAgICoKICAgICovCiAgICB2YXIgY2FsZW5kYXJUZW1wbGF0ZSA9ICc8ZGl2IGNsYXNzPSJkcC1oZWFkZXIiPicgKwogICAgICAgICc8ZGl2IGNsYXNzPSJkcC1sZWZ0bmF2Ij48L2Rpdj4nICsKICAgICAgICAnPGRpdiBjbGFzcz0iZHAtY2FwdGlvbiI+PC9kaXY+JyArCiAgICAgICAgJzxkaXYgY2xhc3M9ImRwLXJpZ2h0bmF2Ij48L2Rpdj4nICsKICAgICAgICAnPC9kaXY+JyArCiAgICAgICAgJzxkaXYgcm9sZT0idGFibGUiIGNsYXNzPSJ2aWV3IGRwLW1vbnRodmlldyI+PC9kaXY+JyArCiAgICAgICAgJzxkaXYgcm9sZT0idGFibGUiIGNsYXNzPSJ2aWV3IGRwLXllYXJ2aWV3Ij48L2Rpdj4nICsKICAgICAgICAnPGRpdiByb2xlPSJ0YWJsZSIgY2xhc3M9InZpZXcgZHAteWVhcnNldHZpZXciPjwvZGl2Pic7CgogICAgLyp0ZW1wbGF0ZSBmb3IgdGhlIHRpbWVyOiBub3QgaW1wbGVtZW50ZWQgeWV0ICovCiAgICB2YXIgd2F0Y2hUZW1wbGF0ZSA9ICc8ZGl2IGNsYXNzPSJkcC1oZWFkZXIiPicgKwogICAgICAgICc8ZGl2IGNsYXNzPSJkcC1sZWZ0bmF2Ij48L2Rpdj4nICsKICAgICAgICAnPGRpdiBjbGFzcz0iZHAtY2FwdGlvbiI+PC9kaXY+JyArCiAgICAgICAgJzxkaXYgY2xhc3M9ImRwLXJpZ2h0bmF2Ij48L2Rpdj4nICsKICAgICAgICAnPC9kaXY+JyArCiAgICAgICAgJzxkaXYgY2xhc3M9InZpZXcgZHAtbW9udGh2aWV3Ij48L2Rpdj4nICsKICAgICAgICAnPGRpdiBjbGFzcz0idmlldyBkcC15ZWFydmlldyI+PC9kaXY+JyArCiAgICAgICAgJzxkaXYgY2xhc3M9InZpZXcgZHAteWVhcnNldHZpZXciPjwvZGl2Pic7CgogICAgLyoqIGRlZmF1bHQgY29uZmlndXJhdGlvbiBvcHRpb25zCiAgICAgKgogICAgICogY29udGFpbmVyOiB0aGUgaHRtbCBlbGVtZW50IHdoZXJlIHRoZSBkYXRlcGlja2VyIHRlbXBsYXRlIHdpbGwgYmUgYWRkZWQKICAgICAqCiAgICAgKiB5ZWFyc1BlclZpZXc6IG51bWJlciBvZiB5ZWFycyB0byBzaG93IGluIHRoZSB5ZWFyc2V0IHZpZXcKICAgICAqCiAgICAgKiB3aWR0aDogd2l0aCBvZiB0aGUgd2lkZ2V0CiAgICAgKgogICAgICogdmlld0hlaWdodDogSGVpZ2h0IG9mIHRoZSBtb250aCx5ZWFyIGFuZCB5ZWFyc2V0IHZpZXcuIFRoaXMgZG9lc24ndCBpbmNsdWRlCiAgICAgKiAgICAgICAgICAgICB0aGUgaGVpZ2h0IG9mIHRoZSBoZWFkZXIKICAgICAqCiAgICAgKiBsb2NhbGU6IGxvY2FsZSBpbmZvcm1hdGlvbiBmb3IgdGhlIGxvY2FsZSBpbiB3aGljaCB0byBzaG93IHRoZSBkYXRlcGlja2VyIHdoaWNoIGNvbXByaXNlcyBvZgogICAgICogICAgICAgIGRheXM6IGRheSBuYW1lcyB0byBkaXNwbGF5IGluIHRoZSBtb250aHZpZXcKICAgICAqICAgICAgICBtb250aHM6IG1vbnRoIG5hbWVzIHRvIGRpc3BsYXkgaW4gdGhlIHllYXJ2aWV3CiAgICAgKiAgICAgICAgemVybzogc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHplcm8gaW4gdGhlIGxvY2FsZS4gTnVtYmVycyB3aWxsIGJlCiAgICAgKiAgICAgICAgICAgICAgZGlzcGxheWVkIGluIHRoYXQgbG9jYWxlIG9ubHkKICAgICAqICAgICAgICBjbGVhclRleHQ6IFRleHQgdG8gZGlzcGxheSBmb3IgdGhlIHJlc2V0IGJ1dHRvbgogICAgICogICAgICAgIG5hbWU6IG5hbWUgb2YgdGhlIGxvY2FsZQogICAgICoKICAgICAqIGZvcm1hdDogaW5wdXQgZm9ybWF0IGZvciB0aGUgZGF0ZXBpY2tlciAobm90IGltcGxlbWVudGVkKQogICAgICoKICAgICAqIHBpY2tlclR5cGU6IHR5cGUgb2YgdGhlIGRhdGV0aW1lcGlja2VyIChkYXRlLCBkYXRldGltZSBhbmQgdGltZSkKICAgICAqCiAgICAgKiBwb3NpdGlvbmluZzogZWxlbWVudCBhcm91bmQgd2hpY2ggZGF0ZXBpY2tlciB3aWxsIGJlIGRpc3BsYXllZC4gaWYgbnVsbCB0aGVuIGl0CiAgICAgKiAgICAgICAgICAgICAgd2lsbCBiZSBkaXNwbGF5ZWQgYXJvdW5kIHRoZSBpbnB1dCBlbGVtZW50CiAgICAgKgogICAgICogc2hvd0NhbGVuZGFySWNvbjogdG8gc2hvdyB0aGUgQ2FsZW5kYXIgb24gdGhlIHJpZ2h0IG9mIHRoZSB0ZXh0IGZpZWxkIG9yIG5vdAogICAgICovCgogICAgdmFyIGRlZmF1bHRzID0gewogICAgICAgIGNvbnRhaW5lcjogImJvZHkiLAogICAgICAgIHllYXJzUGVyVmlldzogMTYsCiAgICAgICAgd2lkdGg6IDM0MCwKICAgICAgICB2aWV3SGVpZ2h0OiAyNDgsCiAgICAgICAgbG9jYWxlOiB7CiAgICAgICAgICAgIGRheXM6WyJTIiwiTSIsIlQiLCJXIiwiVCIsIkYiLCJTIl0sCiAgICAgICAgICAgIG1vbnRoczogWyJKYW51YXJ5IiwiRmVicnVhcnkiLCJNYXJjaCIsIkFwcmlsIiwiTWF5IiwiSnVuZSIsIkp1bHkiLCJBdWd1c3QiLCJTZXB0ZW1iZXIiLCJPY3RvYmVyIiwiTm92ZW1iZXIiLCJEZWNlbWJlciJdLAogICAgICAgICAgICB6ZXJvOiAiMCIsCiAgICAgICAgICAgIGNsZWFyVGV4dDogIkNsZWFyIiwKICAgICAgICAgICAgbmFtZToiZW5fVVMiCiAgICAgICAgfSwKICAgICAgICBmb3JtYXQ6IllZWVktTU0tREQiLAogICAgICAgIHBpY2tlclR5cGU6ImRhdGUiLAogICAgICAgIHBvc2l0aW9uaW5nOiBudWxsLAogICAgICAgIHNob3dDYWxlbmRhckljb246IGZhbHNlCiAgICB9LAogICAgZGF0ZXMgPSBbMzEsMjgsMzEsMzAsMzEsMzAsMzEsMzEsMzAsMzEsMzAsMzFdLAogICAgLyoKICAgICAqICBBY3Rpb25zIHRvIHBlcmZvcm0gd2hlbiBjbGlja2VkIG9uIHRoZSBkYXRlcGlja2VyIGJ1dHRvbnMKICAgICAqICBmb3IgZGlmZmVyZW50IHZpZXdzCiAgICAgKiAgY2FwdGlvbjogdmlldyB0byBzaG93IHdoZW4gY2xpY2tlZCBvbiBjYXB0aW9uCiAgICAgKiAgICAgICAgICAgKFllYXIvWWVhclNldC9Nb250aC9udWxsKSBudWxsIG1lYW5zIGRvbid0IGNoYW5nZSB0aGUgdmlldwogICAgICogIGxpOiB2aWV3IHRvIHNob3cgd2hlbiBjbGlja2VkIG9uIGRhdGUsIG1vbnRoIG9yIHllYXIgZWxlbWVudAogICAgICogIHVwRG93bjogYWRkKHVwIGtleSkgb3Igc3VidHJhY3QoZG93biBrZXkpIGN1cnJlbnQgZGF0ZSAoZm9yIG1vbnRodmlldyksCiAgICAgKiAgICAgICAgICBtb250aChZZWFyIFZpZXcpIG9yIHllYXIoWWVhclNldFZpZXcpIHdpdGggdGhlIG51bWJlciBwcm92aWRlZAogICAgICogIGtleTogaWRlbnRpZmllcyB0aGUga2V5IHRoYXQgbmVlZHMgdG8gYmUgY2hhbmdlZCBmb3IgdGhhdCB2aWV3CiAgICAgKi8KICAgIHZpZXdBY3Rpb24gPSB7CiAgICAgICAgTW9udGg6IHsKICAgICAgICAgICAgY2FwdGlvbjogJ1llYXInLAogICAgICAgICAgICBsaTogbnVsbCwKICAgICAgICAgICAga2V5OiJkYXkiLAogICAgICAgICAgICB1cERvd246NwogICAgICAgIH0sCiAgICAgICAgWWVhcjogewogICAgICAgICAgICBjYXB0aW9uOiAiWWVhcnNldCIsCiAgICAgICAgICAgIGxpOiAiTW9udGgiLAogICAgICAgICAgICBrZXk6Im1vbnRoIiwKICAgICAgICAgICAgdXBEb3duOjMKICAgICAgICB9LAogICAgICAgIFllYXJzZXQ6IHsKICAgICAgICAgICAgY2FwdGlvbjogbnVsbCwKICAgICAgICAgICAgbGk6ICJZZWFyIiwKICAgICAgICAgICAga2V5OiJ5ZWFyIiwKICAgICAgICAgICAgdXBEb3duOjQKICAgICAgICB9CiAgICB9LAogICAgaGVhZGVyQ2xhc3MgPSAiaGVhZGVyIiwKCiAgICBEYXRlVGltZVBpY2tlciA9IGZ1bmN0aW9uKCkgewogICAgICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSBmYWxzZTsKICAgIH0KCiAgICAkLmV4dGVuZChEYXRlVGltZVBpY2tlci5wcm90b3R5cGUsIHsKICAgICAgICAvKgogICAgICAgICAqIGNyZWF0ZSB0aGUgd2lkZ2V0IHVzaW5nIHRoZSBwcm92aWRlZCBvcHRpb25zCiAgICAgICAgICovCiAgICAgICAgY3JlYXRlOiBmdW5jdGlvbihvcHRpb25zKSB7CiAgICAgICAgICAgIHZhciAkZHAsc2VsZiA9IHRoaXMsaHRtbD0iIixwcmV2TmF2V2lkdGgsbmV4dE5hdldpZHRoOwogICAgICAgICAgICBpZiAod2luZG93LkZEICYmIHdpbmRvdy5GRC5pc1RvZ2dsZUVuYWJsZWQoIkZUX0ZPUk1TLTEzNTk5IikpIHsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0cy53aWR0aCA9IDQzMzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5vcHRpb25zID0gJC5leHRlbmQoe30sZGVmYXVsdHMsb3B0aW9ucyk7CiAgICAgICAgICAgIC8vIHByZXZlbnQgbWVtb3J5IGxlYWsgc2luY2Ugb3B0aW9ucy5wb3NpdGlvbmluZyBob2xkcyByZWZlcmVuY2UgdG8gSFRNTCBET00KICAgICAgICAgICAgdGhpcy5vcHRpb25zLnBvc2l0aW9uaW5nID0gbnVsbDsKICAgICAgICAgICAgLy8gSWYgd2lkdGggb2YgZGF0ZS1waWNrZXIgZXhjZWVkcyBzY3JlZW4gd2lkdGggdGhlbiBpdCdsbCB0YWtlIHVwIHRoZSBlbnRpcmUgc2NyZWVuIHdpZHRoIGluIEFGCiAgICAgICAgICAgIGlmKHdpbmRvdy5ndWlkZUJyaWRnZSAmJiB0aGlzLm9wdGlvbnMud2lkdGggPiB3aW5kb3cuaW5uZXJXaWR0aCAmJiB3aW5kb3cuaW5uZXJXaWR0aCA+IDApIHsKICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLndpZHRoPXdpbmRvdy5pbm5lcldpZHRoIC0gQlVGRkVSX1NQQzsgLy8gYnVmZmVyCiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLnBpY2tlclR5cGUubWF0Y2goL2RhdGUvKSkgewogICAgICAgICAgICAgICAgaHRtbCArPSBjYWxlbmRhclRlbXBsYXRlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZih0aGlzLm9wdGlvbnMucGlja2VyVHlwZS5tYXRjaCgvdGltZS8pKSB7CiAgICAgICAgICAgICAgICBodG1sICs9IHdhdGNoVGVtcGxhdGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGh0bWwgKz0gY2xlYXJCdXR0b25UZW1wbGF0ZTsKCiAgICAgICAgICAgICQuZXh0ZW5kKHRoaXMsIHsKICAgICAgICAgICAgICAgIHNlbGVjdGVkRGF5OjAsCiAgICAgICAgICAgICAgICBzZWxlY3RlZE1vbnRoOjAsCiAgICAgICAgICAgICAgICBzZWxlY3RlZFllYXI6MCwKICAgICAgICAgICAgICAgIGN1cnJlbnREYXk6MCwKICAgICAgICAgICAgICAgIGN1cnJlbnRNb250aDowLAogICAgICAgICAgICAgICAgY3VycmVudFllYXI6MCwKICAgICAgICAgICAgICAgIHRvdWNoU3VwcG9ydGVkIDogeGZhbGliLnV0LlRvdWNoVXRpbC5UT1VDSF9FTkFCTEVELAogICAgICAgICAgICAgICAgX3Zpc2libGU6ZmFsc2UsCiAgICAgICAgICAgICAgICBfZGVmYXVsdFZpZXc6Ik1vbnRoIiwKICAgICAgICAgICAgICAgIF9rZXlzRW5hYmxlZDpmYWxzZSwKICAgICAgICAgICAgICAgIGZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtIDogZmFsc2UsCiAgICAgICAgICAgICAgICBrZXlib2FyZEFjY2Vzc2liaWxpdHkgOiB0cnVlLAogICAgICAgICAgICAgICAgJGRwOiQoIjxkaXY+PC9kaXY+IikuYWRkQ2xhc3MoImRhdGV0aW1lcGlja2VyIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndpZHRoKHRoaXMub3B0aW9ucy53aWR0aCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFwcGVuZChodG1sKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoImRhdGVQaWNrZXJUYXJnZXQiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYXBwZW5kVG8odGhpcy5vcHRpb25zLmNvbnRhaW5lcikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvZ2dsZUNsYXNzKCJkYXRldGltZXBpY2tlci1ub3RvdWNoIix0aGlzLnRvdWNoU3VwcG9ydGVkKSwKICAgICAgICAgICAgICAgICRtb250aDogJCgiLmRwLW1vbnRodmlldyIsdGhpcy4kZHApLmhlaWdodCh0aGlzLm9wdGlvbnMudmlld0hlaWdodCksCiAgICAgICAgICAgICAgICAkeWVhcjogJCgiLmRwLXllYXJ2aWV3Iix0aGlzLiRkcCkuaGVpZ2h0KHRoaXMub3B0aW9ucy52aWV3SGVpZ2h0KSwKICAgICAgICAgICAgICAgICR5ZWFyc2V0IDogJCgiLmRwLXllYXJzZXR2aWV3Iix0aGlzLiRkcCkuaGVpZ2h0KHRoaXMub3B0aW9ucy52aWV3SGVpZ2h0KQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgdGhpcy5hY3R1YWxXaWR0aCA9IE1hdGguZmxvb3IodGhpcy4kZHAud2lkdGgoKSk7CiAgICAgICAgICAgIHRoaXMuJGNsZWFyID0gJCgnLmRwLWNsZWFyIGEnLCB0aGlzLiRkcCkub24oImNsaWNrIiwgJC5wcm94eSh0aGlzLl9jbGVhckRhdGUsIHRoaXMpKTsKICAgICAgICAgICAgdGhpcy4kcHJldk5hdldpZHRoQnRuID0gJCgiLmRwLWxlZnRuYXYiLCB0aGlzLiRkcCkub24oImNsaWNrIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oZXZudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fYWRqdXN0RGF0ZSgtMSwgc2VsZi52aWV3LCBmYWxzZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHRoaXMuJG5leHROYXZXaWR0aEJ0biA9ICQoIi5kcC1yaWdodG5hdiIsIHRoaXMuJGRwKS5vbigiY2xpY2siLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9hZGp1c3REYXRlKDEsIHNlbGYudmlldywgZmFsc2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICBwcmV2TmF2V2lkdGggPSB0aGlzLiRwcmV2TmF2V2lkdGhCdG4ub3V0ZXJXaWR0aCh0cnVlKTsKICAgICAgICAgICAgbmV4dE5hdldpZHRoID0gdGhpcy4kbmV4dE5hdldpZHRoQnRuLm91dGVyV2lkdGgodHJ1ZSk7CiAgICAgICAgICAgIHRoaXMuJGNhcHRpb24gPSAkKCIuZHAtY2FwdGlvbiIsIHRoaXMuJGRwKS53aWR0aCh0aGlzLmFjdHVhbFdpZHRoIC0gcHJldk5hdldpZHRoIC0gbmV4dE5hdldpZHRoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbigiY2xpY2siLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZighc2VsZi4kY2FwdGlvbi5oYXNDbGFzcygiZGlzYWJsZWQiKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2xheW91dCh2aWV3QWN0aW9uW3NlbGYudmlld10uY2FwdGlvbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICBpZiAodGhpcy5rZXlib2FyZEFjY2Vzc2liaWxpdHkpIHsKICAgICAgICAgICAgICAgIF8uZWFjaChbdGhpcy4kcHJldk5hdldpZHRoQnRuLCB0aGlzLiRjYXB0aW9uLCB0aGlzLiRuZXh0TmF2V2lkdGhCdG4sIHRoaXMuJGNsZWFyXSwgZnVuY3Rpb24gKGVsZW0sIGkpIHsKICAgICAgICAgICAgICAgICAgICBlbGVtLmF0dHIoInRhYkluZGV4IiwgaSArIDEpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gYXR0YWNoIGNsaWNrIGV2ZW50IG9uIGVudGlyZSBkYXRlUGlja2VyIHBvcHVwCiAgICAgICAgICAgICQodGhpcy4kZHApLm9uKCJjbGljayIsCiAgICAgICAgICAgICAgICBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgICAgICAgICAgLy9mb2N1cyBvbmx5IGlmIHRoZSBkZXZpY2UgZG9lc24ndCBzdXBwb3J0IHRvdWNoCiAgICAgICAgICAgICAgICAgICAgLy8gaW5wdXQgb3RoZXJ3aXNlIG9uIHNjcmVlbiBrZXlib2FyZCB3aWxsIHBvcHVwCiAgICAgICAgICAgICAgICAgICAgaWYoIXNlbGYudG91Y2hTdXBwb3J0ZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2N1ckluc3RhbmNlLiRmaWVsZC5mb2N1cygpOwogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAkKHdpbmRvdykub24oInRvdWNoc3RhcnQuZGF0ZXRpbWVwaWNrZXIgbW91c2Vkb3duLmRhdGV0aW1lcGlja2VyIixzZWxmLl9jaGVja1dpbmRvd0NsaWNrZWQpOwogICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZSA9IG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBhdHRhY2hlcyB0aGUgZGF0ZSBwaWNrZXIgdG8gdGhlIGZpZWxkLiBUaGlzIGlzIGEgb25lIHRpbWUgb3BlcmF0aW9uCiAgICAgICAgICogRmlyc3QgY3JlYXRlcyBhIGNvbmZpZ3VyYXRpb24gb2JqZWN0IGFuZCBzdG9yZXMgaXQgaW4gdGhlIGZpZWxkIGRhdGEgYXR0cmlidXRlcwogICAgICAgICAqIHRoZW4gYXR0YWNoZXMgZXZlbnQgaGFuZGxlcnMgb24gY2xpY2ssIGZvY3VzICh0byBzaG93IHRoZSBwaWNrZXIpIGFuZCBibHVyICh0byBoaWRlKSBldmVudHMKICAgICAgICAgKi8KICAgICAgICBfYXR0YWNoRmllbGQ6IGZ1bmN0aW9uKCRmaWVsZCxvcHRpb25zLCB2YWx1ZSkgewogICAgICAgICAgICB2YXIgaW5zdCA9IHRoaXMuX25ld0luc3QoJGZpZWxkLG9wdGlvbnMsIHZhbHVlKSwKICAgICAgICAgICAgICAgIHNlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgYWN0aXZhdGVGaWVsZCA9IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IHhmYVV0aWwuJGRhdGEoZXZudC50YXJnZXQsImRhdGV0aW1lcGlja2VyIik7CiAgICAgICAgICAgICAgICAgICAgaWYoc2VsZi5faXNGaWVsZERpc2FibGVkKGRhdGEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYoIXNlbGYuX2N1ckluc3RhbmNlKQogICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fYWN0aXZhdGVGaWVsZChldm50KTsKCiAgICAgICAgICAgICAgICAgICAgaWYoc2VsZi5vcHRpb25zLnNob3dDYWxlbmRhckljb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2bnQudHlwZSA9PT0gc2VsZi5nZXRFdmVudCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5faWNvbkNsaWNrZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9pY29uQ2xpY2tlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxmLl92aXNpYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2hpZGUoKTsgLy8gaGlkZSB0aGUgY2FsZW5kYXIgcG9wdXAgaWYgdmlzaWJsZSB3aGVuIGNhbGVuZGFyIGljb24gaXMgY2xpY2tlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jdXJJbnN0YW5jZS4kZmllbGQuZm9jdXMoKTsgLy8gYnJpbmcgYmFjayBmb2N1cyBpbiBmaWVsZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3Nob3coKTsgLy8vLyBzaG93IHRoZSBjYWxlbmRhciBwb3B1cCBpZiBub3QgdmlzaWJsZSB3aGVuIGNhbGVuZGFyIGljb24gaXMgY2xpY2tlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qc2hvdyB0aGUgcG9wdXAgb25seSBpZgogICAgICAgICAgICAgICAgICAgICAgICAgMS4gY2xpY2svdG91Y2ggZXZlbnQKICAgICAgICAgICAgICAgICAgICAgICAgIDIuIGZvY3VzIGV2ZW50IGluIGNhc2Ugb2Ygbm9uLXRvdWNoIGRldmljZXMgYW5kIGZvY3VzIGlzIG5vdCBkb25lIHVzaW5nIHNjcmlwdAogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2bnQudHlwZSA9PT0gc2VsZi5nZXRFdmVudCgpIHx8IChldm50LnR5cGUgPT09ICJmb2N1cyIgJiYgIXNlbGYudG91Y2hTdXBwb3J0ZWQgJiYgIXNlbGYuc2NyaXB0Rm9jdXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9zaG93KGV2bnQpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBzZWxmLl9jbGlja2VkV2luZG93ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBzZWxmLnNjcmlwdEZvY3VzID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZGVhY3RpdmF0ZUZpZWxkID0gZnVuY3Rpb24oZXZudCkgewogICAgICAgICAgICAgICAgICAgIC8vZGVhY3RpdmF0ZSBvbmx5IGlmIGNsaWNrZWQgb3V0c2lkZSB3aW5kb3cKICAgICAgICAgICAgICAgICAgICAvLyBvbiB0b3VjaCBkZXZpY2VzIG9ubHkga2V5Ym9hcmQgb3IgY2FsYW5kZXIgc2hvdWxkIGJlIGFjdGl2ZSBhdCBvbmNlLCB0b3VjaGluZyBrZXlib2FyZCBzaG91bGQgZGVhY3RpdmF0ZSBjYWxlbmRhcgogICAgICAgICAgICAgICAgICAgIGlmICgoc2VsZi5fY2xpY2tlZFdpbmRvdyAmJiAhc2VsZi5mb2N1c2VkT25EYXRlcGlja2VySXRlbSkgJiYgKHNlbGYub3B0aW9ucy5zaG93Q2FsZW5kYXJJY29uIHx8ICFzZWxmLnRvdWNoU3VwcG9ydGVkKSkgewogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9oaWRlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2RlYWN0aXZhdGVGaWVsZCgpOwogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jbGlja2VkV2luZG93ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgeGZhVXRpbC4kZGF0YSgkZmllbGRbMF0sImRhdGV0aW1lcGlja2VyIixpbnN0KTsKCiAgICAgICAgICAgICRmaWVsZC5vbih0aGlzLmdldEV2ZW50KCksYWN0aXZhdGVGaWVsZCkKICAgICAgICAgICAgICAgICAgLmZvY3VzKGFjdGl2YXRlRmllbGQpCiAgICAgICAgICAgICAgICAgIC5ibHVyKGRlYWN0aXZhdGVGaWVsZCk7CiAgICAgICAgICAgIGlmKG9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbikgewogICAgICAgICAgICAgICAgdmFyIGNhbGVuZGFySWNvbiA9ICQoIjxkaXY+PC9kaXY+IikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZENsYXNzKCJkYXRlcGlja2VyLWNhbGVuZGFyLWljb24iKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY3NzKHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3aWR0aCI6IG9wdGlvbnMuaWNvbldpZHRoICsgInB4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJoZWlnaHQiOiBvcHRpb25zLmljb25IZWlnaHQgKyAicHgiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgY2FsZW5kYXJJY29uLmluc2VydEFmdGVyKCRmaWVsZCk7CgogICAgICAgICAgICAgICAgaWYgKHRoaXMua2V5Ym9hcmRBY2Nlc3NpYmlsaXR5KSB7CiAgICAgICAgICAgICAgICAgICAgY2FsZW5kYXJJY29uLmF0dHIoInRhYmluZGV4IiwgMCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgY2FsZW5kYXJJY29uLm9uKHRoaXMuZ2V0RXZlbnQoKSwgZnVuY3Rpb24gKGV2bnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9pY29uQ2xpY2tlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGZpZWxkLmNsaWNrKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbigia2V5ZG93biIsIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gMzIgfHwgZXZlbnQua2V5Q29kZSA9PT0gMTMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGZpZWxkIGlzIGRpc2FibGVkIGJlZm9yZSB0cmlnZ2VyaW5nIGNsaWNrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IHhmYVV0aWwuJGRhdGEoJGZpZWxkWzBdLCAiZGF0ZXRpbWVwaWNrZXIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhICYmICFzZWxmLl9pc0ZpZWxkRGlzYWJsZWQoZGF0YSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZmllbGQuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9uZXdJbnN0OiBmdW5jdGlvbigkZixvcHRpb25zLCB2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgJGZpZWxkOiRmLAogICAgICAgICAgICAgICAgbG9jYWxlOiBvcHRpb25zLmxvY2FsZSwKICAgICAgICAgICAgICAgIHBvc2l0aW9uaW5nOiBvcHRpb25zLnBvc2l0aW9uaW5nIHx8ICRmLAogICAgICAgICAgICAgICAgYWNjZXNzOm9wdGlvbnMuYWNjZXNzLAogICAgICAgICAgICAgICAgc2VsZWN0ZWREYXRlOm9wdGlvbnMudmFsdWUsCiAgICAgICAgICAgICAgICBlZGl0VmFsdWUgOm9wdGlvbnMuZWRpdFZhbHVlLAogICAgICAgICAgICAgICAgbWluVmFsaWREYXRlIDogb3B0aW9ucy5taW5WYWxpZERhdGUsCiAgICAgICAgICAgICAgICBtYXhWYWxpZERhdGUgOiBvcHRpb25zLm1heFZhbGlkRGF0ZSwKICAgICAgICAgICAgICAgIGV4Y2xNaW5EYXRlIDogIG9wdGlvbnMuZXhjbE1pbkRhdGUsCiAgICAgICAgICAgICAgICBleGNsTWF4RGF0ZSA6IG9wdGlvbnMuZXhjbE1heERhdGUKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogVG8gY2hlY2sgd2hlcmUgdGhlIGNsaWNrIGhhcHBlbmVkLCBpZiBoYXBwZW5lZCBvdXRzaWRlIHRoZSBkYXRlcGlja2VyCiAgICAgICAgICogdGhlbiBoaWRlIHRoZSBwaWNrZXIuIFRoaXMgaXMgY2hlY2tlZCB3aGV0aGVyIGFueSBhbmNlc3RvciBvZiBjbGlja2VkIHRhcmdldAogICAgICAgICAqIGhhcyBhIGNsYXNzIGRhdGVQaWNrZXJUYXJnZXQuIFRoaXMgY2xhc3MgaXMgYWRkZWQgdG8gdGhlIGF0dGFjaGVkIGVsZW1lbnQgYXMgd2VsbAogICAgICAgICAqLwogICAgICAgIF9jaGVja1dpbmRvd0NsaWNrZWQgOiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgIHZhciBzZWxmID0gYWRvYmVEYXRlVGltZVBpY2tlcjsKICAgICAgICAgICAgaWYoc2VsZi5fY3VySW5zdGFuY2UpIHsKICAgICAgICAgICAgICAgIC8vIGRhdGVwaWNrZXJUYXJnZXQgY2xhc3MgZGVwaWN0cyB0aGF0IHRoZSBjb21wb25lbnQgaXMgYSBwYXJ0IG9mIHRoZSBEYXRlIEZpZWxkCiAgICAgICAgICAgICAgICAvLyBhbmQgb24gY2xpY2sgb2YgdGhhdCBjbGFzcywgd2Ugc2hvdWxkIG5vdCBoaWRlIHRoZSBkYXRlcGlja2VyIG9yIGZpcmUgZXhpdCBldmVudHMuCiAgICAgICAgICAgICAgICBpZighJChldm50LnRhcmdldCkuY2xvc2VzdCgiLmRhdGVQaWNrZXJUYXJnZXQiKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAvL25vbi10b3VjaCBkZXZpY2VzIGRvIG5vdCBkZWFjdGl2YXRlIG9uIGJsdXIuIEhlbmNlIG5lZWRzIHRvIGJlIGRvbmUgaGVyZQogICAgICAgICAgICAgICAgICAgIGlmKHNlbGYudG91Y2hTdXBwb3J0ZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5faGlkZSgpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vY2xpY2tpbmcgb3V0c2lkZSBhIGZpZWxkIGRvZXNuJ3QgYmx1ciB0aGUgZmllbGQgaW4gSVBhZC4gRG9pbmcgaXQgYnkgc2NyaXB0CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2N1ckluc3RhbmNlLiRmaWVsZFswXS5ibHVyKCkKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fZGVhY3RpdmF0ZUZpZWxkKCkKICAgICAgICAgICAgICAgICAgICB9IGVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NsaWNrZWRXaW5kb3cgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBzZXQgZm9jdXNlZE9uRGF0ZXBpY2tlckl0ZW0gdG8gZmFsc2UsIGl0IGhpZGVzIHRoZSBkYXRlcGlja2VyIHNlZSBtZXRob2QgZGVhY3RpdmF0ZUZpZWxkLgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2N1ckluc3RhbmNlLiRmaWVsZC5ibHVyKCkKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBzZWxmLl9jbGlja2VkV2luZG93ID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBDaGVja3MgaWYgdGhlIGN1cnJlbnQgZGF0ZXBpY2tlciBmaWVsZCBpcyBkaXNhYmxlZC4KICAgICAgICAgKgogICAgICAgICAqIEZpZWxkcyBtYXJrZWQgYXMgInJlYWRPbmx5IiBvciB3aXRoIGFjY2VzcyBzZXQgdG8gZmFsc2UgYXJlIGNvbnNpZGVyZWQKICAgICAgICAgKiBkaXNhYmxlZCBhbmQgc2hvdWxkIG5vdCBhbGxvdyBkYXRlcGlja2VyIGludGVyYWN0aW9uLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IFtkYXRhXSAtIE9wdGlvbmFsIGRhdGEgb2JqZWN0IHRvIGNoZWNrLiBJZiBub3QgcHJvdmlkZWQsIHVzZXMgY3VycmVudCBpbnN0YW5jZS4KICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZmllbGQgaXMgZGlzYWJsZWQgKGFjY2VzcyBpcyAicmVhZE9ubHkiIG9yIGZhbHNlKSwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICAgICAqICAgICAgICAgICAgICAgICAgIFJldHVybnMgZmFsc2UgaWYgbm8gY3VycmVudCBpbnN0YW5jZSBleGlzdHMuCiAgICAgICAgICovCiAgICAgICAgX2lzRmllbGREaXNhYmxlZDogZnVuY3Rpb24oZGF0YSkgewogICAgICAgICAgICBpZiAoZGF0YSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuYWNjZXNzID09PSBmYWxzZSB8fCBkYXRhLmFjY2VzcyA9PT0gInJlYWRPbmx5IjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdGhpcy5fY3VySW5zdGFuY2UgJiYgKHRoaXMuX2N1ckluc3RhbmNlLmFjY2VzcyA9PT0gZmFsc2UgfHwgdGhpcy5fY3VySW5zdGFuY2UuYWNjZXNzID09PSAicmVhZE9ubHkiKTsKICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIGhhbmRsaW5nIG9mIGtleSBzdHJva2VzLiBBbGwgdGhlIGtleSBzdHJva2VzIHByZXZlbnQgdGhlIGRlZmF1bHQgYnJvd3NlciBhY3Rpb24KICAgICAgICAgKiB1bmxlc3Mgc3BlY2lmaWVkIG90aGVyd2lzZQogICAgICAgICAqIHRhYjogc2V0IGZvY3VzIG9uIGNhbGVuZGFyIGljb24gd2hlbiBkYXRlaW5wdXQgZmllbGQgaXMgYWN0aXZlLCBuYXZpZ2F0ZXMgdGhyb3VnaCBkYXRlIHBpY2tlciBidXR0b25zIHdoZW4gZGF0ZXBpY2tlciBpcyBvcGVuLAogICAgICAgICAqIG90aGVyd2lzZSBwZXJmb3JtIGRlZmF1bHQgYnJvd3NlciBhY3Rpb24KICAgICAgICAgKiBlc2NhcGU6IGhpZGVzIHRoZSBkYXRlcGlja2VyCiAgICAgICAgICogZG93biBhcnJvdyBrZXk6IG5hdmlnYXRlIHRoZSBwaWNrZXIgZG93bndhcmRzIGJ5IHRoZSBudW1iZXIgc3BlY2lmaWVkIGluIGFjdGlvblZpZXcudXBEb3duIG9mIHRoZSBjdXJyZW50IFZpZXcKICAgICAgICAgKiB1cCBhcnJvdyBrZXk6IG5hdmlnYXRlIHRoZSBwaWNrZXIgdXB3YXJkcyBieSB0aGUgbnVtYmVyIHNwZWNpZmllZCBpbiBhY3Rpb25WaWV3LnVwRG93biBvZiB0aGUgY3VycmVudCBWaWV3CiAgICAgICAgICogbGVmdCBhcnJvdyBrZXk6IG5hdmlnYXRlIHRoZSBwaWNrZXIgb25lIHVuaXQgb2YgdGhhdCB2aWV3IGJhY2t3YXJkCiAgICAgICAgICogcmlnaHQgYXJyb3cga2V5OiBuYXZpZ2F0ZSB0aGUgcGlja2VyIG9uZSB1bml0IG9mIHRoYXQgdmlldyBmb3J3YXJkCiAgICAgICAgICogc2hpZnQgKyB1cDogcGVyZm9ybSB0aGUgYWN0aW9uIHRoYXQgaGFwcGVucyBvbiBjbGlja2luZyB0aGUgY2FwdGlvbiAoYXMgc3BlY2lmaWVkIGluIGFjdGlvblZpZXcuY2FwdGlvbikKICAgICAgICAgKiBzaGlmdCArIGxlZnQ6IHBlcmZvcm0gdGhlIGFjdGlvbiB0aGF0IGhhcHBlbnMgb24gY2xpY2tpbmcgdGhlIGxlZnQgbmF2aWdhdGlvbiBidXR0b24KICAgICAgICAgKiBzaGlmdCArIHJpZ2h0OiBwZXJmb3JtIHRoZSBhY3Rpb24gdGhhdCBoYXBwZW5zIG9uIGNsaWNraW5nIHRoZSByaWdodCBuYXZpZ2F0aW9uIGJ1dHRvbgogICAgICAgICAqIHNwYWNlL2VudGVyOiB0cmlnZ2VycyB0aGUgY2xpY2sgZXZlbnQgZm9yIHRoZSBjdXJyZW50IGZvY3VzZWQgZWxlbWVudCBmcm9tIGRhdGVwaWNrZXIvIG9wZW5zIGRhdGVwaWNrZXIgd2hlbiBjYWxlbmRhciBpY29uIGlzIGZvY3VzZWQuCiAgICAgICAgICovCiAgICAgICAgX2hvdEtleXM6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgdmFyIGhhbmRsZWQgPSBmYWxzZSwgZGF0ZTsKICAgICAgICAgICAgc3dpdGNoKGV2bnQua2V5Q29kZSkgewogICAgICAgICAgICAgICAgY2FzZSA5OiAvL3RhYgogICAgICAgICAgICAgICAgICAgIC8vIENRLTQyMzkzNTIgOiBTZXR0aW5nIGNsaWNrZWRXaW5kb3cgcHJvcGVydHkgdG8gdHJ1ZSBvbiB0YWJiaW5nIHNvIHRoYXQgZGVhY3RpdmF0ZUZpZWxkIGxvZ2ljIGdldHMgZXhlY3V0ZWQKICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGNsaWNraW5nIG9uICJ4IiBvbiBpbnB1dCBmaWVsZCBpbiBpbiBJRSBhbmQgd2hlbiBzZWxlY3RpbmcgdGhlIGNvbnRlbnQgYW5kIHJlbGVhc2luZyB0aGUgbW91c2Ugc2VsZWN0IG91dHNpZGUgdGhlIGZpZWxkCiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGNsaWNrIGV2ZW50IGlzIG5vdCB0cmlnZXJyZWQgb24gdGhlIGZpZWxkIGFuZCBoZW5jZSBhY3RpdmF0ZUZpZWxkIGlzIG5vdCBleGVjdXRlZCwgc28gY2xpY2tlZFdpbmRvdyByZW1haW5zIGFzIGZhbHNlCiAgICAgICAgICAgICAgICAgICAgYWRvYmVEYXRlVGltZVBpY2tlci5fY2xpY2tlZFdpbmRvdyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAyNzovL2VzY2FwZQogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX3Zpc2libGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWRvYmVEYXRlVGltZVBpY2tlci5faGlkZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQuZm9jdXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAzMjogLy9zcGFjZQogICAgICAgICAgICAgICAgY2FzZSAxMzogLy8gZW50ZXIKICAgICAgICAgICAgICAgICAgICBpZigkKGV2bnQudGFyZ2V0KS5oYXNDbGFzcygiZGF0ZXBpY2tlci1jYWxlbmRhci1pY29uIikpewogICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBmaWVsZCBpcyBkaXNhYmxlZCBiZWZvcmUgc2hvd2luZyBkYXRlcGlja2VyCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRpc2FibGVkIGZpZWxkcyBhcmUgbWFya2VkIGFzIHJlYWRPbmx5IGluIHRoZSBmb3JtCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX2lzRmllbGREaXNhYmxlZCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYoIXRoaXMuX3Zpc2libGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Nob3coKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRmb2N1c2VkRGF0ZS5hZGRDbGFzcygiZHAtZm9jdXMiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDQwOiAvL2Rvd24gYXJyb3cga2V5CiAgICAgICAgICAgICAgICAgICAgaWYoIXRoaXMuX3Zpc2libGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgZmllbGQgaXMgZGlzYWJsZWQgYmVmb3JlIHNob3dpbmcgZGF0ZXBpY2tlcgogICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl9pc0ZpZWxkRGlzYWJsZWQoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Nob3coKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aGlzLiRmb2N1c2VkRGF0ZS5hZGRDbGFzcygiZHAtZm9jdXMiKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYoYWRvYmVEYXRlVGltZVBpY2tlci5fdmlzaWJsZSAmJiB0aGlzLl9rZXlzRW5hYmxlZCkgewogICAgICAgICAgICAgICAgdmFyIHYgPSB2aWV3QWN0aW9uW3RoaXMudmlld10ua2V5LAogICAgICAgICAgICAgICAgICAgIHVwZG93bj12aWV3QWN0aW9uW3RoaXMudmlld10udXBEb3duOwogICAgICAgICAgICAgICAgc3dpdGNoKGV2bnQua2V5Q29kZSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgOTogLy8gdGFiCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldm50LnNoaWZ0S2V5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoJChldm50LnRhcmdldCkuaGFzQ2xhc3MoImRwLWxlZnRuYXYiKSB8fCAkKGV2bnQudGFyZ2V0KS5oYXNDbGFzcygiZHAtZm9jdXMiKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2hpZGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQuZm9jdXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGJ1dHRvblRhYmluZGV4ID0gJChldm50LnRhcmdldCkuYXR0cigidGFiaW5kZXgiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChidXR0b25UYWJpbmRleCA9PT0gJzAnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2bnQudGFyZ2V0LnRhZ05hbWUudG9Mb2NhbGVMb3dlckNhc2UoKSA9PT0gImlucHV0IikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9oaWRlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRwcmV2TmF2V2lkdGhCdG4uZm9jdXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChidXR0b25UYWJpbmRleCA9PT0gJzQnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faGlkZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlLiRmaWVsZC5mb2N1cygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAzMjogLy9zZWxlY3Qgb24gc3BhY2UKICAgICAgICAgICAgICAgICAgICBjYXNlIDEzOiAvLyBzZWxlY3Qgb24gZW50ZXIKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5ob3RLZXlQcmVzc2VkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mb2N1c2VkT25EYXRlcGlja2VySXRlbSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZm9jdXNlZE9uRGF0ZXBpY2tlckl0ZW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoZXZudC50YXJnZXQsIHRoaXMuJGRwKS50cmlnZ2VySGFuZGxlcigiY2xpY2siKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLiRmb2N1c2VkRGF0ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGZvY3VzZWREYXRlLnRyaWdnZXIoImNsaWNrIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5ob3RLZXlQcmVzc2VkID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIDM3OiAvL2xlZnQgYXJyb3cga2V5CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldm50LnNoaWZ0S2V5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCIuZHAtbGVmdG5hdiIsIHRoaXMuJGRwKS50cmlnZ2VySGFuZGxlcigiY2xpY2siKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkanVzdERhdGUoLTEsIHYsIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIDM4OiAvL3VwIGFycm93IGtleQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZudC5zaGlmdEtleSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kY2FwdGlvbi50cmlnZ2VySGFuZGxlcigiY2xpY2siKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkanVzdERhdGUoLXVwZG93biwgdiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgMzk6IC8vcmlnaHQgYXJyb3cga2V5CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldm50LnNoaWZ0S2V5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCIuZHAtcmlnaHRuYXYiLCB0aGlzLiRkcCkudHJpZ2dlckhhbmRsZXIoImNsaWNrIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9hZGp1c3REYXRlKCsxLCB2LCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSA0MDogLy9kb3duIGFycm93IGtleQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9hZGp1c3REYXRlKHVwZG93biwgdiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKGhhbmRsZWQpIHsKICAgICAgICAgICAgICAgIGV2bnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogc2hvdyB0aGUgZGF0ZXBpY2tlci4KICAgICAgICAgKi8KICAgICAgICBfc2hvdzogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmKHRoaXMuX2lzRmllbGREaXNhYmxlZCgpKQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB0aGlzLm9wdGlvbnMubG9jYWxlID0gdGhpcy5fY3VySW5zdGFuY2UubG9jYWxlOwogICAgICAgICAgICBpZighdGhpcy5fdmlzaWJsZSkgewogICAgICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgICAgIGRhdGUgPSBuZXcgRGF0ZSgpLAogICAgICAgICAgICAgICAgICAgIHZhbCwKICAgICAgICAgICAgICAgICAgICBtYXhEYXRlSW5mbywKICAgICAgICAgICAgICAgICAgICBtaW5EYXRlSW5mbywKICAgICAgICAgICAgICAgICAgICB2YWxpZERhdGU7CiAgICAgICAgICAgICAgICAvL0J1ZyMzNjA3NzM1OgogICAgICAgICAgICAgICAgLy8gRGF0ZSBjb25zdHJ1Y3RvciBpbiBpcGFkIDUuMSBkb2Vzbid0IHN1cHBvcnQgIllZWVktTU0tREQiLCBoZW5jZSBwYXJzaW5nIHRoZSBkYXRlIG9uIG91ciBvd24KICAgICAgICAgICAgICAgIHZhbGlkRGF0ZSA9IHhmYWxpYi51dC5EYXRlSW5mby5QYXJzZUlzb1N0cmluZyh0aGlzLl9jdXJJbnN0YW5jZS5zZWxlY3RlZERhdGUpOwogICAgICAgICAgICAgICAgZGF0ZSA9ICh2YWxpZERhdGUgIT0gbnVsbCk/IHZhbGlkRGF0ZS5nZXREYXRlKCk6IG5ldyBEYXRlKCk7CiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkRGF5ID0gdGhpcy5jdXJyZW50RGF5ID0gZGF0ZS5nZXREYXRlKCk7CiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkTW9udGggPSB0aGlzLmN1cnJlbnRNb250aCA9IGRhdGUuZ2V0TW9udGgoKTsKICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRZZWFyID0gdGhpcy5jdXJyZW50WWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKTsKICAgICAgICAgICAgICAgIG1heERhdGVJbmZvID0gdGhpcy5vcHRpb25zLm1heFZhbGlkRGF0ZSA/IHhmYWxpYi51dC5EYXRlSW5mby5QYXJzZUlzb1N0cmluZyh0aGlzLl9jdXJJbnN0YW5jZS5tYXhWYWxpZERhdGUpIDogbnVsbDsKICAgICAgICAgICAgICAgIHRoaXMubWF4VmFsaWREYXRlID0gbWF4RGF0ZUluZm8gPyBtYXhEYXRlSW5mby5nZXREYXRlKCkgOiBudWxsOwogICAgICAgICAgICAgICAgbWluRGF0ZUluZm8gPSB0aGlzLm9wdGlvbnMubWluVmFsaWREYXRlID8geGZhbGliLnV0LkRhdGVJbmZvLlBhcnNlSXNvU3RyaW5nKHRoaXMuX2N1ckluc3RhbmNlLm1pblZhbGlkRGF0ZSkgOiBudWxsOwogICAgICAgICAgICAgICAgdGhpcy5taW5WYWxpZERhdGUgPSBtaW5EYXRlSW5mbyA/IG1pbkRhdGVJbmZvLmdldERhdGUoKSA6IG51bGw7CiAgICAgICAgICAgICAgICB0aGlzLmV4Y2xNYXhEYXRlID0gdGhpcy5fY3VySW5zdGFuY2UuZXhjbE1heERhdGU7CiAgICAgICAgICAgICAgICB0aGlzLmV4Y2xNaW5EYXRlID0gdGhpcy5fY3VySW5zdGFuY2UuZXhjbE1pbkRhdGU7CiAgICAgICAgICAgICAgICAkKCcuZHAtY2xlYXIgYScsdGhpcy4kZHApLnRleHQodGhpcy5vcHRpb25zLmxvY2FsZS5jbGVhclRleHQpOwogICAgICAgICAgICAgICAgdGhpcy5fbGF5b3V0KCdNb250aCcpOwogICAgICAgICAgICAgICAgdGhpcy5fcG9zaXRpb24oKTsKICAgICAgICAgICAgICAgIHRoaXMuJGRwLnNob3coKTsKICAgICAgICAgICAgICAgIC8vIGlmIGxpIGVsZW1lbnQgb2YgZGF0ZXBpY2tlciBpcyBmb2N1c2VkIHRoZW4gc2V0IGZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtIHRvIHRydWUsIGl0IG1hbmFnZXMgdGhlIHZpc2liaWxpdHkgb2YgdGhlIGRhdGVwaWNrZXIuCiAgICAgICAgICAgICAgICB0aGlzLmZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtID0gZmFsc2U7CiAgICAgICAgICAgICAgICB0aGlzLl92aXNpYmxlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbikgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlLiRmaWVsZC5hdHRyKCdyZWFkb25seScsIHRydWUpOyAgICAvLyB3aGVuIHRoZSBkYXRlcGlja2VyIGlzIGFjdGl2ZSwgZGVhY3RpdmF0ZSB0aGUgZmllbGQKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gICBEaXNhYmxpbmcgdGhlIGZvY3VzIG9uIGlwYWQgIGR1ZSB0byBhIGJ1ZyB3aGVyZSB2YWx1ZSBvZgogICAgICAgICAgICAvLyBkYXRlIHBpY2tlciBpcyBub3QgYmVpbmcgc2V0CiAgICAgICAgICAgIC8vIFJlbW92aW5nIHRoaXMgY29kZSB3aWxsIG9ubHkgaGFtcGVyIG9uZSB1c2UgY2FzZQogICAgICAgICAgICAvLyB3aGVyZSBvbiBpcGFkIGlmIHlvdSBjbGljayBvbiB0aGUgY2FsYW5kZXIgdGhlbgogICAgICAgICAgICAvLyB0aGUgZmllbGQgYmVjb21lcyByZWFkIG9ubHkgc28KICAgICAgICAgICAgLy8gdGhlcmUgaXMgbm8gaW5kaWNhdGlvbiB3aGVyZSB0aGUgY3VycmVudCBmb2N1cyBpcwogICAgICAgICAgICAvLyBBbmQgIGlmIHlvdSByZW1vdmUgdGhpcyBmb3VjcyBjb2RlIGFsbCB0b2dldGhlcgogICAgICAgICAgICAvLyB0aGVuIHdoYXQgaGFwcGVucyBpcyB0aGF0IG9uIGRlc2t0b3AgTUYgaW4gaWZyYW1lIHRoZSBleGl0IGV2ZW50CiAgICAgICAgICAgIC8vIGlzIG5vdCBnZXR0aW5nIGNhbGxlZCBoZW5jZSBjYWxhbmRlciBnZXR0aW5nIHJlbWFpbmVkIG9wZW4gZXZlbgogICAgICAgICAgICAvLyB3aGVuIHlvdSBjbGljayBzb21ld2hlcmUgb24gd2luZG93IG9yIGZvY3VzIGludG8gc29tZSBvdGhlciBmaWVsZAogICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNob3dDYWxlbmRhckljb24gICYmICF0aGlzLnRvdWNoU3VwcG9ydGVkKSB7CiAgICAgICAgICAgICAgICBpZih0aGlzLiRmb2N1c2VkRGF0ZS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZm9jdXNlZERhdGUuZm9jdXMoKTsgIC8vIHNoaWZ0IGZvY3VzIG9uIGN1cnJlbnQgZGF0ZSBvciBzZWxlY3RlZCBkYXRlLgogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQuZm9jdXMoKTsgLy8gZmllbGQgbG9zZXMgZm9jdXMgYWZ0ZXIgYmVpbmcgbWFya2VkIHJlYWRvbmx5LCBjYXVzaW5nIGJsdXIgZXZlbnQgbm90IHRvIGJlIGZpcmVkIGxhdGVyCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIHBvc2l0aW9uIHRoZSBkYXRlcGlja2VyIGFyb3VuZCB0aGUgcG9zaXRpb25pbmcgZWxlbWVudAogICAgICAgICAqIHByb3ZpZGVkIGluIHRoZSBvcHRpb25zCiAgICAgICAgICovCiAgICAgICAgX3Bvc2l0aW9uOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyICRlbGVtID0gdGhpcy5fY3VySW5zdGFuY2UucG9zaXRpb25pbmcsCiAgICAgICAgICAgICAgICB3aW5kb3dTY3JvbGxYID0gd2luZG93LnNjcm9sbFgvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IsCiAgICAgICAgICAgICAgICB3aW5kb3dTY3JvbGxZID0gd2luZG93LnNjcm9sbFkvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IsCiAgICAgICAgICAgICAgICB3aW5kb3dJbm5lckhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodC8geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmZvcm1TY2FsZUZhY3RvciwKICAgICAgICAgICAgICAgIHdpbmRvd0lubmVyV2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aC8geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmZvcm1TY2FsZUZhY3RvciwKICAgICAgICAgICAgICAgIGhlaWdodCA9ICRlbGVtLm91dGVySGVpZ2h0KHRydWUpLAogICAgICAgICAgICAgICAgd2lkdGggID0gJGVsZW0ub3V0ZXJXaWR0aCh0cnVlKSwKICAgICAgICAgICAgICAgIHRvcCA9ICRlbGVtLm9mZnNldCgpLnRvcCAvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IgKyBoZWlnaHQsCiAgICAgICAgICAgICAgICBsZWZ0ID0gJGVsZW0ub2Zmc2V0KCkubGVmdCAvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IsCiAgICAgICAgICAgICAgICBzdHlsZXMgPSB7InRvcCI6ICh0b3ArInB4IiksICJsZWZ0IjogKGxlZnQrInB4Iil9LAogICAgICAgICAgICAgICAgZGlmZkJvdHRvbSA9IHRvcCArIHRoaXMuJGRwLm91dGVySGVpZ2h0KHRydWUpIC0gd2luZG93SW5uZXJIZWlnaHQgLSB3aW5kb3dTY3JvbGxZLAogICAgICAgICAgICAgICAgbmV3TGVmdCwKICAgICAgICAgICAgICAgIG5ld1RvcDsKICAgICAgICAgICAgaWYoZGlmZkJvdHRvbSA+IDApIHsKICAgICAgICAgICAgICAgIC8vY2FuJ3QgYXBwZWFyIGF0IHRoZSBib3R0b20KICAgICAgICAgICAgICAgIC8vY2hlY2sgdG9wCiAgICAgICAgICAgICAgICBuZXdUb3AgPSB0b3AgLSBoZWlnaHQgLSB0aGlzLiRkcC5vdXRlckhlaWdodCh0cnVlKSAtIEJVRkZFUl9TUEM7CiAgICAgICAgICAgICAgICBpZihuZXdUb3AgPCB3aW5kb3dTY3JvbGxZKSB7CiAgICAgICAgICAgICAgICAgICAgLy9jYW4ndCBhcHBlYXIgYXQgdGhlIHRvcCBhcyB3ZWxsIC4uLiB0aGUgZGF0ZVBpY2tlciBwb3AgdXAgb3ZlcmxhcHMgdGhlIGRhdGUgZmllbGQKICAgICAgICAgICAgICAgICAgICBuZXdUb3AgPSB0b3AgLSBkaWZmQm90dG9tOwogICAgICAgICAgICAgICAgICAgIC8vIEZpeCBmb3IgQlVHICMzNjI2OTc0CiAgICAgICAgICAgICAgICAgICAgaWYoeGZhVXRpbC5pc1dlYmtpdCgpICYmICF0aGlzLm9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbikgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQudHJpZ2dlcigib25vdmVybGFwLmRhdGV0aW1lcGlja2VyIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc3R5bGVzLnRvcCA9IG5ld1RvcCArICJweCI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYobGVmdCArIHRoaXMuJGRwLm91dGVyV2lkdGgodHJ1ZSkgPiB3aW5kb3dTY3JvbGxYICsgd2luZG93SW5uZXJXaWR0aCApIHsKICAgICAgICAgICAgICAgIC8vYWxpZ24gd2l0aCB0aGUgcmlnaHQgZWRnZQogICAgICAgICAgICAgICAgbmV3TGVmdCA9IHdpbmRvd1Njcm9sbFggKyB3aW5kb3dJbm5lcldpZHRoIC0gdGhpcy4kZHAub3V0ZXJXaWR0aCh0cnVlKSAtIEJVRkZFUl9TUEM7CiAgICAgICAgICAgICAgICBzdHlsZXMubGVmdCA9IG5ld0xlZnQgKyAicHgiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHhmYVV0aWwuJGNzcyh0aGlzLiRkcC5nZXQoMCksIHN0eWxlcyk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogbGF5b3V0IHRoZSBuZXh0Vmlldy4gaWYgbmV4dFZpZXcgaXMgbnVsbCByZXR1cm4KICAgICAgICAgKgogICAgICAgICAqLwogICAgICAgIF9sYXlvdXQ6IGZ1bmN0aW9uKG5leHRWaWV3KSB7CiAgICAgICAgICAgIGlmKG5leHRWaWV3ID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2hpZGUoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMudmlldykKICAgICAgICAgICAgICAgICAgICB0aGlzWyckJyt0aGlzLnZpZXcudG9Mb3dlckNhc2UoKV0uaGlkZSgpOwogICAgICAgICAgICAgICAgdGhpcy52aWV3ID0gbmV4dFZpZXc7CiAgICAgICAgICAgICAgICB0aGlzLiRjYXB0aW9uLnRvZ2dsZUNsYXNzKCJkaXNhYmxlZCIsIXZpZXdBY3Rpb25bdGhpcy52aWV3XS5jYXB0aW9uKTsKICAgICAgICAgICAgICAgIHRoaXNbJyQnK3RoaXMudmlldy50b0xvd2VyQ2FzZSgpXS5zaG93KCk7CiAgICAgICAgICAgICAgICB0aGlzWyJzaG93Iit0aGlzLnZpZXddKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBzaG93IHRoZSBtb250aCB2aWV3CiAgICAgICAgICovCiAgICAgICAgc2hvd01vbnRoOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgY3VyRGF0ZSA9IG5ldyBEYXRlKHRoaXMuY3VycmVudFllYXIsIHRoaXMuY3VycmVudE1vbnRoKSwKICAgICAgICAgICAgICAgIG1heERheSA9ICAgdGhpcy5fbWF4RGF0ZSh0aGlzLmN1cnJlbnRNb250aCksCiAgICAgICAgICAgICAgICBwcmV2TWF4RGF5ID0gdGhpcy5fbWF4RGF0ZSgodGhpcy5jdXJyZW50TW9udGggKyAxMSklMTIpLAogICAgICAgICAgICAgICAgZGF5MSA9IG5ldyBEYXRlKHRoaXMuY3VycmVudFllYXIsdGhpcy5jdXJyZW50TW9udGgsMSkuZ2V0RGF5KCksCiAgICAgICAgICAgICAgICBkYXRhLGRpc3BsYXk7CgogICAgICAgICAgICB0aGlzLnRhYnVsYXRlVmlldygKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXB0aW9uOiB0aGlzLm9wdGlvbnMubG9jYWxlLm1vbnRoc1t0aGlzLmN1cnJlbnRNb250aF0gKyAiLCAiKyB0aGlzLl9jb252ZXJ0TnVtYmVyVG9Mb2NhbGUodGhpcy5jdXJyZW50WWVhciksCiAgICAgICAgICAgICAgICAgICAgaGVhZGVyOnRoaXMub3B0aW9ucy5sb2NhbGUuZGF5cywKICAgICAgICAgICAgICAgICAgICBudW1Sb3dzOjcsCiAgICAgICAgICAgICAgICAgICAgbnVtQ29sdW1uczo3LAogICAgICAgICAgICAgICAgICAgIGVsZW1lbnRBdDogZnVuY3Rpb24ocm93LGNvbCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGF5ID0gKHJvdy0xKSo3ICsgY29sIC0gZGF5MSArIDE7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtb250aFZhbCA9IHNlbGYuY3VycmVudE1vbnRoICsgMTsKICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheSA9IHNlbGYuX2NvbnZlcnROdW1iZXJUb0xvY2FsZShkYXkpOwogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF5OwogICAgICAgICAgICAgICAgICAgICAgICBpZihkYXkgPCAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5ID0gc2VsZi5fY29udmVydE51bWJlclRvTG9jYWxlKHByZXZNYXhEYXkgKyBkYXkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IC0xOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9udGhWYWwgPSBzZWxmLmN1cnJlbnRNb250aDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKGRheSA+IG1heERheSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheSA9IHNlbGYuX2NvbnZlcnROdW1iZXJUb0xvY2FsZShkYXktbWF4RGF5KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSAtMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vbnRoVmFsID0gc2VsZi5jdXJyZW50TW9udGggKyAyOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyRGF0ZS5zZXREYXRlKGRheSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29tcGFyZUZuID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLl9jb21wYXJlVmFsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgdGhlIGN1cnJlbnRkYXRlIGlzIHZhbGlkIGJhc2VkIG9uIG1heCBhbmQgbWluIHZhbGlkIGRhdGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNvbXBhcmVGbihjdXJEYXRlLCBzZWxmLm1heFZhbGlkRGF0ZSwgc2VsZi5leGNsTWF4RGF0ZSkgfHwgY29tcGFyZUZuKHNlbGYubWluVmFsaWREYXRlLCBjdXJEYXRlLCBzZWxmLmV4Y2xNaW5EYXRlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSAtMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA6IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5IDogZGlzcGxheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWFMYWJlbCA6IHNlbGYub3B0aW9ucy5lZGl0VmFsdWUoc2VsZi5jdXJyZW50WWVhcisiLSIrc2VsZi5fcGFkMihtb250aFZhbCkrIi0iK3NlbGYuX3BhZDIoZGlzcGxheSkpCiAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgfSwKCgoKICAgICAgICAvKgogICAgICAgICAqIHNob3cgdGhlIHllYXIgdmlldwogICAgICAgICAqLwogICAgICAgIHNob3dZZWFyOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgbWluRGF0ZSA9IHRoaXMubWluVmFsaWREYXRlID8gbmV3IERhdGUodGhpcy5taW5WYWxpZERhdGUuZ2V0RnVsbFllYXIoKSwgdGhpcy5taW5WYWxpZERhdGUuZ2V0TW9udGgoKSkgOiBudWxsLAogICAgICAgICAgICAgICAgbWF4RGF0ZSA9IHRoaXMubWF4VmFsaWREYXRlID8gbmV3IERhdGUodGhpcy5tYXhWYWxpZERhdGUuZ2V0RnVsbFllYXIoKSwgdGhpcy5tYXhWYWxpZERhdGUuZ2V0TW9udGgoKSkgOiBudWxsLAogICAgICAgICAgICAgICAgY3VyRGF0ZSA9IG5ldyBEYXRlKHRoaXMuY3VycmVudFllYXIsIDApLCAvL2Nhbid0IG9taXQgbW9udGgsIGlmIG9ubHkgb25lIHBhcmFtIHByZXNlbnQgaXQgaXMgdHJlYXRlZCBhcyBtaWxsaXNlY29uZAogICAgICAgICAgICAgICAgZGF0YSwKICAgICAgICAgICAgICAgIG1vbnRoOwogICAgICAgICAgICB0aGlzLnRhYnVsYXRlVmlldygKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXB0aW9uIDogdGhpcy5fY29udmVydE51bWJlclRvTG9jYWxlKHRoaXMuY3VycmVudFllYXIpLAogICAgICAgICAgICAgICAgICAgIG51bVJvd3MgOiA0LAogICAgICAgICAgICAgICAgICAgIG51bUNvbHVtbnMgOiAzLAogICAgICAgICAgICAgICAgICAgIGVsZW1lbnRBdCA6IGZ1bmN0aW9uKHJvdyxjb2wpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IG1vbnRoID0gIHJvdyozICsgY29sOwogICAgICAgICAgICAgICAgICAgICAgICBjdXJEYXRlLnNldE1vbnRoKG1vbnRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChtaW5EYXRlICYmIGN1ckRhdGUgPCBtaW5EYXRlKSB8fCAobWF4RGF0ZSAmJiBjdXJEYXRlID4gbWF4RGF0ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSAtMTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA6IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5IDogc2VsZi5vcHRpb25zLmxvY2FsZS5tb250aHNbbW9udGhdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYUxhYmVsIDogc2VsZi5vcHRpb25zLmxvY2FsZS5tb250aHNbbW9udGhdICsgIiAiICtzZWxmLmN1cnJlbnRZZWFyCiAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBzaG93IHRoZSB5ZWFyIHNldCB2aWV3CiAgICAgICAgICovCiAgICAgICAgc2hvd1llYXJzZXQ6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgeWVhciwKICAgICAgICAgICAgICAgIG1pbkRhdGUgPSB0aGlzLm1pblZhbGlkRGF0ZSA/IG5ldyBEYXRlKHRoaXMubWluVmFsaWREYXRlLmdldEZ1bGxZZWFyKCksIDApIDogbnVsbCAsCiAgICAgICAgICAgICAgICBtYXhEYXRlID0gdGhpcy5tYXhWYWxpZERhdGUgPyBuZXcgRGF0ZSh0aGlzLm1heFZhbGlkRGF0ZS5nZXRGdWxsWWVhcigpICsgMSwgMCkgOiBudWxsLAogICAgICAgICAgICAgICAgY3VyRGF0ZSA9IG5ldyBEYXRlKCksCiAgICAgICAgICAgICAgICBkYXRhLAogICAgICAgICAgICAgICAgc2VsZiA9IHRoaXM7CiAgICAgICAgICAgIHRoaXMudGFidWxhdGVWaWV3KAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNhcHRpb246IHRoaXMuX2NvbnZlcnROdW1iZXJUb0xvY2FsZSh0aGlzLmN1cnJlbnRZZWFyIC0gdGhpcy5vcHRpb25zLnllYXJzUGVyVmlldy8yKSArIi0iK3RoaXMuX2NvbnZlcnROdW1iZXJUb0xvY2FsZSh0aGlzLmN1cnJlbnRZZWFyIC0gdGhpcy5vcHRpb25zLnllYXJzUGVyVmlldy8yICsgdGhpcy5vcHRpb25zLnllYXJzUGVyVmlldyAtIDEpLAogICAgICAgICAgICAgICAgICAgIG51bVJvd3M6NCwKICAgICAgICAgICAgICAgICAgICBudW1Db2x1bW5zOjQsCiAgICAgICAgICAgICAgICAgICAgZWxlbWVudEF0OiBmdW5jdGlvbihyb3csY29sKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSB5ZWFyID0gIHNlbGYuY3VycmVudFllYXIgLSA4ICsgKHJvdyo0ICsgY29sKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3VyRGF0ZS5zZXRGdWxsWWVhcih5ZWFyKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChtaW5EYXRlICYmIGN1ckRhdGUgPCBtaW5EYXRlKSB8fCAobWF4RGF0ZSAmJiBjdXJEYXRlID4gbWF4RGF0ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSAtMTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgImRhdGEiIDogZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkaXNwbGF5IiA6IHNlbGYuX2NvbnZlcnROdW1iZXJUb0xvY2FsZSh5ZWFyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWFMYWJlbCA6IHllYXIKICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICB9LAoKICAgICAgICBpbnNlcnRSb3cgOiAgZnVuY3Rpb24ocm93TnVtLHJvd0FycmF5LGlzSGVhZGVyLGhlaWdodCkgewogICAgICAgICAgICB2YXIgJHZpZXcgPSB0aGlzWyIkIit0aGlzLnZpZXcudG9Mb3dlckNhc2UoKV0sCiAgICAgICAgICAgICAgICB3aWR0aCA9ICh0aGlzLmFjdHVhbFdpZHRoKS9yb3dBcnJheS5sZW5ndGgsCiAgICAgICAgICAgICAgICAkcm93ID0gJCgidWwiLCR2aWV3KS5lcShyb3dOdW0pLAogICAgICAgICAgICAgICAgaXRlbXMsJGxpLGVsZW1lbnQsJHRtcCwKICAgICAgICAgICAgICAgIHNlbGY9IHRoaXM7CiAgICAgICAgICAgIGlmKCEkcm93Lmxlbmd0aCkKICAgICAgICAgICAgICAgICRyb3cgPSAkKCI8dWw+PC91bD4iKS5hdHRyKCJhcmlhLWxhYmVsIiwgIiIpLmF0dHIoInJvbGUiLCAicm93IikuYXBwZW5kVG8oJHZpZXcpLnRvZ2dsZUNsYXNzKGhlYWRlckNsYXNzLGlzSGVhZGVyKTsKICAgICAgICAgICAgJHJvdy5oZWlnaHQoaGVpZ2h0KTsKICAgICAgICAgICAgaXRlbXMgPSAkKCJsaSIsJHJvdykubGVuZ3RoOwogICAgICAgICAgICB3aGlsZShpdGVtcysrIDwgcm93QXJyYXkubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAkdG1wID0gJCgiPGxpPjwvbGk+IikuYXR0cigicm9sZSIsICJjZWxsIikuYXBwZW5kVG8oJHJvdyk7CiAgICAgICAgICAgICAgICBpZighaXNIZWFkZXIpCiAgICAgICAgICAgICAgICAgICAgJHRtcC5vbigiY2xpY2siLCAkLnByb3h5KHRoaXMuX3NlbGVjdERhdGUsdGhpcykpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBfLmVhY2gocm93QXJyYXksIGZ1bmN0aW9uKGVsLGluZGV4KSB7CiAgICAgICAgICAgICAgICAkbGkgPSAkKCJsaSIsJHJvdykuZXEoaW5kZXgpOwogICAgICAgICAgICAgICAgaWYoaXNIZWFkZXIpCiAgICAgICAgICAgICAgICAgICAgJGxpLnRleHQocm93QXJyYXlbaW5kZXhdKTsKICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSByb3dBcnJheVtpbmRleF07CiAgICAgICAgICAgICAgICAgICAgeGZhVXRpbC4kZGF0YSgkbGkuZ2V0KDApLCAidmFsdWUiLCBlbGVtZW50LmRhdGEpOwogICAgICAgICAgICAgICAgICAgIGlmKHNlbGYuX2NoZWNrRGF0ZUlzRm9jdXNzZWQoZWxlbWVudC5kYXRhKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZihzZWxmLiRmb2N1c2VkRGF0ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi4kZm9jdXNlZERhdGUucmVtb3ZlQ2xhc3MoImRwLWZvY3VzIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLiRmb2N1c2VkRGF0ZS5hdHRyKCJ0YWJpbmRleCIsICItMSIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuJGZvY3VzZWREYXRlID0gJGxpOwogICAgICAgICAgICAgICAgICAgICAgICBpZihzZWxmLl9rZXlzRW5hYmxlZCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuJGZvY3VzZWREYXRlLmFkZENsYXNzKCJkcC1mb2N1cyIpCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICRsaS50b2dnbGVDbGFzcygiZHAtc2VsZWN0ZWQiLHNlbGYuX2NoZWNrRGF0ZUlzU2VsZWN0ZWQoZWxlbWVudC5kYXRhKSkKICAgICAgICAgICAgICAgICAgICAgICAgLnRvZ2dsZUNsYXNzKCJkaXNhYmxlZCIsIGVsZW1lbnQuZGF0YSA9PSAtMSkudGV4dChlbGVtZW50LmRpc3BsYXkpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJ0aXRsZSIsIGVsZW1lbnQuYXJpYUxhYmVsKQogICAgICAgICAgICAgICAgICAgICAgICAuYXR0cigiYXJpYS1sYWJlbCIsIGVsZW1lbnQuYXJpYUxhYmVsKQogICAgICAgICAgICAgICAgICAgICAgICAuYXR0cigidGFiaW5kZXgiLCAtMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkbGkuY3NzKCB7ImhlaWdodCI6aGVpZ2h0KyJweCIsIndpZHRoIjp3aWR0aCsicHgiLCJsaW5lLWhlaWdodCI6aGVpZ2h0KyJweCJ9KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHJldHVybiAkcm93OwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogY3JlYXRlcyBhIHRhYnVsYXIgdmlldyBiYXNlZCBvbiB0aGUgb3B0aW9ucyBwcm92aWRlZC4gVGhlIG9wdGlvbnMgdGhhdCBjYW4gYmUgcGFzc2VkIGFyZQogICAgICAgICAqIG51bVJvd3M6IG51bWJlciBvZiByb3dzIHRoYXQgbmVlZHMgcmVuZGVyaW5nCiAgICAgICAgICogbnVtQ29sczogbnVtYmVyIG9mIGNvbHVtbnMgdGhhdCBuZWVkcyByZW5kZXJpbmcKICAgICAgICAgKiBjYXB0aW9uOiB0ZXh0IGZvciB0aGUgZGF0ZXBpY2tlcnMgY2FwdGlvbiBlbGVtZW50CiAgICAgICAgICogaGVhZGVyOiBhbiBhcnJheSBvZiBlbGVtZW50cyB0aGF0IGlkZW50aWZpZXMgdGhlIGhlYWRlciByb3cKICAgICAgICAgKiBlbGVtZW50QXQ6IGEgZnVuY3Rpb24ocm93LCBjb2x1bW4pIHRoYXQgcmV0dXJucyBhbiBvYmplY3QgKGRhdGE6IDxkYXRhPiwgZGlzcGxheTogPGRpc3BsYXk+KSB3aGVyZQogICAgICAgICAqICAgICAgICAgICAgPGRhdGE+IGlzIHRoZSB2YWx1ZSB0byBzZXQgZm9yIHRoYXQgdmlldyB3aGVuIHRoZSBlbGVtZW50IGF0IChyb3csY29sdW1uKSBpcyBjbGlja2VkIGFuZAogICAgICAgICAqICAgICAgICAgICAgPGRpc3BsYXk+IGlzIHRoZSB2YWx1ZSB0aGF0IHdpbGwgYmUgdmlzaWJsZSB0byB0aGUgdXNlcgogICAgICAgICAqLwogICAgICAgIHRhYnVsYXRlVmlldyA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgdmFyIHIgPSAwLHJvd3MgPSAwLAogICAgICAgICAgICAgICAgcm93ID0gW10sCiAgICAgICAgICAgICAgICBodCA9ICB0aGlzLm9wdGlvbnMudmlld0hlaWdodC9vcHRpb25zLm51bVJvd3MsCiAgICAgICAgICAgICAgICBjOwogICAgICAgICAgICB0aGlzLiRjYXB0aW9uLnRleHQob3B0aW9ucy5jYXB0aW9uKTsKICAgICAgICAgICAgaWYob3B0aW9ucy5oZWFkZXIpIHsKICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0Um93KHIrKyxvcHRpb25zLmhlYWRlcix0cnVlLGh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICB3aGlsZShyIDwgb3B0aW9ucy5udW1Sb3dzKSB7CiAgICAgICAgICAgICAgICBjID0gMDsKICAgICAgICAgICAgICAgIHdoaWxlKGMgPCBvcHRpb25zLm51bUNvbHVtbnMpIHsKICAgICAgICAgICAgICAgICAgICByb3dbY10gPSBvcHRpb25zLmVsZW1lbnRBdChyLGMpOwogICAgICAgICAgICAgICAgICAgIGMrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0Um93KHIrKyxyb3csZmFsc2UsaHQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2FjdGl2YXRlRmllbGQgOiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlID0geGZhVXRpbC4kZGF0YShldm50LnRhcmdldCwiZGF0ZXRpbWVwaWNrZXIiKTsKICAgICAgICAgICAgdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLnRyaWdnZXIoIm9uZm9jdXMxLmRhdGV0aW1lcGlja2VyIikuYWRkQ2xhc3MoImRhdGVQaWNrZXJUYXJnZXQiKTsKICAgICAgICAgICAgLy8gSXNzdWUgTEMtNzA0OToKICAgICAgICAgICAgLy8gZGF0ZXBpY2tlclRhcmdldCBzaG91bGQgYmUgYWRkZWQgd2hlbiBhY3RpdmF0ZSB0aGUgZmllbGQgYW5kIHNob3VsZCBiZSByZW1vdmVkCiAgICAgICAgICAgIC8vIGFmdGVyIHRoZSBmaWVsZHMgZ2V0cyBkZWFjdGl2YXRlZC4KICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaG93Q2FsZW5kYXJJY29uKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQucGFyZW50KCkuYWRkQ2xhc3MoImRhdGVQaWNrZXJUYXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL2VuYWJsZSBob3Qga2V5cyBvbmx5IGZvciBub24gdG91Y2ggZGV2aWNlcwogICAgICAgICAgICBpZighdGhpcy50b3VjaFN1cHBvcnRlZCAmJiAhdGhpcy5fa2V5c0VuYWJsZWQpIHsKICAgICAgICAgICAgICAgICQod2luZG93KS5vbigia2V5ZG93bi5kYXRldGltZXBpY2tlciIsICQucHJveHkodGhpcy5faG90S2V5cyx0aGlzKSk7CiAgICAgICAgICAgICAgICB0aGlzLl9rZXlzRW5hYmxlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZGVhY3RpdmF0ZUZpZWxkOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYodGhpcy5fY3VySW5zdGFuY2UpIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMuX2tleXNFbmFibGVkKSB7CiAgICAgICAgICAgICAgICAgICAgJCh3aW5kb3cpLm9mZigia2V5ZG93bi5kYXRldGltZXBpY2tlciIpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5c0VuYWJsZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vQnVnIzM2MDc0OTk6IG9uIGRlYWN0aXZhdGUgY2hlY2sgdGhlIHZhbHVlIGluIHRoZSBpbnB1dCBib3gsIGlmIHRoYXQgaXMKICAgICAgICAgICAgICAgIC8vIGRpZmZlcmVudCB0aGFuIHRoZSBzZWxlY3RlZCBEYXRlLCBjaGFuZ2UgdGhlIHNlbGVjdGVkRGF0ZQogICAgICAgICAgICAgICAgLy9pZiAodGhpcy5fY3VySW5zdGFuY2Uuc2VsZWN0ZWREYXRlICE9IHRoaXMuX2N1ckluc3RhbmNlLiRmaWVsZC52YWwoKSkgewogICAgICAgICAgICAgICAgLy8gICAgdGhpcy5fY3VySW5zdGFuY2Uuc2VsZWN0ZWREYXRlID0gdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLnZhbCgpOwogICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQudHJpZ2dlcigib25mb2N1c291dC5kYXRldGltZXBpY2tlciIpLnJlbW92ZUNsYXNzKCJkYXRlUGlja2VyVGFyZ2V0Iik7CiAgICAgICAgICAgICAgICAvLyBJc3N1ZSBMQy03MDQ5OgogICAgICAgICAgICAgICAgLy8gZGF0ZXBpY2tlclRhcmdldCBzaG91bGQgYmUgYWRkZWQgd2hlbiBhY3RpdmF0ZSB0aGUgZmllbGQgYW5kIHNob3VsZCBiZSByZW1vdmVkCiAgICAgICAgICAgICAgICAvLyBhZnRlciB0aGUgZmllbGRzIGdldHMgZGVhY3RpdmF0ZWQuIE90aGVyd2lzZSBjbGlja2luZyBvbiBhbnkgb3RoZXIgZGF0ZWZpZWxkCiAgICAgICAgICAgICAgICAvLyB3aWxsIG5vdCBoaWRlIHRoZSBleGlzdGluZyBkYXRlcGlja2VyCiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnNob3dDYWxlbmRhckljb24pIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQucGFyZW50KCkucmVtb3ZlQ2xhc3MoImRhdGVQaWNrZXJUYXJnZXQiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9oaWRlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYodGhpcy5fdmlzaWJsZSkgewogICAgICAgICAgICAgICAgdGhpcy4kZHAuaGlkZSgpOwogICAgICAgICAgICAgICAgdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLnRyaWdnZXIoIm9uY2xvc2UuZGF0ZXRpbWVwaWNrZXIiKTsKICAgICAgICAgICAgICAgIHRoaXMuX3Zpc2libGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbikgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlLiRmaWVsZC5hdHRyKCdyZWFkb25seScsIGZhbHNlKTsgICAgLy8gd2hlbiB0aGUgZGF0ZXBpY2tlciBpcyBkZWFjdGl2YXRlZCwgYWN0aXZhdGUgdGhlIGZpZWxkCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfYWRqdXN0RGF0ZTogZnVuY3Rpb24oc3RlcCwgdmlldywgZm9jdXMpIHsKICAgICAgICAgICAgdmFyIG1heERhdGUscHJldk1heERhdGU7CiAgICAgICAgICAgIHZhciBfZm9jdXMgPSBmb2N1cyB8fCBmYWxzZTsKICAgICAgICAgICAgc3dpdGNoKHZpZXcudG9Mb3dlckNhc2UoKSkgewogICAgICAgICAgICAgICAgY2FzZSAiZGF5IjoKICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnREYXkgKz0gc3RlcDsKICAgICAgICAgICAgICAgICAgICBtYXhEYXRlID0gdGhpcy5fbWF4RGF0ZSh0aGlzLmN1cnJlbnRNb250aCkKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmN1cnJlbnREYXkgPCAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHByZXZNYXhEYXRlID0gIHRoaXMuX21heERhdGUoKHRoaXMuY3VycmVudE1vbnRoIC0gMSArIDEyKSUxMik7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudERheSA9IHByZXZNYXhEYXRlICsgdGhpcy5jdXJyZW50RGF5OwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYWRqdXN0RGF0ZSgtMSwgIm1vbnRoIiwgX2ZvY3VzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5jdXJyZW50RGF5ID4gbWF4RGF0ZSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnREYXkgLT0gbWF4RGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2FkanVzdERhdGUoKzEsICJtb250aCIsIF9mb2N1cyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAibW9udGgiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudE1vbnRoICs9IHN0ZXA7CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5jdXJyZW50TW9udGggPiAxMSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRZZWFyKys7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudE1vbnRoID0gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5jdXJyZW50TW9udGggPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFllYXItLTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50TW9udGggPSAxMTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJ5ZWFyIjoKICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRZZWFyICs9IHN0ZXA7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJ5ZWFyc2V0IjoKICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRZZWFyICs9IHN0ZXAqdGhpcy5vcHRpb25zLnllYXJzUGVyVmlldzsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl9sYXlvdXQodGhpcy52aWV3KTsKICAgICAgICAgICAgaWYgKF9mb2N1cykgewogICAgICAgICAgICAgICAgdGhpcy5mb2N1c2VkT25EYXRlcGlja2VySXRlbSA9IHRydWU7CiAgICAgICAgICAgICAgICB0aGlzLiRmb2N1c2VkRGF0ZS5hdHRyKCJ0YWJpbmRleCIsIDApWzBdLmZvY3VzKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfY2hlY2tEYXRlSXNTZWxlY3RlZDogZnVuY3Rpb24oZGF0YSkgewogICAgICAgICAgICBzd2l0Y2godGhpcy52aWV3LnRvTG93ZXJDYXNlKCkpIHsKICAgICAgICAgICAgICAgIGNhc2UgIm1vbnRoIjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50WWVhciA9PSB0aGlzLnNlbGVjdGVkWWVhciAmJiB0aGlzLmN1cnJlbnRNb250aCA9PSB0aGlzLnNlbGVjdGVkTW9udGggJiYgZGF0YSA9PSB0aGlzLnNlbGVjdGVkRGF5OwogICAgICAgICAgICAgICAgY2FzZSAieWVhciI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFllYXIgPT0gdGhpcy5zZWxlY3RlZFllYXIgJiYgdGhpcy5zZWxlY3RlZE1vbnRoID09IGRhdGE7CiAgICAgICAgICAgICAgICBjYXNlICJ5ZWFyc2V0IjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3RlZFllYXIgPT0gZGF0YTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jaGVja0RhdGVJc0ZvY3Vzc2VkOiBmdW5jdGlvbihkYXRhKSB7CiAgICAgICAgICAgIHN3aXRjaCh0aGlzLnZpZXcudG9Mb3dlckNhc2UoKSkgewogICAgICAgICAgICAgICAgY2FzZSAibW9udGgiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRhID09IHRoaXMuY3VycmVudERheTsKICAgICAgICAgICAgICAgIGNhc2UgInllYXIiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRNb250aCA9PSBkYXRhOwogICAgICAgICAgICAgICAgY2FzZSAieWVhcnNldCI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudFllYXIgPT0gZGF0YTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jb252ZXJ0TnVtYmVyVG9Mb2NhbGUgOiBmdW5jdGlvbihudW1iZXIpIHsKICAgICAgICAgICAgdmFyIHplcm9Db2RlID0gdGhpcy5vcHRpb25zLmxvY2FsZS56ZXJvLmNoYXJDb2RlQXQoMCk7CiAgICAgICAgICAgIG51bWJlciArPSAiIjsKICAgICAgICAgICAgdmFyIG5ld051bWJlciA9IFtdOwogICAgICAgICAgICBmb3IodmFyIGkgPSAwO2kgPCBudW1iZXIubGVuZ3RoO2krKykgewogICAgICAgICAgICAgICAgbmV3TnVtYmVyLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZSh6ZXJvQ29kZSArIHBhcnNlSW50KG51bWJlci5jaGFyQXQoaSkpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5ld051bWJlci5qb2luKCIiKTsKICAgICAgICB9LAoKICAgICAgICBfY2xlYXJEYXRlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIGlzRGF0ZUVtcHR5ID0gdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLnZhbCgpID8gZmFsc2UgOiB0cnVlOwogICAgICAgICAgICB0aGlzLnNlbGVjdGVkWWVhcgogICAgICAgICAgICAgICAgPSB0aGlzLnNlbGVjdGVkTW9udGgKICAgICAgICAgICAgICAgID0gdGhpcy5zZWxlY3RlZFllYXIKICAgICAgICAgICAgICAgID0gLTE7CiAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlLnNlbGVjdGVkRGF0ZSA9ICIiOwogICAgICAgICAgICB0aGlzLl9jdXJJbnN0YW5jZS4kZmllbGQudmFsKCIiKTsKICAgICAgICAgICAgaWYgKCFpc0RhdGVFbXB0eSkgewogICAgICAgICAgICAgICAgdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLnRyaWdnZXIoIm9udmFsdWVjaGFuZ2UuZGF0ZXRpbWVwaWNrZXIiLCBbCiAgICAgICAgICAgICAgICAgICAge3NlbGVjdGVkRGF0ZTogIiJ9CiAgICAgICAgICAgICAgICBdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkKCIuZHAtc2VsZWN0ZWQiLHRoaXNbJyQnK3RoaXMudmlldy50b0xvd2VyQ2FzZSgpXSkucmVtb3ZlQ2xhc3MoImRwLXNlbGVjdGVkIik7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RXZlbnQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuICJjbGljayI7Ly90aGlzLnRvdWNoU3VwcG9ydGVkID8gInRvdWNoc3RhcnQiIDogImNsaWNrIjsKICAgICAgICB9LAoKICAgICAgICBfcGFkMjogZnVuY3Rpb24obSkgewogICAgICAgICAgICByZXR1cm4gbSA9IG0gPCAxMCA/IjAiK206bTsKICAgICAgICB9LAoKICAgICAgICB0b1N0cmluZyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3RlZFllYXIgKyItIit0aGlzLl9wYWQyKHRoaXMuc2VsZWN0ZWRNb250aCArIDEpKyItIit0aGlzLl9wYWQyKHRoaXMuc2VsZWN0ZWREYXkpOwogICAgICAgIH0sCgogICAgICAgIF9zZWxlY3REYXRlIDogZnVuY3Rpb24oZXZudCkgewogICAgICAgICAgICB2YXIgdmFsID0geGZhVXRpbC4kZGF0YShldm50LnRhcmdldCwgInZhbHVlIiksCiAgICAgICAgICAgICAgICBuZXh0VmlldyA9IHZpZXdBY3Rpb25bdGhpcy52aWV3XS5saSwKICAgICAgICAgICAgICAgIGVkaXRWYWw7CiAgICAgICAgICAgIC8vZGlzYWJsZWQgZGF0ZXMgaGF2ZSBhIHZhbHVlIG9mIC0xLiBEbyBub3RoaW5nIGluIHRoYXQgY2FzZQogICAgICAgICAgICBpZih2YWwgPT0gLTEpCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIHN3aXRjaCh0aGlzLnZpZXcudG9Mb3dlckNhc2UoKSkgewogICAgICAgICAgICAgICAgY2FzZSAibW9udGgiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRNb250aCA9IHRoaXMuY3VycmVudE1vbnRoOwogICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRZZWFyID0gdGhpcy5jdXJyZW50WWVhcjsKICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkRGF5ID0gdmFsOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlLnNlbGVjdGVkRGF0ZSA9IHRoaXMudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgICAgICBlZGl0VmFsID0gdGhpcy5fY3VySW5zdGFuY2UuZWRpdFZhbHVlKHRoaXMudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY3VySW5zdGFuY2UuJGZpZWxkLnZhbChlZGl0VmFsKS5mb2N1cygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2N1ckluc3RhbmNlLiRmaWVsZC50cmlnZ2VyKCJvbnZhbHVlY2hhbmdlLmRhdGV0aW1lcGlja2VyIiwgWwogICAgICAgICAgICAgICAgICAgICAgICB7c2VsZWN0ZWREYXRlOiBlZGl0VmFsfQogICAgICAgICAgICAgICAgICAgIF0pOwogICAgICAgICAgICAgICAgICAgICQoIi5kcC1zZWxlY3RlZCIsdGhpc1snJCcrdGhpcy52aWV3LnRvTG93ZXJDYXNlKCldKS5yZW1vdmVDbGFzcygiZHAtc2VsZWN0ZWQiKTsKICAgICAgICAgICAgICAgICAgICAkKGV2bnQudGFyZ2V0KS5hZGRDbGFzcygiZHAtc2VsZWN0ZWQiKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInllYXIiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudE1vbnRoID0gdmFsOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAieWVhcnNldCI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50WWVhciA9IHZhbDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl9sYXlvdXQobmV4dFZpZXcpOwogICAgICAgICAgICAvL21hbnVhbGx5IGZvY3VzIG9uIHRoZSBmaWVsZCBpZiBjbGlja2VkIG9uIHRoZSBwb3B1cCBidXR0b25zIGZvciBub24tdG91Y2ggZGV2aWNlCiAgICAgICAgICAgIGlmKCF0aGlzLnRvdWNoU3VwcG9ydGVkKSB7CiAgICAgICAgICAgICAgICAvL05vIG5lZWQgdG8gZm9jdXMgaWYgc2VsZWN0aW9uIGlzIG1hZGUgYnkgcHJlc3Npbmcgc3BhY2UuCiAgICAgICAgICAgICAgICBpZighdGhpcy5ob3RLZXlQcmVzc2VkKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zY3JpcHRGb2N1cyA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgaWYobmV4dFZpZXcgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYobmV4dFZpZXcgPT0gbnVsbCl7CiAgICAgICAgICAgICAgICAvL0ZvciB0b3VjaCBkZXZpY2VzLCBkZWFjdGl2YXRlIHRoZSBmaWVsZCBpZiBhIHNlbGVjdGlvbiBpcyBtYWRlCiAgICAgICAgICAgICAgICB0aGlzLmZvY3VzZWRPbkRhdGVwaWNrZXJJdGVtID0gZmFsc2U7CiAgICAgICAgICAgICAgICB0aGlzLl9kZWFjdGl2YXRlRmllbGQoKQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2xlYXBZZWFyIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRZZWFyICUgNDAwID09IDAgfHwgKHRoaXMuY3VycmVudFllYXIgJSAxMDAgIT0gMCAmJiB0aGlzLmN1cnJlbnRZZWFyICUgNCA9PSAwKTsKICAgICAgICB9LAoKICAgICAgICBfbWF4RGF0ZSA6IGZ1bmN0aW9uKG0pIHsKICAgICAgICAgICAgaWYodGhpcy5fbGVhcFllYXIoKSAmJiBtID09IDEpCiAgICAgICAgICAgICAgICByZXR1cm4gMjk7CiAgICAgICAgICAgIGVsc2UgcmV0dXJuIGRhdGVzW21dOwogICAgICAgIH0sCgogICAgICAgIF9hY2Nlc3M6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICBpZih0eXBlb2YgdmFsID09ICJ1bmRlZmluZWQiKQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWNjZXNzCiAgICAgICAgICAgIHRoaXMuYWNjZXNzID0gdmFsOwogICAgICAgIH0sCgogICAgICAgIF92YWx1ZTpmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgaWYodHlwZW9mIHZhbCA9PSAidW5kZWZpbmVkIikKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLiRmaWVsZC52YWwoKQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gdmFsOwogICAgICAgICAgICAgICAgdmFyIGVkaXRWYWx1ZSA9IHRoaXMuZWRpdFZhbHVlKHZhbCk7CiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgdGhlIGZpZWxkIHZhbCB3aXRoIHByb3ZpZGVkIHZhbHVlIGluc3RlYWQgb2YgbnVsbAogICAgICAgICAgICAgICAgaWYgKCFlZGl0VmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICBlZGl0VmFsdWUgPSB2YWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLiRmaWVsZC52YWwoZWRpdFZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKICAgIHZhciBhZG9iZURhdGVUaW1lUGlja2VyID0gbmV3IERhdGVUaW1lUGlja2VyKCk7CgogICAgJC5mbi5hZG9iZURhdGVUaW1lUGlja2VyID0gZnVuY3Rpb24ob3B0aW9ucywgdmFsdWUpIHsKICAgICAgICBpZighYWRvYmVEYXRlVGltZVBpY2tlci5pbml0aWFsaXplZCkgewogICAgICAgICAgICBhZG9iZURhdGVUaW1lUGlja2VyLmNyZWF0ZShvcHRpb25zKTsKICAgICAgICAgICAgYWRvYmVEYXRlVGltZVBpY2tlci5pbml0aWFsaXplZCA9IHRydWU7CiAgICAgICAgfQogICAgICAgIGlmKHR5cGVvZiBvcHRpb25zID09PSAib2JqZWN0IikgewogICAgICAgICAgICBhZG9iZURhdGVUaW1lUGlja2VyLl9hdHRhY2hGaWVsZCh0aGlzLCBvcHRpb25zKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gInN0cmluZyIpIHsKICAgICAgICAgICAgaWYoYXJndW1lbnRzLmxlbmd0aCA9PSAyKQogICAgICAgICAgICAgICAgYWRvYmVEYXRlVGltZVBpY2tlclsiXyIrb3B0aW9uc10uYXBwbHkoeGZhVXRpbC4kZGF0YSh0aGlzWzBdLCJkYXRldGltZXBpY2tlciIpLFt2YWx1ZV0pCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBhZG9iZURhdGVUaW1lUGlja2VyWyJfIitvcHRpb25zXS5hcHBseSh4ZmFVdGlsLiRkYXRhKHRoaXNbMF0sImRhdGV0aW1lcGlja2VyIikpCiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgfQp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24gKHhmYWxpYikgewogICAgeGZhbGliLnV0LlRvdWNoVXRpbCA9IChmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIHRvdWNoQXZhaWxhYmxlID0gISEoIm9udG91Y2hzdGFydCIgaW4gd2luZG93IHx8IHdpbmRvdy5Eb2N1bWVudFRvdWNoICYmIGRvY3VtZW50IGluc3RhbmNlb2YgRG9jdW1lbnRUb3VjaCkgLAogICAgICAgICAgICBwb2ludGVyRW5hYmxlZCA9ICEhKHdpbmRvdy5NU1BvaW50ZXJFdmVudCB8fCB3aW5kb3cuUG9pbnRlckV2ZW50KSAsCiAgICAgICAgICAgIFBPSU5URVJfRE9XTl9FVkVOVCA9ICJtb3VzZWRvd24iLAogICAgICAgICAgICBQT0lOVEVSX01PVkVfRVZFTlQgPSAibW91c2Vtb3ZlIiwKICAgICAgICAgICAgUE9JTlRFUl9VUF9FVkVOVCA9ICJtb3VzZXVwIiwKICAgICAgICAgICAgRVZFTlRfVFlQRSA9ICJNb3VzZUV2ZW50IjsKCiAgICAgICAgaWYgKHdpbmRvdy5Qb2ludGVyRXZlbnQpIHsgLy8+IElFMTEKICAgICAgICAgICAgUE9JTlRFUl9ET1dOX0VWRU5UID0gInBvaW50ZXJkb3duIjsKICAgICAgICAgICAgUE9JTlRFUl9NT1ZFX0VWRU5UID0gInBvaW50ZXJtb3ZlIjsKICAgICAgICAgICAgUE9JTlRFUl9VUF9FVkVOVCA9ICJwb2ludGVydXAiOwogICAgICAgICAgICBFVkVOVF9UWVBFID0gIlBvaW50ZXJFdmVudCI7CgogICAgICAgIH0gZWxzZSBpZiAod2luZG93Lk1TUG9pbnRlckV2ZW50KSB7IC8vIElFMTAKICAgICAgICAgICAgUE9JTlRFUl9ET1dOX0VWRU5UID0gIk1TUG9pbnRlckRvd24iOwogICAgICAgICAgICBQT0lOVEVSX01PVkVfRVZFTlQgPSAiTVNQb2ludGVyTW92ZSI7CiAgICAgICAgICAgIFBPSU5URVJfVVBfRVZFTlQgPSAiTVNQb2ludGVyVXAiOwogICAgICAgICAgICBFVkVOVF9UWVBFID0gIk1TUG9pbnRlckV2ZW50IiA7CgogICAgICAgIH0gZWxzZSBpZiAodG91Y2hBdmFpbGFibGUpIHsgIC8vIG90aGVyIHRvdWNoIGRldmljZXMKICAgICAgICAgICAgUE9JTlRFUl9ET1dOX0VWRU5UID0gInRvdWNoc3RhcnQiOwogICAgICAgICAgICBQT0lOVEVSX01PVkVfRVZFTlQgPSAidG91Y2htb3ZlIjsKICAgICAgICAgICAgUE9JTlRFUl9VUF9FVkVOVCA9ICJ0b3VjaGVuZCI7CiAgICAgICAgICAgIEVWRU5UX1RZUEUgPSAiVG91Y2hFdmVudCI7CiAgICAgICAgfQogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIFRPVUNIX0VOQUJMRUQ6IHRvdWNoQXZhaWxhYmxlLAogICAgICAgICAgICAvLyBuZXcgTVMgUG9pbnRlciBFdmVudHMKICAgICAgICAgICAgUE9JTlRFUl9FVkVOVDogRVZFTlRfVFlQRSwKICAgICAgICAgICAgUE9JTlRFUl9FTkFCTEVEOiBwb2ludGVyRW5hYmxlZCwKICAgICAgICAgICAgUE9JTlRFUl9ET1dOOiBQT0lOVEVSX0RPV05fRVZFTlQsCiAgICAgICAgICAgIFBPSU5URVJfTU9WRTogUE9JTlRFUl9NT1ZFX0VWRU5ULAogICAgICAgICAgICBQT0lOVEVSX1VQOiBQT0lOVEVSX1VQX0VWRU5ULAogICAgICAgICAgICBnZXRUb3VjaEV2ZW50OiBmdW5jdGlvbiAoZXZ0KSB7CiAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0OwogICAgICAgICAgICAgICAgaWYgKHBvaW50ZXJFbmFibGVkKSB7CiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gZXZ0Lm9yaWdpbmFsRXZlbnQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRvdWNoQXZhaWxhYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gZXZ0Lm9yaWdpbmFsRXZlbnQgfHwgZXZ0OwogICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IHRhcmdldC50b3VjaGVzWzBdOwogICAgICAgICAgICAgICAgICAgIC8vaWYgKGV2dC5vcmlnaW5hbEV2ZW50ICYmIGV2dC5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzICYmIGV2dC5vcmlnaW5hbEV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gICAgdGUgPSBldnQub3JpZ2luYWxFdmVudC5jaGFuZ2VkVG91Y2hlc1swXTsKICAgICAgICAgICAgICAgICAgICAvL30KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0IHx8IGV2dDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZ2V0UG9pbnRlckV2ZW50OiBmdW5jdGlvbiAoZXZlbnRUeXBlKSB7CiAgICAgICAgICAgICAgICB2YXIgZXZlbnQgPSBudWxsOwogICAgICAgICAgICAgICAgaWYgKCh0eXBlb2YgUG9pbnRlckV2ZW50KSA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICAgICAgICAgIGV2ZW50ID0gbmV3IFBvaW50ZXJFdmVudChldmVudFR5cGUsIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnViYmxlczogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgY2FuY2VsYWJsZTogdHJ1ZQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KEVWRU5UX1RZUEUpOwogICAgICAgICAgICAgICAgICAgIGV2ZW50LmluaXRFdmVudChldmVudFR5cGUsIHRydWUsIHRydWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50OwogICAgICAgICAgICB9LAogICAgICAgICAgICBnZXRUb3VjaGVzOmZ1bmN0aW9uKGV2dCl7CiAgICAgICAgICAgICAgICB2YXIgdG91Y2hlcyA9IFtdOwogICAgICAgICAgICAgICAgaWYodG91Y2hBdmFpbGFibGUgJiYgZXZ0Lm9yaWdpbmFsRXZlbnQgJiYgZXZ0Lm9yaWdpbmFsRXZlbnQudG91Y2hlcyApewogICAgICAgICAgICAgICAgICAgIHRvdWNoZXMgPSBldnQub3JpZ2luYWxFdmVudC50b3VjaGVzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRvdWNoZXM7CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfSkoKTsKfSkoeGZhbGliKTsKKGZ1bmN0aW9uICgkLCBfKSB7CiAgICAkLndpZGdldCgieGZhV2lkZ2V0LmFic3RyYWN0V2lkZ2V0IiwgewoKICAgICAgICAkdXNlckNvbnRyb2w6IG51bGwsCgogICAgICAgICRkYXRhOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuJGRhdGEsCgogICAgICAgICRjc3M6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS4kY3NzLAoKICAgICAgICBnZXRPckVsc2U6IHhmYWxpYi51dC5DbGFzcy5wcm90b3R5cGUuZ2V0T3JFbHNlLAoKICAgICAgICBkSW5kZXhPZjogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmRJbmRleE9mLAoKICAgICAgICBidHduOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuYnR3biwKCiAgICAgICAgbG9nZ2VyOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0TG9nZ2VyLAoKICAgICAgICBsb2NhbGVTdHJpbmdzOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0TG9jYWxlU3RyaW5ncywKCiAgICAgICAgbG9nTXNnczogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmdldExvZ01lc3NhZ2VzLAoKICAgICAgICBlcnJvck1hbmFnZXI6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5nZXRFcnJvck1hbmFnZXIsCgogICAgICAgIF93aWRnZXROYW1lOiAiYWJzdHJhY3RXaWRnZXQiLAoKICAgICAgICAvLyBpZiB0aGVyZSBhcmUgYW55IHNwZWNpZmljIGJsYWNrIGxpc3RlZCBhdHRyaWJ1dGVzLCBlYWNoIHdpZGdldCBzaG91bGQgZGVmaW5lIHRoZWlyIG93bgogICAgICAgIF9ibGFja0xpc3RlZEF0dHJpYnV0ZXMgOiBbInR5cGUiXSwKCiAgICAgICAgb3B0aW9uczogewogICAgICAgICAgICBuYW1lOiAiIiwKICAgICAgICAgICAgdmFsdWU6IG51bGwsCiAgICAgICAgICAgIGNvbW1pdFByb3BlcnR5OiAidmFsdWUiLAogICAgICAgICAgICBkaXNwbGF5VmFsdWU6IG51bGwsCiAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHQ6IG51bGwsCiAgICAgICAgICAgIHRhYkluZGV4OiAwLAogICAgICAgICAgICByb2xlOiBudWxsLAogICAgICAgICAgICBwYXJhU3R5bGVzOiBudWxsLAogICAgICAgICAgICBkaXI6IG51bGwsCiAgICAgICAgICAgIGVycm9yTWVzc2FnZTogbnVsbCwKICAgICAgICAgICAgd2FybmluZ01lc3NhZ2U6IG51bGwsCiAgICAgICAgICAgIGhTY3JvbGxEaXNhYmxlZDogZmFsc2UsCiAgICAgICAgICAgIHBsYWNlaG9sZGVyOiIiLAogICAgICAgICAgICBpc1ZhbGlkOnRydWUsCiAgICAgICAgICAgIG1hbmRhdG9yeTogZmFsc2UKICAgICAgICB9LAoKICAgICAgICBnZXRPcHRpb25zTWFwOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAidGFiSW5kZXgiOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigidGFiaW5kZXgiLCB2YWwpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJyb2xlIjogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgIGlmICh2YWwpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoInJvbGUiLCB2YWwpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJzY3JlZW5SZWFkZXJUZXh0IjogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgIGlmICh2YWwpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImFyaWEtbGFiZWwiLCB2YWwpCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInBhcmFTdHlsZXMiOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuJHVzZXJDb250cm9sLmdldCgwKSwgdmFsKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZGlyIjogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgIGlmICh2YWwpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImRpciIsIHRoaXMub3B0aW9ucy5kaXIpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJoZWlnaHQiOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy4kdXNlckNvbnRyb2xbMF0sIHsiaGVpZ2h0IjogdmFsfSkKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIndpZHRoIjogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgIGlmICh2YWwpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLiR1c2VyQ29udHJvbFswXSwgeyJ3aWR0aCI6IHZhbH0pCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImlzVmFsaWQiOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYodmFsKXsKICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImFyaWEtaW52YWxpZCIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJhcmlhLWludmFsaWQiLHRydWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiY29sb3IiIDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICBpZighXy5pc0VtcHR5KHZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29sb3IgPSAicmdiKCIgKyB2YWx1ZSArICIpIjsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuJHVzZXJDb250cm9sWzBdLCB7ImNvbG9yIjogY29sb3J9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImZvbnQtc3R5bGUiIDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFfLmlzRW1wdHkodmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLiR1c2VyQ29udHJvbFswXSwgeyJmb250LXN0eWxlIjogdmFsdWV9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIm1hbmRhdG9yeSIgOiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICBpZih2YWx1ZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImFyaWEtcmVxdWlyZWQiLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJhcmlhLXJlcXVpcmVkIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIGdldEV2ZW50TWFwOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAiZm9jdXMiOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VOVEVSX0VWRU5ULAogICAgICAgICAgICAgICAgImJsdXIiOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VYSVRfRVZFTlQsCiAgICAgICAgICAgICAgICAiY2xpY2siOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NMSUNLX0VWRU5UCiAgICAgICAgICAgIH07CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQ29waWVzIGFsbCB0aGUgYXR0cmlidXRlcyBmcm9tIHNvdXJjZSBqcXVlcnkgb2JqZWN0IHRvIGRlc3RpbmF0aW9uIGpxdWVyeSBvYmplY3QKICAgICAgICAgKiBAcGFyYW0gJHNyYyAgICAgIHNvdXJjZSBqcXVlcnkgb2JqZWN0CiAgICAgICAgICogQHBhcmFtICRkZXN0ICAgICBkZXN0aW5hdGlvbiBqcXVlcnkgb2JqZWN0CiAgICAgICAgICovCiAgICAgICAgY29weUF0dHJpYnV0ZXNGcm9tU3JjVG9EZXN0IDogZnVuY3Rpb24oJHNyYywgJGRlc3QpewogICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgIC8vIGxldCdzIGdldCBhbGwgdGhlIGF0dHJpYnV0ZSBmcm9tIHRoZSBzcmMgZWxlbWVudCBhbmQgY29weSBpdCB0byBkZXN0IGpxdWVyeSBvYmplY3QKICAgICAgICAgICAgaWYoJHNyYyAhPSBudWxsICYmICRzcmNbMF0gJiYgJHNyY1swXS5hdHRyaWJ1dGVzICYmICRkZXN0ICE9IG51bGwpewogICAgICAgICAgICAgICAgJC5lYWNoKCRzcmNbMF0uYXR0cmlidXRlcywgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gd2UgZG9uJ3QgYWRkIHRoZSBibGFjayBsaXN0ZWQgc2V0IG9mIGF0dHJpYnV0ZXMKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLnNwZWNpZmllZCAmJiB0aGlzLnZhbHVlICE9IG51bGwgJiYgXy5pc1N0cmluZyh0aGlzLnZhbHVlKSAmJiB0aGlzLnZhbHVlLmxlbmd0aCA+IDAgJiYgdGhhdC5fYmxhY2tMaXN0ZWRBdHRyaWJ1dGVzLmluZGV4T2YodGhpcy5uYW1lKSA9PT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGRlc3QuYXR0cih0aGlzLm5hbWUsIHRoaXMudmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2NyZWF0ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLndpZGdldEV2ZW50UHJlZml4ID0gIiI7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5hZGRDbGFzcyh0aGlzLl93aWRnZXROYW1lKTsKICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wgPSB0aGlzLnJlbmRlcigpOwogICAgICAgICAgICB0aGlzLm9wdGlvbnNIYW5kbGVyID0gdGhpcy5nZXRPcHRpb25zTWFwKCk7CiAgICAgICAgICAgIHRoaXMuZXZlbnRNYXAgPSB0aGlzLmdldEV2ZW50TWFwKCk7CiAgICAgICAgICAgIHRoaXMuX2luaXRpYWxpemVPcHRpb25zKCk7CiAgICAgICAgICAgIHRoaXMuX2luaXRpYWxpemVFdmVudEhhbmRsZXJzKCk7CiAgICAgICAgICAgIHRoaXMuZXJyT2JqID0gdGhpcy5lcnJvck1hbmFnZXIoKTsKICAgICAgICAgICAgLy9jYWxsIGl0IG9ubHkgYWZ0ZXIgcmVuZGVyCiAgICAgICAgICAgIC8vIERpcnR5IGhhY2sgdG8gcHJldmVudCB0aGlzIGJlaW5nIGNhbGxlZCBpbiBHdWlkZQogICAgICAgICAgICBpZiAodHlwZW9mIGd1aWRlbGliID09PSAidW5kZWZpbmVkIikgewogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuJHVzZXJDb250cm9sLmdldCgwKSwgewogICAgICAgICAgICAgICAgICAgICJib3gtc2l6aW5nIjogImJvcmRlci1ib3giLAogICAgICAgICAgICAgICAgICAgICJwb3NpdGlvbiI6ICJhYnNvbHV0ZSIKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRpYWxpemVFdmVudEhhbmRsZXJzOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5nZXRMb2dnZXIoKS5kZWJ1ZygieGZhIiwgImluaXRpYWxpemUgZXZlbnQgaGFuZGxlcnMgZm9yICIgKyB0aGlzLl93aWRnZXROYW1lKTsKICAgICAgICAgICAgXy5lYWNoKHRoaXMuZXZlbnRNYXAsIGZ1bmN0aW9uICh4ZmFldmVudCwgaHRtbGV2ZW50KSB7CiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICAgICAgICAgICAgICBpZiAoeGZhZXZlbnQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoISh4ZmFldmVudCBpbnN0YW5jZW9mICBBcnJheSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeGZhZXZlbnQgPSBbeGZhZXZlbnRdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhmYWV2ZW50Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5nZXRMb2dnZXIoKS5kZWJ1ZygieGZhIiwgImJpbmRpbmcgIiArIGh0bWxldmVudCArICIgd2l0aCAiICsgeGZhZXZlbnRbaV0pOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5vbihodG1sZXZlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKHhmZXZudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0TG9nZ2VyKCkuZGVidWcoInhmYSIsICJ0cmlnZ2VyICIgKyBldm50LnR5cGUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIHhmYS1ldmVudCAiICsgeGZldm50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fcHJlUHJvY2Vzc0V2ZW50LmFwcGx5KHNlbGYsIFt4ZmV2bnQsIGV2bnRdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9zaW5jZSB0aGUgZml4IGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvanF1ZXJ5L3B1bGwvOTcyLCBGaXggZm9yIGtlZXBpbmcgbmFtZXNwYWNlIHdoZW4gdHJpZ2dlcmluZyBhbiBldmVudCB1c2luZyBhbiBFdmVudCAjOTcyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vd2UgbmVlZCB0byBjbGVhciB0aGUgbmFtZXNwYWNlIGFuZCBpdHMgcmVndWxhciBleHByZXNzaW9uIG9mIHRyaWdnZXJpbmcgZXZlbnQsIGFzIHRoZSBsaXN0ZW5lcnMgYXJlIHJlZ2lzdGVyZWQgb24gdW4tbmFtZXNwYWNlZCBldmVudHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZudC5uYW1lc3BhY2UgPSAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZudC5uYW1lc3BhY2VfcmUgPSAiIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fdHJpZ2dlcih4ZmV2bnQsIGV2bnQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9wb3N0UHJvY2Vzc0V2ZW50LmFwcGx5KHNlbGYsIFt4ZmV2bnQsIGV2bnRdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSh4ZmFldmVudFtpXSkKICAgICAgICAgICAgICAgICAgICAgICAgKQoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIHRoaXMpCiAgICAgICAgfSwKCiAgICAgICAgX3ByZVByb2Nlc3NFdmVudDogZnVuY3Rpb24gKHhmYWV2ZW50LCBodG1sZXZlbnQpIHsKICAgICAgICAgICAgaWYgKHhmYWV2ZW50ID09IHRoaXMub3B0aW9ucy5jb21taXRFdmVudCkgewogICAgICAgICAgICAgICAgdGhpcy5wcmVQcm9jZXNzQ29tbWl0KGh0bWxldmVudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3dpdGNoICh4ZmFldmVudCkgewogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VOVEVSX0VWRU5UOgogICAgICAgICAgICAgICAgICAgIHRoaXMucHJlUHJvY2Vzc0VudGVyKGh0bWxldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRVhJVF9FVkVOVDoKICAgICAgICAgICAgICAgICAgICB0aGlzLnByZVByb2Nlc3NFeGl0KGh0bWxldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0hBTkdFX0VWRU5UOgogICAgICAgICAgICAgICAgICAgIHRoaXMucHJlUHJvY2Vzc0NoYW5nZShodG1sZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NMSUNLX0VWRU5UOgogICAgICAgICAgICAgICAgICAgIHRoaXMucHJlUHJvY2Vzc0NsaWNrKGh0bWxldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgfSwKCiAgICAgICAgX3Bvc3RQcm9jZXNzRXZlbnQ6IGZ1bmN0aW9uICh4ZmFldmVudCwgaHRtbGV2ZW50KSB7CiAgICAgICAgICAgIGlmICh4ZmFldmVudCA9PSB0aGlzLm9wdGlvbnMuY29tbWl0RXZlbnQpIHsKICAgICAgICAgICAgICAgIHRoaXMucG9zdFByb2Nlc3NDb21taXQoaHRtbGV2ZW50KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzd2l0Y2ggKHhmYWV2ZW50KSB7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRU5URVJfRVZFTlQ6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3N0UHJvY2Vzc0VudGVyKGh0bWxldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRVhJVF9FVkVOVDoKICAgICAgICAgICAgICAgICAgICB0aGlzLnBvc3RQcm9jZXNzRXhpdChodG1sZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NIQU5HRV9FVkVOVDoKICAgICAgICAgICAgICAgICAgICB0aGlzLnBvc3RQcm9jZXNzQ2hhbmdlKGh0bWxldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0xJQ0tfRVZFTlQ6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3N0UHJvY2Vzc0NsaWNrKGh0bWxldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaW5pdGlhbGl6ZU9wdGlvbnM6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgXy5lYWNoKHRoaXMub3B0aW9uc0hhbmRsZXIsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7CiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAiZnVuY3Rpb24iKQogICAgICAgICAgICAgICAgICAgIHZhbHVlLmFwcGx5KHRoaXMsIFt0aGlzLm9wdGlvbnNba2V5XV0pOyAvLyBUT0RPOiBjaGVjayB3aGV0aGVyIGl0IGlzIG5lZWRlZCBmb3IgaW5pdGlhbGl6YXRpb24gb3Igbm90CiAgICAgICAgICAgIH0sIHRoaXMpCiAgICAgICAgfSwKCiAgICAgICAgX3NldE9wdGlvbjogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHsKICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9uc1trZXldICE9IHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnNbIGtleSBdID0gdmFsdWU7CiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMub3B0aW9uc0hhbmRsZXJba2V5XSA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9uc0hhbmRsZXJba2V5XS5hcHBseSh0aGlzLCBbdGhpcy5vcHRpb25zW2tleV1dKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQG92ZXJyaWRlCiAgICAgICAgICovCiAgICAgICAgb3B0aW9uOiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkgewogICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJgogICAgICAgICAgICAgICAgdHlwZW9mIGtleSA9PT0gInN0cmluZyIgJiYKICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmCiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnNba2V5XSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAkLldpZGdldC5wcm90b3R5cGUub3B0aW9uLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykKICAgICAgICB9LAoKICAgICAgICBkZXN0cm95OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUNsYXNzKHRoaXMuX3dpZGdldE5hbWUpOwogICAgICAgIH0sCgoKICAgICAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGNvbnRyb2w7CiAgICAgICAgICAgIGlmICh0aGlzLmVsZW1lbnQuY2hpbGRyZW4oKS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICBjb250cm9sID0gJCh0aGlzLmVsZW1lbnQuY2hpbGRyZW4oKS5nZXQoMCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGNvbnRyb2wgPSB0aGlzLmVsZW1lbnQ7CiAgICAgICAgICAgIGNvbnRyb2wuYXR0cigibmFtZSIsIHRoaXMub3B0aW9ucy5uYW1lKQogICAgICAgICAgICByZXR1cm4gY29udHJvbDsKICAgICAgICB9LAoKCiAgICAgICAgcHJlUHJvY2Vzc0NvbW1pdDogZnVuY3Rpb24gKGV2bnQpIHsKICAgICAgICAgICAgdGhpcy5vcHRpb25zLnZhbHVlID0gdGhpcy5nZXRDb21taXRWYWx1ZSgpOwogICAgICAgICAgICB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0TG9nZ2VyKCkuZGVidWcoInhmYSIsICJwYXNzaW5nIGNvbW1pdCB2YWx1ZSAiICsgdGhpcy5vcHRpb25zLnZhbHVlICsKICAgICAgICAgICAgInRvIG1vZGVsICIpOwogICAgICAgIH0sCgogICAgICAgIGdldENvbW1pdFZhbHVlOiBmdW5jdGlvbiAoKSB7CgogICAgICAgIH0sCgogICAgICAgIHByZVByb2Nlc3NFeGl0OiBmdW5jdGlvbiAoZXZudCkgewoKICAgICAgICB9LAoKICAgICAgICBwcmVQcm9jZXNzRW50ZXI6IGZ1bmN0aW9uIChldm50KSB7CiAgICAgICAgICAgIC8vT25seSBmb2N1cyB0aGUgZW5hYmxlZCB3aWRnZXRzCiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuYWNjZXNzID09PSAib3BlbiIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX3Nob3dFcnJvcigpOwogICAgICAgICAgICAgICAgdGhpcy5zaG93VmFsdWUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHByZVByb2Nlc3NDaGFuZ2U6IGZ1bmN0aW9uIChldm50KSB7CgogICAgICAgIH0sCgogICAgICAgIHByZVByb2Nlc3NDbGljazogZnVuY3Rpb24gKGV2bnQpIHsKCiAgICAgICAgfSwKCiAgICAgICAgcG9zdFByb2Nlc3NDb21taXQ6IGZ1bmN0aW9uIChldm50KSB7CiAgICAgICAgICAgIHRoaXMuc2hvd0Rpc3BsYXlWYWx1ZSgpOwogICAgICAgIH0sCgogICAgICAgIHBvc3RQcm9jZXNzRXhpdDogZnVuY3Rpb24gKGV2bnQpIHsKICAgICAgICAgICAgLy9Pbmx5IGZvciB0aGUgZW5hYmxlZCB3aWRnZXRzCiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuYWNjZXNzID09PSAib3BlbiIpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2hvd0Rpc3BsYXlWYWx1ZSgpOwogICAgICAgICAgICAgICAgdGhpcy5faGlkZUVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBwb3N0UHJvY2Vzc0VudGVyOiBmdW5jdGlvbiAoZXZudCkgewogICAgICAgIH0sCgogICAgICAgIHBvc3RQcm9jZXNzQ2hhbmdlOiBmdW5jdGlvbiAoZXZudCkgewoKICAgICAgICB9LAoKICAgICAgICBwb3N0UHJvY2Vzc0NsaWNrOiBmdW5jdGlvbiAoZXZudCkgewoKICAgICAgICB9LAoKICAgICAgICBzaG93RGlzcGxheVZhbHVlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnZhbCh0aGlzLm9wdGlvbnMuZGlzcGxheVZhbHVlKQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIENoZWNrcyBpZiB0aGUgZWRpdCB2YWx1ZSBpcyBzYW1lIGFzIHZhbHVlIHByZXNlbnQgaW4gdGhlIHVzZXIgY29udHJvbChodG1sIGZvcm0gZWxlbWVudCkKICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0KICAgICAgICAgKi8KICAgICAgICBfaXNWYWx1ZVNhbWUgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gKCgodGhpcy5vcHRpb25zLnZhbHVlID09PSBudWxsKSAmJiAodGhpcy4kdXNlckNvbnRyb2wudmFsKCkgPT09ICIiKSkgfHwgKHRoaXMub3B0aW9ucy52YWx1ZSA9PT0gdGhpcy4kdXNlckNvbnRyb2wudmFsKCkpKTsKICAgICAgICB9LAoKICAgICAgICBzaG93VmFsdWU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgLy8gTWF5IGJlICR1c2VyQ29udHJvbCBkb2Vzbid0IGhhdmUgdmFsKCksIHVzaW5nIGl0IGFzIG9mIG5vdwogICAgICAgICAgICAvLyBJZiB0aGUgdmFsdWUgb2YgdGhlIGZpZWxkIGlzIG5vdCBzYW1lIGFzIGVkaXQgdmFsdWUsIG9ubHkgdGhlbiBzZXQgdGhlIHZhbHVlLCB0aGlzIGFsc28gc29sdmVzIElFIGJ1ZyBvZiBjdXJzb3IKICAgICAgICAgICAgLy8gbW92aW5nIHRvIHRoZSBlbmQgb2YgZmllbGQgb24gY2xpY2sKICAgICAgICAgICAgaWYoIXRoaXMuX2lzVmFsdWVTYW1lKCkpIHsKICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnZhbCh0aGlzLm9wdGlvbnMudmFsdWUpCiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBmb2N1czogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgIC8vIHNldFRpbWVvdXQgYWRkZWQgdG8gZml4IENRLTUxMTQxCiAgICAgICAgICAgIC8vIFdoaWxlIHVzaW5nIHNldEZvY3VzIEFQSSBpbiBhZGFwdGl2ZSBmb3JtLCB0aGUgZm9jdXMgd2FzIG5vdCBiZWluZyBzZXQgaW4gVGV4dEJveCBvbiBjaHJvbWUKICAgICAgICAgICAgLy8gYW5kIGFsc28gb24gY2xpY2sgb2YgY2FwdGlvbiBvZiBSYWRpb0J1dHRvbi9DaGVja2JveCwgZHVlIHRvIGZhc3QgZXZlbnQgZXhlY3V0aW9uLCBoZW5jZSBhZGRpbmcgZGVsYXkgZHVyaW5nIGZvY3VzLgogICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICB0aGF0LiR1c2VyQ29udHJvbFswXS5mb2N1cygpOwogICAgICAgICAgICB9LCAxKTsKICAgICAgICB9LAoKICAgICAgICBjbGljazogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLmZvY3VzKCk7CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXJIYW5kbGVyKCJjbGljayIpOyAvLyB3ZSBkbyBub3Qgd2FudCB0aGUgZXhhY3QgY2xpY2sgYXMgbWlnaHQgYnViYmxlIHVwIHRvIHRoZSBmaWVsZC4KICAgICAgICB9LAoKICAgICAgICAvKiB3aWRnZXQgc3BlY2lmaWMgY29kZSAqLwoKICAgICAgICBfc2hvd0Vycm9yOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmKHRoaXMuZXJyT2JqICYmIF8uaXNGdW5jdGlvbih0aGlzLmVyck9iai5vbkZpZWxkRW50ZXIpKSB7CiAgICAgICAgICAgICAgICB0aGlzLmVyck9iai5vbkZpZWxkRW50ZXIodGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfY2FsY3VsYXRlUGFkZGluZ0ZvclZBbGlnbjpmdW5jdGlvbihkaWZmKXsKICAgICAgICAgICB2YXIgZmxhZ0Zvck1veiA9ICQuYnJvd3Nlci5tb3ppbGxhICYmICF4ZmFsaWIudXQuVXRpbGl0aWVzLmlzSUUxMSgpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5tdWx0aUxpbmUsCiAgICAgICAgICAgICAgIHZBbGlnbkJvdHRvbU9yVG9wID0gdGhpcy5vcHRpb25zLnBhcmFTdHlsZXMgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodGhpcy5vcHRpb25zLnBhcmFTdHlsZXNbInZlcnRpY2FsLWFsaWduIl0gPT0gImJvdHRvbSIgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLnBhcmFTdHlsZXNbInZlcnRpY2FsLWFsaWduIl0gPT0gInRvcCIpOwoKICAgICAgICAgICBpZihmbGFnRm9yTW96ICYmIHZBbGlnbkJvdHRvbU9yVG9wIHx8ICQuYnJvd3Nlci5tc2llICYmIHRoaXMub3B0aW9ucy5tdWx0aUxpbmUpIHsKICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgfQogICAgICAgICAgIC8vIHRvIGhhbmRsZSB0aGUgZWRnZSBjYXNlcywgaWYgdGhlIGRpZmYgaXMgbGlrZSAtMC4wMSB0aGUgd2hvbGUgb3BlcmF0aW9uIGlzIGdldHRpbmcgYWJvcnRlZAogICAgICAgICAgIC8vIHRoaXMgZGlmZiBjb21lcyBtYWlubHkgZHVlIHRvIHNjcm9sbCBoZWlnaHQgZ2V0dGluZyByb3VuZGVkIG9mZiB3aGVuIHdpZGdldEhlaWdodCBpcyBsaWtlIHguOTk5OTk5CiAgICAgICAgICAgZGlmZiA9IChkaWZmID4gLTAuMDEpID8gTWF0aC5hYnMoZGlmZikgOiBkaWZmOwogICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMucGFyYVN0eWxlcyAmJiBkaWZmID4gMCkgewogICAgICAgICAgICAgICAgdmFyIHZBbGlnbiA9IHRoaXMub3B0aW9ucy5wYXJhU3R5bGVzWyJ2ZXJ0aWNhbC1hbGlnbiJdOwogICAgICAgICAgICAgICAgaWYgKHZBbGlnbiA9PSAiYm90dG9tIikgewogICAgICAgICAgICAgICAgICAgIGRpZmYgPSBkaWZmIC0gdGhpcy5vcHRpb25zLnBhcmFTdHlsZXNbInBhZGRpbmctYm90dG9tIl07CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuY3NzKCJwYWRkaW5nLXRvcCIsIGRpZmYpOwogICAgICAgICAgICAgICAgICAgIHRoaXMucGFkZGluZyA9IHRoaXMuJHVzZXJDb250cm9sLmNzcygicGFkZGluZy10b3AiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZBbGlnbiA9PSAidG9wIiB8fCAodkFsaWduICE9ICJtaWRkbGUiICYmIHZBbGlnbiA9PSB1bmRlZmluZWQpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wYXJhU3R5bGVzWyJwYWRkaW5nLXRvcCJdKQogICAgICAgICAgICAgICAgICAgICAgICBkaWZmID0gZGlmZiAtIHRoaXMub3B0aW9ucy5wYXJhU3R5bGVzWyJwYWRkaW5nLXRvcCJdOwogICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNzcygicGFkZGluZy1ib3R0b20iLCBkaWZmKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnBhZGRpbmcgPSB0aGlzLiR1c2VyQ29udHJvbC5jc3MoInBhZGRpbmctYm90dG9tIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLm9wdGlvbnMubXVsdGlMaW5lICYmIHZBbGlnbiA9PSAibWlkZGxlIikgewogICAgICAgICAgICAgICAgICAgIHZhciBuZXdEaWZmID0gZGlmZiAvIDI7CiAgICAgICAgICAgICAgICAgICAgbmV3RGlmZiA9IG5ld0RpZmYgLSB0aGlzLm9wdGlvbnMucGFyYVN0eWxlc1sicGFkZGluZy1ib3R0b20iXTsKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnBhcmFTdHlsZXNbInBhZGRpbmctdG9wIl0pCiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0RpZmYgPSBuZXdEaWZmICsgdGhpcy5vcHRpb25zLnBhcmFTdHlsZXNbInBhZGRpbmctdG9wIl07CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuY3NzKCJwYWRkaW5nLXRvcCIsIG5ld0RpZmYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZVZBbGlnbk9uRXhpdDogZnVuY3Rpb24gKGV2bnQpIHsKCiAgICAgICAgICAgIGlmICghdGhpcy5vcHRpb25zLnBhcmFTdHlsZXMpIHsKICAgICAgICAgICAgICAgIC8vdkFsaWduIGhhcyB0byBiZSBoYW5kbGVkIG9ubHkgaWYgdGhlcmUgaXMgcGFyYVN0eWxlcwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMub3B0aW9ucy5kaXNwbGF5VmFsdWUsCiAgICAgICAgICAgICAgICBsaW5lSGVpZ2h0ID0geGZhbGliLnZpZXcudXRpbC5UZXh0TWV0cmljcy5tZWFzdXJlRXh0ZW50KHZhbHVlLCB7cmVmRWw6IHRoaXMuJHVzZXJDb250cm9sLmdldCgwKSwgbWF4SGVpZ2h0OiAtMX0pLmhlaWdodCwKICAgICAgICAgICAgICAgIHdpZGdldEhlaWdodCA9IHRoaXMub3B0aW9ucy5oZWlnaHQsCiAgICAgICAgICAgICAgICBkaWZmID0gd2lkZ2V0SGVpZ2h0IC0gbGluZUhlaWdodDsKICAgICAgICAgICAgdGhpcy5fY2FsY3VsYXRlUGFkZGluZ0ZvclZBbGlnbihkaWZmKTsKCiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZVZBbGlnbk9uRW50ZXI6IGZ1bmN0aW9uIChldm50KSB7CiAgICAgICAgICAgIC8vT25seSBhbGlnbiB0aGUgZW5hYmxlZCB3aWRnZXRzCiAgICAgICAgICAgIHZhciBmbGFnRm9ySUUgPSAkLmJyb3dzZXIubXNpZSAmJiB0aGlzLm9wdGlvbnMubXVsdGlMaW5lOwogICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnBhcmFTdHlsZXMgJiYgIWZsYWdGb3JJRSkgewogICAgICAgICAgICAgICAgIHZhciB2QWxpZ24gPSB0aGlzLm9wdGlvbnMucGFyYVN0eWxlc1sidmVydGljYWwtYWxpZ24iXTsKICAgICAgICAgICAgICAgICBpZiAodkFsaWduID09ICJib3R0b20iICYmIHRoaXMucGFkZGluZykKICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuY3NzKCJwYWRkaW5nLXRvcCIsIHRoaXMucGFkZGluZyk7CiAgICAgICAgICAgICAgICAgZWxzZSBpZiAodkFsaWduID09ICJ0b3AiICYmIHRoaXMucGFkZGluZykKICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuY3NzKCJwYWRkaW5nLWJvdHRvbSIsIHRoaXMucGFkZGluZyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaGlkZUVycm9yOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmKHRoaXMuZXJyT2JqICYmIF8uaXNGdW5jdGlvbih0aGlzLmVyck9iai5vbkZpZWxkRXhpdCkpIHsKICAgICAgICAgICAgICAgIHRoaXMuZXJyT2JqLm9uRmllbGRFeGl0KHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbWFya0Vycm9yOiBmdW5jdGlvbiAobXNnLCB0eXBlKSB7CiAgICAgICAgICAgIGlmKHRoaXMuZXJyT2JqICYmIF8uaXNGdW5jdGlvbih0aGlzLmVyck9iai5tYXJrRXJyb3IpKSB7CiAgICAgICAgICAgICAgICB0aGlzLmVyck9iai5tYXJrRXJyb3IodGhpcywgbXNnLCB0eXBlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNsZWFyRXJyb3I6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYodGhpcy5lcnJPYmogJiYgXy5pc0Z1bmN0aW9uKHRoaXMuZXJyT2JqLmNsZWFyRXJyb3IpKSB7CiAgICAgICAgICAgICAgICB0aGlzLmVyck9iai5jbGVhckVycm9yKHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RWRpdFZhbHVlOiBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgICBpZih0aGlzLm9wdGlvbnMuZWRpdFBhdHRlcm4gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlBpY3R1cmVGbXQuZm9ybWF0KHZhbHVlLCB0aGlzLm9wdGlvbnMuZWRpdFBhdHRlcm4pOwogICAgICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcGFyc2VFZGl0VmFsdWU6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5lZGl0UGF0dGVybiA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiB4ZmFsaWIudXQuUGljdHVyZUZtdC5wYXJzZSh2YWx1ZSwgdGhpcy5vcHRpb25zLmVkaXRQYXR0ZXJuKTsKICAgICAgICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKfSkoJCwgd2luZG93Ll8pOwooZnVuY3Rpb24oJCkgewogICAgJC53aWRnZXQoICJ4ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCIsICQueGZhV2lkZ2V0LmFic3RyYWN0V2lkZ2V0LCB7CgogICAgICAgIF93aWRnZXROYW1lOiAiZGVmYXVsdFdpZGdldCIsCgogICAgICAgIGdldE9wdGlvbnNNYXA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgcGFyZW50T3B0aW9uc01hcCA9ICQueGZhV2lkZ2V0LmFic3RyYWN0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LHBhcmVudE9wdGlvbnNNYXAsewogICAgICAgICAgICAgICAgImFjY2VzcyI6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAgICAgICAgIHN3aXRjaCh2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAib3BlbiIgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQXR0cigicmVhZE9ubHkiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImFyaWEtcmVhZG9ubHkiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJhcmlhLWRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAibm9uSW50ZXJhY3RpdmUiIDoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAicHJvdGVjdGVkIiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJkaXNhYmxlZCIsICJkaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiYXJpYS1kaXNhYmxlZCIsICJ0cnVlIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAicmVhZE9ubHkiIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoInJlYWRPbmx5IiwgInJlYWRPbmx5Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJhcmlhLXJlYWRvbmx5IiwgInRydWUiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0ICA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJkaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQXR0cigiYXJpYS1kaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKCiAgICAgICAgICAgICAgICAiZGlzcGxheVZhbHVlIjogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLmNvbW1pdFByb3BlcnR5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCQuYnJvd3Nlci5tb3ppbGxhICYmIHRoaXMub3B0aW9ucy5jb21taXRQcm9wZXJ0eSA9PSAidmFsdWUiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvbiBzdWJtaXR0aW5nIGZvcm0gZmlyZWZveCBkb2VzIG5vdCByZW1lbWJlciBhdXRvY29tcGxldGUgdmFsdWVzLCBpZiB1cGRhdGVkIHRocm91Z2ggYXR0cigpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC52YWwodGhpcy5fZGlzcGxheUVtcHR5U3RyaW5nRm9ySUUodGhpcy5vcHRpb25zLmRpc3BsYXlWYWx1ZSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucHJvcCh0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHksIHRoaXMuX2Rpc3BsYXlFbXB0eVN0cmluZ0ZvcklFKHRoaXMub3B0aW9ucy5kaXNwbGF5VmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIodGhpcy5vcHRpb25zLmNvbW1pdFByb3BlcnR5LCB0aGlzLl9kaXNwbGF5RW1wdHlTdHJpbmdGb3JJRSh0aGlzLm9wdGlvbnMuZGlzcGxheVZhbHVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ2dlcigpLmRlYnVnKCJ4ZmFWaWV3IiwgIltEZWZhdWx0V2lkZ2V0Ll91cGRhdGVdLCBVc2VyIENvbnRyb2wgb3IgQ29tbWl0IFByb3BlcnR5IGlzIG51bGwiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgICJwbGFjZWhvbGRlciI6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJwbGFjZWhvbGRlciIsIHZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfSwKCiAgICAgICAgX2Rpc3BsYXlFbXB0eVN0cmluZ0ZvcklFOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgIC8qQ1EtNjk0MTc6IEJ5IGRlZmF1bHQgIm51bGwiIGlzIGRpc3BsYXllZCBpbiB0aGUgY29tbWVudHMgdGV4dCBib3gKICAgICAgICAgICAgICAibnVsbCIgdmFsdWVzIHNob3duIGluIElFICovCiAgICAgICAgICAgIC8vIENRLTY5MTA3IGluY2x1ZGVkIGNoZWNrIGZvciBlZGdlIGFzIHdlbGwKICAgICAgICAgICAgcmV0dXJuICh2YWx1ZSA9PSBudWxsICYmIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5kZXRlY3RJRSgpKSA/ICcnIDogdmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgcmVuZGVyIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBjb250cm9sID0gJC54ZmFXaWRnZXQuYWJzdHJhY3RXaWRnZXQucHJvdG90eXBlLnJlbmRlci5hcHBseSh0aGlzLGFyZ3VtZW50cykKICAgICAgICAgICAgdGhpcy5fYXR0YWNoRXZlbnRIYW5kbGVycyhjb250cm9sKQogICAgICAgICAgICByZXR1cm4gY29udHJvbAogICAgICAgIH0sCgogICAgICAgIGdldENvbW1pdFZhbHVlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHZhbHVlID0gdGhpcy4kdXNlckNvbnRyb2wudmFsKCk7CiAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5oU2Nyb2xsRGlzYWJsZWQgJiYgIXRoaXMub3B0aW9ucy5tdWx0aUxpbmUpCiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuc3BsaXRTdHJpbmdCeVdpZHRoKHRoaXMuJHVzZXJDb250cm9sLnZhbCgpLHRoaXMuJHVzZXJDb250cm9sLndpZHRoKCksdGhpcy4kdXNlckNvbnRyb2wuZ2V0KDApKSA7CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9LAoKICAgICAgICBfYXR0YWNoRXZlbnRIYW5kbGVyczogZnVuY3Rpb24oJGNvbnRyb2wpIHsKICAgICAgICAgICAgJGNvbnRyb2wua2V5ZG93bigkLnByb3h5KHRoaXMuX2hhbmRsZUtleURvd24sdGhpcykpOwogICAgICAgICAgICAkY29udHJvbC5rZXlwcmVzcygkLnByb3h5KHRoaXMuX2hhbmRsZUtleVByZXNzLHRoaXMpKTsKICAgICAgICAgICAgJGNvbnRyb2wub24oJ3Bhc3RlJywkLnByb3h5KHRoaXMuX2hhbmRsZVBhc3RlLHRoaXMpKTsKICAgICAgICAgICAgJGNvbnRyb2wub24oJ2N1dCcsJC5wcm94eSh0aGlzLl9oYW5kbGVDdXQsdGhpcykpOwogICAgICAgIH0sCgogICAgICAgIF9jb21wb3NpdGlvblVwZGF0ZUNhbGxiYWNrIDogZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfYXR0YWNoQ29tcG9zaXRpb25FdmVudEhhbmRsZXJzIDogZnVuY3Rpb24oJGNvbnRyb2wpIHsKICAgICAgICAgICAgdmFyIGlzQ29tcG9zaW5nID0gZmFsc2U7IC8vIElNRSBDb21wb3NpbmcgZ29pbmcgb24KICAgICAgICAgICAgdmFyIGhhc0NvbXBvc2l0aW9uSnVzdEVuZGVkID0gZmFsc2U7IC8vIFVzZWQgdG8gc3dhbGxvdyBrZXl1cCBldmVudCByZWxhdGVkIHRvIGNvbXBvc2l0aW9uZW5kCiAgICAgICAgICAgIC8vIElNRSBzcGVjaWZpYyBoYW5kbGluZywgdG8gaGFuZGxlIGphcGFuZXNlIGxhbmd1YWdlcyBtYXggbGltaXQKICAgICAgICAgICAgLy8gc2luY2UgZW50ZXIgY2FuIGFsc28gYmUgaW52b2tlZCBkdXJpbmcgY29tcG9zaW5nLCBhIHNwZWNpYWwgaGFuZGxpbmcgaXMgZG9uZSBoZXJlCiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcywKICAgICAgICAgICAgICAgIGNoYW5nZUNhcmF0UG9zaXRpb24gPSBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICAvLyBjaGFuZ2UgdGhlIGNhcmF0IHNlbGVjdGlvbiBwb3NpdGlvbiB0byBmdXJ0aGVyIGxpbWl0IGlucHV0IG9mIGNoYXJhY3RlcnMKICAgICAgICAgICAgICAgICAgICB2YXIgcmFuZ2UgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgcmFuZ2Uuc2VsZWN0QWxsQ2hpbGRyZW4odGhhdC4kdXNlckNvbnRyb2xbMF0pOwogICAgICAgICAgICAgICAgICAgIHJhbmdlLmNvbGxhcHNlVG9FbmQoKTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICRjb250cm9sLmtleXVwKGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgICAgICBpZiAoLyppc0NvbXBvc2luZyB8fCAqL2hhc0NvbXBvc2l0aW9uSnVzdEVuZGVkKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoYXQuX2NvbXBvc2l0aW9uVXBkYXRlQ2FsbGJhY2soZXZlbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZUNhcmF0UG9zaXRpb24oKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gSU1FIGNvbXBvc2luZyBmaXJlcyBrZXlkb3duL2tleXVwIGV2ZW50cwogICAgICAgICAgICAgICAgICAgIGhhc0NvbXBvc2l0aW9uSnVzdEVuZGVkID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICAkY29udHJvbC5vbigiY29tcG9zaXRpb25zdGFydCIsCiAgICAgICAgICAgICAgICBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAgICAgICAgIGlzQ29tcG9zaW5nID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAub24oImNvbXBvc2l0aW9udXBkYXRlIiwKICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBldmVudC5vcmlnaW5hbEV2ZW50LmRhdGEgcmVmZXJzIHRvIHRoZSBhY3R1YWwgY29udGVudAogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhhdC5fY29tcG9zaXRpb25VcGRhdGVDYWxsYmFjayhldmVudCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZUNhcmF0UG9zaXRpb24oKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAub24oImNvbXBvc2l0aW9uZW5kIiwKICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICBpc0NvbXBvc2luZyA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICAvLyBzb21lIGJyb3dzZXJzIChJRSwgRmlyZWZveCwgU2FmYXJpKSBzZW5kIGEga2V5dXAgZXZlbnQgYWZ0ZXIKICAgICAgICAgICAgICAgICAgICAgICAgLy8gIGNvbXBvc2l0aW9uZW5kLCBzb21lIChDaHJvbWUsIEVkZ2UpIGRvbid0LiBUaGlzIGlzIHRvIHN3YWxsb3cKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIG5leHQga2V5dXAgZXZlbnQsIHVubGVzcyBhIGtleWRvd24gZXZlbnQgaGFwcGVucyBmaXJzdAogICAgICAgICAgICAgICAgICAgICAgICBoYXNDb21wb3NpdGlvbkp1c3RFbmRlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIC5vbigia2V5ZG93biIsCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIG9uIE9TIFggbWF5IHNlbmQgYSBrZXlkb3duIG9mIDIyOSBhZnRlciBjb21wb3NpdGlvbmVuZAogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQud2hpY2ggIT09IDIyOSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzQ29tcG9zaXRpb25KdXN0RW5kZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVLZXlEb3duIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICBpZihldmVudC5rZXlDb2RlID09IDEzIHx8IGV2ZW50LmNoYXJDb2RlID09IDEzIHx8IGV2ZW50LndoaWNoID09IDEzKSAvLyB0b3VjaCBkZXZpY2VzIG1heSByZXR1cm4gY2hhckNvZGUKICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUtleVByZXNzIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICBpZihldmVudC5rZXlDb2RlID09IDEzIHx8IGV2ZW50LmNoYXJDb2RlID09IDEzIHx8IGV2ZW50LndoaWNoID09IDEzKSAvLyB0b3VjaCBkZXZpY2VzIG1heSByZXR1cm4gY2hhckNvZGUKICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgfQogICAgfSk7Cn0pKCQpOwooZnVuY3Rpb24oJCwgXykgewogICAgdmFyIHhmYVV0aWwgPSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGU7CiAgICAkLndpZGdldCggInhmYVdpZGdldC5kYXRlVGltZUVkaXQiLCAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LCB7CgogICAgICAgIF93aWRnZXROYW1lIDogImRhdGVUaW1lRWRpdCIsCgogICAgICAgIGdldEV2ZW50TWFwOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRFdmVudE1hcC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMuX25hdGl2ZVdpZGdldCA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSwgcGFyZW50T3B0aW9uc01hcCwgewogICAgICAgICAgICAgICAgICAgICJvbmZvY3VzMS5kYXRldGltZXBpY2tlciI6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRU5URVJfRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgIm9udmFsdWVjaGFuZ2UuZGF0ZXRpbWVwaWNrZXIiOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NIQU5HRV9FVkVOVCwKICAgICAgICAgICAgICAgICAgICAib25mb2N1c291dC5kYXRldGltZXBpY2tlciI6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRVhJVF9FVkVOVCwKICAgICAgICAgICAgICAgICAgICAib25vdmVybGFwLmRhdGV0aW1lcGlja2VyIjogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DTElDS19FVkVOVCwgLy8gQ3VzdG9tIEV2ZW50IHRvIGZpeCBCVUcgIzM2MjY5NzQKICAgICAgICAgICAgICAgICAgICAiaW5wdXQiOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NIQU5HRV9FVkVOVCwgLy8gVE9ETyA6IGFkZCBoYW5kbGVyIGZvciB4ZmEuZXZlbnQuY2hhbmdlCiAgICAgICAgICAgICAgICAgICAgImZvY3VzIjogbnVsbCwKICAgICAgICAgICAgICAgICAgICAiYmx1ciI6IG51bGwKICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJC5leHRlbmQoe30sIHBhcmVudE9wdGlvbnNNYXAsIHsKICAgICAgICAgICAgICAgICAgICAiY2hhbmdlIjogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQKICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZ2V0QWRvYmVEYXRlUGlja2VyT3B0aW9uc01hcCA6IGZ1bmN0aW9uKHBhcmVudE9wdGlvbnNNYXApIHsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICJhY2Nlc3MiIDogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIm9wZW4iIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmFkb2JlRGF0ZVRpbWVQaWNrZXIoImFjY2VzcyIsIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIm5vbkludGVyYWN0aXZlIiA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInByb3RlY3RlZCIgOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJyZWFkT25seSIgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYWRvYmVEYXRlVGltZVBpY2tlcigiYWNjZXNzIiwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHBhcmVudE9wdGlvbnNNYXAuYWNjZXNzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImRpc3BsYXlWYWx1ZSIgOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gc2V0IHRoZSB2YWx1ZSBpbiB0aGUgZGF0ZXBpY2tlciBwbHVnaW4KICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hZG9iZURhdGVUaW1lUGlja2VyKCJ2YWx1ZSIsIHRoaXMub3B0aW9ucy52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgLy8gc2hvdyB0aGUgZGlzcGxheSB2YWx1ZQogICAgICAgICAgICAgICAgICAgIHRoaXMuc2hvd0Rpc3BsYXlWYWx1ZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldE5hdGl2ZURhdGVQaWNrZXJPcHRpb25zTWFwOiBmdW5jdGlvbiAocGFyZW50T3B0aW9uc01hcCkgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgImRpc3BsYXlWYWx1ZSI6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dEaXNwbGF5VmFsdWUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgoKICAgICAgICBnZXRPcHRpb25zTWFwOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKSwKICAgICAgICAgICAgICAgIGRhdGVQaWNrZXJPcHRpb25zID0gdGhpcy5fbmF0aXZlV2lkZ2V0ID09PSBmYWxzZSA/IHRoaXMuX2dldEFkb2JlRGF0ZVBpY2tlck9wdGlvbnNNYXAocGFyZW50T3B0aW9uc01hcCkKICAgICAgICAgICAgICAgICAgICA6IHRoaXMuX2dldE5hdGl2ZURhdGVQaWNrZXJPcHRpb25zTWFwKHBhcmVudE9wdGlvbnNNYXApLAogICAgICAgICAgICAgICAgY29tbW9uT3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgICAgICAicGFyYVN0eWxlcyI6IGZ1bmN0aW9uIChwYXJhU3R5bGVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE9wdGlvbnNNYXAucGFyYVN0eWxlcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVWQWxpZ25PbkV4aXQoKTsKICAgICAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgICAgICAgImFjY2VzcyI6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyB1cGRhdGUgd2lkdGggb24gY2hhbmdlIG9mIGFjY2VzcyAoYXMgd2lkdGggb2Ygd2lkZ2V0IGlzIGRlcGVuZGVudCBvbiBhY2Nlc3MpCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBjYWxlbmRlciBpY29uIHNob3VsZCBiZSBoaWRkZW4sIGFuZCB3aWRnZXQgc2hvdWxkIHRha2UgZnVsbCBzcGFjZSB3aGVuIHJlYWRPbmx5CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE9wdGlvbnNNYXAuYWNjZXNzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uc01hcCgpLndpZHRoLmFwcGx5KHRoaXMsW3RoaXMub3B0aW9ucy53aWR0aF0pOwogICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgIndpZHRoIjogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRPcHRpb25zTWFwLndpZHRoLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbiAmJiB2YWwgJiYgdGhpcy5vcHRpb25zLmFjY2VzcyA9PSAib3BlbiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlZmZlY3RpdmVXaWR0aCA9IHZhbCA+IHRoaXMub3B0aW9ucy5jYWxlbmRhckljb25XaWR0aCA/IHZhbCAtIHRoaXMub3B0aW9ucy5jYWxlbmRhckljb25XaWR0aCA6IHZhbDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLndpZHRoKGVmZmVjdGl2ZVdpZHRoKTsgIC8vIGxlYXZlIHNwYWNlIGZvciB0aGUgY2FsIGljb24KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgICAgICJoZWlnaHQiOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50T3B0aW9uc01hcC5oZWlnaHQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlVkFsaWduT25FeGl0KCk7CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAic2NyZWVuUmVhZGVyVGV4dCI6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVkaXRQYXR0ZXJuID0gdGhpcy5vcHRpb25zLmVkaXRQYXR0ZXJuOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdEVkaXRQYXR0ZXJuID0gdGhpcy5fbmF0aXZlV2lkZ2V0ID8gIm1tL2RkL3l5eXkiIDogIllZWVktTU0tREQiOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVnZXggPSAvKD86ZGF0ZSl7MCwxfXsoLiopfS87IC8vIGRhdGV7PHBhdHRlcm4+fSBvciB7PHBhdHRlcm4+fSBib3RoIGFyZSB2YWxpZCBhcyBwZXIgeGZhIHNwZWMKICAgICAgICAgICAgICAgICAgICAgICAgZWRpdFBhdHRlcm4gPSB0eXBlb2YgZWRpdFBhdHRlcm4gPT09ICJzdHJpbmciID8gZWRpdFBhdHRlcm4ubWF0Y2gocmVnZXgpWzFdIDogZGVmYXVsdEVkaXRQYXR0ZXJuOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVmYXVsdExhYmVsID0gIlBsZWFzZSBFbnRlciBkYXRlIGluIHswfSBmb3JtYXQgb25seSI7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlZGl0UGF0dGVybikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFyaWFMYWJlbCA9IHhmYWxpYi51dC5Mb2NhbGl6YXRpb25VdGlsLnByb3RvdHlwZS5nZXRMb2NhbGl6ZWRNZXNzYWdlKCIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmYWxpYi5sb2NhbGUuU3RyaW5ncy5kYXRlUGlja2VyQXJpYUxhYmVsIHx8IGRlZmF1bHRMYWJlbCwgW2VkaXRQYXR0ZXJuXSkKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmluYWxWYWwgPSB2YWwgIT09IHVuZGVmaW5lZCA/IHZhbCArICIgIiArIGFyaWFMYWJlbCA6IHZhbDsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiYXJpYS1sYWJlbCIsIGZpbmFsVmFsKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICByZXR1cm4gJC5leHRlbmQoe30scGFyZW50T3B0aW9uc01hcCxkYXRlUGlja2VyT3B0aW9ucywgY29tbW9uT3B0aW9ucyk7CiAgICAgICAgfSwKCiAgICAgICAgcG9zdFByb2Nlc3NFeGl0OiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLnBvc3RQcm9jZXNzRXhpdC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuX2hhbmRsZVZBbGlnbk9uRXhpdCAoKTsKICAgICAgICB9LAoKICAgICAgICBwcmVQcm9jZXNzRW50ZXI6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUucHJlUHJvY2Vzc0VudGVyLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5faGFuZGxlVkFsaWduT25FbnRlcigpOwogICAgICAgIH0sCgogICAgICAgIHByZVByb2Nlc3NDaGFuZ2U6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAvL0NRLTQ2MzMyOmxvc3Mgb2YgZGF0ZSB2YWx1ZSBpbiBkYXRlLXBpY2tlciAsIHNldHRpbmcgdGhlIHZhbHVlIGhlcmUgb3IgZWxzZQogICAgICAgICAgIC8vaXQgZ2V0cyBsb3N0IGR1cmluZyBmb2N1cwogICAgICAgICAgIGlmKHRoaXMuX25hdGl2ZVdpZGdldCA9PT0gdHJ1ZSl7CiAgICAgICAgICAgIHRoaXMub3B0aW9ucy52YWx1ZSA9IHRoaXMuJHVzZXJDb250cm9sLnZhbCgpOwogICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBzaG93RGlzcGxheVZhbHVlOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYodGhpcy5fbmF0aXZlV2lkZ2V0ID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuc2hvd0Rpc3BsYXlWYWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5zaG93VmFsdWUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgoKICAgICAgICBzaG93VmFsdWU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKHRoaXMuX25hdGl2ZVdpZGdldCA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYWRvYmVEYXRlVGltZVBpY2tlcigidmFsdWUiLCB0aGlzLm9wdGlvbnMudmFsdWUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuc2hvd1ZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJC54ZmFXaWRnZXQudGV4dEZpZWxkLnByb3RvdHlwZS5fc2VsZWN0T25Gb2N1c0luSUUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBnZXRDb21taXRWYWx1ZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVXaWRnZXQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLiR1c2VyQ29udHJvbC5hZG9iZURhdGVUaW1lUGlja2VyKCJ2YWx1ZSIpLAogICAgICAgICAgICAgICAgICAgIHBhcnNlZFZhbHVlID0gdGhpcy5wYXJzZUVkaXRWYWx1ZSh2YWx1ZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VkVmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmdldENvbW1pdFZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfSwKCiAgICAgICAgcmVuZGVyOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgdGV4dFN0eWxlID0gdGhpcy5nZXRPckVsc2UodGhpcy4kZGF0YSh0aGlzLmVsZW1lbnQuZ2V0KDApLCAieGZhbW9kZWwiKSwgInRleHRzdHlsZSIsICIiKSwKICAgICAgICAgICAgICAgICRjb250cm9sID0gJC54ZmFXaWRnZXQuYWJzdHJhY3RXaWRnZXQucHJvdG90eXBlLnJlbmRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpLAogICAgICAgICAgICAgICAgJHNvdXJjZSA9ICRjb250cm9sLAogICAgICAgICAgICAgICAgaWQsCiAgICAgICAgICAgICAgICBleGlzdGluZ0lubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzLAogICAgICAgICAgICAgICAgbmV3SW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXMsCiAgICAgICAgICAgICAgICBjb21iaW5lZElubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzOwogICAgICAgICAgICBleGlzdGluZ0lubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzID0gdGhpcy5lbGVtZW50LmZpbmQoImlucHV0IikuYXR0cigic3R5bGUiKSB8fCAnJzsKICAgICAgICAgICAgdGhpcy5fbmF0aXZlV2lkZ2V0ID0gdHJ1ZTsKICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLnVzZU5hdGl2ZVdpZGdldCA9PT0gZmFsc2UgfHwgJGNvbnRyb2xbMF0udHlwZSAhPT0gImRhdGUiKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVXaWRnZXQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGlkID0gdGhpcy5lbGVtZW50LmZpbmQoImlucHV0IilbMF0uaWQ7CiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQuY2hpbGRyZW4oKS5yZW1vdmUoKTsKICAgICAgICAgICAgICAgICQoIjxkaXY+PC9kaXY+IikuY3NzKHtwb3NpdGlvbjogInJlbGF0aXZlIiwgd2lkdGg6ICIxMDAlIiwgaGVpZ2h0OiAiMTAwJSJ9KSAvLyB3YW50IHRvIGZpbGwgZW50aXJlIHdpZHRoIG9mIGNvbnRhaW5pbmcgdGFibGUgY2VsbAogICAgICAgICAgICAgICAgICAgIC5hcHBlbmQoJCgiPGlucHV0IHR5cGU9J3RleHQnLz4iKSkKICAgICAgICAgICAgICAgICAgICAuYXBwZW5kVG8odGhpcy5lbGVtZW50KTsKICAgICAgICAgICAgICAgICRjb250cm9sID0gJCgiaW5wdXQiLCB0aGlzLmVsZW1lbnQpLgogICAgICAgICAgICAgICAgICAgIGF0dHIoInN0eWxlIiwgdGV4dFN0eWxlKS4KICAgICAgICAgICAgICAgICAgICBhdHRyKCJuYW1lIiwgdGhpcy5vcHRpb25zLm5hbWUpLgogICAgICAgICAgICAgICAgICAgIGF0dHIoImlkIiwgaWQpLgogICAgICAgICAgICAgICAgICAgIGFkb2JlRGF0ZVRpbWVQaWNrZXIoewogICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbmluZzogdGhpcy5lbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICBsb2NhbGU6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vbnRoczogdGhpcy5vcHRpb25zLm1vbnRocywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRheXM6IHRoaXMub3B0aW9ucy5kYXlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgemVybzogdGhpcy5vcHRpb25zLnplcm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRleHQ6IHRoaXMub3B0aW9ucy5jbGVhclRleHQKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzOiB0aGlzLm9wdGlvbnMuYWNjZXNzLAogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdGhpcy5vcHRpb25zLnZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICBzaG93Q2FsZW5kYXJJY29uOiB0aGlzLm9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbiwKICAgICAgICAgICAgICAgICAgICAgICAgaWNvbldpZHRoOiB0aGlzLm9wdGlvbnMuY2FsZW5kYXJJY29uV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgIG1pblZhbGlkRGF0ZSA6IHRoaXMub3B0aW9ucy5taW5WYWxpZERhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgIG1heFZhbGlkRGF0ZSA6IHRoaXMub3B0aW9ucy5tYXhWYWxpZERhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2xNaW5EYXRlIDogIHRoaXMub3B0aW9ucy5leGNsTWluRGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXhjbE1heERhdGUgOiB0aGlzLm9wdGlvbnMuZXhjbE1heERhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgIGVkaXRWYWx1ZTogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5nZXRFZGl0VmFsdWUodmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5fYXR0YWNoRXZlbnRIYW5kbGVycygkY29udHJvbCk7CiAgICAgICAgICAgIG5ld0lubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzID0gdGhpcy5lbGVtZW50LmZpbmQoImlucHV0IikuYXR0cigic3R5bGUiKSB8fCAnJzsKICAgICAgICAgICAgLy9hcHBlbmQgdGhlIHByZXZpb3VzIGlubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzIHRvIG5ld0lubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzIHNvIHRoYXQgdGhlIGlubGluZSBzdHlsZXMKICAgICAgICAgICAgLy9hZGRlZCBmcm9tIHRoZSBkaWFsb2cgYXJlIGFwcGxpZWQuCiAgICAgICAgICAgIGNvbWJpbmVkSW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXMgPSBuZXdJbmxpbmVTdHlsZUF0dHJpYnV0ZVZhbHVlcyArIGV4aXN0aW5nSW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXM7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5maW5kKCJpbnB1dCIpLmF0dHIoInN0eWxlIiwgY29tYmluZWRJbmxpbmVTdHlsZUF0dHJpYnV0ZVZhbHVlcyk7CiAgICAgICAgICAgIC8vIG9ubHkgaW4gY2FzZSBvZiBhZGFwdGl2ZSBmb3JtLCB3ZSB3b3VsZCBjb3B5IHRoZSBhdHRyaWJ1dGVzIGJhY2sKICAgICAgICAgICAgaWYod2luZG93Lmd1aWRlQnJpZGdlKSB7CiAgICAgICAgICAgICAgICAvLyByZXN0b3JlIHRoZSBvcmlnaW5hbCBhdHRyaWJ1dGUgYmFjayB0byBkZXN0aW5hdGlvbiBvYmplY3QKICAgICAgICAgICAgICAgIHRoaXMuY29weUF0dHJpYnV0ZXNGcm9tU3JjVG9EZXN0KCRzb3VyY2UsIHRoaXMuZWxlbWVudC5maW5kKCJpbnB1dCIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gJGNvbnRyb2w7CiAgICAgICAgfQogICAgfSkgOwoKfSkoJCwgXyk7CihmdW5jdGlvbigkLCBfKSB7CiQud2lkZ2V0KCJ4ZmFXaWRnZXQubnVtZXJpY0lucHV0IiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgewoKICAgIF93aWRnZXROYW1lOiAibnVtZXJpY0lucHV0IiwKCglvcHRpb25zIDogewoJCXZhbHVlIDogbnVsbCwKCQljdXJWYWx1ZTogbnVsbCwKICAgICAgICBwb3M6IDAsCiAgICAgICAgbGVuZ3RoTGltaXRWaXNpYmxlOiB0cnVlLAogICAgICAgIHplcm86IjAiLAogICAgICAgIGRlY2ltYWw6Ii4iLAogICAgICAgIG1pbnVzOiItIgoJfSwKCiAgICAvL1RPRE86IHRvIHN1cHBvcnQgd3JpdGluZyBpbiBkaWZmZXJlbnQgbG9jYWxlcyBcZCBzaG91bGQgYmUgcmVwbGFjZWQgYnkgWzAtOV0gZm9yIGRpZmZlcmVudCBsb2NhbGVzCiAgICBfbWF0Y2hBcnJheSA6IHsKICAgICAgICAgICAgICAgICAgICAiaW50ZWdlciI6Il5bKy1dP3tkaWdpdHN9KiQiLAogICAgICAgICAgICAgICAgICAgICJkZWNpbWFsIjoiXlsrLV0/e2RpZ2l0c317bGVhZGluZ30oe2RlY2ltYWx9e2RpZ2l0c317ZnJhY3Rpb259KT8kIiwKICAgICAgICAgICAgICAgICAgICAiZmxvYXQiOiJeWystXT97ZGlnaXRzfSooe2RlY2ltYWx9e2RpZ2l0c30qKT8kIgogICAgICAgICAgICAgICAgICB9LAoKICAgIF9yZWdleCA6IG51bGwsCgogICAgX2VuZ1JlZ2V4IDogbnVsbCwKCiAgICBfd3JpdHRlbkluTG9jYWxlIDogZmFsc2UsCgogICAgX3ByZXZpb3VzQ29tcG9zaXRpb25WYWwgOiAiIiwKCgogICAgX3RvTGF0aW5Gb3JtIDogZnVuY3Rpb24gKGhhbGZPckZ1bGxXaWR0aFN0cikgewogICAgICAgIC8vIHJlZmVyIGh0dHA6Ly93d3cuZmlsZWZvcm1hdC5pbmZvL2luZm8vdW5pY29kZS9ibG9jay9oYWxmd2lkdGhfYW5kX2Z1bGx3aWR0aF9mb3Jtcy91dGY4dGVzdC5odG0KICAgICAgICByZXR1cm4gaGFsZk9yRnVsbFdpZHRoU3RyLnJlcGxhY2UoCiAgICAgICAgICAgIC9bXHVmZjAwLVx1ZmZlZl0vZywKICAgICAgICAgICAgZnVuY3Rpb24oY2gpIHsgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoY2guY2hhckNvZGVBdCgwKSAtIDB4ZmVlMCk7IH0KICAgICAgICApOwogICAgfSwKCiAgICBnZXRPcHRpb25zTWFwOiBmdW5jdGlvbigpIHsKICAgICAgICB2YXIgcGFyZW50T3B0aW9uc01hcCA9ICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmdldE9wdGlvbnNNYXAuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSxwYXJlbnRPcHRpb25zTWFwLHsKICAgICAgICAgICAgInBhcmFTdHlsZXMiOiBmdW5jdGlvbihwYXJhU3R5bGVzKXsKICAgICAgICAgICAgICAgIHBhcmVudE9wdGlvbnNNYXAucGFyYVN0eWxlcy5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVWQWxpZ25PbkV4aXQgKCk7CiAgICAgICAgICAgIH0gLAoKICAgICAgICAgICAgImhlaWdodCI6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAgICAgaWYodmFsKSAgIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy4kdXNlckNvbnRyb2xbMF0seyJoZWlnaHQiIDp2YWx9KTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVWQWxpZ25PbkV4aXQoKTsgICAgLy8gVG8gSGFuZGxlIHRoZSBjYXNlIG9mIGV4cGFuZGFibGUgRmllbGRzCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgfSkKICAgIH0sCgogICAgZ2V0RXZlbnRNYXA6IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0RXZlbnRNYXAuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSxwYXJlbnRPcHRpb25zTWFwLHsKICAgICAgICAgICAgIm9uS2V5SW5wdXQubnVtZXJpY0lucHV0IiA6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0hBTkdFX0VWRU5UCiAgICAgICAgfSkKICAgIH0sCgogICAgX2dldERpZ2l0czogZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIHplcm9Db2RlID0gdGhpcy5vcHRpb25zLnplcm8uY2hhckNvZGVBdCgwKSwKICAgICAgICAgICAgZGlnaXRzID0gIiI7CiAgICAgICAgZm9yKHZhciBpID0gMDtpIDwgMTA7aSsrKSB7CiAgICAgICAgICAgIGRpZ2l0cyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHplcm9Db2RlICsgaSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAiWyIrZGlnaXRzKyJdIgogICAgfSwKCiAgICBfZXNjYXBlOiBmdW5jdGlvbihzdHIpIHsKICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKCIuIiwiXFwuIikKICAgIH0sCgogICAgcG9zdFByb2Nlc3NFeGl0OiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUucG9zdFByb2Nlc3NFeGl0LmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICB0aGlzLl9oYW5kbGVWQWxpZ25PbkV4aXQgKCk7CiAgICB9LAoKICAgIHByZVByb2Nlc3NFbnRlcjogZnVuY3Rpb24oZXZudCkgewogICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLnByZVByb2Nlc3NFbnRlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgdGhpcy5faGFuZGxlVkFsaWduT25FbnRlcigpOwogICAgfSwKCglyZW5kZXIgOiBmdW5jdGlvbigpIHsKICAgICAgICB2YXIgbWF0Y2hTdHIgPSAgdGhpcy5fbWF0Y2hBcnJheVt0aGlzLm9wdGlvbnMuZGF0YVR5cGVdOwogICAgICAgIGlmKG1hdGNoU3RyKSB7CiAgICAgICAgICAgIHZhciBsZCA9IHRoaXMub3B0aW9ucy5sZWFkRGlnaXRzLAogICAgICAgICAgICAgICAgZmQgPSB0aGlzLm9wdGlvbnMuZnJhY0RpZ2l0cywKICAgICAgICAgICAgICAgIGxkc3RyID0gbGQgJiYgbGQgIT0gLTEgPyAiezAsIitsZCsifSIKICAgICAgICAgICAgICAgICAgICA6ICIqIiwKICAgICAgICAgICAgICAgIGZkc3RyID0gZmQgJiYgZmQgIT0gLTEgPyAiezAsIitmZCsifSIKICAgICAgICAgICAgICAgICAgICA6ICIqIiwKICAgICAgICAgICAgICAgIG1hdGNoU3RyID0gIG1hdGNoU3RyLnJlcGxhY2UoIntsZWFkaW5nfSIsbGRzdHIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKCJ7ZnJhY3Rpb259IixmZHN0ciksCiAgICAgICAgICAgICAgICBsb2NhbGVTdHIgPSBtYXRjaFN0ci5yZXBsYWNlKC97ZGlnaXRzfS9nLHRoaXMuX2dldERpZ2l0cygpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgie2RlY2ltYWx9Iix0aGlzLl9lc2NhcGUodGhpcy5vcHRpb25zLmRlY2ltYWwpKSwKICAgICAgICAgICAgICAgIGVuZ1N0ciA9IG1hdGNoU3RyLnJlcGxhY2UoL3tkaWdpdHN9L2csIlswLTldIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgie2RlY2ltYWx9IiwiXFwuIikKICAgICAgICAgICAgdGhpcy5fcHJvY2Vzc1ZhbHVlID0gISh0aGlzLl9nZXREaWdpdHMoKSA9PSAiWzAxMjM0NTY3ODldIiAmJiB0aGlzLm9wdGlvbnMuZGVjaW1hbCA9PSAiLiIpCiAgICAgICAgICAgIHRoaXMuX3JlZ2V4ID0gbmV3IFJlZ0V4cChsb2NhbGVTdHIsICJnIik7CiAgICAgICAgICAgIHRoaXMuX2VuZ1JlZ2V4ID0gbmV3IFJlZ0V4cChlbmdTdHIsICJnIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5yZW5kZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgIH0sCgogICAgZ2V0Q29tbWl0VmFsdWU6IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciB2YWx1ZSA9ICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmdldENvbW1pdFZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgLy8gd2Ugc3VwcG9ydCBmdWxsIHdpZHRoLCBoYWxmIHdpZHRoIGFuZCBsb2NhbGUgc3BlY2lmaWMgbnVtYmVycwogICAgICAgIHZhbHVlID0gdGhpcy5fdG9MYXRpbkZvcm0odmFsdWUpOwogICAgICAgIGlmKHZhbHVlLmxlbmd0aCA+IDAgJiYgdGhpcy5fcHJvY2Vzc1ZhbHVlICYmICF2YWx1ZS5tYXRjaCh0aGlzLl9lbmdSZWdleCkpIHsKICAgICAgICAgICAgdGhpcy5fd3JpdHRlbkluTG9jYWxlID0gdHJ1ZTsKICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9jb252ZXJ0VmFsdWVGcm9tTG9jYWxlKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aGlzLl93cml0dGVuSW5Mb2NhbGUgPSBmYWxzZQogICAgICAgIH0KICAgICAgICBpZih2YWx1ZSAmJiB2YWx1ZS5sZW5ndGggPj0gdGhpcy5vcHRpb25zLmNvbWJDZWxscyApCiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc2xpY2UoMCx0aGlzLm9wdGlvbnMuY29tYkNlbGxzKTsKICAgICAgICB0aGlzLl9wcmV2aW91c0NvbXBvc2l0aW9uVmFsID0gdmFsdWU7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgfSwKCiAgICBfY29tcG9zaXRpb25VcGRhdGVDYWxsYmFjayA6IGZ1bmN0aW9uIChldmVudCkgewogICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICB2YXIgZmxhZyA9IGZhbHNlOwogICAgICAgIHZhciBsZWFkRGlnaXRzID0gdGhhdC5vcHRpb25zLmxlYWREaWdpdHM7CiAgICAgICAgdmFyIGZyYWNEaWdpdHMgPSB0aGF0Lm9wdGlvbnMuZnJhY0RpZ2l0czsKICAgICAgICAvLyB3ZSBkb24ndCBjaGVjayB1c2UtY2FzZSB3aGVyZSBqdXN0IGZyYWNEaWdpdHMgaXMgc2V0IHNpbmNlIGluIGNhc2Ugb2YgY29tcG9zaXRpb24gdXBkYXRlLCB0aGUgdmFsdWUgdG8gdXBkYXRlIGlzIG5vdCBrbm93bgogICAgICAgIGlmIChsZWFkRGlnaXRzICE9PSAtMSkgewogICAgICAgICAgICB2YXIgdmFsID0gdGhhdC4kdXNlckNvbnRyb2wudmFsKCk7CiAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSAiY29tcG9zaXRpb251cGRhdGUiICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQuZGF0YSkgewogICAgICAgICAgICAgICAgdmFsID0gdmFsICsgZXZlbnQub3JpZ2luYWxFdmVudC5kYXRhLnN1YnN0cihldmVudC5vcmlnaW5hbEV2ZW50LmRhdGEubGVuZ3RoIC0gMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gY2FuJ3QgdXNlIHRoZSBleGlzdGluZyByZWdleCAoc2luY2UgY3VycmVudCByZWdleCBjaGVja3MgZm9yIGVuZ2xpc2ggZGlnaXRzKSwgcmF0aGVyIGRvaW5nIGxlYWREaWdpdCBjb21wYXJlCiAgICAgICAgICAgIHZhciB0b3RhbExlbmd0aCA9IGxlYWREaWdpdHMgKyAoZnJhY0RpZ2l0cyAhPT0gLTEgPyAoZnJhY0RpZ2l0cyArIHRoYXQub3B0aW9ucy5kZWNpbWFsLmxlbmd0aCkgOiAwKTsKICAgICAgICAgICAgaWYgKHZhbC5pbmRleE9mKHRoYXQub3B0aW9ucy5kZWNpbWFsKSA9PT0gLTEpIHsKICAgICAgICAgICAgICAgIHRvdGFsTGVuZ3RoID0gbGVhZERpZ2l0czsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgbGF0aW5WYWwgPSB0aGlzLl90b0xhdGluRm9ybSh2YWwpOwogICAgICAgICAgICAvLyBtYXRjaCBib3RoIHNpbmNlIHdlIHN1cHBvcnQgZnVsbCB3aWR0aCwgaGFsZiB3aWR0aCBhbmQgbG9jYWxlIHNwZWNpZmljIGlucHV0CiAgICAgICAgICAgIHZhciBtYXRjaCA9IGxhdGluVmFsLm1hdGNoKHRoYXQuX3JlZ2V4KXx8IGxhdGluVmFsLm1hdGNoKHRoaXMuX2VuZ1JlZ2V4KTsKICAgICAgICAgICAgZmxhZyAgPSAhbWF0Y2g7CiAgICAgICAgICAgIGlmIChtYXRjaCA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgLy8gZW50ZXJlZCBpbnZhbGlkIGNoYXJhY3RlciwgcmV2ZXJ0IHRvIHByZXZpb3VzIHZhbHVlCiAgICAgICAgICAgICAgICB0aGF0LiR1c2VyQ29udHJvbC52YWwodGhhdC5fcHJldmlvdXNDb21wb3NpdGlvblZhbCk7CiAgICAgICAgICAgICAgICBmbGFnID0gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIGlmIChmbGFnKSB7CiAgICAgICAgICAgICAgICAvLyBpZiBtYXggcmVhY2hlZAogICAgICAgICAgICAgICAgdmFyIG5ld1ZhbCA9IHZhbC5zdWJzdHIoMCwgdG90YWxMZW5ndGgpOwogICAgICAgICAgICAgICAgdGhhdC4kdXNlckNvbnRyb2wudmFsKG5ld1ZhbCk7CiAgICAgICAgICAgICAgICB0aGF0Ll9wcmV2aW91c0NvbXBvc2l0aW9uVmFsID0gbmV3VmFsOwogICAgICAgICAgICAgICAgZmxhZyA9IHRydWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGF0Ll9wcmV2aW91c0NvbXBvc2l0aW9uVmFsID0gdmFsOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmbGFnOwogICAgfSwKCiAgICBfYXR0YWNoRXZlbnRIYW5kbGVycyA6IGZ1bmN0aW9uKCRjb250cm9sKSB7CiAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuX2F0dGFjaEV2ZW50SGFuZGxlcnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAvLyBJTUUgc3BlY2lmaWMgaGFuZGxpbmcsIHRvIGhhbmRsZSBqYXBhbmVzZSBsYW5ndWFnZXMgbWF4IGxpbWl0CiAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuX2F0dGFjaENvbXBvc2l0aW9uRXZlbnRIYW5kbGVycy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwoJfSwKCiAgICBfaGFuZGxlS2V5SW5wdXQgOiBmdW5jdGlvbihldmVudCwgY2hhcmFjdGVyLCBjb2RlKXsKICAgICAgICBpZihldmVudC5jdHJsS2V5ICYmICFfLmNvbnRhaW5zKFsncGFzdGUnLCAnY3V0J10sIGV2ZW50LnR5cGUpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuX2hhbmRsZUtleURvd24uYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgIHRoaXMub3B0aW9ucy5sZW5ndGhMaW1pdFZpc2libGUgPSB0cnVlOwoKICAgICAgICB2YXIgdmFsID0gdGhpcy4kdXNlckNvbnRyb2wucHJvcCh0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHkpIHx8ICcnLAogICAgICAgICAgICAvLyBpZiBzZWxlY3Rpb25TdGFydCBhdHRyaWJ1dGUgaXNuJ3Qgc3VwcG9ydGVkIHRoZW4gaXRzIHZhbHVlIHdpbGwgYmUgdW5kZWZpbmVkCiAgICAgICAgICAgIHNlbGVjdGlvblN0YXJ0ID0geGZhbGliLnZpZXcudXRpbC5IdG1sVXRpbC5nZXRIVE1MU3VwcG9ydGVkQXR0cih0aGlzLiR1c2VyQ29udHJvbFswXSwgInNlbGVjdGlvblN0YXJ0IiksCiAgICAgICAgICAgIGlzU2VsZWN0aW9uQXR0clN1cHBvcnRlZCA9ICEoc2VsZWN0aW9uU3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzZWxlY3Rpb25TdGFydCA9PT0gbnVsbCksCiAgICAgICAgICAgIHNlbGVjdGlvblN0YXJ0ID0gc2VsZWN0aW9uU3RhcnQgfHwgMCwKICAgICAgICAgICAgc2VsZWN0aW9uRW5kID0geGZhbGliLnZpZXcudXRpbC5IdG1sVXRpbC5nZXRIVE1MU3VwcG9ydGVkQXR0cih0aGlzLiR1c2VyQ29udHJvbFswXSwgInNlbGVjdGlvbkVuZCIpIHx8IDAsCiAgICAgICAgICAgIGNvbWJDZWxscyA9IHBhcnNlSW50KHRoaXMub3B0aW9ucy5jb21iQ2VsbHMpIHx8IDAsCiAgICAgICAgICAgIGN1cnJlbnQsCiAgICAgICAgICAgIGNoYW5nZSA9IGNoYXJhY3RlcjsKCiAgICAgICAgaWYgKGNvbWJDZWxscyA+IDAgKSB7CiAgICAgICAgICAgIGNoYW5nZSA9IGNoYXJhY3Rlci5zdWJzdHIoMCwgY29tYkNlbGxzIC0gdmFsLmxlbmd0aCArIHNlbGVjdGlvbkVuZCAtIHNlbGVjdGlvblN0YXJ0KTsKICAgICAgICB9CgogICAgICAgIGN1cnJlbnQgPSB2YWwuc3Vic3RyKDAsIHNlbGVjdGlvblN0YXJ0KSArIGNoYW5nZSArIHZhbC5zdWJzdHIoc2VsZWN0aW9uRW5kKTsKICAgICAgICAvLyBkb25lIHRvIGhhbmRsZSBzdXBwb3J0IGZvciBib3RoIGZ1bGwgd2lkdGgsIGhhbGYgd2lkdGggb3IgbWl4ZWQgaW5wdXQgaW4gbnVtYmVyIGZpZWxkCiAgICAgICAgdmFyIGxhdGluQ3VycmVudFZhbHVlID0gdGhpcy5fdG9MYXRpbkZvcm0oY3VycmVudCk7CgoJLy8gd2Ugd2FudCB0byBjaGVjayByZWdleCBmaXJzdCBhbmQgdGhlbiBzZWUgd2hldGhlciBpdCB3YXMgbnVtZXJpYyBvciBub3QuCiAgICAgICAgaWYgKCEodGhpcy5fcmVnZXggPT0gbnVsbCB8fCBsYXRpbkN1cnJlbnRWYWx1ZS5tYXRjaCh0aGlzLl9yZWdleCkgfHwgbGF0aW5DdXJyZW50VmFsdWUubWF0Y2godGhpcy5fZW5nUmVnZXgpKSkgewogICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKCS8vIENRLTQyNDU0MDcgOiBzZWxlY3Rpb25TdGFydCBhbmQgc2VsZWN0aW9uRW5kIGF0dHJpYnV0ZXMgYXJlbid0IHN1cHBvcnRlZCBpbiBjYXNlIG9mIGlucHV0IHR5cGUgPSBudW1iZXIKICAgICAgICAvLyBpdCBpcyB1c2VkIGZvciBwcm92aWRpbmcgbmF0aXZlIEhUTUw1IGltcGxlbWVudGF0aW9uIGZvciBudW1lcmljIGZpZWxkLCBzbyBubyBmdXJ0aGVyIHByb2Nlc3NpbmcgaXMgcmVxdWlyZWQKICAgICAgICAvLyBBcyBpdCBpcyBzcGVjaWZpYyB0byBBRiBhbmQgQUYgZG9lc24ndCBzdXBwb3J0IGNoYW5nZSBldmVudCBvbiBlYWNoIGtleXByZXNzLCBzbyB0aGlzIGNoYW5nZSBzaG91bGQgYmUgZmluZQogICAgICAgIGlmICghaXNTZWxlY3Rpb25BdHRyU3VwcG9ydGVkKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFfLmNvbnRhaW5zKFsna2V5ZG93bicsICdjdXQnXSwgZXZlbnQudHlwZSkgJiYgY29tYkNlbGxzICYmICh2YWwubGVuZ3RoID49IGNvbWJDZWxscyB8fCBjdXJyZW50Lmxlbmd0aCA+IGNvbWJDZWxscykgJiYgc2VsZWN0aW9uU3RhcnQgPT09IHNlbGVjdGlvbkVuZCkgewogICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICB0aGlzLm9wdGlvbnMuY3VyVmFsdWUgPSB2YWw7CiAgICAgICAgdGhpcy5fcHJldmlvdXNDb21wb3NpdGlvblZhbCA9IHZhbDsKICAgICAgICB0aGlzLm9wdGlvbnMucG9zID0gc2VsZWN0aW9uU3RhcnQ7CgogICAgICAgIGlmKHRoaXMub3B0aW9ucy5oU2Nyb2xsRGlzYWJsZWQgJiYgIV8uY29udGFpbnMoWydrZXlkb3duJywgJ2N1dCddLCBldmVudC50eXBlKSkgewogICAgICAgICAgICB2YXIgZXhwZWN0ZWRXaWR0aCA9IHhmYWxpYi52aWV3LnV0aWwuVGV4dE1ldHJpY3MubWVhc3VyZUV4dGVudChjdXJyZW50LCB7cmVmRWw6IHRoaXMuJHVzZXJDb250cm9sWzBdLCBtYXhXaWR0aDotMX0pLndpZHRoOwogICAgICAgICAgICBpZighZXZlbnQuY3RybEtleSAmJiBleHBlY3RlZFdpZHRoID4gdGhpcy4kdXNlckNvbnRyb2wud2lkdGgoKSAtIDUpewogICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5sZW5ndGhMaW1pdFZpc2libGUgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wudHJpZ2dlcih7CiAgICAgICAgICAgIHR5cGUgOiAib25LZXlJbnB1dC5udW1lcmljSW5wdXQiLAogICAgICAgICAgICBvcmlnaW5hbFR5cGUgOiBldmVudC50eXBlLAogICAgICAgICAgICBjaGFyYWN0ZXIgOiBjaGFyYWN0ZXIsICAvLyBjb250YWlucyB0aGUgcGFzdGVkIHN0cmluZyBvciBwcmVzc2VkIGtleQogICAgICAgICAgICBrZXlDb2RlIDogZXZlbnQua2V5Q29kZSB8fCAwLAogICAgICAgICAgICBjaGFyQ29kZSA6IGV2ZW50LmNoYXJDb2RlIHx8IDAsCiAgICAgICAgICAgIHdoaWNoIDogZXZlbnQud2hpY2ggfHwgMCwKICAgICAgICAgICAgY3RybEtleSA6IGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSB8fCBmYWxzZSwKICAgICAgICAgICAgc2hpZnRLZXkgOiBldmVudC5zaGlmdEtleSB8fCBmYWxzZSwKICAgICAgICAgICAga2V5RG93biA6IGZhbHNlLCAvLyBUaGlzIHByb3BlcnR5IGlzIGF2YWlsYWJsZSBvbmx5IGZvciBsaXN0IGJveGVzIGFuZCBkcm9wLWRvd24gbGlzdHMKICAgICAgICAgICAgc2VsZWN0aW9uU3RhcnQ6IHNlbGVjdGlvblN0YXJ0LAogICAgICAgICAgICBzZWxlY3Rpb25FbmQ6IHNlbGVjdGlvbkVuZAogICAgICAgIH0pOwogICAgfSwKCiAgICBfaGFuZGxlS2V5RG93biA6IGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICBpZiAoZXZlbnQpIHsKICAgICAgICAgICAgdmFyIGNvZGUgPSBldmVudC5jaGFyQ29kZSB8fCBldmVudC53aGljaCB8fCBldmVudC5rZXlDb2RlIHx8IDA7CiAgICAgICAgICAgIGlmKGNvZGUgPT0gOCB8fCBjb2RlID09IDQ2KSAvLyBiYWNrc3BhY2UgYW5kIGRlbAogICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVLZXlJbnB1dChldmVudCwgIiIsIGNvZGUpOwogICAgICAgICAgICBlbHNlIGlmKGNvZGUgPT0gMzIpIHsgLy8gc3VwcHJlc3Mgc3BhY2UKICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAoKICAgIF9pc1ZhbGlkQ2hhcjogZnVuY3Rpb24gKGNoYXJhY3RlcikgewogICAgICAgIGNoYXJhY3RlciA9IHRoaXMuX3RvTGF0aW5Gb3JtKGNoYXJhY3Rlcik7CiAgICAgICAgdmFyIGxhc3RTaW5nbGVEaWdpdENoYXIgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMub3B0aW9ucy56ZXJvLmNoYXJDb2RlQXQoMCkgKyA5KTsKICAgICAgICAvLyB3ZSBvbmx5IGZ1bGwgd2lkdGgsIGhhbGYgd2lkdGggYW5kIGFsc28gbG9jYWxlIHNwZWNpZmljIGlmIGN1c3RvbWVyIGhhcyBvdmVybGF5ZWQgdGhlIGkxOG4gZmlsZQogICAgICAgIHJldHVybiAoY2hhcmFjdGVyID49ICIwIiAmJiBjaGFyYWN0ZXIgPD0gIjkiKSB8fCAoY2hhcmFjdGVyPj10aGlzLm9wdGlvbnMuemVybyAmJiBjaGFyYWN0ZXI8PWxhc3RTaW5nbGVEaWdpdENoYXIpIHx8IGNoYXJhY3Rlcj09PXRoaXMub3B0aW9ucy5kZWNpbWFsIHx8IGNoYXJhY3Rlcj09PXRoaXMub3B0aW9ucy5taW51czsKICAgIH0sCgogICAgX2hhbmRsZUtleVByZXNzIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgIGlmIChldmVudCkgewogICAgICAgICAgICB2YXIgY29kZSA9IGV2ZW50LmNoYXJDb2RlIHx8IGV2ZW50LndoaWNoIHx8IGV2ZW50LmtleUNvZGUgfHwgMCwKICAgICAgICAgICAgICAgIGNoYXJhY3RlciA9IFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZSk7CgogICAgICAgICAgICBpZih4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuaXNOb25QcmludGFibGVLZXkoZXZlbnQua2V5KSkgeyAvLyBtb3ppbGxhIGFsc28gZ2VuZXJhdGVzIGEga2V5cHJlc3MsIGFsb25nIHdpdGgga2V5ZG93bgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgYWxsIGtleXMsIHNvIG9ubHkgaGFuZGxpbmcgcHJpbnRhYmxlIGtleXMgaW4ga2V5cHJlc3MKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRoaXMuX2lzVmFsaWRDaGFyKGNoYXJhY3RlcikpCiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVLZXlJbnB1dChldmVudCwgY2hhcmFjdGVyLCBjb2RlKTsKICAgICAgICAgICAgZWxzZSBpZiAoIWV2ZW50LmN0cmxLZXkpewogICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sCgogICAgX2hhbmRsZVBhc3RlIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgIGlmIChldmVudCkgewogICAgICAgICAgICB2YXIgcGFzdGVkQ2hhciA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgaWYgKHdpbmRvdy5jbGlwYm9hcmREYXRhICYmIHdpbmRvdy5jbGlwYm9hcmREYXRhLmdldERhdGEpIHsgLy8gSUUKICAgICAgICAgICAgICAgIHBhc3RlZENoYXIgPSB3aW5kb3cuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCdUZXh0Jyk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnQub3JpZ2luYWxFdmVudC5jbGlwYm9hcmREYXRhICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQuY2xpcGJvYXJkRGF0YS5nZXREYXRhKSB7CiAgICAgICAgICAgICAgICBwYXN0ZWRDaGFyID0gZXZlbnQub3JpZ2luYWxFdmVudC5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQvcGxhaW4nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYocGFzdGVkQ2hhcikgewogICAgICAgICAgICAgICAgdmFyIGFsbFBhc3RlZENoYXJzVmFsaWQgPSBfLmV2ZXJ5KHBhc3RlZENoYXIuc3BsaXQoJycpLCBmdW5jdGlvbiAoY2hhcmFjdGVyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2lzVmFsaWRDaGFyKGNoYXJhY3Rlcik7CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIGlmIChhbGxQYXN0ZWRDaGFyc1ZhbGlkKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gZHVyaW5nIHBhc3RlIHdlIHN1cHBvcnQgYm90aCBoYWxmIHdpZHRoLCBmdWxsIHdpZHRoIGFuZCBsb2NhbGUgc3BlY2lmaWMgbnVtYmVycwogICAgICAgICAgICAgICAgICAgIHBhc3RlZENoYXIgPSB0aGlzLl90b0xhdGluRm9ybShwYXN0ZWRDaGFyKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVLZXlJbnB1dChldmVudCwgcGFzdGVkQ2hhciwgMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmICghZXZlbnQuY3RybEtleSkgewogICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwKCiAgICBfaGFuZGxlQ3V0IDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICBpZiAoZXZlbnQpIHsKICAgICAgICAgICAgdGhpcy5faGFuZGxlS2V5SW5wdXQoZXZlbnQsICIiLCAwKTsKICAgICAgICB9CiAgICB9LAogICAgLy8gQ1EtMTA3ODg2IDogYWRkZWQgaGFuZGxpbmcgZm9yIG5lZ2F0aXZlIHZhbHVlcywgYXMgZm9yICctJywgJy0zJyB3YXMgZ2V0dGluZyByZXR1cm5lZAogICAgX2NvbnZlcnRWYWx1ZVRvTG9jYWxlOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICB2YXIgemVyb0NvZGUgPSB0aGlzLm9wdGlvbnMuemVyby5jaGFyQ29kZUF0KDApOwogICAgICAgIHJldHVybiAgXy5tYXAodmFsLGZ1bmN0aW9uKGMpIHsKICAgICAgICAgICAgaWYoYyA9PSAiLiIpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZGVjaW1hbDsKICAgICAgICAgICAgfSBlbHNlIGlmKGMgPT0gIi0iKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLm1pbnVzOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUocGFyc2VJbnQoYykgKyB6ZXJvQ29kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LHRoaXMpLmpvaW4oIiIpOwogICAgfSwKCiAgICBfY29udmVydFZhbHVlRnJvbUxvY2FsZTogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgdmFsID0gdGhpcy5fdG9MYXRpbkZvcm0odmFsKTsKICAgICAgICB2YXIgemVyb0NvZGUgPSB0aGlzLm9wdGlvbnMuemVyby5jaGFyQ29kZUF0KDApOwogICAgICAgIHJldHVybiAgXy5tYXAodmFsLGZ1bmN0aW9uKGMpIHsKICAgICAgICAgICAgaWYoYyA9PSB0aGlzLm9wdGlvbnMuZGVjaW1hbCkgewogICAgICAgICAgICAgICAgcmV0dXJuICIuIjsKICAgICAgICAgICAgfSBlbHNlIGlmKGMgPT0gdGhpcy5vcHRpb25zLm1pbnVzKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIi0iOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIChjLmNoYXJDb2RlQXQoMCkgLSB6ZXJvQ29kZSkudG9TdHJpbmcoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sdGhpcykuam9pbigiIik7CiAgICB9LAoKICAgIHNob3dWYWx1ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgLy8gaWYgdGhlIHZhbHVlIGlzIHNhbWUsIGRvbid0IGRvIGFueXRoaW5nCiAgICAgICBpZighdGhpcy5faXNWYWx1ZVNhbWUoKSl7CiAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLnZhbHVlICYmIHRoaXMuX3dyaXR0ZW5JbkxvY2FsZSkgewogICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC52YWwodGhpcy5fY29udmVydFZhbHVlVG9Mb2NhbGUodGhpcy5vcHRpb25zLnZhbHVlKSkKICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC52YWwodGhpcy5vcHRpb25zLnZhbHVlKQogICAgICAgICAgIH0KICAgICAgIH0KICAgICAgIC8vSUUgZG9lc24ndCBzaG93IHNlbGVjdGVkIHRleHQgaWYgd2UgZm9jdXMgYW5kIHNldCBpdHMgdmFsdWUgYWxsIHRoZSB0aW1lIHNvIGZvcmNlIHNlbGVjdGlvbgogICAgICAgJC54ZmFXaWRnZXQudGV4dEZpZWxkLnByb3RvdHlwZS5fc2VsZWN0T25Gb2N1c0luSUUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgIH0KfSk7Cn0pKCQsIHdpbmRvdy5fKTsoZnVuY3Rpb24gKCQsIF8pIHsKICAgICQud2lkZ2V0KCJ4ZmFXaWRnZXQuZHJvcERvd25MaXN0IiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgeyAgICAgICAgICAgIC8vY29tbWl0RXZlbnQ6IGNoYW5nZTsgY29tbWl0UHJvcGVydHk6IHZhbHVlPEFycmF5PgoKICAgICAgICBfd2lkZ2V0TmFtZTogImRyb3BEb3duTGlzdCIsCgogICAgICAgIG9wdGlvbnM6IHsKICAgICAgICAgICAgdmFsdWU6IFtdLAogICAgICAgICAgICBpdGVtczogW10sCiAgICAgICAgICAgIGVkaXRhYmxlOiBmYWxzZSwKICAgICAgICAgICAgcGxhY2Vob2xkZXI6ICIiLAogICAgICAgICAgICBkaXNwbGF5VmFsdWU6IFtdCiAgICAgICAgfSwKCiAgICAgICAgd2lkZ2V0U2tlbGV0b246ICc8c2VsZWN0IG5hbWU9IiIgc3R5bGU9IiIgc2l6ZSA9ICIxIj48L3NlbGVjdD4nLAogICAgICAgIG9wdGlvblNrZWxldG9uOiAnPG9wdGlvbiBkYXRhLXVzZXItb3B0aW9uPjwvb3B0aW9uPicsCiAgICAgICAgb3B0R3JvdXBTa2VsZXRvbjogJzxvcHRncm91cCBsYWJlbD0iIj48L29wdGdyb3VwPicsCiAgICAgICAgQUZfT1BUR1JPVVBfTkFNRTogImFmT3B0R3JvdXBOYW1lIiwKICAgICAgICBQTEFDRV9IT0xERVJfU1RZTEVfQ0xBU1MgOiAicGxhY2VIb2xkZXIiLAoKICAgICAgICBnZXRPcHRpb25zTWFwOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0T3B0aW9uc01hcC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICByZXR1cm4gJC5leHRlbmQoe30sIHBhcmVudE9wdGlvbnNNYXAsIHsKICAgICAgICAgICAgICAgICJ2YWx1ZSI6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIV8uaXNBcnJheSh2YWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA9IFt2YWxdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWRPcHRpb25Gb3VuZCA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICB0aGF0ID0gdGhpczsKICAgICAgICAgICAgICAgICAgICAvL3N5bmMgb3B0aW9uIHNlbGVjdGlvbiBhcyBwZXIgbmV3IHZhbHVlcwogICAgICAgICAgICAgICAgICAgICQoIm9wdGlvbiIsIHRoaXMuJHVzZXJDb250cm9sKS5lYWNoKGZ1bmN0aW9uIChpbmRleCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0VmFsdWUgPSAkKHRoaXMpLnZhbCgpOwogICAgICAgICAgICAgICAgICAgICAgICAvL0NoZWNrIGlmIHRoaXMgdmFsdWUgaXMgcHJlc2VudCBpbiBvcHRpb25zIHZhbHVlIGFycmF5CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfLmNvbnRhaW5zKHZhbCwgc2VsZWN0VmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLnByb3AoInNlbGVjdGVkIiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZE9wdGlvbkZvdW5kID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcykucHJvcCgic2VsZWN0ZWQiLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pZCA9PT0gImVtcHR5VmFsdWUiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS52YWwoIiIpLmh0bWwodGhhdC5vcHRpb25zLnBsYWNlaG9sZGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0hpZGluZyBlbXB0eVZhbHVlIHdpdGggbm8gcGxhY2Vob2xkZXIgdGV4dCBjb25maWd1cmVkLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoYXQub3B0aW9ucy5wbGFjZWhvbGRlci5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLmhpZGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgLyogQWRkIGRlZmF1bHQgb3B0aW9uIGlmIDoKICAgICAgICAgICAgICAgICAgICAvIDEuIElmIHBsYWNlaG9sZGVyIGFkZCBhbiBleHRyYSBvcHRpb24KICAgICAgICAgICAgICAgICAgICAvIDIuIElmIHRoZSB2YWx1ZSBpcyBzZXQgYW55dGhpbmcgb3RoZXIgdGhhbiB0aGUgb3B0aW9ucyAoYW5kIG51bGwvIiIpIGNyZWF0ZSBhIG5ldyBvcHRpb24KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoKCFzZWxlY3RlZE9wdGlvbkZvdW5kICYmIHZhbC5sZW5ndGggIT0gMCAmJiB2YWxbMF0gIT0gbnVsbCkgfHwgdGhhdC5vcHRpb25zLnBsYWNlaG9sZGVyLmxlbmd0aCAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLiR1c2VyQ29udHJvbC5jaGlsZHJlbignW2RhdGEtZW1wdHktb3B0aW9uXScpLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXh0cmFPcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJvcHRpb24iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhT3B0aW9uLnNldEF0dHJpYnV0ZSgiZGF0YS1lbXB0eS1vcHRpb24iLCAiIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyYU9wdGlvbi5zZXRBdHRyaWJ1dGUoInJvbGUiLCAibm9uZSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFPcHRpb24uc2V0QXR0cmlidXRlKCJ2YWx1ZSIsICIiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2xbMF0uaW5zZXJ0QmVmb3JlKGV4dHJhT3B0aW9uLCB0aGlzLiR1c2VyQ29udHJvbFswXS5maXJzdENoaWxkKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBwbGFjZWhvbGRlciBpcyBwcmVzZW50IHRoZSBzZXQgdmFsdWUgb2YgZW1wdHkgb3B0aW9uIHRvIHBsYWNlaG9sZGVyCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGF0Lm9wdGlvbnMucGxhY2Vob2xkZXIubGVuZ3RoICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCdbZGF0YS1lbXB0eS1vcHRpb25dJykudGV4dCh0aGF0Lm9wdGlvbnMucGxhY2Vob2xkZXIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHBsYWNlaG9sZGVyIGlzIHByZXNlbnQgYW5kIHZhbHVlIGlzIG5vdCBwcmVzZW50IHRoZW4gc2VsZWN0IHBsYWNlaG9sZGVyCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWwubGVuZ3RoID09IDAgfHwgdmFsWzBdID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCdbZGF0YS1lbXB0eS1vcHRpb25dJykucHJvcCgic2VsZWN0ZWQiLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSAvLyBJZiB2YWx1ZSBpcyBzZXQgYW55dGhpbmcgb3RoZXIgdGhhbiBvcHRpb24gdGhlbiBzZXQgZW1wdHkgb3B0aW9uIHRvIHZhbHVlCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzZWxlY3RlZE9wdGlvbkZvdW5kICYmIHZhbC5sZW5ndGggIT0gMCAmJiB2YWxbMF0gIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oJ1tkYXRhLWVtcHR5LW9wdGlvbl0nKS50ZXh0KHZhbFswXSkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wKCJzZWxlY3RlZCIsIHRydWUpLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsKF8uZXNjYXBlKHZhbFswXSkpLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvdygpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGF0Lm9wdGlvbnMucGxhY2Vob2xkZXIubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRlIGRlZmF1bHQgb3B0aW9uIGlmIHZhbHVlIGlzIGZvdW5kIGluIG9wdGlvbnMgd2hpbGUgYWRkaW5nIG9wdGlvbnMKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkT3B0aW9uRm91bmQgJiYgdGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oJ1tkYXRhLWVtcHR5LW9wdGlvbl0nKS52YWwoKSAhPSB0aGF0Lm9wdGlvbnMuZGlzcGxheVZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oJ1tkYXRhLWVtcHR5LW9wdGlvbl0nKS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2xbMF0ucmVtb3ZlQ2hpbGQodGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oJ1tkYXRhLWVtcHR5LW9wdGlvbl0nKVswXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVzZXQgdGhlIHZhbHVlIG9mIGRyb3Bkb3duIGJhc2VkIG9uIHJ1bGUKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoIXNlbGVjdGVkT3B0aW9uRm91bmQgJiYgKHZhbC5sZW5ndGggPT0gMCB8fCB2YWwgPT0gbnVsbCB8fCB2YWxbMF0gPT0gbnVsbCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sWzBdLnZhbHVlID0gIiI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wudG9nZ2xlQ2xhc3ModGhpcy5QTEFDRV9IT0xERVJfU1RZTEVfQ0xBU1MsIHZhbC5sZW5ndGggPT0gMCB8fCB2YWwgPT0gbnVsbCk7CiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgICJpdGVtcyI6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIV8uaXNBcnJheSh2YWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA9IFt2YWxdOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgdmFyIEFGX09QVEdST1VQX05BTUUgPSAiYWZPcHRHcm91cE5hbWUiOwogICAgICAgICAgICAgICAgICAgIHZhciBpLCBqLCBvcHRncm91cE9wdGlvbnMgPSBbXSwgZWxlbWVudCwgJHZpZXdPcHRncm91cCwgJHByZU9wdGdyb3VwOwogICAgICAgICAgICAgICAgICAgIHZhciB2aWV3T3B0Z3JvdXBzID0gJCgib3B0Z3JvdXAiLCB0aGlzLiR1c2VyQ29udHJvbCk7CiAgICAgICAgICAgICAgICAgICAgLy8gUmVtb3ZlcyBhbGwgb3B0aW9ucyB3aGljaCBlYXJsaWVyIGRpZG4ndCBiZWxvbmcgdG8gYW55IG9wdGdyb3VwLgogICAgICAgICAgICAgICAgICAgIGlmICh2aWV3T3B0Z3JvdXBzLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNhdmUgc2VsZWN0ZWQgdmFsdWUgYmVjYXVzZSB3aGVuIHZhbHVlIGlzIHNldCBiZWZvcmUgaXRlbXMgaW4gc2V0V2lkZ2V0T3B0aW9ucwogICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgc2VsZWN0ZWQgdmFsdWUgd291bGQgZ2V0IGxvc3QgaW4gaHRtbAogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWRPcHRpb24gPSB0aGlzLiR1c2VyQ29udHJvbC5maW5kKCdbc2VsZWN0ZWRdJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCJvcHRpb25bZGF0YS11c2VyLW9wdGlvbl0iKS5yZW1vdmUoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMCwgaiA9IDA7IGogPCB2YWwubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudCA9IHZhbFtqXTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQuc2F2ZSAhPSBBRl9PUFRHUk9VUF9OQU1FKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgb3B0aW9ucyB0byBTdHJpbmdbXSB3aGljaCB3aWxsIGJlIGxhdGVyIHN5bmNlZCB0byB0aGUgb3B0Z3JvdXAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRncm91cE9wdGlvbnMucHVzaChlbGVtZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2aWV3T3B0Z3JvdXAgPSB2aWV3T3B0Z3JvdXBzW2krK107CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIG9wdGdyb3VwIGlzIGxlc3MgdGhhbiB0aGUgcmVxdWlyZWQgb3B0Z3JvdXBzLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiB2aWV3T3B0Z3JvdXBzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR2aWV3T3B0Z3JvdXAgPSB0aGlzLmFkZEdyb3VwKGVsZW1lbnQuZGlzcGxheSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBVbmRlZmluZWQgYXMgaXQgbWF5IG5vdCBvY2N1ciBldmVuIG9uY2Ugd2hlbiBsaXN0IGlzIHB1cmVseSBvZiBvcHRpb25zLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKCR2aWV3T3B0Z3JvdXApICYmICR2aWV3T3B0Z3JvdXAubGFiZWwgIT0gZWxlbWVudC5kaXNwbGF5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHZpZXdPcHRncm91cC5sYWJlbCA9IGVsZW1lbnQuZGlzcGxheSB8fCAnJzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIHRvIHNraXAgdGhlIGZpcnN0IG9wdGdyb3VwLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGogIT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN5bmNzIG9wdGlvbnMgdG8gdGhlIHByZXYgb3B0Z3JvdXAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUHJldiBvcHRncm91cCBiZWNhdXNlIGN1cnJlbnQgb3B0Z3JvdXAgbWFya3MgdGhlIGVuZCBvZiBvcHRpb25zIG9mIHByZXYuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVPcHRpb25zKCRwcmVPcHRncm91cCwgb3B0Z3JvdXBPcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDbGVhciBvcHRpb25zIG9mIHRoZSBvcHRncm91cCBmb3IgbmV4dCBvcHRncm91cC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRncm91cE9wdGlvbnMgPSBbXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRwcmVPcHRncm91cCA9ICR2aWV3T3B0Z3JvdXA7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gUmVtb3ZlcyBhbGwgZXh0cmEgb3B0Z3JvdXBzLgogICAgICAgICAgICAgICAgICAgIHdoaWxlIChpIDwgdmlld09wdGdyb3Vwcy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHZpZXdPcHRncm91cCA9IHZpZXdPcHRncm91cHNbaSsrXTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWxldGVHcm91cCgkdmlld09wdGdyb3VwLmxhYmVsKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy9BZGQgcmVtYWluaW5nIG9wdGlvbnMgdG8gcmVzcGVjdGl2ZSBvcHRncm91cC4KICAgICAgICAgICAgICAgICAgICBpZiAob3B0Z3JvdXBPcHRpb25zLmxlbmd0aCAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlT3B0aW9ucygkcHJlT3B0Z3JvdXAsIG9wdGdyb3VwT3B0aW9ucywgc2VsZWN0ZWRPcHRpb24pOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy9JbnRlbnRpb25hbGx5IGxlZnQgdGhlIHNlbGVjdGlvbiBjaGVjayAtPiBJIGFtIHJlbHlpbmcgb24gdGhlIGZhY3QgdGhhdCAidmFsdWUiIHN5bmMgZXZlbnQgaXMgY2FsbGVkIGFmdGVyICJpdGVtcyIgc3luYy4KICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgImRpc3BsYXlWYWx1ZSI6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAicGxhY2Vob2xkZXIiOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICAgICAgLy8gb3ZlcnJpZGluZyB0aGUgZGVmYXVsdCBoYW5kbGluZyBvZiBwbGFjZSBob2xkZXIgb3B0aW9ucyBzZXR0ZXIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiYWNjZXNzIjogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIm9wZW4iIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJhcmlhLWRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJhcmlhLXJlYWRvbmx5Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3B0aW9ucyA9IHRoaXMuJHVzZXJDb250cm9sWzBdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYob3B0aW9ucyAmJiBvcHRpb25zLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLmVhY2godGhpcy4kdXNlckNvbnRyb2xbMF0sIGZ1bmN0aW9uIChlbGVtZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCJkaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIm5vbkludGVyYWN0aXZlIiA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInByb3RlY3RlZCIgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW4gY2FzZSBvZiBub25JbnRlcmFjdGl2ZSBhbmQgcHJvdGVjdGVkLCBmaWVsZCBzaG91bGQgYmUgZGlzYWJsZWQgYW5kIGNhbm5vdCBiZSB0YWJiZWQuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJkaXNhYmxlZCIsICJkaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJyZWFkT25seSIgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiYXJpYS1kaXNhYmxlZCIsICJ0cnVlIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJhcmlhLXJlYWRvbmx5IiwgInRydWUiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcHRpb25zID0gdGhpcy4kdXNlckNvbnRyb2xbMF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihvcHRpb25zICYmIG9wdGlvbnMubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8uZWFjaCh0aGlzLiR1c2VyQ29udHJvbFswXSwgZnVuY3Rpb24gKGVsZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5kaXNhYmxlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCAgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQXR0cigiZGlzYWJsZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImFyaWEtZGlzYWJsZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImFyaWEtcmVhZG9ubHkiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSkKICAgICAgICB9LAoKICAgICAgICBnZXRFdmVudE1hcDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgcGFyZW50T3B0aW9uc01hcCA9ICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmdldEV2ZW50TWFwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSwgcGFyZW50T3B0aW9uc01hcCwgewogICAgICAgICAgICAgICAgImZvY3VzIjogW3hmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRU5URVJfRVZFTlQsIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfUFJFT1BFTl9FVkVOVF0sCiAgICAgICAgICAgICAgICAiY2hhbmdlIjogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQKICAgICAgICAgICAgfSkKICAgICAgICB9LAoKICAgICAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGV4aXN0aW5nSW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXMgPSB0aGlzLmVsZW1lbnQuZmluZCgic2VsZWN0IikuYXR0cigic3R5bGUiKSwKICAgICAgICAgICAgICAgIG5ld0lubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzLAogICAgICAgICAgICAgICAgY29tYmluZWRJbmxpbmVTdHlsZUF0dHJpYnV0ZVZhbHVlcywKICAgICAgICAgICAgICAgIHNpemUgPSAxOwoKICAgICAgICAgICAgdGhpcy5lbGVtZW50LmFkZENsYXNzKHRoaXMuX3dpZGdldE5hbWUpOwogICAgICAgICAgICB0aGlzLmVsZW1lbnQuY2hpbGRyZW4oKS5yZW1vdmUoKTsKCiAgICAgICAgICAgIHZhciBpbnB1dE5hbWUgPSBfLnVuaXF1ZUlkKCJzZWxlY3QiKSwgIC8vVW5pcXVlIElkCiAgICAgICAgICAgICAgICB0ZXh0U3R5bGUgPSB0aGlzLmdldE9yRWxzZSh0aGlzLiRkYXRhKHRoaXMuZWxlbWVudC5nZXQoMCksICJ4ZmFtb2RlbCIpLCAidGV4dHN0eWxlIiwgIiIpLAogICAgICAgICAgICAgICAgJHdpZGdldFNrZWxldG9uID0gJCh0aGlzLndpZGdldFNrZWxldG9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYXR0cignc3R5bGUnLCB0ZXh0U3R5bGUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCduYW1lJywgaW5wdXROYW1lKTsKICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLmVkaXRhYmxlKSB7CiAgICAgICAgICAgICAgICAkd2lkZ2V0U2tlbGV0b24uYWRkQ2xhc3MoJ2NvbWJvYm94Jyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5pdGVtcyAmJiB0aGlzLm9wdGlvbnMuaXRlbXMubGVuZ3RoPjApewogICAgICAgICAgICAgICAgc2l6ZSA9IHRoaXMub3B0aW9ucy5pdGVtcy5sZW5ndGgKICAgICAgICAgICAgfQogICAgICAgICAgICBpZih0aGlzLm9wdGlvbnMubXVsdGlTZWxlY3QpIHsKICAgICAgICAgICAgICAgICR3aWRnZXRTa2VsZXRvbi5hZGRDbGFzcygnbXVsdGlEcm9wZG93bicpOwogICAgICAgICAgICAgICAgJHdpZGdldFNrZWxldG9uLmF0dHIoJ211bHRpcGxlJywnbXVsdGlwbGUnKTsKICAgICAgICAgICAgICAgICR3aWRnZXRTa2VsZXRvbi5hdHRyKCdzaXplJyxzaXplKTsKICAgICAgICAgICAgICAgICR3aWRnZXRTa2VsZXRvbi5hdHRyKCdkYXRhLW11bHRpcGxlLXNlbGVjdGlvbicsInRydWUiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyICRwYXJFbCA9ICR3aWRnZXRTa2VsZXRvbjsKICAgICAgICAgICAgXy5lYWNoKHRoaXMub3B0aW9ucy5pdGVtcywgZnVuY3Rpb24oaXRlbSl7CiAgICAgICAgICAgICAgICB2YXIgc2F2ZUl0ZW0gPSBfLmlzU3RyaW5nKGl0ZW0uc2F2ZSkgPyBpdGVtLnNhdmUucmVwbGFjZSgvXCIvZywgIiZxdW90OyIpIDogIiI7CiAgICAgICAgICAgICAgICBpZiAoc2F2ZUl0ZW0gPT09IHRoaXMuQUZfT1BUR1JPVVBfTkFNRSl7IC8vIGFzc3VtaW5nIG9wdGdyb3VwcyBhcHBlYXIgYmVmb3JlIG9wdGlvbnMKICAgICAgICAgICAgICAgICAgICAkcGFyRWwgPSAkKHRoaXMub3B0R3JvdXBTa2VsZXRvbikuYXR0cignbGFiZWwnLCBpdGVtLmRpc3BsYXkpLmFwcGVuZFRvKCR3aWRnZXRTa2VsZXRvbik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICQodGhpcy5vcHRpb25Ta2VsZXRvbikudmFsKHNhdmVJdGVtKS50ZXh0KGl0ZW0uZGlzcGxheSkuYXBwZW5kVG8oJHBhckVsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSx0aGlzKTsKCiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmQoJHdpZGdldFNrZWxldG9uKTsKCiAgICAgICAgICAgIHZhciBjb250cm9sID0gdGhpcy5lbGVtZW50LmNoaWxkcmVuKCkuZXEoMCkuYXR0cigibmFtZSIsIHRoaXMub3B0aW9ucy5uYW1lKTsKICAgICAgICAgICAgdGhpcy5fYXR0YWNoRXZlbnRIYW5kbGVycyhjb250cm9sKTsKICAgICAgICAgICAgbmV3SW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXMgPSB0aGlzLmVsZW1lbnQuZmluZCgic2VsZWN0IikuYXR0cigic3R5bGUiKTsKICAgICAgICAgICAgLy9hcHBlbmQgdGhlIHByZXZpb3VzIGlubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzIHRvIG5ld0lubGluZVN0eWxlQXR0cmlidXRlVmFsdWVzIHNvIHRoYXQgdGhlIGlubGluZSBzdHlsZXMKICAgICAgICAgICAgLy9hZGRlZCBmcm9tIHRoZSBkaWFsb2cgYXJlIGFwcGxpZWQuCiAgICAgICAgICAgIGNvbWJpbmVkSW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXMgPSBuZXdJbmxpbmVTdHlsZUF0dHJpYnV0ZVZhbHVlcyArIGV4aXN0aW5nSW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXM7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5maW5kKCJzZWxlY3QiKS5hdHRyKCJzdHlsZSIsIGNvbWJpbmVkSW5saW5lU3R5bGVBdHRyaWJ1dGVWYWx1ZXMpOwogICAgICAgICAgICByZXR1cm4gY29udHJvbDsKICAgICAgICB9LAoKICAgICAgICAvL3N5bmNzIHRoZSBvcHRpb25zIHRvIHRoZSBvcHRncm91cCBkeW5hbWljYWxseS4KICAgICAgICBoYW5kbGVPcHRpb25zIDogZnVuY3Rpb24gKCR2aWV3T3B0Z3JvdXAsIHZhbCwgc2VsZWN0ZWRPcHRpb24pIHsKICAgICAgICAgICAgLy9XaGVuIHRoZSBsaXN0IHNvIGZhciBjb25zaXN0cyBwdXJlbHkgb2Ygb3B0aW9ucy4KICAgICAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoJHZpZXdPcHRncm91cCkpIHsKICAgICAgICAgICAgICAgICR2aWV3T3B0Z3JvdXAgPSB0aGlzLiR1c2VyQ29udHJvbFswXTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgdmlld09wdGlvbnMgPSAkKCJvcHRpb25bZGF0YS11c2VyLW9wdGlvbl0iLCAkdmlld09wdGdyb3VwKTsKICAgICAgICAgICAgLy9TeW5jcyB0aGUgdmFsdWUgb2Ygb3B0aW9ucy4KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGogPSAwOyBpIDwgdmlld09wdGlvbnMubGVuZ3RoICYmIGogPCB2YWwubGVuZ3RoOyBpKyssIGorKykgewogICAgICAgICAgICAgICAgdmFyICR2aWV3T3B0aW9uID0gdmlld09wdGlvbnNbaV07CiAgICAgICAgICAgICAgICB2YXIgZWxlbWVudCA9IHZhbFtqXTsKICAgICAgICAgICAgICAgIGlmICgkdmlld09wdGlvbi50ZXh0ICE9IGVsZW1lbnQuZGlzcGxheSkgewogICAgICAgICAgICAgICAgICAgICR2aWV3T3B0aW9uLnRleHQgPSBlbGVtZW50LmRpc3BsYXkgfHwgJyc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJHZpZXdPcHRpb24udmFsdWUgIT0gZWxlbWVudC5zYXZlKSB7CiAgICAgICAgICAgICAgICAgICAgJHZpZXdPcHRpb24udmFsdWUgPSBlbGVtZW50LnNhdmUgfHwgJyc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9EZWxldGVzIG9wdGlvbnMgaWYgY291bnQgaXMgbW9yZSB0aGFuIHJlcXVpcmVkLgogICAgICAgICAgICB3aGlsZSAoaSA8IHZpZXdPcHRpb25zLmxlbmd0aCkgewogICAgICAgICAgICAgICAgdGhpcy5kZWxldGVPcHRpb24odmlld09wdGlvbnNbaSsrXSkKICAgICAgICAgICAgfQogICAgICAgICAgICAvL0FkZCBvcHRpb25zIGlmIGNvdW50IGlzIGxlc3MgdGhhbiByZXF1aXJlZC4KICAgICAgICAgICAgd2hpbGUgKGogPCB2YWwubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICB0aGlzLmFkZE9wdGlvbigkdmlld09wdGdyb3VwLCB2YWxbaisrXSwgc2VsZWN0ZWRPcHRpb24pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFNldCBlbXB0eSB2YWx1ZSB0byBkcm9wZG93biBpZiBwbGFjZWhvbGRlciBhbmQgZGVmYXVsdCB2YWx1ZSBpcyBub3QgcHJlc2VudAogICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnBsYWNlaG9sZGVyLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgIAlpZiAodGhpcy5jaGVja0ZvckVtcHR5VmFsdWUodGhpcy5vcHRpb25zLnZhbHVlKSkgewogICAgICAgICAgICAJCXRoaXMuJHVzZXJDb250cm9sWzBdLnZhbHVlID0gIiI7CiAgICAgICAgICAgIAl9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gc2luY2Ugb3B0aW9ucyBhcmUgcmVtb3ZlZCBhbmQgYWRkZWQgYWdhaW4gZHVyaW5nIGl0ZW1zIHdlIG5lZWQgdG8gc2V0IHRoZSBhY2Nlc3MgYWdhaW4gb3B0aW9ucy4KICAgICAgICAgICAgdGhpcy5vcHRpb25zSGFuZGxlclsiYWNjZXNzIl0uYXBwbHkodGhpcywgW3RoaXMub3B0aW9uc1siYWNjZXNzIl1dKTsKICAgICAgICB9LAoKICAgICAgICBhZGRPcHRpb24gOiBmdW5jdGlvbiAoJHZpZXdPcHRncm91cCwgZWxlbWVudCwgc2VsZWN0ZWRPcHRpb24pIHsKICAgICAgICAgICAgdmFyICRuZXdPcHRpb24gPSAkKHRoaXMub3B0aW9uU2tlbGV0b24pLnZhbChlbGVtZW50LnNhdmUpLnRleHQoZWxlbWVudC5kaXNwbGF5KTsKICAgICAgICAgICAgJG5ld09wdGlvbi5hcHBlbmRUbygkdmlld09wdGdyb3VwKTsKICAgICAgICAgICAgaWYoc2VsZWN0ZWRPcHRpb24pIHsKICAgICAgICAgICAgICAgIGlmKGVsZW1lbnQuc2F2ZSA9PT0gc2VsZWN0ZWRPcHRpb24udmFsKCkgJiYgZWxlbWVudC5kaXNwbGF5ID09PSBzZWxlY3RlZE9wdGlvbi50ZXh0KCkpIHsKICAgICAgICAgICAgICAgICAgICAkbmV3T3B0aW9uLnByb3AoInNlbGVjdGVkIiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gU2luY2UgdGhlIGRpc3BsYXlWYWx1ZSBpcyBhICdcbicgc2VwYXJhdGVkIHN0cmluZyBvZiBzZWxlY3RlZCB2YWx1ZXMgaW4gY2FzZSBvZiBtdWx0aVNlbGVjdCwKICAgICAgICAgICAgLy8gd2UgY29udmVydCBpdCB0byBhbiBhcnJheSBhbmQgY2hlY2sgd2hldGhlciB0aGF0IGFycmF5IGNvbnRhaW5zIHRoZSBzYXZlIHZhbHVlIG9mIHRoZSBlbGVtZW50CiAgICAgICAgICAgIHZhciB2YWx1ZXM7CiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMudmFsdWUgJiYgXy5pc1N0cmluZyh0aGlzLm9wdGlvbnMudmFsdWUpKSB7CiAgICAgICAgICAgICAgICB2YWx1ZXMgPSB0aGlzLm9wdGlvbnMudmFsdWUuc3BsaXQoJ1xuJyk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoXy5pc0FycmF5KHRoaXMub3B0aW9ucy52YWx1ZSkpIHsKICAgICAgICAgICAgICAgIC8vIEluIHRoZSBjYXNlIG9mIEFGIHdlIGhhdmUgdmFsdWUvZGlzcGxheVZhbHVlIGFzIGFuIGFycmF5CiAgICAgICAgICAgICAgICB2YWx1ZXMgPSB0aGlzLm9wdGlvbnMudmFsdWUKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodmFsdWVzICYmIHZhbHVlcy5pbmRleE9mKGVsZW1lbnQuc2F2ZSkgPj0gMCkgewogICAgICAgICAgICAgICAgLy9EZWxldGUgZW1wdHlWYWx1ZSB3aXRoIG5vIHBsYWNlaG9sZGVyIHRleHQgY29uZmlndXJlZCBhbmQgdmFsdWUgaXMgZm91bmQgaW4gb3B0aW9ucwogICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wbGFjZWhvbGRlci5sZW5ndGggPT0gMCAmJiB0aGlzLiR1c2VyQ29udHJvbC5jaGlsZHJlbignW2RhdGEtZW1wdHktb3B0aW9uXScpLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbFswXS5yZW1vdmVDaGlsZCh0aGlzLiR1c2VyQ29udHJvbC5jaGlsZHJlbignW2RhdGEtZW1wdHktb3B0aW9uXScpWzBdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCkuZmlsdGVyKGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlID09IGVsZW1lbnQuc2F2ZTsKICAgICAgICAgICAgICAgIH0pLnByb3AoInNlbGVjdGVkIiwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBkZWxldGVPcHRpb246IGZ1bmN0aW9uICgkdmlld09wdGlvbikgewogICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5maW5kKCdvcHRpb25bdmFsdWU9Jyskdmlld09wdGlvbi52YWx1ZSsnXScpLnJlbW92ZSgpOwogICAgICAgIH0sCgogICAgICAgIGNoZWNrRm9yRW1wdHlWYWx1ZTogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgaWYgKCh2YWx1ZSAmJiBfLmlzQXJyYXkodmFsdWUpICYmIHZhbHVlWzBdID09IG51bGwpIHx8ICh0aGlzLm9wdGlvbnMudmFsdWUgPT0gbnVsbCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIGFkZEdyb3VwOiBmdW5jdGlvbihsYWJlbCkgewogICAgICAgICAgICAvL0NyZWF0ZXMgYSBvcHRncm91cCBOb2RlLgogICAgICAgICAgICB2YXIgb3B0aW9uR3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJPUFRHUk9VUCIpOwogICAgICAgICAgICBvcHRpb25Hcm91cC5sYWJlbCA9IGxhYmVsOwogICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbFswXS5hcHBlbmRDaGlsZChvcHRpb25Hcm91cCk7CiAgICAgICAgICAgIHJldHVybiBvcHRpb25Hcm91cDsKICAgICAgICB9LAoKICAgICAgICBkZWxldGVHcm91cDogZnVuY3Rpb24obGFiZWwpIHsKICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oKS5yZW1vdmUoJ29wdGdyb3VwW2xhYmVsPScrbGFiZWwrJ10nKTsKICAgICAgICB9LAoKICAgICAgICBhZGRJdGVtOiBmdW5jdGlvbihpdGVtVmFsdWVzKSB7CiAgICAgICAgICAgIHZhciBuZXdPcHRpb24gPSBuZXcgT3B0aW9uKGl0ZW1WYWx1ZXMuc0Rpc3BsYXlWYWwgfHwgJycsIGl0ZW1WYWx1ZXMuc1NhdmVWYWwgfHwgJycpLAogICAgICAgICAgICAgICAgdmFsID0gdGhpcy5vcHRpb25zLnZhbHVlOwogICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbFswXS5hZGQobmV3T3B0aW9uLCBudWxsKTsKICAgICAgICAgICAgLy8gaWYgaXRlbSBoYXMgc2FtZSB2YWx1ZSBhcyBwcmVzZW50IGluIG9wdGlvbnMgdGhlbiBtYXJrIGl0IGFzIHNlbGVjdGVkCiAgICAgICAgICAgIGlmIChfLmNvbnRhaW5zKHZhbCwgaXRlbVZhbHVlcy5zU2F2ZVZhbCkpIHsKICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmZpbmQoIm9wdGlvblt2YWx1ZT0iICsgaXRlbVZhbHVlcy5zU2F2ZVZhbCArICJdIikucHJvcCgic2VsZWN0ZWQiLCB0cnVlKTsKICAgICAgICAgICAgICAgIHZhciBlbXB0eVZhbHVlID0gdGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oJ1tkYXRhLWVtcHR5LW9wdGlvbl0nKTsKICAgICAgICAgICAgICAgIGlmIChlbXB0eVZhbHVlLmxlbmd0aCA+IDAgJiYgZW1wdHlWYWx1ZS52YWwoKSA9PT0gaXRlbVZhbHVlcy5zU2F2ZVZhbCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sWzBdLnJlbW92ZUNoaWxkKGVtcHR5VmFsdWVbMF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKCh2YWwgPT0gbnVsbCB8fCB2YWwubGVuZ3RoID09IDAgfHwgdmFsWzBdID09IG51bGwpICYmIHRoaXMub3B0aW9ucy5wbGFjZWhvbGRlci5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgLy8gVmFsdWUgc2hvdWxkIHJlbWFpbiBlbXB0eSBpZiBvcHRpb24gaXMgbm90IGFscmVhZHkgc2VsZWN0ZWQgJiBwbGFjZWhvbGRlciBpcyBlbXB0eQogICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2xbMF0udmFsdWUgPSAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNsZWFySXRlbXM6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgLy9EZWxldGluZyBhbGwgdGhlIG9wdGlvbnMgaW5jbHVkaW5nIG9wdEdyb3VwIGV4Y2VwdCB0aGUgZW1wdHkgdmFsdWUuCiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCkubm90KCdbZGF0YS1lbXB0eS1vcHRpb25dJykucmVtb3ZlKCk7CiAgICAgICAgfSwKCiAgICAgICAgZGVsZXRlSXRlbTogZnVuY3Rpb24gKG5JbmRleCkgewogICAgICAgICAgICAvL2NoZWNrIGZvciBlbXB0eVZhbHVlIGluc3RlYWQgb2YgYmxpbmRseSBkb2luZyArIDEKICAgICAgICAgICAgaWYgKHRoaXMuJHVzZXJDb250cm9sWzBdLml0ZW0oMCkgJiYgdGhpcy4kdXNlckNvbnRyb2xbMF0uaXRlbSgwKS5pZCA9PSAiZW1wdHlWYWx1ZSIpCiAgICAgICAgICAgICAgICBuSW5kZXggPSBuSW5kZXggKyAxOwogICAgICAgICAgICAvL2lmIHRoZXJlIGlzIGVtcHR5VmFsdWUgZWxlbWVudCB0aGVuIGp1c3QgZGVsZXRlIG9uZSBpbmRleCBoaWdoZXIKICAgICAgICAgICAgLy90aGlzIGNoZWNrIGlzIG11c3QgaW5zdGVhZCBvZiBibGluZGx5IGluY3JlYXNpbmcgdGhlIGluZGV4IGJ5IDEgYmVjYXVzZSBOV0tMaXN0Qm94IGV4dGVuZHMgdGhpcyBjbGFzcyBhbmQgdGhhdCBkb2Vzbid0IG1haW50YWluIGVtcHR5VmFsdWUKICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2xbMF0ucmVtb3ZlKG5JbmRleCk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0Q29tbWl0VmFsdWU6IGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICB2YXIgdmFsdWUgPSAkKCJvcHRpb246c2VsZWN0ZWQiLCB0aGlzLiR1c2VyQ29udHJvbCkubWFwKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiAkKHRoaXMpLnZhbCgpOwogICAgICAgICAgICB9KS5nZXQoKTsKICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgIH0sCgogICAgICAgIHNob3dEaXNwbGF5VmFsdWU6IGZ1bmN0aW9uICgpIHsKICAgICAgICB9LAoKICAgICAgICBkZXN0cm95OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuZWxlbWVudC4KICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKHRoaXMuX3dpZGdldE5hbWUpLgogICAgICAgICAgICAgICAgY2hpbGRyZW4oKS5yZW1vdmUoKS4KICAgICAgICAgICAgICAgIHRleHQoIiIpOwoKICAgICAgICAgICAgLy8gY2FsbCB0aGUgYmFzZSBkZXN0cm95IGZ1bmN0aW9uCiAgICAgICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmRlc3Ryb3kuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlS2V5RG93bjogZnVuY3Rpb24gKGV2ZW50KSB7CgogICAgICAgICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PSAxMykgewogICAgICAgICAgICAgICAgLy9kbyBub3RoaW5nCiAgICAgICAgICAgICAgICAvL2p1c3Qgb3ZlcnJpZGUgdGhlIHJldHVybiBrZXkgYmVoYXZpb3VyIGFuZCBvdmVyIHRvIGRlZmF1bHRXaWRnZXQgZm9yIHJlc3Qgb2YgdGhlIHN0dWZmLgogICAgICAgICAgICAgICAgLy9yZXR1cm4ga2V5IGlzIGludGVyY2VwdGVkIHRvIGF2b2lkIHN1Ym1pc3Npb24gb2YgZm9ybSB3aGljaCBpcyBkZWZhdWx0IGJlaGF2aW9yIG9mIGh0bWwgZm9ybSBlbGVtZW50CiAgICAgICAgICAgICAgICAvL2J1dCBhcyBhIHNpZGUgZWZmZWN0IGl0IGFsc28gc3RvcHMgdGhlIGNsb3Npbmcgb2YgZHJvcCBkb3duIG9ubHkgaW4gSUUgLT4gcHJvYmFibHkgSSBzaG91bGQgdXNlIElFIGNvbmRpdGlvbiBidXQKICAgICAgICAgICAgICAgIC8vIHRoaXMgY29kZSB3b3JrcyBmaW5lIGluICAgICAgICAgIGNocm9tZSBhcyB3ZWxsIHNvIGtlZXBpbmcgaXQgdGhhdCB3YXkuCiAgICAgICAgICAgICAgICAvL3dhdHNvbiBidWcjMzY3NTE0MQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLl9oYW5kbGVLZXlEb3duLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfSwKCiAgICAgICAgLy8gQ1EtNTE0NjIgOiBmb2N1cyBhbmQgY29tbWl0IGV2ZW50IChjaGFuZ2UpIGhhcHBlbiB0b2dldGhlciBoZW5jZSBmaXJzdCBzZWxlY3Rpb24gd2FzIG1vZGlmeWluZyB0aGUgdmFsdWUKICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCBmb2N1cyB0byBtb2RpZnkgdGhlIHZhbHVlIHRoYXQgaXMgYWJvdXQgdG8gYmUgY29tbWl0dGVkCiAgICAgICAgc2hvd1ZhbHVlIDogZnVuY3Rpb24oKSB7CgogICAgICAgIH0KICAgIH0pOwp9KSgkLCBfKTsKKGZ1bmN0aW9uKCQsIF8pewoJJC53aWRnZXQoICJ4ZmFXaWRnZXQubGlzdEJveCIsICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQsIHsKCiAgICBfd2lkZ2V0TmFtZTogImxpc3RCb3hXaWRnZXQiLAoKICAgIG9wdGlvbnMgOiB7CiAgICAgICAgdmFsdWUgOiBbXSwKICAgICAgICBpdGVtcyA6IFtdLAogICAgICAgIG11bHRpU2VsZWN0IDogZmFsc2UKICAgIH0sCgogICAgZ2V0T3B0aW9uc01hcDogZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICByZXR1cm4gJC5leHRlbmQoe30scGFyZW50T3B0aW9uc01hcCx7CiAgICAgICAgICAgICJ3aWR0aCIgOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgIC8vQnVnIzM1OTc3NzEuIHNldHRpbmcgdGhlIGhlaWdodCBtb3JlIHRoYW4gMC45NSBicmluZ3Mgc2Nyb2xsYmFyCiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMud2lkdGggPSB2YWwqMC45NQogICAgICAgICAgICAgICAgcGFyZW50T3B0aW9uc01hcC53aWR0aC5hcHBseSh0aGlzLFt0aGlzLm9wdGlvbnMud2lkdGhdKQogICAgICAgICAgICB9LAogICAgICAgICAgICAiYWNjZXNzIiA6IGZ1bmN0aW9uKCkge30sCiAgICAgICAgICAgICJ2YWx1ZSI6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAgICAgdmFyIG5ld1ZhbHVlcyA9IHRoaXMub3B0aW9ucy52YWx1ZSwKICAgICAgICAgICAgICAgICAgICBzZWxmID0gdGhpcywKICAgICAgICAgICAgICAgICAgICB0YWJTZXQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGlmKCFfLmlzQXJyYXkobmV3VmFsdWVzKSkKICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZXMgPSBbbmV3VmFsdWVzXTsKICAgICAgICAgICAgICAgIHZhciB0YWJTZXQKICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpewogICAgICAgICAgICAgICAgICAgIHZhciBzYXZlVmFsID0gJCh0aGlzKS5hdHRyKCJkYXRhLXNhdmUiKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyB2YWx1ZSBpcyBwcmVzZW50IGluIG9wdGlvbnMgdmFsdWUgYXJyYXkKICAgICAgICAgICAgICAgICAgICBpZihuZXdWYWx1ZXMgJiYgXy5jb250YWlucyhuZXdWYWx1ZXMsIHNhdmVWYWwpKXsKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fc2VsZWN0TGlzdEl0ZW0oJCh0aGlzKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhYlNldCA9IHRydWU7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIHNlbGVjdGVkIGRhdGEgYXR0cmlidXRlIHRvIHRydWUuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghJC5kYXRhKHRoaXMsICJfeGZhSW5pdGlhbGl6ZWQiKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9Jbml0aWFsaXplZCBkYXRhLSBhdHRyaWJ1dGVzIHBhcnNlIGZvciBvbmNlIHVzaW5nIHRoaXMgY2FsbC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5leHQgb253YXJkIGRvbid0IHVzZSB0aGlzLiBJbnN0ZWFkIHVzZSAkLmRhdGEgd2hpY2ggaXMgY2hlYXAvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLmRhdGEoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQuZGF0YSh0aGlzLCAiX3hmYUluaXRpYWxpemVkIiwgdHJ1ZSk7IC8vTWFyayB0aGUgZWxlbWVudCB0byBzYXkgdGhhdCBkYXRhIGhhcyBiZWVuIGluaXRpYWxpemVkLgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICQuZGF0YSh0aGlzLCAic2VsZWN0ZWQiLCB0cnVlKTsKCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcykucmVtb3ZlQ2xhc3MoIml0ZW0tc2VsZWN0ZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5hZGRDbGFzcygiaXRlbS1zZWxlY3RhYmxlIik7CiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcykuYXR0cigidGFiSW5kZXgiLCAiLTEiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGlmKCF0YWJTZXQpIHsKICAgICAgICAgICAgICAgICAgICAkKHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCkuZ2V0KDApKS5hdHRyKCJ0YWJJbmRleCIsIHRoaXMub3B0aW9ucy50YWJJbmRleCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAiaXRlbXMiIDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgICAgICBpZighXy5pc0FycmF5KHZhbCkpCiAgICAgICAgICAgICAgICAgICAgdmFsID0gW3ZhbF07CiAgICAgICAgICAgICAgICB2YXIgdmlld0l0ZW1zID0gdGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oKTsKCiAgICAgICAgICAgICAgICAvL2lmIG51bWJlciBvZiBpdGVtcyBhcmUgbm90IHNhbWUgaW4gbW9kZWwgYW5kIHZpZXcgdGhlbiBiYWxhbmNlIGl0CiAgICAgICAgICAgICAgICBpZigodmlld0l0ZW1zLmxlbmd0aCkgPiB2YWwubGVuZ3RoKXsKICAgICAgICAgICAgICAgICAgICBmb3IodmFyIGk9dmlld0l0ZW1zLmxlbmd0aDsgaSA+ICB2YWwubGVuZ3RoOyBpLS0pewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlbGV0ZUl0ZW0oaS0xKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKCh2aWV3SXRlbXMubGVuZ3RoKSA8IHZhbC5sZW5ndGgpewogICAgICAgICAgICAgICAgICAgIGZvcih2YXIgaT12aWV3SXRlbXMubGVuZ3RoOyBpIDwgKHZhbC5sZW5ndGgpOyBpKyspewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZEl0ZW0oe3NEaXNwbGF5VmFsOiB2YWxbaV0uZGlzcGxheSwgc1NhdmVWYWw6IHZhbFtpXS5zYXZlfSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIF8uZWFjaCh2YWwsIGZ1bmN0aW9uKGVsZW1lbnQsIGluZGV4KXsKICAgICAgICAgICAgICAgICAgICB2YXIgJHZpZXdJdGVtID0gJCh2aWV3SXRlbXNbaW5kZXhdKTsKICAgICAgICAgICAgICAgICAgICBpZiggJHZpZXdJdGVtLnRleHQoKSAhPSBlbGVtZW50LmRpc3BsYXkpewogICAgICAgICAgICAgICAgICAgICAgICAkdmlld0l0ZW0udGV4dChlbGVtZW50LmRpc3BsYXkgfHwgJycpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYoICR2aWV3SXRlbS5hdHRyKCJkYXRhLXNhdmUiKSAhPSBlbGVtZW50LnNhdmUpewogICAgICAgICAgICAgICAgICAgICAgICAkdmlld0l0ZW0uYXR0cigiZGF0YS1zYXZlIiwgZWxlbWVudC5zYXZlIHx8ICcnKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAvL0ludGVudGlvbmFsbHkgbGVmdCB0aGUgc2VsZWN0aW9uIGNoZWNrIC0+IEkgYW0gcmVseWluZyBvbiB0aGUgZmFjdCB0aGF0ICJ2YWx1ZSIgc3luYyBldmVudCBpcyBjYWxsZWQgYWZ0ZXIgIml0ZW1zIiBzeW5jLgogICAgICAgICAgICB9LAoKICAgICAgICAgICAgImRpc3BsYXlWYWx1ZSIgOiBmdW5jdGlvbigpezt9LAoKICAgICAgICAgICAgInRhYkluZGV4IjogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWRJdGVtID0gdGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oIi5pdGVtLXNlbGVjdGVkIiksCiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPXRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCkKICAgICAgICAgICAgICAgIGlmKHNlbGVjdGVkSXRlbS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEl0ZW0uZXEoMCkuYXR0cigidGFiSW5kZXgiLCB0aGlzLm9wdGlvbnMudGFiSW5kZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZihjaGlsZHJlbi5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4uZXEoMCkuYXR0cigidGFiSW5kZXgiLCB0aGlzLm9wdGlvbnMudGFiSW5kZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSkKICAgIH0sCgogICAgZ2V0RXZlbnRNYXA6IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0RXZlbnRNYXAuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSxwYXJlbnRPcHRpb25zTWFwLHsKICAgICAgICAgICAgImxpc3Rib3hlbnRlciI6eGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FTlRFUl9FVkVOVCwKICAgICAgICAgICAgImxpc3Rib3hleGl0Ijp4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VYSVRfRVZFTlQsCiAgICAgICAgICAgICJsaXN0Ym94Y2hhbmdlIjp4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NIQU5HRV9FVkVOVCwKICAgICAgICAgICAgImZvY3VzIjpudWxsLAogICAgICAgICAgICAiYmx1ciI6bnVsbAogICAgICAgIH0pCiAgICB9LAoKICAgIHNob3dEaXNwbGF5VmFsdWUgOiBmdW5jdGlvbigpIHsKICAgICAgICB9LAoKICAgIHJlbmRlciA6IGZ1bmN0aW9uKCkgewogICAgICAgIHRoaXMuZWxlbWVudC5hZGRDbGFzcyggdGhpcy5fd2lkZ2V0TmFtZSk7CiAgICAgICAgdGhpcy5lbGVtZW50LmNoaWxkcmVuKCkucmVtb3ZlKCk7CgogICAgICAgIC8vVE9ETzogYWRkIGEgZnVuY3Rpb24gZm9yIGdldGluZyB0ZXh0U3R5bGUKICAgICAgICB2YXIgdGV4dFN0eWxlID0gdGhpcy5nZXRPckVsc2UodGhpcy4kZGF0YSh0aGlzLmVsZW1lbnQuZ2V0KDApLCAieGZhbW9kZWwiKSwgInRleHRzdHlsZSIsICIiKSwKICAgICAgICAgICAgdGhhdCA9IHRoaXMsCiAgICAgICAgICAgIC8vQnVnIzM1OTc3NzEgd2lkdGggYW5kIGhlaWdodCBhcmUgcHJvdmlkZWQgYnkgdGhlIHZpZXcgaXRzZWxmLgogICAgICAgICAgICBsaXN0RWxUZW1wbGF0ZSA9CiAgICAgICAgICAgICc8b2wgc3R5bGU9InBvc2l0aW9uOmFic29sdXRlOzwlPXRleHRTdHlsZSU+IiByb2xlPSJsaXN0Ym94Ij4nICsKICAgICAgICAgICAgICAgICc8JSBfLmVhY2goaXRlbXMsIGZ1bmN0aW9uKGl0ZW0peyAlPicgKwogICAgICAgICAgICAgICAgJzwlIHZhciBzYXZlSXRlbSA9IGl0ZW0uc2F2ZSA/IGl0ZW0uc2F2ZS5yZXBsYWNlKC9cIi9nLCImcXVvdDsiKTpudWxsICU+JysKICAgICAgICAgICAgICAgICAgICAnPGxpIHJvbGU9Im9wdGlvbiIgZGF0YS1zYXZlPSI8JSBwcmludChzYXZlSXRlbSkgJT4iIGRhdGEtc2VsZWN0ZWQ9ImZhbHNlIj48JSBwcmludChpdGVtLmRpc3BsYXkpICU+PC9saT4nKwogICAgICAgICAgICAgICAgJzwlfSklPicrCiAgICAgICAgICAgICc8L29sPicsCiAgICAgICAgICAgIGNvbXBpbGVkTGlzdEVsVGVtcGxhdGUgPSBfLnRlbXBsYXRlKGxpc3RFbFRlbXBsYXRlKSwKICAgICAgICAgICAgdGVtcGxhdGVPcHRpb25zID0gXy5leHRlbmQoewogICAgICAgICAgICAgICAgInRleHRTdHlsZSIgOiB0ZXh0U3R5bGUKICAgICAgICAgICAgICAgIH0sIHRoaXMub3B0aW9ucyksCiAgICAgICAgICAgIHJlc29sdmVkTGlzdEVsID0gY29tcGlsZWRMaXN0RWxUZW1wbGF0ZSh0ZW1wbGF0ZU9wdGlvbnMpOwogICAgICAgIHRoYXQuZWxlbWVudC5odG1sKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5lbmNvZGVTY3JpcHRhYmxlVGFncyhyZXNvbHZlZExpc3RFbCkpOwogICAgICAgIHZhciBjb250cm9sID0gJCh0aGF0LmVsZW1lbnQuY2hpbGRyZW4oKS5nZXQoMCkpLmF0dHIoIm5hbWUiLHRoaXMub3B0aW9ucy5uYW1lKTsKICAgICAgICB0aGlzLl9hdHRhY2hFdmVudEhhbmRsZXJzKGNvbnRyb2wpOwogICAgICAgIHJldHVybiBjb250cm9sCiAgICB9LAoKICAgIGZvY3VzOiBmdW5jdGlvbigpIHsKICAgICAgICBpZih0aGlzLiR1c2VyQ29udHJvbC5jaGlsZHJlbigiLml0ZW0tc2VsZWN0ZWQiKS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKCIuaXRlbS1zZWxlY3RlZCIpWzBdLmZvY3VzKCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYodGhpcy4kdXNlckNvbnRyb2wuY2hpbGRyZW4oKS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNoaWxkcmVuKClbMF0uZm9jdXMoKTsKICAgICAgICB9CiAgICB9LAoKICAgIGFkZEl0ZW0gOiBmdW5jdGlvbihpdGVtVmFsdWVzKXsKICAgICAgICAkKCI8bGk+PC9saT4iKQogICAgICAgICAgICAuYXR0cigiZGF0YS1zYXZlIiwgaXRlbVZhbHVlcy5zU2F2ZVZhbCB8fCAnJykKICAgICAgICAgICAgLnRleHQoaXRlbVZhbHVlcy5zRGlzcGxheVZhbCB8fCAnJykKICAgICAgICAgICAgLmFwcGVuZFRvKHRoaXMuJHVzZXJDb250cm9sKQogICAgICAgICAgICAuY2xpY2soJC5wcm94eSh0aGlzLl9oYW5kbGVJdGVtQ2xpY2ssIHRoaXMpKQogICAgICAgICAgICAuZm9jdXMoJC5wcm94eSh0aGlzLl9oYW5kbGVJdGVtRm9jdXMsIHRoaXMpKTsKCiAgICAgICAgLy8gYWRkIG5ldyBpdGVtIGFzIHNlbGVjdGVkIGlmIHRoZSB2YWx1ZSBpcyBhbHJlYWR5IHByZXNlbnQgaW4gb3B0aW9ucwogICAgICAgIGlmIChfLmNvbnRhaW5zKHRoaXMub3B0aW9ucy52YWx1ZSwgaXRlbVZhbHVlcy5zU2F2ZVZhbCkpIHsKICAgICAgICAgICAgdGhpcy5fc2VsZWN0TGlzdEl0ZW0odGhpcy4kdXNlckNvbnRyb2wuZmluZCgiW2RhdGEtc2F2ZT0iICsgaXRlbVZhbHVlcy5zU2F2ZVZhbCsgIl0iKSk7CiAgICAgICAgfQogICAgfSwKCiAgICBjbGVhckl0ZW1zIDogZnVuY3Rpb24oKXsKICAgICAgICAkKHRoaXMuJHVzZXJDb250cm9sKS5lbXB0eSgpOwogICAgfSwKCiAgICBkZWxldGVJdGVtIDogZnVuY3Rpb24obkluZGV4KXsKICAgICAgICAkKHRoaXMuJHVzZXJDb250cm9sKS5jaGlsZHJlbignbGknKS5lYWNoKGZ1bmN0aW9uKGluZGV4LGVsZW1lbnQpewogICAgICAgICAgICBpZihpbmRleD09bkluZGV4KXsKICAgICAgICAgICAgICAgICQoZWxlbWVudCkub2ZmKCJjbGljayIpLm9mZigiZm9jdXMiKS5yZW1vdmUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0pCiAgICB9LAoKCiAgICBfYXR0YWNoRXZlbnRIYW5kbGVycyA6IGZ1bmN0aW9uKCRjb250cm9sKXsKICAgICAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICAgICAgJGNvbnRyb2wua2V5ZG93bigkLnByb3h5KHRoaXMuX2hvdEtleXMsdGhpcykpCiAgICAgICAgICAgIC5jaGlsZHJlbigpLm9uKCJtb3VzZWRvd24iLGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIGlmKHNlbGYuaW5Gb2N1cyA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubW91c2VEb3duID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICAuY2xpY2soJC5wcm94eSh0aGlzLl9oYW5kbGVJdGVtQ2xpY2ssIHRoaXMpKQogICAgICAgICAgICAuZm9jdXMoJC5wcm94eSh0aGlzLl9oYW5kbGVJdGVtRm9jdXMsIHRoaXMpKQogICAgICAgICAgICAuYmx1cigkLnByb3h5KHRoaXMuX2hhbmRsZUZvY3VzT3V0LHRoaXMpKQoKICAgIH0sCgogICAgIF9ob3RLZXlzIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICBpZih0aGlzLm9wdGlvbnMuYWNjZXNzICE9ICJvcGVuIikKICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgaWYodGhpcy5pdGVtSW5Gb2N1cyl7CiAgICAgICAgICAgICBzd2l0Y2goZXZlbnQud2hpY2gpIHsKICAgICAgICAgICAgICAgICBjYXNlIDM4OiAvL2Fycm93IHVwCiAgICAgICAgICAgICAgICAgICAgIHZhciBwcmV2U2libGluZyA9ICQodGhpcy5pdGVtSW5Gb2N1cykucHJldigpOwogICAgICAgICAgICAgICAgICAgICBpZihwcmV2U2libGluZyl7CiAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmtleURvd24gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgcHJldlNpYmxpbmcuZm9jdXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMua2V5RG93biA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgIGNhc2UgNDA6IC8vYXJyb3cgZG93bgogICAgICAgICAgICAgICAgICAgICB2YXIgbmV4dFNpYmxpbmcgPSAkKHRoaXMuaXRlbUluRm9jdXMpLm5leHQoKTsKICAgICAgICAgICAgICAgICAgICAgaWYobmV4dFNpYmxpbmcpewogICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5rZXlEb3duID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRTaWJsaW5nLmZvY3VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmtleURvd24gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICBjYXNlIDkxOiAvL2xlZnQgYXJyb3cKICAgICAgICAgICAgICAgICBjYXNlIDkyOiAvL3JpZ2h0IGFycm93CiAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgIGNhc2UgMzI6CiAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3RvZ2dsZUl0ZW0odGhpcy5pdGVtSW5Gb2N1cyk7CiAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICB9CiAgICAgICAgIH0KICAgICB9LAoKICAgICBfdG9nZ2xlSXRlbTogZnVuY3Rpb24oaXRlbSkgewogICAgICAgICB2YXIgJGl0ZW0gPSAkKGl0ZW0pLAogICAgICAgICAgICAgbXVsdGlNb2RlID0gdGhpcy5vcHRpb25zLm11bHRpU2VsZWN0LCAvLyAmJiBldmVudC5jdHJsS2V5IDsKICAgICAgICAgICAgIHRoYXQgPSB0aGlzOwogICAgICAgICAgICAgLy90b2dnbGUgc2VsZWN0ZWQgc3RhdGUgb2YgdGhpcyBpdGVtCiAgICAgICAgICAgICB0aGlzLiRkYXRhKGl0ZW0sICJzZWxlY3RlZCIsICF0aGlzLiRkYXRhKGl0ZW0sICJzZWxlY3RlZCIpKTsKICAgICAgICAgdmFyIHN0YXRlID0gdGhpcy4kZGF0YShpdGVtLCAic2VsZWN0ZWQiKQoKICAgICAgICAgaWYoIW11bHRpTW9kZSkgewogICAgICAgICAgICAgdmFyICRzZWxlY3RlZEl0ZW0gPSB0aGlzLiR1c2VyQ29udHJvbC5jaGlsZHJlbigiLml0ZW0tc2VsZWN0ZWQiKQogICAgICAgICAgICAgaWYoJHNlbGVjdGVkSXRlbS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICB0aGlzLiRkYXRhKCRzZWxlY3RlZEl0ZW1bMF0sInNlbGVjdGVkIixmYWxzZSkKICAgICAgICAgICAgICAgICAkc2VsZWN0ZWRJdGVtLnJlbW92ZUNsYXNzKCJpdGVtLXNlbGVjdGVkIikuYWRkQ2xhc3MoIml0ZW0tc2VsZWN0YWJsZSIpCiAgICAgICAgICAgICB9CiAgICAgICAgIH0KICAgICAgICAgJGl0ZW0udG9nZ2xlQ2xhc3MoIml0ZW0tc2VsZWN0YWJsZSIsIXN0YXRlKS4KICAgICAgICAgICAgICAgdG9nZ2xlQ2xhc3MoIml0ZW0tc2VsZWN0ZWQiLHN0YXRlKQoKICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wudHJpZ2dlcigibGlzdGJveGNoYW5nZSIpOwogICAgIH0sCgogICAgIGdldENvbW1pdFZhbHVlOiBmdW5jdGlvbigpIHsKICAgICAgICAgdmFyIHRoYXQgPSB0aGlzLAogICAgICAgICAgICAgbXVsdGlNb2RlID0gdGhpcy5vcHRpb25zLm11bHRpU2VsZWN0OwoKCiAgICAgICAgIHJldHVybiB0aGlzLiR1c2VyQ29udHJvbC5jaGlsZHJlbigpLm1hcChmdW5jdGlvbigpewogICAgICAgICAgICAgLy8gaW50ZW50aW9uYWxseSB1c2luZyAkdGhpcy5hdHRyKCJkYXRhLXNhdmUiKSBpbnN0ZWFkIG9mICR0aGlzLmRhdGEoImRhdGEiKQogICAgICAgICAgICAgcmV0dXJuIHRoYXQuJGRhdGEodGhpcywgInNlbGVjdGVkIikgPyAkKHRoaXMpLmF0dHIoImRhdGEtc2F2ZSIpIDogbnVsbDsKICAgICAgICAgfSkuZ2V0KCk7CiAgICAgfSwKCiAgICAgIF9oYW5kbGVJdGVtRm9jdXMgOiBmdW5jdGlvbihldmVudCl7CiAgICAgICAgICBpZih0aGlzLm9wdGlvbnMuYWNjZXNzICE9ICJvcGVuIikKICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICB2YXIgaXRlbSA9IGV2ZW50LnRhcmdldDsKICAgICAgICAgIHRoaXMuaXRlbUluRm9jdXMgPSBpdGVtOwoKICAgICAgICAgIC8vIG92ZXJyaWRpbmcgZGVmYXVsdCB3aWRnZXRzIGhhbmRsZUZvY3VzCiAgICAgICAgICBpZighKHRoaXMua2V5RG93biB8fCB0aGlzLm1vdXNlRG93bikpIHsgICAgICAgIC8vd2UgZG8gbm90IG5lZWQgdG8gZmlyZSBmb2N1cyBldmVudCBpZgogICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXIoImxpc3Rib3hlbnRlciIpICAvLyBjbGlja2VkIG9uIGFub3RoZXIgbGkgZWxlbWVudCBvciBwcmVzc2VkIGEga2V5IHRvIG1vdmUgdGhlIHNlbGVjdGlvCiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1vdXNlRG93biA9IGZhbHNlOwogICAgICAgICAgdGhpcy5pbkZvY3VzID0gdHJ1ZTsKICAgICAgfSwKCiAgICAgX2hhbmRsZUl0ZW1DbGljayA6IGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAvLyBCdWcjMzUwMTgxMSBJZiBjbGlja2VkIG9ubGlzdGJveCBlbnRyeSBtb3JlIHRoYW4gb25jZSwgZXhpdCBldmVudCBpcyBub3QgZmlyZWQKICAgICAgICAvLyBDbGlja2luZyBvbiB0aGUgc2FtZSBlbnRyeSBkb2VzIG5vdCBjYWxsIGZvY3VzIGFuZCBoZW5jZSB3ZSB3ZXJlIG5vdCByZXNldHRpbmcgdGhlIHN0YXRlLiBEb2luZyBpdCBpbiBvbkNsaWNrCiAgICAgICAgaWYodGhpcy5tb3VzZURvd24gPT0gdHJ1ZSkKICAgICAgICAgICAgdGhpcy5tb3VzZURvd24gPSBmYWxzZTsKICAgICAgICBpZih0aGlzLm9wdGlvbnMuYWNjZXNzICE9ICJvcGVuIikKICAgICAgICAgICAgIHJldHVybjsKICAgICAgICB0aGlzLl90b2dnbGVJdGVtKGV2ZW50LnRhcmdldCkKICAgIH0sCgogICAgX2hhbmRsZUZvY3VzT3V0OiBmdW5jdGlvbigpewogICAgICAgIGlmKCEodGhpcy5rZXlEb3duIHx8IHRoaXMubW91c2VEb3duKSkgewogICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC50cmlnZ2VyKCJsaXN0Ym94ZXhpdCIpOwogICAgICAgICAgICB0aGlzLmluRm9jdXMgPSBmYWxzZQogICAgICAgIH0KICAgIH0sCgogICAgX3NlbGVjdExpc3RJdGVtIDogZnVuY3Rpb24gKCRlbGVtKSB7CiAgICAgICAgaWYgKCRlbGVtICYmICRlbGVtLmxlbmd0aCkgewogICAgICAgICAgICAkZWxlbS5yZW1vdmVDbGFzcygiaXRlbS1zZWxlY3RhYmxlIikKICAgICAgICAgICAgICAgIC5hZGRDbGFzcygiaXRlbS1zZWxlY3RlZCIpCiAgICAgICAgICAgICAgICAuYXR0cigidGFiSW5kZXgiLCB0aGlzLm9wdGlvbnMudGFiSW5kZXgpOwogICAgICAgIH0KICAgIH0sCgogICAgZGVzdHJveTogZnVuY3Rpb24oKSB7CiAgICAgICAgdGhpcy5lbGVtZW50LgogICAgICAgICAgICByZW1vdmVDbGFzcyh0aGlzLl93aWRnZXROYW1lKS4KICAgICAgICAgICAgY2hpbGRyZW4oKS5yZW1vdmUoKS4KICAgICAgICAgICAgdGV4dCgiIik7CgogICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmRlc3Ryb3kuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgIH0KfSk7Cn0pKCQsIHdpbmRvdy5fKTsKKGZ1bmN0aW9uKCQpIHsKICAgICQud2lkZ2V0KCAieGZhV2lkZ2V0Lm53a0xpc3RCb3giLCAgJC54ZmFXaWRnZXQuZHJvcERvd25MaXN0LCB7ICAgICAgICAgICAgLy9ub24td2Via2l0IGxpc3Rib3gKCiAgICAgICAgX3dpZGdldE5hbWUgOiAibndrTGlzdEJveCIsCgogICAgICAgIG9wdGlvbnMgOiB7CiAgICAgICAgICAgIHZhbHVlIDogW10sCiAgICAgICAgICAgIG11bHRpU2VsZWN0IDogZmFsc2UKICAgICAgICB9LAoKICAgICAgICByZW5kZXIgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyICRjb250cm9sID0gJC54ZmFXaWRnZXQuZHJvcERvd25MaXN0LnByb3RvdHlwZS5yZW5kZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgaWYoJGNvbnRyb2wpewogICAgICAgICAgICAgICAgJGNvbnRyb2wuY2hpbGRyZW4oIiNlbXB0eVZhbHVlIikucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICBpZih0aGlzLm9wdGlvbnMubXVsdGlTZWxlY3QpCiAgICAgICAgICAgICAgICAgICAgJGNvbnRyb2wuYXR0cigibXVsdGlwbGUiLCAibXVsdGlwbGUiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl91cGRhdGVTZWxlY3RTaXplKCRjb250cm9sKTsKICAgICAgICAgICAgcmV0dXJuICRjb250cm9sOwogICAgICAgIH0sCgogICAgICAgIGFkZEl0ZW0gOiBmdW5jdGlvbihpdGVtVmFsdWVzKXsKICAgICAgICAgICAgJC54ZmFXaWRnZXQuZHJvcERvd25MaXN0LnByb3RvdHlwZS5hZGRJdGVtLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdFNpemUoKTsKICAgICAgICB9LAoKICAgICAgICBjbGVhckl0ZW1zIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgJC54ZmFXaWRnZXQuZHJvcERvd25MaXN0LnByb3RvdHlwZS5jbGVhckl0ZW1zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdFNpemUoKTsKICAgICAgICB9LAoKICAgICAgICBkZWxldGVJdGVtIDogZnVuY3Rpb24obkluZGV4KXsKICAgICAgICAgICAgJC54ZmFXaWRnZXQuZHJvcERvd25MaXN0LnByb3RvdHlwZS5kZWxldGVJdGVtLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdFNpemUoKTsKICAgICAgICB9LAoKICAgICAgICBfdXBkYXRlU2VsZWN0U2l6ZSA6IGZ1bmN0aW9uKCRjb250cm9sKXsKICAgICAgICAgICAgJGNvbnRyb2wgPSAkY29udHJvbCB8fCB0aGlzLiR1c2VyQ29udHJvbDsKICAgICAgICAgICAgJGNvbnRyb2wuYXR0cigic2l6ZSIsICh0aGlzLm9wdGlvbnMuaXRlbXMgfHwgW10pLmxlbmd0aCk7CiAgICAgICAgfSwKCiAgICAgICAgLy8gQnVnIzM1OTc3NzEKICAgICAgICAvLyBmb2N1cyBhbmQgY29tbWl0IGV2ZW50IGhhcHBlbiB0b2dldGhlciBoZW5jZSBmaXJzdCBzZWxlY3Rpb24gd2FzIG1vZGlmeWluZyB0aGUgdmFsdWUKICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCBmb2N1cyB0byBtb2RpZnkgdGhlIHZhbHVlIHRoYXQgaXMgYWJvdXQgdG8gYmUgY29tbWl0dGVkCiAgICAgICAgc2hvd1ZhbHVlIDogZnVuY3Rpb24oKSB7CgogICAgICAgIH0KCiAgfSk7Cn0pKCQpOwooZnVuY3Rpb24gKCQpIHsKICAgICQud2lkZ2V0KCJ4ZmFXaWRnZXQueGZhQnV0dG9uIiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgeyAgICAgICAgICAgIC8vY29tbWl0RXZlbnQ6IGNoYW5nZTsgY29tbWl0UHJvcGVydHk6IHZhbHVlPEFycmF5PgoKICAgICAgICBfd2lkZ2V0TmFtZTogInhmYUJ1dHRvbiIsCgogICAgICAgIG9wdGlvbnM6IHsKICAgICAgICAgICAgdmFsdWU6IG51bGwsCiAgICAgICAgICAgIHN2Z0NhcHRpb246IGZhbHNlIC8vb3B0aW9uIHRvIGluZGljYXRlIGlmIGJ1dHRvbiBhbHJlYWR5IGhhcyBhbiBTVkcgY2FwdGlvbgogICAgICAgIH0sCgogICAgICAgIGdldE9wdGlvbnNNYXA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSwgcGFyZW50T3B0aW9uc01hcCwgewogICAgICAgICAgICAgICAgImFjY2VzcyI6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJvcGVuIiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJkaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQXR0cigiYXJpYS1kaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIm5vbkludGVyYWN0aXZlIiA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInByb3RlY3RlZCIgOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJyZWFkT25seSIgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiZGlzYWJsZWQiLCAiZGlzYWJsZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImFyaWEtZGlzYWJsZWQiLCAidHJ1ZSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJhcmlhLWRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInZhbHVlIjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJkaXNwbGF5VmFsdWUiOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInN2Z0NhcHRpb24iOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJ2YWx1ZSIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSkKICAgICAgICB9LAoKICAgICAgICBfYXR0YWNoRXZlbnRIYW5kbGVyczogZnVuY3Rpb24gKCRjb250cm9sKSB7CiAgICAgICAgICAgICRjb250cm9sLmNsaWNrKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHRoaXMuZm9jdXMoKQogICAgICAgICAgICB9KTsKICAgICAgICB9LAoKICAgICAgICBnZXRDb21taXRWYWx1ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnZhbHVlOwogICAgICAgIH0sCgogICAgICAgIHNob3dWYWx1ZTogZnVuY3Rpb24gKCkgewogICAgICAgIH0sCgogICAgICAgIHNob3dEaXNwbGF5VmFsdWU6IGZ1bmN0aW9uICgpIHsKICAgICAgICB9CiAgICB9KTsKfSkoJCk7KGZ1bmN0aW9uICgkKSB7CiAgICAkLndpZGdldCgieGZhV2lkZ2V0LlhmYUNoZWNrQm94IiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgeyAgICAgICAgICAgIC8vY29tbWl0RXZlbnQ6IGNoYW5nZTsgY29tbWl0UHJvcGVydHk6IHZhbHVlPEFycmF5PgoKICAgICAgICBfd2lkZ2V0TmFtZTogIlhmYUNoZWNrQm94IiwKCiAgICAgICAgb3B0aW9uczogewogICAgICAgICAgICB2YWx1ZTogbnVsbCwKICAgICAgICAgICAgc3RhdGU6IC0xLAogICAgICAgICAgICBzdGF0ZXM6IDIsCiAgICAgICAgICAgIHZhbHVlczogW10sCiAgICAgICAgICAgIG1hbmRhdG9yeTogZmFsc2UKICAgICAgICB9LAoKICAgICAgICBjaGVja2VkU3RhdGU6IGZhbHNlLAogICAgICAgIGNsaWNrUGVuZGluZzogZmFsc2UsCgogICAgICAgIGdldE9wdGlvbnNNYXA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSwgcGFyZW50T3B0aW9uc01hcCwgewogICAgICAgICAgICAgICAgImFjY2VzcyI6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJvcGVuIiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJkaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQXR0cigiYXJpYS1kaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIm5vbkludGVyYWN0aXZlIiA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInByb3RlY3RlZCIgOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJyZWFkT25seSIgOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiZGlzYWJsZWQiLCAiZGlzYWJsZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImFyaWEtZGlzYWJsZWQiLCAidHJ1ZSIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVBdHRyKCJhcmlhLWRpc2FibGVkIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgICJkaXNwbGF5VmFsdWUiOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cih0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHksIHRoaXMub3B0aW9ucy52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUodGhpcy5kSW5kZXhPZih0aGlzLm9wdGlvbnMudmFsdWVzLCB0aGlzLm9wdGlvbnMudmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJjaGVja2VkIiwgdGhpcy5jaGVja2VkU3RhdGUgPyAiY2hlY2tlZCIgOiBudWxsKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5wcm9wKCJjaGVja2VkIiwgdGhpcy5jaGVja2VkU3RhdGUgPyAiY2hlY2tlZCIgOiBudWxsKTsKICAgICAgICAgICAgICAgICAgICAvL2ZvciBhY2Nlc3NpYmlsaXR5CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiYXJpYS1jaGVja2VkIiwgdGhpcy5jaGVja2VkU3RhdGUpOwogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc3RhdGUgPT0gMikKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYWRkQ2xhc3MoIm5ldXRyYWwiKTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzLm9wdGlvbnMuc3RhdGVzID09IDMpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUNsYXNzKCJuZXV0cmFsIik7ICAgLy8gc2luY2UgY3VycmVudCBzdGF0ZSAhPSBuZXV0cmFsCiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgICJhbGxvd05ldXRyYWwiOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGludFZhbCA9IHBhcnNlSW50KHZhbCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGludFZhbCA9PSAwIHx8IGludFZhbCA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5zdGF0ZXMgPSAyICsgaW50VmFsOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgInBhcmFTdHlsZXMiOiBmdW5jdGlvbiAocGFyYVN0eWxlcykgewogICAgICAgICAgICAgICAgICAgIHBhcmVudE9wdGlvbnNNYXAucGFyYVN0eWxlcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVZBbGlnbk9uRXhpdCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KQogICAgICAgIH0sCgogICAgICAgIGdldEV2ZW50TWFwOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0RXZlbnRNYXAuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LCBwYXJlbnRPcHRpb25zTWFwLCB7CiAgICAgICAgICAgICAgICAgInhmYWNoZWNrYm94Y2hhbmdlIiA6ICB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0NIQU5HRV9FVkVOVCwKICAgICAgICAgICAgICAgICAieGZhY2hlY2tib3hjbGljayIgOiAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0xJQ0tfRVZFTlQsCiAgICAgICAgICAgICAgICAgImNoYW5nZSI6IG51bGwsCiAgICAgICAgICAgICAgICAgImNsaWNrIiA6IG51bGwKICAgICAgICAgICAgICAgfSkKICAgICAgICB9LAoKICAgICAgICBfYXR0YWNoRXZlbnRIYW5kbGVyczogZnVuY3Rpb24gKCRjb250cm9sKSB7CiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgdmFyIGZvY3VzRnVuYyA9IGZ1bmN0aW9uIChldm50KSB7CiAgICAgICAgICAgICAgICBpZiAoIXRoYXQuaW5Gb2N1cykgewogICAgICAgICAgICAgICAgICAgIHRoYXQuZm9jdXMoKTsKICAgICAgICAgICAgICAgICAgICB0aGF0LmluRm9jdXMgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBmb2N1c091dEZ1bmMgPSBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICAgICAgdGhhdC5pbkZvY3VzID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGNvbnRyb2wuY2xpY2soZm9jdXNGdW5jKS5jaGFuZ2UoZm9jdXNGdW5jKS5ibHVyKGZvY3VzT3V0RnVuYyk7CiAgICAgICAgICAgICRjb250cm9sLmNoYW5nZSgkLnByb3h5KHRoaXMuX2hhbmRsZUNoYW5nZSx0aGlzKSkuY2xpY2soJC5wcm94eSh0aGlzLl9oYW5kbGVDbGljayx0aGlzKSk7ICAgLy9MQy01MTA2CiAgICAgICAgfSwKCiAgICAgICAgZ2V0Q29tbWl0VmFsdWU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdGhpcy5fc3RhdGUoKHRoaXMub3B0aW9ucy5zdGF0ZSArIDEpICUgdGhpcy5vcHRpb25zLnN0YXRlcyk7CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImNoZWNrZWQiLCB0aGlzLmNoZWNrZWRTdGF0ZSA/ICJjaGVja2VkIiA6IG51bGwpOwogICAgICAgICAgICAvL2ZvciBhY2Nlc3NpYmlsaXR5CiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmF0dHIoImFyaWEtY2hlY2tlZCIsIHRoaXMuY2hlY2tlZFN0YXRlKQogICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnN0YXRlID09IDIpIHsKICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmFkZENsYXNzKCJuZXV0cmFsIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5vcHRpb25zLnN0YXRlcyA9PSAzKQogICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQ2xhc3MoIm5ldXRyYWwiKTsgLy8gc2luY2UgY3VycmVudCBzdGF0ZSAhPSBuZXV0cmFsCgogICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnZhbHVlc1t0aGlzLm9wdGlvbnMuc3RhdGVdOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVWQWxpZ25PbkV4aXQ6IGZ1bmN0aW9uIChldm50KSB7CiAgICAgICAgICAgIC8vLS10aGlzIGlzIGJlaW5nIGtlcHQgZW1wdHkgYXMgbm8gb3RoZXIgYnJvd3NlciAoaS5lIE1vemlsbGEgYW5kIENocm9tZSkgdGFrZSB0aGUgcGFkZGluZy1ib3R0b20gb3IgcGFkZGluZy10b3AgaW50byBhY2NvdW50LgogICAgICAgICAgICAvLyB0aGUgb25seSBicm93c2VyIHRvIHRha2UgaXQgaW50byBjb25zaWRlcmF0aW9uIGlzIElFLiBBbmQgbW9yZW92ZXIgdGhlIGFsaWdubWVudCBhbmQgcGFkZGluZyBjb25zaWRlcmF0aW9ucyBoYXZlIGFscmVhZHkgYmVlbiB0YWtlbiBpbnRvIGFjY291bnQgaW4KICAgICAgICAgICAgLy8gY2FsY3VsYXRpb25zIGluIENoZWNrQnV0dG9uRmllbGRWaWV3LmpzLiBBbmQgb24gcmVtb3ZpbmcgdGhlIGVudGlyZSBmdW5jdGlvbiBpdCB0YWtlcyB1cCB0aGUgX2hhbmRsZVZBbGlnbk9uRXhpdCgpIG9mIEFic3RyYWN0V2lkZ2V0LgoKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlQ2hhbmdlOiBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC50cmlnZ2VyKCJ4ZmFjaGVja2JveGNoYW5nZSIpOyAvL2NoYW5nZSBpcyBhbHdheXMgZmlyZWQKICAgICAgICAgICAgaWYodGhpcy5jbGlja1BlbmRpbmcgPT09IHRydWUpIHsKICAgICAgICAgICAgICB0aGlzLmNsaWNrUGVuZGluZyA9IGZhbHNlOwogICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXIoInhmYWNoZWNrYm94Y2xpY2siKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIGhhbmRsaW5nIG9mIHRoaXMuY2xpY2tQZW5kaW5nIGlzIGFkZGVkIHRvIGhhbmRsZSB0aGUgY2FzZSB3aGVuIGNsaWNrZWQgb24gY2hlY2tib3gvcmFkaW9idXR0b24gbGFiZWwvY2FwdGlvbgogICAgICAgICAgICAgICAgdGhpcy5jbGlja1BlbmRpbmcgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUNsaWNrOiBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICAgdmFyIGlzQ2hyb21lID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmRldGVjdENocm9tZSgpLAogICAgICAgICAgICAgICAgIGlzSUUgPSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZGV0ZWN0SUUoKSwKICAgICAgICAgICAgICAgICBpc1NhZmFyaSA9IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5pc1NhZmFyaSgpLAogICAgICAgICAgICAgICAgIHVzZXJDb250cm9sVHlwZSA9IHRoaXMuJHVzZXJDb250cm9sLmF0dHIoInR5cGUiKTsKICAgICAgICAgICAgIC8vIGNsaWNrIHdpbGwgbm90IGJlIGZpcmVkIGlmIHRoZSBwcmV2aW91cyBzdGF0ZSBvZiB0aGUgcmFkaW9idXR0b24gaXMgJ29uJy4KICAgICAgICAgICAgIC8vIE5QUi0zNTY1MiA6IENoZWNrYm94IG1vdmVtZW50IC0gQ2xpY2sgZXZlbnQgd29ya3MgZmluZSBvbiBjaHJvbWUgYnV0IG5vdCBpbiBpT1Mgc2FmYXJpIGZvciBjb2xsYXBzaWJsZSBmaWVsZHMKICAgICAgICAgICAgIC8vIENRLTEwMzAyMyA6IENsaWNrIEV2ZW50IG9uIFJhZGlvIEJ1dHRvbiBub3Qgd29ya2luZyBjb3JyZWN0bHkgaW4gQ2hyb21lIDUzCiAgICAgICAgICAgICAvLyBDUS0xMDM3MTUgOiBDUS0xMDM3MTUgOiBDbGljayBFdmVudCBvbiBDaGVjayBCb3ggbm90IHdvcmtpbmcgY29ycmVjdGx5IGluIENocm9tZSBhbmQgRmlyZWZveCwgYWRkZWQgaGFuZGxpbmcgZm9yIGNoZWNrYm94IGFsc28KICAgICAgICAgICAgIC8vIGhhbmRsaW5nIG9mIHRoaXMuY2xpY2tQZW5kaW5nIGlzIGFkZGVkIHRvIGhhbmRsZSB0aGUgY2FzZSB3aGVuIGNsaWNrZWQgb24gY2hlY2tib3gvcmFkaW9idXR0b24gbGFiZWwvY2FwdGlvbgogICAgICAgICAgICAgaWYoKCQuYnJvd3Nlci5tb3ppbGxhIHx8IGlzQ2hyb21lIHx8IGlzU2FmYXJpKSAmJiAhaXNJRSAmJiB0aGlzLmNsaWNrUGVuZGluZyA9PT0gZmFsc2UgJiYgKCh1c2VyQ29udHJvbFR5cGUgPT09ICJyYWRpbyIgJiYgdGhpcy5jaGVja2VkU3RhdGUgPT09IGZhbHNlKSB8fCAodXNlckNvbnRyb2xUeXBlID09PSAiY2hlY2tib3giKSkpIHsKICAgICAgICAgICAgICAgdGhpcy5jbGlja1BlbmRpbmcgPSB0cnVlOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC50cmlnZ2VyKCJ4ZmFjaGVja2JveGNsaWNrIik7CiAgICAgICAgICAgICAgICB0aGlzLmNsaWNrUGVuZGluZyA9IGZhbHNlOwogICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9zdGF0ZTogZnVuY3Rpb24gKG5ld1N0YXRlKSB7CiAgICAgICAgICAgIGlmIChuZXdTdGF0ZSA9PSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnN0YXRlOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuc3RhdGUgPSBuZXdTdGF0ZTsKICAgICAgICAgICAgdGhpcy5jaGVja2VkU3RhdGUgPSAobmV3U3RhdGUgPT0gMCB8fCBuZXdTdGF0ZSA9PSAyKTsKICAgICAgICB9LAoKICAgICAgICBjbGljazogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAvLyB0cmlnZ2VyIGNoYW5nZSBmb3IgY2hlY2sgYm94IGFuZCBmb3IgcmFkaW8gb25seSBpZiBpdCBpcyBub3Qgc2VsZWN0ZWQKICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHJhZGlvIGJ1dHRvbiB3aWxsIGdvIGluIGRlc2VsZWN0ZWQgc3RhdGUKICAgICAgICAgICAgaWYgKHRoaXMuJHVzZXJDb250cm9sLmF0dHIoInR5cGUiKSAhPT0gInJhZGlvIiB8fCB0aGlzLm9wdGlvbnMuc3RhdGUgIT09IDApIHsKICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXIoImNoYW5nZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vd2Ugc2hvdWxkIGNhbGwgb25seSB0aGUgaGFuZGxlciBzaW5jZSBjYWxsaW5nIGNsaWNrIHdpbGwgdHJpZ2dlciBjaGFuZ2UuCiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXJIYW5kbGVyKCJjbGljayIpOwogICAgICAgIH0KICAgIH0pOwp9KSgkKTsKKGZ1bmN0aW9uKCQsIF8pewogICAgJC53aWRnZXQoICJ4ZmFXaWRnZXQudGV4dEZpZWxkIiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgewoKICAgICAgICBfd2lkZ2V0TmFtZTogInRleHRGaWVsZCIsCgogICAgICAgIG9wdGlvbnM6IHsKICAgICAgICAgICAgY3VyVmFsdWUgOiBudWxsICwKICAgICAgICAgICAgcG9zOjAsCiAgICAgICAgICAgIGxlbmd0aExpbWl0VmlzaWJsZTogdHJ1ZSwKICAgICAgICAgICAgbWF4Q2hhcnM6MCAsCiAgICAgICAgICAgIGZsYWc6IiIsCiAgICAgICAgICAgIC8vIGJ5IGRlZmF1bHQgaHRtbDVUeXBlIGlzIHNldCB0byB0cnVlCiAgICAgICAgICAgIC8vIHdlIGxldmVyYWdlIHBhdHRlcm4sIG1heExlbmd0aCBzdXBwb3J0IGZyb20gSFRNTDUgYnJvd3NlciBmb3IgbW9iaWxlIGZvcm1zCiAgICAgICAgICAgIGh0bWw1VHlwZSA6ICJ0ZXh0IiwKICAgICAgICAgICAgbGVuZ3RoIDogbnVsbCwKICAgICAgICAgICAgbWluTGVuZ3RoIDogMCwKICAgICAgICAgICAgdG90YWxMZW5ndGhNZXNzYWdlIDogIiIsCiAgICAgICAgICAgIG1pbmltdW1MZW5ndGhNZXNzYWdlIDogIiIsCiAgICAgICAgfSwKCiAgICAgICAgZ2V0T3B0aW9uc01hcDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0T3B0aW9uc01hcC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSxwYXJlbnRPcHRpb25zTWFwLHsKICAgICAgICAgICAgICAgICJtYXhDaGFycyI6IGZ1bmN0aW9uKG1heGNoYXJzKSB7CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5fbWF4Q2hhcnNSZWFjaGVkKHRoaXMub3B0aW9ucy52YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5vcHRpb25zLnZhbHVlLnNsaWNlKDAsbWF4Y2hhcnMpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NldE9wdGlvbigidmFsdWUiLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NldE9wdGlvbigiZGlzcGxheVZhbHVlIiwgdmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgICJtdWx0aUxpbmUgIjogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLm11bHRpTGluZSkKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cigiYXJpYS1tdWx0aWxpbmUiLCAidHJ1ZSIpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQXR0cigiYXJpYS1tdWx0aWxpbmUiLCAiZmFsc2UiKTsKICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgImhlaWdodCI6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAgICAgICAgIGlmKHZhbCkgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLiR1c2VyQ29udHJvbFswXSx7ImhlaWdodCIgOnZhbH0pCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVZBbGlnbk9uRXhpdCgpOyAgICAvLyBUbyBIYW5kbGUgdGhlIGNhc2Ugb2YgZXhwYW5kYWJsZSBGaWVsZHMKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIndpZHRoIjogZnVuY3Rpb24odmFsKXsKICAgICAgICAgICAgICAgICAgICBwYXJlbnRPcHRpb25zTWFwLndpZHRoLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICAvLyBoYW5kbGUgdmFsaWduIG9uIHdpZHRoIGNoYW5nZSBhcyB3ZWxsCiAgICAgICAgICAgICAgICAgICAgLy8gYXMgY29udGVudCBoZWlnaHQoc2Nyb2xsSGVpZ2h0KSB2YXJpZXMgYWNjb3JkaW5nIHRvIHdpZHRoCiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlVkFsaWduT25FeGl0KCk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgInBhcmFTdHlsZXMiOiBmdW5jdGlvbihwYXJhU3R5bGVzKXsKICAgICAgICAgICAgICAgICAgICBwYXJlbnRPcHRpb25zTWFwLnBhcmFTdHlsZXMuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVZBbGlnbk9uRXhpdCgpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgfSkKICAgICAgICB9LAoKICAgICAgICByZW5kZXIgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIGNvbnRyb2wgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5yZW5kZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgLy8gdXNlIHRoZSBjb250cm9sIHRvIHNldCBIVE1MNSBhdHRyaWJ1dGVzCiAgICAgICAgICAgIGlmIChjb250cm9sICYmIGNvbnRyb2wubGVuZ3RoID4gMCAmJiB0aGlzLm9wdGlvbnMuaHRtbDVUeXBlKSB7CiAgICAgICAgICAgICAgICB2YXIgbWluTGVuZ3RoID0gdGhpcy5vcHRpb25zLm1pbkxlbmd0aCwKICAgICAgICAgICAgICAgICAgICBtYXhMZW5ndGggPSB0aGlzLm9wdGlvbnMubWF4Q2hhcnMsCiAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID0gdGhpcy5vcHRpb25zLmxlbmd0aDsKICAgICAgICAgICAgICAgICAgICBpc01pbkxlbmd0aFNldCA9IG1pbkxlbmd0aCAhPSBudWxsICYmIG1pbkxlbmd0aCA+IDAsCiAgICAgICAgICAgICAgICAgICAgaXNNYXhMZW5ndGhTZXQgPSBtYXhMZW5ndGggIT0gbnVsbCAmJiBtYXhMZW5ndGggPiAwLAogICAgICAgICAgICAgICAgICAgIGlzTGVuZ3RoU2V0ID0gbGVuZ3RoICE9IG51bGwgJiYgbGVuZ3RoID4gMCwKICAgICAgICAgICAgICAgICAgICBpc011bHRpbGluZSA9IHRoaXMub3B0aW9ucy5tdWx0aUxpbmUsCiAgICAgICAgICAgICAgICAgICAgbWluTGVuZ3RoTXNnID0gdGhpcy5vcHRpb25zLm1pbmltdW1MZW5ndGhNZXNzYWdlLAogICAgICAgICAgICAgICAgICAgIHRvdExlbmd0aE1zZyA9IHRoaXMub3B0aW9ucy50b3RhbExlbmd0aE1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgcGF0dGVybiA9ICIiOyAvLyBodG1sNSBwYXR0ZXJuIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHRleHRhcmVhCgogICAgICAgICAgICAgICAgLy8gb3JkZXIgb2YgZXhlY3V0aW9uIG1hdHRlcnMgZm9yIHRoZSBiZWxvdyBjb2RlIHNuaXBwZXQKICAgICAgICAgICAgICAgIGlmIChpc01pbkxlbmd0aFNldCkgewogICAgICAgICAgICAgICAgICAgIC8vIGFkZCBtaW5MZW5ndGggdGhvdWdoIGl0IGlzIG5vdCBmdWxseSBzdXBwb3J0ZWQgaW4gYWxsIGJyb3dzZXJzCiAgICAgICAgICAgICAgICAgICAgLy8gaGVuY2UgYWxzbyBhZGRpbmcgcGF0dGVybiBhdHRyaWJ1dGUKICAgICAgICAgICAgICAgICAgICBjb250cm9sLmF0dHIoIm1pbmxlbmd0aCIsIHBhcnNlSW50KG1pbkxlbmd0aCkpOwogICAgICAgICAgICAgICAgICAgIGlmKG1pbkxlbmd0aE1zZyAmJiBtaW5MZW5ndGhNc2cubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sLmF0dHIoInRpdGxlIiwgdGhpcy5vcHRpb25zLm1pbmltdW1MZW5ndGhNZXNzYWdlKTsgLy8gaHRtbDUgc3VwcG9ydGVkIG1lc3NhZ2Ugb24gcGF0dGVybiB2YWxpZGF0aW9uIGZhaWx1cmUKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGlzTWF4TGVuZ3RoU2V0KSB7CiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5hdHRyKCJtYXhsZW5ndGgiLCBwYXJzZUludChtYXhMZW5ndGgpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBpZiBib3RoIG1pbiBhbmQgbWF4IGxlbmd0aCBpcyBzZXQKICAgICAgICAgICAgICAgIGlmKGlzTWluTGVuZ3RoU2V0ICYmIGlzTWF4TGVuZ3RoU2V0KXsKICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuICs9ICIueyIgKyBtaW5MZW5ndGggKyAiLCIgKyBtYXhMZW5ndGggKyAifSI7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYoaXNNaW5MZW5ndGhTZXQpIHsKICAgICAgICAgICAgICAgICAgICAvLyBpZiBvbmx5IG1pbiBsZW5ndGggc2V0CiAgICAgICAgICAgICAgICAgICAgcGF0dGVybiArPSAiLnsiICsgbWluTGVuZ3RoICsgIix9IjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBpZiBsZW5ndGggaXMgc2V0IHRoZW4gc2V0IG1pbiBhbmQgbWF4IGxlbmd0aCBpbiBwYXR0ZXJuIGVxdWFsIHRvIGxlbmd0aAogICAgICAgICAgICAgICAgaWYgKGlzTGVuZ3RoU2V0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYoaXNNdWx0aWxpbmUpeyAvLyBzZXQgYm90aCBtaW4gYW5kIG1heGxlbmd0aCBhcyBwYXR0ZXJuIGlzIG5vdCBzdXBwb3J0ZWQKICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC5hdHRyKCJtaW5sZW5ndGgiLCBwYXJzZUludChsZW5ndGgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbC5hdHRyKCJtYXhsZW5ndGgiLCBwYXJzZUludChsZW5ndGgpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYodG90TGVuZ3RoTXNnICYmIHRvdExlbmd0aE1zZy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wuYXR0cigidGl0bGUiLCB0aGlzLm9wdGlvbnMudG90YWxMZW5ndGhNZXNzYWdlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLy8gcmVzZXQgdGhlIHBhdHRlcm4gc3RyaW5nCiAgICAgICAgICAgICAgICAgICAgcGF0dGVybiA9ICIueyIgKyBsZW5ndGggKyAiLCIgKyBsZW5ndGggKyAifSI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBpZiByZXF1aXJlZCBpcyBzZXQsIHNldCB0aGUgcmVxdWlyZWQgYXR0cmlidXRlLCBpdCBpcyBuZWNlc3NhcnkgZWxzZSBhbiBlbXB0eSB2YWx1ZSB3aWxsIGJlIGV4Y2x1ZGVkIGZyb20gY29uc3RyYWludCB2YWxpZGF0aW9uCiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLnJlcXVpcmVkKSB7CiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5hdHRyKCJyZXF1aXJlZCIsIHRydWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gc2V0IHRoZSBwYXR0ZXJuIGlmIG5vdCBlbXB0eSBhbmQgY2hlY2sgaWYgdGhpcyBpcyBub3QgbXVsdGlsaW5lLCBzaW5jZSBwYXR0ZXJuIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIHRleHRhcmVhCiAgICAgICAgICAgICAgICBpZiAocGF0dGVybiAmJiBwYXR0ZXJuLmxlbmd0aCA+IDAgJiYgIWlzTXVsdGlsaW5lKSB7CiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5hdHRyKCJwYXR0ZXJuIiwgcGF0dGVybik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGNvbnRyb2w7CiAgICAgICAgfSwKCiAgICAgICAgLyogIFRoaXMgZnVuY3Rpb24gYWxpZ25zIHZBbGlnbiB3aGVuOgogICAgICAgICAxLiBwYXJhc3R5bGVzIGlzIHByZXNlbnQgYW5kIHRoZSB3aWRnZXQgY29udGFpbnMgYSB2YWx1ZS4KICAgICAgICAgMi4gRHVyaW5nIGluaXRpYWwgcmVuZGVyaW5nIGlmIG5vIGNvbnRlbnQgcHJlc2VudCBmYWxsYmFjayB0byB0aGUgcHJldmlvdXMgbG9naWMuCiAgICAgICAgIDMuIFByZXNlbmNlIG9mIGNvbnRlbnQgaW4gd2lkZ2V0LgogICAgICAgICovCiAgICAgICAgX2hhbmRsZVZBbGlnbk9uRXhpdDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMub3B0aW9ucy5kaXNwbGF5VmFsdWUsCiAgICAgICAgICAgICAgICAgbm9Db250ZW50UHJlc2VudCA9IF8uaXNFbXB0eSh0aGlzLiR1c2VyQ29udHJvbC52YWwoKSB8fCB0aGlzLm9wdGlvbnMuZGlzcGxheVZhbHVlKSwKICAgICAgICAgICAgICAgICBjb250ZW50SGVpZ2h0LHdpZGdldEhlaWdodCxkaWZmLHRlbXBDU1M7CgogICAgICAgICAgICAgLy90aGUgd2lkZ2V0IGRvZXNuJ3QgaGF2ZSB2YWx1ZSBhcyB5ZXQgYnV0IGNvbnRlbnQgZXhpc3RzIFsgUmVuZGVyaW5nIG9mIHdpZGdldF0KICAgICAgICAgICAgIGlmICghdGhpcy5vcHRpb25zLnBhcmFTdHlsZXMgfHwgbm9Db250ZW50UHJlc2VudCkgewogICAgICAgICAgICAgICAgLy92QWxpZ24gaGFzIHRvIGJlIGhhbmRsZWQgb25seSBpZiB0aGVyZSBpcyBwYXJhU3R5bGVzIGFuZCB3aWRnZXQgaGFzIGNvbnRlbnQKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAvLyBtb3ppbGxhIHJlc3VsdHMgaW4gdkFsaWduIHJlZ3Jlc3Npb24gaGVuY2UgbWFkZSB0aGlzIGNoYW5nZSBvbmx5IGZvciB0ZXh0YXJlYQogICAgICAgICAgICAgaWYoJCh0aGlzLmVsZW1lbnRbMF0pLmZpbmQoInRleHRhcmVhIikubGVuZ3RoID4wICYmICFub0NvbnRlbnRQcmVzZW50KSAgewogICAgICAgICAgICAgICAvKiBtZWFzdXJlRXh0ZW50IG5vdCByZXR1cm5pbmcgY29ycmVjdCBoZWlnaHQgb2YgY29udGVudCBpbiB0ZXh0YXJlYSBldmVuIHdpdGggYWxsCiAgICAgICAgICAgICAgICAgY3NzIHZhbHVlcyAqLwogICAgICAgICAgICAgICB0ZW1wQ1NTPXsnaGVpZ2h0Jzp0aGlzLiR1c2VyQ29udHJvbC5jc3MoJ2hlaWdodCcpLCdwYWRkaW5nJzp0aGlzLiR1c2VyQ29udHJvbC5jc3MoJ3BhZGRpbmcnKX07CiAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLiR1c2VyQ29udHJvbFswXSx7J2hlaWdodCc6JzFweCcsJ3BhZGRpbmcnOicwcHgnfSk7CgogICAgICAgICAgICAgICBjb250ZW50SGVpZ2h0ID0gdGhpcy5fZ2V0Q29udGVudEhlaWdodCgpOwogICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy4kdXNlckNvbnRyb2xbMF0sdGVtcENTUyk7CiAgICAgICAgICAgICAgIHdpZGdldEhlaWdodCA9IHRoaXMub3B0aW9ucy5oZWlnaHQ7CiAgICAgICAgICAgICAgIGRpZmYgPSB3aWRnZXRIZWlnaHQgLSBjb250ZW50SGVpZ2h0OwogICAgICAgICAgICAgICB0aGlzLl9jYWxjdWxhdGVQYWRkaW5nRm9yVkFsaWduKGRpZmYpOwogICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIHdpZGdldCBoYXMgbm8gaW5pdGlhbCBjb250ZW50IG9yIGlzIGEgdGV4dGZpZWxkLlByb2NlZWQgYXMgYmVmb3JlLgogICAgICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuX2hhbmRsZVZBbGlnbk9uRXhpdC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RXZlbnRNYXA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgcGFyZW50T3B0aW9uc01hcCA9ICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmdldEV2ZW50TWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LHBhcmVudE9wdGlvbnNNYXAsewogICAgICAgICAgICAgICAgIm9uS2V5SW5wdXQudGV4dEZpZWxkIiA6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0hBTkdFX0VWRU5UCiAgICAgICAgICAgIH0pCiAgICAgICAgfSwKCiAgICAgICAgX21heENoYXJzUmVhY2hlZDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIHZhciBpc01heExlbmd0aFN1cHBvcnRlZCA9IGZhbHNlLAogICAgICAgICAgICAgICAgZWxlbWVudE5hbWUgPSB0aGlzLm9wdGlvbnMubXVsdGlMaW5lID8gInRleHRhcmVhIiA6ICJpbnB1dCI7CiAgICAgICAgICAgIC8vIGluIGJyb3dzZXJzLCB3aGVyZSBtYXggbGVuZ3RoIGlzIHN1cHBvcnRlZCwgd2UgZG9uJ3QgY3VzdG9tIGphdmFzY3JpcHQgY2hlY2tzLCB3ZSBsZXQgSFRNTCBkbyB0aGUgdmFsaWRhdGlvbiBvZiBtYXggbGVuZ3RoCiAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5odG1sNVR5cGUgJiYgeGZhbGliLnZpZXcudXRpbC5IdG1sVXRpbC5lbGVtZW50U3VwcG9ydHNBdHRyaWJ1dGUoZWxlbWVudE5hbWUsICJtYXhMZW5ndGgiKSl7CiAgICAgICAgICAgICAgICBpc01heExlbmd0aFN1cHBvcnRlZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuICFpc01heExlbmd0aFN1cHBvcnRlZCAmJiB0aGlzLm9wdGlvbnMubWF4Q2hhcnMKICAgICAgICAgICAgICAgICAgICYmIHRoaXMub3B0aW9ucy5tYXhDaGFycyE9PSIwIgogICAgICAgICAgICAgICAgICAgJiYgdmFsCiAgICAgICAgICAgICAgICAgICAmJiAgdmFsLmxlbmd0aCA+PSB0aGlzLm9wdGlvbnMubWF4Q2hhcnMKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlS2V5SW5wdXQgOiBmdW5jdGlvbihldmVudCwgY2hhcmFjdGVyLCBjb2RlKSB7CiAgICAgICAgICAgIGlmKGV2ZW50LmN0cmxLZXkgJiYgIV8uY29udGFpbnMoWydwYXN0ZScsICdjdXQnXSwgZXZlbnQudHlwZSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZighdGhpcy5vcHRpb25zLm11bHRpTGluZSkgewogICAgICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuX2hhbmRsZUtleURvd24uYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgIGNoYXJhY3RlciA9IChjb2RlID09IDEzKSA/ICcnIDogY2hhcmFjdGVyIDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHZhbCA9ICB0aGlzLiR1c2VyQ29udHJvbC52YWwoKSwKICAgICAgICAgICAgICAgIHNlbGVjdGlvblN0YXJ0ID0geGZhbGliLnZpZXcudXRpbC5IdG1sVXRpbC5nZXRIVE1MU3VwcG9ydGVkQXR0cih0aGlzLiR1c2VyQ29udHJvbFswXSwgInNlbGVjdGlvblN0YXJ0IikgfHwgMCwKICAgICAgICAgICAgICAgIHNlbGVjdGlvbkVuZCA9IHhmYWxpYi52aWV3LnV0aWwuSHRtbFV0aWwuZ2V0SFRNTFN1cHBvcnRlZEF0dHIodGhpcy4kdXNlckNvbnRyb2xbMF0sICJzZWxlY3Rpb25FbmQiKSB8fCAwLAogICAgICAgICAgICAgICAgcG9zID0gc2VsZWN0aW9uU3RhcnQsCiAgICAgICAgICAgICAgICAvLyBDUS00MjYwMjM5IDogIiZuYnNwIiB0YWtpbmcgc3BhY2Ugb2YgNSBjaGFycyBmb3IgcmVzdHJpY3RpbmcgdGhlIGxlbmd0aCB0byB2aXNpYmxlIGFyZWEKICAgICAgICAgICAgICAgIG5ld1ZhbCA9ICh2YWwuc3Vic3RyKDAsIHNlbGVjdGlvblN0YXJ0KSArIGNoYXJhY3RlciArIHZhbC5zdWJzdHIoc2VsZWN0aW9uRW5kKSk7CiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5jdXJWYWx1ZSA9IHZhbDsKICAgICAgICAgICAgaWYoIXRoaXMub3B0aW9ucy5tdWx0aUxpbmUpIHsgLy9UT0RPOmxvb2tzIGxpa2UgYSBidWcKICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5sZW5ndGhMaW1pdFZpc2libGUgPSB0cnVlOwogICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLnBvcyA9IHBvczsKICAgICAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5oU2Nyb2xsRGlzYWJsZWQgJiYgIV8uY29udGFpbnMoWydrZXlkb3duJywgJ2N1dCddLCBldmVudC50eXBlKSkgewogICAgICAgICAgICAgICAgICAgIHZhciBleHBlY3RlZFdpZHRoID0geGZhbGliLnZpZXcudXRpbC5UZXh0TWV0cmljcy5tZWFzdXJlRXh0ZW50KG5ld1ZhbCwge3JlZkVsOiB0aGlzLiR1c2VyQ29udHJvbFswXSwgbWF4V2lkdGg6LTF9KS53aWR0aDsKICAgICAgICAgICAgICAgICAgICBpZighZXZlbnQuY3RybEtleSAmJiBleHBlY3RlZFdpZHRoID4gdGhpcy4kdXNlckNvbnRyb2wud2lkdGgoKSl7ICAgLy8gV2h5ICBhbGxvd2FuY2Ugb2YgNSByZXF1aXJlZD8/CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5sZW5ndGhMaW1pdFZpc2libGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLm9wdGlvbnMubXVsdGlMaW5lICYmIHRoaXMub3B0aW9ucy5oU2Nyb2xsRGlzYWJsZWQpIHsgIC8vIExDLTQ2NTYgOiB3YWl0IHRpbGwgdXNlciBpbnB1dCwgaWYgaXQgY2F1c2VzIGFuIG92ZXJmbG93IHJldmVydCB0byBvbGQgdGV4dAogICAgICAgICAgICAgICAgdmFyICR0ZXh0QXJlYSA9IHRoaXMuJHVzZXJDb250cm9sOwogICAgICAgICAgICAgICAgJHRleHRBcmVhLmNzcygicGFkZGluZyIsICIwcHggMHB4IDBweCIpOyAgLy8gVE9ETyA6IHRha2UgY2FyZSBvZiBtdWx0aWxpbmUgc2VsZWN0aW9uICYgcGFkZGluZyBsYXRlcgoKICAgICAgICAgICAgICAgIC8vIFRPRE8gOiBmaW5kIGEgc2NoZW1lIHRvIGF2b2lkIGF0dGFjaGluZyBhbmQgZGV0YWNoaW5nIGxpc3RlbmVycywgY3VycmVudGx5ICQudmFsKCkgY2F1c2VzICdpbnB1dCcgdG8gZmlyZSwgcmVzdWx0aW5nIGluIGFuIGluZmluaXRlIGxvb3AKICAgICAgICAgICAgICAgICR0ZXh0QXJlYS5vbmUoImlucHV0IiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIGlmICgkdGV4dEFyZWEucHJvcCgnc2Nyb2xsSGVpZ2h0JykgPiAkdGV4dEFyZWEucHJvcCgnb2Zmc2V0SGVpZ2h0JykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRleHRBcmVhLnZhbCh2YWwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wcm9wKCJzZWxlY3Rpb25TdGFydCIsIHNlbGVjdGlvbkVuZCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnByb3AoInNlbGVjdGlvbkVuZCIsIHNlbGVjdGlvbkVuZCk7ICAvLyBMQy00NjU2IDogcmVzZXQgdGhlIGN1cnNvciBwb3MsIGFmdGVyd2FyZHMKICAgICAgICAgICAgICAgICAgICAgICAgY2hhcmFjdGVyID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgY29kZSA9IDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICghXy5jb250YWlucyhbJ2tleWRvd24nLCAnY3V0J10sIGV2ZW50LnR5cGUpICYmIHRoaXMuX21heENoYXJzUmVhY2hlZCh2YWwpICYmIHNlbGVjdGlvblN0YXJ0ID09PSBzZWxlY3Rpb25FbmQpIHsKICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXIoewogICAgICAgICAgICAgICAgdHlwZSA6ICJvbktleUlucHV0LnRleHRGaWVsZCIsCiAgICAgICAgICAgICAgICBvcmlnaW5hbFR5cGUgOiBldmVudC50eXBlLAogICAgICAgICAgICAgICAgY2hhcmFjdGVyIDogY2hhcmFjdGVyLCAgLy8gY29udGFpbnMgdGhlIHBhc3RlZCBzdHJpbmcgb3IgcHJlc3NlZCBrZXkKICAgICAgICAgICAgICAgIGtleUNvZGUgOiBldmVudC5rZXlDb2RlIHx8IDAsCiAgICAgICAgICAgICAgICBjaGFyQ29kZSA6IGV2ZW50LmNoYXJDb2RlIHx8IDAsCiAgICAgICAgICAgICAgICB3aGljaCA6IGV2ZW50LndoaWNoIHx8IDAsCiAgICAgICAgICAgICAgICBjdHJsS2V5IDogZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5IHx8IGZhbHNlLAogICAgICAgICAgICAgICAgc2hpZnRLZXkgOiBldmVudC5zaGlmdEtleSB8fCBmYWxzZSwKICAgICAgICAgICAgICAgIGtleURvd246IGZhbHNlLCAvLyBUaGlzIHByb3BlcnR5IGlzIGF2YWlsYWJsZSBvbmx5IGZvciBsaXN0IGJveGVzIGFuZCBkcm9wLWRvd24gbGlzdHMKICAgICAgICAgICAgICAgIHNlbGVjdGlvblN0YXJ0OiBzZWxlY3Rpb25TdGFydCwKICAgICAgICAgICAgICAgIHNlbGVjdGlvbkVuZDogc2VsZWN0aW9uRW5kCiAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVLZXlEb3duIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICBpZiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgIHZhciBjb2RlID0gZXZlbnQuY2hhckNvZGUgfHwgZXZlbnQud2hpY2ggfHwgZXZlbnQua2V5Q29kZSB8fCAwOwogICAgICAgICAgICAgICAgaWYoY29kZSA9PSA4IHx8IGNvZGUgPT0gNDYpIC8vIGJhY2tzcGFjZSBhbmQgZGVsCiAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVLZXlJbnB1dChldmVudCwgIiIsIGNvZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUtleVByZXNzIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICBpZiAoZXZlbnQpIHsKICAgICAgICAgICAgICAgIHZhciBjb2RlID0gZXZlbnQuY2hhckNvZGUgfHwgZXZlbnQud2hpY2ggfHwgZXZlbnQua2V5Q29kZSB8fCAwLAogICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlciA9IChjb2RlID09IDEzKSA/ICJcbiIgOiBTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGUpOyAvLyBtb2RpZmllZCAnXHJcbicgLT4gJ1xuJwoKICAgICAgICAgICAgaWYoeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmlzTm9uUHJpbnRhYmxlS2V5KGV2ZW50LmtleSkpIHsgLy8gbW96aWxsYSBhbHNvIGdlbmVyYXRlcyBhIGtleXByZXNzLCBhbG9uZyB3aXRoIGtleWRvd24KICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIGFsbCBrZXlzLCBzbyBvbmx5IGhhbmRsaW5nIHByaW50YWJsZSBrZXlzIGluIGtleXByZXNzCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX2hhbmRsZUtleUlucHV0KGV2ZW50LCBjaGFyYWN0ZXIsIGNvZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2NvbXBvc2l0aW9uVXBkYXRlQ2FsbGJhY2sgOiBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICB2YXIgdmFsID0gdGhhdC4kdXNlckNvbnRyb2wudmFsKCk7CiAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSAiY29tcG9zaXRpb251cGRhdGUiICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQuZGF0YSkgewogICAgICAgICAgICAgICAgLy8gdGhpcyBoYXMgYmVlbiBkZWxpYmVyYXRlbHkgZG9uZSB0byBnZXQgdGhlIGFjdHVhbCBkYXRhIGluIGNhc2Ugb2YgbWF4IGNoYXJhY3Rlci4KICAgICAgICAgICAgICAgIGlmICh0aGF0Lm9wdGlvbnMubWF4Q2hhcnMpIHsKICAgICAgICAgICAgICAgICAgICB2YWwgPSBldmVudC5vcmlnaW5hbEV2ZW50LmRhdGE7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHZhbCA9IHZhbCArIGV2ZW50Lm9yaWdpbmFsRXZlbnQuZGF0YS5zdWJzdHIoZXZlbnQub3JpZ2luYWxFdmVudC5kYXRhLmxlbmd0aCAtIDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBmbGFnID0gdGhhdC5fbWF4Q2hhcnNSZWFjaGVkKHZhbCk7CiAgICAgICAgICAgIGlmIChmbGFnKSB7CiAgICAgICAgICAgICAgICAvLyBpZiBtYXggcmVhY2hlZAogICAgICAgICAgICAgICAgdmFyIG5ld1ZhbCA9IHZhbC5zdWJzdHIoMCwgdGhhdC5vcHRpb25zLm1heENoYXJzKTsKICAgICAgICAgICAgICAgIC8vaW4gY2FzZSB0aGUgdmFsdWUgaXMgbm90IGNoYW5nZWQgdGhlbiB3ZSBkbyBub3QgbmVlZCB0byB1cGRhdGUgdmFsdWUgYW5kIGNsb3NlIHRoZSBhbmRyb2lkIGtleWJvYXJkLgogICAgICAgICAgICAgICAgaWYgKHZhbCA9PT0gbmV3VmFsKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhhdC4kdXNlckNvbnRyb2wudmFsKG5ld1ZhbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZsYWc7CiAgICAgICAgfSwKCiAgICAgICAgX2F0dGFjaEV2ZW50SGFuZGxlcnM6IGZ1bmN0aW9uKCRjb250cm9sKSB7CiAgICAgICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLl9hdHRhY2hFdmVudEhhbmRsZXJzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIC8vIElNRSBzcGVjaWZpYyBoYW5kbGluZywgdG8gaGFuZGxlIGphcGFuZXNlIGxhbmd1YWdlcyBtYXggbGltaXQKICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuX2F0dGFjaENvbXBvc2l0aW9uRXZlbnRIYW5kbGVycy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVQYXN0ZSA6IGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgaWYgKGV2ZW50KSB7CiAgICAgICAgICAgICAgICB2YXIgcGFzdGVkQ2hhciA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIGlmICh3aW5kb3cuY2xpcGJvYXJkRGF0YSAmJiB3aW5kb3cuY2xpcGJvYXJkRGF0YS5nZXREYXRhKSB7IC8vIElFCiAgICAgICAgICAgICAgICAgICAgcGFzdGVkQ2hhciA9IHdpbmRvdy5jbGlwYm9hcmREYXRhLmdldERhdGEoJ1RleHQnKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXZlbnQub3JpZ2luYWxFdmVudC5jbGlwYm9hcmREYXRhICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQuY2xpcGJvYXJkRGF0YS5nZXREYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgcGFzdGVkQ2hhciA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCd0ZXh0L3BsYWluJyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihwYXN0ZWRDaGFyKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlS2V5SW5wdXQoZXZlbnQsIHBhc3RlZENoYXIsIDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUN1dCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmIChldmVudCkgewogICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlS2V5SW5wdXQoZXZlbnQsICIiLCAwKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHBvc3RQcm9jZXNzRXhpdDogZnVuY3Rpb24oZXZudCkgewogICAgICAgICAgICAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5wb3N0UHJvY2Vzc0V4aXQuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLm11bHRpTGluZSAmJiB0aGlzLm9wdGlvbnMuaFNjcm9sbERpc2FibGVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5faGFuZGxlVkFsaWduT25FeGl0KCk7CiAgICAgICAgfSwKCiAgICAgICAgcHJlUHJvY2Vzc0VudGVyOiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLnByZVByb2Nlc3NFbnRlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5tdWx0aUxpbmUgJiYgdGhpcy5vcHRpb25zLmhTY3JvbGxEaXNhYmxlZCkKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgdGhpcy5faGFuZGxlVkFsaWduT25FbnRlcigpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBicmllZjogU2VsZWN0IHRoZSBnaXZlbiBmaWVsZCBvbiBmb2N1cyBpbiBJbnRlcm5ldCBFeHBsb3JlcgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgX3NlbGVjdE9uRm9jdXNJbklFIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgLy8gaWYgdGhlIHZhbHVlIGlzIG5vdCBzYW1lIG9ubHkgdGhlbiBkbyBzZWxlY3Rpb24gaW4gSUUKICAgICAgICAgICAgLy8gRm9yIElzc3VlOiBMQy05ODk1LCB3ZSBjaGVjayBpZiB2YWx1ZSBub3Qgc2FtZQogICAgICAgICAgICBpZigkLmJyb3dzZXIubXNpZSAmJiAhdGhpcy5faXNWYWx1ZVNhbWUoKSkgewogICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuc2VsZWN0KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAvL2FsbCBvdGhlciBicm93c2VycyBiZWhhdmUgbGlrZSBhIGdvb2QgYm95CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBzaG93VmFsdWUgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuc2hvd1ZhbHVlLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICAgICAgLy9JRSBkb2Vzbid0IHNob3cgc2VsZWN0ZWQgdGV4dCBpZiB3ZSBmb2N1cyBhbmQgc2V0IGl0cyB2YWx1ZSBhbGwgdGhlIHRpbWUgc28gZm9yY2Ugc2VsZWN0aW9uCiAgICAgICAgICAgIHRoaXMuX3NlbGVjdE9uRm9jdXNJbklFKCk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0Q29tbWl0VmFsdWU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgdmFsdWUgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRDb21taXRWYWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwoKICAgICAgICAgICAgaWYodGhpcy5fbWF4Q2hhcnNSZWFjaGVkKHZhbHVlKSkgewogICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5zbGljZSgwLHRoaXMub3B0aW9ucy5tYXhDaGFycyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnZhbCh0aGlzLm9wdGlvbnMudmFsdWUpOwoKICAgICAgICAgICAgLy9UT0RPOiBhc2sgU2hhcmFkIHdoZXRoZXIgaXQgaXMgcmlnaHQKICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLm11bHRpTGluZSAmJiB0aGlzLm9wdGlvbnMuaFNjcm9sbERpc2FibGVkKSAgewogICAgICAgICAgICAgICAgLy92YXIgc3RyPSB0aGlzLl9jaGVja0xpbmVzKHZhbHVlKTsKICAgICAgICAgICAgICAgIC8vaWYodmFsdWUgIT0gc3RyKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICAgICAgLy99CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgKiogcmV0dXJucyB0aGUgY29udGVudEhlaWdodCB3aGljaCBuZWVkcyB0byBiZSBjb25zaWRlcmVkIGZvciBwYWRkaW5nIGZvciB2YWxpZ24sCiAgICAgICAgKiogaWYgbm8gY29udGVudEhlaWdodCBpcyBwcmVzZW50IHRoZW4gZm9udFNpemUgaXMgcmV0dXJuZWQuCiAgICAgICAgKi8KICAgICAgICBfZ2V0Q29udGVudEhlaWdodDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgY29udGVudEhlaWdodCA9IE1hdGguY2VpbCh0aGlzLiR1c2VyQ29udHJvbC5nZXQoMCkuc2Nyb2xsSGVpZ2h0KTsKICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnRIZWlnaHQgPyBjb250ZW50SGVpZ2h0IDogdGhpcy5vcHRpb25zLmZvbnRTaXplOwogICAgICAgIH0KICAgIH0pOwp9KSgkLCB3aW5kb3cuXyk7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX18KICoKICogIENvcHlyaWdodCAyMDE5IEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiBzdXBwbGllcnMgYW5kIG1heSBiZSBjb3ZlcmVkIGJ5IFUuUy4gYW5kIEZvcmVpZ24gUGF0ZW50cywKICogcGF0ZW50cyBpbiBwcm9jZXNzLCBhbmQgYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCihmdW5jdGlvbiAoJCkgewogICAgJC53aWRnZXQoInhmYVdpZGdldC5yaWNoVGV4dEZpZWxkIiwgJC54ZmFXaWRnZXQudGV4dEZpZWxkLCB7CgogICAgICAgIF93aWRnZXROYW1lIDogInJpY2hUZXh0RmllbGQiLAoKICAgICAgICBfcmljaFRleHRXaWRnZXQgOiBudWxsLAoKICAgICAgICBfY2hhbmdlQWNjZXNzIDogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICBzd2l0Y2ggKHZhbCkgewogICAgICAgICAgICAgICAgY2FzZSAib3BlbiI6CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3JpY2hUZXh0V2lkZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3JpY2hUZXh0V2lkZ2V0LmVkaXRvci5lbmFibGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmljaFRleHRXaWRnZXQuJHRvb2xiYXIucmVtb3ZlQ2xhc3MoImhpZGVUb29sYmFyIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAicmVhZE9ubHkiOgogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9yaWNoVGV4dFdpZGdldCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9yaWNoVGV4dFdpZGdldC5lZGl0b3IuZGlzYWJsZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9yaWNoVGV4dFdpZGdldC4kdG9vbGJhci5hZGRDbGFzcygiaGlkZVRvb2xiYXIiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBnZXRPcHRpb25zTWFwIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgcGFyZW50T3B0aW9uc01hcCA9ICQueGZhV2lkZ2V0LnRleHRGaWVsZC5wcm90b3R5cGUuZ2V0T3B0aW9uc01hcC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICByZXR1cm4gJC5leHRlbmQoe30sIHBhcmVudE9wdGlvbnNNYXAsIHsKICAgICAgICAgICAgICAgICJ2YWx1ZSIgOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3JpY2hUZXh0V2lkZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3JpY2hUZXh0V2lkZ2V0LnNldFJpY2hUZXh0RWRpdG9yQ29udGVudCh2YWwpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiYWNjZXNzIiA6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VBY2Nlc3ModmFsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RXZlbnRNYXAgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vIGluIGNhc2Ugb2YgSUUgYnJvd3NlcnMsIGZvY3VzIGV2ZW50IGlzIGRlbGF5ZWQsIGhlbmNlIGFkZGluZyBhY3RpdmF0ZSBtZXRob2QgZm9yIGNvbnRlbnQgZWRpdGFibGUKICAgICAgICAgICAgaWYgKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5pc0lFKCkpIHsKICAgICAgICAgICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQudGV4dEZpZWxkLnByb3RvdHlwZS5nZXRFdmVudE1hcC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LCBwYXJlbnRPcHRpb25zTWFwLCB7CiAgICAgICAgICAgICAgICAgICAgImFjdGl2YXRlLnJpY2hUZXh0RmllbGQiIDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FTlRFUl9FVkVOVAogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gJC54ZmFXaWRnZXQudGV4dEZpZWxkLnByb3RvdHlwZS5nZXRFdmVudE1hcC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcmVuZGVyIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgJHJpY2hUZXh0V2lkZ2V0ID0gdGhpcy5lbGVtZW50LmZpbmQoImRpdi5yaWNoVGV4dFdpZGdldCIpLmVxKDApOwogICAgICAgICAgICBpZighJHJpY2hUZXh0V2lkZ2V0Lmxlbmd0aCl7CiAgICAgICAgICAgICAgICB2YXIgYXR0YWNoZWRUZXh0YXJlYUNsYXNzZXMgPSB0aGlzLmVsZW1lbnQuY2hpbGRyZW4oKS5hdHRyKCdjbGFzcycpOwogICAgICAgICAgICAgICAgdmFyIHJpY2hUZXh0V2lkZ2V0RWxlbWVudCA9ICc8ZGl2IGNsYXNzPSJyaWNoVGV4dFdpZGdldCAnICsgYXR0YWNoZWRUZXh0YXJlYUNsYXNzZXMgKyAnIiBpZD0icmljaFRleHRGaWVsZF8nICsgdGhpcy5vcHRpb25zLm5hbWUgKyAnXycgKyBhdHRhY2hlZFRleHRhcmVhQ2xhc3NlcyArICciPjwvZGl2Pic7CiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQuY2hpbGRyZW4oKS5yZW1vdmUoKTsKICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmQocmljaFRleHRXaWRnZXRFbGVtZW50KTsKICAgICAgICAgICAgICAgICRyaWNoVGV4dFdpZGdldCA9IHRoaXMuZWxlbWVudC5maW5kKCJkaXYucmljaFRleHRXaWRnZXQiKS5lcSgwKTsKICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAkcmljaFRleHRXaWRnZXQuY2hpbGRyZW4oKS5yZW1vdmUoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkcmljaFRleHRXaWRnZXQuYXBwZW5kKHRoaXMub3B0aW9ucy52YWx1ZSk7CiAgICAgICAgICAgIHJldHVybiAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5yZW5kZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBnZXRDb21taXRWYWx1ZSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHZhbHVlID0gIiI7CiAgICAgICAgICAgIGlmICh0aGlzLl9yaWNoVGV4dFdpZGdldCkgewogICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9yaWNoVGV4dFdpZGdldC5nZXRSaWNoVGV4dEVkaXRvckNvbnRlbnQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgcHJlUHJvY2Vzc0VudGVyIDogZnVuY3Rpb24gKGV2bnQpIHsKICAgICAgICAgICAgJC54ZmFXaWRnZXQudGV4dEZpZWxkLnByb3RvdHlwZS5wcmVQcm9jZXNzRW50ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdmFyICRyaWNoVGV4dERpdiA9IHRoaXMuJHVzZXJDb250cm9sLmZpbmQoImRpdi5yaWNoVGV4dFdpZGdldCIpLmVxKDApOwogICAgICAgICAgICBpZighJHJpY2hUZXh0RGl2Lmxlbmd0aCl7CiAgICAgICAgICAgICAgICAkcmljaFRleHREaXYgPSB0aGlzLmVsZW1lbnQuZmluZCgiZGl2LnJpY2hUZXh0V2lkZ2V0IikuZXEoMCk7CiAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZURlZmF1bHRUb29sYmFyQ29uZmlnKCk7CiAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5wYXJlbnRzKCcucmljaHRleHRzdXBwb3J0JykuY3NzKCd6LWluZGV4JywgJ2F1dG8nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAod2luZG93LkZvcm0gPT09IHVuZGVmaW5lZCB8fCB3aW5kb3cuRm9ybS5ydGUgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgLyogRm9ybXMgUlRFIGlzIHBhcnQgb2YgRm9ybXMgQWRkb24gcGFja2FnZSBvbmx5LiBEb250IGRvIGFueXRoaW5nIGlmIGFkZG9uIGlzIG5vdCBpbnN0YWxsZWQuKi8KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9yaWNoVGV4dFdpZGdldCA9PT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhpcy5faW5pdGlhbGl6ZVJURVRvb2xiYXIoKTsKICAgICAgICAgICAgICAgIHRoaXMuX3JpY2hUZXh0V2lkZ2V0ID0gbmV3IHdpbmRvdy5Gb3JtLnJ0ZS5SaWNoVGV4dEVkaXRvcih7CiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3IgOiAkcmljaFRleHREaXYuYXR0cigiaWQiKSwKICAgICAgICAgICAgICAgICAgICB0b29sYmFyIDogd2luZG93LkZvcm0ucnRlLlJpY2hUZXh0RWRpdG9yLk1GVG9vbGJhciwKICAgICAgICAgICAgICAgICAgICBkYXRhIDogdGhpcy5vcHRpb25zLnZhbHVlLAogICAgICAgICAgICAgICAgICAgIGxvY2FsZSA6ICRyaWNoVGV4dERpdi5kYXRhKCJsb2NhbGUiKQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgICAgICB0aGlzLl9yaWNoVGV4dFdpZGdldC5lZGl0b3Iub24oImJsdXI6Y29tcG9zZXIiLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgdGhhdC4kdXNlckNvbnRyb2wudHJpZ2dlcigiYmx1ciIpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAvLyBpbml0aWFsaXplIHRoZSBhY2Nlc3MKICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuYWNjZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2hhbmdlQWNjZXNzKHRoaXMub3B0aW9ucy5hY2Nlc3MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgY2hhbmdlRGVmYXVsdFRvb2xiYXJDb25maWc6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHdpbmRvdy5Gb3JtICYmIHdpbmRvdy5Gb3JtLnJ0ZSl7CiAgICAgICAgICAgICAgICB2YXIgdG9vbGJhckRlZmF1bHRDb25maWdEYXRhID0gd2luZG93LkZvcm0ucnRlLkRlZmF1bHRDb25maWc7CiAgICAgICAgICAgICAgICB0b29sYmFyRGVmYXVsdENvbmZpZ0RhdGEuZm9udFNpemUuZGVmYXVsdFZhbHVlID0gdGhpcy5vcHRpb25zLmZvbnRTaXplOwogICAgICAgICAgICAgICAgdG9vbGJhckRlZmF1bHRDb25maWdEYXRhLmZvbnRGYW1pbHkuZGVmYXVsdFZhbHVlID0gdGhpcy5vcHRpb25zLmZvbnRGYW1pbHk7CgogICAgICAgICAgICAgICAgLy8gQWRkaW5nICdpc0ZvbnRJblB4JyBmbGFnIGFuZCBvdmVycmlkaW5nIHR3byB1dGlsaXR5IGZ1bmN0aW9ucwogICAgICAgICAgICAgICAgLy8gJ2dldERlZmF1bHRQYXJhU3R5bGUnIGFuZCAnZ2V0TWlzc2luZ1BhcmFTdHlsZScgYXJlIHJlc3BvbnNpYmxlIGZvciBhZGRpbmcgUlRFIGZvbnQgc3R5bGluZyBhdHRyaWJ1dGVzIHRvIHJpY2ggdGV4dCBlbGVtZW50cwogICAgICAgICAgICAgICAgdG9vbGJhckRlZmF1bHRDb25maWdEYXRhLmlzRm9udEluUHggPSB0cnVlOwogICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VEZWZhdWx0UGFyYVN0eWxlVXRpbGl0eSgpOwogICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VNaXNzaW5nUGFyYVN0eWxlVXRpbGl0eSgpOwoKICAgICAgICAgICAgICAgIC8vIEFkZGluZyBkcm9wZG93biB2YWx1ZXMgaW4gZGVmYXVsdCBjb25maWcgaWYgbm90IGF2YWlsYWJsZSBpbiBvcHRpb25zCiAgICAgICAgICAgICAgICBpZih0b29sYmFyRGVmYXVsdENvbmZpZ0RhdGEuZm9udFNpemUub3B0aW9ucy5pbmRleE9mKHRoaXMub3B0aW9ucy5mb250U2l6ZSkgPT09IC0xKXsKICAgICAgICAgICAgICAgICAgICB0b29sYmFyRGVmYXVsdENvbmZpZ0RhdGEuZm9udFNpemUub3B0aW9ucy5wdXNoKHRoaXMub3B0aW9ucy5mb250U2l6ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZih0b29sYmFyRGVmYXVsdENvbmZpZ0RhdGEuZm9udEZhbWlseS5vcHRpb25zLmluZGV4T2YodGhpcy5vcHRpb25zLmZvbnRGYW1pbHkpID09PSAtMSl7CiAgICAgICAgICAgICAgICAgICAgdG9vbGJhckRlZmF1bHRDb25maWdEYXRhLmZvbnRGYW1pbHkub3B0aW9ucy5wdXNoKHRoaXMub3B0aW9ucy5mb250RmFtaWx5KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNoYW5nZURlZmF1bHRQYXJhU3R5bGVVdGlsaXR5OiBmdW5jdGlvbigpewogICAgICAgICAgICBGb3JtLnJ0ZS51dGlsLkh0bWxVdGlscy5nZXREZWZhdWx0UGFyYVN0eWxlID0gZnVuY3Rpb24gKGNvbmZpZykgewogICAgICAgICAgICAgICAgdmFyIHN0eWxlID0gIiI7CiAgICAgICAgICAgICAgICBpZiAoY29uZmlnKSB7CiAgICAgICAgICAgICAgICAgICAgc3R5bGUgKz0gJ2ZvbnQtZmFtaWx5OicgKyBjb25maWcuZm9udEZhbWlseS5kZWZhdWx0VmFsdWUgKyAnOyc7CiAgICAgICAgICAgICAgICAgICAgaWYoY29uZmlnLmlzRm9udEluUHgpewogICAgICAgICAgICAgICAgICAgICAgICBzdHlsZSArPSAnZm9udC1zaXplOicgKyBjb25maWcuZm9udFNpemUuZGVmYXVsdFZhbHVlICsgJ3B4Oyc7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdsZXR0ZXItc3BhY2luZzonICsgY29uZmlnLmxldHRlclNwYWNpbmcuZGVmYXVsdFZhbHVlICsgJ3B4Oyc7CiAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdmb250LXNpemU6JyArIGNvbmZpZy5mb250U2l6ZS5kZWZhdWx0VmFsdWUgKyAncHQ7JzsKICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgKz0gJ2xldHRlci1zcGFjaW5nOicgKyBjb25maWcubGV0dGVyU3BhY2luZy5kZWZhdWx0VmFsdWUgKyAncHQ7JzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgc3R5bGUgKz0gJ2NvbG9yOiMwMDAwMDA7JzsKICAgICAgICAgICAgICAgICAgICBzdHlsZSArPSAndGV4dC1hbGlnbjpsZWZ0Oyc7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIHN0eWxlOwogICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIGNoYW5nZU1pc3NpbmdQYXJhU3R5bGVVdGlsaXR5IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgRm9ybS5ydGUudXRpbC5IdG1sVXRpbHMuZ2V0TWlzc2luZ1BhcmFTdHlsZSA9IGZ1bmN0aW9uIChzdHlsZSwgY29uZmlnKSB7CiAgICAgICAgICAgICAgICBpZiAoc3R5bGUgJiYgc3R5bGUubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgIGlmIChjb25maWcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFGb3JtLnJ0ZS51dGlsLlN0cmluZ0hlbHBlci5lbmRzV2l0aChzdHlsZSwgIjsiKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgKz0gIjsiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHlsZS5pbmRleE9mKCJmb250LWZhbWlseSIpIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgKz0gJ2ZvbnQtZmFtaWx5OicgKyBjb25maWcuZm9udEZhbWlseS5kZWZhdWx0VmFsdWUgKyAnOyc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0eWxlLmluZGV4T2YoImZvbnQtc2l6ZSIpIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY29uZmlnLmlzRm9udEluUHgpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdmb250LXNpemU6JyArIGNvbmZpZy5mb250U2l6ZS5kZWZhdWx0VmFsdWUgKyAncHg7JzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdmb250LXNpemU6JyArIGNvbmZpZy5mb250U2l6ZS5kZWZhdWx0VmFsdWUgKyAncHQ7JzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGUuaW5kZXhPZigibGV0dGVyLXNwYWNpbmciKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNvbmZpZy5pc0ZvbnRJblB4KXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZSArPSAnbGV0dGVyLXNwYWNpbmc6JyArIGNvbmZpZy5sZXR0ZXJTcGFjaW5nLmRlZmF1bHRWYWx1ZSArICdweDsnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGUgKz0gJ2xldHRlci1zcGFjaW5nOicgKyBjb25maWcubGV0dGVyU3BhY2luZy5kZWZhdWx0VmFsdWUgKyAncHQ7JzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3R5bGUuaW5kZXhPZigiY29sb3IiKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICdjb2xvcjojMDAwMDAwOyc7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0eWxlLmluZGV4T2YoInRleHQtYWxpZ24iKSA8IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlICs9ICd0ZXh0LWFsaWduOmxlZnQ7JzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc3R5bGUgPSBGb3JtLnJ0ZS51dGlsLkh0bWxVdGlscy5nZXREZWZhdWx0UGFyYVN0eWxlKGNvbmZpZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gc3R5bGU7CiAgICAgICAgICAgIH07CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRpYWxpemVSVEVUb29sYmFyIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB3aW5kb3cuRm9ybS5ydGUuUmljaFRleHRFZGl0b3IuTUZUb29sYmFyID0gd2luZG93LkZvcm0ucnRlLlJpY2hUZXh0RWRpdG9yLk1GVG9vbGJhciB8fCB7CiAgICAgICAgICAgICAgICBkZWZhdWx0TW9kZSA6ICdiYXNpYycsCiAgICAgICAgICAgICAgICB0b29sYmFycyA6IHsKICAgICAgICAgICAgICAgICAgICBiYXNpYyA6IHsKICAgICAgICAgICAgICAgICAgICAgICAgbGF5b3V0IDogWwogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zIDogW0Zvcm0ucnRlLkNvbW1hbmRzLkhFQURFUl0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMgOiBbRm9ybS5ydGUuQ29tbWFuZHMuQk9MRCwgRm9ybS5ydGUuQ29tbWFuZHMuSVRBTElDLCBGb3JtLnJ0ZS5Db21tYW5kcy5VTkRFUkxJTkVdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgOiAnbGlzdHMnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb24gOiAnbGlzdCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgOiAiTGlzdCBUeXBlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlIDogJ3BvcG92ZXInLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlbWVudCA6ICdib3R0b20nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zIDogW0Zvcm0ucnRlLkNvbW1hbmRzLklOU0VSVF9VTk9SREVSRURfTElTVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybS5ydGUuQ29tbWFuZHMuSU5TRVJUX09SREVSRURfTElTVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybS5ydGUuQ29tbWFuZHMuSU5TRVJUX0xPV0VSQ0FTRV9BTFBIQUJFVF9MSVNUXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA6ICdFeHBhbmQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgOiBGb3JtLnJ0ZS5Db21tYW5kcy5NT0RFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlIDogRm9ybS5ydGUuVG9vbGJhck1vZGUuRlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpY29uIDogJ3Jlc2l6ZS1mdWxsJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgICAgICAgICBmbG9hdGluZyA6IHRydWUKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIGZ1bGwgOiB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxheW91dCA6IFsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtcyA6IFtGb3JtLnJ0ZS5Db21tYW5kcy5CT0xELCBGb3JtLnJ0ZS5Db21tYW5kcy5JVEFMSUMsIEZvcm0ucnRlLkNvbW1hbmRzLlVOREVSTElORV0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMgOiBbRm9ybS5ydGUuQ29tbWFuZHMuU1VQRVJTQ1JJUFQsIEZvcm0ucnRlLkNvbW1hbmRzLlNVQlNDUklQVF0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMgOiBbCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvcm0ucnRlLkNvbW1hbmRzLkhFQURFUiwgRm9ybS5ydGUuQ29tbWFuZHMuRk9OVF9GQU1JTFksIEZvcm0ucnRlLkNvbW1hbmRzLkxJTkVfSEVJR0hULCBGb3JtLnJ0ZS5Db21tYW5kcy5GT1JFX0NPTE9SLCBGb3JtLnJ0ZS5Db21tYW5kcy5ISUxJVEVfQ09MT1IsIEZvcm0ucnRlLkNvbW1hbmRzLkxJTksKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zIDogW0Zvcm0ucnRlLkNvbW1hbmRzLklOU0VSVF9VTk9SREVSRURfTElTVCwgRm9ybS5ydGUuQ29tbWFuZHMuSU5TRVJUX09SREVSRURfTElTVCwgRm9ybS5ydGUuQ29tbWFuZHMuSU5TRVJUX0xPV0VSQ0FTRV9BTFBIQUJFVF9MSVNUCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA6ICdDb2xsYXBzZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZCA6IEZvcm0ucnRlLkNvbW1hbmRzLk1PREUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgOiBGb3JtLnJ0ZS5Ub29sYmFyTW9kZS5CQVNJQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpY29uIDogJ3Jlc2l6ZS1zbWFsbCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQgOiB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfSk7Cgp9KSgkKTsoZnVuY3Rpb24oJCl7CgkkLndpZGdldCggInhmYVdpZGdldC5pbWFnZUZpZWxkIiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgewoKICAgIF93aWRnZXROYW1lOiJpbWFnZUZpZWxkIiwKCiAgICBvcHRpb25zOiB7CiAgICAgICAgdGFiSW5kZXg6IDAsCiAgICAgICAgInJvbGUiOiAiaW1nIgogICAgfSwKCiAgICBnZXRFdmVudE1hcDogZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0RXZlbnRNYXAuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICByZXR1cm4gJC5leHRlbmQoe30sIHBhcmVudE9wdGlvbnNNYXAsIHsKICAgICAgICAgICAgImltYWdlY2hhbmdlIjogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQKICAgICAgICB9KQogICAgfSwKCiAgICBnZXRPcHRpb25zTWFwOiBmdW5jdGlvbigpIHsKICAgICAgICB2YXIgcGFyZW50T3B0aW9uc01hcCA9ICQueGZhV2lkZ2V0LmRlZmF1bHRXaWRnZXQucHJvdG90eXBlLmdldE9wdGlvbnNNYXAuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSxwYXJlbnRPcHRpb25zTWFwLHsKICAgICAgICAgICAgInNjcmVlblJlYWRlclRleHQiOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgIGlmKHZhbCkKICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJhbHQiLCB2YWwpCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJkaXNwbGF5VmFsdWUiOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgIHZhciB3aWRnZXRWYWx1ZTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMudmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICB3aWRnZXRWYWx1ZSA9ICJkYXRhOjtiYXNlNjQsIiArIHRoaXMub3B0aW9ucy52YWx1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgd2lkZ2V0VmFsdWUgPSAiIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnByb3AodGhpcy5vcHRpb25zLmNvbW1pdFByb3BlcnR5LCB3aWRnZXRWYWx1ZSk7CiAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKHRoaXMub3B0aW9ucy5jb21taXRQcm9wZXJ0eSwgd2lkZ2V0VmFsdWUpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAiYWNjZXNzIiA6IGZ1bmN0aW9uKCkge30sCgogICAgICAgICAgICAvLyBDUS04NTUxNCA6IHVzZSBtYXgtaHQgJiBtYXgtd2QgdG8gaG9ub3IgaW1hZ2UncyBpbnRyaW5zaWMgaHQgJiB3ZCBhdHRyaWJ1dGVzICYgcHJldmVudCBkaXN0b3J0aW9uCiAgICAgICAgICAgICJoZWlnaHQiIDogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgLy8gaW4gY2FzZSBhc3BlY3QgaXMgYWN0dWFsIHRoZW4gd2UgbmVlZCB0byBjcm9wIHRoZSBpbWFnZSwgd2hpY2ggd2lsbCBiZSBub3QgcG9zc2libGUgaWYgbWF4IGhlaWdodCBhbmQgd2lkdGggYXJlIHNldAogICAgICAgICAgICAgICAgaWYgKHZhbCAmJiB0aGlzLm9wdGlvbnMuYXNwZWN0ICE9ICJhY3R1YWwiKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuJHVzZXJDb250cm9sWzBdLCB7Im1heC1oZWlnaHQiOiB2YWx9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgIndpZHRoIiA6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgIGlmICh2YWwgJiYgdGhpcy5vcHRpb25zLmFzcGVjdCAhPSAiYWN0dWFsIikgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLiR1c2VyQ29udHJvbFswXSwgeyJtYXgtd2lkdGgiOiB2YWx9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgImFzcGVjdCIgOiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICAvLyB2YWx1ZSBvZiBhY3R1YWwgdHVybnMgb2ZmIHNjYWxpbmcsIGNhdXNpbmcgdGhlIGltYWdlIHRvIGJlIGRyYXduIGF0IGl0cyBuYXRpdmUgc2l6ZSwKICAgICAgICAgICAgICAgIC8vIGFzIHBlciB4ZmEgc3BlYyBBZG9iZSBpbXBsZW1lbnRhdGlvbnMgY3JvcCB0aGUgaW1hZ2UKICAgICAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5hc3BlY3QgPT0gImFjdHVhbCIpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcmlnaHQgPSB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJ3aWR0aCIpLAogICAgICAgICAgICAgICAgICAgICAgICBib3R0b20gPSB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKCJoZWlnaHQiKTsKICAgICAgICAgICAgICAgICAgICByaWdodCA9IHJpZ2h0LmluZGV4T2YoInB4IikgPj0gMCA/IHJpZ2h0IDogcmlnaHQgKyAicHgiOwogICAgICAgICAgICAgICAgICAgIGJvdHRvbSA9IGJvdHRvbS5pbmRleE9mKCJweCIpID49IDAgPyBib3R0b20gOiBib3R0b20gKyAicHgiOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2Nyb3BJbWFnZSgiMHB4IiwgcmlnaHQsIGJvdHRvbSwgIjBweCIpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnJlbW92ZUF0dHIoImhlaWdodCB3aWR0aCIpOwogICAgICAgICAgICAgICAgLy8gdmFsdWUgb2Ygbm9uZSBpbmRpY2F0ZXMgbm8gYXNwZWN0IHJhdGlvCiAgICAgICAgICAgICAgICAvLyBhcyBwZXIgeGZhIHNwZWMgaW1hZ2UgaXMgaW5kZXBlbmRlbnRseSBzY2FsZWQgaW4gdGhlIGhvcml6b250YWwgYW5kIHZlcnRpY2FsIGRpcmVjdGlvbnMgdG8gZXhhY3RseSBmaWxsIHRoZSBmaWVsZCwKICAgICAgICAgICAgICAgIC8vIHdoaWNoIGFyZSBhbHJlYWR5IHNldCB0byBmaWxsIHRoZSBmaWVsZAogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLm9wdGlvbnMuYXNwZWN0ICE9ICJub25lIikgewogICAgICAgICAgICAgICAgLy8gQSB2YWx1ZSBvZiBmaXQsIHdoaWNoIGlzIHRoZSBkZWZhdWx0LCBjYXVzZXMgdGhlIHNjYWxlIHRvIGJlIHN1Y2ggdGhhdCB0aGUgaW1hZ2UgZmlsbHMgYXMgbXVjaCBvZiB0aGUgZmllbGQgYXMgcG9zc2libGUKICAgICAgICAgICAgICAgIC8vIHdpdGhvdXQgb3ZlcmZsb3dpbmcgaXQgaW4gZWl0aGVyIGRpbWVuc2lvbi4KICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hdHRyKHsiaGVpZ2h0IiA6ICJhdXRvIiwgIndpZHRoIiA6ICJhdXRvIn0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9LAoKICAgIC8vIGNyb3AgdGhlIGltYWdlIHVzaW5nIHRvcCxyaWdodCwgYm90dG9tLCBsZWZ0IGNvb3JkaWFudGVzIG9mIHRoZSBpbWFnZQogICAgX2Nyb3BJbWFnZSA6IGZ1bmN0aW9uICh0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQpIHsKICAgICAgICB2YXIgY2xpcFJlY3QgPSAicmVjdCgiICsgdG9wICsgIiwiICsgcmlnaHQgKyAiLCIgKyBib3R0b20gKyAiLCIgKyBsZWZ0ICsgIikiOwogICAgICAgIHZhciBjbGlwUGF0aFBvbHlnb24gPSAicG9seWdvbiggMHB4IDBweCwgMHB4ICIgKyBib3R0b20gKyAiLCIgKyByaWdodCArICIgIiArIGJvdHRvbSArIiwiICsgcmlnaHQgKyAiIDBweCkiOwogICAgICAgIC8vIGNsaXAgcHJvcGVydHkgaXMgZGVwcmVjYXRlZCBidXQgc3RpbGwgc3VwcG9ydGVkIGJ5IGFsbCB0aGUgbWFqb3IgYnJvd3NlcnMKICAgICAgICAvLyBjbGlwLXBhdGggcmVwbGFjZXMgdGhlIGRlcHJlY2F0ZWQgY2xpcCBwcm9wZXJ0eSBidXQgc3RpbGwgaXMgbm90IGZ1bGx5IHN1cHBvcnRlZCBieSBhbGwgbWFqb3IgYnJvd3NlcgogICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmNzcyh7ImNsaXAiIDogY2xpcFJlY3QsICJjbGlwLXBhdGgiIDogY2xpcFBhdGhQb2x5Z29ufSk7CiAgICB9LAoKICAgIHJlbmRlciA6IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciBzZWxmID0gdGhpczsKICAgICAgICBpZiAodHlwZW9mIEZpbGVSZWFkZXIgIT09ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgIHRoaXMucmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZ2V0TG9nZ2VyKCkuZXJyb3IoIkltYWdlIEZpZWxkIGlzIHN1cHBvcnRlZCBvbmx5IGZvciBIVE1MNSBzdXBwb3J0ZWQgYnJvd3NlcnMuIik7CiAgICAgICAgfQogICAgICAgIGlmICh0aGlzLmVsZW1lbnQpIHsKICAgICAgICAgICAgLy8gY2hhbmdlIGV2ZW50IHRyaWdnZXJlZCB3aGVuIG5ldyBpbWFnZSBpcyBzZWxlY3RlZAogICAgICAgICAgICB0aGlzLiR3aWRnZXRJbnB1dCA9IHRoaXMuZWxlbWVudC5maW5kKCJpbnB1dCIpLm9uKCJjaGFuZ2UuaW1hZ2VGaWVsZCIsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgc2VsZi5faGFuZGxlSW5wdXRDaGFuZ2UoKTsKICAgICAgICAgICAgfSkuY2xpY2soZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgICAgIC8vIHRvIHN0b3AgYnViYmxpbmcgb2YgZXZlbnQgZnJvbSBpbnB1dCB0byB3aWRnZXQKICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgdGhpcy4kd2lkZ2V0SW1nID0gdGhpcy5lbGVtZW50Lm9uKCJjbGljay5pbWFnZUZpZWxkIiwgZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICBzZWxmLl9pbWFnZUNsaWNrKCk7CiAgICAgICAgICAgIH0pLmZpbmQoImltZyIpOwogICAgICAgIH0KICAgICAgICBpZiAodGhpcy5yZWFkZXIpIHsKICAgICAgICAgICAgLy9sb2FkIGV2ZW50IGlzIHRyaWdnZXJlZCBlYWNoIHRpbWUgdGhlIHJlYWRpbmcgb3BlcmF0aW9uIGlzIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQKICAgICAgICAgICAgdGhpcy5yZWFkZXIuYWRkRXZlbnRMaXN0ZW5lcigibG9hZCIsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHNlbGYuJHdpZGdldEltZy5hdHRyKCJzcmMiLHNlbGYucmVhZGVyLnJlc3VsdCk7CiAgICAgICAgICAgICAgICBzZWxmLiR3aWRnZXRJbWcudHJpZ2dlcigiaW1hZ2VjaGFuZ2UiKTsKICAgICAgICAgICAgfSwgZmFsc2UpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUucmVuZGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICB9LAoKICAgIGdldENvbW1pdFZhbHVlOiBmdW5jdGlvbigpIHsKICAgICAgICByZXR1cm4gdGhpcy5fZXh0cmFjdERhdGEodGhpcy4kdXNlckNvbnRyb2wuYXR0cigic3JjIikpOwogICAgfSwKCiAgICAvLyBoaWRkZW4gaW5wdXQgY2hhbmdlIGhhbmRsZXIsIGlucHV0IGNoYW5nZSB3aWxsIGJlIHRyaWdnZXJlZCBvbiBzZWxlY3RpbmcgYSBuZXcgaW1hZ2UKICAgIF9oYW5kbGVJbnB1dENoYW5nZSA6IGZ1bmN0aW9uKCkgewogICAgICAgIHRoaXMuX2Rpc3BsYXlJbWFnZSgpOwogICAgfSwKCiAgICBfaW1hZ2VDbGljayA6IGZ1bmN0aW9uKGNsaWNrRXZlbnQpIHsKICAgICAgICAvL2FzIHRoZSBpbnB1dCBidXR0b24gaXMgaGlkZGVuIHdlIHRyaWdnZXIgY2xpY2sgZXhwbGljaXRseSBvbiBjbGljayBvZiB0aGUgd2lkZ2V0CiAgICAgICAgdGhpcy4kd2lkZ2V0SW5wdXQudHJpZ2dlcigiY2xpY2siKTsKICAgIH0sCgogICAgLy8gcmVtb3ZlcyAiZGF0YVw6LipcO2Jhc2U2NCwiIGZyb20gdGhlIGltYWdlIGJhc2U2NCBzdHJpbmcKICAgIF9leHRyYWN0RGF0YSA6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL2RhdGFcOi4qXDtiYXNlNjQsLywgIiIpOwogICAgfSwKCiAgICAvLyBwcmV2aWV3cyBpbWFnZSBpbiB0aGUgaW1hZ2VmaWVsZCB3aWRnZXQKICAgIF9kaXNwbGF5SW1hZ2UgOiBmdW5jdGlvbigpIHsKICAgICAgICB2YXIgaW1hZ2VGaWxlID0gdGhpcy4kd2lkZ2V0SW5wdXQuZ2V0KDApLmZpbGVzID8gdGhpcy4kd2lkZ2V0SW5wdXQuZ2V0KDApLmZpbGVzWzBdIDogbnVsbDsKICAgICAgICBpZiAoaW1hZ2VGaWxlICYmIHRoaXMuX2lzRmlsZU9mSW1hZ2VUeXBlKGltYWdlRmlsZS5uYW1lKSkgewogICAgICAgICAgICBpZiAodGhpcy5yZWFkZXIpIHsKICAgICAgICAgICAgICAgIC8vcmVhZEFzRGF0YVVSTCBtZXRob2QgaXMgdXNlZCB0byByZWFkIHRoZSBjb250ZW50cyBvZiB0aGUgc3BlY2lmaWVkIGZpbGUsIHJlc3VsdCBhdHRyaWJ1dGUgY29udGFpbnMgIHRoZSBkYXRhIGFzIGEgVVJMIHJlcHJlc2VudGluZyB0aGUgZmlsZSdzIGRhdGEgYXMgYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcKICAgICAgICAgICAgICAgIHRoaXMucmVhZGVyLnJlYWRBc0RhdGFVUkwoaW1hZ2VGaWxlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sCgogICAgLy8gVGVzdCBmb3Igc3VwcG9ydGVkIGltYWdlIGZpbGUoanBnLGpwZWcscG5nLGdpZix0aWYsYm1wKQogICAgX2lzRmlsZU9mSW1hZ2VUeXBlIDogZnVuY3Rpb24oZmlsZU5hbWUpIHsKICAgICAgICBpZiAoZmlsZU5hbWUpIHsKICAgICAgICAgICAgcmV0dXJuICgvXC4oanBlP2d8cG5nfGdpZnx0aWZ8Ym1wKSQvaS50ZXN0KGZpbGVOYW1lKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfSk7Cn0pKCQpOwovKioKICogQ3JlYXRlZCB3aXRoIEludGVsbGlKIElERUEuCiAqIFVzZXI6IHJwYW5kZXkKICogRGF0ZTogMTIvMjQvMTIKICogVGltZTogODowNiBQTQogKiBUbyBjaGFuZ2UgdGhpcyB0ZW1wbGF0ZSB1c2UgRmlsZSB8IFNldHRpbmdzIHwgRmlsZSBUZW1wbGF0ZXMuCiAqLwoKCihmdW5jdGlvbigkKXsKICAgICQud2lkZ2V0KCAieGZhV2lkZ2V0LnNpZ25hdHVyZUZpZWxkIiwgJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldCwgewoKICAgICAgICBfd2lkZ2V0TmFtZToic2lnbmF0dXJlRmllbGQiLAoKICAgICAgICBnZXRPcHRpb25zTWFwOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LHBhcmVudE9wdGlvbnNNYXAsewogICAgICAgICAgICAgICAgImRpc3BsYXlWYWx1ZSI6IGZ1bmN0aW9uKHZhbCkge30sCiAgICAgICAgICAgICAgICAiYWNjZXNzIjogZnVuY3Rpb24odmFsKSB7fQogICAgICAgICAgICB9KQogICAgICAgIH0sCgogICAgICAgIHJlbmRlciA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgJGNvbnRyb2wgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5yZW5kZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgLy9wZXNzaW1pc3RpYyBjaGVja3MKICAgICAgICAgICAgaWYoJGNvbnRyb2wpIHsKICAgICAgICAgICAgICAgICRjb250cm9sLmF0dHIoInJlYWRPbmx5IiwicmVhZG9ubHkiKS5hdHRyKCJkaXNhYmxlZCIsIHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAkY29udHJvbDsKICAgICAgICB9CiAgICB9KTsKfSkoJCk7Ci8qCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX19fCiAqCiAqIENvcHlyaWdodCAyMDExLTIwMTIgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogc3VwcGxpZXJzIGFuZCBtYXkgYmUgY292ZXJlZCBieSBVLlMuIGFuZCBGb3JlaWduIFBhdGVudHMsCiAqIHBhdGVudHMgaW4gcHJvY2VzcywgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuCiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKi8KIAovKioKICogd2lkZ2V0IGRlZmluaXRpb24gZm9yIHNjcmliYmxlYWJsZSBmaWVsZAogKi8KKGZ1bmN0aW9uKCQseGZhbGliKXsKCiB2YXIgVG91Y2hVdGlsPXhmYWxpYi51dC5Ub3VjaFV0aWw7CiB2YXIgU2NyaWJibGVVdGlsPShmdW5jdGlvbigpewogICAgICByZXR1cm4gewogICAgICAgICAgbG9jYWxlU3RyaW5nOmZ1bmN0aW9uKGlkKXsKICAgICAgICAgICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmVuY29kZVNjcmlwdGFibGVUYWdzKCQueGZhV2lkZ2V0LmFic3RyYWN0V2lkZ2V0LnByb3RvdHlwZS5sb2NhbGVTdHJpbmdzKClbaWRdKSAgfHwgaWQ7CiAgICAgICAgICB9CiAgICAgIH07CiB9KSgpOwogdmFyIERFTEVURV9LRVkgPSA0NjsKIHZhciBFU0NfS0VZID0gMjc7CiB2YXIgRU5URVJfS0VZID0gMTM7Ci8qKgogKiBTY3JpYmJsZSBjbGFzcyBkZWZpbml0aW9uLCB1c2VkIGZvciBkcmF3aW5nIG9uIGNhbnZhcyB1c2luZyBtb3VzZSBvciB0b3VjaAogKi8KZnVuY3Rpb24gU2NyaWJibGUoIGNhbnZhc0lELGltYWdlLF93aWR0aCxfaGVpZ2h0LCBjYWxsYmFjaykgewogICAgdGhpcy5fY2FsbGJhY2sgPSBjYWxsYmFjazsKICAgIHRoaXMuY2FudmFzSUQgPSBjYW52YXNJRDsKICAgIHRoaXMuX2xpbmVXaWR0aD01OwogICAgdGhpcy5jYW52YXMgPSAkKCIjIitjYW52YXNJRCk7CiAgICB0aGlzLmNvbnRleHQgPSB0aGlzLmNhbnZhcy5nZXQoMCkuZ2V0Q29udGV4dCgiMmQiKTsgCiAgICB0aGlzLmNvbnRleHQuY2xlYXJSZWN0KDAsMCx0aGlzLmNhbnZhcy53aWR0aCx0aGlzLmNhbnZhcy5oZWlnaHQpOwogICAgdGhpcy5fZW5hYmxlZD10cnVlOwogICAgdGhpcy5jb250ZXh0LnN0cm9rZVN0eWxlID0gIiMwMDAwMDAiOwogICAgdGhpcy5jYW52YXNCb3JkZXJXaWR0aCA9IHBhcnNlSW50KHRoaXMuY2FudmFzLmNzcygnYm9yZGVyLWxlZnQtd2lkdGgnKSwxMCk7IC8vIGFzc3VtaW5nIHRvcCBhbmQgbGVmdCBib3JkZXJzIGFyZSBzYW1lIHdpZHRoCiAgICB0aGlzLmNvbnRleHQubGluZVdpZHRoID0gdGhpcy5fbGluZVdpZHRoOwogICAgdGhpcy5sYXN0TW91c2VQb2ludCA9IHt4OjAsIHk6MH07CiAgICAKICAgIHRoaXMuY2FudmFzWzBdLndpZHRoID0gX3dpZHRoOy8vIHRoaXMuY2FudmFzLnBhcmVudCgpLmlubmVyV2lkdGgoKTsKICAgIHRoaXMuY2FudmFzWzBdLmhlaWdodCA9IF9oZWlnaHQ7Ly90aGlzLmNhbnZhcy5wYXJlbnQoKS5pbm5lckhlaWdodCgpOwogICAgaWYoIWltYWdlKXsKICAgICAgICB0aGlzLmNvbnRleHQuZmlsbFN0eWxlICAgPSAnI2ZmZmZmZic7CiAgICAgICAgdGhpcy5jb250ZXh0LmNsZWFyUmVjdCgwLDAsX3dpZHRoLF9oZWlnaHQpOwogICAgfSBlbHNlIHsKICAgICAgICB0aGlzLmNvbnRleHQuZHJhd0ltYWdlKGltYWdlLDAsMCk7CiAgICB9CiAgICB0aGlzLmNhbnZhcy5vbiggVG91Y2hVdGlsLlBPSU5URVJfRE9XTiwgdGhpcy5vbkNhbnZhc01vdXNlRG93bigpICk7Cn0KU2NyaWJibGUucHJvdG90eXBlLnNldExpbmVXaWR0aD1mdW5jdGlvbih3KXsKICAgIHRoaXMuX2xpbmVXaWR0aD13Owp9OwpTY3JpYmJsZS5wcm90b3R5cGUub25DYW52YXNNb3VzZURvd24gPSBmdW5jdGlvbiAoKSB7CiAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICByZXR1cm4gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICBpZihUb3VjaFV0aWwuZ2V0VG91Y2hlcyhldmVudCkubGVuZ3RoIDwgMil7CiAgICAgICAgICAgIHNlbGYubW91c2VNb3ZlSGFuZGxlciA9IHNlbGYub25DYW52YXNNb3VzZU1vdmUoKTsKICAgICAgICAgICAgc2VsZi5tb3VzZVVwSGFuZGxlciA9IHNlbGYub25DYW52YXNNb3VzZVVwKCk7CiAgICAgICAgICAgIC8vQ1EtNDI2MTc2NSA6IFNjcmliYmxlIHNpZ24gc2Nyb2xsIGlzc3VlIHdpdGggaW9zCiAgICAgICAgICAgIC8vaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDk1MDAzMzkvY2FudC1wcmV2ZW50LXRvdWNobW92ZS1mcm9tLXNjcm9sbGluZy13aW5kb3ctb24taW9zCiAgICAgICAgICAgIC8vaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9qcXVlcnkvaXNzdWVzLzI4NzEKICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihUb3VjaFV0aWwuUE9JTlRFUl9NT1ZFLCBzZWxmLm1vdXNlTW92ZUhhbmRsZXIseyBwYXNzaXZlOiBmYWxzZSB9KTsKICAgICAgICAgICAgJChkb2N1bWVudCkub24oVG91Y2hVdGlsLlBPSU5URVJfVVAsIHNlbGYubW91c2VVcEhhbmRsZXIgKTsKICAgICAgICAgICAgc2VsZi51cGRhdGVNb3VzZVBvc2l0aW9uKCBldmVudCApOwogICAgICAgICAgICBzZWxmLnVwZGF0ZUNhbnZhcyggZXZlbnQgKTsKICAgICAgICB9CiAgICB9Cn07CgpTY3JpYmJsZS5wcm90b3R5cGUub25DYW52YXNNb3VzZU1vdmUgPSBmdW5jdGlvbiAoKSB7CiAgICB2YXIgc2VsZiA9IHRoaXM7CiAgICByZXR1cm4gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICBpZihUb3VjaFV0aWwuZ2V0VG91Y2hlcyhldmVudCkubGVuZ3RoIDwgMil7CiAgICAgICAgICAgIHNlbGYudXBkYXRlQ2FudmFzKCBldmVudCApOwogICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9OwoKU2NyaWJibGUucHJvdG90eXBlLm9uQ2FudmFzTW91c2VVcCA9IGZ1bmN0aW9uIChldmVudCkgewogICAgdmFyIHNlbGYgPSB0aGlzOwogICAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihUb3VjaFV0aWwuUE9JTlRFUl9NT1ZFLCBzZWxmLm1vdXNlTW92ZUhhbmRsZXIseyBwYXNzaXZlOiBmYWxzZSB9KTsKICAgICAgICAkKGRvY3VtZW50KS5vZmYoVG91Y2hVdGlsLlBPSU5URVJfVVAsIHNlbGYubW91c2VVcEhhbmRsZXIgKTsKICAgICAgICBzZWxmLm1vdXNlTW92ZUhhbmRsZXIgPSBudWxsOwogICAgICAgIHNlbGYubW91c2VVcEhhbmRsZXIgPSBudWxsOwogICAgfQp9OwoKU2NyaWJibGUucHJvdG90eXBlLnVwZGF0ZU1vdXNlUG9zaXRpb24gPSBmdW5jdGlvbiAoZXZlbnQpIHsKICAgIGlmKCF0aGlzLl9lbmFibGVkKSByZXR1cm4gOwogICAgdmFyIHRhcmdldCA9IFRvdWNoVXRpbC5nZXRUb3VjaEV2ZW50KGV2ZW50KTsKCiAgICB2YXIgb2Zmc2V0ID0gdGhpcy5jYW52YXMub2Zmc2V0KCk7CiAgICAvKiBJbiBJRT49MTAgcGFnZVggdmFsdWVzIGFyZSBpbmNvcnJlY3Qgd2hlbiB1c2luZyB6b29tCiAgICAgc28gY2FsY3VsYXRlIHRoZW0gdXNpbmcgY2xpZW50WCBhbmQgc2Nyb2xsTGVmdCAqLwogICAgdGhpcy5sYXN0TW91c2VQb2ludC54ID0gdGFyZ2V0LmNsaWVudFggKyAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpIC0gb2Zmc2V0LmxlZnQgLSB0aGlzLmNhbnZhc0JvcmRlcldpZHRoOwogICAgdGhpcy5sYXN0TW91c2VQb2ludC55ID0gdGFyZ2V0LmNsaWVudFkgKyAkKHdpbmRvdykuc2Nyb2xsVG9wKCkgLSBvZmZzZXQudG9wIC0gdGhpcy5jYW52YXNCb3JkZXJXaWR0aDsKCn07ClNjcmliYmxlLnByb3RvdHlwZS5faXNJbnNpZGVDYW52YXMgPSBmdW5jdGlvbih4LHkpewogICAgcmV0dXJuIHk+PTAgJiYgeTx0aGlzLmNhbnZhc1swXS5oZWlnaHQgJiYgeD49MCAmJiB4IDwgdGhpcy5jYW52YXNbMF0ud2lkdGg7Cn07CiAgICBTY3JpYmJsZS5wcm90b3R5cGUudXBkYXRlQ2FudmFzID0gZnVuY3Rpb24gKGV2ZW50KSB7CiAgICBpZighdGhpcy5fZW5hYmxlZCkgewogICAgICAgcmV0dXJuOwogICAgfQogICAgdmFyIG9sZFgsb2xkWSxkWCxkWSxjYW5EcmF3LHNjYWxlWCxzY2FsZVksY3NzV2lkdGgsY3NzSGVpZ2h0OwogICAgY3NzV2lkdGggPSBwYXJzZUludCh0aGlzLmNhbnZhc1swXS5zdHlsZS53aWR0aCwxMCk7CiAgICBjc3NIZWlnaHQgPSBwYXJzZUludCh0aGlzLmNhbnZhc1swXS5zdHlsZS5oZWlnaHQsMTApOwogICAgc2NhbGVYID0gIGNzc1dpZHRoP3RoaXMuY2FudmFzWzBdLndpZHRoL2Nzc1dpZHRoOjE7CiAgICBzY2FsZVkgPSBjc3NIZWlnaHQ/dGhpcy5jYW52YXNbMF0uaGVpZ2h0L2Nzc0hlaWdodDoxOwoKICAgIHNjYWxlWCAvPSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZm9ybVNjYWxlRmFjdG9yOwogICAgc2NhbGVZIC89IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3I7CgogICAgb2xkWCA9IHRoaXMubGFzdE1vdXNlUG9pbnQueCpzY2FsZVg7CiAgICBvbGRZID0gdGhpcy5sYXN0TW91c2VQb2ludC55KnNjYWxlWTsKICAgCiAgICB0aGlzLnVwZGF0ZU1vdXNlUG9zaXRpb24oIGV2ZW50ICk7CgogICAgdmFyIG5ld1ggPSAgdGhpcy5sYXN0TW91c2VQb2ludC54KnNjYWxlWDsKICAgIHZhciBuZXdZID0gIHRoaXMubGFzdE1vdXNlUG9pbnQueSpzY2FsZVk7CgogICAgZFggPSBNYXRoLmFicyhuZXdYIC0gb2xkWCApOwogICAgZFkgPSBNYXRoLmFicyhuZXdZIC0gb2xkWSApOwoKICAgIGNhbkRyYXcgPSAoIGRYID4gMCB8fCBkWSA+IDAgKSAmJiB0aGlzLl9pc0luc2lkZUNhbnZhcyhvbGRYLG9sZFkpICYmIHRoaXMuX2lzSW5zaWRlQ2FudmFzKG5ld1gsbmV3WSk7OwoKICAgIGlmKGNhbkRyYXcpewogICAgICAgIHRoaXMuY29udGV4dC5iZWdpblBhdGgoKTsKICAgICAgICB0aGlzLmNvbnRleHQubW92ZVRvKCBvbGRYLCBvbGRZICk7CiAgICAgICAgdGhpcy5jb250ZXh0LmxpbmVUbyhuZXdYLCBuZXdZICk7CiAgICAgICAgdGhpcy5jb250ZXh0LmxpbmVXaWR0aD10aGlzLl9saW5lV2lkdGg7CiAgICAgICAgdGhpcy5jb250ZXh0LmxpbmVDYXA9J3JvdW5kJzsKICAgICAgICB0aGlzLmNvbnRleHQuc3Ryb2tlKCk7CgkJCiAgICAgICAgdGhpcy5fY2FsbGJhY2soKTsKCQkKICAgIH0KfTsKClNjcmliYmxlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHsKCiAgICB2YXIgZGF0YVN0cmluZyA9IHRoaXMuY2FudmFzLmdldCgwKS50b0RhdGFVUkwoImltYWdlL3BuZyIpOwogICAgLy92YXIgaW5kZXggPSBkYXRhU3RyaW5nLmluZGV4T2YoICIsIiApKzE7CiAgICAvL2RhdGFTdHJpbmcgPSBkYXRhU3RyaW5nLnN1YnN0cmluZyggaW5kZXggKTsKCiAgICByZXR1cm4gZGF0YVN0cmluZzsKfTsKU2NyaWJibGUucHJvdG90eXBlLnNldEVuYWJsZWQ9ZnVuY3Rpb24oZW5hYmxlKXsKICAgIHRoaXMuX2VuYWJsZWQ9ZW5hYmxlOwp9OwpTY3JpYmJsZS5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7CgogICAgdmFyIGMgPSB0aGlzLmNhbnZhc1swXTsKICAgIHRoaXMuY29udGV4dC5jbGVhclJlY3QoIDAsIDAsIGMud2lkdGgsIGMuaGVpZ2h0ICk7Cn07CgoKLy8gSW1hZ2VFZGl0IGRpYWxvZyBib3gKdmFyIGltYWdlRWRpdERpYWxvZz0oZnVuY3Rpb24oXyl7CiAgCiAgICAvLyBodG1sIHVzZWQgdG8gY29uc3RydWN0IGRpYWxvZyBib3gKICAgIHZhciBodG1sU3RyPShmdW5jdGlvbigpewogICAgICAgICB2YXIgaHRtbD1bCiAgICAgICAgICAgICAnPGRpdiBpZD0iaUVCb3hfY29udGFpbmVyIiB0YWJpbmRleD0iMCIgcm9sZT0iZGlhbG9nIiBhcmlhLWxhYmVsPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoInBsZWFzZVNpZ25UZXh0IikrJyI+JywKICAgICAgICAgICAgICAgICAgJzxkaXYgaWQ9ImlFQm94X3BhbmVsIj4nLAogICAgICAgICAgICAgICAgICAgICAgJzxkaXYgIGlkID0gImlFQm94X0NhbmNlbCIgY2xhc3M9ImlFQm94X2J1dHRvbiIgdGFiaW5kZXg9IjAiIHJvbGU9ImJ1dHRvbiIgYXJpYS1sYWJlbD0iJytTY3JpYmJsZVV0aWwubG9jYWxlU3RyaW5nKCJjYW5jZWwiKSsnIiB0aXRsZT0iJytTY3JpYmJsZVV0aWwubG9jYWxlU3RyaW5nKCJjYW5jZWwiKSsnIiA+PC9kaXY+JywKICAgICAgICAgICAgICAgICAgJzwvZGl2PicsCiAgICAgICAgICAgICAgICAgICc8ZGl2IGlkPSJpRUJveF9jb250ZW50Ij4nLAogICAgICAgICAgICAgICAgICAgICAgJzxkaXYgaWQ9ImlFQm94X2NhbnZhc2VzIiBhbGlnbj1jZW50ZXI+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBzdHlsZT0iZGlzcGxheTppbmxpbmUtYmxvY2s7IHZlcnRpY2FsLWFsaWduOnRvcDsiPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGNhbnZhcyAgaWQ9ImlFQm94X2NhbnZhcyIgc3R5bGU9Im1hcmdpbjowcHg7Ym9yZGVyLWJvdHRvbTowcHg7IiB3aWR0aD0iNjk2IiBoZWlnaHQ9IjM5MCIgPjwvY2FudmFzPicgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxpbnB1dCB0eXBlPSJ0ZXh0IiBpZD0ia2V5Ym9hcmRfU2lnbl9Cb3giIG5hbWU9InNpZ25hdHVyZVRleHQiIHBsYWNlaG9sZGVyPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoInR5cGVZb3VyU2lnbmF0dXJlSGVyZSIpKyciPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGZpZWxkc2V0IGlkPSJpRUJveF9jYXB0aW9uIj48bGVnZW5kIGFsaWduPSJjZW50ZXIiPicrU2NyaWJibGVVdGlsLmxvY2FsZVN0cmluZygicGxlYXNlU2lnblRleHQiKSsnPC9sZWdlbmQ+PC9maWVsZHNldD4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICc8Y2FudmFzIGlkPSJpRUJveF9nZW9DYW52YXNSaWdodCIgd2lkdGg9IjAiIGhlaWdodD0iMCIgPjwvY2FudmFzPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJzxkaXY+PGNhbnZhcyBpZD0iaUVCb3hfZ2VvQ2FudmFzQm90dG9tIiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiA+PC9jYW52YXM+PC9kaXY+JywKICAgICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nLAogICAgICAgICAgICAgICAgICAgICAgJzxkaXY+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBpZD0iaUVCb3hfQnJ1c2giIGNsYXNzPSJpRUJveF9idXR0b24iIHRhYmluZGV4PSIwIiAgcm9sZT0iYnV0dG9uIiBhcmlhLWxhYmVsPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoImJydXNoZXMiKSsnIiAgdGl0bGU9IicrU2NyaWJibGVVdGlsLmxvY2FsZVN0cmluZygiYnJ1c2hlcyIpKyciPjwvZGl2PicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJzxkaXYgaWQ9ImlFQm94X0NsZWFyIiBjbGFzcz0iaUVCb3hfYnV0dG9uIiB0YWJpbmRleD0iMCIgIHJvbGU9ImJ1dHRvbiIgYXJpYS1sYWJlbD0iJytTY3JpYmJsZVV0aWwubG9jYWxlU3RyaW5nKCJjbGVhciIpKyciICB0aXRsZT0iJytTY3JpYmJsZVV0aWwubG9jYWxlU3RyaW5nKCJjbGVhciIpKyciID48L2Rpdj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICc8ZGl2IGlkPSJpRUJveF9HZW8iIGNsYXNzPSJpRUJveF9idXR0b24iIHRhYmluZGV4PSIwIiAgcm9sZT0iYnV0dG9uIiBhcmlhLWxhYmVsPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoImdlb2xvY2F0aW9uIikrJyIgIHRpdGxlPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoImdlb2xvY2F0aW9uIikrJyIgPjwvZGl2PicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgJzxkaXYgaWQ9ImlFQm94X1RleHQiIGNsYXNzPSJpRUJveF9idXR0b24iIHRhYmluZGV4PSIwIiAgcm9sZT0iYnV0dG9uIiBhcmlhLWxhYmVsPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoInR5cGVZb3VyTmFtZSIpKyciICB0aXRsZT0iJytTY3JpYmJsZVV0aWwubG9jYWxlU3RyaW5nKCJ0eXBlWW91ck5hbWUiKSsnIj48L2Rpdj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICc8ZGl2IGlkPSJpRUJveF90aXRsZSI+PC9kaXY+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBpZD0iaUVCb3hfT2siIGNsYXNzPSJpRUJveF9idXR0b24iIHRhYmluZGV4PSIwIiAgcm9sZT0iYnV0dG9uIiBhcmlhLWxhYmVsPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoIm9rIikrJyIgIHRpdGxlPSInK1NjcmliYmxlVXRpbC5sb2NhbGVTdHJpbmcoIm9rIikrJyIgPjwvZGl2PicsCiAgICAgICAgICAgICAgICAgICAgICAnPC9kaXY+JyAsCiAgICAgICAgICAgICAgICAgICc8L2Rpdj4nICwKICAgICAgICAgICAgICAgICAgJzxkaXYgaWQ9ImlFQm94X21vdmVmcmFtZSIgPjwvZGl2PicsCiAgICAgICAgICAgICAgICAgICc8ZGl2IGlkPSJpRUJveF9icnVzaExpc3QiID48L2Rpdj4nLAogICAgICAgICAgICAgICc8L2Rpdj4nXS5qb2luKCIiKTsKICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKXsKICAgICAgICAgICAgICByZXR1cm4gaHRtbDsKICAgICAgICAgICB9OwogICAgfSk7CgkKICAgIC8qKgoJICogICAKCSAqLwoJCiAgICB2YXIgZGlhbG9nT2JqID0gewogICAgICAgIHZlcnRpY2FsT2Zmc2V0OiAwLCAvLyByZW1vdmluZyB0aGUgbWFnaWMgdmFsdWUgb2YgLTc1IHNpbmNlIGl0IHdhcyBub3QgY2F1c2luZyBhbnkgaW1wYWN0CiAgICAgICAgaG9yaXpvbnRhbE9mZnNldDogMCwKICAgICAgICByZXBvc2l0aW9uT25SZXNpemU6IHRydWUsCiAgICAgICAgb3ZlcmxheU9wYWNpdHk6IC43NSwKICAgICAgICBvdmVybGF5Q29sb3I6ICcjQ0NDQ0NDJywKICAgICAgICBkcmFnZ2FibGU6IHRydWUsCiAgICAgICAgX2JydXNoZXM6WzIsMyw0LDUsNiw3LDgsOSwxMF0sCgkJX2J1dHRvbnNFbmFibGVkOnt9LAoJCV9pc09wZW46ZmFsc2UsCiAgICAgICAgc2hvdzpmdW5jdGlvbih0aXRsZSxjYWxsYmFjayl7CiAgICAgICAgICAgdGhpcy5fc2hvdyhjYWxsYmFjayk7CgkJICAgdGhpcy5fYnV0dG9uc0VuYWJsZWQ9e0dlbzp0cnVlLENsZWFyOnRydWUsT2s6dHJ1ZSxDYW5jZWw6dHJ1ZSxCcnVzaDp0cnVlLFRleHQ6dHJ1ZX07CiAgICAgICAgfSwKCQlzZXRFbmFibGVkOmZ1bmN0aW9uKGJ1dHRvbixlbmFibGUpewoJCSAgICBpZih0aGlzLl9idXR0b25zRW5hYmxlZFtidXR0b25dIT1lbmFibGUpewoJCSAgICAgICAgICAgdGhpcy5fYnV0dG9uc0VuYWJsZWRbYnV0dG9uXT1lbmFibGU7CgkJCQkgICBpZihlbmFibGUpewoJCQkJICAgICAgICQoJyNpRUJveF8nK2J1dHRvbikuZW1wdHkoJzxkaXYgc3R5bGU9ImJhY2tncm91bmQ6d2hpdGU7d2lkdGg6MTAwJTtoZWlnaHQ6MTAwJTtvcGFjaXR5OjAuNzU7Ij48L2Rpdj4nKS4KCQkJCSAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKCJkaXNhYmxlX2J1dHRvbiIpOwoJCQkJICAgfSBlbHNlIHsKCQkJCSAgICAgICAkKCcjaUVCb3hfJytidXR0b24pLmFwcGVuZCgnPGRpdiBzdHlsZT0iYmFja2dyb3VuZDp3aGl0ZTt3aWR0aDoxMDAlO2hlaWdodDoxMDAlO29wYWNpdHk6MC43NTsiPjwvZGl2PicpLgoJCQkJICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoImRpc2FibGVfYnV0dG9uIik7CgkJCQkgICB9CgkJCSAgICAgICAKCQkJfQoJCX0sCgkJZW5hYmxlQnV0dG9uczpmdW5jdGlvbihidXR0b25zKXsKCQkgICAgZm9yKHZhciBrIGluIGJ1dHRvbnMpewoJCQkJICAgdGhpcy5zZXRFbmFibGVkKGssYnV0dG9uc1trXSk7CgkJCX0KCQl9LAogICAgICAgIHRvZ2dsZUJydXNoTGlzdDpmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgICAgICBpZigkKCcjaUVCb3hfYnJ1c2hMaXN0JykuY3NzKCdkaXNwbGF5JykhPSdub25lJyl7CiAgICAgICAgICAgICAgICAgICAgJCgnI2lFQm94X2JydXNoTGlzdCcpLmNzcyh7ZGlzcGxheTonbm9uZSd9KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgdmFyIHRtcEZuID0gIGRvY3VtZW50Lm9uc2VsZWN0c3RhcnQ7CiAgICAgICAgICAgICAgICAgZG9jdW1lbnQub25zZWxlY3RzdGFydD1mdW5jdGlvbigpe3JldHVybiBmYWxzZTt9OwogICAgICAgICAgICAgICAgICQoJyNpRUJveF9icnVzaExpc3QnKS5jc3Moe2Rpc3BsYXk6J2Jsb2NrJyx2aXNpYmlsaXR5OidoaWRkZW4nfSk7CiAgICAgICAgICAgICAgICAgICAgJCgnI2lFQm94X2JydXNoTGlzdCcpLm9mZnNldCgkKCcjaUVCb3hfQnJ1c2gnKS5vZmZzZXQoKSk7CiAgICAgICAgICAgICAgICAgICAgJCgnI2lFQm94X2JydXNoTGlzdCcpLm9mZnNldCh7dG9wOiQoJyNpRUJveF9CcnVzaCcpLm9mZnNldCgpLnRvcC0kKCcjaUVCb3hfYnJ1c2hMaXN0JykuaGVpZ2h0KCl9KTsKICAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfYnJ1c2hMaXN0JykuY3NzKHtkaXNwbGF5OidibG9jaycsdmlzaWJpbGl0eTondmlzaWJsZSd9KTsKICAgICAgICAgICAgICAgICAgLy8gICQoJyNpRUJveF9icnVzaExpc3QnKS5mb2N1cygpOwogICAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfYnJ1c2hMaXN0Jykub25lKCdtb3VzZWxlYXZlJyxmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfYnJ1c2hMaXN0JykuY3NzKHtkaXNwbGF5Oidub25lJ30pOwogICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50Lm9uc2VsZWN0c3RhcnQ9dG1wRm47CiAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgIH0sCiAgICAgICAgX2F0dGFjaENhbGxiYWNrczogZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICB2YXIgc2lnQ2FudmFzID0gJCgnI2lFQm94X2NhbnZhcycpWzBdOwogICAgICAgICAgICB2YXIgY3R4PXNpZ0NhbnZhcy5nZXRDb250ZXh0KCIyZCIpOwogICAgICAgICAgICB2YXIgbWluU2lnQ2FudmFzRm9udFNpemU9MTA7CiAgICAgICAgICAgIHZhciBtYXhTaWdDYW52YXNGb250U2l6ZT03MDsKICAgICAgICAgICAgdmFyIHNpZ0NhbnZhc0ZvbnRTaXplPW1pblNpZ0NhbnZhc0ZvbnRTaXplOwogICAgICAgICAgICB2YXIgaW5pdGlhbFNpZ0NhbnZhc0ZvbnRTaXplPXNpZ0NhbnZhc0ZvbnRTaXplOwogICAgICAgICAgICB2YXIgaW5pdGlhbEZvbnRDYWxjdWxhdGVkRmxhZz1mYWxzZTsKICAgICAgICAgICAgdmFyIHNpZ0NhbnZhc0ZvbnRGYW1pbHk9InNhbnMtc2VyaWYsIEdlb3JnaWEiOwogICAgICAgICAgICB2YXIgc2lnQ2FudmFzRm9udFN0eWxlPSJpdGFsaWMiOwogICAgICAgICAgIF8uZWFjaCgiQ2FuY2VsLUNsZWFyLUdlby1Pay1CcnVzaC1UZXh0Ii5zcGxpdCgiLSIpLGZ1bmN0aW9uKHZhbCxpZHgpewogICAgICAgICAgICAgICAgICAgICQoIiNpRUJveF8iK3ZhbCkuY2xpY2soIGZ1bmN0aW9uKGV2ZW50KSB7CgkJCQkgICAgICAgaWYodGhhdC5fYnV0dG9uc0VuYWJsZWRbdmFsXSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sodmFsKTsKCQkJCSAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CgkJCQkJJCgiI2lFQm94XyIrdmFsKS5rZXlkb3duKCBmdW5jdGlvbihldmVudCkgewoJCQkJICAgICAgIGlmKHRoYXQuX2J1dHRvbnNFbmFibGVkW3ZhbF0gJiYgKGV2ZW50LmtleUNvZGUgPT0gRU5URVJfS0VZIHx8IGV2ZW50LmNoYXJDb2RlID09IEVOVEVSX0tFWSB8fCBldmVudC53aGljaCA9PSBFTlRFUl9LRVkpICl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sodmFsKTsKCQkJCSAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBfLmVhY2goJCgiI2lFQm94X2JydXNoTGlzdCIpLmNoaWxkcmVuKCksZnVuY3Rpb24oaXRtLGlkeCl7CiAgICAgICAgICAgICAgICAgICQoaXRtKS5vbihUb3VjaFV0aWwuUE9JTlRFUl9VUCxmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygiQnJ1c2hTZWxlY3QiLHRoYXQuX2JydXNoZXNbaWR4XSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfYnJ1c2hMaXN0JykuY3NzKHtkaXNwbGF5Oidub25lJ30pOwogICAgICAgICAgICAgICAgICAgICAgICAgIC8vICQoaXRtKS5jc3Moe2JhY2tncm91bmRDb2xvcjonI0ZGRkZGRid9KTsKICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICQoaXRtKS5vbihUb3VjaFV0aWwuUE9JTlRFUl9ET1dOLGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAkKGl0bSkuY3NzKHtiYWNrZ3JvdW5kQ29sb3I6JyNBQUFBQUEnfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAkKCcja2V5Ym9hcmRfU2lnbl9Cb3gnKS5rZXlkb3duKGZ1bmN0aW9uIChldmVudCl7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXRTaWduPSQoJyNrZXlib2FyZF9TaWduX0JveCcpWzBdLnZhbHVlOwoKICAgICAgICAgICAgICAgIGlmKGV2ZW50LmtleT09PSJCYWNrc3BhY2UiKSB7CiAgICAgICAgICAgICAgICAgICAgY3R4LmZvbnQ9c2lnQ2FudmFzRm9udFN0eWxlK3NpZ0NhbnZhc0ZvbnRTaXplKyJweCAiK3NpZ0NhbnZhc0ZvbnRGYW1pbHk7CiAgICAgICAgICAgICAgICAgICAgc2lnQ2FudmFzRm9udFNpemU9ZGlhbG9nT2JqLl9pbmNyZWFzZUZvbnRGb3JTaWduYXR1cmUoY3R4Lm1lYXN1cmVUZXh0KGlucHV0U2lnbikud2lkdGgsc2lnQ2FudmFzLndpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICBzaWdDYW52YXNGb250U2l6ZSxpbml0aWFsU2lnQ2FudmFzRm9udFNpemUpOwogICAgICAgICAgICAgICAgICAgIGN0eC5mb250PXNpZ0NhbnZhc0ZvbnRTdHlsZSsiICIrc2lnQ2FudmFzRm9udFNpemUrInB4ICIrc2lnQ2FudmFzRm9udEZhbWlseTsKICAgICAgICAgICAgICAgICAgICBjdHguY2xlYXJSZWN0KDAsIDAsIHNpZ0NhbnZhcy53aWR0aCwgc2lnQ2FudmFzLmhlaWdodCk7CiAgICAgICAgICAgICAgICAgICAgY3R4LmZpbGxUZXh0KGlucHV0U2lnbiwgMywgc2lnQ2FudmFzRm9udFNpemUsIHNpZ0NhbnZhcy53aWR0aC01KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICQoIiNrZXlib2FyZF9TaWduX0JveCIpLmtleXVwKGZ1bmN0aW9uIChldmVudCl7CiAgICAgICAgICAgICAgICB2YXIgaW5wdXRTaWduPSQoJyNrZXlib2FyZF9TaWduX0JveCcpWzBdLnZhbHVlOwogICAgICAgICAgICAgICAgaWYoaW5wdXRTaWduLmxlbmd0aD09MCkgewogICAgICAgICAgICAgICAgICAgIGRpYWxvZ09iai5lbmFibGVCdXR0b25zKHtPazogZmFsc2UsIENsZWFyOiBmYWxzZX0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYoaW5wdXRTaWduLmxlbmd0aD49MSAmJiBpbnB1dFNpZ24udHJpbSgpLmxlbmd0aCE9MCkgewogICAgICAgICAgICAgICAgICAgIGRpYWxvZ09iai5lbmFibGVCdXR0b25zKHtPazogdHJ1ZSwgQ2xlYXI6IHRydWV9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGluaXRpYWxGb250Q2FsY3VsYXRlZEZsYWc9PT1mYWxzZSl7CiAgICAgICAgICAgICAgICAgICAgc2lnQ2FudmFzRm9udFNpemU9c2lnQ2FudmFzLmhlaWdodC0yMDsKICAgICAgICAgICAgICAgICAgICBzaWdDYW52YXNGb250U2l6ZT1zaWdDYW52YXNGb250U2l6ZTxtaW5TaWdDYW52YXNGb250U2l6ZT9taW5TaWdDYW52YXNGb250U2l6ZTpzaWdDYW52YXNGb250U2l6ZTsKICAgICAgICAgICAgICAgICAgICBzaWdDYW52YXNGb250U2l6ZT1zaWdDYW52YXNGb250U2l6ZT5tYXhTaWdDYW52YXNGb250U2l6ZT9tYXhTaWdDYW52YXNGb250U2l6ZTpzaWdDYW52YXNGb250U2l6ZTsKICAgICAgICAgICAgICAgICAgICBpbml0aWFsU2lnQ2FudmFzRm9udFNpemU9c2lnQ2FudmFzRm9udFNpemU7CiAgICAgICAgICAgICAgICAgICAgJCgnI2tleWJvYXJkX1NpZ25fQm94JylbMF0uc3R5bGUuZm9udD1zaWdDYW52YXNGb250U3R5bGUrIiAycmVtICIrc2lnQ2FudmFzRm9udEZhbWlseTsKICAgICAgICAgICAgICAgICAgICBpbml0aWFsRm9udENhbGN1bGF0ZWRGbGFnPXRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdHguZm9udD1zaWdDYW52YXNGb250U3R5bGUrc2lnQ2FudmFzRm9udFNpemUrInB4ICIrc2lnQ2FudmFzRm9udEZhbWlseTsKICAgICAgICAgICAgICAgIHNpZ0NhbnZhc0ZvbnRTaXplPWRpYWxvZ09iai5fZGVjcmVhc2VGb250Rm9yU2lnbmF0dXJlKGN0eCxpbnB1dFNpZ24sc2lnQ2FudmFzLndpZHRoLAogICAgICAgICAgICAgICAgICAgIHNpZ0NhbnZhc0ZvbnRTaXplLHNpZ0NhbnZhc0ZvbnRGYW1pbHkpOwogICAgICAgICAgICAgICAgY3R4LmZvbnQ9c2lnQ2FudmFzRm9udFN0eWxlKyIgIitzaWdDYW52YXNGb250U2l6ZSsicHggIitzaWdDYW52YXNGb250RmFtaWx5OwogICAgICAgICAgICAgICAgY3R4LmNsZWFyUmVjdCgwLCAwLCBzaWdDYW52YXMud2lkdGgsIHNpZ0NhbnZhcy5oZWlnaHQpOwogICAgICAgICAgICAgICAgY3R4LmZpbGxUZXh0KGlucHV0U2lnbiwzLHNpZ0NhbnZhc0ZvbnRTaXplLHNpZ0NhbnZhcy53aWR0aC01KTsKICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIC8vIGNhcHR1cmUgdGFiIGtleSBhbmQgZXNjYXBlCiAgICAgICAgICAgICQoJyNpRUJveF9jb250YWluZXInKS5rZXlkb3duKGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgICAgIHZhciBmaXJzdEZvY3VzYWJsZUl0ZW0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIjaUVCb3hfY29udGFpbmVyIik7CiAgICAgICAgICAgICAgICB2YXIgbGFzdEZvY3VzYWJsZUl0ZW0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIjaUVCb3hfT2siKTsKICAgICAgICAgICAgICAgIHZhciBLRVlDT0RFX1RBQiA9IDk7CiAgICAgICAgICAgICAgICB2YXIgaXNUYWJQcmVzc2VkID0gKGV2ZW50LmtleSA9PT0gJ1RhYicgfHwgZXZlbnQua2V5Q29kZSA9PT0gS0VZQ09ERV9UQUIpOwogICAgICAgICAgICAgICAgaWYoKGV2ZW50LmtleUNvZGUgPT0gRVNDX0tFWSB8fCBldmVudC5jaGFyQ29kZSA9PSBFU0NfS0VZIHx8IGV2ZW50LndoaWNoID09IEVTQ19LRVkpKSB7CiAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygiQ2FuY2VsIik7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzVGFiUHJlc3NlZCkgewogICAgICAgICAgICAgICAgICAgIC8vIFRyYXAgZm9jdXMgaW5zaWRlIHRoZSBkaWFsb2cgYm94CiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5ICYmIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT09IGZpcnN0Rm9jdXNhYmxlSXRlbSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyB3aGVuIHNoaWZ0ICsgdGFiIGtleSBpcyBwcmVzc2VkCiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RGb2N1c2FibGVJdGVtLmZvY3VzKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09PSBsYXN0Rm9jdXNhYmxlSXRlbSkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyB3aGVuIHRhYiBrZXkgaXMgcHJlc3NlZAogICAgICAgICAgICAgICAgICAgICAgICBmaXJzdEZvY3VzYWJsZUl0ZW0uZm9jdXMoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIGlmKHRoaXMuZHJhZ2dhYmxlKXsKICAgICAgICAgICAgICAgIHRoaXMuX21ha2VEcmFnZ2FibGUoVG91Y2hVdGlsLlRPVUNIX0VOQUJMRUQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2RlY3JlYXNlRm9udEZvclNpZ25hdHVyZTpmdW5jdGlvbihjdHgsaW5wdXRTaWduLHNpZ0NhbnZhc1dpZHRoLGZvbnRTaXplLHNpZ0NhbnZhc0ZvbnRGYW1pbHkpewogICAgICAgICAgICB3aGlsZShjdHgubWVhc3VyZVRleHQoaW5wdXRTaWduKS53aWR0aD5zaWdDYW52YXNXaWR0aC01ICYmIGZvbnRTaXplPjIwKXsKICAgICAgICAgICAgICAgIGZvbnRTaXplPWZvbnRTaXplLTEwOwogICAgICAgICAgICAgICAgY3R4LmZvbnQ9Zm9udFNpemUrInB4ICIrc2lnQ2FudmFzRm9udEZhbWlseTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZm9udFNpemUKICAgICAgICB9LAogICAgICAgIF9pbmNyZWFzZUZvbnRGb3JTaWduYXR1cmU6ZnVuY3Rpb24odGV4dFdpZHRoLHNpZ0NhbnZhc1dpZHRoLGZvbnRTaXplLGluaXRpYWxTaWdDYW52YXNGb250U2l6ZSl7CiAgICAgICAgICAgIGlmKHNpZ0NhbnZhc1dpZHRoLXRleHRXaWR0aD4wKXsKICAgICAgICAgICAgICAgIGZvbnRTaXplPWluaXRpYWxTaWdDYW52YXNGb250U2l6ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZm9udFNpemU7CiAgICAgICAgfSwKICAgICAgICBfbWFrZURyYWdnYWJsZTpmdW5jdGlvbih0b3VjaEVuYWJsZWQpewogICAgICAgICAgICAgIHZhciBfaXNNb3VzZURvd249ZmFsc2U7CiAgICAgICAgICAgICAgdmFyIF90aGF0PXRoaXM7CiAgICAgICAgICAgICAgdmFyIGRYOwogICAgICAgICAgICAgIHZhciBkWTsKICAgICAgICAgICAgICB2YXIgb2Zmc2V0UG9zOwogICAgICAgICAgICAgIHZhciBfbW91c2VNb3ZGdW47CiAgICAgICAgICAgICAgdmFyIF9tb3VzZVVwRnVuOwogICAgICAgICAgICAgICQoJyNpRUJveF9wYW5lbCcpLm9uKFRvdWNoVXRpbC5QT0lOVEVSX0RPV04sZnVuY3Rpb24oIGV2ZW50ICl7CiAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgIGlmKFRvdWNoVXRpbC5nZXRUb3VjaGVzKGV2ZW50KS5sZW5ndGggPCAyKXsKICAgICAgICAgICAgICAgICAgICAgIGlmKCQoZXZlbnQudGFyZ2V0KS5pcygnI2lFQm94X3BhbmVsJykpewogICAgICAgICAgICAgICAgICAgICAgICAgICQoJ2JvZHknKVswXS5hZGRFdmVudExpc3RlbmVyKFRvdWNoVXRpbC5QT0lOVEVSX01PVkUsX21vdXNlTW92RnVuPWZ1bmN0aW9uKCBldmVudCApewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihUb3VjaFV0aWwuZ2V0VG91Y2hlcyhldmVudCkubGVuZ3RoIDwgMiAmJiBfaXNNb3VzZURvd24pewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBldnQgPSBUb3VjaFV0aWwuZ2V0VG91Y2hFdmVudChldmVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVsWCA9IGV2dC5wYWdlWCAtIGRYOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRlbFkgPSBldnQucGFnZVkgLSBkWTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJyNpRUJveF9tb3ZlZnJhbWUnKS5vZmZzZXQoewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogb2Zmc2V0UG9zLnRvcCtkZWxZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IG9mZnNldFBvcy5sZWZ0K2RlbFgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgeyBwYXNzaXZlOiBmYWxzZSB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAkKCdib2R5Jykub24oVG91Y2hVdGlsLlBPSU5URVJfVVAsX21vdXNlVXBGdW49ZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihfaXNNb3VzZURvd24pewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9mZnNldE1vdmUgPSAkKCcjaUVCb3hfbW92ZWZyYW1lJykub2Zmc2V0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG9wRWRnZSAgPSAkKHdpbmRvdykuc2Nyb2xsVG9wKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYm90dG9tRWRnZSA9IHRvcEVkZ2UgKyAkKHdpbmRvdykuaGVpZ2h0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihvZmZzZXRNb3ZlLnRvcCAtIHRvcEVkZ2UgPCAxKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRNb3ZlLnRvcCA9IHRvcEVkZ2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihvZmZzZXRNb3ZlLnRvcCAtIGJvdHRvbUVkZ2UgKyAkKCcjaUVCb3hfcGFuZWwnKS5oZWlnaHQoKSA+IDAgKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXRNb3ZlLnRvcCA9IGJvdHRvbUVkZ2UgLSAkKCcjaUVCb3hfcGFuZWwnKS5oZWlnaHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoJyNpRUJveF9jb250YWluZXInKS5vZmZzZXQob2Zmc2V0TW92ZSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJCgnI2lFQm94X21vdmVmcmFtZScpLmNzcyh7ZGlzcGxheTonbm9uZSd9KS5vZmZzZXQob2Zmc2V0TW92ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaXNNb3VzZURvd249ZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCdib2R5JylbMF0ucmVtb3ZlRXZlbnRMaXN0ZW5lcihUb3VjaFV0aWwuUE9JTlRFUl9NT1ZFLF9tb3VzZU1vdkZ1bix7IHBhc3NpdmU6IGZhbHNlIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJCgnYm9keScpLm9mZihUb3VjaFV0aWwuUE9JTlRFUl9VUCxfbW91c2VVcEZ1bik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGV2dCA9IFRvdWNoVXRpbC5nZXRUb3VjaEV2ZW50KGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICBfaXNNb3VzZURvd249dHJ1ZTsgZFggPSBldnQucGFnZVg7ZFk9ZXZ0LnBhZ2VZOwogICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldFBvcyA9ICQoJyNpRUJveF9jb250YWluZXInKS5vZmZzZXQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfbW92ZWZyYW1lJykuY3NzKHtkaXNwbGF5OidibG9jayd9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfbW92ZWZyYW1lJykub2Zmc2V0KG9mZnNldFBvcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgJCgnI2lFQm94X21vdmVmcmFtZScpLmNzcygnd2lkdGgnLCQoJyNpRUJveF9jb250YWluZXInKS5jc3MoJ3dpZHRoJykpOwogICAgICAgICAgICAgICAgICAgICAgICAgICQoJyNpRUJveF9tb3ZlZnJhbWUnKS5jc3MoJ2hlaWdodCcsJCgnI2lFQm94X2NvbnRhaW5lcicpLmNzcygnaGVpZ2h0JykpOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAKICAgICAgICB9LAogICAgICAgIF9jcmVhdGVCcnVzaGVzOmZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgIHZhciBfdGhhdD10aGlzOwogICAgICAgICAgICAgIF8uZWFjaCh0aGlzLl9icnVzaGVzLGZ1bmN0aW9uKHZhbCxpZHgpewogICAgICAgICAgICAgICAgICB2YXIgZGl2ZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdESVYnKTsKICAgICAgICAgICAgICAgICAgdmFyIGNudiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ0NBTlZBUycpOwogICAgICAgICAgICAgICAgICB2YXIgY3R4ID0gY252LmdldENvbnRleHQoJzJkJyk7CiAgICAgICAgICAgICAgICAgIGNudi5zdHlsZS5ib3JkZXI9JzFweCBzb2xpZCAjQUFBQUFBJzsKICAgICAgICAgICAgICAgICAgY252LndpZHRoPVRvdWNoVXRpbC5UT1VDSF9FTkFCTEVEPzIwMDoxMDA7CiAgICAgICAgICAgICAgICAgIGNudi5oZWlnaHQ9VG91Y2hVdGlsLlRPVUNIX0VOQUJMRUQ/NDA6MjA7OwogICAgICAgICAgICAgICAgICBjdHgubGluZVdpZHRoPXZhbDsKICAgICAgICAgICAgICAgICAgY3R4LmJlZ2luUGF0aCgpOwogICAgICAgICAgICAgICAgICBjdHgubW92ZVRvKDEwLGNudi5oZWlnaHQvMik7CiAgICAgICAgICAgICAgICAgIGN0eC5saW5lVG8oY252LndpZHRoLTEwLGNudi5oZWlnaHQvMik7CiAgICAgICAgICAgICAgICAgIGN0eC5zdHJva2UoKTsKICAgICAgICAgICAgICAgICAgZGl2ZWwuYXBwZW5kQ2hpbGQoY252KTsKICAgICAgICAgICAgICAgICAgJCgnI2lFQm94X2JydXNoTGlzdCcpLmFwcGVuZChkaXZlbCk7CiAgICAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgkJZ2V0SXNPcGVuOmZ1bmN0aW9uKCl7CgkJICAgIHJldHVybiBkaWFsb2dPYmouX2lzT3BlbjsKCQl9LAoJCXNldElzT3BlbjpmdW5jdGlvbihvcGVuKXsKCQkgICAgZGlhbG9nT2JqLl9pc09wZW4gPSBvcGVuOwoJCX0sCiAgICAgICAgX3Nob3c6IGZ1bmN0aW9uKGNhbGxiYWNrKSB7CiAgICAgICAgICAgIGRpYWxvZ09iai5oaWRlKCk7CiAgICAgICAgICAgIGRpYWxvZ09iai5fb3ZlcmxheSgnc2hvdycpOwogICAgICAgICAgICAKICAgICAgICAgICAgJCgiQk9EWSIpLmFwcGVuZChodG1sU3RyKCkpOwogICAgICAgICAgICBkaWFsb2dPYmouc2V0SXNPcGVuKHRydWUpOwogICAgICAgICAgICAkKCcjaUVCb3hfY29udGFpbmVyJykuZm9jdXMoKTsKICAgICAgICAgICAgZGlhbG9nT2JqLl9jcmVhdGVCcnVzaGVzKCk7CgogICAgICAgICAgICBkaWFsb2dPYmouX3JlcG9zaXRpb24oKTsKCiAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSBzcGFjaW5nIGFyb3VuZCBjYW52YXMgYXJlYQogICAgICAgICAgICAvLyB0aGlzIHdpbGwgYmUgdXNlZCB0byBmaW5kIGNhbnZhcyBkaW1lbnNpb25zIGJhc2VkIG9uIGF2YWlsYWJsZSBzY3JlZW4gYXJlYS4KICAgICAgICAgICAgdmFyIGNvbnRhaW5lcl9lbCA9ICQoJyNpRUJveF9jb250YWluZXInKTsKICAgICAgICAgICAgdmFyIGNhbnZhc19lbCA9ICAkKCcjaUVCb3hfY2FudmFzJyk7CiAgICAgICAgICAgIHZhciBjb250YWluZXJfd2lkdGggPSAkKCcjaUVCb3hfY29udGFpbmVyJykub3V0ZXJXaWR0aCh0cnVlKTsKICAgICAgICAgICAgdmFyIGNvbnRhaW5lcl9oZWlnaHQgPSAkKCcjaUVCb3hfY29udGFpbmVyJykub3V0ZXJIZWlnaHQodHJ1ZSk7CiAgICAgICAgICAgIHZhciBjYW52YXNfd2lkdGggPSBjYW52YXNfZWxbMF0ud2lkdGg7CiAgICAgICAgICAgIHZhciBjYW52YXNfaGVpZ2h0ID0gY2FudmFzX2VsWzBdLmhlaWdodDsKICAgICAgICAgICAgZGlhbG9nT2JqLmNhbnZhc19zcGFjaW5nID0geyB4OmNvbnRhaW5lcl93aWR0aCAtIGNhbnZhc193aWR0aCwgeTpjb250YWluZXJfaGVpZ2h0LWNhbnZhc19oZWlnaHR9OwoKICAgICAgICAgICAgZGlhbG9nT2JqLl9tYWludGFpblBvc2l0aW9uKHRydWUpOwogICAgICAgICAgICAKICAgICAgICAgICAgZGlhbG9nT2JqLl9hdHRhY2hDYWxsYmFja3MoY2FsbGJhY2spOwogICAgICAgIH0sCgogICAgICAgIGhpZGU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAkKCIjaUVCb3hfY29udGFpbmVyIikucmVtb3ZlKCk7CiAgICAgICAgICAgIHRoaXMuX292ZXJsYXkoJ2hpZGUnKTsKICAgICAgICAgICAgZGlhbG9nT2JqLnNldElzT3BlbihmYWxzZSk7CiAgICAgICAgICAgIHRoaXMuX21haW50YWluUG9zaXRpb24oZmFsc2UpOwogICAgICAgIH0sCiAgICAgICAgX292ZXJsYXlSZXNpemU6ZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgaWYoJCgiI2lFQm94X292ZXJsYXkiKS5oZWlnaHQoKSE9ICQoZG9jdW1lbnQpLmhlaWdodCgpKXsKICAgICAgICAgICAgICAgICQoIiNpRUJveF9vdmVybGF5IikuaGVpZ2h0KCAkKGRvY3VtZW50KS5oZWlnaHQoKSApOwogICAgICAgICAgICB9CgogICAgICAgIH0sCiAgICAgICAgX2Rpc2FibGVNb3ZlOmZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgICAgfSwKICAgICAgICBfb3ZlcmxheTogZnVuY3Rpb24oc3RhdHVzKSB7CiAgICAgICAgICAgIHN3aXRjaCggc3RhdHVzICkgewogICAgICAgICAgICAgICAgY2FzZSAnc2hvdyc6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb3ZlcmxheSgnaGlkZScpOwogICAgICAgICAgICAgICAgICAgICQoIkJPRFkiKS5hcHBlbmQoJzxkaXYgaWQ9ImlFQm94X292ZXJsYXkiPjwvZGl2PicpOwogICAgICAgICAgICAgICAgICAgICQoIiNpRUJveF9vdmVybGF5IikuY3NzKHsKICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246ICdmaXhlZCcsCiAgICAgICAgICAgICAgICAgICAgICAgIHpJbmRleDogOTk5OTcsCiAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogJzBweCcsCiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6ICcwcHgnLAogICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogJzEwMCUnLAogICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6ICQoZG9jdW1lbnQpLmhlaWdodCgpLAogICAgICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiB0aGlzLm92ZXJsYXlDb2xvciwKICAgICAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogdGhpcy5vdmVybGF5T3BhY2l0eQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIGlmKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5pc1NhZmFyaSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiNpRUJveF9vdmVybGF5Iikub24oJ3RvdWNobW92ZScsIHRoaXMuX2Rpc2FibGVNb3ZlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJChkb2N1bWVudCkub24oJ3Njcm9sbCcsdGhpcy5fb3ZlcmxheVJlc2l6ZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgJ2hpZGUnOgogICAgICAgICAgICAgICAgICAgIGlmKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5pc1NhZmFyaSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiNpRUJveF9vdmVybGF5Iikub2ZmKCd0b3VjaG1vdmUnKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJCgiI2lFQm94X292ZXJsYXkiKS5yZW1vdmUoKTsKICAgICAgICAgICAgICAgICAgICAkKGRvY3VtZW50KS5vZmYoJ3Njcm9sbCcsdGhpcy5fb3ZlcmxheVJlc2l6ZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgLyoqCiAgICAgICAgICogcmVzaXplIGRpYWxvZyBiYXNlZCBvbiBhdmFpbGFibGUgc2NyZWVuIGFyZWEKICAgICAgICAgKi8KICAgICAgICBfcmVzaXplOmZ1bmN0aW9uKCl7CiAgICAgICAgICAgIC8vIGF2YWlsYWJsZSBzY3JlZW4gYXJlYQogICAgICAgICAgICB2YXIgYVdpZHRoID0gJCh3aW5kb3cpLndpZHRoKCk7CiAgICAgICAgICAgIHZhciBhSGVpZ2h0ID0gJCh3aW5kb3cpLmhlaWdodCgpOwoKICAgICAgICAgICAgdmFyIHNpZ0NudiA9ICQoJyNpRUJveF9jYW52YXMnKVswXTsKICAgICAgICAgICAgdmFyIHNpZ1RleHRCb3ggPSAkKCcja2V5Ym9hcmRfU2lnbl9Cb3gnKVswXTsKICAgICAgICAgICAgdmFyIGJHZW9DbnYgPSAkKCcjaUVCb3hfZ2VvQ2FudmFzQm90dG9tJylbMF07CiAgICAgICAgICAgIHZhciByR2VvQ252ID0gJCgnI2lFQm94X2dlb0NhbnZhc1JpZ2h0JylbMF07CgogICAgICAgICAgICAvLyBjYWxjdWxhdGUgYW1vdW50IG9mIHdpZHRoIGhlaWdodCB3ZSBuZWVkIHRvIHJlZHVjZQoKICAgICAgICAgICAgdmFyIHRvdGFsQ252V2lkdGggPSBzaWdDbnYud2lkdGggKyByR2VvQ252LndpZHRoOwogICAgICAgICAgICB2YXIgdG90YWxDbnZIZWlnaHQgPSBzaWdDbnYuaGVpZ2h0ICsgYkdlb0Nudi5oZWlnaHQ7CgoKCgoKICAgICAgICAgICAgdmFyIGRpZmZXID0gdG90YWxDbnZXaWR0aCArIGRpYWxvZ09iai5jYW52YXNfc3BhY2luZy54IC0gYVdpZHRoOwogICAgICAgICAgICBpZihkaWZmVyA8IDApIHsKICAgICAgICAgICAgICAgIGRpZmZXID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgZGlmZkggPSB0b3RhbENudkhlaWdodCArIGRpYWxvZ09iai5jYW52YXNfc3BhY2luZy55IC0gYUhlaWdodDsKICAgICAgICAgICAgaWYoZGlmZkggPCAwKXsKICAgICAgICAgICAgICAgIGRpZmZIID0gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIG5ld1RvdGFsQ252SGVpZ2h0LCBuZXdUb3RhbENudldpZHRoOwogICAgICAgICAgICBpZiggZGlmZlcgPiAwIHx8IGRpZmZIID4gMCApeyAvLyBkb2VzIGFueSBzaWRlIG5lZWQgcmVzaXplCgogICAgICAgICAgICAgICAgaWYoZGlmZkggKiB0b3RhbENudldpZHRoID4gdG90YWxDbnZIZWlnaHQgKiBkaWZmVyl7IC8vIG5lZWQgdG8gcmVkdWNlIGhlaWdodAogICAgICAgICAgICAgICAgICAgbmV3VG90YWxDbnZIZWlnaHQgPSB0b3RhbENudkhlaWdodCAtIGRpZmZIOwogICAgICAgICAgICAgICAgICAgbmV3VG90YWxDbnZXaWR0aCA9IChuZXdUb3RhbENudkhlaWdodCAqIHRvdGFsQ252V2lkdGgpLyB0b3RhbENudkhlaWdodDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICBuZXdUb3RhbENudldpZHRoID0gdG90YWxDbnZXaWR0aCAtIGRpZmZXOwogICAgICAgICAgICAgICAgICAgbmV3VG90YWxDbnZIZWlnaHQgPSAobmV3VG90YWxDbnZXaWR0aCAqIHRvdGFsQ252SGVpZ2h0KS8gdG90YWxDbnZXaWR0aDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBkaXN0cmlidXRlIGV2ZW5seSB0aGUgbmV3IGRpbWVuc2lvbnMKCgogICAgICAgICAgICAgICAgdmFyIG5ld1NpZ0NudldpZHRoICAgPSAobmV3VG90YWxDbnZXaWR0aCpzaWdDbnYud2lkdGgpL3RvdGFsQ252V2lkdGg7CiAgICAgICAgICAgICAgICB2YXIgbmV3U2lnQ252SGVpZ2h0ID0gKG5ld1RvdGFsQ252SGVpZ2h0KnNpZ0Nudi5oZWlnaHQpL3RvdGFsQ252SGVpZ2h0OwoKICAgICAgICAgICAgICAgIHNpZ0Nudi5zdHlsZS53aWR0aCA9IG5ld1NpZ0NudldpZHRoICsgInB4IjsKICAgICAgICAgICAgICAgIHNpZ0Nudi5zdHlsZS5oZWlnaHQgPSBuZXdTaWdDbnZIZWlnaHQgKyAicHgiOwoKICAgICAgICAgICAgICAgIHNpZ1RleHRCb3guc3R5bGUud2lkdGggPSBuZXdTaWdDbnZXaWR0aCArICJweCI7CiAgICAgICAgICAgICAgICBzaWdUZXh0Qm94LnN0eWxlLmhlaWdodCA9IG5ld1NpZ0NudkhlaWdodCArICJweCI7CgoKICAgICAgICAgICAgICAgIGJHZW9DbnYuc3R5bGUud2lkdGggPSBuZXdTaWdDbnZXaWR0aCArInB4IjsKICAgICAgICAgICAgICAgIGJHZW9DbnYuc3R5bGUuaGVpZ2h0ID0gKG5ld1RvdGFsQ252SGVpZ2h0IC0gbmV3U2lnQ252SGVpZ2h0KSArInB4IjsKCiAgICAgICAgICAgICAgICByR2VvQ252LnN0eWxlLndpZHRoID0gKG5ld1RvdGFsQ252V2lkdGggLSBuZXdTaWdDbnZXaWR0aCkgKyJweCI7CiAgICAgICAgICAgICAgICByR2VvQ252LnN0eWxlLmhlaWdodCA9IG5ld1NpZ0NudkhlaWdodCArICJweCI7CgoKICAgICAgICAgICAgICAgICQoJyNpRUJveF9jYXB0aW9uJykud2lkdGgoTWF0aC5mbG9vcihuZXdTaWdDbnZXaWR0aCkpOwoKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNpZ0Nudi5zdHlsZS53aWR0aCA9ICBzaWdDbnYud2lkdGggKyAicHgiOwogICAgICAgICAgICAgICAgc2lnQ252LnN0eWxlLmhlaWdodCA9IHNpZ0Nudi5oZWlnaHQgKyAicHgiOwoKICAgICAgICAgICAgICAgIHNpZ1RleHRCb3guc3R5bGUud2lkdGggPSAgc2lnQ252LndpZHRoICsgInB4IjsKICAgICAgICAgICAgICAgIHNpZ1RleHRCb3guc3R5bGUuaGVpZ2h0ID0gc2lnQ252LmhlaWdodCArICJweCI7CgogICAgICAgICAgICAgICAgYkdlb0Nudi5zdHlsZS53aWR0aCA9ICBiR2VvQ252LndpZHRoICsgInB4IjsKICAgICAgICAgICAgICAgIGJHZW9DbnYuc3R5bGUuaGVpZ2h0ID0gYkdlb0Nudi5oZWlnaHQgKyAicHgiOwoKICAgICAgICAgICAgICAgIHJHZW9DbnYuc3R5bGUud2lkdGggPSAgckdlb0Nudi53aWR0aCArICJweCI7CiAgICAgICAgICAgICAgICByR2VvQ252LnN0eWxlLmhlaWdodCA9IHJHZW9DbnYuaGVpZ2h0ICsgInB4IjsKCiAgICAgICAgICAgICAgICAkKCcjaUVCb3hfY2FwdGlvbicpLndpZHRoKHNpZ0Nudi53aWR0aCk7CgogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBfcmVwb3NpdGlvbjogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB0b3AgPSAoKCQod2luZG93KS5oZWlnaHQoKSAqICgxIC8geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmZvcm1TY2FsZUZhY3RvcikgLyAyKSAtICgkKCIjaUVCb3hfY29udGFpbmVyIikub3V0ZXJIZWlnaHQoKSAvIDIpKSArIGRpYWxvZ09iai52ZXJ0aWNhbE9mZnNldDsKICAgICAgICAgICAgdmFyIGxlZnQgPSAoKCQod2luZG93KS53aWR0aCgpICogKDEgLyB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZm9ybVNjYWxlRmFjdG9yKSAvIDIpIC0gKCQoIiNpRUJveF9jb250YWluZXIiKS5vdXRlcldpZHRoKCkgLyAyKSkgKyBkaWFsb2dPYmouaG9yaXpvbnRhbE9mZnNldDsKICAgICAgICAgICAgaWYoIHRvcCA8IDAgKSB0b3AgPSAwOwogICAgICAgICAgICBpZiggbGVmdCA8IDAgKSBsZWZ0ID0gMDsKCiAgICAgICAgICAgICQoIiNpRUJveF9jb250YWluZXIiKS5jc3MoewogICAgICAgICAgICAgICAgdG9wOiB0b3AgKyAkKHdpbmRvdykuc2Nyb2xsVG9wKCkgKiAoMSAvIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IpICsgJ3B4JywKICAgICAgICAgICAgICAgIGxlZnQ6IGxlZnQgKyAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpICogKDEgLyB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZm9ybVNjYWxlRmFjdG9yKSArICdweCcKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICQoIiNpRUJveF9jb250YWluZXIiKS5mb2N1cygpOyAgIC8vIHNjcm9sbCB1cCB0byB0aGUgY2FudmFzCiAgICAgICAgICAgICQoIiNpRUJveF9vdmVybGF5IikuaGVpZ2h0KCAkKGRvY3VtZW50KS5oZWlnaHQoKSApOwogICAgICAgIH0sCiAgICAgICAgX21haW50YWluRGlhbG9nOmZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGRpYWxvZ09iai5fcmVzaXplKCk7CiAgICAgICAgICAgIGRpYWxvZ09iai5fcmVwb3NpdGlvbigpOwogICAgICAgIH0sCiAgICAgICAgX21haW50YWluUG9zaXRpb246IGZ1bmN0aW9uKHN0YXR1cykgewogICAgICAgICAgICBpZihkaWFsb2dPYmoucmVwb3NpdGlvbk9uUmVzaXplICkgewogICAgICAgICAgICAgICAgc3dpdGNoKHN0YXR1cykgewogICAgICAgICAgICAgICAgICAgIGNhc2UgdHJ1ZToKICAgICAgICAgICAgICAgICAgICAgICAgJCh3aW5kb3cpLm9uKCdvcmllbnRhdGlvbmNoYW5nZScsIGRpYWxvZ09iai5fbWFpbnRhaW5EaWFsb2cpOyAvLyBhbHNvIHJlcG9zaXRpb24gaWYgZGV2aWNlIGlzIHRpbHRlZAogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgZmFsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgICQod2luZG93KS5vZmYoJ29yaWVudGF0aW9uY2hhbmdlJywgZGlhbG9nT2JqLl9tYWludGFpbkRpYWxvZyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICB9OwogICAgcmV0dXJuIGRpYWxvZ09iajsKfSkod2luZG93Ll8pOwoKLyoqCiAqIGNsYXNzIGRlZmluaXRpb24gZm9yIEdlb0xvY2F0aW9uUXVlcnlSZXF1ZXN0CiAqIGVuY2Fwc3VsYXRlZCBzdWNjZXNzIGFuZCBlcnJvciBoYW5kbGVycyAKICovCmZ1bmN0aW9uIEdlb0xvY1F1ZXJ5KCl7fQpHZW9Mb2NRdWVyeS5wcm90b3R5cGU9ewogICAgaW5pdDpmdW5jdGlvbihzdWNjZXNzLGZhaWx1cmUpewogICAgICAgIHRoaXMuX3N1Y2Nlc3NIYW5kbGVyID0gc3VjY2VzczsKICAgICAgICB0aGlzLl9lcnJvckhhbmRsZXIgPSBmYWlsdXJlOwogICAgICAgIHRoaXMuX2FjdGl2ZT10cnVlOwogICAgICAgIHJldHVybiB0aGlzOwogICAgfSwKICAgIF9oYW5kbGVTdWNjZXNzOmZ1bmN0aW9uKGRhdGEpewogICAgICAgIHRoaXMuX3N1Y2Nlc3NIYW5kbGVyKGRhdGEpOyAKICAgIH0sCiAgICBfaGFuZGxlRXJyb3I6ZnVuY3Rpb24oZXJyKXsKICAgICAgICB0aGlzLl9lcnJvckhhbmRsZXIoZXJyKTsgICAKICAgIH0sCiAgICBxdWVyeTpmdW5jdGlvbigpewogICAgICAgICBfdGhhdD10aGlzOwogICAgICAgICBuYXZpZ2F0b3IuZ2VvbG9jYXRpb24uZ2V0Q3VycmVudFBvc2l0aW9uKGZ1bmN0aW9uKHBvcyl7CiAgICAgICAgICBpZihfdGhhdC5fYWN0aXZlKXsKICAgICAgICAgICAgIF90aGF0Ll9oYW5kbGVTdWNjZXNzKHBvcyk7CiAgICAgICAgICB9CiAgICAgICAgICBfdGhhdC5fYWN0aXZlPWZhbHNlOwogICAgICAgfSxmdW5jdGlvbihlcnIpewogICAgICAgICAgaWYoX3RoYXQuX2FjdGl2ZSl7CiAgICAgICAgICAgICBfdGhhdC5faGFuZGxlRXJyb3IoZXJyKTsKICAgICAgICAgIH0KICAgICAgICAgIF90aGF0Ll9hY3RpdmU9ZmFsc2U7CiAgICAgICB9LHt0aW1lb3V0OjEwMDAwfSk7CiAgICB9LAogICAgY2FuY2VsOmZ1bmN0aW9uKCl7CiAgICAgICAgX3RoYXQuX2FjdGl2ZT1mYWxzZTsKICAgIH0KCn07Ci8vIEdlb0xvY1F1ZXJ5IGRlZmluaXRpb24gZW5kcyBoZXJlCgovKioKKgoqICBCYXNlNjQgZW5jb2RlIC8gZGVjb2RlCiogIGh0dHA6Ly93d3cud2VidG9vbGtpdC5pbmZvLwoqCioqLwogCnZhciBCYXNlNjQgPSB7CiAKCS8vIHByaXZhdGUgcHJvcGVydHkKCV9rZXlTdHIgOiAiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz0iLAogCgkvLyBwdWJsaWMgbWV0aG9kIGZvciBlbmNvZGluZwoJZW5jb2RlIDogZnVuY3Rpb24gKGlucHV0KSB7CgkJdmFyIG91dHB1dCA9ICIiOwoJCXZhciBjaHIxLCBjaHIyLCBjaHIzLCBlbmMxLCBlbmMyLCBlbmMzLCBlbmM0OwoJCXZhciBpID0gMDsKIAoJCXdoaWxlIChpIDwgaW5wdXQubGVuZ3RoKSB7CiAKCQkJY2hyMSA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTsKCQkJY2hyMiA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTsKCQkJY2hyMyA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTsKIAoJCQllbmMxID0gY2hyMSA+PiAyOwoJCQllbmMyID0gKChjaHIxICYgMykgPDwgNCkgfCAoY2hyMiA+PiA0KTsKCQkJZW5jMyA9ICgoY2hyMiAmIDE1KSA8PCAyKSB8IChjaHIzID4+IDYpOwoJCQllbmM0ID0gY2hyMyAmIDYzOwogCgkJCWlmIChpc05hTihjaHIyKSkgewoJCQkJZW5jMyA9IGVuYzQgPSA2NDsKCQkJfSBlbHNlIGlmIChpc05hTihjaHIzKSkgewoJCQkJZW5jNCA9IDY0OwoJCQl9CiAKCQkJb3V0cHV0ID0gb3V0cHV0ICsKCQkJdGhpcy5fa2V5U3RyLmNoYXJBdChlbmMxKSArIHRoaXMuX2tleVN0ci5jaGFyQXQoZW5jMikgKwoJCQl0aGlzLl9rZXlTdHIuY2hhckF0KGVuYzMpICsgdGhpcy5fa2V5U3RyLmNoYXJBdChlbmM0KTsKIAoJCX0KIAoJCXJldHVybiBvdXRwdXQ7Cgl9LAogCgkvLyBwdWJsaWMgbWV0aG9kIGZvciBkZWNvZGluZwoJZGVjb2RlIDogZnVuY3Rpb24gKGlucHV0KSB7CgkJdmFyIG91dHB1dCA9ICIiOwoJCXZhciBjaHIxLCBjaHIyLCBjaHIzOwoJCXZhciBlbmMxLCBlbmMyLCBlbmMzLCBlbmM0OwoJCXZhciBpID0gMDsKIAoJCWlucHV0ID0gaW5wdXQucmVwbGFjZSgvW15BLVphLXowLTlcK1wvXD1dL2csICIiKTsKIAoJCXdoaWxlIChpIDwgaW5wdXQubGVuZ3RoKSB7CiAKCQkJZW5jMSA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTsKCQkJZW5jMiA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTsKCQkJZW5jMyA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTsKCQkJZW5jNCA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTsKIAoJCQljaHIxID0gKGVuYzEgPDwgMikgfCAoZW5jMiA+PiA0KTsKCQkJY2hyMiA9ICgoZW5jMiAmIDE1KSA8PCA0KSB8IChlbmMzID4+IDIpOwoJCQljaHIzID0gKChlbmMzICYgMykgPDwgNikgfCBlbmM0OwogCgkJCW91dHB1dCA9IG91dHB1dCArIFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMSk7CiAKCQkJaWYgKGVuYzMgIT0gNjQpIHsKCQkJCW91dHB1dCA9IG91dHB1dCArIFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMik7CgkJCX0KCQkJaWYgKGVuYzQgIT0gNjQpIHsKCQkJCW91dHB1dCA9IG91dHB1dCArIFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMyk7CgkJCX0KIAoJCX0KIAoJCXJldHVybiBvdXRwdXQ7CiAKCX0KIAoJCiAKfTsKCi8qKgogKiBVdGlsaXR5IFNpbmdsZXRvbiBmb3IgaGFuZGxpbmcgUE5HIERhdGEKICovCnZhciBQTkdVdGlsPShmdW5jdGlvbigpewogICAgdmFyIHNsZj17CiAgIF9MQ19TY3JpYmJsZV9NZXRhRGF0YUtleToiTENfU0NJQkJMRV9NRVRBREFUQSIsCiAgICAgICAgICAgX2lzUG5nOmZ1bmN0aW9uKGI2NGRhdGEpewogICAgICAgICAgICAgICByZXR1cm4gIGI2NGRhdGEgJiYgYjY0ZGF0YS5yZXBsYWNlKC9ccysvZywgIiIpLmluZGV4T2YoImlWQk9SdzBLR2dvIikgPT0gMDsgICAvLyBMQy01NzExIDogdHJpbSBhbnkgbGVhZGluZyBXaGl0ZVNwYWNlCiAgICAgICAgICAgICAgIC8vIFRPRE8gOiAgYmFzZTY0IGVuY29kaW5nIG1heSBoYXZlIHdoaXRlIHNwYWNlcyBldmVuIGJldHdlZW4gdGhlIG1hZ2ljIG51bWJlcnMgISEgVGhpbmsgb2YgYSBiZXR0ZXIgd2F5IHRvIHN0b3Agc3RyaXBwaW5nIHdoaXRlIHNwYWNlcyByZXBlYXRlZGx5IGluIFBOR1V0aWwsIGFuZCBjYWNoZSB0aGUgcmVzdWx0CiAgICAgICAgICAgfSwKICAgICAgICAgICBfdXBkYXRlX2NyYzpmdW5jdGlvbihjcmMsZGF0YSl7CiAgICAgICAgICAgICAgIHZhciBjID0gY3JjOwogICAgICAgICAgICAgICB2YXIgbjsKICAgICAgICAgICAgICAgZm9yKG49MDtuPGRhdGEubGVuZ3RoO24rKyl7CiAgICAgICAgICAgICAgICAgIGMgPSB0aGlzLl9YT1Ioc2xmLl9jcmNfdGFibGVbKHRoaXMuX1hPUihjLGRhdGEuY2hhckNvZGVBdChuKSkmMHhmZik+Pj4wXSwoYz4+PjgpKTsKICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICByZXR1cm4gYzsKICAgICAgICAgICB9LAoJCSAgIF9YT1I6ZnVuY3Rpb24oYSxiKXsKCQkgICAgICAgcmV0dXJuIChhXmIpPj4+MDsKCQkgICB9LAogICAgICAgICAgIF9VMzJJbnQyU3RyOmZ1bmN0aW9uKG4pewogICAgICAgICAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoKG4+Pj4yNCkmMHhGRikrU3RyaW5nLmZyb21DaGFyQ29kZSgobj4+PjE2KSYweEZGKStTdHJpbmcuZnJvbUNoYXJDb2RlKChuPj4+OCkmMHhGRikrU3RyaW5nLmZyb21DaGFyQ29kZShuPj4+MCYweEZGKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICBfaW5pdF9jcmNfdGFibGU6ZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgdmFyIGM9MDsKICAgICAgICAgICAgICAgdmFyIG4sazsKICAgICAgICAgICAgICAgc2xmLl9jcmNfdGFibGU9W107CiAgICAgICAgICAgICAgIGZvcihuPTA7bjwyNTY7bisrKXsKICAgICAgICAgICAgICAgICAgIGMgPSBuOwogICAgICAgICAgICAgICAgICAgZm9yKGs9MDtrPDg7aysrKXsKICAgICAgICAgICAgICAgICAgICAgIGlmKCgoYyYxKT4+PjApPjApewogICAgICAgICAgICAgICAgICAgICAgICAgIGMgPSBzbGYuX1hPUigweGVkYjg4MzIwICwgKGM+Pj4xKSk7CiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgIGMgPSBjPj4+MTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgIHNsZi5fY3JjX3RhYmxlW25dPWM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgfSwKICAgICAgICAgICBfQ1JDOmZ1bmN0aW9uKGRhdGEpewogICAgICAgICAgICAgICAgaWYoIXRoaXMuX2NyY190YWJsZSkgdGhpcy5faW5pdF9jcmNfdGFibGUoKTsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9YT1IodGhpcy5fdXBkYXRlX2NyYygweGZmZmZmZmZmLGRhdGEpICwgMHhmZmZmZmZmZik7CiAgICAgICAgICB9LAogICAgICAgICAgX3ByZXBhcmVUZXh0Q2h1bms6ZnVuY3Rpb24oY29udGVudCxwYWQpewogICAgICAgICAgICAgIC8vIHBhZCB0aGUgZGF0YSBhcHByb3ByaWF0ZWx5ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICB2YXIgbGVuID0gY29udGVudC5sZW5ndGg7CiAgICAgICAgICAgICAgIHZhciBsZW5TdHIgPSBzbGYuX1UzMkludDJTdHIobGVuKTsKICAgICAgICAgICAgICAgdmFyIGNodW5rVHlwZT0idEVYdCI7CiAgICAgICAgICAgICAgIHZhciBjaGVja1N1bVN0ciA9IHNsZi5fVTMySW50MlN0cihzbGYuX0NSQyhjaHVua1R5cGUrY29udGVudCkpOwogICAgICAgICAgICAgICByZXR1cm4gbGVuU3RyK2NodW5rVHlwZStjb250ZW50K2NoZWNrU3VtU3RyOwogICAgICAgICAgIH0sCiAgICAgICAgX3N0YXJ0OmZ1bmN0aW9uKHN0cil7CiAgICAgICAgICAgc2xmLl9zdGFydFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTsKICAgICAgICAgICBzbGYuX3N0YXJ0RnVuPXN0cjsKICAgICAgICB9LAogICAgICAgIF9lbmQ6ZnVuY3Rpb24oKXsKICAgICAgICAgICB2YXIgc3RyID0gIlRpbWUgIitzbGYuX3N0YXJ0RnVuKyI6ICIrKG5ldyBEYXRlKCkuZ2V0VGltZSgpLXNsZi5fc3RhcnRUaW1lKTsKICAgICAgICAgIC8vICAkKCdCT0RZJykuYXBwZW5kKCI8cD4iK3N0cisiPC9wPjxici8+Iik7CiAgICAgICAgfSwKICAgICAgICBfcmVhZFUzMkludDpmdW5jdGlvbihjdHgpewogICAgICAgICAgICB2YXIgdmFsPTA7CiAgICAgICAgICAgIHZhciBkPWN0eC5kOwogICAgICAgICAgICB2YWw9KChkLmNoYXJDb2RlQXQoY3R4LnArKyk8PDI0KXwoZC5jaGFyQ29kZUF0KGN0eC5wKyspPDwxNil8KGQuY2hhckNvZGVBdChjdHgucCsrKTw8OCl8KGQuY2hhckNvZGVBdChjdHgucCsrKSkpPj4+MDsKICAgICAgICAgICAgIHJldHVybiB2YWw7CiAgICAgICAgfSwKICAgICAgIF9yZWFkQ2h1bmtUeXBlOmZ1bmN0aW9uKGN0eCl7CiAgICAgICAgICB2YXIgZCA9IGN0eC5kOwogICAgICAgICAgdmFyIHN0ciA9IGRbY3R4LnArK10rZFtjdHgucCsrXStkW2N0eC5wKytdK2RbY3R4LnArK107CiAgICAgICAgICByZXR1cm4gc3RyOwogICAgICAgfSwKICAgICAgICBfbWFrZVJlYWRPbmx5OmZ1bmN0aW9uKGI2NGRhdGEpewogICAgICBzbGYuX3N0YXJ0KCJfbWFrZVJlYWRPbmx5Iik7CiAgICAgIC8vIGFzc3VtZSBhIHZhbGlkIHBuZyBpbWFnZSBlbmNvZGVkIGluIGJhc2U2NDsKICAgICAgdmFyIGJpbmRhdGEgPSBzbGYuX2F0b2IoYjY0ZGF0YS5yZXBsYWNlKC9ccysvZywgJycpKTsgLy8gcmVtb3ZlIHdoaXRlIHNwYWNlcyB0aGF0IG1pZ2h0IGhhdmUgYmVlbiBpbnNlcnRlZAogICAgICB2YXIgcG5nY3R4PXtwOjAsZDpiaW5kYXRhfTsKICAgICAgcG5nY3R4LnArPTg7Ly8gc2tpcCBwbmdoZWFkZXIKICAgICAgLy8gcmVhZCBJSERSCiAgICAgIHZhciBzaXplID0gc2xmLl9yZWFkVTMySW50KHBuZ2N0eCk7CiAgICAgIHNsZi5fcmVhZENodW5rVHlwZShwbmdjdHgpOyAvL0lIRFIKICAgICAgcG5nY3R4LnArPXNpemU7IC8vRGF0YQogICAgICBzbGYuX3JlYWRVMzJJbnQocG5nY3R4KTsvL0NSQwogICAgICB2YXIgbWV0YWRhdGFDaHVuayA9IHNsZi5fcHJlcGFyZVRleHRDaHVuayhzbGYuX0xDX1NjcmliYmxlX01ldGFEYXRhS2V5K1N0cmluZy5mcm9tQ2hhckNvZGUoMCkrInRydWUiKTsKICAgICAgdmFyIG5ld2RhdGEgPSBwbmdjdHguZC5zdWJzdHJpbmcoMCxwbmdjdHgucCkrbWV0YWRhdGFDaHVuaytwbmdjdHguZC5zdWJzdHJpbmcocG5nY3R4LnApOwogICAgICB2YXIgcmV0PSBzbGYuX2J0b2EobmV3ZGF0YSk7CiAgICAgIHNsZi5fZW5kKCk7CiAgICAgIHJldHVybiByZXQ7CiAgIH0sCiAgIF9hdG9iOmZ1bmN0aW9uKGlucCl7CiAgICAgIGlmKHdpbmRvdy5hdG9iKXsgcmV0dXJuIGF0b2IoaW5wKTsgfQoJICByZXR1cm4gQmFzZTY0LmRlY29kZShpbnApOwogICB9LAogICBfYnRvYTpmdW5jdGlvbihpbnApewogICAgICBpZih3aW5kb3cuYnRvYSl7IHJldHVybiBidG9hKGlucCk7IH0KCSAgcmV0dXJuIEJhc2U2NC5lbmNvZGUoaW5wKTsKICAgfSwKICAgX2lzUmVhZE9ubHk6ZnVuY3Rpb24oYjY0ZGF0YSl7CiAgICBzbGYuX3N0YXJ0KCJfaXNSZWFkT25seSIpOwogICAgICAgaWYoc2xmLl9pc1BuZyhiNjRkYXRhKSl7CiAgICAgICAgICAgdmFyIHRlc3RTdHIgPSBzbGYuX0xDX1NjcmliYmxlX01ldGFEYXRhS2V5K1N0cmluZy5mcm9tQ2hhckNvZGUoMCkrInRydWUiOwogICAgICAgICAgIHZhciBiaW5kYXRhID0gc2xmLl9hdG9iKGI2NGRhdGEucmVwbGFjZSgvXHMrL2csICcnKSk7IC8vIHN0cmlwIHdoaXRlIHNwYWNlcwogICAgICAgICAgIHZhciBwbmdjdHg9e3A6MCxkOmJpbmRhdGF9OwogICAgICAgICAgIHBuZ2N0eC5wKz04Oy8vIHNraXAgaGVhZGVyCiAgICAgICAgICAgd2hpbGUocG5nY3R4LnA8cG5nY3R4LmQubGVuZ3RoKXsKICAgICAgICAgICAgICAgdmFyIHNpemUgPSBzbGYuX3JlYWRVMzJJbnQocG5nY3R4KTsKICAgICAgICAgICAgICAgdmFyIHR5cGUgPSBzbGYuX3JlYWRDaHVua1R5cGUocG5nY3R4KTsKICAgICAgICAgICAgICAgaWYodHlwZT09InRFWHQiKXsKICAgICAgICAgICAgICAgICAgIGlmKHBuZ2N0eC5kLmluZGV4T2YodGVzdFN0cixwbmdjdHgucCk9PXBuZ2N0eC5wKXsKICAgICAgICAgICAgICAgICAgICAgICBzbGYuX2VuZCgpOwogICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcG5nY3R4LnArPXNpemU7CiAgICAgICAgICAgICAgc2xmLl9yZWFkVTMySW50KHBuZ2N0eCk7Ly8gCiAgICAgICAgICB9Ly8gd2hpbGUgZW5kCiAgICAgICB9CiAgICAgICBzbGYuX2VuZCgpOwogICAgICAgcmV0dXJuIGZhbHNlOwogICB9CiAgICB9OwogICAgcmV0dXJuIHNsZjsKfSkoKTsKCi8qKgogKiBKUXVlcnkgd2lkZ2V0IGRlZmluaXRpb24gc3RhcnRzIGhlcmUKICovCiQud2lkZ2V0KCAieGZhV2lkZ2V0LlNjcmliYmxlSW1hZ2VGaWVsZCIsICQueGZhV2lkZ2V0LmltYWdlRmllbGQsIHsKCiAgICBfd2lkZ2V0TmFtZToiU2NyaWJibGVJbWFnZUZpZWxkIiwKICAgIF9nZW9Mb2NRdWVyeTpudWxsLAogICBfZW1wdHlJbWFnZVZhbDpudWxsLC8vIHNob3VsZCBiZSBudWxsLCBidXQgZm9yIG5vdwogICBfZXh0cmFJbmZvOm51bGwsCiAgIF9kZWZhdWx0U3RhdHVzOiImbmJzcDsiLAogICBfZW5mb3JjZUdlb0xvYzohIW5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQYWQvaSksCiAgIF9zaWdDYW52YXNXaWR0aDo2OTYsCiAgIF9zaWdDYW52YXNIZWlnaHQ6MzkwLAogICBfZ2VvQ2FudklkOm51bGwsCiAgICBfZ2VvTG9jQXRCb3R0b206ZmFsc2UsCiAgIF9nZW9DYW52YXNIZWlnaHQ6MTAwLAogICBfZ2VvQ2FudmFzV2lkdGg6Njk2LAogICAKICAgIF9pc19yZWFkb25seTpmYWxzZSwKCQogICAgb3B0aW9uczogewogICAgICAgIHRhYkluZGV4OiAwLAogICAgICAgICJyb2xlIjogImltZyIKICAgIH0sCgogICAgZ2V0T3B0aW9uc01hcDogZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIHBhcmVudE9wdGlvbnNNYXAgPSAkLnhmYVdpZGdldC5kZWZhdWx0V2lkZ2V0LnByb3RvdHlwZS5nZXRPcHRpb25zTWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKTsKICAgICAgICByZXR1cm4gJC5leHRlbmQoe30scGFyZW50T3B0aW9uc01hcCx7CiAgICAgICAgICAgICJkaXNwbGF5VmFsdWUiOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5jb21taXRQcm9wZXJ0eSkgewogICAgICAgICAgICAgICAgICAgIGlmKCF2YWwpewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9kaXNwbGF5VmFsdWUodGhpcy5fZXh0cmFjdERhdGEodGhpcy5fY3JlYXRlRW1wdHlJbWFnZURhdGEoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hZGRDbGFzcygiZW1wdHlTY3JpYmJsZSIpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9pc19yZWFkb25seT1mYWxzZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5yZW1vdmVDbGFzcygiZW1wdHlTY3JpYmJsZSIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZihQTkdVdGlsLl9pc1BuZyh2YWwpKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aWRnZXRWYWx1ZSA9ICJkYXRhOmltYWdlL3BuZztiYXNlNjQsIit0aGlzLm9wdGlvbnMudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aWRnZXRWYWx1ZSA9ICJkYXRhOjtiYXNlNjQsIiArIHRoaXMub3B0aW9ucy52YWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZXRWYWx1ZSh3aWRnZXRWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSkKICAgIH0sCgogICAgZ2V0RXZlbnRNYXA6IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciBwYXJlbnRPcHRpb25zTWFwID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUuZ2V0RXZlbnRNYXAuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgIHJldHVybiAkLmV4dGVuZCh7fSxwYXJlbnRPcHRpb25zTWFwLHsKICAgICAgICAgICAgInNjcmliYmxlZm9jdXMiOnhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRU5URVJfRVZFTlQsCiAgICAgICAgICAgICJjbGljayI6bnVsbCwKICAgICAgICAgICAgInNjcmliYmxlY2xpY2siOnhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0xJQ0tfRVZFTlQsCiAgICAgICAgICAgICJjaGFuZ2UiOm51bGwsCiAgICAgICAgICAgICJzY3JpYmJsZWNoYW5nZSI6eGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQsCiAgICAgICAgICAgICJibHVyIjpudWxsLAogICAgICAgICAgICAic2NyaWJibGVjbG9zZSI6eGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FWElUX0VWRU5UCiAgICAgICAgfSkKICAgIH0sCgoJLyoqCgkgKiBUaGlzIGZ1bmN0aW9uIGFjaGlldmVzIGZvbGxvd2luZwoJICogMS4gQ2FsY3VsYXRlIGRpbWVuc2lvbnMgb2YgY2FudmFzZXMgdG8gYmUgdXNlZAoJICogMi4gRmluZG91dCBpZiByaWdodCBvciBib3R0b20gY2FudmFzIGlzIHRvIGJlIHVzZWQgZm9yIGdlbyBsb2NhdGlvbgoJICovCgoJIGFzcGVjdFJhdGlvVG9CZVVzZWQgOmZ1bmN0aW9uKCl7CiAgICAgICAgdmFyIGFzcGVjdFJhdGlvIDsKICAgICAgICBpZih0aGlzLm9wdGlvbnMuYXNwZWN0UmF0aW8gJiYgcGFyc2VGbG9hdCh0aGlzLm9wdGlvbnMuYXNwZWN0UmF0aW8pID4gMCl7CiAgICAgICAgICAgYXNwZWN0UmF0aW8gPSAxL3BhcnNlRmxvYXQodGhpcy5vcHRpb25zLmFzcGVjdFJhdGlvKTsgIC8vLS1pbiBNRiByYXRpbyBpcyBjb21wdXRlZCBhcyBoZWlnaHQvd2lkdGggaW5zdGVhZCBvZiB3aWR0aC9oZWlnaHQKICAgICAgICB9IGVsc2UgewogICAgICAgICAgIHZhciBpbWdFbCA9IHRoaXMuZWxlbWVudC5jaGlsZHJlbigiaW1nIiksCiAgICAgICAgICAgICAgIHdpZHRoID0gaW1nRWwuYXR0cignd2lkdGgnKSwKICAgICAgICAgICAgICAgaGVpZ2h0ID0gaW1nRWwuYXR0cignaGVpZ2h0JyksCiAgICAgICAgICAgICAgIGZpZWxkV2lkdGgsCiAgICAgICAgICAgICAgIGZpZWxkSGVpZ2h0OwoKICAgICAgICAgICBpZih3aWR0aCl7CiAgICAgICAgICAgICAgZmllbGRXaWR0aCA9IHBhcnNlSW50KHdpZHRoLDEwKTsKICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGZpZWxkV2lkdGggPSBpbWdFbC53aWR0aCgpOwogICAgICAgICAgIH0KICAgICAgICAgICBpZihoZWlnaHQpewogICAgICAgICAgICAgIGZpZWxkSGVpZ2h0ID0gcGFyc2VJbnQoaGVpZ2h0LDEwKTsKICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGZpZWxkSGVpZ2h0ID0gaW1nRWwuaGVpZ2h0KCk7CiAgICAgICAgICAgfQogICAgICAgICAgIGFzcGVjdFJhdGlvID0gZmllbGRIZWlnaHQvZmllbGRXaWR0aDsKICAgICAgICB9CgkgICAgcmV0dXJuIGFzcGVjdFJhdGlvOwoJIH0sCgogICAgX3NldFVwQ2FudmFzOmZ1bmN0aW9uKCl7CiAgICAgICAgdmFyIGFzcGVjdFJhdGlvIDsKCQlhc3BlY3RSYXRpbyA9IHRoaXMuYXNwZWN0UmF0aW9Ub0JlVXNlZCgpOwogICAgICAgCiAgICAgICAgLy8gbWF4IHdpZHRoLCBoZWlnaHQgb2YgZ2VuZXJhdGVkIGltYWdlCiAgICAgICAgdmFyIG1heFdpZHRoID0gNjQwOwogICAgICAgIHZhciBtYXhIZWlnaHQgPSA0ODA7CiAgICAgICAgCiAgICAgICAgLy8gd2lkdGggb2YgZmllbGQgc2NhbGVkIHRvIGZpdCBtYXggaW1hZ2Ugc2l6ZQogICAgICAgIHZhciBzY2FsZWRXaWR0aDsKICAgICAgICB2YXIgc2NhbGVkSGVpZ2h0OwogICAgICAgIAogICAgICAgIAoJCS8vIGFwcHJveCBwaXhlbHMgcmVxdWlyZWQgZm9yIHJlbmRlcmluZyBnZW8gbG9jIGluZm8gaW4gMTJwdCBBcmlhbCBmb250IAoJCXZhciBhcHByb3hHZW9Mb2NXaWR0aD0yNTA7CgkJdmFyIGFwcHJveEdlb0xvY0hlaWdodD04NDsKICAgICAgICAKICAgICAgICBzY2FsZWRXaWR0aCA9IG1heFdpZHRoOwogICAgICAgIHNjYWxlZEhlaWdodCA9IG1heFdpZHRoKmFzcGVjdFJhdGlvOwogICAgICAgIGlmKHNjYWxlZEhlaWdodD5tYXhIZWlnaHQpewogICAgICAgICAgICBzY2FsZWRIZWlnaHQgPSBtYXhIZWlnaHQ7CiAgICAgICAgICAgIHNjYWxlZFdpZHRoID0gbWF4SGVpZ2h0L2FzcGVjdFJhdGlvOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBzZXQgY2FudmFzIGRpbWVuc2lvbnMKICAgICAgICBpZihhc3BlY3RSYXRpbz49MSl7CgkJCXRoaXMuX2dlb0NhbnZJZD0naUVCb3hfZ2VvQ2FudmFzQm90dG9tJzsKICAgICAgICAgICAgdGhpcy5fZ2VvTG9jQXRCb3R0b209dHJ1ZTsKICAgICAgICAgIAoJCQkKICAgICAgICAgICAgIHRoaXMuX2dlb0NhbnZhc1dpZHRoID0gc2NhbGVkV2lkdGg7CgkJCSAvLyBsaW1pdCBoZWlnaHQgdG8gMzAlIG9mIGZ1bGwgaGVpZ2h0OwoJCQkgdGhpcy5fZ2VvQ2FudmFzSGVpZ2h0PU1hdGgubWluKGFwcHJveEdlb0xvY0hlaWdodCxzY2FsZWRIZWlnaHQvMyk7CiAgICAgICAgICAgICB0aGlzLl9zaWdDYW52YXNXaWR0aCA9IHNjYWxlZFdpZHRoOwogICAgICAgICAgICAgdGhpcy5fc2lnQ2FudmFzSGVpZ2h0PSBzY2FsZWRIZWlnaHQtKHRoaXMuX2VuZm9yY2VHZW9Mb2M/dGhpcy5fZ2VvQ2FudmFzSGVpZ2h0OjApOwogICAgICAgIH0gZWxzZSB7CgkJCXRoaXMuX2dlb0NhbnZJZD0naUVCb3hfZ2VvQ2FudmFzUmlnaHQnOwogICAgICAgICAgICB0aGlzLl9nZW9Mb2NBdEJvdHRvbT1mYWxzZTsKICAgICAgICAgICAKCQkJCiAgICAgICAgICAgIHRoaXMuX2dlb0NhbnZhc0hlaWdodCA9IHNjYWxlZEhlaWdodDsKCQkJLy8gbGltaXQgd2lkdGggdG8gMzAlIG9mIGZ1bGwgd2lkdGg7CgkJCXRoaXMuX2dlb0NhbnZhc1dpZHRoPU1hdGgubWluKGFwcHJveEdlb0xvY1dpZHRoLHNjYWxlZFdpZHRoLzMpOwogICAgICAgICAgICB0aGlzLl9zaWdDYW52YXNIZWlnaHQ9IHNjYWxlZEhlaWdodDsKICAgICAgICAgICAgdGhpcy5fc2lnQ2FudmFzV2lkdGg9IHNjYWxlZFdpZHRoLSh0aGlzLl9lbmZvcmNlR2VvTG9jP3RoaXMuX2dlb0NhbnZhc1dpZHRoOjApOwogICAgICAgIH0KICAgICAgIAogICAgfSwKCiAgIHJlbmRlciA6IGZ1bmN0aW9uKCkgewogICAgICAgdmFyIGdlb0xvY01hbmRhdG9yeU9uSXBhZCA9IHRoaXMub3B0aW9ucy5nZW9Mb2NNYW5kYXRvcnlPbklwYWQ7CiAgICAgICBpZih0eXBlb2YoZ2VvTG9jTWFuZGF0b3J5T25JcGFkKSE9InVuZGVmaW5lZCIpewogICAgICAgICAgIHRoaXMuX2VuZm9yY2VHZW9Mb2M9IHRoaXMuX2VuZm9yY2VHZW9Mb2MgJiYgKC9eKHRydWV8MSkkL2kpLnRlc3QoJC50cmltKGdlb0xvY01hbmRhdG9yeU9uSXBhZCkpOwogICAgICAgfQogICAgICAgdGhpcy5fd2d0SWQ9IndpZCIrfn4oTWF0aC5yYW5kb20oKSoyMDAwKSsiXyIrbmV3IERhdGUoKS5nZXRUaW1lKCk7CgogICAgICAgdmFyICRjb250cm9sID0gJC54ZmFXaWRnZXQuZGVmYXVsdFdpZGdldC5wcm90b3R5cGUucmVuZGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykKCiAgICAgICBpZih0aGlzLm9wdGlvbnMudmFsdWUgfHwgdGhpcy5vcHRpb25zLnZhbHVlICE9IHRoaXMuX2VtcHR5SW1hZ2VWYWwpewogICAgICAgICAgdGhpcy5faXNfcmVhZG9ubHk9ISFQTkdVdGlsLl9pc1JlYWRPbmx5KHRoaXMub3B0aW9ucy52YWx1ZSk7CiAgICAgICB9CiAgIAogICAgICAgaWYodGhpcy5faXNfcmVhZG9ubHkpewogICAgICAgICAgJGNvbnRyb2wuYWZ0ZXIoIjxkaXYgaWQ9JyIrdGhpcy5fd2d0SWQrIicgY2xhc3M9J3NjX3BvcFVwTWVudSc+PC9kaXY+Iik7CiAgICAgICB9IGVsc2UgewogICAgICAgICAgJGNvbnRyb2wuYWZ0ZXIoIjxkaXYgaWQ9JyIrdGhpcy5fd2d0SWQrIicgc3R5bGU9J2Rpc3BsYXk6bm9uZTsnIGNsYXNzPSdzY19wb3BVcE1lbnUnPjwvZGl2PiIpOwogICAgICAgfQoJICAgCgkgICB0aGlzLl9zZXRVcENhbnZhcygpOwogICAgICAgcmV0dXJuICRjb250cm9sOwogICAgfSwKCiAgIGNsaWNrOiBmdW5jdGlvbigpIHsKICAgICAgICB0aGlzLmZvY3VzKCk7CiAgICAgICAgdmFyIHRtcEVsID0gdGhpcy5lbGVtZW50Lmxlbmd0aD90aGlzLmVsZW1lbnRbMF06dGhpcy5lbGVtZW50OwogICAgICAgIGlmKHRoaXMub3B0aW9ucy5hY2Nlc3MgIT0gIm9wZW4iKQogICAgICAgICAgcmV0dXJuOwogICAgICAgaWYgKFRvdWNoVXRpbC5QT0lOVEVSX0VOQUJMRUQgfHwgVG91Y2hVdGlsLlRPVUNIX0VOQUJMRUQpIHsKICAgICAgICAgICAvLyBzaW11bGF0ZSBhIGNsaWNrIGV2ZW50CiAgICAgICAgICAgdG1wRWwuZGlzcGF0Y2hFdmVudChUb3VjaFV0aWwuZ2V0UG9pbnRlckV2ZW50KFRvdWNoVXRpbC5QT0lOVEVSX0RPV04pKTsKICAgICAgICAgICB0bXBFbC5kaXNwYXRjaEV2ZW50KFRvdWNoVXRpbC5nZXRQb2ludGVyRXZlbnQoVG91Y2hVdGlsLlBPSU5URVJfVVApKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wudHJpZ2dlckhhbmRsZXIoImNsaWNrIik7CiAgICAgICAgfQogICB9LAoKICAgIF9hdHRhY2hFdmVudEhhbmRsZXJzOmZ1bmN0aW9uKCRjb250cm9sKXsKCSAgICAgaWYoVG91Y2hVdGlsLlBPSU5URVJfRU5BQkxFRCB8fCBUb3VjaFV0aWwuVE9VQ0hfRU5BQkxFRCl7CiAgICAgICAgICAgIHRoaXMuX2F0dGFjaFRvdWNoRXZlbnRIYW5kbGVycygkY29udHJvbCk7CiAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRoaXMuX2F0dGFjaE1vdXNlRXZlbnRIYW5kbGVycygkY29udHJvbCk7CiAgICAgICAgIH0KICAgICAgICAgJGNvbnRyb2wua2V5ZG93bigkLnByb3h5KHRoaXMuX2hhbmRsZUtleURvd24sdGhpcykpOwogICAgfSwKCV9hdHRhY2hFdmVudEhhbmRsZXJGb3JDcm9zc0ljb246ZnVuY3Rpb24oJGNvbnRyb2wpewoJICAgIHZhciBfdGhhdCA9IHRoaXM7CgkgICAgJGNvbnRyb2wubW91c2VlbnRlcihmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgICBpZihfdGhhdC5vcHRpb25zLmFjY2VzcyAhPSAib3BlbiIpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgICAgICAgICBpZihfdGhhdC5faXNfcmVhZG9ubHkpewogICAgICAgICAgICAgICAgJCgnIycrX3RoYXQuX3dndElkKS5jc3Moe2Rpc3BsYXk6J2Jsb2NrJ30pOwogICAgICAgICAgICAgICAgdmFyIGJvZHlNb3ZlSGFuZGxlcjsKICAgICAgICAgICAgICAgICQoJ2JvZHknKS5vbignbW91c2Vtb3ZlJyxib2R5TW92ZUhhbmRsZXI9ZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICAgICAgICAgIGlmKGV2ZW50LnRhcmdldCE9JCgnIycrX3RoYXQuX3dndElkKVswXSYmZXZlbnQudGFyZ2V0IT1fdGhhdC4kdXNlckNvbnRyb2xbMF0pewogICAgICAgICAgICAgICAgICAgICAgICAkKCcjJytfdGhhdC5fd2d0SWQpLmNzcyh7ZGlzcGxheTonbm9uZSd9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICQoJ2JvZHknKS5vZmYoJ21vdXNlbW92ZScsYm9keU1vdmVIYW5kbGVyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9CiAgICAgICB9KTsKCiAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ICQoIiMiK190aGF0Ll93Z3RJZCkuY2xpY2soJC5wcm94eShfdGhhdC5fb25Dcm9zc0NsaWNrLF90aGF0KSk7fSw1MCk7ICAKCX0sCiAgICBfYXR0YWNoVG91Y2hFdmVudEhhbmRsZXJzOmZ1bmN0aW9uKCRjb250cm9sKXsKICAgICAgICB2YXIgX3RpbWVyLF90aGF0PXRoaXM7CiAgICAgICAgdmFyIHRtcEVsID0gdGhpcy5lbGVtZW50Lmxlbmd0aD90aGlzLmVsZW1lbnRbMF06dGhpcy5lbGVtZW50OwogICAgICAgdG1wRWwuYWRkRXZlbnRMaXN0ZW5lcihUb3VjaFV0aWwuUE9JTlRFUl9ET1dOLGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICBpZihfdGhhdC5vcHRpb25zLmFjY2VzcyAhPSAib3BlbiIpCiAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgICAgICBfdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICBfdGltZXI9MDsKICAgICAgICAgICAgICAgX3RoYXQuX29uQ3Jvc3NDbGljayhldmVudCk7CiAgICAgICAgICAgIH0sMTAwMCk7CiAgICAgICAgfSk7CiAgICAgICB0bXBFbC5hZGRFdmVudExpc3RlbmVyKFRvdWNoVXRpbC5QT0lOVEVSX1VQLGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgaWYoX3RoYXQub3B0aW9ucy5hY2Nlc3MgIT0gIm9wZW4iKQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICBpZihfdGltZXIpewogICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoX3RpbWVyKTsKICAgICAgICAgICAgICAgX3RoYXQuX29uSW1hZ2VDbGljayhldmVudCk7CiAgICAgICAgICAgIH0gCiAgICAgICAgfSk7CgkJCgkgICBpZihUb3VjaFV0aWwuUE9JTlRFUl9FTkFCTEVEKXsKCQkgICAgIHRoaXMuX2F0dGFjaEV2ZW50SGFuZGxlckZvckNyb3NzSWNvbigkY29udHJvbCk7CgkJCSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ICQoIiMiK190aGF0Ll93Z3RJZCkub24oVG91Y2hVdGlsLlBPSU5URVJfVVAsZnVuY3Rpb24oZXZlbnQpewoJCQkgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwoJCQkgfSk7fSw1MCk7CgkgICB9CiAgICB9LAoKICAgIF9hdHRhY2hNb3VzZUV2ZW50SGFuZGxlcnM6ZnVuY3Rpb24oJGNvbnRyb2wpewogICAgICAgICB2YXIgX3RpbWVyPTAsX3RoYXQ9dGhpcyxfaG92ZXJUaW1lcj0wOwogICAgICAgICRjb250cm9sLmRibGNsaWNrKGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgaWYoX3RoYXQub3B0aW9ucy5hY2Nlc3MgIT0gIm9wZW4iKQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7CiAgICAgICAgICAgaWYoX3RpbWVyLnZhbCl7CiAgICAgICAgICAgICBjbGVhclRpbWVvdXQoX3RpbWVyKTtfdGltZXIgPTA7CiAgICAgICAgICAgfQogICAgICAgICAgIF90aGF0Ll9vbkNyb3NzQ2xpY2soZXZlbnQpOwogICAgICAgIH0pLmNsaWNrKGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICBfdGhhdC4kdXNlckNvbnRyb2wudHJpZ2dlcigic2NyaWJibGVjbGljayIsZXZlbnQpOwogICAgICAgICAgIGlmKF90aGF0Lm9wdGlvbnMuYWNjZXNzICE9ICJvcGVuIikKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgICAgICAgIGlmKF90aW1lcil7CiAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF90aW1lcik7X3RpbWVyPTA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgX3RpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpewogICAgICAgICAgICAgICAgIF90aW1lcj0wOwogICAgICAgICAgICAgICAgIF90aGF0Ll9vbkltYWdlQ2xpY2soZXZlbnQpOwogICAgICAgICAgICAgIH0sNTAwKTsKICAgICAgICAgICAgfQogICAgICAgfSk7CgkgICAKCSAgIHRoaXMuX2F0dGFjaEV2ZW50SGFuZGxlckZvckNyb3NzSWNvbigkY29udHJvbCk7CiAgICAgICAKICAgIH0sCgogICAgX29uQ3Jvc3NDbGljazpmdW5jdGlvbihldmVudCl7CiAgICAgICAgaWYoIXRoaXMuX2lzX3JlYWRvbmx5KSByZXR1cm47CiAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wudHJpZ2dlcigic2NyaWJibGVmb2N1cyIsZXZlbnQpOwogICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXIoInNjcmliYmxlY2xpY2siLGV2ZW50KTsKICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKICAgICAgICAkLmFsZXJ0Qm94Lnllc05vKG51bGwsCiAgICAgICAgIHRoaXMubG9jYWxlU3RyaW5ncygpLmNsZWFyU2lnbmF0dXJlQ29uZmlybSwKICAgICAgICAgdGhpcy5sb2NhbGVTdHJpbmdzKCkuY2xlYXJTaWduYXR1cmUsCiAgICAgICAgICQucHJveHkodGhpcy5fcmVtb3ZlU2lnQ29uZmlybWF0aW9uSGFuZGxlcix0aGlzKSk7CiAgICAgfSwKCiAgICAgX3JlbW92ZVNpZ0NvbmZpcm1hdGlvbkhhbmRsZXI6ZnVuY3Rpb24oaXNZZXMpewogICAgICAgIGlmKGlzWWVzKXsKICAgICAgICAgICB0aGlzLl9zYXZlVmFsdWUodGhpcy5fZW1wdHlJbWFnZVZhbCk7CiAgICAgICAgICAgdGhpcy5fZGlzcGxheVZhbHVlKHRoaXMuX2V4dHJhY3REYXRhKHRoaXMuX2NyZWF0ZUVtcHR5SW1hZ2VEYXRhKCkpKTsKICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hZGRDbGFzcygiZW1wdHlTY3JpYmJsZSIpLnRyaWdnZXIoInNjcmliYmxlY2xvc2UiLHt9KTsKICAgICAgICAgICB0aGlzLl9pc19yZWFkb25seT1mYWxzZTsKICAgICAgICB9CiAgICAgfSwKCiAgICBfY3JlYXRlRW1wdHlJbWFnZURhdGE6ZnVuY3Rpb24oKXsKICAgICAgICAgaWYoIXRoaXMuX2VtcHR5SW1hZ2VEYXRhKXsKICAgICAgICAgICAgdmFyIGVtcHR5Q2FudmFzT2JqID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7CiAgICAgICAgICAgIGVtcHR5Q2FudmFzT2JqLnN0eWxlLndpZHRoPXRoaXMuX3NpZ0NhbnZhc1dpZHRoKydweCc7CiAgICAgICAgICAgIGVtcHR5Q2FudmFzT2JqLnN0eWxlLmhlaWdodD10aGlzLl9zaWdDYW52YXNIZWlnaHQrJ3B4JzsKICAgICAgICAgICAgZW1wdHlDYW52YXNPYmoud2lkdGg9dGhpcy5fc2lnQ2FudmFzV2lkdGg7CiAgICAgICAgICAgIGVtcHR5Q2FudmFzT2JqLmhlaWdodD10aGlzLl9zaWdDYW52YXNIZWlnaHQ7CiAgICAgICAgICAgIHZhciBjdHggPSBlbXB0eUNhbnZhc09iai5nZXRDb250ZXh0KCcyZCcpOwogICAgICAgICAgICBjdHguZmlsbFN0eWxlPScjZmZmZmZmJzsKICAgICAgICAgICAgY3R4LmNsZWFyUmVjdCgwLDAsdGhpcy5fc2lnQ2FudmFzV2lkdGgsdGhpcy5fc2lnQ2FudmFzSGVpZ2h0KTsKICAgICAgICAgICAgdGhpcy5fZW1wdHlJbWFnZURhdGEgPSBlbXB0eUNhbnZhc09iai50b0RhdGFVUkwoImltYWdlL3BuZyIpOwogICAgICAgICB9CiAgICAgICAgIHJldHVybiB0aGlzLl9lbXB0eUltYWdlRGF0YTsKICAgICB9LAoKICAgIGdldENvbW1pdFZhbHVlOiBmdW5jdGlvbigpIHsKICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnZhbHVlCiAgICB9LAoKICAgIF9zYXZlVmFsdWU6ZnVuY3Rpb24odmFsKXsKICAgICAgICB0aGlzLm9wdGlvbnMudmFsdWU9dmFsOwogICAgICAgIHRoaXMuJHVzZXJDb250cm9sLnRyaWdnZXIoJ3NjcmliYmxlY2hhbmdlJyk7CiAgICB9LAoKICAgIF9kaXNwbGF5VmFsdWU6ZnVuY3Rpb24odmFsKXsKICAgICAgICBpZih0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHkpIHsKICAgICAgICAgICAgLy9oYXJkY29kZSB0aGUgd2lkZ2V0IFZBTFVFIGJ5IHVua25vd24gaW1hZ2UgdHlwZQogICAgICAgICAgICBpZih2YWwpewogICAgICAgICAgICAgIHZhciB3aWRnZXRWYWx1ZSA9ICJkYXRhOmltYWdlL3BuZztiYXNlNjQsIit2YWw7CiAgICAgICAgICAgICAgICB0aGlzLl9zZXRWYWx1ZSh3aWRnZXRWYWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICB0aGlzLmxvZ2dlcigpLmRlYnVnKCJ4ZmFWaWV3IiwiW0RlZmF1bHRXaWRnZXQuX3VwZGF0ZV0sIFVzZXIgQ29udHJvbCBvciBDb21taXQgUHJvcGVydHkgaXMgbnVsbCIgKTsKICAgIH0sCgogICAgX2RvT2s6ZnVuY3Rpb24oKXsKICAgICAgICB2YXIgbWFpbkNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ0NBTlZBUycpOwogICAgICAgIHZhciBnZW9DbnYgPSAkKCcjJyt0aGlzLl9nZW9DYW52SWQpWzBdOwogICAgICAgIHZhciBzaWdDbnYgPSAkKCcjaUVCb3hfY2FudmFzJylbMF07CiAgICAgICAgdmFyIGN0eCA9IG1haW5DYW52YXMuZ2V0Q29udGV4dCgnMmQnKTsKICAgICAgIAogICAgICAgIGlmKGdlb0Nudi53aWR0aD4wJiZnZW9DbnYuaGVpZ2h0PjApewogICAgICAgICAgICAKICAgICAgICAgICAgaWYodGhpcy5fZ2VvTG9jQXRCb3R0b20pewogICAgICAgICAgICAgICAgbWFpbkNhbnZhcy53aWR0aD1zaWdDbnYud2lkdGg7CiAgICAgICAgICAgICAgICBtYWluQ2FudmFzLmhlaWdodCA9c2lnQ252LmhlaWdodCtnZW9DbnYuaGVpZ2h0OwogICAgICAgICAgICAgICAgY3R4LmRyYXdJbWFnZShzaWdDbnYsMCwwKTsKICAgICAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2UoZ2VvQ252LDAsc2lnQ252LmhlaWdodCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBtYWluQ2FudmFzLndpZHRoPXNpZ0Nudi53aWR0aCtnZW9DbnYud2lkdGg7CiAgICAgICAgICAgICAgICBtYWluQ2FudmFzLmhlaWdodCA9c2lnQ252LmhlaWdodDsKICAgICAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2Uoc2lnQ252LDAsMCk7CiAgICAgICAgICAgICAgICBjdHguZHJhd0ltYWdlKGdlb0NudixzaWdDbnYud2lkdGgsMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgbWFpbkNhbnZhcy53aWR0aD1zaWdDbnYud2lkdGg7CiAgICAgICAgICAgICBtYWluQ2FudmFzLmhlaWdodCA9c2lnQ252LmhlaWdodDsKICAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2Uoc2lnQ252LDAsMCk7CiAgICAgICAgfQogICAgICAgIGltYWdlRWRpdERpYWxvZy5oaWRlKCk7CiAgICAgICAgdmFyIG5ld2RhdGEgPSBtYWluQ2FudmFzLnRvRGF0YVVSTCgiaW1hZ2UvcG5nIik7Ly8odGhpcy5teVNjcmliYmxlSGFuZGxlfHwiIikudG9TdHJpbmcoKTsKICAgICAgICAKICAgICAgICAgdmFyIHZhbCx2YWwxOwogICAgICAgICBpZigodmFsPS8qPSovdGhpcy5fZXh0cmFjdERhdGEobmV3ZGF0YSkpKXsKICAgICAgICAgLy8gIHZhbDEgPSBQTkdVdGlsLl9tYWtlUmVhZE9ubHkodmFsKTsKICAgICAgICAgICAgdmFsID0gUE5HVXRpbC5fbWFrZVJlYWRPbmx5KHZhbCk7CiAgICAgICAgICAgIHRoaXMuX3NhdmVWYWx1ZSh2YWwpOyAgIAogICAgICAgICAgICB0aGlzLl9pc19yZWFkb25seT10cnVlOyAgICAgICAKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMuX2dlb0xvY1F1ZXJ5JiZ0aGlzLl9nZW9Mb2NRdWVyeS5jYW5jZWwoKTsvLyBjYW5jZWwgY3VycmVudCBnZW8gbG9jIHJlcXVlc3Q7CiAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wudHJpZ2dlcigic2NyaWJibGVjbG9zZSIpCiAgICB9LAogICAgX2hhbmRsZU9rOmZ1bmN0aW9uKCl7CiAgICAgICAgaWYodGhpcy5fZW5mb3JjZUdlb0xvYyl7CiAgICAgICAgICAgdGhpcy5fZ2VvTG9jUXVlcnkgPSBuZXcgR2VvTG9jUXVlcnkoKS5pbml0KCQucHJveHkoZnVuY3Rpb24oZGF0YSl7CiAgICAgICAgICAgICAgIHRoaXMuX2dlb1F1ZXJ5U3VjY2Vzc0hhbmRsZXIoZGF0YSk7CiAgICAgICAgICAgICAgIHRoaXMuX2RvT2soKTsKICAgICAgICAgICB9LHRoaXMpLCQucHJveHkodGhpcy5fZ2VvUXVlcnlFcnJvckhhbmRsZXIsdGhpcykpOwogICAgICAgICAgIHRoaXMuX2dlb0xvY1F1ZXJ5LnF1ZXJ5KCk7CiAgICAgICAgICAgdGhpcy5fc2hvd01lc3NhZ2UodGhpcy5sb2NhbGVTdHJpbmdzKCkuZmV0Y2hHZW9Mb2NhdGlvbik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHRoaXMuX2RvT2soKTsKICAgICAgICB9CiAgICB9LAoKICAgIF9oYW5kbGVDYW5jZWw6ZnVuY3Rpb24oKXsKICAgICAgICAgaW1hZ2VFZGl0RGlhbG9nLmhpZGUoKTsKICAgICAgICAgdGhpcy5fZ2VvTG9jUXVlcnkmJnRoaXMuX2dlb0xvY1F1ZXJ5LmNhbmNlbCgpOy8vIGNhbmNlbCBjdXJyZW50IGdlbyBsb2MgcmVxdWVzdDsKICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC50cmlnZ2VyKCJzY3JpYmJsZWNsb3NlIikKICAgIH0sCgogICAgX2hhbmRsZUNsZWFyOmZ1bmN0aW9uKCl7CiAgICAgICAgdGhpcy5teVNjcmliYmxlSGFuZGxlLnNldEVuYWJsZWQodHJ1ZSk7CiAgICAgICAgdGhpcy5faXNfcmVhZG9ubHk9ZmFsc2U7CiAgICAgICAgdGhpcy5fbWFrZVJlYWRPbmx5KHRoaXMuX2lzX3JlYWRvbmx5KTsKICAgICAgICAkKCcjaUVCb3hfY2FudmFzJylbMF0ud2lkdGg9dGhpcy5fc2lnQ2FudmFzV2lkdGg7CiAgICAgICAgICQoJyNpRUJveF9jYXB0aW9uJykud2lkdGgodGhpcy5fc2lnQ2FudmFzV2lkdGgpOwoJCSQoJyNpRUJveF9jYW52YXMnKVswXS5oZWlnaHQ9dGhpcy5fc2lnQ2FudmFzSGVpZ2h0OwogICAgICAgICQoJyNrZXlib2FyZF9TaWduX0JveCcpWzBdLnZhbHVlPSIiOwogICAgICAgIHZhciBnZW9DYW52ID0gJCgnIycrdGhpcy5fZ2VvQ2FudklkKVswXTsKICAgICAgICBpbWFnZUVkaXREaWFsb2cuZW5hYmxlQnV0dG9ucyh7T2s6ZmFsc2UsQ2xlYXI6ZmFsc2V9KTsKICAgICAgICBnZW9DYW52LndpZHRoPTA7CiAgICAgICAgZ2VvQ2Fudi5oZWlnaHQ9MDsKICAgICAgICBpbWFnZUVkaXREaWFsb2cuX3Jlc2l6ZSgpOwogICAgICAgIHRoaXMuX2dlb0xvY1F1ZXJ5JiZ0aGlzLl9nZW9Mb2NRdWVyeS5jYW5jZWwoKTsvLyBjYW5jZWwgY3VycmVudCBnZW8gbG9jIHJlcXVlc3Q7CiAgICB9LAogICAgX21ha2VSZWFkT25seTpmdW5jdGlvbihyZWFkb25seSl7CiAgICAgICBpbWFnZUVkaXREaWFsb2cuZW5hYmxlQnV0dG9ucyh7T2s6ZmFsc2UsQ2xlYXI6ZmFsc2UsR2VvOiFyZWFkb25seSxCcnVzaDohcmVhZG9ubHksVGV4dDohcmVhZG9ubHl9KTsKICAgICAgIGlmKHJlYWRvbmx5KXsKCQkgICAkKCcjaUVCb3hfY2FudmFzJykuY3NzKHtib3JkZXI6JzFweCBzb2xpZCBncmF5J30pOwogICAgICAgICAgICQoJyNpRUJveF9jYXB0aW9uJykuY3NzKHtkaXNwbGF5Oidub25lJ30pOwoKICAgICAgIH0KICAgICAgIHRoaXMuX2RlZmF1bHRTdGF0dXMgPSAiJm5ic3A7IjsKICAgICAgIHRoaXMuX3Nob3dNZXNzYWdlKHRoaXMuX2RlZmF1bHRTdGF0dXMpOwogICAgfSwKCiAgICBfc2hvd01lc3NhZ2U6ZnVuY3Rpb24obXNnKXsKICAgICAgICB2YXIgX3RoYXQgPSB0aGlzOwogICAgICAgIGlmKHRoaXMuX21zZ1RpbWVvdXQpIHsgY2xlYXJUaW1lb3V0KHRoaXMuX21zZ1RpbWVvdXQpOyB0aGlzLl9tc2dUaW1lb3V0PTA7IH0KICAgICAgICAgJCgiI2lFQm94X3RpdGxlIikucmVwbGFjZVdpdGgoJzxkaXYgaWQ9ImlFQm94X3RpdGxlIj4nK21zZysnPC9kaXY+Jyk7CiAgICAgICAgIHRoaXMuX21zZ1RpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpewogICAgICAgICAgICAgJCgiI2lFQm94X3RpdGxlIikucmVwbGFjZVdpdGgoJzxkaXYgaWQ9ImlFQm94X3RpdGxlIj4nK190aGF0Ll9kZWZhdWx0U3RhdHVzKyc8L2Rpdj4nKTsKICAgICAgICAgfSwxNTAwMCk7CiAgICB9LAoKICAgIF9nZW9RdWVyeUVycm9ySGFuZGxlcjpmdW5jdGlvbihlcnIpewogICAgICAgIHRoaXMuX3Nob3dNZXNzYWdlKHRoaXMubG9jYWxlU3RyaW5ncygpLmVycm9yRmV0Y2hHZW9Mb2NhdGlvbik7CiAgICB9LAoKCV9nZXRMb2dNZXNzYWdlOmZ1bmN0aW9uKGtleSl7CgkJICAgICByZXR1cm4gdGhpcy5sb2dNc2dzKClba2V5XXx8a2V5OwoJfSwKCiAgICBfaGFuZGxlR2VvOmZ1bmN0aW9uKCl7CiAgICAgICAgICAvLyBpbml0aWF0ZSBnZW9sb2NhdGlvbiAKICAgICAgIGlmKG5hdmlnYXRvci5nZW9sb2NhdGlvbil7CiAgICAgICAgICAgdGhpcy5fZ2VvTG9jUXVlcnkgPSBuZXcgR2VvTG9jUXVlcnkoKS5pbml0KCQucHJveHkodGhpcy5fZ2VvUXVlcnlTdWNjZXNzSGFuZGxlcix0aGlzKSwkLnByb3h5KHRoaXMuX2dlb1F1ZXJ5RXJyb3JIYW5kbGVyLHRoaXMpKTsKICAgICAgICAgICB0aGlzLl9nZW9Mb2NRdWVyeS5xdWVyeSgpOwogICAgICAgICAgIHRoaXMuX3Nob3dNZXNzYWdlKHRoaXMubG9jYWxlU3RyaW5ncygpLmZldGNoR2VvTG9jYXRpb24pOwogICAgICAgfSBlbHNlIHsKICAgICAgICAgICB0aGlzLmxvZ2dlcigpLmRlYnVnKCJ4ZmFWaWV3Iix0aGlzLl9nZXRMb2dNZXNzYWdlKCJBTEMtRlJNLTkwMS0wMTEiKSk7CiAgICAgICB9CiAgICB9LAoKICAgIC8vIFRoaXMgRnVuY3Rpb24gaXMgdXNlZCB0byBmZXRjaCB0aGUgZ2VvbG9jYXRpb24uCiAgICBjYWxjdWxhdGVHZW9sb2NhdGlvbjogZnVuY3Rpb24oKXsKICAgICAgdGhpcy5faGFuZGxlR2VvKCk7CiAgICB9LAoKICAgIF9oYW5kbGVUZXh0OmZ1bmN0aW9uKCl7CiAgICAgICAgdmFyIHNpZ25Cb3hFbD1kb2N1bWVudC5nZXRFbGVtZW50QnlJZCgia2V5Ym9hcmRfU2lnbl9Cb3giKTsKICAgICAgICB2YXIgc2lnbkNhbnZhc0VsPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJpRUJveF9jYW52YXMiKTsKICAgICAgICBpZihzaWduQm94RWwudmFsdWUubGVuZ3RoPT0wKXsKICAgICAgICAgICAgdGhpcy5faGFuZGxlQ2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5fZGlzYWJsZVNpZ25hdHVyZUNhbnZhcygpOwogICAgICAgIHRoaXMuX2VuYWJsZVNpZ25hdHVyZVRleHRCb3goKTsKICAgICAgICBzaWduQm94RWwuZm9jdXMoKTsKICAgIH0sCgogICAgX2Rpc2FibGVTaWduYXR1cmVUZXh0Qm94OmZ1bmN0aW9uKCl7CiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImtleWJvYXJkX1NpZ25fQm94Iikuc3R5bGUuZGlzcGxheSA9ICJub25lIjsKICAgIH0sCgogICAgX2VuYWJsZVNpZ25hdHVyZVRleHRCb3g6ZnVuY3Rpb24oKXsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgia2V5Ym9hcmRfU2lnbl9Cb3giKS5zdHlsZS5kaXNwbGF5ID0gImlubGluZS1ibG9jayI7CiAgICB9LAoKICAgIF9kaXNhYmxlU2lnbmF0dXJlQ2FudmFzOmZ1bmN0aW9uKCl7CiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoImlFQm94X2NhbnZhcyIpLnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7CiAgICB9LAoKICAgIF9lbmFibGVTaWduYXR1cmVDYW52YXM6ZnVuY3Rpb24oKXsKICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiaUVCb3hfY2FudmFzIikuc3R5bGUuZGlzcGxheSA9ICJpbmxpbmUtYmxvY2siOwogICAgfSwKCiAgICBfaGFuZGxlQnJ1c2hTZWxlY3Q6ZnVuY3Rpb24odyl7CiAgICAgICAgaWYodGhpcy5teVNjcmliYmxlSGFuZGxlJiYhdGhpcy5faXNfcmVhZG9ubHkpIHsKICAgICAgICAgICAgdGhpcy5teVNjcmliYmxlSGFuZGxlLnNldExpbmVXaWR0aCh3KTsKICAgICAgICB9CiAgICB9LAoKICAgIF9oYW5kbGVCcnVzaDpmdW5jdGlvbihldnQpewogICAgICAgIGlmKCQoJyNrZXlib2FyZF9TaWduX0JveCcpWzBdLnZhbHVlLmxlbmd0aD4wKXsKICAgICAgICAgICAgdGhpcy5faGFuZGxlQ2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5fZGlzYWJsZVNpZ25hdHVyZVRleHRCb3goKTsKICAgICAgICB0aGlzLl9lbmFibGVTaWduYXR1cmVDYW52YXMoKTsKICAgICAgICBpbWFnZUVkaXREaWFsb2cudG9nZ2xlQnJ1c2hMaXN0KGV2dCk7CiAgICB9LAoJX2hhbmRsZUtleURvd246ZnVuY3Rpb24oZXZlbnQpewoJCWlmKGV2ZW50LmtleUNvZGUgPT0gRU5URVJfS0VZIHx8IGV2ZW50LmNoYXJDb2RlID09IEVOVEVSX0tFWSB8fCBldmVudC53aGljaCA9PSBFTlRFUl9LRVkpIHsgLy8gdG91Y2ggZGV2aWNlcyBtYXkgcmV0dXJuIGNoYXJDb2RlCgkJICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CgkJICAgIHRoaXMuX29uSW1hZ2VDbGljayhldmVudCk7CgkJfSBlbHNlIGlmKGV2ZW50LmtleUNvZGUgPT0gREVMRVRFX0tFWSB8fCBldmVudC5jaGFyQ29kZSA9PSBERUxFVEVfS0VZIHx8IGV2ZW50LndoaWNoID09IERFTEVURV9LRVkpIHsKCQkgICAgdGhpcy5fb25Dcm9zc0NsaWNrKGV2ZW50KTsKCQl9CiAgICB9LAogICAgX2RpYWxvZ0NhbGxiYWNrOmZ1bmN0aW9uKGJ1dHRvbl92YWwsYXJnMSl7CiAgICAgICAgICAgLy8gYWRkIGJhY2sgb24gY2xpY2sgaGFuZGxlcgogICAgICAgICAvLyAgdGhpcy4kdXNlckNvbnRyb2wuY2xpY2soJC5wcm94eSh0aGlzLl9vbkltYWdlQ2xpY2ssIHRoaXMpKTsKICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgc3dpdGNoKGJ1dHRvbl92YWwpewogICAgICAgICAgICAgICBjYXNlICJPayI6CiAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZU9rKCk7CiAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICBjYXNlICJDYW5jZWwiOgogICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVDYW5jZWwoKTsKICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgIGNhc2UgIkNsZWFyIjoKICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQ2xlYXIoKTsKICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgIGNhc2UgIkdlbyI6CiAgICAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlR2VvbG9jYXRpb24oKTsKICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgIGNhc2UgIkJydXNoU2VsZWN0IjoKICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQnJ1c2hTZWxlY3QoYXJnMSk7CiAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICBjYXNlICJCcnVzaCI6CiAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUJydXNoKGFyZzEpOwogICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgY2FzZSAiVGV4dCI6CiAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVRleHQoKTsKICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgCiAgICAgICAgICAgfQogICAgfSwKCiAgICBfZ2VvUXVlcnlTdWNjZXNzSGFuZGxlcjpmdW5jdGlvbihkYXRhKXsKICAgICAgICB0aGlzLl9yZW5kZXJQb3NpdGlvbihkYXRhKTsKICAgIH0sCgoJX2ZpdEdlb0xvY1RleHQ6ZnVuY3Rpb24obGF0U3RyLGxvbmdTdHIsdGltZVN0cixjdHgsbWF4V2lkdGgsbWF4SGVpZ2h0KXsKCSAgICB2YXIgZm9udFNpemU9MTI7CgkJY3R4LmZvbnQ9ImJvbGQgIitmb250U2l6ZSsicHQgQXJpYWwiOwoJCXZhciB3aWR0aCA9IE1hdGgubWF4KGN0eC5tZWFzdXJlVGV4dChsYXRTdHIpLndpZHRoLGN0eC5tZWFzdXJlVGV4dChsb25nU3RyKS53aWR0aCxjdHgubWVhc3VyZVRleHQodGltZVN0cikud2lkdGgpOwoJCXZhciBsaW5lSGVpZ2h0ID0gY3R4Lm1lYXN1cmVUZXh0KCJtIikud2lkdGgqMS41OwoJCXdoaWxlKCh3aWR0aD5tYXhXaWR0aHx8MypsaW5lSGVpZ2h0Pm1heEhlaWdodCkmJmZvbnRTaXplPjEpewoJCSAgICBmb250U2l6ZS0tOwoJCSAgICBjdHguZm9udD0iYm9sZCAiK2ZvbnRTaXplKyJwdCBBcmlhbCI7CgkJICAgIHdpZHRoID0gTWF0aC5tYXgoY3R4Lm1lYXN1cmVUZXh0KGxhdFN0cikud2lkdGgsY3R4Lm1lYXN1cmVUZXh0KGxvbmdTdHIpLndpZHRoLGN0eC5tZWFzdXJlVGV4dCh0aW1lU3RyKS53aWR0aCk7CgkJICAgIGxpbmVIZWlnaHQgPSBjdHgubWVhc3VyZVRleHQoIm0iKS53aWR0aCoxLjU7CgkJfQoJCXJldHVybiB7d2lkdGg6d2lkdGgsbGluZUhlaWdodDpsaW5lSGVpZ2h0LGZvbnRTaXplOmZvbnRTaXplfTsKCX0sCgogICAgX3JlbmRlclBvc2l0aW9uOmZ1bmN0aW9uKHBvc2l0aW9uKXsKICAgICAgICBpZihwb3NpdGlvbiYmcG9zaXRpb24uY29vcmRzKXsKICAgICAgICAgdGhpcy5fc2hvd01lc3NhZ2UoIiZuYnNwOyIpOwogICAgICAgICAgICB2YXIgbGF0U3RyID0gdGhpcy5sb2NhbGVTdHJpbmdzKCkubGF0aXR1ZGUrIjogIiArIHBvc2l0aW9uLmNvb3Jkcy5sYXRpdHVkZTsKICAgICAgICAgICAgdmFyIGxvbmdTdHIgPSB0aGlzLmxvY2FsZVN0cmluZ3MoKS5sb25naXR1ZGUrIjogIiArIHBvc2l0aW9uLmNvb3Jkcy5sb25naXR1ZGU7CiAgICAgICAgICAgIHZhciBkYXRlT2JqID0gbmV3IERhdGUoKTsKICAgICAgICAgICAgdmFyIHRab25lID0gKGRhdGVPYmouZ2V0VGltZXpvbmVPZmZzZXQoKS82MCotMSk7CiAgICAgICAgICAgIAogICAgICAgICAgICB2YXIgdGltZVN0ciA9IHRoaXMubG9jYWxlU3RyaW5ncygpLnRpbWUrIjogIisoZGF0ZU9iai5nZXRNb250aCgpKzEpKyIvIitkYXRlT2JqLmdldERhdGUoKSsiLyIrZGF0ZU9iai5nZXRGdWxsWWVhcigpKyIgIitkYXRlT2JqLmdldEhvdXJzKCkrIjoiK2RhdGVPYmouZ2V0TWludXRlcygpKyI6IitkYXRlT2JqLmdldFNlY29uZHMoKSsoKHRab25lPjApPyIgKyI6IiAiKSsodFpvbmUpOwogICAgICAgICAgICB2YXIgY2FudmFzT2JqICA9ICQoJyMnK3RoaXMuX2dlb0NhbnZJZClbMF07CgkJCXZhciBzaWdDYW52YXMgPSAkKCcjaUVCb3hfY2FudmFzJylbMF07CiAgICAgICAgICAgIHZhciBzaWdUZXh0Qm94ID0gJCgnI2tleWJvYXJkX1NpZ25fQm94JylbMF07CgkJCXZhciBkdW1teUNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpOwogICAgICAgICAgICBpZihjYW52YXNPYmopewoJCQkgICB2YXIgY3R4ID0gY2FudmFzT2JqLmdldENvbnRleHQoJzJkJyk7CgkJCSAgIGN0eC5mb250PSJib2xkIDEycHQgQXJpYWwiOwoKCQkJICAgY2FudmFzT2JqLndpZHRoPXRoaXMuX2dlb0NhbnZhc1dpZHRoOwogICAgICAgICAgICAgICBjYW52YXNPYmouaGVpZ2h0PXRoaXMuX2dlb0NhbnZhc0hlaWdodDsKCQkJICAgdmFyIGxheW91dCA9IHRoaXMuX2ZpdEdlb0xvY1RleHQobGF0U3RyLGxvbmdTdHIsdGltZVN0cixjdHgsY2FudmFzT2JqLndpZHRoLGNhbnZhc09iai5oZWlnaHQpOwogICAgICAgICAgICAgICB2YXIgYXNwZWN0UmF0aW8gOwogICAgIAkJICAgYXNwZWN0UmF0aW8gPSB0aGlzLmFzcGVjdFJhdGlvVG9CZVVzZWQoKTsKCQkJICAgaWYoIXRoaXMuX2VuZm9yY2VHZW9Mb2MpewoJCQkgICAgICAgaWYodGhpcy5fZ2VvTG9jQXRCb3R0b20pewogICAgICAgICAgICAgICAgICAgICBkdW1teUNhbnZhcy5oZWlnaHQgPSB0aGlzLl9zaWdDYW52YXNIZWlnaHQtY2FudmFzT2JqLmhlaWdodDsKICAgICAgICAgICAgICAgICAgICAgZHVtbXlDYW52YXMud2lkdGggPSBkdW1teUNhbnZhcy5oZWlnaHQvYXNwZWN0UmF0aW87CiAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICBkdW1teUNhbnZhcy53aWR0aCA9IHRoaXMuX3NpZ0NhbnZhc1dpZHRoLWNhbnZhc09iai53aWR0aDsKCQkJCQkgZHVtbXlDYW52YXMuaGVpZ2h0ID0gZHVtbXlDYW52YXMud2lkdGgqYXNwZWN0UmF0aW87CgkJCQkgICB9CgkJCQkgICAvLyBtb3ZlIGRyYXduIHNpZ25hdHVyZSB0byBhIHRlbXBvcmFyeSBjYW52YXMgYW5kIHNjYWxlIGl0IHRvIG5ldyBkaW1lbnNpb24KICAgICAgICAgICAgICAgICAgIGR1bW15Q2FudmFzLmdldENvbnRleHQoJzJkJykuZHJhd0ltYWdlKHNpZ0NhbnZhcywwLDAsZHVtbXlDYW52YXMud2lkdGgsZHVtbXlDYW52YXMuaGVpZ2h0KTsKICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX2dlb0xvY0F0Qm90dG9tKXsKICAgICAgICAgICAgICAgICAgICAgc2lnQ2FudmFzLmhlaWdodCA9IGR1bW15Q2FudmFzLmhlaWdodDsKICAgICAgICAgICAgICAgICAgICAgc2lnVGV4dEJveC5oZWlnaHQgPSBkdW1teUNhbnZhcy5oZWlnaHQ7CiAgICAgICAgICAgICAgICAgICAgIHNpZ0NhbnZhcy5nZXRDb250ZXh0KCcyZCcpLmRyYXdJbWFnZShkdW1teUNhbnZhcywoc2lnQ2FudmFzLndpZHRoLWR1bW15Q2FudmFzLndpZHRoKS8yLDApOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgc2lnQ2FudmFzLndpZHRoID0gZHVtbXlDYW52YXMud2lkdGg7CiAgICAgICAgICAgICAgICAgICAgIHNpZ1RleHRCb3gud2lkdGggPSBkdW1teUNhbnZhcy53aWR0aDsKICAgICAgICAgICAgICAgICAgICAgc2lnQ2FudmFzLmdldENvbnRleHQoJzJkJykuZHJhd0ltYWdlKGR1bW15Q2FudmFzLDAsKHNpZ0NhbnZhcy5oZWlnaHQtZHVtbXlDYW52YXMuaGVpZ2h0KS8yKTsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICQoJyNpRUJveF9jYXB0aW9uJykud2lkdGgoc2lnQ2FudmFzLndpZHRoKTsKCQkJCSAgIGltYWdlRWRpdERpYWxvZy5lbmFibGVCdXR0b25zKHtDbGVhcjp0cnVlfSk7CgkJCSAgIH0KCQkJICAgICAgCgkJCSAgIHZhciBmd2lkdGggPSBsYXlvdXQud2lkdGg7CiAgICAgICAgICAgICAgIHZhciBmaGVpZ2h0ID0gbGF5b3V0LmxpbmVIZWlnaHQ7CgkJCSAgIHZhciBib3R0b21NYXJnaW49MjsKICAgICAgICAgICAgICAgY3R4LmZpbGxTdHlsZT0nIzU1NTU1NSc7CiAgICAgICAgICAgICAgIGN0eC5mb250PSJib2xkICIrbGF5b3V0LmZvbnRTaXplKyJwdCBBcmlhbCI7CiAgICAgICAgICAgICAgIGN0eC5maWxsVGV4dChsYXRTdHIsMCxjYW52YXNPYmouaGVpZ2h0LTIqZmhlaWdodC1ib3R0b21NYXJnaW4pOwogICAgICAgICAgICAgICBjdHguZmlsbFRleHQobG9uZ1N0ciwwLGNhbnZhc09iai5oZWlnaHQtZmhlaWdodC1ib3R0b21NYXJnaW4pOwogICAgICAgICAgICAgICBjdHguZmlsbFRleHQodGltZVN0ciwwLGNhbnZhc09iai5oZWlnaHQtYm90dG9tTWFyZ2luKTsKCQkJICAgCgkJCSAgIGltYWdlRWRpdERpYWxvZy5fcmVzaXplKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAogICAgX3NjcmliYmxlQ2FsbGJhY2s6ZnVuY3Rpb24oKXsKICAgICAgIGltYWdlRWRpdERpYWxvZy5lbmFibGVCdXR0b25zKHtDbGVhcjp0cnVlLE9rOnRydWV9KTsgIC8vICBlbmFibGUgY2xlYXIgYW5kIG9rIGJ1dHRvbnMKICAgIH0sCiAgICBfb25JbWFnZUNsaWNrOmZ1bmN0aW9uKCl7CiAgICAgICBpZighaW1hZ2VFZGl0RGlhbG9nLmdldElzT3BlbigpKXsKICAgICAgICAgICB2YXIgX3RoYXQgPSB0aGlzOwogICAgICAgICAgIGltYWdlRWRpdERpYWxvZy5zaG93KCImbmJzcDsiLCQucHJveHkodGhpcy5fZGlhbG9nQ2FsbGJhY2ssIHRoaXMpKTsKICAgICAgICAgICBpZighdGhpcy5fZW5mb3JjZUdlb0xvYyl7CiAgICAgICAgICAgICAgICQoJyNpRUJveF9HZW8nKS5jc3Moe2Rpc3BsYXk6J2lubGluZS1ibG9jayd9KTsKICAgICAgICAgICB9CiAgICAgICAgICAgdmFyIGltYWdlID0gbmV3IEltYWdlKCk7CiAgICAgICAgICAgaW1hZ2Uub25sb2FkPWZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgIF90aGF0Lm15U2NyaWJibGVIYW5kbGUgPSBuZXcgU2NyaWJibGUoImlFQm94X2NhbnZhcyIsaW1hZ2UsaW1hZ2Uud2lkdGgsaW1hZ2UuaGVpZ2h0LCQucHJveHkoX3RoYXQuX3NjcmliYmxlQ2FsbGJhY2ssX3RoYXQpKTsKICAgICAgICAgICAgICAgX3RoYXQubXlTY3JpYmJsZUhhbmRsZS5zZXRFbmFibGVkKCFfdGhhdC5faXNfcmVhZG9ubHkpOwogICAgICAgICAgICAgICAkKCcjaUVCb3hfY2FwdGlvbicpLndpZHRoKGltYWdlLndpZHRoKTsKICAgICAgICAgICAgICAgJCgnI2lFQm94X2NvbnRhaW5lcicpLmNzcyh7ZGlzcGxheTondGFibGUnfSk7CiAgICAgICAgICAgICAgIGlmKCQoJyNpRUJveF9jb250YWluZXInKS5sZW5ndGggPT0gMSl7CiAgICAgICAgICAgICAgICAgICAkKCcjaUVCb3hfY29udGFpbmVyJylbMF0uZm9jdXMoKTsKICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICBpbWFnZUVkaXREaWFsb2cuX3Jlc2l6ZSgpOwogICAgICAgICAgICAgICBpbWFnZUVkaXREaWFsb2cuX3JlcG9zaXRpb24oKTsgICAgICAvLyByZWNhbGN1bGF0ZSBwb3NpdGlvbiwgc28gdGhhdCB0aGUgdmFsdWVzIGFyZSB1cGRhdGVkLCBlc3AuIGluIGlQYWQKICAgICAgICAgICB9CiAgICAgICAgICAgaWYoIXRoaXMub3B0aW9ucy52YWx1ZXx8dGhpcy5vcHRpb25zLnZhbHVlPT10aGlzLl9lbXB0eUltYWdlVmFsKXsKICAgICAgICAgICAgICAgdGhpcy5faXNfcmVhZG9ubHk9ZmFsc2U7CiAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmFkZENsYXNzKCJlbXB0eVNjcmliYmxlIik7CiAgICAgICAgICAgICAgIGltYWdlLnNyYyA9IHRoaXMuX2NyZWF0ZUVtcHR5SW1hZ2VEYXRhKCk7CiAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucmVtb3ZlQ2xhc3MoImVtcHR5U2NyaWJibGUiKTsKICAgICAgICAgICAgICAgaWYoUE5HVXRpbC5faXNQbmcodGhpcy5vcHRpb25zLnZhbHVlKSl7CiAgICAgICAgICAgICAgICAgICB0aGlzLl9pc19yZWFkb25seSA9ICEhUE5HVXRpbC5faXNSZWFkT25seSh0aGlzLm9wdGlvbnMudmFsdWUpOwoJCQkgICAgICAgaW1hZ2Uuc3JjID0gImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCwiK3RoaXMub3B0aW9ucy52YWx1ZTsvL3RoaXMuY3JlYXRlQmwgX3RoYXQuJHVzZXJDb250cm9sLmF0dHIoX3RoYXQub3B0aW9ucy5jb21taXRQcm9wZXJ0eSk7CiAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICBpbWFnZS5zcmMgPSAiZGF0YTo7YmFzZTY0LCIgKyB0aGlzLm9wdGlvbnMudmFsdWU7Ly90aGlzLmNyZWF0ZUJsIF90aGF0LiR1c2VyQ29udHJvbC5hdHRyKF90aGF0Lm9wdGlvbnMuY29tbWl0UHJvcGVydHkpOwoJCSAgICAgICB9CiAgICAgICAgICAgfQogICAgICAgICAgIHRoaXMuX21ha2VSZWFkT25seSh0aGlzLl9pc19yZWFkb25seSk7CiAgICAgICB9CiAgICB9LAoKICAgIF9leHRyYWN0RGF0YTpmdW5jdGlvbihkYXRhdXJpKXsKICAgICAgICB2YXIgaWR4OwogICAgICAgIGlmKGRhdGF1cmkhPW51bGwmJmRhdGF1cmkubGVuZ3RoPjAmJmRhdGF1cmkuaW5kZXhPZigiZGF0YToiKT09MCl7CiAgICAgICAgICAgIGlmKChpZHg9ZGF0YXVyaS5pbmRleE9mKCIsIikpPjApewogICAgICAgICAgICAgICAgcmV0dXJuIGRhdGF1cmkuc3Vic3RyKGlkeCsxKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0sCgogICAgX3NldFZhbHVlOmZ1bmN0aW9uKHZhbCl7CiAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wucHJvcCh0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHksIHZhbCk7CiAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYXR0cih0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHksIHZhbCk7CiAgICAgICAgaWYodGhpcy5fZHVtbXlJbWcpewogICAgICAgICAgICB0aGlzLl9kdW1teUltZy5zZXRBdHRyaWJ1dGUodGhpcy5vcHRpb25zLmNvbW1pdFByb3BlcnR5LHZhbCk7CiAgICAgICAgfQogICAgfQp9KTsKIC8vaGFjayBmb3IgSU9TNSB0b3VjaCBidWcKICAkKGZ1bmN0aW9uKCl7CiAgICAgICAgICQoJ2JvZHknKS5vbigndG91Y2hzdGFydCcsIGZ1bmN0aW9uKGUpIHt9KTsKICB9KTsKICAKfSkoJCx4ZmFsaWIpOwooZnVuY3Rpb24gKCQsIHdpbmRvdywgXykgewoKICAgIHZhciBfZGVmYXVsdHMgPSB7CiAgICAgICAgcGxhY2VIb2xkZXJUZXh0IDogIkVudGVyIGNvbW1lbnRzIGhlcmUiCiAgICB9OwoKICAgIHZhciBBZG9iZUZpbGVBdHRhY2htZW50ID0gZnVuY3Rpb24gKGVsZW1lbnQsIG9wdGlvbnMpIHsKICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zOwogICAgICAgIHRoaXMuJGVsZW1lbnRGaWxlVXBsb2FkQnRuID0gW107CiAgICAgICAgdGhpcy4kZWxlbWVudEZpbGVMaXN0ID0gW107CiAgICAgICAgdGhpcy4kZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICAgICAgaWYgKHRoaXMuJGVsZW1lbnQuYXR0cigibXVsdGlwbGUiKSAmJiAheGZhbGliLnV0LlV0aWxpdGllcy5faXNEYXRhQ29udGFpbmVyU3VwcG9ydGVkKCkpIHsKICAgICAgICAgICAgLy8gcmVtb3ZlIG11bHRpcGxlIGF0dHJpYnV0ZSBpZiBtdWx0aSBmaWxlIHNlbGVjdGlvbiBpbiBvbmUgZ28gaXMgbm90IHN1cHBvcnRlZAogICAgICAgICAgICB0aGlzLiRlbGVtZW50LnJlbW92ZUF0dHIoIm11bHRpcGxlIik7CiAgICAgICAgfQogICAgICAgIHRoaXMuJHBhcmVudCA9IHRoaXMuJGVsZW1lbnQucGFyZW50KCk7CiAgICAgICAgdGhpcy5pbnZhbGlkRmVhdHVyZSA9IHsKICAgICAgICAgICAgIlNJWkUiOjEsCiAgICAgICAgICAgICJOQU1FIjoyLAogICAgICAgICAgICAiTUlNRVRZUEUiOjMKICAgICAgICB9OwogICAgICAgIE9iamVjdC5mcmVlemUodGhpcy5pbnZhbGlkRmVhdHVyZSk7CiAgICAgICAgLy8gaW5pdGlhbGl6ZSB0aGUgcmVnZXggaW5pdGlhbGx5CiAgICAgICAgdGhpcy5yZWdleE1pbWVUeXBlTGlzdCAgPSB0aGlzLm9wdGlvbnMubWltZVR5cGUubWFwKGZ1bmN0aW9uICh2YWx1ZSwgaSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWdFeHAodmFsdWUudHJpbSgpKTsKICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgLy8gZmFpbHVyZSBkdXJpbmcgcmVnZXggcGFyc2luZywgZG9uJ3QgcmV0dXJuIGFueXRoaW5nIHNwZWNpZmljIHRvIHRoaXMgdmFsdWUgc2luY2UgdGhlIHZhbHVlIGNvbnRhaW5zCiAgICAgICAgICAgICAgICAvLyBpbmNvcnJlY3QgcmVnZXggc3RyaW5nCiAgICAgICAgICAgICAgICBpZih3aW5kb3cuY29uc29sZSkgewogICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9OwoKICAgIHZhciBpc0Jyb3dzZXJJRTlPcklFMTAgPSAoJC5icm93c2VyLm1zaWUgJiYgKCQuYnJvd3Nlci52ZXJzaW9uID09PSAnOS4wJyB8fCAkLmJyb3dzZXIudmVyc2lvbiA9PT0gJzEwLjAnKSksCiAgICAgICAgZmlsZUxhYmVsc0NvdW50ID0gMDsKCgogICAgQWRvYmVGaWxlQXR0YWNobWVudC5wcm90b3R5cGUgPSB7CiAgICAgICAgX2ZpbGVJZnJhbWVOYW1lIDogImd1aWRlLWZ1LWlmcmFtZSIsCiAgICAgICAgX2FkZEZpbGUgOiAiQWRkIEZpbGUiLAoKICAgICAgICBjbGVhcjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLiRlbGVtZW50LnZhbCgnJyk7CiAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRGaWxlTGlzdC5lbXB0eSgpOwogICAgICAgIH0sCgogICAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdGhpcy4kZmlsZURvbUVsZW1lbnRzID0gJC5tYXAodGhpcy4kZmlsZURvbUVsZW1lbnRzLCBmdW5jdGlvbihpdGVtKXsKICAgICAgICAgICAgICAgIC8vIHNpbmNlIGl0ZW0gY2FuIGJlIG51bGwgb3Igb2JqZWN0LCBkb2luZyB0aGlzIGNoZWNrCiAgICAgICAgICAgICAgICBpZihfLmlzT2JqZWN0KGl0ZW0pICYmIGl0ZW0udmFsKCkubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgLy9UT0RPOiByZW1vdmUgaXRlbSBmcm9tIGRvbSwgc2luY2UgdGhlcmUgaXMgYSBtZW1vcnkgbGVhawogICAgICAgICAgICAgICAgICAgIHJldHVybiBpdGVtOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgdGhpcy52YWx1ZXMgPSBbXTsKICAgICAgICAgICAgaWYoaXNCcm93c2VySUU5T3JJRTEwKXsKICAgICAgICAgICAgICAgIGlmKF8ubGFzdCh0aGlzLiRmaWxlRG9tRWxlbWVudHMpID09IG51bGwpewogICAgICAgICAgICAgICAgICAgIHRoaXMuY2xvbmVGaWxlSW5wdXRBbmRVcGRhdGVJZEZvcklFOSgpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUxhYmVsRm9yQXR0cihfLmxhc3QodGhpcy4kZmlsZURvbUVsZW1lbnRzKS5hdHRyKCJpZCIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoImNoYW5nZS5maWxldXBsb2FkIik7CiAgICAgICAgfSwKCiAgICAgICAgX3NldFVybCA6IGZ1bmN0aW9uKHVybCwgaW5kZXgpewogICAgICAgICAgICB0aGlzLiRlbGVtZW50RmlsZUxpc3QuZmluZCgic3Bhbi5ndWlkZS1mdS1maWxlTmFtZSIpLmVxKGluZGV4KS5kYXRhKCJrZXkiLCB1cmwpOwogICAgICAgIH0sCgogICAgICAgIF9nZXRVcmwgOiBmdW5jdGlvbihpbmRleCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy4kZWxlbWVudEZpbGVMaXN0LmZpbmQoInNwYW4uZ3VpZGUtZnUtZmlsZU5hbWUiKS5lcShpbmRleCkuZGF0YSgia2V5Iik7CiAgICAgICAgfSwKICAgICAgICBnZXRTZXRGaWxlUGF0aEFuZFJldHVybk5hbWVQYXRoTWFwOiBmdW5jdGlvbih2YWx1ZUxpc3QpIHsKCiAgICAgICAgICAgIHZhciBtYXBPZk9iamVjdHNIYXZpbmdUZW1wUGF0aEFuZEZpbGVOYW1lcyA9IHt9LAogICAgICAgICAgICAgICAgJHRlbXAsCiAgICAgICAgICAgICAgICB0ZW1wUGF0aDsKCiAgICAgICAgICAgICQuZWFjaCh0aGlzLiRlbGVtZW50RmlsZUxpc3QuY2hpbGRyZW4oKSwgZnVuY3Rpb24gKCBpbmRleCwgY2hpbGRMaUVsZW1lbnQpIHsKICAgICAgICAgICAgICAgICR0ZW1wID0gJChjaGlsZExpRWxlbWVudCkuZmluZCgic3Bhbi5ndWlkZS1mdS1maWxlTmFtZSIpOwogICAgICAgICAgICAgICAgdGVtcFBhdGggPSAkdGVtcC5kYXRhKCJrZXkiKTsKICAgICAgICAgICAgICAgIGlmKCF0ZW1wUGF0aCAmJiB2YWx1ZUxpc3QgJiYgdmFsdWVMaXN0W2luZGV4XSkgewogICAgICAgICAgICAgICAgICAgICR0ZW1wLmRhdGEoImtleSIsIHZhbHVlTGlzdFtpbmRleF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbWFwT2ZPYmplY3RzSGF2aW5nVGVtcFBhdGhBbmRGaWxlTmFtZXNbJHRlbXAuaHRtbCgpXSA9IHRlbXBQYXRoIHx8ICR0ZW1wLmRhdGEoImtleSIpOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgcmV0dXJuIG1hcE9mT2JqZWN0c0hhdmluZ1RlbXBQYXRoQW5kRmlsZU5hbWVzOwogICAgICAgIH0sCgoKICAgICAgICB2YWx1ZSA6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgIGlmKCFfLmlzVW5kZWZpbmVkKHZhbHVlKSkgewogICAgICAgICAgICAgICAgdmFyIF9zZWxmID0gdGhpcywKICAgICAgICAgICAgICAgICAgICBjb21tZW50cyA9IHRoaXMuY29tbWVudCgpLAogICAgICAgICAgICAgICAgICAgIGlzQ2hhbmdlID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZmlsZU5hbWVzID0gXy5pc0FycmF5KHRoaXMub3B0aW9ucy5maWxlTmFtZXMpID8gdGhpcy5vcHRpb25zLmZpbGVOYW1lcyA6IG51bGwsCiAgICAgICAgICAgICAgICAgICAgb2xkVXJscyA9IHt9OwogICAgICAgICAgICAgICAgLy8gQ2FjaGUgdGhlIHVybCBiZWZvcmUgZGVsZXRpb24KICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRGaWxlTGlzdC5jaGlsZHJlbigpLmZpbmQoInNwYW4uZ3VpZGUtZnUtZmlsZU5hbWUiKS5lYWNoKGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICAgICAgdmFyIHVybCA9ICQodGhpcykuZGF0YSgia2V5Iik7CiAgICAgICAgICAgICAgICAgICAgaWYoIV8uaXNVbmRlZmluZWQodXJsKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmaWxlTmFtZSA9IHVybC5zdWJzdHJpbmcodXJsLmxhc3RJbmRleE9mKCIvIikgKyAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgb2xkVXJsc1tmaWxlTmFtZV0gPSB1cmw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB0aGlzLiRlbGVtZW50RmlsZUxpc3QuZW1wdHkoKTsKICAgICAgICAgICAgICAgIGlmKHZhbHVlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgYXJyID0gdmFsdWUuc3BsaXQoIlxuIik7CiAgICAgICAgICAgICAgICAgICAgLy8gY29udHJ1Y3QgaW5pdGlhbCBmaWxlIG5hbWUgYW5kIHZhbHVlIG1hcAogICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgZG9uZSBvbmx5IG9uY2UgaW4gZW50aXJlIGxpdmUgY3ljbGUsIGl0cyBkb25lIGhlcmUsIHNpbmNlIHdlIGdldCB2YWx1ZSBoZXJlCiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVOYW1lcyAmJiBfLmlzRW1wdHkodGhpcy5faW5pdGlhbEZpbGVWYWx1ZUZpbGVOYW1lTWFwKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgZmlsZU5hbWVzLmxlbmd0aDsgaW5kZXgrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NlbGYuX2luaXRpYWxGaWxlVmFsdWVGaWxlTmFtZU1hcFthcnJbaW5kZXhdXSA9IGZpbGVOYW1lc1tpbmRleF0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBVcGRhdGUgdGhlIHZhbHVlIGFycmF5IHdpdGggdGhlIGZpbGUKICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlcyA9IF8ubWFwKGFyciwgZnVuY3Rpb24oZmlsZU5hbWUsIGluZGV4KXsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgZmlsZSBOYW1lIGlzIGEgcGF0aCwgaWYgeWVzIGdldCB0aGUgbGFzdCBwYXJ0IGFmdGVyICIvIgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2xhc2ggPSBmaWxlTmFtZS5sYXN0SW5kZXhPZigiLyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVVybCA9IGZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVVwbG9hZFVybCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHNsYXNoICE9PSAtMSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RvcmUgdGhlIGNhY2hlZCB1cmwgaGVyZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVVybCA9IGZpbGVVcGxvYWRVcmwgPSBmaWxlTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gZmlsZU5hbWUuc3Vic3RyaW5nKHNsYXNoICsgMSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYXNlOiB3aGVuIHlvdSBjbGljayBvbiBzYXZlIHNlY29uZCB0aW1lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZigoXy5pc09iamVjdChfc2VsZi4kZmlsZURvbUVsZW1lbnRzW2luZGV4XSkgJiYgX3NlbGYuJGZpbGVEb21FbGVtZW50c1tpbmRleF0udmFsKCkubGVuZ3RoID4gMCkgfHwgXy5pc1N0cmluZyhfc2VsZi4kZmlsZURvbUVsZW1lbnRzW2luZGV4XSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQ2hhbmdlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2VsZi4kZmlsZURvbUVsZW1lbnRzW2luZGV4XSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYoX3NlbGYuJGZpbGVEb21FbGVtZW50c1tpbmRleF0gIT09IG51bGwpIHsgLy8gY3JlYXRlIGEgZHVtbXkgZmlsZSBkb20gZm9yIHRoZSBjYWNoZWQgdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNDaGFuZ2UgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zZWxmLiRmaWxlRG9tRWxlbWVudHMuc3BsaWNlKGluZGV4LCAwLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvbGRVcmxzW2ZpbGVOYW1lXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVVwbG9hZFVybCA9IG9sZFVybHNbZmlsZU5hbWVdOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIGZpbGVOYW1lcyBvcHRpb25zIGlzIGV4cGxpY2l0bHkgcGFzc2VkLCB1c2UgaXQKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVOYW1lcyAmJiBfc2VsZi5faW5pdGlhbEZpbGVWYWx1ZUZpbGVOYW1lTWFwW2ZpbGVVcmxdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlTmFtZSA9IF9zZWxmLl9pbml0aWFsRmlsZVZhbHVlRmlsZU5hbWVNYXBbZmlsZVVybF07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgX3NlbGYuc2hvd0ZpbGVMaXN0KGZpbGVOYW1lLCBjb21tZW50c1tpbmRleF0sIGZpbGVVcGxvYWRVcmwpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsZVVybDsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICBpZihpc0NoYW5nZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcigiY2hhbmdlLmZpbGV1cGxvYWQiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmKF8uaXNBcnJheSh0aGlzLnZhbHVlcykgJiYgdGhpcy52YWx1ZXMubGVuZ3RoICE9PSAwKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXN0cm95KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVzOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgZmlsZUF0dGFjaG1lbnQ6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlczsKICAgICAgICB9LAoKICAgICAgICBjb21tZW50IDogZnVuY3Rpb24odmFsdWUpewogICAgICAgICAgICB2YXIgX3NlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgJGVsZW0gPSBudWxsLAogICAgICAgICAgICAgICAgY29tbWVudHM7CiAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZCh2YWx1ZSkpIHsKICAgICAgICAgICAgICAgIGlmKHZhbHVlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBjb21tZW50cyA9IHZhbHVlLnNwbGl0KCJcbiIpOwogICAgICAgICAgICAgICAgICAgICRlbGVtID0gdGhpcy4kZWxlbWVudEZpbGVMaXN0LmZpbmQoJ2Rpdi5ndWlkZS1mdS1jb21tZW50Jyk7CiAgICAgICAgICAgICAgICAgICAgJGVsZW0uZWFjaChmdW5jdGlvbihpbmRleCl7CiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcykudGV4dChjb21tZW50c1tpbmRleF0pOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJGVsZW0gPSB0aGlzLiRlbGVtZW50RmlsZUxpc3QuZmluZCgnZGl2Lmd1aWRlLWZ1LWNvbW1lbnQnKTsKICAgICAgICAgICAgICAgIGNvbW1lbnRzID0gW107CiAgICAgICAgICAgICAgICAkZWxlbS5lYWNoKGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICAgICAgY29tbWVudHMucHVzaCgkKHRoaXMpLnRleHQoKSk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHJldHVybiBjb21tZW50czsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIG11bHRpU2VsZWN0IDogZnVuY3Rpb24odmFsdWUpewogICAgICAgICAgICBpZih2YWx1ZSAhPT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLm11bHRpU2VsZWN0ID0gdmFsdWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMubXVsdGlTZWxlY3Q7CiAgICAgICAgfSwKCiAgICAgICAgZmlsZVNpemVMaW1pdCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgaWYodmFsdWUgIT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5maWxlU2l6ZUxpbWl0ID0gdmFsdWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZmlsZVNpemVMaW1pdDsKICAgICAgICB9LAoKICAgICAgICBtaW1lVHlwZSA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgaWYodmFsdWUgIT09IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5taW1lVHlwZSA9IHZhbHVlOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLm1pbWVUeXBlOwogICAgICAgIH0sCgogICAgICAgIGFjY2VzcyA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgaWYodmFsdWUgPT0gInJlYWRPbmx5IikgewogICAgICAgICAgICAgICAgdGhpcy4kZWxlbWVudC5hdHRyKCJkaXNhYmxlZCIsICJkaXNhYmxlZCIpOwogICAgICAgICAgICAgICAgLy9mb3IgcmVhZE9ubHkgaGlkZSB0aGUgZGVsZXRlIGljb24gaW4gZmlsZSBsaXN0CiAgICAgICAgICAgICAgICAkKHRoaXMuJHBhcmVudCkuYWRkQ2xhc3MoJ2d1aWRlLWZ1LWRpc2FibGVkJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZih2YWx1ZSA9PSAib3BlbiIpIHsKICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnQucmVtb3ZlQXR0cigiZGlzYWJsZWQiKTsKICAgICAgICAgICAgICAgICQodGhpcy4kcGFyZW50KS5yZW1vdmVDbGFzcygnZ3VpZGUtZnUtZGlzYWJsZWQnKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGZpbGVMaXN0IDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgdmFyIGZpbHRlcmVkLAogICAgICAgICAgICAgICAgX3NlbGYgPSB0aGlzOwogICAgICAgICAgICBpZih2YWx1ZSAhPT0gdW5kZWZpbmVkKXsKICAgICAgICAgICAgICAgIHRoaXMuJGZpbGVEb21FbGVtZW50cyA9IFtdOwogICAgICAgICAgICAgICAgXy5lYWNoKHZhbHVlLCBmdW5jdGlvbihpdGVtLCBpbmRleCl7CiAgICAgICAgICAgICAgICAgICAgaWYoKF8uaXNPYmplY3QoaXRlbSkgJiYgKGlzQnJvd3NlcklFOU9ySUUxMCB8fCBpdGVtLnZhbCgpLmxlbmd0aCA+IDApKSB8fCAoXy5pc1N0cmluZyhpdGVtKSkpewogICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgaW5kZXggaXMgd2l0aGluIHRoZSBsZW5ndGgKICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgd3JpdHRlbiBmb3IgZGVsZXRlIGNhc2UKICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIGl0ZW0gaXMgYSBzdHJpbmcsIHRoZW4gaXQgc2hvdWxkIGJlIHNldCBudWxsCiAgICAgICAgICAgICAgICAgICAgICAgICBpZihfLmlzU3RyaW5nKGl0ZW0pKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgIF9zZWxmLiRmaWxlRG9tRWxlbWVudHNbaW5kZXhdID0gaXRlbTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGZpbHRlcmVkID0gdGhpcy4kZmlsZURvbUVsZW1lbnRzOwogICAgICAgICAgICAgICAgLy8gSW4gY2FzZSBvZiBJRTksIGdldCB0aGUgbGFzdCBlbGVtZW50IG9mIGZpbGVEb20gYW5kIHVwZGF0ZSB0aGUgaWQgZm9yIGxhYmVsCiAgICAgICAgICAgICAgICBpZihpc0Jyb3dzZXJJRTlPcklFMTAgJiYgdmFsdWUgIT09IG51bGwpewogICAgICAgICAgICAgICAgICAgIC8vIENhc2U6IGlmIGl0IGlzIHNpbmdsZSBzZWxlY3QsIGFuZCB0aGVuIHdlIGRvIGEgcmVzdG9yZSBhbmQgdGhlbiBhZnRlciBhdHRhY2hpbmcgYW5vdGhlciBmaWxlIHdlIGNsaWNrIHNhdmUKICAgICAgICAgICAgICAgICAgICBpZihfLmxhc3QodGhpcy4kZmlsZURvbUVsZW1lbnRzKSA9PSBudWxsKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbG9uZUZpbGVJbnB1dEFuZFVwZGF0ZUlkRm9ySUU5KCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVMYWJlbEZvckF0dHIoXy5sYXN0KHRoaXMuJGZpbGVEb21FbGVtZW50cykuYXR0cigiaWQiKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgLy8gaGVyZSBmaWx0ZXJlZCBpcyBhIG5ldyBhcnJheQogICAgICAgICAgICAgICAgLy8gQSBuZXcgYXJyYXkgaXMgcmV0dXJuZWQgb3ZlciBoZXJlIHNvIHRoYXQgdGhlIHVzZXIgb2YgdGhpcyBBUEkgZG9lc24ndCB0cnkgdG8gY2hhbmdlIHRoZSB3aWRnZXQgYXJyYXkgZGlyZWN0bHkKICAgICAgICAgICAgICAgIGZpbHRlcmVkID0gJC5tYXAodGhpcy4kZmlsZURvbUVsZW1lbnRzLCBmdW5jdGlvbihpdGVtLCBpbmRleCl7CiAgICAgICAgICAgICAgICAgICAgaWYoIWl0ZW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9zZWxmLl9nZXRVcmwoaW5kZXgpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZigoaXRlbVswXS5maWxlcyAmJiBpdGVtWzBdLmZpbGVzLmxlbmd0aCAhPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IChfc2VsZi5vcHRpb25zLm11bHRpU2VsZWN0IHx8IGl0ZW1bMF0udmFsdWUubGVuZ3RoID4gMCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZpbHRlcmVkOwogICAgICAgIH0sCgogICAgICAgIC8vIGZpbGUgcHJldmlldyBodG1sCiAgICAgICAgZmlsZUl0ZW1QcmV2aWV3OiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gJCgiPHNwYW4+PC9zcGFuPiIpLmFkZENsYXNzKCJndWlkZS1mdS1maWxlUHJldmlldyBnbHlwaGljb24gZ2x5cGhpY29uLW9rIik7CiAgICAgICAgfSwKCiAgICAgICAgLy8gZm9yY2UgZmxhZyBpbmRpY2F0ZXMgdGhhdCBmb3JjZWZ1bGx5IHNldCB0aGUgZG9tIGJ1dCBkb24ndCB1cGRhdGUgdGhlIG9wdGlvbnMKICAgICAgICBidXR0b25UZXh0OiBmdW5jdGlvbiAodmFsdWUsIGZvcmNlKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICBpZighZm9yY2UpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLmJ1dHRvblRleHQgPSB2YWx1ZTsKICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRGaWxlVXBsb2FkQnRuLmZpbmQoJ3NwYW4uZ3VpZGUtZnUtbGFiZWwnKS5odG1sKHZhbHVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuYnV0dG9uVGV4dDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8vIFRvIGNoYW5nZSB0aGUgaWNvbiBvZiB0aGUgYnV0dG9uLCB0aGUgdXNlciBzaG91bGQgY3VzdG9taXplIHRoZSBjbGFzcwogICAgICAgIGJ0bkljb246IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICQoIjxzcGFuPjwvc3Bhbj4iKS5hZGRDbGFzcygiZ3VpZGUtZnUtaWNvbiBnbHlwaGljb24gZ2x5cGhpY29uLWZvbGRlci1vcGVuIik7CiAgICAgICAgfSwKCiAgICAgICAgYnRuTGFiZWw6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiAkKCI8c3Bhbj48L3NwYW4+IikuYWRkQ2xhc3MoImd1aWRlLWZ1LWxhYmVsIikuaHRtbCh0aGlzLm9wdGlvbnMuYnV0dG9uVGV4dCk7CiAgICAgICAgfSwKCiAgICAgICAgZmlsZUl0ZW1MaXN0OiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy4kcGFyZW50LmZpbmQodGhpcy5vcHRpb25zLmZpbGVJdGVtTGlzdENsYXNzKTsKICAgICAgICB9LAoKICAgICAgICBnZXROZXdDb21tZW50RWxlbWVudFN1bW1hcnkgOiBmdW5jdGlvbih0ZXh0KXsKICAgICAgICAgICAgcmV0dXJuICQoIjxkaXYgdGl0bGU9J0NsaWNrIHRvIGVkaXQnIHRhYmluZGV4PScwJz48L3A+IikuYWRkQ2xhc3MoImd1aWRlLWZ1LWNvbW1lbnQiKS50ZXh0KHRleHQgfHwgX2RlZmF1bHRzLnBsYWNlSG9sZGVyVGV4dCk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0TmV3Q29tbWVudEVsZW1lbnQgOiBmdW5jdGlvbih0ZXh0KXsKICAgICAgICAgICAgcmV0dXJuICQoIjxkaXYgY29udGVudGVkaXRhYmxlPSd0cnVlJyB0YWJpbmRleD0nMCc+PC9kaXY+IikuYWRkQ2xhc3MoImd1aWRlLWZ1LWNvbW1lbnQiKS50ZXh0KHRleHQgfHwgIiIpOwogICAgICAgIH0sCgogICAgICAgIGZpbGVJdGVtOiBmdW5jdGlvbihmaWxlTmFtZSwgY29tbWVudCwgZmlsZVVybCl7CiAgICAgICAgICAgIHZhciAkZmlsZUl0ZW0gPSAkKCI8bGk+PC9saT4iKS5hZGRDbGFzcygiZ3VpZGUtZnUtZmlsZUl0ZW0iKTsKICAgICAgICAgICAgdmFyIG5hbWVXaXRob3V0TWFya2VyID0geGZhbGliLnV0LlV0aWxpdGllcy5fZ2V0TmFtZVdpdGhvdXRNYXJrZXIoZmlsZU5hbWUpOwogICAgICAgICAgICB2YXIgJGVsZW0gPSAkKCI8c3BhbiB0YWJpbmRleD0nMCc+PC9zcGFuPiIpLmFkZENsYXNzKCJndWlkZS1mdS1maWxlTmFtZSIpLmF0dHIoImFyaWEtbGFiZWwiLCBuYW1lV2l0aG91dE1hcmtlcikudGV4dChuYW1lV2l0aG91dE1hcmtlcikuYXBwZW5kVG8oJGZpbGVJdGVtKS5rZXlwcmVzcyhmdW5jdGlvbihlKSB7CiAgICAgICAgICAgICAgICBpZiAoZS5rZXlDb2RlID09PSAxMyB8fCBlLmNoYXJDb2RlID09PSAzMikgewogICAgICAgICAgICAgICAgICAgICQoZS50YXJnZXQpLmNsaWNrKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pLmNsaWNrKCQucHJveHkodGhpcy5oYW5kbGVGaWxlUHJldmlldywgdGhpcykpOwogICAgICAgICAgICBpZih0aGlzLm9wdGlvbnMuZGlzYWJsZVByZXZpZXcpIHsKICAgICAgICAgICAgICAgJGVsZW0uYWRkQ2xhc3MoJ25vbi1wcmV2aWV3LWZpbGVOYW1lJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoZmlsZVVybCAhPSBudWxsKXsKICAgICAgICAgICAgICAgICRlbGVtLmF0dHIoImRhdGEta2V5IiwgZmlsZVVybCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJCgiPHNwYW4gdGFiaW5kZXg9JzAnPjwvc3Bhbj4iKS5hZGRDbGFzcygiZ3VpZGUtZnUtZmlsZUNsb3NlIGNsb3NlIikuYXR0cigicm9sZSIsICJidXR0b24iKS5hdHRyKCJhcmlhLWxhYmVsIiwgeGZhbGliLmxvY2FsZS5TdHJpbmdzLkZpbGVDbG9zZUFjY2Vzc1RleHQgKyBuYW1lV2l0aG91dE1hcmtlcikudGV4dCgieCIpLmFwcGVuZFRvKCRmaWxlSXRlbSkua2V5cHJlc3MoZnVuY3Rpb24oZSkgewogICAgICAgICAgICAgICAgaWYgKGUua2V5Q29kZSA9PT0gMTMgfHwgZS5jaGFyQ29kZSA9PT0gMzIpIHsKICAgICAgICAgICAgICAgICAgICAkKGUudGFyZ2V0KS5jbGljaygpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KQogICAgICAgICAgICAgICAgLmNsaWNrKCQucHJveHkodGhpcy5oYW5kbGVDbGljaywgdGhpcykpOwoKICAgICAgICAgICAgdGhpcy5maWxlSXRlbVByZXZpZXcoKS5hcHBlbmRUbygkZmlsZUl0ZW0pOwoKICAgICAgICAgICAgaWYodGhpcy5vcHRpb25zLnNob3dDb21tZW50KXsKICAgICAgICAgICAgICAgIHRoaXMuZ2V0TmV3Q29tbWVudEVsZW1lbnRTdW1tYXJ5KGNvbW1lbnQpLmFwcGVuZFRvKCRmaWxlSXRlbSkuZm9jdXMoJC5wcm94eSh0aGlzLmhhbmRsZUNvbW1lbnRDbGljaywgdGhpcykpLmNsaWNrKCQucHJveHkodGhpcy5oYW5kbGVDb21tZW50Q2xpY2ssIHRoaXMpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gJGZpbGVJdGVtOwogICAgICAgIH0sCgogICAgICAgIHRvZ2dsZUZpbGVVcGxvYWRCdG46IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMub3B0aW9ucy5tdWx0aVNlbGVjdCkgewogICAgICAgICAgICAgICAgLy8gQ2hhbmdlIHRoZSBsb29rIG9mIGZpbGUgdXBsb2FkIGJ1dHRvbgogICAgICAgICAgICAgICAgaWYodGhpcy4kZWxlbWVudEZpbGVMaXN0LmNoaWxkcmVuKCkubGVuZ3RoID4gMCl7CiAgICAgICAgICAgICAgICAgICAgLy8gQ2hhbmdlIHRoZSB0ZXh0CiAgICAgICAgICAgICAgICAgICAgdGhpcy5idXR0b25UZXh0KHRoaXMuX2FkZEZpbGUsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIC8vIENoYW5nZSB0aGUgaWNvbiB0b28KICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbGVtZW50RmlsZVVwbG9hZEJ0bi5maW5kKCdzcGFuLmd1aWRlLWZ1LWljb24nKS5yZW1vdmVDbGFzcygiZ2x5cGhpY29uLWZvbGRlci1vcGVuIikuYWRkQ2xhc3MoImdseXBoaWNvbi1wbHVzIik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoaXMuYnV0dG9uVGV4dCh0aGlzLm9wdGlvbnMuYnV0dG9uVGV4dCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZWxlbWVudEZpbGVVcGxvYWRCdG4uZmluZCgnc3Bhbi5ndWlkZS1mdS1pY29uJykucmVtb3ZlQ2xhc3MoImdseXBoaWNvbi1wbHVzIikuYWRkQ2xhc3MoImdseXBoaWNvbi1mb2xkZXItb3BlbiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc2hvd0ludmFsaWRNZXNzYWdlOiBmdW5jdGlvbihmaWxlTmFtZSwgaW52YWxpZEZlYXR1cmUpewogICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgIHZhciBJU19JUEFEID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBhZC9pKSAhPT0gbnVsbCwKICAgICAgICAgICAgICAgIElTX0lQSE9ORSA9IChuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmUvaSkgIT09IG51bGwpOwogICAgICAgICAgICBpZihJU19JUEFEIHx8IElTX0lQSE9ORSl7CiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICB0aGF0LmludmFsaWRNZXNzYWdlKHRoYXQsZmlsZU5hbWUsIGludmFsaWRGZWF0dXJlKTsKICAgICAgICAgICAgICAgIH0sIDApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICB0aGlzLmludmFsaWRNZXNzYWdlKHRoaXMsZmlsZU5hbWUsIGludmFsaWRGZWF0dXJlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGludmFsaWRNZXNzYWdlOiBmdW5jdGlvbihyZWZPYmosZmlsZU5hbWUsIGludmFsaWRGZWF0dXJlKXsKICAgICAgICAgICAgaWYoaW52YWxpZEZlYXR1cmUgPT09IHJlZk9iai5pbnZhbGlkRmVhdHVyZS5TSVpFKSB7CiAgICAgICAgICAgICAgICBhbGVydCh4ZmFsaWIudXQuTG9jYWxpemF0aW9uVXRpbC5wcm90b3R5cGUuZ2V0TG9jYWxpemVkTWVzc2FnZSgiIiwgeGZhbGliLmxvY2FsZS5TdHJpbmdzWyJGaWxlU2l6ZUdyZWF0ZXIiXSwgW2ZpbGVOYW1lLCByZWZPYmoub3B0aW9ucy5maWxlU2l6ZUxpbWl0XSkpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGludmFsaWRGZWF0dXJlID09PSByZWZPYmouaW52YWxpZEZlYXR1cmUuTkFNRSkgewogICAgICAgICAgICAgICAgYWxlcnQoeGZhbGliLnV0LkxvY2FsaXphdGlvblV0aWwucHJvdG90eXBlLmdldExvY2FsaXplZE1lc3NhZ2UoIiIsIHhmYWxpYi5sb2NhbGUuU3RyaW5nc1siRmlsZU5hbWVJbnZhbGlkIl0sIFtmaWxlTmFtZV0pKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChpbnZhbGlkRmVhdHVyZSA9PT0gcmVmT2JqLmludmFsaWRGZWF0dXJlLk1JTUVUWVBFKSB7CiAgICAgICAgICAgICAgICBhbGVydCh4ZmFsaWIudXQuTG9jYWxpemF0aW9uVXRpbC5wcm90b3R5cGUuZ2V0TG9jYWxpemVkTWVzc2FnZSgiIiwgeGZhbGliLmxvY2FsZS5TdHJpbmdzWyJGaWxlTWltZVR5cGVJbnZhbGlkIl0sIFtmaWxlTmFtZV0pKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKioKICAgICAgICAgKiBGaW5kcyB0aGUgdmFsdWUgaW4gdGhlIGFycmF5LCBpZiB0aGUgdmFsdWUgaXMgYSB1cmwgdGhlbiBpdCB1c2VzIHRoZSBmaWxlbmFtZSBpbiB0aGUgdXJsIHRvIHNlYXJjaCBmb3IgdGhlIHRleHQKICAgICAgICAgKiBUaGlzIGlzIGRvbmUgc2luY2Ugb3VyIG1vZGVsIHN0b3JlcyB0aGUgVVJMIHRvbyBpbiBjYXNlIG9mIGRyYWZ0IHJlc3RvcmUgb3IgY2xpY2tpbmcgb24gc2F2ZSBpbiBndWlkZQogICAgICAgICAqIEBwYXJhbSB0ZXh0ICAgICAgICAgIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHRleHQgb2Ygd2hpY2ggdGhlIGluZGV4IGlzIHRvIGJlIGZvdW5kCiAgICAgICAgICogQHBhcmFtICRlbGVtICAgICAgICAgcmVmZXJlbmNlIHRvIHRoZSBqcXVlcnkgZWxlbWVudC4gVGhpcyBpcyB1c2VkIGlmIHRoZXJlIGFyZSBkdXBsaWNhdGUgZmlsZSBuYW1lcyBwcmVzZW50IGluIHRoZSBmaWxlIHVwbG9hZC4KICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfQogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2dldEluZGV4T2ZUZXh0IDogZnVuY3Rpb24odGV4dCwgJGVsZW0pewogICAgICAgICAgICB2YXIgaW5kZXggPSAtMSwKICAgICAgICAgICAgICAgIHNlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgaXNEdXBsaWNhdGVQcmVzZW50ID0gZmFsc2U7CiAgICAgICAgICAgIF8uZmluZCh0aGlzLnZhbHVlcywgZnVuY3Rpb24odmFsdWUsIGl0ZXIpewogICAgICAgICAgICAgICAgLy8gaWYgdmFsdWUgaXMgYSB1cmwsIHRoZW4gY29tcGFyZSB3aXRoIGxhc3QKICAgICAgICAgICAgICAgIHZhciB0ZW1wVmFsdWUgPSB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAvLyBjYW4ndCB1c2UgZ2V0T3JFbHNlIGhlcmUgc2luY2UgdmFsdWUgY2FuIGhhdmUgIi4iIGluIFVSTCBhbmQgZ2V0T3JFbHNlIHNwbGl0cyBiYXNlZCBvbiBwZXJpb2QgdG8gZmluZCBrZXkgaW5zaWRlIG9iamVjdAogICAgICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gIChfLmlzT2JqZWN0KHNlbGYuX2luaXRpYWxGaWxlVmFsdWVGaWxlTmFtZU1hcCkgJiYgdHlwZW9mIHNlbGYuX2luaXRpYWxGaWxlVmFsdWVGaWxlTmFtZU1hcFt2YWx1ZV0gIT09IHVuZGVmaW5lZCkgPyBzZWxmLl9pbml0aWFsRmlsZVZhbHVlRmlsZU5hbWVNYXBbdmFsdWVdIDogbnVsbDsKICAgICAgICAgICAgICAgIGlmKHRlbXBWYWx1ZS5tYXRjaCgvXC8vZykgJiYgdGVtcFZhbHVlLm1hdGNoKC9cLy9nKS5sZW5ndGggPiAxKXsKICAgICAgICAgICAgICAgICAgICB0ZW1wVmFsdWUgPSAgdmFsdWUuc3Vic3RyaW5nKHZhbHVlLmxhc3RJbmRleE9mKCIvIikrMSk7CiAgICAgICAgICAgICAgICAgICAgdGVtcFZhbHVlID0geGZhbGliLnV0LlV0aWxpdGllcy5fZ2V0TmFtZVdpdGhvdXRNYXJrZXIodGVtcFZhbHVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIHdlIHBhc3MgZmlsZSBuYW1lIGV4cGxpY2l0eWx5IGFzIG9wdGlvbnMsIGlmIHBhc3NlZCB1c2UgdGhhdCBhcyBmYWxsYmFjayB0byBmaW5kIHRoZSBVUkwKICAgICAgICAgICAgICAgIGlmKHRlbXBWYWx1ZSA9PT0gdGV4dCB8fCBmaWxlTmFtZSA9PT0gdGV4dCl7CiAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBpdGVyOwogICAgICAgICAgICAgICAgICAgIGlzRHVwbGljYXRlUHJlc2VudCA9IHNlbGYudmFsdWVzLmluZGV4T2YodmFsdWUsIGluZGV4ICsgMSkgIT09IC0xOwogICAgICAgICAgICAgICAgICAgIGlmKCRlbGVtICYmIGlzRHVwbGljYXRlUHJlc2VudCl7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdyBjaGVjayBpZiBkdXBsaWNhdGUgcHJlc2VudCBhbmQgZ2V0IGl0cyBjb3JyZWN0IGluZGV4CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRvZGF5IGFsbCBmaWxlcyBhcmUgd3JhcHBlZCB1bmRlciAuZ3VpZGUtZnUtZmlsZUl0ZW0gbm9kZQogICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9ICRlbGVtLmNsb3Nlc3QoIi5ndWlkZS1mdS1maWxlSXRlbSIpLmluZGV4KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIHRoZXJlIGlzIGEgZHVwbGljYXRlCiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBpcyB0byBqdXN0IGJyZWFrIHRoZSBsb29wCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgcmV0dXJuIGluZGV4OwogICAgICAgIH0sCgoKICAgICAgICAvKgogICAgICAgICAqIFNpbmNlIGlucHV0IGZpbGUgZWxlbWVudCBtaWdodCBjb250YWluIG11bHRpcGxlIGZpbGVzLgogICAgICAgICAqIFRoaXMgZnVuY3Rpb24gdGFrZXMgYWJzb2x1dGUgZmlsZSBpbmRleCBhcyBwYXJhbWV0ZXIgJiByZXR1cm5zIHBvc2l0aW9uIG9mIHRoZSBmaWxlIHcuci50IGlucHV0IGZpbGUgZWx0CiAgICAgICAgICovCiAgICAgICAgX2dldEZpbGVPYmpJZHggOiBmdW5jdGlvbiAoaW5kZXgpIHsKICAgICAgICAgICAgaWYgKGluZGV4ID49IDApIHsKICAgICAgICAgICAgICAgIHZhciBjdXJyZW50SWR4ID0gMDsKICAgICAgICAgICAgICAgIGZvciAodmFyIGZpbGVJbnB1dEVsdElkeCA9IDA7IGZpbGVJbnB1dEVsdElkeCA8IHRoaXMuJGZpbGVEb21FbGVtZW50cy5sZW5ndGg7IGZpbGVJbnB1dEVsdElkeCsrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuJGZpbGVEb21FbGVtZW50c1tmaWxlSW5wdXRFbHRJZHhdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmaWxlcyA9IHRoaXMuJGZpbGVEb21FbGVtZW50c1tmaWxlSW5wdXRFbHRJZHhdWzBdLmZpbGVzOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsZXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmaWxlc0xlbmd0aCA9ICBmaWxlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIGluZGV4IDw9IGN1cnJlbnRJZHggKyBmaWxlc0xlbmd0aCAtIDEgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtmaWxlSW5wdXRFbHRJZHgsIGluZGV4IC0gY3VycmVudElkeF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50SWR4Kz1maWxlcy5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT0gY3VycmVudElkeCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtmaWxlSW5wdXRFbHRJZHgsMF07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudElkeCsrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBGaWxlTGlzdCBvYmplY3Qgb2YgdGhlIHBhc3NlZCBmaWxlIGFycmF5CiAgICAgICAgICovCiAgICAgICAgX2dldEZpbGVMaXN0SXRlbSA6IGZ1bmN0aW9uIChmaWxlcykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdmFyIGRhdGFDb250YWluZXIgPSBuZXcgRGF0YVRyYW5zZmVyKCkgfHwgKG5ldyBDbGlwYm9hcmRFdmVudCgiIikpLmNsaXBib2FyZERhdGE7CiAgICAgICAgICAgICAgICBfLmVhY2goZmlsZXMsIGZ1bmN0aW9uIChmaWxlKSB7CiAgICAgICAgICAgICAgICAgICAgZGF0YUNvbnRhaW5lci5pdGVtcy5hZGQoZmlsZSk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHJldHVybiBkYXRhQ29udGFpbmVyLmZpbGVzOwogICAgICAgICAgICB9IGNhdGNoKGVycikgewogICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpOwogICAgICAgICAgICAgICAgdGhyb3cgZXJyOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX3VwZGF0ZUZpbGVzSW5Eb20gOiBmdW5jdGlvbigkZmlsZURvbSwgZmlsZXMpIHsKICAgICAgICAgICAgLy8gaW4gc2FmYXJpLCBhIGNoYW5nZSBldmVudCBpcyB0cmlnZ2VkIGlmIGZpbGVzIHByb3BlcnR5IGlzIGNoYW5nZWQgZHluYW1pY2FsbHkKICAgICAgICAgICAgLy8gaGVuY2UgYWRkaW5nIHRoaXMgY2hlY2sgdG8gY2xlYXIgZXhpc3Rpbmcgc3RhdGUgb25seSBmb3Igc2FmYXJpIGJyb3dzZXJzCiAgICAgICAgICAgIHRoaXMuX2lzRmlsZVVwZGF0ZSA9IHRydWU7CiAgICAgICAgICAgICRmaWxlRG9tWzBdLmZpbGVzID0gdGhpcy5fZ2V0RmlsZUxpc3RJdGVtKGZpbGVzKTsKICAgICAgICAgICAgdGhpcy5faXNGaWxlVXBkYXRlID0gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBUaGlzIGZ1bmN0aW9uIGRlbGV0ZXMgZmlsZXMgYXQgc3BlY2lmaWVkIGluZGV4ZXMgZnJvbSBpbnB1dCBkb20gZWx0CiAgICAgICAgICovCiAgICAgICAgX2RlbGV0ZUZpbGVzRnJvbUlucHV0RG9tIDogZnVuY3Rpb24gKCRmaWxlRG9tRWx0LCBkZWxldGVkSW5kZXhlcykgewogICAgICAgICAgICB2YXIgcmVtYWluaW5nRmlsZXMgPSBbXTsKICAgICAgICAgICAgXy5lYWNoKCRmaWxlRG9tRWx0WzBdLmZpbGVzLCBmdW5jdGlvbihmaWxlLGlkeCl7CiAgICAgICAgICAgICAgICBpZighZGVsZXRlZEluZGV4ZXMuaW5jbHVkZXMoaWR4KSl7CiAgICAgICAgICAgICAgICAgICAgcmVtYWluaW5nRmlsZXMucHVzaChmaWxlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAvLyBpbiBzYWZhcmksIGEgY2hhbmdlIGV2ZW50IGlzIHRyaWdnZWQgaWYgZmlsZXMgcHJvcGVydHkgaXMgY2hhbmdlZCBkeW5hbWljYWxseQogICAgICAgICAgICAgICAgLy8gaGVuY2UgYWRkaW5nIHRoaXMgY2hlY2sgdG8gY2xlYXIgZXhpc3Rpbmcgc3RhdGUgb25seSBmb3Igc2FmYXJpIGJyb3dzZXJzCiAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVGaWxlc0luRG9tKCRmaWxlRG9tRWx0LCByZW1haW5pbmdGaWxlcyk7CiAgICAgICAgICAgIH0gY2F0Y2goZXJyKXsKICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoIkRlbGV0aW5nIGZpbGVzIGlzIG5vdCBzdXBwb3J0ZWQgaW4geW91ciBicm93c2VyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBUaGlzIGV2ZW50IGxpc3RlbmVyIGdldHMgY2FsbGVkIG9uIGNsaWNrIG9mIGNsb3NlIGJ1dHRvbiBpbiBmaWxlIHVwbG9hZAogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIGV2ZW50CiAgICAgICAgICovCiAgICAgICAgaGFuZGxlQ2xpY2s6IGZ1bmN0aW9uKGV2ZW50KXsKCiAgICAgICAgICAgIHZhciAkZWxlbSA9ICQoZXZlbnQudGFyZ2V0KSwKICAgICAgICAgICAgICAgIHRleHQgPSAkZWxlbS5wcmV2KCkudGV4dCgpLAogICAgICAgICAgICAgICAgaW5kZXggPSB0aGlzLl9nZXRJbmRleE9mVGV4dCh0ZXh0LCAkZWxlbSksCiAgICAgICAgICAgICAgICB1cmwgPSAkZWxlbS5wcmV2KCkuZGF0YSgia2V5IiksCiAgICAgICAgICAgICAgICBvYmplY3RVcmwgPSAkZWxlbS5wcmV2KCkuZGF0YSgib2JqZWN0VXJsIik7CiAgICAgICAgICAgIGlmIChpbmRleCAhPSAtMSkgewogICAgICAgICAgICAgICAgdGhpcy52YWx1ZXMuc3BsaWNlKGluZGV4LCAxKTsKICAgICAgICAgICAgICAgIHZhciBmaWxlT2JqSWR4ID0gdGhpcy5fZ2V0RmlsZU9iaklkeChpbmRleCk7CiAgICAgICAgICAgICAgICB2YXIgJGZpbGVEb21FbHQgPSB0aGlzLiRmaWxlRG9tRWxlbWVudHNbZmlsZU9iaklkeFswXV07CiAgICAgICAgICAgICAgICBpZiAoISRmaWxlRG9tRWx0IHx8ICRmaWxlRG9tRWx0WzBdLmZpbGVzLmxlbmd0aCA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGZpbGVEb21FbGVtZW50cy5zcGxpY2UoZmlsZU9iaklkeFswXSwgMSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX2RlbGV0ZUZpbGVzRnJvbUlucHV0RG9tKCRmaWxlRG9tRWx0LCBbZmlsZU9iaklkeFsxXV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGlzQnJvd3NlcklFOU9ySUUxMCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuY2xvbmVGaWxlSW5wdXRBbmRVcGRhdGVJZEZvcklFOSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHVybCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBkYXRhIHNvIHRoYXQgb3RoZXJzIGRvbid0IHVzZSB0aGlzIHVybAogICAgICAgICAgICAgICAgICAgICRlbGVtLnByZXYoKS5yZW1vdmVEYXRhKCJrZXkiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKG9iamVjdFVybCkgewogICAgICAgICAgICAgICAgICAgIC8vIHJldm9rZSB0aGUgb2JqZWN0IFVSTCB0byBhdm9pZCBtZW1vcnkgbGVha3MgaW4gYnJvd3NlcgogICAgICAgICAgICAgICAgICAgIC8vIHNpbmNlIGZpbGUgaXMgYW55d2F5cyBnZXR0aW5nIGRlbGV0ZWQsIHJlbW92ZSB0aGUgb2JqZWN0IFVSTCdzIHRvbwogICAgICAgICAgICAgICAgICAgIHdpbmRvdy5VUkwucmV2b2tlT2JqZWN0VVJMKG9iamVjdFVybCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBkb20gZnJvbSB2aWV3CiAgICAgICAgICAgIC8vQWxsIGJvdW5kIGV2ZW50cyBhbmQgalF1ZXJ5IGRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSBlbGVtZW50IGFyZSBhbHNvIHJlbW92ZWQKICAgICAgICAgICAgJGVsZW0ucGFyZW50KCkucmVtb3ZlKCk7CiAgICAgICAgICAgIC8vIHRyaWdnZXIgdGhlIGNoYW5nZSBldmVudCB0byB1cGRhdGUgdGhlIHZhbHVlCiAgICAgICAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcigiY2hhbmdlLmZpbGV1cGxvYWQiKTsKICAgICAgICAgICAgLy8gU2V0IHRoZSBmb2N1cyBvbiBmaWxlIHVwbG9hZCBidXR0b24gYWZ0ZXIgY2xpY2sgb2YgY2xvc2UKICAgICAgICAgICAgdGhpcy4kZWxlbWVudEZpbGVVcGxvYWRCdG4uZm9jdXMoKTsKCiAgICAgICAgfSwKCgogICAgICAgIGRpc3BsYXlTVkc6IGZ1bmN0aW9uIChvYmplY3RVcmwpIHsKICAgICAgICAgICAgY29uc3QgdXJsID0gb2JqZWN0VXJsOwogICAgICAgICAgICBjb25zdCBpbWcgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW1nJyk7CiAgICAgICAgICAgIGltZy5zcmMgPSB1cmw7CiAgICAgICAgICAgIGNvbnN0IG5ld1RhYiA9IHdpbmRvdy5vcGVuKCcnLCAnX2JsYW5rJywgJ3Njcm9sbGJhcnM9bm8sbWVudWJhcj1ubyxoZWlnaHQ9NjAwLHdpZHRoPTgwMCxyZXNpemFibGU9eWVzLHRvb2xiYXI9bm8sc3RhdHVzPW5vJyk7CiAgICAgICAgICAgIG5ld1RhYi5kb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGltZyk7CiAgICAgICAgfSwKCgogICAgICAgIF9wcmV2aWV3RmlsZVVzaW5nT2JqZWN0VXJsIDogZnVuY3Rpb24gKGZpbGUpIHsKICAgICAgICAgICAgaWYgKGZpbGUpIHsKICAgICAgICAgICAgICAgIGlmICh3aW5kb3cubmF2aWdhdG9yICYmIHdpbmRvdy5uYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYikgeyAvLyBmb3IgSUUKICAgICAgICAgICAgICAgICAgICB3aW5kb3cubmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IoZmlsZSwgZmlsZS5uYW1lKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKGZpbGUpOwogICAgICAgICAgICAgICAgICAgIGlmIChmaWxlLnR5cGUgPT09ICdpbWFnZS9zdmcreG1sJykgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc3BsYXlTVkcodXJsKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cub3Blbih1cmwsICcnLCAnc2Nyb2xsYmFycz1ubyxtZW51YmFyPW5vLGhlaWdodD02MDAsd2lkdGg9ODAwLHJlc2l6YWJsZT15ZXMsdG9vbGJhcj1ubyxzdGF0dXM9bm8nKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVybDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8vIHRoaXMgZnVuY3Rpb24gbWFpbnRhaW5zIGEgbWFwIGZvcgogICAgICAgIGhhbmRsZUZpbGVQcmV2aWV3OiBmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgIGlmKCF0aGlzLm9wdGlvbnMuZGlzYWJsZVByZXZpZXcpIHsKICAgICAgICAgICAgICAgIHZhciAkZWxlbSA9ICQoZXZlbnQudGFyZ2V0KSwKICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gJGVsZW0udGV4dCgpLAogICAgICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5fZ2V0SW5kZXhPZlRleHQodGV4dCwgJGVsZW0pLAogICAgICAgICAgICAgICAgICAgIGZpbGVEb20gPSBudWxsLAogICAgICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gbnVsbCwKICAgICAgICAgICAgICAgICAgICBmaWxlVXJsID0gbnVsbCwKICAgICAgICAgICAgICAgICAgICB0aW1lU3RhbXAgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTsKCiAgICAgICAgICAgICAgICAvLyBmb3IgZHJhZnQgdXNlY2FzZSwgaWYgdGV4dCBjb250YWlucyAiLyIgaW4gaXQsIGl0IG1lYW5zIHRoZSBmaWxlIGlzIGFscmVhZHkgdXBsb2FkZWQKICAgICAgICAgICAgICAgIC8vIHRleHQgc2hvdWxkIGNvbnRhaW4gdGhlIHBhdGgsIGFzc3VtaW5nIHRoYXQgdGhlIGZpbGVVcmwgaXMgc3RvcmVkIGluIGRhdGEgZWxlbWVudAoKICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgIC8vIFN0b3JlIHRoZSB1cmwgb2YgZmlsZSBhcyBkYXRhCiAgICAgICAgICAgICAgICAgICAgaWYoIV8uaXNVbmRlZmluZWQoJGVsZW0uZGF0YSgia2V5IikpKQogICAgICAgICAgICAgICAgICAgICAgICBmaWxlVXJsID0gJGVsZW0uZGF0YSgia2V5Iik7CgogICAgICAgICAgICAgICAgICAgIGlmKGZpbGVVcmwpICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vcHJlcGVuZCBjb250ZXh0IHBhdGggaWYgbm90IGFscmVhZHkgYXBwZW5kZWQKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoZmlsZVVybC5sYXN0SW5kZXhPZih0aGlzLm9wdGlvbnMuX2dldFVybCwgMCkgPT09IDApKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlVXJsID0gIHRoaXMub3B0aW9ucy5fZ2V0VXJsICsgZmlsZVVybDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZpZXdGaWxlLmFwcGx5KHRoaXMsIFtudWxsLCB7ImZpbGVVcmwiIDogZmlsZVVybH1dKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcHJldmlld0ZpbGVPYmpJZHggPSB0aGlzLl9nZXRGaWxlT2JqSWR4KGluZGV4KTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHByZXZpZXdGaWxlID0gdGhpcy4kZmlsZURvbUVsZW1lbnRzW3ByZXZpZXdGaWxlT2JqSWR4WzBdXVswXS5maWxlc1twcmV2aWV3RmlsZU9iaklkeFsxXV07CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvYmplY3RVcmwgPSB0aGlzLl9wcmV2aWV3RmlsZVVzaW5nT2JqZWN0VXJsKHByZXZpZXdGaWxlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9iamVjdFVybCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGVsZW0uZGF0YSgib2JqZWN0VXJsIiwgb2JqZWN0VXJsKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHByZXZpZXdGaWxlOiBmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgIHZhciB1cmwgPSBudWxsOwogICAgICAgICAgICBpZihfLmlzVW5kZWZpbmVkKGFyZ3VtZW50c1sxXSkpCiAgICAgICAgICAgICAgICB1cmwgPSB0aGlzLiRlbGVtZW50W3RoaXMub3B0aW9ucy51cGxvYWRlclBsdWdpbk5hbWVdKCJnZXRGaWxlVXJsIik7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHVybCA9IGFyZ3VtZW50c1sxXS5maWxlVXJsOwogICAgICAgICAgICB2YXIgbGFzdEluZGV4ID0gdXJsLmxhc3RJbmRleE9mKCcvJyk7CiAgICAgICAgICAgIC8vdG8gbWFrZSBzdXJlIHVybCBoYXMgYSBzbGFzaCAnLycKICAgICAgICAgICAgaWYobGFzdEluZGV4ID49IDApIHsKICAgICAgICAgICAgICAgIC8vZW5jb2RlIHRoZSBmaWxlbmFtZSBhZnRlciBsYXN0IHNsYXNoIHRvIGVuc3VyZSB0aGUgaGFuZGxpbmcgb2Ygc3BlY2lhbCBjaGFyYWN0ZXJzCiAgICAgICAgICAgICAgICB1cmwgPSB1cmwuc3Vic3RyKDAsIGxhc3RJbmRleCkgKycvJysgZW5jb2RlVVJJQ29tcG9uZW50KHVybC5zdWJzdHIobGFzdEluZGV4ICsgMSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIHRoaXMgd291bGQgd29yayBmb3IgZGF0YVVSbCBvciBub3JtYWwgVVJMCiAgICAgICAgICAgIC8vIHRvZG86IGFkZCBzdXBwb3J0IHRvIHByZXZpZXcgYmFzZSA2NCBlbmNvZGVkIGltYWdlLCB0byBwcmV2aWV3IGJhc2U2NCBlbmNvZGVkIGJpbmFyeSwgd2Ugd291bGQgcHJvYmFibHkgbmVlZAogICAgICAgICAgICAvLyB0b2RvOiB0aGUgY29udGVudCB0eXBlIGluIHRoZSB3aWRnZXQgdG9vCiAgICAgICAgICAgIHdpbmRvdy5vcGVuKHVybCwgJycsICdzY3JvbGxiYXJzPW5vLG1lbnViYXI9bm8saGVpZ2h0PTYwMCx3aWR0aD04MDAscmVzaXphYmxlPXllcyx0b29sYmFyPW5vLHN0YXR1cz1ubycpOwoKICAgICAgICB9LAoKICAgICAgICByZXNldElmTm90TXVsdGlTZWxlY3Q6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKCF0aGlzLm9wdGlvbnMubXVsdGlTZWxlY3QpewogICAgICAgICAgICAgICAgLy8gUmVzZXQgdGhlIHZhbHVlIGFuZCBmaWxlIGFycmF5CiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlcyA9IFtdOwogICAgICAgICAgICAgICAgLy90aGlzLmNvbW1lbnRzID0gW107CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBzaG93RmlsZUxpc3Q6IGZ1bmN0aW9uKGZpbGVOYW1lLCBjb21tZW50LCBmaWxlVXJsKXsKICAgICAgICAgICAgaWYoIXRoaXMub3B0aW9ucy5tdWx0aVNlbGVjdCB8fCBmaWxlTmFtZSA9PSBudWxsIHx8IF8uaXNVbmRlZmluZWQoZmlsZU5hbWUpKSB7CiAgICAgICAgICAgICAgICAvLyBpZiBub3QgbXVsdGlzZWxlY3QsIHJlbW92ZSBhbGwgdGhlIGNoaWxkcmVuIG9mIGZpbGUgbGlzdAogICAgICAgICAgICAgICAgdGhpcy4kZWxlbWVudEZpbGVMaXN0LmVtcHR5KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEFkZCB0aGUgZmlsZSBpdGVtCiAgICAgICAgICAgIC8vIE9uIGNsaWNrIG9mIGNsb3NlLCByZW1vdmUgdGhlIGVsZW1lbnQgYW5kIHVwZGF0ZSB0aGUgbW9kZWwKICAgICAgICAgICAgLy8gaGFuZGxlIG9uIGNsaWNrIG9mIHByZXZpZXcgYnV0dG9uCiAgICAgICAgICAgIGlmKGZpbGVOYW1lICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHRoaXMuJGZpbGVJdGVtID0gdGhpcy4kZWxlbWVudEZpbGVMaXN0LmFwcGVuZCh0aGlzLmZpbGVJdGVtKGZpbGVOYW1lLCBjb21tZW50LCBmaWxlVXJsKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBIYW5kbGVzIHRoZSBjbGljayBvbiBjb21tZW50IGZpZWxkCiAgICAgICAgICoKICAgICAgICAgKiBUT0RPOiBJbXBsZW1lbnQgc2hvdy9oaWRlIGJlaGF2aW91ciBpbnN0ZWFkIG9mIHJlcGxhY2VXaXRoCiAgICAgICAgICogVGhpcyBtYXkgYmUgY2F1c2UgcHJvYmxlbSBkdXJpbmcgYnViYmxlIHVwIG9mIGV2ZW50CiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gZXZlbnQKICAgICAgICAgKi8KICAgICAgICBoYW5kbGVDb21tZW50Q2xpY2sgOiBmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgIHZhciAkY29tbWVudEVsZW0gPSBudWxsLAogICAgICAgICAgICAgICAgJGVsZW0gPSAkKGV2ZW50LnRhcmdldCk7CiAgICAgICAgICAgIGlmICgkZWxlbS50ZXh0KCkgPT09IF9kZWZhdWx0cy5wbGFjZUhvbGRlclRleHQpIHsKICAgICAgICAgICAgICAgICRjb21tZW50RWxlbSA9IHRoaXMuZ2V0TmV3Q29tbWVudEVsZW1lbnQoKQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGNvbW1lbnRFbGVtID0gdGhpcy5nZXROZXdDb21tZW50RWxlbWVudCgkKGV2ZW50LnRhcmdldCkudGV4dCgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkZWxlbS5yZXBsYWNlV2l0aCgkY29tbWVudEVsZW0pOwogICAgICAgICAgICAvLyByZWdpc3RlciB0aGUgZXZlbnQgYWdhaW4KICAgICAgICAgICAgaWYoaXNCcm93c2VySUU5T3JJRTEwKXsKICAgICAgICAgICAgICAgICRjb21tZW50RWxlbS5mb2N1cygpLmZvY3Vzb3V0KCQucHJveHkodGhpcy5oYW5kbGVDb21tZW50Qmx1ciwgdGhpcykpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgJGNvbW1lbnRFbGVtLmZvY3VzKCkuYmx1cigkLnByb3h5KHRoaXMuaGFuZGxlQ29tbWVudEJsdXIsIHRoaXMpKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUNvbW1lbnRCbHVyIDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICB2YXIgJGNvbW1lbnRTdW1tYXJ5RWxlbSA9IG51bGwsCiAgICAgICAgICAgICAgICAkZWxlbSA9ICQoZXZlbnQudGFyZ2V0KTsKICAgICAgICAgICAgaWYgKCRlbGVtLnRleHQoKSA9PT0gX2RlZmF1bHRzLnBsYWNlSG9sZGVyVGV4dCkgewogICAgICAgICAgICAgICAgJGNvbW1lbnRTdW1tYXJ5RWxlbSA9IHRoaXMuZ2V0TmV3Q29tbWVudEVsZW1lbnRTdW1tYXJ5KCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAkY29tbWVudFN1bW1hcnlFbGVtID0gdGhpcy5nZXROZXdDb21tZW50RWxlbWVudFN1bW1hcnkoJChldmVudC50YXJnZXQpLnRleHQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJGVsZW0ucmVwbGFjZVdpdGgoJGNvbW1lbnRTdW1tYXJ5RWxlbSk7CiAgICAgICAgICAgICRjb21tZW50U3VtbWFyeUVsZW0uZm9jdXMoJC5wcm94eSh0aGlzLmhhbmRsZUNvbW1lbnRDbGljayx0aGlzKSkuY2xpY2soJC5wcm94eSh0aGlzLmhhbmRsZUNvbW1lbnRDbGljayx0aGlzKSk7CiAgICAgICAgICAgIC8vIEFkZCBhIGRpdiB3aXRoIHRoZSBodG1sCiAgICAgICAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcigiY2hhbmdlLmZpbGV1cGxvYWQiKTsKICAgICAgICB9LAoKICAgICAgICAvLyBjaGVja3MgaWYgZmlsZSBuYW1lIGlzIHZhbGlkIG9yIG5vdCB0byBwcmV2ZW50IHNlY3VyaXR5IHRocmVhdHMKICAgICAgICBpc1ZhbGlkIDogZnVuY3Rpb24oZm5hbWUpIHsKICAgICAgICAgICAgdmFyIHJnMT0vXlteXFwvOlwqXDtcJFwlXD8iPD5cfF0rJC87IC8vIGZvcmJpZGRlbiBjaGFyYWN0ZXJzIFwgLyA6ICogPyAiIDwgPiB8IDsgJSAkCiAgICAgICAgICAgIHZhciByZzI9L15cLi87IC8vIGNhbm5vdCBzdGFydCB3aXRoIGRvdCAoLikKICAgICAgICAgICAgdmFyIHJnMz0vXihudWx8cHJufGNvbnxscHRbMC05XXxjb21bMC05XSkoXC58JCkvaTsgLy8gZm9yYmlkZGVuIGZpbGUgbmFtZXMKICAgICAgICAgICAgcmV0dXJuIHJnMS50ZXN0KGZuYW1lKSAmJiAhcmcyLnRlc3QoZm5hbWUpICYmICFyZzMudGVzdChmbmFtZSk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlQ2hhbmdlOiBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICBpZiAoIXRoaXMuX2lzRmlsZVVwZGF0ZSkgewogICAgICAgICAgICAgICAgdmFyIGN1cnJGaWxlTmFtZSA9ICcnLAogICAgICAgICAgICAgICAgICAgIGluVmFsaWRTaXplZmlsZU5hbWVzID0gJycsCiAgICAgICAgICAgICAgICAgICAgaW5WYWxpZE5hbWVmaWxlTmFtZXMgPSAnJywKICAgICAgICAgICAgICAgICAgICBpblZhbGlkTWltZVR5cGVmaWxlTmFtZXMgPSAnJywKICAgICAgICAgICAgICAgICAgICAkZWxlbSA9ICQoZXZudC50YXJnZXQpLAogICAgICAgICAgICAgICAgICAgIGZpbGVzID0gJGVsZW1bMF0uZmlsZXM7CiAgICAgICAgICAgICAgICAvLyBJbml0aWFsbHkgc2V0IHRoZSBpbnZhbGlkIGZsYWcgdG8gZmFsc2UKICAgICAgICAgICAgICAgIC8vIGlmIG5vdCBtdWx0aXNlbGVjdCB0aGVuIHJlbW92ZSB0aGUgZXh0cmEgZG9tRUxlbWVudCBjbG9uZQogICAgICAgICAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMubXVsdGlTZWxlY3QgJiYgdGhpcy4kZmlsZURvbUVsZW1lbnRzLmxlbmd0aCA+IDEpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiRmaWxlRG9tRWxlbWVudHMuc3BsaWNlKDAsIDEpCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyIGlzSW52YWxpZFNpemUgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBpc0ludmFsaWRGaWxlTmFtZSA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGlzSW52YWxpZE1pbWVUeXBlID0gZmFsc2U7CiAgICAgICAgICAgICAgICB0aGlzLnJlc2V0SWZOb3RNdWx0aVNlbGVjdCgpOwogICAgICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aHJvdWdoIGFsbCB0aGUgZmlsZXMKICAgICAgICAgICAgICAgIGlmIChpc0Jyb3dzZXJJRTlPcklFMTApIHsgLy8gSUU5IGRvZXNuJ3Qgc3VwcG9ydCBGaWxlTGlzdCwgaGVuY2UgZmlsZXMgdmFyaWFibGUgaXMgdW5kZWZpbmVkCiAgICAgICAgICAgICAgICAgICAgY3VyckZpbGVOYW1lID0gJGVsZW0udmFsKCkuc3BsaXQoIlxcIikucG9wKCk7CiAgICAgICAgICAgICAgICAgICAgLy91cGRhdGUgdGhlIGxhc3QgZWxlbWVudCBvZiBhcnJheQogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLiRmaWxlRG9tRWxlbWVudHMubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRmaWxlRG9tRWxlbWVudHNbdGhpcy4kZmlsZURvbUVsZW1lbnRzLmxlbmd0aCAtIDFdID0gJGVsZW07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHRoaXMuY2xvbmVGaWxlSW5wdXRBbmRVcGRhdGVJZEZvcklFOSgpOwoKICAgICAgICAgICAgICAgICAgICAvLyBJbiBjYXNlIG9mIElFOSwgb25seSBkbyB0aGlzCiAgICAgICAgICAgICAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoZmlsZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2hvd0ZpbGVMaXN0KGN1cnJGaWxlTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWVzLnB1c2goY3VyckZpbGVOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHJpZ2dlciB0aGUgY2hhbmdlIGV2ZW50IHRvIHVwZGF0ZSB0aGUgdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCJjaGFuZ2UuZmlsZXVwbG9hZCIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChmaWxlcykpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaW52YWxpZEZpbGVzSW5kZXhlcyA9IFtdOwogICAgICAgICAgICAgICAgICAgIF8uZWFjaChmaWxlcywgZnVuY3Rpb24gKGZpbGUsIGZpbGVJbmRleCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNDdXJyZW50SW52YWxpZEZpbGVTaXplID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0N1cnJlbnRJbnZhbGlkRmlsZU5hbWUgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQ3VycmVudEludmFsaWRNaW1lVHlwZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBjdXJyRmlsZU5hbWUgPSBmaWxlLm5hbWUuc3BsaXQoIlxcIikucG9wKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdyBzaXplIGlzIGluIE1CCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzaXplID0gZmlsZS5zaXplIC8gMTAyNCAvIDEwMjQ7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIGZpbGUgc2l6ZSBsaW1pdCBpcyB3aXRoaW4gbGltaXRzCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoc2l6ZSA+IHBhcnNlRmxvYXQodGhpcy5vcHRpb25zLmZpbGVTaXplTGltaXQpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNJbnZhbGlkU2l6ZSA9IGlzQ3VycmVudEludmFsaWRGaWxlU2l6ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpblZhbGlkU2l6ZWZpbGVOYW1lcyA9IGN1cnJGaWxlTmFtZSArICIsIiArIGluVmFsaWRTaXplZmlsZU5hbWVzOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLmlzVmFsaWQoY3VyckZpbGVOYW1lKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgaWYgZmlsZSBuYW1lcyBhcmUgdmFsaWQgKGllKSB0aGVyZSBhcmUgbm8gY29udHJvbCBjaGFyYWN0ZXJzIGluIGZpbGUgbmFtZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzSW52YWxpZEZpbGVOYW1lID0gaXNDdXJyZW50SW52YWxpZEZpbGVOYW1lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluVmFsaWROYW1lZmlsZU5hbWVzID0gY3VyckZpbGVOYW1lICsgIiwiICsgaW5WYWxpZE5hbWVmaWxlTmFtZXM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZmlsZS50eXBlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNNYXRjaCA9IHRoaXMucmVnZXhNaW1lVHlwZUxpc3Quc29tZShmdW5jdGlvbiAocngpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcngudGVzdChmaWxlLnR5cGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzTWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0ludmFsaWRNaW1lVHlwZSA9IGlzQ3VycmVudEludmFsaWRNaW1lVHlwZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5WYWxpZE1pbWVUeXBlZmlsZU5hbWVzID0gY3VyckZpbGVOYW1lICsgIiwiICsgaW5WYWxpZE1pbWVUeXBlZmlsZU5hbWVzOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGUgZmlsZSBpcyBub3QgaW52YWxpZCwgc2hvdyBpdCBhbmQgcHVzaCBpdCB0byBpbnRlcm5hbCBhcnJheQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzQ3VycmVudEludmFsaWRGaWxlU2l6ZSAmJiAhaXNDdXJyZW50SW52YWxpZEZpbGVOYW1lICYmICFpc0N1cnJlbnRJbnZhbGlkTWltZVR5cGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2hvd0ZpbGVMaXN0KGN1cnJGaWxlTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlcy5wdXNoKGN1cnJGaWxlTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnZhbGlkRmlsZXNJbmRleGVzLnB1c2goZmlsZUluZGV4KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICAgICAgICAgIGlmIChpbnZhbGlkRmlsZXNJbmRleGVzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRGaWxlRG9tSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY3VycmVudEZpbGVEb21FbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXNDb3VudDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuJGZpbGVEb21FbGVtZW50cy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50RmlsZURvbUluZGV4ID0gdGhpcy4kZmlsZURvbUVsZW1lbnRzLmxlbmd0aCAtIDE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY3VycmVudEZpbGVEb21FbGVtZW50ID0gdGhpcy4kZmlsZURvbUVsZW1lbnRzW2N1cnJlbnRGaWxlRG9tSW5kZXhdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCRjdXJyZW50RmlsZURvbUVsZW1lbnQgJiYgJGN1cnJlbnRGaWxlRG9tRWxlbWVudC5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZXNDb3VudCA9ICRjdXJyZW50RmlsZURvbUVsZW1lbnRbMF0uZmlsZXMubGVuZ3RoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgYWxsIHRoZSBmaWxlcyBhcmUgaW52YWxpZCByZW1vdmUgdGhlIGlucHV0IGVsZW1lbnQgYXMgd2VsbCBvdGhlcndpc2Ugb25seSByZW1vdmUgdGhlIGludmFsaWQgZmlsZXMuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbGVzQ291bnQgPT09IGludmFsaWRGaWxlc0luZGV4ZXMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGZpbGVEb21FbGVtZW50cy5zcGxpY2UoLTEsIDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2RlbGV0ZUZpbGVzRnJvbUlucHV0RG9tKCRjdXJyZW50RmlsZURvbUVsZW1lbnQsIGludmFsaWRGaWxlc0luZGV4ZXMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW4gY2FzZSBvZiBJRTEwLCBjcmVhdGUgb25lIGV4dHJhIGVsZW1lbnQKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQnJvd3NlcklFOU9ySUUxMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbG9uZUZpbGVJbnB1dEFuZFVwZGF0ZUlkRm9ySUU5KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIHRyaWdnZXIgdGhlIGNoYW5nZSBldmVudCB0byB1cGRhdGUgdGhlIHZhbHVlCiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCJjaGFuZ2UuZmlsZXVwbG9hZCIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChpc0ludmFsaWRTaXplKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zaG93SW52YWxpZE1lc3NhZ2UoaW5WYWxpZFNpemVmaWxlTmFtZXMuc3Vic3RyaW5nKDAsIGluVmFsaWRTaXplZmlsZU5hbWVzLmxhc3RJbmRleE9mKCcsJykpLCB0aGlzLmludmFsaWRGZWF0dXJlLlNJWkUpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc0ludmFsaWRGaWxlTmFtZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc2hvd0ludmFsaWRNZXNzYWdlKGluVmFsaWROYW1lZmlsZU5hbWVzLnN1YnN0cmluZygwLCBpblZhbGlkTmFtZWZpbGVOYW1lcy5sYXN0SW5kZXhPZignLCcpKSwgdGhpcy5pbnZhbGlkRmVhdHVyZS5OQU1FKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNJbnZhbGlkTWltZVR5cGUpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnNob3dJbnZhbGlkTWVzc2FnZShpblZhbGlkTWltZVR5cGVmaWxlTmFtZXMuc3Vic3RyaW5nKDAsIGluVmFsaWRNaW1lVHlwZWZpbGVOYW1lcy5sYXN0SW5kZXhPZignLCcpKSwgdGhpcy5pbnZhbGlkRmVhdHVyZS5NSU1FVFlQRSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBjbG9uZUZpbGVJbnB1dEFuZFVwZGF0ZUlkRm9ySUU5IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIGVsZW0gPSBfLmxhc3QodGhpcy4kZmlsZURvbUVsZW1lbnRzKSwKICAgICAgICAgICAgICAgIGVsZW1FeGlzdHMgPSBlbGVtICE9IG51bGwsCiAgICAgICAgICAgICAgICBlbGVtSGFzVmFsdWUgPSBlbGVtRXhpc3RzICYmIGVsZW0udmFsKCkubGVuZ3RoID4gMCwKICAgICAgICAgICAgICAgIGVsZW1JZCA9IG51bGwsCiAgICAgICAgICAgICAgICBzZWxlY3RvciA9IG51bGw7CgogICAgICAgICAgICAvLyBDUS00MjM3OTAzIDogY3JlYXRlIGNsb25lIHRvIGhhbmRsZSB0aGUgY2FzZSB3aGVuIHVzZXIgY2xpY2tzIGNhbmNlbCBpbiBjaHJvbWUgYW5kIGZvciBtdWx0aXNlbGVjdAogICAgICAgICAgICAvLyBvbiBjbGlja2luZyBjYW5jZWwgaW4gY2hyb21lIGZpbGUgYnJvd3NlciwgY2hyb21lIHJlbW92ZXMgYWxsIHRoZSBmaWxlcyBmcm9tIHRoZSBpbnB1dCBlbGVtZW50CiAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgZXh0cmEgY2xvbmUgaW4gJGZpbGVEb21FbGVtZW50IG9uIGhhbmRsZUNoYW5nZQogICAgICAgICAgICBpZighZWxlbUV4aXN0cyB8fCBlbGVtSGFzVmFsdWUpIHsKICAgICAgICAgICAgICAgIGVsZW0gPSB0aGlzLiRlbGVtZW50LmNsb25lKCk7CiAgICAgICAgICAgICAgICAvLyBjb3B5IHRoZSBkYXRhIGF0dHJpYnV0ZXMKICAgICAgICAgICAgICAgIGVsZW0uZGF0YSh0aGlzLiRlbGVtZW50LmRhdGEoKSk7CiAgICAgICAgICAgICAgICBpZihpc0Jyb3dzZXJJRTlPcklFMTApewogICAgICAgICAgICAgICAgICAgIGVsZW1JZCA9IHRoaXMuJGVsZW1lbnQuYXR0cigiaWQiKSArICgrK2ZpbGVMYWJlbHNDb3VudCk7CiAgICAgICAgICAgICAgICAgICAgZWxlbS5hdHRyKCJpZCIsIGVsZW1JZCk7CiAgICAgICAgICAgICAgICAgICAgZWxlbS5jc3MoewogICAgICAgICAgICAgICAgICAgICAgICAncG9zaXRpb24nIDogJ2Fic29sdXRlJywKICAgICAgICAgICAgICAgICAgICAgICAgJ3RvcCcgOiAnLTIwMDBweCcsCiAgICAgICAgICAgICAgICAgICAgICAgICdsZWZ0JzogJy0yMDAwcHgnCiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgZWxlbS5hcHBlbmRUbygnYm9keScpOwogICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlTGFiZWxGb3JBdHRyKGVsZW1JZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbGVtLmNoYW5nZSgkLnByb3h5KHRoaXMuaGFuZGxlQ2hhbmdlLCB0aGlzKSk7CiAgICAgICAgICAgICAgICB0aGlzLiRmaWxlRG9tRWxlbWVudHMucHVzaChlbGVtKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBDYXNlOiBpZiBpdCBpcyBub3QgbXVsdGlzZWxlY3QgYW5kIGlmIHRoZSBmaXJzdCBmaWxlIGRvbSBlbGVtZW50IGlzIG51bGwKICAgICAgICAgICAgLy8gdGhpcyBjYXNlIHdvdWxkIGhpdCB3aGVuIHdlIHJlc3RvcmUgYSBzaW5nbGUgc2VsZWN0IGZpbGUgYXR0YWNobWVudCBhbmQgYXR0YWNoIGEgbmV3IGZpbGUKICAgICAgICAgICAgaWYoIXRoaXMub3B0aW9ucy5tdWx0aVNlbGVjdCAmJiB0aGlzLiRmaWxlRG9tRWxlbWVudHNbMF0gPT09IG51bGwpewogICAgICAgICAgICAgICAgLy9TcGxpY2UgbnVsbCBvdXQgb2YgaXQsIHNpbmNlIHdlIGFyZSBhdHRhY2hpbmcgYSBuZXcgZmlsZQogICAgICAgICAgICAgICAgdGhpcy4kZmlsZURvbUVsZW1lbnRzLnNwbGljZSgwLCAxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBpZiB0aGUgYnJvd3NlciBpcyBub3QgSUU5LCB0aGVuIGNsaWNrIGl0CiAgICAgICAgICAgIGlmKCFpc0Jyb3dzZXJJRTlPcklFMTApIHsKICAgICAgICAgICAgICAgIGVsZW0uY2xpY2soKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBJbiBjYXNlIG9mIElFOSwgZ2V0IHRoZSBsYXN0IGVsZW1lbnQgb2YgZmlsZURvbSBhbmQgdXBkYXRlIHRoZSBpZCBmb3IgbGFiZWwKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBmaWxlSW5wdXRJZAogICAgICAgICAqLwogICAgICAgIHVwZGF0ZUxhYmVsRm9yQXR0ciA6IGZ1bmN0aW9uKGZpbGVJbnB1dElkKXsKICAgICAgICAgICAgdGhpcy4kbGFiZWwuYXR0cigiZm9yIiAsIGZpbGVJbnB1dElkKTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVMYWJlbEZvckZpbGVJbnB1dCA6IGZ1bmN0aW9uIChmaWxlSW5wdXRJZCl7CiAgICAgICAgICAgIGlmKGlzQnJvd3NlcklFOU9ySUUxMCkgewogICAgICAgICAgICAgICAgdGhpcy4kbGFiZWwgPSAkKCI8bGFiZWw+PC9sYWJlbD4iKS5hZGRDbGFzcygiZ3VpZGUtZnUtYXR0YWNoLWJ1dHRvbiBidXR0b24iKQogICAgICAgICAgICAgICAgICAgICAgICAudGV4dCh0aGlzLm9wdGlvbnMuYnV0dG9uVGV4dCkKICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2ZvcicsZmlsZUlucHV0SWQpOwogICAgICAgICAgICAgICAgdGhpcy4kZWxlbWVudEZpbGVVcGxvYWRCdG4ucmVwbGFjZVdpdGgodGhpcy4kbGFiZWwpOwogICAgICAgICAgICAgICAgdGhpcy4kbGFiZWwucGFyZW50KCkuYXR0cigidGFiaW5kZXgiLCAwKS5hdHRyKCJyb2xlIiwgImJ1dHRvbiIpLmF0dHIoImFyaWEtbGFiZWwiLCB0aGlzLm9wdGlvbnMuc2NyZWVuUmVhZGVyVGV4dCB8fCAiIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKCiAgICAgICAgY29uc3RydWN0b3I6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGUgc2VsZiBpbnN0YW5jZQogICAgICAgICAgICB2YXIgX3NlbGYgPSB0aGlzLAogICAgICAgICAgICAgICAgaXNGaXJzdCA9IHRydWU7CiAgICAgICAgICAgIC8vanF1ZXJ5IGluc3RhbmNlIG9mIGZpbGUgdXBsb2FkIGJ1dHRvbgogICAgICAgICAgICB0aGlzLiRlbGVtZW50RmlsZVVwbG9hZEJ0biA9IHRoaXMuJHBhcmVudC5maW5kKHRoaXMub3B0aW9ucy5idXR0b25DbGFzcyk7CiAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRGaWxlVXBsb2FkQnRuLmF0dHIoImFyaWEtbGFiZWwiLCB0aGlzLm9wdGlvbnMuc2NyZWVuUmVhZGVyVGV4dCB8fCAiIik7CiAgICAgICAgICAgIGlmKGlzQnJvd3NlcklFOU9ySUUxMCl7CiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnRJZCA9IHRoaXMuJGVsZW1lbnQuYXR0cigiaWQiKTsKICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlTGFiZWxGb3JGaWxlSW5wdXQodGhpcy4kZWxlbWVudC5hdHRyKCJpZCIpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gaHRtbCBmb3IgZmlsZSBsaXN0CiAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRGaWxlTGlzdCA9ICQodGhpcy5maWxlSXRlbUxpc3QoKSk7CiAgICAgICAgICAgIC8vIEluaXRpYWxpemUgdGhlIHZhbHVlIGFuZCBmaWxlKFJlZmVyIEZpbGVMaXN0IGNsYXNzIG1kbikKICAgICAgICAgICAgdGhpcy52YWx1ZXMgPSBbXTsKICAgICAgICAgICAgdGhpcy5faW5pdGlhbEZpbGVWYWx1ZUZpbGVOYW1lTWFwID0ge307CiAgICAgICAgICAgIC8vIExpc3Qgb2YgZG9tIGVsZW1lbnRzIG9mIGlucHV0IHR5cGUgZmlsZQogICAgICAgICAgICB0aGlzLiRmaWxlRG9tRWxlbWVudHMgPSBbXTsKCiAgICAgICAgICAgIHZhciBmbGFnID0gZmFsc2UsCiAgICAgICAgICAgICAgICAkY3VyckVsZW0gPSBudWxsOwoKICAgICAgICAgICAgJChkb2N1bWVudCkubW91c2Vkb3duKGZ1bmN0aW9uKGUpIHsKICAgICAgICAgICAgICAgICRjdXJyRWxlbSA9ICQoZS50YXJnZXQpOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgLy8gRW50ZXIga2V5IHNob3VsZCByZXN1bHQgaW4gY2xpY2sgb2YgYnV0dG9uCiAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRGaWxlVXBsb2FkQnRuCiAgICAgICAgICAgICAgICAuZm9jdXMoZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgICAgICBfc2VsZi4kZWxlbWVudC50cmlnZ2VyKCJmb2N1cy5maWxldXBsb2FkIik7CiAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICAgICAgLmNsaWNrKCQucHJveHkodGhpcy5jbG9uZUZpbGVJbnB1dEFuZFVwZGF0ZUlkRm9ySUU5LCB0aGlzKSkKICAgICAgICAgICAgICAgIC5ibHVyKGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgY3VyckVsZW0gZG9lcyBub3QgYmVsb25nIHRvIHRoZSBmaWxlSXRlbUxpc3QKICAgICAgICAgICAgICAgICAgICBpZighZmxhZyAmJiAkY3VyckVsZW0hPSBudWxsICYmICRjdXJyRWxlbS5jbG9zZXN0KCIuZ3VpZGUtZnUtZmlsZUl0ZW1MaXN0IikubGVuZ3RoIDw9MCl7CiAgICAgICAgICAgICAgICAgICAgICAgIF9zZWxmLiRlbGVtZW50LnRyaWdnZXIoImZvY3Vzb3V0LmZpbGV1cGxvYWQiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZmxhZyA9IGZhbHNlOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIC8vSW5pdGlhbGl6ZSB0aGUgZmlsZVByZXZpZXcgUGx1Z2luCiAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRbdGhpcy5vcHRpb25zLnVwbG9hZGVyUGx1Z2luTmFtZV0oewogICAgICAgICAgICAgICAgaWZyYW1lQ29udGFpbmVyOiB0aGlzLm9wdGlvbnMuaWZyYW1lQ29udGFpbmVyLAogICAgICAgICAgICAgICAgX2ZpbGVQYXRoOiB0aGlzLm9wdGlvbnMuX2ZpbGVQYXRoLAogICAgICAgICAgICAgICAgX3V1aWRHZW5lcmF0b3I6IHRoaXMub3B0aW9ucy5fdXVpZEdlbmVyYXRvciwKICAgICAgICAgICAgICAgIF9nZXRVcmw6IHRoaXMub3B0aW9ucy5fZ2V0VXJsCgogICAgICAgICAgICB9KTsKICAgICAgICAgICAgLy8gR2V0dGluZyBpbnB1dCBmaWxlIHZhbHVlCiAgICAgICAgICAgIC8vIGxpc3RlbmluZyBvbiBmaWxldXBsb2FkZWQgZXZlbnQKICAgICAgICAgICAgdGhpcy4kZWxlbWVudC5jaGFuZ2UoJC5wcm94eSh0aGlzLmhhbmRsZUNoYW5nZSwgdGhpcykpCiAgICAgICAgICAgICAgICAub24oImFkb2JlRmlsZVVwbG9hZGVyLmZpbGVVcGxvYWRlZCIsICQucHJveHkodGhpcy5wcmV2aWV3RmlsZSwgdGhpcykpOwogICAgICAgIH0KICAgIH07CgogICAgJC5mbi5hZG9iZUZpbGVBdHRhY2htZW50ID0gZnVuY3Rpb24gKG9wdGlvbiwgdmFsdWUpIHsKICAgICAgICB2YXIgZ2V0ID0gJycsCiAgICAgICAgICAgIGVsZW1lbnQgPSB0aGlzLmVhY2goZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgLy8gaW4gY2FzZSBvZiBpbnB1dCB0eXBlIGZpbGUKICAgICAgICAgICAgICAgIGlmICgkKHRoaXMpLmF0dHIoJ3R5cGUnKSA9PT0gJ2ZpbGUnKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyICR0aGlzID0gJCh0aGlzKSwKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9ICR0aGlzLmRhdGEoJ2Fkb2JlRmlsZUF0dGFjaG1lbnQnKSwKICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBBZG9iZUZpbGVBdHRhY2htZW50LnByb3RvdHlwZS5kZWZhdWx0cywgdHlwZW9mIG9wdGlvbiA9PT0gJ29iamVjdCcgJiYgb3B0aW9uKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gU2F2ZSB0aGUgYWRvYmVGaWxlQXR0YWNobWVudCBkYXRhIGluIGpxdWVyeQogICAgICAgICAgICAgICAgICAgIGlmICghZGF0YSkgewogICAgICAgICAgICAgICAgICAgICAgICAkdGhpcy5kYXRhKCdhZG9iZUZpbGVBdHRhY2htZW50JywgKGRhdGEgPSBuZXcgQWRvYmVGaWxlQXR0YWNobWVudCh0aGlzLCBvcHRpb25zKSkpOwogICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmNvbnN0cnVjdG9yKCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBjb2RlIHRvIGdldCBhbmQgc2V0IGFuIG9wdGlvbgogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb3B0aW9uID09PSAnc3RyaW5nJykgewogICAgICAgICAgICAgICAgICAgICAgICBnZXQgPSBkYXRhW29wdGlvbl0odmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CgogICAgICAgIGlmICh0eXBlb2YgZ2V0ICE9PSAndW5kZWZpbmVkJykgewogICAgICAgICAgICByZXR1cm4gZ2V0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBlbGVtZW50OwogICAgICAgIH0KICAgIH07CgogICAgLy8gZmlsZVNpemVMaW1pdCBpcyBpbiBNQiwgZGVmYXVsdCB2YWx1ZSBpcyAyTUIKICAgIEFkb2JlRmlsZUF0dGFjaG1lbnQucHJvdG90eXBlLmRlZmF1bHRzID0gewogICAgICAgICdidXR0b25UZXh0JzogJ0F0dGFjaCcsCiAgICAgICAgJ211bHRpU2VsZWN0JzogZmFsc2UsCiAgICAgICAgJ2ZpbGVTaXplTGltaXQnOiAyLAogICAgICAgICd1cGxvYWRlclBsdWdpbk5hbWUnOiAiYWRvYmVGaWxlVXBsb2FkZXIiLAogICAgICAgICdtaW1lVHlwZScgOiBbJ2F1ZGlvLyonLCAndmlkZW8vKicsICdpbWFnZS8qJywgJ3RleHQvKicsICdhcHBsaWNhdGlvbi9wZGYnXQogICAgfTsKCn0pKCQsIHdpbmRvdywgd2luZG93Ll8pOwooZnVuY3Rpb24oJCwgXykgewogICAgdmFyIHhmYVV0aWwgPSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGU7CiAgICAkLndpZGdldCggInhmYVdpZGdldC5maWxlVXBsb2FkIiwgJC54ZmFXaWRnZXQuYWJzdHJhY3RXaWRnZXQsIHsKCiAgICAgICAgX3dpZGdldE5hbWU6ImZpbGVVcGxvYWQiLAogICAgICAgIF9zdXBlclByb3RvdHlwZSA6ICQueGZhV2lkZ2V0LmFic3RyYWN0V2lkZ2V0LnByb3RvdHlwZSwKICAgICAgICBnZXRPcHRpb25zTWFwOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgcGFyZW50T3B0aW9uc01hcCA9IHRoaXMuX3N1cGVyUHJvdG90eXBlLmdldE9wdGlvbnNNYXAuYXBwbHkodGhpcyxhcmd1bWVudHMpLAogICAgICAgICAgICAgICAgbmV3TWFwID0gJC5leHRlbmQoe30scGFyZW50T3B0aW9uc01hcCwgJC5leHRlbmQoe30sIHRoaXMub3B0aW9ucywgewogICAgICAgICAgICAgICAgICAgICJ2YWx1ZSIgOiBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiR1c2VyQ29udHJvbC5hZG9iZUZpbGVBdHRhY2htZW50KCJ2YWx1ZSIsIHZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICJmaWxlTGlzdCI6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYWRvYmVGaWxlQXR0YWNobWVudCgiZmlsZUxpc3QiLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAiY29tbWVudCIgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJHVzZXJDb250cm9sLmFkb2JlRmlsZUF0dGFjaG1lbnQoImNvbW1lbnQiLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAvLyAiYWNjZXNzIiBjYW4gYmUgZWl0aGVyIG9wZW4gb3IgcmVhZG9ubHkKICAgICAgICAgICAgICAgICAgICAiYWNjZXNzIiA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kdXNlckNvbnRyb2wuYWRvYmVGaWxlQXR0YWNobWVudCgiYWNjZXNzIiwgdmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB9KSk7CgogICAgICAgICAgICByZXR1cm4gbmV3TWFwOwoKICAgICAgICB9LAogICAgICAgIC8vIFRPRE86IFdpbGwgbmVlZCB0byByZW1vdmUgdGhpcyBmdW5jdGlvbnMKICAgICAgICAvLyAgd2lsbCBiZSB0cmFja2VkIGJ5IExDLTM5MTIwMAoKICAgICAgICBfaW5pdGlhbGl6ZU9wdGlvbnM6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgXy5lYWNoKHRoaXMub3B0aW9uc0hhbmRsZXIsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7CiAgICAgICAgICAgICAgICAvLyBvdmVycmlkaW5nIHRoZSBiZWhhdmlvdXIgb2YgX2luaXRpYWxpemVPcHRpb25zCiAgICAgICAgICAgICAgICAvLyBvbmx5IGZvciBfdXVpZEdlbmVyYXRvcgogICAgICAgICAgICAgICAgLy8gYXMgd2UgZm9udCB3YW50IGdldFVVSUQgdG8gYmUgY2FsbGVkIGF0IHJlbmRlciB0aW1lCiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAiZnVuY3Rpb24iICYmIGtleSAhPT0gJ191dWlkR2VuZXJhdG9yJyApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUuYXBwbHkodGhpcywgW3RoaXMub3B0aW9uc1trZXldXSkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcykKICAgICAgICB9LAoKICAgICAgICBfZ2V0RmlsZUxpc3Q6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLiR1c2VyQ29udHJvbC5hZG9iZUZpbGVBdHRhY2htZW50KCJmaWxlTGlzdCIpOwogICAgICAgIH0sCgogICAgICAgIF9nZXRDb21tZW50OiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy4kdXNlckNvbnRyb2wuYWRvYmVGaWxlQXR0YWNobWVudCgiY29tbWVudCIpOwogICAgICAgIH0sCiAgICAgICAgX2dldEZpbGVOYW1lUGF0aE1hcDogZnVuY3Rpb24gKHBhdGhMaXN0KSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLiR1c2VyQ29udHJvbC5hZG9iZUZpbGVBdHRhY2htZW50KCJnZXRTZXRGaWxlUGF0aEFuZFJldHVybk5hbWVQYXRoTWFwIiwgcGF0aExpc3QpOwogICAgICAgIH0sCiAgICAgICAgZ2V0RXZlbnRNYXA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgcGFyZW50RXZlbnRNYXAgPSB0aGlzLl9zdXBlclByb3RvdHlwZS5nZXRFdmVudE1hcC5hcHBseSh0aGlzLCBhcmd1bWVudHMpLAogICAgICAgICAgICAgICAgbmV3TWFwID0gJC5leHRlbmQoe30sIHBhcmVudEV2ZW50TWFwLAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgImNoYW5nZSIgOiBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICAiZm9jdXNvdXQuZmlsZXVwbG9hZCIgOiB4ZmFVdGlsLlhGQV9FWElUX0VWRU5ULAogICAgICAgICAgICAgICAgICAgICAgICAiZm9jdXMuZmlsZXVwbG9hZCIgOiB4ZmFVdGlsLlhGQV9FTlRFUl9FVkVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgImNoYW5nZS5maWxldXBsb2FkIiA6IHhmYVV0aWwuWEZBX0NIQU5HRV9FVkVOVAogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICByZXR1cm4gbmV3TWFwOwogICAgICAgIH0sCiAgICAgICAgcmVuZGVyOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyICRlbCA9IHRoaXMuX3N1cGVyUHJvdG90eXBlLnJlbmRlci5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgICRlbC5hZG9iZUZpbGVBdHRhY2htZW50KHRoaXMuZ2V0T3B0aW9uc01hcCgpKTsKICAgICAgICAgICAgcmV0dXJuICRlbDsKICAgICAgICB9LAogICAgICAgIHNob3dEaXNwbGF5VmFsdWU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgLy9zaW5jZSB2YWx1ZSBjYW4ndCBiZSBzZXQgaW4gZmlsZSBlbGVtZW50IGlucHV0LCBsZWF2aW5nIHRoaXMgZm4gZW1wdHkKICAgICAgICB9LAogICAgICAgIHNob3dWYWx1ZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIC8vc2luY2UgdmFsdWUgY2FuJ3QgYmUgc2V0IGluIGZpbGUgZWxlbWVudCBpbnB1dCwgbGVhdmluZyB0aGlzIGZuIGVtcHR5CiAgICAgICAgfSwKICAgICAgICBnZXRDb21taXRWYWx1ZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5maWxlTGlzdCA9IHRoaXMuX2dldEZpbGVMaXN0KCk7CiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5jb21tZW50ID0gdGhpcy5fZ2V0Q29tbWVudCgpOwogICAgICAgICAgICByZXR1cm4gdGhpcy4kdXNlckNvbnRyb2wuYWRvYmVGaWxlQXR0YWNobWVudCgidmFsdWUiKTsKICAgICAgICB9CiAgICB9KTsKfSkoJCwgd2luZG93Ll8pOwoKLyoqCiAqIEFkb2JlIEZpbGVQcmV2aWV3IFdpZGdldCBQbHVnaW4KICoKICogT3B0aW9ucyBleHBlY3RlZCBieSBmaWxlIHByZXZpZXcgaXMgdGhlIHVybAogKgogKiBPcHRpb25zIFJlcXVpcmVkIEFyZToKICoKICogIGlmcmFtZU5hbWU6IE5hbWUgb2YgdGhlIElmcmFtZQogKiAgaWZyYW1lQ29udGFpbmVyOiBDb250YWluZXIgb2YgdGhlIGlmcmFtZShlZyBCb2R5KQogKiAgZmlsZVVwbG9hZFBhdGg6IFBhdGggd2hlcmUgdGhlIGZpbGUgaXMgdG8gYmUgdXBsb2FkZWQKICogIGZpbGVVcGxvYWRTZXJ2bGV0OiBTZXJ2bGV0IHdoZXJlIHRoZSBmaWxlIGlzIHRvIGJlIHVwbG9hZGVkCiAqCiAqLwooZnVuY3Rpb24gKCQsIF8pIHsKCiAgICB2YXIgQWRvYmVGaWxlVXBsb2FkZXIgPSBmdW5jdGlvbiAoZWxlbWVudCwgb3B0aW9ucykgewogICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7CiAgICAgICAgdGhpcy4kZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICB9OwoKICAgIEFkb2JlRmlsZVVwbG9hZGVyLnByb3RvdHlwZSA9IHsKCiAgICAgICAgX2ZpbGVJZnJhbWVOYW1lOiAiZ3VpZGUtZnUtaWZyYW1lIiwKCiAgICAgICAgX2ZpbGVQYXRoOiAiL3RtcC9mZC9tZiIsCgogICAgICAgIF9pZnJhbWVDb250YWluZXI6ICJib2R5I2Zvcm1Cb2R5IiwKCgogICAgICAgIGZpbGVJZnJhbWU6IGZ1bmN0aW9uIChuYW1lKSB7CiAgICAgICAgICAgIHJldHVybiAkKCI8aWZyYW1lPjwvaWZyYW1lPiIpLmF0dHIoewogICAgICAgICAgICAgICAgc3R5bGU6ICJkaXNwbGF5Om5vbmUiLAogICAgICAgICAgICAgICAgbmFtZTogbmFtZQogICAgICAgICAgICB9KTsKICAgICAgICB9LAoKICAgICAgICB1cGxvYWRGaWxlOiBmdW5jdGlvbiAoZmlsZU9iamVjdCkgewogICAgICAgICAgICB2YXIgbXVsdGlwbGUgPSBmYWxzZSwKICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gbnVsbCwKICAgICAgICAgICAgICAgIGFjdGlvblVybCA9IG51bGwsCiAgICAgICAgICAgICAgICBmaWxlVXBsb2FkUGF0aCA9IGZpbGVPYmplY3QuZmlsZVVwbG9hZFBhdGgsCiAgICAgICAgICAgICAgICB1dWlkOwoKICAgICAgICAgICAgaWYgKCFmaWxlVXBsb2FkUGF0aCkgewogICAgICAgICAgICAgICAgdXVpZCA9IGZpbGVPYmplY3QuX3V1aWRHZW5lcmF0b3IoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gaWYgdXVpZCBleGlzdHMgb25seSB0aGVuIHVwbG9hZCB0aGUgZmlsZSBpbiB0aGUgY3VycmVudCAgaW5zdGFuY2UKICAgICAgICAgICAgaWYgKF8uaXNPYmplY3QoZmlsZU9iamVjdCkgJiYgKGZpbGVVcGxvYWRQYXRoIHx8IHV1aWQpKSB7CiAgICAgICAgICAgICAgICB2YXIgZmlsZURvbSA9IGZpbGVPYmplY3QuZmlsZURvbSwKICAgICAgICAgICAgICAgICAgICAkZm9ybSA9ICQodGhpcy5vcHRpb25zLmlmcmFtZUNvbnRhaW5lcikuZmluZCgiLmZpbGVQcmV2aWV3Iik7CiAgICAgICAgICAgICAgICBmaWxlTmFtZSA9IGZpbGVPYmplY3QuZmlsZU5hbWU7CiAgICAgICAgICAgICAgICBtdWx0aXBsZSA9IGZpbGVPYmplY3QubXVsdGlwbGU7CiAgICAgICAgICAgICAgICBpZighZmlsZVVwbG9hZFBhdGgpIHsKICAgICAgICAgICAgICAgICAgICBmaWxlVXBsb2FkUGF0aCA9IHRoaXMub3B0aW9ucy5maWxlVXBsb2FkUGF0aCArICIvIiArIHV1aWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZmlsZURvbSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIC8vcHJlcGVuZCBjb250ZXh0cGF0aAogICAgICAgICAgICAgICAgICAgIGFjdGlvblVybCA9IGZpbGVPYmplY3QuX2dldFVybCArIGZpbGVVcGxvYWRQYXRoOwogICAgICAgICAgICAgICAgICAgIGlmICghbXVsdGlwbGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoZmlsZVVwbG9hZFBhdGgubGFzdEluZGV4T2YoZmlsZU9iamVjdC5fZ2V0VXJsLCAwKSA9PT0gMCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZmlsZVVybCA9IGZpbGVPYmplY3QuX2dldFVybCArIGZpbGVVcGxvYWRQYXRoICsgIi8iICsgZmlsZU5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbGVVcmwgPSBmaWxlVXBsb2FkUGF0aCArICIvIiArIGZpbGVOYW1lOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWxlVXJsID0gYWN0aW9uVXJsOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvLyBkb25lIHRvIHNvbHZlIGlzc3VlIExDLTU4MzUKICAgICAgICAgICAgICAgICAgICBpZigkZm9ybS5sZW5ndGggPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJGZvcm0gPSAkKCI8Zm9ybSBtZXRob2Q9J3Bvc3QnIGVuY3R5cGU9J211bHRpcGFydC9mb3JtLWRhdGEnLz4iKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZENsYXNzKCJmaWxlUHJldmlldyIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjcmVhdGUgaWQgc28gdGhhdCBpdCBkb2VzIG5vdCBpbnRlcmNlcHQgd2l0aCBvdGhlciBmb3JtcyBpbiB0aGUgcGFnZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkIDogImZvcm0iICsgbmV3IERhdGUoKS52YWx1ZU9mKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uIDogYWN0aW9uVXJsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCA6IHRoaXMub3B0aW9ucy5pZnJhbWVOYW1lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFwcGVuZFRvKHRoaXMub3B0aW9ucy5pZnJhbWVDb250YWluZXIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vLyBmaXJzdCBlbXB0eSBhbGwgY2hpbGRyZW4sIHVzaW5nIGRldGFjaCBzbyB0aGF0IGRhdGEgaXMgbm90IGNsZWFyCiAgICAgICAgICAgICAgICAgICAgICAgICRmb3JtLmNoaWxkcmVuKCkuZGV0YWNoKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdyB1cGRhdGUgdGhlIG5ldyBhdHRyaWJ1dGVzCiAgICAgICAgICAgICAgICAgICAgICAgICRmb3JtLmF0dHIoewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uIDogYWN0aW9uVXJsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0IDogdGhpcy5vcHRpb25zLmlmcmFtZU5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgZG9uZSBzbyB0aGF0IHRoZSBvdGhlciBldmVudHMgYXR0YWNoZWQgYXQgc29tZSBvdGhlciBsZXZlbCBpbiBET00gVHJlZSBkb24ndCBpbnRlcmZlcmUKICAgICAgICAgICAgICAgICAgICAkZm9ybS5vbmUoInN1Ym1pdCIsIGZ1bmN0aW9uKGV2bnQpewogICAgICAgICAgICAgICAgICAgICAgICBldm50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBuZXcgRm9ybURhdGEoKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKG11bHRpcGxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIF8uZWFjaChmaWxlRG9tLCBmdW5jdGlvbiAoZmlsZURvbUVsZW1lbnQsIGluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPT1RCLCB0aGlzIGNvZGUgaXMgc3RpbGwgdXNlZCBpbiBkYXNoYm9hcmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGZpbGVEb21FbGVtZW50ICE9PSBudWxsICYmICFfLmlzU3RyaW5nKGZpbGVEb21FbGVtZW50KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoZmlsZURvbUVsZW1lbnRbMF0pLmF0dHIoJ25hbWUnLCBmaWxlTmFtZVtpbmRleF0pLmFwcGVuZFRvKCRmb3JtKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWxlRG9tRWxlbWVudCBtaWdodCBjb250YWluIG11bHRpcGxlIGZpbGVzIHNvIGFsbCB0aGUgZmlsZXMgbmVlZHMgdG8gYmUgYWRkZWQgdG8gZm9ybWRhdGEuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRGaWxlTmFtZXMgPSBmaWxlTmFtZVtpbmRleF0uc3BsaXQoIlxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBmaWxlSW5kZXggPSAwOyBmaWxlSW5kZXggPCBjdXJyZW50RmlsZU5hbWVzLmxlbmd0aDsgZmlsZUluZGV4KyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5hcHBlbmQoY3VycmVudEZpbGVOYW1lc1tmaWxlSW5kZXhdLCBmaWxlRG9tRWxlbWVudFswXS5maWxlc1tmaWxlSW5kZXhdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVEb20uYXR0cignbmFtZScsIGZpbGVOYW1lKS5hcHBlbmRUbygkZm9ybSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEuYXBwZW5kKGZpbGVOYW1lLCBmaWxlRG9tWzBdLmZpbGVzWzBdKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8qIFVzZUNhc2U6IFN1cHBvc2UgdGhlIGZpbGVOYW1lIGlzIGluIG90aGVyIGxhbmd1YWdlLCBvbiBjbGljayBvZiBmaWxlTmFtZSwgaXQgdHJpZXMgdG8gdXBsb2FkIHRoZSBmaWxlCiAgICAgICAgICAgICAgICAgICAgIHNvIHRoYXQgaXQgY291bGQgYmUgcHJldmlldywgdGhpcyBjaGFuZ2Ugd291bGQgZW5zdXJlIHRoYXQgdGhlIGZpbGUgaXMgcHJvcGVybHkgcHJldmlld2VkIHN1cHBvcnRpbmcKICAgICAgICAgICAgICAgICAgICAgdGhlIGdpdmVuIFVURi04IGNoYXJzZXQgKi8KICAgICAgICAgICAgICAgICAgICAkKCI8aW5wdXQgdHlwZT0naGlkZGVuJyBuYW1lPSdfY2hhcnNldF8nIHZhbHVlPSdVVEYtOCcvPiIpLmFwcGVuZFRvKCRmb3JtKTsKICAgICAgICAgICAgICAgICAgICBkYXRhLmFwcGVuZCgiX2NoYXJzZXRfIiwgIlVURi04Iik7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFtdWx0aXBsZSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbGVNYXBbdGhpcy5maWxlVXJsXSA9IHRoaXMuJGVsZW1lbnQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpczsKICAgICAgICAgICAgICAgICAgICAkLmFqYXgoewogICAgICAgICAgICAgICAgICAgICAgICB1cmw6ICRmb3JtLmF0dHIoImFjdGlvbiIpLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBjYWNoZTogZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0RhdGE6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJywKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ1BPU1QnLAogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbihkYXRhKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbXVsdGlwbGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmhhbmRsZVNpbmdsZUZpbGVVcGxvYWQoZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuaGFuZGxlTXVsdGlwbGVGaWxlVXBsb2FkKGRhdGEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoImFkb2JlRmlsZVVwbG9hZGVyLmZpbGVVcGxvYWRGYWlsZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzLmZpbGVVcmw7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlTXVsdGlwbGVGaWxlVXBsb2FkOiBmdW5jdGlvbiAoZGF0YSkgewogICAgICAgICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoImFkb2JlRmlsZVVwbG9hZGVyLm11bHRpcGxlRmlsZVVwbG9hZGVkIik7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RmlsZVVybDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5maWxlVXJsOwogICAgICAgIH0sCgogICAgICAgIGdldFVybENvbnRlbnRzRnJvbVVwbG9hZERhdGE6IGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgICAgIHZhciB0ZW1wOwogICAgICAgICAgICBpZihkYXRhICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHRlbXAgPSAkKGRhdGEpLmZpbmQoIiNDaGFuZ2VMb2ciKS50ZXh0KCkuc3BsaXQoImJyIiwgMilbMV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0b3IgPSB0aGlzLm9wdGlvbnMuaWZyYW1lQ29udGFpbmVyICsgIiBpZnJhbWVbbmFtZT0nIiArIHRoaXMub3B0aW9ucy5pZnJhbWVOYW1lICsgIiddIjsKICAgICAgICAgICAgICAgIHRlbXAgPSAkKHNlbGVjdG9yKS5jb250ZW50cygpLmZpbmQoIiNDaGFuZ2VMb2ciKS50ZXh0KCkuc3BsaXQoImJyIiwgMilbMV07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIHRlbXAgPSB0ZW1wLnN1YnN0cmluZyh0ZW1wLmluZGV4T2YoImNyZWF0ZWQiKSArIDksIHRlbXAuaW5kZXhPZigiOzwiKSk7CiAgICAgICAgICAgIHRlbXAgPSB0ZW1wLnN1YnN0cmluZygwLCB0ZW1wLmxlbmd0aCAtIDIpOwogICAgICAgICAgICB2YXIgaW5kZXggPSB0ZW1wLmluZGV4T2YoIi9qY3I6Y29udGVudCIpOwogICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKQogICAgICAgICAgICAgICAgdGVtcCA9IHRlbXAuc3Vic3RyaW5nKDAsIGluZGV4KTsKICAgICAgICAgICAgcmV0dXJuIHRlbXA7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlU2luZ2xlRmlsZVVwbG9hZDogZnVuY3Rpb24gKGRhdGEpIHsKICAgICAgICAgICAgdmFyIHVybCA9IHRoaXMuZ2V0VXJsQ29udGVudHNGcm9tVXBsb2FkRGF0YShkYXRhKTsKCiAgICAgICAgICAgIC8vcHJlcGVuZCBjb250ZXh0IHBhdGgKICAgICAgICAgICAgdXJsID0gdGhpcy5vcHRpb25zLl9nZXRVcmwgKyB1cmw7CiAgICAgICAgICAgIGlmICh1cmwgaW4gdGhpcy5maWxlTWFwKSB7CiAgICAgICAgICAgICAgICB0aGlzLmZpbGVNYXBbdXJsXS50cmlnZ2VyKCJhZG9iZUZpbGVVcGxvYWRlci5maWxlVXBsb2FkZWQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgLy8gUHV0IGlmcmFtZSBpbnNpZGUgdGhlIGlmcmFtZSBjb250YWluZXIKICAgICAgICAgICAgLy8gT24gdGhlIGxvYWQgb2YgaWZyYW1lLCBkaXNwbGF5IHRoZSBjb250ZW50cyBvZiBmaWxlCiAgICAgICAgICAgIC8vIHNpbmNlIHRoZXJlIGlzIG9ubHkgb25lIGlmcmFtZSBmb3IgYWxsIHRoZSBmaWxlIGF0dGFjaG1lbnRzLCB0aGVyZSBtYXkgYmUgcmFjZSBjb25kaXRpb24KICAgICAgICAgICAgaWYgKHRoaXMuJGlmcmFtZSA9PSBudWxsIHx8IHRoaXMuJGlmcmFtZS5sZW5ndGggPT09IDApIHsKICAgICAgICAgICAgICAgIHRoaXMuJGlmcmFtZSA9IHRoaXMuZmlsZUlmcmFtZSh0aGlzLm9wdGlvbnMuaWZyYW1lTmFtZSkuYXBwZW5kVG8odGhpcy5vcHRpb25zLmlmcmFtZUNvbnRhaW5lcik7CiAgICAgICAgICAgICAgICAvLyBzaW5jZSB0aGVyZSBpcyBvbmx5IGlmcmFtZSBmb3IgdGhlIHByZXZpZXcgb2YgYWxsIGZpbGUgYXR0YWNobWVudHMKICAgICAgICAgICAgICAgIC8vIHRoaXMgbWFwIGlzIGFkZGVkIGluIHRoZSBjbG9zdXJlIHNjb3BlCiAgICAgICAgICAgICAgICAvLyBtYXAgY29udGFpbnMgdGhlIHVybChrZXkpIHZzIGZpbGVEb21FbGVtZW50KHZhbHVlKQogICAgICAgICAgICAgICAgLy8gaXQgaGVscHMgYXZvaWRzIHRoZSByYWNlIGNvbmRpdGlvbgogICAgICAgICAgICAgICAgdGhpcy5maWxlTWFwID0ge307CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwoKICAgICQuZm4uYWRvYmVGaWxlVXBsb2FkZXIgPSBmdW5jdGlvbiAob3B0aW9uLCB2YWx1ZSkgewogICAgICAgIHZhciBnZXQgPSAnJywKICAgICAgICAgICAgZWxlbWVudCA9IHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAvLyBpbiBjYXNlIG9mIGlucHV0IHR5cGUgZmlsZQogICAgICAgICAgICAgICAgaWYgKCQodGhpcykuYXR0cigndHlwZScpID09PSAnZmlsZScpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpLAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gJHRoaXMuZGF0YSgnYWRvYmVGaWxlVXBsb2FkZXInKSwKICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBBZG9iZUZpbGVVcGxvYWRlci5wcm90b3R5cGUuZGVmYXVsdHMob3B0aW9uLCB2YWx1ZSksIHR5cGVvZiBvcHRpb24gPT09ICdvYmplY3QnICYmIG9wdGlvbik7CgogICAgICAgICAgICAgICAgICAgIC8vIFNhdmUgdGhlIGFkb2JlRmlsZUF0dGFjaG1lbnQgZGF0YSBpbiBqcXVlcnkKICAgICAgICAgICAgICAgICAgICBpZiAoIWRhdGEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJHRoaXMuZGF0YSgnYWRvYmVGaWxlVXBsb2FkZXInLCAoZGF0YSA9IG5ldyBBZG9iZUZpbGVVcGxvYWRlcih0aGlzLCBvcHRpb25zKSkpOwogICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmluaXRpYWxpemUoKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAvLyB1cGRhdGUgZWxlbWVudHMgaWYgbm90IGVxdWFsLCBzaW5jZSBzb21ldGltZXMgb25lIGNhbiBjbG9uZSB0b28KICAgICAgICAgICAgICAgICAgICAgICAgaWYoZGF0YS4kZWxlbWVudC5nZXQoMCkgIT09IHRoaXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEuJGVsZW1lbnQgPSAkKHRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBjb2RlIHRvIGdldCBhbmQgc2V0IGFuIG9wdGlvbgogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb3B0aW9uID09PSAnc3RyaW5nJykgewogICAgICAgICAgICAgICAgICAgICAgICBnZXQgPSBkYXRhW29wdGlvbl0odmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CgogICAgICAgIGlmICh0eXBlb2YgZ2V0ICE9PSAndW5kZWZpbmVkJykgewogICAgICAgICAgICByZXR1cm4gZ2V0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBlbGVtZW50OwogICAgICAgIH0KICAgIH07CgoKICAgIEFkb2JlRmlsZVVwbG9hZGVyLnByb3RvdHlwZS5kZWZhdWx0cyA9IGZ1bmN0aW9uIChvcHRpb25zLHZhbHVlKSAgewogICAgICAgIHZhciBwcm9wZXJ0eU9iamVjdCA9IHt9OwogICAgICAgIGlmKHR5cGVvZiBvcHRpb25zID09ICdvYmplY3QnKSB7CiAgICAgICAgICAgIHByb3BlcnR5T2JqZWN0Ll9maWxlSWZyYW1lTmFtZSA9IG9wdGlvbnMuX2ZpbGVJZnJhbWVOYW1lOwogICAgICAgICAgICBwcm9wZXJ0eU9iamVjdC5fZmlsZVBhdGggPSBvcHRpb25zLl9maWxlUGF0aDsKICAgICAgICAgICAgcHJvcGVydHlPYmplY3QuYWN0aW9uVXJsID0gb3B0aW9ucy5hY3Rpb25Vcmw7CiAgICAgICAgICAgIHByb3BlcnR5T2JqZWN0Ll9nZXRVcmwgPSBvcHRpb25zLl9nZXRVcmw7CiAgICAgICAgfQogICAgICAgIGlmKHR5cGVvZiAgdmFsdWUgPT0gJ29iamVjdCcpIHsKICAgICAgICAgICAgcHJvcGVydHlPYmplY3QuX2ZpbGVJZnJhbWVOYW1lID0gdmFsdWUuX2ZpbGVJZnJhbWVOYW1lOwogICAgICAgICAgICBwcm9wZXJ0eU9iamVjdC5fZmlsZVBhdGggPSB2YWx1ZS5fZmlsZVBhdGg7CiAgICAgICAgICAgIHByb3BlcnR5T2JqZWN0LmFjdGlvblVybCA9IHZhbHVlLmFjdGlvblVybDsKICAgICAgICAgICAgcHJvcGVydHlPYmplY3QuX2dldFVybCA9IG9wdGlvbnMuX2dldFVybDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgJ2ZpbGVVcGxvYWRQYXRoJzogcHJvcGVydHlPYmplY3QuX2ZpbGVQYXRoIHx8IEFkb2JlRmlsZVVwbG9hZGVyLnByb3RvdHlwZS5fZmlsZVBhdGgsCiAgICAgICAgICAgICdpZnJhbWVOYW1lJzogQWRvYmVGaWxlVXBsb2FkZXIucHJvdG90eXBlLl9maWxlSWZyYW1lTmFtZSArIG5ldyBEYXRlKCkudmFsdWVPZigpLAogICAgICAgICAgICAnZmlsZVVwbG9hZFNlcnZsZXQnOiBwcm9wZXJ0eU9iamVjdC5fZmlsZVBhdGggfHwgQWRvYmVGaWxlVXBsb2FkZXIucHJvdG90eXBlLl9maWxlUGF0aCwKICAgICAgICAgICAgJ2lmcmFtZUNvbnRhaW5lcic6IHByb3BlcnR5T2JqZWN0Ll9pZnJhbWVDb250YWluZXIgfHwgQWRvYmVGaWxlVXBsb2FkZXIucHJvdG90eXBlLl9pZnJhbWVDb250YWluZXIsCiAgICAgICAgICAgICdfZ2V0VXJsJzogcHJvcGVydHlPYmplY3QuX2dldFVybCB8fCAiIgogICAgICAgIH07CiAgICB9OwoKfSkoJCwgd2luZG93Ll8pOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTMgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCihmdW5jdGlvbihfLHhmYWxpYikgewogICAgdmFyIENvbnN0YW50cyA9IHsKICAgICAgICBhY2Nlc3NWYWx1ZXMgOiBbIm9wZW4iLCJwcm90ZWN0ZWQiLCJyZWFkT25seSIsIm5vbkludGVyYWN0aXZlIl0sCiAgICAgICAgcHJlc2VuY2VWYWx1ZXMgOiBbInZpc2libGUiLCAiaGlkZGVuIiwiaW5hY3RpdmUiLCJpbnZpc2libGUiXSwKICAgICAgICBpdGVtU2F2ZVZhbHVlcyA6IFswLDFdLAogICAgICAgIHZhbHVlT3ZlcnJpZGVWYWx1ZXMgOiBbMCwxXSwKICAgICAgICBvbmVPZkNoaWxkIDoge3R5cGU6ICJvbmVPZkNoaWxkIiwgbWluOjAsIG1heDoxfSwKICAgICAgICB6ZXJvT3JNb3JlIDoge3R5cGU6ICJ6ZXJvT3JNb3JlIixtaW46MCwgbWF4OkluZmluaXR5fSwKICAgICAgICB6ZXJvT3JPbmUgOiB7dHlwZTogInplcm9Pck9uZSIsbWluOjAsIG1heDoxfSwKICAgICAgICB6ZXJvT3JUd28gOiB7dHlwZTogInplcm9PclR3byIsIG1pbjowLCBtYXg6Mn0sCiAgICAgICAgemVyb09yRm91ciA6IHt0eXBlOiAiemVyb09yRm91ciIsIG1pbjowLCBtYXg6NH0sCiAgICAgICAgb25lT3JNb3JlIDoge3R5cGU6ICJvbmVPck1vcmUiLCBtaW46MSwgbWF4OkluZmluaXR5fSwKCiAgICAgICAgZW5jcnlwdERhdGFPcGVyYXRpb25WYWx1ZXMgOiBbImVuY3J5cHQiLCAiZGVjcnlwdCJdLAogICAgICAgIHJlcXVpcmVkVHlwZVZhbHVlcyA6IFsib3B0aW9uYWwiLCAicmVxdWlyZWQiXSwKICAgICAgICBkYXRhVmFsdWVzIDogWyJsaW5rIiwgImVtYmVkIl0sCiAgICAgICAgaFNjcm9sbFBvbGljeVZhbHVlcyA6IFsiYXV0byIsICJvZmYiLCAib24iXSwKICAgICAgICBkaXNhYmxlQWxsVmFsdWVzIDogWyIwIiwgIjEiXSwKICAgICAgICBmb3JtYXRUZXN0VmFsdWVzIDogWyJ3YXJuaW5nIiwgImRpc2FibGVkIiwgImVycm9yIl0sCiAgICAgICAgbnVsbFRlc3RWYWx1ZXMgOiBbImRpc2FibGVkIiwgImVycm9yIiwgIndhcm5pbmciIF0sCiAgICAgICAgc2NyaXB0VGVzdFZhbHVlcyA6IFsiZXJyb3IiLCAiZGlzYWJsZWQiLCAid2FybmluZyJdLAogICAgICAgIGFmdGVyVmFsdWVzIDogWyJhdXRvIiwgImNvbnRlbnRBcmVhIiwgInBhZ2VBcmVhIiwgInBhZ2VFdmVuIiwgInBhZ2VPZGQiXSwKICAgICAgICBiZWZvcmVWYWx1ZXMgOiBbImF1dG8iLCAiY29udGVudEFyZWEiLCAicGFnZUFyZWEiLCAicGFnZUV2ZW4iLCAicGFnZU9kZCJdLAogICAgICAgIHN0YXJ0TmV3VmFsdWVzIDogWyIwIiwgIjEiXSwKICAgICAgICBjaXJjdWxhclZhbHVlcyA6IFsiMCIsICIxIl0sCiAgICAgICAgaGFuZFZhbHVlcyA6IFsiZXZlbiIsICJsZWZ0IiwgInJpZ2h0Il0sCiAgICAgICAgaGlnaGxpZ2h0VmFsdWVzIDogWyJpbnZlcnRlZCIsICJub25lIiwgIm91dGxpbmUiLCAicHVzaCJdLAogICAgICAgIGFjdGl2aXR5VmFsdWVzIDogWyJjbGljayIsICJjaGFuZ2UiLCAiZG9jQ2xvc2UiLCAiZG9jUmVhZHkiLCAiZW50ZXIiLAogICAgICAgICAgICAiZXhpdCIsICJmdWxsIiwgImluZGV4Q2hhbmdlIiwgImluaXRpYWxpemUiLAogICAgICAgICAgICAibW91c2VEb3duIiwgIm1vdXNlRW50ZXIiLCAibW91c2VFeGl0IiwgIm1vdXNlVXAiLAogICAgICAgICAgICAicG9zdEV4ZWN1dGUiLCAicG9zdE9wZW4iLCAicG9zdFByaW50IiwgInBvc3RTYXZlIiwKICAgICAgICAgICAgInBvc3RTaWduIiwgInBvc3RTdWJtaXQiLCAicHJlRXhlY3V0ZSIsICJwcmVPcGVuIiwKICAgICAgICAgICAgInByZVByaW50IiwgInByZVNhdmUiLCAicHJlU2lnbiIsICJwcmVTdWJtaXQiLAogICAgICAgICAgICAicmVhZHkiLCAidmFsaWRhdGlvblN0YXRlIl0sCiAgICAgICAgbGlzdGVuVmFsdWVzIDogWyJyZWZPbmx5IiwgInJlZkFuZERlc2NlbmRlbnRzIl0sCiAgICAgICAgYnJlYWtWYWx1ZXMgOiBbImNsb3NlIiwgIm9wZW4iXSwKICAgICAgICB0YXJnZXRUeXBlVmFsdWVzIDogWyJhdXRvIiwgImNvbnRlbnRBcmVhIiwgInBhZ2VBcmVhIiwgInBhZ2VFdmVuIiwgInBhZ2VPZGQiXSwKICAgICAgICBzaWduVHlwZVZhbHVlcyA6IFsiUERGMS4zIiwgIlBERjEuNiJdLAogICAgICAgIHNpZ25EYXRhT3BlcmF0aW9uVmFsdWVzIDogWyJzaWduIiwgImNsZWFyIiwgInZlcmlmeSJdLAogICAgICAgIGFzcGVjdFZhbHVlcyA6IFsiZml0IiwgImFjdHVhbCIsICJoZWlnaHQiLCAibm9uZSIsICJ3aWR0aCJdLAogICAgICAgIHRyYW5zZmVyRW5jb2RpbmdWYWx1ZXMgOiBbIm5vbmUiLCAicGFja2FnZSIsICJiYXNlNjQiXSwKICAgICAgICBtYW5pZmVzdEFjdGlvblZhbHVlcyA6IFsiaW5jbHVkZSIsICJhbGwiLCAiZXhjbHVkZSJdLAogICAgICAgIHRyYXZlcnNlRGVsZWdhdGVWYWx1ZXMgOiBbIjAiLCAiMSJdLAogICAgICAgIHRyYXZlcnNlT3BlcmF0aW9uVmFsdWVzIDogWyJuZXh0IiwgImJhY2siLCAiZG93biIsICJmaXJzdCIsICJsZWZ0IiwgInJpZ2h0IiwgInVwIl0sCiAgICAgICAgc2xvcGVWYWx1ZXMgOiBbIlxcIiwgIi8iXSwKICAgICAgICBleGNsdWRlQWxsQ2Fwc1ZhbHVlcyA6IFsiMCIsICIxIl0sCiAgICAgICAgZXhjbHVkZUluaXRpYWxDYXBWYWx1ZXMgOiBbIjAiLCAiMSJdLAogICAgICAgIGh5cGhlbmF0ZVZhbHVlcyA6IFsiMCIsICIxIl0sCiAgICAgICAgYWxsb3dOZXV0cmFsVmFsdWVzIDogWyIwIiwgIjEiXSwKICAgICAgICBtYXJrVmFsdWVzIDogWyJkZWZhdWx0IiwgImNoZWNrIiwgImNpcmNsZSIsICJjcm9zcyIsICJkaWFtb25kIiwgInNxdWFyZSIsICJzdGFyIl0sCiAgICAgICAgc2hhcGVWYWx1ZXMgOiBbInNxdWFyZSIsICJyb3VuZCJdLAogICAgICAgIGNvbW1pdE9uVmFsdWVzIDogWyAic2VsZWN0IiwgImV4aXQiXSwKICAgICAgICBvcGVuVmFsdWVzIDogWyJ1c2VyQ29udHJvbCIsICJhbHdheXMiLCAibXVsdGlTZWxlY3QiLCAib25FbnRyeSIgXSwKICAgICAgICB0ZXh0RW50cnlWYWx1ZXMgOiBbIjAiLCAiMSJdLAogICAgICAgIGxpbmVhclR5cGVWYWx1ZXMgOiBbInRvUmlnaHQiLCAidG9Cb3R0b20iLCAidG9MZWZ0IiwgInRvVG9wIl0sCiAgICAgICAgZWRnZUNhcFZhbHVlcyA6IFsic3F1YXJlIiwgImJ1dHQiLCAicm91bmQiXSwKICAgICAgICBzdHJva2VWYWx1ZXMgOiBbInNvbGlkIiwgImRhc2hEb3QiLCAiZGFzaERvdERvdCIsICJkYXNoZWQiLCAiZG90dGVkIiwgImVtYm9zc2VkIiwgImV0Y2hlZCIsICJsb3dlcmVkIiwgInJhaXNlZCJdLAogICAgICAgIGNvcm5lckludmVydGVkVmFsdWVzIDogWyIwIiwgIjEiXSwKICAgICAgICBjb3JuZXJKb2luVmFsdWVzIDogWyJzcXVhcmUiLCJyb3VuZCJdLAogICAgICAgIHNwZWFrRGlzYWJsZVZhbHVlcyA6IFsiMCIsICIxIl0sCiAgICAgICAgc3BlYWtQcmlvcml0eVZhbHVlcyA6IFsgImN1c3RvbSIsICJjYXB0aW9uIiwgIm5hbWUiLCAidG9vbFRpcCJdLAogICAgICAgIGNhcHRpb25QbGFjZW1lbnRWYWx1ZXMgOiBbImxlZnQiLCAiYm90dG9tIiwgImlubGluZSIsICJyaWdodCIsICJ0b3AiXSwKICAgICAgICBvcmllbnRhdGlvblZhbHVlcyA6IFsicG9ydHJhaXQiLCAibGFuZHNjYXBlIl0sCiAgICAgICAgbWVkaXVtVHJheUluVmFsdWVzIDogWyJhdXRvIiwgImRlbGVnYXRlIiwgInBhZ2VGcm9udCJdLAogICAgICAgIG1lZGl1bVRyYXlPdXRWYWx1ZXMgOiBbImF1dG8iLCAiZGVsZWdhdGUiXSwKICAgICAgICBwYXR0ZXJuVHlwZVZhbHVlcyA6IFsiY3Jvc3NIYXRjaCIsICJjcm9zc0RpYWdvbmFsIiwgImRpYWdvbmFsTGVmdCIsICJkaWFnb25hbFJpZ2h0IiwgImhvcml6b250YWwiLCAidmVydGljYWwiXSwKICAgICAgICBrZWVwSW50YWN0VmFsdWVzIDogWyJub25lIiwgImNvbnRlbnRBcmVhIiwgInBhZ2VBcmVhIl0sCiAgICAgICAga2VlcE5leHRWYWx1ZXMgOiBbIm5vbmUiLCAiY29udGVudEFyZWEiLCAicGFnZUFyZWEiXSwKICAgICAgICBrZWVwUHJldmlvdXNWYWx1ZXMgOiBbIm5vbmUiLCAiY29udGVudEFyZWEiLCAicGFnZUFyZWEiXSwKICAgICAgICBwYXNzVGhyb3VnaFZhbHVlcyA6IFsiMCIsICIxIl0sCiAgICAgICAgYWxsb3dSaWNoVGV4dFZhbHVlcyA6IFsiMCIsICIxIl0sCiAgICAgICAgbXVsdGlMaW5lVmFsdWVzIDogWyIxIiwgIjAiXSwKICAgICAgICB2U2Nyb2xsUG9saWN5VmFsdWVzIDogWyJhdXRvIiwgIm9mZiIsICJvbiJdLAogICAgICAgIGtlcm5pbmdNb2RlVmFsdWVzIDogWyJub25lIiwgInBhaXIiXSwKICAgICAgICBsaW5lVGhyb3VnaFZhbHVlcyA6IFsiMCIsICIxIiwgIjIiXSwKICAgICAgICBsaW5lVGhyb3VnaFBlcmlvZFZhbHVlcyA6IFsiYWxsIiwgIndvcmQiXSwKICAgICAgICBmb250T3ZlcmxpbmVWYWx1ZXMgOiBbIjAiLCAiMSIsICIyIl0sCiAgICAgICAgZm9udE92ZXJsaW5lUGVyaW9kVmFsdWVzIDogWyJhbGwiLCAid29yZCJdLAogICAgICAgIHBvc3R1cmVWYWx1ZXMgOiBbIm5vcm1hbCIsICJpdGFsaWMiXSwKICAgICAgICB1bmRlcmxpbmVWYWx1ZXMgOiBbIjAiLCAiMSIsICIyIl0sCiAgICAgICAgdW5kZXJsaW5lUGVyaW9kVmFsdWVzIDogWyJhbGwiLCAid29yZCJdLAogICAgICAgIGZvbnRXZWlnaHRWYWx1ZXMgOiBbIm5vcm1hbCIsICJib2xkIl0sCiAgICAgICAgY2hlY2tzdW1WYWx1ZXMgOiBbIm5vbmUiLCAiMW1vZDEwIiwgIjFtb2QxMF8xbW9kMTEiLCAiMm1vZDEwIiwgImF1dG8iXSwKICAgICAgICBkYXRhUHJlcFZhbHVlcyA6IFsibm9uZSIsICJmbGF0ZUNvbXByZXNzIl0sCiAgICAgICAgcHJpbnRDaGVja0RpZ2l0VmFsdWVzIDogWyIwIiwgIjEiXSwKICAgICAgICB0ZXh0TG9jYXRpb25WYWx1ZXMgOiBbImJlbG93IiwgImJlbG93RW1iZWRkZWQiLCAibm9uZSIsICJhYm92ZSIsICJhYm92ZUVtYmVkZGVkIl0sCiAgICAgICAgdHJ1bmNhdGVWYWx1ZXMgOiBbIjAiLCAiMSJdLAogICAgICAgIHVwc01vZGVWYWx1ZXMgOiBbInVzQ2FycmllciIsICJpbnRlcm5hdGlvbmFsQ2FycmllciIsICJzZWN1cmVTeW1ib2wiLCAic3RhbmRhcmRTeW1ib2wiXSwKICAgICAgICBtZHBQZXJtaXNzaW9uc1ZhbHVlcyA6IFsiMiIsICIxIiwgIjMiXSwKICAgICAgICBtZHBTaWduYXR1cmVUeXBlVmFsdWVzIDogWyJmaWxsZXIiLCAiYXV0aG9yIl0sCiAgICAgICAgY29ubmVjdFVzYWdlVmFsdWVzIDogWyJleHBvcnRBbmRJbXBvcnQiLCAiZXhwb3J0T25seSIsICJpbXBvcnRPbmx5Il0sCiAgICAgICAgcmFkaWFsVHlwZVZhbHVlcyA6IFsidG9FZGdlIiwgInRvQ2VudGVyIl0sCiAgICAgICAgY3JlZGVudGlhbFNlcnZlclBvbGljeVZhbHVlcyA6IFsib3B0aW9uYWwiLCAicmVxdWlyZWQiXSwKICAgICAgICBkYXRlVGltZUVkaXRQaWNrZXJWYWx1ZXMgOiBbImhvc3QiLCAibm9uZSJdLAogICAgICAgIGJpbmRNYXRjaFZhbHVlcyA6IFsib25jZSIsICJkYXRhUmVmIiwgImdsb2JhbCIsICJub25lIl0sCiAgICAgICAgcnVuQXRWYWx1ZXMgOiBbImNsaWVudCIsICJib3RoIiwgInNlcnZlciJdLAogICAgICAgIHN0YXRlbGVzc1ZhbHVlcyA6IFsiMCIsICIxIl0sCiAgICAgICAgZXhlY3V0ZVR5cGVWYWx1ZXMgOiBbImltcG9ydCIsICJyZW1lcmdlIl0sCiAgICAgICAgY2FsY092ZXJyaWRlVmFsdWVzIDogWyJkaXNhYmxlZCIsICJlcnJvciIsICJpZ25vcmUiLCAid2FybmluZyIgXSwKICAgICAgICBlbWJlZFBERlZhbHVlcyA6IFsiMCIsICIxIl0sCiAgICAgICAgc3VibWl0Rm9ybWF0VmFsdWVzIDogWyJ4ZHAiLCAiZm9ybWRhdGEiLCAicGRmIiwgInVybGVuY29kZWQiLCAieGZkIiwgInhtbCIgXSwKICAgICAgICBzZXRSZWxhdGlvblZhbHVlcyA6IFsib3JkZXJlZCIgLCAiY2hvaWNlIiAsICJ1bm9yZGVyZWQiXSwKICAgICAgICBmaXJzdFRyYXZlcnNhbCA6ICJmaXJzdCIsCiAgICAgICAgbmV4dFRyYXZlcnNhbCA6ICJuZXh0IiwKICAgICAgICBTY3JpYmJsZUltYWdlRmllbGQgOiAiU2NyaWJibGVJbWFnZUZpZWxkIiwKICAgICAgICBzY3JpYmJsZUNoYW5nZUV2ZW50IDogInNjcmliYmxlQ2hhbmdlIiwKICAgICAgICBjYWxlbmRhckljb25NYXhXaWR0aCA6IDQwCgogICAgfTsKICAgIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMgPSBDb25zdGFudHM7Cn0pKF8seGZhbGliKTsKKGZ1bmN0aW9uKF8sIHhmYWxpYil7Cgp2YXIgWGZhVGVtcGxhdGVTY2hlbWEgPSB7fTsKCnZhciBUZW1wbGF0ZVNjaGVtYSA9IHhmYWxpYi50ZW1wbGF0ZS5UZW1wbGF0ZVNjaGVtYSA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewogICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciBlbGVtID0gbnVsbDsKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZmllbGQiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsiYWNjZXNzIix4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmFjY2Vzc1ZhbHVlcywwXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJoIiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbInciLCJtZWFzdXJlbWVudCIsMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsieCIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJ5IiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbInByZXNlbmNlIix4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnByZXNlbmNlVmFsdWVzLDBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJyZWxldmFudCIsICJzdHJpbmciLCAiIiBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbImxvY2FsZSIsInN0cmluZyIsImVuX1VTIl0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJpdGVtcyIsInplcm9PclR3byJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbImV4dHJhcyIsInplcm9Pck9uZSJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbImRlc2MiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJldmVudCIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJ2YWx1ZSIsInplcm9Pck9uZSJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbInVpIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsiYXNzaXN0IiwiemVyb09yT25lIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsiYm9yZGVyIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsicGFyYSIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbImNhcHRpb24iLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJ2YWxpZGF0ZSIsInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsibWFyZ2luIiwgInplcm9Pck9uZSJdICwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyJmb250IiwgInplcm9Pck9uZSJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbImNhbGN1bGF0ZSIsInplcm9Pck9uZSJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbImZvcm1hdCIsInplcm9Pck9uZSJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbImJpbmRJdGVtcyIsInplcm9Pck1vcmUiXQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiYXJlYSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJ4IiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICBbInkiLCJtZWFzdXJlbWVudCIsMF0sCiAgICAgICAgICAgIFsicmVsZXZhbnQiLCAic3RyaW5nIiwgIiIgXSwKICAgICAgICAgICAgWyJuYW1lIiwic3RyaW5nIiwiIl0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJkZXNjIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiZmllbGQiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZHJhdyIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJleGNsR3JvdXAiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiaW5zdGFuY2VNYW5hZ2VyIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImFyZWEiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsic3ViZm9ybSIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJzdWJmb3JtU2V0IiwiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJzdWJmb3JtU2V0Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInJlbGF0aW9uIix4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnNldFJlbGF0aW9uVmFsdWVzLDBdLAogICAgICAgICAgICBbInJlbGV2YW50Iiwic3RyaW5nIiwiIl0sCiAgICAgICAgICAgIFsibmFtZSIsInN0cmluZyIsIiJdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiYm9va2VuZCIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbImJyZWFrIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiZGVzYyIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbImV4dHJhcyIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbIm9jY3VyIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsib3ZlcmZsb3ciLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJicmVha0FmdGVyIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImJyZWFrQmVmb3JlIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImluc3RhbmNlTWFuYWdlciIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJzdWJmb3JtIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbInN1YmZvcm1TZXQiLCJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImNvbnRlbnRBcmVhIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXSwKICAgICAgICAgICAgWyJoIiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICBbInciLCJtZWFzdXJlbWVudCIsMF0sCiAgICAgICAgICAgIFsieCIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgWyJyZWxldmFudCIsICJzdHJpbmciLCAiIiBdLAogICAgICAgICAgICBbInkiLCJtZWFzdXJlbWVudCIsMF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJkZXNjIiwiemVyb09yT25lIl0KICAgICAgICBdKTsKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImRhdGUiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsibmFtZSIsInN0cmluZyIsIiJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJkZWNpbWFsIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXSwKICAgICAgICAgICAgWyJsZWFkRGlnaXRzIiwiaW50ZWdlciIsLTFdLAogICAgICAgICAgICBbImZyYWNEaWdpdHMiLCJpbnRlZ2VyIiwyXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZHJhdyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJoIiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICBbInciLCJtZWFzdXJlbWVudCIsMF0sCiAgICAgICAgICAgIFsieCIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgWyJ5IiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICBbInByZXNlbmNlIix4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnByZXNlbmNlVmFsdWVzLDBdLAogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXSwKICAgICAgICAgICAgWyJhY2Nlc3MiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmFjY2Vzc1ZhbHVlcywgMF0sICAvLyBUT0RPIDogZml4IHNjaGVtYSB2aW9sYXRpb24KICAgICAgICAgICAgWyJyZWxldmFudCIsICJzdHJpbmciLCAiIiBdLAogICAgICAgICAgICBbImxvY2FsZSIsInN0cmluZyIsImVuX1VTIl0KCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZXh0cmFzIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiZGVzYyIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbInZhbHVlIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsidWkiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJib3JkZXIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJmb250IiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsicGFyYSIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImNhcHRpb24iLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJhc3Npc3QiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJmb250IiwgInplcm9Pck9uZSJdLAogICAgICAgICAgICBbIm1hcmdpbiIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZXhjbEdyb3VwIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImFjY2VzcyIseGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5hY2Nlc3NWYWx1ZXMsMF0sCiAgICAgICAgICAgIFsiaCIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgWyJ3IiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICBbIngiLCJtZWFzdXJlbWVudCIsMF0sCiAgICAgICAgICAgIFsieSIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgWyJyZWxldmFudCIsICJzdHJpbmciLCAiIiBdLAogICAgICAgICAgICBbInByZXNlbmNlIix4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnByZXNlbmNlVmFsdWVzLDBdLAogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbImRlc2MiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJmaWVsZCIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJhc3Npc3QiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJib3JkZXIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJwYXJhIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiY2FwdGlvbiIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbInZhbGlkYXRlIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsibWFyZ2luIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJmbG9hdCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJuYW1lIiwic3RyaW5nIiwiIl0KICAgICAgICBdKTsKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImludGVnZXIiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsibmFtZSIsInN0cmluZyIsIiJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJpdGVtcyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJzYXZlIix4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLml0ZW1TYXZlVmFsdWVzLDBdLAogICAgICAgICAgICBbInByZXNlbmNlIix4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnByZXNlbmNlVmFsdWVzLDBdLAogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbInRleHQiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiaW50ZWdlciIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJkYXRlIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImRlY2ltYWwiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZmxvYXQiLCJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbIm9jY3VyIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImluaXRpYWwiLCJpbnRlZ2VyIiwxXSwKICAgICAgICAgICAgWyJtYXgiLCJpbnRlZ2VyIiwxXSwKICAgICAgICAgICAgWyJtaW4iLCJpbnRlZ2VyIiwxXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJwYWdlQXJlYSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJyZWxldmFudCIsICJzdHJpbmciLCAiIiBdLAogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbIm9jY3VyIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiZXh0cmFzIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiZGVzYyIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbImFyZWEiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZmllbGQiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZHJhdyIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJleGNsR3JvdXAiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiaW5zdGFuY2VNYW5hZ2VyIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbInN1YmZvcm0iLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiY29udGVudEFyZWEiLCJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsicGFnZVNldCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJyZWxldmFudCIsICJzdHJpbmciLCAiIiBdLAogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbIm9jY3VyIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiZXh0cmFzIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsicGFnZUFyZWEiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsicGFnZVNldCIsInplcm9Pck1vcmUiXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsic3ViZm9ybSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJhY2Nlc3MiLHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuYWNjZXNzVmFsdWVzLDBdLAogICAgICAgICAgICBbImgiLCJtZWFzdXJlbWVudCIsMF0sCiAgICAgICAgICAgIFsidyIsIm1lYXN1cmVtZW50IiwwXSwKICAgICAgICAgICAgWyJ4IiwibWVhc3VyZW1lbnQiLDBdLAogICAgICAgICAgICBbInkiLCJtZWFzdXJlbWVudCIsMF0sCiAgICAgICAgICAgIFsicHJlc2VuY2UiLHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucHJlc2VuY2VWYWx1ZXMsMF0sCiAgICAgICAgICAgIFsibmFtZSIsInN0cmluZyIsIiJdLAogICAgICAgICAgICBbInJlbGV2YW50IiwgInN0cmluZyIsICIiIF0sCiAgICAgICAgICAgIFsibG9jYWxlIiwic3RyaW5nIiwiZW5fVVMiXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbIm9jY3VyIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiZXh0cmFzIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsiZGVzYyIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbInBhZ2VTZXQiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJ2YXJpYWJsZXMiLCJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJhcmVhIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImZpZWxkIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImRyYXciLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZXhjbEdyb3VwIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImluc3RhbmNlTWFuYWdlciIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJzdWJmb3JtIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImFzc2lzdCIsInplcm9Pck9uZSJdLAogICAgICAgICAgICBbImJvcmRlciIsICJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJwYXJhIiwgInplcm9Pck9uZSJdLAogICAgICAgICAgICBbInZhbGlkYXRlIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsic3ViZm9ybVNldCIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJiaW5kIiwiemVyb09yT25lIl0sCiAgICAgICAgICAgIFsibWFyZ2luIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJ0ZXh0Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXSwKICAgICAgICAgICAgWyJtYXhDaGFycyIsImludGVnZXIiLDBdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJleERhdGEiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsibmFtZSIsInN0cmluZyIsIiJdLAogICAgICAgICAgICBbIm1heExlbmd0aCIsImludGVnZXIiLC0xXSwKICAgICAgICAgICAgWyJ0cmFuc2ZlckVuY29kaW5nIix4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnRyYW5zZmVyRW5jb2RpbmdWYWx1ZXMsMF0sCiAgICAgICAgICAgIFsiY29udGVudFR5cGUiLCJzdHJpbmciLCJ0ZXh0L3BsYWluIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJleHRyYXMiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsibmFtZSIsInN0cmluZyIsIiJdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsidGV4dCIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJpbnRlZ2VyIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImRhdGUiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZGVjaW1hbCIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJmbG9hdCIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJ2YWx1ZSIsICJ6ZXJvT3JPbmUiXSwKICAgICAgICAgICAgWyJleHRyYXMiLCJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImRlc2MiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJ0ZXh0IiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImludGVnZXIiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZGF0ZSIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJkZWNpbWFsIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImZsb2F0IiwiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJ2YXJpYWJsZXMiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJib29sZWFuIiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbImRhdGUiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZGF0ZVRpbWUiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZGVjaW1hbCIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJleERhdGEiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiZmxvYXQiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiaW1hZ2UiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsiaW50ZWdlciIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJtYW5pZmVzdCIsInplcm9Pck1vcmUiXSwKICAgICAgICAgICAgWyJzY3JpcHQiLCJ6ZXJvT3JNb3JlIl0sCiAgICAgICAgICAgIFsic2NyaXB0IiwiemVyb09yTW9yZSJdLAogICAgICAgICAgICBbInRpbWUiLCJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJwYXJhIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImhBbGlnbiIsInN0cmluZyIsImxlZnQiXSwKICAgICAgICAgICAgWyJsaW5lSGVpZ2h0IiwibWVhc3VyZW1lbnQiLCIwcHQiXSwKICAgICAgICAgICAgWyJtYXJnaW5MZWZ0IiwibWVhc3VyZW1lbnQiLCIwaW4iXSwKICAgICAgICAgICAgWyJtYXJnaW5SaWdodCIsIm1lYXN1cmVtZW50IiwiMGluIl0sCiAgICAgICAgICAgIFsib3JwaGFucyIsImludGVnZXIiLDBdLAogICAgICAgICAgICBbInByZXNlcnZlIiwic3RyaW5nIiwiIl0sCiAgICAgICAgICAgIFsicmFkaXhPZmZzZXQiLCJtZWFzdXJlbWVudCIsIjBpbiJdLAogICAgICAgICAgICBbInNwYWNlQWJvdmUiLCJtZWFzdXJlbWVudCIsIjBpbiJdLAogICAgICAgICAgICBbInNwYWNlQmVsb3ciLCJtZWFzdXJlbWVudCIsIjBpbiJdLAogICAgICAgICAgICBbInRhYkRlZmF1bHQiLCJzdHJpbmciLCIiXSwKICAgICAgICAgICAgWyJ0YWJTdG9wcyIsInN0cmluZyIsIiJdLAogICAgICAgICAgICBbInRleHRJbmRlbnQiLCJtZWFzdXJlbWVudCIsIjBpbiJdLAogICAgICAgICAgICBbInZBbGlnbiIsInN0cmluZyIsInRvcCJdLAogICAgICAgICAgICBbIndpZG93cyIsImludGVnZXIiLDBdLAogICAgICAgICAgICBbIndvcmRTcGFjaW5nTWF4aW11bSIsInN0cmluZyIsIiJdLAogICAgICAgICAgICBbIndvcmRTcGFjaW5nTWluaW11bSIsInN0cmluZyIsIiJdLAogICAgICAgICAgICBbIndvcmRTcGFjaW5nT3B0aW11bSIsInN0cmluZyIsIiJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJlbmNyeXB0RGF0YSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJvcGVyYXRpb24iLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmVuY3J5cHREYXRhT3BlcmF0aW9uVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJ0YXJnZXQiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImZpbHRlciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbIm1hbmlmZXN0IiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiaXNzdWVycyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJ0eXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5yZXF1aXJlZFR5cGVWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImNlcnRpZmljYXRlIiwgInplcm9Pck1vcmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImltYWdlRWRpdCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJkYXRhIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5kYXRhVmFsdWVzLCAxIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJib3JkZXIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJtYXJnaW4iLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJib29rZW5kIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImxlYWRlciIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidHJhaWxlciIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsicmVhc29uIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm5hbWUiLCJzdHJpbmciLCIiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInBhc3N3b3JkRWRpdCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJoU2Nyb2xsUG9saWN5IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5oU2Nyb2xsUG9saWN5VmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJwYXNzd29yZENoYXIiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImJvcmRlciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbIm1hcmdpbiIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInZhbGlkYXRlIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImRpc2FibGVBbGwiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmRpc2FibGVBbGxWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbImZvcm1hdFRlc3QiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmZvcm1hdFRlc3RWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbIm51bGxUZXN0IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5udWxsVGVzdFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsic2NyaXB0VGVzdCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuc2NyaXB0VGVzdFZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsibWVzc2FnZSIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbInBpY3R1cmUiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJzY3JpcHQiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJicmVhayJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJhZnRlciIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuYWZ0ZXJWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbImFmdGVyVGFyZ2V0IiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJiZWZvcmUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmJlZm9yZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsiYmVmb3JlVGFyZ2V0IiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJib29rZW5kTGVhZGVyIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJib29rZW5kVHJhaWxlciIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsib3ZlcmZsb3dMZWFkZXIiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbIm92ZXJmbG93VGFyZ2V0IiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJvdmVyZmxvd1RyYWlsZXIiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInN0YXJ0TmV3IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5zdGFydE5ld1ZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsidGltZSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJuYW1lIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJjZXJ0aWZpY2F0ZSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJuYW1lIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJsb2NrRG9jdW1lbnQiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsidHlwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucmVxdWlyZWRUeXBlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJhcmMiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiY2lyY3VsYXIiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmNpcmN1bGFyVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJoYW5kIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5oYW5kVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJzdGFydEFuZ2xlIiwgInN0cmluZyIsICIwIiBdICAsCiAgICAgICAgICAgIFsic3dlZXBBbmdsZSIsICJzdHJpbmciLCAiMzYwIiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZWRnZSIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImZpbGwiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJidXR0b24iXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiaGlnaGxpZ2h0IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5oaWdobGlnaHRWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImV2ZW50Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImFjdGl2aXR5IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5hY3Rpdml0eVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsibGlzdGVuIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5saXN0ZW5WYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbIm5hbWUiLCAic3RyaW5nIiwgIiIgXSwKICAgICAgICAgICAgWyJyZWYiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImVuY3J5cHREYXRhIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbImV4ZWN1dGUiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsic2NyaXB0IiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbInNpZ25EYXRhIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbInN1Ym1pdCIsICJvbmVPZkNoaWxkIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJib29sZWFuIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm5hbWUiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbIm1hcmdpbiJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJib3R0b21JbnNldCIsICJtZWFzdXJlbWVudCIsICIwaW4iIF0gICwKICAgICAgICAgICAgWyJsZWZ0SW5zZXQiLCAibWVhc3VyZW1lbnQiLCAiMGluIiBdICAsCiAgICAgICAgICAgIFsicmlnaHRJbnNldCIsICJtZWFzdXJlbWVudCIsICIwaW4iIF0gICwKICAgICAgICAgICAgWyJ0b3BJbnNldCIsICJtZWFzdXJlbWVudCIsICIwaW4iIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJib3JkZXIiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiYnJlYWsiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmJyZWFrVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJoYW5kIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5oYW5kVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJwcmVzZW5jZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucHJlc2VuY2VWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInJlbGV2YW50IiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJjb3JuZXIiLCAiemVyb09yRm91ciJdICAsCiAgICAgICAgICAgIFsiZWRnZSIsICJ6ZXJvT3JGb3VyIl0gICwKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJmaWxsIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsibWFyZ2luIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiYnJlYWtBZnRlciJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJsZWFkZXIiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInN0YXJ0TmV3IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5zdGFydE5ld1ZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsidGFyZ2V0IiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJ0YXJnZXRUeXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy50YXJnZXRUeXBlVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJ0cmFpbGVyIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJzY3JpcHQiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJzaWduYXR1cmUiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsidHlwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuc2lnblR5cGVWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImJvcmRlciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImZpbHRlciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbIm1hbmlmZXN0IiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsibWFyZ2luIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsic2lnbkRhdGEiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsib3BlcmF0aW9uIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5zaWduRGF0YU9wZXJhdGlvblZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicmVmIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJ0YXJnZXQiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImZpbHRlciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbIm1hbmlmZXN0IiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiaW1hZ2UiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiYXNwZWN0IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5hc3BlY3RWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbImNvbnRlbnRUeXBlIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJocmVmIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJuYW1lIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJ0cmFuc2ZlckVuY29kaW5nIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy50cmFuc2ZlckVuY29kaW5nVmFsdWVzLCAyIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJvaWRzIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnJlcXVpcmVkVHlwZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsib2lkIiwgInplcm9Pck1vcmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInNvbGlkIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsibWFuaWZlc3QiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiYWN0aW9uIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5tYW5pZmVzdEFjdGlvblZhbHVlcywgMCBdLAogICAgICAgICAgICBbIm5hbWUiLCAic3RyaW5nIiwgIjIiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJyZWYiLCAiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInRyYXZlcnNlIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImRlbGVnYXRlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy50cmF2ZXJzZURlbGVnYXRlVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJvcGVyYXRpb24iLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnRyYXZlcnNlT3BlcmF0aW9uVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJyZWYiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbInNjcmlwdCIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImxpbmUiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiaGFuZCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuaGFuZFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsic2xvcGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnNsb3BlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJlZGdlIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZGlnZXN0TWV0aG9kcyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJ0eXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5yZXF1aXJlZFR5cGVWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImRpZ2VzdE1ldGhvZCIsICJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJyZWFzb25zIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnJlcXVpcmVkVHlwZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsicmVhc29uIiwgInplcm9Pck1vcmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImRlZmF1bHRVaSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImh5cGhlbmF0aW9uIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImV4Y2x1ZGVBbGxDYXBzIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5leGNsdWRlQWxsQ2Fwc1ZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsiZXhjbHVkZUluaXRpYWxDYXAiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmV4Y2x1ZGVJbml0aWFsQ2FwVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJoeXBoZW5hdGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmh5cGhlbmF0ZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsibGFkZGVyQ291bnQiLCAiaW50ZWdlciIsIDIgXSAgLAogICAgICAgICAgICBbInB1c2hDaGFyYWN0ZXJDb3VudCIsICJpbnRlZ2VyIiwgMyBdICAsCiAgICAgICAgICAgIFsicmVtYWluQ2hhcmFjdGVyQ291bnQiLCAiaW50ZWdlciIsIDMgXSAgLAogICAgICAgICAgICBbIndvcmRDaGFyYWN0ZXJDb3VudCIsICJpbnRlZ2VyIiwgNyBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsicmVjdGFuZ2xlIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImhhbmQiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmhhbmRWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImNvcm5lciIsICJ6ZXJvT3JGb3VyIl0gICwKICAgICAgICAgICAgWyJlZGdlIiwgInplcm9PckZvdXIiXSAgLAogICAgICAgICAgICBbImZpbGwiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJlbmNyeXB0aW9uTWV0aG9kIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiY2hlY2tCdXR0b24iXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiYWxsb3dOZXV0cmFsIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5hbGxvd05ldXRyYWxWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbIm1hcmsiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLm1hcmtWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInNoYXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5zaGFwZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsic2l6ZSIsICJzdHJpbmciLCAiMTBwdCIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImJvcmRlciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbIm1hcmdpbiIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImNob2ljZUxpc3QiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiY29tbWl0T24iLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmNvbW1pdE9uVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJvcGVuIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5vcGVuVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJ0ZXh0RW50cnkiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnRleHRFbnRyeVZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiYm9yZGVyIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsibWFyZ2luIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsib2lkIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm5hbWUiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImVuY29kaW5nIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsidWkiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJwaWN0dXJlIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiYmFyY29kZSIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJidXR0b24iLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsiY2hlY2tCdXR0b24iLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsiY2hvaWNlTGlzdCIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJkYXRlVGltZUVkaXQiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsiZGVmYXVsdFVpIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbImV4T2JqZWN0IiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbImltYWdlRWRpdCIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJudW1lcmljRWRpdCIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJwYXNzd29yZEVkaXQiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsic2lnbmF0dXJlIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbInRleHRFZGl0IiwgIm9uZU9mQ2hpbGQiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImxpbmVhciJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJ0eXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5saW5lYXJUeXBlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJjb2xvciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImVkZ2UiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiY2FwIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5lZGdlQ2FwVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJwcmVzZW5jZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucHJlc2VuY2VWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInN0cm9rZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuc3Ryb2tlVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJ0aGlja25lc3MiLCAic3RyaW5nIiwgIjAuNXB0IiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiY29sb3IiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJjb3JuZXIiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiaW52ZXJ0ZWQiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmNvcm5lckludmVydGVkVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJqb2luIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5jb3JuZXJKb2luVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJwcmVzZW5jZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucHJlc2VuY2VWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInJhZGl1cyIsICJzdHJpbmciLCAiMGluIiBdICAsCiAgICAgICAgICAgIFsic3Ryb2tlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5zdHJva2VWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInRoaWNrbmVzcyIsICJzdHJpbmciLCAiMC4wNXB0IiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiY29sb3IiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJ0b29sVGlwIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInJpZCIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsic3BlYWsiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiZGlzYWJsZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuc3BlYWtEaXNhYmxlVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJwcmlvcml0eSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuc3BlYWtQcmlvcml0eVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicmlkIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJjYXB0aW9uIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInBsYWNlbWVudCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuY2FwdGlvblBsYWNlbWVudFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicHJlc2VuY2UiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnByZXNlbmNlVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJyZXNlcnZlIiwgInN0cmluZyIsICItMSIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImZvbnQiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJtYXJnaW4iLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJwYXJhIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsidmFsdWUiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJjb21iIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm51bWJlck9mQ2VsbHMiLCAiaW50ZWdlciIsIDAgXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbIm1lZGl1bSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJpbWFnaW5nQkJveCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsibG9uZyIsICJzdHJpbmciLCAiMGluIiBdICAsCiAgICAgICAgICAgIFsib3JpZW50YXRpb24iLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLm9yaWVudGF0aW9uVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJzaG9ydCIsICJzdHJpbmciLCAiMGluIiBdICAsCiAgICAgICAgICAgIFsic3RvY2siLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInRyYXlJbiIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMubWVkaXVtVHJheUluVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJ0cmF5T3V0IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5tZWRpdW1UcmF5T3V0VmFsdWVzLCAwIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJyZWYiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJwYXR0ZXJuIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnBhdHRlcm5UeXBlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJjb2xvciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImtlZXAiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiaW50YWN0IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5rZWVwSW50YWN0VmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJuZXh0IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5rZWVwTmV4dFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicHJldmlvdXMiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmtlZXBQcmV2aW91c1ZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZGlnZXN0TWV0aG9kIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsic2lnbmluZyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJ0eXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5yZXF1aXJlZFR5cGVWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImNlcnRpZmljYXRlIiwgInplcm9Pck1vcmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImVuY3J5cHRpb24iXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsidHlwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucmVxdWlyZWRUeXBlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJjZXJ0aWZpY2F0ZSIsICJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJzdWJqZWN0RE5zIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnJlcXVpcmVkVHlwZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsic3ViamVjdEROIiwgInplcm9Pck1vcmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImVuY3J5cHQiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJjZXJ0aWZpY2F0ZSIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInZhbHVlIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm92ZXJyaWRlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy52YWx1ZU92ZXJyaWRlVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJyZWxldmFudCIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiYXJjIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbImJvb2xlYW4iLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsiZGF0ZSIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJkYXRlVGltZSIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJkZWNpbWFsIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbImV4RGF0YSIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJmbG9hdCIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJpbWFnZSIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJpbnRlZ2VyIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbImxpbmUiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsicmVjdGFuZ2xlIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbInRleHQiLCAib25lT2ZDaGlsZCJdICAsCiAgICAgICAgICAgIFsidGltZSIsICJvbmVPZkNoaWxkIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJ0cmF2ZXJzYWwiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsicGFzc1Rocm91Z2giLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnBhc3NUaHJvdWdoVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJ0cmF2ZXJzZSIsICJ6ZXJvT3JNb3JlIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJ0ZXh0RWRpdCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJhbGxvd1JpY2hUZXh0IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5hbGxvd1JpY2hUZXh0VmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJoU2Nyb2xsUG9saWN5IiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5oU2Nyb2xsUG9saWN5VmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJtdWx0aUxpbmUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLm11bHRpTGluZVZhbHVlcywgMSBdICAsCiAgICAgICAgICAgIFsidlNjcm9sbFBvbGljeSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMudlNjcm9sbFBvbGljeVZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiYm9yZGVyIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiY29tYiIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbIm1hcmdpbiIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInN0aXBwbGUiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsicmF0ZSIsICJpbnRlZ2VyIiwgNTAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImNvbG9yIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZm9udCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJiYXNlbGluZVNoaWZ0IiwgInN0cmluZyIsICIwaW4iIF0gICwKICAgICAgICAgICAgWyJmb250SG9yaXpvbnRhbFNjYWxlIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJmb250VmVydGljYWxTY2FsZSIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsia2VybmluZ01vZGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmtlcm5pbmdNb2RlVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJsZXR0ZXJTcGFjaW5nIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJsaW5lVGhyb3VnaCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMubGluZVRocm91Z2hWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbImxpbmVUaHJvdWdoUGVyaW9kIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5saW5lVGhyb3VnaFBlcmlvZFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsib3ZlcmxpbmUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmZvbnRPdmVybGluZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsib3ZlcmxpbmVQZXJpb2QiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmZvbnRPdmVybGluZVBlcmlvZFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicG9zdHVyZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucG9zdHVyZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsic2l6ZSIsICJzdHJpbmciLCAiMTBwdCIgXSAgLAogICAgICAgICAgICBbInR5cGVmYWNlIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJ1bmRlcmxpbmUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnVuZGVybGluZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsidW5kZXJsaW5lUGVyaW9kIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy51bmRlcmxpbmVQZXJpb2RWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbIndlaWdodCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuZm9udFdlaWdodFZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZmlsbCIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImJhcmNvZGUiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiY2hhckVuY29kaW5nIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJjaGVja3N1bSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuY2hlY2tzdW1WYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbImRhdGFDb2x1bW5Db3VudCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsiZGF0YUxlbmd0aCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsiZGF0YVByZXAiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmRhdGFQcmVwVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJkYXRhUm93Q291bnQiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbImVuZENoYXIiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbImVycm9yQ29ycmVjdGlvbkxldmVsIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJtb2R1bGVIZWlnaHQiLCAic3RyaW5nIiwgIjVtbSIgXSAgLAogICAgICAgICAgICBbIm1vZHVsZVdpZHRoIiwgInN0cmluZyIsICIwLjI1bW0iIF0gICwKICAgICAgICAgICAgWyJwcmludENoZWNrRGlnaXQiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnByaW50Q2hlY2tEaWdpdFZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsicm93Q29sdW1uUmF0aW8iLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInN0YXJ0Q2hhciIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidGV4dExvY2F0aW9uIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy50ZXh0TG9jYXRpb25WYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInRydW5jYXRlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy50cnVuY2F0ZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsidHlwZSIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidXBzTW9kZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMudXBzTW9kZVZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsid2lkZU5hcnJvd1JhdGlvIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJlbmNyeXB0IiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiYXNzaXN0Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInJvbGUiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbInNwZWFrIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsidG9vbFRpcCIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImJyZWFrQmVmb3JlIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImxlYWRlciIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsic3RhcnROZXciLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnN0YXJ0TmV3VmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJ0YXJnZXQiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInRhcmdldFR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnRhcmdldFR5cGVWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInRyYWlsZXIiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbInNjcmlwdCIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImZvcm1hdCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbInBpY3R1cmUiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJrZXlVc2FnZSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJjcmxTaWduIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJkYXRhRW5jaXBoZXJtZW50IiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJkZWNpcGhlck9ubHkiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbImRpZ2l0YWxTaWduYXR1cmUiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbImVuY2lwaGVyT25seSIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsia2V5QWdyZWVtZW50IiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJrZXlDZXJ0U2lnbiIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsia2V5RW5jaXBoZXJtZW50IiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJub25SZXB1ZGlhdGlvbiIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidHlwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucmVxdWlyZWRUeXBlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKCgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsicGljdHVyZSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsibWRwIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInBlcm1pc3Npb25zIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5tZHBQZXJtaXNzaW9uc1ZhbHVlcywgMCBdICAsCiAgICAgICAgICAgIFsic2lnbmF0dXJlVHlwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMubWRwU2lnbmF0dXJlVHlwZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsib3ZlcmZsb3ciXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsibGVhZGVyIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJ0YXJnZXQiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInRyYWlsZXIiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbIm51bWVyaWNFZGl0Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImhTY3JvbGxQb2xpY3kiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmhTY3JvbGxQb2xpY3lWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImJvcmRlciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImNvbWIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJleHRyYXMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJtYXJnaW4iLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJhcHBlYXJhbmNlRmlsdGVyIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnJlcXVpcmVkVHlwZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZmlsdGVyIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImFkZFJldm9jYXRpb25JbmZvIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJuYW1lIiwgInN0cmluZyIsICIiIF0sCiAgICAgICAgICAgIFsidmVyc2lvbiIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiYXBwZWFyYW5jZUZpbHRlciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImNlcnRpZmljYXRlcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImRpZ2VzdE1ldGhvZHMiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJlbmNvZGluZ3MiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJlbmNyeXB0aW9uTWV0aG9kcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImhhbmRsZXIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJsb2NrRG9jdW1lbnQiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJtZHAiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJyZWFzb25zIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsidGltZVN0YW1wIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsicmVuZGVyQXMiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiQVBJVmVyc2lvbiIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsic3ZnIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsidGltZVN0YW1wIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInNlcnZlciIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidHlwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucmVxdWlyZWRUeXBlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJjb25uZWN0Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImNvbm5lY3Rpb24iLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInJlZiIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidXNhZ2UiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmNvbm5lY3RVc2FnZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsicGljdHVyZSIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImRhdGVUaW1lIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm5hbWUiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImJpbmRJdGVtcyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJjb25uZWN0aW9uIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJsYWJlbFJlZiIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsicmVmIiwgInN0cmluZyIsICIiIF0gICwKICAgICAgICAgICAgWyJ2YWx1ZVJlZiIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZW5jb2RpbmdzIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnJlcXVpcmVkVHlwZVZhbHVlcywgMCBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZW5jb2RpbmciLCAiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsicmFkaWFsIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbInR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnJhZGlhbFR5cGVWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImNvbG9yIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiY2VydGlmaWNhdGVzIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImNyZWRlbnRpYWxTZXJ2ZXJQb2xpY3kiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmNyZWRlbnRpYWxTZXJ2ZXJQb2xpY3lWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInVybCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidXJsUG9saWN5IiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJlbmNyeXB0aW9uIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiaXNzdWVycyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImtleVVzYWdlIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsib2lkcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbInNpZ25pbmciLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJzdWJqZWN0RE5zIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsic3ZnIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImhlaWdodCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidmlld0JveCIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsid2lkdGgiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImZpbGwiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsicHJlc2VuY2UiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnByZXNlbmNlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJjb2xvciIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImxpbmVhciIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJwYXR0ZXJuIiwgIm9uZU9mQ2hpbGQiXSAgLAogICAgICAgICAgICBbInJhZGlhbCIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJzb2xpZCIsICJvbmVPZkNoaWxkIl0gICwKICAgICAgICAgICAgWyJzdGlwcGxlIiwgIm9uZU9mQ2hpbGQiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInNldFByb3BlcnR5Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImNvbm5lY3Rpb24iLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInJlZiIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsidGFyZ2V0IiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJlbmNyeXB0aW9uTWV0aG9kcyJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJ0eXBlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5yZXF1aXJlZFR5cGVWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImVuY3J5cHRpb25NZXRob2QiLCAiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiZGF0ZVRpbWVFZGl0Il0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbImhTY3JvbGxQb2xpY3kiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmhTY3JvbGxQb2xpY3lWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInBpY2tlciIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuZGF0ZVRpbWVFZGl0UGlja2VyVmFsdWVzLCAwIF0KICAgICAgICBdKTsKICAgICAgICB0aGlzLmFkZENoaWxkcmVuKGVsZW0sIFsKICAgICAgICAgICAgWyJib3JkZXIiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJjb21iIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsibWFyZ2luIiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsibWVzc2FnZSJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbInRleHQiLCAiemVyb09yTW9yZSJdCiAgICAgICAgXSk7CgoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiY29sb3IiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiY1NwYWNlIiwgInN0cmluZyIsICJTUkdCIiBdICAsCiAgICAgICAgICAgIFsidmFsdWUiLCAic3RyaW5nIiwgIiIgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInN1YmplY3RETiJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJkZWxpbWl0ZXIiLCAic3RyaW5nIiwgIiIgXSwKICAgICAgICAgICAgWyJuYW1lIiwgInN0cmluZyIsICIiIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJiaW5kIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm1hdGNoIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5iaW5kTWF0Y2hWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInJlZiIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsicGljdHVyZSIsICJ6ZXJvT3JPbmUiXQogICAgICAgIF0pOwoKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImhhbmRsZXIiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsidHlwZSIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucmVxdWlyZWRUeXBlVmFsdWVzLCAwIF0KICAgICAgICBdKTsKCgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJvY2N1ciJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJpbml0aWFsIiwgImludGVnZXIiLCAxIF0gICwKICAgICAgICAgICAgWyJtYXgiLCAiaW50ZWdlciIsIDEgXSAgLAogICAgICAgICAgICBbIm1pbiIsICJpbnRlZ2VyIiwgMSBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZXh0cmFzIiwgInplcm9Pck9uZSJdICAsCiAgICAgICAgICAgIFsic2NyaXB0IiwgInplcm9Pck9uZSJdCiAgICAgICAgXSk7CgogICAgICAgIFhmYVRlbXBsYXRlU2NoZW1hWyJzY3JpcHQiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiYmluZGluZyIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsiY29udGVudFR5cGUiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbIm5hbWUiLCAic3RyaW5nIiwgIiIgXSwKICAgICAgICAgICAgWyJydW5BdCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucnVuQXRWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbInN0YXRlbGVzcyIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuc3RhdGVsZXNzVmFsdWVzLCAwIF0KICAgICAgICBdKTsKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbImV4ZWN1dGUiXSA9IGVsZW0gPSB0aGlzLmNyZWF0ZUVsZW1lbnQoKTsKICAgICAgICB0aGlzLmFkZEF0dHJpYnV0ZXMoZWxlbSxbCiAgICAgICAgICAgIFsiY29ubmVjdGlvbiIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsiZXhlY3V0ZVR5cGUiLCB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmV4ZWN1dGVUeXBlVmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJydW5BdCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMucnVuQXRWYWx1ZXMsIDAgXQogICAgICAgIF0pOwoKICAgICAgICBYZmFUZW1wbGF0ZVNjaGVtYVsiY2FsY3VsYXRlIl0gPSBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCk7CiAgICAgICAgdGhpcy5hZGRBdHRyaWJ1dGVzKGVsZW0sWwogICAgICAgICAgICBbIm92ZXJyaWRlIiwgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5jYWxjT3ZlcnJpZGVWYWx1ZXMsIDAgXQogICAgICAgIF0pOwogICAgICAgIHRoaXMuYWRkQ2hpbGRyZW4oZWxlbSwgWwogICAgICAgICAgICBbImV4dHJhcyIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbIm1lc3NhZ2UiLCAiemVyb09yT25lIl0gICwKICAgICAgICAgICAgWyJzY3JpcHQiLCAiemVyb09yT25lIl0KICAgICAgICBdKTsKCiAgICAgICAgWGZhVGVtcGxhdGVTY2hlbWFbInN1Ym1pdCJdID0gZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgpOwogICAgICAgIHRoaXMuYWRkQXR0cmlidXRlcyhlbGVtLFsKICAgICAgICAgICAgWyJlbWJlZFBERiIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuZW1iZWRQREZWYWx1ZXMsIDAgXSAgLAogICAgICAgICAgICBbImZvcm1hdCIsIHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuc3VibWl0Rm9ybWF0VmFsdWVzLCAwIF0gICwKICAgICAgICAgICAgWyJ0YXJnZXQiLCAic3RyaW5nIiwgIiIgXSAgLAogICAgICAgICAgICBbInRleHRFbmNvZGluZyIsICJzdHJpbmciLCAiIiBdICAsCiAgICAgICAgICAgIFsieGRwQ29udGVudCIsICJzdHJpbmciLCAiIiBdCiAgICAgICAgXSk7CiAgICAgICAgdGhpcy5hZGRDaGlsZHJlbihlbGVtLCBbCiAgICAgICAgICAgIFsiZW5jcnlwdCIsICJ6ZXJvT3JPbmUiXSAgLAogICAgICAgICAgICBbImVuY3J5cHREYXRhIiwgInplcm9Pck1vcmUiXSAgLAogICAgICAgICAgICBbInNpZ25EYXRhIiwgInplcm9Pck1vcmUiXQogICAgICAgIF0pOwoKICAgIH0sCgogICAgYWRkQXR0cmlidXRlczogZnVuY3Rpb24oZWxlbWVudCxhdHRyQXJyYXkpIHsKICAgICAgICBfLmVhY2goYXR0ckFycmF5LCBmdW5jdGlvbihlbGVtKSB7CiAgICAgICAgICAgIGVsZW1lbnQuYXR0cmlidXRlc1tlbGVtWzBdXSA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ZWxlbVsxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkZWZhdWx0IjplbGVtWzJdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0sCgogICAgYWRkQ2hpbGRyZW46IGZ1bmN0aW9uKGVsZW1lbnQsY2hpbGRyZW5BcnJheSkgewogICAgICAgIF8uZWFjaChjaGlsZHJlbkFycmF5LCBmdW5jdGlvbihlbGVtKSB7CiAgICAgICAgICAgIGVsZW1lbnQuY2hpbGRyZW5bZWxlbVswXV0gPSB7CiAgICAgICAgICAgICAgICByZWxhdGlvbiA6IHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHNbZWxlbVsxXV0KICAgICAgICAgICAgfTsKICAgICAgICB9KTsKICAgIH0sCgogICAgY3JlYXRlRWxlbWVudDogZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuIHthdHRyaWJ1dGVzOiB7fSxjaGlsZHJlbjoge319OwogICAgfSwKCiAgICBnZXREZWZhdWx0QXR0cmlidXRlOiBmdW5jdGlvbihlbGVtZW50LGF0dHJpYnV0ZSkgewogICAgICAgIHZhciBlbGVtID0gIFhmYVRlbXBsYXRlU2NoZW1hW2VsZW1lbnRdOwogICAgICAgIGlmKCFlbGVtKQogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgdmFyIGF0dHIgPSBlbGVtLmF0dHJpYnV0ZXNbYXR0cmlidXRlXTsKICAgICAgICBpZighYXR0cikKICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICBpZihhdHRyLnR5cGUgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICAgICAgICByZXR1cm4gYXR0ci50eXBlW2F0dHJbImRlZmF1bHQiXV07CiAgICAgICAgfSBlbHNlCiAgICAgICAgICAgIHJldHVybiBhdHRyWyJkZWZhdWx0Il07CiAgICB9LAoKICAgIGhhc0F0dHJpYnV0ZTogZnVuY3Rpb24gKGVsZW1lbnQsIGF0dHJpYnV0ZSkgewogICAgICAgIHZhciBlbGVtID0gWGZhVGVtcGxhdGVTY2hlbWFbZWxlbWVudF07CiAgICAgICAgaWYgKCFlbGVtKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIF8uaGFzKGVsZW0uYXR0cmlidXRlcywgYXR0cmlidXRlKTsKICAgIH0sCgogICAgZ2V0Q2hpbGRyZW4gOiBmdW5jdGlvbihlbGVtZW50KXsKICAgICAgICBpZihYZmFUZW1wbGF0ZVNjaGVtYVtlbGVtZW50XSkKICAgICAgICAgICAgcmV0dXJuIFhmYVRlbXBsYXRlU2NoZW1hW2VsZW1lbnRdLmNoaWxkcmVuOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9LAoKICAgIF9nZXRSZWxhdGlvbjogZnVuY3Rpb24ocGFyZW50LGNoaWxkKSB7CiAgICAgICB2YXIgcCA9IFhmYVRlbXBsYXRlU2NoZW1hW3BhcmVudF07CiAgICAgICBpZighcCkKICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgdmFyIGMgPSBwLmNoaWxkcmVuW2NoaWxkXQogICAgICAgaWYoYykKICAgICAgICAgICByZXR1cm4gYy5yZWxhdGlvbjsKICAgICAgIHJldHVybiBudWxsOwogICAgfSwKCiAgICBfZ2V0RGF0YVR5cGU6IGZ1bmN0aW9uKGVsZW1lbnQsYXR0cmlidXRlKSB7CiAgICAgICAgdmFyIGF0dHIgPSAgWGZhVGVtcGxhdGVTY2hlbWFbZWxlbWVudF0uYXR0cmlidXRlc1thdHRyaWJ1dGVdOwogICAgICAgIHJldHVybiBhdHRyLnR5cGU7CiAgICB9LAoKICAgIF9nZXRPbmVPZkNoaWxkOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgdmFyIHJlcyA9IHt9OwogICAgICAgIF8uZWFjaChYZmFUZW1wbGF0ZVNjaGVtYVtlbGVtZW50XS5jaGlsZHJlbiwKICAgICAgICAgICAgZnVuY3Rpb24ob2JqLGNsYXMpIHsKICAgICAgICAgICAgICAgIGlmKG9iai5yZWxhdGlvbi50eXBlID09ICJvbmVPZkNoaWxkIikKICAgICAgICAgICAgICAgICAgICByZXNbY2xhc10gPSB0cnVlCiAgICAgICAgICAgIH0pOwogICAgICAgIHJldHVybiByZXM7CiAgICB9Cgp9KTsKfSkoXywgeGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi51dC5WZXJzaW9uCiAqIEBpbXBvcnQgeGZhbGliLnV0LkNsYXNzCiAqLwoKKGZ1bmN0aW9uKF8sIHhmYWxpYil7CiAgICB2YXIgVmVyc2lvbiA9IHhmYWxpYi51dC5WZXJzaW9uID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CgogICAgICAgIEVTNDogMTEwMCwKICAgICAgICBFUzRTUDE6IDExMDEsCiAgICAgICAgUDlBOiAxMTAyLCAvL2FkZGVkIG5ldyB2ZXJzaW9uIGZvciBQOUEgLT4gbm90IGJlaW5nIHVzZWQgYnV0IHN0aWxsIGlmIHdlIG5lZWQgc29tZWRheQoKICAgICAgICBjdXJyZW50OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuUDlBOwogICAgICAgIH0sCgogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbihvcHRpb25zKXsKICAgICAgICAgICAgVmVyc2lvbi5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLl9vcmlnaW5hbFZlcnNpb24gPSBvcHRpb25zICE9IG51bGwgPyBvcHRpb25zLm9yaWdpbmFsVmVyc2lvbiA6IHRoaXMuY3VycmVudCgpOwogICAgICAgICAgICB0aGlzLl9vdmVycmlkZSA9IG9wdGlvbnMgPyBvcHRpb25zLm92ZXJyaWRlIDoge30gOwogICAgICAgICAgICBpZighdGhpcy5fb3ZlcnJpZGUpIHsKICAgICAgICAgICAgICAgIHRoaXMuX292ZXJyaWRlID0ge307CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKCiAgICAgICAgaXNTYW1lIDogZnVuY3Rpb24odikgewogICAgICAgICAgICByZXR1cm4gKHRoaXMuX29yaWdpbmFsVmVyc2lvbiA9PSB2KTsKICAgICAgICB9LAoKICAgICAgICBpc0FmdGVyOiBmdW5jdGlvbih2KSB7CiAgICAgICAgICAgIHJldHVybiAodGhpcy5fb3JpZ2luYWxWZXJzaW9uID4gdik7CiAgICAgICAgfSwKCiAgICAgICAgaXNBZnRlck9yU2FtZSA6IGZ1bmN0aW9uKHYpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXNBZnRlcih2KSB8fCB0aGlzLmlzU2FtZSh2KTsKICAgICAgICB9LAoKICAgICAgICBpc1ByZXZpb3VzOiBmdW5jdGlvbih2KSB7CiAgICAgICAgICAgIHJldHVybiAodGhpcy5fb3JpZ2luYWxWZXJzaW9uIDwgdik7CiAgICAgICAgfSwKCiAgICAgICAgaXNQcmV2aW91c09yU2FtZSA6IGZ1bmN0aW9uKHYpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXNQcmV2aW91cyh2KSB8fCB0aGlzLmlzU2FtZSh2KTsKICAgICAgICB9LAoKICAgICAgICBpc09uIDogZnVuY3Rpb24oZmxhZykgewogICAgICAgICAgICAvL2Z1bmN0aW9uIHRvIGNvbnRyb2wgaWYgYSBwYXJ0aWN1bGFyIGZsYWcgaXMgb24KICAgICAgICAgICAgLy9zaW5jZSBpdCBtaWdodCBkZXBlbmRlbnQgb24gdmVyc2lvbiBzbyBpdCBpcyBpbiBWZXJzaW9uIGNsYXNzCiAgICAgICAgICAgcmV0dXJuKHRoaXMuX292ZXJyaWRlW2ZsYWddKTsKICAgICAgICB9CgogICAgfSk7Cn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZEFzc2lzdCA9IHsKICAgICAgICBwcm9wZXJ0eURlc2NyaXB0b3JzIDogewogICAgICAgICAgICAiYXNzaXN0IiA6IHsKICAgICAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImFzc2lzdCIsIDApOwogICAgICAgICAgICAgICAgfSwKCiAgICAgICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJhc3Npc3QiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfSkoXywgeGZhbGliKTsKCgooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRCb3JkZXIgPSB7CiAgICAgICAgcHJvcGVydHlEZXNjcmlwdG9ycyA6IHsKICAgICAgICAgICAgImJvcmRlciIgOiB7CiAgICAgICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJib3JkZXIiLCAwKTsKICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiYm9yZGVyIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0pKF8sIHhmYWxpYik7CgoKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQ2FwdGlvbiA9IHsKICAgICAgICBwcm9wZXJ0eURlc2NyaXB0b3JzIDogewogICAgICAgICAgICAiY2FwdGlvbiIgOiB7CiAgICAgICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjYXB0aW9uIiwgMCk7CiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImNhcHRpb24iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfSkoXywgeGZhbGliKTsKCgooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRQcmVzZW5jZSA9IHsKICAgICAgICBwcm9wZXJ0eURlc2NyaXB0b3JzIDogewogICAgICAgICAgICAicHJlc2VuY2UiIDogewogICAgICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgLy9Bdm9pZGVkIGdldEF0dHJpYnV0ZSBjYWxsIHRvIGF2b2lkIGFueSByZWdyZXNzaW9uIGluIGNhc2Ugc29tZXRoaW5nIGlzIG1pc3NpbmcgaW4gVGVtcGxhdGUgU2NoZW1hCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JFbHNlKHRoaXMuanNvbk1vZGVsLnByZXNlbmNlLCB4ZmFsaWIuc2NyaXB0Lk5vZGUucHJvdG90eXBlLl9kZWZhdWx0cy5wcmVzZW5jZSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24oc1ByZXNlbmNlKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG9sZFByZXNlbmNlID0gdGhpcy5qc29uTW9kZWwucHJlc2VuY2U7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUoc1ByZXNlbmNlLCAicHJlc2VuY2UiKTsKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5qc29uTW9kZWwucHJlc2VuY2UgIT0gb2xkUHJlc2VuY2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FsY3VsYXRlRWZmZWN0aXZlUHJlc2VuY2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsInByZXNlbmNlIixvbGRQcmVzZW5jZSx0aGlzLmpzb25Nb2RlbC5wcmVzZW5jZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsZXZudCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9KShfLHhmYWxpYik7CgooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRYWVdIID0gewogICAgICAgIHByb3BlcnR5RGVzY3JpcHRvcnMgOiB7CiAgICAgICAgICAgICJoIiA6IHsKICAgICAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5oLCB4ZmFsaWIuc2NyaXB0Lk5vZGUucHJvdG90eXBlLl9kZWZhdWx0cy5oKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCJoIik7CiAgICAgICAgICAgICAgICAgICAgdmFyIGV2ZW50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsImgiLHZhbHVlLCB2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2ZW50Lm5hbWUsZXZlbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgInciIDogewogICAgICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JFbHNlKHRoaXMuanNvbk1vZGVsLncsIHhmYWxpYi5zY3JpcHQuTm9kZS5wcm90b3R5cGUuX2RlZmF1bHRzLncpOwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKCkgewoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgICJ4IiA6IHsKICAgICAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC54LCB4ZmFsaWIuc2NyaXB0Lk5vZGUucHJvdG90eXBlLl9kZWZhdWx0cy54KTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBzZXQgOiBmdW5jdGlvbigpIHsKCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAieSIgOiB7CiAgICAgICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwueSwgeGZhbGliLnNjcmlwdC5Ob2RlLnByb3RvdHlwZS5fZGVmYXVsdHMueSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24oKSB7CgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9KShfLHhmYWxpYik7CgooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRGaWxsQ29sb3IgPSB7CiAgICAgICAgcHJvcGVydHlEZXNjcmlwdG9ycyA6IHsKICAgICAgICAgICAgImZpbGxDb2xvciIgOiB7CiAgICAgICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgIHJldHVybiAodGhpcy5ib3JkZXIuZmlsbC5jb2xvci52YWx1ZSA9PSAiIikgPyAiMjU1LDI1NSwyNTUiIDogdGhpcy5ib3JkZXIuZmlsbC5jb2xvci52YWx1ZTsKICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24oY29sb3IpIHsKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmJvcmRlciAmJiB0aGlzLmJvcmRlci5maWxsICYmIHRoaXMuYm9yZGVyLmZpbGwuY29sb3IpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5ib3JkZXIuZmlsbC5wcmVzZW5jZT0idmlzaWJsZSI7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYm9yZGVyLmZpbGwuY29sb3IudmFsdWUgPSBjb2xvcjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0pKF8seGZhbGliKTsKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQm9yZGVyQ29sb3IgPSB7CiAgICAgICAgcHJvcGVydHlEZXNjcmlwdG9ycyA6IHsKICAgICAgICAgICAgImJvcmRlckNvbG9yIiA6IHsKICAgICAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmJvcmRlci5lZGdlLmNvbG9yLnZhbHVlOwogICAgICAgICAgICAgICAgfSwKCiAgICAgICAgICAgICAgICBzZXQgOiBmdW5jdGlvbihjb2xvcikgewogICAgICAgICAgICAgICAgICAgIC8vVE9ETzogU2V0IGJvcmRlci5lZGdlLnByZXNlbmNlIHByb3BlcnR5IHRvIHZpc2libGUgb25jZSBCb3JkZXIgaXMgaW1wbGVtZW50ZWQKICAgICAgICAgICAgICAgICAgICB0aGlzLmJvcmRlci5lZGdlLmNvbG9yLnZhbHVlID0gY29sb3IgOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9KShfLCB4ZmFsaWIpOwoKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQm9yZGVyV2lkdGggPSB7CiAgICAgICAgcHJvcGVydHlEZXNjcmlwdG9ycyA6IHsKICAgICAgICAgICAgImJvcmRlcldpZHRoIiA6IHsKICAgICAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmJvcmRlci5lZGdlLnRoaWNrbmVzczsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuYm9yZGVyLmVkZ2UudGhpY2tuZXNzID0gdmFsdWUgOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9KShfLCB4ZmFsaWIpOyhmdW5jdGlvbihfLHhmYWxpYil7CiAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFBhcmEgPSB7CiAgICAgICAgcHJvcGVydHlEZXNjcmlwdG9ycyA6IHsKICAgICAgICAgICAgInBhcmEiIDogewogICAgICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgicGFyYSIsIDApOwogICAgICAgICAgICAgICAgfSwKCiAgICAgICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJwYXJhIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0pKF8sIHhmYWxpYik7CgoKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkTWFyZ2luID0gewogICAgICAgIHByb3BlcnR5RGVzY3JpcHRvcnMgOiB7CiAgICAgICAgICAgICJtYXJnaW4iIDogewogICAgICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFyZ2luIiwgMCk7CiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgIm1hcmdpbiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9KShfLCB4ZmFsaWIpOwoKCi8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0Lk9iamVjdAogKiBAaW1wb3J0IHhmYWxpYi51dC5FdmVudENsYXNzCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgT2JqZWN0IENsYXNzIHJlcXVpcmVkIGZvciBYRkEgbGlicmFyeQogKiBAdmVyc2lvbiAwLjAuMQogKi8KCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3IGNsYXNzCiAgICAgKiBAY2xhc3MgQmFzZSBYRkEgY2xhc3MuIEFsbCB0aGUgb3RoZXIgY2xhc3NlcyBhcmUgYSBzdWJjbGFzcyBvZiB0aGlzLgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gY2xhc3NOYW1lIHJlcHJlc2VudHMgdGhlIG5hbWUgb2YgdGhlIGNsYXNzIGZvciB0aGlzIG9iamVjdAogICAgICovCiAgICB2YXIgeGZhT2JqZWN0ID0geGZhbGliLnNjcmlwdC5PYmplY3QgPSB4ZmFsaWIudXQuRXZlbnRDbGFzcy5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lIDogIm9iamVjdCIsCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIC8vRm9yIHBlcmYgcmVhc29uLCB3ZSBhcmUgY29tcHV0aW5nIGNsYXNzTmFtZSBhdCBpbnRpYWxpemUgdGltZSBpbnN0ZWFkIG9mIGFjY2Vzc2luZyBpdCB2aWEgcHJvcGVydHlEZXNjcmlwdG9yCiAgICAgICAgICAgIHRoaXMuY2xhc3NOYW1lID0gdGhpcy5qc29uTW9kZWwuX2NsYXNzIHx8IHRoaXMubXNDbGFzc05hbWU7CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5YZmFMaXN0CiAqIEBpbXBvcnQgeGZhbGliLnV0LkNsYXNzCiAqLwoKKGZ1bmN0aW9uKF8sIHhmYWxpYil7CiAgICB2YXIgWGZhTGlzdCA9IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIFhmYUxpc3QuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgdGhpcy5jdXJyZW50SW5kZXggPSAtMTsKICAgICAgICAgICAgdGhpcy5tb0FycmF5bGlzdCA9ICBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5tUGFyZW50ID0gdGhpcy5vcHRpb25zLnBhcmVudDsKICAgICAgICB9LAoKICAgICAgICBpdGVtIDogZnVuY3Rpb24obkluZGV4KSB7CiAgICAgICAgICAgIGlmKG5JbmRleCA8PSB0aGlzLmN1cnJlbnRJbmRleCkKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1vQXJyYXlsaXN0W25JbmRleF07CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIF9hcHBlbmQgOiBmdW5jdGlvbihvUGFyYW0pIHsKICAgICAgICAgICAgdGhpcy5tb0FycmF5bGlzdFsrK3RoaXMuY3VycmVudEluZGV4XSA9IG9QYXJhbTsKICAgICAgICB9LAoKICAgICAgICBhcHBlbmQgOiBmdW5jdGlvbihvUGFyYW0pIHsKICAgICAgICAgICAgaWYodGhpcy5tUGFyZW50ICYmIHRoaXMubVBhcmVudCBpbnN0YW5jZW9mIHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudCkgICB7CiAgICAgICAgICAgICAgICB2YXIgcmVsYXRpb24gPSB0aGlzLm1QYXJlbnQuX3hmYSgpLl90ZW1wbGF0ZVNjaGVtYS5fZ2V0UmVsYXRpb24odGhpcy5tUGFyZW50LmNsYXNzTmFtZSxvUGFyYW0uY2xhc3NOYW1lKTsKICAgICAgICAgICAgICAgIHN3aXRjaChyZWxhdGlvbi50eXBlKQogICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICBjYXNlICJ6ZXJvT3JPbmUiOgogICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgIGNhc2UgInplcm9PclR3byI6CiAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgY2FzZSAiemVyb09yTW9yZSI6CiAgICAgICAgICAgICAgICB0aGlzLm1QYXJlbnQuX2FkZENoaWxkKG9QYXJhbSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICBkZWZhdWx0OgoKICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuX2FwcGVuZChvUGFyYW0pOwogICAgICAgIH0sCgogICAgICAgIHJlbW92ZSA6IGZ1bmN0aW9uKG9QYXJhbSkgewogICAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLm1vQXJyYXlsaXN0LmluZGV4T2Yob1BhcmFtKTsKICAgICAgICAgICAgaWYoaW5kZXggPj0gMCkgewogICAgICAgICAgICAgICAgdGhpcy5tb0FycmF5bGlzdC5zcGxpY2UoaW5kZXgsMSk7CiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRJbmRleC0tOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgaW5zZXJ0IDogZnVuY3Rpb24ob0luc2VydCxvQmVmb3JlKSB7CiAgICAgICAgICAgIHZhciBpbmRleCA9IHRoaXMubW9BcnJheWxpc3QuaW5kZXhPZihvQmVmb3JlKTsKICAgICAgICAgICAgdGhpcy5jdXJyZW50SW5kZXgrKzsKICAgICAgICAgICAgaWYoaW5kZXggPD0gMCkKICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5jdXJyZW50SW5kZXg7CiAgICAgICAgICAgIHRoaXMubW9BcnJheWxpc3Quc3BsaWNlKGluZGV4LDAsb0luc2VydCk7CiAgICAgICAgfSwKCiAgICAgICAgX2NvbmNhdCA6IGZ1bmN0aW9uKG9MaXN0KSB7CiAgICAgICAgICAgIGlmKG9MaXN0ID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIGZvcih2YXIgaSA9MDsgaTwgb0xpc3QubGVuZ3RoO2krKykgewogICAgICAgICAgICAgICAgdGhpcy5fYXBwZW5kKG9MaXN0Lml0ZW0oaSkpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbmFtZWRJdGVtIDogZnVuY3Rpb24ob1BhcmFtKXsKICAgICAgICAgICAgdmFyIG5vZGUgPSB0aGlzLl9maW5kKGZ1bmN0aW9uKG9iaikgewogICAgICAgICAgICAgICAgcmV0dXJuIG9iai5nZXRBdHRyaWJ1dGUoIm5hbWUiKSA9PT0gb1BhcmFtOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgaWYobm9kZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gbnVsbDsKICAgICAgICAgICAgcmV0dXJuIG5vZGU7CiAgICAgICAgfSwKCiAgICAgICAgX2ZpbmQgOiBmdW5jdGlvbihmbikgewogICAgICAgICAgICByZXR1cm4gXy5maW5kKHRoaXMubW9BcnJheWxpc3QsZm4pOwogICAgICAgIH0sCgogICAgICAgIF9maWx0ZXIgOiBmdW5jdGlvbihmbikgewogICAgICAgICAgICByZXR1cm4gXy5maWx0ZXIodGhpcy5tb0FycmF5bGlzdCxmbik7CiAgICAgICAgfQogICAgfSk7CgogICAgWGZhTGlzdC5kZWZpbmVQcm9wcyh7CiAgICAgICAgImxlbmd0aCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubW9BcnJheWxpc3QubGVuZ3RoOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYik7CgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5TT01FeHByZXNzaW9uCiAqIEBpbXBvcnQgeGZhbGliLnV0LkNsYXNzCiAqLwogCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIFNPTUV4cHJlc3Npb24gPSB4ZmFsaWIuc2NyaXB0LlNPTUV4cHJlc3Npb24gPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIFNPTUV4cHJlc3Npb24uX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgLy8gRm9ybWF0OiBzdWJmb3JtQVtufCpdCiAgICAgICAgICAgIC8vIEZvcm1hdDogc3ViZm9ybUFbbnwqXS5bcHJlZGljYXRlIGV4cHJdCiAgICAgICAgICAgIC8vIEZvcm1hdDogc3ViZm9ybUEuW3ByZWRpY2F0ZSBleHByXQogICAgICAgICAgICAvLyBwcmVkaWNhdGUgZXhwcjogYm9vbGVhbiBleHByZXNzaW9uIHRoYXQgbWF5IGluY2x1ZGUgb2JqZWN0IHJlZmVyZW5jZXMgYW5kCiAgICAgICAgICAgIC8vIFNPTUV4cHJlc3Npb25zCgogICAgICAgICAgICB0aGlzLl9leHByID0gdGhpcy5vcHRpb25zLmV4cHJlc3Npb247CiAgICAgICAgICAgIHRoaXMuc2NhbGVyTWF0Y2ggPSBudWxsOwogICAgICAgICAgICB0aGlzLnByZWRpY2F0ZSA9IG51bGw7CiAgICAgICAgICAgIHRoaXMubmFtZSA9IHRoaXMub3B0aW9ucy5leHByZXNzaW9uOwogICAgICAgICAgICB0aGlzLmluZGV4ID0gdGhpcy5vcHRpb25zLmRlZmF1bHRPY2N1cnJlbmNlOwogICAgICAgICAgICB0aGlzLl9iRGVmYXVsdEluZGV4ID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5fbWF0Y2hDb3VudCA9IDA7CgogICAgICAgICAgICB2YXIgYXJyID0gdGhpcy5fcGFyc2VFeHByZXNzaW9uKHRoaXMub3B0aW9ucy5leHByZXNzaW9uKTsKICAgICAgICAgICAgaWYgKGFyciA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICAgICAgaWYgKGFyci5sZW5ndGggPT0gMSkKICAgICAgICAgICAgICAgIHRoaXMubmFtZSA9IGFyclswXTsKICAgICAgICAgICAgZWxzZSBpZiAoYXJyLmxlbmd0aCA9PSAyKSB7CiAgICAgICAgICAgICAgICB0aGlzLm5hbWUgPSBhcnJbMF07CiAgICAgICAgICAgICAgICBpZiAoYXJyWzFdICE9ICcnKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gU3RyaXAgYnJhY2tldHMKICAgICAgICAgICAgICAgICAgICB2YXIgb2NjID0gYXJyWzFdLnN1YnN0cmluZygxLCBhcnJbMV0ubGVuZ3RoIC0gMSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKG9jYyA9PSAnKicpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5kZXggPSAnKic7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluZGV4ID0gcGFyc2VJbnQob2NjKTsKCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYkRlZmF1bHRJbmRleCA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKGFyci5sZW5ndGggPT0gMykgewogICAgICAgICAgICAgICAgdGhpcy5uYW1lID0gYXJyWzBdOwogICAgICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5pZ25vcmVQcmVkaWNhdGUgPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgICAgICAvLyBTdHJpcCBicmFja2V0cwogICAgICAgICAgICAgICAgICAgIHRoaXMucHJlZGljYXRlID0gYXJyWzJdLnN1YnN0cmluZygxLCBhcnJbMl0ubGVuZ3RoIC0gMSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmRleCA9ICcqJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGVxdWFscyA6IGZ1bmN0aW9uKG9iaikgewogICAgICAgICAgcmV0dXJuIHRoaXMubmFtZXNFcXVhbChvYmopIHx8IHRoaXMuY2xhc3Nlc0VxdWFsKG9iaik7CiAgICAgICAgfSwKCiAgICAgICAgZXZhbFByZWRpY2F0ZSA6IGZ1bmN0aW9uIChvYmopIHsKICAgICAgICAgICAgLy8gRGVmYXVsdDogdHJ1ZSwgaW5kaWNhdGluZyBvYmogcGFzc2VzIHByZWQgZXhwciBxdWFsaWZpY2F0aW9uCiAgICAgICAgICAgIHZhciBiUHJlZGljYXRlUmVzdWx0ID0gdHJ1ZTsKCiAgICAgICAgICAgIC8vVE9ETzogSW1wbGVtZW50IGxhdGVyCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICBpZiAodGhpcy5wcmVkaWNhdGUgIT0gbnVsbCAmJiBvYmogIT0gbnVsbCkKICAgICAgICAgICAgIHsKICAgICAgICAgICAgIHZhciBwYXJzZXI6S1BhcnNlciA9IG5ldyBLUGFyc2VyKCk7CiAgICAgICAgICAgICB2YXIgcmVzdWx0Ok9iamVjdCA9IHBhcnNlci5ldmFsdWF0ZUV4cHJlc3Npb24gKHRoaXMucHJlZGljYXRlLCBvYmopOwogICAgICAgICAgICAgaWYgKHJlc3VsdCBpcyBCb29sZWFuKQogICAgICAgICAgICAgewogICAgICAgICAgICAgdHJhY2UgKCJldmFsUHJlZGljYXRlKCkgb246ICIgKyB0aGlzLnByZWRpY2F0ZSArICIsIHJlc3VsdDogIiArIHJlc3VsdCk7CiAgICAgICAgICAgICBiUHJlZGljYXRlUmVzdWx0ID0gcmVzdWx0OwogICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmV0dXJuIGJQcmVkaWNhdGVSZXN1bHQ7CiAgICAgICAgfSwKCiAgICAgICAgbmFtZXNFcXVhbCA6IGZ1bmN0aW9uKG9iaikgewogICAgICAgICAgICBpZiAodGhpcy5uYW1lID09IG9iai5nZXRBdHRyaWJ1dGUoIm5hbWUiKSl7CiAgICAgICAgICAgICAgICB2YXIgYlByZWRSZXN1bHQgPSB0aGlzLmV2YWxQcmVkaWNhdGUob2JqKTsKCiAgICAgICAgICAgICAgICBpZiAoKCh0aGlzLmluZGV4ID09ICcqJykgfHwgKHRoaXMuaW5kZXggPT0gb2JqLmluZGV4KSkgJiYgYlByZWRSZXN1bHQgPT0gdHJ1ZSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgLy8gSWYgdGhlIFNPTSBleHByZXNzaW9uIGRvZXMgbm90IGhhdmUgYSBzcGVjaWZpYyBpbmRleAogICAgICAgICAgICAgICAgLy8gcmVjb3JkIGEgbmFtZSBtYXRjaCB3aXRoIHRoZSBvYmogd2l0aCB0aGUgbG93ZXN0IGluZGV4CiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgaWYgKHRoaXMuX2JEZWZhdWx0SW5kZXggJiYgYlByZWRSZXN1bHQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCh0aGlzLnNjYWxlck1hdGNoID09IG51bGwpIHx8IChvYmouaW5kZXggPCB0aGlzLnNjYWxlck1hdGNoLmluZGV4KSkKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zY2FsZXJNYXRjaCA9IG9iajsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgY2xhc3Nlc0VxdWFsIDogZnVuY3Rpb24gKCBvYmopewogICAgICAgICAgICB2YXIgYlJldCA9IGZhbHNlOwogICAgICAgICAgICB2YXIgYlByZWRSZXN1bHQgPSB0aGlzLmV2YWxQcmVkaWNhdGUob2JqKTsKCiAgICAgICAgICAgIGlmICh0aGlzLm5hbWUgPT0gIiMiK29iai5jbGFzc05hbWUpewogICAgICAgICAgICAgICAgaWYgKHRoaXMuaW5kZXggPT0gJyonICYmIGJQcmVkUmVzdWx0ID09IHRydWUpewogICAgICAgICAgICAgICAgICAgIGJSZXQgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZXsKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pbmRleCA9PSBvYmoubW5DbGFzc0luZGV4ICYmIGJQcmVkUmVzdWx0ID09IHRydWUpCiAgICAgICAgICAgICAgICAgICAgICAgIGJSZXQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgYlJldCA9IGZhbHNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBiUmV0OwogICAgICAgIH0sCgogICAgICAgIHRhZ0VxdWFscyA6IGZ1bmN0aW9uIChvYmopIHsKICAgICAgICAgICAgdmFyIHBhcmVudCA9IG9iai5wYXJlbnQ7CiAgICAgICAgICAgIHZhciBtYXg7CiAgICAgICAgICAgIGlmKHBhcmVudCkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICB2YXIgcmVsYXRpb24gPSBwYXJlbnQuX2dldFJlbGF0aW9uKG9iaik7CiAgICAgICAgICAgICAgICAgICAgaWYocmVsYXRpb24pCiAgICAgICAgICAgICAgICAgICAgICAgIG1heCA9IHJlbGF0aW9uLm1heDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhdGNoKGUpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5Mb2dnZXIuZGVidWcoInhmYSIsICJpbmNvbXBsZXRlIHNjaGVtYS4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvL2lmIHRoaXMgb2JqIGlzIHRoZSBvbmx5IHBvc3NpYmxlIGNoaWxkIG9mIGl0cyB0eXBlIHRoZW4gaWdub3JlIGNsYXNzIGluZGV4LgogICAgICAgICAgICByZXR1cm4gdGhpcy5uYW1lID09IG9iai5jbGFzc05hbWUgJiYgKG1heCA9PSAxIHx8IHRoaXMuaW5kZXggPT0nKicgfHwgdGhpcy5pbmRleCA9PSBvYmoubW5DbGFzc0luZGV4KQogICAgICAgIH0sCgogICAgICAgIF9wYXJzZUV4cHJlc3Npb24gOiBmdW5jdGlvbihzU29tRXhwcmVzc2lvbikgewogICAgICAgICAgICBpZiAoc1NvbUV4cHJlc3Npb24gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBhcnIgPSBbXTsKICAgICAgICAgICAgdmFyIGJ1ZiA9ICIiOwogICAgICAgICAgICB2YXIgaW5CcmFjZSA9IDA7CiAgICAgICAgICAgIHZhciBiRXNjYXBlID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAoIHZhciBqID0gMDsgaiA8IHNTb21FeHByZXNzaW9uLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICB2YXIgcyA9IHNTb21FeHByZXNzaW9uLmNoYXJBdChqKTsKICAgICAgICAgICAgICAgIGlmIChzID09ICJbIiAmJiAhaW5CcmFjZSkgewogICAgICAgICAgICAgICAgICAgIGluQnJhY2UrKzsKICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChidWYpOwogICAgICAgICAgICAgICAgICAgIGJ1ZiA9ICIiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHMgPT0gIlsiICYmIGluQnJhY2UpIHsKICAgICAgICAgICAgICAgICAgICBpbkJyYWNlKys7CiAgICAgICAgICAgICAgICAgICAgYnVmICs9IHM7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHMgPT0gIl0iICYmIGluQnJhY2UpIHsKICAgICAgICAgICAgICAgICAgICAtLWluQnJhY2U7CiAgICAgICAgICAgICAgICAgICAgYnVmICs9IHM7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHMgPT0gIlxcIikgewogICAgICAgICAgICAgICAgICAgIGJFc2NhcGUgPSB0cnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzID09ICIuIiAmJiAhaW5CcmFjZSAmJiAhYkVzY2FwZSkgewogICAgICAgICAgICAgICAgICAgIGFyci5wdXNoKGJ1Zik7CiAgICAgICAgICAgICAgICAgICAgYnVmID0gIiI7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGJ1ZiArPSBzOwogICAgICAgICAgICAgICAgICAgIGJFc2NhcGUgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoaiA9PSBzU29tRXhwcmVzc2lvbi5sZW5ndGggLSAxKQogICAgICAgICAgICAgICAgICAgIGFyci5wdXNoKGJ1Zik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGFycjsKICAgICAgICB9LAoKICAgICAgICBzcGxpdEV4cHJlc3Npb24gOiBmdW5jdGlvbihzU29tRXhwcmVzc2lvbikgewogICAgICAgICAgICBpZiAoc1NvbUV4cHJlc3Npb24gPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwoKICAgICAgICAgICAgdmFyIGFyciA9IFtdOwogICAgICAgICAgICB2YXIgYnVmID0gIiI7CiAgICAgICAgICAgIHZhciBpbkJyYWNlID0gMDsKICAgICAgICAgICAgdmFyIGJFc2NhcGUgPSBmYWxzZTsKICAgICAgICAgICAgZm9yICggdmFyIGogPSAwOyBqIDwgc1NvbUV4cHJlc3Npb24ubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgIHZhciBzID0gc1NvbUV4cHJlc3Npb24uY2hhckF0KGopOwogICAgICAgICAgICAgICAgaWYgKHMgPT0gIlsiKSB7CiAgICAgICAgICAgICAgICAgICAgaW5CcmFjZSsrOwogICAgICAgICAgICAgICAgICAgIGJ1ZiArPSBzOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzID09ICJdIikgewogICAgICAgICAgICAgICAgICAgIC0taW5CcmFjZTsKICAgICAgICAgICAgICAgICAgICBidWYgKz0gczsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocyA9PSAiXFwiKSB7CiAgICAgICAgICAgICAgICAgICAgYkVzY2FwZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnVmICs9IHM7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHMgPT0gIi4iICYmIGluQnJhY2UgPT0gMCAmJiBiRXNjYXBlID09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJ1Zi5sZW5ndGggPT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnB1c2goIi4uIik7IC8vIGVsaXBzaXMKICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJ1Zi5pbmRleE9mKCIjdmFyaWFibGVzIikgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChidWYpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJ1ZiA9ICIiOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBidWYgKz0gczsKICAgICAgICAgICAgICAgICAgICBiRXNjYXBlID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKGogPT0gc1NvbUV4cHJlc3Npb24ubGVuZ3RoIC0gMSkgewogICAgICAgICAgICAgICAgICAgIGlmIChidWYuaW5kZXhPZigiI3ZhcmlhYmxlcyIpIDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChidWYpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGFyci5sZW5ndGggPT0gMSkKICAgICAgICAgICAgICAgIHJldHVybiBhcnI7CgogICAgICAgICAgICB2YXIgb3V0ID0gW107CiAgICAgICAgICAgIHZhciBwYXR0ZXJuID0gL15cWy4qXF0vOwogICAgICAgICAgICBmb3IgKCB2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBzZWcgPSBTdHJpbmcoYXJyW2ldKTsKICAgICAgICAgICAgICAgIGlmIChzZWcubWF0Y2gocGF0dGVybikgJiYgaSA+IDApCiAgICAgICAgICAgICAgICAgICAgb3V0LnNwbGljZShpIC0gMSwgMSwgYXJyW2kgLSAxXSArICIuIiArIHNlZyk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgb3V0LnB1c2goYXJyW2ldKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gb3V0OwogICAgICAgIH0KCiAgICB9KTsKCiAgICBTT01FeHByZXNzaW9uLmRlZmluZVByb3BzKHsKICAgICAgICAiZXhwcmVzc2lvbiIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V4cHI7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKGV4cHJlc3Npb24pIHsgICAgICAgICAgICAJCiAgICAgICAgICAgIAlleHByZXNzaW9uID0gdGhpcy52YWxpZGF0ZUlucHV0KGV4cHJlc3Npb24sInN0cmluZyIpOwogICAgICAgICAgICAgICAgdGhpcy5fZXhwciA9IGV4cHJlc3Npb247CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CgoKCi8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk9iamVjdAogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIFhmYU1vZGVsRXZlbnQgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwooZnVuY3Rpb24oXyx4ZmFsaWIpIHsKCiAgICB2YXIgWGZhTW9kZWxFdmVudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudCA9IHhmYWxpYi5zY3JpcHQuT2JqZWN0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJldmVudFBzZXVkb01vZGVsIgogICAgfSk7CgogICAgWGZhTW9kZWxFdmVudC5kZWZpbmVQcm9wcyh7CiAgICAgICAgInByZXZUZXh0IiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmpzb25Nb2RlbC5wcmV2VGV4dDsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgIm5ld1RleHQiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuanNvbk1vZGVsLm5ld1RleHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJmdWxsVGV4dCI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwuZnVsbFRleHQ7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJuYW1lIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmpzb25Nb2RlbC5uYW1lOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAia2V5RG93biIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwua2V5RG93bjsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgIm1vZGlmaWVyIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmpzb25Nb2RlbC5tb2RpZmllcjsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInRhcmdldCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwudGFyZ2V0OwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAic2hpZnQiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuanNvbk1vZGVsLnNoaWZ0OwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbmdlIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmpzb25Nb2RlbC5jaGFuZ2U7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLmNoYW5nZSA9IHZhbHVlOwogICAgICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCx0aGlzLnRhcmdldCwKICAgICAgICAgICAgICAgICAgICAnY2hhbmdlJyx2YWx1ZSxudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0LnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiX3Byb3BlcnR5IiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmpzb25Nb2RlbC5fcHJvcGVydHk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC5fcHJvcGVydHkgPSB2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKICAgIFhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQgPSBmdW5jdGlvbihubSx0Z3QscHJvcCxvbGRWYWwsbmV3VmFsKSB7CiAgICAgICAgdmFyIGV2bnQgPSB7CiAgICAgICAgICAgIG5hbWU6bm0sCiAgICAgICAgICAgIHRhcmdldDp0Z3QsCiAgICAgICAgICAgIF9wcm9wZXJ0eTpwcm9wLAogICAgICAgICAgICBwcmV2VGV4dDpvbGRWYWwsCiAgICAgICAgICAgIG5ld1RleHQ6bmV3VmFsCiAgICAgICAgfTsKICAgICAgICByZXR1cm4gbmV3IFhmYU1vZGVsRXZlbnQoeyJqc29uTW9kZWwiIDogZXZudH0pOwogICAgfTsKCiAgICBYZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCA9ICJmb3JtTW9kZWxDaGFuZ2VkIjsKICAgIFhmYU1vZGVsRXZlbnQuUkFXX1ZBTFVFX0NIQU5HRUQgPSAicmF3VmFsdWVDaGFuZ2VkIjsKICAgIFhmYU1vZGVsRXZlbnQuQ0hJTERfQURERUQgPSAiY2hpbGRBZGRlZCI7CiAgICBYZmFNb2RlbEV2ZW50LkNISUxEX1JFTU9WRUQgPSAiY2hpbGRSZW1vdmVkIjsKICAgIFhmYU1vZGVsRXZlbnQuQ0hJTERfTU9WRUQgPSAiY2hpbGRNb3ZlZCI7CiAgICBYZmFNb2RlbEV2ZW50Lk9CSkVDVF9ERVNUUk9ZRUQgPSAib2JqZWN0RGVzdHJveWVkIjsKICAgIFhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9SRUZSRVNIID0gImZvcm1Nb2RlbFJlZnJlc2giOwogICAgWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCA9ICJkb21DaGFuZ2VkIjsKfSkoXyx4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5MYXlvdXQKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LkNsYXNzCiAqLwoKKGZ1bmN0aW9uKF8sIHhmYWxpYil7CiAgICB2YXIgTGF5b3V0ID0geGZhbGliLnNjcmlwdC5MYXlvdXQgPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdGhpcy5wYWdpbmdNYW5hZ2VyID0gbnVsbCA7CiAgICAgICAgICAgIExheW91dC5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwoKICAgICAgICB9LAoKICAgICAgICBfeGZhIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB4ZmFsaWIuc2NyaXB0LlhmYS5JbnN0YW5jZTsKICAgICAgICB9LAoKICAgICAgICByZWxheW91dDogZnVuY3Rpb24oKSB7CiAgICAgICAgfSwKCiAgICAgICAgcGFnZTogZnVuY3Rpb24obm9kZSl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnBhZ2luZ01hbmFnZXIuZmluZFBhZ2Uobm9kZS5odG1sSWQpICsgMTsKICAgICAgICB9LAoKICAgICAgICBwYWdlQ291bnQ6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpZih0aGlzLnBhZ2luZ01hbmFnZXIpCiAgICAgICAgICAgICAgICByZXR1cm4odGhpcy5wYWdpbmdNYW5hZ2VyLnBhZ2VDb3VudCgpKTsKICAgICAgICB9LAoKICAgICAgICBhYnNQYWdlQ291bnQ6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpZih0aGlzLnBhZ2luZ01hbmFnZXIpCiAgICAgICAgICAgICAgICByZXR1cm4odGhpcy5wYWdpbmdNYW5hZ2VyLnBhZ2VDb3VudCgpKTsKICAgICAgICB9LAoKICAgICAgICBwYWdlQ29udGVudCA6IGZ1bmN0aW9uKHBhZ2VOdW0sIGNsYXNzTmFtZSwgYlBhZ2VBcmVhKXsKICAgICAgICAgICAgaWYodGhpcy5wYWdpbmdNYW5hZ2VyKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBhZ2luZ01hbmFnZXIuX3BhZ2VDb250ZW50KHBhZ2VOdW0sIGNsYXNzTmFtZSwgYlBhZ2VBcmVhKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgIH0sCgogICAgICAgIHB4MnB0OiBmdW5jdGlvbihweCkgewogICAgICAgICAgICByZXR1cm4gcHgvMjsKICAgICAgICB9LAoKICAgICAgICBwdDJpbmNoOiBmdW5jdGlvbihwdCkgewogICAgICAgICAgICByZXR1cm4gcHQvNzI7CiAgICAgICAgfSwKCiAgICAgICAgcHQybW06IGZ1bmN0aW9uKHB0KSB7CiAgICAgICAgICAgIHJldHVybiAocHQqMjUuNCkvNzI7CiAgICAgICAgfSwKCiAgICAgICAgaDogZnVuY3Rpb24obm9kZSwgdW5pdCwgb2Zmc2V0KSB7CiAgICAgICAgICAgIGlmKHRoaXMucGFnaW5nTWFuYWdlcikgICAgewogICAgICAgICAgICAgICAgdGhpcy5wYWdpbmdNYW5hZ2VyLl9tYWtlUGFnZUZvckh0bWxJZChub2RlLmh0bWxJZCk7CiAgICAgICAgICAgICAgICB2YXIgbGF5b3V0ID0gdGhpcy5wYWdpbmdNYW5hZ2VyLmdldExheW91dChub2RlLmh0bWxJZCk7CiAgICAgICAgICAgICAgICBpZihsYXlvdXQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaCA9IHRoaXMucHgycHQobGF5b3V0LmV4dGVudGgpIDsKICAgICAgICAgICAgICAgICAgICBpZih1bml0ID09ICJpbmNoIiB8fCB1bml0ID09ICJpbiIpCiAgICAgICAgICAgICAgICAgICAgICAgIGggPSB0aGlzLnB0MmluY2goaCk7CiAgICAgICAgICAgICAgICAgICAgaWYodW5pdCA9PSAibW0iKQogICAgICAgICAgICAgICAgICAgICAgICBoID0gdGhpcy5wdDJtbShoKTsKICAgICAgICAgICAgICAgICAgICBpZihvZmZzZXQgIT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgICAgICAgICBoPSAwOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBoOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSByZXR1cm4gMDsKCiAgICAgICAgICAgIH0KCiAgICAgICAgfSwKCiAgICAgICAgdzogZnVuY3Rpb24obm9kZSwgdW5pdCwgb2Zmc2V0KSB7CiAgICAgICAgICAgIGlmKHRoaXMucGFnaW5nTWFuYWdlcikgICAgewogICAgICAgICAgICAgICAgdGhpcy5wYWdpbmdNYW5hZ2VyLl9tYWtlUGFnZUZvckh0bWxJZChub2RlLmh0bWxJZCk7CiAgICAgICAgICAgICAgICB2YXIgbGF5b3V0ID0gdGhpcy5wYWdpbmdNYW5hZ2VyLmdldExheW91dChub2RlLmh0bWxJZCk7CiAgICAgICAgICAgICAgICBpZihsYXlvdXQpICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciB3ID0gdGhpcy5weDJwdChsYXlvdXQuZXh0ZW50dykgOwogICAgICAgICAgICAgICAgICAgIGlmKHVuaXQgPT0gImluY2giIHx8IHVuaXQgPT0gImluIikKICAgICAgICAgICAgICAgICAgICAgICAgdyA9IHRoaXMucHQyaW5jaCh3KTsKICAgICAgICAgICAgICAgICAgICBpZih1bml0ID09ICJtbSIpCiAgICAgICAgICAgICAgICAgICAgICAgIHcgPSB0aGlzLnB0Mm1tKHcpOwogICAgICAgICAgICAgICAgICAgIGlmKG9mZnNldCAhPSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIHc9IDA7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHcgOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSByZXR1cm4gMDsKCiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICB4OiBmdW5jdGlvbihub2RlLCB1bml0LCBvZmZzZXQpIHsKICAgICAgICAgICAgaWYodGhpcy5wYWdpbmdNYW5hZ2VyKSAgICB7CiAgICAgICAgICAgICAgICB0aGlzLnBhZ2luZ01hbmFnZXIuX21ha2VQYWdlRm9ySHRtbElkKG5vZGUuaHRtbElkKTsKICAgICAgICAgICAgICAgIHZhciBsYXlvdXQgPSB0aGlzLnBhZ2luZ01hbmFnZXIuZ2V0TGF5b3V0KG5vZGUuaHRtbElkKTsKICAgICAgICAgICAgICAgIGlmKGxheW91dCl7CiAgICAgICAgICAgICAgICAgICAgdmFyIHggPSB0aGlzLnB4MnB0KGxheW91dC5leHRlbnR4KSA7CiAgICAgICAgICAgICAgICAgICAgaWYodW5pdCA9PSAiaW5jaCIgfHwgdW5pdCA9PSAiaW4iKQogICAgICAgICAgICAgICAgICAgICAgICB4ID0gdGhpcy5wdDJpbmNoKHgpOwogICAgICAgICAgICAgICAgICAgIGlmKHVuaXQgPT0gIm1tIikKICAgICAgICAgICAgICAgICAgICAgICAgeCA9IHRoaXMucHQybW0oeCk7CiAgICAgICAgICAgICAgICAgICAgaWYob2Zmc2V0ICE9IHVuZGVmaW5lZCkKICAgICAgICAgICAgICAgICAgICAgICAgeD0gMDsKICAgICAgICAgICAgICAgICAgICByZXR1cm4geDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgcmV0dXJuIDA7CgogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgeTogZnVuY3Rpb24obm9kZSwgdW5pdCwgb2Zmc2V0KSB7CiAgICAgICAgICAgIGlmKHRoaXMucGFnaW5nTWFuYWdlcikgICAgewogICAgICAgICAgICAgICAgdGhpcy5wYWdpbmdNYW5hZ2VyLl9tYWtlUGFnZUZvckh0bWxJZChub2RlLmh0bWxJZCk7CiAgICAgICAgICAgICAgICB2YXIgbGF5b3V0ID0gdGhpcy5wYWdpbmdNYW5hZ2VyLmdldExheW91dChub2RlLmh0bWxJZCk7CiAgICAgICAgICAgICAgICBpZihsYXlvdXQpewogICAgICAgICAgICAgICAgICAgIHZhciB5ID0gdGhpcy5weDJwdChsYXlvdXQuZXh0ZW50eSkgOwogICAgICAgICAgICAgICAgICAgIGlmKHVuaXQgPT0gImluY2giIHx8IHVuaXQgPT0gImluIikKICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHRoaXMucHQyaW5jaCh5KTsKICAgICAgICAgICAgICAgICAgICBpZih1bml0ID09ICJtbSIpCiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSB0aGlzLnB0Mm1tKHkpOwogICAgICAgICAgICAgICAgICAgIGlmKG9mZnNldCAhPSB1bmRlZmluZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIHk9IDA7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHJldHVybiAwOwoKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKICAgIExheW91dC5kZWZpbmVQcm9wcyh7CiAgICAgICAgInJlYWR5IiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYik7CgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5Ob2RlCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5PYmplY3QKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LlNPTUV4cHJlc3Npb24KICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LlhmYUxpc3QKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBOb2RlIENsYXNzIHJlcXVpcmVkIGZvciBYRkEgbGlicmFyeQogKiBAdmVyc2lvbiAwLjAuMQogKi8KCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBOb2RlID0geGZhbGliLnNjcmlwdC5Ob2RlID0geGZhbGliLnNjcmlwdC5PYmplY3QuZXh0ZW5kKHsKICAgICAgICBfZGVmYXVsdHMgOiB7CiAgICAgICAgICAgICJwcmVzZW5jZSIgOiAidmlzaWJsZSIKICAgICAgICB9LAoKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgTm9kZS5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgICAgICogQHR5cGUgeGZhbGliLnNjcmlwdC5Ob2RlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB0aGlzLm1QYXJlbnQgPSBudWxsOwogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgICAgICogQHR5cGUgc3RyaW5nCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB0aGlzLm1uSW5kZXggPSAwOwogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgICAgICogQHR5cGUgc3RyaW5nCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB0aGlzLm1uQ2xhc3NJbmRleCA9IDA7CiAgICAgICAgfSwKCiAgICAgICAgcGxheUpzb24gOiBmdW5jdGlvbihwSnNvbk1vZGVsKSB7CiAgICAgICAgICAgIC8vIHRhYkluZGV4IHNob3VsZCBiZSBleGVtcHRlZCBiZWNhdXNlIHdlIGFyZSBhbHJlYWR5IGNvbXB1dGluZyBpdCBpbiBfaW5zZXJ0IEluc3RhbmNlCiAgICAgICAgICAgIC8vIENRLTQzMjQ5NzA6IHJlcGxhY2UgZGVmYXVsdCBGU19EQVRBX1NPTSBwcmVzZW50IGluIEZTX0VYVFJBUyB3aXRoIGRhdGFTb20gcHJlc2VudCBpbiBleHRyYXMgZm9yIHJlcGVhdGVkIGVsZW1lbnRzLgogICAgICAgICAgICB0aGlzLnNldEZzRGF0YVNvbShwSnNvbk1vZGVsKTsKICAgICAgICAgICAgdGhpcy5jb3B5T2JqZWN0KHBKc29uTW9kZWwsIHRoaXMuanNvbk1vZGVsLCB7ZXhjZXB0aW9ucyA6IFsiaHRtbElkIiwgImNoaWxkcmVuIiwidGFiSW5kZXgiXSwga2VlcFJlZmVyZW5jZSA6IHRydWV9KTsKICAgICAgICB9LAoKICAgICAgICBzZXRGc0RhdGFTb20gOiBmdW5jdGlvbihwSnNvbk1vZGVsKSB7CiAgICAgICAgICAgIGlmICh3aW5kb3cuRkQgJiYgd2luZG93LkZELmlzVG9nZ2xlRW5hYmxlZCgiRlRfRk9STVMtMTQzNDkiKSkgeyAvLyBGT1JNUy0xMDczMSA6IGRvbid0IGNoYW5nZSBGU19EQVRBX1NPTSBpZiBmaWVsZCBpcyBub3QgbmFtZWQuCiAgICAgICAgICAgICAgICB0aGlzLnNldEZzRGF0YVNvbVZhbHVlKHBKc29uTW9kZWwpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIikgJiYgdGhpcy5nZXRBdHRyaWJ1dGUoIm5hbWUiKS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRGc0RhdGFTb21WYWx1ZShwSnNvbk1vZGVsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHNldEZzRGF0YVNvbVZhbHVlIDogZnVuY3Rpb24ocEpzb25Nb2RlbCkgewogICAgICAgICAgICB2YXIgZnNEYXRhU29tID0gdGhpcy5yZXNvbHZlTm9kZSgiI2V4dHJhcy5GU19FWFRSQVMuRlNfREFUQV9TT00iKTsKICAgICAgICAgICAgaWYgKGZzRGF0YVNvbSAmJiBwSnNvbk1vZGVsLmV4dHJhcyAmJiBwSnNvbk1vZGVsLmV4dHJhcy5kYXRhU29tKSB7CiAgICAgICAgICAgICAgICBmc0RhdGFTb20udmFsdWUgPSBwSnNvbk1vZGVsLmV4dHJhcy5kYXRhU29tOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLy9UT0RPOiBSRU1PVkUgdGhpcyB3aGVuIHRoZSBhY3R1YWwgaW1wbGVtZW50YXRpb24gaXMgYXZhaWxhYmxlCiAgICAgICAgc2F2ZVhNTCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gIiI7CiAgICAgICAgfSwKCiAgICAgICAgLy9UT0RPOiBSRU1PVkUgdGhpcyB3aGVuIHRoZSBhY3R1YWwgaW1wbGVtZW50YXRpb24gaXMgYXZhaWxhYmxlCiAgICAgICAgbG9hZFhNTCA6IGZ1bmN0aW9uKCkgewogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmYgOiBmdW5jdGlvbihkaWZmX2xldmVsKXsKICAgICAgICAgICAgdmFyIGRlc3QgPSB7fTsKICAgICAgICAgICAgZGVzdC5fY2xhc3MgPSB0aGlzLmNsYXNzTmFtZTsKICAgICAgICAgICAgaWYodGhpcy5qc29uTW9kZWwuaGFzT3duUHJvcGVydHkoIm5hbWUiKSl7CiAgICAgICAgICAgICAgICBkZXN0Lm5hbWUgPSB0aGlzLmpzb25Nb2RlbC5uYW1lOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciBjaGFuZ2VGb3VuZCA9IGZhbHNlOwogICAgICAgICAgICB2YXIgaW5pdGlhbEpzb24gPSB0aGlzLl94ZmEoKS5feGZhVGVtcGxhdGVDYWNoZS5nZXRJbml0aWFsRm9ybURvbVJlZih0aGlzLmh0bWxJZCk7CiAgICAgICAgICAgIGlmKCFpbml0aWFsSnNvbikKICAgICAgICAgICAgICAgIGluaXRpYWxKc29uID0gdGhpcy5feGZhKCkuX3hmYVRlbXBsYXRlQ2FjaGUuZ2V0SW5pdGlhbEZvcm1Eb21SZWYodGhpcy5fdGVtcGxhdGVJZCgpKSB8fCB7fTsKICAgICAgICAgICAgdmFyIGluaXRpYWxQcm9wTGVuZ3RoID0gXy5maWx0ZXIoaW5pdGlhbEpzb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpewogICAgICAgICAgICAgICAgcmV0dXJuIGtleSAhPSJleHRyYXMiOwogICAgICAgICAgICB9LCB0aGlzKS5sZW5ndGg7CiAgICAgICAgICAgIHZhciBqc29uUHJvcExlbmd0aCA9IF8uZmlsdGVyKHRoaXMuanNvbk1vZGVsLCBmdW5jdGlvbih2YWx1ZSwga2V5KXsKICAgICAgICAgICAgICAgIHJldHVybiBrZXkgIT0iZXh0cmFzIjsKICAgICAgICAgICAgfSwgdGhpcykubGVuZ3RoOwoKICAgICAgICAgICAgaWYoanNvblByb3BMZW5ndGggIT0gaW5pdGlhbFByb3BMZW5ndGgpewogICAgICAgICAgICAgICAgLy9XZSBuZWVkIHRvIGNvbXBhcmUgcHJvcGVydHkgc2l6ZXMgd2l0aG91dCAnZXh0cmEnIHByb3BlcnR5IHNpbmNlIHRoaXMgaXMgbm90IGFjdHVhbGx5IHBhcnQgb2Ygc2NoZW1hCiAgICAgICAgICAgICAgICBjaGFuZ2VGb3VuZCA9IGRpZmZfbGV2ZWw9PT0wOyAgIC8vIG9ubHkgbmVlZCBfY2xhc3MgYW5kIG5hbWUgZHVyaW5nIHN1Ym1pc3Npb24gJiByZXN0b3JlRm9ybVN0YXRlCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIF8uZWFjaCh0aGlzLmpzb25Nb2RlbCwgZnVuY3Rpb24odmFsdWUsIGtleSl7CiAgICAgICAgICAgICAgICBpZihrZXkgPT09ICJfY2xhc3MiIHx8IGtleSA9PT0gImNoaWxkcmVuIiB8fCBrZXkgPT09ICJleHRyYXMiIHx8IGtleSA9PSAie2RlZmF1bHR9Iil7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy9Ob3RlOiBXZSBhcmUgYXNzdW1pbmcgdGhhdCBhbnkga2V5IHRoYXQgaXMgcHJlc2VudCBpbiB0ZW1wbGF0ZUpzb24gd291bGQgYWxzbyBiZSB0aGVyZSBpbiBtb2RlbCBqc29uIHRob3VnaCBpdCdzIHZhbHVlIG1heSBiZSBudWxsL3VuZGVmaW5lZAogICAgICAgICAgICAgICAgICAgIGlmKHZhbHVlICE9PSBpbml0aWFsSnNvbltrZXldKXsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoXy5pc0FycmF5KHZhbHVlKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmVycm9yKCJ4ZmEiLCAia2V5OiIra2V5ICsgIiBoYXMgdW5leHBlY3RlZCBhcnJheSB2YWx1ZToiK0pTT04uc3RyaW5naWZ5KHZhbHVlKSArICJwYXJlbnQ6XG4iKyBKU09OLnN0cmluZ2lmeShzcmMpKSA7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZihfLmlzT2JqZWN0KHZhbHVlKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmVycm9yKCJ4ZmEiLCAia2V5OiIra2V5ICsgIiBoYXMgdW5leHBlY3RlZCBvYmplY3QgdmFsdWU6IitKU09OLnN0cmluZ2lmeSh2YWx1ZSkgKyAicGFyZW50OlxuIisgSlNPTi5zdHJpbmdpZnkoc3JjKSkgOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlmZl9sZXZlbD09PTApIHsgICAvLyBvbmx5IG5lZWQgX2NsYXNzIGFuZCBuYW1lIGR1cmluZyBzdWJtaXNzaW9uICYgcmVzdG9yZUZvcm1TdGF0ZSwgcmVzdCB3aWxsIHN0cmlwcGVkIGJ5IGNvbXB1dGVKc29uRElmZi1zCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdFtrZXldID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlRm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgIC8vd2UgYXJlIHNlbmRpbmcgYWRkaXRpb25hbCBwcm9wZXJ0aWVzIGxpa2UgYWNjZXNzIGFuZCBwcmVzZW5jZSBmb3IgZGlmZl9sZXZlbCAzIGFzIGEgdGVtcCBmaXggZm9yIGN1c3RvbWVyCiAgICAgICAgICAgIGlmIChkaWZmX2xldmVsID09PSAxIHx8ICh3aW5kb3cuRkQgJiYgd2luZG93LkZELmlzVG9nZ2xlRW5hYmxlZCgiRlRfRk9STVMtMjA0OTMiKSAmJiBkaWZmX2xldmVsID09PSAzKSkgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX3hmYSgpLl90ZW1wbGF0ZVNjaGVtYS5oYXNBdHRyaWJ1dGUodGhpcy5jbGFzc05hbWUsICdhY2Nlc3MnKSAmJgogICAgICAgICAgICAgICAgICAgIF8uY29udGFpbnMoWyJleGNsR3JvdXAiLCAiZmllbGQiLCAic3ViZm9ybSJdLCB0aGlzLmNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBkZXN0LmFjY2VzcyA9IHRoaXMuanNvbk1vZGVsLmFjY2VzczsKICAgICAgICAgICAgICAgICAgICBjaGFuZ2VGb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAodGhpcy5feGZhKCkuX3RlbXBsYXRlU2NoZW1hLmhhc0F0dHJpYnV0ZSh0aGlzLmNsYXNzTmFtZSwgJ3ByZXNlbmNlJykgJiYKICAgICAgICAgICAgICAgICAgICBfLmNvbnRhaW5zKFsiZXhjbEdyb3VwIiwgImZpZWxkIiwgIml0ZW1zIiwgInN1YmZvcm0iLCAiZHJhdyJdLCB0aGlzLmNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBkZXN0LnByZXNlbmNlID0gdGhpcy5qc29uTW9kZWwucHJlc2VuY2U7CiAgICAgICAgICAgICAgICAgICAgY2hhbmdlRm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB7ImNoYW5nZWQiIDogY2hhbmdlRm91bmQsCiAgICAgICAgICAgICAgICBqc29uRGlmZmVyZW5jZSA6IGRlc3QKICAgICAgICAgICAgfTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0U29tRXhwcmVzc2lvbiA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpZiAodGhpcy5tUGFyZW50ID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gInhmYVswXS4iICsgdGhpcy5fZXNjYXBlUXVhbGlmaWVkTmFtZSgpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tUGFyZW50LnNvbUV4cHJlc3Npb24gKyAiLiIgKyB0aGlzLl9lc2NhcGVRdWFsaWZpZWROYW1lKCk7CiAgICAgICAgfSwKCiAgICAgICAgX2VzY2FwZVF1YWxpZmllZE5hbWUgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIG5hbWUgPSAiIyIgKyB0aGlzLmNsYXNzTmFtZSwKICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5tbkNsYXNzSW5kZXgsCiAgICAgICAgICAgICAgICBvYmpOYW1lID0gdGhpcy5nZXRBdHRyaWJ1dGUoIm5hbWUiKQogICAgICAgICAgICBpZiAob2JqTmFtZS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICBuYW1lID0gb2JqTmFtZTsKICAgICAgICAgICAgICAgIGluZGV4ID0gdGhpcy5pbmRleDsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgcW5hbWUgPSBuYW1lICsgIlsiICsgaW5kZXggKyAiXSI7CiAgICAgICAgICAgIHJldHVybiBxbmFtZS5yZXBsYWNlKC9cLi8sICJcXC4iKTsKICAgICAgICB9LAoKICAgICAgICBfeGZhIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB4ZmFsaWIuc2NyaXB0LlhmYS5JbnN0YW5jZTsKICAgICAgICB9LAoKICAgICAgICBfcmVzZXREYXRhOiBmdW5jdGlvbigpIHsKCiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogRXZhbHVhdGVzIHRoZSBzcGVjaWZpZWQgU09NIGV4cHJlc3Npb24sIGJlZ2lubmluZyB3aXRoIHRoZSBjdXJyZW50IFhNTCBmb3JtCiAgICAgICAgICogb2JqZWN0IG1vZGVsIG9iamVjdCwgYW5kIHJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBvYmplY3Qgc3BlY2lmaWVkIGluIHRoZSBTT00KICAgICAgICAgKiBleHByZXNzaW9uCiAgICAgICAgICoKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKi8KICAgICAgICByZXNvbHZlTm9kZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgbm9kZXMgPSBudWxsOwogICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAxKQogICAgICAgICAgICAgICAgbm9kZXMgPSB0aGlzLl9yZXNvbHZlTm9kZXNDb21tb24odGhpcywgYXJndW1lbnRzWzBdLCBmYWxzZSwgdHJ1ZSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIG5vZGVzID0gdGhpcy5fcmVzb2x2ZU5vZGVzQ29tbW9uKGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLCBmYWxzZSwKICAgICAgICAgICAgICAgICAgICB0cnVlKTsKCiAgICAgICAgICAgIGlmIChub2RlcyAmJiBub2Rlcy5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgcmV0dXJuIG5vZGVzLml0ZW0oMCk7CiAgICAgICAgICAgIGVsc2UgewoKICAgICAgICAgICAgICAgIC8veGZhLkxvZ2dlci5kZWJ1ZygicmVzb2x2ZU5vZGUgZm9yIHNvbUV4cHJlc3Npb24gIiArIGFyZ3VtZW50c1sxXQogICAgICAgICAgICAgICAgLy8gICAgKyAiIGZhaWxlZCIpOwogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBFdmFsdWF0ZXMgdGhlIHNwZWNpZmllZCBTT00gZXhwcmVzc2lvbiwgYmVnaW5uaW5nIHdpdGggdGhlIGN1cnJlbnQgWE1MIGZvcm0KICAgICAgICAgKiBvYmplY3QgbW9kZWwgb2JqZWN0LCBhbmQgcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIG9iamVjdCBzcGVjaWZpZWQgaW4gdGhlIFNPTQogICAgICAgICAqIGV4cHJlc3Npb24KICAgICAgICAgKgogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqLwogICAgICAgIHJlc29sdmVOb2RlcyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgbm9kZXMgPSBudWxsOwogICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAxKQogICAgICAgICAgICAgICAgbm9kZXMgPSB0aGlzLl9yZXNvbHZlTm9kZXNDb21tb24odGhpcywgYXJndW1lbnRzWzBdLCB0cnVlLCB0cnVlKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbm9kZXMgPSB0aGlzLl9yZXNvbHZlTm9kZXNDb21tb24oYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0sIHRydWUsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gbm9kZXM7CiAgICAgICAgfSwKCiAgICAgICAgX29iakluTGlzdDogZnVuY3Rpb24ob2JqKSB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICBsaXN0Ll9hcHBlbmQob2JqKTsKICAgICAgICAgICAgcmV0dXJuIGxpc3Q7CiAgICAgICAgfSwKCiAgICAgICAgX2ZpbmRQcm9wZXJ0eTogZnVuY3Rpb24ob1NvbSkgewogICAgICAgICAgICB2YXIgYXJyID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgaWYob1NvbS5pbmRleCA9PSAwKSB7CiAgICAgICAgICAgICAgLy9jaGVjayB3aGV0aGVyIHNvbSBpcyBhIGR5bmFtaWMgcHJvcGVydHkKICAgICAgICAgICAgICBpZih0aGlzLnJlc29sdmVQcm9wZXJ0aWVzICYmIHRoaXMucmVzb2x2ZVByb3BlcnRpZXMuaW5kZXhPZihvU29tLm5hbWUpICE9IC0xKQogICAgICAgICAgICAgICAgYXJyLl9hcHBlbmQodGhpc1tvU29tLm5hbWVdKQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGFycjsKICAgICAgICB9LAoKICAgICAgICBfcmVzb2x2ZU5vZGVzQ29tbW9uIDogZnVuY3Rpb24ob2JqLCBzU29tRXhwcmVzc2lvbiwgYk11bHRpcGxlLCBiRmlyc3QpIHsKICAgICAgICAgICAgdmFyIGFycjEgPSB4ZmFsaWIuc2NyaXB0LlNPTUV4cHJlc3Npb24ucHJvdG90eXBlLnNwbGl0RXhwcmVzc2lvbihzU29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgIGlmKGFycjFbMF0gPT0gJyQnKSB7CiAgICAgICAgICAgICAgICBhcnIxLnNwbGljZSgwLDEsdGhpcy5zb21FeHByZXNzaW9uKTsKICAgICAgICAgICAgICAgIHNTb21FeHByZXNzaW9uID0gYXJyMS5qb2luKCIuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoYXJyMVswXS5jaGFyQXQoMCkgPT0gJyQnIHx8IGFycjFbMF0gPT0gJ3hmYScgfHwgYXJyMVswXSA9PSAndGhpcycpIHsKICAgICAgICAgICAgICAgIHZhciByb290LCBpID0gYXJyMVswXS5sZW5ndGggKyAxOwogICAgICAgICAgICAgICAgc3dpdGNoKGFycjFbMF0pIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJ4ZmEiOgogICAgICAgICAgICAgICAgICAgIGNhc2UgIiR4ZmEiOgogICAgICAgICAgICAgICAgICAgICAgICByb290ID0gdGhpcy5feGZhKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIiR0ZW1wbGF0ZSI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJvb3QgPSB0aGlzLl94ZmEoKS50ZW1wbGF0ZQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICIkZm9ybSI6CiAgICAgICAgICAgICAgICAgICAgICAgIHJvb3QgPSB0aGlzLl94ZmEoKS5mb3JtOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJ0aGlzIjoKICAgICAgICAgICAgICAgICAgICAgICAgcm9vdCA9IHRoaXMuX3hmYSgpLl9jb250ZXh0Tm9kZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGFycjEubGVuZ3RoID09IDEpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29iakluTGlzdChyb290KQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc29sdmVOb2Rlc0NvbW1vbihyb290LHNTb21FeHByZXNzaW9uCiAgICAgICAgICAgICAgICAgICAgLnN1YnN0cihpKSwgYk11bHRpcGxlLCBiRmlyc3QpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgbkN1cnJlbnRJbmRleCA9IDA7CiAgICAgICAgICAgIC8vIFRPRE86IERvIGNvbnRleHROb2RlIG11bWJvIGp1bWJvCiAgICAgICAgICAgIGlmICh0aGlzLl94ZmEoKSAmJiAodGhpcy5feGZhKCkuX2NvbnRleHROb2RlKCkgIT0gbnVsbCkpCiAgICAgICAgICAgICAgICBuQ3VycmVudEluZGV4ID0gdGhpcy5feGZhKCkuX2NvbnRleHROb2RlKCkuaW5kZXg7CgogICAgICAgICAgICB2YXIgb0NoaWxkcmVuID0gbnVsbDsgLy8gcmV0dXJuZWQgYXMgZWl0aGVyIGFuIGFycmF5IG9mIHNpbmdsZSBvYmplY3QKICAgICAgICAgICAgdmFyIG9QYXJlbnQgPSBvYmo7CiAgICAgICAgICAgIHZhciBzaSA9IDA7CiAgICAgICAgICAgIHZhciBiUm9vdE1hdGNoID0gZmFsc2U7CgogICAgICAgICAgICAvLwogICAgICAgICAgICAvLyBTZWUgaWYgdGhlIGZpcnN0IHRva2VuIG9mIHRoZSBleHByZXNzaW9uIG1hdGNoZXMgdGhpcyBub2RlCiAgICAgICAgICAgIC8vIE9uIHRoZSBmaXJzdCBjYWxsIHRoZSBjaGlsZHJlbiBhcmUgY2hlY2tlZCBmaXJzdAogICAgICAgICAgICAvLwogICAgICAgICAgICB2YXIgb1NPTSA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlU29tRXhwcmVzc2lvbihhcnIxWzBdLCBvYmouaW5kZXgpOwogICAgICAgICAgICBpZiAoKGJGaXJzdCA9PSBmYWxzZSkgJiYgKG9TT00uZXF1YWxzKG9iaikgfHwgKG9TT00uc2NhbGVyTWF0Y2ggPT0gb2JqKSkpIHsKICAgICAgICAgICAgICAgIGJSb290TWF0Y2ggPSB0cnVlOwogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIC8vIGZvdW5kCiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgaWYgKChhcnIxLmxlbmd0aCA9PSAxKSkgewogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGV4cHJlc3Npb24gb25seSBoYXMgb25lIHRva2VuIHRoZW4gdGhlIGV4cHJlc3Npb24gbWF0Y2hlcwogICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgbm9kZQogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgaWYgKCFiTXVsdGlwbGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgeGZhbGliLnNjcmlwdC5YZmFMaXN0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3QuX2FwcGVuZChvYmopOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIG9QYXJlbnQgPSBvYmoucGFyZW50OwogICAgICAgICAgICAgICAgICAgIGlmIChvUGFyZW50ID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb0NoaWxkcmVuID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICAgICAgICAgICAgICBvQ2hpbGRyZW4uX2FwcGVuZChvYmopOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb0NoaWxkcmVuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzaSA9IDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGV4cHJlc3Npb24gaGFzIG1vcmUgdGhhbiBvbmUgdG9rZW4gdGhlbiBzdGFydCBsb29raW5nIGZvcgogICAgICAgICAgICAgICAgICAgIC8vIGEgbWF0Y2ggb2Ygc3Vic2VxdWVudCB0b2tlbnMgd2l0aCB0aGUgY2hpbGRyZW4gb2YgdGhpcyBub2RlLgogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgc2kgPSAxOwogICAgICAgICAgICAgICAgICAgIG9TT00gPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZVNvbUV4cHJlc3Npb24oYXJyMVsxXSwgMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIG1hdGNoIHdpdGggb25lIG9mIHRoZSBjaGlsZCBub2RlcwogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIG9TT00gPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZVNvbUV4cHJlc3Npb24oYXJyMVswXSwgbkN1cnJlbnRJbmRleCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChvYmouX2lzQ29udGFpbmVyTm9kZSgpKSB7CiAgICAgICAgICAgICAgICB2YXIgYkVsaXBzaXMgPSBmYWxzZTsKCiAgICAgICAgICAgICAgICBmb3IgKCB2YXIgaiA9IHNpOyBqIDwgYXJyMS5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGlmIChhcnIxW2pdID09ICIuLiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYkVsaXBzaXMgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBqKys7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqID09IGFycjEubGVuZ3RoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIG9TT00gPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZVNvbUV4cHJlc3Npb24oYXJyMVtqXSwgMCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB2YXIgYkxhc3QgPSAoKGogKyAxKSA9PSBhcnIxLmxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgb0NoaWxkcmVuID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoIShvUGFyZW50IGluc3RhbmNlb2YgeGZhbGliLnNjcmlwdC5YZmFMaXN0KSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgb1BhcmVudExpc3QgPSBuZXcgeGZhbGliLnNjcmlwdC5YZmFMaXN0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG9QYXJlbnRMaXN0Ll9hcHBlbmQob1BhcmVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG9QYXJlbnQgPSBvUGFyZW50TGlzdDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGZvciAoIHZhciBrID0gMDsgayA8IG9QYXJlbnQubGVuZ3RoOyBrKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkcmVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gb1BhcmVudC5pdGVtKGspOwogICAgICAgICAgICAgICAgICAgICAgICBpZihwYXJlbnQgIT0gbnVsbCAmJiBwYXJlbnQuX2lzQ29udGFpbmVyTm9kZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYkVsaXBzaXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IHBhcmVudC5fZmluZENoaWxkcmVuRGVlcChvU09NLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiTXVsdGlwbGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJFbGlwc2lzID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gcGFyZW50Ll9maW5kQ2hpbGRyZW4ob1NPTSwgYk11bHRpcGxlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihjaGlsZHJlbi5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IHBhcmVudC5fZmluZFByb3BlcnR5KG9TT00pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgb0NoaWxkcmVuLl9jb25jYXQoY2hpbGRyZW4pOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYgKG9DaGlsZHJlbi5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGJSb290TWF0Y2ggPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGlmIChiTGFzdCA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgICAgICBvU09NID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVTb21FeHByZXNzaW9uKGFycjFbaiArIDFdLCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgb1BhcmVudCA9IG9DaGlsZHJlbjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChvQ2hpbGRyZW4gJiYgKG9DaGlsZHJlbi5sZW5ndGggIT0gMCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBvQ2hpbGRyZW47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmICgoYlJvb3RNYXRjaCA9PSB0cnVlKSB8fCAob2JqLnBhcmVudCA9PSBudWxsKSkgewogICAgICAgICAgICAgICAgaWYgKGJGaXJzdCA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAvLyBUcnkgYWdhaW4gYXR0ZW1wdGluZyB0byBtYXRjaCB0aGUgY3VycmVudCBub2RlCiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVzb2x2ZU5vZGVzQ29tbW9uKG9iaiwgc1NvbUV4cHJlc3Npb24sIGJNdWx0aXBsZSwKICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG9iai5wYXJlbnQgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVzb2x2ZU5vZGVzQ29tbW9uKG9iai5wYXJlbnQsIHNTb21FeHByZXNzaW9uLAogICAgICAgICAgICAgICAgICAgICAgICBiTXVsdGlwbGUsIGZhbHNlKTsKCiAgICAgICAgICAgICAgICBpZiAoYk11bHRpcGxlKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5YZmFMaXN0KCk7CgogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgLy8gdHJ5IHBhcmVudAogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc29sdmVOb2Rlc0NvbW1vbihvYmoucGFyZW50LCBzU29tRXhwcmVzc2lvbiwgYk11bHRpcGxlLAogICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IHJldHVybnMgd2hldGhlciB0aGUgbm9kZSBpcyBhbiBpbnN0YW5jZSBvZiBhIGNvbnRhaW5lcgogICAgICAgICAqICAgICAgICAgIE5vZGUgb3Igbm90CiAgICAgICAgICovCiAgICAgICAgX2lzQ29udGFpbmVyTm9kZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgX2lzWEZBQ29udGFpbmVyTm9kZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gcmV0dXJucyB3aGV0aGVyIHRoZSBub2RlIGlzIGFuIGluc3RhbmNlIG9mIGEgRmllbGQgb3Igbm90CiAgICAgICAgICovCiAgICAgICAgX2lzRmllbGQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IHJldHVybnMgd2hldGhlciB0aGUgbm9kZSBpcyBhbiBpbnN0YW5jZSBvZiBhIHN1YmZvcm0gb3IKICAgICAgICAgKiAgICAgICAgICBub3QKICAgICAgICAgKi8KICAgICAgICBfaXNTdWJmb3JtIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfaXNFeGNsdXNpb25Hcm91cCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgX2ZpbmRDaGlsZHJlbiA6IGZ1bmN0aW9uKG9TT00sIGJNdWx0aXBsZSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICBfZmluZENoaWxkcmVuRGVlcCA6IGZ1bmN0aW9uKG9TT00sIGJNdWx0aXBsZSkgewogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSByZXR1cm5zIHdoZXRoZXIgdGhlIG5vZGUgaXMgYW4gaW5zdGFuY2Ugb2YgYSBjb250ZW50IE5vZGUKICAgICAgICAgKiAgICAgICAgICBvciBub3QKICAgICAgICAgKi8KICAgICAgICBfaXNDb250ZW50IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfaXNFdmVudE5vZGUgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgY2xvbmUgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIGNsb25lZEpzb24gPSB7fTsKICAgICAgICAgICAgdGhpcy5jb3B5T2JqZWN0KHRoaXMuanNvbk1vZGVsLCBjbG9uZWRKc29uLHtleGNlcHRpb25zIDogWyJodG1sSWQiXX0gKTsKICAgICAgICAgICAgdmFyIG5vZGUgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZU1vZGVsKGNsb25lZEpzb24pOwogICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICB9LAoKICAgICAgICBuYWtlZEZpZWxkUmVmZXJlbmNlcyA6IGZ1bmN0aW9uKG5JbmRleCwgY3JlYXRlR2V0dGVyU2V0dGVyLG9iaikgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfSwKCiAgICAgICAgZ2V0QXR0cmlidXRlOiBmdW5jdGlvbihuYW1lLCBiUGVlaykgewogICAgICAgICAgICB2YXIgYXR0clZhbHVlID0gdW5kZWZpbmVkOwogICAgICAgICAgICAvL0J1ZyMzNjA5NDM0IDogY2hlY2sgb25seSBmb3IgdW5kZWZpbmVkCiAgICAgICAgICAgIGlmKG5hbWUgJiYgIV8uaXNVbmRlZmluZWQodGhpcy5qc29uTW9kZWxbbmFtZV0pKSB7CiAgICAgICAgICAgICAgICBhdHRyVmFsdWUgPSB0aGlzLmpzb25Nb2RlbFtuYW1lXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKGJQZWVrICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgYXR0clZhbHVlID0gdGhpcy5fZ2V0RGVmYXVsdEF0dHJpYnV0ZShuYW1lKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKG5hbWUgPT0gIm5hbWUiICYmIChfLmlzVW5kZWZpbmVkKGF0dHJWYWx1ZSkgfHwgXy5pc051bGwoYXR0clZhbHVlKSkpewogICAgICAgICAgICAgICAgLyogTEMtODE1MDogSWYgYXR0ck5hbWUgaXMgbmFtZSBhbmQgYXR0clZhbHVlIGlzIHVuZGVmaW5lZCBvciBudWxsIHRoZW4gd2UgcmV0dXJuIGVtcHR5IHN0cmluZyBpbnN0ZWFkIG9mIG51bGwuCiAgICAgICAgICAgICAgICAqIFJlYXNvbiBiZWluZyBtb3N0IG9mIHRoZSBjb2RlIGFzc3VtZSB0aGF0IGV2ZXJ5IG5vZGUgd291bGQgaGF2ZSBuYW1lIHByb3BlcnR5CiAgICAgICAgICAgICAgICAqICovCiAgICAgICAgICAgICAgICBhdHRyVmFsdWUgPSAiIjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYXR0clZhbHVlOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogY29uZGl0aW9ucyBmb3IgcHV0dGluZyBhIG5vZGUgaW4gZ2xvYmFsIGNvbnRleHQKICAgICAgICAgKiAxLiBJdCBzaG91bGQgaGF2ZSBhIG5hbWUKICAgICAgICAgKiAyLiBJdHMgaW5kZXggc2hvdWxkIG1hdGNoIHdpdGggdGhlIGluZGV4IHByb3ZpZGVkCiAgICAgICAgICogICAgICAgICAgICAgICAgICBPUgogICAgICAgICAqIDIuIFRoZXJlIHNob3VsZCBub3QgYmUgbW9yZSB0aGFuIG9uZSBub2RlIHdpdGggdGhlIHNhbWUgbmFtZSBpbiBpdHMgbm9ybWFsaXplZFBhcmVudCBCdWcjMzU5NDI4MgogICAgICAgICAqLwogICAgICAgIGdldE5ha2VkIDogZnVuY3Rpb24obkluZGV4LGNyZWF0ZUdldHRlclNldHRlcixPYmosc2NvcGUpIHsKICAgICAgICAgICAgdmFyIG5vZGVOYW1lID0gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwsICJuYW1lIiwgIiIpOwogICAgICAgICAgICBpZiAoKG5vZGVOYW1lICE9IG51bGwpICYmIChub2RlTmFtZS5sZW5ndGggIT0gMCkgJiYgKChzY29wZSAmJiBzY29wZS5tb05hbWVBcnJheVtub2RlTmFtZV0gPT0gMSkgfHwgKG5JbmRleCA9PSB0aGlzLmluZGV4KSkpIHsKICAgICAgICAgICAgICAgIC8vVE9ETzoga2VlcCBhIHN0YXRlIHdoZXRoZXIgdGhpcyBub2RlIHdhcyBwcmV2aW91c2x5IG5ha2VkIG9yIG5vdC4gSWYgeWVzIGRvIG5vdGhpbmcKICAgICAgICAgICAgICAgIHZhciBvT2JqZWN0ID0gZG9jdW1lbnRbbm9kZU5hbWVdOwogICAgICAgICAgICAgICAgaWYgKChvT2JqZWN0ID09IG51bGwpIHx8IChvT2JqZWN0IGluc3RhbmNlb2YgeGZhbGliLnNjcmlwdC5Ob2RlKSkgewogICAgICAgICAgICAgICAgICAgIGlmKGNyZWF0ZUdldHRlclNldHRlciApewogICAgICAgICAgICAgICAgICAgICAgICBpZihPYmouX3ByaXZhdGVbIl8iK25vZGVOYW1lKyJfIl09PW51bGwgfHwgT2JqLl9wcml2YXRlWyJfIitub2RlTmFtZSsiXyJdPT11bmRlZmluZWQpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlR2V0dGVyU2V0dGVyKE9iaiwgbm9kZU5hbWUsIHRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgT2JqWyJfIitub2RlTmFtZSsiXyJdID0gT2JqWyJfIitub2RlTmFtZSsiXyJdIHx8IHRoaXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZ2V0TmFrZWRUaGlzIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgdG9KU09OU3RyaW5nIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzLmpzb25Nb2RlbCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKgogICAgICAgICAqIHRoaXMgZnVuY3Rpb24gcGVyZm9ybXMgaW5pdGlhbGl6YXRpb24gZm9yIHRoaXMgbm9kZS4KICAgICAgICAgKi8KICAgICAgICBfaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewoKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqIEBmdW5jdGlvbiBpbmRpY2F0ZSB0aGF0IHRoaXMgaXMgYSBGb3JtIG5vZGUgKH5+KS4KICAgICAgICAgKi8KICAgICAgICBfaXNGb3JtIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfZGVzdHJveSA6IGZ1bmN0aW9uKG9DaGlsZCkgewogICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCggeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50Lk9CSkVDVF9ERVNUUk9ZRUQsIHRoaXMsCiAgICAgICAgICAgICAgICAnZGVzdHJveScsIG51bGwsIHRoaXMpOwogICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICB0aGlzLm9mZigpOwogICAgICAgICAgICB2YXIgcHJvcCA9ICAiXyIrdGhpcy5nZXRBdHRyaWJ1dGUoIm5hbWUiKSsiXyI7CiAgICAgICAgICAgIGlmICh4ZmFsaWIucnVudGltZS5oYXNPd25Qcm9wZXJ0eShwcm9wKSAmJiB0eXBlb2YgeGZhbGliLnJ1bnRpbWVbcHJvcF0gIT0gInVuZGVmaW5lZCIpCiAgICAgICAgICAgICAgICBpZiAoeGZhbGliLnJ1bnRpbWVbcHJvcF0uc29tRXhwcmVzc2lvbiA9PSB0aGlzLnNvbUV4cHJlc3Npb24pCiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWVbcHJvcF0gPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIHRoaXMuX3hmYSgpLl94ZmFUZW1wbGF0ZUNhY2hlLnJlbW92ZU1vZGVsKHRoaXMuaHRtbElkKTsKICAgICAgICB9LAoKICAgICAgICBfbWF0Y2hlcyA6IGZ1bmN0aW9uKG9Ob2RlKSB7CiAgICAgICAgICAgIHJldHVybiAob05vZGUgIT0gbnVsbCAmJiB0aGlzLnNvbUV4cHJlc3Npb24gPT0gb05vZGUuc29tRXhwcmVzc2lvbik7CiAgICAgICAgfSwKCiAgICAgICAgX3NldEZvY3VzIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KCB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELCB0aGlzLAogICAgICAgICAgICAgICAgJ2ZvY3VzJywgbnVsbCwgdGhpcyk7CiAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsZXZudCk7CiAgICAgICAgfSwKCiAgICAgICAgX3RlbXBsYXRlUmVmIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3hmYSgpLl94ZmFUZW1wbGF0ZUNhY2hlLmdldFRlbXBsYXRlUmVmKHRoaXMuZ2V0T3JFbHNlKHRoaXMuanNvbk1vZGVsLCAiZXh0cmFzLmh0bWxJZCIsIG51bGwpKTsKICAgICAgICB9LAoKICAgICAgICBfdGVtcGxhdGVJZCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLl90ZW1wbGF0ZVJlZigpLCAiZXh0cmFzLmh0bWxJZCIsIG51bGwpOwogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVHZXR0ZXJTZXR0ZXIgOiBmdW5jdGlvbihjb250YWluZXIsbmFtZSxvYmopIHsKICAgICAgICAgICAgdmFyIGlOYW1lID0gIl8iICsgbmFtZSArICJfIjsKICAgICAgICAgICAgaWYoIWNvbnRhaW5lci5oYXNPd25Qcm9wZXJ0eShuYW1lKSl7CiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29udGFpbmVyLG5hbWUsewogICAgICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuX3ByaXZhdGVbaU5hbWVdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcHJpdmF0ZVtpTmFtZV0uX2dldE5ha2VkVGhpcygpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9iaiA9IHRoaXMuX3ByaXZhdGVbaU5hbWVdOwogICAgICAgICAgICAgICAgICAgICAgICBvYmpbb2JqLl9kZWZhdWx0XSA9IHZhbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250YWluZXIuX3ByaXZhdGVbaU5hbWVdPW9iajsKICAgICAgICB9LAoKICAgICAgICBfZ2V0RGVmYXVsdEF0dHJpYnV0ZSA6IGZ1bmN0aW9uKGF0dHJpYnV0ZSkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5feGZhKCkuX3RlbXBsYXRlU2NoZW1hLmdldERlZmF1bHRBdHRyaWJ1dGUodGhpcy5jbGFzc05hbWUsIGF0dHJpYnV0ZSk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldERlZmF1bHRFbGVtZW50IDogZnVuY3Rpb24oZWxOYW1lLCBpbmRleCwgYXBwZW5kKSB7CiAgICAgICAgICAgIHZhciByZWxhdGlvbiA9IHRoaXMuX3hmYSgpLl90ZW1wbGF0ZVNjaGVtYS5fZ2V0UmVsYXRpb24odGhpcy5jbGFzc05hbWUsIGVsTmFtZSk7CiAgICAgICAgICAgIGlmKHJlbGF0aW9uID09IHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuemVyb09yT25lIHx8IHJlbGF0aW9uID09IHhmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMub25lT2ZDaGlsZCB8fAogICAgICAgICAgICAgICAgKChyZWxhdGlvbiA9PSB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnplcm9PclR3byB8fCByZWxhdGlvbiA9PSB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnplcm9PckZvdXIpICYmIGluZGV4ID09IDApKXsKICAgICAgICAgICAgICAgIHZhciBkZWZhdWx0RWwgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZU1vZGVsKHtfY2xhc3MgOiBlbE5hbWV9KTsKICAgICAgICAgICAgICAgIGlmKGRlZmF1bHRFbCAmJiBhcHBlbmQpewogICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkZENoaWxkKGRlZmF1bHRFbC5fZ2V0TmFrZWRUaGlzKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRFbDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICBfZ2V0RGF0YVR5cGU6IGZ1bmN0aW9uKGF0dHJpYnV0ZSkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5feGZhKCkuX3RlbXBsYXRlU2NoZW1hLl9nZXREYXRhVHlwZSh0aGlzLmNsYXNzTmFtZSwgYXR0cmlidXRlKTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0UmVsYXRpb246IGZ1bmN0aW9uKGNoaWxkKSB7CiAgICAgICAgICAgIHJldHVybiAgdGhpcy5feGZhKCkuX3RlbXBsYXRlU2NoZW1hLl9nZXRSZWxhdGlvbih0aGlzLmNsYXNzTmFtZSxjaGlsZC5jbGFzc05hbWUpOwogICAgICAgIH0sCgogICAgICAgIC8vdGhpcyBmdW5jdGlvbiBmaWx0ZXJzIHRoZSBub2RlcyBiYXNlZCBvbiBhIGZpbHRlckZuLgogICAgICAgIC8vdGhpcyBwcm9jZXNzZXMgbm90IG9ubHkgaW1tZWRpYXRlIGNoaWxkcmVuIGJ1dCBnb2VzIHJlY3Vyc2l2ZWx5IHRocm91Z2ggdGhlIHdob2xlIHRyZWUKICAgICAgICBfZmlsdGVyTm9kZXM6ZnVuY3Rpb24oZmlsdGVyRm4pIHsKICAgICAgICAgICAgdmFyIG5vZGVMaXN0ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICBpZiAodGhpcy5faXNDb250YWluZXJOb2RlKCkpIHsKICAgICAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuX2dldENoaWxkcmVuKCk7CiAgICAgICAgICAgICAgICBmb3IodmFyIGk9MDsgaTwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspewogICAgICAgICAgICAgICAgICAgIHZhciBuID0gY2hpbGRyZW4uaXRlbShpKTsKICAgICAgICAgICAgICAgICAgICBpZihmaWx0ZXJGbihuKSkKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZUxpc3QuX2FwcGVuZChuKTsKICAgICAgICAgICAgICAgICAgICBub2RlTGlzdC5fY29uY2F0KG4uX2ZpbHRlck5vZGVzKGZpbHRlckZuKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5vZGVMaXN0OwogICAgICAgIH0sCgogICAgICAgIGdldEVsZW1lbnQ6IGZ1bmN0aW9uKGNsYXNzTmFtZSxpbmRleCwgYlBlZWspIHsKICAgICAgICAgICAgaW5kZXggPSBpbmRleCB8fCAwOwogICAgICAgICAgICB2YXIgYXJyID0gdGhpcy5fZmluZENoaWxkcmVuKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlU29tRXhwcmVzc2lvbihjbGFzc05hbWUrIlsiK2luZGV4KyJdIiksZmFsc2UpOwogICAgICAgICAgICBpZihhcnIgJiYgYXJyLmxlbmd0aCA+MCkKICAgICAgICAgICAgICAgIHJldHVybiBhcnIuaXRlbSgwKTsKICAgICAgICAgICAgZWxzZSBpZighYlBlZWsgJiYgKHRoaXMuX2dldE9uZU9mQ2hpbGQgJiYgICF0aGlzLl9nZXRPbmVPZkNoaWxkKHRydWUpKSkKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXREZWZhdWx0RWxlbWVudChjbGFzc05hbWUsIGluZGV4LCB0cnVlKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgc2V0RWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgY2xhc3NOYW1lLGluZGV4KXsKICAgICAgICAgICAgaWYoXy5pc051bWJlcihlbGVtZW50KSB8fCBfLmlzQm9vbGVhbihlbGVtZW50KSB8fCBfLmlzRGF0ZShlbGVtZW50KSB8fCBfLmlzU3RyaW5nKGVsZW1lbnQpKXsKICAgICAgICAgICAgICAgIHZhciBjaGlsZE5vZGUgPSB0aGlzLmdldEVsZW1lbnQoY2xhc3NOYW1lLCBpbmRleCk7CiAgICAgICAgICAgICAgICBpZihjaGlsZE5vZGUgJiYgY2hpbGROb2RlLl9kZWZhdWx0KXsKICAgICAgICAgICAgICAgICAgICBjaGlsZE5vZGVbY2hpbGROb2RlLl9kZWZhdWx0XSA9IGVsZW1lbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgc2V0QXR0cmlidXRlOiBmdW5jdGlvbih2YWx1ZSwgYXR0ck5hbWUpewogICAgICAgICAgICB0aGlzLmpzb25Nb2RlbFthdHRyTmFtZV0gPSB0aGlzLnZhbGlkYXRlSW5wdXQodmFsdWUsIHRoaXMuX2dldERhdGFUeXBlKGF0dHJOYW1lKSx0aGlzLmpzb25Nb2RlbFthdHRyTmFtZV0pOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiB0aGUgRGF0YVNPTU1hcCBhZnRlciBhZGRpbmcgYW4gZW50cnkgaW4gdGhlIG1hcCBmb3IgdGhlIG5vZGUuIFRoZSBlbnRyeSBjb250YWlucyB0aGUgdmFsdWUgb2YgdGhlIG5vZGUKICAgICAgICAgKiBhbG9uZyB3aXRoIGl0cyBEYXRhIFNPTS4gSWYgdGhlcmUgaXMgbm8gRGF0YSBTT00gdGhlbiByZXR1cm4gdGhlIHVubW9kaWZpZWQgbWFwCiAgICAgICAgICogQHBhcmFtIG1hcAogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2dldERhdGFTb21NYXAgOiBmdW5jdGlvbihtYXApIHsKICAgICAgICAgICAgcmV0dXJuIG1hcDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBVcGRhdGUgdGhlIHZhbHVlIG9mIHRoZSBub2RlIHdpdGggdGhlIHZhbHVlIHByb3ZpZGVkIGluIHRoZSBpbnB1dCBtYXAuIFRoZSBtYXAgY29udGFpbnMgdGhlIHZhbHVlcyBvZiB0aGUgZmllbGRzCiAgICAgICAgICogbWFwcGVkIHdpdGggdGhlaXIgRGF0YVNPTS4gVGhlIGZ1bmN0aW9uIGlzIGVtcHR5IGZvciBhbGwgdGhlIG5vZGVzLCBleGNlcHQgZm9yIEZpZWxkLCBTdWJmb3JtIGFuZCBBcmVhLgogICAgICAgICAqIEBwYXJhbSBtYXAKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9yZXN0b3JlRGF0YVNvbU1hcCA6IGZ1bmN0aW9uIChtYXApIHsKCiAgICAgICAgfSwKCiAgICAgICAgX3BsYXlEYXRhWE1MOiBmdW5jdGlvbih4bWxEb2N1bWVudCwgY29udGV4dE5vZGUpIHsKCiAgICAgICAgfSwKCiAgICAgICAgZ2VuZXJhdGVEYXRhWE1MOiBmdW5jdGlvbihyb290Tm9kZSwgY29udGV4dE5vZGUpIHsKCiAgICAgICAgfQoKICAgIH0pOwoKICAgIE5vZGUuZGVmaW5lUHJvcHMoewogICAgICAgICJwYXJlbnQiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1QYXJlbnQ7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHBhcmVudCkgewogICAgICAgICAgICAgICAgcGFyZW50ID0gdGhpcy52YWxpZGF0ZUlucHV0KHBhcmVudCwgIm9iamVjdCIsbnVsbCk7CiAgICAgICAgICAgICAgICB0aGlzLm1QYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHJlc29sdmU6dHJ1ZQogICAgICAgIH0sCgogICAgICAgICJuYW1lIiAgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHNOYW1lKSB7CiAgICAgICAgICAgICAgICAvL3NOYW1lID0gdGhpcy52YWxpZGF0ZUlucHV0KHNOYW1lLCAic3RyaW5nIik7CiAgICAgICAgICAgICAgICAvL3RoaXMuanNvbk1vZGVsLm5hbWUgPSBzTmFtZTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgY29uZmlndXJhYmxlOnRydWUKICAgICAgICB9LAoKICAgICAgICAibm9kZXMiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLl9pc0NvbnRhaW5lck5vZGUoKSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRDaGlsZHJlbigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LlhmYUxpc3QoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJpbmRleCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubW5JbmRleDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24obkluZGV4KSB7CiAgICAgICAgICAgICAgICBuSW5kZXggPSB0aGlzLnZhbGlkYXRlSW5wdXQobkluZGV4LCAiaW50ZWdlciIsdGhpcy5tbkluZGV4KTsKICAgICAgICAgICAgICAgIHRoaXMubW5JbmRleCA9IG5JbmRleDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJzb21FeHByZXNzaW9uIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0U29tRXhwcmVzc2lvbigpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZXJyb3IoInhmYSIsIHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAwNiJdLFsic2V0dGluZyBTb21FeHByZXNzaW9uIl0pCiAgICAgICAgICAgICAgICB0aHJvdyAidW5zdXBwb3J0ZWQgb3BlcmF0aW9uIjsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJpc0NvbnRhaW5lciIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2lzWEZBQ29udGFpbmVyTm9kZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImh0bWxJZCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwsICJleHRyYXMuaHRtbElkIiwgbnVsbCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHNIdG1sSWQpewogICAgICAgICAgICAgICAgdGhpcy5qc29uTW9kZWwuZXh0cmFzID0gdGhpcy5qc29uTW9kZWwuZXh0cmFzIHx8IHt9OwogICAgICAgICAgICAgICAgdGhpcy5qc29uTW9kZWwuZXh0cmFzLmh0bWxJZCA9IHNIdG1sSWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAiaXNOdWxsIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJhbGwiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgeGZhbGliLnNjcmlwdC5YZmFMaXN0KCk7CiAgICAgICAgICAgICAgICB2YXIgc29tID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVTb21FeHByZXNzaW9uKHRoaXMuanNvbk1vZGVsLm5hbWUrIlsqXSIpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmpzb25Nb2RlbC5uYW1lKSAgewogICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLnBhcmVudCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBhcmVudC5fZmluZENoaWxkcmVuRGVlcChzb20sIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHJldHVybiBsaXN0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHRocm93ICJOYW1lIHVuZGVmaW5lZCIgOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2F0Y2goZSkgICB7CiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcigiR2V0IG9wZXJhdGlvbiBhbGwgcmVxdWlyZXMgdGhlIG5vZGUgdG8gaGF2ZSBhIG5hbWUiKTsKICAgICAgICAgICAgICAgIH0KCgogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImV4dHJhcyIgOnsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsMCkKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKfSkoXywgeGZhbGliKTsKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5FbGVtZW50CiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Ob2RlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgRWxlbWVudCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBCiAqICAgICAgICAgICAgICAgbGlicmFyeQogKiBAdmVyc2lvbiAwLjAuMgogKi8KCihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICAvKioKICAgICAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyBhbGwgdGhlIFhGQSBPYmplY3RzIHdoaWNoIGNhbiBjb250YWluIG90aGVyIFhGQQogICAgICogICAgICAgIG5vZGVzIGluc2lkZSB0aGVtCiAgICAgKiBAZXh0ZW5kcyBjb20uYWRvYmUueGZhLnNjcmlwdGluZy5Ob2RlCiAgICAgKgogICAgICogQHByb3BlcnR5IHtBcnJheX0gY2hpbGRyZW4gY2hpbGRyZW4gb2YgdGhlIEVsZW1lbnQKICAgICAqCiAgICAgKiBAY29uc3RydWN0b3IKICAgICAqIEBwYXJhbSB7c3RyaW5nfQogICAgICogICAgICAgICAgICBuYW1lIHRoZSBuYW1lIG9mIHRoZSBub2RlCiAgICAgKgogICAgICogQHR5cGUgeyp8dm9pZH0KICAgICAqLwogICAgdmFyIEVsZW1lbnQgPSB4ZmFsaWIuc2NyaXB0LkVsZW1lbnQgPSB4ZmFsaWIuc2NyaXB0Lk5vZGUuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBFbGVtZW50Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX21vQ2hpbGROb2RlcyA9IFtdOwogICAgICAgICAgICB0aGlzLm1uQ3VycmVudEluZGV4ID0gLTE7CiAgICAgICAgICAgIHRoaXMubW9OYW1lQXJyYXkgPSBuZXcgT2JqZWN0KCk7CiAgICAgICAgICAgIHRoaXMubW9Ob3JtYWxpemVkQ2hpbGRyZW4gPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgdGhpcy5fcHJpdmF0ZSA9IHt9OwogICAgICAgICAgICB0aGlzLl9pbml0Q2hpbGRyZW4oKTsKICAgICAgICB9LAoKICAgICAgICBfaW5pdENoaWxkcmVuOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IG5ldyBBcnJheSgpOwogICAgICAgICAgICB2YXIgbGFzdENyZWF0ZWRJbnN0YW5jZU1hbmFnZXIgPSBudWxsOwoKICAgICAgICAgICAgaWYgKHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuKSB7CiAgICAgICAgICAgICAgICB2YXIgaiA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5qc29uTW9kZWwuY2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkTW9kZWwgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZU1vZGVsKGNoaWxkKTsKICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRNb2RlbCBpbnN0YW5jZW9mIHhmYWxpYi5zY3JpcHQuSW5zdGFuY2VNYW5hZ2VyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RDcmVhdGVkSW5zdGFuY2VNYW5hZ2VyID0gY2hpbGRNb2RlbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY2hpbGRNb2RlbCBpbnN0YW5jZW9mIHhmYWxpYi5zY3JpcHQuU3ViZm9ybSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAobGFzdENyZWF0ZWRJbnN0YW5jZU1hbmFnZXIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RDcmVhdGVkSW5zdGFuY2VNYW5hZ2VyLm5hbWUubGVuZ3RoID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdENyZWF0ZWRJbnN0YW5jZU1hbmFnZXIubmFtZSA9ICJfIiArIGNoaWxkTW9kZWwubmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RDcmVhdGVkSW5zdGFuY2VNYW5hZ2VyLl9tYW5hZ2VDaGlsZChjaGlsZE1vZGVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRNb2RlbCkgewogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbltqKytdID0gY2hpbGRNb2RlbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLmNoaWxkcmVuID0gY2hpbGRyZW47CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZ2V0Q2hpbGRyZW46IGZ1bmN0aW9uIChjaGlsZCkgewogICAgICAgICAgICB2YXIgcGFyZW50ID0gdGhpczsKICAgICAgICAgICAgdmFyIG9iaiA9IHsicGFyZW50IjogcGFyZW50fTsKICAgICAgICAgICAgdmFyIGxpc3QgPSBuZXcgeGZhbGliLnNjcmlwdC5YZmFMaXN0KG9iaik7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tb0NoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIGxpc3QuX2FwcGVuZCh0aGlzLm1vQ2hpbGROb2Rlc1tpXS5fZ2V0TmFrZWRUaGlzKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBmdW5jdGlvbnMgYWRkcyBhIGNoaWxkIHRvIHRoaXMgY29udGFpbmVyTm9kZQogICAgICAgICAqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHBhcmFtIHtub2RlfQogICAgICAgICAqICAgICAgICAgICAgY2hpbGQgVGhlIGNoaWxkIG5vZGUgdG8gYWRkIHRvIHRoaXMgRWxlbWVudAogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgX2FkZENoaWxkOiBmdW5jdGlvbiAoY2hpbGQpIHsKICAgICAgICAgICAgaWYgKGNoaWxkICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2FkZENoaWxkQXQoY2hpbGQsIHRoaXMubW9DaGlsZE5vZGVzLmxlbmd0aCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqIEBmdW5jdGlvbiByZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIHNjb3BlbGVzcyBjb250YWluZXIKICAgICAgICAgKgogICAgICAgICAqLwogICAgICAgIHNjb3BlbGVzczogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgLy9pbmNsdWRlRG9tRWxlbWVudCB0ZWxscyB3aGV0aGVyIERPTUVsZW1lbnQgc2hvdWxkIGJlIGVzY2FsYXRlZCB0byB0aGVpciBwYXJlbnQKICAgICAgICBhcHBlbmROb3JtYWxpemVkQ2hpbGRyZW46IGZ1bmN0aW9uIChvTm9ybWFsaXplZENoaWxkcmVuLCBpbmNsdWRlRG9tRWxlbWVudCkgewogICAgICAgICAgICB2YXIgaSA9IDA7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLm1vQ2hpbGROb2Rlcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIG9DaGlsZCA9IHRoaXMubW9DaGlsZE5vZGVzW2ldOwogICAgICAgICAgICAgICAgaWYgKG9DaGlsZCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgLy9DUS0xMDIzNDEgOiBib3JkZXIgY2hpbGQgb2YgdW5uYW1lZCBzdWJmb3JtIHdhcyBnZXR0aW5nIGFwcGVuZGVkIHRvIHBhcmVudCBzdWJmb3JtCiAgICAgICAgICAgICAgICAgICAgaWYoaW5jbHVkZURvbUVsZW1lbnQgPT09IHRydWUgfHwgIShvQ2hpbGQgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LmRvbS5Cb3JkZXIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG9Ob3JtYWxpemVkQ2hpbGRyZW4ucHVzaChvQ2hpbGQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB2YXIgb0NvbnRhaW5lciA9IG9DaGlsZDsKICAgICAgICAgICAgICAgICAgICBpZiAob0NvbnRhaW5lcgogICAgICAgICAgICAgICAgICAgICAgICAmJiAob0NvbnRhaW5lci5faXNDb250YWluZXJOb2RlKCkgJiYgb0NvbnRhaW5lci5zY29wZWxlc3MoKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgb0NvbnRhaW5lci5hcHBlbmROb3JtYWxpemVkQ2hpbGRyZW4ob05vcm1hbGl6ZWRDaGlsZHJlbiwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICoKICAgICAgICAgKiBhZGRzIGEgZHluYW1pYyBwcm9wZXJ0eSB0byB0aGlzIGNvbnRhaW5lci4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBzTmFtZQogICAgICAgICAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIGJlIGFkZGVkLgogICAgICAgICAqIEBwYXJhbSBvVmFsdWVPYmplY3QKICAgICAgICAgKiAgICAgICAgICAgIHRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgdGhhdCBpcyBhZGRlZC4KICAgICAgICAgKiBAcmV0dXJuIHRoZSAwIGJhc2VkIGluZGV4IG9mIHRoZSBwcm9wZXJ0eSBuYW1lLgogICAgICAgICAqLwogICAgICAgIF9hZGRQcm9wZXJ0eTogZnVuY3Rpb24gKHNOYW1lLCBvVmFsdWVPYmplY3QsIGNyZWF0ZUdldHRlclNldHRlcikgewogICAgICAgICAgICB2YXIgbkluZGV4ID0gMDsKICAgICAgICAgICAgaWYgKChzTmFtZSAhPSBudWxsKSAmJiAoc05hbWUubGVuZ3RoID4gMCkpIHsKICAgICAgICAgICAgICAgIGlmIChvVmFsdWVPYmplY3QgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgLy8ganVzdCByZXNldCBpdAogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXNbc05hbWVdKQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzW3NOYW1lXSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb05hbWVBcnJheVtzTmFtZV0gPSAwOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgIC8vIGFkZCBpdCBhcyBhIHByb3BlcnR5IGFsc28ga2VlcCB0cmFjayBvZiB0aGUgaW5kZXgKICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgIHRoaXMubW9OYW1lQXJyYXlbc05hbWVdID0gdGhpcy5tb05hbWVBcnJheVtzTmFtZV0gfHwgbkluZGV4OwogICAgICAgICAgICAgICAgICAgIG5JbmRleCA9IHRoaXMubW9OYW1lQXJyYXlbc05hbWVdKys7CiAgICAgICAgICAgICAgICAgICAgaWYgKG5JbmRleCA9PSAwICYmIGNyZWF0ZUdldHRlclNldHRlcikgewogICAgICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IHB1dCB0aGUgZmlyc3QgaW5zdGFuY2UgYXMgYSBwcm9wZXJ0eSBvZiB0aGUgY29udGFpbmVyCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRvbid0IG92ZXJ3cml0ZSBub24gZHluYW1pYyBwcm9wZXJ0aWVzCiAgICAgICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUdldHRlclNldHRlcih0aGlzLCBzTmFtZSwgb1ZhbHVlT2JqZWN0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5JbmRleDsKICAgICAgICB9LAoKICAgICAgICBub3JtYWxpemVDaGlsZHJlbjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLm1vTm9ybWFsaXplZENoaWxkcmVuID0gbmV3IEFycmF5KCk7CiAgICAgICAgICAgIHRoaXMuYXBwZW5kTm9ybWFsaXplZENoaWxkcmVuKHRoaXMubW9Ob3JtYWxpemVkQ2hpbGRyZW4sIHRydWUpOwogICAgICAgICAgICB2YXIgYlNjb3BlbGVzcyA9IHRoaXMuc2NvcGVsZXNzKCk7CgogICAgICAgICAgICBpZiAoYlNjb3BlbGVzcykgewogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIC8vIG11c3Qgc2NvcGUgY2hpbGRyZW4gaW4gdGhlIHBhcmVudCBjb250YWluZXIKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICB2YXIgb1BhcmVudCA9IHRoaXMucGFyZW50OwogICAgICAgICAgICAgICAgaWYgKG9QYXJlbnQgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICBvUGFyZW50Lm5vcm1hbGl6ZUNoaWxkcmVuKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBpID0gMDsKICAgICAgICAgICAgdGhpcy5tb05hbWVBcnJheSA9IG5ldyBPYmplY3QoKTsKICAgICAgICAgICAgZm9yICg7IGkgPCB0aGlzLm1vTm9ybWFsaXplZENoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB2YXIgb0NoaWxkID0gdGhpcy5tb05vcm1hbGl6ZWRDaGlsZHJlbltpXTsKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAvLyBTZXQgcHJvcGVydGllcyBhbmQgaW5kaWNlcyBiYXNlZCBvbiBub3JtYWxpemVkIGNoaWxkcmVuCiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgdmFyIGNyZWF0ZUdldHRlclNldHRlciA9IHRoaXMuX3JlcXVpcmVHZXR0ZXJTZXR0ZXIob0NoaWxkKTsKICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX2FkZFByb3BlcnR5KHRoaXMuZ2V0T3JFbHNlKG9DaGlsZC5qc29uTW9kZWwsICJuYW1lIiwgIiIpLCBvQ2hpbGQsIGNyZWF0ZUdldHRlclNldHRlcik7CiAgICAgICAgICAgICAgICB2YXIgY2xhc3NJbmRleCA9IHRoaXMuX2FkZFByb3BlcnR5KCcjJyArIG9DaGlsZC5jbGFzc05hbWUsIG9DaGlsZCwgZmFsc2UpOwogICAgICAgICAgICAgICAgaWYgKCFiU2NvcGVsZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAvLyBzY29wZSBpbmRleGVzIHJlbGF0aXZlIHRvIHRoaXMgY29udGFpbmVyCiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICBvQ2hpbGQuaW5kZXggPSBpbmRleDsKICAgICAgICAgICAgICAgICAgICBvQ2hpbGQubW5DbGFzc0luZGV4ID0gY2xhc3NJbmRleDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IHJldHVybnMgd2hldGhlciB0aGUgbm9kZSBpcyBhbiBpbnN0YW5jZSBvZiBhIGNvbnRhaW5lcgogICAgICAgICAqICAgICAgICAgIE5vZGUgb3Igbm90CiAgICAgICAgICovCiAgICAgICAgX2lzQ29udGFpbmVyTm9kZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBfcmVxdWlyZUdldHRlclNldHRlcjogZnVuY3Rpb24gKG9DaGlsZCkgewogICAgICAgICAgICAvL1Rlc3RzIHdoZXRoZXIgZHluYW1pYyBnZXR0ZXIvc2V0dGVyIHNob3VsZCBiZSBnZW5lcmF0ZWQgZm9yIHRoaXMgY2hpbGQgd2hpY2ggaGFwcGVucyBmb3IgaW5maW5pdGUgY2FyZGluYWxpdHkKICAgICAgICAgICAgdmFyIHJlbGF0aW9uID0gdGhpcy5fZ2V0UmVsYXRpb24ob0NoaWxkKTsKICAgICAgICAgICAgcmV0dXJuIChyZWxhdGlvbiA9PSBudWxsIHx8IHJlbGF0aW9uLm1heCA9PSBJbmZpbml0eSk7CiAgICAgICAgfSwKCiAgICAgICAgX2ZpbmRDaGlsZHJlbjogZnVuY3Rpb24gKG9TT00sIGJNdWx0aXBsZSkgewogICAgICAgICAgICB2YXIgYXJyID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICB2YXIgZWxlbUZvdW5kID0gZmFsc2U7CiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdGhpcy5tb05vcm1hbGl6ZWRDaGlsZHJlbi5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgdmFyIG9DaGlsZCA9IHRoaXMubW9Ob3JtYWxpemVkQ2hpbGRyZW5bal07CiAgICAgICAgICAgICAgICB2YXIgcmVsYXRpb24gPSB0aGlzLl9nZXRSZWxhdGlvbihvQ2hpbGQpOwogICAgICAgICAgICAgICAgaWYgKG9TT00uZXF1YWxzKG9DaGlsZCkgfHwgKHJlbGF0aW9uICYmIHJlbGF0aW9uLm1heCAhPSBJbmZpbml0eSAmJiBvU09NLnRhZ0VxdWFscyhvQ2hpbGQpKSkgewogICAgICAgICAgICAgICAgICAgIGFyci5fYXBwZW5kKG9DaGlsZC5fZ2V0TmFrZWRUaGlzKCkpOwogICAgICAgICAgICAgICAgICAgIGVsZW1Gb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZWxlbUZvdW5kICYmICFiTXVsdGlwbGUpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFycjsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVsZW1Gb3VuZCAmJiBvU09NLmluZGV4ICE9ICcqJykKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG9TT00uc2NhbGVyTWF0Y2ggIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYgKGJNdWx0aXBsZSA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgIGFyci5fYXBwZW5kKG9TT00uc2NhbGVyTWF0Y2guX2dldE5ha2VkVGhpcygpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXJyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy8gYXJyID0gW107CiAgICAgICAgICAgICAgICAgICAgLy8gYXJyLmxlbmd0aCA9IG9TT00uc2NhbGFyTWF0Y2g7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBhcnI7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKgogICAgICAgICAqIGxpa2UgX2ZpbmRDaGlsZHJlbiBidXQgc2VhcmNoZXMgZGVlcCBmb3IgYSBtYXRjaAogICAgICAgICAqLwogICAgICAgIF9maW5kQ2hpbGRyZW5EZWVwOiBmdW5jdGlvbiAob1NPTSwgYk11bHRpcGxlKSB7CiAgICAgICAgICAgIHZhciBvT2JqZWN0ID0gdGhpcy5fZmluZENoaWxkcmVuKG9TT00sIGJNdWx0aXBsZSk7CiAgICAgICAgICAgIGlmIChvT2JqZWN0ID09IG51bGwgfHwgb09iamVjdC5sZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgdmFyIG9DaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW47CiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG9DaGlsZHJlbi5sZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIG9PYmplY3QgPSBvQ2hpbGRyZW5bal0uX2ZpbmRDaGlsZHJlbkRlZXAob1NPTSwgYk11bHRpcGxlKTsKICAgICAgICAgICAgICAgICAgICBpZiAob09iamVjdCAmJiBvT2JqZWN0Lmxlbmd0aCA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBvT2JqZWN0OwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICoKICAgICAgICAgKiBnZXQgdGhlIGluZGV4IG9mIHRoZSBzcGVjaWZpZWQgY2hpbGQuCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge2NvbS5hZG9iZS54ZmEuc2NyaXB0aW5nLk5vZGV9CiAgICAgICAgICogICAgICAgICAgICBvTm9kZSB0aGUgbm9kZSBvZiB3aGljaCB0aGUgaW5kZXggaXMgdG8gYmUgZm91bmQuCiAgICAgICAgICogQHJldHVybiB7bnVtYmVyfSB0aGUgMCBiYXNlZCBpbmRleCBvZiB0aGUgbm9kZSBvciAtMSBpZiBub3QgZm91bmQuCiAgICAgICAgICovCiAgICAgICAgX2dldENoaWxkSW5kZXg6IGZ1bmN0aW9uIChvTm9kZSkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5tb0NoaWxkTm9kZXMuaW5kZXhPZihvTm9kZSk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKgogICAgICAgICAqIGFkZCBzcGVjaWZpZWQgY2hpbGQgdG8gdGhlIHNwZWNpZmllZCBpbmRleC4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBvTm9kZQogICAgICAgICAqICAgICAgICAgICAgdGhlIG5vZGUgdG8gYmUgYWRkZWQuCiAgICAgICAgICogQHBhcmFtIG5JTmRleAogICAgICAgICAqICAgICAgICAgICAgdGhlIGluZGV4IHdoZXJlIHRoZSBjaGlsZCB3aWxsIGJlIGluc2VydGVkLgogICAgICAgICAqLwogICAgICAgIF9hZGRDaGlsZEF0OiBmdW5jdGlvbiAob05vZGUsIG5JbmRleCkgewogICAgICAgICAgICB0aGlzLm1vQ2hpbGROb2Rlcy5zcGxpY2UobkluZGV4LCAwLCBvTm9kZSk7CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuID0gdGhpcy5qc29uTW9kZWwuY2hpbGRyZW4gfHwgW107CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuLnNwbGljZShuSW5kZXgsIDAsIG9Ob2RlLmpzb25Nb2RlbCk7CiAgICAgICAgICAgIG9Ob2RlLnBhcmVudCA9IHRoaXM7CiAgICAgICAgICAgIHRoaXMubm9ybWFsaXplQ2hpbGRyZW4oKTsKICAgICAgICAgICAgdGhpcy5fcG9zdEFkZENoaWxkKG9Ob2RlKTsKICAgICAgICB9LAoKICAgICAgICBfcG9zdEFkZENoaWxkOiBmdW5jdGlvbiAob05vZGUpIHsKICAgICAgICAgICAgb05vZGUuX2luaXRpYWxpemUoKTsKICAgICAgICAgICAgaWYgKG9Ob2RlIGluc3RhbmNlb2YgeGZhbGliLnNjcmlwdC5ET01FbGVtZW50IHx8IG9Ob2RlIGluc3RhbmNlb2YgeGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dCkgewogICAgICAgICAgICAgICAgb05vZGUub24oeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkRPTV9DSEFOR0VELCB0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9kZXN0cm95OiBmdW5jdGlvbiAob0NoaWxkKSB7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tb0NoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IHRoaXMubW9DaGlsZE5vZGVzW2ldOwogICAgICAgICAgICAgICAgaWYgKGNoaWxkICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgY2hpbGQuX2Rlc3Ryb3koKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBFbGVtZW50Ll9zdXBlci5fZGVzdHJveS5jYWxsKHRoaXMsIG9DaGlsZCk7CiAgICAgICAgfSwKCiAgICAgICAgX3JlbW92ZUFsbDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBfLmVhY2godGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uIChvQ2hpbGQsIGluZGV4KSB7CiAgICAgICAgICAgICAgICBvQ2hpbGQuX2Rlc3Ryb3koKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHRoaXMubW9DaGlsZE5vZGVzID0gW107CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuID0gW107CiAgICAgICAgICAgIHRoaXMubm9ybWFsaXplQ2hpbGRyZW4oKTsKICAgICAgICAgICAgLy9Ub0RvIGFkZCBldmVudCB0cmlnZ2VyIGxpa2UgX3JlbW92ZSBtZXRob2QgaWYgcmVxdWlyZWQKICAgICAgICB9LAoKICAgICAgICBfcmVtb3ZlQ2hpbGQ6IGZ1bmN0aW9uIChvQ2hpbGQpIHsKICAgICAgICAgICAgb0NoaWxkLl9kZXN0cm95KCk7CiAgICAgICAgICAgIHZhciBuSW5kZXggPSB0aGlzLm1vQ2hpbGROb2Rlcy5pbmRleE9mKG9DaGlsZCk7CiAgICAgICAgICAgIHRoaXMubW9DaGlsZE5vZGVzLnNwbGljZShuSW5kZXgsIDEpOwogICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC5jaGlsZHJlbi5zcGxpY2UobkluZGV4LCAxKTsKICAgICAgICAgICAgdGhpcy5ub3JtYWxpemVDaGlsZHJlbigpOwogICAgICAgICAgICB0aGlzLl9wb3N0UmVtb3ZlQ2hpbGQob0NoaWxkKTsKICAgICAgICB9LAoKICAgICAgICBfcG9zdFJlbW92ZUNoaWxkOiBmdW5jdGlvbiAob0NoaWxkKSB7CiAgICAgICAgICAgIC8vZG8gbm90aGluZyBoZXJlCiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKgogICAgICAgICAqIGluaXRpYWxpemUgdGhpcyBDb250YWluZXIgTm9kZQogICAgICAgICAqLwogICAgICAgIF9pbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmICgodGhpcy5tb0NoaWxkTm9kZXMgPT0gbnVsbCkgfHwgKHRoaXMubW9DaGlsZE5vZGVzLmxlbmd0aCA9PSAwKSkgewogICAgICAgICAgICAgICAgdGhpcy5tYkluaXRpYWxpemVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHRoaXMuX3hmYSgpID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRocm93ICh4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDMiXSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEluaXQgdGhpcwogICAgICAgICAgICBpZiAodGhpcy5wYXJlbnQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhpcy5pbmRleCA9IDA7CiAgICAgICAgICAgICAgICAvL3RoaXMuX3hmYSgpLl9wdXNoQ29udGV4dE5vZGUodGhpcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIGxvb3AgdGhyb3VnaCB0aGUgY29udHJvbHMgdGhhdCBhcmUgY2hpbGQgY29tcG9uZW50cyBvZiB0aGlzIGNvbnRhaW5lcgogICAgICAgICAgICAvLyBjb3B5IGludG8gYXJyYXksIHNpbmNlIG1vQ2hpbGROb2RlcyBtYXkgYmUgbW9kaWZpZWQgYXMgd2UgaW5pdGlhbGl6ZQogICAgICAgICAgICAvLyBJbnN0YW5jZU1hbmFnZXJzCiAgICAgICAgICAgIC8vCgogICAgICAgICAgICB2YXIgb0NoaWxkcmVuID0gdGhpcy5tb0NoaWxkTm9kZXM7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb0NoaWxkcmVuLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB2YXIgb05vZGUgPSBvQ2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICBpZiAob05vZGUgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmVycm9yKCJ4ZmEiLCB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDQiXSwgW3RoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIiksIGldKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBvTm9kZS5faW5pdGlhbGl6ZSgpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGlzLm1iSW5pdGlhbGl6ZWQgPSB0cnVlOwoKICAgICAgICB9LAoKICAgICAgICBwbGF5SnNvbjogZnVuY3Rpb24gKHBKc29uTW9kZWwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogcGxheUpzb24gYXNzdW1wdGlvbjogVGhlIG5vbiBkb20gZWxlbWVudHMgc2hvdWxkIGFsd2F5cyBtYWludGFpbiB0aGUgc3RydWN0dXJhbCBoaWVyYXJjaHkuCiAgICAgICAgICAgICAqIEZvciBkb20gZWxlbWVudHMsIHdlIHN1cHBvcnQgb25seSB2YWx1ZSBhbmQgaXRlbXMuIHJlc3QgYXJlIGlnbm9yZWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBFbGVtZW50Ll9zdXBlci5wbGF5SnNvbi5jYWxsKHRoaXMsIHBKc29uTW9kZWwpOwogICAgICAgICAgICB2YXIgc2NoZW1hQ2hpbGRyZW4gPSB0aGlzLl94ZmEoKS5fdGVtcGxhdGVTY2hlbWEuZ2V0Q2hpbGRyZW4odGhpcy5jbGFzc05hbWUpOwogICAgICAgICAgICBfLmVhY2goc2NoZW1hQ2hpbGRyZW4sIGZ1bmN0aW9uIChzY2hlbWFDaGlsZFByb3BzLCBzY2hlbWFDaGlsZFRhZykgewogICAgICAgICAgICAgICAgLy8gaWYgc2NoZW1hQ2hpbGRUYWcgaXMgYSBET01lbGVtIG90aGVyIHRoYW4gaXRlbXMsdmFsdWUgY29udGludWUKICAgICAgICAgICAgICAgIGlmICh4ZmFsaWIuc2NyaXB0LmRvbVtzY2hlbWFDaGlsZFRhZy5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHNjaGVtYUNoaWxkVGFnLnN1YnN0cmluZygxKV0gIT09IHVuZGVmaW5lZCAvLyBUT0RPIDogdGFrZSBjYXJlIG9mIHRob3NlIGRvbUVsZW1lbnRzIHdpdGggMm5kIG9yZGVyIGluaGVyaXRhbmNlCiAgICAgICAgICAgICAgICAgICAgJiYgIV8uY29udGFpbnMoWyJ2YWx1ZSIsICJpdGVtcyJdLCBzY2hlbWFDaGlsZFRhZykpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAodGhpcy5wbGF5SnNvbkZvckVsZW1lbnQoc2NoZW1hQ2hpbGRUYWcsIHBKc29uTW9kZWwpKSB7ICAgLy8gY29udGludWUgaWYgdGhpcyBjaGlsZFRhZyBoYXMgc3BlY2lhbCBoYW5kbGluZwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2YXIgcmVsYXRpb24gPSBzY2hlbWFDaGlsZFByb3BzLnJlbGF0aW9uOwogICAgICAgICAgICAgICAgdmFyIG5ld0pDaGlsZHJlbiA9IF8uZmlsdGVyKF8uY29tcGFjdChwSnNvbk1vZGVsLmNoaWxkcmVuKSwgZnVuY3Rpb24gKGpDaGlsZCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBqQ2hpbGQuX2NsYXNzID09IHNjaGVtYUNoaWxkVGFnOwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICB2YXIgb2xkTUNoaWxkcmVuID0gXy5maWx0ZXIodGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uIChtQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbUNoaWxkLmNsYXNzTmFtZSA9PSBzY2hlbWFDaGlsZFRhZzsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICAgICAgdmFyIG9uZU9mQ2hpbGRQcm9jZXNzZWQgPSBmYWxzZTsKCiAgICAgICAgICAgICAgICAvLyB0byBtZXJnZSBmaWVsZCBpdGVtcyBoYXZpbmcgYmluZ2RJdGVtcyBwcm9wZXJ0eQogICAgICAgICAgICAgICAgLy8gaG9ub3VyIHNhdmVQcm9wZXJ0eSB3aGlsZSBwbGF5aW5nSnNvbiBmb3IgbmV3IGFuZCBvbGQgY2hpbGRyZW4KICAgICAgICAgICAgICAgIC8vIGl0ZW1zIGhhdmUgemVyb09yVHdvIHJlbGF0aW9uCiAgICAgICAgICAgICAgICBpZiAoc2NoZW1hQ2hpbGRUYWcgPT0gIml0ZW1zIiAmJiB0aGlzLmdldEVsZW1lbnQoIiNiaW5kSXRlbXMiKSAmJiBvbGRNQ2hpbGRyZW4ubGVuZ3RoICYmIG5ld0pDaGlsZHJlbi5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRJbmRleCA9IC0xLAogICAgICAgICAgICAgICAgICAgICAgICBuZXdDaGlsZCA9IG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgIG9sZENoaWxkID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBjaGlsZEluZGV4ID0gXy5maW5kSW5kZXgob2xkTUNoaWxkcmVuICwgZnVuY3Rpb24gKG9sZE1DaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2Uob2xkTUNoaWxkLCAic2F2ZSIsIDApID09IDE7CiAgICAgICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICAgICAgb2xkQ2hpbGQgPSBvbGRNQ2hpbGRyZW4uc3BsaWNlKGNoaWxkSW5kZXgsIDEpOwogICAgICAgICAgICAgICAgICAgIGNoaWxkSW5kZXggPSBfLmZpbmRJbmRleChuZXdKQ2hpbGRyZW4gLCBmdW5jdGlvbiAobmV3SkNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZShuZXdKQ2hpbGQsICJzYXZlIiwgMCkgPT0gMTsKICAgICAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICBuZXdDaGlsZCA9IG5ld0pDaGlsZHJlbi5zcGxpY2UoY2hpbGRJbmRleCwgMSk7CiAgICAgICAgICAgICAgICAgICAgb2xkQ2hpbGRbMF0ucGxheUpzb24obmV3Q2hpbGRbMF0pOyAgLy8gcGxheUpzb24gZm9yIGl0ZW0gaGF2aW5nIHNhdmUgcHJvcGVydHkKCiAgICAgICAgICAgICAgICAgICAgb2xkQ2hpbGQgPSBvbGRNQ2hpbGRyZW4uc2hpZnQoKTsKICAgICAgICAgICAgICAgICAgICBuZXdDaGlsZCA9IG5ld0pDaGlsZHJlbi5zaGlmdCgpOwogICAgICAgICAgICAgICAgICAgIGlmIChvbGRDaGlsZCAmJiBuZXdDaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICBvbGRDaGlsZC5wbGF5SnNvbihuZXdDaGlsZCk7ICAvL3BsYXlKc29uIGZvciBpdGVtIHdpdGhvdXQgc2F2ZSBwcm9wZXJ0eQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBzd2l0Y2ggKHJlbGF0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLnplcm9Pck9uZSA6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdKQ2hpbGRyZW4ubGVuZ3RoID4gMCAmJiBvbGRNQ2hpbGRyZW4ubGVuZ3RoID09IDApIHsgLy9BZGRpdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld01DaGlsZCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlTW9kZWwobmV3SkNoaWxkcmVuWzBdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkZENoaWxkKG5ld01DaGlsZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobmV3SkNoaWxkcmVuLmxlbmd0aCA9PSAwICYmIG9sZE1DaGlsZHJlbi5sZW5ndGggPiAwKSB7IC8vcmVtb3ZhbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVtb3ZlQ2hpbGQob2xkTUNoaWxkcmVuWzBdKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChuZXdKQ2hpbGRyZW4ubGVuZ3RoID4gMCAmJiBvbGRNQ2hpbGRyZW4ubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkTUNoaWxkcmVuWzBdLnBsYXlKc29uKG5ld0pDaGlsZHJlblswXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5vbmVPZkNoaWxkIDoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFvbmVPZkNoaWxkUHJvY2Vzc2VkICYmIG5ld0pDaGlsZHJlbi5sZW5ndGggPiAwICYmIG9sZE1DaGlsZHJlbi5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3IgdGhlIHRpbWUgYmVpbmcgbGV0J3MgYXNzdW1lIG9uZU9mQ2hpbGQgdHlwZSBjYW4gbm90IGJlIG1vZGlmaWVkIGFuZCBjYW4gbm90IGJlIGFkZGVkL3JlbW92ZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZE1DaGlsZHJlblswXS5wbGF5SnNvbihuZXdKQ2hpbGRyZW5bMF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgb25lT2ZDaGlsZFByb2Nlc3NlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgOgogICAgICAgICAgICAgICAgICAgICAgICBfLmVhY2gob2xkTUNoaWxkcmVuLCBmdW5jdGlvbiAob2xkTUNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3SkNoaWxkID0gbmV3SkNoaWxkcmVuLnNoaWZ0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3SkNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkTUNoaWxkLnBsYXlKc29uKG5ld0pDaGlsZCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVDaGlsZChvbGRNQ2hpbGQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ld0pDaGlsZHJlbi5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLmVhY2gobmV3SkNoaWxkcmVuLCBmdW5jdGlvbiAobmV3SkNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld01DaGlsZCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlTW9kZWwobmV3SkNoaWxkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9hZGRDaGlsZChuZXdNQ2hpbGQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIHBsYXlKc29uRm9yRWxlbWVudDogZnVuY3Rpb24gKGVsTmFtZSwgcEpzb25Nb2RlbCkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgIGlmIChkaWZmX2xldmVsPT09MCAmJiB0aGlzLl9uZXdDaGlsZCA9PSB0cnVlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICJjaGFuZ2VkIjogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAianNvbkRpZmZlcmVuY2UiOiB0aGlzLmpzb25Nb2RlbAogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgZGlmZiA9IEVsZW1lbnQuX3N1cGVyLl9jb21wdXRlSnNvbkRpZmYuY2FsbCh0aGlzLCBkaWZmX2xldmVsKTsKICAgICAgICAgICAgdmFyIGF0dHJDaGFuZ2VGb3VuZCA9IGRpZmYuY2hhbmdlZDsKICAgICAgICAgICAgdmFyIGRlc3QgPSBkaWZmLmpzb25EaWZmZXJlbmNlOwogICAgICAgICAgICB2YXIgaW5pdGlhbEpzb24gPSB0aGlzLl94ZmEoKS5feGZhVGVtcGxhdGVDYWNoZS5nZXRJbml0aWFsRm9ybURvbVJlZih0aGlzLmh0bWxJZCk7CiAgICAgICAgICAgIGlmICghaW5pdGlhbEpzb24pIHsKICAgICAgICAgICAgICAgIGluaXRpYWxKc29uID0gdGhpcy5feGZhKCkuX3hmYVRlbXBsYXRlQ2FjaGUuZ2V0SW5pdGlhbEZvcm1Eb21SZWYodGhpcy5fdGVtcGxhdGVJZCgpKSB8fCB7fTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgY2hpbGRDaGFuZ2VGb3VuZCA9IGZhbHNlOwogICAgICAgICAgICB2YXIgaW5pdGlhbEpzb25DaGlsZHJlbiA9IHRoaXMuZ2V0T3JFbHNlKGluaXRpYWxKc29uLCAiY2hpbGRyZW4iLCBbXSk7CiAgICAgICAgICAgIGlmICh0aGlzLmdldE9yRWxzZSh0aGlzLm1vQ2hpbGROb2RlcywgImxlbmd0aCIsIDApICE9IHRoaXMuZ2V0T3JFbHNlKGluaXRpYWxKc29uQ2hpbGRyZW4sICJsZW5ndGgiLCAwKSkgewogICAgICAgICAgICAgICAgY2hpbGRDaGFuZ2VGb3VuZCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBjaGlsZENoYW5nZUZvdW5kID0gKG51bGwgIT0gXy5maW5kKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbiAobUNoaWxkLCBpbmRleCkgewogICAgICAgICAgICAgICAgICAgIGlmICgobUNoaWxkLmNsYXNzTmFtZSAhPSBpbml0aWFsSnNvbkNoaWxkcmVuW2luZGV4XS5fY2xhc3MpIHx8IChtQ2hpbGQuanNvbk1vZGVsLm5hbWUgIT09IGluaXRpYWxKc29uQ2hpbGRyZW5baW5kZXhdLm5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9LCB0aGlzKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBkZXN0Q2hpbGRyZW4gPSBbXTsKICAgICAgICAgICAgXy5lYWNoKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbiAobUNoaWxkLCBpbmRleCkgewogICAgICAgICAgICAgICAgdmFyIGNoaWxkRGlmZiA9IG1DaGlsZC5fY29tcHV0ZUpzb25EaWZmKGRpZmZfbGV2ZWwpIHx8IHt9OwogICAgICAgICAgICAgICAgaWYgKCEoZGlmZl9sZXZlbD4wICYmIF8uaXNFbXB0eShjaGlsZERpZmYuanNvbkRpZmZlcmVuY2UpKSkgeyAgLy8gc2tpcCBpZiBkdXJpbmcgc3VibWlzc2lvbiAmIHJlc3RvcmVGb3JtU3RhdGUgdGhlIGNoaWxkRGlmZiBpcyBlbXB0eQogICAgICAgICAgICAgICAgICAgIGRlc3RDaGlsZHJlbi5wdXNoKGNoaWxkRGlmZi5qc29uRGlmZmVyZW5jZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZENoYW5nZUZvdW5kICYmIGNoaWxkRGlmZi5jaGFuZ2VkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkQ2hhbmdlRm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICBpZiAoZGlmZl9sZXZlbD4wICYmIGRlc3RDaGlsZHJlbi5sZW5ndGggPT0gMCkgeyAvLyBza2lwIGlmIGR1cmluZyBzdWJtaXNzaW9uICAmIHJlc3RvcmVGb3JtU3RhdGUgbm8gY2hpbGRyZW4gcHJlc2VudAogICAgICAgICAgICAgICAgaWYgKHRoaXMuanNvbk1vZGVsLl9jbGFzcyAhPT0gJ2Zvcm0nKSB7IC8vIGV4Y2VwdCBmb3Igcm9vdCBzdWJmb3JtIExDLTkzMTcKICAgICAgICAgICAgICAgICAgICBkZXN0ID0gdW5kZWZpbmVkOyAvLyBtdXN0IGJlIGNhcmVmdWwgd2hpbGUgYXNzaWduaW5nIHRvIGpzb25EaWZmZXJlbmNlLCBpZGVhbGx5IHNob3VsZCBsZXQgaXQgYmUge30sIGJ1dCB0aGlzIGNvc3RzIGJ5dGVzIGluIGZpbmFsIGpzb24KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGRlc3QuY2hpbGRyZW4gPSBkZXN0Q2hpbGRyZW47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB7ImNoYW5nZWQiOiBjaGlsZENoYW5nZUZvdW5kIHx8IGF0dHJDaGFuZ2VGb3VuZCwKICAgICAgICAgICAgICAgIGpzb25EaWZmZXJlbmNlOiBkZXN0CiAgICAgICAgICAgIH07CiAgICAgICAgfSwKCiAgICAgICAgX2dldE9uZU9mQ2hpbGQ6IGZ1bmN0aW9uIChiUGVlaykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgYlBlZWsgPSB0eXBlb2YgYlBlZWsgPT09ICJ1bmRlZmluZWQiID8gZmFsc2UgOiB0cnVlOwogICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9vbmVPZkNoaWxkICYmIGJQZWVrID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuX3hmYSgpLl90ZW1wbGF0ZVNjaGVtYS5fZ2V0T25lT2ZDaGlsZCh0aGlzLmNsYXNzTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb25lT2ZDaGlsZCA9IF8uZmluZCh0aGlzLm1vQ2hpbGROb2RlcywgZnVuY3Rpb24gKGNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZC5jbGFzc05hbWUgaW4gY2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX29uZU9mQ2hpbGQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX29uZU9mQ2hpbGQgPSB0aGlzLl9vbmVPZkNoaWxkLl9nZXROYWtlZFRoaXMoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbmVPZkNoaWxkOwogICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLkxvZ2dlci5lcnJvcigieGZhIiwgeGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDE3Il0sIFtleGNlcHRpb24sICJvbmVPZkNoaWxkIiwgY29udGV4dE9iai5zb21FeHByZXNzaW9uXSkKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiB0aGUgYmluZCBjaGlsZCBvZiB0aGUgY3VycmVudCBlbGVtZW50LiBnZXRFbGVtZW50IEFQSSBkb2Vzbid0IHJldHVybiB0aGUgY29ycmVjdCB2YWx1ZSBpbiBjYXNlIG9mCiAgICAgICAgICogdW5uYW1lZCBlbGVtZW50IGluc2lkZSB0aGUgY3VycmVudCBlbGVtZW50CiAgICAgICAgICogQHJldHVybnMgeyp9CiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfZ2V0QmluZGluZzogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gXy5maW5kKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbihjaGlsZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkLmNsYXNzTmFtZSA9PT0gImJpbmQiCiAgICAgICAgICAgIH0pCiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQ2hlY2tzIHdoZXRoZXIgYmluZGluZyBpcyBub25lIG9yIG5vdC4gUmV0dXJucyBmYWxzZSBpZiBiaW5kaW5nIGlzIHNldCB0byBub25lLCBvdGhlcndpc2UgZmFsc2UuCiAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59CiAgICAgICAgICovCiAgICAgICAgaGFzRGF0YUJpbmRpbmc6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGJpbmQgPSB0aGlzLl9nZXRCaW5kaW5nKCk7CiAgICAgICAgICAgIC8vYmluZCA9IG51bGwgbWVhbnMgdXNlIG5hbWUgYmluZGluZwogICAgICAgICAgICByZXR1cm4gYmluZCA9PSBudWxsIHx8IGJpbmQubWF0Y2ggIT09ICJub25lIjsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiByZXR1cm5zIGRhdGFTb20gZm9yIHRoZSBjdXJyZW50IGZpZWxkCiAgICAgICAgICogQHJldHVybnMgeyp9CiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfZ2V0RGF0YVNvbTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcywgImV4dHJhcy5GU19FWFRSQVMuRlNfREFUQV9TT00udmFsdWUiLCBudWxsKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGJpbmRSZWYgZm9yIHRoZSBlbGVtZW50IHBvaW50cyB0byBhbiBhdHRyaWJ1dGUgb3RoZXJ3aXNlIGZhbHNlLgogICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufQogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2lzQmluZFJlZkF0dHJpYnV0ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gMSA9PSB0aGlzLmdldE9yRWxzZSh0aGlzLCAiZXh0cmFzLkZTX0VYVFJBUy5JU19BVFRSSUJVVEUudmFsdWUiLCAwKTsKICAgICAgICB9LAoKICAgICAgICBfY29udmVydFJlZlRvWFBhdGg6IGZ1bmN0aW9uIChiaW5kUmVmKSB7CiAgICAgICAgICAgIHZhciAkcmVnZXggPSAvXlwkXC4vLAogICAgICAgICAgICAgICAgJHJlY29yZFJlZ2V4ID0gL15cJHJlY29yZFwuLywKICAgICAgICAgICAgICAgIHJlbGF0aXZlLAogICAgICAgICAgICAgICAgX2JpbmRSZWYsCiAgICAgICAgICAgICAgICBzb21BcnJheTsKICAgICAgICAgICAgaWYoYmluZFJlZi5tYXRjaCgkcmVjb3JkUmVnZXgpICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHJlbGF0aXZlID0gZmFsc2U7CiAgICAgICAgICAgICAgICBfYmluZFJlZiA9IGJpbmRSZWYucmVwbGFjZSgkcmVjb3JkUmVnZXgsICIiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJlbGF0aXZlID0gdHJ1ZTsKICAgICAgICAgICAgICAgIF9iaW5kUmVmID0gYmluZFJlZi5yZXBsYWNlKCRyZWdleCwgIiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNvbUFycmF5ID0geGZhbGliLnNjcmlwdC5TT01FeHByZXNzaW9uLnByb3RvdHlwZS5zcGxpdEV4cHJlc3Npb24oX2JpbmRSZWYpOwogICAgICAgICAgICBfYmluZFJlZiA9IF8ucmVkdWNlKHNvbUFycmF5LCBmdW5jdGlvbiAobWVtbywgc29tLCBpbmR4KSB7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudFNvbSA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlU29tRXhwcmVzc2lvbihzb20sIDApLAogICAgICAgICAgICAgICAgICAgIGluZGV4ID0gY3VycmVudFNvbS5pbmRleDsKICAgICAgICAgICAgICAgIC8vIGluZGV4IGluIFNPTSBFeHByZXNzaW9uIHN0YXJ0cyBmcm9tIDAgd2hlcmVhcyBpbiB4cGF0aCBpdCBzdGFydHMgZnJvbSAxCiAgICAgICAgICAgICAgICBpZihfLmlzTnVtYmVyKGluZGV4KSkgewogICAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihpbmR4ID09PSBzb21BcnJheS5sZW5ndGggLSAxICYmIHRoaXMuX2lzQmluZFJlZkF0dHJpYnV0ZSgpKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gb25seSBsYXN0IHBhcnQgaW4gdGhlIGJpbmRSZWYgY2FuIGJlIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgIHJldHVybiBtZW1vICsgIkAiICsgY3VycmVudFNvbS5uYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIG1lbW8gKyBjdXJyZW50U29tLm5hbWUgKyAiWyIgKyBpbmRleCArICJdLyIKICAgICAgICAgICAgfSwgIiIsIHRoaXMpOwogICAgICAgICAgICAvL3JlcGxhY2UgdGhlIGxhc3QgLyBpZiBleGlzdHMgd2l0aCBlbXB0eSBzdHJpbmcKICAgICAgICAgICAgX2JpbmRSZWYgPSBfYmluZFJlZi5yZXBsYWNlKC9cLyQvLCIiKTsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgIHJlbGF0aXZlOiByZWxhdGl2ZSwKICAgICAgICAgICAgICAgIGJpbmRSZWY6IF9iaW5kUmVmCiAgICAgICAgICAgIH07CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyB0aGUgeHBhdGggZnJvbSB0aGUgYmluZC5kYXRhcmVmIHByb3BlcnR5LiByZW1vdmVzIHRoZSBsZWFkaW5nICQuIGZyb20gdGhlIGRhdGFSZWYuCiAgICAgICAgICogVE9ETzogaW4gc29tZSBwbGFjZXMgdGhlIGRhdGFSZWYgcHJvcGVydHkgaGFzICRyZWNvcmQuIE5lZWQgdG8gZGlzY3VzcyB0aGF0IGNhc2UKICAgICAgICAgKiBNb3Jlb3ZlciB0aGlzIG1pZ2h0IG5vdCBiZSBuZWVkZWQgaWYgWFRHIHByb3ZpZGVzIERBVEFTT00gZm9yIHRoZSBzdWJmb3Jtcy4KICAgICAgICAgKiBAcmV0dXJucyB7Kn0KICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9nZXRYcGF0aEZyb21CaW5kUmVmOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBiaW5kID0gdGhpcy5fZ2V0QmluZGluZygpLAogICAgICAgICAgICAgICAgYmluZFJlZiA9IHRoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIiksCiAgICAgICAgICAgICAgICAkcmVnZXggPSAvXlwkXC4vLAogICAgICAgICAgICAgICAgJHJlY29yZFJlZ2V4ID0gL15cJHJlY29yZFwuLywKICAgICAgICAgICAgICAgIHJlbGF0aXZlID0gdHJ1ZSwKICAgICAgICAgICAgICAgIHNvbUFycmF5OwogICAgICAgICAgICBpZihiaW5kICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGlmKGJpbmQubWF0Y2ggPT09ICJkYXRhUmVmIikgewogICAgICAgICAgICAgICAgICAgIGlmKGJpbmQucmVmLm1hdGNoKCRyZWNvcmRSZWdleCkgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBiaW5kUmVmID0gYmluZC5yZWYucmVwbGFjZSgkcmVjb3JkUmVnZXgsICIiKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRSZWYgPSBiaW5kLnJlZi5yZXBsYWNlKCRyZWdleCwgIiIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzb21BcnJheSA9IHhmYWxpYi5zY3JpcHQuU09NRXhwcmVzc2lvbi5wcm90b3R5cGUuc3BsaXRFeHByZXNzaW9uKGJpbmRSZWYpOwogICAgICAgICAgICAgICAgICAgIGJpbmRSZWYgPSBfLnJlZHVjZShzb21BcnJheSwgZnVuY3Rpb24gKG1lbW8sIHNvbSwgaW5keCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VycmVudFNvbSA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlU29tRXhwcmVzc2lvbihzb20sIDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBjdXJyZW50U29tLmluZGV4OwogICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmRleCBpbiBTT00gRXhwcmVzc2lvbiBzdGFydHMgZnJvbSAwIHdoZXJlYXMgaW4geHBhdGggaXQgc3RhcnRzIGZyb20gMQogICAgICAgICAgICAgICAgICAgICAgICBpZihfLmlzTnVtYmVyKGluZGV4KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDE7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYoaW5keCA9PT0gc29tQXJyYXkubGVuZ3RoIC0gMSAmJiB0aGlzLl9pc0JpbmRSZWZBdHRyaWJ1dGUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb25seSBsYXN0IHBhcnQgaW4gdGhlIGJpbmRSZWYgY2FuIGJlIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1lbW8gKyAiQCIgKyBjdXJyZW50U29tLm5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1lbW8gKyBjdXJyZW50U29tLm5hbWUgKyAiWyIgKyBpbmRleCArICJdLyIKICAgICAgICAgICAgICAgICAgICB9LCAiIiwgdGhpcyk7CiAgICAgICAgICAgICAgICAgICAgLy9yZXBsYWNlIHRoZSBsYXN0IC8gaWYgZXhpc3RzIHdpdGggZW1wdHkgc3RyaW5nCiAgICAgICAgICAgICAgICAgICAgYmluZFJlZiA9IGJpbmRSZWYucmVwbGFjZSgvXC8kLywiIik7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmU6IHJlbGF0aXZlLAogICAgICAgICAgICAgICAgICAgICAgICBiaW5kUmVmOiBiaW5kUmVmCiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYmluZC5tYXRjaCA9PT0gImdsb2JhbCIgJiYgWyJmaWVsZCIsICJleGNsR3JvdXAiXS5pbmRleE9mKHRoaXMuY2xhc3NOYW1lKSAhPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZTogImdsb2JhbCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRSZWY6IHRoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIikgKyAiWzFdIgogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYoYmluZC5tYXRjaCA9PT0gIm9uY2UiKSB7IC8vIGZvciBmaWVsZHMgd2l0aCBwYXR0ZXJucwogICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRYUGF0aEZvclVzZU5hbWVCaW5kaW5nKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBiaW5kLm1hdGNoID09PSBudWxsCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL3VzZSBuYW1lIGJpbmRpbmcKICAgICAgICAgICAgLyoqIGZvciB1bm5hbWVkIGVsZW1lbnRzLCB3aXRoIGRhdGEgYmluZGluZyBhcyB1c2UgbmFtZSwgd2UgYXJlIHJldHVybmluZyBudWxsICovCiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRYUGF0aEZvclVzZU5hbWVCaW5kaW5nKCk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldFhQYXRoRm9yVXNlTmFtZUJpbmRpbmc6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIG5hbWUgPSB0aGlzLmdldEF0dHJpYnV0ZSgibmFtZSIpLAogICAgICAgICAgICAgICAgLy9TT00gSW5kZXggc3RhcnRzIGZyb20gMCB3aGlsZSBpbiBYUGF0aCBpdCBzdGFydHMgZnJvbSAxCiAgICAgICAgICAgICAgICBpbmRleCA9IHRoaXMuaW5kZXggKyAxOwogICAgICAgICAgICByZXR1cm4gbmFtZSA9PT0gIiIgPyBudWxsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmU6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRSZWY6IG5hbWUgKyAiWyIgKyBpbmRleCArICJdIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeSBjaGlsZCBhbmQgYWRkIGVudHJ5IGZvciB0aGVtIGludG8gdGhlIGRhdGFTT01NYXAuIFNlZSBAIE5vZGUuX2dldERhdGFTb21NYXAgZm9yIG1vcmUgZGV0YWlscwogICAgICAgICAqIEBwYXJhbSBtYXAKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqIGlmIG1hcCBpcyBub3QgYW4gb2JqZWN0IGl0IGJlaGF2ZXMgYXMgYW4gaWRlbnRpdHkgZnVuY3Rpb24KICAgICAgICAgKi8KICAgICAgICBfZ2V0RGF0YVNvbU1hcDogZnVuY3Rpb24obWFwKSB7CiAgICAgICAgICAgIGlmKCFfLmlzT2JqZWN0KG1hcCkpIHsKICAgICAgICAgICAgICAgIHJldHVybiBtYXA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgXy5lYWNoKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgIG1hcCA9IGNoaWxkLl9nZXREYXRhU29tTWFwKG1hcCk7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICByZXR1cm4gbWFwOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeSBjaGlsZCBhbmQgdXBkYXRlIHRoZWlyIHZhbHVlcyBiYXNlZCBvbiB0aGUgZW50cmllcyBpbiB0aGUgbWFwLiBTZWUgQCBOb2RlLl9nZXREYXRhU29tTWFwCiAgICAgICAgICogZm9yIG1vcmUgZGV0YWlscwogICAgICAgICAqIEBwYXJhbSBtYXAKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9yZXN0b3JlRGF0YVNvbU1hcDogZnVuY3Rpb24gKG1hcCkgewogICAgICAgICAgICBpZighXy5pc09iamVjdChtYXApKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgXy5lYWNoKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgIGNoaWxkLl9yZXN0b3JlRGF0YVNvbU1hcChtYXApOwogICAgICAgICAgICB9KQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEV2YWx1YXRlcyB0aGUgZ2l2ZW4geHBhdGggcmVsYXRpdmUgdG8gY29udGV4dE5vZGUgb3IgUm9vdE5vZGUgZGVwZW5kaW5nIHVwb24gdGhlIHZhbHVlIG9mIHhwYXRoLnJlbGF0aXZlCiAgICAgICAgICogSW4gY2FzZSBpdCBpcyB0cnVlLCB4cGF0aCBpcyBldmFsdWF0ZXMgcmVsYXRpdmUgdG8gY29udGV4dE5vZGUgb3RoZXJ3aXNlIHJvb3ROb2RlCiAgICAgICAgICogQHBhcmFtIHhwYXRoCiAgICAgICAgICogQHBhcmFtIGNvbnRleHROb2RlCiAgICAgICAgICogQHBhcmFtIHJvb3ROb2RlCiAgICAgICAgICogQHJldHVybnMgeyp9CiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfZ2V0RWxlbWVudHNGcm9tWHBhdGg6IGZ1bmN0aW9uKHhwYXRoLCBjb250ZXh0Tm9kZSwgcm9vdE5vZGUpIHsKICAgICAgICAgICAgdmFyIG5vZGVJdGVyLAogICAgICAgICAgICAgICAgWE1MVXRpbHMgPSB4ZmFsaWIudXQuWE1MVXRpbHMsCiAgICAgICAgICAgICAgICBkb2MgPSByb290Tm9kZSBpbnN0YW5jZW9mIERvY3VtZW50ID8gcm9vdE5vZGUgOiByb290Tm9kZS5vd25lckRvY3VtZW50OwogICAgICAgICAgICBpZih4cGF0aC5yZWxhdGl2ZSA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIG5vZGVJdGVyID0gWE1MVXRpbHMuZXZhbHVhdGVYUGF0aCh4cGF0aC5iaW5kUmVmLCByb290Tm9kZSwgbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBhdGhSZXN1bHQuT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUsIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYoY29udGV4dE5vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgbm9kZUl0ZXIgPSBYTUxVdGlscy5ldmFsdWF0ZVhQYXRoKHhwYXRoLmJpbmRSZWYsIGNvbnRleHROb2RlLCBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYUGF0aFJlc3VsdC5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSwgbnVsbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG5vZGVJdGVyOwogICAgICAgIH0sCgogICAgICAgIF9wbGF5RGF0YVhNTCA6IGZ1bmN0aW9uICh4bWxEb2N1bWVudCwgY29udGV4dE5vZGUsIGN1cnJlbnRCaW5kUmVmKSB7CiAgICAgICAgICAgIF8uZWFjaCh0aGlzLmNoaWxkcmVuLCBmdW5jdGlvbihjaGlsZCkgewogICAgICAgICAgICAgICBjaGlsZC5fcGxheURhdGFYTUwoeG1sRG9jdW1lbnQsIGNvbnRleHROb2RlLCBjdXJyZW50QmluZFJlZik7CiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEdlbmVyYXRlcyB0aGUgWE1MIGJ5IGFwcGVuZGluZyB0aGUgZWxlbWVudHMgaW4gdGhlIHJvb3ROb2RlCiAgICAgICAgICogQHBhcmFtIHJvb3ROb2RlIFRoZSByb290Tm9kZSBvZiB0aGUgeG1sLiBHZW5lcmFsbHkgdGhlIGVsZW1lbnQgdGhhdCBtYXBzIHRvIHRoZSByb290IG9mIHRoZSBmb3JtCiAgICAgICAgICogQHBhcmFtIGNvbnRleHROb2RlIEN1cnJlbnQgTm9kZSB3aGVyZSB0byBpbnNlcnQgdGhlIGVsZW1lbnRzIGluIGNhc2Ugb2YgcmVsYXRpdmUgYmluZGluZ3MKICAgICAgICAgKi8KICAgICAgICBnZW5lcmF0ZURhdGFYTUw6IGZ1bmN0aW9uIChyb290Tm9kZSwgY29udGV4dE5vZGUpIHsKICAgICAgICAgICAgXy5lYWNoKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbihjaGlsZCkgewogICAgICAgICAgICAgICAgY2hpbGQuZ2VuZXJhdGVEYXRhWE1MKHJvb3ROb2RlLCBjb250ZXh0Tm9kZSk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybnMgYmluZFJlZiByZWxhdGl2ZSB0byBwYXJlbnRCaW5kUmVmLiBJZiBiaW5kUmVmIGlzIG5vdCBhIGNoaWxkIG9mIHBhcmVudEJpbmRSZWYsIHJldHVybnMgbnVsbAogICAgICAgICAqIG90aGVyd2lzZSByZW1vdmVzIHRoZSBwYXJlbnRCaW5kUmVmIHN0cmluZyBmcm9tIHRoZSBiaW5kUmVmCiAgICAgICAgICogQHBhcmFtIHBhcmVudEJpbmRSZWYKICAgICAgICAgKiBAcGFyYW0gYmluZFJlZgogICAgICAgICAqIEByZXR1cm5zIHsqfQogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2dldFJlbGF0aXZlWFBhdGg6IGZ1bmN0aW9uKHBhcmVudEJpbmRSZWYsIGJpbmRSZWYpIHsKICAgICAgICAgICB2YXIgcmVnZXhwID0gbmV3IFJlZ0V4cCgiXiIgKyBwYXJlbnRCaW5kUmVmKyIvIik7CiAgICAgICAgICAgaWYoYmluZFJlZi5tYXRjaChyZWdleHApKSB7CiAgICAgICAgICAgICAgcmV0dXJuIGJpbmRSZWYucmVwbGFjZShyZWdleHAsIiIpOwogICAgICAgICAgIH0KICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICB9KTsKCiAgICBFbGVtZW50LmRlZmluZVByb3BzKHsKICAgICAgICAiY2hpbGRyZW4iOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIG5vZGVzID0gW107CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubW9DaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5tb0NoaWxkTm9kZXNbaV07CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzLnB1c2goY2hpbGQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIG5vZGVzOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChtb0NoaWxkcmVuKSB7CiAgICAgICAgICAgICAgICBtb0NoaWxkcmVuID0gdGhpcy52YWxpZGF0ZUlucHV0KG1vQ2hpbGRyZW4sICJvYmplY3QiLCBudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMubW9DaGlsZE5vZGVzID0gbmV3IEFycmF5KG1vQ2hpbGRyZW4ubGVuZ3RoKTsKICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuID0gW107CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1vQ2hpbGRyZW4ubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLm1vQ2hpbGROb2Rlc1tpXSA9IG1vQ2hpbGRyZW5baV07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb0NoaWxkTm9kZXNbaV0ucGFyZW50ID0gdGhpczsKICAgICAgICAgICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC5jaGlsZHJlbltpXSA9IG1vQ2hpbGRyZW5baV0uanNvbk1vZGVsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5ub3JtYWxpemVDaGlsZHJlbigpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgIm9uZU9mQ2hpbGQiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldE9uZU9mQ2hpbGQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIG1vQ2hpbGROb2RlczogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb0NoaWxkTm9kZXM7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tb0NoaWxkTm9kZXMgPSB2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoiYm9yZGVyV2lkdGgiIDogewogICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgdGhpcy5fYm9yZGVyV2lkdGggPSB0aGlzLl9ib3JkZXJXaWR0aCB8fCAiMC42NjI0IHB4IiA7CiAgICAgICAgIHJldHVybiAodGhpcy5fYm9yZGVyV2lkdGgpOwogICAgICAgICB9LAoKICAgICAgICAgc2V0IDogZnVuY3Rpb24od2lkdGgpIHsKICAgICAgICAgLy9UT0RPOiBTZXQgYm9yZGVyLmVkZ2UucHJlc2VuY2UgcHJvcGVydHkgdG8gdmlzaWJsZSBvbmNlIEJvcmRlciBpcyBpbXBsZW1lbnRlZAogICAgICAgICB0aGlzLl9ib3JkZXJXaWR0aCA9IHdpZHRoIDsKICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwKICAgICAgICAgdGhpcywiYm9yZGVyV2lkdGgiLG51bGwsd2lkdGgpOwogICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICB9CiAgICAgICAgIH0sICAgICAgKi8KCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CgoKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBHZW5lcmljVGV4dCA9IHhmYWxpYi5zY3JpcHQuR2VuZXJpY1RleHQgPSB4ZmFsaWIuc2NyaXB0Lk5vZGUuZXh0ZW5kKHsKICAgICAgICBfZGVmYXVsdDogInZhbHVlIiwKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIEdlbmVyaWNUZXh0Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX21vZGVsQ2hhbmdlZCA9IGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIHNldEF0dHJpYnV0ZTogZnVuY3Rpb24gKHZhbHVlLCBhdHRyTmFtZSkgewogICAgICAgICAgICBHZW5lcmljVGV4dC5fc3VwZXIuc2V0QXR0cmlidXRlLmNhbGwodGhpcywgdmFsdWUsIGF0dHJOYW1lKTsKICAgICAgICAgICAgdGhpcy5fbW9kZWxDaGFuZ2VkID0gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUpzb25EaWZmOiBmdW5jdGlvbiAoZGlmZl9sZXZlbCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTaW5jZSB3ZSBkbyBub3QgbWFpbnRhaW4gaW5pdGlhbEpzb24gb3IgdGVtcGxhdGVKc29uIGZvciBET00gZWxlbWVudHMsIHdlIHVzZSB0aGlzIGFwcHJveGltYXRlIG1ldGhvZCB0byBjb21wdXRlIGpzb25EaWZmLgogICAgICAgICAgICAgKiBUaGlzIGFzc3VtZXMgdGhhdCBhbGwgYXR0ciBjaGFuZ2VzIHdvdWxkIGhhcHBlbiB0aHJvdWdoIHNldEF0dHJpYnV0ZSBBUEkuCiAgICAgICAgICAgICAqIHNlZUFsc286IERPTUVsZW1lbnQgYW5kIE5vZGVWYWx1ZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgLy8gbXVzdCBwYXNzICd0aGlzJyBub2RlIGFzIGFyZ3VtZW50IGFycmF5IHRvIGNvbXB1dGVEb21Kc29uRGlmZgogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLnN0cmlwT3JDYWxsLmNhbGwodGhpcywgZGlmZl9sZXZlbD4wLCB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuY29tcHV0ZURvbUpzb25EaWZmLCBbdGhpc10pOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBHZW5lcmljVGV4dC5kZWZpbmVQcm9wcyh7CiAgICAgICAgInZhbHVlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmpzb25Nb2RlbC5fdmFsdWU7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT09IHRoaXMuanNvbk1vZGVsLl92YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX21vZGVsQ2hhbmdlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgdmFyIG9sZFZhbCA9IHRoaXMuanNvbk1vZGVsLl92YWx1ZQogICAgICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLl92YWx1ZSA9IHRoaXMudmFsaWRhdGVJbnB1dCh2YWx1ZSwgInN0cmluZyIsIHRoaXMuanNvbk1vZGVsLl92YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGV2ZW50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwgdGhpcywgdGhpcy5jbGFzc05hbWUsIG9sZFZhbCwgdGhpcy5qc29uTW9kZWwuX3ZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZlbnQubmFtZSwgZXZlbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwoKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBET01FbGVtZW50ID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50ID0geGZhbGliLnNjcmlwdC5FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgX2RlZmF1bHQ6ICJ2YWx1ZSIsCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBET01FbGVtZW50Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX25vcm1hbGl6ZVBlbmRpbmcgPSB0cnVlOwogICAgICAgICAgICB0aGlzLl9jaGlsZHJlbkluaXRpYWxpemVQZW5kaW5nID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5fY2hpbGRNb2RpZmllZCA9IGZhbHNlOwogICAgICAgICAgICB0aGlzLl9tb2RlbENoYW5nZWQgPSBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBoYW5kbGVFdmVudDogZnVuY3Rpb24gKGV2bnQpIHsKICAgICAgICAgICAgaWYgKGV2bnQubmFtZSA9PSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQpIHsKICAgICAgICAgICAgICAgIGV2bnQuX3Byb3BlcnR5ID0gdGhpcy5jbGFzc05hbWUgKyAiLiIgKyBldm50Ll9wcm9wZXJ0eTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsIGV2bnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRDaGlsZHJlbjogZnVuY3Rpb24gKCkgewogICAgICAgIH0sCgogICAgICAgIF9pbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vZG8gbm90aGluZwogICAgICAgIH0sCgogICAgICAgIF9pbml0Q2hpbGRyZW5JbnRlcm5hbDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgY2hpbGRyZW4gPSBuZXcgQXJyYXkoKTsKICAgICAgICAgICAgdmFyIHRlbXBOYW1lQ29udGFpbmVyID0ge307CiAgICAgICAgICAgIGlmICh0aGlzLmpzb25Nb2RlbC5jaGlsZHJlbikgewogICAgICAgICAgICAgICAgdmFyIGogPSAwOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmpzb25Nb2RlbC5jaGlsZHJlbi5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuW2ldOwogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZE1vZGVsID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVNb2RlbChjaGlsZCk7CiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5baisrXSA9IGNoaWxkTW9kZWw7CiAgICAgICAgICAgICAgICAgICAgY2hpbGRNb2RlbC5wYXJlbnQgPSB0aGlzOwogICAgICAgICAgICAgICAgICAgIGNoaWxkTW9kZWwub24oeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkRPTV9DSEFOR0VELCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICBjaGlsZE1vZGVsLl9pbml0aWFsaXplKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkTW9kZWwubmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZUluZGV4ID0gdGVtcE5hbWVDb250YWluZXJbY2hpbGRNb2RlbC5uYW1lXSB8fCAwOwogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZE1vZGVsLmluZGV4ID0gbmFtZUluZGV4OwogICAgICAgICAgICAgICAgICAgICAgICBuYW1lSW5kZXgrKzsKICAgICAgICAgICAgICAgICAgICAgICAgdGVtcE5hbWVDb250YWluZXJbY2hpbGRNb2RlbC5uYW1lXSA9IG5hbWVJbmRleDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkTW9kZWwuY2xhc3NOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc0luZGV4ID0gdGVtcE5hbWVDb250YWluZXJbIiMiICsgY2hpbGRNb2RlbC5jbGFzc05hbWVdIHx8IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkTW9kZWwubW5DbGFzc0luZGV4ID0gY2xhc3NJbmRleDsKICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NJbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICB0ZW1wTmFtZUNvbnRhaW5lclsiIyIgKyBjaGlsZE1vZGVsLmNsYXNzTmFtZV0gPSBjbGFzc0luZGV4OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX21vQ2hpbGROb2RlcyA9IGNoaWxkcmVuOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldE5ha2VkVGhpczogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBpZiAodGhpcy5fbm9ybWFsaXplUGVuZGluZykgewogICAgICAgICAgICAgICAgdGhpcy5ub3JtYWxpemVDaGlsZHJlbigpOwogICAgICAgICAgICAgICAgdGhpcy5fbm9ybWFsaXplUGVuZGluZyA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBET01FbGVtZW50Ll9zdXBlci5fZ2V0TmFrZWRUaGlzLmNhbGwodGhpcyk7CiAgICAgICAgfSwKCiAgICAgICAgc2V0QXR0cmlidXRlOiBmdW5jdGlvbiAodmFsdWUsIGF0dHJOYW1lKSB7CiAgICAgICAgICAgIERPTUVsZW1lbnQuX3N1cGVyLnNldEF0dHJpYnV0ZS5jYWxsKHRoaXMsIHZhbHVlLCBhdHRyTmFtZSk7CiAgICAgICAgICAgIHRoaXMuX21vZGVsQ2hhbmdlZCA9IHRydWU7CiAgICAgICAgfSwKCiAgICAgICAgX3Bvc3RBZGRDaGlsZDogZnVuY3Rpb24gKG9Ob2RlKSB7CiAgICAgICAgICAgIERPTUVsZW1lbnQuX3N1cGVyLl9wb3N0QWRkQ2hpbGQuY2FsbCh0aGlzLCBvTm9kZSk7Ci8vICAgICAgICAgICAgaWYob05vZGUgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQpCiAgICAgICAgICAgIC8vICAgICAgICBvTm9kZS5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQsdGhpcykgOwogICAgICAgICAgICB0aGlzLl9jaGlsZE1vZGlmaWVkID0gdHJ1ZTsKICAgICAgICAgICAgb05vZGUuX25ld0NoaWxkID0gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBfcG9zdFJlbW92ZUNoaWxkOiBmdW5jdGlvbiAob0NoaWxkKSB7CiAgICAgICAgICAgIERPTUVsZW1lbnQuX3N1cGVyLl9wb3N0UmVtb3ZlQ2hpbGQuY2FsbCh0aGlzLCBvQ2hpbGQpOwogICAgICAgICAgICB0aGlzLl9jaGlsZE1vZGlmaWVkID0gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBwbGF5SnNvbjogZnVuY3Rpb24gKHBKc29uTW9kZWwpIHsKICAgICAgICAgICAgaWYgKF8uY29udGFpbnMoWyJ2YWx1ZSIsICJpdGVtcyJdLCB0aGlzLmNsYXNzTmFtZSkpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi5zY3JpcHQuRWxlbWVudC5wcm90b3R5cGUucGxheUpzb24uY2FsbCh0aGlzLCBwSnNvbk1vZGVsKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgIGlmIChkaWZmX2xldmVsICYmIGRpZmZfbGV2ZWwgIT0gMykgewogICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICAiY2hhbmdlZCI6IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICJqc29uRGlmZmVyZW5jZSI6IHt9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9IGVsc2UgeyAvLyBub3QgY2FsbGVkIGR1cmluZyBzdWJtaXNzaW9uCiAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmV3Q2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAiY2hhbmdlZCI6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICdqc29uRGlmZmVyZW5jZSc6IHRoaXMuanNvbk1vZGVsCiAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBTaW5jZSB3ZSBkbyBub3QgbWFpbnRhaW4gaW5pdGlhbEpzb24gb3IgdGVtcGxhdGVKc29uIGZvciBET00gZWxlbWVudHMsIHdlIHVzZSB0aGlzIGFwcHJveGltYXRlIG1ldGhvZCB0byBjb21wdXRlIGpzb25EaWZmLgogICAgICAgICAgICAgICAgICAgICAqIFRoaXMgYXNzdW1lcyB0aGF0IGFsbCBhdHRyIGNoYW5nZXMgd291bGQgaGFwcGVuIHRocm91Z2ggc2V0QXR0cmlidXRlIEFQSS4KICAgICAgICAgICAgICAgICAgICAgKiBzZWVBbHNvOiBHZW5lcmljVGV4dCBhbmQgTm9kZVZhbHVlCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGZEaWZmID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmNvbXB1dGVEb21Kc29uRGlmZi5jYWxsKHRoaXMsIHRoaXMsIGRpZmZfbGV2ZWwpLAogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbkRpZmYgPSBbXSwKICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlZCA9IHNlbGZEaWZmLmNoYW5nZWQgfHwgdGhpcy5fY2hpbGRNb2RpZmllZCwKICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRDaGFuZ2VkID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25EaWZmZXJlbmNlID0gc2VsZkRpZmYuanNvbkRpZmZlcmVuY2U7CgogICAgICAgICAgICAgICAgICAgIF8uZWFjaCh0aGlzLm1vQ2hpbGROb2RlcywgZnVuY3Rpb24gKG1DaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkRGlmZiA9IG1DaGlsZC5fY29tcHV0ZUpzb25EaWZmKGRpZmZfbGV2ZWwpIHx8IHt9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRDaGFuZ2VkID0gY2hpbGRDaGFuZ2VkIHx8IGNoaWxkRGlmZi5jaGFuZ2VkOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkRGlmZi5jaGFuZ2VkICYmICFfLmlzRW1wdHkoY2hpbGREaWZmLmpzb25EaWZmZXJlbmNlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuRGlmZi5wdXNoKGNoaWxkRGlmZi5qc29uRGlmZmVyZW5jZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMpOwogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9jaGlsZE1vZGlmaWVkIHx8IGNoaWxkQ2hhbmdlZCkgewogICAgICAgICAgICAgICAgICAgICAgICBqc29uRGlmZmVyZW5jZS5jaGlsZHJlbiA9IGNoaWxkcmVuRGlmZjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJjaGFuZ2VkIjogY2hhbmdlZCwKICAgICAgICAgICAgICAgICAgICAgICAgImpzb25EaWZmZXJlbmNlIjoganNvbkRpZmZlcmVuY2UKICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJuIHRoZSBEYXRhU09NTWFwIGFmdGVyIGFkZGluZyBhbiBlbnRyeSBpbiB0aGUgbWFwIGZvciB0aGUgbm9kZS4gVGhlIGVudHJ5IGNvbnRhaW5zIHRoZSB2YWx1ZSBvZiB0aGUgbm9kZQogICAgICAgICAqIGFsb25nIHdpdGggaXRzIERhdGEgU09NLiBJZiB0aGVyZSBpcyBubyBEYXRhIFNPTSB0aGVuIHJldHVybiB0aGUgdW5tb2RpZmllZCBtYXAKICAgICAgICAgKiBAcGFyYW0gbWFwCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfZ2V0RGF0YVNvbU1hcCA6IGZ1bmN0aW9uIChtYXApIHsKICAgICAgICAgICAgcmV0dXJuIG1hcDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBVcGRhdGUgdGhlIHZhbHVlIG9mIHRoZSBub2RlIHdpdGggdGhlIHZhbHVlIHByb3ZpZGVkIGluIHRoZSBpbnB1dCBtYXAuIFRoZSBtYXAgY29udGFpbnMgdGhlIHZhbHVlcyBvZiB0aGUgZmllbGRzCiAgICAgICAgICogbWFwcGVkIHdpdGggdGhlaXIgRGF0YVNPTS4gVGhlIGZ1bmN0aW9uIGlzIGVtcHR5IGZvciBhbGwgdGhlIG5vZGVzLCBleGNlcHQgZm9yIEZpZWxkLCBTdWJmb3JtIGFuZCBBcmVhLgogICAgICAgICAqIEBwYXJhbSBtYXAKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9yZXN0b3JlRGF0YVNvbU1hcCA6IGZ1bmN0aW9uIChtYXApIHsKCiAgICAgICAgfSwKCiAgICAgICAgX3BsYXlEYXRhWE1MOiBmdW5jdGlvbiAocm9vdE5vZGUsIGNvbnRleHROb2RlKSB7CgogICAgICAgIH0sCgogICAgICAgIGdlbmVyYXRlRGF0YVhNTDogZnVuY3Rpb24gKHhtbERvY3VtZW50LCBjb250ZXh0Tm9kZSkgewoKICAgICAgICB9CgogICAgfSk7CgogICAgRE9NRWxlbWVudC5kZWZpbmVQcm9wcyh7CiAgICAgICAgbW9DaGlsZE5vZGVzOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgaWYgKHRoaXMuX2NoaWxkcmVuSW5pdGlhbGl6ZVBlbmRpbmcpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbml0Q2hpbGRyZW5JbnRlcm5hbCgpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2NoaWxkcmVuSW5pdGlhbGl6ZVBlbmRpbmcgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tb0NoaWxkTm9kZXM7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tb0NoaWxkTm9kZXMgPSB2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CgoKCi8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LkNvbnRhaW5lck5vZGUKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LkVsZW1lbnQKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBDb250YWluZXIgRWxlbWVudCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBCiAqICAgICAgICAgICAgICAgbGlicmFyeQogKiBAdmVyc2lvbiAwLjAuMQogKi8KCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgLyoqCiAgICAgKiBAY2xhc3MgVGhlIGNsYXNzIHJlcHJlc2VudHMgYWxsIHRoZSBYRkEgT2JqZWN0cyB3aGljaCBjYW4gY29udGFpbiBvdGhlciBYRkEKICAgICAqICAgICAgICBub2RlcyBpbnNpZGUgdGhlbQogICAgICogQGV4dGVuZHMgY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuRWxlbWVudAogICAgICoKICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IGNoaWxkcmVuIGNoaWxkcmVuIG9mIHRoZSBDb250YWluZXJOb2RlCiAgICAgKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgbm9kZQogICAgICoKICAgICAqLwogICAgdmFyIENvbnRhaW5lck5vZGUgPSB4ZmFsaWIuc2NyaXB0LkNvbnRhaW5lck5vZGUgPSB4ZmFsaWIuc2NyaXB0LkVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBfaXNYRkFDb250YWluZXJOb2RlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CgoKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHZhciBFdmVudENvbnRhaW5lck5vZGUgPSB4ZmFsaWIuc2NyaXB0LkV2ZW50Q29udGFpbmVyTm9kZSA9IHhmYWxpYi5zY3JpcHQuQ29udGFpbmVyTm9kZS5leHRlbmQoewogICAgICAgIF9kZWZhdWx0cyA6IHsKICAgICAgICAgICAgImFjY2VzcyIgOiAib3BlbiIsCiAgICAgICAgICAgICJldmVudCIgOiB7CiAgICAgICAgICAgICAgICAidHlwZSIgOiAiY2xpY2siIC8vaWRlYWxseSwgdGhpcyBzaG91bGQgYmUgYWN0aXZpdHkKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInZhbGlkYXRlIiA6IHsKICAgICAgICAgICAgICAgICJkaXNhYmxlQWxsIiA6ICIwIiwKICAgICAgICAgICAgICAgICJmb3JtYXRUZXN0IiA6ICJ3YXJuaW5nIiwKICAgICAgICAgICAgICAgICJudWxsVGVzdCIgOiAiZGlzYWJsZWQiLAogICAgICAgICAgICAgICAgInNjcmlwdFRlc3QiIDogImVycm9yIiwKICAgICAgICAgICAgICAgICJtZXNzYWdlIiA6IHsKICAgICAgICAgICAgICAgICAgICAiZGVmYXVsdE1lc3NhZ2UiIDogewogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogeGZhbGliLmxvY2FsZS5TdHJpbmdzLnZhbGlkYXRpb25Jc3N1ZQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICBFdmVudENvbnRhaW5lck5vZGUuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICAgICAqIEB0eXBlIE9iamVjdAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdGhpcy5tb0V2ZW50cyA9IHt9OwogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogbWFya3MgdGhlIGV2ZW50IHRoYXQgYXJlIGZpcmVkIGluIHRoZSBjdXJyZW50IHNjcmlwdCBleGVjdXRpb24gYXMgdHJ1ZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgICAgICogQHR5cGUgT2JqZWN0CiAgICAgICAgICAgICAqLwogICAgICAgICAgICB0aGlzLm1BY3RpdmVFdmVudHMgPSB7fTsKICAgICAgICAgICAgdGhpcy5fZXJyb3JUZXh0ID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5fbUZhaWxlZFZhbFRlc3QgPSBudWxsOwogICAgICAgICAgICB0aGlzLl9tRmFpbGVkVmFsTGV2ZWwgPSBudWxsOyAvL2NhbiBiZSB3YXJuaW5nIG9yIGVycm9yCiAgICAgICAgICAgIHRoaXMuZGVwZW5kYW50ID0gW107CiAgICAgICAgICAgIHRoaXMudGVzdHM9IG51bGw7IC8vbXVzdCBiZSBvdmVycmlkZGVuIGJ5IHN1YiBjbGFzc2VzCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAgICAgKiBAdHlwZSBzdHJpbmcKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHRoaXMubUVmZmVjdGl2ZUFjY2VzcyA9IG51bGw7CiAgICAgICAgICAgIHRoaXMubUVmZmVjdGl2ZVByZXNlbmNlID0gbnVsbDsKICAgICAgICAgICAgLy9Jbml0aWFsaXplIGV2ZW50cyBhcnJheQogICAgICAgICAgICB0aGlzLl9hZGRFdmVudHMoKTsKICAgICAgICAgICAgdGhpcy5fZXZlbnRMaXN0ZW5lcigpOwoKICAgICAgICAgICAgdGhpcy5fbW9Db250ZXh0ID0gbnVsbDsgIC8vIHdpbGwgY2FjaGUgdGhlIG5ha2VkUmVmZXJlbmNlcyBmb3IgZWFjaCBFdmVudENvbnRhaW5lck5vZGUKICAgICAgICAgfSwKCiAgICAgICAgLy8gdmlzaXQgdGhpcyBhbmQgYWxsIGNoaWxkIG5vZGVzIHJlY3Vyc2l2ZWx5CiAgICAgICAgX3Zpc2l0QWxsbW9DaGlsZHJlbjogZnVuY3Rpb24gKHZpc2l0b3IpIHsKICAgICAgICAgICAgaWYgKF8uaXNGdW5jdGlvbih2aXNpdG9yKSkgewogICAgICAgICAgICAgICAgdmlzaXRvcih0aGlzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgXy5lYWNoKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbiAoY2hpbGQpIHsKICAgICAgICAgICAgICAgIGlmIChfLmlzRnVuY3Rpb24oY2hpbGQuX3Zpc2l0QWxsbW9DaGlsZHJlbikpIHsKICAgICAgICAgICAgICAgICAgICBjaGlsZC5fdmlzaXRBbGxtb0NoaWxkcmVuKHZpc2l0b3IpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9LAoKCiAgICAgICAgX2V2ZW50TGlzdGVuZXIgOmZ1bmN0aW9uKCkgewogICAgICAgICAgICBmb3IgKCB2YXIgaSA9IDA7IGkgPCB0aGlzLm1vQ2hpbGROb2Rlcy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICAgICB2YXIgb05vZGUgPSB0aGlzLm1vQ2hpbGROb2Rlc1tpXTsKICAgICAgICAgICAgICAgaWYob05vZGUgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQpCiAgICAgICAgICAgICAgICAgIG9Ob2RlLm9uKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCx0aGlzKSA7CiAgICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcGFyYW0gcHJlZGljYXRlVGVzdCA6IGZ1bmN0aW9uIGNvbnRhaW5pbmcgcHJlZGljYXRlIHRlc3QuCiAgICAgICAgICogQHBhcmFtIGV4ZWNFdmVudCA6IGZ1bmN0aW9uIGNvbnRhaW5pbmcgZXZlbnRzIHdoaWNoIG5lZWRzIHRvIGJlIGV4ZWN1dGVkLgogICAgICAgICAqIGV4ZWN1dGVzIGV2ZW50cyBvbiBjaGlsZCBub2RlcyBwcm92aWRlZCBhcyBleGVjRXZlbnQuCiAgICAgICAgICovCiAgICAgICAgX2V4ZWNFdmVudE9uQ2hpbGROb2RlcyA6IGZ1bmN0aW9uIChjaGlsZE5vZGVzRmlsdGVyLCBleGVjRXZlbnQpIHsKICAgICAgICAgICAgaWYoIXRoaXMuX2lzRmllbGQoKSl7IC8vSWRlYWxseSBpc0ZpZWxkIGNoZWNrIHNob3VsZCBub3QgYmUgaGVyZSBidXQgYSBzaG9ydCBjdXQgZm9yIG5vdyBzaW5jZSBpdCdzIHRoZSBvbmx5IGV4Y3B0aW9uLgogICAgICAgICAgICAgICAgXy5lYWNoICh0aGlzLm1vQ2hpbGROb2RlcywgZnVuY3Rpb24ob05vZGUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGROb2Rlc0ZpbHRlcihvTm9kZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZXhlY0V2ZW50KG9Ob2RlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jaGlsZE5vZGVzRmlsdGVyIDogZnVuY3Rpb24gKG9Ob2RlKSB7CiAgICAgICAgICAgIHJldHVybiBvTm9kZS5faXNFdmVudE5vZGUoKSAmJiBvTm9kZS5jbGFzc05hbWUgIT0gInBhZ2VTZXQiICYmIG9Ob2RlLnByZXNlbmNlICE9ICJpbmFjdGl2ZSI7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY0luaXRpYWxpemUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGZ1bmN0aW9uIGV4ZWNFdmVudCAob05vZGUpIHsKICAgICAgICAgICAgICAgIG9Ob2RlLmV4ZWNJbml0aWFsaXplKCkKICAgICAgICAgICAgfTsKICAgICAgICAgICAgdGhpcy5fZXhlY0V2ZW50T25DaGlsZE5vZGVzKHRoaXMuX2NoaWxkTm9kZXNGaWx0ZXIsIGV4ZWNFdmVudCk7CiAgICAgICAgICAgIHRoaXMuZXhlY0V2ZW50KCJpbml0aWFsaXplIik7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY0Zvcm1SZWFkeSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBmdW5jdGlvbiBleGVjRXZlbnQgKG9Ob2RlKSB7CiAgICAgICAgICAgICAgICBvTm9kZS5leGVjRm9ybVJlYWR5KCkKICAgICAgICAgICAgfTsKICAgICAgICAgICAgdGhpcy5fZXhlY0V2ZW50T25DaGlsZE5vZGVzKHRoaXMuX2NoaWxkTm9kZXNGaWx0ZXIsIGV4ZWNFdmVudCk7CiAgICAgICAgICAgIHRoaXMuZXhlY0V2ZW50KCIkZm9ybXJlYWR5Iik7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY0xheW91dFJlYWR5IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGZ1bmN0aW9uIGV4ZWNFdmVudCAob05vZGUpIHsKICAgICAgICAgICAgICAgIG9Ob2RlLmV4ZWNMYXlvdXRSZWFkeSgpCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHRoaXMuX2V4ZWNFdmVudE9uQ2hpbGROb2Rlcyh0aGlzLl9jaGlsZE5vZGVzRmlsdGVyLCBleGVjRXZlbnQpOwogICAgICAgICAgICB0aGlzLmV4ZWNFdmVudCgiJGxheW91dHJlYWR5Iik7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY0NhbGN1bGF0ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBmdW5jdGlvbiBjaGlsZE5vZGVzRmlsdGVyIChvTm9kZSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG9Ob2RlLl9pc0V2ZW50Tm9kZSgpICYmIG9Ob2RlLnByZXNlbmNlICE9ICJpbmFjdGl2ZSI7CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIGZ1bmN0aW9uIGV4ZWNFdmVudCAob05vZGUpIHsKICAgICAgICAgICAgICAgIG9Ob2RlLmV4ZWNDYWxjdWxhdGUoKQogICAgICAgICAgICB9OwogICAgICAgICAgICBpZiAoIXRoaXMuX3hmYSgpLmhvc3QuY2FsY3VsYXRpb25zRW5hYmxlZCkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMuX2V4ZWNFdmVudE9uQ2hpbGROb2RlcyhjaGlsZE5vZGVzRmlsdGVyLCBleGVjRXZlbnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgdGhpcy5leGVjRXZlbnQoImNhbGN1bGF0ZSIpOwogICAgICAgIH0sCgogICAgICAgIGV4ZWNWYWxpZGF0ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpZiAoIXRoaXMuX3hmYSgpLmhvc3QudmFsaWRhdGlvbnNFbmFibGVkKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIHZhciB2YWxpZCA9IHRydWU7CiAgICAgICAgICAgIGlmKCF0aGlzLl9pc0ZpZWxkKCkpewogICAgICAgICAgICAgICAgZm9yICggdmFyIGkgPSAwOyBpIDwgdGhpcy5tb0NoaWxkTm9kZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgb05vZGUgPSB0aGlzLm1vQ2hpbGROb2Rlc1tpXTsKICAgICAgICAgICAgICAgICAgICBpZiAob05vZGUuX2lzRXZlbnROb2RlKCkpewogICAgICAgICAgICAgICAgICAgICAgICBpZighb05vZGUuZXhlY1ZhbGlkYXRlKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB2YWxpZCA9IHZhbGlkICYmIHRoaXMuX3ZhbGlkYXRlKFtdKTsKICAgICAgICAgICAgcmV0dXJuIHZhbGlkOwogICAgICAgIH0sCgogICAgICAgIGV4ZWNQcmVTdWJtaXQgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBpc1N1Ym1pc3Npb25BbGxvd2VkID0gdHJ1ZTsgIC8vIHRvIGhhbmRsZSB0aGUgY2FuY2VsQWN0aW9uIHByb3BlcnR5LCB3aGljaCBpZiB0cnVlIHdpbGwgcHJldmVudCBzdWJtaXNzaW9uCiAgICAgICAgICAgIGlmKCF0aGlzLl9pc0ZpZWxkKCkpIHsKICAgICAgICAgICAgICAgIF8uZWFjaCAodGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uKG9Ob2RlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKG9Ob2RlLl9pc0V2ZW50Tm9kZSgpICYmIG9Ob2RlLnByZXNlbmNlICE9ICJpbmFjdGl2ZSIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXNTdWJtaXNzaW9uQWxsb3dlZCA9IG9Ob2RlLmV4ZWNQcmVTdWJtaXQoKSAmJiBpc1N1Ym1pc3Npb25BbGxvd2VkOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLmV4ZWNFdmVudCgiJGZvcm1wcmVTdWJtaXQiKSA9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgaXNTdWJtaXNzaW9uQWxsb3dlZCA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBpc1N1Ym1pc3Npb25BbGxvd2VkOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqCiAgICAgICAgICogY3JlYXRlcyBhIHNjb3BlIHNvIHRoYXQgYWxsIHRoZSBub2RlcyBhY2Nlc3NpYmxlIGZyb20gdGhpcyBub2RlCiAgICAgICAgICogYXJlIGF2YWlsYWJsZSB0byB0aGUgc2NyaXB0IGV2ZW50IGFuZCByZXR1cm5zIHRoZSBwcmV2aW91cyBzY29wZQogICAgICAgICAqCiAgICAgICAgICogQWZ0ZXIgZXhlY3V0aW5nIHRoZSBzY3JpcHQgdGhlIHNjb3BlIG11c3QgYmUgcmVzZXQgdXNpbmcgX3Jlc2V0TmFrZWRSZWZlcmVuY2VzU2NvcGUKICAgICAgICAgKiBOb3QgZG9pbmcgdGhhdCB3aWxsIHJlc3VsdCBpbiB1bnN0YWJsZSBzdGF0ZSBhbmQgY2F1c2Ugc2VyaW91cyBpc3N1ZXMKICAgICAgICAgKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgX2NyZWF0ZU5ha2VkUmVmZXJlbmNlc1Njb3BlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBzdGFydE5vZGUgPSB0aGlzLAogICAgICAgICAgICAgICAgY3VycmVudEluZGV4ID0gdGhpcy5pbmRleCwKICAgICAgICAgICAgICAgIG9sZENvbnRleHQgPSB7fTsKCiAgICAgICAgICAgIC8vc3RvcmUgdGhlIG9sZCBjb250ZXh0IGluIG9yZGVyIHRvIHJlc2V0IGl0LgogICAgICAgICAgICBfLmV4dGVuZChvbGRDb250ZXh0LHhmYWxpYi5ydW50aW1lLl9wcml2YXRlKTsKCiAgICAgICAgICAgIC8vVE9ETzogb3B0aW1pemUgdG8gY2hlY2sgd2l0aCBsYXN0TmFrZWRTdWJmb3JtCiAgICAgICAgICAgIGlmICh0aGlzLl9tb0NvbnRleHQgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuX3ByaXZhdGUgPSB7fTsKICAgICAgICAgICAgICAgIHdoaWxlIChzdGFydE5vZGUpIHsKICAgICAgICAgICAgICAgICAgICBzdGFydE5vZGUubmFrZWRGaWVsZFJlZmVyZW5jZXMoY3VycmVudEluZGV4LCB0cnVlLCB4ZmFsaWIucnVudGltZSk7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudEluZGV4ID0gc3RhcnROb2RlLmluZGV4OwogICAgICAgICAgICAgICAgICAgIHN0YXJ0Tm9kZSA9IHN0YXJ0Tm9kZS5wYXJlbnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLl9tb0NvbnRleHQgPSB4ZmFsaWIucnVudGltZS5fcHJpdmF0ZTsgICAgLy8ganVzdCBjb3B5IHJlZiBhcyB3ZSBhcmUgcmVjcmVhdGluZyB4ZmFsaWIucnVudGltZS5fcHJpdmF0ZQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuX3ByaXZhdGUgPSB0aGlzLl9tb0NvbnRleHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG9sZENvbnRleHQ7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICoKICAgICAgICAgKiBUaGUgZnVuY3Rpb24gc2hvdWxkIGJlIGNhbGxlZCBhZnRlciBleGVjdXRpbmcgdGhlIHNjcmlwdCB0byByZXNldCB0aGUgc2NvcGUKICAgICAgICAgKiBOb3QgZG9pbmcgdGhhdCB3aWxsIHJlc3VsdCBpbiB1bnN0YWJsZSBzdGF0ZSBhbmQgY2F1c2Ugc2VyaW91cyBpc3N1ZXMKICAgICAgICAgKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgX3Jlc2V0TmFrZWRSZWZlcmVuY2VzU2NvcGUgOiBmdW5jdGlvbihzY29wZSkgewogICAgICAgICAgICB4ZmFsaWIucnVudGltZS5fcHJpdmF0ZSA9IHt9OwogICAgICAgICAgICBfLmV4dGVuZCh4ZmFsaWIucnVudGltZS5fcHJpdmF0ZSwgc2NvcGUpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSBjYXB0dXJlcyB0aGUgZXZlbnQgYW5kIHNlbmRzIGl0IHRvIHRoZSB7QGxpbmsgX2V2ZW50SGFuZGxlcn0KICAgICAgICAgKi8KICAgICAgICBleGVjRXZlbnQgOiBmdW5jdGlvbihldmVudE5hbWUsIGRldGFpbCkgewogICAgICAgICAgICBpZih0eXBlb2YgdGhpcy5tb0V2ZW50c1tldmVudE5hbWVdID09PSAidW5kZWZpbmVkIikgewogICAgICAgICAgICAgICAgaWYodGhpcy5feGZhKCkubW9Db250ZXh0Tm9kZXMubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5ydW5DYWxjQW5kVmFsaWRhdGUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZGVidWcoInhmYSIsIGV2ZW50TmFtZSsiIGZpcmVkIGZvciAiK3RoaXMuc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgIC8vdXNlIHN0YW5kYXJkIGV2ZW50IG5hbWVzIGluc3RlYWQgb2Ygb3VyIGhvbWUgbWFkZSBuYW1lcyB0byBtYXRjaCB3aGF0IHBkZiByZXR1cm5zIHRvIHVzZXIKICAgICAgICAgICAgdmFyIHN0ZEV2ZW50TmFtZSA9IHRoaXMueGZhVXRpbCgpLl94dGdFdmVudE5hbWVbZXZlbnROYW1lXSA/IHRoaXMueGZhVXRpbCgpLl94dGdFdmVudE5hbWVbZXZlbnROYW1lXSA6IGV2ZW50TmFtZTsKICAgICAgICAgICAgc3dpdGNoKGV2ZW50TmFtZSl7CiAgICAgICAgICAgICAgICBjYXNlICJjaGFuZ2UiOgogICAgICAgICAgICAgICAgICAgIGlmIChkZXRhaWw9PT11bmRlZmluZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciAkZXZlbnQgPSBuZXcgeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50KHsianNvbk1vZGVsIjp7Im5hbWUiOnN0ZEV2ZW50TmFtZSwidGFyZ2V0Ijp0aGlzfX0pOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgdmFyICRldmVudCA9IG5ldyB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQoeyJqc29uTW9kZWwiOnsibmFtZSI6c3RkRXZlbnROYW1lLCJ0YXJnZXQiOnRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicHJldlRleHQiOmRldGFpbC5wcmV2VGV4dCwibmV3VGV4dCI6ZGV0YWlsLm5ld1RleHQsImtleURvd24iOmRldGFpbC5rZXlEb3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1vZGlmaWVyIjpkZXRhaWwubW9kaWZpZXIsInNoaWZ0IjpkZXRhaWwuc2hpZnQsImNoYW5nZSI6ZGV0YWlsLmNoYW5nZSwiZnVsbFRleHQiOmRldGFpbC5mdWxsVGV4dH19KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgImNsaWNrIjoKICAgICAgICAgICAgICAgICAgICBpZiAoZGV0YWlsPT09dW5kZWZpbmVkKQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgJGV2ZW50ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudCh7Impzb25Nb2RlbCI6eyJuYW1lIjpzdGRFdmVudE5hbWUsInRhcmdldCI6dGhpc319KTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciAkZXZlbnQgPSBuZXcgeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50KHsianNvbk1vZGVsIjp7Im5hbWUiOnN0ZEV2ZW50TmFtZSwidGFyZ2V0Ijp0aGlzLCJtb2RpZmllciI6ZGV0YWlsLm1vZGlmaWVyLCJzaGlmdCI6ZGV0YWlsLnNoaWZ0fX0pOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB2YXIgJGV2ZW50ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudCh7Impzb25Nb2RlbCI6eyJuYW1lIjpzdGRFdmVudE5hbWUsInRhcmdldCI6dGhpc319KTsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuJGV2ZW50ID0gJGV2ZW50OwogICAgICAgICAgICB0aGlzLl94ZmEoKS5ldmVudCA9ICRldmVudDsKICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuZXZlbnQgPSB4ZmFsaWIuYWNyb2JhdC5BY3JvRXZlbnQuY2xvbmVFdmVudCgkZXZlbnQpOwogICAgICAgICAgICBpZih0aGlzLmFjY2VzcyA9PSAicHJvdGVjdGVkIiAmJiBldmVudE5hbWUhPT0iY2FsY3VsYXRlIiAmJiBldmVudE5hbWUhPT0gInZhbGlkYXRlIikgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEFjY29yZGluZyB0byB4ZmEgc3BlYyA6IHdoZW4gYSBjb250YWluZXIgaXMgaW5hY3RpdmUgYW55IGNhbGN1bGF0aW9ucywgdmFsaWRhdGlvbnMsIG9yIGV2ZW50cyBpdCB3b3VsZCBub3JtYWxseSBnZW5lcmF0ZSBhcmUgc3VwcHJlc3NlZAogICAgICAgICAgICBpZiAodGhpcy5tRWZmZWN0aXZlUHJlc2VuY2UgPT0gImluYWN0aXZlIikgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGhpcy5tQWN0aXZlRXZlbnRzW2V2ZW50TmFtZV0pIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLm1BY3RpdmVFdmVudHNbZXZlbnROYW1lXSA9IHRydWU7CiAgICAgICAgICAgIHRoaXMuX3hmYSgpLl9wdXNoQ29udGV4dE5vZGUodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX3hmYSgpLm1vQ29udGV4dFNjcmlwdEV2ZW50ID0gZXZlbnROYW1lOwoKICAgICAgICAgICAgdmFyIG9sZFNjb3BlID0gdGhpcy5fY3JlYXRlTmFrZWRSZWZlcmVuY2VzU2NvcGUoKTsKCiAgICAgICAgICAgIHZhciB0ZW1wJCA9ICQ7CiAgICAgICAgICAgICQgPSB0aGlzOwogICAgICAgICAgICB2YXIgclZhbHVlID0gdGhpcy5fZXZlbnRIYW5kbGVyKGV2ZW50TmFtZSk7CiAgICAgICAgICAgICQgPSB0ZW1wJDsKICAgICAgICAgICAgdGhpcy5tQWN0aXZlRXZlbnRzW2V2ZW50TmFtZV0gPSBmYWxzZTsKICAgICAgICAgICAgdGhpcy5feGZhKCkuX3BvcENvbnRleHROb2RlKCk7CiAgICAgICAgICAgIHRoaXMuX3hmYSgpLm1vQ29udGV4dFNjcmlwdEV2ZW50ID0gbnVsbDsKCiAgICAgICAgICAgICRldmVudCA9IG51bGw7CiAgICAgICAgICAgIGlmKHRoaXMuX3hmYSgpLm1vQ29udGV4dE5vZGVzLmxlbmd0aCA9PSAwKSB7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5ydW5DYWxjQW5kVmFsaWRhdGUoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2V0TmFrZWRSZWZlcmVuY2VzU2NvcGUob2xkU2NvcGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByVmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRG9tRXZlbnQ6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICB9LAoKICAgICAgICBoYW5kbGVFdmVudCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQubmFtZSkgewogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuT0JKRUNUX0RFU1RST1lFRDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZW1vdmVEZXBlbmRhbnQoZXZlbnQudGFyZ2V0KTsKICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkRPTV9DSEFOR0VEOgogICAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVEb21FdmVudChldmVudCkKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgLy94ZmEuTG9nZ2VyLmRlYnVnKCJldmVudCAiICsgZXZlbnQubmFtZSArICIgbm90IHN1cHBvcnRlZCIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGFkZERlcGVuZGFudDogZnVuY3Rpb24ob05vZGUpIHsKICAgICAgICAgICAgaWYoIX50aGlzLmRlcGVuZGFudC5pbmRleE9mKG9Ob2RlKSAmJiBvTm9kZSAhPSB0aGlzKQogICAgICAgICAgICAgICAgdGhpcy5kZXBlbmRhbnQucHVzaChvTm9kZSk7CiAgICAgICAgfSwKCiAgICAgICAgX2FkZEV2ZW50cyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgZXZlbnRzID0gXy5maWx0ZXIodGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uKGNoaWxkTW9kZWwpewogICAgICAgICAgICAgICByZXR1cm4gY2hpbGRNb2RlbC5jbGFzc05hbWUgPT0gImV2ZW50IjsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlmIChldmVudHMgJiYgZXZlbnRzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIGZvciAoIHZhciBpID0gMDsgaSA8IGV2ZW50cy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHZhciBldmVudCA9IGV2ZW50c1tpXTsKICAgICAgICAgICAgICAgICAgICAvLyByZWYgd2FzIGFkZGVkIHRvIHN1cHBvcnQgZm9ybVJlYWR5IGFuZCBsYXlvdXRSZWFkeSB3aGVyZSB0aGUgZXZlbnQgbmFtZXMgYXJlIGF2YWlsYWJsZSBhcwogICAgICAgICAgICAgICAgICAgIC8vJGZvcm1SZWFkeSBhbmQgJGxheW91dFJlYWR5IChjaGVjayAtIF94dGdFdmVudE5hbWUgaW4gdGhlIGNsYXNzOiBYZmFVdGlsLmpzKS4KICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHdlIGFkZCBhIHN0eWxlIHRvIGFuIGVsZW1lbnQsIGRlc2lnbmVyIGFkZHMgYSByZWYgdmFsdWUgb2YgJyQnCiAgICAgICAgICAgICAgICAgICAgLy93aGljaCBpcyBhbHNvIHRoZSBkZWZhdWx0LiBJbiBzdWNoIGEgc2NlbmFyaW8gdGhlIGV2ZW50IG5hbWVzIGJlY29tZSAkY2xpY2ssICRjaGFuZ2UsIGV0Yy4gVG8KICAgICAgICAgICAgICAgICAgICAvL2hhbmRsZSB0aGlzIGZvciBub3cgKHdpdGhvdXQgYSBmdWxsIGltcGxlbWVudGF0aW9uIG9mIHJlZikgd2UgYXJlIHJlbW92aW5nIHRoZSAkIGRlZmF1bHQgdmFsdWUKICAgICAgICAgICAgICAgICAgICAvL2FuZCBzZXR0aW5nIGl0IGFzICRjbGljayAtPiBjbGljaywgZXRjLiBGb3IgZGV0YWlscyBvbiByZWY6CiAgICAgICAgICAgICAgICAgICAgLy9odHRwOi8vYmxvZ3MuYWRvYmUuY29tL2Zvcm1mZWVkLzIwMDkvMDMveGZhXzMwX2V2ZW50X3Byb3BhZ2F0aW9uLmh0bWwKICAgICAgICAgICAgICAgICAgICB2YXIgcmVmID0gKGV2ZW50LnJlZiB8fCAiIik7CiAgICAgICAgICAgICAgICAgICAgaWYocmVmID09ICIkIikgcmVmID0gIiI7CiAgICAgICAgICAgICAgICAgICAgdmFyIHR5cGUgPSByZWYgKyBldmVudC5hY3Rpdml0eTsKICAgICAgICAgICAgICAgICAgICB0aGlzLm1vRXZlbnRzW3R5cGVdID0gdGhpcy5tb0V2ZW50c1t0eXBlXSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnRDaGlsZCA9IGV2ZW50Lm9uZU9mQ2hpbGQ7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGV2ZW50Q2hpbGQuY2xhc3NOYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInNjcmlwdCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihldmVudENoaWxkLnZhbHVlIT1udWxsICYmIChldmVudENoaWxkLnJ1bkF0ID09PSAic2VydmVyIiB8fCBldmVudENoaWxkLnZhbHVlLnRyaW0oKS5sZW5ndGggPjApKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubW9FdmVudHNbdHlwZV0ucHVzaChuZXcgeGZhbGliLnNjcmlwdC5FeGVjdXRhYmxlU2NyaXB0KHsianNvbk1vZGVsIiA6IGV2ZW50Q2hpbGQuanNvbk1vZGVsfSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInN1Ym1pdCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1vRXZlbnRzW3R5cGVdLnB1c2gobmV3IHhmYWxpYi5zY3JpcHQuU3VibWl0KHsianNvbk1vZGVsIiA6IGV2ZW50Q2hpbGQuanNvbk1vZGVsfSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuX25ld1N1Ym1pdEJ1dHRvbih0aGlzKTsgIC8vVE9ETzogV2hhdCBpcyBpdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgY2FsY0NoaWxkID0gIF8uZmluZCh0aGlzLm1vQ2hpbGROb2RlcywgZnVuY3Rpb24oY2hpbGRNb2RlbCl7CiAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGRNb2RlbC5jbGFzc05hbWUgPT0gImNhbGN1bGF0ZSI7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBpZihjYWxjQ2hpbGQpIHsKICAgICAgICAgICAgICAgIHZhciBjYWxjU2NyID0gXy5maW5kKGNhbGNDaGlsZC5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uKGNoaWxkTW9kZWwpewogICAgICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZE1vZGVsLmNsYXNzTmFtZSA9PSAic2NyaXB0IjsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgaWYoY2FsY1NjcikgewogICAgICAgICAgICAgICAgICAgIHRoaXMubW9FdmVudHNbImNhbGN1bGF0ZSJdID0gW25ldyB4ZmFsaWIuc2NyaXB0LkNhbGN1bGF0ZVNjcmlwdCh7Impzb25Nb2RlbCIgOiBjYWxjU2NyLmpzb25Nb2RlbH0pXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIHZhbGlkQ2hpbGQgPSAgXy5maW5kKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbihjaGlsZE1vZGVsKXsKICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZE1vZGVsLmNsYXNzTmFtZSA9PSAidmFsaWRhdGUiOwogICAgICAgICAgICB9KTsKICAgICAgICAgICAgaWYodmFsaWRDaGlsZCkgewogICAgICAgICAgICAgICAgdmFyIHZhbGlkU2NyID0gXy5maW5kKHZhbGlkQ2hpbGQubW9DaGlsZE5vZGVzLCBmdW5jdGlvbihjaGlsZE1vZGVsKXsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGRNb2RlbC5jbGFzc05hbWUgPT0gInNjcmlwdCI7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGlmKHZhbGlkU2NyKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb0V2ZW50c1sidmFsaWRhdGUiXSA9IFtuZXcgeGZhbGliLnNjcmlwdC5WYWxpZGF0ZVNjcmlwdCh7Impzb25Nb2RlbCIgOiB2YWxpZFNjci5qc29uTW9kZWx9KV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vaXMgaXQgYSBnb29kIGlkZWEgdG8gY3JlYXRlIGJlaGF2aW9yQ29uZmlnIGF0IHRoZSBmb3JtYnJpZGdlIG9yIHhmYWxpYi5ydW50aW1lIGxldmVsPz8/CiAgICAgICAgICAgIHZhciBiZWhhdmlvckNvbmZpZyA9IG5ldyB4ZmFsaWIudXQuVmVyc2lvbihmb3JtQnJpZGdlLnVzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl0pOwoKICAgICAgICAgICAgLy9UbyBtYWludGFpbiBiYWNrd2FyZCBjb21wYXRpYmlsaXR5CiAgICAgICAgICAgIGlmKGJlaGF2aW9yQ29uZmlnLmlzT24oJ2RhdGFEZXBlbmRlbnRGbG9hdGluZ0ZpZWxkJykgfHwgYmVoYXZpb3JDb25maWcuaXNPbignbWZEYXRhRGVwZW5kZW50RmxvYXRpbmdGaWVsZCcpKSB7CiAgICAgICAgICAgICAgICAvL3RoaXMgaXMgaW5zZXJ0ZWQgYnkgc2VydmVyIHdoZW4gYSBkcmF3IGVsZW1lbnQgY29udGFpbnMgZmxvYXRpbmcgZmllbGRzLgogICAgICAgICAgICAgICAgdmFyIHJlc29sdmVDaGlsZCA9IF8uZmluZCh0aGlzLm1vQ2hpbGROb2RlcywgZnVuY3Rpb24oY2hpbGRNb2RlbCl7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkTW9kZWwuY2xhc3NOYW1lID09ICJyZXNvbHZlIjsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgaWYgKHJlc29sdmVDaGlsZCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMubW9FdmVudHNbImNhbGN1bGF0ZSJdID0gW107CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl0ucHVzaChuZXcgeGZhbGliLnNjcmlwdC5GbG9hdGluZ0ZpZWxkU2NyaXB0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIEV2ZW50IEhhbmRsZXIgZnVuY3Rpb24gdG8gaGFuZGxlIGV2ZW50cyB0aHJvd24KICAgICAgICAgKi8KICAgICAgICBfZXZlbnRIYW5kbGVyIDogZnVuY3Rpb24oZXZlbnROYW1lKSB7CiAgICAgICAgICAgIHZhciByVmFsdWUgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIHN3aXRjaCAoZXZlbnROYW1lKSB7CiAgICAgICAgICAgICAgICBjYXNlICJ2YWxpZGF0ZSI6CiAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gclZhbHVlOwogICAgICAgIH0sCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiByZXR1cm5zIGlmIHRoZSBub2RlIGlzIGVsaWdpYmxlIGZvciB2YWxpZGF0aW9uIG9yIG5vdCBiYXNlZCBvbiB0aGUgcHJlc2VuY2UKICAgICAgICAgKi8KICAgICAgICBfaXNFbGlnaWJsZUZvclZhbGlkYXRpb24gOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMubUVmZmVjdGl2ZVByZXNlbmNlICE9ICJpbmFjdGl2ZSI7CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZURlcGVuZGFudHM6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBmb3IodmFyIGkgPTA7aTx0aGlzLmRlcGVuZGFudC5sZW5ndGg7aSsrKSB7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5xdWV1ZUNhbGNFdmVudCh0aGlzLmRlcGVuZGFudFtpXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaXNFdmVudE5vZGUgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICByZW1vdmVEZXBlbmRhbnQ6IGZ1bmN0aW9uKG9Ob2RlKSB7CiAgICAgICAgICAgIHRoaXMuZGVwZW5kYW50ID0gXy53aXRob3V0KG9Ob2RlKTsgICAgICAgLy9UT0RPOiBXaGF0IGlzIGl0LCBubyBzZWNvbmQgYXJndW1lbnQ/CiAgICAgICAgfSwKCiAgICAgICAgX2NoZWNrVGVzdHM6IGZ1bmN0aW9uKHNNZXNzYWdlcykgewogICAgICAgICAgICB2YXIgdmFsaWQgPSB0cnVlOwogICAgICAgICAgICB2YXIgdGVzdHMgPSB0aGlzLnRlc3RzIHx8IFtdOwogICAgICAgICAgICBmb3IodmFyIGkgPSAwO2k8dGVzdHMubGVuZ3RoO2krKykgewogICAgICAgICAgICAgICAgdmFsaWQgPSB0ZXN0c1tpXS5hcHBseSh0aGlzLGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICBpZighdmFsaWQpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbGlkOwogICAgICAgIH0sCgogICAgICAgIF9zY3JpcHRUZXN0IDogZnVuY3Rpb24oc01lc3NhZ2VzKSB7CiAgICAgICAgICAgIHZhciB2YWxpZCA9IHRydWU7CiAgICAgICAgICAgIHZhciB2YWxpZCA9IHRoaXMuZXhlY0V2ZW50KCJ2YWxpZGF0ZSIpOwogICAgICAgICAgICBpZiAodmFsaWQgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tRmFpbGVkVmFsVGVzdCA9ICJzY3JpcHRUZXN0IjsKICAgICAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxMZXZlbCAgPSB0aGlzLmdldE9yRWxzZSh0aGlzLnZhbGlkYXRlLnNjcmlwdFRlc3QsIHRoaXMuX2RlZmF1bHRzLnZhbGlkYXRlLnNjcmlwdFRlc3QpIDsKICAgICAgICAgICAgICAgIHRoaXMuX2Vycm9yVGV4dCA9IHRoaXMudmFsaWRhdGlvbk1lc3NhZ2U7CiAgICAgICAgICAgICAgICB0aGlzLl9hZGRNZXNzYWdlKHNNZXNzYWdlcywgdGhpcy5fZXJyb3JUZXh0LCB0aGlzLl9tRmFpbGVkVmFsTGV2ZWwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB2YWxpZDsKICAgICAgICB9LAoKICAgICAgICBfdmFsaWRhdGUgOiBmdW5jdGlvbihzTWVzc2FnZXMpIHsKICAgICAgICAgICAgdmFyIG9sZEZhaWxlZFRlc3QgPSB0aGlzLl9tRmFpbGVkVmFsVGVzdDsKICAgICAgICAgICAgdmFyIG9sZFZhbGlkID0gdGhpcy5fZXJyb3JUZXh0ID8gZmFsc2UgOiB0cnVlOwogICAgICAgICAgICB0aGlzLl9tRmFpbGVkVmFsVGVzdCA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxMZXZlbCA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuX2Vycm9yVGV4dCA9IG51bGw7CiAgICAgICAgICAgIHZhciBjaGlsZFZhbGlkID0gdHJ1ZTsKICAgICAgICAgICAgaWYgKCF0aGlzLl9pc0VsaWdpYmxlRm9yVmFsaWRhdGlvbigpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodGhpcy5feGZhKCkuaG9zdC52YWxpZGF0aW9uc0VuYWJsZWQpIHsKICAgICAgICAgICAgICAgIGZvciAoIHZhciBpID0gMDsgaSA8IHRoaXMubW9DaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkTm9kZSA9IHRoaXMubW9DaGlsZE5vZGVzW2ldOwogICAgICAgICAgICAgICAgICAgIGlmKGNoaWxkTm9kZS5faXNFdmVudE5vZGUoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFZhbGlkID0gdGhpcy5tb0NoaWxkTm9kZXNbaV0uX3ZhbGlkYXRlKHNNZXNzYWdlcykgJiYgY2hpbGRWYWxpZDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgdmFsaWQgPSB0aGlzLl9jaGVja1Rlc3RzKHNNZXNzYWdlcykgJiYgY2hpbGRWYWxpZDsKICAgICAgICAgICAgICAgIGlmKHZhbGlkPT1mYWxzZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsIHRoaXMsIlZhbGlkYXRpb25TdGF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxMZXZlbCwgdGhpcy5fZXJyb3JUZXh0KTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICAgICAgICAgIC8vIHRydWUgaW5kaWNhdGluZyB0aGF0IHByZXZpb3VzbHkgdGhpcyBmaWVsZCBpcyBub3QgaGF2aW5nIGVycm9yCiAgICAgICAgICAgICAgICAgICAgLy8gZmFsc2UgaW5kaWNhdGluZyB0aGF0IG5vdyB0aGlzIGZpZWxkIGlzIGhhdmluZyBhbiBlcnJvcgogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELAogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLCJDbGVhckVycm9yIixudWxsLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICAgICAgICAgIC8vIGZhbHNlIGluZGljYXRpbmcgdGhhdCBwcmV2aW91c2x5IHRoaXMgZmllbGQgaXMgIGhhdmluZyBlcnJvcgogICAgICAgICAgICAgICAgICAgIC8vIHRydWUgaW5kaWNhdGluZyB0aGF0IG5vdyB0aGlzIGZpZWxkIGlzIGhhdmluZyBhbiBlcnJvciBpLmUuIGVycm9yIENsZWFyZWQKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5fdHJpZ2dlck9uQnJpZGdlKCJlbGVtZW50VmFsaWRhdGlvblN0YXR1c0NoYW5nZWQiLCB0aGlzLCAidmFsaWRhdGlvblN0YXR1cyIsICF2YWxpZCwgdmFsaWQpOwogICAgICAgICAgICAgICAgLy9UT0RPOiBzaG93IHRoZSBlcnJvciB0byB1c2VyLgogICAgICAgICAgICAgICAgaWYgKHRoaXMuX21GYWlsZWRWYWxUZXN0ICE9IG9sZEZhaWxlZFRlc3QgfHwgdmFsaWQgIT0gb2xkVmFsaWQpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5leGVjRXZlbnQoInZhbGlkYXRpb25TdGF0ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB2YWxpZDsKICAgICAgICB9LAoKICAgICAgICBfYWRkTWVzc2FnZSA6IGZ1bmN0aW9uKHNNZXNzYWdlcywgc01lc3NhZ2UsIHNTZXZlcml0eSkgewogICAgICAgICAgICBpZiAoc01lc3NhZ2UpIHsKICAgICAgICAgICAgICAgIHZhciBvTWVzc2FnZU9iamVjdCA9IG5ldyBPYmplY3QoKTsKICAgICAgICAgICAgICAgIG9NZXNzYWdlT2JqZWN0Lm1lc3NhZ2UgPSBzTWVzc2FnZTsKICAgICAgICAgICAgICAgIG9NZXNzYWdlT2JqZWN0LnNldmVyaXR5ID0gc1NldmVyaXR5OwogICAgICAgICAgICAgICAgb01lc3NhZ2VPYmplY3QucmVmID0gdGhpcy5zb21FeHByZXNzaW9uOwogICAgICAgICAgICAgICAgc01lc3NhZ2VzLnB1c2gob01lc3NhZ2VPYmplY3QpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2NhbGN1bGF0ZUVmZmVjdGl2ZUFjY2VzcyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgcGFyZW50QWNjZXNzID0gdGhpcy5wYXJlbnQgPyB0aGlzLnBhcmVudC5tRWZmZWN0aXZlQWNjZXNzOiAib3BlbiIKICAgICAgICAgICAgdmFyIG5ld0VmZkFjY2VzcyA9ICh0aGlzLmFjY2VzcyA9PT0gIm9wZW4iICYmIHBhcmVudEFjY2Vzcyk/cGFyZW50QWNjZXNzIDp0aGlzLmFjY2VzczsKICAgICAgICAgICAgaWYodGhpcy5tRWZmZWN0aXZlQWNjZXNzICE9IG5ld0VmZkFjY2VzcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIG9sZFZhbCA9IHRoaXMubUVmZmVjdGl2ZUFjY2VzczsKICAgICAgICAgICAgICAgIHRoaXMubUVmZmVjdGl2ZUFjY2VzcyA9IG5ld0VmZkFjY2VzczsKICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUNoaWxkcmVuRWZmZWN0aXZlQWNjZXNzKCk7CiAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELAogICAgICAgICAgICAgICAgICAgIHRoaXMsImFjY2VzcyIsb2xkVmFsLHRoaXMubUVmZmVjdGl2ZUFjY2Vzcyk7CiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX3VwZGF0ZUNoaWxkcmVuRWZmZWN0aXZlQWNjZXNzIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmKCF0aGlzLl9pc0ZpZWxkKCkpeyAvL0lkZWFsbHkgaXNGaWVsZCBjaGVjayBzaG91bGQgbm90IGJlIGhlcmUgYnV0IGEgc2hvcnQgY3V0IGZvciBub3cgc2luY2UgaXQncyB0aGUgb25seSBleGNlcHRpb24uCiAgICAgICAgICAgICAgICBfLmVhY2godGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uKGVsZW0pIHsKICAgICAgICAgICAgICAgICAgICBpZihlbGVtLl9pc0V2ZW50Tm9kZSgpKQogICAgICAgICAgICAgICAgICAgICAgICBlbGVtLl9jYWxjdWxhdGVFZmZlY3RpdmVBY2Nlc3MoKTsKICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqIGNhbGN1bGF0ZSBlZmZlY3RpdmUgcHJlc2VuY2Ugd2hpY2ggaXMgdXNlZCB0byBpZGVudGlmeSB3aGV0aGVyIGN1cnJlbnQgbm9kZSBoYXZlIGFuY2VzdG9yIHByZXNlbmNlIGluYWN0aXZlCiAgICAgICAgICogQWNjb3JkaW5nIHRvIFhGQSBTUEVDIDogQSBuZXcgdmFsdWUsIGluYWN0aXZlLCBpcyBkZWZpbmVkIGZvciB0aGUgdWJpcXVpdG91cyBwcmVzZW5jZSBwcm9wZXJ0eS4gV2hlbiBhcHBsaWVkIHRvIGNvbnRhaW5lcnMKICAgICAgICAgKiB0aGlzIHByZXZlbnRzIHRoZSBjb250YWluZXIgYW5kIGl0cyBjb250ZW50cyBmcm9tIHByb2Nlc3NpbmcgY2FsY3VsYXRpb25zLCB2YWxpZGF0aW9ucywgYW5kIGV2ZW50cy4KICAgICAgICAgKiBXaGVuIGFuIG91dGVyIGNvbnRhaW5lciBjb250YWlucyBpbm5lciBjb250YWluZXJzLCBhbmQgdGhlIG91dGVyIGNvbnRhaW5lciBoYXMgYSBwcmVzZW5jZSB2YWx1ZSB0aGF0IHJlc3RyaWN0cyBpdHMgYmVoYXZpb3IsCiAgICAgICAgICogdGhlIGlubmVyIGNvbnRhaW5lcnMgaW5oZXJpdCB0aGUgb3V0ZXIgY29udGFpbmVy4oCZcyByZXN0cmljdGVkIGJlaGF2aW9yIHJlZ2FyZGxlc3Mgb2YgdGhlaXIgcHJlc2VuY2UgdmFsdWUuCiAgICAgICAgICovCiAgICAgICAgX2NhbGN1bGF0ZUVmZmVjdGl2ZVByZXNlbmNlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICh0aGlzLnByZXNlbmNlKSB7ICAgICAvLyBvbmx5IGNhbGN1bGF0ZSBlZmZlY3RpdmUgcHJlc2VuY2UgaWYgaXQgY29udGFpbnMgcHJlc2VuY2UgcHJvcGVydHkKICAgICAgICAgICAgICAgIHZhciBwYXJlbnRQcmVzZW5jZSA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMsICJwYXJlbnQubUVmZmVjdGl2ZVByZXNlbmNlIiwgInZpc2libGUiKSwKICAgICAgICAgICAgICAgICAgICBuZXdFZmZQcmVzZW5jZSA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAocGFyZW50UHJlc2VuY2UgPT0gImluYWN0aXZlIiApIHsKICAgICAgICAgICAgICAgICAgICBuZXdFZmZQcmVzZW5jZSA9ICJpbmFjdGl2ZSI7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmVudFByZXNlbmNlID09ICJoaWRkZW4iICYmIHRoaXMucHJlc2VuY2UgIT0gImluYWN0aXZlIikgewogICAgICAgICAgICAgICAgICAgIG5ld0VmZlByZXNlbmNlID0gImhpZGRlbiI7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcmVudFByZXNlbmNlID09ICJpbnZpc2libGUiICYmIHRoaXMucHJlc2VuY2UgPT0gInZpc2libGUiKSB7CiAgICAgICAgICAgICAgICAgICAgbmV3RWZmUHJlc2VuY2UgPSAiaW52aXNpYmxlIjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgbmV3RWZmUHJlc2VuY2UgPSB0aGlzLnByZXNlbmNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYodGhpcy5tRWZmZWN0aXZlUHJlc2VuY2UgIT0gbmV3RWZmUHJlc2VuY2UpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLm1FZmZlY3RpdmVQcmVzZW5jZSA9IG5ld0VmZlByZXNlbmNlOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUNoaWxkcmVuRWZmZWN0aXZlUHJlc2VuY2UoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUNoaWxkcmVuRWZmZWN0aXZlUHJlc2VuY2UoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogY2FsY3VsYXRlIGVmZmVjdGl2ZSBwcmVzZW5jZSBmb3IgY2hpbGQgbm9kZQogICAgICAgICAqLwogICAgICAgIF91cGRhdGVDaGlsZHJlbkVmZmVjdGl2ZVByZXNlbmNlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmKCF0aGlzLl9pc0ZpZWxkKCkgJiYgdGhpcy5tb0NoaWxkTm9kZXMpewogICAgICAgICAgICAgICAgXy5lYWNoKHRoaXMubW9DaGlsZE5vZGVzLCBmdW5jdGlvbihvTm9kZSkgewogICAgICAgICAgICAgICAgICAgIGlmKG9Ob2RlLl9pc0V2ZW50Tm9kZSgpKQogICAgICAgICAgICAgICAgICAgICAgICBvTm9kZS5fY2FsY3VsYXRlRWZmZWN0aXZlUHJlc2VuY2UoKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcGxheUpzb24gOiBmdW5jdGlvbihwSnNvbk1vZGVsKSB7CiAgICAgICAgICAgIC8vT25seSBoYW5kbGUgc3BlY2lhbCBwcm9wZXJ0aWVzIHdoaWNoIGhhcyBwcml2YXRlIHByb3BlcnR5IGluIG1vZGVsLiBOZWVkIGEgcmV2aWV3IG9mIGFjY2VzcyBwcm9wZXJ0eQogICAgICAgICAgICBpZiAodGhpcy5feGZhKCkuX3RlbXBsYXRlU2NoZW1hLmhhc0F0dHJpYnV0ZSh0aGlzLmNsYXNzTmFtZSwgJ2FjY2VzcycpKSB7CiAgICAgICAgICAgICAgICB0aGlzLmFjY2VzcyA9IHBKc29uTW9kZWwuYWNjZXNzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLl94ZmEoKS5fdGVtcGxhdGVTY2hlbWEuaGFzQXR0cmlidXRlKHRoaXMuY2xhc3NOYW1lLCAncHJlc2VuY2UnKSkgewogICAgICAgICAgICAgICAgdGhpcy5wcmVzZW5jZSA9IHBKc29uTW9kZWwucHJlc2VuY2U7IC8vV2F0c29uIGJ1ZyAzNzg3MDAyIDogcHJlc2VuY2UgcHJvcGVydHkgY2hhbmdlZCBieSBzZXJ2ZXIgc2lkZSBzY3JpcAogICAgICAgICAgICB9CiAgICAgICAgICAgIEV2ZW50Q29udGFpbmVyTm9kZS5fc3VwZXIucGxheUpzb24uY2FsbCh0aGlzLCBwSnNvbk1vZGVsKTsKICAgICAgICB9LAoKICAgICAgICBzY29wZWxlc3MgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgLy8gVE9ETzogY2hlY2sgaXNBcmVhCiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibmFtZSIpLmxlbmd0aCA9PSAwOwogICAgICAgIH0sCgogICAgICAgIF9yZXNldERhdGEgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgZm9yICggdmFyIGkgPSAwOyBpIDwgdGhpcy5tb0NoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBvTm9kZSA9IHRoaXMubW9DaGlsZE5vZGVzW2ldOwogICAgICAgICAgICAgICAgb05vZGUuX3Jlc2V0RGF0YSgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbmFrZWRGaWVsZFJlZmVyZW5jZXMgOiBmdW5jdGlvbihuSW5kZXgsIGNyZWF0ZUdldHRlclNldHRlcixvYmopIHsKICAgICAgICAgICAgZm9yICggdmFyIGkgPSAwOyBpIDwgdGhpcy5tb05vcm1hbGl6ZWRDaGlsZHJlbi5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIG9Ob2RlID0gdGhpcy5tb05vcm1hbGl6ZWRDaGlsZHJlbltpXTsKICAgICAgICAgICAgICAgIGlmKHRoaXMuX3JlcXVpcmVHZXR0ZXJTZXR0ZXIob05vZGUpKQogICAgICAgICAgICAgICAgICAgIG9Ob2RlLmdldE5ha2VkKG5JbmRleCwgY3JlYXRlR2V0dGVyU2V0dGVyLCBvYmosdGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvLyByZXR1cm4gdGhlIHRyYXZlcnNhbCBvYmplY3QKICAgICAgICBnZXRUcmF2ZXJzYWxPYmplY3QgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMsICJqc29uTW9kZWwuY2hpbGRyZW4iLCBudWxsKSwKICAgICAgICAgICAgICAgIHRyYXZlcnNhbE9iaiA9IG51bGw7CiAgICAgICAgICAgIGlmKGNoaWxkcmVuKSB7CiAgICAgICAgICAgICAgICB0cmF2ZXJzYWxPYmogPSBfLmZpbmQoY2hpbGRyZW4sIGZ1bmN0aW9uKGNoaWxkKXsgcmV0dXJuIGNoaWxkLl9jbGFzcyA9PSAidHJhdmVyc2FsIjsgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNhbE9iajsKICAgICAgICB9LAoKICAgICAgICAvLyByZXR1cm4gTkVYVC9GSVJTVCB0cmF2ZXJzYWwgb2JqZWN0IGJhc2VkIG9uIHRoZSBvcGVyYXRpb24oZmlyc3QvbmV4dCkgcHJvdmlkZWQKICAgICAgICBnZXROZXh0VHJhdmVyc2FsU29tIDogZnVuY3Rpb24gKG9wZXJhdGlvbikgewogICAgICAgICAgICB2YXIgdHJhdmVyc2UgPSBudWxsLAogICAgICAgICAgICAgICAgdHJhdmVyc2FsUmVmID0gbnVsbCwKICAgICAgICAgICAgICAgIHRyYXZlcnNhbE9iaiA9IHRoaXMuZ2V0VHJhdmVyc2FsT2JqZWN0KCk7CiAgICAgICAgICAgIGlmICh0cmF2ZXJzYWxPYmogJiYgKHRyYXZlcnNlID0gdHJhdmVyc2FsT2JqLmNoaWxkcmVuKSkgewogICAgICAgICAgICAgICAgaWYgKG9wZXJhdGlvbiA9PSB4ZmFsaWIudGVtcGxhdGUuQ29uc3RhbnRzLmZpcnN0VHJhdmVyc2FsKSB7CiAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsUmVmID0gXy5maW5kKHRyYXZlcnNlLCBmdW5jdGlvbihjaGlsZCl7IHJldHVybiBjaGlsZC5vcGVyYXRpb24gPT0geGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5maXJzdFRyYXZlcnNhbH0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsgLy8gb25seSBmaXJzdCBhbmQgbmV4dCBhcmUgc3VwcG9ydGVkIGFuZCBpZiBubyBvcGVyYXRpb24gaXMgbWVudGlvbmVkIHRoZW4gaXQgaXMgdHJlYXRlZCBhcyBuZXh0CiAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2FsUmVmID0gXy5maW5kKHRyYXZlcnNlLCBmdW5jdGlvbihjaGlsZCl7IHJldHVybiBjaGlsZC5vcGVyYXRpb24gIT0geGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5maXJzdFRyYXZlcnNhbH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFRPIERPOiBhZGQgaGFuZGxpbmcgZm9yIHNjcmlwdCBpbiByZWZlcmVuY2UKICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNhbFJlZiAmJiB0aGlzLnJlc29sdmVOb2RlKHRyYXZlcnNhbFJlZi5yZWYpID8gdGhpcy5yZXNvbHZlTm9kZSh0cmF2ZXJzYWxSZWYucmVmKS5zb21FeHByZXNzaW9uIDogbnVsbDsKICAgICAgICB9CiAgICB9KTsKCiAgICBFdmVudENvbnRhaW5lck5vZGUuZGVmaW5lUHJvcHMoewogICAgICAgICJ2YWxpZGF0ZSIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgidmFsaWRhdGUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRFbGVtZW50KHZhbCwidmFsaWRhdGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJlcnJvclRleHQiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Vycm9yVGV4dCB8fCAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJ2YWxpZGF0aW9uTWVzc2FnZSIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgdmFyIG0gPSB0aGlzLmdldE9yRWxzZSh0aGlzLnZhbGlkYXRlLm1lc3NhZ2Uuc2NyaXB0VGVzdCwgdGhpcy5fZGVmYXVsdHMudmFsaWRhdGUubWVzc2FnZS5kZWZhdWx0TWVzc2FnZSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbS52YWx1ZTsKICAgICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgIHZhciBub2RlcyA9IHRoaXMudmFsaWRhdGUubWVzc2FnZS5ub2RlczsKICAgICAgICAgICAgICAgIGlmKG5vZGVzLm5hbWVkSXRlbSgic2NyaXB0VGVzdCIpID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSB0aGlzLl94ZmEoKS5mb3JtLmNyZWF0ZU5vZGUoInRleHQiLCJzY3JpcHRUZXN0Iik7CiAgICAgICAgICAgICAgICAgICAgbm9kZXMuYXBwZW5kKG5vZGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy52YWxpZGF0ZS5tZXNzYWdlLnNjcmlwdFRlc3QudmFsdWUgPXZhbDsKICAgICAgICAgICAgICAgIHRoaXMuZXhlY1ZhbGlkYXRlKCkgOwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgICJhY2Nlc3MiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5hY2Nlc3MsIHRoaXMuX2RlZmF1bHRzLmFjY2Vzcyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZBY2Nlc3MpIHsKICAgICAgICAgICAgICAgIHZBY2Nlc3MgPSB0aGlzLnZhbGlkYXRlSW5wdXQodkFjY2VzcywgdGhpcy5fZ2V0RGF0YVR5cGUoImFjY2VzcyIpLCB0aGlzLmpzb25Nb2RlbC5hY2Nlc3MpOwogICAgICAgICAgICAgICAgaWYgKHRoaXMuanNvbk1vZGVsLmFjY2VzcyAhPSB2QWNjZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5qc29uTW9kZWwuYWNjZXNzID0gdkFjY2VzczsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9jYWxjdWxhdGVFZmZlY3RpdmVBY2Nlc3MoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJyZWxldmFudCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyZWxldmFudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICAgICAgIHZhbCA9IHRoaXMudmFsaWRhdGVJbnB1dCh2YWwsIHRoaXMuX2dldERhdGFUeXBlKCJyZWxldmFudCIpLCB0aGlzLmpzb25Nb2RlbC5yZWxldmFudCkgOwogICAgICAgICAgICAgICAgaWYgKHRoaXMuZ2V0QXR0cmlidXRlKCJyZWxldmFudCIpICE9IHZhbCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLnJlbGV2YW50ID0gdmFsOwogICAgICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsInJlbGV2YW50IixudWxsLHZhbCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJkZXNjIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJkZXNjIiwwKQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXyx4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5Db250ZW50CiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Ob2RlCQogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIENvbnRlbnQgTm9kZSBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgovL2dvb2cucHJvdmlkZSgnY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuQ29udGVudCcpOwovLwovL2dvb2cucmVxdWlyZSgnY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuTm9kZScpOwoKKGZ1bmN0aW9uKF8sIHhmYWxpYil7CiAgICB2YXIgQ29udGVudCA9IHhmYWxpYi5zY3JpcHQuQ29udGVudCA9IHhmYWxpYi5zY3JpcHQuTm9kZS5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiAiY29udGVudCIsCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gcmV0dXJucyB3aGV0aGVyIHRoZSBub2RlIGlzIGFuIGluc3RhbmNlIG9mIGEgY29udGVudCBOb2RlIG9yIG5vdAogICAgICAgICAqLwogICAgICAgIF9pc0NvbnRlbnQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYik7CgoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuTm9kZVZhbHVlCiAqIEBpbXBvcnQgeGZhbGliLnV0LkNsYXNzCiAqLwoKCihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgTm9kZVZhbHVlID0geGZhbGliLnNjcmlwdC5Ob2RlVmFsdWUgPSB4ZmFsaWIuc2NyaXB0LkNvbnRlbnQuZXh0ZW5kKHsKCiAgICAgICAgX2RlZmF1bHQ6ICJ2YWx1ZSIsCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBOb2RlVmFsdWUuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgdGhpcy5qc29uTW9kZWwuX3ZhbHVlID0gdGhpcy5qc29uTW9kZWwuX3ZhbHVlIHx8IG51bGw7CiAgICAgICAgICAgIHRoaXMuX2luaXRpYWxKc29uU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkodGhpcy5qc29uTW9kZWwpOwogICAgICAgICAgICB0aGlzLl9tb2RlbENoYW5nZWQgPSBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBOb2RlVmFsdWUuX3N1cGVyLl9pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmICh0aGlzLl9pc0ZpZWxkRGVzY2VuZGFudCgpKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tb2RlbENoYW5nZWQgPSB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogY29udmVydHMgYSB2YWx1ZSBpbnRvIHRoZSBkZXNpZ25hdGVkIHR5cGUuIG51bGwgaXMgYSB2YWxpZCB2YWx1ZQogICAgICAgICAqIGZvciBhbGwgdHlwZXMuIEZvciBpbnZhbGlkIHZhbHVlIGl0IHJldHVybnMgdW5kZWZpbmVkCiAgICAgICAgICovCiAgICAgICAgdHlwZWRWYWx1ZTogZnVuY3Rpb24gKHZhbCwgY29udGVudFR5cGUpIHsKICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICJ1bmRlZmluZWQiKQogICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICAgICAgaWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09ICIiKQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIHJldHVybiB2YWw7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiByZXR1cm5zIHRoZSB0eXBlZCB2YWx1ZS4gc2luY2Ugd2UgbmV2ZXIgc3RvcmUgdW5kZWZpbmVkIHZhbHVlcwogICAgICAgICAqIGl0IGFsd2F5cyByZXR1cm5zIHZhbGlkIHZhbHVlCiAgICAgICAgICovCiAgICAgICAgZ2V0VmFsdWU6IGZ1bmN0aW9uIChjb250ZW50VHlwZSwgc2tpcFR5cGVDaGVjaykgewogICAgICAgICAgICBpZihza2lwVHlwZUNoZWNrID09PSB0cnVlKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwuX3ZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzLnR5cGVkVmFsdWUodGhpcy5qc29uTW9kZWwuX3ZhbHVlLCBjb250ZW50VHlwZSk7CiAgICAgICAgfSwKCiAgICAgICAgX3N0b3JlVmFsdWU6IGZ1bmN0aW9uICh2YWwsIHR5cGVWYWwpIHsKICAgICAgICAgICAgdGhpcy5qc29uTW9kZWwuX3ZhbHVlID0gdmFsOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogY29udmVydHMgdmFsIHRvIGl0cyB0eXBlZCB2ZXJzaW9uIGFuZCBpZiB2YWwgaXMgdmFsaWQgc3RvcmVzCiAgICAgICAgICogaXQuCiAgICAgICAgICogcmV0dXJucyB3aGV0aGVyIHRoZSBuZXcgdmFsdWUgaXMgZGlmZmVyZW50IGZyb20gdGhlIG9sZCBvbmUuCiAgICAgICAgICovCiAgICAgICAgc2V0VmFsdWU6IGZ1bmN0aW9uICh2YWwsIHNraXBUeXBlQ2hlY2spIHsKICAgICAgICAgICAgdmFyIG9sZFZhbCA9IHRoaXMuanNvbk1vZGVsLl92YWx1ZSwKICAgICAgICAgICAgICAgIHR5cGVWYWwgPSB0aGlzLnR5cGVkVmFsdWUodmFsKSwKICAgICAgICAgICAgICAgIHJldFZhbCA9IGZhbHNlOwoKICAgICAgICAgICAgaWYgKHNraXBUeXBlQ2hlY2sgPT09IHRydWUgfHwgdHlwZW9mIHR5cGVWYWwgIT09ICJ1bmRlZmluZWQiKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9zdG9yZVZhbHVlKHZhbCwgdHlwZVZhbCk7CiAgICAgICAgICAgICAgICByZXRWYWwgPSB0aGlzLnR5cGVkVmFsdWUob2xkVmFsKSAhPT0gdHlwZVZhbDsKICAgICAgICAgICAgICAgIHRoaXMuX21vZGVsQ2hhbmdlZCA9IHRydWU7ICAvLyBMQy01NDY1IDogYWxsIGZpZWxkJ3Mgd2hvc2UgdmFsdWUgaXMgc2V0IGlzIHRvIGJlIHJlZmxlY3RlZCBpbiBqc29uRGlmZgogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXRWYWw7CiAgICAgICAgfSwKCiAgICAgICAgZXF1YWxzOiBmdW5jdGlvbiAob1ZhbCkgewogICAgICAgICAgICByZXR1cm4gKHRoaXMuZ2V0VmFsdWUoKSA9PT0gb1ZhbC5nZXRWYWx1ZSgpKTsKICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUpzb25EaWZmOiBmdW5jdGlvbiAoZGlmZl9sZXZlbCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTaW5jZSB3ZSBkbyBub3QgbWFpbnRhaW4gaW5pdGlhbEpzb24gb3IgdGVtcGxhdGVKc29uIGZvciBET00gZWxlbWVudHMsIHdlIHVzZSB0aGlzIGFwcHJveGltYXRlIG1ldGhvZCB0byBjb21wdXRlIGpzb25EaWZmLgogICAgICAgICAgICAgKiBTaW5jZSB2YWx1ZSBBUEkgaXMgbm90IGFzIHNpbXBsZSBhcyBvdGhlciBET00gYXBpLCB3ZSBzaW1wbHkgY29tcGFyZSBvbGQgYW5kIG5ldyBqc29uIHN0cmluZyB0byBjaGVjayBpZiBhbnl0aGluZyBoYXMgY2hhbmdlZAogICAgICAgICAgICAgKiBzZWVBbHNvOiBET01FbGVtZW50IGFuZCBHZW5lcmljVGV4dAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdmFyIGpzb25TdHIgPSBKU09OLnN0cmluZ2lmeSh0aGlzLmpzb25Nb2RlbCk7CiAgICAgICAgICAgIHZhciBjaGFuZ2VkID0gKHRoaXMuX2luaXRpYWxKc29uU3RyaW5nICE9IGpzb25TdHIpOwogICAgICAgICAgICBpZiAodGhpcy5uYW1lID09PSAiRlNfREFUQV9TT00iICYmIGRpZmZfbGV2ZWwgPT09IDMpIHsKICAgICAgICAgICAgICAgIGNoYW5nZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgdGhpcy5fbW9kZWxDaGFuZ2VkID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIganNvbkRpZmYgPSBjaGFuZ2VkID8gdGhpcy5qc29uTW9kZWwgOiB7X2NsYXNzOiB0aGlzLmNsYXNzTmFtZSwgbmFtZTogdGhpcy5qc29uTW9kZWwubmFtZX07CiAgICAgICAgICAgIGlmICghY2hhbmdlZCAmJiB0aGlzLl9tb2RlbENoYW5nZWQpCiAgICAgICAgICAgICAgICBqc29uRGlmZi5fdmFsdWUgPSB0aGlzLmpzb25Nb2RlbC5fdmFsdWU7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAiY2hhbmdlZCI6IHRoaXMuX21vZGVsQ2hhbmdlZCwKICAgICAgICAgICAgICAgIGpzb25EaWZmZXJlbmNlOiBqc29uRGlmZgogICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIF9pc0ZpZWxkRGVzY2VuZGFudDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgZ3JhbmRQYXJlbnQgPSB0aGlzLmdldE9yRWxzZSh0aGlzLCAicGFyZW50LnBhcmVudCIsIG51bGwpOwogICAgICAgICAgICBpZiAoZ3JhbmRQYXJlbnQgJiYgZ3JhbmRQYXJlbnQuY2xhc3NOYW1lID09ICJmaWVsZCIpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIHBsYXlKc29uOiBmdW5jdGlvbiAocEpzb25Nb2RlbCkgewogICAgICAgICAgICBpZiAocEpzb25Nb2RlbC5fdmFsdWUgIT0gdGhpcy5qc29uTW9kZWwuX3ZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tb2RlbENoYW5nZWQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIE5vZGVWYWx1ZS5fc3VwZXIucGxheUpzb24uYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgaWYgKHR5cGVvZiBwSnNvbk1vZGVsLl92YWx1ZSA9PSAidW5kZWZpbmVkIikKICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLl92YWx1ZSA9IG51bGw7CiAgICAgICAgfQogICAgfSk7CgogICAgTm9kZVZhbHVlLmRlZmluZVByb3BzKHsKICAgICAgICAicHJlc2VuY2UiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgeyAvL2kgYW0gbm90IHN1cmUgaG93IHRvIG1ha2UgdGhpcyBwcm9wZXJ0eSB1bmRlZmluZWQgc28ganVzdCByZW1vdmVkIHNldHRlcnMKICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAidmFsdWUiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWUoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHNWYWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRWYWx1ZShzVmFsdWUpOwogICAgICAgICAgICAgICAgdmFyIGV2ZW50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwgdGhpcywgdGhpcy5jbGFzc05hbWUsIG51bGwsIHRoaXMudmFsdWUpOwogICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2ZW50Lm5hbWUsIGV2ZW50KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5JbWFnZVZhbHVlCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Ob2RlVmFsdWUKICovCgooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEltYWdlVmFsdWUgPSB4ZmFsaWIuc2NyaXB0LkltYWdlVmFsdWUgPSB4ZmFsaWIuc2NyaXB0Lk5vZGVWYWx1ZS5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiAiaW1hZ2UiCiAgICB9KTsKICAgIEltYWdlVmFsdWUuZGVmaW5lUHJvcHMoewogICAgICAgICJocmVmIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiaHJlZiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cn0oXywgeGZhbGliKSk7LyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuVGV4dFZhbHVlCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Ob2RlVmFsdWUKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBUZXh0VmFsdWUgPSB4ZmFsaWIuc2NyaXB0LlRleHRWYWx1ZSA9IHhmYWxpYi5zY3JpcHQuTm9kZVZhbHVlLmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJ0ZXh0IiwKICAgICAgICB0eXBlZFZhbHVlIDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIHZhciB0VmFsdWUgPSBUZXh0VmFsdWUuX3N1cGVyLnR5cGVkVmFsdWUuY2FsbCh0aGlzLCB2YWwpOwogICAgICAgICAgICBpZiAodFZhbHVlICE9IG51bGwpCiAgICAgICAgICAgICAgICB0VmFsdWUgPSB0VmFsdWUudG9TdHJpbmcoKTsKICAgICAgICAgICAgcmV0dXJuIHRWYWx1ZTsKICAgICAgICB9CgogICAgfSk7CgogICAgVGV4dFZhbHVlLmRlZmluZVByb3BzKHsKICAgICAgICAibWF4Q2hhcnMiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5tYXhDaGFycywgIjAiKSA7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgICAgICBpZih2YWx1ZSA8IDAgJiYgdmFsdWUgPT0gcGFyc2VJbnQodmFsdWUpKQogICAgICAgICAgICAgICAgICAgIHZhbHVlID0gIjAiOwogICAgICAgICAgICAgICAgaWYodmFsdWUgPj0gMCAmJiB2YWx1ZSA9PSBwYXJzZUludCh2YWx1ZSkpICAgewogICAgICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLm1heENoYXJzID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAodmFsdWUgPT0gIjAiKT8iMjU1Ijp2YWx1ZTsKICAgICAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQsCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsIm1heENoYXJzIix2YWx1ZSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pCn0pKF8sIHhmYWxpYik7CgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5FeERhdGFWYWx1ZQogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuTm9kZVZhbHVlCiAqLwoKKGZ1bmN0aW9uKF8sIHhmYWxpYiwgJCl7CgogICAgdmFyIEV4RGF0YVZhbHVlID0geGZhbGliLnNjcmlwdC5FeERhdGFWYWx1ZSA9IHhmYWxpYi5zY3JpcHQuTm9kZVZhbHVlLmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJleERhdGEiLAogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICBFeERhdGFWYWx1ZS5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLl90cmFuc2Zvcm1Ub1hGQUNvbXBsaWFudE1vZGVsKCk7CiAgICAgICAgICAgIHRoaXMuXyRpbnRlcm5hbFhNTERvYyA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuX29yaWdUbXBsdFZhbCA9IG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgX3RyYW5zZm9ybVRvWEZBQ29tcGxpYW50TW9kZWw6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMuY2xhc3NOYW1lID09PSAiZXhEYXRhIiAmJiB0aGlzLmpzb25Nb2RlbC5fdmFsdWUgIT09IG51bGwgJiYgdGhpcy5qc29uTW9kZWwuX3ZhbHVlLmluZGV4T2YoIjxib2R5IHhtbG5zPSIpID09PSAtMSAmJiB0aGlzLmpzb25Nb2RlbC5fdmFsdWUuaW5kZXhPZigiPGJvZHkiKSAhPT0gLTEpewogICAgICAgICAgICAgICAgdmFyIG9wZW5pbmdCb2R5VGFnSW5kZXggPSB0aGlzLmpzb25Nb2RlbC5fdmFsdWUuaW5kZXhPZignPCcpOwogICAgICAgICAgICAgICAgdmFyIGVuZGluZ0JvZHlUYWdJbmRleCA9IHRoaXMuanNvbk1vZGVsLl92YWx1ZS5pbmRleE9mKCc+Jyk7CiAgICAgICAgICAgICAgICB2YXIgYm9keVRhZ1N0cmluZyA9IHRoaXMuanNvbk1vZGVsLl92YWx1ZS5zdWJzdHJpbmcob3BlbmluZ0JvZHlUYWdJbmRleCwgZW5kaW5nQm9keVRhZ0luZGV4KzEpOwogICAgICAgICAgICAgICAgdGhpcy5qc29uTW9kZWwuX3ZhbHVlID0gdGhpcy5qc29uTW9kZWwuX3ZhbHVlLnJlcGxhY2UoYm9keVRhZ1N0cmluZywgJzxib2R5IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiB4bWxuczp4ZmE9Imh0dHA6Ly93d3cueGZhLm9yZy9zY2hlbWEveGZhLWRhdGEvMS4wLyIgeGZhOkFQSVZlcnNpb249IjIuNy4wLjAiPicpOwogICAgICAgICAgICAgICAgLy8gdGhpcy5qc29uTW9kZWwuX3ZhbHVlID0gJzxib2R5IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiB4bWxuczp4ZmE9Imh0dHA6Ly93d3cueGZhLm9yZy9zY2hlbWEveGZhLWRhdGEvMS4wLyIgeGZhOkFQSVZlcnNpb249IjIuNy4wLjAiPicgKyB0aGlzLmpzb25Nb2RlbC5fdmFsdWUgKyAnPC9ib2R5Pic7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUpzb25EaWZmOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgLy8gcmljaHRleHQgZmllbGQgdmFsdWUgc2hvdWxkIG5vdCBiZSBlbXB0eSBzdHJpbmcuCiAgICAgICAgICAgIGlmKHRoaXMuanNvbk1vZGVsLl9jbGFzcyA9PT0gImV4RGF0YSIgJiYgIXRoaXMuanNvbk1vZGVsLl92YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC5fdmFsdWUgPSBKU09OLnBhcnNlKHRoaXMuX2luaXRpYWxKc29uU3RyaW5nKS5fdmFsdWU7CiAgICAgICAgICAgICAgICB0aGlzLl90cmFuc2Zvcm1Ub1hGQUNvbXBsaWFudE1vZGVsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHsiY2hhbmdlZCIgOiB0cnVlLAogICAgICAgICAgICAgICAganNvbkRpZmZlcmVuY2UgOiB0aGlzLmpzb25Nb2RlbAogICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIHR5cGVkVmFsdWU6IGZ1bmN0aW9uKHZhbCwgY29udGVudFR5cGUpIHsKICAgICAgICAgICAgLy9pZiBjb250ZW50VHlwZSBpcyBub3QgcGFzc2VkIC0+IGRlcml2ZSBpdCBmcm9tIGNvbnRlbnRUeXBlIGF0dHJpYnV0ZQogICAgICAgICAgICBpZighY29udGVudFR5cGUpCiAgICAgICAgICAgICAgICBjb250ZW50VHlwZSA9IHRoaXMuZ2V0QXR0cmlidXRlKCJjb250ZW50VHlwZSIpOwogICAgICAgICAgICBzd2l0Y2goY29udGVudFR5cGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgInRleHQvcGxhaW4iOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBFeERhdGFWYWx1ZS5fc3VwZXIudHlwZWRWYWx1ZS5hcHBseSh0aGlzLFt2YWxdKTsKICAgICAgICAgICAgICAgIGNhc2UgInRleHQveG1sIjoKICAgICAgICAgICAgICAgICAgICBpZih2YWwgPT0gbnVsbCB8fCB2YWwubGVuZ3RoID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl8kaW50ZXJuYWxYTUxEb2MgPSAkLnBhcnNlWE1MKHZhbCk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLkxvZ2dlci5lcnJvcigiSW52YWxpZCBYTUwgZm9yIHRoZSBmaWVsZCIpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvL0lFIDkgc3VwcG9ydHMgWE1MU2VyaWFsaXplcgogICAgICAgICAgICAgICAgICAgIHJldHVybiBYTUxTZXJpYWxpemVyID8gKG5ldyBYTUxTZXJpYWxpemVyKCkpLnNlcmlhbGl6ZVRvU3RyaW5nKHRoaXMuXyRpbnRlcm5hbFhNTERvYyk6IHZhbAogICAgICAgICAgICAgICAgY2FzZSAidGV4dC9odG1sIjoKICAgICAgICAgICAgICAgICAgICBpZighKHZhbCAmJiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuaXNIVE1MKHZhbCkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuXyRpbnRlcm5hbEhUTUwgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl8kaW50ZXJuYWxIVE1MID0gJCgiPGJvZHk+PHA+PC9wPjwvYm9keT4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl8kaW50ZXJuYWxIVE1MLmh0bWwoeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmVuY29kZVNjcmlwdGFibGVUYWdzKHZhbCkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciAkdmFsID0gJCh2YWwpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl8kaW50ZXJuYWxIVE1MID0gJHZhbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuXyRpbnRlcm5hbEhUTUwudGV4dCgpOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gRXhEYXRhVmFsdWUuX3N1cGVyLnR5cGVkVmFsdWUuYXBwbHkodGhpcyxbdmFsXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBzYXZlWE1MOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHByZWZpeCA9ICc8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PicgKwogICAgICAgICAgICAgICAgICAgICAgICAgJzxleERhdGEgY29udGVudFR5cGU9InRleHQvaHRtbCIgeG1sbnM9Imh0dHA6Ly93d3cueGZhLm9yZy9zY2hlbWEveGZhLXRlbXBsYXRlLzMuNi8iPicgKwogICAgICAgICAgICAgICAgICAgICAgICAgJzxib2R5IHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiB4bWxuczp4ZmE9Imh0dHA6Ly93d3cueGZhLm9yZy9zY2hlbWEveGZhLWRhdGEvMS4wLyI+JywKICAgICAgICAgICAgICAgIHN1ZmZpeCA9ICc8L2JvZHk+PC9leERhdGE+JywKICAgICAgICAgICAgICAgIHN0clhNTCA9IHRoaXMuanNvblZhbHVlOwoKICAgICAgICAgICAgICAgIC8vIFRPRE8gOiB1c2UgalF1ZXJ5IG9yIFhNTHBhcnNlciB0byBkbyB0aGlzIG1vcmUgcmVsaWFibHkKICAgICAgICAgICAgICAgIGlmKHN0clhNTC5pbmRleE9mKCI8Ym9keSIpID49MCkKICAgICAgICAgICAgICAgICAgICBzdHJYTUwgPSBzdHJYTUwuc2xpY2Uoc3RyWE1MLmluZGV4T2YoIj4iLCBzdHJYTUwuaW5kZXhPZigiPGJvZHkiKSkrMSk7CiAgICAgICAgICAgICAgICBpZihzdHJYTUwubGFzdEluZGV4T2YoIjwvYm9keT4iKSA+PTApCiAgICAgICAgICAgICAgICAgICAgc3RyWE1MID0gc3RyWE1MLnNsaWNlKDAsc3RyWE1MLmxhc3RJbmRleE9mKCI8L2JvZHk+IikpOwoKICAgICAgICAgICByZXR1cm4gcHJlZml4ICsgc3RyWE1MICsgc3VmZml4IDsKICAgICAgICB9LAoKICAgICAgICBsb2FkWE1MOiBmdW5jdGlvbihzdHJYTUwpIHsKICAgICAgICAvL1RPRE8gOiBhZGQgc3VwcG9ydCBmb3Igb3RoZXIgcGFyYW1zIHRvIGxvYWRYTUwsIGFzIG9mIG5vdyBhbGwgY2FsbHMgYXJlIGVxdWl2YWxlbnQgdG8gbG9hZFhNTCh4LHRydWUsdHJ1ZSkKICAgICAgICAgICAgdmFyIGRpc3BWYWx1ZTsKICAgICAgICAgICAgaWYoc3RyWE1MLmluZGV4T2YoIjxib2R5IikgIT0gLTEgJiYgc3RyWE1MLmxhc3RJbmRleE9mKCI8L2JvZHk+IikgIT0gLTEpIHsgLy8gYXNzdW1pbmcgYSB3ZWxsIGZvcm1lZCB2YWxpZCBYTUwgc3RyaW5nCiAgICAgICAgICAgICAgICBkaXNwVmFsdWUgPSBzdHJYTUwuc2xpY2Uoc3RyWE1MLmluZGV4T2YoIj4iLCBzdHJYTUwuaW5kZXhPZigiPGJvZHkiKSkrMSxzdHJYTUwubGFzdEluZGV4T2YoIjwvYm9keT4iKSk7IC8vIGdldCBjb250ZW50cyB3aXRoaW4gPGJvZHk+IHRhZ3MKICAgICAgICAgICAgfQogICAgICAgICAgICBpZih0aGlzLmdldEF0dHJpYnV0ZSgiY29udGVudFR5cGUiKSA9PSAndGV4dC9odG1sJykgewogICAgICAgICAgICAgICAgaWYoZGlzcFZhbHVlLmluZGV4T2YoJzxzcGFuPicpICE9IDApIHsKICAgICAgICAgICAgICAgICAgICBkaXNwVmFsdWUgPSAnPHNwYW4+JyArIGRpc3BWYWx1ZSArICc8L3NwYW4+JzsgIC8vIGluIGNhc2Ugb2YgbXVsdGlwbGUgaHRtbCBlbGVtZW50cywgd3JhcCBpbiBhIHNwYW4sIGVsc2UgdGhleSBvdmVybGFwICEhCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmFyICRpbnRlcm5hbEhUTUwgPSAkKCc8c3Bhbj4nKyBkaXNwVmFsdWUgKyc8L3NwYW4+Jyk7CiAgICAgICAgICAgICAgICAkaW50ZXJuYWxIVE1MLmZpbmQoInAiKS5lcSgwKS5jc3MoJ2Rpc3BsYXknLCdpbmxpbmUnKTsKICAgICAgICAgICAgICAgIGRpc3BWYWx1ZSA9ICRpbnRlcm5hbEhUTUwuaHRtbCgpOyAgIC8vIGdldCB0aGUgaW5uZXIgaHRtbCB3aXRoIGFsbCBtYXJrdXBzCgogICAgICAgICAgICAgICAgdGhpcy5qc29uVmFsdWUgPSBkaXNwVmFsdWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBkaXNwVmFsdWUgPSAnPGJvZHk+JyArIGRpc3BWYWx1ZSArICc8L2JvZHk+JzsKICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSBkaXNwVmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgIH0pOwoKICAgIEV4RGF0YVZhbHVlLmRlZmluZVByb3BzKHsKICAgICAgICAianNvblZhbHVlIjogeyAgLy8gc2hvdWxkIHVzZSBpdCB0byBjaXJjdW12ZW50ICd0eXBlZFZhbHVlJywgd2hpY2ggc3RyaXBzIGh0bWwgdGFncwogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmpzb25Nb2RlbC5fdmFsdWU7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChzVmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmKF8uaXNOdWxsKHRoaXMuX29yaWdUbXBsdFZhbCkpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9vcmlnVG1wbHRWYWwgPSB0aGlzLmpzb25Nb2RlbC5fdmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLl9tb2RlbENoYW5nZWQgPSB0cnVlOyAgLy8ganVzdCB0byBiZSBjb25zaXN0ZW50ICYgc2FmZSB3aXRoICd2YWx1ZScKCiAgICAgICAgICAgICAgICBpZihzVmFsdWUgIT09IHRoaXMuanNvbk1vZGVsLl92YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLl92YWx1ZSA9IHNWYWx1ZTsKICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkRPTV9DSEFOR0VELCB0aGlzLCB0aGlzLmNsYXNzTmFtZSwgbnVsbCwgc1ZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZlbnQubmFtZSwgZXZlbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYiwgJCk7CgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5JbnRlZ2VyVmFsdWUKICogQGltcG9ydCAgeGZhbGliLnNjcmlwdC5Ob2RlVmFsdWUKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBJbnRlZ2VyVmFsdWUgPSB4ZmFsaWIuc2NyaXB0LkludGVnZXJWYWx1ZSA9IHhmYWxpYi5zY3JpcHQuTm9kZVZhbHVlLmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJpbnRlZ2VyIiwKICAgICAgICB0eXBlZFZhbHVlIDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIHZhciB0VmFsdWUgPSBJbnRlZ2VyVmFsdWUuX3N1cGVyLnR5cGVkVmFsdWUuY2FsbCh0aGlzLCB2YWwpOwogICAgICAgICAgICBpZiAodFZhbHVlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHRWYWx1ZSA9IHBhcnNlSW50KHRWYWx1ZSk7CiAgICAgICAgICAgICAgICBpZiAoaXNOYU4odFZhbHVlKSkKICAgICAgICAgICAgICAgICAgIHRWYWx1ZSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdFZhbHVlOwogICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5EZWNpbWFsVmFsdWUKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk5vZGVWYWx1ZQogKi8KCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIERlY2ltYWxWYWx1ZSA9IHhmYWxpYi5zY3JpcHQuRGVjaW1hbFZhbHVlID0geGZhbGliLnNjcmlwdC5Ob2RlVmFsdWUuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZTogImRlY2ltYWwiLAoKICAgICAgICB0eXBlZFZhbHVlIDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIHZhciB0VmFsdWUgPSBEZWNpbWFsVmFsdWUuX3N1cGVyLnR5cGVkVmFsdWUuY2FsbCh0aGlzLCB2YWwpOwogICAgICAgICAgICBpZiAodFZhbHVlKSB7CiAgICAgICAgICAgICAgICB0VmFsdWUgPSBwYXJzZUZsb2F0KHRWYWx1ZSk7CiAgICAgICAgICAgICAgICBpZiAoaXNOYU4odFZhbHVlKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgdmFyIHN0ciA9IHRWYWx1ZSArICcnOwogICAgICAgICAgICAgICAgdmFyIGxlbiA9IHN0ci5sZW5ndGg7CiAgICAgICAgICAgICAgICB2YXIgbGVhZEQgPSBzdHIuaW5kZXhPZigiLiIpOwogICAgICAgICAgICAgICAgdmFyIGZyYWNEID0gbGVuIC0gbGVhZEQgLSAxOwogICAgICAgICAgICAgICAgaWYoZnJhY0QgPiB0aGlzLmZyYWNEaWdpdHMgJiYgdGhpcy5mcmFjRGlnaXRzICE9IC0xKQogICAgICAgICAgICAgICAgICAgIHRWYWx1ZSA9IHBhcnNlRmxvYXQodFZhbHVlLnRvRml4ZWQodGhpcy5mcmFjRGlnaXRzKSk7CiAgICAgICAgICAgICAgICBpZihsZWFkRCA+IHRoaXMubGVhZERpZ2l0cyAmJiB0aGlzLmxlYWREaWdpdHMgIT0gLTEpCiAgICAgICAgICAgICAgICAgICAgdFZhbHVlID0gbnVsbDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdFZhbHVlOwogICAgICAgIH0KICAgIH0pOwoKICAgIERlY2ltYWxWYWx1ZS5kZWZpbmVQcm9wcyh7CiAgICAgICAgImZyYWNEaWdpdHMiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJmcmFjRGlnaXRzIikKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJsZWFkRGlnaXRzIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGVhZERpZ2l0cyIpCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKfSkoXywgeGZhbGliKTsKCgovKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LkZsb2F0VmFsdWUKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk5vZGVWYWx1ZQogKi8KICAKCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIEZsb2F0VmFsdWUgPSB4ZmFsaWIuc2NyaXB0LkZsb2F0VmFsdWUgPSB4ZmFsaWIuc2NyaXB0Lk5vZGVWYWx1ZS5leHRlbmQoewoKICAgICAgICBtc0NsYXNzTmFtZTogImZsb2F0IiwKICAgICAgICB0eXBlZFZhbHVlIDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIHZhciB0VmFsdWUgPSBGbG9hdFZhbHVlLl9zdXBlci50eXBlZFZhbHVlLmNhbGwodGhpcywgdmFsKTsKICAgICAgICAgICAgaWYgKHRWYWx1ZSkgewogICAgICAgICAgICAgICAgdFZhbHVlID0gcGFyc2VGbG9hdCh0VmFsdWUpOwogICAgICAgICAgICAgICAgaWYgKGlzTmFOKHRWYWx1ZSkpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0VmFsdWU7CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYik7LyoKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5EYXRlVmFsdWUKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk5vZGVWYWx1ZQogKi8KCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBEYXRlVmFsdWUgPSB4ZmFsaWIuc2NyaXB0LkRhdGVWYWx1ZSA9IHhmYWxpYi5zY3JpcHQuTm9kZVZhbHVlLmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJkYXRlIiwKICAgICAgICB0eXBlZFZhbHVlIDogZnVuY3Rpb24odmFsKSB7CiAgICAgICAgICAgIHZhciB0VmFsdWUgPSBEYXRlVmFsdWUuX3N1cGVyLnR5cGVkVmFsdWUuY2FsbCh0aGlzLCB2YWwpOwogICAgICAgICAgICBpZiAodFZhbHVlKSB7CiAgICAgICAgICAgICAgICB2YXIgdFZhbHVlUGFyc2VkID0geGZhbGliLnV0LkRhdGVJbmZvLlBhcnNlKHRWYWx1ZSwgdW5kZWZpbmVkLCBmYWxzZSk7CiAgICAgICAgICAgICAgICBpZiAodFZhbHVlUGFyc2VkICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdFZhbHVlUGFyc2VkID0gdFZhbHVlUGFyc2VkLmdldElTT0RhdGUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIGlmIHZhbHVlIGlzIG5vdCBjb3JyZWN0bHkgcGFyc2VkIHRoZW4gcmV0dXJuIHRoZSBvcmlnaW5hbCB2YWx1ZQogICAgICAgICAgICAgICAgcmV0dXJuIHRWYWx1ZVBhcnNlZCA/IHRWYWx1ZVBhcnNlZCA6IHRWYWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdFZhbHVlOwogICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIpOy8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LkZvcm0KICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LkNvbnRhaW5lck5vZGUKICovCgooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgLyoqCiAgICAgKiBAY2xhc3MKICAgICAqIDxwPgogICAgICogVGhlIEZvcm0gY2xhc3MgaXMgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoZSB0b3AgbGV2ZWwgWEZBIGZvcm0gb2JqZWN0LgogICAgICogPC9wPgogICAgICoKICAgICAqIDxwPgogICAgICogVGhlIGZvcm0gb2JqZWN0IGlzIGFjY2Vzc2VkIGZyb20gdGhlIHhmYSBvYmplY3QgYXMgeGZhLmZvcm0KICAgICAqIDwvcD4KICAgICAqCiAgICAgKi8KICAgIHZhciBEYXRhTm9kZSA9IHhmYWxpYi5zY3JpcHQuRGF0YU5vZGUgPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLnZhbHVlID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5maWVsZHMgPSBbXTsKICAgICAgICB9LAoKICAgICAgICBnZXRJZCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuanNvbk1vZGVsLmlkOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIHdpbGwgc3luYyBmaWVsZHMgaGF2aW5nIHNhbWUgZGF0YUlkIChzYW1lIGJpbmRyZWYgb3IgdXNlIGdsb2JhbCkKICAgICAgICAgKiBAcGFyYW0gbW9kZWwKICAgICAgICAgKi8KICAgICAgICBhZGRGaWVsZCA6IGZ1bmN0aW9uIChtb2RlbCkgewogICAgICAgICAgICBpZiAodGhpcy5maWVsZHMubGVuZ3RoID09PSAwICYmIG1vZGVsLnJhd1ZhbHVlICE9IG51bGwpIHsgLy8gbG9vc2UgY2hlY2sgZm9yIG51bGwvdW5kZWYKICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLnZhbHVlID0gbW9kZWwucmF3VmFsdWU7IC8vIGluaXRpYWxpemUgZGF0YU5vZGUgZ3JvdXAncyB2YWx1ZSB0byAxc3QgaGllcmFyY2hpY2FsbHkgcmVhY2hlZCBmaWVsZAogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbW9kZWwucmF3VmFsdWUgPSB0aGlzLmpzb25Nb2RlbC52YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLmZpZWxkcy5wdXNoKG1vZGVsKTsKICAgICAgICAgICAgbW9kZWwub24oeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwgdGhpcyk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRXZlbnQgOiBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICBzd2l0Y2ggKGV2bnQubmFtZSkgewogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VEOgogICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlTW9kZWxDaGFuZ2VkKGV2bnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmRlYnVnKCJ4ZmEiLCAnVW5leHBlY3RlZCAgRXZlbnQgICJ7MH0iIHRocm93biBpbiBkYXRhTm9kZSB3aXRoIGlkIDogInsxfSIgJywgW2V2bnQubmFtZSwgdGhpcy5qc29uTW9kZWwuaWRdKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGhhbmRsZU1vZGVsQ2hhbmdlZCA6IGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICBpZiAoZXZlbnQuX3Byb3BlcnR5ID09PSAicmF3VmFsdWUiKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVWYWx1ZUNoYW5nZShldmVudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlVmFsdWVDaGFuZ2UgOiBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgdGhpcy5fdXBkYXRlTGlua2VkRmllbGRzVmFsdWUoZXZlbnQucHJldlRleHQsIGV2ZW50LnRhcmdldCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogd2lsbCB1cGRhdGUgYWxsIGxpbmtlZCBmaWVsZHMgdG8gdGhlIG5ldyB2YWx1ZSBwYXNzZWQgaW4KICAgICAgICAgKiBAcGFyYW0gbmV3VmFsdWUKICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0CiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAbWVtYmVyb2YgRGF0YU5vZGUKICAgICAgICAgKi8KICAgICAgICBfdXBkYXRlTGlua2VkRmllbGRzVmFsdWUgOiBmdW5jdGlvbiAobmV3VmFsdWUsIHRhcmdldCkgewogICAgICAgICAgICBpZiAobmV3VmFsdWUgIT09IHVuZGVmaW5lZCAmJiBuZXdWYWx1ZSAhPSB0aGlzLmpzb25Nb2RlbC52YWx1ZSkgeyAvLyBsb29zZSB0eXBlIGNvZXJjaW9uIGhlcmUgZm9yIGludC9zdHIKICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLnZhbHVlID0gbmV3VmFsdWU7CgogICAgICAgICAgICAgICAgXy5lYWNoKHRoaXMuZmllbGRzLCBmdW5jdGlvbiAoZmllbGQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZmllbGQgIT09IHRhcmdldCkgewogICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC5vZmYoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwgdGhpcyk7IC8vIHJlbW92ZSBsaXN0ZW5lcnMgdG8gcHJldmVudCBldmVudCB0aHJvdyBzdG9ybQogICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC5yYXdWYWx1ZSA9IG5ld1ZhbHVlOwogICAgICAgICAgICAgICAgICAgICAgICBmaWVsZC5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELCB0aGlzKTsgLy8gcmUgYXR0YWNoIGxpc3RlbmVycwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYik7Ci8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LkV4ZWN1dGFibGVTY3JpcHQKICogQGltcG9ydCB4ZmFsaWIudXQuQ2xhc3MKICovCgoKKGZ1bmN0aW9uKF8sIHhmYWxpYil7CiAgICB2YXIgRXhlY3V0YWJsZVNjcmlwdCA9IHhmYWxpYi5zY3JpcHQuRXhlY3V0YWJsZVNjcmlwdCA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewogICAgICAgIF9kZWZhdWx0cyA6IHsKICAgICAgICAgICAgInJ1bkF0IiA6ICJjbGllbnQiCiAgICAgICAgfSwKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIEV4ZWN1dGFibGVTY3JpcHQuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgdGhpcy5fc2NyaXB0Rm4gPSBudWxsOwogICAgICAgIH0sCgogICAgICAgIGV4ZWN1dGUgOiBmdW5jdGlvbihjb250ZXh0T2JqLCBldmVudE5hbWUpIHsKICAgICAgICAgICAgLy8gQWNjb3JkaW5nIHRvIFhGQSBTUEVDIDogSWYgdGhlIHByZXN1Ym1pdCBzY3JpcHQgaXMgbWFya2VkIHRvIGJlIHJ1biBvbmx5IGF0IHRoZSBzZXJ2ZXIsIHRoZSBkYXRhIGlzIHNlbnQgdG8gdGhlIHNlcnZlciB3aXRoIGFuCiAgICAgICAgICAgIC8vIGluZGljYXRpb24gdGhhdCBpdCBzaG91bGQgcnVuIHRoZSBhc3NvY2lhdGVkIHNjcmlwdCBiZWZvcmUgcGVyZm9ybWluZyB0aGUgcmVzdCBvZiB0aGUgcHJvY2Vzc2luZy4gQ2xpZW50IHNpZGUgc2NyaXB0IGZvciBwcmVzdWJtaXQKICAgICAgICAgICAgLy8gYXJlIGV4ZWN1dGVkIGJlZm9yZSBydW5uaW5nIHZhbGlkYXRpb24uCiAgICAgICAgICAgIGlmKHRoaXMucnVuQXQgPT0gInNlcnZlciIgJiYgZXZlbnROYW1lICE9ICIkZm9ybXByZVN1Ym1pdCIpIHsKICAgICAgICAgICAgICAgIHZhciBvcHRpb25zID0ge307CiAgICAgICAgICAgICAgICBvcHRpb25zLmFjdGl2aXR5ID0gdGhpcy54ZmFVdGlsKCkuX3h0Z0V2ZW50TmFtZVtldmVudE5hbWVdID8gdGhpcy54ZmFVdGlsKCkuX3h0Z0V2ZW50TmFtZVtldmVudE5hbWVdIDogZXZlbnROYW1lOwogICAgICAgICAgICAgICAgb3B0aW9ucy5jb250ZXh0U29tID0gY29udGV4dE9iai5zb21FeHByZXNzaW9uOwogICAgICAgICAgICAgICAgY29udGV4dE9iai5feGZhKCkuaG9zdC5ydW5TZXJ2ZXJTY3JpcHQob3B0aW9ucyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXhlY3V0ZUxvY2FsKGNvbnRleHRPYmosIGV2ZW50TmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZXhlY3V0ZUxvY2FsIDogIGZ1bmN0aW9uKGNvbnRleHRPYmosIGV2ZW50TmFtZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdGhpcy5zY3JpcHQuY2FsbChjb250ZXh0T2JqKTsgICAgICAvLyBUT0RPIDogVGhlIGJlc3Qgd2F5IHdpbGwgYmUgdG8gdXNlIGB3aXRoYCBzbyB0aGF0IGV2YWwgY2FuIGFsc28gYmUgdXNlZCB3aXRob3V0IG1vZGlmeWluZyBhbnl0aGluZwogICAgICAgICAgICB9IGNhdGNoKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgY29udGV4dE9iai5feGZhKCkuTG9nZ2VyLmVycm9yKCJ4ZmEiLCB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDIiXSxbZXZlbnROYW1lLCBjb250ZXh0T2JqLnNvbUV4cHJlc3Npb24sZXhjZXB0aW9uLm1lc3NhZ2VdKQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgfQoKICAgIH0pOwoKICAgIEV4ZWN1dGFibGVTY3JpcHQuZGVmaW5lUHJvcHMoewogICAgICAgICJydW5BdCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwucnVuQXQsIHRoaXMuX2RlZmF1bHRzLnJ1bkF0KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJzY3JpcHQiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMuX3NjcmlwdEZuID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgc2NyaXB0Q29udGVudCA9IHRoaXMuanNvbk1vZGVsLl92YWx1ZTsKICAgICAgICAgICAgICAgICAgICB0cnl7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50ID0gIndpdGgodGhpcykge1xuXG4gd2l0aCh4ZmFsaWIucnVudGltZSkge1xuXG4iICsgc2NyaXB0Q29udGVudCArICJcblxufVxuXG4gfSI7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NjcmlwdEZuID0gbmV3IEZ1bmN0aW9uKGNvbnRlbnQpOwogICAgICAgICAgICAgICAgICAgIH1jYXRjaChleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5lcnJvcigieGZhIiwgeGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDA1Il0sW2V4Y2VwdGlvbi5tZXNzYWdlLHNjcmlwdENvbnRlbnRdKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2NyaXB0Rm4gPSBuZXcgRnVuY3Rpb24oIiIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9zY3JpcHRGbjsKICAgICAgICAgICAgfQogICAgICAgIH0KCgogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuVmFsaWRhdGVTY3JpcHQKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LkV4ZWN1dGFibGVTY3JpcHQKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBWYWxpZGF0ZVNjcmlwdCA9IHhmYWxpYi5zY3JpcHQuVmFsaWRhdGVTY3JpcHQgPSB4ZmFsaWIuc2NyaXB0LkV4ZWN1dGFibGVTY3JpcHQuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBWYWxpZGF0ZVNjcmlwdC5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIGV2YWxTY3JpcHQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgd2l0aCh0aGlzKXsKICAgICAgICAgICAgICAgIHdpdGgoeGZhbGliLnJ1bnRpbWUpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgX19YRkFfZXZhbFZhbGlkYXRlU2NyaXB0UmV0VmFsX18gPSBldmFsKGFyZ3VtZW50c1swXSk7IC8vIExDLTczMTkgOiB2YXJpYWJsZSBuYW1lcyBwYXNzZWQgaW4gJ2V2YWwnIGFyZSBvdmVycmlkZGVuIGR1ZSB0byBlbmNsb3NpbmcgJ3dpdGgnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIF9fWEZBX2V2YWxWYWxpZGF0ZVNjcmlwdFJldFZhbF9fOwogICAgICAgIH0sCgogICAgICAgIF9leGVjdXRlTG9jYWwgOiAgZnVuY3Rpb24oY29udGV4dE9iaiwgZXZlbnROYW1lKSB7CiAgICAgICAgICAgIHZhciByVmFsdWUgPSB0cnVlOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgaWYodGhpcy5zY3JpcHQpCiAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdGhpcy5ldmFsU2NyaXB0LmNhbGwoY29udGV4dE9iaix0aGlzLnNjcmlwdCk7CiAgICAgICAgICAgICAgICBpZighclZhbHVlKQogICAgICAgICAgICAgICAgICAgIGNvbnRleHRPYmouX3hmYSgpLkxvZ2dlci5kZWJ1ZygieGZhIiwgeGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDE0Il0sW2NvbnRleHRPYmouc29tRXhwcmVzc2lvbix0aGlzLnNjcmlwdF0pCiAgICAgICAgICAgIH0gY2F0Y2goZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICBjb250ZXh0T2JqLl94ZmEoKS5Mb2dnZXIuZXJyb3IoInhmYSIsIHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAwMiJdLFtldmVudE5hbWUsIGNvbnRleHRPYmouc29tRXhwcmVzc2lvbixleGNlcHRpb24ubWVzc2FnZV0pCiAgICAgICAgICAgICAgICByVmFsdWUgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByVmFsdWU7CiAgICAgICAgfQoKICAgIH0pOwoKICAgIFZhbGlkYXRlU2NyaXB0LmRlZmluZVByb3BzKHsKICAgICAgICAic2NyaXB0IiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5qc29uTW9kZWwuX3ZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5DYWxjdWxhdGVTY3JpcHQKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LlZhbGlkYXRlU2NyaXB0CiAqLwooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBDYWxjdWxhdGVTY3JpcHQgPSB4ZmFsaWIuc2NyaXB0LkNhbGN1bGF0ZVNjcmlwdCA9IHhmYWxpYi5zY3JpcHQuVmFsaWRhdGVTY3JpcHQuZXh0ZW5kKHsKCiAgICAgICAgX2V4ZWN1dGVMb2NhbCA6ICBmdW5jdGlvbihjb250ZXh0T2JqLCBldmVudE5hbWUpIHsKICAgICAgICAgICAgdmFyIHJWYWx1ZSA7CiAgICAgICAgICAgIGlmKHRoaXMuc2NyaXB0KXsKICAgICAgICAgICAgICAgIC8vIHByZV9wcm9jZXNzCiAgICAgICAgICAgICAgICBjb250ZXh0T2JqLl94ZmEoKS5fcHVzaENhbGN1bGF0ZUV2ZW50Tm9kZShjb250ZXh0T2JqKTsKCiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGNvbnRleHRPYmoucmF3VmFsdWUgPSB0aGlzLmV2YWxTY3JpcHQuY2FsbChjb250ZXh0T2JqLHRoaXMuc2NyaXB0KQogICAgICAgICAgICAgICAgfSBjYXRjaChleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICBjb250ZXh0T2JqLl94ZmEoKS5Mb2dnZXIuZXJyb3IoInhmYSIsIHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAwMiJdLFtldmVudE5hbWUsIGNvbnRleHRPYmouc29tRXhwcmVzc2lvbixleGNlcHRpb24ubWVzc2FnZV0pCiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gcG9zdF9wcm9jZXNzCiAgICAgICAgICAgICAgICBjb250ZXh0T2JqLl94ZmEoKS5fcG9wQ2FsY3VsYXRlRXZlbnROb2RlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJWYWx1ZTsKICAgICAgICB9CgogICAgfSk7Cn0pKF8sIHhmYWxpYik7Ci8qKgogKiBDcmVhdGVkIHdpdGggSW50ZWxsaUogSURFQS4KICogVXNlcjogcnBhbmRleQogKiBEYXRlOiAxMS8yNy8xMwogKiBUaW1lOiAxMDoyNiBBTQogKi8KLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuRmxvYXRpbmdGaWVsZFNjcmlwdAogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuQ2FsY3VsYXRlU2NyaXB0CiAqLwooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBGbG9hdGluZ0ZpZWxkU2NyaXB0ID0geGZhbGliLnNjcmlwdC5GbG9hdGluZ0ZpZWxkU2NyaXB0ID0geGZhbGliLnNjcmlwdC5DYWxjdWxhdGVTY3JpcHQuZXh0ZW5kKHsKICAgICAgICAvL0RvIHdlIHJlYWxseSBuZWVkIG5ldyBjbGFzcyBmb3IgRmxvYXRpbmdGaWVsZFNjcmlwdCBqdXN0IGZvciBhIGRpZmZlcmVudCBlcnJvciBtZXNzYWdlIGFuZCBhIGRpZmZlcmVudCBzY3JpcHQKCiAgICAgICAgX2V4ZWN1dGVMb2NhbCA6ICBmdW5jdGlvbihjb250ZXh0T2JqLCBldmVudE5hbWUpIHsKICAgICAgICAgICAgaWYoY29udGV4dE9iai5fcmVzb2x2ZUZsb2F0aW5nRmllbGQpewogICAgICAgICAgICAgICAgLy8gcHJlX3Byb2Nlc3MKICAgICAgICAgICAgICAgIGNvbnRleHRPYmouX3hmYSgpLl9wdXNoQ2FsY3VsYXRlRXZlbnROb2RlKGNvbnRleHRPYmopOwoKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgLy9DYWxsIF9yZXNvbHZlRmxvYXRpbmdGaWVsZCBpbiB0aGlzIGNvbnRleHQKICAgICAgICAgICAgICAgICAgICAvL3RoaXMgaGFyZC1jb2RpbmcgZGVjb3VwbGVzIHRoZSBzZXJ2ZXIgZnJvbSBzY3JpcHQgZnVuY3Rpb24gbmFtZS4uLgogICAgICAgICAgICAgICAgICAgIC8vTm93IGl0IGlzIG9ubHkgYXQgdGhlIGNsaWVudCBzaWRlIHdlIGtlZXAgdGhlIG5hbWUgb2YgZmxvYXRpbmcgZmllbGRzIHJlc29sdmVyIHNjcmlwdAogICAgICAgICAgICAgICAgICAgIHRoaXMuZXZhbFNjcmlwdC5jYWxsKGNvbnRleHRPYmosICdfcmVzb2x2ZUZsb2F0aW5nRmllbGQoKScpOwogICAgICAgICAgICAgICAgfSBjYXRjaChleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgICAgICBjb250ZXh0T2JqLl94ZmEoKS5Mb2dnZXIuZXJyb3IoInhmYSIsIHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAxOSJdLFtjb250ZXh0T2JqLnNvbUV4cHJlc3Npb25dKQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIHBvc3RfcHJvY2VzcwogICAgICAgICAgICAgICAgY29udGV4dE9iai5feGZhKCkuX3BvcENhbGN1bGF0ZUV2ZW50Tm9kZSgpOwoKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICB9CgogICAgfSk7Cn0pKF8sIHhmYWxpYik7Ci8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LlN1Ym1pdAogKiBAaW1wb3J0IHhmYWxpYi51dC5DbGFzcwogKi8KCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIFN1Ym1pdCA9IHhmYWxpYi5zY3JpcHQuU3VibWl0ID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgU3VibWl0Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY3V0ZSA6IGZ1bmN0aW9uKG9iaiwgZXZlbnROYW1lKSB7CiAgICAgICAgICAgIHZhciBvcHRpb25zID0ge307CiAgICAgICAgICAgIGlmKHRoaXMudGFyZ2V0KQogICAgICAgICAgICAgICAgb3B0aW9ucy5hY3Rpb24gPSB0aGlzLnRhcmdldDsKICAgICAgICAgICAgb3B0aW9ucy5mb3JtYXQgPSB0aGlzLmZvcm1hdDsKICAgICAgICAgICAgb3B0aW9ucy50ZXh0RW5jb2RpbmcgPSB0aGlzLnRleHRFbmNvZGluZzsKCiAgICAgICAgICAgIGZvcm1CcmlkZ2Uuc3VibWl0Rm9ybShvcHRpb25zKTsgLy9UT0RPOiByZW1vdmUgZGlyZWN0IGRlcGVuZGVuY3kgb24gRm9ybUJyaWRnZQogICAgICAgIH0KCiAgICB9KTsKCiAgICBTdWJtaXQuZGVmaW5lUHJvcHMoewogICAgICAgIGZvcm1hdCA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5mb3JtYXQsIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgdGFyZ2V0IDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JFbHNlKHRoaXMuanNvbk1vZGVsLnRhcmdldCwgbnVsbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICB0ZXh0RW5jb2RpbmcgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwudGV4dEVuY29kaW5nLCBudWxsKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKfSkoXywgeGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuRmllbGQKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk5vZGUKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBGaWVsZCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3IEZpZWxkIGNsYXNzCiAgICAgKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgRmllbGQKICAgICAqIEBwYXJhbSB7c3RyaW5nfQogICAgICogICAgICAgICAgICByYXdWYWwgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgRmllbGQKICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByYXdWYWwgcmVwcmVzZW50cyB0aGUgZGF0YSB2YWx1ZSBpbiB0aGUgbm9kZQogICAgICogQGV4dGVuZHMgeGZhbGliLnNjcmlwdC5Ob2RlCiAgICAgKi8KICAgIHZhciBGaWVsZCA9IHhmYWxpYi5zY3JpcHQuRmllbGQgPSB4ZmFsaWIuc2NyaXB0LkV2ZW50Q29udGFpbmVyTm9kZS5leHRlbmQoewogICAgICAgIF9kZWZhdWx0czogewogICAgICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICAgICAic2F2ZSI6ICIwIgogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgIl9kZWZhdWx0IjogInJhd1ZhbHVlIiwKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIEZpZWxkLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsWyJ7ZGVmYXVsdH0iXSA9IHRoaXMuX2dldFZhbHVlKCk7CiAgICAgICAgICAgIHRoaXMudGVzdHMgPSBbdGhpcy5fbnVsbFRlc3QsIHRoaXMuX2Zvcm1hdFRlc3QsIHRoaXMuX3NjcmlwdFRlc3RdOwogICAgICAgICAgICBpZiAodGhpcy5qc29uTW9kZWwuZXh0cmFzICYmIHRoaXMuanNvbk1vZGVsLmV4dHJhcy5kYXRhSWQpCiAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5jcmVhdGVEYXRhTm9kZSh0aGlzLmpzb25Nb2RlbC5leHRyYXMuZGF0YUlkLCB0aGlzKTsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm1vQ2hpbGROb2Rlcy5sZW5ndGg7ICsraSkgewogICAgICAgICAgICAgICAgdmFyIG9Ob2RlID0gdGhpcy5tb0NoaWxkTm9kZXNbaV07CiAgICAgICAgICAgICAgICBvTm9kZS5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQsIHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLmpzb25Nb2RlbC5pZCkgewogICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuTG9nZ2VyLmRlYnVnKCJ4ZmEiLCAiQWRkZWQgZmllbGQgd2l0aCBpZCA6IiArIHRoaXMuanNvbk1vZGVsLmlkKQogICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuX3hmYVRlbXBsYXRlQ2FjaGUuaWRNYXBbdGhpcy5qc29uTW9kZWwuaWRdID0gdGhpczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy5lZGl0UGF0dGVybiA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMuanNvbk1vZGVsLCAiZXh0cmFzLmVkaXRQYXR0ZXJuRXgiLCBudWxsKTsKICAgICAgICB9LAoKICAgICAgICBwbGF5SnNvbjogZnVuY3Rpb24gKHBKc29uTW9kZWwpIHsKICAgICAgICAgICAgRmllbGQuX3N1cGVyLnBsYXlKc29uLmNhbGwodGhpcywgcEpzb25Nb2RlbCk7CgogICAgICAgICAgICAvLyB1cGRhdGUgZGF0YSBub2RlIGNhY2hlZCB2YWx1ZQogICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELCB0aGlzLAogICAgICAgICAgICAgICAgJ3Jhd1ZhbHVlJywgdGhpcy5yYXdWYWx1ZSwgdGhpcy5mb3JtYXR0ZWRWYWx1ZSk7CiAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsIGV2bnQpOwogICAgICAgIH0sCgogICAgICAgIF9zZXRQYXR0ZXJuOiBmdW5jdGlvbiAodHlwZSwgcGF0dGVybnMsIGNhbGxiYWNrKSB7CiAgICAgICAgICAgIGlmIChwYXR0ZXJucyAmJiBwYXR0ZXJucy5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLmV4dHJhcyA9IHRoaXMuanNvbk1vZGVsLmV4dHJhcyB8fCB7fTsKICAgICAgICAgICAgICAgIF8uZWFjaChwYXR0ZXJucywgZnVuY3Rpb24gKHBhdHRlcm4sIGkpIHsKICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuLmxvY2FsZSA9IHBhdHRlcm4ubG9jYWxlIHx8IHRoaXMubG9jYWxlCiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLmV4dHJhc1t0eXBlXSA9IHBhdHRlcm5zOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZURvbUV2ZW50OiBmdW5jdGlvbiAoZXZudCkgewogICAgICAgICAgICBzd2l0Y2ggKGV2bnQuX3Byb3BlcnR5KSB7CiAgICAgICAgICAgICAgICBjYXNlICJmb3JtYXQucGljdHVyZSI6CiAgICAgICAgICAgICAgICAgICAgdmFyIHJlcyA9IHRoaXMuX3NldFBhdHRlcm4oImRpc3BsYXlQYXR0ZXJuRXgiLAogICAgICAgICAgICAgICAgICAgICAgICB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLnBhcnNlUGljdHVyZUNsYXVzZShldm50Lm5ld1RleHQpKTsKICAgICAgICAgICAgICAgICAgICBpZiAocmVzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Nob3dEaXNwbGF5Rm9ybWF0KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAidmFsaWRhdGUucGljdHVyZSI6CiAgICAgICAgICAgICAgICAgICAgdmFyIHJlcyA9IHRoaXMuX3NldFBhdHRlcm4oInZhbGlkYXRlUGF0dGVybkV4IiwKICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnV0LlBpY3R1cmVVdGlscy5wYXJzZVBpY3R1cmVDbGF1c2UoZXZudC5uZXdUZXh0KSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlcykgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWxpZGF0ZShbXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB4ZmFsaWIuc2NyaXB0LkV2ZW50Q29udGFpbmVyTm9kZS5wcm90b3R5cGUuaGFuZGxlRG9tRXZlbnQuYXBwbHkodGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHNhdmVYTUw6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMucmF3VmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgbG9hZFhNTDogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAvL3RoaXMucmF3VmFsdWUgPSB2YWw7CiAgICAgICAgfSwKCgogICAgICAgIGFkZEl0ZW06IGZ1bmN0aW9uIChzRGlzcGxheVZhbCwgc1NhdmVWYWwpIHsKICAgICAgICAgICAgLy9jYWxsIF9nZXREaXNwbGF5SXRlbXMgYmVmb3JlIHNhdmluZyBhbnkgU2F2ZUl0ZW1zLgogICAgICAgICAgICB2YXIgc0l0ZW1zID0gdGhpcy5fZ2V0U2F2ZUl0ZW1zKHRydWUpOwogICAgICAgICAgICB2YXIgZEl0ZW1zID0gdGhpcy5fZ2V0RGlzcGxheUl0ZW1zKHRydWUpOwoKICAgICAgICAgICAgdmFyIHNhdmVJdGVtID0gewogICAgICAgICAgICAgICAgIl9jbGFzcyI6ICJ0ZXh0IiwKICAgICAgICAgICAgICAgICJfdmFsdWUiOiBzU2F2ZVZhbCA9PT0gdW5kZWZpbmVkID8gc0Rpc3BsYXlWYWwgOiBzU2F2ZVZhbAogICAgICAgICAgICB9OwoKICAgICAgICAgICAgc0l0ZW1zLl9hZGRDaGlsZCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZU1vZGVsKHNhdmVJdGVtKSk7CgogICAgICAgICAgICB2YXIgZGlzcGxheUl0ZW0gPSB7CiAgICAgICAgICAgICAgICAiX2NsYXNzIjogInRleHQiLAogICAgICAgICAgICAgICAgIl92YWx1ZSI6IHNEaXNwbGF5VmFsCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBkSXRlbXMuX2FkZENoaWxkKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlTW9kZWwoZGlzcGxheUl0ZW0pKTsKCiAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsCiAgICAgICAgICAgICAgICB0aGlzLCAiYWRkSXRlbSIsIHNhdmVJdGVtLl92YWx1ZSwgZGlzcGxheUl0ZW0uX3ZhbHVlKTsKICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSwgZXZudCk7CiAgICAgICAgfSwKCiAgICAgICAgX3NwbGl0U3RyaW5nV2l0aEVzY2FwZWRDb21tYXM6IGZ1bmN0aW9uIChzdHJpbmcpIHsKICAgICAgICAgICAgdmFyIGFyciA9IFtdOwogICAgICAgICAgICB2YXIgc3RhcnQgPSAwOwogICAgICAgICAgICAvLyBhIG5lZ2F0aXZlIGxvb2t1cCB3YXMgYXZvaWRlZCBhcyBpdCdzIG5vdCBzdXBwb3J0ZWQgaW4gcmhpbm8gYW5kIElFIDExCiAgICAgICAgICAgIGZvcih2YXIgaSA9IDAgOyBpIDwgc3RyaW5nLmxlbmd0aCA7IGkrKyApewogICAgICAgICAgICAgICAgaWYoc3RyaW5nW2ldID09PSAnLCcgJiYgc3RyaW5nW2ktMV0hPT0gJ1xcJyApLy8gaS0xIGlzIHNhZmUgYmVjYXVzZSB0aGUgY29tbWFzIGFyZSBhbHJlYWR5IGRlbGltaXRlZAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFyci5wdXNoKHN0cmluZy5zdWJzdHJpbmcoc3RhcnQsIGkpLnJlcGxhY2UoL1xcLC9nLCAnLCcpKTsKICAgICAgICAgICAgICAgICAgICBzdGFydCA9IGkgKyAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGFyci5wdXNoKHN0cmluZy5zdWJzdHJpbmcoc3RhcnQpLnJlcGxhY2UoL1xcLC9nLCAnLCcpKTsKICAgICAgICAgICAgcmV0dXJuIGFycjsKICAgICAgICB9LAoKICAgICAgICBzZXRJdGVtczogZnVuY3Rpb24gKHN0cmluZywgcGFpcikgewogICAgICAgICAgICBwYWlyID0gcGFpciA9PT0gdW5kZWZpbmVkID8gMSA6IHBhaXI7CiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgdmFyIHZhbCA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuY2xlYXJJdGVtcygpOwogICAgICAgICAgICB2YXIgYXJyYXkgPSBudWxsOwogICAgICAgICAgICBpZihzdHJpbmcuaW5kZXhPZignXFwsJykgPiAtMSl7CiAgICAgICAgICAgICAgICBhcnJheSA9IHRoaXMuX3NwbGl0U3RyaW5nV2l0aEVzY2FwZWRDb21tYXMoc3RyaW5nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGFycmF5ID0gc3RyaW5nLnNwbGl0KCcsJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHBhaXIgPT0gMikgewogICAgICAgICAgICAgICAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbiAoZW50cnksIGluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ICUgMiA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuYWRkSXRlbShlbGVtLCBlbnRyeSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbCA9IGVudHJ5OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0gPSBlbnRyeTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgaWYgKGFycmF5Lmxlbmd0aCAlIDIpCiAgICAgICAgICAgICAgICAgICAgdGhhdC5hZGRJdGVtKGVsZW0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHBhaXIgPT0gMSkgewogICAgICAgICAgICAgICAgYXJyYXkuZm9yRWFjaChmdW5jdGlvbiAoZW50cnkpIHsKICAgICAgICAgICAgICAgICAgICB0aGF0LmFkZEl0ZW0oZW50cnkpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChwYWlyID4gMikKICAgICAgICAgICAgICAgIHJldHVybiAgZmFsc2U7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9LAoKICAgICAgICBjbGVhckl0ZW1zOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBzSXRlbXMgPSB0aGlzLl9nZXRTYXZlSXRlbXMoZmFsc2UpOwogICAgICAgICAgICB2YXIgZEl0ZW1zID0gdGhpcy5fZ2V0RGlzcGxheUl0ZW1zKGZhbHNlKTsKICAgICAgICAgICAgaWYgKHNJdGVtcykKICAgICAgICAgICAgICAgIHNJdGVtcy5fcmVtb3ZlQWxsKCk7CiAgICAgICAgICAgIGlmIChkSXRlbXMpCiAgICAgICAgICAgICAgICBkSXRlbXMuX3JlbW92ZUFsbCgpOwogICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELAogICAgICAgICAgICAgICAgdGhpcywgImNsZWFySXRlbXMiLCBudWxsLCBudWxsKTsKICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSwgZXZudCk7CiAgICAgICAgfSwKCiAgICAgICAgYm91bmRJdGVtOiBmdW5jdGlvbiAoc0Rpc3BsYXlWYWwpIHsKICAgICAgICAgICAgdmFyIGRJdGVtcyA9IHRoaXMuX2dldERpc3BsYXlJdGVtcyhmYWxzZSk7CiAgICAgICAgICAgIHZhciBzYXZlVmFsdWUgPSBudWxsOwogICAgICAgICAgICBfLmZpbmQoZEl0ZW1zID8gZEl0ZW1zLmNoaWxkcmVuIDogW10sCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoaXRlbSwgaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbS52YWx1ZSA9PSBzRGlzcGxheVZhbCkgewogICAgICAgICAgICAgICAgICAgICAgICBzYXZlVmFsdWUgPSB0aGlzLmdldFNhdmVJdGVtKGluZGV4KTsgLy9UaGlzIHNob3VsZCBhbHdheXMgYmUgcHJlc2VudAogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9LCB0aGlzCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybiBzYXZlVmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RGlzcGxheUl0ZW06IGZ1bmN0aW9uIChuSW5kZXgpIHsKICAgICAgICAgICAgdmFyIGRJdGVtcyA9IHRoaXMuX2dldERpc3BsYXlJdGVtcyh0cnVlKTsKICAgICAgICAgICAgaWYgKG5JbmRleCA+PSAwICYmIGRJdGVtcyAmJiBkSXRlbXMuY2hpbGRyZW4ubGVuZ3RoID4gbkluZGV4KQogICAgICAgICAgICAgICAgcmV0dXJuIGRJdGVtcy5tb0NoaWxkTm9kZXNbbkluZGV4XS52YWx1ZTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsgLy9Eb24ndCBjaGFuZ2UKICAgICAgICB9LAoKICAgICAgICBnZXRTYXZlSXRlbTogZnVuY3Rpb24gKG5JbmRleCkgewogICAgICAgICAgICB2YXIgc0l0ZW1zID0gdGhpcy5fZ2V0U2F2ZUl0ZW1zKHRydWUpOwogICAgICAgICAgICBpZiAobkluZGV4ID49IDAgJiYgc0l0ZW1zICYmIHNJdGVtcy5jaGlsZHJlbi5sZW5ndGggPiBuSW5kZXgpCiAgICAgICAgICAgICAgICByZXR1cm4gc0l0ZW1zLm1vQ2hpbGROb2Rlc1tuSW5kZXhdLnZhbHVlOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkOyAvL0Rvbid0IGNoYW5nZQogICAgICAgIH0sCgogICAgICAgIGdldEl0ZW1TdGF0ZTogZnVuY3Rpb24gKG5JbmRleCkgewogICAgICAgICAgICB2YXIgaXRlbVZhbHVlID0gdGhpcy5nZXRPckVsc2UodGhpcy5nZXRTYXZlSXRlbShuSW5kZXgpLCB0aGlzLmdldERpc3BsYXlJdGVtKG5JbmRleCkpOwogICAgICAgICAgICBpZiAoaXRlbVZhbHVlICE9PSBudWxsICYmIGl0ZW1WYWx1ZSAhPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yYXdWYWx1ZSA9PSBpdGVtVmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vIFRPRE86IHJldHVybiBudWxsIG9yIGZhbHNlCiAgICAgICAgfSwKCiAgICAgICAgc2V0SXRlbVN0YXRlOiBmdW5jdGlvbiAobkluZGV4LCBiVmFsKSB7CiAgICAgICAgICAgIHZhciBpdGVtVmFsdWUgPSB0aGlzLmdldE9yRWxzZSh0aGlzLmdldFNhdmVJdGVtKG5JbmRleCksIHRoaXMuZ2V0RGlzcGxheUl0ZW0obkluZGV4KSk7CiAgICAgICAgICAgIGlmIChpdGVtVmFsdWUgIT09IG51bGwgJiYgaXRlbVZhbHVlICE9PSB1bmRlZmluZWQpIHsgICAgICAgICAgICAgICAgICAgICAgLy9UT0RPOklzIGl0IGNvcnJlY3QuIFdoYXQgYWJvdXQgVGV4dCBhbmQgTnVtZXJpY0lucHV0PwogICAgICAgICAgICAgICAgaWYgKGJWYWwpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5yYXdWYWx1ZSA9IGl0ZW1WYWx1ZTsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMucmF3VmFsdWUgPT0gaXRlbVZhbHVlKQogICAgICAgICAgICAgICAgICAgIHRoaXMucmF3VmFsdWUgPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgZGVsZXRlSXRlbTogZnVuY3Rpb24gKG5JbmRleCkgewogICAgICAgICAgICB2YXIgc0l0ZW1zID0gdGhpcy5fZ2V0U2F2ZUl0ZW1zKGZhbHNlKTsKICAgICAgICAgICAgdmFyIGRJdGVtcyA9IHRoaXMuX2dldERpc3BsYXlJdGVtcyhmYWxzZSk7CiAgICAgICAgICAgIGlmIChuSW5kZXggPj0gMCAmJiBzSXRlbXMgJiYgc0l0ZW1zLm1vQ2hpbGROb2Rlcy5sZW5ndGggPiBuSW5kZXgpIC8vQ2hlY2sgd2hldGhlciBuZWdhdGl2ZSB2YWx1ZSBvZiBuSW5kZXggaXMgYSBsZWdhbCB2YWx1ZT8/CiAgICAgICAgICAgICAgICBzSXRlbXMuX3JlbW92ZUNoaWxkKHNJdGVtcy5tb0NoaWxkTm9kZXNbbkluZGV4XSk7CiAgICAgICAgICAgIGlmIChuSW5kZXggPj0gMCAmJiBkSXRlbXMgJiYgZEl0ZW1zLm1vQ2hpbGROb2Rlcy5sZW5ndGggPiBuSW5kZXgpIC8vQ2hlY2sgd2hldGhlciBuZWdhdGl2ZSB2YWx1ZSBvZiBuSW5kZXggaXMgYSBsZWdhbCB2YWx1ZT8/CiAgICAgICAgICAgICAgICBkSXRlbXMuX3JlbW92ZUNoaWxkKGRJdGVtcy5tb0NoaWxkTm9kZXNbbkluZGV4XSk7CiAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsCiAgICAgICAgICAgICAgICB0aGlzLCAiZGVsZXRlSXRlbSIsIG51bGwsIG5JbmRleCk7CiAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsIGV2bnQpOwogICAgICAgIH0sCgogICAgICAgIGV4ZWNWYWxpZGF0ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4odGhpcy5fdmFsaWRhdGUoW10pKTsKICAgICAgICB9LAoKICAgICAgICBuYWtlZEZpZWxkUmVmZXJlbmNlczogZnVuY3Rpb24gKG5JbmRleCwgY3JlYXRlR2V0dGVyU2V0dGVyLCBvYmopIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0sCgogICAgICAgIF9yZXNldERhdGE6IGZ1bmN0aW9uIChuSW5kZXgsIGJGb3JjZSkgewogICAgICAgICAgICB0aGlzLnJhd1ZhbHVlID0gdGhpcy5qc29uTW9kZWxbIntkZWZhdWx0fSJdOwogICAgICAgIH0sCgogICAgICAgIF9udWxsVGVzdDogZnVuY3Rpb24gKHNNZXNzYWdlcykgewogICAgICAgICAgICB2YXIgdmFsaWQgPSB0cnVlOwogICAgICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLl9nZXRWYWx1ZSgpOwogICAgICAgICAgICBpZiAoKHZhbHVlID09IG51bGwgfHwgdmFsdWUubGVuZ3RoID09IDApICYmIHRoaXMubWFuZGF0b3J5ICE9ICJkaXNhYmxlZCIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxUZXN0ID0gIm51bGxUZXN0IjsKICAgICAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxMZXZlbCA9IHRoaXMubWFuZGF0b3J5OwogICAgICAgICAgICAgICAgdGhpcy5fZXJyb3JUZXh0ID0gdGhpcy5tYW5kYXRvcnlNZXNzYWdlOwogICAgICAgICAgICAgICAgdGhpcy5fYWRkTWVzc2FnZShzTWVzc2FnZXMsIHRoaXMuX2Vycm9yVGV4dCwgdGhpcy5fbUZhaWxlZFZhbExldmVsKTsKICAgICAgICAgICAgICAgIHZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbGlkOwogICAgICAgIH0sCgogICAgICAgIF9mb3JtYXRUZXN0OiBmdW5jdGlvbiAoc01lc3NhZ2VzKSB7CiAgICAgICAgICAgIHZhciB2YWxpZCA9IHRydWU7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuX2dldFZhbHVlKCk7CiAgICAgICAgICAgIGlmICh2YWx1ZSkKICAgICAgICAgICAgICAgIHZhbHVlICs9ICIiOwogICAgICAgICAgICB2YXIgcGljdHVyZSA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMuanNvbk1vZGVsLCJleHRyYXMudmFsaWRhdGVQYXR0ZXJuRXgiLCB1bmRlZmluZWQpOwogICAgICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiBwaWN0dXJlKSB7CiAgICAgICAgICAgICAgICB2YXIgcmV0VmFsID0gdGhpcy5fZm9ybWF0VmFsdWUodmFsdWUsIHBpY3R1cmUsIDApOwogICAgICAgICAgICAgICAgaWYgKCFyZXRWYWwpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZXRFcnJvckRhdGEoImZvcm1hdFRlc3QiLCB0aGlzLmdldE9yRWxzZSh0aGlzLnZhbGlkYXRlLmZvcm1hdFRlc3QsIHRoaXMuX2RlZmF1bHRzLnZhbGlkYXRlLmZvcm1hdFRlc3QpLCB0aGlzLmZvcm1hdE1lc3NhZ2UpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2FkZE1lc3NhZ2Uoc01lc3NhZ2VzLCB0aGlzLl9lcnJvclRleHQsIHRoaXMuX21GYWlsZWRWYWxMZXZlbCk7CiAgICAgICAgICAgICAgICAgICAgdmFsaWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdmFsaWQ7CiAgICAgICAgfSwKCiAgICAgICAgX3NldEVycm9yRGF0YTogZnVuY3Rpb24gKGZhaWxlZFRlc3QsIGZhaWxlZExldmVsLCBlcnJvclRleHQpIHsKICAgICAgICAgICAgdGhpcy5fbUZhaWxlZFZhbFRlc3QgPSBmYWlsZWRUZXN0OwogICAgICAgICAgICB0aGlzLl9tRmFpbGVkVmFsTGV2ZWwgPSBmYWlsZWRMZXZlbDsKICAgICAgICAgICAgdGhpcy5fZXJyb3JUZXh0ID0gZXJyb3JUZXh0OwogICAgICAgIH0sCgogICAgICAgIF9nZXRTYXZlSXRlbXM6IGZ1bmN0aW9uIChjcmVhdGVJZlJlcWQpIHsKICAgICAgICAgICAgdmFyIGl0ZW1zTGlzdCA9IHRoaXMuCiAgICAgICAgICAgICAgICBfZmluZENoaWxkcmVuKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlU29tRXhwcmVzc2lvbigiaXRlbXNbKl0iKSwKICAgICAgICAgICAgICAgIHRydWUpCiAgICAgICAgICAgIHZhciBzYXZlSXRlbXMgPSBpdGVtc0xpc3QuX2ZpbmQoZnVuY3Rpb24gKGl0ZW0sIGluZGV4KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gaXRlbS5zYXZlID09IDE7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBpZiAoIXNhdmVJdGVtcyAmJiBjcmVhdGVJZlJlcWQpIHsKICAgICAgICAgICAgICAgIHNhdmVJdGVtcyA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlTW9kZWwoewogICAgICAgICAgICAgICAgICAgIF9jbGFzczogIml0ZW1zIiwKICAgICAgICAgICAgICAgICAgICBzYXZlOiAiMSIsCiAgICAgICAgICAgICAgICAgICAgbmFtZTogIml0ZW1zIgogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB0aGlzLl9hZGRDaGlsZChzYXZlSXRlbXMpOwogICAgICAgICAgICAgICAgdmFyIGRpc3BsYXlJdGVtcyA9IGl0ZW1zTGlzdC5fZmluZChmdW5jdGlvbiAoaXRlbSwgaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlbS5zYXZlID09IDA7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHNhdmVJdGVtcy5jaGlsZHJlbiA9IGRpc3BsYXlJdGVtcyA/IGRpc3BsYXlJdGVtcy5tb0NoaWxkTm9kZXMgOiBbXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoc2F2ZUl0ZW1zKQogICAgICAgICAgICAgICAgcmV0dXJuIHNhdmVJdGVtczsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgX2dldERpc3BsYXlJdGVtczogZnVuY3Rpb24gKGNyZWF0ZUlmUmVxZCkgewogICAgICAgICAgICB2YXIgaXRlbXNMaXN0ID0gdGhpcy4KICAgICAgICAgICAgICAgIF9maW5kQ2hpbGRyZW4oeGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVTb21FeHByZXNzaW9uKCJpdGVtc1sqXSIpLAogICAgICAgICAgICAgICAgdHJ1ZSkKICAgICAgICAgICAgdmFyIGRpc3BsYXlJdGVtcyA9IGl0ZW1zTGlzdC5fZmluZChmdW5jdGlvbiAoaXRlbSwgaW5kZXgpIHsKICAgICAgICAgICAgICAgIHJldHVybiBpdGVtLnNhdmUgPT0gMDsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlmICghZGlzcGxheUl0ZW1zICYmIGNyZWF0ZUlmUmVxZCkgewogICAgICAgICAgICAgICAgZGlzcGxheUl0ZW1zID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVNb2RlbCh7CiAgICAgICAgICAgICAgICAgICAgX2NsYXNzOiAiaXRlbXMiLAogICAgICAgICAgICAgICAgICAgIG5hbWU6ICJpdGVtcyIKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgdGhpcy5fYWRkQ2hpbGQoZGlzcGxheUl0ZW1zKTsKICAgICAgICAgICAgICAgIHZhciBzYXZlSXRlbXMgPSBpdGVtc0xpc3QuX2ZpbmQoZnVuY3Rpb24gKGl0ZW0sIGluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0uc2F2ZSA9PSAxOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBkaXNwbGF5SXRlbXMuY2hpbGRyZW4gPSBzYXZlSXRlbXMgPyBzYXZlSXRlbXMubW9DaGlsZE5vZGVzIDogW107CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGRpc3BsYXlJdGVtcykKICAgICAgICAgICAgICAgIHJldHVybiBkaXNwbGF5SXRlbXM7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRTYXZlSXRlbXMoKTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0VmFsdWU6IGZ1bmN0aW9uIChjb250ZW50VHlwZSwgc2tpcFR5cGVDaGVjaykgewogICAgICAgICAgICByZXR1cm4gdGhpcy52YWx1ZS5vbmVPZkNoaWxkLmdldFZhbHVlKGNvbnRlbnRUeXBlLCBza2lwVHlwZUNoZWNrKTsKICAgICAgICB9LAoKICAgICAgICBfc2V0VmFsdWU6IGZ1bmN0aW9uIChzVmFsLCBza2lwVHlwZUNoZWNrKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlLm9uZU9mQ2hpbGQuc2V0VmFsdWUoc1ZhbCwgc2tpcFR5cGVDaGVjayk7CiAgICAgICAgfSwKCiAgICAgICAgX3NldEhUTUxWYWx1ZTogZnVuY3Rpb24oaHRtbFN0cikgewogICAgICAgICAgICAvLyBhcGkgdG8gc2V0IHRoZSBodG1sIHZhbHVlIGZvciBjbSB1c2UtY2FzZQogICAgICAgICAgICB0aGlzLl9zZXRWYWx1ZShodG1sU3RyLCB0cnVlKTsKICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwgdGhpcywKICAgICAgICAgICAgICAgICdyYXdWYWx1ZScsIG51bGwsIGh0bWxTdHIpOwogICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLCBldm50KTsKICAgICAgICB9LAoKICAgICAgICBfZXZlbnRIYW5kbGVyOiBmdW5jdGlvbiAoZXZlbnROYW1lKSB7CiAgICAgICAgICAgIHZhciByVmFsdWUgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIHN3aXRjaCAoZXZlbnROYW1lKSB7CiAgICAgICAgICAgICAgICBjYXNlICJjYWxjdWxhdGUiOgogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm1vRXZlbnRzWyJjYWxjdWxhdGUiXSAmJiB0aGlzLm1vRXZlbnRzWyJjYWxjdWxhdGUiXS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJWYWx1ZSA9IHRoaXMubW9FdmVudHNbImNhbGN1bGF0ZSJdWzBdLmV4ZWN1dGUodGhpcywgImNhbGN1bGF0ZSIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInZhbGlkYXRlIjoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5tb0V2ZW50c1sidmFsaWRhdGUiXSAmJiB0aGlzLm1vRXZlbnRzWyJ2YWxpZGF0ZSJdLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdGhpcy5tb0V2ZW50c1sidmFsaWRhdGUiXVswXS5leGVjdXRlKHRoaXMsICJ2YWxpZGF0ZSIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgICAgICAgICByVmFsdWUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiJGZvcm1wcmVTdWJtaXQiOgogICAgICAgICAgICAgICAgICAgIHJWYWx1ZSA9IHRoaXMuX3ByZVN1Ym1pdEV2ZW50SGFuZGxlcigpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5tb0V2ZW50c1tldmVudE5hbWVdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tb0V2ZW50c1tldmVudE5hbWVdLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1vRXZlbnRzW2V2ZW50TmFtZV1baV0uZXhlY3V0ZSh0aGlzLCBldmVudE5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByVmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgX2lzRmllbGQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSwKCiAgICAgICAgX3Nob3dEaXNwbGF5Rm9ybWF0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsIHRoaXMsCiAgICAgICAgICAgICAgICAncmF3VmFsdWUnLCB0aGlzLnJhd1ZhbHVlLCB0aGlzLmZvcm1hdHRlZFZhbHVlKTsKICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSwgZXZudCk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldERlZmF1bHRQaWN0dXJlQ2xhdXNlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9LAoKICAgICAgICBfZm9ybWF0VmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSwgcGljdHVyZSwgZm9yY2UpIHsKICAgICAgICAgICAgLy90ZXN0aW5nIHNwZWNpZmljYWxseSBmb3Igb25seSBudWxsIGFuZCB6ZXJvIGxlbmd0aCBzdHJpbmcKICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAidW5kZWZpbmVkIiB8fCB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gIiIpCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKCiAgICAgICAgICAgIC8vZm9yY2UgaXMgc2FtZSBhcyBiUmVsYXhlZCAsIHdoaWNoIGlzIHRydWUgaW4gY2FzZSBvZiBEaXNwbGF5IGFuZCBmYWxzZSBpbiBjYXNlIG9mIHBhcnNpbmcuCiAgICAgICAgICAgIGZvcmNlID0gZm9yY2UgfHwgZmFsc2U7CiAgICAgICAgICAgIGlmIChwaWN0dXJlKSB7CiAgICAgICAgICAgICAgICB2YXIgaSA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IHBpY3R1cmUubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGF0dGVybiA9IHBpY3R1cmVbaV0uY2F0ZWdvcnkgKyAieyIgKyBwaWN0dXJlW2ldLm1hc2sgKyAifSI7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB4ZmFsaWIudXQuUGljdHVyZUZtdC5mb3JtYXQodmFsdWUgKyAiIiwgcGF0dGVybiwgcGljdHVyZVtpXS5sb2NhbGUsIGZvcmNlICxmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vY29udGludWUgdG8gbmV4dCBwYwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZm9yY2UpIHsKICAgICAgICAgICAgICAgIHBhdHRlcm4gPSB0aGlzLl9nZXREZWZhdWx0UGljdHVyZUNsYXVzZSgpOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlBpY3R1cmVGbXQuZm9ybWF0KHZhbHVlICsgIiIsIHBhdHRlcm4sIHRoaXMubG9jYWxlLGZvcmNlLHRydWUpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIF9wYXJzZVZhbHVlOiBmdW5jdGlvbiAodmFsdWUsIHBpY3R1cmUpIHsKICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwoKICAgICAgICAgICAgaWYgKHBpY3R1cmUpIHsKICAgICAgICAgICAgICAgIHZhciBpID0gMDsKICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgcGljdHVyZS5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXR0ZXJuID0gcGljdHVyZVtpXS5jYXRlZ29yeSArICJ7IiArIHBpY3R1cmVbaV0ubWFzayArICJ9IjsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5QaWN0dXJlRm10LnBhcnNlKHZhbHVlLCBwYXR0ZXJuLCBwaWN0dXJlW2ldLmxvY2FsZSk7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vY29udGludWUgdG8gbmV4dCBwYwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBwYXR0ZXJuID0gdGhpcy5fZ2V0RGVmYXVsdFBpY3R1cmVDbGF1c2UoKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiB4ZmFsaWIudXQuUGljdHVyZUZtdC5wYXJzZSh2YWx1ZSwgcGF0dGVybiwgdGhpcy5sb2NhbGUpOwogICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHsKICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgoKICAgICAgICBfZ2V0TG9jYWxlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBvYmogPSB0aGlzOwogICAgICAgICAgICB2YXIgbG9jYWxlOwogICAgICAgICAgICB3aGlsZSAoIWxvY2FsZSAmJiBvYmopIHsKICAgICAgICAgICAgICAgIGxvY2FsZSA9IG9iai5qc29uTW9kZWwubG9jYWxlOwogICAgICAgICAgICAgICAgb2JqID0gb2JqLnBhcmVudDsKICAgICAgICAgICAgfQogICAgICAgICAgICBsb2NhbGUgPSBsb2NhbGUgfHwgdGhpcy5feGZhKCkuZGVmYXVsdExvY2FsZTsKICAgICAgICAgICAgcmV0dXJuIGxvY2FsZTsKICAgICAgICB9LAoKICAgICAgICBzY29wZWxlc3M6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgIC8vY2hlY2sgYmluZGluZ3MgLT4gaWYgaXQgaXMgbm9uZSB0aGVuIHRoaXMgZmllbGQgaXMgbm90IG5lZWRlZCBpbiB4bWwKICAgICAgICAgICAgaWYgKGRpZmZfbGV2ZWw+MCkgewogICAgICAgICAgICAgICAgdmFyIGJpbmRFbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50KCJiaW5kIiwgMCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICBpZiAoYmluZEVsZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYmluZEVsZW1lbnQuZ2V0QXR0cmlidXRlKCJtYXRjaCIpID09PSAibm9uZSIgJiYgZGlmZl9sZXZlbCA9PT0gMikgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgImNoYW5nZWQiOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqc29uRGlmZmVyZW5jZSI6IHt9CiAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBGaWVsZC5fc3VwZXIuX2NvbXB1dGVKc29uRGlmZi5jYWxsKHRoaXMsIGRpZmZfbGV2ZWwpOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiB0aGUgRGF0YVNPTU1hcCBhZnRlciBhZGRpbmcgYW4gZW50cnkgaW4gdGhlIG1hcCBmb3IgdGhlIG5vZGUuIFRoZSBlbnRyeSBjb250YWlucyB0aGUgdmFsdWUgb2YgdGhlIG5vZGUKICAgICAgICAgKiBhbG9uZyB3aXRoIGl0cyBEYXRhIFNPTS4gSWYgdGhlcmUgaXMgbm8gRGF0YSBTT00gdGhlbiByZXR1cm4gdGhlIHVubW9kaWZpZWQgbWFwCiAgICAgICAgICogQHBhcmFtIG1hcAogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2dldERhdGFTb21NYXAgOiBmdW5jdGlvbihtYXApIHsKICAgICAgICAgICAgaWYoIV8uaXNPYmplY3QobWFwKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG1hcDsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgZGF0YXNvbSA9IHRoaXMuX2dldERhdGFTb20oKTsKICAgICAgICAgICAgaWYoZGF0YXNvbSAhPT0gbnVsbCkgewogICAgICAgICAgICAgICAgbWFwW2RhdGFzb21dID0gdGhpcy5yYXdWYWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbWFwOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFVwZGF0ZSB0aGUgdmFsdWUgb2YgdGhlIG5vZGUgd2l0aCB0aGUgdmFsdWUgcHJvdmlkZWQgaW4gdGhlIGlucHV0IG1hcC4gVGhlIG1hcCBjb250YWlucyB0aGUgdmFsdWVzIG9mIHRoZSBmaWVsZHMKICAgICAgICAgKiBtYXBwZWQgd2l0aCB0aGVpciBEYXRhU09NLiBUaGUgZnVuY3Rpb24gaXMgZW1wdHkgZm9yIGFsbCB0aGUgbm9kZXMsIGV4Y2VwdCBmb3IgRmllbGQsIFN1YmZvcm0gYW5kIEFyZWEuCiAgICAgICAgICogVGhlIGZ1bmN0aW9uIGRvZXMgbm90aGluZyBpZiB0aGUgbWFwIGlzIG5vdCBhbiBvYmplY3QKICAgICAgICAgKiBAcGFyYW0gbWFwIHtvYmplY3R9CiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfcmVzdG9yZURhdGFTb21NYXAgOiBmdW5jdGlvbiAobWFwKSB7CiAgICAgICAgICAgIGlmKCFfLmlzT2JqZWN0KG1hcCkpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgZGF0YXNvbSA9IHRoaXMuX2dldERhdGFTb20oKTsKICAgICAgICAgICAgaWYgKGRhdGFzb20gIT0gbnVsbCAmJiBtYXBbZGF0YXNvbV0gIT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgdGhpcy5yYXdWYWx1ZSA9IG1hcFtkYXRhc29tXTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEV2YWx1YXRlcyB0aGUgZ2l2ZW4geHBhdGggcmVsYXRpdmUgdG8gY29udGV4dE5vZGUgb3IgUm9vdE5vZGUgZGVwZW5kaW5nIHVwb24gdGhlIHZhbHVlIG9mIHhwYXRoLnJlbGF0aXZlCiAgICAgICAgICogSW4gY2FzZSBpdCBpcyB0cnVlLCB4cGF0aCBpcyBldmFsdWF0ZXMgcmVsYXRpdmUgdG8gY29udGV4dE5vZGUgb3RoZXJ3aXNlIHJvb3ROb2RlCiAgICAgICAgICogRm9yIEZpZWxkcywgdGhlIHZhbHVlIG9mIHhwYXRoLnJlbGF0aXZlIGNhbiBiZSAiZ2xvYmFsIiBpbiB3aGljaCBjYXNlIHdlIG5lZWQgdG8gc2VhcmNoIHRoZSBkZXNjZW5kYW50cyBvZgogICAgICAgICAqIHRoZSByb290Tm9kZQogICAgICAgICAqIEBwYXJhbSB4cGF0aAogICAgICAgICAqIEBwYXJhbSBjb250ZXh0Tm9kZQogICAgICAgICAqIEBwYXJhbSByb290Tm9kZQogICAgICAgICAqIEByZXR1cm5zIHsqfQogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2dldEVsZW1lbnRzRnJvbVhwYXRoOiBmdW5jdGlvbih4cGF0aCwgY29udGV4dE5vZGUsIHJvb3ROb2RlKSB7CiAgICAgICAgICAgIHZhciBub2RlSXRlciwKICAgICAgICAgICAgICAgIFhNTFV0aWxzID0geGZhbGliLnV0LlhNTFV0aWxzLAogICAgICAgICAgICAgICAgZG9jID0gcm9vdE5vZGUgaW5zdGFuY2VvZiBEb2N1bWVudCA/IHJvb3ROb2RlIDogcm9vdE5vZGUub3duZXJEb2N1bWVudDsKICAgICAgICAgICAgaWYoeHBhdGgucmVsYXRpdmUgPT09ICJnbG9iYWwiKSB7CiAgICAgICAgICAgICAgICBub2RlSXRlciA9IFhNTFV0aWxzLmV2YWx1YXRlWFBhdGgoIi8vIit4cGF0aC5iaW5kUmVmLCByb290Tm9kZSwgbnVsbCwKICAgICAgICAgICAgICAgICAgICBYUGF0aFJlc3VsdC5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSwgbnVsbCk7CiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZUl0ZXI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIEZpZWxkLl9zdXBlci5fZ2V0RWxlbWVudHNGcm9tWHBhdGguYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBfcGxheURhdGFYTUw6IGZ1bmN0aW9uKHhtbERvY3VtZW50LCBjb250ZXh0Tm9kZSwgY3VycmVudEJpbmRSZWYpIHsKICAgICAgICAgICAgaWYodGhpcy5oYXNEYXRhQmluZGluZygpKSB7CiAgICAgICAgICAgICAgICB2YXIgeHBhdGggPSB0aGlzLl9nZXRYcGF0aEZyb21CaW5kUmVmKCksCiAgICAgICAgICAgICAgICAgICAgZGF0YVBhdHRlcm4gPSB0aGlzLmpzb25Nb2RlbC5kYXRhUGF0dGVybiwvLyBUT0RPIDogaWRlYWxseSBzaG91bGQgcmVhZCBmcm9tIGJpbmQucGljdHVyZS52YWx1ZQogICAgICAgICAgICAgICAgICAgIHJlc3VsdCwgbm9kZSwKICAgICAgICAgICAgICAgICAgICBsb2dnZXIgPSB0aGlzLl94ZmEoKS5Mb2dnZXI7CiAgICAgICAgICAgICAgICBpZih4cGF0aCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5fZ2V0RWxlbWVudHNGcm9tWHBhdGgoeHBhdGgsIGNvbnRleHROb2RlLCB4bWxEb2N1bWVudCk7CiAgICAgICAgICAgICAgICAgICAgaWYocmVzdWx0ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IHJlc3VsdC5pdGVyYXRlTmV4dCgpOwogICAgICAgICAgICAgICAgICAgICAgICBpZihub2RlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcmVGaWxsVmFsdWUgPSBub2RlLnRleHRDb250ZW50OwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKF8uaXNTdHJpbmcoZGF0YVBhdHRlcm4pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcnNlZFBhdHRlcm4gPSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLnBhcnNlUGljdHVyZUNsYXVzZShkYXRhUGF0dGVybik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoXy5pc0FycmF5KHBhcnNlZFBhdHRlcm4pICYmIHBhcnNlZFBhdHRlcm4ubGVuZ3RoID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDUS00MjQ0OTgzIDogY2hhbmdpbmcgdGhlIGZvcm1hdFRlc3QgY29uZGl0aW9uLiBDYXNlcyB3aGVyZSBwcmVmaWxsZWQgdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlzIHByb3Blcmx5IGZvcm1hdHRlZCwgdmFsdWUgd2FzIG5vdCBiZWluZyBwYXJzZWQgYW5kIHRoZSByYXdWYWx1ZSBpbiBtb2RlbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2FzIGJlaW5nIHN0b3JlZCBpbiBkYXRhIHBhdHRlcm4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV4IDogZGF0YSBwYXR0ZXJuIGlzIHRleHR7OTk5LTk5LTk5OTl9IGFuZCB2YWx1ZSBpcyAxMjMtNDUtNjc4OQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gMSkgZm9yIG1vYmlsZSBmb3JtcyByYXdWYWx1ZSBiZWluZyBzdG9yZWQgaXMgMTIzNDU2Nzg5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAyKSBmb3IgZm9ybXNldCByYXdWYWx1ZSBiZWluZyBzdG9yZWQgd2FzIDEyMy00NS02Nzg5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbiBjYXNlIHRoZSBwYXJzZSBpcyBpbmNvcnJlY3QgYmVjYXVzZSBvZiBtaXNtYXRjaCBpbiBkYXRhIHBhdHRlcm4gYW5kIHByZWZpbGxWYWx1ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlbiB0aGVyZSB3aWxsIGJlIGRhdGEgbG9zcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIGlmIHRoZXJlIGlzIGFueSBleGNlcHRpb24gd2hpbGUgcGFyc2luZyB0aGVuIG9yaWdpbmFsIHZhbHVlIGlzIHN0b3JlZC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZUZpbGxWYWx1ZSA9IHhmYWxpYi51dC5QaWN0dXJlRm10LnBhcnNlKHByZUZpbGxWYWx1ZSwgZGF0YVBhdHRlcm4pOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdGUgOiBudW1lcmljIHBhcnNlIGRvZXNuJ3QgdGhyb3csIGJ1dCByZXR1cm5zIDAsIG5lZWQgdG8gdGFrZSBjYXJlIG9mIGl0IGxhdGVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG11c3Qgc2V0IHZhbHVlIHRvIHByZXNlcnZlIHByZWZpbGwgZGF0YSBvbiBzdWJtaXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NldFZhbHVlKG5vZGUudGV4dENvbnRlbnQsIHRydWUpOyAgLy8gbmVlZCB0byBzZXQgdmFsdWUgd2l0aG91dCB0eXBlIGNoZWNraW5nLCBmb3IgbnVtZXJpYyBmaWVsZCBkb2Vzbid0IGFsbG93IG5vbiBudW1lcmljIGNoYXJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybigieGZhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIucmVzb2x2ZU1lc3NhZ2UoeGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDIxIl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRhUGF0dGVybiwgbm9kZS50ZXh0Q29udGVudCwgZV0pKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3NldFZhbHVlKG5vZGUudGV4dENvbnRlbnQsIHRydWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybigieGZhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5yZXNvbHZlTWVzc2FnZSh4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMjIiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0YVBhdHRlcm4sIG5vZGUudGV4dENvbnRlbnRdKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnVnIGluIHBpY3R1cmVmbXQgbnVtZXJpYyBwYXJzZSA6IGNhbnQgcGFyc2UgcGF0dGVybnMgd2l0aCAoIG9yICksIGJ1dCBkb2VzbnQgdGhyb3csIHJldHVybnMgMCBpbnN0ZWFkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoXy5pc1N0cmluZyhkYXRhUGF0dGVybikgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhUGF0dGVybi50cmltKCkuaW5kZXhPZigibnVtIikgPT09IDAgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocHJlRmlsbFZhbHVlID09IDAgJiYgcGFyc2VGbG9hdChub2RlLnRleHRDb250ZW50LnJlcGxhY2UoL1teMC05XS9nLCAiIikpICE9PSAwKSkgeyAvLyBoYWNrOiBpZiBwYXJzZXIgcmV0dXJucyAwLCBhbmQgaW5wdXQgaGFzIGFueSBub24gemVybyBkaWdpdCB0aGVuIHBhcnNpbmcgZmFpbGVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2V0VmFsdWUobm9kZS50ZXh0Q29udGVudCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oInhmYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5yZXNvbHZlTWVzc2FnZSh4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMjMiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRhUGF0dGVybiwgbm9kZS50ZXh0Q29udGVudF0pKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2V0VmFsdWUocHJlRmlsbFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2V0RGF0YSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEdlbmVyYXRlcyB0aGUgWE1MIGJ5IGFwcGVuZGluZyB0aGUgZWxlbWVudHMgaW4gdGhlIHJvb3ROb2RlCiAgICAgICAgICogQHBhcmFtIHJvb3ROb2RlIFRoZSByb290Tm9kZSBvZiB0aGUgeG1sLiBHZW5lcmFsbHkgdGhlIGVsZW1lbnQgdGhhdCBtYXBzIHRvIHRoZSByb290IG9mIHRoZSBmb3JtCiAgICAgICAgICogQHBhcmFtIGNvbnRleHROb2RlIEN1cnJlbnQgTm9kZSB3aGVyZSB0byBpbnNlcnQgdGhlIGVsZW1lbnRzIGluIGNhc2Ugb2YgcmVsYXRpdmUgYmluZGluZ3MKICAgICAgICAgKi8KICAgICAgICBnZW5lcmF0ZURhdGFYTUw6IGZ1bmN0aW9uIChyb290Tm9kZSwgY29udGV4dE5vZGUpIHsKICAgICAgICAgICAgaWYodGhpcy5oYXNEYXRhQmluZGluZygpKSB7CiAgICAgICAgICAgICAgICB2YXIgeHBhdGggPSB0aGlzLl9nZXRYcGF0aEZyb21CaW5kUmVmKCksCiAgICAgICAgICAgICAgICAgICAgcmVsYXRpdmVYUGF0aCwgbm9kZUl0ZXIsIG5vZGVMaXN0ID0gW10sIHJlc3VsdCwgbm9kZTsKICAgICAgICAgICAgICAgIGlmKHhwYXRoICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudCA9IHhwYXRoLnJlbGF0aXZlID09PSBmYWxzZSB8fCB4cGF0aC5yZWxhdGl2ZSA9PT0gImdsb2JhbCIgPyByb290Tm9kZSA6IGNvbnRleHROb2RlOwogICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSB4ZmFsaWIudXQuWE1MVXRpbHMuY3JlYXRlRWxlbWVudHNGcm9tWFBhdGgoeHBhdGguYmluZFJlZiwgZWxlbWVudCwgZmFsc2UpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2FwcGVuZFZhbHVlSW5YTUxFbGVtZW50KGVsZW1lbnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2FwcGVuZFZhbHVlSW5YTUxFbGVtZW50OiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICBpZihlbGVtZW50ICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIGVsZW1lbnQudGV4dENvbnRlbnQgPSB0aGlzLl9nZXRWYWx1ZShudWxsLCB0cnVlKTsgLy8gTEMtMzkxMTE4MCA6IG5lZWQgdG8gY2lyY3VtdmVudCB0eXBlIGNoZWNrIHRvIHByZXNlcnZlIGRhdGEKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogZXhlY3V0ZXMgcHJlc3VibWl0IGV2ZW50IHNjcmlwdHMgYW5kIGNoZWNrIGZvciBjYW5jZWxBY3Rpb24gcHJvcGVydHkKICAgICAgICAgKiByZXR1cm4gZmFsc2UgaWYgdGhlIGNhbmNlbEFjdGlvbiBwcm9wZXJ0eSBpcyBzZXQgdHJ1ZQogICAgICAgICAqLwogICAgICAgIF9wcmVTdWJtaXRFdmVudEhhbmRsZXIgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmICh0aGlzLm1vRXZlbnRzWyIkZm9ybXByZVN1Ym1pdCJdICYmIHRoaXMubW9FdmVudHNbIiRmb3JtcHJlU3VibWl0Il0ubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgdGhpcy5tb0V2ZW50c1siJGZvcm1wcmVTdWJtaXQiXVswXS5leGVjdXRlKHRoaXMsICIkZm9ybXByZVN1Ym1pdCIpOwogICAgICAgICAgICAgICAgLy8gSWYgYSBzY3JpcHQgaW52b2tlZCBieSB0aGUgcHJlLXN1Ym1pdCBldmVudCBzZXRzICRldmVudC5jYW5jZWxBY3Rpb24sIHRoZSBzdWJtaXQgYWN0aW9uIGRvZXMgbm90IHRha2UgcGxhY2UKICAgICAgICAgICAgICAgIGlmICh0aGlzLl94ZmEoKS5ldmVudC5jYW5jZWxBY3Rpb24pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgIH0pOwoKICAgIEZpZWxkLmRlZmluZVByb3BzKHsKICAgICAgICAibG9jYWxlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGlmICghdGhpcy5fbG9jYWxlKQogICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvY2FsZSA9IHRoaXMuX2dldExvY2FsZSgpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvY2FsZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJtdWx0aUxpbmUiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICh0aGlzLnVpLm9uZU9mQ2hpbGQubXVsdGlMaW5lID09IDEpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInJhd1ZhbHVlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBjdXJyZW50Tm9kZSA9IHRoaXMuX3hmYSgpLm1vQ2FsY3VsYXRlRXZlbnROb2RlOwogICAgICAgICAgICAgICAgaWYgKGN1cnJlbnROb2RlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZERlcGVuZGFudChjdXJyZW50Tm9kZSk7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudE5vZGUub24oeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50Lk9CSkVDVF9ERVNUUk9ZRUQsIHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldFZhbHVlKG51bGwsIHRoaXMudmFsdWUub25lT2ZDaGlsZC5nZXRBdHRyaWJ1dGUoImNvbnRlbnRUeXBlIikgPT09ICJ0ZXh0L2h0bWwiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAob1ZhbHVlKSB7CiAgICAgICAgICAgICAgICBvVmFsdWUgPSB0aGlzLnZhbGlkYXRlSW5wdXQob1ZhbHVlLCAic3RyaW5nIik7CiAgICAgICAgICAgICAgICBpZiAodGhpcy52YWx1ZS5vbmVPZkNoaWxkLm1heENoYXJzICYmIHRoaXMudmFsdWUub25lT2ZDaGlsZC5tYXhDaGFycyAhPT0gIjAiICYmIG9WYWx1ZSAmJiB0aGlzLnZhbHVlLm9uZU9mQ2hpbGQubWF4Q2hhcnMgPCBvVmFsdWUubGVuZ3RoKQogICAgICAgICAgICAgICAgICAgIG9WYWx1ZSA9IG9WYWx1ZS5zbGljZSgwLCB0aGlzLnZhbHVlLm9uZU9mQ2hpbGQubWF4Q2hhcnMpOwogICAgICAgICAgICAgICAgdmFyIG9sZHZhbCA9IHRoaXMuX2dldFZhbHVlKCk7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc2V0VmFsdWUob1ZhbHVlLCB0aGlzLnZhbHVlLm9uZU9mQ2hpbGQuZ2V0QXR0cmlidXRlKCJjb250ZW50VHlwZSIpID09PSAidGV4dC9odG1sIikpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVEZXBlbmRhbnRzKCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkucXVldWVWYWxpZGF0ZUV2ZW50KHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG9sZHZhbCAhPSBvVmFsdWUpCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2hvd0Rpc3BsYXlGb3JtYXQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICAiZm9udCI6IHsKICAgICAgICAgICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICB0aGlzLmdldEVsZW1lbnQoImZvbnQiLDApOwogICAgICAgICAgICAgICAgICAgIH0gLAogICAgICAgICAgICAgICAgICAgIHNldCA6ZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsImZvbnQiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAoKICAgICAgICAiZm9udENvbG9yIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZm9udCIsIDApLmdldEVsZW1lbnQoImZpbGwiLCAwKS5nZXRFbGVtZW50KCJjb2xvciIsIDApLnZhbHVlOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuZ2V0RWxlbWVudCgiZm9udCIsIDApLmdldEVsZW1lbnQoImZpbGwiLCAwKS5nZXRFbGVtZW50KCJjb2xvciIsIDApLnZhbHVlID0gdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAidmFsdWUiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiAgdGhpcy5nZXRFbGVtZW50KCJ2YWx1ZSIsMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKCkge30KICAgICAgICB9LAoKICAgICAgICAvL1RPRE86IE5vdGU6IEJlbG93IGhhbmRsaW5nIHNob3VsZCBoYW5kbGUgYm90aCBtdWx0aVNlbGVjdCBhbmQgc2luZ2xlIFNlbGVjdHMuIE5lZWQgdG8gdmVyaWZ5IHRoaXMuCiAgICAgICAgInNlbGVjdGVkSW5kZXgiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5yYXdWYWx1ZTsKICAgICAgICAgICAgICAgIHZhciBpdGVtU2l6ZSA9IHRoaXMubGVuZ3RoOwogICAgICAgICAgICAgICAgaWYgKGl0ZW1TaXplID49IDApIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZW1TaXplOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkID0gdGhpcy5nZXRJdGVtU3RhdGUoaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAtMTsgICAvL2RlZmF1bHQgLTEKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAobkluZGV4KSB7CiAgICAgICAgICAgICAgICBuSW5kZXggPSB0aGlzLnZhbGlkYXRlSW5wdXQobkluZGV4LCAic3RyaW5nIik7CiAgICAgICAgICAgICAgICB0aGlzLl9zZXRWYWx1ZShudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMuc2V0SXRlbVN0YXRlKG5JbmRleCwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAibGVuZ3RoIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBpdGVtcyA9ICh0aGlzLl9nZXRTYXZlSXRlbXMoZmFsc2UpIHx8IHRoaXMuX2dldERpc3BsYXlJdGVtcyhmYWxzZSkpOwogICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW1zID8gaXRlbXMubW9DaGlsZE5vZGVzLmxlbmd0aCA6IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAicGFyZW50U3ViZm9ybSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgdGVtcCA9IHRoaXMucGFyZW50OwogICAgICAgICAgICAgICAgd2hpbGUgKHRlbXAgJiYgdGVtcC5jbGFzc05hbWUgIT09ICJzdWJmb3JtIikKICAgICAgICAgICAgICAgICAgICB0ZW1wID0gdGVtcC5wYXJlbnQ7CiAgICAgICAgICAgICAgICByZXR1cm4gdGVtcDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJtYW5kYXRvcnkiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JFbHNlKHRoaXMudmFsaWRhdGUubnVsbFRlc3QsIHRoaXMuX2RlZmF1bHRzLnZhbGlkYXRlLm51bGxUZXN0KTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLnZhbGlkYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy52YWxpZGF0ZS5udWxsVGVzdCA9IHZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgIm1hbmRhdG9yeU1lc3NhZ2UiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5fZ2V0TWFuZGF0b3J5TWVzc2FnZSh0aGlzKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICB2YXIgbm9kZXMgPSB0aGlzLnZhbGlkYXRlLm1lc3NhZ2Uubm9kZXM7CiAgICAgICAgICAgICAgICBpZiAobm9kZXMubmFtZWRJdGVtKCJudWxsVGVzdCIpID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSB0aGlzLl94ZmEoKS5mb3JtLmNyZWF0ZU5vZGUoInRleHQiLCAibnVsbFRlc3QiKTsKICAgICAgICAgICAgICAgICAgICBub2Rlcy5hcHBlbmQobm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLnZhbGlkYXRlLm1lc3NhZ2UubnVsbFRlc3QudmFsdWUgPSB2YWw7CiAgICAgICAgICAgICAgICB0aGlzLmV4ZWNWYWxpZGF0ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImZvcm1hdE1lc3NhZ2UiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIG1zZyA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMudmFsaWRhdGUsICJtZXNzYWdlLmZvcm1hdFRlc3QiLCB0aGlzLl9kZWZhdWx0cy52YWxpZGF0ZS5tZXNzYWdlLmRlZmF1bHRNZXNzYWdlKTsKICAgICAgICAgICAgICAgIHJldHVybiBtc2cudmFsdWU7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbCkgewogICAgICAgICAgICAgICAgdmFyIG5vZGVzID0gdGhpcy52YWxpZGF0ZS5tZXNzYWdlLm5vZGVzOwogICAgICAgICAgICAgICAgaWYgKG5vZGVzLm5hbWVkSXRlbSgiZm9ybWF0VGVzdCIpID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSB0aGlzLl94ZmEoKS5mb3JtLmNyZWF0ZU5vZGUoInRleHQiLCAiZm9ybWF0VGVzdCIpOwogICAgICAgICAgICAgICAgICAgIG5vZGVzLmFwcGVuZChub2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMudmFsaWRhdGUubWVzc2FnZS5mb3JtYXRUZXN0LnZhbHVlID0gdmFsOwogICAgICAgICAgICAgICAgdGhpcy5leGVjVmFsaWRhdGUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJmb3JtYXR0ZWRWYWx1ZSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZm9ybWF0VmFsdWUodGhpcy5fZ2V0VmFsdWUoKSwgdGhpcy5qc29uTW9kZWwuZXh0cmFzLmRpc3BsYXlQYXR0ZXJuRXgsIHRydWUpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWwpIHsKICAgICAgICAgICAgICAgIHRoaXMucmF3VmFsdWUgPSB0aGlzLl9wYXJzZVZhbHVlKHZhbCwgdGhpcy5qc29uTW9kZWwuZXh0cmFzLmRpc3BsYXlQYXR0ZXJuRXgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImlzTnVsbCI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5fZ2V0VmFsdWUoKSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIGVsc2UgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAiZWRpdFZhbHVlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9mb3JtYXRWYWx1ZSh0aGlzLl9nZXRWYWx1ZSgpLCB0aGlzLmpzb25Nb2RlbC5leHRyYXMuZWRpdFBhdHRlcm5FeCwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICB1aTogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInVpIiwgMCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAidWkiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJpdGVtcyI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJpdGVtcyIsIDApOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImNhbGN1bGF0ZSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjYWxjdWxhdGUiLCAwKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJmb3JtYXQiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZm9ybWF0IiwgMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoKICAgIH0pOwoKICAgIEZpZWxkLmFkZE1peGlucyhbCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRBc3Npc3QsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRDYXB0aW9uLAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkUHJlc2VuY2UsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRYWVdILAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkRmlsbENvbG9yLAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQm9yZGVyLAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQm9yZGVyQ29sb3IsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRCb3JkZXJXaWR0aCwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFBhcmEsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRNYXJnaW4KICAgIF0pOwoKfSkoXywgeGZhbGliKTsKCgoKCgoKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5EcmF3CiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Ob2RlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgRHJhdyBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24gKF8sIHhmYWxpYiwgJCkgewogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3IERyYXcgY2xhc3MKICAgICAqCiAgICAgKiBAY29uc3RydWN0b3IKICAgICAqIEBwYXJhbSB7c3RyaW5nfQogICAgICogICAgICAgICAgICBuYW1lIHRoZSBuYW1lIG9mIHRoZSBEcmF3CiAgICAgKiBAZXh0ZW5kcyBjb20uYWRvYmUueGZhLnNjcmlwdGluZy5Ob2RlCiAgICAgKi8KICAgIHZhciBEcmF3ID0geGZhbGliLnNjcmlwdC5EcmF3ID0geGZhbGliLnNjcmlwdC5FdmVudENvbnRhaW5lck5vZGUuZXh0ZW5kKHsKCiAgICAgICAgX3NldFZhbHVlOiB4ZmFsaWIuc2NyaXB0LkZpZWxkLnByb3RvdHlwZS5fc2V0VmFsdWUsCgogICAgICAgIF9nZXRWYWx1ZTogeGZhbGliLnNjcmlwdC5GaWVsZC5wcm90b3R5cGUuX2dldFZhbHVlLAoKICAgICAgICBfZ2V0RmllbGRCeUlkOiBmdW5jdGlvbiAoZmllbGRJZCkgewoKICAgICAgICAgICAgaWYgKHRoaXMuX3hmYSgpLl94ZmFUZW1wbGF0ZUNhY2hlLmlkTWFwLmhhc093blByb3BlcnR5KGZpZWxkSWQpKSB7CiAgICAgICAgICAgICAgICAvL3h0ZyB1c2VzIGp1c3QgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGZpbmQgdGhlIGFjdHVhbCBjb250ZXh0IG5vZGUKICAgICAgICAgICAgICAgIC8vdGhpcyBpcyBhIHF1aWNrIGFuZCBkaXJ0eSB3YXkgdG8gZW5zdXJlIGluZGV4IGFmZmluaXR5CiAgICAgICAgICAgICAgICAvL2p1c3QgdG8gYmUgaW4gc3luYyB3aXRoIFhURywgSSBhbSB1c2luZyB0aGUgc2FtZSBpbXBsZW1lbnRhdGlvbiBhcyBYRkFMYXlvdXRUZXh0UmVzb2x2ZXIgY2xhc3MKICAgICAgICAgICAgICAgIHZhciBmaWVsZCA9IHRoaXMuX3hmYSgpLl94ZmFUZW1wbGF0ZUNhY2hlLmlkTWFwW2ZpZWxkSWRdOwogICAgICAgICAgICAgICAgdmFyIHJlc29sdmVkRmllbGQgPSBudWxsOwoKICAgICAgICAgICAgICAgIHZhciBiUXVpdCA9IGZhbHNlOwogICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gMDsKICAgICAgICAgICAgICAgIC8vVE9ETyA6IENhbiB3ZSBoYXZlIHByb2JsZW0gaW4gY29udGV4dCBvYmplY3Qgc2V0dGluZyB3aGlsZSBkb2luZyBpbmRleCBhZmZpbmUgcmVzb2x1dGlvbnMgPwogICAgICAgICAgICAgICAgd2hpbGUgKCFiUXVpdCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YXIgc29tID0gZmllbGQubmFtZSArICdbJyArIGluZGV4ICsgJ10nOwogICAgICAgICAgICAgICAgICAgIC8vdGhpcyB3aWxsIGJlIGRvbmUgaW4gdGhlIGNvbnRleHQgb2YgX3Jlc29sdmVGbG9hdGluZ0ZpZWxkCiAgICAgICAgICAgICAgICAgICAgdmFyIHByb2JGaWVsZCA9IHRoaXMucmVzb2x2ZU5vZGUoc29tKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIV8uaXNFbXB0eShwcm9iRmllbGQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9iRmllbGQuanNvbk1vZGVsLmlkID09PSBmaWVsZC5qc29uTW9kZWwuaWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJRdWl0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVkRmllbGQgPSBwcm9iRmllbGQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2tlZXAgbG9va2luZwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgeyAvL3RoaXMgd2lsbCBub3QgYmUgdXNlZCB2ZXJ5IG9mdGVuIGluIGZhY3QgSSBrZXB0IGl0IGp1c3QgZm9yIGNvbXBsZXRlbmVzcy4uLgogICAgICAgICAgICAgICAgICAgICAgICBiUXVpdCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlTmFtZSA9IHRoaXM7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vdmR1YSBzdWdnZXN0cyB0byB1c2UgeGZhLmZvcm0uLm5vZGVOYW1lIGluc3RlYWQgb2YgX2ZpbHRlck5vZGVzLgogICAgICAgICAgICAgICAgICAgICAgICAvL2l0IHRha2VzIGNhcmUgb2YgaW5kZXggYWZmaW5pdHkgYWxzbyB3aGljaCBpcyBhIGJpdCB1bnByZWRpY3RhYmxlCiAgICAgICAgICAgICAgICAgICAgICAgIC8vTGV0J3MgdHJ5IHRoaXMgaW4gbmV4dCBpdGVyYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRleHROb2RlcyA9IHRoaXMuX3hmYSgpLmZvcm0uX2ZpbHRlck5vZGVzKGZ1bmN0aW9uIChuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbi5uYW1lID09IG5vZGVOYW1lOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvY2N1cnJlbmNlVG9Mb29rRm9yID0gMDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29udGV4dE5vZGVzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29udGV4dE5vZGVzLml0ZW0oaSkgPT0gdGhpcykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jY3VycmVuY2VUb0xvb2tGb3IgPSBpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmxvYXRpbmdGaWVsZE5vZGVzID0gdGhpcy5feGZhKCkuZm9ybS5fZmlsdGVyTm9kZXMoZnVuY3Rpb24gKG4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuLm5hbWUgPT0gZmllbGQubmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2NjdXJyZW5jZSA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmb3VuZEF0TGVhc3RPbmVNYXRjaCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXhPZkZpcnN0Rm91bmQgPSAwOwoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBmbG9hdGluZ0ZpZWxkTm9kZXMubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcm9iRmllbGQgPSBmbG9hdGluZ0ZpZWxkTm9kZXMuaXRlbShqKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9iRmllbGQuanNvbk1vZGVsLmlkID09IGZpZWxkLmpzb25Nb2RlbC5pZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZm91bmRBdExlYXN0T25lTWF0Y2gpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4T2ZGaXJzdEZvdW5kID0gajsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3VuZEF0TGVhc3RPbmVNYXRjaCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9jY3VycmVuY2VUb0xvb2tGb3IgPT0gb2NjdXJyZW5jZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByb2JGaWVsZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvY2N1cnJlbmNlKys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3VuZEF0TGVhc3RPbmVNYXRjaCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmbG9hdGluZ0ZpZWxkTm9kZXMuaXRlbShpbmRleE9mRmlyc3RGb3VuZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGluZGV4Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZWRGaWVsZDsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUpzb25EaWZmOiBmdW5jdGlvbiAoZGlmZl9sZXZlbCkgewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLnN0cmlwT3JDYWxsLmNhbGwodGhpcywgZGlmZl9sZXZlbCA9PT0gMiwgeGZhbGliLnNjcmlwdC5Ob2RlLnByb3RvdHlwZS5fY29tcHV0ZUpzb25EaWZmLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIHBsYXlKc29uIDogZnVuY3Rpb24ocEpzb25Nb2RlbCkgewogICAgICAgICAgICAvL0RvIG5vdCBkbyBhbnkgcGxheUpzb24gZm9yIGRyYXcgY2hpbGRyZW4uIEl0IHNob3VsZCBub3QgaW1wYWN0IGZsb2F0aW5nIGZpZWxkcy4KICAgICAgICAgICAgeGZhbGliLnNjcmlwdC5Ob2RlLnByb3RvdHlwZS5wbGF5SnNvbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIF9wbGF5RGF0YVhNTDogZnVuY3Rpb24gKCkgewoKICAgICAgICB9LAoKICAgICAgICBnZW5lcmF0ZURhdGFYTUw6IGZ1bmN0aW9uIChyb290Tm9kZSwgY29udGV4dE5vZGUpIHsKCiAgICAgICAgfSwKCiAgICAgICAgX3Jlc29sdmVGbG9hdGluZ0ZpZWxkOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vQ2FuIHdlIHNvbWVob3cgc3RvcmUgZW1iZWRzIGFuZCBodG1sIHRleHQgaW4gRHJhdyBvYmplY3QgYW5kIGNvbXB1dGUgaXQgb3ZlciBhbmQgb3ZlciBhZ2FpbgogICAgICAgICAgICAvL21heSB3ZSBuZWVkIGFub3RoZXIgTm9kZVZhbHVlIHR5cGUgdG8gaGFuZGxlIGl0Pz8/PwoKICAgICAgICAgICAgaWYgKHRoaXMudmFsdWUpIHsKICAgICAgICAgICAgICAgIHZhciBjb250ZW50ID0gdGhpcy52YWx1ZS5vbmVPZkNoaWxkOwogICAgICAgICAgICAgICAgaWYgKGNvbnRlbnQuZ2V0QXR0cmlidXRlKCdjb250ZW50VHlwZScpID09PSAndGV4dC9odG1sJykgewogICAgICAgICAgICAgICAgICAgIGlmKF8uaXNOdWxsKGNvbnRlbnQuX29yaWdUbXBsdFZhbCkpewogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Ll9vcmlnVG1wbHRWYWwgPSBjb250ZW50Lmpzb25WYWx1ZTsgLy8gc2F2ZSBvcmlnaW5hbCB0ZW1wbGF0ZSBpbmZvIGNvbnRhaW5pbmcgdGhlIGVtYmVkIHRhZ3MKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdmFyIGlzVGV4dEVtYmVkcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICB0aGF0ID0gdGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgaHRtbFRleHQgPSBjb250ZW50Ll9vcmlnVG1wbHRWYWw7CiAgICAgICAgICAgICAgICAgICAgaHRtbFRleHQgPSBodG1sVGV4dC5yZXBsYWNlQWxsKCI8L2JyPiIsIiIpOwogICAgICAgICAgICAgICAgICAgIHZhciAkaW50ZXJuYWxIVE1MID0gJCgnPHNwYW4+JyArIGh0bWxUZXh0ICsgJzwvc3Bhbj4nKTsKICAgICAgICAgICAgICAgICAgICAvL2NoYW5nZSB0aGUgdG9wIGxldmVsIGVsZW1lbnQgdG8gc3BhbiB0byB3cmFwIHVwIGFsbCB0aGUgPHA+LCBiZWNhdXNlIGl0IHdpbGwgY2F1c2UgdW5uZWNlc3NhcnkgcGFyYWdyYXBoIGJyZWFrCgogICAgICAgICAgICAgICAgICAgIC8vbm8gbnVsbCBjaGVjayBiZWNhdXNlIGpRdWVyeSBpcyBjb29sIQogICAgICAgICAgICAgICAgICAgICRpbnRlcm5hbEhUTUwuZmluZCgicCIpLmVxKDApLmNzcygnZGlzcGxheScsICdpbmxpbmUnKTsKCiAgICAgICAgICAgICAgICAgICAgJGludGVybmFsSFRNTC5maW5kKCdbeGZhXFw6ZW1iZWRdJykuZWFjaChmdW5jdGlvbiAoaW5kZXgsIHNwYW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXNUZXh0RW1iZWRzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyICRzcGFuID0gJChzcGFuKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVtYmVkID0gJHNwYW4uYXR0cigneGZhOmVtYmVkJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbWJlZFR5cGUgPSAkc3Bhbi5hdHRyKCd4ZmE6ZW1iZWRUeXBlJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbWJlZE1vZGUgPSAkc3Bhbi5hdHRyKCd4ZmE6ZW1iZWRNb2RlJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbWJlZCAmJiBlbWJlZC5sZW5ndGggPiAxICYmIGVtYmVkWzBdID09ICcjJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1iZWQgPSBlbWJlZC5zdWJzdHIoMSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc29sdmUgTm9kZSB3aWxsIHRha2UgY2FyZSBvZiBpbmRleCBhZmZpbml0eSBoZXJlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmllbGQgPSAoZW1iZWRUeXBlID09ICd1cmknKSA/IHRoYXQuX2dldEZpZWxkQnlJZChlbWJlZCkgOiB0aGF0LnJlc29sdmVOb2RlKGVtYmVkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbWJlZE1vZGUgPT09ICdyYXcnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZC5yYXdWYWx1ZSA9PSBudWxsKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNwYW4ucmVwbGFjZVdpdGgoZmllbGQucmF3VmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc3Bhbi5yZXBsYWNlV2l0aCgkLnBhcnNlSFRNTCh4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZW5jb2RlU2NyaXB0YWJsZVRhZ3MoZmllbGQucmF3VmFsdWUudG9TdHJpbmcoKSkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkc3Bhbi5yZXBsYWNlV2l0aCh4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZW5jb2RlU2NyaXB0YWJsZVRhZ3MoZmllbGQuZm9ybWF0dGVkVmFsdWUudG9TdHJpbmcoKSkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5feGZhKCkuTG9nZ2VyLmRlYnVnKCJ4ZmEiLCAicmVmZXJyZWQgZmllbGQgd2l0aCBpZCAiICsgZW1iZWQgKyAiIGRvZXNuJ3QgZXhpc3QuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNwYW4ucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll94ZmEoKS5Mb2dnZXIuZGVidWcoInhmYSIsICJyZWZlcnJlZCBmaWVsZCB3aXRoIGludmFsaWQgaWQgIiArIGVtYmVkICsgIiBkb2Vzbid0IGV4aXN0LiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHNwYW4ucmVtb3ZlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgLy9pc1RleHRFbWJlZHMgaXMgc2V0IHRvIHRydWUgaWYgdGhlcmUgaXMgYW55IGVtYmVkZGVkIHRleHQgZmllbGQuCiAgICAgICAgICAgICAgICAgICAgaWYgKGlzVGV4dEVtYmVkcykgewogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50Lmpzb25WYWx1ZSA9ICI8c3Bhbj4iICsgJGludGVybmFsSFRNTC5odG1sKCkgKyAiPC9zcGFuPiI7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHBhZ2VzIG1heSBub3QgeWV0IGJlIHJlbmRlcmVkLCBidXQgaW5pdGlhbGl6ZSBjYWxsZWQgZHVlIHRvICJpbml0aWFsIGNvdW50IiBvZiBycHQuIFNGCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlY29yZCB1cGRhdGVkIHZhbHVlIHRvIGJlIGFwcGxpZWQgaW4gX3N5bmNGb3JtTm9kZVRvSHRtbCBkdXJpbmcgcGcuIHJlbmRlcgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHNjb3BlbGVzczogZnVuY3Rpb24gKCkgeyAvL1tMQy04ODAxXSBET00gUHJvcGVydGllcyBvZiBkcmF3IGdldHMgaW5jb3JyZWN0bHkgYXR0YWNoZWQKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIF9ldmVudEhhbmRsZXI6IGZ1bmN0aW9uIChldmVudE5hbWUpIHsKICAgICAgICAgICAgLy93YW50IHRvIGhhbmRsZSBvbmx5IGNhbGN1bGF0ZSBldmVudCB0aGF0IHRvbyBpbiBjYXNlIG9mIGRyYXcgdGV4dAogICAgICAgICAgICBpZiAodGhpcy51aSAmJiB0aGlzLnVpLm9uZU9mQ2hpbGQgJiYgdGhpcy51aS5vbmVPZkNoaWxkLmNsYXNzTmFtZSA9PSAndGV4dEVkaXQnKSB7CiAgICAgICAgICAgICAgICB2YXIgclZhbHVlID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgc3dpdGNoIChldmVudE5hbWUpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJjYWxjdWxhdGUiOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl0gJiYgdGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl0ubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl1bMF0uZXhlY3V0ZSh0aGlzLCAiY2FsY3VsYXRlIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdCA6CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBEcmF3Ll9zdXBlci5fZXZlbnRIYW5kbGVyLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gclZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBEcmF3Ll9zdXBlci5fZXZlbnRIYW5kbGVyLmNhbGwodGhpcyk7CgogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFJldHVybiB0aGUgRGF0YVNPTU1hcCBhZnRlciBhZGRpbmcgYW4gZW50cnkgaW4gdGhlIG1hcCBmb3IgdGhlIG5vZGUuIFRoZSBlbnRyeSBjb250YWlucyB0aGUgdmFsdWUgb2YgdGhlIG5vZGUKICAgICAgICAgKiBhbG9uZyB3aXRoIGl0cyBEYXRhIFNPTS4gSWYgdGhlcmUgaXMgbm8gRGF0YSBTT00gdGhlbiByZXR1cm4gdGhlIHVubW9kaWZpZWQgbWFwCiAgICAgICAgICogQHBhcmFtIG1hcAogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICovCiAgICAgICAgX2dldERhdGFTb21NYXA6IGZ1bmN0aW9uIChtYXApIHsKICAgICAgICAgICAgcmV0dXJuIG1hcDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBVcGRhdGUgdGhlIHZhbHVlIG9mIHRoZSBub2RlIHdpdGggdGhlIHZhbHVlIHByb3ZpZGVkIGluIHRoZSBpbnB1dCBtYXAuIFRoZSBtYXAgY29udGFpbnMgdGhlIHZhbHVlcyBvZiB0aGUgZmllbGRzCiAgICAgICAgICogbWFwcGVkIHdpdGggdGhlaXIgRGF0YVNPTS4gVGhlIGZ1bmN0aW9uIGlzIGVtcHR5IGZvciBhbGwgdGhlIG5vZGVzLCBleGNlcHQgZm9yIEZpZWxkLCBTdWJmb3JtIGFuZCBBcmVhLgogICAgICAgICAqIEBwYXJhbSBtYXAKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9yZXN0b3JlRGF0YVNvbU1hcCA6IGZ1bmN0aW9uIChtYXApIHsKCiAgICAgICAgfQogICAgfSk7CgogICAgRHJhdy5kZWZpbmVQcm9wcyh7CiAgICAgICAgInJhd1ZhbHVlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRWYWx1ZSgpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChzVmFsdWUpIHsKICAgICAgICAgICAgICAgIHZhciBvbGR2YWwgPSB0aGlzLl9nZXRWYWx1ZSgpOwogICAgICAgICAgICAgICAgc1ZhbHVlID0gdGhpcy52YWxpZGF0ZUlucHV0KHNWYWx1ZSwgInN0cmluZyIpOwogICAgICAgICAgICAgICAgdGhpcy5fc2V0VmFsdWUoc1ZhbHVlKTsKICAgICAgICAgICAgICAgIHZhciBldmVudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELCB0aGlzLCAncmF3VmFsdWUnLCBudWxsLCBzVmFsdWUpOwogICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2ZW50Lm5hbWUsIGV2ZW50KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHVpOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgidWkiLCAwKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJ1aSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImZvbnQiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICB0aGlzLmdldEVsZW1lbnQoImZvbnQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImZvbnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJ2YWx1ZSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIHRoaXMuZ2V0RWxlbWVudCgidmFsdWUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsLCAidmFsdWUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJkZXNjIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImRlc2MiLCAwKQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgRHJhdy5hZGRNaXhpbnMoWwogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQXNzaXN0LAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQ2FwdGlvbiwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFhZV0gsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRQcmVzZW5jZSwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZEJvcmRlciwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFBhcmEsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRNYXJnaW4KICAgIF0pOwoKfSkoXywgeGZhbGliLCAkKTsKCgoKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5EYXRlVGltZUZpZWxkCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5GaWVsZAogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIERhdGUgVGltZSBGaWVsZCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBEYXRlIFRpbWUgRmllbGQgY2xhc3MKICAgICAqCiAgICAgKiBAY29uc3RydWN0b3IKICAgICAqIEBwYXJhbSB7c3RyaW5nfQogICAgICAgICogICAgICAgICAgICBuYW1lIHRoZSBuYW1lIG9mIHRoZSBGaWVsZAogICAgICogQHBhcmFtIHtzdHJpbmd9CiAgICAgICAgKiAgICAgICAgICAgIHJhd1ZhbCBpbml0aWFsIHZhbHVlIG9mIHRoZSBGaWVsZAogICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHJhd1ZhbCByZXByZXNlbnRzIHRoZSBkYXRhIHZhbHVlIGluIHRoZSBub2RlCiAgICAgKiBAZXh0ZW5kcyBjb20uYWRvYmUueGZhLnNjcmlwdGluZy5Ob2RlCiAgICAgKi8KICAgIHZhciBEYXRlVGltZUZpZWxkID0geGZhbGliLnNjcmlwdC5EYXRlVGltZUZpZWxkID0geGZhbGliLnNjcmlwdC5GaWVsZC5leHRlbmQoewogICAgICAgIF9nZXREZWZhdWx0UGljdHVyZUNsYXVzZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIC8vd2F0c29uIGJ1ZyMzNjcyMzY0IGFuZCAzNjcyMzY3LgogICAgICAgICAgICAvL1N0YXJ0IHJlYWRpbmcgY2FsZW5kYXIgcGljdHVyZSBmb3JtYXQgZnJvbSB0aGUgbG9jYWxlc2V0LgogICAgICAgICAgICBpZih0aGlzLnZhbHVlLm9uZU9mQ2hpbGQuY2xhc3NOYW1lID09PSAiZGF0ZSIpCiAgICAgICAgICAgICAgICByZXR1cm4gImRhdGV7Iit0aGlzLl94ZmEoKS5fZ2V0TG9jYWxlU3ltYm9scyh0aGlzLmxvY2FsZSwiZGF0ZVBhdHRlcm5zIikubWVkKyJ9IjsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuICIiOwogICAgICAgIH0sCgogICAgICAgIF9zZXRWYWx1ZTogZnVuY3Rpb24gKHNWYWwsIHNraXBUeXBlQ2hlY2spIHsKICAgICAgICAgICAgcmV0dXJuIERhdGVUaW1lRmllbGQuX3N1cGVyLl9zZXRWYWx1ZS5jYWxsKHRoaXMsIHNWYWwsIHNraXBUeXBlQ2hlY2spOwogICAgICAgIH0sCgogICAgICAgIF9zaG93RGlzcGxheUZvcm1hdDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgZm9ybWF0dGVkVmFsdWUgPSB0aGlzLmZvcm1hdHRlZFZhbHVlLAogICAgICAgICAgICAgICAgcmF3VmFsdWUgPSB0aGlzLnJhd1ZhbHVlOwogICAgICAgICAgICAvLyBpZiBmb3JtYXR0ZWRWYWx1ZSBpcyBudWxsIHRoZW4gc2hvdyByYXdWYWx1ZSBpbiB3aWRnZXQgYWxvbmcgd2l0aCBlcnJvciBtZXNzYWdlCiAgICAgICAgICAgIGlmICghZm9ybWF0dGVkVmFsdWUpIHsKICAgICAgICAgICAgICAgIGZvcm1hdHRlZFZhbHVlID0gcmF3VmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwgdGhpcywKICAgICAgICAgICAgICAgICdyYXdWYWx1ZScsIHJhd1ZhbHVlLCBmb3JtYXR0ZWRWYWx1ZSk7CiAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsIGV2bnQpOwogICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5OdW1lcmljRmllbGQKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LkZpZWxkCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgTnVtZXJpYyBGaWVsZCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBOdW1lcmljIEZpZWxkIGNsYXNzCiAgICAgKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgRmllbGQKICAgICAqIEBwYXJhbSB7c3RyaW5nfQogICAgICAgICogICAgICAgICAgICByYXdWYWwgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgRmllbGQKICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByYXdWYWwgcmVwcmVzZW50cyB0aGUgZGF0YSB2YWx1ZSBpbiB0aGUgbm9kZQogICAgICogQGV4dGVuZHMgY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuTm9kZQogICAgICovCiAgICB2YXIgTnVtZXJpY0ZpZWxkID0geGZhbGliLnNjcmlwdC5OdW1lcmljRmllbGQgPSB4ZmFsaWIuc2NyaXB0LkZpZWxkLmV4dGVuZCh7CiAgICAgICAgIF9nZXREZWZhdWx0UGljdHVyZUNsYXVzZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiAibnVteyIrdGhpcy5feGZhKCkuX2dldExvY2FsZVN5bWJvbHModGhpcy5sb2NhbGUsIm51bWJlclBhdHRlcm5zIikubnVtZXJpYysifSI7CiAgICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5CdXR0b25GaWVsZAogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuRmllbGQKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBCdXR0b24gRmllbGQgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQQogKiAgICAgICAgICAgICAgIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJ1dHRvbkZpZWxkID0geGZhbGliLnNjcmlwdC5CdXR0b25GaWVsZCA9IHhmYWxpYi5zY3JpcHQuRmllbGQuZXh0ZW5kKHsKICAgICAgICBfY29tcHV0ZUpzb25EaWZmOiBmdW5jdGlvbiAoZGlmZl9sZXZlbCkgewogICAgICAgICAgICAvL3dlIGRvbid0IHdhbnQgYnV0dG9uIHRvIGFwcGVhciBpbiBmaW5hbCBzdWJtaXQsIGJ1dCBmb3IgcmVzdG9yZUZvcm1TdGF0ZQogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLnN0cmlwT3JDYWxsLmNhbGwodGhpcywgZGlmZl9sZXZlbCA9PT0gMiwgQnV0dG9uRmllbGQuX3N1cGVyLl9jb21wdXRlSnNvbkRpZmYsIGFyZ3VtZW50cyk7CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYik7CgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5DaGVja0J1dHRvbkZpZWxkCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5GaWVsZAogKi8KLyoqCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgQ2hlY2tCdXR0b24gRmllbGQgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQQogKiAgICAgICAgICAgICAgIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBDaGVja0J1dHRvbkZpZWxkIEZpZWxkIGNsYXNzCiAgICAgKgogICAgICogQGNvbnN0cnVjdG9yCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgRmllbGQKICAgICAqIEBwYXJhbSB7c3RyaW5nfQogICAgICAgICogICAgICAgICAgICByYXdWYWwgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgRmllbGQKICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByYXdWYWwgcmVwcmVzZW50cyB0aGUgZGF0YSB2YWx1ZSBpbiB0aGUgbm9kZQogICAgICogQGV4dGVuZHMgY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuTm9kZQogICAgICovCiAgICB2YXIgQ2hlY2tCdXR0b25GaWVsZCA9IHhmYWxpYi5zY3JpcHQuQ2hlY2tCdXR0b25GaWVsZCA9IHhmYWxpYi5zY3JpcHQuRmllbGQuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgQ2hlY2tCdXR0b25GaWVsZC5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLl9vbiA9IDA7CiAgICAgICAgICAgIHRoaXMuX29mZiA9IDE7CiAgICAgICAgICAgIHRoaXMuX25ldXRyYWwgPSAyOwogICAgICAgIH0sCgogICAgICAgIGFkZEl0ZW0gOiBmdW5jdGlvbihzRGlzcGxheVZhbCwgc1NhdmVWYWwpIHsKICAgICAgICAgICAgaWYgKHRoaXMubGVuZ3RoID09IHRoaXMuX2dldE1heEl0ZW1zKCkpCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIENoZWNrQnV0dG9uRmllbGQuX3N1cGVyLmFkZEl0ZW0uY2FsbCh0aGlzLCBzRGlzcGxheVZhbCwgc1NhdmVWYWwpOwogICAgICAgIH0sCgogICAgICAgIF9nZXRNYXhJdGVtcyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hbGxvd05ldXRyYWwoKSA/IDMgOiAyOwogICAgICAgIH0sCgogICAgICAgIF9hbGxvd05ldXRyYWwgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy51aS5vbmVPZkNoaWxkLmFsbG93TmV1dHJhbCA9PSAxID8gdHJ1ZSA6IGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVEZXBlbmRhbnRzIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIENoZWNrQnV0dG9uRmllbGQuX3N1cGVyLl9oYW5kbGVEZXBlbmRhbnRzLmNhbGwodGhpcyk7CiAgICAgICAgICAgIGlmICh0aGlzLnBhcmVudC5faXNFeGNsdXNpb25Hcm91cCgpKSB7CiAgICAgICAgICAgICAgICB0aGlzLnBhcmVudC5faGFuZGxlU2VsZWN0Q2hpbGQodGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sIHhmYWxpYik7Ci8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LkNob2ljZUxpc3RGaWVsZAogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuRmllbGQKICovCi8qKgogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIENob2ljZUxpc3QgRmllbGQgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQQogKiAgICAgICAgICAgICAgIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgoKKGZ1bmN0aW9uKF8sIHhmYWxpYiwgJCl7CiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgQ2hvaWNlTGlzdCBGaWVsZCBjbGFzcwogICAgICoKICAgICAqIEBjb25zdHJ1Y3RvcgogICAgICogQHBhcmFtIHtzdHJpbmd9CiAgICAgICAgKiAgICAgICAgICAgIG5hbWUgdGhlIG5hbWUgb2YgdGhlIEZpZWxkCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAqICAgICAgICAgICAgcmF3VmFsIGluaXRpYWwgdmFsdWUgb2YgdGhlIEZpZWxkCiAgICAgKiBAcHJvcGVydHkge3N0cmluZ30gcmF3VmFsIHJlcHJlc2VudHMgdGhlIGRhdGEgdmFsdWUgaW4gdGhlIG5vZGUKICAgICAqIEBleHRlbmRzIGNvbS5hZG9iZS54ZmEuc2NyaXB0aW5nLk5vZGUKICAgICAqLwogICAgdmFyIENob2ljZUxpc3RGaWVsZCA9IHhmYWxpYi5zY3JpcHQuQ2hvaWNlTGlzdEZpZWxkID0geGZhbGliLnNjcmlwdC5GaWVsZC5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBDaG9pY2VMaXN0RmllbGQuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgLy8gdG8gaGFuZGxlIHRoZSBzY2VuYXJpbyB3aGVyZSBiaW5kUmVmIGl0ZW1zIHdlcmUgbm90IGdldHRpbmcgcG9wdWxhdGVkIG9uIGFkZGluZyBuZXcgaW5zdGFuY2UKICAgICAgICAgICAgaWYgKHRoaXMuZ2V0RWxlbWVudCgiI2JpbmRJdGVtcyIpICYmIHhmYWxpYi5ydW50aW1lLnJlbmRlckNvbnRleHQuZGF0YSkgewogICAgICAgICAgICAgICAgdmFyIHByZWZpbGxYbWxEb2MgPSB4ZmFsaWIudXQuWE1MVXRpbHMuZ2V0WEZBUm9vdEZvcm1FbGVtZW50RnJvbVhNTCgkLnBhcnNlWE1MKHhmYWxpYi5ydW50aW1lLnJlbmRlckNvbnRleHQuZGF0YSkpOwogICAgICAgICAgICAgICAgdGhpcy5fcGxheUl0ZW1zKHByZWZpbGxYbWxEb2MsIG51bGwpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2NvbnZlcnRWYWx1ZVRvWG1sOiBmdW5jdGlvbih2YWwpIHsKICAgICAgICAgICBpZih2YWwgPT0gbnVsbCB8fCB2YWwubGVuZ3RoID09IDApCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbAogICAgICAgICAgIHZhciB4bWwgPSAiPCIrdGhpcy5uYW1lKyI+IgogICAgICAgICAgIF8uZWFjaCgodmFsKyIiKS5zcGxpdCgiXG4iKSxmdW5jdGlvbih2YWx1ZSkgewogICAgICAgICAgICAgICBpZih2YWx1ZSAmJiB2YWx1ZS5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgICAgIHhtbCArPSI8dmFsdWU+Iit2YWx1ZSsiPC92YWx1ZT4iCiAgICAgICAgICAgIH0pCiAgICAgICAgICAgIHhtbCArPSAiPC8iK3RoaXMubmFtZSsiPiIKICAgICAgICAgICAgcmV0dXJuIHhtbAogICAgICAgIH0sCgogICAgICAgIF9nZXRUZXh0OiBmdW5jdGlvbih4bWwsc2VwLCQpIHsKICAgICAgICAgICAgdmFyIHJlY1RleHQgPSBmdW5jdGlvbihvYmosYXJyKSB7CiAgICAgICAgICAgICAgICBpZihvYmouY2hpbGRyZW4oKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBvYmouY2hpbGRyZW4oKS5tYXAoZnVuY3Rpb24oaW5keCxjaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICByZWNUZXh0KCQoY2hpbGQpLGFycik7CiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYXJyLnB1c2gob2JqLnRleHQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHZhciBhcnIgPSBbXTsKICAgICAgICAgICAgcmVjVGV4dCgkKCQucGFyc2VYTUwoeG1sKSksYXJyKTsKICAgICAgICAgICAgcmV0dXJuIGFyci5qb2luKHNlcCk7CiAgICAgICAgfSwKCiAgICAgICAgX2NvbnZlcnRYbWxUb1ZhbHVlOiBmdW5jdGlvbigkeG1sKSB7CiAgICAgICAgICAgIGlmKCR4bWwgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0VGV4dCgkeG1sLCJcbiIsJCk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldFZhbHVlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IENob2ljZUxpc3RGaWVsZC5fc3VwZXIuX2dldFZhbHVlLmFwcGx5KHRoaXMsIHRoaXMuX211bHRpU2VsZWN0KCkgPyBbInRleHQveG1sIl0gOiBbXSk7CiAgICAgICAgICAgIGlmKHRoaXMuX211bHRpU2VsZWN0KCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fY29udmVydFhtbFRvVmFsdWUodmFsdWUpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUKICAgICAgICB9LAoKICAgICAgICBfc2V0VmFsdWUgOiBmdW5jdGlvbihzVmFsKSB7CiAgICAgICAgICAgIGlmKHRoaXMuX211bHRpU2VsZWN0KCkpCiAgICAgICAgICAgICAgICBzVmFsID0gdGhpcy5fY29udmVydFZhbHVlVG9YbWwoc1ZhbCk7CiAgICAgICAgICAgIHJldHVybiBDaG9pY2VMaXN0RmllbGQuX3N1cGVyLl9zZXRWYWx1ZS5hcHBseSh0aGlzLFtzVmFsXSk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0SXRlbVN0YXRlIDogZnVuY3Rpb24obkluZGV4KSB7CiAgICAgICAgICAgIGlmICh0aGlzLl9tdWx0aVNlbGVjdCgpICE9PSBmYWxzZSkgewogICAgICAgICAgICAgICAgdmFyIHNhdmVWYWx1ZSA9IHRoaXMuZ2V0U2F2ZUl0ZW0obkluZGV4KTsKICAgICAgICAgICAgICAgIGlmKHNhdmVWYWx1ZSE9PSBudWxsICYmIHNhdmVWYWx1ZSE9PSB1bmRlZmluZWQpewogICAgICAgICAgICAgICAgICAgIHNhdmVWYWx1ZSA9ICIiK3NhdmVWYWx1ZTsKICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWVBcnJheSA9ICh0aGlzLnJhd1ZhbHVlICsgIiIpLnNwbGl0KCJcbiIpOwogICAgICAgICAgICAgICAgICAgIHZhciBjdXJyZW50VmFsSW5kZXggPSB0aGlzLnhmYVV0aWwoKS5kSW5kZXhPZih2YWx1ZUFycmF5LHNhdmVWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRWYWxJbmRleCA+PSAwOwogICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vIFRPRE86IHJldHVybiBudWxsIG9yIGZhbHNlCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gQ2hvaWNlTGlzdEZpZWxkLl9zdXBlci5nZXRJdGVtU3RhdGUuY2FsbCh0aGlzLCBuSW5kZXgpOwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIC8vIHJldHVybnMgYXJyYXkgb2YgaW5kaWNlcyBjb3JyZXNwb25kaW5nIHRvIHNlbGVjdGVkIHZhbHVlCiAgICAgICAgX3NlbGVjdGVkTGFzdEluZGljZXMgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIGl0ZW1TaXplID0gdGhpcy5sZW5ndGgsCiAgICAgICAgICAgICAgICBsYXN0U2VsZWN0ZWRJbmRpY2VzID0gW107CgogICAgICAgICAgICBmb3IgKHZhciBpPTA7IGk8IGl0ZW1TaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmdldEl0ZW1TdGF0ZShpKSkgewogICAgICAgICAgICAgICAgICAgIGxhc3RTZWxlY3RlZEluZGljZXMucHVzaChpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbGFzdFNlbGVjdGVkSW5kaWNlczsKICAgICAgICB9LAoKICAgICAgICAvLyByZXR1cm5zIGRpc3BsYXkgdmFsdWUgY29ycmVzcG9uZGluZyB0byBzZWxlY3RlZCB2YWx1ZQogICAgICAgIF9mb3JtYXRWYWx1ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgbGFzdFNlbGVjdGVkSW5kaWNlcyA9IHRoaXMuX3NlbGVjdGVkTGFzdEluZGljZXMoKTsKICAgICAgICAgICAgcmV0dXJuIGxhc3RTZWxlY3RlZEluZGljZXMubWFwKCBmdW5jdGlvbiAoc2VsSW5kZXgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldERpc3BsYXlJdGVtKHNlbEluZGV4KTsKICAgICAgICAgICAgfSwgdGhpcykuam9pbigiXG4iKTsKICAgICAgICB9LAoKICAgICAgICBfbXVsdGlTZWxlY3QgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy51aS5vbmVPZkNoaWxkLm9wZW4gPT0gIm11bHRpU2VsZWN0IiA/IHRydWUgOiBmYWxzZTsKICAgICAgICB9LAoKCgogICAgICAgIHNldEl0ZW1TdGF0ZSA6IGZ1bmN0aW9uKG5JbmRleCwgYlZhbCkgewogICAgICAgICAgICBpZiAodGhpcy5fbXVsdGlTZWxlY3QoKSAhPT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIHZhciBzYXZlVmFsdWUgPSB0aGlzLmdldFNhdmVJdGVtKG5JbmRleCk7CiAgICAgICAgICAgICAgICBpZihzYXZlVmFsdWUgIT09IG51bGwgJiYgc2F2ZVZhbHVlICE9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICBzYXZlVmFsdWUgPSAiIitzYXZlVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlQXJyYXkgPSAodGhpcy5yYXdWYWx1ZSArICIiKS5zcGxpdCgiXG4iKTsKICAgICAgICAgICAgICAgICAgICB2YXIgY3VycmVudFZhbEluZGV4ID0gdGhpcy54ZmFVdGlsKCkuZEluZGV4T2YodmFsdWVBcnJheSxzYXZlVmFsdWUpOyAvKml0ZW0gdmFsdWUgaXMgdHlwZWQgc28gY29udmVydGluZyBpdCB0byBzdHJpbmcgZm9yIG1hdGNoaW5nICovCiAgICAgICAgICAgICAgICAgICAgaWYoYlZhbCAmJiBjdXJyZW50VmFsSW5kZXggPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzYXZlSXRlbXMgPSB0aGlzLl9nZXRTYXZlSXRlbXMoKS5jaGlsZHJlbgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3VmFsQXJyYXkgPSBfLnJlZHVjZShzYXZlSXRlbXMsZnVuY3Rpb24obWVtbyxpdGVtKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy54ZmFVdGlsKCkuZEluZGV4T2YodmFsdWVBcnJheSxpdGVtLnZhbHVlKSA+PSAwIHx8IGl0ZW0udmFsdWUgPT0gc2F2ZVZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1vLnB1c2goaXRlbS52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1lbW8KICAgICAgICAgICAgICAgICAgICAgICAgfSxbXSx0aGlzKQogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZUFycmF5ID0gbmV3VmFsQXJyYXk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoIWJWYWwgJiYgY3VycmVudFZhbEluZGV4ID49MCkKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVBcnJheS5zcGxpY2UoY3VycmVudFZhbEluZGV4LCAxKQogICAgICAgICAgICAgICAgICAgIHRoaXMucmF3VmFsdWUgPSB2YWx1ZUFycmF5LmpvaW4oIlxuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBDaG9pY2VMaXN0RmllbGQuX3N1cGVyLnNldEl0ZW1TdGF0ZS5jYWxsKHRoaXMsIG5JbmRleCwgYlZhbCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfcGxheURhdGFYTUw6IGZ1bmN0aW9uICh4bWxEb2N1bWVudCwgY29udGV4dE5vZGUsIGN1cnJlbnRCaW5kUmVmKSB7CiAgICAgICAgICAgIHZhciB4cGF0aCA9IHRoaXMuX2dldFhwYXRoRnJvbUJpbmRSZWYoKSwKICAgICAgICAgICAgICAgIHZhbHVlLCBub2RlSXRlciwgbm9kZTsKICAgICAgICAgICAgaWYoeHBhdGggIT0gbnVsbCkgewogICAgICAgICAgICAgICAgaWYodGhpcy5fbXVsdGlTZWxlY3QoKSkgewogICAgICAgICAgICAgICAgICAgIC8vIGluIGNhc2Ugb2YgbXVsdGlzZWxlY3QgdGhlIHZhbHVlIGlzIHhtbCBhbmQgaGVuY2UgbmVlZHMgc3BlY2lhbCBwcm9jZXNzaW5nCiAgICAgICAgICAgICAgICAgICAgbm9kZUl0ZXIgPSB0aGlzLl9nZXRFbGVtZW50c0Zyb21YcGF0aCh4cGF0aCwgY29udGV4dE5vZGUsIHhtbERvY3VtZW50KTsKICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZSA9IG5vZGVJdGVyLml0ZXJhdGVOZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgaWYobm9kZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbmV3IFhNTFNlcmlhbGl6ZXIoKS5zZXJpYWxpemVUb1N0cmluZyhub2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgQ2hvaWNlTGlzdEZpZWxkLl9zdXBlci5fc2V0VmFsdWUuYXBwbHkodGhpcyxbdmFsdWVdKTsKICAgICAgICAgICAgICAgICAgICAgICAgLy90b2RvOiBJZiB3ZSBtb3ZlIHByb2Nlc3Npbmcgb2YgZGF0YSB4bWwgYmVmb3JlIHZpZXcKICAgICAgICAgICAgICAgICAgICAgICAgLy9nZW5lcmF0aW9uIHRoZW4gc2hvd0Rpc3BsYXlGb3JtYXQgY2FsbCB3aWxsIG5vdCBiZSBuZWVkZWQuCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Nob3dEaXNwbGF5Rm9ybWF0KCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBDaG9pY2VMaXN0RmllbGQuX3N1cGVyLl9wbGF5RGF0YVhNTC5hcHBseSh0aGlzLCBbeG1sRG9jdW1lbnQsIGNvbnRleHROb2RlLCBjdXJyZW50QmluZFJlZl0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuX3BsYXlJdGVtcyh4bWxEb2N1bWVudCwgY29udGV4dE5vZGUpOwogICAgICAgIH0sCgogICAgICAgIF9wbGF5SXRlbXM6IGZ1bmN0aW9uICh4bWxEb2N1bWVudCwgY29udGV4dE5vZGUpIHsKICAgICAgICAgICAgdmFyIGJpbmRJdGVtcyA9IHRoaXMuZ2V0RWxlbWVudCgiI2JpbmRJdGVtc1swXSIpOwogICAgICAgICAgICBpZiAoYmluZEl0ZW1zICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIHZhciBjb25uZWN0aW9uID0gYmluZEl0ZW1zLmNvbm5lY3Rpb247CiAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvbiA9PSBudWxsIHx8IGNvbm5lY3Rpb24ubGVuZ3RoID09IDApIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcmVmID0gYmluZEl0ZW1zLnJlZjsKICAgICAgICAgICAgICAgICAgICBpZiAocmVmICE9IG51bGwgJiYgcmVmLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHhwYXRoID0gdGhpcy5fY29udmVydFJlZlRvWFBhdGgocmVmKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHhwYXRoICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpdGVtTm9kZXMgPSB0aGlzLl9nZXRFbGVtZW50c0Zyb21YcGF0aCh4cGF0aCwgY29udGV4dE5vZGUsIHhtbERvY3VtZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtTm9kZXMgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYXJJdGVtcygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpdGVtTm9kZSA9IGl0ZW1Ob2Rlcy5pdGVyYXRlTmV4dCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4bWxVdGlscyA9IHhmYWxpYi51dC5YTUxVdGlsczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaXRlbU5vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1RPRE86IHN1cHBvcnQgdmFsdWVSZWYvbGFiZWxSZWYgd2l0aCB4UGF0aCBoYXZpbmcgbW9yZSB0aGFuIG9uZSBlbGVtZW50CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFuZCB2YWx1ZVJlZi9sYWJlbFJlZiBwb2ludGluZyB0byBhbiBhdHRyaWJ1dGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlTm9kZVJlc3VsdCA9IHhtbFV0aWxzLmV2YWx1YXRlWFBhdGgoYmluZEl0ZW1zLnZhbHVlUmVmLCBpdGVtTm9kZSwgbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhQYXRoUmVzdWx0Lk9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlTm9kZVJlc3VsdCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbGFiZWxOb2RlUmVzdWx0ID0gdmFsdWVOb2RlUmVzdWx0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJpbmRJdGVtcy5sYWJlbFJlZikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsTm9kZVJlc3VsdCA9IHhtbFV0aWxzLmV2YWx1YXRlWFBhdGgoYmluZEl0ZW1zLmxhYmVsUmVmLCBpdGVtTm9kZSwgbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWFBhdGhSZXN1bHQuT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEUsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlTm9kZSA9IHZhbHVlTm9kZVJlc3VsdC5pdGVyYXRlTmV4dCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodmFsdWVOb2RlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbGFiZWxOb2RlID0gbGFiZWxOb2RlUmVzdWx0ID8gbGFiZWxOb2RlUmVzdWx0Lml0ZXJhdGVOZXh0KCkgOiBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGxhYmVsTm9kZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsTm9kZSA9IHZhbHVlTm9kZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuTG9nZ2VyLndhcm4oInhmYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxhYmVsUmVmIGRvZXNuJ3QgZXhpc3QgZm9yIFsiICsgdGhpcy5zb21FeHByZXNzaW9uICsgIiwiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBiaW5kSXRlbXMucmVmICsgIiwiICsgYmluZEl0ZW1zLmxhYmVsUmVmICsgIl0iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRJdGVtKGxhYmVsTm9kZS50ZXh0Q29udGVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVOb2RlLnRleHRDb250ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuTG9nZ2VyLmVycm9yKCJ4ZmEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInZhbHVlUmVmIGRvZXNuJ3QgZXhpc3QgZm9yIFsiICsgdGhpcy5zb21FeHByZXNzaW9uICsgIiwiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBiaW5kSXRlbXMucmVmICsgIiwiICsgYmluZEl0ZW1zLmxhYmVsUmVmICsgIl0iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLkxvZ2dlci5lcnJvcigieGZhIiwgInZhbHVlUmVmIHBvaW50cyB0byBhbiBpbnZhbGlkIHhtbCBlbGVtZW50ICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIGJpbmRJdGVtcy52YWx1ZVJlZik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1Ob2RlID0gaXRlbU5vZGVzLml0ZXJhdGVOZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5Mb2dnZXIud2FybigieGZhIiwgImNvbm5lY3Rpb24gaW4gYmluZEl0ZW1zIGlzIG5vdCBzdXBwb3J0ZWQgaW4gRm9ybXNldCIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2FwcGVuZFZhbHVlSW5YTUxFbGVtZW50OiBmdW5jdGlvbiAoZWxlbWVudCkgewogICAgICAgICAgICBpZighdGhpcy5fbXVsdGlTZWxlY3QoKSkgewogICAgICAgICAgICAgICAgQ2hvaWNlTGlzdEZpZWxkLl9zdXBlci5fYXBwZW5kVmFsdWVJblhNTEVsZW1lbnQuYXBwbHkodGhpcyxbZWxlbWVudF0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gbmVlZCB0byByZW1vdmUgdGhlIG9sZCBjaG9pY2VzIGJlZm9yZSBhcHBlbmRpbmcgdGhlIG5ldyBvbmVzCiAgICAgICAgICAgICAgICB3aGlsZSAoZWxlbWVudC5maXJzdENoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVDaGlsZChlbGVtZW50LmZpcnN0Q2hpbGQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHhtbFZhbHVlID0gdGhpcy52YWx1ZS5vbmVPZkNoaWxkLmdldFZhbHVlKCJ0ZXh0L3htbCIpLAogICAgICAgICAgICAgICAgICAgIHhtbERvYywgbm9kZUl0ZXIsIG5vZGUsIGltcG9ydGVkTm9kZSwgYWRkZWRDaGlsZDsKICAgICAgICAgICAgICAgIGlmKHhtbFZhbHVlICE9IG51bGwgJiYgeG1sVmFsdWUgIT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICB4bWxEb2MgPSAkLnBhcnNlWE1MKHhtbFZhbHVlKTsKICAgICAgICAgICAgICAgICAgICBub2RlSXRlciA9IHhmYWxpYi51dC5YTUxVdGlscy5ldmFsdWF0ZVhQYXRoKCIqIiwgeG1sRG9jLmRvY3VtZW50RWxlbWVudCwgbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYUGF0aFJlc3VsdC5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRSwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5vZGVJdGVyLml0ZXJhdGVOZXh0KCk7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUobm9kZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGltcG9ydGVkTm9kZSA9IGVsZW1lbnQub3duZXJEb2N1bWVudC5pbXBvcnROb2RlKG5vZGUsIGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkZWRDaGlsZCA9IGVsZW1lbnQuYXBwZW5kQ2hpbGQoaW1wb3J0ZWROb2RlKTsKICAgICAgICAgICAgICAgICAgICAgICAgYWRkZWRDaGlsZC50ZXh0Q29udGVudCA9IG5vZGUudGV4dENvbnRlbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlSXRlci5pdGVyYXRlTmV4dCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIsICQpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5TdWJmb3JtCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Db250YWluZXJOb2RlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgU3ViZm9ybSBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQGNsYXNzIFRoZSBjbGFzcyByZXByZXNlbnRzIGEgc3ViZm9ybSBpbiB0aGUgWEZBIERvbQogKiBAdmVyc2lvbiAwLjAuMQogKi8KKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHZhciBTdWJmb3JtID0geGZhbGliLnNjcmlwdC5TdWJmb3JtID0geGZhbGliLnNjcmlwdC5FdmVudENvbnRhaW5lck5vZGUuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgU3ViZm9ybS5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLl9pbnN0YW5jZU1hbmFnZXIgPSBudWxsOwogICAgICAgICAgICB0aGlzLm1uSW5zdGFuY2VJbmRleCA9IDA7CiAgICAgICAgICAgIHRoaXMudGVzdHM9IFt0aGlzLl9zY3JpcHRUZXN0XTsKICAgICAgICB9LAoKICAgICAgICBfaXNTdWJmb3JtIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0sCgogICAgICAgIGdldEludmFsaWRPYmplY3RzIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICB2YXIgc01lc3NhZ2VzID0gbmV3IEFycmF5KCk7CiAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRlKHNNZXNzYWdlcyk7CiAgICAgICAgICAgIGZvciAoIHZhciBpID0gMDsgaSA8IHNNZXNzYWdlcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgbGlzdC5fYXBwZW5kKHNNZXNzYWdlc1tpXS5yZWYpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgIH0sCgogICAgICAgIF9ldmVudEhhbmRsZXIgOiBmdW5jdGlvbihldmVudE5hbWUpIHsKICAgICAgICAgICAgdmFyIHJWYWx1ZSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgc3dpdGNoIChldmVudE5hbWUpIHsKICAgICAgICAgICAgICAgIGNhc2UgInZhbGlkYXRlIjoKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLm1vRXZlbnRzWyJ2YWxpZGF0ZSJdICYmIHRoaXMubW9FdmVudHNbInZhbGlkYXRlIl0ubGVuZ3RoID4wKXsKICAgICAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdGhpcy5tb0V2ZW50c1sidmFsaWRhdGUiXVswXS5leGVjdXRlKHRoaXMsICJ2YWxpZGF0ZSIpOwogICAgICAgICAgICAgICAgICAgIH1lbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHJWYWx1ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICIkZm9ybXByZVN1Ym1pdCI6CiAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdGhpcy5fcHJlU3VibWl0RXZlbnRIYW5kbGVyKCk7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgaWYgKHRoaXMubW9FdmVudHNbZXZlbnROYW1lXSkgewogICAgICAgICAgICAgICAgICAgIGZvciAoIHZhciBpID0gMDsgaSA8IHRoaXMubW9FdmVudHNbZXZlbnROYW1lXS5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1vRXZlbnRzW2V2ZW50TmFtZV1baV0uZXhlY3V0ZSh0aGlzLCBldmVudE5hbWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gclZhbHVlOwogICAgICAgIH0sCgogICAgICAgIF9udWxsVGVzdCA6IGZ1bmN0aW9uKHZhbHVlLHNNZXNzYWdlcykgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBfcmVxdWlyZUdldHRlclNldHRlciA6IGZ1bmN0aW9uKG9DaGlsZCl7CiAgICAgICAgICAgIGlmKG9DaGlsZC5jbGFzc05hbWUgPT0gInBhZ2VTZXQiKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBTdWJmb3JtLl9zdXBlci5fcmVxdWlyZUdldHRlclNldHRlci5jYWxsKHRoaXMsIG9DaGlsZCk7CiAgICAgICAgfSwKCiAgICAgICAgX3Bvc3RBZGRDaGlsZCA6IGZ1bmN0aW9uKG9Ob2RlKXsKICAgICAgICAgICAgaWYob05vZGUuaW5zdGFuY2VNYW5hZ2VyKXsKICAgICAgICAgICAgICAgIC8vIGNsZWFyIGFsbCBjYWNoZWQgY29udGV4dHMgaW4gRXZlbnRDb250YWluZXJOb2RlLXMKICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5fY2xlYXJBbGxNb0NvbnRleHRzKCk7CgogICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuX3hmYVRlbXBsYXRlQ2FjaGUucHV0TW9kZWwob05vZGUsIG9Ob2RlLmluc3RhbmNlTWFuYWdlci5faW5zdGFuY2VUZW1wbGF0ZSgpKTsKICAgICAgICAgICAgICAgIGlmKHRoaXMubUVmZmVjdGl2ZUFjY2Vzcyl7CiAgICAgICAgICAgICAgICAgICAgb05vZGUuX2NhbGN1bGF0ZUVmZmVjdGl2ZUFjY2VzcygpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYodGhpcy5tRWZmZWN0aXZlUHJlc2VuY2UpewogICAgICAgICAgICAgICAgICAgIG9Ob2RlLl9jYWxjdWxhdGVFZmZlY3RpdmVQcmVzZW5jZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgb05vZGUuX2luaXRpYWxpemUoKTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm1iSW5pdGlhbGl6ZWQpIHsKICAgICAgICAgICAgICAgICAgICAvLyBvTm9kZS5leGVjRXZlbnQoImluaXRpYWxpemUiKTsKICAgICAgICAgICAgICAgICAgICBvTm9kZS5leGVjQ2FsY3VsYXRlKCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gaW50ZXJuYWxEaXNwYXRjaEV2ZW50KENvbGxlY3Rpb25FdmVudEtpbmQuQURELCBvTm9kZSwgaW5kZXgpOwoKICAgICAgICAgICAgICAgIC8vIGlmICh0aGlzLmhhc0V2ZW50TGlzdGVuZXIoImNoYW5nZSIpKQogICAgICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkNISUxEX0FEREVELHRoaXMsImNoaWxkIixudWxsLG9Ob2RlKTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsZXZudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAvL2RvIG5vdGhpbmcgLS0tIExldCdzIGZhY2UgaXQgWW91IG1pZ2h0IGNhbGwgdGhpcyBmdW5jdGlvbiBmb3Igb3RoZXIgdGhpbmdzIGJlc2lkZXMgc3ViZm9ybSBlLnguIGl0ZW1zIChzZWUgX2dldERpc3BsYXlJdGVtcygpKQogICAgICAgICAgICAgICAgU3ViZm9ybS5fc3VwZXIuX3Bvc3RBZGRDaGlsZC5jYWxsKHRoaXMsIG9Ob2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9wb3N0UmVtb3ZlQ2hpbGQgOiBmdW5jdGlvbihvQ2hpbGQpewogICAgICAgICAgICBpZihvQ2hpbGQuaW5zdGFuY2VNYW5hZ2VyKXsKICAgICAgICAgICAgICAgIC8vIGNsZWFyIGFsbCBjYWNoZWQgY29udGV4dHMgaW4gRXZlbnRDb250YWluZXJOb2RlLXMKICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5fY2xlYXJBbGxNb0NvbnRleHRzKCk7CgogICAgICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkNISUxEX1JFTU9WRUQsdGhpcywiY2hpbGQiLCBvQ2hpbGQsIG51bGwpOwogICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIFN1YmZvcm0uX3N1cGVyLl9wb3N0UmVtb3ZlQ2hpbGQuY2FsbCh0aGlzLCBvQ2hpbGQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcGxheUpzb25Gb3JFbGVtZW50IDogZnVuY3Rpb24oZWxOYW1lLCBwSnNvbk1vZGVsKXsKICAgICAgICAgICAgaWYoZWxOYW1lID09ICJpbnN0YW5jZU1hbmFnZXIiKXsKICAgICAgICAgICAgICAgIHZhciBuZXdKQ2hpbGRyZW4gPSBfLmZpbHRlcihfLmNvbXBhY3QocEpzb25Nb2RlbC5jaGlsZHJlbiksIGZ1bmN0aW9uIChqQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy54ZmFVdGlsKCkuaXNSZXBlYXRhYmVFbChqQ2hpbGQuX2NsYXNzKSB8fCBqQ2hpbGQuX2NsYXNzID09ICJpbnN0YW5jZU1hbmFnZXIiOwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICB2YXIgb2xkTUNoaWxkcmVuID0gXy5maWx0ZXIodGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uKG1DaGlsZCl7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICB0aGlzLnhmYVV0aWwoKS5pc1JlcGVhdGFiZUVsKG1DaGlsZC5jbGFzc05hbWUpICB8fCBtQ2hpbGQuY2xhc3NOYW1lID09ICJpbnN0YW5jZU1hbmFnZXIiIDsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwoKICAgICAgICAgICAgICAgIHZhciBsYXN0SU0gPSBudWxsOwogICAgICAgICAgICAgICAgXy5lYWNoKG9sZE1DaGlsZHJlbiwgZnVuY3Rpb24ob2xkTUNoaWxkKXsKICAgICAgICAgICAgICAgICAgICAvL0lmIG9sZE1DaGlsZCBoYXMgYW55IHJlbWFpbmluZyBJTSB0aGVuIG5ld0pDaGlsZHJlbiBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIElNIGxlZnQKICAgICAgICAgICAgICAgICAgICBpZihvbGRNQ2hpbGQuY2xhc3NOYW1lID09ICJpbnN0YW5jZU1hbmFnZXIiICYmIG5ld0pDaGlsZHJlblswXS5fY2xhc3MgPT0gImluc3RhbmNlTWFuYWdlciIpewogICAgICAgICAgICAgICAgICAgICAgICBuZXdKQ2hpbGRyZW4uc2hpZnQoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZihvbGRNQ2hpbGQuY2xhc3NOYW1lID09ICJpbnN0YW5jZU1hbmFnZXIiICYmIHRoaXMueGZhVXRpbCgpLmlzUmVwZWF0YWJlRWwobmV3SkNoaWxkcmVuWzBdLl9jbGFzcykpewogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSh0aGlzLnhmYVV0aWwoKS5pc1JlcGVhdGFiZUVsKG5ld0pDaGlsZHJlblswXS5fY2xhc3MpKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhZGRlZFNmID1sYXN0SU0uYWRkSW5zdGFuY2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZGVkU2YucGxheUpzb24obmV3SkNoaWxkcmVuLnNoaWZ0KCkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0pDaGlsZHJlbi5zaGlmdCgpOyAvLyBUaGlzIG11c3QgYmUgaW5zdGFuY2VNYW5hZ2VyIGZvciBuZXh0IHN1YmZvcm0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih0aGlzLnhmYVV0aWwoKS5pc1JlcGVhdGFiZUVsKG9sZE1DaGlsZC5jbGFzc05hbWUgKSAmJiAobmV3SkNoaWxkcmVuWzBdID09IG51bGwgfHwgbmV3SkNoaWxkcmVuWzBdLl9jbGFzcyA9PSAiaW5zdGFuY2VNYW5hZ2VyIikpewogICAgICAgICAgICAgICAgICAgICAgICBsYXN0SU0ucmVtb3ZlSW5zdGFuY2Uob2xkTUNoaWxkLmluc3RhbmNlSW5kZXgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9vbGRNQ2hpbGQuY2xhc3NOYW1lID09ICJzdWJmb3JtIiAmJiBuZXdKQ2hpbGRyZW5bMF0uX2NsYXNzID09ICJzdWJmb3JtIgogICAgICAgICAgICAgICAgICAgICAgICBvbGRNQ2hpbGQucGxheUpzb24obmV3SkNoaWxkcmVuLnNoaWZ0KCkpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgaWYob2xkTUNoaWxkLmNsYXNzTmFtZSA9PSAiaW5zdGFuY2VNYW5hZ2VyIiApCiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RJTSA9IG9sZE1DaGlsZDsKCiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIHdoaWxlKG5ld0pDaGlsZHJlbi5sZW5ndGggPiAwKXsKICAgICAgICAgICAgICAgICAgICB2YXIgbmV3SlNGID0gbmV3SkNoaWxkcmVuLnNoaWZ0KCk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGFkZGVkU0YgPSBsYXN0SU0uYWRkSW5zdGFuY2UoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYWRkZWRTRikgewogICAgICAgICAgICAgICAgICAgICAgICBhZGRlZFNGLnBsYXlKc29uKG5ld0pTRik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy54ZmFVdGlsKCkuaXNSZXBlYXRhYmVFbChlbE5hbWUpKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIGlmIChlbE5hbWUgPT09ICJ2YXJpYWJsZXMiKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgIC8vIExDLTk1MDg6IGRvbid0IHBsYXlKc29uIGZvciB2YXJpYWJsZXMKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBTdWJmb3JtLl9zdXBlci5wbGF5SnNvbkZvckVsZW1lbnQuY2FsbCh0aGlzLCBlbE5hbWUsIHBKc29uTW9kZWwpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldFhQYXRoRm9yVXNlTmFtZUJpbmRpbmc6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYodGhpcy5pbnN0YW5jZU1hbmFnZXIuX2lzUmVwZWF0YWJsZSgpKSB7CiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IHRoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIik7CiAgICAgICAgICAgICAgICByZXR1cm4gbmFtZSA9PT0gIiIgPyBudWxsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZTogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRSZWY6IG5hbWUgKyAiWypdIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBTdWJmb3JtLl9zdXBlci5fZ2V0WFBhdGhGb3JVc2VOYW1lQmluZGluZy5hcHBseSh0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9wbGF5RGF0YVhNTDogZnVuY3Rpb24oeG1sRG9jdW1lbnQsIGNvbnRleHROb2RlLCBjdXJyZW50QmluZFJlZikgewogICAgICAgICAgICBpZih0aGlzLnBhcmVudC5jbGFzc05hbWUgPT09ICJmb3JtIikgewogICAgICAgICAgICAgICAgcmV0dXJuIFN1YmZvcm0uX3N1cGVyLl9wbGF5RGF0YVhNTC5hcHBseSh0aGlzLFt4bWxEb2N1bWVudCxjb250ZXh0Tm9kZSwgY3VycmVudEJpbmRSZWZdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgeHBhdGggPSB0aGlzLl9nZXRYcGF0aEZyb21CaW5kUmVmKCksCiAgICAgICAgICAgICAgICByZWxhdGl2ZVhQYXRoLCBub2RlSXRlciwgbm9kZUxpc3QgPSBbXSwgbm9kZSwgY291bnQsIGluc3RhbmNlOwogICAgICAgICAgICBpZih4cGF0aCA9PSBudWxsKSB7CiAgICAgICAgICAgICAgIFN1YmZvcm0uX3N1cGVyLl9wbGF5RGF0YVhNTC5hcHBseSh0aGlzLFt4bWxEb2N1bWVudCxjb250ZXh0Tm9kZSwgY3VycmVudEJpbmRSZWZdKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIFRoZSBmaXJzdCBpbnN0YW5jZSB3aWxsIHRha2UgY2FyZSBvZiB0aGUgcmVzdCBvZiB0aGUgaW5zdGFuY2VzLgogICAgICAgICAgICAgICAgaWYodGhpcy5pbnN0YW5jZUluZGV4ID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgbm9kZUl0ZXIgPSB0aGlzLl9nZXRFbGVtZW50c0Zyb21YcGF0aCh4cGF0aCwgY29udGV4dE5vZGUsIHhtbERvY3VtZW50KTsKICAgICAgICAgICAgICAgICAgICBpZiAobm9kZUl0ZXIgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZUl0ZXIuaXRlcmF0ZU5leHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKG5vZGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVMaXN0LnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZUl0ZXIuaXRlcmF0ZU5leHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gbm9kZUxpc3Quc2hpZnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAobm9kZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPiB0aGlzLmluc3RhbmNlTWFuYWdlci5jb3VudCAtIDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZSA9IHRoaXMuaW5zdGFuY2VNYW5hZ2VyLmFkZEluc3RhbmNlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlID0gdGhpcy5pbnN0YW5jZU1hbmFnZXIuaW5zdGFuY2VzW2NvdW50XTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN1YmZvcm0uX3N1cGVyLl9wbGF5RGF0YVhNTC5hcHBseShpbnN0YW5jZSwgW3htbERvY3VtZW50LCBub2RlLCB4cGF0aF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSA9IG5vZGVMaXN0LnNoaWZ0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChjb3VudCA8IHRoaXMuaW5zdGFuY2VNYW5hZ2VyLmNvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pbnN0YW5jZU1hbmFnZXIuY291bnQgPT09IHRoaXMuaW5zdGFuY2VNYW5hZ2VyLm1pbikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlID0gdGhpcy5pbnN0YW5jZU1hbmFnZXIuaW5zdGFuY2VzW2NvdW50XTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdWJmb3JtLl9zdXBlci5fcGxheURhdGFYTUwuYXBwbHkoaW5zdGFuY2UsIFt4bWxEb2N1bWVudCwgbnVsbCwgeHBhdGhdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluc3RhbmNlTWFuYWdlci5yZW1vdmVJbnN0YW5jZShjb3VudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBHZW5lcmF0ZXMgdGhlIFhNTCBieSBhcHBlbmRpbmcgdGhlIGVsZW1lbnRzIGluIHRoZSByb290Tm9kZQogICAgICAgICAqIEBwYXJhbSByb290Tm9kZSBUaGUgcm9vdE5vZGUgb2YgdGhlIHhtbC4gR2VuZXJhbGx5IHRoZSBlbGVtZW50IHRoYXQgbWFwcyB0byB0aGUgcm9vdCBvZiB0aGUgZm9ybQogICAgICAgICAqIEBwYXJhbSBjb250ZXh0Tm9kZSBDdXJyZW50IE5vZGUgd2hlcmUgdG8gaW5zZXJ0IHRoZSBlbGVtZW50cyBpbiBjYXNlIG9mIHJlbGF0aXZlIGJpbmRpbmdzCiAgICAgICAgICovCiAgICAgICAgZ2VuZXJhdGVEYXRhWE1MOiBmdW5jdGlvbihyb290Tm9kZSwgY29udGV4dE5vZGUpIHsKICAgICAgICAgICAgaWYodGhpcy5wYXJlbnQuY2xhc3NOYW1lID09PSAiZm9ybSIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBTdWJmb3JtLl9zdXBlci5nZW5lcmF0ZURhdGFYTUwuYXBwbHkodGhpcyxbcm9vdE5vZGUsY29udGV4dE5vZGVdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgeHBhdGggPSB0aGlzLl9nZXRYcGF0aEZyb21CaW5kUmVmKCksCiAgICAgICAgICAgICAgICB4bWxVdGlscyA9IHhmYWxpYi51dC5YTUxVdGlscywKICAgICAgICAgICAgICAgIHBhcmVudEVsZW1lbnQsIGVsZW1lbnQsIGNoaWxkRWxlbWVudCwgY2hpbGRYUGF0aCwgY2hpbGRYUGF0aFBhcnRzLAogICAgICAgICAgICAgICAgY2hpbGRFbGVtZW50TmFtZSwgY2hpbGRFbGVtZW50SW5kZXg7CiAgICAgICAgICAgIGlmKHhwYXRoID09IG51bGwpIHsKICAgICAgICAgICAgICAgIFN1YmZvcm0uX3N1cGVyLmdlbmVyYXRlRGF0YVhNTC5hcHBseSh0aGlzLFtyb290Tm9kZSxjb250ZXh0Tm9kZV0pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZWxlbWVudCA9IHhwYXRoLnJlbGF0aXZlID09PSBmYWxzZSA/IHJvb3ROb2RlIDogY29udGV4dE5vZGU7CiAgICAgICAgICAgICAgICBwYXJlbnRFbGVtZW50ID0geG1sVXRpbHMuY3JlYXRlRWxlbWVudHNGcm9tWFBhdGgoeHBhdGguYmluZFJlZiwgZWxlbWVudCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICBjaGlsZFhQYXRoID0gXy5sYXN0KHhwYXRoLmJpbmRSZWYuc3BsaXQoIi8iKSk7CiAgICAgICAgICAgICAgICBjaGlsZFhQYXRoUGFydHMgPSB4bWxVdGlscy5fZ2V0RWxlbWVudE5hbWVBbmRJbmRleEZyb21YUGF0aFBhcnQoY2hpbGRYUGF0aCk7CiAgICAgICAgICAgICAgICBjaGlsZEVsZW1lbnROYW1lID0gY2hpbGRYUGF0aFBhcnRzLm5hbWU7CiAgICAgICAgICAgICAgICBjaGlsZEVsZW1lbnRJbmRleCA9IGNoaWxkWFBhdGhQYXJ0cy5pbmRleDsKICAgICAgICAgICAgICAgIC8vVE9ETzogKiBkb2Vzbid0IGdhdXJhbnRlZXMgdGhhdCB0aGUgZWxlbWVudCBjYW4gYmUgcmVwZWF0ZWQgaW4gc2NoZW1hLiBCdXQgd2UgaGF2ZSBubyBjaG9pY2UgZm9yIG5vdwogICAgICAgICAgICAgICAgaWYoY2hpbGRFbGVtZW50SW5kZXggPT09ICIqIikgewogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuaW5zdGFuY2VJbmRleCA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3IgcmVwZWF0YWJsZSBzdWJmb3JtcyB0aGUgZmlyc3QgY2hpbGQgZG9lcyB0aGUgcHJvY2Vzc2luZyBmb3IgYWxsIHRoZSBzaWJsaW5ncwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FjaGUgYWxsIGV4aXN0aW5nIGNoaWxkcmVuCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleGlzdGluZ0luc3RhbmNlcyA9IHBhcmVudEVsZW1lbnQuaGFzQ2hpbGROb2RlcygpID8gcGFyZW50RWxlbWVudC5jaGlsZE5vZGVzIDogbnVsbDsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbHRlciBvdXQgY3VycmVudCByZXBlYXRhYmxlIG9uZXMKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfLmlzRW1wdHkoZXhpc3RpbmdJbnN0YW5jZXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0luc3RhbmNlcyA9IF8uZmlsdGVyKGV4aXN0aW5nSW5zdGFuY2VzLCBmdW5jdGlvbiAoY2hpbGQpIHsgcmV0dXJuIGNoaWxkLm5vZGVOYW1lID09PSBjaGlsZEVsZW1lbnROYW1lOyB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgXy5lYWNoKHRoaXMuaW5zdGFuY2VNYW5hZ2VyLmluc3RhbmNlcywgZnVuY3Rpb24gKGluc3RhbmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBpbnN0YW5jZS5pbnN0YW5jZUluZGV4ICsgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZEVsZW1lbnQgPSB4bWxVdGlscy5maW5kT3JDcmVhdGVFbGVtZW50KGNoaWxkRWxlbWVudE5hbWUgKyAiWyIgKyBpbmRleCArICJdIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50RWxlbWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdWJmb3JtLl9zdXBlci5nZW5lcmF0ZURhdGFYTUwuYXBwbHkoaW5zdGFuY2UsW3Jvb3ROb2RlLCBjaGlsZEVsZW1lbnRdKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZighXy5pc0VtcHR5KGV4aXN0aW5nSW5zdGFuY2VzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBsZWZ0IG92ZXIgb25lcywgY2F1c2VkIGlmIG9uZSBkZWxldGVzIGFuIGluc3RhbmNlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2luY2Ugd2UgYXJlIHJlZ2VuZXJhdGluZyB4bWwsIG5vIG5lZWQgdG8gd29ycnkgYWJvdXQgb3JkZXIsIHJlbWFpbmluZyBTRnMgd2lsbCB1cGRhdGUgdGhlaXIgZGF0YSBmcm9tIHRoZSB4bWwncyB0b3AgZWxlbXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcih2YXIgaSA9IHRoaXMuaW5zdGFuY2VNYW5hZ2VyLmNvdW50OyBpIDwgZXhpc3RpbmdJbnN0YW5jZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKGV4aXN0aW5nSW5zdGFuY2VzW2ldKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAvLyBCdXQgdGhpcyB3aWxsIGhhdmUgYSBzaWRlIGVmZmVjdCBpbiBjYXNlIG9mIGFueSBvdGhlciByZXBlYXRhYmxlIHN1YmZvcm0gbWFwcGluZyB0byB0aGUgc2FtZSB4cGF0aCBMQy0zOTExNTE4CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjaGlsZEVsZW1lbnQgPSB4bWxVdGlscy5maW5kT3JDcmVhdGVFbGVtZW50KGNoaWxkRWxlbWVudE5hbWUgKyJbIiArIGNoaWxkRWxlbWVudEluZGV4ICsgIl0iLAogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRFbGVtZW50KTsKICAgICAgICAgICAgICAgICAgICBTdWJmb3JtLl9zdXBlci5nZW5lcmF0ZURhdGFYTUwuYXBwbHkodGhpcyxbcm9vdE5vZGUsIGNoaWxkRWxlbWVudF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldERhdGFTb21NYXAgOiBmdW5jdGlvbiAoZGF0YVNvbU1hcCkgewogICAgICAgICAgICBpZighdGhpcy5pbnN0YW5jZU1hbmFnZXIgfHwgIXRoaXMuaW5zdGFuY2VNYW5hZ2VyLl9pc1JlcGVhdGFibGUoKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIFN1YmZvcm0uX3N1cGVyLl9nZXREYXRhU29tTWFwLmFwcGx5KHRoaXMsYXJndW1lbnRzKQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBkYXRhU29tTWFwOwogICAgICAgIH0sCgogICAgICAgIF9yZXN0b3JlRGF0YVNvbU1hcDogZnVuY3Rpb24obWFwKSB7CiAgICAgICAgICAgIGlmKCF0aGlzLmluc3RhbmNlTWFuYWdlciB8fCAhdGhpcy5pbnN0YW5jZU1hbmFnZXIuX2lzUmVwZWF0YWJsZSgpKSB7CiAgICAgICAgICAgICAgICBTdWJmb3JtLl9zdXBlci5fcmVzdG9yZURhdGFTb21NYXAuYXBwbHkodGhpcyxhcmd1bWVudHMpCiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfcHJlU3VibWl0RXZlbnRIYW5kbGVyOiB4ZmFsaWIuc2NyaXB0LkZpZWxkLnByb3RvdHlwZS5fcHJlU3VibWl0RXZlbnRIYW5kbGVyCiAgICB9KTsKCiAgICBTdWJmb3JtLmRlZmluZVByb3BzKHsKICAgICAgICAibG9jYWxlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgdmFyIG9iaiA9IHRoaXM7CiAgICAgICAgICAgICAgICB2YXIgbG9jYWxlOwogICAgICAgICAgICAgICAgd2hpbGUoIWxvY2FsZSAmJiBvYmopIHsKICAgICAgICAgICAgICAgICAgICBsb2NhbGUgPSBvYmouanNvbk1vZGVsLmxvY2FsZTsKICAgICAgICAgICAgICAgICAgICBvYmogPSBvYmoucGFyZW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbG9jYWxlID0gbG9jYWxlIHx8ICJlbi1VUyI7IC8vVE9ETzogcmVhZCBmcm9tIGpzcAogICAgICAgICAgICAgICAgcmV0dXJuIGxvY2FsZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJpbnN0YW5jZUluZGV4IjoKICAgICAgICB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubW5JbnN0YW5jZUluZGV4OwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImluc3RhbmNlTWFuYWdlciI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9pbnN0YW5jZU1hbmFnZXI7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHJlc29sdmU6dHJ1ZQogICAgICAgIH0sCgogICAgICAgICJvY2N1ciI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmluc3RhbmNlTWFuYWdlci5vY2N1cjsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgcmVzb2x2ZTp0cnVlCiAgICAgICAgfSwKCiAgICAgICAgInBhZ2VTZXQiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInBhZ2VTZXQiLCAwLCB0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJ2YXJpYWJsZXMiOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICB0aGlzLmdldEVsZW1lbnQoInZhcmlhYmxlcyIsMCk7CiAgICAgICAgICAgIH0gLAogICAgICAgICAgICBzZXQgOmZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsInZhcmlhYmxlcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgU3ViZm9ybS5hZGRNaXhpbnMoWwogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQXNzaXN0LAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkUHJlc2VuY2UsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRYWVdILAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkRmlsbENvbG9yLAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQm9yZGVyLAogICAgICAgIHhmYWxpYi5zY3JpcHQubWl4aW4uQWRkQm9yZGVyQ29sb3IsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRCb3JkZXJXaWR0aCwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFBhcmEsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRNYXJnaW4KICAgIF0pOwoKfSkoXyx4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5Db250ZW50QXJlYQogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuQ29udGFpbmVyTm9kZQogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIENvbnRlbnRBcmVhIENsYXNzIHJlcXVpcmVkIGZvciBYRkEgbGlicmFyeQogKiBAdmVyc2lvbiAwLjAuMQogKi8KCihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgQ29udGVudEFyZWEgY2xhc3MKICAgICAqCiAgICAgKiBAY2xhc3MgVGhlIGNsYXNzIHJlcHJlc2VudHMgYSBzdWJmb3JtIGluIHRoZSBYRkEgRG9tCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgbm9kZQogICAgICogQGV4dGVuZHMgY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuQ29udGFpbmVyTm9kZQogICAgICovCiAgICB2YXIgQ29udGVudEFyZWEgPSB4ZmFsaWIuc2NyaXB0LkNvbnRlbnRBcmVhID0geGZhbGliLnNjcmlwdC5Db250YWluZXJOb2RlLmV4dGVuZCh7CiAgICAgICAgX2NvbXB1dGVKc29uRGlmZjogZnVuY3Rpb24gKGRpZmZfbGV2ZWwpIHsKICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5wYXJ0aWFsU3RyaXBPckNhbGwuY2FsbCh0aGlzLCBkaWZmX2xldmVsLCBDb250ZW50QXJlYS5fc3VwZXIuX2NvbXB1dGVKc29uRGlmZik7CiAgICAgICAgfQogICAgfSk7CgogICAgQ29udGVudEFyZWEuYWRkTWl4aW5zKFsKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFhZV0gKICAgIF0pOwoKfSkoXywgeGZhbGliKTsKCi8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LlBhZ2VBcmVhCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Db250YWluZXJOb2RlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgUGFnZUFyZWEgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKKGZ1bmN0aW9uKF8sIHhmYWxpYil7CiAgICAvKioKICAgICAqIENyZWF0ZXMgYSBuZXcgUGFnZUFyZWEgY2xhc3MKICAgICAqCiAgICAgKiBAY2xhc3MgVGhlIGNsYXNzIHJlcHJlc2VudHMgYSBzdWJmb3JtIGluIHRoZSBYRkEgRG9tCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgbm9kZQogICAgICogQGV4dGVuZHMgY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuQ29udGFpbmVyTm9kZQogICAgICovCiAgICB2YXIgUGFnZUFyZWEgPSB4ZmFsaWIuc2NyaXB0LlBhZ2VBcmVhID0geGZhbGliLnNjcmlwdC5FdmVudENvbnRhaW5lck5vZGUuZXh0ZW5kKHsKICAgICAgICBleGVjRXZlbnQgOiBmdW5jdGlvbihldmVudE5hbWUpIHsKICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICB9LAoKICAgICAgICBwbGF5SnNvbkZvckVsZW1lbnQ6IHhmYWxpYi5zY3JpcHQuU3ViZm9ybS5wcm90b3R5cGUucGxheUpzb25Gb3JFbGVtZW50LAoKICAgICAgICBfY29tcHV0ZUpzb25EaWZmOiBmdW5jdGlvbiAoZGlmZl9sZXZlbCkgewogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLnBhcnRpYWxTdHJpcE9yQ2FsbC5jYWxsKHRoaXMsIGRpZmZfbGV2ZWwsIFBhZ2VBcmVhLl9zdXBlci5fY29tcHV0ZUpzb25EaWZmKTsKICAgICAgICB9CiAgICB9KTsKCiAgICBQYWdlQXJlYS5kZWZpbmVQcm9wcyh7CiAgICAgICAgImFjY2VzcyIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgeyAgLy9pIGFtIG5vdCBzdXJlIGhvdyB0byBtYWtlIHRoaXMgcHJvcGVydHkgdW5kZWZpbmVkIHNvIGp1c3QgcmVtb3ZlZCBzZXR0ZXJzCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwuYWNjZXNzLCB0aGlzLl9kZWZhdWx0cy5hY2Nlc3MpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCgogICAgICAgICJwcmVzZW5jZSIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgeyAvL2kgYW0gbm90IHN1cmUgaG93IHRvIG1ha2UgdGhpcyBwcm9wZXJ0eSB1bmRlZmluZWQgc28ganVzdCByZW1vdmVkIHNldHRlcnMKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5wcmVzZW5jZSwgdGhpcy5fZGVmYXVsdHMucHJlc2VuY2UpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cn0pKF8sIHhmYWxpYik7CgoKCgovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5QYWdlU2V0CiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Db250YWluZXJOb2RlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgUGFnZVNldCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBQYWdlU2V0IGNsYXNzCiAgICAgKgogICAgICogQGNsYXNzIFRoZSBjbGFzcyByZXByZXNlbnRzIGEgc3ViZm9ybSBpbiB0aGUgWEZBIERvbQogICAgICogQHBhcmFtIHtzdHJpbmd9CiAgICAgICAgKiAgICAgICAgICAgIG5hbWUgdGhlIG5hbWUgb2YgdGhlIG5vZGUKICAgICAqIEBleHRlbmRzIGNvbS5hZG9iZS54ZmEuc2NyaXB0aW5nLkNvbnRhaW5lck5vZGUKICAgICAqLwogICAgdmFyIFBhZ2VTZXQgPSB4ZmFsaWIuc2NyaXB0LlBhZ2VTZXQgPSB4ZmFsaWIuc2NyaXB0LkV2ZW50Q29udGFpbmVyTm9kZS5leHRlbmQoewogICAgICAgIGV4ZWNFdmVudCA6IGZ1bmN0aW9uKGV2ZW50TmFtZSkgewogICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgIHJldHVybiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUucGFydGlhbFN0cmlwT3JDYWxsLmNhbGwodGhpcywgZGlmZl9sZXZlbCwgUGFnZVNldC5fc3VwZXIuX2NvbXB1dGVKc29uRGlmZik7CiAgICAgICAgfSwKCiAgICAgICAgcGxheUpzb25Gb3JFbGVtZW50OiBmdW5jdGlvbiAoZWxOYW1lLCBwSnNvbk1vZGVsKSB7CiAgICAgICAgICAgIGlmKGVsTmFtZSA9PT0gInBhZ2VBcmVhIikgeyAvLyBMQy0zNjQyNTE4IDogYWxsb3cgZGF0YS1tZXJnZSBvbiBtYXN0ZXIgcGFnZQogICAgICAgICAgICAgICAgdmFyIG5ld0pDaGlsZHJlbiA9IF8uZmlsdGVyKF8uY29tcGFjdChwSnNvbk1vZGVsLmNoaWxkcmVuKSwgZnVuY3Rpb24gKGpDaGlsZCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBqQ2hpbGQuX2NsYXNzID09PSAicGFnZUFyZWEiOwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICB2YXIgb2xkTUNoaWxkcmVuID0gXy5maWx0ZXIodGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uIChtQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbUNoaWxkLmNsYXNzTmFtZSA9PT0gInBhZ2VBcmVhIjsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwoKICAgICAgICAgICAgICAgIF8uZWFjaChvbGRNQ2hpbGRyZW4sIGZ1bmN0aW9uIChvbGRNQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaWRQYXR0ZXJuID0gbmV3IFJlZ0V4cCgiXiIgKyBvbGRNQ2hpbGQuanNvbk1vZGVsLmlkICsgIig/Ol9JRCkqJCIpOyAvLyBsb29rIGZvciBhbiBpZCB2YWx1ZSwgZm9sbG93ZWQgYnkgemVybyBvciBtb3JlICJfSUQiIHN1ZmZpeGVzCiAgICAgICAgICAgICAgICAgICAgXy5lYWNoKG5ld0pDaGlsZHJlbiwgZnVuY3Rpb24gKG5ld0pDaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAob2xkTUNoaWxkLm5hbWUgJiYgb2xkTUNoaWxkLm5hbWUgPT0gbmV3SkNoaWxkLm5hbWUgJiYgaWRQYXR0ZXJuLnRlc3QobmV3SkNoaWxkLmlkKSkgeyAvLyBtYXRjaCBuYW1lIGFzIHdlbGwgYXMgaWQsIHRvIGFjY291bnQgZm9yIG15c3RlcnkgeHRnIG1hc3RlciBwZyBpZCBnZW4gbG9naWMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkTUNoaWxkLnBsYXlKc29uKG5ld0pDaGlsZCk7IC8vIG1heSB0aHJvdyBhbiBleGNlcHRpb24sIHNheSBmb3IgMC1pbnN0YW5jZSBmaWVsZHMgb24gbWFzdGVyIHBnLiBTYXkgZXhwZWN0ZWQgYW4gaW5zdC5tYW4gYnV0IGZvdW5kIG51bGwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZXJyb3IoInhmYSIsICJFeGNlcHRpb24gZHVyaW5nIERhdGFNZXJnZSBvbiBmaWVsZHMgaW4gbWFzdGVyIHBhZ2UuICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZXhjZXB0aW9uLCBvbGRNQ2hpbGQsIiBQbGF5SlNPTiBvbiIsIG5ld0pDaGlsZF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBQYWdlU2V0Ll9zdXBlci5wbGF5SnNvbkZvckVsZW1lbnQuY2FsbCh0aGlzLCBlbE5hbWUsIHBKc29uTW9kZWwpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgUGFnZVNldC5kZWZpbmVQcm9wcyh7CiAgICAgICAgImFjY2VzcyIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgeyAgLy9pIGFtIG5vdCBzdXJlIGhvdyB0byBtYWtlIHRoaXMgcHJvcGVydHkgdW5kZWZpbmVkIHNvIGp1c3QgcmVtb3ZlZCBzZXR0ZXJzCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwuYWNjZXNzLCB0aGlzLl9kZWZhdWx0cy5hY2Nlc3MpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInByZXNlbmNlIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7IC8vaSBhbSBub3Qgc3VyZSBob3cgdG8gbWFrZSB0aGlzIHByb3BlcnR5IHVuZGVmaW5lZCBzbyBqdXN0IHJlbW92ZWQgc2V0dGVycwogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JFbHNlKHRoaXMuanNvbk1vZGVsLnByZXNlbmNlLCB0aGlzLl9kZWZhdWx0cy5wcmVzZW5jZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sIHhmYWxpYik7Ci8qKgogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIFN1YmZvcm1TZXQgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyBhIFN1YmZvcm1TZXQgaW4gdGhlIFhGQSBEb20KICogQHZlcnNpb24gMC4wLjEKICovCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgU3ViZm9ybVNldCA9IHhmYWxpYi5zY3JpcHQuU3ViZm9ybVNldCA9IHhmYWxpYi5zY3JpcHQuU3ViZm9ybS5leHRlbmQoewogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBTdWJmb3JtU2V0Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMudGVzdHMgPSBudWxsOwogICAgICAgIH0sCgogICAgICAgIGV4ZWNFdmVudCA6IGZ1bmN0aW9uKGV2ZW50TmFtZSkgewogICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBTdWJmb3JtU2V0LmRlZmluZVByb3BzKHsKICAgICAgICAiYWNjZXNzIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgIC8vaSBhbSBub3Qgc3VyZSBob3cgdG8gbWFrZSB0aGlzIHByb3BlcnR5IHVuZGVmaW5lZCBzbyBqdXN0IHJlbW92ZWQgc2V0dGVycyBmb3Igbm93CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwuYWNjZXNzLCB0aGlzLl9kZWZhdWx0cy5hY2Nlc3MpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvL1RPRE8gOiBBZGQgc2V0dGVyIHRvIGRlbGVnYXRlIHRvIGNoaWxkcmVuCgogICAgICAgIH0sCgogICAgICAgICJwcmVzZW5jZSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IC8vaSBhbSBub3Qgc3VyZSBob3cgdG8gbWFrZSB0aGlzIHByb3BlcnR5IHVuZGVmaW5lZCBzbyBqdXN0IHJlbW92ZWQgc2V0dGVycyBmb3Igbm93CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwucHJlc2VuY2UsIHRoaXMuX2RlZmF1bHRzLnByZXNlbmNlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9UT0RPIDogQWRkIHNldHRlciB0byBkZWxlZ2F0ZSB0byBjaGlsZHJlbgogICAgICAgIH0KCiAgICB9KTsKfSkoXyx4ZmFsaWIpOy8qKgogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIEFyZWEgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyBhIEFyZWEgaW4gdGhlIFhGQSBEb20KICogQHZlcnNpb24gMC4wLjEKICovCihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgQXJlYSA9IHhmYWxpYi5zY3JpcHQuQXJlYSA9IHhmYWxpYi5zY3JpcHQuRXZlbnRDb250YWluZXJOb2RlLmV4dGVuZCh7CiAgICAgICAgZXhlY0V2ZW50IDogZnVuY3Rpb24oZXZlbnROYW1lKSB7CiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7CiAgICAgICAgfSwKCiAgICAgICAgcGxheUpzb25Gb3JFbGVtZW50IDogeGZhbGliLnNjcmlwdC5TdWJmb3JtLnByb3RvdHlwZS5wbGF5SnNvbkZvckVsZW1lbnQKCiAgICB9KTsKCiAgICBBcmVhLmRlZmluZVByb3BzKHsKICAgICAgICAiYWNjZXNzIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7ICAvL2kgYW0gbm90IHN1cmUgaG93IHRvIG1ha2UgdGhpcyBwcm9wZXJ0eSB1bmRlZmluZWQgc28ganVzdCByZW1vdmVkIHNldHRlcnMKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5hY2Nlc3MsIHRoaXMuX2RlZmF1bHRzLmFjY2Vzcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAicHJlc2VuY2UiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsgLy9pIGFtIG5vdCBzdXJlIGhvdyB0byBtYWtlIHRoaXMgcHJvcGVydHkgdW5kZWZpbmVkIHNvIGp1c3QgcmVtb3ZlZCBzZXR0ZXJzCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwucHJlc2VuY2UsIHRoaXMuX2RlZmF1bHRzLnByZXNlbmNlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKCiAgICBBcmVhLmFkZE1peGlucyhbCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRYWVdICiAgICBdKTsKCn0pKF8seGZhbGliKTsvKioKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBWYXJpYWJsZXMgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyBhIFZhcmlhYmxlcyBpbiB0aGUgWEZBIERvbQogKiBAdmVyc2lvbiAwLjAuMQogKi8KKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBWYXJpYWJsZXMgPSB4ZmFsaWIuc2NyaXB0LlZhcmlhYmxlcyA9IHhmYWxpYi5zY3JpcHQuQ29udGFpbmVyTm9kZS5leHRlbmQoewogICAgICAgIF9pbml0Q2hpbGRyZW46IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gbmV3IEFycmF5KCk7CiAgICAgICAgICAgIGlmICh0aGlzLmpzb25Nb2RlbC5jaGlsZHJlbikgewogICAgICAgICAgICAgICAgdmFyIGogPSAwOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmpzb25Nb2RlbC5jaGlsZHJlbi5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IHRoaXMuanNvbk1vZGVsLmNoaWxkcmVuW2ldOwogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZE1vZGVsID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVOb2RlVmFsdWUoY2hpbGQpOwogICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZE1vZGVsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuW2orK10gPSBjaGlsZE1vZGVsOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgIC8vIGRvbid0IG5lZWQgdmFyaWFibGVzIGZvciBzdWJtaXNzaW9uLCBidXQgbmVlZCB0aGVtIGZvciByZXBsYXkgb24gcmVzdG9yZUZvcm1TdGF0ZQogICAgICAgICAgICByZXR1cm4geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLnN0cmlwT3JDYWxsLmNhbGwodGhpcywgZGlmZl9sZXZlbCA9PT0gMiwgVmFyaWFibGVzLl9zdXBlci5fY29tcHV0ZUpzb25EaWZmLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIHNjb3BlbGVzczogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gKCh0aGlzLm5hbWUgfHwgIiIpLmxlbmd0aCA9PSAwKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm4gdGhlIERhdGFTT01NYXAgYWZ0ZXIgYWRkaW5nIGFuIGVudHJ5IGluIHRoZSBtYXAgZm9yIHRoZSBub2RlLiBUaGUgZW50cnkgY29udGFpbnMgdGhlIHZhbHVlIG9mIHRoZSBub2RlCiAgICAgICAgICogYWxvbmcgd2l0aCBpdHMgRGF0YSBTT00uIElmIHRoZXJlIGlzIG5vIERhdGEgU09NIHRoZW4gcmV0dXJuIHRoZSB1bm1vZGlmaWVkIG1hcAogICAgICAgICAqIEBwYXJhbSBtYXAKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9nZXREYXRhU29tTWFwOiBmdW5jdGlvbiAobWFwKSB7CiAgICAgICAgICAgIHJldHVybiBtYXA7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVXBkYXRlIHRoZSB2YWx1ZSBvZiB0aGUgbm9kZSB3aXRoIHRoZSB2YWx1ZSBwcm92aWRlZCBpbiB0aGUgaW5wdXQgbWFwLiBUaGUgbWFwIGNvbnRhaW5zIHRoZSB2YWx1ZXMgb2YgdGhlIGZpZWxkcwogICAgICAgICAqIG1hcHBlZCB3aXRoIHRoZWlyIERhdGFTT00uIFRoZSBmdW5jdGlvbiBpcyBlbXB0eSBmb3IgYWxsIHRoZSBub2RlcywgZXhjZXB0IGZvciBGaWVsZCwgU3ViZm9ybSBhbmQgQXJlYS4KICAgICAgICAgKiBAcGFyYW0gbWFwCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfcmVzdG9yZURhdGFTb21NYXAgOiBmdW5jdGlvbiAobWFwKSB7CgogICAgICAgIH0KCiAgICB9KTsKCiAgICBWYXJpYWJsZXMuZGVmaW5lUHJvcHMoewogICAgICAgICJwcmVzZW5jZSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IC8vaSBhbSBub3Qgc3VyZSBob3cgdG8gbWFrZSB0aGlzIHByb3BlcnR5IHVuZGVmaW5lZCBzbyBqdXN0IHJlbW92ZWQgc2V0dGVycwogICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sIHhmYWxpYik7Ci8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0Lk9jY3VyCiAqIEBpbXBvcnQgeGZhbGliLnV0LkNsYXNzCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgT2NjdXIgQ2xhc3MgcmVxdWlyZWQgYnkgSW5zdGFuY2VNYW5hZ2VyCiAqICAgICAgICAgICAgICAgZm9yIFhGQSBsaWJyYXJ5CiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgLyoqCiAgICAgKiBDcmVhdGVzIGEgbmV3IE9jY3VyIG9iamVjdAogICAgICoKICAgICAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyB0aGUgT2NjdXIgT2JqZWN0CiAgICAgKiBAY29uc3RydWN0b3IKICAgICAqIEBwYXJhbSB7bnVtYmVyfQogICAgICAgICogICAgICAgICAgICBpbml0aWFsIEluaXRpYWwgb2NjdXJyZW5jZSBvZiB0aGUgc3ViZm9ybSBtYW5hZ2VkIGJ5IHBhcmVudAogICAgICogICAgICAgICAgICBJbnN0YW5jZU1hbmFnZXIKICAgICAqIEBwYXJhbSB7bnVtYmVyfQogICAgICAgICogICAgICAgICAgICBtYXggTWF4aW11bSBvY2N1cnJlbmNlIG9mIHRoZSBzdWJmb3JtIG1hbmFnZWQgYnkgcGFyZW50CiAgICAgKiAgICAgICAgICAgIEluc3RhbmNlTWFuYWdlcgogICAgICogQHBhcmFtIHtudW1iZXJ9CiAgICAgICAgKiAgICAgICAgICAgIG1pbiBNaW5pbXVtIG9jY3VycmVuY2Ugb2YgdGhlIHN1YmZvcm0gbWFuYWdlZCBieSBwYXJlbnQKICAgICAqICAgICAgICAgICAgSW5zdGFuY2VNYW5hZ2VyCiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gaW5pdGlhbCBJbml0aWFsIG9jY3VycmVuY2Ugb2YgdGhlIHN1YmZvcm0gbWFuYWdlZCBieQogICAgICogICAgICAgICAgIHBhcmVudCBJbnN0YW5jZU1hbmFnZXIKICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtYXggTWF4aW11bSBvY2N1cnJlbmNlIG9mIHRoZSBzdWJmb3JtIG1hbmFnZWQgYnkgcGFyZW50CiAgICAgKiAgICAgICAgICAgSW5zdGFuY2VNYW5hZ2VyCiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gbWluIE1pbmltdW0gb2NjdXJyZW5jZSBvZiB0aGUgc3ViZm9ybSBtYW5hZ2VkIGJ5IHBhcmVudAogICAgICogICAgICAgICAgIEluc3RhbmNlTWFuYWdlcgogICAgICovCiAgICB2YXIgT2NjdXIgPSB4ZmFsaWIuc2NyaXB0Lk9jY3VyID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CiAgICAgICAgX2RlZmF1bHRzIDogewogICAgICAgICAgICAibWluIiA6ICIxIiwKICAgICAgICAgICAgIm1heCIgOiAiMSIsCiAgICAgICAgICAgICJpbml0aWFsIiA6ICIxIgogICAgICAgIH0sCiAgICAgICAgbXNDbGFzc05hbWU6ICJvY2N1ciIKCiAgICB9KTsKCiAgICBPY2N1ci5kZWZpbmVQcm9wcyh7CiAgICAgICAgaW5pdGlhbDp7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwuaW5pdGlhbCwgdGhpcy5fZGVmYXVsdHMuaW5pdGlhbCkpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbWluOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodGhpcy5nZXRPckVsc2UodGhpcy5qc29uTW9kZWwubWluLCB0aGlzLl9kZWZhdWx0cy5taW4pKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbihuTWluKSB7CiAgICAgICAgICAgIAl0aGlzLmpzb25Nb2RlbC5taW4gPSBuTWluICsgIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBtYXg6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh0aGlzLmdldE9yRWxzZSh0aGlzLmpzb25Nb2RlbC5tYXgsIHRoaXMubWluKSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24obk1heCkgewogICAgICAgICAgICAJdGhpcy5qc29uTW9kZWwubWF4ID0gbk1heCArICIiOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcGxheUpzb24gOiBmdW5jdGlvbihwSnNvbk1vZGVsKSB7CgogICAgICAgIH0KCiAgICB9KQp9KShfLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5JbnN0YW5jZU1hbmFnZXIKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk5vZGUKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk9jY3VyCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgSW5zdGFuY2VNYW5hZ2VyIENsYXNzIHJlcXVpcmVkIGZvciBYRkEKICogICAgICAgICAgICAgICBsaWJyYXJ5CiAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyBhIEluc3RhbmNlIE1hbmFnZXIgdG8gbWFuYWdlIG11bHRpcGxlIGluc3RhbmNlIG9mCiAqICAgICAgICBzdWJmb3JtcwogKiBAdmVyc2lvbiAwLjAuMQogKi8KCihmdW5jdGlvbiAoXywgeGZhbGliKSB7CgogICAgdmFyIEluc3RhbmNlTWFuYWdlciA9IHhmYWxpYi5zY3JpcHQuSW5zdGFuY2VNYW5hZ2VyID0geGZhbGliLnNjcmlwdC5Ob2RlLmV4dGVuZCgKICAgICAgICB7CiAgICAgICAgICAgIG1zQ2xhc3NOYW1lOiAiaW5zdGFuY2VNYW5hZ2VyIiwKICAgICAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgSW5zdGFuY2VNYW5hZ2VyLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgICB0aGlzLl9vY2N1ciA9IG5ldyB4ZmFsaWIuc2NyaXB0Lk9jY3VyKHsianNvbk1vZGVsIjogdGhpcy5qc29uTW9kZWx9KTsKICAgICAgICAgICAgICAgIHRoaXMubW9DaGlsZHJlbkNyZWF0ZWQgPSBbXTsKICAgICAgICAgICAgICAgIHRoaXMubW5DdXJyZW50ID0gMDsKICAgICAgICAgICAgICAgIHRoaXMubWJTdGFuZGFsb25lID0gZmFsc2U7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfaW5zdGFuY2VUZW1wbGF0ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50OwogICAgICAgICAgICAgICAgaWYgKHRoaXMuX3RlbXBsYXRlUmVmKCkgPT0gbnVsbCB8fCBwYXJlbnQgPT0gbnVsbCB8fCBwYXJlbnQuX3RlbXBsYXRlUmVmKCkgPT0gbnVsbCB8fCBwYXJlbnQuX3RlbXBsYXRlUmVmKCkuY2hpbGRyZW4gPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIHZhciB0bXBsdFBhcmVudCA9IHBhcmVudC5fdGVtcGxhdGVSZWYoKTsKICAgICAgICAgICAgICAgIHZhciBpbUluZGV4ID0gdG1wbHRQYXJlbnQuY2hpbGRyZW4uaW5kZXhPZih0aGlzLl90ZW1wbGF0ZVJlZigpKTsKICAgICAgICAgICAgICAgIGlmIChpbUluZGV4IDwgMCB8fCB0bXBsdFBhcmVudC5jaGlsZHJlbi5sZW5ndGggPCBpbUluZGV4ICsgMikKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiB0bXBsdFBhcmVudC5jaGlsZHJlbltpbUluZGV4ICsgMV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBfaXNSZXBlYXRhYmxlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgbWF4OwogICAgICAgICAgICAgICAgcmV0dXJuICgobWF4ID0gK3RoaXMubWF4KSA8IDAgfHwgK3RoaXMubWluIDwgbWF4KTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9pc0luc3RhbmNlTWFuYWdlcjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogTWFuYWdlIGEgY2hpbGQgaW5zdGFuY2UgdGhhdCB3YXMgY3JlYXRlZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIG9DcmVhdGVkQ2hpbGQKICAgICAgICAgICAgICogICAgICAgIHRoZSBjaGlsZCB0byBiZSBtYW5hZ2VkLgogICAgICAgICAgICAgKi8KCgogICAgICAgICAgICBfbWFuYWdlQ2hpbGQ6IGZ1bmN0aW9uIChvQ3JlYXRlZENoaWxkLCBuSW5kZXgpIHsKICAgICAgICAgICAgICAgIG9DcmVhdGVkQ2hpbGQuX2luc3RhbmNlTWFuYWdlciA9IHRoaXM7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5tb0NoaWxkcmVuQ3JlYXRlZC5sZW5ndGggPj0gMSkgewogICAgICAgICAgICAgICAgICAgIG9DcmVhdGVkQ2hpbGQgPSB0aGlzLl91cGRhdGVEYXRhU29tRm9yUmVwZWF0ZWRSb3dzKG9DcmVhdGVkQ2hpbGQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG5JbmRleCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb0NoaWxkcmVuQ3JlYXRlZC5zcGxpY2UodGhpcy5tbkN1cnJlbnQsIDAsIG9DcmVhdGVkQ2hpbGQpOwogICAgICAgICAgICAgICAgICAgIG9DcmVhdGVkQ2hpbGQubW5JbnN0YW5jZUluZGV4ID0gdGhpcy5tbkN1cnJlbnQrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoaXMubW9DaGlsZHJlbkNyZWF0ZWQuc3BsaWNlKG5JbmRleCwgMCwgb0NyZWF0ZWRDaGlsZCk7CiAgICAgICAgICAgICAgICAgICAgb0NyZWF0ZWRDaGlsZC5tbkluc3RhbmNlSW5kZXggPSBuSW5kZXg7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tbkN1cnJlbnQrKzsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gbkluZGV4ICsgMTsgaSA8IHRoaXMubW9DaGlsZHJlbkNyZWF0ZWQubGVuZ3RoOyBpKyspCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubW9DaGlsZHJlbkNyZWF0ZWRbaV0ubW5JbnN0YW5jZUluZGV4ID0gaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9yZXBsYWNlTGFzdE9jY3VycmVuY2VPZlN1YlN0cmluZzogZnVuY3Rpb24oc3RyaW5nLCBmaW5kLCByZXBsYWNlKSB7CiAgICAgICAgICAgICAgICB2YXIgbGFzdEluZGV4ID0gc3RyaW5nLmxhc3RJbmRleE9mKGZpbmQpOwogICAgICAgICAgICAgICAgaWYgKGxhc3RJbmRleCA9PT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyaW5nOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIGJlZ2luU3RyaW5nID0gc3RyaW5nLnN1YnN0cmluZygwLCBsYXN0SW5kZXgpOwogICAgICAgICAgICAgICAgdmFyIGVuZFN0cmluZyA9IHN0cmluZy5zdWJzdHJpbmcobGFzdEluZGV4ICsgZmluZC5sZW5ndGgpOwogICAgICAgICAgICAgICAgcmV0dXJuIGJlZ2luU3RyaW5nICsgcmVwbGFjZSArIGVuZFN0cmluZzsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF91cGRhdGVEYXRhU29tRm9yUmVwZWF0ZWRSb3dzOiBmdW5jdGlvbihvQ3JlYXRlZENoaWxkKSB7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudERhdGFTb20gPSBvQ3JlYXRlZENoaWxkLmpzb25Nb2RlbC5leHRyYXMuZGF0YVNvbTsKICAgICAgICAgICAgICAgIHZhciBsZW5ndGhPZkNoaWxkQ3JlYXRlZCA9IHRoaXMubW9DaGlsZHJlbkNyZWF0ZWQubGVuZ3RoOwogICAgICAgICAgICAgICAgdmFyIGxhc3RBZGRlZFJvd0RhdGFTb20gPSB0aGlzLm1vQ2hpbGRyZW5DcmVhdGVkW2xlbmd0aE9mQ2hpbGRDcmVhdGVkIC0gMV0uanNvbk1vZGVsLmV4dHJhcy5kYXRhU29tOwogICAgICAgICAgICAgICAgaWYgKGN1cnJlbnREYXRhU29tICYmIGxhc3RBZGRlZFJvd0RhdGFTb20pIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXhUb1VwZGF0ZSA9IGN1cnJlbnREYXRhU29tLnN1YnN0cmluZyhjdXJyZW50RGF0YVNvbS5sYXN0SW5kZXhPZigiWyIpICsgMSwgY3VycmVudERhdGFTb20ubGFzdEluZGV4T2YoIl0iKSk7CiAgICAgICAgICAgICAgICAgICAgdmFyIHVwZGF0ZWREYXRhU29tSW5kZXggPSBsYXN0QWRkZWRSb3dEYXRhU29tLnN1YnN0cmluZyhsYXN0QWRkZWRSb3dEYXRhU29tLmxhc3RJbmRleE9mKCJbIikgKyAxLCBsYXN0QWRkZWRSb3dEYXRhU29tLmxhc3RJbmRleE9mKCJdIikpOwogICAgICAgICAgICAgICAgICAgIHVwZGF0ZWREYXRhU29tSW5kZXgrKzsKICAgICAgICAgICAgICAgICAgICB2YXIgdXBkYXRlZERhdGFTb20gPSB0aGlzLl9yZXBsYWNlTGFzdE9jY3VycmVuY2VPZlN1YlN0cmluZyhjdXJyZW50RGF0YVNvbSwgaW5kZXhUb1VwZGF0ZSwgdXBkYXRlZERhdGFTb21JbmRleCk7CiAgICAgICAgICAgICAgICAgICAgb0NyZWF0ZWRDaGlsZC5qc29uTW9kZWwuZXh0cmFzLmRhdGFTb20gPSB1cGRhdGVkRGF0YVNvbTsKICAgICAgICAgICAgICAgICAgICBvQ3JlYXRlZENoaWxkLnJlc29sdmVOb2RlKCIjZXh0cmFzLkZTX0VYVFJBUy5GU19EQVRBX1NPTSIpLnZhbHVlID0gdXBkYXRlZERhdGFTb207CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gb0NyZWF0ZWRDaGlsZDsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgICAgICAvL3dlIGRvbid0IG5lZWQgSW5zdGFuY2VNYW5hZ2VyIGZvciBmaW5hbCBzdWJtaXNzaW9uIGlmIHRoZXJlIGlzIG9ubHkgb25lIGluc3RhbmNlLCBhbmQgaXQncyBub3QgYSByZXBlYXRhYmxlIFNGCiAgICAgICAgICAgICAgICAvLyBidXQgbmVlZCBpdCBmb3IgbWFpbnRhaW5pbmcgaGllcmFyY2h5IGluIHJlc3RvcmVGb3JtU3RhdGUKICAgICAgICAgICAgICAgIHJldHVybiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuc3RyaXBPckNhbGwuY2FsbCh0aGlzLCBkaWZmX2xldmVsID09PSAyICYmICghdGhpcy5faXNSZXBlYXRhYmxlKCkgJiYgdGhpcy5tb0NoaWxkcmVuQ3JlYXRlZC5sZW5ndGggPD0gMSksIEluc3RhbmNlTWFuYWdlci5fc3VwZXIuX2NvbXB1dGVKc29uRGlmZiwgYXJndW1lbnRzKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGFkZCBhbiBpbnN0YW5jZSBvZiB0aGUgcmVwZWF0YWJsZSBzdWJmb3JtLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYWRkSW5zdGFuY2U6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9pbnNlcnRJbnN0YW5jZSgpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgX2luc2VydEluc3RhbmNlOiBmdW5jdGlvbiAobkluZGV4LCBvQ2hpbGRBZGRlZCkgewogICAgICAgICAgICAgICAgaWYgKCgrdGhpcy5tYXggPj0gMCkgJiYgKCt0aGlzLm1heCA9PSB0aGlzLmNvdW50KSkgLy9UT0RPIDogZGlzY3VzcyB3aGV0aGVyIHRvIHVzZSBwcml2YXRlIHZhcmlhYmxlcyBvciBub3QKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIGlmIChuSW5kZXggIT09IHVuZGVmaW5lZCAmJiBuSW5kZXggPiArdGhpcy5jb3VudCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKCiAgICAgICAgICAgICAgICBpZiAob0NoaWxkQWRkZWQgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgIHZhciBzZlRlbXBsYXRlID0gdGhpcy5faW5zdGFuY2VUZW1wbGF0ZSgpOwogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgLy8gbmVlZHMgdG8gYWRkIGFuIGluc3RhbmNlIHRvIHRoZSBtb2RlbAogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgaWYgKHNmVGVtcGxhdGUgPT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNsb25lZEpzb24gPSB7fTsKICAgICAgICAgICAgICAgICAgICB2YXIgdW5pcXVlUHJlZml4ID0gdGhpcy54ZmFVdGlsKCkuZ2VuZXJhdGVVSUQoKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmNvcHlPYmplY3Qoc2ZUZW1wbGF0ZSwgY2xvbmVkSnNvbiwKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhjZXB0aW9uczogWyJodG1sSWQiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybU1hcHM6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGF0YUlkIjogZnVuY3Rpb24gKHNyY1ZhbHVlLCBvcHRpb25zKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmlxdWVQcmVmaXggKyAiXyIgKyBzcmNWYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIG9DaGlsZEFkZGVkID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5LnByb3RvdHlwZS5jcmVhdGVNb2RlbChjbG9uZWRKc29uKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChvQ2hpbGRBZGRlZCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAvLyBmaXJzdCBhZGQgdGhlIGNoaWxkIHRvIHRoZSBsaXN0IG9mIG1hbmFnZWQgY2hpbGRyZW4KICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgIG9DaGlsZEFkZGVkLl9uZXdDaGlsZCA9IHRydWUKICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYW5hZ2VDaGlsZChvQ2hpbGRBZGRlZCwgbkluZGV4KTsKICAgICAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgICAgIC8vVE9ETzogSWYgbm90IHN0YW5kYWxvbmUgbW9kZSwgYWRkIHRoZSBuZXcgaXRlbSB0byB0aGUgcGFyZW50IGNvbnRhaW5lciBhcyB3ZWxsLiBVbmRlcnN0YW5kaW5nIHN0YW5kYWxvbmUgbW9kZQogICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubWJTdGFuZGFsb25lID09IHRydWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5JbmRleCAhPT0gdW5kZWZpbmVkKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb0NoaWxkQWRkZWQuaW5kZXggPSBuSW5kZXg7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9DaGlsZEFkZGVkLmluZGV4ID0gdGhpcy5tbkN1cnJlbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIG9DaGlsZEFkZGVkLnBhcmVudCA9IHRoaXMucGFyZW50OwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvUGFyZW50Q29udGFpbmVyID0gdGhpcy5wYXJlbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvUGFyZW50Q29udGFpbmVyICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm1uQ3VycmVudCA+IDEgJiYgbkluZGV4IT09MCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgd2UgYWxyZWFkeSBoYWQgY2hpbGRyZW4gZ2V0IHRoZSBpbmRleCBvZiBmaXJzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNoaWxkIGluIHRoZSBwYXJlbnQgY29udGFpbmVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuSW5kZXggPSBuSW5kZXggIT09IHVuZGVmaW5lZCA/IG5JbmRleCA6IHRoaXMubW5DdXJyZW50IC0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbkluc2VydGlvbkluZGV4ID0gb1BhcmVudENvbnRhaW5lcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuX2dldENoaWxkSW5kZXgodGhpcy5tb0NoaWxkcmVuQ3JlYXRlZFtuSW5kZXggLSAxXSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkluc2VydGlvbkluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb1BhcmVudENvbnRhaW5lci5fYWRkQ2hpbGRBdChvQ2hpbGRBZGRlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkluc2VydGlvbkluZGV4KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIGlzIHRoZSBmaXJzdCBjaGlsZCwgYWRkIGl0IGp1c3QgYWZ0ZXIgdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5zdGFuY2UgbWFuYWdlcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb1BhcmVudENvbnRhaW5lci5fYWRkQ2hpbGRBdChvQ2hpbGRBZGRlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9QYXJlbnRDb250YWluZXIuX2dldENoaWxkSW5kZXgodGhpcykgKyAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKF8uY29udGFpbnMoWydJTklUSUFMSVpFRCcsICdJTklUSUFMSVpJTkcnXSwgdGhpcy5feGZhKCkuX21vZGVsSW5pdGlhbGl6ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9DaGlsZEFkZGVkLmV4ZWNJbml0aWFsaXplKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiB0aGUgaW5zdGFuY2UgYmVpbmcgYWRkZWQgaXMgdGhlIGZpcnN0IG9uZSwgd2UgbmVlZCB0byBydW4gZXhlY0NhbGN1bGF0ZSBvbiB0aGUgZm9ybSB0byBnZXQgZGVwZW5kZW50cwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIHRoZSBpbnN0YW5jZSBiZWluZyBhZGRlZC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvdW50ID09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5mb3JtLmV4ZWNDYWxjdWxhdGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZpcnN0SW5zdGFuY2UgPSB0aGlzLmluc3RhbmNlc1swXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmlnZ2VyQ2FsY3VsYXRlRm9yRGVwZW5kYW50RmllbGRzKGZpcnN0SW5zdGFuY2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9DaGlsZEFkZGVkLmV4ZWNDYWxjdWxhdGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLkxvZ2dlci5lcnJvcigieGZhIiwgeGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDEzIl0sIFsiYWRkSW5zdGFuY2UiXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9DaGlsZEFkZGVkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBpbnNlcnRJbnN0YW5jZTogZnVuY3Rpb24gKG5JbmRleCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2luc2VydEluc3RhbmNlKG5JbmRleCk7CiAgICAgICAgICAgIH0sCgoKICAgICAgICAgICAgbW92ZUluc3RhbmNlOiBmdW5jdGlvbiAoc0luZGV4LCBkSW5kZXgpIHsKICAgICAgICAgICAgICAgIGlmICgoK3RoaXMubWF4ID49IDApICYmIGRJbmRleCA+PSArdGhpcy5jb3VudCB8fCBzSW5kZXggPj0gK3RoaXMuY291bnQgfHwgc0luZGV4ID09IGRJbmRleCkgLy9UT0RPIDogZGlzY3VzcyB3aGV0aGVyIHRvIHVzZSBwcml2YXRlIHZhcmlhYmxlcyBvciBub3QKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgICAgIHZhciB0SW5kZXgsCiAgICAgICAgICAgICAgICAgICAgb1BhcmVudENvbnRhaW5lciA9IHRoaXMucGFyZW50LAogICAgICAgICAgICAgICAgICAgIG9DaGlsZCA9IHRoaXMubW9DaGlsZHJlbkNyZWF0ZWRbc0luZGV4XSwKICAgICAgICAgICAgICAgICAgICB0c0luZGV4ID0gZEluZGV4IDwgc0luZGV4ID8gc0luZGV4ICsgMSA6IHNJbmRleCwKICAgICAgICAgICAgICAgICAgICB0ZEluZGV4ID0gZEluZGV4ID4gc0luZGV4ID8gZEluZGV4ICsgMSA6IGRJbmRleDsKICAgICAgICAgICAgICAgIHRoaXMubWF4Kys7CiAgICAgICAgICAgICAgICB2YXIgbmV3Q2hpbGQgPSB0aGlzLl9pbnNlcnRJbnN0YW5jZSh0ZEluZGV4KTsKICAgICAgICAgICAgICAgIHRoaXMubWF4LS07CiAgICAgICAgICAgICAgICBuZXdDaGlsZC5wbGF5SnNvbihvQ2hpbGQuanNvbk1vZGVsKTsKICAgICAgICAgICAgICAgIGlmIChvUGFyZW50Q29udGFpbmVyICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuQ0hJTERfTU9WRUQsIG9QYXJlbnRDb250YWluZXIsICJjaGlsZCIsIG51bGwsIG51bGwpOwogICAgICAgICAgICAgICAgICAgIG9QYXJlbnRDb250YWluZXIudHJpZ2dlcihldm50Lm5hbWUsIGV2bnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVJbnN0YW5jZSh0c0luZGV4KTsKICAgICAgICAgICAgfSwKCgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBhZGQgYW4gaW5zdGFuY2Ugb2YgdGhlIHJlcGVhdGFibGUgc3ViZm9ybS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJlbW92ZUluc3RhbmNlOiBmdW5jdGlvbiAoaW5kZXgpIHsKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAvLyBkb24ndCByZW1vdmUgYW55IG1vcmUgdGhhbiB0aGUgbWluaW11bQogICAgICAgICAgICAgICAgLy8KICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvdW50ID09IDAgfHwgdGhpcy5taW4gPT0gdGhpcy5jb3VudCkKICAgICAgICAgICAgICAgICAgICByZXR1cm47CgogICAgICAgICAgICAgICAgaWYgKGluZGV4ID49ICt0aGlzLmNvdW50KQogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIC8vCiAgICAgICAgICAgICAgICAvLyBuZWVkcyB0byByZW1vdmUgYW4gaW5zdGFuY2UgdG8gdGhlIG1vZGVsCiAgICAgICAgICAgICAgICAvLwogICAgICAgICAgICAgICAgdmFyIGZpcnN0SW5zdGFuY2UgPSB0aGlzLmluc3RhbmNlc1swXTsKICAgICAgICAgICAgICAgIHZhciBvQ2hpbGQgPSB0aGlzLm1vQ2hpbGRyZW5DcmVhdGVkW2luZGV4XTsKICAgICAgICAgICAgICAgIHRoaXMubW9DaGlsZHJlbkNyZWF0ZWQuc3BsaWNlKGluZGV4LCAxKTsKICAgICAgICAgICAgICAgIHRoaXMubW5DdXJyZW50LS07CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gaW5kZXg7IGkgPCB0aGlzLm1vQ2hpbGRyZW5DcmVhdGVkLmxlbmd0aDsgaSsrKQogICAgICAgICAgICAgICAgICAgIHRoaXMubW9DaGlsZHJlbkNyZWF0ZWRbaV0ubW5JbnN0YW5jZUluZGV4ID0gaTsKICAgICAgICAgICAgICAgIHZhciBwYXJlbnQgPSBvQ2hpbGQucGFyZW50OwogICAgICAgICAgICAgICAgcGFyZW50Ll9yZW1vdmVDaGlsZChvQ2hpbGQpOwoKICAgICAgICAgICAgICAgIGlmIChfLmNvbnRhaW5zKFsnSU5JVElBTElaRUQnLCAnSU5JVElBTElaSU5HJ10sIHRoaXMuX3hmYSgpLl9tb2RlbEluaXRpYWxpemUpKSB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlckNhbGN1bGF0ZUZvckRlcGVuZGFudEZpZWxkcyhmaXJzdEluc3RhbmNlKTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5Mb2dnZXIuZXJyb3IoInhmYSIsIHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAxMyJdLCBbInJlbW92ZUluc3RhbmNlIl0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGVtcHR5IGZ1bmN0aW9uIHNpbmNlIHRoZXJlIGlzIG5vIGRhdGEgYXNzb2NpYXRlZCB3aXRoIElNCiAgICAgICAgICAgICAqLwogICAgICAgICAgICByZXNldERhdGE6IGZ1bmN0aW9uICgpIHsKCiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBzZXRJbnN0YW5jZXM6IGZ1bmN0aW9uIChudW0pIHsKICAgICAgICAgICAgICAgIHRoaXMuY291bnQgPSBudW07CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBnZXROYWtlZDogZnVuY3Rpb24gKG5JbmRleCwgY3JlYXRlR2V0dGVyU2V0dGVyLCBPYmosIHNjb3BlKSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5nZXRBdHRyaWJ1dGUoIm5hbWUiKS5sZW5ndGggPiAwICYmIHRoaXMuZ2V0QXR0cmlidXRlKCJuYW1lIikgIT0gIl8iKQogICAgICAgICAgICAgICAgICAgIEluc3RhbmNlTWFuYWdlci5fc3VwZXIuZ2V0TmFrZWQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIHBsYXlKc29uOiBmdW5jdGlvbiAocEpzb25Nb2RlbCkgewoKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVHJpZ2dlciBjYWxjdWxhdGUgZXZlbnQgZm9yIG9ubHkgdGhlIGRlcGVuZGVudCBmaWVsZHMgaW4gdGhlIHJlcGVhdGFibGUgc3ViZm9ybQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgX3RyaWdnZXJDYWxjdWxhdGVGb3JEZXBlbmRhbnRGaWVsZHMgOiBmdW5jdGlvbiAobW9kZWwpIHsKICAgICAgICAgICAgICAgIHZhciBtb2RlbENoaWxkcmVuID0gbW9kZWwubW9DaGlsZE5vZGVzOwogICAgICAgICAgICAgICAgXy5lYWNoKG1vZGVsQ2hpbGRyZW4sIGZ1bmN0aW9uKG1vZGVsQ2hpbGQpewogICAgICAgICAgICAgICAgICAgIC8vIHRyaWdnZXIgY2FsY3VsYXRlIGZvciB0aGUgZGVwZW5kZW50cyBvZiB0aGUgZmllbGQgYW5kIGV4Y2x1c2lvbiBncm91cAogICAgICAgICAgICAgICAgICAgIGlmIChtb2RlbENoaWxkLl9pc0ZpZWxkKCkgfHwgbW9kZWxDaGlsZC5faXNFeGNsdXNpb25Hcm91cCgpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZXBlbmRhbnROb2RlcyA9IG1vZGVsQ2hpbGQuZGVwZW5kYW50OwogICAgICAgICAgICAgICAgICAgICAgICBfLmVhY2goZGVwZW5kYW50Tm9kZXMsIGZ1bmN0aW9uKGRlcGVuZGFudE5vZGUpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwZW5kYW50Tm9kZS5leGVjRXZlbnQoImNhbGN1bGF0ZSIpOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG1vZGVsQ2hpbGQuX2lzRXZlbnROb2RlKCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlckNhbGN1bGF0ZUZvckRlcGVuZGFudEZpZWxkcyhtb2RlbENoaWxkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgKTsKICAgIEluc3RhbmNlTWFuYWdlci5kZWZpbmVQcm9wcyh7CiAgICAgICAgIm1pbiI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vY2N1ci5taW4gKyAiIjsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAobk1pbikgewogICAgICAgICAgICAgICAgdGhpcy5vY2N1ci5taW4gPSBuTWluOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAibWF4IjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9jY3VyLm1heCArICIiOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuTWF4KSB7CiAgICAgICAgICAgICAgICB0aGlzLm9jY3VyLm1heCA9IG5NYXg7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAib2NjdXIiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29jY3VyOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAvLyBUaGlzIEFQSSBpcyB1c2VkIGluIGFkYXB0aXZlIGZvcm0KICAgICAgICAiaW5zdGFuY2VzIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIF8uZXh0ZW5kKFtdLCB0aGlzLm1vQ2hpbGRyZW5DcmVhdGVkKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJjb3VudCI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tb0NoaWxkcmVuQ3JlYXRlZC5sZW5ndGggKyAiIjsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBwYXJzZUludCh2YWx1ZSkpCiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZUludCh2YWx1ZSk7CiAgICAgICAgICAgICAgICBlbHNlIHJldHVybjsKICAgICAgICAgICAgICAgIHZhciBjb3VudCA9ICt0aGlzLmNvdW50LAogICAgICAgICAgICAgICAgICAgIHR2YWx1ZSA9IE1hdGguYWJzKHZhbHVlIC0gY291bnQpLAogICAgICAgICAgICAgICAgICAgIG1heCA9ICt0aGlzLm1heCwKICAgICAgICAgICAgICAgICAgICBtaW4gPSArdGhpcy5taW47CiAgICAgICAgICAgICAgICAvL0J1ZyMzNTQ0MzY4IHZhbHVlID4gbWF4IGNvbmRpdGlvbiB3aWxsIG9ubHkgaG9sZCBpZiBtYXggaXMgcG9zaXRpdmUgKGlmIG1heCA9PSAtMQogICAgICAgICAgICAgICAgLy8gdGhlcmUgaXMgbm8gbGltaXQgb24gdGhlIHVwcGVyIGNvdW50ICkKICAgICAgICAgICAgICAgIGlmICgobWF4ID4gMCAmJiB2YWx1ZSA+IG1heCkgfHwgdmFsdWUgPCBtaW4gfHwgdmFsdWUgPT0gY291bnQpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgaWYgKHZhbHVlID4gY291bnQpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR2YWx1ZTsgaSsrKQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbnNlcnRJbnN0YW5jZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHZhbHVlIDwgY291bnQpIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR2YWx1ZTsgaSsrKQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUluc3RhbmNlKC0tY291bnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSkKfSkoXywgeGZhbGliKTsKCi8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LkV4Y2x1c2lvbkdyb3VwCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Db250YWluZXJOb2RlCiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgRXhjbHVzaW9uR3JvdXAgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQQogKiAgICAgICAgICAgICAgIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIC8qKgogICAgICogQ3JlYXRlcyBhIG5ldyBFeGNsdXNpb25Hcm91cCBjbGFzcwogICAgICoKICAgICAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyBhIEV4Y2x1c2lvbkdyb3VwIGluIHRoZSBYRkEgRG9tCiAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAqICAgICAgICAgICAgbmFtZSB0aGUgbmFtZSBvZiB0aGUgbm9kZQogICAgICogQGV4dGVuZHMgY29tLmFkb2JlLnhmYS5zY3JpcHRpbmcuQ29udGFpbmVyTm9kZQogICAgICovCiAgICB2YXIgRXhjbHVzaW9uR3JvdXAgPSB4ZmFsaWIuc2NyaXB0LkV4Y2x1c2lvbkdyb3VwID0geGZhbGliLnNjcmlwdC5FdmVudENvbnRhaW5lck5vZGUuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIEV4Y2x1c2lvbkdyb3VwLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMudGVzdHM9IFt0aGlzLl9udWxsVGVzdCx0aGlzLl9zY3JpcHRUZXN0XTsKICAgICAgICAgICAgdmFyIGRhdGFJZCA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMsICJqc29uTW9kZWwuZXh0cmFzLmRhdGFJZCIsIG51bGwpOwogICAgICAgICAgICBpZiAoZGF0YUlkKSB7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5jcmVhdGVEYXRhTm9kZShkYXRhSWQsIHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldE9uQ2hpbGQ6IGZ1bmN0aW9uKG90aGVyQ2hpbGQpIHsKICAgICAgICAgICAgcmV0dXJuIF8uZmluZCh0aGlzLm1vQ2hpbGROb2RlcywgZnVuY3Rpb24oY2hpbGQpIHsKICAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGQuY2xhc3NOYW1lID09ICJmaWVsZCIgJiYgY2hpbGQuc2VsZWN0ZWRJbmRleCA9PSAwICYmIGNoaWxkICE9IG90aGVyQ2hpbGQKICAgICAgICAgICAgfSkKICAgICAgICB9LAoKICAgICAgICBfZXZlbnRIYW5kbGVyIDogZnVuY3Rpb24oZXZlbnROYW1lKSB7CiAgICAgICAgICAgIHZhciByVmFsdWUgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIHN3aXRjaChldmVudE5hbWUpIHsKICAgICAgICAgICAgICAgIGNhc2UgImNhbGN1bGF0ZSI6CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl0gJiYgdGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl0ubGVuZ3RoID4wKXsKICAgICAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdGhpcy5tb0V2ZW50c1siY2FsY3VsYXRlIl1bMF0uZXhlY3V0ZSh0aGlzLCAiY2FsY3VsYXRlIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAidmFsaWRhdGUiOgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMubW9FdmVudHNbInZhbGlkYXRlIl0gJiYgdGhpcy5tb0V2ZW50c1sidmFsaWRhdGUiXS5sZW5ndGggPjApewogICAgICAgICAgICAgICAgICAgICAgICByVmFsdWUgPSB0aGlzLm1vRXZlbnRzWyJ2YWxpZGF0ZSJdWzBdLmV4ZWN1dGUodGhpcywgInZhbGlkYXRlIik7CiAgICAgICAgICAgICAgICAgICAgfWVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgclZhbHVlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIiRmb3JtcHJlU3VibWl0IjoKICAgICAgICAgICAgICAgICAgICByVmFsdWUgPSB0aGlzLl9wcmVTdWJtaXRFdmVudEhhbmRsZXIoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubW9FdmVudHNbZXZlbnROYW1lXSkgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKCB2YXIgaSA9IDA7IGkgPCB0aGlzLm1vRXZlbnRzW2V2ZW50TmFtZV0ubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubW9FdmVudHNbZXZlbnROYW1lXVtpXS5leGVjdXRlKHRoaXMsIGV2ZW50TmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9Ci8vICAgICAgICAgICAgICAgICAgICBFeGNsdXNpb25Hcm91cC5fc3VwZXIuX2V2ZW50SGFuZGxlci5jYWxsKHRoaXMsIGV2ZW50TmFtZSk7ICAvL1RPRE86IFdoeSB0aGlzIGlzIHJlcXVpcmVkPwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByVmFsdWUKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlU2VsZWN0Q2hpbGQgOiBmdW5jdGlvbihjaGlsZCkgewogICAgICAgICAgICB2YXIgb2xkVmFsID0gdGhpcy5yYXdWYWx1ZSwKICAgICAgICAgICAgICAgIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsIkNsZWFyRXJyb3IiLG51bGwsIG51bGwpLAogICAgICAgICAgICAgICAgb25DaGlsZCA9IHRoaXMuX2dldE9uQ2hpbGQoY2hpbGQpOwoKICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKCiAgICAgICAgICAgIGlmIChjaGlsZC5zZWxlY3RlZEluZGV4ID09IDApIHsKICAgICAgICAgICAgICAgIGlmKG9uQ2hpbGQpCiAgICAgICAgICAgICAgICAgICAgb25DaGlsZC5zZXRJdGVtU3RhdGUoMCxmYWxzZSk7CiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVEZXBlbmRhbnRzKCk7CiAgICAgICAgICAgICAgICAvLyB0cmlnZ2VyIG1vZGVsIGNoYW5nZSBldmVudCBmb3IgcmF3VmFsdWUsIHNvIHRoYXQgdmFsdWUgY2FuIGJlIHByb3BvZ2F0ZWQgdG8gcmVzdCBvZiB0aGUgZmllbGRzIHdpdGggc2FtZSBkYXRhSWQKICAgICAgICAgICAgICAgIHZhciBldm50UmF3VmFsdWUgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLCJyYXdWYWx1ZSIsdGhpcy5yYXdWYWx1ZSwgdGhpcy5yYXdWYWx1ZSk7CiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudFJhd1ZhbHVlLm5hbWUsZXZudFJhd1ZhbHVlKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChjaGlsZC5fbWF0Y2hlcyhvbkNoaWxkKSkgewogICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZURlcGVuZGFudHMoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHNlbGVjdGVkTWVtYmVyIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBjdXJyZW50Tm9kZSA9IHRoaXMuX3hmYSgpLm1vQ2FsY3VsYXRlRXZlbnROb2RlOwogICAgICAgICAgICBpZiAoY3VycmVudE5vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhpcy5hZGREZXBlbmRhbnQoY3VycmVudE5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRPbkNoaWxkKCk7CiAgICAgICAgfSwKCiAgICAgICAgX2lzRXhjbHVzaW9uR3JvdXAgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSwKCiAgICAgICAgX2dldFZhbHVlIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBvbkNoaWxkID0gdGhpcy5fZ2V0T25DaGlsZCgpCiAgICAgICAgICAgIHJldHVybiBvbkNoaWxkID8gb25DaGlsZC5fZ2V0VmFsdWUoKSA6IG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgX251bGxUZXN0IDogZnVuY3Rpb24oc01lc3NhZ2VzKSB7CiAgICAgICAgICAgIHZhciB2YWxpZCA9IHRydWU7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuX2dldFZhbHVlKCk7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsICYmIHRoaXMubWFuZGF0b3J5ICE9ICJkaXNhYmxlZCIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxUZXN0ID0gIm51bGxUZXN0IjsKICAgICAgICAgICAgICAgIHRoaXMuX21GYWlsZWRWYWxMZXZlbCA9IHRoaXMubWFuZGF0b3J5OwogICAgICAgICAgICAgICAgdGhpcy5fZXJyb3JUZXh0ID0gdGhpcy5tYW5kYXRvcnlNZXNzYWdlOwogICAgICAgICAgICAgICAgdGhpcy5fYWRkTWVzc2FnZShzTWVzc2FnZXMsIHRoaXMuX2Vycm9yVGV4dCwgdGhpcy5fbUZhaWxlZFZhbExldmVsKTsKICAgICAgICAgICAgICAgIHZhbGlkID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZhbGlkOwogICAgICAgIH0sCgogICAgICAgIF9nZXRFbGVtZW50c0Zyb21YcGF0aDogeGZhbGliLnNjcmlwdC5GaWVsZC5wcm90b3R5cGUuX2dldEVsZW1lbnRzRnJvbVhwYXRoLAoKICAgICAgICBfcHJlU3VibWl0RXZlbnRIYW5kbGVyOiB4ZmFsaWIuc2NyaXB0LkZpZWxkLnByb3RvdHlwZS5fcHJlU3VibWl0RXZlbnRIYW5kbGVyLAoKICAgICAgICAvKioKICAgICAgICAgKiBFeGNsdXNpb24gR3JvdXAgY2FuIGhhdmUgdHdvIHR5cGVzIG9mIHByZWZpbGwgeG1sLiBMb25nIGZvcm1hdCBhbmQgc2hvcnQgZm9ybWF0IC4gSW4gY2FzZSBvZiBMb25nIGZvcm1hdCwKICAgICAgICAgKiB0aGUgdmFsdWUgb2YgZWFjaCBvZiAgdGhlIGNoaWxkcmVuIG9mIGV4Y2x1c2lvbiBncm91cCBpcyBwcmVzZW50IGFuZCBoZW5jZSB3ZSBuZWVkIHRvIGl0ZXJhdGUgdGhlIGNoaWxkcmVuIHRvCiAgICAgICAgICogcHJlZmlsbCB0aGUgdmFsdWUuIEZvciBzaG9ydCBmb3JtYXQgdGhlIHRleHRDb250ZW50IGlzIHRoZSB2YWx1ZSBvZiB0aGUgRXhjbHVzaW9uIEdyb3VwCiAgICAgICAgICoKICAgICAgICAgKiBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBzaG9ydCBhbmQgTG9uZyBmb3JtYXQgaXMgdGhhdCBpbiBzaG9ydCBGb3JtYXQsIHRoZXJlIGFyZSBubyBjaGlsZHJlbiBvZiBFeGNsdXNpb24KICAgICAgICAgKiBHcm91cCBpbiB4bWwuCiAgICAgICAgICogQHBhcmFtIHhtbERvY3VtZW50CiAgICAgICAgICogQHBhcmFtIGNvbnRleHROb2RlCiAgICAgICAgICogQHBhcmFtIGN1cnJlbnRCaW5kUmVmCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfcGxheURhdGFYTUw6IGZ1bmN0aW9uKHhtbERvY3VtZW50LCBjb250ZXh0Tm9kZSwgY3VycmVudEJpbmRSZWYpIHsKICAgICAgICAgICAgdmFyIHhwYXRoID0gdGhpcy5fZ2V0WHBhdGhGcm9tQmluZFJlZigpLAogICAgICAgICAgICAgICAgbm9kZUl0ZXI7CiAgICAgICAgICAgIGlmKHhwYXRoICE9IG51bGwpIHsKICAgICAgICAgICAgICAgIG5vZGVJdGVyID0gdGhpcy5fZ2V0RWxlbWVudHNGcm9tWHBhdGgoeHBhdGgsIGNvbnRleHROb2RlLCB4bWxEb2N1bWVudCk7CiAgICAgICAgICAgICAgICBpZihub2RlSXRlciAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSBub2RlSXRlci5pdGVyYXRlTmV4dCgpOwogICAgICAgICAgICAgICAgICAgIGlmKG5vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBub2RlIGhhcyBmdXJ0aGVyIGVsZW1lbnQgY2hpbGRzIHRoZW4gaXRlcmF0ZSBvdmVyIHRoZW0gb3RoZXJ3aXNlIHNldCB0aGUgY29udGVudCBhcyBpdHMgcmF3VmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgaWYobm9kZS5jaGlsZEVsZW1lbnRDb3VudCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2x1c2lvbkdyb3VwLl9zdXBlci5fcGxheURhdGFYTUwuYXBwbHkodGhpcywgW3htbERvY3VtZW50LCBub2RlLCBjdXJyZW50QmluZFJlZl0pOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yYXdWYWx1ZSA9IG5vZGUudGV4dENvbnRlbnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2V0RGF0YSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgZ2VuZXJhdGVEYXRhWE1MOiB4ZmFsaWIuc2NyaXB0LkZpZWxkLnByb3RvdHlwZS5nZW5lcmF0ZURhdGFYTUwsCgogICAgICAgIF9hcHBlbmRWYWx1ZUluWE1MRWxlbWVudDogeGZhbGliLnNjcmlwdC5GaWVsZC5wcm90b3R5cGUuX2FwcGVuZFZhbHVlSW5YTUxFbGVtZW50CiAgICB9KTsKCiAgICBFeGNsdXNpb25Hcm91cC5kZWZpbmVQcm9wcyh7CiAgICAgICAgInJhd1ZhbHVlIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudE5vZGUgPSB0aGlzLl94ZmEoKS5tb0NhbGN1bGF0ZUV2ZW50Tm9kZTsKICAgICAgICAgICAgICAgIGlmIChjdXJyZW50Tm9kZSAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGREZXBlbmRhbnQoY3VycmVudE5vZGUpOwogICAgICAgICAgICAgICAgICAgIC8vIFRoZSBjaGlsZHJlbiBzaG91bGQgbm90IHJlZ2lzdGVyIHRoZQogICAgICAgICAgICAgICAgICAgIC8vIGNhbGN1bGF0ZU5vZGUgYXMgZGVwZW5kZW50IG9uIHRoZW0sIGVsc2UgdGhlCiAgICAgICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIGV2ZW50IGZvciBjYWxjdWxhdGVOb2RlIHdpbGwgYmUgY2FsbGVkCiAgICAgICAgICAgICAgICAgICAgLy8gbXVsdGlwbGUgdGltZXMuCiAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuX3BvcENhbGN1bGF0ZUV2ZW50Tm9kZSgpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciB2YWwgPSB0aGlzLl9nZXRWYWx1ZSgpOwoKICAgICAgICAgICAgICAgIGlmIChjdXJyZW50Tm9kZSAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLl9wdXNoQ2FsY3VsYXRlRXZlbnROb2RlKGN1cnJlbnROb2RlKTsKCiAgICAgICAgICAgICAgICByZXR1cm4gdmFsOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbihvVmFsdWUpIHsKICAgICAgICAgICAgCXZhciBzTWVzc2FnZXMgPSBuZXcgQXJyYXkoKSwKICAgICAgICAgICAgICAgICAgICBvbkNoaWxkID0gdGhpcy5fZ2V0T25DaGlsZCgpLAogICAgICAgICAgICAgICAgICAgIG9sZFZhbCA9IG9uQ2hpbGQgPyBvbkNoaWxkLl9nZXRWYWx1ZSgpIDogbnVsbAoKICAgICAgICAgICAgICAgIG9WYWx1ZSA9IHRoaXMudmFsaWRhdGVJbnB1dChvVmFsdWUsICJzdHJpbmciKTsKICAgICAgICAgICAgICAgIGlmIChvbGRWYWwgPT09IG9WYWx1ZSkKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICBpZiAob25DaGlsZCkgewogICAgICAgICAgICAgICAgICAgIG9uQ2hpbGQuc2V0SXRlbVN0YXRlKDAsIGZhbHNlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG9uQ2hpbGQgPSBfLmZpbmQodGhpcy5tb0NoaWxkTm9kZXMsIGZ1bmN0aW9uKGNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZC5jbGFzc05hbWUgPT0gImZpZWxkIiAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQuZ2V0T3JFbHNlKGNoaWxkLmdldFNhdmVJdGVtKDApLCBjaGlsZC5nZXREaXNwbGF5SXRlbSgwKSkgPT0gb1ZhbHVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIGlmIChvbkNoaWxkKQogICAgICAgICAgICAgICAgICAgIG9uQ2hpbGQucmF3VmFsdWUgPSBvVmFsdWU7CiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVEZXBlbmRhbnRzKCk7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5xdWV1ZVZhbGlkYXRlRXZlbnQodGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAibWFuZGF0b3J5IiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcy52YWxpZGF0ZS5udWxsVGVzdCwgdGhpcy5fZGVmYXVsdHMudmFsaWRhdGUubnVsbFRlc3QpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgaWYodGhpcy52YWxpZGF0ZSl7CiAgICAgICAgICAgICAgICAgICAgdGhpcy52YWxpZGF0ZS5udWxsVGVzdCA9IHZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgIm1lbWJlcnMiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHZhciBsaXN0ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICAgICAgdGhpcy5tb0NoaWxkTm9kZXMuZmlsdGVyKGZ1bmN0aW9uKGVsZW0pIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxlbS5faXNGaWVsZCgpOwogICAgICAgICAgICAgICAgfSkubWFwKGZ1bmN0aW9uKGVsZW0xKXsKICAgICAgICAgICAgICAgICAgICBsaXN0Ll9hcHBlbmQoZWxlbTEpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbGlzdDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJpc051bGwiOnsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgIGlmKHRoaXMuX2dldFZhbHVlKCkgIT0gbnVsbClyZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgIGVsc2UgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAibWFuZGF0b3J5TWVzc2FnZSIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5fZ2V0TWFuZGF0b3J5TWVzc2FnZSh0aGlzKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsKSB7CiAgICAgICAgICAgICAgICB2YXIgbm9kZXMgPSB0aGlzLnZhbGlkYXRlLm1lc3NhZ2Uubm9kZXM7CiAgICAgICAgICAgICAgICBpZiAobm9kZXMubmFtZWRJdGVtKCJudWxsVGVzdCIpID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSB0aGlzLl94ZmEoKS5mb3JtLmNyZWF0ZU5vZGUoInRleHQiLCAibnVsbFRlc3QiKTsKICAgICAgICAgICAgICAgICAgICBub2Rlcy5hcHBlbmQobm9kZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLnZhbGlkYXRlLm1lc3NhZ2UubnVsbFRlc3QudmFsdWUgPSB2YWw7CiAgICAgICAgICAgICAgICB0aGlzLmV4ZWNWYWxpZGF0ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7CgogICAgRXhjbHVzaW9uR3JvdXAuYWRkTWl4aW5zKFsKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZEFzc2lzdCwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZENhcHRpb24sCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRQcmVzZW5jZSwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFhZV0gsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRGaWxsQ29sb3IsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRCb3JkZXIsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRCb3JkZXJDb2xvciwKICAgICAgICB4ZmFsaWIuc2NyaXB0Lm1peGluLkFkZFBhcmEsCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRNYXJnaW4KICAgIF0pOwoKfSkoXywgeGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuTW9kZWwKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk5vZGUKICovCgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBNb2RlbCA9IHhmYWxpYi5zY3JpcHQuTW9kZWwgPSB4ZmFsaWIuc2NyaXB0LkVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZTogIm1vZGVsIiwKCiAgICAgICAgY3JlYXRlTm9kZSA6IGZ1bmN0aW9uKHNDbGFzc05hbWUsc05hbWUsc05hbWVzcGFjZSkgeyAgICAvL1RPRE86IGxvb2tzIGluY29tcGxldGUKICAgICAgICAgICAgc05hbWUgPSAodHlwZW9mIHNOYW1lICE9ICd1bmRlZmluZWQnKT9zTmFtZToiIjsKICAgICAgICAgICAgc05hbWVzcGFjZSA9ICh0eXBlb2Ygc05hbWVzcGFjZSAhPSAndW5kZWZpbmVkJyk/c05hbWVzcGFjZToiIjsKICAgICAgICAgICAgdmFyIGpzb25Nb2RlbCA9IHt9OwogICAgICAgICAgICBqc29uTW9kZWwuX2NsYXNzID0gc0NsYXNzTmFtZTsKICAgICAgICAgICAganNvbk1vZGVsLm5hbWUgPSBzTmFtZTsKICAgICAgICAgICAgdmFyIG5vZGUgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZU1vZGVsKGpzb25Nb2RlbCk7CiAgICAgICAgICAgIHJldHVybiBub2RlOwogICAgICAgIH0KICAgIH0pOwp9KShfLCB4ZmFsaWIpOwoKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuRm9ybQogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuQ29udGFpbmVyTm9kZQogKi8KCihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICAvKioKICAgICAqIEBjbGFzcwogICAgICogPHA+CiAgICAgKiBUaGUgRm9ybSBjbGFzcyBpcyB0aGUgaW1wbGVtZW50YXRpb24gb2YgdGhlIHRvcCBsZXZlbCBYRkEgZm9ybSBvYmplY3QuCiAgICAgKiA8L3A+CiAgICAgKgogICAgICogPHA+CiAgICAgKiBUaGUgZm9ybSBvYmplY3QgaXMgYWNjZXNzZWQgZnJvbSB0aGUgeGZhIG9iamVjdCBhcyB4ZmEuZm9ybQogICAgICogPC9wPgogICAgICoKICAgICAqLwogICAgdmFyIEZvcm0gPSB4ZmFsaWIuc2NyaXB0LkZvcm0gPSB4ZmFsaWIuc2NyaXB0LkV2ZW50Q29udGFpbmVyTm9kZS5leHRlbmQoewogICAgICAgIF9nZXRSb290U3ViZm9ybTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5jaGlsZHJlblswXTsKICAgICAgICB9LAoKICAgICAgICBfaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLl94ZmEoKS5fbW9kZWxJbml0aWFsaXplID0gJ0lOSVRJQUxJWklORyc7CiAgICAgICAgICAgIHZhciByb290U3ViZm9ybSA9IHRoaXMuX2dldFJvb3RTdWJmb3JtKCk7CiAgICAgICAgICAgIHJvb3RTdWJmb3JtLl9pbml0aWFsaXplKCk7CiAgICAgICAgICAgIC8vCiAgICAgICAgICAgIC8vIENhbGwgYWxsIGluaXRpYWxpemF0aW9uIHRoZW4KICAgICAgICAgICAgLy8gY2FsY3VsYXRpb25zCiAgICAgICAgICAgIC8vIHNjcmlwdHMgdG8gZXhlY3V0ZQogICAgICAgICAgICAvLwogICAgICAgICAgICB2YXIgcGdTZXRzID0gcm9vdFN1YmZvcm0ucmVzb2x2ZU5vZGVzKCIjcGFnZVNldFsqXSIpOwogICAgICAgICAgICBmdW5jdGlvbiBleGVjT25QZ1NldHMgKGV4ZWNGdW5jbmFtZSkgewogICAgICAgICAgICAgICAgZm9yKHZhciBpPTA7IGkgPCBwZ1NldHMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICBwZ1NldHMuaXRlbShpKVtleGVjRnVuY25hbWVdKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJvb3RTdWJmb3JtLmV4ZWNGb3JtUmVhZHkoKTsKICAgICAgICAgICAgZXhlY09uUGdTZXRzKCJleGVjRm9ybVJlYWR5Iik7CiAgICAgICAgICAgIHJvb3RTdWJmb3JtLmV4ZWNJbml0aWFsaXplKCk7CiAgICAgICAgICAgIGV4ZWNPblBnU2V0cygiZXhlY0luaXRpYWxpemUiKTsKICAgICAgICAgICAgcm9vdFN1YmZvcm0uZXhlY0xheW91dFJlYWR5KCk7CiAgICAgICAgICAgIGV4ZWNPblBnU2V0cygiZXhlY0xheW91dFJlYWR5Iik7CiAgICAgICAgICAgIHJvb3RTdWJmb3JtLmV4ZWNDYWxjdWxhdGUoKTsKICAgICAgICAgICAgdGhpcy5feGZhKCkuX21vZGVsSW5pdGlhbGl6ZSA9ICdJTklUSUFMSVpFRCc7CiAgICAgICAgfSwKCiAgICAgICAgcGxheUpzb246IGZ1bmN0aW9uIChwSnNvbk1vZGVsKSB7CiAgICAgICAgICAgIHRoaXMuX2dldFJvb3RTdWJmb3JtKCkucGxheUpzb24ocEpzb25Nb2RlbC5jaGlsZHJlblswXSk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKiBAZnVuY3Rpb24gaW5kaWNhdGUgdGhhdCB0aGlzIGlzIGEgRm9ybSBub2RlICh+fikuCiAgICAgICAgICovCiAgICAgICAgX2lzRm9ybTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBleGVjQ2FsY3VsYXRlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRSb290U3ViZm9ybSgpLmV4ZWNDYWxjdWxhdGUoKTsKICAgICAgICB9LAoKICAgICAgICBleGVjSW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLl9nZXRSb290U3ViZm9ybSgpLmV4ZWNJbml0aWFsaXplKCk7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY0Zvcm1SZWFkeTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLl9nZXRSb290U3ViZm9ybSgpLmV4ZWNGb3JtUmVhZHkoKTsKICAgICAgICB9LAoKICAgICAgICBleGVjTGF5b3V0UmVhZHk6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdGhpcy5fZ2V0Um9vdFN1YmZvcm0oKS5leGVjTGF5b3V0UmVhZHkoKTsKICAgICAgICB9LAoKICAgICAgICBleGVjVmFsaWRhdGU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldFJvb3RTdWJmb3JtKCkuZXhlY1ZhbGlkYXRlKCk7CiAgICAgICAgfSwKCiAgICAgICAgZXhlY1ByZVN1Ym1pdDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Um9vdFN1YmZvcm0oKS5leGVjUHJlU3VibWl0KCk7CiAgICAgICAgfSwKICAgICAgICAvKioKICAgICAgICAgKiByZW1lcmdlIHRoZSBkYXRhIHdpdGggdGhlIGZvcm0gbW9kZWwKICAgICAgICAgKi8KICAgICAgICByZW1lcmdlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuX2dldFJvb3RTdWJmb3JtKCkuX2JpbmQoKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiByZWNhbGN1bGF0ZSB0aGlzIGZvcm0gbW9kZWwKICAgICAgICAgKi8KICAgICAgICByZWNhbGN1bGF0ZTogZnVuY3Rpb24gKGJvb2wpIHsKICAgICAgICAgICAgdmFyIHhmID0gdGhpcy5feGZhKCk7CiAgICAgICAgICAgIGlmICh4Zi5ob3N0LmNhbGN1bGF0aW9uc0VuYWJsZWQpIHsKICAgICAgICAgICAgICAgIGlmICh4Zi5jYWxjdWxhdGVSdW5uaW5nKQogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIGlmIChib29sKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5leGVjQ2FsY3VsYXRlKCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5leGVjRm9ybVJlYWR5KCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHhmLnJ1bkNhbGNzKCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CiAgICAgICAgICAgIHZhciBkaWZmID0gRm9ybS5fc3VwZXIuX2NvbXB1dGVKc29uRGlmZi5jYWxsKHRoaXMsIGRpZmZfbGV2ZWwpOwogICAgICAgICAgICBkaWZmLmpzb25EaWZmZXJlbmNlWyJ2ZXJzaW9uTlMiXSA9IHRoaXMuanNvbk1vZGVsWyJ2ZXJzaW9uTlMiXTsKICAgICAgICAgICAgcmV0dXJuIHsgImNoYW5nZWQiOiB0cnVlLAogICAgICAgICAgICAgICAgImpzb25EaWZmZXJlbmNlIjogZGlmZi5qc29uRGlmZmVyZW5jZQogICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZU5vZGU6IHhmYWxpYi5zY3JpcHQuTW9kZWwucHJvdG90eXBlLmNyZWF0ZU5vZGUKCiAgICB9KTsKfSkoXywgeGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuSG9zdAogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuTm9kZQogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIEhvc3QgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKKGZ1bmN0aW9uKF8sIHhmYWxpYiwgJCl7CiAgICAvKioKICAgICAqIEBjbGFzcyBUaGUgY2xhc3MgcmVwcmVzZW50cyB0aGUgSG9zdCBPYmplY3QKICAgICAqIEBleHRlbmRzIGNvbS5hZG9iZS54ZmEuc2NyaXB0aW5nLk5vZGUKICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBhcHBUeXBlIHRoZSBhcHBsaWNhdGlvbiB0eXBlIG9mIHRoZSBob3N0CiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gY3VycmVudFBhZ2UgUGFnZSBudW1iZXIgb2YgdGhlIGZvcm0gdGhhdCBpcyBiZWluZwogICAgICogICAgICAgICAgIGRpc3BsYXllZAogICAgICogQHByb3BlcnR5IHtudW1iZXJ9IG51bVBhZ2VzIHRvdGFsIG51bWJlciBvZiBwYWdlcyBpbiB0aGUgZm9ybQogICAgICogQHByb3BlcnR5IHtuYW1lfSBuYW1lIG5hbWUgb2YgdGhlIGFwcGxpY2F0aW9uCiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gcGxhdGZvcm0gT1MgcGxhdGZvcm0gb24gd2hpY2ggdGhlIGFwcGxpY2F0aW9uIGlzIHJ1bm5pbmcKICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB0aXRsZSB0aXRsZSBvZiB0aGUgZG9jdW1lbnQKICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB2ZXJzaW9uIHZlcnNpb24gbnVtYmVyIG9mIHRoZSBjdXJyZW50IGFwcGxpY2F0aW9uCiAgICAgKi8KICAgIHZhciBIb3N0ID0geGZhbGliLnNjcmlwdC5Ib3N0ID0geGZhbGliLnNjcmlwdC5Ob2RlLmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJob3N0UHNldWRvTW9kZWwiLAogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICBIb3N0Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuanNvbk1vZGVsLm5hbWUgPSAiIjsKICAgICAgICAgICAgdGhpcy5tUGFnZU51bWJlciA9IDA7CiAgICAgICAgICAgIHRoaXMucGFnaW5nTWFuYWdlciA9IG51bGwgOwogICAgICAgICAgICB0aGlzLm1DYWxjdWxhdGlvbnNFbmFibGVkID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5tVmFsaWRhdGFpb25zRW5hYmxlZCA9IHRydWU7CiAgICAgICAgICAgIHRoaXMubU51bVBhZ2VzID0gIiI7CiAgICAgICAgICAgIHRoaXMuZGF0YUJyb3dzZXIgPSBbCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RyaW5nOiBuYXZpZ2F0b3IudXNlckFnZW50LAogICAgICAgICAgICAgICAgICAgIHN1YlN0cmluZzogIkNocm9tZSIsCiAgICAgICAgICAgICAgICAgICAgaWRlbnRpdHk6ICJDaHJvbWUiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0cmluZzogbmF2aWdhdG9yLnZlbmRvciwKICAgICAgICAgICAgICAgICAgICBzdWJTdHJpbmc6ICJBcHBsZSIsCiAgICAgICAgICAgICAgICAgICAgaWRlbnRpdHk6ICJTYWZhcmkiLAogICAgICAgICAgICAgICAgICAgIHZlcnNpb25TZWFyY2g6ICJWZXJzaW9uIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBwcm9wOiB3aW5kb3cub3BlcmEsCiAgICAgICAgICAgICAgICAgICAgaWRlbnRpdHk6ICJPcGVyYSIsCiAgICAgICAgICAgICAgICAgICAgdmVyc2lvblNlYXJjaDogIlZlcnNpb24iCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0cmluZzogbmF2aWdhdG9yLnVzZXJBZ2VudCwKICAgICAgICAgICAgICAgICAgICBzdWJTdHJpbmc6ICJGaXJlZm94IiwKICAgICAgICAgICAgICAgICAgICBpZGVudGl0eTogIkZpcmVmb3giCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewkJLy8gZm9yIG5ld2VyIE5ldHNjYXBlcyAoNispCiAgICAgICAgICAgICAgICAgICAgc3RyaW5nOiBuYXZpZ2F0b3IudXNlckFnZW50LAogICAgICAgICAgICAgICAgICAgIHN1YlN0cmluZzogIk5ldHNjYXBlIiwKICAgICAgICAgICAgICAgICAgICBpZGVudGl0eTogIk5ldHNjYXBlIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdHJpbmc6IG5hdmlnYXRvci51c2VyQWdlbnQsCiAgICAgICAgICAgICAgICAgICAgc3ViU3RyaW5nOiAiTVNJRSIsCiAgICAgICAgICAgICAgICAgICAgaWRlbnRpdHk6ICJJbnRlcm5ldCBFeHBsb3JlciIsCiAgICAgICAgICAgICAgICAgICAgdmVyc2lvblNlYXJjaDogIk1TSUUiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0cmluZzogbmF2aWdhdG9yLnVzZXJBZ2VudCwKICAgICAgICAgICAgICAgICAgICBzdWJTdHJpbmc6ICJHZWNrbyIsCiAgICAgICAgICAgICAgICAgICAgaWRlbnRpdHk6ICJNb3ppbGxhIiwKICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uU2VhcmNoOiAicnYiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgeyAJCS8vIGZvciBvbGRlciBOZXRzY2FwZXMgKDQtKQogICAgICAgICAgICAgICAgICAgIHN0cmluZzogbmF2aWdhdG9yLnVzZXJBZ2VudCwKICAgICAgICAgICAgICAgICAgICBzdWJTdHJpbmc6ICJNb3ppbGxhIiwKICAgICAgICAgICAgICAgICAgICBpZGVudGl0eTogIk5ldHNjYXBlIiwKICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uU2VhcmNoOiAiTW96aWxsYSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgXTsKICAgICAgICB9LAoKICAgICAgICBfc2VhcmNoVmVyc2lvbiA6IGZ1bmN0aW9uKGRhdGEsc3JjaCkgewogICAgICAgICAgICB2YXIgaW5kZXggPSBkYXRhLmluZGV4T2Yoc3JjaCk7CiAgICAgICAgICAgIGlmIChpbmRleCA9PSAtMSkgcmV0dXJuOwogICAgICAgICAgICB2YXIgc3BjSW5kZXggPSBkYXRhLmluZGV4T2YoIiAiLGluZGV4KTsKICAgICAgICAgICAgaWYoc3BjSW5kZXggPT0gLTEpCiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5zdWJzdHJpbmcoaW5kZXgrc3JjaC5sZW5ndGgrMSk7CiAgICAgICAgICAgIHJldHVybiBkYXRhLnN1YnN0cmluZyhpbmRleCtzcmNoLmxlbmd0aCsxLHNwY0luZGV4KTsKICAgICAgICB9LAoKICAgICAgICBfYnJvd3NlckRldGVjdCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YUJyb3dzZXI7CiAgICAgICAgICAgIGZvciAodmFyIGk9MDtpPGRhdGEubGVuZ3RoO2krKykJewogICAgICAgICAgICAgICAgdmFyIGRhdGFTdHJpbmcgPSBkYXRhW2ldLnN0cmluZzsKICAgICAgICAgICAgICAgIHZhciBkYXRhUHJvcCA9IGRhdGFbaV0ucHJvcDsKICAgICAgICAgICAgICAgIHZhciB2ZXJzaW9uU2VhcmNoU3RyaW5nID0gZGF0YVtpXS52ZXJzaW9uU2VhcmNoIHx8IGRhdGFbaV0uaWRlbnRpdHk7CiAgICAgICAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMuX3NlYXJjaFZlcnNpb24obmF2aWdhdG9yLnVzZXJBZ2VudCx2ZXJzaW9uU2VhcmNoU3RyaW5nKSB8fCB0aGlzLl9zZWFyY2hWZXJzaW9uKG5hdmlnYXRvci5hcHBWZXJzaW9uLHZlcnNpb25TZWFyY2hTdHJpbmcpIHx8ICJhbiB1bmtub3duIHZlcnNpb24iOwogICAgICAgICAgICAgICAgaWYgKGRhdGFTdHJpbmcpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YVN0cmluZy5pbmRleE9mKGRhdGFbaV0uc3ViU3RyaW5nKSAhPSAtMSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGFbaV0uaWRlbnRpdHkrIiAiK3ZlcnNpb247CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChkYXRhUHJvcCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVtpXS5pZGVudGl0eSsiICIrdmVyc2lvbjsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBmdW5jdGlvbiBkaXNwbGF5cyBhIGRpYWxvZyBib3ggb24gdGhlIHNjcmVlbi4gPGJyIC8+CiAgICAgICAgICogPGI+VE8gRE88L2I+PGJyIC8+CiAgICAgICAgICogPHVsPgogICAgICAgICAqIDxsaT4gVGhlIGZ1bmN0aW9uIGRvZXNuJ3Qgc3VwcG9ydHMgaWNvbnMgYXMgb2Ygbm93LiBOZWVkcyBhZGRpbmcgc3VwcG9ydCBmb3IKICAgICAgICAgKiB0aGF0LjwvbGk+CiAgICAgICAgICogPGxpPiBUaGUgZGlhbG9nIHVzZXMgdGhlIGRlZmF1bHQgc3R5bGluZyAocHJvdmlkZWQgYnkgZ29vZ2xlKS4gTmVlZCB0byBjaGFuZ2UKICAgICAgICAgKiB0aGF0IHRvby4gPC9saT4KICAgICAgICAgKiA8L3VsPgogICAgICAgICAqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9CiAgICAgICAgICAgICogICAgICAgICAgICBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30KICAgICAgICAgICAgKiAgICAgICAgICAgIHRpdGxlIFRoZSB0aXRsZSB0byBhcHBlYXIgaW4gdGhlIGRpYWxvZydzIHdpbmRvdyB0aXRsZQogICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfQogICAgICAgICAgICAqICAgICAgICAgICAgdHlwZSBUaGUgaWNvbiB0byBkaXNwbGF5OiAnMCcgKEVycm9yIChkZWZhdWx0KSksICcxJyAoV2FybmluZyksCiAgICAgICAgICogICAgICAgICAgICAnMicgKFF1ZXN0aW9uKSwgYW5kICczJyAoU3RhdHVzKS4KICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0KICAgICAgICAgICAgKiAgICAgICAgICAgIGJ1dHRvbnMgVGhlIGJ1dHRvbnMgdG8gZGlzcGxheTogJzAnIChPSyAoZGVmYXVsdCkpLCAnMScgKE9LLAogICAgICAgICAqICAgICAgICAgICAgQ2FuY2VsKSwgJzInIChZZXMsIE5vKSwgYW5kICczJyAoWWVzLCBObywgQ2FuY2VsKS4KICAgICAgICAgKi8KICAgICAgICBtZXNzYWdlQm94IDogZnVuY3Rpb24obWVzc2FnZSwgdGl0bGUsIHR5cGUsIGJ1dHRvbnMpIHsKICAgICAgICAgICAgcmV0dXJuICh0aGlzLl9tZXNzYWdlQm94KG1lc3NhZ2UsdGl0bGUsdHlwZSxidXR0b25zLG51bGwpKTsKICAgICAgICB9LAoKICAgICAgICBfbWVzc2FnZUJveCA6IGZ1bmN0aW9uKG1lc3NhZ2UsIHRpdGxlLCB0eXBlLCBidXR0b25zLGNhbGxiYWNrKSB7CiAgICAgICAgICAgIHRpdGxlID0gdGl0bGUgfHwgIiI7CiAgICAgICAgICAgIGJ1dHRvbnMgPSBidXR0b25zIHx8IDA7CiAgICAgICAgICAgIHZhciBpbWcgPVsiRXJyb3IiLCJXYXJuaW5nIiwiUXVlc3Rpb24iLCJTdGF0dXMiXTsKICAgICAgICAgICAgdmFyIGltZ1R5cGUgPSAiIjsKICAgICAgICAgICAgaWYodHlwZSE9dW5kZWZpbmVkKQogICAgICAgICAgICAgICAgaW1nVHlwZSA9ICAiWyAiICsgaW1nW3R5cGVdICsgIiBdICAiOwogICAgICAgICAgICBtZXNzYWdlID0gaW1nVHlwZSAgKyAgdGl0bGUgKyAiXG5cciIgKyBtZXNzYWdlIDsKCiAgICAgICAgICAgIHN3aXRjaCAoYnV0dG9ucykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICAgIGFsZXJ0KG1lc3NhZ2UpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAxIDsKICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICB2YXIgYSA9IGNvbmZpcm0obWVzc2FnZSk7CiAgICAgICAgICAgICAgICAgICAgaWYoYT09dHJ1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgICAgICAgZWxzZSByZXR1cm4gMjsKICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICB2YXIgYSA9IGNvbmZpcm0obWVzc2FnZSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuTG9nZ2VyLmVycm9yKCJ4ZmEiLCB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDkiXSkgOwogICAgICAgICAgICAgICAgICAgIGlmKGE9PXRydWUpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiA0OwogICAgICAgICAgICAgICAgICAgIGVsc2UgcmV0dXJuIDM7CgogICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLkxvZ2dlci5lcnJvcigieGZhIiwgeGZhbGliLmxvY2FsZS5Mb2dNZXNzYWdlc1siQUxDLUZSTS05MDEtMDEwIl0pOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIGZ1bmN0aW9uIGRpc3BsYXlzIHRoZSBuZXh0IHBhZ2Ugb2YgdGhlIGRvY3VtZW50IChpZiBvbmUgZXhpc3RzKQogICAgICAgICAqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgcGFnZURvd24gOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudFBhZ2UgIT0gdGhpcy5udW1QYWdlcyAtMSApIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMucGFnaW5nTWFuYWdlcikKICAgICAgICAgICAgICAgICAgICB0aGlzLnBhZ2luZ01hbmFnZXIucGFnZURvd24oKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBmdW5jdGlvbiBkaXNwbGF5cyB0aGUgcHJldmlvdXMgcGFnZSBvZiB0aGUgZG9jdW1lbnQgKGlmIG9uZSBleGlzdHMpCiAgICAgICAgICoKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKi8KICAgICAgICBwYWdlVXAgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudFBhZ2UgIT0gMCkgIHsKICAgICAgICAgICAgICAgIHZhciBwcmV2UGFnZSA9IHRoaXMuY3VycmVudFBhZ2UgLSAxOwogICAgICAgICAgICAgICAgdmFyIGEgPSAkKCQoIi5wYWdlIilbcHJldlBhZ2VdKSAgOwogICAgICAgICAgICAgICAgd2luZG93LnNjcm9sbFRvKDAsYS5vZmZzZXQoKS50b3ApIDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGdvdG9VUkw6IGZ1bmN0aW9uKHVybCwgYk5ld0ZyYW1lKSB7CiAgICAgICAgICAgIC8qaWYoISQoImEjZ290b3VybCIpLmxlbmd0aCkKICAgICAgICAgICAgICAgICQoIjxhIGlkPSdnb3RvdXJsJz48L2E+IikuYXBwZW5kVG8oJ2JvZHknKTsKICAgICAgICAgICAgJCgiYSNnb3RvdXJsIikuYXR0cigiaHJlZiIsdXJsKVswXS5jbGljaygpOwogICAgICAgICAgICAvLyQoImEiKS5jbGljaygpOyAgICAgKi8KICAgICAgICAgICAgaWYodXJsLnNlYXJjaCgiaHR0cCIpID09IC0xKQogICAgICAgICAgICAgICAgdXJsID0gImh0dHA6Ly8iICsgdXJsIDsKICAgICAgICAgICAgaWYoYk5ld0ZyYW1lICE9IHRydWUpIHsKICAgICAgICAgICAgICAgIHdpbmRvdy5vcGVuKHVybCkgOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbiA9IHVybDsKICAgICAgICB9LAoKICAgICAgICByZXNldERhdGEgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYoYXJndW1lbnRzLmxlbmd0aCkKICAgICAgICAgICAgICAgIF8uZWFjaChhcmd1bWVudHMsZnVuY3Rpb24oc29tKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGUgPSB0aGlzLl94ZmEoKS5yZXNvbHZlTm9kZShzb20pOwogICAgICAgICAgICAgICAgICAgIGlmKG5vZGUpCiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuX3Jlc2V0RGF0YSgpOwogICAgICAgICAgICAgICAgfSx0aGlzKQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLmZvcm0uX3Jlc2V0RGF0YSgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc2V0Rm9jdXMgOiBmdW5jdGlvbihzb20pIHsKICAgICAgICAgICAgaWYobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBhZC9pKSAhPSBudWxsICYmIHRoaXMuX3hmYSgpLm1vQ29udGV4dFNjcmlwdEV2ZW50ID09ICdjaGFuZ2UnKSB7CiAgICAgICAgICAgIC8vIExDLTQ2NjMgOiBzZXRGb2N1cyB3YXMgc2hpZnRpbmcgZm9jdXMsIGJlZm9yZSBrZXlwcmVzcyB3YXMgdmlzaWJsZSBpbiBicm93c2VyLgogICAgICAgICAgICAvLyBDdXJyZW50bHkgaVBhZCBkb2VzbnQgc3VwcG9ydCBjYWxsaW5nIGZvY3VzKCkgZnJvbSB3aXRoaW4gc2V0VGltZW91dCwgc28gZGlzYWJsaW5nIHRoZSBmdW5jdGlvbmFsaXR5LgogICAgICAgICAgICAgICAgdGhpcy5fc2V0Rm9jdXMoc29tKTsgLy8gZG9uJ3QgcXVldWUgZm9jdXMgZXZlbnRzLCBmaXJlIGl0IGltbWVkaWF0ZWx5CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5xdWV1ZUZvY3VzRXZlbnQodGhpcywgc29tKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICBfc2V0Rm9jdXMgOiBmdW5jdGlvbihzb20pIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbm9kZSA9IHNvbTsKICAgICAgICAgICAgICAgICAgICBpZih0eXBlb2Ygc29tID09ICJzdHJpbmciKQogICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gdGhpcy5feGZhKCkucmVzb2x2ZU5vZGUoc29tKTsKICAgICAgICAgICAgICAgICAgICBpZihub2RlICE9IG51bGwpewogICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMucGFnaW5nTWFuYWdlcil7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGFkL2kpICE9IG51bGwgJiYgdGhpcy5feGZhKCkubW9Db250ZXh0U2NyaXB0RXZlbnQgPT0gJ2NoYW5nZScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBhZ2luZ01hbmFnZXIuX21ha2VQYWdlRm9ySHRtbElkKG5vZGUuaHRtbElkKTsgLy8gTEMtNDY2MyA6IGp1c3QgcmVuZGVyLCBub3Qgc2V0Rm9jdXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYWdpbmdNYW5hZ2VyLl9tYWtlUGFnZUZvckh0bWxJZChub2RlLmh0bWxJZCxub2RlLl9zZXRGb2N1cyxub2RlKTsgIC8vIGZvciBhbGwgb3RoZXIgZXZlbnRzIHNldCB0aGUgZm9jdXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICB9LAoKICAgICAgICAgZ2V0Rm9jdXMgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBpZih4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1cykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybih4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1cy5tb2RlbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gLAoKICAgICAgICBwbGF5RGF0YVhtbDogZnVuY3Rpb24gKHhtbERvY3VtZW50KSB7CiAgICAgICAgICAgIHZhciByb290RWxlbWVudDsKICAgICAgICAgICAgaWYoXy5pc1VuZGVmaW5lZChkb2N1bWVudC5ldmFsdWF0ZSkpIHsKICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gZG8gaXQgaGVyZSBzaW5jZSBYUGF0aFJlc3VsdCBpcyBhbHNvIHVuZGVmaW5lZCBpbiBJRQogICAgICAgICAgICAgICAgd2d4cGF0aC5pbnN0YWxsKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoXy5pc1N0cmluZyh4bWxEb2N1bWVudCkpIHsKICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLkxvZ2dlci5pbmZvKCJ4ZmEiLCAieG1sRG9jdW1lbnQgaXMgb2YgdHlwZSBzdHJpbmcuIGNvbnZlcnRpbmcgaXQgdG8gZG9jdW1lbnQiKTsKICAgICAgICAgICAgICAgIHhtbERvY3VtZW50ID0gJC5wYXJzZVhNTCh4bWxEb2N1bWVudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcm9vdEVsZW1lbnQgPSB4ZmFsaWIudXQuWE1MVXRpbHMuZ2V0WEZBUm9vdEZvcm1FbGVtZW50RnJvbVhNTCh4bWxEb2N1bWVudCk7CiAgICAgICAgICAgIHRoaXMuX3hmYSgpLmZvcm0uX3BsYXlEYXRhWE1MKHJvb3RFbGVtZW50LCByb290RWxlbWVudCwgIiIpOwogICAgICAgIH0sCgogICAgICAgIHBsYXlKc29uIDogZnVuY3Rpb24oeGZhSnNvbk1vZGVsKSB7CiAgICAgICAgICAgIHZhciBmb3JtRG9tID0gIF8uZmluZCh4ZmFKc29uTW9kZWwuY2hpbGRyZW4sCiAgICAgICAgICAgICAgICBmdW5jdGlvbihjaGlsZCl7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkLl9jbGFzcyA9PSAiZm9ybSI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHRoaXMuX3hmYSgpLmZvcm0ucGxheUpzb24oZm9ybURvbSk7CiAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX1JFRlJFU0gsCiAgICAgICAgICAgICAgICB0aGlzLCJqc29uTW9kZWwiLG51bGwsdGhpcy5feGZhKCkuZm9ybS5qc29uTW9kZWwpOwogICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgIH0sCgogICAgICAgIHJ1blNlcnZlclNjcmlwdCA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnN8fCB7fTsKICAgICAgICAgICAgdmFyIHhmYURpZmY7CiAgICAgICAgICAgIGlmICh3aW5kb3cuRkQgJiYgd2luZG93LkZELmlzVG9nZ2xlRW5hYmxlZCgiRlRfRk9STVMtMTQyMjQiKSkgewogICAgICAgICAgICAgICAgeGZhRGlmZiA9IHRoaXMuX3hmYSgpLl9jb21wdXRlSnNvbkRpZmYoMykuanNvbkRpZmZlcmVuY2U7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB4ZmFEaWZmID0gdGhpcy5feGZhKCkuX2NvbXB1dGVKc29uRGlmZigwKS5qc29uRGlmZmVyZW5jZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgeGZhRG9tU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkoeGZhRGlmZik7CiAgICAgICAgICAgLy9jbG9uZSB0aGUgb2JqZWN0IHRvIGF2b2lkIHBvbGx1dGluZyB0aGUgY29udGV4dAogICAgICAgICAgICB2YXIgcGFyYW1zID0gXy5leHRlbmQoewogICAgICAgICAgICAgICAgICAgIGZvcm1Eb206IHhmYURvbVN0cmluZywKICAgICAgICAgICAgICAgICAgICBwYWNrZXQ6ICdmb3JtJwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIG9wdGlvbnMsCiAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS5yZW5kZXJDb250ZXh0KTsKCiAgICAgICAgICAgIHZhciBzZXJ2ZXJTY3JpcHRTdWNjZXNzSGFuZGxlciA9IGZ1bmN0aW9uKHJlc3VsdCl7CiAgICAgICAgICAgICAgICB0aGlzLnBsYXlKc29uKHJlc3VsdCk7IC8vcmVzdWx0IHdpbGwgYmUgYSBKU09OIG9iamVjdCBzbyBqdXN0IHBsYXkgaXQuCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBpZihvcHRpb25zLmNvbnRleHRTb20gJiYgb3B0aW9ucy5hY3Rpdml0eSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICAgICAgd2luZG93LmZvcm1CcmlkZ2UuX2ludm9rZUF0U2VydmVyKHsKICAgICAgICAgICAgICAgICAgICBkYXRhOiBwYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgc3VjY2VzczpfLmJpbmQoc2VydmVyU2NyaXB0U3VjY2Vzc0hhbmRsZXIsdGhpcyksCiAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uKHhocix0eHRTdGF0dXMsZXJyb3JUaHJvd24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1zZwogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2goeGhyLnN0YXR1cykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zZyA9IHhmYWxpYi5sb2NhbGUuTG9nTWVzc2FnZXNbIkFMQy1GUk0tOTAxLTAwOCJdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX3hmYSgpLkxvZ2dlci5lcnJvcigieGZhIiwgbXNnICsgIiAiICsgeGhyLnN0YXR1c1RleHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2cgPSB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDEiXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0Ll94ZmEoKS5Mb2dnZXIuZXJyb3IoInhmYSIsIG1zZyArICIgIiArIHhoci5zdGF0dXNUZXh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGF0Lm1lc3NhZ2VCb3gobXNnKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF92YWxpZGF0ZSA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgdmFyIF9vcHRpb25zID0gb3B0aW9ucyB8fCB7fSwKICAgICAgICAgICAgICAgIHZhbE1lc3NhZ2VzID0gX29wdGlvbnMudmFsTWVzc2FnZXMgfHwgW107CiAgICAgICAgICAgIHZhciB2YWxpZCA9IHRoaXMuX3hmYSgpLmZvcm0uX3ZhbGlkYXRlKHZhbE1lc3NhZ2VzKTsKICAgICAgICAgICAgaWYodmFsaWQpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgICAgIHZhciBlcnJvcnMgPSAiIjsKICAgICAgICAgICAgdmFyIHdhcm5pbmdzID0gIiI7CgogICAgICAgICAgICBmb3IodmFyIGk9MDsgaSA8IHZhbE1lc3NhZ2VzLmxlbmd0aDsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgbXNnID0gbnVsbDsKICAgICAgICAgICAgICAgIGlmKG1zZyA9IHZhbE1lc3NhZ2VzW2ldKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmKG1zZy5zZXZlcml0eSA9PSAiZXJyb3IiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9ycyA9IGVycm9ycyArIG1zZy5tZXNzYWdlICsgIlxyXG4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZihtc2cuc2V2ZXJpdHkgPT0gIndhcm5pbmciKXsKICAgICAgICAgICAgICAgICAgICAgICAgd2FybmluZ3MgPSB3YXJuaW5ncyArIG1zZy5tZXNzYWdlICsgIlxyXG4iOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZihlcnJvcnMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgICAgIHZhciBtc2cgPSAiICBUaGUgZm9ybSBjb3VsZCBub3QgYmUgc3VibWl0dGVkIGJlY2F1c2UgIit2YWxNZXNzYWdlcy5sZW5ndGggKyIgZXJyb3JzIHdlcmUgZm91bmQiCiAgICAgICAgICAgICAgICBpZigkKCIjd2ItbWFpbi1pbiIpLmxlbmd0aCl7CiAgICAgICAgICAgICAgICAgICAgaWYoISQoIiN4ZmEtZXJyb3JNZXNzYWdlcyIpLmxlbmd0aCl7CiAgICAgICAgICAgICAgICAgICAgICAgICQoIiN3Yi1tYWluLWluIikucHJlcGVuZCgiPGRpdiBpZCA9J3hmYS1lcnJvck1lc3NhZ2VzJz48L2Rpdj4iKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgJCgiI3hmYS1lcnJvck1lc3NhZ2VzIikuZW1wdHkoKS50ZXh0KG1zZykuYXBwZW5kKCI8dWwgaWQ9J3hmYS1lcnJvckxpc3QnPjwvdWw+Iik7CiAgICAgICAgICAgICAgICAgICAgXy5lYWNoKHZhbE1lc3NhZ2VzLGZ1bmN0aW9uKGVsZW0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiPGE+PC9hPiIpLmFwcGVuZFRvKCQoIjxsaT48L2xpPiIpLmFwcGVuZFRvKCcjeGZhLWVycm9yTGlzdCcpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50ZXh0KGVsZW0ubWVzc2FnZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNsaWNrKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGF0LnNldEZvY3VzKGVsZW0ucmVmKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICAgICBpZih2YWxNZXNzYWdlcy5sZW5ndGggPT0wKQogICAgICAgICAgICAgICAgICAgICAgICAkKCIjeGZhLWVycm9yTWVzc2FnZXMiKS5oaWRlKCk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAkKCIjeGZhLWVycm9yTWVzc2FnZXMiKS5zaG93KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLnNldEZvY3VzKHZhbE1lc3NhZ2VzWzBdLnJlZik7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZih3YXJuaW5ncykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlQm94KHdhcm5pbmdzLCB4ZmFsaWIubG9jYWxlLlN0cmluZ3Mud2FybmluZywgMSwgMCk7ICAgLy9UT0RPIDpTaG91bGQgIGJlIG9rL2NhbmNlbAogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGN1cnJlbnREYXRlVGltZQogICAgICAgICAqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgX3BhZHplcm8gOiBmdW5jdGlvbihuKSB7CiAgICAgICAgICAgIHJldHVybiBuIDwgMTAgPyAnMCcgKyBuIDogbjsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGN1cnJlbnREYXRlVGltZQogICAgICAgICAqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgX3BhZDJ6ZXJvcyA6IGZ1bmN0aW9uKG4pIHsKICAgICAgICAgICAgaWYgKG4gPCAxMDApIHsKICAgICAgICAgICAgICAgIG4gPSAnMCcgKyBuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChuIDwgMTApIHsKICAgICAgICAgICAgICAgIG4gPSAnMCcgKyBuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuOwogICAgICAgIH0sCgogICAgICAgIC8qKgogICAgICAgICogVGhlIGZ1bmN0aW9uIFJldHVybnMgY3VycmVudCBkYXRlIGFuZCB0aW1lIGluIFttXW0vW2RdZC95eSBbSF1IOltNXU0gKEF8UClNIGZvcm1hdAogICAgICAgICoKICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICovCiAgICAgICAgY3VycmVudERhdGVUaW1lIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBub3cgPSBuZXcgRGF0ZSgpLAogICAgICAgICAgICAgICAgICAgIGN1clllYXIgPSBub3cuZ2V0RnVsbFllYXIoKSArJycsCiAgICAgICAgICAgICAgICAgICAgY3VyTW9udGggPSBub3cuZ2V0TW9udGgoKSsxICsnJywKICAgICAgICAgICAgICAgICAgICBjdXJEYXRlID0gbm93LmdldERhdGUoKSArJycsCiAgICAgICAgICAgICAgICAgICAgY3VySG91ciA9IG5vdy5nZXRIb3VycygpICsnJywKICAgICAgICAgICAgICAgICAgICBjdXJNaW4gPSBub3cuZ2V0TWludXRlcygpICsnJywKICAgICAgICAgICAgICAgICAgICBjdXJTZWMgPSBub3cuZ2V0U2Vjb25kcygpICsnJzsKCiAgICAgICAgICAgIHJldHVybiAoY3VyWWVhciArIHRoaXMuX3BhZHplcm8oY3VyTW9udGgpICsgdGhpcy5fcGFkemVybyhjdXJEYXRlKSArICdUJyArCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFkemVybyhjdXJIb3VyKSArIHRoaXMuX3BhZHplcm8oY3VyTWluKSArIHRoaXMuX3BhZHplcm8oY3VyU2VjKSk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogSGVscGVyIGZ1bmN0aW9uIGZvciBjdXJyZW50RGF0ZVRpbWUKICAgICAgICAgKgogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqLwogICAgICAgIF90b0lTT1N0cmluZyA6IGZ1bmN0aW9uKGQpIHsKICAgICAgICAgICAgcmV0dXJuIGQuZ2V0VVRDRnVsbFllYXIoKSArICctJyArICB0aGlzLl9wYWR6ZXJvKGQuZ2V0VVRDTW9udGgoKSArIDEpICsgJy0nICsKICAgICAgICAgICAgICAgIHRoaXMuX3BhZHplcm8oZC5nZXRVVENEYXRlKCkpICsgJ1QnICsgdGhpcy5fcGFkemVybyhkLmdldFVUQ0hvdXJzKCkpICsgJzonICsKICAgICAgICAgICAgICAgIHRoaXMuX3BhZHplcm8oZC5nZXRVVENNaW51dGVzKCkpICsgJzonICsgdGhpcy5fcGFkemVybyhkLmdldFVUQ1NlY29uZHMoKSkgKyAnLicgKyB0aGlzLl9wYWQyemVyb3MoZC5nZXRVVENNaWxsaXNlY29uZHMoKSkgKyAnWic7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIGZ1bmN0aW9uIFJldHVybnMgY3VycmVudCBkYXRlIGFuZCB0aW1lIGluIElTTyA4NjAxIGZvcm1hdAogICAgICAgICAqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgX2N1cnJlbnREYXRlVGltZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgbm93ID0gbmV3IERhdGUoKTsKICAgICAgICAgICAgcmV0dXJuKHRoaXMuX3RvSVNPU3RyaW5nKG5vdykpOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBIb3N0LnBsYXRmb3JtcyA9IFtbIldpbiIsIldpbmRvd3MiXSxbIk1hYyJdLFsiaVBob25lIiwiaVBob25lL2lQb2QiXSxbImlQYWQiXSxbIkxpbnV4Il0sWyJVbmtub3duIl1dOwoKICAgIEhvc3QuZGVmaW5lUHJvcHMoewogICAgICAgICJhcHBUeXBlIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIkhUTUwgNSI7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAiY3VycmVudFBhZ2UiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMucGFnaW5nTWFuYWdlcikKICAgICAgICAgICAgICAgICAgICByZXR1cm4odGhpcy5wYWdpbmdNYW5hZ2VyLmN1cnJlbnRQYWdlKCkpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbihwYWdlKSB7CiAgICAgICAgICAgICAgICB2YXIgY3VycmVudFBhZ2UgPSAwLAogICAgICAgICAgICAgICAgICAgIGxhc3RQYWdlID0gMDsKICAgICAgICAgICAgICAgIHBhZ2UgPSBwYXJzZUludChwYWdlKTsKICAgICAgICAgICAgICAgIGlmKHRoaXMucGFnaW5nTWFuYWdlcikgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRQYWdlID0gdGhpcy5wYWdpbmdNYW5hZ2VyLmN1cnJlbnRQYWdlKCk7CiAgICAgICAgICAgICAgICAgICAgbGFzdFBhZ2UgPSB0aGlzLnBhZ2luZ01hbmFnZXIucGFnZUNvdW50KCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYocGFnZSA8IDApCiAgICAgICAgICAgICAgICAgICAgcGFnZSA9IDA7CiAgICAgICAgICAgICAgICBlbHNlIGlmKHBhZ2UgPj0gbGFzdFBhZ2UpCiAgICAgICAgICAgICAgICAgICAgcGFnZSA9ICAobGFzdFBhZ2UgPiAwKSA/IGxhc3RQYWdlIC0xIDogMDsKCiAgICAgICAgICAgICAgICB2YXIgJHBhZ2VzID0gJCgiLnBhZ2UiKTsKCiAgICAgICAgICAgICAgICBpZiggcGFnZSA+ICRwYWdlcy5sZW5ndGgtMSApIHsgIC8vIG5vdCBhbGwgcGFnZXMgcmVuZGVyZWQgeWV0CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5wYWdpbmdNYW5hZ2VyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlKHRoaXMucGFnaW5nTWFuYWdlci5oYXNNb3JlUGFnZXMoKSAmJiBjdXJyZW50UGFnZSA8PSBwYWdlKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFnaW5nTWFuYWdlci5yZW5kZXJOZXh0UGFnZSgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudFBhZ2UrKzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkcGFnZXMgPSAkKCIucGFnZSIpOyAgIC8vIHNlbGVjdCBuZXdseSByZW5kZXJlZCBwYWdlcwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBhID0gJCgkcGFnZXNbcGFnZV0pOwogICAgICAgICAgICAgICAgd2luZG93LnNjcm9sbFRvKDAsYS5vZmZzZXQoKS50b3ApIDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJuYW1lIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYnJvd3NlckRldGVjdCgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInZhcmlhdGlvbiIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewoKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJudW1QYWdlcyIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgaWYodGhpcy5wYWdpbmdNYW5hZ2VyKQogICAgICAgICAgICAgICAgICAgIHJldHVybih0aGlzLnBhZ2luZ01hbmFnZXIucGFnZUNvdW50KCkpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInBsYXRmb3JtIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICB2YXIgYXJyID0gSG9zdC5wbGF0Zm9ybXM7CiAgICAgICAgICAgICAgICBpZiAoIXRoaXMubVBsYXRmb3JtKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBpID0gMDtpPGFyci5sZW5ndGg7aSsrKQogICAgICAgICAgICAgICAgICAgICAgICAgIGlmKH5uYXZpZ2F0b3IucGxhdGZvcm0uaW5kZXhPZihhcnJbaV1bMF0pKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGkgPSBpID09IGFyci5sZW5ndGggPyBpIC0gMSA6aTsKICAgICAgICAgICAgICAgICAgICB0aGlzLm1QbGF0Zm9ybSA9ICBhcnJbaV1bYXJyW2ldLmxlbmd0aC0xXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1QbGF0Zm9ybQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInRpdGxlIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZG9jdW1lbnQudGl0bGU7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHRpdGxlKSB7CiAgICAgICAgICAgIAl0aXRsZSA9IHRoaXMudmFsaWRhdGVJbnB1dCh0aXRsZSwgInN0cmluZyIpOwogICAgICAgICAgICAgICAgZG9jdW1lbnQudGl0bGUgPSB0aXRsZTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZW51bWVyYWJsZSA6IHRydWUKICAgICAgICB9LAoKICAgICAgICAidmVyc2lvbiIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICIxLjAiOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCgogICAgICAgICJjYWxjdWxhdGlvbnNFbmFibGVkIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tQ2FsY3VsYXRpb25zRW5hYmxlZDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24oc0NhbGN1bGF0aW9uc0VuYWJsZWQpIHsKICAgICAgICAgICAgCS8vc0NhbGN1bGF0aW9uc0VuYWJsZWQgPSB0aGlzLnZhbGlkYXRlSW5wdXQoc0NhbGN1bGF0aW9uc0VuYWJsZWQsICJzdHJpbmciKTsKICAgICAgICAgICAgICAgIHZhciBzT3JpZ2luYWxWYWx1ZSA9IHRoaXMubUNhbGN1bGF0aW9uc0VuYWJsZWQ7CiAgICAgICAgICAgICAgICB0aGlzLm1DYWxjdWxhdGlvbnNFbmFibGVkID0gc0NhbGN1bGF0aW9uc0VuYWJsZWQ7CiAgICAgICAgICAgICAgICBpZiAoIXNDYWxjdWxhdGlvbnNFbmFibGVkKSB7CiAgICAgICAgICAgICAgICAgICAgLy90aGlzLnhmYS5fcm9vdFN1YmZvcm0uX2NsZWFyTWVzc2FnZXMoKTsgVE9ETzogQ2xlYXIgQ2FsY3VsYXRpb24gbWVzc2FnZXMKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc0NhbGN1bGF0aW9uc0VuYWJsZWQgJiYgKHNPcmlnaW5hbFZhbHVlID09IGZhbHNlKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLmZvcm0uZXhlY0NhbGN1bGF0ZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInZhbGlkYXRpb25zRW5hYmxlZCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubVZhbGlkYXRhaW9uc0VuYWJsZWQ7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHNWYWxpZGF0aW9uc0VuYWJsZWQpIHsKICAgICAgICAgICAgCS8vc1ZhbGlkYXRpb25zRW5hYmxlZCA9IHRoaXMudmFsaWRhdGVJbnB1dChzVmFsaWRhdGlvbnNFbmFibGVkLCAic3RyaW5nIik7CiAgICAgICAgICAgICAgICB2YXIgc09yaWdpbmFsVmFsdWUgPSB0aGlzLm1WYWxpZGF0YWlvbnNFbmFibGVkOwogICAgICAgICAgICAgICAgdGhpcy5tVmFsaWRhdGFpb25zRW5hYmxlZCA9IHNWYWxpZGF0aW9uc0VuYWJsZWQ7CiAgICAgICAgICAgICAgICBpZiAoIXNWYWxpZGF0aW9uc0VuYWJsZWQpIHsKICAgICAgICAgICAgICAgICAgICAvL3RoaXMueGZhLl9yb290U3ViZm9ybS5fY2xlYXJNZXNzYWdlcygpOyBUT0RPOiBDbGVhciBWYWxpZGF0aW9uIG1lc3NhZ2VzCiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNWYWxpZGF0aW9uc0VuYWJsZWQgJiYgKHNPcmlnaW5hbFZhbHVlID09IGZhbHNlKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuX3hmYSgpLmZvcm0uX3ZhbGlkYXRlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sIHhmYWxpYiwgJCk7CgoKCgoKCgooZnVuY3Rpb24gKF8sICQsIHhmYWxpYikgewogICAgdmFyIFhmYVRlbXBsYXRlQ2FjaGUgPSB4ZmFsaWIuc2NyaXB0LlhmYVRlbXBsYXRlQ2FjaGUgPSB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBYZmFUZW1wbGF0ZUNhY2hlLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX2xhc3RJRCA9IChuZXcgRGF0ZSgpKS5nZXRUaW1lKCk7IC8vVE9ETzogR2V0IGEgYmV0dGVyIHNjaGVtZQogICAgICAgICAgICB0aGlzLl9ub2RlQ2FjaGUgPSB7fTsgICAgICAgIC8vIGxpdmUgY2FjaGUKICAgICAgICAgICAgdGhpcy5fdDBKc29uTm9kZUNhY2hlID0ge307IC8vIGluaXRpYWwgY2FjaGUKICAgICAgICAgICAgdGhpcy5pZE1hcCA9IHt9OyAgICAgICAgICAgLy8tLW1hcCB0byBnZXQgdGhlIGZpZWxkIGluc3RhbmNlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGZpZWxkLWlkCgogICAgICAgICAgICB2YXIganNvblN0cmluZyA9IEpTT04uc3RyaW5naWZ5KHRoaXMub3B0aW9ucy5pbml0aWFsRm9ybURvbSksIC8vV2UgY3JlYXRlIGNvcHkgb2YgaW5pdGlhbCBmb3JtIGRvbSB2aWEgSlNPTiBhcGkgaW5zdGVhZCBvZiB0aGlzLmNvcHlPYmplY3Qgc2luY2UgdGhhdCBpcyBmYXN0CiAgICAgICAgICAgICAgICBpbml0aWFsRm9ybURvbUNvcHkgPSBKU09OLnBhcnNlKGpzb25TdHJpbmcpLCAgICAvL0NyZWF0ZSBjb3B5IG9mIGluaXRpYWwgZm9ybSBkb20gdG8gZ3VhcmQgYWdhaW5zdCBmdXR1cmUgbW9kaWZpY2F0aW9ucwogICAgICAgICAgICAgICAgZm9ybURvbVRlbXBsYXRlID0ge307ICAgLy9Db3B5IGhvbGRpbmcgZm9ybURvbVRlbXBsYXRlCgogICAgICAgICAgICB0aGlzLmNvcHlPYmplY3QoaW5pdGlhbEZvcm1Eb21Db3B5LCBmb3JtRG9tVGVtcGxhdGUsIHsiZXhjZXB0aW9ucyI6IFsiY2hpbGRyZW4iXX0pOwogICAgICAgICAgICAvL0dlbmVyYXRlIHRlbXBsYXRlCiAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3NUZW1wbGF0ZShmb3JtRG9tVGVtcGxhdGUsIGluaXRpYWxGb3JtRG9tQ29weSwgZmFsc2UpOwogICAgICAgICAgICB2YXIgYmVoYXZpb3JDb25maWcgPSBuZXcgeGZhbGliLnV0LlZlcnNpb24oZm9ybUJyaWRnZS51c2VyQ29uZmlnWyJiZWhhdmlvckNvbmZpZyJdKTsKICAgICAgICAgICAgLy9UbyBtYWludGFpbiBiYWNrd2FyZCBjb21wYXRpYmlsaXR5CiAgICAgICAgICAgIGlmIChiZWhhdmlvckNvbmZpZy5pc09uKCdzdHJpcEluaXRpYWxGb3JtRG9tJykgfHwgYmVoYXZpb3JDb25maWcuaXNPbignbWZTdHJpcEluaXRpYWxGb3JtRG9tJykpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5zdHJpcE9iamVjdCh0aGlzLl90MEpzb25Ob2RlQ2FjaGVbaW5pdGlhbEZvcm1Eb21Db3B5LmV4dHJhcy5odG1sSWRdLmluaXRpYWxSZWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWydfY2xhc3MnLCAnbmFtZScsICdodG1sSWQnLCAncHJlc2VuY2UnLCAnbWluJywgJ21heCddKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGdldFRlbXBsYXRlUmVmOiBmdW5jdGlvbiAoaHRtbElkKSB7CiAgICAgICAgICAgIGlmICh0aGlzLl9ub2RlQ2FjaGUuaGFzT3duUHJvcGVydHkoaHRtbElkKSkKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9ub2RlQ2FjaGVbaHRtbElkXS50ZW1wbGF0ZVJlZjsKICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fdDBKc29uTm9kZUNhY2hlLmhhc093blByb3BlcnR5KGh0bWxJZCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdDBKc29uTm9kZUNhY2hlW2h0bWxJZF0udGVtcGxhdGVSZWY7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIGdldEluaXRpYWxGb3JtRG9tUmVmOiBmdW5jdGlvbiAoaHRtbElkKSB7CiAgICAgICAgICAgIGlmICh0aGlzLl90MEpzb25Ob2RlQ2FjaGUuaGFzT3duUHJvcGVydHkoaHRtbElkKSkKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl90MEpzb25Ob2RlQ2FjaGVbaHRtbElkXS5pbml0aWFsUmVmOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9LAoKICAgICAgICBnZXRNb2RlbDogZnVuY3Rpb24gKGh0bWxJZCkgewogICAgICAgICAgICBpZiAodGhpcy5fbm9kZUNhY2hlLmhhc093blByb3BlcnR5KGh0bWxJZCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbm9kZUNhY2hlW2h0bWxJZF0ubW9kZWw7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIHB1dE1vZGVsOiBmdW5jdGlvbiAobW9kZWwsIGpzb25UZW1wbGF0ZSkgewogICAgICAgICAgICB0aGlzLl9wcm9jZXNzTW9kZWwoanNvblRlbXBsYXRlLCBtb2RlbCk7CiAgICAgICAgfSwKCiAgICAgICAgcmVtb3ZlTW9kZWw6IGZ1bmN0aW9uIChodG1sSWQpIHsKICAgICAgICAgICAgaWYgKHRoaXMuX25vZGVDYWNoZS5oYXNPd25Qcm9wZXJ0eShodG1sSWQpKQogICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX25vZGVDYWNoZVtodG1sSWRdOwogICAgICAgIH0sCgogICAgICAgIF9wcm9jZXNzVGVtcGxhdGU6IGZ1bmN0aW9uIChqc29uVGVtcGxhdGUsIGpzb25Nb2RlbCwgY2FuUmVwZWF0KSB7CiAgICAgICAgICAgIHZhciB0ZW1wbGF0ZUlkID0gbnVsbDsKICAgICAgICAgICAgaWYgKHRoaXMuZ2V0T3JFbHNlKGpzb25UZW1wbGF0ZSwgImV4dHJhcy5odG1sSWQiLCBudWxsKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBqc29uVGVtcGxhdGUuZXh0cmFzID0ganNvblRlbXBsYXRlLmV4dHJhcyB8fCB7fTsKICAgICAgICAgICAgICAgIGpzb25UZW1wbGF0ZS5leHRyYXMuaHRtbElkID0gIkNMXyIgKyAoKyt0aGlzLl9sYXN0SUQpOwogICAgICAgICAgICAgICAgdGVtcGxhdGVJZCA9IGpzb25UZW1wbGF0ZS5leHRyYXMuaHRtbElkOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0aGlzLmdldE9yRWxzZShqc29uTW9kZWwsICJleHRyYXMuaHRtbElkIiwgbnVsbCkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAganNvbk1vZGVsLmV4dHJhcyA9IGpzb25Nb2RlbC5leHRyYXMgfHwge307CiAgICAgICAgICAgICAgICBpZiAodGVtcGxhdGVJZCAhPSBudWxsKQogICAgICAgICAgICAgICAgICAgIGpzb25Nb2RlbC5leHRyYXMuaHRtbElkID0gdGVtcGxhdGVJZDsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBqc29uTW9kZWwuZXh0cmFzLmh0bWxJZCA9ICJDTF8iICsgKCsrdGhpcy5fbGFzdElEKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl90MEpzb25Ob2RlQ2FjaGVbanNvbk1vZGVsLmV4dHJhcy5odG1sSWRdID0ge3RlbXBsYXRlUmVmOiBqc29uVGVtcGxhdGUsIGluaXRpYWxSZWY6IGpzb25Nb2RlbH07CgogICAgICAgICAgICBpZiAoIWNhblJlcGVhdCAmJiAhXy5jb250YWlucyhbImFyZWEiLCAicGFnZVNldCIsICJwYWdlQXJlYSIsICJzdWJmb3JtIiwgInN1YmZvcm1TZXQiLCAiY29udGVudEFyZWEiLCAiZXhjbEdyb3VwIiwgImZvcm0iXSwganNvbk1vZGVsLl9jbGFzcykpIHsKICAgICAgICAgICAgICAgIC8vUHJvY2VzcyBpdCdzIGNoaWxkIG9ubHkgaWYgdGhhdCBjYW4gcmVwZWF0IG9yIGl0IGNhbiBoYXZlIHBhaW50YWJsZSBjaGlsZHJlbi4gVGhpcyBpcyBiYWRseSB3cml0dGVuIGNoZWNrLiBOZWVkIHRvIHJlLWNvZGUgdGhpcy4KICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGxhc3RJTSA9IG51bGw7CiAgICAgICAgICAgIHZhciBsYXN0Q2hpbGRTRiA9IGZhbHNlOwogICAgICAgICAgICB2YXIgY2hpbGRUZW1wbGF0ZUluZGV4ID0gLTE7CiAgICAgICAgICAgIF8uZWFjaChqc29uTW9kZWwuY2hpbGRyZW4sCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoY2hpbGROb2RlLCBpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubWF0Y2hKc29uVHlwZShjaGlsZE5vZGUsICJpbnN0YW5jZU1hbmFnZXIiKSkgewogICAgICAgICAgICAgICAgICAgICAgICBsYXN0SU0gPSBjaGlsZE5vZGU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoIWxhc3RDaGlsZFNGKSB7ICAgLy9JZiBsYXN0IGNoaWxkIHdhcyBub3Qgc3ViZm9ybSB0aGVuIGluY3JlYXNlIHRlbXBsYXRlIGluZGV4CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkVGVtcGxhdGVJbmRleCA9IGNoaWxkVGVtcGxhdGVJbmRleCArIDE7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy54ZmFVdGlsKCkuaXNSZXBlYXRhYmVFbChjaGlsZE5vZGUuX2NsYXNzKSkgeyAvL0Vsc2UgaW5jcmVhc2UgdGVtcGxhdGUgaW5kZXggb25seSBmb3Igbm9uLXN1YmZvcm0KICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRUZW1wbGF0ZUluZGV4ID0gY2hpbGRUZW1wbGF0ZUluZGV4ICsgMTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZFJlcGVhdCA9IGNhblJlcGVhdDsKICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy54ZmFVdGlsKCkuaXNSZXBlYXRhYmVFbChjaGlsZE5vZGUuX2NsYXNzKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFJlcGVhdCA9IGNoaWxkUmVwZWF0IHx8IHBhcnNlSW50KHRoaXMuZ2V0T3JFbHNlKGxhc3RJTSwgIm1heCIsIHhmYWxpYi5zY3JpcHQuT2NjdXIucHJvdG90eXBlLl9kZWZhdWx0cy5tYXgpKSA8IDAgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChwYXJzZUludCh0aGlzLmdldE9yRWxzZShsYXN0SU0sICJtaW4iLCB4ZmFsaWIuc2NyaXB0Lk9jY3VyLnByb3RvdHlwZS5fZGVmYXVsdHMubWluKSkgPCBwYXJzZUludCh0aGlzLmdldE9yRWxzZShsYXN0SU0sICJtYXgiLCB4ZmFsaWIuc2NyaXB0Lk9jY3VyLnByb3RvdHlwZS5fZGVmYXVsdHMubWF4KSkpOwogICAgICAgICAgICAgICAgICAgICAgICBsYXN0Q2hpbGRTRiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgbGFzdENoaWxkU0YgPSBmYWxzZTsKCiAgICAgICAgICAgICAgICAgICAganNvblRlbXBsYXRlLmNoaWxkcmVuID0ganNvblRlbXBsYXRlLmNoaWxkcmVuIHx8IFtdOwogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZFRlbXBsYXRlID0ganNvblRlbXBsYXRlLmNoaWxkcmVuW2NoaWxkVGVtcGxhdGVJbmRleF07CiAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZFRlbXBsYXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkVGVtcGxhdGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3M6IGNoaWxkTm9kZS5fY2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBjaGlsZE5vZGUubmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhczogY2hpbGROb2RlLmV4dHJhcyB8fCB7fQogICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRSZXBlYXQpIHsgLy9Gb3IgcmVwZWF0YWJsZSBjaGlsZCBjb3B5IGFsbCBwcm9wZXJ0aWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvcHlPYmplY3QoY2hpbGROb2RlLCBjaGlsZFRlbXBsYXRlLCB7ZXhjZXB0aW9uczogWyJjaGlsZHJlbiJdLCBrZWVwUmVmZXJlbmNlOiBmYWxzZX0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGpzb25UZW1wbGF0ZS5jaGlsZHJlbi5wdXNoKGNoaWxkVGVtcGxhdGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcm9jZXNzVGVtcGxhdGUoY2hpbGRUZW1wbGF0ZSwgY2hpbGROb2RlLCBjaGlsZFJlcGVhdCk7CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICB9LAoKICAgICAgICBfcHJvY2Vzc01vZGVsOiBmdW5jdGlvbiAoanNvblRlbXBsYXRlLCBtb2RlbCkgewogICAgICAgICAgICBpZiAobW9kZWwuaHRtbElkID09IG51bGwpIHsKICAgICAgICAgICAgICAgIG1vZGVsLmh0bWxJZCA9ICJDTF8iICsgKCsrdGhpcy5fbGFzdElEKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl9ub2RlQ2FjaGVbbW9kZWwuaHRtbElkXSA9IHt0ZW1wbGF0ZVJlZjoganNvblRlbXBsYXRlLCBtb2RlbDogbW9kZWx9OwogICAgICAgICAgICB2YXIgY2hpbGRUZW1wbGF0ZUluZGV4ID0gLTE7CiAgICAgICAgICAgIHZhciBsYXN0Q2hpbGRTRiA9IGZhbHNlOwogICAgICAgICAgICBfLmVhY2gobW9kZWwuY2hpbGRyZW4sCiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoY2hpbGROb2RlLCBpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFsYXN0Q2hpbGRTRikgeyAgIC8vSWYgbGFzdCBjaGlsZCB3YXMgbm90IHN1YmZvcm0gdGhlbiBpbmNyZWFzZSB0ZW1wbGF0ZSBpbmRleAogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFRlbXBsYXRlSW5kZXggPSBjaGlsZFRlbXBsYXRlSW5kZXggKyAxOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIShjaGlsZE5vZGUgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LlN1YmZvcm0pKSB7IC8vRWxzZSBpbmNyZWFzZSB0ZW1wbGF0ZSBpbmRleCBvbmx5IGZvciBub24tc3ViZm9ybQogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFRlbXBsYXRlSW5kZXggPSBjaGlsZFRlbXBsYXRlSW5kZXggKyAxOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgbGFzdENoaWxkU0YgPSBjaGlsZE5vZGUgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LlN1YmZvcm07CgogICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZFRlbXBsYXRlID0ganNvblRlbXBsYXRlLmNoaWxkcmVuID8ganNvblRlbXBsYXRlLmNoaWxkcmVuW2NoaWxkVGVtcGxhdGVJbmRleF0gOiB1bmRlZmluZWQKICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRUZW1wbGF0ZSkKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcHJvY2Vzc01vZGVsKGNoaWxkVGVtcGxhdGUsIGNoaWxkTm9kZSk7CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICB9LAoKICAgICAgICBtYXRjaEpzb25UeXBlOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUubWF0Y2hKc29uVHlwZQoKICAgIH0pOwoKfSkoXywgJCwgeGZhbGliKTsKLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuWGZhCiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5Nb2RlbAogKiBAaW1wb3J0IHhmYWxpYi51dC5Mb2dnZXIKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lkhvc3QKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBYRkEgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwoKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIC8qKgogICAgICogQGNsYXNzIFRoZSBjbGFzcyByZXByZXNlbnRzIHRoZSBYRkEgT2JqZWN0CiAgICAgKiBAZXh0ZW5kcyBjb20uYWRvYmUueGZhLnNjcmlwdGluZy5Nb2RlbAogICAgICogQHByb3BlcnR5IHtjb20uYWRvYmUueGZhLnNjcmlwdGluZy5Ib3N0fSBob3N0IE9iamVjdCBvZiB0aGUgaG9zdCBjbGFzcwogICAgICovCiAgICB2YXIgWGZhID0geGZhbGliLnNjcmlwdC5YZmEgPSB4ZmFsaWIuc2NyaXB0Lk1vZGVsLmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJ4ZmEiLAogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhID0gdGhpczsgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1RPRE86IEhhbmRsZSBhbml0aGluZyBiZWluZyB1c2VkIGJlZm9yZSBzdXBlcgogICAgICAgICAgICB4ZmFsaWIucnVudGltZVsiJHhmYSJdID0gdGhpczsKICAgICAgICAgICAgdGhpcy4kbGF5b3V0ID0gdGhpcy5sYXlvdXQgPSBuZXcgeGZhbGliLnNjcmlwdC5MYXlvdXQoeyJqc29uTW9kZWwiOiB7fX0pOwogICAgICAgICAgICB2YXIgbG9nQ29uZiA9IHdpbmRvdy5mb3JtQnJpZGdlLnJlZ2lzdGVyQ29uZmlnKCJMb2dnZXJDb25maWciKS5kYXRhIHx8IHt9OwogICAgICAgICAgICB2YXIgcmVuZGVyQ29udGV4dENvcHkgPSB7fTsKICAgICAgICAgICAgdGhpcy5jb3B5T2JqZWN0KHhmYWxpYi5ydW50aW1lLnJlbmRlckNvbnRleHQsIHJlbmRlckNvbnRleHRDb3B5LCB7ImV4Y2VwdGlvbnMiOiBbImRhdGEiXX0pCiAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIgPSBuZXcgeGZhbGliLnV0LkxvZ2dlcih7CiAgICAgICAgICAgICAgICAianNvbk1vZGVsIjogbG9nQ29uZiwKICAgICAgICAgICAgICAgIGxvZ1NlcnZpY2VQcm94eTogdGhpcy5nZXRPckVsc2Uod2luZG93LmZvcm1CcmlkZ2UudXNlckNvbmZpZ1sic3VibWl0U2VydmljZVByb3h5Q29uZmlnIl0sICJsb2dTZXJ2aWNlUHJveHkiLCAiIiksCiAgICAgICAgICAgICAgICByZW5kZXJDb250ZXh0OiByZW5kZXJDb250ZXh0Q29weSwKICAgICAgICAgICAgICAgIGNvbnRleHRQYXRoOiB3aW5kb3cuZm9ybUJyaWRnZS51c2VyQ29uZmlnWyJjb250ZXh0UGF0aCJdCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuRXJyb3JNYW5hZ2VyID0gdGhpcy5nZXRPckVsc2Uod2luZG93LmZvcm1CcmlkZ2UudXNlckNvbmZpZ1siZXJyb3JDb25maWciXSxuZXcgeGZhbGliLnZpZXcudXRpbC5FcnJvck1hbmFnZXIpCiAgICAgICAgICAgIHhmYWxpYi5zY3JpcHQuWGZhLkluc3RhbmNlID0gdGhpczsgICAgICAgICAgLy9UT0RPOiBTaW5nbGV0b24gcmVxZD8KICAgICAgICAgICAgdGhpcy5fc3VibWl0QnV0dG9ucyA9IFtdOwogICAgICAgICAgICB0aGlzLl9tb2RlbEluaXRpYWxpemUgPSAnVU5JTklUSUFMSVpFRCc7IC8vIGNhbiBiZSBzZXQgdG8gJ0lOSVRJQUxJWkVEJyBvciAnJ0lOSVRJQUxJWklORycKICAgICAgICAgICAgdGhpcy5tb0NvbnRleHROb2RlcyA9IFtdOwogICAgICAgICAgICB0aGlzLm1vQ2FsY3VsYXRlRXZlbnRTdGFjayA9IFtdOwogICAgICAgICAgICB0aGlzLm1vQ2FsY3VsYXRlRXZlbnROb2RlID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5ob3N0ID0gbmV3IHhmYWxpYi5zY3JpcHQuSG9zdCgpOwogICAgICAgICAgICB4ZmFsaWIucnVudGltZVsiJGhvc3QiXSA9IHRoaXMuaG9zdDsKICAgICAgICAgICAgdGhpcy5jb3VudEVycm9yID0gMDsKICAgICAgICAgICAgdGhpcy5kYXRhTm9kZXMgPSB7fTsKICAgICAgICAgICAgdGhpcy5fdGVtcGxhdGVTY2hlbWEgPSBuZXcgeGZhbGliLnRlbXBsYXRlLlRlbXBsYXRlU2NoZW1hKCk7CiAgICAgICAgICAgIHRoaXMubW9Db250ZXh0U2NyaXB0RXZlbnQgPSBudWxsOyAvLyB3aWxsIGhvbGQgY3VycmVudCBldmVudCBmb3Igd2hpY2ggc2NyaXB0IGlzIGV4ZWN1dGluZwogICAgICAgICAgICB0aGlzLlF1ZXVlID0geyJjYWxjIjogW10sICJjYWxjaW5kZXgiOiAwLCAidmFsaWRhdGUiOiBbXSwgInZhbGlkYXRlaW5kZXgiOiAwLCBjYWxjQ291bnQ6IHt9LAogICAgICAgICAgICAgICAgInNldGZvY3VzIjogW10sICJzZXRmb2N1c2luZGV4IjogMH07CgogICAgICAgICAgICAvLyB0byBjbGVhciBhbGwgX21vQ29udGV4dC1zIGNhY2hlZCBpbiBldmVudENvbnRhaW5lck5vZGUtcywgYWZ0ZXIgc3ViZm9ybS5hZGRJbnN0YW5jZSBvciBzdWJmb3JtLnJlbW92ZUluc3RhbmNlCiAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5fY2xlYXJBbGxNb0NvbnRleHRzID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgZnVuY3Rpb24gY2xlYXJNb0NvbnRleHRWaXNpdG9yKHRhcmdldCkgewogICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LkV2ZW50Q29udGFpbmVyTm9kZSkgewogICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQuX21vQ29udGV4dCA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLmZvcm0uX2dldFJvb3RTdWJmb3JtKCkuX3Zpc2l0QWxsbW9DaGlsZHJlbihjbGVhck1vQ29udGV4dFZpc2l0b3IpOwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgLy9DcmVhdGUgRm9ybSBDaGlsZAogICAgICAgICAgICB2YXIgZm9ybUpzb24gPSBfLmZpbmQodGhpcy5qc29uTW9kZWwuY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkLl9jbGFzcyA9PSAiZm9ybSI7CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICB0aGlzLl94ZmFUZW1wbGF0ZUNhY2hlID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhVGVtcGxhdGVDYWNoZSh7aW5pdGlhbEZvcm1Eb206IGZvcm1Kc29ufSk7CgogICAgICAgICAgICAvL1dlIGNhbGwgU3VwZXIgbGF0ZXIgYXQgdGhpcyBzdGFnZSBzaW5jZSB3ZSBuZWVkIHRvIGluaXRpYWxpemUgZmV3IHZhcmlhYmxlcyB3aGljaCBhcmUgcmVxdWlyZWQgd2hpbGUgaW5pdGlhbGl6aW5nIGNoaWxkcmVuCiAgICAgICAgICAgIFhmYS5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwoKICAgICAgICAgICAgLy9nZXQgdGhlIGNoaWxkIGZyb20gY2hpbGRyZW4gbW9kZWxzIHRoYXQgYXJlIGFscmVhZHkgY3JlYXRlZC4KICAgICAgICAgICAgdGhpcy5mb3JtID0gXy5maW5kKHRoaXMuY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkLl9pc0Zvcm0oKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHRoaXMuX3hmYVRlbXBsYXRlQ2FjaGUucHV0TW9kZWwodGhpcy5mb3JtLAogICAgICAgICAgICAgICAgdGhpcy5feGZhVGVtcGxhdGVDYWNoZS5nZXRUZW1wbGF0ZVJlZih0aGlzLmdldE9yRWxzZShmb3JtSnNvbiwgImV4dHJhcy5odG1sSWQiLCB7fSkpCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAvL05vdGU6IHNpbmNlIHdlIGRvIG5vdCBzdXBwb3J0IHRlbXBsYXRlIGN1cnJlbnRseSwgd2Ugd29ya2Fyb25kIGJ5IHBvaW50aW5nIHRlbXBsYXRlIG5vZGUgdG8gZm9ybSBub2RlIHdoaWNoIHdvdWxkIGhhdmUgc2ltaWxhciBzdHJ1Y3R1cmUgaW4gbW9zdCBjYXNlcy4KICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWVbJyR0ZW1wbGF0ZSddID0gdGhpcy50ZW1wbGF0ZSA9IHhmYWxpYi5ydW50aW1lWyckZm9ybSddID0gdGhpcy5mb3JtOwogICAgICAgICAgICB4ZmFsaWIucnVudGltZVsndGVtcGxhdGUnXSA9IHhmYWxpYi5ydW50aW1lWydmb3JtJ10gPSB0aGlzLmZvcm07CgogICAgICAgICAgICAvL0NyZWF0ZSBDb25maWcgQ2hpbGQuIE5vdGljZSB0aGF0IGl0IGlzIG5vdCBYRkEgTm9kZSBtb2RlbCwganVzdCBhIGpzb24gY2hpbGQgZm9yIG5vdy4KICAgICAgICAgICAgdGhpcy5jb25maWcgPSBfLmZpbmQodGhpcy5qc29uTW9kZWwuY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkLl9jbGFzcyA9PSAiY29uZmlnIjsKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lWyckY29uZmlnJ10gPSB0aGlzLmNvbmZpZzsKCiAgICAgICAgICAgIC8vQ3JlYXRlIGxvY2FsZVNldCBDaGlsZC4gTm90aWNlIHRoYXQgaXQgaXMgbm90IFhGQSBOb2RlIG1vZGVsLCBqdXN0IGEganNvbiBjaGlsZCBmb3Igbm93LgogICAgICAgICAgICB0aGlzLmxvY2FsZVNldCA9IHRoaXMuanNvbk1vZGVsLmxvY2FsZVNldDsKICAgICAgICAgICAgdGhpcy5kZWZhdWx0TG9jYWxlID0gImVuX1VTIjsgLy9UT0RPOiByZWFkIGZyb20ganNwCgogICAgICAgICAgICAvL09uY2UgZXZlcnl0aGluZyBpcyBzZXQgdXAsIG5vdyBpcyB0aGUgdGltZSB0byBzZXQgcGFyZW50IGFjY2VzcwogICAgICAgICAgICB0aGlzLmZvcm0uX2NhbGN1bGF0ZUVmZmVjdGl2ZUFjY2VzcygpOwogICAgICAgICAgICB0aGlzLmZvcm0uX2NhbGN1bGF0ZUVmZmVjdGl2ZVByZXNlbmNlKCk7CiAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlUnVubmluZyA9IGZhbHNlOwogICAgICAgICAgICB0aGlzLnZhbGlkYXRlUnVubmluZyA9IGZhbHNlOwogICAgICAgICAgICB0aGlzLnZlcnNpb25Db25maWcgPSBuZXcgeGZhbGliLnV0LlZlcnNpb24oZm9ybUJyaWRnZS51c2VyQ29uZmlnWyJiZWhhdmlvckNvbmZpZyJdKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBFdmFsdWF0ZXMgdGhlIHNwZWNpZmllZCBTT00gZXhwcmVzc2lvbiwgYmVnaW5uaW5nIHdpdGggdGhlIGN1cnJlbnQgWE1MIGZvcm0KICAgICAgICAgKiBvYmplY3QgbW9kZWwgb2JqZWN0LCBhbmQgcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIG9iamVjdCBzcGVjaWZpZWQgaW4gdGhlIFNPTQogICAgICAgICAqIGV4cHJlc3Npb24KICAgICAgICAgKiBAT3ZlcnJpZGVzCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgcmVzb2x2ZU5vZGU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMSkKICAgICAgICAgICAgICAgIHJldHVybiBYZmEuX3N1cGVyLnJlc29sdmVOb2RlLmNhbGwodGhpcywgdGhpcy5fY29udGV4dE5vZGUoKSB8fCB0aGlzLCBhcmd1bWVudHNbMF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gWGZhLl9zdXBlci5yZXNvbHZlTm9kZS5jYWxsKHRoaXMsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBFdmFsdWF0ZXMgdGhlIHNwZWNpZmllZCBTT00gZXhwcmVzc2lvbiwgYmVnaW5uaW5nIHdpdGggdGhlIGN1cnJlbnQgWE1MIGZvcm0KICAgICAgICAgKiBvYmplY3QgbW9kZWwgb2JqZWN0LCBhbmQgcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIG9iamVjdCBzcGVjaWZpZWQgaW4gdGhlIFNPTQogICAgICAgICAqIGV4cHJlc3Npb24KICAgICAgICAgKiBAT3ZlcnJpZGVzCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICovCiAgICAgICAgcmVzb2x2ZU5vZGVzOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDEpCiAgICAgICAgICAgICAgICByZXR1cm4gWGZhLl9zdXBlci5yZXNvbHZlTm9kZXMuY2FsbCh0aGlzLCB0aGlzLl9jb250ZXh0Tm9kZSgpLCBhcmd1bWVudHNbMF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gWGZhLl9zdXBlci5yZXNvbHZlTm9kZXMuY2FsbCh0aGlzLCBhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSk7CiAgICAgICAgfSwKCiAgICAgICAgX25ld1N1Ym1pdEJ1dHRvbjogZnVuY3Rpb24gKGVsZW0pIHsKICAgICAgICAgICAgaWYgKCF+dGhpcy5fc3VibWl0QnV0dG9ucy5pbmRleE9mKGVsZW0pKSAgICAgLy9UT0RPOiBXaGF0IGlzIHRoaXMuIEFkZCBhIGNvbW1lbnQKICAgICAgICAgICAgICAgIHRoaXMuX3N1Ym1pdEJ1dHRvbnMucHVzaChlbGVtKTsKICAgICAgICB9LAoKICAgICAgICBfaGlkZVN1Ym1pdEJ1dHRvbnM6IGZ1bmN0aW9uIChlbGVtKSB7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fc3VibWl0QnV0dG9ucy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5fc3VibWl0QnV0dG9uc1tpXS5wcmVzZW5jZSA9ICJoaWRkZW4iOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIGZ1bmN0aW9uIHB1c2hlcyBhIG5ldyBDYWxjdWxhdGUgRXZlbnQgTm9kZSBpbnRvIHRoZSBDYWxjdWxhdGUgU3RhY2sKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcGFyYW0ge2NvbS5hZG9iZS54ZmEuc2NyaXB0aW5nLk5vZGV9IG5vZGUgY3VycmVudCBjb250ZXh0IG5vZGUKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9wdXNoQ2FsY3VsYXRlRXZlbnROb2RlOiBmdW5jdGlvbiAobm9kZSkgewogICAgICAgICAgICB0aGlzLm1vQ2FsY3VsYXRlRXZlbnRTdGFjay5wdXNoKG5vZGUpOwogICAgICAgICAgICB0aGlzLm1vQ2FsY3VsYXRlRXZlbnROb2RlID0gbm9kZTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgZnVuY3Rpb24gcHVzaGVzIGEgbmV3IFhGQSBOb2RlIGluIHRoZSBjdXJyZW50IGNvbnRleHQKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcGFyYW0ge2NvbS5hZG9iZS54ZmEuc2NyaXB0aW5nLk5vZGV9IG5vZGUgY3VycmVudCBjb250ZXh0IG5vZGUKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9wdXNoQ29udGV4dE5vZGU6IGZ1bmN0aW9uIChub2RlKSB7CiAgICAgICAgICAgIHRoaXMubW9Db250ZXh0Tm9kZXMucHVzaChub2RlKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgZnVuY3Rpb24gcG9wcyBDYWxjdWxhdGUgRXZlbnQgTm9kZSBmcm9tIHRoZSBzdGFjayBvZiBjb250ZXh0IG5vZGVzCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogQHByaXZhdGUKICAgICAgICAgKi8KICAgICAgICBfcG9wQ2FsY3VsYXRlRXZlbnROb2RlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMubW9DYWxjdWxhdGVFdmVudFN0YWNrLnBvcCgpOwogICAgICAgICAgICB0aGlzLm1vQ2FsY3VsYXRlRXZlbnROb2RlID0gbnVsbDsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgZnVuY3Rpb24gcG9wcyBhIFhGQSBOb2RlIGZyb20gdGhlIHN0YWNrIG9mIGNvbnRleHQgbm9kZXMKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9wb3BDb250ZXh0Tm9kZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGlzLm1vQ29udGV4dE5vZGVzLnBvcCgpOwogICAgICAgIH0sCgogICAgICAgIF9jb250ZXh0Tm9kZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgbGVuID0gdGhpcy5tb0NvbnRleHROb2Rlcy5sZW5ndGg7CiAgICAgICAgICAgIGlmIChsZW4gPiAwKQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubW9Db250ZXh0Tm9kZXNbbGVuIC0gMV0KICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgfSwKCiAgICAgICAgX2lzWEZBQ29udGFpbmVyTm9kZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0U29tRXhwcmVzc2lvbjogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm5hbWUiKSArICJbIiArIHRoaXMuaW5kZXggKyAiXSI7CiAgICAgICAgfSwKCiAgICAgICAgX2dldExvY2FsZVN5bWJvbHM6IGZ1bmN0aW9uIChsb2NhbGUsIHN5bWJvbCkgewogICAgICAgICAgICB2YXIgcmV0ID0gbnVsbDsKICAgICAgICAgICAgdmFyIG5ld1N5bWJvbCA9ICJsb2NhbGVzLiIgKyBsb2NhbGUgKyAiLiIgKyBzeW1ib2w7CiAgICAgICAgICAgIHJldCA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMubG9jYWxlU2V0LCBuZXdTeW1ib2wsIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5nZXREZWZhdWx0TG9jYWxlUHJvcGVydHkoc3ltYm9sKSk7CiAgICAgICAgICAgIGlmICghcmV0KSB7CiAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmVycm9yKCJ4ZmEiLCAidW5hYmxlIHRvIGZpbmQgIiArIHN5bWJvbCArICIgZm9yIGxvY2FsZSAiICsgbG9jYWxlICsgImluIGxvY2FsZVNldCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfSwKCiAgICAgICAgc2V0U3ViZm9ybUZvY3VzOiBmdW5jdGlvbiAoc3ViZm9ybSkgewogICAgICAgICAgICB2YXIgb2xkU3ViZm9ybSA9IHRoaXMuY3VycmVudFN1YmZvcm07CiAgICAgICAgICAgIHRoaXMuY3VycmVudFN1YmZvcm0gPSBzdWJmb3JtOwogICAgICAgICAgICB2YXIgdmlld3MgPSBbXTsKICAgICAgICAgICAgaWYgKG9sZFN1YmZvcm0pIHsKICAgICAgICAgICAgICAgIHZhciBwU3ViZm9ybSA9IHN1YmZvcm07CiAgICAgICAgICAgICAgICB3aGlsZSAocFN1YmZvcm0pIHsKICAgICAgICAgICAgICAgICAgICB2aWV3cy5wdXNoKHBTdWJmb3JtKTsKICAgICAgICAgICAgICAgICAgICBwU3ViZm9ybSA9IHBTdWJmb3JtLnBhcmVudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHdoaWxlIChvbGRTdWJmb3JtICYmIHZpZXdzLmluZGV4T2Yob2xkU3ViZm9ybSkgPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICBvbGRTdWJmb3JtLmV4ZWNFdmVudCgiZXhpdCIpOwogICAgICAgICAgICAgICAgICAgIG9sZFN1YmZvcm0gPSBvbGRTdWJmb3JtLnBhcmVudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZURhdGFOb2RlOiBmdW5jdGlvbiAoaWQsIG1vZGVsKSB7CiAgICAgICAgICAgIGlmIChpZCkgewogICAgICAgICAgICAgICAgdmFyIGRuID0gdGhpcy5kYXRhTm9kZXNbaWRdIHx8IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxSZWdpc3RyeS5wcm90b3R5cGUuY3JlYXRlRGF0YU5vZGUoaWQpOwogICAgICAgICAgICAgICAgZG4uYWRkRmllbGQobW9kZWwpOwogICAgICAgICAgICAgICAgdGhpcy5kYXRhTm9kZXNbaWRdID0gZG47CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBxdWV1ZUNhbGNFdmVudDogZnVuY3Rpb24gKG9MaXN0ZW5lcikgewogICAgICAgICAgICBpZiAoIXRoaXMuaG9zdC5jYWxjdWxhdGlvbnNFbmFibGVkKQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB2YXIgcSA9IHRoaXMuUXVldWVbImNhbGMiXTsKICAgICAgICAgICAgdmFyIHNvbSA9IG9MaXN0ZW5lci5zb21FeHByZXNzaW9uOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHEubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBpdGVtID0gcVtpXTsKICAgICAgICAgICAgICAgIGlmIChvTGlzdGVuZXIgPT0gaXRlbSkgewogICAgICAgICAgICAgICAgICAgIGlmIChpIDwgdGhpcy5RdWV1ZS5jYWxjaW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuUXVldWUuY2FsY0NvdW50W3NvbV0gPT09IDEwKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLlF1ZXVlLmNhbGNDb3VudFtzb21dID0gdGhpcy5RdWV1ZS5jYWxjQ291bnRbc29tXSB8fCAwOwogICAgICAgICAgICB0aGlzLlF1ZXVlLmNhbGNDb3VudFtzb21dKys7CiAgICAgICAgICAgIHEucHVzaChvTGlzdGVuZXIpOwogICAgICAgIH0sCgogICAgICAgIHF1ZXVlVmFsaWRhdGVFdmVudDogZnVuY3Rpb24gKG9Ob2RlKSB7CiAgICAgICAgICAgIGlmICghdGhpcy5ob3N0LnZhbGlkYXRpb25zRW5hYmxlZCkKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgaWYgKCF+dGhpcy5RdWV1ZVsidmFsaWRhdGUiXS5pbmRleE9mKG9Ob2RlKSkKICAgICAgICAgICAgICAgIHRoaXMuUXVldWVbInZhbGlkYXRlIl0ucHVzaChvTm9kZSk7CiAgICAgICAgfSwKCiAgICAgICAgcXVldWVGb2N1c0V2ZW50OiBmdW5jdGlvbiAoY29udGV4dCwgc29tKSB7CiAgICAgICAgICAgIHRoaXMuUXVldWVbInNldGZvY3VzIl0ucHVzaCh7J2NvbnRleHQnOiBjb250ZXh0LCAnc29tJzogc29tfSk7CiAgICAgICAgfSwKCiAgICAgICAgcnVuUXVldWU6IGZ1bmN0aW9uIChxdWV1ZSwgZXZudCkgewogICAgICAgICAgICBpZiAocXVldWUgIT09ICJjYWxjIiAmJiBxdWV1ZSAhPT0gInZhbGlkYXRlIikKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgaWYgKHF1ZXVlID09ICJjYWxjIiAmJiAhdGhpcy5ob3N0LmNhbGN1bGF0aW9uc0VuYWJsZWQpCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIGlmIChxdWV1ZSA9PSAidmFsaWRhdGUiICYmICF0aGlzLmhvc3QudmFsaWRhdGlvbnNFbmFibGVkKQogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB2YXIgUSA9IHRoaXMuUXVldWVbcXVldWVdOwogICAgICAgICAgICB2YXIgaW5kID0gdGhpcy5RdWV1ZVtxdWV1ZSArICJpbmRleCJdOwogICAgICAgICAgICBmb3IgKHZhciBpID0gaW5kOyBpIDwgUS5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdGhpcy5RdWV1ZVtxdWV1ZSArICJpbmRleCJdKys7CiAgICAgICAgICAgICAgICBpZiAoZXZudCA9PT0gInZhbGlkYXRlIikgewogICAgICAgICAgICAgICAgICAgIFFbaV0uX3ZhbGlkYXRlKFtdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIFFbaV0uZXhlY0V2ZW50KGV2bnQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcnVuQ2FsY0FuZFZhbGlkYXRlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuX3B1c2hDb250ZXh0Tm9kZSh0aGlzLmZvcm0pOwogICAgICAgICAgICB0aGlzLnJ1bkNhbGNzKCk7CiAgICAgICAgICAgIHRoaXMucnVuVmFsaWRhdGVzKCk7CiAgICAgICAgICAgIHRoaXMucnVuU2V0Rm9jdXNlcygpOwogICAgICAgICAgICB0aGlzLlF1ZXVlWyJjYWxjIl0gPSBbXTsKICAgICAgICAgICAgdGhpcy5RdWV1ZS5jYWxjaW5kZXggPSAwOwogICAgICAgICAgICB0aGlzLlF1ZXVlLmNhbGNDb3VudCA9IHt9OwogICAgICAgICAgICB0aGlzLlF1ZXVlWyJ2YWxpZGF0ZSJdID0gW107CiAgICAgICAgICAgIHRoaXMuUXVldWUudmFsaWRhdGVpbmRleCA9IDA7CiAgICAgICAgICAgIHRoaXMuUXVldWVbInNldGZvY3VzIl0gPSBbXTsKICAgICAgICAgICAgdGhpcy5RdWV1ZS5zZXRmb2N1c2luZGV4ID0gMDsKICAgICAgICAgICAgdGhpcy5fcG9wQ29udGV4dE5vZGUoKTsKICAgICAgICB9LAoKICAgICAgICBydW5DYWxjczogZnVuY3Rpb24gKHN0YXJ0KSB7CiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3RhcnQgIT0gInVuZGVmaW5lZCIgJiYgc3RhcnQgPT09ICJ0cnVlIikKICAgICAgICAgICAgICAgIHRoaXMuUXVldWUuY2FsY2luZGV4ID0gMDsKICAgICAgICAgICAgdGhpcy5jYWxjdWxhdGVSdW5uaW5nID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5ydW5RdWV1ZSgiY2FsYyIsICJjYWxjdWxhdGUiKTsKICAgICAgICAgICAgdGhpcy5jYWxjdWxhdGVSdW5uaW5nID0gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgcnVuVmFsaWRhdGVzOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMudmFsaWRhdGVSdW5uaW5nID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5ydW5RdWV1ZSgidmFsaWRhdGUiLCAidmFsaWRhdGUiKQogICAgICAgICAgICB0aGlzLnZhbGlkYXRlUnVubmluZyA9IGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIHJ1blNldEZvY3VzZXM6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIFEgPSB0aGlzLlF1ZXVlWyJzZXRmb2N1cyJdLAogICAgICAgICAgICAgICAgaW5kZXggPSB0aGlzLlF1ZXVlWyJzZXRmb2N1c2luZGV4Il07CiAgICAgICAgICAgIGZvciAodmFyIGkgPSBpbmRleDsgaSA8IFEubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHRoaXMuUXVldWVbInNldGZvY3VzaW5kZXgiXSsrOwogICAgICAgICAgICAgICAgdmFyIHNvbSA9IFFbaV1bJ3NvbSddLAogICAgICAgICAgICAgICAgICAgIG5vZGUgPSBzb20sCiAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IFFbaV1bJ2NvbnRleHQnXTsKICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc29tID09ICJzdHJpbmciKQogICAgICAgICAgICAgICAgICAgIG5vZGUgPSBjb250ZXh0Ll94ZmEoKS5yZXNvbHZlTm9kZShzb20pOwogICAgICAgICAgICAgICAgaWYgKG5vZGUgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChjb250ZXh0LnBhZ2luZ01hbmFnZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQYWQvaSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmNsZWFyVGltZW91dE9uRGVzdHJveSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5wYWdpbmdNYW5hZ2VyLl9tYWtlUGFnZUZvckh0bWxJZChub2RlLmh0bWxJZCwgbm9kZS5fc2V0Rm9jdXMsIG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApOyAgLy8ganVzdCBnaXZlIGJyb3dzZXIgZW5vdWdoIHRpbWUgdG8gcmVnaXN0ZXIgdGhlIGtleXByZXNzCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LnBhZ2luZ01hbmFnZXIuX21ha2VQYWdlRm9ySHRtbElkKG5vZGUuaHRtbElkLCBub2RlLl9zZXRGb2N1cywgbm9kZSk7IC8vICQuZm9jdXMoKSBkb2Vzbid0IHdvcmsgaW5zaWRlIHNldFRpbWVvdXQgaW4gaVBhZAogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2NvbXB1dGVKc29uRGlmZjogZnVuY3Rpb24gKGRpZmZfbGV2ZWwpIHsKICAgICAgICAgICAgdmFyIGZvcm1EaWZmID0gdGhpcy5mb3JtLl9jb21wdXRlSnNvbkRpZmYoZGlmZl9sZXZlbCk7CiAgICAgICAgICAgIHZhciBkZXN0ID0gewogICAgICAgICAgICAgICAgX2NsYXNzOiB0aGlzLmNsYXNzTmFtZSwKICAgICAgICAgICAgICAgIG5hbWU6ICJ4ZmEiLAogICAgICAgICAgICAgICAgdmVyc2lvbk5TOiB0aGlzLmpzb25Nb2RlbC52ZXJzaW9uTlMsCiAgICAgICAgICAgICAgICBjaGlsZHJlbjogW2Zvcm1EaWZmLmpzb25EaWZmZXJlbmNlXQogICAgICAgICAgICB9OwoKICAgICAgICAgICAgcmV0dXJuIHsgImNoYW5nZWQiOiB0cnVlLAogICAgICAgICAgICAgICAgImpzb25EaWZmZXJlbmNlIjogZGVzdAogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0pOwoKICAgIFhmYS5fZGVmYXVsdExvY2FsZSA9IHsKICAgICAgICAiY2FsZW5kYXJTeW1ib2xzIjogewogICAgICAgICAgICAibW9udGhOYW1lcyI6IFsiSmFudWFyeSIsICJGZWJydWFyeSIsICJNYXJjaCIsICJBcHJpbCIsICJNYXkiLCAiSnVuZSIsICJKdWx5IiwgIkF1Z3VzdCIsICJTZXB0ZW1iZXIiLCAiT2N0b2JlciIsICJOb3ZlbWJlciIsICJEZWNlbWJlciJdLAogICAgICAgICAgICAiYWJicm1vbnRoTmFtZXMiOiBbIkphbiIsICJGZWIiLCAiTWFyIiwgIkFwciIsICJNYXkiLCAiSnVuIiwgIkp1bCIsICJBdWciLCAiU2VwIiwgIk9jdCIsICJOb3YiLCAiRGVjIl0sCiAgICAgICAgICAgICJkYXlOYW1lcyI6IFsiU3VuZGF5IiwgIk1vbmRheSIsICJUdWVzZGF5IiwgIldlZG5lc2RheSIsICJUaHVyc2RheSIsICJGcmlkYXkiLCAiU2F0dXJkYXkiXSwKICAgICAgICAgICAgImFiYnJkYXlOYW1lcyI6IFsiU3VuIiwgIk1vbiIsICJUdWUiLCAiV2VkIiwgIlRodSIsICJGcmkiLCAiU2F0Il0sCiAgICAgICAgICAgICJtZXJpZGllbU5hbWVzIjogWyJBTSIsICJQTSJdLAogICAgICAgICAgICAiZXJhTmFtZXMiOiBbIkJDIiwgIkFEIl0KICAgICAgICB9LAogICAgICAgICJkYXRlUGF0dGVybnMiOiB7CiAgICAgICAgICAgICJmdWxsIjogIkVFRUUgRCBNTU1NIFlZWVkiLAogICAgICAgICAgICAibG9uZyI6ICJEIE1NTU0gWVlZWSIsCiAgICAgICAgICAgICJtZWQiOiAiREQtTU1NLVlZIiwKICAgICAgICAgICAgInNob3J0IjogIkREL01NL1lZIgogICAgICAgIH0sCiAgICAgICAgInRpbWVQYXR0ZXJucyI6IHsKICAgICAgICAgICAgImZ1bGwiOiAiaDpNTTpTUyBBIFoiLAogICAgICAgICAgICAibG9uZyI6ICJoOk1NOlNTIEEgWiIsCiAgICAgICAgICAgICJtZWQiOiAiaDpNTTpTUyBBIiwKICAgICAgICAgICAgInNob3J0IjogImg6TU0gQSIKICAgICAgICB9LAogICAgICAgICJkYXRlVGltZVN5bWJvbHMiOiAiR3lNZGtIbXNTRURGd1dhaEt6WiIsCiAgICAgICAgIm51bWJlclBhdHRlcm5zIjogewogICAgICAgICAgICAibnVtZXJpYyI6ICJ6LHp6LHp6OS56enoiLAogICAgICAgICAgICAiY3VycmVuY3kiOiAiJCB6LHp6LHp6OS45OSIsCiAgICAgICAgICAgICJwZXJjZW50IjogInosenoseno5JSIKICAgICAgICB9LAogICAgICAgICJudW1iZXJTeW1ib2xzIjogewogICAgICAgICAgICAiZGVjaW1hbCI6ICIuIiwKICAgICAgICAgICAgImdyb3VwaW5nIjogIiwiLAogICAgICAgICAgICAicGVyY2VudCI6ICIlIiwKICAgICAgICAgICAgIm1pbnVzIjogIi0iLAogICAgICAgICAgICAiemVybyI6ICIwIgogICAgICAgIH0sCiAgICAgICAgImN1cnJlbmN5U3ltYm9scyI6IHsKICAgICAgICAgICAgInN5bWJvbCI6ICIkIiwKICAgICAgICAgICAgImlzb25hbWUiOiAiVVNEIiwKICAgICAgICAgICAgImRlY2ltYWwiOiAiLiIKICAgICAgICB9LAogICAgICAgICJ0eXBlZmFjZXMiOiB7fQogICAgfQp9KShfLCB4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5CiAqIEBpbXBvcnQgeGZhbGliLnV0LkNsYXNzCiAqLwooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBYZmFNb2RlbFJlZ2lzdHJ5ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbFJlZ2lzdHJ5ID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CgogICAgICAgIF9jbGFzc1RvRmFjdG9yeU1hcCA6IHsKICAgICAgICAgICAgInNjcmlwdCIgOiAiY3JlYXRlU2NyaXB0IiwKICAgICAgICAgICAgImV4Y2xHcm91cCIgOiAiY3JlYXRlRXhjbHVzaW9uR3JvdXAiLAoKICAgICAgICAgICAgImFyYyIgOiAiY3JlYXRlTm9kZVZhbHVlIiwKICAgICAgICAgICAgImJvb2xlYW4iOiAiY3JlYXRlTm9kZVZhbHVlIiwKICAgICAgICAgICAgImRhdGUiOiAiY3JlYXRlTm9kZVZhbHVlIiwKICAgICAgICAgICAgImRhdGVUaW1lIjogImNyZWF0ZU5vZGVWYWx1ZSIsCiAgICAgICAgICAgICJkZWNpbWFsIjogImNyZWF0ZU5vZGVWYWx1ZSIsCiAgICAgICAgICAgICJleERhdGEiOiAiY3JlYXRlTm9kZVZhbHVlIiwKICAgICAgICAgICAgImZsb2F0IjogImNyZWF0ZU5vZGVWYWx1ZSIsCiAgICAgICAgICAgICJpbWFnZSI6ICJjcmVhdGVOb2RlVmFsdWUiLAogICAgICAgICAgICAiaW50ZWdlciI6ICJjcmVhdGVOb2RlVmFsdWUiLAogICAgICAgICAgICAibGluZSI6ICJjcmVhdGVOb2RlVmFsdWUiLAogICAgICAgICAgICAicmVjdGFuZ2xlIjogImNyZWF0ZU5vZGVWYWx1ZSIsCiAgICAgICAgICAgICJ0ZXh0IjogImNyZWF0ZU5vZGVWYWx1ZSIsCiAgICAgICAgICAgICJ0aW1lIjogImNyZWF0ZU5vZGVWYWx1ZSIKCiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlTW9kZWwgOiBmdW5jdGlvbihqc29uTW9kZWwpewogICAgICAgICAgICB2YXIgbW9kZWwgPSBudWxsOwogICAgICAgICAgICB2YXIgZWxDbGFzcyA9IGpzb25Nb2RlbC5fY2xhc3MuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBqc29uTW9kZWwuX2NsYXNzLnN1YnN0cigxKTsKICAgICAgICAgICAgdmFyIGZhY3RvcnlGbk5hbWUgPSAiY3JlYXRlIiArIGVsQ2xhc3MgOwogICAgICAgICAgICBpZih0aGlzLl9jbGFzc1RvRmFjdG9yeU1hcFtqc29uTW9kZWwuX2NsYXNzXSl7CiAgICAgICAgICAgICAgICBmYWN0b3J5Rm5OYW1lID0gdGhpcy5fY2xhc3NUb0ZhY3RvcnlNYXBbanNvbk1vZGVsLl9jbGFzc107CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYodGhpc1tmYWN0b3J5Rm5OYW1lXSkKICAgICAgICAgICAgICAgIG1vZGVsID0gdGhpc1tmYWN0b3J5Rm5OYW1lXS5jYWxsKHRoaXMsIGpzb25Nb2RlbCk7CgoKICAgICAgICAgICAgaWYoIW1vZGVsICYmIHhmYWxpYi5zY3JpcHQuZG9tW2VsQ2xhc3NdKXsKICAgICAgICAgICAgICAgIG1vZGVsID0gbmV3IHhmYWxpYi5zY3JpcHQuZG9tW2VsQ2xhc3NdKHsianNvbk1vZGVsIiA6IGpzb25Nb2RlbH0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZighbW9kZWwpIHsKICAgICAgICAgICAgICAgIG1vZGVsID0gbmV3IHhmYWxpYi5zY3JpcHQuTm9kZSh7Impzb25Nb2RlbCIgOiBqc29uTW9kZWx9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbW9kZWw7CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlWGZhIDogZnVuY3Rpb24oanNvbil7CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5YZmEoeyJqc29uTW9kZWwiIDoganNvbn0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUZvcm0gOiBmdW5jdGlvbihqc29uKXsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LkZvcm0oeyJqc29uTW9kZWwiIDoganNvbn0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUNvbmZpZyA6IGZ1bmN0aW9uKGpzb24pewogICAgICAgICAgICByZXR1cm4ganNvbjsgICAgICAvL05vIHNlcGVyYXRlIG1vZGVsIEFQSSBmb3IgY29uZmlnIGZvciBub3cKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVUZXh0RmllbGQgOiBmdW5jdGlvbihmaWVsZCkgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuRmllbGQoeyJqc29uTW9kZWwiIDogZmllbGR9KTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVJbWFnZUZpZWxkIDogZnVuY3Rpb24oZmllbGQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LkZpZWxkKHsianNvbk1vZGVsIiA6IGZpZWxkfSk7CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlRGF0ZVRpbWVGaWVsZCA6IGZ1bmN0aW9uKGZpZWxkKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5EYXRlVGltZUZpZWxkKHsianNvbk1vZGVsIiA6IGZpZWxkfSk7CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlTnVtZXJpY0ZpZWxkIDogZnVuY3Rpb24oZmllbGQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0Lk51bWVyaWNGaWVsZCh7Impzb25Nb2RlbCIgOiBmaWVsZH0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUNob2ljZUxpc3RGaWVsZCA6IGZ1bmN0aW9uKGZpZWxkKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5DaG9pY2VMaXN0RmllbGQoeyJqc29uTW9kZWwiIDogZmllbGR9KTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVCdXR0b25GaWVsZCA6IGZ1bmN0aW9uKGZpZWxkKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5CdXR0b25GaWVsZCh7Impzb25Nb2RlbCIgOiBmaWVsZH0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUNoZWNrQnV0dG9uRmllbGQgOiBmdW5jdGlvbihmaWVsZCkgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuQ2hlY2tCdXR0b25GaWVsZCh7Impzb25Nb2RlbCIgOiBmaWVsZH0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZVRleHREcmF3IDogZnVuY3Rpb24oZHJhdykgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuRHJhdyh7Impzb25Nb2RlbCIgOiBkcmF3fSk7CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlSW5zdGFuY2VNYW5hZ2VyIDogZnVuY3Rpb24ob0luc3RhbmNlTWFuYWdlcikgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuSW5zdGFuY2VNYW5hZ2VyKHsianNvbk1vZGVsIiA6IG9JbnN0YW5jZU1hbmFnZXJ9KTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVQYWdlU2V0OiBmdW5jdGlvbih2UGFnZVNldCkgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuUGFnZVNldCh7Impzb25Nb2RlbCIgOiB2UGFnZVNldH0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZVBhZ2VBcmVhOiBmdW5jdGlvbih2UGFnZUFyZWEpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LlBhZ2VBcmVhKHsianNvbk1vZGVsIiA6IHZQYWdlQXJlYX0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUNvbnRlbnRBcmVhOiBmdW5jdGlvbih2Q29udGVudEFyZWEpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LkNvbnRlbnRBcmVhKHsianNvbk1vZGVsIiA6IHZDb250ZW50QXJlYX0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUV4Y2x1c2lvbkdyb3VwIDogZnVuY3Rpb24oZXhjbEdyb3VwKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5FeGNsdXNpb25Hcm91cCh7Impzb25Nb2RlbCIgOiBleGNsR3JvdXB9KTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVTdWJmb3JtOiBmdW5jdGlvbih2U3ViZm9ybSkgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuU3ViZm9ybSh7Impzb25Nb2RlbCIgOiB2U3ViZm9ybX0pOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUFyZWE6IGZ1bmN0aW9uKHZBcmVhKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5BcmVhKHsianNvbk1vZGVsIiA6IHZBcmVhfSk7CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlU3ViZm9ybVNldDogZnVuY3Rpb24odlN1YmZvcm1TZXQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LlN1YmZvcm1TZXQoeyJqc29uTW9kZWwiIDogdlN1YmZvcm1TZXR9KTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVWYXJpYWJsZXM6IGZ1bmN0aW9uKHZWYXJpYWJsZXMpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LlZhcmlhYmxlcyh7Impzb25Nb2RlbCIgOiB2VmFyaWFibGVzfSk7CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlU2NyaXB0OiBmdW5jdGlvbih2U2NyaXB0KSB7CiAgICAgICAgICAgIGlmKHZTY3JpcHQuX3BhcmVudENsYXNzICYmIHZTY3JpcHQuX3BhcmVudENsYXNzID09ICJ2YXJpYWJsZXMiKXsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5kb20uU2NyaXB0T2JqZWN0KHsianNvbk1vZGVsIiA6IHZTY3JpcHR9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5kb20uU2NyaXB0KHsianNvbk1vZGVsIiA6IHZTY3JpcHR9KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUZpZWxkIDogZnVuY3Rpb24oZmllbGQpIHsKICAgICAgICAgICAgdmFyIHQgPSBudWxsOwogICAgICAgICAgICB2YXIgY2hpbGRUeXBlID0gdGhpcy5nZXRPckVsc2UodGhpcy54ZmFVdGlsKCkuZ2V0VWlPbmVPZkNoaWxkVGFnKGZpZWxkKSwgIiIpLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgIHN3aXRjaCAoY2hpbGRUeXBlKSB7CiAgICAgICAgICAgICAgICBjYXNlICJkYXRldGltZWVkaXQiOgogICAgICAgICAgICAgICAgICAgIHQgPXRoaXMuY3JlYXRlRGF0ZVRpbWVGaWVsZChmaWVsZCkKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInRleHRlZGl0IjoKICAgICAgICAgICAgICAgICAgICB0ID0gdGhpcy5jcmVhdGVUZXh0RmllbGQoZmllbGQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiaW1hZ2VlZGl0IjoKICAgICAgICAgICAgICAgICAgICB0ID0gdGhpcy5jcmVhdGVJbWFnZUZpZWxkKGZpZWxkKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIm51bWVyaWNlZGl0IjoKICAgICAgICAgICAgICAgICAgICB0ID0gdGhpcy5jcmVhdGVOdW1lcmljRmllbGQoZmllbGQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiY2hvaWNlbGlzdCI6CiAgICAgICAgICAgICAgICAgICAgdCA9IHRoaXMuY3JlYXRlQ2hvaWNlTGlzdEZpZWxkKGZpZWxkKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgImJ1dHRvbiI6CiAgICAgICAgICAgICAgICAgICAgdCA9IHRoaXMuY3JlYXRlQnV0dG9uRmllbGQoZmllbGQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiY2hlY2tidXR0b24iOgogICAgICAgICAgICAgICAgICAgIHQgPSB0aGlzLmNyZWF0ZUNoZWNrQnV0dG9uRmllbGQoZmllbGQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAvL3hmYS5Mb2dnZXIud2FybigidW5rbm93biB1aVR5cGUgZm9yIHRoZSBmaWVsZCAiICsgZmllbGQudWkudHlwZSArICIgPCIKICAgICAgICAgICAgICAgICAgICAvLyAgICArIGZpZWxkLm5hbWUgKyAiPiBDcmVhdGluZyBhIFRleHRGaWVsZCBpbnN0ZWFkIik7CiAgICAgICAgICAgICAgICAgICAgdCA9IHRoaXMuY3JlYXRlVGV4dEZpZWxkKGZpZWxkKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVEcmF3IDogZnVuY3Rpb24oZHJhdykgewogICAgICAgICAgICB2YXIgdCA9IG51bGw7CiAgICAgICAgICAgIHZhciBjaGlsZFR5cGUgPSB0aGlzLmdldE9yRWxzZSh0aGlzLnhmYVV0aWwoKS5nZXRVaU9uZU9mQ2hpbGRUYWcoZHJhdyksICIiKS50b0xvd2VyQ2FzZSgpOwogICAgICAgICAgICBzd2l0Y2ggKGNoaWxkVHlwZSkgewogICAgICAgICAgICAgICAgY2FzZSAidGV4dGVkaXQiOgogICAgICAgICAgICAgICAgICAgIHQgPSB0aGlzLmNyZWF0ZVRleHREcmF3KGRyYXcpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAvL3hmYS5Mb2dnZXIud2FybigidW5rbm93biB1aVR5cGUgZm9yIHRoZSBkcmF3ICIgKyBkcmF3LnVpLnR5cGUgKyAiIDwiCiAgICAgICAgICAgICAgICAgICAgLy8gICAgKyBkcmF3Lm5hbWUgKyAiPiBDcmVhdGluZyBhIFN0YXRpYyBUZXh0IGluc3RlYWQiKTsKICAgICAgICAgICAgICAgICAgICB0ID0gdGhpcy5jcmVhdGVUZXh0RHJhdyhkcmF3KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdDsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVTb21FeHByZXNzaW9uIDogZnVuY3Rpb24oc0V4cHJlc3Npb24sIG5EZWZhdWx0T2NjdXJyZW5jZSwgYklnbm9yZVByZWRpY2F0ZSkgewogICAgICAgICAgICB2YXIgb3B0aW9ucyA9IHsKICAgICAgICAgICAgICAgIGV4cHJlc3Npb24gOiBzRXhwcmVzc2lvbiwKICAgICAgICAgICAgICAgIGRlZmF1bHRPY2N1cnJlbmNlIDogbkRlZmF1bHRPY2N1cnJlbmNlLAogICAgICAgICAgICAgICAgaWdub3JlUHJlZGljYXRlIDogYklnbm9yZVByZWRpY2F0ZQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5TT01FeHByZXNzaW9uKG9wdGlvbnMpOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZVZhbHVlOiBmdW5jdGlvbih2YWx1ZUpzb24pIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LmRvbS5WYWx1ZSh7Impzb25Nb2RlbCIgOiB2YWx1ZUpzb259KTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVOb2RlVmFsdWUgOiBmdW5jdGlvbih2YWx1ZUpzb24pIHsKICAgICAgICAgICAgLy9Ub0RvIDogdGhpcyBpcyBhIHN0b3AgZ3JhcCBtZWFzdXJlIHRpbGwgd2UgZmluZCBhIHdheSB0byBoYW5kbGUgZGVmYXVsdCB2YWx1ZUpzb24KICAgICAgICAgICAgdmFsdWVKc29uID0gdmFsdWVKc29uIHx8IHtfY2xhc3M6ICIiLCByYXdWYWx1ZTogIiJ9OwogICAgICAgICAgICB2YXIgdmFsVHlwZSA9IHZhbHVlSnNvbi5fY2xhc3MudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgc3dpdGNoICh2YWxUeXBlKSB7CiAgICAgICAgICAgICAgICBjYXNlICJ0ZXh0IjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuVGV4dFZhbHVlKHsianNvbk1vZGVsIiA6IHZhbHVlSnNvbn0pOwogICAgICAgICAgICAgICAgY2FzZSAiaW50ZWdlciI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LkludGVnZXJWYWx1ZSh7Impzb25Nb2RlbCIgOiB2YWx1ZUpzb259KTsKICAgICAgICAgICAgICAgIGNhc2UgImRlY2ltYWwiOgogICAgICAgICAgICAgICAgCXJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5EZWNpbWFsVmFsdWUoeyJqc29uTW9kZWwiIDogdmFsdWVKc29ufSk7CiAgICAgICAgICAgICAgICBjYXNlICJmbG9hdCI6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LkZsb2F0VmFsdWUoeyJqc29uTW9kZWwiIDogdmFsdWVKc29ufSk7IAogICAgICAgICAgICAgICAgY2FzZSAiZXhkYXRhIjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuRXhEYXRhVmFsdWUoeyJqc29uTW9kZWwiIDogdmFsdWVKc29ufSk7CiAgICAgICAgICAgICAgICBjYXNlICJkYXRlIjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5zY3JpcHQuRGF0ZVZhbHVlKHsianNvbk1vZGVsIiA6IHZhbHVlSnNvbn0pOwogICAgICAgICAgICAgICAgY2FzZSAiaW1hZ2UiOgogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5JbWFnZVZhbHVlKHsianNvbk1vZGVsIiA6IHZhbHVlSnNvbn0pOwogICAgICAgICAgICAgICAgY2FzZSAic2NyaXB0IjoKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVTY3JpcHQodmFsdWVKc29uKTsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgLy94ZmEuTG9nZ2VyLndhcm4oInVua25vd24gdmFsdWUgdHlwZSAiICsgdmFsdWVKc29uLnR5cGUgKyAiIGZvciBlbGVtZW50IDwiCiAgICAgICAgICAgICAgICAgICAgLy8gICAgKyB0aGlzLm5hbWUgKyAiPiIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnNjcmlwdC5Ob2RlVmFsdWUoeyJqc29uTW9kZWwiIDogdmFsdWVKc29ufSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBjcmVhdGVEYXRhTm9kZTogZnVuY3Rpb24oaWQpIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIuc2NyaXB0LkRhdGFOb2RlKHsianNvbk1vZGVsIiA6IHsiaWQiOmlkfX0pOwogICAgICAgIH0KCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIEFwcCA9IHhmYWxpYi5hY3JvYmF0LkFwcCA9ICB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIEFwcC5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB4ZmFsaWIucnVudGltZS5hcHAgPSB0aGlzOwogICAgICAgICAgICB0aGlzLl92ZXJzaW9uID0gd2luZG93LmZvcm1CcmlkZ2UuZ2V0QnJpZGdlVmVyc2lvbigpOwoKICAgICAgICB9LAoKICAgICAgICBhbGVydDogZnVuY3Rpb24oY01zZykgewogICAgICAgICAgICByZXR1cm4gd2luZG93LmFsZXJ0KGNNc2cpOwogICAgICAgIH0sCgogICAgICAgIGJlZXA6IGZ1bmN0aW9uKG5UeXBlKSB7CgogICAgICAgIH0sCgoKICAgICAgICBleGVjRGlhbG9nOiBmdW5jdGlvbihkaWFsb2cpIHsKCiAgICAgICAgfSwKCiAgICAgICAgbGF1bmNoVVJMOiBmdW5jdGlvbih1cmwsIGJOZXdGcmFtZSkgewogICAgICAgICAgICBpZih1cmwuc2VhcmNoKCJodHRwIikgPT0gLTEpCiAgICAgICAgICAgICAgICB1cmwgPSAiaHR0cDovLyIgKyB1cmwgOwogICAgICAgICAgICBpZihiTmV3RnJhbWUgIT0gdHJ1ZSkgewogICAgICAgICAgICAgICAgd2luZG93Lm9wZW4odXJsKSA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uID0gdXJsOwogICAgICAgIH0sCgogICAgICAgIHNldFRpbWVPdXQ6IGZ1bmN0aW9uKGNFeHByLCBuTWlsbGlzZWNvbmRzKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICB2YXIgZm4gPSBuZXcgRnVuY3Rpb24odGhpcy5fd2l0aGluKGNFeHByKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICAgICAgIGZuLmNhbGwoeGZhbGliLnJ1bnRpbWUuRG9jdW1lbnQpOwogICAgICAgICAgICAgICAgfSwgbk1pbGxpc2Vjb25kcyk7CiAgICAgICAgICAgIH0gY2F0Y2goZXgpIHsKICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGV4KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHNldEludGVydmFsOiBmdW5jdGlvbihjRXhwciwgbk1pbGxpc2Vjb25kcykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdmFyIGZuID0gbmV3IEZ1bmN0aW9uKHRoaXMuX3dpdGhpbihjRXhwcikpOwogICAgICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5zZXRJbnRlcnZhbChmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgICAgICBmbi5jYWxsKHhmYWxpYi5ydW50aW1lLkRvY3VtZW50KTsKICAgICAgICAgICAgICAgIH0sIG5NaWxsaXNlY29uZHMpOwogICAgICAgICAgICB9IGNhdGNoKGV4KSB7CiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhleCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBjbGVhclRpbWVPdXQ6IGZ1bmN0aW9uKG9UaW1lKSB7CiAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQob1RpbWUpOwogICAgICAgIH0sCgogICAgICAgIGNsZWFySW50ZXJ2YWw6IGZ1bmN0aW9uKG9JbnRlcnZhbCkgewogICAgICAgICAgICB3aW5kb3cuY2xlYXJJbnRlcnZhbChvSW50ZXJ2YWwpOwogICAgICAgIH0sCgogICAgICAgIGV2YWw6IGZ1bmN0aW9uKHNjcmlwdCkgewogICAgICAgICAgICB3aW5kb3cuZXZhbCh0aGlzLl93aXRoaW4oc2NyaXB0KSk7CiAgICAgICAgfSwKCiAgICAgICAgX3dpdGhpbjogZnVuY3Rpb24oc2NyaXB0KXsKICAgICAgICAgICAgdmFyIHN0cmluZyAgPSAgICJ0cnkge1xuIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndpdGgoeGZhbGliLnJ1bnRpbWUuRG9jdW1lbnQpIHtcbiIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2l0aCh4ZmFsaWIucnVudGltZSkge1xuIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JpcHQgKyJcbiIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAifVxuIiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIn1cbiIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIn0gY2F0Y2goZXgpIHtcbiIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb25zb2xlLmxvZyhleClcbiIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIn0iOwogICAgICAgICAgICByZXR1cm4gc3RyaW5nOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBBcHAuZGVmaW5lUHJvcHMoewogICAgICAgICJhY3RpdmVEb2NzIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKFtdKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJjYWxjdWxhdGUiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiAodHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAiY29uc3RhbnRzIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKHthbGlnbjp7fX0pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImZvY3VzUmVjdCIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICh0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgICJmb3Jtc1ZlcnNpb24iIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiAodGhpcy5fdmVyc2lvbik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAiZnJvbVBERkNvbnZlcnRlcnMiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoW10pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgImZzIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gKHtpc0Z1bGxTY3JlZW46IGZhbHNlfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAiZnVsbHNjcmVlbiIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIChmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAibGFuZ3VhZ2UiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIGlmKG5hdmlnYXRvci5sYW5ndWFnZS5zdWJzdHIoMCwyKSA9PT0gImVuIikKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCJFTlUiKTsKICAgICAgICAgICAgICAgIHJldHVybiAoIkVOVSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInBsYXRmb3JtIiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICBpZihuYXZpZ2F0b3IuYXBwVmVyc2lvbi5pbmRleE9mKCJXaW4iKSAhPSAtMSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCJXSU4iKTsKICAgICAgICAgICAgICAgIGlmKG5hdmlnYXRvci5hcHBWZXJzaW9uLmluZGV4T2YoIk1hYyIpICE9IC0xKQogICAgICAgICAgICAgICAgICAgIHJldHVybiAoIk1BQyIpOwogICAgICAgICAgICAgICAgcmV0dXJuICgiVU5JWCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInZpZXdlclR5cGUiIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoIkV4Y2hhbmdlLVBybyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInZpZXdlclZhcmlhdGlvbiIgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuICgiRnVsbCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgInZpZXdlclZlcnNpb24iIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgICAgIHJldHVybiAodGhpcy5fdmVyc2lvbik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KQoKfSkoXywgeGZhbGliKTsKCihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIENvbnNvbGUgPSB4ZmFsaWIuYWNyb2JhdC5Db25zb2xlID0gIHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbihiUmVnaXN0ZXIpIHsKICAgICAgICAgICAgQ29uc29sZS5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICBpZihiUmVnaXN0ZXIpCiAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS5jb25zb2xlID0gdGhpczsKICAgICAgICB9LAoKICAgICAgICBwcmludGxuOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgLy9hZGQgdGhpcyBtZXRob2QgdG8gaW5zZXJ0IGNvbnNvbGUgd2hlcmUgJ2NvbnNvbGUnIGlzIG5vdCBzdXBwb3J0ZWQKICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CgooZnVuY3Rpb24oXywgeGZhbGliKXsKICAgIHZhciBBY3JvYmF0ID0geGZhbGliLmFjcm9iYXQuQWNyb2JhdCA9ICB4ZmFsaWIudXQuQ2xhc3MuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIEFjcm9iYXQuX3N1cGVyLmluaXRpYWxpemUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgLy9pbml0aWFsaXplIEFwcCBvYmplY3QKICAgICAgICAgICAgbmV3IHhmYWxpYi5hY3JvYmF0LkFwcCgpOwogICAgICAgICAgICAvL2luc2VydCBwcmludGxuIGluc2lkZSBjb25zb2xlIG9iamVjdAogICAgICAgICAgICBpZih0eXBlb2YoY29uc29sZSkgIT0gInVuZGVmaW5lZCIpIHsKICAgICAgICAgICAgICAgIGlmKGNvbnNvbGUubG9nKQogICAgICAgICAgICAgICAgICAgIGNvbnNvbGUucHJpbnRsbiA9IGNvbnNvbGUubG9nOwogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy9yZWdpc3RlciBlbXB0eSBtZXRob2QKICAgICAgICAgICAgICAgICAgICB2YXIgY29uID0gbmV3IHhmYWxpYi5hY3JvYmF0LkNvbnNvbGUoKTsKICAgICAgICAgICAgICAgICAgICBjb25zb2xlLnByaW50bG4gPSBjb24ucHJpbnRsbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIG5ldyB4ZmFsaWIuYWNyb2JhdC5Db25zb2xlKHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwoKLyoqCiAqIENyZWF0ZWQgd2l0aCBJbnRlbGxpSiBJREVBLgogKiBVc2VyOiB2ZHVhCiAqIERhdGU6IDIxLzUvMTMKICogVGltZTogNTo1NiBQTQogKiBUbyBjaGFuZ2UgdGhpcyB0ZW1wbGF0ZSB1c2UgRmlsZSB8IFNldHRpbmdzIHwgRmlsZSBUZW1wbGF0ZXMuCgogLyoqCiAqIEBwYWNrYWdlIHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudAogKiBAaW1wb3J0IHhmYWxpYi5zY3JpcHQuT2JqZWN0CiAqIEBmaWxlT3ZlcnZpZXcgVGhlIGZpbGUgY3JlYXRlcyB0aGUgWGZhTW9kZWxFdmVudCBDbGFzcyByZXF1aXJlZCBmb3IgWEZBIGxpYnJhcnkKICogQHZlcnNpb24gMC4wLjEKICovCihmdW5jdGlvbihfLHhmYWxpYikgewoKICAgIHZhciBGaWVsZCA9IHhmYWxpYi5hY3JvYmF0LkZpZWxkID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBGaWVsZC5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLl94ZmFGaWVsZCA9IHhmYWxpYi5zY3JpcHQuWGZhLkluc3RhbmNlLnJlc29sdmVOb2RlKCJ4ZmEuZm9ybS4iK3RoaXMuanNvbk1vZGVsLnNvbUV4cHJlc3Npb24pOwogICAgICAgIH0sCgogICAgICAgIHNpZ25hdHVyZUluZm8gOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdGhyb3cge21lc3NhZ2U6InNpZ25hdHVyZUluZm8gaXMgbm90IHN1cHBvcnRlZCJ9CiAgICAgICAgfSwKCiAgICAgICAgc2V0Rm9jdXM6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB4ZmFsaWIuc2NyaXB0LlhmYS5JbnN0YW5jZS5ob3N0LnNldEZvY3VzKHRoaXMuanNvbk1vZGVsLnNvbUV4cHJlc3Npb24pOwogICAgICAgIH0KICAgIH0pOwoKICAgIEZpZWxkLmRlZmluZVByb3BzKHsKCiAgICB9KQp9KShfLHhmYWxpYik7Ci8qKgogKiBAcGFja2FnZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQKICogQGltcG9ydCB4ZmFsaWIuc2NyaXB0Lk9iamVjdAogKiBAZmlsZU92ZXJ2aWV3IFRoZSBmaWxlIGNyZWF0ZXMgdGhlIFhmYU1vZGVsRXZlbnQgQ2xhc3MgcmVxdWlyZWQgZm9yIFhGQSBsaWJyYXJ5CiAqIEB2ZXJzaW9uIDAuMC4xCiAqLwooZnVuY3Rpb24oXyx4ZmFsaWIpIHsKCiAgICB2YXIgRG9jID0geGZhbGliLmFjcm9iYXQuRG9jID0geGZhbGliLnV0LkNsYXNzLmV4dGVuZCh7CgogICAgICAgIGdldFVSTDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB3aW5kb3cubG9jYXRpb24uaHJlZjsKICAgICAgICB9LAoKICAgICAgICByZXNldEZvcm06IGZ1bmN0aW9uKGZpZWxkQXJyYXkpIHsKICAgICAgICAgICAgaWYoIShmaWVsZEFycmF5IGluc3RhbmNlb2YgQXJyYXkpKSB7CiAgICAgICAgICAgICAgICBmaWVsZEFycmF5ID0gW2ZpZWxkQXJyYXldOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMueGZhLmhvc3QucmVzZXREYXRhLmFwcGx5KHRoaXMueGZhLmhvc3QsZmllbGRBcnJheSk7CiAgICAgICAgfSwKCiAgICAgICAgc3VibWl0Rm9ybTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHRoaXMueGZhLkxvZ2dlci5lcnJvcigieGZhIix4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMDYiXSxbInN1Ym1pdEZvcm0iXSk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0RmllbGQ6IGZ1bmN0aW9uKHNvbSkgewogICAgICAgICAgICByZXR1cm4gbmV3IHhmYWxpYi5hY3JvYmF0LkZpZWxkKHsianNvbk1vZGVsIiA6IHsic29tRXhwcmVzc2lvbiI6IHNvbX19KTsKICAgICAgICB9LAoKICAgICAgICBpbXBvcnREYXRhT2JqZWN0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdGhyb3cge21lc3NhZ2U6ImltcG9ydERhdGFPYmplY3QgaXMgbm90IHN1cHBvcnRlZCJ9CiAgICAgICAgfQoKICAgIH0pOwoKICAgIERvYy5kZWZpbmVQcm9wcyh7CiAgICAgICAgInhmYSIgOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICByZXR1cm4geGZhbGliLnNjcmlwdC5YZmEuSW5zdGFuY2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSkKCiAgICB4ZmFsaWIucnVudGltZS5Eb2N1bWVudCA9IG5ldyB4ZmFsaWIuYWNyb2JhdC5Eb2Moe2pzb25Nb2RlbDp7fX0pOwoKfSkoXyx4ZmFsaWIpOwovKioKICogQHBhY2thZ2UgeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50CiAqIEBpbXBvcnQgeGZhbGliLnNjcmlwdC5PYmplY3QKICogQGZpbGVPdmVydmlldyBUaGUgZmlsZSBjcmVhdGVzIHRoZSBYZmFNb2RlbEV2ZW50IENsYXNzIHJlcXVpcmVkIGZvciBYRkEgbGlicmFyeQogKiBAdmVyc2lvbiAwLjAuMQogKi8KKGZ1bmN0aW9uKF8seGZhbGliKSB7CgogICAgdmFyIEFjcm9FdmVudCA9IHhmYWxpYi5hY3JvYmF0LkFjcm9FdmVudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiAiYWNyb0V2ZW50IiwKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLmpzb25Nb2RlbC50YXJnZXQgPSB4ZmFsaWIucnVudGltZS5Eb2N1bWVudDsKICAgICAgICB9CiAgICB9KTsKCiAgICBBY3JvRXZlbnQuY2xvbmVFdmVudCA9IGZ1bmN0aW9uKHhmYU1vZGVsRXZlbnQpIHsKICAgICAgICB2YXIgY29weSA9IHhmYU1vZGVsRXZlbnQuY29weU9iamVjdCh4ZmFNb2RlbEV2ZW50Lmpzb25Nb2RlbCwge30seyJleGNlcHRpb25zIjpbInRhcmdldCJdfSk7CiAgICAgICAgcmV0dXJuIG5ldyBBY3JvRXZlbnQoeyJqc29uTW9kZWwiIDogY29weX0pOwogICAgfTsKCn0pKF8seGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBBcHBlYXJhbmNlRmlsdGVyID0geGZhbGliLnNjcmlwdC5kb20uQXBwZWFyYW5jZUZpbHRlciA9IHhmYWxpYi5zY3JpcHQuR2VuZXJpY1RleHQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiYXBwZWFyYW5jZUZpbHRlciIKICAgIH0pOwoKICAgIEFwcGVhcmFuY2VGaWx0ZXIuZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEFzc2lzdCA9IHhmYWxpYi5zY3JpcHQuZG9tLkFzc2lzdCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJhc3Npc3QiCiAgICB9KTsKCiAgICBBc3Npc3QuZGVmaW5lUHJvcHMoewogICAgICAgIHJvbGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyb2xlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicm9sZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzcGVhazp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJzcGVhayIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzcGVhayIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0b29sVGlwOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInRvb2xUaXAiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAidG9vbFRpcCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJhcmNvZGUgPSB4ZmFsaWIuc2NyaXB0LmRvbS5CYXJjb2RlID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImJhcmNvZGUiCiAgICB9KTsKCiAgICBCYXJjb2RlLmRlZmluZVByb3BzKHsKICAgICAgICBjaGFyRW5jb2Rpbmc6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJjaGFyRW5jb2RpbmciKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJjaGFyRW5jb2RpbmciKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY2hlY2tzdW06ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJjaGVja3N1bSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImNoZWNrc3VtIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGRhdGFDb2x1bW5Db3VudDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImRhdGFDb2x1bW5Db3VudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImRhdGFDb2x1bW5Db3VudCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBkYXRhTGVuZ3RoOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZGF0YUxlbmd0aCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImRhdGFMZW5ndGgiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZGF0YVByZXA6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJkYXRhUHJlcCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImRhdGFQcmVwIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGRhdGFSb3dDb3VudDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImRhdGFSb3dDb3VudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImRhdGFSb3dDb3VudCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBlbmRDaGFyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZW5kQ2hhciIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImVuZENoYXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXJyb3JDb3JyZWN0aW9uTGV2ZWw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJlcnJvckNvcnJlY3Rpb25MZXZlbCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImVycm9yQ29ycmVjdGlvbkxldmVsIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG1vZHVsZUhlaWdodDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm1vZHVsZUhlaWdodCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm1vZHVsZUhlaWdodCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtb2R1bGVXaWR0aDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm1vZHVsZVdpZHRoIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibW9kdWxlV2lkdGgiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcHJpbnRDaGVja0RpZ2l0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicHJpbnRDaGVja0RpZ2l0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicHJpbnRDaGVja0RpZ2l0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJvd0NvbHVtblJhdGlvOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicm93Q29sdW1uUmF0aW8iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJyb3dDb2x1bW5SYXRpbyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzdGFydENoYXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJzdGFydENoYXIiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJzdGFydENoYXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdGV4dExvY2F0aW9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidGV4dExvY2F0aW9uIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidGV4dExvY2F0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRydW5jYXRlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidHJ1bmNhdGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0cnVuY2F0ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0eXBlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidHlwZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInR5cGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdXBzTW9kZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInVwc01vZGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ1cHNNb2RlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHdpZGVOYXJyb3dSYXRpbzp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIndpZGVOYXJyb3dSYXRpbyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIndpZGVOYXJyb3dSYXRpbyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBlbmNyeXB0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImVuY3J5cHQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZW5jcnlwdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJpbmQgPSB4ZmFsaWIuc2NyaXB0LmRvbS5CaW5kID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImJpbmQiCiAgICB9KTsKCiAgICBCaW5kLmRlZmluZVByb3BzKHsKICAgICAgICBtYXRjaDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm1hdGNoIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibWF0Y2giKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVmOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicmVmIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicmVmIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHBpY3R1cmU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgicGljdHVyZSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJwaWN0dXJlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgQmluZEl0ZW1zID0geGZhbGliLnNjcmlwdC5kb20uQmluZEl0ZW1zID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJiaW5kSXRlbXMiCiAgICB9KTsKCiAgICBCaW5kSXRlbXMuZGVmaW5lUHJvcHMoewogICAgICAgIGNvbm5lY3Rpb246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJjb25uZWN0aW9uIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiY29ubmVjdGlvbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBsYWJlbFJlZjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImxhYmVsUmVmIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGFiZWxSZWYiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVmOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicmVmIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicmVmIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHZhbHVlUmVmOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidmFsdWVSZWYiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ2YWx1ZVJlZiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJvb2tlbmQgPSB4ZmFsaWIuc2NyaXB0LmRvbS5Cb29rZW5kID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJib29rZW5kIgogICAgfSk7CgogICAgQm9va2VuZC5kZWZpbmVQcm9wcyh7CiAgICAgICAgbGVhZGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGVhZGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGVhZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRyYWlsZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0cmFpbGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHJhaWxlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJvcmRlciA9IHhmYWxpYi5zY3JpcHQuZG9tLkJvcmRlciA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJib3JkZXIiLAoKICAgICAgICBoYW5kbGVFdmVudDogZnVuY3Rpb24gKGV2bnQpIHsKICAgICAgICAgICAgaWYoZXZudC5fcHJvcGVydHkgPT0gJ2VkZ2UuY29sb3IudmFsdWUnKSB7CiAgICAgICAgICAgICAgICAvL0lmIHRoZSBjb2xvciBpcyBiZWluZyBzZXQgZm9yIGZpcnN0IGJvcmRlciBlZGdlLCBhbmQgdGhlIGNvcm5lciBhcmUgcm91bmRlZCAtIHNldCBmb3IgYWxsIHRoZSBlZGdlcwogICAgICAgICAgICAgICAgLy9yZWFzb246IEluIGNhc2Ugb2Ygcm91bmRlZCBjb3JuZXIsIHdlIGRpdmlkZSB0aGUgc2luZ2xlIGVkZ2UgaW50byA0IGVkZ2VzLCBhbmQgdGh1cyB3aGVuIHRyeWluZyB0byBzZXQKICAgICAgICAgICAgICAgIC8vdGhlIGNvbG9yIGZvciBhbGwgb2YgdGhlbSB0b2dldGhlciwgb25seSBmaXJzdCBpcyBzZXQgLSBOUFItMTU0NDQKICAgICAgICAgICAgICAgIHZhciBpc0ZpcnN0SW5kZXggPSBldm50LnRhcmdldC5wYXJlbnQubW5DbGFzc0luZGV4ID09IDAsCiAgICAgICAgICAgICAgICAgICAgaXNSb3VuZGVkQm9yZGVyID0gISEocGFyc2VJbnQodGhpcy5jb3JuZXIucmFkaXVzKSk7CiAgICAgICAgICAgICAgICBpZihpc0ZpcnN0SW5kZXggJiYgaXNSb3VuZGVkQm9yZGVyKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgZWRnZTsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZWRnZSA9IHRoaXMuZ2V0RWxlbWVudCgnZWRnZScsIGluZGV4LCB0cnVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvL3NldCB0aGUgdmFsdWUgaW4gY2FzZSBhIGRpZmZlcmVudCBjb2xvciBoYXMgbm90IGJlZW4gc2V0IGZvciBhIGRpZmZlcmVudCBlZGdlIGV4cGxpY2l0bHkKICAgICAgICAgICAgICAgICAgICAgICAgZWRnZS5jb2xvci5zZXRBdHRyaWJ1dGUoZXZudC50YXJnZXQudmFsdWUsJ3ZhbHVlJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIEJvcmRlci5fc3VwZXIuaGFuZGxlRXZlbnQuY2FsbCh0aGlzLCBldm50KTsKICAgICAgICB9CiAgICB9KTsKCiAgICBCb3JkZXIuZGVmaW5lUHJvcHMoewogICAgICAgICJicmVhayI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJicmVhayIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImJyZWFrIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGhhbmQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJoYW5kIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaGFuZCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBwcmVzZW5jZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInByZXNlbmNlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicHJlc2VuY2UiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVsZXZhbnQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyZWxldmFudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJlbGV2YW50Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGNvcm5lcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjb3JuZXIiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY29ybmVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGVkZ2U6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZWRnZSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJlZGdlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGZpbGw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZmlsbCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJmaWxsIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG1hcmdpbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJtYXJnaW4iLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWFyZ2luIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgQnJlYWsgPSB4ZmFsaWIuc2NyaXB0LmRvbS5CcmVhayA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJicmVhayIKICAgIH0pOwoKICAgIEJyZWFrLmRlZmluZVByb3BzKHsKICAgICAgICBhZnRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImFmdGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiYWZ0ZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgYWZ0ZXJUYXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJhZnRlclRhcmdldCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImFmdGVyVGFyZ2V0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGJlZm9yZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImJlZm9yZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImJlZm9yZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBiZWZvcmVUYXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJiZWZvcmVUYXJnZXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJiZWZvcmVUYXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgYm9va2VuZExlYWRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImJvb2tlbmRMZWFkZXIiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJib29rZW5kTGVhZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGJvb2tlbmRUcmFpbGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiYm9va2VuZFRyYWlsZXIiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJib29rZW5kVHJhaWxlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBvdmVyZmxvd0xlYWRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm92ZXJmbG93TGVhZGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAib3ZlcmZsb3dMZWFkZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgb3ZlcmZsb3dUYXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJvdmVyZmxvd1RhcmdldCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm92ZXJmbG93VGFyZ2V0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG92ZXJmbG93VHJhaWxlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm92ZXJmbG93VHJhaWxlciIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm92ZXJmbG93VHJhaWxlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzdGFydE5ldzp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInN0YXJ0TmV3Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic3RhcnROZXciKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBCcmVha0FmdGVyID0geGZhbGliLnNjcmlwdC5kb20uQnJlYWtBZnRlciA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJicmVha0FmdGVyIgogICAgfSk7CgogICAgQnJlYWtBZnRlci5kZWZpbmVQcm9wcyh7CiAgICAgICAgbGVhZGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGVhZGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGVhZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHN0YXJ0TmV3OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic3RhcnROZXciKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJzdGFydE5ldyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0YXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0YXJnZXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdGFyZ2V0VHlwZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRhcmdldFR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXRUeXBlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRyYWlsZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0cmFpbGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHJhaWxlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzY3JpcHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic2NyaXB0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInNjcmlwdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJyZWFrQmVmb3JlID0geGZhbGliLnNjcmlwdC5kb20uQnJlYWtCZWZvcmUgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiYnJlYWtCZWZvcmUiCiAgICB9KTsKCiAgICBCcmVha0JlZm9yZS5kZWZpbmVQcm9wcyh7CiAgICAgICAgbGVhZGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGVhZGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGVhZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHN0YXJ0TmV3OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic3RhcnROZXciKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJzdGFydE5ldyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0YXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0YXJnZXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdGFyZ2V0VHlwZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRhcmdldFR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXRUeXBlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRyYWlsZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0cmFpbGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHJhaWxlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzY3JpcHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic2NyaXB0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInNjcmlwdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEJ1dHRvbiA9IHhmYWxpYi5zY3JpcHQuZG9tLkJ1dHRvbiA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJidXR0b24iCiAgICB9KTsKCiAgICBCdXR0b24uZGVmaW5lUHJvcHMoewogICAgICAgIGhpZ2hsaWdodDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImhpZ2hsaWdodCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImhpZ2hsaWdodCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIENhbGN1bGF0ZSA9IHhmYWxpYi5zY3JpcHQuZG9tLkNhbGN1bGF0ZSA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJjYWxjdWxhdGUiCiAgICB9KTsKCiAgICBDYWxjdWxhdGUuZGVmaW5lUHJvcHMoewogICAgICAgIG92ZXJyaWRlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgib3ZlcnJpZGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJvdmVycmlkZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtZXNzYWdlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoIm1lc3NhZ2UiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWVzc2FnZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzY3JpcHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic2NyaXB0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInNjcmlwdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIENhcHRpb24gPSB4ZmFsaWIuc2NyaXB0LmRvbS5DYXB0aW9uID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImNhcHRpb24iCiAgICB9KTsKCiAgICBDYXB0aW9uLmRlZmluZVByb3BzKHsKICAgICAgICBwbGFjZW1lbnQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJwbGFjZW1lbnQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwbGFjZW1lbnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcHJlc2VuY2U6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJwcmVzZW5jZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInByZXNlbmNlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlc2VydmU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyZXNlcnZlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicmVzZXJ2ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBmb250OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImZvbnQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZm9udCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYXJnaW46ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFyZ2luIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgIm1hcmdpbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBwYXJhOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInBhcmEiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAicGFyYSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB2YWx1ZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJ2YWx1ZSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJ2YWx1ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIENlcnRpZmljYXRlID0geGZhbGliLnNjcmlwdC5kb20uQ2VydGlmaWNhdGUgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImNlcnRpZmljYXRlIgogICAgfSk7CgogICAgQ2VydGlmaWNhdGUuZGVmaW5lUHJvcHMoewogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIENlcnRpZmljYXRlcyA9IHhmYWxpYi5zY3JpcHQuZG9tLkNlcnRpZmljYXRlcyA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJjZXJ0aWZpY2F0ZXMiCiAgICB9KTsKCiAgICBDZXJ0aWZpY2F0ZXMuZGVmaW5lUHJvcHMoewogICAgICAgIGNyZWRlbnRpYWxTZXJ2ZXJQb2xpY3k6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJjcmVkZW50aWFsU2VydmVyUG9saWN5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiY3JlZGVudGlhbFNlcnZlclBvbGljeSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB1cmw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ1cmwiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ1cmwiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdXJsUG9saWN5OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidXJsUG9saWN5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidXJsUG9saWN5Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGVuY3J5cHRpb246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZW5jcnlwdGlvbiIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJlbmNyeXB0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGlzc3VlcnM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiaXNzdWVycyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJpc3N1ZXJzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGtleVVzYWdlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImtleVVzYWdlIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImtleVVzYWdlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG9pZHM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgib2lkcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJvaWRzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHNpZ25pbmc6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic2lnbmluZyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzaWduaW5nIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHN1YmplY3RETnM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic3ViamVjdEROcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzdWJqZWN0RE5zIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgQ2hlY2tCdXR0b24gPSB4ZmFsaWIuc2NyaXB0LmRvbS5DaGVja0J1dHRvbiA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJjaGVja0J1dHRvbiIKICAgIH0pOwoKICAgIENoZWNrQnV0dG9uLmRlZmluZVByb3BzKHsKICAgICAgICBhbGxvd05ldXRyYWw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJhbGxvd05ldXRyYWwiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJhbGxvd05ldXRyYWwiKTsKICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCx0aGlzLCJhbGxvd05ldXRyYWwiLHZhbHVlLCBudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsZXZudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG1hcms6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJtYXJrIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibWFyayIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzaGFwZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInNoYXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic2hhcGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgc2l6ZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInNpemUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJzaXplIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGJvcmRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJib3JkZXIiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiYm9yZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG1hcmdpbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJtYXJnaW4iLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWFyZ2luIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgQ2hvaWNlTGlzdCA9IHhmYWxpYi5zY3JpcHQuZG9tLkNob2ljZUxpc3QgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiY2hvaWNlTGlzdCIKICAgIH0pOwoKICAgIENob2ljZUxpc3QuZGVmaW5lUHJvcHMoewogICAgICAgIGNvbW1pdE9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiY29tbWl0T24iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJjb21taXRPbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBvcGVuOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgib3BlbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm9wZW4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdGV4dEVudHJ5OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidGV4dEVudHJ5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidGV4dEVudHJ5Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGJvcmRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJib3JkZXIiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiYm9yZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG1hcmdpbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJtYXJnaW4iLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWFyZ2luIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgQ29sb3IgPSB4ZmFsaWIuc2NyaXB0LmRvbS5Db2xvciA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJjb2xvciIKICAgIH0pOwoKICAgIENvbG9yLmRlZmluZVByb3BzKHsKICAgICAgICBjU3BhY2U6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJjU3BhY2UiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJjU3BhY2UiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdmFsdWU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ2YWx1ZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInZhbHVlIik7CiAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQsCiAgICAgICAgICAgICAgICAgICAgdGhpcywiY29sb3IudmFsdWUiLHZhbHVlLCBudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsZXZudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgQ29tYiA9IHhmYWxpYi5zY3JpcHQuZG9tLkNvbWIgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImNvbWIiCiAgICB9KTsKCiAgICBDb21iLmRlZmluZVByb3BzKHsKICAgICAgICBudW1iZXJPZkNlbGxzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibnVtYmVyT2ZDZWxscyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm51bWJlck9mQ2VsbHMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBDb25uZWN0ID0geGZhbGliLnNjcmlwdC5kb20uQ29ubmVjdCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJjb25uZWN0IgogICAgfSk7CgogICAgQ29ubmVjdC5kZWZpbmVQcm9wcyh7CiAgICAgICAgY29ubmVjdGlvbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImNvbm5lY3Rpb24iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJjb25uZWN0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlZjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJlZiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJlZiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB1c2FnZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInVzYWdlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidXNhZ2UiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcGljdHVyZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJwaWN0dXJlIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInBpY3R1cmUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBDb3JuZXIgPSB4ZmFsaWIuc2NyaXB0LmRvbS5Db3JuZXIgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiY29ybmVyIgogICAgfSk7CgogICAgQ29ybmVyLmRlZmluZVByb3BzKHsKICAgICAgICBpbnZlcnRlZDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImludmVydGVkIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaW52ZXJ0ZWQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgam9pbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImpvaW4iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJqb2luIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHByZXNlbmNlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicHJlc2VuY2UiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwcmVzZW5jZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICByYWRpdXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyYWRpdXMiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJyYWRpdXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgc3Ryb2tlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic3Ryb2tlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic3Ryb2tlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRoaWNrbmVzczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRoaWNrbmVzcyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInRoaWNrbmVzcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb2xvcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjb2xvciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJjb2xvciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIERhdGVUaW1lRWRpdCA9IHhmYWxpYi5zY3JpcHQuZG9tLkRhdGVUaW1lRWRpdCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJkYXRlVGltZUVkaXQiCiAgICB9KTsKCiAgICBEYXRlVGltZUVkaXQuZGVmaW5lUHJvcHMoewogICAgICAgIGhTY3JvbGxQb2xpY3k6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJoU2Nyb2xsUG9saWN5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaFNjcm9sbFBvbGljeSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBwaWNrZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJwaWNrZXIiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwaWNrZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgYm9yZGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImJvcmRlciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJib3JkZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY29tYjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjb21iIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImNvbWIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbWFyZ2luOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoIm1hcmdpbiIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJtYXJnaW4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBEZWZhdWx0VWkgPSB4ZmFsaWIuc2NyaXB0LmRvbS5EZWZhdWx0VWkgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiZGVmYXVsdFVpIgogICAgfSk7CgogICAgRGVmYXVsdFVpLmRlZmluZVByb3BzKHsKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24oXyx4ZmFsaWIpewogICAgdmFyIERlc2MgPSB4ZmFsaWIuc2NyaXB0LmRvbS5EZXNjID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ICJkZXNjIgogICAgfSk7Cgp9KShfLHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgRGlnZXN0TWV0aG9kID0geGZhbGliLnNjcmlwdC5kb20uRGlnZXN0TWV0aG9kID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJkaWdlc3RNZXRob2QiCiAgICB9KTsKCiAgICBEaWdlc3RNZXRob2QuZGVmaW5lUHJvcHMoewogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIERpZ2VzdE1ldGhvZHMgPSB4ZmFsaWIuc2NyaXB0LmRvbS5EaWdlc3RNZXRob2RzID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImRpZ2VzdE1ldGhvZHMiCiAgICB9KTsKCiAgICBEaWdlc3RNZXRob2RzLmRlZmluZVByb3BzKHsKICAgICAgICAidHlwZSI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBFZGdlID0geGZhbGliLnNjcmlwdC5kb20uRWRnZSA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJlZGdlIgogICAgfSk7CgogICAgRWRnZS5kZWZpbmVQcm9wcyh7CiAgICAgICAgY2FwOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiY2FwIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiY2FwIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHByZXNlbmNlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicHJlc2VuY2UiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwcmVzZW5jZSIpOwogICAgICAgICAgICAgICAgdmFyIGV2bnQgPSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkRPTV9DSEFOR0VELAogICAgICAgICAgICAgICAgICAgIHRoaXMsImVkZ2UucHJlc2VuY2UiLHZhbHVlLCBudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsZXZudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHN0cm9rZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInN0cm9rZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInN0cm9rZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0aGlja25lc3M6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0aGlja25lc3MiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0aGlja25lc3MiKTsKICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICB0aGlzLCJlZGdlLnRoaWNrbmVzcyIsdmFsdWUsIG51bGwpOwogICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY29sb3I6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiY29sb3IiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY29sb3IiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBFbmNvZGluZyA9IHhmYWxpYi5zY3JpcHQuZG9tLkVuY29kaW5nID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJlbmNvZGluZyIKICAgIH0pOwoKICAgIEVuY29kaW5nLmRlZmluZVByb3BzKHsKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBFbmNvZGluZ3MgPSB4ZmFsaWIuc2NyaXB0LmRvbS5FbmNvZGluZ3MgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiZW5jb2RpbmdzIgogICAgfSk7CgogICAgRW5jb2RpbmdzLmRlZmluZVByb3BzKHsKICAgICAgICAidHlwZSI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBFbmNyeXB0ID0geGZhbGliLnNjcmlwdC5kb20uRW5jcnlwdCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJlbmNyeXB0IgogICAgfSk7CgogICAgRW5jcnlwdC5kZWZpbmVQcm9wcyh7CiAgICAgICAgY2VydGlmaWNhdGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiY2VydGlmaWNhdGUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY2VydGlmaWNhdGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBFbmNyeXB0RGF0YSA9IHhmYWxpYi5zY3JpcHQuZG9tLkVuY3J5cHREYXRhID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImVuY3J5cHREYXRhIgogICAgfSk7CgogICAgRW5jcnlwdERhdGEuZGVmaW5lUHJvcHMoewogICAgICAgIG9wZXJhdGlvbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm9wZXJhdGlvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm9wZXJhdGlvbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0YXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0YXJnZXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZmlsdGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImZpbHRlciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJmaWx0ZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbWFuaWZlc3Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFuaWZlc3QiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWFuaWZlc3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBFbmNyeXB0aW9uID0geGZhbGliLnNjcmlwdC5kb20uRW5jcnlwdGlvbiA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJlbmNyeXB0aW9uIgogICAgfSk7CgogICAgRW5jcnlwdGlvbi5kZWZpbmVQcm9wcyh7CiAgICAgICAgdHlwZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0eXBlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEVuY3J5cHRpb25NZXRob2QgPSB4ZmFsaWIuc2NyaXB0LmRvbS5FbmNyeXB0aW9uTWV0aG9kID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJlbmNyeXB0aW9uTWV0aG9kIgogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEVuY3J5cHRpb25NZXRob2RzID0geGZhbGliLnNjcmlwdC5kb20uRW5jcnlwdGlvbk1ldGhvZHMgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiZW5jcnlwdGlvbk1ldGhvZHMiCiAgICB9KTsKCiAgICBFbmNyeXB0aW9uTWV0aG9kcy5kZWZpbmVQcm9wcyh7CiAgICAgICAgInR5cGUiOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidHlwZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInR5cGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgRXZlbnQgPSB4ZmFsaWIuc2NyaXB0LmRvbS5FdmVudCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJldmVudCIKICAgIH0pOwoKICAgIEV2ZW50LmRlZmluZVByb3BzKHsKICAgICAgICBhY3Rpdml0eTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImFjdGl2aXR5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiYWN0aXZpdHkiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbGlzdGVuOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGlzdGVuIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGlzdGVuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlZjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJlZiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJlZiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBlbmNyeXB0RGF0YTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJlbmNyeXB0RGF0YSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJlbmNyeXB0RGF0YSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleGVjdXRlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4ZWN1dGUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXhlY3V0ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzY3JpcHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic2NyaXB0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInNjcmlwdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzaWduRGF0YTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJzaWduRGF0YSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzaWduRGF0YSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzdWJtaXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic3VibWl0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInN1Ym1pdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEV4ZWN1dGUgPSB4ZmFsaWIuc2NyaXB0LmRvbS5FeGVjdXRlID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJleGVjdXRlIgogICAgfSk7CgogICAgRXhlY3V0ZS5kZWZpbmVQcm9wcyh7CiAgICAgICAgY29ubmVjdGlvbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImNvbm5lY3Rpb24iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJjb25uZWN0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4ZWN1dGVUeXBlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZXhlY3V0ZVR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJleGVjdXRlVHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBydW5BdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJ1bkF0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicnVuQXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uKF8seGZhbGliKXsKICAgIHZhciBFeHRyYXMgPSB4ZmFsaWIuc2NyaXB0LmRvbS5FeHRyYXMgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZTogImV4dHJhcyIKICAgIH0pOwoKfSkoXyx4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEZpbGwgPSB4ZmFsaWIuc2NyaXB0LmRvbS5GaWxsID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImZpbGwiCiAgICB9KTsKCiAgICBGaWxsLmRlZmluZVByb3BzKHsKICAgICAgICBwcmVzZW5jZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInByZXNlbmNlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicHJlc2VuY2UiKTsKICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICB0aGlzLCJmaWxsLnByZXNlbmNlIix2YWx1ZSwgbnVsbCk7CiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb2xvcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjb2xvciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJjb2xvciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBsaW5lYXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibGluZWFyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImxpbmVhciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBwYXR0ZXJuOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInBhdHRlcm4iLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAicGF0dGVybiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICByYWRpYWw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgicmFkaWFsIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInJhZGlhbCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzb2xpZDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJzb2xpZCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzb2xpZCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzdGlwcGxlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInN0aXBwbGUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAic3RpcHBsZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEZpbHRlciA9IHhmYWxpYi5zY3JpcHQuZG9tLkZpbHRlciA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJmaWx0ZXIiCiAgICB9KTsKCiAgICBGaWx0ZXIuZGVmaW5lUHJvcHMoewogICAgICAgIGFkZFJldm9jYXRpb25JbmZvOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiYWRkUmV2b2NhdGlvbkluZm8iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJhZGRSZXZvY2F0aW9uSW5mbyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB2ZXJzaW9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidmVyc2lvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInZlcnNpb24iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgYXBwZWFyYW5jZUZpbHRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJhcHBlYXJhbmNlRmlsdGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImFwcGVhcmFuY2VGaWx0ZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY2VydGlmaWNhdGVzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImNlcnRpZmljYXRlcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJjZXJ0aWZpY2F0ZXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZGlnZXN0TWV0aG9kczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJkaWdlc3RNZXRob2RzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImRpZ2VzdE1ldGhvZHMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZW5jb2RpbmdzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImVuY29kaW5ncyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJlbmNvZGluZ3MiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZW5jcnlwdGlvbk1ldGhvZHM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZW5jcnlwdGlvbk1ldGhvZHMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZW5jcnlwdGlvbk1ldGhvZHMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgaGFuZGxlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJoYW5kbGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImhhbmRsZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbG9ja0RvY3VtZW50OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImxvY2tEb2N1bWVudCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJsb2NrRG9jdW1lbnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbWRwOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoIm1kcCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJtZHAiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVhc29uczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJyZWFzb25zIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInJlYXNvbnMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdGltZVN0YW1wOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInRpbWVTdGFtcCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJ0aW1lU3RhbXAiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBGb250ID0geGZhbGliLnNjcmlwdC5kb20uRm9udCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJmb250IgogICAgfSk7CgogICAgRm9udC5kZWZpbmVQcm9wcyh7CiAgICAgICAgYmFzZWxpbmVTaGlmdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImJhc2VsaW5lU2hpZnQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJiYXNlbGluZVNoaWZ0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGZvbnRIb3Jpem9udGFsU2NhbGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJmb250SG9yaXpvbnRhbFNjYWxlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZm9udEhvcml6b250YWxTY2FsZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBmb250VmVydGljYWxTY2FsZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImZvbnRWZXJ0aWNhbFNjYWxlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZm9udFZlcnRpY2FsU2NhbGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAga2VybmluZ01vZGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJrZXJuaW5nTW9kZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImtlcm5pbmdNb2RlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGxldHRlclNwYWNpbmc6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJsZXR0ZXJTcGFjaW5nIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGV0dGVyU3BhY2luZyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBsaW5lVGhyb3VnaDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImxpbmVUaHJvdWdoIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGluZVRocm91Z2giKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbGluZVRocm91Z2hQZXJpb2Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJsaW5lVGhyb3VnaFBlcmlvZCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImxpbmVUaHJvdWdoUGVyaW9kIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG92ZXJsaW5lOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgib3ZlcmxpbmUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJvdmVybGluZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBvdmVybGluZVBlcmlvZDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm92ZXJsaW5lUGVyaW9kIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAib3ZlcmxpbmVQZXJpb2QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcG9zdHVyZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInBvc3R1cmUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwb3N0dXJlIik7CiAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQsCiAgICAgICAgICAgICAgICAgICAgdGhpcywgImZvbnQucG9zdHVyZSIsIHZhbHVlLCBudWxsKTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsIGV2bnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzaXplOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic2l6ZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInNpemUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdHlwZWZhY2U6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlZmFjZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInR5cGVmYWNlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHVuZGVybGluZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInVuZGVybGluZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInVuZGVybGluZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB1bmRlcmxpbmVQZXJpb2Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ1bmRlcmxpbmVQZXJpb2QiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ1bmRlcmxpbmVQZXJpb2QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgd2VpZ2h0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgid2VpZ2h0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAid2VpZ2h0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGZpbGw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZmlsbCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJmaWxsIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgRm9ybWF0ID0geGZhbGliLnNjcmlwdC5kb20uRm9ybWF0ID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImZvcm1hdCIKICAgIH0pOwoKICAgIEZvcm1hdC5kZWZpbmVQcm9wcyh7CiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcGljdHVyZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJwaWN0dXJlIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInBpY3R1cmUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBIYW5kbGVyID0geGZhbGliLnNjcmlwdC5kb20uSGFuZGxlciA9IHhmYWxpYi5zY3JpcHQuR2VuZXJpY1RleHQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToiaGFuZGxlciIKICAgIH0pOwoKICAgIEhhbmRsZXIuZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEh5cGhlbmF0aW9uID0geGZhbGliLnNjcmlwdC5kb20uSHlwaGVuYXRpb24gPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6Imh5cGhlbmF0aW9uIgogICAgfSk7CgogICAgSHlwaGVuYXRpb24uZGVmaW5lUHJvcHMoewogICAgICAgIGV4Y2x1ZGVBbGxDYXBzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZXhjbHVkZUFsbENhcHMiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJleGNsdWRlQWxsQ2FwcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleGNsdWRlSW5pdGlhbENhcDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImV4Y2x1ZGVJbml0aWFsQ2FwIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZXhjbHVkZUluaXRpYWxDYXAiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgaHlwaGVuYXRlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiaHlwaGVuYXRlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaHlwaGVuYXRlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGxhZGRlckNvdW50OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGFkZGVyQ291bnQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJsYWRkZXJDb3VudCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBwdXNoQ2hhcmFjdGVyQ291bnQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJwdXNoQ2hhcmFjdGVyQ291bnQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwdXNoQ2hhcmFjdGVyQ291bnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVtYWluQ2hhcmFjdGVyQ291bnQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyZW1haW5DaGFyYWN0ZXJDb3VudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJlbWFpbkNoYXJhY3RlckNvdW50Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHdvcmRDaGFyYWN0ZXJDb3VudDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIndvcmRDaGFyYWN0ZXJDb3VudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIndvcmRDaGFyYWN0ZXJDb3VudCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEltYWdlRWRpdCA9IHhmYWxpYi5zY3JpcHQuZG9tLkltYWdlRWRpdCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJpbWFnZUVkaXQiCiAgICB9KTsKCiAgICBJbWFnZUVkaXQuZGVmaW5lUHJvcHMoewogICAgICAgIGRhdGE6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJkYXRhIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZGF0YSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBib3JkZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiYm9yZGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImJvcmRlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYXJnaW46ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFyZ2luIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgIm1hcmdpbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIElzc3VlcnMgPSB4ZmFsaWIuc2NyaXB0LmRvbS5Jc3N1ZXJzID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6Imlzc3VlcnMiCiAgICB9KTsKCiAgICBJc3N1ZXJzLmRlZmluZVByb3BzKHsKICAgICAgICAidHlwZSI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBJdGVtcyA9IHhmYWxpYi5zY3JpcHQuZG9tLkl0ZW1zID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgX2RlZmF1bHRzOiB7CiAgICAgICAgICAgICJzYXZlIjogIjAiCiAgICAgICAgfSwKCiAgICAgICAgbXNDbGFzc05hbWU6ICJpdGVtcyIsCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICBJdGVtcy5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBhbHdheXMgcmV0dXJuIDxpdGVtcz4gLSBidWcjMzYyMTg5OAogICAgICAgICAgICAgKiBJbiBjYXNlIG9mIGZpbmFsIHN1Ym1pc3Npb24sIGRvbid0IHNlbmQgSXRlbXMKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJldHVybiBkaWZmX2xldmVsID09PSAyID8gewogICAgICAgICAgICAgICAgImNoYW5nZWQiOiBmYWxzZSwKICAgICAgICAgICAgICAgIGpzb25EaWZmZXJlbmNlOiB7fQogICAgICAgICAgICB9IDogewogICAgICAgICAgICAgICAgImNoYW5nZWQiOiB0cnVlLAogICAgICAgICAgICAgICAganNvbkRpZmZlcmVuY2U6IHRoaXMuanNvbk1vZGVsCiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgIH0pOwoKICAgIEl0ZW1zLmRlZmluZVByb3BzKHsKICAgICAgICAic2F2ZSI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInNhdmUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKICAgIEl0ZW1zLmFkZE1peGlucyhbCiAgICAgICAgeGZhbGliLnNjcmlwdC5taXhpbi5BZGRQcmVzZW5jZQogICAgXSk7Cn0pKF8sIHhmYWxpYik7CgooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEtlZXAgPSB4ZmFsaWIuc2NyaXB0LmRvbS5LZWVwID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImtlZXAiCiAgICB9KTsKCiAgICBLZWVwLmRlZmluZVByb3BzKHsKICAgICAgICBpbnRhY3Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJpbnRhY3QiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJpbnRhY3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbmV4dDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm5leHQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJuZXh0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHByZXZpb3VzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicHJldmlvdXMiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwcmV2aW91cyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIEtleVVzYWdlID0geGZhbGliLnNjcmlwdC5kb20uS2V5VXNhZ2UgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6ImtleVVzYWdlIgogICAgfSk7CgogICAgS2V5VXNhZ2UuZGVmaW5lUHJvcHMoewogICAgICAgIGNybFNpZ246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJjcmxTaWduIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiY3JsU2lnbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBkYXRhRW5jaXBoZXJtZW50OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZGF0YUVuY2lwaGVybWVudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImRhdGFFbmNpcGhlcm1lbnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZGVjaXBoZXJPbmx5OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZGVjaXBoZXJPbmx5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZGVjaXBoZXJPbmx5Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGRpZ2l0YWxTaWduYXR1cmU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJkaWdpdGFsU2lnbmF0dXJlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZGlnaXRhbFNpZ25hdHVyZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBlbmNpcGhlck9ubHk6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJlbmNpcGhlck9ubHkiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJlbmNpcGhlck9ubHkiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAga2V5QWdyZWVtZW50OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgia2V5QWdyZWVtZW50Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAia2V5QWdyZWVtZW50Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGtleUNlcnRTaWduOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgia2V5Q2VydFNpZ24iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJrZXlDZXJ0U2lnbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBrZXlFbmNpcGhlcm1lbnQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJrZXlFbmNpcGhlcm1lbnQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJrZXlFbmNpcGhlcm1lbnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbm9uUmVwdWRpYXRpb246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJub25SZXB1ZGlhdGlvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm5vblJlcHVkaWF0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIExpbmVhciA9IHhmYWxpYi5zY3JpcHQuZG9tLkxpbmVhciA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJsaW5lYXIiCiAgICB9KTsKCiAgICBMaW5lYXIuZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb2xvcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjb2xvciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJjb2xvciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIExvY2tEb2N1bWVudCA9IHhmYWxpYi5zY3JpcHQuZG9tLkxvY2tEb2N1bWVudCA9IHhmYWxpYi5zY3JpcHQuR2VuZXJpY1RleHQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToibG9ja0RvY3VtZW50IgogICAgfSk7CgogICAgTG9ja0RvY3VtZW50LmRlZmluZVByb3BzKHsKICAgICAgICB0eXBlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidHlwZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInR5cGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBNYW5pZmVzdCA9IHhmYWxpYi5zY3JpcHQuZG9tLk1hbmlmZXN0ID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6Im1hbmlmZXN0IgogICAgfSk7CgogICAgTWFuaWZlc3QuZGVmaW5lUHJvcHMoewogICAgICAgIGFjdGlvbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImFjdGlvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImFjdGlvbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBNYXJnaW4gPSB4ZmFsaWIuc2NyaXB0LmRvbS5NYXJnaW4gPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToibWFyZ2luIgogICAgfSk7CgogICAgTWFyZ2luLmRlZmluZVByb3BzKHsKICAgICAgICBib3R0b21JbnNldDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImJvdHRvbUluc2V0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiYm90dG9tSW5zZXQiKTsKICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICB0aGlzLCJib3R0b21JbnNldCIsdmFsdWUsIG51bGwpOwogICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbGVmdEluc2V0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibGVmdEluc2V0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGVmdEluc2V0Iik7CiAgICAgICAgICAgICAgICB2YXIgZXZudCA9IHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCh4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQsCiAgICAgICAgICAgICAgICAgICAgdGhpcywibGVmdEluc2V0Iix2YWx1ZSwgbnVsbCk7CiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICByaWdodEluc2V0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicmlnaHRJbnNldCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJpZ2h0SW5zZXQiKTsKICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICB0aGlzLCJyaWdodEluc2V0Iix2YWx1ZSwgbnVsbCk7CiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIoZXZudC5uYW1lLGV2bnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0b3BJbnNldDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRvcEluc2V0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidG9wSW5zZXQiKTsKICAgICAgICAgICAgICAgIHZhciBldm50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwKICAgICAgICAgICAgICAgICAgICB0aGlzLCJ0b3BJbnNldCIsdmFsdWUsIG51bGwpOwogICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKGV2bnQubmFtZSxldm50KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBNZHAgPSB4ZmFsaWIuc2NyaXB0LmRvbS5NZHAgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6Im1kcCIKICAgIH0pOwoKICAgIE1kcC5kZWZpbmVQcm9wcyh7CiAgICAgICAgcGVybWlzc2lvbnM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJwZXJtaXNzaW9ucyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInBlcm1pc3Npb25zIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHNpZ25hdHVyZVR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJzaWduYXR1cmVUeXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic2lnbmF0dXJlVHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIE1lZGl1bSA9IHhmYWxpYi5zY3JpcHQuZG9tLk1lZGl1bSA9IHhmYWxpYi5zY3JpcHQuR2VuZXJpY1RleHQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToibWVkaXVtIgogICAgfSk7CgogICAgTWVkaXVtLmRlZmluZVByb3BzKHsKICAgICAgICBpbWFnaW5nQkJveDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImltYWdpbmdCQm94Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaW1hZ2luZ0JCb3giKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImxvbmciOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibG9uZyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImxvbmciKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgb3JpZW50YXRpb246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJvcmllbnRhdGlvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm9yaWVudGF0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJzaG9ydCI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJzaG9ydCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInNob3J0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHN0b2NrOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic3RvY2siKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJzdG9jayIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0cmF5SW46ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0cmF5SW4iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0cmF5SW4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdHJheU91dDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRyYXlPdXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0cmF5T3V0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgTWVzc2FnZSA9IHhmYWxpYi5zY3JpcHQuZG9tLk1lc3NhZ2UgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToibWVzc2FnZSIKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBOdW1lcmljRWRpdCA9IHhmYWxpYi5zY3JpcHQuZG9tLk51bWVyaWNFZGl0ID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6Im51bWVyaWNFZGl0IgogICAgfSk7CgogICAgTnVtZXJpY0VkaXQuZGVmaW5lUHJvcHMoewogICAgICAgIGhTY3JvbGxQb2xpY3k6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJoU2Nyb2xsUG9saWN5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaFNjcm9sbFBvbGljeSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBib3JkZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiYm9yZGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImJvcmRlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb21iOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImNvbWIiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY29tYiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYXJnaW46ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFyZ2luIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgIm1hcmdpbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIE9jY3VyID0geGZhbGliLnNjcmlwdC5kb20uT2NjdXIgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToib2NjdXIiLAogICAgICAgIHBsYXlKc29uIDogZnVuY3Rpb24ocEpzb25Nb2RlbCkgewoKICAgICAgICB9CgogICAgfSk7CgogICAgT2NjdXIuZGVmaW5lUHJvcHMoewogICAgICAgIGluaXRpYWw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJpbml0aWFsIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaW5pdGlhbCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYXg6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJtYXgiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJtYXgiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbWluOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibWluIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibWluIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHNjcmlwdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJzY3JpcHQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAic2NyaXB0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgT2lkID0geGZhbGliLnNjcmlwdC5kb20uT2lkID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJvaWQiCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgT2lkcyA9IHhmYWxpYi5zY3JpcHQuZG9tLk9pZHMgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToib2lkcyIKICAgIH0pOwoKICAgIE9pZHMuZGVmaW5lUHJvcHMoewogICAgICAgICJ0eXBlIjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0eXBlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIE92ZXJmbG93ID0geGZhbGliLnNjcmlwdC5kb20uT3ZlcmZsb3cgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6Im92ZXJmbG93IgogICAgfSk7CgogICAgT3ZlcmZsb3cuZGVmaW5lUHJvcHMoewogICAgICAgIGxlYWRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImxlYWRlciIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImxlYWRlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0YXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0YXJnZXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdHJhaWxlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRyYWlsZXIiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0cmFpbGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbihfLHhmYWxpYil7CiAgICB2YXIgUGFyYSA9IHhmYWxpYi5zY3JpcHQuZG9tLlBhcmEgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToicGFyYSIKICAgIH0pOwoKICAgIFBhcmEuZGVmaW5lUHJvcHMoewogICAgICAgIGhBbGlnbiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiaEFsaWduIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaEFsaWduIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBsaW5lSGVpZ2h0IDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJsaW5lSGVpZ2h0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibGluZUhlaWdodCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbWFyZ2luTGVmdCA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibWFyZ2luTGVmdCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm1hcmdpbkxlZnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIG1hcmdpblJpZ2h0IDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJtYXJnaW5SaWdodCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm1hcmdpblJpZ2h0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBvcnBoYW5zIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJvcnBoYW5zIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAib3JwaGFucyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgcHJlc2VydmUgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInByZXNlcnZlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicHJlc2VydmUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHJhZGl4T2Zmc2V0IDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyYWRpeE9mZnNldCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJhZGl4T2Zmc2V0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBzcGFjZUFib3ZlIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJzcGFjZUFib3ZlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic3BhY2VBYm92ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc3BhY2VCZWxvdyA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic3BhY2VCZWxvdyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInNwYWNlQmVsb3ciKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHRhYkRlZmF1bHQgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRhYkRlZmF1bHQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsdWUpewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YWJEZWZhdWx0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICB0YWJTdG9wcyA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidGFiU3RvcHMiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsdWUpewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YWJTdG9wcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgdGV4dEluZGVudCA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidGV4dEluZGVudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInRleHRJbmRlbnQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHZBbGlnbiA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidkFsaWduIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidkFsaWduIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICB3aWRvd3MgOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIndpZG93cyIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIndpZG93cyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgd29yZFNwYWNpbmdNYXhpbXVtIDogewogICAgICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ3b3JkU3BhY2luZ01heGltdW0iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0IDogZnVuY3Rpb24odmFsdWUpewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ3b3JkU3BhY2luZ01heGltdW0iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHdvcmRTcGFjaW5nTWluaW11bSA6IHsKICAgICAgICAgICAgZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgid29yZFNwYWNpbmdNaW5pbXVtIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldCA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAid29yZFNwYWNpbmdNaW5pbXVtIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICB3b3JkU3BhY2luZ09wdGltdW0gOiB7CiAgICAgICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIndvcmRTcGFjaW5nT3B0aW11bSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQgOiBmdW5jdGlvbih2YWx1ZSl7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIndvcmRTcGFjaW5nT3B0aW11bSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLHhmYWxpYik7CgoKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBQYXNzd29yZEVkaXQgPSB4ZmFsaWIuc2NyaXB0LmRvbS5QYXNzd29yZEVkaXQgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToicGFzc3dvcmRFZGl0IgogICAgfSk7CgogICAgUGFzc3dvcmRFZGl0LmRlZmluZVByb3BzKHsKICAgICAgICBoU2Nyb2xsUG9saWN5OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiaFNjcm9sbFBvbGljeSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImhTY3JvbGxQb2xpY3kiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcGFzc3dvcmRDaGFyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicGFzc3dvcmRDaGFyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicGFzc3dvcmRDaGFyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGJvcmRlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJib3JkZXIiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiYm9yZGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIG1hcmdpbjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJtYXJnaW4iLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWFyZ2luIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgUGF0dGVybiA9IHhmYWxpYi5zY3JpcHQuZG9tLlBhdHRlcm4gPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToicGF0dGVybiIKICAgIH0pOwoKICAgIFBhdHRlcm4uZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb2xvcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjb2xvciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJjb2xvciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFBpY3R1cmUgPSB4ZmFsaWIuc2NyaXB0LmRvbS5QaWN0dXJlID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJwaWN0dXJlIgogICAgfSk7CgogICAgUGljdHVyZS5kZWZpbmVQcm9wcyh7CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgUmFkaWFsID0geGZhbGliLnNjcmlwdC5kb20uUmFkaWFsID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InJhZGlhbCIKICAgIH0pOwoKICAgIFJhZGlhbC5kZWZpbmVQcm9wcyh7CiAgICAgICAgdHlwZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0eXBlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGNvbG9yOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImNvbG9yIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImNvbG9yIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgUmVhc29uID0geGZhbGliLnNjcmlwdC5kb20uUmVhc29uID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJyZWFzb24iCiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgUmVhc29ucyA9IHhmYWxpYi5zY3JpcHQuZG9tLlJlYXNvbnMgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToicmVhc29ucyIKICAgIH0pOwoKICAgIFJlYXNvbnMuZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBSZWYgPSB4ZmFsaWIuc2NyaXB0LmRvbS5SZWYgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InJlZiIKICAgIH0pOwoKICAgIFJlZi5kZWZpbmVQcm9wcyh7CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgUmVuZGVyQXMgPSB4ZmFsaWIuc2NyaXB0LmRvbS5SZW5kZXJBcyA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJyZW5kZXJBcyIKICAgIH0pOwoKICAgIFJlbmRlckFzLmRlZmluZVByb3BzKHsKICAgICAgICBBUElWZXJzaW9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiQVBJVmVyc2lvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIkFQSVZlcnNpb24iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgc3ZnOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInN2ZyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzdmciKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTY3JpcHQgPSB4ZmFsaWIuc2NyaXB0LmRvbS5TY3JpcHQgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InNjcmlwdCIKICAgIH0pOwoKICAgIFNjcmlwdC5kZWZpbmVQcm9wcyh7CiAgICAgICAgYmluZGluZzp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImJpbmRpbmciKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJiaW5kaW5nIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGNvbnRlbnRUeXBlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiY29udGVudFR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJjb250ZW50VHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBydW5BdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJ1bkF0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicnVuQXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgc3RhdGVsZXNzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgic3RhdGVsZXNzIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic3RhdGVsZXNzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbihfLCB4ZmFsaWIpewogICAgdmFyIFNjcmlwdE9iamVjdCA9IHhmYWxpYi5zY3JpcHQuZG9tLlNjcmlwdE9iamVjdCA9IHhmYWxpYi5zY3JpcHQuZG9tLlNjcmlwdC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiAic2NyaXB0IiwKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgU2NyaXB0T2JqZWN0Ll9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuX3NjcmlwdEluaXRpYWxpemVkID0gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgX2dldE5ha2VkVGhpcyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKCF0aGlzLl9zY3JpcHRJbml0aWFsaXplZCl7CiAgICAgICAgICAgICAgICBpZih0aGlzLnZhbHVlKXsKICAgICAgICAgICAgICAgICAgICB0cnl7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvbGRTY29wZSA9IG51bGw7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMucGFyZW50LnBhcmVudCBpbnN0YW5jZW9mIHhmYWxpYi5zY3JpcHQuRXZlbnRDb250YWluZXJOb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRTY29wZSA9IHRoaXMucGFyZW50LnBhcmVudC5fY3JlYXRlTmFrZWRSZWZlcmVuY2VzU2NvcGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5fcHVzaENvbnRleHROb2RlKHRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICB3aXRoKHRoaXMucGFyZW50LnBhcmVudCkgeyAvLyB0aGUgcGFyZW50IHN1YmZvcm0gb2Ygc2NyaXB0IG9iai4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpdGgoeGZhbGliLnJ1bnRpbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1RPRE86IHBvc3NpYmxlIHhzcyBhdHRhY2sKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZXZhbCgiKCIrdGhpcy52YWx1ZSsiKSIpKS5hcHBseSh0aGlzLnBhcmVudC5wYXJlbnQsW3RoaXNdKTsgLy8gc3ViZm9ybSAtPiBzZWxmLCB0aGlzIC0+IGJhc2VvYmogLyBzY3JpcHQgT2JqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGNhdGNoKGV4Y2VwdGlvbil7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzb20gPSB0aGlzLl94ZmEoKS5tb0NvbnRleHROb2Rlc1swXSA/IHRoaXMuX3hmYSgpLm1vQ29udGV4dE5vZGVzWzBdLnNvbUV4cHJlc3Npb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogIiIKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuTG9nZ2VyLmVycm9yKCJ4ZmEiLCB4ZmFsaWIubG9jYWxlLkxvZ01lc3NhZ2VzWyJBTEMtRlJNLTkwMS0wMTUiXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2V4Y2VwdGlvbi5tZXNzYWdlLCB0aGlzLm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmEoKS5ldmVudC5uYW1lLCBzb21dKQogICAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKG9sZFNjb3BlICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFyZW50LnBhcmVudC5fcmVzZXROYWtlZFJlZmVyZW5jZXNTY29wZShvbGRTY29wZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5feGZhKCkuX3BvcENvbnRleHROb2RlKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5fc2NyaXB0SW5pdGlhbGl6ZWQgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICB9KTsKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTZXRQcm9wZXJ0eSA9IHhmYWxpYi5zY3JpcHQuZG9tLlNldFByb3BlcnR5ID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJzZXRQcm9wZXJ0eSIKICAgIH0pOwoKICAgIFNldFByb3BlcnR5LmRlZmluZVByb3BzKHsKICAgICAgICBjb25uZWN0aW9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiY29ubmVjdGlvbiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImNvbm5lY3Rpb24iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVmOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicmVmIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicmVmIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRhcmdldDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRhcmdldCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInRhcmdldCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFNpZ25hdHVyZSA9IHhmYWxpYi5zY3JpcHQuZG9tLlNpZ25hdHVyZSA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJzaWduYXR1cmUiCiAgICB9KTsKCiAgICBTaWduYXR1cmUuZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBib3JkZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiYm9yZGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImJvcmRlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBmaWx0ZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZmlsdGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImZpbHRlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYW5pZmVzdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJtYW5pZmVzdCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJtYW5pZmVzdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYXJnaW46ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFyZ2luIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgIm1hcmdpbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFNpZ25EYXRhID0geGZhbGliLnNjcmlwdC5kb20uU2lnbkRhdGEgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToic2lnbkRhdGEiCiAgICB9KTsKCiAgICBTaWduRGF0YS5kZWZpbmVQcm9wcyh7CiAgICAgICAgb3BlcmF0aW9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgib3BlcmF0aW9uIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAib3BlcmF0aW9uIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlZjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJlZiIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJlZiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0YXJnZXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0YXJnZXQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0YXJnZXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZmlsdGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImZpbHRlciIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJmaWx0ZXIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbWFuaWZlc3Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFuaWZlc3QiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWFuaWZlc3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTaWduaW5nID0geGZhbGliLnNjcmlwdC5kb20uU2lnbmluZyA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJzaWduaW5nIgogICAgfSk7CgogICAgU2lnbmluZy5kZWZpbmVQcm9wcyh7CiAgICAgICAgdHlwZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInR5cGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0eXBlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFNvbGlkID0geGZhbGliLnNjcmlwdC5kb20uU29saWQgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToic29saWQiCiAgICB9KTsKCiAgICBTb2xpZC5kZWZpbmVQcm9wcyh7CiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTcGVhayA9IHhmYWxpYi5zY3JpcHQuZG9tLlNwZWFrID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJzcGVhayIKICAgIH0pOwoKICAgIFNwZWFrLmRlZmluZVByb3BzKHsKICAgICAgICBkaXNhYmxlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZGlzYWJsZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImRpc2FibGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcHJpb3JpdHk6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJwcmlvcml0eSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInByaW9yaXR5Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJpZDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJpZCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJpZCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFN0aXBwbGUgPSB4ZmFsaWIuc2NyaXB0LmRvbS5TdGlwcGxlID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InN0aXBwbGUiCiAgICB9KTsKCiAgICBTdGlwcGxlLmRlZmluZVByb3BzKHsKICAgICAgICByYXRlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicmF0ZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJhdGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY29sb3I6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiY29sb3IiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY29sb3IiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTdWJqZWN0RE4gPSB4ZmFsaWIuc2NyaXB0LmRvbS5TdWJqZWN0RE4gPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InN1YmplY3RETiIKICAgIH0pOwoKICAgIFN1YmplY3RETi5kZWZpbmVQcm9wcyh7CiAgICAgICAgZGVsaW1pdGVyOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZGVsaW1pdGVyIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZGVsaW1pdGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgU3ViamVjdEROcyA9IHhmYWxpYi5zY3JpcHQuZG9tLlN1YmplY3RETnMgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToic3ViamVjdEROcyIKICAgIH0pOwoKICAgIFN1YmplY3RETnMuZGVmaW5lUHJvcHMoewogICAgICAgIHR5cGU6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0eXBlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidHlwZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTdWJtaXQgPSB4ZmFsaWIuc2NyaXB0LmRvbS5TdWJtaXQgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToic3VibWl0IgogICAgfSk7CgogICAgU3VibWl0LmRlZmluZVByb3BzKHsKICAgICAgICBlbWJlZFBERjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoImVtYmVkUERGIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZW1iZWRQREYiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZm9ybWF0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZm9ybWF0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZm9ybWF0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHRhcmdldDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInRhcmdldCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInRhcmdldCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0ZXh0RW5jb2Rpbmc6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ0ZXh0RW5jb2RpbmciKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ0ZXh0RW5jb2RpbmciKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgeGRwQ29udGVudDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInhkcENvbnRlbnQiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJ4ZHBDb250ZW50Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGVuY3J5cHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZW5jcnlwdCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJlbmNyeXB0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBTdmcgPSB4ZmFsaWIuc2NyaXB0LmRvbS5TdmcgPSB4ZmFsaWIuc2NyaXB0LkdlbmVyaWNUZXh0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InN2ZyIKICAgIH0pOwoKICAgIFN2Zy5kZWZpbmVQcm9wcyh7CiAgICAgICAgaGVpZ2h0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiaGVpZ2h0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiaGVpZ2h0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHZpZXdCb3g6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ2aWV3Qm94Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidmlld0JveCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB3aWR0aDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIndpZHRoIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAid2lkdGgiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBUZXh0RWRpdCA9IHhmYWxpYi5zY3JpcHQuZG9tLlRleHRFZGl0ID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InRleHRFZGl0IgogICAgfSk7CgogICAgVGV4dEVkaXQuZGVmaW5lUHJvcHMoewogICAgICAgIGFsbG93UmljaFRleHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJhbGxvd1JpY2hUZXh0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiYWxsb3dSaWNoVGV4dCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBoU2Nyb2xsUG9saWN5OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiaFNjcm9sbFBvbGljeSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImhTY3JvbGxQb2xpY3kiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbXVsdGlMaW5lOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgibXVsdGlMaW5lIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAibXVsdGlMaW5lIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHZTY3JvbGxQb2xpY3k6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJ2U2Nyb2xsUG9saWN5Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAidlNjcm9sbFBvbGljeSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBib3JkZXI6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiYm9yZGVyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImJvcmRlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBjb21iOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImNvbWIiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY29tYiIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtYXJnaW46ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibWFyZ2luIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgIm1hcmdpbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFRleHROb2RlID0geGZhbGliLnNjcmlwdC5UZXh0Tm9kZSA9IHhmYWxpYi5zY3JpcHQuT2JqZWN0LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InRleHROb2RlIgogICAgfSk7CgogICAgVGV4dE5vZGUuZGVmaW5lUHJvcHMoewoKICAgIH0pCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgVGltZVN0YW1wID0geGZhbGliLnNjcmlwdC5kb20uVGltZVN0YW1wID0geGZhbGliLnNjcmlwdC5HZW5lcmljVGV4dC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJ0aW1lU3RhbXAiCiAgICB9KTsKCiAgICBUaW1lU3RhbXAuZGVmaW5lUHJvcHMoewogICAgICAgIHNlcnZlcjp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInNlcnZlciIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInNlcnZlciIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB0eXBlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgidHlwZSIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInR5cGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBUb29sVGlwID0geGZhbGliLnNjcmlwdC5kb20uVG9vbFRpcCA9IHhmYWxpYi5zY3JpcHQuR2VuZXJpY1RleHQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZToidG9vbFRpcCIKICAgIH0pOwoKICAgIFRvb2xUaXAuZGVmaW5lUHJvcHMoewogICAgICAgIHJpZDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoInJpZCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgInJpZCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFRyYXZlcnNhbCA9IHhmYWxpYi5zY3JpcHQuZG9tLlRyYXZlcnNhbCA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJ0cmF2ZXJzYWwiCiAgICB9KTsKCiAgICBUcmF2ZXJzYWwuZGVmaW5lUHJvcHMoewogICAgICAgIHBhc3NUaHJvdWdoOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicGFzc1Rocm91Z2giKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJwYXNzVGhyb3VnaCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBUcmF2ZXJzZSA9IHhmYWxpYi5zY3JpcHQuZG9tLlRyYXZlcnNlID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InRyYXZlcnNlIgogICAgfSk7CgogICAgVHJhdmVyc2UuZGVmaW5lUHJvcHMoewogICAgICAgIGRlbGVnYXRlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZGVsZWdhdGUiKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJkZWxlZ2F0ZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBvcGVyYXRpb246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJvcGVyYXRpb24iKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJvcGVyYXRpb24iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcmVmOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgicmVmIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAicmVmIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4dHJhczp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJleHRyYXMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXh0cmFzIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHNjcmlwdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJzY3JpcHQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAic2NyaXB0Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KTsKCn0pKF8sIHhmYWxpYik7CihmdW5jdGlvbiAoXywgeGZhbGliKSB7CiAgICB2YXIgVWkgPSB4ZmFsaWIuc2NyaXB0LmRvbS5VaSA9IHhmYWxpYi5zY3JpcHQuRE9NRWxlbWVudC5leHRlbmQoewogICAgICAgIG1zQ2xhc3NOYW1lOiJ1aSIsCgogICAgICAgIC8vIFRPRE8gOiByZW1vdmUgdGhlc2Ugb25jZSBTaGFyYWQgbWVyZ2VzIGNoYW5nZXMgZnJvbSBITVJDCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIFVpLl9zdXBlci5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tb0NoaWxkTm9kZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgIHZhciBvTm9kZSA9IHRoaXMubW9DaGlsZE5vZGVzW2ldOwogICAgICAgICAgICAgICAgb05vZGUub24oeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkRPTV9DSEFOR0VELHRoaXMpIDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUV2ZW50OiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldm50Lm5hbWUsZXZudCk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldE9uZU9mQ2hpbGQgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgb25lQ2hpbGQgPSBVaS5fc3VwZXIuX2dldE9uZU9mQ2hpbGQuY2FsbCh0aGlzKTsKICAgICAgICAgICAgaWYob25lQ2hpbGQpCiAgICAgICAgICAgICAgICByZXR1cm4gb25lQ2hpbGQ7CgogICAgICAgICAgICB2YXIgY2hpbGRUeXBlID0gInRleHRFZGl0IjsKICAgICAgICAgICAgaWYodGhpcy5wYXJlbnQpewogICAgICAgICAgICAgICAgdmFyIHZhbHVlQ2hpbGQgPSB0aGlzLnBhcmVudC52YWx1ZS5vbmVPZkNoaWxkIHx8IHtjbGFzc05hbWUgOiAidGV4dCJ9OwogICAgICAgICAgICAgICAgc3dpdGNoICh2YWx1ZUNoaWxkLmNsYXNzTmFtZSl7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiZGF0ZVRpbWUiIDoKICAgICAgICAgICAgICAgICAgICBjYXNlICJkYXRlIiA6CiAgICAgICAgICAgICAgICAgICAgY2FzZSAidGltZSIgOgogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFR5cGUgPSAiZGF0ZVRpbWVFZGl0IjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiZGVjaW1hbCIgOgogICAgICAgICAgICAgICAgICAgIGNhc2UgImZsb2F0IiA6CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiaW50ZWdlciIgOgogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFR5cGUgPSAibnVtZXJpY0VkaXQiOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJib29sZWFuIiA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkVHlwZSA9ICJjaGVja0J1dHRvbiI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgInRleHQiIDoKICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRUeXBlID0gInRleHRFZGl0IjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiaW1hZ2UiIDoKICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRUeXBlID0gImltYWdlRWRpdCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXREZWZhdWx0RWxlbWVudChjaGlsZFR5cGUsIDAsIHRydWUpOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBVaS5kZWZpbmVQcm9wcyh7CiAgICAgICAgZXh0cmFzOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4dHJhcyIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJleHRyYXMiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcGljdHVyZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJwaWN0dXJlIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInBpY3R1cmUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgYmFyY29kZTp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJiYXJjb2RlIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImJhcmNvZGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgYnV0dG9uOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImJ1dHRvbiIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJidXR0b24iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY2hlY2tCdXR0b246ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiY2hlY2tCdXR0b24iLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiY2hlY2tCdXR0b24iKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgY2hvaWNlTGlzdDp7CiAgICAgICAgICAgIGdldDpmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJjaG9pY2VMaXN0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImNob2ljZUxpc3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZGF0ZVRpbWVFZGl0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImRhdGVUaW1lRWRpdCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJkYXRlVGltZUVkaXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZGVmYXVsdFVpOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImRlZmF1bHRVaSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJkZWZhdWx0VWkiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZXhPYmplY3Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXhPYmplY3QiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXhPYmplY3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgaW1hZ2VFZGl0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImltYWdlRWRpdCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJpbWFnZUVkaXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbnVtZXJpY0VkaXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgibnVtZXJpY0VkaXQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibnVtZXJpY0VkaXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgcGFzc3dvcmRFZGl0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInBhc3N3b3JkRWRpdCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJwYXNzd29yZEVkaXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgc2lnbmF0dXJlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInNpZ25hdHVyZSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJzaWduYXR1cmUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgdGV4dEVkaXQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgidGV4dEVkaXQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAidGV4dEVkaXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pOwoKfSkoXywgeGZhbGliKTsKKGZ1bmN0aW9uIChfLCB4ZmFsaWIpIHsKICAgIHZhciBWYWxpZGF0ZSA9IHhmYWxpYi5zY3JpcHQuZG9tLlZhbGlkYXRlID0geGZhbGliLnNjcmlwdC5ET01FbGVtZW50LmV4dGVuZCh7CiAgICAgICAgbXNDbGFzc05hbWU6InZhbGlkYXRlIgogICAgfSk7CgogICAgVmFsaWRhdGUuZGVmaW5lUHJvcHMoewogICAgICAgIGRpc2FibGVBbGw6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJkaXNhYmxlQWxsIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAiZGlzYWJsZUFsbCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBmb3JtYXRUZXN0OnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSgiZm9ybWF0VGVzdCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgImZvcm1hdFRlc3QiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgbnVsbFRlc3Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJudWxsVGVzdCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6ZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB2YXIgb2xkVmFsdWUgPSB0aGlzLm51bGxUZXN0OwogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJudWxsVGVzdCIpOwogICAgICAgICAgICAgICAgdmFyIGV2ZW50ID0geGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LmNyZWF0ZUV2ZW50KHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwgdGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgJ251bGxUZXN0Jywgb2xkVmFsdWUsIHZhbHVlKTsKICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcihldmVudC5uYW1lLCBldmVudCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHNjcmlwdFRlc3Q6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJzY3JpcHRUZXN0Iik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0QXR0cmlidXRlKHZhbHVlLCAic2NyaXB0VGVzdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBleHRyYXM6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgiZXh0cmFzIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImV4dHJhcyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtZXNzYWdlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoIm1lc3NhZ2UiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAibWVzc2FnZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBwaWN0dXJlOnsKICAgICAgICAgICAgZ2V0OmZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInBpY3R1cmUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OmZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAicGljdHVyZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzY3JpcHQ6ewogICAgICAgICAgICBnZXQ6ZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgic2NyaXB0IiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDpmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInNjcmlwdCIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sIHhmYWxpYikgewogICAgdmFyIFZhbHVlID0geGZhbGliLnNjcmlwdC5kb20uVmFsdWUgPSB4ZmFsaWIuc2NyaXB0LkRPTUVsZW1lbnQuZXh0ZW5kKHsKICAgICAgICBtc0NsYXNzTmFtZTogInZhbHVlIiwKCiAgICAgICAgX2dldE9uZU9mQ2hpbGQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIG9uZUNoaWxkID0gVmFsdWUuX3N1cGVyLl9nZXRPbmVPZkNoaWxkLmNhbGwodGhpcyk7CiAgICAgICAgICAgIGlmIChvbmVDaGlsZCkKICAgICAgICAgICAgICAgIHJldHVybiBvbmVDaGlsZDsKCiAgICAgICAgICAgIHZhciBjaGlsZFR5cGUgPSAidGV4dCI7CiAgICAgICAgICAgIGlmICh0aGlzLnBhcmVudCAmJiAodGhpcy5wYXJlbnQuY2xhc3NOYW1lID09ICJmaWVsZCIgfHwgdGhpcy5wYXJlbnQuY2xhc3NOYW1lID09ICJkcmF3IikpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBCdWc6MzYwMDI0NgogICAgICAgICAgICAgICAgICogV2hlbiBjaGVja2luZyB1aSBvbmVPZkNoaWxkLCBkbyBub3QgZGlyZWN0bHkgdXNlIHVpLm9uZU9mQ2hpbGQgc2luY2UgaXQgd291bGQgYWdhaW4gZmFsbGJhY2sgdG8gdmFsdWUub25PZkNoaWxkIGluIGNhc2UgdmFsdWUgaXMgYWxzbyBtaXNzaW5nLgogICAgICAgICAgICAgICAgICogU28gY2hlY2sganNvbiBpbnN0ZWFkIGFuZCBzZWUgaWYgdWkgb25lT2ZDaGlsZCBleGlzdCBhbmQgdGhlbiBvbmx5IGFjY2VzcyBpdC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgdmFyIHVpQ2hpbGQgPSB0aGlzLnhmYVV0aWwoKS5nZXRVaU9uZU9mQ2hpbGRUYWcodGhpcy5wYXJlbnQuanNvbk1vZGVsKSA/IHRoaXMucGFyZW50LnVpLm9uZU9mQ2hpbGQgOiB7Y2xhc3NOYW1lOiAidGV4dCJ9OwogICAgICAgICAgICAgICAgc3dpdGNoICh1aUNoaWxkLmNsYXNzTmFtZSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgIm51bWVyaWNFZGl0IiA6CiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkVHlwZSA9ICJmbG9hdCI7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgImRhdGVUaW1lRWRpdCIgOgogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFR5cGUgPSAiZGF0ZVRpbWUiOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJpbWFnZUVkaXQiIDoKICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRUeXBlID0gImltYWdlIjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAidGV4dEVkaXQiIDoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVpQ2hpbGQuYWxsb3dSaWNoVGV4dCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRUeXBlID0gImV4RGF0YSI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFR5cGUgPSAidGV4dCI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiY2hvaWNlTGlzdCIgOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAodWlDaGlsZC5vcGVuID09ICJtdWx0aVNlbGVjdCIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkVHlwZSA9ICJleERhdGEiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRUeXBlID0gInRleHQiOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXREZWZhdWx0RWxlbWVudChjaGlsZFR5cGUsIDAsIHRydWUpOwogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlSnNvbkRpZmY6IGZ1bmN0aW9uIChkaWZmX2xldmVsKSB7CgogICAgICAgICAgICAvL0ZvcmNlIGFsbCB0aGUgZGVzY2VuZGFudHMgb2YgdmFsdWUgaXJyZXNwZWN0aXZlIG9mIHN1Ym1pdCBjYWxsCiAgICAgICAgICAgIHZhciBkaWZmT2JqID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLnN0cmlwT3JDYWxsLmNhbGwodGhpcywgZmFsc2UsIFZhbHVlLl9zdXBlci5fY29tcHV0ZUpzb25EaWZmLCBbMF0pOwoKICAgICAgICAgICAgLy9ub3cgc3RyaXAgYWxsIHRoZSBFWFRSQSBwcm9wZXJ0aWVzIGZyb20gdmFsdWUgaWYgaXQgaXMgZmluYWwgc3VibWlzc2lvbiAgb3IgcmVzdG9yZUZvcm1TdGF0ZQogICAgICAgICAgICBpZiAoZGlmZl9sZXZlbD4wICYmIHRoaXMuZ2V0T3JFbHNlKGRpZmZPYmosICdqc29uRGlmZmVyZW5jZS5jaGlsZHJlbi5sZW5ndGgnLCAwKSkgewogICAgICAgICAgICAgICAgLy9iZWxpZXZlIG1lIHRoaXMgaXMgbm90IHRoYXQgY29zdGx5IGFzIGl0IGxvb2tzIHRvIGJlIGFzIHRoZXJlIHdpbGwgYmUgb25seSBvbmUgY2hpbGQgaW4gYWxsIHRoZSBkaWZmZXJlbmNlcyBhbmQgb25seSB0d28ga2V5cyBwZXIgY2hpbGQKICAgICAgICAgICAgICAgIHZhciBibGFja2xpc3RlZCA9IFsnZXh0cmFzJ107CiAgICAgICAgICAgICAgICBkaWZmT2JqLmpzb25EaWZmZXJlbmNlLmNoaWxkcmVuID0gXy5tYXAoZGlmZk9iai5qc29uRGlmZmVyZW5jZS5jaGlsZHJlbiwgZnVuY3Rpb24gKGNoaWxkKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNvcHkgPSB7fTsKICAgICAgICAgICAgICAgICAgICBfLmVhY2goT2JqZWN0LmtleXMoY2hpbGQpLCBmdW5jdGlvbiAoa2V5KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghXy5jb250YWlucyhibGFja2xpc3RlZCwga2V5KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29weVtrZXldID0gY2hpbGRba2V5XTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBjb3B5OwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vTEMtODMxOSA6IGRvbid0IHNlbmQgW10gaW4gZGlmZk9iai5qc29uRGlmZmVyZW5jZS5jaGlsZHJlbgogICAgICAgICAgICBpZiAoZGlmZk9iai5qc29uRGlmZmVyZW5jZSAmJiBfLmV2ZXJ5KGRpZmZPYmouanNvbkRpZmZlcmVuY2UuY2hpbGRyZW4sIF8uaXNFbXB0eSkpIHsgIC8vIGRpZmZPYmogc2hvdWxkIGhhdmUgYSBqc29uRGlmZmVyZW5jZSBtZW1iZXIKICAgICAgICAgICAgICAgIGRpZmZPYmouanNvbkRpZmZlcmVuY2UuY2hpbGRyZW4gPSB1bmRlZmluZWQ7IC8vIHNjYXJ5IHRvIHVzZSBkZWxldGUgZHVlIHRvIHBlcmYuIGltcGFjdAogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBkaWZmT2JqOwogICAgICAgIH0KCiAgICB9KTsKCiAgICBWYWx1ZS5kZWZpbmVQcm9wcyh7CiAgICAgICAgb3ZlcnJpZGU6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUoIm92ZXJyaWRlIik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEF0dHJpYnV0ZSh2YWx1ZSwgIm92ZXJyaWRlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlbGV2YW50OiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKCJyZWxldmFudCIpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUodmFsdWUsICJyZWxldmFudCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBhcmM6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJhcmMiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImFyYyIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiYm9vbGVhbiI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJib29sZWFuIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJib29sZWFuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJkYXRlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImRhdGUiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgImRhdGUiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImRhdGVUaW1lIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImRhdGVUaW1lIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJkYXRlVGltZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiZGVjaW1hbCI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJkZWNpbWFsIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJkZWNpbWFsIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGV4RGF0YTogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImV4RGF0YSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZXhEYXRhIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJmbG9hdCI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJmbG9hdCIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAiZmxvYXQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImltYWdlIjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoImltYWdlIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJpbWFnZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiaW50ZWdlciI6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJpbnRlZ2VyIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJpbnRlZ2VyIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGxpbmU6IHsKICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFbGVtZW50KCJsaW5lIiwgMCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQodmFsdWUsICJsaW5lIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlY3RhbmdsZTogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInJlY3RhbmdsZSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAicmVjdGFuZ2xlIik7CiAgICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJ0ZXh0IjogewogICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVsZW1lbnQoInRleHQiLCAwKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIHRoaXMuc2V0RWxlbWVudCh2YWx1ZSwgInRleHQiKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgInRpbWUiOiB7CiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RWxlbWVudCgidGltZSIsIDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5zZXRFbGVtZW50KHZhbHVlLCAidGltZSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCB4ZmFsaWIpOwoKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CgogICAgdmFyIEh0bWxUZW1wbGF0ZUNhY2hlID0geGZhbGliLnZpZXcudXRpbC5IdG1sVGVtcGxhdGVDYWNoZSA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICBIdG1sVGVtcGxhdGVDYWNoZS5fc3VwZXIuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICB0aGlzLl9jYWNoZSA9IHt9OwogICAgICAgICAgICB0aGlzLl9oaWRkZW5PYmpQYWdlcyA9IFtdOwogICAgICAgIH0sCgogICAgICAgIHB1dDogZnVuY3Rpb24gKGVsKSB7CiAgICAgICAgICAgIHZhciBvY2N1ckluZGV4ID0gdGhpcy5nZXRPckVsc2UodGhpcy54ZmFVdGlsKCkuJGRhdGEoZWwsIHhmYWxpYi52aWV3LkxheW91dENvbnN0LlhGQV9NT0RFTCksIHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9NT0RFTCArICIuIiArIHhmYWxpYi52aWV3LkxheW91dENvbnN0Lk9DQ1VSX0lOREVYLCAnMCcpOwogICAgICAgICAgICBpZiAoIXRoaXMuY29udGFpbnMoZWwuaWQpIHx8IHRoaXMuX2NhY2hlW2VsLmlkXVtvY2N1ckluZGV4XSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZVtlbC5pZF0gPSB0aGlzLl9jYWNoZVtlbC5pZF0gfHwge307CiAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZVtlbC5pZF1bb2NjdXJJbmRleF0gPSBlbDsgLy8gdGhlIGNhY2hlIGlzIG5vdyAyRCwgYWdhaW5zdCBlYWNoIGVsIGlkIHN0b3JlIGEgbWFwLCBpbmRleGVkIGJ5IG9jY3VyIGluZGV4CiAgICAgICAgICAgICAgICB0aGlzLl9jYWNoZUNoaWxkcmVuKGVsKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGNvbnRhaW5zIDogZnVuY3Rpb24oZWxJZCl7CiAgICAgICAgICAgIHJldHVybiAodGhpcy5fY2FjaGUuaGFzT3duUHJvcGVydHkoZWxJZCkgJiYgdGhpcy5fY2FjaGVbZWxJZF0gIT09IHVuZGVmaW5lZCk7CiAgICAgICAgfSwKCiAgICAgICAgZ2V0IDogZnVuY3Rpb24oZWxJZCwgbG9va1VwSGlkZGVuQ2FjaGUpewogICAgICAgICAgICB2YXIgJG5vZGVEaXYgPSBudWxsLAogICAgICAgICAgICAgICAgbm9kZVhmYU1vZGVsID0gbnVsbCwKICAgICAgICAgICAgICAgIHBhcnRPZmZzZXRZID0gMCwKICAgICAgICAgICAgICAgICRwYWdlRGl2LAogICAgICAgICAgICAgICAgJHNwbGl0UGFydDsKCiAgICAgICAgICAgIGZ1bmN0aW9uIHN0aXRjaE5vZGVzKCkgewogICAgICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBjb2xsZWN0IGFsbCBwYXJ0cyBvZiB0aGlzIG5vZGUgZnJvbSB2YXJpb3VzIHBhZ2VzL29jY3VycmVuY2VzIGFuZCBzdGl0Y2ggdGhlbSB0b2dldGhlci4KICAgICAgICAgICAgICAgIC8vIFdlIHN0YXJ0IGJ5IHBpY2tpbmcgKnN0aXRjaGVkKiBjaGlsZHJlbiBvZiB0aGlzIHBhcnQgYW5kIGFwcGVuZCB0aGVtIHRvIGluaXRpYWxseSBlbXB0eSAkbm9kZURpdi4gQXMgd2UgbW92ZSBvbiB0byBuZXh0CiAgICAgICAgICAgICAgICAvLyBwYXJ0LCB3ZSdsbCBwaWNrIG9ubHkgdGhvc2UgY2hpbGRyZW4gd2hpY2ggc3RhcnRzIGZyb20gdGhhdCBwYXJ0KG9jY3VySW5kZXg6MCkKICAgICAgICAgICAgICAgIC8vIFN0aXRjaGluZyB3b3VsZCByZXF1aXJlIG1vZGlmeSB0aGUgZXh0ZW50eSBvZiBjaGlsZHJlbiB0byBhZGQgY29udGVudCBoZWlnaHQgb2YgY3VycmVudCBzdGl0Y2hlZAogICAgICAgICAgICAgICAgLy8gcGFydCBhbmQgdGhlbiBtb2RpZnkgdGhlIGV4dGVudGggb2YgY3VycmVudGx5IHN0aXRjaGVkIHBhcnQgdG8gaW5jbHVkZSBoZWlnaHQgb2YgbmV3IHBhcnQuIEFsbCB0aGUgY2hpbGRyZW4gZnJvbSBuZXcgcGFydCBhcmUgY2xvbmVkLWFwcGVuZGVkIGludG8KICAgICAgICAgICAgICAgIC8vIGN1cnJlbnQgc3RpdGNoIHBhcnQuCgogICAgICAgICAgICAgICAgaWYgKCEkbm9kZURpdikgewogICAgICAgICAgICAgICAgICAgIC8vZG8gbm90IG1vZGlmeSBleGlzdGluZyBub2RlLiBXb3JrIG9uIGl0J3MgY2xvbmUgYW5kIHN0YXJ0IGJ1aWxkaW5nIGZyb20gc2NyYXRjaC4KICAgICAgICAgICAgICAgICAgICAkbm9kZURpdiA9ICRzcGxpdFBhcnQuY2xvbmUoKTsKICAgICAgICAgICAgICAgICAgICAkbm9kZURpdi5jaGlsZHJlbigpLnJlbW92ZSgpOwogICAgICAgICAgICAgICAgICAgIG5vZGVYZmFNb2RlbCA9IHRoaXMueGZhVXRpbCgpLiRkYXRhKCRub2RlRGl2LmdldCgwKSwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIHBhcnRPZmZzZXRZID0gcGFyc2VGbG9hdChub2RlWGZhTW9kZWxbeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX01PREVMXVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5FWFRFTlRfSF0pIC0KICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VGbG9hdCh0aGlzLmdldE9yRWxzZShub2RlWGZhTW9kZWxbeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX01PREVMXVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5NQVJHSU5fVE9QXSwgMCkpIC0KICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VGbG9hdCh0aGlzLmdldE9yRWxzZShub2RlWGZhTW9kZWxbeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX01PREVMXVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5NQVJHSU5fQk9UVE9NXSwgMCkpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIF8uZWFjaCgkc3BsaXRQYXJ0LmNoaWxkcmVuKCkuZ2V0KCksCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHBhcnRDaGlsZCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRJZCA9IHBhcnRDaGlsZC5pZDsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkSGFzU3BsaXQgPSAodGhpcy5nZXRPckVsc2UodGhpcy54ZmFVdGlsKCkuJGRhdGEocGFydENoaWxkLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5YRkFfTU9ERUwpLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfTU9ERUwgKyAiLiIgKyB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5PQ0NVUlJFTkNFUywgMSkgPiAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzQ2hpbGRGaXJzdFNwbGl0ID0gKHRoaXMuZ2V0T3JFbHNlKHRoaXMueGZhVXRpbCgpLiRkYXRhKHBhcnRDaGlsZCwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMKSwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX01PREVMICsgIi4iICsgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuT0NDVVJfSU5ERVgsIDApID09IDApOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgJGNoaWxkQ2xvbmUgPSBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRIYXNTcGxpdCAmJiAhaXNDaGlsZEZpcnN0U3BsaXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3BsaXQgY2hpbGQgd291bGQgYWxyZWFkeSBiZWVuIGhhbmRsZWQgd2hlbiBpdCdzIGZpcnN0IHBhcnQgd2FzIGZvdW5kLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkSGFzU3BsaXQgJiYgaXNDaGlsZEZpcnN0U3BsaXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vSWYgdGhpcyBjaGlsZCBoYXMgc3BsaXQgYW5kIGl0IGlzIGZpcnN0IHBhcnQgb2YgdGhlIGNoaWxkIHNwbGl0LCBnZXQgdGhlIGVudGlyZSBzdGl0Y2hlZCBjaGlsZC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjaGlsZENsb25lID0gJCh0aGlzLmdldChjaGlsZElkLCB0cnVlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2hpbGRDbG9uZSA9ICQocGFydENoaWxkKS5jbG9uZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZFhmYU1vZGVsID0gdGhpcy54ZmFVdGlsKCkuJGRhdGEoJGNoaWxkQ2xvbmUuZ2V0KDApLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5YRkFfTU9ERUwpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGRYZmFNb2RlbCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbW9kaWZ5IHRoZSBleHRlbnR5IG9mIGNoaWxkIGFuZCB0aGVuIGFwcGVuZCB0aGlzIGNoaWxkIGNsb25lIHRvIGN1cnJlbnQgc3RpdGNoIHBhcnQgJG5vZGVEaXYKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkWGZhTW9kZWxbeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX01PREVMXVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5FWFRFTlRfWV0gPSBwYXJ0T2Zmc2V0WSArIHBhcnNlRmxvYXQodGhpcy5nZXRPckVsc2UoY2hpbGRYZmFNb2RlbFt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfTU9ERUxdW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9ZXSwgMCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNoaWxkQ2xvbmUuYXR0cigiZGF0YS0iICsgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMLCBKU09OLnN0cmluZ2lmeShjaGlsZFhmYU1vZGVsKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgJGNoaWxkQ2xvbmUuYXBwZW5kVG8oJG5vZGVEaXYpOwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgdGhpcwogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAvLyBtb2RpZnkgdGhlIGV4dGVudGggcGFydCAkbm9kZURpdgogICAgICAgICAgICAgICAgbm9kZVhmYU1vZGVsW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9NT0RFTF1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX0hdID0gcGFyc2VGbG9hdCh0aGlzLnhmYVV0aWwoKS4kZGF0YSgkc3BsaXRQYXJ0LmdldCgwKSwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMKVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfTU9ERUxdW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9IXSkgKyBwYXJ0T2Zmc2V0WTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYodGhpcy5jb250YWlucyhlbElkKSkgewogICAgICAgICAgICAgICAgaWYoXy5rZXlzKHRoaXMuX2NhY2hlW2VsSWRdKS5sZW5ndGggPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fY2FjaGVbZWxJZF1bIjAiXS5jbG9uZU5vZGUodHJ1ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBzdWJmb3JtIHdhcyBzcGxpdCBpbnRvIGRpZmZlcmVudCBwYXJ0cywgc3RpdGNoIGVhY2ggcGFydCBpbiBvcmRlciBvZiBvY2N1ckluZGV4CiAgICAgICAgICAgICAgICBmb3IgKHZhciBvY2N1ckluZGV4ID0gMDsgb2NjdXJJbmRleCA8IF8ua2V5cyh0aGlzLl9jYWNoZVtlbElkXSkubGVuZ3RoOyArK29jY3VySW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICAkc3BsaXRQYXJ0ID0gJCh0aGlzLl9jYWNoZVtlbElkXVtvY2N1ckluZGV4XSk7CiAgICAgICAgICAgICAgICAgICAgc3RpdGNoTm9kZXMuY2FsbCh0aGlzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoJG5vZGVEaXYgJiYgJG5vZGVEaXYuZ2V0KDApKSB7CiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgc3RpdGNoZWQgbm9kZSBpbiBjYWNoZSwgYWZ0ZXIgbW9kaWZ5aW5nIG9jY3VycmVuY2VzIGFuZCBvY2N1ciBpbmRleCB0byBtYWtlIGl0IGFwcGVhciBhcyB1bnNwbGl0CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2FjaGVbZWxJZF0gPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgICAgICAgbm9kZVhmYU1vZGVsW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9NT0RFTF1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuT0NDVVJSRU5DRVNdID0gIjEiOwogICAgICAgICAgICAgICAgICAgIG5vZGVYZmFNb2RlbFt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfTU9ERUxdW3hmYWxpYi52aWV3LkxheW91dENvbnN0Lk9DQ1VSX0lOREVYXSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKGxvb2tVcEhpZGRlbkNhY2hlKSB7CiAgICAgICAgICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faGlkZGVuT2JqUGFnZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICAkcGFnZURpdiA9ICQodGhpcy5faGlkZGVuT2JqUGFnZXNbaV0pOwogICAgICAgICAgICAgICAgICAgICRzcGxpdFBhcnQgPSAkcGFnZURpdi5maW5kKHRoaXMuanFJZChlbElkKSk7CiAgICAgICAgICAgICAgICAgICAgaWYoJHNwbGl0UGFydCAmJiAkc3BsaXRQYXJ0LmdldCgwKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0aXRjaE5vZGVzLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hpZGRlbk9ialBhZ2VzW2ldID0gJHBhZ2VEaXYuZ2V0KDApOyAvLyBjYWNoZSB0aGUgY29uc3RydWN0ZWQgcGFnZSBkb20gYmFjayBpbiBoaWRkZW4gb2JqZWN0cyBhcnJheSBpbiBjYXNlIHBhZ2Ugd2FzIHN0cmluZyBhcyBpdCBoYXBwZW5zIGZvciB0aGUgZmlyc3QgdGltZS4KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCRub2RlRGl2ICYmICRub2RlRGl2LmdldCgwKSkgewogICAgICAgICAgICAgICAgJG5vZGVEaXYuYXR0cigiZGF0YS0iICsgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMLCBKU09OLnN0cmluZ2lmeShub2RlWGZhTW9kZWwpKTsKICAgICAgICAgICAgICAgIHRoaXMucHV0KCRub2RlRGl2LmdldCgwKSk7ICAvL3B1dCBpdCBpbiB0aGUgY2FjaGUuCiAgICAgICAgICAgICAgICByZXR1cm4gJG5vZGVEaXYuZ2V0KDApLmNsb25lTm9kZSh0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgc2V0SGlkZGVuT2JqUGFnZXMgOiBmdW5jdGlvbihoaWRkZW5QYWdlcyl7CiAgICAgICAgICAgIHRoaXMuX2hpZGRlbk9ialBhZ2VzID0gaGlkZGVuUGFnZXMgfHwgW107CiAgICAgICAgfSwKCiAgICAgICAgX2NhY2hlQ2hpbGRyZW4gOiBmdW5jdGlvbihwYXJlbnQpewogICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgICQocGFyZW50KS5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIC8vY2FjaGUgeGZhIHN1YiBlbGVtZW50cyBhcyB3ZWxsLgogICAgICAgICAgICAgICAgaWYodGhhdC5nZXRPckVsc2UodGhhdC54ZmFVdGlsKCkuJGRhdGEodGhpcywgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMKSwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTk9ERV9UWVBFLCAiIikubGVuZ3RoID4gMCl7CiAgICAgICAgICAgICAgICAgICAgdGhhdC5wdXQodGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXyx4ZmFsaWIpIHsKICAgIHZhciBDb25zdGFudHMgPSB7CiAgICAgICAgWEZBX01PREVMIDogIngiLAogICAgICAgIE5PREVfVFlQRSA6ICJ0IiwKICAgICAgICBMQVlPVVRfTU9ERUw6ICJsIiwKICAgICAgICBTVUJGT1JNX0xBWU9VVDogInNsIiwKICAgICAgICBFWFRFTlRfWCA6ICJ4IiwKICAgICAgICBFWFRFTlRfWSA6ICJ5IiwKICAgICAgICBFWFRFTlRfVyA6ICJ3IiwKICAgICAgICBFWFRFTlRfSCA6ICJoIiwKICAgICAgICBFWFRFTlRfTUlOX0ggOiAibmgiLAogICAgICAgIEVYVEVOVF9NSU5fVyA6ICJudyIsCiAgICAgICAgRVhURU5UX01BWF9IIDogInhoIiwKICAgICAgICBFWFRFTlRfTUFYX1cgOiAieHciLAogICAgICAgIEVYVEVOVF9BQ1RVQUxfSCA6ICJhaCIsCiAgICAgICAgRVhURU5UX0FDVFVBTF9XIDogImF3IiwKICAgICAgICBNQVJHSU5fVE9QIDogInQiLAogICAgICAgIE1BUkdJTl9MRUZUIDogImwiLAogICAgICAgIE1BUkdJTl9CT1RUT00gOiAiYiIsCiAgICAgICAgTUFSR0lOX1JJR0hUIDogInIiLAoKICAgICAgICBCT1JERVJfVE9QIDogImJ0IiwKICAgICAgICBCT1JERVJfTEVGVCA6ICJibCIsCiAgICAgICAgQk9SREVSX0JPVFRPTSA6ICJiYiIsCiAgICAgICAgQk9SREVSX1JJR0hUIDogImJyIiwKCiAgICAgICAgQ09MX1NQQU4gOiAiYyIsCiAgICAgICAgUk9XX1NQQU4gOiAicnMiLAogICAgICAgIE9DQ1VSUkVOQ0VTIDogIm8iLAogICAgICAgIE9DQ1VSX0lOREVYOiAiaSIsCiAgICAgICAgQ09MVU1OX1dJRFRIUyA6ICJjdyIsCiAgICAgICAgUEFHRV9OVU1CRVI6ICJwbiIsCiAgICAgICAgQ0FQX1BMQUNFTUVOVCA6ICJwIiwKICAgICAgICBMQVlPVVRfTEVGVFJJR0hUVE9QQk9UVE9NIDogImxyIiwKICAgICAgICBMQVlPVVRfUklHSFRMRUZUVE9QQk9UVE9NIDogInJsIiwKICAgICAgICBMQVlPVVRfVE9QQk9UVE9NIDogInRiIiwKICAgICAgICBMQVlPVVRfVEFCTEUgOiAidCIsCiAgICAgICAgTEFZT1VUX1JPVyA6ICJyIiwKICAgICAgICBMQVlPVVRfUklHSFRMRUZUUk9XIDogInJyIiwKICAgICAgICBMQVlPVVRfREFUQVRBQkxFIDogImR0IgogICAgfTsKICAgIHhmYWxpYi52aWV3LkxheW91dENvbnN0ID0gQ29uc3RhbnRzOwp9KShfLHhmYWxpYik7CihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgdmFyIExheW91dEJhc2UgPSB4ZmFsaWIudmlldy5sYXlvdXQuTGF5b3V0QmFzZSA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudXQuQ2xhc3MucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5fbGF5b3V0TWFuYWdlciA9IHRoaXMuX3hmYVZpZXdSZWdpc3RyeSgpLmxheW91dE1hbmFnZXIoKTsKICAgICAgICAgICAgdGhpcy50YXJnZXQgPSB0aGlzLm9wdGlvbnMudGFyZ2V0OyAvL0NvbnRhaW5lclZpZXcgaW5zdGFuY2UKICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25pbmdDc3NQcm9wZXJ0eVggPSAibGVmdCI7CiAgICAgICAgICAgIHRoaXMuX3Bvc2l0aW9uaW5nQ3NzUHJvcGVydHlZID0gInRvcCI7CiAgICAgICAgfSwKCiAgICAgICAgbWVhc3VyZVNpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4geGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLm1lYXN1cmVTaXplLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIGludmFsaWRhdGVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5pbnZhbGlkYXRlU2l6ZS5hcHBseSh0aGlzLnRhcmdldCwgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICB1cGRhdGVEaXNwbGF5IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLnVwZGF0ZURpc3BsYXkuYXBwbHkodGhpcy50YXJnZXQsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIF8uZWFjaCh0aGlzLnRhcmdldC5fbm9ybWFsaXplZENoaWxkVmlld3MoKSwgZnVuY3Rpb24oY2hpbGRWaWV3LCBpbmRleCl7CiAgICAgICAgICAgICAgICB2YXIgZXh0ZW50ID0ge307CiAgICAgICAgICAgICAgICBleHRlbnRbdGhpcy5fcG9zaXRpb25pbmdDc3NQcm9wZXJ0eVhdID0gIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHg7CiAgICAgICAgICAgICAgICBleHRlbnRbdGhpcy5fcG9zaXRpb25pbmdDc3NQcm9wZXJ0eVldID0gIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHk7CiAgICAgICAgICAgICAgICB0aGlzLiRjc3MoY2hpbGRWaWV3LmVsLCBleHRlbnQpOwogICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICB9LAoKICAgICAgICBfdGFyZ2V0UGFkZGluZ1ggOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy50YXJnZXQuX3BhZExlZnQoKTsKICAgICAgICB9LAoKICAgICAgICBfdGFyZ2V0UGFkZGluZ1kgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy50YXJnZXQuX3BhZFRvcCgpOwogICAgICAgIH0sCgogICAgICAgICRkYXRhIDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLiRkYXRhLAoKICAgICAgICAkY3NzIDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLiRjc3MsCgogICAgICAgIF94ZmFWaWV3UmVnaXN0cnkgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy54ZmFWaWV3UmVnaXN0cnk7ICAgIC8vVE9ETzogcmVtb3ZlIHdpbmRvdyBkZXBlbmRlbmN5CiAgICAgICAgfQoKICAgIH0pCgp9KShfLCAkLCB4ZmFsaWIpOwoKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgeGZhbGliLnZpZXcubGF5b3V0LlBvc2l0aW9uTGF5b3V0ID0geGZhbGliLnZpZXcubGF5b3V0LkxheW91dEJhc2UuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnZpZXcubGF5b3V0LkxheW91dEJhc2UucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBtZWFzdXJlU2l6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciBsYXlvdXRNb2RlbCA9IHRoaXMudGFyZ2V0LmxheW91dE1vZGVsOwogICAgICAgICAgICB2YXIgcGFyZW50UGFkTGVmdCA9IHRoaXMuX3RhcmdldFBhZGRpbmdYKCk7CiAgICAgICAgICAgIHZhciBwYXJlbnRQYWRUb3AgPSB0aGlzLl90YXJnZXRQYWRkaW5nWSgpOwogICAgICAgICAgICB2YXIgb2xkRXh0ZW50VyA9IGxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgIHZhciBvbGRFeHRlbnRIID0gbGF5b3V0TW9kZWwuZXh0ZW50aDsKICAgICAgICAgICAgdmFyIGNvbnRhaW5lclcgPSAwOwogICAgICAgICAgICB2YXIgY29udGFpbmVySCA9IDA7CiAgICAgICAgICAgIF8uZWFjaCh0aGlzLnRhcmdldC5fbm9ybWFsaXplZENoaWxkVmlld3MoKSwgZnVuY3Rpb24oY2hpbGRWaWV3LCBpbmRleCl7CgogICAgICAgICAgICAgICAgY2hpbGRWaWV3LmxheW91dE1vZGVsLm1lYXN1cmVkeCA9ICBwYXJlbnRQYWRMZWZ0ICsgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHg7CiAgICAgICAgICAgICAgICBjaGlsZFZpZXcubGF5b3V0TW9kZWwubWVhc3VyZWR5ID0gIHBhcmVudFBhZFRvcCArIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnR5OwogICAgICAgICAgICAgICAgaWYoY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHggKyBjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50dyA+IGNvbnRhaW5lclcpCiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyVyA9IGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnR4ICsgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgICAgICBpZihjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50eSArIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnRoID4gY29udGFpbmVySCkKICAgICAgICAgICAgICAgICAgICBjb250YWluZXJIID0gY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHkgKyBjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50aDsKICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICBpZihsYXlvdXRNb2RlbC5leHRlbnRhY3R1YWx3IDwgMCl7CiAgICAgICAgICAgICAgICB2YXIgcGFyZW50RXh0ZW50VyA9IGxheW91dE1vZGVsLm1hcmdpbmxlZnQgKyBjb250YWluZXJXICsgbGF5b3V0TW9kZWwubWFyZ2lucmlnaHQ7CiAgICAgICAgICAgICAgICBsYXlvdXRNb2RlbC5leHRlbnR3ID0gcGFyZW50RXh0ZW50VzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihsYXlvdXRNb2RlbC5leHRlbnRhY3R1YWxoIDwgMCl7CiAgICAgICAgICAgICAgICB2YXIgcGFyZW50RXh0ZW50SCA9IGxheW91dE1vZGVsLm1hcmdpbnRvcCArIGNvbnRhaW5lckggKyBsYXlvdXRNb2RlbC5tYXJnaW5ib3R0b207CiAgICAgICAgICAgICAgICBsYXlvdXRNb2RlbC5leHRlbnRoID0gcGFyZW50RXh0ZW50SDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYob2xkRXh0ZW50VyAhPSBsYXlvdXRNb2RlbC5leHRlbnR3IHx8IG9sZEV4dGVudEggIT0gbGF5b3V0TW9kZWwuZXh0ZW50aCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KQp9KShfLCAkLCB4ZmFsaWIpOwoKCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LmxheW91dC5MZWZ0UmlnaHRMYXlvdXQgPSB4ZmFsaWIudmlldy5sYXlvdXQuTGF5b3V0QmFzZS5leHRlbmQoewogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5sYXlvdXQuTGF5b3V0QmFzZS5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIG1lYXN1cmVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIGxheW91dE1vZGVsID0gdGhpcy50YXJnZXQubGF5b3V0TW9kZWw7CiAgICAgICAgICAgIHZhciBwYXJlbnRQYWRYID0gdGhpcy5fdGFyZ2V0UGFkZGluZ1goKTsKICAgICAgICAgICAgdmFyIHBhcmVudFBhZFkgPSB0aGlzLl90YXJnZXRQYWRkaW5nWSgpOwogICAgICAgICAgICB2YXIgb2xkRXh0ZW50VyA9IGxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgIHZhciBvbGRFeHRlbnRIID0gbGF5b3V0TW9kZWwuZXh0ZW50aDsKICAgICAgICAgICAgdmFyIHBhcmVudENvbnRlbnRXaWR0aCAgPSAgbGF5b3V0TW9kZWwuZXh0ZW50dyAtIGxheW91dE1vZGVsLm1hcmdpbmxlZnQgLSBsYXlvdXRNb2RlbC5tYXJnaW5yaWdodCArIHRoaXMuX2xheW91dE1hbmFnZXIuTEFZT1VUX0VSUk9SX01BUkdJTjsKICAgICAgICAgICAgaWYobGF5b3V0TW9kZWwuZXh0ZW50YWN0dWFsdyA8IDApewogICAgICAgICAgICAgICAgcGFyZW50Q29udGVudFdpZHRoID0gMTAwMDAwMDsgLy9BcmJpdHJhcnkgbGltaXRhdGlvbiBmb3IgbWF4IHdpZHRoLiBDb3VsZCBiZSBNQVhfVkFMVUUsIGJ1dCB0aGF0IG1heSBiZSBjb3N0bHk/CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBjdXJyZW50WCA9ICAwOy8vUmlnaHQgb2YgdGhlIGxhc3QgZWxlbWVudAogICAgICAgICAgICB2YXIgY3VycmVudExpbmVZID0gMDsKICAgICAgICAgICAgdmFyIGxpbmVIZWlnaHQgPSAwOyAvL0xpbmUgSGVpZ2h0IGZvciBjdXJyZW50IGxpbmUKICAgICAgICAgICAgXy5lYWNoKHRoaXMudGFyZ2V0Ll9ub3JtYWxpemVkQ2hpbGRWaWV3cygpLCBmdW5jdGlvbihjaGlsZFZpZXcsIGluZGV4KXsKICAgICAgICAgICAgICAgIGlmKGN1cnJlbnRYICsgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHcgPiBwYXJlbnRDb250ZW50V2lkdGgpewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRYID0gMDsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50TGluZVkgPSBjdXJyZW50TGluZVkgKyBsaW5lSGVpZ2h0OwogICAgICAgICAgICAgICAgICAgIGxpbmVIZWlnaHQgPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2hpbGRWaWV3LmxheW91dE1vZGVsLm1lYXN1cmVkeCA9ICBwYXJlbnRQYWRYICsgY3VycmVudFg7CiAgICAgICAgICAgICAgICBjaGlsZFZpZXcubGF5b3V0TW9kZWwubWVhc3VyZWR5ID0gcGFyZW50UGFkWSArIGN1cnJlbnRMaW5lWTsKICAgICAgICAgICAgICAgIGlmKGxpbmVIZWlnaHQgPCBjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50aCl7CiAgICAgICAgICAgICAgICAgICAgbGluZUhlaWdodCA9IGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy91cGRhdGUgdG9wIHZhcmlhYmxlcyBmb3Igc2Vjb25kIGVsZW1lbnQKICAgICAgICAgICAgICAgIGN1cnJlbnRYID0gY3VycmVudFggKyAgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICBpZihsYXlvdXRNb2RlbC5leHRlbnRhY3R1YWx3IDwgMCkgewogICAgICAgICAgICAgICAgdmFyIHBhcmVudEV4dGVudFcgPSBsYXlvdXRNb2RlbC5tYXJnaW5sZWZ0ICsgY3VycmVudFggKyBsYXlvdXRNb2RlbC5tYXJnaW5yaWdodDsKICAgICAgICAgICAgICAgIGxheW91dE1vZGVsLmV4dGVudHcgPSBwYXJlbnRFeHRlbnRXOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKGxheW91dE1vZGVsLmV4dGVudGFjdHVhbGggPCAwKSB7CiAgICAgICAgICAgICAgICB2YXIgcGFyZW50RXh0ZW50SCA9IGxheW91dE1vZGVsLm1hcmdpbnRvcCArIGN1cnJlbnRMaW5lWSArIGxpbmVIZWlnaHQgKyBsYXlvdXRNb2RlbC5tYXJnaW5ib3R0b207CiAgICAgICAgICAgICAgICBsYXlvdXRNb2RlbC5leHRlbnRoID0gcGFyZW50RXh0ZW50SDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYob2xkRXh0ZW50VyAhPSBsYXlvdXRNb2RlbC5leHRlbnR3IHx8IG9sZEV4dGVudEggIT0gbGF5b3V0TW9kZWwuZXh0ZW50aCl7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pCn0pKF8sICQsIHhmYWxpYik7CgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LmxheW91dC5SaWdodExlZnRMYXlvdXQgPSB4ZmFsaWIudmlldy5sYXlvdXQuTGVmdFJpZ2h0TGF5b3V0LmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LmxheW91dC5MZWZ0UmlnaHRMYXlvdXQucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25pbmdDc3NQcm9wZXJ0eVggPSAicmlnaHQiOwogICAgICAgICAgICB0aGlzLl9wb3NpdGlvbmluZ0Nzc1Byb3BlcnR5WSA9ICJ0b3AiOwogICAgICAgIH0sCgogICAgICAgIF90YXJnZXRQYWRkaW5nWCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnRhcmdldC5fcGFkUmlnaHQoKTsKICAgICAgICB9LAoKICAgICAgICBfdGFyZ2V0UGFkZGluZ1kgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy50YXJnZXQuX3BhZFRvcCgpOwogICAgICAgIH0KCiAgICB9KQp9KShfLCAkLCB4ZmFsaWIpOwoKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgeGZhbGliLnZpZXcubGF5b3V0LlRvcEJvdHRvbUxheW91dCA9IHhmYWxpYi52aWV3LmxheW91dC5MYXlvdXRCYXNlLmV4dGVuZCh7CgogICAgICAgIG1lYXN1cmVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIGxheW91dE1vZGVsID0gdGhpcy50YXJnZXQubGF5b3V0TW9kZWw7CiAgICAgICAgICAgIHZhciBwYXJlbnRQYWRMZWZ0ID0gdGhpcy5fdGFyZ2V0UGFkZGluZ1goKTsKICAgICAgICAgICAgdmFyIHBhcmVudFBhZFRvcCA9IHRoaXMuX3RhcmdldFBhZGRpbmdZKCk7CiAgICAgICAgICAgIHZhciBvbGRFeHRlbnRXID0gbGF5b3V0TW9kZWwuZXh0ZW50dzsKICAgICAgICAgICAgdmFyIG9sZEV4dGVudEggPSBsYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICB2YXIgY29udGFpbmVyVyA9IDA7CiAgICAgICAgICAgIHZhciBjdXJyZW50TGluZVkgID0gIDA7CiAgICAgICAgICAgIF8uZWFjaCh0aGlzLnRhcmdldC5fbm9ybWFsaXplZENoaWxkVmlld3MoKSwgZnVuY3Rpb24oY2hpbGRWaWV3LCBpbmRleCl7CiAgICAgICAgICAgICAgICBjaGlsZFZpZXcubGF5b3V0TW9kZWwubWVhc3VyZWR4ID0gcGFyZW50UGFkTGVmdDsKICAgICAgICAgICAgICAgIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHkgPSAgcGFyZW50UGFkVG9wICsgY3VycmVudExpbmVZOwogICAgICAgICAgICAgICAgaWYoY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHcgPiBjb250YWluZXJXKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyVyA9IGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnR3OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy91cGRhdGUgY3VycmVudExpbmVZIHZhcmlhYmxlcyBmb3Igc2Vjb25kIGVsZW1lbnQKICAgICAgICAgICAgICAgIGN1cnJlbnRMaW5lWSA9IGN1cnJlbnRMaW5lWSArIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgIGlmKGxheW91dE1vZGVsLmV4dGVudGFjdHVhbHcgPCAwKXsKICAgICAgICAgICAgICAgIHZhciBwYXJlbnRFeHRlbnRXID0gbGF5b3V0TW9kZWwubWFyZ2lubGVmdCArIGNvbnRhaW5lclcgKyBsYXlvdXRNb2RlbC5tYXJnaW5yaWdodDsKICAgICAgICAgICAgICAgIGxheW91dE1vZGVsLmV4dGVudHcgPSBwYXJlbnRFeHRlbnRXOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKGxheW91dE1vZGVsLmV4dGVudGFjdHVhbGggPCAwKXsKICAgICAgICAgICAgICAgIHZhciBwYXJlbnRFeHRlbnRIID0gbGF5b3V0TW9kZWwubWFyZ2ludG9wICsgY3VycmVudExpbmVZICsgbGF5b3V0TW9kZWwubWFyZ2luYm90dG9tOwogICAgICAgICAgICAgICAgbGF5b3V0TW9kZWwuZXh0ZW50aCA9IHBhcmVudEV4dGVudEg7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKG9sZEV4dGVudFcgIT0gbGF5b3V0TW9kZWwuZXh0ZW50dyB8fCBvbGRFeHRlbnRIICE9IGxheW91dE1vZGVsLmV4dGVudGgpewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSkKfSkoXywgJCwgeGZhbGliKTsKCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LmxheW91dC5Sb3dMYXlvdXQgPSB4ZmFsaWIudmlldy5sYXlvdXQuTGF5b3V0QmFzZS5leHRlbmQoewogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5sYXlvdXQuTGF5b3V0QmFzZS5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIG1lYXN1cmVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIGxheW91dE1vZGVsID0gdGhpcy50YXJnZXQubGF5b3V0TW9kZWw7CiAgICAgICAgICAgIHZhciBsaW5lSGVpZ2h0ID0gMDsgLy9MaW5lIEhlaWdodCBmb3IgY3VycmVudCBsaW5lCiAgICAgICAgICAgIF8uZWFjaCh0aGlzLnRhcmdldC5fbm9ybWFsaXplZENoaWxkVmlld3MoKSwgZnVuY3Rpb24oY2hpbGRWaWV3LCBpbmRleCl7Ci8vICAgICAgICAgICAgICAgIGlmKGNoaWxkVmlldy5tb2RlbCAmJiBjaGlsZFZpZXcubW9kZWwuY2xhc3NOYW1lID09ICJkcmF3IikgICAgICAvL0RyYXcgdGFibGUgY2VsbHMgYXJlIHNldCB0byAxMDAlIHNpemVzLiBUaGV5IGNhbiBub3QgZ3Jvdy4gSWYgbW92ZWQsIHRoZXknbGwgb3ZlcmxheSBib3JkZXIKLy8gICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIGlmKGxpbmVIZWlnaHQgPCBjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50aCl7CiAgICAgICAgICAgICAgICAgICAgbGluZUhlaWdodCA9IGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgLy9TZXQgZXh0ZW50aCBmb3IgYWxsIHJvdyBjZWxscwogICAgICAgICAgICBfLmVhY2godGhpcy50YXJnZXQuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uKGNoaWxkVmlldywgaW5kZXgpewogICAgICAgICAgICAgICAgaWYoY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudGggIT0gbGluZUhlaWdodCl7CiAgICAgICAgICAgICAgICAgICAgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudGggPSBsaW5lSGVpZ2h0OwogICAgICAgICAgICAgICAgICAgIGNoaWxkVmlldy5pbnZhbGlkYXRlRGlzcGxheSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgIGxheW91dE1vZGVsLmV4dGVudGggPSBsYXlvdXRNb2RlbC5tYXJnaW50b3AgKyBsaW5lSGVpZ2h0ICsgbGF5b3V0TW9kZWwubWFyZ2luYm90dG9tOwoKICAgICAgICAgICAgLy9pbiBjYXNlIG9mIHJvd0xheW91dCBtZWFzdXJlIHdvdWxkIGFsd2F5cyByZXR1cm4gdHJ1ZSB3aGljaCBtZWFucwogICAgICAgICAgICAvLyBsYXlvdXQgYWxnbyBvZiB0YWJsZSB3b3VsZCBhbHdheXMgYmUgdHJpZ2dlcmVkIGFzIHJvdyBkb2VzIG5vdCBoYXZlIGVub3VnaCBkYXRhIHRvIGNvbXB1dGUgaWYgYW55IGNvbHVtbiB3aWR0aCBjaGFuZ2VkCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICB9KQp9KShfLCAkLCB4ZmFsaWIpOwoKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgeGZhbGliLnZpZXcubGF5b3V0LkRhdGFUYWJsZVJvd0xheW91dCA9IHhmYWxpYi52aWV3LmxheW91dC5Sb3dMYXlvdXQuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnZpZXcubGF5b3V0LlJvd0xheW91dC5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIG1lYXN1cmVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgLy9pbiBjYXNlIG9mIHJvd0xheW91dCBtZWFzdXJlIHdvdWxkIGFsd2F5cyByZXR1cm4gdHJ1ZSB3aGljaCBtZWFucwogICAgICAgICAgICAvLyBsYXlvdXQgYWxnbyBvZiB0YWJsZSB3b3VsZCBhbHdheXMgYmUgdHJpZ2dlcmVkIGFzIHJvdyBkb2VzIG5vdCBoYXZlIGVub3VnaCBkYXRhIHRvIGNvbXB1dGUgaWYgYW55IGNvbHVtbiB3aWR0aCBjaGFuZ2VkCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0sCgogICAgICAgIHVwZGF0ZURpc3BsYXkgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5sYXlvdXQuUm93TGF5b3V0LnByb3RvdHlwZS51cGRhdGVEaXNwbGF5LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLnRhcmdldC5lbCwgeyJwb3NpdGlvbiI6InJlbGF0aXZlIn0pOwogICAgICAgICAgICBfLmVhY2godGhpcy50YXJnZXQuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uKGNoaWxkVmlldyl7CiAgICAgICAgICAgICAgICB2YXIgZXh0ZW50ID0ge307CiAgICAgICAgICAgICAgICBleHRlbnRbInBvc2l0aW9uIl0gPSAgInJlbGF0aXZlIjsKICAgICAgICAgICAgICAgIHRoaXMuJGNzcyhjaGlsZFZpZXcuZWwsIGV4dGVudCk7CiAgICAgICAgICAgICAgICBpZihjaGlsZFZpZXcubGF5b3V0TW9kZWwuYm9yZGVybGVmdCA+IDIpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3MoY2hpbGRWaWV3LmVsLCB7ImJvcmRlci1sZWZ0LXdpZHRoIjpjaGlsZFZpZXcubGF5b3V0TW9kZWwuYm9yZGVybGVmdC8yLjB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGNoaWxkVmlldy5sYXlvdXRNb2RlbC5ib3JkZXJ0b3AgPiAyKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKGNoaWxkVmlldy5lbCwgeyAiYm9yZGVyLXRvcC13aWR0aCI6Y2hpbGRWaWV3LmxheW91dE1vZGVsLmJvcmRlcnRvcC8yLjB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGNoaWxkVmlldy5sYXlvdXRNb2RlbC5ib3JkZXJib3R0b20gPiAyKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKGNoaWxkVmlldy5lbCwgeyJib3JkZXItYm90dG9tLXdpZHRoIjpjaGlsZFZpZXcubGF5b3V0TW9kZWwuYm9yZGVyYm90dG9tLzIuMH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYoY2hpbGRWaWV3LmxheW91dE1vZGVsLmJvcmRlcnJpZ2h0ID4gMikgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyhjaGlsZFZpZXcuZWwsIHsiYm9yZGVyLXJpZ2h0LXdpZHRoIjpjaGlsZFZpZXcubGF5b3V0TW9kZWwuYm9yZGVycmlnaHQvMi4wfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIHRoaXMpOwoKICAgICAgICB9CiAgICB9KQp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LmxheW91dC5SaWdodExlZnRSb3dMYXlvdXQgPSB4ZmFsaWIudmlldy5sYXlvdXQuUm93TGF5b3V0LmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LmxheW91dC5Sb3dMYXlvdXQucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25pbmdDc3NQcm9wZXJ0eVggPSAicmlnaHQiOwogICAgICAgICAgICB0aGlzLl9wb3NpdGlvbmluZ0Nzc1Byb3BlcnR5WSA9ICJ0b3AiOwogICAgICAgIH0sCgogICAgICAgIF90YXJnZXRQYWRkaW5nWCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybiB0aGlzLnRhcmdldC5fcGFkUmlnaHQoKTsKICAgICAgICB9LAoKICAgICAgICBfdGFyZ2V0UGFkZGluZ1kgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy50YXJnZXQuX3BhZFRvcCgpOwogICAgICAgIH0KICAgIH0pCn0pKF8sICQsIHhmYWxpYik7CgoKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgeGZhbGliLnZpZXcubGF5b3V0LlRhYmxlTGF5b3V0ID0geGZhbGliLnZpZXcubGF5b3V0LkxheW91dEJhc2UuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnZpZXcubGF5b3V0LkxheW91dEJhc2UucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5fdGFibGVDZWxsR3JpZCA9IFsgW10gXTsKICAgICAgICAgICAgdGhpcy5hc3NpZ25lZENvbFdpZHRocyA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMudGFyZ2V0LmxheW91dE1vZGVsLmNvbHVtbndpZHRocywgW10pOwogICAgICAgICAgICB0aGlzLl9jb2x1bW5XaWR0aHMgPSB0aGlzLmFzc2lnbmVkQ29sV2lkdGhzLnNsaWNlKCk7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogUmV0dXJucyB0aGUgUm93cyBpbiB0aGUgdGFibGUgYnkgZmlsdGVyaW5nIG91dCByb3dzIGZyb20gYWxsIHRoZSBjaGlsZCB2aWV3cwogICAgICAgICAqIEByZXR1cm5zIEFycmF5IGNvbnRhaW5pbmcgdGhlIGNoaWxkIHZpZXdzIHRoYXQgYXJlIHJvd3MKICAgICAgICAgKiBAcHJpdmF0ZQogICAgICAgICAqLwogICAgICAgIF9nZXRSb3dzIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gXy5maWx0ZXIodGhpcy50YXJnZXQuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uIChjaGlsZFZpZXcpIHsKICAgICAgICAgICAgICAgIGlmIChjaGlsZFZpZXcubGF5b3V0TW9kZWwubGF5b3V0ID09IHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9ST1cKICAgICAgICAgICAgICAgICAgICAgICAgfHwgY2hpbGRWaWV3LmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUklHSFRMRUZUUk9XKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgfSwKCiAgICAgICAgbWVhc3VyZVNpemUgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBsYXlvdXRNb2RlbCA9IHRoaXMudGFyZ2V0LmxheW91dE1vZGVsLAogICAgICAgICAgICAgICAgcm93Vmlld3MgPSB0aGlzLl9nZXRSb3dzKCk7CgogICAgICAgICAgICB0aGlzLl92YWxpZENlbGxzSW5Sb3cocm93Vmlld3MpOwoKICAgICAgICAgICAgXy5lYWNoKHJvd1ZpZXdzLCBmdW5jdGlvbihyb3dWaWV3LCByb3dJbmRleCl7CiAgICAgICAgICAgICAgICBfLmVhY2gocm93Vmlldy5fbm9ybWFsaXplZENoaWxkVmlld3MoKSwgZnVuY3Rpb24oY2VsbFZpZXcpewogICAgICAgICAgICAgICAgICAgIHZhciBjZWxsTGF5b3V0ID0gY2VsbFZpZXcubGF5b3V0TW9kZWw7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbHNwYW4gPSB0aGlzLmdldE9yRWxzZShjZWxsTGF5b3V0LmNvbHNwYW4sIDEpOwogICAgICAgICAgICAgICAgICAgIGlmKGNvbHNwYW4gPT0gLTEpCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbHNwYW4gPSB0aGlzLl90YWJsZUNlbGxHcmlkLmxlbmd0aCAtIGNlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleDsgLy9pZiBjb2xwYW4gaXMgLTEsIHRoZW4gc2V0IGl0IHRvIHJlbWFpbmluZyBncmlkIGxlbmd0aAogICAgICAgICAgICAgICAgICAgIHZhciBsYXN0Q2VsbEluZGV4ID0gY2VsbFZpZXcuZWZmZWN0aXZlQ2VsbEluZGV4ICsgY29sc3BhbiAtMTsKCiAgICAgICAgICAgICAgICAgICAgaWYoIXRoaXMuX3RhYmxlQ2VsbEdyaWRbbGFzdENlbGxJbmRleF0pewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbGFzdE5vbkVtcHR5Q29sSW5kZXggPSAtMTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBqID0gbGFzdENlbGxJbmRleDsgaj49MDsgai0tICl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLl90YWJsZUNlbGxHcmlkW2pdKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0Tm9uRW1wdHlDb2xJbmRleCA9IGo7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLy9sYXN0Tm9uRW1wdHlDb2xJbmRleCBjYW4gbm90IGJlIC0xIGhlcmUuIHNpbmNlIGl0IHNob3VsZCBiZSBhdCBsZWFzdCAwCiAgICAgICAgICAgICAgICAgICAgICAgIC8vTm93IGNvcHkgZmlsbCBhbGwgcHJldmlvdXMgbWlzc2luZyBjb2x1bW4gZGF0YSB3aXRoIGxhc3ROb25FbXB0eUNvbCBkYXRhCiAgICAgICAgICAgICAgICAgICAgICAgIGZvcih2YXIgayA9IGxhc3ROb25FbXB0eUNvbEluZGV4ICsgMTsgayA8PSBsYXN0Q2VsbEluZGV4IDsgaysrKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3RhYmxlQ2VsbEdyaWRba10gPSB0aGlzLl90YWJsZUNlbGxHcmlkW2stMV0uc3BsaWNlKCkgOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8vTm93IGFkZCBjdXJyZW50Q2VsbFZpZXcgdG8gcHJvcGVyIGxvY2F0aW9uIGluIGNlbGwgZ3JpZAogICAgICAgICAgICAgICAgICAgIGZvcih2YXIgaSA9IGNlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleDsgaSA8PSBsYXN0Q2VsbEluZGV4OyAgaSsrKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGFibGVDZWxsR3JpZFtpXVtyb3dJbmRleF0gPSBjZWxsVmlldzsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuYXNzaWduZWRDb2xXaWR0aHNbY2VsbFZpZXcuZWZmZWN0aXZlQ2VsbEluZGV4XSA+IC0xKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29sdW1uV2lkdGhzW2NlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleF0gPSB0aGlzLmFzc2lnbmVkQ29sV2lkdGhzW2NlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleF07CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih0aGlzLmdldE9yRWxzZShjZWxsTGF5b3V0LmNvbHNwYW4sIDEpID09IDEpeyAvLyB1c2UgYWN0dWFsIGNvbHNwYW4KICAgICAgICAgICAgICAgICAgICAgICAgLy9UT0RPOmNoZWNrIGlmIHRhYmxlQ2VsbEluZGV4IG1haW50YWluZWQgcHJvcGVybHkKICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2VsbExheW91dC5leHRlbnR3ID4gKHRoaXMuX2NvbHVtbldpZHRoc1tjZWxsVmlldy5lZmZlY3RpdmVDZWxsSW5kZXhdIHx8IDApKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29sdW1uV2lkdGhzW2NlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleF0gID0gY2VsbExheW91dC5leHRlbnR3OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgIC8vQWRkaXRpb25hbCBwYXNzIHRvIGFkanVzdCBjb2x1bW5XaWR0aHMgZm9yIGNvbHVtbnMgd2l0aCBjb2xwc2FuID4gMQogICAgICAgICAgICBfLmVhY2godGhpcy5fdGFibGVDZWxsR3JpZCwgZnVuY3Rpb24oY29sdW1uQ2VsbHMsIGNvbEluZGV4KXsKICAgICAgICAgICAgICAgIGlmKHRoaXMuYXNzaWduZWRDb2xXaWR0aHNbY29sSW5kZXhdID4gLTEpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgdmFyIGNvbFdpZHRoID0gdGhpcy5fY29sdW1uV2lkdGhzW2NvbEluZGV4XTsKICAgICAgICAgICAgICAgIF8uZWFjaChjb2x1bW5DZWxscywgZnVuY3Rpb24oY2VsbFZpZXcpewogICAgICAgICAgICAgICAgICAgIHZhciBjb2xzcGFuID0gdGhpcy5nZXRPckVsc2UoY2VsbFZpZXcubGF5b3V0TW9kZWwuY29sc3BhbiwgIjEiKTsKICAgICAgICAgICAgICAgICAgICBpZihjb2xzcGFuID09IC0xKQogICAgICAgICAgICAgICAgICAgICAgICBjb2xzcGFuID0gdGhpcy5fdGFibGVDZWxsR3JpZC5sZW5ndGggLSBjZWxsVmlldy5lZmZlY3RpdmVDZWxsSW5kZXg7CiAgICAgICAgICAgICAgICAgICAgLy9JZiBjb2xzcGFuIGlzIG9uZSwgd2UgaGF2ZSBhbHJlYWR5IHRha2VuIGNhcmUuIGlmIHRoaXMgY2VsbCBzdGlsbCBleHRlbmRzIGJleW9uZCB0aGlzIGNvbHVtbiwgd2UnbGwgaGFuZGxlIGl0IGxhdGVyCiAgICAgICAgICAgICAgICAgICAgaWYoIGNvbHNwYW4gPT0gMSB8fCAoKGNlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleCArIGNvbHNwYW4gLTEpICE9IGNvbEluZGV4KSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIC8vRm9yIHNwYW5uZWQgY29sdW1uLCBjb21wdXRlIHRoZSB3aXRoIG9mIHRoZSBjZWxsIHRoYXQgbGllcyBpbiB0aGlzIGNsb3Vtbi4KICAgICAgICAgICAgICAgICAgICB2YXIgc3Bhbm5lZENvbFdpZHRoID0gY2VsbFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50dzsKICAgICAgICAgICAgICAgICAgICBmb3IodmFyIGwgPSBjZWxsVmlldy5lZmZlY3RpdmVDZWxsSW5kZXg7IGwgPCBjb2xJbmRleDsgbCsrKXsKICAgICAgICAgICAgICAgICAgICAgICAgc3Bhbm5lZENvbFdpZHRoID0gc3Bhbm5lZENvbFdpZHRoIC0gdGhpcy5fY29sdW1uV2lkdGhzW2xdOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZihzcGFubmVkQ29sV2lkdGggPiB0aGlzLl9jb2x1bW5XaWR0aHNbY29sSW5kZXhdKQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jb2x1bW5XaWR0aHNbY29sSW5kZXhdID0gc3Bhbm5lZENvbFdpZHRoOwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgIH0sIHRoaXMpOwoKICAgICAgICAgICAgLy9Ob3cgdXBkYXRlIHRoZSBmaW5hbCBjb21wdXRlZCBleHRlbnR3IGZvciBjZWxscyBhbmQgcm93cy4KICAgICAgICAgICAgLy9BbHNvIHVwZGF0ZSBtZWFzdXJlZHgveSBmb3IgaXQncyBjZWxscwogICAgICAgICAgICBfLmVhY2gocm93Vmlld3MsIGZ1bmN0aW9uKHJvd1ZpZXcsIHJvd0luZGV4KXsKICAgICAgICAgICAgICAgIHZhciByb3dQYWRYID0gcm93Vmlldy5sYXlvdXQuX3RhcmdldFBhZGRpbmdYKCk7CiAgICAgICAgICAgICAgICB2YXIgcm93UGFkWSA9IHJvd1ZpZXcubGF5b3V0Ll90YXJnZXRQYWRkaW5nWSgpOwogICAgICAgICAgICAgICAgdmFyIHJvd1dpZHRoID0gMDsKICAgICAgICAgICAgICAgIF8uZWFjaChyb3dWaWV3Ll9ub3JtYWxpemVkQ2hpbGRWaWV3cygpLCBmdW5jdGlvbihjZWxsVmlldyl7CiAgICAgICAgICAgICAgICAgICAgdmFyIG5ld0NlbGxXID0gdGhpcy5fY29tcHV0ZUNvbHVtbldpZHRoKGNlbGxWaWV3KTsKICAgICAgICAgICAgICAgICAgICBpZihuZXdDZWxsVyAhPSBjZWxsVmlldy5sYXlvdXRNb2RlbC5leHRlbnR3KXsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50dyA9IG5ld0NlbGxXOwogICAgICAgICAgICAgICAgICAgICAgICBjZWxsVmlldy5pbnZhbGlkYXRlRGlzcGxheSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjZWxsVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHggPSByb3dQYWRYICsgcm93V2lkdGg7CiAgICAgICAgICAgICAgICAgICAgY2VsbFZpZXcubGF5b3V0TW9kZWwubWVhc3VyZWR5ID0gcm93UGFkWTsKICAgICAgICAgICAgICAgICAgICByb3dXaWR0aCA9IHJvd1dpZHRoICsgY2VsbFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50dzsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICAgICAgdmFyIG5ld1Jvd1dpZHRoID0gcm93Vmlldy5sYXlvdXRNb2RlbC5tYXJnaW5sZWZ0ICsgcm93V2lkdGggKyByb3dWaWV3LmxheW91dE1vZGVsLm1hcmdpbnJpZ2h0OwogICAgICAgICAgICAgICAgaWYocm93Vmlldy5sYXlvdXRNb2RlbC5leHRlbnR3ICE9IG5ld1Jvd1dpZHRoKXsKICAgICAgICAgICAgICAgICAgICByb3dWaWV3LmxheW91dE1vZGVsLmV4dGVudHcgPSBuZXdSb3dXaWR0aDsKICAgICAgICAgICAgICAgICAgICByb3dWaWV3LmludmFsaWRhdGVEaXNwbGF5KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sIHRoaXMpOwoKICAgICAgICAgICAgLy9Ob3cgdXBkYXRlIHRoZSBmaW5hbCBjb21wdXRlZCBleHRlbnR3IGZvciB0YWJsZSBhbmQgbWVhc3VyZWR4L3kgZm9yIGl0J3MgY2hpbGRyZW4KICAgICAgICAgICAgdmFyIHRhYmxlUGFkWCA9IHRoaXMuX3RhcmdldFBhZGRpbmdYKCk7CiAgICAgICAgICAgIHZhciB0YWJsZVBhZFkgPSB0aGlzLl90YXJnZXRQYWRkaW5nWSgpOwogICAgICAgICAgICB2YXIgcGFyZW50VyA9IDA7CiAgICAgICAgICAgIHZhciBwYXJlbnRIID0gMDsKICAgICAgICAgICAgXy5lYWNoKHRoaXMudGFyZ2V0Ll9ub3JtYWxpemVkQ2hpbGRWaWV3cygpLCBmdW5jdGlvbihjaGlsZFZpZXcsIGNoaWxkSW5kZXgpewogICAgICAgICAgICAgICAgaWYoY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHcgPiBwYXJlbnRXKXsKICAgICAgICAgICAgICAgICAgICBwYXJlbnRXID0gY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjaGlsZFZpZXcubGF5b3V0TW9kZWwubWVhc3VyZWR4ID0gdGFibGVQYWRYOwogICAgICAgICAgICAgICAgY2hpbGRWaWV3LmxheW91dE1vZGVsLm1lYXN1cmVkeSA9IHRhYmxlUGFkWSArIHBhcmVudEg7CiAgICAgICAgICAgICAgICBwYXJlbnRIID0gcGFyZW50SCArIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgIHZhciBvbGRFeHRlbnRXID0gbGF5b3V0TW9kZWwuZXh0ZW50dzsKICAgICAgICAgICAgdmFyIG9sZEV4dGVudEggPSBsYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICBsYXlvdXRNb2RlbC5leHRlbnR3ID0gbGF5b3V0TW9kZWwubWFyZ2lubGVmdCArIHBhcmVudFcgKyBsYXlvdXRNb2RlbC5tYXJnaW5yaWdodDsKICAgICAgICAgICAgbGF5b3V0TW9kZWwuZXh0ZW50aCA9IGxheW91dE1vZGVsLm1hcmdpbnRvcCArIHBhcmVudEggKyBsYXlvdXRNb2RlbC5tYXJnaW5ib3R0b207CiAgICAgICAgICAgIGlmKG9sZEV4dGVudFcgIT0gbGF5b3V0TW9kZWwuZXh0ZW50dyB8fCBvbGRFeHRlbnRIICE9IGxheW91dE1vZGVsLmV4dGVudGgpewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUNvbHVtbldpZHRoIDogZnVuY3Rpb24oY2VsbFZpZXcpewogICAgICAgICAgICB2YXIgY29sc3BhbiA9IHRoaXMuZ2V0T3JFbHNlKGNlbGxWaWV3LmxheW91dE1vZGVsLmNvbHNwYW4sIDEpOwogICAgICAgICAgICBpZihjb2xzcGFuIDwwKXsKICAgICAgICAgICAgICAgIGNvbHNwYW4gPSB0aGlzLl9jb2x1bW5XaWR0aHMubGVuZ3RoIC0gY2VsbFZpZXcudGFibGVDZWxsSW5kZXg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoY2VsbFZpZXcuZWZmZWN0aXZlQ2VsbEluZGV4ICsgY29sc3BhbiAtMSA+PSB0aGlzLl9jb2x1bW5XaWR0aHMubGVuZ3RoKQogICAgICAgICAgICAgICAgcmV0dXJuIGNlbGxWaWV3LmxheW91dE1vZGVsLmV4dGVudHc7ICAgICAgICAgICAgICAvL3Nob3VsZCBub3QgYmUgdGhlIGNhc2UgZXZlcgogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgdmFyIGNvbFdpZHRoID0gMDsKICAgICAgICAgICAgICAgIGZvcih2YXIgaT0gY2VsbFZpZXcuZWZmZWN0aXZlQ2VsbEluZGV4OyBpIDw9IGNlbGxWaWV3LmVmZmVjdGl2ZUNlbGxJbmRleCArIGNvbHNwYW4gLTE7IGkrKyl7CiAgICAgICAgICAgICAgICAgICAgY29sV2lkdGggPSBjb2xXaWR0aCArIHRoaXMuX2NvbHVtbldpZHRoc1tpXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBjb2xXaWR0aDsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF92YWxpZENlbGxzSW5Sb3cgOiBmdW5jdGlvbihyb3dWaWV3cykgewogICAgICAgICAgICB2YXIgaGlkZGVuQ2hpbGRJbmRleDsKICAgICAgICAgICAgdmFyIGluZGV4OwogICAgICAgICAgICB2YXIgY291bnQgPTA7CgogICAgICAgICAgICBfLmVhY2gocm93Vmlld3MsIGZ1bmN0aW9uKHJvd1ZpZXcsIHJvd0luZGV4KXsKICAgICAgICAgICAgICAgIHZhciBDaGlsZFZpZXdzID0gcm93Vmlldy5jaGlsZFZpZXdzOwogICAgICAgICAgICAgICAgaGlkZGVuQ2hpbGRJbmRleCA9IFtdOwogICAgICAgICAgICAgICAgXy5lYWNoKENoaWxkVmlld3MsZnVuY3Rpb24odkNoaWxkVmlldywgaW5kZXgpewogICAgICAgICAgICAgICAgICAgICAgIGlmKHZDaGlsZFZpZXcubW9kZWwucHJlc2VuY2UgIT0gInZpc2libGUiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZGVuQ2hpbGRJbmRleC5wdXNoKGluZGV4KTsgIC8vIGtlZXBzIHRoZSBpbmRleCBvZiBoaWRkZW4gZmllbGRzCiAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9LHRoaXMpOwoKCiAgICAgICAgICAgICAgICAgIGZvcih2YXIgaT1DaGlsZFZpZXdzLmxlbmd0aC0xO2k+MDtpLS0pIHsKICAgICAgICAgICAgICAgICAgICAgY291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICBfLmVhY2goaGlkZGVuQ2hpbGRJbmRleCxmdW5jdGlvbih2YWx1ZSxpbmRleCl7IC8vIHRoaXMgaXMgdG8gZmluZCB0aGUgbnVtYmVyIG9mIGhpZGRlbiBlbGVtZW50cyBiZWZvcmUgdGhlIGdpdmVuIGluZGV4LgogICAgICAgICAgICAgICAgICAgICAgICAgaWYodmFsdWUgPCBpKSBjb3VudCsrOwogICAgICAgICAgICAgICAgICAgICB9LHRoaXMpOwogICAgICAgICAgICAgICAgICAgICBDaGlsZFZpZXdzW2ldLmVmZmVjdGl2ZUNlbGxJbmRleCA9IENoaWxkVmlld3NbaV0udGFibGVDZWxsSW5kZXggLSBjb3VudCA7IC8vIHRvIGNhbGN1bGF0ZSB0aGUgZWZmZWN0aXZlIGNlbGwgaW5kZXggZm9yIHZpc2libGUgZmllbGRzLgogICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9LHRoaXMpOwogICAgICAgIH0sCgogICAgICAgIC8vbGF5b3V0IHJlbGF0ZWQgZnVuY3Rpb25zCiAgICAgICAgaW52YWxpZGF0ZVNpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICBpZighdGhpcy5fbGF5b3V0TWFuYWdlci5pc1BlbmRpbmdWYWxpZGF0ZVNpemUodGhpcy50YXJnZXQpKXsgLy9jaGVjayBpc1BlbmRpbmcgdG8gYXZvaWQgcmVjdXJzaW9uCiAgICAgICAgICAgICAgICBfLmVhY2godGhpcy50YXJnZXQuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uKGNoaWxkVmlldykgewogICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5fbGF5b3V0TWFuYWdlci5pc1BlbmRpbmdWYWxpZGF0ZVNpemUoY2hpbGRWaWV3KSAmJiAoY2hpbGRWaWV3LmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUk9XIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFZpZXcubGF5b3V0TW9kZWwubGF5b3V0ID09IHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9SSUdIVExFRlRST1cpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIF8uZWFjaChjaGlsZFZpZXcuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uKGNlbGxWaWV3KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2xheW91dE1hbmFnZXIuaXNQZW5kaW5nVmFsaWRhdGVTaXplKGNlbGxWaWV3KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGxWaWV3LmludmFsaWRhdGVTaXplKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZFZpZXcuaW52YWxpZGF0ZVNpemUoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LmxheW91dC5MYXlvdXRCYXNlLnByb3RvdHlwZS5pbnZhbGlkYXRlU2l6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pCn0pKF8sICQsIHhmYWxpYik7CgoKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewoKICAgIHhmYWxpYi52aWV3LmxheW91dC5EYXRhVGFibGVMYXlvdXQgPSB4ZmFsaWIudmlldy5sYXlvdXQuVGFibGVMYXlvdXQuZXh0ZW5kKHsKCiAgICAgICAgLy9mb3IgYSBnaXZlbiBpZCBnZXQgdGhlIGxpc3Qgb2YgaGVhZGVycyAoaW5jbHVkaW5nIHJvdy1oZWFkZXJzIGFuZCBjb2x1bW4taGVhZGVycykKICAgICAgICAvL3RoaXMgY2FuIGJlIG11bHRpcGxlIGluIGNhc2Ugd2UgaGF2ZSBtdWx0aXBsZSByb3cvY29sdW1uLCBvciBjZWxsIHNwYW5zIG11bHRpcGxlIGNvbHVtbnMKICAgICAgICAvL1RDSDogVGFibGUgQ29sdW1uIEhlYWRlcgogICAgICAgIC8vVFJIOiBUYWJsZSBSb3cgSGVhZGVyCiAgICAgICAgLy9UREM6IFRhYmxlIERhdGEgQ2VsbAogICAgICAgIGdldEhlYWRlcjpmdW5jdGlvbihjZWxsSWQsZGF0YVByZXNlbmNlVGFibGUpIHsKICAgICAgICAgICAgLy8gdXNlIGhlYWRlcnMgYXMgYSBTZXQKICAgICAgICAgICAgdmFyIGhlYWRlcnMgPSB7fTsKICAgICAgICAgICAgXy5lYWNoKGRhdGFQcmVzZW5jZVRhYmxlLCBmdW5jdGlvbihyb3csIGkpIHsKICAgICAgICAgICAgICAgIF8uZWFjaChkYXRhUHJlc2VuY2VUYWJsZVtpXSwgZnVuY3Rpb24oY29sdW1uLCBqKSB7CiAgICAgICAgICAgICAgICAgICAgaWYoY2VsbElkID09IGRhdGFQcmVzZW5jZVRhYmxlW2ldW2pdLnN1YnN0cmluZyg0KSkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgaywgaGVhZGVyOwogICAgICAgICAgICAgICAgICAgICAgICBmb3Ioaz0wO2s8aTtrKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGRhdGFQcmVzZW5jZVRhYmxlW2tdW2pdLmluZGV4T2YoIlRDSDoiKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyID0gZGF0YVByZXNlbmNlVGFibGVba11bal0uc3Vic3RyaW5nKDQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCFoZWFkZXJzLmhhc093blByb3BlcnR5KGhlYWRlcikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyc1toZWFkZXJdID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yKGs9MDtrPGo7aysrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihkYXRhUHJlc2VuY2VUYWJsZVtpXVtrXS5pbmRleE9mKCJUUkg6IikgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlciA9IGRhdGFQcmVzZW5jZVRhYmxlW2ldW2tdLnN1YnN0cmluZyg0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZighaGVhZGVycy5oYXNPd25Qcm9wZXJ0eShoZWFkZXIpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnNbaGVhZGVyXSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSx0aGlzKTsKICAgICAgICAgICAgfSx0aGlzKTsKICAgICAgICAgICAgLy8gY29udmVydCBoZWFkZXJzIFNldCBpbnRvIHN0cmluZyB0byBiZSBhZGRlZCB0byBoZWFkZXJzIGF0dHJpYnV0ZQogICAgICAgICAgICByZXR1cm4gXy5rZXlzKGhlYWRlcnMpLmpvaW4oIiAiKS50cmltKCk7CiAgICAgICAgfSwKCgogICAgICAgIG1lYXN1cmVTaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vaGVpZ2h0VGFibGU6IGNvbnRhaW5zIHRoZSBoZWlnaHQgZm9yIGVhY2ggcm93CiAgICAgICAgICAgIC8vd2lkdGhUYWJsZTogY29udGFpbnMgdGhlIHdpZHRoIGZvciBlYWNoIGNlbGwKICAgICAgICAgICAgLy9kYXRhUHJlc2VuY2VUYWJsZTogY2FwdHVyZXMgdGhlIG1hcHBpbmcgZm9yIGhlYWRlciB0byBkYXRhIGNlbGxzCiAgICAgICAgICAgIHZhciBoZWlnaHRUYWJsZSA9IFtdLCB3aWR0aFRhYmxlID0gW10sIGRhdGFQcmVzZW5jZVRhYmxlID0gW107CgogICAgICAgICAgICB2YXIgbGF5b3V0TW9kZWwgPSB0aGlzLnRhcmdldC5sYXlvdXRNb2RlbDsKICAgICAgICAgICAgLy9nZXQgY2hpbGQgb2YgdGFibGVzIHdoaWNoIGFyZSBhY3R1YWxseSByb3dzCiAgICAgICAgICAgIHZhciByb3dWaWV3cyA9IF8uZmlsdGVyKHRoaXMudGFyZ2V0Ll9ub3JtYWxpemVkQ2hpbGRWaWV3cygpLCBmdW5jdGlvbiAoY2hpbGRWaWV3KSB7CiAgICAgICAgICAgICAgICBpZiAoY2hpbGRWaWV3LmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUk9XIHx8IGNoaWxkVmlldy5sYXlvdXRNb2RlbC5sYXlvdXQgPT0geGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1JJR0hUTEVGVFJPVykKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICB0aGlzLl92YWxpZENlbGxzSW5Sb3cocm93Vmlld3MpOwoKICAgICAgICAgICAgLy9pZGVudGlmeSB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgaW4gdGhlIHRhYmxlICh0aGUgZmlyc3Qgcm93IGlzIHRoZSBiZXQgdG8gZ2V0IHRoaXMgYXMKICAgICAgICAgICAgLy8gcHJldmlvdXMgcm93IHJvd3NwYW4gZG9lcyBub3QgaW1wYWN0IGl0KS4gQWRkIGFsbCBjb2xzcGFucyB0byBnZXQgdGhlIGFjdHVhbCBudW1iZXIgb2YgY29sdW1ucwogICAgICAgICAgICB2YXIgbnVtQ29sdW1ucyA9IDA7CiAgICAgICAgICAgIF8uZWFjaChyb3dWaWV3cywgZnVuY3Rpb24gKHJvd1ZpZXcsIHJvd0luZGV4KSB7CiAgICAgICAgICAgICAgICBfLmVhY2gocm93Vmlldy5fbm9ybWFsaXplZENoaWxkVmlld3MoKSwgZnVuY3Rpb24gKGNlbGxWaWV3LCBjZWxsSW5kZXgpIHsKICAgICAgICAgICAgICAgICAgICBpZihyb3dJbmRleCA9PSAwKXsKICAgICAgICAgICAgICAgICAgICAgICAgbnVtQ29sdW1ucys9dGhpcy5nZXRPckVsc2UoY2VsbFZpZXcubGF5b3V0TW9kZWwuY29sc3BhbiwgMSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgICAgICAvL2luaXRpbGFpemUgdGhlIGNvbHVtbnMgdG8gYW4gX19lbXB0eSBzdHJpbmcsIGFuZCB0aGUgZW5kIG9mIHByb2Nlc3NpbmcgdGFibGUgd2lsbCBub3QKICAgICAgICAgICAgICAgIC8vY29udGFpbiBhbnkgX19lbXB0eSBjZWxscwogICAgICAgICAgICAgICAgZGF0YVByZXNlbmNlVGFibGVbcm93SW5kZXhdID0gW107CiAgICAgICAgICAgICAgICBmb3IodmFyIGk9MDtpPG51bUNvbHVtbnM7aSsrKSB7CiAgICAgICAgICAgICAgICAgICAgZGF0YVByZXNlbmNlVGFibGVbcm93SW5kZXhdW2ldID0gIl9fZW1wdHkiOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LHRoaXMpOwoKCiAgICAgICAgICAgIC8vUG9wdWxhdGUgdGhlIGRhdGFQcmVzZW5jZVRhYmxlIHdpdGggdGhlIElEcyBmb3IgaGVhZGVyIGFuZCBkYXRhIGNlbGwgLSByZXF1aXJlZCB0byBhc3NvY2lhdGUgdGhlIGhlYWRlcnMKICAgICAgICAgICAgLy8gd2l0aCB0aGUgZGF0YSBjZWxscy4gQWxzbyBwb3B1bGF0ZSB0aGUgaGVpZ2h0IHRhYmxlcyBuZWVkZWQgZm9yIGZvcm1hdHRpbmcgdGhlIHRhYmxlLgogICAgICAgICAgICBfLmVhY2gocm93Vmlld3MsIGZ1bmN0aW9uIChyb3dWaWV3LCByb3dJbmRleCkgewogICAgICAgICAgICAgICAgXy5lYWNoKHJvd1ZpZXcuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uIChjZWxsVmlldywgY2VsbEluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNlbGxMYXlvdXQgPSBjZWxsVmlldy5sYXlvdXRNb2RlbDsKICAgICAgICAgICAgICAgICAgICB2YXIgcm93c3BhbiA9IHRoaXMuZ2V0T3JFbHNlKGNlbGxMYXlvdXQucm93c3BhbiwgMSk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbHNwYW4gPSB0aGlzLmdldE9yRWxzZShjZWxsTGF5b3V0LmNvbHNwYW4sIDEpOwogICAgICAgICAgICAgICAgICAgIGlmIChjb2xzcGFuID09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgY29scGFuIGlzIC0xLCB0aGVuIHNldCBpdCB0byByZW1haW5pbmcgZ3JpZCBsZW5ndGgKICAgICAgICAgICAgICAgICAgICAgICAgY29sc3BhbiA9IHRoaXMuX3RhYmxlQ2VsbEdyaWQubGVuZ3RoIC0gY2VsbFZpZXcuZWZmZWN0aXZlQ2VsbEluZGV4OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZihyb3dzcGFuID09IDEpewogICAgICAgICAgICAgICAgICAgICAgICBpZihoZWlnaHRUYWJsZVtyb3dJbmRleF0gPT0gdW5kZWZpbmVkIHx8IGNlbGxWaWV3LmxheW91dE1vZGVsLmV4dGVudGggPiBoZWlnaHRUYWJsZVtyb3dJbmRleF0gKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHRUYWJsZVtyb3dJbmRleF0gPSBjZWxsVmlldy5sYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2VsbFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50aCA8IGNlbGxWaWV3LmxheW91dE1vZGVsLmluaXRpYWxoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodFRhYmxlW3Jvd0luZGV4XSA9IGNlbGxWaWV3LmxheW91dE1vZGVsLmluaXRpYWxoOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHZhciBhY3R1YWxDb2x1bW5JbmRleCA9IDA7CiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW1Db2x1bW5zOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoZGF0YVByZXNlbmNlVGFibGVbcm93SW5kZXhdW2ldID09ICJfX2VtcHR5IikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yKHZhciBqPTA7ajxjb2xzcGFuO2orKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcih2YXIgaz0wO2s8cm93c3BhbjtrKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2VsbFZpZXcuZWwubm9kZU5hbWUgPT0gIlRIIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoY2VsbFZpZXcuX2lzUGFydE9mSGVhZGVyUm93KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhUHJlc2VuY2VUYWJsZVtyb3dJbmRleCtrXVthY3R1YWxDb2x1bW5JbmRleCtqXSA9ICJUQ0g6IitjZWxsVmlldy5faWQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFQcmVzZW5jZVRhYmxlW3Jvd0luZGV4K2tdW2FjdHVhbENvbHVtbkluZGV4K2pdID0gIlRSSDoiK2NlbGxWaWV3Ll9pZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFQcmVzZW5jZVRhYmxlW3Jvd0luZGV4K2tdW2FjdHVhbENvbHVtbkluZGV4K2pdID0gIlREQzoiK2NlbGxWaWV3Ll9pZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihjb2xzcGFuID09IDEpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYod2lkdGhUYWJsZVthY3R1YWxDb2x1bW5JbmRleF0gPT0gdW5kZWZpbmVkIHx8IGNlbGxWaWV3LmxheW91dE1vZGVsLmV4dGVudHcgPiB3aWR0aFRhYmxlW2FjdHVhbENvbHVtbkluZGV4XSApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aFRhYmxlW2FjdHVhbENvbHVtbkluZGV4XSA9IGNlbGxWaWV3LmxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3R1YWxDb2x1bW5JbmRleCsrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGxheW91dE1vZGVsLmV4dGVudGggPSAwOwogICAgICAgICAgICAgICAgICAgIGxheW91dE1vZGVsLmV4dGVudHcgPSAwOwogICAgICAgICAgICAgICAgICAgIF8uZWFjaChoZWlnaHRUYWJsZSwgZnVuY3Rpb24oaGVpZ2h0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxheW91dE1vZGVsLmV4dGVudGgrPWhlaWdodCA7CiAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgIF8uZWFjaCh3aWR0aFRhYmxlLCBmdW5jdGlvbih3aWR0aCkgewogICAgICAgICAgICAgICAgICAgICAgICBsYXlvdXRNb2RlbC5leHRlbnR3Kz13aWR0aDsKICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICAvL3NldCB0aGUgcm93IGFuZCBjZWxsIGhlaWdodCBmcm9tIGhlaWdodCB0YWJsZSB0byBrZWVwIGFsbCBjZWxscyBzeW1tZXRyaWMKICAgICAgICAgICAgLy9hbHNvIGFkZCB0aGUgaGVhZGVycyBhdHRyaWJ1dGUgdG8gdGhlIHZpZXcKICAgICAgICAgICAgXy5lYWNoKHJvd1ZpZXdzLCBmdW5jdGlvbiAocm93Vmlldywgcm93SW5kZXgpIHsKICAgICAgICAgICAgICAgIHZhciByb3dQYWRYID0gcm93Vmlldy5sYXlvdXQuX3RhcmdldFBhZGRpbmdYKCk7CiAgICAgICAgICAgICAgICB2YXIgcm93UGFkWSA9IHJvd1ZpZXcubGF5b3V0Ll90YXJnZXRQYWRkaW5nWSgpOwogICAgICAgICAgICAgICAgcm93Vmlldy5sYXlvdXRNb2RlbC5leHRlbnRoID0gIGhlaWdodFRhYmxlW3Jvd0luZGV4XTsKCiAgICAgICAgICAgICAgICAvL3Byb2Nlc3MgdGhlIGluZm8gdG8gZ2V0IHJvdyBoZWlnaHRzLCBjb2x1bW4gaGVpZ2h0cyBhbmQgZmlyc3QgY2VsbAogICAgICAgICAgICAgICAgXy5lYWNoKHJvd1ZpZXcuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uIChjZWxsVmlldywgY2VsbEluZGV4KSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGhlYWRlcnMgPSB0aGlzLmdldEhlYWRlcihjZWxsVmlldy5faWQsZGF0YVByZXNlbmNlVGFibGUpOwogICAgICAgICAgICAgICAgICAgIGlmKGhlYWRlcnMgIT0gIiIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2VsbFZpZXcuJGVsLmF0dHIoJ2hlYWRlcnMnLCBoZWFkZXJzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYoY2VsbFZpZXcubGF5b3V0TW9kZWwucm93c3BhbiA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGxWaWV3LmxheW91dE1vZGVsLmV4dGVudGggPSAgaGVpZ2h0VGFibGVbcm93SW5kZXhdCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIGNlbGxWaWV3LmxheW91dE1vZGVsLmJvcmRlcnRvcCAvIDIuMAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBjZWxsVmlldy5sYXlvdXRNb2RlbC5ib3JkZXJib3R0b20gLyAyLjA7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGxWaWV3LmludmFsaWRhdGVEaXNwbGF5KCk7CgogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB9LHRoaXMpOwogICAgICAgICAgICB9LHRoaXMpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICB1cGRhdGVEaXNwbGF5IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnZpZXcubGF5b3V0LlRhYmxlTGF5b3V0LnByb3RvdHlwZS51cGRhdGVEaXNwbGF5LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLnRhcmdldC5lbCwgeyJib3JkZXItc3BhY2luZyI6IjAifSk7CiAgICAgICAgICAgIC8vIExDLTM5MTE2NjggOiBTYWZhcmkgZG9lcyBub3QgdXBkYXRlIHRoZSBkaXNwbGF5IHdoZW4gYSBET00gY2hhbmdlIGlzIGRvbmUgaW4gYSB0YWJsZToKICAgICAgICAgICAgaWYoeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmlzU2FmYXJpKCkpIHsKICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0LiRlbC5oaWRlKCkuY3NzKCJoZWlnaHQiKTt0aGlzLnRhcmdldC4kZWwuc2hvdygpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0sIHRoaXMpOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sICQsIHhmYWxpYikgewogICAgeGZhbGliLnZpZXcubGF5b3V0LlN0YXRpY0xheW91dCA9IHhmYWxpYi52aWV3LmxheW91dC5MYXlvdXRCYXNlLmV4dGVuZCh7CgogICAgICAgIG1lYXN1cmVTaXplIDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgZ3Jvd2FibGVPZmZzZXRIID0gMCwgZ3Jvd2FibGVBc3NpZ25lZEgsIG5ld09mZnNldDsKICAgICAgICAgICAgdmFyIGluaXRpYWxHcm93YWJsZUJvdHRvbSA9IC0xOwogICAgICAgICAgICB2YXIgZ3Jvd2FibGVWaWV3ID0gdGhpcy50YXJnZXQuZ3Jvd2FibGVWaWV3OwogICAgICAgICAgICB2YXIgbGF5b3V0TW9kZWwgPSB0aGlzLnRhcmdldC5sYXlvdXRNb2RlbDsKICAgICAgICAgICAgdmFyIGdyb3dGID0gMDsKICAgICAgICAgICAgaWYgKCFfLmlzRW1wdHkoZ3Jvd2FibGVWaWV3KSkgewogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBncm93YWJsZVZpZXcubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKGdyb3dhYmxlVmlld1tpXS5sYXlvdXRNb2RlbC5leHRlbnRoIC0gZ3Jvd2FibGVWaWV3W2ldLmxheW91dE1vZGVsLmluaXRpYWxoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgZ3Jvd0YgPSBpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBncm93YWJsZUFzc2lnbmVkSCA9IGdyb3dhYmxlVmlld1tncm93Rl0ubGF5b3V0TW9kZWwuaW5pdGlhbGg7CiAgICAgICAgICAgICAgICBuZXdPZmZzZXQgPSBncm93YWJsZVZpZXdbZ3Jvd0ZdLmxheW91dE1vZGVsLmV4dGVudGggLSBncm93YWJsZUFzc2lnbmVkSDsKICAgICAgICAgICAgICAgIGluaXRpYWxHcm93YWJsZUJvdHRvbSA9IGdyb3dhYmxlVmlld1tncm93Rl0ubGF5b3V0TW9kZWwuZXh0ZW50eSArIGdyb3dhYmxlQXNzaWduZWRIOwoKICAgICAgICAgICAgICAgIC8vYnVnIzM0NzU1NjYsIG1ha2UgYW4gZXhjZXB0aW9uIGZvciBmaXJzdCBwYWdlIGFuZCByZW5kZXIgaXQgZXZlbiBpZiB0aGVyZSBpcyBubyBjb250ZW50LgogICAgICAgICAgICAgICAgaWYgKCF0aGlzLnRhcmdldC5fZm9yY2VWaWV3KCkgJiYKICAgICAgICAgICAgICAgICAgICBncm93YWJsZVZpZXdbZ3Jvd0ZdLmxheW91dE1vZGVsLmV4dGVudGggPD0gKGdyb3dhYmxlVmlld1tncm93Rl0ubGF5b3V0TW9kZWwubWFyZ2ludG9wICsgZ3Jvd2FibGVWaWV3W2dyb3dGXS5sYXlvdXRNb2RlbC5tYXJnaW5ib3R0b20pKSB7CiAgICAgICAgICAgICAgICAgICAgLy9BbGwgdGhlIGNoaWxkcmVuIG9mIGdyb3dhYmxlIHN1YmZvcm0gaGF2ZSBlaXRoZXIgYmVlbiByZW1vdmVkIG9yIGJlZW4gaGlkZGVuLiBTbyBzZXQgaXQncyBoZWlnaHQgdG8gemVybyBhcyB3ZWxsLgogICAgICAgICAgICAgICAgICAgIGdyb3dhYmxlT2Zmc2V0SCA9IC1sYXlvdXRNb2RlbC5pbml0aWFsaDsKICAgICAgICAgICAgICAgICAgICBsYXlvdXRNb2RlbC5tZWFzdXJlZGRpc3BsYXkgPSAiaGlkZGVuIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChuZXdPZmZzZXQgPiAwIHx8ICghdGhpcy5feGZhVmlld1JlZ2lzdHJ5KCkucGFnaW5nQ29uZmlnKCkuc2hyaW5rUGFnZURpc2FibGVkICYmCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0Ll9mb3JtRG9tUm9vdCgpLmhvc3QubnVtUGFnZXMgPiAxKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvL0lmIHZpZXcgaGFzIG92ZXJncm93biBvcgogICAgICAgICAgICAgICAgICAgICAgICAvL3BhZ2VTaHJpbmsgaXMgZW5hYmxlZCBhbmQgdG90YWwgbnVtYmVyIG9mIHBhZ2VzIGFyZSBtb3JlIHRoYXQgb25lIHRoZW4gY2hhbmdlIHRoZSBncm93YWJsZU9mZlNldCBhbmQgbW92ZSBldmVyeXRoaW5nLgogICAgICAgICAgICAgICAgICAgICAgICBncm93YWJsZU9mZnNldEggPSBuZXdPZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXdPZmZzZXQgPCAwICYmIHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgeGZhbGliLnZpZXcuUGFnZVZpZXcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0Ll9mb3JtRG9tUm9vdCgpLmhvc3QucGFnaW5nTWFuYWdlci5hdXRvUmVuZGVyUGFnZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGxheW91dE1vZGVsLm1lYXN1cmVkZGlzcGxheSA9ICJibG9jayI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdmFyIHBhcmVudFBhZExlZnQgPSB0aGlzLl90YXJnZXRQYWRkaW5nWCgpOwogICAgICAgICAgICB2YXIgcGFyZW50UGFkVG9wID0gdGhpcy5fdGFyZ2V0UGFkZGluZ1koKTsKICAgICAgICAgICAgdmFyIG9sZEV4dGVudEggPSBsYXlvdXRNb2RlbC5leHRlbnRoOwogICAgICAgICAgICB2YXIgY29udGFpbmVySCA9IGxheW91dE1vZGVsLmluaXRpYWxoICsgZ3Jvd2FibGVPZmZzZXRIOwogICAgICAgICAgICBfLmVhY2godGhpcy50YXJnZXQuY2hpbGRWaWV3cywgZnVuY3Rpb24gKGNoaWxkVmlldywgaW5kZXgpIHsKICAgICAgICAgICAgICAgIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHggPSBwYXJlbnRQYWRMZWZ0ICsgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHg7CiAgICAgICAgICAgICAgICBpZiAoY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHkgPj0gaW5pdGlhbEdyb3dhYmxlQm90dG9tKSB7CiAgICAgICAgICAgICAgICAgICAgY2hpbGRWaWV3LmxheW91dE1vZGVsLm1lYXN1cmVkeSA9IHBhcmVudFBhZFRvcCArIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5leHRlbnR5ICsgZ3Jvd2FibGVPZmZzZXRIOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjaGlsZFZpZXcubGF5b3V0TW9kZWwubWVhc3VyZWR5ID0gcGFyZW50UGFkVG9wICsgY2hpbGRWaWV3LmxheW91dE1vZGVsLmV4dGVudHk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihsYXlvdXRNb2RlbC5tZWFzdXJlZGRpc3BsYXkgIT09ICJoaWRkZW4iKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkVmlldy5tb2RlbCAmJiBjaGlsZFZpZXcubW9kZWwuanNvbk1vZGVsICYmIGNoaWxkVmlldy5tb2RlbC5qc29uTW9kZWwucHJlc2VuY2UgIT09ICJoaWRkZW4iICYmCiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHkgKyBjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50aCA+IGNvbnRhaW5lckgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVySCA9IGNoaWxkVmlldy5sYXlvdXRNb2RlbC5tZWFzdXJlZHkgKyBjaGlsZFZpZXcubGF5b3V0TW9kZWwuZXh0ZW50aAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcyk7CgogICAgICAgICAgICBsYXlvdXRNb2RlbC5leHRlbnRoID0gY29udGFpbmVySDsKICAgICAgICAgICAgaWYgKG9sZEV4dGVudEggIT0gbGF5b3V0TW9kZWwuZXh0ZW50aCkgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZ2V0Um9vdFZpZXcgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS5yb290U3ViZm9ybVZpZXc7CiAgICAgICAgfSwKCiAgICAgICAgcmVuZGVyTmV4dFBhZ2UgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuX2dldFJvb3RWaWV3KCkucmVuZGVyRGVmZXJyZWRQYWdlKCk7CiAgICAgICAgfSwKCiAgICAgICAgdXBkYXRlRGlzcGxheSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgeGZhbGliLnZpZXcubGF5b3V0LkxheW91dEJhc2UucHJvdG90eXBlLnVwZGF0ZURpc3BsYXkuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgaWYgKHRoaXMuZ2V0T3JFbHNlKHRoaXMudGFyZ2V0LCAibGF5b3V0TW9kZWwubWVhc3VyZWRkaXNwbGF5IiwgIiIpID09ICJoaWRkZW4iKSB7CiAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy50YXJnZXQuZWwsIHsiZGlzcGxheSIgOiAiaGlkZGVuIn0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMudGFyZ2V0LmVsLCB7ImRpc3BsYXkiIDogImJsb2NrIn0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0pCn0pKF8sICQsIHhmYWxpYik7CgoKCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LmxheW91dC5TdWJmb3JtU2V0TGF5b3V0ID0geGZhbGliLnZpZXcubGF5b3V0LkxheW91dEJhc2UuZXh0ZW5kKHsKICAgICAgICBtZWFzdXJlU2l6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIC8vU3ViZm9ybXNldCBzaG91bGQgYWx3YXlzIHJldHVybiB0cnVlIHNob3cgdGhhdCBtZWFzdXJlU2l6ZSgwIG9mIHBhcmVudCBpcyBjYWxsZWQuCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0sCgogICAgICAgIGludmFsaWRhdGVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgaWYodGhpcy50YXJnZXQucGFyZW50Vmlldyl7CiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldC5wYXJlbnRWaWV3LmludmFsaWRhdGVTaXplKCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIH0pCn0pKF8sICQsIHhmYWxpYik7CgoKCgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LmxheW91dC5Sb290U3ViZm9ybUxheW91dCA9IHhmYWxpYi52aWV3LmxheW91dC5MYXlvdXRCYXNlLmV4dGVuZCh7CiAgICAgICAgbWVhc3VyZVNpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgdXBkYXRlRGlzcGxheSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9KQp9KShfLCAkLCB4ZmFsaWIpOwoKCgoKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy5sYXlvdXQuTGF5b3V0TWFuYWdlciA9IHhmYWxpYi51dC5DbGFzcy5leHRlbmQoewogICAgICAgIExBWU9VVF9FUlJPUl9NQVJHSU4gOiAxLAoKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnV0LkNsYXNzLnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuX2ludmFsaWRTaXplUSA9IFtdOwogICAgICAgICAgICB0aGlzLl9pbnZhbGlkRGlzcGxheVEgPSBbXTsKICAgICAgICAgICAgdGhpcy5fdmFsaWRhdGluZ1NpemUgPSBmYWxzZTsKICAgICAgICAgICAgdGhpcy5fdmFsaWRhdGluZ0Rpc3BsYXkgPSBmYWxzZTsKICAgICAgICAgICAgdGhpcy5fdmFsaWRhdGlvblBlbmRpbmcgPSBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBpbnZhbGlkYXRlU2l6ZSA6IGZ1bmN0aW9uKHZpZXcpewogICAgICAgICAgICBpZih0aGlzLl92YWxpZGF0aW5nRGlzcGxheSAmJiB2aWV3ICYmIHZpZXcgaW5zdGFuY2VvZiBPYmplY3QpewogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5lcnJvcigieGZhVmlldyIsICJpbnZhbGlkYXRlU2l6ZSBpcyBjYWxsZWQgd2hpbGUgdmFsaWRhdGluZ0Rpc3BsYXkgaXMgcnVubmluZyB3aGljaCBpcyBhbiBpc3N1ZS4gaWQiICsgdmlldy5faWQgKwogICAgICAgICAgICAgICAgICAgICIsIHBhcmVudCBpZDoiKyAodmlldy5wYXJlbnRWaWV3ICYmICh2aWV3LnBhcmVudFZpZXcgaW5zdGFuY2VvZiBPYmplY3QpKSA/IHZpZXcucGFyZW50Vmlldy5faWQgOiB2aWV3LnBhcmVudFZpZXcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZighdGhpcy5fdmFsaWRhdGluZ1NpemUgJiYgIXRoaXMuX3ZhbGlkYXRpb25QZW5kaW5nKXsKICAgICAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRpb25QZW5kaW5nID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHZhciB0aW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgICAgICB0aGF0LnRyaWdnZXJWYWxpZGF0aW9uKCk7CiAgICAgICAgICAgICAgICB9LCAxKTsKICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5jbGVhclRpbWVvdXRPbkRlc3Ryb3kodGltZW91dCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBmb3VuZCA9IHRoaXMuaXNQZW5kaW5nVmFsaWRhdGVTaXplKHZpZXcpOwogICAgICAgICAgICBpZighZm91bmQpewogICAgICAgICAgICAgICAgdGhpcy5faW52YWxpZFNpemVRLnB1c2godmlldyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBpbnZhbGlkYXRlRGlzcGxheSA6IGZ1bmN0aW9uKHZpZXcpewogICAgICAgICAgICB2YXIgZm91bmQgPSBfLmZpbmQodGhpcy5faW52YWxpZERpc3BsYXlRLCBmdW5jdGlvbihpbnZhbGlkVmlldyl7CiAgICAgICAgICAgICAgICBpZihpbnZhbGlkVmlldyA9PSB2aWV3KXsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGlmKCFmb3VuZCl7CiAgICAgICAgICAgICAgICB0aGlzLl9pbnZhbGlkRGlzcGxheVEucHVzaCh2aWV3KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHRyaWdnZXJWYWxpZGF0aW9uIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgaWYodGhpcy5fdmFsaWRhdGluZ1NpemUpewogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5kZWJ1ZygieGZhVmlldyIsICJ2YWxpZGF0aW9uIGlzIGFscmVhZHkgcnVubmluZyIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRpb25QZW5kaW5nID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRpbmdTaXplID0gdHJ1ZTsKICAgICAgICAgICAgd2hpbGUodGhpcy5faW52YWxpZFNpemVRLmxlbmd0aCA+IDApewogICAgICAgICAgICAgICAgdmFyIHZpZXcgPSB0aGlzLl9pbnZhbGlkU2l6ZVEuc2hpZnQoKTsKICAgICAgICAgICAgICAgIHZpZXcuX3ZhbGlkYXRlU2l6ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRpbmdTaXplID0gZmFsc2U7CiAgICAgICAgICAgIGlmICh0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS5yb290U3ViZm9ybVZpZXcuX2Zvcm1Eb21Sb290KCkuX21vZGVsSW5pdGlhbGl6ZSA9PT0gJ0lOSVRJQUxJWkVEJykgewogICAgICAgICAgICAgICAgdGhpcy5feGZhVmlld1JlZ2lzdHJ5KCkucm9vdFN1YmZvcm1WaWV3Ll9mb3JtRG9tUm9vdCgpLmZvcm0uZXhlY0xheW91dFJlYWR5KCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRpbmdEaXNwbGF5ID0gdHJ1ZTsKICAgICAgICAgICAgd2hpbGUodGhpcy5faW52YWxpZERpc3BsYXlRLmxlbmd0aCA+MCl7CiAgICAgICAgICAgICAgICB2YXIgdmlldyA9IHRoaXMuX2ludmFsaWREaXNwbGF5US5zaGlmdCgpOwogICAgICAgICAgICAgICAgdmlldy5fdmFsaWRhdGVEaXNwbGF5KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5fdmFsaWRhdGluZ0Rpc3BsYXkgPSBmYWxzZTsKCiAgICAgICAgICAgICBpZiAoZm9ybUJyaWRnZSAmJiB4ZmFsaWIuZ2xvYmFscy5oaWdobGlnaHQpICAgLy8gaGlnaExpZ2h0IG5ld2x5IGFkZGVkIGZpZWxkcwogICAgICAgICAgICAgICAgJChmb3JtQnJpZGdlKS50cmlnZ2VyKCJ4ZmFMYXlvdXRDb21wbGV0ZSIpOwogICAgICAgIH0sCgogICAgICAgIGNyZWF0ZUxheW91dCA6IGZ1bmN0aW9uKHZpZXcpewogICAgICAgICAgICB2YXIgb3B0aW9ucyA9IHt0YXJnZXQ6dmlld30gOwogICAgICAgICAgICBpZih2aWV3IGluc3RhbmNlb2YgeGZhbGliLnZpZXcuUm9vdFN1YmZvcm1WaWV3KQogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIudmlldy5sYXlvdXQuUm9vdFN1YmZvcm1MYXlvdXQob3B0aW9ucyk7CiAgICAgICAgICAgIGVsc2UgaWYodmlldyBpbnN0YW5jZW9mIHhmYWxpYi52aWV3LlBhZ2VWaWV3ICkKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnZpZXcubGF5b3V0LlN0YXRpY0xheW91dChvcHRpb25zKTsKICAgICAgICAgICAgZWxzZSBpZih2aWV3IGluc3RhbmNlb2YgeGZhbGliLnZpZXcuQ29udGVudEFyZWFWaWV3KQogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIudmlldy5sYXlvdXQuVG9wQm90dG9tTGF5b3V0KG9wdGlvbnMpOwogICAgICAgICAgICBlbHNlIGlmKHZpZXcgaW5zdGFuY2VvZiB4ZmFsaWIudmlldy5TdWJmb3JtU2V0VmlldykKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgeGZhbGliLnZpZXcubGF5b3V0LlN1YmZvcm1TZXRMYXlvdXQob3B0aW9ucyk7CiAgICAgICAgICAgIGVsc2UgaWYodmlldy5lbC5ub2RlTmFtZSA9PSAiVFIiKQogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyB4ZmFsaWIudmlldy5sYXlvdXQuRGF0YVRhYmxlUm93TGF5b3V0KG9wdGlvbnMpOwoKICAgICAgICAgICAgdmFyIGxheW91dCA9IG51bGw7CiAgICAgICAgICAgIHN3aXRjaCAodmlldy5sYXlvdXRNb2RlbC5sYXlvdXQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX0xFRlRSSUdIVFRPUEJPVFRPTToKICAgICAgICAgICAgICAgICAgICBsYXlvdXQgPSBuZXcgeGZhbGliLnZpZXcubGF5b3V0LkxlZnRSaWdodExheW91dChvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1JJR0hUTEVGVFRPUEJPVFRPTToKICAgICAgICAgICAgICAgICAgICBsYXlvdXQgPSBuZXcgeGZhbGliLnZpZXcubGF5b3V0LlJpZ2h0TGVmdExheW91dChvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1RPUEJPVFRPTToKICAgICAgICAgICAgICAgICAgICBsYXlvdXQgPSBuZXcgeGZhbGliLnZpZXcubGF5b3V0LlRvcEJvdHRvbUxheW91dChvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1RBQkxFOgogICAgICAgICAgICAgICAgICAgIGxheW91dCA9IG5ldyB4ZmFsaWIudmlldy5sYXlvdXQuVGFibGVMYXlvdXQob3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9ST1c6CiAgICAgICAgICAgICAgICAgICAgbGF5b3V0ID0gbmV3IHhmYWxpYi52aWV3LmxheW91dC5Sb3dMYXlvdXQob3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9SSUdIVExFRlRST1c6CiAgICAgICAgICAgICAgICAgICAgbGF5b3V0ID0gbmV3IHhmYWxpYi52aWV3LmxheW91dC5SaWdodExlZnRSb3dMYXlvdXQob3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9EQVRBVEFCTEU6CiAgICAgICAgICAgICAgICAgICAgbGF5b3V0ID0gbmV3IHhmYWxpYi52aWV3LmxheW91dC5EYXRhVGFibGVMYXlvdXQob3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0IDoKICAgICAgICAgICAgICAgICAgICBsYXlvdXQgPSBuZXcgeGZhbGliLnZpZXcubGF5b3V0LlBvc2l0aW9uTGF5b3V0KG9wdGlvbnMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBsYXlvdXQ7CiAgICAgICAgfSwKCiAgICAgICAgaXNQZW5kaW5nVmFsaWRhdGVTaXplIDogZnVuY3Rpb24odmlldyl7CiAgICAgICAgICAgIHJldHVybiAodGhpcy5faW52YWxpZFNpemVRLmluZGV4T2YodmlldykgID4gLTEpOwogICAgICAgIH0sCgogICAgICAgIF94ZmFWaWV3UmVnaXN0cnkgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy54ZmFWaWV3UmVnaXN0cnk7ICAgIC8vVE9ETzogcmVtb3ZlIHdpbmRvdyBkZXBlbmRlbmN5CiAgICAgICAgfSwKICAgICAgICAvKgogICAgICAgICAqIENoZWNrcyB3aGV0aGVyIGFueSB2aWV3IGhhcyBhbnkga2luZCBvZiBsYXlvdXQgYWN0aXZpdHkgcGVuZGluZyBlaXRoZXIgaW4gbWVhc3VyZSBvciB1cGRhdGUgcGhhc2UuCiAgICAgICAgICovCiAgICAgICAgaXNMYXlvdXRDeWNsZUNvbXBsZXRlIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgcmV0dXJuICEodGhpcy5faW52YWxpZFNpemVRLmxlbmd0aCAgPiAwIHx8IHRoaXMuX2ludmFsaWREaXNwbGF5US5sZW5ndGggPiAwKTsKICAgICAgICB9CgogICAgfSkKfSkoXywgJCwgeGZhbGliKTsKCihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgeGZhbGliLnZpZXcuWGZhVmlld0V2ZW50ID0gewogICAgICAgIFBSRVNFTkNFX0NIQU5HRSA6ICJwcmVzZW5jZUNoYW5nZSIsCiAgICAgICAgRVhURU5UX0NIQU5HRSA6ICJleHRlbnRDaGFuZ2UiCiAgICB9Cn0pKF8sICQsIHhmYWxpYik7CgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3Lk9iamVjdFZpZXcgPSB4ZmFsaWIudXQuRXZlbnRDbGFzcy5leHRlbmQoewoKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi51dC5FdmVudENsYXNzLnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuaWQgPSB0aGlzLm9wdGlvbnMuaWQ7CiAgICAgICAgICAgIHRoaXMuJGVsID0gKHRoaXMub3B0aW9ucy5lbCBpbnN0YW5jZW9mICQpID8gdGhpcy5vcHRpb25zLmVsIDogJCh0aGlzLm9wdGlvbnMuZWwpOwogICAgICAgICAgICB0aGlzLmVsID0gdGhpcy4kZWxbMF07CiAgICAgICAgICAgIHRoaXMuX2xheW91dE1hbmFnZXIgPSB0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS5sYXlvdXRNYW5hZ2VyKCk7CiAgICAgICAgfSwKCiAgICAgICAgLy8galF1ZXJ5IGRlbGVnYXRlIGZvciBlbGVtZW50IGxvb2t1cCwgc2NvcGVkIHRvIERPTSBlbGVtZW50cyB3aXRoaW4gdGhlCiAgICAgICAgLy8gY3VycmVudCB2aWV3LiBUaGlzIHNob3VsZCBiZSBwcmVmZXJlZCB0byBnbG9iYWwgbG9va3VwcyB3aGVyZSBwb3NzaWJsZS4KICAgICAgICAkOiBmdW5jdGlvbihzZWxlY3RvcikgewogICAgICAgICAgICByZXR1cm4gdGhpcy4kZWwuZmluZChzZWxlY3Rvcik7CiAgICAgICAgfSwKCiAgICAgICAgX2Zvcm1Eb21Sb290IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB4ZmFsaWIuc2NyaXB0LlhmYS5JbnN0YW5jZTsgLy9UT0RPOiBSZW1vdmUgc2luZ2xldG9uIGRlcGVuZGVuY3kKICAgICAgICB9LAoKICAgICAgICBfYmluZCA6IGZ1bmN0aW9uKGNvbnRleHQsIGZ1bmMpIHsKICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF94ZmFWaWV3UmVnaXN0cnkgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy54ZmFWaWV3UmVnaXN0cnk7ICAgIC8vVE9ETzogcmVtb3ZlIHdpbmRvdyBkZXBlbmRlbmN5CiAgICAgICAgfSwKCiAgICAgICAgX21tMnB4IDogZnVuY3Rpb24obW1TaXplKXsKICAgICAgICAgICAgcmV0dXJuIHhmYWxpYi52aWV3LnV0aWwuU3R5bGVzLl9tbTJweChtbVNpemUpOwogICAgICAgIH0sCgogICAgICAgIF9jb252ZXJ0VG9QeCA6IGZ1bmN0aW9uKHNpemUpewogICAgICAgICAgICByZXR1cm4geGZhbGliLnZpZXcudXRpbC5TdHlsZXMuX2NvbnZlcnRUb1B4KHNpemUpOwogICAgICAgIH0sCgogICAgICAgIGdldE9yRWxzZSA6IHhmYWxpYi51dC5DbGFzcy5wcm90b3R5cGUuZ2V0T3JFbHNlLCAvL3Nob3J0IGN1dCBidXQgcmVhbGx5IG5lZWRlZCB0byBhdm9pZCBkdXBsaWNhdGUgY29kZS4gTWF5IGJlIGJldHRlciB3YXkgbmV4dCB0aW1lLgoKICAgICAgICBqcUlkOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuanFJZCwKCiAgICAgICAgbWF0Y2hKc29uVHlwZTogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLm1hdGNoSnNvblR5cGUsCgogICAgICAgICRkYXRhIDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLiRkYXRhLAoKICAgICAgICAkY3NzIDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLiRjc3MKCiAgICB9KTsKCn0pKF8sICQsIHhmYWxpYik7CihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgdmFyIEJhc2VWaWV3ID0geGZhbGliLnZpZXcuQmFzZVZpZXcgPSAgeGZhbGliLnZpZXcuT2JqZWN0Vmlldy5leHRlbmQoewoKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHhmYWxpYi52aWV3Lk9iamVjdFZpZXcucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5faWQgPSB0aGlzLmVsLmlkOwogICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplZCA9IGZhbHNlOwogICAgICAgICAgICB0aGlzLnBhcmVudFZpZXcgPSB0aGlzLm9wdGlvbnMucGFyZW50VmlldzsKICAgICAgICAgICAgdGhpcy50YWJsZUNlbGxJbmRleCA9IHRoaXMub3B0aW9ucy50YWJsZUNlbGxJbmRleCB8fCAwOwogICAgICAgICAgICB0aGlzLmVmZmVjdGl2ZUNlbGxJbmRleCA9IDA7CiAgICAgICAgICAgIHRoaXMubW9kZWwgPSBudWxsOwogICAgICAgICAgICB0aGlzLmxheW91dE1vZGVsID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5faW52YWxpZFNpemVGbGFnID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5faW52YWxpZERpc3BsYXlGbGFnID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5fcmVzaXphYmxlID0gZmFsc2U7CiAgICAgICAgICAgIHRoaXMuZWRnZVByZXNlbmNlID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy4kZGF0YSh0aGlzLmVsLCAieGZhVmlldyIsIHRoaXMpOwogICAgICAgICAgICBpZih0aGlzLl9pZCkKICAgICAgICAgICAgICAgIHRoaXMubW9kZWwgPSB0aGlzLl9mb3JtRG9tUm9vdCgpLl94ZmFUZW1wbGF0ZUNhY2hlLmdldE1vZGVsKHRoaXMuX2lkKTsKICAgICAgICAgICAgaWYodGhpcy5tb2RlbCl7CiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZUJvcmRlcigpOwogICAgICAgICAgICAgICAgaWYodGhpcy5tb2RlbC5wcmVzZW5jZSA9PSAidmlzaWJsZSIpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5pdEhhbmRsZXIgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUV2ZW50OiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihldm50Ll9wcm9wZXJ0eSA9PSAicHJlc2VuY2UiICYmICF0aGF0Ll9pbml0aWFsaXplZCl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5faW5pdExheW91dCgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoYXQuX2luaXRpYWxpemVkKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5tb2RlbC5vZmYoeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkZPUk1fTU9ERUxfQ0hBTkdFRCwgaW5pdEhhbmRsZXIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZih0aGF0Ll9pbml0aWFsaXplZCl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9UaGUgb25seSBjYXNlIHdoZW4gaW5pdEhhbmRsZXIgY2FuIGJlIGNhbGxlZCBldmVuIGlmIGl0J3MgaW5pdGlhbGl6ZWQgaXMgaW4gY2FzZSBvZiBzZXJ2ZXIgc2lkZSBzY3JpcHRzIHdoaWNoIGNoYW5nZSBwcmVzZW5jZSBvbiBzZXJ2ZXIuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9idXQgZG9lcyBub3QgY2FsbCBpbml0SGFuZGxlciBhdCB0aGF0IHRpbWUuIFNvIHdlIG5lZWQgdG8gcmVtb3ZlIGluaXRIYW5kbGVyIGV4cGxpY2l0bHkgaW4gbmV4dCBjYWxsLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQubW9kZWwub2ZmKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX0NIQU5HRUQsIGluaXRIYW5kbGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELCBpbml0SGFuZGxlcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9uKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5ET01fQ0hBTkdFRCwgdGhpcyk7CgoKICAgICAgICAgICAgfQoKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVCb3JkZXIgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgYm9yZGVyID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCJib3JkZXIiLDAsdHJ1ZSksCiAgICAgICAgICAgICAgICBmaWxsLAogICAgICAgICAgICAgICAgY29sb3IsCiAgICAgICAgICAgICAgICBlZGdlOwogICAgICAgICAgICBpZihib3JkZXIpewogICAgICAgICAgICAgICAgaWYoKGZpbGwgPSBib3JkZXIuZ2V0RWxlbWVudCgiZmlsbCIsMCx0cnVlKSkgJiYgKGNvbG9yID0gZmlsbC5nZXRFbGVtZW50KCJjb2xvciIsMCx0cnVlKSkKICAgICAgICAgICAgICAgICAgICAmJiBmaWxsLnByZXNlbmNlIT0iaGlkZGVuIgogICAgICAgICAgICAgICAgICAgICYmIGZpbGwucHJlc2VuY2UgIT0iaW52aXNpYmxlIgogICAgICAgICAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gY29sb3IudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgaWYoY29sb3IgPT0gIiIpCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPSIyNTUsMjU1LDI1NSI7ICAgICAvLyBpZiBubyBjb2xvciB2YWx1ZSBpcyBzcGVjaWZpZWQgdGhlbiBmaWxsIGRlZmF1bHQgY29sb3IKICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJyZ2IoIiArIGNvbG9yICsgIikiOwogICAgICAgICAgICAgICAgICAgICQodGhpcy5lbCkuY3NzKCJiYWNrZ3JvdW5kLWNvbG9yIiwgY29sb3IpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBhbGxFZGdlSGlkZGVuID0gdHJ1ZSwKICAgICAgICAgICAgICAgIGluZGV4ID0gMCwKICAgICAgICAgICAgICAgIGVkZ2U7CiAgICAgICAgICAgICAgICB3aGlsZShlZGdlID0gYm9yZGVyLmdldEVsZW1lbnQoImVkZ2UiLGluZGV4LHRydWUpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYoZWRnZS5wcmVzZW5jZSE9ImhpZGRlbiIgJiYgIGVkZ2UucHJlc2VuY2UhPSJpbnZpc2libGUiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFsbEVkZ2VIaWRkZW4gPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGluZGV4Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihib3JkZXIucHJlc2VuY2UgPT0gInZpc2libGUiCiAgICAgICAgICAgICAgICAgICAgJiYgIWFsbEVkZ2VIaWRkZW4pIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY3NzU3R5bGVPYmogPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5nZXRTdHlsZUZvckJvcmRlcihib3JkZXIpOwogICAgICAgICAgICAgICAgICAgIGlmKGNzc1N0eWxlT2JqKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuZWwsIGNzc1N0eWxlT2JqKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIExDLTM5MTAzODAgOiBJbiBjYXNlIGJvcmRlciBwcmVzZW5jZSBvciBlZGdlIHByZXNlbmNlIGlzIGludmlzaWJsZSBvciBoaWRkZW4gdGhlbiBtYXJraW5nIGJvcmRlciBhcyBub25lCiAgICAgICAgICAgICAgICAgICAgaWYoYm9yZGVyLnByZXNlbmNlPT0iaGlkZGVuIgogICAgICAgICAgICAgICAgICAgICAgICB8fCBib3JkZXIucHJlc2VuY2U9PSJpbnZpc2libGUiCiAgICAgICAgICAgICAgICAgICAgICAgIHx8IGFsbEVkZ2VIaWRkZW4pewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzLmVsKS5jc3MoImJvcmRlciIsICJub25lIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMuZWRnZVByZXNlbmNlID0gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgLy9nZW5lcmljIGZ1bmN0aW9uIHRvIGNvbXB1dGUgY3NzIHN0eWxlIGZyb20gdGhlIDxmb250PiAmIDxwYXJhPiBlbGVtZW50IG9mIHRoZSBtb2RlbAogICAgICAgIF9nZXRUZXh0U3R5bGUgOiBmdW5jdGlvbihyZWZlcmVuY2VNb2RlbCkgewogICAgICAgICAgICB2YXIgY3NzU3R5bGVPYmo9e307CiAgICAgICAgICAgIHZhciBhc3BhcmFTdHlsZXNPYmogPSB7fTsKCiAgICAgICAgICAgIHZhciBmb250RWxlbWVudCA9IHJlZmVyZW5jZU1vZGVsLmdldEVsZW1lbnQoJ2ZvbnQnLDAsdHJ1ZSk7CiAgICAgICAgICAgIGlmKGZvbnRFbGVtZW50KSB7CiAgICAgICAgICAgICAgICBjc3NTdHlsZU9ialsnZm9udC1mYW1pbHknXSA9IGZvbnRFbGVtZW50LmdldEF0dHJpYnV0ZSgndHlwZWZhY2UnKTsKICAgICAgICAgICAgICAgIGNzc1N0eWxlT2JqWydmb250LXNpemUnXSAgID0gdGhpcy5fY29udmVydFRvUHgoZm9udEVsZW1lbnQuZ2V0QXR0cmlidXRlKCdzaXplJykpOwogICAgICAgICAgICAgICAgY3NzU3R5bGVPYmpbJ2ZvbnQtc3R5bGUnXSAgPSBmb250RWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3Bvc3R1cmUnKTsKICAgICAgICAgICAgICAgIGNzc1N0eWxlT2JqWydmb250LXdlaWdodCddID0gZm9udEVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3ZWlnaHQnKTsKICAgICAgICAgICAgICAgIGNzc1N0eWxlT2JqWyd0ZXh0LWRlY29yYXRpb24nXSA9IGZvbnRFbGVtZW50LmdldEF0dHJpYnV0ZSgndW5kZXJsaW5lJykgIT0gMCA/ICd1bmRlcmxpbmUnIDogdW5kZWZpbmVkOwoKICAgICAgICAgICAgICAgIHZhciBmaWxsID0gZm9udEVsZW1lbnQuZ2V0RWxlbWVudCgnZmlsbCcsMCx0cnVlKTsKICAgICAgICAgICAgICAgIGlmKGZpbGwpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY29sb3IgPSBmaWxsLmdldEVsZW1lbnQoJ2NvbG9yJywwLHRydWUpOwogICAgICAgICAgICAgICAgICAgIHZhciBjb2xvclZhbHVlID0gY29sb3IudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgaWYoY29sb3JWYWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICBjc3NTdHlsZU9ialsnY29sb3InXSA9ICdyZ2IoJytjb2xvclZhbHVlKycpJzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBwYXJhID0gcmVmZXJlbmNlTW9kZWwuZ2V0RWxlbWVudCgncGFyYScsMCx0cnVlKTsKICAgICAgICAgICAgaWYocGFyYSkgewogICAgICAgICAgICAgICAgaWYocGFyYS5oQWxpZ24pICB7CiAgICAgICAgICAgICAgICAgICAgYXNwYXJhU3R5bGVzT2JqWydyaWdodCddPSB0aGlzLl9jb252ZXJ0VG9QeChwYXJhLm1hcmdpblJpZ2h0KTsKICAgICAgICAgICAgICAgICAgICBhc3BhcmFTdHlsZXNPYmpbJ2xlZnQnXT0gdGhpcy5fY29udmVydFRvUHgocGFyYS5tYXJnaW5MZWZ0KTsKICAgICAgICAgICAgICAgICAgICBhc3BhcmFTdHlsZXNPYmpbJ292ZXJmbG93J109ICJoaWRkZW4iOwogICAgICAgICAgICAgICAgICAgIHN3aXRjaChwYXJhLmhBbGlnbikgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJyaWdodCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3BhcmFTdHlsZXNPYmpbJ3RleHQtYWxpZ24nXT0gInJpZ2h0IjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJsZWZ0IjoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAicmFkaXgiOiAgLy9UaWxsIG5vdyByYWRpeCBpcyBub3QgaW1wbGVtZW50ZWQsIGl0IGlzIG1hcHBlZCB0byB0aGUgZGVmYXVsdCBvbmUgaS5lIGxlZnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcGFyYVN0eWxlc09ialsndGV4dC1hbGlnbiddPSAibGVmdCI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAiY2VudGVyIjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcGFyYVN0eWxlc09ialsndGV4dC1hbGlnbiddPSAiY2VudGVyIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJqdXN0aWZ5IjoKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAianVzdGlmeUFsbCI6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3BhcmFTdHlsZXNPYmpbJ3RleHQtYWxpZ24nXT0gImp1c3RpZnkiOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc3dpdGNoKHBhcmEudkFsaWduKSB7CiAgICAgICAgICAgICAgICAgICBjYXNlICJ0b3AiOgogICAgICAgICAgICAgICAgICAgICAgIGFzcGFyYVN0eWxlc09ialsndG9wJ109IHRoaXMuX2NvbnZlcnRUb1B4KHBhcmEuc3BhY2VBYm92ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICBjYXNlICJib3R0b20iOgogICAgICAgICAgICAgICAgICAgICAgIGFzcGFyYVN0eWxlc09ialsnYm90dG9tJ109IHRoaXMuX2NvbnZlcnRUb1B4KHBhcmEuc3BhY2VCZWxvdyk7CiAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBhc3BhcmFTdHlsZXNPYmpbJ3RleHQtaW5kZW50J10gPSB0aGlzLl9jb252ZXJ0VG9QeChwYXJhLnRleHRJbmRlbnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB7Zm9udFN0eWxlcyA6IGNzc1N0eWxlT2JqLCBwYXJhU3R5bGVzIDogIGFzcGFyYVN0eWxlc09ian07CiAgICAgICAgfSwKCiAgICAgICAgX2NvbnZlcnRYRkFSaWNoVG9IdG1sOiBmdW5jdGlvbih0ZXh0KXsKICAgICAgICAgICAgdmFyIHZhbHVlOwogICAgICAgICAgICBpZih0ZXh0ICE9IG51bGwpICB7CiAgICAgICAgICAgICBpZih0eXBlb2YgdGV4dCA9PSAnc3RyaW5nJyAmJiB0ZXh0WzBdICE9ICc8JykgewogICAgICAgICAgICAgICAgIHRleHQgPSAiPHNwYW4+Iit0ZXh0KyI8L3NwYW4+IjsgICAvLyAkLnJlcGxhY2VXaXRoIGV4cGVjdHMgYSBIVE1MIHN0cmluZwogICAgICAgICAgICAgfQoKICAgICAgICAgICAgIC8vLS1jb252ZXJzaW9uIHRvIGpRdWVyeSBvYmogdG8gaGFuZGxlIGZvbnQtc2l6ZSBvZiBzcGFuCiAgICAgICAgICAgICB2YXIgc3BhblRleHQgPSAkKHRleHQpOwogICAgICAgICAgICAgc3BhblRleHQuZmluZCgiKiIpLmVhY2goZnVuY3Rpb24oaW5kZXgsIHNwYW4pewogICAgICAgICAgICAgICAgICBpZihzcGFuLnN0eWxlKSB7CiAgICAgICAgICAgICAgICAgICAgICBpZihzcGFuLnN0eWxlLmZvbnRTaXplKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5fY29udmVydFRvUHgoc3Bhbi5zdHlsZS5mb250U2l6ZSkrInB4IjsKICAgICAgICAgICAgICAgICAgICAgICAgc3Bhbi5zdHlsZVsnZm9udC1zaXplJ10gPSBzcGFuLnN0eWxlLmZvbnRTaXplID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICB0ZXh0PSAiPHNwYW4+IitzcGFuVGV4dC5odG1sKCkrIjwvc3Bhbj4iOwogICAgICAgICAgIH0KICAgICAgICAgICByZXR1cm4gdGV4dDsKICAgICAgICB9LAoKICAgICAgICBfaW5pdEFjY2Vzc2liaWxpdHlJbmZvOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgLy9hY2Nlc3NpYmlsaXR5IGluZm8KCiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0TW9kZWwuY29sc3BhbiA+IDEpIHsKICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoImNvbHNwYW4iLCB0aGlzLmxheW91dE1vZGVsLmNvbHNwYW4pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0TW9kZWwucm93c3BhbiA+IDEpIHsKICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvd3NwYW4iLCB0aGlzLmxheW91dE1vZGVsLnJvd3NwYW4pOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBUT0RPIC0gbW92ZSB0aGVzZSB0YWJsZSByZWxhdGVkIHN0dWZmIHRvIHRhYmxlIHZpZXcKICAgICAgICAgICAgLy9UaGUgYmVsb3cgcm9sZXMgYXJlIG5vdCBjb25mbGljdGluZyB3aXRoIHRoZSBuYXRpdmUgYWNjZXNzaWJpbGl0eSBzdXBwb3J0IGludHJvZHVjZWQgaW4gRGF0YVRhYmxlcywgYnV0CiAgICAgICAgICAgIC8vbm90IHJlY29tbWVuZGVkIHVudGlsIHNjcmlwdGVkIGRhdGEgZWxlbWVudCBpcyB1c2VkIChSZWZlciB0bzogaHR0cDovL3d3dy53My5vcmcvVFIvYXJpYS1pbi1odG1sLykuCiAgICAgICAgICAgIC8vV2l0aCB0aGUgaW50cm9kdWN0aW9uIG9mIHJvdy1zcGFuIGFuZCByb3cgaGVhZGVyIC0gdGhlIGN1cnJlbnQgaW5mbyBpcyBub3QgY29tcGxldGUgZm9yIEFSSUEtUm9sZXMKICAgICAgICAgICAgLy9TbyBpZiBuYXRpdmUgSFRNTCB0YWJsZSBpcyBiZWluZyB1c2VkIGZvciByZW5kZXIgKERhdGFUYWJsZUxheW91dCwgZG8gbm90IGFkZCB0aGUgQVJJQS1Sb2xlcyBiZWxvdykuCiAgICAgICAgICAgIC8vIC0gTm8gY2hhbmdlIHJlcXVpcmVkIGZvciB0YWJsZSBhcyBsYXlvdXQgZm9yIERhdGFUYWJsZSBpcyAgREFUQV9MQVlPVVRfVEFCTEUKICAgICAgICAgICAgLy8gLSBEbyBub3QgYWRkIGFjY2Vzc2liaWxpdHkgZm9yICdjb2x1bW5oZWFkZXInIG9yICdncmlkY2VsbCcgaWYgbm9kZSBpcyBUSCBvciBUUiAodGhlIGNoZWNrIHdpbGwgYWxzbyBhdm9pZCB0aGUgaW5lZmZpY2llbnQgY2hlY2spCiAgICAgICAgICAgIC8vIC0gRG8gbm90IGFkZCB0aGUgYWNjZXNzaWJpbGl0eSBmb3IgJ3JvdycgaWYgbm9kZSBpcyBUUgogICAgICAgICAgICB2YXIgbm9kZU5hbWUgPSB0aGlzLmVsLm5vZGVOYW1lOwogICAgICAgICAgICB2YXIgcGFydE9mTmF0aXZlVGFibGUgPSAobm9kZU5hbWUgPT0gIlRBQkxFIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBub2RlTmFtZSA9PSAiVFIiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IG5vZGVOYW1lID09ICJURCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgbm9kZU5hbWUgPT0gIlRIIik7CgogICAgICAgICAgICBpZighcGFydE9mTmF0aXZlVGFibGUpIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfVEFCTEUpIHsKICAgICAgICAgICAgICAgICAgICAvL3B1dCBncmlkIHJvbGUKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJyb2xlIiwgImdyaWQiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX2lzVGFibGVIZWFkZXJDZWxsKCkpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJyb2xlIiwgImNvbHVtbmhlYWRlciIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5faXNUYWJsZUNlbGwoKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvbGUiLCAiZ3JpZGNlbGwiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMubGF5b3V0TW9kZWwubGF5b3V0ID09IHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9ST1cpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJyb2xlIiwgInJvdyIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5sYXlvdXRNb2RlbC5sYXlvdXQgPT0geGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1JJR0hUTEVGVFJPVykgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvbGUiLCAicm93Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy9hZGQgcm9sZSBhbmQgdGl0bGUgdG8gdGhpcy4kZWwKICAgICAgICAgICAgdmFyIGFzc2lzdCA9IHRoaXMubW9kZWwuZ2V0RWxlbWVudCgiYXNzaXN0IiwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIGlmKGFzc2lzdCAmJiBhc3Npc3Qucm9sZSkgewogICAgICAgICAgICAgICAgLy90cmFuc2xhdGUgWEZBIHJvbGVzIHRvIEhUTUw1IHJvbGVzIChXQXJpYSByb2xlcykKICAgICAgICAgICAgICAgIGlmKGFzc2lzdC5yb2xlID09ICdUUicgJiYgIXBhcnRPZk5hdGl2ZVRhYmxlKQogICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvbGUiLCAicm93Iik7CiAgICAgICAgICAgICAgICBlbHNlIGlmKGFzc2lzdC5yb2xlID09ICdUSCcpewogICAgICAgICAgICAgICAgICAgIC8vZG8gbm90aGluZyBhcyBoZWFkZXIgaW5mbyBpcyB0byBiZSBwcm9wYWdhdGVkIHRvIGluZGl2aWR1YWwgY2VsbHMKICAgICAgICAgICAgICAgICAgICAvL3RoaXMuJGVsLmF0dHIoInJvbGUiLCAicm93Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKGFzc2lzdC5yb2xlID09ICdURicpewogICAgICAgICAgICAgICAgICAgIC8vZG8gbm90aGluZyBhcyBoZWFkZXIgaW5mbyBpcyB0byBiZSBwcm9wYWdhdGVkIHRvIGluZGl2aWR1YWwgY2VsbHMKICAgICAgICAgICAgICAgICAgICAvL3RoaXMuJGVsLmF0dHIoInJvbGUiLCAicm93Iik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKCFwYXJ0T2ZOYXRpdmVUYWJsZSkgewogICAgICAgICAgICAgICAgICAgIC8vIGxpc3Qgcm9sZSBuZWVkcyB0byBiZSB1c2VkIGZvciBhIGRpdiB3aXRoIGxpc3Qgb2YgaXRlbXMgYW5kIGxpc3RpdGVtIHJvbGUgZm9yIGl0cyBjaGlsZHJlbi4KICAgICAgICAgICAgICAgICAgICBpZihhc3Npc3Qucm9sZSA9PSAnVUwnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvbGUiLCAibGlzdCIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZihhc3Npc3Qucm9sZSA9PSAiTEkiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvbGUiLCAibGlzdGl0ZW0iKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJyb2xlIiwgYXNzaXN0LnJvbGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG5vZGVOYW1lID09PSAiVEFCTEUiKSB7CiAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJhcmlhLWxhYmVsIiwgdGhpcy5fZ2V0U2NyZWVuUmVhZGVyVGV4dCgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9hZGQgbGFuZyBwYXJhbWV0ZXIKICAgICAgICAgICAgdmFyIGxhbmcgPSB0aGlzLl9sYW5nRnJvbUxvY2FsZSh0aGlzLm1vZGVsLmpzb25Nb2RlbC5sb2NhbGUpOwogICAgICAgICAgICBpZihsYW5nICYmIGxhbmcubGVuZ3RoID4gMCl7CiAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJsYW5nIiwgbGFuZyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMuX2Fzc2lnblRvb2xUaXAoKTsKICAgICAgICB9LAoKICAgICAgICBfYXNzaWduVG9vbFRpcCA6IGZ1bmN0aW9uICgpIHsKICAgICAgICB9LAoKICAgICAgICBfZ2V0U2NyZWVuUmVhZGVyVGV4dDogZnVuY3Rpb24oKXsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBpCiAgICAgICAgICogQHBhcmFtIHZhbAogICAgICAgICAqIEByZXR1cm4ge1N0cmluZ30KICAgICAgICAgKiBAcHJpdmF0ZSB1c2VkIGJ5IFhmYURyYXdWaWV3IGFuZCBGaWVsZFZpZXcKICAgICAgICAgKi8KICAgICAgICBfYWRqdXN0VGV4dENvb3JkaW5hdGU6IGZ1bmN0aW9uKGksIHZhbCl7CiAgICAgICAgICAgIC8vc29tZWhvdyBqcXVlcnkgYXR0cigpIGZ1bmN0aW9uIGNhbm5vdCByZWFkIHRleHRMZW5ndGggYXR0cmlidXRlCiAgICAgICAgICAgIHZhciBzVGV4dExlbiA9IHRoaXMuZ2V0QXR0cmlidXRlKCd0ZXh0TGVuZ3RoJyk7CiAgICAgICAgICAgIGlmKHNUZXh0TGVuICYmIHZhbCAmJiB2YWwubGVuZ3RoID4gMikgewogICAgICAgICAgICAgICAgLy9yZW1vdmUgcHgKICAgICAgICAgICAgICAgIHZhciB0ZXh0TGVuID0gTnVtYmVyKHNUZXh0TGVuLnN1YnN0cigwLCBzVGV4dExlbi5sZW5ndGgtMikpOwogICAgICAgICAgICAgICAgdmFyIHggPSBOdW1iZXIodmFsLnN1YnN0cigwLCB2YWwubGVuZ3RoLTIpKTsKICAgICAgICAgICAgICAgIC8vc2VydmVyIGFkanVzdCB4IGZvciBhbGwgcnRsIHRleHQgY29udGVudCBzbyB3ZSBuZWVkIHRvIHJldmVydCBpdCBiYWNrIGZvciB3ZWJraXQKICAgICAgICAgICAgICAgIHggKz0gdGV4dExlbjsKICAgICAgICAgICAgICAgIHJldHVybiB4KyJweCI7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAgKgogICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICogaW50ZXJuYWwgZnVuY3Rpb24gdG8gZXh0cmFjdCBsYW5nIGZyb20gbG9jYWxlCiAgICAgICAgICovCiAgICAgICAgX2xhbmdGcm9tTG9jYWxlIDogZnVuY3Rpb24obG9jYWxlKSB7CiAgICAgICAgICAgIHZhciBsYW5nOwogICAgICAgICAgICBpZihsb2NhbGUgJiYgbG9jYWxlLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIC8vbG9jYWxlIGNhbiBiZSBpbiB0aGUgZm9ybSBvZiBjb3VudHJ5X0xBTkcgLS0gZW5fVVMKICAgICAgICAgICAgICAgIC8vV2hlcmVhcyBsYW5nIGF0dHJpYnV0ZSBvZiBodG1sIGV4cGVjdHMgb25seSBjb3VudHJ5IGNvZGUKICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IGxvY2FsZS5pbmRleE9mKCdfJyk7CgogICAgICAgICAgICAgICAgaWYoaW5kZXggIT0gLTEpewogICAgICAgICAgICAgICAgICAgIGxhbmcgPSBsb2NhbGUuc3Vic3RyKDAsIGluZGV4KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGxhbmcgPSBsb2NhbGU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy9sZWFwIG9mIGZhaXRoIHRoYXQgbGFuZyB3b3VsZCBiZSBJU08gNjMxIGNvbXBsYWludC4KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbGFuZzsKICAgICAgICB9LAoKICAgICAgICBzZXRFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAgICAgICB0aGlzLnVuZGVsZWdhdGVFdmVudHMoKTsKICAgICAgICAgIHRoaXMuX3NldEVsZW1lbnQoZWxlbWVudCk7CiAgICAgICAgICB0aGlzLmRlbGVnYXRlRXZlbnRzKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9LAoKICAgICAgICBfc2V0RWxlbWVudDogZnVuY3Rpb24oZWwpIHsKICAgICAgICAgIHRoaXMuJGVsID0gZWwgaW5zdGFuY2VvZiAkID8gZWwgOiAkKGVsKTsKICAgICAgICAgIHRoaXMuZWwgPSB0aGlzLiRlbFswXTsKICAgICAgICB9LAoKCiAgICAgICAgZGVsZWdhdGVFdmVudHM6IGZ1bmN0aW9uKGV2ZW50cykgewogICAgICAgICAgdmFyIGRlbGVnYXRlRXZlbnRTcGxpdHRlciA9IC9eKFxTKylccyooLiopJC87CiAgICAgICAgICBldmVudHMgfHwgKGV2ZW50cyA9IF8ucmVzdWx0KHRoaXMsICdldmVudHMnKSk7CiAgICAgICAgICBpZiAoIWV2ZW50cykgcmV0dXJuIHRoaXM7CiAgICAgICAgICB0aGlzLnVuZGVsZWdhdGVFdmVudHMoKTsKICAgICAgICAgIGZvciAodmFyIGtleSBpbiBldmVudHMpIHsKICAgICAgICAgICAgdmFyIG1ldGhvZCA9IGV2ZW50c1trZXldOwogICAgICAgICAgICBpZiAoIV8uaXNGdW5jdGlvbihtZXRob2QpKSBtZXRob2QgPSB0aGlzW21ldGhvZF07CiAgICAgICAgICAgIGlmICghbWV0aG9kKSBjb250aW51ZTsKICAgICAgICAgICAgdmFyIG1hdGNoID0ga2V5Lm1hdGNoKGRlbGVnYXRlRXZlbnRTcGxpdHRlcik7CiAgICAgICAgICAgIHRoaXMuZGVsZWdhdGUobWF0Y2hbMV0sIG1hdGNoWzJdLCBfLmJpbmQobWV0aG9kLCB0aGlzKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9LAoKICAgICAgICBkZWxlZ2F0ZTogZnVuY3Rpb24oZXZlbnROYW1lLCBzZWxlY3RvciwgbGlzdGVuZXIpIHsKICAgICAgICAgIHRoaXMuJGVsLm9uKGV2ZW50TmFtZSArICcuZGVsZWdhdGVFdmVudHMnICsgdGhpcy5jaWQsIHNlbGVjdG9yLCBsaXN0ZW5lcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9LAoKICAgICAgICB1bmRlbGVnYXRlRXZlbnRzOiBmdW5jdGlvbigpIHsKICAgICAgICAgIGlmICh0aGlzLiRlbCkgdGhpcy4kZWwub2ZmKCcuZGVsZWdhdGVFdmVudHMnICsgdGhpcy5jaWQpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRMYXlvdXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgcHJlc2VuY2UgPSB0aGlzLm1vZGVsID8gdGhpcy5tb2RlbC5wcmVzZW5jZSA6ICJ2aXNpYmxlIjsKCiAgICAgICAgICAgIGlmKCF0aGlzLmxheW91dE1vZGVsKXsKICAgICAgICAgICAgICAgIC8vSWYgbGF5b3V0bW9kZWwgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkLCBpbml0aWFsaXplIHRoYXQuCiAgICAgICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplTGF5b3V0TW9kZWwoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYodGhpcy5faXNQbGFjZUhvbGRlckVsKCkgJiYgKHByZXNlbmNlID09ICJ2aXNpYmxlIiB8fCBwcmVzZW5jZSA9PSAiaW52aXNpYmxlIikpewogICAgICAgICAgICAgICAgLy8gQ3VycmVudGx5IHdlIGFyZSBvbiBhIHBsYWNlaG9sZGVyIGRpdiBlbCAoYmVjYXVzZSB0aGlzIGVsZW1lbnQgd2FzIGhpZGRlbiBvciBpbmFjdGl2ZSkuIEl0J3MgdGltZSB0byBmaW5kIHRoZSBhY3R1YWwgZWxlbWVudC4KICAgICAgICAgICAgICAgIHZhciB0ZW1wbGF0ZUlkID0gKHRoaXMubW9kZWwgPyB0aGlzLm1vZGVsLl90ZW1wbGF0ZUlkKCkgOiB0aGlzLl9pZCkgfHwgdGhpcy5faWQ7CiAgICAgICAgICAgICAgICB2YXIgYWN0dWFsRWwgPSB0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS50ZW1wbGF0ZUNhY2hlKCkuZ2V0KHRlbXBsYXRlSWQsIHRydWUpOwogICAgICAgICAgICAgICAgaWYoYWN0dWFsRWwpewogICAgICAgICAgICAgICAgICAgIC8vIGhpZGVzIHRoZSBhY3R1YWxFTCBhcyB0aGUgbGF5b3V0IGlzIHN0aWxsIGRpc3R1cmJlZCwgcmVtb3ZlcyB0aGUgaGlkZUVsZW1lbnQgY2xhc3Mgb24gdXBkYXRlRGlzcGxheQogICAgICAgICAgICAgICAgICAgICQoYWN0dWFsRWwpLmFkZENsYXNzKCJoaWRlRWxlbWVudCIpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLnJlcGxhY2VXaXRoKGFjdHVhbEVsKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQoYWN0dWFsRWwpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuJGRhdGEodGhpcy5lbCwgInhmYVZpZXciLCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplTGF5b3V0TW9kZWwoKTsgLy9uZWVkIHRvIHJlLWluaXRpYWxpemUgbGF5b3V0IG1vZGVsIGF0IHRoaXMgcG9pbnQuCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5lcnJvcigieGZhVmlldyIsICJIdG1sIHRlbXBsYXRlIGNvdWxkIG5vdCBiZSBmb3VuZC4gaWQ6Iit0aGlzLl9pZCsiLCBzb206Iit0aGlzLmdldE9yRWxzZSh0aGlzLm1vZGVsLCAic29tRXhwcmVzc2lvbiIpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYocHJlc2VuY2UgPT0gInZpc2libGUiKXsKICAgICAgICAgICAgICAgIHZhciBub2RlTmFtZSA9ICIiOwogICAgICAgICAgICAgICAgaWYodGhpcy5tb2RlbCl7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VELCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbml0QWNjZXNzaWJpbGl0eUluZm8oKTsKICAgICAgICAgICAgICAgICAgICBub2RlTmFtZSA9IHRoaXMubW9kZWwuZ2V0QXR0cmlidXRlKCJuYW1lIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBhcyBwYXJ0IG9mIGh0bWwgc2l6ZSByZWR1Y3Rpb24sIHNlcnZlciBzdG9wcGVkIHNlbmRpbmcgbm9kZSB0eXBlIGFuZCBuYW1lIG9mIHRoZSBjb21wb25lbnQKICAgICAgICAgICAgICAgIC8vIGFkZCBjbGFzc2VzIGZvciB0aGUgc2FtZQogICAgICAgICAgICAgICAgdmFyIG5vZGVUeXBlID0gKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS4kZGF0YSh0aGlzLmVsLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5YRkFfTU9ERUwpIHx8e30pW3hmYWxpYi52aWV3LkxheW91dENvbnN0Lk5PREVfVFlQRV07CiAgICAgICAgICAgICAgICBpZihub2RlVHlwZSkKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hZGRDbGFzcyhub2RlVHlwZSk7CiAgICAgICAgICAgICAgICBpZihub2RlTmFtZSAhPSBudWxsICYmIG5vZGVOYW1lLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hZGRDbGFzcyhub2RlTmFtZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgZXh0ZW50ID0gdGhpcy5fY29tcHV0ZUV4dGVudCgpOwogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuZWwsIGV4dGVudCk7CiAgICAgICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7CiAgICAgICAgICAgIH0gZWxzZXsKICAgICAgICAgICAgICAgIC8vSWYgcHJlc2VuY2UgaXMgc2V0IHRvIHZpc2libGUgdGhlbiBfaGFuZGxlUHJlc2VuY2VDaGFuZ2UgaXMgY2FsbGVkIGFzIHBhcnQgb2Ygc3luYyBmcm9tIHN1YmNsYXNzZXMKICAgICAgICAgICAgICAgIC8vIEJ1dCBvdGhlcndpc2Ugd2UgbmVlZCB0byBleHBsaWNpdGxseSBjYWxsIF9oYW5kbGVQcmVzZW5jZUNoYW5nZSBoZXJlLgogICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlUHJlc2VuY2VDaGFuZ2Uoe25ld1RleHQgOiBwcmVzZW5jZX0pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRXZlbnQ6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgc3dpdGNoKGV2bnQubmFtZSkgewogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9DSEFOR0VEOgogICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlTW9kZWxDaGFuZ2VkKGV2bnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRE9NX0NIQU5HRUQ6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVEb21DaGFuZ2VkKGV2bnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAvKiBsb2cgYW4gZXJyb3IgbWVzc2FnZSAqLwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRG9tQ2hhbmdlZCA6IGZ1bmN0aW9uKGV2ZW50KXsKICAgICAgICAgICAgc3dpdGNoKGV2ZW50Ll9wcm9wZXJ0eSkgewogICAgICAgICAgICAgICAgY2FzZSAiZm9udC5maWxsLmNvbG9yLnZhbHVlIjoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVGb250RmlsbENvbG9yVmFsdWUoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiYm9yZGVyLmZpbGwuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgY2FzZSAidGV4dEVkaXQuYm9yZGVyLmZpbGwuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgY2FzZSAibnVtZXJpY0VkaXQuYm9yZGVyLmZpbGwuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgY2FzZSAiaW1hZ2VFZGl0LmJvcmRlci5maWxsLmNvbG9yLnZhbHVlIjoKICAgICAgICAgICAgICAgIGNhc2UgInNpZ25hdHVyZS5ib3JkZXIuZmlsbC5jb2xvci52YWx1ZSI6CiAgICAgICAgICAgICAgICBjYXNlICJkYXRlVGltZUVkaXQuYm9yZGVyLmZpbGwuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgY2FzZSAicGFzc3dvcmRFZGl0LmJvcmRlci5maWxsLmNvbG9yLnZhbHVlIjoKICAgICAgICAgICAgICAgIGNhc2UgImNob2ljZUxpc3QuYm9yZGVyLmZpbGwuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUJvcmRlckZpbGxDb2xvclZhbHVlKGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgImJvcmRlci5lZGdlLnByZXNlbmNlIjoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVCb3JkZXJFZGdlUHJlc2VuY2UoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAiYm9yZGVyLmVkZ2UuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUJvcmRlckNoYW5nZShldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJib3JkZXIuZWRnZS50aGlja25lc3MiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUJvcmRlckNoYW5nZShldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJib3JkZXIuZmlsbC5wcmVzZW5jZSI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQm9yZGVyRmlsbFByZXNlbmNlKGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInRvcEluc2V0IjoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVUb3BJbnNldChldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJib3R0b21JbnNldCI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQm90dG9tSW5zZXQoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAibGVmdEluc2V0IjoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVMZWZ0SW5zZXQoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAicmlnaHRJbnNldCI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlUmlnaHRJbnNldChldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYW5kbGVNb2RlbENoYW5nZWQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICBpZiAoZXZlbnQuX3Byb3BlcnR5ID09ICJwcmVzZW5jZSIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVByZXNlbmNlQ2hhbmdlKGV2ZW50KTsKICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudC5fcHJvcGVydHkgPT0gImFjY2VzcyIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUFjY2Vzc0NoYW5nZShldmVudCk7CiAgICAgICAgICAgIH1lbHNlIGlmIChldmVudC5fcHJvcGVydHkgPT0gInJlbGV2YW50IikgIHsKICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVJlbGV2YW50Q2hhbmdlKGV2ZW50KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVSZWxldmFudENoYW5nZSA6IGZ1bmN0aW9uKGV2ZW50KSB7Ci8vCQkJCXhmYS5Mb2dnZXIuZGVidWcoIltfaGFuZGxlUHJlc2VuY2VDaGFuZ2VdcHJlc2VuY2U6c29tIgovLwkJCQkJCSsgZXZlbnQubmV3VGV4dCArICI6IiArIHRoaXMuJGVsLmRhdGEoInNvbSIpKTsKICAgICAgICAgICAgc3dpdGNoIChldmVudC5uZXdUZXh0KSB7CiAgICAgICAgICAgICAgICBjYXNlICIrcHJpbnQiOgogICAgICAgICAgICAgICAgY2FzZSAicHJpbnQiIDoKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLm1vZGVsLmdldEF0dHJpYnV0ZSgicHJlc2VuY2UiKSA9PSAidmlzaWJsZSIpCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWwuc3R5bGUudmlzaWJpbGl0eSA9ICJoaWRkZW4iIDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgIi1wcmludCI6CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5tb2RlbC5nZXRBdHRyaWJ1dGUoInByZXNlbmNlIikgPT0gInZpc2libGUiKQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVsLnN0eWxlLnZpc2liaWxpdHkgPSAidmlzaWJsZSI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMucGFyZW50Vmlldy5pbnZhbGlkYXRlU2l6ZSgpOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVQcmVzZW5jZUNoYW5nZSA6IGZ1bmN0aW9uKGV2ZW50KSB7Ci8vCQkJCXhmYS5Mb2dnZXIuZGVidWcoIltfaGFuZGxlUHJlc2VuY2VDaGFuZ2VdcHJlc2VuY2U6c29tIgovLwkJCQkJCSsgZXZlbnQubmV3VGV4dCArICI6IiArIHRoaXMuJGVsLmRhdGEoInNvbSIpKTsKICAgICAgICAgICAgc3dpdGNoIChldmVudC5uZXdUZXh0KSB7CiAgICAgICAgICAgIGNhc2UgInZpc2libGUiOgogICAgICAgICAgICAgICAgaWYodGhpcy5tb2RlbC5nZXRBdHRyaWJ1dGUoInJlbGV2YW50IikgPT0gInByaW50IiB8fCB0aGlzLm1vZGVsLmdldEF0dHJpYnV0ZSgicmVsZXZhbnQiKSA9PSAiK3ByaW50IikKICAgICAgICAgICAgICAgICAgICB0aGlzLmVsLnN0eWxlLnZpc2liaWxpdHkgPSAiaGlkZGVuIiA7CiAgICAgICAgICAgICAgICBlbHNlIHRoaXMuZWwuc3R5bGUudmlzaWJpbGl0eT0gImluaGVyaXQiOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgImludmlzaWJsZSI6CiAgICAgICAgICAgIGNhc2UgImhpZGRlbiI6CiAgICAgICAgICAgIGNhc2UgImluYWN0aXZlIjoKICAgICAgICAgICAgICAgIHRoaXMuZWwuc3R5bGUudmlzaWJpbGl0eSA9ICJoaWRkZW4iOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB0aGlzLmVsLnN0eWxlLnZpc2liaWxpdHk9ICJpbmhlcml0IjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICBGT1JNUy0xMTM2MyA6IGZpeCBmb3IgaGVpZ2h0IGNhbGN1bGF0aW9uIG9mIHRhYmxlIGNlbGwKICAgICAgICAgICAgIEVuYWJsZSB0aGlzIHRvZ2dsZSBmb3Igb2xkIGJlaGF2aW91ciAoaWYgYW55IHJlZ3Jlc3Npb24gY29tZXMpCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoKHdpbmRvdy5GRCAmJiB3aW5kb3cuRkQuaXNUb2dnbGVFbmFibGVkKCJGVF9GT1JNUy0xMTM2MyIpKSAmJiB4ZmFsaWIucnVudGltZS54ZmEuZm9ybS5tYkluaXRpYWxpemVkKSB7CiAgICAgICAgICAgICAgICB0aGlzLnBhcmVudFZpZXcuaW52YWxpZGF0ZVNpemUoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRoaXMucGFyZW50Vmlldy5pbnZhbGlkYXRlU2l6ZSgpOwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVSaWdodEluc2V0IDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlQm90dG9tSW5zZXQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAvKnZhciBib3R0b21JbnNldCA9IHBhcnNlRmxvYXQoZXZlbnQucHJldlRleHQpIDsKICAgICAgICAgICAgIGlmKGJvdHRvbUluc2V0KSAgewogICAgICAgICAgICAgdmFyIGV4dGVudCA9IHRoaXMuX2NvbXB1dGVFeHRlbnQoKTsKICAgICAgICAgICAgIGV4dGVudFsibWFyZ2luLWJvdHRvbSJdID0gIHRoaXMuX21tMnB4KDI1LjQqIGJvdHRvbUluc2V0KSA7CiAgICAgICAgICAgICB0aGlzLmxheW91dE1vZGVsLm1hcmdpbmJvdHRvbSA9IGV4dGVudFsibWFyZ2luLWJvdHRvbSJdOwogICAgICAgICAgICAgdGhpcy5faW52YWxpZERpc3BsYXlGbGFnID0gdHJ1ZTsKICAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRlRGlzcGxheSgpOwogICAgICAgICAgICAgdmFyIGE9IHRoaXMubWVhc3VyZVNpemUoKTsKICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLmVsLCBleHRlbnQpOwogICAgICAgICAgICAgfSAqLwoKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlTGVmdEluc2V0IDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlVG9wSW5zZXQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVGb250RmlsbENvbG9yVmFsdWUgOiBmdW5jdGlvbihldmVudCkgewoKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlQm9yZGVyRmlsbENvbG9yVmFsdWUgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICB2YXIgYm9yZGVyRmlsbENvbG9yVmFsdWUgPSBldmVudC5wcmV2VGV4dDsKICAgICAgICAgICAgdmFyIHZpc2liaWxpdHkgPSAgdGhpcy5tb2RlbC5ib3JkZXIuZmlsbC5wcmVzZW5jZSA7CgogICAgICAgICAgICBpZihib3JkZXJGaWxsQ29sb3JWYWx1ZSAmJiB2aXNpYmlsaXR5ICE9ICJpbnZpc2libGUiICYmIHZpc2liaWxpdHkgIT0gImhpZGRlbiIpICB7CiAgICAgICAgICAgICAgICBpZihib3JkZXJGaWxsQ29sb3JWYWx1ZS5pbmRleE9mKCJyZ2IiKSA9PSAtMSkKICAgICAgICAgICAgICAgICAgICBib3JkZXJGaWxsQ29sb3JWYWx1ZSA9ICJyZ2IoIiArIGJvcmRlckZpbGxDb2xvclZhbHVlICsgIikiOwoKICAgICAgICAgICAgICAgIGlmIChfLmNvbnRhaW5zKFsidGV4dEVkaXQiLCJudW1lcmljRWRpdCIsImltYWdlRWRpdCIsInNpZ25hdHVyZSIsImRhdGVUaW1lRWRpdCIsImNob2ljZUxpc3QiLAogICAgICAgICAgICAgICAgICAgICAgICAicGFzc3dvcmRFZGl0Il0sIGV2ZW50Ll9wcm9wZXJ0eS5zdWJzdHJpbmcoMCxldmVudC5fcHJvcGVydHkuaW5kZXhPZignLicpKSkpIHsKICAgICAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5jc3MoImJhY2tncm91bmQtY29sb3IiLCBib3JkZXJGaWxsQ29sb3JWYWx1ZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYoIGV2ZW50Ll9wcm9wZXJ0eSA9PT0gImJvcmRlci5maWxsLmNvbG9yLnZhbHVlIikgewogICAgICAgICAgICAgICAgICAgICQodGhpcy5lbCkuY3NzKCJiYWNrZ3JvdW5kLWNvbG9yIiwgYm9yZGVyRmlsbENvbG9yVmFsdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUJvcmRlckVkZ2VQcmVzZW5jZSA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciB2aXNpYmlsaXR5ID0gZXZlbnQucHJldlRleHQ7CiAgICAgICAgICAgIHZhciBkZWZhdWx0Qm9yZGVyID0gIjFweCBzb2xpZCByZ2IoMCwgMCwgMCkiCiAgICAgICAgICAgIGlmKHZpc2liaWxpdHkgPT0gImhpZGRlbiIgfHwgdmlzaWJpbGl0eSA9PSAiaW52aXNpYmxlIikgewogICAgICAgICAgICAgICAgJCh0aGlzLmVsKS5jc3MoImJvcmRlciIsICJub25lIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB2YXIgY3NzU3R5bGVPYmogPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5nZXRTdHlsZUZvckJvcmRlcih0aGlzLm1vZGVsLmJvcmRlcik7CiAgICAgICAgICAgICAgICBpZihjc3NTdHlsZU9iaikKICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy5lbCwgY3NzU3R5bGVPYmopOwogICAgICAgICAgICAgICAgZWxzZSAkKHRoaXMuZWwpLmNzcygiYm9yZGVyIiwgZGVmYXVsdEJvcmRlcik7CiAgICAgICAgICAgIH0KCgogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVCb3JkZXJDaGFuZ2UgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICB2YXIgY3NzU3R5bGVPYmogPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5nZXRTdHlsZUZvckJvcmRlcih0aGlzLm1vZGVsLmJvcmRlcik7CiAgICAgICAgICAgIGlmKGNzc1N0eWxlT2JqKQogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuZWwsIGNzc1N0eWxlT2JqKTsKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlQm9yZGVyRmlsbFByZXNlbmNlIDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgdmFyIGJvcmRlckZpbGxQcmVzZW5jZSA9IGV2ZW50LnByZXZUZXh0OwogICAgICAgICAgICB2YXIgY29sb3IgPSB0aGlzLm1vZGVsLmJvcmRlci5maWxsLmNvbG9yLnZhbHVlOwogICAgICAgICAgICBpZihib3JkZXJGaWxsUHJlc2VuY2UgPT0gImhpZGRlbiIgfHwgYm9yZGVyRmlsbFByZXNlbmNlID09ICJpbnZpc2libGUiKXsKICAgICAgICAgICAgICAgICQodGhpcy5lbCkuY3NzKCJiYWNrZ3JvdW5kLWNvbG9yIiwgInJnYigyNTUsMjU1LDI1NSkiICkKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGlmKGNvbG9yLmluZGV4T2YoInJnYiIpID09IC0xKQogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gInJnYigiICsgY29sb3IgKyAiKSI7CiAgICAgICAgICAgICAgICAkKHRoaXMuZWwpLmNzcygiYmFja2dyb3VuZC1jb2xvciIsIGNvbG9yKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9maWxsQ29sb3IgOiBmdW5jdGlvbihjb2xvcikgewogICAgICAgICAgICAkKHRoaXMuZWwpLmNzcygiYmFja2dyb3VuZC1jb2xvciIsIGNvbG9yKQogICAgICAgIH0sCgogICAgICAgIF9ib3JkZXJDb2xvciA6IGZ1bmN0aW9uKGNvbG9yKSB7CiAgICAgICAgICAgICQodGhpcy5lbCkuY3NzKCJib3JkZXJDb2xvciIsIGNvbG9yKQogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVBY2Nlc3NDaGFuZ2UgOiBmdW5jdGlvbihldmVudCkgewoKICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIFRoaXMgbWV0aG9kIGNhbGxzIF9pbml0TGF5b3V0IGluIGFkZGl0aW9uIHRvIGNhbGxpbmcgb3JpZ2luYWwgX3N5bmNGb3JtVG9IdG1sLgogICAgICAgICAqIFRoaXMgaXMgc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIHVzaW5nIHNlcnZlciBzaWRlIHNjcmlwdHMgYW5kIGNhbGxzIGRlZXAgc3luYy4KICAgICAgICAgKiBJZiB5b3UgYXJlIHN1cmUgdGhhdCBvYmplY3QgaGFzIGJlZW4gaW5pdGlhbGl6ZWQgY2FsbCBfc3luY0Zvcm1Ub0h0bWwgZWxzZSBjYWxsIHRoaXMgbWV0aG9kLgogICAgICAgICAqIE90aGVyIG9iamVjdHMob3RoZXIgdGhhbiAqdGhpcyopIHNob3VsZCBhbHdheXMgY2FsbCB0aGlzIG1ldGhvZCBpbnN0ZWFkT2YgaW50ZXJuYWwgX3N5bmNGb3JtVG9IdG1sIG1ldGhvZC4KICAgICAgICAgKi8KICAgICAgICBzeW5jRm9ybU5vZGVUb0h0bWw6IGZ1bmN0aW9uKGRlZXBTeW5jKXsKICAgICAgICAgICAgaWYoIXRoaXMuX2luaXRpYWxpemVkICYmIHRoaXMuX2lzUGxhY2VIb2xkZXJFbCgpKXsKICAgICAgICAgICAgICAgIC8vSWYgdGhpcyBpcyB1bmluaXRpYWxpemVkIHBsYWNlSG9sZGVyRWwoaW4gY2FzZSBwcmVzZW5jZSBpcyBoaWRkZW4gaW5pdGlhbGx5IGFuZCBoYXMgbm90IGJlZW4gY2hhbmdlZCBzaW5jZQogICAgICAgICAgICAgICAgLy8gdGhlbiB3ZSB3YW50IHRvIGF0dGVtcHQgYW4gX2luaXRMYXlvdXQgdG8gY2hlY2sgaWYgcHJlc2VuY2UgbmVlZHMgdG8gYmUgaGFuZGxlZC4KICAgICAgICAgICAgICAgIHRoaXMuX2luaXRMYXlvdXQoKTsKICAgICAgICAgICAgICAgIGlmKCF0aGlzLl9pbml0aWFsaXplZCAmJiB0aGlzLl9pc1BsYWNlSG9sZGVyRWwoKSl7CiAgICAgICAgICAgICAgICAgICAgLy9JZiB0aGlzIGlzIHN0aWxsIHBsYWNlSG9sZGVyRWwgdGhlbiBubyBwb2ludCBvZiBydW5uaW5nIGEgc3luYwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLl9zeW5jRm9ybU5vZGVUb0h0bWwoZGVlcFN5bmMpOwogICAgICAgIH0sCgogICAgICAgIF9zeW5jRm9ybU5vZGVUb0h0bWwgOiBmdW5jdGlvbihkZWVwU3luYykgewogICAgICAgICAgICAvLyBUT0RPIDogbWFrZSBzeW5jIGxvZ2ljIGJldHRlcgogICAgICAgICAgICBpZiAodGhpcy5tb2RlbCkgewogICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlUHJlc2VuY2VDaGFuZ2Uoe25ld1RleHQ6dGhpcy5tb2RlbC5wcmVzZW5jZX0pICA7CiAgICAgICAgICAgICAgICAvL3RoaXMuX2hhbmRsZUFjY2Vzc0NoYW5nZSh7bmV3VGV4dDp0aGlzLm1vZGVsLm1FZmZBY2Nlc3N9KSAgICAgIDsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLmludmFsaWRhdGVTaXplKCk7CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRpYWxpemVMYXlvdXRNb2RlbCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAvL0luIG9yZGVyIHRvIG1pbmltaXplIHRoZSBzaXplIG9mIGh0bWwgZ2VuZXJhdGVkLCB0aGlzIGxheW91dG1vZGVsIGlzIGdlbmVyYXRlZCBpbiBhIGNyeXB0aWMgd2F5CiAgICAgICAgICAgIC8vaGVyZSBpcyB0aGUgbWFwcGluZyBiZXR3ZWVuIHRoZSBjcnlwdGljIHZhcmlhYmxlcyBhbmQgZXhwbGFuYXRvcnkgdmFyaWFibGVzLgogICAgICAgICAgICAvL2luIHRoZSBpbnRlcmVzdCBvZiByZWFkYWJpbGl0eSwgcHJlc2VydmluZyB0aGUgZ29vZCByZWFkYWJsZSBuYW1lcwoKICAgICAgICAgICAgdmFyIGxtID0gdGhpcy5nZXRPckVsc2UodGhpcy4kZGF0YSh0aGlzLmVsLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5YRkFfTU9ERUwpLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfTU9ERUwsIHt9KQogICAgICAgICAgICB2YXIgbGF5b3V0ID0ge307CiAgICAgICAgICAgIGlmKHRoaXMgaW5zdGFuY2VvZiB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3ICYmICFsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5TVUJGT1JNX0xBWU9VVCkpewogICAgICAgICAgICAgICAgbGF5b3V0LmxheW91dCA9ICJwb3NpdGlvbiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZihsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5TVUJGT1JNX0xBWU9VVCkpIHsKICAgICAgICAgICAgICAgIGxheW91dC5sYXlvdXQgPSBsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5TVUJGT1JNX0xBWU9VVF0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9YKSkKICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnR4ID0gdGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX1hdKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbGF5b3V0LmV4dGVudHggPSAwOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9ZKSkKICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnR5ID0gdGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX1ldKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbGF5b3V0LmV4dGVudHkgPSAwOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NSU5fVykpCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWludyA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NSU5fV10pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWludyA9IC0xOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NSU5fSCkpCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWluaCA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NSU5fSF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWluaCA9IC0xOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NQVhfVykpCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWF4dyA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NQVhfV10pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWF4dyA9IC0xOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NQVhfSCkpCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWF4aCA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9NQVhfSF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWF4aCA9IC0xOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkVYVEVOVF9XKSkKICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnR3ID0gTWF0aC5tYXgodGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX1ddKSwgbGF5b3V0LmV4dGVudG1pbncpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50dyA9ICBNYXRoLm1heCgwLCBsYXlvdXQuZXh0ZW50bWludyk7CgogICAgICAgICAgICBpZiAobG0uaGFzT3duUHJvcGVydHkoeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX0gpKQogICAgICAgICAgICAgICAgbGF5b3V0LmV4dGVudGggPSBNYXRoLm1heCh0aGlzLl9tbTJweChsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5FWFRFTlRfSF0pLCBsYXlvdXQuZXh0ZW50bWluaCk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnRoID0gIE1hdGgubWF4KDAsIGxheW91dC5leHRlbnRtaW5oKTsKCiAgICAgICAgICAgIGlmIChsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5FWFRFTlRfQUNUVUFMX1cpKQogICAgICAgICAgICAgICAgbGF5b3V0LmV4dGVudGFjdHVhbHcgPSB0aGlzLl9tbTJweChsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5FWFRFTlRfQUNUVUFMX1ddKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbGF5b3V0LmV4dGVudGFjdHVhbHcgPSAgLTE7CgogICAgICAgICAgICBpZiAobG0uaGFzT3duUHJvcGVydHkoeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX0FDVFVBTF9IKSkKICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnRhY3R1YWxoID0gdGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuRVhURU5UX0FDVFVBTF9IXSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnRhY3R1YWxoID0gIC0xOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0Lk1BUkdJTl9UT1ApKQogICAgICAgICAgICAgICAgbGF5b3V0Lm1hcmdpbnRvcCA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0Lk1BUkdJTl9UT1BdKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbGF5b3V0Lm1hcmdpbnRvcCA9IDA7CgogICAgICAgICAgICBpZiAobG0uaGFzT3duUHJvcGVydHkoeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTUFSR0lOX1JJR0hUKSkKICAgICAgICAgICAgICAgIGxheW91dC5tYXJnaW5yaWdodCA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0Lk1BUkdJTl9SSUdIVF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQubWFyZ2lucmlnaHQgPSAwOwoKICAgICAgICAgICAgaWYgKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0Lk1BUkdJTl9CT1RUT00pKQogICAgICAgICAgICAgICAgbGF5b3V0Lm1hcmdpbmJvdHRvbSA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0Lk1BUkdJTl9CT1RUT01dKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbGF5b3V0Lm1hcmdpbmJvdHRvbSA9IDA7CgogICAgICAgICAgICBpZiAobG0uaGFzT3duUHJvcGVydHkoeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTUFSR0lOX0xFRlQpKQogICAgICAgICAgICAgICAgbGF5b3V0Lm1hcmdpbmxlZnQgPSB0aGlzLl9tbTJweChsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5NQVJHSU5fTEVGVF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQubWFyZ2lubGVmdCA9IDA7CgogICAgICAgICAgICBpZiAobG0uaGFzT3duUHJvcGVydHkoeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuQk9SREVSX1RPUCkpCiAgICAgICAgICAgICAgICBsYXlvdXQuYm9yZGVydG9wID0gdGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuQk9SREVSX1RPUF0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuYm9yZGVydG9wID0gMDsKCiAgICAgICAgICAgIGlmIChsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5CT1JERVJfUklHSFQpKQogICAgICAgICAgICAgICAgbGF5b3V0LmJvcmRlcnJpZ2h0ID0gdGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuQk9SREVSX1JJR0hUXSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGxheW91dC5ib3JkZXJyaWdodCA9IDA7CgogICAgICAgICAgICBpZiAobG0uaGFzT3duUHJvcGVydHkoeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuQk9SREVSX0JPVFRPTSkpCiAgICAgICAgICAgICAgICBsYXlvdXQuYm9yZGVyYm90dG9tID0gdGhpcy5fbW0ycHgobG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuQk9SREVSX0JPVFRPTV0pOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBsYXlvdXQuYm9yZGVyYm90dG9tID0gMDsKCiAgICAgICAgICAgIGlmIChsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5CT1JERVJfTEVGVCkpCiAgICAgICAgICAgICAgICBsYXlvdXQuYm9yZGVybGVmdCA9IHRoaXMuX21tMnB4KGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0LkJPUkRFUl9MRUZUXSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGxheW91dC5ib3JkZXJsZWZ0ID0gMDsKCiAgICAgICAgICAgIGlmIChsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5DT0xfU1BBTikpCiAgICAgICAgICAgICAgICBsYXlvdXQuY29sc3BhbiA9ICtsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5DT0xfU1BBTl07CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGxheW91dC5jb2xzcGFuID0gMTsKCiAgICAgICAgICAgIGlmIChsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5ST1dfU1BBTikpCiAgICAgICAgICAgICAgICBsYXlvdXQucm93c3BhbiA9ICtsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5ST1dfU1BBTl07CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGxheW91dC5yb3dzcGFuID0gMTsKCiAgICAgICAgICAgIGlmKGxtLmhhc093blByb3BlcnR5KHhmYWxpYi52aWV3LkxheW91dENvbnN0LkNPTFVNTl9XSURUSFMpKXsKICAgICAgICAgICAgICAgIHZhciBjb2xXaWR0aHMgPSBsbVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5DT0xVTU5fV0lEVEhTXS5zcGxpdCgiICIpOwogICAgICAgICAgICAgICAgdmFyIGNhbGNXaWR0aHMgPSBfLm1hcChjb2xXaWR0aHMsCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oY29sV2lkdGgpewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbW0ycHgoY29sV2lkdGgpOwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgdGhpcyk7CiAgICAgICAgICAgICAgICBsYXlvdXQuY29sdW1ud2lkdGhzID0gY2FsY1dpZHRoczsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYodGhpcy5faXNUYWJsZUNlbGwoKSl7CiAgICAgICAgICAgICAgICB2YXIgY29sdW1uV2lkdGggPSAtMTsKICAgICAgICAgICAgICAgIHZhciB0YWJsZUxheW91dE1vZGVsID0gdGhpcy5wYXJlbnRWaWV3LnBhcmVudFZpZXcubGF5b3V0TW9kZWw7CiAgICAgICAgICAgICAgICBpZih0YWJsZUxheW91dE1vZGVsLmNvbHVtbndpZHRocyAmJiB0YWJsZUxheW91dE1vZGVsLmNvbHVtbndpZHRocy5sZW5ndGggPj0gdGhpcy50YWJsZUNlbGxJbmRleCkKICAgICAgICAgICAgICAgICAgICBjb2x1bW5XaWR0aCA9IHRhYmxlTGF5b3V0TW9kZWwuY29sdW1ud2lkdGhzW3RoaXMudGFibGVDZWxsSW5kZXhdOwogICAgICAgICAgICAgICAgaWYoY29sdW1uV2lkdGggPj0gMCl7CiAgICAgICAgICAgICAgICAgICAgbGF5b3V0LmV4dGVudHcgPSBjb2x1bW5XaWR0aDsKICAgICAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50YWN0dWFsdyA9IGNvbHVtbldpZHRoOwogICAgICAgICAgICAgICAgICAgIGxheW91dC5leHRlbnRtaW53ID0gMDsKICAgICAgICAgICAgICAgICAgICBsYXlvdXQuZXh0ZW50bWF4dyA9ICJub25lIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBsYXlvdXQuaW5pdGlhbGggPSBsYXlvdXQuZXh0ZW50aDsKICAgICAgICAgICAgbGF5b3V0LmluaXRpYWx3ID0gbGF5b3V0LmV4dGVudHc7CgogICAgICAgICAgICBpZihsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5DQVBfUExBQ0VNRU5UKSkKICAgICAgICAgICAgICAgIGxheW91dC5jYXB0aW9uUGxhY2VtZW50ID0gbG1beGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuQ0FQX1BMQUNFTUVOVF07CgogICAgICAgICAgICBpZihsbS5oYXNPd25Qcm9wZXJ0eSh4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5QQUdFX05VTUJFUikpCiAgICAgICAgICAgICAgICBsYXlvdXQucGFnZU51bWJlciA9IGxtW3hmYWxpYi52aWV3LkxheW91dENvbnN0LlBBR0VfTlVNQkVSXTsKCiAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwgPSBsYXlvdXQ7CiAgICAgICAgICAgIHRoaXMucmVzaXphYmxlID0gdGhpcy5sYXlvdXRNb2RlbC5leHRlbnRhY3R1YWx3IDwgMCB8fCAgdGhpcy5sYXlvdXRNb2RlbC5leHRlbnRhY3R1YWxoIDwgMDsKICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUV4dGVudCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgZXh0ZW50ID0ge30gOwogICAgICAgICAgICBleHRlbnRbIm1hcmdpbi1sZWZ0Il0gPSB0aGlzLl9tYXJnaW5MZWZ0KCk7CiAgICAgICAgICAgIGV4dGVudFsibWFyZ2luLXJpZ2h0Il0gPSB0aGlzLl9tYXJnaW5SaWdodCgpOwogICAgICAgICAgICBleHRlbnRbIm1hcmdpbi10b3AiXSA9IHRoaXMuX21hcmdpblRvcCgpOwogICAgICAgICAgICBleHRlbnRbIm1hcmdpbi1ib3R0b20iXSA9IHRoaXMuX21hcmdpbkJvdHRvbSgpOwogICAgICAgICAgICBleHRlbnRbInBhZGRpbmctbGVmdCJdID0gdGhpcy5fcGFkTGVmdCgpOwogICAgICAgICAgICBleHRlbnRbInBhZGRpbmctcmlnaHQiXSA9IHRoaXMuX3BhZFJpZ2h0KCk7CiAgICAgICAgICAgIGV4dGVudFsicGFkZGluZy10b3AiXSA9IHRoaXMuX3BhZFRvcCgpOwogICAgICAgICAgICBleHRlbnRbInBhZGRpbmctYm90dG9tIl0gPSB0aGlzLl9wYWRCb3R0b20oKTsKICAgICAgICAgICAgZXh0ZW50WyJib3JkZXItbGVmdC13aWR0aCJdID0gdGhpcy5fc3ViUGl4ZWxWYWx1ZSh0aGlzLmxheW91dE1vZGVsLmJvcmRlcmxlZnQpOwogICAgICAgICAgICBleHRlbnRbImJvcmRlci1yaWdodC13aWR0aCJdID0gdGhpcy5fc3ViUGl4ZWxWYWx1ZSh0aGlzLmxheW91dE1vZGVsLmJvcmRlcnJpZ2h0KTsKICAgICAgICAgICAgZXh0ZW50WyJib3JkZXItdG9wLXdpZHRoIl0gPSB0aGlzLl9zdWJQaXhlbFZhbHVlKHRoaXMubGF5b3V0TW9kZWwuYm9yZGVydG9wKTsKICAgICAgICAgICAgZXh0ZW50WyJib3JkZXItYm90dG9tLXdpZHRoIl0gPSB0aGlzLl9zdWJQaXhlbFZhbHVlKHRoaXMubGF5b3V0TW9kZWwuYm9yZGVyYm90dG9tKTsKICAgICAgICAgICAgZXh0ZW50WyItd2Via2l0LWJveC1zaXppbmciXSA9ICJib3JkZXItYm94IjsKICAgICAgICAgICAgZXh0ZW50WyItbW96LWJveC1zaXppbmciXSA9ICJib3JkZXItYm94IjsKICAgICAgICAgICAgZXh0ZW50WyJib3gtc2l6aW5nIl0gPSAiYm9yZGVyLWJveCI7CiAgICAgICAgICAgIGV4dGVudFsicG9zaXRpb24iXSA9ICJhYnNvbHV0ZSI7CiAgICAgICAgICAgIHJldHVybiBleHRlbnQ7CiAgICAgICAgfSwKCiAgICAgICAgX3BhZExlZnQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0TW9kZWwubWFyZ2lubGVmdAogICAgICAgICAgICAgICAgICAgIC0gdGhpcy5sYXlvdXRNb2RlbC5ib3JkZXJsZWZ0IC8gMjsKICAgICAgICB9LAoKICAgICAgICBfcGFkUmlnaHQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0TW9kZWwubWFyZ2lucmlnaHQKICAgICAgICAgICAgICAgICAgICAtIHRoaXMubGF5b3V0TW9kZWwuYm9yZGVycmlnaHQgLyAyOwogICAgICAgIH0sCgogICAgICAgIF9wYWRUb3AgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0TW9kZWwubWFyZ2ludG9wIC0gdGhpcy5sYXlvdXRNb2RlbC5ib3JkZXJ0b3AgLyAyOwogICAgICAgIH0sCgogICAgICAgIF9wYWRCb3R0b20gOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0TW9kZWwubWFyZ2luYm90dG9tCiAgICAgICAgICAgICAgICAgICAgLSB0aGlzLmxheW91dE1vZGVsLmJvcmRlcmJvdHRvbSAvIDI7CiAgICAgICAgfSwKCiAgICAgICAgX21hcmdpbkxlZnQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIC10aGlzLmxheW91dE1vZGVsLmJvcmRlcmxlZnQgLyAyOwogICAgICAgIH0sCgogICAgICAgIF9tYXJnaW5SaWdodCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gLXRoaXMubGF5b3V0TW9kZWwuYm9yZGVycmlnaHQgLyAyOwogICAgICAgIH0sCgogICAgICAgIF9tYXJnaW5Ub3AgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIC10aGlzLmxheW91dE1vZGVsLmJvcmRlcnRvcCAvIDI7CiAgICAgICAgfSwKCiAgICAgICAgX21hcmdpbkJvdHRvbSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICByZXR1cm4gLXRoaXMubGF5b3V0TW9kZWwuYm9yZGVyYm90dG9tIC8gMjsKICAgICAgICB9LAoKICAgICAgICBfaXNUYWJsZUNlbGwgOiBmdW5jdGlvbigpeyAvL1RvbyBsb25nIGNoZWNrPz8/IFBsZWFzZSBzaG9ydGVuIGl0LgogICAgICAgICAgICBpZih0aGlzLnBhcmVudFZpZXcgJiYgdGhpcy5wYXJlbnRWaWV3LmxheW91dE1vZGVsICYmCiAgICAgICAgICAgICAgICAodGhpcy5wYXJlbnRWaWV3LmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUk9XIHx8IHRoaXMucGFyZW50Vmlldy5sYXlvdXRNb2RlbC5sYXlvdXQgPT0geGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1JJR0hUTEVGVFJPVykgJiYKICAgICAgICAgICAgICAgIHRoaXMucGFyZW50Vmlldy5wYXJlbnRWaWV3ICYmIHRoaXMucGFyZW50Vmlldy5wYXJlbnRWaWV3LmxheW91dE1vZGVsICYmCiAgICAgICAgICAgICAgICB0aGlzLnBhcmVudFZpZXcucGFyZW50Vmlldy5sYXlvdXRNb2RlbC5sYXlvdXQgPT0geGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1RBQkxFKXsKICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfaXNUYWJsZUhlYWRlckNlbGwgOiBmdW5jdGlvbigpeyAvL1RvbyBsb25nIGNoZWNrPz8/IFBsZWFzZSBzaG9ydGVuIGl0LgogICAgICAgICAgICBpZih0aGlzLnBhcmVudFZpZXcgJiYgdGhpcy5wYXJlbnRWaWV3LmxheW91dE1vZGVsICYmCiAgICAgICAgICAgICAgICAodGhpcy5wYXJlbnRWaWV3LmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUk9XIHx8IHRoaXMucGFyZW50Vmlldy5sYXlvdXRNb2RlbC5sYXlvdXQgPT0geGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX1JJR0hUTEVGVFJPVykgJiYKICAgICAgICAgICAgICAgIHRoaXMucGFyZW50Vmlldy5tb2RlbC5nZXRFbGVtZW50KCJhc3Npc3QiLCAwLCB0cnVlKSAmJiB0aGlzLnBhcmVudFZpZXcubW9kZWwuYXNzaXN0LnJvbGUgPT0gIlRIIil7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCgogICAgICAgIC8vRm9yIGEgZ2l2ZW4gY2VsbCBpZGVudGlmeSBpZiB0aGUgY2VsbCBpcyBwYXJ0IG9mIGhlYWRlciByb3cgKFRIRUFEKQogICAgICAgIF9pc1BhcnRPZkhlYWRlclJvdyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMucGFyZW50VmlldyAmJiB0aGlzLnBhcmVudFZpZXcubGF5b3V0TW9kZWwgJiYKICAgICAgICAgICAgICAgICh0aGlzLnBhcmVudFZpZXcubGF5b3V0TW9kZWwubGF5b3V0ID09IHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9ST1cgfHwgdGhpcy5wYXJlbnRWaWV3LmxheW91dE1vZGVsLmxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUklHSFRMRUZUUk9XKSAmJgogICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRWaWV3LmVsLnBhcmVudE5vZGUubm9kZU5hbWUgPT0gIlRIRUFEIil7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgJGNvbXB1dGVXSCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIC8vcHJpdmF0ZSBtZXRob2QgYnV0IHN0aWxsIG92ZXJyaWRkZW4gaW4gU3ViZm9ybVNldFZpZXcKICAgICAgICAgICAgdmFyIGV4dGVudCA9IHt9OwogICAgICAgICAgICAvL0lmIHRoZSBmaWVsZCBpcyBub3QgaW5pdGlhbGl6ZWQoaW52aXNpYmxlIG9yIGhpZGRlbiksIHRoZW4gdGhlcmUgaXMgbm8gbmVlZCB0byBzZXQgdy9oIGZvciBlbC4gVGhpcyB3b3VsZCBhdXRvbWF0aWNhbGx5IGJlIGRvbmUgZHVyaW5nIGluaXRpYWxpemF0aW9uIHZpYSBzeW5jCiAgICAgICAgICAgIGV4dGVudFsid2lkdGgiXSA9IHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50dyArIHRoaXMubGF5b3V0TW9kZWwuYm9yZGVybGVmdC8yICsgdGhpcy5sYXlvdXRNb2RlbC5ib3JkZXJyaWdodC8yOwogICAgICAgICAgICBleHRlbnRbImhlaWdodCJdID0gdGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoICsgdGhpcy5sYXlvdXRNb2RlbC5ib3JkZXJ0b3AvMiArIHRoaXMubGF5b3V0TW9kZWwuYm9yZGVyYm90dG9tLzIgOwogICAgICAgICAgICByZXR1cm4gZXh0ZW50OwogICAgICAgIH0sCgogICAgICAgIF9pc1BsYWNlSG9sZGVyRWwgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy4kZGF0YSh0aGlzLmVsLCAieGZhSGlkZGVuUEgiKTsKICAgICAgICB9LAoKICAgICAgICAvL2xheW91dCByZWxhdGVkIGZ1bmN0aW9ucwogICAgICAgIGludmFsaWRhdGVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdGhpcy5faW52YWxpZFNpemVGbGFnID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5fbGF5b3V0TWFuYWdlci5pbnZhbGlkYXRlU2l6ZSh0aGlzKTsKICAgICAgICAgICAgdGhpcy5pbnZhbGlkYXRlRGlzcGxheSgpOwogICAgICAgIH0sCgogICAgICAgIGludmFsaWRhdGVEaXNwbGF5IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdGhpcy5faW52YWxpZERpc3BsYXlGbGFnID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5fbGF5b3V0TWFuYWdlci5pbnZhbGlkYXRlRGlzcGxheSh0aGlzKTsKICAgICAgICB9LAoKICAgICAgICBfdmFsaWRhdGVTaXplIDogZnVuY3Rpb24ocmVjdXJzaXZlKXsKICAgICAgICAgICAgaWYodGhpcy5faW52YWxpZFNpemVGbGFnKXsKICAgICAgICAgICAgICAgIGlmKHRoaXMuX2luaXRpYWxpemVkKXsKICAgICAgICAgICAgICAgICAgICB2YXIgc2l6ZUNoYW5nZWQgPSB0aGlzLm1lYXN1cmVTaXplKCk7CiAgICAgICAgICAgICAgICAgICAgaWYoc2l6ZUNoYW5nZWQpCiAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRWaWV3LmludmFsaWRhdGVTaXplKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLl9pbnZhbGlkU2l6ZUZsYWcgPSBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF92YWxpZGF0ZURpc3BsYXkgOiBmdW5jdGlvbihyZWN1cnNpdmUpewogICAgICAgICAgICBpZih0aGlzLl9pbnZhbGlkRGlzcGxheUZsYWcpewogICAgICAgICAgICAgICAgaWYodGhpcy5faW5pdGlhbGl6ZWQpewogICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlRGlzcGxheSgpOwogICAgICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcigibGF5b3V0Q29tcGxldGUiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX2ludmFsaWREaXNwbGF5RmxhZyA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbWVhc3VyZVNpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgY2hhbmdlZCA9IGZhbHNlOwogICAgICAgICAgICBpZighdGhpcy5yZXNpemFibGUpewogICAgICAgICAgICAgICAgaWYodGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoICE9IHRoaXMubGF5b3V0TW9kZWwuaW5pdGlhbGgpewogICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50aCA9IHRoaXMubGF5b3V0TW9kZWwuaW5pdGlhbGg7CiAgICAgICAgICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZih0aGlzLmxheW91dE1vZGVsLmV4dGVudHcgIT0gdGhpcy5sYXlvdXRNb2RlbC5pbml0aWFsdyl7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXlvdXRNb2RlbC5leHRlbnR3ID0gdGhpcy5sYXlvdXRNb2RlbC5pbml0aWFsdzsKICAgICAgICAgICAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY2hhbmdlZDsKICAgICAgICB9LAoKICAgICAgICB1cGRhdGVEaXNwbGF5IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIGV4dGVudCA9IHRoaXMuJGNvbXB1dGVXSCgpOwogICAgICAgICAgICB0aGlzLiRjc3ModGhpcy5lbCwgZXh0ZW50KTsKICAgICAgICAgICAgJCh0aGlzLmVsKS5yZW1vdmVDbGFzcygiaGlkZUVsZW1lbnQiKTsKICAgICAgICB9LAoKICAgICAgICBfc3ViUGl4ZWxWYWx1ZSA6IGZ1bmN0aW9uKHZhbHVlKXsKICAgICAgICAgICAgaWYodmFsdWUgPiAwLjAxKQogICAgICAgICAgICAgICAgcmV0dXJuIE1hdGgubWF4KHZhbHVlLCAxLjApOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBSZXR1cm4gdGhlIHBhZ2UgbnVtYmVyIGNvbnRhaW5pbmcgdGhpcyB2aWV3LgogICAgICAgICAqIE5vdGU6IHBhZ2UgbnVtYmVyIHN0YXJ0cyB3aXRoIDEgaW5zdGVhZCBvZiAwCiAgICAgICAgICovCiAgICAgICAgX3BhZ2VOdW1iZXIgOiBmdW5jdGlvbigpewogICAgICAgICAgICAvL1BhZ2UgbnVtYmVyIGlzIHBhc3NlZCBhcyBhcmd1bWVudCB0byBjcmVhdGVWaWV3IGFuZCBpcyBhdmFpbGFibGUgaW4gb3B0aW9ucwogICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPckVsc2UodGhpcywgIm9wdGlvbnMucGFnZU51bWJlciIsIC0xKTsKICAgICAgICB9LAoKICAgICAgICAvKgogICAgICAgICAqIEBmdW5jdGlvbgogICAgICAgICAqIEZvY3VzZXMgdGhlIHdpZGdldCBvZiB0aGUgcHJvdmlkZWQgdmlldy4KICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gdmlldyA6IHZpZXcgd2hvc2Ugd2lkZ2V0IG5lZWRzIHRvIGJlIGZvY3Vzc2VkLgogICAgICAgICAqLwogICAgICAgIF9mb2N1c1dpZGdldCA6IGZ1bmN0aW9uICh2aWV3KSB7CiAgICAgICAgICAgIHZhciBqcVdpZGdldCA9IHZpZXcuanFXaWRnZXQ7CiAgICAgICAgICAgIGlmICghanFXaWRnZXQpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZih4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuX2lzSXBhZCgpKSB7CiAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0ID0ganFXaWRnZXQuJHVzZXJDb250cm9sLm9mZnNldCgpLAogICAgICAgICAgICAgICAgICAgIHRvcCA9IG9mZnNldC50b3AsCiAgICAgICAgICAgICAgICAgICAgbGVmdCA9IG9mZnNldC5sZWZ0OwogICAgICAgICAgICAgICAgd2luZG93LnNjcm9sbFRvKGxlZnQsdG9wKSA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAganFXaWRnZXQuZm9jdXMoKTsKICAgICAgICB9CgogICAgfSk7CgogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJhc2VWaWV3LnByb3RvdHlwZSwgInJlc2l6YWJsZSIsIHsKICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVzaXphYmxlOwogICAgICAgIH0sCgogICAgICAgIHNldCA6IGZ1bmN0aW9uKHNWYWx1ZSl7CiAgICAgICAgICAgIHRoaXMuX3Jlc2l6YWJsZSA9IHNWYWx1ZTsKICAgICAgICB9CiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy5YZmFEcmF3VmlldyA9IHhmYWxpYi52aWV3LkJhc2VWaWV3LmV4dGVuZCh7CiAgICAgICAgJGRyYXdDaGlsZCA6IG51bGwsCgogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5CYXNlVmlldy5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICB0aGlzLl9pbml0TGF5b3V0KCk7CiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUFjY2Vzc2liaWxpdHlJbmZvKCk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlTW9kZWxDaGFuZ2VkIDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgc3dpdGNoKGV2ZW50Ll9wcm9wZXJ0eSkgewogICAgICAgICAgICAgICAgY2FzZSAicmF3VmFsdWUiIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihldmVudC5qc29uTW9kZWwubmV3VGV4dCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVWaWV3KGV2ZW50Lmpzb25Nb2RlbC5uZXdUZXh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5oYW5kbGVNb2RlbENoYW5nZWQuYXBwbHkodGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGhhbmRsZURvbUNoYW5nZWQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAgc3dpdGNoKGV2ZW50Ll9wcm9wZXJ0eSkgewogICAgICAgICAgICAgICAgIGNhc2UgInZhbHVlLnRleHQiIDoKICAgICAgICAgICAgICAgICBjYXNlICJ2YWx1ZS5leERhdGEiIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZXZlbnQuanNvbk1vZGVsLm5ld1RleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVZpZXcoZXZlbnQuanNvbk1vZGVsLm5ld1RleHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgIGNhc2UgImgiIDovLy0td2Ugc3VwcG9ydCBjb21wdXRhdGlvbiBvbmx5IG9uIGxpbmUgZm9yIG5vdy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5nZXRPckVsc2UodGhpcy5tb2RlbCwgInZhbHVlLm9uZU9mQ2hpbGQuY2xhc3NOYW1lIiwgIiIpID09PSAibGluZSIpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29tcHV0ZUxpbmVIZWlnaHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5CYXNlVmlldy5wcm90b3R5cGUuaGFuZGxlRG9tQ2hhbmdlZC5hcHBseSh0aGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlRm9udEZpbGxDb2xvclZhbHVlIDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgaWYodGhpcy5tb2RlbCAmJiB0aGlzLm1vZGVsLnZhbHVlKSB7CiAgICAgICAgICAgICAgICB2YXIgY29udGVudCA9IHRoaXMubW9kZWwudmFsdWUub25lT2ZDaGlsZDsKICAgICAgICAgICAgICAgIHZhciBodG1sVGV4dCA9IGNvbnRlbnQuanNvbk1vZGVsLl92YWx1ZTsKICAgICAgICAgICAgICAgIGlmKGNvbnRlbnQuZ2V0QXR0cmlidXRlKCdjb250ZW50VHlwZScpID09ICd0ZXh0L2h0bWwnKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyICRpbnRlcm5hbEhUTUwgPSAkKCc8c3Bhbj4nK2h0bWxUZXh0Kyc8L3NwYW4+Jyk7CiAgICAgICAgICAgICAgICAgICAgLy9jaGFuZ2UgdGhlIHRvcCBsZXZlbCBlbGVtZW50IHRvIHNwYW4gdG8gd3JhcCB1cCBhbGwgdGhlIDxwPiwgYmVjYXVzZSBpdCB3aWxsIGNhdXNlIHVubmVjZXNzYXJ5IHBhcmFncmFwaCBicmVhawogICAgICAgICAgICAgICAgICAgIC8vYWRkICdkaXNwbGF5OmlubGluZScgc3R5bGUKICAgICAgICAgICAgICAgICAgICAvL25vIG51bGwgY2hlY2sgYmVjYXVzZSBqUXVlcnkgaXMgY29vbCEKICAgICAgICAgICAgICAgICAgICAvL1RvRG86IGNoYW5nZSBhbGwgeW91ciBwYXJhZ3JhcGhzIGludG8gPHNwYW4+IGFuZCBhZGQgYSA8YnI+IGVsZW1lbnQgYmV0d2VlbiB0aGVtCiAgICAgICAgICAgICAgICAgICAgLy90aGlzIHdpbGwgd29yayBmb3IgZmV3IGNhc2VzIHdoZXJlIHRoZXJlIGlzIG9uZSBzaW5nbGUgcGFyYWdyYXBoIGluIHRoZSB0ZXh0IG9yIHBsYWluIHRleHQgY2FzZXMuCiAgICAgICAgICAgICAgICAgICAgJGludGVybmFsSFRNTC5maW5kKCJwIikuZXEoMCkuY3NzKCdkaXNwbGF5JywnaW5saW5lJyk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlVmlldygkaW50ZXJuYWxIVE1MWzBdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVWaWV3KGh0bWxUZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvL25vdyBjaGVjayB0aGUgcmF3VmFsdWUgYW5kIHVwZGF0ZSB2aWV3IGJhc2VkIG9uIHRoYXQgcmF3VmFsdWUKCiAgICAgICAgfSwKCiAgICAgICAgX3VwZGF0ZVZpZXcgOiBmdW5jdGlvbih0ZXh0KSB7CiAgICAgICAgICAgICAgaWYgKHRoaXMuX2luaXRpYWxpemVkICYmIHRoaXMubW9kZWwpIHsKICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCd2YWx1ZScsMCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgIGlmKHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICB2YXIgIGNoaWxkID0gdmFsdWUub25lT2ZDaGlsZDsKICAgICAgICAgICAgICAgICAgICAgIGlmIChbInRleHQiLCJleERhdGEiXS5pbmRleE9mKGNoaWxkLmNsYXNzTmFtZSkgIT09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNzc09iaiA9IHRoaXMuX2dldFRleHRTdHlsZSh0aGlzLm1vZGVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3NzT2JqKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy5lbCwgY3NzT2JqLmZvbnRTdHlsZXMpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmVuY29kZVNjcmlwdGFibGVUYWdzKHRoaXMuX2NvbnZlcnRYRkFSaWNoVG9IdG1sKHRleHQpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5jaGlsZHJlbigpLnJlcGxhY2VXaXRoKHRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmVsLmNoaWxkcmVuWzBdICYmIGNzc09iaikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy5lbC5jaGlsZHJlblswXSwgY3NzT2JqLnBhcmFTdHlsZXMpOwogICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkLmNsYXNzTmFtZSA9PT0gJ2ltYWdlJyAmJiB0ZXh0KSB7Ly9pZiBkcmF3IGlzIG9mIHR5cGUgaW1hZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5jaGlsZHJlbigpWzBdLnNldEF0dHJpYnV0ZSgnc3JjJywgJ2RhdGE6O2Jhc2U2NCwnICsgdGV4dCk7CiAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5yZXNpemFibGUpewogICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52YWxpZGF0ZVNpemUoKTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgbWVhc3VyZVNpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgcmVzaXplZCA9IGZhbHNlLAogICAgICAgICAgICAgICAgdGV4dCA9IG51bGwsCiAgICAgICAgICAgICAgICBjb250ZW50ID0gdGhpcy5nZXRPckVsc2UodGhpcywgIm1vZGVsLnZhbHVlLm9uZU9mQ2hpbGQiLCBudWxsKTsKCiAgICAgICAgICAgIC8vIGNoZWNrIHRvIHJlc2l6ZSBkcmF3IG9ubHkgaW4gY2FzZSBvZiBmbG9hdGluZyBmaWVsZCBhbmQgaXMgcmVzaXphYmxlCiAgICAgICAgICAgIGlmKHRoaXMucmVzaXphYmxlICYmIHRoaXMuX2lzRmxvYXRpbmdGaWVsZFByZXNlbnQoY29udGVudCkpewogICAgICAgICAgICAgICAgLy8gaWYgY29udGVudCBpcyByaWNoIHRleHQsIHRoZW4gdXNlIGpxdWVyeSBodG1sKCkgdG8gc3VwcG9ydCByaWNoIHRleHQgZWxlbWVudCBlbHNlIHRleHQoKQogICAgICAgICAgICAgICAgaWYoY29udGVudCAmJiBjb250ZW50LmdldEF0dHJpYnV0ZSgnY29udGVudFR5cGUnKSA9PSAndGV4dC9odG1sJykgewogICAgICAgICAgICAgICAgICAgIHRleHQgPSB0aGlzLiRlbC5odG1sKCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRleHQgPSB0aGlzLiRlbC50ZXh0KCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXNpemVkID0geGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fdXBkYXRlV2lkZ2V0TW9kZWwuY2FsbCh0aGlzLCB0ZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzaXplZDsKICAgICAgICB9LAoKICAgICAgICBfZ2V0TWVhc3VyZW1lbnRPcHRpb25zIDogZnVuY3Rpb24oKXsKICAgICAgICAgICB2YXIgbWVhc3VyZU9wdGlvbnMgPSB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9nZXRNZWFzdXJlbWVudE9wdGlvbnMuYXBwbHkodGhpcywgYXJndW1lbnRzKSwKICAgICAgICAgICAgICAgY29udGVudCA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMsICJtb2RlbC52YWx1ZS5vbmVPZkNoaWxkIiwgbnVsbCk7CiAgICAgICAgICAgcmV0dXJuICQuZXh0ZW5kKHt9LCBtZWFzdXJlT3B0aW9ucywgewogICAgICAgICAgICAgICBjb250ZW50VHlwZSA6IGNvbnRlbnQgPyBjb250ZW50LmdldEF0dHJpYnV0ZSgnY29udGVudFR5cGUnKSA6ICIiLAogICAgICAgICAgICAgICBpc0RyYXcgOiB0cnVlLAogICAgICAgICAgICAgICByZWZFbCA6IHRoaXMuZWwKICAgICAgICAgICB9KTsKCiAgICAgICAgfSwKICAgICAgICAvKioKICAgICAgICAgKiBAZnVuY3Rpb24KICAgICAgICAgKiBVdGlsaXR5IGZ1bmN0aW9uIHRvIGNoZWNrcyB3aGV0aGVyIHRoZSBkcmF3IGlzIGhhdmluZyBmbG9hdGluZyBmaWVsZCBvciBub3QKICAgICAgICAgKiBAcGFyYW0ge29iamVjdH0gY29udGVudCA6IGNvbnRhaW5zIGpzb25WYWx1ZSAsIF9vcmlnVG1wbHRWYWwgZXRjLgogICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSA6IHRydWUgaWYgZHJhdyBjb250YWlucyBmbG9hdGluZyBmaWVsZCBlbHNlIGZhbHNlCiAgICAgICAgICovCiAgICAgICAgX2lzRmxvYXRpbmdGaWVsZFByZXNlbnQgOiBmdW5jdGlvbiAoY29udGVudCkgewogICAgICAgICAgICBpZiAoY29udGVudCAmJiBjb250ZW50Ll9vcmlnVG1wbHRWYWwpIHsKICAgICAgICAgICAgICAgIHZhciAkaW50ZXJuYWxIVE1MID0gJCgnPHNwYW4+JyArIGNvbnRlbnQuX29yaWdUbXBsdFZhbCArICc8L3NwYW4+Jyk7CiAgICAgICAgICAgICAgICByZXR1cm4gJGludGVybmFsSFRNTC5maW5kKCdbeGZhXFw6ZW1iZWRdJykubGVuZ3RoID4gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgX3N5bmNGb3JtTm9kZVRvSHRtbCA6IGZ1bmN0aW9uKHZhbCkgewogICAgICAgICAgICAvL2luIG9yZGVyIHRvIHNhdmUgc29tZSBieXRlcwogICAgICAgICAgICAvLyB3ZSBkb24ndCBzZW5kIHhtbG5zIGF0dHJpYnV0ZXMgZnJvbSBzZXJ2ZXIgc28gc2V0IGl0IGhlcmUKICAgICAgICAgICAgdmFyIGNoaWxkcmVuID0gdGhpcy4kZWwuY2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIHZhbHVlID0gbnVsbDsKICAgICAgICAgICAgaWYoY2hpbGRyZW4ubGVuZ3RoKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoY2hpbGRyZW5bMF0udGFnTmFtZSA9PT0gJ3N2ZycpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluIGNhc2Ugb2Yga2VybmluZywgd2UgYWRkIGxldHRlclNwYWNpbmcgaW4gWERQLiBWaWV3IGdlbmVyYXRlZCBjb250YWlucyBzcGFjZWQgbGV0dGVycyB3aGljaCBhcmUgcmVhZCBzZXBhcmF0ZWx5CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ5IHRoZSBzY3JlZW4gcmVhZGVycywgdG8gYXZvaWQgdGhpcyB3ZSBhcmUgY2hlY2tpbmcgaWYgaXQgY29udGFpbnMgbGV0dGVyU3BhY2luZywgaWYgeWVzIHRoZW4gYWRkIGFyaWEtbGFiZWwKICAgICAgICAgICAgICAgICAgICAgICAgLy8gb24gdG9wIGxldmVsIGFuZCBoaWRlIG5lc3RlZCBlbGVtZW50cyBmcm9tIHNjcmVlbiByZWFkZXIuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMubW9kZWwgJiYgdGhpcy5tb2RlbC5qc29uTW9kZWwgJiYgdGhpcy5tb2RlbC5qc29uTW9kZWwuY2hpbGRyZW4pewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm1vZGVsLmpzb25Nb2RlbC5jaGlsZHJlbi5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMubW9kZWwuanNvbk1vZGVsLmNoaWxkcmVuW2ldLl9jbGFzcz09PSJmb250Iil7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMubW9kZWwuanNvbk1vZGVsLmNoaWxkcmVuW2ldLmxldHRlclNwYWNpbmcpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbC5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWwnLCB0aGlzLm1vZGVsLnJhd1ZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuWzBdLnNldEF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nLCAndHJ1ZScpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuWzBdLnNldEF0dHJpYnV0ZSgncm9sZScsJ3ByZXNlbnRhdGlvbicpOyAvLyBDUS00Mjc0NzMyIDogVG8gcHJldmVudCBzdmcgYmVpbmcgcmVhZCBvdXQgYXMgZ3JhcGhpYwogICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuWzBdLnNldEF0dHJpYnV0ZSgneG1sbnMnLCAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnKTsKICAgICAgICAgICAgICAgICAgICBjaGlsZHJlblswXS5zZXRBdHRyaWJ1dGUoJ3htbG5zOnhsaW5rJywgJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnKTsKICAgICAgICAgICAgICAgICAgICBjaGlsZHJlblswXS5zZXRBdHRyaWJ1dGUoJ2ZvY3VzYWJsZScsICdmYWxzZScpOyAvL0xDLTcxMDUgTEMtNTQ0NCBzdmcgdGFiSW5kZXggZG9lc24ndCB3b3JrIHNvIGFkZGluZyBmb2N1c2FibGUgYXMgZmFsc2UKICAgICAgICAgICAgICAgICAgICAvL1JlcXVpcmVkIHNvIHRoYXQgZHJhdyBkbyBub3Qgc3BpbGwgb3V0IG9mIHRoZWlyIHBhcmVudCBkaXYuCiAgICAgICAgICAgICAgICAgICAgdmFyIGNzc0V4dGVudCA9IHt9OwogICAgICAgICAgICAgICAgICAgIGNzc0V4dGVudFsid2lkdGgiXSA9ICIxMDAlIjsKICAgICAgICAgICAgICAgICAgICBjc3NFeHRlbnRbImhlaWdodCJdPSAiMTAwJSI7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKGNoaWxkcmVuWzBdLCBjc3NFeHRlbnQpOwogICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuZ2V0T3JFbHNlKHRoaXMubW9kZWwsICJ2YWx1ZS5vbmVPZkNoaWxkLmNsYXNzTmFtZSIsICIiKSA9PT0gJ2xpbmUnKXsKICAgICAgICAgICAgICAgICAgICAgICB2YXIgcHhIZWlnaHQgPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5fY29udmVydFRvUHgodGhpcy5tb2RlbC5oKTsKICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3ZnSGVpZ2h0ID0geGZhbGliLnZpZXcudXRpbC5TdHlsZXMuX2NvbnZlcnRUb1B4KGNoaWxkcmVuWzBdLmdldEF0dHJpYnV0ZSgnaGVpZ2h0JykpOwogICAgICAgICAgICAgICAgICAgICAgIGlmKHN2Z0hlaWdodCAmJiBweEhlaWdodCAhPSBzdmdIZWlnaHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29tcHV0ZUxpbmVIZWlnaHQoKTsKICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZih0aGlzLm1vZGVsKXsKICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCd2YWx1ZScsMCwgdHJ1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYodmFsdWUpIHsKICAgICAgICAgICAgICAgIHZhciAgY2hpbGQgPSB2YWx1ZS5vbmVPZkNoaWxkOwogICAgICAgICAgICAgICAgaWYgKGNoaWxkLl9tb2RlbENoYW5nZWQgPT09IHRydWUpIHsgLy9ubyBuZWVkIHRvIGNoZWNrIGl0IGhlcmUgYXMgdXBkYXRldmlldyBjaGVja3MgaXQgYW55d2F5CiAgICAgICAgICAgICAgICAgICAgdmFyIGpzb25WYWwgPSBjaGlsZC5qc29uVmFsdWUgfHwgY2hpbGQudmFsdWU7IC8vIGNhbGwgdG8gY2hpbGQudmFsdWUgd2lsbCB1c2UgdHlwZWRWYWwgYW5kIHN0cmlwIG9mZiBodG1sIHRhZ3MgOiBMQy01NDI3CiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLmNsYXNzTmFtZSA9PT0gImltYWdlIiAmJiBqc29uVmFsID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9mb3IgaW1hZ2VzLCBpZiB0aGUgdmFsdWUgaXMgdW5kZWZpbmVkIG9yIG51bGwgcmV0dXJuIHRoZSBocmVmIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgICAgICBqc29uVmFsID0gY2hpbGQuaHJlZjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlVmlldyhqc29uVmFsKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vZm9yIGRyYXcgZG8gaXQgZm9yIHRoZSB2ZXJ5IGZpcnN0IHRpbWUgYXMgd2VsbAogICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5jbGFzc05hbWUgPT09ICdpbWFnZScpIHsgLy9pZiBkcmF3IGlzIG9mIHR5cGUgaW1hZ2UKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLnZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5jaGlsZHJlbigpWzBdLnNldEF0dHJpYnV0ZSgnc3JjJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZGF0YTo7YmFzZTY0LCcgKyBjaGlsZC52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5jaGlsZHJlbigpWzBdLnNldEF0dHJpYnV0ZSgnc3JjJywgY2hpbGQuaHJlZik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5fc3luY0Zvcm1Ob2RlVG9IdG1sLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfSwKCiAgICAgICAgX2NvbXB1dGVMaW5lSGVpZ2h0IDogZnVuY3Rpb24oKSB7ICAgLy9sYy01NDYzCiAgICAgICAgICAgLy8tLSBjb21wdXRpbmcgbGluZSBoZWlnaHQKICAgICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMuJGVsLmNoaWxkcmVuKCk7CiAgICAgICAgICB2YXIgbGluZU5vZGUgPXt9OwogICAgICAgICAgaWYoY2hpbGRyZW5bMF0pIHsKICAgICAgICAgICAgIGxpbmVOb2RlID0gY2hpbGRyZW5bMF0uY2hpbGROb2Rlc1swXTsKICAgICAgICAgIH0KICAgICAgICAgIHZhciBweEhlaWdodCA9IHhmYWxpYi52aWV3LnV0aWwuU3R5bGVzLl9jb252ZXJ0VG9QeCh0aGlzLm1vZGVsLmgpOwogICAgICAgICAgaWYobGluZU5vZGUpIHsKICAgICAgICAgICAgIC8vLS10cmFuc2Zvcm1pbmcgdGhlIGNvZGUgZnJvbSBvdGhlciB1bml0cyB0byBwaXhlbCBhbmQgY2hhbmdpbmcgaXRzIHR5cGUgdG8gTnVtZXIgZm9yIGZ1cnRoZXIgY29tcHV0YXRpb24KICAgICAgICAgICAgIHZhciB4MSA9IHhmYWxpYi52aWV3LnV0aWwuU3R5bGVzLl9jb252ZXJ0VG9QeChsaW5lTm9kZS5nZXRBdHRyaWJ1dGUoJ3gxJykpOwogICAgICAgICAgICAgdmFyIHgyID0geGZhbGliLnZpZXcudXRpbC5TdHlsZXMuX2NvbnZlcnRUb1B4KGxpbmVOb2RlLmdldEF0dHJpYnV0ZSgneDInKSk7CiAgICAgICAgICAgICB2YXIgeTEgPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5fY29udmVydFRvUHgobGluZU5vZGUuZ2V0QXR0cmlidXRlKCd5MScpKTsKICAgICAgICAgICAgIHZhciB5MiA9IHhmYWxpYi52aWV3LnV0aWwuU3R5bGVzLl9jb252ZXJ0VG9QeChsaW5lTm9kZS5nZXRBdHRyaWJ1dGUoJ3kyJykpOwoKICAgICAgICAgICAgIHZhciBzbG9wZSA9ICh5Mi15MSkvKHgyLXgxKTsKICAgICAgICAgICAgIGlmKCFpc0Zpbml0ZShzbG9wZSkpIHsKICAgICAgICAgICAgICAgIHkyID0geTEgKyAgcHhIZWlnaHQ7CiAgICAgICAgICAgICAgICBsaW5lTm9kZS5zZXRBdHRyaWJ1dGUoJ3kyJyxTdHJpbmcoeTIgKydweCcpKTsKICAgICAgICAgICAgICAgIGNoaWxkcmVuWzBdLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JyxTdHJpbmcocHhIZWlnaHQgKydweCcpKTsKICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50aCA9IHB4SGVpZ2h0IDsKICAgICAgICAgICAgICAgIHZhciBjc3NIZWlnaHQgPSB7fTsKICAgICAgICAgICAgICAgIGNzc0hlaWdodFsnaGVpZ2h0J10gPSBTdHJpbmcocHhIZWlnaHQgKydweCcpOwogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuZWwsIGNzc0hlaWdodCk7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgLyppZihzbG9wZSA9PSAwKSB7CiAgICAgICAgICAgICAgICB4MiA9IHgxICsgIHB4SGVpZ2h0OwogICAgICAgICAgICAgfQogICAgICAgICAgICAgaWYoaXNGaW5pdGUoc2xvcGUpICYmIHNsb3BlICE9IDApIHsKICAgICAgICAgICAgICAgIHgyID0geDEgKyAgcHhIZWlnaHQgKiBNYXRoLnNpbihNYXRoLmF0YW4oc2xvcGUpKSA7CiAgICAgICAgICAgICAgICB5MiA9IHkxIC0gIHB4SGVpZ2h0ICogTWF0aC5jb3MoTWF0aC5hdGFuKHNsb3BlKSkgOwogICAgICAgICAgICAgfSovCiAgICAgICAgICAgIC8vIGxpbmVOb2RlLnNldEF0dHJpYnV0ZSgneDInLFN0cmluZyh4MiArJ3B4JykpOwoKICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaW5pdExheW91dCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5faW5pdExheW91dC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICBpZih0aGlzLl9pbml0aWFsaXplZCl7CiAgICAgICAgICAgICAgICB2YXIgZHJhd1R5cGUgPSB0aGlzLmdldE9yRWxzZSh0aGlzLiRkYXRhKHRoaXMuZWwsIHhmYWxpYi52aWV3LkxheW91dENvbnN0LlhGQV9NT0RFTClbeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTk9ERV9UWVBFXSwgIiIpLnRvTG93ZXJDYXNlKCk7CgogICAgICAgICAgICAgICAgaWYoISQuYnJvd3Nlci5tc2llKXsKICAgICAgICAgICAgICAgICAgICAvL0FsbCBzdXBwb3J0ZWQgYnJvd3NlciBleGNlcHQgSUUgYXJlIG5vdCBhYmxlIHRvIGdyYWNlZnVsbHkgaGFuZGxlIDFweCBzdmcgZHJhd2luZ3MuCiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHJlYXNvbiBmb3IgdGhhdCwgdGhleSBzdGFydCBkcmF3IGF0IGdyaWQgbGluZXMgYW5kIGRyYXcgLjVweCBvbiBib3RoIHNpZGVzIG9mIGdyaWRsaW5lcy4KICAgICAgICAgICAgICAgICAgICAvLyBTb21lIGJyb3dzZXJzIG1peCBoYWxmIHBpeGVsIGJsYWNrIHdpdGggd2hpdGUgdG8gcHJvZHVjZSBncmV5IGJ1dCBvdGhlcnMgbWF5IG5vdC4KICAgICAgICAgICAgICAgICAgICAvLyBUbyBoYW5kbGUgdGhpcyBjb25zaXN0ZW50bHksIHdlIHVwZ3JhZGUgMXB4IGRyYXdpbmdzIHRvIDJweCBmb3Igbm9uIElFIGJyb3dzZXJzLgogICAgICAgICAgICAgICAgICAgIGlmKGRyYXdUeXBlID09ICJsaW5lIil7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJCgnbGluZVtzdHJva2Utd2lkdGg9IjFweCJdJykuYXR0cigic3Ryb2tlLXdpZHRoIiwgIjJweCIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKGRyYXdUeXBlID09ICJyZWN0YW5nbGUiKXsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kKCdwYXRoW3N0cm9rZS13aWR0aD0iMXB4Il0nKS5hdHRyKCJzdHJva2Utd2lkdGgiLCAiMnB4Iik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmKCQuYnJvd3Nlci53ZWJraXQgfHwgJC5icm93c2VyLmNocm9tZSB8fCB4ZmFsaWIudXQuVXRpbGl0aWVzLmNoZWNrTWluTW96aWxsYVZlcnNpb24oMjgpKXsKICAgICAgICAgICAgICAgICAgICAvL2Nocm9tZSBoYW5kbGVzIHRoZSBydGwgdGV4dCBlbGVtZW50IGluIGEgZGlmZmVyZW50IHdheS4KICAgICAgICAgICAgICAgICAgICAvL3RoZXJlIGlzIGEgc2ltaWxhciBmdW5jdGlvbiBpbiBGaWVsZFZpZXcKICAgICAgICAgICAgICAgICAgICB0aGlzLiQoJ3RleHRbZGlyZWN0aW9uPSJydGwiXScpLmF0dHIoJ3RleHQtYW5jaG9yJywgJ2VuZCcpOwogICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgICAgICB0aGlzLiRkcmF3Q2hpbGQgPSAkKHRoaXMuX2ZpbmREcmF3RWxlbWVudCgpKTsKICAgICAgICAgICAgICAgIGlmKGRyYXdUeXBlID09ICJsaW5lIil7CiAgICAgICAgICAgICAgICAgICAgLy9Gb3IgdmVyeSB0aGluIGxpbmVzIGxlc3MgdGhhbiBvbmUgcGl4ZWwsIHRvIGF2b2lkIG1pc3NpbmcgbGluZXMsIHRoZWlyIGNvbnRhaW5pbmcgZGl2IHNob3VsZCBiZSAxcHggbWluaW11bSBpbiBzaXplCiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5sYXlvdXRNb2RlbC5leHRlbnR3ID4gMC4wMSAmJiB0aGlzLmxheW91dE1vZGVsLmV4dGVudHcgPCAxLjApCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50dyAgPSAxLjA7CiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoID4gMC4wMSAmJiB0aGlzLmxheW91dE1vZGVsLmV4dGVudGggPCAxLjApCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50aCA9IDEuMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGRyYXdUeXBlID09ICJyZWN0YW5nbGUiKXsKICAgICAgICAgICAgICAgICAgICAvL1RvIGF2b2lkIG1pc3NpbmcgZWRnZXMgb2YgcmVjdGFuZ2xlLCB0aGVpciBjb250YWluaW5nIGRpdiBzaG91bGQgYmUgKmNlaWwqZWQgdG8gbmV4dCBpbnRlZ2VyLiBKdXN0IGhldXJpc3RpYy9vYnNlcnZhdGlvbgogICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50dyA9IE1hdGguY2VpbCh0aGlzLmxheW91dE1vZGVsLmV4dGVudHcpOwogICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50aCAgPSBNYXRoLmNlaWwodGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX3N5bmNGb3JtTm9kZVRvSHRtbCh0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVBY2Nlc3NpYmlsaXR5SW5mbzogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBzY3JlZW5SZWFkZXJUZXh0ID0gdGhpcy5fZ2V0U2NyZWVuUmVhZGVyVGV4dCgpOwogICAgICAgICAgICAvL2FkZCBhbHQgZm9yIGltZyB0YWdzLi4uCiAgICAgICAgICAgIGlmKHNjcmVlblJlYWRlclRleHQgJiYgdGhpcy4kZHJhd0NoaWxkICYmIHRoaXMuJGRyYXdDaGlsZC5pcygiaW1nIikpewogICAgICAgICAgICAgICAgdGhpcy4kZHJhd0NoaWxkLmF0dHIoImFsdCIsIHNjcmVlblJlYWRlclRleHQpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZihzY3JlZW5SZWFkZXJUZXh0KSB7CiAgICAgICAgICAgICAgICAkKHRoaXMpLmF0dHIoImFyaWEtbGFiZWwiLCBzY3JlZW5SZWFkZXJUZXh0KQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBjaGVjayBmb3IgaGVhZGluZyByb2xlcwogICAgICAgICAgICB2YXIgcm9sZSA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMubW9kZWwuZ2V0RWxlbWVudCgiYXNzaXN0IiksICJyb2xlIiwgIiIpOwogICAgICAgICAgICBpZiAoL15IWzEtNl0kLy50ZXN0KHJvbGUpKSB7CiAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJyb2xlIiwgImhlYWRpbmciKS5hdHRyKCJhcmlhLWxldmVsIiwgcm9sZVsxXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfYXNzaWduVG9vbFRpcDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgdG9vbFRpcFRleHQgPSB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuX2dldFRvb2xUaXBUZXh0KHRoaXMubW9kZWwpOwogICAgICAgICAgICBpZiAodG9vbFRpcFRleHQpIHsKICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInRpdGxlIiwgdG9vbFRpcFRleHQpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldFNjcmVlblJlYWRlclRleHQgOiBmdW5jdGlvbigpewogICAgICAgICAgICBpZiAodGhpcy5tb2RlbCkgewogICAgICAgICAgICAgICAgLy9maW5kIHNwZWFrIHByaW9yaXR5IGZpcnN0IC0tLQogICAgICAgICAgICAgICAgdmFyIGFzc2lzdCA9IHRoaXMubW9kZWwuZ2V0RWxlbWVudCgiYXNzaXN0IiwgMCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB2YXIgc2NyZWVuUmVhZGVyVGV4dDsKCiAgICAgICAgICAgICAgICB2YXIgcHJpb3JpdHkgPSAiY3VzdG9tIjsKICAgICAgICAgICAgICAgIHZhciBzcGVhazsKICAgICAgICAgICAgICAgIHZhciB0b29sVGlwOwoKICAgICAgICAgICAgICAgIGlmKGFzc2lzdCApIHsKICAgICAgICAgICAgICAgICAgICAvLyYmIGFzc2lzdC5zcGVhayAmJiBhc3Npc3Quc3BlYWsucHJpb3JpdHkKICAgICAgICAgICAgICAgICAgICBzcGVhayA9IGFzc2lzdC5nZXRFbGVtZW50KCJzcGVhayIsIDAsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIHRvb2xUaXAgPSBhc3Npc3QuZ2V0RWxlbWVudCgidG9vbFRpcCIsIDAsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIGlmKHNwZWFrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yaXR5ID0gc3BlYWsuZ2V0QXR0cmlidXRlKCdwcmlvcml0eScpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZihwcmlvcml0eSA9PSAiY3VzdG9tIikgewogICAgICAgICAgICAgICAgICAgIGlmKHNwZWFrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHQgPSBzcGVhay52YWx1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih0b29sVGlwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHQgPSB0b29sVGlwLnZhbHVlOyAvL0xDLTY4MDU6IHRvb2x0aXAgaXMgc2hvd24gYXMgW09iamVjdCBPYmplY3RdIGZvciB0ZXh0IG9iamVjdHMKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih0aGlzLm1vZGVsLmpzb25Nb2RlbC5leHRyYXMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2NyZWVuUmVhZGVyVGV4dCA9IHRoaXMubW9kZWwuanNvbk1vZGVsLmV4dHJhcy5jYXB0aW9uOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2NyZWVuUmVhZGVyVGV4dCA9IHRoaXMubW9kZWwuanNvbk1vZGVsLm5hbWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZihwcmlvcml0eSA9PSAidG9vbFRpcCIpIHsKICAgICAgICAgICAgICAgICAgICBpZih0b29sVGlwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHQgPSB0b29sVGlwLnZhbHVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKHRoaXMubW9kZWwuanNvbk1vZGVsLmV4dHJhcykgewogICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW5SZWFkZXJUZXh0ID0gdGhpcy5tb2RlbC5qc29uTW9kZWwuZXh0cmFzLmNhcHRpb247CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW5SZWFkZXJUZXh0ID0gdGhpcy5tb2RlbC5qc29uTW9kZWwubmFtZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKHByaW9yaXR5ID09ICJuYW1lIikgewogICAgICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHQgPSB0aGlzLm1vZGVsLmpzb25Nb2RlbC5uYW1lOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIHJldHVybiBzY3JlZW5SZWFkZXJUZXh0OwoKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlRHJhd0NoaWxkRXh0ZW50IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIGV4dGVudCA9IHt9OwogICAgICAgICAgICB2YXIgZHJhd1R5cGUgPSB0aGlzLmdldE9yRWxzZSh0aGlzLiRkYXRhKHRoaXMuZWwsIHhmYWxpYi52aWV3LkxheW91dENvbnN0LlhGQV9NT0RFTClbeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTk9ERV9UWVBFXSwgIiIpLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICAgIGlmKGRyYXdUeXBlID09ICJ0ZXh0Iil7CiAgICAgICAgICAgICAgICAvL1RoaXMgaXMgdG8gYXZvaWQgdHJ1bmNhdGlvbiBvZiBzdmcgdGV4dCB3aGVuIFNWRyBpcyBsYXJnZXIgdGhhbiBjb250YWluaW5nIGRpdi4KICAgICAgICAgICAgICAgIC8vSW4gdGhhdCBjYXNlIHdlIGFsbG93IFNWRyB0byBiZSBsYXJnZSB1cHRvIGV4dGVudCBvZiAxMjAlIG9mIHRoZSBhc3NpZ25lZCBkcmF3IGV4dGVudHMKICAgICAgICAgICAgICAgIC8vIEVhY2ggYnJvd3NlciBoYW5kbGVzIHN2ZyBkaWZmZXJlbnRseS4gQmVsb3cgZml4IHdvcmtzIGZvciBhbGwgc3VwcG9ydGVkIGJyb3dzZXIgYW5kIGF2b2lkIDIwJSB0cnVuY2F0aW9uIHdoaWNoIHdvdWxkIGhhbmRsZSBtb3N0IGNvbW1vbiBjYXNlcy4KICAgICAgICAgICAgICAgIC8vIEFjdHVhbCBmaXggd291bGQgcmVxdWlyZSBleGFjdCBjb21iaW5lZCBzdmcgaGVpZ2h0L3dpZHRoIGNhbGN1bGF0aW9uIHByb2JhYmx5IGluIFhURyBzaWRlLgogICAgICAgICAgICAgICAgZXh0ZW50WyJ3aWR0aCJdID0gIjEyMCUiOwogICAgICAgICAgICAgICAgZXh0ZW50WyJoZWlnaHQiXT0gIjEyMCUiOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy9SZXF1aXJlZCBzbyB0aGF0IGRyYXcgZG8gbm90IHNwaWxsIG91dCBvZiB0aGVpciBwYXJlbnQgZGl2LgogICAgICAgICAgICAgICAgZXh0ZW50WyJ3aWR0aCJdID0gIjEwMCUiOwogICAgICAgICAgICAgICAgZXh0ZW50WyJoZWlnaHQiXT0gIjEwMCUiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBleHRlbnQ7CiAgICAgICAgfSwKCiAgICAgICAgX2ZpbmREcmF3RWxlbWVudCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciBkcmF3RWxzID0gdGhpcy4kZWwuY2hpbGRyZW4oKTsKICAgICAgICAgICAgaWYoZHJhd0Vscy5sZW5ndGggPjApCiAgICAgICAgICAgICAgICByZXR1cm4gZHJhd0Vscy5nZXQoMCk7CiAgICAgICAgfSwKCiAgICAgICAgdXBkYXRlRGlzcGxheSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS51cGRhdGVEaXNwbGF5LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMuJGRyYXdDaGlsZCAhPSBudWxsICYmICF0aGlzLiRkcmF3Q2hpbGQuaXMoImltZyIpKSB7CiAgICAgICAgICAgICAgICAvL29ubHkgc2V0IGV4dGVudCBpZiBpdCBpcyBub3QgaW1nIGFzIGltZyBoYXMgaXRzIG93biBleHRlbnQKICAgICAgICAgICAgICAgIHZhciBkcmF3Q2hpbGRFeHRlbnQgPSB0aGlzLl9jb21wdXRlRHJhd0NoaWxkRXh0ZW50KCk7CiAgICAgICAgICAgICAgICAvL2RvIHRoaXMgb25seSBpZgogICAgICAgICAgICAgICAgaWYodGhpcy4kZHJhd0NoaWxkLmxlbmd0aCkKICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy4kZHJhd0NoaWxkLmdldCgwKSwgZHJhd0NoaWxkRXh0ZW50KTsKCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sICQsIHhmYWxpYik7KGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB2YXIgYnR3biA9IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5idHduOwoKICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldyA9ICB4ZmFsaWIudmlldy5CYXNlVmlldy5leHRlbmQoewogICAgICAgIC8vbGlzdCBvZiBSVEwgbGFuZ3VhZ2VzCiAgICAgICAgX3J0bExhbmc6e2hlIDogImhlIiwgYXIgOiAiYXIiLCBmYTogImZhIn0sCgogICAgICAgIF9hZGRPbnM6ewogICAgICAgICAgICAieC1zY3JpYmJsZS1hZGQtb24iIDogeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5TY3JpYmJsZUltYWdlRmllbGQKICAgICAgICB9LAogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdGhpcy5jYXB0aW9uTGF5b3V0TW9kZWwgPSBudWxsOwogICAgICAgICAgICB0aGlzLndpZGdldExheW91dE1vZGVsID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IG51bGw7CiAgICAgICAgICAgIHRoaXMuY29tbWl0RXZlbnQgPSB0aGlzLm9wdGlvbnMuY29tbWl0RXZlbnQ7CiAgICAgICAgICAgIHRoaXMuY29tbWl0UHJvcGVydHkgPSB0aGlzLm9wdGlvbnMuY29tbWl0UHJvcGVydHk7CiAgICAgICAgICAgIHRoaXMuY29tbWl0VGFyZ2V0ID0gdGhpcy5vcHRpb25zLmNvbW1pdFRhcmdldDsKICAgICAgICAgICAgdGhpcy5pc0Vycm9yID0gZmFsc2U7CgogICAgICAgICAgICB0aGlzLmNhcHRpb24gPSB0aGlzLl9maW5kQ2FwdGlvbigpOwogICAgICAgICAgICB0aGlzLndpZGdldCA9IHRoaXMuX2ZpbmRXaWRnZXQoKTsKICAgICAgICAgICAgaWYgKHRoaXMud2lkZ2V0KSB7CiAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZUJvcmRlckZvcldpZGdldCgpOwogICAgICAgICAgICAgICAgaWYodGhpcy5jb21taXRFdmVudCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkub24odGhpcy5jb21taXRFdmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fYmluZCh0aGlzLCB0aGlzLmhhbmRsZUNvbW1pdCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkub24oeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DTElDS19FVkVOVCwKICAgICAgICAgICAgICAgICAgICB0aGlzLl9iaW5kKHRoaXMsIHRoaXMuaGFuZGxlQ2xpY2tFdmVudCkpOwogICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkub24oeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FWElUX0VWRU5ULAogICAgICAgICAgICAgICAgICAgIHRoaXMuX2JpbmQodGhpcywgdGhpcy5oYW5kbGVGb2N1c091dCkpOwogICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkub24oeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYmluZCh0aGlzLCB0aGlzLmhhbmRsZUNoYW5nZUV2ZW50KSk7CiAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5vbih4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VOVEVSX0VWRU5ULAogICAgICAgICAgICAgICAgICAgIHRoaXMuX2JpbmQodGhpcywgdGhpcy5oYW5kbGVGb2N1c0V2ZW50KSk7CiAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5vbigia2V5cHJlc3MiLAogICAgICAgICAgICAgICAgICAgIHRoaXMuX2JpbmQodGhpcywgdGhpcy5oYW5kbGVLZXlQcmVzc0V2ZW50KSk7CiAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5vbih4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX1BSRU9QRU5fRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgJC5wcm94eSh0aGlzLmhhbmRsZVByZU9wZW5FdmVudCwgdGhpcykpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgaWYodGhpcy5jYXB0aW9uKSB7CiAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy5jYXB0aW9uLHsiY3Vyc29yIjoiZGVmYXVsdCJ9KTsKICAgICAgICAgICAgICAgIC8vYWRkIHByZXNlbnRhdGlvbiByb2xlIHRvIGNhcHRpb24KICAgICAgICAgICAgICAgICQodGhpcy5jYXB0aW9uKS5hdHRyKCJyb2xlIiwgInByZXNlbnRhdGlvbiIpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgJCh0aGlzLiRlbCkub24oIm1vdXNlZG93biIsICQucHJveHkodGhpcy5faGFuZGxlTW91c2VEb3duLHRoaXMpKQogICAgICAgICAgICAgICAgICAgICAgIC5vbigiY2xpY2siLCBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhhdC5tb2RlbC5tRWZmZWN0aXZlQWNjZXNzICE9ICJvcGVuIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9sYWJlbCBpcyBjbGlja2VkIGNsaWNrIHRoZSB3aWRnZXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCEkKGV2ZW50LnRhcmdldCkuY2xvc2VzdCgiLndpZGdldCIpLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuanFXaWRnZXQuY2xpY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHRoaXMuX2luaXRMYXlvdXQoKTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVCb3JkZXJGb3JXaWRnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICBpZih0aGlzLm1vZGVsKXsKICAgICAgICAgICAgICAgIHZhciB1aSA9IHRoaXMubW9kZWwuZ2V0RWxlbWVudCgidWkiLCAwLHRydWUpOwogICAgICAgICAgICAgICAgdmFyIGZpbGwsY29sb3IgOwogICAgICAgICAgICAgICAgaWYodWkpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgYm9yZGVyID0gdWkub25lT2ZDaGlsZC5nZXRFbGVtZW50KCJib3JkZXIiLCAwLHRydWUpOwogICAgICAgICAgICAgICAgICAgIGlmKGJvcmRlciAmJiBib3JkZXIucHJlc2VuY2UgPT0gInZpc2libGUiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuY2FwdGlvbiAgJiYgcGFyc2VJbnQodGhpcy5tb2RlbC5jYXB0aW9uLmdldEF0dHJpYnV0ZSgicmVzZXJ2ZSIpKSE9MCAgJiYgdGhpcy5tb2RlbC5wYXJlbnQuY2xhc3NOYW1lICE9ImV4Y2xHcm91cCIpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNzc1N0eWxlT2JqID0geGZhbGliLnZpZXcudXRpbC5TdHlsZXMuZ2V0U3R5bGVGb3JCb3JkZXIoYm9yZGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNzc1N0eWxlT2JqKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLndpZGdldCwgY3NzU3R5bGVPYmopOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYoIXRoaXMuZWRnZVByZXNlbmNlICAmJiB0aGlzLm1vZGVsLnBhcmVudC5jbGFzc05hbWUgIT0iZXhjbEdyb3VwIikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNzc1N0eWxlT2JqID0geGZhbGliLnZpZXcudXRpbC5TdHlsZXMuZ2V0U3R5bGVGb3JCb3JkZXIoYm9yZGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNzc1N0eWxlT2JqKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLndpZGdldCwgY3NzU3R5bGVPYmopOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmKGJvcmRlciAmJiAoZmlsbCA9IGJvcmRlci5nZXRFbGVtZW50KCJmaWxsIiwwLHRydWUpKSAmJiAoY29sb3IgPSBmaWxsLmdldEVsZW1lbnQoImNvbG9yIiwwLHRydWUpKQogICAgICAgICAgICAgICAgICAgICAgICAmJiBmaWxsLnByZXNlbmNlIT0iaGlkZGVuIgogICAgICAgICAgICAgICAgICAgICAgICAmJiBmaWxsLnByZXNlbmNlICE9ImludmlzaWJsZSIKICAgICAgICAgICAgICAgICAgICAgICApIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbG9yID0gY29sb3IudmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNvbG9yID09ICIiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9IjI1NSwyNTUsMjU1IjsgIC8vIGlmIG5vIGNvbG9yIHZhbHVlIGlzIHNwZWNpZmllZCB0aGVuIGZpbGwgZGVmYXVsdCBjb2xvcgogICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJyZ2IoIiArIGNvbG9yICsgIikiOwogICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5jc3MoImJhY2tncm91bmQtY29sb3IiLCBjb2xvcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCgogICAgICAgIF9oYW5kbGVNb3VzZURvd246IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmKCAhJChldmVudC50YXJnZXQpLmNsb3Nlc3QoIi53aWRnZXQiKS5sZW5ndGggJiYgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5jdXJyZW50Rm9jdXMgPT0gdGhpcyApIHsKICAgICAgICAgICAgICAgIHRoaXMuY2xpY2tlZE9uQ2FwdGlvbiA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfbWFya0FjY2VzcyA6IGZ1bmN0aW9uKGFjY2VzcykgewogICAgICAgICAgICBzd2l0Y2goYWNjZXNzKSB7CiAgICAgICAgICAgICAgICBjYXNlICJvcGVuIiA6CiAgICAgICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkucmVtb3ZlQ2xhc3MoIndpZGdldHJlYWRvbmx5Iik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJub25JbnRlcmFjdGl2ZSIgOgogICAgICAgICAgICAgICAgY2FzZSAicHJvdGVjdGVkIiA6CiAgICAgICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkuYWRkQ2xhc3MoIndpZGdldHJlYWRvbmx5Iik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJyZWFkT25seSIgOgogICAgICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLmFkZENsYXNzKCJ3aWRnZXRyZWFkb25seSIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRMYXlvdXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5CYXNlVmlldy5wcm90b3R5cGUuX2luaXRMYXlvdXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgaWYodGhpcy5faW5pdGlhbGl6ZWQpewogICAgICAgICAgICAgICAgdGhpcy5faW5pdGlhbGl6ZUZpZWxkQ2hpbGRMYXlvdXRBbmRFeHRlbnQoKTsKICAgICAgICAgICAgICAgIHRoaXMuX3N5bmNGb3JtTm9kZVRvSHRtbCh0cnVlKTsKICAgICAgICAgICAgICAgIHRoaXMubWFya01hbmRhdG9yeSgpOwogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuZWwsIHsiei1pbmRleCI6IDJ9KTsKICAgICAgICAgICAgICAgIGlmKHRoaXMuY2FwdGlvbil7CiAgICAgICAgICAgICAgICAgICAgLy9UaGlzIGlzIHRvIGF2b2lkIHRydW5jYXRpb24gb2Ygc3ZnIHRleHQgd2hlbiBTVkcgaXMgbGFyZ2VyIHRoYW4gY29udGFpbmluZyBkaXYuCiAgICAgICAgICAgICAgICAgICAgLy9JbiB0aGF0IGNhc2Ugd2UgYWxsb3cgU1ZHIHRvIGJlIGxhcmdlIHVwdG8gZXh0ZW50IG9mIDEyMCUgb2YgdGhlIGFzc2lnbmVkIGRyYXcgZXh0ZW50cwogICAgICAgICAgICAgICAgICAgIC8vIEVhY2ggYnJvd3NlciBoYW5kbGVzIHN2ZyBkaWZmZXJlbnRseS4gQmVsb3cgZml4IHdvcmtzIGZvciBhbGwgc3VwcG9ydGVkIGJyb3dzZXIgYW5kIGF2b2lkIDIwJSB0cnVuY2F0aW9uIHdoaWNoIHdvdWxkIGhhbmRsZSBtb3N0IGNvbW1vbiBjYXNlcy4KICAgICAgICAgICAgICAgICAgICAvLyBBY3R1YWwgZml4IHdvdWxkIHJlcXVpcmUgZXhhY3QgY29tYmluZWQgc3ZnIGhlaWdodC93aWR0aCBjYWxjdWxhdGlvbiBwcm9iYWJseSBpbiBYVEcgc2lkZS4KICAgICAgICAgICAgICAgICAgICB2YXIgY2FwdGlvblNWRyA9ICQodGhpcy5jYXB0aW9uKS5jaGlsZHJlbigic3ZnIikuZ2V0KDApOwoKICAgICAgICAgICAgICAgICAgICAvLyBEdWUgdG8gZXh0cmEgMjAlLCBCdXR0b24tMSBhbmQgQnV0dG9uLTIgcGxhY2VkIG5leHQgdG8gZWFjaCBvdGhlciBvdmVybGFwcy4KICAgICAgICAgICAgICAgICAgICAvLyBTbyB3aGVuIGNsaWNraW5nIG9uIEJ1dHRvbi0yLCBjbGljayBvbiBCdXR0b24tMSBnZXRzIHRyaWdnZXJlZCBiZWNhdXNlIG9mIEJ1dHRvbi0xIG92ZXJsYXBwaW5nIGFyZWEKICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmluZyBleHRyYSAyMCUgYW5kIGhpZGluZyBvdmVyZmxvd24gU1ZHIHRleHQgZm9yIGJ1dHRvbiBmaWVsZC4KCiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2tpbmcgZm9yIHN1Ym1pdCBhbmQgcmFkaW8gYnV0dG9uCiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc1BhcmVudEJ1dHRvbkZpZWxkID0gJCh0aGlzLmNhcHRpb24pLnBhcmVudCgpLmxlbmd0aCAmJiAkKHRoaXMuY2FwdGlvbikucGFyZW50KCkuaGFzQ2xhc3MoJ2J1dHRvbmZpZWxkJyk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc1NpYmxpbmdCdXR0b25GaWVsZCA9ICQodGhpcy5jYXB0aW9uKS5zaWJsaW5ncygpLmxlbmd0aCAmJiAkKHRoaXMuY2FwdGlvbikuc2libGluZ3MoKS5oYXNDbGFzcygnYnV0dG9uZmllbGR3aWRnZXQnKTsKICAgICAgICAgICAgICAgICAgICB2YXIgaGFzUGFyZW50UmFkaW9CdXR0b25GaWVsZCA9ICQodGhpcy5jYXB0aW9uKS5wYXJlbnQoKS5sZW5ndGggJiYgJCh0aGlzLmNhcHRpb24pLnBhcmVudCgpLmhhc0NsYXNzKCdyYWRpb2ZpZWxkJyk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc1NpYmxpbmdSYWRpb0J1dHRvbkZpZWxkID0gJCh0aGlzLmNhcHRpb24pLnNpYmxpbmdzKCkubGVuZ3RoICYmICQodGhpcy5jYXB0aW9uKS5zaWJsaW5ncygpLmhhc0NsYXNzKCdyYWRpb2ZpZWxkd2lkZ2V0Jyk7CiAgICAgICAgICAgICAgICAgICAgaWYoY2FwdGlvblNWRyl7CiAgICAgICAgICAgICAgICAgICAgICAgICQoY2FwdGlvblNWRykuYXR0cignZm9jdXNhYmxlJywgJ2ZhbHNlJyk7IC8vTEMtNzEwNSBMQy01NDQ0IHN2ZyB0YWJJbmRleCBkb2Vzbid0IHdvcmsgc28gYWRkaW5nIGZvY3VzYWJsZSBhcyBmYWxzZQogICAgICAgICAgICAgICAgICAgICAgICAvL0NRLTQyNzQ3MzIgOiBUbyBwcmV2ZW50IHN2ZyBiZWluZyByZWFkIG91dC4gQ2FwdGlvbihzdmcpIGFuZCBpbnB1dCBib3RoIGFyZSBiZWluZyByZWFkIGJ5IHNjcmVlbiByZWFkZXIsIG9ubHkgZm9jdXNzYWJsZSBzaG91bGQgYmUgcmVhZC4KICAgICAgICAgICAgICAgICAgICAgICAgJChjYXB0aW9uU1ZHKS5hdHRyKCdhcmlhLWhpZGRlbicsICd0cnVlJyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjYXB0aW9uQ2hpbGRFeHRlbnQgPSB7fTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoKGhhc1BhcmVudEJ1dHRvbkZpZWxkICYmIGhhc1NpYmxpbmdCdXR0b25GaWVsZCkgfHwgKGhhc1BhcmVudFJhZGlvQnV0dG9uRmllbGQgJiYgaGFzU2libGluZ1JhZGlvQnV0dG9uRmllbGQpKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRpb25DaGlsZEV4dGVudFsid2lkdGgiXSA9ICIxMDAlIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRpb25DaGlsZEV4dGVudFsiaGVpZ2h0Il09ICIxMDAlIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcy5jYXB0aW9uKS5jc3MoIm92ZXJmbG93IiwgImhpZGRlbiIpOwogICAgICAgICAgICAgICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRpb25DaGlsZEV4dGVudFsid2lkdGgiXSA9ICIxMjAlIjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcHRpb25DaGlsZEV4dGVudFsiaGVpZ2h0Il09ICIxMjAlIjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3MoY2FwdGlvblNWRywgY2FwdGlvbkNoaWxkRXh0ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoJC5icm93c2VyLndlYmtpdCB8fCAkLmJyb3dzZXIuY2hyb21lIHx8IHhmYWxpYi51dC5VdGlsaXRpZXMuY2hlY2tNaW5Nb3ppbGxhVmVyc2lvbigyOCkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9jaHJvbWUgaGFuZGxlcyB0aGUgcnRsIHRleHQgZWxlbWVudCBpbiBhIGRpZmZlcmVudCB3YXkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RoZXJlIGlzIGEgc2ltaWxhciBmdW5jdGlvbiBpbiBYZmFEcmF3VmlldwogICAgICAgICAgICAgICAgICAgICAgICAgICAgJChjYXB0aW9uU1ZHKS5jaGlsZHJlbigndGV4dFtkaXJlY3Rpb249InJ0bCJdJykuYXR0cigneCcsIHRoaXMuX2FkanVzdFRleHRDb29yZGluYXRlKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL0ludmFsaWRhdGUgdGhlIHRhYiBpbmRleGVzIGZvciB0aGUgcGFnZSBjb250YWluaW5nIHRoaXMgZmllbGQgd2hlbiB0aGlzIGZpZWxkIGlzIGluaXRpYWxpemVkLgogICAgICAgICAgICAgICAgLy9UaGlzIHdvdWxkIGp1c3QgcXVldWUgdGhlIHRhYmJpbmcgY29tcHV0YXRpb24gZm9yIHRoaXMgcGFydGljdWxhciBwYWdlLgogICAgICAgICAgICAgICAgdGhpcy5feGZhVmlld1JlZ2lzdHJ5KCkuaW52YWxpZGF0ZVRhYkluZGV4KHRoaXMuX3BhZ2VOdW1iZXIoKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYW5kbGVQcmVPcGVuRXZlbnQ6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLmV4ZWNFdmVudCgicHJlT3BlbiIpOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUZvY3VzRXZlbnQ6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmKCF0aGlzLmNsaWNrZWRPbkNhcHRpb24pIHsKICAgICAgICAgICAgICAgIHRoaXMubW9kZWwuX3hmYSgpLnNldFN1YmZvcm1Gb2N1cyh0aGlzLm1vZGVsLnBhcmVudFN1YmZvcm0pOwogICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5leGVjRXZlbnQoImVudGVyIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5jbGlja2VkT25DYXB0aW9uID0gZmFsc2U7IC8vIHJlc2V0IHRoZSBzdGF0ZQogICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9zZXRGb2N1c1BhcmFtKHRoaXMpOwogICAgICAgICAgICBpZihmb3JtQnJpZGdlKSB7CiAgICAgICAgICAgICAgICBpZihmb3JtQnJpZGdlLmlzQW5hbHl0aWNzRW5hYmxlZCkgeyAgIC8vT25seSBjb21wdXRpbmcgd2hlbiBhbmFseXRpY3MgZW5hYmxlZAogICAgICAgICAgICAgICAgICAgIHZhciBwcmV2Rm9jdXM9eGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5wcmV2Rm9jdXMsCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJGb2N1cz14ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1czsKICAgICAgICAgICAgICAgICAgICBpZihwcmV2Rm9jdXMpeyAgLy9pZiBwcmV2Rm9jdXMgaXMgYWxyZWFkeSBudWxsIHRoZW4gbm8gbmVlZCB0byBwYXNzIFNPTSBFeHByZXNzaW9uCiAgICAgICAgICAgICAgICAgICAgICAgIHByZXZGb2N1cz1wcmV2Rm9jdXMubW9kZWwuc29tRXhwcmVzc2lvbjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYoY3VyckZvY3VzKXsgLy9pZiBjdXJyRm9jdXMgaXMgYWxyZWFkeSBudWxsIHRoZW4gbm8gbmVlZCB0byBwYXNzIFNPTSBFeHByZXNzaW9uCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJGb2N1cz1jdXJyRm9jdXMubW9kZWwuc29tRXhwcmVzc2lvbjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLl90cmlnZ2VyT25CcmlkZ2UoImVsZW1lbnRGb2N1c0NoYW5nZWQiLCB0aGlzLm1vZGVsLCAiZm9jdXMiLCBwcmV2Rm9jdXMsIGN1cnJGb2N1cyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3JtQnJpZGdlLmNsaWNrZWRPbldpbmRvdyA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRm9jdXNPdXQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICBpZighdGhpcy5jbGlja2VkT25DYXB0aW9uKSB7CiAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLmV4ZWNFdmVudCgiZXhpdCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKGZvcm1CcmlkZ2UgJiYgZm9ybUJyaWRnZS5jbGlja2VkT25XaW5kb3cgPT09IHRydWUpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX3NldEZvY3VzUGFyYW0obnVsbCk7CiAgICAgICAgICAgICAgICBmb3JtQnJpZGdlLmNsaWNrZWRPbldpbmRvdyA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX3NldEZvY3VzUGFyYW0gOiBmdW5jdGlvbihjdXJyRm9jdXMpIHsKICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5wcmV2Rm9jdXMgPSB4ZmFsaWIudXQuQ2xhc3MucHJvdG90eXBlLmdldE9yRWxzZSh4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1cywgbnVsbCk7CiAgICAgICAgICAgIC8vVG8gbWluaW1pemUgcmVncmVzc2lvbiBpbXBhY3QgYXMgInhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuY3VycmVudEZvY3VzIiBpcyB1c2VkIGF0IGFsbCB0aGUgcGxhY2VzIGluIHRoZSBjb2RlCiAgICAgICAgICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuY3VycmVudEZvY3VzPWN1cnJGb2N1czsKICAgICAgICB9LAoKICAgICAgICBfY2xlYXJGb2N1c0luZm8gOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5wcmV2Rm9jdXMgPSBudWxsOwogICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1cz1udWxsOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUtleVByZXNzRXZlbnQ6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciBjb2RlID0gZXZlbnQuY2hhckNvZGUgfHwgZXZlbnQud2hpY2ggfHwgZXZlbnQua2V5Q29kZSB8fCAwOwogICAgICAgICAgICB2YXIgY2hhcmFjdGVyID0gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKTsKCiAgICAgICAgICAgIGlmKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5pc05vblByaW50YWJsZUtleShldmVudC5rZXkpKSB7IC8vIG1vemlsbGEgYWxzbyBnZW5lcmF0ZXMgYSBrZXlwcmVzcywgYWxvbmcgd2l0aCBrZXlkb3duCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBhbGwga2V5cywgc28gb25seSBoYW5kbGluZyBwcmludGFibGUga2V5cyBpbiBrZXlwcmVzcwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZih0aGlzLmNoYXJhY3RlciAhPSB1bmRlZmluZWQpIHsgLy8gdGFrZXMgY2FyZSBvZiBjYXNlcyB3aGVuIHhmYS5ldmVudC5jaGFuZ2UgaXMgc2V0IGJ5IHVzZXIgc2NyaXB0CiAgICAgICAgICAgICAgICBpZih0aGlzLmNoYXJhY3RlciA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24oInZhbHVlIix0aGlzLmpxV2lkZ2V0Lm9wdGlvbigiY3VyVmFsdWUiKSk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24oImRpc3BsYXlWYWx1ZSIsdGhpcy5qcVdpZGdldC5vcHRpb24oImN1clZhbHVlIikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZih0aGlzLmNoYXJhY3RlciAhPSBjaGFyYWN0ZXIgJiYKICAgICAgICAgICAgICAgICAgICAhKGV2ZW50LmtleSA9PT0gIkVudGVyIiAmJiB0aGlzLmNoYXJhY3RlciA9PT0gIlxuIikpIHsKICAgICAgICAgICAgICAgICAgICAvL1N0cmluZy5mcm9tQ2hhckNvZGUgcmV0dXJucyBcciBmb3IgRW50ZXIga2V5LCBidXQgY2hhcmFjdGVyIGlzIFxuIC0gaWdub3JlIHRoaXMgbWlzbWF0Y2gKICAgICAgICAgICAgICAgICAgICB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigidmFsdWUiLHRoaXMuY3VycmVudCk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24oImRpc3BsYXlWYWx1ZSIsdGhpcy5jdXJyZW50KTsKICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdGhpcy5jaGFyYWN0ZXIgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfc3luY0Zvcm1Ob2RlVG9IdG1sIDogZnVuY3Rpb24oZGVlcFN5bmMpIHsKICAgICAgICAgICAgdmFyIHBsdWdpbk9wdGlvbnMgPSB0aGlzLl9jcmVhdGVQbHVnaW5PcHRpb25zKCk7CiAgICAgICAgICAgIGlmKCF0aGlzLmpxV2lkZ2V0KQogICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVXaWRnZXRQbHVnaW4ocGx1Z2luT3B0aW9ucyk7CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgXy5lYWNoKHBsdWdpbk9wdGlvbnMsIGZ1bmN0aW9uKHZhbHVlLCBrZXkpewogICAgICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQub3B0aW9uKGtleSwgdmFsdWUpOwogICAgICAgICAgICAgICAgfSwgdGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5fbWFya0FjY2Vzcyh0aGlzLm1vZGVsLm1FZmZlY3RpdmVBY2Nlc3MpCiAgICAgICAgICAgIGlmKHRoaXMubW9kZWwuX19lcnJvclRleHQpCiAgICAgICAgICAgICAgICB0aGlzLl9kZWZlcnJlZE1hcmtFcnJvcigpOwogICAgICAgICAgICB4ZmFsaWIudmlldy5CYXNlVmlldy5wcm90b3R5cGUuX3N5bmNGb3JtTm9kZVRvSHRtbC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZU1vZGVsQ2hhbmdlZCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmIChldmVudC5fcHJvcGVydHkgPT0gdGhpcy5jb21taXRUYXJnZXQpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZVZhbHVlQ2hhbmdlKGV2ZW50KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgc3dpdGNoKGV2ZW50Ll9wcm9wZXJ0eSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgImZvY3VzIjoKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZm9jdXNXaWRnZXQodGhpcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgIlZhbGlkYXRpb25TdGF0ZSIgOgogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9tYXJrRXJyb3IoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJjaGFuZ2UiOgogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVFdmVudENoYW5nZVByb3BlcnR5KGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiQ2xlYXJFcnJvciI6CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NsZWFyRXJyb3IoZXZlbnQpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJmaWxsQ29sb3IiOgogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9maWxsQ29sb3IoZXZlbnQubmV3VGV4dCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5oYW5kbGVNb2RlbENoYW5nZWQuYXBwbHkodGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRG9tQ2hhbmdlZCA6ZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICBzd2l0Y2goZXZlbnQuX3Byb3BlcnR5KSB7CiAgICAgICAgICAgICAgICBjYXNlICJmb250LmZpbGwuY29sb3IudmFsdWUiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUZvbnRGaWxsQ29sb3JWYWx1ZShldmVudC5wcmV2VGV4dCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJmb250LnBvc3R1cmUiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUZvbnRQb3N0dXJlKGV2ZW50LnByZXZUZXh0KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgInZhbHVlLm1heENoYXJzIjoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVNYXhDaGFycyhldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJjYXB0aW9uLmZvbnQuZmlsbC5jb2xvci52YWx1ZSI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQ2FwdGlvbkZvbnRGaWxsQ29sb3JWYWx1ZShldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJudWxsVGVzdCI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlTnVsbFRlc3QoZXZlbnQsICQodGhpcy53aWRnZXQpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLmhhbmRsZURvbUNoYW5nZWQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVOdWxsVGVzdDogZnVuY3Rpb24gKGV2ZW50LCAkdGFyZ2V0KSB7CiAgICAgICAgICAgIHRoaXMuX2hhbmRsZU1hbmRhdG9yeShldmVudC5uZXdUZXh0LCAkdGFyZ2V0KTsKICAgICAgICAgICAgdGhpcy5faGFuZGxlRGlzYWJsZWQoZXZlbnQpOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVNYW5kYXRvcnk6IGZ1bmN0aW9uIChjaGFuZ2UsICR0YXJnZXQpIHsKICAgICAgICAgICAgaWYgKF8uY29udGFpbnMoWydkaXNhYmxlZCcsICd3YXJuaW5nJ10sIGNoYW5nZSkpIHsKICAgICAgICAgICAgICAgICR0YXJnZXQuYXR0cignZGF0YS1tYW5kYXRvcnknLCAnZmFsc2UnKQogICAgICAgICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnd2lkZ2V0TWFuZGF0b3J5Qm9yZGVyJyk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hhbmdlID09PSAnZXJyb3InKSB7CiAgICAgICAgICAgICAgICAkdGFyZ2V0LmF0dHIoJ2RhdGEtbWFuZGF0b3J5JywgJ3RydWUnKQogICAgICAgICAgICAgICAgICAgICAgIC50b2dnbGVDbGFzcygid2lkZ2V0TWFuZGF0b3J5Qm9yZGVyIiwgeGZhbGliLmdsb2JhbHMuaGlnaGxpZ2h0KTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVEaXNhYmxlZDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgIHZhciBjaGFuZ2UgPSBldmVudC5uZXdUZXh0OwogICAgICAgICAgIGlmIChjaGFuZ2UgPT09ICdkaXNhYmxlZCcpIHsKICAgICAgICAgICAgICB0aGlzLl9jbGVhckVycm9yKGV2ZW50KTsKICAgICAgICAgICB9CiAgICAgICAgfSwKCgogICAgICAgIF9oYW5kbGVDYXB0aW9uRm9udEZpbGxDb2xvclZhbHVlIDpmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICB2YXIgY2hpbGRTdmcgPSB0aGlzLmNhcHRpb24uY2hpbGRyZW5bMF07CiAgICAgICAgICAgIHZhciBmaWxsID0gInJnYigiICsgZXZlbnQucHJldlRleHQgKyAiKSIgOwoKICAgICAgICAgICAgaWYoY2hpbGRTdmcudGFnTmFtZSA9PSAic3ZnIiAmJiBjaGlsZFN2Zy5jaGlsZE5vZGVzKSB7CiAgICAgICAgICAgICAgXy5lYWNoKGNoaWxkU3ZnLmNoaWxkTm9kZXMsZnVuY3Rpb24obm9kZSxpbmRleCl7CiAgICAgICAgICAgICAgICBpZihub2RlLnRhZ05hbWUgPT0gJ3RleHQnKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKG5vZGUseydmaWxsJyA6IGZpbGx9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9LHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUZvbnRGaWxsQ29sb3JWYWx1ZSA6IGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigiY29sb3IiLCB2YWx1ZSk7CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUZvbnRQb3N0dXJlIDogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgIHRoaXMuanFXaWRnZXQub3B0aW9uKCJmb250LXN0eWxlIiwgdmFsdWUpOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVNYXhDaGFycyA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciBtYXhjaGFycyA9IGV2ZW50LnByZXZUZXh0OwogICAgICAgICAgICBpZihtYXhjaGFycykKICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQub3B0aW9uKCJtYXhDaGFycyIsZXZlbnQucHJldlRleHQpOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUNvbW1pdCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciByZXNpemVScWQgPSBmYWxzZTsKICAgICAgICAgICAgaWYodGhpcy5yZXNpemFibGUgJiYgdGhpcy5qcVdpZGdldC5vcHRpb24oInZhbHVlIikgIT0gdGhpcy5tb2RlbFt0aGlzLmNvbW1pdFRhcmdldF0pCiAgICAgICAgICAgICAgICByZXNpemVScWQgPSB0cnVlOwogICAgICAgICAgICB0aGlzLm1vZGVsW3RoaXMuY29tbWl0VGFyZ2V0XSA9IHRoaXMuanFXaWRnZXQub3B0aW9uKCJ2YWx1ZSIpOwogICAgICAgICAgICBpZihyZXNpemVScWQpCiAgICAgICAgICAgICAgICB0aGlzLmludmFsaWRhdGVTaXplKCk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlQ2hhbmdlRXZlbnQgOiBmdW5jdGlvbihjaGFuZ2VFdmVudCkgewogICAgICAgICAgICB2YXIgY3VycmVudCwKICAgICAgICAgICAgICAgIGV2ZW50ID0gY2hhbmdlRXZlbnQub3JpZ2luYWxFdmVudCwKICAgICAgICAgICAgICAgIG1heENoYXJzID0gcGFyc2VJbnQodGhpcy5qcVdpZGdldC5vcHRpb24oIm1heENoYXJzIikgfHwgdGhpcy5qcVdpZGdldC5vcHRpb24oImNvbWJDZWxscyIpKSB8fCAwLCAvLyB0byB0YWtlIGNhcmUgZm9yIGJvdGggdGV4dCAmIG51bWVyaWMgZmllbGRzCiAgICAgICAgICAgICAgICB2YWwgPSB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigiY3VyVmFsdWUiKSB8fCB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigiZGlzcGxheVZhbHVlIikgfHwgJycsCiAgICAgICAgICAgICAgICBzZWxlY3Rpb25TdGFydCA9IGV2ZW50LnNlbGVjdGlvblN0YXJ0LAogICAgICAgICAgICAgICAgc2VsZWN0aW9uRW5kID0gZXZlbnQuc2VsZWN0aW9uRW5kLAogICAgICAgICAgICAgICAgY29kZSA9IGV2ZW50LmNoYXJDb2RlIHx8IGV2ZW50LmtleUNvZGUgfHwgZXZlbnQud2hpY2gsCiAgICAgICAgICAgICAgICBjaGFyYWN0ZXIgPSBldmVudC5jaGFyYWN0ZXIgfHwgJycsCiAgICAgICAgICAgICAgICBjaGFuZ2UsCiAgICAgICAgICAgICAgICBmdWxsVGV4dDsKCiAgICAgICAgICAgIGlmKGV2ZW50Lm9yaWdpbmFsVHlwZSA9PSAiY3V0IikgewogICAgICAgICAgICAgICAgY2hhbmdlID0gIiI7CiAgICAgICAgICAgICAgICBpZih2YWwpIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gdmFsLnN1YnN0cigwLCBzZWxlY3Rpb25TdGFydCkgKyB2YWwuc3Vic3RyKHNlbGVjdGlvbkVuZCk7CiAgICAgICAgICAgICAgICAgICAgZnVsbFRleHQgPSBjdXJyZW50OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYoZXZlbnQub3JpZ2luYWxUeXBlID09ICJrZXlkb3duIikgewogICAgICAgICAgICAgICAgY2hhbmdlID0gIiI7CgogICAgICAgICAgICAgICAgaWYodmFsKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvZGUgPT0gOCB8fCBjb2RlID09IDQ2KSB7ICAvLyBiYWNrU3BhY2Ugb3IgRGVsCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3Rpb25TdGFydCAhPT0gc2VsZWN0aW9uRW5kKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gdmFsLnN1YnN0cigwLCBzZWxlY3Rpb25TdGFydCkgKyB2YWwuc3Vic3RyKHNlbGVjdGlvbkVuZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29kZSA9PSA4KSB7ICAvLyBiYWNrc3BhY2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gdmFsLnN1YnN0cigwLCBzZWxlY3Rpb25TdGFydCAtIDEpICsgdmFsLnN1YnN0cihzZWxlY3Rpb25TdGFydCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29kZSA9PSA0NikgeyAgLy8gZGVsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudCA9IHZhbC5zdWJzdHIoMCwgc2VsZWN0aW9uU3RhcnQpICsgdmFsLnN1YnN0cihzZWxlY3Rpb25TdGFydCArIDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gdmFsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZnVsbFRleHQgPSBjdXJyZW50OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgeyAvLyBrZXlwcmVzcyBvciBwYXN0ZQogICAgICAgICAgICAgICAgY2hhbmdlID0gY2hhcmFjdGVyOwogICAgICAgICAgICAgICAgaWYgKG1heENoYXJzID4gMCApIHsKICAgICAgICAgICAgICAgICAgICBpZiAodmFsLmxlbmd0aCAtIChzZWxlY3Rpb25FbmQgLSBzZWxlY3Rpb25TdGFydCkgPj0gbWF4Q2hhcnMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlID0gIiI7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlID0gY2hhcmFjdGVyLnN1YnN0cigwLCBtYXhDaGFycyAtIHZhbC5sZW5ndGggKyBzZWxlY3Rpb25FbmQgLSBzZWxlY3Rpb25TdGFydCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICh2YWwpIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gdmFsLnN1YnN0cigwLCBzZWxlY3Rpb25TdGFydCkgKyBjaGFuZ2UgKyB2YWwuc3Vic3RyKHNlbGVjdGlvbkVuZCk7CiAgICAgICAgICAgICAgICAgICAgZnVsbFRleHQgPSB2YWwuc3Vic3RyKDAsIHNlbGVjdGlvblN0YXJ0KSArIGNoYXJhY3RlciArIHZhbC5zdWJzdHIoc2VsZWN0aW9uRW5kKTsKCiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgPSBjaGFuZ2U7CiAgICAgICAgICAgICAgICAgICAgZnVsbFRleHQgPSBjaGFyYWN0ZXI7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYoIChtYXhDaGFycyAhPTAgJiYgY3VycmVudC5sZW5ndGggID4gbWF4Q2hhcnMpIHx8ICF0aGlzLmpxV2lkZ2V0Lm9wdGlvbigibGVuZ3RoTGltaXRWaXNpYmxlIikgKSB7CiAgICAgICAgICAgICAgICAgICAgY2hhbmdlID0gIiI7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudCA9IHZhbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBMQy02MjkwIDogcHJldmVudCBwYXN0ZSBmcm9tIHRydW5jYXRpbmcgYW55IG9mIHRoZSBwcmV2aW91cyB0ZXh0CiAgICAgICAgICAgICAgICBpZiAoZXZlbnQub3JpZ2luYWxUeXBlID09ICJwYXN0ZSIgJiYKICAgICAgICAgICAgICAgICAgICAoKG1heENoYXJzICE9IDAgJiYgZnVsbFRleHQubGVuZ3RoID4gbWF4Q2hhcnMpIHx8ICF0aGlzLmpxV2lkZ2V0Lm9wdGlvbigibGVuZ3RoTGltaXRWaXNpYmxlIikpKSB7IC8vIFRPRE8gOiB0YWtlIGNhcmUgb2YgbXVsdGlsaW5lIHNlbGVjdGlvbiBsYXRlcgogICAgICAgICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpczsKICAgICAgICAgICAgICAgICAgICBzZWxmLmpxV2lkZ2V0LiR1c2VyQ29udHJvbC5vbmUoImlucHV0IiwgZnVuY3Rpb24gKCkgeyAgLy8gd2FpdCB0aWxsIHRoZSBwYXN0ZSBhY3Rpb24gb2NjdXJzIGFuZCB0aGVuIHJlcGxhY2Ugd2l0aCBjb3JyZWN0IHZhbHVlCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuanFXaWRnZXQuJHVzZXJDb250cm9sLnZhbChjdXJyZW50KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wcm9wKCJzZWxlY3Rpb25TdGFydCIsIHNlbGVjdGlvbkVuZCkgLy8gTEMtNjI5MCA6IHJlc2V0IHRoZSBjdXJzb3IgcG9zIGFmdGVyd2FyZHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucHJvcCgic2VsZWN0aW9uRW5kIiwgc2VsZWN0aW9uRW5kKTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGRldGFpbCA9IHsKICAgICAgICAgICAgICAgIHByZXZUZXh0OnZhbCwKICAgICAgICAgICAgICAgIGtleWNvZGU6Y29kZSwKICAgICAgICAgICAgICAgIG1vZGlmaWVyOmV2ZW50LmN0cmxLZXksCiAgICAgICAgICAgICAgICBrZXlEb3duOiBldmVudC5rZXlEb3duLAogICAgICAgICAgICAgICAgc2hpZnQ6ZXZlbnQuc2hpZnRLZXksCiAgICAgICAgICAgICAgICBjaGFuZ2U6Y2hhbmdlLAogICAgICAgICAgICAgICAgbmV3VGV4dDpjdXJyZW50LAogICAgICAgICAgICAgICAgZnVsbFRleHQ6IGZ1bGxUZXh0CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIGlmKCEhY2hhbmdlIHx8IGN1cnJlbnQgIT0gdmFsKQogICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5leGVjRXZlbnQoImNoYW5nZSIsIGRldGFpbCk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlQ2xpY2tFdmVudCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciBwcmV2VmFsdWU9IHRoaXMuanFXaWRnZXQub3B0aW9uKCJ2YWx1ZSIpOwogICAgICAgICAgICB2YXIgZGV0YWlsID0gewogICAgICAgICAgICAgICAga2V5Y29kZTpldmVudC53aGljaCwKICAgICAgICAgICAgICAgIG1vZGlmaWVyOmV2ZW50LmN0cmxLZXksCiAgICAgICAgICAgICAgICBzaGlmdDpldmVudC5zaGlmdEtleQogICAgICAgICAgICB9OwogICAgICAgICAgICB0aGlzLm1vZGVsLmV4ZWNFdmVudCgiY2xpY2siLCBkZXRhaWwpOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVFdmVudENoYW5nZVByb3BlcnR5IDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgdGhpcy5jaGFyYWN0ZXIgPSBldmVudC5wcmV2VGV4dDsKICAgICAgICAgICAgdmFyIHByZXZWYWx1ZT0gdGhpcy5qcVdpZGdldC5vcHRpb24oImN1clZhbHVlIikgfHwgdGhpcy5qcVdpZGdldC5vcHRpb24oImRpc3BsYXlWYWx1ZSIpIHx8ICIiOwogICAgICAgICAgICB2YXIgcG9zID0gdGhpcy5qcVdpZGdldC5vcHRpb25zLnBvcyA7CiAgICAgICAgICAgIHRoaXMuY3VycmVudCA9IHByZXZWYWx1ZS5zdWJzdHIoMCwgcG9zKSArIHRoaXMuY2hhcmFjdGVyICsgcHJldlZhbHVlLnN1YnN0cihwb3MpOwogICAgICAgICAgICAvL3ZhciB2YWx1ZSA9IHRoaXMuanFXaWRnZXQub3B0aW9uKCJ2YWx1ZSIpIHx8ICIiIDsKICAgICAgICAgICAgLy92YXIgZGlzcGxheVZhbHVlID0gdGhpcy5qcVdpZGdldC5vcHRpb24oImRpc3BsYXlWYWx1ZSIpIHx8ICIiICAgOwoKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlVmFsdWVDaGFuZ2UgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAvL3hmYS5Mb2dnZXIuZGVidWcoIltGaWVsZFZpZXcuX2hhbmRsZVZhbHVlQ2hhbmdlXXZhbHVlOnNvbSIKICAgICAgICAgICAgLy8gICAgICAgICsgZXZlbnQubmV3VGV4dCArICI6IiArIHRoaXMuJGVsLmRhdGEoInNvbSIpKTsKICAgICAgICAgICAgdmFyIHJlc2l6ZVJlcXVpcmVkID0gICh0aGlzLmpxV2lkZ2V0Lm9wdGlvbigiZGlzcGxheVZhbHVlIikgIT0gZXZlbnQubmV3VGV4dCkgJiYgdGhpcy5yZXNpemFibGUgOwogICAgICAgICAgICB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigidmFsdWUiLGV2ZW50LnByZXZUZXh0KTsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24oImRpc3BsYXlWYWx1ZSIsZXZlbnQubmV3VGV4dCk7CiAgICAgICAgICAgIGlmKHJlc2l6ZVJlcXVpcmVkKXsKICAgICAgICAgICAgICAgIHRoaXMuaW52YWxpZGF0ZVNpemUoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9tYXJrRXJyb3IgOiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgIC8vdGhpcy4kY3NzKHRoaXMud2lkZ2V0LCAiYmFja2dyb3VuZC1jb2xvciIsIiNEM0QzRDMiKTsKICAgICAgICAgICAgJCh0aGlzLndpZGdldCkuYWRkQ2xhc3MoIndpZGdldEVycm9yIik7CiAgICAgICAgICAgIHRoaXMuanFXaWRnZXQubWFya0Vycm9yKGV2bnQubmV3VGV4dCwgZXZudC5wcmV2VGV4dCk7CiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZVdpZGdldE9wdGlvbigiaXNWYWxpZCIsZmFsc2UpOwogICAgICAgIH0sCgogICAgICAgIF9kZWZlcnJlZE1hcmtFcnJvciA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAvL3RoaXMuJGNzcyh0aGlzLndpZGdldCwgImJhY2tncm91bmQtY29sb3IiLCIjRDNEM0QzIik7CiAgICAgICAgICAgIGlmKHRoaXMubW9kZWwubWFuZGF0b3J5ID09ICJlcnJvciIpCiAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5hZGRDbGFzcygid2lkZ2V0RXJyb3IiKTsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5tYXJrRXJyb3IodGhpcy5tb2RlbC5fX2Vycm9yVGV4dCwgdGhpcy5tb2RlbC5tYW5kYXRvcnkpOwogICAgICAgICAgICB0aGlzLl91cGRhdGVXaWRnZXRPcHRpb24oImlzVmFsaWQiLGZhbHNlKTsKICAgICAgICB9LAoKICAgICAgICBfY2xlYXJFcnJvciA6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgLy90aGlzLiRjc3ModGhpcy53aWRnZXQsICJiYWNrZ3JvdW5kLWNvbG9yIiwgIndoaXRlIik7CiAgICAgICAgICAgICQodGhpcy53aWRnZXQpLnJlbW92ZUNsYXNzKCJ3aWRnZXRFcnJvciIpOwogICAgICAgICAgICB0aGlzLmpxV2lkZ2V0LmNsZWFyRXJyb3IoKTsKICAgICAgICAgICAgdGhpcy5fdXBkYXRlV2lkZ2V0T3B0aW9uKCJpc1ZhbGlkIix0cnVlKTsKICAgICAgICB9LAoKICAgICAgICAvLyBmb3IgYWxsIGZpZWxkcwogICAgICAgIF91cGRhdGVXaWRnZXRPcHRpb246IGZ1bmN0aW9uKG9wdGlvbk5hbWUsIG9wdGlvblZhbHVlKXsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24ob3B0aW9uTmFtZSwgb3B0aW9uVmFsdWUpOwogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVBY2Nlc3NDaGFuZ2UgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAvL3hmYS5Mb2dnZXIuZGVidWcoIltfaGFuZGxlQWNjZXNzQ2hhbmdlXWFjY2Vzczpzb20iCiAgICAgICAgICAgIC8vICAgICAgICArIGV2ZW50Lm5ld1RleHQgKyAiOiIgKyB0aGlzLiRlbC5kYXRhKCJzb20iKSk7CiAgICAgICAgICAgIHRoaXMuanFXaWRnZXQub3B0aW9uKCJhY2Nlc3MiLGV2ZW50Lm5ld1RleHQpOwogICAgICAgICAgICBpZihldmVudC5uZXdUZXh0ICE9IGV2ZW50LnByZXZUZXh0KQogICAgICAgICAgICAgICAgdGhpcy5fbWFya0FjY2VzcyhldmVudC5uZXdUZXh0KQogICAgICAgIH0sCgogICAgICAgIF9maW5kV2lkZ2V0IDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICh0aGlzLiRlbC5oYXNDbGFzcygid2lkZ2V0IikpCiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy4kZWwuZ2V0KDApOwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciB3aWRnZXRMaXN0ID0gdGhpcy4kZWwuZmluZCgiLndpZGdldCIpOwogICAgICAgICAgICAgICAgaWYgKHdpZGdldExpc3QubGVuZ3RoID4gMCl7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdpZGdldExpc3QuZ2V0KDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBfZmluZENhcHRpb24gOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIGNhcHRpb25MaXN0ID0gJCgiLmNhcHRpb24iLCB0aGlzLiRlbCk7CiAgICAgICAgICAgIGlmIChjYXB0aW9uTGlzdC5sZW5ndGggPiAwKXsKICAgICAgICAgICAgICAgIHJldHVybiBjYXB0aW9uTGlzdC5nZXQoMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfZ2V0UGFyYVN0eWxlcyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciBwYXJhU3R5bGVzID0ge30scGFyYTsKICAgICAgICAgICAgcGFyYSA9IHRoaXMubW9kZWwuZ2V0RWxlbWVudCgicGFyYSIsIDAsIHRydWUpOwogICAgICAgICAgICBpZihwYXJhKXsKICAgICAgICAgICAgICAgIHBhcmFTdHlsZXMgPSB7CiAgICAgICAgICAgICAgICAgICAgInRleHQtYWxpZ24iIDogcGFyYS5oQWxpZ24sCiAgICAgICAgICAgICAgICAgICAgInZlcnRpY2FsLWFsaWduIiA6IHBhcmEudkFsaWduLAogICAgICAgICAgICAgICAgICAgICJ0ZXh0LWluZGVudCIgOiB0aGlzLl9jb252ZXJ0VG9QeChwYXJhLnRleHRJbmRlbnQpLAogICAgICAgICAgICAgICAgICAgICJwYWRkaW5nLWxlZnQiIDogdGhpcy5fY29udmVydFRvUHgocGFyYS5tYXJnaW5MZWZ0KSwKICAgICAgICAgICAgICAgICAgICAicGFkZGluZy1yaWdodCIgOiB0aGlzLl9jb252ZXJ0VG9QeChwYXJhLm1hcmdpblJpZ2h0KSwKICAgICAgICAgICAgICAgICAgICAicGFkZGluZy10b3AiIDogdGhpcy5fY29udmVydFRvUHgocGFyYS5zcGFjZUFib3ZlKSwKICAgICAgICAgICAgICAgICAgICAicGFkZGluZy1ib3R0b20iIDogdGhpcy5fY29udmVydFRvUHgocGFyYS5zcGFjZUJlbG93KQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcGFyYVN0eWxlczsKICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlUGx1Z2luT3B0aW9ucyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpZih0aGlzLm1vZGVsKXsKICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMubW9kZWxbdGhpcy5jb21taXRUYXJnZXRdIHx8IG51bGw7CiAgICAgICAgICAgICAgICB2YXIgc2NyZWVuUmVhZGVyVGV4dDsKICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHQgPSB0aGlzLl9nZXRTY3JlZW5SZWFkZXJUZXh0KCk7CiAgICAgICAgICAgICAgICB2YXIgdGFiSW5kZXggPSAwOwogICAgICAgICAgICAgICAgaWYodGhpcy5tb2RlbC5qc29uTW9kZWwuZXh0cmFzICYmIHRoaXMubW9kZWwuanNvbk1vZGVsLmV4dHJhcy50YWJJbmRleCkgewogICAgICAgICAgICAgICAgICAgIHRhYkluZGV4ID0gdGhpcy5tb2RlbC5qc29uTW9kZWwuZXh0cmFzLnRhYkluZGV4OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBsYW5nID0gdGhpcy5fbGFuZ0Zyb21Mb2NhbGUodGhpcy5tb2RlbC5fZ2V0TG9jYWxlKCkpOwogICAgICAgICAgICAgICAgdmFyIGRpcmVjdGlvbjsKCiAgICAgICAgICAgICAgICBpZihsYW5nICYmIHRoaXMuX3J0bExhbmdbbGFuZ10pewogICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9ICJydGwiOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBwYXJhU3R5bGVzID0gdGhpcy5fZ2V0UGFyYVN0eWxlcygpOwogICAgICAgICAgICAgICAgdmFyIHdpZGdldE1vZGVsID0gdGhpcy53aWRnZXRMYXlvdXRNb2RlbCB8fCB0aGlzLmxheW91dE1vZGVsOwogICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICAibmFtZSIgOiB0aGlzLm1vZGVsLmpzb25Nb2RlbC5uYW1lKyIiK3RoaXMuX2lkLAogICAgICAgICAgICAgICAgICAgICJ2YWx1ZSIgOiB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAiZGlzcGxheVZhbHVlIjogdGhpcy5tb2RlbC5mb3JtYXR0ZWRWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAiY29tbWl0UHJvcGVydHkiIDogdGhpcy5jb21taXRQcm9wZXJ0eSwKICAgICAgICAgICAgICAgICAgICAiYWNjZXNzIjogdGhpcy5tb2RlbC5tRWZmZWN0aXZlQWNjZXNzLAogICAgICAgICAgICAgICAgICAgICJwbGF0Zm9ybSI6IHRoaXMubW9kZWwuX3hmYSgpLmhvc3QucGxhdGZvcm0sCiAgICAgICAgICAgICAgICAgICAgInNjcmVlblJlYWRlclRleHQiOiBzY3JlZW5SZWFkZXJUZXh0LAogICAgICAgICAgICAgICAgICAgIC8qInRhYkluZGV4IjogdGFiSW5kZXgsKi8KICAgICAgICAgICAgICAgICAgICAicGFyYVN0eWxlcyIgOiBwYXJhU3R5bGVzLAogICAgICAgICAgICAgICAgICAgICJkaXIiIDogZGlyZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICJoU2Nyb2xsRGlzYWJsZWQiIDogIXRoaXMucmVzaXphYmxlICYmIHRoaXMubW9kZWwudWkub25lT2ZDaGlsZC5oU2Nyb2xsUG9saWN5ID09PSAib2ZmIiwKICAgICAgICAgICAgICAgICAgICAiaGVpZ2h0IiA6IHdpZGdldE1vZGVsLmV4dGVudGggKyB3aWRnZXRNb2RlbC5ib3JkZXJ0b3AvMiArIHdpZGdldE1vZGVsLmJvcmRlcmJvdHRvbS8yLAogICAgICAgICAgICAgICAgICAgICJjb21taXRFdmVudCIgOiB0aGlzLmNvbW1pdEV2ZW50CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgIH0sCgogICAgICAgIF9nZXRTY3JlZW5SZWFkZXJUZXh0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciBzY3JlZW5SZWFkZXJUZXh0ID0gIiI7CiAgICAgICAgICAgIGlmICh0aGlzLm1vZGVsKSB7CiAgICAgICAgICAgICAgICB2YXIgYXNzaXN0ID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCJhc3Npc3QiLCAwLCB0cnVlKTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmdldE9yRWxzZShhc3Npc3QsICJzcGVhay5kaXNhYmxlIiwgMCkgIT0gMSkgeyAvLyBsb29zZSBjb21wYXJlIHN0cmluZyB2YWx1ZQoKICAgICAgICAgICAgICAgICAgICB2YXIgcHJpb3JpdHkgPSB0aGlzLmdldE9yRWxzZShhc3Npc3QsICJzcGVhay5wcmlvcml0eSIsICJzcGVhayIpLAogICAgICAgICAgICAgICAgICAgICAgICBjYW5kaWRhdGVzID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNwZWFrIjogdGhpcy5nZXRPckVsc2UoYXNzaXN0LCAic3BlYWsudmFsdWUiLCAiIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2FwdGlvbiI6IHRoaXMuZ2V0T3JFbHNlKHRoaXMubW9kZWwsICJqc29uTW9kZWwuZXh0cmFzLmNhcHRpb24iLCAiIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidG9vbFRpcCI6IHRoaXMuZ2V0T3JFbHNlKGFzc2lzdCwgInRvb2xUaXAudmFsdWUiLCAiIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAibmFtZSI6IHRoaXMuZ2V0T3JFbHNlKHRoaXMubW9kZWwsICJqc29uTW9kZWwubmFtZSIsICIiKQogICAgICAgICAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgICAgICBzY3JlZW5SZWFkZXJUZXh0ID0gY2FuZGlkYXRlc1twcmlvcml0eV0gfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FuZGlkYXRlc1sic3BlYWsiXSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYW5kaWRhdGVzWyJjYXB0aW9uIl0gfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FuZGlkYXRlc1sidG9vbFRpcCJdIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbmRpZGF0ZXNbIm5hbWUiXTsKICAgICAgICAgICAgICAgICAgICAvLyBDUS04NTE4MyA6IGdvaW5nIGFnYWluc3QgeGZhIHNwZWMgKHBnIDUwNSkgcHJpb3JpdGlzZSBjYXB0aW9uIG92ZXIgdG9vbHRpcAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzY3JlZW5SZWFkZXJUZXh0OwogICAgICAgIH0sCgogICAgICAgIF9hc3NpZ25Ub29sVGlwOiB4ZmFsaWIudmlldy5YZmFEcmF3Vmlldy5wcm90b3R5cGUuX2Fzc2lnblRvb2xUaXAsCgoJCV9pbnN0YW50aWF0ZVdpZGdldDpmdW5jdGlvbih3aWRnZXROYW1lLG9wdGlvbnMpewoJCSAgICBpZiAod2lkZ2V0TmFtZSAmJiB3aWRnZXROYW1lLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICB0cnl7CiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpW3dpZGdldE5hbWVdKG9wdGlvbnMpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy4kZGF0YSh0aGlzLndpZGdldCwgd2lkZ2V0TmFtZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtIit3aWRnZXROYW1lKTsKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmVycm9yKCJ4ZmFWaWV3IiwgImV4Y2VwdGlvbiAiK2V4Y2VwdGlvbi5tZXNzYWdlKyIgaW4gY3JlYXRpbmcgdXNlciB3aWRnZXQuIHdpZGdldDoiK3dpZGdldE5hbWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoJCX0sCiAgICAgICAgX2NyZWF0ZVNjcmliYmxlV2lkZ2V0T3B0aW9uczpmdW5jdGlvbihvcHRpb25zKXsKICAgICAgICAgICAgdmFyIGluaXRQYXJhbXMgPSB0aGlzLmdldE9yRWxzZSh0aGlzLm1vZGVsLnVpLCJleHRyYXMuY2hpbGRyZW4iLG51bGwpOwogICAgICAgICAgICB2YXIgZ2VvTG9jUGFyYW0gPSBfLmZpbmQoaW5pdFBhcmFtcyxmdW5jdGlvbihvYmopewoJICAgICAgICAgICAgcmV0dXJuIG9iaiYmb2JqLm5hbWU9PSJnZW9Mb2NNYW5kYXRvcnlPbklwYWQiOyAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICB2YXIgZ2VvTG9jTWFuZGF0b3J5T25JcGFkID0gKGdlb0xvY1BhcmFtJiZnZW9Mb2NQYXJhbS52YWx1ZSkgfHwgKCB3aW5kb3cuZm9ybUJyaWRnZS51c2VyQ29uZmlnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgd2luZG93LmZvcm1CcmlkZ2UudXNlckNvbmZpZ1snc2NyaWJibGVJbWFnZUZpZWxkQ29uZmlnJ10KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiB3aW5kb3cuZm9ybUJyaWRnZS51c2VyQ29uZmlnWydzY3JpYmJsZUltYWdlRmllbGRDb25maWcnXS5nZW9Mb2NNYW5kYXRvcnlPbklwYWQgKTsKICAgICAgICAgICAgcmV0dXJuIF8uZXh0ZW5kKHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvTG9jTWFuZGF0b3J5T25JcGFkOmdlb0xvY01hbmRhdG9yeU9uSXBhZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxvcHRpb25zKTsKICAgICAgICB9LAogICAgICAgIGNyZWF0ZVdpZGdldFBsdWdpbiA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgdmFyIHdpZGdldENvbmZpZyA9IHRoaXMuX3hmYVZpZXdSZWdpc3RyeSgpLndpZGdldENvbmZpZygpOwogICAgICAgICAgICB2YXIgd2lkZ2V0TmFtZTsKCQkJCiAgICAgICAgICAgIGlmKHdpZGdldENvbmZpZyl7CiAgICAgICAgICAgICAgICAgICAgd2lkZ2V0TmFtZSA9IF8uZmlsdGVyKHdpZGdldENvbmZpZywKICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih3aWRnZXROYW1lLCBzZWxlY3Rvcil7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoaXMuJGVsLmZpbHRlcihzZWxlY3RvcikubGVuZ3RoID4wKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHRoaXMpWzBdOwogICAgICAgICAgICB9IAoKICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuX2luc3RhbnRpYXRlV2lkZ2V0KHdpZGdldE5hbWUsb3B0aW9ucyk7CgkJCQogICAgICAgICAgICBpZighdGhpcy5qcVdpZGdldCl7CiAgICAgICAgICAgICAgICB3aWRnZXROYW1lID0gdGhpcy5fZ2V0V2lkZ2V0TmFtZUZyb21VaUV4dHJhKCk7CiAgICAgICAgICAgICAgICBpZiAod2lkZ2V0TmFtZSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQgPSB0aGlzLl9pbnN0YW50aWF0ZVdpZGdldCh3aWRnZXROYW1lLCB0aGlzLl9jcmVhdGVTY3JpYmJsZVdpZGdldE9wdGlvbnMob3B0aW9ucykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgkJCQogICAgICAgICAgICBpZighdGhpcy5qcVdpZGdldCl7CgkJCQkJdGhpcy5fY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbihvcHRpb25zKTsKCQkJfQogICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmRlYnVnKCJ4ZmFWaWV3IiwgImNyZWF0aW5nIHVzZXIgd2lkZ2V0LiB3aWRnZXQ6IiArIHRoaXMuanFXaWRnZXQuX3dpZGdldE5hbWUKICAgICAgICAgICAgKyAiIGZvciAiICsgdGhpcy5tb2RlbC5zb21FeHByZXNzaW9uKTsKICAgICAgICB9LAoKICAgICAgICAvKioKICAgICAgICAqIHJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHdpZGdldCBwcmVzZW50IGluIHVpIGV4dHJhcwogICAgICAgICogQHJldHVybnMge3N0cmluZ30gd2lkZ2V0TmFtZQogICAgICAgICovCiAgICAgICAgX2dldFdpZGdldE5hbWVGcm9tVWlFeHRyYSA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHdpZGdldE5hbWUgPSBudWxsLAogICAgICAgICAgICAgICAgdWlFeHRyYXNOYW1lID0gdGhpcy5nZXRPckVsc2UodGhpcywibW9kZWwudWkuZXh0cmFzLm5hbWUiLG51bGwpOwogICAgICAgICAgICBpZih1aUV4dHJhc05hbWUgJiYgdWlFeHRyYXNOYW1lLmxlbmd0aCA+PSAyICYmIHRoaXMuX2FkZE9ucy5oYXNPd25Qcm9wZXJ0eSh1aUV4dHJhc05hbWUpKXsKICAgICAgICAgICAgICAgIHdpZGdldE5hbWUgPSB0aGlzLl9hZGRPbnNbdWlFeHRyYXNOYW1lXTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gd2lkZ2V0TmFtZTsKICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbiA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgJCh0aGlzLndpZGdldCkuZGVmYXVsdFdpZGdldChvcHRpb25zKTsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtZGVmYXVsdFdpZGdldCIpOwogICAgICAgIH0sCgogICAgICAgIG1hcmtNYW5kYXRvcnkgOiBmdW5jdGlvbigpewogICAgICAgICAgICBpZih0aGlzLm1vZGVsLm1hbmRhdG9yeT09ICJlcnJvciIpCiAgICAgICAgICAgICAgICBpZih0aGlzLndpZGdldCkKICAgICAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5hdHRyKCJkYXRhLW1hbmRhdG9yeSIsICJ0cnVlIikgOwoKICAgICAgICB9LAoKICAgICAgICBfaW5pdGlhbGl6ZUZpZWxkQ2hpbGRMYXlvdXRBbmRFeHRlbnQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYgKHRoaXMuY2FwdGlvbikgewogICAgICAgICAgICAgICAgdmFyIGNWaWV3ID0gXy5leHRlbmQoe30sIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZSwgewogICAgICAgICAgICAgICAgICAgIGVsIDogdGhpcy5jYXB0aW9uLAogICAgICAgICAgICAgICAgICAgICRlbCA6ICQodGhpcy5jYXB0aW9uKQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5CYXNlVmlldy5wcm90b3R5cGUuX2luaXRpYWxpemVMYXlvdXRNb2RlbC5hcHBseShjVmlldyk7ICAvL1RPRE86IGhhbmRsZSB0aGluZ3Mgd2hlbiBtb3ZpbmcgbGF5b3V0IHRvIGZvcm1Eb20KICAgICAgICAgICAgICAgIHRoaXMuY2FwdGlvbkxheW91dE1vZGVsID0gY1ZpZXcubGF5b3V0TW9kZWw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRoaXMud2lkZ2V0ICYmIHRoaXMuY2FwdGlvbikgewogICAgICAgICAgICAgICAgdmFyIHdWaWV3ID0gXy5leHRlbmQoe30sIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZSwgewogICAgICAgICAgICAgICAgICAgIGVsIDogdGhpcy53aWRnZXQsCiAgICAgICAgICAgICAgICAgICAgJGVsIDogJCh0aGlzLndpZGdldCkKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLl9pbml0aWFsaXplTGF5b3V0TW9kZWwuYXBwbHkod1ZpZXcpOwogICAgICAgICAgICAgICAgdGhpcy53aWRnZXRMYXlvdXRNb2RlbCA9IHdWaWV3LmxheW91dE1vZGVsOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2dldE1lYXN1cmVtZW50T3B0aW9ucyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciB3aWRnZXRNb2RlbCA9IHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwgfHwgdGhpcy5sYXlvdXRNb2RlbDsKICAgICAgICAgICAgcmV0dXJuICh7CiAgICAgICAgICAgICAgIHJlZkVsIDogdGhpcy5qcVdpZGdldCAmJiB0aGlzLmpxV2lkZ2V0LiR1c2VyQ29udHJvbCA/IHRoaXMuanFXaWRnZXQuJHVzZXJDb250cm9sWzBdIDogbnVsbCwKICAgICAgICAgICAgICAgd2lkdGggOiAod2lkZ2V0TW9kZWwuZXh0ZW50dyAtIHdpZGdldE1vZGVsLm1hcmdpbmxlZnQgLSB3aWRnZXRNb2RlbC5tYXJnaW5yaWdodCksCiAgICAgICAgICAgICAgIGhlaWdodCA6ICh3aWRnZXRNb2RlbC5leHRlbnRoIC0gd2lkZ2V0TW9kZWwubWFyZ2ludG9wIC0gd2lkZ2V0TW9kZWwubWFyZ2luYm90dG9tKSwKICAgICAgICAgICAgICAgbWluV2lkdGggOiAod2lkZ2V0TW9kZWwuZXh0ZW50bWludz4tMSk/KHdpZGdldE1vZGVsLmV4dGVudG1pbncgLSB3aWRnZXRNb2RlbC5tYXJnaW5sZWZ0IC0gd2lkZ2V0TW9kZWwubWFyZ2lucmlnaHQpOndpZGdldE1vZGVsLmV4dGVudG1pbncsCiAgICAgICAgICAgICAgIG1pbkhlaWdodCA6KHdpZGdldE1vZGVsLmV4dGVudG1pbmg+LTEpPyh3aWRnZXRNb2RlbC5leHRlbnRtaW5oIC0gd2lkZ2V0TW9kZWwubWFyZ2ludG9wIC0gd2lkZ2V0TW9kZWwubWFyZ2luYm90dG9tKTp3aWRnZXRNb2RlbC5leHRlbnRtaW5oLAogICAgICAgICAgICAgICBtYXhXaWR0aCA6ICh3aWRnZXRNb2RlbC5leHRlbnRtYXh3ID4gLTEpPyh3aWRnZXRNb2RlbC5leHRlbnRtYXh3IC0gd2lkZ2V0TW9kZWwubWFyZ2lubGVmdCAtIHdpZGdldE1vZGVsLm1hcmdpbnJpZ2h0KTp3aWRnZXRNb2RlbC5leHRlbnRtYXh3LAogICAgICAgICAgICAgICBtYXhIZWlnaHQgOih3aWRnZXRNb2RlbC5leHRlbnRtYXhoID4gLTEpPyh3aWRnZXRNb2RlbC5leHRlbnRtYXhoIC0gd2lkZ2V0TW9kZWwubWFyZ2ludG9wIC0gd2lkZ2V0TW9kZWwubWFyZ2luYm90dG9tKTp3aWRnZXRNb2RlbC5leHRlbnRtYXhoCiAgICAgICAgICAgIH0pOwogICAgICAgIH0sCgogICAgICAgIG1lYXN1cmVTaXplIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIHJlc2l6ZWQgPSBmYWxzZTsKICAgICAgICAgICAgaWYodGhpcy5yZXNpemFibGUpewogICAgICAgICAgICAgICAgdmFyIHRleHQgPSAodGhpcy5tb2RlbCAmJiB0aGlzLm1vZGVsW3RoaXMuY29tbWl0VGFyZ2V0XSE9IG51bGwpPyB0aGlzLm1vZGVsW3RoaXMuY29tbWl0VGFyZ2V0XSA6ICIiOwogICAgICAgICAgICAgICAgcmVzaXplZCA9IHRoaXMuX3VwZGF0ZVdpZGdldE1vZGVsKHRleHQpOwogICAgICAgICAgICAgICAgaWYocmVzaXplZCAmJiB0aGlzLmNhcHRpb24gJiYgdGhpcy53aWRnZXQgJiYgdGhpcy5tb2RlbC5jYXB0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKHRoaXMubW9kZWwuY2FwdGlvbi5nZXRBdHRyaWJ1dGUoInBsYWNlbWVudCIpKXsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAibGVmdCI6CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInJpZ2h0IjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50dyAgPSB0aGlzLmxheW91dE1vZGVsLm1hcmdpbmxlZnQgKyB0aGlzLl9nZXRDYXB0aW9uUmVzZXJ2ZWRXKCkgKyB0aGlzLndpZGdldExheW91dE1vZGVsLmV4dGVudHcgKyB0aGlzLmxheW91dE1vZGVsLm1hcmdpbnJpZ2h0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoID0gdGhpcy5sYXlvdXRNb2RlbC5tYXJnaW50b3AgKyBNYXRoLm1heCh0aGlzLl9nZXRDYXB0aW9uUmVzZXJ2ZWRIKCksIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuZXh0ZW50aCkgKyB0aGlzLmxheW91dE1vZGVsLm1hcmdpbmJvdHRvbTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJ0b3AiOgogICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJib3R0b20iOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXlvdXRNb2RlbC5leHRlbnR3ID0gdGhpcy5sYXlvdXRNb2RlbC5tYXJnaW5sZWZ0ICsgTWF0aC5tYXgodGhpcy5fZ2V0Q2FwdGlvblJlc2VydmVkVygpLCB0aGlzLndpZGdldExheW91dE1vZGVsLmV4dGVudHcpICsgdGhpcy5sYXlvdXRNb2RlbC5tYXJnaW5yaWdodCAgICAgOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoICA9IHRoaXMubGF5b3V0TW9kZWwubWFyZ2ludG9wICsgdGhpcy5fZ2V0Q2FwdGlvblJlc2VydmVkSCgpICsgdGhpcy53aWRnZXRMYXlvdXRNb2RlbC5leHRlbnRoICsgdGhpcy5sYXlvdXRNb2RlbC5tYXJnaW5ib3R0b207CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc2l6ZWQ7CiAgICAgICAgfSwKCiAgICAgICAgLyoqCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogVG8gdXBkYXRlIGhlaWdodCBhbmQgd2lkdGggb2Ygd2lkZ2V0IG1vZGVsCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQgOiB0ZXh0IHRvIGJlIHVzZWQgdG8gY29tcHV0ZSBuZXcgaGVpZ2h0IGFuZCB3aWR0aAogICAgICAgICAqIHJldHVybiB0cnVlIGlmIGhlaWdodCBvciB3aWR0aCB1cGRhdGVkIGVsc2UgZmFsc2UKICAgICAgICAgKi8KICAgICAgICBfdXBkYXRlV2lkZ2V0TW9kZWwgOiBmdW5jdGlvbiAodGV4dCkgewogICAgICAgICAgICB2YXIgc3BhY2VBYm92ZSA9IDAsCiAgICAgICAgICAgICAgICBzcGFjZUJlbG93ID0gMCwKICAgICAgICAgICAgICAgIHBhcmEgPSB0aGlzLmdldE9yRWxzZSh0aGlzLCAibW9kZWwucGFyYSIsIG51bGwpLAogICAgICAgICAgICAgICAgcmVzaXplZCA9IGZhbHNlLAogICAgICAgICAgICAgICAgbWVhc3VyZU9wdGlvbnMgPSB0aGlzLl9nZXRNZWFzdXJlbWVudE9wdGlvbnMoKSwKICAgICAgICAgICAgICAgIG1lYXN1cmVkRXh0ZW50ID0geGZhbGliLnZpZXcudXRpbC5UZXh0TWV0cmljcy5tZWFzdXJlRXh0ZW50KHRleHQsIF8uY2xvbmUobWVhc3VyZU9wdGlvbnMpKSwKICAgICAgICAgICAgICAgIHdpZGdldE1vZGVsID0gdGhpcy53aWRnZXRMYXlvdXRNb2RlbCB8fCB0aGlzLmxheW91dE1vZGVsOwoKICAgICAgICAgICAgaWYocGFyYSkgewogICAgICAgICAgICAgICAgc3BhY2VBYm92ZSA9IHBhcmEuc3BhY2VBYm92ZTsKICAgICAgICAgICAgICAgIHNwYWNlQmVsb3cgPSBwYXJhLnNwYWNlQmVsb3c7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKG1lYXN1cmVPcHRpb25zLndpZHRoICE9IG1lYXN1cmVkRXh0ZW50LndpZHRoIHx8IG1lYXN1cmVPcHRpb25zLmhlaWdodCAhPSBtZWFzdXJlZEV4dGVudC5oZWlnaHQpIHsKICAgICAgICAgICAgICAgIHJlc2l6ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgaWYobWVhc3VyZU9wdGlvbnMud2lkdGggIT0gbWVhc3VyZWRFeHRlbnQud2lkdGgpIHsKICAgICAgICAgICAgICAgICAgICB3aWRnZXRNb2RlbC5leHRlbnR3ID0gd2lkZ2V0TW9kZWwubWFyZ2lubGVmdCArIG1lYXN1cmVkRXh0ZW50LndpZHRoICsgd2lkZ2V0TW9kZWwubWFyZ2lucmlnaHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZihtZWFzdXJlT3B0aW9ucy5oZWlnaHQgIT0gbWVhc3VyZWRFeHRlbnQuaGVpZ2h0KSB7CiAgICAgICAgICAgICAgICAgICAgd2lkZ2V0TW9kZWwuZXh0ZW50aCA9IHdpZGdldE1vZGVsLm1hcmdpbnRvcCArIG1lYXN1cmVkRXh0ZW50LmhlaWdodCArIHdpZGdldE1vZGVsLm1hcmdpbmJvdHRvbSArIHRoaXMuX2NvbnZlcnRUb1B4KHNwYWNlQWJvdmUpCiAgICAgICAgICAgICAgICAgICAgICAgICsgdGhpcy5fY29udmVydFRvUHgoc3BhY2VCZWxvdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc2l6ZWQKICAgICAgICB9LAoKICAgICAgICBfZ2V0Q2FwdGlvblJlc2VydmVkVzogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmKHRoaXMuY2FwdGlvbiAmJiB0aGlzLm1vZGVsLmNhcHRpb24pewogICAgICAgICAgICAgICAgc3dpdGNoKHRoaXMubW9kZWwuY2FwdGlvbi5nZXRBdHRyaWJ1dGUoInBsYWNlbWVudCIpKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAibGVmdCIgOgogICAgICAgICAgICAgICAgICAgIGNhc2UgInJpZ2h0IiA6CiAgICAgICAgICAgICAgICAgICAgICAgIC8vaW4gY2FzZSBsZWZ0IGFuZCByaWdodCwgInJlc2VydmUiIGRpY3RhdGVzIHRoZSB3aWR0aCBvZiB0aGUgY2FwdGlvbgogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzZXJ2ZSA9IHRoaXMubW9kZWwuY2FwdGlvbi5nZXRBdHRyaWJ1dGUoInJlc2VydmUiKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChyZXNlcnZlICE9ICItMSIgPyB0aGlzLl9jb252ZXJ0VG9QeChyZXNlcnZlKSA6IDApOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlICJ0b3AiIDoKICAgICAgICAgICAgICAgICAgICBjYXNlICJib3R0b20iIDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2FwdGlvbkxheW91dE1vZGVsLmV4dGVudHc7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0sCgogICAgICAgIF9nZXRDYXB0aW9uUmVzZXJ2ZWRIOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYodGhpcy5jYXB0aW9uICYmIHRoaXMubW9kZWwuY2FwdGlvbil7CiAgICAgICAgICAgICAgICBzd2l0Y2godGhpcy5tb2RlbC5jYXB0aW9uLmdldEF0dHJpYnV0ZSgicGxhY2VtZW50IikpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJsZWZ0IiA6CiAgICAgICAgICAgICAgICAgICAgY2FzZSAicmlnaHQiIDoKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2FwdGlvbkxheW91dE1vZGVsLmV4dGVudGg7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgInRvcCIgOgogICAgICAgICAgICAgICAgICAgIGNhc2UgImJvdHRvbSIgOgogICAgICAgICAgICAgICAgICAgICAgICAvL2luIGNhc2UgdG9wIGFuZCBib3R0b20sICJyZXNlcnZlIiBkaWN0YXRlcyB0aGUgaGVpZ2h0IG9mIHRoZSBjYXB0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNlcnZlID0gdGhpcy5tb2RlbC5jYXB0aW9uLmdldEF0dHJpYnV0ZSgicmVzZXJ2ZSIpOwogICAgICAgICAgICAgICAgICAgICAgICAvL0NRLTEwMjM0MSA6IExheW91dCBvZiBvbGRlciBmb3JtcyBnb3QgZGlzdHVyYmVzIHdoaWNoIGhhZCBubyByZXNlcnZlIHZhbHVlLiBTbyBpZiBubyByZXNlcnZlIGlzIGZvdW5kIHRoZSBvbGRlciB2YWx1ZSBpLmUgdGhpcy5jYXB0aW9uTGF5b3V0TW9kZWwuZXh0ZW50aCBpcyByZXR1cm5lZAogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHRoaXMuX2lzUmVzZXJ2ZVByZXNlbnQocmVzZXJ2ZSkgPyB0aGlzLl9jb252ZXJ0VG9QeChyZXNlcnZlKSA6IHRoaXMuY2FwdGlvbkxheW91dE1vZGVsLmV4dGVudGgpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9LAoKICAgICAgICBfaXNSZXNlcnZlUHJlc2VudDogZnVuY3Rpb24ocmVzZXJ2ZSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgcmV0dXJuICEocmVzZXJ2ZSA9PSAiLTEiIHx8IHBhcnNlRmxvYXQocmVzZXJ2ZS5yZXBsYWNlKC9bXi1cZFwuXS9nLCAnJykpID09IDApOwogICAgICAgICAgICB9IGNhdGNoKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci53YXJuKCJ4ZmEiLCJpc3N1ZSB3aXRoIHBhcnNlRmxvYXQgb2YgcmVzZXJ2ZSAsIHJlc2VydmUgdmFsdWUgOiIgKyByZXNlcnZlKTsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jYWxjdWxhdGVEaXNwbGF5IDogZnVuY3Rpb24oY2FwRXh0ZW50LHdFeHRlbnQpIHsKICAgICAgICAgICAgIHdFeHRlbnRbIndpZHRoIl0gPSB0aGlzLndpZGdldExheW91dE1vZGVsLmV4dGVudHcgKyB0aGlzLndpZGdldExheW91dE1vZGVsLmJvcmRlcmxlZnQvMiArIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuYm9yZGVycmlnaHQvMiA7CiAgICAgICAgICAgICB3RXh0ZW50WyJoZWlnaHQiXSA9IHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuZXh0ZW50aCArIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuYm9yZGVydG9wLzIgKyB0aGlzLndpZGdldExheW91dE1vZGVsLmJvcmRlcmJvdHRvbS8yIDsKICAgICAgICAgICAgIHN3aXRjaCh0aGlzLm1vZGVsLmNhcHRpb24ucGxhY2VtZW50KSB7CiAgICAgICAgICAgICAgIGNhc2UgImxlZnQiIDoKICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJsZWZ0Il0gPSB0aGlzLl9wYWRMZWZ0KCk7CiAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsidG9wIl0gPSB0aGlzLl9wYWRUb3AoKTsKICAgICAgICAgICAgICAgICAgd0V4dGVudFsibGVmdCJdID0gdGhpcy5fcGFkTGVmdCgpICsgdGhpcy5fZ2V0Q2FwdGlvblJlc2VydmVkVygpOwogICAgICAgICAgICAgICAgICB3RXh0ZW50WyJ0b3AiXSA9IHRoaXMuX3BhZFRvcCgpOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgY2FzZSAicmlnaHQiIDoKICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJyaWdodCJdID0gdGhpcy5fcGFkUmlnaHQoKTsKICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJ0b3AiXSA9IHRoaXMuX3BhZFRvcCgpOwogICAgICAgICAgICAgICAgICB3RXh0ZW50WyJyaWdodCJdID0gdGhpcy5fcGFkUmlnaHQoKSArIE1hdGgubWF4KHRoaXMuX2dldENhcHRpb25SZXNlcnZlZFcoKSwgY2FwRXh0ZW50WyJ3aWR0aCJdKTsKICAgICAgICAgICAgICAgICAgd0V4dGVudFsidG9wIl0gPSB0aGlzLl9wYWRUb3AoKTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgIGNhc2UgInRvcCIgOgogICAgICAgICAgICAgICAgICBjYXBFeHRlbnRbImxlZnQiXSA9IHRoaXMuX3BhZExlZnQoKTsKICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJ0b3AiXSA9IHRoaXMuX3BhZFRvcCgpOwogICAgICAgICAgICAgICAgICB3RXh0ZW50WyJsZWZ0Il0gPSB0aGlzLl9wYWRMZWZ0KCk7CiAgICAgICAgICAgICAgICAgIHdFeHRlbnRbInRvcCJdID0gdGhpcy5fcGFkVG9wKCkgKyB0aGlzLl9nZXRDYXB0aW9uUmVzZXJ2ZWRIKCk7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICBjYXNlICJib3R0b20iIDoKICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJsZWZ0Il0gPSB0aGlzLl9wYWRMZWZ0KCk7CiAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsiYm90dG9tIl0gPSB0aGlzLl9wYWRCb3R0b20oKTsKICAgICAgICAgICAgICAgICAgd0V4dGVudFsibGVmdCJdID0gdGhpcy5fcGFkTGVmdCgpOwogICAgICAgICAgICAgICAgICB3RXh0ZW50WyJib3R0b20iXSA9IHRoaXMuX3BhZEJvdHRvbSgpICArIHRoaXMuX2dldENhcHRpb25SZXNlcnZlZEgoKTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgfQogICAgICAgfSwKCiAgICAgICAgdXBkYXRlRGlzcGxheSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS51cGRhdGVEaXNwbGF5LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMuY2FwdGlvbiAmJiB0aGlzLndpZGdldCl7CiAgICAgICAgICAgICAgICB2YXIgcGFyZW50UGFkTGVmdCA9IHRoaXMuX3BhZExlZnQoKTsKICAgICAgICAgICAgICAgIHZhciBwYXJlbnRQYWRUb3AgPSB0aGlzLl9wYWRUb3AoKTsKICAgICAgICAgICAgICAgIHZhciBjYXBFeHRlbnQgPSB7fTsKICAgICAgICAgICAgICAgIHZhciB3RXh0ZW50ID0ge307CiAgICAgICAgICAgICAgICBjYXBFeHRlbnRbIndpZHRoIl0gPSB0aGlzLmNhcHRpb25MYXlvdXRNb2RlbC5leHRlbnR3ICsgdGhpcy5jYXB0aW9uTGF5b3V0TW9kZWwuYm9yZGVybGVmdC8yICsgdGhpcy5jYXB0aW9uTGF5b3V0TW9kZWwuYm9yZGVycmlnaHQvMiA7CiAgICAgICAgICAgICAgICBjYXBFeHRlbnRbImhlaWdodCJdID0gdGhpcy5jYXB0aW9uTGF5b3V0TW9kZWwuZXh0ZW50aCArIHRoaXMuY2FwdGlvbkxheW91dE1vZGVsLmJvcmRlcnRvcC8yICsgdGhpcy5jYXB0aW9uTGF5b3V0TW9kZWwuYm9yZGVyYm90dG9tLzIgOwogICAgICAgICAgICAgICAgdGhpcy5fY2FsY3VsYXRlRGlzcGxheShjYXBFeHRlbnQsd0V4dGVudCk7CiAgICAgICAgICAgICAgICB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigid2lkdGgiLHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuZXh0ZW50dyAtIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwubWFyZ2lubGVmdCAtIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwubWFyZ2lucmlnaHQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9wdGlvbigiaGVpZ2h0Iix0aGlzLndpZGdldExheW91dE1vZGVsLmV4dGVudGggLSB0aGlzLndpZGdldExheW91dE1vZGVsLm1hcmdpbmJvdHRvbSAtIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwubWFyZ2ludG9wKQogICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuY2FwdGlvbiwgY2FwRXh0ZW50KTsKICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLndpZGdldCwgd0V4dGVudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigid2lkdGgiLHRoaXMubGF5b3V0TW9kZWwuZXh0ZW50dyAtIHRoaXMubGF5b3V0TW9kZWwubWFyZ2lubGVmdCAtIHRoaXMubGF5b3V0TW9kZWwubWFyZ2lucmlnaHQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9wdGlvbigiaGVpZ2h0Iix0aGlzLmxheW91dE1vZGVsLmV4dGVudGggLSB0aGlzLmxheW91dE1vZGVsLm1hcmdpbmJvdHRvbSAtIHRoaXMubGF5b3V0TW9kZWwubWFyZ2ludG9wKQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgdXBkYXRlVGFiSW5kZXggOiBmdW5jdGlvbihuZXdUYWJJbmRleCl7CiAgICAgICAgICAgIHRoaXMuanFXaWRnZXQub3B0aW9uKCJ0YWJJbmRleCIsIG5ld1RhYkluZGV4KTsKICAgICAgICB9LAoKICAgICAgICAvLyBDUS0xMDI0NzIgOiBPdmVycmlkaW5nIEJhc2VWaWV3IF9oYW5kbGVCb3JkZXJDaGFuZ2UsIGFzIGluIGNhc2Ugb2YgZmllbGQgd2l0aCBubyBjYXB0aW9uLCBmaWVsZCBib3JkZXIgY29sb3IgZ2V0cyBhc3NpZ25lZCB0byB3aWRnZXQgYm9yZGVyIGFzIG5vIGNhcHRpb24gYW5kIGZpZWxkIGRpdnMgYXJlIHByZXNlbnQKICAgICAgICBfaGFuZGxlQm9yZGVyQ2hhbmdlIDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgaWYgKHRoaXMuY2FwdGlvbiB8fCB0aGlzLm1vZGVsLmJvcmRlci5lZGdlLmdldEF0dHJpYnV0ZSgidGhpY2tuZXNzIiwgZmFsc2UpKSB7CiAgICAgICAgICAgICAgICB2YXIgY3NzU3R5bGVPYmogPSB4ZmFsaWIudmlldy51dGlsLlN0eWxlcy5nZXRTdHlsZUZvckJvcmRlcih0aGlzLm1vZGVsLmJvcmRlcik7CiAgICAgICAgICAgICAgICBpZihjc3NTdHlsZU9iaikgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLmVsLCBjc3NTdHlsZU9iaik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sICQsIHhmYWxpYik7CgooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LkNoZWNrQnV0dG9uRmllbGRWaWV3ID0geGZhbGliLnZpZXcuRmllbGRWaWV3LmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbiA6ICBmdW5jdGlvbihvcHRpb25zKXsKICAgICAgICAgICAgaWYodGhpcy5tb2RlbCl7CiAgICAgICAgICAgICAgICBvcHRpb25zLnNpemUgPSAgdGhpcy5tb2RlbC51aS5vbmVPZkNoaWxkLnNpemU7CiAgICAgICAgICAgICAgICBvcHRpb25zLnN0YXRlID0gdGhpcy5tb2RlbC5zZWxlY3RlZEluZGV4OwogICAgICAgICAgICAgICAgb3B0aW9ucy5zdGF0ZXMgPSB0aGlzLm1vZGVsLnVpLm9uZU9mQ2hpbGQuYWxsb3dOZXV0cmFsID09ICIxIiA/IDM6MjsgIC8vICNidWc9MzY1MDkyMCwgdHlwZW9mIGFsbG93TmV1dHJhbCBpcyBzdHJpbmcKICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLlhmYUNoZWNrQm94KG9wdGlvbnMpOwogICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtWGZhQ2hlY2tCb3giKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbi5hcHBseSh0aGlzLCBbb3B0aW9uc10pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAvL05vdGU6IFRoZSBzY3JlZW5yZWFkZXIgdGV4dCBmb3IgZXhjbHVzaW9uIGdyb3VwIHNob3VsZCBub3QgYmVoYXZlIGRpZmZlcmVudGx5LCBhbmQgc2hvdWxkIGJlIGFsaWduZWQgdG8gUERGLgogICAgICAgIC8vUmVmZXJlbmNlOiBDUS04MTg3NSAoQUVNIEZvcm1zIHNob3cgcmFkaW8gYnV0dG9uIG5hbWUgaW5jbHVkZWQgd2l0aCB0b29sdGlwKQogICAgICAgIF9nZXRTY3JlZW5SZWFkZXJUZXh0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdmFyIHNjcmVlblJlYWRlclRleHQgPSAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fZ2V0U2NyZWVuUmVhZGVyVGV4dC5hcHBseSh0aGlzKSwKICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHRQYXJlbnQ7CiAgICAgICAgICAgIGlmKHRoaXMubW9kZWwucGFyZW50ICYmIHRoaXMubW9kZWwucGFyZW50Ll9pc0V4Y2x1c2lvbkdyb3VwKCkpIHsKICAgICAgICAgICAgICAgIHNjcmVlblJlYWRlclRleHRQYXJlbnQgPSB0aGlzLnBhcmVudFZpZXcuX2dldFNjcmVlblJlYWRlclRleHQoKTsKICAgICAgICAgICAgICAgIGlmKHNjcmVlblJlYWRlclRleHRQYXJlbnQpIHsKICAgICAgICAgICAgICAgICAgICBzY3JlZW5SZWFkZXJUZXh0UGFyZW50ID0gc2NyZWVuUmVhZGVyVGV4dFBhcmVudCArICIgIiA7CiAgICAgICAgICAgICAgICAgICAgaWYoc2NyZWVuUmVhZGVyVGV4dCkgewogICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW5SZWFkZXJUZXh0PSBzY3JlZW5SZWFkZXJUZXh0UGFyZW50ICArICAgc2NyZWVuUmVhZGVyVGV4dDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzY3JlZW5SZWFkZXJUZXh0ID0gc2NyZWVuUmVhZGVyVGV4dFBhcmVudDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAgc2NyZWVuUmVhZGVyVGV4dCA7CgogICAgICAgIH0sCiAgICAgICAgKi8KICAgICAgICBfaGFuZGxlTW91c2VEb3duOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICBpZih4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1cyA9PSB0aGlzKSB7CiAgICAgICAgICAgICAgICB0aGlzLmNsaWNrZWRPbkNhcHRpb24gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgY3JlYXRlQm9yZGVyRm9yV2lkZ2V0IDogZnVuY3Rpb24oKXsKICAgICAgICB9LAoKICAgICAgICBoYW5kbGVDaGFuZ2VFdmVudCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmKHRoaXMubW9kZWwucGFyZW50LmNsYXNzTmFtZSA9PSAiZXhjbEdyb3VwIikgewogICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5wYXJlbnQuZXhlY0V2ZW50KCJjaGFuZ2UiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLm1vZGVsLmV4ZWNFdmVudCgiY2hhbmdlIik7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlQ2xpY2tFdmVudCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICBpZih0aGlzLm1vZGVsLnBhcmVudC5jbGFzc05hbWUgPT0gImV4Y2xHcm91cCIpIHsKICAgICAgICAgICAgICAgIHRoaXMubW9kZWwucGFyZW50LmV4ZWNFdmVudCgiY2xpY2siKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLm1vZGVsLmV4ZWNFdmVudCgiY2xpY2siKTsKICAgICAgICB9LAoKICAgICAgICBoYW5kbGVEb21DaGFuZ2VkIDpmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgIHN3aXRjaChldmVudC5fcHJvcGVydHkpIHsKICAgICAgICAgICAgICAgIGNhc2UgImFsbG93TmV1dHJhbCI6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQWxsb3dOZXV0cmFsKGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5oYW5kbGVEb21DaGFuZ2VkLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICAgX2NhbGN1bGF0ZURpc3BsYXkgOiBmdW5jdGlvbihjYXBFeHRlbnQsd0V4dGVudCkgewogICAgICAgICAgICAgICB2YXIgc2l6ZSA9IHRoaXMuX2dldFdpZGdldFJlc2VydmVkKCk7ICAvLy0tIHdlIGFyZSBjaGFuZ2luZyB0aGUgY2FsY3VsYXRpb25zIGZyb20gY2FwdGlvbi1jZW50cmljIHRvIGEgd2lkZ2V0IGNlbnRyaWMKICAgICAgICAgICAgICAgdGhpcy53aWRnZXRMYXlvdXRNb2RlbC5leHRlbnR3ID0gdGhpcy53aWRnZXRMYXlvdXRNb2RlbC5leHRlbnRoID0gc2l6ZTsKICAgICAgICAgICAgICAgdmFyIHBhcmVudEV4dGVudCA9IHt9OwogICAgICAgICAgICAgICB2YXIgcGFyYUZpZWxkID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCJwYXJhIikKICAgICAgICAgICAgICAgaWYocGFyYUZpZWxkKQogICAgICAgICAgICAgICAgIHZhciB2QWxpZ25XaWRnZXQgPSBwYXJhRmllbGQuZ2V0QXR0cmlidXRlKCJ2QWxpZ24iKTsKICAgICAgICAgICAgICAgcGFyZW50RXh0ZW50WyJ3aWR0aCJdID0gdGhpcy5sYXlvdXRNb2RlbC5leHRlbnR3ICsgdGhpcy5sYXlvdXRNb2RlbC5ib3JkZXJsZWZ0LzIgKyB0aGlzLmxheW91dE1vZGVsLmJvcmRlcnJpZ2h0LzIgOwogICAgICAgICAgICAgICBwYXJlbnRFeHRlbnRbImhlaWdodCJdID0gdGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoICsgdGhpcy5sYXlvdXRNb2RlbC5ib3JkZXJ0b3AvMiArIHRoaXMubGF5b3V0TW9kZWwuYm9yZGVyYm90dG9tLzIgOwogICAgICAgICAgICAgICB3RXh0ZW50WyJ3aWR0aCJdID0gdGhpcy53aWRnZXRMYXlvdXRNb2RlbC5leHRlbnR3ICsgdGhpcy53aWRnZXRMYXlvdXRNb2RlbC5ib3JkZXJsZWZ0LzIgKyB0aGlzLndpZGdldExheW91dE1vZGVsLmJvcmRlcnJpZ2h0LzIgOwogICAgICAgICAgICAgICB3RXh0ZW50WyJoZWlnaHQiXSA9IHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuZXh0ZW50aCArIHRoaXMud2lkZ2V0TGF5b3V0TW9kZWwuYm9yZGVydG9wLzIgKyB0aGlzLndpZGdldExheW91dE1vZGVsLmJvcmRlcmJvdHRvbS8yIDsKICAgICAgICAgICAgICAgdmFyIHRvcEJvdHRvbVBhZGRpbmcgPSAodGhpcy5sYXlvdXRNb2RlbC5leHRlbnRoLSh0aGlzLndpZGdldExheW91dE1vZGVsLmV4dGVudGggKyB0aGlzLmNhcHRpb25MYXlvdXRNb2RlbC5leHRlbnRoKSkvMjsKCiAgICAgICAgICAgICAgIHN3aXRjaCh2QWxpZ25XaWRnZXQpIHsgLy8gc2V0dGluZyB0aGUgdkFsaWduIG9mIHRoZSB3aWRnZXQgZXF1YWwgdG8gaXRzIHBhcmVudC4gKGkuZSBmaWVsZCkKICAgICAgICAgICAgICAgICBjYXNlICJib3R0b20iOgogICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJib3R0b20iXT0gdGhpcy5fcGFkQm90dG9tKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICBjYXNlICJtaWRkbGUiOgogICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJ0b3AiXSA9ICh0aGlzLmxheW91dE1vZGVsLmV4dGVudGgtc2l6ZSkvMjsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIGNhc2UgInRvcCI6CiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHdFeHRlbnRbInRvcCJdPSB0aGlzLl9wYWRUb3AoKTsKICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgc3dpdGNoKHRoaXMubW9kZWwuY2FwdGlvbi5wbGFjZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlICJyaWdodCIgOgogICAgICAgICAgICAgICAgICAgICAgICBjYXBFeHRlbnRbImxlZnQiXSA9IHRoaXMuX3BhZExlZnQoKSArIHNpemU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsidG9wIl0gPSB0aGlzLl9wYWRUb3AoKTsKICAgICAgICAgICAgICAgICAgICAgICAgd0V4dGVudFsibGVmdCJdID0gdGhpcy5fcGFkTGVmdCgpCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgImxlZnQiIDoKICAgICAgICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJyaWdodCJdID0gdGhpcy5fcGFkUmlnaHQoKSArIHNpemU7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsidG9wIl0gPSB0aGlzLl9wYWRUb3AoKTsKICAgICAgICAgICAgICAgICAgICAgICAgd0V4dGVudFsicmlnaHQiXSA9IHRoaXMuX3BhZFJpZ2h0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgImJvdHRvbSIgOgogICAgICAgICAgICAgICAgICAgICAgICBjYXBFeHRlbnRbImxlZnQiXSA9IHRoaXMuX3BhZExlZnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJ0b3AiXSA9IHRoaXMuX3BhZFRvcCgpKyBzaXplICsgdG9wQm90dG9tUGFkZGluZzsKICAgICAgICAgICAgICAgICAgICAgICAgd0V4dGVudFsibGVmdCJdID0gdGhpcy5fcGFkTGVmdCgpOwogICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJib3R0b20iXT0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJ0b3AiXSA9IHRoaXMuX3BhZFRvcCgpICsgdG9wQm90dG9tUGFkZGluZyA7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgInRvcCIgOgogICAgICAgICAgICAgICAgICAgICAgICBjYXBFeHRlbnRbImxlZnQiXSA9IHRoaXMuX3BhZExlZnQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJib3R0b20iXSA9dGhpcy5fcGFkQm90dG9tKCkrIHNpemUgKyB0b3BCb3R0b21QYWRkaW5nOwogICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJ0b3AiXT0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJsZWZ0Il0gPSB0aGlzLl9wYWRMZWZ0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHdFeHRlbnRbImJvdHRvbSJdID0gdGhpcy5fcGFkQm90dG9tKCkrIHRvcEJvdHRvbVBhZGRpbmc7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgIHZhciBsYW5nID0gdGhpcy5fbGFuZ0Zyb21Mb2NhbGUodGhpcy5tb2RlbC5fZ2V0TG9jYWxlKCkpOwogICAgICAgICAgICAgICB2YXIgZGlyZWN0aW9uID0gImx0ciIKICAgICAgICAgICAgICAgaWYobGFuZyAmJiB0aGlzLl9ydGxMYW5nW2xhbmddKXsKICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAicnRsIjsKICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICBpZihjYXBFeHRlbnRbIndpZHRoIl08KHBhcmVudEV4dGVudFsid2lkdGgiXSAtIHdFeHRlbnRbIndpZHRoIl0pKSB7CiAgICAgICAgICAgICAgICAgICBzd2l0Y2godGhpcy5tb2RlbC5jYXB0aW9uLnBsYWNlbWVudCkgewogICAgICAgICAgICAgICAgICAgICAgIGNhc2UgInJpZ2h0IiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsibGVmdCJdID0gIHBhcmVudEV4dGVudFsid2lkdGgiXS1jYXBFeHRlbnRbIndpZHRoIl0gOwogICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJsZWZ0IiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsicmlnaHQiXSA9IHVuZGVmaW5lZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJsZWZ0Il0gPSB0aGlzLl9wYWRMZWZ0KCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgIHdFeHRlbnRbInJpZ2h0Il0gPSBkaXJlY3Rpb24gPT09ICJydGwiID8gMCA6IHVuZGVmaW5lZAogICAgICAgICAgICAgICAgICAgICAgICAgICB3RXh0ZW50WyJsZWZ0Il0gPSBkaXJlY3Rpb24gPT09ICJydGwiID8gdW5kZWZpbmVkIDogdGhpcy5fcGFkTGVmdCgpK2NhcEV4dGVudFsid2lkdGgiXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgaWYoY2FwRXh0ZW50WyJoZWlnaHQiXTwocGFyZW50RXh0ZW50WyJoZWlnaHQiXSAtIHdFeHRlbnRbImhlaWdodCJdKSkgewogICAgICAgICAgICAgICAgICAgc3dpdGNoKHRoaXMubW9kZWwuY2FwdGlvbi5wbGFjZW1lbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJib3R0b20iIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwRXh0ZW50WyJ0b3AiXSA9IHBhcmVudEV4dGVudFsiaGVpZ2h0Il0tY2FwRXh0ZW50WyJoZWlnaHQiXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAidG9wIiA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcEV4dGVudFsiYm90dG9tIl0gPSBwYXJlbnRFeHRlbnRbImhlaWdodCJdLWNhcEV4dGVudFsiaGVpZ2h0Il07CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICB9CgogICAgICAgICB9LAoKCiAgICAgICAgX2dldFdpZGdldFJlc2VydmVkOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgaWYodGhpcy53aWRnZXQgKXsKICAgICAgICAgICAgICAgICB2YXIgc2l6ZSA9IHRoaXMubW9kZWwudWkub25lT2ZDaGlsZC5nZXRBdHRyaWJ1dGUoInNpemUiKTsKICAgICAgICAgICAgICAgICByZXR1cm4gKHNpemUgIT0gIi0xIiA/IHRoaXMuX2NvbnZlcnRUb1B4KHNpemUpIDogMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlQWxsb3dOZXV0cmFsIDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgaWYoZXZlbnQucHJldlRleHQpIHsKICAgICAgICAgICAgICAgIGlmKGV2ZW50LnByZXZUZXh0ID09ICIwIiAmJiB0aGlzLm1vZGVsLmdldEl0ZW1TdGF0ZSgyKSkgeyAgLy8gaWYgYnV0dG9uIHdhcyBpbiBuZXV0cmFsLAogICAgICAgICAgICAgICAgICAgIHRoaXMubW9kZWwuc2V0SXRlbVN0YXRlKDEsIHRydWUpOyAgIC8vIHNldCBpdCB0byBvZmYsIHdoaWxlIGRpc2FibGluZyBhbGxvd05ldXRyYWwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQub3B0aW9uKCJhbGxvd05ldXRyYWwiLCBldmVudC5wcmV2VGV4dCk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlUGx1Z2luT3B0aW9ucyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICB2YXIgdk9wdGlvbnMgPSB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9jcmVhdGVQbHVnaW5PcHRpb25zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMubW9kZWwpIHsKICAgICAgICAgICAgICAgIC8vVE9ETzogdXNlZCBfZ2V0RGlzcGxheUl0ZW1zLiBJbnRlcm5hbCBBUEkKICAgICAgICAgICAgICAgIHZhciB2SXRlbXMgPSBfLm1hcCgKICAgICAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLl9nZXREaXNwbGF5SXRlbXMoKSA/IHRoaXMubW9kZWwuX2dldERpc3BsYXlJdGVtcygpLm1vQ2hpbGROb2RlczogW10sCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oaXRlbSwgaW5kZXgpewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlbS52YWx1ZTsKICAgICAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgICAgIHZPcHRpb25zLnZhbHVlcyA9IHZJdGVtczsKCiAgICAgICAgICAgICAgICBpZih0aGlzLm1vZGVsLnBhcmVudCAmJiB0aGlzLm1vZGVsLnBhcmVudC5faXNFeGNsdXNpb25Hcm91cCgpKSB7CiAgICAgICAgICAgICAgICAgICAgLy9wdXNoIGF0bGVhc3Qgb25lIG9mIHRoZXNlCiAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMubmFtZSA9IHRoaXMubW9kZWwucGFyZW50Lm5hbWUrIiIrdGhpcy5wYXJlbnRWaWV3Ll9pZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdk9wdGlvbnM7CiAgICAgICAgfQogICAgfSk7CgogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHhmYWxpYi52aWV3LkNoZWNrQnV0dG9uRmllbGRWaWV3LnByb3RvdHlwZSwgInJlc2l6YWJsZSIsIHsKICAgICAgICBnZXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgc2V0IDogZnVuY3Rpb24oc1ZhbHVlKXsKICAgICAgICAgICAgLy9EbyBOb3RoaW5nCiAgICAgICAgfQogICAgfSk7Cgp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LlRleHRGaWVsZFZpZXcgPSB4ZmFsaWIudmlldy5GaWVsZFZpZXcuZXh0ZW5kKHsKICAgICAgICBfY3JlYXRlUGx1Z2luT3B0aW9ucyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgdk9wdGlvbnMgPSB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9jcmVhdGVQbHVnaW5PcHRpb25zLmFwcGx5KHRoaXMsCiAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzKTsKICAgICAgICAgICAgdk9wdGlvbnMubXVsdGlMaW5lID0gZmFsc2U7CiAgICAgICAgICAgIGlmICh0aGlzLm1vZGVsKSB7CiAgICAgICAgICAgICAgICB2YXIgdWkgPSB0aGlzLm1vZGVsLmdldEVsZW1lbnQoJ3VpJywgMCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICB2YXIgdWlDaGlsZDsKCiAgICAgICAgICAgICAgICBpZih1aSkgewogICAgICAgICAgICAgICAgICAgIHVpQ2hpbGQgPSB1aS5vbmVPZkNoaWxkOwogICAgICAgICAgICAgICAgICAgIGlmKHVpQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMubXVsdGlMaW5lID0gdWlDaGlsZC5nZXRBdHRyaWJ1dGUoIm11bHRpTGluZSIpID09IDAgPyBmYWxzZSA6IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMubW9kZWwuZ2V0RWxlbWVudCgidmFsdWUiLCAwLCB0cnVlKTsKICAgICAgICAgICAgICAgIGlmKHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlQ2hpbGQgPSB2YWx1ZS5vbmVPZkNoaWxkOwogICAgICAgICAgICAgICAgICAgIGlmKHZhbHVlQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1heENoYXJzID0gdmFsdWVDaGlsZC5nZXRBdHRyaWJ1dGUoIm1heENoYXJzIik7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vbm90ZSA6IG1heENoYXJzLyBudW1iZXJPZkNlbGxzIGFzIHplcm8gc2hvdWxkIGJlIHRyZWF0ZWQgYXMgdW5kZWZpbmVkL25vIHJlc3RyaWN0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgIHZPcHRpb25zLm1heENoYXJzID0gdGhpcy5nZXRPckVsc2UobWF4Q2hhcnMsIHVuZGVmaW5lZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmKHZhbHVlQ2hpbGQuY2xhc3NOYW1lID09PSAiZXhEYXRhIiAmJiB2YWx1ZUNoaWxkLmpzb25Nb2RlbC5fdmFsdWUgIT09IG51bGwgJiYgdmFsdWVDaGlsZC5qc29uTW9kZWwuX3ZhbHVlLmluZGV4T2YoIjxib2R5IHhtbG5zPSIpID09PSAtMSl7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlQ2hpbGQuX3RyYW5zZm9ybVRvWEZBQ29tcGxpYW50TW9kZWwoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMudmFsdWUgPSB2YWx1ZUNoaWxkLmpzb25Nb2RlbC5fdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmKCF2T3B0aW9ucy5tYXhDaGFycyl7CiAgICAgICAgICAgICAgICAgICAgLy9ub3RlIDogbnVtYmVyT2ZDZWxscyBhcyB6ZXJvIHNob3VsZCBiZSB0cmVhdGVkIGFzIHVuZGVmaW5lZC9ubyByZXN0cmljdGlvbgogICAgICAgICAgICAgICAgICAgIGlmKHVpQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbWIgPSB1aUNoaWxkLmdldEVsZW1lbnQoImNvbWIiLCAwLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoY29tYikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMubWF4Q2hhcnMgPSBjb21iLmdldEF0dHJpYnV0ZSgnbnVtYmVyT2ZDZWxscycpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCF2T3B0aW9ucy5mb250U2l6ZSkgewogICAgICAgICAgICAgICAgICAgIHZhciBmb250ID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCJmb250IiwgMCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGZvbnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMuZm9udFNpemUgPSB0aGlzLl9jb252ZXJ0VG9QeChmb250LnNpemUpOwogICAgICAgICAgICAgICAgICAgICAgICB2T3B0aW9ucy5mb250RmFtaWx5ID0gZm9udC50eXBlZmFjZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZPcHRpb25zOwogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luIDogZnVuY3Rpb24ob3B0aW9ucykgewogICAgICAgICAgICBpZih0aGlzLl9yaWNoVGV4dFN1cHBvcnQoKSl7CiAgICAgICAgICAgICAgICAkKHRoaXMud2lkZ2V0KS5yaWNoVGV4dEZpZWxkKG9wdGlvbnMpOwogICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtcmljaFRleHRGaWVsZCIpOwogICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLnRleHRGaWVsZChvcHRpb25zKTsKICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQgPSB0aGlzLiRkYXRhKHRoaXMud2lkZ2V0LCAieGZhV2lkZ2V0LXRleHRGaWVsZCIpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX3JpY2hUZXh0U3VwcG9ydDogZnVuY3Rpb24oKXsKICAgICAgICAgICByZXR1cm4odGhpcy5nZXRPckVsc2UodGhpcy5tb2RlbCwgInZhbHVlLm9uZU9mQ2hpbGQuY2xhc3NOYW1lIiwgbnVsbCkgPT09ICJleERhdGEiPyB0cnVlOmZhbHNlKTsKICAgICAgICB9LAoKICAgICAgICBjcmVhdGVXaWRnZXRQbHVnaW4gOiBmdW5jdGlvbihvcHRpb25zKSB7CiAgICAgICAgICAgIC8vY20tdXNlY2FzZTogYWRkaW5nIGNsYXNzIHRvIGVuYWJsZSByaWNoIHRleHQgd2lkZ2V0IHJlZ2lzdHJhdGlvbiBhZ2FpbnN0IHRoZSBjbGFzcwogICAgICAgICAgICBpZih0aGlzLl9yaWNoVGV4dFN1cHBvcnQoKSkgewogICAgICAgICAgICAgICAgdGhpcy4kZWwuYWRkQ2xhc3MoJ3JpY2h0ZXh0c3VwcG9ydCcpOwogICAgICAgIH0KICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5jcmVhdGVXaWRnZXRQbHVnaW4uY2FsbCh0aGlzLAogICAgICAgICAgICAgICAgb3B0aW9ucyk7CiAgICAgICAgfSwKCgogICAgICAgIF9nZXRNZWFzdXJlbWVudE9wdGlvbnMgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICB2YXIgbWVhc3VyZU9wdGlvbnMgPSB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9nZXRNZWFzdXJlbWVudE9wdGlvbnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAvLyBhZGRpbmcgdGhpcyBvcHRpb24gdG8gY2hlY2sgZm9yIGZpZWxkcyByZXF1aXJpbmcgcmljaCB0ZXh0IHN1cHBvcnQuCiAgICAgICAgICAgbWVhc3VyZU9wdGlvbnMuY29udGVudFR5cGUgPSB0aGlzLl9yaWNoVGV4dFN1cHBvcnQoKSA/ICJ0ZXh0L2h0bWwiOiJ0ZXh0L3BsYWluIjsKICAgICAgICAgICBtZWFzdXJlT3B0aW9ucy5za2lwWFNTUHJvdGVjdGlvbiA9ICQodGhpcy53aWRnZXQpLmRhdGEoJ3NraXBYU1NQcm90ZWN0aW9uJyk7CiAgICAgICAgICAgcmV0dXJuIG1lYXN1cmVPcHRpb25zOwogICAgICAgIH0sCgogICAgICAgIF9nZXRQYXJhU3R5bGVzIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIHBhcmFTdHlsZXMgPSB7fSxwYXJhOwogICAgICAgICAgICBwYXJhID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCJwYXJhIiwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIGlmKHBhcmEpewogICAgICAgICAgICAgICAgcGFyYVN0eWxlcyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX2dldFBhcmFTdHlsZXMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgIHBhcmFTdHlsZXNbJ2xpbmUtaGVpZ2h0J109IHBhcnNlRmxvYXQocGFyYS5saW5lSGVpZ2h0KT4wPyB0aGlzLl9jb252ZXJ0VG9QeChwYXJhLmxpbmVIZWlnaHQpKyJweCI6Im5vcm1hbCI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHBhcmFTdHlsZXM7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LkRhdGVUaW1lRmllbGRWaWV3ID0geGZhbGliLnZpZXcuRmllbGRWaWV3LmV4dGVuZCh7CgogICAgICAgIF9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luIDogZnVuY3Rpb24ob3B0aW9ucykgewogICAgICAgICAgICBpZiAodGhpcy5tb2RlbCAvKiYmIHhmYS5ob3N0LnBsYXRmb3JtICE9PSAiaVBhZCIqLykgewogICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkuZGF0ZVRpbWVFZGl0KG9wdGlvbnMpOwogICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtZGF0ZVRpbWVFZGl0Iik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luLmFwcGx5KHRoaXMsW29wdGlvbnNdKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVQbHVnaW5PcHRpb25zIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgdmFyIHZPcHRpb25zID0geGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fY3JlYXRlUGx1Z2luT3B0aW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICBpZih0aGlzLm1vZGVsKSB7CiAgICAgICAgICAgICAgICB2YXIgbG9jYWxlID0gdGhpcy5tb2RlbC5sb2NhbGU7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy5kYXlzID0gdGhpcy5tb2RlbC5feGZhKCkuX2dldExvY2FsZVN5bWJvbHMobG9jYWxlLCJjYWxlbmRhclN5bWJvbHMuYWJicmRheU5hbWVzIik7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy5tb250aHMgPSB0aGlzLm1vZGVsLl94ZmEoKS5fZ2V0TG9jYWxlU3ltYm9scyhsb2NhbGUsImNhbGVuZGFyU3ltYm9scy5tb250aE5hbWVzIik7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy56ZXJvID0gdGhpcy5tb2RlbC5feGZhKCkuX2dldExvY2FsZVN5bWJvbHMobG9jYWxlLCJudW1iZXJTeW1ib2xzLnplcm8iKTsKICAgICAgICAgICAgICAgIHZPcHRpb25zLmNsZWFyVGV4dCA9IHhmYWxpYi5sb2NhbGUuU3RyaW5ncy5jbGVhclRleHQ7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy4kY2xpY2thYmxlID0gdGhpcy4kZWw7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy51c2VOYXRpdmVXaWRnZXQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIHZhciBiZWhhdmlvckNvbmZpZyA9IG5ldyB4ZmFsaWIudXQuVmVyc2lvbihmb3JtQnJpZGdlLnVzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl0pOwogICAgICAgICAgICAgICAgdk9wdGlvbnMuc2hvd0NhbGVuZGFySWNvbiA9ICFiZWhhdmlvckNvbmZpZy5pc09uKCdtZkRpc2FibGVDYWxlbmRhckljb24nKTsKICAgICAgICAgICAgICAgIHZPcHRpb25zLmNhbGVuZGFySWNvbldpZHRoID0gXy5taW4oW3hmYWxpYi50ZW1wbGF0ZS5Db25zdGFudHMuY2FsZW5kYXJJY29uTWF4V2lkdGgsIE1hdGguZmxvb3Iodk9wdGlvbnMuaGVpZ2h0KV0pIC0gMjsKCiAgICAgICAgICAgICAgICB2YXIgZWRpdFBhdHRlcm4gPSB0aGlzLmdldE9yRWxzZSh0aGlzLm1vZGVsLCAidWkucGljdHVyZS52YWx1ZSIsIG51bGwpOwogICAgICAgICAgICAgICAgaWYgKGVkaXRQYXR0ZXJuKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcnNlZFBhdHRlcm4gPSB4ZmFsaWIudXQuUGljdHVyZVV0aWxzLnBhcnNlUGljdHVyZUNsYXVzZShlZGl0UGF0dGVybik7CiAgICAgICAgICAgICAgICAgICAgaWYgKF8uaXNFbXB0eShwYXJzZWRQYXR0ZXJuKSB8fCBfLmlzQXJyYXkocGFyc2VkUGF0dGVybikgJiYgcGFyc2VkUGF0dGVybi5sZW5ndGggPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVkaXRQYXR0ZXJuID0gbnVsbDsgLy8gZm9yIG5vdyBmYWxsIGJhY2sgdG8gZGVmYXVsdCBwYXR0ZXJucyBpbiBjYXNlIG9mIHVuc3VwcG9ydGVkIC8gbXVsdGlwbGUgcGF0dGVybnMKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETyA6IG1ha2UgYSBhcnJheSBvZiB0aGUgcGFyc2VkIG9iamVjdHMgYW5kIGl0ZXIgb3ZlciB0aGVtIGluIGFic3RyYWN0IHdpZGdldCA6IHBhcnNlRWRpdFZhbHVlCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZPcHRpb25zLmVkaXRQYXR0ZXJuID0gZWRpdFBhdHRlcm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZPcHRpb25zOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUNoYW5nZUV2ZW50OiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICAvL1RPRE86IHBhc3Mgb24gdGhlIGNvcnJlY3QgZGF0YQogICAgICAgICAgICB2YXIgZGV0YWlsID0gewogICAgICAgICAgICAgICAgbmV3VGV4dDpudWxsLAogICAgICAgICAgICAgICAga2V5Y29kZTpudWxsLAogICAgICAgICAgICAgICAgbW9kaWZpZXI6bnVsbCwKICAgICAgICAgICAgICAgIGtleURvd246ZmFsc2UsCiAgICAgICAgICAgICAgICBzaGlmdDpmYWxzZSwKICAgICAgICAgICAgICAgIGNoYW5nZTogbnVsbAogICAgICAgICAgICB9OwogICAgICAgICAgICB0aGlzLm1vZGVsLmV4ZWNFdmVudCgiY2hhbmdlIiwgZGV0YWlsKTsKICAgICAgICB9CiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy5JbWFnZUZpZWxkVmlldyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5leHRlbmQoewoKICAgICAgICBfY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbiA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgJCh0aGlzLndpZGdldCkuaW1hZ2VGaWVsZChvcHRpb25zKTsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtaW1hZ2VGaWVsZCIpOwogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVQbHVnaW5PcHRpb25zIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB2T3B0aW9ucyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX2NyZWF0ZVBsdWdpbk9wdGlvbnMuYXBwbHkoCiAgICAgICAgICAgICAgICAgICAgdGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgdmFyIGltYWdlT2JqID0gdGhpcy5nZXRPckVsc2UodGhpcywgIm1vZGVsLnZhbHVlLmltYWdlIiwgbnVsbCk7CiAgICAgICAgICAgIGlmIChpbWFnZU9iaikgewogICAgICAgICAgICAgICAgdk9wdGlvbnMuYXNwZWN0ID0gaW1hZ2VPYmouZ2V0QXR0cmlidXRlKCJhc3BlY3QiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdk9wdGlvbnM7CiAgICAgICAgfSwKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICB9LAoKICAgICAgICBoYW5kbGVDaGFuZ2VFdmVudCA6IGZ1bmN0aW9uKGNoYW5nZUV2ZW50KSB7CiAgICAgICAgICAgdGhpcy5tb2RlbC5leGVjRXZlbnQoImNoYW5nZSIpOwogICAgICAgICAgIC8vIE5QUi0xNTI4NiA6IHRvIHRyaWdnZXIgZXZlbnQgb24gZm9ybWJyaWRnZSB3aGVuZXZlciB0aGUgdmFsdWUgb2Ygc2NyaWJibGUgY2hhbmdlcy4KICAgICAgICAgICBpZiAodGhpcy5fZ2V0V2lkZ2V0TmFtZUZyb21VaUV4dHJhKCkgPT0geGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5TY3JpYmJsZUltYWdlRmllbGQpIHsKICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLl90cmlnZ2VyT25CcmlkZ2UoeGZhbGliLnRlbXBsYXRlLkNvbnN0YW50cy5zY3JpYmJsZUNoYW5nZUV2ZW50LCB0aGlzLm1vZGVsLCAiY2hhbmdlIiwgdGhpcy5tb2RlbC5zb21FeHByZXNzaW9uKTsKICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSk7Cn0pKF8sICQsIHhmYWxpYik7CihmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgeGZhbGliLnZpZXcuQnV0dG9uRmllbGRWaWV3ID0geGZhbGliLnZpZXcuRmllbGRWaWV3LmV4dGVuZCh7CiAgICAgICAgaGFuZGxlQ29tbWl0IDogZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICAvLyB4ZmEuTG9nZ2VyLmRlYnVnKCJbQnV0dG9uRmllbGRWaWV3LmhhbmRsZUNvbW1pdF1zb20iICsKICAgICAgICAgICAgLy8gdGhpcy4kZWwuZGF0YSgic29tIikpOwogICAgICAgICAgICAvLyBkbyBOb3RoaW5nCiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlQ2xpY2tFdmVudCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmKHRoaXMuanFXaWRnZXQub3B0aW9uKCJhY2Nlc3MiKSA9PSAib3BlbiIpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX3NldEZvY3VzUGFyYW0odGhpcyk7CiAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmhhbmRsZUNsaWNrRXZlbnQuYXBwbHkodGhpcyxhcmd1bWVudHMpOwogICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLl90cmlnZ2VyT25CcmlkZ2UoImVsZW1lbnRCdXR0b25DbGlja2VkIiwgdGhpcy5tb2RlbCwgImNsaWNrIiwgdGhpcy5tb2RlbC5zb21FeHByZXNzaW9uKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9oYW5kbGVLZXlEb3duIDogZnVuY3Rpb24oZXZlbnQpIHsKCiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRG9tQ2hhbmdlZCA6ZnVuY3Rpb24oZXZlbnQpewogICAgICAgICAgICBzd2l0Y2goZXZlbnQuX3Byb3BlcnR5KSB7CiAgICAgICAgICAgICAgIGNhc2UgImNhcHRpb24udmFsdWUudGV4dCI6CiAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2hhbmRsZUNhcHRpb25WYWx1ZUNoYW5nZShldmVudC5uZXdUZXh0KTsKICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuaGFuZGxlRG9tQ2hhbmdlZC5hcHBseSh0aGlzLAogICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHMpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2hhbmRsZUNhcHRpb25WYWx1ZUNoYW5nZSA6IGZ1bmN0aW9uKHRleHQpIHsKICAgICAgICAgICAgIHZhciAgY2hpbGQgPSB7fTsKICAgICAgICAgICAgIHZhciBjYXB0aW9uID0gdGhpcy5tb2RlbC5nZXRFbGVtZW50KCdjYXB0aW9uJywwLCB0cnVlKTsKICAgICAgICAgICAgIHZhciB2YWx1ZSA9IGNhcHRpb24uZ2V0RWxlbWVudCgndmFsdWUnLDAsIHRydWUpOwoKICAgICAgICAgICAgIGlmKHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgY2hpbGQgPSB2YWx1ZS5vbmVPZkNoaWxkOwogICAgICAgICAgICAgICAgIGlmIChbInRleHQiLCJleERhdGEiXS5pbmRleE9mKGNoaWxkLmNsYXNzTmFtZSkgIT09IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGNzc09iaiA9IHRoaXMuX2dldFRleHRTdHlsZShjYXB0aW9uKTsKICAgICAgICAgICAgICAgICAgICBpZihjc3NPYmopIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kY3NzKHRoaXMuY2FwdGlvbiwgY3NzT2JqLmZvbnRTdHlsZXMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0aGlzLiRjc3ModGhpcy5jYXB0aW9uLCB7J2Rpc3BsYXknOid0YWJsZSd9KTsgLy8gdXNpbmcgdGhpcyB0byB1dGlsaXNlIHRoZSBjc3MgcHJvcGVydHkgdmVydGljYWwtYWxpZ24gdG8gYWNjb3VudCBmb3IgdkFsaWduCiAgICAgICAgICAgICAgICAgICAgdGV4dD14ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZW5jb2RlU2NyaXB0YWJsZVRhZ3ModGhpcy5fY29udmVydFhGQVJpY2hUb0h0bWwodGV4dCkpOwogICAgICAgICAgICAgICAgICAgICQodGhpcy5jYXB0aW9uLmNoaWxkcmVuWzBdKS5yZXBsYWNlV2l0aCh0ZXh0KTsKICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmNhcHRpb24uY2hpbGRyZW5bMF0gJiYgY3NzT2JqKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGNzcyh0aGlzLmNhcHRpb24uY2hpbGRyZW5bMF0sIGNzc09iai5wYXJhU3R5bGVzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9nZXRUZXh0U3R5bGUgOiBmdW5jdGlvbihjYXB0aW9uKXsKICAgICAgICAgICAgdmFyIGNzc09iaj14ZmFsaWIudmlldy5CYXNlVmlldy5wcm90b3R5cGUuX2dldFRleHRTdHlsZS5hcHBseSh0aGlzLFtjYXB0aW9uXSk7CiAgICAgICAgICAgIHZhciBwYXJhID0gY2FwdGlvbi5nZXRFbGVtZW50KCdwYXJhJywwLHRydWUpOwogICAgICAgICAgICBpZihjc3NPYmogJiYgcGFyYSAmJiBwYXJhLnZBbGlnbikgewogICAgICAgICAgICAgICBjc3NPYmoucGFyYVN0eWxlc1sndmVydGljYWwtYWxpZ24nXT0gcGFyYS52QWxpZ247CiAgICAgICAgICAgICAgIGNzc09iai5wYXJhU3R5bGVzWydkaXNwbGF5J10gPSAndGFibGUtY2VsbCc7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGNzc09iajsKICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlUGx1Z2luT3B0aW9ucyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgcGx1Z2luT3B0aW9ucyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX2NyZWF0ZVBsdWdpbk9wdGlvbnMuY2FsbCh0aGlzKTsKICAgICAgICAgICAgdmFyIHBhcmFTdHlsZXMgPSBudWxsOwogICAgICAgICAgICBpZih0aGlzLm1vZGVsLmdldEVsZW1lbnQoImNhcHRpb24iLCAwLCB0cnVlKSAmJiB0aGlzLm1vZGVsLmNhcHRpb24uZ2V0RWxlbWVudCgicGFyYSIsIDAsIHRydWUpKXsKICAgICAgICAgICAgICAgIHZhciBwYXJhID0gdGhpcy5tb2RlbC5jYXB0aW9uLnBhcmE7CiAgICAgICAgICAgICAgICBwYXJhU3R5bGVzID0gewogICAgICAgICAgICAgICAgICAgICJ0ZXh0LWFsaWduIiA6IHBhcmEuaEFsaWduLAogICAgICAgICAgICAgICAgICAgICJ2ZXJ0aWNhbC1hbGlnbiIgOiBwYXJhLnZBbGlnbiwKICAgICAgICAgICAgICAgICAgICAidGV4dC1pbmRlbnQiIDogdGhpcy5fY29udmVydFRvUHgocGFyYS50ZXh0SW5kZW50KSwKICAgICAgICAgICAgICAgICAgICAicGFkZGluZy1sZWZ0IiA6IHRoaXMuX2NvbnZlcnRUb1B4KHBhcmEubWFyZ2luTGVmdCksCiAgICAgICAgICAgICAgICAgICAgInBhZGRpbmctcmlnaHQiIDogdGhpcy5fY29udmVydFRvUHgocGFyYS5tYXJnaW5SaWdodCksCiAgICAgICAgICAgICAgICAgICAgInBhZGRpbmctdG9wIiA6IHRoaXMuX2NvbnZlcnRUb1B4KHBhcmEuc3BhY2VBYm92ZSksCiAgICAgICAgICAgICAgICAgICAgInBhZGRpbmctYm90dG9tIiA6IHRoaXMuX2NvbnZlcnRUb1B4KHBhcmEuc3BhY2VCZWxvdykKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcGx1Z2luT3B0aW9uc1sicGFyYVN0eWxlcyJdID0gcGFyYVN0eWxlczsKICAgICAgICAgICAgcGx1Z2luT3B0aW9uc1sic3ZnQ2FwdGlvbiJdID0gdGhpcy5jYXB0aW9uICE9IG51bGw7CiAgICAgICAgICAgIHJldHVybiBwbHVnaW5PcHRpb25zOwogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luIDogIGZ1bmN0aW9uKG9wdGlvbnMpewogICAgICAgICAgICBpZih0aGlzLm1vZGVsKXsKICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLnhmYUJ1dHRvbihvcHRpb25zKTsKICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQgPSB0aGlzLiRkYXRhKHRoaXMud2lkZ2V0LCAieGZhV2lkZ2V0LXhmYUJ1dHRvbiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luLmFwcGx5KHRoaXMsIFtvcHRpb25zXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSk7Cn0pKF8sICQsIHhmYWxpYik7KGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy5OdW1lcmljRmllbGRWaWV3ID0geGZhbGliLnZpZXcuRmllbGRWaWV3LmV4dGVuZCh7CiAgICAgICAgX21hdGNoQXJyYXkgOiB7ICJpbnRlZ2VyIjoiXlsrLV0/XFxkKiQiLCAiZGVjaW1hbCI6Il5bKy1dP1xcZGxkKFxcLlxcZGZkKT8kIiwgImZsb2F0IjoiXlsrLV0/XFxkKihcXC5cXGQqKT8kIiB9LAogICAgICAgIF9jcmVhdGVQbHVnaW5PcHRpb25zIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB2T3B0aW9ucyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX2NyZWF0ZVBsdWdpbk9wdGlvbnMuYXBwbHkoCiAgICAgICAgICAgICAgICAgICAgdGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgaWYgKHRoaXMubW9kZWwpIHsKICAgICAgICAgICAgICAgIHZPcHRpb25zLmRhdGFUeXBlID0gdGhpcy5tb2RlbC52YWx1ZS5vbmVPZkNoaWxkLmNsYXNzTmFtZSA7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy5sZWFkRGlnaXRzID0gdGhpcy5tb2RlbC52YWx1ZS5vbmVPZkNoaWxkLmxlYWREaWdpdHM7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy5mcmFjRGlnaXRzID0gdGhpcy5tb2RlbC52YWx1ZS5vbmVPZkNoaWxkLmZyYWNEaWdpdHM7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy56ZXJvID0gdGhpcy5tb2RlbC5feGZhKCkuX2dldExvY2FsZVN5bWJvbHModGhpcy5tb2RlbC5sb2NhbGUsIm51bWJlclN5bWJvbHMuemVybyIpOwogICAgICAgICAgICAgICAgdk9wdGlvbnMuZGVjaW1hbCA9IHRoaXMubW9kZWwuX3hmYSgpLl9nZXRMb2NhbGVTeW1ib2xzKHRoaXMubW9kZWwubG9jYWxlLCJudW1iZXJTeW1ib2xzLmRlY2ltYWwiKTsKICAgICAgICAgICAgICAgIC8vbm90ZSA6IG51bWJlck9mQ2VsbHMgYXMgemVybyBzaG91bGQgYmUgdHJlYXRlZCBhcyB1bmRlZmluZWQvbm8gcmVzdHJpY3Rpb24KICAgICAgICAgICAgICAgIHZhciB1aUNoaWxkID0gdGhpcy5tb2RlbC51aS5vbmVPZkNoaWxkOwogICAgICAgICAgICAgICAgaWYodWlDaGlsZCAhPSBudWxsICYmIHVpQ2hpbGQuZ2V0RWxlbWVudCgiY29tYiIsIDAsIHRydWUpICE9IG51bGwpCiAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMuY29tYkNlbGxzID0gdGhpcy5tb2RlbC51aS5vbmVPZkNoaWxkLmNvbWIubnVtYmVyT2ZDZWxscyB8fCB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHZPcHRpb25zOwogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luIDogZnVuY3Rpb24ob3B0aW9ucykgewogICAgICAgICAgICBpZiAodGhpcy5tb2RlbCkgewogICAgICAgICAgICAgICAgJCh0aGlzLndpZGdldCkubnVtZXJpY0lucHV0KG9wdGlvbnMpOwogICAgICAgICAgICAgICAgdGhpcy5qcVdpZGdldCA9IHRoaXMuJGRhdGEodGhpcy53aWRnZXQsICJ4ZmFXaWRnZXQtbnVtZXJpY0lucHV0Iik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9jcmVhdGVEZWZhdWx0V2lkZ2V0UGx1Z2luLmFwcGx5KHRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYW5kbGVDb21taXQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICB2YXIgX3JlZ2V4ID0gbnVsbDsKICAgICAgICAgICAgdmFyIHRlbXAgPSB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigidmFsdWUiKSArICIiOwoKICAgICAgICAgICAgdmFyIGxkID0gdGhpcy5tb2RlbC52YWx1ZS5vbmVPZkNoaWxkLmxlYWREaWdpdHM7CiAgICAgICAgICAgIHZhciBmZCA9IHRoaXMubW9kZWwudmFsdWUub25lT2ZDaGlsZC5mcmFjRGlnaXRzOwoKICAgICAgICAgICAgdmFyIG1hdGNoU3RyID0gdGhpcy5fbWF0Y2hBcnJheVt0aGlzLm1vZGVsLnZhbHVlLm9uZU9mQ2hpbGQuY2xhc3NOYW1lXTsKCiAgICAgICAgICAgIGxkID0gKGxkICE9PSB1bmRlZmluZWQgJiYgfmxkKSA/ICJ7MCwiK2xkKyJ9IiA6ICIqIjsKICAgICAgICAgICAgZmQgPSAoZmQgIT09IHVuZGVmaW5lZCAmJiB+ZmQpID8gInswLCIrZmQrIn0iIDogIioiOwogICAgICAgICAgICBtYXRjaFN0ciA9IG1hdGNoU3RyLnJlcGxhY2UoImxkIiwgbGQpOwogICAgICAgICAgICBtYXRjaFN0ciA9IG1hdGNoU3RyLnJlcGxhY2UoImZkIiwgZmQpOwogICAgICAgICAgICBfcmVnZXggPSBuZXcgUmVnRXhwKG1hdGNoU3RyLCAiZyIpOwoKICAgICAgICAgICAgaWYgKHRlbXAubWF0Y2goX3JlZ2V4KSkgLy8gaWYgd2UgbmVlZCB0byBrZWVwIHRoaXMgbmV3CWVudGVyZWQgdmFsdWUKICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuaGFuZGxlQ29tbWl0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigidmFsdWUiLHRoaXMubW9kZWxbdGhpcy5jb21taXRUYXJnZXRdKTsKICAgICAgICB9CiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy5DaG9pY2VMaXN0RmllbGRWaWV3ID0geGZhbGliLnZpZXcuRmllbGRWaWV3LmV4dGVuZCh7CgogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMuX3ByZXZTZWxlY3Rpb24gPSBudWxsOwogICAgICAgIH0sCgogICAgICAgIF92YWx1ZVRvQXJyYXk6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgICAgICAgIHZhciB2YWx1ZUFycmF5OwogICAgICAgICAgICBpZih2YWx1ZSAhPSBudWxsKQogICAgICAgICAgICAgICAgdmFsdWVBcnJheSA9IHZhbHVlLnNwbGl0KCJcbiIpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB2YWx1ZUFycmF5ID0gW251bGxdOwogICAgICAgICAgICByZXR1cm4gdmFsdWVBcnJheTsKICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlVmFsdWVDaGFuZ2UgOiBmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgIC8veGZhLkxvZ2dlci5kZWJ1ZygiW0Nob2ljZUxpc3RGaWVsZFZpZXcuX2hhbmRsZVZhbHVlQ2hhbmdlXXZhbHVlOnNvbSIgKyBldmVudC5uZXdUZXh0ICsgIjoiICsgdGhpcy4kZWwuZGF0YSgic29tIikpOwogICAgICAgICAgICB2YXIgcHJldlRleHQgPSB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigiZGlzcGxheVZhbHVlIik7CiAgICAgICAgICAgIGlmIChfLmlzQXJyYXkocHJldlRleHQpKSB7CiAgICAgICAgICAgICAgICBwcmV2VGV4dCA9IHByZXZUZXh0LmpvaW4oIlxuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5fcHJldlNlbGVjdGlvbiA9IHByZXZUZXh0OwoKICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24oInZhbHVlIix0aGlzLl92YWx1ZVRvQXJyYXkoZXZlbnQucHJldlRleHQpKTsKICAgICAgICAgICAgdGhpcy5qcVdpZGdldC5vcHRpb24oImRpc3BsYXlWYWx1ZSIsdGhpcy5fdmFsdWVUb0FycmF5KGV2ZW50Lm5ld1RleHQpKTsKICAgICAgICB9LAoKICAgICAgICBoYW5kbGVDb21taXQgOiBmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgIC8veGZhLkxvZ2dlci5kZWJ1ZygiW0Nob2ljZUxpc3RGaWVsZFZpZXcuaGFuZGxlQ29tbWl0XXNvbSIgKyB0aGlzLiRlbC5kYXRhKCJzb20iKSk7CiAgICAgICAgICAgIHZhciB2YWwgPSB0aGlzLmpxV2lkZ2V0Lm9wdGlvbigidmFsdWUiKTsKICAgICAgICAgICAgaWYoXy5pc0FycmF5KHZhbCkpewogICAgICAgICAgICAgICAgdmFsID0gdmFsLmpvaW4oIlxuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5tb2RlbFt0aGlzLmNvbW1pdFRhcmdldF0gPSB2YWw7CiAgICAgICAgfSwKCiAgICAgICAgX2NyZWF0ZURlZmF1bHRXaWRnZXRQbHVnaW4gOiAgZnVuY3Rpb24ob3B0aW9ucyl7CiAgICAgICAgICAgIGlmKHRoaXMubW9kZWwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKHRoaXMubW9kZWwudWkub25lT2ZDaGlsZC5vcGVuID09ICdhbHdheXMnIHx8IHRoaXMubW9kZWwudWkub25lT2ZDaGlsZC5vcGVuID09ICdtdWx0aVNlbGVjdCcpewoJCQkJCS8vZG8gcm9sZSBzZXR0aW5nIC0tCiAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5hdHRyKCJyb2xlIiwgImxpc3Rib3giKTsgLy9maW5kIGEgYmV0dGVyIHBsYWNlIHRvIGRvIHRoaXMKICAgICAgICAgICAgICAgICAgICBpZigkLmJyb3dzZXIubXNpZSB8fCAkLmJyb3dzZXIubW96aWxsYSl7CiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLm53a0xpc3RCb3gob3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQgPSB0aGlzLiRkYXRhKHRoaXMud2lkZ2V0LCAieGZhV2lkZ2V0LW53a0xpc3RCb3giKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLmxpc3RCb3gob3B0aW9ucyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuanFXaWRnZXQgPSB0aGlzLiRkYXRhKHRoaXMud2lkZ2V0LCAieGZhV2lkZ2V0LWxpc3RCb3giKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgICAgICQodGhpcy53aWRnZXQpLmRyb3BEb3duTGlzdChvcHRpb25zKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmpxV2lkZ2V0ID0gdGhpcy4kZGF0YSh0aGlzLndpZGdldCwgInhmYVdpZGdldC1kcm9wRG93bkxpc3QiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbi5hcHBseSh0aGlzLCBbb3B0aW9uc10pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2NyZWF0ZVBsdWdpbk9wdGlvbnMgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgdk9wdGlvbnMgPSAgeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fY3JlYXRlUGx1Z2luT3B0aW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICBpZih2T3B0aW9ucy52YWx1ZSE9bnVsbCAmJiAhXy5pc0FycmF5KHZPcHRpb25zLnZhbHVlKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoXy5pc1N0cmluZyh2T3B0aW9ucy52YWx1ZSkpCiAgICAgICAgICAgICAgICAgICAgdk9wdGlvbnMudmFsdWUgPSB2T3B0aW9ucy52YWx1ZS5zcGxpdCgiXG4iKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB2T3B0aW9ucy52YWx1ZSA9IFt2T3B0aW9ucy52YWx1ZV07IC8vY29udmVydCBuZXcgdmFsdWUgdG8gYXJyYXkKICAgICAgICAgICAgfQogICAgICAgICAgICBpZih0aGlzLm1vZGVsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy5lZGl0YWJsZSA9ICAodGhpcy5tb2RlbC51aS5vbmVPZkNoaWxkLnRleHRFbnRyeSA9PSAnMScpOwogICAgICAgICAgICAgICAgdk9wdGlvbnMubXVsdGlTZWxlY3QgPSAgKHRoaXMubW9kZWwudWkub25lT2ZDaGlsZC5vcGVuID09ICdtdWx0aVNlbGVjdCcpOwogICAgICAgICAgICAgICAgdmFyIHZJdGVtcyA9IF8ubWFwKHRoaXMubW9kZWwuX2dldERpc3BsYXlJdGVtcygpID8gdGhpcy5tb2RlbC5fZ2V0RGlzcGxheUl0ZW1zKCkubW9DaGlsZE5vZGVzIDogW10sCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oaXRlbSwgaW5kZXgpewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2F2ZUl0ZW0gPSAgdGhhdC5tb2RlbC5nZXRTYXZlSXRlbShpbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkaXNwbGF5SXRlbSA9IHRoYXQubW9kZWwuZ2V0RGlzcGxheUl0ZW0oaW5kZXgpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgInNhdmUiIDogc2F2ZUl0ZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGlzcGxheSIgOiBkaXNwbGF5SXRlbQogICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB2T3B0aW9ucy5pdGVtcyA9IHZJdGVtczsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdk9wdGlvbnM7CiAgICAgICAgfSwKICAgICAgICAKICAgICAgICBoYW5kbGVNb2RlbENoYW5nZWQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICBpZiAoZXZlbnQuX3Byb3BlcnR5ID09ICJhZGRJdGVtIikgewogICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlQWRkSXRlbShldmVudCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGV2ZW50Ll9wcm9wZXJ0eSA9PSAiY2xlYXJJdGVtcyIpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVDbGVhckl0ZW1zKGV2ZW50KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZXZlbnQuX3Byb3BlcnR5ID09ICJkZWxldGVJdGVtIikgewogICAgICAgICAgICAgICAgdGhpcy5faGFuZGxlRGVsZXRlSXRlbShldmVudCk7CiAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmhhbmRsZU1vZGVsQ2hhbmdlZC5hcHBseSh0aGlzLAogICAgICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUNoYW5nZUV2ZW50IDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgdmFyIG5ld1ZhbHVlID0gIHRoaXMuanFXaWRnZXQub3B0aW9uKCJkaXNwbGF5VmFsdWUiKTsKICAgICAgICAgICAgaWYoXy5pc0FycmF5KG5ld1ZhbHVlKSkgewogICAgICAgICAgICAgICAgbmV3VmFsdWUgPSBuZXdWYWx1ZS5qb2luKCJcbiIpOyAvLyByZXR1cm4gYSBzdHJpbmcKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgZGV0YWlsID0gewogICAgICAgICAgICAgICAgbmV3VGV4dDpuZXdWYWx1ZSwKICAgICAgICAgICAgICAgIHByZXZUZXh0OiB0aGlzLl9wcmV2U2VsZWN0aW9uLAogICAgICAgICAgICAgICAga2V5Y29kZTpldmVudC53aGljaCwKICAgICAgICAgICAgICAgIG1vZGlmaWVyOmV2ZW50LmN0cmxLZXksCiAgICAgICAgICAgICAgICBrZXlEb3duOmV2ZW50LndoaWNoPT09NDAsCiAgICAgICAgICAgICAgICBzaGlmdDpldmVudC5zaGlmdEtleSwKICAgICAgICAgICAgICAgIGNoYW5nZTogbmV3VmFsdWUKICAgICAgICAgICAgfTsKICAgICAgICAgICAgdGhpcy5tb2RlbC5leGVjRXZlbnQoImNoYW5nZSIsIGRldGFpbCk7CiAgICAgICAgfSwKICAgICAgICAKICAgICAgICBfaGFuZGxlQWRkSXRlbSA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgCXZhciBpdGVtVmFsdWVzID0gewogICAgICAgIAkJCXNEaXNwbGF5VmFsOmV2ZW50Lm5ld1RleHQsCiAgICAgICAgCQkJc1NhdmVWYWw6ZXZlbnQucHJldlRleHQKICAgICAgICAgICAgICAgIH07CiAgICAgICAgCXRoaXMuanFXaWRnZXQuYWRkSXRlbShpdGVtVmFsdWVzKTsKICAgICAgICAgICAgfSwKICAgICAgICAKICAgICAgICBfaGFuZGxlQ2xlYXJJdGVtcyA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgCXRoaXMuanFXaWRnZXQuY2xlYXJJdGVtcygpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgCiAgICAgICAgX2hhbmRsZURlbGV0ZUl0ZW0gOiBmdW5jdGlvbihldmVudCkgewogICAgICAgIAl0aGlzLmpxV2lkZ2V0LmRlbGV0ZUl0ZW0oZXZlbnQubmV3VGV4dCk7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKCiAgICB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3ID0geGZhbGliLnZpZXcuQmFzZVZpZXcuZXh0ZW5kKHsKICAgICAgICBpbml0aWFsaXplIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHRoaXMubGF5b3V0VGVtcGxhdGUgPSB7fTsKICAgICAgICAgICAgdGhpcy5jaGlsZFZpZXdzID0gW107CiAgICAgICAgICAgIHRoaXMubGF5b3V0ID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5faW5pdExheW91dCgpOwogICAgICAgIH0sCgogICAgICAgIF9pbml0TGF5b3V0IDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLl9pbml0TGF5b3V0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMuX2luaXRpYWxpemVkKXsKICAgICAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3NMYXlvdXRUZW1wbGF0ZSgpOwogICAgICAgICAgICAgICAgdGhpcy5sYXlvdXQgPSB0aGlzLl9sYXlvdXRNYW5hZ2VyLmNyZWF0ZUxheW91dCh0aGlzKTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLm1vZGVsKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuQ0hJTERfQURERUQsdGhpcyk7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuQ0hJTERfUkVNT1ZFRCx0aGlzKTsKICAgICAgICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9uKHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5DSElMRF9NT1ZFRCx0aGlzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX3N5bmNGb3JtTm9kZVRvSHRtbCh0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9wcm9jZXNzTGF5b3V0VGVtcGxhdGUgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgeGZhVGVtcGxhdGVDYWNoZSA9IHRoaXMuX2Zvcm1Eb21Sb290KCkuX3hmYVRlbXBsYXRlQ2FjaGU7CiAgICAgICAgICAgIHZhciBodG1sVGVtcGxhdGVDYWNoZSA9IHRoaXMuX3hmYVZpZXdSZWdpc3RyeSgpLnRlbXBsYXRlQ2FjaGUoKTsKICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICB2YXIgaW5pdGlhbEZvcm1Ob2RlID0geGZhVGVtcGxhdGVDYWNoZS5nZXRJbml0aWFsRm9ybURvbVJlZih0aGlzLl9pZCk7CiAgICAgICAgICAgIGlmKCFpbml0aWFsRm9ybU5vZGUpewogICAgICAgICAgICAgICAgdGhpcy5sYXlvdXRUZW1wbGF0ZS5oYXNUZW1wbGF0ZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0VGVtcGxhdGUuaGFzVGVtcGxhdGUgPSB0cnVlOwoKICAgICAgICAgICAgdGhpcy4kZWxjaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKSB7CiAgICAgICAgICAgICAgICB2YXIgaUNoaWxkTm9kZSA9IHhmYVRlbXBsYXRlQ2FjaGUuZ2V0SW5pdGlhbEZvcm1Eb21SZWYodGhpcy5pZCk7CiAgICAgICAgICAgICAgICBpZighaUNoaWxkTm9kZSkKICAgICAgICAgICAgICAgICAgICByZXR1cm47CgogICAgICAgICAgICAgICAgdmFyIHBhcnRCZWdpbiA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgcGFydFNwbGl0ID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgcGFydEVuZCA9IHRydWU7CiAgICAgICAgICAgICAgICB2YXIgb2NjdXJyZW5jZXMgPSB0aGF0LmdldE9yRWxzZSh0aGF0LiRkYXRhKHRoaXMsIHhmYWxpYi52aWV3LkxheW91dENvbnN0LlhGQV9NT0RFTCksIHhmYWxpYi52aWV3LkxheW91dENvbnN0LkxBWU9VVF9NT0RFTCsiLiIreGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuT0NDVVJSRU5DRVMsIDEpOyAvL29jY3VycmVuY2VzCiAgICAgICAgICAgICAgICB2YXIgY3VycmVudE9jY3VyZW5jZSA9IHRoYXQuZ2V0T3JFbHNlKHRoYXQuJGRhdGEodGhpcywgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMKSwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuTEFZT1VUX01PREVMKyIuIit4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5PQ0NVUl9JTkRFWCwgMCk7IC8vb2NjdXJJbmRleAogICAgICAgICAgICAgICAgaWYoY3VycmVudE9jY3VyZW5jZSAhPSAwKXsKICAgICAgICAgICAgICAgICAgICAvL1RoZSBwYXJ0IGhhcyBiZWVuIHNwbGl0IGFuZCBjdXJyZW50T2NjdXJhbmNlIGlzIG5vdCB6ZXJvLiBUaGF0IG1lYW5zIHRoaXMgZWxlbWVudCBkb2VzIG5vdCBzdGFydCBpbiB0aGUgcGFyZW50IGxheW91dC4KICAgICAgICAgICAgICAgICAgICBwYXJ0QmVnaW4gPSBmYWxzZTsgLy8gbm90IHJlYWxseSB1c2VkIGFueXdoZXJlCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZigob2NjdXJyZW5jZXMgLSBjdXJyZW50T2NjdXJlbmNlKSA+IDEpewogICAgICAgICAgICAgICAgICAgIC8vVGhpcyBtZWFucyB0aGF0IHRoaXMgZWxlbWVudCBsYXlvdXQgaGFzIGJlZW4gc3BsaXQgaW50byBtdWx0aXBsZSBwYXJ0cyBhbmQgdGhpcyBwYXJ0IGlzIG5vdCBsYXN0IHBhcnQuCiAgICAgICAgICAgICAgICAgICAgcGFydFNwbGl0ID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBwYXJ0RW5kID0gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgY2hpbGRUZW1wbGF0ZUlkID0geGZhVGVtcGxhdGVDYWNoZS5nZXRUZW1wbGF0ZVJlZihpQ2hpbGROb2RlLmV4dHJhcy5odG1sSWQpLmV4dHJhcy5odG1sSWQ7CiAgICAgICAgICAgICAgICB0aGF0LiRkYXRhKHRoaXMsICJ0ZW1wbGF0ZUlkIiwgY2hpbGRUZW1wbGF0ZUlkKTsgLy8gU2V0IHRoZSB0ZW1wbGF0ZUlkIGFzIGFjdHVhbCBpZCBtYXkgY2hhbmdlLgogICAgICAgICAgICAgICAgaWYoeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmlzVGFibGVIRihpQ2hpbGROb2RlKSl7CiAgICAgICAgICAgICAgICAgICAgLy9BIHN1cGVyIGhhY2sgZm9yICMzNDY4NDA3IHRpbGwgd2Ugc3VwcG9ydCBsZWFkZXIvdHJhaWxlci4gRm9yIFRhYmxlIEhlYWRlci9Gb290ZXIgd2UgbWF5IG5vdCBoYXZlIElNIGJlZm9yZSBpdC4gU28gaGFuZGxlIGV4Y2x1c2l2ZWx5IHRpbGwgd2UgZml4IGl0CiAgICAgICAgICAgICAgICAgICAgdGhhdC5sYXlvdXRUZW1wbGF0ZVtpQ2hpbGROb2RlLmV4dHJhcy5odG1sSWRdID0ge2hhc0ZpcnN0UGFydEJlZ2luIDogcGFydEJlZ2luLCBoYXNMYXN0UGFydE92ZXJmbG93IDogcGFydFNwbGl0fTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYoaUNoaWxkTm9kZSAmJiB0aGF0LmdldE9yRWxzZSh0aGF0LiRkYXRhKHRoaXMsIHhmYWxpYi52aWV3LkxheW91dENvbnN0LlhGQV9NT0RFTCksIHhmYWxpYi52aWV3LkxheW91dENvbnN0Lk5PREVfVFlQRSAsIiIpLnRvTG93ZXJDYXNlKCkgPT0gInN1YmZvcm0iKXsKICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2VJbmRleCA9IC0xOwogICAgICAgICAgICAgICAgICAgIHZhciBzZklNID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICB2YXIgZm91bmQgPSBfLmZpbmQoaW5pdGlhbEZvcm1Ob2RlLmNoaWxkcmVuLCBmdW5jdGlvbihpbml0Q2hpbGQpewogICAgICAgICAgICAgICAgICAgICAgICBpZih0aGF0Lm1hdGNoSnNvblR5cGUoaW5pdENoaWxkLCAiaW5zdGFuY2VNYW5hZ2VyIikpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZJTSA9IGluaXRDaGlsZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSW5kZXggPSAtMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSW5kZXggPSBpbnN0YW5jZUluZGV4ICsgMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGluaXRDaGlsZCA9PSBpQ2hpbGROb2RlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIGlmKGZvdW5kKXsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgcmVwZWF0YWJsZSBwdXQgaW4gY2FjaGUsIGFsb25nIHdpdGggY3VycmVudCBvY2N1ckluZGV4IGZvciBsYXRlciBzdGl0Y2hpbmcKICAgICAgICAgICAgICAgICAgICAgICAgaWYoaUNoaWxkTm9kZS5leHRyYXMuaHRtbElkID09IGNoaWxkVGVtcGxhdGVJZCAmJiBzZklNICYmIChwYXJzZUludCh0aGF0LmdldE9yRWxzZShzZklNLm1heCwgeGZhbGliLnNjcmlwdC5PY2N1ci5wcm90b3R5cGUuX2RlZmF1bHRzLm1heCkpIDwgMCB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VJbnQodGhhdC5nZXRPckVsc2Uoc2ZJTS5taW4sIHhmYWxpYi5zY3JpcHQuT2NjdXIucHJvdG90eXBlLl9kZWZhdWx0cy5taW4gKSkgPCBwYXJzZUludCh0aGF0LmdldE9yRWxzZShzZklNLm1heCwgeGZhbGliLnNjcmlwdC5PY2N1ci5wcm90b3R5cGUuX2RlZmF1bHRzLm1heCApKSkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaHRtbFRlbXBsYXRlQ2FjaGUucHV0KHRoaXMuY2xvbmVOb2RlKHRydWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNMYXN0Q2hpbGQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRJbmRleCA9IGluaXRpYWxGb3JtTm9kZS5jaGlsZHJlbi5pbmRleE9mKGlDaGlsZE5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZihpbml0aWFsRm9ybU5vZGUuY2hpbGRyZW4ubGVuZ3RoID4gY2hpbGRJbmRleCArMSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5tYXRjaEpzb25UeXBlKGluaXRpYWxGb3JtTm9kZS5jaGlsZHJlbltjaGlsZEluZGV4ICsgMV0sICJzdWJmb3JtIikpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNMYXN0Q2hpbGQgPSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUluZGV4ID0gaW5zdGFuY2VJbmRleCArIGN1cnJlbnRPY2N1cmVuY2UvMTAwMDsgIC8vIGhhY2ssIGFzc3VtZSBhdCBtb3N0IDEwMDAgaW5zdGFuY2VzIG9mIGEgcnB0LiBTRi4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBkZWNpbWFsIHBhcnQgaXMgdXNlZCB0byBqdWRnZSB0aGUgb3ZlcmZsb3dlZCBwYXJ0IHdoaWNoIGhhcyBzcGxpdCBvdmVyIG11bHRpcGxlIHBhZ2VzCiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQubGF5b3V0VGVtcGxhdGVbY2hpbGRUZW1wbGF0ZUlkXSA9ICFfLmlzRW1wdHkodGhhdC5sYXlvdXRUZW1wbGF0ZVtjaGlsZFRlbXBsYXRlSWRdKSA/IHRoYXQubGF5b3V0VGVtcGxhdGVbY2hpbGRUZW1wbGF0ZUlkXSA6IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBjaGlsZFRlbXBsYXRlSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydCA6IGluc3RhbmNlSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQgOiBpbnN0YW5jZUluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzRmlyc3RQYXJ0QmVnaW4gOiBwYXJ0QmVnaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXNMYXN0UGFydE92ZXJmbG93IDogcGFydFNwbGl0CiAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQubGF5b3V0VGVtcGxhdGVbY2hpbGRUZW1wbGF0ZUlkXS5lbmQgPSBpc0xhc3RDaGlsZCAmJiBwYXJ0RW5kID8gLTEgOiBpbnN0YW5jZUluZGV4OwogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmxheW91dFRlbXBsYXRlW2NoaWxkVGVtcGxhdGVJZF0uaGFzTGFzdFBhcnRPdmVyZmxvdyA9IHBhcnRTcGxpdDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHRoYXQubGF5b3V0VGVtcGxhdGVbY2hpbGRUZW1wbGF0ZUlkXSA9IHtoYXNGaXJzdFBhcnRCZWdpbiA6IHBhcnRCZWdpbiwgaGFzTGFzdFBhcnRPdmVyZmxvdyA6IHBhcnRTcGxpdH07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pIDsKICAgICAgICB9LAoKICAgICAgICBfc3luY0Zvcm1Ob2RlVG9IdG1sOiBmdW5jdGlvbihkZWVwU3luYyl7CiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpczsKICAgICAgICAgICAgdmFyIGh0bWxUZW1wbGF0ZUNhY2hlID0gdGhpcy5feGZhVmlld1JlZ2lzdHJ5KCkudGVtcGxhdGVDYWNoZSgpOwogICAgICAgICAgICB2YXIgb2xkSWRUb0NoaWxkVmlld3MgPSB7fTsKICAgICAgICAgICAgdmFyIG5ld0lkVG9DaGlsZFZpZXdzID0ge307CiAgICAgICAgICAgIHZhciBjZWxsSW5kZXggPSAwOwogICAgICAgICAgICB2YXIgbGFzdFNpYmxpbmcgPSBudWxsOwoKICAgICAgICAgICAgLy9jYWNoZSB0aGUgb2xkIGNoaWxkIHZpZXdzIGFnYWluc3QgdGhlaXIgSURzCiAgICAgICAgICAgIF8uZWFjaCh0aGlzLmNoaWxkVmlld3MsIGZ1bmN0aW9uKGNoaWxkVmlldyl7CiAgICAgICAgICAgICAgICBvbGRJZFRvQ2hpbGRWaWV3c1tjaGlsZFZpZXcuZWwuaWRdID0gY2hpbGRWaWV3OwogICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgIF8uZWFjaCh0aGlzLmdldE9yRWxzZSh0aGlzLCAibW9kZWwuY2hpbGRyZW4iLCBbXSksCiAgICAgICAgICAgICAgICBmdW5jdGlvbihjaGlsZE1vZGVsKXsKICAgICAgICAgICAgICAgICAgICBpZighdGhpcy5fdmFsaWRhdGVMYXlvdXRUZW1wbGF0ZShjaGlsZE1vZGVsKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIHZhciBjVGVtcGxhdGVJZCA9IGNoaWxkTW9kZWwuX3RlbXBsYXRlSWQoKTsKICAgICAgICAgICAgICAgICAgICB2YXIgaWQgPSBjaGlsZE1vZGVsLmh0bWxJZDsKICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRFbCA9IHRoaXMuJGVsY2hpbGRyZW4odGhhdC5qcUlkKGlkKSlbMF07CiAgICAgICAgICAgICAgICAgICAgaWYoIWNoaWxkRWwgJiYgKCFuZXdJZFRvQ2hpbGRWaWV3cy5oYXNPd25Qcm9wZXJ0eShjVGVtcGxhdGVJZCkgJiYgIW9sZElkVG9DaGlsZFZpZXdzLmhhc093blByb3BlcnR5KGNUZW1wbGF0ZUlkKSkpewogICAgICAgICAgICAgICAgICAgICAgICBjaGlsZEVsID0gdGhpcy4kZWxjaGlsZHJlbih0aGF0LmpxSWQoY1RlbXBsYXRlSWQpKVswXTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYoIWNoaWxkRWwpewogICAgICAgICAgICAgICAgICAgICAgICBpZighdGhpcy5faXNIaWRkZW4oY2hpbGRNb2RlbCkpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGh0bWxUbXBsdCA9IGh0bWxUZW1wbGF0ZUNhY2hlLmdldChjVGVtcGxhdGVJZCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZighaHRtbFRtcGx0KXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmVycm9yKCJ4ZmFWaWV3IiwgIkh0bWwgdGVtcGxhdGUgY291bGQgbm90IGJlIGZvdW5kLiBjVGVtcGxhdGVJZDoiK2NUZW1wbGF0ZUlkKyIsIHNvbToiK2NoaWxkTW9kZWwuc29tRXhwcmVzc2lvbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZEVsID0gaHRtbFRtcGx0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHhmYUhpZGRlblBIID0gJCgiPGRpdj48L2Rpdj4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGNoaWxkTW9kZWwgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LkRyYXcpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmYUhpZGRlblBILmFkZENsYXNzKCJkcmF3Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKGNoaWxkTW9kZWwgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LkZpZWxkKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZmFIaWRkZW5QSC5hZGRDbGFzcygiZmllbGQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkRWwgPSB4ZmFIaWRkZW5QSC5nZXQoMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1RPRE86IGJlbG93IHdheSBvZiBmaW5kaW5nIG5vZGV0eXBlIGlzIG5vdCBhbHdheXMgdHJ1ZSBhbmQgbWF5IGJyZWFrIGhpZGRlbiBvYmplY3RzLiBXZSB3aWxsIG5lZWQgcm9idXN0IHdheSB0byBnZXQgbm9kZSB0eXBlIHRoYXQgY2FuIGJlIHVzZWQgYnkgWGZhVmlld1JlZ2lzdHJ5Lm5vZGVUeXBlcmVnaXN0cnkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0J1dCBmb3IgY3VycmVudCBpbXBsZW1lbnRhdGlvbiBpdCB3b3VsZCB3b3JrIGFzIHdlIGNhcmUgb25seSBhYm91dCBjb250YWluZXIgbm9kZSB0eXBlcy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbE5vZGVUeXBlID0gY2hpbGRNb2RlbC5jbGFzc05hbWUudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuJGRhdGEoY2hpbGRFbCwgInhmYUhpZGRlblBIIiwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgeGZhTW9kZWxPYmogPSB7fTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmYU1vZGVsT2JqW3hmYWxpYi52aWV3LkxheW91dENvbnN0Lk5PREVfVFlQRV0gPSBlbE5vZGVUeXBlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4kZGF0YShjaGlsZEVsLCB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5YRkFfTU9ERUwsIHhmYU1vZGVsT2JqKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjaGlsZEVsLmlkID0gY2hpbGRNb2RlbC5odG1sSWQ7CgogICAgICAgICAgICAgICAgICAgIHRoaXMuJGRhdGEoY2hpbGRFbCwidGVtcGxhdGVJZCIsIGNUZW1wbGF0ZUlkKTsgLy9SZXF1aXJlZCBmb3IgbmVzdGVkIHRlbXBsYXRlIEVMcwogICAgICAgICAgICAgICAgICAgIHZhciB2aWV3ID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICBpZihvbGRJZFRvQ2hpbGRWaWV3cy5oYXNPd25Qcm9wZXJ0eShjaGlsZEVsLmlkKSkgewogICAgICAgICAgICAgICAgICAgICAgICB2aWV3ID0gb2xkSWRUb0NoaWxkVmlld3NbY2hpbGRFbC5pZF07CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGxhc3RTaWJsaW5nICYmIGxhc3RTaWJsaW5nLm1vZGVsIGluc3RhbmNlb2YgeGZhbGliLnNjcmlwdC5TdWJmb3JtICYmIGxhc3RTaWJsaW5nLm1vZGVsLmluc3RhbmNlTWFuYWdlci5faXNSZXBlYXRhYmxlKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0U2libGluZy4kZWwuYWZ0ZXIodmlldy4kZWwpOyAvL1RoZSByZXBlYXRhYmxlIHN1YmZvcm0gbWlnaHQgaGF2ZSBtb3ZlZCB1c2luZyBtb3ZlSW5zdGFuY2UuIFNvIHBvc2l0aW9uIGl0IGFmdGVyIGl0J3Mgc2libGluZy4KICAgICAgICAgICAgICAgICAgICAgICAgaWYoZGVlcFN5bmMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3LnN5bmNGb3JtTm9kZVRvSHRtbChkZWVwU3luYyk7IC8vU3luYyBleGlzdGluZyB2aWV3cyBvbmx5IGlmIGRlZXBTeW5jIGlzIHJlcXVlc3RlZAogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZpZXcgPSB0aGlzLl9jcmVhdGVDaGlsZChjaGlsZEVsLCBjZWxsSW5kZXgsIGxhc3RTaWJsaW5nKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2VsbEluZGV4ID0gY2VsbEluZGV4ICsgKHZpZXcubGF5b3V0TW9kZWwuY29sc3BhbiB8fCAxKTsgLy9BZGQgdGhlIGNvbHNwYW4gb3Igb25lCiAgICAgICAgICAgICAgICAgICAgbmV3SWRUb0NoaWxkVmlld3NbY2hpbGRNb2RlbC5odG1sSWRdID0gdmlldzsKICAgICAgICAgICAgICAgICAgICBsYXN0U2libGluZyA9IHZpZXc7CiAgICAgICAgICAgICAgICB9LCB0aGlzCiAgICAgICAgICAgICk7CgogICAgICAgICAgICB0aGlzLmNoaWxkVmlld3MgPSBbXTsKICAgICAgICAgICAgaWYgKCF0aGlzLiRlbC5pcygiOmVtcHR5IikpIHsKICAgICAgICAgICAgICAgIHRoaXMuJGVsY2hpbGRyZW4oKS5lYWNoKGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIGlmKG5ld0lkVG9DaGlsZFZpZXdzLmhhc093blByb3BlcnR5KHRoaXMuaWQpKQogICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmNoaWxkVmlld3MucHVzaChuZXdJZFRvQ2hpbGRWaWV3c1t0aGlzLmlkXSk7CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmxvZygieGZhVmlldyIsNSwicmVtb3ZpbmcgZWxlbWVudCBhcyBubyBjb3JyZXNwb25kaW5nIGZvcm0gZG9tIG5vZGUgZm91bmQuIGlkOiIgKyB0aGlzLmlkICsgIiwgcGFyZW50IGlkOiIrIHRoYXQuX2lkKTsKICAgICAgICAgICAgICAgICAgICAgICAgJCh0aGlzKS5yZW1vdmUoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KSA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLl9zeW5jRm9ybU5vZGVUb0h0bWwuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgICAvL3N5bmMgb3RoZXIgcHJvcHMgYmVmb3JlIGxheW91dAogICAgICAgIH0sCgogICAgICAgIF9jcmVhdGVDaGlsZCA6IGZ1bmN0aW9uKGNoaWxkRWwsIGNlbGxJbmRleCwgcHJldmlvdXNTaWJsaW5nKXsKICAgICAgICAgICAgdmFyIHZpZXcgPSB0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS5jcmVhdGVWaWV3KGNoaWxkRWwsIHsKICAgICAgICAgICAgICAgICAgICBwYXJlbnRWaWV3OiB0aGlzLAogICAgICAgICAgICAgICAgICAgIHRhYmxlQ2VsbEluZGV4IDogY2VsbEluZGV4LAogICAgICAgICAgICAgICAgICAgIHBhZ2VOdW1iZXI6IHRoaXMuX3BhZ2VOdW1iZXIoKQogICAgICAgICAgICAgICAgfSk7Ci8vICAgICAgICAgICAgaWYodGhpcy5yZXNpemFibGUgfHwgdmlldy5faXNQbGFjZUhvbGRlckVsKCkpewovLyAgICAgICAgICAgICAgICAvL1dlIGFsc28gbmVlZCB0byBjYWxsIGxheW91dENvbnRhaW5lciBmb3IgdGhlIGNhc2VzIHdoZXJlIHRoZSBvYmplY3QgaXMgaW5pdGlhbGx5IGhpZGRlbiBldmVuIGlmIHBhcmVudCBpcyBub3QgcmVzaXphYmxlCi8vICAgICAgICAgICAgICAgIC8vIHNpbmNlIHdlIGRvIG5vdCBoYXZlIGVsIGZvciBoaWRkZW4gb2JqZWN0IGFzIHlldCwuIFRPRE86IG9wdGltaXplIGl0LgovLyAgICAgICAgICAgICAgICB2aWV3Lm9uKHhmYWxpYi52aWV3LlhmYVZpZXdFdmVudC5FWFRFTlRfQ0hBTkdFICsiICIrIHdpbmRvdy54ZmFsaWIudmlldy5YZmFWaWV3RXZlbnQuUFJFU0VOQ0VfQ0hBTkdFLAovLyAgICAgICAgICAgICAgICAgICAgdGhpcy5fbGF5b3V0Q29udGFpbmVyLCB0aGlzKTsKLy8gICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKHRoaXMuJGVsLmZpbmQodmlldy4kZWwpLmxlbmd0aCA8IDEpewogICAgICAgICAgICAgICAgaWYocHJldmlvdXNTaWJsaW5nKQogICAgICAgICAgICAgICAgICAgIHByZXZpb3VzU2libGluZy4kZWwuYWZ0ZXIodmlldy4kZWwpOyAgICAgICAgLy9QdXNoIHRoZSBlbGVtZW50IGFmdGVyIHRoZSBzaWJsaW5nCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZWwucHJlcGVuZCh2aWV3LiRlbCk7ICAgICAgLy9wdXNoIHRoZSBlbGVtZW50IGF0IHRoZSBiZWdpbmluZyBvZiBwYXJlbnQgaWYgbm8gc2libGluZyBpcyBmb3VuZCxcLgogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB2aWV3OwogICAgICAgIH0sCgogICAgICAgIF92YWxpZGF0ZUxheW91dFRlbXBsYXRlIDogZnVuY3Rpb24oY2hpbGRNb2RlbCl7CiAgICAgICAgICAgIHZhciBjVGVtcGxhdGVJZCA9IGNoaWxkTW9kZWwuX3RlbXBsYXRlSWQoKTsKICAgICAgICAgICAgaWYoeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmlzVGFibGVIRihjaGlsZE1vZGVsKSl7CiAgICAgICAgICAgICAgICAvL0Egc3VwZXIgaGFjayBmb3IgIzM0Njg0MDcgdGlsbCB3ZSBzdXBwb3J0IGxlYWRlci90cmFpbGVyLiBGb3IgdGFibGUgSGVhZGVyL0Zvb3RlciwgdGVtcGxhdGVJZCB3b3VsZCBiZSB0aGlzIHNhbWUgaHRtbElkLgogICAgICAgICAgICAgICAgY1RlbXBsYXRlSWQgPSBjaGlsZE1vZGVsLmh0bWxJZDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZighdGhpcy5faXNQYWludGFibGUoY2hpbGRNb2RlbCkpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0VGVtcGxhdGUuaGFzVGVtcGxhdGUpewogICAgICAgICAgICAgICAgdmFyIHhmYVRlbXBsYXRlQ2FjaGUgPSB0aGlzLl9mb3JtRG9tUm9vdCgpLl94ZmFUZW1wbGF0ZUNhY2hlOwogICAgICAgICAgICAgICAgdmFyIGlDaGlsZEpzb24gPSB4ZmFUZW1wbGF0ZUNhY2hlLmdldEluaXRpYWxGb3JtRG9tUmVmKGNoaWxkTW9kZWwuaHRtbElkKTsgLy9maW5kIHRoZSB0MCB2ZXJzaW9uIG9mIHRoaXMgY2hpbGQKICAgICAgICAgICAgICAgIGlmKCF0aGlzLmxheW91dFRlbXBsYXRlLmhhc093blByb3BlcnR5KGNUZW1wbGF0ZUlkKSAmJiAhdGhpcy5faXNIaWRkZW4oaUNoaWxkSnNvbikpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBIZXJlIGJlY2F1c2UgdGhlIHBhZ2UgaGFzIGJlZW4gc3BsaXQgYW5kIHRoaXMgY2hpbGRNb2RlbCBpcyByZW5kZXJlZCBpbiBkaWZmZXJlbnQgcGFnZQogICAgICAgICAgICAgICAgZWxzZSBpZighdGhpcy5sYXlvdXRUZW1wbGF0ZS5oYXNPd25Qcm9wZXJ0eShjVGVtcGxhdGVJZCkgJiYgdGhpcy5faXNIaWRkZW4oaUNoaWxkSnNvbikpewogICAgICAgICAgICAgICAgICAgIC8vaWYgdGhpcyBjaGlsZCBtYXkgbm90IHByZXNlbnQgaW4gbGF5b3V0IHRlbXBsYXRlIGlmIGl0IHdhcyBoaWRkZW4gYXQgdDAgYmVjYXNlIGZvciBoaWRkZW4gY29udGFpbmVycyBsYXlvdXQgaXMgbm90IGdlbmVyYXRlZC4KICAgICAgICAgICAgICAgICAgICAvL1NvIHdlIG5lZWQgdG8gcHV0IGV4dHJhIGVmZm9ydCB0byBjaGVjayBpZiB0aGlzIGhpZGRlbiBvYmplY3QgZml0cyBsYXlvdXQgdGVtcGxhdGUgb2YgdGhpcyB2aWV3LgogICAgICAgICAgICAgICAgICAgIHZhciB2YWxpZCA9IHRoaXMuX3ZhbGlkYXRlSGlkZGVuQ2hpbGRMYXlvdXQoY2hpbGRNb2RlbCk7CiAgICAgICAgICAgICAgICAgICAgaWYodmFsaWQpewogICAgICAgICAgICAgICAgICAgICAgICAvL2lmIGZvdW5kIHZhbGlkYXRlZCwgY2FjaGUgaXQgZm9yIGZ1dHVyZS4gQWxzbyBoaWRkZW4gcGFydCBhcmUgYXV0b21hdGljYWxseSBzdGl0Y2hlZCBpbnRvIG9uZSBwYXJ0LCBzbyBoYXNMYXN0UGFydE92ZXJmbG93IHdvdWxkIGZhbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0VGVtcGxhdGVbY1RlbXBsYXRlSWRdID0ge2hhc0ZpcnN0UGFydEJlZ2luOiB0cnVlLCBoYXNMYXN0UGFydE92ZXJmbG93IDogZmFsc2V9OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsaWQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKGNoaWxkTW9kZWwgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0LlN1YmZvcm0gJiYKICAgICAgICAgICAgICAgICAgICAoY2hpbGRNb2RlbC5pbnN0YW5jZUluZGV4IDwgTWF0aC5mbG9vcih0aGlzLmxheW91dFRlbXBsYXRlW2NUZW1wbGF0ZUlkXS5zdGFydCkgfHwKICAgICAgICAgICAgICAgICAgICAoY2hpbGRNb2RlbC5pbnN0YW5jZUluZGV4ID4gdGhpcy5sYXlvdXRUZW1wbGF0ZVtjVGVtcGxhdGVJZF0uZW5kICYmIHRoaXMubGF5b3V0VGVtcGxhdGVbY1RlbXBsYXRlSWRdLmVuZCA+IC0xKSkpewogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgICAvL1RoaXMgc3ViZm9ybSBpcyBub3QgaW4gdGhlIHJhbmdlIG9mIEluc3RhbmNlcyBoYW5kbGVkIGJ5IHRoaXMgcGFnZS4gTHlpbmcgZWl0aGVyIGluIGVhcmxpZXIgb3IgbmV4dCBwYWdlcy4KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9LAoKICAgICAgICBfdmFsaWRhdGVIaWRkZW5DaGlsZExheW91dCA6IGZ1bmN0aW9uKGNoaWxkTW9kZWwpewogICAgICAgICAgICBpZighY2hpbGRNb2RlbC5wYXJlbnQpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7ICAgICAgIC8vY2FuIGhhcHBlbiBvbmx5IGZvciByb290c3ViZm9ybXZpZXcgYXMgY2hpbGQgbW9kZWwKICAgICAgICAgICAgdmFyIHNpYmxpbmdzID0gY2hpbGRNb2RlbC5wYXJlbnQuY2hpbGRyZW47CiAgICAgICAgICAgIGlmKHNpYmxpbmdzICYmIHNpYmxpbmdzLmluZGV4T2YoY2hpbGRNb2RlbCkgPiAwKXsKICAgICAgICAgICAgICAgIHZhciBjaGlsZEluZGV4ID0gc2libGluZ3MuaW5kZXhPZihjaGlsZE1vZGVsKTsKICAgICAgICAgICAgICAgIHZhciBsYXN0UGFpbnRhYmxlU2libGluZyA9IG51bGw7CiAgICAgICAgICAgICAgICBmb3IodmFyIGxhc3RJbmRleCA9IGNoaWxkSW5kZXgtMTsgbGFzdEluZGV4ID49MDsgbGFzdEluZGV4LS0pewogICAgICAgICAgICAgICAgICAgIHZhciBsYXN0U2libGluZyA9IHNpYmxpbmdzW2xhc3RJbmRleF07CiAgICAgICAgICAgICAgICAgICAgaWYobGFzdFNpYmxpbmcgaW5zdGFuY2VvZiB4ZmFsaWIuc2NyaXB0Lkluc3RhbmNlTWFuYWdlcil7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZVRlbXBsYXRlID0gbGFzdFNpYmxpbmcuX2luc3RhbmNlVGVtcGxhdGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRlbXBsYXRlSWQgPSB0aGlzLmdldE9yRWxzZShpbnN0YW5jZVRlbXBsYXRlLCAiZXh0cmFzLmh0bWxJZCIsIG51bGwpOwogICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmxheW91dFRlbXBsYXRlW3RlbXBsYXRlSWRdICE9IG51bGwpewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5sYXlvdXRUZW1wbGF0ZVt0ZW1wbGF0ZUlkXS5lbmQgPT0gLTEgJiYgIXRoaXMubGF5b3V0VGVtcGxhdGVbdGVtcGxhdGVJZF0uaGFzTGFzdFBhcnRPdmVyZmxvdyl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9MYXN0IGxheW91dCBwYXJ0IG9mIGxhc3QgaW5zdGFuY2Ugb2YgdGhpcyBJTSB3YXMgaGVyZSBhdCB0MC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1NvIGhpZGRlbiBvYmplY3Qgc2hvdWxkIGNvbWUgb24gdGhpcyBwYWdlLiBFbHNlIG9uIGFub3RoZXIgcGFnZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7ICAgLy9JTSBvZiB0aGlzIGhpZGRlbiBzZj8uCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoIXRoaXMuX2lzUGFpbnRhYmxlKGxhc3RTaWJsaW5nKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgICAgICAgICBsYXN0UGFpbnRhYmxlU2libGluZyA9IGxhc3RTaWJsaW5nOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZighbGFzdFBhaW50YWJsZVNpYmxpbmcpewogICAgICAgICAgICAgICAgICAgIC8vVGhpcyBoaWRkZW4gY2hpbGQgbW9kZWwgaXMgZmlyc3QgcGFpbnRhYmxlIGNoaWxkIG9mIHRoaXMuIElmIHRoaXMgbGF5b3V0IGVsZW1lbnQgaXMgZmlyc3QgcGFydCBvZiB0aGlzIG1vZGVsIGxheW91dAogICAgICAgICAgICAgICAgICAgIC8vIFRoZW4gaGlkZGVuIGNoaWxkIHNob3VsZCBiZSBwYWludGVkIGluIHRoaXMgcGFnZS92aWV3LiBFbHNlIGluIG90aGVyIHZpZXcuCiAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5nZXRPckVsc2UodGhpcy5sYXlvdXRNb2RlbCwgIm9jY3VySW5kZXgiLCAwKSA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vRWxzZSBpZiAqbGFzdCBwYXJ0IG9mIGxhc3QgcGFpbnRhYmxlIHNpYmxpbmcqIG9mIHRoaXMgaGlkZGVuIG5vZGUgYmVsb25nIHRvIHRoaXMgbGF5b3V0IHRlbXBsYXRlIHRoZW4gdGhpcyBoaWRkZW4gbm9kZSB3b3VsZCBhbHNvIGJlbG9uZyBoZXJlLgogICAgICAgICAgICAgICAgICAgIHZhciBsYXN0U2libGluZ1ZhbGlkID0gdGhpcy5fdmFsaWRhdGVMYXlvdXRUZW1wbGF0ZShsYXN0UGFpbnRhYmxlU2libGluZyk7CiAgICAgICAgICAgICAgICAgICAgaWYobGFzdFNpYmxpbmdWYWxpZCl7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsYXN0U2libGluZ1RlbXBsYXRlSWQgPSBsYXN0UGFpbnRhYmxlU2libGluZy5fdGVtcGxhdGVJZCgpOwogICAgICAgICAgICAgICAgICAgICAgICBpZighdGhpcy5sYXlvdXRUZW1wbGF0ZVtsYXN0U2libGluZ1RlbXBsYXRlSWRdLmhhc0xhc3RQYXJ0T3ZlcmZsb3cpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlRXZlbnQ6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgc3dpdGNoKGV2bnQubmFtZSkgewogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuQ0hJTERfQURERUQ6CiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVDaGlsZEFkZGVkKGV2bnQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuQ0hJTERfUkVNT1ZFRDoKICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZUNoaWxkUmVtb3ZlZChldm50KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgeGZhbGliLnNjcmlwdC5YZmFNb2RlbEV2ZW50LkNISUxEX01PVkVEOgogICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlQ2hpbGRNb3ZlZChldm50KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLmhhbmRsZUV2ZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYW5kbGVEb21DaGFuZ2VkIDpmdW5jdGlvbihldmVudCl7CiAgICAgICAgICAgIHN3aXRjaChldmVudC5fcHJvcGVydHkpIHsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuQmFzZVZpZXcucHJvdG90eXBlLmhhbmRsZURvbUNoYW5nZWQuYXBwbHkodGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGhhbmRsZU1vZGVsQ2hhbmdlZCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIGlmIChldmVudC5fcHJvcGVydHkgPT0gImZpbGxDb2xvciIpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2ZpbGxDb2xvcihldmVudC5uZXdUZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChldmVudC5fcHJvcGVydHkgPT0gImJvcmRlckNvbG9yIikgewogICAgICAgICAgICAgICAgdGhpcy5fYm9yZGVyQ29sb3IoZXZlbnQubmV3VGV4dCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyplbHNlIGlmIChldmVudC5fcHJvcGVydHkgPT0gImJvcmRlcldpZHRoIikgewogICAgICAgICAgICAgICAgdGhpcy5fYm9yZGVyV2lkdGgoZXZlbnQubmV3VGV4dCk7CiAgICAgICAgICAgIH0gICAgICovCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5oYW5kbGVNb2RlbENoYW5nZWQuYXBwbHkodGhpcywKICAgICAgICAgICAgICAgICAgICBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIC8qX2JvcmRlcldpZHRoIDogZnVuY3Rpb24od2lkdGgpIHsKICAgICAgICAgICAgJCh0aGlzLmVsKS5jc3MoImJvcmRlcldpZHRoIiwgd2lkdGgpCiAgICAgICAgfSwgICAgICAgICAgKi8KCiAgICAgICAgaGFuZGxlQ2hpbGRBZGRlZCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHZhciBhZGRlZENoaWxkICA9IGV2ZW50Lm5ld1RleHQ7CiAgICAgICAgICAgIHZhciBjaGlsZFRlbXBsYXRlSWQgPSBhZGRlZENoaWxkLl90ZW1wbGF0ZUlkKCk7CiAgICAgICAgICAgIGlmKCF0aGlzLmxheW91dFRlbXBsYXRlLmhhc1RlbXBsYXRlIHx8ICh0aGlzLmxheW91dFRlbXBsYXRlLmhhc093blByb3BlcnR5KGNoaWxkVGVtcGxhdGVJZCkgJiYgYWRkZWRDaGlsZC5pbnN0YW5jZUluZGV4ID49ICB0aGlzLmxheW91dFRlbXBsYXRlW2NoaWxkVGVtcGxhdGVJZF0uc3RhcnQgJiYKICAgICAgICAgICAgICAgICh0aGlzLmxheW91dFRlbXBsYXRlW2NoaWxkVGVtcGxhdGVJZF0uZW5kIDwgMCB8fCBhZGRlZENoaWxkLmluc3RhbmNlSW5kZXggPD0gdGhpcy5sYXlvdXRUZW1wbGF0ZVtjaGlsZFRlbXBsYXRlSWRdLmVuZCkpKXsKICAgICAgICAgICAgICAgIC8vSWYgYWRkZWQgY2hpbGQgcmVzaWRlcyBpbiB0aGUgcmFuZ2Ugc3VwcG9ydGVkIGJ5IHRoaXMgdmlldywgc3luYyBpdC4KICAgICAgICAgICAgICAgIHRoaXMuX3N5bmNGb3JtTm9kZVRvSHRtbChmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5kZWJ1ZyggInhmYVZpZXciLCJUaGlzIGluc3RhbmNlTWFuYWdlciBoYXMgbm8gY2hpbGQgaW4gdGhpcyBsYXlvdXQgdGVtcGxhdGUuIFRoaXMgd291bGQgYmUgaGFuZGxlZCBpbiBvdGhlciBwYXJ0IG9mIHNwbGl0dGVkIHN1YmZvcm0uIGVsIGlkOiIrdGhpcy5faWQpOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZUNoaWxkTW92ZWQgOiBmdW5jdGlvbihldmVudCkgewogICAgICAgICAgICB0aGlzLl9zeW5jRm9ybU5vZGVUb0h0bWwodHJ1ZSk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlQ2hpbGRSZW1vdmVkIDogZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgICAgICAgdmFyIHJlbW92ZWRDaGlsZCA9IGV2ZW50LnByZXZUZXh0OwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBOb3RlL0hhY2s6IFRvIGdldCB0aGUgdGVtcGxhdGVJZCBvZiByZW1vdmVkQ2hpbGQsIHdlIGNhbiBub3Qgc2ltcGx5IGFzayBjaGlsZC5fdGVtcGxhdGVJZCgpIGFzIHRoaXMgd291bGQgcmV0dXJuIHRlbXBsYXRlIElkIG9mIG9ubHkgdGhvc2UKICAgICAgICAgICAgICAqIG5vZGVzIHdoaWNoIGFyZSBzdGlsbCBjb25uZWN0ZWQgdG8geGZhIGRvbS4gU2luY2UgcmVtb3ZlIGNoaWxkIGlzIGRpc2Nvbm5lY3RlZCBmcm9tIHhmYSwgd2UgYXJlIGFza2luZyB0ZW1wbGF0ZSBJZCBvZiB0aGlzIGZyb20gaXQncyBpbnN0YW5jZU1hbmFnZQogICAgICAgICAgICAgICogd2hpY2ggaXMgc3RpbGwgdGhlcmUuIEEgd29ya2Fyb3VuZCBmb3Igbm93LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdmFyIGNoaWxkVGVtcGxhdGVJZCA9IHJlbW92ZWRDaGlsZC5pbnN0YW5jZU1hbmFnZXIuX2luc3RhbmNlVGVtcGxhdGUoKS5leHRyYXMuaHRtbElkOwogICAgICAgICAgICBpZighdGhpcy5sYXlvdXRUZW1wbGF0ZS5oYXNUZW1wbGF0ZSB8fCAodGhpcy5sYXlvdXRUZW1wbGF0ZS5oYXNPd25Qcm9wZXJ0eShjaGlsZFRlbXBsYXRlSWQpICYmCiAgICAgICAgICAgICAgICAodGhpcy5sYXlvdXRUZW1wbGF0ZVtjaGlsZFRlbXBsYXRlSWRdLmVuZCA8IDAgfHwgcmVtb3ZlZENoaWxkLmluc3RhbmNlSW5kZXggPD0gdGhpcy5sYXlvdXRUZW1wbGF0ZVtjaGlsZFRlbXBsYXRlSWRdLmVuZCkpKXsKICAgICAgICAgICAgICAgIC8vSWYgdGhlIHJlbW92ZWQgY2hpbGQgaGFzIGluc3RhbmNlSW5kZXggbGVzcyB0aGFuIHRoZSBlbmQgcmFuZ2UgdGhlbiB0aGVyZSBpcyBwb3RlbnRpYWwgZm9yIHJlbGF5b3V0IG9mIHRoaXMgcGFnZS4gU28gc3luIGl0LgogICAgICAgICAgICAgICAgdGhpcy5fc3luY0Zvcm1Ob2RlVG9IdG1sKGZhbHNlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmRlYnVnKCAieGZhVmlldyIsIlRoaXMgaW5zdGFuY2VNYW5hZ2VyIGhhcyBubyBjaGlsZCBpbiB0aGlzIGxheW91dCB0ZW1wbGF0ZS4gVGhpcyB3b3VsZCBiZSBoYW5kbGVkIGluIG90aGVyIHBhcnQgb2Ygc3BsaXR0ZWQgc3ViZm9ybS4gZWwgaWQ6Iit0aGlzLl9pZCk7CiAgICAgICAgfSwKCiAgICAgICAgZGVzdHJveSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgLy9UT0RPOiBJbXBsZW1lbnQgYW5kIGNhbGwgZGVzdHJveSBtZXRob2QKICAgICAgICB9LAoKICAgICAgICBfaXNBbm9ueW1vdXMgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIF9ub3JtYWxpemVkQ2hpbGRWaWV3cyA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgbm9ybWFsaXplZENoaWxkVmlld3MgPSBbXTsKICAgICAgICAgICAgXy5mb2xkbCh0aGlzLmNoaWxkVmlld3MsIGZ1bmN0aW9uKG1lbW8sIGNoaWxkVmlldywgaW5kZXgpewogICAgICAgICAgICAgICAgaWYoY2hpbGRWaWV3IGluc3RhbmNlb2YgeGZhbGliLnZpZXcuQ29udGFpbmVyVmlldyAmJiBjaGlsZFZpZXcuX2lzQW5vbnltb3VzKCkpewogICAgICAgICAgICAgICAgICAgIF8uZWFjaChjaGlsZFZpZXcuX25vcm1hbGl6ZWRDaGlsZFZpZXdzKCksIGZ1bmN0aW9uKG5vcm1hbGl6ZWRDaGlsZCl7CiAgICAgICAgICAgICAgICAgICAgICAgIG1lbW8ucHVzaChub3JtYWxpemVkQ2hpbGQpOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZighdGhpcy5faXNIaWRkZW4oY2hpbGRWaWV3Lm1vZGVsKSl7CiAgICAgICAgICAgICAgICAgICAgbWVtby5wdXNoKGNoaWxkVmlldyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gbWVtbzsKICAgICAgICAgICAgfSwgbm9ybWFsaXplZENoaWxkVmlld3MsIHRoaXMpOwogICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplZENoaWxkVmlld3M7CiAgICAgICAgfSwKCiAgICAgICAgX2lzSGlkZGVuIDogZnVuY3Rpb24obW9kZWwpewogICAgICAgICAgICAvL21vZGVsIGNhbiBiZSBhIE5vZGUgb2JqZWN0IG9yIHNpbXBseSBhIGpzb24KICAgICAgICAgICAgaWYobW9kZWwgJiYgKG1vZGVsLnByZXNlbmNlID09ICJoaWRkZW4iIHx8IG1vZGVsLnByZXNlbmNlID09ICJpbmFjdGl2ZSIpKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfaXNQYWludGFibGUgOiBmdW5jdGlvbihtb2RlbCl7CiAgICAgICAgICAgIC8vY2FuIHRoaXMgbW9kZWwgaGF2ZSB2aXN1YWwgcmVwcmVzZW50YXRpb24KICAgICAgICAgICAgaWYobW9kZWwgJiYgbW9kZWwuaXNDb250YWluZXIgJiYgbW9kZWwuY2xhc3NOYW1lICE9ICJ2YXJpYWJsZXMiKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBtZWFzdXJlU2l6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0KQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0Lm1lYXN1cmVTaXplKCk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBpbnZhbGlkYXRlU2l6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0KQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0LmludmFsaWRhdGVTaXplKCk7CiAgICAgICAgfSwKCiAgICAgICAgdXBkYXRlRGlzcGxheSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0KQogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0LnVwZGF0ZURpc3BsYXkoKTsKICAgICAgICB9LAoKICAgICAgICAkZWxjaGlsZHJlbiA6IGZ1bmN0aW9uKGlkKSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLiRlbC5jaGlsZHJlbihpZCk7CiAgICAgICAgfQoKCiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICAvL0ludGVybWVkaWF0ZSBoaWVyYXJjaHkgdG8gZXh0cmFjdCBvdXQgY29tbW9uIGNvZGUgZm9yIFBhZ2VWaWV3L0NvbnRlbnRBcmVhVmlldy9Sb290U3ViZm9ybVZpZXcKICAgIHhmYWxpYi52aWV3LkxheW91dENvbnRhaW5lclZpZXcgPSB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3LmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHRoaXMuZ3Jvd2FibGVWaWV3ID0gW107IC8vIEVsZW1lbnQgdGhhdCBjYW4gZ3JvdyBiZXlvbmQgYm91bmRhcnkuIEN1cnJlbnQgYXNzdW1wdGlvbiBpcyB0aGF0IHRoZXJlIGNhbiBiZSBvbmx5IG9uZSBzdWNoIGVsZW1lbnQgaW4gQ29udGVudEFyZWEvUGFnZUFyZWEKICAgICAgICAgICAgeGZhbGliLnZpZXcuQ29udGFpbmVyVmlldy5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgIH0sCgogICAgICAgIF9zeW5jRm9ybU5vZGVUb0h0bWw6IGZ1bmN0aW9uKGRlZXBTeW5jKXsKICAgICAgICAgICAgaWYodGhpcy5jaGlsZFZpZXdzID09IG51bGwgfHwgdGhpcy5jaGlsZFZpZXdzLmxlbmd0aCA9PSAwKXsKICAgICAgICAgICAgICAgIHRoaXMuY2hpbGRWaWV3cyA9IFtdOwogICAgICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICAgICAgdmFyIGNlbGxJbmRleCA9IDA7CiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuJGVsLmlzKCI6ZW1wdHkiKSkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuY2hpbGRWaWV3cyA9IHRoaXMuJGVsLmNoaWxkcmVuKCkubWFwKGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRWaWV3ID0gdGhhdC5feGZhVmlld1JlZ2lzdHJ5KCkuY3JlYXRlVmlldyh0aGlzLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRWaWV3OiB0aGF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVDZWxsSW5kZXggOiBjZWxsSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTnVtYmVyOiB0aGF0Ll9wYWdlTnVtYmVyKCkKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGxJbmRleCA9IGNlbGxJbmRleCArIChjaGlsZFZpZXcubGF5b3V0TW9kZWwuY29sc3BhbiB8fCAxKTsgLy9BZGQgdGhlIGNvbHNwYW4gb3Igb25lCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHRoYXQuX2lzR3Jvd2FibGVWaWV3KGNoaWxkVmlldykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuZ3Jvd2FibGVWaWV3LnB1c2goY2hpbGRWaWV3KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGRWaWV3OwogICAgICAgICAgICAgICAgICAgIH0pLmdldCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgXy5lYWNoKHRoaXMuY2hpbGRWaWV3cywgZnVuY3Rpb24oY2hpbGRWaWV3KXsKICAgICAgICAgICAgICAgICAgICBjaGlsZFZpZXcuc3luY0Zvcm1Ob2RlVG9IdG1sKGRlZXBTeW5jKTsKICAgICAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkJhc2VWaWV3LnByb3RvdHlwZS5fc3luY0Zvcm1Ob2RlVG9IdG1sLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7ICAgLy9zeW5jIG90aGVyIHByb3BzIGJlZm9yZSBsYXlwdXQKICAgICAgICB9LAoKICAgICAgICBfaXNHcm93YWJsZVZpZXcgOmZ1bmN0aW9uKGNoaWxkVmlldyl7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBfZm9yY2VWaWV3OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgLy90aGlzIGZ1bmN0aW9uIGlzIHRvIGRpY3RhdGUgd2hldGhlciB0aGUgdmlldyBpcyBmb3JjZWQKICAgICAgICAgICAgLy93aWxsIGJlIHVzZWQgdG8gZm9yY2UgdGhlIHJlbmRlciBvZiBmaXJzdCBwYWdlIGF0IGxlYXN0LgogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwoKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB2YXIgU3ViZm9ybVZpZXcgPSB4ZmFsaWIudmlldy5TdWJmb3JtVmlldyA9IHhmYWxpYi52aWV3LkNvbnRhaW5lclZpZXcuZXh0ZW5kKHsKCiAgICAgICAgX2Fzc2lnblRvb2xUaXA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHRvb2xUaXBUZXh0ID0geGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLl9nZXRUb29sVGlwVGV4dCh0aGlzLm1vZGVsKTsKICAgICAgICAgICAgLy8gQ1EtNDIyMjk4MSA6IGFzc2lnbiB0b29sdGlwIGZvciBzdWJmb3JtIGhhdmluZyByb2xlIGFzIHRhYmxlIG9yIGl0IGlzIHRhYmxlCiAgICAgICAgICAgIGlmICh0b29sVGlwVGV4dCAmJiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuX3RhYmxlQ2hlY2tGb3JBY2Nlc3NpYmlsaXR5KHRoaXMpKSB7CiAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJ0aXRsZSIsIHRvb2xUaXBUZXh0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9KTsKCiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoU3ViZm9ybVZpZXcucHJvdG90eXBlLCAicmVzaXphYmxlIiwgewogICAgICAgIGdldCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIGlmKHRoaXMuX3Jlc2l6YWJsZSkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB2YXIgbGF5b3V0ID0gdGhpcy5sYXlvdXRNb2RlbC5sYXlvdXQ7CiAgICAgICAgICAgIGlmKGxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfTEVGVFJJR0hUVE9QQk9UVE9NIHx8IGxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfUklHSFRMRUZUVE9QQk9UVE9NIHx8IGxheW91dCA9PSB4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5MQVlPVVRfVE9QQk9UVE9NKQogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9LAoKICAgICAgICBzZXQgOiBmdW5jdGlvbihzVmFsdWUpewogICAgICAgICAgICB0aGlzLl9yZXNpemFibGUgPSBzVmFsdWU7CiAgICAgICAgfQogICAgfSk7Cgp9KShfLCAkLCB4ZmFsaWIpOyhmdW5jdGlvbihfLCAkLCB4ZmFsaWIpewogICAgdmFyIFN1YmZvcm1TZXRWaWV3ID0geGZhbGliLnZpZXcuU3ViZm9ybVNldFZpZXcgPSB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3LmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3LnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgfSwKCiAgICAgICAgX2lzQW5vbnltb3VzIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0sCgogICAgICAgICRjb21wdXRlV0ggOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgZXh0ZW50ID0ge307CiAgICAgICAgICAgIHJldHVybiBleHRlbnQ7CiAgICAgICAgfSwKCiAgICAgICAgX2NvbXB1dGVFeHRlbnQgOiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgLy9tYXJrIHRoZSBwb3NpdGlvbiBvZiB0aGUgc3ViZm9ybXNldCBhcyB0cmFuc3BhcmVudAogICAgICAgICAgICB2YXIgZXh0ZW50ID0geGZhbGliLnZpZXcuQ29udGFpbmVyVmlldy5wcm90b3R5cGUuX2NvbXB1dGVFeHRlbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgZXh0ZW50Wydwb3NpdGlvbiddID0gJ3N0YXRpYyc7CiAgICAgICAgICAgIHJldHVybiBleHRlbnQKICAgICAgICB9CiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsoZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LkNvbnRlbnRBcmVhVmlldyA9IHhmYWxpYi52aWV3LkxheW91dENvbnRhaW5lclZpZXcuZXh0ZW5kKHsKICAgICAgICBfaXNHcm93YWJsZVZpZXcgOmZ1bmN0aW9uKGNoaWxkVmlldyl7CiAgICAgICAgICAgIHJldHVybiAoY2hpbGRWaWV3Lm1vZGVsID09PSB0aGlzLl9mb3JtRG9tUm9vdCgpLmZvcm0uY2hpbGRyZW5bMF0pOyAvLyBJcyByb290IHN1YmZvcm0gb2YgdGhlIGZvcm0gZG9tCiAgICAgICAgfSwKCiAgICAgICAgX2luaXRpYWxpemVMYXlvdXRNb2RlbCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkxheW91dENvbnRhaW5lclZpZXcucHJvdG90eXBlLl9pbml0aWFsaXplTGF5b3V0TW9kZWwuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgLy9TcGVjaWFsIGhhbmRsaW5nIGZvciBlbmFibGluZyBzaHJpbmsgcGFnZSBmdW5jdGlvbmFsaXR5LiBXZSdsbCB0cmVhdCBjb250ZW50QXJlYSBhcyBUb3BCb3R0b24gZmxvd2FibGUgc3ViZm9ybS5CdWcjMzYwODc3MwogICAgICAgICAgICB0aGlzLmxheW91dE1vZGVsLmV4dGVudGFjdHVhbGggPSAtMTsKICAgICAgICAgICAgdGhpcy5yZXNpemFibGUgPSB0cnVlOwogICAgICAgIH0KCiAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB4ZmFsaWIudmlldy5QYWdlVmlldyA9IHhmYWxpYi52aWV3LkxheW91dENvbnRhaW5lclZpZXcuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB4ZmFsaWIudmlldy5MYXlvdXRDb250YWluZXJWaWV3LnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIC8qIEZsYWcgaW5kaWNhdGluZyB0aGF0IHRoZSB0YWJiaW5nIGNvbXB1dGF0aW9uIGZvciB0aGlzIFBhZ2Ugd291bGQgYmUgcmVkb25lICovCiAgICAgICAgICAgIHRoaXMuX3RhYkNvbXB1dGVQZW5kaW5nID0gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgX2luaXRMYXlvdXQgOiBmdW5jdGlvbigpewogICAgICAgICAgICB4ZmFsaWIudmlldy5MYXlvdXRDb250YWluZXJWaWV3LnByb3RvdHlwZS5faW5pdExheW91dC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICBpZih0aGlzLl9pbml0aWFsaXplZCl7CiAgICAgICAgICAgICAgICAvKiBXaGVuIGEgUGFnZSBWaWV3IGlzIGluaXRpYWxpemVkLCBpbW1lZGlhdGVseSBtYXJrIGl0IGZvciB0YWIgY29tcHV0ZSovCiAgICAgICAgICAgICAgICB0aGlzLmludmFsaWRhdGVUYWJJbmRleCgpOwogICAgICAgICAgICB9CiAgICAgICAgfSwKCiAgICAgICAgX2ZvcmNlVmlldzogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIC8vdGhpcyBmdW5jdGlvbiBpcyB0byBkaWN0YXRlIHdoZXRoZXIgdGhlIHZpZXcgaXMgZm9yY2VkCiAgICAgICAgICAgIC8vd2lsbCBiZSB1c2VkIHRvIGZvcmNlIHRoZSByZW5kZXIgb2YgZmlyc3QgcGFnZSBhdCBsZWFzdC4KICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhZ2VOdW1iZXIoKSA9PSAxOwogICAgICAgIH0sCgogICAgICAgIF9pc0dyb3dhYmxlVmlldyA6ZnVuY3Rpb24oY2hpbGRWaWV3KXsKICAgICAgICAgICAgcmV0dXJuIChjaGlsZFZpZXcgaW5zdGFuY2VvZiB4ZmFsaWIudmlldy5Db250ZW50QXJlYVZpZXcpOwogICAgICAgIH0sCgogICAgICAgIF9wYWdlTnVtYmVyIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgLyogUmV0dXJuIHRoZSBwYWdlIG51bWJlciB0aGF0IHdhcyBzZW50IGZyb20gc2VydmVyLiBQYWdlIE51bWJlciBzdGFydHMgd2l0aCAxLiovCiAgICAgICAgICAgIGlmKHRoaXMubGF5b3V0TW9kZWwpewogICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF5b3V0TW9kZWwucGFnZU51bWJlcjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSwKCiAgICAgICAgX2NvbXB1dGVFeHRlbnQgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgZXh0ZW50ID0geGZhbGliLnZpZXcuTGF5b3V0Q29udGFpbmVyVmlldy5wcm90b3R5cGUuX2NvbXB1dGVFeHRlbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgZXh0ZW50WyJwb3NpdGlvbiJdID0gInJlbGF0aXZlIjsKICAgICAgICAgICAgZXh0ZW50WyJtYXJnaW4tbGVmdCJdID0gImF1dG8iOyAgICAgICAgICAgICAgIC8vV2UgbmVlZCB0byBtYXJrIHBhZ2UgbWFyZ2lucyB0byBhdXRvIHRvIGFkanVzdCBwYWdlcyB3aXRoIGRpZmZlcmVudCBtYXN0ZXIgcGFnZSBsYXlvdXQKICAgICAgICAgICAgZXh0ZW50WyJtYXJnaW4tcmlnaHQiXSA9ICJhdXRvIjsKICAgICAgICAgICAgZXh0ZW50WyJtYXJnaW4tYm90dG9tIl0gPSAxMDsKICAgICAgICAgICAgZXh0ZW50WyJtYXJnaW4tdG9wIl0gPSB0aGlzLl9wYWdlTnVtYmVyKCkgPT0gMSA/IDAgOiAxMCA7CiAgICAgICAgICAgIHJldHVybiBleHRlbnQ7CiAgICAgICAgfSwKCiAgICAgICAgLyoKICAgICAgICAgKiBNYXJrcy9RdWV1ZXMgdGhlIFBhZ2UgZm9yIHJlLWNvbXB1dGUgb2YgdGFiIGluZGV4ZXMuIFJlLWNvbXB1dGF0aW9uIHdvdWxkIGF1dG9tYXRpY2FsbHkgYmUgZmlyZWQKICAgICAgICAgKiBhc3luY2hyb25vdXNseS4KICAgICAgICAgKi8KICAgICAgICBpbnZhbGlkYXRlVGFiSW5kZXggOiBmdW5jdGlvbihmb3JjZUNvbXB1dGUpIHsKICAgICAgICAgICAgaWYoIXRoaXMuX3RhYkNvbXB1dGVQZW5kaW5nIHx8IGZvcmNlQ29tcHV0ZSl7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogVGFiIGNvbXB1dGUgaW52YWxpZGF0aW9uIHNldHMgdGhlIHRhYkNvbXB1dGVQZW5kaW5nIGZsYWcgdG8gdHJ1ZSBhbmQgdGhlbiBmaXJlcyBhY3R1YWwgY29tcHV0YXRpb24gYXN5bmMKICAgICAgICAgICAgICAgICAqIHdheSBpbi1vcmRlciBmb3IgY2FzZXMgd2hlcmUgc2ltdWx0YW5lb3VzIGluLXZhbGlkYXRpb25zIG1heSBvY2N1ciBtdWx0aXBsZSB0aW1lcyBmb3IgZGlmZmVyZW50CiAgICAgICAgICAgICAgICAgKiBmaWVsZHMgb3IgcmVwZWF0YWJsZSBzdWJmb3JtIG9mIHRoZSBzYW1lIHBhZ2UuIEluIHRob3NlIGNhc2VzLCB3ZSB3YW50IHRvIGNvbXB1dGUgdGFiIGluZGV4ZXMgb25seSBvbmNlIHdoZW4KICAgICAgICAgICAgICAgICAqIGV2ZXJ5dGhpbmcgaXMgZG9uZS4KICAgICAgICAgICAgICAgICAqIEFub3RoZXIgdGhpbmcsIGlmIHRoZXJlIGlzIGFueSBsYXlvdXQgY29tcHV0YXRpb24gcGVuZGluZyBpbiBsYXlvdXQgbWFuYWdlciwgd2UgZGVmZXIgdGhlIHRhYiBjb21wdXRhdGlvbiB0aWxsCiAgICAgICAgICAgICAgICAgKiB0aGF0IGlzIGNvbXBsZXRlIHNpbmNlIHgseSBjYW4gY2hhbmdlIGluIHRob3NlIGNhc2VzLgogICAgICAgICAgICAgICAgICoqLwogICAgICAgICAgICAgICAgdGhpcy5fdGFiQ29tcHV0ZVBlbmRpbmcgPSB0cnVlOwogICAgICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmNsZWFyVGltZW91dE9uRGVzdHJveSgKICAgICAgICAgICAgICAgICAgICB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpewogICAgICAgICAgICAgICAgICAgICAgICBpZighdGhhdC5fbGF5b3V0TWFuYWdlci5pc0xheW91dEN5Y2xlQ29tcGxldGUoKSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2xheW91dCBjeWNsZSBydW5uaW5nIHNvIGRvIGEgZm9yY2UgaW52YWxpZGF0aW9uIHRvIGRlZmVyIHRhYiBjb21wdXRhdGlvbiB0byBuZXh0IGN5Y2xlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmludmFsaWRhdGVUYWJJbmRleCh0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdC5fY29tcHV0ZVRhYkluZGV4KCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9LCAxKQogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIF9jb21wdXRlVGFiSW5kZXggOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHRoaXMuX3RhYkNvbXB1dGVQZW5kaW5nID0gZmFsc2U7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LnV0aWwudHJhdmVyc2FsTWFuYWdlci5fY29tcHV0VGFiSW5kZXgodGhpcyk7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24gKF8sICQsIHhmYWxpYikgewogICAgeGZhbGliLnZpZXcuUm9vdFN1YmZvcm1WaWV3ID0geGZhbGliLnZpZXcuTGF5b3V0Q29udGFpbmVyVmlldy5leHRlbmQoewogICAgICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHBhZ2luZ0NvbmZpZyA9IHRoaXMuX3hmYVZpZXdSZWdpc3RyeSgpLnBhZ2luZ0NvbmZpZygpOwogICAgICAgICAgICB0aGlzLiRlbCA9ICh0aGlzLm9wdGlvbnMuZWwgaW5zdGFuY2VvZiAkKSA/IHRoaXMub3B0aW9ucy5lbCA6ICQodGhpcy5vcHRpb25zLmVsKTsKICAgICAgICAgICAgLy9tYWtlIHBhZ2luZyBkZWZhdWx0CiAgICAgICAgICAgIGlmIChwYWdpbmdDb25maWcucGFnaW5nRGlzYWJsZWQpIHsKICAgICAgICAgICAgICAgIF8uZWFjaCh0aGlzLm9wdGlvbnMucmVzdE9mVGhlUGFnZXMsIGZ1bmN0aW9uIChwYWdlRWwpIHsKICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmVkIGNyZWF0aW9uIG9mIGV4dHJhIHBhZ2UgdmlldyBhcyBjaGlsZFZpZXcsIG9uIGNvbnRhaW5lclZpZXcgaW5pdGlhbGl6ZSB3ZSBhbnl3YXlzIGluaXRpYWxpemUgY2hpbGRWaWV3IGFzIGVtcHR5IGFycmF5CiAgICAgICAgICAgICAgICAgICAgLy8gb24gc3luY0Zvcm1Ob2RlVG9IdG1sIHdlIGFyZSB1c2luZyAkZWwuY2hpbGRyZW4oKSB0byBjcmVhdGUgbmV3IGNoaWxkIHZpZXdzCiAgICAgICAgICAgICAgICAgICAgLy8gc28ganVzdCBhcHBlbmRpbmcgcmVzdCBvZiB0aGUgcGFnZXMgZWxlbWVudCBzaG91bGQgYmUgZW5vdWdoCiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZWwuYXBwZW5kKHBhZ2VFbCk7CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5vcHRpb25zICYmIHRoaXMub3B0aW9ucy5yZXN0T2ZUaGVQYWdlcykgewogICAgICAgICAgICAgICAgLy9kbyBub3RoaW5nLCBqdXN0IG1hcmsgcmVzdCBvZiB0aGUgcGFnZXMgYXMgZGVmZXJyZWQgcGFnZXMKICAgICAgICAgICAgICAgIHRoaXMuX2RlZmVycmVkUGFnZXMgPSB0aGlzLm9wdGlvbnMucmVzdE9mVGhlUGFnZXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoaXMudG90UGFnZXMgPSB0aGlzLmdldE9yRWxzZSh0aGlzLCAib3B0aW9ucy5yZXN0T2ZUaGVQYWdlcy5sZW5ndGgiLCAwKSArIDE7ICAvLyB0b2RvOiBmaXggdGhpcyB3aGVuIGluaXRpYWwgY291bnQgaXMgcHJlc2VudAovLyAgICAgICAgICAgIGNvbnNvbGUucHJvZmlsZSgiUDEiKTsKICAgICAgICAgICAgeGZhbGliLnZpZXcuTGF5b3V0Q29udGFpbmVyVmlldy5wcm90b3R5cGUuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwovLyAgICAgICAgICAgIGNvbnNvbGUucHJvZmlsZUVuZCgpOwoKICAgICAgICAgICAgLy9CdWcjMzY3MDM3MzogYSBjdXN0b20gZXZlbnQgaXMgdHJpZ2dlcmVkIGFmdGVyIHRoZSBmaXJzdCBwYWdlIGlzIGxvYWRlZC4KICAgICAgICAgICAgdmFyIF90cmlnZ2VyWGZhRmlyc3RQZ0xheW91dENvbXBsZXRlID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgdGhpcy5jaGlsZFZpZXdzWzBdLm9mZignbGF5b3V0Q29tcGxldGUnLCBfdHJpZ2dlclhmYUZpcnN0UGdMYXlvdXRDb21wbGV0ZSk7CiAgICAgICAgICAgICAgICAkKHdpbmRvdykudHJpZ2dlcigneGZhRmlyc3RQZ0xheW91dENvbXBsZXRlJyk7CiAgICAgICAgICAgICAgICB0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS5zY2FsZUZvcm0oKTsKICAgICAgICAgICAgfTsKICAgICAgICAgICAgdGhpcy5jaGlsZFZpZXdzWzBdLm9uKCdsYXlvdXRDb21wbGV0ZScsIF90cmlnZ2VyWGZhRmlyc3RQZ0xheW91dENvbXBsZXRlLCB0aGlzKTsKCiAgICAgICAgICAgIC8vYWNjZXNzaWJpbGl0eQogICAgICAgICAgICAvL2FkZCBmb3JtIHJvbGUgdG8gcm9vdFN1YmZvcm1WaWV3CiAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoInJvbGUiLCAiZm9ybSIpOwoKICAgICAgICAgICAgLy9hbHNvIGFkZCBsYW5nIGF0dHJpYnV0ZSBpbiBpdAogICAgICAgICAgICAvL2xlYXAgb2YgZmFpdGggLS0gZ2V0dGluZyB0aGUgcm9vdHN1YmZvcm0gb2YgdGhlIGZvcm0gbW9kZWwgYW5kIHRoZW4gc2V0IHRoZSBsYW5nIGF0dHJpYnV0ZQogICAgICAgICAgICBpZiAoeGZhbGliLnJ1bnRpbWUuZm9ybS5jaGlsZHJlblswXSAmJiB4ZmFsaWIucnVudGltZS5mb3JtLmNoaWxkcmVuWzBdLmpzb25Nb2RlbCAmJiB4ZmFsaWIucnVudGltZS5mb3JtLmNoaWxkcmVuWzBdLmxvY2FsZSkgewogICAgICAgICAgICAgICAgLy9hZGQgbGFuZyBwYXJhbWV0ZXIKICAgICAgICAgICAgICAgIHZhciBsYW5nID0gdGhpcy5fbGFuZ0Zyb21Mb2NhbGUoeGZhbGliLnJ1bnRpbWUuZm9ybS5jaGlsZHJlblswXS5sb2NhbGUpOwoKICAgICAgICAgICAgICAgIGlmIChsYW5nICYmIGxhbmcubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsLmF0dHIoImxhbmciLCBsYW5nKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICB9LAoKICAgICAgICBfY29tcHV0ZUV4dGVudDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4ge307CiAgICAgICAgfSwKCiAgICAgICAgcmVuZGVyRGVmZXJyZWRQYWdlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vYXNzZXJ0KHVzZXJDb25maWcgJiYgdXNlckNvbmZpZy5wYWdpbmdDb25maWcgJiYgdXNlckNvbmZpZy5wYWdpbmdDb25maWcucGFnaW5nRW5hYmxlZCk7CiAgICAgICAgICAgIGlmICh0aGlzLmhhc01vcmVEZWZlcnJlZFBhZ2VzKCkpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2p1c3QgbWFrZSBzdXJlIHdlIGhhdmUgbW9yZSB0aGFuIDEwIGJ5dGVzCiAgICAgICAgICAgICAgICAvL2NyZWF0ZSBkb20gaGVyZQogICAgICAgICAgICAgICAgdmFyIG5leHRQYWdlRWwgPSAkKHRoaXMuX2RlZmVycmVkUGFnZXMuc2hpZnQoKSk7CiAgICAgICAgICAgICAgICB2YXIgbmV4dFBhZ2VWaWV3ID0gdGhpcy5feGZhVmlld1JlZ2lzdHJ5KCkuY3JlYXRlVmlldyhuZXh0UGFnZUVsLCB7cGFyZW50VmlldzogdGhpc30pOwogICAgICAgICAgICAgICAgdGhpcy4kZWwuYXBwZW5kKG5leHRQYWdlRWwpOwogICAgICAgICAgICAgICAgdGhpcy5jaGlsZFZpZXdzID0gdGhpcy5jaGlsZFZpZXdzIHx8IFtdOwogICAgICAgICAgICAgICAgdGhpcy5jaGlsZFZpZXdzLnB1c2gobmV4dFBhZ2VWaWV3KTsKICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5fdHJpZ2dlck9uQnJpZGdlKCJlbGVtZW50UGFnZVJlbmRlcmVkIiwgeGZhbGliLnJ1bnRpbWUueGZhLmZvcm0uZm9ybTEsICJuZXh0UGFnZSIsIHRoaXMuY2hpbGRWaWV3cy5sZW5ndGgtMSwgdGhpcy5jaGlsZFZpZXdzLmxlbmd0aCk7CiAgICAgICAgICAgICAgICAvL3RoaXMuY2hpbGRWaWV3cy5sZW5ndGgtMSBpcyB0aGUgcGFnZSBudW1iZXIgdGlsbCB3aGljaCBmb3JtIGlzIGFscmVhZHkgcmVuZGVyZWQKICAgICAgICAgICAgICAgIC8vdGhpcy5jaGlsZFZpZXdzLmxlbmd0aCBpbmRpY2F0ZXMgdGhlIHBhZ2UgbnVtYmVyIG9mIGN1cnJlbnQgcGFnZSByZW5kZXJlZAogICAgICAgICAgICAgICAgLy9pZih3aW5kb3cuaGlnaGxpZ2h0KQogICAgICAgICAgICAgICAgLy8gICAgaGlnaGxpZ2h0RmllbGRzKCk7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV4dFBhZ2VWaWV3OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgIH0sCgogICAgICAgIGhhc01vcmVEZWZlcnJlZFBhZ2VzOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAodGhpcy5nZXRPckVsc2UodGhpcy5fZGVmZXJyZWRQYWdlcywgW10pLmxlbmd0aCA+IDApOwogICAgICAgIH0KICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LkV4Y2xHcm91cFZpZXcgPSB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3LmV4dGVuZCh7CiAgICAgICAgaW5pdGlhbGl6ZSA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkNvbnRhaW5lclZpZXcucHJvdG90eXBlLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgJCh0aGlzLiRlbCkub24oeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DTElDS19FVkVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkLnByb3h5KHRoaXMuaGFuZGxlQ2xpY2tFdmVudCx0aGlzKSk7CiAgICAgICAgfSwKCiAgICAgICAgaGFuZGxlQ2xpY2tFdmVudCA6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAvL3RoaXMubW9kZWwuZXhlY0V2ZW50KCJjbGljayIpOwogICAgICAgIH0sCgogICAgICAgIF9nZXRTY3JlZW5SZWFkZXJUZXh0IDogeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fZ2V0U2NyZWVuUmVhZGVyVGV4dCwKCiAgICAgICAgX2Fzc2lnblRvb2xUaXAgOiB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9hc3NpZ25Ub29sVGlwLAoKICAgICAgICBfaW5pdExheW91dCA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHhmYWxpYi52aWV3LkNvbnRhaW5lclZpZXcucHJvdG90eXBlLl9pbml0TGF5b3V0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIGlmKHRoaXMuX2luaXRpYWxpemVkKXsKICAgICAgICAgICAgICAgIHRoaXMubWFya01hbmRhdG9yeSgpOwogICAgICAgICAgICAgICAgdGhpcy4kZWwuYXR0cigicm9sZSIsICJyYWRpb2dyb3VwIik7IC8vYWRkIHJvbGUKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIG1hcmtNYW5kYXRvcnkgOiBmdW5jdGlvbigpewogICAgICAgICAgICBpZih0aGlzLm1vZGVsLm1hbmRhdG9yeT09ICJlcnJvciIpCiAgICAgICAgICAgICAgICBpZih0aGlzLiRlbCkKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbC5hdHRyKCJkYXRhLW1hbmRhdG9yeSIsICJ0cnVlIikgOwogICAgICAgIH0sCgogICAgICAgIGhhbmRsZU1vZGVsQ2hhbmdlZCA6IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQuX3Byb3BlcnR5KSB7CiAgICAgICAgICAgICAgICBjYXNlICJmb2N1cyI6CiAgICAgICAgICAgICAgICAgICAgdmFyIGNoaWxkVmlldyA9IHRoaXMuX2dldENoaWxkVG9Gb2N1cygpOwogICAgICAgICAgICAgICAgICAgIHRoaXMuX2ZvY3VzV2lkZ2V0KGNoaWxkVmlldyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJWYWxpZGF0aW9uU3RhdGUiOgogICAgICAgICAgICAgICAgICAgIHRoaXMuX21hcmtFcnJvcihldmVudCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlICJDbGVhckVycm9yIjoKICAgICAgICAgICAgICAgICAgICB0aGlzLl9jbGVhckVycm9yKGV2ZW50KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnZpZXcuQ29udGFpbmVyVmlldy5wcm90b3R5cGUuaGFuZGxlTW9kZWxDaGFuZ2VkLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYW5kbGVEb21DaGFuZ2VkOiBmdW5jdGlvbiAoZXZlbnQpIHsKICAgICAgICAgICAgc3dpdGNoIChldmVudC5fcHJvcGVydHkpIHsKICAgICAgICAgICAgICAgIGNhc2UgIm51bGxUZXN0IjoKICAgICAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9oYW5kbGVOdWxsVGVzdC5jYWxsKHRoaXMsIGV2ZW50LCB0aGlzLiRlbC5jbG9zZXN0KCcuZXhjbGdyb3VwJykpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB4ZmFsaWIudmlldy5Db250YWluZXJWaWV3LnByb3RvdHlwZS5oYW5kbGVEb21DaGFuZ2VkLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBfaGFuZGxlTWFuZGF0b3J5OiB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9oYW5kbGVNYW5kYXRvcnksCiAgICAgICAgX2hhbmRsZURpc2FibGVkOiB4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLl9oYW5kbGVEaXNhYmxlZCwKCiAgICAgICAgX21hcmtFcnJvciA6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgdGhpcy4kZWwuYWRkQ2xhc3MoIndpZGdldEVycm9yIik7CiAgICAgICAgfSwKCiAgICAgICAgX2NsZWFyRXJyb3IgOiBmdW5jdGlvbihldm50KSB7CiAgICAgICAgICAgIHRoaXMuJGVsLnJlbW92ZUNsYXNzKCJ3aWRnZXRFcnJvciIpOwogICAgICAgIH0sCgogICAgICAgIC8qCiAgICAgICAgICogQGZ1bmN0aW9uCiAgICAgICAgICogZ2V0IGNoaWxkIHZpZXcgb2YgZXhjbHVzaW9uIGdyb3VwIHdoaWNoIG5lZWRzIHRvIGJlIGZvY3Vzc2VkLgogICAgICAgICAqLwogICAgICAgIF9nZXRDaGlsZFRvRm9jdXMgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBfLmZpbmQodGhpcy5jaGlsZFZpZXdzLCBmdW5jdGlvbiAoY2hpbGRWaWV3KSB7CiAgICAgICAgICAgICAgICB2YXIgbW9kZWwgPSBjaGlsZFZpZXcubW9kZWw7CiAgICAgICAgICAgICAgICByZXR1cm4gKG1vZGVsICYmIG1vZGVsLnByZXNlbmNlID09ICJ2aXNpYmxlIiAmJiBtb2RlbC5tRWZmZWN0aXZlQWNjZXNzID09ICJvcGVuIik7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwovKioKICogQ3JlYXRlZCB3aXRoIEludGVsbGlKIElERUEuCiAqIFVzZXI6IHJwYW5kZXkKICogRGF0ZTogMTIvMjQvMTIKICogVGltZTogODoxNCBQTQogKiBUbyBjaGFuZ2UgdGhpcyB0ZW1wbGF0ZSB1c2UgRmlsZSB8IFNldHRpbmdzIHwgRmlsZSBUZW1wbGF0ZXMuCiAqLwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKICAgIHhmYWxpYi52aWV3LlNpZ25hdHVyZUZpZWxkVmlldyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5leHRlbmQoewogICAgICAgIF9jcmVhdGVQbHVnaW5PcHRpb25zIDogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciB2T3B0aW9ucyA9IHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX2NyZWF0ZVBsdWdpbk9wdGlvbnMuYXBwbHkodGhpcywKICAgICAgICAgICAgICAgIGFyZ3VtZW50cyk7CiAgICAgICAgICAgIHJldHVybiB2T3B0aW9uczsKICAgICAgICB9LAoKICAgICAgICBfY3JlYXRlRGVmYXVsdFdpZGdldFBsdWdpbiA6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgICAgICAgICAgJCh0aGlzLndpZGdldCkuc2lnbmF0dXJlRmllbGQob3B0aW9ucyk7CiAgICAgICAgICAgIHRoaXMuanFXaWRnZXQgPSB0aGlzLiRkYXRhKHRoaXMud2lkZ2V0LCAieGZhV2lkZ2V0LXNpZ25hdHVyZUZpZWxkIik7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOyhmdW5jdGlvbiAoXywgJCwgeGZhbGliKSB7CgogICAgeGZhbGliLnZpZXcuUGFnaW5nTWFuYWdlciA9IHhmYWxpYi52aWV3Lk9iamVjdFZpZXcuZXh0ZW5kKHsKCiAgICAgICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICB4ZmFsaWIudmlldy5PYmplY3RWaWV3LnByb3RvdHlwZS5pbml0aWFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgIHRoaXMuYXV0b1JlbmRlclBhZ2VIYW5kbGVyID0gbnVsbDsKICAgICAgICAgICAgdGhpcy5fYXV0b1BhZ2VSZW5kZXJQZW5kaW5nID0gZmFsc2U7CiAgICAgICAgfSwKCiAgICAgICAgcmVuZGVyTmV4dFBhZ2U6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzOwogICAgICAgICAgICB2YXIgcGFnZVZpZXcgPSB0aGlzLl9nZXRSb290VmlldygpLnJlbmRlckRlZmVycmVkUGFnZSgpOwogICAgICAgICAgICBpZiAocGFnZVZpZXcpIHsKICAgICAgICAgICAgICAgIHBhZ2VWaWV3Lm9uKCJsYXlvdXRDb21wbGV0ZSIsCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKGV2ZW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQudHJpZ2dlcigibmV3UGFnZVJlbmRlciIpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl94ZmFWaWV3UmVnaXN0cnkoKS5zY2FsZUZvcm0oKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBwYWdlVmlldzsKCiAgICAgICAgfSwKCiAgICAgICAgYXV0b1JlbmRlclBhZ2U6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKHRoaXMuYXV0b1JlbmRlclBhZ2VIYW5kbGVyKSB7CiAgICAgICAgICAgICAgICAvL0lkZWFsbHkgYXV0b1JlbmRlclBhZ2VIYW5kbGVyIHNob3VsZCBiZSBwb3N0cG9uZWQgdGlsbCBhbGwgcnVubmluZyBsYXlvdXQvZGlzcGxheSB2YWxpZGF0aW9uIGN5Y2xlcyBhcmUgZmluaXNoZWQgYW5kCiAgICAgICAgICAgICAgICAvL3RoZXJlIGlzIG5vIHBlbmRpbmcgbGF5b3V0IHZhbGlkYXRpb24uIEZvciBub3cgd2UgYXJlIGRvaW5nIGl0IGluIG5leHQgc2NyaXB0IGN5Y2xlL3NldFRpbWVvdXQuCiAgICAgICAgICAgICAgICB2YXIgYXV0b1JlbmRlckhhbmRsZXIgPSB0aGlzLmF1dG9SZW5kZXJQYWdlSGFuZGxlcjsKICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5jbGVhclRpbWVvdXRPbkRlc3Ryb3kod2luZG93LnNldFRpbWVvdXQoYXV0b1JlbmRlckhhbmRsZXIsIDEpKTsKICAgICAgICAgICAgICAgIHRoaXMuX2F1dG9QYWdlUmVuZGVyUGVuZGluZyA9IGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgdGhpcy5fYXV0b1BhZ2VSZW5kZXJQZW5kaW5nID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHNldEF1dG9SZW5kZXJQYWdlSGFuZGxlcjogZnVuY3Rpb24gKHZhbHVlKSB7CiAgICAgICAgICAgIGlmICh0aGlzLmF1dG9SZW5kZXJQYWdlSGFuZGxlciAhPSB2YWx1ZSkgewogICAgICAgICAgICAgICAgdGhpcy5hdXRvUmVuZGVyUGFnZUhhbmRsZXIgPSB2YWx1ZTsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmF1dG9SZW5kZXJQYWdlSGFuZGxlciAmJiB0aGlzLl9hdXRvUGFnZVJlbmRlclBlbmRpbmcpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmF1dG9SZW5kZXJQYWdlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBoYXNNb3JlUGFnZXM6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldFJvb3RWaWV3KCkuaGFzTW9yZURlZmVycmVkUGFnZXMoKTsKICAgICAgICB9LAoKICAgICAgICBfZ2V0Um9vdFZpZXc6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3hmYVZpZXdSZWdpc3RyeSgpLnJvb3RTdWJmb3JtVmlldzsKICAgICAgICB9LAoKICAgICAgICBwYWdlQ291bnQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgcmV0dXJuICh0aGlzLl9nZXRSb290VmlldygpLnRvdFBhZ2VzIHx8IDEpOwogICAgICAgIH0sCgogICAgICAgIF9tYWtlUGFnZTogZnVuY3Rpb24gKHBhZ2VOdW0pIHsKICAgICAgICAgICAgaWYgKHBhZ2VOdW0gPiB0aGlzLnBhZ2VDb3VudCgpKSB7CiAgICAgICAgICAgICAgICBwYWdlTnVtID0gdGhpcy5wYWdlQ291bnQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAocGFnZU51bSA+IHRoaXMuY3VycmVudFBhZ2UoKSkgewogICAgICAgICAgICAgICAgdmFyIGV4dFBhZ2VDb3VudHMgPSBwYWdlTnVtIC0gdGhpcy5jdXJyZW50UGFnZSgpOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBleHRQYWdlQ291bnRzOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbmRlck5leHRQYWdlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSwKCiAgICAgICAgY3VycmVudFBhZ2U6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIGIgPSB0aGlzLl9nZXRSb290VmlldygpLmNoaWxkVmlld3M7CiAgICAgICAgICAgIGlmICh4ZmFsaWIudmlldy5GaWVsZFZpZXcucHJvdG90eXBlLmN1cnJlbnRGb2N1cykgewogICAgICAgICAgICAgICAgdmFyIGEgPSAkKHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuY3VycmVudEZvY3VzLmVsKS5wYXJlbnRzKCIucGFnZSIpWzBdOwogICAgICAgICAgICAgICAgLy9UT0RPOiBUcnkgdG8gZG8gd2l0aG91dCBmb3IgTG9vcAogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiLmxlbmd0aDsgaSsrKQogICAgICAgICAgICAgICAgICAgIGlmIChiW2ldLmVsID09IGEpCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0sCgogICAgICAgIHBhZ2VEb3duOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmICh0aGlzLl9nZXRSb290VmlldygpLmhhc01vcmVEZWZlcnJlZFBhZ2VzKCkpIHsKICAgICAgICAgICAgICAgIHZhciBwYWdlVmlldyA9IHRoaXMucmVuZGVyTmV4dFBhZ2UoKTsKICAgICAgICAgICAgICAgIHRoaXMuX3BhZ2VEb3duKHBhZ2VWaWV3KTsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgdGhpcy5fcGFnZURvd24oKTsKCgogICAgICAgIH0sCgoKICAgICAgICBfcGFnZURvd246IGZ1bmN0aW9uIChwYWdlVmlldykgewogICAgICAgICAgICB2YXIgbmV4dFBhZ2UgPSB0aGlzLmN1cnJlbnRQYWdlKCkgKyAxOwogICAgICAgICAgICB2YXIgYSA9ICQoJCgiLnBhZ2UiKVtuZXh0UGFnZV0pOwogICAgICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgYS5vZmZzZXQoKS50b3ApOwogICAgICAgICAgICBwYWdlVmlldy5vZmYoImxheW91dENvbXBsZXRlIiwKICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChldmVudCkgewogICAgICAgICAgICAgICAgICAgIHRoYXQuX3BhZ2VEb3duKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICk7CiAgICAgICAgfSwKCiAgICAgICAgX21ha2VQYWdlRm9ySHRtbElkOiBmdW5jdGlvbiAoaHRtbElkLCBjYWxsYmFjaywgY29udGV4dCkgewogICAgICAgICAgICBpZiAoaHRtbElkID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIHZhciBub2RlU2VsZWN0b3IgPSB0aGlzLmpxSWQoaHRtbElkKTsKICAgICAgICAgICAgdmFyIHJvb3RWaWV3ID0gdGhpcy5fZ2V0Um9vdFZpZXcoKTsKICAgICAgICAgICAgdmFyIG5vZGVFbEFycmF5ID0gcm9vdFZpZXcuJGVsLmZpbmQobm9kZVNlbGVjdG9yKTsKICAgICAgICAgICAgaWYgKG5vZGVFbEFycmF5Lmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykKICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5hcHBseShjb250ZXh0KTsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgoKICAgICAgICAgICAgdmFyIHBhZ2VGb3VuZCA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAodGhpcy5oYXNNb3JlUGFnZXMoKSkgewogICAgICAgICAgICAgICAgdmFyIHZpZXcgPSByb290Vmlldy5yZW5kZXJEZWZlcnJlZFBhZ2UoKTsKICAgICAgICAgICAgICAgIGlmICh2aWV3LiRlbC5maW5kKG5vZGVTZWxlY3RvcikubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykKLy9MQy00NDI0IFdlIGFyZSBzZW5kaW5nIHRoZSBldmVudCBsYXlvdXRDb21wbGV0ZSB0aGF0IHRoZSBsYXlvdXQgaXMgY29tcGxldGUgZnJvbSBvdXIgdmlldyBwb2ludCBidXQgdGhlCi8vIGJyb3dzZXIgaGFzIG5vdCB5ZXQgcGFpbnRlZCB0aGUgcGFnZSggQ2hyb21lKSBhbmQgaGVuY2UgdGhlIGZvY3VzIGlzIGNvbWluZyBhdCB0aGUgd3JvbmcgcGxhY2UuCiAgICAgICAgICAgICAgICAgICAgICAgIHZpZXcub24oImxheW91dENvbXBsZXRlIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmNsZWFyVGltZW91dE9uRGVzdHJveSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmFwcGx5KGNvbnRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICBwYWdlRm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChwYWdlRm91bmQpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0sCgogICAgICAgIGZpbmRQYWdlOiBmdW5jdGlvbiAoaHRtbElkKSB7CiAgICAgICAgICAgIGlmIChodG1sSWQgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgdmFyIG5vZGVTZWxlY3RvciA9IHRoaXMuanFJZChodG1sSWQpOwogICAgICAgICAgICB2YXIgcm9vdFZpZXcgPSB0aGlzLl9nZXRSb290VmlldygpOwogICAgICAgICAgICB2YXIgaSA9IDA7CiAgICAgICAgICAgIGZvciAoOyBpIDwgcm9vdFZpZXcuY2hpbGRWaWV3cy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIG5vZGVFbEFycmF5ID0gJChyb290Vmlldy5jaGlsZFZpZXdzW2ldLmVsKS5maW5kKG5vZGVTZWxlY3Rvcik7CiAgICAgICAgICAgICAgICBpZiAobm9kZUVsQXJyYXkubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHdoaWxlICh0aGlzLmhhc01vcmVQYWdlcygpKSB7CiAgICAgICAgICAgICAgICByb290Vmlldy5yZW5kZXJEZWZlcnJlZFBhZ2UoKTsKICAgICAgICAgICAgICAgIHZhciBub2RlRWxBcnJheSA9ICQocm9vdFZpZXcuY2hpbGRWaWV3c1tpXS5lbCkuZmluZChub2RlU2VsZWN0b3IpOwogICAgICAgICAgICAgICAgaWYgKG5vZGVFbEFycmF5Lmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIGdldExheW91dDogZnVuY3Rpb24gKGh0bWxJZCkgewogICAgICAgICAgICBpZiAoaHRtbElkID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIHZhciBub2RlU2VsZWN0b3IgPSB0aGlzLmpxSWQoaHRtbElkKTsKICAgICAgICAgICAgdmFyIHJvb3RWaWV3ID0gdGhpcy5fZ2V0Um9vdFZpZXcoKTsKICAgICAgICAgICAgdmFyIGVsID0gcm9vdFZpZXcuJGVsLmZpbmQobm9kZVNlbGVjdG9yKTsKICAgICAgICAgICAgaWYgKGVsLmdldCgwKSkgewogICAgICAgICAgICAgICAgdmFyIGxheW91dCA9IHRoaXMuZ2V0T3JFbHNlKHRoaXMuJGRhdGEoZWwuZ2V0KDApLCAieGZhVmlldyIpLCB7fSk7CiAgICAgICAgICAgICAgICByZXR1cm4gbGF5b3V0LmxheW91dE1vZGVsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgcmV0dXJuIG51bGw7CgogICAgICAgIH0sCgogICAgICAgIF9wYWdlQ29udGVudDogZnVuY3Rpb24gKHBhZ2VOdW0sIGNsYXNzTmFtZSwgYlBhZ2VBcmVhKSB7CiAgICAgICAgICAgIGJQYWdlQXJlYSA9IGJQYWdlQXJlYSB8fCBmYWxzZTsKICAgICAgICAgICAgdGhpcy5fbWFrZVBhZ2UocGFnZU51bSk7CiAgICAgICAgICAgIHZhciBwYWdlVmlldyA9IHRoaXMuX2dldFJvb3RWaWV3KCkuY2hpbGRWaWV3c1twYWdlTnVtXTsKICAgICAgICAgICAgdmFyIGNvbnRlbnRMaXN0ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICBpZiAocGFnZVZpZXcubW9kZWwgJiYgKCFjbGFzc05hbWUgfHwgY2xhc3NOYW1lID09ICJwYWdlQXJlYSIpKSB7CiAgICAgICAgICAgICAgICBjb250ZW50TGlzdC5fYXBwZW5kKHBhZ2VWaWV3Lm1vZGVsKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWJQYWdlQXJlYSkgewogICAgICAgICAgICAgICAgZm9yICh2YXIgcHYgaW4gcGFnZVZpZXcuY2hpbGRWaWV3cykgewogICAgICAgICAgICAgICAgICAgIGlmIChwYWdlVmlldy5jaGlsZFZpZXdzW3B2XSBpbnN0YW5jZW9mICB4ZmFsaWIudmlldy5Db250ZW50QXJlYVZpZXcpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudExpc3QuX2NvbmNhdCh0aGlzLiRwYWdlQ29udGVudChwYWdlVmlldy5jaGlsZFZpZXdzW3B2XSwgY2xhc3NOYW1lLCBiUGFnZUFyZWEpKTsgICAvL1JhdGhlciB0aGFuIHBhc3NpbmcgdGhlIHBhZ2VBcmVhLCB3ZSBhcmUgcGFzc2luZyBvbmx5IGNvbnRlbnRBcmVhCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNvIHRoYXQgaXQgcmV0dXJucyBhbGwgbm9uLXBhZ2VBcmVhIGNvbnRlbnQgbm9kZXMKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnRMaXN0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbnRlbnRMaXN0Ll9jb25jYXQodGhpcy4kcGFnZUNvbnRlbnQocGFnZVZpZXcsIGNsYXNzTmFtZSwgYlBhZ2VBcmVhKSk7CiAgICAgICAgICAgIHJldHVybiBjb250ZW50TGlzdDsKICAgICAgICB9LAoKICAgICAgICAkbm9kZUNvbnRlbnQ6IGZ1bmN0aW9uIChub2RlLCBjbGFzc05hbWUsIGJQYWdlQXJlYSkgewogICAgICAgICAgICAvL3Byb2Nlc3MgY2hpbGQgbm9kZXMKICAgICAgICAgICAgdmFyIGNvbnRlbnRMaXN0ID0gbmV3IHhmYWxpYi5zY3JpcHQuWGZhTGlzdCgpOwogICAgICAgICAgICBpZiAobm9kZSkgewogICAgICAgICAgICAgICAgXy5lYWNoKG5vZGUuY2hpbGRyZW4sIGZ1bmN0aW9uIChub2RlQ2hpbGQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIWNsYXNzTmFtZSAmJiBub2RlQ2hpbGQuaXNDb250YWluZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudExpc3QuX2FwcGVuZChub2RlQ2hpbGQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChub2RlQ2hpbGQuY2xhc3NOYW1lID09IGNsYXNzTmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50TGlzdC5fYXBwZW5kKG5vZGVDaGlsZCk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAobm9kZUNoaWxkLmlzQ29udGFpbmVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlQ2hpbGRDb250ZW50TGlzdCA9IHRoaXMuJG5vZGVDb250ZW50KG5vZGVDaGlsZCwgY2xhc3NOYW1lLCBiUGFnZUFyZWEpOwogICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50TGlzdC5fY29uY2F0KG5vZGVDaGlsZENvbnRlbnRMaXN0KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LCB0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY29udGVudExpc3Q7CiAgICAgICAgfSwKCiAgICAgICAgJHBhZ2VDb250ZW50OiBmdW5jdGlvbiAodmlldywgY2xhc3NOYW1lLCBiUGFnZUFyZWEpIHsKCiAgICAgICAgICAgIHZhciBjb250ZW50TGlzdCA9IG5ldyB4ZmFsaWIuc2NyaXB0LlhmYUxpc3QoKTsKICAgICAgICAgICAgLy9wcm9jZXNzIGNoaWxkIG5vZGVzCiAgICAgICAgICAgIGlmIChiUGFnZUFyZWEgJiYgdmlldyBpbnN0YW5jZW9mIHhmYWxpYi52aWV3LkNvbnRlbnRBcmVhVmlldykKICAgICAgICAgICAgICAgIHJldHVybiBjb250ZW50TGlzdDsgICAgICAvLyBCcmVha2luZyB0aGUgcmVjdXJzaW9uIGhlcmUsIHNvIHRoYXQgaXQgd2lsbCByZXR1cm4gb25seSBwYWdlQXJlYSBjb250ZW50IG5vZGVzCiAgICAgICAgICAgIF8uZWFjaCh2aWV3LmNoaWxkVmlld3MsIGZ1bmN0aW9uIChjaGlsZFZpZXcpIHsKICAgICAgICAgICAgICAgIGlmIChjaGlsZFZpZXcubW9kZWwpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRNb2RlbCA9IGNoaWxkVmlldy5tb2RlbDsKICAgICAgICAgICAgICAgICAgICBpZiAoIWNsYXNzTmFtZSAmJiBjaGlsZE1vZGVsLmlzQ29udGFpbmVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRMaXN0Ll9hcHBlbmQoY2hpbGRNb2RlbCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGlsZE1vZGVsLmNsYXNzTmFtZSA9PSBjbGFzc05hbWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudExpc3QuX2FwcGVuZChjaGlsZE1vZGVsKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvL1RpbWUgdG8gcmVjdXJzZQoKICAgICAgICAgICAgICAgIGlmIChjaGlsZFZpZXcuX2lzUGxhY2VIb2xkZXJFbCgpICYmIGNoaWxkVmlldy5tb2RlbCkgewogICAgICAgICAgICAgICAgICAgIC8vRm9yIGhpZGRlbiB2aWV3cyB0aGF0IGhhdmUgbmV2ZXIgYmVlbiBpbml0aWFsaXplZCwgd2Ugd291bGQgd2FudCB0byByZXR1cm4gYWxsIGNvbnRhaW5lZCBub2RlcyBzaW5jZSB3ZSBzdGl0Y2gKICAgICAgICAgICAgICAgICAgICAvL2hpZGRlbiBub2RlIHRvZ2V0aGVyIGluIGZpcnN0IHBhZ2UuCiAgICAgICAgICAgICAgICAgICAgY29udGVudExpc3QuX2NvbmNhdCh0aGlzLiRub2RlQ29udGVudChjaGlsZFZpZXcubW9kZWwsIGNsYXNzTmFtZSwgYlBhZ2VBcmVhKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjb250ZW50TGlzdC5fY29uY2F0KHRoaXMuJHBhZ2VDb250ZW50KGNoaWxkVmlldywgY2xhc3NOYW1lLCBiUGFnZUFyZWEpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgIH0sIHRoaXMpOwogICAgICAgICAgICByZXR1cm4gY29udGVudExpc3Q7CiAgICAgICAgfQoKICAgIH0pOwp9KShfLCAkLCB4ZmFsaWIpOwooZnVuY3Rpb24oXywgJCwgeGZhbGliKXsKCiAgICAgICAgeGZhbGliLnZpZXcuRGF0YVRhYmxlVmlldyA9IHhmYWxpYi52aWV3LkNvbnRhaW5lclZpZXcuZXh0ZW5kKHsKCiAgICAgICAgJGVsY2hpbGRyZW4gOiBmdW5jdGlvbihpZCkgewogICAgICAgICAgICByZXR1cm4gdGhpcy4kZWwuY2hpbGRyZW4oKS5jaGlsZHJlbihpZCk7CiAgICAgICAgfSwKCiAgICAgICAgX2dldFNjcmVlblJlYWRlclRleHQ6IHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuX2dldFNjcmVlblJlYWRlclRleHQsCgogICAgICAgIF9hc3NpZ25Ub29sVGlwIDogeGZhbGliLnZpZXcuRmllbGRWaWV3LnByb3RvdHlwZS5fYXNzaWduVG9vbFRpcAoKICAgICAgICB9KTsKfSkoXywgJCwgeGZhbGliKTsKKGZ1bmN0aW9uKF8sICQsIHhmYWxpYil7CiAgICB2YXIgcm9vdCA9IHdpbmRvdzsKICAgIHJvb3QueGZhVmlld1JlZ2lzdHJ5ID0gKGZ1bmN0aW9uKCl7CiAgICAgICAgdmFyIF90ZW1wbGF0ZUNhY2hlID0gbmV3IHhmYWxpYi52aWV3LnV0aWwuSHRtbFRlbXBsYXRlQ2FjaGUoKTsKICAgICAgICB2YXIgX2xheW91dE1hbmFnZXIgPSBuZXcgeGZhbGliLnZpZXcubGF5b3V0LkxheW91dE1hbmFnZXIoKTsKICAgICAgICB2YXIgeGZhVXRpbCA9IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZTsKCiAgICAgICAgdmFyIF92aWV3VHlwZVJlZ2lzdHJ5ID0gewogICAgICAgICAgICBCYXNlVmlldyA6IHhmYWxpYi52aWV3LkJhc2VWaWV3LAogICAgICAgICAgICBGaWVsZFZpZXcgOiB4ZmFsaWIudmlldy5GaWVsZFZpZXcsCiAgICAgICAgICAgIE51bWVyaWNGaWVsZFZpZXcgOiB4ZmFsaWIudmlldy5OdW1lcmljRmllbGRWaWV3LAogICAgICAgICAgICBDaG9pY2VMaXN0RmllbGRWaWV3IDogeGZhbGliLnZpZXcuQ2hvaWNlTGlzdEZpZWxkVmlldywKICAgICAgICAgICAgT2JqZWN0VmlldyA6IHhmYWxpYi52aWV3Lk9iamVjdFZpZXcsCiAgICAgICAgICAgIFN1YmZvcm1WaWV3IDogeGZhbGliLnZpZXcuU3ViZm9ybVZpZXcsCiAgICAgICAgICAgIFN1YmZvcm1TZXRWaWV3IDogeGZhbGliLnZpZXcuU3ViZm9ybVNldFZpZXcsCiAgICAgICAgICAgIFBhZ2VWaWV3IDogeGZhbGliLnZpZXcuUGFnZVZpZXcsCiAgICAgICAgICAgIENvbnRlbnRBcmVhVmlldyA6IHhmYWxpYi52aWV3LkNvbnRlbnRBcmVhVmlldywKICAgICAgICAgICAgUm9vdFN1YmZvcm1WaWV3IDogeGZhbGliLnZpZXcuUm9vdFN1YmZvcm1WaWV3LAogICAgICAgICAgICBDb250YWluZXJWaWV3IDogeGZhbGliLnZpZXcuQ29udGFpbmVyVmlldywKICAgICAgICAgICAgQnV0dG9uRmllbGRWaWV3IDogeGZhbGliLnZpZXcuQnV0dG9uRmllbGRWaWV3LAogICAgICAgICAgICBDaGVja0J1dHRvbkZpZWxkVmlldyA6IHhmYWxpYi52aWV3LkNoZWNrQnV0dG9uRmllbGRWaWV3LAogICAgICAgICAgICBUZXh0RmllbGRWaWV3IDogeGZhbGliLnZpZXcuVGV4dEZpZWxkVmlldywKICAgICAgICAgICAgU2lnbmF0dXJlRmllbGRWaWV3IDogeGZhbGliLnZpZXcuU2lnbmF0dXJlRmllbGRWaWV3LAogICAgICAgICAgICBJbWFnZUZpZWxkVmlldyA6IHhmYWxpYi52aWV3LkltYWdlRmllbGRWaWV3LAogICAgICAgICAgICBYZmFEcmF3VmlldyA6IHhmYWxpYi52aWV3LlhmYURyYXdWaWV3LAogICAgICAgICAgICBEYXRlVGltZUZpZWxkVmlldzogeGZhbGliLnZpZXcuRGF0ZVRpbWVGaWVsZFZpZXcsCiAgICAgICAgICAgIEV4Y2xHcm91cFZpZXc6IHhmYWxpYi52aWV3LkV4Y2xHcm91cFZpZXcsCiAgICAgICAgICAgIERhdGFUYWJsZVZpZXc6IHhmYWxpYi52aWV3LkRhdGFUYWJsZVZpZXcKICAgICAgICB9OwoKICAgICAgICB2YXIgX2RlZmF1bHREcmF3ID0gewogICAgICAgICAgICB2aWV3IDogX3ZpZXdUeXBlUmVnaXN0cnkuWGZhRHJhd1ZpZXcKICAgICAgICB9OwoKICAgICAgICB2YXIgX2RlZmF1bHRGaWVsZCA9IHsKICAgICAgICAgICAgdmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LkZpZWxkVmlldywKICAgICAgICAgICAgd2lkZ2V0VGVtcGxhdGUgOiBudWxsLAogICAgICAgICAgICB2aWV3SW5pdENvbmZpZyA6IHsKICAgICAgICAgICAgICAgIGNvbW1pdEV2ZW50IDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FWElUX0VWRU5ULAogICAgICAgICAgICAgICAgY29tbWl0UHJvcGVydHkgOiAidmFsdWUiLAogICAgICAgICAgICAgICAgY29tbWl0VGFyZ2V0IDogInJhd1ZhbHVlIgogICAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICB2YXIgX2RlZmF1bHRDb250YWluZXIgPSB7CiAgICAgICAgICAgIHZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5Db250YWluZXJWaWV3CiAgICAgICAgfTsKICAgICAgICB2YXIgX2RlZmF1bHREYXRhVGFibGUgPSB7CiAgICAgICAgICAgIHZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5EYXRhVGFibGVWaWV3CiAgICAgICAgfTsKCiAgICAgICAgdmFyIF9ub2RlVHlwZVJlZ2lzdHJ5ID0gewogICAgICAgICAgICAvL0NvbnRhaW5lcnMKICAgICAgICAgICAgImFyZWEiIDogICAgX2RlZmF1bHRDb250YWluZXIsCiAgICAgICAgICAgICJjb250ZW50YXJlYSIgOiB7dmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LkNvbnRlbnRBcmVhVmlld30sCiAgICAgICAgICAgICJleGNsZ3JvdXAiIDoge3ZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5FeGNsR3JvdXBWaWV3fSwKICAgICAgICAgICAgInBhZ2UiIDoge3ZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5QYWdlVmlld30sCiAgICAgICAgICAgICJzdWJmb3JtIiA6IHt2aWV3IDogX3ZpZXdUeXBlUmVnaXN0cnkuU3ViZm9ybVZpZXd9LAogICAgICAgICAgICAic3ViZm9ybXNldCIgOiB7dmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LlN1YmZvcm1TZXRWaWV3fSwKICAgICAgICAgICAgInJvb3RzdWJmb3JtIiA6IHt2aWV3IDogX3ZpZXdUeXBlUmVnaXN0cnkuUm9vdFN1YmZvcm1WaWV3fSwKCiAgICAgICAgICAgIC8vRmllbGRzCiAgICAgICAgICAgICJ0ZXh0ZmllbGQiIDogewogICAgICAgICAgICAgICAgdmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LlRleHRGaWVsZFZpZXcsCiAgICAgICAgICAgICAgICB2aWV3SW5pdENvbmZpZyA6IHsKICAgICAgICAgICAgICAgICAgICBjb21taXRFdmVudCA6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfRVhJVF9FVkVOVCwKICAgICAgICAgICAgICAgICAgICBjb21taXRQcm9wZXJ0eSA6ICJ2YWx1ZSIsCiAgICAgICAgICAgICAgICAgICAgY29tbWl0VGFyZ2V0IDogInJhd1ZhbHVlIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICAic2lnbmF0dXJlZmllbGQiIDogewogICAgICAgICAgICAgICAgdmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LlNpZ25hdHVyZUZpZWxkVmlldywKICAgICAgICAgICAgICAgIHZpZXdJbml0Q29uZmlnIDogewogICAgICAgICAgICAgICAgICAgIGNvbW1pdEV2ZW50IDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FWElUX0VWRU5ULAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFByb3BlcnR5IDogInZhbHVlIiwKICAgICAgICAgICAgICAgICAgICBjb21taXRUYXJnZXQgOiAicmF3VmFsdWUiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ0ZXh0YXJlYWZpZWxkIiA6IHsKICAgICAgICAgICAgICAgIHZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5UZXh0RmllbGRWaWV3LAogICAgICAgICAgICAgICAgdmlld0luaXRDb25maWcgOiB7CiAgICAgICAgICAgICAgICAgICAgY29tbWl0RXZlbnQgOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VYSVRfRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgY29tbWl0UHJvcGVydHkgOiAidmFsdWUiLAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFRhcmdldCA6ICJyYXdWYWx1ZSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm51bWVyaWNmaWVsZCIgOiB7CiAgICAgICAgICAgICAgICB2aWV3IDogX3ZpZXdUeXBlUmVnaXN0cnkuTnVtZXJpY0ZpZWxkVmlldywKICAgICAgICAgICAgICAgIHZpZXdJbml0Q29uZmlnIDogewogICAgICAgICAgICAgICAgICAgIGNvbW1pdEV2ZW50IDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9FWElUX0VWRU5ULAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFByb3BlcnR5IDogInZhbHVlIiwKICAgICAgICAgICAgICAgICAgICBjb21taXRUYXJnZXQgOiAicmF3VmFsdWUiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJpbWFnZWZpZWxkIiA6IHsKICAgICAgICAgICAgICAgIHZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5JbWFnZUZpZWxkVmlldywKICAgICAgICAgICAgICAgIHZpZXdJbml0Q29uZmlnIDogewogICAgICAgICAgICAgICAgICAgIGNvbW1pdEV2ZW50IDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgY29tbWl0UHJvcGVydHkgOiAic3JjIiwKICAgICAgICAgICAgICAgICAgICBjb21taXRUYXJnZXQgOiAicmF3VmFsdWUiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJkYXRlZmllbGQiIDogewogICAgICAgICAgICAgICAgdmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LkRhdGVUaW1lRmllbGRWaWV3LAogICAgICAgICAgICAgICAgdmlld0luaXRDb25maWcgOiB7CiAgICAgICAgICAgICAgICAgICAgY29tbWl0RXZlbnQgOiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuWEZBX0VYSVRfRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgY29tbWl0UHJvcGVydHkgOiAidmFsdWUiLAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFRhcmdldCA6ICJyYXdWYWx1ZSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgInRpbWVmaWVsZCIgOiBfZGVmYXVsdEZpZWxkLAogICAgICAgICAgICAiZGF0ZXRpbWVmaWVsZCIgOiBfZGVmYXVsdEZpZWxkLAogICAgICAgICAgICAicGFzc3dvcmRmaWVsZCIgOiBfZGVmYXVsdEZpZWxkLAogICAgICAgICAgICAiYnV0dG9uZmllbGQiIDogewogICAgICAgICAgICAgICAgdmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LkJ1dHRvbkZpZWxkVmlldywKICAgICAgICAgICAgICAgIHZpZXdJbml0Q29uZmlnIDogewogICAgICAgICAgICAgICAgICAgIGNvbW1pdEV2ZW50IDogbnVsbCwKICAgICAgICAgICAgICAgICAgICBjb21taXRQcm9wZXJ0eSA6ICJ2YWx1ZSIsCiAgICAgICAgICAgICAgICAgICAgY29tbWl0VGFyZ2V0IDogInJhd1ZhbHVlIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICAic3VibWl0ZmllbGQiIDogX2RlZmF1bHREcmF3LAogICAgICAgICAgICAicmFkaW9maWVsZCIgOiB7CiAgICAgICAgICAgICAgICB2aWV3IDogX3ZpZXdUeXBlUmVnaXN0cnkuQ2hlY2tCdXR0b25GaWVsZFZpZXcsCiAgICAgICAgICAgICAgICB2aWV3SW5pdENvbmZpZyA6IHsKICAgICAgICAgICAgICAgICAgICBjb21taXRFdmVudCA6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0hBTkdFX0VWRU5ULAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFByb3BlcnR5IDogInZhbHVlIiwKICAgICAgICAgICAgICAgICAgICBjb21taXRUYXJnZXQgOiAicmF3VmFsdWUiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJjaGVja2JveGZpZWxkIiA6IHsKICAgICAgICAgICAgICAgIHZpZXcgOiBfdmlld1R5cGVSZWdpc3RyeS5DaGVja0J1dHRvbkZpZWxkVmlldywKICAgICAgICAgICAgICAgIHZpZXdJbml0Q29uZmlnIDogewogICAgICAgICAgICAgICAgICAgIGNvbW1pdEV2ZW50IDogeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLlhGQV9DSEFOR0VfRVZFTlQsCiAgICAgICAgICAgICAgICAgICAgY29tbWl0UHJvcGVydHkgOiAidmFsdWUiLAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFRhcmdldCA6ICJyYXdWYWx1ZSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgImNob2ljZWxpc3QiIDogewogICAgICAgICAgICAgICAgdmlldyA6IF92aWV3VHlwZVJlZ2lzdHJ5LkNob2ljZUxpc3RGaWVsZFZpZXcsCiAgICAgICAgICAgICAgICB2aWV3SW5pdENvbmZpZyA6IHsKICAgICAgICAgICAgICAgICAgICBjb21taXRFdmVudCA6IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5YRkFfQ0hBTkdFX0VWRU5ULAogICAgICAgICAgICAgICAgICAgIGNvbW1pdFByb3BlcnR5IDogInZhbHVlIiwKICAgICAgICAgICAgICAgICAgICBjb21taXRUYXJnZXQgOiAicmF3VmFsdWUiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKCiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgdmlld1R5cGVSZWdpc3RyeSA6IF92aWV3VHlwZVJlZ2lzdHJ5LAogICAgICAgICAgICByb290U3ViZm9ybVZpZXcgOiBudWxsLAogICAgICAgICAgICBub2RlVHlwZVJlZ2lzdHJ5IDogX25vZGVUeXBlUmVnaXN0cnksCiAgICAgICAgICAgIF91c2VyQ29uZmlnIDogbnVsbCwKCiAgICAgICAgICAgIHdpZGdldENvbmZpZyA6IGZ1bmN0aW9uKCl7CiAgICAgICAgICAgICAgICBpZih0aGlzLl91c2VyQ29uZmlnICYmIHRoaXMuX3VzZXJDb25maWdbIndpZGdldENvbmZpZyJdKXsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdXNlckNvbmZpZ1sid2lkZ2V0Q29uZmlnIl07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBwYWdpbmdDb25maWcgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgaWYodGhpcy5fdXNlckNvbmZpZyAmJiB0aGlzLl91c2VyQ29uZmlnWyJwYWdpbmdDb25maWciXSl7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3VzZXJDb25maWdbInBhZ2luZ0NvbmZpZyJdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgdmFyIHNocmlua1BhZ2VEaXNhYmxlZFZhbHVlID0gZmFsc2U7CiAgICAgICAgICAgICAgICBpZih0aGlzLl91c2VyQ29uZmlnICYmIHRoaXMuX3VzZXJDb25maWdbImJlaGF2aW9yQ29uZmlnIl0pewogICAgICAgICAgICAgICAgICAgIC8vVE9ETzogQ3JlYXRlIGEgZ2VuZXJpYyBtZXRob2Qgc29tZXdoZXJlIGluIEZvcm1CcmlkZ2U/CiAgICAgICAgICAgICAgICAgICAgdmFyIHZlcnNpb24gPSBuZXcgeGZhbGliLnV0LlZlcnNpb24odGhpcy5fdXNlckNvbmZpZ1siYmVoYXZpb3JDb25maWciXSk7CiAgICAgICAgICAgICAgICAgICAgaWYodmVyc2lvbi5pc1ByZXZpb3VzT3JTYW1lKHZlcnNpb24uRVM0KSkKICAgICAgICAgICAgICAgICAgICAgICAgc2hyaW5rUGFnZURpc2FibGVkVmFsdWUgPSB0cnVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAgICAgcGFnaW5nRGlzYWJsZWQgOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBzaHJpbmtQYWdlRGlzYWJsZWQgOiBzaHJpbmtQYWdlRGlzYWJsZWRWYWx1ZQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGxvb2tVcFZpZXcgOiBmdW5jdGlvbihvcHRpb25zKXsKICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwoKICAgICAgICAgICAgICAgIGlmKG9wdGlvbnMuZGF0YVRhYmxlKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBfZGVmYXVsdERhdGFUYWJsZTsKICAgICAgICAgICAgICAgIHZhciBub2RlVHlwZVZpZXcgPSB0aGlzLm5vZGVUeXBlUmVnaXN0cnlbb3B0aW9ucy5ub2RlVHlwZV07CiAgICAgICAgICAgICAgICBpZihub2RlVHlwZVZpZXcpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGVUeXBlVmlldzsKCiAgICAgICAgICAgICAgICBpZihvcHRpb25zLmZpZWxkKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBfZGVmYXVsdEZpZWxkOwogICAgICAgICAgICAgICAgZWxzZSBpZihvcHRpb25zLmRyYXcpCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9kZWZhdWx0RHJhdzsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2RlZmF1bHRDb250YWluZXI7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBjcmVhdGVWaWV3IDogZnVuY3Rpb24oaHRtbERvbU5vZGUsIG9wdGlvbnMpewogICAgICAgICAgICAgICAgdmFyICRodG1sRG9tTm9kZSA9ICQoaHRtbERvbU5vZGUpOwogICAgICAgICAgICAgICAgdmFyIG5vZGVUeXBlID0gKHhmYVV0aWwuJGRhdGEoJGh0bWxEb21Ob2RlLmdldCgwKSwgeGZhbGliLnZpZXcuTGF5b3V0Q29uc3QuWEZBX01PREVMKSB8fHt9KVt4ZmFsaWIudmlldy5MYXlvdXRDb25zdC5OT0RFX1RZUEVdOwogICAgICAgICAgICAgICAgdmFyIGlzRmllbGQgPSAkaHRtbERvbU5vZGUuaGFzQ2xhc3MoImZpZWxkIik7CiAgICAgICAgICAgICAgICB2YXIgaXNEcmF3ID0gJGh0bWxEb21Ob2RlLmhhc0NsYXNzKCJkcmF3Iik7CiAgICAgICAgICAgICAgICB2YXIgaXNEYXRhVGFibGUgPSAoJGh0bWxEb21Ob2RlLnByb3AoInRhZ05hbWUiKSA9PSAiVEFCTEUiKTsKICAgICAgICAgICAgICAgIHZhciBpc0RhdGFUYWJsZVJvdyA9ICgkaHRtbERvbU5vZGUucHJvcCgidGFnTmFtZSIpID09ICJUUiIpOwogICAgICAgICAgICAgICAgdmFyIGlzRGF0YVRhYmxlQ2VsbCA9ICgkaHRtbERvbU5vZGUucHJvcCgidGFnTmFtZSIpID09ICJURCIgfHwgJGh0bWxEb21Ob2RlLnByb3AoInRhZ05hbWUiKSA9PSAiVEgiICk7CiAgICAgICAgICAgICAgICB2YXIgdmlld09wdGlvbnMgPSB7CiAgICAgICAgICAgICAgICAgICAgIm5vZGVUeXBlIiA6IG5vZGVUeXBlLAogICAgICAgICAgICAgICAgICAgICJmaWVsZCIgOiBpc0ZpZWxkLAogICAgICAgICAgICAgICAgICAgICJkcmF3IiA6IGlzRHJhdywKICAgICAgICAgICAgICAgICAgICAiZGF0YVRhYmxlIiA6IGlzRGF0YVRhYmxlLAogICAgICAgICAgICAgICAgICAgICJkYXRhVGFibGVSb3ciIDogaXNEYXRhVGFibGVSb3csCiAgICAgICAgICAgICAgICAgICAgImRhdGFUYWJsZUNlbGwiIDogaXNEYXRhVGFibGVDZWxsCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgdmFyIHZpZXdDb25maWcgPSB0aGlzLmxvb2tVcFZpZXcodmlld09wdGlvbnMpOwogICAgICAgICAgICAgICAgdmFyIGluaXRQYXJhbSA9ICBfLmV4dGVuZCgKICAgICAgICAgICAgICAgICAgICB7ZWw6aHRtbERvbU5vZGV9LAogICAgICAgICAgICAgICAgICAgIHZpZXdDb25maWdbInZpZXdJbml0Q29uZmlnIl0sCiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIHZhciB2aWV3SW5zdGFuY2UgPSAgbmV3IHZpZXdDb25maWdbInZpZXciXShpbml0UGFyYW0pOwogICAgICAgICAgICAgICAgcmV0dXJuIHZpZXdJbnN0YW5jZTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDbGVhcnMgdGhlIHRlbXBsYXRlIGNhY2hlLiBUaGUgQVBJIGlzIG5lZWRlZCB0byBjbGVhciB0aGUgY2FjaGUgd2hlbgogICAgICAgICAgICAgKiB1bmxvYWRpbmcgb25lIGZvcm0gYW5kIGxvYWRpbmcgYW5vdGhlciBmb3JtIGluIEZvcm0gU2V0LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2xlYXJUZW1wbGF0ZUNhY2hlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBfdGVtcGxhdGVDYWNoZSA9IG5ldyB4ZmFsaWIudmlldy51dGlsLkh0bWxUZW1wbGF0ZUNhY2hlKCk7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ2xlYXJzIHRoZSBMYXlvdXQgTWFuYWdlci4gVGhlIEFQSSBpcyBuZWVkZWQgdG8gdW5sb2FkIHRoZSBsYXlvdXQgTWFuYWdlcgogICAgICAgICAgICAgKiB3aGVuIHVubG9hZGluZyBvbmUgZm9ybSBhbmQgbG9hZGluZyBhbm90aGVyIGZvcm0gaW4gRm9ybSBTZXQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICByZXNldExheW91dE1hbmFnZXIgOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgX2xheW91dE1hbmFnZXIgPSBuZXcgeGZhbGliLnZpZXcubGF5b3V0LkxheW91dE1hbmFnZXIoKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBUaGUgZnVuY3Rpb24gaXMgdXNlZCB0byBkZXN0cm95IHRoZSByZXNvdXJjZXMgaGVsZCBieSB0aGUgb2JqZWN0LgogICAgICAgICAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuIHRoZSBmb3JtIGlzIGRlc3Ryb3llZC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIF90ZW1wbGF0ZUNhY2hlID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgICAgX2xheW91dE1hbmFnZXIgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICB0ZW1wbGF0ZUNhY2hlIDogZnVuY3Rpb24oKXsKICAgICAgICAgICAgICAgIHJldHVybiBfdGVtcGxhdGVDYWNoZTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGxheW91dE1hbmFnZXIgOiBmdW5jdGlvbigpewogICAgICAgICAgICAgICAgcmV0dXJuIF9sYXlvdXRNYW5hZ2VyOwogICAgICAgICAgICB9LAoKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGxvb2sgdXBzIHRoZSBmb3JtV2lkdGggdmFsdWUgaW4gYmVoYXZpb3VyQ29uZmlnOyBhbmQgaWYgYnJvd3NlciBzdXBwb3J0cyBzY2FsaW5nLCBlbmZvcmNlIHRoYXQgd2lkdGggYnkgc2NhbGluZyB0aGUgZm9ybQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2NhbGVGb3JtOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgZm9ybVdpZHRoID0gdGhpcy5fdXNlckNvbmZpZ1sidmlld3BvcnRXaWR0aCJdOwogICAgICAgICAgICAgICAgaWYgKGZvcm1XaWR0aCkgewogICAgICAgICAgICAgICAgICAgIHZhciB0aW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyAgICAgLy8gd2FpdCBmb3IgZW5vdWdoIHRpbWUgdG8gbGV0IGxheW91dCBjb21wbGV0ZQogICAgICAgICAgICAgICAgICAgICAgICBmb3JtV2lkdGggPSBwYXJzZUludChmb3JtV2lkdGgpOwogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFnZU1heFdpZHRoID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiLnBhZ2UiKS5lYWNoKGZ1bmN0aW9uIChpLCBvYmopIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0bXBXaWR0aCA9IHBhcnNlSW50KCQob2JqKS53aWR0aCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0bXBXaWR0aCA+IHBhZ2VNYXhXaWR0aCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTWF4V2lkdGggPSB0bXBXaWR0aDsKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aWR0aCA9IHBhZ2VNYXhXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCA9IHBhcnNlSW50KCQoImJvZHkiKS5oZWlnaHQoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZUZhY3RvciA9IHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5mb3JtU2NhbGVGYWN0b3IgPSBmb3JtV2lkdGggLyB3aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybVZhbHVlID0gInNjYWxlKCIgKyBzY2FsZUZhY3RvciArICIpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbkhlaWdodCA9IGhlaWdodCAtIHNjYWxlRmFjdG9yICogaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luV2lkdGggPSB3aWR0aCAtIHNjYWxlRmFjdG9yICogd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZVN0eWxlcyA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLXdlYmtpdC10cmFuc2Zvcm0iOiB0cmFuc2Zvcm1WYWx1ZSwgLyogU2FmMy4xKywgQ2hyb21lICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi1tb3otdHJhbnNmb3JtIjogdHJhbnNmb3JtVmFsdWUsIC8qIEZGMy41KyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICItbXMtdHJhbnNmb3JtIjogdHJhbnNmb3JtVmFsdWUsIC8qIElFOSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cmFuc2Zvcm0iOiB0cmFuc2Zvcm1WYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLXdlYmtpdC10cmFuc2Zvcm0tb3JpZ2luIjogIjAgMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi1tb3otdHJhbnNmb3JtLW9yaWdpbiI6ICIwIDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICItbXMtdHJhbnNmb3JtLW9yaWdpbiI6ICIwIDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cmFuc2Zvcm0tb3JpZ2luIjogIjAgMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogYmVsb3cgdHdvIHZhbHVlcyBhcmUgYmFzZWQgb24gdG90YWwgaGV1cmlzdGljcy4gYmVzdCBjb21iaW5hdGlvbiB0byBnZXQgdGhpbmcgd29ya2luZyBjcm9zcyBicm93c2VyOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICBJbiBmZXcgYnJvd3NlcnMsIGFmdGVyIHNjYWxpbmcgdGhlcmUgaXMgYmxhbmsgc3BhY2Ugb24gYm90dG9tIHNvIG1hcmdpbi1ib3R0b20gaXMgdXNlZCB3aXRoIG5lZ2F0aXZlIHZhbHVlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICBtYXJnaW4gcmlnaHQgaXMgcmVxdWlyZWQgZm9yIHJlbW92aW5nIHNwYWNlIG9uIHJpZ2h0IGluIGZldyBicm93c2VyLCBhZnRlciBzY2FsaW5nLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICBBbmQgaW50ZXJlc3RpbmdseSwgZm9ybXVsYWUgZm9yIGJvdGggYXJlIGRpZmZlcmVudCwgbm90IG15IG1pc3Rha2UtIHRvdGFsIGhldXJpc3RpY3MuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogIElFIHN0aWxsIGhhcyBzcGFjZSBsZWZ0IGluIGJvdHRvbSZyaWdodCBpbiBzY2FsZWQgZG93biB2ZXJzaW9uIGJ1dCB3b3JrcyBnb29kIGluIHNjYWxlIHVwIHZlcnNpb24uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogIE5ldywgc3RlcCB3b3VsZCBiZSB0byBtYWtlIHRoZXNlIHZhbHVlcyBwZXIgYnJvd3NlciB0eXBlLiBCdXQgY29tbW9uIGZvciBub3cuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWFyZ2luLWJvdHRvbSI6IE1hdGgubWluKDAsIC0xICogbWFyZ2luSGVpZ2h0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWFyZ2luLXJpZ2h0IjogLTEgKiBtYXJnaW5XaWR0aAogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAkKCJib2R5IikuY3NzKHNjYWxlU3R5bGVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgJCgiLnBhZ2UiKS5jc3MoIm1hcmdpbiIsIDApOwogICAgICAgICAgICAgICAgICAgICAgICAvKmRpc3BhdGNoIGV2ZW50IHNvIHRoYXQgdG9vbGJhciBhbmQgb3RoZXIgd2lkdGhzIGNhbiBiZSByZS1jb21wdXRlZC4qLwogICAgICAgICAgICAgICAgICAgICAgICAkKHdpbmRvdy5mb3JtQnJpZGdlKS50cmlnZ2VyKCJ4ZmFGb3JtU2NhbGUiKTsKICAgICAgICAgICAgICAgICAgICB9LCAxMDApOwogICAgICAgICAgICAgICAgICAgIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5jbGVhclRpbWVvdXRPbkRlc3Ryb3kodGltZW91dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBJbnZhbGlkYXRlcyB0YWIgaW5kZXhlcyBmb3IgZ2l2ZW4gcGFnZSBudW1iZXIuIE5vdGUgdGhhdCBwYWdlIG51bWJlciBzdGFydHMgd2l0aCBvbmUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbnZhbGlkYXRlVGFiSW5kZXggOiBmdW5jdGlvbihwYWdlTnVtKXsKICAgICAgICAgICAgICAgIGlmKHBhZ2VOdW0gPiAtMSAmJiB0aGlzLnJvb3RTdWJmb3JtVmlldyAmJiB0aGlzLnJvb3RTdWJmb3JtVmlldy5jaGlsZFZpZXdzICl7CiAgICAgICAgICAgICAgICAgICAgdmFyIHBhZ2VWaWV3ID0gdGhpcy5yb290U3ViZm9ybVZpZXcuY2hpbGRWaWV3c1twYWdlTnVtIC0xXTsKICAgICAgICAgICAgICAgICAgICBpZihwYWdlVmlldyl7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VWaWV3LmludmFsaWRhdGVUYWJJbmRleCgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9KSgpOwoKICAgIHJvb3QueGZhVmlld1JlZ2lzdHJ5LmluaXRpYWxpemVWaWV3ID0gZnVuY3Rpb24oZmlyc3RQYWdlSHRtbFN0ciwgcmVzdE9mVGhlUGFnZXMpewogICAgICAgIHZhciB2aWV3U3RhcnRUaW1lID0gRGF0ZS5ub3coKTsKICAgICAgICB2YXIgJGZvcm1IdG1sID0gJChmaXJzdFBhZ2VIdG1sU3RyKTsKICAgICAgICB2YXIgb3B0aW9ucyA9IHt9OwogICAgICAgIG9wdGlvbnMucmVzdE9mVGhlUGFnZXMgPSByZXN0T2ZUaGVQYWdlczsKICAgICAgICB2YXIgcGFnaW5nTWFuYWdlciA9IG5ldyB4ZmFsaWIudmlldy5QYWdpbmdNYW5hZ2VyKCk7CiAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLmhvc3QucGFnaW5nTWFuYWdlciA9IHBhZ2luZ01hbmFnZXI7CiAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLiRsYXlvdXQucGFnaW5nTWFuYWdlciA9IHBhZ2luZ01hbmFnZXI7CiAgICAgICAgd2luZG93LnhmYVZpZXdSZWdpc3RyeS5yb290U3ViZm9ybVZpZXcgPSB3aW5kb3cueGZhVmlld1JlZ2lzdHJ5LmNyZWF0ZVZpZXcoJGZvcm1IdG1sLCBvcHRpb25zKTsKICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuaG9zdC5vbih4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuRk9STV9NT0RFTF9SRUZSRVNILHsKICAgICAgICAgICAgaGFuZGxlRXZlbnQ6IGZ1bmN0aW9uKGV2bnQpIHsKICAgICAgICAgICAgICAgIHN3aXRjaChldm50Lm5hbWUpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIHhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5GT1JNX01PREVMX1JFRlJFU0g6CiAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy54ZmFWaWV3UmVnaXN0cnkucm9vdFN1YmZvcm1WaWV3LnN5bmNGb3JtTm9kZVRvSHRtbCh0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAvKiBsb2cgYW4gZXJyb3IgbWVzc2FnZSAqLwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgLy9UT0RPOiBtb3ZlIHRoaXMgdG8gTG9nZ2VyCiAgICAgICAgZm9ybUJyaWRnZS52aWV3VGltZSA9IERhdGUubm93KCktdmlld1N0YXJ0VGltZTsKICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmRlYnVnKCJ4ZmFWaWV3IiwiIyMjIyMjIyMjIyMjIyMjIyB0b3RhbCB0aW1lIHRvIGNyZWF0ZSB2aWV3OiIrZm9ybUJyaWRnZS52aWV3VGltZSk7CiAgICAgICAgcmV0dXJuICRmb3JtSHRtbDsKICAgIH07CgogICAgcm9vdC54ZmFWaWV3UmVnaXN0cnkuaW5pdGlhbGl6ZU1vZGVsID0gZnVuY3Rpb24oeGZhSnNvbiwgeGZhRGF0YU1lcmdlRG9ybSwgeGZhbG9jYWxlc2V0LCB4ZmFyZW5kZXJjb250ZXh0KSB7CiAgICAgICAgLy9yZWFkIHJlbmRlckNvbnRleHQgYW5kIG90aGVyIHhmYSBzcGVjaWZpYyBub2RlIGFuZCBwdXNoIGl0CiAgICAgICAgeGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dCA9IHhmYXJlbmRlcmNvbnRleHQ7CgogICAgICAgIGlmKHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5nZXRPckVsc2UoeGZhbGliLnJ1bnRpbWUsICJjdXN0b21Qcm9wZXJ0eU1hcC54bWxPbkNsaWVudCIsICIwIikgPT09ICIxIikgewogICAgICAgICAgICBpZih4ZmFsaWIucnVudGltZS5yZW5kZXJDb250ZXh0LmRhdGEpIHsKICAgICAgICAgICAgICAgIGZvcm1CcmlkZ2UucGxheURhdGFYTUwoewogICAgICAgICAgICAgICAgICAgIHhtbERvY3VtZW50IDogeGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dC5kYXRhCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvL3JlYWQgbG9jYWxlc2V0IGFzIHdlbGwKICAgICAgICB4ZmFKc29uLmxvY2FsZVNldCA9IHhmYWxvY2FsZXNldDsKCiAgICAgICAgLy9DcmVhdGUgWGZhIE5vZGUKICAgICAgICB4ZmFsaWIuc2NyaXB0LlhmYU1vZGVsUmVnaXN0cnkucHJvdG90eXBlLmNyZWF0ZU1vZGVsKHhmYUpzb24pOyAgICAgICAvL1RPRE86IEhhbmRsZSB3aW5kb3cgZGVwZW5kZW5jeQoKICAgICAgICBpZih4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmlzTG9nRW5hYmxlZCgieGZhIiwgeGZhbGliLnV0LkxvZ2dlci5wcm90b3R5cGUuVFJBQ0UpKXsKICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci50cmFjZSgieGZhIiwiIyMjIyMjIyMjIyMjIyMjIyB0MCB4ZmFkb206XG4iICsgSlNPTi5zdHJpbmdpZnkoeGZhSnNvbikpOwogICAgICAgIH0KCiAgICAgICAgdmFyIGhhc1Jlc3RvcmVTdGF0ZSA9IGZhbHNlOwogICAgICAgIGlmICh3aW5kb3cuZm9ybUJyaWRnZSAhPSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgdmFyIGxvY2FsU3RvcmFnZSA9IHdpbmRvdy5mb3JtQnJpZGdlLl9nZXRTdG9yYWdlKCk7CiAgICAgICAgICAgIGlmIChsb2NhbFN0b3JhZ2UgJiYgbG9jYWxTdG9yYWdlLnhmYURvbSkgewogICAgICAgICAgICAgICAgeGZhSnNvbiA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLnhmYURvbSk7CiAgICAgICAgICAgICAgICBpZih4ZmFKc29uKSB7CiAgICAgICAgICAgICAgICAgICAgaGFzUmVzdG9yZVN0YXRlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBpZih4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLmlzTG9nRW5hYmxlZCgieGZhIiwgeGZhbGliLnV0LkxvZ2dlci5wcm90b3R5cGUuVFJBQ0UpKXsKICAgICAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci50cmFjZSgieGZhIiwiIyMjIyMjIyMjIyMjIyMjIyByZXN0b3JlIHhmYWRvbTpcbiIgKyBKU09OLnN0cmluZ2lmeSh4ZmFKc29uKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5ob3N0LnBsYXlKc29uKHhmYUpzb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhciB4bWxTdG9yYWdlID0gd2luZG93LmZvcm1CcmlkZ2UuX2dldFhtbFN0b3JhZ2UoKTsKICAgICAgICAgICAgaWYoeG1sU3RvcmFnZSkgewogICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci50cmFjZSgieGZhIiwiIyMjIyMjIyMjIyMjIyMjIyByZXN0b3JlIHhtbDpcbiIgKyB4bWxTdG9yYWdlKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLmhvc3QucGxheURhdGFYbWwoeG1sU3RvcmFnZSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoKGV4Y2VwdGlvbikgewogICAgICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZXJyb3IoInhmYSIsICJyZXN0b3JpbmcgeG1sIGZhaWxlZCAiKQogICAgICAgICAgICAgICAgICAgIGlmKF8uaXNGdW5jdGlvbihmb3JtQnJpZGdlLnhtbFN0b3JhZ2UuZXJyb3IpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNPYmogPSBmb3JtQnJpZGdlLl9nZXRSZXN1bHRPYmplY3QoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzT2JqLmFkZE1lc3NhZ2UoMiwgZXhjZXB0aW9uLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUJyaWRnZS54bWxTdG9yYWdlLmVycm9yLmFwcGx5KGZvcm1CcmlkZ2UueG1sU3RvcmFnZS5jb250ZXh0LCBbcmVzT2JqXSkKICAgICAgICAgICAgICAgICAgICAgICAgLy90byBlbnN1cmUgdGhhdCBzdWNjZXNzIGhhbmRsZXIgaXMgbm90IGNhbGxlZCBhZnRlciBmb3JtIHJlbmRlciBmcm9tIEZvcm1CcmlkZ2UuX3hmYUluaXRpYWxpemVkCiAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1CcmlkZ2UueG1sU3RvcmFnZS5zdWNjZXNzID0gbnVsbDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYoIHhmYWxpYi51dC5YZmFVdGlsLnByb3RvdHlwZS5nZXRPckVsc2UoeGZhbGliLnJ1bnRpbWUsICJjdXN0b21Qcm9wZXJ0eU1hcC54bWxPbkNsaWVudCIsICIwIikgIT09ICIxIikgewogICAgICAgICAgICBpZighaGFzUmVzdG9yZVN0YXRlICYmIHhmYURhdGFNZXJnZURvcm0pewogICAgICAgICAgICAgICAgaWYoeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci5pc0xvZ0VuYWJsZWQoInhmYSIsIHhmYWxpYi51dC5Mb2dnZXIucHJvdG90eXBlLlRSQUNFKSl7CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci50cmFjZSgieGZhIiwiIyMjIyMjIyMjIyMjIyMjIyByZXN0b3JlIHhmYWRvbTpcbiIgKyBKU09OLnN0cmluZ2lmeSh4ZmFEYXRhTWVyZ2VEb3JtKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuaG9zdC5wbGF5SnNvbih4ZmFEYXRhTWVyZ2VEb3JtKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiggeGZhbGliLnV0LlhmYVV0aWwucHJvdG90eXBlLmdldE9yRWxzZSh4ZmFsaWIucnVudGltZSwgImN1c3RvbVByb3BlcnR5TWFwLmRlc3Ryb3lPbkV4aXQiLCAiMCIpID09PSAiMSIpIHsKICAgICAgICAgICAgJCh3aW5kb3cpLm9uKCJiZWZvcmV1bmxvYWQueGZhIiwgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgZm9ybUJyaWRnZS5kZXN0cm95Rm9ybSh0cnVlKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfTsKCiAgICByb290LnhmYVZpZXdSZWdpc3RyeS5pbml0aWFsaXplRm9ybU9uRG9tUmVhZHkgPSBmdW5jdGlvbigpIHsKICAgICAgICAkKGZ1bmN0aW9uKCQpewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgdmFyIGluaXRTdGFydCA9IERhdGUubm93KCk7CiAgICAgICAgICAgICAgICAvL2luaXRpYWxpemUgQWNyb2JhdCBzcGVjaWZpYyBzY3JpcHRzCiAgICAgICAgICAgICAgICBuZXcgeGZhbGliLmFjcm9iYXQuQWNyb2JhdCgpOwogICAgICAgICAgICAgICAgaWYoeGZhbGliLnJ1bnRpbWUueGZhKSB7CiAgICAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLmZvcm0uX2luaXRpYWxpemUodHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgJCh3aW5kb3cpLnRyaWdnZXIoIlhmYUluaXRpYWxpemVkIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmb3JtQnJpZGdlLm1vZGVsSW5pdFRpbWUgPSBEYXRlLm5vdygpLWluaXRTdGFydDsKICAgICAgICAgICAgICAgIHhmYWxpYi52aWV3LkZpZWxkVmlldy5wcm90b3R5cGUuY3VycmVudEZvY3VzID0gbnVsbDsKICAgICAgICAgICAgICAgICQod2luZG93KS5vbigibW91c2Vkb3duLnhmYSIsIGZ1bmN0aW9uKCkgewogICAgICAgICAgICAgICAgICAgIGZvcm1CcmlkZ2UuY2xpY2tlZE9uV2luZG93ID0gdHJ1ZTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZXJyb3IoInhmYSIsImVycm9yIGluIGZvcm0uX2luaXRpYWxpemUiKTsKICAgICAgICAgICAgICAgIGlmKGUuc3RhY2spewogICAgICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZXJyb3IoInhmYSIsIGUuc3RhY2spOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9OwoKICAgIC8vVE9ETzogUHV0IGJlbG93IGNhbGwgYXQgcHJvcGVyIHBsYWNlCiAgICB3aW5kb3cuX2luaXRpYWxpemVYZmFMb2FkaW5nID0gZnVuY3Rpb24gKHhmYUpzb24sIHhmYURhdGFNZXJnZURvcm0sIHhmYWxvY2FsZXNldCwgeGZhcmVuZGVyY29udGV4dCwgZmlsZUF0dGFjaG1lbnRNYXApIHsKICAgICAgICB3aW5kb3cuZm9ybUJyaWRnZS5fcG9zdEV4dGVybmFsTWVzc2FnZSh7bmFtZSA6ICJfZm9ybWRvbXN0YXJ0In0pOwogICAgICAgIHZhciB4ZmFNb2RlbExvYWRTdGFydCA9IERhdGUubm93KCk7CiAgICAgICAgdmFyIHhmYVZpZXdSZWdpc3RyeSA9IHdpbmRvdy54ZmFWaWV3UmVnaXN0cnk7CgogICAgICAgIC8vcmVhZCBpbnRlcm5hbCBjc3MgYW5kIGF0dGFjaCBpdCB0byBoZWFkCiAgICAgICAgLy9leGN1c2UgbQogICAgICAgIGlmKCQoJyNmb3JtTG9hZGluZ0RpdicpLmRhdGEoJ2ludGVybmFsY3NzJykpIHsKICAgICAgICAgICAgdmFyIGludGVybmFsY3NzID0gJCgnI2Zvcm1Mb2FkaW5nRGl2JykuZGF0YSgnaW50ZXJuYWxjc3MnKSwKICAgICAgICAgICAgICAgIHN0eWxlVGFnID0gJzxzdHlsZSBpZD0ibWZzdHlsZSIgdHlwZT0idGV4dC9jc3MiPicraW50ZXJuYWxjc3MrJzwvc3R5bGU+JzsKICAgICAgICAgICAgLy9pbnNlcnQgaW50ZXJuYWwgY3NzIGJlZm9yZSB0aGUgZmlyc3Qgc3R5bGUgZWxlbWVudC4KICAgICAgICAgICAgaWYoJCgnaGVhZD5zdHlsZTpmaXJzdCcpLmxlbmd0aCA+IDApCiAgICAgICAgICAgICAgICAkKCdoZWFkPnN0eWxlOmZpcnN0JykuYmVmb3JlKHN0eWxlVGFnKTsKICAgICAgICAgICAgZWxzZSBpZigkKCdoZWFkJykubGVuZ3RoID4gMCkKICAgICAgICAgICAgICAgICQoJ2hlYWQnKS5hcHBlbmQoc3R5bGVUYWcpOwogICAgICAgICAgICBlbHNlIGlmKCQoJ2JvZHknKS5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgJCgnYm9keScpLnByZXBlbmQoc3R5bGVUYWcpOwogICAgICAgICAgICBlbHNlIGlmKCQoJ2h0bWwnKS5sZW5ndGggPiAwKQogICAgICAgICAgICAgICAgJCgnaHRtbCcpLnByZXBlbmQoc3R5bGVUYWcpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAkKCcjZm9ybUxvYWRpbmdEaXYnKS5wcmVwZW5kKHN0eWxlVGFnKTsKICAgICAgICB9CgogICAgICAgIHhmYVZpZXdSZWdpc3RyeS5pbml0aWFsaXplTW9kZWwoeGZhSnNvbiwgeGZhRGF0YU1lcmdlRG9ybSwgeGZhbG9jYWxlc2V0LCB4ZmFyZW5kZXJjb250ZXh0KTsKCiAgICAgICAgd2luZG93LmZvcm1CcmlkZ2UuX3Bvc3RFeHRlcm5hbE1lc3NhZ2Uoe25hbWUgOiAiX2xheW91dHN0YXJ0In0pOwogICAgICAgIHhmYVZpZXdSZWdpc3RyeS5fdXNlckNvbmZpZyA9IHdpbmRvdy5mb3JtQnJpZGdlLnVzZXJDb25maWc7CiAgICAgICAgLy9UT0RPOiBtb3ZlIHRoaXMgdG8gTG9nZ2VyCiAgICAgICAgZm9ybUJyaWRnZS5tb2RlbFRpbWUgPSBEYXRlLm5vdygpLXhmYU1vZGVsTG9hZFN0YXJ0OwogICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZGVidWcoInhmYVZpZXciLCIjIyMjIyMjIyMjIyMjIyMjIHRvdGFsIHRpbWUgdG8gbG9hZCB4ZmEgbW9kZWw6IisgZm9ybUJyaWRnZS5tb2RlbFRpbWUpOwoKICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuZm9ybS5tYkluaXRpYWxpemVkID0gZmFsc2U7CgogICAgICAgIHZhciB4ZmFodG1sZG9tID0gICQoJyNmb3JtTG9hZGluZ0RpdicpLmRhdGEoJ3hmYWh0bWxkb20nKTsKICAgICAgICB2YXIgeGZhcmVzdGh0bWxkb20gPSAkKCcjZm9ybUxvYWRpbmdEaXYnKS5kYXRhKCd4ZmFyZXN0aHRtbGRvbScpOwogICAgICAgIHZhciB4ZmFoaWRkZW5vYmpkb20gPSAkKCcjZm9ybUxvYWRpbmdEaXYnKS5kYXRhKCd4ZmFoaWRkZW5vYmpkb20nKTsKCiAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci50cmFjZSgieGZhVmlldyIsIiMjIyMjIyMjIyMjIyMjIyMgeGZhaHRtbGRvbTpcbiIgKyB4ZmFodG1sZG9tKTsKICAgICAgICB4ZmFsaWIucnVudGltZS54ZmEuTG9nZ2VyLnRyYWNlKCJ4ZmFWaWV3IiwiIyMjIyMjIyMjIyMjIyMjIyB4ZmFyZXN0aHRtbGRvbTpcbiIgKyB4ZmFyZXN0aHRtbGRvbSk7CiAgICAgICAgeGZhbGliLnJ1bnRpbWUueGZhLkxvZ2dlci50cmFjZSgieGZhVmlldyIsIiMjIyMjIyMjIyMjIyMjIyMgeGZhaGlkZGVub2JqZG9tOlxuIDxhPiIgKyB4ZmFoaWRkZW5vYmpkb20gKyAiPC9hPiIpOwoKICAgICAgICB4ZmFWaWV3UmVnaXN0cnkudGVtcGxhdGVDYWNoZSgpLnNldEhpZGRlbk9ialBhZ2VzKHhmYWhpZGRlbm9iamRvbSk7IC8vY2FjaGUgdGhlIHBhZ2VzIHdpdGggaGlkZGVuIG9iamVjdCBsYXlvdXQKICAgICAgICAkKCcjZm9ybUxvYWRpbmdEaXYnKS5yZXBsYWNlV2l0aCh4ZmFWaWV3UmVnaXN0cnkuaW5pdGlhbGl6ZVZpZXcoIHhmYWh0bWxkb20sIHhmYXJlc3RodG1sZG9tKSk7CgogICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZGVidWcoInhmYVZpZXciLCIjIyMjIyMjIyMjIyMjIyMjIHRvdGFsIHRpbWUgdG8gbG9hZCB4ZmEgbW9kZWwgKyB2aWV3OiIrKERhdGUubm93KCkteGZhTW9kZWxMb2FkU3RhcnQpKTsKICAgICAgICB3aW5kb3cuZm9ybUJyaWRnZS5fcG9zdEV4dGVybmFsTWVzc2FnZSh7bmFtZSA6ICJfbGF5b3V0ZW5kIn0pOwoKICAgICAgICB4ZmFWaWV3UmVnaXN0cnkuaW5pdGlhbGl6ZUZvcm1PbkRvbVJlYWR5KCk7CgogICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5mb3JtLm1iSW5pdGlhbGl6ZWQgPSB0cnVlOwoKICAgICAgICAvLyBSZXN0b3JlIGF0dGFjaG1lbnRzCiAgICAgICAgLy8gV2UgYXJlIHNldHRpbmcgdGhpcyB3aGljaCBpcyBwYXNzZWQgYnkgZmlsZSBhdHRhY2htZW50IHBsdWdpbiB0byAgdGhlIGZpbGVVcGxvYWQgd2lkZ2V0CiAgICAgICAgLy8gYXMgb3B0aW9ucy52YWx1ZSBhbmQgdGhlbiB3aWRnZXQgY3JlYXRpb24gdGFrZXMgcGxhY2UKICAgICAgICBpZih4ZmFsaWIucnVudGltZSkgewogICAgICAgICAgICB4ZmFsaWIucnVudGltZS5maWxlQXR0YWNobWVudCA9IGZpbGVBdHRhY2htZW50TWFwOwogICAgICAgIH0KCiAgICB9OwoKfSkoXywgJCwgeGZhbGliKTsKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTMgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKGZ1bmN0aW9uICgkKSB7CgogICAgZnVuY3Rpb24gaGlnaGxpZ2h0RmllbGRzKCkgewogICAgICAgICQoIi53aWRnZXQ6bm90KC5idXR0b25maWVsZHdpZGdldCwuc3VibWl0ZmllbGR3aWRnZXQpIikKICAgICAgICAgICAgLnRvZ2dsZUNsYXNzKCJ3aWRnZXRCYWNrR3JvdW5kQ29sb3JIaWdobGlnaHQiLCB4ZmFsaWIuZ2xvYmFscy5oaWdobGlnaHQpOwogICAgICAgICQoIi53aWRnZXRbZGF0YS1tYW5kYXRvcnk9J3RydWUnXSwuZXhjbGdyb3VwW2RhdGEtbWFuZGF0b3J5PSd0cnVlJ10iKQogICAgICAgICAgICAudG9nZ2xlQ2xhc3MoIndpZGdldE1hbmRhdG9yeUJvcmRlciIsIHhmYWxpYi5nbG9iYWxzLmhpZ2hsaWdodCk7CiAgICB9CgogICAgZnVuY3Rpb24gX2dldFRvb2xiYXJXaWR0aCgpIHsKICAgICAgICB2YXIgX3Rid2lkdGggPSBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoOwogICAgICAgIGlmICh3aW5kb3cuZm9ybUJyaWRnZSAmJiB3aW5kb3cuZm9ybUJyaWRnZS51c2VyQ29uZmlnWyJ2aWV3cG9ydFdpZHRoIl0pIHsKICAgICAgICAgICAgX3Rid2lkdGggPSB3aW5kb3cuZm9ybUJyaWRnZS51c2VyQ29uZmlnWyJ2aWV3cG9ydFdpZHRoIl07CiAgICAgICAgfQogICAgICAgICQoIi5wYWdlIikuZWFjaChmdW5jdGlvbiAoaSwgb2JqKSB7CiAgICAgICAgICAgIHZhciBleHRlbnQgPSB7fTsKICAgICAgICAgICAgdmFyIHRtcFdpZHRoID0gcGFyc2VJbnQoJCh0aGlzKS53aWR0aCgpKTsKICAgICAgICAgICAgaWYgKHRtcFdpZHRoID4gX3Rid2lkdGgpCiAgICAgICAgICAgICAgICBfdGJ3aWR0aCA9IHRtcFdpZHRoOwogICAgICAgIH0pOwogICAgICAgIHJldHVybiBfdGJ3aWR0aCAtIDI7CiAgICB9CgogICAgZnVuY3Rpb24gX3NldFRvb2xiYXJXaWR0aCgpIHsKICAgICAgICB2YXIgZXh0ZW50ID0ge307CiAgICAgICAgZXh0ZW50WyJ3aWR0aCJdID0gX2dldFRvb2xiYXJXaWR0aCgpOwogICAgICAgICQoIi50b29sYmFyaGVhZGVyIikuY3NzKGV4dGVudCk7CiAgICAgICAgJCgiLnBhZ2luZ2Zvb3RlciIpLmNzcyhleHRlbnQpOwogICAgICAgICQoIi50b29sYmFyaGVhZGVyIikuY3NzKCJsZWZ0IiwgIjBweCIpOwogICAgICAgICQoIi50b29sYmFyaGVhZGVyIikuY3NzKCJyaWdodCIsICIwcHgiKTsKICAgIH0KCiAgICAvL3Nob3cgdG9vbGJhciBidXR0b24gYmFzZWQgb24gbG9nZ2VyLgogICAgd2luZG93LmZvcm1CcmlkZ2UuY29ubmVjdCgKICAgICAgICBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICQoIiNsb2FkaW5nUGFnZSIpLmhpZGUoKTsKICAgICAgICAgICAgaWYgKHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuaXNTZXJ2ZXJMb2dnaW5nRW5hYmxlZCgpKSB7CiAgICAgICAgICAgICAgICAkKCIjdG9vbGJhcmxvZ2dlcmJ0biIpLmNzcyh7ZGlzcGxheTogImlubGluZS1ibG9jayJ9KTsKICAgICAgICAgICAgICAgIC8vcmVnaXN0ZXIgY2xpY2sgaGFuZGxlciB0byBzZW5kIGxvZ3MKICAgICAgICAgICAgICAgICQoIiN0b29sYmFybG9nZ2VyYnRuIikuY2xpY2soZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuc2VydmVySGFuZGxlcigpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICApOwoKICAgICQod2luZG93KS5vbmUoJ3hmYUZpcnN0UGdMYXlvdXRDb21wbGV0ZScsIGZ1bmN0aW9uKCkgewogICAgICAgICQoIiNsb2FkaW5nUGFnZSIpLmhpZGUoKTsKICAgICAgICAkKCIubG9hZGluZ0JvZHkiKS5yZW1vdmVDbGFzcygibG9hZGluZ0JvZHkiKTsKICAgIH0pOwoKICAgIC8vcmVnaXN0ZXIgd2hlbiBkb2N1bWVudCBpcyByZWFkeQogICAgJChmdW5jdGlvbiAoJCkgewoKICAgICAgICB2YXIgdG9vbEJhckluaXQgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIF9zZXRUb29sYmFyV2lkdGgoKTsKICAgICAgICAgICAgaGlnaGxpZ2h0RmllbGRzKCk7CgogICAgICAgICAgICAkKHdpbmRvdykub24oJ3Jlc2l6ZScsIF9zZXRUb29sYmFyV2lkdGgpOyAvLyBCdWcjMzY3MDM5NCA6IGNoYW5nZWQgJCgnYm9keScpIHRvICQod2luZG93KQogICAgICAgICAgICAkKGZvcm1CcmlkZ2UpLm9uKCd4ZmFGb3JtU2NhbGUnLCBfc2V0VG9vbGJhcldpZHRoKTsgLy8gcmVzY2FsZSB0aGUgdG9vbGJhcgogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgd2luZG93LnBhcmVudC5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICB3aW5kb3cueGZhVmlld1JlZ2lzdHJ5LnNjYWxlRm9ybSgpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi5ydW50aW1lLnhmYS5Mb2dnZXIuZXJyb3IoInhmYSIsICJjb3VsZCBub3QgcmVnaXN0ZXIgb3JpZW50YXRpb25jaGFuZ2UgbGlzdGVuZXIiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJChmb3JtQnJpZGdlKS5vbigieGZhTmV4dFBhZ2VSZW5kZXJlZCB4ZmFMYXlvdXRDb21wbGV0ZSIsIGhpZ2hsaWdodEZpZWxkcyk7CgogICAgICAgICAgICAkKCcjdG9vbGJhcmhpZ2hsaWdodCcpLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHhmYWxpYi5nbG9iYWxzLmhpZ2hsaWdodCA9ICF4ZmFsaWIuZ2xvYmFscy5oaWdobGlnaHQ7CiAgICAgICAgICAgICAgICBoaWdobGlnaHRGaWVsZHMoKTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfTsKICAgICAgICAvL0J1ZyMzNjA1NTU4OiBpUGFkIGRvZXNuJ3QgZ2l2ZSB0aGUgd2lkdGggdmFsdWVzIGluc3RhbnRhbmVvdXNseSwgaGVuY2UgcHV0dGluZyBhIHRpbWUgb3V0IHNpbmNlIHdlIG5lZWQKICAgICAgICAvLyB3aWR0aCBvZiB0aGUgcGFnZXMgcmVuZGVyZWQuCiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmICgheGZhbGliLnJ1bnRpbWUueGZhKSAgLy9CdWcjMzY3MDM3MzogSW4gSUUsIGRvYy5yZWFkeSBpcyBjYWxsZWQgdG9vIGVhcmx5IGZvciBzb21lIGZvcm1zLCBzbyB4ZmFsaWIucnVudGltZS54ZmEgaXMgdW5kZWZpbmVkCiAgICAgICAgICAgICAgICAkKHdpbmRvdykub25lKCd4ZmFGaXJzdFBnTGF5b3V0Q29tcGxldGUnLCB0b29sQmFySW5pdCk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHRvb2xCYXJJbml0KCk7CiAgICAgICAgfSwgMTAwKTsKCgogICAgfSk7Cn0pKCQpOwoKCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKiBCb290c3RyYXA6IG1vZGFsLmpzIHYzLjQuMQogKiBodHRwczovL2dldGJvb3RzdHJhcC5jb20vZG9jcy8zLjQvamF2YXNjcmlwdC8jbW9kYWxzCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKiBDb3B5cmlnaHQgMjAxMS0yMDE5IFR3aXR0ZXIsIEluYy4KICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSkKICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovCgoKKGZ1bmN0aW9uICgkKSB7CiAgICAndXNlIHN0cmljdCc7CgogICAgLy8gTU9EQUwgQ0xBU1MgREVGSU5JVElPTgogICAgLy8gPT09PT09PT09PT09PT09PT09PT09PQoKICAgIHZhciBNb2RhbCA9IGZ1bmN0aW9uIChlbGVtZW50LCBvcHRpb25zKSB7CiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucwogICAgICAgIHRoaXMuJGJvZHkgPSAkKGRvY3VtZW50LmJvZHkpCiAgICAgICAgdGhpcy4kZWxlbWVudCA9ICQoZWxlbWVudCkKICAgICAgICB0aGlzLiRkaWFsb2cgPSB0aGlzLiRlbGVtZW50LmZpbmQoJy5tb2RhbC1kaWFsb2cnKQogICAgICAgIHRoaXMuJGJhY2tkcm9wID0gbnVsbAogICAgICAgIHRoaXMuaXNTaG93biA9IG51bGwKICAgICAgICB0aGlzLm9yaWdpbmFsQm9keVBhZCA9IG51bGwKICAgICAgICB0aGlzLnNjcm9sbGJhcldpZHRoID0gMAogICAgICAgIHRoaXMuaWdub3JlQmFja2Ryb3BDbGljayA9IGZhbHNlCiAgICAgICAgdGhpcy5maXhlZENvbnRlbnQgPSAnLm5hdmJhci1maXhlZC10b3AsIC5uYXZiYXItZml4ZWQtYm90dG9tJwoKICAgICAgICBpZiAodGhpcy5vcHRpb25zLnJlbW90ZSkgewogICAgICAgICAgICB0aGlzLiRlbGVtZW50CiAgICAgICAgICAgICAgICAuZmluZCgnLm1vZGFsLWNvbnRlbnQnKQogICAgICAgICAgICAgICAgLmxvYWQodGhpcy5vcHRpb25zLnJlbW90ZSwgJC5wcm94eShmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCdsb2FkZWQuYnMubW9kYWwnKQogICAgICAgICAgICAgICAgfSwgdGhpcykpCiAgICAgICAgfQogICAgfQoKICAgIE1vZGFsLlZFUlNJT04gPSAnMy40LjEnCgogICAgTW9kYWwuVFJBTlNJVElPTl9EVVJBVElPTiA9IDMwMAogICAgTW9kYWwuQkFDS0RST1BfVFJBTlNJVElPTl9EVVJBVElPTiA9IDE1MAoKICAgIE1vZGFsLkRFRkFVTFRTID0gewogICAgICAgIGJhY2tkcm9wOiB0cnVlLAogICAgICAgIGtleWJvYXJkOiB0cnVlLAogICAgICAgIHNob3c6IHRydWUKICAgIH0KCiAgICBNb2RhbC5wcm90b3R5cGUudG9nZ2xlID0gZnVuY3Rpb24gKF9yZWxhdGVkVGFyZ2V0KSB7CiAgICAgICAgcmV0dXJuIHRoaXMuaXNTaG93biA/IHRoaXMuaGlkZSgpIDogdGhpcy5zaG93KF9yZWxhdGVkVGFyZ2V0KQogICAgfQoKICAgIE1vZGFsLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKF9yZWxhdGVkVGFyZ2V0KSB7CiAgICAgICAgdmFyIHRoYXQgPSB0aGlzCiAgICAgICAgdmFyIGUgPSAkLkV2ZW50KCdzaG93LmJzLm1vZGFsJywgeyByZWxhdGVkVGFyZ2V0OiBfcmVsYXRlZFRhcmdldCB9KQoKICAgICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoZSkKCiAgICAgICAgaWYgKHRoaXMuaXNTaG93biB8fCBlLmlzRGVmYXVsdFByZXZlbnRlZCgpKSByZXR1cm4KCiAgICAgICAgdGhpcy5pc1Nob3duID0gdHJ1ZQoKICAgICAgICB0aGlzLmNoZWNrU2Nyb2xsYmFyKCkKICAgICAgICB0aGlzLnNldFNjcm9sbGJhcigpCiAgICAgICAgdGhpcy4kYm9keS5hZGRDbGFzcygnbW9kYWwtb3BlbicpCgogICAgICAgIHRoaXMuZXNjYXBlKCkKICAgICAgICB0aGlzLnJlc2l6ZSgpCgogICAgICAgIHRoaXMuJGVsZW1lbnQub24oJ2NsaWNrLmRpc21pc3MuYnMubW9kYWwnLCAnW2RhdGEtZGlzbWlzcz0ibW9kYWwiXScsICQucHJveHkodGhpcy5oaWRlLCB0aGlzKSkKCiAgICAgICAgdGhpcy4kZGlhbG9nLm9uKCdtb3VzZWRvd24uZGlzbWlzcy5icy5tb2RhbCcsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdGhhdC4kZWxlbWVudC5vbmUoJ21vdXNldXAuZGlzbWlzcy5icy5tb2RhbCcsIGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgICAgICBpZiAoJChlLnRhcmdldCkuaXModGhhdC4kZWxlbWVudCkpIHRoYXQuaWdub3JlQmFja2Ryb3BDbGljayA9IHRydWUKICAgICAgICAgICAgfSkKICAgICAgICB9KQoKICAgICAgICB0aGlzLmJhY2tkcm9wKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgdmFyIHRyYW5zaXRpb24gPSAkLnN1cHBvcnQudHJhbnNpdGlvbiAmJiB0aGF0LiRlbGVtZW50Lmhhc0NsYXNzKCdmYWRlJykKCiAgICAgICAgICAgIGlmICghdGhhdC4kZWxlbWVudC5wYXJlbnQoKS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIHRoYXQuJGVsZW1lbnQuYXBwZW5kVG8odGhhdC4kYm9keSkgLy8gZG9uJ3QgbW92ZSBtb2RhbHMgZG9tIHBvc2l0aW9uCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHRoYXQuJGVsZW1lbnQKICAgICAgICAgICAgICAgIC5zaG93KCkKICAgICAgICAgICAgICAgIC5zY3JvbGxUb3AoMCkKCiAgICAgICAgICAgIHRoYXQuYWRqdXN0RGlhbG9nKCkKCiAgICAgICAgICAgIGlmICh0cmFuc2l0aW9uKSB7CiAgICAgICAgICAgICAgICB0aGF0LiRlbGVtZW50WzBdLm9mZnNldFdpZHRoIC8vIGZvcmNlIHJlZmxvdwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aGF0LiRlbGVtZW50LmFkZENsYXNzKCdpbicpCgogICAgICAgICAgICB0aGF0LmVuZm9yY2VGb2N1cygpCgogICAgICAgICAgICB2YXIgZSA9ICQuRXZlbnQoJ3Nob3duLmJzLm1vZGFsJywgeyByZWxhdGVkVGFyZ2V0OiBfcmVsYXRlZFRhcmdldCB9KQoKICAgICAgICAgICAgdHJhbnNpdGlvbiA/CiAgICAgICAgICAgICAgICB0aGF0LiRkaWFsb2cgLy8gd2FpdCBmb3IgbW9kYWwgdG8gc2xpZGUgaW4KICAgICAgICAgICAgICAgICAgICAub25lKCdic1RyYW5zaXRpb25FbmQnLCBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuJGVsZW1lbnQudHJpZ2dlcignZm9jdXMnKS50cmlnZ2VyKGUpCiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgICAgICAuZW11bGF0ZVRyYW5zaXRpb25FbmQoTW9kYWwuVFJBTlNJVElPTl9EVVJBVElPTikgOgogICAgICAgICAgICAgICAgdGhhdC4kZWxlbWVudC50cmlnZ2VyKCdmb2N1cycpLnRyaWdnZXIoZSkKICAgICAgICB9KQogICAgfQoKICAgIE1vZGFsLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKGUpIHsKICAgICAgICBpZiAoZSkgZS5wcmV2ZW50RGVmYXVsdCgpCgogICAgICAgIGUgPSAkLkV2ZW50KCdoaWRlLmJzLm1vZGFsJykKCiAgICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKGUpCgogICAgICAgIGlmICghdGhpcy5pc1Nob3duIHx8IGUuaXNEZWZhdWx0UHJldmVudGVkKCkpIHJldHVybgoKICAgICAgICB0aGlzLmlzU2hvd24gPSBmYWxzZQoKICAgICAgICB0aGlzLmVzY2FwZSgpCiAgICAgICAgdGhpcy5yZXNpemUoKQoKICAgICAgICAkKGRvY3VtZW50KS5vZmYoJ2ZvY3VzaW4uYnMubW9kYWwnKQoKICAgICAgICB0aGlzLiRlbGVtZW50CiAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnaW4nKQogICAgICAgICAgICAub2ZmKCdjbGljay5kaXNtaXNzLmJzLm1vZGFsJykKICAgICAgICAgICAgLm9mZignbW91c2V1cC5kaXNtaXNzLmJzLm1vZGFsJykKCiAgICAgICAgdGhpcy4kZGlhbG9nLm9mZignbW91c2Vkb3duLmRpc21pc3MuYnMubW9kYWwnKQoKICAgICAgICAkLnN1cHBvcnQudHJhbnNpdGlvbiAmJiB0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdmYWRlJykgPwogICAgICAgICAgICB0aGlzLiRlbGVtZW50CiAgICAgICAgICAgICAgICAub25lKCdic1RyYW5zaXRpb25FbmQnLCAkLnByb3h5KHRoaXMuaGlkZU1vZGFsLCB0aGlzKSkKICAgICAgICAgICAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChNb2RhbC5UUkFOU0lUSU9OX0RVUkFUSU9OKSA6CiAgICAgICAgICAgIHRoaXMuaGlkZU1vZGFsKCkKICAgIH0KCiAgICBNb2RhbC5wcm90b3R5cGUuZW5mb3JjZUZvY3VzID0gZnVuY3Rpb24gKCkgewogICAgICAgICQoZG9jdW1lbnQpCiAgICAgICAgICAgIC5vZmYoJ2ZvY3VzaW4uYnMubW9kYWwnKSAvLyBndWFyZCBhZ2FpbnN0IGluZmluaXRlIGZvY3VzIGxvb3AKICAgICAgICAgICAgLm9uKCdmb2N1c2luLmJzLm1vZGFsJywgJC5wcm94eShmdW5jdGlvbiAoZSkgewogICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50ICE9PSBlLnRhcmdldCAmJgogICAgICAgICAgICAgICAgICAgIHRoaXMuJGVsZW1lbnRbMF0gIT09IGUudGFyZ2V0ICYmCiAgICAgICAgICAgICAgICAgICAgIXRoaXMuJGVsZW1lbnQuaGFzKGUudGFyZ2V0KS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ2ZvY3VzJykKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwgdGhpcykpCiAgICB9CgogICAgTW9kYWwucHJvdG90eXBlLmVzY2FwZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAodGhpcy5pc1Nob3duICYmIHRoaXMub3B0aW9ucy5rZXlib2FyZCkgewogICAgICAgICAgICB0aGlzLiRlbGVtZW50Lm9uKCdrZXlkb3duLmRpc21pc3MuYnMubW9kYWwnLCAkLnByb3h5KGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgICAgICBlLndoaWNoID09IDI3ICYmIHRoaXMuaGlkZSgpCiAgICAgICAgICAgIH0sIHRoaXMpKQogICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuaXNTaG93bikgewogICAgICAgICAgICB0aGlzLiRlbGVtZW50Lm9mZigna2V5ZG93bi5kaXNtaXNzLmJzLm1vZGFsJykKICAgICAgICB9CiAgICB9CgogICAgTW9kYWwucHJvdG90eXBlLnJlc2l6ZSA9IGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAodGhpcy5pc1Nob3duKSB7CiAgICAgICAgICAgICQod2luZG93KS5vbigncmVzaXplLmJzLm1vZGFsJywgJC5wcm94eSh0aGlzLmhhbmRsZVVwZGF0ZSwgdGhpcykpCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJCh3aW5kb3cpLm9mZigncmVzaXplLmJzLm1vZGFsJykKICAgICAgICB9CiAgICB9CgogICAgTW9kYWwucHJvdG90eXBlLmhpZGVNb2RhbCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgdGhhdCA9IHRoaXMKICAgICAgICB0aGlzLiRlbGVtZW50LmhpZGUoKQogICAgICAgIHRoaXMuYmFja2Ryb3AoZnVuY3Rpb24gKCkgewogICAgICAgICAgICB0aGF0LiRib2R5LnJlbW92ZUNsYXNzKCdtb2RhbC1vcGVuJykKICAgICAgICAgICAgdGhhdC5yZXNldEFkanVzdG1lbnRzKCkKICAgICAgICAgICAgdGhhdC5yZXNldFNjcm9sbGJhcigpCiAgICAgICAgICAgIHRoYXQuJGVsZW1lbnQudHJpZ2dlcignaGlkZGVuLmJzLm1vZGFsJykKICAgICAgICB9KQogICAgfQoKICAgIE1vZGFsLnByb3RvdHlwZS5yZW1vdmVCYWNrZHJvcCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLiRiYWNrZHJvcCAmJiB0aGlzLiRiYWNrZHJvcC5yZW1vdmUoKQogICAgICAgIHRoaXMuJGJhY2tkcm9wID0gbnVsbAogICAgfQoKICAgIE1vZGFsLnByb3RvdHlwZS5iYWNrZHJvcCA9IGZ1bmN0aW9uIChjYWxsYmFjaykgewogICAgICAgIHZhciB0aGF0ID0gdGhpcwogICAgICAgIHZhciBhbmltYXRlID0gdGhpcy4kZWxlbWVudC5oYXNDbGFzcygnZmFkZScpID8gJ2ZhZGUnIDogJycKCiAgICAgICAgaWYgKHRoaXMuaXNTaG93biAmJiB0aGlzLm9wdGlvbnMuYmFja2Ryb3ApIHsKICAgICAgICAgICAgdmFyIGRvQW5pbWF0ZSA9ICQuc3VwcG9ydC50cmFuc2l0aW9uICYmIGFuaW1hdGUKCiAgICAgICAgICAgIHRoaXMuJGJhY2tkcm9wID0gJChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSkKICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnbW9kYWwtYmFja2Ryb3AgJyArIGFuaW1hdGUpCiAgICAgICAgICAgICAgICAuYXBwZW5kVG8odGhpcy4kYm9keSkKCiAgICAgICAgICAgIHRoaXMuJGVsZW1lbnQub24oJ2NsaWNrLmRpc21pc3MuYnMubW9kYWwnLCAkLnByb3h5KGZ1bmN0aW9uIChlKSB7CiAgICAgICAgICAgICAgICBpZiAodGhpcy5pZ25vcmVCYWNrZHJvcENsaWNrKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpcy5pZ25vcmVCYWNrZHJvcENsaWNrID0gZmFsc2UKICAgICAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChlLnRhcmdldCAhPT0gZS5jdXJyZW50VGFyZ2V0KSByZXR1cm4KICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5iYWNrZHJvcCA9PSAnc3RhdGljJwogICAgICAgICAgICAgICAgICAgID8gdGhpcy4kZWxlbWVudFswXS5mb2N1cygpCiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLmhpZGUoKQogICAgICAgICAgICB9LCB0aGlzKSkKCiAgICAgICAgICAgIGlmIChkb0FuaW1hdGUpIHRoaXMuJGJhY2tkcm9wWzBdLm9mZnNldFdpZHRoIC8vIGZvcmNlIHJlZmxvdwoKICAgICAgICAgICAgdGhpcy4kYmFja2Ryb3AuYWRkQ2xhc3MoJ2luJykKCiAgICAgICAgICAgIGlmICghY2FsbGJhY2spIHJldHVybgoKICAgICAgICAgICAgZG9BbmltYXRlID8KICAgICAgICAgICAgICAgIHRoaXMuJGJhY2tkcm9wCiAgICAgICAgICAgICAgICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgY2FsbGJhY2spCiAgICAgICAgICAgICAgICAgICAgLmVtdWxhdGVUcmFuc2l0aW9uRW5kKE1vZGFsLkJBQ0tEUk9QX1RSQU5TSVRJT05fRFVSQVRJT04pIDoKICAgICAgICAgICAgICAgIGNhbGxiYWNrKCkKCiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5pc1Nob3duICYmIHRoaXMuJGJhY2tkcm9wKSB7CiAgICAgICAgICAgIHRoaXMuJGJhY2tkcm9wLnJlbW92ZUNsYXNzKCdpbicpCgogICAgICAgICAgICB2YXIgY2FsbGJhY2tSZW1vdmUgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB0aGF0LnJlbW92ZUJhY2tkcm9wKCkKICAgICAgICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKCkKICAgICAgICAgICAgfQogICAgICAgICAgICAkLnN1cHBvcnQudHJhbnNpdGlvbiAmJiB0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdmYWRlJykgPwogICAgICAgICAgICAgICAgdGhpcy4kYmFja2Ryb3AKICAgICAgICAgICAgICAgICAgICAub25lKCdic1RyYW5zaXRpb25FbmQnLCBjYWxsYmFja1JlbW92ZSkKICAgICAgICAgICAgICAgICAgICAuZW11bGF0ZVRyYW5zaXRpb25FbmQoTW9kYWwuQkFDS0RST1BfVFJBTlNJVElPTl9EVVJBVElPTikgOgogICAgICAgICAgICAgICAgY2FsbGJhY2tSZW1vdmUoKQoKICAgICAgICB9IGVsc2UgaWYgKGNhbGxiYWNrKSB7CiAgICAgICAgICAgIGNhbGxiYWNrKCkKICAgICAgICB9CiAgICB9CgogICAgLy8gdGhlc2UgZm9sbG93aW5nIG1ldGhvZHMgYXJlIHVzZWQgdG8gaGFuZGxlIG92ZXJmbG93aW5nIG1vZGFscwoKICAgIE1vZGFsLnByb3RvdHlwZS5oYW5kbGVVcGRhdGUgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdGhpcy5hZGp1c3REaWFsb2coKQogICAgfQoKICAgIE1vZGFsLnByb3RvdHlwZS5hZGp1c3REaWFsb2cgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgdmFyIG1vZGFsSXNPdmVyZmxvd2luZyA9IHRoaXMuJGVsZW1lbnRbMF0uc2Nyb2xsSGVpZ2h0ID4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodAoKICAgICAgICB0aGlzLiRlbGVtZW50LmNzcyh7CiAgICAgICAgICAgIHBhZGRpbmdMZWZ0OiAhdGhpcy5ib2R5SXNPdmVyZmxvd2luZyAmJiBtb2RhbElzT3ZlcmZsb3dpbmcgPyB0aGlzLnNjcm9sbGJhcldpZHRoIDogJycsCiAgICAgICAgICAgIHBhZGRpbmdSaWdodDogdGhpcy5ib2R5SXNPdmVyZmxvd2luZyAmJiAhbW9kYWxJc092ZXJmbG93aW5nID8gdGhpcy5zY3JvbGxiYXJXaWR0aCA6ICcnCiAgICAgICAgfSkKICAgIH0KCiAgICBNb2RhbC5wcm90b3R5cGUucmVzZXRBZGp1c3RtZW50cyA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLiRlbGVtZW50LmNzcyh7CiAgICAgICAgICAgIHBhZGRpbmdMZWZ0OiAnJywKICAgICAgICAgICAgcGFkZGluZ1JpZ2h0OiAnJwogICAgICAgIH0pCiAgICB9CgogICAgTW9kYWwucHJvdG90eXBlLmNoZWNrU2Nyb2xsYmFyID0gZnVuY3Rpb24gKCkgewogICAgICAgIHZhciBmdWxsV2luZG93V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aAogICAgICAgIGlmICghZnVsbFdpbmRvd1dpZHRoKSB7IC8vIHdvcmthcm91bmQgZm9yIG1pc3Npbmcgd2luZG93LmlubmVyV2lkdGggaW4gSUU4CiAgICAgICAgICAgIHZhciBkb2N1bWVudEVsZW1lbnRSZWN0ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpCiAgICAgICAgICAgIGZ1bGxXaW5kb3dXaWR0aCA9IGRvY3VtZW50RWxlbWVudFJlY3QucmlnaHQgLSBNYXRoLmFicyhkb2N1bWVudEVsZW1lbnRSZWN0LmxlZnQpCiAgICAgICAgfQogICAgICAgIHRoaXMuYm9keUlzT3ZlcmZsb3dpbmcgPSBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoIDwgZnVsbFdpbmRvd1dpZHRoCiAgICAgICAgdGhpcy5zY3JvbGxiYXJXaWR0aCA9IHRoaXMubWVhc3VyZVNjcm9sbGJhcigpCiAgICB9CgogICAgTW9kYWwucHJvdG90eXBlLnNldFNjcm9sbGJhciA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB2YXIgYm9keVBhZCA9IHBhcnNlSW50KCh0aGlzLiRib2R5LmNzcygncGFkZGluZy1yaWdodCcpIHx8IDApLCAxMCkKICAgICAgICB0aGlzLm9yaWdpbmFsQm9keVBhZCA9IGRvY3VtZW50LmJvZHkuc3R5bGUucGFkZGluZ1JpZ2h0IHx8ICcnCiAgICAgICAgdmFyIHNjcm9sbGJhcldpZHRoID0gdGhpcy5zY3JvbGxiYXJXaWR0aAogICAgICAgIGlmICh0aGlzLmJvZHlJc092ZXJmbG93aW5nKSB7CiAgICAgICAgICAgIHRoaXMuJGJvZHkuY3NzKCdwYWRkaW5nLXJpZ2h0JywgYm9keVBhZCArIHNjcm9sbGJhcldpZHRoKQogICAgICAgICAgICAkKHRoaXMuZml4ZWRDb250ZW50KS5lYWNoKGZ1bmN0aW9uIChpbmRleCwgZWxlbWVudCkgewogICAgICAgICAgICAgICAgdmFyIGFjdHVhbFBhZGRpbmcgPSBlbGVtZW50LnN0eWxlLnBhZGRpbmdSaWdodAogICAgICAgICAgICAgICAgdmFyIGNhbGN1bGF0ZWRQYWRkaW5nID0gJChlbGVtZW50KS5jc3MoJ3BhZGRpbmctcmlnaHQnKQogICAgICAgICAgICAgICAgJChlbGVtZW50KQogICAgICAgICAgICAgICAgICAgIC5kYXRhKCdwYWRkaW5nLXJpZ2h0JywgYWN0dWFsUGFkZGluZykKICAgICAgICAgICAgICAgICAgICAuY3NzKCdwYWRkaW5nLXJpZ2h0JywgcGFyc2VGbG9hdChjYWxjdWxhdGVkUGFkZGluZykgKyBzY3JvbGxiYXJXaWR0aCArICdweCcpCiAgICAgICAgICAgIH0pCiAgICAgICAgfQogICAgfQoKICAgIE1vZGFsLnByb3RvdHlwZS5yZXNldFNjcm9sbGJhciA9IGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLiRib2R5LmNzcygncGFkZGluZy1yaWdodCcsIHRoaXMub3JpZ2luYWxCb2R5UGFkKQogICAgICAgICQodGhpcy5maXhlZENvbnRlbnQpLmVhY2goZnVuY3Rpb24gKGluZGV4LCBlbGVtZW50KSB7CiAgICAgICAgICAgIHZhciBwYWRkaW5nID0gJChlbGVtZW50KS5kYXRhKCdwYWRkaW5nLXJpZ2h0JykKICAgICAgICAgICAgJChlbGVtZW50KS5yZW1vdmVEYXRhKCdwYWRkaW5nLXJpZ2h0JykKICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5wYWRkaW5nUmlnaHQgPSBwYWRkaW5nID8gcGFkZGluZyA6ICcnCiAgICAgICAgfSkKICAgIH0KCiAgICBNb2RhbC5wcm90b3R5cGUubWVhc3VyZVNjcm9sbGJhciA9IGZ1bmN0aW9uICgpIHsgLy8gdGh4IHdhbHNoCiAgICAgICAgdmFyIHNjcm9sbERpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpCiAgICAgICAgc2Nyb2xsRGl2LmNsYXNzTmFtZSA9ICdtb2RhbC1zY3JvbGxiYXItbWVhc3VyZScKICAgICAgICB0aGlzLiRib2R5LmFwcGVuZChzY3JvbGxEaXYpCiAgICAgICAgdmFyIHNjcm9sbGJhcldpZHRoID0gc2Nyb2xsRGl2Lm9mZnNldFdpZHRoIC0gc2Nyb2xsRGl2LmNsaWVudFdpZHRoCiAgICAgICAgdGhpcy4kYm9keVswXS5yZW1vdmVDaGlsZChzY3JvbGxEaXYpCiAgICAgICAgcmV0dXJuIHNjcm9sbGJhcldpZHRoCiAgICB9CgoKICAgIC8vIE1PREFMIFBMVUdJTiBERUZJTklUSU9OCiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PQoKICAgIGZ1bmN0aW9uIFBsdWdpbihvcHRpb24sIF9yZWxhdGVkVGFyZ2V0KSB7CiAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHZhciAkdGhpcyA9ICQodGhpcykKICAgICAgICAgICAgdmFyIGRhdGEgPSAkdGhpcy5kYXRhKCdicy5tb2RhbCcpCiAgICAgICAgICAgIHZhciBvcHRpb25zID0gJC5leHRlbmQoe30sIE1vZGFsLkRFRkFVTFRTLCAkdGhpcy5kYXRhKCksIHR5cGVvZiBvcHRpb24gPT0gJ29iamVjdCcgJiYgb3B0aW9uKQoKICAgICAgICAgICAgaWYgKCFkYXRhKSAkdGhpcy5kYXRhKCdicy5tb2RhbCcsIChkYXRhID0gbmV3IE1vZGFsKHRoaXMsIG9wdGlvbnMpKSkKICAgICAgICAgICAgaWYgKHR5cGVvZiBvcHRpb24gPT0gJ3N0cmluZycpIGRhdGFbb3B0aW9uXShfcmVsYXRlZFRhcmdldCkKICAgICAgICAgICAgZWxzZSBpZiAob3B0aW9ucy5zaG93KSBkYXRhLnNob3coX3JlbGF0ZWRUYXJnZXQpCiAgICAgICAgfSkKICAgIH0KCiAgICB2YXIgb2xkID0gJC5mbi5tb2RhbAoKICAgICQuZm4ubW9kYWwgPSBQbHVnaW4KICAgICQuZm4ubW9kYWwuQ29uc3RydWN0b3IgPSBNb2RhbAoKCiAgICAvLyBNT0RBTCBOTyBDT05GTElDVAogICAgLy8gPT09PT09PT09PT09PT09PT0KCiAgICAkLmZuLm1vZGFsLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgJC5mbi5tb2RhbCA9IG9sZAogICAgICAgIHJldHVybiB0aGlzCiAgICB9CgoKICAgIC8vIE1PREFMIERBVEEtQVBJCiAgICAvLyA9PT09PT09PT09PT09PQoKICAgICQoZG9jdW1lbnQpLm9uKCdjbGljay5icy5tb2RhbC5kYXRhLWFwaScsICdbZGF0YS10b2dnbGU9Im1vZGFsIl0nLCBmdW5jdGlvbiAoZSkgewogICAgICAgIHZhciAkdGhpcyA9ICQodGhpcykKICAgICAgICB2YXIgaHJlZiA9ICR0aGlzLmF0dHIoJ2hyZWYnKQogICAgICAgIHZhciB0YXJnZXQgPSAkdGhpcy5hdHRyKCdkYXRhLXRhcmdldCcpIHx8CiAgICAgICAgICAgIChocmVmICYmIGhyZWYucmVwbGFjZSgvLiooPz0jW15cc10rJCkvLCAnJykpIC8vIHN0cmlwIGZvciBpZTcKCiAgICAgICAgdmFyICR0YXJnZXQgPSAkKGRvY3VtZW50KS5maW5kKHRhcmdldCkKICAgICAgICB2YXIgb3B0aW9uID0gJHRhcmdldC5kYXRhKCdicy5tb2RhbCcpID8gJ3RvZ2dsZScgOiAkLmV4dGVuZCh7IHJlbW90ZTogIS8jLy50ZXN0KGhyZWYpICYmIGhyZWYgfSwgJHRhcmdldC5kYXRhKCksICR0aGlzLmRhdGEoKSkKCiAgICAgICAgaWYgKCR0aGlzLmlzKCdhJykpIGUucHJldmVudERlZmF1bHQoKQoKICAgICAgICAkdGFyZ2V0Lm9uZSgnc2hvdy5icy5tb2RhbCcsIGZ1bmN0aW9uIChzaG93RXZlbnQpIHsKICAgICAgICAgICAgaWYgKHNob3dFdmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSkgcmV0dXJuIC8vIG9ubHkgcmVnaXN0ZXIgZm9jdXMgcmVzdG9yZXIgaWYgbW9kYWwgd2lsbCBhY3R1YWxseSBnZXQgc2hvd24KICAgICAgICAgICAgJHRhcmdldC5vbmUoJ2hpZGRlbi5icy5tb2RhbCcsIGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICR0aGlzLmlzKCc6dmlzaWJsZScpICYmICR0aGlzLnRyaWdnZXIoJ2ZvY3VzJykKICAgICAgICAgICAgfSkKICAgICAgICB9KQogICAgICAgIFBsdWdpbi5jYWxsKCR0YXJnZXQsIG9wdGlvbiwgdGhpcykKICAgIH0pCgp9KSgkKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX18KICoKICogIENvcHlyaWdodCAyMDE0IEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogKiBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiBzdXBwbGllcnMgYW5kIG1heSBiZSBjb3ZlcmVkIGJ5IFUuUy4gYW5kIEZvcmVpZ24gUGF0ZW50cywKICogcGF0ZW50cyBpbiBwcm9jZXNzLCBhbmQgYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4KICogRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqIGZyb20gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgokKGZ1bmN0aW9uICgkKSB7CiAgICAvLyAkZG9jLnJlYWR5IGZvciBqcXVlcnkgMS44IGNhdXNpbmcgaXNzdWVzIGZvciBJRSBzbwogICAgLy8gZG9pbmcgd2lkZ2V0IGluaXRpYWxpemF0aW9uIG9uIGNvbm5lY3QKIHdpbmRvdy5mb3JtQnJpZGdlLmNvbm5lY3QoZnVuY3Rpb24gKCkgewogICAgIHZhciBtZXRob2QgPSB7CiAgICAgICAgIGluaXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgIHZhciAkcGx1Z0ZpbGVXaWRnZXREb20gPSAkKCdbZGF0YS1maWxld2lkZ2V0PSJ0cnVlIl0nKSwKICAgICAgICAgICAgICAgICBvcHRpb25zLAogICAgICAgICAgICAgICAgICRmaWxlV2lkZ2V0LAogICAgICAgICAgICAgICAgICRpbnB1dFdpZGdldCwKICAgICAgICAgICAgICAgICAkYnV0dG9uV2lkZ2V0LAogICAgICAgICAgICAgICAgICRsaXN0V2lkZ2V0LAogICAgICAgICAgICAgICAgIHdpZGdldE5hbWUsCiAgICAgICAgICAgICAgICAgbXVsdGlTZWxlY3QgPSB0cnVlLAogICAgICAgICAgICAgICAgIG9wdGlvbnNUb1dpZGdldDsKICAgICAgICAgICAgICAgICBvcHRpb25zID0gJHBsdWdGaWxlV2lkZ2V0RG9tLmRhdGEoIm9wdGlvbnMiKSB8fCB7fTsKICAgICAgICAgICAgICAgICBvcHRpb25zLmJ1dHRvblRleHQgPSBvcHRpb25zLmJ1dHRvblRleHQgfHwgIkF0dGFjaCI7CiAgICAgICAgICAgICAgICAgb3B0aW9ucy5hY2NlcHQgPSBvcHRpb25zLmFjY2VwdCB8fCAiYXVkaW8vKiwgdmlkZW8vKiwgaW1hZ2UvKiwgdGV4dC8qLCBhcHBsaWNhdGlvbi9wZGYiOwogICAgICAgICAgICAgICAgICRmaWxlV2lkZ2V0ID0gJCgiPGRpdj48L2Rpdj4iKS5hZGRDbGFzcygiZ3VpZGVGaWVsZFdpZGdldCIpLmFkZENsYXNzKCJmaWxlVXBsb2FkIikuYXR0cigic3R5bGUiLCIiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJ0aXRsZSIsIHhmYWxpYi5sb2NhbGUuU3RyaW5nc1siQXR0YWNoIl0pOwoKICAgICAgICAgICAgICAgICAkaW5wdXRXaWRnZXQgPSAkKCI8aW5wdXQvPiIpLmF0dHIoImlkIiwgImZpbGVVcGxvYWRfd2lkZ2V0IikuYXR0cigibmFtZSIsICJmaWxlVXBsb2FkIikKICAgICAgICAgICAgICAgICAgICAgLmF0dHIoInR5cGUiLCJmaWxlIikKICAgICAgICAgICAgICAgICAgICAgLmF0dHIoInN0eWxlIiwgIiIpCiAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJhY2NlcHQiLG9wdGlvbnMuYWNjZXB0KQogICAgICAgICAgICAgICAgICAgICAuYXR0cigidGFiaW5kZXgiLCAiLTEiKQogICAgICAgICAgICAgICAgICAgICAuYXR0cigiY2FwdHVyZSIsIiIpOwoKICAgICAgICAgICAgICAgICAkYnV0dG9uV2lkZ2V0ID0gJCgiPGJ1dHRvbj48L2J1dHRvbj4iKS5hZGRDbGFzcygiYnV0dG9uLWRlZmF1bHQiKS5hZGRDbGFzcygiYnV0dG9uLW1lZGl1bSIpCiAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygiZ3VpZGUtZnUtYXR0YWNoLWJ1dHRvbiIpCiAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCJ0eXBlIiwgImZpbGUiKQogICAgICAgICAgICAgICAgICAgICAuaHRtbChvcHRpb25zLmJ1dHRvblRleHQpOwoKICAgICAgICAgICAgICAgICAkbGlzdFdpZGdldD0gJCgnPHVsPjwvdWw+JykuYWRkQ2xhc3MoImd1aWRlLWZ1LWZpbGVJdGVtTGlzdCIpOwogICAgICAgICAgICAgICAgICRmaWxlV2lkZ2V0LmFwcGVuZCgkaW5wdXRXaWRnZXQpLmFwcGVuZCgkYnV0dG9uV2lkZ2V0KS5hcHBlbmQoJGxpc3RXaWRnZXQpOwogICAgICAgICAgICAgICAgICRmaWxlV2lkZ2V0LmFwcGVuZFRvKCRwbHVnRmlsZVdpZGdldERvbSk7CiAgICAgICAgICAgICAgICAgd2lkZ2V0TmFtZSA9IG9wdGlvbnMud2lkZ2V0TmFtZSB8fCAiZmlsZVVwbG9hZCI7CiAgICAgICAgICAgICAgICAgLy8gbXVsdGlTZWxlY3QgaXMgZXhwZWN0ZWQgdG8gYmUgYm9vbGVhbiBieSB3aWRnZXQKICAgICAgICAgICAgICAgICAvLyBBbmQgdGhlIHByb2ZpbGUgbm9kZSBwYXNzZXMgaXQgYXMgc3RyaW5nCiAgICAgICAgICAgICAgICAgLy8gYW5kIHdpZGdldC5qc3AgcGFzc2VzIHRoZSBzYW1lIGFzIGJvb2xlYW4KICAgICAgICAgICAgICAgICAvLyAgb3B0aW9ucy5tdWx0aVNlbGVjdCBjYW4gYmUgInRydWUiICwgICJmYWxzZSIKICAgICAgICAgICAgICAgICAvLyBvciBjYW4gYmUgdHJ1ZSAsICBmYWxzZQogICAgICAgICAgICAgICAgIC8vIG9yIGl0IGNhbiBiZSB1bmRlZmluZWQgKHdoZW4gaW5pdGlhbGl6aW5nICBtdWx0aVNlbGVjdCAgdG8gdHJ1ZSBkZWZpbmVzIGRlZmF1bHQgYmVoYXZpb3VyICkKICAgICAgICAgICAgICAgICBpZihfLmlzQm9vbGVhbihvcHRpb25zLm11bHRpU2VsZWN0KSkgewogICAgICAgICAgICAgICAgICAgICBtdWx0aVNlbGVjdCA9IG9wdGlvbnMubXVsdGlTZWxlY3Q7CiAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChfLmlzU3RyaW5nKG9wdGlvbnMubXVsdGlTZWxlY3QpKSB7CiAgICAgICAgICAgICAgICAgICAgIG11bHRpU2VsZWN0ID0gb3B0aW9ucy5tdWx0aVNlbGVjdC50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZSc7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIG9wdGlvbnNUb1dpZGdldCA9ICAgewogICAgICAgICAgICAgICAgICAgICBidXR0b25UZXh0ICA6IG9wdGlvbnMuYnV0dG9uVGV4dCB8fCAiQXR0YWNoIiwKICAgICAgICAgICAgICAgICAgICAgbXVsdGlTZWxlY3QgOiAgbXVsdGlTZWxlY3QsCiAgICAgICAgICAgICAgICAgICAgIGZpbGVTaXplTGltaXQgOiBvcHRpb25zLmZpbGVTaXplTGltaXQgfHwgIjIiLAogICAgICAgICAgICAgICAgICAgICBidXR0b25DbGFzcyA6IG9wdGlvbnMuYnV0dG9uQ2xhc3MgfHwgImJ1dHRvbi5ndWlkZS1mdS1hdHRhY2gtYnV0dG9uIiwKICAgICAgICAgICAgICAgICAgICAgZmlsZUl0ZW1MaXN0Q2xhc3MgOiBvcHRpb25zLmZpbGVJdGVtTGlzdENsYXNzfHwgInVsLmd1aWRlLWZ1LWZpbGVJdGVtTGlzdCIsCiAgICAgICAgICAgICAgICAgICAgIGlmcmFtZUNvbnRhaW5lcjogb3B0aW9ucy5pZnJhbWVDb250YWluZXIgfHwgImJvZHkjZm9ybUJvZHkiLAogICAgICAgICAgICAgICAgICAgICBzaG93Q29tbWVudCA6ICBvcHRpb25zLnNob3dDb21tZW50IHx8IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICBfdXVpZEdlbmVyYXRvcjogZnVuY3Rpb24gKCkgeyByZXR1cm4gZm9ybUJyaWRnZS5fZ2V0VVVJRC5hcHBseSh0aGlzKTsgfSwKICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMudmFsdWUgfHwgeGZhbGliLnJ1bnRpbWUuZmlsZUF0dGFjaG1lbnQgLAogICAgICAgICAgICAgICAgICAgICBfZmlsZVBhdGg6IG9wdGlvbnMuX2ZpbGVQYXRoIHx8ICIvdG1wL2ZkL3hmYWZvcm5zIiwKICAgICAgICAgICAgICAgICAgICAgd2lkZ2V0TmFtZTogImZpbGVVcGxvYWQiLAogICAgICAgICAgICAgICAgICAgICBfZ2V0VXJsOiBvcHRpb25zLl9nZXRVcmwgfHwgZm9ybUJyaWRnZS5fZ2V0VXJsKCIiKSwKICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZVByZXZpZXc6IG9wdGlvbnMuZGlzYWJsZVByZXZpZXcgfHwgZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgIHVwbG9hZGVyUGx1Z2luTmFtZTogImFkb2JlRmlsZVVwbG9hZGVyIgoKCgogICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgdmFyIHdpZGdldCA9ICRmaWxlV2lkZ2V0W3dpZGdldE5hbWVdKG9wdGlvbnNUb1dpZGdldCk7CiAgICAgICAgICAgICAgICAgeGZhbGliLnJ1bnRpbWUuZmlsZVVwbG9hZFdpZGdldCA9IHdpZGdldC5kYXRhKHdpZGdldE5hbWUpIHx8IHdpZGdldC5kYXRhKCJ4ZmFXaWRnZXQtIiArIHdpZGdldE5hbWUpOwogICAgICAgICAgICAgfQogICAgIH07CiAgICAgbWV0aG9kLmluaXQoKTsKIH0pOwp9KTsKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQURPQkUgQ09ORklERU5USUFMCiAqICBfX19fX19fX19fX19fX19fX19fCiAqCiAqICAgQ29weXJpZ2h0IDIwMTMgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiAgTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqICB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqICBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkCiAqICBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogIHN1cHBsaWVycyBhbmQgYXJlIHByb3RlY3RlZCBieSBhbGwgYXBwbGljYWJsZSBpbnRlbGxlY3R1YWwgcHJvcGVydHkKICogIGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiAgRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsCiAqICBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiAgZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCihmdW5jdGlvbiAoJCkgewogICAgZnVuY3Rpb24gaGFuZGxlU2Nyb2xsKGV2ZW50KSB7CiAgICAgICAgdmFyIHBhZ2luZ01hbmFnZXIgPSB3aW5kb3cuZm9ybUJyaWRnZSA/IHdpbmRvdy5mb3JtQnJpZGdlLnBhZ2luZ01hbmFnZXIoKSA6IG51bGw7CiAgICAgICAgdmFyIHNjcm9sbFRvcCA9ICQod2luZG93KS5zY3JvbGxUb3AoKTsKICAgICAgICB2YXIgd2luSGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0ID8gd2luZG93LmlubmVySGVpZ2h0IDogJCh3aW5kb3cpLmhlaWdodCgpOwogICAgICAgIHZhciB3aW5CdG1Qb3MgPSBzY3JvbGxUb3AgKyB3aW5IZWlnaHQ7CiAgICAgICAgdmFyICRib2R5RWwgPSAkKCIjZm9ybUJvZHkiKTsKICAgICAgICAvKldlIGFsc28gbmVlZCB0byB0YWtlIGJvZHlTY2FsZUZhY3RvciBpbnRvIGFjY291bnQgaW4gb3JkZXIgdG8gY29tcGFyZSBpdCB3aXRoIHdpbmRvdyBoZWlnaHQuKi8KICAgICAgICB2YXIgYm9keUJvdHRvbSA9ICRib2R5RWwuaGVpZ2h0KCkgKiB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuZm9ybVNjYWxlRmFjdG9yICsgJGJvZHlFbC5vZmZzZXQoKS50b3A7CiAgICAgICAgaWYgKGJvZHlCb3R0b20gPCB3aW5CdG1Qb3MgKyA1MCkgewogICAgICAgICAgICBpZiAocGFnaW5nTWFuYWdlciAmJiBwYWdpbmdNYW5hZ2VyLmhhc01vcmVQYWdlcygpKSB7CiAgICAgICAgICAgICAgICAkKCcjbG9hZGluZ3BhZ2UnKS5jaGlsZHJlbigiOm5vdChhLnBhZ2Vsb2Fkbm93KSIpLmNzcygidmlzaWJpbGl0eSIsICJ2aXNpYmxlIik7CiAgICAgICAgICAgICAgICB4ZmFsaWIudXQuWGZhVXRpbC5wcm90b3R5cGUuY2xlYXJUaW1lb3V0T25EZXN0cm95KHNldFRpbWVvdXQocmVuZGVyTmV4dFBhZ2UsIDUpKTsgLy93b3JrYXJvdW5kIGZvciBJUEFEIHRvIHNob3cgaW50ZXJtZWRpYXRlIGxvYWQgaWNvbgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGhhbmRsZUZvb3RlckxvZ2ljKCkgewogICAgICAgIHZhciBwYWdpbmdNYW5hZ2VyID0gd2luZG93LmZvcm1CcmlkZ2UgPyB3aW5kb3cuZm9ybUJyaWRnZS5wYWdpbmdNYW5hZ2VyKCkgOiBudWxsOwogICAgICAgIGlmIChwYWdpbmdNYW5hZ2VyID09IG51bGwpIHJldHVybjsKICAgICAgICBpZiAoIXBhZ2luZ01hbmFnZXIuaGFzTW9yZVBhZ2VzKCkpIHsKICAgICAgICAgICAgJCgnI2xvYWRpbmdwYWdlJykuY3NzKHtkaXNwbGF5OiAibm9uZSJ9KTsKICAgICAgICAgICAgJCh3aW5kb3cpLm9mZigic2Nyb2xsLnhmYXZpZXciKTsKICAgICAgICAgICAgJCgnI25vbW9yZXBhZ2VzJykuY3NzKHtkaXNwbGF5OiAiaW5saW5lLWJsb2NrIn0pOwogICAgICAgIH0gZWxzZSBpZiAocGFnaW5nTWFuYWdlci5oYXNNb3JlUGFnZXMoKSkgewogICAgICAgICAgICAkKCcjbG9hZGluZ3BhZ2UnKS5jaGlsZHJlbigiOm5vdChhLnBhZ2Vsb2Fkbm93KSIpLmNzcyh7dmlzaWJpbGl0eTogImhpZGRlbiJ9KTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gcmVuZGVyTmV4dFBhZ2UoaW5pdGlhbExvYWQpIHsKICAgICAgICB2YXIgcGFnaW5nTWFuYWdlciA9IHdpbmRvdy5mb3JtQnJpZGdlID8gd2luZG93LmZvcm1CcmlkZ2UucGFnaW5nTWFuYWdlcigpIDogbnVsbDsKICAgICAgICBpZiAoIWluaXRpYWxMb2FkICYmIHBhZ2luZ01hbmFnZXIpIHsKICAgICAgICAgICAgcGFnaW5nTWFuYWdlci5yZW5kZXJOZXh0UGFnZSgpOwogICAgICAgIH0KICAgICAgICBoYW5kbGVGb290ZXJMb2dpYygpOwogICAgICAgICQoZm9ybUJyaWRnZSkudHJpZ2dlcigieGZhTmV4dFBhZ2VSZW5kZXJlZCIpOwogICAgfQoKICAgIHdpbmRvdy5yZW5kZXJOZXh0UGFnZSA9IHJlbmRlck5leHRQYWdlOwogICAgd2luZG93LmhhbmRsZUZvb3RlckxvZ2ljID0gaGFuZGxlRm9vdGVyTG9naWM7CiAgICB3aW5kb3cuaGFuZGxlU2Nyb2xsID0gaGFuZGxlU2Nyb2xsOwp9KSgkKTsKCgovKioKIEFET0JFIENPTkZJREVOVElBTAoKIENvcHlyaWdodCAyMDE0IEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiBBbGwgUmlnaHRzIFJlc2VydmVkLgoKIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogdGhlIHByb3BlcnR5IG9mIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMgc3VwcGxpZXJzLAogaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiBzdXBwbGllcnMgYW5kIG1heSBiZSBjb3ZlcmVkIGJ5IFUuUy4gYW5kIEZvcmVpZ24gUGF0ZW50cywKIHBhdGVudHMgaW4gcHJvY2VzcywgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuCiBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKi8KCihmdW5jdGlvbiAoJCkgewogICAgd2luZG93LkZEID0gd2luZG93LkZEIHx8IHt9OwogICAgRkQuRlAgICAgID0gRkQuRlAgfHwge307CiAgICBGRC5GUC5NRiA9IEZELkZQLk1GIHx8IHt9OwogICAgRkQuRlAuTUYgPSB7CiAgICAgICAgc2F2ZU1GRHJhZnQgOiBmdW5jdGlvbigpewogICAgICAgICAgICB2YXIgZHJhZnRJRCA9IHdpbmRvdy5mb3JtQnJpZGdlLmN1c3RvbUNvbnRleHRQcm9wZXJ0eSgibWZEcmFmdElkIiksCiAgICAgICAgICAgICAgICBmaWxlTGlzdCA9ICIiLAogICAgICAgICAgICAgICAgZm9ybVBhdGggPSB3aW5kb3cueGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dC5jb250ZW50Um9vdC5zdWJzdHJpbmcoNikgKyAiLyIgK3dpbmRvdy54ZmFsaWIucnVudGltZS5yZW5kZXJDb250ZXh0LnRlbXBsYXRlLAogICAgICAgICAgICAgICAgZm9ybU5hbWUgPSB3aW5kb3cueGZhbGliLnJ1bnRpbWUucmVuZGVyQ29udGV4dC50ZW1wbGF0ZSwKICAgICAgICAgICAgICAgIGZvcm1EYXRhID0gIG51bGwsCiAgICAgICAgICAgICAgICB1cmxGb3JEcmFmdCA9IHdpbmRvdy5mb3JtQnJpZGdlLl9nZXRVcmwoZm9ybVBhdGgpICsgIi9qY3I6Y29udGVudC5mcC5kcmFmdC5qc29uP2Z1bmM9c2F2ZURyYWZ0IiwKICAgICAgICAgICAgICAgIHByb2ZpbGUgPSB4ZmFsaWIucnVudGltZS5jdXN0b21Qcm9wZXJ0eU1hcC5wcm9maWxlLAogICAgICAgICAgICAgICAgc3VibWl0VXJsID0geGZhbGliLnJ1bnRpbWUuY3VzdG9tUHJvcGVydHlNYXAuc3VibWl0VXJsLAogICAgICAgICAgICAgICAgaW5zdGFuY2VJZCA9IHdpbmRvdy5mb3JtQnJpZGdlLmN1c3RvbUNvbnRleHRQcm9wZXJ0eSgiaW5zdGFuY2VJZCIpOwoKICAgICAgICAgICAgdmFyIGZpbGVVcGxvYWRQYXRoID0gd2luZG93LmZvcm1CcmlkZ2UuX2dldFVybChmb3JtUGF0aCkgKyAiL2pjcjpjb250ZW50LmZwLmF0dGFjaC5qc3AvIiArIGRyYWZ0SUQsCiAgICAgICAgICAgICAgICBzaG93RHJhZnRTdGF0dXMgPSBmdW5jdGlvbihtZXNzYWdlLGlkKXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKCIjIitpZCkudGV4dChtZXNzYWdlKS5zaG93KCkuZmFkZU91dCgxNjAwLCJsaW5lYXIiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICB2YXIgb2JqID0gewogICAgICAgICAgICAgICAgInN1Y2Nlc3MiOmZ1bmN0aW9uKHJlc3VsdCl7CiAgICAgICAgICAgICAgICAgICAgd2luZG93LmZvcm1CcmlkZ2UudHJpZ2dlcigKICAgICAgICAgICAgICAgICAgICAgICAgInNhdmVTdGFydGVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LnhmYWxpYi5zY3JpcHQuWGZhTW9kZWxFdmVudC5jcmVhdGVFdmVudCAoInNhdmVTdGFydGVkIikKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICAgIGZvcm1EYXRhID0gcmVzdWx0LmRhdGE7CiAgICAgICAgICAgICAgICAgICAgdmFyIGRhdGEgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICdmb3JtTmFtZScgIDogZm9ybU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICdmb3JtUGF0aCcgIDogZm9ybVBhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICdmb3JtRGF0YScgIDogZm9ybURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICdkcmFmdElEJyAgIDogZHJhZnRJRCwKICAgICAgICAgICAgICAgICAgICAgICAgJ2Zvcm1UeXBlJyAgOiAibWYiLAogICAgICAgICAgICAgICAgICAgICAgICAnX2NoYXJzZXRfJyA6ICJVVEYtOCIsCiAgICAgICAgICAgICAgICAgICAgICAgICdwcm9maWxlJyAgIDogcHJvZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgJ3N1Ym1pdFVybCcgOiBzdWJtaXRVcmwsCiAgICAgICAgICAgICAgICAgICAgICAgICdmaWxlTGlzdCcgIDogZmlsZUxpc3QKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIGFsbG93ZWRNZXRhZGF0YSA9IFtdOwoKICAgICAgICAgICAgICAgICAgICBpZihpbnN0YW5jZUlkKXsKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVsiaW5zdGFuY2VJZCJdID0gaW5zdGFuY2VJZDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZm9yKGtleSBpbiBkYXRhKXsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoa2V5ICE9PSAnZm9ybURhdGEnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxvd2VkTWV0YWRhdGEucHVzaChrZXkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRhdGFbImZwQWxsb3dlZE1ldGFkYXRhIl0gPSBhbGxvd2VkTWV0YWRhdGEudG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgICAgICAkLmFqYXgoewogICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiJQT1NUIiwKICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiB1cmxGb3JEcmFmdCwKICAgICAgICAgICAgICAgICAgICAgICAgYXN5bmM6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3VsdCkgewoJCQkJCQkJaWYocmVzdWx0ICYmIHJlc3VsdC5kcmFmdElEKXsKCQkJCQkJCQl3aW5kb3cuZm9ybUJyaWRnZS50cmlnZ2VyKAoJCQkJCQkJCQkic2F2ZUNvbXBsZXRlZCIsCgkJCQkJCQkJCXdpbmRvdy54ZmFsaWIuc2NyaXB0LlhmYU1vZGVsRXZlbnQuY3JlYXRlRXZlbnQgKCJzYXZlQ29tcGxldGVkIikKCQkJCQkJCQkpOwoJCQkJCQkJCXNob3dEcmFmdFN0YXR1cyh4ZmFsaWIubG9jYWxlLlN0cmluZ3MuU2F2ZWRTdWNjZXNzZnVsbHksICJmcERyYWZ0U3RhdHVzIik7CgkJCQkJCQkJd2luZG93LmZvcm1CcmlkZ2UuY3VzdG9tQ29udGV4dFByb3BlcnR5KCJtZkRyYWZ0SWQiLHJlc3VsdC5kcmFmdElEKTsKCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkgICAgc2hvd0RyYWZ0U3RhdHVzKHhmYWxpYi5sb2NhbGUuU3RyaW5ncy5VbmFibGVUb1NhdmUsImZwRHJhZnRTdGF0dXMiKTsKCQkJCQkJCX0KICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgOiBmdW5jdGlvbiAocmVzdWx0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93RHJhZnRTdGF0dXMoeGZhbGliLmxvY2FsZS5TdHJpbmdzLlVuYWJsZVRvU2F2ZSwiZnBEcmFmdFN0YXR1cyIpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgImVycm9yIjpmdW5jdGlvbihyZXN1bHQpewogICAgICAgICAgICAgICAgICAgIHNob3dEcmFmdFN0YXR1cyh4ZmFsaWIubG9jYWxlLlN0cmluZ3MuVW5hYmxlVG9TYXZlLCJmcERyYWZ0U3RhdHVzIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHZhciBmaWxlVXBsb2FkT2JqID0gewogICAgICAgICAgICAgICAgInN1Y2Nlc3MiOmZ1bmN0aW9uKHJlc3VsdCl7CiAgICAgICAgICAgICAgICAgICAgJC5lYWNoKHJlc3VsdCwgZnVuY3Rpb24oaW5kZXgsIHJlcykgewogICAgICAgICAgICAgICAgICAgICAgICBmaWxlTGlzdCArPSByZXMucGF0aCArICJcbiI7CiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgLy90byByZW1vdmUgbGFzdCAnXG4nIGZyb20gbGlzdAogICAgICAgICAgICAgICAgICAgIGZpbGVMaXN0ID0gZmlsZUxpc3QucmVwbGFjZSgvXG4kLywgIiIpOwogICAgICAgICAgICAgICAgICAgIHdpbmRvdy5mb3JtQnJpZGdlLmdldERhdGFYTUwob2JqKTsKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAiZXJyb3IiOmZ1bmN0aW9uKHJlc3VsdCl7CgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJmaWxlVXBsb2FkUGF0aCI6ZmlsZVVwbG9hZFBhdGgKICAgICAgICAgICAgfTsKICAgICAgICAgICAgd2luZG93LmZvcm1CcmlkZ2UuZ2V0RmlsZUF0dGFjaG1lbnRzSW5mbyhmaWxlVXBsb2FkT2JqKTsKICAgICAgICB9LAoKICAgICAgICBfc2F2ZU1GRHJhZnRXcmFwcGVyOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGlmICh0eXBlb2Ygd2luZG93LmZvcm1CcmlkZ2UuY3VzdG9tQ29udGV4dFByb3BlcnR5KCJtZkRyYWZ0SWQiKSA9PT0gInVuZGVmaW5lZCIgfHwgd2luZG93LmZvcm1CcmlkZ2UuY3VzdG9tQ29udGV4dFByb3BlcnR5KCJtZkRyYWZ0SWQiKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkLmFqYXgoewogICAgICAgICAgICAgICAgICAgIG1ldGhvZDogIkdFVCIsCiAgICAgICAgICAgICAgICAgICAgdXJsOiBHcmFuaXRlLkhUVFAuZXh0ZXJuYWxpemUoIi9jb250ZW50L2Zvcm1zL3BvcnRhbC9kcmFmdGFuZHN1Ym1pc3Npb24uZnAuZHJhZnQuanNvbj9mdW5jPWdldFVpZCIpLAogICAgICAgICAgICAgICAgICAgIGNhY2hlIDogZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6ICJqc29uIgogICAgICAgICAgICAgICAgfSkuZG9uZShmdW5jdGlvbiAocmVzcG9uc2UpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZHJhZnRJRCA9IHJlc3BvbnNlLmlkOwogICAgICAgICAgICAgICAgICAgIHdpbmRvdy5mb3JtQnJpZGdlLmN1c3RvbUNvbnRleHRQcm9wZXJ0eSgibWZEcmFmdElkIiwgZHJhZnRJRCArICJfbWYiKTsKICAgICAgICAgICAgICAgICAgICBGRC5GUC5NRi5zYXZlTUZEcmFmdCgpOwogICAgICAgICAgICAgICAgfSkuZmFpbChmdW5jdGlvbiAoZXJyb3JPYmopIHsKICAgICAgICAgICAgICAgICAgICAkKCIjZnBEcmFmdFN0YXR1cyIpLnRleHQoeGZhbGliLmxvY2FsZS5TdHJpbmdzLlVuYWJsZVRvU2F2ZSkuc2hvdygpLmZhZGVPdXQoMTYwMCwibGluZWFyIik7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEZELkZQLk1GLnNhdmVNRkRyYWZ0KCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwoKICAgICQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uKCl7CiAgICAgICAgJCgiI3Rvb2xiYXJzYXZlYnRuIikuY2xpY2soZnVuY3Rpb24oKXsKICAgICAgICAgICAgd2luZG93LkZELkZQLk1GLl9zYXZlTUZEcmFmdFdyYXBwZXIoKTsKICAgICAgICB9KQogICAgfSk7Cn0pKGpRdWVyeSk7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFET0JFIENPTkZJREVOVElBTAogKiBfX19fX19fX19fX19fX19fX19fCiAqCiAqIENvcHlyaWdodCAyMDIzIEFkb2JlCiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIE5PVElDRTogQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBhbmQgaXRzIHN1cHBsaWVycywgaWYgYW55LiBUaGUgaW50ZWxsZWN0dWFsCiAqIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUKICogYW5kIGl0cyBzdXBwbGllcnMgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgYWxsIGFwcGxpY2FibGUgaW50ZWxsZWN0dWFsCiAqIHByb3BlcnR5IGxhd3MsIGluY2x1ZGluZyB0cmFkZSBzZWNyZXQgYW5kIGNvcHlyaWdodCBsYXdzLgogKiBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogZnJvbSBBZG9iZS4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKKGZ1bmN0aW9uICgkKSB7Cgl3aW5kb3cuRkQgPSB3aW5kb3cuRkQgfHwge30KCXZhciB0b2dnbGVzOwoKCXZhciBodHRwRXZhbCA9IGZ1bmN0aW9uICh1cmwpIHsKCQl2YXIgcmVzcG9uc2UgPSAkLmFqYXgoewoJCQl1cmw6IHVybCwKCQkJdHlwZTogImdldCIsCgkJCWFzeW5jOiBmYWxzZSwKCQkJZGF0YVR5cGU6ICJqc29uIgoJCX0pOwoJCWlmKHJlc3BvbnNlLnN0YXR1cyE9MjAwKXsKICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoJCXZhciB0ZXh0ID0gcmVzcG9uc2UuYm9keSA/IHJlc3BvbnNlLmJvZHkgOiByZXNwb25zZS5yZXNwb25zZVRleHQ7CgkJcmV0dXJuIEpTT04ucGFyc2UodGV4dCk7Cgl9OwoKCglGRC5pc1RvZ2dsZUVuYWJsZWQgPSBmdW5jdGlvbiAodG9nZ2xlTmFtZSkgewoJCXZhciBjb250ZXh0Um9vdCA9ICh0eXBlb2YgZm9ybUJyaWRnZSAhPT0gJ3VuZGVmaW5lZCcgJiYgZm9ybUJyaWRnZS5fZ2V0Q29udGV4dFJvb3QoKSkgPyBmb3JtQnJpZGdlLl9nZXRDb250ZXh0Um9vdCgpIDoKCQkJKHR5cGVvZiBndWlkZUJyaWRnZSAhPT0gJ3VuZGVmaW5lZCcgJiYgZ3VpZGVCcmlkZ2UuX2dldENvbnRleHRSb290KCkpID8gZ3VpZGVCcmlkZ2UuX2dldENvbnRleHRSb290KCkgOiAiIjsKCQl0b2dnbGVzID0gdG9nZ2xlcyB8fCBodHRwRXZhbChjb250ZXh0Um9vdCArICIvZXRjLmNsaWVudGxpYnMvdG9nZ2xlcy5qc29uIik7CgkJdmFyIHJldFZhbCA9IGZhbHNlOwoJCWlmICh0b2dnbGVzICYmIHRvZ2dsZXMuZW5hYmxlZCBpbnN0YW5jZW9mIEFycmF5KSB7CgkJCXJldFZhbCA9IHRvZ2dsZXMuZW5hYmxlZC5pbmRleE9mKHRvZ2dsZU5hbWUpID4gLTEKCQl9CgkJcmV0dXJuIHJldFZhbDsKCX0KfSkoalF1ZXJ5KTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICogIF9fX19fX19fX19fX19fX19fX18KICoKICogICBDb3B5cmlnaHQgMjAxMyBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAogKiAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqICBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcywgYW5kIHJlbWFpbnMKICogIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cwogKiAgc3VwcGxpZXJzIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IGFsbCBhcHBsaWNhYmxlIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiAgbGF3cywgaW5jbHVkaW5nIHRyYWRlIHNlY3JldCBhbmQgY29weXJpZ2h0IGxhd3MuCiAqICBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogIGlzIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIG9idGFpbmVkCiAqICBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwooZnVuY3Rpb24oJCl7CiAgICB3aW5kb3cuZm9ybUJyaWRnZS5jb25uZWN0KAogICAgICAgIGZ1bmN0aW9uKCl7CiAgICAgICAgICAgIHZhciB0aXRsZVJlc3VsdCA9IHdpbmRvdy5mb3JtQnJpZGdlLmdldEZpZWxkUHJvcGVydGllcygieGZhLmZvcm0uLmRlc2MudGl0bGUiLCJ2YWx1ZSIpOwogICAgICAgICAgICBpZih0aXRsZVJlc3VsdCAmJiAhdGl0bGVSZXN1bHQuZXJyb3JzICYmIHRpdGxlUmVzdWx0LmRhdGEgJiYgdGl0bGVSZXN1bHQuZGF0YVswXSl7CiAgICAgICAgICAgICAgICAkKGRvY3VtZW50KS5hdHRyKCd0aXRsZScsIHRpdGxlUmVzdWx0LmRhdGFbMF0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgKTsKfSkoJCk7CgoKLyoKICogQURPQkUgQ09ORklERU5USUFMCiAqCiAqIENvcHlyaWdodCAyMDE2IEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqIHN1cHBsaWVycyBhbmQgbWF5IGJlIGNvdmVyZWQgYnkgVS5TLiBhbmQgRm9yZWlnbiBQYXRlbnRzLAogKiBwYXRlbnRzIGluIHByb2Nlc3MsIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IHRyYWRlIHNlY3JldCBvciBjb3B5cmlnaHQgbGF3LgogKiBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICovCgp3aW5kb3cualF1ZXJ5Lm5vQ29uZmxpY3QodHJ1ZSk7CmlmICghd2luZG93LmpRdWVyeSkgewogICAgd2luZG93LmpRdWVyeSA9IHdpbmRvdy54ZmFsaWIualF1ZXJ5Owp9CmlmICghd2luZG93LiQpIHsKICAgIHdpbmRvdy4kID0gd2luZG93LnhmYWxpYi4kOwp9Cgp3aW5kb3cuXy5ub0NvbmZsaWN0KCk7CmlmICghd2luZG93Ll8pIHsKICAgIHdpbmRvdy5fID0gd2luZG93LnhmYWxpYi5fOwp9Cg==",
"headers" : {
"X-Content-Type-Options" : "nosniff",
- "Last-Modified" : "Sat, 03 May 2025 13:59:40 GMT",
- "Date" : "Sun, 11 May 2025 11:23:44 GMT",
+ "Last-Modified" : "Thu, 18 Sep 2025 12:51:51 GMT",
+ "Date" : "Sun, 16 Nov 2025 14:26:31 GMT",
"Content-Type" : "application/javascript;charset=utf-8"
}
},
- "uuid" : "0d679342-fffe-4666-9286-bd35cc64a58e",
+ "uuid" : "0a024c8e-aa5e-4459-91bf-531695e412fe",
"persistent" : true,
- "insertionIndex" : 19
+ "insertionIndex" : 33
}
\ No newline at end of file
diff --git a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_toggles_json.json b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_toggles_json.json
index 8d950c94..b645c37d 100644
--- a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_toggles_json.json
+++ b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_etc.clientlibs_toggles_json.json
@@ -1,5 +1,5 @@
{
- "id" : "12f8a3d2-2fed-45c3-a025-7f8668b43320",
+ "id" : "df2fc952-74e3-4262-8fad-6ed36fd6a6ad",
"name" : "etc.clientlibs_toggles.json",
"request" : {
"url" : "/etc.clientlibs/toggles.json",
@@ -10,11 +10,11 @@
"body" : "{\"enabled\":[\"ENABLED\"]}",
"headers" : {
"Cache-Control" : "max-age=30",
- "Date" : "Sun, 11 May 2025 11:23:47 GMT",
+ "Date" : "Sun, 16 Nov 2025 14:26:33 GMT",
"Content-Type" : "application/json;charset=utf-8"
}
},
- "uuid" : "12f8a3d2-2fed-45c3-a025-7f8668b43320",
+ "uuid" : "df2fc952-74e3-4262-8fad-6ed36fd6a6ad",
"persistent" : true,
- "insertionIndex" : 18
+ "insertionIndex" : 32
}
\ No newline at end of file
diff --git a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_libs_granite_csrf_token_json.json b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_libs_granite_csrf_token_json.json
index dfd5330a..f26ec0c1 100644
--- a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_libs_granite_csrf_token_json.json
+++ b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_libs_granite_csrf_token_json.json
@@ -1,22 +1,21 @@
{
- "id" : "34969b80-157b-4075-8fdf-adc52fd6ce11",
- "name" : "libs_granite_csrf_token.json",
+ "id" : "c5b7cce5-d5fc-47b5-bd75-6214d86d7e05",
+ "name" : "etc.clientlibs_clientlibs_granite_jquery_granite_csrf.js",
"request" : {
- "url" : "/libs/granite/csrf/token.json",
+ "url" : "/etc.clientlibs/clientlibs/granite/jquery/granite/csrf.js",
"method" : "GET"
},
"response" : {
"status" : 200,
- "body" : "{\"token\":\"eyJleHAiOjE3NDY5NjMyMjgsImlhdCI6MTc0Njk2MjYyOH0.LCykkZEZpvibCViWTKfXMVDFJ3V5aUoXVrn53xwpZWY\"}",
+ "base64Body" : "LyoKICogQURPQkUgQ09ORklERU5USUFMCiAqCiAqIENvcHlyaWdodCAyMDE1IEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkCiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzLCBhbmQgcmVtYWlucwogKiB0aGUgcHJvcGVydHkgb2YgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQgYW5kIGl0cyBzdXBwbGllcnMsCiAqIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQKICogaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzCiAqIHN1cHBsaWVycyBhbmQgbWF5IGJlIGNvdmVyZWQgYnkgVS5TLiBhbmQgRm9yZWlnbiBQYXRlbnRzLAogKiBwYXRlbnRzIGluIHByb2Nlc3MsIGFuZCBhcmUgcHJvdGVjdGVkIGJ5IHRyYWRlIHNlY3JldCBvciBjb3B5cmlnaHQgbGF3LgogKiBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwKICogaXMgc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgb2J0YWluZWQKICogZnJvbSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZC4KICoKICovCi8qIGdsb2JhbCBDUVVSTEluZm86ZmFsc2UgKi8KKGZ1bmN0aW9uKHdpbmRvdykgewogICAgInVzZSBzdHJpY3QiOwoKICAgIHdpbmRvdy5HcmFuaXRlID0gd2luZG93LkdyYW5pdGUgfHwge307CiAgICB3aW5kb3cuR3Jhbml0ZS5IVFRQID0gd2luZG93LkdyYW5pdGUuSFRUUCB8fCB7fTsKCiAgICB2YXIgY29udGV4dFBhdGggPSBudWxsOwoKICAgIGZ1bmN0aW9uIGRldGVjdENvbnRleHRQYXRoKCkgewogICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuCiAgICAgICAgdmFyIFNDUklQVF9VUkxfUkVHRVhQID0gL14oPzpodHRwfGh0dHBzKTpcL1wvW14vXSsoXC8uKilcLyg/OmV0Y1wuY2xpZW50bGlic3xldGMoXC8uKikqXC9jbGllbnRsaWJzfGxpYnMoXC8uKikqXC9jbGllbnRsaWJzfGFwcHMoXC8uKikqXC9jbGllbnRsaWJzfGV0Y1wvZGVzaWducykuKlwuanMoXD8uKik/JC87CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgaWYgKHdpbmRvdy5DUVVSTEluZm8pIHsKICAgICAgICAgICAgICAgIGNvbnRleHRQYXRoID0gQ1FVUkxJbmZvLmNvbnRleHRQYXRoIHx8ICIiOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIHNjcmlwdHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgic2NyaXB0Iik7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNjcmlwdHMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gU0NSSVBUX1VSTF9SRUdFWFAuZXhlYyhzY3JpcHRzW2ldLnNyYyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0UGF0aCA9IHJlc3VsdFsxXTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvbnRleHRQYXRoID0gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIC8vIGlnbm9yZWQKICAgICAgICB9CiAgICB9CgogICAgd2luZG93LkdyYW5pdGUuSFRUUC5leHRlcm5hbGl6ZSA9IHdpbmRvdy5HcmFuaXRlLkhUVFAuZXh0ZXJuYWxpemUgfHwgZnVuY3Rpb24odXJsKSB7CiAgICAgICAgaWYgKGNvbnRleHRQYXRoID09PSBudWxsKSB7CiAgICAgICAgICAgIGRldGVjdENvbnRleHRQYXRoKCk7CiAgICAgICAgfQoKICAgICAgICB0cnkgewogICAgICAgICAgICBpZiAodXJsLmluZGV4T2YoIi8iKSA9PT0gMCAmJiBjb250ZXh0UGF0aCAmJiB1cmwuaW5kZXhPZihjb250ZXh0UGF0aCArICIvIikgIT09IDApIHsKICAgICAgICAgICAgICAgIHVybCA9IGNvbnRleHRQYXRoICsgdXJsOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAvLyBpZ25vcmVkCiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdXJsOwogICAgfTsKfSkodGhpcyk7CgovKgogKiBBRE9CRSBDT05GSURFTlRJQUwKICoKICogQ29weXJpZ2h0IDIwMTUgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQKICogQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogTk9USUNFOiAgQWxsIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gaXMsIGFuZCByZW1haW5zCiAqIHRoZSBwcm9wZXJ0eSBvZiBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZCBhbmQgaXRzIHN1cHBsaWVycywKICogaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZAogKiBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkIGFuZCBpdHMKICogc3VwcGxpZXJzIGFuZCBtYXkgYmUgY292ZXJlZCBieSBVLlMuIGFuZCBGb3JlaWduIFBhdGVudHMsCiAqIHBhdGVudHMgaW4gcHJvY2VzcywgYW5kIGFyZSBwcm90ZWN0ZWQgYnkgdHJhZGUgc2VjcmV0IG9yIGNvcHlyaWdodCBsYXcuCiAqIERpc3NlbWluYXRpb24gb2YgdGhpcyBpbmZvcm1hdGlvbiBvciByZXByb2R1Y3Rpb24gb2YgdGhpcyBtYXRlcmlhbAogKiBpcyBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBvYnRhaW5lZAogKiBmcm9tIEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkLgogKgogKi8KKGZ1bmN0aW9uKGZhY3RvcnkpIHsKICAgICJ1c2Ugc3RyaWN0IjsKCiAgICAvLyBHUkFOSVRFLTIyMjgxIENoZWNrIGZvciBtdWx0aXBsZSBpbml0aWFsaXphdGlvbgogICAgaWYgKHdpbmRvdy5HcmFuaXRlLmNzcmYpIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgd2luZG93LkdyYW5pdGUuY3NyZiA9IGZhY3Rvcnkod2luZG93LkdyYW5pdGUuSFRUUCk7Cn0oZnVuY3Rpb24oaHR0cCkgewogICAgInVzZSBzdHJpY3QiOwoKICAgIC8vIEFkb2JlUGF0ZW50SUQ9IlA1Mjk2IgoKICAgIGZ1bmN0aW9uIFByb21pc2UoKSB7CiAgICAgICAgdGhpcy5faGFuZGxlciA9IFtdOwogICAgfQoKICAgIFByb21pc2UucHJvdG90eXBlID0gewogICAgICAgIHRoZW46IGZ1bmN0aW9uKHJlc29sdmVGbiwgcmVqZWN0Rm4pIHsKICAgICAgICAgICAgdGhpcy5faGFuZGxlci5wdXNoKHsgcmVzb2x2ZTogcmVzb2x2ZUZuLCByZWplY3Q6IHJlamVjdEZuIH0pOwogICAgICAgIH0sCiAgICAgICAgcmVzb2x2ZTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHRoaXMuX2V4ZWN1dGUoInJlc29sdmUiLCBhcmd1bWVudHMpOwogICAgICAgIH0sCiAgICAgICAgcmVqZWN0OiBmdW5jdGlvbigpIHsKICAgICAgICAgICAgdGhpcy5fZXhlY3V0ZSgicmVqZWN0IiwgYXJndW1lbnRzKTsKICAgICAgICB9LAogICAgICAgIF9leGVjdXRlOiBmdW5jdGlvbihyZXN1bHQsIGFyZ3MpIHsKICAgICAgICAgICAgaWYgKHRoaXMuX2hhbmRsZXIgPT09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiUHJvbWlzZSBhbHJlYWR5IGNvbXBsZXRlZC4iKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxuID0gdGhpcy5faGFuZGxlci5sZW5ndGg7IGkgPCBsbjsgaSsrKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9oYW5kbGVyW2ldW3Jlc3VsdF0uYXBwbHkod2luZG93LCBhcmdzKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGhpcy50aGVuID0gZnVuY3Rpb24ocmVzb2x2ZUZuLCByZWplY3RGbikgewogICAgICAgICAgICAgICAgKHJlc3VsdCA9PT0gInJlc29sdmUiID8gcmVzb2x2ZUZuIDogcmVqZWN0Rm4pLmFwcGx5KHdpbmRvdywgYXJncyk7CiAgICAgICAgICAgIH07CgogICAgICAgICAgICB0aGlzLl9oYW5kbGVyID0gbnVsbDsKICAgICAgICB9CiAgICB9OwoKICAgIGZ1bmN0aW9uIHZlcmlmeVNhbWVPcmlnaW4odXJsKSB7CiAgICAgICAgLy8gdXJsIGNvdWxkIGJlIHJlbGF0aXZlIG9yIHNjaGVtZSByZWxhdGl2ZSBvciBhYnNvbHV0ZQogICAgICAgIC8vIGhvc3QgKyBwb3J0CiAgICAgICAgdmFyIGhvc3QgPSBkb2N1bWVudC5sb2NhdGlvbi5ob3N0OwogICAgICAgIHZhciBwcm90b2NvbCA9IGRvY3VtZW50LmxvY2F0aW9uLnByb3RvY29sOwogICAgICAgIHZhciByZWxhdGl2ZU9yaWdpbiA9ICIvLyIgKyBob3N0OwogICAgICAgIHZhciBvcmlnaW4gPSBwcm90b2NvbCArIHJlbGF0aXZlT3JpZ2luOwoKICAgICAgICAvLyBBbGxvdyBhYnNvbHV0ZSBvciBzY2hlbWUgcmVsYXRpdmUgVVJMcyB0byBzYW1lIG9yaWdpbgogICAgICAgIHJldHVybiAodXJsID09PSBvcmlnaW4gfHwgdXJsLnNsaWNlKDAsIG9yaWdpbi5sZW5ndGggKyAxKSA9PT0gb3JpZ2luICsgIi8iKSB8fAogICAgICAgICAgICAgICAgKHVybCA9PT0gcmVsYXRpdmVPcmlnaW4gfHwgdXJsLnNsaWNlKDAsIHJlbGF0aXZlT3JpZ2luLmxlbmd0aCArIDEpID09PSByZWxhdGl2ZU9yaWdpbiArICIvIikgfHwKICAgICAgICAgICAgICAgIC8vIG9yIGFueSBvdGhlciBVUkwgdGhhdCBpc24ndCBzY2hlbWUgcmVsYXRpdmUgb3IgYWJzb2x1dGUgaS5lIHJlbGF0aXZlLgogICAgICAgICAgICAgICAgISgvXihcL1wvfGh0dHA6fGh0dHBzOikuKi8udGVzdCh1cmwpKTsKICAgIH0KCiAgICB2YXIgRklFTERfTkFNRSA9ICI6Y3FfY3NyZl90b2tlbiI7CiAgICB2YXIgSEVBREVSX05BTUUgPSAiQ1NSRi1Ub2tlbiI7CiAgICB2YXIgVE9LRU5fU0VSVkxFVCA9IGh0dHAuZXh0ZXJuYWxpemUoIi9saWJzL2dyYW5pdGUvY3NyZi90b2tlbi5qc29uIik7CgogICAgdmFyIHByb21pc2U7CiAgICB2YXIgZ2xvYmFsVG9rZW47CgogICAgZnVuY3Rpb24gbG9nRmFpbFJlcXVlc3QoZXJyb3IpIHsKICAgICAgICBpZiAod2luZG93LmNvbnNvbGUpIHsKICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGUKICAgICAgICAgICAgY29uc29sZS53YXJuKCJDU1JGIGRhdGEgbm90IGF2YWlsYWJsZTsiICsKICAgICAgICAgICAgICAgICAgICAiVGhlIGRhdGEgbWF5IGJlIHVuYXZhaWxhYmxlIGJ5IGRlc2lnbiwgc3VjaCBhcyBkdXJpbmcgbm9uLWF1dGhlbnRpY2F0ZWQgcmVxdWVzdHM6ICIgKyBlcnJvcik7CiAgICAgICAgfQogICAgfQoKICAgIGZ1bmN0aW9uIGdldFRva2VuKCkgewogICAgICAgIHZhciBsb2NhbFByb21pc2UgPSBuZXcgUHJvbWlzZSgpOwogICAgICAgIHByb21pc2UgPSBsb2NhbFByb21pc2U7CgogICAgICAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTsKICAgICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PT0gNCkgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IEpTT04ucGFyc2UoeGhyLnJlc3BvbnNlVGV4dCk7CiAgICAgICAgICAgICAgICAgICAgZ2xvYmFsVG9rZW4gPSBkYXRhLnRva2VuOwogICAgICAgICAgICAgICAgICAgIGxvY2FsUHJvbWlzZS5yZXNvbHZlKGdsb2JhbFRva2VuKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4KSB7CiAgICAgICAgICAgICAgICAgICAgbG9nRmFpbFJlcXVlc3QoZXgpOwogICAgICAgICAgICAgICAgICAgIGxvY2FsUHJvbWlzZS5yZWplY3QoeGhyLnJlc3BvbnNlVGV4dCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIHhoci5vcGVuKCJHRVQiLCBUT0tFTl9TRVJWTEVULCB0cnVlKTsKICAgICAgICB4aHIuc2VuZCgpOwoKICAgICAgICByZXR1cm4gbG9jYWxQcm9taXNlOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldFRva2VuU3luYygpIHsKICAgICAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7CiAgICAgICAgeGhyLm9wZW4oIkdFVCIsIFRPS0VOX1NFUlZMRVQsIGZhbHNlKTsKICAgICAgICB4aHIuc2VuZCgpOwoKICAgICAgICB0cnkgewogICAgICAgICAgICByZXR1cm4gZ2xvYmFsVG9rZW4gPSBKU09OLnBhcnNlKHhoci5yZXNwb25zZVRleHQpLnRva2VuOwogICAgICAgIH0gY2F0Y2ggKGV4KSB7CiAgICAgICAgICAgIGxvZ0ZhaWxSZXF1ZXN0KGV4KTsKICAgICAgICB9CiAgICB9CgogICAgZnVuY3Rpb24gY2xlYXJUb2tlbigpIHsKICAgICAgICBnbG9iYWxUb2tlbiA9IHVuZGVmaW5lZDsKICAgICAgICBnZXRUb2tlbigpOwogICAgfQoKICAgIGZ1bmN0aW9uIGFkZEZpZWxkKGZvcm0pIHsKICAgICAgICB2YXIgYWN0aW9uID0gZm9ybS5nZXRBdHRyaWJ1dGUoImFjdGlvbiIpOwogICAgICAgIGlmIChmb3JtLm1ldGhvZC50b1VwcGVyQ2FzZSgpID09PSAiR0VUIiB8fCAoYWN0aW9uICYmICF2ZXJpZnlTYW1lT3JpZ2luKGFjdGlvbikpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGlmICghZ2xvYmFsVG9rZW4pIHsKICAgICAgICAgICAgZ2V0VG9rZW5TeW5jKCk7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWdsb2JhbFRva2VuKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHZhciBpbnB1dCA9IGZvcm0ucXVlcnlTZWxlY3RvcignaW5wdXRbbmFtZT0iJyArIEZJRUxEX05BTUUgKyAnIl0nKTsKCiAgICAgICAgaWYgKCFpbnB1dCkgewogICAgICAgICAgICBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImlucHV0Iik7CiAgICAgICAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgidHlwZSIsICJoaWRkZW4iKTsKICAgICAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJuYW1lIiwgRklFTERfTkFNRSk7CiAgICAgICAgICAgIGZvcm0uYXBwZW5kQ2hpbGQoaW5wdXQpOwogICAgICAgIH0KCiAgICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJ2YWx1ZSIsIGdsb2JhbFRva2VuKTsKICAgIH0KCiAgICBmdW5jdGlvbiBoYW5kbGVGb3JtKGRvY3VtZW50KSB7CiAgICAgICAgdmFyIGhhbmRsZXIgPSBmdW5jdGlvbihldikgewogICAgICAgICAgICB2YXIgdCA9IGV2LnRhcmdldDsKCiAgICAgICAgICAgIGlmICh0Lm5vZGVOYW1lID09PSAiRk9STSIpIHsKICAgICAgICAgICAgICAgIGFkZEZpZWxkKHQpOwogICAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgaWYgKGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIpIHsKICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigic3VibWl0IiwgaGFuZGxlciwgdHJ1ZSk7CiAgICAgICAgfSBlbHNlIGlmIChkb2N1bWVudC5hdHRhY2hFdmVudCkgewogICAgICAgICAgICBkb2N1bWVudC5hdHRhY2hFdmVudCgic3VibWl0IiwgaGFuZGxlcik7CiAgICAgICAgfQogICAgfQoKICAgIGhhbmRsZUZvcm0oZG9jdW1lbnQpOwoKICAgIHZhciBvcGVuID0gWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLm9wZW47CgogICAgWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbihtZXRob2QsIHVybCwgYXN5bmMpIHsKICAgICAgICBpZiAobWV0aG9kLnRvTG93ZXJDYXNlKCkgIT09ICJnZXQiICYmIHZlcmlmeVNhbWVPcmlnaW4odXJsKSkgewogICAgICAgICAgICB0aGlzLl9jc3JmID0gdHJ1ZTsKICAgICAgICAgICAgdGhpcy5fYXN5bmMgPSBhc3luYzsKICAgICAgICB9CgogICAgICAgIHJldHVybiBvcGVuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICB9OwoKICAgIHZhciBzZW5kID0gWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLnNlbmQ7CgogICAgWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbigpIHsKICAgICAgICBpZiAoIXRoaXMuX2NzcmYpIHsKICAgICAgICAgICAgc2VuZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBpZiAoZ2xvYmFsVG9rZW4pIHsKICAgICAgICAgICAgdGhpcy5zZXRSZXF1ZXN0SGVhZGVyKEhFQURFUl9OQU1FLCBnbG9iYWxUb2tlbik7CiAgICAgICAgICAgIHNlbmQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgaWYgKHRoaXMuX2FzeW5jID09PSBmYWxzZSkgewogICAgICAgICAgICBnZXRUb2tlblN5bmMoKTsKCiAgICAgICAgICAgIGlmIChnbG9iYWxUb2tlbikgewogICAgICAgICAgICAgICAgdGhpcy5zZXRSZXF1ZXN0SGVhZGVyKEhFQURFUl9OQU1FLCBnbG9iYWxUb2tlbik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNlbmQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdmFyIHNlbGYgPSB0aGlzOwogICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTsKCiAgICAgICAgcHJvbWlzZS50aGVuKGZ1bmN0aW9uKHRva2VuKSB7CiAgICAgICAgICAgIHNlbGYuc2V0UmVxdWVzdEhlYWRlcihIRUFERVJfTkFNRSwgdG9rZW4pOwogICAgICAgICAgICBzZW5kLmFwcGx5KHNlbGYsIGFyZ3MpOwogICAgICAgIH0sIGZ1bmN0aW9uKCkgewogICAgICAgICAgICBzZW5kLmFwcGx5KHNlbGYsIGFyZ3MpOwogICAgICAgIH0pOwogICAgfTsKCiAgICB2YXIgc3VibWl0ID0gSFRNTEZvcm1FbGVtZW50LnByb3RvdHlwZS5zdWJtaXQ7CgogICAgSFRNTEZvcm1FbGVtZW50LnByb3RvdHlwZS5zdWJtaXQgPSBmdW5jdGlvbigpIHsKICAgICAgICBhZGRGaWVsZCh0aGlzKTsKICAgICAgICByZXR1cm4gc3VibWl0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICB9OwoKICAgIGlmICh3aW5kb3cuTm9kZSkgewogICAgICAgIHZhciBhYyA9IE5vZGUucHJvdG90eXBlLmFwcGVuZENoaWxkOwoKICAgICAgICBOb2RlLnByb3RvdHlwZS5hcHBlbmRDaGlsZCA9IGZ1bmN0aW9uKCkgewogICAgICAgICAgICB2YXIgcmVzdWx0ID0gYWMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKCiAgICAgICAgICAgIGlmIChyZXN1bHQubm9kZU5hbWUgPT09ICJJRlJBTUUiKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuY29udGVudFdpbmRvdyAmJiAhcmVzdWx0Ll9jc3JmKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5fY3NyZiA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUZvcm0ocmVzdWx0LmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zcmMgJiYgcmVzdWx0LnNyYy5sZW5ndGggJiYgdmVyaWZ5U2FtZU9yaWdpbihyZXN1bHQuc3JjKSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAod2luZG93LmNvbnNvbGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCJVbmFibGUgdG8gYXR0YWNoIENTUkYgdG9rZW4gdG8gYW4gaWZyYW1lIGVsZW1lbnQgb24gdGhlIHNhbWUgb3JpZ2luIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIFBvdGVudGlhbCBlcnJvcjogQWNjZXNzIGlzIERlbmllZAogICAgICAgICAgICAgICAgICAgIC8vIHdlIGNhbiBzYWZlbHkgaWdub3JlIENPUlMgc2VjdXJpdHkgZXJyb3JzIGhlcmUKICAgICAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGUgY3NyZiBhbnl3YXlzIHRvIGFub3RoZXIgZG9tYWluCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfTsKICAgIH0KCiAgICAvLyByZWZyZXNoaW5nIGNzcmYgdG9rZW4gcGVyaW9kaWNhbGx5CiAgICBnZXRUb2tlbigpOwoKICAgIHNldEludGVydmFsKGZ1bmN0aW9uKCkgewogICAgICAgIGdldFRva2VuKCk7CiAgICB9LCAzMDAwMDApOwoKICAgIHJldHVybiB7CiAgICAgICAgaW5pdGlhbGlzZWQ6IGZhbHNlLAogICAgICAgIHJlZnJlc2hUb2tlbjogZ2V0VG9rZW4sCiAgICAgICAgX2NsZWFyVG9rZW46IGNsZWFyVG9rZW4KICAgIH07Cn0pKTsKCg==",
"headers" : {
- "Cache-Control" : "no-cache",
"X-Content-Type-Options" : "nosniff",
- "Expires" : "-1",
- "Date" : "Sun, 11 May 2025 11:23:48 GMT",
- "Content-Type" : "application/json"
+ "Last-Modified" : "Thu, 18 Sep 2025 12:46:42 GMT",
+ "Date" : "Sun, 16 Nov 2025 14:26:31 GMT",
+ "Content-Type" : "application/javascript;charset=utf-8"
}
},
- "uuid" : "34969b80-157b-4075-8fdf-adc52fd6ce11",
+ "uuid" : "c5b7cce5-d5fc-47b5-bd75-6214d86d7e05",
"persistent" : true,
- "insertionIndex" : 17
+ "insertionIndex" : 34
}
\ No newline at end of file
diff --git a/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_services_html5_renderhtml5form.json b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_services_html5_renderhtml5form.json
new file mode 100644
index 00000000..bc23abdc
--- /dev/null
+++ b/spring/fluentforms-sample-webmvc-app/src/test/resources/mappings/AemProxyEndpointTest_proxyTest_services_html5_renderhtml5form.json
@@ -0,0 +1,25 @@
+{
+ "id" : "dd236fa1-e635-4d56-a090-b9e6b99a5955",
+ "name" : "services_html5_renderhtml5form",
+ "request" : {
+ "url" : "/services/Html5/RenderHtml5Form",
+ "method" : "POST",
+ "bodyPatterns" : [ {
+ "anything" : "anything"
+ } ]
+ },
+ "response" : {
+ "status" : 200,
+ "body" : "\n\n\n\n\n\n \n \n\n\n\n\n\n\nLC Forms\n\n\n\n\n\n\n\n\n \n \n \n \n \n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n \n \n \n\n\n\n\n \n\n\n\n \n \n\n\n\n\n\n\n\n\n\n\n\n \n \n\n\n\n\n\n\n \n\n\n \n \n\n\n\n\n\n\n\n\n\n\n\n \n\n",
+ "headers" : {
+ "X-Content-Type-Options" : "nosniff",
+ "Set-Cookie" : "cq-authoring-mode=TOUCH; Path=/; Expires=Sun, 23-Nov-2025 14:26:29 GMT; Max-Age=604800",
+ "Expires" : "Thu, 01 Jan 1970 00:00:00 GMT",
+ "Date" : "Sun, 16 Nov 2025 14:26:29 GMT",
+ "Content-Type" : "text/html;charset=utf-8"
+ }
+ },
+ "uuid" : "dd236fa1-e635-4d56-a090-b9e6b99a5955",
+ "persistent" : true,
+ "insertionIndex" : 37
+}
\ No newline at end of file
diff --git a/spring/fluentforms-spring-boot-autoconfigure/pom.xml b/spring/fluentforms-spring-boot-autoconfigure/pom.xml
index c942c402..35838067 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/pom.xml
+++ b/spring/fluentforms-spring-boot-autoconfigure/pom.xml
@@ -5,13 +5,13 @@
org.springframework.boot
spring-boot-starter-parent
- 3.5.5
+ 3.5.7
com._4point.aem.fluentforms
fluentforms-spring-boot-autoconfigure
0.0.5-SNAPSHOT
- AutoConfigure Project
+ FluentForms AutoConfigure Project
17
@@ -19,7 +19,7 @@
3.0.5
0.0.5-SNAPSHOT
0.0.4-SNAPSHOT
- 4.0.0-beta.15
+ 4.0.0-beta.16
1.20.2
1.2.3
@@ -66,7 +66,7 @@
org.springframework.boot
- spring-boot-starter-jersey
+ spring-boot-starter-web
true
provided
@@ -80,11 +80,6 @@
rest-services.client
${fluentforms.version}
-
- com._4point.aem.docservices.rest-services
- rest-services.jersey-client
- ${fluentforms.version}
-
org.springframework.boot
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemConfiguration.java b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemConfiguration.java
index f8a6615b..ee55d261 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemConfiguration.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemConfiguration.java
@@ -27,6 +27,6 @@ public record AemConfiguration(
) {
public String url() {
- return "http" + (useSsl ? "s" : "") + "://" + servername + (port != 80 ? ":" + port : "") + "/";
+ return "http" + (useSsl ? "s" : "") + "://" + servername + (port != null && port != 80 ? ":" + port : "") + "/";
}
}
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmission.java b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmission.java
index 7fce01ed..3e0a4e65 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmission.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmission.java
@@ -1,46 +1,41 @@
package com._4point.aem.fluentforms.spring;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.InputStream;
+import java.io.UncheckedIOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
+import java.util.function.Consumer;
import java.util.function.Function;
import java.util.regex.Pattern;
-import org.glassfish.jersey.client.ChunkedInput;
-import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.media.multipart.BodyPartEntity;
-import org.glassfish.jersey.media.multipart.FormDataBodyPart;
-import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.ssl.SslBundles;
+import org.springframework.boot.autoconfigure.web.client.RestClientSsl;
+import org.springframework.boot.ssl.NoSuchSslBundleException;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.HttpStatusCode;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.support.BasicAuthenticationInterceptor;
import org.springframework.util.MultiValueMap;
import org.springframework.util.MultiValueMapAdapter;
-
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.InternalServerErrorException;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.client.WebTarget;
-import jakarta.ws.rs.core.Context;
-import jakarta.ws.rs.core.GenericType;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.MultivaluedMap;
-import jakarta.ws.rs.core.Response;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestClient;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.util.UriBuilder;
/**
* Class that handles Adaptive Form Submissions.
@@ -60,27 +55,30 @@
*
*
*/
-@Path("/aem")
+@Lazy // Not sure why this is required, but without it the Jersey auto-configuration tests fail. Leaving it in for now.
+@CrossOrigin
+@RestController
+@RequestMapping("/aem")
public class AemProxyAfSubmission {
private final static Logger logger = LoggerFactory.getLogger(AemProxyAfSubmission.class);
- private static final String CONTENT_FORMS_AF = "content/forms/af/";
+ private static final String CONTENT_FORMS_AF = "/content/forms/af/";
+
+ private final SpringAfSubmitProcessor submitProcessor;
- @Autowired
- AfSubmitProcessor submitProcessor;
+ AemProxyAfSubmission(SpringAfSubmitProcessor submitProcessor) {
+ this.submitProcessor = submitProcessor;
+ }
- @Path(CONTENT_FORMS_AF + "{remainder : .+}")
- @POST
- @Consumes(MediaType.MULTIPART_FORM_DATA)
- @Produces(MediaType.WILDCARD)
- public Response proxySubmitPost(@PathParam("remainder") String remainder, /* @HeaderParam(CorrelationId.CORRELATION_ID_HDR) final String correlationIdHdr,*/ @Context HttpHeaders headers, final FormDataMultiPart inFormData) {
+ @PostMapping(path = CONTENT_FORMS_AF + "{*remainder}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.ALL_VALUE)
+ public ResponseEntity proxySubmitPost(@PathVariable("remainder") String remainder, /* @HeaderParam(CorrelationId.CORRELATION_ID_HDR) final String correlationIdHdr,*/ @RequestHeader HttpHeaders headers, final MultipartHttpServletRequest inFormData) {
logger.atInfo().addArgument(()->submitProcessor != null ? submitProcessor.getClass().getName() : "null" ).log("Submit proxy called. SubmitProcessor={}");
// final String correlationId = CorrelationId.generate(correlationIdHdr);
// ProcessingMetadataBuilder pmBuilder = ProcessingMetadata.start(correlationId);
- return submitProcessor.processRequest(inFormData, headers, remainder);
+ return submitProcessor.processRequest(inFormData, remainder);
}
/**
- * Transforms a FormDataMultiPart object using a set of provided functions.
+ * Transforms a incoming object using a set of provided functions.
*
* Accepts incoming form data, in the form of a FormDataMultiPart object and a Map collection of functions. It walks through the
* parts and if it finds a function in the Map with the same name it executes that function on the the data from the corresponding part.
@@ -92,29 +90,21 @@ public Response proxySubmitPost(@PathParam("remainder") String remainder, /* @He
* @return
* @throws IOException
*/
- private static FormDataMultiPart transformFormData(final FormDataMultiPart inFormData, final Map> fieldFunctions, Logger logger) {
- try {
- FormDataMultiPart outFormData = new FormDataMultiPart();
- var fields = inFormData.getFields();
- logger.atDebug().log(()->"Found " + fields.size() + " fields");
-
- for (var fieldEntry : fields.entrySet()) {
- String fieldName = fieldEntry.getKey();
- for (FormDataBodyPart fieldData : fieldEntry.getValue()) {
- logger.atDebug().log(()->"Copying '" + fieldName + "' field");
- byte[] fieldBytes = ((BodyPartEntity)fieldData.getEntity()).getInputStream().readAllBytes();
- logger.atTrace().log(()->"Fieldname '" + fieldName + "' is '" + new String(fieldBytes) + "'.");
- var fieldFn = fieldFunctions.getOrDefault(fieldName, Function.identity()); // Look for an entry in fieldFunctions table for this field. Return the Identity function if we don't find one.
- byte[] modifiedFieldBytes = fieldFn.apply(fieldBytes);
- if (modifiedFieldBytes != null) { // If the function returned bytes (if not, then remove that part)
- outFormData.field(fieldName, new String(modifiedFieldBytes, StandardCharsets.UTF_8)); // Apply the field function to bytes.
- }
- }
+ private static MultipartHttpServletRequest transformFormData(final MultipartHttpServletRequest inFormData, final Map> fieldFunctions, Logger logger) {
+ var fields = inFormData.getParameterMap();
+ logger.atDebug().log(()->"Found " + fields.size() + " fields");
+
+ for (var fieldEntry : fields.entrySet()) {
+ String fieldName = fieldEntry.getKey();
+ for (var fieldData : fieldEntry.getValue()) {
+ logger.atDebug().log(()->"Copying '" + fieldName + "' field");
+ byte[] fieldBytes = fieldData.getBytes();
+ logger.atTrace().log(()->"Fieldname '" + fieldName + "' is '" + new String(fieldBytes) + "'.");
+ var fieldFn = fieldFunctions.getOrDefault(fieldName, Function.identity()); // Look for an entry in fieldFunctions table for this field. Return the Identity function if we don't find one.
+ fieldFn.apply(fieldBytes); // throw away the result.
}
- return outFormData;
- } catch (IOException e) {
- throw new InternalServerErrorException("Error while transforming submission data.", e);
}
+ return inFormData;
}
/**
@@ -126,7 +116,7 @@ private static FormDataMultiPart transformFormData(final FormDataMultiPart inFor
*
*/
@FunctionalInterface
- public interface AfSubmitProcessor {
+ public interface SpringAfSubmitProcessor {
/**
* Processor to process incoming Adaptive Forms submit.
*
@@ -138,11 +128,11 @@ public interface AfSubmitProcessor {
* Adaptive Forms location path (relative to /content/forms/af/)
* @return
*/
- Response processRequest(final FormDataMultiPart inFormData, HttpHeaders headers, String remainder);
+ ResponseEntity processRequest(final MultipartHttpServletRequest inFormData, String remainder);
}
@FunctionalInterface
- public interface AfFormDataTransformer {
+ public interface SpringAfFormDataTransformer {
/**
* If one or more of these are available in the Spring context, they will be run against the incoming
* data before it is processed.
@@ -158,7 +148,7 @@ public interface AfFormDataTransformer {
* @return
* outgoing form data object
*/
- FormDataMultiPart transformFormData(final FormDataMultiPart inFormData);
+ MultipartHttpServletRequest transformFormData(final MultipartHttpServletRequest inFormData);
}
/**
* This processor forwards the Adaptive Form submissions on to AEM for processing by the AEM instance.
@@ -169,50 +159,118 @@ public interface AfFormDataTransformer {
* Spring context.
*
*/
- static class AfSubmitAemProxyProcessor implements AfSubmitProcessor {
+ static class AfSubmitAemProxyProcessor implements SpringAfSubmitProcessor {
- private final AemConfiguration aemConfig;
- private final Client httpClient;
+ private final RestClient httpClient;
- public AfSubmitAemProxyProcessor(AemConfiguration aemConfig, SslBundles sslBundles) {
- this.aemConfig = aemConfig;
- this.httpClient = JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle(), aemConfig.user(), aemConfig.password());
+ public AfSubmitAemProxyProcessor(AemConfiguration aemConfig, RestClientSsl restClientSsl) {
+ this.httpClient = Optional.of(RestClient.builder())
+ .map(b->b.baseUrl(aemConfig.url()))
+ .map(b->configureBasicAuthentication(b, aemConfig))
+ .map(b->configureSsl(b, aemConfig, restClientSsl))
+ .get().build();
+// this.httpClient = configureBasicAuthentication(RestClient.builder().baseUrl(aemConfig.url()), aemConfig).build();
+// JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle(), aemConfig.user(), aemConfig.password());
+ }
+
+ private static RestClient.Builder configureBasicAuthentication(
+ RestClient.Builder builder,
+ AemConfiguration aemConfig
+ ) {
+ ClientHttpRequestInterceptor basicAuth = new BasicAuthenticationInterceptor(aemConfig.user(), aemConfig.password());
+
+ return builder.requestInterceptor(basicAuth);
+ }
+
+ private static RestClient.Builder configureSsl(RestClient.Builder builder, AemConfiguration aemConfig, RestClientSsl restClientSsl) {
+ return aemConfig.useSsl() ? builder.apply(getSslBundle(aemConfig.sslBundle(), restClientSsl))
+ : builder;
+ }
+
+ private static Consumer getSslBundle(String sslBundleName, RestClientSsl restClientSsl) {
+ try {
+ return restClientSsl.fromBundle(sslBundleName);
+ } catch (NoSuchSslBundleException e) {
+ // Default to normal SSL context (which includes the default trust store)
+ // This is not ideal since misspelling the bundle name silently fails, but is required to avoid breaking existing code.
+ // At dome point it should probably be changed to let the exception pass and only use the default SSL context
+ // if the SSL bundle name is empty.
+ return b->{}; // No-op;
+ }
}
@Override
- public Response processRequest(FormDataMultiPart formSubmission, HttpHeaders headers, String remainder) {
- logger.atTrace().addArgument(()->{ String formData = formSubmission.getField("jcr:data").getEntityAs(String.class);
- return formData != null ? formData : "null";
- })
+ public ResponseEntity processRequest(MultipartHttpServletRequest formSubmission, String remainder) {
+ logger.atTrace().addArgument(()->getFormData(formSubmission))
.log("AF Submit Proxy: Data = '{}'");
// Transfer to AEM
- String contentType = headers.getMediaType().toString();
- String cookie = headers.getHeaderString("cookie");
- WebTarget webTarget = httpClient.target(aemConfig.url())
- .property(ClientProperties.FOLLOW_REDIRECTS, Boolean.FALSE)
- .path("/" + CONTENT_FORMS_AF + remainder);
+ var headers = formSubmission.getRequestHeaders();
+// String contentType = headers.getContentType().toString();
+// String cookie = headers.getFirst("cookie");
+ ResponseEntity result = httpClient.post()
+ .uri(ub->appendPath(ub, remainder))
+ .body(new HttpEntity<>(formSubmission.getMultiFileMap(), headers))
+// .headers(h->{
+// h.set("cookie", cookie);
+// })
+ .retrieve()
+ .toEntity(byte[].class)
+ ;
+
+// WebTarget webTarget = httpClient.target(aemConfig.url())
+// .property(ClientProperties.FOLLOW_REDIRECTS, Boolean.FALSE)
+// .path("/" + CONTENT_FORMS_AF + remainder);
+//
+// logger.atDebug().log(()->"Proxying Submit POST request for target '" + webTarget.getUri().toString() + "'.");
+// Response result = webTarget.request()
+// .header("cookie", cookie)
+// .post(Entity.entity(formSubmission , contentType));
- logger.atDebug().log(()->"Proxying Submit POST request for target '" + webTarget.getUri().toString() + "'.");
- Response result = webTarget.request()
- .header("cookie", cookie)
- .post(Entity.entity(formSubmission , contentType));
+ logger.atDebug().log(()->"AEM Response = " + result.getStatusCode().value());
+ logger.atDebug().log(()->"AEM Response Location = " + result.getHeaders().getLocation());
- logger.atDebug().log(()->"AEM Response = " + result.getStatus());
- logger.atDebug().log(()->"AEM Response Location = " + result.getLocation());
+ // TODO: Add correlation ID header
+ return ResponseEntity.status(result.getStatusCode())
+ .headers(removeChunkedTransferEncoding(result.getHeaders()))
+ .body(result.getBody());
+// String aemResponseEncoding = result.getHeaderString("Transfer-Encoding");
+// if (aemResponseEncoding != null && aemResponseEncoding.equalsIgnoreCase("chunked")) {
+// logger.atDebug().log("Returning chunked response from AEM.");
+// return Response.status(result.getStatus()).entity(new ByteArrayInputStream(transferFromAem(result, logger)))
+// .type(result.getMediaType())
+//// .header(CorrelationId.CORRELATION_ID_HDR, correlationId)
+// .build();
+// } else {
+// logger.atDebug().log("Returning response from AEM.");
+// return Response.fromResponse(result)
+//// .header(CorrelationId.CORRELATION_ID_HDR, correlationId)
+// .build();
+// }
+ }
+
+ private HttpHeaders removeChunkedTransferEncoding(HttpHeaders headers) {
+ var transferEncoding = headers.getFirst(HttpHeaders.TRANSFER_ENCODING);
+ if (transferEncoding != null && transferEncoding.equalsIgnoreCase("chunked")) {
+ var newHeaders = new HttpHeaders(headers);
+ newHeaders.remove(HttpHeaders.TRANSFER_ENCODING);
+ return newHeaders;
+ }
+ return headers;
+ }
- String aemResponseEncoding = result.getHeaderString("Transfer-Encoding");
- if (aemResponseEncoding != null && aemResponseEncoding.equalsIgnoreCase("chunked")) {
- logger.atDebug().log("Returning chunked response from AEM.");
- return Response.status(result.getStatus()).entity(new ByteArrayInputStream(transferFromAem(result, logger)))
- .type(result.getMediaType())
-// .header(CorrelationId.CORRELATION_ID_HDR, correlationId)
- .build();
- } else {
- logger.atDebug().log("Returning response from AEM.");
- return Response.fromResponse(result)
-// .header(CorrelationId.CORRELATION_ID_HDR, correlationId)
- .build();
+ private static URI appendPath(UriBuilder builder, String remainder) {
+ var uri = builder.path(CONTENT_FORMS_AF + remainder).build();
+ logger.atDebug().log(()->"Proxying Submit POST request for target '" + uri.toString() + "'.");
+ return uri;
+ }
+
+ private static String getFormData(MultipartHttpServletRequest formSubmission) {
+ try {
+ var formData = formSubmission.getFile("jcr:data");
+ return formData != null ? formData.getResource().getContentAsString(StandardCharsets.UTF_8) : "null";
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
}
@@ -224,43 +282,43 @@ public Response processRequest(FormDataMultiPart formSubmission, HttpHeaders hea
* @return
* @throws IOException
*/
- private static byte[] transferFromAem(Response result, Logger logger) {
- try {
- if (logger.isDebugEnabled()) {
- logger.debug("AEM Response Mediatype=" + (result.getMediaType() != null ? result.getMediaType().toString(): "null"));
- MultivaluedMap headers = result.getHeaders();
- for(Entry> entry : headers.entrySet()) {
- String msgLine = "For header '" + entry.getKey() + "', ";
- for (Object value : entry.getValue()) {
- msgLine += "'" + value.toString() + "' ";
- }
- logger.debug(msgLine);
- }
- }
-
- String aemResponseEncoding = result.getHeaderString("Transfer-Encoding");
- if (aemResponseEncoding != null && aemResponseEncoding.equalsIgnoreCase("chunked")) {
- // They've sent back chunked response.
- logger.debug("Found a chunked encoding.");
- final ChunkedInput chunkedInput = result.readEntity(new GenericType>() {});
- byte[] chunk;
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- try (buffer) {
- while ((chunk = chunkedInput.read()) != null) {
- buffer.writeBytes(chunk);
- logger.debug("Read chunk from AEM response.");
- }
- }
-
- return buffer.toByteArray();
- } else {
- return ((InputStream)result.getEntity()).readAllBytes();
- }
- } catch (IllegalStateException | IOException e) {
- throw new InternalServerErrorException("Error while processing transferring result from AEM.", e);
- }
- }
-
+// private static byte[] transferFromAem(Response result, Logger logger) {
+// try {
+// if (logger.isDebugEnabled()) {
+// logger.debug("AEM Response Mediatype=" + (result.getMediaType() != null ? result.getMediaType().toString(): "null"));
+// MultivaluedMap headers = result.getHeaders();
+// for(Entry> entry : headers.entrySet()) {
+// String msgLine = "For header '" + entry.getKey() + "', ";
+// for (Object value : entry.getValue()) {
+// msgLine += "'" + value.toString() + "' ";
+// }
+// logger.debug(msgLine);
+// }
+// }
+//
+// String aemResponseEncoding = result.getHeaderString("Transfer-Encoding");
+// if (aemResponseEncoding != null && aemResponseEncoding.equalsIgnoreCase("chunked")) {
+// // They've sent back chunked response.
+// logger.debug("Found a chunked encoding.");
+// final ChunkedInput chunkedInput = result.readEntity(new GenericType>() {});
+// byte[] chunk;
+// ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+// try (buffer) {
+// while ((chunk = chunkedInput.read()) != null) {
+// buffer.writeBytes(chunk);
+// logger.debug("Read chunk from AEM response.");
+// }
+// }
+//
+// return buffer.toByteArray();
+// } else {
+// return ((InputStream)result.getEntity()).readAllBytes();
+// }
+// } catch (IllegalStateException | IOException e) {
+// throw new InternalServerErrorException("Error while processing transferring result from AEM.", e);
+// }
+// }
+//
}
/**
@@ -289,7 +347,7 @@ public record Response(byte[] responseBytes, String mediaType) implements Submit
* @return
* Response object with a media type of "text/plain"
*/
- public static Response text(String text) { return new Response(text.getBytes(StandardCharsets.UTF_8), MediaType.TEXT_PLAIN); }
+ public static Response text(String text) { return new Response(text.getBytes(StandardCharsets.UTF_8), MediaType.TEXT_PLAIN_VALUE); }
/**
* Creates an HTML response from a String
*
@@ -298,7 +356,7 @@ public record Response(byte[] responseBytes, String mediaType) implements Submit
* @return
* Response object with a media type of "text/html"
*/
- public static Response html(String html) { return new Response(html.getBytes(StandardCharsets.UTF_8), MediaType.TEXT_HTML); }
+ public static Response html(String html) { return new Response(html.getBytes(StandardCharsets.UTF_8), MediaType.TEXT_HTML_VALUE); }
/**
* Creates an JSON response from a String
*
@@ -307,7 +365,7 @@ public record Response(byte[] responseBytes, String mediaType) implements Submit
* @return
* Response object with a media type of "application/html"
*/
- public static Response json(String json) { return new Response(json.getBytes(StandardCharsets.UTF_8), MediaType.APPLICATION_JSON); }
+ public static Response json(String json) { return new Response(json.getBytes(StandardCharsets.UTF_8), MediaType.APPLICATION_JSON_VALUE); }
/**
* Creates an XML response from a String
*
@@ -316,7 +374,7 @@ public record Response(byte[] responseBytes, String mediaType) implements Submit
* @return
* Response object with a media type of "application/xml"
*/
- public static Response xml(String xml) { return new Response(xml.getBytes(StandardCharsets.UTF_8), MediaType.APPLICATION_XML); }
+ public static Response xml(String xml) { return new Response(xml.getBytes(StandardCharsets.UTF_8), MediaType.APPLICATION_XML_VALUE); }
};
/**
* A Temporary Redirect (302 HTTP status code) response
@@ -481,7 +539,7 @@ public SubmitResponse processSubmission(Submission submission) {
* ALL - process all handlers that canHandle a request.
*
*/
- static class AfSubmitLocalProcessor implements AfSubmitProcessor {
+ static class AfSubmitLocalProcessor implements SpringAfSubmitProcessor {
private final static Logger logger = LoggerFactory.getLogger(AfSubmitLocalProcessor.class);
private static final String REMAINDER_PATH_SUFFIX = "/jcr:content/guideContainer.af.submit.jsp";
@@ -492,10 +550,10 @@ static class AfSubmitLocalProcessor implements AfSubmitProcessor {
public interface InternalAfSubmitAemProxyProcessor {
AfSubmitAemProxyProcessor get();
}
-
+
private final List submissionHandlers;
private final AfSubmitAemProxyProcessor aemProxyProcessor;
-
+
AfSubmitLocalProcessor(List submissionHandlers, InternalAfSubmitAemProxyProcessor aemProxyProcessor) {
this.submissionHandlers = submissionHandlers;
this.aemProxyProcessor = aemProxyProcessor.get();
@@ -504,29 +562,37 @@ public interface InternalAfSubmitAemProxyProcessor {
submissionHandlers.forEach(sh->logger.atDebug().addArgument(sh.getClass().getName()).log(" Found AfSubmissionHandler named '{}'."));
}
}
-
+
@Override
- public Response processRequest(FormDataMultiPart inFormData, HttpHeaders headers, String remainder) {
+ public ResponseEntity processRequest(MultipartHttpServletRequest inFormData, String remainder) {
if (!remainder.endsWith(REMAINDER_PATH_SUFFIX)) {
// If the submission does not end with the expected submission suffix, then just proxy it AEM.
- return aemProxyProcessor.processRequest(inFormData, headers, remainder);
+ return aemProxyProcessor.processRequest(inFormData, remainder);
}
String formName = determineFormName(remainder);
Optional firstHandler = submissionHandlers.stream()
.filter(sh->canHandle(sh, formName))
.findFirst();
- return firstHandler.map(h->processSubmission(h, inFormData, headers, formName))
+ return firstHandler.map(h->processSubmission(h, inFormData, formName))
.orElseGet(()->errorResponse());
}
-
- private Response processSubmission(AfSubmissionHandler handler, FormDataMultiPart inFormData, HttpHeaders headers, String formName) {
+
+ private ResponseEntity processSubmission(AfSubmissionHandler handler, MultipartHttpServletRequest inFormData, String formName) {
logger.atInfo().addArgument(handler.getClass().getName()).log("Calling AfSubmissionHandler={}");
- return formulateResponse(handler.processSubmission(formulateSubmission(inFormData, headers, formName)));
+ return formulateResponse(handler.processSubmission(formulateSubmission(inFormData, formName)));
}
private String determineFormName(String guideContainerPath) {
- return guideContainerPath.substring(0, guideContainerPath.length() - REMAINDER_PATH_SUFFIX.length());
+ return extractFormName(removeLeadingSlash(guideContainerPath));
+ }
+
+ private static String extractFormName(String relativePath) {
+ return relativePath.substring(0, relativePath.length() - REMAINDER_PATH_SUFFIX.length());
+ }
+
+ private static String removeLeadingSlash(String path) {
+ return path.startsWith("/") ? path.substring(1) : path;
}
private boolean canHandle(AfSubmissionHandler sh, String formName) {
@@ -536,7 +602,7 @@ private boolean canHandle(AfSubmissionHandler sh, String formName) {
}
// Create a AfSubmissionHandler.Submission object from the JAX-RS Request classes.
- private AfSubmissionHandler.Submission formulateSubmission(FormDataMultiPart inFormData, HttpHeaders headers, String formName) {
+ private AfSubmissionHandler.Submission formulateSubmission(MultipartHttpServletRequest inFormData, String formName) {
class ExtractedData {
String formData;
String redirectUrl;
@@ -552,39 +618,52 @@ class ExtractedData {
return new AfSubmissionHandler.Submission(extractedData.formData,
formName,
extractedData.redirectUrl,
- transferHeaders(headers)
+ transferHeaders(inFormData.getRequestHeaders())
);
}
// Transfer headers from JAX-RS construct to Spring construct (in order to keep JAX-RS encapsulated in this class)
private MultiValueMapAdapter transferHeaders(HttpHeaders headers) {
if (logger.isDebugEnabled()) {
- headers.getRequestHeaders().forEach((k,v)->logger.atDebug().addArgument(k).addArgument(v.size()).log("Found Http header {} with {} values."));
+ headers.forEach((k,v)->logger.atDebug().addArgument(k).addArgument(v.size()).log("Found Http header {} with {} values."));
}
- return new MultiValueMapAdapter(headers.getRequestHeaders());
+ return new MultiValueMapAdapter(headers);
}
// Convert the SubmitResponse object into a JAX-RS Response object.
- private Response formulateResponse(AfSubmissionHandler.SubmitResponse submitResponse) {
+ private ResponseEntity formulateResponse(AfSubmissionHandler.SubmitResponse submitResponse) {
if (submitResponse instanceof AfSubmissionHandler.SubmitResponse.Response response) {
- var builder = response.responseBytes().length > 0 ? Response.ok().entity(response.responseBytes()).type(response.mediaType())
- : Response.noContent();
- return builder.build();
+ return response.responseBytes().length > 0
+ ? ResponseEntity.ok().contentType(MediaType.valueOf(response.mediaType())).body(response.responseBytes())
+ : ResponseEntity.noContent().build();
} else if (submitResponse instanceof AfSubmissionHandler.SubmitResponse.SeeOther redirectFound) {
- return Response.seeOther(redirectFound.redirectUrl()).build();
+ return seeOther(redirectFound.redirectUrl());
} else if (submitResponse instanceof AfSubmissionHandler.SubmitResponse.Redirect redirect) {
- return Response.temporaryRedirect(redirect.redirectUrl()).build();
+ return temporaryRedirect(redirect.redirectUrl());
} else {
// This cannot happen, but we need to supply an else until we can turn this code into a switch
// expression in JDK 21.
throw new IllegalStateException("Unexpected SubmitResponse class type '%s', this should never happen!".formatted(submitResponse.getClass().getName()));
}
}
-
+
+ private static ResponseEntity seeOther(URI url) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setLocation(url);
+ return ResponseEntity.status(HttpStatusCode.valueOf(HttpStatus.SEE_OTHER.value())).headers(headers).build();
+ }
+
+ private static ResponseEntity temporaryRedirect(URI url) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setLocation(url);
+ return ResponseEntity.status(HttpStatusCode.valueOf(HttpStatus.TEMPORARY_REDIRECT.value())).headers(headers).build();
+ }
+
// Generate an JAX-RS Error response if not AfSubmissionHandler was found.
- private Response errorResponse() {
+ private static ResponseEntity errorResponse() {
logger.atWarn().log("No applicable AfSubmissionHandler found.");
- return Response.status(Response.Status.NOT_FOUND).build();
+ return ResponseEntity.notFound().build();
}
}
+
}
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAutoConfiguration.java b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAutoConfiguration.java
index 7e917dc1..1dd997ac 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAutoConfiguration.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyAutoConfiguration.java
@@ -9,19 +9,15 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
-import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
+import org.springframework.boot.autoconfigure.web.client.RestClientSsl;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.ssl.SslBundles;
-import org.springframework.boot.system.JavaVersion;
import org.springframework.context.annotation.Bean;
-import org.springframework.core.task.SimpleAsyncTaskExecutor;
-import org.springframework.core.task.TaskExecutor;
import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmissionHandler;
-import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitAemProxyProcessor;
import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitLocalProcessor;
import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitLocalProcessor.InternalAfSubmitAemProxyProcessor;
-import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitAemProxyProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.SpringAfSubmitProcessor;
/**
* AutoConfiguration for the Reverse Proxy Library which reverse proxies secondary
@@ -30,44 +26,33 @@
@AutoConfiguration
@ConditionalOnWebApplication(type=Type.SERVLET)
@ConditionalOnProperty(prefix="fluentforms.rproxy", name="enabled", havingValue="true", matchIfMissing=true )
+@ConditionalOnProperty(prefix="fluentforms.rproxy", name="type", havingValue="springmvc", matchIfMissing=true )
@EnableConfigurationProperties({AemConfiguration.class, AemProxyConfiguration.class})
+@ConditionalOnMissingBean(AemProxyImplemention.class)
public class AemProxyAutoConfiguration {
-
+
/**
- * Configures the JAX-RS resources associated with reverse proxying resources and submissions from
- * Adaptive Forms.
+ * Marker bean to indicate that the Spring MVC-based AEM Proxy implementation is being used.
*
- * @param aemConfig
- * AEM configuration typically configured using application.properties files. This is
- * typically injected by the Spring Framework.
- * @param aemProxyConfig
- * AEM proxy-specific configuration typically configured using application.properties files.
- * This is typically injected by the Spring Framework.
- * @param aemProxyTaskExecutor
* @return
- * JAX-RS Resource configuration customizer that is used by the spring-jersey starter to configure
- * JAX-RS Resources (i.e. endpoints)
*/
@Bean
- public ResourceConfigCustomizer afProxyConfigurer(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, @Autowired(required = false) SslBundles sslBundles, TaskExecutor aemProxyTaskExecutor) {
- return config->config.register(new AemProxyEndpoint(aemConfig, aemProxyConfig, sslBundles, aemProxyTaskExecutor))
- .register(new AemProxyAfSubmission())
- ;
+ AemProxyImplemention aemProxyImplemention() {
+ return new AemProxyImplemention() {
+ // This is just a marker bean.
+ };
}
- /**
- * Supply a TaskExecutor for use by the AemProxyEndpoint. This is used to process csrf token requests because they are Chunked.
- *
- * @return the taskeExecutor that will be used to process csrf token requests.
- */
@Bean
- public TaskExecutor aemProxyTaskExecutor() {
- var executor = new SimpleAsyncTaskExecutor("AemProxy-");
- // Use virtual threads if available. This will be the default for Java 21 and later.
- executor.setVirtualThreads(JavaVersion.getJavaVersion().isEqualOrNewerThan(JavaVersion.TWENTY_ONE));
- return executor;
+ AemProxyEndpoint aemProxyEndpoint(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, @Autowired(required = false) RestClientSsl restClientSsl) {
+ return new AemProxyEndpoint(aemConfig, aemProxyConfig, restClientSsl);
}
+ @Bean
+ AemProxyAfSubmission aemProxyAfSubmission(SpringAfSubmitProcessor submitProcessor) {
+ return new AemProxyAfSubmission(submitProcessor);
+ }
+
/**
* Supply a AfSubmitLocalProcessor if the user has not already supplied one *and* there is an
* available AfSubmissionHandler
@@ -83,10 +68,10 @@ public TaskExecutor aemProxyTaskExecutor() {
* Processor that will call the first submission handler that says that it can
* process this request.
*/
- @ConditionalOnMissingBean(AfSubmitProcessor.class)
+ @ConditionalOnMissingBean(SpringAfSubmitProcessor.class)
@ConditionalOnBean(AfSubmissionHandler.class)
@Bean
- public AfSubmitProcessor localSubmitProcessor(List submissionHandlers, InternalAfSubmitAemProxyProcessor aemProxyProcessor) {
+ public SpringAfSubmitProcessor localSubmitProcessor(List submissionHandlers, InternalAfSubmitAemProxyProcessor aemProxyProcessor) {
return new AfSubmitLocalProcessor(submissionHandlers, aemProxyProcessor);
}
@@ -102,10 +87,10 @@ public AfSubmitProcessor localSubmitProcessor(List submissi
* @return
* Processor that forwards all submissions on to AEM.
*/
- @ConditionalOnMissingBean({AfSubmitProcessor.class, AfSubmissionHandler.class})
+ @ConditionalOnMissingBean({SpringAfSubmitProcessor.class, AfSubmissionHandler.class})
@Bean()
- public AfSubmitProcessor aemSubmitProcessor(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
- return new AfSubmitAemProxyProcessor(aemConfig, sslBundles);
+ public SpringAfSubmitProcessor aemSubmitProcessor(AemConfiguration aemConfig, @Autowired(required = false) RestClientSsl restClientSsl) {
+ return new AfSubmitAemProxyProcessor(aemConfig, restClientSsl);
}
/**
@@ -124,7 +109,7 @@ public AfSubmitProcessor aemSubmitProcessor(AemConfiguration aemConfig, @Autowir
@ConditionalOnMissingBean(InternalAfSubmitAemProxyProcessor.class)
@ConditionalOnBean(AfSubmissionHandler.class)
@Bean
- public InternalAfSubmitAemProxyProcessor aemProxyProcessor(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
- return ()->new AfSubmitAemProxyProcessor(aemConfig, sslBundles);
+ public InternalAfSubmitAemProxyProcessor aemProxyProcessor(AemConfiguration aemConfig, @Autowired(required = false) RestClientSsl restClientSsl) {
+ return ()->new AfSubmitAemProxyProcessor(aemConfig, restClientSsl);
}
}
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyEndpoint.java b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyEndpoint.java
index 794eb6eb..2804d8f0 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyEndpoint.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyEndpoint.java
@@ -3,33 +3,34 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URI;
import java.nio.charset.StandardCharsets;
+import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.naming.ConfigurationException;
-import org.glassfish.jersey.client.ChunkedInput;
-import org.glassfish.jersey.server.ChunkedOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.boot.ssl.SslBundles;
-import org.springframework.core.task.TaskExecutor;
+import org.springframework.boot.autoconfigure.web.client.RestClientSsl;
+import org.springframework.boot.ssl.NoSuchSslBundleException;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.client.support.BasicAuthenticationInterceptor;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestClient;
+import org.springframework.web.util.UriComponentsBuilder;
import com._4point.aem.docservices.rest_services.client.helpers.ReplacingInputStream;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.HeaderParam;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.client.WebTarget;
-import jakarta.ws.rs.core.GenericType;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-
/**
* Reverse Proxy Code which reverse proxies secondary resources (.css, .js, etc.) that the browser will request.
* These requests are forwarded to AEM.
@@ -42,74 +43,64 @@
* get the AdaptiveForm or HTML5 Form using the FLuentForms libraries.
*
*/
-@Path("/aem")
+@CrossOrigin
+@RestController
+@RequestMapping("/aem")
public class AemProxyEndpoint {
private final static Logger logger = LoggerFactory.getLogger(AemProxyEndpoint.class);
private static final String AEM_APP_PREFIX = "/";
- private Client httpClient;
+ private final RestClient httpClient;
private final AemProxyConfiguration aemProxyConfig;
private final AemConfiguration aemConfig;
- private final TaskExecutor taskExecutor;
/**
*
*/
- public AemProxyEndpoint(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, SslBundles sslBundles, TaskExecutor taskExecutor) {
+ public AemProxyEndpoint(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, RestClientSsl restClientSsl) {
this.aemProxyConfig = aemProxyConfig;
this.aemConfig = aemConfig;
- this.httpClient = JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle(), aemConfig.user(), aemConfig.password());
- this.taskExecutor = taskExecutor;
+ this.httpClient = createClient(aemConfig, RestClient.builder(), restClientSsl);
}
- @Path("libs/granite/csrf/token.json")
- @GET
- public ChunkedOutput proxyOsgiCsrfToken() throws IOException {
+ @GetMapping("/libs/granite/csrf/token.json")
+ public ResponseEntity proxyOsgiCsrfToken() throws IOException {
final String path = AEM_APP_PREFIX + "libs/granite/csrf/token.json";
return getCsrfToken(path);
}
- @Path("lc/libs/granite/csrf/token.json")
- @GET
- public ChunkedOutput proxyJeeCsrfToken() throws IOException {
+ @GetMapping("/lc/libs/granite/csrf/token.json")
+ public ResponseEntity proxyJeeCsrfToken() throws IOException {
final String path = "/lc/libs/granite/csrf/token.json";
return getCsrfToken(path);
}
- private ChunkedOutput getCsrfToken(final String path) {
+ private ResponseEntity getCsrfToken(final String path) {
logger.atDebug().log("Proxying GET request. CSRF token");
- WebTarget webTarget = httpClient.target(aemConfig.url())
- .path(path);
- logger.atDebug().log(()->"Proxying GET request for CSRF token '" + webTarget.getUri().toString() + "'.");
- Response result = webTarget.request()
- .get();
-
- logger.atDebug().log(()->"CSRF token GET response status = " + result.getStatus());
- final ChunkedInput chunkedInput = result.readEntity(new GenericType>() {});
- final ChunkedOutput output = new ChunkedOutput(byte[].class);
- taskExecutor.execute(() -> {
- try (result; chunkedInput; output) {
- byte[] chunk;
- while ((chunk = chunkedInput.read()) != null) {
- output.write(chunk);
- logger.debug("Returning GET chunk for CSRF token.");
- }
- logger.debug("Finished GETting chunks for CSRF token.");
- } catch (IllegalStateException | IOException e) {
- e.printStackTrace();
- }
- logger.debug("Exiting Thread.");
- });
+ URI uri = UriComponentsBuilder.fromUriString(aemConfig.url())
+ .path(path)
+ .build()
+ .toUri();
+
+ logger.atDebug().log(()->"Proxying GET request for CSRF token '" + uri.toString() + "'.");
+ ResponseEntity response = httpClient.get()
+ .uri(uri)
+ .retrieve()
+ .toEntity(byte[].class);
+
+ logger.atDebug()
+ .addArgument(()->response.getStatusCode().toString())
+ .log(()->"CSRF token GET response status = {}");
logger.atDebug().log("Returning GET response for CSRF token.");
- return output;
+ return ResponseEntity.status(response.getStatusCode())
+ .headers(removeChunkedTransferEncoding(response.getHeaders()))
+ .body(response.getBody());
}
-
-
/**
* This function acts as a reverse proxy for anything under clientlibs. It just forwards
* anything it receives on AEM and then returns the response.
@@ -118,31 +109,54 @@ private ChunkedOutput getCsrfToken(final String path) {
* @return
* @throws ConfigurationException
*/
- @Path("{remainder : .+}")
- @GET
- public Response proxyGet(@PathParam("remainder") String remainder) {
+ @GetMapping("/{*remainder}")
+ public ResponseEntity proxyGet(@PathVariable("remainder") String remainder) {
logger.atDebug().log(()->"Proxying GET request. remainder=" + remainder);
- WebTarget webTarget = httpClient.target(aemConfig.url())
- .path(AEM_APP_PREFIX + remainder);
- logger.atDebug().log(()->"Proxying GET request for target '" + webTarget.getUri().toString() + "'.");
- Response result = webTarget.request()
- .get();
+ URI uri = UriComponentsBuilder.fromUriString(aemConfig.url())
+ .path(AEM_APP_PREFIX + remainder)
+ .build()
+ .toUri();
+ logger.atDebug().log(()->"Proxying GET request for target '" + uri.toString() + "'.");
+ ResponseEntity response = httpClient.get()
+ .uri(uri)
+ .retrieve()
+ .toEntity(byte[].class);
+
if (logger.isDebugEnabled()) {
- result.getHeaders().forEach((h, l)->logger.atDebug().log("For " + webTarget.getUri().toString() + ", Header:" + h + "=" + l.stream().map(o->(String)o).collect(Collectors.joining("','", "'", "'"))));
+ response.getHeaders().forEach((h, l)->logger.atDebug().log("For " + uri + ", Header:" + h + "=" + l.stream().map(o->(String)o).collect(Collectors.joining("','", "'", "'"))));
}
- logger.atDebug().log(()->"Returning GET response from target '" + webTarget.getUri().toString() + "' status code=" + result.getStatus() + ".");
+ logger.atDebug().log(()->"Returning GET response from target '" + uri + "' status code=" + response.getStatusCode().value() + ".");
Function filter = switch (remainder) {
- case "etc.clientlibs/clientlibs/granite/utils.js" -> this::substituteAfBaseLocation;
- case "etc.clientlibs/fd/xfaforms/clientlibs/profile.js" -> this::fixTogglesDotJsonLocation;
+ case "/etc.clientlibs/clientlibs/granite/utils.js" -> this::substituteAfBaseLocation;
+ case "/etc.clientlibs/fd/xfaforms/clientlibs/profile.js" -> AemProxyEndpoint::fixTogglesDotJsonLocation;
default -> is -> is; // No filtering needed
};
- return Response.fromResponse(result)
- .header("Transfer-Encoding", null) // Remove the Transfer-Encoding header
- .entity(filter.apply(result.readEntity(InputStream.class)))
- .build();
+ return ResponseEntity.status(response.getStatusCode())
+ .headers(removeChunkedTransferEncoding(response.getHeaders()))
+ .body(filterByteArray(response.getBody(), filter));
}
+ // Remove transfer-encoding header to prevent chunked encoding issues.
+ private static HttpHeaders removeChunkedTransferEncoding(HttpHeaders headers) {
+ var transferEncoding = headers.getFirst(HttpHeaders.TRANSFER_ENCODING);
+ if (transferEncoding != null && transferEncoding.equalsIgnoreCase("chunked")) {
+ var newHeaders = new HttpHeaders(headers);
+ newHeaders.remove(HttpHeaders.TRANSFER_ENCODING);
+ return newHeaders;
+ }
+ return headers;
+ }
+
+ // passes a byte array through an InputStream filter and returns the result as a byte array.
+ private static byte[] filterByteArray(byte[] input, Function isFilter) {
+ try (var bais = new ByteArrayInputStream(input)) {
+ return isFilter.apply(bais).readAllBytes();
+ } catch (IOException e) {
+ throw new IllegalStateException("This should never happen - ", e);
+ }
+ }
+
/**
* Wraps an InputStream with a wrapper that replaces some code in the Adobe utils.js code.
*
@@ -167,61 +181,97 @@ private InputStream substituteAfBaseLocation(InputStream is) {
}
}
- private InputStream fixTogglesDotJsonLocation(InputStream is) {
+ private static InputStream fixTogglesDotJsonLocation(InputStream is) {
String target = "\"/etc.clientlibs/toggles.json\"";
String replacement = "\"/aem/etc.clientlibs/toggles.json\"";
logger.atDebug().log("Altering profile.js to replace '{}' with '{}'", target, replacement);
return new ReplacingInputStream(is, target, replacement);
}
- @Path("{remainder : .+}")
- @POST
- public Response proxyPost(@PathParam("remainder") String remainder, @HeaderParam("Content-Type") String contentType, InputStream in) {
+ @PostMapping("/{*remainder}")
+ public ResponseEntity proxyPost(@PathVariable("remainder") String remainder, @RequestHeader(value = "Content-Type", required = false) String contentType, byte[] in) {
logger.atDebug().log("Proxying POST request. remainder={}", remainder);
- WebTarget webTarget = httpClient.target(aemConfig.url())
- .path(AEM_APP_PREFIX + remainder);
- logger.atDebug().addArgument(()->webTarget.getUri().toString())
- .addArgument(contentType)
- .log(()->"Proxying POST request for target '{}'. ContentType='{}'.");
- Response result = webTarget.request()
- .post(Entity.entity(
- logger.isDebugEnabled() ? debugInput(in, webTarget.getUri().toString()) : in, // if Debug is on, write out information about input stream
- contentType != null ? contentType : "application/octet-stream" // supply default content type if it was omitted.
- ));
+ URI uri = UriComponentsBuilder.fromUriString(aemConfig.url())
+ .path(AEM_APP_PREFIX + remainder)
+ .build()
+ .toUri();
+ logger.atDebug().addArgument(()->uri.toString())
+ .addArgument(contentType)
+ .log(()->"Proxying POST request for target '{}'. ContentType='{}'.");
+
+ ResponseEntity response = httpClient.post()
+ .uri(uri)
+ .body(debugInput(Objects.requireNonNullElseGet(in, ()->new byte[0]), uri.toString())) // if Debug is on, write out information about input stream
+ .contentType(contentType != null ? MediaType.valueOf(contentType) : MediaType.APPLICATION_OCTET_STREAM) // supply default content type if it was omitted.
+ .retrieve()
+ .toEntity(byte[].class);
if (remainder.contains("af.submit.jsp")) {
- logger.atDebug().addArgument(()->Boolean.valueOf(result == null).toString())
+ logger.atDebug().addArgument(()->Boolean.valueOf(response == null).toString())
.log("result == null is {}.");
- MediaType mediaType = result.getMediaType();
+ MediaType mediaType = response.getHeaders().getContentType();
logger.atDebug()
- .addArgument(()->webTarget.getUri().toString())
+ .addArgument(()->uri.toString())
.addArgument(()->mediaType != null ? mediaType.toString() : "")
- .addArgument(()->result.getHeaderString("Transfer-Encoding"))
+ .addArgument(()->response.getHeaders().getFirst("Transfer-Encoding"))
.log("Returning POST response from target '{}'. contentType='{}'. transfer-encoding='{}'.");
} else {
logger.atDebug()
- .addArgument(webTarget.getUri()::toString)
+ .addArgument(uri::toString)
.log("Returning POST response from target '{}'.");
}
- return Response.fromResponse(result).build();
+ return response;
}
- private InputStream debugInput(InputStream in, String target) {
- try {
- byte[] inputBytes = in.readAllBytes();
- logger.atDebug()
- .log("Proxying POST request for target '{}'. numberOfBytes proxied='{}'.", target, inputBytes.length);
- logger.atTrace()
- .addArgument(target)
- .addArgument(()->new String(inputBytes, StandardCharsets.UTF_8))
- .log("Proxying POST request for target '{}'. input bytes proxied='{}'.");
- return new ByteArrayInputStream(inputBytes);
- } catch (IOException e) {
- logger.atError()
- .setCause(e)
- .log("Error reading input stream.");
- return new ByteArrayInputStream(new byte[0]);
- }
+ private static byte[] debugInput(byte[] inputBytes, String target) {
+ logger.atDebug()
+ .log("Proxying POST request for target '{}'. numberOfBytes proxied='{}'.", target, inputBytes.length);
+ logger.atTrace()
+ .addArgument(target)
+ .addArgument(()->new String(inputBytes, StandardCharsets.UTF_8))
+ .log("Proxying POST request for target '{}'. input bytes proxied='{}'.");
+ return inputBytes;
}
+
+ private static RestClient createClient(
+ AemConfiguration aemConfig,
+ RestClient.Builder builder,
+ RestClientSsl restClientSsl
+ ) {
+
+ if (aemConfig.useSsl()) {
+ configureSsl(builder, restClientSsl, aemConfig.sslBundle());
+ } else {
+ logger.info("Creating default client.");
+ }
+
+ if (aemConfig.user() != null) {
+ configureBasicAuth(builder, aemConfig.user(), aemConfig.password());
+ }
+
+ return builder.baseUrl(aemConfig.url())
+ .build();
+ }
+
+ private static void configureBasicAuth(RestClient.Builder builder, String username, String password) {
+ builder.requestInterceptor(new BasicAuthenticationInterceptor(username, password));
+ }
+
+ private static void configureSsl(RestClient.Builder builder, RestClientSsl restClientSsl, String bundleName) {
+ if (restClientSsl != null && bundleName != null) {
+ logger.info("Using Client ssl bundle: '" + bundleName + "'.");
+ try {
+ builder.apply(restClientSsl.fromBundle(bundleName));
+ } catch (NoSuchSslBundleException e) {
+ // Eat the exception and fall through to the default client
+ // Default the SSL context (which includes the default trust store)
+ logger.warn("Unable to locate ssl bundle '" + bundleName + "'. Creating default client.");
+ }
+ } else if (restClientSsl == null && bundleName != null) {
+ throw new IllegalStateException("RestClientSsl is null, unable to configure SSL bundle '" + bundleName + "'.");
+ } else { /* bundlename == null */
+ logger.info("AEM bundleName is null. Creating default client.");
+ }
+ }
}
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyImplemention.java b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyImplemention.java
new file mode 100644
index 00000000..42b26f10
--- /dev/null
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/AemProxyImplemention.java
@@ -0,0 +1,9 @@
+package com._4point.aem.fluentforms.spring;
+
+/**
+ * This is a placeholder interface used to identify the AEM Proxy Implementation, Each implementation
+ * (spring-mvc, jersey, etc.) will provide a bean that implements this one so that only one implementation is used.
+ */
+public interface AemProxyImplemention {
+
+}
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/FluentFormsAutoConfiguration.java b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/FluentFormsAutoConfiguration.java
index 659fe806..00a99df8 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/FluentFormsAutoConfiguration.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/main/java/com/_4point/aem/fluentforms/spring/FluentFormsAutoConfiguration.java
@@ -4,17 +4,14 @@
import java.util.function.Consumer;
import java.util.function.Function;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.client.RestClientSsl;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.ssl.NoSuchSslBundleException;
-import org.springframework.boot.ssl.SslBundles;
import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Fallback;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.client.RestClient;
@@ -29,7 +26,6 @@
import com._4point.aem.docservices.rest_services.client.helpers.FormsFeederUrlFilterBuilder;
import com._4point.aem.docservices.rest_services.client.helpers.StandardFormsFeederUrlFilters;
import com._4point.aem.docservices.rest_services.client.html5.Html5FormsService;
-import com._4point.aem.docservices.rest_services.client.jersey.JerseyRestClient;
import com._4point.aem.docservices.rest_services.client.output.RestServicesOutputServiceAdapter;
import com._4point.aem.docservices.rest_services.client.pdfUtility.RestServicesPdfUtilityServiceAdapter;
import com._4point.aem.fluentforms.api.DocumentFactory;
@@ -51,7 +47,6 @@
import com._4point.aem.fluentforms.impl.pdfUtility.PdfUtilityServiceImpl;
import com._4point.aem.fluentforms.spring.rest_services.client.SpringRestClientRestClient;
-import jakarta.ws.rs.client.Client;
/**
* AutoConfiguration for the FluentForms Rest Services Client library.
@@ -64,8 +59,6 @@
@AutoConfiguration
@EnableConfigurationProperties(AemConfiguration.class)
public class FluentFormsAutoConfiguration {
- // // TODO: Either call JerseuRestClient.factory(JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle())) or create SpringRestClient
-// private static final BiFunction restClientFactory = (b, s)->JerseyRestClient.factory(JerseyClientFactory.createClient(b, s));
@SuppressWarnings("unchecked")
private T setAemFields(T builder, AemConfiguration aemConfig) {
@@ -77,11 +70,10 @@ private T setAemFields(T builder, AemConfiguration aemConfig
}
- // matchIfMissing is currently set to false so that, by default (if nothing is specified in the properties file), then the JersetRestClient is used.
- // To use the SpringRestClient, set fluentforms.restclient.springrestclient.enabled=true
- // At some point, we may want to set matchIfMissing=true which would make the SpringRestClient the default..
- @ConditionalOnProperty(prefix="fluentforms", name="restclient", havingValue="springrestclient", matchIfMissing=false )
+ // matchIfMissing is set to true so that, by default (if nothing is specified in the properties file), then the SpringRestClient is used.
+ @ConditionalOnProperty(prefix="fluentforms", name="restclient", havingValue="springrestclient", matchIfMissing=true )
@ConditionalOnMissingBean
+ @Fallback
@Bean
public RestClientFactory springRestClientFactory(AemConfiguration aemConfig, RestClient.Builder restClientBuilder, RestClientSsl restClientSsl) {
return SpringRestClientRestClient.factory(aemConfig.useSsl() ? restClientBuilder.apply(getSslBundle(aemConfig.sslBundle(), restClientSsl))
@@ -89,8 +81,7 @@ public RestClientFactory springRestClientFactory(AemConfiguration aemConfig, Res
); // Create a RestClientFactory using Spring RestClient implementation
}
-
- private Consumer getSslBundle(String sslBundleName, RestClientSsl restClientSsl) {
+ private static Consumer getSslBundle(String sslBundleName, RestClientSsl restClientSsl) {
try {
return restClientSsl.fromBundle(sslBundleName);
} catch (NoSuchSslBundleException e) {
@@ -101,22 +92,7 @@ private Consumer getSslBundle
return b->{}; // No-op;
}
}
-
- @Configuration(proxyBeanMethods = false)
- @ConditionalOnClass(org.glassfish.jersey.client.JerseyClient.class)
- public static class JerseyRestClientConfiguration {
-
- @ConditionalOnProperty(prefix="fluentforms", name="restclient", havingValue="jersey", matchIfMissing=true )
- @ConditionalOnMissingBean
- @Bean
- public RestClientFactory jerseyRestClientFactory(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
- Client jerseyClient = JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle()); // Create custom Jersey Client with SSL bundle
- return JerseyRestClient.factory(jerseyClient); // Create a RestClientFactory using JerseyClient implementation
- }
- }
-
-
@ConditionalOnMissingBean
@Bean
public AdaptiveFormsService adaptiveFormsService(AemConfiguration aemConfig, Function afInputStreamFilter, RestClientFactory restClientFactory) {
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmissionTest.java b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmissionTest.java
index 39a739b3..960760fa 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmissionTest.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyAfSubmissionTest.java
@@ -1,7 +1,5 @@
package com._4point.aem.fluentforms.spring;
-import static com._4point.aem.fluentforms.spring.AemProxyAfSubmissionTest.TestApplication.JerseyConfig;
-import static com._4point.testing.matchers.jaxrs.ResponseMatchers.*;
import static com._4point.testing.matchers.javalang.ExceptionMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
@@ -13,10 +11,10 @@
import java.util.List;
import java.util.function.Function;
-import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.media.multipart.FormDataMultiPart;
-import org.glassfish.jersey.media.multipart.MultiPartFeature;
-import org.glassfish.jersey.server.ResourceConfig;
+import org.hamcrest.Description;
+import org.hamcrest.FeatureMatcher;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -35,25 +33,29 @@
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.HttpStatusCode;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestClient;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitAemProxyProcessor;
import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitLocalProcessor;
import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmissionHandler;
-import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.SpringAfSubmitProcessor;
import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmissionHandler.SubmitResponse;
import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitLocalProcessor.InternalAfSubmitAemProxyProcessor;
import com._4point.aem.fluentforms.spring.AemProxyAfSubmissionTest.AemProxyAfSubmissionTestWithLocalAfSubmitProcessorTest.MockAemProxy;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
-
-import jakarta.ws.rs.client.ClientBuilder;
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.client.WebTarget;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
+import com.github.tomakehurst.wiremock.verification.LoggedRequest;
/**
* Tests for AemProxyAfSubmissions classes.
@@ -65,23 +67,52 @@ class AemProxyAfSubmissionTest {
public static final String AF_TEMPLATE_NAME = "sample00002test";
private static final String SUBMIT_ADAPTIVE_FORM_SERVICE_PATH = "/aem/content/forms/af/" + AF_TEMPLATE_NAME + "/jcr:content/guideContainer.af.submit.jsp";
private static final String AEM_SUBMIT_ADAPTIVE_FORM_SERVICE_PATH = SUBMIT_ADAPTIVE_FORM_SERVICE_PATH.substring(4); // Same as above minus "/aem"
- public static final MediaType APPLICATION_PDF = new MediaType("application", "pdf");
private static final String SAMPLE_RESPONSE_BODY = "body";
- record JakartaRestClient(WebTarget target, URI uri) {};
-
- public static JakartaRestClient setUpRestClient(int port) {
- var uri = getBaseUri(port);
- var target = ClientBuilder.newClient() //newClient(clientConfig)
- .property(ClientProperties.FOLLOW_REDIRECTS, Boolean.FALSE) // Disable re-directs so that we can test for "thank you page" redirection.
- .register(MultiPartFeature.class)
- .target(uri);
- return new JakartaRestClient(target, uri);
+// record JakartaRestClient(WebTarget target, URI uri) {};
+//
+// public static JakartaRestClient setUpRestClient(int port) {
+// var uri = getBaseUri(port);
+// var target = ClientBuilder.newClient() //newClient(clientConfig)
+// .property(ClientProperties.FOLLOW_REDIRECTS, Boolean.FALSE) // Disable re-directs so that we can test for "thank you page" redirection.
+// .register(MultiPartFeature.class)
+// .target(uri);
+// return new JakartaRestClient(target, uri);
+// }
+
+ private static RestClient createRestClient(int port) {
+ return RestClient.builder()
+ .baseUrl(getBaseUri(port))
+ .build();
}
+
+ record FormDataMultiPart(MultiValueMap> parts) {
+ public FormDataMultiPart() {
+ this(new LinkedMultiValueMap<>());
+ }
+
+ public FormDataMultiPart field(String fieldName, String fieldData) {
+ internalAdd(fieldName, fieldData, MediaType.TEXT_PLAIN);
+ return this;
+ }
+ public FormDataMultiPart field(String fieldName, byte[] fieldData) {
+ internalAdd(fieldName, fieldData, MediaType.APPLICATION_OCTET_STREAM);
+ return this;
+ }
+
+ private void internalAdd(String fieldName, Object fieldData, MediaType contentType) {
+ parts.add(fieldName, new HttpEntity<>(fieldData, new HttpHeaders() {
+ {
+ setContentType(contentType);
+ }
+ }));
+ }
+ }
+
/* package */ static FormDataMultiPart mockFormData(String redirect, String data) {
- final FormDataMultiPart getPdfForm = new FormDataMultiPart();
+ var getPdfForm = new FormDataMultiPart();
getPdfForm.field("guideContainerPath", "/aem/content/forms/af/" + AF_TEMPLATE_NAME + "/jcr:content/guideContainer")
.field("aemFormComponentPath", "")
.field("_asyncSubmit", "false")
@@ -112,10 +143,6 @@ public static class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
-
- @Component
- public static class JerseyConfig extends ResourceConfig {
- }
}
/**
@@ -123,9 +150,9 @@ public static class JerseyConfig extends ResourceConfig {
*
*/
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
- classes = {TestApplication.class, JerseyConfig.class, AfSubmitAemProxyProcessor.class},
+ classes = {TestApplication.class, AfSubmitAemProxyProcessor.class},
properties = {
-// "debug",
+ "debug",
"fluentforms.aem.servername=" + "localhost",
"fluentforms.aem.port=" + "8502",
"fluentforms.aem.user=admin",
@@ -153,11 +180,13 @@ public static class AemProxyAfSubmissionTestWithAemAfSubmitProcessorTest {
@LocalServerPort
private int port;
- private JakartaRestClient jrc;
+// private JakartaRestClient jrc;
+ private RestClient restClient;
@BeforeEach
public void setUp() throws Exception {
- jrc = setUpRestClient(port);
+// jrc = setUpRestClient(port);
+ restClient = createRestClient(port);
}
@Test
@@ -170,15 +199,35 @@ void test() {
final FormDataMultiPart getPdfForm = mockFormData("foo", "bar");
// when
- Response response = jrc.target.path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH).request().accept(APPLICATION_PDF)
- .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
+ MultiValueMap> parts = getPdfForm.parts();
+ ResponseEntity response = restClient.post()
+ .uri(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+// .contentType(MediaType.MULTIPART_FORM_DATA)
+ .body(parts)
+ .accept(MediaType.APPLICATION_PDF)
+ .retrieve()
+ .toEntity(byte[].class)
+ ;
+
+// .target.path().request().accept(APPLICATION_PDF)
+// .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
// then
- assertThat(response, allOf(isStatus(Response.Status.OK),hasEntityMatching(equalTo(expectedResponseString.getBytes()))));
+ assertThat(response, allOf(hasStatus(HttpStatus.OK), hasEntityMatching(equalTo(expectedResponseString.getBytes()))));
WireMock.verify(
- WireMock.postRequestedFor(WireMock.urlEqualTo(AEM_SUBMIT_ADAPTIVE_FORM_SERVICE_PATH))
- .withAnyRequestBodyPart(WireMock.aMultipart("jcr:data").withBody(WireMock.equalTo("bar")))
+// WireMock.postRequestedFor(WireMock.urlMatching(AEM_SUBMIT_ADAPTIVE_FORM_SERVICE_PATH))
+// .withAnyRequestBodyPart(WireMock.aMultipart("jcr:data").withBody(WireMock.equalTo("bar")))
+ WireMock.postRequestedFor(WireMock.urlMatching(AEM_SUBMIT_ADAPTIVE_FORM_SERVICE_PATH))
+// .withAnyRequestBodyPart(WireMock.aMultipart("jcr:data"))
);
+
+ System.out.println("Writing to: " + SUBMIT_ADAPTIVE_FORM_SERVICE_PATH);
+ LoggedRequest loggedRequest = WireMock.findAll(WireMock.postRequestedFor(WireMock.urlEqualTo(AEM_SUBMIT_ADAPTIVE_FORM_SERVICE_PATH))).get(0);
+ String requestBody = loggedRequest.getBodyAsString();
+ System.out.println("Request Body:\n" + requestBody);
+ loggedRequest.getAllHeaderKeys().forEach(headerName -> {
+ System.out.println("Header: " + headerName + " = " + loggedRequest.getHeader(headerName));
+ });
}
}
@@ -188,7 +237,7 @@ void test() {
*
*/
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
- classes = {TestApplication.class, JerseyConfig.class, AfSubmitLocalProcessor.class, MockAemProxy.class,
+ classes = {TestApplication.class, AfSubmitLocalProcessor.class, MockAemProxy.class,
AemProxyAfSubmissionTestWithLocalAfSubmitProcessorTest.MockSubmissionProcessor.class,
AemProxyAfSubmissionTestWithLocalAfSubmitProcessorTest.MockSubmissionProcessor2.class}
,properties={
@@ -204,11 +253,13 @@ public static class AemProxyAfSubmissionTestWithLocalAfSubmitProcessorTest {
@LocalServerPort
private int port;
- private JakartaRestClient jrc;
+// private JakartaRestClient jrc;
+ private RestClient restClient;
@BeforeEach
public void setUp() throws Exception {
- jrc = setUpRestClient(port);
+// jrc = setUpRestClient(port);
+ restClient = createRestClient(port);
}
@@ -216,52 +267,86 @@ public void setUp() throws Exception {
void testResponse() {
final FormDataMultiPart getPdfForm = mockFormData("foo1", "bar");
- Response response = jrc.target
- .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
- .request()
- .accept(MediaType.TEXT_PLAIN_TYPE)
- .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
-
- assertThat(response, allOf(isStatus(Response.Status.OK),hasEntityMatching(equalTo(AF_SUBMIT_LOCAL_PROCESSOR_RESPONSE.getBytes()))));
+ ResponseEntity response = restClient.post()
+ .uri(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+ .contentType(MediaType.MULTIPART_FORM_DATA)
+ .body(getPdfForm.parts())
+ .accept(MediaType.TEXT_PLAIN)
+ .retrieve()
+ .toEntity(byte[].class)
+ ;
+
+// Response response = jrc.target
+// .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+// .request()
+// .accept(MediaType.TEXT_PLAIN_TYPE)
+// .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
+
+ assertThat(response, allOf(hasStatus(HttpStatus.OK),hasEntityMatching(equalTo(AF_SUBMIT_LOCAL_PROCESSOR_RESPONSE.getBytes()))));
}
@Test
void testRedirect() {
final FormDataMultiPart getPdfForm = mockFormData("foo2", "bar");
- Response response = jrc.target
- .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
- .request()
- .accept(MediaType.TEXT_PLAIN_TYPE)
- .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
-
- assertThat(response, allOf(isStatus(Response.Status.TEMPORARY_REDIRECT), doesNotHaveEntity()));
+ ResponseEntity response = restClient.post()
+ .uri(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+ .contentType(MediaType.MULTIPART_FORM_DATA)
+ .body(getPdfForm.parts())
+ .accept(MediaType.TEXT_PLAIN)
+ .retrieve()
+ .toBodilessEntity()
+ ;
+// Response response = jrc.target
+// .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+// .request()
+// .accept(MediaType.TEXT_PLAIN_TYPE)
+// .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
+
+ assertThat(response, allOf(hasStatus(HttpStatus.TEMPORARY_REDIRECT), doesNotHaveEntity()));
}
@Test
void testSeeOther() {
final FormDataMultiPart getPdfForm = mockFormData("foo3", "bar");
- Response response = jrc.target
- .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
- .request()
- .accept(MediaType.TEXT_PLAIN_TYPE)
- .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
-
- assertThat(response, allOf(isStatus(Response.Status.SEE_OTHER), doesNotHaveEntity()));
+ ResponseEntity response = restClient.post()
+ .uri(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+// .contentType(MediaType.MULTIPART_FORM_DATA)
+ .body(getPdfForm.parts())
+ .accept(MediaType.TEXT_PLAIN)
+ .retrieve()
+ .toBodilessEntity()
+ ;
+// Response response = jrc.target
+// .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+// .request()
+// .accept(MediaType.TEXT_PLAIN_TYPE)
+// .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
+
+ assertThat(response, allOf(hasStatus(HttpStatus.SEE_OTHER), doesNotHaveEntity()));
}
@Test
void testProxy() {
final FormDataMultiPart getPdfForm = mockFormData("foo2", "bar");
- Response response = jrc.target
- .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH+"anythingElse")
- .request()
- .accept(MediaType.TEXT_PLAIN_TYPE)
- .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
-
- assertThat(response, allOf(isStatus(Response.Status.OK), doesNotHaveEntity()));
+ ResponseEntity response = restClient.post()
+ .uri(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH+"anythingElse")
+ .contentType(MediaType.MULTIPART_FORM_DATA)
+ .body(getPdfForm.parts())
+ .accept(MediaType.TEXT_PLAIN)
+ .retrieve()
+ .toBodilessEntity()
+ ;
+
+// Response response = jrc.target
+// .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH+"anythingElse")
+// .request()
+// .accept(MediaType.TEXT_PLAIN_TYPE)
+// .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
+
+ assertThat(response, allOf(hasStatus(HttpStatus.OK), doesNotHaveEntity()));
}
@Component
@@ -283,8 +368,8 @@ public SubmitResponse processSubmission(Submission submission) {
()->assertEquals(AF_TEMPLATE_NAME, submission.formName()),
()->assertEquals("bar", submission.formData()),
()->assertThat(submission.redirectUrl(), anyOf(equalTo("foo1"), equalTo("foo2"), equalTo("foo3"))),
- ()->assertEquals(MediaType.TEXT_PLAIN, submission.headers().getFirst("accept")),
- ()->assertTrue(MediaType.MULTIPART_FORM_DATA_TYPE.isCompatible(MediaType.valueOf(submission.headers().getFirst("content-type"))))
+ ()->assertEquals(MediaType.TEXT_PLAIN_VALUE, submission.headers().getFirst("accept")),
+ ()->assertTrue(MediaType.MULTIPART_FORM_DATA.isCompatibleWith(MediaType.valueOf(submission.headers().getFirst("content-type"))))
);
try {
String redirectUrl = submission.redirectUrl();
@@ -321,7 +406,7 @@ public static class MockAemProxy {
@Bean()
public InternalAfSubmitAemProxyProcessor aemProxyProcessor() {
AfSubmitAemProxyProcessor mock = Mockito.mock(AfSubmitAemProxyProcessor.class);
- Mockito.when(mock.processRequest(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(Response.ok().build());
+ Mockito.when(mock.processRequest(Mockito.any(), Mockito.any())).thenReturn(ResponseEntity.ok().build());
return ()->mock;
}
}
@@ -332,40 +417,55 @@ public InternalAfSubmitAemProxyProcessor aemProxyProcessor() {
*
*/
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
- classes = {TestApplication.class, JerseyConfig.class, AemProxyAfSubmissionTestWithCustomAfSubmitProcessorTest.MockSubmitProcessor.class}
-// ,properties="debug"
+ classes = {TestApplication.class, AemProxyAfSubmissionTestWithCustomAfSubmitProcessorTest.MockSubmitProcessor.class}
+// ,properties= {
+// "debug"
+// ,"logging.level.com._4point.aem.fluentforms.spring=DEBUG"
+// ,"logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping=TRACE"
+// }
)
public static class AemProxyAfSubmissionTestWithCustomAfSubmitProcessorTest {
@LocalServerPort
private int port;
- private JakartaRestClient jrc;
+// private JakartaRestClient jrc;
+ private RestClient restClient;
@BeforeEach
public void setUp() throws Exception {
- jrc = setUpRestClient(port);
+// jrc = setUpRestClient(port);
+ restClient = createRestClient(port);
}
@Test
void test() {
final FormDataMultiPart getPdfForm = mockFormData("foo", "bar");
- Response response = jrc.target
- .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
- .request()
- .accept(APPLICATION_PDF)
- .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
-
- assertThat(response, allOf(isStatus(Response.Status.OK), hasEntityMatching(equalTo(SAMPLE_RESPONSE_BODY.getBytes()))));
+ MultiValueMap> parts = getPdfForm.parts();
+ ResponseEntity response = restClient.post()
+ .uri(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+// .contentType(MediaType.MULTIPART_FORM_DATA)
+ .body(parts)
+ .accept(MediaType.APPLICATION_PDF)
+ .retrieve()
+ .toEntity(byte[].class)
+ ;
+// Response response = jrc.target
+// .path(SUBMIT_ADAPTIVE_FORM_SERVICE_PATH)
+// .request()
+// .accept(APPLICATION_PDF)
+// .post(Entity.entity(getPdfForm, getPdfForm.getMediaType()));
+
+ assertThat(response, allOf(hasStatus(HttpStatus.OK), hasEntityMatching(equalTo(SAMPLE_RESPONSE_BODY.getBytes()))));
}
@Component
- public static class MockSubmitProcessor implements AfSubmitProcessor {
+ public static class MockSubmitProcessor implements SpringAfSubmitProcessor {
@Override
- public Response processRequest(FormDataMultiPart inFormData, HttpHeaders headers, String remainder) {
- return Response.ok().entity(SAMPLE_RESPONSE_BODY).build();
+ public ResponseEntity processRequest(MultipartHttpServletRequest inFormData, String remainder) {
+ return ResponseEntity.ok().body(SAMPLE_RESPONSE_BODY.getBytes());
}
}
}
@@ -477,4 +577,66 @@ void testcanHandleFormNameMatchesRegEx(String formNameIn, boolean expectedResult
assertEquals(expectedResult, underTest.canHandle(formNameIn));
}
}
+
+ private static Matcher isStatus(HttpStatusCode statusCode) {
+ return new TypeSafeDiagnosingMatcher() {
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("HttpStatus with value " + statusCode.value());
+ }
+
+ @Override
+ protected boolean matchesSafely(HttpStatusCode item, Description mismatchDescription) {
+ if (statusCode.isSameCodeAs(item)) {
+ return true;
+ } else {
+ mismatchDescription.appendText("was HttpStatus with value " + item.value());
+ return false;
+ }
+ }
+ };
+ }
+
+ private static Matcher> doesNotHaveEntity() {
+ return new TypeSafeDiagnosingMatcher>() {
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("ResponseEntity with no body");
+ }
+
+ @Override
+ protected boolean matchesSafely(ResponseEntity> item, Description mismatchDescription) {
+ if (item.hasBody() == false) {
+ return true;
+ } else {
+ mismatchDescription.appendText("was ResponseEntity with body of size " + ((byte[])item.getBody()).length);
+ return false;
+ }
+ }
+
+ };
+ }
+
+
+ private static Matcher> hasStatus(HttpStatusCode status) {
+ return new FeatureMatcher, HttpStatusCode>(isStatus(status), "ResponseEntity with status", "status") {
+
+ @Override
+ protected HttpStatusCode featureValueOf(ResponseEntity> actual) {
+ return actual.getStatusCode();
+ }
+ };
+ }
+
+ private static Matcher> hasEntityMatching(Matcher super byte[]> matcher) {
+ return new FeatureMatcher, byte[]>(matcher, "ResponseEntity with entity matching", "entity") {
+
+ @Override
+ protected byte[] featureValueOf(ResponseEntity> actual) {
+ return (byte[]) actual.getBody();
+ }
+ };
+ }
}
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyAutoConfigurationTest.java b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyAutoConfigurationTest.java
index ec190091..7cafea43 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyAutoConfigurationTest.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AemProxyAutoConfigurationTest.java
@@ -6,7 +6,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
@@ -19,10 +18,11 @@
})
class AemProxyAutoConfigurationTest {
- @Test
- void testDocumentFactory(@Autowired ResourceConfigCustomizer afProxyConfigurer) {
- assertNotNull(afProxyConfigurer);
- }
+ // TODO: Maybe add more tests here later.
+// @Test
+// void testDocumentFactory(@Autowired ResourceConfigCustomizer afProxyConfigurer) {
+// assertNotNull(afProxyConfigurer);
+// }
@SpringBootApplication
@EnableConfigurationProperties({AemConfiguration.class,AemProxyConfiguration.class})
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AutoConfigurationTest.java b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AutoConfigurationTest.java
index 42ec67dd..1d1bf50e 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AutoConfigurationTest.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/AutoConfigurationTest.java
@@ -4,32 +4,47 @@
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.autoconfigure.web.client.RestClientSsl;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
-import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.client.RestClient;
import com._4point.aem.fluentforms.api.output.OutputService;
import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitAemProxyProcessor;
-import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitLocalProcessor;
import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmissionHandler;
-import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmitLocalProcessor;
+import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.SpringAfSubmitProcessor;
/**
- * Test that AutoCOnfiguration happens. The code in this test class is based on the following docs:
+ * Test that AutoConfiguration happens. The code in this test class is based on the following docs:
*
* https://spring.io/blog/2018/03/07/testing-auto-configurations-with-spring-boot-2-0
*
*/
class AutoConfigurationTest {
- private static final AutoConfigurations AUTO_CONFIG = AutoConfigurations.of(FluentFormsAutoConfiguration.class, AemProxyAutoConfiguration.class);
+ /**
+ * This class provides mock versions of beans that would normally be provided by Spring Boot in a real application. We
+ * only need to mock out the RestClient.Builder and RestClientSsl beans because those are the only Spring Boot provided
+ * beans that our AutoConfigurations depend on.
+ */
+ private static class SpringBootMocks {
+ @Bean RestClient.Builder mockRestClientBuilder() { return Mockito.mock(RestClient.Builder.class, Mockito.RETURNS_DEEP_STUBS); }
+ @Bean private RestClientSsl mockRestClientSsl() { return Mockito.mock(RestClientSsl.class); }
+ }
+
+ private static final AutoConfigurations AUTO_CONFIG = AutoConfigurations.of(FluentFormsAutoConfiguration.class, AemProxyAutoConfiguration.class, SpringBootMocks.class);
- private static final AutoConfigurations LOCAL_SUBMIT_CONFIG = AutoConfigurations.of(FluentFormsAutoConfiguration.class, AemProxyAutoConfiguration.class, DummyLocalSubmitHandler.class);
+ private static final AutoConfigurations LOCAL_SUBMIT_CONFIG = AutoConfigurations.of(FluentFormsAutoConfiguration.class, AemProxyAutoConfiguration.class, DummyLocalSubmitHandler.class, SpringBootMocks.class);
+ private static final AutoConfigurations ALTERNATE_PROXY_CONFIG = AutoConfigurations.of(DummyProxyImplementation.class, FluentFormsAutoConfiguration.class, AemProxyAutoConfiguration.class, SpringBootMocks.class);
+
// Tests to make sure that only the FluentFormsLibraries are loaded in a non-web application.
private static final ContextConsumer super AssertableApplicationContext> FF_LIBRARIES_ONLY = (context) -> {
assertAll(
@@ -38,8 +53,7 @@ class AutoConfigurationTest {
()->assertThat(context).hasSingleBean(OutputService.class),
()->assertThat(context).getBean("outputService").isNotNull(),
()->assertThat(context).doesNotHaveBean(AemProxyAutoConfiguration.class),
- ()->assertThat(context).doesNotHaveBean(ResourceConfigCustomizer.class),
- ()->assertThat(context).doesNotHaveBean(AfSubmitProcessor.class),
+ ()->assertThat(context).doesNotHaveBean(SpringAfSubmitProcessor.class),
()->assertThat(context).doesNotHaveBean(AfSubmissionHandler.class)
);
};
@@ -52,8 +66,7 @@ class AutoConfigurationTest {
()->assertThat(context).hasSingleBean(OutputService.class),
()->assertThat(context).getBean("outputService").isNotNull(),
()->assertThat(context).doesNotHaveBean(AemProxyAutoConfiguration.class),
- ()->assertThat(context).doesNotHaveBean(ResourceConfigCustomizer.class),
- ()->assertThat(context).doesNotHaveBean(AfSubmitProcessor.class),
+ ()->assertThat(context).doesNotHaveBean(SpringAfSubmitProcessor.class),
()->assertThat(context).doesNotHaveBean(AfSubmissionHandler.class)
);
};
@@ -67,10 +80,8 @@ class AutoConfigurationTest {
()->assertThat(context).getBean("outputService").isNotNull(),
()->assertThat(context).hasSingleBean(AemProxyAutoConfiguration.class),
()->assertThat(context).getBean(AemProxyAutoConfiguration.class.getName()).isSameAs(context.getBean(AemProxyAutoConfiguration.class)),
- ()->assertThat(context).hasSingleBean(ResourceConfigCustomizer.class),
- ()->assertThat(context).getBean("afProxyConfigurer").isNotNull(),
- ()->assertThat(context).hasSingleBean(AfSubmitProcessor.class),
- ()->assertThat(context).getBean(AfSubmitProcessor.class).isSameAs(context.getBean(AfSubmitAemProxyProcessor.class)),
+ ()->assertThat(context).hasSingleBean(SpringAfSubmitProcessor.class),
+ ()->assertThat(context).getBean(SpringAfSubmitProcessor.class).isSameAs(context.getBean(AfSubmitAemProxyProcessor.class)),
()->assertThat(context).doesNotHaveBean(AfSubmissionHandler.class)
);
};
@@ -84,10 +95,8 @@ class AutoConfigurationTest {
()->assertThat(context).getBean("outputService").isNotNull(),
()->assertThat(context).hasSingleBean(AemProxyAutoConfiguration.class),
()->assertThat(context).getBean(AemProxyAutoConfiguration.class.getName()).isSameAs(context.getBean(AemProxyAutoConfiguration.class)),
- ()->assertThat(context).hasSingleBean(ResourceConfigCustomizer.class),
- ()->assertThat(context).getBean("afProxyConfigurer").isNotNull(),
- ()->assertThat(context).hasSingleBean(AfSubmitProcessor.class),
- ()->assertThat(context).getBean(AfSubmitProcessor.class).isSameAs(context.getBean(AfSubmitLocalProcessor.class)),
+ ()->assertThat(context).hasSingleBean(SpringAfSubmitProcessor.class),
+ ()->assertThat(context).getBean(SpringAfSubmitProcessor.class).isSameAs(context.getBean(AfSubmitLocalProcessor.class)),
()->assertThat(context).hasSingleBean(AfSubmissionHandler.class)
);
};
@@ -101,6 +110,9 @@ class AutoConfigurationTest {
private final WebApplicationContextRunner webLocalSubmitContextRunner = new WebApplicationContextRunner()
.withConfiguration(LOCAL_SUBMIT_CONFIG);
+ private final WebApplicationContextRunner webAlternateProxyContextRunner = new WebApplicationContextRunner()
+ .withConfiguration(ALTERNATE_PROXY_CONFIG);
+
// Only the services that do not require a web server should be started.
@Test
void nonWebContext_StartNonWebServices() {
@@ -158,6 +170,35 @@ void webContext_StartAllServices_LocalSubmit() {
.run(WEB_LOCAL_SUBMIT_SERVICES);
}
+ // Only the FluentForms libraries are instantiated by this autoconfiguration when an alternate proxy implementation is supplied.
+ @Test
+ void webContext_StartAllServices_AlternateProxySupplied() {
+ this.webAlternateProxyContextRunner
+ .withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=user", "fluentforms.aem.password=password")
+ .run(WEB_FF_LIBRARIES_ONLY);
+ }
+
+ // Only the FluentForms libraries are instantiated when an alternate proxy tyoe is configured.
+ @Test
+ void webContext_ProxyDisabled_AlternateProxyConfigured() {
+ this.webContextRunner
+ .withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=user", "fluentforms.aem.password=password",
+ "fluentforms.rproxy.type=someothertype")
+ .run(WEB_FF_LIBRARIES_ONLY);
+ }
+
+ // All services should start when the default proxy type is configured.
+ @Test
+ void webContext_ProxyEnabled_DefaultProxyConfigured() {
+ this.webContextRunner
+ .withPropertyValues("fluentforms.aem.servername=localhost", "fluentforms.aem.port=4502",
+ "fluentforms.aem.user=user", "fluentforms.aem.password=password",
+ "fluentforms.rproxy.type=springmvc")
+ .run(WEB_ALL_DEFAULT_SERVICES);
+ }
+
public static class DummyLocalSubmitHandler implements AfSubmissionHandler {
@@ -171,4 +212,8 @@ public SubmitResponse processSubmission(Submission submission) {
return null;
}
}
+
+ public static class DummyProxyImplementation implements AemProxyImplemention {
+
+ }
}
diff --git a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/FluentFormsAutoConfigurationTest.java b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/FluentFormsAutoConfigurationTest.java
index 40f981a2..56309a3e 100644
--- a/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/FluentFormsAutoConfigurationTest.java
+++ b/spring/fluentforms-spring-boot-autoconfigure/src/test/java/com/_4point/aem/fluentforms/spring/FluentFormsAutoConfigurationTest.java
@@ -23,7 +23,6 @@
import com._4point.aem.docservices.rest_services.client.helpers.AemConfig;
import com._4point.aem.docservices.rest_services.client.helpers.Builder.RestClientFactory;
import com._4point.aem.docservices.rest_services.client.html5.Html5FormsService;
-import com._4point.aem.docservices.rest_services.client.jersey.JerseyRestClient;
import com._4point.aem.fluentforms.api.DocumentFactory;
import com._4point.aem.fluentforms.api.assembler.AssemblerService;
import com._4point.aem.fluentforms.api.convertPdf.ConvertPdfService;
@@ -97,7 +96,7 @@ void testDocumentFactory(@Autowired DocumentFactory factory) {
@Test
void testRestClientFactory(@Autowired RestClientFactory factory, @Autowired AemConfiguration config) {
RestClient client = factory.apply(toAemConfig(config) , "testRestClientFactory", ()->"correlationId");
- assertTrue(client instanceof JerseyRestClient, "RestClientFactory should return a JerseyRestClient by default");
+ assertTrue(client instanceof SpringRestClientRestClient, "RestClientFactory should return a SpringRestClientRestClient by default");
}
@Test
@@ -193,23 +192,24 @@ void testRestClientFactory(@Autowired RestClientFactory factory, @Autowired AemC
}
}
- @SpringBootTest(classes = {com._4point.aem.fluentforms.spring.FluentFormsAutoConfigurationTest.TestApplication.class, FluentFormsAutoConfiguration.class},
- properties = {
- "fluentforms.aem.servername=localhost",
- "fluentforms.aem.port=4502",
- "fluentforms.aem.user=admin",
- "fluentforms.aem.password=admin",
- "fluentforms.aem.usessl=true",
- "fluentforms.restclient=jersey" // Configure for Jersey RestClient
- })
- public static class JserseyRestClient_SslNoBundleNameTest {
-
- @Test
- void testRestClientFactory(@Autowired RestClientFactory factory, @Autowired AemConfiguration config) {
- RestClient client = factory.apply(toAemConfig(config) , "testRestClientFactory", ()->"correlationId");
- assertTrue(client instanceof JerseyRestClient, "RestClientFactory should return a JerseyRestClient when configured to do so");
- }
- }
+// @Disabled("Needs to be moved to the Jersey Rest Client module")
+// @SpringBootTest(classes = {com._4point.aem.fluentforms.spring.FluentFormsAutoConfigurationTest.TestApplication.class, FluentFormsAutoConfiguration.class},
+// properties = {
+// "fluentforms.aem.servername=localhost",
+// "fluentforms.aem.port=4502",
+// "fluentforms.aem.user=admin",
+// "fluentforms.aem.password=admin",
+// "fluentforms.aem.usessl=true",
+// "fluentforms.restclient=jersey" // Configure for Jersey RestClient
+// })
+// public static class JserseyRestClient_SslNoBundleNameTest {
+//
+// @Test
+// void testRestClientFactory(@Autowired RestClientFactory factory, @Autowired AemConfiguration config) {
+// RestClient client = factory.apply(toAemConfig(config) , "testRestClientFactory", ()->"correlationId");
+// assertTrue(client instanceof JerseyRestClient, "RestClientFactory should return a JerseyRestClient when configured to do so");
+// }
+// }
@SpringBootTest(classes = {com._4point.aem.fluentforms.spring.FluentFormsAutoConfigurationTest.TestApplication.class, FluentFormsAutoConfiguration.class},
properties = {
@@ -232,26 +232,28 @@ void testRestClientFactory(@Autowired RestClientFactory factory, @Autowired AemC
}
}
- @SpringBootTest(classes = {com._4point.aem.fluentforms.spring.FluentFormsAutoConfigurationTest.TestApplication.class, FluentFormsAutoConfiguration.class},
- properties = {
- "fluentforms.aem.servername=localhost",
- "fluentforms.aem.port=4502",
- "fluentforms.aem.user=admin",
- "fluentforms.aem.password=admin",
- "fluentforms.aem.usessl=true",
- "spring.ssl.bundle.jks.aem.truststore.location=file:src/test/resources/aemforms.p12",
- "spring.ssl.bundle.jks.aem.truststore.password=Pa$$123",
- "spring.ssl.bundle.jks.aem.truststore.type=PKCS12",
- "fluentforms.restclient=jersey" // Configure for Jersey RestClient
- })
- public static class JserseyRestClient_SslBundleTest {
-
- @Test
- void testRestClientFactory(@Autowired RestClientFactory factory, @Autowired AemConfiguration config) {
- RestClient client = factory.apply(toAemConfig(config) , "testRestClientFactory", ()->"correlationId");
- assertTrue(client instanceof JerseyRestClient, "RestClientFactory should return a JerseyRestClient when configured to do so");
- }
- }
+// @Disabled("This test needs to be moved to the Jersey autoconfiguration project when it is created.")
+// @SpringBootTest(classes = {com._4point.aem.fluentforms.spring.FluentFormsAutoConfigurationTest.TestApplication.class, FluentFormsAutoConfiguration.class},
+// properties = {
+// "fluentforms.aem.servername=localhost",
+// "fluentforms.aem.port=4502",
+// "fluentforms.aem.user=admin",
+// "fluentforms.aem.password=admin",
+// "fluentforms.aem.usessl=true",
+// "spring.ssl.bundle.jks.aem.truststore.location=file:src/test/resources/aemforms.p12",
+// "spring.ssl.bundle.jks.aem.truststore.password=Pa$$123",
+// "spring.ssl.bundle.jks.aem.truststore.type=PKCS12",
+// "fluentforms.restclient=jersey" // Configure for Jersey RestClient
+// })
+// public static class JserseyRestClient_SslBundleTest {
+//
+// @Test
+// void testRestClientFactory(@Autowired RestClientFactory factory, @Autowired AemConfiguration config) {
+// RestClient client = factory.apply(toAemConfig(config) , "testRestClientFactory", ()->"correlationId");
+// assertTrue(client instanceof JerseyRestClient, "RestClientFactory should return a JerseyRestClient when configured to do so");
+// }
+// }
+
private static AemConfig toAemConfig(AemConfiguration config) {
return new AemConfig() {
diff --git a/spring/fluentforms-spring-boot-starter/pom.xml b/spring/fluentforms-spring-boot-starter/pom.xml
index fa2086be..f91e248f 100644
--- a/spring/fluentforms-spring-boot-starter/pom.xml
+++ b/spring/fluentforms-spring-boot-starter/pom.xml
@@ -6,7 +6,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.5.5
+ 3.5.7
fluentforms-spring-boot-starter
diff --git a/spring/pom.xml b/spring/pom.xml
new file mode 100644
index 00000000..01466dc9
--- /dev/null
+++ b/spring/pom.xml
@@ -0,0 +1,41 @@
+
+ 4.0.0
+ com._4point.aem.fluentforms
+ spring-starters
+ pom
+ 0.0.4-SNAPSHOT
+ Fluent Forms Spring Boot Starter Projects
+
+
+
+ fluentforms-spring-boot-autoconfigure
+ fluentforms-spring-boot-starter
+ fluentforms-sample-webmvc-app
+ fluentforms-sample-cli-app
+
+ fluentforms-jersey-spring-boot-autoconfigure
+ fluentforms-jersey-spring-boot-starter
+ fluentforms-sample-web-jersey-app
+
+
+
+
+
+
+ maven-install-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+
+ true
+
+
+
+
+
\ No newline at end of file