From f6644810560618fb0b2073bb160a962bbd3ed132 Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Mon, 15 Jul 2024 11:02:51 +0200 Subject: [PATCH 01/24] :sparkles: Implement WCS and 2 axis FoV recovery --- js/models/event_handler.js | 7 +++++++ js/widget.js | 9 +++++++++ src/ipyaladin/widget.py | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/js/models/event_handler.js b/js/models/event_handler.js index d3c3bb8c..3dc43bed 100644 --- a/js/models/event_handler.js +++ b/js/models/event_handler.js @@ -42,6 +42,7 @@ export default class EventHandler { } jsTargetLock.lock(); const raDec = [position.ra, position.dec]; + this.model.set("_wcs", this.aladin.getViewWCS()); this.model.set("_target", `${raDec[0]} ${raDec[1]}`); this.model.save_changes(); }); @@ -68,7 +69,13 @@ export default class EventHandler { } jsFovLock.lock(); // fov MUST be cast into float in order to be sent to the model + this.model.set("_wcs", this.aladin.getViewWCS()); this.model.set("_fov", parseFloat(fov.toFixed(5))); + const fov_xy = this.aladin.getFov(); + this.model.set("_fov_xy", { + x: fov_xy[0], + y: fov_xy[1], + }); this.model.save_changes(); }); diff --git a/js/widget.js b/js/widget.js index 7b261dde..98b05251 100644 --- a/js/widget.js +++ b/js/widget.js @@ -24,6 +24,15 @@ function initAladinLite(model, el) { const raDec = initOptions["target"].split(" "); aladin.gotoRaDec(raDec[0], raDec[1]); + // Set current FoV and WCS + const FoV = aladin.getFov(); + model.set("_fov_xy", { + x: FoV[0], + y: FoV[1], + }); + model.set("_wcs", aladin.getViewWCS()); + model.save_changes(); + el.appendChild(aladinDiv); return { aladin, aladinDiv }; } diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index 735fee5a..8b296a18 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -9,7 +9,7 @@ import pathlib from pathlib import Path import typing -from typing import ClassVar, Union, Final, Optional +from typing import ClassVar, Union, Final, Optional, Tuple import warnings import anywidget @@ -19,6 +19,7 @@ from astropy.io import fits as astropy_fits from astropy.io.fits import HDUList import traitlets +from astropy.wcs import WCS try: from regions import ( @@ -126,6 +127,10 @@ class Aladin(anywidget.AnyWidget): grid_opacity = Float(0.5).tag(sync=True, init_option=True) grid_options = traitlets.Dict().tag(sync=True, init_option=True) + # Values + _wcs = traitlets.Dict().tag(sync=True) + _fov_xy = traitlets.Dict().tag(sync=True) + # content of the last click clicked_object = traitlets.Dict().tag(sync=True) # listener callback is on the python side and contains functions to link to events @@ -165,6 +170,35 @@ def _handle_custom_message(self, _: any, message: dict, __: any) -> None: elif event_type == "select" and "select" in self.listener_callback: self.listener_callback["select"](message_content) + @property + def wcs(self) -> WCS: + """The world coordinate system of the Aladin Lite widget. + + Returns + ------- + WCS + An astropy WCS object representing the world coordinate system. + + """ + if "RADECSYS" in self._wcs: # RADECSYS keyword is deprecated for astropy.WCS + self._wcs["RADESYS"] = self._wcs.pop("RADECSYS") + return WCS(self._wcs) + + @property + def fov_xy(self) -> Tuple[Angle, Angle]: + """The field of view of the Aladin Lite along the two axis. + + Returns + ------- + tuple[Angle, Angle] + A tuple of astropy.units.Angle objects representing the field of view. + + """ + return ( + Angle(self._fov_xy["x"], unit="deg"), + Angle(self._fov_xy["y"], unit="deg"), + ) + @property def fov(self) -> Angle: """The field of view of the Aladin Lite widget along the horizontal axis. From 90c6fda2898c69bd1e77e187a2e27d43dd9c2a89 Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Mon, 15 Jul 2024 11:28:04 +0200 Subject: [PATCH 02/24] :memo: Add new notebook example for wcs and ov recovery --- examples/11_Values_Recovery.ipynb | 236 ++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 examples/11_Values_Recovery.ipynb diff --git a/examples/11_Values_Recovery.ipynb b/examples/11_Values_Recovery.ipynb new file mode 100644 index 00000000..1b309445 --- /dev/null +++ b/examples/11_Values_Recovery.ipynb @@ -0,0 +1,236 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 20, + "id": "initial_id", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-15T09:19:49.859887Z", + "start_time": "2024-07-15T09:19:49.856897Z" + }, + "collapsed": true + }, + "outputs": [], + "source": [ + "from ipyaladin import Aladin" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "2e62d34eb8543145", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-15T09:19:50.731329Z", + "start_time": "2024-07-15T09:19:50.706131Z" + } + }, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "1bd7729f085f4d4e8874464da6aa7bec", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Aladin(height=600, init_options=['_fov', '_target', 'background_color', 'coo_frame', 'full_screen', 'grid_colo…" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "aladin = Aladin(fov=5, height=600, target=\"M31\")\n", + "aladin" + ] + }, + { + "cell_type": "markdown", + "id": "54a2d7bb2777de3b", + "metadata": {}, + "source": [ + "# Values Recovery\n", + "## Recover current values\n", + "Currently, ipyaladin allow you to recover some values from the Aladin Lite instance. These values are:\n", + "- The World Coordinate System (WCS)\n", + "- The field of view for the x and y axis\n", + "You can recover these values by calling the corresponding attribute." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "84153657cb7cd837", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-15T09:19:53.288584Z", + "start_time": "2024-07-15T09:19:53.270738Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "WCS Keywords\n", + "\n", + "Number of WCS axes: 2\n", + "CTYPE : 'RA---SIN' 'DEC--SIN' \n", + "CRVAL : 10.684708330000005 41.26875 \n", + "CRPIX : 639.5 300.5 \n", + "PC1_1 PC1_2 : 1.0 0.0 \n", + "PC2_1 PC2_2 : 0.0 1.0 \n", + "CDELT : 0.003912363067292645 0.003912363067292645 \n", + "NAXIS : 1278 600" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "aladin.wcs # Recover the current WCS" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "9595ae02388b245a", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-15T09:19:54.416080Z", + "start_time": "2024-07-15T09:19:54.405967Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(, )" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "aladin.fov_xy # Recover the current field of view for the x and y axis" + ] + }, + { + "cell_type": "markdown", + "id": "870935d9c4e2aaa", + "metadata": {}, + "source": [ + "## Recover values after changing\n", + "In case you are changing a value like the target or the field of view, you need to recover one of these values in the next cell." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "dfdc3a54019d7e34", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-15T09:19:56.582921Z", + "start_time": "2024-07-15T09:19:56.566380Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "WCS Keywords\n", + "\n", + "Number of WCS axes: 2\n", + "CTYPE : 'RA---SIN' 'DEC--SIN' \n", + "CRVAL : 10.684708330000005 41.26875 \n", + "CRPIX : 639.5 300.5 \n", + "PC1_1 PC1_2 : 1.0 0.0 \n", + "PC2_1 PC2_2 : 0.0 1.0 \n", + "CDELT : 0.003912363067292645 0.003912363067292645 \n", + "NAXIS : 1278 600" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "aladin.target = \"M33\"\n", + "aladin.fov = 2\n", + "aladin.wcs # This will display the previous WCS" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "ad62fb2664e45a30", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-15T09:19:57.772224Z", + "start_time": "2024-07-15T09:19:57.763011Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "WCS Keywords\n", + "\n", + "Number of WCS axes: 2\n", + "CTYPE : 'RA---SIN' 'DEC--SIN' \n", + "CRVAL : 23.462069062180003 30.660175111980003 \n", + "CRPIX : 639.5 300.5 \n", + "PC1_1 PC1_2 : 1.0 0.0 \n", + "PC2_1 PC2_2 : 0.0 1.0 \n", + "CDELT : 0.001564945226917058 0.001564945226917058 \n", + "NAXIS : 1278 600" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "aladin.wcs # This will represent the new WCS" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "281941943a948d7b", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 4a15caa6075d440ad0138c1fdd2ad08c84b595fc Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Mon, 15 Jul 2024 11:29:27 +0200 Subject: [PATCH 03/24] :memo: Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 879a12e5..2c8ce4d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for `astropy.coordinates.SkyCoord` for assigning and reading the `target` property (#80) - Support for `astropy.coordinates.Angle` for reading the `fov` property (#83) - Support for `regions.LineSkyRegion`, `regions.CircleSkyRegion`, `regions.EllipseSkyRegion`, `regions.PolygonSkyRegion`, `regions.RectangleSkyRegion`, `regions.Regions` with `add_graphic_overlay_from_region` (#88) +- Allow WCS and 2 axis FoV recovery from `wcs` and `fov_xy` properties (#96) ### Fixed From 5f0b7455d6f84caeb167a66c922387ebe9cfd6b7 Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Mon, 15 Jul 2024 12:23:18 +0200 Subject: [PATCH 04/24] :sparkles: Add support for cooFrameChanged event to update the WCS --- js/models/event_handler.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/js/models/event_handler.js b/js/models/event_handler.js index 3dc43bed..5f7697c7 100644 --- a/js/models/event_handler.js +++ b/js/models/event_handler.js @@ -97,6 +97,11 @@ export default class EventHandler { /* Aladin callbacks */ + this.aladin.on("cooFrameChanged", () => { + this.model.set("_wcs", this.aladin.getViewWCS()); + this.model.save_changes(); + }); + this.aladin.on("objectHovered", (object) => { if (object["data"] !== undefined) { this.model.send({ From 71c0d13f27133567534bed5b0988163a36becf92 Mon Sep 17 00:00:00 2001 From: Tom Czekaj <47594493+Xen0Xys@users.noreply.github.com> Date: Mon, 15 Jul 2024 13:35:20 +0200 Subject: [PATCH 05/24] :pencil2: Fix typo Co-authored-by: Manon Marchand --- src/ipyaladin/widget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index 8b296a18..e746ed66 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -186,7 +186,7 @@ def wcs(self) -> WCS: @property def fov_xy(self) -> Tuple[Angle, Angle]: - """The field of view of the Aladin Lite along the two axis. + """The field of view of the Aladin Lite along the two axes. Returns ------- From 610ceaf30cc3e99d59e320ef354a4dcb6801a2f2 Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Mon, 15 Jul 2024 13:43:15 +0200 Subject: [PATCH 06/24] :art: Add error raising when recovering the WSC in the same cell that an update --- examples/11_Values_Recovery.ipynb | 169 +++++------------------------- src/ipyaladin/widget.py | 13 +++ 2 files changed, 39 insertions(+), 143 deletions(-) diff --git a/examples/11_Values_Recovery.ipynb b/examples/11_Values_Recovery.ipynb index 1b309445..bc1647e0 100644 --- a/examples/11_Values_Recovery.ipynb +++ b/examples/11_Values_Recovery.ipynb @@ -2,51 +2,26 @@ "cells": [ { "cell_type": "code", - "execution_count": 20, "id": "initial_id", "metadata": { - "ExecuteTime": { - "end_time": "2024-07-15T09:19:49.859887Z", - "start_time": "2024-07-15T09:19:49.856897Z" - }, "collapsed": true }, - "outputs": [], "source": [ "from ipyaladin import Aladin" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "code", - "execution_count": 21, "id": "2e62d34eb8543145", - "metadata": { - "ExecuteTime": { - "end_time": "2024-07-15T09:19:50.731329Z", - "start_time": "2024-07-15T09:19:50.706131Z" - } - }, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "1bd7729f085f4d4e8874464da6aa7bec", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Aladin(height=600, init_options=['_fov', '_target', 'background_color', 'coo_frame', 'full_screen', 'grid_colo…" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], + "metadata": {}, "source": [ "aladin = Aladin(fov=5, height=600, target=\"M31\")\n", "aladin" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -63,64 +38,23 @@ }, { "cell_type": "code", - "execution_count": 22, "id": "84153657cb7cd837", - "metadata": { - "ExecuteTime": { - "end_time": "2024-07-15T09:19:53.288584Z", - "start_time": "2024-07-15T09:19:53.270738Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "WCS Keywords\n", - "\n", - "Number of WCS axes: 2\n", - "CTYPE : 'RA---SIN' 'DEC--SIN' \n", - "CRVAL : 10.684708330000005 41.26875 \n", - "CRPIX : 639.5 300.5 \n", - "PC1_1 PC1_2 : 1.0 0.0 \n", - "PC2_1 PC2_2 : 0.0 1.0 \n", - "CDELT : 0.003912363067292645 0.003912363067292645 \n", - "NAXIS : 1278 600" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], + "metadata": {}, "source": [ "aladin.wcs # Recover the current WCS" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "code", - "execution_count": 23, "id": "9595ae02388b245a", - "metadata": { - "ExecuteTime": { - "end_time": "2024-07-15T09:19:54.416080Z", - "start_time": "2024-07-15T09:19:54.405967Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(, )" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], + "metadata": {}, "source": [ "aladin.fov_xy # Recover the current field of view for the x and y axis" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -133,83 +67,32 @@ }, { "cell_type": "code", - "execution_count": 24, "id": "dfdc3a54019d7e34", - "metadata": { - "ExecuteTime": { - "end_time": "2024-07-15T09:19:56.582921Z", - "start_time": "2024-07-15T09:19:56.566380Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "WCS Keywords\n", - "\n", - "Number of WCS axes: 2\n", - "CTYPE : 'RA---SIN' 'DEC--SIN' \n", - "CRVAL : 10.684708330000005 41.26875 \n", - "CRPIX : 639.5 300.5 \n", - "PC1_1 PC1_2 : 1.0 0.0 \n", - "PC2_1 PC2_2 : 0.0 1.0 \n", - "CDELT : 0.003912363067292645 0.003912363067292645 \n", - "NAXIS : 1278 600" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], + "metadata": {}, "source": [ "aladin.target = \"M33\"\n", - "aladin.fov = 2\n", - "aladin.wcs # This will display the previous WCS" - ] + "aladin.fov = 2" + ], + "outputs": [], + "execution_count": null }, { "cell_type": "code", - "execution_count": 25, "id": "ad62fb2664e45a30", - "metadata": { - "ExecuteTime": { - "end_time": "2024-07-15T09:19:57.772224Z", - "start_time": "2024-07-15T09:19:57.763011Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "WCS Keywords\n", - "\n", - "Number of WCS axes: 2\n", - "CTYPE : 'RA---SIN' 'DEC--SIN' \n", - "CRVAL : 23.462069062180003 30.660175111980003 \n", - "CRPIX : 639.5 300.5 \n", - "PC1_1 PC1_2 : 1.0 0.0 \n", - "PC2_1 PC2_2 : 0.0 1.0 \n", - "CDELT : 0.001564945226917058 0.001564945226917058 \n", - "NAXIS : 1278 600" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], + "metadata": {}, "source": [ "aladin.wcs # This will represent the new WCS" - ] + ], + "outputs": [], + "execution_count": null }, { "cell_type": "code", - "execution_count": null, "id": "281941943a948d7b", "metadata": {}, + "source": [], "outputs": [], - "source": [] + "execution_count": null } ], "metadata": { diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index e746ed66..5be01f40 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -180,6 +180,11 @@ def wcs(self) -> WCS: An astropy WCS object representing the world coordinate system. """ + if self._wcs == {}: + raise ValueError( + "The world coordinate system is not available. " + "Please recover it from another cell." + ) if "RADECSYS" in self._wcs: # RADECSYS keyword is deprecated for astropy.WCS self._wcs["RADESYS"] = self._wcs.pop("RADECSYS") return WCS(self._wcs) @@ -194,6 +199,11 @@ def fov_xy(self) -> Tuple[Angle, Angle]: A tuple of astropy.units.Angle objects representing the field of view. """ + if self._fov_xy == {}: + raise ValueError( + "The field of view along the two axes is not available. " + "Please recover it from another cell." + ) return ( Angle(self._fov_xy["x"], unit="deg"), Angle(self._fov_xy["y"], unit="deg"), @@ -219,6 +229,8 @@ def fov(self, fov: Union[float, Angle]) -> None: if isinstance(fov, Angle): fov = fov.deg self._fov = fov + self._fov_xy = {} + self._wcs = {} self.send({"event_name": "change_fov", "fov": fov}) @property @@ -234,6 +246,7 @@ def target(self) -> SkyCoord: """ ra, dec = self._target.split(" ") + self._wcs = None return SkyCoord( ra=ra, dec=dec, From 72dedd237995529541f358723c55203fe7f678f6 Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Mon, 15 Jul 2024 15:50:50 +0200 Subject: [PATCH 07/24] :ambulance: Fix wrong _wcs traitlets assignation --- src/ipyaladin/widget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index 5be01f40..1e1e0056 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -246,7 +246,6 @@ def target(self) -> SkyCoord: """ ra, dec = self._target.split(" ") - self._wcs = None return SkyCoord( ra=ra, dec=dec, @@ -263,6 +262,7 @@ def target(self, target: Union[str, SkyCoord]) -> None: "target must be a string or an astropy.coordinates.SkyCoord object" ) self._target = f"{target.icrs.ra.deg} {target.icrs.dec.deg}" + self._wcs = {} self.send( { "event_name": "goto_ra_dec", From 676911c9fe542db0ea62df41d56d45dd24796103 Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Tue, 16 Jul 2024 09:55:53 +0200 Subject: [PATCH 08/24] :art: Rename example 11 --- ...1_Extracting_information_from_the_view.ipynb} | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) rename examples/{11_Values_Recovery.ipynb => 11_Extracting_information_from_the_view.ipynb} (85%) diff --git a/examples/11_Values_Recovery.ipynb b/examples/11_Extracting_information_from_the_view.ipynb similarity index 85% rename from examples/11_Values_Recovery.ipynb rename to examples/11_Extracting_information_from_the_view.ipynb index bc1647e0..67eda70c 100644 --- a/examples/11_Values_Recovery.ipynb +++ b/examples/11_Extracting_information_from_the_view.ipynb @@ -28,8 +28,8 @@ "id": "54a2d7bb2777de3b", "metadata": {}, "source": [ - "# Values Recovery\n", - "## Recover current values\n", + "# Extracting information from the view\n", + "## Extracting values\n", "Currently, ipyaladin allow you to recover some values from the Aladin Lite instance. These values are:\n", "- The World Coordinate System (WCS)\n", "- The field of view for the x and y axis\n", @@ -61,8 +61,8 @@ "id": "870935d9c4e2aaa", "metadata": {}, "source": [ - "## Recover values after changing\n", - "In case you are changing a value like the target or the field of view, you need to recover one of these values in the next cell." + "## Changing values\n", + "If you change a value that affects the value you want to extract, you need to extract this value in the next cell." ] }, { @@ -85,14 +85,6 @@ ], "outputs": [], "execution_count": null - }, - { - "cell_type": "code", - "id": "281941943a948d7b", - "metadata": {}, - "source": [], - "outputs": [], - "execution_count": null } ], "metadata": { From 70688fc4612684b65f282102d1e75e5c8e4867c4 Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Tue, 16 Jul 2024 12:03:09 +0200 Subject: [PATCH 09/24] :arrow_up: Update Aladin Lite from 3.4.1-beta to 3.4.4-beta --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1588d45e..61e4388e 100644 --- a/README.md +++ b/README.md @@ -58,8 +58,8 @@ Correspondence table between ipyaladin versions and Aladin Lite versions: | ipyaladin | Aladin-Lite | | --------- | ----------- | -| 0.3.0 | 3.3.3-dev | | 0.4.0 | 3.4.4-beta | +| 0.3.0 | 3.3.3-dev | > [!TIP] > This can always be read like so From 6f3d3ae1e1711dee52c8b0c109a4c36ed300d34d Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Tue, 16 Jul 2024 12:03:47 +0200 Subject: [PATCH 10/24] :sparkles: Add missing events that impact WCS and FoV --- js/models/event_handler.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/js/models/event_handler.js b/js/models/event_handler.js index 5f7697c7..8812a887 100644 --- a/js/models/event_handler.js +++ b/js/models/event_handler.js @@ -102,6 +102,21 @@ export default class EventHandler { this.model.save_changes(); }); + this.aladin.on("projectionChanged", () => { + this.model.set("_wcs", this.aladin.getViewWCS()); + this.model.save_changes(); + }); + + this.aladin.on("resizeChanged", () => { + this.model.set("_wcs", this.aladin.getViewWCS()); + const fov_xy = this.aladin.getFov(); + this.model.set("_fov_xy", { + x: fov_xy[0], + y: fov_xy[1], + }); + this.model.save_changes(); + }); + this.aladin.on("objectHovered", (object) => { if (object["data"] !== undefined) { this.model.send({ From 4483b76760b0d66dfaf4c05ebeaff4b3f3d58d45 Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Tue, 16 Jul 2024 11:39:26 +0200 Subject: [PATCH 11/24] maint: prepare release 0.4.0 fix: A.line was removed from public AL API in favor of A.vector --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c8ce4d1..91017399 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Allow WCS and 2 axis FoV recovery from `wcs` and `fov_xy` properties (#96) - monochromatic FITS images can be added to the view with `ipyaladin.Aladin.add_fits`. The method accepts `astropy.io.fits.HDUList`, `pathlib.Path`, or `string` representing paths (#86) @@ -29,13 +30,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for `astropy.coordinates.SkyCoord` for assigning and reading the `target` property (#80) - Support for `astropy.coordinates.Angle` for reading the `fov` property (#83) - Support for `regions.LineSkyRegion`, `regions.CircleSkyRegion`, `regions.EllipseSkyRegion`, `regions.PolygonSkyRegion`, `regions.RectangleSkyRegion`, `regions.Regions` with `add_graphic_overlay_from_region` (#88) -- Allow WCS and 2 axis FoV recovery from `wcs` and `fov_xy` properties (#96) ### Fixed - `clicked_object` was not properly updated after a click - Fix asynchronous update for the `target` property (#80) -- some options were not accepted in snake_case anymore in `add_moc` and in `add_catalog_from_url` (#82) +- Allow WCS and 2 axis FoV recovery from `wcs` and `fov_xy` properties (#96) ### Changed From 48999a259d75b1c08354d210dfca51999693bb6b Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Tue, 16 Jul 2024 15:37:05 +0200 Subject: [PATCH 12/24] :sparkles: Add layerChanged listener for future AL version --- js/models/event_handler.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/js/models/event_handler.js b/js/models/event_handler.js index 8812a887..5b3c80cd 100644 --- a/js/models/event_handler.js +++ b/js/models/event_handler.js @@ -107,6 +107,12 @@ export default class EventHandler { this.model.save_changes(); }); + this.aladin.on("layerChanged", (_, layer) => { + if (layer !== "base") return; + this.model.set("_wcs", this.aladin.getViewWCS()); + this.model.save_changes(); + }); + this.aladin.on("resizeChanged", () => { this.model.set("_wcs", this.aladin.getViewWCS()); const fov_xy = this.aladin.getFov(); From 5f8e397d1084cff4e8e77446b886a940bdfd0517 Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Tue, 16 Jul 2024 11:39:26 +0200 Subject: [PATCH 13/24] maint: prepare release 0.4.0 fix: A.line was removed from public AL API in favor of A.vector --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91017399..5028afbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,7 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `clicked_object` was not properly updated after a click - Fix asynchronous update for the `target` property (#80) -- Allow WCS and 2 axis FoV recovery from `wcs` and `fov_xy` properties (#96) +- some options were not accepted in snake_case anymore in `add_moc` and in `add_catalog_from_url` (#82) ### Changed From baeed5d2f63cf5a710bbeed1e06031703f859649 Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Thu, 18 Jul 2024 10:40:40 +0200 Subject: [PATCH 14/24] :arrow_up: Bump Aladin Lite to 3.4.5-beta --- CHANGELOG.md | 6 +++++- README.md | 9 +++++---- js/aladin_lite.js | 2 +- js/models/event_handler.js | 16 ++++++++-------- js/widget.js | 6 +++--- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5028afbb..5989cd58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - monochromatic FITS images can be added to the view with `ipyaladin.Aladin.add_fits`. The method accepts `astropy.io.fits.HDUList`, `pathlib.Path`, or `string` representing paths (#86) +### Changed + +- Upgrade Aladin Lite version to 3.4.5-beta (#96) + ## [0.4.0] ### Added @@ -41,7 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Change the jslink target trait from `target` to `shared_target` (#80) - Change the jslink fov trait from `fov` to `shared_fov` (#83) -- Upgrade Aladin Lite version to 3.4.1-beta (#88) +- Upgrade Aladin Lite version to 3.4.4-beta (#88) - Add support for list of strings in `add_overlay_from_stcs` (#88) ### Deprecated diff --git a/README.md b/README.md index 61e4388e..bdf8388b 100644 --- a/README.md +++ b/README.md @@ -56,10 +56,11 @@ Ipyaladin brings [Aladin Lite](https://github.com/cds-astro/aladin-lite) into no Correspondence table between ipyaladin versions and Aladin Lite versions: -| ipyaladin | Aladin-Lite | -| --------- | ----------- | -| 0.4.0 | 3.4.4-beta | -| 0.3.0 | 3.3.3-dev | +| ipyaladin | Aladin-Lite | +| ---------- | ----------- | +| Unreleased | 3.4.5-beta | +| 0.4.0 | 3.4.4-beta | +| 0.3.0 | 3.3.3-dev | > [!TIP] > This can always be read like so diff --git a/js/aladin_lite.js b/js/aladin_lite.js index 379517f1..98addcb1 100644 --- a/js/aladin_lite.js +++ b/js/aladin_lite.js @@ -1,3 +1,3 @@ -import A from "https://esm.sh/aladin-lite@3.4.4-beta"; +import A from "https://esm.sh/aladin-lite@3.4.5-beta"; export default A; diff --git a/js/models/event_handler.js b/js/models/event_handler.js index 5b3c80cd..49417d04 100644 --- a/js/models/event_handler.js +++ b/js/models/event_handler.js @@ -71,10 +71,10 @@ export default class EventHandler { // fov MUST be cast into float in order to be sent to the model this.model.set("_wcs", this.aladin.getViewWCS()); this.model.set("_fov", parseFloat(fov.toFixed(5))); - const fov_xy = this.aladin.getFov(); + const twoAxisFoV = this.aladin.getFov(); this.model.set("_fov_xy", { - x: fov_xy[0], - y: fov_xy[1], + x: twoAxisFoV[0], + y: twoAxisFoV[1], }); this.model.save_changes(); }); @@ -107,18 +107,18 @@ export default class EventHandler { this.model.save_changes(); }); - this.aladin.on("layerChanged", (_, layer) => { - if (layer !== "base") return; + this.aladin.on("layerChanged", (_, layerName, state) => { + if (layerName !== "base" || state !== "ADDED") return; this.model.set("_wcs", this.aladin.getViewWCS()); this.model.save_changes(); }); this.aladin.on("resizeChanged", () => { this.model.set("_wcs", this.aladin.getViewWCS()); - const fov_xy = this.aladin.getFov(); + const twoAxisFoV = this.aladin.getFov(); this.model.set("_fov_xy", { - x: fov_xy[0], - y: fov_xy[1], + x: twoAxisFoV[0], + y: twoAxisFoV[1], }); this.model.save_changes(); }); diff --git a/js/widget.js b/js/widget.js index 98b05251..3be29317 100644 --- a/js/widget.js +++ b/js/widget.js @@ -25,10 +25,10 @@ function initAladinLite(model, el) { aladin.gotoRaDec(raDec[0], raDec[1]); // Set current FoV and WCS - const FoV = aladin.getFov(); + const twoAxisFoV = aladin.getFov(); model.set("_fov_xy", { - x: FoV[0], - y: FoV[1], + x: twoAxisFoV[0], + y: twoAxisFoV[1], }); model.set("_wcs", aladin.getViewWCS()); model.save_changes(); From 3ce83855ab82af29053b3569cfd1f2145cdfd5b1 Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Thu, 18 Jul 2024 11:46:39 +0200 Subject: [PATCH 15/24] :sparkles: Convert height to property to change the WCS on height updates --- js/models/event_handler.js | 16 ++++++++++++---- js/models/message_handler.js | 5 ++++- src/ipyaladin/widget.py | 24 +++++++++++++++++++++++- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/js/models/event_handler.js b/js/models/event_handler.js index 49417d04..0406e99f 100644 --- a/js/models/event_handler.js +++ b/js/models/event_handler.js @@ -12,7 +12,7 @@ export default class EventHandler { this.aladin = aladin; this.aladinDiv = aladinDiv; this.model = model; - this.messageHandler = new MessageHandler(aladin); + this.messageHandler = new MessageHandler(aladin, model); } /** @@ -90,9 +90,17 @@ export default class EventHandler { }); /* Div control */ - this.model.on("change:height", () => { - let height = this.model.get("height"); + this.model.on("change:_height", () => { + let height = this.model.get("_height"); this.aladinDiv.style.height = `${height}px`; + // Update WCS and FoV + this.model.set("_wcs", this.aladin.getViewWCS()); + const twoAxisFoV = this.aladin.getFov(); + this.model.set("_fov_xy", { + x: twoAxisFoV[0], + y: twoAxisFoV[1], + }); + this.model.save_changes(); }); /* Aladin callbacks */ @@ -233,7 +241,7 @@ export default class EventHandler { unsubscribeAll() { this.model.off("change:_target"); this.model.off("change:_fov"); - this.model.off("change:height"); + this.model.off("change:_height"); this.model.off("change:coo_frame"); this.model.off("change:survey"); this.model.off("change:overlay_survey"); diff --git a/js/models/message_handler.js b/js/models/message_handler.js index b5387d7f..28294c7e 100644 --- a/js/models/message_handler.js +++ b/js/models/message_handler.js @@ -4,8 +4,9 @@ import A from "../aladin_lite"; let imageCount = 0; export default class MessageHandler { - constructor(aladin) { + constructor(aladin, model) { this.aladin = aladin; + this.model = model; } handleChangeFoV(msg) { @@ -29,6 +30,8 @@ export default class MessageHandler { URL.revokeObjectURL(url); }); this.aladin.setOverlayImageLayer(image, options.name); + // this.model.set("_wcs", this.aladin.getViewWCS()); + // this.model.save_changes(); } handleAddCatalogFromURL(msg) { diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index 1e1e0056..4d919186 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -80,7 +80,7 @@ class Aladin(anywidget.AnyWidget): _css: Final = pathlib.Path(__file__).parent / "static" / "widget.css" # Options for the view initialization - height = Int(400).tag(sync=True, init_option=True) + _height = Int(400).tag(sync=True, init_option=True) _target = Unicode( "0 0", help="A private trait that stores the current target of the widget in a string." @@ -148,6 +148,7 @@ def _init_options(self) -> typing.List[str]: def __init__(self, *args: any, **kwargs: any) -> None: super().__init__(*args, **kwargs) + self.height = kwargs.get("height", 400) self.target = kwargs.get("target", "0 0") self.fov = kwargs.get("fov", 60.0) self.on_msg(self._handle_custom_message) @@ -170,6 +171,26 @@ def _handle_custom_message(self, _: any, message: dict, __: any) -> None: elif event_type == "select" and "select" in self.listener_callback: self.listener_callback["select"](message_content) + @property + def height(self) -> int: + """The height of the Aladin Lite widget. + + Returns + ------- + int + The height of the widget in pixels. + + """ + return self._height + + @height.setter + def height(self, height: int) -> None: + if self._height == height: + return + self._wcs = {} + self._fov_xy = {} + self._height = height + @property def wcs(self) -> WCS: """The world coordinate system of the Aladin Lite widget. @@ -313,6 +334,7 @@ def add_fits(self, fits: Union[str, Path, HDUList], **image_options: any) -> Non fits_bytes = io.BytesIO() fits.writeto(fits_bytes) + self._wcs = {} self.send( {"event_name": "add_fits", "options": image_options}, buffers=[fits_bytes.getvalue()], From 975c8e96d07fa4db86ffc86bd18e80bc541d8818 Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Thu, 18 Jul 2024 11:49:55 +0200 Subject: [PATCH 16/24] :goal_net: Add custom WidgetCommunicationError --- src/ipyaladin/errors/widget_communication_error.py | 6 ++++++ src/ipyaladin/widget.py | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 src/ipyaladin/errors/widget_communication_error.py diff --git a/src/ipyaladin/errors/widget_communication_error.py b/src/ipyaladin/errors/widget_communication_error.py new file mode 100644 index 00000000..a77b3e73 --- /dev/null +++ b/src/ipyaladin/errors/widget_communication_error.py @@ -0,0 +1,6 @@ +class WidgetCommunicationError(OSError): + """Error raised when there is a communication error with the widget.""" + + def __init__(self, message: str) -> None: + self.message = message + super(WidgetCommunicationError, self).__init__(message) diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index 4d919186..91e9cf3e 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -21,6 +21,8 @@ import traitlets from astropy.wcs import WCS +from .errors.widget_communication_error import WidgetCommunicationError + try: from regions import ( CircleSkyRegion, @@ -202,7 +204,7 @@ def wcs(self) -> WCS: """ if self._wcs == {}: - raise ValueError( + raise WidgetCommunicationError( "The world coordinate system is not available. " "Please recover it from another cell." ) @@ -221,7 +223,7 @@ def fov_xy(self) -> Tuple[Angle, Angle]: """ if self._fov_xy == {}: - raise ValueError( + raise WidgetCommunicationError( "The field of view along the two axes is not available. " "Please recover it from another cell." ) From 972cab58945893db41918cbbbf4acc625ac6b613 Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Thu, 18 Jul 2024 17:34:59 +0200 Subject: [PATCH 17/24] refactor: create a utils submodule --- src/ipyaladin/utils/__init__.py | 0 src/ipyaladin/{ => utils}/coordinate_parser.py | 0 .../widget_communication_error.py => utils/exceptions.py} | 0 src/ipyaladin/{ => utils}/region_converter.py | 0 src/ipyaladin/widget.py | 6 +++--- src/test/test_aladin.py | 2 +- src/test/test_coordinate_parser.py | 2 +- 7 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 src/ipyaladin/utils/__init__.py rename src/ipyaladin/{ => utils}/coordinate_parser.py (100%) rename src/ipyaladin/{errors/widget_communication_error.py => utils/exceptions.py} (100%) rename src/ipyaladin/{ => utils}/region_converter.py (100%) diff --git a/src/ipyaladin/utils/__init__.py b/src/ipyaladin/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/ipyaladin/coordinate_parser.py b/src/ipyaladin/utils/coordinate_parser.py similarity index 100% rename from src/ipyaladin/coordinate_parser.py rename to src/ipyaladin/utils/coordinate_parser.py diff --git a/src/ipyaladin/errors/widget_communication_error.py b/src/ipyaladin/utils/exceptions.py similarity index 100% rename from src/ipyaladin/errors/widget_communication_error.py rename to src/ipyaladin/utils/exceptions.py diff --git a/src/ipyaladin/region_converter.py b/src/ipyaladin/utils/region_converter.py similarity index 100% rename from src/ipyaladin/region_converter.py rename to src/ipyaladin/utils/region_converter.py diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index 91e9cf3e..23141a79 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -21,7 +21,7 @@ import traitlets from astropy.wcs import WCS -from .errors.widget_communication_error import WidgetCommunicationError +from .utils.exceptions import WidgetCommunicationError try: from regions import ( @@ -50,7 +50,7 @@ default, ) -from .coordinate_parser import parse_coordinate_string +from .utils.coordinate_parser import parse_coordinate_string SupportedRegion = Union[ typing.List[ @@ -534,7 +534,7 @@ def add_graphic_overlay_from_region( "See the documentation for the supported region types." ) - from .region_converter import RegionInfos + from .utils.region_converter import RegionInfos # Define behavior for each region type regions_infos.append(RegionInfos(region_element).to_clean_dict()) diff --git a/src/test/test_aladin.py b/src/test/test_aladin.py index 4ff155cf..14a42cac 100644 --- a/src/test/test_aladin.py +++ b/src/test/test_aladin.py @@ -4,7 +4,7 @@ from typing import Callable from ipyaladin import Aladin -from ipyaladin.coordinate_parser import parse_coordinate_string +from ipyaladin.utils.coordinate_parser import parse_coordinate_string from .test_coordinate_parser import test_is_coordinate_string_values diff --git a/src/test/test_coordinate_parser.py b/src/test/test_coordinate_parser.py index 9282f2b0..bcd5d3f1 100644 --- a/src/test/test_coordinate_parser.py +++ b/src/test/test_coordinate_parser.py @@ -1,5 +1,5 @@ from typing import Tuple -from ipyaladin.coordinate_parser import ( +from ipyaladin.utils.coordinate_parser import ( parse_coordinate_string, _split_coordinate_string, _is_hour_angle_string, From 0500082e52d32f4e374c2a4f363742d25a45e36f Mon Sep 17 00:00:00 2001 From: Xen0Xys Date: Fri, 19 Jul 2024 14:16:09 +0200 Subject: [PATCH 18/24] :sparkles: Add support for multiple Aladin Lite instances Data will be exported from the last created one --- js/models/event_handler.js | 76 ++++++++++++++++++++++++------------ js/models/message_handler.js | 2 - js/utils.js | 13 +++++- js/widget.js | 13 +++--- 4 files changed, 72 insertions(+), 32 deletions(-) diff --git a/js/models/event_handler.js b/js/models/event_handler.js index 0406e99f..d0b4dbfb 100644 --- a/js/models/event_handler.js +++ b/js/models/event_handler.js @@ -1,5 +1,5 @@ import MessageHandler from "./message_handler"; -import { Lock } from "../utils"; +import { divNumber, Lock } from "../utils"; export default class EventHandler { /** @@ -15,6 +15,45 @@ export default class EventHandler { this.messageHandler = new MessageHandler(aladin, model); } + /** + * Checks if the current div is the last active div. + * @returns {boolean} + */ + isLastDiv() { + let maxDiv = divNumber; + for (let i = maxDiv; i >= 0; i--) { + const alDiv = document.getElementById(`aladin-lite-div-${i}`); + if (!alDiv) continue; + if (alDiv.style.display !== "none") { + maxDiv = i; + break; + } + } + return parseInt(this.aladinDiv.id.split("-").pop()) === maxDiv; + } + + /** + * Updates the WCS coordinates in the model. + * WARNING: This method don't call model.save_changes()! + */ + updateWCS() { + if (!this.isLastDiv()) return; + this.model.set("_wcs", this.aladin.getViewWCS()); + } + + /** + * Updates the 2-axis FoV in the model. + * WARNING: This method don't call model.save_changes()! + */ + update2AxisFoV() { + if (!this.isLastDiv()) return; + const twoAxisFoV = this.aladin.getFov(); + this.model.set("_fov_xy", { + x: twoAxisFoV[0], + y: twoAxisFoV[1], + }); + } + /** * Subscribes to all the events needed for the Aladin Lite widget. */ @@ -42,7 +81,7 @@ export default class EventHandler { } jsTargetLock.lock(); const raDec = [position.ra, position.dec]; - this.model.set("_wcs", this.aladin.getViewWCS()); + this.updateWCS(); this.model.set("_target", `${raDec[0]} ${raDec[1]}`); this.model.save_changes(); }); @@ -69,13 +108,9 @@ export default class EventHandler { } jsFovLock.lock(); // fov MUST be cast into float in order to be sent to the model - this.model.set("_wcs", this.aladin.getViewWCS()); + this.updateWCS(); + this.update2AxisFoV(); this.model.set("_fov", parseFloat(fov.toFixed(5))); - const twoAxisFoV = this.aladin.getFov(); - this.model.set("_fov_xy", { - x: twoAxisFoV[0], - y: twoAxisFoV[1], - }); this.model.save_changes(); }); @@ -93,41 +128,33 @@ export default class EventHandler { this.model.on("change:_height", () => { let height = this.model.get("_height"); this.aladinDiv.style.height = `${height}px`; - // Update WCS and FoV - this.model.set("_wcs", this.aladin.getViewWCS()); - const twoAxisFoV = this.aladin.getFov(); - this.model.set("_fov_xy", { - x: twoAxisFoV[0], - y: twoAxisFoV[1], - }); + // Update WCS and FoV only if this is the last div + this.updateWCS(); + this.update2AxisFoV(); this.model.save_changes(); }); /* Aladin callbacks */ this.aladin.on("cooFrameChanged", () => { - this.model.set("_wcs", this.aladin.getViewWCS()); + this.updateWCS(); this.model.save_changes(); }); this.aladin.on("projectionChanged", () => { - this.model.set("_wcs", this.aladin.getViewWCS()); + this.updateWCS(); this.model.save_changes(); }); this.aladin.on("layerChanged", (_, layerName, state) => { if (layerName !== "base" || state !== "ADDED") return; - this.model.set("_wcs", this.aladin.getViewWCS()); + this.updateWCS(); this.model.save_changes(); }); this.aladin.on("resizeChanged", () => { - this.model.set("_wcs", this.aladin.getViewWCS()); - const twoAxisFoV = this.aladin.getFov(); - this.model.set("_fov_xy", { - x: twoAxisFoV[0], - y: twoAxisFoV[1], - }); + this.updateWCS(); + this.update2AxisFoV(); this.model.save_changes(); }); @@ -163,6 +190,7 @@ export default class EventHandler { }); this.aladin.on("click", (clickContent) => { + console.log("Click", this.isLastDiv()); this.model.send({ event_type: "click", content: clickContent, diff --git a/js/models/message_handler.js b/js/models/message_handler.js index 28294c7e..76fd9a25 100644 --- a/js/models/message_handler.js +++ b/js/models/message_handler.js @@ -30,8 +30,6 @@ export default class MessageHandler { URL.revokeObjectURL(url); }); this.aladin.setOverlayImageLayer(image, options.name); - // this.model.set("_wcs", this.aladin.getViewWCS()); - // this.model.save_changes(); } handleAddCatalogFromURL(msg) { diff --git a/js/utils.js b/js/utils.js index 41cc3660..d2ac7295 100644 --- a/js/utils.js +++ b/js/utils.js @@ -41,4 +41,15 @@ class Lock { } } -export { snakeCaseToCamelCase, convertOptionNamesToCamelCase, Lock }; +let divNumber = -1; +function setDivNumber(num) { + divNumber = num; +} + +export { + snakeCaseToCamelCase, + convertOptionNamesToCamelCase, + Lock, + divNumber, + setDivNumber, +}; diff --git a/js/widget.js b/js/widget.js index 3be29317..778d1872 100644 --- a/js/widget.js +++ b/js/widget.js @@ -1,11 +1,15 @@ import "./widget.css"; import EventHandler from "./models/event_handler"; -import { snakeCaseToCamelCase } from "./utils"; +import { + divNumber, + getDivNumber, + setDivNumber, + snakeCaseToCamelCase, +} from "./utils"; import A from "./aladin_lite"; -let idxView = 0; - function initAladinLite(model, el) { + setDivNumber(divNumber + 1); let initOptions = {}; model.get("init_options").forEach((option_name) => { initOptions[snakeCaseToCamelCase(option_name)] = model.get(option_name); @@ -15,9 +19,8 @@ function initAladinLite(model, el) { aladinDiv.classList.add("aladin-widget"); aladinDiv.style.height = `${initOptions["height"]}px`; - aladinDiv.id = `aladin-lite-div-${idxView}`; + aladinDiv.id = `aladin-lite-div-${divNumber}`; let aladin = new A.aladin(aladinDiv, initOptions); - idxView += 1; // Set the target again after the initialization to be sure that the target is set // from icrs coordinates because of the use of gotoObject in the Aladin Lite API From 45662fda32cee6a707373bafaeb33051414a4117 Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Mon, 22 Jul 2024 12:45:18 +0200 Subject: [PATCH 19/24] maint: sort imports --- src/ipyaladin/widget.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index 23141a79..790b6e65 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -8,20 +8,20 @@ import io import pathlib from pathlib import Path -import typing -from typing import ClassVar, Union, Final, Optional, Tuple +from typing import ClassVar, Dict, Final, List, Optional, Tuple, Union import warnings import anywidget +from astropy.coordinates import SkyCoord, Angle from astropy.table.table import QTable from astropy.table import Table -from astropy.coordinates import SkyCoord, Angle from astropy.io import fits as astropy_fits from astropy.io.fits import HDUList -import traitlets from astropy.wcs import WCS +import traitlets from .utils.exceptions import WidgetCommunicationError +from .utils.coordinate_parser import parse_coordinate_string try: from regions import ( @@ -50,10 +50,8 @@ default, ) -from .utils.coordinate_parser import parse_coordinate_string - SupportedRegion = Union[ - typing.List[ + List[ Union[ CircleSkyRegion, EllipseSkyRegion, @@ -136,7 +134,7 @@ class Aladin(anywidget.AnyWidget): # content of the last click clicked_object = traitlets.Dict().tag(sync=True) # listener callback is on the python side and contains functions to link to events - listener_callback: ClassVar[typing.Dict[str, callable]] = {} + listener_callback: ClassVar[Dict[str, callable]] = {} # overlay survey overlay_survey = Unicode("").tag(sync=True, init_option=True) @@ -145,7 +143,7 @@ class Aladin(anywidget.AnyWidget): init_options = traitlets.List(trait=Any()).tag(sync=True) @default("init_options") - def _init_options(self) -> typing.List[str]: + def _init_options(self) -> List[str]: return list(self.traits(init_option=True)) def __init__(self, *args: any, **kwargs: any) -> None: @@ -548,7 +546,7 @@ def add_graphic_overlay_from_region( ) def add_overlay_from_stcs( - self, stc_string: Union[typing.List[str], str], **overlay_options: any + self, stc_string: Union[List[str], str], **overlay_options: any ) -> None: """Add an overlay layer defined by an STC-S string. @@ -569,7 +567,7 @@ def add_overlay_from_stcs( self.add_graphic_overlay_from_stcs(stc_string, **overlay_options) def add_graphic_overlay_from_stcs( - self, stc_string: Union[typing.List[str], str], **overlay_options: any + self, stc_string: Union[List[str], str], **overlay_options: any ) -> None: """Add an overlay layer defined by an STC-S string. From 49c17db1035c505be1e342f9fda0dde19da64809 Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Mon, 22 Jul 2024 12:52:11 +0200 Subject: [PATCH 20/24] fix: avoid most getElementById calls --- js/models/event_handler.js | 10 +++++++--- js/widget.js | 7 +------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/js/models/event_handler.js b/js/models/event_handler.js index d0b4dbfb..f6fe0253 100644 --- a/js/models/event_handler.js +++ b/js/models/event_handler.js @@ -1,5 +1,5 @@ import MessageHandler from "./message_handler"; -import { divNumber, Lock } from "../utils"; +import { divNumber, setDivNumber, Lock } from "../utils"; export default class EventHandler { /** @@ -20,6 +20,10 @@ export default class EventHandler { * @returns {boolean} */ isLastDiv() { + let currentDivNumber = parseInt(this.aladinDiv.id.split("-").pop()); + if (currentDivNumber === divNumber) { + return true; + } let maxDiv = divNumber; for (let i = maxDiv; i >= 0; i--) { const alDiv = document.getElementById(`aladin-lite-div-${i}`); @@ -29,7 +33,8 @@ export default class EventHandler { break; } } - return parseInt(this.aladinDiv.id.split("-").pop()) === maxDiv; + setDivNumber(maxDiv); + return currentDivNumber === maxDiv; } /** @@ -190,7 +195,6 @@ export default class EventHandler { }); this.aladin.on("click", (clickContent) => { - console.log("Click", this.isLastDiv()); this.model.send({ event_type: "click", content: clickContent, diff --git a/js/widget.js b/js/widget.js index 778d1872..b2e13fc0 100644 --- a/js/widget.js +++ b/js/widget.js @@ -1,11 +1,6 @@ import "./widget.css"; import EventHandler from "./models/event_handler"; -import { - divNumber, - getDivNumber, - setDivNumber, - snakeCaseToCamelCase, -} from "./utils"; +import { divNumber, setDivNumber, snakeCaseToCamelCase } from "./utils"; import A from "./aladin_lite"; function initAladinLite(model, el) { From a4ab722f05aac48e5b4d65913407aaf4fcaf2233 Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Mon, 22 Jul 2024 12:52:55 +0200 Subject: [PATCH 21/24] fix: don't empty fov_xy if fov does not change --- src/ipyaladin/widget.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ipyaladin/widget.py b/src/ipyaladin/widget.py index 790b6e65..9f528bd9 100644 --- a/src/ipyaladin/widget.py +++ b/src/ipyaladin/widget.py @@ -18,6 +18,7 @@ from astropy.io import fits as astropy_fits from astropy.io.fits import HDUList from astropy.wcs import WCS +import numpy as np import traitlets from .utils.exceptions import WidgetCommunicationError @@ -185,7 +186,7 @@ def height(self) -> int: @height.setter def height(self, height: int) -> None: - if self._height == height: + if np.isclose(self._height, height): return self._wcs = {} self._fov_xy = {} @@ -250,6 +251,8 @@ def fov(self, fov: Union[float, Angle]) -> None: if isinstance(fov, Angle): fov = fov.deg self._fov = fov + if np.isclose(fov, self._fov): + return self._fov_xy = {} self._wcs = {} self.send({"event_name": "change_fov", "fov": fov}) From d51920e2e23888d0ca1372b4a5a1695588ad60ca Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Mon, 22 Jul 2024 12:56:31 +0200 Subject: [PATCH 22/24] docs: edit info extractions --- ...Extracting_information_from_the_view.ipynb | 309 +++++++++++++++--- 1 file changed, 267 insertions(+), 42 deletions(-) diff --git a/examples/11_Extracting_information_from_the_view.ipynb b/examples/11_Extracting_information_from_the_view.ipynb index 67eda70c..89e37514 100644 --- a/examples/11_Extracting_information_from_the_view.ipynb +++ b/examples/11_Extracting_information_from_the_view.ipynb @@ -1,109 +1,334 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "98601fdf-e2df-46c9-b039-710e45aabfdc", + "metadata": {}, + "source": [ + "# Retrieving data from the current widget's view\n", + "\n", + "So far, we've seen how to send information (tables, MOCs, ...) into the widget. The other way also works! Here are a list of methods to extract diverse information about the current view:" + ] + }, { "cell_type": "code", + "execution_count": 1, "id": "initial_id", - "metadata": { - "collapsed": true - }, + "metadata": {}, + "outputs": [], "source": [ "from ipyaladin import Aladin" - ], - "outputs": [], - "execution_count": null + ] }, { "cell_type": "code", + "execution_count": 2, "id": "2e62d34eb8543145", "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "8609c7b19f7644acb71ce3a258199fd9", + "version_major": 2, + "version_minor": 1 + }, + "text/plain": [ + "Aladin(init_options=['_fov', '_height', '_target', 'background_color', 'coo_frame', 'full_screen', 'grid_color…" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "aladin = Aladin(fov=5, height=600, target=\"M31\")\n", "aladin" - ], - "outputs": [], - "execution_count": null + ] }, { "cell_type": "markdown", - "id": "54a2d7bb2777de3b", + "id": "ae0a5496-d621-49ef-a11a-3578c272ce92", "metadata": {}, "source": [ - "# Extracting information from the view\n", - "## Extracting values\n", - "Currently, ipyaladin allow you to recover some values from the Aladin Lite instance. These values are:\n", - "- The World Coordinate System (WCS)\n", - "- The field of view for the x and y axis\n", - "You can recover these values by calling the corresponding attribute." + "## Getting the current WCS\n", + "\n", + "The World Coordinates System (WCS) describes the field of view, the projection, and it's rotation. It is returned as an `astropy.coordinates.WCS` object." ] }, { "cell_type": "code", + "execution_count": 3, "id": "84153657cb7cd837", "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "WCS Keywords\n", + "\n", + "Number of WCS axes: 2\n", + "CTYPE : 'RA---SIN' 'DEC--SIN' \n", + "CRVAL : 10.6847083 41.26875 \n", + "CRPIX : 929.0 300.5 \n", + "PC1_1 PC1_2 : 1.0 0.0 \n", + "PC2_1 PC2_2 : 0.0 1.0 \n", + "CDELT : -0.00269251480883144 0.002692514808831448 \n", + "NAXIS : 1857 600" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "aladin.wcs # Recover the current WCS" - ], - "outputs": [], - "execution_count": null + ] }, { - "cell_type": "code", - "id": "9595ae02388b245a", + "cell_type": "markdown", + "id": "998def1f-3963-405b-8be2-6d4ef4012634", "metadata": {}, "source": [ - "aladin.fov_xy # Recover the current field of view for the x and y axis" - ], + "If you edit the view either by modifiing the widget through its interface, or programmatically: " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a63f210b-3a64-4860-8e70-42a4c66378fa", + "metadata": {}, "outputs": [], - "execution_count": null + "source": [ + "aladin.height = 800\n", + "aladin.survey = \"CDS/P/PLANCK/R2/HFI/color\"\n", + "aladin.target = \"LMC\"\n", + "aladin.fov = 50" + ] }, { "cell_type": "markdown", - "id": "870935d9c4e2aaa", + "id": "9c2221f3-6ecc-46d6-9d53-5dbefa71326d", "metadata": {}, "source": [ - "## Changing values\n", - "If you change a value that affects the value you want to extract, you need to extract this value in the next cell." + "The wcs is updated and you can print its new value in the **next cell**:" ] }, { "cell_type": "code", - "id": "dfdc3a54019d7e34", + "execution_count": 5, + "id": "2ddc9637-b5c3-4412-8435-2302b6d86816", "metadata": {}, - "source": [ - "aladin.target = \"M33\"\n", - "aladin.fov = 2" + "outputs": [ + { + "data": { + "text/plain": [ + "WCS Keywords\n", + "\n", + "Number of WCS axes: 2\n", + "CTYPE : 'RA---SIN' 'DEC--SIN' \n", + "CRVAL : 80.89416999999995 -69.75611 \n", + "CRPIX : 929.0 400.5 \n", + "PC1_1 PC1_2 : 1.0 0.0 \n", + "PC2_1 PC2_2 : 0.0 1.0 \n", + "CDELT : -0.00269251480883144 0.002692514808831449 \n", + "NAXIS : 1857 800" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } ], - "outputs": [], - "execution_count": null + "source": [ + "aladin.wcs" + ] }, { - "cell_type": "code", - "id": "ad62fb2664e45a30", + "cell_type": "markdown", + "id": "f5add3a2-be30-488e-86df-426338b98f5d", "metadata": {}, "source": [ - "aladin.wcs # This will represent the new WCS" + "If you try to recover the value in the same cell, you'll get a `WidgetCommunicationError` error. This is because the calculation of the WCS is done by Aladin Lite *between* cell exceutions. \n", + "\n", + "## Getting the field of view\n", + "\n", + "The field of view is printed in the bottom left corner of the view. You can grab the two values with:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "9595ae02388b245a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(, )" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } ], - "outputs": [], - "execution_count": null + "source": [ + "aladin.fov_xy # Recover the current field of view for the x and y axis" + ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" + "pygments_lexer": "ipython3", + "version": "3.11.8" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": { + "8609c7b19f7644acb71ce3a258199fd9": { + "model_module": "anywidget", + "model_module_version": "0.9.10", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "ipyaladin.widget.Aladin", + "_css": ".cell-output-ipywidget-background{background:transparent}.jp-OutputArea-output,.aladin-widget{background-color:transparent}.aladin-widget .aladin-measurement-div{max-height:100px}\n/*# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vanMvd2lkZ2V0LmNzcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLmNlbGwtb3V0cHV0LWlweXdpZGdldC1iYWNrZ3JvdW5kIHtcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG59XG4uanAtT3V0cHV0QXJlYS1vdXRwdXQge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbn1cbi5hbGFkaW4td2lkZ2V0IHtcbiAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7XG59XG4uYWxhZGluLXdpZGdldCAuYWxhZGluLW1lYXN1cmVtZW50LWRpdiB7XG4gIG1heC1oZWlnaHQ6IDEwMHB4O1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIkFBQUEsQ0FBQyxpQ0FDQyxXQUFZLFdBQ2QsQ0FDQSxDQUFDLHFCQUdELENBQUMsY0FGQyxpQkFBa0IsV0FDcEIsQ0FJQSxDQUhDLGNBR2MsQ0FBQyx1QkFDZCxXQUFZLEtBQ2QiLAogICJuYW1lcyI6IFtdCn0K */\n", + "_esm": "function f(s){s.charAt(0)===\"_\"&&(s=s.slice(1));let e=s.split(\"_\");for(let a=1;a{this.aladin.gotoRaDec(r,v),console.info(`FITS located at ra: ${r}, dec: ${v}`),URL.revokeObjectURL(o)});this.aladin.setOverlayImageLayer(d,i.name)}handleAddCatalogFromURL(e){let a=h(e.options||{});this.aladin.addCatalog(l.catalogFromURL(e.votable_URL,a))}handleAddMOCFromURL(e){let a=h(e.options||{});this.aladin.addMOC(l.MOCFromURL(e.moc_URL,a))}handleAddMOCFromDict(e){let a=h(e.options||{});this.aladin.addMOC(l.MOCFromJSON(e.moc_dict,a))}handleAddOverlay(e){let a=e.regions_infos,i=h(e.graphic_options||{});i.color||(i.color=\"red\");let n=l.graphicOverlay(i);this.aladin.addOverlay(n);for(let t of a){let o=t.infos;switch(t.region_type){case\"stcs\":n.addFootprints(l.footprintsFromSTCS(o.stcs,t.options));break;case\"circle\":n.add(l.circle(o.ra,o.dec,o.radius,t.options));break;case\"ellipse\":n.add(l.ellipse(o.ra,o.dec,o.a,o.b,o.theta,t.options));break;case\"line\":t.options.lineWidth=t.options.lineWidth||3,n.add(l.vector(o.ra1,o.dec1,o.ra2,o.dec2,t.options));break;case\"polygon\":n.add(l.polygon(o.vertices,t.options));break}}}handleChangeColormap(e){this.aladin.getBaseImageLayer().setColormap(e.colormap)}handleGetJPGThumbnail(){this.aladin.exportAsPNG()}handleTriggerRectangularSelection(){this.aladin.select()}handleAddTable(e,a){let i=h(e.options||{}),n=a[0].buffer,t=new TextDecoder(\"utf-8\"),o=new Blob([t.decode(n)]),d=URL.createObjectURL(o);l.catalogFromURL(d,Object.assign(i,{onClick:\"showTable\"}),r=>{this.aladin.addCatalog(r)},!1),URL.revokeObjectURL(d)}};var p=class{constructor(e,a,i){this.aladin=e,this.aladinDiv=a,this.model=i,this.messageHandler=new g(e,i)}isLastDiv(){let e=parseInt(this.aladinDiv.id.split(\"-\").pop());if(e===m)return!0;let a=m;for(let i=a;i>=0;i--){let n=document.getElementById(`aladin-lite-div-${i}`);if(n&&n.style.display!==\"none\"){a=i;break}}return u(a),e===a}updateWCS(){this.isLastDiv()&&this.model.set(\"_wcs\",this.aladin.getViewWCS())}update2AxisFoV(){if(!this.isLastDiv())return;let e=this.aladin.getFov();this.model.set(\"_fov_xy\",{x:e[0],y:e[1]})}subscribeAll(){let e=new c,a=new c;this.aladin.on(\"positionChanged\",t=>{if(a.locked){a.unlock();return}e.lock();let o=[t.ra,t.dec];this.updateWCS(),this.model.set(\"_target\",`${o[0]} ${o[1]}`),this.model.save_changes()}),this.model.on(\"change:_target\",()=>{if(e.locked){e.unlock();return}a.lock();let t=this.model.get(\"_target\"),[o,d]=t.split(\" \");this.aladin.gotoRaDec(o,d)});let i=new c,n=new c;this.aladin.on(\"zoomChanged\",t=>{if(n.locked){n.unlock();return}i.lock(),this.updateWCS(),this.update2AxisFoV(),this.model.set(\"_fov\",parseFloat(t.toFixed(5))),this.model.save_changes()}),this.model.on(\"change:_fov\",()=>{if(i.locked){i.unlock();return}n.lock();let t=this.model.get(\"_fov\");this.aladin.setFoV(t)}),this.model.on(\"change:_height\",()=>{let t=this.model.get(\"_height\");this.aladinDiv.style.height=`${t}px`,this.updateWCS(),this.update2AxisFoV(),this.model.save_changes()}),this.aladin.on(\"cooFrameChanged\",()=>{this.updateWCS(),this.model.save_changes()}),this.aladin.on(\"projectionChanged\",()=>{this.updateWCS(),this.model.save_changes()}),this.aladin.on(\"layerChanged\",(t,o,d)=>{o!==\"base\"||d!==\"ADDED\"||(this.updateWCS(),this.model.save_changes())}),this.aladin.on(\"resizeChanged\",()=>{this.updateWCS(),this.update2AxisFoV(),this.model.save_changes()}),this.aladin.on(\"objectHovered\",t=>{t.data!==void 0&&this.model.send({event_type:\"object_hovered\",content:{ra:t.ra,dec:t.dec}})}),this.aladin.on(\"objectClicked\",t=>{if(t){let o={ra:t.ra,dec:t.dec};t.data!==void 0&&(o.data=t.data),this.model.set(\"clicked_object\",o),this.model.send({event_type:\"object_clicked\",content:o}),this.model.save_changes()}}),this.aladin.on(\"click\",t=>{this.model.send({event_type:\"click\",content:t})}),this.aladin.on(\"select\",t=>{let o=[];t.forEach(d=>{d.forEach(r=>{o.push({ra:r.ra,dec:r.dec,data:r.data,x:r.x,y:r.y})})}),this.model.send({event_type:\"select\",content:o})}),this.model.on(\"change:coo_frame\",()=>{this.aladin.setFrame(this.model.get(\"coo_frame\"))}),this.model.on(\"change:survey\",()=>{this.aladin.setImageSurvey(this.model.get(\"survey\"))}),this.model.on(\"change:overlay_survey\",()=>{this.aladin.setOverlayImageLayer(this.model.get(\"overlay_survey\"))}),this.model.on(\"change:overlay_survey_opacity\",()=>{this.aladin.getOverlayImageLayer().setAlpha(this.model.get(\"overlay_survey_opacity\"))}),this.eventHandlers={change_fov:this.messageHandler.handleChangeFoV,goto_ra_dec:this.messageHandler.handleGotoRaDec,add_fits:this.messageHandler.handleAddFits,add_catalog_from_URL:this.messageHandler.handleAddCatalogFromURL,add_MOC_from_URL:this.messageHandler.handleAddMOCFromURL,add_MOC_from_dict:this.messageHandler.handleAddMOCFromDict,add_overlay:this.messageHandler.handleAddOverlay,change_colormap:this.messageHandler.handleChangeColormap,get_JPG_thumbnail:this.messageHandler.handleGetJPGThumbnail,trigger_rectangular_selection:this.messageHandler.handleTriggerRectangularSelection,add_table:this.messageHandler.handleAddTable},this.model.on(\"msg:custom\",(t,o)=>{let d=t.event_name,r=this.eventHandlers[d];if(r)r.call(this,t,o);else throw new Error(`Unknown event name: ${d}`)})}unsubscribeAll(){this.model.off(\"change:_target\"),this.model.off(\"change:_fov\"),this.model.off(\"change:_height\"),this.model.off(\"change:coo_frame\"),this.model.off(\"change:survey\"),this.model.off(\"change:overlay_survey\"),this.model.off(\"change:overlay_survey_opacity\"),this.model.off(\"change:trigger_event\"),this.model.off(\"msg:custom\")}};function C(s,e){u(m+1);let a={};s.get(\"init_options\").forEach(d=>{a[f(d)]=s.get(d)});let i=document.createElement(\"div\");i.classList.add(\"aladin-widget\"),i.style.height=`${a.height}px`,i.id=`aladin-lite-div-${m}`;let n=new l.aladin(i,a),t=a.target.split(\" \");n.gotoRaDec(t[0],t[1]);let o=n.getFov();return s.set(\"_fov_xy\",{x:o[0],y:o[1]}),s.set(\"_wcs\",n.getViewWCS()),s.save_changes(),e.appendChild(i),{aladin:n,aladinDiv:i}}async function b({model:s}){await l.init}function k({model:s,el:e}){let{aladin:a,aladinDiv:i}=C(s,e),n=new p(a,i,s);return n.subscribeAll(),()=>{n.unsubscribeAll()}}var j={initialize:b,render:k};export{j as default};\n//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vanMvdXRpbHMuanMiLCAiLi4vLi4vLi4vanMvYWxhZGluX2xpdGUuanMiLCAiLi4vLi4vLi4vanMvbW9kZWxzL21lc3NhZ2VfaGFuZGxlci5qcyIsICIuLi8uLi8uLi9qcy9tb2RlbHMvZXZlbnRfaGFuZGxlci5qcyIsICIuLi8uLi8uLi9qcy93aWRnZXQuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQ29udmVydHMgYSBzdHJpbmcgZnJvbSBjYW1lbENhc2UgdG8gc25ha2VfY2FzZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzbmFrZUNhc2VTdHIgLSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgc3RyaW5nIGNvbnZlcnRlZCB0byBzbmFrZV9jYXNlLlxuICovXG5mdW5jdGlvbiBzbmFrZUNhc2VUb0NhbWVsQ2FzZShzbmFrZUNhc2VTdHIpIHtcbiAgaWYgKHNuYWtlQ2FzZVN0ci5jaGFyQXQoMCkgPT09IFwiX1wiKSBzbmFrZUNhc2VTdHIgPSBzbmFrZUNhc2VTdHIuc2xpY2UoMSk7XG4gIGxldCB0ZW1wID0gc25ha2VDYXNlU3RyLnNwbGl0KFwiX1wiKTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCB0ZW1wLmxlbmd0aDsgaSsrKVxuICAgIHRlbXBbaV0gPSB0ZW1wW2ldLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgdGVtcFtpXS5zbGljZSgxKTtcbiAgcmV0dXJuIHRlbXAuam9pbihcIlwiKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvcHRpb24gbmFtZXMgaW4gYW4gb2JqZWN0IGZyb20gc25ha2VfY2FzZSB0byBjYW1lbENhc2UuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIG9iamVjdCB3aXRoIHNuYWtlX2Nhc2UgcHJvcGVydHkgbmFtZXMuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBBbiBvYmplY3Qgd2l0aCBwcm9wZXJ0eSBuYW1lcyBjb252ZXJ0ZWQgdG8gY2FtZWxDYXNlLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0T3B0aW9uTmFtZXNUb0NhbWVsQ2FzZShvcHRpb25zKSB7XG4gIGNvbnN0IG5ld09wdGlvbnMgPSB7fTtcbiAgZm9yIChjb25zdCBvcHRpb25OYW1lIGluIG9wdGlvbnMpXG4gICAgbmV3T3B0aW9uc1tzbmFrZUNhc2VUb0NhbWVsQ2FzZShvcHRpb25OYW1lKV0gPSBvcHRpb25zW29wdGlvbk5hbWVdO1xuICByZXR1cm4gbmV3T3B0aW9ucztcbn1cblxuY2xhc3MgTG9jayB7XG4gIGxvY2tlZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBVbmxvY2tzIHRoZSBvYmplY3RcbiAgICovXG4gIHVubG9jaygpIHtcbiAgICB0aGlzLmxvY2tlZCA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIExvY2tzIHRoZSBvYmplY3RcbiAgICovXG4gIGxvY2soKSB7XG4gICAgdGhpcy5sb2NrZWQgPSB0cnVlO1xuICB9XG59XG5cbmxldCBkaXZOdW1iZXIgPSAtMTtcbmZ1bmN0aW9uIHNldERpdk51bWJlcihudW0pIHtcbiAgZGl2TnVtYmVyID0gbnVtO1xufVxuXG5leHBvcnQge1xuICBzbmFrZUNhc2VUb0NhbWVsQ2FzZSxcbiAgY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UsXG4gIExvY2ssXG4gIGRpdk51bWJlcixcbiAgc2V0RGl2TnVtYmVyLFxufTtcbiIsICJpbXBvcnQgQSBmcm9tIFwiaHR0cHM6Ly9lc20uc2gvYWxhZGluLWxpdGVAMy40LjUtYmV0YVwiO1xuXG5leHBvcnQgZGVmYXVsdCBBO1xuIiwgImltcG9ydCB7IGNvbnZlcnRPcHRpb25OYW1lc1RvQ2FtZWxDYXNlIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgQSBmcm9tIFwiLi4vYWxhZGluX2xpdGVcIjtcblxubGV0IGltYWdlQ291bnQgPSAwO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZXNzYWdlSGFuZGxlciB7XG4gIGNvbnN0cnVjdG9yKGFsYWRpbiwgbW9kZWwpIHtcbiAgICB0aGlzLmFsYWRpbiA9IGFsYWRpbjtcbiAgICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gIH1cblxuICBoYW5kbGVDaGFuZ2VGb1YobXNnKSB7XG4gICAgdGhpcy5hbGFkaW4uc2V0Rm9WKG1zZ1tcImZvdlwiXSk7XG4gIH1cblxuICBoYW5kbGVHb3RvUmFEZWMobXNnKSB7XG4gICAgdGhpcy5hbGFkaW4uZ290b1JhRGVjKG1zZ1tcInJhXCJdLCBtc2dbXCJkZWNcIl0pO1xuICB9XG5cbiAgaGFuZGxlQWRkRml0cyhtc2csIGJ1ZmZlcnMpIHtcbiAgICBjb25zdCBvcHRpb25zID0gY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UobXNnW1wib3B0aW9uc1wiXSB8fCB7fSk7XG4gICAgaWYgKCFvcHRpb25zLm5hbWUpXG4gICAgICBvcHRpb25zLm5hbWUgPSBgaW1hZ2VfJHtTdHJpbmcoKytpbWFnZUNvdW50KS5wYWRTdGFydCgzLCBcIjBcIil9YDtcbiAgICBjb25zdCBidWZmZXIgPSBidWZmZXJzWzBdO1xuICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbYnVmZmVyXSwgeyB0eXBlOiBcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiIH0pO1xuICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgY29uc3QgaW1hZ2UgPSB0aGlzLmFsYWRpbi5jcmVhdGVJbWFnZUZJVFModXJsLCBvcHRpb25zLCAocmEsIGRlYykgPT4ge1xuICAgICAgdGhpcy5hbGFkaW4uZ290b1JhRGVjKHJhLCBkZWMpO1xuICAgICAgY29uc29sZS5pbmZvKGBGSVRTIGxvY2F0ZWQgYXQgcmE6ICR7cmF9LCBkZWM6ICR7ZGVjfWApO1xuICAgICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICAgIH0pO1xuICAgIHRoaXMuYWxhZGluLnNldE92ZXJsYXlJbWFnZUxheWVyKGltYWdlLCBvcHRpb25zLm5hbWUpO1xuICB9XG5cbiAgaGFuZGxlQWRkQ2F0YWxvZ0Zyb21VUkwobXNnKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IGNvbnZlcnRPcHRpb25OYW1lc1RvQ2FtZWxDYXNlKG1zZ1tcIm9wdGlvbnNcIl0gfHwge30pO1xuICAgIHRoaXMuYWxhZGluLmFkZENhdGFsb2coQS5jYXRhbG9nRnJvbVVSTChtc2dbXCJ2b3RhYmxlX1VSTFwiXSwgb3B0aW9ucykpO1xuICB9XG5cbiAgaGFuZGxlQWRkTU9DRnJvbVVSTChtc2cpIHtcbiAgICBjb25zdCBvcHRpb25zID0gY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UobXNnW1wib3B0aW9uc1wiXSB8fCB7fSk7XG4gICAgdGhpcy5hbGFkaW4uYWRkTU9DKEEuTU9DRnJvbVVSTChtc2dbXCJtb2NfVVJMXCJdLCBvcHRpb25zKSk7XG4gIH1cblxuICBoYW5kbGVBZGRNT0NGcm9tRGljdChtc2cpIHtcbiAgICBjb25zdCBvcHRpb25zID0gY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UobXNnW1wib3B0aW9uc1wiXSB8fCB7fSk7XG4gICAgdGhpcy5hbGFkaW4uYWRkTU9DKEEuTU9DRnJvbUpTT04obXNnW1wibW9jX2RpY3RcIl0sIG9wdGlvbnMpKTtcbiAgfVxuXG4gIGhhbmRsZUFkZE92ZXJsYXkobXNnKSB7XG4gICAgY29uc3QgcmVnaW9ucyA9IG1zZ1tcInJlZ2lvbnNfaW5mb3NcIl07XG4gICAgY29uc3QgZ3JhcGhpY19vcHRpb25zID0gY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UoXG4gICAgICBtc2dbXCJncmFwaGljX29wdGlvbnNcIl0gfHwge30sXG4gICAgKTtcbiAgICBpZiAoIWdyYXBoaWNfb3B0aW9uc1tcImNvbG9yXCJdKSBncmFwaGljX29wdGlvbnNbXCJjb2xvclwiXSA9IFwicmVkXCI7XG4gICAgY29uc3Qgb3ZlcmxheSA9IEEuZ3JhcGhpY092ZXJsYXkoZ3JhcGhpY19vcHRpb25zKTtcbiAgICB0aGlzLmFsYWRpbi5hZGRPdmVybGF5KG92ZXJsYXkpO1xuICAgIGZvciAoY29uc3QgcmVnaW9uIG9mIHJlZ2lvbnMpIHtcbiAgICAgIGNvbnN0IGluZm9zID0gcmVnaW9uW1wiaW5mb3NcIl07XG4gICAgICBzd2l0Y2ggKHJlZ2lvbltcInJlZ2lvbl90eXBlXCJdKSB7XG4gICAgICAgIGNhc2UgXCJzdGNzXCI6XG4gICAgICAgICAgb3ZlcmxheS5hZGRGb290cHJpbnRzKFxuICAgICAgICAgICAgQS5mb290cHJpbnRzRnJvbVNUQ1MoaW5mb3Muc3RjcywgcmVnaW9uLm9wdGlvbnMpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJjaXJjbGVcIjpcbiAgICAgICAgICBvdmVybGF5LmFkZChcbiAgICAgICAgICAgIEEuY2lyY2xlKGluZm9zLnJhLCBpbmZvcy5kZWMsIGluZm9zLnJhZGl1cywgcmVnaW9uLm9wdGlvbnMpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJlbGxpcHNlXCI6XG4gICAgICAgICAgb3ZlcmxheS5hZGQoXG4gICAgICAgICAgICBBLmVsbGlwc2UoXG4gICAgICAgICAgICAgIGluZm9zLnJhLFxuICAgICAgICAgICAgICBpbmZvcy5kZWMsXG4gICAgICAgICAgICAgIGluZm9zLmEsXG4gICAgICAgICAgICAgIGluZm9zLmIsXG4gICAgICAgICAgICAgIGluZm9zLnRoZXRhLFxuICAgICAgICAgICAgICByZWdpb24ub3B0aW9ucyxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImxpbmVcIjpcbiAgICAgICAgICAvLyByZW1vdmUgZGVmYXVsdCBsaW5lV2lkdGggd2hlbiB3ZSBzd2l0Y2ggdG8gQUwgPiAzLjQuNFxuICAgICAgICAgIHJlZ2lvbi5vcHRpb25zLmxpbmVXaWR0aCA9IHJlZ2lvbi5vcHRpb25zLmxpbmVXaWR0aCB8fCAzO1xuICAgICAgICAgIG92ZXJsYXkuYWRkKFxuICAgICAgICAgICAgQS52ZWN0b3IoXG4gICAgICAgICAgICAgIGluZm9zLnJhMSxcbiAgICAgICAgICAgICAgaW5mb3MuZGVjMSxcbiAgICAgICAgICAgICAgaW5mb3MucmEyLFxuICAgICAgICAgICAgICBpbmZvcy5kZWMyLFxuICAgICAgICAgICAgICByZWdpb24ub3B0aW9ucyxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcInBvbHlnb25cIjpcbiAgICAgICAgICBvdmVybGF5LmFkZChBLnBvbHlnb24oaW5mb3MudmVydGljZXMsIHJlZ2lvbi5vcHRpb25zKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlQ2hhbmdlQ29sb3JtYXAobXNnKSB7XG4gICAgdGhpcy5hbGFkaW4uZ2V0QmFzZUltYWdlTGF5ZXIoKS5zZXRDb2xvcm1hcChtc2dbXCJjb2xvcm1hcFwiXSk7XG4gIH1cblxuICBoYW5kbGVHZXRKUEdUaHVtYm5haWwoKSB7XG4gICAgdGhpcy5hbGFkaW4uZXhwb3J0QXNQTkcoKTtcbiAgfVxuXG4gIGhhbmRsZVRyaWdnZXJSZWN0YW5ndWxhclNlbGVjdGlvbigpIHtcbiAgICB0aGlzLmFsYWRpbi5zZWxlY3QoKTtcbiAgfVxuXG4gIGhhbmRsZUFkZFRhYmxlKG1zZywgYnVmZmVycykge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBjb252ZXJ0T3B0aW9uTmFtZXNUb0NhbWVsQ2FzZShtc2dbXCJvcHRpb25zXCJdIHx8IHt9KTtcbiAgICBjb25zdCBidWZmZXIgPSBidWZmZXJzWzBdLmJ1ZmZlcjtcbiAgICBjb25zdCBkZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKFwidXRmLThcIik7XG4gICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtkZWNvZGVyLmRlY29kZShidWZmZXIpXSk7XG4gICAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICBBLmNhdGFsb2dGcm9tVVJMKFxuICAgICAgdXJsLFxuICAgICAgT2JqZWN0LmFzc2lnbihvcHRpb25zLCB7IG9uQ2xpY2s6IFwic2hvd1RhYmxlXCIgfSksXG4gICAgICAoY2F0YWxvZykgPT4ge1xuICAgICAgICB0aGlzLmFsYWRpbi5hZGRDYXRhbG9nKGNhdGFsb2cpO1xuICAgICAgfSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICB9XG59XG4iLCAiaW1wb3J0IE1lc3NhZ2VIYW5kbGVyIGZyb20gXCIuL21lc3NhZ2VfaGFuZGxlclwiO1xuaW1wb3J0IHsgZGl2TnVtYmVyLCBzZXREaXZOdW1iZXIsIExvY2sgfSBmcm9tIFwiLi4vdXRpbHNcIjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXZlbnRIYW5kbGVyIHtcbiAgLyoqXG4gICAqIENvbnN0cnVjdG9yIGZvciB0aGUgRXZlbnRIYW5kbGVyIGNsYXNzLlxuICAgKiBAcGFyYW0gYWxhZGluIFRoZSBBbGFkaW4gaW5zdGFuY2VcbiAgICogQHBhcmFtIGFsYWRpbkRpdiBUaGUgQWxhZGluIGRpdlxuICAgKiBAcGFyYW0gbW9kZWwgVGhlIG1vZGVsIGluc3RhbmNlXG4gICAqL1xuICBjb25zdHJ1Y3RvcihhbGFkaW4sIGFsYWRpbkRpdiwgbW9kZWwpIHtcbiAgICB0aGlzLmFsYWRpbiA9IGFsYWRpbjtcbiAgICB0aGlzLmFsYWRpbkRpdiA9IGFsYWRpbkRpdjtcbiAgICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gICAgdGhpcy5tZXNzYWdlSGFuZGxlciA9IG5ldyBNZXNzYWdlSGFuZGxlcihhbGFkaW4sIG1vZGVsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGN1cnJlbnQgZGl2IGlzIHRoZSBsYXN0IGFjdGl2ZSBkaXYuXG4gICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgKi9cbiAgaXNMYXN0RGl2KCkge1xuICAgIGxldCBjdXJyZW50RGl2TnVtYmVyID0gcGFyc2VJbnQodGhpcy5hbGFkaW5EaXYuaWQuc3BsaXQoXCItXCIpLnBvcCgpKVxuICAgIGlmIChjdXJyZW50RGl2TnVtYmVyID09PSBkaXZOdW1iZXIpe1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9O1xuICAgIGxldCBtYXhEaXYgPSBkaXZOdW1iZXI7XG4gICAgZm9yIChsZXQgaSA9IG1heERpdjsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IGFsRGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYGFsYWRpbi1saXRlLWRpdi0ke2l9YCk7XG4gICAgICBpZiAoIWFsRGl2KSBjb250aW51ZTtcbiAgICAgIGlmIChhbERpdi5zdHlsZS5kaXNwbGF5ICE9PSBcIm5vbmVcIikge1xuICAgICAgICBtYXhEaXYgPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgc2V0RGl2TnVtYmVyKG1heERpdik7XG4gICAgcmV0dXJuIGN1cnJlbnREaXZOdW1iZXIgPT09IG1heERpdjtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHRoZSBXQ1MgY29vcmRpbmF0ZXMgaW4gdGhlIG1vZGVsLlxuICAgKiBXQVJOSU5HOiBUaGlzIG1ldGhvZCBkb24ndCBjYWxsIG1vZGVsLnNhdmVfY2hhbmdlcygpIVxuICAgKi9cbiAgdXBkYXRlV0NTKCkge1xuICAgIGlmICghdGhpcy5pc0xhc3REaXYoKSkgcmV0dXJuO1xuICAgIHRoaXMubW9kZWwuc2V0KFwiX3djc1wiLCB0aGlzLmFsYWRpbi5nZXRWaWV3V0NTKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIDItYXhpcyBGb1YgaW4gdGhlIG1vZGVsLlxuICAgKiBXQVJOSU5HOiBUaGlzIG1ldGhvZCBkb24ndCBjYWxsIG1vZGVsLnNhdmVfY2hhbmdlcygpIVxuICAgKi9cbiAgdXBkYXRlMkF4aXNGb1YoKSB7XG4gICAgaWYgKCF0aGlzLmlzTGFzdERpdigpKSByZXR1cm47XG4gICAgY29uc3QgdHdvQXhpc0ZvViA9IHRoaXMuYWxhZGluLmdldEZvdigpO1xuICAgIHRoaXMubW9kZWwuc2V0KFwiX2Zvdl94eVwiLCB7XG4gICAgICB4OiB0d29BeGlzRm9WWzBdLFxuICAgICAgeTogdHdvQXhpc0ZvVlsxXSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmVzIHRvIGFsbCB0aGUgZXZlbnRzIG5lZWRlZCBmb3IgdGhlIEFsYWRpbiBMaXRlIHdpZGdldC5cbiAgICovXG4gIHN1YnNjcmliZUFsbCgpIHtcbiAgICAvKiAtLS0tLS0tLS0tLS0tLS0tLS0tICovXG4gICAgLyogTGlzdGVuZXJzIC0tLS0tLS0tLSAqL1xuICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuICAgIC8qIFBvc2l0aW9uIENvbnRyb2wgKi9cbiAgICAvLyB0aGVyZSBhcmUgdHdvIHdheXMgb2YgY2hhbmdpbmcgdGhlIHRhcmdldCwgb25lIGZyb20gdGhlIGphdmFzY3JpcHQgc2lkZSwgYW5kXG4gICAgLy8gb25lIGZyb20gdGhlIHB5dGhvbiBzaWRlLiBXZSBoYXZlIHRvIGluc3RhbnRpYXRlIHR3byBsaXN0ZW5lcnMgZm9yIHRoZXNlLCBidXRcbiAgICAvLyB0aGUgZ290b09iamVjdCBjYWxsIHNob3VsZCBvbmx5IGhhcHBlbiBvbmNlLiBUaGUgdHdvIGJvb2xlYW5zIHByZXZlbnQgdGhlIHR3b1xuICAgIC8vIGxpc3RlbmVycyBmcm9tIHRyaWdnZXJpbmcgZWFjaCBvdGhlciBhbmQgY3JlYXRpbmcgYSBidWdneSBsb29wLiBUaGUgc2FtZSB0cmlja1xuICAgIC8vIGlzIGFsc28gbmVjZXNzYXJ5IGZvciB0aGUgZmllbGQgb2Ygdmlldy5cblxuICAgIC8qIFRhcmdldCBjb250cm9sICovXG4gICAgY29uc3QganNUYXJnZXRMb2NrID0gbmV3IExvY2soKTtcbiAgICBjb25zdCBweVRhcmdldExvY2sgPSBuZXcgTG9jaygpO1xuXG4gICAgLy8gRXZlbnQgdHJpZ2dlcmVkIHdoZW4gdGhlIHVzZXIgbW92ZXMgdGhlIG1hcCBpbiBBbGFkaW4gTGl0ZVxuICAgIHRoaXMuYWxhZGluLm9uKFwicG9zaXRpb25DaGFuZ2VkXCIsIChwb3NpdGlvbikgPT4ge1xuICAgICAgaWYgKHB5VGFyZ2V0TG9jay5sb2NrZWQpIHtcbiAgICAgICAgcHlUYXJnZXRMb2NrLnVubG9jaygpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBqc1RhcmdldExvY2subG9jaygpO1xuICAgICAgY29uc3QgcmFEZWMgPSBbcG9zaXRpb24ucmEsIHBvc2l0aW9uLmRlY107XG4gICAgICB0aGlzLnVwZGF0ZVdDUygpO1xuICAgICAgdGhpcy5tb2RlbC5zZXQoXCJfdGFyZ2V0XCIsIGAke3JhRGVjWzBdfSAke3JhRGVjWzFdfWApO1xuICAgICAgdGhpcy5tb2RlbC5zYXZlX2NoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIHRoaXMubW9kZWwub24oXCJjaGFuZ2U6X3RhcmdldFwiLCAoKSA9PiB7XG4gICAgICBpZiAoanNUYXJnZXRMb2NrLmxvY2tlZCkge1xuICAgICAgICBqc1RhcmdldExvY2sudW5sb2NrKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHB5VGFyZ2V0TG9jay5sb2NrKCk7XG4gICAgICBsZXQgdGFyZ2V0ID0gdGhpcy5tb2RlbC5nZXQoXCJfdGFyZ2V0XCIpO1xuICAgICAgY29uc3QgW3JhLCBkZWNdID0gdGFyZ2V0LnNwbGl0KFwiIFwiKTtcbiAgICAgIHRoaXMuYWxhZGluLmdvdG9SYURlYyhyYSwgZGVjKTtcbiAgICB9KTtcblxuICAgIC8qIEZpZWxkIG9mIFZpZXcgY29udHJvbCAqL1xuICAgIGNvbnN0IGpzRm92TG9jayA9IG5ldyBMb2NrKCk7XG4gICAgY29uc3QgcHlGb3ZMb2NrID0gbmV3IExvY2soKTtcblxuICAgIHRoaXMuYWxhZGluLm9uKFwiem9vbUNoYW5nZWRcIiwgKGZvdikgPT4ge1xuICAgICAgaWYgKHB5Rm92TG9jay5sb2NrZWQpIHtcbiAgICAgICAgcHlGb3ZMb2NrLnVubG9jaygpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBqc0ZvdkxvY2subG9jaygpO1xuICAgICAgLy8gZm92IE1VU1QgYmUgY2FzdCBpbnRvIGZsb2F0IGluIG9yZGVyIHRvIGJlIHNlbnQgdG8gdGhlIG1vZGVsXG4gICAgICB0aGlzLnVwZGF0ZVdDUygpO1xuICAgICAgdGhpcy51cGRhdGUyQXhpc0ZvVigpO1xuICAgICAgdGhpcy5tb2RlbC5zZXQoXCJfZm92XCIsIHBhcnNlRmxvYXQoZm92LnRvRml4ZWQoNSkpKTtcbiAgICAgIHRoaXMubW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLm1vZGVsLm9uKFwiY2hhbmdlOl9mb3ZcIiwgKCkgPT4ge1xuICAgICAgaWYgKGpzRm92TG9jay5sb2NrZWQpIHtcbiAgICAgICAganNGb3ZMb2NrLnVubG9jaygpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBweUZvdkxvY2subG9jaygpO1xuICAgICAgbGV0IGZvdiA9IHRoaXMubW9kZWwuZ2V0KFwiX2ZvdlwiKTtcbiAgICAgIHRoaXMuYWxhZGluLnNldEZvVihmb3YpO1xuICAgIH0pO1xuXG4gICAgLyogRGl2IGNvbnRyb2wgKi9cbiAgICB0aGlzLm1vZGVsLm9uKFwiY2hhbmdlOl9oZWlnaHRcIiwgKCkgPT4ge1xuICAgICAgbGV0IGhlaWdodCA9IHRoaXMubW9kZWwuZ2V0KFwiX2hlaWdodFwiKTtcbiAgICAgIHRoaXMuYWxhZGluRGl2LnN0eWxlLmhlaWdodCA9IGAke2hlaWdodH1weGA7XG4gICAgICAvLyBVcGRhdGUgV0NTIGFuZCBGb1Ygb25seSBpZiB0aGlzIGlzIHRoZSBsYXN0IGRpdlxuICAgICAgdGhpcy51cGRhdGVXQ1MoKTtcbiAgICAgIHRoaXMudXBkYXRlMkF4aXNGb1YoKTtcbiAgICAgIHRoaXMubW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG4gICAgfSk7XG5cbiAgICAvKiBBbGFkaW4gY2FsbGJhY2tzICovXG5cbiAgICB0aGlzLmFsYWRpbi5vbihcImNvb0ZyYW1lQ2hhbmdlZFwiLCAoKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZVdDUygpO1xuICAgICAgdGhpcy5tb2RlbC5zYXZlX2NoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuYWxhZGluLm9uKFwicHJvamVjdGlvbkNoYW5nZWRcIiwgKCkgPT4ge1xuICAgICAgdGhpcy51cGRhdGVXQ1MoKTtcbiAgICAgIHRoaXMubW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFsYWRpbi5vbihcImxheWVyQ2hhbmdlZFwiLCAoXywgbGF5ZXJOYW1lLCBzdGF0ZSkgPT4ge1xuICAgICAgaWYgKGxheWVyTmFtZSAhPT0gXCJiYXNlXCIgfHwgc3RhdGUgIT09IFwiQURERURcIikgcmV0dXJuO1xuICAgICAgdGhpcy51cGRhdGVXQ1MoKTtcbiAgICAgIHRoaXMubW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFsYWRpbi5vbihcInJlc2l6ZUNoYW5nZWRcIiwgKCkgPT4ge1xuICAgICAgdGhpcy51cGRhdGVXQ1MoKTtcbiAgICAgIHRoaXMudXBkYXRlMkF4aXNGb1YoKTtcbiAgICAgIHRoaXMubW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFsYWRpbi5vbihcIm9iamVjdEhvdmVyZWRcIiwgKG9iamVjdCkgPT4ge1xuICAgICAgaWYgKG9iamVjdFtcImRhdGFcIl0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLm1vZGVsLnNlbmQoe1xuICAgICAgICAgIGV2ZW50X3R5cGU6IFwib2JqZWN0X2hvdmVyZWRcIixcbiAgICAgICAgICBjb250ZW50OiB7XG4gICAgICAgICAgICByYTogb2JqZWN0W1wicmFcIl0sXG4gICAgICAgICAgICBkZWM6IG9iamVjdFtcImRlY1wiXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuYWxhZGluLm9uKFwib2JqZWN0Q2xpY2tlZFwiLCAoY2xpY2tlZCkgPT4ge1xuICAgICAgaWYgKGNsaWNrZWQpIHtcbiAgICAgICAgbGV0IGNsaWNrZWRDb250ZW50ID0ge1xuICAgICAgICAgIHJhOiBjbGlja2VkW1wicmFcIl0sXG4gICAgICAgICAgZGVjOiBjbGlja2VkW1wiZGVjXCJdLFxuICAgICAgICB9O1xuICAgICAgICBpZiAoY2xpY2tlZFtcImRhdGFcIl0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNsaWNrZWRDb250ZW50W1wiZGF0YVwiXSA9IGNsaWNrZWRbXCJkYXRhXCJdO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubW9kZWwuc2V0KFwiY2xpY2tlZF9vYmplY3RcIiwgY2xpY2tlZENvbnRlbnQpO1xuICAgICAgICAvLyBzZW5kIGEgY3VzdG9tIG1lc3NhZ2UgaW4gY2FzZSB0aGUgdXNlciB3YW50cyB0byBkZWZpbmUgdGhlaXIgb3duIGNhbGxiYWNrc1xuICAgICAgICB0aGlzLm1vZGVsLnNlbmQoe1xuICAgICAgICAgIGV2ZW50X3R5cGU6IFwib2JqZWN0X2NsaWNrZWRcIixcbiAgICAgICAgICBjb250ZW50OiBjbGlja2VkQ29udGVudCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmFsYWRpbi5vbihcImNsaWNrXCIsIChjbGlja0NvbnRlbnQpID0+IHtcbiAgICAgIHRoaXMubW9kZWwuc2VuZCh7XG4gICAgICAgIGV2ZW50X3R5cGU6IFwiY2xpY2tcIixcbiAgICAgICAgY29udGVudDogY2xpY2tDb250ZW50LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFsYWRpbi5vbihcInNlbGVjdFwiLCAoY2F0YWxvZ3MpID0+IHtcbiAgICAgIGxldCBvYmplY3RzRGF0YSA9IFtdO1xuICAgICAgLy8gVE9ETzogdGhpcyBmbGF0dGVucyB0aGUgc2VsZWN0aW9uLiBFYWNoIG9iamVjdCBmcm9tIGRpZmZlcmVudFxuICAgICAgLy8gY2F0YWxvZ3MgYXJlIGVudGVyZWQgaW4gdGhlIGFycmF5LiBUbyBjaGFuZ2UgdGhpcywgbWF5YmUgY2hhbmdlXG4gICAgICAvLyB1cHN0cmVhbSB3aGF0IGlzIHJldHVybmVkIHVwb24gc2VsZWN0aW9uP1xuICAgICAgY2F0YWxvZ3MuZm9yRWFjaCgoY2F0YWxvZykgPT4ge1xuICAgICAgICBjYXRhbG9nLmZvckVhY2goKG9iamVjdCkgPT4ge1xuICAgICAgICAgIG9iamVjdHNEYXRhLnB1c2goe1xuICAgICAgICAgICAgcmE6IG9iamVjdC5yYSxcbiAgICAgICAgICAgIGRlYzogb2JqZWN0LmRlYyxcbiAgICAgICAgICAgIGRhdGE6IG9iamVjdC5kYXRhLFxuICAgICAgICAgICAgeDogb2JqZWN0LngsXG4gICAgICAgICAgICB5OiBvYmplY3QueSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMubW9kZWwuc2VuZCh7XG4gICAgICAgIGV2ZW50X3R5cGU6IFwic2VsZWN0XCIsXG4gICAgICAgIGNvbnRlbnQ6IG9iamVjdHNEYXRhLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvKiBBbGFkaW4gZnVuY3Rpb25hbGl0aWVzICovXG5cbiAgICB0aGlzLm1vZGVsLm9uKFwiY2hhbmdlOmNvb19mcmFtZVwiLCAoKSA9PiB7XG4gICAgICB0aGlzLmFsYWRpbi5zZXRGcmFtZSh0aGlzLm1vZGVsLmdldChcImNvb19mcmFtZVwiKSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLm1vZGVsLm9uKFwiY2hhbmdlOnN1cnZleVwiLCAoKSA9PiB7XG4gICAgICB0aGlzLmFsYWRpbi5zZXRJbWFnZVN1cnZleSh0aGlzLm1vZGVsLmdldChcInN1cnZleVwiKSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLm1vZGVsLm9uKFwiY2hhbmdlOm92ZXJsYXlfc3VydmV5XCIsICgpID0+IHtcbiAgICAgIHRoaXMuYWxhZGluLnNldE92ZXJsYXlJbWFnZUxheWVyKHRoaXMubW9kZWwuZ2V0KFwib3ZlcmxheV9zdXJ2ZXlcIikpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5tb2RlbC5vbihcImNoYW5nZTpvdmVybGF5X3N1cnZleV9vcGFjaXR5XCIsICgpID0+IHtcbiAgICAgIHRoaXMuYWxhZGluXG4gICAgICAgIC5nZXRPdmVybGF5SW1hZ2VMYXllcigpXG4gICAgICAgIC5zZXRBbHBoYSh0aGlzLm1vZGVsLmdldChcIm92ZXJsYXlfc3VydmV5X29wYWNpdHlcIikpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5ldmVudEhhbmRsZXJzID0ge1xuICAgICAgY2hhbmdlX2ZvdjogdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVDaGFuZ2VGb1YsXG4gICAgICBnb3RvX3JhX2RlYzogdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVHb3RvUmFEZWMsXG4gICAgICBhZGRfZml0czogdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVBZGRGaXRzLFxuICAgICAgYWRkX2NhdGFsb2dfZnJvbV9VUkw6IHRoaXMubWVzc2FnZUhhbmRsZXIuaGFuZGxlQWRkQ2F0YWxvZ0Zyb21VUkwsXG4gICAgICBhZGRfTU9DX2Zyb21fVVJMOiB0aGlzLm1lc3NhZ2VIYW5kbGVyLmhhbmRsZUFkZE1PQ0Zyb21VUkwsXG4gICAgICBhZGRfTU9DX2Zyb21fZGljdDogdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVBZGRNT0NGcm9tRGljdCxcbiAgICAgIGFkZF9vdmVybGF5OiB0aGlzLm1lc3NhZ2VIYW5kbGVyLmhhbmRsZUFkZE92ZXJsYXksXG4gICAgICBjaGFuZ2VfY29sb3JtYXA6IHRoaXMubWVzc2FnZUhhbmRsZXIuaGFuZGxlQ2hhbmdlQ29sb3JtYXAsXG4gICAgICBnZXRfSlBHX3RodW1ibmFpbDogdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVHZXRKUEdUaHVtYm5haWwsXG4gICAgICB0cmlnZ2VyX3JlY3Rhbmd1bGFyX3NlbGVjdGlvbjpcbiAgICAgICAgdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVUcmlnZ2VyUmVjdGFuZ3VsYXJTZWxlY3Rpb24sXG4gICAgICBhZGRfdGFibGU6IHRoaXMubWVzc2FnZUhhbmRsZXIuaGFuZGxlQWRkVGFibGUsXG4gICAgfTtcblxuICAgIHRoaXMubW9kZWwub24oXCJtc2c6Y3VzdG9tXCIsIChtc2csIGJ1ZmZlcnMpID0+IHtcbiAgICAgIGNvbnN0IGV2ZW50TmFtZSA9IG1zZ1tcImV2ZW50X25hbWVcIl07XG4gICAgICBjb25zdCBoYW5kbGVyID0gdGhpcy5ldmVudEhhbmRsZXJzW2V2ZW50TmFtZV07XG4gICAgICBpZiAoaGFuZGxlcikgaGFuZGxlci5jYWxsKHRoaXMsIG1zZywgYnVmZmVycyk7XG4gICAgICBlbHNlIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBldmVudCBuYW1lOiAke2V2ZW50TmFtZX1gKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnN1YnNjcmliZSBmcm9tIGFsbCB0aGUgbW9kZWwgZXZlbnRzLlxuICAgKiBUaGVyZSBpcyBubyBuZWVkIHRvIHVuc3Vic2NyaWJlIGZyb20gdGhlIEFsYWRpbiBMaXRlIGV2ZW50cy5cbiAgICovXG4gIHVuc3Vic2NyaWJlQWxsKCkge1xuICAgIHRoaXMubW9kZWwub2ZmKFwiY2hhbmdlOl90YXJnZXRcIik7XG4gICAgdGhpcy5tb2RlbC5vZmYoXCJjaGFuZ2U6X2ZvdlwiKTtcbiAgICB0aGlzLm1vZGVsLm9mZihcImNoYW5nZTpfaGVpZ2h0XCIpO1xuICAgIHRoaXMubW9kZWwub2ZmKFwiY2hhbmdlOmNvb19mcmFtZVwiKTtcbiAgICB0aGlzLm1vZGVsLm9mZihcImNoYW5nZTpzdXJ2ZXlcIik7XG4gICAgdGhpcy5tb2RlbC5vZmYoXCJjaGFuZ2U6b3ZlcmxheV9zdXJ2ZXlcIik7XG4gICAgdGhpcy5tb2RlbC5vZmYoXCJjaGFuZ2U6b3ZlcmxheV9zdXJ2ZXlfb3BhY2l0eVwiKTtcbiAgICB0aGlzLm1vZGVsLm9mZihcImNoYW5nZTp0cmlnZ2VyX2V2ZW50XCIpO1xuICAgIHRoaXMubW9kZWwub2ZmKFwibXNnOmN1c3RvbVwiKTtcbiAgfVxufVxuIiwgImltcG9ydCBcIi4vd2lkZ2V0LmNzc1wiO1xuaW1wb3J0IEV2ZW50SGFuZGxlciBmcm9tIFwiLi9tb2RlbHMvZXZlbnRfaGFuZGxlclwiO1xuaW1wb3J0IHtcbiAgZGl2TnVtYmVyLFxuICBzZXREaXZOdW1iZXIsXG4gIHNuYWtlQ2FzZVRvQ2FtZWxDYXNlLFxufSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IEEgZnJvbSBcIi4vYWxhZGluX2xpdGVcIjtcblxuZnVuY3Rpb24gaW5pdEFsYWRpbkxpdGUobW9kZWwsIGVsKSB7XG4gIHNldERpdk51bWJlcihkaXZOdW1iZXIgKyAxKTtcbiAgbGV0IGluaXRPcHRpb25zID0ge307XG4gIG1vZGVsLmdldChcImluaXRfb3B0aW9uc1wiKS5mb3JFYWNoKChvcHRpb25fbmFtZSkgPT4ge1xuICAgIGluaXRPcHRpb25zW3NuYWtlQ2FzZVRvQ2FtZWxDYXNlKG9wdGlvbl9uYW1lKV0gPSBtb2RlbC5nZXQob3B0aW9uX25hbWUpO1xuICB9KTtcblxuICBsZXQgYWxhZGluRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgYWxhZGluRGl2LmNsYXNzTGlzdC5hZGQoXCJhbGFkaW4td2lkZ2V0XCIpO1xuICBhbGFkaW5EaXYuc3R5bGUuaGVpZ2h0ID0gYCR7aW5pdE9wdGlvbnNbXCJoZWlnaHRcIl19cHhgO1xuXG4gIGFsYWRpbkRpdi5pZCA9IGBhbGFkaW4tbGl0ZS1kaXYtJHtkaXZOdW1iZXJ9YDtcbiAgbGV0IGFsYWRpbiA9IG5ldyBBLmFsYWRpbihhbGFkaW5EaXYsIGluaXRPcHRpb25zKTtcblxuICAvLyBTZXQgdGhlIHRhcmdldCBhZ2FpbiBhZnRlciB0aGUgaW5pdGlhbGl6YXRpb24gdG8gYmUgc3VyZSB0aGF0IHRoZSB0YXJnZXQgaXMgc2V0XG4gIC8vIGZyb20gaWNycyBjb29yZGluYXRlcyBiZWNhdXNlIG9mIHRoZSB1c2Ugb2YgZ290b09iamVjdCBpbiB0aGUgQWxhZGluIExpdGUgQVBJXG4gIGNvbnN0IHJhRGVjID0gaW5pdE9wdGlvbnNbXCJ0YXJnZXRcIl0uc3BsaXQoXCIgXCIpO1xuICBhbGFkaW4uZ290b1JhRGVjKHJhRGVjWzBdLCByYURlY1sxXSk7XG5cbiAgLy8gU2V0IGN1cnJlbnQgRm9WIGFuZCBXQ1NcbiAgY29uc3QgdHdvQXhpc0ZvViA9IGFsYWRpbi5nZXRGb3YoKTtcbiAgbW9kZWwuc2V0KFwiX2Zvdl94eVwiLCB7XG4gICAgeDogdHdvQXhpc0ZvVlswXSxcbiAgICB5OiB0d29BeGlzRm9WWzFdLFxuICB9KTtcbiAgbW9kZWwuc2V0KFwiX3djc1wiLCBhbGFkaW4uZ2V0Vmlld1dDUygpKTtcbiAgbW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG5cbiAgZWwuYXBwZW5kQ2hpbGQoYWxhZGluRGl2KTtcbiAgcmV0dXJuIHsgYWxhZGluLCBhbGFkaW5EaXYgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gaW5pdGlhbGl6ZSh7IG1vZGVsIH0pIHtcbiAgYXdhaXQgQS5pbml0O1xufVxuXG5mdW5jdGlvbiByZW5kZXIoeyBtb2RlbCwgZWwgfSkge1xuICAvKiAtLS0tLS0tLS0tLS0tLS0tLS0tICovXG4gIC8qIFZpZXcgLS0tLS0tLS0tLS0tLS0gKi9cbiAgLyogLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4gIGNvbnN0IHsgYWxhZGluLCBhbGFkaW5EaXYgfSA9IGluaXRBbGFkaW5MaXRlKG1vZGVsLCBlbCk7XG5cbiAgY29uc3QgZXZlbnRIYW5kbGVyID0gbmV3IEV2ZW50SGFuZGxlcihhbGFkaW4sIGFsYWRpbkRpdiwgbW9kZWwpO1xuICBldmVudEhhbmRsZXIuc3Vic2NyaWJlQWxsKCk7XG5cbiAgcmV0dXJuICgpID0+IHtcbiAgICAvLyBOZWVkIHRvIHVuc3Vic2NyaWJlIHRoZSBsaXN0ZW5lcnNcbiAgICBldmVudEhhbmRsZXIudW5zdWJzY3JpYmVBbGwoKTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgeyBpbml0aWFsaXplLCByZW5kZXIgfTtcbiJdLAogICJtYXBwaW5ncyI6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LEtBQUssRUFDNUNBLEVBQVUsVUFBVSxJQUFJLGVBQWUsRUFDdkNBLEVBQVUsTUFBTSxPQUFTLEdBQUdILEVBQVksTUFBUyxLQUVqREcsRUFBVSxHQUFLLG1CQUFtQkosQ0FBUyxHQUMzQyxJQUFJSyxFQUFTLElBQUlDLEVBQUUsT0FBT0YsRUFBV0gsQ0FBVyxFQUkxQ00sRUFBUU4sRUFBWSxPQUFVLE1BQU0sR0FBRyxFQUM3Q0ksRUFBTyxVQUFVRSxFQUFNLENBQUMsRUFBR0EsRUFBTSxDQUFDLENBQUMsRUFHbkMsSUFBTUMsRUFBYUgsRUFBTyxPQUFPLEVBQ2pDLE9BQUFSLEVBQU0sSUFBSSxVQUFXLENBQ25CLEVBQUdXLEVBQVcsQ0FBQyxFQUNmLEVBQUdBLEVBQVcsQ0FBQyxDQUNqQixDQUFDLEVBQ0RYLEVBQU0sSUFBSSxPQUFRUSxFQUFPLFdBQVcsQ0FBQyxFQUNyQ1IsRUFBTSxhQUFhLEVBRW5CQyxFQUFHLFlBQVlNLENBQVMsRUFDakIsQ0FBRSxPQUFBQyxFQUFRLFVBQUFELENBQVUsQ0FDN0IsQ0FFQSxlQUFlSyxFQUFXLENBQUUsTUFBQVosQ0FBTSxFQUFHLENBQ25DLE1BQU1TLEVBQUUsSUFDVixDQUVBLFNBQVNJLEVBQU8sQ0FBRSxNQUFBYixFQUFPLEdBQUFDLENBQUcsRUFBRyxDQUs3QixHQUFNLENBQUUsT0FBQU8sRUFBUSxVQUFBRCxDQUFVLEVBQUlSLEVBQWVDLEVBQU9DLENBQUUsRUFFaERhLEVBQWUsSUFBSUMsRUFBYVAsRUFBUUQsRUFBV1AsQ0FBSyxFQUM5RCxPQUFBYyxFQUFhLGFBQWEsRUFFbkIsSUFBTSxDQUVYQSxFQUFhLGVBQWUsQ0FDOUIsQ0FDRixDQUVBLElBQU9FLEVBQVEsQ0FBRSxXQUFBSixFQUFZLE9BQUFDLENBQU8iLAogICJuYW1lcyI6IFsic25ha2VDYXNlVG9DYW1lbENhc2UiLCAic25ha2VDYXNlU3RyIiwgInRlbXAiLCAiaSIsICJjb252ZXJ0T3B0aW9uTmFtZXNUb0NhbWVsQ2FzZSIsICJvcHRpb25zIiwgIm5ld09wdGlvbnMiLCAib3B0aW9uTmFtZSIsICJMb2NrIiwgImRpdk51bWJlciIsICJzZXREaXZOdW1iZXIiLCAibnVtIiwgIkEiLCAiYWxhZGluX2xpdGVfZGVmYXVsdCIsICJpbWFnZUNvdW50IiwgIk1lc3NhZ2VIYW5kbGVyIiwgImFsYWRpbiIsICJtb2RlbCIsICJtc2ciLCAiYnVmZmVycyIsICJvcHRpb25zIiwgImNvbnZlcnRPcHRpb25OYW1lc1RvQ2FtZWxDYXNlIiwgImJ1ZmZlciIsICJibG9iIiwgInVybCIsICJpbWFnZSIsICJyYSIsICJkZWMiLCAiYWxhZGluX2xpdGVfZGVmYXVsdCIsICJyZWdpb25zIiwgImdyYXBoaWNfb3B0aW9ucyIsICJvdmVybGF5IiwgInJlZ2lvbiIsICJpbmZvcyIsICJkZWNvZGVyIiwgImNhdGFsb2ciLCAiRXZlbnRIYW5kbGVyIiwgImFsYWRpbiIsICJhbGFkaW5EaXYiLCAibW9kZWwiLCAiTWVzc2FnZUhhbmRsZXIiLCAiY3VycmVudERpdk51bWJlciIsICJkaXZOdW1iZXIiLCAibWF4RGl2IiwgImFsRGl2IiwgInNldERpdk51bWJlciIsICJ0d29BeGlzRm9WIiwgImpzVGFyZ2V0TG9jayIsICJMb2NrIiwgInB5VGFyZ2V0TG9jayIsICJwb3NpdGlvbiIsICJyYURlYyIsICJ0YXJnZXQiLCAicmEiLCAiZGVjIiwgImpzRm92TG9jayIsICJweUZvdkxvY2siLCAiZm92IiwgImhlaWdodCIsICJfIiwgImxheWVyTmFtZSIsICJzdGF0ZSIsICJvYmplY3QiLCAiY2xpY2tlZCIsICJjbGlja2VkQ29udGVudCIsICJjbGlja0NvbnRlbnQiLCAiY2F0YWxvZ3MiLCAib2JqZWN0c0RhdGEiLCAiY2F0YWxvZyIsICJtc2ciLCAiYnVmZmVycyIsICJldmVudE5hbWUiLCAiaGFuZGxlciIsICJpbml0QWxhZGluTGl0ZSIsICJtb2RlbCIsICJlbCIsICJzZXREaXZOdW1iZXIiLCAiZGl2TnVtYmVyIiwgImluaXRPcHRpb25zIiwgIm9wdGlvbl9uYW1lIiwgInNuYWtlQ2FzZVRvQ2FtZWxDYXNlIiwgImFsYWRpbkRpdiIsICJhbGFkaW4iLCAiYWxhZGluX2xpdGVfZGVmYXVsdCIsICJyYURlYyIsICJ0d29BeGlzRm9WIiwgImluaXRpYWxpemUiLCAicmVuZGVyIiwgImV2ZW50SGFuZGxlciIsICJFdmVudEhhbmRsZXIiLCAid2lkZ2V0X2RlZmF1bHQiXQp9Cg==\n", + "_fov": 5.60143, + "_fov_xy": { + "x": 5.60143396583755, + "y": 5.60143396583755 + }, + "_height": 800, + "_model_module": "anywidget", + "_model_module_version": "0.9.10", + "_model_name": "AnyModel", + "_target": "10.684708299999999 41.268749999999976", + "_view_module": "anywidget", + "_view_module_version": "0.9.10", + "_view_name": "AnyView", + "_wcs": { + "CDELT1": -5.60143396583755, + "CDELT2": 5.60143396583755, + "CRPIX1": 1, + "CRPIX2": 1, + "CRVAL1": 10.684708299999997, + "CRVAL2": 41.26874999999998, + "CTYPE1": "RA---SIN", + "CTYPE2": "DEC--SIN", + "CUNIT1": "deg ", + "CUNIT2": "deg ", + "LONPOLE": 180.00000000000006, + "NAXIS": 2, + "NAXIS1": 1, + "NAXIS2": 1, + "RADESYS": "ICRS " + }, + "background_color": "rgb(60, 60, 60)", + "clicked_object": {}, + "coo_frame": "J2000", + "full_screen": false, + "grid_color": "rgb(178, 50, 178)", + "grid_opacity": 0.5, + "grid_options": { + "color": { + "b": 0.6980392156862745, + "g": 0.19607843137254902, + "r": 0.6980392156862745 + }, + "enabled": false, + "labelSize": 15, + "opacity": 0.5, + "showLabels": true, + "thickness": 2 + }, + "init_options": [ + "_fov", + "_height", + "_target", + "background_color", + "coo_frame", + "full_screen", + "grid_color", + "grid_opacity", + "grid_options", + "overlay_survey", + "overlay_survey_opacity", + "projection", + "reticle_color", + "reticle_size", + "samp", + "show_catalog", + "show_context_menu", + "show_coo_grid", + "show_coo_grid_control", + "show_coo_location", + "show_fov", + "show_frame", + "show_fullscreen_control", + "show_layers_control", + "show_overlay_stack_control", + "show_projection_control", + "show_reticle", + "show_settings_control", + "show_share_control", + "show_simbad_pointer_control", + "show_status_bar", + "show_zoom_control", + "survey" + ], + "layout": "IPY_MODEL_963ac6a600854d92a585c08214f76219", + "overlay_survey": "", + "overlay_survey_opacity": 0, + "projection": "SIN", + "reticle_color": "rgb(178, 50, 178)", + "reticle_size": 20, + "samp": false, + "show_catalog": true, + "show_context_menu": true, + "show_coo_grid": false, + "show_coo_grid_control": true, + "show_coo_location": true, + "show_fov": true, + "show_frame": true, + "show_fullscreen_control": true, + "show_layers_control": true, + "show_overlay_stack_control": true, + "show_projection_control": true, + "show_reticle": true, + "show_settings_control": true, + "show_share_control": false, + "show_simbad_pointer_control": true, + "show_status_bar": true, + "show_zoom_control": false, + "survey": "CDS/P/PLANCK/R2/HFI/color" + } + }, + "963ac6a600854d92a585c08214f76219": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": {} + } + }, + "version_major": 2, + "version_minor": 0 + } } }, "nbformat": 4, From 8121131e3b4a3d99bfb5a2bcdcadaace0e6b46fd Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Mon, 22 Jul 2024 15:47:24 +0200 Subject: [PATCH 23/24] fix: only parse string once --- js/models/event_handler.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/models/event_handler.js b/js/models/event_handler.js index f6fe0253..4c1ccaea 100644 --- a/js/models/event_handler.js +++ b/js/models/event_handler.js @@ -13,6 +13,7 @@ export default class EventHandler { this.aladinDiv = aladinDiv; this.model = model; this.messageHandler = new MessageHandler(aladin, model); + this.currentDivNumber = parseInt(aladinDiv.id.split("-").pop()); } /** @@ -20,8 +21,7 @@ export default class EventHandler { * @returns {boolean} */ isLastDiv() { - let currentDivNumber = parseInt(this.aladinDiv.id.split("-").pop()); - if (currentDivNumber === divNumber) { + if (this.currentDivNumber === divNumber) { return true; } let maxDiv = divNumber; @@ -34,7 +34,7 @@ export default class EventHandler { } } setDivNumber(maxDiv); - return currentDivNumber === maxDiv; + return this.currentDivNumber === maxDiv; } /** From 0ad20d37dfd5f6d8cfde05675c56b8124869cffc Mon Sep 17 00:00:00 2001 From: MARCHAND MANON Date: Mon, 22 Jul 2024 15:48:16 +0200 Subject: [PATCH 24/24] docs: add paragraph on limitations --- ...Extracting_information_from_the_view.ipynb | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/examples/11_Extracting_information_from_the_view.ipynb b/examples/11_Extracting_information_from_the_view.ipynb index 89e37514..39fc3ab4 100644 --- a/examples/11_Extracting_information_from_the_view.ipynb +++ b/examples/11_Extracting_information_from_the_view.ipynb @@ -7,7 +7,10 @@ "source": [ "# Retrieving data from the current widget's view\n", "\n", - "So far, we've seen how to send information (tables, MOCs, ...) into the widget. The other way also works! Here are a list of methods to extract diverse information about the current view:" + "So far, we've seen how to send information (tables, MOCs, ...) into the widget. The other way also works! This notebook contains a list of methods to extract diverse information about the current view. However, here are several information about retrieving data from the widget:\n", + "\n", + "- when the view is modified programmatically (*i.e.* not by clicking on the buttons), the update of its properties is done between cell execution. This means that you'll see a `WidgetCommunicationError` when you try to modify the view and retrieve information about it in the **same** cell. Simply switch the property-reading to the next cell and everything will work as intended!\n", + "- if you generate different views of the same `Aladin()` instances -- either by calling `display` multiple times, or by using the `Create new view for cell output` button in Jupyter, the information contained in `wcs` and `fov_xy` will always correspond to the **most recently** created view." ] }, { @@ -29,7 +32,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "8609c7b19f7644acb71ce3a258199fd9", + "model_id": "68df3ccd903340b4aa8af8aad92c0c20", "version_major": 2, "version_minor": 1 }, @@ -71,11 +74,11 @@ "Number of WCS axes: 2\n", "CTYPE : 'RA---SIN' 'DEC--SIN' \n", "CRVAL : 10.6847083 41.26875 \n", - "CRPIX : 929.0 300.5 \n", + "CRPIX : 843.0 300.5 \n", "PC1_1 PC1_2 : 1.0 0.0 \n", "PC2_1 PC2_2 : 0.0 1.0 \n", - "CDELT : -0.00269251480883144 0.002692514808831448 \n", - "NAXIS : 1857 600" + "CDELT : -0.0029673590504451 0.002967359050445104 \n", + "NAXIS : 1685 600" ] }, "execution_count": 3, @@ -105,6 +108,7 @@ "aladin.height = 800\n", "aladin.survey = \"CDS/P/PLANCK/R2/HFI/color\"\n", "aladin.target = \"LMC\"\n", + "aladin.frame = \"Galactic\"\n", "aladin.fov = 50" ] }, @@ -130,11 +134,11 @@ "Number of WCS axes: 2\n", "CTYPE : 'RA---SIN' 'DEC--SIN' \n", "CRVAL : 80.89416999999995 -69.75611 \n", - "CRPIX : 929.0 400.5 \n", + "CRPIX : 843.0 400.5 \n", "PC1_1 PC1_2 : 1.0 0.0 \n", "PC2_1 PC2_2 : 0.0 1.0 \n", - "CDELT : -0.00269251480883144 0.002692514808831449 \n", - "NAXIS : 1857 800" + "CDELT : -0.0029673590504451 0.002967359050445104 \n", + "NAXIS : 1685 800" ] }, "execution_count": 5, @@ -151,7 +155,7 @@ "id": "f5add3a2-be30-488e-86df-426338b98f5d", "metadata": {}, "source": [ - "If you try to recover the value in the same cell, you'll get a `WidgetCommunicationError` error. This is because the calculation of the WCS is done by Aladin Lite *between* cell exceutions. \n", + "If you try to recover the value in the **same cell**, you'll get a `WidgetCommunicationError` error. This is because the calculation of the WCS is done by Aladin Lite *between* cell executions. \n", "\n", "## Getting the field of view\n", "\n", @@ -167,7 +171,7 @@ { "data": { "text/plain": [ - "(, )" + "(, )" ] }, "execution_count": 6, @@ -201,34 +205,34 @@ "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { - "8609c7b19f7644acb71ce3a258199fd9": { + "68df3ccd903340b4aa8af8aad92c0c20": { "model_module": "anywidget", "model_module_version": "0.9.10", "model_name": "AnyModel", "state": { "_anywidget_id": "ipyaladin.widget.Aladin", "_css": ".cell-output-ipywidget-background{background:transparent}.jp-OutputArea-output,.aladin-widget{background-color:transparent}.aladin-widget .aladin-measurement-div{max-height:100px}\n/*# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vanMvd2lkZ2V0LmNzcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLmNlbGwtb3V0cHV0LWlweXdpZGdldC1iYWNrZ3JvdW5kIHtcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG59XG4uanAtT3V0cHV0QXJlYS1vdXRwdXQge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbn1cbi5hbGFkaW4td2lkZ2V0IHtcbiAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7XG59XG4uYWxhZGluLXdpZGdldCAuYWxhZGluLW1lYXN1cmVtZW50LWRpdiB7XG4gIG1heC1oZWlnaHQ6IDEwMHB4O1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIkFBQUEsQ0FBQyxpQ0FDQyxXQUFZLFdBQ2QsQ0FDQSxDQUFDLHFCQUdELENBQUMsY0FGQyxpQkFBa0IsV0FDcEIsQ0FJQSxDQUhDLGNBR2MsQ0FBQyx1QkFDZCxXQUFZLEtBQ2QiLAogICJuYW1lcyI6IFtdCn0K */\n", - "_esm": "function f(s){s.charAt(0)===\"_\"&&(s=s.slice(1));let e=s.split(\"_\");for(let a=1;a{this.aladin.gotoRaDec(r,v),console.info(`FITS located at ra: ${r}, dec: ${v}`),URL.revokeObjectURL(o)});this.aladin.setOverlayImageLayer(d,i.name)}handleAddCatalogFromURL(e){let a=h(e.options||{});this.aladin.addCatalog(l.catalogFromURL(e.votable_URL,a))}handleAddMOCFromURL(e){let a=h(e.options||{});this.aladin.addMOC(l.MOCFromURL(e.moc_URL,a))}handleAddMOCFromDict(e){let a=h(e.options||{});this.aladin.addMOC(l.MOCFromJSON(e.moc_dict,a))}handleAddOverlay(e){let a=e.regions_infos,i=h(e.graphic_options||{});i.color||(i.color=\"red\");let n=l.graphicOverlay(i);this.aladin.addOverlay(n);for(let t of a){let o=t.infos;switch(t.region_type){case\"stcs\":n.addFootprints(l.footprintsFromSTCS(o.stcs,t.options));break;case\"circle\":n.add(l.circle(o.ra,o.dec,o.radius,t.options));break;case\"ellipse\":n.add(l.ellipse(o.ra,o.dec,o.a,o.b,o.theta,t.options));break;case\"line\":t.options.lineWidth=t.options.lineWidth||3,n.add(l.vector(o.ra1,o.dec1,o.ra2,o.dec2,t.options));break;case\"polygon\":n.add(l.polygon(o.vertices,t.options));break}}}handleChangeColormap(e){this.aladin.getBaseImageLayer().setColormap(e.colormap)}handleGetJPGThumbnail(){this.aladin.exportAsPNG()}handleTriggerRectangularSelection(){this.aladin.select()}handleAddTable(e,a){let i=h(e.options||{}),n=a[0].buffer,t=new TextDecoder(\"utf-8\"),o=new Blob([t.decode(n)]),d=URL.createObjectURL(o);l.catalogFromURL(d,Object.assign(i,{onClick:\"showTable\"}),r=>{this.aladin.addCatalog(r)},!1),URL.revokeObjectURL(d)}};var p=class{constructor(e,a,i){this.aladin=e,this.aladinDiv=a,this.model=i,this.messageHandler=new g(e,i)}isLastDiv(){let e=parseInt(this.aladinDiv.id.split(\"-\").pop());if(e===m)return!0;let a=m;for(let i=a;i>=0;i--){let n=document.getElementById(`aladin-lite-div-${i}`);if(n&&n.style.display!==\"none\"){a=i;break}}return u(a),e===a}updateWCS(){this.isLastDiv()&&this.model.set(\"_wcs\",this.aladin.getViewWCS())}update2AxisFoV(){if(!this.isLastDiv())return;let e=this.aladin.getFov();this.model.set(\"_fov_xy\",{x:e[0],y:e[1]})}subscribeAll(){let e=new c,a=new c;this.aladin.on(\"positionChanged\",t=>{if(a.locked){a.unlock();return}e.lock();let o=[t.ra,t.dec];this.updateWCS(),this.model.set(\"_target\",`${o[0]} ${o[1]}`),this.model.save_changes()}),this.model.on(\"change:_target\",()=>{if(e.locked){e.unlock();return}a.lock();let t=this.model.get(\"_target\"),[o,d]=t.split(\" \");this.aladin.gotoRaDec(o,d)});let i=new c,n=new c;this.aladin.on(\"zoomChanged\",t=>{if(n.locked){n.unlock();return}i.lock(),this.updateWCS(),this.update2AxisFoV(),this.model.set(\"_fov\",parseFloat(t.toFixed(5))),this.model.save_changes()}),this.model.on(\"change:_fov\",()=>{if(i.locked){i.unlock();return}n.lock();let t=this.model.get(\"_fov\");this.aladin.setFoV(t)}),this.model.on(\"change:_height\",()=>{let t=this.model.get(\"_height\");this.aladinDiv.style.height=`${t}px`,this.updateWCS(),this.update2AxisFoV(),this.model.save_changes()}),this.aladin.on(\"cooFrameChanged\",()=>{this.updateWCS(),this.model.save_changes()}),this.aladin.on(\"projectionChanged\",()=>{this.updateWCS(),this.model.save_changes()}),this.aladin.on(\"layerChanged\",(t,o,d)=>{o!==\"base\"||d!==\"ADDED\"||(this.updateWCS(),this.model.save_changes())}),this.aladin.on(\"resizeChanged\",()=>{this.updateWCS(),this.update2AxisFoV(),this.model.save_changes()}),this.aladin.on(\"objectHovered\",t=>{t.data!==void 0&&this.model.send({event_type:\"object_hovered\",content:{ra:t.ra,dec:t.dec}})}),this.aladin.on(\"objectClicked\",t=>{if(t){let o={ra:t.ra,dec:t.dec};t.data!==void 0&&(o.data=t.data),this.model.set(\"clicked_object\",o),this.model.send({event_type:\"object_clicked\",content:o}),this.model.save_changes()}}),this.aladin.on(\"click\",t=>{this.model.send({event_type:\"click\",content:t})}),this.aladin.on(\"select\",t=>{let o=[];t.forEach(d=>{d.forEach(r=>{o.push({ra:r.ra,dec:r.dec,data:r.data,x:r.x,y:r.y})})}),this.model.send({event_type:\"select\",content:o})}),this.model.on(\"change:coo_frame\",()=>{this.aladin.setFrame(this.model.get(\"coo_frame\"))}),this.model.on(\"change:survey\",()=>{this.aladin.setImageSurvey(this.model.get(\"survey\"))}),this.model.on(\"change:overlay_survey\",()=>{this.aladin.setOverlayImageLayer(this.model.get(\"overlay_survey\"))}),this.model.on(\"change:overlay_survey_opacity\",()=>{this.aladin.getOverlayImageLayer().setAlpha(this.model.get(\"overlay_survey_opacity\"))}),this.eventHandlers={change_fov:this.messageHandler.handleChangeFoV,goto_ra_dec:this.messageHandler.handleGotoRaDec,add_fits:this.messageHandler.handleAddFits,add_catalog_from_URL:this.messageHandler.handleAddCatalogFromURL,add_MOC_from_URL:this.messageHandler.handleAddMOCFromURL,add_MOC_from_dict:this.messageHandler.handleAddMOCFromDict,add_overlay:this.messageHandler.handleAddOverlay,change_colormap:this.messageHandler.handleChangeColormap,get_JPG_thumbnail:this.messageHandler.handleGetJPGThumbnail,trigger_rectangular_selection:this.messageHandler.handleTriggerRectangularSelection,add_table:this.messageHandler.handleAddTable},this.model.on(\"msg:custom\",(t,o)=>{let d=t.event_name,r=this.eventHandlers[d];if(r)r.call(this,t,o);else throw new Error(`Unknown event name: ${d}`)})}unsubscribeAll(){this.model.off(\"change:_target\"),this.model.off(\"change:_fov\"),this.model.off(\"change:_height\"),this.model.off(\"change:coo_frame\"),this.model.off(\"change:survey\"),this.model.off(\"change:overlay_survey\"),this.model.off(\"change:overlay_survey_opacity\"),this.model.off(\"change:trigger_event\"),this.model.off(\"msg:custom\")}};function C(s,e){u(m+1);let a={};s.get(\"init_options\").forEach(d=>{a[f(d)]=s.get(d)});let i=document.createElement(\"div\");i.classList.add(\"aladin-widget\"),i.style.height=`${a.height}px`,i.id=`aladin-lite-div-${m}`;let n=new l.aladin(i,a),t=a.target.split(\" \");n.gotoRaDec(t[0],t[1]);let o=n.getFov();return s.set(\"_fov_xy\",{x:o[0],y:o[1]}),s.set(\"_wcs\",n.getViewWCS()),s.save_changes(),e.appendChild(i),{aladin:n,aladinDiv:i}}async function b({model:s}){await l.init}function k({model:s,el:e}){let{aladin:a,aladinDiv:i}=C(s,e),n=new p(a,i,s);return n.subscribeAll(),()=>{n.unsubscribeAll()}}var j={initialize:b,render:k};export{j as default};\n//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vanMvdXRpbHMuanMiLCAiLi4vLi4vLi4vanMvYWxhZGluX2xpdGUuanMiLCAiLi4vLi4vLi4vanMvbW9kZWxzL21lc3NhZ2VfaGFuZGxlci5qcyIsICIuLi8uLi8uLi9qcy9tb2RlbHMvZXZlbnRfaGFuZGxlci5qcyIsICIuLi8uLi8uLi9qcy93aWRnZXQuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQ29udmVydHMgYSBzdHJpbmcgZnJvbSBjYW1lbENhc2UgdG8gc25ha2VfY2FzZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzbmFrZUNhc2VTdHIgLSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgc3RyaW5nIGNvbnZlcnRlZCB0byBzbmFrZV9jYXNlLlxuICovXG5mdW5jdGlvbiBzbmFrZUNhc2VUb0NhbWVsQ2FzZShzbmFrZUNhc2VTdHIpIHtcbiAgaWYgKHNuYWtlQ2FzZVN0ci5jaGFyQXQoMCkgPT09IFwiX1wiKSBzbmFrZUNhc2VTdHIgPSBzbmFrZUNhc2VTdHIuc2xpY2UoMSk7XG4gIGxldCB0ZW1wID0gc25ha2VDYXNlU3RyLnNwbGl0KFwiX1wiKTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCB0ZW1wLmxlbmd0aDsgaSsrKVxuICAgIHRlbXBbaV0gPSB0ZW1wW2ldLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgdGVtcFtpXS5zbGljZSgxKTtcbiAgcmV0dXJuIHRlbXAuam9pbihcIlwiKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvcHRpb24gbmFtZXMgaW4gYW4gb2JqZWN0IGZyb20gc25ha2VfY2FzZSB0byBjYW1lbENhc2UuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIG9iamVjdCB3aXRoIHNuYWtlX2Nhc2UgcHJvcGVydHkgbmFtZXMuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBBbiBvYmplY3Qgd2l0aCBwcm9wZXJ0eSBuYW1lcyBjb252ZXJ0ZWQgdG8gY2FtZWxDYXNlLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0T3B0aW9uTmFtZXNUb0NhbWVsQ2FzZShvcHRpb25zKSB7XG4gIGNvbnN0IG5ld09wdGlvbnMgPSB7fTtcbiAgZm9yIChjb25zdCBvcHRpb25OYW1lIGluIG9wdGlvbnMpXG4gICAgbmV3T3B0aW9uc1tzbmFrZUNhc2VUb0NhbWVsQ2FzZShvcHRpb25OYW1lKV0gPSBvcHRpb25zW29wdGlvbk5hbWVdO1xuICByZXR1cm4gbmV3T3B0aW9ucztcbn1cblxuY2xhc3MgTG9jayB7XG4gIGxvY2tlZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBVbmxvY2tzIHRoZSBvYmplY3RcbiAgICovXG4gIHVubG9jaygpIHtcbiAgICB0aGlzLmxvY2tlZCA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIExvY2tzIHRoZSBvYmplY3RcbiAgICovXG4gIGxvY2soKSB7XG4gICAgdGhpcy5sb2NrZWQgPSB0cnVlO1xuICB9XG59XG5cbmxldCBkaXZOdW1iZXIgPSAtMTtcbmZ1bmN0aW9uIHNldERpdk51bWJlcihudW0pIHtcbiAgZGl2TnVtYmVyID0gbnVtO1xufVxuXG5leHBvcnQge1xuICBzbmFrZUNhc2VUb0NhbWVsQ2FzZSxcbiAgY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UsXG4gIExvY2ssXG4gIGRpdk51bWJlcixcbiAgc2V0RGl2TnVtYmVyLFxufTtcbiIsICJpbXBvcnQgQSBmcm9tIFwiaHR0cHM6Ly9lc20uc2gvYWxhZGluLWxpdGVAMy40LjUtYmV0YVwiO1xuXG5leHBvcnQgZGVmYXVsdCBBO1xuIiwgImltcG9ydCB7IGNvbnZlcnRPcHRpb25OYW1lc1RvQ2FtZWxDYXNlIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgQSBmcm9tIFwiLi4vYWxhZGluX2xpdGVcIjtcblxubGV0IGltYWdlQ291bnQgPSAwO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZXNzYWdlSGFuZGxlciB7XG4gIGNvbnN0cnVjdG9yKGFsYWRpbiwgbW9kZWwpIHtcbiAgICB0aGlzLmFsYWRpbiA9IGFsYWRpbjtcbiAgICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gIH1cblxuICBoYW5kbGVDaGFuZ2VGb1YobXNnKSB7XG4gICAgdGhpcy5hbGFkaW4uc2V0Rm9WKG1zZ1tcImZvdlwiXSk7XG4gIH1cblxuICBoYW5kbGVHb3RvUmFEZWMobXNnKSB7XG4gICAgdGhpcy5hbGFkaW4uZ290b1JhRGVjKG1zZ1tcInJhXCJdLCBtc2dbXCJkZWNcIl0pO1xuICB9XG5cbiAgaGFuZGxlQWRkRml0cyhtc2csIGJ1ZmZlcnMpIHtcbiAgICBjb25zdCBvcHRpb25zID0gY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UobXNnW1wib3B0aW9uc1wiXSB8fCB7fSk7XG4gICAgaWYgKCFvcHRpb25zLm5hbWUpXG4gICAgICBvcHRpb25zLm5hbWUgPSBgaW1hZ2VfJHtTdHJpbmcoKytpbWFnZUNvdW50KS5wYWRTdGFydCgzLCBcIjBcIil9YDtcbiAgICBjb25zdCBidWZmZXIgPSBidWZmZXJzWzBdO1xuICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbYnVmZmVyXSwgeyB0eXBlOiBcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiIH0pO1xuICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgY29uc3QgaW1hZ2UgPSB0aGlzLmFsYWRpbi5jcmVhdGVJbWFnZUZJVFModXJsLCBvcHRpb25zLCAocmEsIGRlYykgPT4ge1xuICAgICAgdGhpcy5hbGFkaW4uZ290b1JhRGVjKHJhLCBkZWMpO1xuICAgICAgY29uc29sZS5pbmZvKGBGSVRTIGxvY2F0ZWQgYXQgcmE6ICR7cmF9LCBkZWM6ICR7ZGVjfWApO1xuICAgICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICAgIH0pO1xuICAgIHRoaXMuYWxhZGluLnNldE92ZXJsYXlJbWFnZUxheWVyKGltYWdlLCBvcHRpb25zLm5hbWUpO1xuICB9XG5cbiAgaGFuZGxlQWRkQ2F0YWxvZ0Zyb21VUkwobXNnKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IGNvbnZlcnRPcHRpb25OYW1lc1RvQ2FtZWxDYXNlKG1zZ1tcIm9wdGlvbnNcIl0gfHwge30pO1xuICAgIHRoaXMuYWxhZGluLmFkZENhdGFsb2coQS5jYXRhbG9nRnJvbVVSTChtc2dbXCJ2b3RhYmxlX1VSTFwiXSwgb3B0aW9ucykpO1xuICB9XG5cbiAgaGFuZGxlQWRkTU9DRnJvbVVSTChtc2cpIHtcbiAgICBjb25zdCBvcHRpb25zID0gY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UobXNnW1wib3B0aW9uc1wiXSB8fCB7fSk7XG4gICAgdGhpcy5hbGFkaW4uYWRkTU9DKEEuTU9DRnJvbVVSTChtc2dbXCJtb2NfVVJMXCJdLCBvcHRpb25zKSk7XG4gIH1cblxuICBoYW5kbGVBZGRNT0NGcm9tRGljdChtc2cpIHtcbiAgICBjb25zdCBvcHRpb25zID0gY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UobXNnW1wib3B0aW9uc1wiXSB8fCB7fSk7XG4gICAgdGhpcy5hbGFkaW4uYWRkTU9DKEEuTU9DRnJvbUpTT04obXNnW1wibW9jX2RpY3RcIl0sIG9wdGlvbnMpKTtcbiAgfVxuXG4gIGhhbmRsZUFkZE92ZXJsYXkobXNnKSB7XG4gICAgY29uc3QgcmVnaW9ucyA9IG1zZ1tcInJlZ2lvbnNfaW5mb3NcIl07XG4gICAgY29uc3QgZ3JhcGhpY19vcHRpb25zID0gY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UoXG4gICAgICBtc2dbXCJncmFwaGljX29wdGlvbnNcIl0gfHwge30sXG4gICAgKTtcbiAgICBpZiAoIWdyYXBoaWNfb3B0aW9uc1tcImNvbG9yXCJdKSBncmFwaGljX29wdGlvbnNbXCJjb2xvclwiXSA9IFwicmVkXCI7XG4gICAgY29uc3Qgb3ZlcmxheSA9IEEuZ3JhcGhpY092ZXJsYXkoZ3JhcGhpY19vcHRpb25zKTtcbiAgICB0aGlzLmFsYWRpbi5hZGRPdmVybGF5KG92ZXJsYXkpO1xuICAgIGZvciAoY29uc3QgcmVnaW9uIG9mIHJlZ2lvbnMpIHtcbiAgICAgIGNvbnN0IGluZm9zID0gcmVnaW9uW1wiaW5mb3NcIl07XG4gICAgICBzd2l0Y2ggKHJlZ2lvbltcInJlZ2lvbl90eXBlXCJdKSB7XG4gICAgICAgIGNhc2UgXCJzdGNzXCI6XG4gICAgICAgICAgb3ZlcmxheS5hZGRGb290cHJpbnRzKFxuICAgICAgICAgICAgQS5mb290cHJpbnRzRnJvbVNUQ1MoaW5mb3Muc3RjcywgcmVnaW9uLm9wdGlvbnMpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJjaXJjbGVcIjpcbiAgICAgICAgICBvdmVybGF5LmFkZChcbiAgICAgICAgICAgIEEuY2lyY2xlKGluZm9zLnJhLCBpbmZvcy5kZWMsIGluZm9zLnJhZGl1cywgcmVnaW9uLm9wdGlvbnMpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJlbGxpcHNlXCI6XG4gICAgICAgICAgb3ZlcmxheS5hZGQoXG4gICAgICAgICAgICBBLmVsbGlwc2UoXG4gICAgICAgICAgICAgIGluZm9zLnJhLFxuICAgICAgICAgICAgICBpbmZvcy5kZWMsXG4gICAgICAgICAgICAgIGluZm9zLmEsXG4gICAgICAgICAgICAgIGluZm9zLmIsXG4gICAgICAgICAgICAgIGluZm9zLnRoZXRhLFxuICAgICAgICAgICAgICByZWdpb24ub3B0aW9ucyxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImxpbmVcIjpcbiAgICAgICAgICAvLyByZW1vdmUgZGVmYXVsdCBsaW5lV2lkdGggd2hlbiB3ZSBzd2l0Y2ggdG8gQUwgPiAzLjQuNFxuICAgICAgICAgIHJlZ2lvbi5vcHRpb25zLmxpbmVXaWR0aCA9IHJlZ2lvbi5vcHRpb25zLmxpbmVXaWR0aCB8fCAzO1xuICAgICAgICAgIG92ZXJsYXkuYWRkKFxuICAgICAgICAgICAgQS52ZWN0b3IoXG4gICAgICAgICAgICAgIGluZm9zLnJhMSxcbiAgICAgICAgICAgICAgaW5mb3MuZGVjMSxcbiAgICAgICAgICAgICAgaW5mb3MucmEyLFxuICAgICAgICAgICAgICBpbmZvcy5kZWMyLFxuICAgICAgICAgICAgICByZWdpb24ub3B0aW9ucyxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcInBvbHlnb25cIjpcbiAgICAgICAgICBvdmVybGF5LmFkZChBLnBvbHlnb24oaW5mb3MudmVydGljZXMsIHJlZ2lvbi5vcHRpb25zKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlQ2hhbmdlQ29sb3JtYXAobXNnKSB7XG4gICAgdGhpcy5hbGFkaW4uZ2V0QmFzZUltYWdlTGF5ZXIoKS5zZXRDb2xvcm1hcChtc2dbXCJjb2xvcm1hcFwiXSk7XG4gIH1cblxuICBoYW5kbGVHZXRKUEdUaHVtYm5haWwoKSB7XG4gICAgdGhpcy5hbGFkaW4uZXhwb3J0QXNQTkcoKTtcbiAgfVxuXG4gIGhhbmRsZVRyaWdnZXJSZWN0YW5ndWxhclNlbGVjdGlvbigpIHtcbiAgICB0aGlzLmFsYWRpbi5zZWxlY3QoKTtcbiAgfVxuXG4gIGhhbmRsZUFkZFRhYmxlKG1zZywgYnVmZmVycykge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBjb252ZXJ0T3B0aW9uTmFtZXNUb0NhbWVsQ2FzZShtc2dbXCJvcHRpb25zXCJdIHx8IHt9KTtcbiAgICBjb25zdCBidWZmZXIgPSBidWZmZXJzWzBdLmJ1ZmZlcjtcbiAgICBjb25zdCBkZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKFwidXRmLThcIik7XG4gICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtkZWNvZGVyLmRlY29kZShidWZmZXIpXSk7XG4gICAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICBBLmNhdGFsb2dGcm9tVVJMKFxuICAgICAgdXJsLFxuICAgICAgT2JqZWN0LmFzc2lnbihvcHRpb25zLCB7IG9uQ2xpY2s6IFwic2hvd1RhYmxlXCIgfSksXG4gICAgICAoY2F0YWxvZykgPT4ge1xuICAgICAgICB0aGlzLmFsYWRpbi5hZGRDYXRhbG9nKGNhdGFsb2cpO1xuICAgICAgfSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICB9XG59XG4iLCAiaW1wb3J0IE1lc3NhZ2VIYW5kbGVyIGZyb20gXCIuL21lc3NhZ2VfaGFuZGxlclwiO1xuaW1wb3J0IHsgZGl2TnVtYmVyLCBzZXREaXZOdW1iZXIsIExvY2sgfSBmcm9tIFwiLi4vdXRpbHNcIjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXZlbnRIYW5kbGVyIHtcbiAgLyoqXG4gICAqIENvbnN0cnVjdG9yIGZvciB0aGUgRXZlbnRIYW5kbGVyIGNsYXNzLlxuICAgKiBAcGFyYW0gYWxhZGluIFRoZSBBbGFkaW4gaW5zdGFuY2VcbiAgICogQHBhcmFtIGFsYWRpbkRpdiBUaGUgQWxhZGluIGRpdlxuICAgKiBAcGFyYW0gbW9kZWwgVGhlIG1vZGVsIGluc3RhbmNlXG4gICAqL1xuICBjb25zdHJ1Y3RvcihhbGFkaW4sIGFsYWRpbkRpdiwgbW9kZWwpIHtcbiAgICB0aGlzLmFsYWRpbiA9IGFsYWRpbjtcbiAgICB0aGlzLmFsYWRpbkRpdiA9IGFsYWRpbkRpdjtcbiAgICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gICAgdGhpcy5tZXNzYWdlSGFuZGxlciA9IG5ldyBNZXNzYWdlSGFuZGxlcihhbGFkaW4sIG1vZGVsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGN1cnJlbnQgZGl2IGlzIHRoZSBsYXN0IGFjdGl2ZSBkaXYuXG4gICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgKi9cbiAgaXNMYXN0RGl2KCkge1xuICAgIGxldCBjdXJyZW50RGl2TnVtYmVyID0gcGFyc2VJbnQodGhpcy5hbGFkaW5EaXYuaWQuc3BsaXQoXCItXCIpLnBvcCgpKVxuICAgIGlmIChjdXJyZW50RGl2TnVtYmVyID09PSBkaXZOdW1iZXIpe1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9O1xuICAgIGxldCBtYXhEaXYgPSBkaXZOdW1iZXI7XG4gICAgZm9yIChsZXQgaSA9IG1heERpdjsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IGFsRGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYGFsYWRpbi1saXRlLWRpdi0ke2l9YCk7XG4gICAgICBpZiAoIWFsRGl2KSBjb250aW51ZTtcbiAgICAgIGlmIChhbERpdi5zdHlsZS5kaXNwbGF5ICE9PSBcIm5vbmVcIikge1xuICAgICAgICBtYXhEaXYgPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgc2V0RGl2TnVtYmVyKG1heERpdik7XG4gICAgcmV0dXJuIGN1cnJlbnREaXZOdW1iZXIgPT09IG1heERpdjtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHRoZSBXQ1MgY29vcmRpbmF0ZXMgaW4gdGhlIG1vZGVsLlxuICAgKiBXQVJOSU5HOiBUaGlzIG1ldGhvZCBkb24ndCBjYWxsIG1vZGVsLnNhdmVfY2hhbmdlcygpIVxuICAgKi9cbiAgdXBkYXRlV0NTKCkge1xuICAgIGlmICghdGhpcy5pc0xhc3REaXYoKSkgcmV0dXJuO1xuICAgIHRoaXMubW9kZWwuc2V0KFwiX3djc1wiLCB0aGlzLmFsYWRpbi5nZXRWaWV3V0NTKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIDItYXhpcyBGb1YgaW4gdGhlIG1vZGVsLlxuICAgKiBXQVJOSU5HOiBUaGlzIG1ldGhvZCBkb24ndCBjYWxsIG1vZGVsLnNhdmVfY2hhbmdlcygpIVxuICAgKi9cbiAgdXBkYXRlMkF4aXNGb1YoKSB7XG4gICAgaWYgKCF0aGlzLmlzTGFzdERpdigpKSByZXR1cm47XG4gICAgY29uc3QgdHdvQXhpc0ZvViA9IHRoaXMuYWxhZGluLmdldEZvdigpO1xuICAgIHRoaXMubW9kZWwuc2V0KFwiX2Zvdl94eVwiLCB7XG4gICAgICB4OiB0d29BeGlzRm9WWzBdLFxuICAgICAgeTogdHdvQXhpc0ZvVlsxXSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmVzIHRvIGFsbCB0aGUgZXZlbnRzIG5lZWRlZCBmb3IgdGhlIEFsYWRpbiBMaXRlIHdpZGdldC5cbiAgICovXG4gIHN1YnNjcmliZUFsbCgpIHtcbiAgICAvKiAtLS0tLS0tLS0tLS0tLS0tLS0tICovXG4gICAgLyogTGlzdGVuZXJzIC0tLS0tLS0tLSAqL1xuICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuICAgIC8qIFBvc2l0aW9uIENvbnRyb2wgKi9cbiAgICAvLyB0aGVyZSBhcmUgdHdvIHdheXMgb2YgY2hhbmdpbmcgdGhlIHRhcmdldCwgb25lIGZyb20gdGhlIGphdmFzY3JpcHQgc2lkZSwgYW5kXG4gICAgLy8gb25lIGZyb20gdGhlIHB5dGhvbiBzaWRlLiBXZSBoYXZlIHRvIGluc3RhbnRpYXRlIHR3byBsaXN0ZW5lcnMgZm9yIHRoZXNlLCBidXRcbiAgICAvLyB0aGUgZ290b09iamVjdCBjYWxsIHNob3VsZCBvbmx5IGhhcHBlbiBvbmNlLiBUaGUgdHdvIGJvb2xlYW5zIHByZXZlbnQgdGhlIHR3b1xuICAgIC8vIGxpc3RlbmVycyBmcm9tIHRyaWdnZXJpbmcgZWFjaCBvdGhlciBhbmQgY3JlYXRpbmcgYSBidWdneSBsb29wLiBUaGUgc2FtZSB0cmlja1xuICAgIC8vIGlzIGFsc28gbmVjZXNzYXJ5IGZvciB0aGUgZmllbGQgb2Ygdmlldy5cblxuICAgIC8qIFRhcmdldCBjb250cm9sICovXG4gICAgY29uc3QganNUYXJnZXRMb2NrID0gbmV3IExvY2soKTtcbiAgICBjb25zdCBweVRhcmdldExvY2sgPSBuZXcgTG9jaygpO1xuXG4gICAgLy8gRXZlbnQgdHJpZ2dlcmVkIHdoZW4gdGhlIHVzZXIgbW92ZXMgdGhlIG1hcCBpbiBBbGFkaW4gTGl0ZVxuICAgIHRoaXMuYWxhZGluLm9uKFwicG9zaXRpb25DaGFuZ2VkXCIsIChwb3NpdGlvbikgPT4ge1xuICAgICAgaWYgKHB5VGFyZ2V0TG9jay5sb2NrZWQpIHtcbiAgICAgICAgcHlUYXJnZXRMb2NrLnVubG9jaygpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBqc1RhcmdldExvY2subG9jaygpO1xuICAgICAgY29uc3QgcmFEZWMgPSBbcG9zaXRpb24ucmEsIHBvc2l0aW9uLmRlY107XG4gICAgICB0aGlzLnVwZGF0ZVdDUygpO1xuICAgICAgdGhpcy5tb2RlbC5zZXQoXCJfdGFyZ2V0XCIsIGAke3JhRGVjWzBdfSAke3JhRGVjWzFdfWApO1xuICAgICAgdGhpcy5tb2RlbC5zYXZlX2NoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIHRoaXMubW9kZWwub24oXCJjaGFuZ2U6X3RhcmdldFwiLCAoKSA9PiB7XG4gICAgICBpZiAoanNUYXJnZXRMb2NrLmxvY2tlZCkge1xuICAgICAgICBqc1RhcmdldExvY2sudW5sb2NrKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHB5VGFyZ2V0TG9jay5sb2NrKCk7XG4gICAgICBsZXQgdGFyZ2V0ID0gdGhpcy5tb2RlbC5nZXQoXCJfdGFyZ2V0XCIpO1xuICAgICAgY29uc3QgW3JhLCBkZWNdID0gdGFyZ2V0LnNwbGl0KFwiIFwiKTtcbiAgICAgIHRoaXMuYWxhZGluLmdvdG9SYURlYyhyYSwgZGVjKTtcbiAgICB9KTtcblxuICAgIC8qIEZpZWxkIG9mIFZpZXcgY29udHJvbCAqL1xuICAgIGNvbnN0IGpzRm92TG9jayA9IG5ldyBMb2NrKCk7XG4gICAgY29uc3QgcHlGb3ZMb2NrID0gbmV3IExvY2soKTtcblxuICAgIHRoaXMuYWxhZGluLm9uKFwiem9vbUNoYW5nZWRcIiwgKGZvdikgPT4ge1xuICAgICAgaWYgKHB5Rm92TG9jay5sb2NrZWQpIHtcbiAgICAgICAgcHlGb3ZMb2NrLnVubG9jaygpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBqc0ZvdkxvY2subG9jaygpO1xuICAgICAgLy8gZm92IE1VU1QgYmUgY2FzdCBpbnRvIGZsb2F0IGluIG9yZGVyIHRvIGJlIHNlbnQgdG8gdGhlIG1vZGVsXG4gICAgICB0aGlzLnVwZGF0ZVdDUygpO1xuICAgICAgdGhpcy51cGRhdGUyQXhpc0ZvVigpO1xuICAgICAgdGhpcy5tb2RlbC5zZXQoXCJfZm92XCIsIHBhcnNlRmxvYXQoZm92LnRvRml4ZWQoNSkpKTtcbiAgICAgIHRoaXMubW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLm1vZGVsLm9uKFwiY2hhbmdlOl9mb3ZcIiwgKCkgPT4ge1xuICAgICAgaWYgKGpzRm92TG9jay5sb2NrZWQpIHtcbiAgICAgICAganNGb3ZMb2NrLnVubG9jaygpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBweUZvdkxvY2subG9jaygpO1xuICAgICAgbGV0IGZvdiA9IHRoaXMubW9kZWwuZ2V0KFwiX2ZvdlwiKTtcbiAgICAgIHRoaXMuYWxhZGluLnNldEZvVihmb3YpO1xuICAgIH0pO1xuXG4gICAgLyogRGl2IGNvbnRyb2wgKi9cbiAgICB0aGlzLm1vZGVsLm9uKFwiY2hhbmdlOl9oZWlnaHRcIiwgKCkgPT4ge1xuICAgICAgbGV0IGhlaWdodCA9IHRoaXMubW9kZWwuZ2V0KFwiX2hlaWdodFwiKTtcbiAgICAgIHRoaXMuYWxhZGluRGl2LnN0eWxlLmhlaWdodCA9IGAke2hlaWdodH1weGA7XG4gICAgICAvLyBVcGRhdGUgV0NTIGFuZCBGb1Ygb25seSBpZiB0aGlzIGlzIHRoZSBsYXN0IGRpdlxuICAgICAgdGhpcy51cGRhdGVXQ1MoKTtcbiAgICAgIHRoaXMudXBkYXRlMkF4aXNGb1YoKTtcbiAgICAgIHRoaXMubW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG4gICAgfSk7XG5cbiAgICAvKiBBbGFkaW4gY2FsbGJhY2tzICovXG5cbiAgICB0aGlzLmFsYWRpbi5vbihcImNvb0ZyYW1lQ2hhbmdlZFwiLCAoKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZVdDUygpO1xuICAgICAgdGhpcy5tb2RlbC5zYXZlX2NoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuYWxhZGluLm9uKFwicHJvamVjdGlvbkNoYW5nZWRcIiwgKCkgPT4ge1xuICAgICAgdGhpcy51cGRhdGVXQ1MoKTtcbiAgICAgIHRoaXMubW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFsYWRpbi5vbihcImxheWVyQ2hhbmdlZFwiLCAoXywgbGF5ZXJOYW1lLCBzdGF0ZSkgPT4ge1xuICAgICAgaWYgKGxheWVyTmFtZSAhPT0gXCJiYXNlXCIgfHwgc3RhdGUgIT09IFwiQURERURcIikgcmV0dXJuO1xuICAgICAgdGhpcy51cGRhdGVXQ1MoKTtcbiAgICAgIHRoaXMubW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFsYWRpbi5vbihcInJlc2l6ZUNoYW5nZWRcIiwgKCkgPT4ge1xuICAgICAgdGhpcy51cGRhdGVXQ1MoKTtcbiAgICAgIHRoaXMudXBkYXRlMkF4aXNGb1YoKTtcbiAgICAgIHRoaXMubW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFsYWRpbi5vbihcIm9iamVjdEhvdmVyZWRcIiwgKG9iamVjdCkgPT4ge1xuICAgICAgaWYgKG9iamVjdFtcImRhdGFcIl0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLm1vZGVsLnNlbmQoe1xuICAgICAgICAgIGV2ZW50X3R5cGU6IFwib2JqZWN0X2hvdmVyZWRcIixcbiAgICAgICAgICBjb250ZW50OiB7XG4gICAgICAgICAgICByYTogb2JqZWN0W1wicmFcIl0sXG4gICAgICAgICAgICBkZWM6IG9iamVjdFtcImRlY1wiXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuYWxhZGluLm9uKFwib2JqZWN0Q2xpY2tlZFwiLCAoY2xpY2tlZCkgPT4ge1xuICAgICAgaWYgKGNsaWNrZWQpIHtcbiAgICAgICAgbGV0IGNsaWNrZWRDb250ZW50ID0ge1xuICAgICAgICAgIHJhOiBjbGlja2VkW1wicmFcIl0sXG4gICAgICAgICAgZGVjOiBjbGlja2VkW1wiZGVjXCJdLFxuICAgICAgICB9O1xuICAgICAgICBpZiAoY2xpY2tlZFtcImRhdGFcIl0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNsaWNrZWRDb250ZW50W1wiZGF0YVwiXSA9IGNsaWNrZWRbXCJkYXRhXCJdO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubW9kZWwuc2V0KFwiY2xpY2tlZF9vYmplY3RcIiwgY2xpY2tlZENvbnRlbnQpO1xuICAgICAgICAvLyBzZW5kIGEgY3VzdG9tIG1lc3NhZ2UgaW4gY2FzZSB0aGUgdXNlciB3YW50cyB0byBkZWZpbmUgdGhlaXIgb3duIGNhbGxiYWNrc1xuICAgICAgICB0aGlzLm1vZGVsLnNlbmQoe1xuICAgICAgICAgIGV2ZW50X3R5cGU6IFwib2JqZWN0X2NsaWNrZWRcIixcbiAgICAgICAgICBjb250ZW50OiBjbGlja2VkQ29udGVudCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmFsYWRpbi5vbihcImNsaWNrXCIsIChjbGlja0NvbnRlbnQpID0+IHtcbiAgICAgIHRoaXMubW9kZWwuc2VuZCh7XG4gICAgICAgIGV2ZW50X3R5cGU6IFwiY2xpY2tcIixcbiAgICAgICAgY29udGVudDogY2xpY2tDb250ZW50LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFsYWRpbi5vbihcInNlbGVjdFwiLCAoY2F0YWxvZ3MpID0+IHtcbiAgICAgIGxldCBvYmplY3RzRGF0YSA9IFtdO1xuICAgICAgLy8gVE9ETzogdGhpcyBmbGF0dGVucyB0aGUgc2VsZWN0aW9uLiBFYWNoIG9iamVjdCBmcm9tIGRpZmZlcmVudFxuICAgICAgLy8gY2F0YWxvZ3MgYXJlIGVudGVyZWQgaW4gdGhlIGFycmF5LiBUbyBjaGFuZ2UgdGhpcywgbWF5YmUgY2hhbmdlXG4gICAgICAvLyB1cHN0cmVhbSB3aGF0IGlzIHJldHVybmVkIHVwb24gc2VsZWN0aW9uP1xuICAgICAgY2F0YWxvZ3MuZm9yRWFjaCgoY2F0YWxvZykgPT4ge1xuICAgICAgICBjYXRhbG9nLmZvckVhY2goKG9iamVjdCkgPT4ge1xuICAgICAgICAgIG9iamVjdHNEYXRhLnB1c2goe1xuICAgICAgICAgICAgcmE6IG9iamVjdC5yYSxcbiAgICAgICAgICAgIGRlYzogb2JqZWN0LmRlYyxcbiAgICAgICAgICAgIGRhdGE6IG9iamVjdC5kYXRhLFxuICAgICAgICAgICAgeDogb2JqZWN0LngsXG4gICAgICAgICAgICB5OiBvYmplY3QueSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMubW9kZWwuc2VuZCh7XG4gICAgICAgIGV2ZW50X3R5cGU6IFwic2VsZWN0XCIsXG4gICAgICAgIGNvbnRlbnQ6IG9iamVjdHNEYXRhLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvKiBBbGFkaW4gZnVuY3Rpb25hbGl0aWVzICovXG5cbiAgICB0aGlzLm1vZGVsLm9uKFwiY2hhbmdlOmNvb19mcmFtZVwiLCAoKSA9PiB7XG4gICAgICB0aGlzLmFsYWRpbi5zZXRGcmFtZSh0aGlzLm1vZGVsLmdldChcImNvb19mcmFtZVwiKSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLm1vZGVsLm9uKFwiY2hhbmdlOnN1cnZleVwiLCAoKSA9PiB7XG4gICAgICB0aGlzLmFsYWRpbi5zZXRJbWFnZVN1cnZleSh0aGlzLm1vZGVsLmdldChcInN1cnZleVwiKSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLm1vZGVsLm9uKFwiY2hhbmdlOm92ZXJsYXlfc3VydmV5XCIsICgpID0+IHtcbiAgICAgIHRoaXMuYWxhZGluLnNldE92ZXJsYXlJbWFnZUxheWVyKHRoaXMubW9kZWwuZ2V0KFwib3ZlcmxheV9zdXJ2ZXlcIikpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5tb2RlbC5vbihcImNoYW5nZTpvdmVybGF5X3N1cnZleV9vcGFjaXR5XCIsICgpID0+IHtcbiAgICAgIHRoaXMuYWxhZGluXG4gICAgICAgIC5nZXRPdmVybGF5SW1hZ2VMYXllcigpXG4gICAgICAgIC5zZXRBbHBoYSh0aGlzLm1vZGVsLmdldChcIm92ZXJsYXlfc3VydmV5X29wYWNpdHlcIikpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5ldmVudEhhbmRsZXJzID0ge1xuICAgICAgY2hhbmdlX2ZvdjogdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVDaGFuZ2VGb1YsXG4gICAgICBnb3RvX3JhX2RlYzogdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVHb3RvUmFEZWMsXG4gICAgICBhZGRfZml0czogdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVBZGRGaXRzLFxuICAgICAgYWRkX2NhdGFsb2dfZnJvbV9VUkw6IHRoaXMubWVzc2FnZUhhbmRsZXIuaGFuZGxlQWRkQ2F0YWxvZ0Zyb21VUkwsXG4gICAgICBhZGRfTU9DX2Zyb21fVVJMOiB0aGlzLm1lc3NhZ2VIYW5kbGVyLmhhbmRsZUFkZE1PQ0Zyb21VUkwsXG4gICAgICBhZGRfTU9DX2Zyb21fZGljdDogdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVBZGRNT0NGcm9tRGljdCxcbiAgICAgIGFkZF9vdmVybGF5OiB0aGlzLm1lc3NhZ2VIYW5kbGVyLmhhbmRsZUFkZE92ZXJsYXksXG4gICAgICBjaGFuZ2VfY29sb3JtYXA6IHRoaXMubWVzc2FnZUhhbmRsZXIuaGFuZGxlQ2hhbmdlQ29sb3JtYXAsXG4gICAgICBnZXRfSlBHX3RodW1ibmFpbDogdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVHZXRKUEdUaHVtYm5haWwsXG4gICAgICB0cmlnZ2VyX3JlY3Rhbmd1bGFyX3NlbGVjdGlvbjpcbiAgICAgICAgdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVUcmlnZ2VyUmVjdGFuZ3VsYXJTZWxlY3Rpb24sXG4gICAgICBhZGRfdGFibGU6IHRoaXMubWVzc2FnZUhhbmRsZXIuaGFuZGxlQWRkVGFibGUsXG4gICAgfTtcblxuICAgIHRoaXMubW9kZWwub24oXCJtc2c6Y3VzdG9tXCIsIChtc2csIGJ1ZmZlcnMpID0+IHtcbiAgICAgIGNvbnN0IGV2ZW50TmFtZSA9IG1zZ1tcImV2ZW50X25hbWVcIl07XG4gICAgICBjb25zdCBoYW5kbGVyID0gdGhpcy5ldmVudEhhbmRsZXJzW2V2ZW50TmFtZV07XG4gICAgICBpZiAoaGFuZGxlcikgaGFuZGxlci5jYWxsKHRoaXMsIG1zZywgYnVmZmVycyk7XG4gICAgICBlbHNlIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBldmVudCBuYW1lOiAke2V2ZW50TmFtZX1gKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnN1YnNjcmliZSBmcm9tIGFsbCB0aGUgbW9kZWwgZXZlbnRzLlxuICAgKiBUaGVyZSBpcyBubyBuZWVkIHRvIHVuc3Vic2NyaWJlIGZyb20gdGhlIEFsYWRpbiBMaXRlIGV2ZW50cy5cbiAgICovXG4gIHVuc3Vic2NyaWJlQWxsKCkge1xuICAgIHRoaXMubW9kZWwub2ZmKFwiY2hhbmdlOl90YXJnZXRcIik7XG4gICAgdGhpcy5tb2RlbC5vZmYoXCJjaGFuZ2U6X2ZvdlwiKTtcbiAgICB0aGlzLm1vZGVsLm9mZihcImNoYW5nZTpfaGVpZ2h0XCIpO1xuICAgIHRoaXMubW9kZWwub2ZmKFwiY2hhbmdlOmNvb19mcmFtZVwiKTtcbiAgICB0aGlzLm1vZGVsLm9mZihcImNoYW5nZTpzdXJ2ZXlcIik7XG4gICAgdGhpcy5tb2RlbC5vZmYoXCJjaGFuZ2U6b3ZlcmxheV9zdXJ2ZXlcIik7XG4gICAgdGhpcy5tb2RlbC5vZmYoXCJjaGFuZ2U6b3ZlcmxheV9zdXJ2ZXlfb3BhY2l0eVwiKTtcbiAgICB0aGlzLm1vZGVsLm9mZihcImNoYW5nZTp0cmlnZ2VyX2V2ZW50XCIpO1xuICAgIHRoaXMubW9kZWwub2ZmKFwibXNnOmN1c3RvbVwiKTtcbiAgfVxufVxuIiwgImltcG9ydCBcIi4vd2lkZ2V0LmNzc1wiO1xuaW1wb3J0IEV2ZW50SGFuZGxlciBmcm9tIFwiLi9tb2RlbHMvZXZlbnRfaGFuZGxlclwiO1xuaW1wb3J0IHtcbiAgZGl2TnVtYmVyLFxuICBzZXREaXZOdW1iZXIsXG4gIHNuYWtlQ2FzZVRvQ2FtZWxDYXNlLFxufSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IEEgZnJvbSBcIi4vYWxhZGluX2xpdGVcIjtcblxuZnVuY3Rpb24gaW5pdEFsYWRpbkxpdGUobW9kZWwsIGVsKSB7XG4gIHNldERpdk51bWJlcihkaXZOdW1iZXIgKyAxKTtcbiAgbGV0IGluaXRPcHRpb25zID0ge307XG4gIG1vZGVsLmdldChcImluaXRfb3B0aW9uc1wiKS5mb3JFYWNoKChvcHRpb25fbmFtZSkgPT4ge1xuICAgIGluaXRPcHRpb25zW3NuYWtlQ2FzZVRvQ2FtZWxDYXNlKG9wdGlvbl9uYW1lKV0gPSBtb2RlbC5nZXQob3B0aW9uX25hbWUpO1xuICB9KTtcblxuICBsZXQgYWxhZGluRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgYWxhZGluRGl2LmNsYXNzTGlzdC5hZGQoXCJhbGFkaW4td2lkZ2V0XCIpO1xuICBhbGFkaW5EaXYuc3R5bGUuaGVpZ2h0ID0gYCR7aW5pdE9wdGlvbnNbXCJoZWlnaHRcIl19cHhgO1xuXG4gIGFsYWRpbkRpdi5pZCA9IGBhbGFkaW4tbGl0ZS1kaXYtJHtkaXZOdW1iZXJ9YDtcbiAgbGV0IGFsYWRpbiA9IG5ldyBBLmFsYWRpbihhbGFkaW5EaXYsIGluaXRPcHRpb25zKTtcblxuICAvLyBTZXQgdGhlIHRhcmdldCBhZ2FpbiBhZnRlciB0aGUgaW5pdGlhbGl6YXRpb24gdG8gYmUgc3VyZSB0aGF0IHRoZSB0YXJnZXQgaXMgc2V0XG4gIC8vIGZyb20gaWNycyBjb29yZGluYXRlcyBiZWNhdXNlIG9mIHRoZSB1c2Ugb2YgZ290b09iamVjdCBpbiB0aGUgQWxhZGluIExpdGUgQVBJXG4gIGNvbnN0IHJhRGVjID0gaW5pdE9wdGlvbnNbXCJ0YXJnZXRcIl0uc3BsaXQoXCIgXCIpO1xuICBhbGFkaW4uZ290b1JhRGVjKHJhRGVjWzBdLCByYURlY1sxXSk7XG5cbiAgLy8gU2V0IGN1cnJlbnQgRm9WIGFuZCBXQ1NcbiAgY29uc3QgdHdvQXhpc0ZvViA9IGFsYWRpbi5nZXRGb3YoKTtcbiAgbW9kZWwuc2V0KFwiX2Zvdl94eVwiLCB7XG4gICAgeDogdHdvQXhpc0ZvVlswXSxcbiAgICB5OiB0d29BeGlzRm9WWzFdLFxuICB9KTtcbiAgbW9kZWwuc2V0KFwiX3djc1wiLCBhbGFkaW4uZ2V0Vmlld1dDUygpKTtcbiAgbW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG5cbiAgZWwuYXBwZW5kQ2hpbGQoYWxhZGluRGl2KTtcbiAgcmV0dXJuIHsgYWxhZGluLCBhbGFkaW5EaXYgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gaW5pdGlhbGl6ZSh7IG1vZGVsIH0pIHtcbiAgYXdhaXQgQS5pbml0O1xufVxuXG5mdW5jdGlvbiByZW5kZXIoeyBtb2RlbCwgZWwgfSkge1xuICAvKiAtLS0tLS0tLS0tLS0tLS0tLS0tICovXG4gIC8qIFZpZXcgLS0tLS0tLS0tLS0tLS0gKi9cbiAgLyogLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4gIGNvbnN0IHsgYWxhZGluLCBhbGFkaW5EaXYgfSA9IGluaXRBbGFkaW5MaXRlKG1vZGVsLCBlbCk7XG5cbiAgY29uc3QgZXZlbnRIYW5kbGVyID0gbmV3IEV2ZW50SGFuZGxlcihhbGFkaW4sIGFsYWRpbkRpdiwgbW9kZWwpO1xuICBldmVudEhhbmRsZXIuc3Vic2NyaWJlQWxsKCk7XG5cbiAgcmV0dXJuICgpID0+IHtcbiAgICAvLyBOZWVkIHRvIHVuc3Vic2NyaWJlIHRoZSBsaXN0ZW5lcnNcbiAgICBldmVudEhhbmRsZXIudW5zdWJzY3JpYmVBbGwoKTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgeyBpbml0aWFsaXplLCByZW5kZXIgfTtcbiJdLAogICJtYXBwaW5ncyI6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LEtBQUssRUFDNUNBLEVBQVUsVUFBVSxJQUFJLGVBQWUsRUFDdkNBLEVBQVUsTUFBTSxPQUFTLEdBQUdILEVBQVksTUFBUyxLQUVqREcsRUFBVSxHQUFLLG1CQUFtQkosQ0FBUyxHQUMzQyxJQUFJSyxFQUFTLElBQUlDLEVBQUUsT0FBT0YsRUFBV0gsQ0FBVyxFQUkxQ00sRUFBUU4sRUFBWSxPQUFVLE1BQU0sR0FBRyxFQUM3Q0ksRUFBTyxVQUFVRSxFQUFNLENBQUMsRUFBR0EsRUFBTSxDQUFDLENBQUMsRUFHbkMsSUFBTUMsRUFBYUgsRUFBTyxPQUFPLEVBQ2pDLE9BQUFSLEVBQU0sSUFBSSxVQUFXLENBQ25CLEVBQUdXLEVBQVcsQ0FBQyxFQUNmLEVBQUdBLEVBQVcsQ0FBQyxDQUNqQixDQUFDLEVBQ0RYLEVBQU0sSUFBSSxPQUFRUSxFQUFPLFdBQVcsQ0FBQyxFQUNyQ1IsRUFBTSxhQUFhLEVBRW5CQyxFQUFHLFlBQVlNLENBQVMsRUFDakIsQ0FBRSxPQUFBQyxFQUFRLFVBQUFELENBQVUsQ0FDN0IsQ0FFQSxlQUFlSyxFQUFXLENBQUUsTUFBQVosQ0FBTSxFQUFHLENBQ25DLE1BQU1TLEVBQUUsSUFDVixDQUVBLFNBQVNJLEVBQU8sQ0FBRSxNQUFBYixFQUFPLEdBQUFDLENBQUcsRUFBRyxDQUs3QixHQUFNLENBQUUsT0FBQU8sRUFBUSxVQUFBRCxDQUFVLEVBQUlSLEVBQWVDLEVBQU9DLENBQUUsRUFFaERhLEVBQWUsSUFBSUMsRUFBYVAsRUFBUUQsRUFBV1AsQ0FBSyxFQUM5RCxPQUFBYyxFQUFhLGFBQWEsRUFFbkIsSUFBTSxDQUVYQSxFQUFhLGVBQWUsQ0FDOUIsQ0FDRixDQUVBLElBQU9FLEVBQVEsQ0FBRSxXQUFBSixFQUFZLE9BQUFDLENBQU8iLAogICJuYW1lcyI6IFsic25ha2VDYXNlVG9DYW1lbENhc2UiLCAic25ha2VDYXNlU3RyIiwgInRlbXAiLCAiaSIsICJjb252ZXJ0T3B0aW9uTmFtZXNUb0NhbWVsQ2FzZSIsICJvcHRpb25zIiwgIm5ld09wdGlvbnMiLCAib3B0aW9uTmFtZSIsICJMb2NrIiwgImRpdk51bWJlciIsICJzZXREaXZOdW1iZXIiLCAibnVtIiwgIkEiLCAiYWxhZGluX2xpdGVfZGVmYXVsdCIsICJpbWFnZUNvdW50IiwgIk1lc3NhZ2VIYW5kbGVyIiwgImFsYWRpbiIsICJtb2RlbCIsICJtc2ciLCAiYnVmZmVycyIsICJvcHRpb25zIiwgImNvbnZlcnRPcHRpb25OYW1lc1RvQ2FtZWxDYXNlIiwgImJ1ZmZlciIsICJibG9iIiwgInVybCIsICJpbWFnZSIsICJyYSIsICJkZWMiLCAiYWxhZGluX2xpdGVfZGVmYXVsdCIsICJyZWdpb25zIiwgImdyYXBoaWNfb3B0aW9ucyIsICJvdmVybGF5IiwgInJlZ2lvbiIsICJpbmZvcyIsICJkZWNvZGVyIiwgImNhdGFsb2ciLCAiRXZlbnRIYW5kbGVyIiwgImFsYWRpbiIsICJhbGFkaW5EaXYiLCAibW9kZWwiLCAiTWVzc2FnZUhhbmRsZXIiLCAiY3VycmVudERpdk51bWJlciIsICJkaXZOdW1iZXIiLCAibWF4RGl2IiwgImFsRGl2IiwgInNldERpdk51bWJlciIsICJ0d29BeGlzRm9WIiwgImpzVGFyZ2V0TG9jayIsICJMb2NrIiwgInB5VGFyZ2V0TG9jayIsICJwb3NpdGlvbiIsICJyYURlYyIsICJ0YXJnZXQiLCAicmEiLCAiZGVjIiwgImpzRm92TG9jayIsICJweUZvdkxvY2siLCAiZm92IiwgImhlaWdodCIsICJfIiwgImxheWVyTmFtZSIsICJzdGF0ZSIsICJvYmplY3QiLCAiY2xpY2tlZCIsICJjbGlja2VkQ29udGVudCIsICJjbGlja0NvbnRlbnQiLCAiY2F0YWxvZ3MiLCAib2JqZWN0c0RhdGEiLCAiY2F0YWxvZyIsICJtc2ciLCAiYnVmZmVycyIsICJldmVudE5hbWUiLCAiaGFuZGxlciIsICJpbml0QWxhZGluTGl0ZSIsICJtb2RlbCIsICJlbCIsICJzZXREaXZOdW1iZXIiLCAiZGl2TnVtYmVyIiwgImluaXRPcHRpb25zIiwgIm9wdGlvbl9uYW1lIiwgInNuYWtlQ2FzZVRvQ2FtZWxDYXNlIiwgImFsYWRpbkRpdiIsICJhbGFkaW4iLCAiYWxhZGluX2xpdGVfZGVmYXVsdCIsICJyYURlYyIsICJ0d29BeGlzRm9WIiwgImluaXRpYWxpemUiLCAicmVuZGVyIiwgImV2ZW50SGFuZGxlciIsICJFdmVudEhhbmRsZXIiLCAid2lkZ2V0X2RlZmF1bHQiXQp9Cg==\n", - "_fov": 5.60143, + "_esm": "function f(n){n.charAt(0)===\"_\"&&(n=n.slice(1));let e=n.split(\"_\");for(let a=1;a{this.aladin.gotoRaDec(r,v),console.info(`FITS located at ra: ${r}, dec: ${v}`),URL.revokeObjectURL(o)});this.aladin.setOverlayImageLayer(d,i.name)}handleAddCatalogFromURL(e){let a=h(e.options||{});this.aladin.addCatalog(l.catalogFromURL(e.votable_URL,a))}handleAddMOCFromURL(e){let a=h(e.options||{});this.aladin.addMOC(l.MOCFromURL(e.moc_URL,a))}handleAddMOCFromDict(e){let a=h(e.options||{});this.aladin.addMOC(l.MOCFromJSON(e.moc_dict,a))}handleAddOverlay(e){let a=e.regions_infos,i=h(e.graphic_options||{});i.color||(i.color=\"red\");let s=l.graphicOverlay(i);this.aladin.addOverlay(s);for(let t of a){let o=t.infos;switch(t.region_type){case\"stcs\":s.addFootprints(l.footprintsFromSTCS(o.stcs,t.options));break;case\"circle\":s.add(l.circle(o.ra,o.dec,o.radius,t.options));break;case\"ellipse\":s.add(l.ellipse(o.ra,o.dec,o.a,o.b,o.theta,t.options));break;case\"line\":t.options.lineWidth=t.options.lineWidth||3,s.add(l.vector(o.ra1,o.dec1,o.ra2,o.dec2,t.options));break;case\"polygon\":s.add(l.polygon(o.vertices,t.options));break}}}handleChangeColormap(e){this.aladin.getBaseImageLayer().setColormap(e.colormap)}handleGetJPGThumbnail(){this.aladin.exportAsPNG()}handleTriggerRectangularSelection(){this.aladin.select()}handleAddTable(e,a){let i=h(e.options||{}),s=a[0].buffer,t=new TextDecoder(\"utf-8\"),o=new Blob([t.decode(s)]),d=URL.createObjectURL(o);l.catalogFromURL(d,Object.assign(i,{onClick:\"showTable\"}),r=>{this.aladin.addCatalog(r)},!1),URL.revokeObjectURL(d)}};var p=class{constructor(e,a,i){this.aladin=e,this.aladinDiv=a,this.model=i,this.messageHandler=new g(e,i),this.currentDivNumber=parseInt(a.id.split(\"-\").pop())}isLastDiv(){if(this.currentDivNumber===m)return!0;let e=m;for(let a=e;a>=0;a--){let i=document.getElementById(`aladin-lite-div-${a}`);if(i&&i.style.display!==\"none\"){e=a;break}}return u(e),this.currentDivNumber===e}updateWCS(){this.isLastDiv()&&this.model.set(\"_wcs\",this.aladin.getViewWCS())}update2AxisFoV(){if(!this.isLastDiv())return;let e=this.aladin.getFov();this.model.set(\"_fov_xy\",{x:e[0],y:e[1]})}subscribeAll(){let e=new c,a=new c;this.aladin.on(\"positionChanged\",t=>{if(a.locked){a.unlock();return}e.lock();let o=[t.ra,t.dec];this.updateWCS(),this.model.set(\"_target\",`${o[0]} ${o[1]}`),this.model.save_changes()}),this.model.on(\"change:_target\",()=>{if(e.locked){e.unlock();return}a.lock();let t=this.model.get(\"_target\"),[o,d]=t.split(\" \");this.aladin.gotoRaDec(o,d)});let i=new c,s=new c;this.aladin.on(\"zoomChanged\",t=>{if(s.locked){s.unlock();return}i.lock(),this.updateWCS(),this.update2AxisFoV(),this.model.set(\"_fov\",parseFloat(t.toFixed(5))),this.model.save_changes()}),this.model.on(\"change:_fov\",()=>{if(i.locked){i.unlock();return}s.lock();let t=this.model.get(\"_fov\");this.aladin.setFoV(t)}),this.model.on(\"change:_height\",()=>{let t=this.model.get(\"_height\");this.aladinDiv.style.height=`${t}px`,this.updateWCS(),this.update2AxisFoV(),this.model.save_changes()}),this.aladin.on(\"cooFrameChanged\",()=>{this.updateWCS(),this.model.save_changes()}),this.aladin.on(\"projectionChanged\",()=>{this.updateWCS(),this.model.save_changes()}),this.aladin.on(\"layerChanged\",(t,o,d)=>{o!==\"base\"||d!==\"ADDED\"||(this.updateWCS(),this.model.save_changes())}),this.aladin.on(\"resizeChanged\",()=>{this.updateWCS(),this.update2AxisFoV(),this.model.save_changes()}),this.aladin.on(\"objectHovered\",t=>{t.data!==void 0&&this.model.send({event_type:\"object_hovered\",content:{ra:t.ra,dec:t.dec}})}),this.aladin.on(\"objectClicked\",t=>{if(t){let o={ra:t.ra,dec:t.dec};t.data!==void 0&&(o.data=t.data),this.model.set(\"clicked_object\",o),this.model.send({event_type:\"object_clicked\",content:o}),this.model.save_changes()}}),this.aladin.on(\"click\",t=>{this.model.send({event_type:\"click\",content:t})}),this.aladin.on(\"select\",t=>{let o=[];t.forEach(d=>{d.forEach(r=>{o.push({ra:r.ra,dec:r.dec,data:r.data,x:r.x,y:r.y})})}),this.model.send({event_type:\"select\",content:o})}),this.model.on(\"change:coo_frame\",()=>{this.aladin.setFrame(this.model.get(\"coo_frame\"))}),this.model.on(\"change:survey\",()=>{this.aladin.setImageSurvey(this.model.get(\"survey\"))}),this.model.on(\"change:overlay_survey\",()=>{this.aladin.setOverlayImageLayer(this.model.get(\"overlay_survey\"))}),this.model.on(\"change:overlay_survey_opacity\",()=>{this.aladin.getOverlayImageLayer().setAlpha(this.model.get(\"overlay_survey_opacity\"))}),this.eventHandlers={change_fov:this.messageHandler.handleChangeFoV,goto_ra_dec:this.messageHandler.handleGotoRaDec,add_fits:this.messageHandler.handleAddFits,add_catalog_from_URL:this.messageHandler.handleAddCatalogFromURL,add_MOC_from_URL:this.messageHandler.handleAddMOCFromURL,add_MOC_from_dict:this.messageHandler.handleAddMOCFromDict,add_overlay:this.messageHandler.handleAddOverlay,change_colormap:this.messageHandler.handleChangeColormap,get_JPG_thumbnail:this.messageHandler.handleGetJPGThumbnail,trigger_rectangular_selection:this.messageHandler.handleTriggerRectangularSelection,add_table:this.messageHandler.handleAddTable},this.model.on(\"msg:custom\",(t,o)=>{let d=t.event_name,r=this.eventHandlers[d];if(r)r.call(this,t,o);else throw new Error(`Unknown event name: ${d}`)})}unsubscribeAll(){this.model.off(\"change:_target\"),this.model.off(\"change:_fov\"),this.model.off(\"change:_height\"),this.model.off(\"change:coo_frame\"),this.model.off(\"change:survey\"),this.model.off(\"change:overlay_survey\"),this.model.off(\"change:overlay_survey_opacity\"),this.model.off(\"change:trigger_event\"),this.model.off(\"msg:custom\")}};function b(n,e){u(m+1);let a={};n.get(\"init_options\").forEach(d=>{a[f(d)]=n.get(d)});let i=document.createElement(\"div\");i.classList.add(\"aladin-widget\"),i.style.height=`${a.height}px`,i.id=`aladin-lite-div-${m}`;let s=new l.aladin(i,a),t=a.target.split(\" \");s.gotoRaDec(t[0],t[1]);let o=s.getFov();return n.set(\"_fov_xy\",{x:o[0],y:o[1]}),n.set(\"_wcs\",s.getViewWCS()),n.save_changes(),e.appendChild(i),{aladin:s,aladinDiv:i}}async function C({model:n}){await l.init}function k({model:n,el:e}){let{aladin:a,aladinDiv:i}=b(n,e),s=new p(a,i,n);return s.subscribeAll(),()=>{s.unsubscribeAll()}}var j={initialize:C,render:k};export{j as default};\n//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vanMvdXRpbHMuanMiLCAiLi4vLi4vLi4vanMvYWxhZGluX2xpdGUuanMiLCAiLi4vLi4vLi4vanMvbW9kZWxzL21lc3NhZ2VfaGFuZGxlci5qcyIsICIuLi8uLi8uLi9qcy9tb2RlbHMvZXZlbnRfaGFuZGxlci5qcyIsICIuLi8uLi8uLi9qcy93aWRnZXQuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQ29udmVydHMgYSBzdHJpbmcgZnJvbSBjYW1lbENhc2UgdG8gc25ha2VfY2FzZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzbmFrZUNhc2VTdHIgLSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgc3RyaW5nIGNvbnZlcnRlZCB0byBzbmFrZV9jYXNlLlxuICovXG5mdW5jdGlvbiBzbmFrZUNhc2VUb0NhbWVsQ2FzZShzbmFrZUNhc2VTdHIpIHtcbiAgaWYgKHNuYWtlQ2FzZVN0ci5jaGFyQXQoMCkgPT09IFwiX1wiKSBzbmFrZUNhc2VTdHIgPSBzbmFrZUNhc2VTdHIuc2xpY2UoMSk7XG4gIGxldCB0ZW1wID0gc25ha2VDYXNlU3RyLnNwbGl0KFwiX1wiKTtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCB0ZW1wLmxlbmd0aDsgaSsrKVxuICAgIHRlbXBbaV0gPSB0ZW1wW2ldLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgdGVtcFtpXS5zbGljZSgxKTtcbiAgcmV0dXJuIHRlbXAuam9pbihcIlwiKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvcHRpb24gbmFtZXMgaW4gYW4gb2JqZWN0IGZyb20gc25ha2VfY2FzZSB0byBjYW1lbENhc2UuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIG9iamVjdCB3aXRoIHNuYWtlX2Nhc2UgcHJvcGVydHkgbmFtZXMuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBBbiBvYmplY3Qgd2l0aCBwcm9wZXJ0eSBuYW1lcyBjb252ZXJ0ZWQgdG8gY2FtZWxDYXNlLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0T3B0aW9uTmFtZXNUb0NhbWVsQ2FzZShvcHRpb25zKSB7XG4gIGNvbnN0IG5ld09wdGlvbnMgPSB7fTtcbiAgZm9yIChjb25zdCBvcHRpb25OYW1lIGluIG9wdGlvbnMpXG4gICAgbmV3T3B0aW9uc1tzbmFrZUNhc2VUb0NhbWVsQ2FzZShvcHRpb25OYW1lKV0gPSBvcHRpb25zW29wdGlvbk5hbWVdO1xuICByZXR1cm4gbmV3T3B0aW9ucztcbn1cblxuY2xhc3MgTG9jayB7XG4gIGxvY2tlZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBVbmxvY2tzIHRoZSBvYmplY3RcbiAgICovXG4gIHVubG9jaygpIHtcbiAgICB0aGlzLmxvY2tlZCA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIExvY2tzIHRoZSBvYmplY3RcbiAgICovXG4gIGxvY2soKSB7XG4gICAgdGhpcy5sb2NrZWQgPSB0cnVlO1xuICB9XG59XG5cbmxldCBkaXZOdW1iZXIgPSAtMTtcbmZ1bmN0aW9uIHNldERpdk51bWJlcihudW0pIHtcbiAgZGl2TnVtYmVyID0gbnVtO1xufVxuXG5leHBvcnQge1xuICBzbmFrZUNhc2VUb0NhbWVsQ2FzZSxcbiAgY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UsXG4gIExvY2ssXG4gIGRpdk51bWJlcixcbiAgc2V0RGl2TnVtYmVyLFxufTtcbiIsICJpbXBvcnQgQSBmcm9tIFwiaHR0cHM6Ly9lc20uc2gvYWxhZGluLWxpdGVAMy40LjUtYmV0YVwiO1xuXG5leHBvcnQgZGVmYXVsdCBBO1xuIiwgImltcG9ydCB7IGNvbnZlcnRPcHRpb25OYW1lc1RvQ2FtZWxDYXNlIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgQSBmcm9tIFwiLi4vYWxhZGluX2xpdGVcIjtcblxubGV0IGltYWdlQ291bnQgPSAwO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZXNzYWdlSGFuZGxlciB7XG4gIGNvbnN0cnVjdG9yKGFsYWRpbiwgbW9kZWwpIHtcbiAgICB0aGlzLmFsYWRpbiA9IGFsYWRpbjtcbiAgICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gIH1cblxuICBoYW5kbGVDaGFuZ2VGb1YobXNnKSB7XG4gICAgdGhpcy5hbGFkaW4uc2V0Rm9WKG1zZ1tcImZvdlwiXSk7XG4gIH1cblxuICBoYW5kbGVHb3RvUmFEZWMobXNnKSB7XG4gICAgdGhpcy5hbGFkaW4uZ290b1JhRGVjKG1zZ1tcInJhXCJdLCBtc2dbXCJkZWNcIl0pO1xuICB9XG5cbiAgaGFuZGxlQWRkRml0cyhtc2csIGJ1ZmZlcnMpIHtcbiAgICBjb25zdCBvcHRpb25zID0gY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UobXNnW1wib3B0aW9uc1wiXSB8fCB7fSk7XG4gICAgaWYgKCFvcHRpb25zLm5hbWUpXG4gICAgICBvcHRpb25zLm5hbWUgPSBgaW1hZ2VfJHtTdHJpbmcoKytpbWFnZUNvdW50KS5wYWRTdGFydCgzLCBcIjBcIil9YDtcbiAgICBjb25zdCBidWZmZXIgPSBidWZmZXJzWzBdO1xuICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbYnVmZmVyXSwgeyB0eXBlOiBcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiIH0pO1xuICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgY29uc3QgaW1hZ2UgPSB0aGlzLmFsYWRpbi5jcmVhdGVJbWFnZUZJVFModXJsLCBvcHRpb25zLCAocmEsIGRlYykgPT4ge1xuICAgICAgdGhpcy5hbGFkaW4uZ290b1JhRGVjKHJhLCBkZWMpO1xuICAgICAgY29uc29sZS5pbmZvKGBGSVRTIGxvY2F0ZWQgYXQgcmE6ICR7cmF9LCBkZWM6ICR7ZGVjfWApO1xuICAgICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICAgIH0pO1xuICAgIHRoaXMuYWxhZGluLnNldE92ZXJsYXlJbWFnZUxheWVyKGltYWdlLCBvcHRpb25zLm5hbWUpO1xuICB9XG5cbiAgaGFuZGxlQWRkQ2F0YWxvZ0Zyb21VUkwobXNnKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IGNvbnZlcnRPcHRpb25OYW1lc1RvQ2FtZWxDYXNlKG1zZ1tcIm9wdGlvbnNcIl0gfHwge30pO1xuICAgIHRoaXMuYWxhZGluLmFkZENhdGFsb2coQS5jYXRhbG9nRnJvbVVSTChtc2dbXCJ2b3RhYmxlX1VSTFwiXSwgb3B0aW9ucykpO1xuICB9XG5cbiAgaGFuZGxlQWRkTU9DRnJvbVVSTChtc2cpIHtcbiAgICBjb25zdCBvcHRpb25zID0gY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UobXNnW1wib3B0aW9uc1wiXSB8fCB7fSk7XG4gICAgdGhpcy5hbGFkaW4uYWRkTU9DKEEuTU9DRnJvbVVSTChtc2dbXCJtb2NfVVJMXCJdLCBvcHRpb25zKSk7XG4gIH1cblxuICBoYW5kbGVBZGRNT0NGcm9tRGljdChtc2cpIHtcbiAgICBjb25zdCBvcHRpb25zID0gY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UobXNnW1wib3B0aW9uc1wiXSB8fCB7fSk7XG4gICAgdGhpcy5hbGFkaW4uYWRkTU9DKEEuTU9DRnJvbUpTT04obXNnW1wibW9jX2RpY3RcIl0sIG9wdGlvbnMpKTtcbiAgfVxuXG4gIGhhbmRsZUFkZE92ZXJsYXkobXNnKSB7XG4gICAgY29uc3QgcmVnaW9ucyA9IG1zZ1tcInJlZ2lvbnNfaW5mb3NcIl07XG4gICAgY29uc3QgZ3JhcGhpY19vcHRpb25zID0gY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UoXG4gICAgICBtc2dbXCJncmFwaGljX29wdGlvbnNcIl0gfHwge30sXG4gICAgKTtcbiAgICBpZiAoIWdyYXBoaWNfb3B0aW9uc1tcImNvbG9yXCJdKSBncmFwaGljX29wdGlvbnNbXCJjb2xvclwiXSA9IFwicmVkXCI7XG4gICAgY29uc3Qgb3ZlcmxheSA9IEEuZ3JhcGhpY092ZXJsYXkoZ3JhcGhpY19vcHRpb25zKTtcbiAgICB0aGlzLmFsYWRpbi5hZGRPdmVybGF5KG92ZXJsYXkpO1xuICAgIGZvciAoY29uc3QgcmVnaW9uIG9mIHJlZ2lvbnMpIHtcbiAgICAgIGNvbnN0IGluZm9zID0gcmVnaW9uW1wiaW5mb3NcIl07XG4gICAgICBzd2l0Y2ggKHJlZ2lvbltcInJlZ2lvbl90eXBlXCJdKSB7XG4gICAgICAgIGNhc2UgXCJzdGNzXCI6XG4gICAgICAgICAgb3ZlcmxheS5hZGRGb290cHJpbnRzKFxuICAgICAgICAgICAgQS5mb290cHJpbnRzRnJvbVNUQ1MoaW5mb3Muc3RjcywgcmVnaW9uLm9wdGlvbnMpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJjaXJjbGVcIjpcbiAgICAgICAgICBvdmVybGF5LmFkZChcbiAgICAgICAgICAgIEEuY2lyY2xlKGluZm9zLnJhLCBpbmZvcy5kZWMsIGluZm9zLnJhZGl1cywgcmVnaW9uLm9wdGlvbnMpLFxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJlbGxpcHNlXCI6XG4gICAgICAgICAgb3ZlcmxheS5hZGQoXG4gICAgICAgICAgICBBLmVsbGlwc2UoXG4gICAgICAgICAgICAgIGluZm9zLnJhLFxuICAgICAgICAgICAgICBpbmZvcy5kZWMsXG4gICAgICAgICAgICAgIGluZm9zLmEsXG4gICAgICAgICAgICAgIGluZm9zLmIsXG4gICAgICAgICAgICAgIGluZm9zLnRoZXRhLFxuICAgICAgICAgICAgICByZWdpb24ub3B0aW9ucyxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImxpbmVcIjpcbiAgICAgICAgICAvLyByZW1vdmUgZGVmYXVsdCBsaW5lV2lkdGggd2hlbiB3ZSBzd2l0Y2ggdG8gQUwgPiAzLjQuNFxuICAgICAgICAgIHJlZ2lvbi5vcHRpb25zLmxpbmVXaWR0aCA9IHJlZ2lvbi5vcHRpb25zLmxpbmVXaWR0aCB8fCAzO1xuICAgICAgICAgIG92ZXJsYXkuYWRkKFxuICAgICAgICAgICAgQS52ZWN0b3IoXG4gICAgICAgICAgICAgIGluZm9zLnJhMSxcbiAgICAgICAgICAgICAgaW5mb3MuZGVjMSxcbiAgICAgICAgICAgICAgaW5mb3MucmEyLFxuICAgICAgICAgICAgICBpbmZvcy5kZWMyLFxuICAgICAgICAgICAgICByZWdpb24ub3B0aW9ucyxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcInBvbHlnb25cIjpcbiAgICAgICAgICBvdmVybGF5LmFkZChBLnBvbHlnb24oaW5mb3MudmVydGljZXMsIHJlZ2lvbi5vcHRpb25zKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlQ2hhbmdlQ29sb3JtYXAobXNnKSB7XG4gICAgdGhpcy5hbGFkaW4uZ2V0QmFzZUltYWdlTGF5ZXIoKS5zZXRDb2xvcm1hcChtc2dbXCJjb2xvcm1hcFwiXSk7XG4gIH1cblxuICBoYW5kbGVHZXRKUEdUaHVtYm5haWwoKSB7XG4gICAgdGhpcy5hbGFkaW4uZXhwb3J0QXNQTkcoKTtcbiAgfVxuXG4gIGhhbmRsZVRyaWdnZXJSZWN0YW5ndWxhclNlbGVjdGlvbigpIHtcbiAgICB0aGlzLmFsYWRpbi5zZWxlY3QoKTtcbiAgfVxuXG4gIGhhbmRsZUFkZFRhYmxlKG1zZywgYnVmZmVycykge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBjb252ZXJ0T3B0aW9uTmFtZXNUb0NhbWVsQ2FzZShtc2dbXCJvcHRpb25zXCJdIHx8IHt9KTtcbiAgICBjb25zdCBidWZmZXIgPSBidWZmZXJzWzBdLmJ1ZmZlcjtcbiAgICBjb25zdCBkZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKFwidXRmLThcIik7XG4gICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtkZWNvZGVyLmRlY29kZShidWZmZXIpXSk7XG4gICAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICBBLmNhdGFsb2dGcm9tVVJMKFxuICAgICAgdXJsLFxuICAgICAgT2JqZWN0LmFzc2lnbihvcHRpb25zLCB7IG9uQ2xpY2s6IFwic2hvd1RhYmxlXCIgfSksXG4gICAgICAoY2F0YWxvZykgPT4ge1xuICAgICAgICB0aGlzLmFsYWRpbi5hZGRDYXRhbG9nKGNhdGFsb2cpO1xuICAgICAgfSxcbiAgICAgIGZhbHNlLFxuICAgICk7XG4gICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICB9XG59XG4iLCAiaW1wb3J0IE1lc3NhZ2VIYW5kbGVyIGZyb20gXCIuL21lc3NhZ2VfaGFuZGxlclwiO1xuaW1wb3J0IHsgZGl2TnVtYmVyLCBzZXREaXZOdW1iZXIsIExvY2sgfSBmcm9tIFwiLi4vdXRpbHNcIjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXZlbnRIYW5kbGVyIHtcbiAgLyoqXG4gICAqIENvbnN0cnVjdG9yIGZvciB0aGUgRXZlbnRIYW5kbGVyIGNsYXNzLlxuICAgKiBAcGFyYW0gYWxhZGluIFRoZSBBbGFkaW4gaW5zdGFuY2VcbiAgICogQHBhcmFtIGFsYWRpbkRpdiBUaGUgQWxhZGluIGRpdlxuICAgKiBAcGFyYW0gbW9kZWwgVGhlIG1vZGVsIGluc3RhbmNlXG4gICAqL1xuICBjb25zdHJ1Y3RvcihhbGFkaW4sIGFsYWRpbkRpdiwgbW9kZWwpIHtcbiAgICB0aGlzLmFsYWRpbiA9IGFsYWRpbjtcbiAgICB0aGlzLmFsYWRpbkRpdiA9IGFsYWRpbkRpdjtcbiAgICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gICAgdGhpcy5tZXNzYWdlSGFuZGxlciA9IG5ldyBNZXNzYWdlSGFuZGxlcihhbGFkaW4sIG1vZGVsKTtcbiAgICB0aGlzLmN1cnJlbnREaXZOdW1iZXIgPSBwYXJzZUludChhbGFkaW5EaXYuaWQuc3BsaXQoXCItXCIpLnBvcCgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGN1cnJlbnQgZGl2IGlzIHRoZSBsYXN0IGFjdGl2ZSBkaXYuXG4gICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgKi9cbiAgaXNMYXN0RGl2KCkge1xuICAgIGlmICh0aGlzLmN1cnJlbnREaXZOdW1iZXIgPT09IGRpdk51bWJlcikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGxldCBtYXhEaXYgPSBkaXZOdW1iZXI7XG4gICAgZm9yIChsZXQgaSA9IG1heERpdjsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IGFsRGl2ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYGFsYWRpbi1saXRlLWRpdi0ke2l9YCk7XG4gICAgICBpZiAoIWFsRGl2KSBjb250aW51ZTtcbiAgICAgIGlmIChhbERpdi5zdHlsZS5kaXNwbGF5ICE9PSBcIm5vbmVcIikge1xuICAgICAgICBtYXhEaXYgPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgc2V0RGl2TnVtYmVyKG1heERpdik7XG4gICAgcmV0dXJuIHRoaXMuY3VycmVudERpdk51bWJlciA9PT0gbWF4RGl2O1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIFdDUyBjb29yZGluYXRlcyBpbiB0aGUgbW9kZWwuXG4gICAqIFdBUk5JTkc6IFRoaXMgbWV0aG9kIGRvbid0IGNhbGwgbW9kZWwuc2F2ZV9jaGFuZ2VzKCkhXG4gICAqL1xuICB1cGRhdGVXQ1MoKSB7XG4gICAgaWYgKCF0aGlzLmlzTGFzdERpdigpKSByZXR1cm47XG4gICAgdGhpcy5tb2RlbC5zZXQoXCJfd2NzXCIsIHRoaXMuYWxhZGluLmdldFZpZXdXQ1MoKSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgMi1heGlzIEZvViBpbiB0aGUgbW9kZWwuXG4gICAqIFdBUk5JTkc6IFRoaXMgbWV0aG9kIGRvbid0IGNhbGwgbW9kZWwuc2F2ZV9jaGFuZ2VzKCkhXG4gICAqL1xuICB1cGRhdGUyQXhpc0ZvVigpIHtcbiAgICBpZiAoIXRoaXMuaXNMYXN0RGl2KCkpIHJldHVybjtcbiAgICBjb25zdCB0d29BeGlzRm9WID0gdGhpcy5hbGFkaW4uZ2V0Rm92KCk7XG4gICAgdGhpcy5tb2RlbC5zZXQoXCJfZm92X3h5XCIsIHtcbiAgICAgIHg6IHR3b0F4aXNGb1ZbMF0sXG4gICAgICB5OiB0d29BeGlzRm9WWzFdLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN1YnNjcmliZXMgdG8gYWxsIHRoZSBldmVudHMgbmVlZGVkIGZvciB0aGUgQWxhZGluIExpdGUgd2lkZ2V0LlxuICAgKi9cbiAgc3Vic2NyaWJlQWxsKCkge1xuICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbiAgICAvKiBMaXN0ZW5lcnMgLS0tLS0tLS0tICovXG4gICAgLyogLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4gICAgLyogUG9zaXRpb24gQ29udHJvbCAqL1xuICAgIC8vIHRoZXJlIGFyZSB0d28gd2F5cyBvZiBjaGFuZ2luZyB0aGUgdGFyZ2V0LCBvbmUgZnJvbSB0aGUgamF2YXNjcmlwdCBzaWRlLCBhbmRcbiAgICAvLyBvbmUgZnJvbSB0aGUgcHl0aG9uIHNpZGUuIFdlIGhhdmUgdG8gaW5zdGFudGlhdGUgdHdvIGxpc3RlbmVycyBmb3IgdGhlc2UsIGJ1dFxuICAgIC8vIHRoZSBnb3RvT2JqZWN0IGNhbGwgc2hvdWxkIG9ubHkgaGFwcGVuIG9uY2UuIFRoZSB0d28gYm9vbGVhbnMgcHJldmVudCB0aGUgdHdvXG4gICAgLy8gbGlzdGVuZXJzIGZyb20gdHJpZ2dlcmluZyBlYWNoIG90aGVyIGFuZCBjcmVhdGluZyBhIGJ1Z2d5IGxvb3AuIFRoZSBzYW1lIHRyaWNrXG4gICAgLy8gaXMgYWxzbyBuZWNlc3NhcnkgZm9yIHRoZSBmaWVsZCBvZiB2aWV3LlxuXG4gICAgLyogVGFyZ2V0IGNvbnRyb2wgKi9cbiAgICBjb25zdCBqc1RhcmdldExvY2sgPSBuZXcgTG9jaygpO1xuICAgIGNvbnN0IHB5VGFyZ2V0TG9jayA9IG5ldyBMb2NrKCk7XG5cbiAgICAvLyBFdmVudCB0cmlnZ2VyZWQgd2hlbiB0aGUgdXNlciBtb3ZlcyB0aGUgbWFwIGluIEFsYWRpbiBMaXRlXG4gICAgdGhpcy5hbGFkaW4ub24oXCJwb3NpdGlvbkNoYW5nZWRcIiwgKHBvc2l0aW9uKSA9PiB7XG4gICAgICBpZiAocHlUYXJnZXRMb2NrLmxvY2tlZCkge1xuICAgICAgICBweVRhcmdldExvY2sudW5sb2NrKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGpzVGFyZ2V0TG9jay5sb2NrKCk7XG4gICAgICBjb25zdCByYURlYyA9IFtwb3NpdGlvbi5yYSwgcG9zaXRpb24uZGVjXTtcbiAgICAgIHRoaXMudXBkYXRlV0NTKCk7XG4gICAgICB0aGlzLm1vZGVsLnNldChcIl90YXJnZXRcIiwgYCR7cmFEZWNbMF19ICR7cmFEZWNbMV19YCk7XG4gICAgICB0aGlzLm1vZGVsLnNhdmVfY2hhbmdlcygpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5tb2RlbC5vbihcImNoYW5nZTpfdGFyZ2V0XCIsICgpID0+IHtcbiAgICAgIGlmIChqc1RhcmdldExvY2subG9ja2VkKSB7XG4gICAgICAgIGpzVGFyZ2V0TG9jay51bmxvY2soKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcHlUYXJnZXRMb2NrLmxvY2soKTtcbiAgICAgIGxldCB0YXJnZXQgPSB0aGlzLm1vZGVsLmdldChcIl90YXJnZXRcIik7XG4gICAgICBjb25zdCBbcmEsIGRlY10gPSB0YXJnZXQuc3BsaXQoXCIgXCIpO1xuICAgICAgdGhpcy5hbGFkaW4uZ290b1JhRGVjKHJhLCBkZWMpO1xuICAgIH0pO1xuXG4gICAgLyogRmllbGQgb2YgVmlldyBjb250cm9sICovXG4gICAgY29uc3QganNGb3ZMb2NrID0gbmV3IExvY2soKTtcbiAgICBjb25zdCBweUZvdkxvY2sgPSBuZXcgTG9jaygpO1xuXG4gICAgdGhpcy5hbGFkaW4ub24oXCJ6b29tQ2hhbmdlZFwiLCAoZm92KSA9PiB7XG4gICAgICBpZiAocHlGb3ZMb2NrLmxvY2tlZCkge1xuICAgICAgICBweUZvdkxvY2sudW5sb2NrKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGpzRm92TG9jay5sb2NrKCk7XG4gICAgICAvLyBmb3YgTVVTVCBiZSBjYXN0IGludG8gZmxvYXQgaW4gb3JkZXIgdG8gYmUgc2VudCB0byB0aGUgbW9kZWxcbiAgICAgIHRoaXMudXBkYXRlV0NTKCk7XG4gICAgICB0aGlzLnVwZGF0ZTJBeGlzRm9WKCk7XG4gICAgICB0aGlzLm1vZGVsLnNldChcIl9mb3ZcIiwgcGFyc2VGbG9hdChmb3YudG9GaXhlZCg1KSkpO1xuICAgICAgdGhpcy5tb2RlbC5zYXZlX2NoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIHRoaXMubW9kZWwub24oXCJjaGFuZ2U6X2ZvdlwiLCAoKSA9PiB7XG4gICAgICBpZiAoanNGb3ZMb2NrLmxvY2tlZCkge1xuICAgICAgICBqc0ZvdkxvY2sudW5sb2NrKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHB5Rm92TG9jay5sb2NrKCk7XG4gICAgICBsZXQgZm92ID0gdGhpcy5tb2RlbC5nZXQoXCJfZm92XCIpO1xuICAgICAgdGhpcy5hbGFkaW4uc2V0Rm9WKGZvdik7XG4gICAgfSk7XG5cbiAgICAvKiBEaXYgY29udHJvbCAqL1xuICAgIHRoaXMubW9kZWwub24oXCJjaGFuZ2U6X2hlaWdodFwiLCAoKSA9PiB7XG4gICAgICBsZXQgaGVpZ2h0ID0gdGhpcy5tb2RlbC5nZXQoXCJfaGVpZ2h0XCIpO1xuICAgICAgdGhpcy5hbGFkaW5EaXYuc3R5bGUuaGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YDtcbiAgICAgIC8vIFVwZGF0ZSBXQ1MgYW5kIEZvViBvbmx5IGlmIHRoaXMgaXMgdGhlIGxhc3QgZGl2XG4gICAgICB0aGlzLnVwZGF0ZVdDUygpO1xuICAgICAgdGhpcy51cGRhdGUyQXhpc0ZvVigpO1xuICAgICAgdGhpcy5tb2RlbC5zYXZlX2NoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIC8qIEFsYWRpbiBjYWxsYmFja3MgKi9cblxuICAgIHRoaXMuYWxhZGluLm9uKFwiY29vRnJhbWVDaGFuZ2VkXCIsICgpID0+IHtcbiAgICAgIHRoaXMudXBkYXRlV0NTKCk7XG4gICAgICB0aGlzLm1vZGVsLnNhdmVfY2hhbmdlcygpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5hbGFkaW4ub24oXCJwcm9qZWN0aW9uQ2hhbmdlZFwiLCAoKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZVdDUygpO1xuICAgICAgdGhpcy5tb2RlbC5zYXZlX2NoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuYWxhZGluLm9uKFwibGF5ZXJDaGFuZ2VkXCIsIChfLCBsYXllck5hbWUsIHN0YXRlKSA9PiB7XG4gICAgICBpZiAobGF5ZXJOYW1lICE9PSBcImJhc2VcIiB8fCBzdGF0ZSAhPT0gXCJBRERFRFwiKSByZXR1cm47XG4gICAgICB0aGlzLnVwZGF0ZVdDUygpO1xuICAgICAgdGhpcy5tb2RlbC5zYXZlX2NoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuYWxhZGluLm9uKFwicmVzaXplQ2hhbmdlZFwiLCAoKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZVdDUygpO1xuICAgICAgdGhpcy51cGRhdGUyQXhpc0ZvVigpO1xuICAgICAgdGhpcy5tb2RlbC5zYXZlX2NoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuYWxhZGluLm9uKFwib2JqZWN0SG92ZXJlZFwiLCAob2JqZWN0KSA9PiB7XG4gICAgICBpZiAob2JqZWN0W1wiZGF0YVwiXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMubW9kZWwuc2VuZCh7XG4gICAgICAgICAgZXZlbnRfdHlwZTogXCJvYmplY3RfaG92ZXJlZFwiLFxuICAgICAgICAgIGNvbnRlbnQ6IHtcbiAgICAgICAgICAgIHJhOiBvYmplY3RbXCJyYVwiXSxcbiAgICAgICAgICAgIGRlYzogb2JqZWN0W1wiZGVjXCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5hbGFkaW4ub24oXCJvYmplY3RDbGlja2VkXCIsIChjbGlja2VkKSA9PiB7XG4gICAgICBpZiAoY2xpY2tlZCkge1xuICAgICAgICBsZXQgY2xpY2tlZENvbnRlbnQgPSB7XG4gICAgICAgICAgcmE6IGNsaWNrZWRbXCJyYVwiXSxcbiAgICAgICAgICBkZWM6IGNsaWNrZWRbXCJkZWNcIl0sXG4gICAgICAgIH07XG4gICAgICAgIGlmIChjbGlja2VkW1wiZGF0YVwiXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgY2xpY2tlZENvbnRlbnRbXCJkYXRhXCJdID0gY2xpY2tlZFtcImRhdGFcIl07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5tb2RlbC5zZXQoXCJjbGlja2VkX29iamVjdFwiLCBjbGlja2VkQ29udGVudCk7XG4gICAgICAgIC8vIHNlbmQgYSBjdXN0b20gbWVzc2FnZSBpbiBjYXNlIHRoZSB1c2VyIHdhbnRzIHRvIGRlZmluZSB0aGVpciBvd24gY2FsbGJhY2tzXG4gICAgICAgIHRoaXMubW9kZWwuc2VuZCh7XG4gICAgICAgICAgZXZlbnRfdHlwZTogXCJvYmplY3RfY2xpY2tlZFwiLFxuICAgICAgICAgIGNvbnRlbnQ6IGNsaWNrZWRDb250ZW50LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5tb2RlbC5zYXZlX2NoYW5nZXMoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuYWxhZGluLm9uKFwiY2xpY2tcIiwgKGNsaWNrQ29udGVudCkgPT4ge1xuICAgICAgdGhpcy5tb2RlbC5zZW5kKHtcbiAgICAgICAgZXZlbnRfdHlwZTogXCJjbGlja1wiLFxuICAgICAgICBjb250ZW50OiBjbGlja0NvbnRlbnQsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRoaXMuYWxhZGluLm9uKFwic2VsZWN0XCIsIChjYXRhbG9ncykgPT4ge1xuICAgICAgbGV0IG9iamVjdHNEYXRhID0gW107XG4gICAgICAvLyBUT0RPOiB0aGlzIGZsYXR0ZW5zIHRoZSBzZWxlY3Rpb24uIEVhY2ggb2JqZWN0IGZyb20gZGlmZmVyZW50XG4gICAgICAvLyBjYXRhbG9ncyBhcmUgZW50ZXJlZCBpbiB0aGUgYXJyYXkuIFRvIGNoYW5nZSB0aGlzLCBtYXliZSBjaGFuZ2VcbiAgICAgIC8vIHVwc3RyZWFtIHdoYXQgaXMgcmV0dXJuZWQgdXBvbiBzZWxlY3Rpb24/XG4gICAgICBjYXRhbG9ncy5mb3JFYWNoKChjYXRhbG9nKSA9PiB7XG4gICAgICAgIGNhdGFsb2cuZm9yRWFjaCgob2JqZWN0KSA9PiB7XG4gICAgICAgICAgb2JqZWN0c0RhdGEucHVzaCh7XG4gICAgICAgICAgICByYTogb2JqZWN0LnJhLFxuICAgICAgICAgICAgZGVjOiBvYmplY3QuZGVjLFxuICAgICAgICAgICAgZGF0YTogb2JqZWN0LmRhdGEsXG4gICAgICAgICAgICB4OiBvYmplY3QueCxcbiAgICAgICAgICAgIHk6IG9iamVjdC55LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5tb2RlbC5zZW5kKHtcbiAgICAgICAgZXZlbnRfdHlwZTogXCJzZWxlY3RcIixcbiAgICAgICAgY29udGVudDogb2JqZWN0c0RhdGEsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8qIEFsYWRpbiBmdW5jdGlvbmFsaXRpZXMgKi9cblxuICAgIHRoaXMubW9kZWwub24oXCJjaGFuZ2U6Y29vX2ZyYW1lXCIsICgpID0+IHtcbiAgICAgIHRoaXMuYWxhZGluLnNldEZyYW1lKHRoaXMubW9kZWwuZ2V0KFwiY29vX2ZyYW1lXCIpKTtcbiAgICB9KTtcblxuICAgIHRoaXMubW9kZWwub24oXCJjaGFuZ2U6c3VydmV5XCIsICgpID0+IHtcbiAgICAgIHRoaXMuYWxhZGluLnNldEltYWdlU3VydmV5KHRoaXMubW9kZWwuZ2V0KFwic3VydmV5XCIpKTtcbiAgICB9KTtcblxuICAgIHRoaXMubW9kZWwub24oXCJjaGFuZ2U6b3ZlcmxheV9zdXJ2ZXlcIiwgKCkgPT4ge1xuICAgICAgdGhpcy5hbGFkaW4uc2V0T3ZlcmxheUltYWdlTGF5ZXIodGhpcy5tb2RlbC5nZXQoXCJvdmVybGF5X3N1cnZleVwiKSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLm1vZGVsLm9uKFwiY2hhbmdlOm92ZXJsYXlfc3VydmV5X29wYWNpdHlcIiwgKCkgPT4ge1xuICAgICAgdGhpcy5hbGFkaW5cbiAgICAgICAgLmdldE92ZXJsYXlJbWFnZUxheWVyKClcbiAgICAgICAgLnNldEFscGhhKHRoaXMubW9kZWwuZ2V0KFwib3ZlcmxheV9zdXJ2ZXlfb3BhY2l0eVwiKSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmV2ZW50SGFuZGxlcnMgPSB7XG4gICAgICBjaGFuZ2VfZm92OiB0aGlzLm1lc3NhZ2VIYW5kbGVyLmhhbmRsZUNoYW5nZUZvVixcbiAgICAgIGdvdG9fcmFfZGVjOiB0aGlzLm1lc3NhZ2VIYW5kbGVyLmhhbmRsZUdvdG9SYURlYyxcbiAgICAgIGFkZF9maXRzOiB0aGlzLm1lc3NhZ2VIYW5kbGVyLmhhbmRsZUFkZEZpdHMsXG4gICAgICBhZGRfY2F0YWxvZ19mcm9tX1VSTDogdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVBZGRDYXRhbG9nRnJvbVVSTCxcbiAgICAgIGFkZF9NT0NfZnJvbV9VUkw6IHRoaXMubWVzc2FnZUhhbmRsZXIuaGFuZGxlQWRkTU9DRnJvbVVSTCxcbiAgICAgIGFkZF9NT0NfZnJvbV9kaWN0OiB0aGlzLm1lc3NhZ2VIYW5kbGVyLmhhbmRsZUFkZE1PQ0Zyb21EaWN0LFxuICAgICAgYWRkX292ZXJsYXk6IHRoaXMubWVzc2FnZUhhbmRsZXIuaGFuZGxlQWRkT3ZlcmxheSxcbiAgICAgIGNoYW5nZV9jb2xvcm1hcDogdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVDaGFuZ2VDb2xvcm1hcCxcbiAgICAgIGdldF9KUEdfdGh1bWJuYWlsOiB0aGlzLm1lc3NhZ2VIYW5kbGVyLmhhbmRsZUdldEpQR1RodW1ibmFpbCxcbiAgICAgIHRyaWdnZXJfcmVjdGFuZ3VsYXJfc2VsZWN0aW9uOlxuICAgICAgICB0aGlzLm1lc3NhZ2VIYW5kbGVyLmhhbmRsZVRyaWdnZXJSZWN0YW5ndWxhclNlbGVjdGlvbixcbiAgICAgIGFkZF90YWJsZTogdGhpcy5tZXNzYWdlSGFuZGxlci5oYW5kbGVBZGRUYWJsZSxcbiAgICB9O1xuXG4gICAgdGhpcy5tb2RlbC5vbihcIm1zZzpjdXN0b21cIiwgKG1zZywgYnVmZmVycykgPT4ge1xuICAgICAgY29uc3QgZXZlbnROYW1lID0gbXNnW1wiZXZlbnRfbmFtZVwiXTtcbiAgICAgIGNvbnN0IGhhbmRsZXIgPSB0aGlzLmV2ZW50SGFuZGxlcnNbZXZlbnROYW1lXTtcbiAgICAgIGlmIChoYW5kbGVyKSBoYW5kbGVyLmNhbGwodGhpcywgbXNnLCBidWZmZXJzKTtcbiAgICAgIGVsc2UgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGV2ZW50IG5hbWU6ICR7ZXZlbnROYW1lfWApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVuc3Vic2NyaWJlIGZyb20gYWxsIHRoZSBtb2RlbCBldmVudHMuXG4gICAqIFRoZXJlIGlzIG5vIG5lZWQgdG8gdW5zdWJzY3JpYmUgZnJvbSB0aGUgQWxhZGluIExpdGUgZXZlbnRzLlxuICAgKi9cbiAgdW5zdWJzY3JpYmVBbGwoKSB7XG4gICAgdGhpcy5tb2RlbC5vZmYoXCJjaGFuZ2U6X3RhcmdldFwiKTtcbiAgICB0aGlzLm1vZGVsLm9mZihcImNoYW5nZTpfZm92XCIpO1xuICAgIHRoaXMubW9kZWwub2ZmKFwiY2hhbmdlOl9oZWlnaHRcIik7XG4gICAgdGhpcy5tb2RlbC5vZmYoXCJjaGFuZ2U6Y29vX2ZyYW1lXCIpO1xuICAgIHRoaXMubW9kZWwub2ZmKFwiY2hhbmdlOnN1cnZleVwiKTtcbiAgICB0aGlzLm1vZGVsLm9mZihcImNoYW5nZTpvdmVybGF5X3N1cnZleVwiKTtcbiAgICB0aGlzLm1vZGVsLm9mZihcImNoYW5nZTpvdmVybGF5X3N1cnZleV9vcGFjaXR5XCIpO1xuICAgIHRoaXMubW9kZWwub2ZmKFwiY2hhbmdlOnRyaWdnZXJfZXZlbnRcIik7XG4gICAgdGhpcy5tb2RlbC5vZmYoXCJtc2c6Y3VzdG9tXCIpO1xuICB9XG59XG4iLCAiaW1wb3J0IFwiLi93aWRnZXQuY3NzXCI7XG5pbXBvcnQgRXZlbnRIYW5kbGVyIGZyb20gXCIuL21vZGVscy9ldmVudF9oYW5kbGVyXCI7XG5pbXBvcnQgeyBkaXZOdW1iZXIsIHNldERpdk51bWJlciwgc25ha2VDYXNlVG9DYW1lbENhc2UgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IEEgZnJvbSBcIi4vYWxhZGluX2xpdGVcIjtcblxuZnVuY3Rpb24gaW5pdEFsYWRpbkxpdGUobW9kZWwsIGVsKSB7XG4gIHNldERpdk51bWJlcihkaXZOdW1iZXIgKyAxKTtcbiAgbGV0IGluaXRPcHRpb25zID0ge307XG4gIG1vZGVsLmdldChcImluaXRfb3B0aW9uc1wiKS5mb3JFYWNoKChvcHRpb25fbmFtZSkgPT4ge1xuICAgIGluaXRPcHRpb25zW3NuYWtlQ2FzZVRvQ2FtZWxDYXNlKG9wdGlvbl9uYW1lKV0gPSBtb2RlbC5nZXQob3B0aW9uX25hbWUpO1xuICB9KTtcblxuICBsZXQgYWxhZGluRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgYWxhZGluRGl2LmNsYXNzTGlzdC5hZGQoXCJhbGFkaW4td2lkZ2V0XCIpO1xuICBhbGFkaW5EaXYuc3R5bGUuaGVpZ2h0ID0gYCR7aW5pdE9wdGlvbnNbXCJoZWlnaHRcIl19cHhgO1xuXG4gIGFsYWRpbkRpdi5pZCA9IGBhbGFkaW4tbGl0ZS1kaXYtJHtkaXZOdW1iZXJ9YDtcbiAgbGV0IGFsYWRpbiA9IG5ldyBBLmFsYWRpbihhbGFkaW5EaXYsIGluaXRPcHRpb25zKTtcblxuICAvLyBTZXQgdGhlIHRhcmdldCBhZ2FpbiBhZnRlciB0aGUgaW5pdGlhbGl6YXRpb24gdG8gYmUgc3VyZSB0aGF0IHRoZSB0YXJnZXQgaXMgc2V0XG4gIC8vIGZyb20gaWNycyBjb29yZGluYXRlcyBiZWNhdXNlIG9mIHRoZSB1c2Ugb2YgZ290b09iamVjdCBpbiB0aGUgQWxhZGluIExpdGUgQVBJXG4gIGNvbnN0IHJhRGVjID0gaW5pdE9wdGlvbnNbXCJ0YXJnZXRcIl0uc3BsaXQoXCIgXCIpO1xuICBhbGFkaW4uZ290b1JhRGVjKHJhRGVjWzBdLCByYURlY1sxXSk7XG5cbiAgLy8gU2V0IGN1cnJlbnQgRm9WIGFuZCBXQ1NcbiAgY29uc3QgdHdvQXhpc0ZvViA9IGFsYWRpbi5nZXRGb3YoKTtcbiAgbW9kZWwuc2V0KFwiX2Zvdl94eVwiLCB7XG4gICAgeDogdHdvQXhpc0ZvVlswXSxcbiAgICB5OiB0d29BeGlzRm9WWzFdLFxuICB9KTtcbiAgbW9kZWwuc2V0KFwiX3djc1wiLCBhbGFkaW4uZ2V0Vmlld1dDUygpKTtcbiAgbW9kZWwuc2F2ZV9jaGFuZ2VzKCk7XG5cbiAgZWwuYXBwZW5kQ2hpbGQoYWxhZGluRGl2KTtcbiAgcmV0dXJuIHsgYWxhZGluLCBhbGFkaW5EaXYgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gaW5pdGlhbGl6ZSh7IG1vZGVsIH0pIHtcbiAgYXdhaXQgQS5pbml0O1xufVxuXG5mdW5jdGlvbiByZW5kZXIoeyBtb2RlbCwgZWwgfSkge1xuICAvKiAtLS0tLS0tLS0tLS0tLS0tLS0tICovXG4gIC8qIFZpZXcgLS0tLS0tLS0tLS0tLS0gKi9cbiAgLyogLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4gIGNvbnN0IHsgYWxhZGluLCBhbGFkaW5EaXYgfSA9IGluaXRBbGFkaW5MaXRlKG1vZGVsLCBlbCk7XG5cbiAgY29uc3QgZXZlbnRIYW5kbGVyID0gbmV3IEV2ZW50SGFuZGxlcihhbGFkaW4sIGFsYWRpbkRpdiwgbW9kZWwpO1xuICBldmVudEhhbmRsZXIuc3Vic2NyaWJlQWxsKCk7XG5cbiAgcmV0dXJuICgpID0+IHtcbiAgICAvLyBOZWVkIHRvIHVuc3Vic2NyaWJlIHRoZSBsaXN0ZW5lcnNcbiAgICBldmVudEhhbmRsZXIudW5zdWJzY3JpYmVBbGwoKTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgeyBpbml0aWFsaXplLCByZW5kZXIgfTtcbiJdLAogICJtYXBwaW5ncyI6ICJB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QUFTLGNBQWMsS0FBSyxFQUM1Q0EsRUFBVSxVQUFVLElBQUksZUFBZSxFQUN2Q0EsRUFBVSxNQUFNLE9BQVMsR0FBR0gsRUFBWSxNQUFTLEtBRWpERyxFQUFVLEdBQUssbUJBQW1CSixDQUFTLEdBQzNDLElBQUlLLEVBQVMsSUFBSUMsRUFBRSxPQUFPRixFQUFXSCxDQUFXLEVBSTFDTSxFQUFRTixFQUFZLE9BQVUsTUFBTSxHQUFHLEVBQzdDSSxFQUFPLFVBQVVFLEVBQU0sQ0FBQyxFQUFHQSxFQUFNLENBQUMsQ0FBQyxFQUduQyxJQUFNQyxFQUFhSCxFQUFPLE9BQU8sRUFDakMsT0FBQVIsRUFBTSxJQUFJLFVBQVcsQ0FDbkIsRUFBR1csRUFBVyxDQUFDLEVBQ2YsRUFBR0EsRUFBVyxDQUFDLENBQ2pCLENBQUMsRUFDRFgsRUFBTSxJQUFJLE9BQVFRLEVBQU8sV0FBVyxDQUFDLEVBQ3JDUixFQUFNLGFBQWEsRUFFbkJDLEVBQUcsWUFBWU0sQ0FBUyxFQUNqQixDQUFFLE9BQUFDLEVBQVEsVUFBQUQsQ0FBVSxDQUM3QixDQUVBLGVBQWVLLEVBQVcsQ0FBRSxNQUFBWixDQUFNLEVBQUcsQ0FDbkMsTUFBTVMsRUFBRSxJQUNWLENBRUEsU0FBU0ksRUFBTyxDQUFFLE1BQUFiLEVBQU8sR0FBQUMsQ0FBRyxFQUFHLENBSzdCLEdBQU0sQ0FBRSxPQUFBTyxFQUFRLFVBQUFELENBQVUsRUFBSVIsRUFBZUMsRUFBT0MsQ0FBRSxFQUVoRGEsRUFBZSxJQUFJQyxFQUFhUCxFQUFRRCxFQUFXUCxDQUFLLEVBQzlELE9BQUFjLEVBQWEsYUFBYSxFQUVuQixJQUFNLENBRVhBLEVBQWEsZUFBZSxDQUM5QixDQUNGLENBRUEsSUFBT0UsRUFBUSxDQUFFLFdBQUFKLEVBQVksT0FBQUMsQ0FBTyIsCiAgIm5hbWVzIjogWyJzbmFrZUNhc2VUb0NhbWVsQ2FzZSIsICJzbmFrZUNhc2VTdHIiLCAidGVtcCIsICJpIiwgImNvbnZlcnRPcHRpb25OYW1lc1RvQ2FtZWxDYXNlIiwgIm9wdGlvbnMiLCAibmV3T3B0aW9ucyIsICJvcHRpb25OYW1lIiwgIkxvY2siLCAiZGl2TnVtYmVyIiwgInNldERpdk51bWJlciIsICJudW0iLCAiQSIsICJhbGFkaW5fbGl0ZV9kZWZhdWx0IiwgImltYWdlQ291bnQiLCAiTWVzc2FnZUhhbmRsZXIiLCAiYWxhZGluIiwgIm1vZGVsIiwgIm1zZyIsICJidWZmZXJzIiwgIm9wdGlvbnMiLCAiY29udmVydE9wdGlvbk5hbWVzVG9DYW1lbENhc2UiLCAiYnVmZmVyIiwgImJsb2IiLCAidXJsIiwgImltYWdlIiwgInJhIiwgImRlYyIsICJhbGFkaW5fbGl0ZV9kZWZhdWx0IiwgInJlZ2lvbnMiLCAiZ3JhcGhpY19vcHRpb25zIiwgIm92ZXJsYXkiLCAicmVnaW9uIiwgImluZm9zIiwgImRlY29kZXIiLCAiY2F0YWxvZyIsICJFdmVudEhhbmRsZXIiLCAiYWxhZGluIiwgImFsYWRpbkRpdiIsICJtb2RlbCIsICJNZXNzYWdlSGFuZGxlciIsICJkaXZOdW1iZXIiLCAibWF4RGl2IiwgImkiLCAiYWxEaXYiLCAic2V0RGl2TnVtYmVyIiwgInR3b0F4aXNGb1YiLCAianNUYXJnZXRMb2NrIiwgIkxvY2siLCAicHlUYXJnZXRMb2NrIiwgInBvc2l0aW9uIiwgInJhRGVjIiwgInRhcmdldCIsICJyYSIsICJkZWMiLCAianNGb3ZMb2NrIiwgInB5Rm92TG9jayIsICJmb3YiLCAiaGVpZ2h0IiwgIl8iLCAibGF5ZXJOYW1lIiwgInN0YXRlIiwgIm9iamVjdCIsICJjbGlja2VkIiwgImNsaWNrZWRDb250ZW50IiwgImNsaWNrQ29udGVudCIsICJjYXRhbG9ncyIsICJvYmplY3RzRGF0YSIsICJjYXRhbG9nIiwgIm1zZyIsICJidWZmZXJzIiwgImV2ZW50TmFtZSIsICJoYW5kbGVyIiwgImluaXRBbGFkaW5MaXRlIiwgIm1vZGVsIiwgImVsIiwgInNldERpdk51bWJlciIsICJkaXZOdW1iZXIiLCAiaW5pdE9wdGlvbnMiLCAib3B0aW9uX25hbWUiLCAic25ha2VDYXNlVG9DYW1lbENhc2UiLCAiYWxhZGluRGl2IiwgImFsYWRpbiIsICJhbGFkaW5fbGl0ZV9kZWZhdWx0IiwgInJhRGVjIiwgInR3b0F4aXNGb1YiLCAiaW5pdGlhbGl6ZSIsICJyZW5kZXIiLCAiZXZlbnRIYW5kbGVyIiwgIkV2ZW50SGFuZGxlciIsICJ3aWRnZXRfZGVmYXVsdCJdCn0K\n", + "_fov": 50, "_fov_xy": { - "x": 5.60143396583755, - "y": 5.60143396583755 + "x": 5, + "y": 5 }, "_height": 800, "_model_module": "anywidget", "_model_module_version": "0.9.10", "_model_name": "AnyModel", - "_target": "10.684708299999999 41.268749999999976", + "_target": "80.89416999999995 -69.75611", "_view_module": "anywidget", "_view_module_version": "0.9.10", "_view_name": "AnyView", "_wcs": { - "CDELT1": -5.60143396583755, - "CDELT2": 5.60143396583755, + "CDELT1": -5, + "CDELT2": 5, "CRPIX1": 1, "CRPIX2": 1, - "CRVAL1": 10.684708299999997, - "CRVAL2": 41.26874999999998, + "CRVAL1": 80.89416999999995, + "CRVAL2": -69.75611, "CTYPE1": "RA---SIN", "CTYPE2": "DEC--SIN", "CUNIT1": "deg ", @@ -292,7 +296,7 @@ "show_zoom_control", "survey" ], - "layout": "IPY_MODEL_963ac6a600854d92a585c08214f76219", + "layout": "IPY_MODEL_8b1f9d5607de4bd4a8cc50de5de97650", "overlay_survey": "", "overlay_survey_opacity": 0, "projection": "SIN", @@ -319,7 +323,7 @@ "survey": "CDS/P/PLANCK/R2/HFI/color" } }, - "963ac6a600854d92a585c08214f76219": { + "8b1f9d5607de4bd4a8cc50de5de97650": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel",