Giter Club home page Giter Club logo

tunnelto's Introduction

BuildRelease crate GitHub Docker Registry crate

tunnelto

tunnelto lets you expose your locally running web server via a public URL. Written in Rust. Built completely with async-io on top of tokio.

  1. Install
  2. Usage Instructions
  3. Host it yourself

Install

Brew (macOS)

brew install agrinman/tap/tunnelto

Cargo

cargo install tunnelto

Everywhere

Or Download a release for your target OS here: tunnelto/releases

Usage

Quick Start

tunnelto --port 8000

The above command opens a tunnel and forwards traffic to localhost:8000.

More Options:

tunnelto 0.1.14

USAGE:
    tunnelto [FLAGS] [OPTIONS] [SUBCOMMAND]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information
    -v, --verbose    A level of verbosity, and can be used multiple times

OPTIONS:
        --dashboard-address <dashboard-address>    Sets the address of the local introspection dashboard
    -k, --key <key>                                Sets an API authentication key to use for this tunnel
        --host <local-host>
            Sets the HOST (i.e. localhost) to forward incoming tunnel traffic to [default: localhost]

    -p, --port <port>
            Sets the port to forward incoming tunnel traffic to on the target host

        --scheme <scheme>
            Sets the SCHEME (i.e. http or https) to forward incoming tunnel traffic to [default: http]

    -s, --subdomain <sub-domain>                   Specify a sub-domain for this tunnel

SUBCOMMANDS:
    help        Prints this message or the help of the given subcommand(s)
    set-auth    Store the API Authentication key

Host it yourself

  1. Compile the server for the musl target. See the musl_build.sh for a way to do this trivially with Docker!
  2. See Dockerfile for a simple alpine based image that runs that server binary.
  3. Deploy the image where ever you want.

Testing Locally

# Run the Server: xpects TCP traffic on 8080 and control websockets on 5000
ALLOWED_HOSTS="localhost" cargo run --bin tunnelto_server

# Run a local tunnelto client talking to your local tunnelto_server
CTRL_HOST="localhost" CTRL_PORT=5000 CTRL_TLS_OFF=1 cargo run --bin tunnelto -- -p 8000

# Test it out!
# Remember 8080 is our local tunnelto TCP server
curl -H '<subdomain>.localhost' "http://localhost:8080/some_path?with=somequery"

See tunnelto_server/src/config.rs for the environment variables for configuration.

Caveats for hosting it yourself

The implementation does not support multiple running servers (i.e. centralized coordination). Therefore, if you deploy multiple instances of the server, it will only work if the client connects to the same instance as the remote TCP stream.

The version hosted by us is a proper distributed system running on the the fabulous fly.io service. In short, fly.io makes this super easy with their Private Networking feature. See tunnelto_server/src/network/mod.rs for the implementation details of our gossip mechanism.

tunnelto's People

Contributors

agrinman avatar edrevo avatar jreyes33 avatar mxxk avatar siilwyn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tunnelto's Issues

tunnelto.dev subdomains not working

Hi, cool project!
I was playing with it and instantly noticed the subdomain flag.

Are subdomains supposed to work on the public instance?
Do I need to configure an API key for that to work?

I expected this command to give me back a public URL similar to stealthybox.tunnelto.dev or stealthybox-aexsh3w5.tuneelto.dev, but instead, the -s option seems ignored.

wormhole start -s stealthybox -p 31888
Welcome to wormhole!

<trunctated>

Wormhole activated on: https://aexsh3w5.tunnelto.dev

Did I misunderstand that this is supposed to only be an overriden host-header that's passed into the proxied request?

If not and I'm understanding this feature correctly, we can probably implement an error or warning message and include some docs around API keys or the capabilities of private instances.

UnexpectedEof

Hi, been getting this error since morning when i try to spin a tunnel Error: Tls(Custom { kind: UnexpectedEof, error: "unexpected EOF during handshake" })

Certificate on server

I've just tried to run the server locally on my machine, to have my domain for the tunnels.
What I did not find is how I could set a server certificate under which the tunnel is reachable.

anonymous pull of docker image doesn't work

The README.md mentions an image available on the github package docker registry

However, when I try to pull this image, I have an unauthorized error.

unauthorized: Your request could not be authenticated by the GitHub Packages service. Please ensure your access token is valid and has the appropriate scopes configured.
Error: Error initializing source docker://docker.pkg.github.com/agrinman/tunnelto/tunnelto_server:0.1.10: Error reading manifest 0.1.10 in docker.pkg.github.com/agrinman/tunnelto/tunnelto_server: unauthorized: Your request could not be authenticated by the GitHub Packages service. Please ensure your access token is valid and has the appropriate scopes configured.

Maybe this issue is linked to the introduction of the github container registry that seems to replace the github packages docker registry.
I couldn't find information about the possibility of anonymously pull images on the github package docker registry (the one currently in use in this repo?)

Work within environments with proxy

I've tested the .exe file on a Windows 10, and it doesn't seem to be able to create the tunnel.

The pc is in a proxy'd network, and I guess that is the problem.

There is any way to set the proxy settings?

Incorrect text in help menu

Using multiple v on the command prompt is not allowed, though the help menu indicates that it is.

D:\>tunnelto --port xxxx --subdomain yyyy -vv
error: The argument '--verbose' was provided more than once, but cannot be used multiple times

USAGE:
    tunnelto --port <port> --subdomain <sub-domain> --verbose

For more information try --help

D:\>tunnelto --help
tunnelto 0.1.9
Alex Grinman <[email protected]>
Expose your local web server to the internet with a public url.

USAGE:
    tunnelto [FLAGS] [OPTIONS] [SUBCOMMAND]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information
    -v, --verbose    A level of verbosity, and can be used multiple times   <<<<<<<<<<<<

Grpc Support?

Today I wanted to try tunnelto to expose my local gRPC service to my mobile, but for some reason, tunnelto couldn't handle that:
Here are some logs when I tried to do that

$ grpcurl -plaintext -proto myproto.proto https://myservice.tunnelto.dev myservice.HelloWorld/Hello
Failed to dial target host "https://myservice.tunnelto.dev": dial tcp: lookup tcp///myservice.tunnelto.dev: getaddrinfow: The specified class was not found.

also, I tried to remove https and use port 443 but didn't work.
I thought since gRPC is over http2 it would work, but apparently it didn't :(.

Sudden crashes when running jupyter-notebook

I have been getting Error: Io(Custom { kind: Other, error: "" }) consistently.
I would be happy to supply you with a more comprehensive stack trace soon. It would be much easier though if you throw me a few steps to follow.

Document authentication for selfhost

I'm interested in selfhosting a tunnelto server, but I wouldn't want anyone on the internet to be able to create tunnels with my server. I see there is some API Key concept, but I can't find any instructions on how to set it up server-side. Any help would be appreciated.

client is unaware that it needs to reconnect after OS suspend

I left my PC (WSL2 on Win11) in suspend for overnight and the client continues running, but the tunnel is not found when I tried it in the morning.

This has happened a few times already, but now I've started the client with --verbose, and when it happens next time I'll try to get more details. (strace? gdb?)

Non-root URL doesn't work for Single Page App

Hello,

I'm trying out tunnelto coming from ngrok.

When I run webpack-dev-server (including the option historyApiFallback: true) to bring up my site locally I have an endpoint at http://localhost:3000/oauth-callback which is part of a React app and works fine locally at this address.

When I run

tunnelto --port 3000 --subdomain <mycustomsubdomain>

and launch https://<mycustomsubdomain>.tunnelto.dev I can see the site loads.

However when I visit https://<mycustomsubdomain>.tunnelto.dev/oauth-callback I get:

Error: Cannot GET /oauth-callback

Other valid routes in my React app also get the same response.

This setup works fine for me in ngrok.

Thanks.

Periodically getting denied connection

Hi,

After leaving multiple tunnels open for some period of time they tend to drop with the error below.

⣷ Success! Remote tunnel created on: https://jurat.tunnelto.dev
=> Forwarding to localhost:8003

200             GET     /
200             GET     /favicon.ico
Error: Server denied the connection. Please check your authentication key.

host option is not working

I create tunnel with:
tunnelto --subdomain test --port 443 --scheme https --host local.domain.com --dashboard-port 9443 -v

I have local.domain.com added in /etc/hosts to point to 127.0.0.1.
On local I have my app and when I check the HTTP_HOST header is "test.tunneto.dev" and not "local.domain.com".
If I test with:
curl -H "Host:local.domain.com" https://local.domain.com
I see in my app HTTP_HOST=local.domain.com as expected.

Did I miss something, or it's really a bug?

Header-only responses faulty

I have an endpoint that returns a header-only 200 OK response; there is no body.

It's generated using Rails's head :ok method (here).

When I hit this endpoint with curl via tunnelto, the response does not seem to make it back out of the tunnel to me. curl hangs, and eventually stops itself with:

curl: (92) HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)

If I change my endpoint to return a 200 OK response with a non-empty body, everything works as expected.

In both cases the Request Inspector shows a 200 response being sent straightaway – but the header-only one seems to get lost in the tunnel.

This happens with both GET and POSTs. Not sure if it is related to #30.

I'm using tunnelto 0.1.12.

Crash handling

Improve the user experience by automatically sending crash reports (rather than requesting the user do it) and restarting the tunnel. I don't have a way to see that a tunnel is down unless I look at my console window, and finding the crash report is tedious. Cheers

Failed to save authentication key file

I have a subscription with 5 subdomains set, and use the provided key in the following command.
Running the following as sudo succeeds. However, run as the ordinary user:

tunnelto set-auth --key <redacted>

Produces this error report:

name = 'tunnelto'
operating_system = 'unix:Ubuntu'
crate_version = '0.1.12'
explanation = '''
Panic occurred in file 'tunnelto/src/config.rs' at line 86
'''
cause = 'Failed to save authentication key file.: Os { code: 13, kind: PermissionDenied, message: "Permission denied" }'
method = 'Panic'
backtrace = '''

   0: 0x5637bba6e2c8 - <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::hcd1fa878e1b8802a
   1: 0x5637bbad800b - tokio::runtime::enter::Enter::block_on::h95d34c6dc245a0d5
   2: 0x5637bbaeda97 - tokio::runtime::context::enter::h186f41ed33a1603c
   3: 0x5637bbac58cf - tokio::runtime::handle::Handle::enter::hd6854b6249e24b90
   4: 0x5637bbab5b67 - tunnelto::main::h8cef60dfb4b7b7ab
   5: 0x5637bbafb743 - std::rt::lang_start::{{closure}}::ha5936fcca8ddcd9e
   6: 0x5637bbd627a8 - std::rt::lang_start_internal::{{closure}}::h6d21eebfa4beaf70
                at src/libstd/rt.rs:52
                 - std::panicking::try::do_call::h560a27b87db38b9c
                at src/libstd/panicking.rs:297
                 - std::panicking::try::h453d4afd696011f9
                at src/libstd/panicking.rs:274
                 - std::panic::catch_unwind::h211d02671f23030f
                at src/libstd/panic.rs:394
                 - std::rt::lang_start_internal::h464df2bbf46c7e7c
                at src/libstd/rt.rs:51
   7: 0x5637bbab5c72 - main
   8: 0x7fd61a7e0b97 - __libc_start_main
   9: 0x5637bba340ca - _start
  10:        0x0 - <unknown>'''

I'm having trouble working out the folder and file that are being written to.

Check whether stderr is a tty if writing to stderr

While writing up #48 I found a bit of an odd behaviour in tunnelto: although it apparently writes its output to stderr, it doesn't check whether stderr is a tty, instead it checks stdout:

$ tunnelto 2>test.txt

will write a bunch of ANSI escape codes to test.txt, but

$ tunnelto > /dev/null 2>test.txt

will not.

So when writing a script around tunnelto, despite only reading from stderr one has to redirect stdout in order to avoid an output full of ANSI.

Invalid Host header

hi tunnelto.dev, i have try tunnnelto to access my react app at port 4200, but when i try the tunnel just show invalid host header,

i have try
tunnelto -p 4200 -s mainWeb -h localhost

or
tunnelto -p 4200 -s mainWeb

but noting happens, how to fix it? thanks

Improved CLI Syntax for --dashboard-address

What's the syntax?

C:\Tunnelto>tunnelto-windows --subdomain jurat --port 8000 --dashboard-address http://localhost:60000
Well, this is embarrassing.

tunnelto had a problem and crashed. To help us diagnose the problem you can send us a crash report.

We have generated a report file at "C:\Users\joelc\AppData\Local\Temp\report-2e2f8c8d-91ae-47bd-bf38-c0ac1653d76c.toml". Submit an issue or email with the subject of "tunnelto Crash Report" and include the report as an attachment.

- Authors: Alex Grinman <[email protected]>

We take privacy seriously, and do not perform any automated error collection. In order to improve the software, we rely on people to submit reports.

Thank you kindly!

C:\Tunnelto>
C:\Tunnelto>tunnelto-windows --subdomain jurat --port 8000 --dashboard-address 60000
Well, this is embarrassing.

tunnelto had a problem and crashed. To help us diagnose the problem you can send us a crash report.

We have generated a report file at "C:\Users\joelc\AppData\Local\Temp\report-e6df7ccf-e5e6-4169-a3fe-fe31327afbc2.toml". Submit an issue or email with the subject of "tunnelto Crash Report" and include the report as an attachment.

- Authors: Alex Grinman <[email protected]>

We take privacy seriously, and do not perform any automated error collection. In order to improve the software, we rely on people to submit reports.

Thank you kindly!

C:\Tunnelto>tunnelto-windows --subdomain jurat --port 8000 --dashboard-address http://127.0.0.1:60000
Well, this is embarrassing.

tunnelto had a problem and crashed. To help us diagnose the problem you can send us a crash report.

We have generated a report file at "C:\Users\joelc\AppData\Local\Temp\report-620b9a4d-f791-4fd9-b542-9ca7e5eebec9.toml". Submit an issue or email with the subject of "tunnelto Crash Report" and include the report as an attachment.

- Authors: Alex Grinman <[email protected]>

We take privacy seriously, and do not perform any automated error collection. In order to improve the software, we rely on people to submit reports.

Thank you kindly!

TCP Tunnel support

Hi @agrinman,

Thanks for your work! I used wormhole as local http tunnel instead of ngrok. But is there any plan to add tcp tunnel?

Websocket returns error through tunnel

I had to switch back to ngrok for the time being as I cannot connect a websocket through the tunnel.

When trying to connect, the browser get's stuck throwing Invalid frame header while trying to connect. This is with a hello world Phoenix app that relies on LiveView if you need something to recreate it.

Let me know if I can help any more in tracking down the cause.

Start subcommand may not exist

Hi.
I'm interested in this awesome project!

I found a possible mistake in README.md. Should this line

CTRL_HOST="localhost" CTRL_PORT=5000 CTRL_TLS_OFF=1 cargo run --bin tunnelto -- start -p 8000

be

CTRL_HOST="localhost" CTRL_PORT=5000 CTRL_TLS_OFF=1 cargo run --bin tunnelto -- -p 8000

?

Cargo install custom build command for openssl fails

Running on Ubuntu 20.04 with rustc 1.44.1.

error: failed to run custom build command for `openssl-sys v0.9.58`

Caused by:
  process didn't exit successfully: `/tmp/cargo-installRs25uj/release/build/openssl-sys-b3896320ad7f5e70/build-script-main` (exit code: 101)
--- stdout
cargo:rustc-cfg=const_fn
cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR
X86_64_UNKNOWN_LINUX_GNU_OPENSSL_LIB_DIR unset
cargo:rerun-if-env-changed=OPENSSL_LIB_DIR
OPENSSL_LIB_DIR unset
cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_GNU_OPENSSL_INCLUDE_DIR
X86_64_UNKNOWN_LINUX_GNU_OPENSSL_INCLUDE_DIR unset
cargo:rerun-if-env-changed=OPENSSL_INCLUDE_DIR
OPENSSL_INCLUDE_DIR unset
cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR
X86_64_UNKNOWN_LINUX_GNU_OPENSSL_DIR unset
cargo:rerun-if-env-changed=OPENSSL_DIR
OPENSSL_DIR unset
run pkg_config fail: "`\"pkg-config\" \"--libs\" \"--cflags\" \"openssl\"` did not exit successfully: exit code: 1\n--- stderr\nPackage openssl was not found in the pkg-config search path.\nPerhaps you should add the directory containing `openssl.pc\'\nto the PKG_CONFIG_PATH environment variable\nNo package \'openssl\' found\n"

--- stderr
thread 'main' panicked at '

Could not find directory of OpenSSL installation, and this `-sys` crate cannot
proceed without this knowledge. If OpenSSL is installed and this crate had
trouble finding it,  you can set the `OPENSSL_DIR` environment variable for the
compilation process.

Make sure you also have the development packages of openssl installed.
For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora.

If you're in a situation where you think the directory *should* be found
automatically, please open a bug at https://github.com/sfackler/rust-openssl
and include information about your system as well as this message.

$HOST = x86_64-unknown-linux-gnu
$TARGET = x86_64-unknown-linux-gnu
openssl-sys = 0.9.58

Following the advice to sudo apt install libssl-dev solves it, but depending on system libraries like this is a (small) hurdle to installing the crate. Would there be a way to use an alternative dependency that doesn't need this system dependency?

Better scripting support (URLs output, ...)

This overlaps with but is more general than #25 I think.

The current output of tunnelto is somewhat uncomfortable when using it in a scripting context (e.g. as part of a script or as a tunneling tool for an S2S integration test suite):

  • getting the public URL requires reading stderr, which is not great when simultanously trying to keep / pipe stderr for error reporting / inspection
  • care has to be taken to avoid blocking
  • the formatting of the output is not really conducive to parsing either

I'm thinking one option would be a riff on the usual pidfile method: the ability to give tunnelto a directory name, and it'd write the public URL to $outdir/$pid. tunnelto's pid should be easy for the parent proces to retrieve.

For forward-compatibility purposes, the file could be written in a machine-readable format (e.g. json) so it could be extended more easily in the future, though I'm not entirely sure what else would be added to it, unless it grows an ngrok-like automation API (I don't know if that's in the plans, in that case also writing the endpoint would be useful).

It didn't work in windows 7 32-bit

Hello, I tried it on Windows 7 16-bit, and it works fine,
unfortunately, the current compiled version for windows don't work in 32-bit architecture

Prints tens of thousands of lines of ascii art

Hello!

I tried this program today by running this command:

tunnelto --port 4000 --subdomain lpil

It then printed this many times:


                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,



                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,

Heroku

How can I host tunnelto on Heroku?

Allow any value for gossip protocol DNS discovery domain

Currently, the gossip_dns_host is derived from the FLY_APP_NAME environment variable.

This makes it almost impossible to use the gossip protocol in an environment other than Fly, despite the implementation being pretty generic and only requiring DNS.

By allowing the gossip_dns_host to be specified in full and falling back to the current derivation from FLY_APP_NAME, it should allow other implementations of a distributed system. For instance, headless services in Kubernetes could be used to facilitate the gossip protocol.

Version checker should only recommend monotonic increases maybe

I just installed tunnelto for some testing. Did so via cargo install. As 0.1.17 has apparently been released on Cargo but the github release hasn't been cut yet, I get the following:

New version available: 0.1.17 => 0.1.16 (https://github.com/agrinman/tunnelto/releases/tag/0.1.16)

That's a bit strange, even / especially if 0.1.17 only exists to fix a cargo install issue (which I assume is the case given the commit message), as 0.1.16 might not work at all (I've not tested so no idea).

queryParams are Ignored

Query Params are being ignored while forwarding the request to local server.
I tried ngrok to see if any issue with the request. The request works fine with ngrok.

Tunneling was working for the same few weeks back.

Sample Req Details

Request Received In Terminal
200 POST /api/v1/me/phone/calldetails?location_id=&location_name=&client_id=&client_name=

tunnelto inspector
14:30:21 2s 200 POST /api/v1/me/phone/calldetails 0 KB 0 KB
Text
AccountSid=&ApiVersion=2010-04-01&ApplicationSid=&CallSid=&CallStatus=completed&Called=&Caller=&DialCallSid=&DialCallStatus=&Direction=&From=&To=

Verified With 0.1.9
url "https://github.com/agrinman/tunnelto/archive/0.1.9.zip"
sha256 "8bba2bf602365148e777cd82d23a75fac0d4d96db3d2006cb01b0a275dc9372f"

The Request works fine

New Feature: Config File

Would be great if we could set up a config file with common tunnels (like the ngrok config file)

authtoken: xxx
tunnels:
  quokkabot:
    proto: http
    addr: 7071
    subdomain: quokkabot

Customizable CTRL_PORT for tunnelto_server?

The environment variable CTRL_PORT is useful to override the control port used for the tunnelto client to connect to tunnelto_server, but there seems to be no equivalent to override the control port tunnelto_server binds to, as it is hardcoded:

control_server::spawn(([0,0,0,0], 5000));

let mut control_socket = match TcpStream::connect("localhost:5000").await {

While not critical, it would be nice to set the tunnelto_server control port via an environment variable. 🙂

The larger context for doing this is https://github.com/mxxk/tunnelto-proxy, which provides a proxy configuration for multiplexing between control traffic (on the root domain) and tunnel traffic (on subdomains). Having something like this be integrated into tunnelto directly would be a very significant undertaking, and different from the current approach used by tunnelto.dev where the control traffic is expected at wormhole.tunnelto.dev (and presumably wormhole is in BLOCKED_SUB_DOMAINS), while all other (tunnel) traffic is expected at *.tunnelto.dev.

Random crashes

I leave tunnelto running in a command prompt window and sometimes when I come back to my computer in the morning, the tunnel has crashed for no apparent reason.

D:\>tunnelto --subdomain [tunnelname] --port 8001

                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,


⣷ Success! Remote tunnel created on: https://[tunnelname].tunnelto.dev
=> Forwarding to localhost:8001

Error: Cannot use this sub-domain, it is already taken.

Also I'm curious what the text above the 'success' line is?

Stuck/slow OPTIONS response when no body

Noticed when using Tunnelto.dev with a nodejs/express app and returning an empty response for OPTIONs request results in very long request time (20-60 seconds), it works eventually but very slow to work with and test.
Here's how I used to handle OPTIONS:

if(req.method === 'OPTIONS') {
  return res.status(200).end();
}

Once I changed the response to have a body, tunnelto.dev started handling it much faster:

if(req.method === 'OPTIONS') {
  // add some check if it's tunnelto.dev (check headers.origin or headers.referer)
  return res.send({ success: true }).end();
}

Tunnel dies for no reason

Tunnels go dead after a while, and all I get is this message. They're no longer reachable.

⣷ Success! Remote tunnel created on: https://[tunnel]
=> Forwarding to localhost:8000

Local Inspect Dashboard: http://localhost:64908
 ERROR tunnelto > Malformed protocol control packet: "invalid control byte in DataPacket"

When visiting https://[tunnel] in the browser I get

Error: Tunnel Not Found

I'm having to restart tunnels every few hours.

Support for stdout log

Hi,

Thank you for creating Tunneto.

I am trying to run tunnel-to inside an electron app, which will start the connection between our customer local machine and send tunnel-to link to our server, So we can download data from the local machine.

let spawn = require('child_process');
let path = "path_to_tunnel_to"
ls = spawn(path, ['--version']);
ls.stdout.on('data', (data) => {
        console.log(data);
});

Output: tunnelto 0.1.12

Here in the above code it is returning the version because the process is terminated.

When I try to run

let spawn = require('child_process');
let path = "path_to_tunnel_to"
ls = spawn(path, ['--port', '3000']);
ls.stdout.on('data', (data) => {
        console.log(data);
});

It will not return anything until the process is terminated. I also tried by adding verbose.

Kindly suggest any other way to do this.

In Ngrok there is option log=stdout it will return logs in stdout. So we can process it and get URL

Then I added subdomain to the arguments, Now I know in which subdomain tunnel-to is running. But I cannot get the tunnel-to Local Inspect Dashboard URL for debugging purposes.

Refresh Access key

I accidentally added my access key to a public repo, but there's no option to refresh it.

I contacted support but have had no response and it's been a few weeks

Support static file serving

Hi tunnelto team, just started using it and I thought it would be a nice enhancement to be able to serve a static file (html for example).

Work around

python3 -m http.server 8000

Gracefully handle websocket Close messages

Maybe I missed it, but I don't think tunnelto gracefully handles websocket close messages and/or reconnects.

Testing this locally with a proxy (Fly.io) in-between tunnelto clients and servers: if the proxy goes away, the tunnel client appears to reconnect, but not without an error and then every request to the tunnel endpoint (<sub>.tunnelto.dev) will fail. Your users will have to manually start/stop their tunnel.

The client shows the following:

 ERROR tunnelto > Malformed protocol control packet: "invalid control byte in DataPacket"

and then trying to make a request:

$ curl something.tunnelto.dev
Error: Tunnel Not Found

I'm assuming this happens because a new subdomain is generated for the tunnel, but it's not printed.

Fly's proxy sends a "Restart" close message, to both the client and server, when we deploy. Normal websocket operations dictates clients and servers should try reconnecting when that happens. With tunstenite, that's a matter of handling the Message::Close(Option<CloseFrame>) appropriately depending on the close reason.

I would suggest the same hostname should be kept around on reconnect. The client should have rights to use the same hostname it was previously using for a reconnect sequence.

Restarting of our proxy is a normal part of operation. It does offer zero-downtime, but not for websocket connections (or other very long lives connections). It does the next best thing by gracefully closing the connections, expecting the clients to reconnect (on the freshly deployed version of our proxy).

Erroe: failed to write to incoming websocket: ConnectionClosed

Hi,

I'm having an issue with:

tunnelto 0.1.18

I'm trying to tunnel a wss connection however I'm getting an error. The same connection works with ngrock. The following are the two commands and the error logs:

ngrok http -region eu -hostname=### 172.28.1.3:8080
tunnelto --host 172.28.1.3 --subdomain ###--port 8080 -v

Logs:

101             GET     /v1/graphql
 DEBUG tunnelto::local                   > read from local service: "<non utf8>"
 DEBUG tunnelto::introspect::console_log > no log line for response
 INFO  tunnelto                          > got end stream [StreamId([206, 121, 210, 111, 39, 161, 7, 18])]
 DEBUG tunnelto                          > Processed packet: "END STREAM"
 DEBUG tunnelto::local                   > read from local service: "<non utf8>"
 DEBUG tunnelto::introspect::console_log > no log line for response
 WARN  tunnelto::local                   > closing stream
 DEBUG tunnelto::local                   > read from local service: "<non utf8>"
 DEBUG tunnelto::introspect::console_log > no log line for response
 WARN  tunnelto::local                   > closing stream
 ERROR tunnelto::introspect              > failed to write to incoming websocket: ConnectionClosed
 INFO  tunnelto::local                   > done reading from client stream
 ERROR tunnelto::introspect              > failed to write to incoming websocket: ConnectionClosed
 INFO  tunnelto::local                   > done reading from client stream
 ERROR tunnelto::introspect              > failed to write to incoming websocket: ConnectionClosed
 INFO  tunnelto::local                   > done reading from client stream
 ERROR tunnelto::introspect              > failed to write to incoming websocket: ConnectionClosed
 INFO  tunnelto::local                   > done reading from client stream
 DEBUG tunnelto::local                   > read from local service: "<non utf8>"
 DEBUG tunnelto::introspect::console_log > no log line for response
 WARN  tunnelto::local                   > closing stream
 ERROR tunnelto::introspect              > failed to write to incoming websocket: ConnectionClosed
 INFO  tunnelto::local                   > done reading from client stream
 ERROR tunnelto::introspect              > failed to write to incoming websocket: ConnectionClosed
 INFO  tunnelto::local                   > done reading from client stream
 INFO  tunnelto                          > stream["stream_iB4XD1s61LE"] -> init
 DEBUG tunnelto                          > Processed packet: "INIT STREAM"
 INFO  tunnelto                          > stream["stream_iB4XD1s61LE"] -> new data: 991
 INFO  tunnelto::local                   > setting up local stream: stream_iB4XD1s61LE
 INFO  tunnelto                          > forwarded to local tcp (stream_iB4XD1s61LE)
 DEBUG tunnelto                          > Processed packet: "STREAM DATA"
 DEBUG tunnelto::local                   > wrote to local service: 991
 DEBUG tunnelto::local                   > read from local service: "HTTP/1.1 101 Switching Protocols\r\nconnection: upgrade\r\nupgrade: websocket\r\nsec-websocket-accept: SKh2fziQyGpvgv3E0GZTAMiTZnI=\r\ndate: Fri, 04 Jun 2021 14:23:41 GMT\r\n\r\n"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.