{
  "endpoint": "https://loader.artpipe.epicgames.com",
  "hash": "540d0101df2b662d002355204651f2cd",
  "url": "https://unpipe-loader-bucket.s3.amazonaws.com/unpipe_loader.zip?AWSAccessKeyId=ASIATA4GVB54AXELUFY2&Signature=jT7iwX0T6igWrrU1PN1llNZo9ns%3D&x-amz-security-token=IQoJb3JpZ2luX2VjEPr%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJHMEUCIQCJm%2BbUO%2BE4ulY1dYGYAsPVELNHYUlFNzpstPyQrtp7cwIgW082kaLhCbkVgNr%2BDzgbzzXFYSPM6kdoEVNmEFhAZ%2FEq6QMIw%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FARABGgwyMDgwNTE0NDE1MjgiDF%2BDYL4xkAU3Irlsdiq9A1X2%2BHp1t2Jr2XWEUqygln7S6Tu6HyEpl01fd%2BbGYM4lbYi94%2FC0FdBgONMvwXjmkYLly7p9qbo69iKgjaAwog0B0K6LDXMlBuCkwHGA5T4MZMmLb0NFUYYFKQNgYTkDMWkzXgpi4L%2By8fSjEqB0RDHwoq2rVgItwICGMurXN3TUiGyRXkQs7DUiAXyH7vVJViX26oCj8L2mQwfFe7iMhYZ705lKvMXN91ohvsVk3l2QSfRAXVfqOwKNPAfJuiUwAO3qoRkb6aqgqozMZ67UoFg%2FCdXGm0dUkIAB1XbCwsmr160vaVEYO0yA9RvjCCh8ZYMQ%2F9ZdTqaXTSVSn%2FbHgmqNj4wyQn736df9f2InJIfndIbtLPBBeCHBMBF%2FsqDTvYZabpKoH75vvSNUfg2M4sFq5Nlxz5SLyIp%2BbgRSwOVmydKbktZgUgJ6YwyQj%2Fevhtw7EWNnQeXV54YOy8nA9E07neZfVCXGRfUa03kbuIYTTnhZ0VFjA%2BPcvYAPbJJZm0usenlVsYAhCXoq01D3wVmOLhV4esCn0QZNYGnB8Lxqbk9HJnt8emHH%2BTfVTLZAPY5ZnY5e0oZts0witKQwtoD1zwY6oQGSu1M1Zv0eQtijM4gijSYq9r%2FkF9qnqvA86mx0%2FCbzsYUfc5o46qppvhlGR93s%2FlQrc0GfqtF%2BUs9gIzT0vzIa3yLubxLVV46u40FAKEFdKS7H5Tjs5oAeUzFtI0iMxPsEUxD3YpRSY7ceaWLtS4GOSOiRLb%2F2osFE%2Fjuqv%2FEckuIvkTdDuhk56gy4QC0%2FfkFGMImpydhwh0PraKoCSP%2FFlA%3D%3D&Expires=1778206589",
  "setup": "# Copyright Epic Games, Inc. All Rights Reserved.\nfrom __future__ import annotations\n\n\n__version__ = '1.0.1'\n\nimport io\nimport os\nimport re\nimport sys\nimport json\nimport time\nimport runpy\nimport pathlib\nimport zipfile\nimport tempfile\nfrom urllib.request import urlopen\n\n\n# Provided as exec globals when running this script\nloader_info = globals()['loader_info']\nloader_path = globals().get('cache_path')\ncache_only = globals().get('cache_only', False)\n\nif not loader_path:\n    namespace = re.sub(r\"[/\\\\?%*:|\\\"<>\\x7F\\x00-\\x1F]\", \"-\", loader_info['endpoint'].rpartition('://')[-1])\n    if sys.platform == 'win32':\n        loader_path = pathlib.Path.home() / f'AppData/Roaming/UnPipe/loader/{namespace}'\n    elif sys.platform.startswith('linux'):\n        loader_path = pathlib.Path.home() / f'.local/share/UnPipe/loader/{namespace}'\n    elif sys.platform == 'darwin':\n        loader_path = pathlib.Path.home() / f'Library/Application Support/UnPipe/loader/{namespace}'\n    else:\n        raise OSError(f'Unsupported platform {sys.platform}')\n\n# Create cache parent directory\nloader_path.parent.mkdir(parents=True, exist_ok=True)\ncache_file = loader_path.joinpath('.cached')\ncache_file_temp = loader_path.joinpath('.cached.tmp')\ntry:\n    cache_info = json.loads(cache_file.read_text()) if cache_file.exists() else {}\nexcept json.JSONDecodeError:\n    cache_info = {}\n\n# Only extract if the hashes missmatch\nif cache_info.get('hash') != loader_info['hash']:\n    # Grab the zip\n    with urlopen(loader_info['url']) as response:\n        loader_zipfile = zipfile.ZipFile(io.BytesIO(response.read()))\n\n    # Extract\n    with tempfile.TemporaryDirectory(dir=loader_path.parent) as tempdir:\n        loader_zipfile.extractall(path=tempdir)\n        if loader_path.exists():\n            # Let the tempdir cleanup handle the prior loader\n            os.rename(loader_path, tempdir + '/.cleanup')\n\n        # Write a new .cached file to the extracted copy, before moving it over\n        pathlib.Path(tempdir, 'unpipe_loader', '.cached').write_text(\n            json.dumps(\n                {\n                    'hash': loader_info['hash'],\n                    'loader_url': loader_info['endpoint'],\n                    'path': str(loader_path),\n                    'timestamp': time.time(),\n                },\n                indent=2,\n            )\n        )\n        os.rename(tempdir + '/unpipe_loader', loader_path)\nelse:\n    if cache_info:\n        cache_file_temp.write_text(\n            json.dumps(\n                {\n                    **cache_info,\n                    'timestamp': time.time(),\n                }\n            )\n        )\n        cache_file_temp.replace(cache_file)\n\n# If this isn't in cache-only mode, run the loader entry point\nif not cache_only:\n    runpy.run_path(str(loader_path))\n"
}