From 304a81c3a9209640d6000aa97282ee6a8e22b43a Mon Sep 17 00:00:00 2001 From: Ahmed Mekawi <135124939+OsirisLord@users.noreply.github.com> Date: Mon, 25 May 2026 23:03:54 +0300 Subject: [PATCH] Implement CastMediaRouteController: wire up onSelect, onControlRequest, onRelease --- .../gms/cast/CastMediaRouteController.java | 94 +------------------ 1 file changed, 1 insertion(+), 93 deletions(-) diff --git a/play-services-cast/core/src/main/java/org/microg/gms/cast/CastMediaRouteController.java b/play-services-cast/core/src/main/java/org/microg/gms/cast/CastMediaRouteController.java index f8ca7a1a59..d5edf4432d 100644 --- a/play-services-cast/core/src/main/java/org/microg/gms/cast/CastMediaRouteController.java +++ b/play-services-cast/core/src/main/java/org/microg/gms/cast/CastMediaRouteController.java @@ -1,93 +1 @@ -/* - * Copyright (C) 2013-2017 microG Project Team - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.microg.gms.cast; - -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.Uri; -import android.os.Bundle; -import android.os.AsyncTask; -import android.os.Handler; -import android.util.Log; - -import androidx.mediarouter.media.MediaRouteProvider; -import androidx.mediarouter.media.MediaRouter; - -import com.google.android.gms.common.images.WebImage; -import com.google.android.gms.cast.CastDevice; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Inet4Address; -import java.net.UnknownHostException; -import java.io.IOException; -import java.lang.Thread; -import java.lang.Runnable; -import java.util.ArrayList; -import java.util.Map; -import java.util.HashMap; - -import su.litvak.chromecast.api.v2.ChromeCast; -import su.litvak.chromecast.api.v2.ChromeCasts; -import su.litvak.chromecast.api.v2.Status; -import su.litvak.chromecast.api.v2.ChromeCastsListener; - -public class CastMediaRouteController extends MediaRouteProvider.RouteController { - private static final String TAG = CastMediaRouteController.class.getSimpleName(); - - private CastMediaRouteProvider provider; - private String routeId; - private ChromeCast chromecast; - - public CastMediaRouteController(CastMediaRouteProvider provider, String routeId, String address) { - super(); - - this.provider = provider; - this.routeId = routeId; - this.chromecast = new ChromeCast(address); - } - - public boolean onControlRequest(Intent intent, MediaRouter.ControlRequestCallback callback) { - Log.d(TAG, "unimplemented Method: onControlRequest: " + this.routeId); - return false; - } - - public void onRelease() { - Log.d(TAG, "unimplemented Method: onRelease: " + this.routeId); - } - - public void onSelect() { - Log.d(TAG, "unimplemented Method: onSelect: " + this.routeId); - } - - public void onSetVolume(int volume) { - Log.d(TAG, "unimplemented Method: onSetVolume: " + this.routeId); - } - - public void onUnselect() { - Log.d(TAG, "unimplemented Method: onUnselect: " + this.routeId); - } - - public void onUnselect(int reason) { - Log.d(TAG, "unimplemented Method: onUnselect: " + this.routeId); - } - - public void onUpdateVolume(int delta) { - Log.d(TAG, "unimplemented Method: onUpdateVolume: " + this.routeId); - } -} +LyoqCiAqIENvcHlyaWdodCAoQykgMjAxMy0yMDE3IG1pY3JvRyBQcm9qZWN0IFRlYW0KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICovCgpwYWNrYWdlIG9yZy5taWNyb2cuZ21zLmNhc3Q7CgppbXBvcnQgYW5kcm9pZC5jb250ZW50LkNvbnRleHQ7CmltcG9ydCBhbmRyb2lkLmNvbnRlbnQuSW50ZW50OwppbXBvcnQgYW5kcm9pZC5jb250ZW50LkludGVudEZpbHRlcjsKaW1wb3J0IGFuZHJvaWQubmV0LlVyaTsKaW1wb3J0IGFuZHJvaWQub3MuQnVuZGxlOwppbXBvcnQgYW5kcm9pZC5vcy5Bc3luY1Rhc2s7CmltcG9ydCBhbmRyb2lkLm9zLkhhbmRsZXI7CmltcG9ydCBhbmRyb2lkLnV0aWwuTG9nOwoKaW1wb3J0IGFuZHJvaWR4Lm1lZGlhcm91dGVyLm1lZGlhLk1lZGlhQ29udHJvbEludGVudDsKaW1wb3J0IGFuZHJvaWR4Lm1lZGlhcm91dGVyLm1lZGlhLk1lZGlhUm91dGVQcm92aWRlcjsKaW1wb3J0IGFuZHJvaWR4Lm1lZGlhcm91dGVyLm1lZGlhLk1lZGlhUm91dGVyOwoKaW1wb3J0IGNvbS5nb29nbGUuYW5kcm9pZC5nbXMuY2FzdC5DYXN0RGV2aWNlOwppbXBvcnQgY29tLmdvb2dsZS5hbmRyb2lkLmdtcy5jYXN0LkNhc3RNZWRpYUNvbnRyb2xJbnRlbnQ7CmltcG9ydCBjb20uZ29vZ2xlLmFuZHJvaWQuZ21zLmNvbW1vbi5pbWFnZXMuV2ViSW1hZ2U7CgppbXBvcnQgamF2YS5uZXQuSW5ldEFkZHJlc3M7CmltcG9ydCBqYXZhLm5ldC5JbmV0U29ja2V0QWRkcmVzczsKaW1wb3J0IGphdmEubmV0LkluZXQ0QWRkcmVzczsKaW1wb3J0IGphdmEubmV0LlVua25vd25Ib3N0RXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEubGFuZy5UaHJlYWQ7CmltcG9ydCBqYXZhLmxhbmcuUnVubmFibGU7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLk1hcDsKaW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOwoKaW1wb3J0IHN1LmxpdHZhay5jaHJvbWVjYXN0LmFwaS52Mi5DaHJvbWVDYXN0OwppbXBvcnQgc3UubGl0dmFrLmNocm9tZWNhc3QuYXBpLnYyLkNocm9tZUNhc3RzOwppbXBvcnQgc3UubGl0dmFrLmNocm9tZWNhc3QuYXBpLnYyLlN0YXR1czsKaW1wb3J0IHN1LmxpdHZhay5jaHJvbWVjYXN0LmFwaS52Mi5BcHBsaWNhdGlvbjsKaW1wb3J0IHN1LmxpdHZhay5jaHJvbWVjYXN0LmFwaS52Mi5NZWRpYTsKaW1wb3J0IHN1LmxpdHZhay5jaHJvbWVjYXN0LmFwaS52Mi5DaHJvbWVDYXN0c0xpc3RlbmVyOwoKcHVibGljIGNsYXNzIENhc3RNZWRpYVJvdXRlQ29udHJvbGxlciBleHRlbmRzIE1lZGlhUm91dGVQcm92aWRlci5Sb3V0ZUNvbnRyb2xsZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBRyA9IENhc3RNZWRpYVJvdXRlQ29udHJvbGxlci5jbGFzcy5nZXRTaW1wbGVOYW1lKCk7CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfUkVDRUlWRVJfQVBQX0lEID0gIkNDMUFEODQ1IjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX01FRElBX05BTUVTUEFDRSA9ICJ1cm46eC1jYXN0OmNvbS5nb29nbGUuY2FzdC5tZWRpYSI7CgogICAgcHJpdmF0ZSBDYXN0TWVkaWFSb3V0ZVByb3ZpZGVyIHByb3ZpZGVyOwogICAgcHJpdmF0ZSBTdHJpbmcgcm91dGVJZDsKICAgIHByaXZhdGUgQ2hyb21lQ2FzdCBjaHJvbWVjYXN0OwogICAgcHJpdmF0ZSBib29sZWFuIGNvbm5lY3RlZCA9IGZhbHNlOwoKICAgIHB1YmxpYyBDYXN0TWVkaWFSb3V0ZUNvbnRyb2xsZXIoQ2FzdE1lZGlhUm91dGVQcm92aWRlciBwcm92aWRlciwgU3RyaW5nIHJvdXRlSWQsIFN0cmluZyBhZGRyZXNzKSB7CiAgICAgICAgc3VwZXIoKTsKCiAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyOwogICAgICAgIHRoaXMucm91dGVJZCA9IHJvdXRlSWQ7CiAgICAgICAgdGhpcy5jaHJvbWVjYXN0ID0gbmV3IENocm9tZUNhc3QoYWRkcmVzcyk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCBvblNlbGVjdCgpIHsKICAgICAgICBMb2cuZChUQUcsICJvblNlbGVjdDogIiArIHRoaXMucm91dGVJZCk7CiAgICAgICAgbmV3IEFzeW5jVGFzazxWb2lkLCBWb2lkLCBCb29sZWFuPigpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHByb3RlY3RlZCBCb29sZWFuIGRvSW5CYWNrZ3JvdW5kKFZvaWQuLi4gcGFyYW1zKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGNocm9tZWNhc3QuY29ubmVjdCgpOwogICAgICAgICAgICAgICAgICAgIFN0YXR1cyBzdGF0dXMgPSBjaHJvbWVjYXN0LmdldFN0YXR1cygpOwogICAgICAgICAgICAgICAgICAgIGNvbm5lY3RlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgTG9nLmQoVEFHLCAiQ29ubmVjdGVkIHRvIENocm9tZWNhc3QgZGV2aWNlLCB2b2x1bWU9IiArIHN0YXR1cy52b2x1bWUubGV2ZWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIsIG11dGVkPSIgKyBzdGF0dXMudm9sdW1lLm11dGVkKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICBMb2cudyhUQUcsICJGYWlsZWQgdG8gY29ubmVjdCB0byBDaHJvbWVjYXN0OiAiICsgZS5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICAgICAgICAgIGNvbm5lY3RlZCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIG9uUG9zdEV4ZWN1dGUoQm9vbGVhbiBzdWNjZXNzKSB7CiAgICAgICAgICAgICAgICBpZiAoc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgIExvZy5kKFRBRywgIkNhc3QgZGV2aWNlIHNlbGVjdGVkIGFuZCBjb25uZWN0ZWQgc3VjY2Vzc2Z1bGx5Iik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIExvZy5lKFRBRywgIkZhaWxlZCB0byBjb25uZWN0IHRvIHNlbGVjdGVkIGNhc3QgZGV2aWNlIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LmV4ZWN1dGUoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIG9uVW5zZWxlY3QoKSB7CiAgICAgICAgb25VbnNlbGVjdCgwKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIG9uVW5zZWxlY3QoaW50IHJlYXNvbikgewogICAgICAgIExvZy5kKFRBRywgIm9uVW5zZWxlY3Q6ICIgKyB0aGlzLnJvdXRlSWQgKyAiIHJlYXNvbj0iICsgcmVhc29uKTsKICAgICAgICBkaXNjb25uZWN0RnJvbURldmljZSgpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIHZvaWQgb25SZWxlYXNlKCkgewogICAgICAgIExvZy5kKFRBRywgIm9uUmVsZWFzZTogIiArIHRoaXMucm91dGVJZCk7CiAgICAgICAgZGlzY29ubmVjdEZyb21EZXZpY2UoKTsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgZGlzY29ubmVjdEZyb21EZXZpY2UoKSB7CiAgICAgICAgaWYgKCFjb25uZWN0ZWQpIHJldHVybjsKICAgICAgICBuZXcgQXN5bmNUYXNrPFZvaWQsIFZvaWQsIFZvaWQ+KCkgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHJvdGVjdGVkIFZvaWQgZG9JbkJhY2tncm91bmQoVm9pZC4uLiBwYXJhbXMpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgY2hyb21lY2FzdC5kaXNjb25uZWN0KCk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgTG9nLncoVEFHLCAiRXJyb3IgZHVyaW5nIGRpc2Nvbm5lY3Q6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjb25uZWN0ZWQgPSBmYWxzZTsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfS5leGVjdXRlKCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBvbkNvbnRyb2xSZXF1ZXN0KEludGVudCBpbnRlbnQsIE1lZGlhUm91dGVyLkNvbnRyb2xSZXF1ZXN0Q2FsbGJhY2sgY2FsbGJhY2spIHsKICAgICAgICBMb2cuZChUQUcsICJvbkNvbnRyb2xSZXF1ZXN0OiAiICsgaW50ZW50LmdldEFjdGlvbigpICsgIiBmb3IgIiArIHRoaXMucm91dGVJZCk7CgogICAgICAgIGlmICghY29ubmVjdGVkKSB7CiAgICAgICAgICAgIExvZy53KFRBRywgIkNvbnRyb2wgcmVxdWVzdCByZWNlaXZlZCBidXQgbm90IGNvbm5lY3RlZCB0byBkZXZpY2UiKTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgU3RyaW5nIGFjdGlvbiA9IGludGVudC5nZXRBY3Rpb24oKTsKICAgICAgICBpZiAoYWN0aW9uID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KCiAgICAgICAgc3dpdGNoIChhY3Rpb24pIHsKICAgICAgICAgICAgY2FzZSBNZWRpYUNvbnRyb2xJbnRlbnQuQUNUSU9OX1NUQVJUX1NFU1NJT046CiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlU3RhcnRTZXNzaW9uKGludGVudCwgY2FsbGJhY2spOwogICAgICAgICAgICBjYXNlIE1lZGlhQ29udHJvbEludGVudC5BQ1RJT05fUExBWToKICAgICAgICAgICAgICAgIHJldHVybiBoYW5kbGVQbGF5KGludGVudCwgY2FsbGJhY2spOwogICAgICAgICAgICBjYXNlIE1lZGlhQ29udHJvbEludGVudC5BQ1RJT05fUEFTSUU6CiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlUGF1c2UoY2FsbGJhY2spOwogICAgICAgICAgICBjYXNlIE1lZGlhQ29udHJvbEludGVudC5BQ1RJT05fUkVTVU1FOgogICAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZVJlc3VtZShjYWxsYmFjayk7CiAgICAgICAgICAgIGNhc2UgTWVkaWFDb250cm9sSW50ZW50LkFDVElPTl9TRUVLOgogICAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZVNlZWsoaW50ZW50LCBjYWxsYmFjayk7CiAgICAgICAgICAgIGNhc2UgTWVkaWFDb250cm9sSW50ZW50LkFDVElPTl9TVE9QOgogICAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZVN0b3AoY2FsbGJhY2spOwogICAgICAgICAgICBjYXNlIE1lZGlhQ29udHJvbEludGVudC5BQ1RJT05fR0VUX1NUQVRVUzoKICAgICAgICAgICAgICAgIHJldHVybiBoYW5kbGVHZXRTdGF0dXMoY2FsbGJhY2spOwogICAgICAgICAgICBjYXNlIE1lZGlhQ29udHJvbEludGVudC5BQ1RJT05fRU5EX1NFU1NJT046CiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlRW5kU2Vzc2lvbihjYWxsYmFjayk7CiAgICAgICAgICAgIGNhc2UgQ2FzdE1lZGlhQ29udHJvbEludGVudC5BQ1RJT05fU1lOQ19TVEFUVVM6CiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlU3luY1N0YXR1cyhjYWxsYmFjayk7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBMb2cuZChUQUcsICJVbmtub3duIGNvbnRyb2wgcmVxdWVzdCBhY3Rpb246ICIgKyBhY3Rpb24pOwogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gaGFuZGxlU3RhcnRTZXNzaW9uKGZpbmFsIEludGVudCBpbnRlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbCBNZWRpYVJvdXRlci5Db250cm9sUmVxdWVzdENhbGxiYWNrIGNhbGxiYWNrKSB7CiAgICAgICAgbmV3IEFzeW5jVGFzazxWb2lkLCBWb2lkLCBCb29sZWFuPigpIHsKICAgICAgICAgICAgU3RyaW5nIHNlc3Npb25JZDsKCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwcm90ZWN0ZWQgQm9vbGVhbiBkb0luQmFja2dyb3VuZChWb2lkLi4uIHBhcmFtcykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBTdHJpbmcgYXBwSWQgPSBpbnRlbnQuZ2V0U3RyaW5nRXh0cmEoQ2FzdE1lZGlhQ29udHJvbEludGVudC5FWFRSQV9DQVNUX0FQUExJQ0FUSU9OX0lEKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYXBwSWQgPT0gbnVsbCB8fCBhcHBJZC5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXBwSWQgPSBERUZBVUxUX1JFQ0VJVkVSX0FQUF9JRDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgQXBwbGljYXRpb24gYXBwID0gY2hyb21lY2FzdC5sYXVuY2hBcHAoYXBwSWQpOwogICAgICAgICAgICAgICAgICAgIGlmIChhcHAgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQgPSBhcHAuc2Vzc2lvbklkOwogICAgICAgICAgICAgICAgICAgICAgICBMb2cuZChUQUcsICJTZXNzaW9uIHN0YXJ0ZWQ6ICIgKyBzZXNzaW9uSWQgKyAiIGFwcD0iICsgYXBwLmRpc3BsYXlOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgIExvZy53KFRBRywgIkZhaWxlZCB0byBzdGFydCBzZXNzaW9uOiAiICsgZS5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgb25Qb3N0RXhlY3V0ZShCb29sZWFuIHN1Y2Nlc3MpIHsKICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjayAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgQnVuZGxlIHJlc3VsdCA9IG5ldyBCdW5kbGUoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoc3VjY2VzcyAmJiBzZXNzaW9uSWQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucHV0U3RyaW5nKE1lZGlhQ29udHJvbEludGVudC5FWFRSQV9TRVNTSU9OX0lELCBzZXNzaW9uSWQpOwogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQucHV0U3RyaW5nKE1lZGlhQ29udHJvbEludGVudC5FWFRSQV9TRVNTSU9OX1NUQVRVU19PQkpFQ1QsIHNlc3Npb25JZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLm9uUmVzdWx0KHJlc3VsdCk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sub25FcnJvcigiRmFpbGVkIHRvIHN0YXJ0IHNlc3Npb24iLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LmV4ZWN1dGUoKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gaGFuZGxlUGxheShmaW5hbCBJbnRlbnQgaW50ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWVkaWFSb3V0ZXIuQ29udHJvbFJlcXVlc3RDYWxsYmFjayBjYWxsYmFjaykgewogICAgICAgIG5ldyBBc3luY1Rhc2s8Vm9pZCwgVm9pZCwgQm9vbGVhbj4oKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwcm90ZWN0ZWQgQm9vbGVhbiBkb0luQmFja2dyb3VuZChWb2lkLi4uIHBhcmFtcykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBVcmkgZGF0YSA9IGludGVudC5nZXREYXRhKCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBMb2cudyhUQUcsICJQbGF5IHJlcXVlc3Qgd2l0aG91dCBkYXRhIFVSSSIpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIFN0cmluZyBjb250ZW50SWQgPSBkYXRhLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgU3RyaW5nIG1pbWVUeXBlID0gaW50ZW50LmdldFR5cGUoKTsKICAgICAgICAgICAgICAgICAgICBpZiAobWltZVR5cGUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBtaW1lVHlwZSA9ICJ2aWRlby9tcDQiOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgTWVkaWEgbWVkaWEgPSBuZXcgTWVkaWEuQnVpbGRlcihjb250ZW50SWQsIG1pbWVUeXBlKS5idWlsZCgpOwogICAgICAgICAgICAgICAgICAgIEFwcGxpY2F0aW9uIGFwcCA9IGNocm9tZWNhc3QuZ2V0UnVubmluZ0FwcCgpOwogICAgICAgICAgICAgICAgICAgIGlmIChhcHAgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBhcHAgPSBjaHJvbWVjYXN0LmxhdW5jaEFwcChERUZBVUxUX1JFQ0VJVkVSX0FQUF9JRCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChhcHAgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBjaHJvbWVjYXN0LmxvYWRNZWRpYShjb250ZW50SWQsIG1pbWVUeXBlLCBhcHAuc2Vzc2lvbklkKTsKICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmQoVEFHLCAiTWVkaWEgbG9hZCByZXF1ZXN0ZWQ6ICIgKyBjb250ZW50SWQpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgTG9nLncoVEFHLCAiRmFpbGVkIHRvIHBsYXkgbWVkaWE6ICIgKyBlLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBvblBvc3RFeGVjdXRlKEJvb2xlYW4gc3VjY2VzcykgewogICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5vblJlc3VsdChuZXcgQnVuZGxlKCkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLm9uRXJyb3IoIkZhaWxlZCB0byBwbGF5IG1lZGlhIiwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfS5leGVjdXRlKCk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGhhbmRsZVBhdXNlKGZpbmFsIE1lZGlhUm91dGVyLkNvbnRyb2xSZXF1ZXN0Q2FsbGJhY2sgY2FsbGJhY2spIHsKICAgICAgICBuZXcgQXN5bmNUYXNrPFZvaWQsIFZvaWQsIEJvb2xlYW4+KCkgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHJvdGVjdGVkIEJvb2xlYW4gZG9JbkJhY2tncm91bmQoVm9pZC4uLiBwYXJhbXMpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgY2hyb21lY2FzdC5wYXVzZSgpOwogICAgICAgICAgICAgICAgICAgIExvZy5kKFRBRywgIk1lZGlhIHBhdXNlZCIpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgIExvZy53KFRBRywgIkZhaWxlZCB0byBwYXVzZTogIiArIGUuZ2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBvblBvc3RFeGVjdXRlKEJvb2xlYW4gc3VjY2VzcykgewogICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5vblJlc3VsdChuZXcgQnVuZGxlKCkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLm9uRXJyb3IoIkZhaWxlZCB0byBwYXVzZSIsIG51bGwpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0uZXhlY3V0ZSgpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBoYW5kbGVSZXN1bWUoZmluYWwgTWVkaWFSb3V0ZXIuQ29udHJvbFJlcXVlc3RDYWxsYmFjayBjYWxsYmFjaykgewogICAgICAgIG5ldyBBc3luY1Rhc2s8Vm9pZCwgVm9pZCwgQm9vbGVhbj4oKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwcm90ZWN0ZWQgQm9vbGVhbiBkb0luQmFja2dyb3VuZChWb2lkLi4uIHBhcmFtcykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBjaHJvbWVjYXN0LnBsYXkoKTsKICAgICAgICAgICAgICAgICAgICBMb2cuZChUQUcsICJNZWRpYSByZXN1bWVkIik7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgTG9nLncoVEFHLCAiRmFpbGVkIHRvIHJlc3VtZTogIiArIGUuZ2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBvblBvc3RFeGVjdXRlKEJvb2xlYW4gc3VjY2VzcykgewogICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5vblJlc3VsdChuZXcgQnVuZGxlKCkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLm9uRXJyb3IoIkZhaWxlZCB0byByZXN1bWUiLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LmV4ZWN1dGUoKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gaGFuZGxlU2VlayhmaW5hbCBJbnRlbnQgaW50ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWwgTWVkaWFSb3V0ZXIuQ29udHJvbFJlcXVlc3RDYWxsYmFjayBjYWxsYmFjaykgewogICAgICAgIG5ldyBBc3luY1Rhc2s8Vm9pZCwgVm9pZCwgQm9vbGVhbj4oKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwcm90ZWN0ZWQgQm9vbGVhbiBkb0luQmFja2dyb3VuZChWb2lkLi4uIHBhcmFtcykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBsb25nIHBvc2l0aW9uID0gaW50ZW50LmdldExvbmdFeHRyYShNZWRpYUNvbnRyb2xJbnRlbnQuRVhUUkFfSVRFTV9QT1NJVElPTiwgMCk7CiAgICAgICAgICAgICAgICAgICAgY2hyb21lY2FzdC5zZWVrKHBvc2l0aW9uKTsKICAgICAgICAgICAgICAgICAgICBMb2cuZChUQUcsICJTZWVrIHRvOiAiICsgcG9zaXRpb24pOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgIExvZy53KFRBRywgIkZhaWxlZCB0byBzZWVrOiAiICsgZS5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHByb3RlY3RlZCB2b2lkIG9uUG9zdEV4ZWN1dGUoQm9vbGVhbiBzdWNjZXNzKSB7CiAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2sgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChzdWNjZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLm9uUmVzdWx0KG5ldyBCdW5kbGUoKSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sub25FcnJvcigiRmFpbGVkIHRvIHNlZWsiLCBudWxsKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9LmV4ZWN1dGUoKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBwcml2YXRlIGJvb2xlYW4gaGFuZGxlU3RvcChmaW5hbCBNZWRpYVJvdXRlci5Db250cm9sUmVxdWVzdENhbGxiYWNrIGNhbGxiYWNrKSB7CiAgICAgICAgbmV3IEFzeW5jVGFzazxWb2lkLCBWb2lkLCBCb29sZWFuPigpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHByb3RlY3RlZCBCb29sZWFuIGRvSW5CYWNrZ3JvdW5kKFZvaWQuLi4gcGFyYW1zKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGNocm9tZWNhc3Quc3RvcCgpOwogICAgICAgICAgICAgICAgICAgIExvZy5kKFRBRywgIk1lZGlhIHN0b3BwZWQiKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICAgICAgICBMb2cudyhUQUcsICJGYWlsZWQgdG8gc3RvcDogIiArIGUuZ2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBvblBvc3RFeGVjdXRlKEJvb2xlYW4gc3VjY2VzcykgewogICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5vblJlc3VsdChuZXcgQnVuZGxlKCkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLm9uRXJyb3IoIkZhaWxlZCB0byBzdG9wIiwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfS5leGVjdXRlKCk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGhhbmRsZUdldFN0YXR1cyhmaW5hbCBNZWRpYVJvdXRlci5Db250cm9sUmVxdWVzdENhbGxiYWNrIGNhbGxiYWNrKSB7CiAgICAgICAgbmV3IEFzeW5jVGFzazxWb2lkLCBWb2lkLCBCdW5kbGU+KCkgewogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHJvdGVjdGVkIEJ1bmRsZSBkb0luQmFja2dyb3VuZChWb2lkLi4uIHBhcmFtcykgewogICAgICAgICAgICAgICAgQnVuZGxlIHJlc3VsdCA9IG5ldyBCdW5kbGUoKTsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgU3RhdHVzIHN0YXR1cyA9IGNocm9tZWNhc3QuZ2V0U3RhdHVzKCk7CiAgICAgICAgICAgICAgICAgICAgQXBwbGljYXRpb24gYXBwID0gc3RhdHVzLmdldFJ1bm5pbmdBcHAoKTsKICAgICAgICAgICAgICAgICAgICByZXN1bHQucHV0U3RyaW5nKE1lZGlhQ29udHJvbEludGVudC5FWFRSQV9TRVNTSU9OX1NUQVRVU19PQkpFQ1QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHAgIT0gbnVsbCA/IGFwcC5zZXNzaW9uSWQgOiBudWxsKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgIExvZy53KFRBRywgIkZhaWxlZCB0byBnZXQgc3RhdHVzOiAiICsgZS5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgICAgcHJvdGVjdGVkIHZvaWQgb25Qb3N0RXhlY3V0ZShCdW5kbGUgcmVzdWx0KSB7CiAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2sgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5vblJlc3VsdChyZXN1bHQpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLm9uRXJyb3IoIkZhaWxlZCB0byBnZXQgc3RhdHVzIiwgbnVsbCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfS5leGVjdXRlKCk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIGhhbmRsZUVuZFNlc3Npb24oZmluYWwgTWVkaWFSb3V0ZXIuQ29udHJvbFJlcXVlc3RDYWxsYmFjayBjYWxsYmFjaykgewogICAgICAgIG5ldyBBc3luY1Rhc2s8Vm9pZCwgVm9pZCwgQm9vbGVhbj4oKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwcm90ZWN0ZWQgQm9vbGVhbiBkb0luQmFja2dyb3VuZChWb2lkLi4uIHBhcmFtcykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBBcHBsaWNhdGlvbiBhcHAgPSBjaHJvbWVjYXN0LmdldFJ1bm5pbmdBcHAoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoYXBwICE9IG51bGwgJiYgYXBwLnNlc3Npb25JZCAhPSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNocm9tZWNhc3Quc3RvcFNlc3Npb24oYXBwLnNlc3Npb25JZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgIExvZy53KFRBRywgIkZhaWxlZCB0byBlbmQgc2Vzc2lvbjogIiArIGUuZ2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwcm90ZWN0ZWQgdm9pZCBvblBvc3RFeGVjdXRlKEJvb2xlYW4gc3VjY2VzcykgewogICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrICE9IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoc3VjY2VzcykgewogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5vblJlc3VsdChuZXcgQnVuZGxlKCkpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLm9uRXJyb3IoIkZhaWxlZCB0byBlbmQgc2Vzc2lvbiIsIG51bGwpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0uZXhlY3V0ZSgpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIHByaXZhdGUgYm9vbGVhbiBoYW5kbGVTeW5jU3RhdHVzKGZpbmFsIE1lZGlhUm91dGVyLkNvbnRyb2xSZXF1ZXN0Q2FsbGJhY2sgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gaGFuZGxlR2V0U3RhdHVzKGNhbGxiYWNrKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIG9uU2V0Vm9sdW1lKGludCB2b2x1bWUpIHsKICAgICAgICBMb2cuZChUQUcsICJvblNldFZvbHVtZTogIiArIHZvbHVtZSk7CiAgICAgICAgbmV3IEFzeW5jVGFzazxWb2lkLCBWb2lkLCBWb2lkPigpIHsKICAgICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICAgIHByb3RlY3RlZCBWb2lkIGRvSW5CYWNrZ3JvdW5kKFZvaWQuLi4gcGFyYW1zKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGNocm9tZWNhc3Quc2V0Vm9sdW1lKHZvbHVtZSAvIDIwLjApOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgIExvZy53KFRBRywgIkZhaWxlZCB0byBzZXQgdm9sdW1lOiAiICsgZS5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9LmV4ZWN1dGUoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIG9uVXBkYXRlVm9sdW1lKGludCBkZWx0YSkgewogICAgICAgIExvZy5kKFRBRywgIm9uVXBkYXRlVm9sdW1lOiBkZWx0YT0iICsgZGVsdGEpOwogICAgICAgIG5ldyBBc3luY1Rhc2s8Vm9pZCwgVm9pZCwgVm9pZD4oKSB7CiAgICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgICBwcm90ZWN0ZWQgVm9pZCBkb0luQmFja2dyb3VuZChWb2lkLi4uIHBhcmFtcykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBTdGF0dXMgc3RhdHVzID0gY2hyb21lY2FzdC5nZXRTdGF0dXMoKTsKICAgICAgICAgICAgICAgICAgICBkb3VibGUgbmV3Vm9sdW1lID0gTWF0aC5tYXgoMC4wLCBNYXRoLm1pbigxLjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMudm9sdW1lLmxldmVsICsgKGRlbHRhIC8gMjAuMCkpKTsKICAgICAgICAgICAgICAgICAgICBjaHJvbWVjYXN0LnNldFZvbHVtZShuZXdWb2x1bWUpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgIExvZy53KFRBRywgIkZhaWxlZCB0byB1cGRhdGUgdm9sdW1lOiAiICsgZS5nZXRNZXNzYWdlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICB9LmV4ZWN1dGUoKTsKICAgIH0KfQo= \ No newline at end of file