From 9901e9e9ec052ef6a7b52025b747dddbb44f0a70 Mon Sep 17 00:00:00 2001 From: Unrud Date: Mon, 1 Oct 2018 07:35:54 +0200 Subject: [PATCH 001/258] exit fullscreen for multimedia keys --- bindata.generated.go | 4 ++-- webdata/fn.js | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/bindata.generated.go b/bindata.generated.go index 0a0d44b..8c0fd00 100644 --- a/bindata.generated.go +++ b/bindata.generated.go @@ -75,7 +75,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _webdataFnJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x1a\x69\x6f\xdb\x38\xf6\x7b\x7e\xc5\xab\x3e\x14\x76\xe3\x38\x71\xba\xdd\x19\xc4\x75\x77\xdd\xc4\x99\x04\x93\x0b\xb6\x33\xad\x11\x04\x01\x2d\x3d\xdb\x9a\xc8\xa2\x46\xa4\xe2\xb8\xd3\xfc\xf7\x05\x75\x92\x14\x25\xbb\x9d\xce\x7e\x58\xac\x81\xa6\x92\xde\xc1\x77\xf0\x5d\x94\xf6\xdf\xec\xc0\x1b\x00\x80\x63\x1a\xac\x43\x77\xbe\xe0\xd0\xb0\x9b\x70\x78\xd0\xf9\x19\x6e\xfd\x30\x72\xde\x47\xe2\xef\xbf\x69\xc4\x3d\x4a\x1f\xdb\x36\x5d\x7e\xd8\x81\x8c\x68\xbc\x70\x19\xcc\x5c\x0f\xc1\x65\x10\x90\x90\x03\x9d\xc1\x10\x97\x94\xe3\xde\x98\x46\xf6\x22\x20\x4e\xbb\x40\x3f\xa5\x74\x4a\x42\x81\x3b\x0b\x11\x81\xd1\x19\x5f\x91\x10\x8f\x60\x4d\x23\xb0\x89\x0f\x21\x3a\x2e\xe3\xa1\x3b\x8d\x38\x82\xcb\x81\xf8\xce\x3e\x0d\x61\x49\x1d\x77\xb6\x4e\x99\xb8\x1c\x22\xdf\xc1\x10\xf8\x02\x81\x63\xb8\x64\x62\x51\x71\xf3\xcb\xd5\x2d\xfc\x82\x3e\x86\xc4\x83\x9b\x68\xea\xb9\x36\x5c\xb8\x36\xfa\x0c\x81\x30\x08\xc4\x13\xb6\x40\x07\xa6\x19\x2b\x41\x74\x2a\x24\x19\xa5\x92\xc0\x29\x8d\x7c\x87\x70\x97\xfa\x2d\x40\x97\x2f\x30\x84\x27\x0c\x99\x4b\x7d\x78\x9b\x2d\x93\xf2\x6c\x01\x0d\x53\x3e\x0d\xc2\x85\x0a\x21\xd0\x40\x90\x36\x81\xf8\x6b\xf0\x08\x2f\xa8\x25\x23\x68\xe6\x11\xd6\x28\x94\x76\xc0\xf5\xe3\x45\x16\x34\x40\xe0\x0b\xc2\x85\xbe\x2b\xd7\xf3\x60\x8a\x10\x31\x9c\x45\x5e\x2b\x65\x34\x8d\x38\x7c\x3a\x1f\x9f\x5d\xdf\x8e\xa1\x7f\x35\x81\x4f\xfd\xe1\xb0\x7f\x35\x9e\x74\x61\xe5\xf2\x05\x8d\x38\xe0\x13\x26\xdc\xdc\x65\xe0\xb9\xe8\xc0\x8a\x84\x21\xf1\xf9\x1a\xe8\x2c\x65\x72\x39\x18\x1e\x9f\xf5\xaf\xc6\xfd\x8f\xe7\x17\xe7\xe3\x09\xd0\x10\x4e\xcf\xc7\x57\x83\xd1\x08\x4e\xaf\x87\xd0\x87\x9b\xfe\x70\x7c\x7e\x7c\x7b\xd1\x1f\xc2\xcd\xed\xf0\xe6\x7a\x34\x68\x03\x8c\x50\x08\x87\x29\x8f\x1a\xbb\xcf\x62\xef\x85\x08\x0e\x72\xe2\x7a\xac\xb0\xc3\x84\x46\xc0\x16\x34\xf2\x1c\x58\x90\x27\x84\x10\x6d\x74\x9f\xd0\x01\x02\x36\x0d\xd6\x9b\x7d\x9a\xb0\x21\x1e\xf5\xe7\xb1\xc2\xe9\xee\x6a\x03\x9c\xcf\xc0\xa7\xbc\x05\x0c\x11\xde\x2f\x38\x0f\x8e\xf6\xf7\x57\xab\x55\x7b\xee\x47\x6d\x1a\xce\xf7\xbd\x84\x01\xdb\xff\x20\xc4\xd9\xdf\xd9\xd9\xdf\x87\xbb\x0e\xc4\x1e\x69\xc1\x61\x72\x81\xac\x05\x6f\xb3\xcb\xfb\x1d\x9b\xfa\x8c\xc3\xf8\xfa\xf6\xf8\xec\xe1\xf2\xfa\xb7\xc1\xc3\xf8\x6c\x38\x18\x9d\x5d\x5f\x9c\x40\x0f\xee\x3a\x07\x2d\xe8\xbc\x13\xff\xee\xbb\x0a\xea\xf8\xfc\x72\x20\xfc\xd3\x83\xc3\x77\x07\xdd\x78\xa1\xbb\xe0\x79\x9f\xb5\x60\x19\x79\xfc\xbe\x05\xed\x76\x3b\x63\x7e\x73\x7d\x7e\x35\x1e\x0c\x1f\xfa\xc7\xc7\x83\x8b\xc1\xb0\x3f\x3e\xbf\xbe\x12\xcc\x77\x84\x8d\xef\x0e\x5a\x70\x70\xdf\x4a\xae\x7f\xfe\xa9\x05\x9d\xec\xa6\xf3\xd3\x5b\xe9\xee\xdd\xbb\xb7\x2d\x38\xbc\xdf\xb9\xef\xee\x68\x6c\x3f\xde\x8e\xc7\xd7\x57\x0f\x17\x83\x53\x21\xce\x41\xd7\x0c\x1e\x9e\xff\x72\x26\xe0\x9d\x0a\xf8\xe5\xf9\xc9\xc9\xc5\x40\xe8\x93\x2f\xf0\xeb\x60\xf2\xf0\xdb\xf5\xc5\xed\xe5\xe0\xe1\xf2\x76\x3c\x90\x99\x4b\xa0\x93\xeb\x4f\x57\x32\x5f\x09\x74\x7b\x93\xf0\x2b\x00\x97\x83\x93\xf3\xfe\xc3\xcd\x45\x7f\xf2\x70\xd3\xbf\x1d\x09\x9e\x6f\x0d\xf0\xe1\xe0\xb7\x87\xf1\xb0\x7f\xfc\x2b\xf4\xe0\x1f\x65\xf8\xd5\xe0\xf3\x38\x87\xbf\xeb\xee\xec\x3c\x91\x10\x56\xac\x1b\xff\x1f\x10\x27\xbf\xf0\xc8\x14\xbd\x14\xce\x85\xc7\x2f\xa9\xd8\x89\x3d\x98\x11\x8f\x61\xb7\x78\x3e\xe2\x22\xc7\xc5\x0a\xe6\xcf\x2e\x08\xe3\x03\xdf\xd1\x9e\x0e\xd1\x43\xc2\xd0\x39\xa6\x91\x2f\x51\x50\x7f\x4e\x5d\x7f\x9e\x6e\x2b\xe1\xdd\xfb\x04\xb0\xa4\x4f\xf8\x79\x14\x2d\x0b\x54\xf1\x64\xa2\x3c\x61\x76\x48\x3d\xef\xb3\xe1\x99\x8a\xe7\x84\x64\x3e\x77\xfd\xb9\xaa\x40\xf6\x74\xec\x2e\x51\x24\x87\x1e\xf8\x91\xe7\xc9\x5c\x14\x92\x9d\x59\xe4\xdb\x22\x9b\xc1\x2c\xf2\x3c\x66\x87\x88\xfe\xc0\x27\x53\x0f\x9d\x46\x13\xfe\x8c\x77\x5b\x88\x3c\x0a\x7d\x68\x38\xd4\x8e\x96\xe8\xf3\x76\x09\x15\xbe\x7e\x8d\x31\xc5\x2f\xc7\x5a\xe1\xf4\xd1\xe5\xa7\x5b\xe1\x2e\xe9\x17\x81\x38\xda\x8c\xc8\x6a\x19\xc6\x5a\x35\xbb\x3b\x2f\x92\x62\x21\xfe\x11\x21\x93\x04\x69\x60\xa6\x99\x3b\x83\x06\xb6\x4b\x08\x19\x58\xfc\x0c\xe0\x46\xb3\x1b\x83\x5f\x00\x3d\x86\x29\x93\x44\xdb\x61\x3d\xab\x0a\x24\x23\xc3\x25\xfd\x22\x21\x8e\x0c\xdc\x4c\x18\x66\x56\x6c\x83\x5c\x06\x84\x9c\x91\x62\x4b\x7c\x76\x15\x1c\xc9\x8e\xb9\x8b\x54\x1c\x79\xa1\x0a\x14\x83\xcc\xda\x26\x1a\x6c\x66\x69\x42\xac\x63\xbc\xa4\x5f\x8e\x89\x6f\xa3\x67\xb6\x6e\x1d\x5e\x2d\x5b\xb6\x85\xac\x3a\x92\xd9\xd6\x52\x94\x79\x28\xe8\xb6\x0a\xc8\x04\x75\xbb\x80\xac\xc1\x55\x03\xb2\x0e\x91\xd5\x32\x14\xc9\x47\x8b\x47\xe2\x38\x05\x89\xbd\x20\xfe\x1c\x07\x4f\xe8\xf3\x0b\x97\x71\xd1\x02\x34\xbc\xf4\xc2\xb8\xbb\xca\xaa\xbe\xea\xf5\xe2\x56\x71\xe6\xfa\xe8\x18\xed\x4d\x1c\x47\x5d\xc1\x9a\x69\x02\x58\x2d\xc8\x57\xdd\xb4\x19\xcb\xfa\x7e\x8f\x04\x09\xaf\xef\x93\xc3\xe8\x9c\xef\x11\x62\x49\xbf\x7c\xa7\x04\x06\xaf\x7f\x8f\x00\x97\xa3\x82\xcf\x71\xd5\xfa\xca\xee\x11\x5d\x63\x5c\x57\x1b\x3c\x69\xe4\xb8\xbb\xc4\x11\x27\xcb\x40\x8b\x8e\x62\x7d\xd7\x41\x9f\xbb\x33\x17\xc3\xa3\xa4\x6a\xb7\x8b\x27\xad\x1c\x2b\x20\x73\xfc\x9c\x21\xc4\x37\x1a\x2c\xee\x0a\x6a\x10\x26\x32\x6c\xa2\xc1\x4a\xc4\x12\x42\xae\xc1\x51\x71\x99\x68\xae\x06\x8e\xdc\x55\x9c\xfb\x0e\x3e\x7f\x5c\x9f\x3b\x0d\xd7\x19\xd3\x53\xd7\xcf\x2d\x2e\x7a\xf1\x86\xa8\xf6\x6e\xdc\x2a\x80\x0b\xef\xb5\x7e\xa4\xed\xa1\x3f\xe7\x8b\x2e\xb8\xbb\xbb\xb2\x9f\x62\x22\xd1\xe1\xa8\xe8\x77\xee\xbd\x64\xb0\xee\x4e\x61\xd7\x19\x34\x04\x7e\x0f\x74\x19\xb2\x5f\xea\x0a\xb7\x9b\x3f\x7d\xd9\x29\xfe\xa6\xd0\xbd\x8e\xaa\xa6\x4d\x3c\x3b\x12\x63\xd5\x0d\x75\x7d\x8e\x61\xdf\xb6\xd1\xc3\x30\x1e\xd7\x2e\x23\x8f\x37\x58\x80\x58\xab\xae\xa9\xc5\xae\x52\x9a\x1d\x42\xcf\x48\x70\xe7\xde\xdf\x1d\xdc\x17\x92\x93\x3a\xc4\x8e\x84\x28\xcc\xc2\x0e\xe1\x7d\x0f\x14\x41\xb3\x9f\x4d\x7d\xee\xfa\x11\xea\x36\xc9\x2d\x2a\x0c\x7a\x50\x61\x49\x72\x68\x22\x63\x9d\x4a\xd1\x60\x0f\x3a\x9a\x1e\x9b\x90\x65\x5d\xb2\x4a\x93\xd8\x1c\xf6\x80\x75\x9a\xb0\x1f\xeb\x17\x5f\x37\xe1\x0d\x34\x88\xb8\x21\x9d\x26\xec\x02\xe9\x74\x25\x07\x0b\x75\x6a\x7c\x01\x1f\x54\x3d\xd3\xc5\x8c\xb2\xd5\xb1\x51\xa4\x56\xb6\x56\x47\x0f\xa0\x13\xb5\x3b\xce\x2b\x6a\x55\xd7\x2c\x60\x2b\xd6\x66\xe8\x3b\x0d\x6b\x6a\xc1\xae\x71\xce\xda\x05\xab\x7b\x60\x69\x65\x2e\x0a\x1c\xc2\x51\x8c\x18\x7d\xdf\x19\xc5\x9d\x77\xbe\x5c\x3e\x0a\x40\x0f\x2e\x09\x5f\xb4\x79\x18\xf9\x76\x23\x9b\x0e\xd2\xc4\x97\x8f\x07\x65\xac\x49\x81\x25\x8c\x1c\x43\xc9\x94\x25\x1c\x9a\xf0\xa1\x07\x1d\xf8\xfa\x15\x94\xe7\x93\xe4\xb9\x6c\xf1\x7c\x1c\xd9\xeb\x25\xd7\x5d\x05\x34\x91\x40\x93\x02\x94\x1b\x64\x29\x0c\x92\xe8\x21\x4c\x90\xdd\x4d\x9a\xb2\x2b\xa4\x91\x46\xd5\xa3\x98\x73\x24\x7d\xd3\x41\xc7\x84\x59\xa5\x73\xca\xc7\xa0\x75\x4a\x57\xd6\x5b\x1a\xb1\xf6\x7a\xd9\x5d\x57\x03\x4f\x14\xf0\x44\x07\x27\x63\x14\x0f\xe5\x48\xce\x2d\xc3\x84\x2d\x32\xad\x33\xdb\x64\xe2\x98\xca\xda\x82\xf8\x8e\x87\x71\x95\x68\xe0\x13\x97\x5b\x1f\x63\xf2\x2e\x25\x09\x65\x70\xc5\x27\xde\xce\x4b\x49\x57\xc5\xd1\x86\x5e\x05\x66\x18\x67\x33\x78\x79\xda\x54\x5d\xcc\xf3\x59\x57\x2c\x9e\xf4\x12\x4e\x2a\x73\xb7\x32\x53\xf3\xfa\x8a\x24\xd4\xe7\x45\x15\xe2\x24\x9c\x63\xd2\x68\x04\xc4\x81\xd7\xaf\xa1\x12\x18\xcf\xfa\xdf\x92\x7a\x85\xd4\x41\x88\xa2\x3d\x39\xc1\x19\x11\x75\xa6\x59\xe0\x69\x3e\x08\x22\xb6\x68\x68\x9d\x48\x2c\x45\x4b\x35\x7d\xb3\xa9\x19\x58\x39\x45\x90\xb5\x7c\x95\xd9\x57\x97\x59\x3a\x31\xa8\xce\x14\xa5\xa0\xad\x4b\x18\xaa\xde\xca\x69\x43\x5d\x74\x6a\x81\x51\x1f\xa0\x99\x5a\x7a\x5e\x15\xde\x89\x47\x02\xdd\x33\x1e\x92\x30\x4b\xca\x1a\x91\xa6\x63\x5d\xaa\x36\x6c\x56\x35\x40\xd5\x52\x9b\x07\xb2\x2e\x4e\x11\xc7\x33\x4b\x5b\xde\x70\x86\xa2\x32\x37\xc5\xf5\xc0\x77\xe4\xa8\xfe\xdb\xe2\x25\xe9\xe0\x9e\xb5\x16\xae\xe8\x15\xb9\xa9\xa3\xd3\x5c\x26\xe8\xdf\x97\x1b\x90\xba\xd8\xd1\xa2\x83\x05\x9e\x6b\xa3\x60\xd4\x82\x8e\x1e\x01\x4a\x8a\xd9\xdd\xad\x8c\x8f\x8a\x14\xf6\x37\xba\x0d\xe4\x84\xa3\x66\xc2\x0f\xc6\x23\xe1\xd4\x0b\xa5\x2c\x9c\x65\xd8\x62\xeb\xbd\x6c\x91\xcc\xf3\x74\xa6\x2d\x2d\x8a\xda\xeb\xd7\xa5\x3c\x2c\xaf\xfa\x0d\x1d\xca\x0f\x96\xe6\x95\xa4\xf0\xeb\xd7\xaa\xd3\x60\x4f\x2e\x4a\xef\xd5\xa3\x72\x7d\xd7\x4e\x23\xce\xa9\x5f\xce\x8b\xa6\xb2\xa4\x15\x73\x48\x5e\x92\x24\xe4\x06\xe5\x25\x4f\x17\x93\xac\x99\xef\xe1\xb6\x7c\xe3\xf3\xf3\x6f\x60\xfc\x76\x5b\xc6\xc9\xc1\xbb\x29\xc8\x54\x27\xa7\xf4\xc2\xaf\x1d\x4b\x8b\xe0\x8c\xb7\xd1\x1a\xba\x20\xe5\x74\xca\x90\x67\x99\xb8\xd4\x30\xb7\x34\x2f\x96\x4c\x50\x11\x90\xba\xcc\x07\x56\xa9\x18\x99\xf2\x66\x72\xf2\xf6\xff\xd4\xf9\x43\x52\x67\x45\x6e\x82\xff\x76\x31\x14\x22\xe8\x2e\x65\xd1\xf2\x73\x11\xfc\xe9\x93\x89\xfa\xe4\x7f\xc9\xed\x71\xcb\x57\x38\x44\x27\x8d\x5f\xe4\xb8\x8c\x67\x5d\x16\xfb\x23\xe4\xc9\xc0\x13\xd0\x95\x2c\x53\x7c\x0c\x05\x7b\xa5\x13\x1b\xe7\x39\x85\xc5\xc9\xb7\x25\x12\xdb\xae\xb2\x82\xf8\x55\x31\x9c\xd4\x30\x9c\xe4\x0c\xb5\xad\x50\x5d\x4e\x6a\x8b\xa7\x7c\x56\x9c\xfd\x62\xcd\xcd\x54\x77\xe6\x25\xf6\xa0\x73\x6f\xe2\x54\x53\x8f\x3e\xf4\xaa\x0b\x52\xf6\xab\x89\x18\xd5\x9d\x2f\xca\x7e\x8a\xb7\xd3\xb7\x38\xa9\xab\x92\xaf\xcb\xe4\xb5\x2e\x51\xc9\x85\xbe\x27\xe8\x71\xa2\x67\x82\x0a\x16\x86\x4c\x11\x47\xe3\x6e\x4f\x28\xf2\x66\xf3\x71\x5c\x3e\x6e\x3b\xcf\x4d\xd8\x97\xd6\x7f\x03\x9d\x83\x83\x83\xa6\xc2\x77\x12\xf3\x5d\x7f\x1b\xdf\xf5\x06\xbe\x95\x86\x35\xf8\x61\x33\xd5\xc4\x60\xfe\x7a\xaa\xc2\xc4\xc6\xe4\xab\xb5\x96\xf5\xdd\x52\x96\xc6\xeb\xf6\x67\x6d\xeb\x16\x1f\x81\x6c\x9c\x26\x77\x7b\xb1\x97\x2b\xc6\xc7\x04\x3a\x31\x36\x38\x95\x0b\x97\x9a\x27\xed\x94\xa5\xb4\x9c\x76\xcc\xa2\x2e\x98\x5f\x19\xcf\xd1\x8c\x6f\x06\x16\xc4\x13\xd2\xe0\x10\x59\x40\x7d\x86\x8d\x25\x32\x46\xe6\xa8\x14\x9a\x05\xb9\x9e\xfe\x2e\x86\x46\x5c\xc1\xef\x6c\x74\xd6\x6f\x58\xa3\xb3\xfe\xde\xe1\xbb\x7f\x5a\x2d\xb0\xc6\x83\xcf\xe3\xac\xc8\x25\xa8\x6d\x86\xfc\xec\xb2\x7f\xfc\x2b\xae\x33\x7e\x66\xbc\x44\xce\xc6\xca\xf5\x1d\xba\x6a\x7b\xd4\x8e\x77\x72\x7b\x41\xd8\xa2\xcd\xa2\x29\xe3\x61\xa3\x93\x25\xcd\xf4\x78\x72\xca\x29\x69\xa4\xe4\xf3\x64\x99\x86\xf5\x71\x32\x1e\x8c\xac\x66\x72\x9a\x98\x72\x2b\xbf\x38\xf1\x28\x71\xac\x16\x64\xca\x2b\x27\x8b\x24\xe2\x0b\x51\xaa\x6c\xc2\xf5\x93\x9e\xf8\xe3\x84\x00\xfd\xa4\x64\xe7\x2f\x66\xe6\xc8\xd3\xb7\x38\x71\xd1\xb3\x52\x14\x4b\x3a\x98\xb3\x3d\xca\x62\x6e\x95\x44\x09\x46\x46\x13\x90\x5a\xe4\x80\xc8\x98\xf1\x69\xcd\x06\xf4\x18\x47\x96\xe8\x11\xd7\xac\x8e\x46\xc0\x35\xfc\x29\x25\x61\xad\x58\x19\x8e\x4c\x57\xbc\x21\xcb\x9b\xf6\x4a\x7a\x1d\x57\xe6\xc3\xf1\x99\xd7\xd1\x0a\x78\x86\x9f\xd8\xb2\xcd\xf8\xda\xc3\xb6\xe3\xb2\xc0\x23\xa2\x2a\x58\x3e\xf5\xd1\xca\xcd\x56\x0b\x17\xea\x6f\x42\x88\x75\xad\x45\x12\x42\xb5\x9f\x88\x17\xa1\x00\x58\xe9\xdb\x9f\xe4\x0b\x9b\x9b\x90\x72\x6a\x53\xe1\x38\x6b\xc5\xd8\x91\x55\x1c\xce\xe6\xdb\x3f\xc8\x71\x7a\x60\xc5\x1f\x69\x59\xea\xe4\xaa\x32\xc9\x78\x24\xe1\xbf\x62\x69\xa0\x7e\xc2\xe9\x88\xda\x8f\xc8\x1b\x12\xc1\x2e\x58\xfb\xfb\x62\xae\x28\x62\x8d\x32\xee\x93\x25\x4a\xbd\x8e\x24\x09\x0d\x39\xfc\x0b\xac\x23\x85\x24\x7e\x7a\x04\x96\x25\x37\x48\xd6\xfe\x2a\xde\x39\xa9\x10\x6d\xea\xa7\x91\x2f\x82\x29\x8b\xb8\xf8\xa8\x50\xcf\xca\x4a\xe8\x19\x1a\xe9\xd8\xaf\x0d\xad\x75\x4a\xb2\x81\x29\xf7\xe9\x91\x6c\x3e\x6d\x2e\x27\xbe\x58\xb6\xb6\x43\x38\x91\xdb\xb4\x34\xaa\x6b\xfd\x9d\x29\xb2\x70\x19\xa7\xe1\xba\xcd\x38\xe1\x18\x3b\xaf\x08\x0d\x4d\xad\xea\x7d\x34\xf3\xf0\xd9\x52\x75\x8d\xf7\xd3\x8c\xda\x11\x6b\x94\x87\xc7\xca\x85\x99\x69\x51\xc3\xee\xd6\x16\x34\xce\xa4\xc6\xb8\xd1\x09\x93\x4d\x28\xef\x80\xd8\x73\xb2\xff\x75\xd7\x1b\x3e\xd7\xd0\x85\x36\x7f\xf6\xa2\xba\x7c\x5b\x27\x6d\x0a\xff\x6a\x23\x95\x91\x36\xa7\x01\xa8\xc9\x49\x92\xed\x32\x8b\xd5\xe6\xe4\x2c\x33\x1a\xaa\x9a\xed\xb9\xf6\xa3\x55\xbc\x19\x2f\x82\x4d\x37\xe5\x36\xea\x6f\xbd\x4f\xc4\x2f\xdb\x77\x41\xc4\xc4\x84\xc0\x31\x2d\x20\x2d\x91\x1b\x24\x47\xa5\xd7\x1b\x2b\xc8\x0f\xd1\x72\xcb\x7d\x55\xbf\xb7\xd4\xfd\xf5\x8d\xc6\xfb\xab\x91\x5d\x6d\xda\x24\x99\x54\x98\x37\x9e\x8f\x0d\x5f\x24\xca\x9a\xeb\xb5\xb6\x56\xa5\xc4\x00\x25\x92\x4a\xe7\x54\x38\xe5\xaf\x07\xba\x29\x25\x95\xbf\x30\x0c\x88\x53\x3e\x20\x4b\x9f\xdc\xfd\xe9\x3a\x47\x60\x05\x21\x3e\xf1\x90\xd8\x8f\xe9\x4e\x6b\x09\x77\x1d\x19\xbf\x9b\x7d\x49\xf7\x5a\x4a\xe8\x91\x75\x40\x22\x86\x95\x84\xf9\x07\xb9\x2a\xa1\x8f\xcf\xbc\x76\xc5\xe2\x4b\x5c\x95\xf0\x89\x7a\xd1\x12\x1d\xba\xf2\xcb\x94\xd2\x77\xc3\x26\xa2\x65\xc4\x0d\x72\x4a\xdf\x21\x9b\x88\xa2\xa0\x92\xe4\xf6\xe6\xe5\xbe\x3d\xa3\xe1\x80\xd8\x8b\x46\xee\x63\x6a\xfc\x5c\x49\x0b\x6d\xda\x76\x9d\x6d\xc2\x19\x6a\x43\x1a\xe4\x13\xb5\x47\xd1\x8b\xd0\xf6\x23\xae\xf5\x78\xcd\xee\x37\xe6\x1b\xc1\xe8\x87\xe5\x1a\xa9\xdb\x7b\xd5\x8b\x9b\xa2\x1a\xe1\xb9\x10\xbe\xa0\xd0\x34\x00\x53\xf3\xa8\xa8\xa8\xf6\x46\xc9\xa0\x93\xa5\x8a\x29\xb1\x1f\x1b\x86\xbc\x90\xa2\x51\x3f\xa0\x41\xda\x21\x6c\xe8\xc8\xaa\x72\x58\x96\xc4\x4c\xc7\x46\xa6\xa2\x91\xe1\x6f\x55\x88\x0c\xe9\x71\xab\x5a\x0c\xdf\x52\x8f\xcd\x27\xee\x1b\xec\x98\x95\x69\xa8\xdb\x53\x21\x8a\xf1\xf2\x87\xec\xaa\xbc\xd1\x4e\x78\x9a\x7c\x2a\x2c\x58\x5e\x22\x3e\x0c\x61\x9c\x84\xdc\x6a\xc9\x5f\x47\xb4\xf2\x6f\xbc\x37\xd0\xa2\xef\xe4\x94\x03\xdf\xd9\x9a\xce\x8e\xdf\x39\xe4\xa4\xc9\x2b\x88\xad\xa9\x97\xf4\x09\x73\xda\x4b\xfa\x84\x05\xe5\x4b\x71\xf9\x9f\x00\x00\x00\xff\xff\xdf\x41\x43\xaa\x8f\x35\x00\x00") +var _webdataFnJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x1a\x69\x6f\xdb\x38\xf6\x7b\x7e\xc5\xab\x3e\x14\x72\xe3\xc8\x71\xba\xdd\x19\xc4\x75\x77\xdd\xc4\x99\x04\x93\x0b\xb6\x33\xad\x11\x04\x01\x2d\xd1\xb6\x26\xb2\xa8\x11\xa9\x38\xee\x34\xff\x7d\x41\xea\x22\x29\x4a\x4e\xbb\x9d\xc5\x62\xb1\x02\x9a\xca\x7a\x07\xdf\xc1\x77\x51\xea\xbc\xd9\x81\x37\x00\x00\x47\x24\xda\xc4\xfe\x62\xc9\xc0\x76\x5b\x70\xb0\xdf\xfd\x19\x6e\xc2\x38\xf1\xde\x27\xfc\xef\x3f\x49\xc2\x02\x42\x1e\x1c\x97\xac\x3e\xec\x40\x4e\x34\x59\xfa\x14\xe6\x7e\x80\xc1\xa7\x10\xa1\x98\x01\x99\xc3\x08\xaf\x08\xc3\x7b\x13\x92\xb8\xcb\x08\x79\x4e\x89\x7e\x42\xc8\x0c\xc5\x1c\x77\x1e\x63\x0c\x94\xcc\xd9\x1a\xc5\xf8\x10\x36\x24\x01\x17\x85\x10\x63\xcf\xa7\x2c\xf6\x67\x09\xc3\xe0\x33\x40\xa1\xd7\x21\x31\xac\x88\xe7\xcf\x37\x19\x13\x9f\x41\x12\x7a\x38\x06\xb6\xc4\xc0\x70\xbc\xa2\x7c\x51\xfe\xe3\x97\xcb\x1b\xf8\x05\x87\x38\x46\x01\x5c\x27\xb3\xc0\x77\xe1\xdc\x77\x71\x48\x31\x20\x0a\x11\x7f\x42\x97\xd8\x83\x59\xce\x8a\x13\x9d\x70\x49\xc6\x99\x24\x70\x42\x92\xd0\x43\xcc\x27\x61\x1b\xb0\xcf\x96\x38\x86\x47\x1c\x53\x9f\x84\xf0\x36\x5f\x26\xe3\xd9\x06\x12\x67\x7c\x6c\xc4\xb8\x0a\x31\x90\x88\x93\xb6\x00\x85\x1b\x08\x10\x2b\xa9\x25\x23\x68\xe6\xe1\xd6\x28\x95\xf6\xc0\x0f\xc5\x22\x4b\x12\x61\x60\x4b\xc4\xb8\xbe\x6b\x3f\x08\x60\x86\x21\xa1\x78\x9e\x04\xed\x8c\xd1\x2c\x61\xf0\xe9\x6c\x72\x7a\x75\x33\x81\xc1\xe5\x14\x3e\x0d\x46\xa3\xc1\xe5\x64\xda\x83\xb5\xcf\x96\x24\x61\x80\x1f\x71\xca\xcd\x5f\x45\x81\x8f\x3d\x58\xa3\x38\x46\x21\xdb\x00\x99\x67\x4c\x2e\x86\xa3\xa3\xd3\xc1\xe5\x64\xf0\xf1\xec\xfc\x6c\x32\x05\x12\xc3\xc9\xd9\xe4\x72\x38\x1e\xc3\xc9\xd5\x08\x06\x70\x3d\x18\x4d\xce\x8e\x6e\xce\x07\x23\xb8\xbe\x19\x5d\x5f\x8d\x87\x0e\xc0\x18\x73\xe1\x70\xc6\xa3\xc1\xee\x73\xe1\xbd\x18\x83\x87\x19\xf2\x03\x5a\xda\x61\x4a\x12\xa0\x4b\x92\x04\x1e\x2c\xd1\x23\x86\x18\xbb\xd8\x7f\xc4\x1e\x20\x70\x49\xb4\xd9\xee\xd3\x94\x0d\x0a\x48\xb8\x10\x0a\x67\xbb\xcb\x01\x38\x9b\x43\x48\x58\x1b\x28\xc6\xf0\x7e\xc9\x58\x74\xd8\xe9\xac\xd7\x6b\x67\x11\x26\x0e\x89\x17\x9d\x20\x65\x40\x3b\x1f\xb8\x38\x9d\x9d\x9d\x4e\x07\x6e\xbb\x20\x3c\xd2\x86\x83\xf4\x06\xd3\x36\xbc\xcd\x6f\xef\x76\x5c\x12\x52\x06\x93\xab\x9b\xa3\xd3\xfb\x8b\xab\xdf\x86\xf7\x93\xd3\xd1\x70\x7c\x7a\x75\x7e\x0c\x7d\xb8\xed\xee\xb7\xa1\xfb\x8e\xff\xbb\xeb\x29\xa8\x93\xb3\x8b\x21\xf7\x4f\x1f\x0e\xde\xed\xf7\xc4\x42\xb7\xd1\x53\x87\xb6\x61\x95\x04\xec\xae\x0d\x8e\xe3\xe4\xcc\xaf\xaf\xce\x2e\x27\xc3\xd1\xfd\xe0\xe8\x68\x78\x3e\x1c\x0d\x26\x67\x57\x97\x9c\xf9\x0e\xb7\xf1\xed\x7e\x1b\xf6\xef\xda\xe9\xfd\xcf\x3f\xb5\xa1\x9b\xff\xe8\xfe\xf4\x56\xfa\xf5\xee\xdd\xdb\x36\x1c\xdc\xed\xdc\xf5\x76\x34\xb6\x1f\x6f\x26\x93\xab\xcb\xfb\xf3\xe1\x09\x17\x67\xbf\x67\x06\x8f\xce\x7e\x39\xe5\xf0\x6e\x0d\xfc\xe2\xec\xf8\xf8\x7c\xc8\xf5\x29\x16\xf8\x75\x38\xbd\xff\xed\xea\xfc\xe6\x62\x78\x7f\x71\x33\x19\xca\xcc\x25\xd0\xf1\xd5\xa7\x4b\x99\xaf\x04\xba\xb9\x4e\xf9\x95\x80\x8b\xe1\xf1\xd9\xe0\xfe\xfa\x7c\x30\xbd\xbf\x1e\xdc\x8c\x39\xcf\xb7\x06\xf8\x68\xf8\xdb\xfd\x64\x34\x38\xfa\x15\xfa\xf0\xb7\x2a\xfc\x72\xf8\x79\x52\xc0\xdf\xf5\x76\x76\x1e\x51\x0c\x6b\xda\x13\xff\x47\xc8\x2b\x6e\x02\x34\xc3\x41\x06\x67\xdc\xe3\x17\x84\xef\xc4\x3e\xcc\x51\x40\x71\xaf\x7c\x3e\x66\x3c\xc7\x09\x05\x8b\x67\xe7\x88\xb2\x61\xe8\x69\x4f\x47\x38\xc0\x88\x62\xef\x88\x24\xa1\x44\x41\xc2\x05\xf1\xc3\x45\xb6\xad\xb8\x77\xef\x52\xc0\x8a\x3c\xe2\xcf\xe3\x64\x55\xa2\xf2\x27\x53\xe5\x09\x75\x63\x12\x04\x9f\x0d\xcf\x54\x3c\x2f\x46\x8b\x85\x1f\x2e\x54\x05\xf2\xa7\x13\x7f\x85\x79\x72\xe8\x43\x98\x04\x81\xcc\x45\x21\xd9\x99\x27\xa1\xcb\xb3\x19\xcc\x93\x20\xa0\x6e\x8c\x71\x38\x0c\xd1\x2c\xc0\x9e\xdd\x82\x3f\xc5\x6e\x8b\x31\x4b\xe2\x10\x6c\x8f\xb8\xc9\x0a\x87\xcc\xa9\xa0\xc2\xd7\xaf\x02\x93\x5f\x05\xd6\x1a\xcf\x1e\x7c\x76\xf2\x22\xdc\x15\xf9\xc2\x11\xc7\xdb\x11\x69\x23\x43\xa1\x55\xab\xb7\xf3\x2c\x29\x16\xe3\x3f\x12\x4c\x25\x41\x6c\x9c\x6b\xe6\xcf\xc1\xc6\x4e\x05\x21\x07\xf3\xcb\x00\xb6\x5b\x3d\x01\x7e\x06\x1c\x50\x9c\x31\x49\xb5\x1d\x35\xb3\xaa\x41\x32\x32\x5c\x91\x2f\x12\xe2\xd8\xc0\xcd\x84\x61\x66\x45\xb7\xc8\x65\x40\x28\x18\x29\xb6\xc4\x4f\xbe\x82\x23\xd9\xb1\x70\x91\x8a\x23\x2f\x54\x83\x62\x90\x59\xdb\x44\xc3\xed\x2c\x4d\x88\x4d\x8c\x57\xe4\xcb\x11\x0a\x5d\x1c\x98\xad\xdb\x84\xd7\xc8\x96\xbe\x40\x56\x1d\xc9\x6c\x6b\x29\xca\x02\xcc\xe9\x5e\x14\x90\x29\xea\xcb\x02\xb2\x01\x57\x0d\xc8\x26\x44\xda\xc8\x90\x27\x1f\x2d\x1e\x91\xe7\x95\x24\xee\x12\x85\x0b\x3c\x7c\xc4\x21\x3b\xf7\x29\xe3\x2d\x80\x1d\x64\x37\xc6\xdd\x55\x55\xf5\x55\xbf\x2f\x5a\xc5\xb9\x1f\x62\xcf\x68\x6f\xe4\x79\xea\x0a\xd6\x5c\x13\xc0\x6a\x43\xb1\xea\xb6\xcd\x58\xd5\xf7\x7b\x24\x48\x79\x7d\x9f\x1c\x46\xe7\x7c\x8f\x10\x2b\xf2\xe5\x3b\x25\x30\x78\xfd\x7b\x04\xb8\x18\x97\x7c\x8e\xea\xd6\x57\x76\x0f\xef\x1a\x45\x5d\xb5\x59\xda\xc8\x31\x7f\x85\xc7\x0c\xad\x22\x2d\x3a\xca\xf5\x7d\x0f\x87\xcc\x9f\xfb\x38\x3e\x4c\xab\xb6\x53\x3e\x69\x17\x58\x11\x5a\xe0\xcf\x39\x82\xf8\xa1\xc1\x44\x57\xd0\x80\x30\x95\x61\x53\x0d\x56\x21\x96\x10\x0a\x0d\x0e\xcb\xdb\x54\x73\x35\x70\xe4\xae\xe2\x2c\xf4\xf0\xd3\xc7\xcd\x99\x67\xfb\xde\x84\x9c\xf8\x61\x61\x71\xde\x8b\xdb\xbc\xda\xfb\xa2\x55\x00\x1f\xde\x6b\xfd\x88\x13\xe0\x70\xc1\x96\x3d\xf0\x77\x77\x65\x3f\x09\x22\xde\xe1\xa8\xe8\xb7\xfe\x9d\x64\xb0\xde\x4e\x69\xd7\x39\xd8\x1c\xbf\x0f\xba\x0c\xf9\x95\xb9\xc2\xef\x15\x4f\x9f\x77\xca\xbf\x19\x74\xaf\xab\xaa\xe9\xa2\xc0\x4d\xf8\x58\x75\x4d\xfc\x90\xe1\x78\xe0\xba\x38\xc0\xb1\x18\xd7\x2e\x92\x80\xd9\x34\xc2\xb8\x51\x5d\x53\x8b\x5d\xa7\x34\x3d\x80\xbe\x91\xe0\xd6\xbf\xbb\xdd\xbf\x2b\x25\x47\x4d\x88\x5d\x09\x91\x9b\x85\x1e\xc0\xfb\x3e\x28\x82\xe6\x97\x4b\x42\xe6\x87\x09\xd6\x6d\x52\x58\x94\x1b\x74\xbf\xc6\x92\xe8\xc0\x44\x46\xbb\xb5\xa2\xc1\x1e\x74\x35\x3d\xb6\x21\xcb\xba\xe4\x95\x26\xb5\x39\xec\x01\xed\xb6\xa0\x23\xf4\x13\xf7\x2d\x78\x03\x36\xe2\x3f\x50\xb7\x05\xbb\x80\xba\x3d\xc9\xc1\x5c\x9d\x06\x5f\xc0\x07\x55\xcf\x6c\x31\xa3\x6c\x4d\x6c\x14\xa9\x95\xad\xd5\xd5\x03\xe8\x58\xed\x8e\x8b\x8a\x5a\xd7\x35\x73\xd8\x9a\x3a\x14\x87\x9e\x6d\xcd\x2c\xd8\x35\xce\x59\xbb\x60\xf5\xf6\x2d\xad\xcc\x25\x91\x87\x18\xe6\x23\xc6\x20\xf4\xc6\xa2\xf3\x2e\x96\x2b\x46\x01\xe8\xc3\x05\x62\x4b\x87\xc5\x49\xe8\xda\xf9\x74\x90\x25\xbe\x62\x3c\xa8\x62\x4d\x4b\x2c\x6e\x64\x01\x45\x33\x9a\x72\x68\xc1\x87\x3e\x74\xe1\xeb\x57\x50\x9e\x4f\xd3\xe7\xb2\xc5\x8b\x71\x64\xaf\x9f\xde\xf7\x14\xd0\x54\x02\x4d\x4b\x50\x61\x90\x15\x37\x48\xaa\x07\x37\x41\xfe\x6b\xda\x92\x5d\x21\x8d\x34\xaa\x1e\xe5\x9c\x23\xe9\x9b\x0d\x3a\x26\xcc\x3a\x9d\x33\x3e\x06\xad\x33\xba\xaa\xde\xd2\x88\xb5\xd7\xcf\x7f\xf5\x34\xf0\x54\x01\x4f\x75\x70\x3a\x46\xb1\x58\x8e\xe4\xc2\x32\x94\xdb\x22\xd7\x3a\xb7\x4d\x2e\x8e\xa9\xac\x2d\x51\xe8\x05\x58\x54\x09\x1b\x3f\x32\xb9\xf5\x31\x26\xef\x4a\x92\x50\x06\x57\xfc\xc8\x9c\xa2\x94\xf4\x54\x1c\x6d\xe8\x55\x60\x86\x71\x36\x87\x57\xa7\x4d\xd5\xc5\xac\x98\x75\xf9\xe2\x69\x2f\xe1\x65\x32\xf7\x6a\x33\x35\x6b\xae\x48\x5c\x7d\x56\x56\x21\x86\xe2\x05\x4e\x1b\x8d\x08\x79\xf0\xfa\x35\xd4\x02\xc5\xac\xff\x2d\xa9\x97\x4b\x1d\xc5\x98\xb7\x27\xc7\x78\x8e\x78\x9d\x69\x95\x78\x9a\x0f\xa2\x84\x2e\x6d\xad\x13\x11\x52\xb4\x55\xd3\xb7\x5a\x9a\x81\x95\x53\x04\x59\xcb\x57\xb9\x7d\x75\x99\xa5\x13\x83\xfa\x4c\x51\x09\xda\xa6\x84\xa1\xea\xad\x9c\x36\x34\x45\xa7\x16\x18\xcd\x01\x9a\xab\xa5\xe7\x55\xee\x1d\x31\x12\xe8\x9e\x09\x30\x8a\xf3\xa4\xac\x11\x69\x3a\x36\xa5\x6a\xc3\x66\x55\x03\x54\x2d\xb5\x45\x20\xeb\xe2\x94\x71\x3c\xb7\xb4\xe5\x0d\x67\x28\x2a\x73\x53\x5c\x0f\x43\x4f\x8e\xea\xbf\x2c\x5e\xd2\x0e\xee\x49\x6b\xe1\xca\x5e\x91\x99\x3a\x3a\xcd\x65\x9c\xfe\x7d\xb5\x01\x69\x8a\x1d\x2d\x3a\x68\x14\xf8\x2e\xe6\x8c\xda\xd0\xd5\x23\x40\x49\x31\xbb\xbb\xb5\xf1\x51\x93\xc2\xfe\x42\xb7\x81\x9c\x70\xd4\x4c\xf8\xc1\x78\x24\x9c\x79\xa1\x92\x85\xf3\x0c\x5b\x6e\xbd\xe7\x17\x24\xf3\x22\x9d\x69\x4b\xf3\xa2\xf6\xfa\x75\x25\x0f\xcb\xab\x7e\x43\x87\xf2\x83\xa5\x79\x25\x29\xfc\xfa\xb5\xea\x34\xd8\x93\x8b\xd2\x7b\xf5\xa8\x5c\xdf\xb5\xb3\x84\x31\x12\x56\xf3\xa2\xa9\x2c\x69\xc5\x1c\xd2\x97\x24\x29\xb9\x41\x79\xc9\xd3\xe5\x24\x6b\xe6\x7b\xf0\x52\xbe\xe2\xfc\xfc\x1b\x18\xbf\x7d\x29\xe3\xf4\xe0\xdd\x14\x64\xaa\x93\x33\x7a\xee\xd7\xae\xa5\x45\x70\xce\xdb\x68\x0d\x5d\x90\x6a\x3a\xa5\x98\xe5\x99\xb8\xd2\x30\xb7\x35\x2f\x56\x4c\x50\x13\x90\xba\xcc\xfb\x56\xa5\x18\x99\xf2\x66\x7a\xf2\xf6\xff\xd4\xf9\x43\x52\x67\x4d\x6e\x82\xff\x74\x31\xe4\x22\xe8\x2e\xa5\xc9\xea\x73\x19\xfc\xd9\x93\xa9\xfa\xe4\x7f\xc9\xed\xa2\xe5\x2b\x1d\xa2\x93\x8a\x17\x39\x3e\x65\x79\x97\x45\xff\x88\x59\x3a\xf0\x44\x64\x2d\xcb\x24\x8e\xa1\x60\xaf\x72\x62\xe3\x3d\x65\x30\x91\x7c\xdb\x3c\xb1\xed\x2a\x2b\xf0\xab\x8e\xe1\xb4\x81\xe1\xb4\x60\xa8\x6d\x85\xfa\x72\xd2\x58\x3c\xe5\xb3\xe2\xfc\x12\x9a\x9b\xa9\x6e\xcd\x4b\xec\x41\xf7\xce\xc4\xa9\xa1\x1e\x7d\xe8\xd7\x17\xa4\xfc\x6a\x88\x18\xd5\x9d\xcf\xca\x7e\x12\xdb\xe9\x5b\x9c\xd4\x53\xc9\x37\x55\xf2\x46\x97\xa8\xe4\x5c\xdf\x63\x1c\x30\xa4\x67\x82\x1a\x16\x86\x4c\x21\xa2\x71\xb7\xcf\x15\x79\xb3\xfd\x38\xae\x18\xb7\xbd\xa7\x16\x74\xa4\xf5\xdf\x40\x77\x7f\x7f\xbf\xa5\xf0\x9d\x0a\xbe\x9b\x6f\xe3\xbb\xd9\xc2\xb7\xd6\xb0\x06\x3f\x6c\xa7\x9a\x1a\xcc\xdf\x4c\x55\x9a\xd8\x98\x7c\xb5\xd6\xb2\xb9\x5b\xca\xd3\x78\xd3\xfe\x6c\x6c\xdd\xc4\x11\xc8\xd6\x69\x72\xb7\x2f\xbc\x5c\x33\x3e\xa6\xd0\xa9\xb1\xc1\xa9\x5d\xb8\xd2\x3c\x69\xa7\x2c\x95\xe5\xb4\x63\x16\x75\xc1\xe2\xce\x78\x8e\x66\x7c\x33\xb0\x44\x01\x97\x06\x8f\x30\x8d\x48\x48\xb1\xbd\xc2\x94\xa2\x05\x56\x0a\xcd\x12\x5d\xcd\x7e\xe7\x43\x23\x5e\xc3\xef\x74\x7c\x3a\xb0\xad\xf1\xe9\x60\xef\xe0\xdd\xdf\xad\x36\x58\x93\xe1\xe7\x49\x5e\xe4\x52\x54\x87\x62\x76\x7a\x31\x38\xfa\x15\x6f\x72\x7e\x66\xbc\x54\x4e\x7b\xed\x87\x1e\x59\x3b\x01\x71\xc5\x4e\x76\x96\x88\x2e\x1d\x9a\xcc\x28\x8b\xed\x6e\x9e\x34\xb3\xe3\xc9\x19\x23\xc8\xce\xc8\x17\xe9\x32\xb6\xf5\x71\x3a\x19\x8e\xad\x56\x7a\x9a\x98\x71\xab\xbe\x38\x09\x08\xf2\xac\x36\xe4\xca\x2b\x27\x8b\x28\x61\x4b\x5e\xaa\x5c\xc4\xf4\x93\x1e\xf1\x71\x42\x84\xc3\xb4\x64\x17\x2f\x66\x16\x98\x65\x6f\x71\x44\xd1\xb3\x32\x14\x4b\x3a\x98\x73\x03\x42\x05\xb7\x5a\xa2\x14\x23\xa7\x89\x50\x23\x72\x84\x64\x4c\x71\x5a\xb3\x05\x5d\xe0\xc8\x12\x3d\xe0\x0d\x6d\xa2\xe1\x70\x0d\x7f\x46\x50\xdc\x28\x56\x8e\x23\xd3\x95\x6f\xc8\x8a\xa6\xbd\x96\x5e\xc7\x95\xf9\x30\xfc\xc4\x9a\x68\x39\x3c\xc7\x4f\x6d\xe9\x50\xb6\x09\xb0\xe3\xf9\x34\x0a\x10\xaf\x0a\x56\x48\x42\x6c\x15\x66\x6b\x84\x73\xf5\xb7\x21\x08\x5d\x1b\x91\xb8\x50\xce\x23\x0a\x12\xcc\x01\x56\xf6\xf6\x27\xfd\xc2\xe6\x3a\x26\x8c\xb8\x84\x3b\xce\x5a\x53\x7a\x68\x95\x87\xb3\xc5\xf6\x8f\x0a\x9c\x3e\x58\xe2\x23\x2d\x4b\x9d\x5c\x55\x26\x39\x8f\x34\xfc\xd7\x34\x0b\xd4\x4f\x78\x36\x26\xee\x03\x66\xb6\x44\xb0\x0b\x56\xa7\xc3\xe7\x8a\x32\xd6\x08\x65\x21\x5a\x61\xa9\xd7\x91\x24\x21\x31\x83\x7f\x80\x75\xa8\x90\x88\xa7\x87\x60\x59\x72\x83\x64\x75\xd6\x62\xe7\x64\x42\x38\x24\xcc\x22\x9f\x07\x53\x1e\x71\xe2\xa8\x50\xcf\xca\x4a\xe8\x19\x1a\x69\xe1\x57\x5b\x6b\x9d\xd2\x6c\x60\xca\x7d\x7a\x24\x9b\x4f\x9b\xab\x89\x4f\xc8\xe6\x78\x88\x21\xb9\x4d\xcb\xa2\xba\xd1\xdf\xb9\x22\x4b\x9f\x32\x12\x6f\x1c\xca\x10\xc3\xc2\x79\x65\x68\x68\x6a\xd5\xef\xa3\x79\x80\x9f\x2c\x55\x57\xb1\x9f\xe6\xc4\x4d\xa8\x5d\x1d\x1e\x6b\x17\xa6\xa6\x45\x0d\xbb\x5b\x5b\xd0\x38\x93\x1a\xe3\x46\x27\x4c\x37\xa1\xbc\x03\x84\xe7\x64\xff\x2b\x5f\xd0\x18\x3f\xe7\xf8\x16\x9b\x6f\x8b\xe6\x7a\x9d\xab\x48\xdb\xa3\x1a\x1a\x52\x8c\x64\x8a\xdc\x00\x8d\x29\x36\x4f\x74\x86\x22\xe5\x06\xbe\xfb\x60\x95\x2f\xba\xcb\xd8\xd1\xdd\x59\x6f\xc0\x97\x1a\xe7\xc5\x9b\x82\x5f\xf9\x26\x8b\x12\xca\xc7\x01\x86\xb3\x6a\xd1\xe6\x89\x40\xda\x06\xd9\xfd\xd6\x72\xf1\xdf\x65\x83\x7f\x37\x1a\xeb\x2d\x94\x26\x80\x1a\x2b\x89\x99\xd6\xf0\x15\xa1\xac\xa7\x5e\x1f\x1b\x55\x4a\xa3\xb0\x42\x52\x6b\xe3\x1a\xdb\x72\xb9\x0c\xdf\x52\xbd\xdc\xfc\xc6\x34\x52\xfd\x2a\x30\x42\x5e\xf5\x50\x2b\x7b\x72\xfb\xa7\xef\x1d\x82\x15\xc5\xf8\x91\xc5\xc8\x7d\xc8\x36\x4c\x9b\xbb\xeb\xd0\xf8\xad\xeb\x73\xb6\x65\x32\xc2\x00\x6d\x22\x94\x50\x5c\x4b\x58\x7c\x44\xab\x12\x86\xf8\x89\x35\xae\x58\x7e\x3d\xab\x12\x3e\x92\x20\x59\x61\x8f\xac\xc3\x2a\xa5\xf4\xad\xaf\x89\x68\x95\x30\x83\x9c\xd2\xb7\xc3\x26\xa2\x24\xaa\x25\xb9\xb9\x7e\xbe\x73\xe6\x24\x1e\x22\x77\x69\x17\x3e\x26\xc6\x4f\x8c\xb4\x08\x25\x8e\xef\xbd\x24\x2a\x9b\x23\x13\xe4\x53\xb0\x07\xde\x3f\x10\xe7\x01\x6f\xb4\x90\xc9\x7d\xbd\x3d\x6d\x70\x46\x3f\x24\x65\x88\x99\xb2\xec\xd0\x5e\xf5\x45\x23\xd3\x20\x3c\xe3\xc2\x97\x14\x9a\x06\x60\x6a\xf8\x14\x15\xd5\x7e\x26\x1d\x4e\xf2\x54\x31\x43\xee\x83\x6d\xc8\x0b\x19\x1a\x09\x23\x12\x65\x55\x7d\x4b\x17\x55\x97\xc3\xf2\x24\x66\x3a\xea\x31\xe5\xfe\x1c\x5f\x37\xc9\x4b\x5a\x80\x3a\x9e\xdf\x98\x74\x35\x64\xf3\x29\xf9\x16\x3b\xe6\xb5\x18\x9a\xf6\x54\x8c\xf9\x48\xf8\x43\x76\x55\xd1\x1c\xa7\x3c\x4d\x3e\xe5\x16\xac\x2e\x21\x0e\x30\x28\x43\x31\xb3\xda\xf2\x17\x0d\xed\xe2\xbb\xec\x2d\xb4\x38\xf4\x0a\xca\x61\xe8\xbd\x98\xce\x15\xef\x09\x0a\xd2\xf4\xb5\xc1\x8b\xa9\x57\xe4\x11\x17\xb4\x17\xe4\x11\x97\x94\xcf\xe5\xed\xbf\x02\x00\x00\xff\xff\x29\x07\xbb\xc0\x43\x35\x00\x00") func webdataFnJsBytes() ([]byte, error) { return bindataRead( @@ -90,7 +90,7 @@ func webdataFnJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "webdata/fn.js", size: 13711, mode: os.FileMode(436), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "webdata/fn.js", size: 13635, mode: os.FileMode(436), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/webdata/fn.js b/webdata/fn.js index 99b579f..384f2e8 100644 --- a/webdata/fn.js +++ b/webdata/fn.js @@ -354,9 +354,7 @@ window.addEventListener("load", function() { }; ws.onclose = function() { - if (fullscreenElement()) { - exitFullscreen(); - } + exitFullscreen(); opening.style.display = "none"; pad.style.display = "none"; keys.style.display = "none"; @@ -366,15 +364,14 @@ window.addEventListener("load", function() { document.getElementById("keysbutton").addEventListener("click", function(e) { + exitFullscreen(); pad.style.display = "none"; keys.style.display = "flex"; history.pushState("keys", ""); }); document.getElementById("keyboardbutton").addEventListener("click", function(e) { - if (fullscreenElement()) { - exitFullscreen(); - } + exitFullscreen(); pad.style.display = "none"; keyboard.style.display = "flex"; text.focus(); From d95acc275ca3fa2aed0984482b8e15024b4dcb47 Mon Sep 17 00:00:00 2001 From: Unrud Date: Mon, 1 Oct 2018 07:35:54 +0200 Subject: [PATCH 002/258] X11: use existing keycodes when available --- plugin_x11.go | 170 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 136 insertions(+), 34 deletions(-) diff --git a/plugin_x11.go b/plugin_x11.go index ed0a98d..23ff6f6 100644 --- a/plugin_x11.go +++ b/plugin_x11.go @@ -25,6 +25,7 @@ package main // #include // #include // #include +// #include import "C" import ( "errors" @@ -40,6 +41,9 @@ const ( scrollDiv int = 20 ) +var modifierIndices [6]uint = [...]uint{C.ShiftMapIndex, C.Mod1MapIndex, + C.Mod2MapIndex, C.Mod3MapIndex, C.Mod4MapIndex, C.Mod5MapIndex} + type x11Plugin struct { display *C.Display lock sync.Mutex @@ -71,25 +75,16 @@ func (p *x11Plugin) Close() error { return nil } -func (p *x11Plugin) keyboardKeys(keys []Keysym) error { - p.lock.Lock() - defer p.lock.Unlock() - if p.display == nil { - return errors.New("X server connection closed") - } - if len(keys) == 0 { - return nil - } +func (p *x11Plugin) findEmptyKeycodeLocked() (C.KeyCode, C.int, error) { var minKeycodes, maxKeycodes C.int C.XDisplayKeycodes(p.display, &minKeycodes, &maxKeycodes) var keysymsPerKeycode C.int keysyms := C.XGetKeyboardMapping(p.display, C.KeyCode(minKeycodes), maxKeycodes-minKeycodes+1, &keysymsPerKeycode) if keysyms == nil { - return errors.New("failed to get keyboard mapping") + return 0, 0, errors.New("failed to get keyboard mapping") } defer C.XFree(unsafe.Pointer(keysyms)) - emptyKeycode := C.KeyCode(0) keycodes: for keycode := C.KeyCode(minKeycodes); keycode <= C.KeyCode(maxKeycodes); keycode++ { for i := 0; i < int(keysymsPerKeycode); i++ { @@ -101,35 +96,142 @@ keycodes: continue keycodes } } - emptyKeycode = keycode - break - } - if emptyKeycode == 0 { - return errors.New("no empty keycode found") + return keycode, keysymsPerKeycode, nil } + return 0, 0, errors.New("no empty keycode found") +} + +func (p *x11Plugin) changeKeyMappingLocked(keysymsPerKeycode C.int, + keycode C.KeyCode, keysym Keysym) { keycodeMapping := make([]C.KeySym, keysymsPerKeycode) - defer func() { - for i := range keycodeMapping { - keycodeMapping[i] = 0 + for i := range keycodeMapping { + keycodeMapping[i] = C.KeySym(keysym) + } + C.XChangeKeyboardMapping(p.display, C.int(keycode), keysymsPerKeycode, + (*C.KeySym)(unsafe.Pointer(&keycodeMapping[0])), 1) + C.XFlush(p.display) +} + +func (p *x11Plugin) getModKeycodesLocked() map[uint]C.KeyCode { + modKeymap := C.XGetModifierMapping(p.display) + defer C.XFreeModifiermap(modKeymap) + modKeycodes := make(map[uint]C.KeyCode) + for _, modIndex := range modifierIndices { + for i := 0; i < int(modKeymap.max_keypermod); i++ { + keycode := *(*C.KeyCode)(unsafe.Pointer(uintptr(unsafe.Pointer(modKeymap.modifiermap)) + + uintptr(uint(modIndex)*uint(modKeymap.max_keypermod)+uint(i)))) + if keycode != 0 { + modKeycodes[1< Date: Mon, 1 Oct 2018 07:35:55 +0200 Subject: [PATCH 003/258] X11: wait 500ms before and after remapping keycode --- plugin_x11.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin_x11.go b/plugin_x11.go index 23ff6f6..edbc063 100644 --- a/plugin_x11.go +++ b/plugin_x11.go @@ -37,7 +37,7 @@ import ( ) const ( - keyboardMappingDelay time.Duration = 125 * time.Millisecond + keyboardMappingDelay time.Duration = 500 * time.Millisecond scrollDiv int = 20 ) From 361dc8961435633cbea37bf4604de150e9869f79 Mon Sep 17 00:00:00 2001 From: Unrud Date: Mon, 1 Oct 2018 07:35:55 +0200 Subject: [PATCH 004/258] bump version to 0.0.10 --- CHANGELOG.md | 4 ++++ desktop/remote-touchpad.appdata.xml | 13 +++++++++---- main.go | 2 +- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f94b3b..dad3ace 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.0.10 (2018-10-01) + + * avoid race condition when typing on X11 + ## 0.0.9 (2018-09-29) * add multimedia keys diff --git a/desktop/remote-touchpad.appdata.xml b/desktop/remote-touchpad.appdata.xml index 6488c36..e226cf6 100644 --- a/desktop/remote-touchpad.appdata.xml +++ b/desktop/remote-touchpad.appdata.xml @@ -18,6 +18,11 @@ https://github.com/Unrud/remote-touchpad Unrud + +​
    +
  • avoid race condition when typing on X11
  • +
+
  • add multimedia keys
  • @@ -72,16 +77,16 @@ - https://raw.githubusercontent.com/Unrud/remote-touchpad/0.0.9/screenshots/1.png + https://raw.githubusercontent.com/Unrud/remote-touchpad/0.0.10/screenshots/1.png - https://raw.githubusercontent.com/Unrud/remote-touchpad/0.0.9/screenshots/2.png + https://raw.githubusercontent.com/Unrud/remote-touchpad/0.0.10/screenshots/2.png - https://raw.githubusercontent.com/Unrud/remote-touchpad/0.0.9/screenshots/3.png + https://raw.githubusercontent.com/Unrud/remote-touchpad/0.0.10/screenshots/3.png - https://raw.githubusercontent.com/Unrud/remote-touchpad/0.0.9/screenshots/4.png + https://raw.githubusercontent.com/Unrud/remote-touchpad/0.0.10/screenshots/4.png diff --git a/main.go b/main.go index 04e441b..5e83eee 100644 --- a/main.go +++ b/main.go @@ -45,7 +45,7 @@ const ( authenticationRateBurst int = 10 challengeLength int = 8 defaultBind string = ":0" - version string = "0.0.9" + version string = "0.0.10" ) func processCommand(plugin Plugin, command string) error { From 7edb092f93ad70219539fa4918cc97ed747e770e Mon Sep 17 00:00:00 2001 From: Unrud Date: Fri, 12 Oct 2018 12:04:54 +0200 Subject: [PATCH 005/258] Flatpak: Update runtime --- flatpak/com.github.unrud.RemoteTouchpad.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flatpak/com.github.unrud.RemoteTouchpad.json b/flatpak/com.github.unrud.RemoteTouchpad.json index 63413d9..d768c65 100644 --- a/flatpak/com.github.unrud.RemoteTouchpad.json +++ b/flatpak/com.github.unrud.RemoteTouchpad.json @@ -1,7 +1,7 @@ { "app-id" : "com.github.unrud.RemoteTouchpad", "runtime" : "org.freedesktop.Platform", - "runtime-version" : "1.6", + "runtime-version" : "18.08", "sdk" : "org.freedesktop.Sdk", "command" : "remote-touchpad", "rename-appdata-file" : "remote-touchpad.appdata.xml", @@ -21,7 +21,7 @@ { "type" : "git", "url" : "https://github.com/golang/net", - "commit" : "161cd47e91fd58ac17490ef4d742dc98bb4cf60e", + "commit" : "49bb7cea24b1df9410e1712aa6433dae904ff66a", "dest" : "src/golang.org/x/net" }, { From 8e7c945f0f909d2553b3dae9f3ee25d664dabc1a Mon Sep 17 00:00:00 2001 From: Unrud Date: Fri, 19 Oct 2018 00:25:28 +0200 Subject: [PATCH 006/258] rename plugin to backend --- plugin.go => backend.go | 14 ++++---- plugin_portal.go => backend_portal.go | 24 ++++++------- ..._disabled.go => backend_portal_disabled.go | 2 +- plugin_windows.go => backend_windows.go | 22 ++++++------ ...disabled.go => backend_windows_disabled.go | 2 +- plugin_x11.go => backend_x11.go | 34 +++++++++--------- ...x11_disabled.go => backend_x11_disabled.go | 2 +- main.go | 36 +++++++++---------- 8 files changed, 68 insertions(+), 68 deletions(-) rename plugin.go => backend.go (86%) rename plugin_portal.go => backend_portal.go (91%) rename plugin_portal_disabled.go => backend_portal_disabled.go (95%) rename plugin_windows.go => backend_windows.go (89%) rename plugin_windows_disabled.go => backend_windows_disabled.go (95%) rename plugin_x11.go => backend_x11.go (89%) rename plugin_x11_disabled.go => backend_x11_disabled.go (95%) diff --git a/plugin.go b/backend.go similarity index 86% rename from plugin.go rename to backend.go index 44d6511..51b331f 100644 --- a/plugin.go +++ b/backend.go @@ -39,15 +39,15 @@ const ( KeyLimit ) -type PluginInfo struct { +type BackendInfo struct { Name string - Init func() (Plugin, error) + Init func() (Backend, error) } -var Plugins []PluginInfo = []PluginInfo{ - {"X11", InitX11Plugin}, - {"RemoteDesktop portal", InitPortalPlugin}, - {"Windows", InitWindowsPlugin}, +var Backends []BackendInfo = []BackendInfo{ + {"X11", InitX11Backend}, + {"RemoteDesktop portal", InitPortalBackend}, + {"Windows", InitWindowsBackend}, } type UnsupportedPlatformError struct { @@ -58,7 +58,7 @@ func (e UnsupportedPlatformError) Error() string { return e.err.Error() } -type Plugin interface { +type Backend interface { Close() error KeyboardText(text string) error KeyboardKey(key Key) error diff --git a/plugin_portal.go b/backend_portal.go similarity index 91% rename from plugin_portal.go rename to backend_portal.go index fdf22fb..03bd7cf 100644 --- a/plugin_portal.go +++ b/backend_portal.go @@ -40,14 +40,14 @@ const ( btnMiddle int32 = 0x112 ) -type portalPlugin struct { +type portalBackend struct { bus *dbus.Conn remoteDesktop dbus.BusObject sessionHandle dbus.ObjectPath lock sync.RWMutex } -func InitPortalPlugin() (Plugin, error) { +func InitPortalBackend() (Backend, error) { bus, err := dbus.SessionBusPrivate() if err != nil { return nil, UnsupportedPlatformError{err} @@ -139,7 +139,7 @@ func InitPortalPlugin() (Plugin, error) { return nil, errors.New("keyboard or pointer access denied") } cleanupBus = false - return &portalPlugin{bus: bus, remoteDesktop: remoteDesktop, + return &portalBackend{bus: bus, remoteDesktop: remoteDesktop, sessionHandle: sessionHandle}, nil } @@ -171,7 +171,7 @@ func getResponse(bus *dbus.Conn, object dbus.BusObject, method string, } } -func (p *portalPlugin) Close() error { +func (p *portalBackend) Close() error { p.lock.Lock() defer p.lock.Unlock() if p.bus == nil { @@ -185,7 +185,7 @@ func (p *portalPlugin) Close() error { return nil } -func (p *portalPlugin) keyboardKeys(keys []Keysym) error { +func (p *portalBackend) keyboardKeys(keys []Keysym) error { p.lock.RLock() defer p.lock.RUnlock() if p.bus == nil { @@ -204,7 +204,7 @@ func (p *portalPlugin) keyboardKeys(keys []Keysym) error { return nil } -func (p *portalPlugin) KeyboardText(text string) error { +func (p *portalBackend) KeyboardText(text string) error { keys := make([]Keysym, 0, len(text)) for _, runeValue := range text { keysym, err := RuneToKeysym(runeValue) @@ -216,7 +216,7 @@ func (p *portalPlugin) KeyboardText(text string) error { return p.keyboardKeys(keys) } -func (p *portalPlugin) KeyboardKey(key Key) error { +func (p *portalBackend) KeyboardKey(key Key) error { keysym, err := KeyToKeysym(key) if err != nil { return err @@ -225,7 +225,7 @@ func (p *portalPlugin) KeyboardKey(key Key) error { return p.keyboardKeys(keys[:]) } -func (p *portalPlugin) PointerButton(button PointerButton, press bool) error { +func (p *portalBackend) PointerButton(button PointerButton, press bool) error { p.lock.RLock() defer p.lock.RUnlock() if p.bus == nil { @@ -253,7 +253,7 @@ func (p *portalPlugin) PointerButton(button PointerButton, press bool) error { return nil } -func (p *portalPlugin) PointerMove(deltaX, deltaY int) error { +func (p *portalBackend) PointerMove(deltaX, deltaY int) error { p.lock.RLock() defer p.lock.RUnlock() if p.bus == nil { @@ -267,7 +267,7 @@ func (p *portalPlugin) PointerMove(deltaX, deltaY int) error { return nil } -func (p *portalPlugin) pointerScrollFull(deltaHorizontal, deltaVertical int, finish bool) error { +func (p *portalBackend) pointerScrollFull(deltaHorizontal, deltaVertical int, finish bool) error { p.lock.RLock() defer p.lock.RUnlock() if p.bus == nil { @@ -282,10 +282,10 @@ func (p *portalPlugin) pointerScrollFull(deltaHorizontal, deltaVertical int, fin return nil } -func (p *portalPlugin) PointerScroll(deltaHorizontal, deltaVertical int) error { +func (p *portalBackend) PointerScroll(deltaHorizontal, deltaVertical int) error { return p.pointerScrollFull(deltaHorizontal, deltaVertical, false) } -func (p *portalPlugin) PointerScrollFinish() error { +func (p *portalBackend) PointerScrollFinish() error { return p.pointerScrollFull(0, 0, true) } diff --git a/plugin_portal_disabled.go b/backend_portal_disabled.go similarity index 95% rename from plugin_portal_disabled.go rename to backend_portal_disabled.go index 9148781..31a8e59 100644 --- a/plugin_portal_disabled.go +++ b/backend_portal_disabled.go @@ -23,6 +23,6 @@ package main import "errors" -func InitPortalPlugin() (Plugin, error) { +func InitPortalBackend() (Backend, error) { return nil, UnsupportedPlatformError{errors.New("disabled")} } diff --git a/plugin_windows.go b/backend_windows.go similarity index 89% rename from plugin_windows.go rename to backend_windows.go index ec432b8..99812a2 100644 --- a/plugin_windows.go +++ b/backend_windows.go @@ -77,21 +77,21 @@ type keybdInput struct { padding [8]byte } -type windowsPlugin struct{} +type windowsBackend struct{} -func InitWindowsPlugin() (Plugin, error) { - p := &windowsPlugin{} +func InitWindowsBackend() (Backend, error) { + p := &windowsBackend{} if err := sendInputProc.Find(); err != nil { return nil, UnsupportedPlatformError{err} } return p, nil } -func (p *windowsPlugin) Close() error { +func (p *windowsBackend) Close() error { return nil } -func (p *windowsPlugin) sendInput(inputs []keybdInput) error { +func (p *windowsBackend) sendInput(inputs []keybdInput) error { if len(inputs) == 0 { return nil } @@ -103,7 +103,7 @@ func (p *windowsPlugin) sendInput(inputs []keybdInput) error { return nil } -func (p *windowsPlugin) KeyboardText(text string) error { +func (p *windowsBackend) KeyboardText(text string) error { inputs := make([]keybdInput, 0, len(text)*2) for _, runeValue := range text { in := keybdInput{typ: inputKeyboard, wScan: uint16(runeValue), dwFlags: keyeventfUnicode} @@ -117,7 +117,7 @@ func (p *windowsPlugin) KeyboardText(text string) error { return p.sendInput(inputs) } -func (p *windowsPlugin) KeyboardKey(key Key) error { +func (p *windowsBackend) KeyboardKey(key Key) error { input := keybdInput{typ: inputKeyboard} if key == KeyVolumeMute { input.wVk = vkVolumeMute @@ -139,7 +139,7 @@ func (p *windowsPlugin) KeyboardKey(key Key) error { return p.sendInput(inputs[:]) } -func (p *windowsPlugin) PointerButton(button PointerButton, press bool) error { +func (p *windowsBackend) PointerButton(button PointerButton, press bool) error { input := mouseInput{typ: inputMouse} if button == PointerButtonLeft && press { input.dwFlags = mouseeventfLeftdown @@ -163,7 +163,7 @@ func (p *windowsPlugin) PointerButton(button PointerButton, press bool) error { return nil } -func (p *windowsPlugin) PointerMove(deltaX, deltaY int) error { +func (p *windowsBackend) PointerMove(deltaX, deltaY int) error { input := mouseInput{ typ: inputMouse, dx: int32(deltaX), @@ -177,7 +177,7 @@ func (p *windowsPlugin) PointerMove(deltaX, deltaY int) error { return nil } -func (p *windowsPlugin) PointerScroll(deltaHorizontal, deltaVertical int) error { +func (p *windowsBackend) PointerScroll(deltaHorizontal, deltaVertical int) error { inputs := make([]mouseInput, 0, 2) if deltaHorizontal != 0 { inputs = append(inputs, mouseInput{ @@ -204,6 +204,6 @@ func (p *windowsPlugin) PointerScroll(deltaHorizontal, deltaVertical int) error return nil } -func (p *windowsPlugin) PointerScrollFinish() error { +func (p *windowsBackend) PointerScrollFinish() error { return nil } diff --git a/plugin_windows_disabled.go b/backend_windows_disabled.go similarity index 95% rename from plugin_windows_disabled.go rename to backend_windows_disabled.go index dae0dbe..8e9da2f 100644 --- a/plugin_windows_disabled.go +++ b/backend_windows_disabled.go @@ -23,6 +23,6 @@ package main import "errors" -func InitWindowsPlugin() (Plugin, error) { +func InitWindowsBackend() (Backend, error) { return nil, UnsupportedPlatformError{errors.New("disabled")} } diff --git a/plugin_x11.go b/backend_x11.go similarity index 89% rename from plugin_x11.go rename to backend_x11.go index edbc063..9fa0b34 100644 --- a/plugin_x11.go +++ b/backend_x11.go @@ -44,13 +44,13 @@ const ( var modifierIndices [6]uint = [...]uint{C.ShiftMapIndex, C.Mod1MapIndex, C.Mod2MapIndex, C.Mod3MapIndex, C.Mod4MapIndex, C.Mod5MapIndex} -type x11Plugin struct { +type x11Backend struct { display *C.Display lock sync.Mutex scrollHorizontal, scrollVertical int } -func InitX11Plugin() (Plugin, error) { +func InitX11Backend() (Backend, error) { sessionType := os.Getenv("XDG_SESSION_TYPE") if sessionType != "" && sessionType != "x11" { return nil, UnsupportedPlatformError{errors.New(fmt.Sprintf( @@ -61,10 +61,10 @@ func InitX11Plugin() (Plugin, error) { return nil, UnsupportedPlatformError{ errors.New("failed to connect to X server")} } - return &x11Plugin{display: display}, nil + return &x11Backend{display: display}, nil } -func (p *x11Plugin) Close() error { +func (p *x11Backend) Close() error { p.lock.Lock() defer p.lock.Unlock() if p.display == nil { @@ -75,7 +75,7 @@ func (p *x11Plugin) Close() error { return nil } -func (p *x11Plugin) findEmptyKeycodeLocked() (C.KeyCode, C.int, error) { +func (p *x11Backend) findEmptyKeycodeLocked() (C.KeyCode, C.int, error) { var minKeycodes, maxKeycodes C.int C.XDisplayKeycodes(p.display, &minKeycodes, &maxKeycodes) var keysymsPerKeycode C.int @@ -101,7 +101,7 @@ keycodes: return 0, 0, errors.New("no empty keycode found") } -func (p *x11Plugin) changeKeyMappingLocked(keysymsPerKeycode C.int, +func (p *x11Backend) changeKeyMappingLocked(keysymsPerKeycode C.int, keycode C.KeyCode, keysym Keysym) { keycodeMapping := make([]C.KeySym, keysymsPerKeycode) for i := range keycodeMapping { @@ -112,7 +112,7 @@ func (p *x11Plugin) changeKeyMappingLocked(keysymsPerKeycode C.int, C.XFlush(p.display) } -func (p *x11Plugin) getModKeycodesLocked() map[uint]C.KeyCode { +func (p *x11Backend) getModKeycodesLocked() map[uint]C.KeyCode { modKeymap := C.XGetModifierMapping(p.display) defer C.XFreeModifiermap(modKeymap) modKeycodes := make(map[uint]C.KeyCode) @@ -129,7 +129,7 @@ func (p *x11Plugin) getModKeycodesLocked() map[uint]C.KeyCode { return modKeycodes } -func (p *x11Plugin) findKeycodeLocked(keyboard C.XkbDescPtr, +func (p *x11Backend) findKeycodeLocked(keyboard C.XkbDescPtr, modKeycodes map[uint]C.KeyCode, activeMods C.uint, keysym Keysym) (C.KeyCode, C.uint) { keycode := C.XKeysymToKeycode(p.display, C.KeySym(keysym)) @@ -165,7 +165,7 @@ func (p *x11Plugin) findKeycodeLocked(keyboard C.XkbDescPtr, return 0, 0 } -func (p *x11Plugin) sendModsLocked(modKeycodes map[uint]C.KeyCode, mods C.uint, +func (p *x11Backend) sendModsLocked(modKeycodes map[uint]C.KeyCode, mods C.uint, press bool) { var pressC C.int = C.False if press { @@ -178,7 +178,7 @@ func (p *x11Plugin) sendModsLocked(modKeycodes map[uint]C.KeyCode, mods C.uint, } } -func (p *x11Plugin) keyboardKeys(keys []Keysym) error { +func (p *x11Backend) keyboardKeys(keys []Keysym) error { p.lock.Lock() defer p.lock.Unlock() if p.display == nil { @@ -236,7 +236,7 @@ func (p *x11Plugin) keyboardKeys(keys []Keysym) error { return nil } -func (p *x11Plugin) KeyboardText(text string) error { +func (p *x11Backend) KeyboardText(text string) error { keys := make([]Keysym, 0, len(text)) for _, runeValue := range text { keysym, err := RuneToKeysym(runeValue) @@ -248,7 +248,7 @@ func (p *x11Plugin) KeyboardText(text string) error { return p.keyboardKeys(keys) } -func (p *x11Plugin) KeyboardKey(key Key) error { +func (p *x11Backend) KeyboardKey(key Key) error { keysym, err := KeyToKeysym(key) if err != nil { return err @@ -257,7 +257,7 @@ func (p *x11Plugin) KeyboardKey(key Key) error { return p.keyboardKeys(keys[:]) } -func (p *x11Plugin) sendButton(button uint, press bool) error { +func (p *x11Backend) sendButton(button uint, press bool) error { p.lock.Lock() defer p.lock.Unlock() if p.display == nil { @@ -275,7 +275,7 @@ func (p *x11Plugin) sendButton(button uint, press bool) error { return nil } -func (p *x11Plugin) PointerButton(button PointerButton, press bool) error { +func (p *x11Backend) PointerButton(button PointerButton, press bool) error { if button == PointerButtonLeft { return p.sendButton(1, press) } @@ -288,7 +288,7 @@ func (p *x11Plugin) PointerButton(button PointerButton, press bool) error { return errors.New("unsupported pointer button") } -func (p *x11Plugin) PointerMove(deltaX, deltaY int) error { +func (p *x11Backend) PointerMove(deltaX, deltaY int) error { p.lock.Lock() defer p.lock.Unlock() if p.display == nil { @@ -299,7 +299,7 @@ func (p *x11Plugin) PointerMove(deltaX, deltaY int) error { return nil } -func (p *x11Plugin) PointerScroll(deltaHorizontal, deltaVertical int) error { +func (p *x11Backend) PointerScroll(deltaHorizontal, deltaVertical int) error { p.lock.Lock() stepsHorizontal := (p.scrollHorizontal + deltaHorizontal) / scrollDiv stepsVertical := (p.scrollVertical + deltaVertical) / scrollDiv @@ -335,7 +335,7 @@ func (p *x11Plugin) PointerScroll(deltaHorizontal, deltaVertical int) error { return nil } -func (p *x11Plugin) PointerScrollFinish() error { +func (p *x11Backend) PointerScrollFinish() error { p.lock.Lock() defer p.lock.Unlock() p.scrollHorizontal = 0 diff --git a/plugin_x11_disabled.go b/backend_x11_disabled.go similarity index 95% rename from plugin_x11_disabled.go rename to backend_x11_disabled.go index 9b41d2e..dbc894d 100644 --- a/plugin_x11_disabled.go +++ b/backend_x11_disabled.go @@ -23,6 +23,6 @@ package main import "errors" -func InitX11Plugin() (Plugin, error) { +func InitX11Backend() (Backend, error) { return nil, UnsupportedPlatformError{errors.New("disabled")} } diff --git a/main.go b/main.go index 5e83eee..10877e9 100644 --- a/main.go +++ b/main.go @@ -48,12 +48,12 @@ const ( version string = "0.0.10" ) -func processCommand(plugin Plugin, command string) error { +func processCommand(backend Backend, command string) error { if len(command) == 0 { return errors.New("empty command") } if command == "sf" { - return plugin.PointerScrollFinish() + return backend.PointerScrollFinish() } if command[0] == 't' { text := command[1:] @@ -63,7 +63,7 @@ func processCommand(plugin Plugin, command string) error { if !utf8.ValidString(text) { return errors.New("invalid utf-8") } - return plugin.KeyboardText(text) + return backend.KeyboardText(text) } arguments := strings.Split(command[1:], ";") if command[0] == 'k' && len(arguments) != 1 || @@ -78,17 +78,17 @@ func processCommand(plugin Plugin, command string) error { if x < 0 || x >= int64(KeyLimit) { return errors.New("unsupported key") } - return plugin.KeyboardKey(Key(x)) + return backend.KeyboardKey(Key(x)) } y, err := strconv.ParseInt(arguments[1], 10, 32) if err != nil { return err } if command[0] == 'm' { - return plugin.PointerMove(int(x), int(y)) + return backend.PointerMove(int(x), int(y)) } if command[0] == 's' { - return plugin.PointerScroll(int(x), int(y)) + return backend.PointerScroll(int(x), int(y)) } if command[0] == 'b' { if x < 0 || x >= int64(PointerButtonLimit) { @@ -98,7 +98,7 @@ func processCommand(plugin Plugin, command string) error { if y == 0 { b = false } - return plugin.PointerButton(PointerButton(x), b) + return backend.PointerButton(PointerButton(x), b) } return errors.New("unsupported command") } @@ -171,25 +171,25 @@ func main() { if secret == "" { secret = secureRandBase64(defaultSecretLength) } - var plugin Plugin - var pluginName string + var backend Backend + var backendName string platformErrors := "" - for _, pluginInfo := range Plugins { - pluginName = pluginInfo.Name + for _, backendInfo := range Backends { + backendName = backendInfo.Name var err error - plugin, err = pluginInfo.Init() + backend, err = backendInfo.Init() if err == nil { break } else if _, ok := err.(UnsupportedPlatformError); ok { - platformErrors += fmt.Sprintf("%s plugin: %v\n", pluginName, err) + platformErrors += fmt.Sprintf("%s backend: %v\n", backendName, err) } else { - log.Fatal(fmt.Sprintf("%s plugin: %v", pluginName, err)) + log.Fatal(fmt.Sprintf("%s backend: %v", backendName, err)) } } - if plugin == nil { + if backend == nil { log.Fatal("unsupported platform:\n" + platformErrors) } - defer plugin.Close() + defer backend.Close() authenticationChallenges := make(chan challenge, authenticationRateBurst) go authenticationChallengeGenerator(secret, authenticationChallenges) listener, err := net.Listen("tcp", bind) @@ -228,8 +228,8 @@ func main() { if err := websocket.Message.Receive(ws, &message); err != nil { return } - if err := processCommand(plugin, message); err != nil { - log.Print(fmt.Sprintf("%s plugin: %v", pluginName, err)) + if err := processCommand(backend, message); err != nil { + log.Print(fmt.Sprintf("%s backend: %v", backendName, err)) return } } From 2acdaf572d43621e557c3c1437197b17b50330cf Mon Sep 17 00:00:00 2001 From: Unrud Date: Sat, 20 Oct 2018 04:25:54 +0200 Subject: [PATCH 007/258] Flatpak: Use correct names for icon, desktop and appdata without renaming --- ...> com.github.unrud.RemoteTouchpad.appdata.xml} | 9 +++++---- ...op => com.github.unrud.RemoteTouchpad.desktop} | 2 +- flatpak/com.github.unrud.RemoteTouchpad.json | 15 ++++++--------- 3 files changed, 12 insertions(+), 14 deletions(-) rename desktop/{remote-touchpad.appdata.xml => com.github.unrud.RemoteTouchpad.appdata.xml} (91%) rename desktop/{remote-touchpad.desktop => com.github.unrud.RemoteTouchpad.desktop} (85%) diff --git a/desktop/remote-touchpad.appdata.xml b/desktop/com.github.unrud.RemoteTouchpad.appdata.xml similarity index 91% rename from desktop/remote-touchpad.appdata.xml rename to desktop/com.github.unrud.RemoteTouchpad.appdata.xml index e226cf6..273fbd1 100644 --- a/desktop/remote-touchpad.appdata.xml +++ b/desktop/com.github.unrud.RemoteTouchpad.appdata.xml @@ -1,6 +1,6 @@ - - remote-touchpad.desktop + + com.github.unrud.RemoteTouchpad CC0-1.0 GPL-3.0-or-later Remote Touchpad @@ -14,6 +14,7 @@ Supports Flatpak's RemoteDesktop portal (experimental), Windows and X11.

    + com.github.unrud.RemoteTouchpad.desktop https://github.com/Unrud/remote-touchpad/issues https://github.com/Unrud/remote-touchpad Unrud @@ -43,7 +44,7 @@
  • use colors in terminal for QR qode
  • remove -invert command line argument
  • mitigate race condition when typing text on X11
  • -
  • improve KeySyms used for text on X11 and Flatpak's RemoteDesktop portal
  • +
  • improve KeySyms used for text on X11 and Flatpak's RemoteDesktop portal
  • normalize line endings
@@ -89,5 +90,5 @@ https://raw.githubusercontent.com/Unrud/remote-touchpad/0.0.10/screenshots/4.png - + diff --git a/desktop/remote-touchpad.desktop b/desktop/com.github.unrud.RemoteTouchpad.desktop similarity index 85% rename from desktop/remote-touchpad.desktop rename to desktop/com.github.unrud.RemoteTouchpad.desktop index 7924c12..774441d 100644 --- a/desktop/remote-touchpad.desktop +++ b/desktop/com.github.unrud.RemoteTouchpad.desktop @@ -5,5 +5,5 @@ Name=Remote Touchpad Comment=Control mouse and keyboard from a smartphone Terminal=true Exec=remote-touchpad-wait-on-error -Icon=remote-touchpad +Icon=com.github.unrud.RemoteTouchpad Categories=Network;RemoteAccess;ConsoleOnly; diff --git a/flatpak/com.github.unrud.RemoteTouchpad.json b/flatpak/com.github.unrud.RemoteTouchpad.json index d768c65..73316ce 100644 --- a/flatpak/com.github.unrud.RemoteTouchpad.json +++ b/flatpak/com.github.unrud.RemoteTouchpad.json @@ -4,9 +4,6 @@ "runtime-version" : "18.08", "sdk" : "org.freedesktop.Sdk", "command" : "remote-touchpad", - "rename-appdata-file" : "remote-touchpad.appdata.xml", - "rename-desktop-file" : "remote-touchpad.desktop", - "rename-icon" : "remote-touchpad", "sdk-extensions" : [ "org.freedesktop.Sdk.Extension.golang" ], @@ -54,12 +51,12 @@ ". /usr/lib/sdk/golang/enable.sh; env GOPATH=\"$(pwd)\" go build -tags 'portal x11' github.com/unrud/remote-touchpad", "install -Dm0755 -t /app/bin remote-touchpad", "install -Dm0755 -t /app/bin src/github.com/unrud/remote-touchpad/desktop/remote-touchpad-wait-on-error", - "install -Dm0644 -t /app/share/appdata src/github.com/unrud/remote-touchpad/desktop/remote-touchpad.appdata.xml", - "install -Dm0644 -t /app/share/applications src/github.com/unrud/remote-touchpad/desktop/remote-touchpad.desktop", - "install -Dm0644 src/github.com/unrud/remote-touchpad/desktop/remote-touchpad_64.png /app/share/icons/hicolor/64x64/apps/remote-touchpad.png", - "install -Dm0644 src/github.com/unrud/remote-touchpad/desktop/remote-touchpad_128.png /app/share/icons/hicolor/128x128/apps/remote-touchpad.png", - "install -Dm0644 src/github.com/unrud/remote-touchpad/desktop/remote-touchpad_256.png /app/share/icons/hicolor/256x256/apps/remote-touchpad.png", - "install -Dm0644 src/github.com/unrud/remote-touchpad/desktop/remote-touchpad_512.png /app/share/icons/hicolor/512x512/apps/remote-touchpad.png" + "install -Dm0644 -t /app/share/appdata src/github.com/unrud/remote-touchpad/desktop/com.github.unrud.RemoteTouchpad.appdata.xml", + "install -Dm0644 -t /app/share/applications src/github.com/unrud/remote-touchpad/desktop/com.github.unrud.RemoteTouchpad.desktop", + "install -Dm0644 src/github.com/unrud/remote-touchpad/desktop/remote-touchpad_64.png /app/share/icons/hicolor/64x64/apps/com.github.unrud.RemoteTouchpad.png", + "install -Dm0644 src/github.com/unrud/remote-touchpad/desktop/remote-touchpad_128.png /app/share/icons/hicolor/128x128/apps/com.github.unrud.RemoteTouchpad.png", + "install -Dm0644 src/github.com/unrud/remote-touchpad/desktop/remote-touchpad_256.png /app/share/icons/hicolor/256x256/apps/com.github.unrud.RemoteTouchpad.png", + "install -Dm0644 src/github.com/unrud/remote-touchpad/desktop/remote-touchpad_512.png /app/share/icons/hicolor/512x512/apps/com.github.unrud.RemoteTouchpad.png" ] } ] From 56add5f796dd0964ebe0bbc41f8635905a9e0bbf Mon Sep 17 00:00:00 2001 From: Unrud Date: Sat, 20 Oct 2018 04:25:55 +0200 Subject: [PATCH 008/258] Flatpak: update dependencies --- flatpak/com.github.unrud.RemoteTouchpad.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flatpak/com.github.unrud.RemoteTouchpad.json b/flatpak/com.github.unrud.RemoteTouchpad.json index 73316ce..a8377f4 100644 --- a/flatpak/com.github.unrud.RemoteTouchpad.json +++ b/flatpak/com.github.unrud.RemoteTouchpad.json @@ -18,7 +18,7 @@ { "type" : "git", "url" : "https://github.com/golang/net", - "commit" : "49bb7cea24b1df9410e1712aa6433dae904ff66a", + "commit" : "04a2e542c03f1d053ab3e4d6e5abcd4b66e2be8e", "dest" : "src/golang.org/x/net" }, { From 235f6efbac463aa78e775f3d09dd2cfd5132a65f Mon Sep 17 00:00:00 2001 From: Unrud Date: Sat, 20 Oct 2018 04:25:55 +0200 Subject: [PATCH 009/258] bump verstion to 0.0.11 --- CHANGELOG.md | 5 +++++ .../com.github.unrud.RemoteTouchpad.appdata.xml | 14 ++++++++++---- main.go | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dad3ace..d52ac42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 0.0.11 (2018-10-20) + + * rename plugin to backend + * update flatpak + ## 0.0.10 (2018-10-01) * avoid race condition when typing on X11 diff --git a/desktop/com.github.unrud.RemoteTouchpad.appdata.xml b/desktop/com.github.unrud.RemoteTouchpad.appdata.xml index 273fbd1..b51b1dd 100644 --- a/desktop/com.github.unrud.RemoteTouchpad.appdata.xml +++ b/desktop/com.github.unrud.RemoteTouchpad.appdata.xml @@ -19,6 +19,12 @@ https://github.com/Unrud/remote-touchpad Unrud + +​
    +
  • rename plugin to backend
  • +
  • update flatpak
  • +
+