Repository: XX-net/XX-Net Branch: master Commit: 43aec6ff8883 Files: 537 Total size: 6.9 MB Directory structure: gitextract_v3hvtkza/ ├── .github/ │ ├── ISSUE_TEMPLATE.md │ ├── SECURITY.md │ └── workflows/ │ ├── lint_python.yml │ └── notify_aur_upgrade.yml ├── .gitignore ├── README.md ├── SwitchyOmega/ │ ├── OmegaOptions.bak │ └── download SwitchyOmega for Chromium & Firefox.url ├── code/ │ ├── app_info.json │ └── default/ │ ├── LICENSE.txt │ ├── babel_update.py │ ├── download.md │ ├── gae_proxy/ │ │ ├── __init__.py │ │ ├── babel.config │ │ ├── lang/ │ │ │ ├── de_DE/ │ │ │ │ └── LC_MESSAGES/ │ │ │ │ └── messages.po │ │ │ ├── es_VE/ │ │ │ │ └── LC_MESSAGES/ │ │ │ │ └── messages.po │ │ │ ├── fa_IR/ │ │ │ │ └── LC_MESSAGES/ │ │ │ │ └── messages.po │ │ │ ├── ja_JP/ │ │ │ │ └── LC_MESSAGES/ │ │ │ │ └── messages.po │ │ │ └── zh_CN/ │ │ │ └── LC_MESSAGES/ │ │ │ └── messages.po │ │ ├── local/ │ │ │ ├── __init__.py │ │ │ ├── apis.py │ │ │ ├── appid_manager.py │ │ │ ├── appids.txt │ │ │ ├── cacert.pem │ │ │ ├── cert_util.py │ │ │ ├── check_ip.py │ │ │ ├── check_local_network.py │ │ │ ├── config.py │ │ │ ├── direct_handler.py │ │ │ ├── download_gae_lib.py │ │ │ ├── front.py │ │ │ ├── gae_handler.py │ │ │ ├── host_manager.py │ │ │ ├── http2_connection.py │ │ │ ├── ip_list.txt │ │ │ ├── ip_range.old │ │ │ ├── ip_range.txt │ │ │ ├── ipv6_list.txt │ │ │ ├── ipv6_tunnel/ │ │ │ │ ├── IPV6_note.TXT │ │ │ │ ├── __init__.py │ │ │ │ ├── common.py │ │ │ │ ├── darwin.py │ │ │ │ ├── disable_ipv6.bat │ │ │ │ ├── enable_ipv6.bat │ │ │ │ ├── linux.py │ │ │ │ ├── pteredor.py │ │ │ │ ├── unknown.py │ │ │ │ ├── win10.py │ │ │ │ ├── win32runas.py │ │ │ │ └── win_reset_gp.py │ │ │ ├── proxy.py │ │ │ ├── proxy_handler.py │ │ │ ├── sni_manager.py │ │ │ ├── sni_slice.txt │ │ │ └── web_control.py │ │ ├── server/ │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ └── gae/ │ │ │ ├── .gcloudignore │ │ │ ├── app.yaml │ │ │ ├── gunicorn.conf.py │ │ │ ├── main.py │ │ │ └── requirements.txt │ │ ├── tests/ │ │ │ └── test_protocol.py │ │ └── web_ui/ │ │ ├── advanced.html │ │ ├── check_ip.html │ │ ├── config.html │ │ ├── deploy.html │ │ ├── export_ip.html │ │ ├── global_setting.html │ │ ├── import_ip.html │ │ ├── ipv6_tunnel.html │ │ ├── logging.html │ │ ├── menu.json │ │ ├── scan_setting.html │ │ └── status.html │ ├── launcher/ │ │ ├── __init__.py │ │ ├── autorun.py │ │ ├── babel.config │ │ ├── config.py │ │ ├── create_shortcut.js │ │ ├── download.vbs │ │ ├── download_modules.py │ │ ├── global_var.py │ │ ├── gtk_tray.py │ │ ├── lang/ │ │ │ ├── fa_IR/ │ │ │ │ └── LC_MESSAGES/ │ │ │ │ └── messages.po │ │ │ ├── ru_RU/ │ │ │ │ └── LC_MESSAGES/ │ │ │ │ └── messages.po │ │ │ └── zh_CN/ │ │ │ └── LC_MESSAGES/ │ │ │ └── messages.po │ │ ├── mac_helper │ │ ├── mac_helper.c │ │ ├── mac_tray.py │ │ ├── module_init.py │ │ ├── non_tray.py │ │ ├── post_update.py │ │ ├── setup.py │ │ ├── simple_i18n.py │ │ ├── start.py │ │ ├── sys_platform.py │ │ ├── tests/ │ │ │ ├── integrate_testing.py │ │ │ ├── test_update.py │ │ │ ├── test_web_api.py │ │ │ ├── test_win_port_reserve.py │ │ │ ├── try_run.py │ │ │ └── try_smartroute_sock4.py │ │ ├── unzip.vbs │ │ ├── update.py │ │ ├── update_from_github.py │ │ ├── web_control.py │ │ ├── web_ui/ │ │ │ ├── about.html │ │ │ ├── config.html │ │ │ ├── config_applist.html │ │ │ ├── config_general.html │ │ │ ├── config_proxy.html │ │ │ ├── config_update.html │ │ │ ├── css/ │ │ │ │ ├── bootstrap-responsive.css │ │ │ │ ├── bootstrap.css │ │ │ │ ├── flat-ui.css │ │ │ │ ├── primer-markdown.css │ │ │ │ └── style.css │ │ │ ├── index.html │ │ │ ├── js/ │ │ │ │ ├── flat-ui.js │ │ │ │ ├── jquery.timer.js │ │ │ │ └── site.js │ │ │ ├── logging.html │ │ │ ├── menu.json │ │ │ └── status.html │ │ ├── win_compat_suggest.py │ │ └── win_tray.py │ ├── lib/ │ │ ├── noarch/ │ │ │ ├── asn1crypto/ │ │ │ │ ├── __init__.py │ │ │ │ ├── _errors.py │ │ │ │ ├── _inet.py │ │ │ │ ├── _int.py │ │ │ │ ├── _iri.py │ │ │ │ ├── _ordereddict.py │ │ │ │ ├── _teletex_codec.py │ │ │ │ ├── _types.py │ │ │ │ ├── algos.py │ │ │ │ ├── cms.py │ │ │ │ ├── core.py │ │ │ │ ├── crl.py │ │ │ │ ├── csr.py │ │ │ │ ├── keys.py │ │ │ │ ├── ocsp.py │ │ │ │ ├── parser.py │ │ │ │ ├── pdf.py │ │ │ │ ├── pem.py │ │ │ │ ├── pkcs12.py │ │ │ │ ├── tsp.py │ │ │ │ ├── util.py │ │ │ │ ├── version.py │ │ │ │ └── x509.py │ │ │ ├── dnslib/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bimap.py │ │ │ │ ├── bit.py │ │ │ │ ├── buffer.py │ │ │ │ ├── client.py │ │ │ │ ├── dns.py │ │ │ │ ├── fixedresolver.py │ │ │ │ ├── intercept.py │ │ │ │ ├── label.py │ │ │ │ ├── lex.py │ │ │ │ ├── proxy.py │ │ │ │ ├── ranges.py │ │ │ │ ├── server.py │ │ │ │ ├── shellresolver.py │ │ │ │ └── zoneresolver.py │ │ │ ├── ecdsa/ │ │ │ │ ├── __init__.py │ │ │ │ ├── _compat.py │ │ │ │ ├── _rwlock.py │ │ │ │ ├── _sha3.py │ │ │ │ ├── _version.py │ │ │ │ ├── curves.py │ │ │ │ ├── der.py │ │ │ │ ├── ecdh.py │ │ │ │ ├── ecdsa.py │ │ │ │ ├── eddsa.py │ │ │ │ ├── ellipticcurve.py │ │ │ │ ├── errors.py │ │ │ │ ├── keys.py │ │ │ │ ├── numbertheory.py │ │ │ │ ├── rfc6979.py │ │ │ │ └── util.py │ │ │ ├── encrypt.py │ │ │ ├── env_info.py │ │ │ ├── front_base/ │ │ │ │ ├── __init__.py │ │ │ │ ├── boringssl_wrap.py │ │ │ │ ├── check_ip.py │ │ │ │ ├── config.py │ │ │ │ ├── connect_creator.py │ │ │ │ ├── connect_manager.py │ │ │ │ ├── domain_manager.py │ │ │ │ ├── host_manager.py │ │ │ │ ├── http1.py │ │ │ │ ├── http2_connection.py │ │ │ │ ├── http2_stream.py │ │ │ │ ├── http_common.py │ │ │ │ ├── http_dispatcher.py │ │ │ │ ├── ip_manager.py │ │ │ │ ├── ip_source.py │ │ │ │ ├── openssl_wrap.py │ │ │ │ ├── pyopenssl_wrap.py │ │ │ │ ├── random_get_slice.py │ │ │ │ ├── ssl_wrap.py │ │ │ │ └── tlslite_wrap.py │ │ │ ├── hyper/ │ │ │ │ ├── __init__.py │ │ │ │ ├── certs.pem │ │ │ │ ├── cli.py │ │ │ │ ├── common/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── bufsocket.py │ │ │ │ │ ├── connection.py │ │ │ │ │ ├── decoder.py │ │ │ │ │ ├── exceptions.py │ │ │ │ │ ├── headers.py │ │ │ │ │ └── util.py │ │ │ │ ├── compat.py │ │ │ │ ├── contrib.py │ │ │ │ ├── http11/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── connection.py │ │ │ │ │ ├── parser.py │ │ │ │ │ └── response.py │ │ │ │ ├── http20/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── connection.py │ │ │ │ │ ├── errors.py │ │ │ │ │ ├── exceptions.py │ │ │ │ │ ├── response.py │ │ │ │ │ ├── stream.py │ │ │ │ │ ├── util.py │ │ │ │ │ └── window.py │ │ │ │ ├── httplib_compat.py │ │ │ │ ├── packages/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── hpack/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── compat.py │ │ │ │ │ │ ├── exceptions.py │ │ │ │ │ │ ├── hpack.py │ │ │ │ │ │ ├── hpack_compat.py │ │ │ │ │ │ ├── huffman.py │ │ │ │ │ │ ├── huffman_constants.py │ │ │ │ │ │ ├── huffman_table.py │ │ │ │ │ │ ├── struct.py │ │ │ │ │ │ └── table.py │ │ │ │ │ ├── hyperframe/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── flags.py │ │ │ │ │ │ └── frame.py │ │ │ │ │ └── rfc3986/ │ │ │ │ │ ├── LICENSE │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── api.py │ │ │ │ │ ├── compat.py │ │ │ │ │ ├── exceptions.py │ │ │ │ │ ├── misc.py │ │ │ │ │ ├── normalizers.py │ │ │ │ │ ├── parseresult.py │ │ │ │ │ └── uri.py │ │ │ │ ├── ssl_compat.py │ │ │ │ └── tls.py │ │ │ ├── idna/ │ │ │ │ ├── __init__.py │ │ │ │ ├── codec.py │ │ │ │ ├── compat.py │ │ │ │ ├── core.py │ │ │ │ ├── idnadata.py │ │ │ │ ├── intranges.py │ │ │ │ └── uts46data.py │ │ │ ├── lru_cache.py │ │ │ ├── os_platform.py │ │ │ ├── pyasn1/ │ │ │ │ ├── __init__.py │ │ │ │ ├── codec/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── ber/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── decoder.py │ │ │ │ │ │ ├── encoder.py │ │ │ │ │ │ └── eoo.py │ │ │ │ │ ├── cer/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── decoder.py │ │ │ │ │ │ └── encoder.py │ │ │ │ │ ├── der/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── decoder.py │ │ │ │ │ │ └── encoder.py │ │ │ │ │ └── native/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── decoder.py │ │ │ │ │ └── encoder.py │ │ │ │ ├── compat/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── binary.py │ │ │ │ │ ├── calling.py │ │ │ │ │ ├── dateandtime.py │ │ │ │ │ ├── integer.py │ │ │ │ │ ├── octets.py │ │ │ │ │ └── string.py │ │ │ │ ├── debug.py │ │ │ │ ├── error.py │ │ │ │ └── type/ │ │ │ │ ├── __init__.py │ │ │ │ ├── base.py │ │ │ │ ├── char.py │ │ │ │ ├── constraint.py │ │ │ │ ├── error.py │ │ │ │ ├── namedtype.py │ │ │ │ ├── namedval.py │ │ │ │ ├── opentype.py │ │ │ │ ├── tag.py │ │ │ │ ├── tagmap.py │ │ │ │ ├── univ.py │ │ │ │ └── useful.py │ │ │ ├── scrypto/ │ │ │ │ ├── __init__.py │ │ │ │ ├── ctypes_openssl.py │ │ │ │ ├── m2.py │ │ │ │ ├── rc4_md5.py │ │ │ │ ├── salsa20_ctr.py │ │ │ │ ├── table.py │ │ │ │ └── util.py │ │ │ ├── selectors2.py │ │ │ ├── simple_http_client.py │ │ │ ├── simple_http_server.py │ │ │ ├── simple_queue.py │ │ │ ├── six.py │ │ │ ├── socks.py │ │ │ ├── sortedcontainers/ │ │ │ │ ├── __init__.py │ │ │ │ ├── sorteddict.py │ │ │ │ ├── sortedlist.py │ │ │ │ ├── sortedlistwithkey.py │ │ │ │ └── sortedset.py │ │ │ ├── subj_alt_name.py │ │ │ ├── tlslite/ │ │ │ │ ├── __init__.py │ │ │ │ ├── api.py │ │ │ │ ├── basedb.py │ │ │ │ ├── bufferedsocket.py │ │ │ │ ├── checker.py │ │ │ │ ├── constants.py │ │ │ │ ├── defragmenter.py │ │ │ │ ├── dh.py │ │ │ │ ├── errors.py │ │ │ │ ├── extensions.py │ │ │ │ ├── handshakehashes.py │ │ │ │ ├── handshakehelpers.py │ │ │ │ ├── handshakesettings.py │ │ │ │ ├── keyexchange.py │ │ │ │ ├── mathtls.py │ │ │ │ ├── messages.py │ │ │ │ ├── messagesocket.py │ │ │ │ ├── ocsp.py │ │ │ │ ├── recordlayer.py │ │ │ │ ├── session.py │ │ │ │ ├── sessioncache.py │ │ │ │ ├── signed.py │ │ │ │ ├── tlsconnection.py │ │ │ │ ├── tlsrecordlayer.py │ │ │ │ ├── utils/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── aes.py │ │ │ │ │ ├── aesccm.py │ │ │ │ │ ├── aesgcm.py │ │ │ │ │ ├── asn1parser.py │ │ │ │ │ ├── chacha.py │ │ │ │ │ ├── chacha20_poly1305.py │ │ │ │ │ ├── cipherfactory.py │ │ │ │ │ ├── codec.py │ │ │ │ │ ├── compat.py │ │ │ │ │ ├── constanttime.py │ │ │ │ │ ├── cryptomath.py │ │ │ │ │ ├── datefuncs.py │ │ │ │ │ ├── deprecations.py │ │ │ │ │ ├── dns_utils.py │ │ │ │ │ ├── dsakey.py │ │ │ │ │ ├── ecc.py │ │ │ │ │ ├── ecdsakey.py │ │ │ │ │ ├── eddsakey.py │ │ │ │ │ ├── format_output.py │ │ │ │ │ ├── keyfactory.py │ │ │ │ │ ├── lists.py │ │ │ │ │ ├── openssl_aes.py │ │ │ │ │ ├── openssl_aesccm.py │ │ │ │ │ ├── openssl_aesgcm.py │ │ │ │ │ ├── openssl_rc4.py │ │ │ │ │ ├── openssl_rsakey.py │ │ │ │ │ ├── openssl_tripledes.py │ │ │ │ │ ├── pem.py │ │ │ │ │ ├── poly1305.py │ │ │ │ │ ├── pycrypto_aes.py │ │ │ │ │ ├── pycrypto_aesgcm.py │ │ │ │ │ ├── pycrypto_rc4.py │ │ │ │ │ ├── pycrypto_rsakey.py │ │ │ │ │ ├── pycrypto_tripledes.py │ │ │ │ │ ├── python_aes.py │ │ │ │ │ ├── python_aesccm.py │ │ │ │ │ ├── python_aesgcm.py │ │ │ │ │ ├── python_chacha20_poly1305.py │ │ │ │ │ ├── python_dsakey.py │ │ │ │ │ ├── python_ecdsakey.py │ │ │ │ │ ├── python_eddsakey.py │ │ │ │ │ ├── python_key.py │ │ │ │ │ ├── python_rc4.py │ │ │ │ │ ├── python_rsakey.py │ │ │ │ │ ├── python_tripledes.py │ │ │ │ │ ├── rc4.py │ │ │ │ │ ├── rijndael.py │ │ │ │ │ ├── rsakey.py │ │ │ │ │ ├── tackwrapper.py │ │ │ │ │ ├── tlshashlib.py │ │ │ │ │ ├── tlshmac.py │ │ │ │ │ ├── tripledes.py │ │ │ │ │ └── x25519.py │ │ │ │ ├── verifierdb.py │ │ │ │ ├── x509.py │ │ │ │ └── x509certchain.py │ │ │ ├── utils.py │ │ │ ├── xconfig.py │ │ │ ├── xlog.py │ │ │ ├── xstruct.py │ │ │ └── xx_six.py │ │ ├── tests/ │ │ │ ├── stress_boringssl.py │ │ │ ├── stress_boringssl2.py │ │ │ ├── test_http_client.py │ │ │ ├── test_http_server.py │ │ │ ├── test_queue.py │ │ │ └── test_utils.py │ │ └── win32/ │ │ ├── systray/ │ │ │ ├── __init__.py │ │ │ ├── traybar.py │ │ │ └── win32_adapter.py │ │ ├── win32_proxy_manager.py │ │ ├── win32elevate.py │ │ └── win_inet_pton.py │ ├── smart_router/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── babel.config │ │ ├── lang/ │ │ │ ├── fa_IR/ │ │ │ │ └── LC_MESSAGES/ │ │ │ │ └── messages.po │ │ │ ├── ru_RU/ │ │ │ │ └── LC_MESSAGES/ │ │ │ │ └── messages.po │ │ │ └── zh_CN/ │ │ │ └── LC_MESSAGES/ │ │ │ └── messages.po │ │ ├── local/ │ │ │ ├── __init__.py │ │ │ ├── advertisement_list.txt │ │ │ ├── apis.py │ │ │ ├── cacert-get-iprange.pem │ │ │ ├── cloudflare_cert.pem │ │ │ ├── cn_ipv4_range.txt │ │ │ ├── connect_manager.py │ │ │ ├── dns_query.py │ │ │ ├── dns_server.py │ │ │ ├── gfw_black_list.txt │ │ │ ├── gfw_white_list.txt │ │ │ ├── gfwlist.py │ │ │ ├── global_var.py │ │ │ ├── host_records.py │ │ │ ├── ip_region.py │ │ │ ├── pac_server.py │ │ │ ├── pipe_socks.py │ │ │ ├── proxy.pac │ │ │ ├── proxy_handler.py │ │ │ ├── smart_route.py │ │ │ ├── socket_wrap.py │ │ │ ├── speedtest_whitelist.txt │ │ │ ├── sr_top500_banlist.conf │ │ │ ├── user_rules.py │ │ │ └── web_control.py │ │ ├── scripts/ │ │ │ └── update_domain_list.py │ │ ├── tests/ │ │ │ ├── test_black_list.py │ │ │ ├── test_dns_query.py │ │ │ └── test_set_policy.py │ │ └── web_ui/ │ │ ├── config.html │ │ ├── config_cache.html │ │ ├── config_general.html │ │ ├── config_rules.html │ │ ├── logging.html │ │ └── menu.json │ ├── update_v5.txt │ ├── version.txt │ └── x_tunnel/ │ ├── __init__.py │ ├── babel.config │ ├── lang/ │ │ ├── fa_IR/ │ │ │ └── LC_MESSAGES/ │ │ │ └── messages.po │ │ ├── ru_RU/ │ │ │ └── LC_MESSAGES/ │ │ │ └── messages.po │ │ └── zh_CN/ │ │ └── LC_MESSAGES/ │ │ └── messages.po │ ├── local/ │ │ ├── __init__.py │ │ ├── apis.py │ │ ├── base_container.py │ │ ├── client.py │ │ ├── cloudflare_front/ │ │ │ ├── __init__.py │ │ │ ├── cacert.pem │ │ │ ├── check_ip.py │ │ │ ├── config.py │ │ │ ├── front.py │ │ │ ├── front_domains.json │ │ │ ├── good_ip.txt │ │ │ ├── http2_connection.py │ │ │ ├── ip_manager.py │ │ │ ├── ip_range.txt │ │ │ ├── ipv6_list.txt │ │ │ ├── test.py │ │ │ └── web_control.py │ │ ├── cloudfront_front/ │ │ │ ├── __init__.py │ │ │ ├── cacert.pem │ │ │ ├── check_ip.py │ │ │ ├── config.py │ │ │ ├── connect_creator.py │ │ │ ├── front.py │ │ │ ├── good_ip.txt │ │ │ ├── host_manager.py │ │ │ ├── ip_range.txt │ │ │ ├── sni_list.txt │ │ │ ├── test.py │ │ │ └── web_control.py │ │ ├── config.py │ │ ├── direct_front.py │ │ ├── front_dispatcher.py │ │ ├── gae_front.py │ │ ├── global_var.py │ │ ├── openai_handler.py │ │ ├── proxy_handler.py │ │ ├── proxy_session.py │ │ ├── seley_front/ │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── connect_creator.py │ │ │ ├── front.py │ │ │ ├── front_domains.json │ │ │ ├── ip_manager.py │ │ │ ├── rc4_wrap.py │ │ │ ├── test.py │ │ │ └── web_control.py │ │ ├── tls_relay_front/ │ │ │ ├── __init__.py │ │ │ ├── check_ip.py │ │ │ ├── config.py │ │ │ ├── connect_creator.py │ │ │ ├── front.py │ │ │ ├── host_manager.py │ │ │ ├── http2_stream.py │ │ │ ├── ip_manager.py │ │ │ ├── test.py │ │ │ └── web_control.py │ │ ├── upload_logs.py │ │ └── web_control.py │ ├── tests/ │ │ └── test_proxy.py │ └── web_ui/ │ ├── chatgpt.html │ ├── cloudflare_front_logging.html │ ├── cloudfront_front_logging.html │ ├── config.html │ ├── logging.html │ ├── menu.json │ ├── seley_front_logging.html │ ├── status.html │ └── tls_relay_front_logging.html ├── pytest.ini ├── requirements.txt ├── start ├── start.bat ├── start.vbs └── xx_net.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ # 规则: * 请不要只写标题,不写内容,请先清空或另起新行,不遵守规则的提问会被自动关闭。 * 登陆问题、602问题, 请发邮件到 xxnet.dev@gmail.com ,附上帐号,请参考: https://github.com/XX-net/XX-Net/wiki/%E5%A6%82%E4%BD%95%E6%8A%A5%E5%91%8A%E9%97%AE%E9%A2%98 * 是否查看过 [Wiki](https://github.com/XX-net/XX-Net/wiki )? * 是否以相关关键词搜索过类似 issues? * 如果问题得到解决,请务必回复相关情况,谢谢。 * 即使最终无法解决你遇到的问题,这也是正常的,因为系统和网络环境千差万别。最终结果也能帮助到后来者,请保持正常交流,再寻它法。 * 请不要只写标题,不写内容,请先清空或另起新行,不遵守规则的提问会被自动关闭。 # 提问模版: - 操作系统: - 客户端版本号: - 问题现象: - 日志文件: # 日志文件获取方法: 访问 http://localhost:8085/?module=launcher&menu=about 或进入 [系统] -> [关于] 点 收集调试信息 后面的 [下载] 按钮。 ================================================ FILE: .github/SECURITY.md ================================================ # Security Policy ## Supported Versions | Version | Supported | | ------- | ------------------ | | current stable/testing version | :white_check_mark: | | older version | :x: | ## Reporting a Vulnerability Please email xxnet.dev@gmail.com to report security issue. Normally we will response to you in one week. Thank you for your contribution. ================================================ FILE: .github/workflows/lint_python.yml ================================================ name: lint_python on: pull_request: push: branches: [test] jobs: testing_linux: runs-on: ubuntu-latest strategy: matrix: python-version: [ '3.10' ] # 3.8, 3.9, steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - run: pip install pytest # - run: pip install reorder-python-imports codespell flake8 isort # - if: matrix.python-version >= 3.6 # run: | # pip install black # black --check . || true # - run: black --diff . || true # - run: codespell --quiet-level=2 || true # --ignore-words-list="" --skip="" # - run: flake8 code --count --select=E9,F63,F7,F82 --show-source --statistics --exclude=code/default/gae_proxy/server,code/default/lib/noarch/six.py # isort and reorder-python-imports are two ways of doing the same thing # - run: isort --recursive . || true # - run: reorder-python-imports . || true - run: pip install -r requirements.txt || true - shell: bash env: XTUNNEL_USER: ${{ secrets.XTUNNEL_USER }} XTUNNEL_PASS: ${{ secrets.XTUNNEL_PASS }} PYTHONPATH: ./code/default:./code/default/lib/noarch run: | pytest -v code/default || true - name: Integrate testing shell: bash env: XTUNNEL_USER: ${{ secrets.XTUNNEL_USER }} XTUNNEL_PASS: ${{ secrets.XTUNNEL_PASS }} PYTHONPATH: ./code/default:./code/default/lib/noarch run: | python code/default/launcher/tests/integrate_testing.py testing_windows: runs-on: windows-latest strategy: matrix: python-version: [3.8, '3.10'] steps: - uses: actions/checkout@master - uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - run: pip install pytest - run: pip install -r requirements.txt || true - shell: bash env: XTUNNEL_USER: ${{ secrets.XTUNNEL_USER }} XTUNNEL_PASS: ${{ secrets.XTUNNEL_PASS }} PYTHONPATH: ./code/default:./code/default/lib/noarch run: | pytest -v code/default || true - name: Integrate testing shell: bash env: XTUNNEL_USER: ${{ secrets.XTUNNEL_USER }} XTUNNEL_PASS: ${{ secrets.XTUNNEL_PASS }} PYTHONPATH: ./code/default:./code/default/lib/noarch run: | python code/default/launcher/tests/integrate_testing.py testing_mac: runs-on: macos-latest strategy: matrix: python-version: ['3.10'] steps: - uses: actions/checkout@master - uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - run: pip install pytest - run: pip install -r requirements.txt || true - shell: bash env: XTUNNEL_USER: ${{ secrets.XTUNNEL_USER }} XTUNNEL_PASS: ${{ secrets.XTUNNEL_PASS }} PYTHONPATH: ./code/default:./code/default/lib/noarch run: | pytest -v code/default || true - name: Integrate testing shell: bash env: XTUNNEL_USER: ${{ secrets.XTUNNEL_USER }} XTUNNEL_PASS: ${{ secrets.XTUNNEL_PASS }} PYTHONPATH: ./code/default:./code/default/lib/noarch run: | python code/default/launcher/tests/integrate_testing.py ================================================ FILE: .github/workflows/notify_aur_upgrade.yml ================================================ name: notify_aur_upgrade on: push: jobs: Notify: name: Notify if: startsWith(github.ref, 'refs/tags') runs-on: ubuntu-latest steps: - run: | curl -L \ -X POST \ -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer 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"\ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/repos/lisuke/PKGBUILD/actions/workflows/xx-net.yml/dispatches \ -d '{"ref":"xx-net"}' ================================================ FILE: .gitignore ================================================ .idea /data* *~ *.pyc *.swp *.pot *.mo *.xpi *pybabel_update.sh core .DS_Store desktop.ini /SwitchyOmega/AutoProxy.xpi /SwitchyOmega/SwitchyOmega.crx /code/default/gae_proxy/server/lib/ /code/default/gae_proxy/local/ipv6_tunnel/enable_ipv6_temp.bat /code/default/gae_proxy/local/ipv6_tunnel/set_best_server_temp.bat .pytest_cache *.log code/version.txt # Babel files messages.po-e messages.pot translated.po ================================================ FILE: README.md ================================================ :rocket: XX-Net (翻墙VPN) ========= 这是一个稳健可靠的翻墙系统,已经连续运行 9 年! 我们不去研究墙有什么缺陷,因为所有的缺陷都会被慢慢的补上。 我们的策略是化身为普通流量,完全无法区分,最终隐身在茫茫的网络连接中。。。 :electric_plug: 功能特性 ========= * 支持多平台: Android/iOS/Windows/Mac/Linux * 采用独特的混淆算法,让您的流量在网络中无法被识别 * 开源绿色软件,无需安装,可以支持多台设备同时连接 * 模拟Chrome浏览器行为,完全无法识别,稳定翻墙 * 内置 ChatGPT,每个套餐赠送 ChatGPT-3.5 一百万token
### 官网下载: [https://xx-net.com](https://xx-net.com) ### Telegram: [https://t.me/xxnetshare](https://t.me/xxnetshare) ### Twitter: [https://twitter.com/XXNetDev](https://twitter.com/XXNetDev) ### ###### [中文帮助文档](https://github.com/XX-net/XX-Net/wiki/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3)      [English Document](https://github.com/XX-net/XX-Net/wiki/English-Home-Page)      [فارسی صفحه اصلی](https://github.com/XX-net/XX-Net/wiki/Persian-home-page)
### 最新公告: 2024-03-06 * 最新版5.9.10, 更新黑名单列表。 * 5.9.0 升级GAE服务端到python3 * 5.8.8 改进iOS下连接性能 * 5.7.0 为X-Tunnel增加新通道 * 5.6.0 重构代码,减少系统资源消耗 * 5.1.0,内置ChatGPT * 原来是4.x.x 老版本的,需要重新下载新版安装,不能应用内升级。
#### 提示: * 有问题请先看[Wiki文档](https://github.com/XX-net/XX-Net/wiki/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3) * [提问](https://github.com/XX-net/XX-Net/issues) 前,请先看[最近讨论主题](https://github.com/XX-net/XX-Net/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc) ,避免重复发问。 ================================================ FILE: SwitchyOmega/OmegaOptions.bak ================================================ { "+Smart-Router": {"name": "Smart-Router", "color": "#096dba", "fallbackProxy": {"host": "127.0.0.1", "scheme": "socks5", "port": 8086}, "bypassList": [{"pattern": "", "conditionType": "BypassCondition"}], "profileType": "FixedProfile", "revision": "1538358c83c"}, "+GAE-Proxy": {"name": "GAE-Proxy", "color": "#d42d09", "fallbackProxy": {"host": "127.0.0.1", "scheme": "http", "port": 8087}, "bypassList": [{"pattern": "", "conditionType": "BypassCondition"}], "profileType": "FixedProfile", "revision": "15383570633"}, "+X-Tunnel": {"name": "X-Tunnel", "color": "#092dba", "fallbackProxy": {"host": "127.0.0.1", "scheme": "socks5", "port": 1080}, "bypassList": [{"pattern": "", "conditionType": "BypassCondition"}], "profileType": "FixedProfile", "revision": "1538358c83c"}, "+GAE-Proxy\u81ea\u52a8\u5207\u6362": {"name": "GAE-Proxy\u81ea\u52a8\u5207\u6362", "color": "#55bb55", "rules": [ {"profileName": "GAE-Proxy", "condition": {"pattern": "*.google.com.*", "conditionType": "HostWildcardCondition"}}, {"profileName": "GAE-Proxy", "condition": {"pattern": "*.google*.com", "conditionType": "HostWildcardCondition"}} ], "profileType": "SwitchProfile", "defaultProfileName": "__ruleListOf_GAE-Proxy\u81ea\u52a8\u5207\u6362", "revision": "15383578bce"}, "+__ruleListOf_GAE-Proxy\u81ea\u52a8\u5207\u6362": {"sourceUrl": "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt", "name": "__ruleListOf_GAE-Proxy\u81ea\u52a8\u5207\u6362", "format": "AutoProxy", "color": "#dd6633", "matchProfileName": "GAE-Proxy", "profileType": "RuleListProfile", "defaultProfileName": "direct", "ruleList": "", "revision": "1538357da4c"}, "+X-Tunnel\u81ea\u52a8\u5207\u6362": {"name": "X-Tunnel\u81ea\u52a8\u5207\u6362", "rules": [ {"profileName": "X-Tunnel", "condition": {"pattern": "*.google.com.*", "conditionType": "HostWildcardCondition"}}, {"profileName": "X-Tunnel", "condition": {"pattern": "*.google*.com", "conditionType": "HostWildcardCondition"}} ], "color": "#7c05ae", "profileType": "SwitchProfile", "defaultProfileName": "__ruleListOf_X-Tunnel\u81ea\u52a8\u5207\u6362", "revision": "153835abfe0"}, "+__ruleListOf_X-Tunnel\u81ea\u52a8\u5207\u6362": {"sourceUrl": "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt", "name": "__ruleListOf_X-Tunnel\u81ea\u52a8\u5207\u6362", "format": "AutoProxy", "color": "#7c05ae", "matchProfileName": "X-Tunnel", "profileType": "RuleListProfile", "defaultProfileName": "direct", "ruleList": "", "revision": "153835b3117"}, "-monitorWebRequests": true, "-startupProfileName": "Smart-Router", "-showInspectMenu": true, "-confirmDeletion": true, "-revertProxyChanges": false, "-refreshOnProfileChange": true, "-quickSwitchProfiles": ["direct"], "schemaVersion": 2, "-enableQuickSwitch": false, "-downloadInterval": 180 } ================================================ FILE: SwitchyOmega/download SwitchyOmega for Chromium & Firefox.url ================================================ [InternetShortcut] URL=https://github.com/FelisCatus/SwitchyOmega/releases ================================================ FILE: code/app_info.json ================================================ { "app_name": "XX-Net" } ================================================ FILE: code/default/LICENSE.txt ================================================ Copyright (c) [2022], [XX-Net] All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: code/default/babel_update.py ================================================ #!/usr/env/bin python import os # pip install googletrans==4.0.0-rc1 from googletrans import Translator import polib translator = Translator(service_urls=[ 'translate.google.com', ]) for lang in ["ru_RU"]: # "fa_IR", for module in ["launcher", "smart_router", "x_tunnel"]: # source_po = polib.pofile(f'{module}/lang/zh_CN/LC_MESSAGES/messages.po') lang_path = f'{module}/lang/{lang}/LC_MESSAGES' if not os.path.isdir(lang_path): os.makedirs(lang_path, exist_ok=True) new_fp = f'{lang_path}/translated.po' with open(new_fp, "w") as fd: fd.write("") new_po = polib.pofile(new_fp) for entry in source_po: try: result = translator.translate(entry.msgid, dest=lang[0:2]) res_text = result.text except Exception as e: print(f"translate {entry.msgid} failed, e:{e}") res_text = "" new_entry = polib.POEntry( msgid=entry.msgid, msgstr=res_text, occurrences=entry.occurrences ) new_po.append(new_entry) new_po.save(new_fp) print(f"module {module} translated to {lang}.") ================================================ FILE: code/default/download.md ================================================ ## 下载(Download): 稳定版(Stable version 4.12.5): [Win10 版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.5/XX-Net-win10-4.12.5.7z) [Win7 版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.5/XX-Net-win7-4.12.5.7z) [Mac 版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.5/XX-Net-mac-4.12.5.7z) [Linux 版下载](https://github.com/XX-net/XX-Net/archive/4.12.5.zip) [Android版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.5/XX-Net-4.12.5.apk) 测试版(Test version 4.13.7): [Win10 版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.6/XX-Net-win10-4.12.6.7z) [Win7 版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.6/XX-Net-win7-4.12.6.7z) [Mac 版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.6/XX-Net-mac-4.12.6.7z) [Linux 版下载](https://github.com/XX-net/XX-Net/archive/4.12.6.zip) [Android版下载](https://github.com/XX-net/XX-Net/releases/download/4.12.6/XX-Net-4.12.6.apk) ================================================ FILE: code/default/gae_proxy/__init__.py ================================================ __all__ = ["local", "start"] ================================================ FILE: code/default/gae_proxy/babel.config ================================================ # Extraction from Python source files #[python: **.py] # Extraction from HTML and YAML templates [jinja2: **/web_ui/**.html] [jinja2: **/web_ui/**.yaml] encoding = utf-8 ================================================ FILE: code/default/gae_proxy/lang/de_DE/LC_MESSAGES/messages.po ================================================ # German (Germany) translations for PROJECT. # Copyright (C) 2015 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2015. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2015-12-14 07:04+0800\n" "PO-Revision-Date: 2015-12-06 09:15+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: de_DE \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: web_ui/config.html:7 msgid "Public appids used by default" msgstr "" #: web_ui/config.html:10 msgid "The public appids are disabled to access videos or download files." msgstr "" #: web_ui/config.html:11 web_ui/deploy.html:14 msgid "How to apply" msgstr "" #: web_ui/config.html:16 msgid "Attention: inaccessable before appids are deployed." msgstr "" #: web_ui/config.html:23 web_ui/deploy.html:43 msgid "Advanced options" msgstr "" #: web_ui/config.html:29 web_ui/config.html:45 web_ui/deploy.html:49 #: web_ui/scan_ip.html:10 web_ui/status.html:25 web_ui/status.html:33 msgid "Help" msgstr "" #: web_ui/config.html:32 msgid "Needless to configure generally" msgstr "" #: web_ui/config.html:37 msgid "Enable IPv6(If it's available)" msgstr "" #: web_ui/config.html:45 msgid "LAN proxy(Generally not needed)" msgstr "" #: web_ui/config.html:54 msgid "Proxy type" msgstr "" #: web_ui/config.html:66 msgid "Proxy IP address or domain name" msgstr "" #: web_ui/config.html:74 msgid "Port" msgstr "" #: web_ui/config.html:82 msgid "User name" msgstr "" #: web_ui/config.html:90 msgid "Password" msgstr "" #: web_ui/config.html:100 msgid "Save" msgstr "" #: web_ui/config.html:107 msgid "Advanced tricks:" msgstr "" #: web_ui/config.html:107 msgid "By the configuration file" msgstr "" #: web_ui/config.html:112 msgid "Configure GAEProxy" msgstr "" #: web_ui/config.html:194 msgid "Failed reading the seeting." msgstr "" #: web_ui/config.html:239 web_ui/scan_ip.html:77 web_ui/scan_ip.html:148 #: web_ui/scan_ip.html:170 msgid "Settings saved successfully" msgstr "" #: web_ui/config.html:241 msgid "Unkown error occurred." msgstr "" #: web_ui/deploy.html:1 msgid "Deploy XX-Net onto GAE" msgstr "" #: web_ui/deploy.html:3 msgid "Current status: idle" msgstr "" #: web_ui/deploy.html:6 msgid "Authorization" msgstr "" #: web_ui/deploy.html:7 web_ui/menu.yaml:25 web_ui/scan_ip.html:3 msgid "Log" msgstr "" #: web_ui/deploy.html:17 msgid "Delimit multiple appids with |" msgstr "" #: web_ui/deploy.html:35 msgid "If the 2-step verification is in-use, please use your exclusive password." msgstr "" #: web_ui/deploy.html:35 web_ui/deploy.html:36 msgid "Configure now" msgstr "" #: web_ui/deploy.html:36 msgid "" "If the 2-step verification is NOT in-use, please enable the less secure " "apps." msgstr "" #: web_ui/deploy.html:37 msgid "Details" msgstr "" #: web_ui/deploy.html:52 msgid "Needless to fill generally" msgstr "" #: web_ui/deploy.html:54 msgid "" "If RC4 password is used, please configure it in the advanced settings " "while configuring GAE Proxy" msgstr "" #: web_ui/deploy.html:61 msgid "Start to deploy" msgstr "" #: web_ui/deploy.html:65 msgid "Redploy the server if XX-Net version is prior to 1.13.6." msgstr "" #: web_ui/deploy.html:170 web_ui/deploy.html:178 web_ui/deploy.html:184 #: web_ui/deploy.html:190 web_ui/deploy.html:193 web_ui/deploy.html:200 #: web_ui/deploy.html:205 web_ui/deploy.html:269 web_ui/deploy.html:272 msgid "Current status: " msgstr "" #: web_ui/deploy.html:170 msgid "XX-Net was reset." msgstr "" #: web_ui/deploy.html:178 web_ui/deploy.html:200 msgid "Deployment completed. " msgstr "" #: web_ui/deploy.html:178 msgid "Please go to " msgstr "" #: web_ui/deploy.html:178 msgid "the configuration page " msgstr "" #: web_ui/deploy.html:178 msgid "to set AppID to enable them." msgstr "" #: web_ui/deploy.html:184 web_ui/deploy.html:205 web_ui/deploy.html:272 msgid "An exception occurred. " msgstr "" #: web_ui/deploy.html:184 web_ui/deploy.html:205 web_ui/deploy.html:272 msgid "The exception info: " msgstr "" #: web_ui/deploy.html:190 msgid "idle" msgstr "" #: web_ui/deploy.html:193 msgid "deploying ..." msgstr "" #: web_ui/deploy.html:221 web_ui/deploy.html:231 msgid "Start deploying" msgstr "" #: web_ui/deploy.html:225 web_ui/deploy.html:233 msgid "Terminate deploying" msgstr "" #: web_ui/deploy.html:269 msgid "Deployment cancelled." msgstr "" #: web_ui/deploy.html:282 msgid "Either AppID is empty or invalid." msgstr "" #: web_ui/deploy.html:285 msgid "Either your Email address is empty or invalid." msgstr "" #: web_ui/deploy.html:288 msgid "Please fill in your account & its password." msgstr "" #: web_ui/ipconfig.html:4 msgid "Task type" msgstr "" #: web_ui/ipconfig.html:10 msgid "Import" msgstr "" #: web_ui/ipconfig.html:14 msgid "Export" msgstr "" #: web_ui/ipconfig.html:21 msgid "Import/Export format" msgstr "" #: web_ui/ipconfig.html:25 msgid " format" msgstr "" #: web_ui/ipconfig.html:26 msgid "New line delimiter" msgstr "" #: web_ui/ipconfig.html:27 msgid "Intelligent regular matching" msgstr "" #: web_ui/ipconfig.html:33 msgid "IP address list" msgstr "" #: web_ui/ipconfig.html:41 msgid "Run" msgstr "" #: web_ui/ipconfig.html:48 msgid "IP Import/Export" msgstr "" #: web_ui/ipconfig.html:90 msgid "Trying to import " msgstr "" #: web_ui/ipconfig.html:90 web_ui/ipconfig.html:102 web_ui/ipconfig.html:119 msgid " IP addresses." msgstr "" #: web_ui/ipconfig.html:102 msgid "Succeeded importing " msgstr "" #: web_ui/ipconfig.html:105 msgid "Failed importing IP addresses." msgstr "" #: web_ui/ipconfig.html:119 msgid "Succeeded exporting " msgstr "" #: web_ui/ipconfig.html:125 msgid "Failed exporting the IP addresses." msgstr "" #: web_ui/logging.html:15 msgid "GAEProxy Log" msgstr "" #: web_ui/menu.yaml:5 web_ui/status.html:7 msgid "Status" msgstr "" #: web_ui/menu.yaml:9 web_ui/status.html:39 msgid "Configuration" msgstr "" #: web_ui/menu.yaml:13 msgid "Deploy Server" msgstr "" #: web_ui/menu.yaml:17 msgid "Scan IP Addresses" msgstr "" #: web_ui/menu.yaml:21 msgid "Import/Export IP Addresses" msgstr "" #: web_ui/scan_ip.html:2 msgid "Settings" msgstr "" #: web_ui/scan_ip.html:10 msgid "Auto-adjust scan thread count" msgstr "" #: web_ui/scan_ip.html:18 msgid "Max scan thread count" msgstr "" #: web_ui/scan_ip.html:24 msgid "Update" msgstr "" #: web_ui/scan_ip.html:29 msgid "IP range list" msgstr "" #: web_ui/scan_ip.html:29 msgid "Supporting formats" msgstr "" #: web_ui/scan_ip.html:37 msgid "Submit" msgstr "" #: web_ui/scan_ip.html:46 msgid "Refresh" msgstr "" #: web_ui/scan_ip.html:52 msgid "IP scan settings(Needless to modify generally)" msgstr "" #: web_ui/scan_ip.html:99 msgid "Failed reading the log" msgstr "" #: web_ui/scan_ip.html:120 msgid "Failed reading the settings" msgstr "" #: web_ui/scan_ip.html:150 web_ui/scan_ip.html:172 msgid "Unkown error occurred" msgstr "" #: web_ui/status.html:3 msgid "Your browser is obsolete. Partial functionality will not be available." msgstr "" #: web_ui/status.html:4 msgid "The latest Chrome browser is recommended." msgstr "" #: web_ui/status.html:91 msgid "System Version" msgstr "" #: web_ui/status.html:142 msgid "Feedback" msgstr "" #: web_ui/status.html:147 msgid "Diagnostic Info" msgstr "" #: web_ui/status.html:150 msgid "The one-key feedback needs to sign in your Github account" msgstr "" #: web_ui/status.html:154 msgid "To Google Groups" msgstr "" #: web_ui/status.html:155 msgid "One-key feedback" msgstr "" #: web_ui/status.html:161 msgid "GAE Proxy Status Info" msgstr "" #: web_ui/status.html:274 msgid "" "The status page is empty. Highly likely that GAEProxy failed getting " "started. Please follow " msgstr "" #: web_ui/status.html:274 msgid "guide " msgstr "" #: web_ui/status.html:274 msgid "to troubleshoot." msgstr "" #: web_ui/status.html:276 msgid "No response from GAEProxy process. It might have already exited." msgstr "" ================================================ FILE: code/default/gae_proxy/lang/es_VE/LC_MESSAGES/messages.po ================================================ # Spanish (Venezuela) translations for PROJECT. # Copyright (C) 2015 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2015. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2015-12-14 07:04+0800\n" "PO-Revision-Date: 2015-12-06 09:27+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: es_VE \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: web_ui/config.html:7 msgid "Public appids used by default" msgstr "" #: web_ui/config.html:10 msgid "The public appids are disabled to access videos or download files." msgstr "" #: web_ui/config.html:11 web_ui/deploy.html:14 msgid "How to apply" msgstr "" #: web_ui/config.html:16 msgid "Attention: inaccessable before appids are deployed." msgstr "" #: web_ui/config.html:23 web_ui/deploy.html:43 msgid "Advanced options" msgstr "" #: web_ui/config.html:29 web_ui/config.html:45 web_ui/deploy.html:49 #: web_ui/scan_ip.html:10 web_ui/status.html:25 web_ui/status.html:33 msgid "Help" msgstr "" #: web_ui/config.html:32 msgid "Needless to configure generally" msgstr "" #: web_ui/config.html:37 msgid "Enable IPv6(If it's available)" msgstr "" #: web_ui/config.html:45 msgid "LAN proxy(Generally not needed)" msgstr "" #: web_ui/config.html:54 msgid "Proxy type" msgstr "" #: web_ui/config.html:66 msgid "Proxy IP address or domain name" msgstr "" #: web_ui/config.html:74 msgid "Port" msgstr "" #: web_ui/config.html:82 msgid "User name" msgstr "" #: web_ui/config.html:90 msgid "Password" msgstr "" #: web_ui/config.html:100 msgid "Save" msgstr "" #: web_ui/config.html:107 msgid "Advanced tricks:" msgstr "" #: web_ui/config.html:107 msgid "By the configuration file" msgstr "" #: web_ui/config.html:112 msgid "Configure GAEProxy" msgstr "" #: web_ui/config.html:194 msgid "Failed reading the seeting." msgstr "" #: web_ui/config.html:239 web_ui/scan_ip.html:77 web_ui/scan_ip.html:148 #: web_ui/scan_ip.html:170 msgid "Settings saved successfully" msgstr "" #: web_ui/config.html:241 msgid "Unkown error occurred." msgstr "" #: web_ui/deploy.html:1 msgid "Deploy XX-Net onto GAE" msgstr "" #: web_ui/deploy.html:3 msgid "Current status: idle" msgstr "" #: web_ui/deploy.html:6 msgid "Authorization" msgstr "" #: web_ui/deploy.html:7 web_ui/menu.yaml:25 web_ui/scan_ip.html:3 msgid "Log" msgstr "" #: web_ui/deploy.html:17 msgid "Delimit multiple appids with |" msgstr "" #: web_ui/deploy.html:35 msgid "If the 2-step verification is in-use, please use your exclusive password." msgstr "" #: web_ui/deploy.html:35 web_ui/deploy.html:36 msgid "Configure now" msgstr "" #: web_ui/deploy.html:36 msgid "" "If the 2-step verification is NOT in-use, please enable the less secure " "apps." msgstr "" #: web_ui/deploy.html:37 msgid "Details" msgstr "" #: web_ui/deploy.html:52 msgid "Needless to fill generally" msgstr "" #: web_ui/deploy.html:54 msgid "" "If RC4 password is used, please configure it in the advanced settings " "while configuring GAE Proxy" msgstr "" #: web_ui/deploy.html:61 msgid "Start to deploy" msgstr "" #: web_ui/deploy.html:65 msgid "Redploy the server if XX-Net version is prior to 1.13.6." msgstr "" #: web_ui/deploy.html:170 web_ui/deploy.html:178 web_ui/deploy.html:184 #: web_ui/deploy.html:190 web_ui/deploy.html:193 web_ui/deploy.html:200 #: web_ui/deploy.html:205 web_ui/deploy.html:269 web_ui/deploy.html:272 msgid "Current status: " msgstr "" #: web_ui/deploy.html:170 msgid "XX-Net was reset." msgstr "" #: web_ui/deploy.html:178 web_ui/deploy.html:200 msgid "Deployment completed. " msgstr "" #: web_ui/deploy.html:178 msgid "Please go to " msgstr "" #: web_ui/deploy.html:178 msgid "the configuration page " msgstr "" #: web_ui/deploy.html:178 msgid "to set AppID to enable them." msgstr "" #: web_ui/deploy.html:184 web_ui/deploy.html:205 web_ui/deploy.html:272 msgid "An exception occurred. " msgstr "" #: web_ui/deploy.html:184 web_ui/deploy.html:205 web_ui/deploy.html:272 msgid "The exception info: " msgstr "" #: web_ui/deploy.html:190 msgid "idle" msgstr "" #: web_ui/deploy.html:193 msgid "deploying ..." msgstr "" #: web_ui/deploy.html:221 web_ui/deploy.html:231 msgid "Start deploying" msgstr "" #: web_ui/deploy.html:225 web_ui/deploy.html:233 msgid "Terminate deploying" msgstr "" #: web_ui/deploy.html:269 msgid "Deployment cancelled." msgstr "" #: web_ui/deploy.html:282 msgid "Either AppID is empty or invalid." msgstr "" #: web_ui/deploy.html:285 msgid "Either your Email address is empty or invalid." msgstr "" #: web_ui/deploy.html:288 msgid "Please fill in your account & its password." msgstr "" #: web_ui/ipconfig.html:4 msgid "Task type" msgstr "" #: web_ui/ipconfig.html:10 msgid "Import" msgstr "" #: web_ui/ipconfig.html:14 msgid "Export" msgstr "" #: web_ui/ipconfig.html:21 msgid "Import/Export format" msgstr "" #: web_ui/ipconfig.html:25 msgid " format" msgstr "" #: web_ui/ipconfig.html:26 msgid "New line delimiter" msgstr "" #: web_ui/ipconfig.html:27 msgid "Intelligent regular matching" msgstr "" #: web_ui/ipconfig.html:33 msgid "IP address list" msgstr "" #: web_ui/ipconfig.html:41 msgid "Run" msgstr "" #: web_ui/ipconfig.html:48 msgid "IP Import/Export" msgstr "" #: web_ui/ipconfig.html:90 msgid "Trying to import " msgstr "" #: web_ui/ipconfig.html:90 web_ui/ipconfig.html:102 web_ui/ipconfig.html:119 msgid " IP addresses." msgstr "" #: web_ui/ipconfig.html:102 msgid "Succeeded importing " msgstr "" #: web_ui/ipconfig.html:105 msgid "Failed importing IP addresses." msgstr "" #: web_ui/ipconfig.html:119 msgid "Succeeded exporting " msgstr "" #: web_ui/ipconfig.html:125 msgid "Failed exporting the IP addresses." msgstr "" #: web_ui/logging.html:15 msgid "GAEProxy Log" msgstr "" #: web_ui/menu.yaml:5 web_ui/status.html:7 msgid "Status" msgstr "" #: web_ui/menu.yaml:9 web_ui/status.html:39 msgid "Configuration" msgstr "" #: web_ui/menu.yaml:13 msgid "Deploy Server" msgstr "" #: web_ui/menu.yaml:17 msgid "Scan IP Addresses" msgstr "" #: web_ui/menu.yaml:21 msgid "Import/Export IP Addresses" msgstr "" #: web_ui/scan_ip.html:2 msgid "Settings" msgstr "" #: web_ui/scan_ip.html:10 msgid "Auto-adjust scan thread count" msgstr "" #: web_ui/scan_ip.html:18 msgid "Max scan thread count" msgstr "" #: web_ui/scan_ip.html:24 msgid "Update" msgstr "" #: web_ui/scan_ip.html:29 msgid "IP range list" msgstr "" #: web_ui/scan_ip.html:29 msgid "Supporting formats" msgstr "" #: web_ui/scan_ip.html:37 msgid "Submit" msgstr "" #: web_ui/scan_ip.html:46 msgid "Refresh" msgstr "" #: web_ui/scan_ip.html:52 msgid "IP scan settings(Needless to modify generally)" msgstr "" #: web_ui/scan_ip.html:99 msgid "Failed reading the log" msgstr "" #: web_ui/scan_ip.html:120 msgid "Failed reading the settings" msgstr "" #: web_ui/scan_ip.html:150 web_ui/scan_ip.html:172 msgid "Unkown error occurred" msgstr "" #: web_ui/status.html:3 msgid "Your browser is obsolete. Partial functionality will not be available." msgstr "" #: web_ui/status.html:4 msgid "The latest Chrome browser is recommended." msgstr "" #: web_ui/status.html:91 msgid "System Version" msgstr "" #: web_ui/status.html:142 msgid "Feedback" msgstr "" #: web_ui/status.html:147 msgid "Diagnostic Info" msgstr "" #: web_ui/status.html:150 msgid "The one-key feedback needs to sign in your Github account" msgstr "" #: web_ui/status.html:154 msgid "To Google Groups" msgstr "" #: web_ui/status.html:155 msgid "One-key feedback" msgstr "" #: web_ui/status.html:161 msgid "GAE Proxy Status Info" msgstr "" #: web_ui/status.html:274 msgid "" "The status page is empty. Highly likely that GAEProxy failed getting " "started. Please follow " msgstr "" #: web_ui/status.html:274 msgid "guide " msgstr "" #: web_ui/status.html:274 msgid "to troubleshoot." msgstr "" #: web_ui/status.html:276 msgid "No response from GAEProxy process. It might have already exited." msgstr "" #~ msgid "GAEProxy Status Info" #~ msgstr "" ================================================ FILE: code/default/gae_proxy/lang/fa_IR/LC_MESSAGES/messages.po ================================================ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2017-11-15 08:26+0800\n" "PO-Revision-Date: 2015-12-06 09:14+0800\n" "Last-Translator: FULL NAME \n" "Language: fa_IR\n" "Language-Team: fa_IR \n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.3.4\n" msgid "Scan Settings" msgstr "تنظیمات اسکن" msgid "Scan Log" msgstr "اسکن ورود" msgid "Import IP" msgstr "واردات IP" msgid "Export IP" msgstr "صادرات IP" msgid "Check IP" msgstr "بررسی IP" msgid "IPv6 Tunnel" msgstr "" msgid "Advanced" msgstr "پیشرفته" msgid "Your browser is obsolete. Partial functionality will not be available." msgstr "مرورگر شما قدیمی است. قابلیت جزئی در دسترس نخواهد بود." msgid "The latest Chrome browser is recommended." msgstr "آخرین مرورگر کروم توصیه می شود." msgid "Status" msgstr "وضعیت" msgid "Property" msgstr "ویژگی" msgid "Value" msgstr "ارزش" msgid "All IP Number" msgstr "همه شماره IP" msgid "Left Number" msgstr "عدد سمت چپ" msgid "Good IP Number" msgstr "خوب شماره IP" msgid "Run" msgstr "اجرا" msgid "No response from GAEProxy process. It might have already exited." msgstr "هیچ پاسخی از روند GAEProxy. این ممکن است در حال حاضر خارج می شود." msgid "Stop" msgstr "متوقف کردن" msgid "Public appids used by default" msgstr "appids عمومی استفاده می شود به طور پیش فرض" msgid "The public appids are disabled to access videos or download files." msgstr "" "appids عمومی را غیرفعال برای دسترسی به فیلم ها و یا فایل های دانلود می " "باشد." msgid "How to apply" msgstr "چگونه به درخواست" msgid "Attention: inaccessable before appids are deployed." msgstr "توجه: غیر قابل دسترس قبل از appids مستقر هستند." msgid "Advanced options" msgstr "گزینه های پیشرفته" msgid "LAN proxy(Generally not needed)" msgstr "پروکسی LAN (به طور کلی مورد نیاز نیست)" msgid "Help" msgstr "کمک" msgid "Proxy type" msgstr "نوع پروکسی" msgid "Proxy IP address or domain name" msgstr "آدرس IP پروکسی و یا نام دامنه" msgid "Port" msgstr "درگاه" msgid "User name" msgstr "نام کاربری" msgid "Password" msgstr "رمز عبور" msgid "Save" msgstr "ذخیره" msgid "Advanced tricks:" msgstr "ترفندهای پیشرفته:" msgid "By the configuration file" msgstr "توسط فایل پیکربندی" msgid "Configure GAEProxy" msgstr "پیکربندی GAEProxy" msgid "Failed reading the settings." msgstr "خواندن تنظیمات انجام نشد." msgid "Wait for checking setting..." msgstr "صبر کنید برای چک کردن تنظیمات ..." msgid "Settings saved successfully" msgstr "تنظیمات با موفقیت ذخیره" msgid "AppID invalid:" msgstr "_AppID_ نامعتبر است:" msgid ", deploy appid before using." msgstr "، استقرار APPID قبل از استفاده." msgid "Failed saving settings" msgstr "خواندن تنظیمات انجام نشد." msgid "Deploy XX-Net onto GAE" msgstr "استقرار _XX-Net_ بر روی GAE" msgid "Current status: " msgstr "وضعیت فعلی:" msgid "idle" msgstr "آماده به کار" msgid "Authorization" msgstr "اجازه" msgid "Log" msgstr "ورود" msgid "Delimit multiple appids with |" msgstr "محدود appids های متعدد را با |" msgid "Show Debug Log" msgstr "" msgid "Start to deploy" msgstr "شروع به استقرار" msgid "Auth window will popup, make sure don't block popup in browser." msgstr "" msgid "XX-Net was reset." msgstr "_XX-Net_ بازنشانی شد." msgid "Deployment completed. " msgstr "استقرار تکمیل شده است. " msgid "Please go to " msgstr "لطفا رفتن به " msgid "the configuration page " msgstr "صفحه تنظیمات " msgid "to set AppID to enable them." msgstr "به مجموعه ای از _AppID_ به آنها را فعال کنید." msgid "An exception occurred. " msgstr "یک استثنا رخ داده است. " msgid "The exception info: " msgstr "اطلاعات استثنا:" msgid "deploying ..." msgstr "استقرار ..." msgid "Terminate deploying" msgstr "خاتمه استقرار" msgid "Deployment cancelled." msgstr "استقرار لغو شده است." msgid "Your AppID is either empty or invalid." msgstr "_AppID_ خود را به صورت خالی و یا نامعتبر است." msgid "Export format" msgstr "فرمت صادرات" msgid " format" msgstr "قالب " msgid "New line delimiter" msgstr "ذخیره خط جدید" msgid "IP address list" msgstr "لیست آدرس IP" msgid "Succeeded exporting " msgstr "موفق صادرات " msgid " IP addresses." msgstr " آدرس IP است." msgid "Failed exporting the IP addresses." msgstr "صادرات آدرس IP شکست خورده است." msgid "IP list" msgstr "لیست IP" msgid "Enable" msgstr "" msgid "Disable" msgstr "" msgid "Running ..." msgstr "" msgid "GAEProxy Log" msgstr "GAEProxy ورود" msgid "Configuration" msgstr "پیکربندی" msgid "Deploy Server" msgstr "استقرار سرور" msgid "Refresh" msgstr "تازه کردن" msgid "Failed reading the log" msgstr "خواندن ورود به سیستم شکست خورده" msgid "Auto-adjust scan thread count" msgstr "خودکار تنظیم تعداد موضوع اسکن" msgid "Max scan thread count" msgstr "حداکثر تعداد موضوع اسکن" msgid "Enable IPv6(If it's available)" msgstr "فعال کردن IPv6 را (سرنت تنها)" msgid "AUTO" msgstr "" msgid "Force IPv4" msgstr "" msgid "Force IPv6" msgstr "" msgid "IP range list" msgstr "لیست محدوده IP" msgid "Supporting formats" msgstr "حمایت از فرمت های" msgid "Submit" msgstr "ارسال" msgid "Failed reading the settings" msgstr "خواندن تنظیمات انجام نشد" msgid "Unkown error occurred" msgstr "خطای ناشناخته رخ داده" msgid "IPv4 Status" msgstr "" msgid "IPv6 Status" msgstr "" msgid "IPv4 Number" msgstr "" msgid "IPv6 Number" msgstr "" msgid "Is Idle" msgstr "آماده به کار" msgid "IP Quality" msgstr "IP کیفیت" msgid "Connection Pool" msgstr "وضعیت اتصال" msgid "Browser Proxy Setting" msgstr "مرورگر تنظیم پروکسی" msgid "CA status" msgstr "وضعیت CA" msgid "Download" msgstr "دانلود" msgid "Number of IP-Scanning Threads" msgstr "تعداد IP-اسکن موضوعات" msgid "Settings" msgstr "تنظیمات" msgid "Block Status" msgstr "وضعیت بلوک" msgid "XX-Net Version" msgstr "_XX-Net_ نسخه" msgid "System Proxy Status" msgstr "_XX-Net_ نسخه" msgid "Listening Proxy" msgstr "گوش دادن پروکسی" msgid "PAC URL" msgstr "" msgid "USE IPv6" msgstr "" msgid "Working AppIDs" msgstr "بدون APPID کارگر. لطفا بررسی کنید. " msgid "Out-of-quota AppIDs" msgstr "خارج از سهمیه AppIDs" msgid "Nonexistent AppIDs" msgstr "AppIDs وجود ندارد" msgid "System Version" msgstr "نسخه سیستم" msgid "Diagnostic Info" msgstr "اطلاعات تشخیصی" msgid "Check Github issues" msgstr "بررسی مسائل _Github_" msgid " or " msgstr " یا " msgid " Discussions" msgstr "بحث" msgid "Show Details" msgstr "نمایش جزئیات" msgid "Post to Github issue needs to sign in your Github account" msgstr "بازخورد یک کلید نیاز به ثبت نام در حساب github خود را" msgid "GAE Proxy Status Info" msgstr "GAE پروکسی وضعیت" msgid "" "-----------%0AProblem Description:%0APlease describe your problem, " "running logs may be needed.%0A%0A-----------%0ADiagnostic information:%0A" msgstr "" msgid "" "The status page is empty. Highly likely that GAEProxy failed getting " "started. Please follow " msgstr "" "صفحه وضعیت خالی است. بسیار محتمل است که GAEProxy شروع کار شکست خورده است." " لطفا دنبال کنید" msgid "guide " msgstr "راهنما" msgid "to troubleshoot." msgstr "به عیب یابی." msgid "Your local network failed. Please check your network and firewall. " msgstr "شبکه محلی شما را شکست خورده است. لطفا شبکه و فایروال خود را چک کنید." msgid "You may want to $1turn on IP scaner$2." msgstr "" msgid "" "You can try turn on IPv6 or use X-Tunnel" msgstr "" msgid "XX-Net is scanning IP. Please wait about half an hour." msgstr "_XX-Net_ اسکن است. لطفا صبر کنید." msgid "" "Public appid out of quota, Please deploy your own " "APPID" msgstr "" msgid "" "Your appid out of quota, Please deploy more APPID" msgstr "" msgid "No working appid. Please check. " msgstr "بدون APPID کارگر. لطفا بررسی کنید. " msgid "System is Idle. " msgstr "" msgid "Connection not established yet. " msgstr "اتصال برقرار نشده است" msgid "Please check your browser proxy setting." msgstr "لطفا تنظیمات پروکسی مرورگر خود را بررسی کنید." msgid "Detecting..." msgstr "استقرار ..." msgid "Please import certificates to your browser." msgstr "لطفا مرورگر خود را به گواهی وارد کنید." msgid "" "You are using public APPID. You are recommended to deploy your own APPID" msgstr "" msgid ", Everything is OK. Welcome to the FREE Internet. " msgstr "، همه چی خوبه. به اینترنت خوش آمدید. " msgid "" "The status page is empty. Highly likely that XX-Net failed getting " "started. Please follow " msgstr "" "صفحه وضعیت خالی است. بسیار محتمل است که GAEProxy شروع کار شکست خورده است." " لطفا دنبال کنید" msgid "No response from process. It might have already exited." msgstr "هیچ پاسخی از روند GAEProxy. این ممکن است در حال حاضر خارج می شود." msgid "You are using the public Appid." msgstr "شما با استفاده از شناسه های عمومی است." msgid "new:" msgstr "" msgid " h1:" msgstr "" msgid " h2:" msgstr "" msgid "Auto proxy enabled at " msgstr "پروکسی خودکار را فعال کنید در" msgid "Proxy enabled at " msgstr "پروکسی را فعال کنید در " msgid "Proxy disabled" msgstr "پروکسی غیرفعال" ================================================ FILE: code/default/gae_proxy/lang/ja_JP/LC_MESSAGES/messages.po ================================================ # Japanese (Japan) translations for PROJECT. # Copyright (C) 2015 ORGANIZATION # This file is distributed under the same license as the PROJECT project. # FIRST AUTHOR , 2015. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2015-12-14 07:04+0800\n" "PO-Revision-Date: 2015-12-06 09:22+0800\n" "Last-Translator: FULL NAME \n" "Language-Team: ja_JP \n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.3\n" #: web_ui/config.html:7 msgid "Public appids used by default" msgstr "" #: web_ui/config.html:10 msgid "The public appids are disabled to access videos or download files." msgstr "" #: web_ui/config.html:11 web_ui/deploy.html:14 msgid "How to apply" msgstr "" #: web_ui/config.html:16 msgid "Attention: inaccessable before appids are deployed." msgstr "" #: web_ui/config.html:23 web_ui/deploy.html:43 msgid "Advanced options" msgstr "" #: web_ui/config.html:29 web_ui/config.html:45 web_ui/deploy.html:49 #: web_ui/scan_ip.html:10 web_ui/status.html:25 web_ui/status.html:33 msgid "Help" msgstr "" #: web_ui/config.html:32 msgid "Needless to configure generally" msgstr "" #: web_ui/config.html:37 msgid "Enable IPv6(If it's available)" msgstr "" #: web_ui/config.html:45 msgid "LAN proxy(Generally not needed)" msgstr "" #: web_ui/config.html:54 msgid "Proxy type" msgstr "" #: web_ui/config.html:66 msgid "Proxy IP address or domain name" msgstr "" #: web_ui/config.html:74 msgid "Port" msgstr "" #: web_ui/config.html:82 msgid "User name" msgstr "" #: web_ui/config.html:90 msgid "Password" msgstr "" #: web_ui/config.html:100 msgid "Save" msgstr "" #: web_ui/config.html:107 msgid "Advanced tricks:" msgstr "" #: web_ui/config.html:107 msgid "By the configuration file" msgstr "" #: web_ui/config.html:112 msgid "Configure GAEProxy" msgstr "" #: web_ui/config.html:194 msgid "Failed reading the seeting." msgstr "" #: web_ui/config.html:239 web_ui/scan_ip.html:77 web_ui/scan_ip.html:148 #: web_ui/scan_ip.html:170 msgid "Settings saved successfully" msgstr "" #: web_ui/config.html:241 msgid "Unkown error occurred." msgstr "" #: web_ui/deploy.html:1 msgid "Deploy XX-Net onto GAE" msgstr "" #: web_ui/deploy.html:3 msgid "Current status: idle" msgstr "" #: web_ui/deploy.html:6 msgid "Authorization" msgstr "" #: web_ui/deploy.html:7 web_ui/menu.yaml:25 web_ui/scan_ip.html:3 msgid "Log" msgstr "" #: web_ui/deploy.html:17 msgid "Delimit multiple appids with |" msgstr "" #: web_ui/deploy.html:35 msgid "If the 2-step verification is in-use, please use your exclusive password." msgstr "" #: web_ui/deploy.html:35 web_ui/deploy.html:36 msgid "Configure now" msgstr "" #: web_ui/deploy.html:36 msgid "" "If the 2-step verification is NOT in-use, please enable the less secure " "apps." msgstr "" #: web_ui/deploy.html:37 msgid "Details" msgstr "" #: web_ui/deploy.html:52 msgid "Needless to fill generally" msgstr "" #: web_ui/deploy.html:54 msgid "" "If RC4 password is used, please configure it in the advanced settings " "while configuring GAE Proxy" msgstr "" #: web_ui/deploy.html:61 msgid "Start to deploy" msgstr "" #: web_ui/deploy.html:65 msgid "Redploy the server if XX-Net version is prior to 1.13.6." msgstr "" #: web_ui/deploy.html:170 web_ui/deploy.html:178 web_ui/deploy.html:184 #: web_ui/deploy.html:190 web_ui/deploy.html:193 web_ui/deploy.html:200 #: web_ui/deploy.html:205 web_ui/deploy.html:269 web_ui/deploy.html:272 msgid "Current status: " msgstr "" #: web_ui/deploy.html:170 msgid "XX-Net was reset." msgstr "" #: web_ui/deploy.html:178 web_ui/deploy.html:200 msgid "Deployment completed. " msgstr "" #: web_ui/deploy.html:178 msgid "Please go to " msgstr "" #: web_ui/deploy.html:178 msgid "the configuration page " msgstr "" #: web_ui/deploy.html:178 msgid "to set AppID to enable them." msgstr "" #: web_ui/deploy.html:184 web_ui/deploy.html:205 web_ui/deploy.html:272 msgid "An exception occurred. " msgstr "" #: web_ui/deploy.html:184 web_ui/deploy.html:205 web_ui/deploy.html:272 msgid "The exception info: " msgstr "" #: web_ui/deploy.html:190 msgid "idle" msgstr "" #: web_ui/deploy.html:193 msgid "deploying ..." msgstr "" #: web_ui/deploy.html:221 web_ui/deploy.html:231 msgid "Start deploying" msgstr "" #: web_ui/deploy.html:225 web_ui/deploy.html:233 msgid "Terminate deploying" msgstr "" #: web_ui/deploy.html:269 msgid "Deployment cancelled." msgstr "" #: web_ui/deploy.html:282 msgid "Either AppID is empty or invalid." msgstr "" #: web_ui/deploy.html:285 msgid "Either your Email address is empty or invalid." msgstr "" #: web_ui/deploy.html:288 msgid "Please fill in your account & its password." msgstr "" #: web_ui/ipconfig.html:4 msgid "Task type" msgstr "" #: web_ui/ipconfig.html:10 msgid "Import" msgstr "" #: web_ui/ipconfig.html:14 msgid "Export" msgstr "" #: web_ui/ipconfig.html:21 msgid "Import/Export format" msgstr "" #: web_ui/ipconfig.html:25 msgid " format" msgstr "" #: web_ui/ipconfig.html:26 msgid "New line delimiter" msgstr "" #: web_ui/ipconfig.html:27 msgid "Intelligent regular matching" msgstr "" #: web_ui/ipconfig.html:33 msgid "IP address list" msgstr "" #: web_ui/ipconfig.html:41 msgid "Run" msgstr "" #: web_ui/ipconfig.html:48 msgid "IP Import/Export" msgstr "" #: web_ui/ipconfig.html:90 msgid "Trying to import " msgstr "" #: web_ui/ipconfig.html:90 web_ui/ipconfig.html:102 web_ui/ipconfig.html:119 msgid " IP addresses." msgstr "" #: web_ui/ipconfig.html:102 msgid "Succeeded importing " msgstr "" #: web_ui/ipconfig.html:105 msgid "Failed importing IP addresses." msgstr "" #: web_ui/ipconfig.html:119 msgid "Succeeded exporting " msgstr "" #: web_ui/ipconfig.html:125 msgid "Failed exporting the IP addresses." msgstr "" #: web_ui/logging.html:15 msgid "GAEProxy Log" msgstr "" #: web_ui/menu.yaml:5 web_ui/status.html:7 msgid "Status" msgstr "" #: web_ui/menu.yaml:9 web_ui/status.html:39 msgid "Configuration" msgstr "" #: web_ui/menu.yaml:13 msgid "Deploy Server" msgstr "" #: web_ui/menu.yaml:17 msgid "Scan IP Addresses" msgstr "" #: web_ui/menu.yaml:21 msgid "Import/Export IP Addresses" msgstr "" #: web_ui/scan_ip.html:2 msgid "Settings" msgstr "" #: web_ui/scan_ip.html:10 msgid "Auto-adjust scan thread count" msgstr "" #: web_ui/scan_ip.html:18 msgid "Max scan thread count" msgstr "" #: web_ui/scan_ip.html:24 msgid "Update" msgstr "" #: web_ui/scan_ip.html:29 msgid "IP range list" msgstr "" #: web_ui/scan_ip.html:29 msgid "Supporting formats" msgstr "" #: web_ui/scan_ip.html:37 msgid "Submit" msgstr "" #: web_ui/scan_ip.html:46 msgid "Refresh" msgstr "" #: web_ui/scan_ip.html:52 msgid "IP scan settings(Needless to modify generally)" msgstr "" #: web_ui/scan_ip.html:99 msgid "Failed reading the log" msgstr "" #: web_ui/scan_ip.html:120 msgid "Failed reading the settings" msgstr "" #: web_ui/scan_ip.html:150 web_ui/scan_ip.html:172 msgid "Unkown error occurred" msgstr "" #: web_ui/status.html:3 msgid "Your browser is obsolete. Partial functionality will not be available." msgstr "" #: web_ui/status.html:4 msgid "The latest Chrome browser is recommended." msgstr "" #: web_ui/status.html:91 msgid "System Version" msgstr "" #: web_ui/status.html:142 msgid "Feedback" msgstr "" #: web_ui/status.html:147 msgid "Diagnostic Info" msgstr "" #: web_ui/status.html:150 msgid "The one-key feedback needs to sign in your Github account" msgstr "" #: web_ui/status.html:154 msgid "To Google Groups" msgstr "" #: web_ui/status.html:155 msgid "One-key feedback" msgstr "" #: web_ui/status.html:161 msgid "GAE Proxy Status Info" msgstr "" #: web_ui/status.html:274 msgid "" "The status page is empty. Highly likely that GAEProxy failed getting " "started. Please follow " msgstr "" #: web_ui/status.html:274 msgid "guide " msgstr "" #: web_ui/status.html:274 msgid "to troubleshoot." msgstr "" #: web_ui/status.html:276 msgid "No response from GAEProxy process. It might have already exited." msgstr "" ================================================ FILE: code/default/gae_proxy/lang/zh_CN/LC_MESSAGES/messages.po ================================================ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: xxnet.dev@gmail.com\n" "POT-Creation-Date: 2017-12-24 12:00+0800\n" "PO-Revision-Date: 2017-12-29 12:00+0800\n" "Last-Translator: Emphasia@github\n" "Language: zh_Hans_CN\n" "Language-Team: zh_Hans_CN \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.3.4\n" msgid "Global Settings" msgstr "全局设置" msgid "Switch ON to submit setting level" msgstr "切换到 ON 才能提交设置级别" msgid "Passive mode consumes less system resources" msgstr "被动模式消耗更少的系统资源" msgid "Customized an adequate value for your network connection. large values will provide a larger bandwidth limit, but may result in tunnel connection unstable." msgstr "为你的网络连接自定义适当的数值。大的数值会提供较大的带宽上限,但是可能导致隧道连接不稳定。" msgid "Submit setting level" msgstr "提交设置级别" msgid "Setting level" msgstr "设置级别" msgid "Passive" msgstr "被动" msgid "Conservative" msgstr "保守" msgid "Normal" msgstr "正常" msgid "Radical" msgstr "积极" msgid "Extreme" msgstr "极端" msgid "Connect receive buffer size" msgstr "连接接收缓冲大小" msgid "Scan Settings" msgstr "扫描设置" msgid "Scan Log" msgstr "扫描日志" msgid "Import IP" msgstr "导入 IP" msgid "Export IP" msgstr "导出 IP" msgid "Check IP" msgstr "检查 IP" msgid "IPv6 Tunnel" msgstr "IPv6 隧道" msgid "Teredo Tunnel" msgstr "Teredo 隧道" msgid "GAEProxy Advanced Configuration" msgstr "GAEProxy 高级配置" msgid "Your browser is obsolete. Partial functionality will not be available." msgstr "您的浏览器版本过低, 部分功能将无法使用。" msgid "The latest Chrome browser is recommended." msgstr "建议您使用最新版本的 Chrome 浏览器。" msgid "Status" msgstr "状态" msgid "Property" msgstr "属性" msgid "Value" msgstr "值" msgid "All IP Number" msgstr "总 IP 数" msgid "Left Number" msgstr "待测 IP 数" msgid "Good IP Number" msgstr "有效 IP 数" msgid "Run" msgstr "开始" msgid "No response from process: " msgstr "进程:" # msgid "GAEProxy" # msgstr "" # msgid "XX-Net" # msgstr "" msgid ". It might have already exited." msgstr " 无响应, 可能已退出。" msgid "Stop" msgstr "停止" msgid "Public AppIDs used by default" msgstr "默认使用公共 AppID,保存多个 AppID 请用 | 分割" msgid "The public AppIDs are disabled to access videos or download files." msgstr "公共 AppID 不能看视频、下载文件。" msgid "How to apply" msgstr "如何申请" msgid "Attention: inaccessable before AppIDs are deployed." msgstr "注意:AppID 部署之前无法使用。" msgid "Save" msgstr "保存" msgid "Advanced tricks:" msgstr "高级技巧:" msgid "By the configuration file" msgstr "通过文件配置" msgid "GAEProxy Configuration" msgstr "GAEProxy 配置" msgid "Failed reading the settings." msgstr "读取设置失败。" msgid "Failed reading the prefix policies." msgstr "读取前缀策略失败。" msgid "No teredo prefix policiy is found." msgstr "未发现 Teredo 前缀策略。" msgid "Checking settings ..." msgstr "请等待检查设置有效性..." msgid "Settings saved successfully." msgstr "设置保存成功。" msgid "AppID invalid:" msgstr "无效的AppID:" msgid ", deploy AppID before using." msgstr ",使用前请先部署。" msgid "Failed saving settings: " msgstr "保存设置失败:" msgid "Failed saving settings." msgstr "保存设置失败。" msgid "Deploy XX-Net onto GAE" msgstr "部署 XX-Net 至 GAE" msgid "Current status: " msgstr "当前状态:" msgid "idle" msgstr "空闲" msgid "unknown" msgstr "未知" msgid "offline" msgstr "离线(无法连接)" msgid "probe" msgstr "正在检查网络" msgid "qualified" msgstr "合格(已连接)" msgid "dormant" msgstr "休眠(未连接)" msgid "enabled" msgstr "已启用" msgid "disabled" msgstr "已禁用" msgid "Still not connected? Wait for a while, or" msgstr "仍然连接不上?等一会儿,或者" msgid "try to reduce the connection buffer size" msgstr "尝试降低连接缓冲数值" msgid "Script is running, please retry later." msgstr "脚本正在运行,请稍后再试。" msgid ", are you sure to continue?" msgstr ",你确定要继续吗?" msgid "working" msgstr "工作" msgid "Authorization" msgstr "授权" msgid "Log" msgstr "日志" msgid "Delimit multiple AppIDs with |" msgstr "批量部署多个 AppID 请用 | 分割;部署时不要占用 8080 端口" msgid "Show Debug Log" msgstr "显示日志" msgid "Start to deploy" msgstr "开始部署" msgid "Auth window will popup, make sure don't block popup in browser." msgstr "认证会弹出窗口,请确认浏览器不会阻止弹窗。" msgid "XX-Net was reset." msgstr "XX-Net已被重置。" msgid "Deployment completed." msgstr "部署完成。" msgid "Please go to " msgstr "请在" msgid "the configuration page " msgstr "配置页面" msgid "to set AppID to enable them." msgstr "中设置 AppID, 方会生效。" msgid "An exception occurred." msgstr "发生异常。" msgid "The exception info: " msgstr "异常信息:" msgid "deploying ..." msgstr "正在部署..." msgid "Terminate deploying" msgstr "终止部署" msgid "Deployment cancelled." msgstr "部署已被取消。" msgid "Your AppID is either empty or invalid." msgstr "您的 AppID 为空或无效。" msgid "Export format" msgstr "导出格式" msgid "IP|IP|IP (GoGo Tester/GoAgent format)" msgstr "IP|IP|IP (GoGo Tester/GoAgent 格式)" msgid "New line delimiter" msgstr "以换行分隔" msgid "IP address list" msgstr "IP 地址列表" msgid "Succeeded exporting " msgstr "成功导出" msgid " IP addresses." msgstr "个 IP。" msgid "Failed exporting the IP addresses." msgstr "导出 IP 失败。" msgid "IP list" msgstr "IP 列表" msgid "Success import " msgstr "成功导入 " msgid " IP." msgstr "个 IP。" msgid "Failed importing IP." msgstr "导入 IP 失败。" msgid "Tips" msgstr "提示" msgid "Enable operations usually only needs to be performed once at each device." msgstr "启用操作通常只需要在每台设备上执行一次。" msgid "After changing the server, it takes 10-90 seconds to successfully establish a new teredo tunnel." msgstr "更换服务器后,需要等待 10-90 秒钟才会成功建立新的 teredo 隧道。" msgid "To use teredo tunnel, win user must keep firewall enabled, and allow outbound." msgstr "Win 用户使用 teredo 必须保持防火墙开启,出站放行即可。" msgid "Non-win users can also use the test button to get the fastest server for change manually." msgstr "非 win 用户也可以使用测试按钮来获取响应最快的服务器,以便手动更换。" msgid "Enable" msgstr "启用" msgid "Disable" msgstr "禁用" msgid "Test teredo" msgstr "测试 teredo" msgid "Test teredo usability only" msgstr "仅测试 teredo 可用性" msgid "Test teredo server only" msgstr "仅测试 teredo 服务器" msgid "Change teredo server" msgstr "更换 teredo 服务器" msgid "Switch teredo first" msgstr "切换到 teredo 隧道优先" msgid "Switch origin first" msgstr "切换到原生 IPv6 优先" msgid "Running ..." msgstr "正在执行..." msgid "GAEProxy Log" msgstr "GAEProxy 日志" msgid "Configuration" msgstr "配置" msgid "Deploy Server" msgstr "部署服务端" msgid "Advanced" msgstr "高级" msgid "Refresh" msgstr "刷新" msgid "Failed reading the log." msgstr "读取日志失败。" msgid "Auto-adjust scan thread count" msgstr "自动调整扫描线程数" msgid "How enable" msgstr "如何开启" msgid "Help" msgstr "帮助" msgid "Max scan thread count" msgstr "最大扫描线程数" msgid "AUTO" msgstr "自动" msgid "Force-IPv4" msgstr "仅 IPv4" msgid "Force-IPv6" msgstr "仅 IPv6" msgid "IP range list" msgstr "IP 段列表" msgid "Supporting formats" msgstr "支持格式" msgid "Submit" msgstr "提交" msgid "Scan IP thread is larger than the max number." msgstr "扫描线程数超过最大值。" msgid "Unkown error occurred." msgstr "发生未知错误。" msgid "IPv4 Status" msgstr "IPv4 状态" msgid "IPv6 Status" msgstr "IPv6 状态" msgid "try repair" msgstr "尝试修复" msgid "Good IPv4 Number" msgstr "有效 IPv4 IP 数" msgid "Good IPv6 Number" msgstr "有效 IPv6 IP 数" msgid "XX-Net Status" msgstr "XX-Net 状态" msgid "IP Quality" msgstr "IP 延迟" msgid "Connection Pool" msgstr "连接池" msgid "Browser Proxy Setting" msgstr "浏览器代理设置" msgid "CA status" msgstr "CA 证书状态" msgid "Download" msgstr "下载" msgid "Number of IP-Scanning Threads" msgstr "IP 扫描线程数" msgid "Settings" msgstr "设置" msgid "Block Status" msgstr "屏蔽状态" msgid "XX-Net Version" msgstr "XX-Net 版本" msgid "System Proxy Status" msgstr "系统代理状态" msgid "Listening At" msgstr "代理监听" # msgid "PAC URL" # msgstr "PAC 自动代理地址" msgid "IP mode" msgstr "IP 模式" msgid "LAN proxy" msgstr "前置代理" msgid "working AppIDs" msgstr "工作 AppID" msgid "out-of-quota AppIDs" msgstr "超额 AppID" msgid "not-exist AppIDs" msgstr "无效 AppID" msgid "System Info" msgstr "系统信息" msgid "Diagnostic Info" msgstr "诊断信息" msgid "Check" msgstr "查看" msgid "GitHub issues" msgstr "GitHub 问题讨论区" msgid "or" msgstr "或" msgid "Google Group Discussions" msgstr "Google Group 讨论组" msgid "Show Details" msgstr "显示详细信息" msgid "Post to Github issue needs to sign in your Github account" msgstr "贴到 GitHub 问题区需要登录 GitHub 账号" msgid "GAE Proxy Status Info" msgstr "GAEProxy 状态信息" msgid "" "-----------%0AProblem Description:%0APlease describe your problem, " "running logs may be needed.%0A%0A-----------%0ADiagnostic information:%0A" msgstr "-----------%0A问题描述:%0A请在此描述你遇到的问题,必要时贴出相关的日志信息。%0A%0A-----------%0A诊断信息:%0A" msgid "The status page is empty. Highly likely that " msgstr "状态页显示空白, 很可能 " msgid " failed getting started. Please follow " msgstr " 启动失败, 请按 " msgid "guide" msgstr "指导" msgid " to troubleshoot." msgstr "去解决。" msgid "Your local network failed, please check your network and firewall." msgstr "网络无法连接,请检查网络和防火墙设置。" msgid " not available, Please check." msgstr " 不可用,请检查。" msgid "You may want to $1turn on IP scaner$2." msgstr "您应该考虑$1开启IP扫描器$2。" msgid "" "You can try turn on IPv6 or use X-Tunnel." msgstr "你可以尝试 开启IPv6使用X-Tunnel。" msgid "XX-Net is scanning IP. Please wait about half an hour." msgstr "等待扫描 IP,建议开启 IPv6。" msgid "" "Public AppID out of quota, Please deploy your own AppID." msgstr "公共 AppID 配额已用完,请部署私有 AppID。" msgid "" "Your AppID out of quota, Please deploy more AppID." msgstr "您的 AppID 流量已用完,请部署更多 AppID。" msgid "No working AppID. Please check." msgstr "没有可用 AppID,请检查。" msgid "System is Idle." msgstr "系统空闲。" msgid "Connection not established yet." msgstr "连接尚未建立。" msgid "Please check your browser proxy setting." msgstr "请检查浏览器代理设置。" msgid "Detecting ..." msgstr "正在自检..." msgid "Please import certificates to your browser." msgstr "请导入浏览器 CA 证书。" msgid "" "You are using public AppIDs. You are recommended to deploy your own AppID." msgstr "您正在使用公共 AppID,因为资源有限,使用上存在限制,建议部署私有 AppID。" msgid ", Everything is OK. Welcome to the FREE Internet." msgstr ",一切正常,你可以访问真正的互联网了。" msgid "You are using public AppIDs." msgstr "你正使用公共 AppID。" msgid "new:" msgstr "新:" msgid "h1:" msgstr "" msgid "h2:" msgstr "" msgid "Auto proxy enabled at " msgstr "智能代理已启用:" msgid "Proxy enabled at " msgstr "全局代理已启用:" msgid "Proxy disabled" msgstr "全局代理已禁用" ================================================ FILE: code/default/gae_proxy/local/__init__.py ================================================ from . import apis from . import web_control from . import proxy def is_ready(): return proxy.ready def start(args): proxy.main(args) def stop(): proxy.terminate() ================================================ FILE: code/default/gae_proxy/local/apis.py ================================================ from .front import front, direct_front from xlog import getLogger xlog = getLogger("gae_proxy") def set_proxy(args): front.set_proxy(args) direct_front.set_proxy(args) def _count_conn_num(): return len(front.connect_manager.new_conn_pool.pool) +\ front.http_dispatcher.h1_num + \ front.http_dispatcher.h2_num def is_workable(): #if front.http_dispatcher.is_idle(): # return True if _count_conn_num() > 0: return True else: front.http_dispatcher.get_worker() return _count_conn_num() > 0 def set_bind_ip(args): xlog.info("set_bind_ip:%s", args) front.config.listen_ip = args["ip"] front.config.save() ================================================ FILE: code/default/gae_proxy/local/appid_manager.py ================================================ #!/usr/bin/env python # coding:utf-8 import random import threading import time import os from front_base.random_get_slice import RandomGetSlice current_path = os.path.dirname(os.path.abspath(__file__)) class AppidManager(object): lock = threading.Lock() def __init__(self, config, logger): self.config = config self.logger = logger self.check_api = None self.ip_manager = None fn = os.path.join(current_path, "appids.txt") self.public_appid = RandomGetSlice(fn, 60) self.reset_appid() def reset_appid(self): # called by web_control with self.lock: self.working_appid_list = list() for appid in self.config.GAE_APPIDS: if not appid: self.config.GAE_APPIDS.remove(appid) continue self.working_appid_list.append(appid) self.not_exist_appids = [] self.out_of_quota_appids = [] self.last_reset_time = time.time() def get(self): if len(self.config.GAE_APPIDS): if len(self.working_appid_list) == 0: time_to_reset = 600 - (time.time() - self.last_reset_time) if time_to_reset > 0: self.logger.warn("all appid out of quota, wait %d seconds to reset", time_to_reset) sleep_end = time.time() + time_to_reset while len(self.working_appid_list) == 0 and time.time() < sleep_end: time.sleep(1) return None else: self.logger.warn("reset appid") self.reset_appid() appid = random.choice(self.working_appid_list) return str(appid) else: for _ in range(0, 10): appid = self.public_appid.get() if appid in self.out_of_quota_appids or appid in self.not_exist_appids: continue else: return appid return None def report_out_of_quota(self, appid): self.logger.warn("report_out_of_quota:%s", appid) with self.lock: if appid not in self.out_of_quota_appids: self.out_of_quota_appids.append(appid) try: self.working_appid_list.remove(appid) except: pass def report_not_exist(self, appid, ip): self.logger.debug("report_not_exist:%s %s", appid, ip) th = threading.Thread(target=self.process_appid_not_exist, args=(appid, ip), name="process_appid_not_exist") th.start() def process_appid_not_exist(self, appid, ip): ret = self.check_api(ip, "xxnet-1") if ret and ret.ok: self.set_appid_not_exist(appid) else: self.logger.warn("process_appid_not_exist, remove ip:%s", ip) self.ip_manager.report_connect_fail(ip, force_remove=True) def set_appid_not_exist(self, appid): self.logger.warn("APPID_manager, set_appid_not_exist %s", appid) with self.lock: if appid not in self.not_exist_appids: self.not_exist_appids.append(appid) try: self.config.GAE_APPIDS.remove(appid) except: pass try: self.working_appid_list.remove(appid) except: pass def appid_exist(self, appids): for appid in appids.split('|'): if appid == "": continue if appid in self.config.GAE_APPIDS: return True return False ================================================ FILE: code/default/gae_proxy/local/appids.txt ================================================ 1-dot-api-project-959547526753 1-dot-fishding-001 1-dot-fishding-002 1-dot-fishding-003 1-dot-fishding-004 1-dot-fishding-005 1-dot-fishding-006 1-dot-fishding-007 1-dot-fishding-008 1-dot-fishding-009 1-dot-fishding-010 1-dot-fishding-011 1-dot-fishding-012 1-dot-fzongkkkk-1114 1-dot-myzoo-185116 1-dot-nangua0002 1-dot-ningerte004 1-dot-one1-178105 1-dot-one10-178105 1-dot-one11-178105 1-dot-one12-178105 1-dot-one2-178105 1-dot-one3-178105 1-dot-one4-178105 1-dot-one5-178105 1-dot-one6-178105 1-dot-one7-178105 1-dot-one8-178105 1-dot-one9-178105 1-dot-openvpn-helloworld 1-dot-wangwei2017-168512 1-dot-xx-net-01-216008 1-dot-xx-net-155804 1-dot-xx-net-202106 1-dot-xx-net-215409 1-dot-xx-net-8-233015 1-dot-xx-net1-189816 1-dot-xx-net1-paper 1-dot-xx-net2-paper 1-dot-xxnet-01-212704 1-dot-xxnet-20171001 1-dot-xxnet-20180218 1-dot-xxnet-209400 1-dot-xxnet-xhyproject 1-dot-xxnet4ae01 1-dot-xxnet4paper 1-dot-xyyaoxin 1-dot-zippy-rarity-179110 109744884a 13664191203zl 1rrgfre 34e-6y 8487753 8ziw2rt7 a-6332450 a0411641 a0411642 a0411643 a0411644 a0411645 a0411646 a04116471 a04116481 a0411649 a0411650 a0411684 a0411685 a0411686 a0411687 a0411688 a0411689 a0411690 a0411691 a0411692 a41200421 a514987111 a790412405 a82943658 a837036615 aa514987111 aaa514987111 aaaa514987111 aaaaa514987111 aaaaaa-159813 aaaaaaaaa-159813 abc555-214808 abcdff-1 abcdff-2 abcdff-3 abcdff-4 abcdff-5 abiding-cycle-243802 abiding-sunset-201306 able-groove-187110 able-involution-123514 abneimenggu abstract-tract-187808 academic-atlas-149814 academic-atlas-235917 academic-notch-233214 acoustic-bridge-859 acoustic-welder-191202 acquired-backup-212108 activationitrogen activationitrogen2 activationitrogen9 active-campus-216915 adept-crossing-215102 adept-depth-189010 adept-elevator-183105 adept-primacy-191106 adfrog1-152805 adfrog2 adfrog3-152805 adfrog4 adfrog5-152805 adroit-solstice-218302 advance-casing-181213 advance-stratum-226713 aerial-anagram-180703 aerobic-library-225500 affable-audio-859 affable-beaker-189008 agile-skyline-247301 agile-sprite-152707 ai-sentoisuzu airy-ceremony-184318 airy-machine-123514 airy-torus-232908 akakljf115-12 akecheta alert-basis-184913 algebraic-creek-201306 algebraic-depot-170705 alibaba-wangchong-147606 alibaba-wangchong6 alibaba-wangchong8 alibaba-wangchong9 alien-array-241811 alien-paratext-155412 allah-001a allah-001b alpine-air-123504 amiable-flames-189700 analog-crossing-228003 analog-subset-243305 androidproxyforcui andyddy126 aneimenggu angelic-artwork-205801 angyrgoagent9 animated-scope-189703 animated-zenith-859 ankangsex anlahao-159813 annihilation21 anti-wand1 anti-wand2 anti-wand21 anti-wand22 anti-wand23 anti-wand24 anti-wand25 anti-wand26 anti-wand27 anti-wand28 anti-wand29 anti-wand3 anti-wand30 anti-wand31 anti-wand32 anti-wand4 anti-wand5 anti-wand6 anti-wand7 anti-wand8 anti-wand9 anti-wandiix anti-wandx anti-wandxi aotuman-51396 aotuman-513961 aotuman-513962 api-project-256541348713 api-project-338155433549 api-project-855063073479 api-project-8691297067 app12345-149811 app123456-149811 app1234567-149811 app19820220 app19820221 app19820222 app19820223 appid-01-189210 appid-02-161702 appid-03-161702 appid-04-161702 appid-05-161907 appid-06-161907 appid-07-161907 appid-08-161907 appid-09-161907 appid-1-192801 appid-10-161912 appid-11-161912 appid-12-161912 appid-2-192801 appid-3-192801 appid-4-192801 appid-5-192801 appid-6-192801 appid0-174506 appid0-174905 appid1-174506 appid1-174905 appid10-174506 appid10-174905 appid11-174506 appid11-174905 appid2-174506 appid2-174905 appid3-174506 appid3-174905 appid4-174506 appid4-174905 appid5-174506 appid5-174905 appid6-174506 appid6-174905 appid7-174506 appid7-174905 appid8-174506 appid8-174905 appid9-174506 appid9-174905 appjian08225 appjianguo0822 applied-pipe-192704 applied-pursuit-218209 appliss-146309 apt-decorator-163211 apt-subset-113123 arctic-analyzer-236503 arctic-math-146309 arctic-maxim-142514 ardent-curve-190608 argon-ace-180703 argon-gear-119613 artful-logic-203109 artful-reactor-233108 arvin13408100205 ascendant-bloom-171907 assgfwhole assgfwhole2 assgfwhole3 assgfwhole4 assgfwholenew assgfwholenew1 assgfwholenew2 astral-digit-151605 astral-sorter-217505 astute-baton-184209 astute-diode-189007 astute-diode-233015 astute-task-135723 astute-veld-164609 astute-winter-186909 asxx-1 asxx-10 asxx-11 asxx-12 asxx-2 asxx-3 asxx-4 asxx-5 asxx-6 asxx-7 asxx-8 asxx-9 atlantean-depth-248804 atomic-horizon-232307 atomic-matrix-188715 august-tract-169300 automan-513963 automan-513964 automan-513965 automan-513966 automated-rune-187715 automatic-rite-238714 awesome-flash-148607 axial-history-105113 axial-sunup-191202 baba-208615 balmy-cab-232002 balmy-coral-211906 balmy-renderer-153407 balmy-renderer-191106 banded-nimbus-138308 bang-166903 baobao-189715 basic-perigee-193312 bbneimenggu bbszzf bbtvjs2013 bccccccc09 bccccccc10-185400 bcmtester0 bcmtester1 bcmtester2 bcmtester3 be02wz bear940214 bear9402140 bear9402141 bear9402142 bear9402143 bear9402144 bear9402145 bear9402146 bear9402147 bear9402148 bear9402149 bear940325 beckzf9 beijihu129 beyond6679 big-coil-859 big-depth-186703 binjing101010 binjing333 binjing444 binjing555 binjing666 binjing777 binjing888 binjing999 binjoo-xxnet-1-01 binjoo-xxnet-1-02 binjoo-xxnet-1-03 binjoo-xxnet-1-04 binjoo-xxnet-1-05 binjoo-xxnet-1-06 binjoo-xxnet-1-07 binjoo-xxnet-1-08 binjoo-xxnet-1-09 binjoo-xxnet-1-10 binjoo-xxnet-1-11 binjoo-xxnet-1-12 biomeitroic16 bionic-comfort-158112 bionic-genre-214609 bivozeou black-abode-126006 black-abode-187110 blissful-mantis-242711 blissful-sun-152204 bluesailcn06 bluesailcn07 bluesailcn08 bluesailcn09 bluesailcn10 bluesailcn11 bmqe-143715 bmqe-143716 bmqe-143717 bmqe-143718 bmqe-143719 bmqe-143720 bneimenggu bnujazz bold-camera-192906 bold-physics-859 bonew80 bonnyshenvpn bonnyshenvpn-001 bonnyshenvpn-002 bonnyshenvpn-003 bonnyshenvpn-004 bonnyshenvpn-005 bonnyshenvpn-006 bonnyshenvpn-007 bonnyshenvpn-008 bonnyshenvpn-009 booming-alchemy-123514 booming-coast-150311 boulder-158315 boxwood-axon-133123 boxwood-office-208211 boxwood-valve-208507 boy1039459398 brachio112 brachio113 brachio114 brachio115 brachio116 brachio118 brachio119 braided-rush-212512 brave-aileron-193713 brave-embassy-194208 breakqiang751 bright-karma-188116 bright-practice-187913 bronzemonster1 bronzemonster2 bronzemonster3 bslzr003-174918 bujizhicai bujizhicai1 bujizhicai10 bujizhicai11 bujizhicai2 bujizhicai3 bujizhicai4 bujizhicai5 bujizhicai6 bujizhicai7 bujizhicai8 bujizhicai9 buoyant-braid-186612 buoyant-braid-193713 buoyant-operand-199608 burnished-web-191106 bwg1991 bypassgfw-1374 bypassgfw2-1374 bypassgfw3-1374 bypassgfw4-1374 c123123eeeee c123123fffff c123123ggggg calcium-adapter-125209 calcium-adapter-192106 calcium-backup-257701 calixcms1 calixcms2 calm-drive-186612 calm-edge-859 calm-history-153512 caocao595 caocaocao485 caocaocao595 caocaocaocao485 caocaocaocao595 caocaocaocaocao485 caocaocaocaocao595 caocaocaocaocaocao595 caojinsheng123 caojinsheng123456 caojinsheng1234567 caojinsheng12345678 caojinsheng123456789 caojinsheng1234567890 caojinsheng12345678901 car-10-229009 car-11 car-12-229009 car-4-229009 car-9-229009 car-d-229009 car3-229009 car5-229009 car6-229009 car7-229009 car8-229009 caramel-core-249206 caramel-limiter-138023 caramel-pager-197708 caramel-theory-123504 carbide-bonsai-115805 carbon-feat-124818 careful-compass-178405 careful-flow-214609 catpapa0507 catpapa0508 catpapa0509 catpapa0510 catpapa0511 catpapa0513 causal-benefit-242612 causal-temple-212406 cbneimenggu ccdream6501 ccdream6502 ccdream6503 ccdream6504 ccdream6505 ccdream6506 ccdream6507 ccdream6508 ccdream6509 ccdream6510 ccdream6511 ccdream6512 ccdream6513 cedar-abacus-187913 cedar-helper-192506 cedar-shape-188411 celestial-gist-171813 celestial-now-242006 cellular-block-133123 cellular-codex-187205 cellular-gift-184212 celtic-bazaar-122813 cen000001 central-cinema-208808 central-diagram-209014 central-node-151605 cgw19920930 cgwfifa changzhou-194902 changzhou-194903 changzhou-194904 changzhou-194905 changzhou-194906 chaoji000011 chaoji000012 charged-audio-187002 charged-hub-214609 charged-kiln-105204 charles001 charles002 charles003 charles004 charles005 charles006 charles008 charles009 charles010 charles011 charlie-xxnet01 cheathao cheathaob cheathaof cheathaog cheathaoh cheathaoi cheletong-151301 chengchongfan chengchongfan10 chengchongfan2 chengchongfan3 chengchongfan4 chengchongfan5 chengchongfan6 chengchongfan7 chengchongfan8 chengchongfan9 chengjm7619 chenjiaan230 chenjiaan240 chenjiaan250 chenjiaan333 chenjiaan456 chenjiaan555 chenjiaan666 chenjiaan777 chenjiaan888 chenjiaan999 chenqun0411 chenqun0412 chenqun0413 chenqun0414 chenqun0415 chenqun0416 chenqun0417 chenqun0418 chenqun0419 chenqun0420 chenqun0421 chenqun0423 chenqun0424 chenqun0425 chenqun0426 chenqun0427 chenxiyuan1988 chinazhou110 chinazhou112 chinazhou113 chinazhou114 chinazhou115 chinazzlfz chiuhum-appid-10 chiuhum-appid-11 chiuhum-appid-12 chiuhum-appid-7 chiuhum-appid-8 chiuhum-appid-9 chnmc-2132312 chnmc-213503 chnmc-213504 chnmc-6165d chnmc-651652 chome-218209 chrome---1231 chrome---1234 chrome--1231 chrome--1234 chrome-06 chrome-07 chrome-08 chrome-09 chrome-10 chrome-11 chrome-12 chrome-1231 chrome-1231-1231 chrome-1234 chrome-courage-223709 chrome-epigram-125209 chrome-sphere-213503 chrome-unity-146010 chrome0-1234 chrome0-1239 chrome1-1209 chrome1-1234 chrome10-1209 chrome10-1239 chrome11-1209 chrome11-1239 chrome12-1209 chrome2-1209 chrome2-1234 chrome2-1239 chrome26-1100 chrome27-1100 chrome28-1100 chrome29-1100 chrome3-1209 chrome3-1234 chrome3-1239 chrome30-1100 chrome4-1209 chrome4-1234 chrome4-1239 chrome5-1234 chrome5-1239 chrome6-1209 chrome6-1234 chrome6-1239 chrome7-1234 chrome7-1239 chrome8-1234 chrome8-1239 chrome9-1239 chunlong-148607 cindy-01 cindy-02 cindy-03 civic-origin-221514 civil-sprite-211501 civil-victory-186402 cjnjesus01 cjnjesus02 cjnjesus03 cjnjesus04 cjnjesus05 cjnjesus06 cjnjesus07 cjnjesus08 cjnjesus09 cjnjesus10 cjnjesus11 cjnjesus12 clean-yew-123504 clean-yew-167204 clear-column-187715 clear-practice-213002 clever-bee-146713 clever-cortex-149703 clever-cortex-187715 clj156024 clj156025 clj156026 clj156027 clj156028 cloudfra-fjl10 cloudpower-7 cmccc-180801 cneimenggu cnonegae coastal-mercury-177513 cobalt-sector-123504 codetimes-2 codetimes-2017 codetimes-9 codingtiming cogent-quarter-208808 cogent-silicon-133123 coherent-acre-227309 coherent-window-196502 cohesive-idiom-183908 cohesive-keel-214609 cohesive-link-234103 commanding-mix-240201 compact-life-123504 composed-maxim-187205 composite-haiku-132302 composite-rhino-213503 composite-sun-160715 concise-beanbag-120316 concise-cinema-213002 concise-crane-146713 concise-slate-208609 concise-upgrade-217406 confident-key-170508 confident-sweep-187715 cool-continuity-122814 copper-sunspot-254717 copper-tempo-189502 coral-mariner-221514 coral-muse-122814 corded-academy-189703 corded-cortex-242711 corded-smithy-192108 corded-sunlight-166909 core-incentive-241905 cosmic-descent-107908 cosmic-descent-204510 cosmic-gizmo-243106 cowardsage-1470373969510 cozy001250 cpcp6100 cpproxy06 cpproxy07 cpproxy08 cqmh-2016-0610 cqmh-2016-0610-2309 cquptyc crack-muse-151706 crack-photon-232002 crafty-automata-189502 crafty-shield-183514 crazyliting10 crazyliting11 credible-cosine-127307 credible-list-201914 credible-torus-210602 crested-climber-192112 crested-polygon-187205 cryptic-lattice-123514 crypto-galaxy-257701 cugwxt cugwxt2018 cugzb-xx-net cuiduke1 cuiduke10 cuiduke11 cuiduke12 cuiduke2 cuiduke3 cuiduke4 cuiduke6 cuiduke7 cuiduke8 cuiduke9 curious-framing-184318 curious-memory-122814 curious-nucleus-191106 custom-rampart-186612 custom-tine-189010 cwj5814 cwj6714 cwj7714 cwj9714 cxinjia100 cxinjia110 cxinjia120 cxinjia130 cxinjia140 cxinjia150 cxinjia160 cxinjia170 cxinjia180 cxinjia190 cxinjia200 cxinjia210 cxinjia220 cxinjia230 cxinjia240 cxinjia250 cxinjia260 czechrepublic-182402 czyuan93 d-xx-net-1 d-xx-net-2 da-feiji da27149-1 daaikuaiji dadsdasdw dageini dakadklf dark-safeguard-151605 darkzgoagent101 darkzgoagent102 darkzgoagent103 darkzgoagent104 darkzgoagent105 darkzgoagent106 darkzgoagent107 darkzgoagent108 darkzgoagent109 darkzgoagent110 darkzgoagent111 darkzgoagent112 data-media-170706 data-totality-226108 davie1256 daviebear55 dawnlcx-168802 dazzling-ocean-208808 dbneimenggu dcshengz dcshenjx ddd-gae10 ddnnff ddyxhj decent-terra-217505 decoded-doodad-184318 decoded-pilot-223802 deeevilyu-8801 deeevilyu-8802 deep-mile-227309 deft-falcon-186402 deft-falcon-244606 deft-ocean-232002 deft-smile-213002 deft-waters-192112 delta-surface-107908 delta-wonder-227614 depplyloveu22 desire-legend desire-legend2 desire-legend3 desire-legend4 desire-legend5 desire-legend6 desire-legend7 desire-legend8 desire-legend9 desirelegend02 desirelegend03 desirelegend04 desirelegend05 desirelegend06 desirelegend07 desirelegend08 desirelegend09 desirelegend1 desirelegend10 deyidong diafe-181623 diao82017 diaobaz diary-1470053225438 didididw diesel-acolyte-218802 direct-terminal-205201 disablegfw disco-skyline-208808 divine-descent-242711 dmiflyvpn11 dneimenggu docker-187703 dogwood-goods-242711 doit1-142709 doit2-142709 doit3-142709 doit4-142709 doit5-142709 dominica-189005 dona1-185012 donate-153512 donate-5438 donate-for-xx-net donate-xxnet donate1-191205 donate10-191205 donate11-191205 donate12-191205 donate13-191205 donate14-191205 donate15-191205 donate16-191205 donate17-191205 donate18-191205 donate19-191205 donate2-1265 donate2-191205 donate20-191205 donate2017042401 donate2017042402 donate2017042403 donate2017042404 donate2017042405 donate21-191205 donate22-191205 donate23-191205 donate24-191205 donate25-191205 donate26-191205 donate27-191205 donate28-191205 donate29-191205 donate3-1265 donate3-191205 donate30-191205 donate4-1265 donate4-191205 donate5-1265 donate5-191205 donate6-191205 donate7-191205 donate8-191205 donate9-191205 donatetoxxnet donatexxnet1 donation01-196903 donation02-196903 donation03-196903 donation04-196903 donation05-196903 donation06-196903 donation07-196903 donation08-196903 donation09-196904 donation1 donation10-196904 donor-153401 donor1-153401 donor2-153401 dopsy50 dospytang11 dospytang12 dospytang13 dotted-banner-210602 dotted-task-213002 double-venture-133123 dreain-goagent dreain-goagent2 dreain-gogent3 driven-seer-189703 drwangyd8 drwangyd9 drxxnet1 drxxnet2 drxxnet3 drxxnet4 drxxnet5 drxxnet6 dsetng10 dsetng6 dsetng7 dsetng8 dsetng9 duanyu20061994 dujingxiu-147503 dulcet-bastion-106015 dulcet-bucksaw-123514 durable-bond-181103 durable-syntax-194202 dv23d-142511 dxxnet-1 dynamic-cooler-187503 dynamic-cove-239106 dynamic-hybrid-242612 e-lexicon-123514 e-night-125209 e1574559475 earnest-pact-227309 eastern-amp-226408 eastern-stock-168012 ebneimenggu ecg-test eco-layout-195404 ecstatic-fiber-213002 eddy-chiang effective-light-243106 eighth-epsilon-184613 eighth-pen-200303 elated-gizmo-197708 elated-guild-213002 elated-practice-123515 elfive-donateproject-01 elfive-donateproject-02 elfive-donateproject-03 elfive-donateproject-04 elfive-donateproject-05 elfive-donateproject-06 elfive-donateproject-07 elfive-donateproject-08 elfive-donateproject-09 elfive-donateproject-10 elfive-donateproject-11 elfive-donateproject-12 elite-ceremony-167205 elite-name-184603 elliptical-flow-195404 elvis-agl elvis-br em2qhc emerald-ellipse-194808 emy3qg encoded-region-138323 endless-lamp-106710 enduring-button-223912 enduring-coil-186715 enduring-lane-232002 eneimenggu enhanced-gizmo-184213 erdrfn erdrfn1 erdrfn11 erdrfn111 erdrfn1111 erdrfn11111 ersae-181623 ersxs-181623 esoteric-accord-201111 esoteric-life-191107 essential-graph-186112 essential-storm-204406 essential-text-146309 essential-truth-189502 essential-wares-239207 eternal-coral-228003 eternal-empire-188701 eternal-impulse-201306 eternal-outlook-123504 even-scheduler-192108 evic-197614 evident-etching-208503 evident-theory-186402 exalted-ability-170706 exalted-splicer-221514 excellent-tide-213002 exemplary-torch-257701 expanded-genius-243611 f1574559475 f4cj9q fabled-progress-233214 fackgfw1028 fair-hallway-187002 faker-166903 fakexijinping fakezhouyongkang famous-charge-123515 famous-gearing-187002 fan1-143906 fan2-143907 fanfanqiangming fangqiang-207615 faniver98 faniver99 fanqiang161 fashionnew2083st003xt favorable-bolt-200303 favorable-iris-162705 fb0087-1274 fb12011024 fb120110241 fb120110242 fb120110243 fb120110244 fb120110245 fbneimenggu feel-1370 feel-1371 feisty-current-122813 feisty-current-170308 feisty-reporter-207606 ferrous-depth-215910 festive-radar-210100 festive-tiger-237602 fffffffff-142308 fgdhsjak12345 fgdhsjak132 fgrtd-1 fiery-iridium-187212 fifth-being-127312 fire201401 firecola1 firm-vertex-228514 first-10001 first-73017 first-hearth-192112 first-planet-243106 first-tine-148607 first-tracer-242006 fit-asset-215910 fit-authority-231609 five-10005 fixyou-158112 fk-xxnet-01 fk-xxnet-02 fk-xxnet-03 fk-xxnet-04 flash-cache-186402 flash-moonlight-123504 flash-moonlight-123803 flash-sol-225607 fleet-acumen-214609 fleet-muse-143000 fluent-ego-212910 fluid-brook-212406 fluid-fiber-170209 fluted-ranger-188715 flygaes1 fms-test-171708 fneimenggu fnshiwu21 fnshiwu22 fnshiwu23 fnshiwu24 focal-charge-127023 focused-outlook-198215 folkloric-stone-123514 for-friends for-yaya formal-branch-258214 formal-landing-171813 formidable-gate-214906 formidable-pact-221514 forusa2021 forward-pad-123803 forward-scion-152204 forward-server-109414 forxxnet-156508 forxxnet-156508a forxxnet-156508b forxxnet-156508c forxxnet-156508d forxxnet-156508e forxxnet-156508f forxxnet-156508g forxxnet-156508h forxxnet-156508i forxxnet-156508j forxxnet-156508k four-10004 fourth-caster-186402 fourth-library-188412 fourth-walker-123515 foxpro-001 foxpro-002 foxpro-003 foxpro-004 foxpro-005 foxpro-006 foxpro-007 foxpro-008 foxpro-009 foxpro-259503 fqlbshen fqlbshenv2 fqlbshenv3 fqrote1 fqrote2 fqrote3 fqrote4 free-227202 free1-227202 free198228 freedom-00005 freeyangzhihui10 freeyangzhihui11 freeyangzhihui12 freeyangzhihui6 freeyangzhihui7 freeyangzhihui8 freeyangzhihui9 fresh-arcade-208808 fresh-forest-243513 fresh-media-186103 fresh-oath-164207 fresh-ward-162011 friendly-magnet-168105 frog-pig fuba088-1274 fucjeektd fupengnet1 fupengnet2 fupnet3 fupnet4 fupnet5 fupnet6 fupnet7 fupnet8 future-area-163914 future-synapse-123514 fuyexifei9 fzong-1108 fzong-1114 fzongaaa fzongbbb fzongccc fzongfff fzongggg fzonghhh fzongjjj fzongkkkk-1114 fzongmmm fzongnnn fzongsss fzongxcf fzongxxx fzy930 g-1222 gaedonate001 gaedonate002 gaedonate003 gaedonate01 gaedonate02 gaedonate03 gaedonate04 gaedonate05 gaeproxy-1336 gaewb14 gaewb141 gaewb142 gaewb143 gaewb144 gaewb145 gaewb146 gaewb147 gaewb148 gaewb149 galvanized-case-123515 galvanized-case-170706 gap7b01 gap7b02 gap7b03 gap7b04 gap7b05 gap7b06 gap7b07 gap7b08 gap7b09 gap7b10 gap7b11 gap7b12 gap7b13 gap7b14 gap7b15 gap7b16 gap7b17 gap7b18 gap7b19 gap7b20 gate-188212 gbneimenggu gcdsb3 gcdsb4 gcdsb6 gcdsb7 gcdsb8 gdl-go1 gdl-go2 gdl-go3 gdl-go4 gdl-go5 gdl-go6 gdq207590122 gdswcom1 gdswcom2 gdswcom3 genial-cycling-192108 genial-reporter-184705 genial-stage-217017 genuine-essence-174401 geometric-hull-142604 geometric-shine-181213 geometric-vim-232002 getout-share gfw-yes01 gfw10-175208 gfw10-179913 gfw11-179913 gfw6-179913 gfw7-179913 gfw8-179913 gfw9-179913 gfwed-1 gfwed-10 gfwed-11 gfwed-12 gfwed-152305 gfwed-169300 gfwed-2 gfwed-3 gfwed-4 gfwed-5 gfwed-6 gfwed-7 gfwed-8 gfwed-9 gfwfighter001 gfwfighter002 gfwfighter003 gfwfighter004 gfwfighter005 gfwfighter006 gfwfighter007 gggggggggg-142308 ggttd2-1158 gh778-189715 ghq214101 ghq214201 ghq214301 ghq214401 ghq214501 ghq214601 ghq214701 ghq214801 ghq214901 ghr-65 gifted-veld-214609 glass-scanner-167416 glass-stratum-162012 glassy-keyword-859 glassy-vial-122813 glossy-monitor-188715 glowing-baton-258917 gneimenggu goagent-157515 goagent-freeweb goagent1-996 goagent10-157607 goagent11-157607 goagent2-157607 goagent2109 goagent3-157607 goagent4-157607 goagent5-157607 goagent6-157607 goagent7-157607 goagent9955 goagentunderwood goagentv320g goagentv320h goagentv320i goagentv320j goagentxx1 godlikejjyy godlovevpn godlovevpn2 godlovevpn2-169003 godlovevpn3 godlovevpn3-169003 godness-149611 gogo-1292 gold-chess-208703 gold-gearbox-209903 gold-mode-142708 golden-imprint-188912 googae005 goproj-177307 goproxy-a goproxy-b goproxy-c gplin1991-188809 gr45-8 graceful-castle-206711 graceful-ratio-242006 grand-bridge-215910 graphic-theory-125209 graphical-bus-221514 graphical-bus-232304 greatgfw4 gree-20125 gree-20126 gree-20127 gree-20128 gree-20129 green-154700 groovy-design-187913 groovy-patrol-122814 groovy-reserve-256906 grwaitting-244303 grwaitting10 grwaitting11 grwaitting3 grwaitting5 grwaitting6 grwaitting7 grwaitting8 grwaitting9 grwatting2 guogoagent06 guojian0822 guoyangdominating guweishi2b guxizhao1 guxizhao10 guxizhao11 guxizhao12 guxizhao13 guxizhao14 guxizhao2 guxizhao4 guxizhao5 guxizhao6 guxizhao7 guxizhao8 gxfagent3 haha-1007 hahaneimenggu hahazhej halfpaid halfpaid-167105 halogen-goods-243016 halogen-premise-167105 handatouftvpn hanxiao-148607 haodee-146208 haolen-1805 haolen-1806 haolen-1807 haolen-1808 haolen-1809 hardy-thinker-213501 hasaki-187702 hawyrihby hazel-quanta-186402 hbkechen001 hbkechen002 hbkechen003 hbkechen004 hbkechen005 hbkechen006 hbkechen007 hbkechen008 hbkechen009 hbkechen010 hbkechen011 hbkechen012 hbneimenggu healthy-bonsai-240209 healthy-highway-125209 healthy-life-180703 healthy-wares-202206 healthy-zone-237305 heihei-1183 helical-beaker-187715 helical-indexer-187508 helical-land-133123 helical-study-257701 hello-b9a3c helloworld-140114 helloworld-165114 helloworld-187709 helloworld1-187615 helloworld10-188607 helloworld11-188607 helloworld4-187615 helloworld6-187615 helloworld7-187615 helloworld8-187615 helloworld9-188607 helpful-ally-123514 helpful-ally-133123 helpful-quanta-170209 helpful-reactor-205203 hendry001-154114 hengye-1270 hepeng5970 hepeng59700 hfldnt00 hfldnt01 hfldnt02 hfldnt03 hfldnt04 hfldnt05 hfldnt06 hfldnt07 hfldnt08 hfldnt09 hfldnt10 hfldnt11 hhhhh-144412 hhhhh19910926 hhhhhh-144412 hhhhhhhh-142308 hidden-solstice-229902 himon-20172 himon-20173 himon-20174 hip-fusion-224007 hip-spanner-235306 hixcjj hl150423175 hmsfeng20 home-149008 home1-175814 honkerjha003 honkerjha004 honkerjha005 honkerjha006 horizontal-ring-133123 houhou-1183 houweixiao9 huangzhengjun4 huangzhengjun6 huangzhengjun7 huangzhengjun8 huangzhengjun9 huyubo1 huyubo11 huyubo12 huyubo13 huyubo2-150311 huyubo3 huyubo4 huyubo6 huyubo7 huyubo8 hxd-project02 hybrid-text-170706 hypdreamandlove hypdreamandlove1 hypdreamandlove2 hypdreamandlove3 hypdreamandlove4 hypdreamandlove5 hypdreamandlove6 hypdreamandlove7 hypdreamandlove8 hypdreamandlove9 hypnotic-guard-177622 hzc-net10 hzc-net9 hzjxxnet01d hzjxxnet01e hzjxxnet01f hzjxxnet01g hzjxxnet01h hzjxxnet01i hzjxxnet01j hzjxxnet01k hzjxxnet01l-1273 i-beaker-189715 i-condition-232603 i-freedom-205914 iaeegdj10 ibneimenggu icean1025 idyllic-aspect-231106 igneous-primacy-192906 igneous-study-197708 ilinxi-0001 ilinxi-0002 ilinxi-0003 ilinxi-0004 ilinxi-0005 imacatt-1470053327056 imadog-1470053319075 imperial-glyph-123514 imperial-signer-226806 import-187703 imposing-cinema-215910 inbound-fulcrum-207606 inbound-lattice-213503 inbound-pattern-227309 indigo-plate-215910 infra-ratio-127310 infra-sublime-233214 infra-window-190710 innate-octagon-120813 innate-summit-123514 inner-autonomy-183914 inner-legacy-186402 integral-glass-257701 integral-surfer-249613 intense-nexus-189703 intense-pointer-236313 involuted-reach-107908 iron-area-123514 iron-potion-142510 ironic-objectivist-233214 isaac-12 isentropic-road-146309 ivan-shu ivanshuchen iview-65949 ivory-partition-137323 ivory-volt-242306 iwantto-184200 iyft-hws150 jackcp9-19930218-10 jackcp9-19930218-11 jackcp9-19930218-7 jackcp9-19930218-8 jackcp9-19930218-9 jackey001-1181 jackieqqh jackieqqh01 jackieqqh02 jackieqqh03 jackieqqh04 jackieqqh05 jackieqqh06 jackieqqh07 jackieqqh08 jackshao101 jackshao102 james-goagent21 james-goagent22 james-goagent23 james-goagent24 james-goagent25 jameswang-196304 jazuwisa27 jeffluo35 jemmibo2 jemmibo3 jhgkf-232603 jia4-166810 jiangyue111222 jiangzemindashab2 jingtao-001 jiuaiping jiustsos joehello-218304 joeljoel-174906 joeljoel-183810 johnnnn-1470053192524 johntongoagentpublic2 jonewangzai joson-167406 josonchan-167220 juanxian-0001 juanxian-0002 juanxian-0003 juanxian-0004 juanxian-0005 juanxian-0006 juanxian-0007 juanxian-0008 juanzeng-1 juanzeng-10 juanzeng-11 juanzeng-12 juanzeng-13 juanzeng-14 juanzeng-15 juanzeng-2 juanzeng-3 juanzeng-4 juanzeng-5 juanzeng-6 juanzeng-7 juanzeng-8 juanzeng-9 july1-1383 juqn-67440 just-duality-226602 justatest-1470053639545 jw-xxnet002 jxsj-123654 jygxxnet0145 jz1-1234567 jz3-1234567 jz4-1234567 jz5-1234567 jzid-191123 jzxm01-142511 jzxm02 keecolite keecolite1 keecolite2 keecolite3 keecolite4 keecolite5 keecolite6 keecolite7 keecolite8 keecolite9 keen-device-151402 kevin1990-191616 kevinyang-191616 kexueshangwang12-158014 key-affinity-859 key-chalice-192704 key-prism-207507 kfeimaro6 khan-1134 killgfw-004 killgfw-005 killgfw-006 killgfw-007 killgfw-008 killgfw-009 killgfw-010 killgfw-011 killgfw-012 kimpaygoa kinetic-center-197409 kinetic-cosmos-159409 kingdog807 kingdog808 kingdog818 kingdog828 kingdog838 kingdog858 kingdog868 kingdog878 kingdog898 kingdog899 kingdog910 kingdog912 kingdog913 kingdog914 kingdog915 kingdog916 kingdog918 kingdog919 kingmax-1245 kinopakuyumen kiss4-201914 kk92fortune001 kk92fortune002 kk92fortune003 kk92fortune004 kk92fortune005 kk92fortune006 kk92fortune007 kk92fortune008 kk92fortune009 kk92fortune010 kouyt-232603 ksdcjf ksmksm7900-01 kt-1001 kuailezhaoze kuailezhaoze01 kuailezhaoze101 kuailezhaoze102 kuailezhaoze103 kuailezhaoze104 kuailezhaoze105 kurisu-190106 kwanlily-146010 kwchen-208615 kxsw-88888801 kxsw-88888802 kxsw-88888803 kxsw-88888804 kxsw-88888805 kxsw-88888806 kxsw-88888807 kxsw-88888808 kxsw-88888809 kxsw-88888810 kyo9950 kzsj-xx-net-06 kzsj-xx-net-07 kzsj-xx-net-08 kzsj-xx-net-09 kzsj-xx-net-10 lady-160402-1 lady-160402-10 lady-160402-12 lala-1183 lateral-booster-232002 lateral-concord-187913 lateral-faculty-205006 leafy-environs-142014 leafy-ripsaw-151605 learned-cosine-208808 learned-house-143412 learned-iris-188715 leejaewan-166903 leidilldd1 leidilldd10 leidilldd11 leidilldd12 leidilldd13 leidilldd14 leidilldd15 leidilldd16 leidilldd17 leidilldd18 leidilldd19 leidilldd2 leidilldd20 leidilldd21 leidilldd22 leidilldd23 leidilldd24 leidilldd25 leidilldd3 leidilldd4 leidilldd5 leidilldd6 leidilldd7 leidilldd8 leidilldd9 leonproject10 leonproject11 leospublicid13 leospublicid14 leospublicid15 leospublicid16 leospublicid17 leospublicid18 leowlong1989s8 lexical-botany-192906 lgnativs07 lgnativs08 lgnativs09 liangaa2net liangaa2net-187503 liangaanet-187502 lichangmao08 lidegang11231 lidegang11232 light-ether-147016 lihuacai6 lihuacai7 lihuacai9 lihuacaiabc lijiesherlcok lilhoe10 lilhoe11 lilhoe1111 lilhoe22 lilhoe222 lilhoe33 lilhoe66 lilhoe77 lilhoe88 lilhoe99-1229 lilhoea1 linear-axle-186502 linear-ether-244611 linear-facet-168013 linear-reporter-191716 linfenpark-1111 linfenpark-1112 linfenpark-1114 linfenpark-1115 linfenpark-1116 linfenpark-1117 linfenpark-1118 linfenpark-1252 lingdaode linux1-166406 linworld671 linworld672 linworld673 linworld674 linworld675 linworld676 linworld677 linworld678 linworld679 linworld680 lionchinala lionchinaxxx lionkobeseeme lionseekobe liqinna0 liqinna1 liqinna2 liqinna3 liqinna4 liqinna5 liqinna6 liqinna7 liqinna8 liqinna9 liquid-journal-227309 lithe-camp-177104 lithe-saga-214609 lithe-style-242711 liuchenfang1 liuchenfang2 liujianmao-1 liujianmao-2 liuli0-140401 liumangtu147853447 liushappy liushope liuxiaobo-1104 liuxiaobo1-1384 liuxiaobo2-1384 liuxiaobo3 liuxiaobo4-1384 liuxiaobo5-1384 liuxiaobo6-1384 liuxiaobo7-1384 liuxiaobo8-1384 liuxiaobo9-1384 lively-armor-181018 liy-pay-153300 liy-soft-153301 liy-zone-153208 liyafang-project2 liyisn020 liyuankai82 liyuankai83 liyuankai85 liyuankai86 liyuankai87 liyuankai88 liyuankai89 liyuankai90 liyuankai91 lizhaodong199026 lizhaodong199126 ljf01-233906 ljy-xx-net local-chalice-192906 lofty-bolt-859 lofty-dynamics-189703 lokkingg-1470053234347 lonely-bbs lonely-sex lonelyzf longhaofeixia lookeecbb loopback-001 loyal-manifest-187602 lszy-157702 luchia011-1218 luchia012-1218 lucid-course-191201 lucid-sweep-123514 lucid-sweep-192515 lucky-apparatus-213002 luisfly-1 luisfly-2 luluxi-182315 lumia1-163910 lumia10-163910 lumia2-163910 lumia3-163910 lumia4-163910 lumia5-163910 lumia6-163910 lumia7-163910 lumia8-163910 lumia9-163910 luoke90hou luoke91hou luoke92hou luoke93hou lxdfanqiang10 lxdfanqiang11 lxdfanqiang12 lypproxy lzlofjo10 lzlofjo11 lzr001 lzr002 lzr003 lzr004 lzr005 lzr006 lzr007 lzr008 lzr009 lzxx0112 lzxx0113 lzxx20150109 macro-resolver-187502 madalice0226a124bd madalice0226a2c85b madalice0226b2d5df madalice0226b7699d magnetic-gadget-215410 magnetic-hawk-233509 magnificent-pen-221514 main-byte-185802 main-duality-159813 majestic-fuze-196917 makegame makelshadow3103d46 makelshadow32e70fd makelshadow3334424 makelshadow337ade8 makelshadow33eed47 makelshadow35cbb2d makelshadow37ca0bb makelshadow38beb87 makelshadow38c57ae makelshadow3cfde6a makrse-1470053659892 mama-208615 manatsu3115a manatsu3115b manatsu3115d manifest-altar-123515 manifest-quasar-214609 marine-defender-182008 markwang11111 markwang11112 markwang11116 markwang1112 markwang112 marxist-2017 masko1-977 masko2-977 masko3-977 masko4-977 massive-hexagon-164205 massive-tensor-107908 master-bulwark-159814 master-charmer-138323 master-tuner-191112 mathsunhonglin-001 mathsunhonglin-002 mathsunhonglin-003 mathsunhonglin-004 mathsunhonglin-005 mathsunhonglin-006 mathsunhonglin-1283 maximal-ascent-184212 maximal-furnace-189008 maximal-window-209014 mayx160407 mayx160408 mayx160409 mayx160410 mayx160411 mayx160412 meaveric mechbug-1 mechbug-2 mechbug-3 mechbug-4 mei66-165709 mei67-165709 mei68-165709 mei69-165709 meilidewo-142514 mengxian-186203 mercurial-idiom-197708 meta-altar-181522 metal-seeker-211015 metleau metleau01 metleau02 metleau04 metorm-anti-gfw mexzn01 mexzn02 mexzn03 mexzn04 mexzn05 mexzn06 mexzn07 mexzn08 mexzn09 mfk55555 mfk555555 mfsz-001 mianyang621005 mianyang621006 michael-160410 mickweb-1 mickweb-2 mickweb-3 micro-cacao-140616 micro-cacao-215910 midyear-choir-227609 midyear-cursor-184318 midyear-machine-148607 mig2999djproxy4 mig2999djproxy5 mig2999djproxy6 mindful-ship-188705 mindfulness-174001 mltx-00010101 mm0909-1247 model-arcadia-177513 model-cirrus-859 modern-alpha-177622 modular-tube-244203 molten-position-257701 molten-sandbox-170211 molten-topic-208615 mona1-190308 mona2-190308 mona3-190308 mona4-190308 mona5-190308 moonlit-byway-205004 moonlit-creek-151605 moonlit-rock-174804 mosexegae12 moshengrenw2 mp-wlw101 mp-wlw102 mp-wlw103 mp-wlw104 mp-wlw105 mp0009-1275 mphuang2008 mphuang2009 mxx711-1274 mxxnettestid1 mxxnettestid2 mxxnettestid3 mxxnettestid4 mxxnettestid5 my-appid-10-227013 my-appid-111-227013 my-appid-12-227013 my-appid-7-227013 my-appid-8-227013 my-appid-9-227013 my-appid-name my-application-01-01 my-application-02-02 my-application-03-03 my-application-04-04 my-application-05-05 my-application-06-06 my-application-07-07 my-application-08-08 my-application-09-09 my-application-10-10 my-application-11-11 my-application-12-12 my-mcc5 my-phpliang537617 my-project-002-1262 my-project-002-148912 my-project-005-1262 my-project-011-1332 my-project-012-1332 my-project-013-1332 my-project-014-1332 my-project-016-1332 my-project-017-1332 my-project-018 my-project-019-1332 my-project-020-1332 my-project-021 my-project-022 my-project-023 my-project-024 my-project-025 my-project-026 my-project-027 my-project-028 my-project-029 my-project-1-151403 my-project-10-1470318399543 my-project-10-151606 my-project-10-157123 my-project-10-177514 my-project-11-1331 my-project-11-156439 my-project-11-157123 my-project-11-173001 my-project-11-177514 my-project-12-172010 my-project-12-177514 my-project-14-1332 my-project-15-1332 my-project-1539253515081 my-project-16-1332 my-project-16-1469791357104 my-project-17-1332 my-project-17-1469791366911 my-project-18-1469791544968 my-project-19556 my-project-2-147016 my-project-2-155001 my-project-2-157122 my-project-20161007-1 my-project-2017-12-22-1 my-project-2017-12-22-2 my-project-2017-12-22-3 my-project-2017-12-22-4 my-project-2017-12-22-5 my-project-2017-12-22-6 my-project-2017-12-22-7 my-project-2017-12-22-7-189808 my-project-2017-12-22-8 my-project-3-1469883794714 my-project-3-157122 my-project-3-168017 my-project-3-243106 my-project-30-1332 my-project-4-157122 my-project-4-164609 my-project-4-168017 my-project-4-170210 my-project-4-243106 my-project-4172-249613 my-project-5-157122 my-project-5-170706 my-project-524-185314 my-project-57690-juan-xian my-project-597520 my-project-597521 my-project-597522 my-project-597523 my-project-597524 my-project-597525 my-project-597526 my-project-597527 my-project-597528 my-project-597529 my-project-6-1470318197921 my-project-6-157122 my-project-6-170706 my-project-6-243106 my-project-7-1470318242557 my-project-7-157122 my-project-7-170706 my-project-7-243106 my-project-8-1470318289690 my-project-8-157122 my-project-8-170706 my-project-9-1470318330078 my-project-9-157123 my-project-9-194714 my-project-946-189702 my-project-for-first my-project-hzjxxnet01 my-project-hzjxxnet01b my-project-hzjxxnet01c my-project-liu1 my-project-liu10 my-project-lxh my-project-of-ladder-10 my-project-xx-net-186203 my-project-xx-net2-183913 my-project-xxnet1-183914 my-project-xxnet3-183914 my-project-xxnet4-183914 my-project10-1337 my-project10-223908 my-project10503 my-project11-1337 my-project111222-153713 my-project12-1337 my-project13-1332 my-project13-1337 my-project14-1332 my-project14-1337 my-project190307 my-project1996-145807 my-project2-223908 my-project3-223908 my-project3-237503 my-project4-223908 my-project5-223908 my-project6-223908 my-project7-1273 my-project7-223908 my-project8-1273 my-project8-223908 my-project9-1273 my-project9-1337 my-project9-223908 my-time-123 my-vpn-188308 my-vpn-2-188409 my-vpn-3-188409 my-vpn-4-xx-net my-wall-154700 my-xx-net-226203 my-xxnet-21076 my-xxnet-21077 my-xxnet-21078 my-xxnet-21079 my-xxnet-21080 my-xxnet-21081 my-xxnet-21082 my-xxnet-21083 my-xxnet-21084 my-xxnet-21085 my-xxnet-21086 my-xxnet001-171613 my-xxnet002-171614 my2017project04 my2017project05 my20180501 my20180502 my20180503 my20180504 my20180505-203901 myappid-20124443 myappid-ikuta1997 myappid-ikutaerika myappid-lee20124443 myappid-xxnet-226713 myappid1-142508 mycloud201706242 mydonate1 mydonate2 mydonate3 mydonate4 myfanqianone mygoagent1-1226 mygoagent2-1226 mygoagent3-1364 mykeai-189715 mymap-225908 mynet5-165000 mynet6-165000 myproject-223911 myproject-5101162 myproject-europe-west myproject-liu01 myproject-liu02 myproject-liu03 myproject-liu04 myproject-liu05 myproject-liu06 myproject04-247802 myproject1-223908 myproject12-244314 myproject13-244401 myproject14-244401 myproject15 myproject16 myproject17-244401 myproject18 myproject19-244401 myproject20 myproject21-244401 myproject22-244401 myproject23-244401 myproject24 myproject25 myproject26-244406 myproject27 myproject28 myproject9511114 mystic-creek-107908 mythical-height-225406 myxxnet-1264 myxxnet1-1285 myxxnet1-197814 myxxnet2-1285 myxxnet2-197814 myxxnet3-1285 myxxnet4-1285 myxxnetprojectfordonate-1 myxxnetprojectfordonate-2 name1-156514 name2-156514 name3-156514 name4-156514 name5-156514 name6-156514 name7-156514 named-dialect-208808 named-inn-197708 nanj987-1274 nanxijw-xxnet01 narutobm123 narutobm1234 narutonbm123 narutonbm1234 nasxxnet nasxxnet1 nbjncknla neat-bliss-123313 neat-bricolage-218008 neat-vent-149203 neon-circle-226806 neon-feat-211015 neon-trilogy-188809 net-1111 net-246615 net-3-162407 net-ex net-lovely net04-185713 net05-187603 net123-226713 net2-226804 net3-226804 netproject1-196801 netproject2-196802 netproject3-196802 netproject4-196802 netproject5-196802 netproject6-196802 netview-141308 netweb-agent2 netx-231408 netx1-231408 netx2-231408 netx4-231408 netx5-231408 netx6-231408 netx7-231408 netx8-231408 netx9-231408 netxa-231408 netxb-231408 netxc-231408 netxx-199505 netxx-2-199505 netxx-3-199505 netxx-5691aa netz-243307 neural-hour-189703 neural-ripple-146309 neural-tome-123515 newland-170315 newlife-170315 newlove-170315 newproxy-185211 newweb-159812 niangniub nianguib nianguuib nice-azimuth-123514 nico-166707 nifty-altar-184200 nifty-artwork-170209 nightfuryfordou6 nightfuryfordou7 nightfuryfordou8 nikitamas66 nikitamas77 nikitamas99 nikitmas88 nimble-host-191708 ning123-161106 ningerte001 ningerte002 ningerte003 ningerte01 ningerte01-221312 ningerte02 ningerte04 ningerte05 ninoleee2 ninoleee3 ninth-iris-232002 njbh-88 njh19900608 njh19901120 njh19901121 njh19901122 njh19901123 njh19901124 njh19901125 njh19901126 njh19901127 njh19901128 njh19901129 njh420974489 njh869084221 nkatfree20 nmb48keila noble-trees-206114 nodal-deck-178706 nodal-element-217505 nodal-operand-200408 nomadic-archway-234904 norse-wavelet-233015 noted-tide-217505 nth-theater-225607 nudt-toronto10 numeric-button-249613 nvbmj-189715 nxiaobin-2015 nxiaobin-2016 nxiaobin-2017 nxiaobin-2018 nxiaobin-2019 observer20120904 observer20121031 octodile-pus01 octodile-pus02 octodile-pus03 octodile-pus04 octodile-pus05 octodile-pus07 octodile-pus08 octodile-pus09 octodile-pus10 octodile-pus11 octodile-pus12 octodile-pus13 oilrecord-163619 omega-iterator-228003 omega-terrain-123504 omjust onyx-stack-193604 oo349294222 openx-200508 openx-200509 openx-200510 oppffg-189715 oppj-1 oppj-10 oppj-11 oppj-12 oppj-13 oppj-14 oppj-15 oppj-16 oppj-17 oppj-18 oppj-19 oppj-2 oppj-20 oppj-3 oppj-4 oppj-5 oppj-6 oppj-7 oppj-8 oppj-9 opportune-scope-192906 optical-psyche-226312 optical-scarab-151605 optimal-relic-186707 optimal-timer-205006 optimistic-keel-161020 organic-berm-125203 organic-isotope-153512 organic-isotope-189414 organic-spirit-184408 ornate-serenity-232002 our-highway-159814 our-lamp-214609 our-pursuit-250817 our-sign-107908 outstanding-yew-226806 oval-campaign-227309 oval-day-180703 pacific-apex-192906 pacific-destiny-192908 pacific-element-184318 pangzi-1 pangzi-10 pangzi-11 pangzi-12 pangzi-2 pangzi-3 pangzi-4 pangzi-5 pangzi-6 pangzi-7 pangzi-8 pangzi-9 panhut-1233 papastarpapa parabolic-clock-242414 passwall-3 peerless-garage-243002 peerless-kit-133123 peerless-summit-180703 peerless-trees-128708 pelagic-sorter-151605 penghuaifa15 penghuaifa16 penghuaifa17 penghuaifa18 penghuaifa19 penghuaifa20 penghuaifa21 penghuaifa22 penghuaifa23 penghuaifa24 penghuaifa25 pengzhaopan-1272 pengzhaopan11 peoplevsgfw1 peoplevsgfw10 peoplevsgfw11 peoplevsgfw12 peoplevsgfw2 peoplevsgfw3 peoplevsgfw4 peoplevsgfw5 peoplevsgfw6 peoplevsgfw7 peoplevsgfw8 peoplevsgfw9 perfect-aura-177307 perfer-147105 perfer2-147105 perfer3-147105 perfer4-147105 perfer5-147105 pharos-215409 phrasal-bonus-214609 phrasal-chiller-172906 phrasal-edition-193607 pi-project-152413 pichunhan7 pioneering-flow-233206 pivotal-base-221514 pivotal-purpose-170211 planar-name-127301 planar-name-127302 planar-name-127305 planar-name-127306 planar-name-127307 planar-name-127308 planar-name-127309 planar-name-127310 planar-name-127311 planar-name-127312 planar-name-127313 planar-name-127314 planar-osprey-211501 plasma-circle-191107 plasma-elf-189703 platinum-hour-123803 plucky-balm-190215 plucky-order-157607 pnj2014163 pnj201416301 pnj2014163010 pnj201416302 pnj201416303 pnj201416304 pnj201416305 pnj201416306 pnj201416307 pnj201416308 pnj201416309 pnj201416310 pnj201416311 pnj201416312 pnj201416313 pnj201416314 pnj201416315 pnj201416316 pnj201416317 pnj201416318 pnj201416319 pnj201416320 poetic-archway-221514 poetic-chariot-186703 poised-artwork-190710 poised-defender-162012 poised-rock-133123 polished-will-236503 polonium432 polonium543 polymer1-191714 positive-cocoa-213503 possible-jetty-182501 potent-trail-174402 potent-well-237014 potent-zodiac-173517 practical-album-122814 pragmatic-ruler-185005 precise-bank-778 precise-data-180703 precise-formula-184910 predictive-net-187715 prefab-glazing-171713 prefab-pursuit-221514 prefab-segment-125209 premium-oven-184200 premium-weft-123504 primal-buttress-183205 primal-pod-214609 primeval-proton-214605 primeval-stack-209903 primordial-ship-203109 profect-for-xx-net-1 project-161216 project-for-xx-net-167007 project-for-xx-net-2 project202001 project202002 project202003 project202004 project202005 project202006 project202007 project202008 project202009 project4xxnet-206722 project4xxnet1 project4xxnet2-206722 project4xxnet3 project4xxnet4 project4xxnet5 projecteast-5101162 projects1-232002 propane-primacy-214609 protean-mind-207504 protel-pacific10 protel-pacific8 protel-pacific9 proud-storm-122813 proven-wavelet-192906 proxy-181212 proxy-181213 proxy-go-214805 proxy1-185211 proxy2-185211 proxy3-185211 proxypeak21 psychic-etching-190215 psychic-glider-184209 public-1025 public1-190407 publicht2017 pure-chariot-228414 pure-media-187002 pure-mission-183900 python-227202 pz123-190010 pzrproject q74110-208509 q7411074 qawxer4 qiangfei-19880318 qiu15-1105 qiupeng1993 qiupeng1994-1182 qiupeng1995-1182 qiupeng1996-1182 qiupeng1997-1182 qiupeng1998 qiupeng1999-1182 qiupeng2000-1182 qiupeng2001 qiupeng2011-1169 qqnet1 qqqq-208615 qsj901222 qualified-city-189703 quantum-spring-190215 quick-art-257701 quick-function-242612 quick-sonar-189715 quicksci-0011 quicksci-0012 quiet-axon-201702 quiet-branch-146309 quixotic-folio-174804 qujinfeng006 qujinfeng008 qujinfeng390 qunchen0411 qunchen0412 qunchen0416 qwe-qwe1 qwe-qwe2 qwe-qwe3 qwe-qwe4 qwe-qwe5 qwe-qwe6 qwe-qwe7 qwe-qwe8 qwertwert-181109 qybust0 qybust1 qybust2 qybust3 qybust4 qybust5 qybust6 qybust7 qybust8 qybust9 qzhunb qzhunb10 qzhunb11 qzhunb12 qzhunb13 qzhunb14 qzhunb15 qzhunb16 qzhunb17 qzhunb18 qzhunb19 qzhunb2 qzhunb20 qzhunb21 qzhunb22 qzhunb23 qzhunb24 qzhunb3 qzhunb4 qzhunb5 qzhunb6 qzhunb7 qzhunb8 qzhunb9 rabbit-000001 rabbit-000002 rabbit-000003 rabbit-000004 rabbit-000005 rabbit-000006 rabbit-000007 rabbit-000008 rabbit-000009 rabbit-000010 rabbit-000011 rabbit-000012 railgun-11 railgun01-163611 rain1213 rare-attic-170706 rare-chiller-160309 red-agility-192503 red-agility-239914 refined-grammar-125209 refined-helix-143904 refined-rookery-249613 reflecting-card-216108 reliable-return-159813 reliable-vector-146301 ren-zhi-chu21 ren-zhi-chu22 ren-zhi-chu23 ren-zhi-chu24 ren-zhi-chu25 resolute-cat-248804 responsible-map-184603 responsive-sun-183406 rh4xtunnel rich-operand-126901 rich-suprstate-133209 richy20k12 ringed-spot-132123 ringed-tractor-189912 rising-analogy-106015 river-karma-123514 river-psyche-149813 rj226-1 rj226-10 rj226-11 rj226-12 rj226-2 rj226-3 rj226-4 rj226-5 rj226-6 rj226-7 rj226-8 rj226-9 robotic-tide-187615 robotic-tiger-237305 rock-loop-206909 rockneimenggu rongshaofeng-174118 root-1233 root-habitat-232002 root-matrix-142508 root-micron-231600 root-patrol-107908 root-patrol-192908 rosy-dialect-124115 rosy-hangout-210602 round-plating-159814 round-sunset-208402 rtemis0004 rugged-alcove-186315 rugged-layout-189005 rugged-nucleus-221514 runbird20 runck14 saaas-1235 sacred-attic-187913 sacred-catfish-107908 sagitonychen9 sampirga1 sandro-xx-net-2 sanshai-1240 sanshai-1241 sanshai-1242 sanshai-1243 sanshai-1244 sanshai-1255 santali1985 sapient-mote-184209 sappmd-146309 savexx-net1 savexx-net2 savexx-net3 savexx-net4 saviorsyang11 saviorsyang12 savvy-hybrid-188705 sciencesurfininternet-210416 scientific-glow-192905 sclproject-150315 scto2101 scto2102 scto2103 scto2104 scuyanghao01 scuyanghao02 scuyanghao03 sdjproject-214607 sdwanghf5 sdwanghf6 sdwanghf7 sdwanghf8 sdwanghf9 seasprseaspr10 seasprseaspr11 seasprseaspr6 seasprseaspr7 seasprseaspr8 seasprseaspr9 secgao secgao2 secgao3 secgao4 secgao5 second-10002 second-pier-169804 seebug11 seeker958115 seeker958116 seeker958117 seeker958118 seekobelion seelionkobe seeme-lion seemechina seemelion seemelionxxx seismic-operand-177707 self-vpn-209714 semiotic-karma-188809 seraphic-being-151605 serious-mariner-221309 seven-10007 seventh-history-123514 seventh-palace-153014 sfbj9991vpn3 sfbj9991vpn4 sfowqd sfowqd01 sfowqd02 sfowqd03 sfowqd04 sfowqd05 sfowqd06 sfowqd07 sfowqd08 sfowqd09 sfowqd10 sfowqd11 sfowqd12 sfowqd13 sfowqd14 sfowqd15 sfowqd16 sfowqd17 sfowqd18 sfowqd19 sfowqd20 sfowqd21 sfowqd22 sfowqd23 sfowqd24 sfowqd25 sfowqd26 sfowqd27 sfowqd28 sfowqd29 sfowqd30 sfowqd31 sfowqd32 sfowqd33 sfowqd34 sfowqd35 sfowqd36 sfowqd37 sfowqd38 sfowqd39 sfowqd40 sfowqd41 sfowqd42 sfowqd43 sfowqd44 sfowqd45 sfowqd46 sfowqd47 sfowqd48 sfowqd49 sfzo0001-1095 sfzo0002-1095 shangwang1111 shangwang1234 shangwang12345 shangwang123456 shangwang1234567 shangwang12345678 shangwang123456789 shangwang2222 shangwang3333 shangwang5555 shanlonglong-184110 shaofeng-167407 shaofeng-174120 shaofeng2-168206 shaped-density-208808 share-664123 share-xxnet01 share-xxnet02 sharp-airway-192503 sharp-quest-123515 shejiwanga shejiwangb shejiwangc shejiwangd shejiwange shejiwangf shejiwangg shejiwangh shejiwangk shendcsa shewnei2288 shinever-9 shinever-catcher-95809 shining-env-216915 shounan0515 shounan1984 shuaiyer2013 shuaiyer2015 shumaye-20180401 shumaye-20180402 shumaye-20180403 shumaye-20180404 shumaye-20180405 sigma-celerity-248804 sigma-sector-192515 silent-octagon-198615 silicon-coder-191107 silken-inverter-191106 silver-fiber-187715 silver-nova-133623 simon-1283 sincere-quasar-248110 sing-a-song-1991 singingfor-1245 single-beaker-186909 single-bulwark-188715 singular-hash-233108 sinoadongdong sisix-182315 sixth-clone-06 sixth-well-232002 sixx-10006 sj-34474 skilful-display-187515 skilful-scarab-221603 skilled-duality-237523 skyxsky10 smart-oa smart-oasis-184115 smart-seer-188705 smiling-diode-162011 snappy-rainfall-155411 snappy-thought-220505 sodium-hangar-151605 solar-vortex-217018 solid-coder-167907 solid-depot-246308 solid-dominion-107908 somshame somshame1 somshame2 songxu921 songyajun00001 songyuxuan211 songyuxuan212-185304 sonic-column-162405 sound-invention-122813 sound-velocity-184603 southamerica-east-182 sparereal33 spartan-buckeye-242711 speedy-hold-228003 spheric-brand-213002 spiritual-aloe-177622 spring-forest-187715 spry-equator-123515 spry-guru-180703 spry-pipe-249808 spuerjimm ssongyajun stable-balancer-235613 stablemars starlit-cocoa-122814 starlit-primacy-227309 starlit-ship-123504 starlit-verve-194808 starlit-vim-231010 starry-embassy-107908 stately-gist-807 stately-math-123514 static-bond-180703 static-cirrus-184606 static-pottery-207606 static-resource-106711 steam-ego-191802 steam-style-184318 steam-thinker-241905 steam-way-149711 steel-citizen-123515 steel-minutia-167204 steel-sequencer-215206 steel-sonar-146810 stephen-1 stephen-2-1265 still-protocol-210206 still-tensor-216915 stlivoe1-1470704581040 stmapp1 stock-store stoked-dominion-123514 stone-botany-255102 stone-column-213103 stone-dispatch-146309 storied-channel-186702 storied-myth-123514 storied-storm-135623 storystorynight-1108 strategic-cargo-232304 strav311 strav317 strav318 striking-goal-249409 striped-bonfire-125209 striped-device-203807 striped-device-231003 striped-history-249804 strong-minutia-135702 strv301 studious-lore-131616 studious-union-194808 sturdy-plateau-226904 sublime-elixir-118315 sublime-lens-215807 subtle-striker-164609 subtle-sublime-123515 summer-surface-247106 sundayinvip sunlit-fuze-183714 sunlit-segment-224104 sunny-emissary-243002 sunny-footing-184600 sunny-lore-180703 sunxingstargoagent1 super-stingx17 super-stingx18 super-stingx19 superb-cubist-189703 superb-infusion-213503 supermanxia1 supermanxia2 supple-fold-191106 surezheng198822 surezheng198823 surezheng198824 surfree31 surfree32 surfree33 surfree34 surfree35 surfree36 surfree37 surfree38 surfree39 surfree40 sutungpo-09 sutungpo-10 swdada89 swift-hangar-192906 swkoko1989 sxt901222 sxxnet-1222 sylvan-fusion-125209 sylvan-server-233015 sylvan-solstice-241811 symbolic-eye-159814 symmetric-flag-248211 symmetric-lotus-180703 symmetric-ray-116004 tactical-codex-190606 tactical-gate-146713 tactile-acolyte-217410 takonyan-project takonyan-project2 takonyan-project3 takonyan-project4 takonyan-project5 tangtdjia tangyidikej tanjianwen-demo taopanpan tassader006 tassader007 tassader008 tassader009 tassader010 tassader011 tassader012 tassader013 tassader014 tassader015 tassader016 tassader017 tassader018 tassader019 tassader020 tdztw105 teak-banner-242003 teak-instrument-184212 tegry2014 temporal-bebop-226408 temporal-potion-170704 temporal-potion-257701 tenacious-ring-196408 tengjifive tengjione tengjisix tengjithree tengjitwo tensile-analyst-146309 tensile-analyst-229009 tensile-splice-248804 tenymisswork1 tenymisswork2 tenymisswork3 tenymisswork4 tenymisswork5 test-1909 test-207587 test-208448 test-208771 test-208808 test-net-210207 test01-186302 test02-186302 test03-186304 test20190114 test4app7374 test805gz06 test805gz07 test805gz08 testine1001 testxxnetsteven text1-1376 thaishare-195102 thaishare-27502 thankyou-189715 the-flame-208808 the-racer-205005 thematic-cider-249009 thermal-rock-184203 theta-camera-146810 theyirun thinking-text-189910 third-circle-122813 third-wharf-210104 three-10003 tianguomyu003 tianjianxinyue tianjianxinyue1 tianjianxinyue2 tianjianxinyue3 tianjianxinyue4 tianjianxinyue5 tianjianxinyue6 tianjianxinyue7 tianjianxinyue8 tianjianxinyue9 tianxin00888310 tianxin0088837 tianxin0088838 tianxin0088839 tidal-anvil-207507 tidal-discovery-187715 tidal-orbit-186402 tidy-crane-204208 tingxiao4 tingxiao5-1211 tingzhuzhefeng-211214 tinycai001 tinycai002 tinycai003 tinycai004 tinycai005 tinylens-168602 tinylens-168603 tinylens-168604 tizi-164807 tizi-165409 tjdxncu5 tjdxncu6 tjdxncu7 tjdxncu8 tjdxncu9 toadprince2010 toadprince2011 tokyo-mark-185802 tonal-griffin-125209 tony0401175803 tony0405040826 tony0412430025 tony0415978520 tony0423203189 tony0426684326 tony0466478249 tony0469059164 tony198911 tony535134 tony68764354 tony714189010 top-alliance-187715 tornado-190303 total-stratum-178304 tough-hull-192905 tough-ivy-188715 trans-campus-152114 trans-campus-187715 trans-gate-123514 tranwand-hrd tranwandwand tribal-saga-190710 tribal-terra-137723 trim-attic-133123 trim-diode-192219 trim-mote-125209 triple-mountain-127310 triple-virtue-151606 true-velocity-237602 trusty-anchor-214906 trusty-banner-192017 trusty-relic-233617 tset-142510 tunnel-share-001 turing-clover-146309 turnkey-charter-180904 turnkey-diode-186201 turnkey-rookery-125209 ui34-189715 ultra-aloe-261016 ultra-aquifer-182402 ultra-optics-189315 underwoods01 underwoods02 underwoods03 underwoods04 underwoods05 underwoods06 underwoods07 underwoods08 underwoods09 underwoods10 underwoods11 underwoods12 unich881 unified-adviser-186402 unified-chess-166906 unink88 unink880 unink884 unique-antonym-123515 unique-ellipse-123514 unique-source-253502 universal-rider-216108 universal-stone-123514 upbeat-cargo-131607 upbeat-flame-207503 upbeat-voice-123514 upheld-dragon-137308 uplifted-nuance-238209 uplifted-record-242612 ustc641app1 ustc641app2 ustc641app3 utopian-precept-170209 uu7890-1247 valiant-airlock-188715 valiant-index-166213 valiant-metric-143110 valid-chess-233015 valid-moment-221514 valid-octagon-137823 vaulted-codex-237305 vd34-p velvety-folder-181606 velvety-transit-220019 verdant-legacy-186402 verdant-medium-187107 versatile-vine-180703 vertical-karma-261123 vertical-planet-189010 vfr45q viekin880121 vigilant-shell-161715 vincentwangzai virtual-airport-185802 virtual-dynamo-242711 vivid-now-167105 vivid-science-166810 vivid-vent-138023 vmms-163619 vocal-affinity-173517 vocal-ceiling-208808 vocal-sunlight-190710 vocal-terminal-261123 vodomine1 voltaic-racer-185501 voltaic-range-220607 vpn-1001 vpn-1002 vpn-project-1-171712 vpn-project-793427156 vpn5-1383 vpn6-1383 vpnb-179503 vpnbittt-181300 w183110795 w183110796 w183110797 w183110798 w183110799 w3qeqd3 w511655778 w708846696-182101 walker-13-1193 walker313-1319 wall-1336 wamssj11 wang-yu-zhe wang-yu-zhe-9011 wangdatou-001 wangdatou-002 wangfengyoyo1 wangfengyoyo2 wangwei-168512 wangwenbin1 wangwenbin2 wangyan-10 wangyan-11 wangyan-12 wangyan-123 wangyan-8 wangyan-9 wangyansong1010 wanxmo02 wanxmo03 wanxmo04 wanxmo05 wanxmo06 wanxmo07 wanxmo08 wanxmo09 warm-composite-217812 watchful-gear-192108 watchful-scope-208808 wdcagent wdcagent1 wdcagent2 wdcagent3 weberdyx21 weberdyx22 weberdyx23 weberdyx24 wedcf110-3 weienjoy5 weienjoy6 weienjoy7 weienjoy8 weienjoy9 weighty-flag-221514 weighty-works-192112 weimingyangvip10 weimingyangvip2 weimingyangvip3 weimingyangvip4 weimingyangvip5 weimingyangvip6 weimingyangvip7 weimingyangvip8 weimingyangvip9 weipo1989 weipo1991 weipo1994 weipo1995 weipo1996 weipo1997 weipo1998 weipo1999 weipo2000 weipo2001 weishiyong1 welikeclimb wen-412702190 wen-412702196 wen-412702197 wen-412702198 wen-412702199 western-net-192906 western-will-807 westmylove121 westmylove122 whenican2 whenican3 whenican4 white-airship-213502 white-cider-162012 whitescinewoo4xx wide-bivouac-180703 wide-exchanger-189008 windbell-1193 windbell1-1193 windbell12-1193 windbell123-1193 windbell1234-1193 windbell12345-1193 winter-gear-172906 winter-wonder-249804 wise-resolver-163408 wise-trainer-151605 wizga-140504 woaixjj-209617 wojiagougou0000 wooden1-179902 wooden2-179903 wooden3-179903 wooden4-179903 wooden5-179903 works-1470053169939 woshicyx-162308 woven-amulet-127312 woven-rush-164914 woven-victor-170706 wtchina13 wtz-project-1 wu4258528xxnet1 wuguanlinfight8 wuguanlinfight9 wuju0012 wuju0013 wuju009001 wuju009002 wumingkun5-1099 wumingkun6-1099 wumingkun7-1099 wumingkun8-1099 wumingkun9-1099 wushibin01 wushibin02 wushibin03-184301 wushibin14 wushibin15 wushibin16 wushibin17 wushibin18 wushibin19 wuwalkerman wuyaoliuo wuyaoliuoo wuyaoliuoo1 wuyaoliuooo wwszy01 wwszy02 wwwccatv10 wwwccatv11 wwwccatv12 wwwccatv13 wwwccatv14 wwwtt0412 wx362com wxiang01-194109 wxxnet-1 wxxnet-209812 wxy11064 wxy11065 wxy11067 wxy11068 wxy11069 wyb0531-646359954 wys-proxy-1 wys-proxy-10 wys-proxy-2 wys-proxy-3 wys-proxy-4 wys-proxy-5 wys-proxy-6 wys-proxy-7 wys-proxy-8 wys-proxy-9 wyslmt11 wyslmt12 x-alcove-237412 x-micron-123504 x-net-1214 x-net1-185412 x-net2-185412 x-net5-186107 x-router-218209 x-sorter-168017 x-tunnel-communal x-tunnel-lql0 x-tunnel-lql1 x-tunnel-lql10 x-tunnel-lql11 x-tunnel-lql2 x-tunnel-lql3 x-tunnel-lql4 x-tunnel-lql5 x-tunnel-lql6 x-tunnel-lql7 x-tunnel-lql8 x-tunnel-lql9 x-tunnel-tinycai-001 x-tunnel-tinycai-002 x-tunnel-tinycai-003 x-tunnel1 x-tunnel3 x-tunnel4 x-tunnela x-tunnelb x-tunnelc x-tunneld x-tunnele x-tunnelf x-tunnelg x-tunnelh x-tunnelh-221308 x-tunnelk x-tunnelz x-victor-249206 x222-1233 x2netforall01 x333-1233 x444-1233 x555-1233 x666-1233 x777-1234 x888-1234 x888-2345 xaegxy6 xaegxy7 xaegxy8 xdffish15 xdffish16 xdffish17 xdffish18 xdffish19 xdffish20 xenon-momentum-233515 xiang-mu-7 xiang-mu-8 xiaocaiya xiaole5775 xiaole5776 xiaoleiapple xiaolong6-20180829 xiaolong7-20180829 xiaolong7-20180830 xiaolong8-20180909 xiaolongthree-20180826 xiaoxhcrtvu2016001 xiaoyehao-207704 xiejiajia400 xieluo333 xieluo444 xieluo555 xieluo666 xieluo777 xieluo888 xieluo999 xieyihong12 xihaneimenggu xijsidjwn xindewagnsutest xinxijishuwyq xinxijishuwyq1 xinxijishuwyq10 xinxijishuwyq11 xinxijishuwyq12 xinxijishuwyq13 xinxijishuwyq14 xinxijishuwyq15 xinxijishuwyq2 xinxijishuwyq3 xinxijishuwyq4 xinxijishuwyq5 xinxijishuwyq6 xinxijishuwyq7 xinxijishuwyq8 xinxijishuwyq9 xinyang0111 xinyang0211 xinyang0411 xinyi1237 xj00001-1269 xjtusoc1 xjtusoc3 xjtusoc4 xjtusoc5 xnet27154 xnetynmfl2 xnroid1 xnroid2 xqnet-207202 xqqflyer xthetom10 xtunnel002 xtunnelrh1 xtwfyjdh xuanlong-huimiezhe xx-lot-185509 xx-nat-197813 xx-net xx-net-0-191100 xx-net-002-250718 xx-net-003-191104 xx-net-004-191104 xx-net-005-191104 xx-net-006-191104 xx-net-007-191104 xx-net-007001 xx-net-008-191104 xx-net-009-191104 xx-net-010-191104 xx-net-012-12 xx-net-02-188610 xx-net-02-200408 xx-net-0818 xx-net-1-181313 xx-net-1-191100 xx-net-1-194206 xx-net-1-199912 xx-net-10-193808 xx-net-1022-244313 xx-net-11094 xx-net-11110 xx-net-111178 xx-net-1214 xx-net-123459 xx-net-1427690 xx-net-1470434775337 xx-net-149202 xx-net-1500 xx-net-1501 xx-net-15687 xx-net-15688 xx-net-159305 xx-net-162407 xx-net-166900 xx-net-166923 xx-net-16992 xx-net-16997 xx-net-170302 xx-net-170309 xx-net-175407 xx-net-177622 xx-net-177906 xx-net-182702 xx-net-184012 xx-net-184318 xx-net-184501 xx-net-184505 xx-net-185304 xx-net-185612 xx-net-185716 xx-net-185717 xx-net-186704 xx-net-187006-187006 xx-net-187110 xx-net-187310 xx-net-187312 xx-net-187715 xx-net-187812 xx-net-187917 xx-net-18800 xx-net-18801 xx-net-188116 xx-net-188315 xx-net-188610 xx-net-188801 xx-net-188804 xx-net-189012 xx-net-190403 xx-net-190404 xx-net-190507 xx-net-190606 xx-net-191100 xx-net-192116 xx-net-192516 xx-net-192705 xx-net-192706 xx-net-192707 xx-net-192708 xx-net-194206 xx-net-195313 xx-net-197315 xx-net-197409 xx-net-198606 xx-net-198615 xx-net-19970214 xx-net-2-149311 xx-net-2-181313 xx-net-2-191100 xx-net-2-194206 xx-net-2-210704 xx-net-2-215106 xx-net-200615 xx-net-20170830 xx-net-2018-191615 xx-net-20180709-209714 xx-net-20180801901 xx-net-20180801902 xx-net-20180801903 xx-net-20180801904 xx-net-20180801905 xx-net-20180801906 xx-net-20180801907 xx-net-20180801908 xx-net-20180801909 xx-net-20180801910 xx-net-20180801911 xx-net-20180801912 xx-net-20180801913 xx-net-20180801914 xx-net-20180801915 xx-net-20180801916 xx-net-20180801917 xx-net-20180801918 xx-net-20180801919 xx-net-20180801920 xx-net-201811081559 xx-net-201811081601 xx-net-201811081603 xx-net-2018121503 xx-net-20181224 xx-net-20190108 xx-net-202201 xx-net-20564 xx-net-207314 xx-net-208010 xx-net-208614 xx-net-208808 xx-net-209413 xx-net-209502 xx-net-209503 xx-net-209702 xx-net-210503 xx-net-211302 xx-net-211616 xx-net-212100 xx-net-212101 xx-net-213803 xx-net-214308 xx-net-214400 xx-net-214500 xx-net-215011 xx-net-215313 xx-net-215318 xx-net-215456 xx-net-216210 xx-net-216708 xx-net-2170120 xx-net-2170121 xx-net-2170122 xx-net-2170123 xx-net-2170124 xx-net-2170125 xx-net-2170126 xx-net-217015 xx-net-217016 xx-net-217019 xx-net-217203 xx-net-217414 xx-net-218104 xx-net-218703 xx-net-218802 xx-net-218912 xx-net-219205 xx-net-219209 xx-net-219711 xx-net-221217 xx-net-221305 xx-net-2213051 xx-net-221908 xx-net-222211 xx-net-223008 xx-net-223009 xx-net-223710 xx-net-226314 xx-net-226806 xx-net-229906 xx-net-231802 xx-net-232823 xx-net-232901 xx-net-23333 xx-net-233602 xx-net-234909 xx-net-238514 xx-net-241802 xx-net-242206 xx-net-243002 xx-net-243212 xx-net-243316 xx-net-243414 xx-net-243609 xx-net-243611 xx-net-244109 xx-net-244210 xx-net-244306 xx-net-244307 xx-net-244308 xx-net-244309 xx-net-244310 xx-net-244311 xx-net-244312 xx-net-244313 xx-net-244314 xx-net-245300 xx-net-245306 xx-net-2458 xx-net-247012 xx-net-248010 xx-net-248014 xx-net-248804 xx-net-248908 xx-net-249305 xx-net-249613 xx-net-249813 xx-net-249814 xx-net-249815 xx-net-250612 xx-net-250705 xx-net-250713 xx-net-251013 xx-net-251100 xx-net-251101 xx-net-251306 xx-net-251801 xx-net-257302 xx-net-26255 xx-net-264141 xx-net-3-149203 xx-net-3-194206 xx-net-3-215106 xx-net-316356 xx-net-33925 xx-net-35942 xx-net-38195 xx-net-384587 xx-net-4-183714 xx-net-436855 xx-net-443263 xx-net-45284 xx-net-463246 xx-net-473096 xx-net-498415 xx-net-5-182618 xx-net-50640 xx-net-518404 xx-net-6-183714 xx-net-6-226806 xx-net-6-233015 xx-net-614307 xx-net-6178984 xx-net-6883 xx-net-7-183714 xx-net-8-183714 xx-net-8362 xx-net-85869 xx-net-9-226108 xx-net-9038 xx-net-905141 xx-net-91102 xx-net-987512 xx-net-994447 xx-net-agent xx-net-archway-233305 xx-net-basic-fact-191302 xx-net-boom1 xx-net-boom10 xx-net-boom11 xx-net-boom12 xx-net-boom2 xx-net-boom3 xx-net-boom4 xx-net-boom5 xx-net-boom6 xx-net-boom7 xx-net-boom8 xx-net-boom9 xx-net-box-233305 xx-net-card-233305 xx-net-comfort-233305 xx-net-common1122 xx-net-copilot-233305 xx-net-dev xx-net-do-235306 xx-net-do01 xx-net-donate-249109 xx-net-donateaid xx-net-donation01 xx-net-donation02 xx-net-donation03 xx-net-donation04 xx-net-donation05 xx-net-donation06 xx-net-donation07 xx-net-donation08 xx-net-donnate xx-net-dy-01 xx-net-elevator-209413 xx-net-fk-01 xx-net-frame-233305 xx-net-gengchen xx-net-glass-233305 xx-net-hazel-mote-191302 xx-net-hexu16413 xx-net-home xx-net-hrhqm xx-net-jia-001 xx-net-jia-002 xx-net-jia-003 xx-net-jiuyishan-01 xx-net-kxw1 xx-net-kxw2 xx-net-lwy xx-net-mori01 xx-net-mori02 xx-net-movie01 xx-net-movie02 xx-net-movie03 xx-net-nm1 xx-net-project-01-260905 xx-net-project-for-test xx-net-proxy-157013 xx-net-public xx-net-public-000 xx-net-public-001 xx-net-public-002 xx-net-public-003 xx-net-public-004 xx-net-public-005 xx-net-public-006 xx-net-public-007 xx-net-public-009 xx-net-public-01 xx-net-ray-233305 xx-net-self xx-net-si01 xx-net-si010 xx-net-si02 xx-net-si03 xx-net-si04 xx-net-si05 xx-net-si06 xx-net-si07 xx-net-si08 xx-net-si09 xx-net-si10-184013 xx-net-ssssss233305 xx-net-tensor-233305 xx-net-test-1248 xx-net-tk-000 xx-net-tk-001 xx-net-trilogy-233305 xx-net-tt1-194602 xx-net-tt10 xx-net-tt11 xx-net-tt12 xx-net-tt7 xx-net-tt8 xx-net-tunnel-1 xx-net-tunnel-2 xx-net-tunnel-3 xx-net-tunnel-4 xx-net-welder-233305 xx-net-wori xx-net-z-209708 xx-net00-201218 xx-net0001-237309 xx-net0002-190209 xx-net001-140309 xx-net0011 xx-net0012 xx-net01-212303 xx-net01-236212 xx-net01-243000 xx-net02-212303 xx-net02-233711 xx-net02-243000 xx-net03-212303 xx-net04-212303 xx-net05-212303 xx-net06-212303 xx-net07-212303 xx-net0754 xx-net08-212303 xx-net09-212303 xx-net1-169203 xx-net1-179210 xx-net1-184212 xx-net1-193807 xx-net1-211802 xx-net1-213502 xx-net1-217510 xx-net1-218322 xx-net1-225501 xx-net1-226706 xx-net1-248602 xx-net10-184212 xx-net10-186704 xx-net10-187809 xx-net10-188509 xx-net10-192909 xx-net11-1329 xx-net11-184212 xx-net11-186704 xx-net11-187809 xx-net11-188509 xx-net11-192909 xx-net12-1329 xx-net12-184212 xx-net12-187809 xx-net12-189809 xx-net12-192909 xx-net1582 xx-net159 xx-net160 xx-net161 xx-net162 xx-net163 xx-net164 xx-net165 xx-net166 xx-net167 xx-net168 xx-net169 xx-net170 xx-net17341 xx-net188804 xx-net1995 xx-net2-1260 xx-net2-156401 xx-net2-164802 xx-net2-169203 xx-net2-175407 xx-net2-184212 xx-net2-187809 xx-net2-189914 xx-net2-207703 xx-net2-213509 xx-net2-225415 xx-net2-226706 xx-net2-248804 xx-net2008 xx-net20180722 xx-net3-156401 xx-net3-164802 xx-net3-175407 xx-net3-179210 xx-net3-184212 xx-net3-187809 xx-net3-190013 xx-net3-192908 xx-net37048279901 xx-net37048279902 xx-net4-156401 xx-net4-175407 xx-net4-179210 xx-net4-184212 xx-net4-187809 xx-net4-190604 xx-net4-192908 xx-net4-193808 xx-net4-225500 xx-net4444 xx-net4donate xx-net4donate1 xx-net4wiki01 xx-net5-156401 xx-net5-175407 xx-net5-184212 xx-net5-187809 xx-net5-190604 xx-net5-225500 xx-net6-156401 xx-net6-184212 xx-net6-187809 xx-net6-192909 xx-net6-194401 xx-net6-198409 xx-net6-248804 xx-net61674 xx-net7-184212 xx-net7-184901 xx-net7-187809 xx-net7-192909 xx-net7-248804 xx-net72085 xx-net76895 xx-net8-184212 xx-net8-184901 xx-net8-186704 xx-net8-187809 xx-net8-192909 xx-net88356 xx-net9-184212 xx-net9-186704 xx-net9-187809 xx-net9-192909 xx-net9-198410 xx-net91 xx-net92 xx-net93 xx-net94 xx-net971119 xx-neta-208009 xx-neta-208010 xx-neta1 xx-neta2 xx-netcht1 xx-netcht2 xx-netchts21 xx-netdonate1 xx-netdonate2 xx-netjuanxian2 xx-netjy05 xx-netstandley xx-netwdx520 xx-obj-1 xx-obj-10 xx-obj-11 xx-obj-12 xx-obj-2 xx-obj-3 xx-obj-4 xx-obj-5 xx-obj-6 xx-obj-7 xx-obj-8 xx-obj-9 xx-vpn-1 xx-vpn-2 xx-vpn-3 xx-xx0001 xx-xx0002 xx-xx0003 xx-xx0004 xx-xx0005 xx-xx0006 xx-xx0007 xx-xx0008 xx-xx0009 xx-xx0010 xx-xx0011 xx-xx0012 xx-xx0013 xx-xx0014 xx-xx0015 xx-xx0016 xx-zlg01 xx184701 xx7837rhim xxbet-creek-186016 xxcrossfire1144 xxfreevpn xxfreevpn-01 xxfreevpn-02 xxfreevpn-03 xxfreevpn-05 xxfreevpn-06 xxfreevpn-07 xxfreevpn-08 xxfreevpn-10 xxfreevpn-11 xxfreevpn-12 xxfreevpn-4 xxn-833000 xxn-883001 xxna-227105 xxnat2 xxnb-227105 xxne-1273 xxne-184408 xxnet--01 xxnet--02 xxnet--03 xxnet--04 xxnet--05 xxnet--1229 xxnet--1248 xxnet--124811 xxnet--1252 xxnet--1265 xxnet--1267 xxnet--1268 xxnet--1269 xxnet--1273 xxnet--1274 xxnet--1289 xxnet--1290 xxnet--1308 xxnet--1313 xxnet--1357 xxnet--1375 xxnet--142420 xxnet--180307 xxnet--180395 xxnet--205704 xxnet--211902 xxnet--voyage-145601 xxnet--xtunnel xxnet-00-147002 xxnet-001-186502 xxnet-001-186707 xxnet-001-189310 xxnet-001-225608 xxnet-001-229607 xxnet-001-234808 xxnet-001-244402 xxnet-0010-196609 xxnet-001001 xxnet-001002 xxnet-001003 xxnet-001004 xxnet-001005 xxnet-001006 xxnet-001007 xxnet-001008 xxnet-002-186502 xxnet-002-186707 xxnet-002-225608 xxnet-003-186502 xxnet-003-186707 xxnet-003-225608 xxnet-004-186502 xxnet-004-225608 xxnet-004869 xxnet-005-186502 xxnet-005-225608 xxnet-006-186502 xxnet-006-225608 xxnet-007-186502 xxnet-008-186502 xxnet-009-186502 xxnet-01-1 xxnet-01-1300 xxnet-01-1303 xxnet-01-147002 xxnet-01-178218 xxnet-01-185203 xxnet-01-195803 xxnet-01-204407 xxnet-01-215207 xxnet-01-222815 xxnet-010-186502 xxnet-012 xxnet-02-1300 xxnet-02-1303 xxnet-02-147002 xxnet-02-178218 xxnet-02-189012 xxnet-02-192506 xxnet-02-212704 xxnet-02-235917 xxnet-03-1303 xxnet-03-147002 xxnet-03-178218 xxnet-03-189012 xxnet-03-235917 xxnet-0301 xxnet-03045555 xxnet-04-1303 xxnet-04-147002 xxnet-04-178218 xxnet-05-1303 xxnet-05-147002 xxnet-05-178218 xxnet-05-205003 xxnet-050 xxnet-06-1303 xxnet-06-147002 xxnet-06-178218 xxnet-07-1303 xxnet-07-147002 xxnet-0709-1 xxnet-0720-230112 xxnet-0721-230112 xxnet-08-1303 xxnet-08-147002 xxnet-0817 xxnet-0825-233502 xxnet-0828 xxnet-089 xxnet-09-1303 xxnet-09-147002 xxnet-090 xxnet-091 xxnet-092 xxnet-09291 xxnet-092910 xxnet-092911 xxnet-092912 xxnet-09292 xxnet-09293 xxnet-09294 xxnet-09295 xxnet-09296 xxnet-09297 xxnet-09298 xxnet-09299 xxnet-093 xxnet-094 xxnet-095 xxnet-096 xxnet-097 xxnet-097575621 xxnet-1 xxnet-1--1273 xxnet-1-1265 xxnet-1-1294 xxnet-1-1470489237406 xxnet-1-161301 xxnet-1-179915 xxnet-1-181703 xxnet-1-182011 xxnet-1-184213 xxnet-1-184705 xxnet-1-186703 xxnet-1-187504 xxnet-1-190711 xxnet-1-193607 xxnet-1-197113 xxnet-1-199505 xxnet-1-199912 xxnet-1-2008 xxnet-1-2009 xxnet-1-2010 xxnet-1-2011 xxnet-1-2012 xxnet-1-205004 xxnet-1-206406 xxnet-1-207305 xxnet-1-207807 xxnet-1-209000 xxnet-1-211015 xxnet-1-211500 xxnet-1-211501 xxnet-1-218515 xxnet-1-224107 xxnet-1-227015 xxnet-1-232206 xxnet-1-233308 xxnet-1-256910 xxnet-10 xxnet-10-1252 xxnet-10-1264 xxnet-10-1265 xxnet-10-1303 xxnet-10-147002 xxnet-10-184213 xxnet-10-184606 xxnet-10-184705 xxnet-10-187504 xxnet-10-208703 xxnet-10-211015 xxnet-10-214016 xxnet-100 xxnet-100001 xxnet-1001-200215 xxnet-1001-218313 xxnet-1001-226315 xxnet-10011 xxnet-10012 xxnet-1002-218313 xxnet-100201 xxnet-100202 xxnet-100203 xxnet-100204 xxnet-100205 xxnet-1003-218313 xxnet-1005-218313 xxnet-1006-218313 xxnet-10086-188007 xxnet-100a xxnet-101 xxnet-101-x xxnet-1017 xxnet-1017-183905 xxnet-1018 xxnet-1018-183905 xxnet-1019 xxnet-1019-183905 xxnet-102 xxnet-102-x xxnet-1020-183905 xxnet-10200 xxnet-1021 xxnet-1022 xxnet-1023 xxnet-1024 xxnet-1025 xxnet-1025-184012 xxnet-1026 xxnet-1026-184012 xxnet-1026171143 xxnet-1026171144 xxnet-1026171145 xxnet-1026171348 xxnet-1026171349 xxnet-1027 xxnet-1028 xxnet-1029 xxnet-103 xxnet-103-1188 xxnet-103-x xxnet-1030 xxnet-1031 xxnet-1032-1188 xxnet-1033 xxnet-1034 xxnet-1035 xxnet-1037 xxnet-104 xxnet-104-x xxnet-105 xxnet-105-x xxnet-1053 xxnet-1054 xxnet-106 xxnet-107 xxnet-108 xxnet-1088-211906 xxnet-109 xxnet-11 xxnet-11-1264 xxnet-11-1265 xxnet-11-1273 xxnet-11-147002 xxnet-11-184606 xxnet-11-187504 xxnet-11-202110 xxnet-11-211015 xxnet-11-214016 xxnet-11-233209 xxnet-110 xxnet-1101-211906 xxnet-11028 xxnet-11029 xxnet-111 xxnet-111-182502 xxnet-111-186201 xxnet-1111111 xxnet-111112 xxnet-111113 xxnet-111114 xxnet-111115 xxnet-111116 xxnet-111117 xxnet-111118 xxnet-111119 xxnet-112 xxnet-1122-211906 xxnet-11223344 xxnet-1123-186902 xxnet-1123581321 xxnet-1128-187402 xxnet-113 xxnet-113243 xxnet-11398 xxnet-114 xxnet-115 xxnet-11588 xxnet-11589 xxnet-116 xxnet-116110 xxnet-117 xxnet-118 xxnet-119 xxnet-12 xxnet-12-1264 xxnet-12-1265 xxnet-12-184606 xxnet-12-187504 xxnet-12-214016 xxnet-12-233209 xxnet-120 xxnet-120-187109 xxnet-1206-1 xxnet-12099 xxnet-121 xxnet-12123131 xxnet-122 xxnet-123 xxnet-123-186201 xxnet-123-224209 xxnet-12306-194202 xxnet-12307 xxnet-12308 xxnet-12309 xxnet-12309-194202 xxnet-123150 xxnet-1233-211906 xxnet-1234-1273 xxnet-1234-211906 xxnet-1234321-225212 xxnet-123445323 xxnet-12345-214204 xxnet-12345543 xxnet-123456 xxnet-123456-214204 xxnet-123456-239202 xxnet-123457 xxnet-123458 xxnet-123460 xxnet-123461 xxnet-123462 xxnet-123463 xxnet-1235-211906 xxnet-123567321 xxnet-123678 xxnet-124 xxnet-1248903 xxnet-1248904 xxnet-1248905 xxnet-1248906 xxnet-1248907 xxnet-125 xxnet-1252 xxnet-1255 xxnet-1256 xxnet-126 xxnet-12641 xxnet-1268 xxnet-1268841 xxnet-1268842 xxnet-1269 xxnet-127 xxnet-1270 xxnet-1271 xxnet-1272 xxnet-1273 xxnet-1274 xxnet-1275 xxnet-1276 xxnet-1277 xxnet-1278 xxnet-128 xxnet-129 xxnet-1291 xxnet-1292 xxnet-1293 xxnet-1294 xxnet-1295 xxnet-1296 xxnet-1297 xxnet-1298 xxnet-1299 xxnet-13 xxnet-130 xxnet-1300 xxnet-1301 xxnet-1302 xxnet-13081 xxnet-13082 xxnet-131 xxnet-131309 xxnet-131310 xxnet-131311 xxnet-131312 xxnet-131313 xxnet-131314 xxnet-131315 xxnet-131316 xxnet-131317 xxnet-131318 xxnet-131319 xxnet-131320 xxnet-131321 xxnet-131323 xxnet-132 xxnet-1321 xxnet-1327 xxnet-1328 xxnet-133 xxnet-134 xxnet-135 xxnet-13531 xxnet-135725 xxnet-136 xxnet-136847 xxnet-136901 xxnet-136923 xxnet-136924 xxnet-136925 xxnet-137 xxnet-1370-1370 xxnet-1376 xxnet-1377 xxnet-1378 xxnet-1379 xxnet-138 xxnet-1380 xxnet-1381 xxnet-1382 xxnet-1383 xxnet-1384 xxnet-139 xxnet-1396 xxnet-1397 xxnet-139904 xxnet-139905 xxnet-14 xxnet-14-214016 xxnet-140 xxnet-140705 xxnet-141 xxnet-1414114 xxnet-142 xxnet-142603 xxnet-142604 xxnet-142605 xxnet-142606 xxnet-142607 xxnet-142608 xxnet-142609 xxnet-143 xxnet-143404 xxnet-143602 xxnet-143603 xxnet-143604 xxnet-143606 xxnet-143607 xxnet-143608 xxnet-143609 xxnet-143610 xxnet-143611 xxnet-143612 xxnet-143613 xxnet-144 xxnet-1440 xxnet-1441 xxnet-14433 xxnet-14435 xxnet-145 xxnet-1451159047 xxnet-146 xxnet-14641 xxnet-147 xxnet-1470 xxnet-1470434997049 xxnet-1470566028726 xxnet-1470566228993 xxnet-147331 xxnet-147916 xxnet-147917 xxnet-14799 xxnet-148 xxnet-148412 xxnet-149 xxnet-150 xxnet-151 xxnet-151606 xxnet-151715 xxnet-152 xxnet-153 xxnet-154 xxnet-155 xxnet-156 xxnet-1564846 xxnet-15659 xxnet-15678 xxnet-157 xxnet-158 xxnet-1588 xxnet-159 xxnet-15927 xxnet-15927-227708 xxnet-15928 xxnet-15929 xxnet-15930 xxnet-15931 xxnet-15932 xxnet-15933 xxnet-15934 xxnet-15935 xxnet-15936 xxnet-15937 xxnet-15938 xxnet-16 xxnet-16091601 xxnet-16091602 xxnet-16091701 xxnet-16091702 xxnet-16091703 xxnet-161301 xxnet-162408 xxnet-162409 xxnet-163408 xxnet-16439 xxnet-1649911 xxnet-1649912 xxnet-1649913 xxnet-1649915 xxnet-1649916 xxnet-1649917 xxnet-165817 xxnet-165818 xxnet-165820 xxnet-1670 xxnet-1671 xxnet-1672 xxnet-1673 xxnet-1674 xxnet-1675 xxnet-1676 xxnet-1677 xxnet-1678 xxnet-1679 xxnet-1680 xxnet-1681 xxnet-1682 xxnet-1683 xxnet-1684 xxnet-1685 xxnet-1686 xxnet-168602 xxnet-1687 xxnet-169707-169707 xxnet-17 xxnet-17-233 xxnet-17-234 xxnet-17-235 xxnet-17-236 xxnet-17-237 xxnet-1707n1 xxnet-1707n10 xxnet-1707n11 xxnet-1707n12 xxnet-1707n2 xxnet-1707n4 xxnet-1707n5 xxnet-1707n6 xxnet-1707n7 xxnet-1707n8 xxnet-1707n9 xxnet-17101401 xxnet-17101402 xxnet-17101403 xxnet-171127 xxnet-17166 xxnet-1717-1 xxnet-1717-2 xxnet-1717-3 xxnet-1717-4 xxnet-171903-171903 xxnet-171910 xxnet-173011 xxnet-173012 xxnet-173013 xxnet-173014 xxnet-173015 xxnet-173016 xxnet-1730667 xxnet-1730668 xxnet-174008 xxnet-174009 xxnet-174010 xxnet-174011 xxnet-174012 xxnet-174013 xxnet-174014 xxnet-174315 xxnet-17452 xxnet-17474 xxnet-175305 xxnet-175814 xxnet-175916 xxnet-177622 xxnet-177914 xxnet-18 xxnet-18-181111 xxnet-18010601 xxnet-180308 xxnet-180309 xxnet-180310 xxnet-180311 xxnet-180312 xxnet-180313 xxnet-180314 xxnet-180315 xxnet-180316 xxnet-180317 xxnet-180318 xxnet-180319 xxnet-180320 xxnet-180321 xxnet-180322 xxnet-180323 xxnet-180801 xxnet-180808 xxnet-181 xxnet-181013 xxnet-1813 xxnet-1814 xxnet-1818-191511 xxnet-182 xxnet-182006 xxnet-182008 xxnet-182009 xxnet-182010 xxnet-182011 xxnet-182012 xxnet-182013 xxnet-182014 xxnet-182015 xxnet-182104 xxnet-182303 xxnet-182304 xxnet-182305 xxnet-183 xxnet-183009 xxnet-183141 xxnet-183406 xxnet-183407 xxnet-183409 xxnet-183427 xxnet-183457 xxnet-183470 xxnet-183513 xxnet-183607 xxnet-183905 xxnet-183906 xxnet-184 xxnet-184506 xxnet-184507 xxnet-184508 xxnet-184605 xxnet-184705 xxnet-184812 xxnet-185 xxnet-185001 xxnet-185106 xxnet-185304 xxnet-185403 xxnet-185404 xxnet-185406 xxnet-185415 xxnet-185502 xxnet-185505 xxnet-185613 xxnet-185614 xxnet-185705-185705 xxnet-185718 xxnet-185719 xxnet-185720 xxnet-185721 xxnet-185722 xxnet-185723 xxnet-185814 xxnet-185815 xxnet-185816 xxnet-185817 xxnet-185818 xxnet-185906 xxnet-185907 xxnet-185908 xxnet-185909 xxnet-185910 xxnet-186 xxnet-186016 xxnet-186186 xxnet-186201 xxnet-186222 xxnet-186223 xxnet-186301 xxnet-186419 xxnet-186420 xxnet-186421 xxnet-186422 xxnet-186424 xxnet-186425 xxnet-186426 xxnet-186427 xxnet-186428 xxnet-186429 xxnet-186502 xxnet-186602 xxnet-1866190 xxnet-186701 xxnet-186702 xxnet-186703 xxnet-186704 xxnet-186705 xxnet-186706 xxnet-186715 xxnet-186913 xxnet-187 xxnet-187002 xxnet-187204 xxnet-187206 xxnet-187207 xxnet-187208 xxnet-187209 xxnet-187212 xxnet-187303 xxnet-187407 xxnet-187514 xxnet-187515 xxnet-187516 xxnet-187813 xxnet-187913 xxnet-188 xxnet-188004 xxnet-188005 xxnet-188007 xxnet-188008 xxnet-188009 xxnet-188010 xxnet-188111 xxnet-188412-188412 xxnet-188506 xxnet-188608 xxnet-188707 xxnet-188708 xxnet-188709 xxnet-188710 xxnet-188711 xxnet-188715 xxnet-188903 xxnet-188904 xxnet-188905 xxnet-188906 xxnet-188907 xxnet-189012 xxnet-189415 xxnet-189703 xxnet-189816 xxnet-189902 xxnet-19 xxnet-1900 xxnet-190114 xxnet-190123 xxnet-190210 xxnet-190316 xxnet-190405 xxnet-190612 xxnet-190613 xxnet-190812 xxnet-190824 xxnet-190920 xxnet-191201 xxnet-191212 xxnet-191213 xxnet-191410 xxnet-191706 xxnet-1919-191511 xxnet-191919191 xxnet-192017 xxnet-192116 xxnet-192219 xxnet-192906 xxnet-19305 xxnet-193101 xxnet-193103 xxnet-193106 xxnet-193414 xxnet-193512 xxnet-193614 xxnet-19376 xxnet-193817 xxnet-194016 xxnet-194107 xxnet-194110 xxnet-194111 xxnet-194112 xxnet-194113 xxnet-194114 xxnet-194115 xxnet-194116 xxnet-194117 xxnet-194118 xxnet-194207 xxnet-194207-194207 xxnet-194208 xxnet-194209 xxnet-194210 xxnet-194307 xxnet-194418 xxnet-194808 xxnet-19551 xxnet-196106 xxnet-196107 xxnet-196108 xxnet-196109 xxnet-196110 xxnet-196302 xxnet-19640 xxnet-196405 xxnet-196408 xxnet-1964081 xxnet-1964082 xxnet-196412 xxnet-196413 xxnet-196414 xxnet-196415 xxnet-196416 xxnet-196417 xxnet-196501 xxnet-196510 xxnet-197604 xxnet-197620 xxnet-197621 xxnet-197622 xxnet-197623 xxnet-197624 xxnet-197625 xxnet-197626 xxnet-197627 xxnet-197628 xxnet-197629 xxnet-197630 xxnet-197631 xxnet-197701 xxnet-197816 xxnet-1985010101 xxnet-1986-193817 xxnet-198606 xxnet-198615 xxnet-198703 xxnet-19870702 xxnet-1991111 xxnet-1991112 xxnet-1992-186103 xxnet-199207 xxnet-1995-186103 xxnet-199512 xxnet-199513 xxnet-1997-186103 xxnet-1999-186105 xxnet-1ee1 xxnet-1ee2 xxnet-1ee3 xxnet-1ee4 xxnet-1ee5 xxnet-1ee6 xxnet-2 xxnet-2-1252 xxnet-2-1264 xxnet-2-1265 xxnet-2-1294 xxnet-2-142420 xxnet-2-1470489256157 xxnet-2-171901 xxnet-2-179915 xxnet-2-181013 xxnet-2-181703 xxnet-2-182006 xxnet-2-182011 xxnet-2-182815 xxnet-2-184213 xxnet-2-184606 xxnet-2-184705 xxnet-2-185501 xxnet-2-187212 xxnet-2-187504 xxnet-2-188111 xxnet-2-193607 xxnet-2-196917 xxnet-2-197816 xxnet-2-205004 xxnet-2-207305 xxnet-2-209000 xxnet-2-211015 xxnet-2-211501 xxnet-2-216201 xxnet-2-227015 xxnet-2-233308 xxnet-2-233811 xxnet-2-235202 xxnet-2-249806 xxnet-20 xxnet-200-1199 xxnet-2000-211906 xxnet-2000000 xxnet-200001 xxnet-200002 xxnet-200003 xxnet-200004 xxnet-200005 xxnet-200006 xxnet-200007 xxnet-20024 xxnet-200713 xxnet-200714 xxnet-201-1199 xxnet-201104 xxnet-201105 xxnet-2011056 xxnet-2011076 xxnet-201108 xxnet-2011086 xxnet-2011087 xxnet-2011096 xxnet-201113 xxnet-201114 xxnet-201306 xxnet-201614 xxnet-2016ka xxnet-2016kb xxnet-2016kc xxnet-2016kd xxnet-2016ke xxnet-2016kf xxnet-2016kg xxnet-2016kh xxnet-2016ki xxnet-2016kj xxnet-2016kk xxnet-2016km xxnet-2017-182809 xxnet-2017-182830 xxnet-2017-186105 xxnet-2017001a000 xxnet-2017001a001 xxnet-2017001a002 xxnet-2017001a003 xxnet-2017001a004 xxnet-2017001a005 xxnet-2017001a006 xxnet-2017001a007 xxnet-2017001a008 xxnet-2017001a009 xxnet-2017002a000 xxnet-2017002a001 xxnet-2017002a002 xxnet-2017002a003 xxnet-2017002a004 xxnet-2017002a005 xxnet-2017002a006 xxnet-2017002a007 xxnet-2017002a008 xxnet-2017002a009 xxnet-2017003a000 xxnet-2017003a001 xxnet-2017003a002 xxnet-2017003a003 xxnet-2017003a004 xxnet-2017003a005 xxnet-2017003a006 xxnet-2017003a007 xxnet-2017003a008 xxnet-2017003a009 xxnet-2017004a000 xxnet-2017004a001 xxnet-2017004a002 xxnet-2017004a003 xxnet-2017004a004 xxnet-2017004a005 xxnet-2017004a006 xxnet-2017004a007 xxnet-2017004a008 xxnet-2017004a009 xxnet-2017005a000 xxnet-2017005a001 xxnet-2017005a002 xxnet-2017005a003 xxnet-2017005a004 xxnet-2017005a005 xxnet-2017005a006 xxnet-2017005a007 xxnet-2017005a008 xxnet-2017005a009 xxnet-2017006a000 xxnet-2017006a001 xxnet-2017006a002 xxnet-2017006a003 xxnet-2017006a004 xxnet-2017006a005 xxnet-2017006a006 xxnet-2017006a007 xxnet-2017006a008 xxnet-2017006a009 xxnet-2017007a000 xxnet-2017007a001 xxnet-2017007a002 xxnet-2017007a003 xxnet-2017007a004 xxnet-2017007a005 xxnet-2017007a006 xxnet-2017007a007 xxnet-2017007a008 xxnet-2017007a009 xxnet-2017008a000 xxnet-2017008a001 xxnet-2017008a002 xxnet-2017008a003 xxnet-2017008a004 xxnet-2017008a005 xxnet-2017008a006 xxnet-2017008a007 xxnet-2017008a008 xxnet-2017008a009 xxnet-2017009a000 xxnet-2017009a001 xxnet-2017009a002 xxnet-2017009a003 xxnet-2017009a004 xxnet-2017009a005 xxnet-2017009a006 xxnet-2017009a007 xxnet-2017009a008 xxnet-2017009a009 xxnet-2017010a000 xxnet-2017010a001 xxnet-2017010a002 xxnet-2017010a003 xxnet-2017010a004 xxnet-2017010a005 xxnet-2017010a006 xxnet-2017010a007 xxnet-2017010a008 xxnet-2017010a009 xxnet-2017011a000 xxnet-2017011a001 xxnet-2017011a002 xxnet-2017011a003 xxnet-2017011a004 xxnet-2017011a005 xxnet-2017011a006 xxnet-2017011a007 xxnet-2017011a008 xxnet-2017011a009 xxnet-2017012a000 xxnet-2017012a001 xxnet-2017012a002 xxnet-2017012a003 xxnet-2017012a004 xxnet-2017012a005 xxnet-2017012a006 xxnet-2017012a007 xxnet-2017012a008 xxnet-2017012a009 xxnet-2017013a000 xxnet-2017013a001 xxnet-2017013a002 xxnet-2017013a003 xxnet-2017013a004 xxnet-2017013a005 xxnet-2017013a006 xxnet-2017013a007 xxnet-2017013a008 xxnet-2017013a009 xxnet-2017014a000 xxnet-2017014a001 xxnet-2017014a002 xxnet-2017014a003 xxnet-2017014a004 xxnet-2017014a005 xxnet-2017014a006 xxnet-2017014a007 xxnet-2017014a008 xxnet-2017014a009 xxnet-2017015a000 xxnet-2017015a001 xxnet-2017015a002 xxnet-2017015a003 xxnet-2017015a004 xxnet-2017015a005 xxnet-2017015a006 xxnet-2017015a007 xxnet-2017015a008 xxnet-2017015a009 xxnet-2017016a000 xxnet-2017016a001 xxnet-2017016a002 xxnet-2017016a003 xxnet-2017016a004 xxnet-2017016a005 xxnet-2017016a006 xxnet-2017016a007 xxnet-2017016a008 xxnet-2017016a009 xxnet-2017017a000 xxnet-2017017a001 xxnet-2017017a002 xxnet-2017017a003 xxnet-2017017a004 xxnet-2017017a005 xxnet-2017017a006 xxnet-2017017a007 xxnet-2017017a008 xxnet-2017017a009 xxnet-2017018a000 xxnet-2017018a001 xxnet-2017018a002 xxnet-2017018a003 xxnet-2017018a004 xxnet-2017018a005 xxnet-2017018a006 xxnet-2017018a007 xxnet-2017018a008 xxnet-2017018a009 xxnet-2017019a000 xxnet-2017019a001 xxnet-2017019a002 xxnet-2017019a003 xxnet-2017019a004 xxnet-2017019a005 xxnet-2017019a006 xxnet-2017019a007 xxnet-2017019a008 xxnet-2017019a009 xxnet-2017020a000 xxnet-2017020a001 xxnet-2017020a002 xxnet-2017020a003 xxnet-2017020a004 xxnet-2017020a005 xxnet-2017020a006 xxnet-2017020a007 xxnet-2017020a008 xxnet-2017020a009 xxnet-20170601 xxnet-20170602 xxnet-2017100902 xxnet-2017100903 xxnet-2017100904 xxnet-2017100905 xxnet-20171013 xxnet-20171126 xxnet-201712041 xxnet-20171225 xxnet-201716 xxnet-20171610 xxnet-20171611 xxnet-2017162 xxnet-2017163 xxnet-2017164 xxnet-2017165 xxnet-2017166 xxnet-2017167 xxnet-2017168-154812 xxnet-2017169 xxnet-2018-190707 xxnet-2018-226106 xxnet-201801051632 xxnet-20180114-192101 xxnet-20180121 xxnet-20180122 xxnet-201803 xxnet-20180311 xxnet-20180312 xxnet-20180313 xxnet-20180410 xxnet-20180709 xxnet-201807094-209714 xxnet-20180816 xxnet-20180816-213514 xxnet-2018081600 xxnet-2018081601 xxnet-2018081602 xxnet-2018081603 xxnet-2018081604 xxnet-2018081605 xxnet-2018081606 xxnet-2018081607 xxnet-2018081608 xxnet-2018081609 xxnet-20180820 xxnet-2018082602 xxnet-2018082603 xxnet-2018082604 xxnet-20180900 xxnet-20180901 xxnet-20180902 xxnet-20180903 xxnet-20180904 xxnet-20180905 xxnet-20180906 xxnet-20180907 xxnet-20180908 xxnet-20180909 xxnet-20180910 xxnet-201811 xxnet-20181201 xxnet-20181202 xxnet-20181203 xxnet-20181204 xxnet-20181204-224602 xxnet-20181205 xxnet-20181205-224602 xxnet-20181206 xxnet-20181207 xxnet-20181208 xxnet-20181209 xxnet-20181210 xxnet-20181211 xxnet-20190123 xxnet-20190128 xxnet-20190131 xxnet-20190131a xxnet-20190131b xxnet-20190131c xxnet-20190131d xxnet-201902190908 xxnet-2019021909081128 xxnet-20190225 xxnet-20190226 xxnet-20190227 xxnet-20190228 xxnet-20190228-232811 xxnet-20190301 xxnet-20190302 xxnet-20190303 xxnet-2019030301 xxnet-2019030302 xxnet-20190304 xxnet-20190305 xxnet-20190306 xxnet-20190307 xxnet-201904211824 xxnet-201904211828 xxnet-201908 xxnet-20190823a xxnet-20190823b xxnet-20190925 xxnet-202-1199 xxnet-202205 xxnet-202414 xxnet-203-1199 xxnet-203108 xxnet-203500 xxnet-203802 xxnet-203852938 xxnet-204-1199 xxnet-20401 xxnet-20402 xxnet-20403 xxnet-204406 xxnet-204711 xxnet-2047113 xxnet-204719 xxnet-205-1199 xxnet-205202 xxnet-205702 xxnet-205703 xxnet-205705 xxnet-205706 xxnet-205707 xxnet-205708 xxnet-205709 xxnet-205710 xxnet-205711 xxnet-205712 xxnet-205713 xxnet-206-1199 xxnet-206203 xxnet-206752 xxnet-206903 xxnet-207-1199 xxnet-207003 xxnet-207011 xxnet-20712 xxnet-207312 xxnet-207315 xxnet-207609 xxnet-208106 xxnet-208507 xxnet-2090 xxnet-2091 xxnet-2092 xxnet-2093 xxnet-2094 xxnet-2095 xxnet-2096 xxnet-209616 xxnet-2097 xxnet-2098 xxnet-2099 xxnet-209902 xxnet-209903 xxnet-21 xxnet-210002 xxnet-210206 xxnet-210602 xxnet-211015 xxnet-21111-211906 xxnet-211802 xxnet-212302 xxnet-21232123 xxnet-212405 xxnet-212702 xxnet-2137 xxnet-214016 xxnet-214114 xxnet-214115 xxnet-214214 xxnet-214503 xxnet-215102 xxnet-215103 xxnet-215111 xxnet-215413 xxnet-215902 xxnet-215904 xxnet-215910 xxnet-215911 xxnet-2159118 xxnet-2159119 xxnet-215913 xxnet-215916 xxnet-215917 xxnet-215921 xxnet-215922 xxnet-216012 xxnet-216109 xxnet-216915 xxnet-217301 xxnet-217403 xxnet-217607 xxnet-218302 xxnet-218313 xxnet-218323 xxnet-218403 xxnet-218404 xxnet-218705 xxnet-219901 xxnet-22 xxnet-22-1273 xxnet-22-225902 xxnet-220306 xxnet-2203061 xxnet-2204306 xxnet-220609 xxnet-221713 xxnet-2220306 xxnet-222211 xxnet-22233 xxnet-222502 xxnet-223701 xxnet-223708 xxnet-223709 xxnet-224104 xxnet-224208 xxnet-224602 xxnet-225402 xxnet-225902 xxnet-225906 xxnet-226201 xxnet-226202 xxnet-226301 xxnet-226317 xxnet-226318 xxnet-226601 xxnet-226908 xxnet-227710 xxnet-227806 xxnet-228003 xxnet-22832 xxnet-228613 xxnet-229003 xxnet-229101 xxnet-229207 xxnet-229405 xxnet-229515 xxnet-229801 xxnet-23 xxnet-230105 xxnet-230306 xxnet-230617 xxnet-230711 xxnet-230915 xxnet-231 xxnet-231104 xxnet-231501 xxnet-2315017 xxnet-2315037 xxnet-2315047 xxnet-2315057 xxnet-2315067 xxnet-231507 xxnet-2315071 xxnet-2315077 xxnet-2315087 xxnet-2315807 xxnet-2315907 xxnet-232 xxnet-232105 xxnet-232106 xxnet-2322 xxnet-2323 xxnet-232304 xxnet-23230423 xxnet-23245 xxnet-233 xxnet-233001 xxnet-233107 xxnet-233108 xxnet-233109 xxnet-233110 xxnet-233333-185712 xxnet-2336 xxnet-233806 xxnet-233807 xxnet-234 xxnet-234-1q xxnet-234004 xxnet-2341 xxnet-234103 xxnet-2343 xxnet-2347 xxnet-2348 xxnet-2349 xxnet-23491 xxnet-234ghgs xxnet-235 xxnet-235115 xxnet-235404 xxnet-23555 xxnet-23556 xxnet-23557 xxnet-2356 xxnet-235903 xxnet-235917 xxnet-236 xxnet-237 xxnet-237003 xxnet-237010 xxnet-237410 xxnet-237411 xxnet-237502 xxnet-237807 xxnet-238 xxnet-23848 xxnet-239 xxnet-239712 xxnet-239911 xxnet-24 xxnet-240 xxnet-240009 xxnet-240709 xxnet-241 xxnet-242 xxnet-242004 xxnet-242712 xxnet-243802 xxnet-244504 xxnet-244611 xxnet-2456 xxnet-24626 xxnet-246818 xxnet-246914 xxnet-249102 xxnet-249604 xxnet-249803 xxnet-249806 xxnet-25 xxnet-250116 xxnet-250123 xxnet-250160 xxnet-250217 xxnet-251106 xxnet-251301 xxnet-251900 xxnet-251901 xxnet-25305 xxnet-253309 xxnet-253310 xxnet-253311 xxnet-253311-253309 xxnet-255 xxnet-256002 xxnet-256105 xxnet-256602 xxnet-256608 xxnet-257302 xxnet-257304 xxnet-257701 xxnet-2580 xxnet-2581 xxnet-2582 xxnet-2583 xxnet-2584 xxnet-2585 xxnet-2586 xxnet-2587 xxnet-2588 xxnet-2588-209014 xxnet-2589 xxnet-2590 xxnet-26 xxnet-26199 xxnet-26389 xxnet-26868 xxnet-27 xxnet-27044 xxnet-27636 xxnet-276893 xxnet-27887 xxnet-27980 xxnet-28 xxnet-28198 xxnet-28401 xxnet-28764 xxnet-29 xxnet-29250 xxnet-294 xxnet-295 xxnet-3 xxnet-3-1252 xxnet-3-1264 xxnet-3-1265 xxnet-3-1294 xxnet-3-1470489266796 xxnet-3-181013 xxnet-3-181703 xxnet-3-182006 xxnet-3-182011 xxnet-3-182815 xxnet-3-184213 xxnet-3-184606 xxnet-3-184705 xxnet-3-187504 xxnet-3-193607 xxnet-3-196917 xxnet-3-197816 xxnet-3-205004 xxnet-3-209000 xxnet-3-211015 xxnet-3-211501 xxnet-3-214016 xxnet-3-227015 xxnet-3-233308 xxnet-3-233811 xxnet-30 xxnet-300001 xxnet-300002 xxnet-300003 xxnet-300004 xxnet-300005 xxnet-300006 xxnet-300007 xxnet-300008 xxnet-300009 xxnet-300009-228901 xxnet-300010 xxnet-300011 xxnet-300110 xxnet-300111 xxnet-3021 xxnet-30982 xxnet-31 xxnet-311 xxnet-31169-238008 xxnet-3123456 xxnet-3123457 xxnet-31415 xxnet-3141501 xxnet-3141502 xxnet-3141503 xxnet-3141504 xxnet-3141505 xxnet-3141506 xxnet-3141507 xxnet-3141508 xxnet-3141509 xxnet-3141511 xxnet-3141512 xxnet-3141513 xxnet-3141514 xxnet-3141515 xxnet-3141516 xxnet-3141517 xxnet-3141518 xxnet-3141519 xxnet-3141520 xxnet-31605 xxnet-31718 xxnet-32 xxnet-32-1273 xxnet-321 xxnet-322 xxnet-323 xxnet-324 xxnet-3245325 xxnet-326 xxnet-327 xxnet-329 xxnet-33 xxnet-33-1273 xxnet-330 xxnet-331 xxnet-332 xxnet-3326 xxnet-3338 xxnet-33443 xxnet-3345 xxnet-3346 xxnet-3347 xxnet-3348 xxnet-3349 xxnet-34 xxnet-34708 xxnet-347952 xxnet-35 xxnet-351 xxnet-35400 xxnet-35400-208609 xxnet-35422 xxnet-35488 xxnet-35789-171400 xxnet-35789-214215 xxnet-36 xxnet-36922 xxnet-36969 xxnet-37 xxnet-371400 xxnet-371401 xxnet-371402 xxnet-371403 xxnet-371404 xxnet-371405 xxnet-371406 xxnet-371407 xxnet-371408 xxnet-371409 xxnet-371410 xxnet-371411 xxnet-3720 xxnet-37245 xxnet-38 xxnet-38584 xxnet-39 xxnet-39474 xxnet-39475 xxnet-39476 xxnet-39477 xxnet-3952 xxnet-4 xxnet-4-1252 xxnet-4-1264 xxnet-4-1265 xxnet-4-1294 xxnet-4-1470489307188 xxnet-4-181703 xxnet-4-182006 xxnet-4-182011 xxnet-4-182815 xxnet-4-184213 xxnet-4-184606 xxnet-4-184705 xxnet-4-187504 xxnet-4-196917 xxnet-4-197816 xxnet-4-199505 xxnet-4-205004 xxnet-4-211015 xxnet-4-214016 xxnet-4-216002 xxnet-4-227015 xxnet-4-233308 xxnet-4-233811 xxnet-40 xxnet-4011 xxnet-4011-192902 xxnet-4011-193007 xxnet-4012 xxnet-4012-192902 xxnet-4012-193007 xxnet-4013 xxnet-4013-193007 xxnet-4014 xxnet-4014-193007 xxnet-4015 xxnet-4015-193007 xxnet-4016 xxnet-4016-193007 xxnet-4017 xxnet-4017-193007 xxnet-4018 xxnet-4018-193007 xxnet-4019 xxnet-4019-193007 xxnet-4020 xxnet-4020-193007 xxnet-4021 xxnet-4021-193007 xxnet-4022 xxnet-4022-193007 xxnet-40944 xxnet-41 xxnet-42 xxnet-4201 xxnet-42033 xxnet-42630 xxnet-42744 xxnet-43 xxnet-44 xxnet-44144 xxnet-44156 xxnet-44279 xxnet-44566 xxnet-4494 xxnet-45 xxnet-45269 xxnet-4562103 xxnet-456290 xxnet-46 xxnet-46008 xxnet-46079 xxnet-4620 xxnet-46261 xxnet-46565 xxnet-466008 xxnet-46745 xxnet-46768 xxnet-468935 xxnet-47 xxnet-47437 xxnet-47614 xxnet-48 xxnet-48511 xxnet-4869 xxnet-48965 xxnet-49 xxnet-49022 xxnet-49280 xxnet-4980 xxnet-4s5-1 xxnet-5 xxnet-5-1252 xxnet-5-1264 xxnet-5-1265 xxnet-5-1294 xxnet-5-1470489318289 xxnet-5-181703 xxnet-5-182007 xxnet-5-182011 xxnet-5-182815 xxnet-5-184213 xxnet-5-184606 xxnet-5-184705 xxnet-5-187504 xxnet-5-196917 xxnet-5-197816 xxnet-5-199505 xxnet-5-205004 xxnet-5-211015 xxnet-5-214016 xxnet-5-220306 xxnet-5-227308 xxnet-5-233308 xxnet-5-233811 xxnet-50 xxnet-500 xxnet-5000-205202 xxnet-5001 xxnet-5001-205202 xxnet-5002 xxnet-501 xxnet-502 xxnet-503 xxnet-50306 xxnet-504 xxnet-505 xxnet-506 xxnet-50619 xxnet-507 xxnet-508 xxnet-509 xxnet-51 xxnet-510 xxnet-511 xxnet-514987111 xxnet-514987444 xxnet-5168 xxnet-5169 xxnet-51838 xxnet-51990 xxnet-52 xxnet-520001 xxnet-520002 xxnet-520003 xxnet-520004 xxnet-520005 xxnet-520006 xxnet-520007 xxnet-520008 xxnet-520009 xxnet-520010 xxnet-520011 xxnet-520012 xxnet-53 xxnet-5331 xxnet-54 xxnet-5438 xxnet-5443 xxnet-5465 xxnet-55 xxnet-5545 xxnet-55502 xxnet-556 xxnet-56 xxnet-5692aa xxnet-5693aa xxnet-57 xxnet-57420 xxnet-576190 xxnet-58 xxnet-59 xxnet-594463981 xxnet-59808 xxnet-6 xxnet-6-1252 xxnet-6-1264 xxnet-6-1265 xxnet-6-1294 xxnet-6-182007 xxnet-6-184202 xxnet-6-184213 xxnet-6-184606 xxnet-6-184705 xxnet-6-187504 xxnet-6-197816 xxnet-6-205004 xxnet-6-208703 xxnet-6-214016 xxnet-6-227308 xxnet-60 xxnet-601 xxnet-602 xxnet-603 xxnet-604 xxnet-605 xxnet-606 xxnet-607 xxnet-608 xxnet-609 xxnet-61 xxnet-610 xxnet-611 xxnet-612 xxnet-613 xxnet-614 xxnet-615 xxnet-616 xxnet-617 xxnet-618 xxnet-619 xxnet-62 xxnet-620 xxnet-621 xxnet-62576 xxnet-62912 xxnet-62963 xxnet-63 xxnet-63723 xxnet-63997 xxnet-64 xxnet-64187 xxnet-64270 xxnet-64453 xxnet-65 xxnet-6553601 xxnet-6553607 xxnet-66 xxnet-66-184202 xxnet-6623 xxnet-66615 xxnet-66616 xxnet-66617 xxnet-66661 xxnet-667-183908 xxnet-67 xxnet-67168 xxnet-67363 xxnet-68 xxnet-6814 xxnet-6825 xxnet-6853 xxnet-6854 xxnet-6855 xxnet-68558 xxnet-6856 xxnet-6856-1251 xxnet-6857 xxnet-6858 xxnet-6859 xxnet-6870 xxnet-6871 xxnet-6872 xxnet-69 xxnet-6x6666 xxnet-7 xxnet-7-1252 xxnet-7-1264 xxnet-7-1265 xxnet-7-1294 xxnet-7-182007 xxnet-7-184213 xxnet-7-184606 xxnet-7-184705 xxnet-7-185209 xxnet-7-197816 xxnet-7-205004 xxnet-7-208703 xxnet-7-211015 xxnet-7-214016 xxnet-70 xxnet-7096 xxnet-70983 xxnet-71 xxnet-71495 xxnet-72 xxnet-731220 xxnet-74 xxnet-7418-201902191041 xxnet-74523 xxnet-75 xxnet-76 xxnet-77 xxnet-77121649 xxnet-77504 xxnet-77541 xxnet-7777-233503 xxnet-78 xxnet-786446581-1 xxnet-786446581-2 xxnet-786446581-3 xxnet-786446581-4 xxnet-786446581-5 xxnet-786446581-6 xxnet-786446581-7 xxnet-79 xxnet-79412 xxnet-7963 xxnet-7964 xxnet-7965 xxnet-7966 xxnet-7967 xxnet-7968 xxnet-8 xxnet-8-1252 xxnet-8-1264 xxnet-8-1265 xxnet-8-1294 xxnet-8-182007 xxnet-8-184213 xxnet-8-184606 xxnet-8-184705 xxnet-8-185209 xxnet-8-187504 xxnet-8-197816 xxnet-8-205004 xxnet-8-208703 xxnet-8-214016 xxnet-80 xxnet-80221 xxnet-80374 xxnet-81 xxnet-81230 xxnet-81322 xxnet-81706 xxnet-81733 xxnet-82 xxnet-8222 xxnet-83 xxnet-84 xxnet-84114a xxnet-84114c xxnet-84114d xxnet-84114e xxnet-84114f xxnet-84114g xxnet-84114h xxnet-84114j xxnet-84114k xxnet-84114m xxnet-84114n xxnet-84585 xxnet-84832 xxnet-84868 xxnet-85 xxnet-86 xxnet-86212 xxnet-865180983-01 xxnet-865180983-02 xxnet-865180983-03 xxnet-87 xxnet-874184 xxnet-87658 xxnet-87677 xxnet-87742 xxnet-88 xxnet-8881 xxnet-8882 xxnet-89 xxnet-89039003 xxnet-89275 xxnet-896thy xxnet-9 xxnet-9-1252 xxnet-9-1264 xxnet-9-1265 xxnet-9-1294 xxnet-9-184213 xxnet-9-184705 xxnet-9-185209 xxnet-9-187504 xxnet-9-208703 xxnet-9-211015 xxnet-9-214016 xxnet-90 xxnet-900001 xxnet-9011 xxnet-9012 xxnet-905 xxnet-906 xxnet-907 xxnet-908 xxnet-9089 xxnet-909 xxnet-9091 xxnet-9092 xxnet-91 xxnet-910 xxnet-911 xxnet-91170 xxnet-91310 xxnet-9164 xxnet-92 xxnet-92280 xxnet-92676 xxnet-92676-213116 xxnet-93 xxnet-93050 xxnet-93069 xxnet-93279 xxnet-93967 xxnet-94 xxnet-942640 xxnet-94575 xxnet-9489 xxnet-95 xxnet-95111 xxnet-954 xxnet-95413 xxnet-956197212 xxnet-96 xxnet-9616811 xxnet-96170 xxnet-96173 xxnet-96804 xxnet-96928 xxnet-96928-57857 xxnet-97 xxnet-98 xxnet-980311 xxnet-986 xxnet-9875 xxnet-9876-203514 xxnet-98947 xxnet-99 xxnet-99164-240411 xxnet-9955 xxnet-996 xxnet-99668 xxnet-99764 xxnet-999 xxnet-99901 xxnet-99902 xxnet-99903 xxnet-99904 xxnet-99905 xxnet-99906 xxnet-99907 xxnet-99908 xxnet-99909 xxnet-99910 xxnet-99911 xxnet-99912 xxnet-a-191001 xxnet-a-226318 xxnet-a-226609 xxnet-a2 xxnet-a3 xxnet-a372872 xxnet-a372872-184509 xxnet-aa-187503 xxnet-aaa xxnet-abc-188015 xxnet-abiding-lead-162410 xxnet-abroad xxnet-abroad-2 xxnet-adol1 xxnet-adv01 xxnet-adv02 xxnet-adv03 xxnet-adv04 xxnet-adv05 xxnet-adv06 xxnet-adv07 xxnet-adv08 xxnet-adv09 xxnet-adv10 xxnet-adv11 xxnet-adv12 xxnet-akbxx101 xxnet-akbxx102 xxnet-akbxx103 xxnet-akbxx104 xxnet-akbxx105 xxnet-akbxx106 xxnet-akbxx107 xxnet-akbxx108 xxnet-akbxx109 xxnet-akbxx111 xxnet-al1 xxnet-al26313 xxnet-alex3016-1 xxnet-alex3016-2 xxnet-alex3016-3 xxnet-alex3016-4 xxnet-alex3016-5 xxnet-alex3016-6 xxnet-algebraic-depot-187413 xxnet-alien-sol-226702 xxnet-alphago xxnet-alphago-176603 xxnet-andsoareyou xxnet-any008 xxnet-any009 xxnet-any010 xxnet-aono001 xxnet-aono002 xxnet-aow1 xxnet-aow2 xxnet-aow3 xxnet-aow4 xxnet-app30 xxnet-app31 xxnet-appid-001 xxnet-appid-228515 xxnet-appid-230211 xxnet-appid01 xxnet-application-1033 xxnet-apro-01 xxnet-apro-02 xxnet-apro-03 xxnet-asxvccb xxnet-attention-2215 xxnet-aw-01 xxnet-aw-02 xxnet-aw-03 xxnet-aw-04 xxnet-aw-05 xxnet-aw-06 xxnet-aw-07 xxnet-aw-08 xxnet-aw-09 xxnet-aw-10 xxnet-aw-11 xxnet-aw-12 xxnet-b-191001 xxnet-b-226318 xxnet-bb-187503 xxnet-betykang01 xxnet-betykang02 xxnet-bin-1 xxnet-bled01 xxnet-bled02 xxnet-bled03 xxnet-bled04 xxnet-bob1 xxnet-bob2 xxnet-bona-1 xxnet-bona-2 xxnet-bona-3 xxnet-bona-4 xxnet-bona-5 xxnet-bsl001 xxnet-bsl002 xxnet-bsl003 xxnet-burner-248708 xxnet-c-191001 xxnet-c-226318 xxnet-c-226609 xxnet-calvne xxnet-calvneice xxnet-cc-187503 xxnet-cheathao1 xxnet-cheathao2 xxnet-chegan1 xxnet-chegan2 xxnet-chenzn1 xxnet-chenzn2 xxnet-chenzn3 xxnet-chenzn4 xxnet-chenzn5 xxnet-chncnlp xxnet-chncnlp2 xxnet-chris-cn-0 xxnet-chris-cn-1 xxnet-chris-cn-2 xxnet-chris-cn-3 xxnet-chris-cn-4 xxnet-chris-cn-5 xxnet-chris-cn-6 xxnet-chris-cn-7 xxnet-chris-cn-8 xxnet-chris-cn-9 xxnet-cjzs1 xxnet-cjzs10 xxnet-cjzs11 xxnet-cjzs2 xxnet-cjzs3 xxnet-cjzs4 xxnet-cjzs5 xxnet-cjzs6 xxnet-cjzs7 xxnet-cjzs8 xxnet-cjzs9 xxnet-clgg-1010 xxnet-clgg-1011 xxnet-clgg-1012 xxnet-cng1 xxnet-cng10 xxnet-cng11 xxnet-cng12 xxnet-cng2 xxnet-cng3 xxnet-cng4 xxnet-cng5 xxnet-cng6 xxnet-cng7 xxnet-cng8 xxnet-cng9 xxnet-cntchen xxnet-code xxnet-coffe-1 xxnet-coffe-10 xxnet-coffe-11 xxnet-coffe-12 xxnet-coffe-2 xxnet-coffe-3 xxnet-coffe-4 xxnet-coffe-5 xxnet-coffe-6 xxnet-coffe-7 xxnet-coffe-8 xxnet-coffe-9 xxnet-con01 xxnet-con02 xxnet-con03 xxnet-con04 xxnet-con05 xxnet-con06 xxnet-con07 xxnet-con08 xxnet-con09 xxnet-con10 xxnet-con11 xxnet-con12 xxnet-cove-184808 xxnet-csjzc xxnet-csjzc1 xxnet-custardcup xxnet-custardpie xxnet-custardpowder xxnet-custards xxnet-custerite xxnet-custode xxnet-cx-1 xxnet-cx-2 xxnet-cx-3 xxnet-cx-4 xxnet-cx-5 xxnet-d-191001 xxnet-d-226318 xxnet-d-226609 xxnet-d01 xxnet-d01-185014 xxnet-d02 xxnet-d02-185014 xxnet-d03 xxnet-d04 xxnet-d05 xxnet-d06 xxnet-d2131 xxnet-d701 xxnet-d702 xxnet-d703 xxnet-d704 xxnet-da-01 xxnet-da-02 xxnet-da01 xxnet-da02 xxnet-da03 xxnet-da04 xxnet-da05 xxnet-dbd01 xxnet-dbd02 xxnet-dbd04 xxnet-dbd05 xxnet-dbd06 xxnet-dbd07 xxnet-dbd08 xxnet-destiny-184808 xxnet-devn1101 xxnet-dfaggf xxnet-diyag-01 xxnet-djs1 xxnet-djs2 xxnet-djs3 xxnet-djs4 xxnet-djs5 xxnet-djs6 xxnet-djs7 xxnet-dmw02 xxnet-dn001 xxnet-dn002 xxnet-dn003 xxnet-dn004 xxnet-dn005 xxnet-dn006 xxnet-dntbylu1 xxnet-do xxnet-donate xxnet-donate-001-187502 xxnet-donate-0010-40469 xxnet-donate-0011-59245 xxnet-donate-0012-21393 xxnet-donate-003-80571 xxnet-donate-004-20785 xxnet-donate-005-1825 xxnet-donate-006-39642 xxnet-donate-007-69769 xxnet-donate-008-500 xxnet-donate-009-63904 xxnet-donate-01 xxnet-donate-01-220912 xxnet-donate-1 xxnet-donate-1-184903 xxnet-donate-193608 xxnet-donate-2 xxnet-donate-245802 xxnet-donate-3 xxnet-donate-id xxnet-donate-junting1 xxnet-donate001 xxnet-donate002 xxnet-donate1-186509 xxnet-donate1-187508 xxnet-donate1-196407 xxnet-donate1-236708 xxnet-donate2-186509 xxnet-donate2-187508 xxnet-donate2-196407 xxnet-donate2-236708 xxnet-donate3-236708 xxnet-donate4-236708 xxnet-donate5-236708 xxnet-donatelxd1 xxnet-donatelxd1-220102 xxnet-donatelxd2 xxnet-donatelxd3 xxnet-dongdongdonate xxnet-dtdtrr1 xxnet-e-191001 xxnet-e-226609 xxnet-ee xxnet-eighth-veld-162410 xxnet-ellipsia xxnet-ellipsia-189114 xxnet-ellipsia-2 xxnet-ellipsia-3 xxnet-en-130 xxnet-en-131 xxnet-en-132 xxnet-enaihei-a xxnet-enaihei-b xxnet-enaihei-c xxnet-enaihei-d xxnet-enaihei-e xxnet-enaihei-f xxnet-enaihei-g xxnet-environs-124806 xxnet-etc xxnet-etc02 xxnet-etc03 xxnet-etc04 xxnet-etc05 xxnet-etc06 xxnet-ethanzhu1109 xxnet-ethanzhu110902 xxnet-ethanzhu110903 xxnet-evachen xxnet-exh01 xxnet-exh02 xxnet-exh03 xxnet-exh04 xxnet-exh05 xxnet-exh06 xxnet-exh07 xxnet-exh08 xxnet-exh09 xxnet-exh10 xxnet-exh11 xxnet-exh12 xxnet-f-191001 xxnet-f0rrest-cn10 xxnet-f0rrest-cn11 xxnet-f21 xxnet-f22 xxnet-f23 xxnet-f24 xxnet-f25 xxnet-f26 xxnet-fafa xxnet-fangxw-do-01 xxnet-fangxw-do-02 xxnet-fcxnydew xxnet-fek xxnet-fengye xxnet-fengye-237300 xxnet-fengye01 xxnet-fengye02 xxnet-fengye05 xxnet-fengye06 xxnet-fengye07 xxnet-fengye08 xxnet-fengye09 xxnet-fengye10 xxnet-fengye11 xxnet-ff1 xxnet-ff2 xxnet-ff3 xxnet-ff4 xxnet-ff5 xxnet-fgfw xxnet-fgfw-1 xxnet-fgfw-2 xxnet-fin01 xxnet-fin02 xxnet-fin03 xxnet-fin04 xxnet-fin05 xxnet-fin06 xxnet-fin07 xxnet-fin09 xxnet-fin10 xxnet-fin11 xxnet-fin12 xxnet-first-221705 xxnet-fjcyyjcf5 xxnet-fk01 xxnet-fk02 xxnet-fk03 xxnet-flux-184808 xxnet-flykarry1 xxnet-flykarry10 xxnet-flykarry11 xxnet-flykarry2 xxnet-flykarry5 xxnet-flykarry6 xxnet-flykarry7 xxnet-flykarry8 xxnet-flykarry9-218303 xxnet-for-xtunnel xxnet-forpublic xxnet-forxchannel1 xxnet-forxchannel2 xxnet-forzcy4 xxnet-forzcy5 xxnet-forzcy6 xxnet-forzcy7 xxnet-foshan2 xxnet-foshan3 xxnet-foshan4 xxnet-foshan5 xxnet-foshan6 xxnet-foshan7 xxnet-fran xxnet-frank1 xxnet-frank2 xxnet-free01-245209 xxnet-free20180822 xxnet-fu001-00 xxnet-fu001-01 xxnet-fu001-02 xxnet-fu001-03 xxnet-fu001-04 xxnet-fw021 xxnet-fw022 xxnet-fw023 xxnet-fw024 xxnet-fw025 xxnet-fw026 xxnet-fw9020 xxnet-fy1-196501 xxnet-g-189807 xxnet-gagahaha xxnet-game xxnet-gate-184808 xxnet-gate-199205 xxnet-gd01 xxnet-gd02 xxnet-gd03 xxnet-gdei01-188912 xxnet-gdonat0 xxnet-gdonate1 xxnet-gfwed-1 xxnet-gfwed-1-237006 xxnet-gfwed-2 xxnet-gfwed-3 xxnet-gfwed-4 xxnet-gfwed-5 xxnet-gfwed-7 xxnet-gfwed-9 xxnet-gg xxnet-gggion-196917 xxnet-gift xxnet-gift999 xxnet-give1 xxnet-give2 xxnet-give3 xxnet-gkkill1 xxnet-gkkill2 xxnet-gkz001 xxnet-glow-200714 xxnet-gmxshare001 xxnet-go-188707 xxnet-goole-186801 xxnet-guguibin1 xxnet-guguibin2 xxnet-h-191001 xxnet-h-226412 xxnet-h1 xxnet-h2 xxnet-h3 xxnet-haha-205003 xxnet-hahaga xxnet-hahge xxnet-haixuling1 xxnet-haixuling2 xxnet-hbq xxnet-he-210711 xxnet-hello xxnet-hello-123 xxnet-hello-185106 xxnet-hello-204613 xxnet-hello-244611 xxnet-hello0 xxnet-help-go1 xxnet-help-go2 xxnet-helper xxnet-henu-001 xxnet-herry xxnet-hf001 xxnet-hf002 xxnet-hf003 xxnet-hf004 xxnet-hh-187504 xxnet-hifes xxnet-hihibin xxnet-hirro029-01 xxnet-hj-01 xxnet-hj-02 xxnet-hj-03 xxnet-hj-04 xxnet-hj-05 xxnet-hj-06 xxnet-hj-07 xxnet-hj-08 xxnet-hj-09 xxnet-hj-10 xxnet-hj-11 xxnet-hj-12 xxnet-hjwhuhu1 xxnet-hjwhuhu2 xxnet-hjwhuhu3 xxnet-hk-1001 xxnet-hk-1002 xxnet-hk-1003 xxnet-hk-1004 xxnet-hk-1005 xxnet-holle10-donate xxnet-holle11-donate xxnet-holle12-donate xxnet-honkerjha007 xxnet-honlessy xxnet-honlessy02 xxnet-hr01 xxnet-hr02 xxnet-hr03 xxnet-hr04 xxnet-hr05 xxnet-hr06 xxnet-hr07 xxnet-hr08 xxnet-hr09 xxnet-hr10 xxnet-hr11 xxnet-hr12 xxnet-hua01 xxnet-hua03 xxnet-huang1 xxnet-huanggusheng xxnet-huju122547 xxnet-hyh01 xxnet-hyh2-09 xxnet-hyh2-10 xxnet-hyh2-11 xxnet-hyh2-12 xxnet-hyh203 xxnet-hzb-1 xxnet-hzb-2 xxnet-hzb-3 xxnet-i-191001 xxnet-iammkc xxnet-ian01 xxnet-ian02 xxnet-ian03 xxnet-ian04 xxnet-ian05 xxnet-ian06 xxnet-ian07 xxnet-ian08 xxnet-ian09 xxnet-ian1 xxnet-ian10 xxnet-ian11 xxnet-ian12 xxnet-ian13 xxnet-ian14 xxnet-ian15 xxnet-ian16 xxnet-ian17 xxnet-ian18 xxnet-ian19 xxnet-ian20 xxnet-ian21 xxnet-ian22 xxnet-ian23 xxnet-ian24 xxnet-ian25 xxnet-ian26 xxnet-ian27 xxnet-ian28 xxnet-ian29 xxnet-ian30 xxnet-ian31 xxnet-ian32 xxnet-ian33 xxnet-ian34 xxnet-ian35 xxnet-ian36 xxnet-ian37 xxnet-ian38 xxnet-ian39 xxnet-ice01 xxnet-ice02 xxnet-ice03 xxnet-iceliquid xxnet-iceliquid1 xxnet-iceliquid10 xxnet-iceliquid11 xxnet-iceliquid12 xxnet-iceliquid13 xxnet-iceliquid14 xxnet-iceliquid15 xxnet-iceliquid16 xxnet-iceliquid17 xxnet-iceliquid18 xxnet-iceliquid19 xxnet-iceliquid2 xxnet-iceliquid20 xxnet-iceliquid21 xxnet-iceliquid22 xxnet-iceliquid23 xxnet-iceliquid24 xxnet-iceliquid25 xxnet-iceliquid26 xxnet-iceliquid27 xxnet-iceliquid28 xxnet-iceliquid29 xxnet-iceliquid3 xxnet-iceliquid30 xxnet-iceliquid31 xxnet-iceliquid32 xxnet-iceliquid33 xxnet-iceliquid34 xxnet-iceliquid35 xxnet-iceliquid4 xxnet-iceliquid5 xxnet-iceliquid6 xxnet-iceliquid7 xxnet-iceliquid8 xxnet-iceliquid9 xxnet-icloud1024 xxnet-idforxxnet-1 xxnet-idforxxnet-10 xxnet-idforxxnet-11 xxnet-idforxxnet-12 xxnet-idforxxnet-2 xxnet-idforxxnet-3 xxnet-idforxxnet-4 xxnet-idforxxnet-5 xxnet-idforxxnet-6 xxnet-idforxxnet-7 xxnet-idforxxnet-8 xxnet-idforxxnet-9 xxnet-irr1 xxnet-irr10 xxnet-irr11 xxnet-irr2 xxnet-irr3 xxnet-irr4 xxnet-irr5 xxnet-irr6 xxnet-irr7 xxnet-irr8 xxnet-irr9 xxnet-izual1 xxnet-izual2 xxnet-izual3 xxnet-izual4 xxnet-izual5 xxnet-j-191001 xxnet-j0001 xxnet-j0002 xxnet-jaga211 xxnet-jaga863 xxnet-jaga985 xxnet-jaine-donate xxnet-jamayy01 xxnet-jamayy02 xxnet-jamayy03 xxnet-jamayy04 xxnet-jamayy05 xxnet-jamayy06 xxnet-jamayy07 xxnet-jamayy08 xxnet-jamayy09 xxnet-jayxa xxnet-jayxc xxnet-jayxd xxnet-jayxe xxnet-jayxf xxnet-jayxg xxnet-jayxh xxnet-jayxj xxnet-jayxk xxnet-jer xxnet-jer2 xxnet-jiang-527329 xxnet-jianzhi1 xxnet-jianzhi2 xxnet-jianzhi3 xxnet-jianzhi4 xxnet-jianzhi5 xxnet-jiunin01 xxnet-jiunin02 xxnet-jiunin03 xxnet-jiunin04 xxnet-jiunin05 xxnet-jiunin06 xxnet-jiunin07 xxnet-jiunin08 xxnet-jiunin09 xxnet-jiunin10 xxnet-jiunin11 xxnet-jiunin12 xxnet-jj01 xxnet-jj02 xxnet-jj03 xxnet-jksoiyrhkh xxnet-joren xxnet-jsdfgf xxnet-juan-xian-1 xxnet-juan-xian-5 xxnet-juanxian-1 xxnet-juanxian-2 xxnet-juanxian-3 xxnet-juanxian-4 xxnet-juanxian-5 xxnet-juanzheng2 xxnet-jz xxnet-jz001 xxnet-jz002 xxnet-jz01 xxnet-k-191001 xxnet-k1 xxnet-k2 xxnet-keepfighting xxnet-ken001 xxnet-kevin1 xxnet-kevin10 xxnet-kevin11 xxnet-kevin12 xxnet-kevin2 xxnet-kevin3 xxnet-kevin4 xxnet-kevin5 xxnet-kevin6 xxnet-kevin7 xxnet-kevin8 xxnet-kevin9 xxnet-kevinyg1976 xxnet-kg1 xxnet-kg2 xxnet-kimdonate1 xxnet-kimdonate2 xxnet-kimdonate3 xxnet-kimdonate5 xxnet-kimdonate6 xxnet-kimdonate7 xxnet-kittycheny1 xxnet-kittycheny2 xxnet-kittycheny3 xxnet-kittycheny4 xxnet-kittycheny5 xxnet-kittycheny6 xxnet-kokoooro1 xxnet-kokoooro2 xxnet-ksryy1 xxnet-kudo xxnet-kugui xxnet-lead-184808 xxnet-lee01 xxnet-lennon xxnet-leo20171201 xxnet-leo20171202 xxnet-leobert-1 xxnet-lhzbxx-001 xxnet-lhzbxx-002 xxnet-lhzbxx-003 xxnet-li100 xxnet-li102-187505 xxnet-li103-187505 xxnet-li104 xxnet-li105 xxnet-li106 xxnet-liang xxnet-liangzheng xxnet-liaofanqiang107 xxnet-lidegang1 xxnet-lidegang10 xxnet-lidegang11 xxnet-lidegang12 xxnet-lidegang13 xxnet-lidegang14 xxnet-lidegang2 xxnet-lidegang3 xxnet-lidegang4 xxnet-lidegang5 xxnet-lidegang6 xxnet-lidegang7 xxnet-lidegang8 xxnet-lidegang9 xxnet-lifeator xxnet-lifeguard xxnet-lifehistory xxnet-lifeinstinct xxnet-lifejacket xxnet-lifenet xxnet-linch-1 xxnet-linch-2 xxnet-linch-3 xxnet-linch-5 xxnet-lingdu001 xxnet-lingdu002 xxnet-lingdu003 xxnet-lingdu004 xxnet-lingdu005 xxnet-lingdu006 xxnet-lingdu007 xxnet-lingdu008 xxnet-lingdu010 xxnet-lingdu012 xxnet-liu-176602 xxnet-liudanpao xxnet-liufi01 xxnet-liufi03 xxnet-liufi04 xxnet-liushuai-00 xxnet-liushuai-01 xxnet-liushuai-03 xxnet-liushuai-04 xxnet-liushuai-05 xxnet-liushuai-06 xxnet-liushuai-07 xxnet-liushuai-08 xxnet-liushuai-09 xxnet-ll824 xxnet-loc001 xxnet-loc002 xxnet-lolikong1 xxnet-lolikong10 xxnet-lolikong11 xxnet-lolikong12 xxnet-lolikong13 xxnet-lolikong2 xxnet-lolikong4 xxnet-lolikong5 xxnet-lolikong6 xxnet-lolikong7 xxnet-lolikong8 xxnet-lolikong9 xxnet-longer xxnet-longfengweb-2018 xxnet-lq-1910231 xxnet-lss644 xxnet-lx0612 xxnet-lxb1 xxnet-lxb2 xxnet-lxb3 xxnet-lxb4 xxnet-lxb5 xxnet-lxx01 xxnet-lxx02 xxnet-lxx03 xxnet-lxx04 xxnet-lxx05 xxnet-lxx06 xxnet-lxx07 xxnet-lxx08 xxnet-lxx09 xxnet-lxx10 xxnet-ly-185 xxnet-ly-185905 xxnet-ly-186 xxnet-ly-187 xxnet-ly-188 xxnet-ly001 xxnet-ly002 xxnet-ly003 xxnet-ly004 xxnet-ly005 xxnet-lyn0716 xxnet-lyrical-bolt-205705 xxnet-lzskyline-1 xxnet-m-191001 xxnet-m0003 xxnet-m0004 xxnet-m0005 xxnet-mailchenbo0 xxnet-mars-apple xxnet-math xxnet-maxuyang1 xxnet-maxuyang12 xxnet-maxuyang2 xxnet-maxuyang3 xxnet-maxuyang4 xxnet-maxuyang5 xxnet-maxuyang6 xxnet-maxuyang7 xxnet-maxuyang8 xxnet-maxuyang9 xxnet-mceesnail1 xxnet-mceesnail2 xxnet-mceesnail3 xxnet-mceesnail4 xxnet-mceesnail5 xxnet-mceesnail6 xxnet-meijie-pro1 xxnet-mg1838 xxnet-mhui1 xxnet-mhui10 xxnet-mhui11 xxnet-mhui12 xxnet-mhui2 xxnet-mhui3 xxnet-mhui4 xxnet-mhui5 xxnet-mhui6 xxnet-mhui7 xxnet-mhui8 xxnet-mhui9 xxnet-mig2999djproxy xxnet-min-01 xxnet-min-02 xxnet-mingj2018 xxnet-mingj201801 xxnet-mnbv-0987 xxnet-mo1 xxnet-mo2 xxnet-mokio-001 xxnet-mokio-002 xxnet-moon xxnet-mouka-1 xxnet-mouka-12 xxnet-mouka-2 xxnet-mouka-3 xxnet-moustache xxnet-mrhgewnv-1 xxnet-mrhgewnv-2 xxnet-mrhgewnv-3 xxnet-mrhgewnv-4 xxnet-mrsheng-1 xxnet-mrsheng-3 xxnet-msjylll xxnet-msjylls xxnet-mulisai001 xxnet-my-project-10205 xxnet-my-project-11101 xxnet-my-project-13778 xxnet-my-project-16875 xxnet-my-project-20548 xxnet-my-project-39629 xxnet-my-project-41238 xxnet-my-project-54333 xxnet-my-project-58828 xxnet-my-project-73849 xxnet-my-project-90468 xxnet-my1 xxnet-my10 xxnet-my11 xxnet-my12 xxnet-my2 xxnet-my3 xxnet-my4 xxnet-my5 xxnet-my6 xxnet-my7 xxnet-my8 xxnet-my9 xxnet-myapp xxnet-mylove1 xxnet-mylove2 xxnet-mysql xxnet-mzy xxnet-mzy5 xxnet-mzy56 xxnet-mzy6 xxnet-na xxnet-new-244504 xxnet-ninth xxnet-no1-242306 xxnet-nodejs xxnet-nome1 xxnet-np1 xxnet-one-228915 xxnet-one-233315 xxnet-open1-188802 xxnet-ourui668 xxnet-papastar xxnet-paynev-donate-1 xxnet-pbpomgjl xxnet-pc-184914 xxnet-pj01 xxnet-pltznpgu xxnet-pnjdonate1 xxnet-pnjdonate2 xxnet-pnjdonate3 xxnet-pohsin1 xxnet-pohsin2 xxnet-pojo xxnet-pp1 xxnet-pp2 xxnet-pp3 xxnet-ppb01 xxnet-practise xxnet-premise-184808 xxnet-prism-180909 xxnet-project-10 xxnet-project-11 xxnet-project-13206 xxnet-project-2 xxnet-project-20171120 xxnet-project-20171121 xxnet-project-20736 xxnet-project-209711 xxnet-project-21900 xxnet-project-25654 xxnet-project-2730 xxnet-project-3 xxnet-project-37050 xxnet-project-37571 xxnet-project-3987 xxnet-project-4 xxnet-project-433 xxnet-project-47855 xxnet-project-5 xxnet-project-51161 xxnet-project-6 xxnet-project-63452 xxnet-project-63772 xxnet-project-7 xxnet-project-8 xxnet-project-83242 xxnet-project-9 xxnet-project-90354 xxnet-project-yangkai18 xxnet-project02-233001 xxnet-proxynet1 xxnet-proxynet2 xxnet-public--1293 xxnet-public-205803 xxnet-public-205806 xxnet-public-boomkeeper-01 xxnet-public-project-78230 xxnet-public-project-78231 xxnet-publicooa xxnet-python xxnet-q002 xxnet-q003 xxnet-q004 xxnet-q005 xxnet-q006 xxnet-q007 xxnet-q008 xxnet-q009 xxnet-q010 xxnet-q011 xxnet-q012 xxnet-qerb xxnet-qing01 xxnet-qing01-187403 xxnet-qishi xxnet-qsxmq1 xxnet-quantye-test1 xxnet-quantye-test10 xxnet-quantye-test11 xxnet-quantye-test11-208414 xxnet-quantye-test2 xxnet-quantye-test3 xxnet-quantye-test4 xxnet-quantye-test5 xxnet-quantye-test6 xxnet-quantye-test7 xxnet-quantye-test8 xxnet-r1 xxnet-racer-184808 xxnet-random xxnet-rcleart xxnet-release xxnet-rem-0 xxnet-repeater-184808 xxnet-rilnwnqu5 xxnet-rilnwnqu6 xxnet-rilnwnqu7 xxnet-ringno001 xxnet-ringno002 xxnet-rnd01 xxnet-rnd02 xxnet-rnd03 xxnet-rnd04 xxnet-rnd05 xxnet-rnd06 xxnet-rnd07 xxnet-rnd08 xxnet-rnd09 xxnet-rnd10 xxnet-rnd11 xxnet-rnd12 xxnet-rosesarered xxnet-rs4donate0 xxnet-rylkyo xxnet-rylkyo-229615 xxnet-rylkyo1 xxnet-sakura xxnet-sale01 xxnet-sale02 xxnet-sale03 xxnet-sale04 xxnet-sale05 xxnet-sale06 xxnet-sale07 xxnet-sale08 xxnet-sale09 xxnet-sale10 xxnet-sale11 xxnet-sale12 xxnet-samr xxnet-sandbox-235202 xxnet-sayno xxnet-scats01 xxnet-scats02 xxnet-scats03 xxnet-scats04 xxnet-scats05 xxnet-scats06 xxnet-scats07 xxnet-scats08 xxnet-scats09 xxnet-scats10 xxnet-scats11 xxnet-scats12 xxnet-scats13 xxnet-scats14 xxnet-scrisqiu-5 xxnet-scrisqiu-6 xxnet-sdcf1 xxnet-sdcf10 xxnet-sdcf3 xxnet-sdcf4 xxnet-sdcf5 xxnet-sdcf6 xxnet-sdcf7 xxnet-sdcf8 xxnet-sdcf8-1241 xxnet-sdcf9 xxnet-sdcff1 xxnet-sdcff10 xxnet-sdcff11 xxnet-sdcff12 xxnet-sdcff2 xxnet-sdcff3 xxnet-sdcff4 xxnet-sdcff5 xxnet-sdcff6 xxnet-sdcff7 xxnet-sdcff8 xxnet-sdcff9 xxnet-service-lhw xxnet-service01 xxnet-service02 xxnet-service03 xxnet-service04 xxnet-service05 xxnet-sfgsuurxpd3 xxnet-sgg xxnet-sh-1 xxnet-sh-2 xxnet-shadow-111 xxnet-shadow-222 xxnet-shadow-333 xxnet-shadow-444 xxnet-shadow-555 xxnet-shadow-666 xxnet-shadow-777 xxnet-shang xxnet-shangda030900 xxnet-share-1 xxnet-share-193512 xxnet-share-2 xxnet-share-257205 xxnet-share-donate-01 xxnet-share-donate-02 xxnet-share-donate-03 xxnet-share-donate-04 xxnet-share-donate-05 xxnet-share-donate-07 xxnet-share-donate-08 xxnet-share-donate-09 xxnet-share-donate-10 xxnet-share-donate-11 xxnet-ship xxnet-silenq-1 xxnet-silenq-2 xxnet-singlev-001 xxnet-singlev-002 xxnet-singlev-004 xxnet-singlev-006 xxnet-singlev-007 xxnet-sinkzephyr2017 xxnet-skyhifi1 xxnet-skyhifi10 xxnet-skyhifi2-1266 xxnet-skyhifi4 xxnet-skyhifi5 xxnet-skyhifi6 xxnet-skyhifi7 xxnet-skyhifi8 xxnet-skyhifi9 xxnet-smm xxnet-sofia01 xxnet-sofia02 xxnet-sofia03 xxnet-sofia04 xxnet-sofia06 xxnet-sol-1 xxnet-sol-2 xxnet-sol-3 xxnet-sol-4 xxnet-sol-5 xxnet-sol-6 xxnet-sol-7 xxnet-sol-8 xxnet-solid-linker-162409 xxnet-sorter xxnet-sp001 xxnet-spark xxnet-sparkle xxnet-spox-1 xxnet-sqs xxnet-sss xxnet-sss1 xxnet-sss10 xxnet-sss11 xxnet-sss2 xxnet-sss3 xxnet-sss4 xxnet-sss5 xxnet-sss6 xxnet-sss7 xxnet-sss8 xxnet-sss9 xxnet-stan1 xxnet-stan10 xxnet-stan11 xxnet-stan12 xxnet-stan13 xxnet-stan14 xxnet-stan15 xxnet-stan16 xxnet-stan17 xxnet-stan2 xxnet-stan4 xxnet-stan5 xxnet-stan6 xxnet-stan7 xxnet-stan8 xxnet-stan9 xxnet-starwang01 xxnet-sugarissweet xxnet-sun xxnet-sunny01 xxnet-sunqiang00 xxnet-sunqiang01 xxnet-sunqiang02 xxnet-sunqiang03 xxnet-sunqiang04 xxnet-sunqiang05 xxnet-sunqiang06 xxnet-sunqiang07 xxnet-sunqiang09 xxnet-swear xxnet-swear291 xxnet-sxs01 xxnet-sxs02 xxnet-sycamore xxnet-sycamore1 xxnet-t-184503 xxnet-t1-235404 xxnet-t2-235404 xxnet-takeaidebaba1 xxnet-takeaidebaba2 xxnet-takeaidebaba3 xxnet-takonyan1 xxnet-takonyan2 xxnet-takonyan3 xxnet-takonyan3-184808 xxnet-takonyan5 xxnet-talon-184808 xxnet-te xxnet-tech01 xxnet-tech02 xxnet-tech03 xxnet-tech04 xxnet-tech05 xxnet-tech06 xxnet-tech07 xxnet-tech08 xxnet-tech10 xxnet-tech11 xxnet-tech12 xxnet-test-240204 xxnet-test-for-xx xxnet-thanks xxnet-thanks-244611 xxnet-thertno-20180117 xxnet-thertno-20180118 xxnet-thertno-20180119 xxnet-thertno-20180120 xxnet-think-t3 xxnet-tiandidatong xxnet-tiny001 xxnet-tiny002 xxnet-tj xxnet-tlzx0 xxnet-tlzx1 xxnet-tlzx2 xxnet-tlzx3 xxnet-tlzx4 xxnet-tlzx5 xxnet-tlzx6 xxnet-tlzx7 xxnet-tlzx8 xxnet-tlzx9 xxnet-tms1 xxnet-tn01 xxnet-tn02 xxnet-tn03 xxnet-tn04 xxnet-tn05 xxnet-to-gae-10000 xxnet-to-gae-10001 xxnet-to-gae-10002 xxnet-to-gae-10003 xxnet-to-gae-10004 xxnet-to-gae-10005 xxnet-to-gae-10006 xxnet-to-gae-10007 xxnet-to-gae-10008 xxnet-to-gae-10009 xxnet-tom xxnet-totunnel xxnet-trip1 xxnet-trip2 xxnet-trsum-001 xxnet-trsum-003 xxnet-trsum-004 xxnet-trsum-006 xxnet-trsum-007 xxnet-trsum-008 xxnet-trsum-009 xxnet-trsum-010 xxnet-tunnel xxnet-tunnel-2 xxnet-tunnel-251202 xxnet-tunnel-3 xxnet-twogen xxnet-twogen2 xxnet-twogen3 xxnet-tycomputer xxnet-tyreal xxnet-u639 xxnet-ut001 xxnet-uwgwo xxnet-v001 xxnet-v002 xxnet-v003 xxnet-v004 xxnet-v005 xxnet-v006 xxnet-vaip xxnet-vanore-1 xxnet-vanore-2 xxnet-vanore-3 xxnet-vanore-4 xxnet-vanore-5 xxnet-violetsareblue xxnet-vision01 xxnet-vpn-1996 xxnet-vpn-211902 xxnet-vpn002 xxnet-vpn003 xxnet-vssohu1 xxnet-vssohu2 xxnet-vssohu3 xxnet-w-188508 xxnet-w2 xxnet-wallbreaker xxnet-wallbreaker1 xxnet-wallbreaker10 xxnet-wallbreaker2 xxnet-wallbreaker3 xxnet-wallbreaker4 xxnet-wallbreaker5 xxnet-wallbreaker6 xxnet-wallbreaker7 xxnet-wallbreaker8 xxnet-wallbreaker9 xxnet-walterclozet1 xxnet-walterclozet2 xxnet-wantsrain xxnet-wantsrain1 xxnet-wantsrain10 xxnet-wantsrain11 xxnet-wantsrain12 xxnet-wantsrain2 xxnet-wantsrain3 xxnet-wantsrain4 xxnet-wantsrain6 xxnet-wantsrain7 xxnet-wantsrain8 xxnet-wantsrain9 xxnet-water001 xxnet-water002 xxnet-water004 xxnet-water005 xxnet-water007 xxnet-water008 xxnet-wb1 xxnet-wei xxnet-wgqid3 xxnet-wich01 xxnet-wich02 xxnet-wich03 xxnet-wich04 xxnet-wich05 xxnet-wich06 xxnet-wich06-1263 xxnet-wich1 xxnet-wiki4j xxnet-wilsonwu1 xxnet-wilsonwu2 xxnet-wind01 xxnet-wind02 xxnet-wind03 xxnet-wind04 xxnet-wind05 xxnet-wind06 xxnet-wind07 xxnet-wind08 xxnet-wind09 xxnet-wind10 xxnet-wind11 xxnet-wind12 xxnet-wingxu-001 xxnet-wingxu-002 xxnet-wingxu-003 xxnet-wish xxnet-wizard1 xxnet-wizard2 xxnet-wizard3 xxnet-wizard4 xxnet-wkq xxnet-wkq1-212805 xxnet-wmyhnl xxnet-work-219405 xxnet-wuqq-1 xxnet-wuqq-2 xxnet-wwwhl1111 xxnet-wwwhl2 xxnet-wwwhl3 xxnet-wwwhl4 xxnet-wy11 xxnet-wy12 xxnet-wzbbj-01 xxnet-wzz1270 xxnet-wzz1271 xxnet-wzz12710 xxnet-wzz12711 xxnet-wzz1272 xxnet-wzz1273 xxnet-wzz1274 xxnet-wzz1275 xxnet-wzz1276 xxnet-wzz1277 xxnet-wzz1278 xxnet-wzz1279 xxnet-x-200204 xxnet-x-tunnel-donate-1 xxnet-x-tunnel-donate-2 xxnet-x-tunnel-donate-3 xxnet-x-tunnel-donate-4 xxnet-x-tunnel-donate-5 xxnet-x-tunnel-donate-6 xxnet-xhox xxnet-xiaomao xxnet-xiaoxiong6 xxnet-xiaoxiong7 xxnet-xiaoxiong8 xxnet-xiaoxiong9 xxnet-xingxing01 xxnet-xingxing02 xxnet-xique112301 xxnet-xique112302 xxnet-xique112303 xxnet-xique112304 xxnet-xique112305 xxnet-xique112306 xxnet-xique112307 xxnet-xique112308 xxnet-xique112309 xxnet-xique112310 xxnet-xlx01 xxnet-xlx02 xxnet-xlx03 xxnet-xlx04 xxnet-xlx05 xxnet-xlx06 xxnet-xlx07 xxnet-xlx08 xxnet-xlx09 xxnet-xlx10 xxnet-xlx11 xxnet-xlx12 xxnet-xpz10 xxnet-xpz11 xxnet-xpz8-185109 xxnet-xpz9 xxnet-xt-226202 xxnet-xt1 xxnet-xt10 xxnet-xt2 xxnet-xt3 xxnet-xt4 xxnet-xt6 xxnet-xt7 xxnet-xt8 xxnet-xt9 xxnet-xtkong xxnet-xtkong1 xxnet-xtkong2 xxnet-xtkong3 xxnet-xtkong4 xxnet-xtkong5 xxnet-xtkong6 xxnet-xtkong7 xxnet-xtunnel xxnet-xu xxnet-xue1 xxnet-xuehao xxnet-xujj-110301 xxnet-xujj-110302 xxnet-xx06 xxnet-xx18 xxnet-xx19 xxnet-xx2 xxnet-xx20 xxnet-xx21 xxnet-xx22 xxnet-xx23 xxnet-xx24 xxnet-xx25 xxnet-xxnet-1 xxnet-xxnetdonate1 xxnet-xxnetdonate2 xxnet-xxnetdonate3 xxnet-xxnetdonate4 xxnet-xxnetdonate5 xxnet-xxnetdonate6 xxnet-xxnetdonate7 xxnet-xxnetdonate8 xxnet-xy xxnet-xy-1 xxnet-xy-2 xxnet-xy-3 xxnet-xy-4 xxnet-xy-5 xxnet-xzl000 xxnet-xzl001 xxnet-xzl002 xxnet-xzl004 xxnet-xzl004-234103 xxnet-xzl006 xxnet-xzl007 xxnet-yagnitdn xxnet-yang-6-11 xxnet-yang01 xxnet-yang02 xxnet-yang03 xxnet-yang03-235704 xxnet-yanggkka xxnet-yaolong1 xxnet-yaolong2 xxnet-yaolong3 xxnet-ygl xxnet-ykq1 xxnet-ym000 xxnet-ym001 xxnet-ym002 xxnet-yol xxnet-ysk1 xxnet-ysk2 xxnet-yt001 xxnet-yt002 xxnet-yuanchouyc001 xxnet-yuanchouyc002 xxnet-yujie020 xxnet-yujie0201 xxnet-yyl1990 xxnet-yyt02-01 xxnet-yyt02-02 xxnet-yyt02-03 xxnet-yyt02-04 xxnet-yyt02-05 xxnet-yyt02-06 xxnet-yyt02-07 xxnet-yyt02-08 xxnet-yyt02-09 xxnet-yyt02-10 xxnet-yyt02-11 xxnet-yyt02-12 xxnet-zar01 xxnet-zelinlee1 xxnet-zhang1111 xxnet-zhang2222 xxnet-zhang3333 xxnet-zhang4444 xxnet-zhang5555 xxnet-zhangyang7761-1 xxnet-zhanzhan-1 xxnet-zhanzhan-2 xxnet-zhanzhan-3 xxnet-zhanzhan-4 xxnet-zhanzhan-5 xxnet-zhanzhan-6 xxnet-zhaozihao xxnet-zhengqi6 xxnet-zhengqi7 xxnet-zhengqi8 xxnet-zhengqi9 xxnet-zhj1 xxnet-zhj2 xxnet-zhou1 xxnet-zhou2 xxnet-zhoufxw1 xxnet-zhoufxw2 xxnet-zhoufxw3 xxnet-zhoufxw4 xxnet-zhoufxw5 xxnet-zj01 xxnet-zj02 xxnet-zj03 xxnet-zj04 xxnet-zj05 xxnet-zj06 xxnet-zjn-1 xxnet-zld1 xxnet-zld2 xxnet-zlg02 xxnet-zlg03 xxnet-zlg04 xxnet-zt48 xxnet-zx44711 xxnet-zxz xxnet-zz-001 xxnet-zz-002 xxnet-zz-02 xxnet-zz001 xxnet-zzcqkk xxnet0-198703 xxnet0-257701 xxnet001-185802 xxnet001-229801 xxnet002-211112 xxnet003-185588 xxnet004-185588 xxnet005 xxnet005-665555 xxnet0051 xxnet006-226605 xxnet006-444250 xxnet007-665588 xxnet01-188610 xxnet01-197014 xxnet01-213201 xxnet010220 xxnet010221 xxnet010222 xxnet010223 xxnet010224 xxnet010225 xxnet010226 xxnet010227 xxnet010228 xxnet02-197014 xxnet02-199207 xxnet02-207003 xxnet0727 xxnet1-111111111 xxnet1-1345 xxnet1-151005 xxnet1-152111 xxnet1-16974 xxnet1-171111 xxnet1-173906 xxnet1-179710 xxnet1-182212 xxnet1-182815 xxnet1-184408 xxnet1-184506 xxnet1-184602 xxnet1-190512 xxnet1-192017 xxnet1-192215 xxnet1-194702 xxnet1-195604 xxnet1-198703 xxnet1-198900 xxnet1-213107 xxnet1-214011 xxnet1-225311 xxnet1-227710 xxnet1-240509 xxnet1-246818 xxnet10-1208 xxnet10-1345 xxnet10-152204 xxnet10-171112 xxnet10-191411 xxnet10-195605 xxnet10-197815 xxnet10-198703 xxnet10-208507 xxnet10-257701 xxnet1018-234904 xxnet11-1208 xxnet11-152204 xxnet11-191411 xxnet11-197815 xxnet11-208507 xxnet12-141909 xxnet12-152204 xxnet12-197815 xxnet1201 xxnet12111 xxnet12112 xxnet12113 xxnet12114 xxnet12115 xxnet123456-233214 xxnet1258 xxnet135-227515 xxnet1489-186613 xxnet16388 xxnet18010602 xxnet18010603 xxnet18010604 xxnet18010605 xxnet186700 xxnet186701 xxnet186702 xxnet186703 xxnet186704 xxnet186705 xxnet186706 xxnet186707 xxnet186708 xxnet186709 xxnet186710 xxnet190115 xxnet193 xxnet1949 xxnet19601 xxnet19602 xxnet1id xxnet2-1345 xxnet2-151716 xxnet2-152204 xxnet2-170603 xxnet2-171111 xxnet2-179711 xxnet2-182212 xxnet2-184506 xxnet2-184604 xxnet2-187112 xxnet2-187405 xxnet2-190512 xxnet2-192017 xxnet2-192215 xxnet2-194702 xxnet2-195604 xxnet2-198703 xxnet2-2010 xxnet2-202119 xxnet2-203803 xxnet2-208507 xxnet2-213205 xxnet2-214012 xxnet2-225311 xxnet2-225906 xxnet2-227710 xxnet2-228621 xxnet2-240509 xxnet2-246818 xxnet2-262713 xxnet201-156516 xxnet201701-186213 xxnet201702-186213 xxnet2017021406 xxnet201703-186213 xxnet201704-186213 xxnet20170419 xxnet20170420 xxnet20170421 xxnet201705-186213 xxnet201706-186213 xxnet20190227-233009 xxnet20190731 xxnet2019073101 xxnet2019073102 xxnet20191 xxnet20192 xxnet20193 xxnet20194 xxnet233-171123 xxnet23456 xxnet239201 xxnet251306 xxnet2945 xxnet3-1208 xxnet3-1345 xxnet3-171112 xxnet3-179711 xxnet3-182212 xxnet3-184506 xxnet3-185505 xxnet3-187212 xxnet3-190513 xxnet3-192017 xxnet3-192215 xxnet3-194702 xxnet3-195604 xxnet3-197815 xxnet3-198703 xxnet3-2011 xxnet3-203803 xxnet3-208507 xxnet3-214105 xxnet3-225311 xxnet3-225607 xxnet3-227710 xxnet3-228621 xxnet3-240509 xxnet3-246818 xxnet4-1208 xxnet4-1321 xxnet4-1345 xxnet4-152204 xxnet4-168608 xxnet4-184506 xxnet4-190611 xxnet4-192017 xxnet4-192215 xxnet4-195604 xxnet4-197815 xxnet4-198703 xxnet4-208507 xxnet4-225607 xxnet4-227710 xxnet4-240513 xxnet4-262713 xxnet43383fq xxnet445 xxnet456-233214 xxnet45686 xxnet45687 xxnet45688 xxnet45689 xxnet48749 xxnet4ae02 xxnet4ae03 xxnet4good xxnet5-1208 xxnet5-1321 xxnet5-1345 xxnet5-152204 xxnet5-168608 xxnet5-195605 xxnet5-197815 xxnet5-198703 xxnet5-208507 xxnet5-227710 xxnet5-246818 xxnet5-262713 xxnet54857 xxnet6-1208 xxnet6-1345 xxnet6-152204 xxnet6-191411 xxnet6-195605 xxnet6-197815 xxnet6-198703 xxnet6-227710 xxnet7-1208 xxnet7-1345 xxnet7-152204 xxnet7-191411 xxnet7-195605 xxnet7-197815 xxnet7-208507 xxnet7-210802 xxnet74589 xxnet7779-01 xxnet7779-02 xxnet7779-03 xxnet7779-04 xxnet7779-05 xxnet7779-06 xxnet7779-07 xxnet7779-08 xxnet7779-09 xxnet7779-10 xxnet7779-11 xxnet7779-12 xxnet789-233214 xxnet8-1208 xxnet8-1345 xxnet8-152204 xxnet8-178304 xxnet8-191411 xxnet8-195605 xxnet8-197815 xxnet8-198703 xxnet8-208507 xxnet8-257701 xxnet89959 xxnet9-1208 xxnet9-1345 xxnet9-191411 xxnet9-195605 xxnet9-197815 xxnet9-198703 xxnet9-208507 xxnet9255-216802 xxnet9901 xxnet9970 xxnet99901 xxnet99904 xxnet99906 xxnet99907 xxnet99908 xxnet99909 xxnet99910 xxneta xxnetappid-161812 xxnetappid-191416 xxnetappid02 xxnetc1wiki xxnetclair01 xxnetclair02 xxnetclair03 xxnetclair04 xxnetclair05 xxnetclair06 xxnetclair07 xxnetclair08 xxnetclair09 xxnetclair10 xxnetclair11 xxnetclair12 xxnetcogent-repeater-227609 xxnetcrossgfw02 xxnetcrossgfw04 xxnetcrossgfw06 xxnetdisco-math-187208 xxnetdsb xxnetforlaptop xxnetfynmfl5 xxnetid-194208 xxnetid101 xxnetid103 xxnetid104 xxnetid105 xxnetid106 xxnetid107 xxnetid108 xxnetid109 xxnetid110 xxnetid111 xxnetid112 xxnetid113 xxnetid114 xxnetid115 xxnetid116 xxnetid118 xxnetid119 xxnetid120 xxnetid121 xxnetid122 xxnetid123 xxnetid124 xxnetid125 xxnetid126 xxnetid127 xxnetid128 xxnetid129 xxnetid130 xxnetid131 xxnetid132 xxnetid133 xxnetid136 xxnetid137 xxnetid138 xxnetid139 xxnetid21 xxnetidfjy xxnetiimax1 xxnetiimax10 xxnetiimax2 xxnetiimax3 xxnetiimax4 xxnetiimax5 xxnetiimax6 xxnetiimax7 xxnetiimax8 xxnetiimax9 xxnetjuan xxnetjuan2 xxnetlhuang01 xxnetlhuang02 xxnetlhuang03 xxnetlhuang04 xxnetlhuang05 xxnetlhuang06 xxnetlhuang07 xxnetlhuang08 xxnetlhuang09 xxnetlhuang10 xxnetlhuang11 xxnetlhuang12 xxnetli1 xxnetli2 xxnetlinufo xxnetox11 xxnetox12 xxnetp1 xxnetp2 xxnetp4 xxnetp5 xxnetp7 xxnetp8 xxnetp9 xxnetproject-31640 xxnetproject-40187 xxnetshout xxnetsz001 xxnetsz002 xxnetsz003 xxnettest-160605 xxnettest10 xxnettest11 xxnettest12 xxnettest2-160605 xxnettest3-160605 xxnettest4-182813 xxnettest5-182813 xxnettest6-182813 xxnettest7-182813 xxnettest8-182813 xxnettest9-182813 xxnetwang-255506 xxnetwiki-198508 xxnetxe xxnetxx-145814 xxnetydy8-188302 xxnetynmfl1 xxnetynmfl2 xxnetynmfl3 xxnetynmfl4 xxnetyoucai xxnetzhaozhao xxoo650-1274 xxs123456 xxt-donate xxtet-chinese xxtunnel-180904 xxtunnel-180906 xxx-1-111 xxx-net-1209 xxx-net-225913 xxxfhy-102030 xxxnet-1 xxxnet-10 xxxnet-11 xxxnet-12 xxxnet-2-1244 xxxnet-4 xxxnet-5 xxxnet-6 xxxnet-7 xxxnet-8 xxxnet-9 xynet-beichi-send1 yagam9951 yagam9952 yagam9953 yagam9954 yagam9955 yagam9956 yangkevin yangshouyi31 yangyangnetwork yangyuenanxx-net yangyuenanxx-net1 yankop-1661 yankop-1662 yankop-1663 yankop-1664 yankop-1665 yankop-1666 yankop-1667 yankop-1668 yankop-1669 yaowang59722669 ybr1-143110 ybr2-143110 ybr3-143110 ybr4-143110 ybr5-143110 ybr6-143110 ybr7-143110 ybr8-143110 ybr9-143110 ycg18-8-15 yellowcoolcool1 yellowcoolcool10 yellowcoolcool2 yellowcoolcool3 yellowcoolcool4 yellowcoolcool5 yellowcoolcool6 yellowcoolcool7 yellowcoolcool8 yellowcoolcool9 yesxcj yfkm010 yfkm011 yfkm012 yfkm013 yfkm014 yfkm015 yfkm016 yfkm017 yfkm018 yfkm019 yfkm020 yhwc9-235117 yicheng750 yicheng751 yilian123110 yilian123111 ying-9000 yingerson012 yiyi-227007 yj3259669110 yj3259669111 yj3259669112 yj3259669113 yj3259669114 yjy-project yjy-project2 yjy-project4 yjy-project5 ykyworld8 ynning yntdfsrw yntdfsrw10 yntdfsrw2 yntdfsrw3 yntdfsrw4 yntdfsrw5 yntdfsrw6 yntdfsrw7 yntdfsrw8 yntdfsrw9 yochi03104450 yongda-1 yongda-10 yongda-11 yongda-2 yongda-3 yongda-4 yongda-5 yongda-6 yongda-7 yongda-8 yongda-9 youngcookie-147607 yourewb youtube-watcher-186408 yrtsai001 yuan-jang11 yuchen941110 yuemeng440711 yueyilin-163309 yugmail yuku871-1274 yulian0828 yun-id10 yun-id7 yun-id8 yun-id9 yxd0010 yyp111-211404 yytcug yytv587 yytwxt yyx-gtr-1111 yyx-gtr-1112 yyx-gtr-1113 yyx-gtr-1114 yyx-gtr-1115 yyx-gtr-1116 yyx-gtr-1117 yyx-gtr-1118 yyx-gtr-1119 yyx-gtr-1120 z403529262-21 z403529262-22 z403529262-23 z403529262-24 zapoo0709 zebchou-160302 zeta-crossbar-215712 zexitouzi zeziyu31 zeziyu32 zeziyu33 zeziyu34 zeziyu35 zeziyu36 zeziyu37 zeziyu38 zeziyu39 zeziyu40 zeziyu9 zhang-163706 zhanghua-207701 zhanghua1-207705 zhangtina000 zhangtina0000 zhangwantong1 zhangwantong2 zhangwantong3 zhaochengya2654 zhaorain-1186 zhaorain1 zhaorain10 zhaorain11 zheng234-1331 zheng345-1331 zhenhong0001 zhenhong0002 zhenhong0003 zhenhongbeiyong zhijiangdaqu3 zhijiangdaqu4 zhiying-163309 zhongjiamingshitiancai2-168105 zhongshangwu22 zhongshangwu23 zhongshangwu25 zhongshangwu26 zhongshangwu27 zhongshangwu28 zhongshangwu29 zhongshangwu30 zhoubiao-160302 zhoumeng10080 zhoumeng10081 zhoumeng10082 zhoumeng10083 zhoumeng10084 zhoumeng10085 zhoumeng10086 zhoumeng10087 zhoumeng10088 zhoumeng10089 zhoumeng1081 zhousuiyuan4 zhousuiyuan5 zhouwucheng1 zhouwucheng11 zhouxingyucn1 zhouxingyucn10 zhouxingyucn11 zhouxingyucn12 zhouxingyucn13 zhouxingyucn14 zhouxingyucn15 zhouxingyucn16 zhouxingyucn17 zhouxingyucn18 zhouxingyucn19 zhouxingyucn2 zhouxingyucn20 zhouxingyucn21 zhouxingyucn22 zhouxingyucn23 zhouxingyucn24 zhouxingyucn25 zhouxingyucn3 zhouxingyucn4 zhouxingyucn5 zhouxingyucn6 zhouxingyucn7 zhouxingyucn8 zhouxingyucn9 zhuccct zhuccct01 zhuccct02 zhuccct03 zhuccct04 zhuccct05 zhuccct06 zhuccct07 zhuccct08 zhuccct09 zhuccct10 zhujixihu zhyqlp-01 zhyqlp-02 zhyqlp-03 zhyqlp-04 zhyqlp-05 zhyqlp-06 zhyqlp-07 zhyqlp-08 zhzhi4186 zhzhi4187 zhzhi4188 zhzhi4189 zhzytb1 zhzytb2 zhzytb3 zhzytb4 zinc-silicon-206709 zinc-style-240007 zipple0000 zipple00000 zipple000000 zipple0000000 zipple000000000 zipple0000000000 zipple00000000000 zipple000000000000 zipple0000000000000 zipple00000000000000 zippy-world-192108 zoumeng10080 zuooo-12 zuotq121 zuotq122 zuotq123 zuotq124 zuotq125 zuotq126 zuotq127 zuotq128 zuotq129 zuotq130 zwx1232zwx zwx1233zwx zwx1234zwx zx-antigfw1 zx-antigfw2 zx-antigfw3 zx-antigfw4 zx-antigfw5 zx-antigfw6 zyyipai6 zyyipai7 zyyzpubready zzahun zzfa27 zzfa28 zzfa29 zzfa30 zzfa31 zzfa32 zzfa34 zzfa35 zzfahun ================================================ FILE: code/default/gae_proxy/local/cacert.pem ================================================ ## Google Context Issuer Trust Root CA # Operating CA: GlobalSign # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 # Label: "GlobalSign Root CA - R2" # Serial: 02:03:e4:f4:61:ec:99:d9:d5:79:66:ca:7a # MD5 Fingerprint: f1:5f:67:ab:01:e8:b1:0e:32:ff:37:07:26:06:ff:c4 # SHA1 Fingerprint: 02:9d:4b:7e:33:d2:83:8c:66:8c:1d:2c:56:9e:f9:2a:54:0a:7b:96 # SHA256 Fingerprint: 69:e2:d0:6c:30:f3:66:16:61:65:e9:1d:68:d1:ce:e5:cc:47:58:4a:80:22:7e:76:66:60:86:c0:10:72:41:eb -----BEGIN CERTIFICATE----- MIIDvDCCAqSgAwIBAgINAgPk9GHsmdnVeWbKejANBgkqhkiG9w0BAQUFADBMMSAw HgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFs U2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0wNjEyMTUwODAwMDBaFw0yMTEy MTUwODAwMDBaMEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMw EQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAps8kDr4ubyiZRULEqz4hVJsL03+EcPoS s8u/h1/Gf4bTsjBc1v2t8Xvc5fhglgmSEPXQU977e35ziKxSiHtKpspJpl6op4xa Ebx6guu+jOmzrJYlB5dKmSoHL7Qed7+KD7UCfBuWuMW5Oiy81hK561l94tAGhl9e SWq1OV6INOy8eAwImIRsqM1LtKB9DHlN8LgtyyHK1WxbfeGgKYSh+dOUScskYpEg vN0L1dnM+eonCitzkcadG6zIy+jgoPQvkItN+7A2G/YZeoXgbfJhE4hcn+CTClGX ilrOr6vV96oJqmC93Nlf33KpYBNeAAHJSvo/pOoHAyECjoLKA8KbjwIDAQABo4Gc MIGZMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSb 4gdXZxwewGoG3lm0mi3f3BmGLjAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f 3BmGLjA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3JsLmdsb2JhbHNpZ24ubmV0 L3Jvb3QtcjIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQANeX81Z1YqDIs4EaLjG0qP OxIzaJI/y4kiRj3a+y3KOx74clIkLuMgi/9/5iv/n+1LyhGU9g7174slbzJOPbSp p1eT19ST2mYbdgTLx/hm3tTLoHIY/w4ZbnQYwfnPwAG4RefnEFYPQJmpD+Wh8BJw Bgtm2drTale/T6NBwmwnEFunfaMfMX3g6IBrx7VKnxIkJh/3p190WveLKgl9n7i5 SWce/4woPimEn9WfEQWRvp6wKhaCKFjuCMuulEZusoOUJ4LfJnXxcuQTgIrSnwI7 KfSSjsd42w3lX1fbgJp7vPmLM6OBRvAXuYRKTFqMAWbb7OaGIEE+cbxY6PDepnva -----END CERTIFICATE----- # Operating CA: GlobalSign # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 # Label: "GlobalSign ECC Root CA - R4" # Serial: 02:03:e5:7e:f5:3f:93:fd:a5:09:21:b2:a6 # MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc # SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28 # SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2 -----BEGIN CERTIFICATE----- MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/ +wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147 bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm -----END CERTIFICATE----- # Operating CA: Google Trust Services LLC # Issuer: CN=GTS Root R1 O=Google Trust Services LLC # Subject: CN=GTS Root R1 O=Google Trust Services LLC # Label: "GTS Root R1" # Serial: 02:03:e5:93:6f:31:b0:13:49:88:6b:a2:17 # MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40 # SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a # SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf -----BEGIN CERTIFICATE----- MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo 27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT 6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ 0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm 2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- # Operating CA: Google Trust Services LLC # Issuer: CN=GTS Root R2 O=Google Trust Services LLC # Subject: CN=GTS Root R2 O=Google Trust Services LLC # Label: "GTS Root R2" # Serial: 02:03:e5:ae:c5:8d:04:25:1a:ab:11:25:aa # MD5 Fingerprint: 1e:39:c0:53:e6:1e:29:82:0b:ca:52:55:36:5d:57:dc # SHA1 Fingerprint: 9a:44:49:76:32:db:de:fa:d0:bc:fb:5a:7b:17:bd:9e:56:09:24:94 # SHA256 Fingerprint: 8d:25:cd:97:22:9d:bf:70:35:6b:da:4e:b3:cc:73:40:31:e2:4c:f0:0f:af:cf:d3:2d:c7:6e:b5:84:1c:7e:a8 -----BEGIN CERTIFICATE----- MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY 6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV +3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8 0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6 xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV 7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl 6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL -----END CERTIFICATE----- # Operating CA: Google Trust Services LLC # Issuer: CN=GTS Root R3 O=Google Trust Services LLC # Subject: CN=GTS Root R3 O=Google Trust Services LLC # Label: "GTS Root R3" # Serial: 02:03:e5:b8:82:eb:20:f8:25:27:6d:3d:66 # MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73 # SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46 # SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48 -----BEGIN CERTIFICATE----- MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2 4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7 VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X -----END CERTIFICATE----- # Operating CA: Google Trust Services LLC # Issuer: CN=GTS Root R4 O=Google Trust Services LLC # Subject: CN=GTS Root R4 O=Google Trust Services LLC # Label: "GTS Root R4" # Serial: 02:03:e5:c0:68:ef:63:1a:9c:72:90:50:52 # MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8 # SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47 # SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d -----BEGIN CERTIFICATE----- MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D 9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8 p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD -----END CERTIFICATE----- # Operating CA: DigiCert Inc # Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com # Label: "www.digicert.com" # Serial: 0c:e7:e0:e5:17:d8:46:fe:8f:e5:60:fc:1b:f0:30:39 # MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 # SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 # SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c -----BEGIN CERTIFICATE----- MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== -----END CERTIFICATE----- # Operating CA: Equifax # Issuer: O=Equifax OU=Equifax Secure Certificate Authority # Subject: O=Equifax OU=Equifax Secure Certificate Authority # Label: "Equifax Secure Certificate Authority" # Serial: 35:de:f4:cf # MD5 Fingerprint: 67:cb:9d:c0:13:24:8a:82:9b:b2:17:1e:d1:1b:ec:d4 # SHA1 Fingerprint: d2:32:09:ad:23:d3:14:23:21:74:e4:0d:7f:9d:62:13:97:86:63:3a # SHA256 Fingerprint: 08:29:7a:40:47:db:a2:36:80:c7:31:db:6e:31:76:53:ca:78:48:e1:be:bd:3a:0b:01:79:a7:07:f9:2c:f1:78 -----BEGIN CERTIFICATE----- MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y 7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh 1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 -----END CERTIFICATE----- # Old CAs # Operating CA: GlobalSign # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 # Label: "GlobalSign Root CA - R2" DEPRECATED # Serial: 04:00:00:00:00:01:0f:86:26:e6:0d # MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 # SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe # SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e -----BEGIN CERTIFICATE----- MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG 3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO 291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== -----END CERTIFICATE----- # Operating CA: GlobalSign # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 # Label: "GlobalSign ECC Root CA - R4" # Serial: 2a:38:a4:1c:96:0a:04:de:42:b2:28:a5:0b:e8:34:98:02 # MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e # SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb # SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c -----BEGIN CERTIFICATE----- MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs ewv4n4Q= -----END CERTIFICATE----- # Operating CA: Google Trust Services LLC # Issuer: CN=GTS Root R1 O=Google Trust Services LLC # Subject: CN=GTS Root R1 O=Google Trust Services LLC # Label: "GTS Root R1" # Serial: 6e:47:a9:c5:4b:47:0c:0d:ec:33:d0:89:b9:1c:f4:e1 # MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85 # SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8 # SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72 -----BEGIN CERTIFICATE----- MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM +SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl -----END CERTIFICATE----- # Operating CA: Google Trust Services LLC # Issuer: CN=GTS Root R2 O=Google Trust Services LLC # Subject: CN=GTS Root R2 O=Google Trust Services LLC # Label: "GTS Root R2" # Serial: 6e:47:a9:c6:5a:b3:e7:20:c5:30:9a:3f:68:52:f2:6f # MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b # SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d # SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60 -----BEGIN CERTIFICATE----- MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K 8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp 8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk 0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC 5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC -----END CERTIFICATE----- # Operating CA: Google Trust Services LLC # Issuer: CN=GTS Root R3 O=Google Trust Services LLC # Subject: CN=GTS Root R3 O=Google Trust Services LLC # Label: "GTS Root R3" # Serial: 6e:47:a9:c7:6c:a9:73:24:40:89:0f:03:55:dd:8d:1d # MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25 # SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5 # SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5 -----BEGIN CERTIFICATE----- MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout 736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd -----END CERTIFICATE----- # Operating CA: Google Trust Services LLC # Issuer: CN=GTS Root R4 O=Google Trust Services LLC # Subject: CN=GTS Root R4 O=Google Trust Services LLC # Label: "GTS Root R4" # Serial: 6e:47:a9:c8:8b:94:b6:e8:bb:3b:2a:d8:a2:b2:c1:99 # MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26 # SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb # SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd -----BEGIN CERTIFICATE----- MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== -----END CERTIFICATE----- # Operating CA: GeoTrust Inc. # Issuer: CN=GeoTrust Global CA O=GeoTrust Inc. # Subject: CN=GeoTrust Global CA O=GeoTrust Inc. # Label: "GeoTrust Global CA" # Serial: 02:34:56 # MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5 # SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12 # SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a -----BEGIN CERTIFICATE----- MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU 1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV 5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== -----END CERTIFICATE----- ================================================ FILE: code/default/gae_proxy/local/cert_util.py ================================================ #!/usr/bin/env python # coding:utf-8 import os import sys import glob import time import random import base64 import threading import subprocess import datetime try: import OpenSSL except: pass current_path = os.path.dirname(os.path.abspath(__file__)) python_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir)) root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir)) if __name__ == "__main__": noarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch')) sys.path.append(noarch_lib) if sys.platform == "win32": win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32')) sys.path.append(win32_lib) elif sys.platform == "linux" or sys.platform == "linux2": linux_lib = os.path.abspath( os.path.join(python_path, 'lib', 'linux')) sys.path.append(linux_lib) elif sys.platform == "darwin": darwin_lib = os.path.abspath( os.path.join(python_path, 'lib', 'darwin')) sys.path.append(darwin_lib) import env_info data_path = os.path.abspath(os.path.join(env_info.data_path, "gae_proxy")) if not os.path.isdir(data_path): data_path = current_path import utils from xlog import getLogger xlog = getLogger("gae_proxy") from utils import check_ip_valid def get_cmd_out(cmd): proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = proc.stdout lines = out.readlines() return lines class CertUtil(object): """CertUtil module, based on mitmproxy""" ca_vendor = 'GoAgent' #TODO: here should be XX-Net ca_certfile = os.path.join(data_path, 'CA.crt') ca_keyfile = os.path.join(data_path, 'CAkey.pem') ca_thumbprint = b'' ca_privatekey = None ca_subject = None ca_certdir = os.path.join(data_path, 'certs') ca_digest = 'sha256' ca_lock = threading.Lock() ca_validity_years = 10 ca_validity = 24 * 60 * 60 * 365 * ca_validity_years cert_validity_years = 2 cert_validity = 24 * 60 * 60 * 365 * cert_validity_years cert_publickey = None cert_keyfile = os.path.join(data_path, 'Certkey.pem') serial_reduce = 3600 * 24 * 365 * 46 @staticmethod def create_ca(): key = OpenSSL.crypto.PKey() key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048) ca = OpenSSL.crypto.X509() ca.set_version(2) ca.set_serial_number(0) subj = ca.get_subject() subj.countryName = 'CN' subj.stateOrProvinceName = 'Internet' subj.localityName = 'Cernet' subj.organizationName = CertUtil.ca_vendor # Log generated time. subj.organizationalUnitName = '%s Root - %d' % (CertUtil.ca_vendor, int(time.time())) subj.commonName = '%s XX-Net' % CertUtil.ca_vendor ca.gmtime_adj_notBefore(- 3600 * 24) ca.gmtime_adj_notAfter(CertUtil.ca_validity - 3600 * 24) ca.set_issuer(subj) ca.set_subject(subj) ca.set_pubkey(key) ca.add_extensions([ OpenSSL.crypto.X509Extension( b'basicConstraints', False, b'CA:TRUE', subject=ca, issuer=ca) ]) ca.sign(key, CertUtil.ca_digest) #xlog.debug("CA key:%s", key) xlog.info("create CA") return key, ca @staticmethod def generate_ca_file(): xlog.info("generate CA file:%s", CertUtil.ca_keyfile) key, ca = CertUtil.create_ca() with open(CertUtil.ca_certfile, 'wb') as fp: fp.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, ca)) with open(CertUtil.ca_keyfile, 'wb') as fp: fp.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, ca)) fp.write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, key)) @staticmethod def generate_cert_keyfile(): xlog.info("generate certs's key file:%s", CertUtil.cert_keyfile) pkey = OpenSSL.crypto.PKey() pkey.generate_key(OpenSSL.crypto.TYPE_RSA, 2048) with open(CertUtil.cert_keyfile, 'wb') as fp: fp.write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, pkey)) fp.write(OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM, pkey)) CertUtil.cert_publickey = pkey @staticmethod def _get_cert(commonname, isip=False, sans=None): cert = OpenSSL.crypto.X509() cert.set_version(2) # setting the only serial number, the browser will refused fixed serial number when cert updated. serial_number = int((int(time.time() - CertUtil.serial_reduce) + random.random()) * 100) while 1: try: cert.set_serial_number(serial_number) except OpenSSL.SSL.Error: serial_number += 1 else: break subj = cert.get_subject() subj.countryName = 'CN' subj.stateOrProvinceName = 'Internet' subj.localityName = 'Cernet' subj.organizationalUnitName = '%s Branch' % CertUtil.ca_vendor subj.commonName = commonname subj.organizationName = commonname cert.gmtime_adj_notBefore(-600) #avoid crt time error warning cert.gmtime_adj_notAfter(CertUtil.cert_validity) cert.set_issuer(CertUtil.ca_subject) if CertUtil.cert_publickey: pkey = CertUtil.cert_publickey else: pkey = OpenSSL.crypto.PKey() pkey.generate_key(OpenSSL.crypto.TYPE_RSA, 2048) cert.set_pubkey(pkey) sans = set(sans) if sans else set() sans.add(commonname) if isip: sans = b'IP: ' + commonname else: sans = b'DNS: %s, DNS: *.%s' % (commonname, commonname) cert.add_extensions([OpenSSL.crypto.X509Extension(b'subjectAltName', True, sans)]) cert.sign(CertUtil.ca_privatekey, CertUtil.ca_digest) certfile = os.path.join(CertUtil.ca_certdir, utils.to_str(commonname) + '.crt') with open(certfile, 'wb') as fp: fp.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)) if CertUtil.cert_publickey is None: fp.write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, pkey)) return certfile @staticmethod def _get_old_cert(commonname): certfile = os.path.join(CertUtil.ca_certdir, utils.to_str(commonname) + '.crt') if os.path.exists(certfile): with open(certfile, 'rb') as fp: cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, fp.read()) if datetime.datetime.strptime(utils.to_str(cert.get_notAfter()), '%Y%m%d%H%M%SZ') < datetime.datetime.utcnow() + datetime.timedelta(days=30): try: os.remove(certfile) except OSError as e: xlog.warning('CertUtil._get_old_cert failed: unable to remove outdated cert, %r', e) else: return # well, have to use the old one return certfile @staticmethod def get_cert(commonname, sans=None, full_name=False): commonname = utils.to_bytes(commonname) isip = check_ip_valid(commonname) with CertUtil.ca_lock: certfile = CertUtil._get_old_cert(commonname) if certfile: return certfile # some site need full name cert # like https://about.twitter.com in Google Chrome if not isip and not full_name and commonname.count(b'.') >= 2 and [len(x) for x in reversed(commonname.split(b'.'))] > [2, 4]: commonname = commonname.partition(b'.')[-1] certfile = CertUtil._get_old_cert(commonname) if certfile: return certfile return CertUtil._get_cert(commonname, isip, sans) @staticmethod def win32_notify( msg="msg", title="Title"): import ctypes res = ctypes.windll.user32.MessageBoxW(None, msg, title, 1) # Yes:1 No:2 return res @staticmethod def import_windows_ca(certfile): xlog.debug("Begin to import Windows CA") with open(certfile, 'rb') as fp: certdata = fp.read() if certdata.startswith(b'-----'): begin = b'-----BEGIN CERTIFICATE-----' end = b'-----END CERTIFICATE-----' certdata = base64.b64decode(b''.join(certdata[certdata.find(begin)+len(begin):certdata.find(end)].strip().splitlines())) try: common_name = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, certdata).get_subject().CN except Exception as e: #logging.error('load_certificate(certfile=%r) 失败:%s', certfile, e) return -1 assert certdata, 'cert file %r is broken' % certfile import ctypes.wintypes class CERT_CONTEXT(ctypes.Structure): _fields_ = [ ('dwCertEncodingType', ctypes.wintypes.DWORD), ('pbCertEncoded', ctypes.POINTER(ctypes.wintypes.BYTE)), ('cbCertEncoded', ctypes.wintypes.DWORD), ('pCertInfo', ctypes.c_void_p), ('hCertStore', ctypes.c_void_p),] X509_ASN_ENCODING = 0x1 CERT_STORE_ADD_ALWAYS = 4 CERT_STORE_PROV_SYSTEM = 10 CERT_STORE_OPEN_EXISTING_FLAG = 0x4000 CERT_SYSTEM_STORE_CURRENT_USER = 1 << 16 CERT_SYSTEM_STORE_LOCAL_MACHINE = 2 << 16 CERT_FIND_SUBJECT_STR = 8 << 16 | 7 crypt32 = ctypes.windll.crypt32 ca_exists = False store_handle = None pCertCtx = None ret = 0 for store in (CERT_SYSTEM_STORE_LOCAL_MACHINE, CERT_SYSTEM_STORE_CURRENT_USER): try: store_handle = crypt32.CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, None, CERT_STORE_OPEN_EXISTING_FLAG | store, 'root') if not store_handle: if store == CERT_SYSTEM_STORE_CURRENT_USER and not ca_exists: xlog.warning('CertUtil.import_windows_ca failed: could not open system cert store') return False else: continue pCertCtx = crypt32.CertFindCertificateInStore(store_handle, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, common_name, None) while pCertCtx: certCtx = CERT_CONTEXT.from_address(pCertCtx) _certdata = ctypes.string_at(certCtx.pbCertEncoded, certCtx.cbCertEncoded) if _certdata == certdata: ca_exists = True xlog.debug("XX-Net CA already exists") else: cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, _certdata) if hasattr(cert, 'get_subject'): cert = cert.get_subject() cert_name = next((v for k, v in cert.get_components() if k == 'CN'), '') if cert_name == common_name: ret = crypt32.CertDeleteCertificateFromStore(crypt32.CertDuplicateCertificateContext(pCertCtx)) if ret == 1: xlog.debug("Invalid Windows CA %r has been removed", common_name) elif ret == 0 and store == CERT_SYSTEM_STORE_LOCAL_MACHINE: # to elevate break pCertCtx = crypt32.CertFindCertificateInStore(store_handle, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, common_name, pCertCtx) # Only add to current user if store == CERT_SYSTEM_STORE_CURRENT_USER and not ca_exists: ret = crypt32.CertAddEncodedCertificateToStore(store_handle, X509_ASN_ENCODING, certdata, len(certdata), CERT_STORE_ADD_ALWAYS, None) except Exception as e: xlog.warning('CertUtil.import_windows_ca failed: %r', e) if isinstance(e, OSError): store_handle = None continue return False finally: if pCertCtx: crypt32.CertFreeCertificateContext(pCertCtx) pCertCtx = None if store_handle: crypt32.CertCloseStore(store_handle, 0) store_handle = None if ca_exists: return True if ret == 0 and __name__ != "__main__": #res = CertUtil.win32_notify(msg=u'Import GoAgent Ca?', title=u'Authority need') #if res == 2: # return -1 import win32elevate try: win32elevate.elevateAdminRun(os.path.abspath(__file__)) except Exception as e: xlog.warning('CertUtil.import_windows_ca failed: %r', e) return True elif ret == 1: CertUtil.win32_notify(msg='已经导入GoAgent证书,请重启浏览器.', title='Restart browser need.') return ret == 1 @staticmethod def get_linux_firefox_path(): home_path = os.path.expanduser("~") firefox_path = os.path.join(home_path, ".mozilla/firefox") if not os.path.isdir(firefox_path): return for filename in os.listdir(firefox_path): if filename.endswith(".default") and os.path.isdir(os.path.join(firefox_path, filename)): config_path = os.path.join(firefox_path, filename) #xlog.debug("Got Firefox path: %s", config_path) return config_path @staticmethod def import_linux_firefox_ca(common_name, ca_file): xlog.debug("Begin importing CA to Firefox") firefox_config_path = CertUtil.get_linux_firefox_path() if not firefox_config_path: #xlog.debug("Not found Firefox path") return False if not any(os.path.isfile('%s/certutil' % x) for x in os.environ['PATH'].split(os.pathsep)): xlog.warn('please install *libnss3-tools* package to import GoAgent root ca') return False xlog.info("Removing old cert to Firefox in %s", firefox_config_path) cmd_line = 'certutil -L -d %s |grep "GoAgent" &&certutil -d %s -D -n "%s" ' % (firefox_config_path, firefox_config_path, common_name) os.system(cmd_line) # remove old cert first xlog.info("Add new cert to Firefox in %s", firefox_config_path) cmd_line = 'certutil -d %s -A -t "C,," -n "%s" -i "%s"' % (firefox_config_path, common_name, ca_file) os.system(cmd_line) # install new cert return True @staticmethod def import_linux_ca(common_name, ca_file): def get_linux_ca_sha1(nss_path): commonname = "GoAgent XX-Net - GoAgent" #TODO: here should be GoAgent - XX-Net cmd = ['certutil', '-L','-d', 'sql:%s' % nss_path, '-n', commonname] lines = get_cmd_out(cmd) get_sha1_title = False sha1 = b"" for line in lines: if line.endswith(b"Fingerprint (SHA1):\n"): get_sha1_title = True continue if get_sha1_title: sha1 = line break sha1 = sha1.replace(b' ', b'').replace(b':', b'').replace(b'\n', b'') if len(sha1) != 40: return False else: return sha1 home_path = os.path.expanduser("~") nss_path = os.path.join(home_path, ".pki/nssdb") if not os.path.isdir(nss_path): return False if not any(os.path.isfile('%s/certutil' % x) for x in os.environ['PATH'].split(os.pathsep)): xlog.info('please install *libnss3-tools* package to import GoAgent root ca') return False sha1 = get_linux_ca_sha1(nss_path) ca_hash = CertUtil.ca_thumbprint.replace(b':', b'') if sha1 == ca_hash: xlog.info("Database $HOME/.pki/nssdb cert exist") return # shell command to list all cert # certutil -L -d sql:$HOME/.pki/nssdb # remove old cert first xlog.info("Removing old cert in database $HOME/.pki/nssdb") cmd_line = 'certutil -L -d sql:$HOME/.pki/nssdb |grep "GoAgent" && certutil -d sql:$HOME/.pki/nssdb -D -n "%s" ' % ( common_name) os.system(cmd_line) # install new cert xlog.info("Add cert to database $HOME/.pki/nssdb") cmd_line = 'certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n "%s" -i "%s"' % (common_name, ca_file) os.system(cmd_line) return True @staticmethod def import_ubuntu_system_ca(common_name, certfile): import platform platform_distname = platform.dist()[0] if platform_distname != 'Ubuntu': return pemfile = "/etc/ssl/certs/CA.pem" new_certfile = "/usr/local/share/ca-certificates/CA.crt" if not os.path.exists(pemfile) or not CertUtil.file_is_same(certfile, new_certfile): if os.system('cp "%s" "%s" && update-ca-certificates' % (certfile, new_certfile)) != 0: xlog.warning('install root certificate failed, Please run as administrator/root/sudo') @staticmethod def file_is_same(file1, file2): BLOCKSIZE = 65536 try: with open(file1, 'rb') as f1: buf1 = f1.read(BLOCKSIZE) except: return False try: with open(file2, 'rb') as f2: buf2 = f2.read(BLOCKSIZE) except: return False if buf1 != buf2: return False else: return True @staticmethod def import_mac_ca(common_name, certfile): commonname = "GoAgent XX-Net" #TODO: need check again ca_hash = CertUtil.ca_thumbprint.replace(b':', b'') def get_exist_ca_sha1(): args = ['security', 'find-certificate', '-Z', '-a', '-c', commonname] output = subprocess.check_output(args) for line in output.splitlines(True): if len(line) == 53 and line.startswith(b"SHA-1 hash:"): sha1_hash = line[12:52] return sha1_hash exist_ca_sha1 = get_exist_ca_sha1() if exist_ca_sha1 == ca_hash: xlog.info("GoAgent CA exist") return import_command = 'security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ../../../../data/gae_proxy/CA.crt'# % certfile.decode('utf-8') if exist_ca_sha1: delete_ca_command = 'security delete-certificate -Z %s' % exist_ca_sha1 exec_command = "%s;%s" % (delete_ca_command, import_command) else: exec_command = import_command admin_command = """osascript -e 'do shell script "%s" with administrator privileges' """ % exec_command cmd = admin_command.encode('utf-8') xlog.info("try auto import CA command:%s", cmd) os.system(cmd) @staticmethod def import_ca(certfile): xlog.debug("Importing CA") commonname = "GoAgent XX-Net - GoAgent" #TODO: here should be GoAgent - XX-Net if sys.platform.startswith('win'): CertUtil.import_windows_ca(certfile) elif sys.platform == 'darwin': CertUtil.import_mac_ca(commonname, certfile) elif sys.platform.startswith('linux'): CertUtil.import_linux_ca(commonname, certfile) CertUtil.import_linux_firefox_ca(commonname, certfile) #CertUtil.import_ubuntu_system_ca(commonname, certfile) # we don't need install CA to system root, special user is enough @staticmethod def verify_certificate(ca, cert): if hasattr(OpenSSL.crypto, "X509StoreContext"): store = OpenSSL.crypto.X509Store() store.add_cert(ca) try: OpenSSL.crypto.X509StoreContext(store, cert).verify_certificate() except: return False else: return True else: # A fake verify, just check generated time. return ca.get_subject().OU == cert.get_issuer().OU @staticmethod def init_ca(no_mess_system=0): import OpenSSL #xlog.debug("Initializing CA") #Check Certs Dir if not os.path.exists(CertUtil.ca_certdir): os.makedirs(CertUtil.ca_certdir) # Confirmed GoAgent CA exist if not os.path.exists(CertUtil.ca_keyfile): if os.path.exists(CertUtil.ca_certfile): # update old unsafe CA file xlog.info("update CA file storage format") if hasattr(OpenSSL.crypto, "X509StoreContext"): os.rename(CertUtil.ca_certfile, CertUtil.ca_keyfile) else: xlog.warning("users may need to re-import CA file") CertUtil.generate_ca_file() else: xlog.info("no GAE CA file exist in XX-Net data dir") xlog.info("clean old site certs in XX-Net cert dir") any(os.remove(x) for x in glob.glob(os.path.join(CertUtil.ca_certdir, '*.crt')) + glob.glob(os.path.join(CertUtil.ca_certdir, '.*.crt'))) CertUtil.generate_ca_file() # Load GoAgent CA with open(CertUtil.ca_keyfile, 'rb') as fp: content = fp.read() ca = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, content) CertUtil.ca_privatekey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, content) CertUtil.ca_thumbprint = ca.digest('sha1') CertUtil.ca_subject = ca.get_subject() ca_cert_error = True if os.path.exists(CertUtil.ca_certfile): with open(CertUtil.ca_certfile, 'rb') as fp: ca_cert_error = fp.read() not in content if ca_cert_error: with open(CertUtil.ca_certfile, 'wb') as fp: fp.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, ca)) # Check cert keyfile exists if hasattr(OpenSSL.crypto, "load_publickey"): if os.path.exists(CertUtil.cert_keyfile): with open(CertUtil.cert_keyfile, 'rb') as fp: CertUtil.cert_publickey = OpenSSL.crypto.load_publickey(OpenSSL.crypto.FILETYPE_PEM, fp.read()) else: CertUtil.generate_cert_keyfile() else: CertUtil.cert_keyfile = None # Check exist site cert buffer with CA certfiles = glob.glob(os.path.join(CertUtil.ca_certdir, '*.crt')) + glob.glob(os.path.join(CertUtil.ca_certdir, '.*.crt')) if certfiles: filename = random.choice(certfiles) with open(filename, 'rb') as fp: cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, fp.read()) remove_certs = False if not CertUtil.verify_certificate(ca, cert): remove_certs = True if not remove_certs and CertUtil.cert_publickey: context = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD) try: context.use_certificate(cert) context.use_privatekey_file(CertUtil.cert_keyfile) except OpenSSL.SSL.Error: remove_certs = True if remove_certs: xlog.info("clean old site certs in XX-Net cert dir") any(os.remove(x) for x in certfiles) if not no_mess_system: CertUtil.import_ca(CertUtil.ca_keyfile) # change the status, # web_control /cert_import_status will return True, else return False # launcher will wait ready to open browser and check update # config.cert_import_ready = True if __name__ == '__main__': CertUtil.init_ca() #TODO: # CA commaon should be GoAgent, vander should be XX-Net # need change and test on all support platform: Windows/Mac/Ubuntu/Debian ================================================ FILE: code/default/gae_proxy/local/check_ip.py ================================================ #!/usr/bin/env python2 # coding:utf-8 import sys import os import threading current_path = os.path.dirname(os.path.abspath(__file__)) default_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir)) if __name__ == "__main__": sys.path.append(default_path) noarch_lib = os.path.abspath(os.path.join(default_path, 'lib', 'noarch')) sys.path.append(noarch_lib) if sys.platform == "win32": win32_lib = os.path.abspath(os.path.join(default_path, 'lib', 'win32')) sys.path.append(win32_lib) elif sys.platform.startswith("linux"): linux_lib = os.path.abspath(os.path.join(default_path, 'lib', 'linux')) sys.path.append(linux_lib) elif sys.platform == "darwin": darwin_lib = os.path.abspath(os.path.join(default_path, 'lib', 'darwin')) sys.path.append(darwin_lib) extra_lib = "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python" sys.path.append(extra_lib) import env_info module_data_path = os.path.join(env_info.data_path, 'gae_proxy') import xlog logger = xlog.getLogger("gae_proxy") from xx_six import ConnectionError, ConnectionResetError, BrokenPipeError from front_base.openssl_wrap import SSLContext from front_base.connect_creator import ConnectCreator import front_base.check_ip from gae_proxy.local.config import config from gae_proxy.local.host_manager import HostManager class CheckIp(front_base.check_ip.CheckIp): def check_response(self, response): server_type = response.headers.get(b'Server', b"") if isinstance(server_type, list): server_type = server_type[0] self.logger.debug("status:%d", response.status) self.logger.debug("Server type:%s", server_type) if response.status not in self.config.check_ip_accept_status: return False if response.status in [503, 500]: # out of quota if b"gws" not in server_type and b"Google Frontend" not in server_type and b"GFE" not in server_type: xlog.warn("%d but server type:%s", response.status, server_type) return False else: return True try: content = response.read() except Exception as e: if sys.version_info[0] == 3 and ( isinstance(e, ConnectionError) or isinstance(e, ConnectionResetError) or isinstance(e, BrokenPipeError) ): return False self.logger.warn("app check except:%r", e) return False if self.config.check_ip_content not in content: self.logger.warn("app check content:%s", content) return False return True class CheckAllIp(object): def __init__(self): ca_certs = os.path.join(current_path, "cacert.pem") openssl_context = SSLContext( logger, ca_certs=ca_certs, cipher_suites=[b'ALL', b"!RC4-SHA", b"!ECDHE-RSA-RC4-SHA", b"!ECDHE-RSA-AES128-GCM-SHA256", b"!AES128-GCM-SHA256", b"!ECDHE-RSA-AES128-SHA", b"!AES128-SHA"] ) host_manager = HostManager() connect_creator = ConnectCreator(logger, config, openssl_context, host_manager, debug=True) self.check_ip = CheckIp(logger, config, connect_creator) self.lock = threading.Lock() self.in_fd = open("ipv6_list.txt", "r") self.out_fd = open( os.path.join(module_data_path, "ipv6_list.txt"), "w" ) def get_ip(self): with self.lock: while True: line = self.in_fd.readline() if not line: raise Exception() try: ip = line.split()[0] return ip except: continue def write_ip(self, ip, host, handshake): with self.lock: self.out_fd.write("%s %s gws %d 0 0\n" % (ip, host, handshake)) self.out_fd.flush() def checker(self): while True: try: ip = self.get_ip() except Exception as e: xlog.info("no ip left") return try: res = self.check_ip.check_ip(ip) except Exception as e: xlog.warn("check except:%r", e) continue if not res or not res.ok: xlog.debug("ip:%s fail", ip) continue if res.h2: self.write_ip(ip, res.domain, res.handshake_time) def run(self): for i in range(0, 100): threading.Thread(target=self.checker, name="gae_ip_checker").start() def check_all(): check = CheckAllIp() check.run() exit(0) if __name__ == "__main__": # check_all() # case 1: only ip # case 2: ip + domain # connect use domain if len(sys.argv) > 1: ip = sys.argv[1] else: ip = "142.250.66.180" xlog.info(("test ip:%s" % ip)) if len(sys.argv) > 2: top_domain = sys.argv[2] else: top_domain = None if len(sys.argv) > 3: wait_time = int(sys.argv[3]) else: wait_time = 0 ca_certs = os.path.join(current_path, "cacert.pem") openssl_context = SSLContext( logger, ca_certs=ca_certs, protocol="TLSv1_2" # cipher_suites=[b'ALL', b"!RC4-SHA", b"!ECDHE-RSA-RC4-SHA", b"!ECDHE-RSA-AES128-GCM-SHA256", # b"!AES128-GCM-SHA256", b"!ECDHE-RSA-AES128-SHA", b"!AES128-SHA"] ) host_manager = HostManager(config, logger) connect_creator = ConnectCreator(logger, config, openssl_context, host_manager, debug=True) check_ip = CheckIp(logger, config, connect_creator) res = check_ip.check_ip(ip, host=top_domain, wait_time=wait_time) if not res: xlog.info("connect fail") elif res.ok: xlog.info(("success, domain:%s handshake:%d" % (res.host, res.handshake_time))) else: xlog.info("not support") ================================================ FILE: code/default/gae_proxy/local/check_local_network.py ================================================ import sys import os import time import threading current_path = os.path.dirname(os.path.abspath(__file__)) if __name__ == "__main__": python_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir)) root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir)) noarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch')) sys.path.append(noarch_lib) sys.path.append(root_path) if sys.platform == "win32": win32_lib = os.path.abspath(os.path.join(python_path, 'lib', 'win32')) sys.path.append(win32_lib) elif sys.platform.startswith("linux"): linux_lib = os.path.abspath(os.path.join(python_path, 'lib', 'linux')) sys.path.append(linux_lib) from gae_proxy.local.config import config import utils import simple_http_client from xlog import getLogger xlog = getLogger("gae_proxy") max_timeout = 5 class CheckNetwork(object): check_valid = 30 timeout = 5 def __init__(self, type="IPv4"): self.type = type self.urls = [] self._checking_lock = threading.Lock() self._checking_num = 0 self.network_stat = "unknown" self.last_check_time = 0 self.continue_fail_count = 0 if config.PROXY_ENABLE: if config.PROXY_USER: self.proxy = "%s://%s:%s@%s:%d" % \ (config.PROXY_TYPE, config.PROXY_USER, config.PROXY_PASSWD, config.PROXY_HOST, config.PROXY_PORT) else: self.proxy = "%s://%s:%d" % \ (config.PROXY_TYPE, config.PROXY_HOST, config.PROXY_PORT) else: self.proxy = None self.http_client = simple_http_client.Client(self.proxy, timeout=self.timeout) def report_ok(self): self.network_stat = "OK" self.last_check_time = time.time() self.continue_fail_count = 0 def report_fail(self): self.continue_fail_count += 1 # don't record last_check_time here, it's not a real check # last_check_time = time.time() if self.continue_fail_count > 1: # don't set network_stat to "unknown", wait for check # network_stat = "unknown" xlog.debug("report_connect_fail %s continue_fail_count:%d", self.type, self.continue_fail_count) if time.time() - self.last_check_time > self.check_valid: self.triger_check_network(True) def get_stat(self): if config.check_local_network_rules == "force_fail": return "Fail" elif config.check_local_network_rules == "force_ok": return "OK" else: return self.network_stat def is_ok(self): if self.network_stat == "unknown" or time.time() - self.last_check_time > self.check_valid: self.triger_check_network(True) if config.check_local_network_rules == "normal": if self.network_stat == "OK" and time.time() - self.last_check_time < self.check_valid + self.timeout: return True else: return False elif config.check_local_network_rules == "force_fail": return False elif config.check_local_network_rules == "force_ok": return True else: return self.network_stat == "OK" def _test_host(self, url): try: header = { "user-agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36", "accept": "application/json, text/javascript, */*; q=0.01", "accept-encoding": "gzip, deflate, sdch", "accept-language": 'en-US,en;q=0.8,ja;q=0.6,zh-CN;q=0.4,zh;q=0.2', "connection": "keep-alive" } response = self.http_client.request("HEAD", url, header, "", read_payload=False) if response: return True except Exception as e: if __name__ == "__main__": xlog.exception("test %s e:%r", url, e) return False def _simple_check_worker(self): time_now = time.time() self._checking_lock.acquire() self._checking_num += 1 self._checking_lock.release() network_ok = False for url in self.urls: if self._test_host(url): network_ok = True break else: if __name__ == "__main__": xlog.warn("test %s fail", url) time.sleep(1) if network_ok: self.last_check_time = time.time() self.report_ok() xlog.debug("network %s is ok, cost:%d ms", self.type, 1000 * (time.time() - time_now)) else: xlog.warn("network %s fail", self.type) self.network_stat = "Fail" self.last_check_time = time.time() self._checking_lock.acquire() self._checking_num -= 1 self._checking_lock.release() def triger_check_network(self, fail=False, force=False): time_now = time.time() if not force: if self._checking_num > 0: return if fail or self.network_stat != "OK": # Fail or unknown if time_now - self.last_check_time < 3: return else: if time_now - self.last_check_time < 10: return self.last_check_time = time_now threading.Thread(target=self._simple_check_worker, name="network_checker").start() IPv4 = CheckNetwork("IPv4") IPv4.urls = [ "https://www.bing.com", "https://code.jquery.com", "https://cdn.bootcss.com", "https://upcdn.b0.upaiyun.com", "https://cdn.bootcdn.net", "https://cdn.staticfile.org", ] # IPv4.triger_check_network() IPv6 = CheckNetwork("IPv6") IPv6.urls = [ "https://ipv6.vm3.test-ipv6.com", "https://ipv6.lookup.test-ipv6.com", "https://v6.myip.la", "https://speed.neu6.edu.cn/" ] # IPv6.triger_check_network() def report_ok(ip): if "." in ip: IPv4.report_ok() else: IPv6.report_ok() def report_fail(ip): if "." in ip: IPv4.report_fail() else: IPv6.report_fail() def is_ok(ip=None): ip = utils.to_str(ip) if not ip: return IPv4.is_ok() or IPv6.is_ok() elif "." in ip: return IPv4.is_ok() else: return IPv6.is_ok() if __name__ == "__main__": # print(IPv6._test_host("http://[2804:10:4068::202:82]")) IPv4._test_host("https://www.baidu.com") ================================================ FILE: code/default/gae_proxy/local/config.py ================================================ import os from front_base.config import ConfigBase import utils import env_info current_path = os.path.dirname(os.path.abspath(__file__)) root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir)) module_data_path = os.path.join(env_info.data_path, 'gae_proxy') headers = {"connection": "close"} class Config(ConfigBase): def __init__(self, fn): super(Config, self).__init__(fn) # globa setting level # passive < conservative < normal < radical < extreme self.set_var("setting_level", "normal") # proxy self.set_var("listen_ip", "127.0.0.1") self.set_var("listen_port", 8087) # auto range self.set_var("AUTORANGE_THREADS", 10) self.set_var("AUTORANGE_MAXSIZE", 512 * 1024) # if mobile: # self.set_var("AUTORANGE_MAXBUFFERSIZE", 10 * 1024 * 1024 / 8) # else: self.set_var("AUTORANGE_MAXBUFFERSIZE", 20 * 1024 * 1024) self.set_var("JS_MAXSIZE", 0) # gae self.set_var("GAE_PASSWORD", "") self.set_var("GAE_VALIDATE", 1) # host rules self.set_var("hosts_direct", [ #b"docs.google.com", #"play.google.com", #b"scholar.google.com", #"scholar.google.com.hk", #b"appengine.google.com" ]) self.set_var("hosts_direct_endswith", [ #b".gvt1.com", b".appspot.com" ]) self.set_var("hosts_gae", [ b"accounts.google.com", b"mail.google.com" ]) self.set_var("hosts_gae_endswith", [ b".googleapis.com" ]) # sites using br self.set_var("BR_SITES", [ b"webcache.googleusercontent.com", b"www.google.com", b"www.google.com.hk", b"www.google.com.cn", b"fonts.googleapis.com" ]) self.set_var("BR_SITES_ENDSWITH", [ b".youtube.com", b".facebook.com", b".googlevideo.com" ]) # some unsupport request like url length > 2048, will go Direct self.set_var("google_endswith", [ b".youtube.com", b".googleapis.com", b".google.com", b".googleusercontent.com", b".ytimg.com", b".doubleclick.net", b".google-analytics.com", b".googlegroups.com", b".googlesource.com", b".gstatic.com", b".appspot.com", b".gvt1.com", b".android.com", b".ggpht.com", b".googleadservices.com", b".googlesyndication.com", b".2mdn.net" ]) # front self.set_var("front_continue_fail_num", 10) self.set_var("front_continue_fail_block", 0) # http_dispatcher self.set_var("dispather_min_idle_workers", 3) self.set_var("dispather_work_min_idle_time", 0) self.set_var("dispather_work_max_score", 1000) self.set_var("dispather_min_workers", 20) self.set_var("dispather_max_workers", 50) self.set_var("dispather_max_idle_workers", 15) self.set_var("max_task_num", 80) # http 1 worker self.set_var("http1_first_ping_wait", 5) self.set_var("http1_idle_time", 200) self.set_var("http1_ping_interval", 0) # http 2 worker self.set_var("http2_max_concurrent", 20) self.set_var("http2_target_concurrent", 1) self.set_var("http2_max_timeout_tasks", 1) self.set_var("http2_timeout_active", 0) self.set_var("http2_ping_min_interval", 0) # connect_manager self.set_var("https_max_connect_thread", 10) self.set_var("ssl_first_use_timeout", 5) self.set_var("connection_pool_min", 1) self.set_var("https_connection_pool_min", 0) self.set_var("https_connection_pool_max", 10) self.set_var("https_new_connect_num", 3) self.set_var("https_keep_alive", 10) # check_ip self.set_var("check_ip_host", "xxnet-1.appspot.com") self.set_var("check_ip_accept_status", [200, 500, 503]) self.set_var("check_ip_content", b"GoAgent") # host_manager self.set_var("GAE_APPIDS", []) # connect_creator self.set_var("check_pkp", [ # Expired CAs # GIAG2 # GIAG3 # GTSGIAG3 # GIAG3ECC # GIAG4 # https://pki.goog/repo/certs/giag4.pem # GIAG4x # https://pki.goog/repo/certs/giag4x.pem b'''\ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvSw7AnhsoyYa5z/crKtt B52X+R0ld3UdQBU4Yc/4wmF66cpHeEOMSmhdaY5RzYrowZ6kG1xXLrSoVUuudUPR fg/zjRqv/AAVDJFqc8OnhghzaWZU9zlhtRgY4lx4Z6pDosTuR5imCcKvwqiDztOJ r4YKHuk23p3cxu1zDnUsuN+cm4TkVtI1SsuSc9t1uErBvFIcW6v3dLcjrPkmwE61 udZQlBDHJzCFwrhXLtXLlmuSA5/9pOuWJ+U3rSgS7ICSfa83vkBe00ymjIZT6ogD XWuFsu4edue27nG8g9gO1YozIUCV7+zExG0G5kxTovis+FJpy9hIIxSFrRIKM4DX aQIDAQAB -----END PUBLIC KEY----- ''', # GIAG4 ECC # https://pki.goog/repo/certs/giag4ecc.pem b'''\ -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWgDxDsTP7Od9rB8TPUltMacYCHYI NthcDjlPu3wP0Csmy6Drit3ghqaTqFecqcgks5RwcKQkT9rbY3e8lHuuAw== -----END PUBLIC KEY----- ''', # GTS CA 1C3 # https://pki.goog/repo/certs/gts1c3.pem b'''\ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9Yjf52KMHjf4N0KQf2yH 0PtlgiX96MtrpP9t6Voj4pn2HOmSA5kTfAkKivpC1l5WJKp6M4Qf0elpu7l07FdM ZmiTdzdVU/45EE23NLtfJXc3OxeU6jzlndW8w7RD6y6nR++wRBFj2LRBhd1BMEiT G7+39uBFAiHglkIXz9krZVY0ByYEDaj9fcou7+pIfDdNPwCfg9/vdYQueVdc/Fdu Gpb//Iyappm+Jdl/liwG9xEqAoCA62MYPFBJh+WKyl8ZK1mWgQCg+1HbyncLC8mW T+9wScdcbSD9mbS04soud/0t3Au2axMMjBkrF5aYufCL9qAnu7bjjVGPva7Hm7GJ nQIDAQAB -----END PUBLIC KEY----- ''', # GTS CA 1D2 # https://pki.goog/repo/certs/gts1d2.pem b'''\ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAstl74eHXPxyRcv/5EM2H FXl0tz5Hi7JhVf0MNsZ+d0I6svpSWwtxgdZN1ekrJE0jXosrcl8hVbUp70TL64JS qz4npJJJQUreqN0x4DzfbXpNLdZtCbAO42Hysv6QbFp7EGRJtAs8CPLqeQxsphqJ alYyoCmiMIKPgVEM86K52XW5Ip4nFLpKLyxjWIfxXRDmX5G7uVvMR+IedbaMj8x1 XVcF54LGhA50cirLO1X1bnDrZmnDJLs4kzWbaGEvm9aupndyfHFIWDMQr+mAgh21 B0Ab9j3soq1HnbSUKTSzjC/NJQNYNcAlpFVf4bMHVj3I0GO4IPuMHUMs+Pmp1exv lwIDAQAB -----END PUBLIC KEY----- ''', # GTS CA 1D4 # https://pki.goog/repo/certs/gts1d4.pem b'''\ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8Cqo8ITbuXTD3MLx1M8 gTz1sD7FOYNobvLtV9Dhz6Y5aGVR5tRCkrTK/avrvxEkTErQdYON6r6csgc3USbm PqsBFmLGbJFKOEhHQo5A8YExSV2xrO0ggns7SD/zaqP+8YOX//e3i1OrGJGEtCdM tcl14H7YOGR1TogiDHrA3sTk1xQfdFyx6NyqPynlKPX28GbqLUWGosbKaEwWuhZV QY7fG0gf3V2yDLh4Upx8pUtYrejbX3RDQub9KIqYttEnkC7jLV64UmbYkz14HzgW SpreK+tdZR5W3J7QJB0q+xjYWRrO/G3G+6wsnMtZgeTnnNxEBpwMDZJ4S0FtB8PW qwIDAQAB -----END PUBLIC KEY----- ''', # GTS CA 1O1 # https://pki.goog/repo/certs/gts1o1.pem b'''\ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0BjPRdSLzdOc5EDvfrTd aSEbyc88jkx1uQ8xGYQ9njwp71ANEJNvBYCAnyqgvRJLAuE9n1gWJP4wnwt0d1WT HUv3TeGSghD2UawMw7IilA80a5gQSecLnYM53SDGHC3v0RhhZecjgyCoIxL/0iR/ 1C/nRGpbTddQZrCvnkJjBfvgHMRjYa+fajP/Ype9SNnTfBRn3HXcLmno+G14adC3 EAW48THCOyT9GjN0+CPg7GsZihbG482kzQvbs6RZYDiIO60ducaMp1Mb/LzZpKu8 3Txh15MVmO6BvY/iZEcgQAZO16yX6LnAWRKhSSUj5O1wNCyltGN8+aM9g9HNbSSs BwIDAQAB -----END PUBLIC KEY----- ''', # GTS CA 1P5 # https://pki.goog/repo/certs/gts1p5.pem b'''\ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs4LwJIy/LYevstmnrvrK ukTWWz7+sveyZRbc3hDoTy0QWFoohoeh7mqzoNl1T3+hUgGLVahKWwZIyDYSJauJ +fIjX51gZflc2r466FxtfZzQhBiFMM1Om+w82LPhltTzxQtl24+wdMv2HvN48ayV xd1zwzGIga90qm/9DOMFlfDFEE9lY/qgr8YYPcWh35d51wWJszCwdK49khBrjBV3 3QsEV/uBA93qIjTV5Vay8MSNQbHDAtti7IDQ/3bUhuQEGra2DCticX3Zr9nxXvrA HsqgGVxV8IDRKgwHhpCfNeMoK1vvI8ijHaSjOu7+g9yCTCWwTcVRrZ6b01uEwhpa 6QIDAQAB -----END PUBLIC KEY----- ''', # GTS CA 2A1 # https://pki.goog/repo/certs/gts2a1.pem b'''\ -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAN+bsxmjxoOPZBA3MIh/CdD/J31/ 5vRh3MdletXO0zD+TrcD4wZPMrVdMsX4tiPtyzI/rYEiaaJFIBfAXqKIiA== -----END PUBLIC KEY----- ''', # GTS Root R1 Cross # https://pki.goog/repo/certs/gtsr1x.pem b'''\ -----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAthECix7joXebO9y/lD63 ladAPKH9gvl9MgaCcfb2jH/76Nu8ai6Xl6OMS/kr9rH5zoQdsfnFl97vufKj6bwS iV6nqlKr+CMny6SxnGPb15l+8Ape62im9MZaRw1NEDPjTrETo8gYbEvs/AmQ351k KSUjB6G00j0uYODP0gmHu81I8E3CwnqIiru6z1kZ1q+PsAewnjHxgsHA3y6mbWwZ DrXYfiYaRQM9sHmklCitD38m5agI/pboPGiUU+6DOogrFZYJsuB6jC511pzrp1Zk j5ZPaK49l8KEj8C8QMALXL32h7M1bKwYUH+E4EzNktMg6TO8UpmvMrUpsyUqtEj5 cuHKZPfmghCN6J3Cioj6OGaK/GP5Afl4/Xtcd/p2h/rs37EOeZVXtL0m79YB0esW CruOC7XFxYpVq9Os6pFLKcwZpDIlTirxZUTQAs6qzkm06p98g7BAe+dDq6dso499 iYH6TKX/1Y7DzkvgtdizjkXPdsDtQCv9Uw+wp9U7DbGKogPeMa3Md+pvez7W35Ei Eua++tgy/BBjFFFy3l3WFpO9KWgz7zpm7AeKJt8T11dleCfeXkkUAKIAf5qoIbap sZWwpbkNFhHax2xIPEDgfg1azVY80ZcFuctL7TlLnMQ/0lUTbiSw1nH69MG6zO0b 9f6BQdgAmD06yK56mDcYBZUCAwEAAQ== -----END PUBLIC KEY----- ''', # GTS Y1 # https://pki.goog/repo/certs/gtsy1.pem b'''\ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv72WKaCDZTTnN6KC5yhi aDZLawHdgu2zIhpeHogZBdpibue99PU8V26a17//FpbCHzCLBxq8IDnAcIGBtOkG J+QfHcUow/iFccLDQrhN4YlHl4hhEAaejqXKBy3U+NN2De/rfdDB/QX+38MZnfrx cLudTgS8ItVbmA9kC/8wnGGrMbLvC7KhJk6aPspN8hXzmjfEHnz3Y9O64eu9QBou 47trCZspr6bXqW/XZV/b/KiOlsprLR4pobkd4gOkrLSNMTsRcrTHh/4SCPYLR6QV oIZ1K2cmLhJHuxYTOy7ziG0sQmvku/Sh+GeU2Pakm3wSPubxQFDofYs8AQ2dZYfw YQIDAQAB -----END PUBLIC KEY----- ''', # GTS Y2 # https://pki.goog/repo/certs/gtsy2.pem b'''\ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqB9XbHMq4soQmRpOVF9C snIPC2uZ3ITR0QRReBLhOY3sWwjeBctqqMcocN0zg+30c4+UVAcOdAxHjEpVakbr tcqfF71wrhau8o6sn+y8MrdYAtrGrYzns26KETX8NIzxJy/v31wJOQnW/WZEizes 4JfO/1Mo3qWAiaoctsiHmL5PG8xQkdOhPNdHu6KcgO0IsJ9BCCufd9TpJMb0EnO1 WK3WZLQdgmVny5FkEqp0Fz5TgQKekHyajnbujf1T09AGzTQgO0Btz15WL9pkMADM WKwYtbEurJaHrAgejMHWC7KjaqH3XlVmFMJs3rDDIQxyTRLBPqRLaiUkzxvBBnmr lwIDAQAB -----END PUBLIC KEY----- ''', # GTS Y3 # https://pki.goog/repo/certs/gtsy3.pem b'''\ -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8rfkbjTwx1dixmkxk3b8dhsNCYRC npKv6jT9gnu5BtJlK3kG/l57HRM9E1/GwErnpBxDBnkLeee+Qb3VxGWHsw== -----END PUBLIC KEY----- ''', # GTS Y4 # https://pki.goog/repo/certs/gtsy4.pem b'''\ -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqPJbOoggUvyliF5Us9hq047KDrKP 9uViYwR13jjZCM4rgkOdciVuN0w8zuxzFnQWaY0r085HwQKAr8rGsbJYdg== -----END PUBLIC KEY----- ''', # Google CA1 # https://pki.goog/repo/certs/tp_googleca1.pem b'''\ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAupYx7NU9sbeWxSISCARB GUNj/YKmUpoFxnM+cFwU98Qm3TWk+QkkbgWN7ScBqBHKHqwHt6OZvkhCEbV3D7C2 iDknM8riJdR45f9mDzHUiO12AHyxqao54PrSGvIukBCxU0BO8UV8zg/ZDFUoRPL6 4Pk9xWld9Thzlwts6Bi6CkjZ6HM5EiFiiIcOSvx8tGIHc0/ncBBjsop/ceRK6415 ReXKpyFHEEqH42P64XrGdDYSVli0jZhUDQoHCCjZxIpAagLYM5pryVvdWBGTvH4n 0j0uzPIM8riC+XYyHKnpW/JgargXADBQvIRwRNwEuvfvTVa4JIlPhCYwMo4qLzhx vQIDAQAB -----END PUBLIC KEY----- ''', # GTS CA 1D3 # https://pki.goog/repo/certs/tp_gtsca1d3.pem b'''\ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsUX4++gDvlpQYGaFi9Jm omOPfqAsDVJBCLMQa8Ox2vBPsdd7ZqzqiVJquTRnSWNnOJBSuzf+RDZuEZz9eS5k Z19DcwrRU/aIKEhPBcnui7Z//JZpHBF6ai89CXpChanZXbX6I9ylVomPI9+uuTb6 3RUAy6++1I/FdU/G/YTVNbJHsHXyBSHm7C537EPXowAH5zQZ8t18IoLuPVBrQpDV KvBVMdT9Wc21fvPvrkEY+Il/6Z8NXL/kUmAMxsSsulpUBwEUKe+1haRtGMsM6DZh N3Tphr+AwTioLnSvaNDyqo+zfpJeXsoiwFLH+Y6YsP6R5IjVBzUoimFgeWeTSbYP YQIDAQAB -----END PUBLIC KEY----- ''' ]) #self.set_var("check_commonname", "Google") self.set_var("min_intermediate_CA", 2) self.set_var("support_http2", 1) # ip_manager self.set_var("max_scan_ip_thread_num", 10) self.set_var("max_good_ip_num", 100) self.set_var("target_handshake_time", 600) # ip source self.set_var("use_ipv6", "auto") #force_ipv4/force_ipv6/auto self.set_var("ipv6_scan_ratio", 90) # 0 - 100 # Check local network self.set_var("check_local_network_rules", "normal") # normal, force_ok, force_fail self.load() def load(self): super(Config, self).load() need_save = 0 if not os.path.isfile(self.config_path): for fn in [ os.path.join(module_data_path, "config.ini"), os.path.join(module_data_path, "manual.ini") ]: need_save += self.load_old_config(fn) self.HOSTS_GAE = tuple(utils.to_bytes(self.hosts_gae)) self.HOSTS_DIRECT = tuple(utils.to_bytes(self.hosts_direct)) self.HOSTS_GAE_ENDSWITH = tuple(utils.to_bytes(self.hosts_gae_endswith)) self.HOSTS_DIRECT_ENDSWITH = tuple(utils.to_bytes(self.hosts_direct_endswith)) self.GOOGLE_ENDSWITH = tuple(utils.to_bytes(self.google_endswith)) self.br_sites = tuple(utils.to_bytes(self.BR_SITES)) self.br_endswith = tuple(utils.to_bytes(self.BR_SITES_ENDSWITH)) # there are only hundreds of GAE IPs, we don't need a large threads num self.max_scan_ip_thread_num = min(self.max_scan_ip_thread_num, 200) if need_save: self.save() def load_old_config(self, fn): if not os.path.isfile(fn): return 0 need_save = 0 with open(fn, "r") as fd: for line in fd.readlines(): if line.startswith("appid"): try: appid_str = line.split("=")[1] appids = [] for appid in appid_str.split("|"): appid = appid.strip() appids.append(appid) self.GAE_APPIDS = appids need_save += 1 except Exception as e: pass elif line.startswith("password"): password = line.split("=")[1].strip() self.GAE_PASSWORD = password need_save += 1 return need_save def set_level(self, level=None): if level is None: level = self.setting_level elif level in ["passive", "conservative", "normal", "radical", "extreme"]: self.setting_level = level if level == "passive": self.dispather_min_idle_workers = 0 self.dispather_work_min_idle_time = 0 self.dispather_work_max_score = 1000 self.dispather_min_workers = 5 self.dispather_max_workers = 30 self.dispather_max_idle_workers = 5 self.max_task_num = 50 self.https_max_connect_thread = 10 self.https_keep_alive = 5 self.https_connection_pool_min = 0 self.https_connection_pool_max = 10 self.max_scan_ip_thread_num = 10 self.max_good_ip_num = 60 self.target_handshake_time = 600 elif level == "conservative": self.dispather_min_idle_workers = 1 self.dispather_work_min_idle_time = 0 self.dispather_work_max_score = 1000 self.dispather_min_workers = 10 self.dispather_max_workers = 30 self.dispather_max_idle_workers = 10 self.max_task_num = 50 self.https_max_connect_thread = 10 self.https_keep_alive = 15 self.https_connection_pool_min = 0 self.https_connection_pool_max = 10 self.max_scan_ip_thread_num = 10 self.max_good_ip_num = 100 self.target_handshake_time = 600 elif level == "normal": self.dispather_min_idle_workers = 3 self.dispather_work_min_idle_time = 0 self.dispather_work_max_score = 1000 self.dispather_min_workers = 20 self.dispather_max_workers = 50 self.dispather_max_idle_workers = 15 self.max_task_num = 80 self.https_max_connect_thread = 10 self.https_keep_alive = 15 self.https_connection_pool_min = 0 self.https_connection_pool_max = 10 self.max_scan_ip_thread_num = 10 self.max_good_ip_num = 100 self.target_handshake_time = 600 elif level == "radical": self.dispather_min_idle_workers = 3 self.dispather_work_min_idle_time = 1 self.dispather_work_max_score = 1000 self.dispather_min_workers = 30 self.dispather_max_workers = 70 self.dispather_max_idle_workers = 25 self.max_task_num = 100 self.https_max_connect_thread = 15 self.https_keep_alive = 15 self.https_connection_pool_min = 1 self.https_connection_pool_max = 15 self.max_scan_ip_thread_num = 20 self.max_good_ip_num = 100 self.target_handshake_time = 1200 elif level == "extreme": self.dispather_min_idle_workers = 5 self.dispather_work_min_idle_time = 5 self.dispather_work_max_score = 1000 self.dispather_min_workers = 45 self.dispather_max_workers = 100 self.dispather_max_idle_workers = 40 self.max_task_num = 130 self.https_max_connect_thread = 20 self.https_keep_alive = 15 self.https_connection_pool_min = 2 self.https_connection_pool_max = 20 self.max_scan_ip_thread_num = 30 self.max_good_ip_num = 200 self.target_handshake_time = 1500 self.save() self.load() class DirectConfig(object): def __init__(self, config): self._config = config self.set_default() def __getattr__(self, attr): return getattr(self._config, attr) def dummy(*args, **kwargs): pass set_var = save = load = dummy def set_level(self, level=None): if level is None: level = self.setting_level if level == "passive": self.dispather_min_idle_workers = 0 self.dispather_work_min_idle_time = 0 self.dispather_work_max_score = 1000 self.dispather_min_workers = 0 self.dispather_max_workers = 8 self.dispather_max_idle_workers = 0 self.max_task_num = 16 self.https_max_connect_thread = 4 self.https_connection_pool_min = 0 self.https_connection_pool_max = 6 elif level == "conservative": self.dispather_min_idle_workers = 1 self.dispather_work_min_idle_time = 0 self.dispather_work_max_score = 1000 self.dispather_min_workers = 1 self.dispather_max_workers = 8 self.dispather_max_idle_workers = 2 self.max_task_num = 16 self.https_max_connect_thread = 5 self.https_connection_pool_min = 0 self.https_connection_pool_max = 8 elif level == "normal": self.dispather_min_idle_workers = 2 self.dispather_work_min_idle_time = 0 self.dispather_work_max_score = 1000 self.dispather_min_workers = 3 self.dispather_max_workers = 8 self.dispather_max_idle_workers = 3 self.max_task_num = 16 self.https_max_connect_thread = 6 self.https_connection_pool_min = 0 self.https_connection_pool_max = 10 elif level == "radical": self.dispather_min_idle_workers = 3 self.dispather_work_min_idle_time = 1 self.dispather_work_max_score = 1000 self.dispather_min_workers = 5 self.dispather_max_workers = 10 self.dispather_max_idle_workers = 5 self.max_task_num = 20 self.https_max_connect_thread = 6 self.https_connection_pool_min = 1 self.https_connection_pool_max = 10 elif level == "extreme": self.dispather_min_idle_workers = 5 self.dispather_work_min_idle_time = 5 self.dispather_work_max_score = 1000 self.dispather_min_workers = 5 self.dispather_max_workers = 15 self.dispather_max_idle_workers = 5 self.max_task_num = 30 self.https_max_connect_thread = 10 self.https_connection_pool_min = 1 self.https_connection_pool_max = 10 set_default = set_level config_path = os.path.join(module_data_path, "config.json") config = Config(config_path) direct_config = DirectConfig(config) ================================================ FILE: code/default/gae_proxy/local/direct_handler.py ================================================ #!/usr/bin/env python # coding:utf-8 import time import re import socket import ssl import errno try: import OpenSSL NetWorkIOError = (socket.error, ssl.SSLError, OpenSSL.SSL.Error, OSError) except: NetWorkIOError = (socket.error, ssl.SSLError, OSError) from .gae_handler import send_header, return_fail_message from .front import direct_front from xlog import getLogger xlog = getLogger("gae_proxy") google_server_types = [b"ClientMapServer"] def handler(method, host, path, headers, body, wfile, timeout=60): time_request = time.time() if b"Connection" in headers and headers[b"Connection"] == b"close": del headers[b"Connection"] errors = [] while True: time_left = time_request + timeout - time.time() if time_left <= 0: return_fail_message(wfile) return "ok" try: response = direct_front.request(method, host, path, headers, body, timeout=time_left) if response: if response.status > 600: xlog.warn("direct %s %s % status:%d", method, host, path, response.status) continue elif response.status > 400: server_type = response.headers.get(b'Server', b"") if b"G" not in server_type and b"g" not in server_type and server_type not in google_server_types: xlog.debug("IP:%s host:%s not support GAE, server type:%s status:%d", response.ssl_sock.ip_str, host, server_type, response.status) #direct_front.ip_manager.report_connect_fail(response.ssl_sock.ip_str, force_remove=True) response.worker.close() continue break except OpenSSL.SSL.SysCallError as e: errors.append(e) xlog.warn("direct_handler.handler err:%r %s/%s", e, host, path) except Exception as e: errors.append(e) xlog.exception('direct_handler.handler %r %s %s , retry...', e, host, path) response_headers = {} for key, value in list(response.headers.items()): key = key.title() response_headers[key] = value response_headers[b"Persist"] = b"" response_headers[b"Connection"] = b"Persist" try: wfile.write(b"HTTP/1.1 %d %s\r\n" % (response.status, response.reason)) for key, value in list(response_headers.items()): send_header(wfile, key, value) wfile.write(b"\r\n") length = 0 while True: data = response.task.read() data_len = len(data) length += data_len if b'Transfer-Encoding' in response_headers: if not data_len: wfile.write(b'0\r\n\r\n') break wfile.write(b'%x\r\n' % data_len) wfile.write(data) wfile.write(b'\r\n') else: if not data_len: break wfile.write(data) xlog.info("DIRECT t:%d s:%d %d %s %s", (time.time()-time_request)*1000, length, response.status, host, path) if b'Content-Length' in response_headers or b'Transfer-Encoding' in response_headers: return "ok" except NetWorkIOError as e: xlog.warn('DIRECT %s %s%s except:%r', method, host, path, e) if e.args[0] not in (errno.ECONNABORTED, errno.ETIMEDOUT, errno.EPIPE): raise except Exception as e: xlog.exception("DIRECT %s %d %s%s, t:%d send to client except:%r", method, response.status, host, path, (time.time()-time_request)*1000, e) ================================================ FILE: code/default/gae_proxy/local/download_gae_lib.py ================================================ import os import time import zipfile import shutil import simple_http_client import env_info from xlog import getLogger xlog = getLogger("gae_proxy") current_path = os.path.dirname(os.path.abspath(__file__)) root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir)) top_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir)) data_path = os.path.abspath( os.path.join(env_info.data_path, 'gae_proxy')) def request(url, retry=0, timeout=30): cert = os.path.join(data_path, "CA.crt") client = simple_http_client.Client(proxy={ "type": "http", "host": "127.0.0.1", "port": 8087, "user": None, "pass": None }, timeout=timeout, cert=cert) res = client.request("GET", url, read_payload=False) return res def download_file(url, filename): org_url = url if os.path.isfile(filename): return True for i in range(0, 4): try: xlog.info("download %s to %s, retry:%d", url, filename, i) req = request(url, i, timeout=120) if not req: time.sleep(3) continue if req.status == 302: url = req.headers["Location"] continue start_time = time.time() timeout = 300 if req.chunked: downloaded = 0 with open(filename, 'wb') as fp: while True: time_left = timeout - (time.time() - start_time) if time_left < 0: raise Exception("time out") dat = req.read(timeout=time_left) if not dat: break fp.write(dat) downloaded += len(dat) return True else: file_size = int(req.getheader('Content-Length', 0)) left = file_size downloaded = 0 with open(filename, 'wb') as fp: while True: chunk_len = min(65536, left) if not chunk_len: break chunk = req.read(chunk_len) if not chunk: break fp.write(chunk) downloaded += len(chunk) left -= len(chunk) if downloaded != file_size: xlog.warn("download size:%d, need size:%d, download fail.", downloaded, file_size) os.remove(filename) continue else: xlog.info("download %s to %s success.", org_url, filename) return True except Exception as e: xlog.warn("download %s to %s fail:%r", org_url, filename, e) continue xlog.warn("download %s fail", org_url) def download_unzip(url, extract_path): if os.path.isdir(extract_path): return True data_root = os.path.join(top_path, 'data') download_path = os.path.join(data_root, 'downloads') if not os.path.isdir(download_path): os.mkdir(download_path) fn = url.split("/")[-1] dfn = os.path.join(download_path, fn) if not download_file(url, dfn): xlog.warn("download file %s fail.", url) return try: os.mkdir(extract_path) with zipfile.ZipFile(dfn, "r") as dz: dz.extractall(extract_path) dz.close() xlog.info("Extract %s to %s success.", fn, extract_path) except Exception as e: xlog.warn("unzip %s fail:%r", dfn, e) shutil.rmtree(extract_path) raise e os.remove(dfn) def check_lib_or_download(): lib_path = os.path.abspath(os.path.join(current_path, os.pardir, "server", "lib")) if os.path.isdir(lib_path): return True download_unzip("https://github.com/XX-net/XX-Net/releases/download/3.15.0/lib.zip", lib_path) ================================================ FILE: code/default/gae_proxy/local/front.py ================================================ import os current_path = os.path.dirname(os.path.abspath(__file__)) root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir)) import env_info data_path = env_info.data_path module_data_path = os.path.join(data_path, 'gae_proxy') import xlog logger = xlog.getLogger("gae_proxy", log_path=module_data_path, save_start_log=500, save_warning_log=True) logger.set_buffer(500) from . import check_local_network from .config import config, direct_config from . import host_manager from front_base.openssl_wrap import SSLContext from front_base.connect_creator import ConnectCreator from front_base.ip_manager import IpManager from front_base.ip_source import Ipv4RangeSource, Ipv6PoolSource, IpCombineSource from front_base.http_dispatcher import HttpsDispatcher from front_base.connect_manager import ConnectManager from .check_ip import CheckIp from .appid_manager import AppidManager class Front(object): name = "gae_front" def __init__(self): self.logger = logger self.config = config def start(self): self.running = True ca_certs = os.path.join(current_path, "cacert.pem") self.openssl_context = SSLContext( logger, ca_certs=ca_certs, support_http2=config.support_http2, protocol="TLSv1_2" #cipher_suites=[b'ALL', b"!RC4-SHA", b"!ECDHE-RSA-RC4-SHA", b"!ECDHE-RSA-AES128-GCM-SHA256", # b"!AES128-GCM-SHA256", b"!ECDHE-RSA-AES128-SHA", b"!AES128-SHA"] ) self.appid_manager = AppidManager(self.config, logger) self.host_manager = host_manager.HostManager(self.config, logger) self.host_manager.appid_manager = self.appid_manager self.connect_creator = ConnectCreator( logger, self.config, self.openssl_context, self.host_manager) self.ip_checker = CheckIp(xlog.null, self.config, self.connect_creator) self.ipv4_source = Ipv4RangeSource( logger, self.config, os.path.join(current_path, "ip_range.txt"), os.path.join(module_data_path, "ip_range.txt") ) self.ipv6_source = Ipv6PoolSource( logger, self.config, os.path.join(current_path, "ipv6_list.txt") ) self.ip_source = IpCombineSource( logger, self.config, self.ipv4_source, self.ipv6_source ) self.ip_manager = IpManager( logger, self.config, self.ip_source, self.host_manager, check_local_network, self.check_ip, None, os.path.join(module_data_path, "good_ip.txt"), scan_ip_log=None) self.appid_manager.check_api = self.ip_checker.check_ip self.appid_manager.ip_manager = self.ip_manager self.connect_manager = ConnectManager( logger, self.config, self.connect_creator, self.ip_manager, check_local_network) self.http_dispatcher = HttpsDispatcher( logger, self.config, self.ip_manager, self.connect_manager ) def check_ip(self, ip): sni = self.host_manager.sni_manager.get() host = self.config.check_ip_host return self.ip_checker.check_ip(ip, sni=sni, host=host) def get_dispatcher(self): return self.http_dispatcher def request(self, method, host, path=b"/", headers={}, data="", timeout=120): response = self.http_dispatcher.request(method, host, path, dict(headers), data, timeout=timeout) return response def stop(self): logger.info("terminate") self.connect_manager.set_ssl_created_cb(None) self.http_dispatcher.stop() self.connect_manager.stop() self.ip_manager.stop() self.running = False def set_proxy(self, args): logger.info("set_proxy:%s", args) self.config.PROXY_ENABLE = args["enable"] self.config.PROXY_TYPE = args["type"] self.config.PROXY_HOST = args["host"] self.config.PROXY_PORT = args["port"] self.config.PROXY_USER = args["user"] self.config.PROXY_PASSWD = args["passwd"] self.config.save() self.connect_creator.update_config() front = Front() class DirectFront(object): name = "direct_front" def __init__(self): pass def start(self): self.running = True self.host_manager = host_manager.HostManager(front.config, logger) ca_certs = os.path.join(current_path, "cacert.pem") self.openssl_context = SSLContext( logger, ca_certs=ca_certs, support_http2=False, protocol="TLSv1_2" #cipher_suites=[b'ALL', b"!RC4-SHA", b"!ECDHE-RSA-RC4-SHA", b"!ECDHE-RSA-AES128-GCM-SHA256", # b"!AES128-GCM-SHA256", b"!ECDHE-RSA-AES128-SHA", b"!AES128-SHA"] ) self.connect_creator = ConnectCreator( logger, front.config, self.openssl_context, self.host_manager) self.ip_manager = front.ip_manager self.connect_manager = ConnectManager( logger, front.config, self.connect_creator, self.ip_manager, check_local_network) self.dispatchs = {} def get_dispatcher(self, host): if host not in self.dispatchs: http_dispatcher = HttpsDispatcher( logger, direct_config, front.ip_manager, self.connect_manager) self.dispatchs[host] = http_dispatcher return self.dispatchs[host] def request(self, method, host, path="/", headers={}, data="", timeout=60): dispatcher = self.get_dispatcher(host) response = dispatcher.request(method, host, path, dict(headers), data, timeout=timeout) return response def stop(self): logger.info("terminate") self.connect_manager.set_ssl_created_cb(None) for host in self.dispatchs: dispatcher = self.dispatchs[host] dispatcher.stop() self.connect_manager.stop() self.running = False def set_proxy(self, args): self.connect_creator.update_config() direct_front = DirectFront() ================================================ FILE: code/default/gae_proxy/local/gae_handler.py ================================================ #!/usr/bin/env python # coding:utf-8 """ GoAgent local-server protocol 3.2 request: POST /_gh/ HTTP/1.1 HOST: appid.appspot.com content-length: xxx http content: 此为body { pack_req_head_len: 2 bytes,#POST 时使用 pack_req_head : deflate{ 此为负载 original request line, original request headers, X-URLFETCH-kwargs HEADS, { password, maxsize, defined in config AUTO RANGE MAX SIZE timeout, request timeout for GAE urlfetch. } } body } response: 200 OK http-Heads: Content-type: image/gif headers from real_server # real_server 为gae让客户端以为的服务器 #可能被gae改变,但对客户端不可见 #未分片body也直接发给客户端 # body 分为下面两部分 http-content:{ response_head{ data_len: 2 bytes, data: deflate{ HTTP/1.1 status, status_code headers content = error_message, if GAE server fail } } body } """ import errno import sys import time import xstruct as struct import re import string import ssl import threading import zlib import traceback from mimetypes import guess_type try: from urllib.parse import urlparse, urljoin, urljoin except ImportError: from urlparse import urlparse, urljoin, urljoin from xx_six import ConnectionError, ConnectionResetError, BrokenPipeError, ConnectionAbortedError from . import check_local_network from .front import front import utils from xlog import getLogger xlog = getLogger("gae_proxy") def inflate(data): return zlib.decompress(data, -zlib.MAX_WBITS) def deflate(data): return zlib.compress(data)[2:-4] class GAE_Exception(Exception): def __init__(self, error_code, message): xlog.debug("GAE_Exception %r %r", error_code, message) self.error_code = error_code self.message = "%r:%s" % (error_code, message) def __str__(self): # for %s return repr(self.message) def __repr__(self): # for %r return repr(self.message) def generate_message_html(title, banner, detail=''): MESSAGE_TEMPLATE = ''' $title
Message

$banner

$detail

''' return string.Template(MESSAGE_TEMPLATE).substitute( title=title, banner=banner, detail=detail) def spawn_later(seconds, target, *args, **kwargs): def wrap(*args, **kwargs): __import__('time').sleep(seconds) try: result = target(*args, **kwargs) except BaseException: result = None return result return __import__('thread').start_new_thread(wrap, args, kwargs) skip_request_headers = frozenset([ b'Vary', b'Via', b'Proxy-Authorization', b'Proxy-Connection', b'Upgrade', b'X-Google-Cache-Control', b'X-Forwarded-For', b'X-Chrome-Variations', ]) skip_response_headers = frozenset([ # http://en.wikipedia.org/wiki/Chunked_transfer_encoding b'Connection', b'Upgrade', b'Alt-Svc', b'Alternate-Protocol', b'X-Head-Content-Length', b'X-Google-Cache-Control', b'X-Chrome-Variations', ]) def send_header(wfile, keyword, value): keyword = keyword.title() if keyword == b'Set-Cookie': # https://cloud.google.com/appengine/docs/python/urlfetch/responseobjects for cookie in re.split(br', (?=[^ =]+(?:=|$))', value): wfile.write(b"%s: %s\r\n" % (keyword, cookie)) #xlog.debug("Head1 %s: %s", keyword, cookie) elif keyword == b'Content-Disposition' and b'"' not in value: value = re.sub(br'filename=([^"\']+)', b'filename="\\1"', value) wfile.write(b"%s: %s\r\n" % (keyword, value)) #xlog.debug("Head1 %s: %s", keyword, value) elif keyword in skip_response_headers: return else: if isinstance(value, int): wfile.write(b"%s: %d\r\n" % (keyword, value)) else: wfile.write(b"%s: %s\r\n" % (keyword, value)) #xlog.debug("Head1 %s: %s", keyword, value) def send_response(wfile, status=404, headers={}, body=b''): body = utils.to_bytes(body) headers = dict((k.title(), v) for k, v in list(headers.items())) if b'Transfer-Encoding' in headers: del headers[b'Transfer-Encoding'] if b'Content-Length' not in headers: headers[b'Content-Length'] = len(body) if b'Connection' not in headers: headers[b'Connection'] = b'close' try: wfile.write(b"HTTP/1.1 %d\r\n" % status) for key, value in list(headers.items()): send_header(wfile, key, value) wfile.write(b"\r\n") wfile.write(body) except ssl.SSLError as e: xlog.warn("gae send response fail. %r", e) return except Exception as e: if sys.version_info[0] == 3 and ( isinstance(e, ConnectionError) or isinstance(e, ConnectionResetError) or isinstance(e, BrokenPipeError) ): xlog.warn("gae send response fail. %r", e) else: xlog.exception("send response fail %r", e) def return_fail_message(wfile): html = generate_message_html( '504 GAEProxy Proxy Time out', '连接超时,先休息一会再来!') send_response(wfile, 504, body=utils.to_bytes(html)) return def pack_request(method, url, headers, body, timeout): headers = dict(headers) if isinstance(body, bytes) and body: if len(body) < 10 * 1024 * 1024 and b'Content-Encoding' not in headers: # 可以压缩 zbody = deflate(body) if len(zbody) < len(body): body = zbody headers[b'Content-Encoding'] = b'deflate' if len(body) > 10 * 1024 * 1024: xlog.warn("body len:%d %s %s", len(body), method, url) headers[b'Content-Length'] = utils.to_bytes(str(len(body))) # GAE don't allow set `Host` header if b'Host' in headers: del headers[b'Host'] kwargs = {} # gae 用的参数 if front.config.GAE_PASSWORD: kwargs[b'password'] = front.config.GAE_PASSWORD # kwargs['options'] = kwargs[b'validate'] = front.config.GAE_VALIDATE if url.endswith(b".js"): kwargs[b'maxsize'] = front.config.JS_MAXSIZE else: kwargs[b'maxsize'] = front.config.AUTORANGE_MAXSIZE kwargs[b'timeout'] = str(timeout) # gae 用的参数 end payload = b'%s %s HTTP/1.1\r\n' % (method, url) payload += b''.join(b'%s: %s\r\n' % (k, v) for k, v in list(headers.items()) if k not in skip_request_headers) # for k, v in headers.items(): # xlog.debug("Send %s: %s", k, v) for k, v in kwargs.items(): if isinstance(v, int): payload += b'X-URLFETCH-%s: %d\r\n' % (k, v) else: payload += b'X-URLFETCH-%s: %s\r\n' % (k, utils.to_bytes(v)) payload = deflate(payload) body = b'%s%s%s' % (struct.pack('!h', len(payload)), payload, body) request_headers = {} request_headers[b'Content-Length'] = str(len(body)) # request_headers 只有上面一项 return request_headers, body def unpack_response(response): try: data = response.task.read(size=2) if not data: raise GAE_Exception(600, "get protocol head fail") if len(data) !=2: raise GAE_Exception(600, "get protocol head fail, data:%s, len:%d" % (data, len(data))) headers_length, = struct.unpack('!h', data) data = response.task.read(size=headers_length) if not data: raise GAE_Exception(600, "get protocol head fail, len:%d" % headers_length) raw_response_line, headers_data = inflate(data).split(b'\r\n', 1) rl = raw_response_line.split() response.app_status = int(rl[1]) if len(rl) >=3: response.app_reason = rl[2].strip() headers_block, app_msg = headers_data.split(b'\r\n\r\n') headers_pairs = headers_block.split(b'\r\n') response.headers = {} for pair in headers_pairs: if not pair: break k, v = pair.split(b': ', 1) response.headers[k] = v response.app_msg = app_msg return response except Exception as e: response.worker.close("unpack protocol error") raise GAE_Exception(600, "unpack protocol:%r at:%s" % (e, traceback.format_exc())) def request_gae_server(headers, body, url, timeout): # process on http protocol # process status code return by http server # raise error, let up layer retry. try: response = front.request(b"POST", b"", b"/_gh/", headers, body, timeout) if not response: raise GAE_Exception(600, "fetch gae fail") if response.status >= 600: raise GAE_Exception( response.status, "fetch gae fail:%d" % response.status) appid = response.ssl_sock.host.split(".")[0] if response.status == 404: # xlog.warning('APPID %r not exists, remove it.', response.ssl_sock.appid) front.appid_manager.report_not_exist( appid, response.ssl_sock.ip_str) # google_ip.report_connect_closed(response.ssl_sock.ip_str, "appid not exist") response.worker.close("appid not exist:%s" % appid) raise GAE_Exception(603, "appid not exist %s" % appid) if response.status == 503: xlog.warning('APPID %r out of Quota, remove it. %s', appid, response.ssl_sock.ip_str) front.appid_manager.report_out_of_quota(appid) # google_ip.report_connect_closed(response.ssl_sock.ip_str, "out of quota") response.worker.close("appid out of quota:%s" % appid) raise GAE_Exception(604, "appid out of quota:%s" % appid) server_type = response.getheader(b"Server", b"") if (b"gws" not in server_type and b"Google Frontend" not in server_type and b"GFE" not in server_type) or \ response.status == 403 or response.status == 405: # some ip can connect, and server type can be gws # but can't use as GAE server # so we need remove it immediately xlog.warn("IP:%s not support GAE, headers:%s status:%d", response.ssl_sock.ip_str, response.headers, response.status) response.worker.close("ip not support GAE") raise GAE_Exception(602, "ip not support GAE") response.gps = response.getheader(b"x-server", b"") if response.status > 300: raise GAE_Exception(605, "status:%d" % response.status) if response.status != 200: xlog.warn("GAE %s appid:%s status:%d", response.ssl_sock.ip_str, appid, response.status) return response except GAE_Exception as e: if e.error_code not in (600, 603, 604) and hasattr(response, "ssl_sock"): front.ip_manager.recheck_ip(response.ssl_sock.ip_str, first_report=False) raise e def request_gae_proxy(method, url, headers, body, timeout=None): headers = dict(headers) # make retry and time out time_request = time.time() # GAE urlfetch will not decode br if Accept-Encoding include gzip accept_encoding = headers.get(b"Accept-Encoding", b"") if b"br" in accept_encoding: accept_br_encoding = True # xlog.debug("accept_br_encoding for %s", url) else: accept_br_encoding = False host = headers.get(b"Host", b"") if not host: parsed_url = urlparse(url) host = parsed_url.hostname accept_codes = accept_encoding.replace(b" ", b"").split(b",") try: accept_codes.remove(b"") except: pass if not accept_br_encoding: if b"gzip" in accept_encoding: if host in front.config.br_sites or host.endswith(front.config.br_endswith): accept_codes.remove(b"gzip") if b"br" not in accept_codes: accept_codes.append(b"br") accept_code_str = b",".join(accept_codes) if accept_code_str: headers[b"Accept-Encoding"] = accept_code_str else: del headers[b"Accept-Encoding"] error_msg = [] if not timeout: timeouts = [15, 20, 30] else: timeouts = [timeout] if body: timeouts = [timeout + 10 for timeout in timeouts] for timeout in timeouts: request_headers, request_body = pack_request(method, url, headers, body, timeout) try: response = request_gae_server(request_headers, request_body, url, timeout) response = unpack_response(response) # xlog.debug("accept:%s content-encoding:%s url:%s", accept_encoding, # response.headers.get("Content-Encoding", ""), url) if not accept_br_encoding: # if gzip in Accept-Encoding, br will not decode in urlfetch # else, urlfetch in GAE will auto decode br, but return br in Content-Encoding if response.headers.get(b"Content-Encoding", b"") == b"br": # GAE urlfetch always return br in content-encoding even have decoded it. del response.headers[b"Content-Encoding"] # xlog.debug("remove br from Content-Encoding, %s", url) if host not in front.config.br_sites: front.config.BR_SITES.append(host) front.config.save() front.config.load() xlog.warn("Add %s to br_sites", host) if response.app_msg: xlog.warn("server app return fail, status:%d", response.app_status) # if len(response.app_msg) < 2048: # xlog.warn('app_msg:%s', cgi.escape(response.app_msg)) if response.app_status == 510: # reach 80% of traffic today # disable for get big file. appid = response.ssl_sock.host.split(".")[0] front.appid_manager.report_out_of_quota(appid) response.worker.close( "appid out of quota:%s" % appid) continue return response except GAE_Exception as e: err_msg = "gae_exception:%r %s" % (e, url) error_msg.append(err_msg) xlog.warn("gae_exception:%r %s", e, url) if e.message == '605:status:500': raise e except Exception as e: err_msg = 'gae_handler.handler %r %s , retry...' % (e, url) error_msg.append(err_msg) xlog.exception('gae_handler.handler %r %s , retry...', e, url) raise GAE_Exception(600, "".join(error_msg)) def handler(method, host, url, headers, body, wfile, fallback=None): if not url.startswith(b"http") and not url.startswith(b"HTTP"): xlog.error("gae:%s", url) return request_time = time.time() org_headers = dict(headers) remove_list = [] req_range_begin = b"" req_range_end = b"" req_range = b"" for k, v in list(headers.items()): if v == "": remove_list.append(k) continue if k.lower() == b"range": req_range = v req_range_begin, req_range_end = tuple( x for x in re.search(br'bytes=(\d*)-(\d*)', v).group(1, 2)) # fix bug for android market app: Mobogenie # GAE url_fetch refuse empty value in header. for key in remove_list: del headers[key] # force to get content range # reduce wait time if method == b"GET": if req_range_begin and not req_range_end: # don't known how many bytes to get, but get from begin position req_range_begin = int(req_range_begin) headers[b"Range"] = b"bytes=%d-%d" % ( req_range_begin, req_range_begin + front.config.AUTORANGE_MAXSIZE - 1) xlog.debug("change Range %s => %s %s", req_range, headers[b"Range"], url) elif req_range_begin and req_range_end: req_range_begin = int(req_range_begin) req_range_end = int(req_range_end) if req_range_end - req_range_begin + 1 > front.config.AUTORANGE_MAXSIZE: headers[b"Range"] = b"bytes=%d-%d" % ( req_range_begin, req_range_begin + front.config.AUTORANGE_MAXSIZE - 1) # remove wait time for GAE server to get knowledge that content # size exceed the max size per fetch xlog.debug("change Range %s => %s %s", req_range, headers[b"Range"], url) elif not req_range_begin and req_range_end: # get the last n bytes of content pass else: # no begin and no end # don't add range, some host like github don't support Range. # headers["Range"] = "bytes=0-%d" % config.AUTORANGE_MAXSIZE pass try: response = request_gae_proxy(method, url, headers, body) # http://en.wikipedia.org/wiki/Chunked_transfer_encoding response.headers.pop(b"Transfer-Encoding", None) # gae代理请求 except GAE_Exception as e: xlog.warn("GAE %s %s request fail:%r", method, url, e) if fallback and host.endswith(front.config.GOOGLE_ENDSWITH): return fallback() send_response(wfile, e.error_code, body=e.message) return_fail_message(wfile) return "ok" except Exception as e: xlog.exception("request_gae except:%r", e) send_response(wfile, 502, body=e.args[1]) # 502 means Gateway error. return_fail_message(wfile) return "ok" if response.app_msg: # XX-net 自己数据包 send_response(wfile, response.app_status, body=response.app_msg) return "ok" else: response.status = response.app_status if response.status == 206: # use org_headers # RangeFetch need to known the real range end # 需要分片 return RangeFetch2(method, url, org_headers, body, response, wfile).run() response_headers = {} # 初始化给客户端的headers for key, value in list(response.headers.items()): key = key.title() if key in skip_response_headers: continue response_headers[key] = value response_headers[b"Persist"] = b"" response_headers[b"Connection"] = b"Persist" if b'X-Head-Content-Length' in response_headers: if method == b"HEAD": response_headers[b'Content-Length'] = response_headers[b'X-Head-Content-Length'] del response_headers[b'X-Head-Content-Length'] # 只是获取头 content_length = int(response.headers.get(b'Content-Length', 0)) content_range = response.headers.get(b'Content-Range', '') # content_range 分片时合并用到 if content_range and b'bytes */' not in content_range: start, end, length = tuple(int(x) for x in re.search( br'bytes (\d+)-(\d+)/(\d+)', content_range).group(1, 2, 3)) else: start, end, length = 0, content_length - 1, content_length # 未分片 if method == b"HEAD": body_length = 0 else: body_length = end - start + 1 def send_response_headers(): wfile.write(b"HTTP/1.1 %d %s\r\n" % (response.status, utils.to_bytes(response.reason))) for key, value in list(response_headers.items()): send_header(wfile, key, value) # xlog.debug("Head- %s: %s", key, value) wfile.write(b"\r\n") # 写入除body外内容 def is_text_content_type(content_type): content_type = utils.to_bytes(content_type) mct, _, sct = content_type.partition(b'/') if mct == b'text': return True if mct == b'application': sct = sct.split(b';', 1)[0] if (sct in (b'json', b'javascript', b'x-www-form-urlencoded') or sct.endswith((b'xml', b'script')) or sct.startswith((b'xml', b'rss', b'atom'))): return True return False data0 = b"" content_type = response_headers.get(b"Content-Type", b"") content_encoding = response_headers.get(b"Content-Encoding", b"") if body_length and \ content_encoding == b"gzip" and \ response.gps < b"GPS 3.3.2" and \ is_text_content_type(content_type): url_guess_type = guess_type(utils.to_str(url))[0] if url_guess_type is None or is_text_content_type(url_guess_type): # try decode and detect type min_block = min(1024, body_length) data0 = response.task.read(min_block) if not data0 or len(data0) == 0: xlog.warn("recv body fail:%s", url) return gzip_decompressor = zlib.decompressobj(16 + zlib.MAX_WBITS) decoded_data0 = gzip_decompressor.decompress(data0) deflate_decompressor = zlib.decompressobj(-zlib.MAX_WBITS) decoded_data1 = None if len(decoded_data0) > 1: CMF, FLG = bytearray(decoded_data0[:2]) if CMF & 0x0F == 8 and CMF & 0x80 == 0 and ((CMF << 8) + FLG) % 31 == 0: decoded_data1 = deflate_decompressor.decompress(decoded_data0[2:]) if decoded_data1 is None and len(decoded_data0) > 0: try: decoded_data1 = deflate_decompressor.decompress(decoded_data0) if deflate_decompressor.unused_data != '': decoded_data1 = None except: pass if decoded_data1: try: response_headers.pop(b"Content-Length", None) if b"deflate" in headers.get(b"Accept-Encoding", b""): # return deflate data if accept deflate response_headers[b"Content-Encoding"] = b"deflate" send_response_headers() while True: wfile.write(decoded_data0) if response.task.body_readed >= body_length: break data = response.task.read() decoded_data0 = gzip_decompressor.decompress(data) xlog.info("GAE send ungziped deflate data to browser t:%d s:%d %s %s %s", (time.time() - request_time) * 1000, content_length, method, url, response.task.get_trace()) else: # inflate data and send del response_headers[b"Content-Encoding"] send_response_headers() while True: wfile.write(decoded_data1) if response.task.body_readed >= body_length: break data = response.task.read() decoded_data0 = gzip_decompressor.decompress(data) decoded_data1 = deflate_decompressor.decompress(decoded_data0) xlog.info("GAE send ungziped data to browser t:%d s:%d %s %s %s", (time.time() - request_time) * 1000, content_length, method, url, response.task.get_trace()) return except Exception as e: xlog.exception("gae_handler.handler try decode and send response fail. e:%r %s", e, url) return try: send_response_headers() if data0: wfile.write(data0) body_sended = len(data0) else: body_sended = 0 except Exception as e: if sys.version_info[0] == 3 and \ (isinstance(e, BrokenPipeError) or isinstance(e, ConnectionAbortedError) or isinstance(e, ssl.SSLEOFError)): return xlog.exception("gae_handler.handler send response fail. e:%r %s", e, url) return while True: # 可能分片发给客户端 if body_sended >= body_length: break data = response.task.read() if not data: xlog.warn("get body fail, until:%d %s", body_length - body_sended, url) break body_sended += len(data) try: # https 包装 ret = wfile.write(data) if ret == ssl.SSL_ERROR_WANT_WRITE or ret == ssl.SSL_ERROR_WANT_READ: #xlog.debug("send to browser wfile.write ret:%d", ret) #ret = wfile.write(data) wfile.write(data) except Exception as e_b: if sys.version_info[0] == 3 and \ (isinstance(e_b, BrokenPipeError) or isinstance(e_b, ConnectionAbortedError)): return if e_b.args[0] in (errno.ECONNABORTED, errno.EPIPE, errno.ECONNRESET) or 'bad write retry' in repr(e_b): xlog.info('gae_handler send to browser return %r %r, len:%d, sended:%d', e_b, url, body_length, body_sended) else: xlog.info('gae_handler send to browser return %r %r', e_b, url) return # 完整一次https请求 appid = response.ssl_sock.host.split(".")[0] xlog.info("GAE t:%d s:%d %s %s %s appid:%s", (time.time() - request_time) * 1000, content_length, method, url, response.task.get_trace(), appid) return "ok" class RangeFetch2(object): all_data_size = {} def __init__(self, method, url, headers, body, response, wfile): self.method = method self.wfile = wfile self.url = url self.headers = headers self.body = body self.response = response self.keep_running = True self.blocked = False self.lock = threading.Lock() self.waiter = threading.Condition(self.lock) self.data_list = {} # begin => payload self.data_size = 0 self.req_begin = 0 self.req_end = 0 self.wait_begin = 0 def get_all_buffer_size(self): return sum(v for k, v in list(self.all_data_size.items())) def put_data(self, range_begin, payload): with self.lock: if range_begin < self.wait_begin: raise Exception("range_begin:%d expect:%d" % (range_begin, self.wait_begin)) self.data_list[range_begin] = payload self.data_size += len(payload) self.all_data_size[self] = self.data_size if self.wait_begin in self.data_list: self.waiter.notify() def run(self): req_range_begin = None req_range_end = None for k, v in list(self.headers.items()): # xlog.debug("range req head:%s => %s", k, v) if k.lower() == b"range": req_range_begin, req_range_end = tuple( x for x in re.search(br'bytes=(\d*)-(\d*)', v).group(1, 2)) # break response_headers = dict((k.title(), v) for k, v in list(self.response.headers.items())) content_range = response_headers[b'Content-Range'] res_begin, res_end, res_length = tuple(int(x) for x in re.search( br'bytes (\d+)-(\d+)/(\d+)', content_range).group(1, 2, 3)) self.req_begin = res_end + 1 if req_range_begin and req_range_end: self.req_end = int(req_range_end) else: self.req_end = res_length - 1 self.wait_begin = res_begin if self.wait_begin == 0 and self.req_end == res_length - 1: response_headers[b'Content-Length'] = bytes(str(res_length), encoding='ascii') del response_headers[b'Content-Range'] state_code = 200 else: response_headers[b'Content-Range'] = b'bytes %d-%d/%d' % ( res_begin, self.req_end, res_length) response_headers[b'Content-Length'] = bytes(str( self.req_end - res_begin + 1), encoding='ascii') state_code = 206 response_headers[b"Persist"] = b"" response_headers[b"Connection"] = b"Persist" xlog.info('RangeFetch %d-%d started(%r) ', res_begin, self.req_end, self.url) try: self.wfile.write(b"HTTP/1.1 %d OK\r\n" % state_code) for key in response_headers: if key in skip_response_headers: continue value = response_headers[key] #xlog.debug("Head %s: %s", key.title(), value) send_header(self.wfile, key, value) self.wfile.write(b"\r\n") except Exception as e: self.keep_running = False if sys.version_info[0] == 3 and \ (isinstance(e, BrokenPipeError) or isinstance(e, ConnectionAbortedError) or isinstance(e, ssl.SSLEOFError) ): xlog.warn("RangeFetch send response fail:%r %s", e, self.url) return else: xlog.exception("RangeFetch send response fail:%r %s", e, self.url) return data_left_to_fetch = self.req_end - self.req_begin + 1 fetch_times = int( (data_left_to_fetch + front.config.AUTORANGE_MAXSIZE - 1) / front.config.AUTORANGE_MAXSIZE) thread_num = min(front.config.AUTORANGE_THREADS, fetch_times) for i in range(0, thread_num): threading.Thread(target=self.fetch_worker, name="gae_fetch_work").start() threading.Thread(target=self.fetch, args=( res_begin, res_end, self.response), name="gae_fetch").start() ok = "ok" while self.keep_running and \ (front.config.use_ipv6 == "force_ipv6" and check_local_network.IPv6.is_ok() or front.config.use_ipv6 != "force_ipv6" and check_local_network.is_ok()) and \ self.wait_begin < self.req_end + 1: with self.lock: if self.wait_begin not in self.data_list: self.waiter.wait() if self.wait_begin not in self.data_list: xlog.error("get notify but no data") continue else: data = self.data_list[self.wait_begin] del self.data_list[self.wait_begin] self.wait_begin += len(data) self.data_size -= len(data) self.all_data_size[self] = self.data_size try: ret = self.wfile.write(data) if ret == ssl.SSL_ERROR_WANT_WRITE or ret == ssl.SSL_ERROR_WANT_READ: xlog.debug( "send to browser wfile.write ret:%d, retry", ret) ret = self.wfile.write(data) xlog.debug("send to browser wfile.write ret:%d", ret) del data except Exception as e: xlog.info('RangeFetch client closed(%s). %s', e, self.url) ok = None break self.keep_running = False self.all_data_size.pop(self, None) return ok def fetch_worker(self): blocked = False while self.keep_running: if blocked: time.sleep(0.5) with self.lock: # at least 2 wait workers keep running if self.req_begin > self.wait_begin + front.config.AUTORANGE_MAXSIZE: if self.get_all_buffer_size() > front.config.AUTORANGE_MAXBUFFERSIZE * (0.8 + len(self.all_data_size) * 0.2): if not self.blocked: xlog.debug("fetch_worker blocked, buffer:%d %s", self.data_size, self.url) self.blocked = blocked = True continue self.blocked = blocked = False if self.req_begin >= self.req_end + 1: break begin = self.req_begin end = min(begin + front.config.AUTORANGE_MAXSIZE - 1, self.req_end) self.req_begin = end + 1 self.fetch(begin, end, None) def fetch(self, begin, end, first_response): headers = dict((k.title(), v) for k, v in list(self.headers.items())) retry_num = 0 while self.keep_running: retry_num += 1 if retry_num > 20: xlog.warn("RangeFetch try max times, exit. %s", self.url) self.close() break expect_len = end - begin + 1 headers[b'Range'] = b'bytes=%d-%d' % (begin, end) if first_response: response = first_response else: try: response = request_gae_proxy( self.method, self.url, headers, self.body) except GAE_Exception as e: xlog.warning('RangeFetch %s request fail:%r', headers[b'Range'], e) continue if response.app_msg: response.worker.close( "range get gae status:%d" % response.app_status) continue response.status = response.app_status if response.headers.get(b'Location', None): self.url = urljoin( self.url, response.headers.get(b'Location')) xlog.warn('RangeFetch Redirect(%r) status:%s', self.url, response.status) continue if response.status >= 300: #xlog.error('RangeFetch %r return %s :%s', self.url, response.status, cgi.escape(response.body)) response.worker.close("range status:%s" % response.status) continue content_range = response.headers.get(b'Content-Range', b"") if not content_range: xlog.warning('RangeFetch "%s %s" return headers=%r, retry %s-%s', self.method, self.url, response.headers, begin, end) # if len(response.body) < 2048: #xlog.warn('body:%s', cgi.escape(response.body)) # response.worker.close("no range") continue content_length = int(response.headers.get(b'Content-Length', 0)) data_readed = 0 while True: if data_readed >= content_length: percent = begin * 100 / self.req_end xlog.debug('RangeFetch [%s] %d%% length:%s range:%s %s %s', response.ssl_sock.ip_str, percent, content_length, content_range, self.url, response.task.get_trace()) break data = response.task.read() if not data: xlog.warn("RangeFetch [%s] get body fail, begin:%d %s", response.ssl_sock.ip_str, begin, self.url) break data_len = len(data) data_readed += data_len if data_len > expect_len: xlog.warn("RangeFetch expect:%d, get:%d", expect_len, data_len) data = data[:expect_len] data_len = expect_len self.put_data(begin, data) expect_len -= data_len begin += data_len if begin >= end + 1: break xlog.warn("RangeFetch get left, begin:%d end:%d", begin, end) def close(self): self.keep_running = False with self.lock: self.waiter.notify() ================================================ FILE: code/default/gae_proxy/local/host_manager.py ================================================ import time from front_base.connect_manager import NoRescourceException from front_base.host_manager import HostManagerBase from . sni_manager import SniManager class HostManager(HostManagerBase): def __init__(self, config, logger): self.config = config self.logger = logger self.appid_manager = None self.sni_manager = SniManager(logger) def get_host(self): if not self.appid_manager: return "" appid = self.appid_manager.get() if not appid: self.logger.warn("no appid") time.sleep(10) raise NoRescourceException("no appid") return appid + ".appspot.com" def get_sni_host(self, ip): sni = self.sni_manager.get() host = self.get_host() return sni, host ================================================ FILE: code/default/gae_proxy/local/http2_connection.py ================================================ from front_base.http2_connection import Http2Worker class GaeHttp2Worker(Http2Worker): def __init__(self, logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb, log_debug_data, stream_class=None): super(GaeHttp2Worker, self).__init__(logger, ip_manager, config, ssl_sock, close_cb, retry_task_cb, idle_cb, log_debug_data) def get_host(self, task_host): return self.ssl_sock.host ================================================ FILE: code/default/gae_proxy/local/ip_list.txt ================================================ ================================================ FILE: code/default/gae_proxy/local/ip_range.old ================================================ 1.9.22.0-1.9.22.255 1.9.24.0-1.9.24.255 1.9.57.0-1.9.57.255 1.9.91.0-1.9.91.255 1.9.131.0-1.9.131.255 1.54.236.0-1.54.236.255 1.255.22.0-1.255.22.255 1.255.33.0-1.255.33.255 2.78.40.0-2.78.41.255 2.78.44.0-2.78.45.255 2.78.47.0-2.78.47.255 2.127.237.0-2.127.237.255 2.127.251.0-2.127.251.255 4.31.38.0-4.31.38.255 4.31.115.0-4.31.115.255 4.31.144.0-4.31.144.255 4.34.16.0-4.34.16.255 4.35.2.0-4.35.2.255 4.35.21.0-4.35.21.255 4.35.108.0-4.35.108.255 4.35.153.0-4.35.153.255 4.53.36.0-4.53.36.255 4.53.56.0-4.53.56.255 4.53.79.0-4.53.79.255 4.53.166.0-4.53.166.255 4.53.202.0-4.53.202.255 4.59.40.0-4.59.40.255 4.59.67.0-4.59.67.255 4.59.90.0-4.59.90.255 4.59.126.0-4.59.126.255 5.10.226.0-5.10.226.255 5.17.192.0-5.17.192.255 5.20.5.0-5.20.5.255 5.21.229.0-5.21.230.255 5.22.190.0-5.22.190.255 5.44.5.0-5.44.5.255 5.44.32.0-5.44.32.255 5.44.36.0-5.44.36.255 5.62.128.0-5.62.129.255 5.63.167.0-5.63.167.255 5.102.167.0-5.102.167.255 5.102.252.0-5.102.252.255 5.149.101.0-5.149.103.255 5.157.98.0-5.157.98.255 5.158.127.0-5.158.127.255 5.191.12.0-5.191.12.255 5.226.127.0-5.226.127.255 8.8.4.0-8.8.4.255 8.8.8.0-8.8.8.255 8.35.80.0-8.35.80.255 14.1.102.0-14.1.102.255 14.102.170.0-14.102.170.255 14.192.150.0-14.192.150.255 23.28.251.0-23.28.251.255 23.228.129.0-23.228.130.255 23.235.0.0-23.235.0.255 23.236.5.0-23.236.5.255 23.255.240.0-23.255.242.255 23.255.245.0-23.255.245.255 24.35.3.0-24.35.3.255 24.35.137.0-24.35.137.255 24.41.214.0-24.41.214.255 24.51.113.0-24.51.113.255 24.53.238.0-24.53.238.255 24.56.144.0-24.56.144.255 24.96.139.0-24.96.139.255 24.100.187.0-24.100.187.255 24.116.134.0-24.116.134.255 24.124.1.0-24.124.1.255 24.137.105.0-24.137.105.255 24.140.3.0-24.140.3.255 24.149.5.0-24.149.5.255 24.154.57.0-24.154.57.255 24.155.92.0-24.155.92.255 24.156.131.0-24.156.131.255 24.207.9.0-24.207.9.255 24.214.95.0-24.214.95.255 24.220.112.0-24.220.112.255 24.225.16.0-24.225.16.255 24.226.15.0-24.226.16.255 24.244.4.0-24.244.4.255 24.244.14.0-24.244.14.255 24.244.19.0-24.244.19.255 24.244.39.0-24.244.39.255 24.246.130.0-24.246.130.255 27.2.194.0-27.2.194.255 27.2.226.0-27.2.226.255 27.80.250.0-27.80.250.255 27.85.180.0-27.85.181.255 27.90.140.0-27.90.143.255 27.90.189.0-27.90.189.255 27.100.64.0-27.100.64.255 27.106.94.0-27.106.94.255 27.116.252.0-27.116.252.255 27.121.46.0-27.121.46.255 27.121.51.0-27.121.51.255 27.121.54.0-27.121.54.255 27.123.17.0-27.123.17.255 27.123.130.0-27.123.130.255 27.131.16.0-27.131.16.255 31.7.161.0-31.7.161.255 31.24.56.0-31.24.56.255 31.25.141.0-31.25.141.255 31.31.48.0-31.31.48.255 31.46.22.0-31.46.22.255 31.47.193.0-31.47.193.255 31.55.162.0-31.55.163.255 31.55.166.0-31.55.167.255 31.129.192.0-31.129.192.255 31.132.191.0-31.132.191.255 31.132.224.0-31.132.224.255 31.172.32.0-31.172.32.255 31.173.129.0-31.173.129.255 31.173.164.0-31.173.164.255 31.173.166.0-31.173.166.255 31.173.227.0-31.173.227.255 31.186.176.0-31.186.176.255 31.209.137.0-31.209.137.255 31.210.208.0-31.210.208.255 31.211.30.0-31.211.30.255 31.211.248.0-31.211.248.255 36.37.218.0-36.37.218.255 37.8.144.0-37.8.144.255 37.18.13.0-37.18.13.255 37.18.153.0-37.18.153.255 37.26.145.0-37.26.145.255 37.29.1.0-37.29.1.255 37.29.18.0-37.29.18.255 37.44.42.0-37.44.42.255 37.58.167.0-37.58.167.255 37.60.16.0-37.60.17.255 37.75.192.0-37.75.192.255 37.77.53.0-37.77.53.255 37.98.229.0-37.98.229.255 37.98.242.0-37.98.242.255 37.99.5.0-37.99.5.255 37.99.77.0-37.99.77.255 37.139.254.0-37.139.254.255 37.151.45.0-37.151.45.255 37.152.2.0-37.152.2.255 37.236.115.0-37.236.115.255 37.236.167.0-37.236.167.255 37.236.223.0-37.236.223.255 37.237.119.0-37.237.119.255 37.238.127.0-37.238.127.255 37.238.239.0-37.238.239.255 37.238.247.0-37.238.247.255 37.238.252.0-37.238.252.255 37.239.119.0-37.239.119.255 37.239.240.0-37.239.246.255 37.239.252.0-37.239.254.255 40.129.40.0-40.129.40.255 40.130.0.0-40.130.0.255 40.133.6.0-40.133.6.255 40.135.136.0-40.135.136.255 40.136.3.0-40.136.3.255 40.136.10.0-40.136.10.255 40.136.59.0-40.136.59.255 40.137.34.0-40.137.34.255 40.137.237.0-40.137.237.255 40.138.0.0-40.138.0.255 41.21.236.0-41.21.236.255 41.74.24.0-41.74.24.255 41.77.223.0-41.77.223.255 41.84.195.0-41.84.195.255 41.91.252.0-41.91.254.255 41.128.200.0-41.128.200.255 41.128.203.0-41.128.203.255 41.160.35.0-41.160.35.255 41.184.60.0-41.184.60.255 41.187.111.0-41.187.111.255 41.189.63.0-41.189.63.255 41.189.230.0-41.189.230.255 41.191.219.0-41.191.219.255 41.201.128.0-41.201.129.255 41.201.164.0-41.201.164.255 41.205.32.0-41.205.32.255 41.206.47.0-41.206.47.255 41.206.96.0-41.206.96.255 41.216.127.0-41.216.127.255 41.219.127.0-41.219.127.255 41.220.75.0-41.220.75.255 41.221.166.0-41.221.166.255 41.221.196.0-41.221.196.255 41.223.219.0-41.223.219.255 42.104.120.0-42.104.120.255 42.106.160.0-42.106.160.255 42.112.8.0-42.112.11.255 42.116.237.0-42.116.237.255 42.117.10.0-42.117.10.255 42.119.208.0-42.119.211.255 42.119.253.0-42.119.253.255 42.125.225.0-42.125.225.255 42.153.4.0-42.153.4.255 42.153.8.0-42.153.8.255 43.228.209.0-43.228.209.255 43.230.130.0-43.230.130.255 43.240.231.0-43.240.231.255 43.243.38.0-43.243.38.255 43.243.212.0-43.243.212.255 43.245.104.0-43.245.104.255 43.245.142.0-43.245.142.255 43.245.144.0-43.245.145.255 43.245.193.0-43.245.193.255 43.245.195.0-43.245.195.255 43.245.200.0-43.245.201.255 43.245.232.0-43.245.232.255 43.247.158.0-43.247.158.255 43.250.82.0-43.250.82.255 43.250.167.0-43.250.167.255 43.252.16.0-43.252.16.255 43.255.113.0-43.255.113.255 45.64.20.0-45.64.20.255 45.64.28.0-45.64.31.255 45.64.34.0-45.64.35.255 45.64.76.0-45.64.76.255 45.64.138.0-45.64.138.255 45.64.253.0-45.64.253.255 45.112.179.0-45.112.179.255 45.115.55.0-45.115.55.255 45.115.98.0-45.115.98.255 45.115.252.0-45.115.252.255 45.116.219.0-45.116.219.255 45.116.232.0-45.116.233.255 45.117.75.0-45.117.75.255 45.118.245.0-45.118.245.255 45.120.84.0-45.120.85.255 45.121.219.0-45.121.219.255 45.122.234.0-45.122.234.255 45.123.27.0-45.123.27.255 45.125.68.0-45.125.68.255 45.127.244.0-45.127.244.255 45.251.32.0-45.251.32.255 45.251.78.0-45.251.78.255 46.8.148.0-46.8.148.255 46.21.52.0-46.21.52.255 46.29.169.0-46.29.169.255 46.32.101.0-46.32.101.255 46.32.222.0-46.32.222.255 46.36.26.0-46.36.26.255 46.39.3.0-46.39.3.255 46.42.1.0-46.42.1.255 46.42.80.0-46.42.80.255 46.42.84.0-46.42.84.255 46.47.1.0-46.47.1.255 46.48.32.0-46.48.32.255 46.61.155.0-46.61.155.255 46.61.244.0-46.61.244.255 46.97.101.0-46.97.101.255 46.134.193.0-46.134.193.255 46.134.208.0-46.134.208.255 46.149.88.0-46.149.88.255 46.151.240.0-46.151.240.255 46.162.192.0-46.162.192.255 46.165.2.0-46.165.2.255 46.191.224.0-46.191.224.255 46.227.113.0-46.227.113.255 46.229.224.0-46.229.224.255 46.236.127.0-46.236.127.255 46.249.239.0-46.249.239.255 46.252.111.0-46.252.111.255 46.252.175.0-46.252.175.255 49.44.49.0-49.44.49.255 49.44.67.0-49.44.67.255 49.44.76.0-49.44.76.255 49.44.78.0-49.44.78.255 49.44.80.0-49.44.87.255 49.98.24.0-49.98.25.255 49.98.35.0-49.98.35.255 49.106.234.0-49.106.234.255 49.231.55.0-49.231.56.255 49.231.58.0-49.231.58.255 49.231.60.0-49.231.60.255 49.231.113.0-49.231.113.255 49.243.141.0-49.243.141.255 50.0.2.0-50.0.2.255 50.27.150.0-50.27.150.255 50.27.154.0-50.27.154.255 50.38.0.0-50.38.0.255 50.86.10.0-50.86.10.255 58.26.8.0-58.26.8.255 58.27.27.0-58.27.27.255 58.27.108.0-58.27.109.255 58.28.64.0-58.28.64.255 58.97.143.0-58.97.143.255 58.123.102.0-58.123.102.255 58.123.220.0-58.123.220.255 58.162.62.0-58.162.62.255 58.176.217.0-58.176.217.255 58.229.92.0-58.229.92.255 59.18.34.0-59.18.35.255 59.18.44.0-59.18.46.255 59.18.49.0-59.18.49.255 59.20.132.0-59.20.132.255 59.152.110.0-59.152.110.255 59.153.102.0-59.153.102.255 59.190.145.0-59.190.145.255 60.199.175.0-60.199.175.255 61.4.66.0-61.4.67.255 61.5.222.0-61.5.222.255 61.7.18.0-61.7.18.255 61.19.1.0-61.19.2.255 61.33.130.0-61.33.130.255 61.37.150.0-61.37.150.255 61.58.64.0-61.58.64.255 61.62.98.0-61.62.98.255 61.86.203.0-61.86.203.255 61.89.217.0-61.89.217.255 61.90.179.0-61.90.179.255 61.90.189.0-61.90.189.255 61.91.8.0-61.91.9.255 61.91.16.0-61.91.19.255 61.91.160.0-61.91.161.255 61.114.99.0-61.114.99.255 61.122.213.0-61.122.213.255 61.205.118.0-61.205.118.255 61.205.127.0-61.205.127.255 61.219.131.0-61.219.131.255 61.219.146.0-61.219.146.255 61.238.203.0-61.238.203.255 61.238.239.0-61.238.239.255 62.0.80.0-62.0.80.255 62.1.38.0-62.1.38.255 62.4.253.0-62.4.253.255 62.8.95.0-62.8.95.255 62.24.158.0-62.24.158.255 62.38.6.0-62.38.6.255 62.68.246.0-62.68.246.255 62.75.10.0-62.75.10.255 62.75.23.0-62.75.23.255 62.78.83.0-62.78.83.255 62.78.98.0-62.78.98.255 62.84.6.0-62.84.6.255 62.84.32.0-62.84.32.255 62.84.90.0-62.84.90.255 62.94.9.0-62.94.9.255 62.101.158.0-62.101.158.255 62.117.4.0-62.117.4.255 62.133.128.0-62.133.128.255 62.140.228.0-62.140.228.255 62.149.79.0-62.149.79.255 62.164.169.0-62.164.169.255 62.168.125.0-62.168.125.255 62.176.13.0-62.176.13.255 62.197.198.0-62.197.198.255 62.201.204.0-62.201.204.255 62.201.216.0-62.201.216.255 62.201.225.0-62.201.225.255 62.209.24.0-62.209.24.255 62.209.30.0-62.209.30.255 62.212.33.0-62.212.33.255 62.212.252.0-62.212.252.255 62.214.62.0-62.214.62.255 62.231.75.0-62.231.75.255 62.231.91.0-62.231.91.255 62.240.120.0-62.240.120.255 62.243.26.0-62.243.26.255 62.252.60.0-62.252.60.255 62.252.169.0-62.252.170.255 62.252.173.0-62.252.173.255 62.252.191.0-62.252.191.255 62.252.232.0-62.252.232.255 62.253.3.0-62.253.3.255 62.253.72.0-62.253.72.255 63.84.3.0-63.84.3.255 63.88.73.0-63.88.73.255 63.117.14.0-63.117.14.255 63.117.68.0-63.117.68.255 63.117.215.0-63.117.215.255 63.135.48.0-63.135.48.255 63.143.72.0-63.143.72.255 64.4.226.0-64.4.226.255 64.9.227.0-64.9.229.255 64.9.240.0-64.9.243.255 64.15.112.0-64.15.121.255 64.15.124.0-64.15.127.255 64.20.30.0-64.20.30.255 64.39.140.0-64.39.140.255 64.53.1.0-64.53.1.255 64.53.59.0-64.53.59.255 64.53.242.0-64.53.242.255 64.53.251.0-64.53.251.255 64.71.249.0-64.71.249.255 64.90.64.0-64.90.64.255 64.118.108.0-64.118.108.255 64.119.206.0-64.119.206.255 64.126.1.0-64.126.1.255 64.147.91.0-64.147.91.255 64.178.237.0-64.178.237.255 64.184.109.0-64.184.109.255 64.203.194.0-64.203.194.255 64.233.160.0-64.233.171.255 64.233.176.0-64.233.191.255 64.246.133.0-64.246.133.255 64.251.160.0-64.251.160.255 64.253.221.0-64.253.221.255 65.19.82.0-65.19.82.255 65.39.199.0-65.39.199.255 65.48.146.0-65.48.146.255 65.49.173.0-65.49.173.255 65.60.171.0-65.60.171.255 65.79.192.0-65.79.192.255 65.87.229.0-65.87.229.255 65.116.15.0-65.116.15.255 65.183.12.0-65.183.12.255 65.199.32.0-65.199.32.255 65.199.248.0-65.199.248.255 66.37.74.0-66.37.74.255 66.38.63.0-66.38.63.255 66.44.205.0-66.44.205.255 66.54.121.0-66.54.121.255 66.58.255.0-66.58.255.255 66.76.28.0-66.76.28.255 66.76.34.0-66.76.34.255 66.76.194.0-66.76.194.255 66.96.224.0-66.96.224.255 66.96.226.0-66.96.226.255 66.97.30.0-66.97.30.255 66.102.1.0-66.102.1.255 66.102.12.0-66.102.12.255 66.112.178.0-66.112.178.255 66.130.90.0-66.130.90.255 66.152.103.0-66.152.103.255 66.153.250.0-66.153.250.255 66.159.33.0-66.159.33.255 66.171.0.0-66.171.0.255 66.171.92.0-66.171.92.255 66.185.84.0-66.185.84.255 66.186.226.0-66.186.226.255 66.187.114.0-66.187.114.255 66.199.151.0-66.199.151.255 66.201.170.0-66.201.170.255 66.203.176.0-66.203.176.255 66.226.125.0-66.226.125.255 66.244.74.0-66.244.74.255 66.248.191.0-66.248.191.255 66.253.131.0-66.253.131.255 66.253.203.0-66.253.203.255 67.21.145.0-67.21.145.255 67.50.19.0-67.50.19.255 67.89.227.0-67.89.227.255 67.149.209.0-67.149.209.255 67.204.184.0-67.204.184.255 67.212.255.0-67.212.255.255 67.215.19.0-67.215.19.255 67.218.56.0-67.218.56.255 67.218.93.0-67.218.93.255 67.219.192.0-67.219.192.255 67.219.201.0-67.219.201.255 67.221.143.0-67.221.143.255 67.221.221.0-67.221.221.255 67.224.250.0-67.224.250.255 68.65.124.0-68.65.124.255 69.8.160.0-69.8.160.255 69.9.127.0-69.9.127.255 69.46.66.0-69.46.66.255 69.51.73.0-69.51.73.255 69.59.197.0-69.59.197.255 69.63.167.0-69.63.167.255 69.65.64.0-69.65.64.255 69.77.145.0-69.77.145.255 69.79.200.0-69.79.200.255 69.85.196.0-69.85.196.255 69.147.192.0-69.147.192.255 69.160.212.0-69.160.212.255 69.176.0.0-69.176.1.255 69.195.30.0-69.195.30.255 70.34.140.0-70.34.140.255 70.40.189.0-70.40.189.255 70.186.10.0-70.186.10.255 70.186.24.0-70.186.24.255 70.186.26.0-70.186.26.255 70.186.28.0-70.186.28.255 70.186.30.0-70.186.30.255 71.19.173.0-71.19.173.255 71.19.176.0-71.19.176.255 72.22.27.0-72.22.27.255 72.36.125.0-72.36.125.255 72.46.62.0-72.46.62.255 72.47.61.0-72.47.61.255 72.50.12.0-72.50.12.255 72.50.240.0-72.50.240.255 72.195.166.0-72.195.166.255 72.234.39.0-72.234.39.255 72.240.108.0-72.240.108.255 74.50.44.0-74.50.44.255 74.51.15.0-74.51.15.255 74.51.119.0-74.51.119.255 74.51.221.0-74.51.221.255 74.81.99.0-74.81.99.255 74.124.63.0-74.124.63.255 74.125.0.0-74.125.1.255 74.125.3.0-74.125.15.255 74.125.21.0-74.125.24.255 74.125.26.0-74.125.26.255 74.125.28.0-74.125.31.255 74.125.68.0-74.125.71.255 74.125.96.0-74.125.97.255 74.125.100.0-74.125.100.255 74.125.102.0-74.125.108.255 74.125.110.0-74.125.111.255 74.125.124.0-74.125.124.255 74.125.126.0-74.125.136.255 74.125.138.0-74.125.141.255 74.125.143.0-74.125.143.255 74.125.152.0-74.125.174.255 74.125.192.0-74.125.193.255 74.125.196.0-74.125.206.255 74.125.230.0-74.125.230.255 74.125.232.0-74.125.232.255 74.125.238.0-74.125.238.255 74.205.129.0-74.205.129.255 74.213.193.0-74.213.193.255 74.216.233.0-74.216.233.255 75.76.44.0-75.76.44.255 76.73.145.0-76.73.145.255 76.73.150.0-76.73.150.255 76.75.38.0-76.75.38.255 76.165.14.0-76.165.14.255 77.37.252.0-77.37.252.255 77.42.249.0-77.42.249.255 77.42.253.0-77.42.253.255 77.50.2.0-77.50.2.255 77.53.0.0-77.53.0.255 77.66.9.0-77.66.9.255 77.67.49.0-77.67.49.255 77.68.246.0-77.68.246.255 77.68.251.0-77.68.251.255 77.77.7.0-77.77.7.255 77.77.195.0-77.77.195.255 77.82.149.0-77.82.149.255 77.87.99.0-77.87.99.255 77.88.221.0-77.88.221.255 77.94.162.0-77.94.162.255 77.95.65.0-77.95.65.255 77.153.128.0-77.153.130.255 77.154.206.0-77.154.206.255 77.154.221.0-77.154.221.255 77.154.227.0-77.154.228.255 77.214.52.0-77.214.53.255 77.232.162.0-77.232.162.255 77.234.90.0-77.234.91.255 77.235.7.0-77.235.7.255 77.235.22.0-77.235.22.255 77.237.27.0-77.237.27.255 77.239.64.0-77.239.64.255 77.244.17.0-77.244.17.255 77.252.2.0-77.252.2.255 78.11.253.0-78.11.253.255 78.37.65.0-78.37.65.255 78.37.100.0-78.37.100.255 78.37.112.0-78.37.112.255 78.40.178.0-78.40.178.255 78.111.248.0-78.111.248.255 78.111.255.0-78.111.255.255 78.136.92.0-78.136.92.255 78.159.164.0-78.159.164.255 79.98.8.0-79.98.8.255 79.101.110.0-79.101.111.255 79.106.107.0-79.106.107.255 79.121.0.0-79.121.0.255 79.134.0.0-79.134.1.255 79.134.129.0-79.134.129.255 79.136.239.0-79.136.239.255 79.171.121.0-79.171.121.255 79.171.163.0-79.171.163.255 79.173.80.0-79.173.80.255 79.173.126.0-79.173.126.255 80.64.175.0-80.64.175.255 80.67.208.0-80.67.208.255 80.70.231.0-80.70.231.255 80.76.174.0-80.76.174.255 80.77.169.0-80.77.169.255 80.80.161.0-80.80.161.255 80.83.28.0-80.83.28.255 80.83.240.0-80.83.240.255 80.88.243.0-80.88.243.255 80.91.176.0-80.91.176.255 80.93.31.0-80.93.31.255 80.96.255.0-80.96.255.255 80.97.208.0-80.97.208.255 80.202.12.0-80.202.12.255 80.228.66.0-80.228.66.255 80.233.168.0-80.233.168.255 80.252.129.0-80.252.129.255 80.252.131.0-80.252.131.255 80.253.19.0-80.253.19.255 80.253.29.0-80.253.30.255 80.254.96.0-80.254.96.255 81.3.201.0-81.3.201.255 81.5.81.0-81.5.81.255 81.10.128.0-81.10.128.255 81.17.82.0-81.17.82.255 81.20.240.0-81.20.240.255 81.24.29.0-81.24.29.255 81.30.226.0-81.30.226.255 81.88.148.0-81.88.148.255 81.163.63.0-81.163.63.255 81.167.38.0-81.167.38.255 81.175.29.0-81.175.29.255 81.177.123.0-81.177.123.255 81.180.120.0-81.180.120.255 81.192.190.0-81.192.191.255 81.200.2.0-81.200.3.255 81.209.95.0-81.209.95.255 81.218.16.0-81.218.16.255 82.76.79.0-82.76.79.255 82.77.159.0-82.77.159.255 82.85.138.0-82.85.138.255 82.94.228.0-82.94.228.255 82.94.234.0-82.94.234.255 82.102.155.0-82.102.155.255 82.102.181.0-82.102.181.255 82.102.187.0-82.102.187.255 82.112.161.0-82.112.161.255 82.113.19.0-82.113.19.255 82.114.163.0-82.114.163.255 82.117.119.0-82.117.119.255 82.129.128.0-82.129.128.255 82.129.130.0-82.129.130.255 82.135.118.0-82.135.118.255 82.147.54.0-82.147.54.255 82.148.98.0-82.148.98.255 82.148.105.0-82.148.105.255 82.148.110.0-82.148.110.255 82.148.119.0-82.148.119.255 82.148.124.0-82.148.124.255 82.193.82.0-82.193.82.255 82.194.0.0-82.194.0.255 82.206.179.0-82.206.179.255 82.212.91.0-82.212.91.255 82.221.224.0-82.221.224.255 83.94.121.0-83.94.121.255 83.100.221.0-83.100.221.255 83.139.106.0-83.139.106.255 83.140.66.0-83.140.66.255 83.142.166.0-83.142.166.255 83.167.19.0-83.167.19.255 83.167.64.0-83.167.64.255 83.169.197.0-83.169.197.255 83.174.196.0-83.174.196.255 83.174.198.0-83.174.198.255 83.175.145.0-83.175.145.255 83.219.135.0-83.219.135.255 83.233.10.0-83.233.10.255 83.233.164.0-83.233.164.255 83.255.235.0-83.255.235.255 84.15.64.0-84.15.64.255 84.39.249.0-84.39.249.255 84.46.102.0-84.46.102.255 84.54.161.0-84.54.161.255 84.208.42.0-84.208.42.255 84.235.58.0-84.235.58.255 84.235.77.0-84.235.77.255 84.240.234.0-84.240.234.255 84.244.62.0-84.244.62.255 85.14.28.0-85.14.28.255 85.91.7.0-85.91.7.255 85.112.116.0-85.112.117.255 85.112.121.0-85.112.121.255 85.113.32.0-85.113.32.255 85.114.126.0-85.114.126.255 85.114.182.0-85.114.182.255 85.118.123.0-85.118.123.255 85.134.33.0-85.134.33.255 85.158.132.0-85.158.132.255 85.172.1.0-85.172.1.255 85.182.250.0-85.182.250.255 85.187.222.0-85.187.222.255 85.194.196.0-85.194.198.255 85.194.249.0-85.194.250.255 85.233.229.0-85.233.229.255 85.234.4.0-85.234.4.255 85.239.127.0-85.239.127.255 86.38.6.0-86.38.6.255 86.51.24.0-86.51.24.255 86.60.255.0-86.60.255.255 86.62.126.0-86.62.126.255 87.76.32.0-87.76.32.255 87.79.22.0-87.79.22.255 87.119.3.0-87.119.3.255 87.126.158.0-87.126.158.255 87.226.176.0-87.226.176.255 87.229.142.0-87.229.142.255 87.229.144.0-87.229.144.255 87.245.195.0-87.245.198.255 87.245.200.0-87.245.200.255 88.87.68.0-88.87.68.255 88.201.14.0-88.201.15.255 88.204.142.0-88.204.142.255 88.212.9.0-88.212.9.255 88.216.174.0-88.216.174.255 88.217.135.0-88.217.135.255 88.222.2.0-88.222.2.255 89.25.120.0-89.25.120.255 89.25.215.0-89.25.215.255 89.47.210.0-89.47.210.255 89.127.198.0-89.127.198.255 89.185.72.0-89.185.72.255 89.187.219.0-89.187.219.255 89.189.161.0-89.189.161.255 89.201.175.0-89.201.175.255 89.212.69.0-89.212.69.255 89.218.72.0-89.218.72.255 89.221.194.0-89.221.194.255 89.221.200.0-89.221.201.255 89.228.4.0-89.228.4.255 89.250.0.0-89.250.0.255 90.150.4.0-90.150.4.255 90.150.80.0-90.150.80.255 90.150.83.0-90.150.83.255 90.157.127.0-90.157.127.255 90.189.105.0-90.189.105.255 90.201.124.0-90.201.124.255 90.211.177.0-90.211.177.255 90.222.188.0-90.222.188.255 90.223.244.0-90.223.244.255 91.103.72.0-91.103.72.255 91.106.37.0-91.106.37.255 91.142.149.0-91.142.149.255 91.144.134.0-91.144.134.255 91.144.138.0-91.144.138.255 91.144.157.0-91.144.157.255 91.144.165.0-91.144.165.255 91.184.109.0-91.184.109.255 91.185.2.0-91.185.2.255 91.185.4.0-91.185.4.255 91.185.100.0-91.185.100.255 91.189.221.0-91.189.221.255 91.192.65.0-91.192.65.255 91.192.67.0-91.192.67.255 91.195.131.0-91.195.131.255 91.202.206.0-91.202.206.255 91.202.254.0-91.202.254.255 91.204.136.0-91.204.136.255 91.204.176.0-91.204.176.255 91.205.69.0-91.205.69.255 91.211.58.0-91.211.58.255 91.213.30.0-91.213.30.255 91.214.215.0-91.214.215.255 91.218.4.0-91.218.5.255 91.219.138.0-91.219.138.255 91.226.120.0-91.226.120.255 91.229.148.0-91.229.148.255 91.230.210.0-91.230.210.255 91.232.101.0-91.232.101.255 91.235.179.0-91.235.180.255 91.240.80.0-91.240.80.255 91.245.214.0-91.245.214.255 91.246.119.0-91.246.119.255 91.247.2.0-91.247.2.255 92.46.47.0-92.46.47.255 92.46.70.0-92.46.70.255 92.51.99.0-92.51.99.255 92.62.75.0-92.62.75.255 92.87.11.0-92.87.11.255 92.87.156.0-92.87.156.255 92.87.232.0-92.87.232.255 92.126.121.0-92.126.121.255 92.126.123.0-92.126.123.255 92.126.155.0-92.126.155.255 92.226.2.0-92.226.2.255 92.244.237.0-92.244.237.255 92.246.5.0-92.246.5.255 92.246.12.0-92.246.12.255 93.57.114.0-93.57.114.255 93.62.101.0-93.62.101.255 93.87.90.0-93.87.90.255 93.88.163.0-93.88.164.255 93.89.223.0-93.89.223.255 93.90.210.0-93.90.210.255 93.91.155.0-93.91.155.255 93.91.193.0-93.91.193.255 93.100.204.0-93.100.204.255 93.123.23.0-93.123.23.255 93.123.128.0-93.123.128.255 93.183.211.0-93.183.211.255 93.184.1.0-93.184.1.255 93.186.108.0-93.186.108.255 93.191.15.0-93.191.15.255 94.20.252.0-94.20.252.255 94.21.255.0-94.21.255.255 94.24.228.0-94.24.228.255 94.24.237.0-94.24.237.255 94.25.137.0-94.25.137.255 94.25.217.0-94.25.217.255 94.31.189.0-94.31.189.255 94.53.12.0-94.53.12.255 94.79.46.0-94.79.46.255 94.100.228.0-94.100.228.255 94.128.0.0-94.128.0.255 94.128.4.0-94.128.4.255 94.128.13.0-94.128.13.255 94.128.254.0-94.128.254.255 94.129.129.0-94.129.131.255 94.129.254.0-94.129.254.255 94.137.63.0-94.137.63.255 94.140.255.0-94.140.255.255 94.142.38.0-94.142.38.255 94.143.40.0-94.143.40.255 94.156.188.0-94.156.188.255 94.190.64.0-94.190.64.255 94.190.68.0-94.190.68.255 94.228.16.0-94.228.16.255 94.228.193.0-94.228.193.255 94.228.205.0-94.228.205.255 94.230.91.0-94.230.91.255 94.230.140.0-94.230.140.255 94.231.129.0-94.231.129.255 94.232.220.0-94.232.220.255 94.245.201.0-94.245.201.255 94.247.63.0-94.247.63.255 94.255.0.0-94.255.0.255 95.30.216.0-95.30.219.255 95.54.196.0-95.54.196.255 95.57.218.0-95.57.218.255 95.59.126.0-95.59.126.255 95.66.1.0-95.66.1.255 95.66.10.0-95.66.10.255 95.67.12.0-95.67.12.255 95.83.191.0-95.83.191.255 95.107.145.0-95.107.145.255 95.143.84.0-95.143.84.255 95.154.114.0-95.154.114.255 95.158.47.0-95.158.47.255 95.158.130.0-95.158.130.255 95.159.73.0-95.159.73.255 95.161.237.0-95.161.237.255 95.168.222.0-95.168.222.255 95.170.192.0-95.170.192.255 95.170.194.0-95.170.194.255 95.180.157.0-95.180.157.255 95.181.16.0-95.181.16.255 95.189.102.0-95.189.102.255 95.189.122.0-95.189.122.255 95.209.200.0-95.209.200.255 96.4.190.0-96.4.190.255 96.5.123.0-96.5.123.255 96.9.91.0-96.9.91.255 96.20.0.0-96.20.0.255 96.21.0.0-96.21.0.255 96.23.20.0-96.23.20.255 96.27.183.0-96.27.183.255 96.30.112.0-96.30.112.255 96.31.1.0-96.31.1.255 96.43.49.0-96.43.49.255 96.47.87.0-96.47.87.255 96.63.131.0-96.63.131.255 96.127.240.0-96.127.240.255 96.127.250.0-96.127.250.255 97.75.181.0-97.75.181.255 98.124.44.0-98.124.44.255 101.53.58.0-101.53.58.255 101.78.13.0-101.78.13.255 101.96.118.0-101.96.118.255 101.98.9.0-101.98.9.255 101.99.2.0-101.99.2.255 101.99.49.0-101.99.49.255 101.100.179.0-101.100.179.255 101.100.190.0-101.100.190.255 101.203.171.0-101.203.171.255 103.1.139.0-103.1.139.255 103.2.116.0-103.2.116.255 103.3.32.0-103.3.32.255 103.4.110.0-103.4.110.255 103.5.34.0-103.5.35.255 103.7.78.0-103.7.78.255 103.7.249.0-103.7.249.255 103.9.105.0-103.9.105.255 103.9.112.0-103.9.112.255 103.10.20.0-103.10.20.255 103.10.65.0-103.10.65.255 103.10.67.0-103.10.67.255 103.11.28.0-103.11.28.255 103.11.60.0-103.11.62.255 103.12.72.0-103.12.72.255 103.12.172.0-103.12.172.255 103.12.179.0-103.12.179.255 103.12.237.0-103.12.237.255 103.13.116.0-103.13.116.255 103.13.250.0-103.13.250.255 103.15.42.0-103.15.42.255 103.15.61.0-103.15.61.255 103.15.244.0-103.15.244.255 103.16.152.0-103.16.152.255 103.16.204.0-103.16.205.255 103.16.207.0-103.16.207.255 103.17.99.0-103.17.99.255 103.17.203.0-103.17.203.255 103.17.215.0-103.17.215.255 103.18.157.0-103.18.157.255 103.19.254.0-103.19.254.255 103.20.141.0-103.20.141.255 103.21.25.0-103.21.25.255 103.21.42.0-103.21.43.255 103.21.167.0-103.21.167.255 103.21.169.0-103.21.169.255 103.22.242.0-103.22.242.255 103.25.178.0-103.25.178.255 103.25.229.0-103.25.229.255 103.26.211.0-103.26.211.255 103.28.94.0-103.28.94.255 103.29.146.0-103.29.146.255 103.30.113.0-103.30.113.255 103.31.46.0-103.31.46.255 103.35.170.0-103.35.170.255 103.37.30.0-103.37.30.255 103.37.34.0-103.37.34.255 103.40.227.0-103.40.227.255 103.41.23.0-103.41.23.255 103.42.208.0-103.42.208.255 103.43.149.0-103.43.149.255 103.44.15.0-103.44.15.255 103.44.50.0-103.44.50.255 103.44.150.0-103.44.151.255 103.44.156.0-103.44.156.255 103.46.233.0-103.46.233.255 103.47.153.0-103.47.153.255 103.50.76.0-103.50.76.255 103.54.40.0-103.54.40.255 103.55.88.0-103.55.88.255 103.55.147.0-103.55.147.255 103.56.230.0-103.56.230.255 103.57.40.0-103.57.40.255 103.59.200.0-103.59.200.255 103.59.211.0-103.59.211.255 103.60.174.0-103.60.174.255 103.66.70.0-103.66.70.255 103.67.228.0-103.67.228.255 103.70.141.0-103.70.141.255 103.192.46.0-103.192.46.255 103.196.232.0-103.196.232.255 103.200.39.0-103.200.39.255 103.203.231.0-103.203.231.255 103.206.10.0-103.206.10.255 103.206.152.0-103.206.152.255 103.209.19.0-103.209.19.255 103.210.49.0-103.210.49.255 103.214.129.0-103.214.129.255 103.214.200.0-103.214.200.255 103.215.25.0-103.215.25.255 103.217.105.0-103.217.105.255 103.224.186.0-103.224.186.255 103.224.194.0-103.224.194.255 103.225.0.0-103.225.1.255 103.225.124.0-103.225.124.255 103.225.178.0-103.225.178.255 103.226.184.0-103.226.184.255 103.229.129.0-103.229.129.255 103.231.230.0-103.231.230.255 103.233.36.0-103.233.38.255 103.234.120.0-103.234.120.255 103.234.122.0-103.234.122.255 103.236.176.0-103.236.176.255 103.241.59.0-103.241.59.255 103.242.12.0-103.242.12.255 103.242.22.0-103.242.22.255 103.242.58.0-103.242.58.255 103.243.113.0-103.243.113.255 103.243.115.0-103.243.115.255 103.244.186.0-103.244.186.255 103.246.46.0-103.246.46.255 103.248.32.0-103.248.32.255 103.249.65.0-103.249.65.255 103.250.87.0-103.250.87.255 103.250.152.0-103.250.152.255 103.250.184.0-103.250.184.255 103.250.189.0-103.250.189.255 103.251.18.0-103.251.18.255 103.251.244.0-103.251.244.255 103.255.4.0-103.255.5.255 103.255.7.0-103.255.7.255 104.153.249.0-104.153.249.255 104.155.72.0-104.155.72.255 104.166.32.0-104.166.32.255 104.193.66.0-104.193.66.255 104.193.69.0-104.193.69.255 104.199.63.0-104.199.63.255 104.199.230.0-104.199.230.255 104.237.160.0-104.237.163.255 104.237.172.0-104.237.172.255 104.237.174.0-104.237.174.255 104.237.188.0-104.237.190.255 105.112.8.0-105.112.8.255 105.187.242.0-105.187.242.255 105.203.250.0-105.203.250.255 106.0.60.0-106.0.60.255 106.1.140.0-106.1.140.255 106.1.151.0-106.1.151.255 106.1.167.0-106.1.167.255 106.1.220.0-106.1.220.255 106.51.40.0-106.51.40.255 106.51.113.0-106.51.113.255 106.103.1.0-106.103.2.255 106.162.192.0-106.162.192.255 106.162.198.0-106.162.200.255 106.162.216.0-106.162.216.255 107.161.13.0-107.161.13.255 108.177.8.0-108.177.15.255 108.177.96.0-108.177.98.255 108.177.103.0-108.177.104.255 108.177.112.0-108.177.112.255 108.177.119.0-108.177.121.255 108.177.125.0-108.177.125.255 108.177.127.0-108.177.127.255 109.60.129.0-109.60.129.255 109.70.190.0-109.70.190.255 109.88.203.0-109.88.203.255 109.105.109.0-109.105.109.255 109.110.33.0-109.110.33.255 109.127.2.0-109.127.2.255 109.167.228.0-109.167.228.255 109.173.137.0-109.173.137.255 109.194.25.0-109.194.25.255 109.194.73.0-109.194.73.255 109.194.89.0-109.194.89.255 109.194.105.0-109.194.105.255 109.194.121.0-109.194.121.255 109.194.137.0-109.194.137.255 109.194.169.0-109.194.169.255 109.194.185.0-109.194.185.255 109.194.201.0-109.194.201.255 109.194.233.0-109.194.233.255 109.195.9.0-109.195.9.255 109.195.25.0-109.195.25.255 109.195.41.0-109.195.41.255 109.195.73.0-109.195.73.255 109.195.89.0-109.195.89.255 109.195.105.0-109.195.105.255 109.195.121.0-109.195.121.255 109.195.153.0-109.195.153.255 109.195.169.0-109.195.169.255 109.195.185.0-109.195.185.255 109.195.233.0-109.195.233.255 109.195.249.0-109.195.249.255 109.199.81.0-109.199.81.255 109.224.13.0-109.224.13.255 109.224.40.0-109.224.41.255 109.224.43.0-109.224.43.255 109.225.113.0-109.225.113.255 109.226.50.0-109.226.50.255 109.226.232.0-109.226.232.255 109.226.240.0-109.226.240.255 109.229.163.0-109.229.163.255 109.230.180.0-109.230.180.255 109.231.231.0-109.231.231.255 109.239.139.0-109.239.139.255 109.245.221.0-109.245.221.255 109.248.208.0-109.248.208.255 110.50.81.0-110.50.81.255 110.76.130.0-110.76.130.255 110.93.194.0-110.93.194.255 110.163.42.0-110.163.42.255 110.164.4.0-110.164.10.255 110.164.12.0-110.164.14.255 110.164.16.0-110.164.16.255 110.164.18.0-110.164.19.255 110.164.22.0-110.164.23.255 111.84.96.0-111.84.96.255 111.84.224.0-111.84.225.255 111.86.157.0-111.86.157.255 111.92.162.0-111.92.162.255 111.94.248.0-111.94.249.255 111.95.240.0-111.95.240.255 111.119.161.0-111.119.161.255 111.168.255.0-111.168.255.255 112.72.5.0-112.72.5.255 112.133.228.0-112.133.228.255 112.197.5.0-112.197.5.255 112.197.7.0-112.197.8.255 112.197.10.0-112.197.10.255 112.197.12.0-112.197.13.255 112.215.88.0-112.215.88.255 112.215.101.0-112.215.101.255 112.215.126.0-112.215.126.255 112.215.183.0-112.215.184.255 112.215.207.0-112.215.207.255 113.171.18.0-113.171.19.255 113.171.192.0-113.171.192.255 113.171.198.0-113.171.198.255 113.171.202.0-113.171.202.255 113.171.216.0-113.171.216.255 113.171.220.0-113.171.220.255 113.171.232.0-113.171.232.255 113.171.236.0-113.171.247.255 113.171.251.0-113.171.253.255 113.197.108.0-113.197.108.255 114.4.4.0-114.4.4.255 114.4.7.0-114.4.7.255 114.4.160.0-114.4.160.255 114.31.1.0-114.31.1.255 114.31.31.0-114.31.31.255 114.108.204.0-114.108.205.255 114.108.207.0-114.108.207.255 114.120.192.0-114.120.192.255 114.120.225.0-114.120.225.255 114.121.194.0-114.121.194.255 114.121.226.0-114.121.226.255 114.125.1.0-114.125.1.255 114.125.33.0-114.125.33.255 114.125.97.0-114.125.97.255 114.125.129.0-114.125.129.255 114.125.145.0-114.125.145.255 114.125.161.0-114.125.161.255 114.125.192.0-114.125.192.255 114.130.6.0-114.130.6.255 115.84.108.0-115.84.108.255 115.84.159.0-115.84.159.255 115.87.70.0-115.87.71.255 115.127.52.0-115.127.52.255 115.164.12.0-115.164.12.255 115.164.140.0-115.164.140.255 115.166.169.0-115.166.169.255 115.167.72.0-115.167.72.255 115.167.74.0-115.167.74.255 115.167.76.0-115.167.76.255 115.178.26.0-115.178.27.255 115.186.17.0-115.186.17.255 115.186.97.0-115.186.97.255 115.254.97.0-115.254.97.255 115.254.106.0-115.254.106.255 115.254.121.0-115.254.121.255 116.58.204.0-116.58.204.255 116.68.215.0-116.68.215.255 116.93.47.0-116.93.47.255 116.202.230.0-116.202.230.255 116.212.147.0-116.212.147.255 117.102.78.0-117.102.78.255 117.102.117.0-117.102.117.255 117.111.0.0-117.111.0.255 117.219.224.0-117.219.232.255 118.69.247.0-118.69.247.255 118.69.249.0-118.69.249.255 118.98.26.0-118.98.26.255 118.98.30.0-118.98.30.255 118.98.36.0-118.98.36.255 118.98.76.0-118.98.77.255 118.98.106.0-118.98.106.255 118.98.109.0-118.98.111.255 118.107.75.0-118.107.75.255 118.143.88.0-118.143.88.255 118.179.14.0-118.179.14.255 119.2.100.0-119.2.100.255 119.9.76.0-119.9.76.255 119.11.250.0-119.11.250.255 119.15.80.0-119.15.80.255 119.40.97.0-119.40.97.255 119.110.118.0-119.110.118.255 119.149.187.0-119.149.188.255 119.153.111.0-119.153.112.255 119.155.138.0-119.155.138.255 119.160.91.0-119.160.91.255 119.160.114.0-119.160.114.255 119.160.125.0-119.160.125.255 119.161.83.0-119.161.83.255 119.224.142.0-119.224.142.255 119.235.0.0-119.235.0.255 119.235.103.0-119.235.103.255 120.28.5.0-120.28.5.255 120.28.12.0-120.28.12.255 120.28.26.0-120.28.26.255 120.28.53.0-120.28.53.255 120.89.6.0-120.89.6.255 120.89.97.0-120.89.97.255 121.78.42.0-121.78.42.255 121.78.52.0-121.78.52.255 121.78.206.0-121.78.206.255 121.123.238.0-121.123.238.255 121.158.53.0-121.158.53.255 122.2.152.0-122.2.153.255 122.2.215.0-122.2.215.255 122.56.60.0-122.56.60.255 122.56.115.0-122.56.115.255 122.149.3.0-122.149.3.255 122.154.58.0-122.154.58.255 122.154.76.0-122.154.76.255 122.154.133.0-122.154.133.255 122.154.160.0-122.154.160.255 122.154.244.0-122.154.244.255 122.201.16.0-122.201.16.255 122.202.129.0-122.202.129.255 122.251.255.0-122.251.255.255 122.255.117.0-122.255.117.255 123.108.201.0-123.108.201.255 123.108.243.0-123.108.243.255 123.108.252.0-123.108.252.255 123.136.105.0-123.136.105.255 123.136.114.0-123.136.114.255 123.176.0.0-123.176.0.255 123.205.250.0-123.205.250.255 123.241.78.0-123.241.78.255 123.241.255.0-123.241.255.255 124.40.230.0-124.40.230.255 124.40.233.0-124.40.233.255 124.40.244.0-124.40.245.255 124.108.16.0-124.108.16.255 124.108.18.0-124.108.18.255 124.109.34.0-124.109.34.255 124.153.4.0-124.153.4.255 124.153.255.0-124.153.255.255 124.158.72.0-124.158.72.255 124.216.0.0-124.216.0.255 124.217.179.0-124.217.179.255 124.248.162.0-124.248.162.255 125.99.168.0-125.99.168.255 125.214.167.0-125.214.167.255 125.234.48.0-125.234.55.255 125.234.160.0-125.234.160.255 125.235.17.0-125.235.17.255 125.235.30.0-125.235.31.255 125.235.36.0-125.235.36.255 128.0.31.0-128.0.31.255 128.0.86.0-128.0.86.255 128.0.169.0-128.0.169.255 128.74.248.0-128.74.251.255 128.139.200.0-128.139.200.255 128.205.159.0-128.205.159.255 128.210.224.0-128.210.224.255 129.66.96.0-129.66.96.255 130.111.19.0-130.111.19.255 130.206.193.0-130.206.193.255 131.0.95.0-131.0.95.255 131.0.245.0-131.0.245.255 131.0.250.0-131.0.250.255 131.72.76.0-131.72.76.255 131.100.108.0-131.100.108.255 131.161.24.0-131.161.24.255 131.161.109.0-131.161.109.255 131.161.234.0-131.161.234.255 131.221.20.0-131.221.20.255 131.221.169.0-131.221.169.255 131.221.224.0-131.221.224.255 131.255.157.0-131.255.157.255 131.255.212.0-131.255.212.255 132.198.200.0-132.198.200.255 132.239.253.0-132.239.253.255 132.255.148.0-132.255.148.255 132.255.236.0-132.255.236.255 134.0.218.0-134.0.218.255 134.19.215.0-134.19.215.255 134.90.151.0-134.90.151.255 135.0.199.0-135.0.199.255 137.207.250.0-137.207.250.255 138.0.73.0-138.0.73.255 138.0.153.0-138.0.153.255 138.0.199.0-138.0.199.255 138.0.204.0-138.0.204.255 138.36.0.0-138.36.0.255 138.59.209.0-138.59.209.255 138.97.127.0-138.97.127.255 138.97.163.0-138.97.163.255 138.99.133.0-138.99.133.255 138.99.226.0-138.99.226.255 138.99.246.0-138.99.246.255 138.117.71.0-138.117.72.255 138.121.75.0-138.121.75.255 138.122.84.0-138.122.84.255 138.122.110.0-138.122.110.255 138.122.223.0-138.122.223.255 138.185.138.0-138.185.138.255 138.185.180.0-138.185.180.255 138.186.0.0-138.186.0.255 138.186.122.0-138.186.122.255 138.204.143.0-138.204.143.255 138.204.159.0-138.204.159.255 138.219.2.0-138.219.2.255 138.219.152.0-138.219.152.255 139.175.107.0-139.175.107.255 140.113.14.0-140.113.14.255 140.197.248.0-140.197.249.255 140.211.86.0-140.211.86.255 142.161.4.0-142.161.4.255 142.161.132.0-142.161.132.255 142.163.38.0-142.163.38.255 142.165.4.0-142.165.4.255 142.166.12.0-142.166.12.255 142.166.129.0-142.166.129.255 142.166.149.0-142.166.149.255 142.166.242.0-142.166.242.255 142.176.121.0-142.176.121.255 143.137.72.0-143.137.72.255 143.137.113.0-143.137.113.255 143.202.124.0-143.202.124.255 143.208.136.0-143.208.136.255 143.208.211.0-143.208.211.255 143.215.193.0-143.215.193.255 143.255.44.0-143.255.44.255 144.48.163.0-144.48.163.255 144.131.80.0-144.131.80.255 145.255.14.0-145.255.14.255 146.88.60.0-146.88.60.255 146.115.8.0-146.115.8.255 146.115.22.0-146.115.22.255 146.120.79.0-146.120.79.255 146.158.95.0-146.158.95.255 146.186.20.0-146.186.20.255 146.247.1.0-146.247.1.255 148.245.203.0-148.245.203.255 149.126.86.0-149.126.86.255 149.165.180.0-149.165.180.255 149.255.152.0-149.255.152.255 149.255.254.0-149.255.255.255 150.100.16.0-150.100.16.255 150.101.213.0-150.101.213.255 150.129.7.0-150.129.7.255 150.129.59.0-150.129.59.255 150.129.146.0-150.129.146.255 150.199.22.0-150.199.22.255 150.199.24.0-150.199.24.255 150.242.21.0-150.242.21.255 150.242.84.0-150.242.84.255 151.236.167.0-151.236.167.255 151.248.100.0-151.248.100.255 152.231.110.0-152.231.111.255 154.65.36.0-154.65.36.255 154.66.245.0-154.66.245.255 154.67.1.0-154.67.1.255 154.73.81.0-154.73.81.255 154.126.74.0-154.126.74.255 155.69.253.0-155.69.253.255 155.232.240.0-155.232.240.255 157.157.135.0-157.157.135.255 157.161.155.0-157.161.155.255 157.197.92.0-157.197.93.255 159.134.168.0-159.134.168.255 159.148.69.0-159.148.69.255 159.180.253.0-159.180.253.255 159.192.0.0-159.192.0.255 160.3.24.0-160.3.24.255 160.19.221.0-160.19.221.255 160.202.147.0-160.202.147.255 161.0.238.0-161.0.238.255 161.132.34.0-161.132.34.255 162.211.40.0-162.211.40.255 162.212.12.0-162.212.12.255 162.212.208.0-162.212.208.255 162.221.128.0-162.221.128.255 162.246.0.0-162.246.0.255 162.247.80.0-162.247.80.255 162.252.127.0-162.252.127.255 162.253.24.0-162.253.24.255 162.254.10.0-162.254.10.255 163.28.18.0-163.28.18.255 163.28.38.0-163.28.38.255 163.28.51.0-163.28.51.255 163.28.83.0-163.28.83.255 163.28.116.0-163.28.116.255 163.28.130.0-163.28.130.255 163.44.26.0-163.44.26.255 163.53.140.0-163.53.140.255 163.153.215.0-163.153.215.255 164.40.244.0-164.40.244.255 164.58.76.0-164.58.76.255 164.58.87.0-164.58.87.255 164.67.18.0-164.67.18.255 164.85.63.0-164.85.63.255 164.113.94.0-164.113.94.255 164.215.74.0-164.215.74.255 165.98.72.0-165.98.72.255 165.165.38.0-165.165.38.255 165.166.67.0-165.166.67.255 165.254.153.0-165.254.153.255 166.62.221.0-166.62.221.255 166.70.146.0-166.70.146.255 167.142.232.0-167.142.232.255 167.205.23.0-167.205.23.255 167.206.10.0-167.206.10.255 167.206.12.0-167.206.12.255 167.206.145.0-167.206.145.255 167.206.245.0-167.206.245.255 167.206.252.0-167.206.252.255 167.249.134.0-167.249.134.255 168.90.8.0-168.90.9.255 168.90.64.0-168.90.64.255 168.90.91.0-168.90.91.255 168.90.131.0-168.90.131.255 168.90.226.0-168.90.226.255 168.121.53.0-168.121.53.255 168.121.228.0-168.121.228.255 168.187.143.0-168.187.143.255 168.194.15.0-168.194.15.255 168.194.64.0-168.194.64.255 168.205.130.0-168.205.130.255 170.0.176.0-170.0.176.255 170.51.240.0-170.51.240.255 170.51.244.0-170.51.244.255 170.84.132.0-170.84.132.255 170.84.206.0-170.84.206.255 170.150.112.0-170.150.112.255 170.150.168.0-170.150.168.255 170.233.116.0-170.233.116.255 170.254.11.0-170.254.11.255 172.56.128.0-172.56.134.255 172.56.136.0-172.56.136.255 172.56.138.0-172.56.142.255 172.56.144.0-172.56.144.255 172.56.146.0-172.56.146.255 172.217.0.0-172.217.13.255 172.217.16.0-172.217.31.255 172.217.60.0-172.217.60.255 172.217.129.0-172.217.130.255 173.44.117.0-173.44.117.255 173.44.125.0-173.44.125.255 173.194.0.0-173.194.5.255 173.194.7.0-173.194.8.255 173.194.10.0-173.194.32.255 173.194.44.0-173.194.44.255 173.194.48.0-173.194.51.255 173.194.53.0-173.194.61.255 173.194.63.0-173.194.63.255 173.194.66.0-173.194.70.255 173.194.73.0-173.194.74.255 173.194.76.0-173.194.76.255 173.194.78.0-173.194.79.255 173.194.113.0-173.194.113.255 173.194.122.0-173.194.122.255 173.194.128.0-173.194.144.255 173.194.146.0-173.194.158.255 173.194.160.0-173.194.167.255 173.194.175.0-173.194.223.255 173.218.181.0-173.218.181.255 173.218.248.0-173.218.248.255 173.219.93.0-173.219.93.255 173.219.136.0-173.219.136.255 173.224.96.0-173.224.96.255 173.237.115.0-173.237.115.255 173.237.125.0-173.237.125.255 174.140.109.0-174.140.109.255 175.28.1.0-175.28.1.255 175.100.94.0-175.100.94.255 175.101.69.0-175.101.69.255 176.62.72.0-176.62.72.255 176.97.160.0-176.97.160.255 176.99.94.0-176.99.94.255 176.101.253.0-176.101.253.255 176.106.225.0-176.106.225.255 176.112.160.0-176.112.160.255 176.114.27.0-176.114.27.255 176.115.127.0-176.115.127.255 176.116.160.0-176.116.160.255 176.117.255.0-176.117.255.255 176.118.240.0-176.118.240.255 176.122.49.0-176.122.49.255 176.126.59.0-176.126.59.255 176.221.96.0-176.221.96.255 176.222.164.0-176.222.164.255 176.222.187.0-176.222.187.255 176.222.191.0-176.222.191.255 176.241.81.0-176.241.81.255 176.255.201.0-176.255.201.255 177.10.57.0-177.10.57.255 177.10.98.0-177.10.98.255 177.10.120.0-177.10.120.255 177.10.160.0-177.10.160.255 177.10.253.0-177.10.253.255 177.11.153.0-177.11.153.255 177.12.63.0-177.12.63.255 177.12.127.0-177.12.127.255 177.20.208.0-177.20.208.255 177.21.96.0-177.21.96.255 177.22.32.0-177.22.32.255 177.22.96.0-177.22.96.255 177.23.168.0-177.23.168.255 177.23.197.0-177.23.197.255 177.35.32.0-177.35.32.255 177.35.203.0-177.35.203.255 177.36.3.0-177.36.3.255 177.36.38.0-177.36.38.255 177.36.88.0-177.36.88.255 177.36.217.0-177.36.217.255 177.37.69.0-177.37.69.255 177.38.206.0-177.38.206.255 177.38.247.0-177.38.247.255 177.39.144.0-177.39.144.255 177.43.115.0-177.43.115.255 177.43.165.0-177.43.165.255 177.43.170.0-177.43.170.255 177.43.196.0-177.43.196.255 177.43.235.0-177.43.235.255 177.43.239.0-177.43.239.255 177.44.140.0-177.44.140.255 177.44.255.0-177.44.255.255 177.46.79.0-177.46.79.255 177.47.62.0-177.47.62.255 177.47.130.0-177.47.130.255 177.47.173.0-177.47.173.255 177.53.147.0-177.53.147.255 177.54.236.0-177.54.236.255 177.55.10.0-177.55.10.255 177.55.12.0-177.55.13.255 177.55.15.0-177.55.18.255 177.55.62.0-177.55.62.255 177.55.150.0-177.55.150.255 177.55.244.0-177.55.244.255 177.65.111.0-177.65.111.255 177.66.96.0-177.66.96.255 177.66.115.0-177.66.115.255 177.66.245.0-177.66.245.255 177.67.85.0-177.67.85.255 177.69.110.0-177.69.110.255 177.70.66.0-177.70.66.255 177.71.7.0-177.71.7.255 177.72.143.0-177.72.143.255 177.72.178.0-177.72.178.255 177.72.198.0-177.72.198.255 177.73.10.0-177.73.10.255 177.74.241.0-177.74.241.255 177.75.56.0-177.75.56.255 177.75.75.0-177.75.75.255 177.84.67.0-177.84.67.255 177.84.167.0-177.84.167.255 177.85.119.0-177.85.119.255 177.85.200.0-177.85.200.255 177.86.158.0-177.86.158.255 177.91.160.0-177.91.160.255 177.91.162.0-177.91.162.255 177.91.255.0-177.91.255.255 177.92.139.0-177.92.139.255 177.99.179.0-177.99.179.255 177.99.185.0-177.99.185.255 177.99.203.0-177.99.203.255 177.101.143.0-177.101.143.255 177.104.114.0-177.104.114.255 177.107.188.0-177.107.188.255 177.107.191.0-177.107.191.255 177.124.192.0-177.124.192.255 177.125.27.0-177.125.27.255 177.125.168.0-177.125.168.255 177.125.210.0-177.125.210.255 177.126.2.0-177.126.2.255 177.126.124.0-177.126.124.255 177.126.126.0-177.126.126.255 177.126.175.0-177.126.175.255 177.128.193.0-177.128.193.255 177.128.223.0-177.128.223.255 177.129.8.0-177.129.8.255 177.129.16.0-177.129.16.255 177.129.156.0-177.129.156.255 177.130.15.0-177.130.15.255 177.130.53.0-177.130.53.255 177.130.79.0-177.130.79.255 177.131.1.0-177.131.1.255 177.131.55.0-177.131.55.255 177.135.84.0-177.135.84.255 177.135.94.0-177.135.94.255 177.135.103.0-177.135.103.255 177.135.107.0-177.135.107.255 177.135.110.0-177.135.110.255 177.135.135.0-177.135.135.255 177.135.151.0-177.135.151.255 177.135.177.0-177.135.177.255 177.135.245.0-177.135.245.255 177.136.113.0-177.136.113.255 177.136.122.0-177.136.122.255 177.137.225.0-177.137.225.255 177.154.1.0-177.154.1.255 177.154.39.0-177.154.39.255 177.154.223.0-177.154.223.255 177.155.0.0-177.155.0.255 177.155.141.0-177.155.141.255 177.155.163.0-177.155.163.255 177.155.208.0-177.155.208.255 177.159.106.0-177.159.106.255 177.159.161.0-177.159.162.255 177.159.237.0-177.159.237.255 177.183.157.0-177.183.157.255 177.184.128.0-177.184.128.255 177.190.81.0-177.190.81.255 177.190.119.0-177.190.119.255 177.193.95.0-177.193.95.255 177.194.223.0-177.194.223.255 177.200.160.0-177.200.160.255 177.200.184.0-177.200.184.255 177.200.253.0-177.200.253.255 177.207.254.0-177.207.254.255 177.221.73.0-177.221.73.255 177.222.0.0-177.222.0.255 177.222.254.0-177.222.254.255 177.223.13.0-177.223.13.255 177.223.56.0-177.223.56.255 177.233.249.0-177.233.249.255 178.19.252.0-178.19.252.255 178.22.168.0-178.22.168.255 178.23.236.0-178.23.236.255 178.35.137.0-178.35.137.255 178.45.249.0-178.45.249.255 178.45.251.0-178.45.251.255 178.45.253.0-178.45.253.255 178.49.129.0-178.49.129.255 178.49.157.0-178.49.157.255 178.59.100.0-178.59.100.255 178.59.102.0-178.59.102.255 178.60.128.0-178.60.128.255 178.60.195.0-178.60.195.255 178.76.255.0-178.76.255.255 178.88.163.0-178.88.163.255 178.130.15.0-178.130.15.255 178.132.81.0-178.132.81.255 178.134.0.0-178.134.0.255 178.159.49.0-178.159.49.255 178.168.3.0-178.168.3.255 178.209.67.0-178.209.67.255 178.215.223.0-178.215.223.255 178.218.118.0-178.218.118.255 178.235.206.0-178.235.206.255 178.236.130.0-178.236.130.255 178.236.133.0-178.236.133.255 178.248.80.0-178.248.80.255 178.250.208.0-178.250.208.255 178.251.141.0-178.251.141.255 179.1.4.0-179.1.4.255 179.5.71.0-179.5.71.255 179.6.58.0-179.6.58.255 179.6.61.0-179.6.61.255 179.6.63.0-179.6.63.255 179.6.122.0-179.6.122.255 179.6.190.0-179.6.190.255 179.6.254.0-179.6.255.255 179.31.53.0-179.31.53.255 179.49.8.0-179.49.8.255 179.49.15.0-179.49.15.255 179.49.17.0-179.49.17.255 179.49.26.0-179.49.26.255 179.57.193.0-179.57.193.255 179.60.91.0-179.60.91.255 179.62.49.0-179.62.49.255 179.62.81.0-179.62.81.255 179.63.244.0-179.63.244.255 179.96.9.0-179.96.9.255 179.96.24.0-179.96.24.255 179.96.35.0-179.96.35.255 179.96.60.0-179.96.60.255 179.96.250.0-179.96.250.255 179.97.41.0-179.97.42.255 179.97.196.0-179.97.196.255 179.106.0.0-179.106.0.255 179.106.47.0-179.106.47.255 179.106.173.0-179.106.173.255 179.107.0.0-179.107.0.255 179.107.26.0-179.107.26.255 179.108.128.0-179.108.128.255 179.108.192.0-179.108.192.255 179.124.5.0-179.124.5.255 179.124.138.0-179.124.138.255 179.124.224.0-179.124.224.255 179.127.81.0-179.127.81.255 179.127.128.0-179.127.128.255 179.127.142.0-179.127.142.255 179.127.254.0-179.127.254.255 179.154.111.0-179.154.111.255 179.154.159.0-179.154.159.255 179.154.191.0-179.154.191.255 179.155.130.0-179.155.130.255 179.183.24.0-179.183.24.255 179.183.28.0-179.183.28.255 179.184.5.0-179.184.5.255 179.184.10.0-179.184.10.255 179.184.63.0-179.184.63.255 179.184.89.0-179.184.89.255 179.184.115.0-179.184.115.255 179.184.204.0-179.184.204.255 179.185.163.0-179.185.163.255 179.185.194.0-179.185.194.255 179.189.22.0-179.189.22.255 179.189.65.0-179.189.65.255 179.189.182.0-179.189.182.255 179.189.248.0-179.189.248.255 179.190.108.0-179.190.108.255 179.191.16.0-179.191.16.255 179.216.95.0-179.216.95.255 179.216.159.0-179.216.159.255 179.232.3.0-179.232.3.255 179.232.65.0-179.232.65.255 179.232.159.0-179.232.159.255 179.233.130.0-179.233.130.255 179.233.225.0-179.233.225.255 179.234.65.0-179.234.65.255 179.234.143.0-179.234.143.255 179.235.25.0-179.235.25.255 179.235.34.0-179.235.34.255 180.87.217.0-180.87.217.255 180.93.23.0-180.93.23.255 180.93.32.0-180.93.32.255 180.93.80.0-180.93.80.255 180.149.5.0-180.149.5.255 180.149.59.0-180.149.61.255 180.149.91.0-180.149.91.255 180.150.1.0-180.150.1.255 180.188.250.0-180.188.250.255 180.211.201.0-180.211.201.255 180.214.232.0-180.214.232.255 180.234.2.0-180.234.2.255 180.234.129.0-180.234.129.255 181.10.24.0-181.10.24.255 181.10.28.0-181.10.28.255 181.10.135.0-181.10.135.255 181.15.168.0-181.15.168.255 181.15.215.0-181.15.215.255 181.15.220.0-181.15.221.255 181.16.211.0-181.16.211.255 181.30.239.0-181.30.246.255 181.40.16.0-181.40.16.255 181.41.251.0-181.41.251.255 181.47.186.0-181.47.186.255 181.47.248.0-181.47.248.255 181.47.254.0-181.47.254.255 181.48.252.0-181.48.252.255 181.48.254.0-181.48.255.255 181.49.124.0-181.49.124.255 181.49.182.0-181.49.187.255 181.49.192.0-181.49.192.255 181.64.63.0-181.64.63.255 181.64.130.0-181.64.132.255 181.65.115.0-181.65.115.255 181.111.164.0-181.111.164.255 181.114.54.0-181.114.54.255 181.114.113.0-181.114.113.255 181.119.4.0-181.119.4.255 181.174.80.0-181.174.80.255 181.174.127.0-181.174.127.255 181.174.135.0-181.174.135.255 181.176.244.0-181.176.244.255 181.177.20.0-181.177.20.255 181.188.0.0-181.188.0.255 181.189.248.0-181.189.248.255 181.192.0.0-181.192.0.255 181.192.63.0-181.192.63.255 181.197.82.0-181.197.82.255 181.198.79.0-181.198.80.255 181.199.154.0-181.199.154.255 181.199.158.0-181.199.158.255 181.209.15.0-181.209.15.255 181.210.15.0-181.210.15.255 181.224.253.0-181.224.253.255 181.225.140.0-181.225.140.255 182.18.178.0-182.18.178.255 182.48.85.0-182.48.85.255 182.50.68.0-182.50.68.255 182.79.194.0-182.79.194.255 182.79.238.0-182.79.238.255 182.79.251.0-182.79.251.255 182.79.253.0-182.79.254.255 182.163.240.0-182.163.240.255 182.176.41.0-182.176.41.255 182.176.45.0-182.176.45.255 182.176.130.0-182.176.131.255 182.176.138.0-182.176.138.255 182.176.173.0-182.176.173.255 182.239.95.0-182.239.95.255 182.239.127.0-182.239.127.255 182.248.204.0-182.248.204.255 182.253.60.0-182.253.60.255 182.253.220.0-182.253.220.255 183.78.5.0-183.78.5.255 183.78.64.0-183.78.64.255 183.78.96.0-183.78.96.255 183.87.151.0-183.87.151.255 183.91.18.0-183.91.18.255 183.91.188.0-183.91.188.255 183.91.238.0-183.91.238.255 183.182.97.0-183.182.97.255 184.150.152.0-184.150.153.255 184.150.168.0-184.150.168.255 184.150.182.0-184.150.183.255 184.150.186.0-184.150.186.255 184.170.67.0-184.170.67.255 185.2.108.0-185.2.108.255 185.3.1.0-185.3.1.255 185.4.253.0-185.4.253.255 185.5.161.0-185.5.161.255 185.6.12.0-185.6.12.255 185.11.245.0-185.11.245.255 185.13.115.0-185.13.115.255 185.13.132.0-185.13.132.255 185.14.68.0-185.14.68.255 185.16.25.0-185.16.25.255 185.19.98.0-185.19.98.255 185.22.34.0-185.22.34.255 185.23.64.0-185.23.64.255 185.27.107.0-185.27.107.255 185.27.217.0-185.27.217.255 185.34.21.0-185.34.21.255 185.37.85.0-185.37.85.255 185.38.0.0-185.38.0.255 185.38.241.0-185.38.241.255 185.39.160.0-185.39.160.255 185.42.244.0-185.42.244.255 185.48.9.0-185.48.9.255 185.48.127.0-185.48.127.255 185.48.136.0-185.48.136.255 185.51.215.0-185.51.215.255 185.51.222.0-185.51.222.255 185.52.116.0-185.52.116.255 185.52.118.0-185.52.118.255 185.53.235.0-185.53.235.255 185.54.61.0-185.54.61.255 185.54.63.0-185.54.63.255 185.54.255.0-185.54.255.255 185.57.71.0-185.57.71.255 185.58.203.0-185.58.203.255 185.59.69.0-185.59.69.255 185.59.195.0-185.59.195.255 185.61.94.0-185.61.94.255 185.69.7.0-185.69.7.255 185.71.141.0-185.71.141.255 185.73.88.0-185.73.88.255 185.74.230.0-185.74.230.255 185.76.178.0-185.76.178.255 185.78.112.0-185.78.112.255 185.90.125.0-185.90.125.255 185.91.19.0-185.91.19.255 185.91.96.0-185.91.96.255 185.95.204.0-185.95.204.255 185.98.25.0-185.98.25.255 185.99.35.0-185.99.35.255 185.100.209.0-185.100.209.255 185.101.18.0-185.101.18.255 185.104.158.0-185.104.158.255 185.104.254.0-185.104.254.255 185.105.196.0-185.105.196.255 185.112.104.0-185.112.104.255 185.112.190.0-185.112.190.255 185.112.234.0-185.112.234.255 185.117.9.0-185.117.9.255 185.119.13.0-185.119.13.255 185.128.39.0-185.128.39.255 185.135.68.0-185.135.68.255 185.138.120.0-185.138.121.255 186.0.181.0-186.0.181.255 186.0.234.0-186.0.234.255 186.1.18.0-186.1.18.255 186.1.197.0-186.1.197.255 186.2.131.0-186.2.131.255 186.2.134.0-186.2.134.255 186.15.250.0-186.15.251.255 186.16.15.0-186.16.15.255 186.16.31.0-186.16.31.255 186.27.124.0-186.27.124.255 186.31.119.0-186.31.119.255 186.42.100.0-186.42.100.255 186.46.72.0-186.46.72.255 186.46.140.0-186.46.140.255 186.47.201.0-186.47.202.255 186.68.154.0-186.68.154.255 186.68.247.0-186.68.247.255 186.73.72.0-186.73.72.255 186.73.79.0-186.73.79.255 186.96.91.0-186.96.91.255 186.96.222.0-186.96.222.255 186.102.190.0-186.102.191.255 186.124.123.0-186.124.123.255 186.148.159.0-186.148.159.255 186.151.236.0-186.151.236.255 186.160.223.0-186.160.223.255 186.166.151.0-186.166.151.255 186.176.224.0-186.176.224.255 186.177.65.0-186.177.66.255 186.177.192.0-186.177.192.255 186.178.0.0-186.178.0.255 186.179.71.0-186.179.71.255 186.179.252.0-186.179.252.255 186.183.22.0-186.183.22.255 186.192.17.0-186.192.17.255 186.192.145.0-186.192.145.255 186.193.221.0-186.193.221.255 186.194.17.0-186.194.17.255 186.194.48.0-186.194.48.255 186.195.109.0-186.195.109.255 186.207.162.0-186.207.162.255 186.208.1.0-186.208.1.255 186.208.80.0-186.208.80.255 186.208.210.0-186.208.210.255 186.208.225.0-186.208.225.255 186.209.32.0-186.209.32.255 186.209.75.0-186.209.75.255 186.209.78.0-186.209.78.255 186.211.31.0-186.211.31.255 186.211.109.0-186.211.109.255 186.214.37.0-186.214.37.255 186.215.92.0-186.215.92.255 186.215.155.0-186.215.155.255 186.215.194.0-186.215.194.255 186.215.208.0-186.215.208.255 186.216.108.0-186.216.108.255 186.216.190.0-186.216.191.255 186.219.128.0-186.219.128.255 186.219.218.0-186.219.218.255 186.223.131.0-186.223.131.255 186.223.162.0-186.223.162.255 186.223.194.0-186.223.194.255 186.224.227.0-186.224.227.255 186.225.147.0-186.225.147.255 186.225.220.0-186.225.220.255 186.226.128.0-186.226.128.255 186.226.160.0-186.226.160.255 186.226.186.0-186.226.186.255 186.228.156.0-186.228.156.255 186.229.52.0-186.229.53.255 186.229.96.0-186.229.99.255 186.229.127.0-186.229.127.255 186.230.63.0-186.230.63.255 186.231.74.0-186.231.74.255 186.232.44.0-186.232.44.255 186.232.197.0-186.232.197.255 186.233.16.0-186.233.16.255 186.233.72.0-186.233.72.255 186.235.31.0-186.235.31.255 186.235.80.0-186.235.80.255 186.235.144.0-186.235.144.255 186.235.160.0-186.235.160.255 186.235.189.0-186.235.189.255 186.237.52.0-186.237.52.255 186.248.32.0-186.248.32.255 186.249.69.0-186.249.69.255 186.249.163.0-186.249.164.255 186.249.216.0-186.249.216.255 186.250.162.0-186.250.162.255 186.250.215.0-186.250.215.255 186.251.10.0-186.251.10.255 186.251.16.0-186.251.16.255 186.251.179.0-186.251.179.255 186.251.200.0-186.251.200.255 187.1.14.0-187.1.14.255 187.1.17.0-187.1.17.255 187.1.89.0-187.1.89.255 187.1.113.0-187.1.113.255 187.1.185.0-187.1.185.255 187.2.74.0-187.2.74.255 187.2.81.0-187.2.81.255 187.2.95.0-187.2.95.255 187.3.241.0-187.3.241.255 187.7.117.0-187.7.117.255 187.7.130.0-187.7.130.255 187.7.215.0-187.7.215.255 187.7.230.0-187.7.230.255 187.17.48.0-187.17.48.255 187.17.155.0-187.17.155.255 187.18.184.0-187.18.184.255 187.18.187.0-187.18.187.255 187.19.96.0-187.19.96.255 187.19.127.0-187.19.127.255 187.19.145.0-187.19.145.255 187.21.77.0-187.21.77.255 187.22.65.0-187.22.65.255 187.23.64.0-187.23.64.255 187.23.73.0-187.23.73.255 187.23.232.0-187.23.232.255 187.33.50.0-187.33.50.255 187.33.247.0-187.33.247.255 187.36.193.0-187.36.194.255 187.39.177.0-187.39.177.255 187.44.0.0-187.44.0.255 187.44.111.0-187.44.111.255 187.44.155.0-187.44.155.255 187.49.81.0-187.49.81.255 187.49.136.0-187.49.136.255 187.58.66.0-187.58.66.255 187.60.249.0-187.60.249.255 187.61.121.0-187.61.121.255 187.63.166.0-187.63.166.255 187.65.3.0-187.65.3.255 187.66.78.0-187.66.78.255 187.72.192.0-187.72.192.255 187.73.144.0-187.73.144.255 187.85.85.0-187.85.85.255 187.86.12.0-187.86.12.255 187.86.49.0-187.86.49.255 187.86.80.0-187.86.80.255 187.86.180.0-187.86.180.255 187.87.196.0-187.87.196.255 187.87.223.0-187.87.223.255 187.94.94.0-187.94.94.255 187.94.208.0-187.94.208.255 187.95.1.0-187.95.1.255 187.95.255.0-187.95.255.255 187.102.71.0-187.102.71.255 187.102.112.0-187.102.112.255 187.103.72.0-187.103.72.255 187.105.162.0-187.105.162.255 187.106.140.0-187.106.140.255 187.108.224.0-187.108.224.255 187.109.16.0-187.109.16.255 187.109.206.0-187.109.206.255 187.109.238.0-187.109.238.255 187.110.64.0-187.110.64.255 187.110.238.0-187.110.238.255 187.111.81.0-187.111.81.255 187.111.144.0-187.111.144.255 187.114.222.0-187.114.222.255 187.115.146.0-187.115.146.255 187.115.167.0-187.115.167.255 187.120.240.0-187.120.240.255 187.121.160.0-187.121.160.255 187.122.121.0-187.122.121.255 187.122.190.0-187.122.190.255 187.122.250.0-187.122.250.255 187.123.28.0-187.123.28.255 187.123.120.0-187.123.120.255 187.160.243.0-187.160.243.255 187.160.254.0-187.160.254.255 187.162.178.0-187.162.178.255 187.180.31.0-187.180.31.255 187.180.159.0-187.180.159.255 187.181.68.0-187.181.68.255 187.181.125.0-187.181.125.255 187.189.67.0-187.189.67.255 187.189.89.0-187.189.89.255 187.189.157.0-187.189.157.255 187.189.206.0-187.189.206.255 187.190.14.0-187.190.14.255 187.252.80.0-187.252.80.255 187.252.82.0-187.252.84.255 187.254.78.0-187.254.78.255 188.0.128.0-188.0.128.255 188.0.185.0-188.0.185.255 188.21.9.0-188.21.9.255 188.35.142.0-188.35.142.255 188.43.61.0-188.43.61.255 188.43.64.0-188.43.64.255 188.43.66.0-188.43.69.255 188.43.87.0-188.43.87.255 188.43.126.0-188.43.126.255 188.68.163.0-188.68.163.255 188.93.174.0-188.93.174.255 188.112.3.0-188.112.3.255 188.113.128.0-188.113.128.255 188.116.219.0-188.116.220.255 188.130.175.0-188.130.175.255 188.162.160.0-188.162.160.255 188.169.0.0-188.169.0.255 188.191.168.0-188.191.168.255 188.234.130.0-188.234.130.255 188.234.140.0-188.234.140.255 188.244.8.0-188.244.8.255 188.247.240.0-188.247.240.255 188.254.87.0-188.254.87.255 189.1.48.0-189.1.48.255 189.1.145.0-189.1.145.255 189.4.5.0-189.4.5.255 189.4.7.0-189.4.7.255 189.4.66.0-189.4.66.255 189.4.70.0-189.4.70.255 189.5.53.0-189.5.53.255 189.5.130.0-189.5.130.255 189.6.76.0-189.6.76.255 189.7.8.0-189.7.8.255 189.7.16.0-189.7.16.255 189.7.75.0-189.7.75.255 189.7.104.0-189.7.104.255 189.7.112.0-189.7.112.255 189.7.120.0-189.7.120.255 189.7.128.0-189.7.128.255 189.7.176.0-189.7.176.255 189.7.184.0-189.7.184.255 189.7.200.0-189.7.200.255 189.7.208.0-189.7.208.255 189.7.216.0-189.7.216.255 189.14.52.0-189.14.52.255 189.14.78.0-189.14.78.255 189.26.123.0-189.26.123.255 189.28.163.0-189.28.163.255 189.31.143.0-189.31.143.255 189.34.253.0-189.34.253.255 189.38.33.0-189.38.33.255 189.39.116.0-189.39.116.255 189.39.126.0-189.39.126.255 189.39.153.0-189.39.153.255 189.39.192.0-189.39.192.255 189.45.15.0-189.45.15.255 189.45.193.0-189.45.193.255 189.50.145.0-189.50.145.255 189.51.127.0-189.51.127.255 189.51.155.0-189.51.155.255 189.55.196.0-189.55.196.255 189.58.99.0-189.58.99.255 189.59.93.0-189.59.93.255 189.63.251.0-189.63.251.255 189.73.192.0-189.73.192.255 189.76.142.0-189.76.142.255 189.84.66.0-189.84.66.255 189.85.81.0-189.85.81.255 189.86.41.0-189.86.41.255 189.89.27.0-189.89.27.255 189.89.161.0-189.89.161.255 189.90.45.0-189.90.45.255 189.90.96.0-189.90.96.255 189.90.243.0-189.90.243.255 189.91.114.0-189.91.114.255 189.103.27.0-189.103.27.255 189.103.191.0-189.103.191.255 189.112.10.0-189.112.10.255 189.113.79.0-189.113.79.255 189.115.42.0-189.115.42.255 189.124.80.0-189.124.80.255 189.124.133.0-189.124.133.255 189.126.48.0-189.126.48.255 189.126.224.0-189.126.224.255 189.193.189.0-189.193.189.255 189.194.54.0-189.194.54.255 189.194.93.0-189.194.94.255 189.194.132.0-189.194.132.255 189.194.236.0-189.194.236.255 189.195.42.0-189.195.42.255 189.195.64.0-189.195.64.255 189.195.96.0-189.195.96.255 189.195.131.0-189.195.131.255 189.195.168.0-189.195.168.255 189.195.222.0-189.195.222.255 189.196.29.0-189.196.29.255 189.196.168.0-189.196.168.255 189.196.189.0-189.196.189.255 189.197.62.0-189.197.62.255 189.197.77.0-189.197.77.255 189.197.79.0-189.197.79.255 189.197.168.0-189.197.168.255 189.197.190.0-189.197.191.255 189.198.130.0-189.198.130.255 189.198.141.0-189.198.141.255 189.198.158.0-189.198.158.255 189.198.236.0-189.198.236.255 189.198.250.0-189.198.250.255 189.199.19.0-189.199.19.255 189.199.71.0-189.199.71.255 189.199.81.0-189.199.81.255 189.199.103.0-189.199.103.255 189.199.105.0-189.199.105.255 189.199.250.0-189.199.250.255 189.203.151.0-189.203.151.255 189.203.155.0-189.203.155.255 189.203.166.0-189.203.168.255 189.203.232.0-189.203.232.255 189.204.116.0-189.204.116.255 189.205.57.0-189.205.57.255 189.212.93.0-189.212.93.255 189.215.132.0-189.215.132.255 189.215.134.0-189.215.134.255 189.215.200.0-189.215.200.255 189.216.0.0-189.216.0.255 189.216.4.0-189.216.4.255 189.218.235.0-189.218.235.255 189.247.132.0-189.247.138.255 189.247.140.0-189.247.143.255 189.247.145.0-189.247.145.255 189.247.147.0-189.247.155.255 189.247.160.0-189.247.161.255 189.247.168.0-189.247.169.255 190.0.175.0-190.0.175.255 190.2.82.0-190.2.82.255 190.5.159.0-190.5.159.255 190.5.171.0-190.5.171.255 190.5.191.0-190.5.191.255 190.5.222.0-190.5.222.255 190.5.235.0-190.5.235.255 190.6.220.0-190.6.220.255 190.6.222.0-190.6.222.255 190.8.63.0-190.8.63.255 190.11.146.0-190.11.146.255 190.13.226.0-190.13.226.255 190.14.163.0-190.14.163.255 190.15.32.0-190.15.32.255 190.15.100.0-190.15.100.255 190.45.0.0-190.45.0.255 190.52.39.0-190.52.39.255 190.52.206.0-190.52.206.255 190.54.2.0-190.54.2.255 190.55.61.0-190.55.61.255 190.56.231.0-190.56.231.255 190.57.158.0-190.57.158.255 190.58.136.0-190.58.136.255 190.63.32.0-190.63.32.255 190.63.135.0-190.63.135.255 190.82.63.0-190.82.63.255 190.92.11.0-190.92.11.255 190.92.20.0-190.92.20.255 190.92.89.0-190.92.89.255 190.94.74.0-190.94.74.255 190.94.130.0-190.94.130.255 190.94.176.0-190.94.176.255 190.96.8.0-190.96.8.255 190.96.100.0-190.96.100.255 190.97.0.0-190.97.0.255 190.99.74.0-190.99.74.255 190.102.57.0-190.102.57.255 190.103.183.0-190.103.183.255 190.103.220.0-190.103.220.255 190.104.6.0-190.104.7.255 190.104.150.0-190.104.150.255 190.104.250.0-190.104.250.255 190.107.224.0-190.107.224.255 190.108.82.0-190.108.82.255 190.110.97.0-190.110.97.255 190.112.180.0-190.112.180.255 190.112.219.0-190.112.219.255 190.113.97.0-190.113.97.255 190.115.112.0-190.115.112.255 190.116.191.0-190.116.191.255 190.120.207.0-190.120.207.255 190.121.11.0-190.121.11.255 190.121.104.0-190.121.104.255 190.121.155.0-190.121.155.255 190.121.237.0-190.121.237.255 190.122.64.0-190.122.64.255 190.122.192.0-190.122.192.255 190.123.95.0-190.123.95.255 190.124.161.0-190.124.161.255 190.129.124.0-190.129.124.255 190.142.193.0-190.142.193.255 190.143.134.0-190.143.134.255 190.145.255.0-190.145.255.255 190.150.50.0-190.150.50.255 190.153.58.0-190.153.58.255 190.160.0.0-190.160.0.255 190.164.254.0-190.164.254.255 190.166.8.0-190.166.8.255 190.166.41.0-190.166.41.255 190.167.204.0-190.167.204.255 190.167.241.0-190.167.241.255 190.181.111.0-190.181.111.255 190.182.24.0-190.182.24.255 190.183.231.0-190.183.231.255 190.184.224.0-190.184.224.255 190.184.255.0-190.184.255.255 190.186.210.0-190.186.210.255 190.197.65.0-190.197.65.255 190.208.14.0-190.208.14.255 190.210.113.0-190.210.113.255 190.211.101.0-190.211.101.255 190.211.175.0-190.211.175.255 190.212.166.0-190.212.166.255 190.216.191.0-190.216.191.255 190.217.154.0-190.217.154.255 190.235.154.0-190.235.155.255 190.238.117.0-190.238.117.255 190.240.1.0-190.240.2.255 190.240.6.0-190.240.6.255 190.241.121.0-190.241.121.255 190.248.1.0-190.248.1.255 190.248.34.0-190.248.35.255 191.5.47.0-191.5.47.255 191.5.198.0-191.5.198.255 191.6.20.0-191.6.20.255 191.6.136.0-191.6.136.255 191.7.28.0-191.7.28.255 191.7.51.0-191.7.51.255 191.7.136.0-191.7.136.255 191.7.213.0-191.7.213.255 191.32.26.0-191.32.26.255 191.32.58.0-191.32.58.255 191.32.235.0-191.32.235.255 191.33.82.0-191.33.82.255 191.33.177.0-191.33.177.255 191.33.230.0-191.33.230.255 191.34.35.0-191.34.35.255 191.34.161.0-191.34.161.255 191.34.252.0-191.34.252.255 191.37.0.0-191.37.0.255 191.37.167.0-191.37.167.255 191.98.136.0-191.98.136.255 191.99.254.0-191.99.255.255 191.103.96.0-191.103.96.255 191.103.126.0-191.103.126.255 191.179.1.0-191.179.1.255 191.183.80.0-191.183.80.255 191.187.224.0-191.187.224.255 191.189.255.0-191.189.255.255 191.240.237.0-191.240.237.255 191.241.237.0-191.241.237.255 191.242.112.0-191.242.112.255 191.242.179.0-191.242.179.255 191.243.156.0-191.243.157.255 191.250.26.0-191.250.26.255 191.251.119.0-191.251.119.255 191.251.192.0-191.251.192.255 191.251.197.0-191.251.197.255 191.253.208.0-191.253.208.255 192.31.228.0-192.31.228.255 192.70.222.0-192.70.222.255 192.116.22.0-192.116.22.255 192.119.20.0-192.119.21.255 192.119.28.0-192.119.28.255 192.122.185.0-192.122.185.255 192.124.225.0-192.124.225.255 192.124.233.0-192.124.233.255 192.154.121.0-192.154.121.255 192.189.138.0-192.189.138.255 192.225.241.0-192.225.241.255 192.232.16.0-192.232.16.255 192.248.3.0-192.248.3.255 192.254.96.0-192.254.96.255 193.0.255.0-193.0.255.255 193.4.115.0-193.4.115.255 193.28.236.0-193.28.236.255 193.33.240.0-193.33.240.255 193.51.224.0-193.51.224.255 193.90.147.0-193.90.147.255 193.92.133.0-193.92.133.255 193.95.12.0-193.95.13.255 193.95.144.0-193.95.144.255 193.134.255.0-193.134.255.255 193.170.141.0-193.170.141.255 193.189.184.0-193.189.184.255 193.192.226.0-193.192.226.255 193.192.250.0-193.192.250.255 193.206.135.0-193.206.135.255 193.212.4.0-193.212.4.255 193.229.108.0-193.229.108.255 194.9.24.0-194.9.25.255 194.24.134.0-194.24.134.255 194.44.4.0-194.44.4.255 194.54.234.0-194.54.234.255 194.78.0.0-194.78.0.255 194.78.99.0-194.78.99.255 194.90.196.0-194.90.196.255 194.106.173.0-194.106.173.255 194.116.101.0-194.116.101.255 194.122.80.0-194.122.80.255 194.122.82.0-194.122.82.255 194.134.26.0-194.134.26.255 194.150.129.0-194.150.129.255 194.158.92.0-194.158.92.255 194.182.232.0-194.182.232.255 194.183.149.0-194.183.149.255 194.199.78.0-194.199.78.255 194.210.238.0-194.210.238.255 195.8.11.0-195.8.12.255 195.12.176.0-195.12.177.255 195.13.189.0-195.13.189.255 195.13.231.0-195.13.231.255 195.14.151.0-195.14.151.255 195.14.153.0-195.14.153.255 195.39.213.0-195.39.213.255 195.43.73.0-195.43.73.255 195.46.107.0-195.46.107.255 195.46.177.0-195.46.177.255 195.49.27.0-195.49.27.255 195.64.213.0-195.64.213.255 195.72.240.0-195.72.240.255 195.78.217.0-195.78.217.255 195.80.179.0-195.80.179.255 195.94.233.0-195.94.233.255 195.95.178.0-195.95.178.255 195.98.65.0-195.98.65.255 195.111.111.0-195.111.111.255 195.113.214.0-195.113.214.255 195.122.16.0-195.122.16.255 195.122.30.0-195.122.30.255 195.162.39.0-195.162.39.255 195.176.255.0-195.176.255.255 195.177.197.0-195.177.197.255 195.187.242.0-195.187.242.255 195.191.238.0-195.191.238.255 195.202.131.0-195.202.131.255 195.208.12.0-195.208.12.255 195.216.237.0-195.216.237.255 195.218.169.0-195.218.169.255 195.239.122.0-195.239.122.255 195.249.20.0-195.249.20.255 195.249.23.0-195.249.23.255 196.0.3.0-196.0.3.255 196.23.168.0-196.23.168.255 196.27.66.0-196.27.66.255 196.29.35.0-196.29.35.255 196.44.149.0-196.44.149.255 196.46.1.0-196.46.1.255 196.46.123.0-196.46.123.255 196.49.8.0-196.49.8.255 196.201.223.0-196.201.223.255 196.202.246.0-196.202.246.255 196.203.81.0-196.203.81.255 196.203.102.0-196.203.102.255 196.203.188.0-196.203.188.255 196.204.32.0-196.204.32.255 196.207.198.0-196.207.198.255 197.136.0.0-197.136.0.255 197.149.150.0-197.149.150.255 197.155.95.0-197.155.95.255 197.157.244.0-197.157.244.255 197.158.80.0-197.158.80.255 197.159.29.0-197.159.29.255 197.160.155.0-197.160.155.255 197.199.183.0-197.199.183.255 197.199.253.0-197.199.254.255 197.218.0.0-197.218.0.255 197.220.0.0-197.220.0.255 197.221.233.0-197.221.233.255 197.232.44.0-197.232.44.255 197.235.0.0-197.235.0.255 197.243.124.0-197.243.124.255 197.251.230.0-197.251.230.255 197.253.18.0-197.253.18.255 198.7.237.0-198.7.237.255 198.20.48.0-198.20.48.255 198.32.232.0-198.32.232.255 198.49.182.0-198.49.182.255 198.52.15.0-198.52.15.255 198.70.66.0-198.70.71.255 198.70.244.0-198.70.250.255 198.92.97.0-198.92.97.255 198.142.187.0-198.142.187.255 198.231.29.0-198.231.29.255 198.235.201.0-198.235.201.255 198.236.245.0-198.236.245.255 199.36.119.0-199.36.119.255 199.47.189.0-199.47.189.255 199.59.103.0-199.59.103.255 199.83.198.0-199.83.198.255 199.85.229.0-199.85.229.255 199.85.252.0-199.85.252.255 199.102.192.0-199.102.192.255 199.180.84.0-199.180.84.255 199.185.92.0-199.185.92.255 199.192.116.0-199.192.116.255 199.212.24.0-199.212.24.255 199.241.168.0-199.241.168.255 199.244.212.0-199.244.212.255 200.0.56.0-200.0.56.255 200.2.125.0-200.2.125.255 200.3.21.0-200.3.21.255 200.3.169.0-200.3.169.255 200.7.94.0-200.7.94.255 200.7.182.0-200.7.182.255 200.7.241.0-200.7.241.255 200.10.177.0-200.10.177.255 200.10.225.0-200.10.226.255 200.11.154.0-200.11.154.255 200.14.228.0-200.14.229.255 200.16.69.0-200.16.69.255 200.17.7.0-200.17.7.255 200.26.170.0-200.26.170.255 200.28.0.0-200.28.0.255 200.28.6.0-200.28.12.255 200.29.113.0-200.29.113.255 200.29.255.0-200.29.255.255 200.30.192.0-200.30.193.255 200.31.96.0-200.31.96.255 200.33.115.0-200.33.115.255 200.36.99.0-200.36.99.255 200.40.3.0-200.40.3.255 200.40.172.0-200.40.172.255 200.42.246.0-200.42.246.255 200.49.63.0-200.49.63.255 200.49.120.0-200.49.120.255 200.49.185.0-200.49.185.255 200.50.67.0-200.50.67.255 200.50.171.0-200.50.171.255 200.50.241.0-200.50.241.255 200.50.248.0-200.50.248.255 200.52.21.0-200.52.21.255 200.53.245.0-200.53.245.255 200.55.230.0-200.55.230.255 200.56.193.0-200.56.193.255 200.58.65.0-200.58.65.255 200.59.113.0-200.59.113.255 200.62.26.0-200.62.26.255 200.63.105.0-200.63.105.255 200.63.120.0-200.63.120.255 200.63.214.0-200.63.214.255 200.73.1.0-200.73.1.255 200.75.201.0-200.75.201.255 200.77.120.0-200.77.120.255 200.77.137.0-200.77.137.255 200.77.139.0-200.77.139.255 200.77.168.0-200.77.168.255 200.77.222.0-200.77.222.255 200.81.125.0-200.81.125.255 200.85.99.0-200.85.99.255 200.89.75.0-200.89.75.255 200.90.6.0-200.90.6.255 200.90.46.0-200.90.46.255 200.91.33.0-200.91.33.255 200.92.227.0-200.92.227.255 200.94.238.0-200.94.238.255 200.97.85.0-200.97.85.255 200.104.251.0-200.104.251.255 200.104.253.0-200.104.253.255 200.105.131.0-200.105.131.255 200.107.255.0-200.107.255.255 200.108.53.0-200.108.53.255 200.109.224.0-200.109.224.255 200.110.122.0-200.110.122.255 200.110.188.0-200.110.188.255 200.112.190.0-200.112.190.255 200.113.255.0-200.113.255.255 200.114.47.0-200.114.47.255 200.115.86.0-200.115.90.255 200.115.92.0-200.115.94.255 200.123.36.0-200.123.36.255 200.124.254.0-200.124.254.255 200.129.233.0-200.129.233.255 200.130.63.0-200.130.63.255 200.131.47.0-200.131.47.255 200.133.23.0-200.133.23.255 200.141.140.0-200.141.140.255 200.142.191.0-200.142.191.255 200.144.184.0-200.144.184.255 200.149.119.0-200.149.119.255 200.150.4.0-200.150.4.255 200.152.250.0-200.152.251.255 200.160.96.0-200.160.97.255 200.160.104.0-200.160.104.255 200.165.96.0-200.165.96.255 200.169.124.0-200.169.124.255 200.172.62.0-200.172.62.255 200.175.185.0-200.175.185.255 200.175.196.0-200.175.196.255 200.175.224.0-200.175.224.255 200.187.83.0-200.187.83.255 200.187.85.0-200.187.85.255 200.188.128.0-200.188.128.255 200.189.63.0-200.189.63.255 200.189.87.0-200.189.87.255 200.195.155.0-200.195.155.255 200.195.190.0-200.195.190.255 200.199.211.0-200.199.211.255 200.216.39.0-200.216.39.255 200.216.56.0-200.216.56.255 200.216.90.0-200.216.90.255 200.220.141.0-200.220.141.255 200.229.223.0-200.229.223.255 200.237.143.0-200.237.143.255 200.240.237.0-200.240.237.255 201.0.223.0-201.0.225.255 201.0.228.0-201.0.229.255 201.0.231.0-201.0.232.255 201.0.235.0-201.0.238.255 201.0.240.0-201.0.240.255 201.0.244.0-201.0.246.255 201.0.248.0-201.0.250.255 201.6.8.0-201.6.8.255 201.6.16.0-201.6.16.255 201.6.48.0-201.6.48.255 201.16.48.0-201.16.48.255 201.16.57.0-201.16.57.255 201.16.59.0-201.16.59.255 201.16.134.0-201.16.134.255 201.17.29.0-201.17.31.255 201.17.165.0-201.17.165.255 201.17.170.0-201.17.170.255 201.20.107.0-201.20.107.255 201.20.117.0-201.20.117.255 201.21.214.0-201.21.215.255 201.23.161.0-201.23.161.255 201.30.4.0-201.30.4.255 201.31.84.0-201.31.84.255 201.33.170.0-201.33.170.255 201.33.232.0-201.33.232.255 201.33.240.0-201.33.240.255 201.34.205.0-201.34.205.255 201.46.241.0-201.46.241.255 201.46.252.0-201.46.252.255 201.47.112.0-201.47.112.255 201.47.158.0-201.47.158.255 201.48.53.0-201.48.53.255 201.48.56.0-201.48.56.255 201.49.80.0-201.49.81.255 201.49.97.0-201.49.97.255 201.54.66.0-201.54.66.255 201.54.166.0-201.54.166.255 201.55.137.0-201.55.137.255 201.55.233.0-201.55.233.255 201.56.167.0-201.56.167.255 201.57.54.0-201.57.54.255 201.57.60.0-201.57.60.255 201.57.89.0-201.57.89.255 201.57.155.0-201.57.155.255 201.57.227.0-201.57.227.255 201.62.48.0-201.62.48.255 201.64.116.0-201.64.116.255 201.64.241.0-201.64.241.255 201.67.193.0-201.67.193.255 201.76.0.0-201.76.0.255 201.76.28.0-201.76.28.255 201.76.65.0-201.76.65.255 201.77.64.0-201.77.64.255 201.77.112.0-201.77.112.255 201.82.12.0-201.82.12.255 201.82.108.0-201.82.108.255 201.86.233.0-201.86.233.255 201.87.209.0-201.87.209.255 201.94.160.0-201.94.160.255 201.94.177.0-201.94.177.255 201.130.49.0-201.130.49.255 201.130.51.0-201.130.53.255 201.130.196.0-201.130.196.255 201.130.208.0-201.130.208.255 201.132.92.0-201.132.92.255 201.132.200.0-201.132.201.255 201.148.102.0-201.148.102.255 201.148.124.0-201.148.124.255 201.149.62.0-201.149.62.255 201.150.255.0-201.150.255.255 201.151.207.0-201.151.207.255 201.157.30.0-201.157.30.255 201.157.200.0-201.157.201.255 201.159.220.0-201.159.220.255 201.162.64.0-201.162.64.255 201.163.0.0-201.163.0.255 201.163.253.0-201.163.253.255 201.165.0.0-201.165.0.255 201.165.116.0-201.165.116.255 201.165.118.0-201.165.118.255 201.165.221.0-201.165.221.255 201.165.255.0-201.165.255.255 201.167.5.0-201.167.5.255 201.167.51.0-201.167.51.255 201.167.56.0-201.167.56.255 201.167.64.0-201.167.64.255 201.167.93.0-201.167.93.255 201.168.67.0-201.168.67.255 201.173.124.0-201.173.124.255 201.174.48.0-201.174.48.255 201.174.77.0-201.174.77.255 201.174.82.0-201.174.82.255 201.174.96.0-201.174.98.255 201.174.112.0-201.174.112.255 201.175.77.0-201.175.77.255 201.191.202.0-201.191.202.255 201.191.214.0-201.191.214.255 201.215.120.0-201.215.120.255 201.217.3.0-201.217.3.255 201.217.205.0-201.217.205.255 201.217.246.0-201.217.246.255 201.218.56.0-201.218.56.255 201.218.65.0-201.218.65.255 201.219.100.0-201.219.100.255 201.220.160.0-201.220.160.255 201.221.95.0-201.221.95.255 201.221.130.0-201.221.130.255 201.227.61.0-201.227.61.255 201.229.1.0-201.229.1.255 201.230.36.0-201.230.36.255 201.241.118.0-201.241.118.255 201.248.76.0-201.248.76.255 201.248.78.0-201.248.78.255 202.3.240.0-202.3.240.255 202.4.173.0-202.4.173.255 202.28.85.0-202.28.85.255 202.28.87.0-202.28.87.255 202.38.180.0-202.38.180.255 202.39.143.0-202.39.143.255 202.40.221.0-202.40.221.255 202.51.65.0-202.51.65.255 202.51.67.0-202.51.67.255 202.51.73.0-202.51.73.255 202.51.247.0-202.51.247.255 202.56.33.0-202.56.33.255 202.58.96.0-202.58.97.255 202.60.105.0-202.60.105.255 202.62.92.0-202.62.92.255 202.67.33.0-202.67.33.255 202.67.35.0-202.67.35.255 202.67.37.0-202.67.37.255 202.67.39.0-202.67.39.255 202.67.43.0-202.67.43.255 202.67.46.0-202.67.47.255 202.69.11.0-202.69.12.255 202.69.15.0-202.69.15.255 202.69.185.0-202.69.185.255 202.70.50.0-202.70.50.255 202.71.1.0-202.71.1.255 202.75.141.0-202.75.141.255 202.75.147.0-202.75.147.255 202.75.191.0-202.75.191.255 202.78.83.0-202.78.83.255 202.78.113.0-202.78.113.255 202.86.162.0-202.86.162.255 202.88.68.0-202.88.68.255 202.88.147.0-202.88.147.255 202.88.152.0-202.88.152.255 202.88.157.0-202.88.157.255 202.88.175.0-202.88.175.255 202.88.186.0-202.88.186.255 202.88.193.0-202.88.193.255 202.89.241.0-202.89.241.255 202.90.152.0-202.90.152.255 202.90.156.0-202.90.156.255 202.93.153.0-202.93.153.255 202.122.145.0-202.122.146.255 202.124.127.0-202.124.127.255 202.128.15.0-202.128.15.255 202.129.8.0-202.129.8.255 202.129.236.0-202.129.236.255 202.134.14.0-202.134.14.255 202.136.91.0-202.136.91.255 202.141.239.0-202.141.239.255 202.142.160.0-202.142.160.255 202.142.224.0-202.142.225.255 202.144.191.0-202.144.191.255 202.148.204.0-202.148.204.255 202.151.87.0-202.151.87.255 202.152.47.0-202.152.47.255 202.152.130.0-202.152.130.255 202.153.85.0-202.153.85.255 202.155.135.0-202.155.135.255 202.158.57.0-202.158.57.255 202.160.9.0-202.160.9.255 202.163.106.0-202.163.106.255 202.163.122.0-202.163.122.255 202.163.174.0-202.163.174.255 202.166.193.0-202.166.193.255 202.168.156.0-202.168.156.255 202.169.173.0-202.169.173.255 202.169.175.0-202.169.175.255 202.169.193.0-202.169.193.255 202.179.1.0-202.179.1.255 202.181.19.0-202.181.19.255 202.208.170.0-202.208.170.255 202.216.0.0-202.216.0.255 202.220.161.0-202.220.161.255 202.224.62.0-202.224.62.255 202.224.83.0-202.224.83.255 202.231.177.0-202.231.177.255 202.248.151.0-202.248.151.255 202.248.248.0-202.248.248.255 203.5.76.0-203.5.76.255 203.13.161.0-203.13.161.255 203.66.124.0-203.66.124.255 203.66.155.0-203.66.155.255 203.66.169.0-203.66.169.255 203.66.180.0-203.66.180.255 203.66.182.0-203.66.182.255 203.78.32.0-203.78.32.255 203.78.36.0-203.78.37.255 203.79.253.0-203.79.253.255 203.82.75.0-203.82.77.255 203.82.82.0-203.82.82.255 203.82.95.0-203.82.95.255 203.91.113.0-203.91.113.255 203.94.209.0-203.94.209.255 203.94.229.0-203.94.229.255 203.99.50.0-203.99.50.255 203.109.178.0-203.109.178.255 203.113.48.0-203.113.53.255 203.113.55.0-203.113.55.255 203.113.76.0-203.113.81.255 203.113.129.0-203.113.130.255 203.113.160.0-203.113.163.255 203.113.189.0-203.113.189.255 203.114.135.0-203.114.135.255 203.116.165.0-203.116.165.255 203.116.189.0-203.116.189.255 203.117.34.0-203.117.35.255 203.118.141.0-203.118.141.255 203.118.143.0-203.118.143.255 203.118.245.0-203.118.245.255 203.121.59.0-203.121.59.255 203.121.225.0-203.121.225.255 203.133.8.0-203.133.8.255 203.133.72.0-203.133.72.255 203.139.206.0-203.139.206.255 203.142.74.0-203.142.74.255 203.145.84.0-203.145.84.255 203.146.98.0-203.146.98.255 203.151.116.0-203.151.116.255 203.152.112.0-203.152.112.255 203.165.13.0-203.165.14.255 203.171.242.0-203.171.242.255 203.176.177.0-203.176.178.255 203.184.5.0-203.184.5.255 203.184.7.0-203.184.7.255 203.189.185.0-203.189.185.255 203.192.208.0-203.192.208.255 203.207.55.0-203.207.55.255 203.210.6.0-203.210.8.255 203.211.0.0-203.211.0.255 203.211.8.0-203.211.8.255 203.217.98.0-203.217.98.255 203.223.36.0-203.223.36.255 203.233.10.0-203.233.10.255 203.233.18.0-203.233.18.255 203.233.37.0-203.233.37.255 203.233.63.0-203.233.63.255 203.233.88.0-203.233.88.255 203.233.92.0-203.233.92.255 203.233.96.0-203.233.96.255 203.233.126.0-203.233.126.255 203.248.132.0-203.248.132.255 203.248.180.0-203.248.180.255 203.248.210.0-203.248.210.255 203.252.15.0-203.252.15.255 204.9.80.0-204.9.80.255 204.11.134.0-204.11.134.255 204.17.140.0-204.17.140.255 204.85.30.0-204.85.30.255 204.111.84.0-204.111.84.255 204.116.80.0-204.116.80.255 204.186.48.0-204.186.48.255 204.186.55.0-204.186.55.255 204.186.215.0-204.186.215.255 204.239.67.0-204.239.67.255 205.144.216.0-205.144.216.255 205.158.11.0-205.158.11.255 205.213.108.0-205.213.108.255 205.213.114.0-205.213.114.255 205.237.38.0-205.237.38.255 205.237.60.0-205.237.60.255 206.40.112.0-206.40.112.255 206.71.231.0-206.71.231.255 206.80.249.0-206.80.249.255 206.82.17.0-206.82.17.255 206.117.11.0-206.117.11.255 206.124.214.0-206.124.214.255 206.126.112.0-206.126.112.255 206.131.134.0-206.131.134.255 206.166.0.0-206.166.0.255 206.167.212.0-206.167.212.255 206.167.221.0-206.167.221.255 206.181.8.0-206.181.8.255 206.192.244.0-206.192.244.255 206.223.218.0-206.223.218.255 206.248.149.0-206.248.149.255 206.248.151.0-206.248.151.255 206.248.169.0-206.248.169.255 207.34.103.0-207.34.103.255 207.47.131.0-207.47.131.255 207.70.147.0-207.70.147.255 207.134.64.0-207.134.64.255 207.172.61.0-207.172.61.255 207.172.159.0-207.172.159.255 207.172.193.0-207.172.193.255 207.173.228.0-207.173.228.255 207.181.192.0-207.181.192.255 207.191.178.0-207.191.178.255 207.192.195.0-207.192.195.255 207.192.241.0-207.192.241.255 207.204.159.0-207.204.159.255 207.219.213.0-207.219.213.255 207.229.143.0-207.229.143.255 207.237.69.0-207.237.69.255 207.238.18.0-207.238.18.255 207.238.252.0-207.238.252.255 207.248.95.0-207.248.95.255 207.255.26.0-207.255.26.255 208.49.194.0-208.49.194.255 208.53.243.0-208.53.243.255 208.54.2.0-208.54.2.255 208.54.4.0-208.54.4.255 208.54.16.0-208.54.19.255 208.54.34.0-208.54.34.255 208.54.66.0-208.54.66.255 208.54.74.0-208.54.74.255 208.64.172.0-208.64.172.255 208.65.152.0-208.65.152.255 208.65.155.0-208.65.155.255 208.66.189.0-208.66.189.255 208.66.246.0-208.66.246.255 208.68.35.0-208.68.35.255 208.73.255.0-208.73.255.255 208.77.78.0-208.77.78.255 208.84.221.0-208.84.221.255 208.90.107.0-208.90.107.255 208.93.196.0-208.93.196.255 208.104.242.0-208.104.242.255 208.111.59.0-208.111.59.255 208.117.225.0-208.117.229.255 208.117.233.0-208.117.233.255 208.117.240.0-208.117.240.255 208.117.243.0-208.117.244.255 208.117.246.0-208.117.246.255 208.117.249.0-208.117.249.255 208.117.253.0-208.117.253.255 208.124.110.0-208.124.110.255 208.138.46.0-208.138.46.255 208.180.1.0-208.180.1.255 208.180.32.0-208.180.32.255 208.180.168.0-208.180.168.255 208.181.12.0-208.181.12.255 208.187.128.0-208.187.128.255 209.33.32.0-209.33.32.255 209.33.235.0-209.33.235.255 209.52.144.0-209.52.144.255 209.52.146.0-209.52.146.255 209.52.189.0-209.52.189.255 209.55.113.0-209.55.113.255 209.56.124.0-209.56.124.255 209.81.111.0-209.81.111.255 209.85.144.0-209.85.145.255 209.85.147.0-209.85.147.255 209.85.164.0-209.85.165.255 209.85.200.0-209.85.203.255 209.85.224.0-209.85.235.255 209.85.239.0-209.85.239.255 209.90.173.0-209.90.173.255 209.91.104.0-209.91.105.255 209.91.176.0-209.91.176.255 209.91.216.0-209.91.216.255 209.115.217.0-209.115.217.255 209.116.150.0-209.116.150.255 209.116.186.0-209.116.186.255 209.118.7.0-209.118.7.255 209.118.99.0-209.118.99.255 209.118.208.0-209.118.208.255 209.131.254.0-209.131.254.255 209.132.160.0-209.132.160.255 209.141.120.0-209.141.121.255 209.143.6.0-209.143.6.255 209.145.112.0-209.145.112.255 209.148.113.0-209.148.113.255 209.148.195.0-209.148.196.255 209.148.198.0-209.148.199.255 209.148.210.0-209.148.210.255 209.183.147.0-209.183.147.255 209.191.218.0-209.191.218.255 209.221.59.0-209.221.59.255 209.221.127.0-209.221.127.255 209.226.57.0-209.226.57.255 210.1.255.0-210.1.255.255 210.2.177.0-210.2.177.255 210.7.45.0-210.7.45.255 210.19.223.0-210.19.223.255 210.61.221.0-210.61.221.255 210.92.119.0-210.92.119.255 210.94.153.0-210.94.153.255 210.139.253.0-210.139.253.255 210.143.70.0-210.143.70.255 210.143.147.0-210.143.147.255 210.158.146.0-210.158.146.255 210.171.10.0-210.171.10.255 210.187.22.0-210.187.22.255 210.187.25.0-210.187.25.255 210.191.74.0-210.191.74.255 210.209.18.0-210.209.18.255 210.236.185.0-210.236.185.255 210.242.125.0-210.242.125.255 210.242.127.0-210.242.128.255 210.245.14.0-210.245.14.255 210.253.46.0-210.253.46.255 211.1.149.0-211.1.149.255 211.49.146.0-211.49.146.255 211.76.107.0-211.76.107.255 211.76.114.0-211.76.114.255 211.76.116.0-211.76.117.255 211.76.123.0-211.76.123.255 211.77.50.0-211.77.50.255 211.117.39.0-211.117.39.255 211.124.13.0-211.124.13.255 211.175.187.0-211.175.187.255 211.239.234.0-211.239.234.255 212.0.195.0-212.0.195.255 212.1.249.0-212.1.250.255 212.2.108.0-212.2.108.255 212.6.83.0-212.6.83.255 212.9.14.0-212.9.14.255 212.10.212.0-212.10.212.255 212.19.24.0-212.19.24.255 212.20.18.0-212.20.18.255 212.29.228.0-212.29.228.255 212.30.5.0-212.30.5.255 212.33.231.0-212.33.231.255 212.34.3.0-212.34.3.255 212.34.13.0-212.34.13.255 212.39.82.0-212.39.82.255 212.40.1.0-212.40.1.255 212.40.34.0-212.40.34.255 212.40.98.0-212.40.98.255 212.40.135.0-212.40.135.255 212.42.193.0-212.42.193.255 212.43.1.0-212.43.1.255 212.52.60.0-212.52.60.255 212.56.131.0-212.56.132.255 212.57.191.0-212.57.191.255 212.73.69.0-212.73.70.255 212.76.17.0-212.76.17.255 212.88.109.0-212.88.109.255 212.89.5.0-212.89.5.255 212.92.207.0-212.92.207.255 212.96.65.0-212.96.65.255 212.96.85.0-212.96.85.255 212.96.93.0-212.96.94.255 212.104.78.0-212.104.78.255 212.106.207.0-212.106.207.255 212.106.221.0-212.106.221.255 212.109.17.0-212.109.17.255 212.109.19.0-212.109.19.255 212.112.37.0-212.112.37.255 212.112.117.0-212.112.117.255 212.113.49.0-212.113.49.255 212.113.52.0-212.113.52.255 212.113.185.0-212.113.185.255 212.120.241.0-212.120.241.255 212.122.6.0-212.122.6.255 212.122.14.0-212.122.14.255 212.126.109.0-212.126.109.255 212.126.115.0-212.126.115.255 212.142.160.0-212.142.160.255 212.143.195.0-212.143.195.255 212.146.69.0-212.146.69.255 212.179.17.0-212.179.17.255 212.179.154.0-212.179.154.255 212.179.180.0-212.179.180.255 212.188.7.0-212.188.7.255 212.188.10.0-212.188.10.255 212.188.15.0-212.188.15.255 212.188.34.0-212.188.35.255 212.188.49.0-212.188.49.255 212.191.227.0-212.191.227.255 212.191.236.0-212.191.236.255 212.247.8.0-212.247.8.255 213.30.5.0-213.30.5.255 213.30.114.0-213.30.114.255 213.34.205.0-213.34.205.255 213.57.23.0-213.57.25.255 213.59.210.0-213.59.210.255 213.59.221.0-213.59.221.255 213.59.237.0-213.59.237.255 213.81.154.0-213.81.154.255 213.85.209.0-213.85.209.255 213.87.125.0-213.87.125.255 213.94.75.0-213.94.75.255 213.105.64.0-213.105.64.255 213.139.46.0-213.139.46.255 213.140.213.0-213.140.213.255 213.145.140.0-213.145.140.255 213.151.35.0-213.151.35.255 213.151.210.0-213.151.210.255 213.152.1.0-213.152.1.255 213.153.32.0-213.153.32.255 213.155.151.0-213.155.151.255 213.157.199.0-213.157.199.255 213.157.220.0-213.157.220.255 213.157.222.0-213.157.222.255 213.158.11.0-213.158.11.255 213.158.160.0-213.158.160.255 213.158.163.0-213.158.163.255 213.158.172.0-213.158.172.255 213.158.178.0-213.158.178.255 213.158.188.0-213.158.189.255 213.163.23.0-213.163.23.255 213.189.65.0-213.189.66.255 213.190.196.0-213.190.196.255 213.207.140.0-213.207.140.255 213.208.156.0-213.208.156.255 213.233.153.0-213.233.153.255 213.240.44.0-213.240.44.255 213.241.87.0-213.241.89.255 213.253.9.0-213.253.9.255 216.8.161.0-216.8.161.255 216.8.252.0-216.8.252.255 216.11.246.0-216.11.246.255 216.12.120.0-216.12.120.255 216.16.11.0-216.16.11.255 216.21.170.0-216.21.170.255 216.36.151.0-216.36.151.255 216.46.132.0-216.46.132.255 216.50.39.0-216.50.39.255 216.50.166.0-216.50.166.255 216.58.192.0-216.58.214.255 216.58.216.0-216.58.223.255 216.59.116.0-216.59.116.255 216.66.105.0-216.66.105.255 216.68.10.0-216.68.10.255 216.68.248.0-216.68.248.255 216.93.235.0-216.93.235.255 216.99.127.0-216.99.127.255 216.123.194.0-216.123.194.255 216.126.108.0-216.126.108.255 216.147.171.0-216.147.171.255 216.152.163.0-216.152.163.255 216.162.127.0-216.162.127.255 216.167.240.0-216.167.240.255 216.169.73.0-216.169.73.255 216.177.189.0-216.177.189.255 216.197.242.0-216.197.242.255 216.211.1.0-216.211.1.255 216.218.72.0-216.218.72.255 216.221.127.0-216.221.127.255 216.229.87.0-216.229.87.255 216.238.225.0-216.238.225.255 216.239.32.0-216.239.32.255 216.239.34.0-216.239.36.255 216.239.38.0-216.239.38.255 216.239.90.0-216.239.90.255 216.254.140.0-216.254.140.255 217.13.217.0-217.13.217.255 217.14.201.0-217.14.201.255 217.15.105.0-217.15.105.255 217.18.145.0-217.18.145.255 217.18.243.0-217.18.243.255 217.19.150.0-217.19.150.255 217.25.28.0-217.25.28.255 217.64.139.0-217.64.139.255 217.69.176.0-217.69.176.255 217.69.185.0-217.69.185.255 217.69.188.0-217.69.188.255 217.73.128.0-217.73.128.255 217.73.160.0-217.73.160.255 217.75.205.0-217.75.205.255 217.76.5.0-217.76.5.255 217.76.77.0-217.76.78.255 217.115.45.0-217.115.45.255 217.116.48.0-217.116.48.255 217.116.142.0-217.116.143.255 217.119.118.0-217.119.118.255 217.147.40.0-217.147.40.255 217.174.48.0-217.174.48.255 217.197.249.0-217.197.249.255 218.189.25.0-218.189.25.255 218.208.3.0-218.208.3.255 218.219.168.0-218.219.169.255 218.253.0.0-218.253.0.255 219.88.188.0-219.88.189.255 219.117.33.0-219.117.33.255 219.117.35.0-219.117.35.255 219.124.146.0-219.124.146.255 220.102.0.0-220.102.0.255 220.148.241.0-220.148.241.255 220.152.33.0-220.152.33.255 220.158.148.0-220.158.148.255 220.225.89.0-220.225.89.255 220.255.0.0-220.255.0.255 220.255.2.0-220.255.2.255 220.255.5.0-220.255.6.255 221.120.207.0-221.120.207.255 221.133.0.0-221.133.0.255 221.133.8.0-221.133.8.255 221.144.116.0-221.144.116.255 222.165.163.0-222.165.163.255 222.251.134.0-222.251.134.255 223.25.7.0-223.25.7.255 223.26.69.0-223.26.69.255 223.27.200.0-223.27.200.255 223.27.237.0-223.27.237.255 223.62.225.0-223.62.225.255 223.62.232.0-223.62.233.255 223.196.4.0-223.196.4.255 223.196.9.0-223.196.9.255 223.196.67.0-223.196.67.255 223.196.78.0-223.196.78.255 223.196.81.0-223.196.82.255 223.196.116.0-223.196.116.255 223.224.12.0-223.224.12.255 223.255.227.0-223.255.227.255 223.255.229.0-223.255.229.255 ================================================ FILE: code/default/gae_proxy/local/ip_range.txt ================================================ 8.8.4.0/24 8.8.8.0/24 8.35.200.0/21 34.0.228.0/22 34.0.232.0/21 34.1.64.0/18 34.2.32.0/19 34.2.64.0/18 34.2.128.0/17 34.3.0.0/23 34.3.3.0/24 34.3.4.0/24 34.3.8.0/21 34.3.16.0/20 34.3.32.0/19 34.3.64.0/18 34.4.0.0/14 34.13.64.0/22 34.13.72.0/21 34.13.80.0/20 34.13.96.0/19 34.14.128.0/17 34.15.0.0/16 34.34.192.0/20 34.34.208.0/21 34.34.224.0/19 34.43.0.0/16 34.50.128.0/19 34.52.0.0/17 34.64.0.0/19 34.96.0.0/18 34.98.0.0/18 34.98.136.0/21 34.98.144.0/20 34.98.160.0/19 34.98.192.0/18 34.99.0.0/16 34.100.0.0/17 34.101.0.0/20 34.101.16.0/23 34.101.19.0/24 34.101.28.0/22 34.103.0.0/16 34.104.0.0/20 34.104.16.0/21 34.104.24.0/23 34.104.26.0/24 34.104.28.0/22 34.104.32.0/20 34.104.48.0/24 34.104.53.0/24 34.104.54.0/23 34.109.0.0/16 34.110.0.0/17 34.113.0.0/16 34.114.0.0/15 34.116.8.0/21 34.116.16.0/20 34.116.32.0/19 34.118.208.0/20 34.118.224.0/20 34.119.0.0/16 34.124.64.0/19 34.124.96.0/20 34.126.0.0/18 34.126.224.0/19 34.127.128.0/19 34.127.160.0/20 34.127.176.0/24 34.127.181.0/24 34.127.182.0/23 34.127.192.0/18 34.128.0.0/19 34.128.38.0/23 34.128.40.0/23 34.128.50.0/23 34.128.56.0/23 34.128.192.0/18 34.143.0.0/17 34.144.0.0/17 34.144.128.0/18 34.152.70.0/23 34.152.82.0/23 34.152.88.0/21 34.152.96.0/19 34.152.128.0/17 34.153.0.0/19 34.153.34.0/23 34.153.36.0/23 34.153.39.0/24 34.153.56.0/23 34.153.60.0/22 34.153.64.0/18 34.153.192.0/19 34.153.226.0/23 34.153.228.0/23 34.153.231.0/24 34.153.248.0/23 34.153.252.0/22 34.156.0.0/16 34.157.10.0/23 34.157.86.0/24 34.157.120.0/24 34.157.122.0/23 34.157.138.0/23 34.157.214.0/24 34.157.218.0/23 34.157.248.0/24 34.158.0.0/16 34.167.0.0/16 34.177.0.0/19 34.177.38.0/23 34.177.56.0/21 34.177.64.0/18 34.177.128.0/17 34.178.0.0/16 34.180.0.0/16 34.183.0.0/16 34.184.0.0/13 35.187.128.0/20 35.190.96.0/20 35.190.240.0/20 35.191.0.0/16 35.199.128.0/20 35.201.32.0/21 35.201.40.0/24 35.201.42.0/23 35.201.44.0/22 35.201.48.0/20 35.203.192.0/20 35.203.208.0/23 35.203.220.0/22 35.203.224.0/21 35.203.240.0/20 35.206.0.0/21 35.206.8.0/23 35.206.12.0/22 35.206.16.0/20 35.218.0.0/16 35.219.192.0/19 35.220.28.0/23 35.220.30.0/24 35.229.0.0/20 35.230.192.0/19 35.230.224.0/20 35.235.128.0/18 35.235.192.0/20 35.235.208.0/21 35.235.224.0/19 35.242.28.0/23 35.242.30.0/24 35.243.16.0/20 35.243.48.0/21 57.140.192.0/18 64.15.112.0/20 64.233.160.0/19 66.22.228.0/23 66.102.0.0/20 66.249.64.0/19 70.32.128.0/19 72.14.192.0/18 74.125.0.0/16 104.154.0.0/20 104.154.112.0/24 104.154.122.0/23 104.154.124.0/22 104.155.240.0/20 104.196.64.0/24 104.196.72.0/21 104.196.80.0/20 104.199.64.0/23 104.199.240.0/23 104.237.160.0/19 107.178.192.0/20 107.178.224.0/20 108.170.192.0/18 108.177.0.0/17 130.211.0.0/22 136.22.160.0/20 136.22.176.0/21 136.22.184.0/23 136.22.186.0/24 136.124.0.0/15 142.250.0.0/15 146.148.0.0/23 152.65.208.0/22 152.65.214.0/23 152.65.218.0/23 152.65.222.0/23 152.65.224.0/19 162.120.128.0/17 172.110.32.0/21 172.217.0.0/16 172.253.0.0/16 173.194.0.0/16 192.178.0.0/15 193.186.4.0/24 199.36.154.0/23 199.36.156.0/24 199.192.112.0/23 199.192.114.0/24 199.223.237.0/24 199.223.238.0/23 207.223.160.0/20 208.65.152.0/22 208.68.108.0/22 208.81.188.0/22 208.117.224.0/19 209.85.128.0/17 216.58.192.0/19 216.73.80.0/20 216.239.32.0/19 2001:4860::/32 2404:6800::/32 2404:f340::/32 2600:1900::/34 2600:1900:4100::/43 2600:1900:4130::/44 2600:1900:4190::/44 2600:1900:41f0::/44 2600:1900:4200::/41 2600:1900:42b0::/44 2600:1900:42c0::/42 2600:1900:4300::/40 2600:1900:4400::/38 2600:1900:4800::/37 2600:1900:5000::/38 2600:1900:5410::/44 2600:1900:5420::/43 2600:1900:5440::/42 2600:1900:5480::/41 2600:1900:5500::/40 2600:1900:5600::/39 2600:1900:5800::/37 2600:1900:6000::/35 2600:1900:8010::/44 2600:1900:8020::/43 2600:1900:8040::/42 2600:1900:8080::/41 2600:1900:8100::/40 2600:1900:8200::/39 2600:1900:8400::/38 2600:1900:8800::/37 2600:1900:9000::/36 2600:1900:a000::/35 2600:1900:c000::/34 2600:1901:1::/48 2600:1901:2::/47 2600:1901:4::/46 2600:1901:8::/45 2600:1901:10::/44 2600:1901:20::/43 2600:1901:40::/42 2600:1901:80::/41 2600:1901:100::/40 2600:1901:200::/39 2600:1901:400::/38 2600:1901:800::/37 2600:1901:1000::/36 2600:1901:2000::/35 2600:1901:4000::/44 2600:1901:4020::/43 2600:1901:4040::/42 2600:1901:4080::/41 2600:1901:4100::/40 2600:1901:4200::/39 2600:1901:4400::/38 2600:1901:4800::/37 2600:1901:5000::/36 2600:1901:6000::/35 2600:1901:8000::/40 2600:1901:8190::/44 2600:1901:81a0::/44 2600:1901:81d0::/44 2600:1901:81e0::/44 2600:1901:8200::/39 2600:1901:8400::/38 2600:1901:8800::/37 2600:1901:9000::/36 2600:1901:a000::/35 2600:1901:c000::/34 2600:1902::/31 2600:1904::/30 2600:1908::/29 2605:ef80::/32 2606:40::/32 2606:73c0::/32 2607:1c0:241:40::/60 2607:1c0:300::/40 2607:f8b0::/32 2620:11a:a000::/40 2620:120:e000::/40 2800:3f0::/32 2a00:1450::/32 2c0f:fb50::/32 ================================================ FILE: code/default/gae_proxy/local/ipv6_list.txt ================================================ 2607:f8b0:4003:c04::99 google.com gws 100 0 0 2a00:1450:4009:811::2014 google.com gws 100 0 0 2a00:1450:401b:804::2014 google.com gws 100 0 0 2607:f8b0:4020:804::2014 google.com gws 100 0 0 2a00:1450:400d:809::2014 google.com gws 100 0 0 2607:f8b0:4005:80a::2014 google.com gws 100 0 0 2404:6800:4001:806::2014 google.com gws 100 0 0 2a00:1450:4013:c04::99 google.com gws 100 0 0 2800:3f0:4001:807::2014 google.com gws 100 0 0 2a00:1450:4017:80a::2014 google.com gws 100 0 0 2a00:1450:4007:811::2014 google.com gws 100 0 0 2607:f8b0:400d:c01::99 google.com gws 100 0 0 2a00:1450:4002:805::2014 google.com gws 100 0 0 2800:3f0:4004:809::2014 google.com gws 100 0 0 2800:3f0:4005:403::2014 google.com gws 100 0 0 2404:6800:4003:808::2014 google.com gws 100 0 0 2a00:1450:4009:803::2014 google.com gws 100 0 0 2a00:1450:4018:803::2014 google.com gws 100 0 0 2607:f8b0:4007:808::2014 google.com gws 100 0 0 2404:6800:4005:800::2014 google.com gws 100 0 0 2607:f8b0:4005:806::2014 google.com gws 100 0 0 2607:f8b0:4004:80c::2014 google.com gws 100 0 0 64:ff9b::acd9:c299 google.com gws 100 0 0 2a00:1450:400a:801::2014 google.com gws 100 0 0 2a00:1450:4017:804::2014 google.com gws 100 0 0 2a00:1450:4009:810::2014 google.com gws 100 0 0 2607:f8b0:4007:80c::2014 google.com gws 100 0 0 2404:6800:4006:80a::2014 google.com gws 100 0 0 2a00:1450:4016:809::2014 google.com gws 100 0 0 2a00:1450:4010:c03::99 google.com gws 100 0 0 2607:f8b0:4003:c15::99 google.com gws 100 0 0 2a00:1450:4009:808::2014 google.com gws 100 0 0 2a00:1450:4006:801::2014 google.com gws 100 0 0 2a00:1450:4003:803::2014 google.com gws 100 0 0 2404:6800:4008:802::2014 google.com gws 100 0 0 2607:f8b0:4002:c07::99 google.com gws 100 0 0 2a00:1450:400f:80b::2014 google.com gws 100 0 0 2a00:1450:401b:803::2014 google.com gws 100 0 0 2a00:1450:4009:801::2014 google.com gws 100 0 0 2607:f8b0:400e:c09::99 google.com gws 100 0 0 2404:6800:4009:801::2014 google.com gws 100 0 0 2404:6800:4009:805::2014 google.com gws 100 0 0 2404:6800:4004:81a::2014 google.com gws 100 0 0 2a00:1450:4006:807::2014 google.com gws 100 0 0 2607:f8b0:4000:817::2014 google.com gws 100 0 0 2607:f8b0:4000:80c::2014 google.com gws 100 0 0 2607:f8b0:4004:80f::2014 google.com gws 100 0 0 2607:f8b0:4003:c17::99 google.com gws 100 0 0 2607:f8b0:4009:803::2014 google.com gws 100 0 0 2404:6800:4006:807::2014 google.com gws 100 0 0 2607:f8b0:400a:808::2014 google.com gws 100 0 0 2607:f8b0:400b:80f::2014 google.com gws 100 0 0 2a00:1450:4009:812::2014 google.com gws 100 0 0 2404:6800:4002:803::2014 google.com gws 100 0 0 2607:f8b0:4020:807::2014 google.com gws 100 0 0 2a00:1450:4016:80a::2014 google.com gws 100 0 0 2800:3f0:4001:805::2014 google.com gws 100 0 0 2607:f8b0:4009:810::2014 google.com gws 100 0 0 2a00:1450:4018:802::2014 google.com gws 100 0 0 2800:3f0:4005:401::2014 google.com gws 100 0 0 2607:f8b0:4003:c12::99 google.com gws 100 0 0 2607:f8b0:4012:805::2014 google.com gws 100 0 0 2404:6800:4007:80f::2014 google.com gws 100 0 0 2607:f8b0:400d:c0f::99 google.com gws 100 0 0 2607:f8b0:4004:805::2014 google.com gws 100 0 0 2a00:1450:4019:801::2014 google.com gws 100 0 0 2404:6800:4006:808::2014 google.com gws 100 0 0 2607:f8b0:4005:807::2014 google.com gws 100 0 0 2c0f:fb50:4002:802::2014 google.com gws 100 0 0 2a00:1450:401a:805::2014 google.com gws 100 0 0 2a00:1450:4003:80b::2014 google.com gws 100 0 0 2a00:1450:4016:807::2014 google.com gws 100 0 0 2a00:1450:400e:80d::2014 google.com gws 100 0 0 2404:6800:400a:807::2014 google.com gws 100 0 0 2607:f8b0:4008:810::2014 google.com gws 100 0 0 2607:f8b0:400d:c0b::99 google.com gws 100 0 0 2a00:1450:4007:809::2014 google.com gws 100 0 0 2607:f8b0:4009:801::2014 google.com gws 100 0 0 2607:f8b0:4002:c06::99 google.com gws 100 0 0 2404:6800:4004:818::2014 google.com gws 100 0 0 2607:f8b0:4001:c0e::99 google.com gws 100 0 0 2607:f8b0:4001:c1b::99 google.com gws 100 0 0 2a00:1450:4013:c01::99 google.com gws 100 0 0 2800:3f0:4001:814::2014 google.com gws 100 0 0 2404:6800:4007:807::2014 google.com gws 100 0 0 2607:f8b0:400f:800::2014 google.com gws 100 0 0 2404:6800:4004:80b::2014 google.com gws 100 0 0 2a00:1450:401b:805::2014 google.com gws 100 0 0 2607:f8b0:4007:806::2014 google.com gws 100 0 0 2404:6800:4005:804::2014 google.com gws 100 0 0 2a00:1450:4003:801::2014 google.com gws 100 0 0 2a00:1450:4006:802::2014 google.com gws 100 0 0 2607:f8b0:4009:80c::2014 google.com gws 100 0 0 2800:3f0:4004:807::2014 google.com gws 100 0 0 2607:f8b0:4009:812::2014 google.com gws 100 0 0 2404:6800:4009:807::2014 google.com gws 100 0 0 2607:f8b0:4008:803::2014 google.com gws 100 0 0 2a00:1450:4005:80a::2014 google.com gws 100 0 0 2a00:1450:4016:808::2014 google.com gws 100 0 0 2800:3f0:4001:80f::2014 google.com gws 100 0 0 2404:6800:4008:c04::99 google.com gws 100 0 0 2a00:1450:4002:808::2014 google.com gws 100 0 0 2404:6800:4001:800::2014 google.com gws 100 0 0 2800:3f0:4002:804::2014 google.com gws 100 0 0 2a00:1450:4013:c03::99 google.com gws 100 0 0 2404:6800:4004:800::2014 google.com gws 100 0 0 2607:f8b0:400f:805::2014 google.com gws 100 0 0 2607:f8b0:4009:80a::2014 google.com gws 100 0 0 2a00:1450:4017:807::2014 google.com gws 100 0 0 2a00:1450:400e:805::2014 google.com gws 100 0 0 2a00:1450:4005:800::2014 google.com gws 100 0 0 2a00:1450:4007:816::2014 google.com gws 100 0 0 2a00:1450:4003:809::2014 google.com gws 100 0 0 2a00:1450:4001:824::2014 google.com gws 100 0 0 2607:f8b0:4003:c00::99 google.com gws 100 0 0 2a00:1450:400c:c04::99 google.com gws 100 0 0 2404:6800:4004:807::2014 google.com gws 100 0 0 2607:f8b0:4005:805::2014 google.com gws 100 0 0 2607:f8b0:400e:c03::99 google.com gws 100 0 0 2404:6800:4001:80f::2014 google.com gws 100 0 0 2607:f8b0:4009:811::2014 google.com gws 100 0 0 2a00:1450:4010:c09::99 google.com gws 100 0 0 2607:f8b0:4006:810::2014 google.com gws 100 0 0 2607:f8b0:4002:c08::99 google.com gws 100 0 0 2a00:1450:4009:804::2014 google.com gws 100 0 0 2a00:1450:400e:806::2014 google.com gws 100 0 0 2404:6800:4002:804::2014 google.com gws 100 0 0 2a00:1450:4009:807::2014 google.com gws 100 0 0 2607:f8b0:400a:800::2014 google.com gws 100 0 0 64:ff9b::4a7d:1899 google.com gws 100 0 0 2800:3f0:4002:808::2014 google.com gws 100 0 0 2800:3f0:4002:809::2014 google.com gws 100 0 0 2a00:1450:400c:c08::99 google.com gws 100 0 0 2800:3f0:4004:800::2014 google.com gws 100 0 0 2a00:1450:401b:807::2014 google.com gws 100 0 0 2607:f8b0:400b:809::2014 google.com gws 100 0 0 2607:f8b0:4009:809::2014 google.com gws 100 0 0 2a00:1450:4009:80f::2014 google.com gws 100 0 0 2a00:1450:4007:813::2014 google.com gws 100 0 0 2607:f8b0:4002:c09::99 google.com gws 100 0 0 2404:6800:4003:802::2014 google.com gws 100 0 0 2a00:1450:4003:807::2014 google.com gws 100 0 0 2a00:1450:4001:820::2014 google.com gws 100 0 0 2607:f8b0:4006:803::2014 google.com gws 100 0 0 2404:6800:4009:802::2014 google.com gws 100 0 0 2607:f8b0:4006:815::2014 google.com gws 100 0 0 2a00:1450:4009:814::2014 google.com gws 100 0 0 2a00:1450:401b:806::2014 google.com gws 100 0 0 2607:f8b0:4000:811::2014 google.com gws 100 0 0 2404:6800:4012::2014 google.com gws 100 0 0 2a00:1450:4007:817::2014 google.com gws 100 0 0 2404:6800:4009:80a::2014 google.com gws 100 0 0 2404:6800:4005:805::2014 google.com gws 100 0 0 2a00:1450:401b:800::2014 google.com gws 100 0 0 2a00:1450:400e:802::2014 google.com gws 100 0 0 2404:6800:4006:803::2014 google.com gws 100 0 0 2404:6800:4007:80b::2014 google.com gws 100 0 0 2607:f8b0:4009:80b::2014 google.com gws 100 0 0 2607:f8b0:4009:802::2014 google.com gws 100 0 0 2800:3f0:4002:805::2014 google.com gws 100 0 0 2a00:1450:4010:c01::99 google.com gws 100 0 0 2404:6800:4004:80e::2014 google.com gws 100 0 0 2607:f8b0:4000:806::2014 google.com gws 100 0 0 2404:6800:4005:80c::2014 google.com gws 100 0 0 2607:f8b0:4012:80b::2014 google.com gws 100 0 0 2607:f8b0:4004:804::2014 google.com gws 100 0 0 2404:6800:4003:807::2014 google.com gws 100 0 0 2607:f8b0:4000:813::2014 google.com gws 100 0 0 2404:6800:4005:808::2014 google.com gws 100 0 0 2800:3f0:4001:80a::2014 google.com gws 100 0 0 2607:f8b0:4009:806::2014 google.com gws 100 0 0 2404:6800:4001:801::2014 google.com gws 100 0 0 2607:f8b0:4000:808::2014 google.com gws 100 0 0 2a00:1450:4019:802::2014 google.com gws 100 0 0 2404:6800:4004:806::2014 google.com gws 100 0 0 2a00:1450:400d:805::2014 google.com gws 100 0 0 2607:f8b0:4009:80f::2014 google.com gws 100 0 0 2a00:1450:400f:806::2014 google.com gws 100 0 0 2a00:1450:4007:80e::2014 google.com gws 100 0 0 2404:6800:4007:801::2014 google.com gws 100 0 0 2607:f8b0:4006:80f::2014 google.com gws 100 0 0 2a00:1450:401b:802::2014 google.com gws 100 0 0 2a00:1450:400d:808::2014 google.com gws 100 0 0 2404:6800:400a:806::2014 google.com gws 100 0 0 2404:6800:400a:80b::2014 google.com gws 100 0 0 2800:3f0:4001:815::2014 google.com gws 100 0 0 2607:f8b0:4000:804::2014 google.com gws 100 0 0 2607:f8b0:4009:815::2014 google.com gws 100 0 0 2a00:1450:400e:804::2014 google.com gws 100 0 0 2a00:1450:4017:80b::2014 google.com gws 100 0 0 2607:f8b0:4008:813::2014 google.com gws 100 0 0 2404:6800:4001:80c::2014 google.com gws 100 0 0 2a00:1450:4001:80b::2014 google.com gws 100 0 0 2404:6800:4001:803::2014 google.com gws 100 0 0 2a00:1450:4018:800::2014 google.com gws 100 0 0 2a00:1450:400f:809::2014 google.com gws 100 0 0 2607:f8b0:4003:c05::99 google.com gws 100 0 0 2a00:1450:400c:c07::99 google.com gws 100 0 0 2a00:1450:4003:805::2014 google.com gws 100 0 0 2800:3f0:4001:806::2014 google.com gws 100 0 0 2a00:1450:4001:81b::2014 google.com gws 100 0 0 2a00:1450:4010:c02::99 google.com gws 100 0 0 2607:f8b0:4009:804::2014 google.com gws 100 0 0 2607:f8b0:4002:c02::99 google.com gws 100 0 0 2404:6800:4008:c07::99 google.com gws 100 0 0 2a00:1450:4001:806::2014 google.com gws 100 0 0 2a00:1450:4002:807::2014 google.com gws 100 0 0 2a00:1450:4007:808::2014 google.com gws 100 0 0 2607:f8b0:4003:c19::99 google.com gws 100 0 0 2a00:1450:400f:80c::2014 google.com gws 100 0 0 2607:f8b0:4003:c01::99 google.com gws 100 0 0 2404:6800:4005:801::2014 google.com gws 100 0 0 2404:6800:4004:80c::2014 google.com gws 100 0 0 2607:f8b0:4006:804::2014 google.com gws 100 0 0 2404:6800:4009:804::2014 google.com gws 100 0 0 2a00:1450:400e:808::2014 google.com gws 100 0 0 2607:f8b0:4007:80e::2014 google.com gws 100 0 0 2a00:1450:400a:802::2014 google.com gws 100 0 0 2a00:1450:4001:815::2014 google.com gws 100 0 0 2404:6800:4009:808::2014 google.com gws 100 0 0 2607:f8b0:4005:80b::2014 google.com gws 100 0 0 2a00:1450:400f:808::2014 google.com gws 100 0 0 2a00:1450:4001:808::2014 google.com gws 100 0 2 2404:6800:4009:80e::2014 google.com gws 100 0 0 2a00:1450:4016:80b::2014 google.com gws 100 0 0 2404:6800:4005:80b::2014 google.com gws 100 0 0 2a00:1450:4007:80c::2014 google.com gws 100 0 0 2607:f8b0:4006:819::2014 google.com gws 100 0 0 2607:f8b0:400b:80c::2014 google.com gws 100 0 0 2a00:1450:4002:809::2014 google.com gws 100 0 0 2607:f8b0:4000:814::2014 google.com gws 100 0 0 2404:6800:4009:809::2014 google.com gws 100 0 0 2404:6800:4005:810::2014 google.com gws 100 0 0 2607:f8b0:4007:804::2014 google.com gws 100 0 0 2607:f8b0:4004:801::2014 google.com gws 100 0 0 2a00:1450:400f:80a::2014 google.com gws 100 0 0 2607:f8b0:400f:804::2014 google.com gws 100 0 0 2607:f8b0:4007:800::2014 google.com gws 100 0 0 2607:f8b0:4004:80e::2014 google.com gws 100 0 0 2a00:1450:4009:80c::2014 google.com gws 100 0 0 2607:f8b0:4000:812::2014 google.com gws 100 0 0 2404:6800:4001:80d::2014 google.com gws 100 0 0 2404:6800:4007:808::2014 google.com gws 100 0 0 2404:6800:4005:807::2014 google.com gws 100 0 0 2a00:1450:4014:80c::2014 google.com gws 100 0 0 2607:f8b0:4000:815::2014 google.com gws 100 0 0 2800:3f0:4003:c00::99 google.com gws 100 0 0 2a00:1450:400f:807::2014 google.com gws 100 0 0 2404:6800:4009:806::2014 google.com gws 100 0 0 2800:3f0:4004:806::2014 google.com gws 100 0 0 2404:6800:4005:803::2014 google.com gws 100 0 0 2607:f8b0:4000:80e::2014 google.com gws 100 0 0 2607:f8b0:400a:803::2014 google.com gws 100 0 0 2a00:1450:4007:805::2014 google.com gws 100 0 0 2404:6800:4008:c01::99 google.com gws 100 0 0 2404:6800:4009:80d::2014 google.com gws 100 0 0 2404:6800:400a:80c::2014 google.com gws 100 0 0 2a00:1450:400e:80a::2014 google.com gws 100 0 0 2607:f8b0:4006:811::2014 google.com gws 100 0 0 2a00:1450:4016:80d::2014 google.com gws 100 0 0 2607:f8b0:4000:802::2014 google.com gws 100 0 0 2404:6800:4004:809::2014 google.com gws 100 0 0 2a00:1450:4007:812::2014 google.com gws 100 0 0 2404:6800:4004:80a::2014 google.com gws 100 0 0 2a00:1450:4017:806::2014 google.com gws 100 0 0 2a00:1450:4017:808::2014 google.com gws 100 0 0 2800:3f0:4002:80a::2014 google.com gws 100 0 0 2a00:1450:4005:80b::2014 google.com gws 100 0 0 2a00:1450:4002:806::2014 google.com gws 100 0 0 2607:f8b0:4006:802::2014 google.com gws 100 0 0 2800:3f0:4001:802::2014 google.com gws 100 0 0 2404:6800:4005:806::2014 google.com gws 100 0 0 2a00:1450:4007:814::2014 google.com gws 100 0 0 2607:f8b0:4008:802::2014 google.com gws 100 0 0 2800:3f0:4004:805::2014 google.com gws 100 0 0 2a00:1450:4007:80a::2014 google.com gws 100 0 0 2a00:1450:4009:802::2014 google.com gws 100 0 0 2404:6800:4003:c01::99 google.com gws 100 0 0 2404:6800:4007:800::2014 google.com gws 100 0 0 2a00:1450:4001:821::2014 google.com gws 100 0 0 2404:6800:4004:801::2014 google.com gws 100 0 0 2607:f8b0:4008:80c::2014 google.com gws 100 0 0 2404:6800:4004:80f::2014 google.com gws 100 0 0 2607:f8b0:4002:c00::99 google.com gws 100 0 0 2404:6800:4003:c04::99 google.com gws 100 0 0 2404:6800:4006:802::2014 google.com gws 100 0 0 2607:f8b0:4006:81a::2014 google.com gws 100 0 0 2607:f8b0:4005:801::2014 google.com gws 100 0 0 2404:6800:4001:804::2014 google.com gws 100 0 0 2a00:1450:4009:815::2014 google.com gws 100 0 0 2607:f8b0:4007:802::2014 google.com gws 100 0 0 2404:6800:4008:801::2014 google.com gws 100 0 0 2a00:1450:400e:803::2014 google.com gws 100 0 0 2607:f8b0:4007:80b::2014 google.com gws 100 0 0 2a00:1450:4007:80f::2014 google.com gws 100 0 0 2607:f8b0:4004:80d::2014 google.com gws 100 0 0 2800:3f0:4004:808::2014 google.com gws 100 0 0 2a00:1450:4010:c0f::99 google.com gws 100 0 0 2a00:1450:4009:809::2014 google.com gws 100 0 0 2404:6800:4006:806::2014 google.com gws 100 0 0 2404:6800:4003:c03::99 google.com gws 100 0 0 2404:6800:4004:80d::2014 google.com gws 100 0 0 2607:f8b0:4006:813::2014 google.com gws 100 0 0 2a00:1450:4010:c08::99 google.com gws 100 0 0 2607:f8b0:4009:808::2014 google.com gws 100 0 0 2a00:1450:4017:800::2014 google.com gws 100 0 0 2a00:1450:4014:801::2014 google.com gws 100 0 0 2a00:1450:4003:80a::2014 google.com gws 100 0 0 2607:f8b0:4020:805::2014 google.com gws 100 0 0 2607:f8b0:4012:808::2014 google.com gws 100 0 0 2a00:1450:400e:80c::2014 google.com gws 100 0 0 2a00:1450:4001:81f::2014 google.com gws 100 0 0 2800:3f0:4001:80c::2014 google.com gws 100 0 0 2607:f8b0:4007:809::2014 google.com gws 100 0 0 2607:f8b0:4006:812::2014 google.com gws 100 0 0 2a00:1450:4010:c0d::99 google.com gws 100 0 0 2607:f8b0:400b:808::2014 google.com gws 100 0 0 2a00:1450:4007:80d::2014 google.com gws 100 0 0 2800:3f0:4005:400::2014 google.com gws 100 0 0 2a00:1450:4017:801::2014 google.com gws 100 0 0 2607:f8b0:4006:800::2014 google.com gws 100 0 0 2607:f8b0:4009:816::2014 google.com gws 100 0 0 2404:6800:400a:808::2014 google.com gws 100 0 0 2607:f8b0:400a:804::2014 google.com gws 100 0 0 2a00:1450:4016:800::2014 google.com gws 100 0 0 2607:f8b0:4004:810::2014 google.com gws 100 0 0 2c0f:fb50:4002:803::2014 google.com gws 100 0 0 2607:f8b0:4006:814::2014 google.com gws 100 0 0 2800:3f0:4003:c02::99 google.com gws 100 0 0 2404:6800:4009:810::2014 google.com gws 100 0 0 2404:6800:4005:809::2014 google.com gws 100 0 0 2a00:1450:4003:804::2014 google.com gws 100 0 0 2404:6800:4003:c02::99 google.com gws 100 0 0 2607:f8b0:4006:801::2014 google.com gws 100 0 0 2404:6800:4005:80d::2014 google.com gws 100 0 0 2a00:1450:4016:806::2014 google.com gws 100 0 0 2a00:1450:4014:80d::2014 google.com gws 100 0 0 2a00:1450:4009:800::2014 google.com gws 100 0 0 2a00:1450:400c:c0c::99 google.com gws 100 0 0 2404:6800:4005:811::2014 google.com gws 100 0 0 2a00:1450:4010:c05::99 google.com gws 100 0 0 2a00:1450:4003:806::2014 google.com gws 100 0 0 2607:f8b0:400b:80d::2014 google.com gws 100 0 0 2800:3f0:4004:801::2014 google.com gws 100 0 0 2a00:1450:4017:809::2014 google.com gws 100 0 0 2a00:1450:4010:c0e::99 google.com gws 100 0 0 2404:6800:4009:803::2014 google.com gws 100 0 0 2a00:1450:4007:815::2014 google.com gws 100 0 0 2404:6800:4009:800::2014 google.com gws 100 0 0 2a00:1450:4001:816::2014 google.com gws 100 0 0 2800:3f0:4001:803::2014 google.com gws 100 0 0 2a00:1450:4013:c00::99 google.com gws 100 0 0 2a00:1450:4009:80d::2014 google.com gws 100 0 0 2607:f8b0:4002:c0c::99 google.com gws 100 0 0 2a00:1450:4009:80e::2014 google.com gws 100 0 0 2a00:1450:4009:813::2014 google.com gws 100 0 0 2a00:1450:4014:800::2014 google.com gws 100 0 0 2607:f8b0:4007:80d::2014 google.com gws 100 0 0 2404:6800:4005:802::2014 google.com gws 100 0 0 2404:6800:4005:80f::2014 google.com gws 100 0 0 2404:6800:4004:819::2014 google.com gws 100 0 0 2800:3f0:4001:80d::2014 google.com gws 100 0 0 2607:f8b0:4004:802::2014 google.com gws 100 0 0 2a00:1450:4010:c0b::99 google.com gws 100 0 0 2404:6800:4009:80c::2014 google.com gws 100 0 0 2404:6800:4009:80b::2014 google.com gws 100 0 0 2a00:1450:4002:80b::2014 google.com gws 100 0 0 2607:f8b0:4012:804::2014 google.com gws 100 0 0 2a00:1450:4001:81d::2014 google.com gws 600 0 0 2800:3f0:4001:810::2014 google.com gws 600 0 0 2607:f8b0:4006:80e::2014 google.com gws 600 0 0 2a00:1450:4001:819::2014 google.com gws 600 0 0 2a00:1450:4013:c07::99 google.com gws 600 0 0 2a00:1450:4019:803::2014 google.com gws 600 0 0 2607:f8b0:4005:802::2014 google.com gws 600 0 0 2404:6800:4002:80a::2014 google.com gws 600 0 0 2a00:1450:4019:800::2014 google.com gws 600 0 0 2404:6800:4006:804::2014 google.com gws 600 0 0 2404:6800:4004:81b::2014 google.com gws 600 0 0 2a00:1450:4002:800::2014 google.com gws 600 0 0 2607:f8b0:4012:80a::2014 google.com gws 600 0 0 2607:f8b0:400f:806::2014 google.com gws 600 0 0 2a00:1450:400e:809::2014 google.com gws 600 0 0 2607:f8b0:400b:80e::2014 google.com gws 600 0 0 2404:6800:4002:802::2014 google.com gws 600 0 0 2800:3f0:4001:80b::2014 google.com gws 600 0 0 2404:6800:4003:c00::99 google.com gws 600 0 0 2800:3f0:4005:402::2014 google.com gws 600 0 0 2607:f8b0:4008:811::2014 google.com gws 600 0 0 2607:f8b0:4004:800::2014 google.com gws 600 0 0 2404:6800:4004:808::2014 google.com gws 600 0 0 2a00:1450:4002:802::2014 google.com gws 600 0 0 2a00:1450:4002:80a::2014 google.com gws 600 0 0 2404:6800:4003:80a::2014 google.com gws 600 0 0 2607:f8b0:4008:805::2014 google.com gws 600 0 0 2c0f:fb50:4003:801::2014 google.com gws 600 0 0 2607:f8b0:4004:80b::2014 google.com gws 600 0 0 2a00:1450:4007:810::2014 google.com gws 600 0 0 2607:f8b0:4000:80d::2014 google.com gws 600 0 0 2a00:1450:4010:c07::99 google.com gws 600 0 0 2404:6800:4012:1::2014 google.com gws 600 0 0 2607:f8b0:4003:c09::99 google.com gws 600 0 0 2800:3f0:4001:808::2014 google.com gws 600 0 0 2a00:1450:4001:817::2014 google.com gws 600 0 0 2404:6800:4005:80a::2014 google.com gws 600 0 0 2a00:1450:4003:802::2014 google.com gws 600 0 0 2607:f8b0:4008:80e::2014 google.com gws 600 0 0 2607:f8b0:4005:804::2014 google.com gws 600 0 0 2a00:1450:4010:c0a::99 google.com gws 600 0 0 2a00:1450:400d:803::2014 google.com gws 600 0 0 2607:f8b0:4009:807::2014 google.com gws 600 0 0 2607:f8b0:4004:803::2014 google.com gws 600 0 0 2800:3f0:4001:809::2014 google.com gws 600 0 0 2607:f8b0:4006:818::2014 google.com gws 600 0 0 2607:f8b0:400f:807::2014 google.com gws 600 0 0 2800:3f0:4001:816::2014 google.com gws 600 0 0 2a00:1450:4006:808::2014 google.com gws 600 0 0 2404:6800:4008:c00::99 google.com gws 600 0 0 2607:f8b0:4009:80d::2014 google.com gws 600 0 0 2800:3f0:4003:c01::99 google.com gws 600 0 0 2a00:1450:400e:807::2014 google.com gws 600 0 0 2607:f8b0:4002:c03::99 google.com gws 600 0 0 2404:6800:4003:804::2014 google.com gws 600 0 0 2a00:1450:4001:81c::2014 google.com gws 100 1 0 2a00:1450:400d:806::2014 google.com gws 100 1 0 2a00:1450:4001:81a::2014 google.com gws 100 1 0 2a00:1450:4001:825::2014 google.com gws 100 1 0 2800:3f0:4001:817::2014 google.com gws 100 1 0 ================================================ FILE: code/default/gae_proxy/local/ipv6_tunnel/IPV6_note.TXT ================================================ #ͣáip helper net stop "ip helper" #áip helper net start "ip helper" #ʾTeredoϢ netsh interface ipv6 show teredo #Teredo6to4isatap netsh interface teredo set state default netsh interface 6to4 set state default netsh interface isatap set state default #رպжTeredo6to4isatap netsh interface teredo set state disable netsh interface 6to4 set state disabled netsh interface isatap set state disabled #Teredo netsh interface Teredo set state type=default #Teredo netsh interface teredo set state server=teredo.remlab.net netsh interface teredo set state server=teredo-debian.remlab.net netsh interface teredo set state server=teredo.trex.fi #TeredoΪteredo.ipv6.microsoft.comteredoϣ netsh interface ipv6 set teredo client teredo.ipv6.microsoft.com #isatapPINGͨ netsh int IPV6 isatap set router isatap.scu.edu.cn #ֶWindows7IPv6ֵ֧覴 netsh interface IPV6 set global randomizeidentifiers=disabled #Teredo netsh interface ipv6 set teredo enterpriseclient netsh int ter set state enterpriseclient #ֶ㣨IPv4ñӣIPv6ַ #IPv4ַ http://ip-lookup.net/conversion.php #޸ıIPv6ַ #ǰ׺ 48 #google ipv6 dns: 2001:4860:4860::8888 2001:4860:4860::8844 #opendns ipv6 dns: 2620:0:ccc::2 2620:0:ccd::2 #HE ipv6 dns: 2001:470:20::2 ipconfig /all ipconfig /flushdns netsh int ipv6 show int netsh int ipv6 show route #teredo״̬Dzqualified netsh int ipv6 show teredo #ɾ· route DELETE ::/0 #· (һҪһ) netsh int ipv6 add route ::/0 "Teredo Tunneling Pseudo-Interface" #ڡstart.bat䣬ʵXXִ netsh int ipv6 add route ::/0 "Teredo Tunneling Pseudo-Interface" SET PYTHONPATH="%~dp0%start.vbs" console #ȼ netsh int ipv6 show prefix netsh int ipv6 set prefix 2002::/16 30 1 netsh int ipv6 set prefix 2001::/32 5 1 #鿴Teredo Tunneling Pseudo-Interface ӿ route print #ʾIPv6ַ netsh interface ipv6 show address #ʾIPv6· netsh interface ipv6 show route #ipv6 netsh interface ipv6 reset #" 2"ԼҪ netsh interface set interface " 2" disabled netsh interface set interface " 2" enabled #IPV6վ http://test-ipv6.com/ #ժҪֲɺ뵽Ŀв鿴 #ȫǡɹġ http://www.kame.net/kame-mosaic.html #IPv6Կڹ꣬IPv4ڹ겻 ================================================ FILE: code/default/gae_proxy/local/ipv6_tunnel/__init__.py ================================================ import sys import platform from .common import test_teredo if "arm" in platform.machine(): from .unknown import state, state_pp, switch_pp, enable, disable, set_best_server elif sys.platform == "win32": from .win10 import state, state_pp, switch_pp, enable, disable, set_best_server elif sys.platform.startswith("linux"): from .linux import state, state_pp, switch_pp, enable, disable, set_best_server elif sys.platform == "darwin": from .darwin import state, state_pp, switch_pp, enable, disable, set_best_server else: from .unknown import state, state_pp, switch_pp, enable, disable, set_best_server ================================================ FILE: code/default/gae_proxy/local/ipv6_tunnel/common.py ================================================ import os import shlex import subprocess from .pteredor import teredo_prober import env_info import utils from xlog import getLogger xlog = getLogger("gae_proxy") current_path = os.path.dirname(os.path.abspath(__file__)) root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, os.pardir)) data_path = os.path.join(env_info.data_path, "gae_proxy") if not os.path.isdir(data_path): data_path = current_path log_file = os.path.join(data_path, "ipv6_tunnel.log") if os.path.isfile(log_file): os.remove(log_file) class Log(object): def __init__(self): self.fd = open(log_file, "a") def write(self, content): self.fd.write(content + "\n") self.fd.flush() def close(self): self.fd.close() pteredor_is_running = False def new_pteredor(probe_nat=True): if os.path.isfile(log_file): try: os.remove(log_file) except Exception as e: xlog.warn("remove %s fail:%r", log_file, e) global pteredor_is_running, usable pteredor_is_running = probe_nat prober = teredo_prober(probe_nat=probe_nat) if prober.nat_type in ('cone', 'restricted'): usable = 'usable' elif prober.nat_type == 'offline': usable = 'unusable' else: usable = 'unknown' if probe_nat: pteredor_is_running = False log = Log() log.write('qualified: %s\nNAT type: %s' % (prober.qualified, prober.nat_type)) log.close() return prober def test_teredo(probe_nat=True, probe_server=True): if pteredor_is_running: return "Script is running, please retry later." server = '' if probe_server: server = ' and the best server is %s.' % best_server(probe_nat=probe_nat) else: new_pteredor() return 'teredor test result is %s.%s' % (usable, server) def best_server(probe_nat=False): best_server = None prober = new_pteredor(probe_nat=probe_nat) prober.qualified = True if not probe_nat: prober.nat_type = 'unknown' prober.rs_cone_flag = 0 global pteredor_is_running pteredor_is_running = True server_list = prober.eval_servers() pteredor_is_running = False for qualified, server, _, _ in server_list: if qualified: best_server = server[0] break log = Log() if best_server: log.write('best server is: %s.' % best_server) else: xlog.warning('no server detected, return default: teredo.remlab.net.') log.write('no server detected, return default: teredo.remlab.net.') best_server = "teredo.remlab.net" log.close() return best_server def run(cmd): cmd = shlex.split(cmd) try: # hide console in MS windows startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW startupinfo.wShowWindow = subprocess.SW_HIDE #out = subprocess.check_output(cmd, startupinfo=startupinfo) process = subprocess.Popen(cmd, stdout=subprocess.PIPE, startupinfo=startupinfo) out, unused_err = process.communicate() retcode = process.poll() if retcode: return out + b"\n retcode:%s\n unused_err:%s\n" % (retcode, unused_err) except Exception as e: out = "Exception:%r" % e return utils.to_str(out, coding="gb18030") def run_cmds(cmds): log = Log() cmd_pl = cmds.split("\n") outs = [] for cmd in cmd_pl: if not cmd: continue if cmd.startswith("#"): log.write("%s" % cmd) continue log.write("\n>: %s\n------------------------------------" % cmd) out = run(cmd) log.write(out) outs.append(out) log.close() return "\r\n".join(outs) def get_line_value(r, n): r = utils.to_str(r) rls = r.split("\r\n") if len(rls) < n + 1: return None lp = rls[n].split(":") if len(lp) < 2: return None value = lp[1].strip() return value ================================================ FILE: code/default/gae_proxy/local/ipv6_tunnel/darwin.py ================================================ #!/usr/bin/env python2 # coding:utf-8 import os import sys from .common import * def state(): return "Developing" def state_pp(): return "Developing" def switch_pp(): return "Developing" def enable(is_local=False): return "Developing" def disable(is_local=False): return "Developing" def set_best_server(is_local=False): return "Developing" ================================================ FILE: code/default/gae_proxy/local/ipv6_tunnel/disable_ipv6.bat ================================================ @echo off echo Get Admin ::ver|findstr "[6,10]\.[0-9]\.[0-9][0-9]*" > nul && (goto Main) ::ver|findstr "[3-5]\.[0-9]\.[0-9][0-9]*" > nul && (goto isBelowNT6) :: :isBelowNT6 :Main @echo off cd /d "%~dp0" cacls.exe "%SystemDrive%\System Volume Information" >nul 2>nul if %errorlevel%==0 goto Admin if exist "%temp%\getadmin.vbs" del /f /q "%temp%\getadmin.vbs" echo Set RequestUAC = CreateObject^("Shell.Application"^)>"%temp%\getadmin.vbs" echo RequestUAC.ShellExecute "%~s0","","","runas",1 >>"%temp%\getadmin.vbs" echo WScript.Quit >>"%temp%\getadmin.vbs" "%temp%\getadmin.vbs" /f if exist "%temp%\getadmin.vbs" del /f /q "%temp%\getadmin.vbs" exit :Admin netsh interface teredo set state disable netsh interface 6to4 set state disabled netsh interface isatap set state disabled ================================================ FILE: code/default/gae_proxy/local/ipv6_tunnel/enable_ipv6.bat ================================================ :: XX-Net :: Enable IPV6 :: https://github.com/XX-net/XX-Net-dev/issues/53 :: https://www.zhihu.com/question/34541107/answer/137174053 @echo off echo Get Admin ::ver|findstr "[6,10]\.[0-9]\.[0-9][0-9]*" > nul && (goto Main) ::ver|findstr "[3-5]\.[0-9]\.[0-9][0-9]*" > nul && (goto isBelowNT6) :: :isBelowNT6 :Main @echo off cd /d "%~dp0" cacls.exe "%SystemDrive%\System Volume Information" >nul 2>nul if %errorlevel%==0 goto Admin if exist "%temp%\getadmin.vbs" del /f /q "%temp%\getadmin.vbs" echo Set RequestUAC = CreateObject^("Shell.Application"^)>"%temp%\getadmin.vbs" echo RequestUAC.ShellExecute "%~s0","","","runas",1 >>"%temp%\getadmin.vbs" echo WScript.Quit >>"%temp%\getadmin.vbs" "%temp%\getadmin.vbs" /f if exist "%temp%\getadmin.vbs" del /f /q "%temp%\getadmin.vbs" exit :Admin @echo off sc config RpcEptMapper start= auto sc start RpcEptMapper sc config DcomLaunch start= auto sc start DcomLaunch sc config RpcSs start= auto sc start RpcSs sc config nsi start= auto sc start nsi sc config Winmgmt start= auto sc start Winmgmt sc config Dhcp start= auto sc start Dhcp sc config WinHttpAutoProxySvc start= auto sc start WinHttpAutoProxySvc sc config iphlpsvc start= auto sc start iphlpsvc :: Reset IPv6 netsh interface ipv6 reset :: Reset Group Policy Teredo ..\..\..\..\..\python3.8.2\python.exe win_reset_gp.py netsh interface teredo set state type=enterpriseclient servername=teredo.remlab.net. :: Keep teredo interface route (not needed with reset?) :: route DELETE ::/0 :: netsh interface ipv6 add route ::/0 "Teredo Tunneling Pseudo-Interface" :: Set IPv6 prefixpolicies :: See https://tools.ietf.org/html/rfc3484 :: 2002::/16 6to4 tunnel :: 2001::/32 teredo tunnel; not default netsh interface ipv6 add prefixpolicy ::1/128 50 0 netsh interface ipv6 set prefixpolicy ::1/128 50 0 netsh interface ipv6 add prefixpolicy ::/0 40 1 netsh interface ipv6 set prefixpolicy ::/0 40 1 netsh interface ipv6 add prefixpolicy 2002::/16 30 2 netsh interface ipv6 set prefixpolicy 2002::/16 30 2 netsh interface ipv6 add prefixpolicy 2001::/32 25 5 netsh interface ipv6 set prefixpolicy 2001::/32 25 5 netsh interface ipv6 add prefixpolicy ::/96 20 3 netsh interface ipv6 set prefixpolicy ::/96 20 3 netsh interface ipv6 add prefixpolicy ::ffff:0:0/96 10 4 netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 10 4 :: Fix look up AAAA on teredo :: http://technet.microsoft.com/en-us/library/bb727035.aspx :: http://ipv6-or-no-ipv6.blogspot.com/2009/02/teredo-ipv6-on-vista-no-aaaa-resolving.html Reg add HKLM\SYSTEM\CurrentControlSet\services\Dnscache\Parameters /v AddrConfigControl /t REG_DWORD /d 0 /f :: Enable all IPv6 parts Reg add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters /v DisabledComponents /t REG_DWORD /d 0 /f ipconfig /flushdns set time=%date:~0,4%-%date:~5,2%-%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2% @call :output>..\..\..\..\..\data\gae_proxy\ipv6-state%time%.txt @echo Over @echo Reboot system at first time! exit :output @echo off ipconfig /all netsh interface ipv6 show teredo netsh interface ipv6 show route netsh interface ipv6 show interface netsh interface ipv6 show prefixpolicies netsh interface ipv6 show address route print notepad ..\..\..\..\..\data\gae_proxy\ipv6-state%time%.txt ================================================ FILE: code/default/gae_proxy/local/ipv6_tunnel/linux.py ================================================ #!/usr/bin/env python2 # coding:utf-8 import os import sys from .common import * def state(): return "Developing" def state_pp(): return "Developing" def switch_pp(): return "Developing" def enable(is_local=False): return "Developing" def disable(is_local=False): return "Developing" def set_best_server(is_local=False): return "Developing" ================================================ FILE: code/default/gae_proxy/local/ipv6_tunnel/pteredor.py ================================================ #!/usr/bin/env python # coding:utf-8 # A tool to help evaluate the teredo servers. # Thanks XndroidDev # Author: SeaHOH # Compatible: Python 2.7 & 3.4 & 3.5 & 3.6 # References: # https://tools.ietf.org/html/rfc4380 5.1 5.2 # https://tools.ietf.org/html/rfc4861 4.1 4.2 # https://tools.ietf.org/html/rfc2460 8.1 # https://github.com/XndroidDev/Xndroid/blob/master/fqrouter/manager/teredo.py __version__ = '0.1.0' import sys if sys.platform == 'win32' and sys.version_info[0] < 3: import win_inet_pton import os import socket import random import struct import collections import time import logging import select import errno import subprocess import threading from six.moves import queue as Queue try: _real_raw_input = raw_input def raw_input(s='', file=sys.stdout): if isinstance(s, str): file.write(s.encode(sys.getfilesystemencoding(), 'replace')) return _real_raw_input() else: return _real_raw_input(s) except NameError: raw_input = input logger = logging.getLogger('pteredor') teredo_timeout = 4 teredo_port = 3544 link_local_addr = 'fe80::ffff:ffff:ffff' all_router_multicast = 'ff02::2' teredo_server_list = [ # limited # 'teredo.ginzado.ne.jp', # disuse # 'debian-miredo.progsoc.org', # 'teredo.autotrans.consulintel.com', # 'teredo.ngix.ne.kr', # 'teredo.managemydedi.com', # 'teredo.ipv6.microsoft.com', # 'win8.ipv6.microsoft.com', 'teredo.remlab.net', 'teredo2.remlab.net', 'teredo-debian.remlab.net', 'teredo.trex.fi', 'teredo.iks-jena.de', 'win10.ipv6.microsoft.com', 'win1710.ipv6.microsoft.com', 'win1711.ipv6.microsoft.com' ] def creat_rs_nonce(): return struct.pack('d', random.randint(0, 1 << 62)) def creat_ipv6_rs_msg(checksum=None): return struct.pack('!2BH4x', 133, 0, checksum or 0) def in_checksum(data): n = len(data) f = '%dH' % (n // 2) if n % 2: f += 'B' s = sum(struct.unpack(f, data)) while (s >> 16): s = (s & 0xffff) + (s >> 16) s = ~s & 0xffff return socket.ntohs(s) class teredo_rs_packet(object): def __init__(self, nonce=None): self.rs_src = socket.inet_pton(socket.AF_INET6, link_local_addr) self.rs_dst = socket.inet_pton(socket.AF_INET6, all_router_multicast) self._icmpv6_rs_msg = creat_ipv6_rs_msg() self.nonce = nonce or creat_rs_nonce() self.rs_src = bytearray(self.rs_src) self.teredo_header = self.creat_teredo_header() def creat_teredo_header(self): return struct.pack('!H2x8sx', 1, self.nonce) def creat_ipv6_pseudo_header(self): return struct.pack('!16s16sI3xB', bytes(self.rs_src), self.rs_dst, 58, len(self._icmpv6_rs_msg) ) def creat_rs_packet(self, cone=None): self.rs_src[8] = 0x80 if cone else 0 pseudo_header = self.creat_ipv6_pseudo_header() checksum = in_checksum(self._icmpv6_rs_msg + pseudo_header) rs_msg = creat_ipv6_rs_msg(checksum) return self.teredo_header + struct.pack('!B4x3B16s16s', 0x60, len(rs_msg), 58, 255, bytes(self.rs_src), self.rs_dst ) + rs_msg @property def type_cone(self): if not hasattr(self, '_type_cone'): self._type_cone = self.creat_rs_packet(True) return self._type_cone @property def type_restricted(self): if not hasattr(self, '_type_restricted'): self._type_restricted = self.creat_rs_packet() return self._type_restricted def get_sock(port): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) while True: try: _port = port or random.randint(1025, 5000) print(('try bind local port:', _port)) sock.bind(('0.0.0.0', _port)) return sock except socket.error as e: if port: print(('bind local port %d fail: %r' % (_port, e))) return if e.args[0] == errno.EADDRINUSE: pass def is_ipv4(ip): try: socket.inet_aton(ip) except: return False else: return True def resolve(host): try: return socket.gethostbyname_ex(host)[-1] except: return [] def ip2int(ip): return struct.unpack('>I', socket.inet_aton(ip))[0] def int2ip(int): return socket.inet_ntoa(struct.pack('>I', int)) def get_second_server_ip(ip): return int2ip(ip2int(ip) + 1) def remove_same_server(server_ip_list): logger.debug('input ip: %s' % server_ip_list) cleared_list = set() for ip1 in server_ip_list: _ip1 = ip2int(ip1) for ip2 in server_ip_list: b = _ip1 - ip2int(ip2) if b in (1, -1): cleared_list.add(ip1 if b < 0 else ip2) break if b not in (1, -1): cleared_list.add(ip1) logger.debug('cleared ip: %s' % cleared_list) return cleared_list def str2hex(str): str = bytearray(str) h = [''] for c in str: if c > 0xf: h.append(hex(c)[2:]) else: h.append('0' + hex(c)[2:]) return '\\x'.join(h) class deque(collections.deque): def put(self, v): self.append(v) def get(self): try: return self.popleft() except: return None class default_prober_dict(dict): def __init__(self): self['nonce'] = None self['rs_packet'] = None self['ra_packets'] = deque() class teredo_prober(object): _stoped = None nat_type = 'null' qualified = False rs_cone_flag = 1 timeout = teredo_timeout teredo_port = teredo_port def __init__(self, server_list=teredo_server_list, local_port=None, remote_port=None, probe_nat=True): self.teredo_sock = get_sock(local_port) if remote_port: self.teredo_port = remote_port self.prober_dict = collections.defaultdict(default_prober_dict) self.ip2server = collections.defaultdict(list) server_ip_list = [] if isinstance(server_list, str): server_list = [server_list] for server in server_list: if is_ipv4(server): server_ip_list.append(server) else: ip_list = resolve(server) for ip in ip_list: self.ip2server[ip].append(server) server_ip_list += ip_list self.server_ip_list = remove_same_server(server_ip_list) if len(self.server_ip_list) < 1: msg = 'Servers could not be resolved, %r.' % server_list print(msg) raise Exception(msg) elif len(self.server_ip_list) < 2: print(('Need input more teredo servers, now is %d.' % len(self.server_ip_list))) threading.Thread(target=self.receive_loop, name="teredo_recieve_loop").start() if probe_nat: self.nat_type = self.nat_type_probe() def unpack_indication(self, data): return struct.unpack('!2s4s', data[2:8]) def handle_ra_packet(self, ipv6_pkt): server_ip = socket.inet_ntoa(ipv6_pkt[76:80]) cone_flag = bytearray(ipv6_pkt)[32] >> 7 & 1 logger.debug('ipv6_pkt ; RA_cone = %s\nsrc:%s\ndst:%s' % ( cone_flag, str2hex(ipv6_pkt[8:24]), str2hex(ipv6_pkt[24:40]))) return server_ip, cone_flag def receive_ra_packet(self): data, addr = self.teredo_sock.recvfrom(10240) received_ip, port = addr if port != self.teredo_port or len(data) < 40: logger.debug('ipv6_pkt ;1 drop:\n%s' % str2hex(data)) return auth_pkt = indicate_pkt = ipv6_pkt = None if data[0:2] == b'\x00\x01': auth_len = 13 + sum(struct.unpack('2B', data[2:4])) auth_pkt = data[0:auth_len] if data[auth_len:auth_len + 2] == b'\x00\x00': indicate_pkt = data[auth_len:auth_len + 8] ipv6_pkt = data[auth_len + 8:] if (auth_pkt is None or indicate_pkt is None or ipv6_pkt is None or bytearray(ipv6_pkt)[0] & 0xf0 != 0x60 or bytearray(ipv6_pkt)[40] != 134 or struct.unpack('!H', ipv6_pkt[4:6])[0] + 40 != len(ipv6_pkt) ): logger.debug('ipv6_pkt ;2 drop:\n%s' % str2hex(data)) return server_ip, ra_cone_flag = self.handle_ra_packet(ipv6_pkt) logger.debug('server ip: %s ; received ip: %s' % (server_ip, received_ip)) if (received_ip != server_ip and received_ip != get_second_server_ip(server_ip) or auth_pkt[4:12] != self.prober_dict[server_ip]['rs_packet'].nonce ): logger.debug('ipv6_pkt ;3 drop:\n%s' % str2hex(data)) return qualified = ra_cone_flag, indicate_pkt self.prober_dict[received_ip]['ra_packets'].put(qualified) def receive_loop(self): while not self._stoped: try: rd, _, _ = select.select([self.teredo_sock], [], [], 0.5) if rd and not self._stoped: self.receive_ra_packet() except Exception as e: logger.exception('receive procedure fail once: %r', e) pass def send_rs_packet(self, rs_packet, dst_ip): rs_packet = rs_packet.type_cone if self.rs_cone_flag else rs_packet.type_restricted logger.debug('send ; RS_cone = %s\n%s' % (self.rs_cone_flag, str2hex(rs_packet))) self.teredo_sock.sendto(rs_packet, (dst_ip, self.teredo_port)) def qualify(self, server_ip, second_server_ip=None): rs_packet = self.prober_dict[server_ip]['rs_packet'] if rs_packet is None: self.prober_dict[server_ip]['rs_packet'] = rs_packet = teredo_rs_packet() dst_ip = second_server_ip or server_ip self.send_rs_packet(rs_packet, dst_ip) begin_recv = time.time() while time.time() < self.timeout + begin_recv: qualified = self.prober_dict[dst_ip]['ra_packets'].get() if qualified: return qualified time.sleep(0.01) def qualify_loop(self, server_ip, second_server=None): if second_server: self.rs_cone_flag = 0 second_server_ip = get_second_server_ip(server_ip) else: second_server_ip = None for i in range(3): try: return self.qualify(server_ip, second_server_ip) except Exception as e: logger.exception('qualify procedure fail once: %r', e) def nat_type_probe(self): print('Starting probe NAT type...') self.nat_type = 'probing' server_ip_list = self.server_ip_list.copy() self.rs_cone_flag = 1 for server_ip in server_ip_list: qualified = self.qualify_loop(server_ip) if qualified: break if qualified is None: self.rs_cone_flag = 0 while server_ip_list: server_ip = server_ip_list.pop() qualified = self.qualify_loop(server_ip) if qualified: break if qualified is None: self.qualified = False return 'offline' ra_cone_flag, first_indicate = qualified if ra_cone_flag: self.qualified = True return 'cone' qualified = None qualified = self.qualify_loop(server_ip, second_server=True) if qualified is None: self.last_server_ip = server_ip self.qualified = True return 'unknown' ra_cone_flag, second_indicate = qualified if first_indicate == second_indicate: self.qualified = True return 'restricted' else: self.qualified = False return 'symmetric' def _eval_servers(self, server_ip, queue_obj): start = time.time() qualified = self.qualify_loop(server_ip) cost = int((time.time() - start) * 1000) queue_obj.put((bool(qualified), self.ip2server[server_ip], server_ip, cost)) def eval_servers(self): if self.nat_type == 'null': self.nat_type = self.nat_type_probe() elif self.nat_type == 'probing': print('Is probing NAT type now, pleace wait...') while self.nat_type == 'probing': time.sleep(0.1) if not self.qualified: print(('This device can not use teredo tunnel, the NAT type is %s!' % self.nat_type)) return [] print('Starting evaluate servers...') self.clear() eval_list = [] queue_obj = Queue.Queue() for server_ip in self.server_ip_list: threading.Thread(target=self._eval_servers, args=(server_ip, queue_obj), name="teredor_eval").start() for _ in self.server_ip_list: eval_list.append(queue_obj.get()) return eval_list def close(self): self._stoped = True self.clear() if self.teredo_sock: self.teredo_sock.close() self.teredo_sock = None def clear(self): for server_ip in self.server_ip_list: second_server_ip = get_second_server_ip(server_ip) self.prober_dict.pop(server_ip, None) self.prober_dict.pop(second_server_ip, None) local_ip_startswith = tuple( ['192.168', '10.'] + ['100.%d.' % (64 + n) for n in range(1 << 6)] + ['172.%d.' % (16 + n) for n in range(1 << 4)] ) import locale zh_locale = None try: zh_locale = locale.getdefaultlocale()[0] == 'zh_CN' except: if sys.platform == "darwin": try: oot = os.pipe() p = subprocess.Popen(['/usr/bin/defaults', 'read', 'NSGlobalDomain', 'AppleLanguages'], stdout=oot[1]) p.communicate() zh_locale = b'zh' in os.read(oot[0], 10000) except: pass if zh_locale: help_info = ''' pteredor [-p ] [-P ] [-h] [ [ [...]]] -p \u8bbe\u7f6e\u672c\u5730\u5ba2\u6237\u7aef\u7aef\u53e3\u3002 -P \u8bbe\u7f6e\u8fdc\u7a0b\u670d\u52a1\u7aef\u7aef\u53e3\u3002 -h \u663e\u793a\u672c\u5e2e\u52a9\u4fe1\u606f\u3002 Teredo server \u662f\u4e00\u4e2a\u4e3b\u673a\u540d\uff0c\u53ef\u4ee5\u4f7f\u7528\u57df\u540d\u6216 IP\u3002 ''' result_info = '\n\u7ecf\u68c0\u6d4b\uff0c\u63a8\u8350\u670d\u52a1\u5668\u662f %r.' wait_info = '\u8bf7\u7b49\u5f85 10 \u79d2\u949f\u2026\u2026' resume_info = 'Teredo \u5ba2\u6237\u7aef\u5df2\u6062\u590d\u8fd0\u884c\u3002' warn_1 = '\u53c2\u6570 "-p" \u9519\u8bef\uff1a\u7aef\u53e3\u5fc5\u987b\u662f\u4e00\u4e2a\u6570\u5b57\u3002' warn_2 = '\u53c2\u6570 "-P" \u9519\u8bef\uff1a\u7aef\u53e3\u5fc5\u987b\u662f\u4e00\u4e2a\u6570\u5b57\u3002' warn_3 = '\u5f53\u524d\u8bbe\u5907\u53ef\u80fd\u65e0\u6cd5\u6b63\u5e38\u4f7f\u7528 teredo \u96a7\u9053\uff0cNAT \u7c7b\u578b\u662f %s\uff01' warn_4 = '\u65e0\u6cd5\u5224\u65ad NAT \u7c7b\u578b\u3002' confirm_stop = '\u662f\u5426\u5148\u6682\u65f6\u5173\u95ed teredo \u5ba2\u6237\u7aef\uff08IPv6\uff09\u518d\u8fdb\u884c\u6d4b\u8bd5\uff1f\uff08Y/N\uff09' confirm_set = '\u4f60\u60f3\u8981\u5c06 teredo \u670d\u52a1\u5668\u8bbe\u7f6e\u4e3a\u672c\u6d4b\u8bd5\u7684\u63a8\u8350\u503c\u5417\uff1f\uff08Y/N\uff09' confirm_reset = '\u4f60\u60f3\u8981\u91cd\u7f6e teredo \u5ba2\u6237\u7aef\u7684\u5237\u65b0\u95f4\u9694\u5417\uff1f\uff08Y/N\uff09' confirm_over = '\u6309\u56de\u8f66\u952e\u7ed3\u675f\u2026\u2026' confirm_force = '\u4f60\u60f3\u8981\u7ee7\u7eed\u8fdb\u884c\u6d4b\u8bd5\u5417\uff1f\uff08Y/N\uff09' nat_type_result = 'NAT \u7c7b\u578b\u662f %s\u3002' else: help_info = ''' pteredor [-p ] [-P ] [-h] [ [ [...]]] -p Set the local port num. (client) -P Set the remote port num. (server) -h Show this help. The teredo server is a host name (domain or IP). ''' result_info = '\nThe recommend server is %r.' wait_info = 'Please wait 10 seconds...' resume_info = 'The teredo cilent has resumed.' warn_1 = 'The value of parameter "-p" error: local port must be a number.' warn_2 = 'The value of parameter "-P" error: remote port must be a number.' warn_3 = 'This device may not be able to use teredo tunnel, the NAT type is %s!' warn_4 = 'We can not judge the NAT type.' confirm_stop = 'Stop teredo cilent for run prober, Y/N? ' confirm_set = 'Do you want to set recommend teredo server, Y/N? ' confirm_reset = 'Do you want to reset refreshinterval to the default value, Y/N? ' confirm_over = 'Press enter to over...' confirm_force = 'Do you want to force probe and set the teredo servers, Y/N? ' nat_type_result = 'The NAT type is %s.' if os.name == 'nt': from . import win32runas if win32runas.is_admin(): runas = os.system else: def runas(cmd): cmd = tuple(cmd.split(None, 1)) if len(cmd) == 1: cmd += None, win32runas.runas(cmd[1], cmd[0]) def main(local_port=None, remote_port=None, *args): server_list = [] + teredo_server_list for arg in args: if isinstance(arg, str): server_list.append(arg) elif isinstance(arg, list): server_list += arg elif isinstance(arg, tuple): server_list += list(arg) prober = teredo_prober(server_list, local_port=local_port, remote_port=remote_port) need_probe = recommend = None if not prober.qualified: print((warn_3 % prober.nat_type)) if (prober.nat_type == 'symmetric' and input(confirm_force).lower() == 'y'): need_probe = True prober.qualified = True elif prober.nat_type == 'unknown': print(warn_4) recommend = prober.ip2server[prober.last_server_ip] else: print((nat_type_result % prober.nat_type)) need_probe = True if need_probe: qualified_list = prober.eval_servers() for qualified, server, server_ip, cost in qualified_list: print(('%s %s %s' % (server_ip, server, '%sms' % cost if qualified else 'timedout'))) recommend = qualified_list[0][1] prober.close() return recommend, prober.nat_type def test(): logging.basicConfig(level=logging.DEBUG) blank_rs_packet = bytearray( b'\x00\x01\x00\x00\x8a\xde\xb0\xd0\x2e\xea\x0b\xfc\x00' b'\x60\x00\x00\x00\x00\x08\x3a\xff\xfe\x80\x00\x00\x00\x00\x00\x00' b'\x00\x00\xff\xff\xff\xff\xff\xff\xff\x02\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00\x00\x00\x00\x02\x85\x00\x7d\x37\x00\x00\x00\x00') nonce = creat_rs_nonce() blank_rs_packet[4:12] = nonce assert (teredo_rs_packet(nonce).type_restricted == bytes(blank_rs_packet)) server_list = ['teredo.remlab.net', 'win1710.ipv6.microsoft.com'] prober = teredo_prober(server_list, probe_nat=False) prober.timeout = 4 server_ip_list = prober.server_ip_list.copy() server_ip = server_ip_list.pop() for _ in range(2): print((prober.qualify_loop(server_ip))) prober.rs_cone_flag = prober.rs_cone_flag ^ 1 server_ip = server_ip_list.pop() for _ in range(2): print((prober.qualify_loop(server_ip))) prober.rs_cone_flag = prober.rs_cone_flag ^ 1 # prober.close() print((main())) input(confirm_over) sys.exit(0) if '__main__' == __name__: # test() args = sys.argv[1:] if '-h' in args: args.remove('-h') print(help_info) if not args: input(confirm_over) sys.exit(0) try: local_port = args[args.index('-p') + 1] args.remove('-p') args.remove(local_port) try: local_port = int(local_port) except: local_port = None print(warn_1) except: local_port = None try: remote_port = args[args.index('-P') + 1] args.remove('-P') args.remove(remote_port) try: remote_port = int(remote_port) except: remote_port = None print(warn_2) except: remote_port = None done_disabled = False if os.name == 'nt': if input(confirm_stop).lower() == 'y': if runas('netsh interface teredo set state disable'): done_disabled = True win32runas.runas("win_reset_gp.py") print((os.system('netsh interface teredo show state'))) recommend, nat_type = main(*args, local_port=local_port, remote_port=remote_port) print((result_info % recommend)) if os.name == 'nt': ip = [a for a in os.popen('route print').readlines() if ' 0.0.0.0 ' in a][0].split()[-2] if nat_type == 'cone': client = 'client' else: import platform client_ext = 'natawareclient' if platform.version()[0] > '6' else 'enterpriseclient' client = client_ext if ip.startswith(local_ip_startswith) else 'client' if recommend: if os.name == 'nt' and \ input(confirm_set).lower() == 'y': cmd = 'netsh interface teredo set state type=%s servername=%s.' if input(confirm_reset).lower() == 'y': cmd += ' refreshinterval=default' if not remote_port: cmd += ' clientport=default' runas(cmd % (client, recommend[0])) print(wait_info) time.sleep(10) print((os.system('netsh interface teredo show state'))) done_disabled = False if done_disabled: if runas('netsh interface teredo set state type=%s' % client): print(resume_info) input(confirm_over) ================================================ FILE: code/default/gae_proxy/local/ipv6_tunnel/unknown.py ================================================ #!/usr/bin/env python2 # coding:utf-8 import os import sys from .common import * def state(): return "Developing" def state_pp(): return "Developing" def switch_pp(): return "Developing" def enable(is_local=False): return "Developing" def disable(is_local=False): return "Developing" def set_best_server(is_local=False): return "Developing" ================================================ FILE: code/default/gae_proxy/local/ipv6_tunnel/win10.py ================================================ #!/usr/bin/env python2 # coding:utf-8 import os import sys import time import socket import platform import env_info from .common import * from . import win32runas from .pteredor import local_ip_startswith current_path = os.path.dirname(os.path.abspath(__file__)) python_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir)) root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir)) data_path = os.path.join(env_info.data_path, "gae_proxy") if not os.path.isdir(data_path): data_path = current_path if __name__ == "__main__": noarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch')) sys.path.append(noarch_lib) if sys.platform == "win32": win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32')) sys.path.append(win32_lib) # TODO:Help to reset ipv6 if system Teredo Interface not exist # download http://download.microsoft.com/download/3/F/3/3F3CA0F7-2FAF-4C51-8DDF-3516B4D91975/MicrosoftEasyFix20164.mini.diagcab # TODO: Win7 need to change the interface name as the real one. # can use ifconfig to get it. # TODO; Win10 Home and Win10 Profession is different. enable_ipv6_temp = os.path.join(current_path, 'enable_ipv6_temp.bat') disable_ipv6_temp = os.path.join(current_path, 'disable_ipv6_temp.bat') set_best_server_temp = os.path.join(current_path, 'set_best_server_temp.bat') enable_cmds = """ @echo Starting... @set log_file="{}" @echo Config servers... @call:[config servers]>>%log_file% @echo Reset IPv6... @call:[reset ipv6]>>%log_file% @echo Set IPv6 Tunnel... @call:[set ipv6]>>%log_file% @call:[print state]>>%log_file% @echo Over @echo Reboot system at first time! @pause exit :[config servers] sc config RpcEptMapper start= auto sc start RpcEptMapper sc config DcomLaunch start= auto sc start DcomLaunch sc config RpcSs start= auto sc start RpcSs sc config nsi start= auto sc start nsi sc config Winmgmt start= auto sc start Winmgmt sc config Dhcp start= auto sc start Dhcp sc config WinHttpAutoProxySvc start= auto sc start WinHttpAutoProxySvc sc config iphlpsvc start= auto sc start iphlpsvc goto :eof :[reset ipv6] netsh interface ipv6 reset ipconfig /flushdns goto :eof :[set ipv6] :: Reset Group Policy Teredo SET PYTHONPATH= SET PYTHONHOME= "{}" "{}\\win_reset_gp.py" """.format(log_file, sys.executable, current_path) + \ """ netsh interface teredo set state type={} servername={}. :: Set IPv6 prefixpolicies :: See https://tools.ietf.org/html/rfc3484 :: 2002::/16 6to4 tunnel :: 2001::/32 teredo tunnel; not default netsh interface ipv6 add prefixpolicy ::1/128 50 0 netsh interface ipv6 set prefixpolicy ::1/128 50 0 netsh interface ipv6 add prefixpolicy ::/0 40 1 netsh interface ipv6 set prefixpolicy ::/0 40 1 netsh interface ipv6 add prefixpolicy 2002::/16 30 2 netsh interface ipv6 set prefixpolicy 2002::/16 30 2 netsh interface ipv6 add prefixpolicy 2001::/32 25 5 netsh interface ipv6 set prefixpolicy 2001::/32 25 5 netsh interface ipv6 add prefixpolicy ::/96 20 3 netsh interface ipv6 set prefixpolicy ::/96 20 3 netsh interface ipv6 add prefixpolicy ::ffff:0:0/96 10 4 netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 10 4 :: Fix look up AAAA on teredo :: http://technet.microsoft.com/en-us/library/bb727035.aspx :: http://ipv6-or-no-ipv6.blogspot.com/2009/02/teredo-ipv6-on-vista-no-aaaa-resolving.html Reg add HKLM\SYSTEM\CurrentControlSet\services\Dnscache\Parameters /v AddrConfigControl /t REG_DWORD /d 0 /f :: Enable all IPv6 parts Reg add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters /v DisabledComponents /t REG_DWORD /d 0 /f goto :eof :[print state] :: Show state ipconfig /all netsh interface ipv6 show teredo netsh interface ipv6 show route netsh interface ipv6 show interface netsh interface ipv6 show prefixpolicies netsh interface ipv6 show address route print goto :eof """ disable_cmds=""" netsh interface teredo set state disable netsh interface 6to4 set state disabled netsh interface isatap set state disabled """ has_admin = win32runas.is_admin() # Use this if need admin # Don't hide the console window def elevate(script_path, clear_log=True): global script_is_running if not script_is_running: script_is_running = True if clear_log and os.path.isfile(log_file): try: os.remove(log_file) except Exception as e: xlog.warn("remove %s fail:%r", log_file, e) try: win32runas.runas(None, script_path) return True except Exception as e: xlog.warning('elevate e:%r', e) finally: script_is_running = False script_is_running = False last_get_state_time = 0 last_set_server_time = 0 last_state = "unknown" client_ext = 'natawareclient' if platform.version()[0] > '6' else 'enterpriseclient' def client_type(): try: ip = [line for line in run("route print").split("\r\n") if " 0.0.0.0 " in line][0].split()[-2] except: xlog.warning('route setting may wrong, please check.') return 'client' return client_ext if ip.startswith(local_ip_startswith) else 'client' def get_teredo_interface(): r = run("ipconfig /all") return "Developing" def state(): global last_get_state_time, last_state if time.time() - last_get_state_time < 5: return last_state last_get_state_time = time.time() r = run("netsh interface teredo show state") xlog.debug("netsh state: %s", r) type = get_line_value(r, 2) if type == "disabled": last_state = "disabled" else: last_state = get_line_value(r, 6) or "unknown" if "probe" in last_state: last_state = "probe" return last_state def state_pp(): return "Developing" def switch_pp(): return "Developing" def enable(is_local=False): if not is_local: return "Please operating on local host." if script_is_running or pteredor_is_running: return "Script is running, please retry later." else: new_enable_cmds = enable_cmds.format(client_type(), best_server()) with open(enable_ipv6_temp, 'w') as fp: fp.write(new_enable_cmds) done = elevate(enable_ipv6_temp, False) if done: global last_set_server_time last_set_server_time = time.time() return "IPv6 tunnel is enabled, please reboot system." else: return "Enable IPv6 tunnel fail, you must authorized as admin." def disable(is_local=False): if not is_local: return "Please operating on local host." if script_is_running or pteredor_is_running: return "Script is running, please retry later." else: with open(disable_ipv6_temp, 'w') as fp: fp.write(disable_cmds) done = elevate(disable_ipv6_temp) if done: return "IPv6 tunnel is disabled." else: return "Disable IPv6 tunnel fail, you must authorized as admin." def set_best_server(is_local=False): # Allow remote if has admin if not is_local and not has_admin: return "Please operating on local host." if script_is_running or pteredor_is_running: return "Script is running, please retry later." else: global last_set_server_time now = time.time() wait_time = 3 - (now - last_set_server_time) // 60 if wait_time > 0: return "Don't do this repeated, please retry in %d minutes later." % wait_time set_server_cmds = ("netsh interface teredo set state %s %s. default default default" % (client_type(), best_server())) with open(set_best_server_temp, 'w') as fp: fp.write(set_server_cmds) done = elevate(set_best_server_temp, False) if done: last_set_server_time = now return "Set teredo server is completed." else: return "Set teredo server fail, you must authorized as admin." if __name__ == '__main__': enable(True) ================================================ FILE: code/default/gae_proxy/local/ipv6_tunnel/win32runas.py ================================================ # coding:utf-8 # run as admin in Windows import os import sys import ctypes import subprocess from ctypes import c_ulong, c_char_p, c_int, c_void_p from ctypes.wintypes import HANDLE, DWORD, HWND, HINSTANCE, HKEY def is_admin(): try: return ctypes.windll.shell32.IsUserAnAdmin() except: return False def encode_for_locale(s): if s is None: return return s.encode('mbcs') if os.name == 'nt': class ShellExecuteInfo(ctypes.Structure): _fields_ = [('cbSize', DWORD), ('fMask', c_ulong), ('hwnd', HWND), ('lpVerb', c_char_p), ('lpFile', c_char_p), ('lpParameters', c_char_p), ('lpDirectory', c_char_p), ('nShow', c_int), ('hInstApp', HINSTANCE), ('lpIDList', c_void_p), ('lpClass', c_char_p), ('hKeyClass', HKEY), ('dwHotKey', DWORD), ('hIcon', HANDLE), ('hProcess', HANDLE)] SEE_MASK_NOCLOSEPROCESS = 0x00000040 ShellExecuteEx = ctypes.windll.Shell32.ShellExecuteEx ShellExecuteEx.argtypes = ctypes.POINTER(ShellExecuteInfo), WaitForSingleObject = ctypes.windll.kernel32.WaitForSingleObject SE_ERR_CODES = { 0: 'Out of memory or resources', 2: 'File not found', 3: 'Path not found', 5: 'Access denied', 8: 'Out of memory', 26: 'Cannot share an open file', 27: 'File association information not complete', 28: 'DDE operation timed out', 29: 'DDE operation failed', 30: 'DDE operation is busy', 31: 'File association not available', 32: 'Dynamic-link library not found', } sys.argv[0] = os.path.abspath(sys.argv[0]) def runas(args=sys.argv, executable=sys.executable, cwd=None, nShow=1, waitClose=True, waitTimeout=-1): if not 0 <= nShow <= 10: nShow = 1 err = None try: if args is not None and not isinstance(args, str): args = subprocess.list2cmdline(args) pExecInfo = ShellExecuteInfo() pExecInfo.cbSize = ctypes.sizeof(pExecInfo) pExecInfo.fMask |= SEE_MASK_NOCLOSEPROCESS pExecInfo.lpVerb = b'open' if is_admin() else b'runas' pExecInfo.lpFile = encode_for_locale(executable) pExecInfo.lpParameters = encode_for_locale(args) pExecInfo.lpDirectory = encode_for_locale(cwd) pExecInfo.nShow = nShow if ShellExecuteEx(pExecInfo): if waitClose: WaitForSingleObject(pExecInfo.hProcess, waitTimeout) return True else: return pExecInfo.hProcess else: err = SE_ERR_CODES.get(pExecInfo.hInstApp, 'unknown') except Exception as e: err = e if err: print(('runas failed! error: %r' % err)) if __name__ == '__main__': if len(sys.argv) > 1: runas(sys.argv[2:], sys.argv[1]) ================================================ FILE: code/default/gae_proxy/local/ipv6_tunnel/win_reset_gp.py ================================================ # coding:utf-8 import os import sys import platform import ctypes import win32runas def win32_notify( msg='msg', title='Title'): res = ctypes.windll.user32.MessageBoxW(None, msg, title, 1) # Yes:1 No:2 return res == 1 def reset_teredo(): gp_split = b'[\x00' gp_teredo = 'v6Transition\x00;Teredo' gp_teredo = '\x00'.join(b for b in gp_teredo).encode() with open(gp_regpol_file, 'rb') as f: gp_regpol_old = f.read().split(gp_split) gp_regpol_new = [gp for gp in gp_regpol_old if gp_teredo not in gp] if len(gp_regpol_new) != len(gp_regpol_old) and \ win32_notify('发现组策略 Teredo 设置,是否重置?', '提醒'): with open(gp_regpol_file, 'wb') as f: f.write(gp_split.join(gp_regpol_new)) os.system(sysnative + '\\gpupdate /target:computer /force') if '__main__' == __name__: if os.name != 'nt': sys.exit(0) sysver = platform.version() if sysver < '6': # Teredo item was added to Group Policy starting with Windows Vista sys.exit(0) windir = os.environ.get('windir') if not windir: sys.exit(-1) sys64 = os.path.exists(windir + '\\SysWOW64') pe32 = platform.architecture()[0] == '32bit' sysalias = 'Sysnative' if sys64 and pe32 else 'System32' sysnative = '%s\\%s' % (windir, sysalias) gp_regpol_file = sysnative + '\\GroupPolicy\\Machine\\Registry.pol' if os.path.exists(gp_regpol_file): if not win32runas.is_admin(): win32runas.runas() sys.exit(0) reset_teredo() ================================================ FILE: code/default/gae_proxy/local/proxy.py ================================================ #!/usr/bin/env python2 # coding:utf-8 # Based on GAppProxy 2.0.0 by Du XiaoGang # Based on WallProxy 0.4.0 by Hust Moon # Contributor: # Phus Lu # Hewig Xu # Ayanamist Yang # V.E.O # Max Lv # AlsoTang # Christopher Meng # Yonsm Guo # Parkman # Ming Bai # Bin Yu # lileixuan # Cong Ding # Zhang Youfu # Lu Wei # Harmony Meow # logostream # Rui Wang # Wang Wei Qiang # Felix Yan # QXO # Geek An # Poly Rabbit # oxnz # Shusen Liu # Yad Smood # Chen Shuang # cnfuyu # cuixin import sys import os import traceback import platform import threading current_path = os.path.dirname(os.path.abspath(__file__)) root_path = os.path.abspath( os.path.join(current_path, os.pardir, os.pardir)) gae_proxy_path = os.path.join(root_path, "gae_proxy") python_path = root_path noarch_lib = os.path.abspath( os.path.join(python_path, 'lib', 'noarch')) sys.path.append(noarch_lib) import env_info data_path = env_info.data_path data_gae_proxy_path = os.path.join(data_path, 'gae_proxy') if sys.platform == "win32": win32_lib = os.path.abspath( os.path.join(python_path, 'lib', 'win32')) sys.path.append(win32_lib) elif sys.platform.startswith("linux"): linux_lib = os.path.abspath( os.path.join(python_path, 'lib', 'linux')) sys.path.append(linux_lib) elif sys.platform == "darwin": darwin_lib = os.path.abspath( os.path.join(python_path, 'lib', 'darwin')) sys.path.append(darwin_lib) extra_lib = "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python" sys.path.append(extra_lib) __file__ = os.path.abspath(__file__) if os.path.islink(__file__): __file__ = getattr(os, 'readlink', lambda x: x)(__file__) work_path = os.path.dirname(os.path.abspath(__file__)) os.chdir(work_path) sys.path.append(root_path) from gae_proxy.local.cert_util import CertUtil from gae_proxy.local import proxy_handler from gae_proxy.local.front import front, direct_front def check_create_data_path(): if not os.path.isdir(data_path): os.mkdir(data_path) if not os.path.isdir(data_gae_proxy_path): os.mkdir(data_gae_proxy_path) from xlog import getLogger xlog = getLogger("gae_proxy") xlog.set_buffer(1000) import simple_http_server import env_info proxy_server = None # launcher/module_init will check this value for start/stop finished ready = False def log_info(): xlog.info('------------------------------------------------------') xlog.info('Python Version : %s', platform.python_version()) xlog.info('OS : %s', env_info.os_detail()) xlog.info('Listen Address : %s:%d', front.config.listen_ip, front.config.listen_port) if front.config.PROXY_ENABLE: xlog.info('%s Proxy : %s:%s', front.config.PROXY_TYPE, front.config.PROXY_HOST, front.config.PROXY_PORT) if len(front.config.GAE_APPIDS): xlog.info('GAE APPID : %s', '|'.join(front.config.GAE_APPIDS)) else: xlog.info("Using public APPID") xlog.info('------------------------------------------------------') def main(args): global ready, proxy_server no_mess_system = args.get("no_mess_system", 0) allow_remote = args.get("allow_remote", 0) check_create_data_path() log_info() threading.Thread(target=CertUtil.init_ca, args=(no_mess_system,), name="init_ca").start() listen_ips = front.config.listen_ip if isinstance(listen_ips, str): listen_ips = [listen_ips] else: listen_ips = list(listen_ips) if allow_remote and ("0.0.0.0" not in listen_ips or "::" not in listen_ips): listen_ips = [("0.0.0.0"), ] addresses = [(listen_ip, front.config.listen_port) for listen_ip in listen_ips] front.start() direct_front.start() proxy_server = simple_http_server.HTTPServer( addresses, proxy_handler.GAEProxyHandler, logger=xlog) ready = True # checked by launcher.module_init proxy_server.serve_forever() # called by launcher/module/stop def terminate(): global ready, proxy_server xlog.info("start to terminate GAE_Proxy") ready = False front.stop() direct_front.stop() proxy_server.shutdown() if __name__ == '__main__': try: main({}) except Exception: traceback.print_exc(file=sys.stdout) except KeyboardInterrupt: terminate() sys.exit() ================================================ FILE: code/default/gae_proxy/local/proxy_handler.py ================================================ #!/usr/bin/env python # coding:utf-8 """ GAEProxyHandler is the handler of http proxy port. default to 8087 if HTTP request: do_METHOD() elif HTTPS request: do_CONNECT() What is Direct mode: if user access google site like www.google.com, client.google.com, we don't need forward request to GAE server. we can send the original request to google ip directly. because most google ip act as general front server. Youtube content server do not support direct mode. look direct_handler.py for more detail. What GAE mode: Google App Engine support urlfetch for proxy. every google account can apply 12 appid. after deploy server code under gae_proxy/server/gae to GAE server, user can use GAE server as http proxy. Here is the global link view: Browser => GAE_proxy => GAE server => target http/https server. look gae_hander.py for more detail. """ import errno import socket import ssl try: import OpenSSL NetWorkIOError = (socket.error, ssl.SSLError, OpenSSL.SSL.Error, OSError) except: NetWorkIOError = (socket.error, ssl.SSLError, OSError) try: from urllib.parse import urlparse except ImportError: from urlparse import urlparse from xlog import getLogger xlog = getLogger("gae_proxy") import simple_http_client import simple_http_server from gae_proxy.local.cert_util import CertUtil from gae_proxy.local import gae_handler from gae_proxy.local import direct_handler from gae_proxy.local import web_control import utils from gae_proxy.local.front import front class GAEProxyHandler(simple_http_server.HttpServerHandler): gae_support_methods = tuple([b"GET", b"POST", b"HEAD", b"PUT", b"DELETE", b"PATCH"]) # GAE don't support command like OPTION bufsize = 65535 local_names = [] self_check_response_data = b"HTTP/1.1 200 OK\r\n" \ b"Access-Control-Allow-Origin: *\r\n" \ b"Cache-Control: no-cache, no-store, must-revalidate\r\n" \ b"Pragma: no-cache\r\n" \ b"Expires: 0\r\n" \ b"Content-Type: text/plain\r\n" \ b"Keep-Alive:\r\n" \ b"Persist:\r\n" \ b"Connection: Keep-Alive, Persist\r\n" \ b"Content-Length: 2\r\n\r\nOK" fake_host = utils.to_bytes(web_control.get_fake_host()) def setup(self): self.__class__.do_GET = self.__class__.do_METHOD self.__class__.do_PUT = self.__class__.do_METHOD self.__class__.do_POST = self.__class__.do_METHOD self.__class__.do_HEAD = self.__class__.do_METHOD self.__class__.do_DELETE = self.__class__.do_METHOD self.__class__.do_OPTIONS = self.__class__.do_METHOD def forward_local(self): """ If browser send localhost:xxx request to GAE_proxy, we forward it to localhost. """ request_headers = dict((k.title(), v) for k, v in list(self.headers.items())) payload = b'' if b'Content-Length' in request_headers: try: payload_len = int(request_headers.get(b'Content-Length', 0)) payload = self.rfile.read(payload_len) except Exception as e: xlog.warn('forward_local read payload failed:%s', e) return response = simple_http_client.request(self.command, self.path, request_headers, payload) if not response: xlog.warn("forward_local fail, command:%s, path:%s, headers: %s, payload: %s", self.command, self.path, request_headers, payload) return out_list = [] out_list.append(b"HTTP/1.1 %d\r\n" % response.status) for key in response.headers: key = key.title() out_list.append(b"%s: %s\r\n" % (key, response.headers[key])) out_list.append(b"\r\n") out_list.append(response.text) self.wfile.write(b"".join(out_list)) def send_method_allows(self, headers, payload): xlog.debug("send method allow list for:%s %s", self.command, self.path) # Refer: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests response = \ b"HTTP/1.1 200 OK\r\n"\ b"Access-Control-Allow-Credentials: true\r\n"\ b"Access-Control-Allow-Methods: GET, POST, HEAD, PUT, DELETE, PATCH\r\n"\ b"Access-Control-Max-Age: 1728000\r\n"\ b"Content-Length: 0\r\n" req_header = headers.get(b"Access-Control-Request-Headers", b"") if req_header: response += b"Access-Control-Allow-Headers: %s\r\n" % req_header origin = headers.get(b"Origin", b"") if origin: response += b"Access-Control-Allow-Origin: %s\r\n" % origin else: response += b"Access-Control-Allow-Origin: *\r\n" response += b"\r\n" self.wfile.write(response) def is_local(self, hosts): if 0 == len(self.local_names): self.local_names.append(b'localhost') self.local_names.append(socket.gethostname().lower()) try: self.local_names.append(socket.gethostbyname_ex(socket.gethostname())[-1]) except socket.gaierror: # TODO Append local IP address to local_names pass for s in hosts: s = s.lower() if s.startswith(b'127.') \ or s.startswith(b'192.168.') \ or s.startswith(b'10.') \ or s.startswith(b'169.254.') \ or s in self.local_names: # xlog.debug(s) return True return False def do_CONNECT(self): """deploy fake cert to client""" host, _, port = self.path.rpartition(b':') port = int(port) if port not in (80, 443): xlog.warn("CONNECT %s port:%d not support", host, port) return certfile = CertUtil.get_cert(host) self.wfile.write(b'HTTP/1.1 200 Connection Established\r\n\r\n') self.wfile.flush() #self.conntunnel = True leadbyte = self.connection.recv(1, socket.MSG_PEEK) if leadbyte in (b'\x80', b'\x16'): try: ssl_sock = ssl.wrap_socket(self.connection, keyfile=CertUtil.cert_keyfile, certfile=certfile, server_side=True) except ssl.SSLError as e: xlog.info('ssl error: %s, create full domain cert for host:%s', e, host) certfile = CertUtil.get_cert(host, full_name=True) return except Exception as e: if e.args[0] not in (errno.ECONNABORTED, errno.ECONNRESET): xlog.exception('ssl.wrap_socket(self.connection=%r) failed: %s path:%s, errno:%s', self.connection, e, self.path, e.args[0]) return self.__realwfile = self.wfile self.__realrfile = self.rfile self.connection = ssl_sock self.rfile = self.connection.makefile('rb', self.bufsize) self.wfile = self.connection.makefile('wb', 0) self.close_connection = 0 def do_METHOD(self): self.req_payload = None host = self.headers.get(b'Host', b'') host_ip, _, port = host.rpartition(b':') if self.is_local([host, host_ip]): xlog.debug("Browse localhost by proxy") return self.forward_local() elif host == self.fake_host: # xlog.debug("%s %s", self.command, self.path) # for web_ui status page # auto detect browser proxy setting is work return self.wfile.write(self.self_check_response_data) #if not (front.config.use_ipv6 == "force_ipv6" and \ # check_local_network.IPv6.is_ok() or \ # front.config.use_ipv6 != "force_ipv6" and \ # check_local_network.is_ok()): # self.close_connection = 1 # xlog.warn("network fail on do_METHOD, use_ipv6:%s", front.config.use_ipv6) # return if isinstance(self.connection, ssl.SSLSocket): schema = b"https" else: schema = b"http" if self.path[0:1] == b'/': self.host = self.headers[b'Host'] self.url = b'%s://%s%s' % (schema, host, self.path) else: self.url = self.path self.parsed_url = urlparse(self.path) self.host = self.parsed_url[1] if len(self.parsed_url[4]): self.path = b'?'.join([self.parsed_url[2], self.parsed_url[4]]) else: self.path = self.parsed_url[2] if len(self.url) > 2083 and self.host.endswith(front.config.GOOGLE_ENDSWITH): return self.go_DIRECT() if self.host in front.config.HOSTS_GAE: return self.go_AGENT() # redirect http request to https request # avoid key word filter when pass through GFW if host in front.config.HOSTS_DIRECT: return self.go_DIRECT() if host.endswith(front.config.HOSTS_GAE_ENDSWITH): return self.go_AGENT() if host.endswith(front.config.HOSTS_DIRECT_ENDSWITH): return self.go_DIRECT() return self.go_AGENT() # Called by do_METHOD and do_CONNECT_AGENT def go_AGENT(self): request_headers = dict((k.title(), v) for k, v in list(self.headers.items())) payload = self.read_payload() if self.command == b"OPTIONS": xlog.warn("go_AGENT OPTIONS not supported by GAE") return self.send_method_allows(request_headers, payload) if self.command not in self.gae_support_methods: xlog.warn("Method %s not support in GAEProxy for %s", self.command, self.path) return self.wfile.write(('HTTP/1.1 404 Not Found\r\n\r\n').encode()) xlog.debug("GAE %s %s from:%s", self.command, self.url, self.address_string()) if gae_handler.handler(self.command, self.host, self.url, request_headers, payload, self.wfile, self.go_DIRECT) != "ok": self.close_connection = 1 def go_DIRECT(self): if not self.url.startswith(b"https"): xlog.debug("Host:%s Direct redirect to https", self.host) return self.wfile.write(b'HTTP/1.1 301\r\nLocation: %s\r\nContent-Length: 0\r\n\r\n' % self.url.replace(b'http://', b'https://', 1)) request_headers = dict((k.title(), v) for k, v in list(self.headers.items())) payload = self.read_payload() xlog.debug("DIRECT %s %s from:%s", self.command, self.url, self.address_string()) if direct_handler.handler(self.command, self.host, self.path, request_headers, payload, self.wfile) != "ok": self.close_connection = 1 def read_payload(self): def get_crlf(rfile): crlf = rfile.readline(2) if crlf != b"\r\n": xlog.warn("chunk header read fail crlf") if self.req_payload is not None: return self.req_payload payload = b'' if b'Content-Length' in self.headers: try: payload_len = int(self.headers.get(b'Content-Length', 0)) #xlog.debug("payload_len:%d %s %s", payload_len, self.command, self.path) payload = self.rfile.read(payload_len) except NetWorkIOError as e: xlog.error('handle_method_urlfetch read payload failed:%s', e) return elif b'Transfer-Encoding' in self.headers: # chunked, used by facebook android client payload = "" while True: chunk_size_str = self.rfile.readline(65537) chunk_size_list = chunk_size_str.split(b";") chunk_size = int(b"0x"+chunk_size_list[0], 0) if len(chunk_size_list) > 1 and chunk_size_list[1] != b"\r\n": xlog.warn("chunk ext: %s", chunk_size_str) if chunk_size == 0: while True: line = self.rfile.readline(65537) if line == b"\r\n": break else: xlog.warn("entity header:%s", line) break payload += self.rfile.read(chunk_size) get_crlf(self.rfile) self.req_payload = payload return payload # called by smart_router def wrap_ssl(sock, host, port, client_address): certfile = CertUtil.get_cert(host or b'www.google.com') ssl_sock = ssl.wrap_socket(sock, keyfile=CertUtil.cert_keyfile, certfile=certfile, server_side=True) return ssl_sock ================================================ FILE: code/default/gae_proxy/local/sni_manager.py ================================================ import random import os from front_base.random_get_slice import RandomGetSlice current_path = os.path.dirname(os.path.abspath(__file__)) class SniManager(object): plus = ['-', '', "."] end = ["com", "net", "ml", "org", "us"] def __init__(self, logger): self.logger = logger fn = os.path.join(current_path, "sni_slice.txt") self.slice = RandomGetSlice(fn, 20, '|') def get(self): return None n = random.randint(2, 3) ws = [] for i in range(0, n): w = self.slice.get() ws.append(w) p = random.choice(self.plus) name = p.join(ws) name += "." + random.choice(self.end) return name ================================================ FILE: code/default/gae_proxy/local/sni_slice.txt ================================================ people|history|way|art|world|information|map|two|family|government|health|system|computer|meat|year|thanks|music|person|reading|method|data|food|understanding|theory|law|bird|literature|problem|software|control|knowledge|power|ability|economics|love|internet|television|science|library|nature|fact|product|idea|temperature|investment|area|society|activity|story|industry|media|thing|oven|community|definition|safety|quality|development|language|management|player|variety|video|week|security|country|exam|movie|organization|equipment|physics|analysis|policy|series|thought|basis|boyfriend|direction|strategy|technology|army|camera|freedom|paper|environment|child|instance|month|truth|marketing|university|writing|article|department|difference|goal|news|audience|fishing|growth|income|marriage|user|combination|failure|meaning|medicine|philosophy|teacher|communication|night|chemistry|disease|disk|energy|nation|road|role|soup|advertising|location|success|addition|apartment|education|math|moment|painting|politics|attention|decision|event|property|shopping|student|wood|competition|distribution|entertainment|office|population|president|unit|category|cigarette|context|introduction|opportunity|performance|driver|flight|length|magazine|newspaper|relationship|teaching|cell|dealer|debate|finding|lake|member|message|phone|scene|appearance|association|concept|customer|death|discussion|housing|inflation|insurance|mood|woman|advice|blood|effort|expression|importance|opinion|payment|reality|responsibility|situation|skill|statement|wealth|application|city|county|depth|estate|foundation|grandmother|heart|perspective|photo|recipe|studio|topic|collection|depression|imagination|passion|percentage|resource|setting|ad|agency|college|connection|criticism|debt|description|memory|patience|secretary|solution|administration|aspect|attitude|director|personality|psychology|recommendation|response|selection|storage|version|alcohol|argument|complaint|contract|emphasis|highway|loss|membership|possession|preparation|steak|union|agreement|cancer|currency|employment|engineering|entry|interaction|limit|mixture|preference|region|republic|seat|tradition|virus|actor|classroom|delivery|device|difficulty|drama|election|engine|football|guidance|hotel|match|owner|priority|protection|suggestion|tension|variation|anxiety|atmosphere|awareness|bread|climate|comparison|confusion|construction|elevator|emotion|employee|employer|guest|height|leadership|mall|manager|operation|recording|respect|sample|transportation|boring|charity|cousin|disaster|editor|efficiency|excitement|extent|feedback|guitar|homework|leader|mom|outcome|permission|presentation|promotion|reflection|refrigerator|resolution|revenue|session|singer|tennis|basket|bonus|cabinet|childhood|church|clothes|coffee|dinner|drawing|hair|hearing|initiative|judgment|lab|measurement|mode|mud|orange|poetry|police|possibility|procedure|queen|ratio|relation|restaurant|satisfaction|sector|signature|significance|song|tooth|town|vehicle|volume|wife|accident|airport|appointment|arrival|assumption|baseball|chapter|committee|conversation|database|enthusiasm|error|explanation|farmer|gate|girl|hall|historian|hospital|injury|instruction|maintenance|manufacturer|meal|perception|pie|poem|presence|proposal|reception|replacement|revolution|river|son|speech|tea|village|warning|winner|worker|writer|assistance|breath|buyer|chest|chocolate|conclusion|contribution|cookie|courage|dad|desk|drawer|establishment|examination|garbage|grocery|honey|impression|improvement|independence|insect|inspection|inspector|king|ladder|menu|penalty|piano|potato|profession|professor|quantity|reaction|requirement|salad|sister|supermarket|tongue|weakness|wedding|affair|ambition|analyst|apple|assignment|assistant|bathroom|bedroom|beer|birthday|celebration|championship|cheek|client|consequence|departure|diamond|dirt|ear|fortune|friendship|funeral|gene|girlfriend|hat|indication|intention|lady|midnight|negotiation|obligation|passenger|pizza|platform|poet|pollution|recognition|reputation|shirt|sir|speaker|stranger|surgery|sympathy|tale|throat|trainer|uncle|youth|time|work|film|water|money|example|while|business|study|game|life|form|air|day|place|number|part|field|fish|back|process|heat|hand|experience|job|book|end|point|type|home|economy|value|body|market|guide|interest|state|radio|course|company|price|size|card|list|mind|trade|line|care|group|risk|word|fat|force|key|light|training|name|school|top|amount|level|order|practice|research|sense|service|piece|web|boss|sport|fun|house|page|term|test|answer|sound|focus|matter|kind|soil|board|oil|picture|access|garden|range|rate|reason|future|site|demand|exercise|image|case|cause|coast|action|age|bad|boat|record|result|section|building|mouse|cash|class|nothing|period|plan|store|tax|side|subject|space|rule|stock|weather|chance|figure|man|model|source|beginning|earth|program|chicken|design|feature|head|material|purpose|question|rock|salt|act|birth|car|dog|object|scale|sun|note|profit|rent|speed|style|war|bank|craft|half|inside|outside|standard|bus|exchange|eye|fire|position|pressure|stress|advantage|benefit|box|frame|issue|step|cycle|face|item|metal|paint|review|room|screen|structure|view|account|ball|discipline|medium|share|balance|bit|black|bottom|choice|gift|impact|machine|shape|tool|wind|address|average|career|culture|morning|pot|sign|table|task|condition|contact|credit|egg|hope|ice|network|north|square|attempt|date|effect|link|post|star|voice|capital|challenge|friend|self|shot|brush|couple|exit|front|function|lack|living|plant|plastic|spot|summer|taste|theme|track|wing|brain|button|click|desire|foot|gas|influence|notice|rain|wall|base|damage|distance|feeling|pair|savings|staff|sugar|target|text|animal|author|budget|discount|file|ground|lesson|minute|officer|phase|reference|register|sky|stage|stick|title|trouble|bowl|bridge|campaign|character|club|edge|evidence|fan|letter|lock|maximum|novel|option|pack|park|plenty|quarter|skin|sort|weight|baby|background|carry|dish|factor|fruit|glass|joint|master|muscle|red|strength|traffic|trip|vegetable|appeal|chart|gear|ideal|kitchen|land|log|mother|net|party|principle|relative|sale|season|signal|spirit|street|tree|wave|belt|bench|commission|copy|drop|minimum|path|progress|project|sea|south|status|stuff|ticket|tour|angle|blue|breakfast|confidence|daughter|degree|doctor|dot|dream|duty|essay|father|fee|finance|hour|juice|luck|milk|mouth|peace|pipe|stable|storm|substance|team|trick|afternoon|bat|beach|blank|catch|chain|consideration|cream|crew|detail|gold|interview|kid|mark|mission|pain|pleasure|score|screw|sex|shop|shower|suit|tone|window|agent|band|bath|block|bone|calendar|candidate|cap|coat|contest|corner|court|cup|district|door|east|finger|garage|guarantee|hole|hook|implement|layer|lecture|lie|manner|meeting|nose|parking|partner|profile|rice|routine|schedule|swimming|telephone|tip|winter|airline|bag|battle|bed|bill|bother|cake|code|curve|designer|dimension|dress|ease|emergency|evening|extension|farm|fight|gap|grade|holiday|horror|horse|host|husband|loan|mistake|mountain|nail|noise|occasion|package|patient|pause|phrase|proof|race|relief|sand|sentence|shoulder|smoke|stomach|string|tourist|towel|vacation|west|wheel|wine|arm|aside|associate|bet|blow|border|branch|breast|brother|buddy|bunch|chip|coach|cross|document|draft|dust|expert|floor|god|golf|habit|iron|judge|knife|landscape|league|mail|mess|native|opening|parent|pattern|pin|pool|pound|request|salary|shame|shelter|shoe|silver|tackle|tank|trust|assist|bake|bar|bell|bike|blame|boy|brick|chair|closet|clue|collar|comment|conference|devil|diet|fear|fuel|glove|jacket|lunch|monitor|mortgage|nurse|pace|panic|peak|plane|reward|row|sandwich|shock|spite|spray|surprise|till|transition|weekend|welcome|yard|alarm|bend|bicycle|bite|blind|bottle|cable|candle|clerk|cloud|concert|counter|flower|grandfather|harm|knee|lawyer|leather|load|mirror|neck|pension|plate|purple|ruin|ship|skirt|slice|snow|specialist|stroke|switch|trash|tune|zone|anger|award|bid|bitter|boot|bug|camp|candy|carpet|cat|champion|channel|clock|comfort|cow|crack|engineer|entrance|fault|grass|guy|hell|highlight|incident|island|joke|jury|leg|lip|mate|motor|nerve|passage|pen|pride|priest|prize|promise|resident|resort|ring|roof|rope|sail|scheme|script|sock|station|toe|tower|truck|witness|a|you|it|can|will|if|one|many|most|other|use|make|good|look|help|go|great|being|few|might|still|public|read|keep|start|give|human|local|general|she|specific|long|play|feel|high|tonight|put|common|set|change|simple|past|big|possible|particular|today|major|personal|current|national|cut|natural|physical|show|try|check|second|call|move|pay|let|increase|single|individual|turn|ask|buy|guard|hold|main|offer|potential|professional|international|travel|cook|alternative|following|special|working|whole|dance|excuse|cold|commercial|low|purchase|deal|primary|worth|fall|necessary|positive|produce|search|present|spend|talk|creative|tell|cost|drive|green|support|glad|remove|return|run|complex|due|effective|middle|regular|reserve|independent|leave|original|reach|rest|serve|watch|beautiful|charge|active|break|negative|safe|stay|visit|visual|affect|cover|report|rise|walk|white|beyond|junior|pick|unique|anything|classic|final|lift|mix|private|stop|teach|western|concern|familiar|fly|official|broad|comfortable|gain|maybe|rich|save|stand|young|heavy|hello|lead|listen|valuable|worry|handle|leading|meet|release|sell|finish|normal|press|ride|secret|spread|spring|tough|wait|brown|deep|display|flow|hit|objective|shoot|touch|cancel|chemical|cry|dump|extreme|push|conflict|eat|fill|formal|jump|kick|opposite|pass|pitch|remote|total|treat|vast|abuse|beat|burn|deposit|print|raise|sleep|somewhere|advance|anywhere|consist|dark|double|draw|equal|fix|hire|internal|join|kill|sensitive|tap|win|attack|claim|constant|drag|drink|guess|minor|pull|raw|soft|solid|wear|weird|wonder|annual|count|dead|doubt|feed|forever|impress|nobody|repeat|round|sing|slide|strip|whereas|wish|combine|command|dig|divide|equivalent|hang|hunt|initial|march|mention|spiritual|survey|tie|adult|brief|crazy|escape|gather|hate|prior|repair|rough|sad|scratch|sick|strike|employ|external|hurt|illegal|laugh|lay|mobile|nasty|ordinary|respond|royal|senior|split|strain|struggle|swim|train|upper|wash|yellow|convert|crash|dependent|fold|funny|grab|hide|miss|permit|quote|recover|resolve|roll|sink|slip|spare|suspect|sweet|swing|twist|upstairs|usual|abroad|brave|calm|concentrate|estimate|grand|male|mine|prompt|quiet|refuse|regret|reveal|rush|shake|shift|shine|steal|suck|surround|anybody|bear|brilliant|dare|dear|delay|drunk|female|hurry|inevitable|invite|kiss|neat|pop|punch|quit|reply|representative|resist|rip|rub|silly|smile|spell|stretch|stupid|tear|temporary|tomorrow|wake|wrap|yesterday ================================================ FILE: code/default/gae_proxy/local/web_control.py ================================================ #!/usr/bin/env python # coding:utf-8 import platform import json import os import re import subprocess import sys import datetime import locale import time import hashlib import ssl try: from urllib.parse import urlparse, parse_qs except ImportError: from urlparse import urlparse, parse_qs import simple_http_server import simple_http_client import env_info import utils import env_info from xlog import getLogger xlog = getLogger("gae_proxy") from .config import config, direct_config from . import check_local_network from . import cert_util from . import ipv6_tunnel from .front import front, direct_front from . import download_gae_lib current_path = os.path.dirname(os.path.abspath(__file__)) root_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir)) top_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir)) data_path = os.path.join(env_info.data_path, 'gae_proxy') web_ui_path = os.path.join(current_path, os.path.pardir, "web_ui") def get_fake_host(): return "deja.com" def test_appid_exist(ssl_sock, appid): request_data = 'GET /_gh/ HTTP/1.1\r\nHost: %s.appspot.com\r\n\r\n' % appid ssl_sock.send(request_data.encode()) response = simple_http_client.Response(ssl_sock) response.begin() if response.status == 404: # xlog.warn("app check %s status:%d", appid, response.status) return False if response.status == 503: # out of quota return True if response.status != 200: xlog.warn("test appid %s status:%d", appid, response.status) content = response.read() if b"GoAgent" not in content: # xlog.warn("app check %s content:%s", appid, content) return False return True def test_appid(appid): for i in range(0, 3): ssl_sock = direct_front.connect_manager.get_ssl_connection() if not ssl_sock: continue try: return test_appid_exist(ssl_sock, appid) except Exception as e: xlog.warn("check_appid %s %r", appid, e) continue return False def test_appids(appids): appid_list = appids.split("|") fail_appid_list = [] for appid in appid_list: if not test_appid(appid): fail_appid_list.append(appid) else: # return success if one appid is work # just reduce wait time # here can be more ui friendly. return [] return fail_appid_list def get_openssl_version(): return "%s %s h2:%s" % (ssl.OPENSSL_VERSION, front.openssl_context.supported_protocol(), front.openssl_context.support_alpn_npn) deploy_proc = None class ControlHandler(simple_http_server.HttpServerHandler): def __init__(self, client_address, headers, command, path, rfile, wfile): self.client_address = client_address self.headers = headers self.command = command self.path = path self.rfile = rfile self.wfile = wfile def do_CONNECT(self): self.wfile.write(b'HTTP/1.1 403\r\nConnection: close\r\n\r\n') def do_GET(self): path = urlparse(self.path).path if path == "/log": return self.req_log_handler() elif path == "/status": return self.req_status_handler() else: xlog.debug('GAEProxy Web_control %s %s %s ', self.address_string(), self.command, self.path) if path == '/deploy': return self.req_deploy_handler() elif path == "/config": return self.req_config_handler() elif path == "/ip_list": return self.req_ip_list_handler() elif path == "/scan_ip": return self.req_scan_ip_handler() elif path == "/ssl_pool": return self.req_ssl_pool_handler() elif path == "/workers": return self.req_workers_handler() elif path == "/download_cert": return self.req_download_cert_handler() elif path == "/is_ready": return self.req_is_ready_handler() elif path == "/test_ip": return self.req_test_ip_handler() elif path == "/check_ip": return self.req_check_ip_handler() elif path == "/debug": return self.req_debug_handler() elif path.startswith("/ipv6_tunnel"): return self.req_ipv6_tunnel_handler() elif path == "/quit": front.stop() direct_front.stop() data = b"Quit" self.wfile.write((b'HTTP/1.1 200\r\nContent-Type: %s\r\nContent-Length: %s\r\n\r\n' % (b'text/plain', len(data))).encode()) self.wfile.write(data) #sys.exit(0) #quit() #os._exit(0) return elif path.startswith("/wizard/"): file_path = os.path.abspath(os.path.join(web_ui_path, '/'.join(path.split('/')[1:]))) if not os.path.isfile(file_path): self.wfile.write(b'HTTP/1.1 404 Not Found\r\n\r\n') xlog.warn('%s %s %s wizard file %s not found', self.address_string(), self.command, self.path, file_path) return if file_path.endswith('.html'): mimetype = 'text/html' elif file_path.endswith('.png'): mimetype = 'image/png' elif file_path.endswith('.jpg') or file_path.endswith('.jpeg'): mimetype = 'image/jpeg' else: mimetype = 'application/octet-stream' self.send_file(file_path, mimetype) return else: xlog.warn('Control Req %s %s %s ', self.address_string(), self.command, self.path) # check for '..', which will leak file if re.search(r'(\.{2})', self.path) is not None: self.wfile.write(b'HTTP/1.1 404\r\n\r\n') xlog.warn('%s %s %s haking', self.address_string(), self.command, self.path ) return filename = os.path.normpath('./' + path) if self.path.startswith(('http://', 'https://')): data = b'HTTP/1.1 200\r\nCache-Control: max-age=86400\r\nExpires:Oct, 01 Aug 2100 00:00:00 GMT\r\nConnection: close\r\n' data += b'\r\n' self.wfile.write(data) xlog.info('%s "%s %s HTTP/1.1" 200 -', self.address_string(), self.command, self.path) elif os.path.isfile(filename): if filename.endswith('.pac'): mimetype = 'text/plain' else: mimetype = 'application/octet-stream' #self.send_file(filename, mimetype) else: self.wfile.write(b'HTTP/1.1 404\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\n404 Not Found') xlog.info('%s "%s %s HTTP/1.1" 404 -', self.address_string(), self.command, self.path) def do_POST(self): try: refer = self.headers.getheader('Referer') netloc = urlparse(refer).netloc if not netloc.startswith("127.0.0.1") and not netloc.startswitch("localhost"): xlog.warn("web control ref:%s refuse", netloc) return except: pass xlog.debug ('GAEProxy web_control %s %s %s ', self.address_string(), self.command, self.path) path = urlparse(self.path).path if path == '/deploy': return self.req_deploy_handler() elif path == "/config": return self.req_config_handler() elif path == "/scan_ip": return self.req_scan_ip_handler() elif path.startswith("/importip"): return self.req_importip_handler() else: self.wfile.write(b'HTTP/1.1 404\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\n404 Not Found') xlog.info('%s "%s %s HTTP/1.1" 404 -', self.address_string(), self.command, self.path) def req_log_handler(self): req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) reqs = self.unpack_reqs(reqs) data = '' cmd = "get_last" if reqs["cmd"]: cmd = reqs["cmd"] if cmd == "get_last": max_line = int(reqs["max_line"]) data = xlog.get_last_lines(max_line) elif cmd == "get_new": last_no = int(reqs["last_no"]) data = xlog.get_new_lines(last_no) else: xlog.error('WebUI log from:%s unknown cmd:%s path:%s ', self.address_string(), self.command, self.path) mimetype = 'text/plain' self.send_response_nc(mimetype, data) def get_launcher_version(self): return "unknown" @staticmethod def xxnet_version(): version_file = os.path.join(root_path, "version.txt") try: with open(version_file, "r") as fd: version = fd.read() return version except Exception as e: xlog.exception("xxnet_version fail") return "get_version_fail" def get_os_language(self): if hasattr(self, "lang_code"): return self.lang_code try: lang_code, code_page = locale.getdefaultlocale() #('en_GB', 'cp1252'), en_US, self.lang_code = lang_code return lang_code except: #Mac fail to run this pass if sys.platform == "darwin": try: oot = os.pipe() p = subprocess.Popen(["/usr/bin/defaults", 'read', 'NSGlobalDomain', 'AppleLanguages'],stdout=oot[1]) p.communicate() lang_code = os.read(oot[0],10000) self.lang_code = lang_code return lang_code except: pass lang_code = 'Unknown' return lang_code def req_status_handler(self): if "User-Agent" in self.headers: user_agent = self.headers["User-Agent"] else: user_agent = "" if config.PROXY_ENABLE: lan_proxy = "%s://%s:%s" % (config.PROXY_TYPE, config.PROXY_HOST, config.PROXY_PORT) else: lan_proxy = "Disable" res_arr = { "sys_platform": "%s, %s" % (platform.machine(), platform.platform()), "os_system": platform.system(), "os_version": platform.version(), "os_release": platform.release(), "architecture": platform.architecture(), "os_detail": env_info.os_detail(), "language": self.get_os_language(), "browser": user_agent, "xxnet_version": self.xxnet_version(), "python_version": platform.python_version(), "openssl_version": get_openssl_version(), "proxy_listen": str(config.listen_ip) + ":" + str(config.listen_port), "use_ipv6": config.use_ipv6, "lan_proxy": lan_proxy, "gae_appid": "|".join(config.GAE_APPIDS), "working_appid": "|".join(front.appid_manager.working_appid_list), "out_of_quota_appids": "|".join(front.appid_manager.out_of_quota_appids), "not_exist_appids": "|".join(front.appid_manager.not_exist_appids), "ipv4_state": check_local_network.IPv4.get_stat(), "ipv6_state": check_local_network.IPv6.get_stat(), #"ipv6_tunnel": ipv6_tunnel.state(), "all_ip_num": len(front.ip_manager.ip_list), "good_ipv4_num": front.ip_manager.good_ipv4_num, "good_ipv6_num": front.ip_manager.good_ipv6_num, "connected_link_new": len(front.connect_manager.new_conn_pool.pool), "connection_pool_min": config.https_connection_pool_min, "worker_h1": front.http_dispatcher.h1_num, "worker_h2": front.http_dispatcher.h2_num, "is_idle": int(front.http_dispatcher.is_idle()), "scan_ip_thread_num": front.ip_manager.scan_thread_count, "ip_quality": front.ip_manager.ip_quality(), "fake_host": get_fake_host() } data = json.dumps(res_arr, indent=0, sort_keys=True) self.send_response_nc('text/html', data) def req_config_handler(self): req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) data = '' appid_updated = False try: if reqs['cmd'] == ['get_config']: ret_config = { "appid": "|".join(config.GAE_APPIDS), "auto_adjust_scan_ip_thread_num": config.auto_adjust_scan_ip_thread_num, "scan_ip_thread_num": config.max_scan_ip_thread_num, "use_ipv6": config.use_ipv6, "setting_level": config.setting_level, "connect_receive_buffer": config.connect_receive_buffer, } data = json.dumps(ret_config, default=lambda o: o.__dict__) elif reqs['cmd'] == ['set_config']: appids = self.postvars['appid'] if appids != "|".join(config.GAE_APPIDS): if appids and (front.ip_manager.good_ipv4_num + front.ip_manager.good_ipv6_num): fail_appid_list = test_appids(appids) if len(fail_appid_list): fail_appid = "|".join(fail_appid_list) data = json.dumps({"res": "fail", "reason": "appid fail:" + fail_appid }) return appid_updated = True if appids: xlog.info("set appids:%s", appids) config.GAE_APPIDS = appids.split("|") else: config.GAE_APPIDS = [] config.save() config.load() front.appid_manager.reset_appid() if appid_updated: front.http_dispatcher.close_all_worker() front.ip_manager.reset() data = '{"res":"success"}' #http_request("http://127.0.0.1:8085/init_module?module=gae_proxy&cmd=restart") elif reqs['cmd'] == ['set_config_level']: setting_level = self.postvars['setting_level'] if setting_level: xlog.info("set globa config level to %s", setting_level) config.set_level(setting_level) direct_config.set_level(setting_level) front.ip_manager.load_config() front.ip_manager.adjust_scan_thread_num() front.ip_manager.remove_slowest_ip() front.ip_manager.search_more_ip() connect_receive_buffer = int(self.postvars['connect_receive_buffer']) if 8192 <= connect_receive_buffer <= 2097152 and connect_receive_buffer != config.connect_receive_buffer: xlog.info("set connect receive buffer to %dKB", connect_receive_buffer // 1024) config.connect_receive_buffer = connect_receive_buffer config.save() config.load() front.connect_manager.new_conn_pool.clear() direct_front.connect_manager.new_conn_pool.clear() front.http_dispatcher.close_all_worker() for _, http_dispatcher in list(direct_front.dispatchs.items()): http_dispatcher.close_all_worker() data = '{"res":"success"}' except Exception as e: xlog.exception("req_config_handler except:%s", e) data = '{"res":"fail", "except":"%s"}' % e finally: self.send_response_nc('text/html', data) def req_deploy_handler(self): global deploy_proc req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) data = '' log_path = os.path.abspath(os.path.join(current_path, os.pardir, "server", 'upload.log')) time_now = datetime.datetime.today().strftime('%H:%M:%S-%a/%d/%b/%Y') if reqs['cmd'] == ['deploy']: appid = self.postvars['appid'] debug = int(self.postvars['debug']) if deploy_proc and deploy_proc.poll() == None: xlog.warn("deploy is running, request denied.") data = '{"res":"deploy is running", "time":"%s"}' % time_now else: try: download_gae_lib.check_lib_or_download() if os.path.isfile(log_path): os.remove(log_path) script_path = os.path.abspath(os.path.join(current_path, os.pardir, "server", 'uploader.py')) args = [sys.executable, script_path, appid] if debug: args.append("-debug") deploy_proc = subprocess.Popen(args) xlog.info("deploy begin.") data = '{"res":"success", "time":"%s"}' % time_now except Exception as e: data = '{"res":"%s", "time":"%s"}' % (e, time_now) elif reqs['cmd'] == ['cancel']: if deploy_proc and deploy_proc.poll() == None: deploy_proc.kill() data = '{"res":"deploy is killed", "time":"%s"}' % time_now else: data = '{"res":"deploy is not running", "time":"%s"}' % time_now elif reqs['cmd'] == ['get_log']: if deploy_proc and os.path.isfile(log_path): with open(log_path, "r") as f: content = f.read() else: content = "" status = 'init' if deploy_proc: if deploy_proc.poll() == None: status = 'running' else: status = 'finished' data = json.dumps({'status': status, 'log': content, 'time': time_now}) self.send_response_nc('text/html', data) def req_importip_handler(self): req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) data = '' if reqs['cmd'] == ['importip']: count = 0 ip_list = self.postvars['ipList'] lines = ip_list.split("\n") for line in lines: addresses = line.split('|') for ip in addresses: ip = ip.strip() if not utils.check_ip_valid(ip): continue if front.ip_manager.add_ip(ip, 100, "google.com", "gws"): count += 1 data = '{"res":"%s"}' % count front.ip_manager.save(force=True) elif reqs['cmd'] == ['exportip']: data = '{"res":"' for ip in front.ip_manager.ip_list: if front.ip_manager.ip_dict[ip]['fail_times'] > 0: continue data += "%s|" % ip data = data[0: len(data) - 1] data += '"}' self.send_response_nc('text/html', data) def req_test_ip_handler(self): req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) reqs = self.unpack_reqs(reqs) ip = reqs['ip'] result = front.check_ip.check_ip(ip) if not result or not result.ok: data = "{'res':'fail'}" else: data = json.dumps("{'ip':'%s', 'handshake':'%s', 'server':'%s', 'domain':'%s'}" % (ip, result.handshake_time, result.server_type, result.domain)) self.send_response_nc('text/html', data) def req_ip_list_handler(self): time_now = time.time() data = "
" data += "time:%d pointer:%d
\r\n" % (time_now, front.ip_manager.ip_pointer) data += "" data += "" data += "" data += "" data += "\n" i = 1 for ip in front.ip_manager.gws_ip_list: handshake_time = front.ip_manager.ip_dict[ip]["handshake_time"] fail_times = front.ip_manager.ip_dict[ip]["fail_times"] down_fail = front.ip_manager.ip_dict[ip]["down_fail"] links = front.ip_manager.ip_dict[ip]["links"] get_time = front.ip_manager.ip_dict[ip]["get_time"] if get_time: get_time = time_now - get_time success_time = front.ip_manager.ip_dict[ip]["success_time"] if success_time: success_time = time_now - success_time fail_time = front.ip_manager.ip_dict[ip]["fail_time"] if fail_time: fail_time = time_now - fail_time down_fail_time = front.ip_manager.ip_dict[ip]["down_fail_time"] if down_fail_time: down_fail_time = time_now - down_fail_time data_active = front.ip_manager.ip_dict[ip]["data_active"] if data_active: active_time = time_now - data_active else: active_time = 0 history = front.ip_manager.ip_dict[ip]["history"] t0 = 0 str_out = '' for item in history: t = item[0] v = item[1] if t0 == 0: t0 = t time_per = int((t - t0) * 1000) t0 = t str_out += "%d(%s) " % (time_per, v) data += "" \ "\n" % \ (i, ip, handshake_time, fail_times, down_fail, links, get_time, success_time, fail_time, down_fail_time, active_time, str_out) i += 1 data += "
NIPHSFailsdown_faillinksget_timesuccess_timefail_timedown_fail_timedata_activetransfered_dataTranshistory
%d%s%d%d%d%d%d%d%d%d%d%s
" mimetype = 'text/html' self.send_response_nc(mimetype, data) def req_scan_ip_handler(self): req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) reqs = self.unpack_reqs(reqs) data = "" if reqs['cmd'] == 'get_range': data = front.ipv4_source.load_range_content() elif reqs['cmd'] == 'update': #update ip_range if needed content = self.postvars['ip_range'] #check ip_range checksums, update if needed default_digest = hashlib.md5(utils.to_bytes(front.ipv4_source.load_range_content(default=True))).hexdigest() old_digest = hashlib.md5(utils.to_bytes(front.ipv4_source.load_range_content())).hexdigest() new_digest = hashlib.md5(utils.to_bytes(content)).hexdigest() if new_digest == default_digest: front.ipv4_source.remove_user_range() else: if old_digest != new_digest: front.ipv4_source.update_range_content(content) if old_digest != new_digest: front.ipv4_source.load_ip_range() #update auto_adjust_scan_ip and scan_ip_thread_num should_auto_adjust_scan_ip = int(self.postvars['auto_adjust_scan_ip_thread_num']) thread_num_for_scan_ip = int(self.postvars['scan_ip_thread_num']) use_ipv6 = self.postvars['use_ipv6'] if config.use_ipv6 != use_ipv6: xlog.debug("use_ipv6 change to %s", use_ipv6) config.use_ipv6 = use_ipv6 #update user config settings config.auto_adjust_scan_ip_thread_num = should_auto_adjust_scan_ip config.max_scan_ip_thread_num = thread_num_for_scan_ip config.save() config.load() front.ip_manager.adjust_scan_thread_num() #reponse data='{"res":"success"}' mimetype = 'text/plain' self.send_response_nc(mimetype, data) def req_ssl_pool_handler(self): data = "New conn:\n" data += front.connect_manager.new_conn_pool.to_string() for host in front.connect_manager.host_conn_pool: data += "\nHost:%s\n" % host data += front.connect_manager.host_conn_pool[host].to_string() mimetype = 'text/plain' self.send_response_nc(mimetype, data) def req_workers_handler(self): data = front.http_dispatcher.to_string() mimetype = 'text/plain' self.send_response_nc(mimetype, data) def req_download_cert_handler(self): filename = cert_util.CertUtil.ca_keyfile if not os.path.isfile(filename): xlog.warn("CA file not exist, download cert failed.") return self.send_not_found() with open(filename, 'rb') as fp: data = fp.read() mimetype = 'application/x-x509-ca-cert' self.wfile.write(('HTTP/1.1 200\r\nContent-Disposition: inline; filename=CA.crt\r\nContent-Type: %s\r\nContent-Length: %s\r\n\r\n' % (mimetype, len(data))).encode()) self.wfile.write(data) def req_is_ready_handler(self): data = "%s" % config.cert_import_ready mimetype = 'text/plain' self.send_response_nc(mimetype, data) def req_check_ip_handler(self): req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) data = "" if reqs['cmd'] == ['get_process']: all_ip_num = len(front.ip_manager.ip_dict) left_num = front.ip_manager.scan_exist_ip_queue.qsize() good_num = (front.ip_manager.good_ipv4_num + front.ip_manager.good_ipv6_num) data = json.dumps(dict(all_ip_num=all_ip_num, left_num=left_num, good_num=good_num)) self.send_response_nc('text/plain', data) elif reqs['cmd'] == ['start']: left_num = front.ip_manager.scan_exist_ip_queue.qsize() if left_num: self.send_response_nc('text/plain', '{"res":"fail", "reason":"running"}') else: front.ip_manager.start_scan_all_exist_ip() self.send_response_nc('text/plain', '{"res":"success"}') elif reqs['cmd'] == ['stop']: left_num = front.ip_manager.scan_exist_ip_queue.qsize() if not left_num: self.send_response_nc('text/plain', '{"res":"fail", "reason":"not running"}') else: front.ip_manager.stop_scan_all_exist_ip() self.send_response_nc('text/plain', '{"res":"success"}') else: return self.send_not_exist() def req_debug_handler(self): data = "" for obj in [front.connect_manager, front.http_dispatcher]: data += "%s\r\n" % obj.__class__ for attr in dir(obj): if attr.startswith("__"): continue data += " %s = %s\r\n" % (attr, getattr(obj, attr)) mimetype = 'text/plain' self.send_response_nc(mimetype, data) def req_ipv6_tunnel_handler(self): req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) reqs = self.unpack_reqs(reqs) data = '' log_path = os.path.join(data_path, "ipv6_tunnel.log") time_now = datetime.datetime.today().strftime('%H:%M:%S-%a/%d/%b/%Y') client_ip = self.client_address[0] is_local = client_ip.endswith("127.0.0.1") or client_ip == "::1" if reqs['cmd'] in [['enable'], ['disable'], ['test_teredo'], ['test_teredo_usability'], ['test_teredo_server'], ['set_best_server']]: cmd = reqs['cmd'] xlog.info("ipv6_tunnel switch %s", cmd) # Don't remove log file at here. if cmd == "enable": result = ipv6_tunnel.enable(is_local) elif cmd == "disable": result = ipv6_tunnel.disable(is_local) elif cmd == "test_teredo": result = ipv6_tunnel.test_teredo() elif cmd == "test_teredo_usability": result = ipv6_tunnel.test_teredo(probe_server=False) elif cmd == "test_teredo_server": result = ipv6_tunnel.test_teredo(probe_nat=False) elif cmd == "set_best_server": result = ipv6_tunnel.set_best_server(is_local) else: xlog.warn("unknown cmd:%s", cmd) result = None xlog.info("ipv6_tunnel switch %s, result: %s", cmd, result) data = json.dumps({'res': result, 'time': time_now}) elif reqs['cmd'] == ['get_log']: if os.path.isfile(log_path): with open(log_path, "r") as f: content = f.read() else: content = "" status = ipv6_tunnel.state() data = json.dumps({'status': status, 'log': content, 'time': time_now}) elif reqs['cmd'] == ['get_priority']: data = json.dumps({'res': ipv6_tunnel.state_pp(), 'time': time_now}) elif reqs['cmd'] == ['switch_pp']: data = json.dumps({'res': ipv6_tunnel.switch_pp(), 'time': time_now}) self.send_response_nc('text/html', data) ================================================ FILE: code/default/gae_proxy/server/.gitignore ================================================ .DS_Store *~ *.pyc .appcfg_cookies upload.log ================================================ FILE: code/default/gae_proxy/server/README.md ================================================ ## 设置使用密码: 如果你担心流量被别人使用,可以设置使用密码。 编辑main.py 里的 __password____ 注意在客户端中也需要设置一样的密码才能访问。 一般你不泄露appid,别人是无法使用你的流量的。 ## 下载gcloud 并安装 https://cloud.google.com/sdk/docs/install ## 登陆google账户,选择部署的appid 需要先指定代理服务器,可以使用X-tunnel作为代理服务器,端口1080。 `gcloud config set proxy/type socks5` `gcloud config set proxy/address localhost` `gcloud config set proxy/port 1080` 请先确认X-Tunnel 已经登陆并可以访问google服务。 参考这里: https://cloud.google.com/sdk/docs/proxy-settings 登陆并选择需要部署的appid: `gcloud init` ## 未绑定信用卡的需要绑定: https://console.cloud.google.com/billing/enable ## 部署: `cd XX-Net/code/default/gae_proxy/server/gae` `gcloud app deploy` ================================================ FILE: code/default/gae_proxy/server/gae/.gcloudignore ================================================ # This file specifies files that are *not* uploaded to Google Cloud # using gcloud. It follows the same syntax as .gitignore, with the addition of # "#!include" directives (which insert the entries of the given .gitignore-style # file at that point). # # For more information, run: # $ gcloud topic gcloudignore # .gcloudignore # If you would like to upload your .git directory, .gitignore file or files # from your .gitignore file, remove the corresponding line # below: .git .gitignore # Python pycache: __pycache__/ # Ignored by the build system /setup.cfg ================================================ FILE: code/default/gae_proxy/server/gae/app.yaml ================================================ instance_class: F1 automatic_scaling: max_instances: 1 runtime: python312 app_engine_apis: true entrypoint: gunicorn -c gunicorn.conf.py --timeout 60 -b :$PORT main:app ================================================ FILE: code/default/gae_proxy/server/gae/gunicorn.conf.py ================================================ # Recommended number of workers based on instance size: # https://cloud.google.com/appengine/docs/standard/python3/runtime#entrypoint_best_practices threads = 20 # Use an asynchronous worker as most of the work is waiting for websites to load worker_class = 'gthread' ================================================ FILE: code/default/gae_proxy/server/gae/main.py ================================================ import os import time from datetime import timedelta, datetime, tzinfo import struct import zlib import logging from urllib.parse import urlparse import http.client as httplib import json import threading import re import psutil import flask from flask import Flask, request import requests from google.cloud import storage from google.appengine.api import urlfetch from google.appengine.runtime import apiproxy_errors from google.appengine.api.taskqueue.taskqueue import MAX_URL_LENGTH from google.appengine.api import urlfetch_stub from google.appengine.api import apiproxy_stub_map apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap() apiproxy_stub_map.apiproxy.RegisterStub('urlfetch', urlfetch_stub.URLFetchServiceStub()) logging.basicConfig(format='%(asctime)s - %(message)s', level=logging.INFO) app = Flask(__name__) try: storage_client = storage.Client() project_id = os.environ.get("GOOGLE_CLOUD_PROJECT") bucket_name = f"{project_id}.appspot.com" bucket = storage_client.bucket(bucket_name) blob_name = "band_usage_info" except Exception as e: logging.warning("init blob fail:%r", e) storage_client = None __password__ = '' URLFETCH_MAX = 2 URLFETCH_DEFLATE_MAXSIZE = 4 * 1024 * 1024 URLFETCH_TIMEOUT = 30 allowed_traffic = 1024 * 1024 * 1024 * 0.90 gae_support_methods = tuple(["GET", "POST", "HEAD", "PUT", "DELETE", "PATCH"]) def map_with_parameter(function, datas, args): plist = [] for data in datas: d_out = function(data, args) plist.append(d_out) return plist def to_bytes(data, coding='utf-8'): if isinstance(data, bytes): return data if isinstance(data, str): return data.encode(coding) if isinstance(data, dict): return dict(map_with_parameter(to_bytes, data.items(), coding)) if isinstance(data, tuple): return tuple(map_with_parameter(to_bytes, data, coding)) if isinstance(data, list): return list(map_with_parameter(to_bytes, data, coding)) if isinstance(data, int): return to_bytes(str(data)) if data is None: return data return bytes(data) def to_str(data, coding='utf-8'): if isinstance(data, str): return data if isinstance(data, bytes): return data.decode(coding) if isinstance(data, bytearray): return data.decode(coding) if isinstance(data, dict): return dict(map_with_parameter(to_str, data.items(), coding)) if isinstance(data, tuple): return tuple(map_with_parameter(to_str, data, coding)) if isinstance(data, list): return list(map_with_parameter(to_str, data, coding)) if isinstance(data, int): return str(data) if data is None: return data return str(data) def inflate(data): return zlib.decompress(data, -zlib.MAX_WBITS) def deflate(data): return zlib.compress(data)[2:-4] def unpack_request(payload): head_len = struct.unpack('!h', payload[0:2])[0] head = payload[2:2+head_len] body = payload[2+head_len:] head = inflate(head) lines = head.split(b"\r\n") method, url = lines[0].split()[:2] headers = {} kwargs = {} for line in lines[1:]: ls = line.split(b": ") k = ls[0] if not k: continue v = b"".join(ls[1:]) if k.startswith(b"X-URLFETCH-"): k = k[11:] kwargs[k] = v else: headers[k] = v if headers.get(b"Content-Encoding") == b"deflate": body = inflate(body) del headers[b"Content-Encoding"] method = to_str(method) url = to_str(url) headers = to_str(headers) kwargs = to_str(kwargs) if method == "GET" and "Content-Length" in headers: del headers["Content-Length"] return method, url, headers, body, kwargs def pack_response(status, headers, app_msg, content): if app_msg: headers.pop('content-length', None) headers['Content-Length'] = str(len(app_msg)) headers = to_bytes(headers) data = b'HTTP/1.1 %d %s\r\n%s\r\n\r\n%s' % \ (status, to_bytes(httplib.responses.get(status, 'Unknown')), b'\r\n'.join(b'%s: %s' % (k.title(), v) for k, v in headers.items()), app_msg) data = deflate(data) head_len_pack = struct.pack('!h', len(data)) out = head_len_pack + data + to_bytes(content) return out class Pacific(tzinfo): def utcoffset(self, dt): return timedelta(hours=-8) + self.dst(dt) def dst(self, dt): # DST starts last Sunday in March d = datetime(dt.year, 3, 12) # ends last Sunday in October self.dston = d - timedelta(days=d.weekday() + 1) d = datetime(dt.year, 11, 6) self.dstoff = d - timedelta(days=d.weekday() + 1) if self.dston <= dt.replace(tzinfo=None) < self.dstoff: return timedelta(hours=1) else: return timedelta(0) def tzname(self,dt): return "Pacific" def get_pacific_date(): tz = Pacific() sa_time = datetime.now(tz) return sa_time.strftime('%Y-%m-%d') def get_store_info(): if not storage_client: return {} try: blob = bucket.blob(blob_name) content = blob.download_as_string() info = json.loads(content) return info except Exception as e: logging.exception("get_store_info e:%r", e) return {} store_info = get_store_info() store_save_time = time.time() store_change_time = 0 traffic = 0 timer_th = None def get_store(key, default_value=None): global store_info return store_info.get(key, default_value) def set_store(key, value): global store_info store_info[key] = value def save_store(): global store_info, store_save_time, traffic if not storage_client: return store_info = get_store_info() try: store_info["traffic"] = store_info.get("traffic", 0) + traffic traffic = 0 content = json.dumps(store_info) blob = bucket.blob(blob_name) blob.upload_from_string(content) store_save_time = time.time() logging.info("save_store:%s", content) except Exception as e: logging.exception("save_store e:%r", e) def timer_worker(): global store_info, store_save_time, store_change_time, timer_th time.sleep(60 * 14) if store_change_time > store_save_time and time.time() - store_save_time > 60: logging.info("timer save store") save_store() timer_th = None @app.route("/reset_traffic", methods=['GET']) def reset_traffic(): global traffic traffic = 0 set_store("traffic", 0) save_store() return 'Traffic reset finished.' def is_traffic_exceed(): global traffic reset_date = get_store("reset_date", None) pacific_date = get_pacific_date() if reset_date != pacific_date: set_store("reset_date", pacific_date) traffic = 0 set_store("traffic", 0) save_store() return False traffic_sum = get_store("traffic", 0) + traffic if traffic_sum > allowed_traffic: return True else: return False def count_traffic(add_traffic): global timer_th, traffic, store_change_time traffic += add_traffic store_change_time = time.time() if not timer_th: timer_th = threading.Thread(target=timer_worker) timer_th.start() @app.route("/") def root(): out = "GoAgent 服务端已经升级到 python3 版本。
\nVersion: 4.0.0" return out @app.route("/info", methods=['GET']) def info(): global store_info, traffic save_store() out_list = list() out_list.append(f"store:
{json.dumps(store_info, indent=2)}
") traffic_sum = int(store_info.get("traffic", 0)) + traffic out_list.append('Usage: %f %%\r\n' % (traffic_sum * 100 / allowed_traffic)) tz = Pacific() sa_time = datetime.now(tz) pacific_time = sa_time.strftime('%Y-%m-%d %H:%M:%S') out_list.append("American Pacific time:%s" % pacific_time) out_list.append(f"CPU num:{psutil.cpu_count()}") out_list.append(f"CPU percent:{psutil.cpu_percent(interval=1)}") mem = psutil.virtual_memory() out_list.append(f"Mem total:{mem.total}") out_list.append(f"Mem used:{mem.used}") out_list.append(f"Mem available:{mem.available}") out_list.append(f"Mem percent:{mem.percent}") net = psutil.net_io_counters() out_list.append(f"net sent:{net.bytes_sent}") out_list.append(f"net recv:{net.bytes_recv}") env = json.dumps(dict(os.environ), indent=2) out_list.append(f"
env:
{env}
") return "
\r\n".join(out_list) @app.route("/_gh/", methods=['GET']) def check(): logging.debug("req headers:%s", request.headers) return "GoAgent works" def req_by_requests(method, url, req_headers, req_body, kwargs): timeout = int(kwargs.get('timeout', URLFETCH_TIMEOUT)) verify = bool(int(kwargs.get('validate', 0))) errors = [] for i in range(int(kwargs.get('fetchmax', URLFETCH_MAX))): try: # t0 = time.time() res = requests.request(method, url, headers=req_headers, data=req_body, timeout=timeout, verify=verify, stream=True, allow_redirects=False) # t1 = time.time() # logging.info(f"cost:{t1-t0} {method} {url} res:{res.status_code}") break except Exception as e: logging.warning("request %s %s %s %s %s e:%r", method, url, req_headers, timeout, verify, e) errors.append(str(e)) if i == 0 and method == 'GET': timeout *= 2 else: error_string = '
\n'.join(errors) logging.info('%s %s error:%s', method, url, error_string) return 502, {}, "502 Urlfetch Error: " + error_string res_code = res.status_code res_headers = dict(res.headers) content_length = int(res_headers.get("Content-Length", 0)) maxsize = int(kwargs.get('maxsize', URLFETCH_DEFLATE_MAXSIZE)) if (method == "GET" and res_code == 200 and content_length and maxsize and content_length > maxsize and "Range" not in req_headers and res_headers.get('Accept-Ranges', '').lower() == 'bytes'): res_code = 206 res_headers['Content-Range'] = 'bytes 0-%d/%d' % (maxsize - 1, content_length) res_content = res.raw.read(maxsize) logging.info("get %s data len:%d max:%d", url, content_length, maxsize) else: res_content = res.raw.read() if "Transfer-Encoding" in res_headers: del res_headers["Transfer-Encoding"] res_headers["X-Head-Content-Length"] = res_headers["Content-Length"] = len(res_content) return res_code, res_headers, res_content def req_by_urlfetch(method, url, req_headers, req_body, kwargs): timeout = int(kwargs.get('timeout', URLFETCH_TIMEOUT)) maxsize = int(kwargs.get('maxsize', URLFETCH_DEFLATE_MAXSIZE)) verify = bool(int(kwargs.get('validate', 0))) errors = [] allow_truncated = False for i in range(int(kwargs.get('fetchmax', URLFETCH_MAX))): try: t0 = time.time() res = urlfetch.fetch(url, req_body, method, req_headers, allow_truncated=allow_truncated, follow_redirects=False, deadline=timeout, validate_certificate=False) # res = requests.request(method, url, headers=req_headers, data=req_body, timeout=timeout, verify=verify, # stream=True, allow_redirects=False) t1 = time.time() logging.info(f"cost:{t1-t0} {method} {url} res:{res.status_code}") break except apiproxy_errors.OverQuotaError as e: logging.info('%s %s OverQuotaError:%r', method, url, e) return 510, {}, "510 Traffic exceed" except urlfetch.SSLCertificateError as e: errors.append('%r, should validate=0 ?' % e) logging.warning('%r, timeout=%s', e, timeout) return 502, {}, "502 SSLCertificateError" except urlfetch.DeadlineExceededError as e: errors.append('%r, timeout=%s' % (e, timeout)) logging.warning('DeadlineExceededError(timeout=%s, url=%r)', timeout, url) time.sleep(1) allow_truncated = True m = re.search(r'=\s*(\d+)-', req_headers.get('Range') or req_headers.get('range') or '') if m is None: req_headers['Range'] = 'bytes=0-%d' % (maxsize) else: req_headers.pop('Range', '') req_headers.pop('range', '') start = int(m.group(1)) req_headers['Range'] = 'bytes=%s-%d' % (start, start + maxsize) timeout *= 2 except urlfetch.DownloadError as e: errors.append('%r, timeout=%s' % (e, timeout)) logging.warning('DownloadError(timeout=%s, url=%r)', timeout, url) time.sleep(1) timeout *= 2 except urlfetch.ResponseTooLargeError as e: errors.append('%r, timeout=%s' % (e, timeout)) response = e.response logging.warning('ResponseTooLargeError(timeout=%s, url=%r) response(%r)', timeout, url, response) m = re.search(r'=\s*(\d+)-', req_headers.get('Range') or req_headers.get('range') or '') if m is None: req_headers['Range'] = 'bytes=0-%d' % (maxsize) else: req_headers.pop('Range', '') req_headers.pop('range', '') start = int(m.group(1)) req_headers['Range'] = 'bytes=%s-%d' % (start, start + (maxsize)) timeout *= 2 except Exception as e: logging.warning("request %s %s %s %s %s e:%r", method, url, req_headers, timeout, verify, e) errors.append(str(e)) if i == 0 and method == 'GET': timeout *= 2 else: error_string = '
\n'.join(errors) logging.warning('%s %s error:%s', method, url, error_string) return 502, {}, "502 Urlfetch Error: " + error_string res_code = res.status_code res_headers = dict(res.headers) content_length = int(res_headers.get("Content-Length", 0)) if (method == "GET" and res_code == 200 and content_length and maxsize and content_length > maxsize and "Range" not in req_headers and res_headers.get('Accept-Ranges', '').lower() == 'bytes'): res_code = 206 res_headers['Content-Range'] = 'bytes 0-%d/%d' % (maxsize - 1, content_length) res_content = res.content[:maxsize] logging.info("get %s data len:%d max:%d", url, content_length, maxsize) else: res_content = res.content if "Transfer-Encoding" in res_headers: del res_headers["Transfer-Encoding"] res_headers["X-Head-Content-Length"] = res_headers["Content-Length"] = len(res_content) return res_code, res_headers, res_content @app.route("/_gh/", methods=['POST']) def proxy(): if is_traffic_exceed(): logging.info('Traffic exceed') return "510 Traffic exceed", 510 t0 = time.time() try: method, url, req_headers, req_body, kwargs = unpack_request(request.data) except Exception as e: logging.exception("unpack request:%r", e) return "500 Bad Request", 500 # logging.info('from:%s method:%s url:%s kwargs:%s -', request.remote_addr, method, url, kwargs) # 参数使用 if __password__ != kwargs.get('password', ''): logging.info('wrong password') return "401 Wrong password", 401 netloc = urlparse(url).netloc if netloc.startswith(('127.0.0.', '::1', 'localhost')): return "GoAgent is Running", 400 if len(url) > MAX_URL_LENGTH or method not in gae_support_methods: res_code, res_headers, res_body = req_by_requests(method, url, req_headers, req_body, kwargs) else: res_code, res_headers, res_body = req_by_urlfetch(method, url, req_headers, req_body, kwargs) res_data = pack_response(res_code, res_headers, b"", res_body) t1 = time.time() cost = t1 - t0 logging.info("cost:%f %s %s res_len:%d", cost, method, url, len(res_body)) count_traffic(len(request.data) + len(res_data)) resp = flask.Response(res_data) resp.headers['Content-Type'] = 'image/gif' return resp if __name__ == "__main__": # This is used when running locally only. When deploying to Google App # Engine, a webserver process such as Gunicorn will serve the app. app.run(host="127.0.0.1", port=8080, debug=True) ================================================ FILE: code/default/gae_proxy/server/gae/requirements.txt ================================================ Flask==3.0.0 requests gunicorn google-cloud-storage appengine-python-standard psutil ================================================ FILE: code/default/gae_proxy/tests/test_protocol.py ================================================ from unittest import TestCase import os import sys from os.path import join import http.client as httplib import json import struct import zlib import traceback import requests import logging logging.basicConfig(format='%(asctime)s - %(message)s', level=logging.DEBUG) logger = logging.getLogger('simple_example') logger.setLevel(logging.DEBUG) current_path = os.path.dirname(os.path.abspath(__file__)) gae_path = os.path.abspath( os.path.join(current_path, os.pardir)) default_path = os.path.abspath( os.path.join(gae_path, os.pardir)) # local_path = join(gae_path, "local") # sys.path.append(local_path) sys.path.append(join(default_path, "lib", "noarch")) import utils import xlog skip_request_headers = frozenset([ b'Vary', b'Via', b'Proxy-Authorization', b'Proxy-Connection', b'Upgrade', b'X-Google-Cache-Control', b'X-Forwarded-For', b'X-Chrome-Variations', ]) skip_response_headers = frozenset([ # http://en.wikipedia.org/wiki/Chunked_transfer_encoding b'Connection', b'Upgrade', b'Alt-Svc', b'Alternate-Protocol', b'X-Head-Content-Length', b'X-Google-Cache-Control', b'X-Chrome-Variations', ]) def inflate(data): return zlib.decompress(data, -zlib.MAX_WBITS) def deflate(data): return zlib.compress(data)[2:-4] class Conf(object): GAE_PASSWORD = "" GAE_VALIDATE = 0 JS_MAXSIZE = 10000 AUTORANGE_MAXSIZE = 256000 config = Conf() def pack_request(method, url, headers, body, kwargs): method = utils.to_bytes(method) url = utils.to_bytes(url) headers = utils.to_bytes(headers) body = utils.to_bytes(body) kwargs = utils.to_bytes(kwargs) if body: if len(body) < 10 * 1024 * 1024 and b'Content-Encoding' not in headers: # 可以压缩 zbody = deflate(body) if len(zbody) < len(body): body = zbody headers[b'Content-Encoding'] = b'deflate' if len(body) > 10 * 1024 * 1024: xlog.warn("body len:%d %s %s", len(body), utils.to_bytes(method), utils.to_bytes(url)) headers[b'Content-Length'] = utils.to_bytes(str(len(body))) # GAE don't allow set `Host` header if b'Host' in headers: del headers[b'Host'] # gae 用的参数 if config.GAE_PASSWORD: kwargs[b'password'] = config.GAE_PASSWORD # kwargs['options'] = kwargs[b'validate'] = config.GAE_VALIDATE if url.endswith(b".js"): kwargs[b'maxsize'] = config.JS_MAXSIZE else: kwargs[b'maxsize'] = config.AUTORANGE_MAXSIZE # gae 用的参数 end payload = b'%s %s HTTP/1.1\r\n' % (method, url) payload += b''.join(b'%s: %s\r\n' % (k, v) for k, v in list(headers.items()) if k not in skip_request_headers) # for k, v in headers.items(): # xlog.debug("Send %s: %s", k, v) for k, v in kwargs.items(): if isinstance(v, int): payload += b'X-URLFETCH-%s: %d\r\n' % (k, v) else: payload += b'X-URLFETCH-%s: %s\r\n' % (k, utils.to_bytes(v)) payload = deflate(payload) body = b'%s%s%s' % (struct.pack('!h', len(payload)), payload, body) request_headers = {} request_headers[b'Content-Length'] = str(len(body)) # request_headers 只有上面一项 return request_headers, body def unpack_request(payload): head_len = struct.unpack('!h', payload[0:2])[0] print(head_len) head = payload[2:2+head_len] body = payload[2+head_len:] head = inflate(head) lines = head.split(b"\r\n") method, url = lines[0].split()[:2] headers = {} kwargs = {} for line in lines[1:]: ls = line.split(b": ") k = ls[0] if not k: continue v = b"".join(ls[1:]) if k.startswith(b"X-URLFETCH-"): k = k[11:] kwargs[k] = v else: headers[k] = v timeout = int(kwargs.get(b"timeout", 30)) if headers.get(b"Content-Encoding") == b"deflate": body = inflate(body) del headers[b"Content-Encoding"] return method, url, headers, body, timeout, kwargs def pack_response(status, headers, app_msg, content): if app_msg: headers.pop('content-length', None) headers['Content-Length'] = str(len(app_msg)) headers = utils.to_bytes(headers) data = b'HTTP/1.1 %d %s\r\n%s\r\n\r\n%s' % \ (status, utils.to_bytes(httplib.responses.get(status, 'Unknown')), b'\r\n'.join(b'%s: %s' % (k.title(), v) for k, v in headers.items()), app_msg) data = deflate(data) return struct.pack('!h', len(data)) + data + content def unpack_response(body): try: data = body[:2] if not data: raise Exception(600, "get protocol head fail") if len(data) !=2: raise Exception(600, "get protocol head fail, data:%s, len:%d" % (data, len(data))) headers_length, = struct.unpack('!h', data) data = body[2:2+headers_length] if not data: raise Exception(600, "get protocol head fail, len:%d" % headers_length) raw_response_line, headers_data = inflate(data).split(b'\r\n', 1) rl = raw_response_line.split() status_code = int(rl[1]) if len(rl) >=3: reason = rl[2].strip() else: reason = b"" headers_block, app_msg = headers_data.split(b'\r\n\r\n', 1) headers_pairs = headers_block.split(b'\r\n') headers = {} for pair in headers_pairs: if not pair: break k, v = pair.split(b': ', 1) headers[k] = v content = body[2+headers_length:] return status_code, reason, headers, app_msg, content except Exception as e: raise Exception(600, "unpack protocol:%r at:%s" % (e, traceback.format_exc())) class TestProtocol(TestCase): def test_req(self): method = b"POST" url = b"https://cloud.google.com/" info = { "req": "a", "type": "b" } body = utils.to_bytes(json.dumps(info)) headers = { "Content-Length": str(len(body)), "Content-Type": "application/json" } headers = utils.to_bytes(headers) timeout = 30 request_headers, payload = pack_request(method, url, headers, body, timeout) method1, url1, headers1, body1, timeout1, kwargs = unpack_request(payload) print(f"method:{method1}") print(f"url1:{url1}") print(f"headers1:{headers1}") print(f"body1:{body1}") print(f"timeout1:{timeout1}") print(f"kwargs:{kwargs}") def test_response(self): status = 200 headers = { b"Cookie": b"abc" } content = b"ABC" payload = pack_response(status, headers, b"", content) status_code, reason, res_headers, app_msg, body = unpack_response(payload) self.assertEqual(status, status_code) # self.assertEqual(headers, res_headers) self.assertEqual(content, body) print(f"status:{status_code}") print(f"reason:{reason}") logging.debug(f"res_headers:{res_headers}") logger.debug(f"body:{body}") def test_pack_real_response(self): res = requests.get("https://github.com") status = res.status_code headers = dict(res.headers) content = res.content payload = pack_response(status, headers, b"", content) status_code, reason, res_headers, app_msg, body = unpack_response(payload) self.assertEqual(status, status_code) # self.assertEqual(headers, res_headers) self.assertEqual(content, body) print(f"status:{status_code}") print(f"reason:{reason}") print(f"res_headers:{res_headers}") logging.debug(f"body:{body}") def test_req_local(self, url="http://speedtest.ftp.otenet.gr/files/test10Mb.db"): method = "GET" body = "" headers = { # "Content-Length": str(len(body)), # "Content-Type": "application/json" "Accept-Encoding": "gzip, br" } kwargs = { "timeout": "30" } request_headers, payload = pack_request(method, url, headers, body, kwargs) res = requests.post("http://localhost:8080/_gh/", data=payload) status_code, reason, res_headers, app_msg, body = unpack_response(res.content) logging.debug(f"status:{status_code}") logging.debug(f"reason:{reason}") res_headers = utils.to_str(res_headers) logging.debug(f"res_headers:{json.dumps(res_headers, indent=2)}") logging.debug(f"body_len:{len(body)}") logging.debug(f"body_100:{body[:100]}") def test_local_req(self): url = "http://github.com" self.test_req_local(url) ================================================ FILE: code/default/gae_proxy/web_ui/advanced.html ================================================
================================================ FILE: code/default/gae_proxy/web_ui/check_ip.html ================================================

{{ _( "Status" ) }}

{{ _( "Property" ) }} {{ _( "Value" ) }}
{{ _( "All IP Number" ) }}
{{ _( "Left Number" ) }}
{{ _( "Good IP Number" ) }}
================================================ FILE: code/default/gae_proxy/web_ui/config.html ================================================

{{ _( "The public AppIDs are disabled to access videos or download files." ) }} ({{ _( "How to apply" ) }})

{{ _( "Attention: inaccessable before AppIDs are deployed." ) }}

{{ _( "Advanced tricks:" ) }} {{ _( "By the configuration file" ) }}
================================================ FILE: code/default/gae_proxy/web_ui/deploy.html ================================================

{{ _( "Deploy XX-Net onto GAE" ) }}

{{ _( "Current status: " ) }}{{ _( "idle" ) }}

* {{ _( "Auth window will popup, make sure don't block popup in browser." ) }}

================================================ FILE: code/default/gae_proxy/web_ui/export_ip.html ================================================
================================================ FILE: code/default/gae_proxy/web_ui/global_setting.html ================================================
================================================ FILE: code/default/gae_proxy/web_ui/import_ip.html ================================================
================================================ FILE: code/default/gae_proxy/web_ui/ipv6_tunnel.html ================================================

{{ _( "Status" ) }}

{{ _( "Property" ) }} {{ _( "Value" ) }}
{{ _( "Teredo Tunnel" ) }}

{{ _( "Tips" ) }}

  1. {{ _( "Enable operations usually only needs to be performed once at each device." ) }}
  2. {{ _( "After changing the server, it takes 10-90 seconds to successfully establish a new teredo tunnel." ) }}
  3. {{ _( "To use teredo tunnel, win user must keep firewall enabled, and allow outbound." ) }}
  4. {{ _( "Non-win users can also use the test button to get the fastest server for change manually." ) }}
================================================ FILE: code/default/gae_proxy/web_ui/logging.html ================================================
================================================ FILE: code/default/gae_proxy/web_ui/menu.json ================================================ { "module_title": "GAEProxy", "menu_sort_id": 1, "sub_menus": { "1":{ "title": "{{ _("Status") }}", "url": "status" }, "2":{ "title": "{{ _("Configuration") }}", "url": "config" }, "4":{ "title": "{{ _("Advanced") }}", "url": "advanced" }, "5":{ "title": "{{ _("Log") }}", "url": "logging" } } } ================================================ FILE: code/default/gae_proxy/web_ui/scan_setting.html ================================================
================================================ FILE: code/default/gae_proxy/web_ui/status.html ================================================
{{ _( "Show Details" ) }}
================================================ FILE: code/default/launcher/__init__.py ================================================ ================================================ FILE: code/default/launcher/autorun.py ================================================ #!/usr/bin/env python """A simple crossplatform autostart helper""" import os import sys from config import app_name from xlog import getLogger xlog = getLogger("launcher") current_path = os.path.dirname(os.path.abspath(__file__)) root_path = os.path.abspath(os.path.join(current_path, os.pardir)) top_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir)) if sys.platform == 'win32': import winreg _registry = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) def get_runonce(): return winreg.OpenKey(_registry, r"Software\Microsoft\Windows\CurrentVersion\Run", 0, winreg.KEY_ALL_ACCESS) def add(name, application): """add a new autostart entry""" key = get_runonce() winreg.SetValueEx(key, name, 0, winreg.REG_SZ, application) winreg.CloseKey(key) def exists(name): """check if an autostart entry exists""" key = get_runonce() exists = True try: winreg.QueryValueEx(key, name) except: # WindowsError exists = False winreg.CloseKey(key) return exists def remove(name): if not exists(name): return """delete an autostart entry""" key = get_runonce() winreg.DeleteValue(key, name) winreg.CloseKey(key) run_cmd = "\"" + os.path.join(top_path, "start.vbs") + "\"" elif sys.platform.startswith('linux'): _xdg_config_home = os.environ.get("XDG_CONFIG_HOME", "~/.config") home_config_path = os.path.expanduser(_xdg_config_home) _xdg_user_autostart = os.path.join(home_config_path, "autostart") def getfilename(name): """get the filename of an autostart (.desktop) file""" return os.path.join(_xdg_user_autostart, name + ".desktop") def add(name, application): if not os.path.isdir(home_config_path): xlog.warn("autorun linux config path not found:%s", home_config_path) return if not os.path.isdir(_xdg_user_autostart): try: os.mkdir(_xdg_user_autostart) except Exception as e: xlog.warn("Enable auto start, create path:%s fail:%r", _xdg_user_autostart, e) return """add a new autostart entry""" desktop_entry = "[Desktop Entry]\n" \ "Name=%s\n" \ "Exec=%s\n" \ "Type=Application\n" \ "Terminal=false\n" \ "X-GNOME-Autostart-enabled=true" % (name, application) with open(getfilename(name), "w") as f: f.write(desktop_entry) def exists(name): """check if an autostart entry exists""" return os.path.exists(getfilename(name)) def remove(name): """delete an autostart entry""" if (exists(name)): os.unlink(getfilename(name)) run_cmd = os.path.join(top_path, "start") elif sys.platform == 'darwin': plist_template = """ Label com.xxnet.launcher LimitLoadToSessionType Aqua ProgramArguments %s -hungup RunAtLoad StandardErrorPath /dev/null StandardOutPath /dev/null """ run_cmd = os.path.join(top_path, "start") from os.path import expanduser home = expanduser("~") launch_path = os.path.join(home, "Library/LaunchAgents") plist_file_path = os.path.join(launch_path, "com.xxnet.launcher.plist") def add(name, cmd): file_content = plist_template % cmd xlog.info("create file:%s", plist_file_path) if not os.path.isdir(launch_path): os.mkdir(launch_path, 0o755) with open(plist_file_path, "w") as f: f.write(file_content) def remove(name): if (os.path.isfile(plist_file_path)): os.unlink(plist_file_path) xlog.info("remove file:%s", plist_file_path) else: def add(name, cmd): pass def remove(name): pass def enable(): add(app_name, run_cmd) def disable(): remove(app_name) def test(): assert not exists("test_xxx") try: add("test_xxx", "test") assert exists("test_xxx") finally: remove("test_xxx") assert not exists("test_xxx") if __name__ == "__main__": test() ================================================ FILE: code/default/launcher/babel.config ================================================ # Extraction from Python source files #[python: **.py] # Extraction from HTML and YAML templates [jinja2: **/web_ui/**.html] [jinja2: **/web_ui/**.yaml] encoding = utf-8 ================================================ FILE: code/default/launcher/config.py ================================================ #!/usr/bin/env python import os import subprocess import locale import json import sys_platform from simple_http_client import request import xconfig from xlog import getLogger xlog = getLogger("launcher") current_path = os.path.dirname(os.path.abspath(__file__)) version_path = os.path.abspath(os.path.join(current_path, os.pardir)) root_path = os.path.abspath(os.path.join(version_path, os.pardir, os.pardir)) import env_info data_path = env_info.data_path config_path = os.path.join(data_path, 'launcher', 'config.json') config = xconfig.Config(config_path) config.set_var("control_ip", "127.0.0.1") config.set_var("control_port", 8085) config.set_var("allowed_refers", [""]) # System config config.set_var("language", "") # en_US, config.set_var("allow_remote_connect", 0) config.set_var("show_systray", 1) config.set_var("show_android_notification", 1) config.set_var("no_mess_system", 0) config.set_var("auto_start", 0) config.set_var("popup_webui", 1) config.set_var("webui_auth", {}) config.set_var("gae_show_detail", 0) config.set_var("show_compat_suggest", 1) config.set_var("proxy_by_app", 0) config.set_var("enabled_app_list", []) # version control config.set_var("check_update", "notice-stable") # can be: "dont-check", "stable", "notice-stable", "test", "notice-test" config.set_var("keep_old_ver_num", 1) config.set_var("postUpdateStat", "noChange") # "noChange", "isNew", "isPostUpdate" config.set_var("current_version", "") config.set_var("ignore_version", "") config.set_var("last_run_version", "") config.set_var("skip_stable_version", "") config.set_var("skip_test_version", "") # update: config.set_var("last_path", "") config.set_var("update_uuid", "") # savedisk config.set_var("clear_cache", 0) config.set_var("del_win", 0) config.set_var("del_mac", 0) config.set_var("del_linux", 0) config.set_var("del_gae", 0) config.set_var("del_gae_server", 0) config.set_var("del_xtunnel", 0) config.set_var("del_smartroute", 0) # Module config.set_var("all_modules", ["launcher", "gae_proxy", "x_tunnel", "smart_router"]) config.set_var("enable_launcher", 1) config.set_var("enable_x_tunnel", 1) config.set_var("enable_gae_proxy", 0) config.set_var("enable_smart_router", 1) config.set_var("os_proxy_mode", "pac") # can be: gae, x_tunnel, smart_router, disable # Proxy config.set_var("global_proxy_enable", 0) config.set_var("global_proxy_type", "HTTP") # can be: HTTP/ SOCKS4/ SOCKs5 config.set_var("global_proxy_host", "") config.set_var("global_proxy_port", 0) config.set_var("global_proxy_username", "") config.set_var("global_proxy_password", "") try: config.load() except Exception as e: xlog.warn("loading config e:%r", e) app_name = "XX-Net" valid_language = ['en_US', 'fa_IR', 'zh_CN', 'ru_RU'] try: fp = os.path.join(root_path, "code", "app_info.json") with open(fp, "r") as fd: app_info = json.load(fd) app_name = app_info["app_name"] except Exception as e: print("load app_info except:", e) pass def _get_os_language(): if sys_platform.platform == "mac": try: lang_code = subprocess.check_output(["/usr/bin/defaults", 'read', 'NSGlobalDomain', 'AppleLanguages']) if b'zh' in lang_code: return 'zh_CN' elif b'en' in lang_code: return 'en_US' elif b'fa' in lang_code: return 'fa_IR' elif b'ru' in lang_code: return 'ru_RU' except: pass elif sys_platform.platform == "android": try: res = request("GET", "http://localhost:8084/env/") dat = json.loads(res.text) lang_code = dat["lang_code"] xlog.debug("lang_code:%s", lang_code) if 'zh' in lang_code: return 'zh_CN' elif 'en' in lang_code: return 'en_US' elif 'fa' in lang_code: return 'fa_IR' elif 'ru' in lang_code: return 'ru_RU' else: return None except Exception as e: xlog.warn("get lang except:%r", e) return "zh_CN" elif sys_platform.platform == "ios": lang_code = os.environ["IOS_LANG"] if 'zh' in lang_code: return 'zh_CN' elif 'en' in lang_code: return 'en_US' elif 'fa' in lang_code: return 'fa_IR' elif 'ru' in lang_code: return 'ru_RU' else: return None else: try: lang_code, code_page = locale.getdefaultlocale() # ('en_GB', 'cp1252'), en_US, return lang_code except: # Mac fail to run this pass def get_language(): if config.language: lang = config.language else: lang = _get_os_language() if lang not in valid_language: lang = 'en_US' return lang ================================================ FILE: code/default/launcher/create_shortcut.js ================================================ function getParent(path) { var fso = new ActiveXObject("Scripting.FileSystemObject") return fso.GetParentFolderName(path) } function CreateShortcut(app_name) { var wsh = new ActiveXObject('WScript.Shell'); var fso = new ActiveXObject("Scripting.FileSystemObject"); system_folder = fso.GetSpecialFolder(1) target_path = '"' + system_folder + '\\wscript.exe"'; xxnet_path = getParent(getParent(getParent(wsh.CurrentDirectory))); //var shell = new ActiveXObject("WScript.Shell"); //shell.Popup(xxnet_path); // for debugging argument_file = '"' + xxnet_path + '\\start.vbs"'; icon_path = wsh.CurrentDirectory + '\\web_ui\\img\\' + app_name + '\\favicon.ico'; link = wsh.CreateShortcut(wsh.SpecialFolders("Desktop") + '\\' + app_name + '.lnk'); link.TargetPath = target_path; link.Arguments = argument_file; link.WindowStyle = 7; link.IconLocation = icon_path; link.Description = app_name; link.WorkingDirectory = xxnet_path; link.Save(); } function main() { var app_name = WScript.arguments(0); CreateShortcut(app_name); } main(); ================================================ FILE: code/default/launcher/download.vbs ================================================ Sub DownloadFile1(url, strPath) dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP") dim bStrm: Set bStrm = createobject("Adodb.Stream") xHttp.Open "GET", url, False xHttp.Send with bStrm .type = 1 '//binary .open .write xHttp.responseBody .savetofile strPath, 2 '//overwrite end with End Sub Sub DownloadFile2(url, strPath) set WinHttpReq =CreateObject("WinHttp.WinHttpRequest.5.1") WinHttpReq.Open "GET", url, False WinHttpReq.Send dim BinStream: Set BinStream = createobject("Adodb.Stream") BinStream.Type = 1 BinStream.Open BinStream.Write WinHttpReq.ResponseBody BinStream.SaveToFile strPath End Sub ================================================ FILE: code/default/launcher/download_modules.py ================================================ import os import threading import time import zipfile import shutil from update_from_github import request, xlog, hash_file_sum import env_info current_path = os.path.dirname(os.path.abspath(__file__)) root_path = os.path.abspath(os.path.join(current_path, os.pardir)) top_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir)) def download_file(url, filename, sha256=None): org_url = url if os.path.isfile(filename): return True for i in range(0, 4): try: xlog.info("download %s to %s, retry:%d", url, filename, i) req = request(url, i, timeout=120) if not req: time.sleep(60) continue if req.status == 302: url = req.headers[b"Location"] continue start_time = time.time() timeout = 300 if req.chunked: downloaded = 0 with open(filename, 'wb') as fp: while True: time_left = timeout - (time.time() - start_time) if time_left < 0: raise Exception("time out") dat = req.read(timeout=time_left) if not dat: break fp.write(dat) downloaded += len(dat) return True else: file_size = int(req.getheader(b'Content-Length', 0)) left = file_size downloaded = 0 with open(filename, 'wb') as fp: while True: chunk_len = min(65536, left) if not chunk_len: break chunk = req.read(chunk_len) if not chunk: break fp.write(chunk) downloaded += len(chunk) left -= len(chunk) if downloaded != file_size: xlog.warn("download size:%d, need size:%d, download fail.", downloaded, file_size) os.remove(filename) continue else: if sha256 and sha256 != hash_file_sum(filename): xlog.warn("donwload %s checksum fail.", filename) return False else: xlog.info("download %s to %s success.", org_url, filename) return True except Exception as e: xlog.exception("download %s to %s fail:%r", org_url, filename, e) continue xlog.warn("download %s fail", org_url) def download_unzip(url, extract_path): if os.path.isdir(extract_path): return True data_root = env_info.data_path download_path = os.path.join(data_root, 'downloads') if not os.path.isdir(download_path): os.mkdir(download_path) fn = url.split("/")[-1] dfn = os.path.join(download_path, fn) if not download_file(url, dfn): xlog.warn("download file %s fail.", url) return try: os.mkdir(extract_path) with zipfile.ZipFile(dfn, "r") as dz: dz.extractall(extract_path) dz.close() xlog.info("Extract %s to %s success.", fn, extract_path) except Exception as e: xlog.warn("unzip %s fail:%r", dfn, e) shutil.rmtree(extract_path) raise e os.remove(dfn) def get_sha256(fn): sha256_dict = {} with open(fn, "r") as fd: for line in fd.readlines(): if not line: break n, sha256 = line.split()[:2] sha256_dict[n] = sha256 return sha256_dict def download_worker(): switchyomega_path = os.path.join(top_path, "SwitchyOmega") if not os.path.isdir(switchyomega_path): return time.sleep(150) sha256_fn = os.path.join(switchyomega_path, "Sha256.txt") download_file("https://raw.githubusercontent.com/XX-net/XX-Net/master/SwitchyOmega/Sha256.txt", sha256_fn) sha256_dict = get_sha256(sha256_fn) download_file("https://github.com/XX-net/XX-Net/releases/download/5.1.1/SwitchyOmega.zip", os.path.join(switchyomega_path, "SwitchyOmega.zip"), sha256_dict.get("SwitchyOmega.zip", None)) download_file("https://github.com/XX-net/XX-Net/releases/download/3.15.0/AutoProxy.xpi", os.path.join(switchyomega_path, "AutoProxy.xpi"), sha256_dict.get("AutoProxy.xpi", None)) def start_download(): th = threading.Thread(target=download_worker, name="file_downloader") th.start() return True ================================================ FILE: code/default/launcher/global_var.py ================================================ running = True ================================================ FILE: code/default/launcher/gtk_tray.py ================================================ #!/usr/bin/env python # coding:utf-8 # Contributor: # Phus Lu import os import sys import webbrowser from config import config, app_name from xlog import getLogger xlog = getLogger("launcher") current_path = os.path.dirname(os.path.abspath(__file__)) if __name__ == "__main__": python_path = os.path.abspath(os.path.join(current_path, os.pardir)) noarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch')) sys.path.append(noarch_lib) # Only enable AppIndicator in the DEs that are Unity and QT-based enable_appind = False if 'XDG_CURRENT_DESKTOP' in os.environ: cur_desktops = os.environ['XDG_CURRENT_DESKTOP'].split(':') if {'Unity', 'KDE', 'LXQt', 'ENLIGHTENMENT'}.intersection(cur_desktops): enable_appind = True try: import pygtk pygtk.require('2.0') import gtk import gtk.gdk as gdk use_gi = False xlog.info('Using PyGTK as the GUI Backend.') except: # How to install gi: # The simple way: # sudo apt-get install python3-gi # For virtualenv users - The vext way # pip install vext # pip install vext.gi # The pure python developer way: # Install a bunch of developer stuff: # sudo apt-get install pkg-config libcairo2-dev gcc python3-dev libgirepository1.0-dev # Install the python packages: # pip install gobject PyGObject import gi gi.require_version('Gtk', '3.0') gi.require_version('Gdk', '3.0') from gi.repository import Gtk as gtk from gi.repository import Gdk as gdk use_gi = True xlog.info('Using PyGObject as the GUI Backend.') gdk.threads_init() import module_init if use_gi: try: gi.require_version('Notify', '0.7') from gi.repository import Notify as notify notify.init(app_name + ' Notify') new_notification = notify.Notification.new except: xlog.warn("import Notify fail, please install libnotify if possible.") notify = None try: assert (enable_appind) gi.require_version('AppIndicator3', '0.1') from gi.repository import AppIndicator3 as appindicator new_appindicator = appindicator.Indicator.new appind_category = appindicator.IndicatorCategory.APPLICATION_STATUS appind_status = appindicator.IndicatorStatus.ACTIVE except: appindicator = None popup_trayicon_menu = lambda m, s, b, t: m.popup(None, None, gtk.StatusIcon.position_menu, s, b, t) else: try: import pynotify as notify notify.init(app_name + ' Notify') new_notification = notify.Notification except: xlog.warn("import pynotify fail, please install python-notify if possible.") notify = None try: assert (enable_appind) import appindicator new_appindicator = appindicator.Indicator appind_category = appindicator.CATEGORY_APPLICATION_STATUS appind_status = appindicator.STATUS_ACTIVE except: appindicator = None popup_trayicon_menu = lambda m, s, b, t: m.popup(None, None, gtk.status_icon_position_menu, b, t, s) class Gtk_tray(): notify_list = [] def __init__(self): logo_filename = os.path.join(os.path.abspath(current_path), 'web_ui', 'img', app_name, 'favicon.ico') if appindicator: self.trayicon = self.appind_trayicon(logo_filename) xlog.info('AppIndicator found and used.') else: self.trayicon = self.gtk_trayicon(logo_filename) xlog.info('Gtk.StatusIcon used.') def appind_trayicon(self, logo_filename): trayicon = new_appindicator(app_name, 'indicator-messages', appind_category) trayicon.set_status(appind_status) trayicon.set_attention_icon('indicator-messages-new') trayicon.set_icon(logo_filename) trayicon.set_menu(self.make_menu()) try: # this method does not exist when using pygtk and python2-appindicator trayicon.set_title(app_name) except: pass return trayicon def gtk_trayicon(self, logo_filename): trayicon = gtk.StatusIcon() trayicon.set_from_file(logo_filename) trayicon.connect('popup-menu', lambda i, b, t: popup_trayicon_menu(self.make_menu(), trayicon, b, t)) trayicon.connect('activate', self.show_control_web) trayicon.set_tooltip_text(app_name) trayicon.set_title(app_name) trayicon.set_visible(True) return trayicon def make_menu(self): menu = gtk.Menu() itemlist = [('Config', self.on_show), ('Reset Each Module', self.on_restart_each_module), ('Quit', self.on_quit)] for text, callback in itemlist: item = gtk.MenuItem(text) item.connect('activate', callback) item.show() menu.append(item) menu.show() return menu def on_show(self, widget=None, data=None): self.show_control_web() def notify_general(self, msg="msg", title="Title", buttons={}, timeout=3600): if not notify: return False n = new_notification('Test', msg) for k in buttons: data = buttons[k]["data"] label = buttons[k]["label"] callback = buttons[k]["callback"] n.add_action(data, label, callback) n.set_timeout(timeout) n.show() self.notify_list.append(n) return True def show_control_web(self, widget=None, data=None): host_port = config.control_port webbrowser.open_new("http://127.0.0.1:%s/" % host_port) def on_restart_each_module(self, widget=None, data=None): module_init.stop_all() module_init.start_all_auto() def on_quit(self, widget=None, data=None): module_init.stop_all() os._exit(0) gtk.main_quit() def serve_forever(self): gdk.threads_enter() gtk.main() gdk.threads_leave() sys_tray = Gtk_tray() def main(): sys_tray.serve_forever() if __name__ == '__main__': main() ================================================ FILE: code/default/launcher/lang/fa_IR/LC_MESSAGES/messages.po ================================================ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2022-02-25 02:08-0500\n" "PO-Revision-Date: 2015-12-06 09:18+0800\n" "Last-Translator: FULL NAME \n" "Language: fa_IR\n" "Language-Team: fa_IR \n" "Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.14.0\n" msgid "Hello!" msgstr "سلام!" msgid "You seem to be on your first visit." msgstr "به نظر می رسد شما در اولین دیدار خود هستید." msgid "Learn more" msgstr "بیشتر بدانید" msgid "Notice" msgstr "توجه کنید" msgid "click to view" msgstr "برای مشاهده کلیک کنید" msgid "Version" msgstr "نسخه" msgid "Project main page" msgstr "صفحه اصلی پروژه" msgid "Official Web Site" msgstr "وب سایت رسمی" msgid "Telegram group" msgstr "گروه تلگرام" msgid "Telegram Channel" msgstr "کانال تلگرام" msgid "Bug feedback" msgstr "بازخورد اشکال" msgid "When submitting a bug, please attach " msgstr "هنگام ارسال یک اشکال، لطفا ضمیمه" msgid "the status page " msgstr "صفحه وضعیت " msgid "info and " msgstr "اطلاعات و " msgid "the log page " msgstr "صفحه ورود به سیستم " msgid "contents" msgstr "فهرست" msgid "Collect debug info" msgstr "اطلاعات اشکال زدایی را جمع آوری کنید" msgid "Download" msgstr "دانلود کنید" msgid "Thanks to the following projects" msgstr "تشکر از پروژه های زیر" msgid "About" msgstr "در باره" msgid "General Settings" msgstr "تنظیمات عمومی" msgid "System Version" msgstr "نسخه آزمایشی" msgid "LAN Proxy Setting" msgstr "تنظیم پروکسی LAN" msgid "App List" msgstr "فهرست برنامه" msgid "System Configuration" msgstr "گزینه های پیکربندی سیستم" msgid "Configuration" msgstr "پیکربندی" msgid "Configuring the service[%s]. This page will refresh within %s seconds." msgstr "پیکربندی سرویس [٪ s] را. این صفحه را در عرض٪ s ثانیه تازه کردن." msgid "GAE Proxy" msgstr "GAE پروکسی" msgid "X-Tunnel" msgstr "" msgid "Smart Router" msgstr "روتر هوشمند" msgid "Proxy by APP" msgstr "پروکسی توسط APP" msgid "" "Select which APP should be proxied. You need to restart VPN after change " "this." msgstr "انتخاب کنید کدام APP باید پروکسی باشد. " msgid "Select All" msgstr "همه را انتخاب کنید" msgid "Save" msgstr "ذخیره کنید" msgid "Settings saved successfully, Please restart VPN." msgstr "تنظیمات با موفقیت ذخیره شده است." msgid "Failed saving settings: " msgstr "تنظیمات ذخیره نشد:" msgid "Failed saving settings." msgstr "تنظیمات ذخیره نشد." msgid "Language" msgstr "زبان" msgid "Auto-Startup" msgstr "خودکار راه اندازی" msgid "Popup Status Page on Startup" msgstr "پنجره وضعیت صفحه در راه اندازی" msgid "Allow remote" msgstr "اجازه دسترسی از راه دور" msgid "Help" msgstr "کمک" msgid "Display System Tray(Restarting APP Required)" msgstr "نمایش سینی سیستم (شروع مجدد __ مورد نیاز)" msgid "Display Notification" msgstr "نمایش اعلان" msgid "Display Windows software compatibility suggestions" msgstr "نمایش پیشنهادات سازگاری نرم افزار ویندوز" msgid "Feedback" msgstr "بازخورد اشکال" msgid "Run as Green Software" msgstr "به عنوان نرم افزار سبز اجرا شود" msgid "Module management" msgstr "ماژول مدیریت" msgid "Enable" msgstr "فعال کردن" msgid "Restarting all remote, wait to refresh." msgstr "راه‌اندازی مجدد تمام ریموت‌ها، منتظر بمانید تا بازخوانی شود." msgid "Auto-Upgrade to" msgstr "خودکار ارتقا به" msgid "Do not upgrade" msgstr "ارتقاء نکنید" msgid "Notice stable version" msgstr "به نسخه پایدار توجه کنید" msgid "Stable version" msgstr "نسخه پایدار" msgid "Notice test version" msgstr "نسخه آزمایشی توجه کنید" msgid "Test version" msgstr "نسخه آزمایشی" msgid "Check the latest version" msgstr "بررسی آخرین نسخه" msgid "Current version" msgstr "نسخه فعلی" msgid "Version of the test one" msgstr "نسخه از آزمون یک" msgid "Update now" msgstr "به روز رسانی در حال حاضر" msgid "Version of the stable one" msgstr "نسخه از یکی از با ثبات" msgid "Keep old versions count" msgstr "تعداد نسخه های قدیمی را نگه دارید" msgid "keep all" msgstr "همه را نگه دارید" msgid "Manually Manage" msgstr "مدیریت دستی" msgid "Advanced" msgstr "پیشرفته" msgid "All versions download page" msgstr "صفحه دانلود همه نسخه ها" msgid "Released version" msgstr "نسخه آزمایشی" msgid "Released" msgstr "منتشر شد" msgid "Download & Change to" msgstr "دانلود کنید" msgid "no hash check" msgstr "بدون هش چک" msgid "Local version" msgstr "نسخه پایدار" msgid "Local" msgstr "محلی" msgid "Change to this version" msgstr "بررسی آخرین نسخه" msgid "Delete" msgstr "حذف" msgid "Settings saved successfully." msgstr "تنظیمات با موفقیت ذخیره شده است." msgid "Settings save fail:" msgstr "تنظیمات با موفقیت ذخیره شده است." msgid "Deleted successfully." msgstr "موفقیت خارج" msgid "Deleting local version fail." msgstr "حذف نسخه محلی انجام نشد." msgid "Failed getting local versions." msgstr "دریافت نسخه های محلی ناموفق بود." msgid "Failed getting released versions." msgstr "نسخه های منتشر نشد." msgid "(Remote Web Control Enabled)" msgstr "(کنترل وب از راه دور فعال شده)" msgid "Adaptive width" msgstr "عرض تطبیقی" msgid "Exit" msgstr "خروج" msgid "Menu" msgstr "منو" msgid "Remind me later" msgstr "بعدا به من یادآوری کن" msgid "Do not remind me this version" msgstr "این نسخه را به من یادآوری نکنید" msgid "View changes" msgstr "مشاهده تغییرات" msgid "Exited successfully." msgstr "موفقیت خارج" msgid "Exitting failed." msgstr "Exitting شکست خورده" msgid "Exitting failed. A network error occurred." msgstr "Exitting شکست خورده است. یک خطای شبکه رخ داده است." msgid "new to this version?" msgstr "نسخه آزمایشی" msgid "Unkown error occured. Please refresh the page and try again." msgstr "خطای ناشناخته رخ داد. لطفا صفحه را تازه کنید و دوباره امتحان " msgid "Updating in progress ..." msgstr "به روز رسانی در حال انجام ..." msgid "New " msgstr "جدید" msgid "Finished." msgstr "تمام شده." msgid "Downloading ..." msgstr "بارگیری ..." msgid "Download completed." msgstr "بارگیری کامل" msgid "Log" msgstr "ورود به سیستم" msgid "Your browser is obsolete. Partial functionality will not be available." msgstr "مرورگر شما منسوخ است.عملکرد جزئی در دسترس نخواهد بود." msgid "The latest Chrome browser is recommended." msgstr "آخرین مرورگر Chrome توصیه می شود." msgid "Search" msgstr "جستجو کردن" msgid "Search all issues" msgstr "همه موضوعات را جستجو کنید" msgid "Status" msgstr "وضعیت" msgid "Property" msgstr "ویژگی" msgid "Value" msgstr "ارزش" msgid "Browser Proxy Setting" msgstr "تنظیم پروکسی مرورگر" msgid "CA status" msgstr "وضعیت CA" msgid "System Proxy" msgstr "پروکسی سیستم" msgid "Modules" msgstr "ماژول" msgid "Launcher Web UI" msgstr "UI Launcher Web UI" msgid "LAN proxy" msgstr "پروکسی LAN" msgid "System Info" msgstr "اطلاعات سیستم" msgid "Diagnostic Info" msgstr "اطلاعات تشخیصی" msgid "Check" msgstr "بررسی کنید" msgid "GitHub issues" msgstr "مشکلات GitHub" msgid "or" msgstr "یا" msgid "Google Group Discussions" msgstr "بحث های گروهی گوگل" msgid "Show Details" msgstr "نمایش جزئیات" msgid "Post to Github issue needs to sign in your Github account" msgstr "مسئله ارسال به Github باید وارد حساب Github شما شود" msgid "Status Info" msgstr "اطلاعات وضعیت" msgid "" "-----------%0AProblem Description:%0APlease describe your problem, " "running logs may be needed.%0A%0A-----------%0ADiagnostic information:%0A" msgstr "-----------%0توضیحات مشکل:%0APلطفاً مشکل خود را شرح دهید، ممکن است به اجرای گزارش‌ها نیاز باشد.%0A%0A-----------%0ADاطلاعات تشخیصی:%0A" msgid "disable" msgstr "فعال کردن" msgid "idle" msgstr "بیکار" msgid "working" msgstr "کار کردن" msgid "The status page is empty. Highly likely that " msgstr "صفحه وضعیت خالی است. " msgid " failed getting started. Please follow " msgstr "شروع ناموفق. " msgid "guide" msgstr "راهنما" msgid " to troubleshoot." msgstr "عیب یابی." msgid "Your local network failed, please check your network and firewall." msgstr "شبکه محلی شما ناموفق بود، لطفاً شبکه و فایروال خود را بررسی کنید." msgid "Force-IPv6" msgstr "نیرو-IPV6" msgid " not available, Please check." msgstr "در دسترس نیست، لطفا بررسی کنید." msgid "Force-IPv4" msgstr "نیرو-IPV4" msgid "You may want to $1turn on IP scaner$2." msgstr "ممکن است بخواهید $1 را در IP scaner$2 روشن کنید." msgid "" "You can try turn on IPv6 or use X-Tunnel." msgstr "می‌توانید IPv6 را روشن کنید یا < " msgid "XX-Net is scanning IP. Please wait about half an hour." msgstr "XX-Net در حال اسکن IP است. " msgid "" "Public AppID out of quota, Please deploy your own " "AppID." msgstr "Public AppID خارج از سهمیه، لطفا deploy more " "AppID." msgstr "شناسه برنامه شما خارج از حد نصاب است، لطفا deploy your own AppID." msgstr "شما از AppID های عمومی استفاده می کنید. " msgid ", Everything is OK. Welcome to the FREE Internet." msgstr "، همه چیز اوکی است. " msgid "No response from process: " msgstr "بدون پاسخ از فرآیند:" msgid ". It might have already exited." msgstr "بشرممکن است قبلاً خارج شده باشد." msgid "Global PAC Proxy set" msgstr "مجموعه پروکسی جهانی PAC" msgid "Global GAEProxy Proxy set" msgstr "مجموعه پروکسی جهانی GAEProxy" msgid "Global X-Tunnel Proxy set" msgstr "مجموعه پروکسی تونل ایکس جهانی" msgid "Global Smart-Router Proxy set" msgstr "مجموعه پروکسی روتر هوشمند جهانی" msgid "Global Proxy disabled" msgstr "پروکسی جهانی غیرفعال است" ================================================ FILE: code/default/launcher/lang/ru_RU/LC_MESSAGES/messages.po ================================================ # msgid "" msgstr "" msgid "Hello!" msgstr "Привет!" msgid "You seem to be on your first visit." msgstr "Вы, кажется, находитесь в своем первом визите." msgid "Learn more" msgstr "Узнать больше" msgid "Notice" msgstr "Уведомление" msgid "click to view" msgstr "Нажмите, чтобы просмотреть" msgid "Version" msgstr "Версия" msgid "Project main page" msgstr "Главная страница проекта" msgid "Official Web Site" msgstr "Официальный веб-сайт" msgid "Telegram group" msgstr "Telegram Group" msgid "Telegram Channel" msgstr "Телеграмма канал" msgid "Bug feedback" msgstr "Обратная связь с ошибкой" msgid "When submitting a bug, please attach " msgstr "При отправке ошибки, пожалуйста, прикрепите" msgid "the status page " msgstr "страница статуса" msgid "info and " msgstr "Информация и" msgid "the log page " msgstr "страница журнала" msgid "contents" msgstr "содержимое" msgid "Collect debug info" msgstr "Соберите информацию отладки" msgid "Download" msgstr "Скачать" msgid "Thanks to the following projects" msgstr "Спасибо следующим проектам" msgid "About" msgstr "О" msgid "General Settings" msgstr "общие настройки" msgid "System Version" msgstr "Системная версия" msgid "LAN Proxy Setting" msgstr "Настройка прокси -сервера LAN" msgid "App List" msgstr "Список приложений" msgid "System Configuration" msgstr "Конфигурация системы" msgid "Configuring the service[%s]. This page will refresh within %s seconds." msgstr "" "Настройка службы [%s].Эта страница будет освежаться в течение %с секунд." msgid "GAE Proxy" msgstr "GAE Proxy" msgid "X-Tunnel" msgstr "X-Tunnel" msgid "Smart Router" msgstr "Умный маршрутизатор" msgid "Proxy by APP" msgstr "Прокси от приложения" msgid "" "Select which APP should be proxied. You need to restart VPN after change " "this." msgstr "" "Выберите, какое приложение должно быть прокси.Вам нужно перезапустить VPN " "после изменения." msgid "Select All" msgstr "Выбрать все" msgid "Save" msgstr "Сохранять" msgid "Settings saved successfully, Please restart VPN." msgstr "Настройки успешно сохранились, пожалуйста, перезапустите VPN." msgid "Failed saving settings: " msgstr "Неудачные настройки сохранения:" msgid "Failed saving settings." msgstr "Неудачные настройки сохранения." msgid "Language" msgstr "Язык" msgid "Auto-Startup" msgstr "Auto-Startup" msgid "Popup Status Page on Startup" msgstr "Страница статуса всплывающего окна в стартапе" msgid "Allow Remote" msgstr "Разрешить удаленное" msgid "Help" msgstr "Помощь" msgid "Display System Tray(Restarting APP Required)" msgstr "Показать системный лоток (приложение перезагрузки требуется)" msgid "Display Notification" msgstr "Отображение уведомления" msgid "Display Windows software compatibility suggestions" msgstr "" "Показать предложения по совместимости программного обеспечения Windows" msgid "Feedback" msgstr "Обратная связь" msgid "Run as Green Software" msgstr "Работать как зеленое программное обеспечение" msgid "Module management" msgstr "Управление модулем" msgid "Enable" msgstr "Давать возможность" msgid "Restarting all remote, wait to refresh." msgstr "Перезапустив все удаленные, подождите, чтобы обновить." msgid "Auto-Upgrade to" msgstr "Автоматическое обновление до" msgid "Do not upgrade" msgstr "Не обновляйтесь" msgid "Notice stable version" msgstr "Обратите внимание на стабильную версию" msgid "Stable version" msgstr "Стабильная версия" msgid "Notice test version" msgstr "Обратите внимание на тестовую версию" msgid "Test version" msgstr "Тестовая версия" msgid "Check the latest version" msgstr "Проверьте последнюю версию" msgid "Current version" msgstr "Текущая версия" msgid "Version of the test one" msgstr "Версия тестирования" msgid "Update now" msgstr "Обновить сейчас" msgid "Version of the stable one" msgstr "Версия стабильного" msgid "Keep old versions count" msgstr "Сохраняйте старые версии" msgid "keep all" msgstr "сохранить все" msgid "Manually Manage" msgstr "Вручную управлять" msgid "Advanced" msgstr "Передовой" msgid "All versions download page" msgstr "Страница загрузки всех версий" msgid "Released version" msgstr "Выпущенная версия" msgid "Released" msgstr "Выпущенный" msgid "Download & Change to" msgstr "Скачать и изменить на" msgid "no hash check" msgstr "НЕТ ХАШКА" msgid "Local version" msgstr "Местная версия" msgid "Local" msgstr "Местный" msgid "Change to this version" msgstr "Изменить эту версию" msgid "Delete" msgstr "Удалить" msgid "Settings saved successfully." msgstr "Настройки успешно сохранились." msgid "Settings save fail:" msgstr "Настройки Сохранить" msgid "Deleted successfully." msgstr "Удален успешно." msgid "Deleting local version fail." msgstr "Удаление локальной версии не удастся." msgid "Failed getting local versions." msgstr "Не удалось получить местные версии." msgid "Failed getting released versions." msgstr "Не удалось получить выпущенные версии." msgid "(Remote Web Control Enabled)" msgstr "(Удаленный веб -управление включен)" msgid "Adaptive width" msgstr "Адаптивная ширина" msgid "Exit" msgstr "Выход" msgid "Menu" msgstr "Меню" msgid "Remind me later" msgstr "Напомни мне позже" msgid "Do not remind me this version" msgstr "Не напоминайте мне эту версию" msgid "View changes" msgstr "Просмотреть изменения" msgid "Exited successfully." msgstr "Вышел успешно." msgid "Exitting failed." msgstr "Выпуск не удался." msgid "Exitting failed. A network error occurred." msgstr "Выпуск не удался.Произошла сетевая ошибка." msgid "new to this version?" msgstr "новичок в этой версии?" msgid "Unkown error occured. Please refresh the page and try again." msgstr "" "Произошла неизвестная ошибка.Пожалуйста, обновите страницу и попробуйте еще " "раз." msgid "Updating in progress ..." msgstr "Обновление в процессе ..." msgid "New " msgstr "Новый" msgid "Finished." msgstr "Законченный." msgid "Downloading ..." msgstr "Загрузка ..." msgid "Download completed." msgstr "Загрузка завершена." msgid "Info" msgstr "Информация" msgid "System" msgstr "Система" msgid "Log" msgstr "Бревно" msgid "Your browser is obsolete. Partial functionality will not be available." msgstr "Ваш браузер устарел.Частичная функциональность не будет доступна." msgid "The latest Chrome browser is recommended." msgstr "Рекомендуется последний Chrome Browser." msgid "Search" msgstr "Поиск" msgid "Search all issues" msgstr "Ищите все проблемы" msgid "Status" msgstr "Положение дел" msgid "Property" msgstr "Свойство" msgid "Value" msgstr "Ценить" msgid "Browser Proxy Setting" msgstr "Настройка прокси браузера" msgid "CA status" msgstr "Статус CA" msgid "System Proxy" msgstr "Системный прокси" msgid "Modules" msgstr "Модули" msgid "Launcher Web UI" msgstr "Интернет -пользовательский интерфейс" msgid "LAN proxy" msgstr "LAN Proxy" msgid "System Info" msgstr "Системная информация" msgid "Diagnostic Info" msgstr "Диагностическая информация" msgid "Check" msgstr "Проверять" msgid "GitHub issues" msgstr "GitHub выпуски" msgid "or" msgstr "или" msgid "Google Group Discussions" msgstr "Google Group обсуждения" msgid "Show Details" msgstr "Показать детали" msgid "Post to Github issue needs to sign in your Github account" msgstr "Размещение в GitHub. Выпуск должен войти в свою учетную запись GitHub" msgid "Status Info" msgstr "Информация о статусе" msgid "" "-----------%0AProblem Description:%0APlease describe your problem, running " "logs may be needed.%0A%0A-----------%0ADiagnostic information:%0A" msgstr "" "-----------%0a Описание проблемы:%0a, пожалуйста, опишите свою проблему, " "необходимы журналы.%0a%0a -----------%0a Диагностическая информация:%0A" msgid "disable" msgstr "запрещать" msgid "idle" msgstr "праздный" msgid "working" msgstr "работающий" msgid "The status page is empty. Highly likely that " msgstr "Страница статуса пуста.Весьма вероятно, что" msgid " failed getting started. Please follow " msgstr "Не удалось начать.Пожалуйста, следуйте" msgid "guide" msgstr "гид" msgid " to troubleshoot." msgstr "Устранение неполадок." msgid "Your local network failed, please check your network and firewall." msgstr "" "Ваша локальная сеть потерпела неудачу, пожалуйста, проверьте свою сеть и " "брандмауэр." msgid "Force-IPv6" msgstr "Force-Ipv6" msgid " not available, Please check." msgstr "Недоступно, пожалуйста, проверьте." msgid "Force-IPv4" msgstr "Force-Ipv4" msgid "You may want to $1turn on IP scaner$2." msgstr "Вы можете захотеть провести 1 доллар на IP Scanner $ 2." msgid "" "You can try turn on IPv6 or use X-Tunnel." msgstr "" "Вы можете попробовать включить ipv6 или x-tunnel ." msgid "XX-Net is scanning IP. Please wait about half an hour." msgstr "XX-сеть-это сканирование IP.Пожалуйста, подождите около получаса." msgid "" "Public AppID out of quota, Please deploy your own " "AppID." msgstr "" "Публичная приложение из квоты, пожалуйста, развернуть свой" " собственный Appid." msgid "" "Your AppID out of quota, Please deploy more AppID." msgstr "" "Ваша приложение из квоты, пожалуйста, развернуть " "более аппликацию ." msgid "No working AppID. Please check." msgstr "Нет рабочей Аппид.Пожалуйста, проверьте." msgid "System is Idle." msgstr "Система бездействует." msgid "Connection not established yet." msgstr "Соединение еще не установлено." msgid "Please check your browser proxy setting." msgstr "Пожалуйста, проверьте настройку прокси браузера." msgid "Detecting ..." msgstr "Обнаружение ..." msgid "Please import certificates to your browser." msgstr "Пожалуйста, импортируйте сертификаты в ваш браузер." msgid "" "You are using public AppIDs. You are recommended to deploy your own AppID." msgstr "" "Вы используете публичные приставки.Вас рекомендуется развернуть свое собственное Appid ." msgid ", Everything is OK. Welcome to the FREE Internet." msgstr ", Все в порядке.Добро пожаловать в бесплатный интернет." msgid "No response from process: " msgstr "Нет ответа от процесса:" msgid ". It might have already exited." msgstr "ПолемЭто могло бы уже выйти." msgid "Global PAC Proxy set" msgstr "Global PAC Proxy Set" msgid "Global GAEProxy Proxy set" msgstr "Глобальный набор GaeProxy Proxy" msgid "Global X-Tunnel Proxy set" msgstr "Глобальный набор прокси X-Tunnel" msgid "Global Smart-Router Proxy set" msgstr "Глобальный набор прокси-карт с интеллектуальными маркировками" msgid "Global Proxy disabled" msgstr "Global Proxy отключен" ================================================ FILE: code/default/launcher/lang/zh_CN/LC_MESSAGES/messages.po ================================================ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: xxnet.dev@gmail.com\n" "POT-Creation-Date: 2022-02-25 02:08-0500\n" "PO-Revision-Date: 2017-12-29 12:00+0800\n" "Last-Translator: Emphasia@github\n" "Language: zh_Hans_CN\n" "Language-Team: zh_Hans_CN \n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.14.0\n" msgid "Hello!" msgstr "您好!" msgid "You seem to be on your first visit." msgstr "您似乎是初次到访。" msgid "Learn more" msgstr "了解更多" msgid "Notice" msgstr "公告" msgid "click to view" msgstr "点击查看" msgid "Version" msgstr "版本" msgid "Project main page" msgstr "项目主页" msgid "Official Web Site" msgstr "官网" msgid "Telegram group" msgstr "电报群" msgid "Telegram Channel" msgstr "电报频道" msgid "Bug feedback" msgstr "问题反馈" msgid "When submitting a bug, please attach " msgstr "报告问题时, 请附上" msgid "the status page " msgstr "状态页" msgid "info and " msgstr "信息和" msgid "the log page " msgstr "日志页" msgid "contents" msgstr "内容" msgid "Collect debug info" msgstr "收集调试信息" msgid "Download" msgstr "下载" msgid "Thanks to the following projects" msgstr "感谢以下项目" msgid "About" msgstr "关于" msgid "General Settings" msgstr "通用" msgid "System Version" msgstr "版本" msgid "LAN Proxy Setting" msgstr "前置代理" msgid "App List" msgstr "应用列表" msgid "System Configuration" msgstr "系统配置 " msgid "Configuring the service[%s]. This page will refresh within %s seconds." msgstr "正在配置服务 [%s], 页面将在 %s 秒后刷新。" msgid "GAE Proxy" msgstr "GAE前置代理" msgid "X-Tunnel" msgstr "" msgid "Smart Router" msgstr "智能路由" msgid "Proxy by APP" msgstr "选择要代理的APP" msgid "" "Select which APP should be proxied. You need to restart VPN after change " "this." msgstr "选择应该代理哪个APP。 更改此设置后,您需要重新启动 VPN。" msgid "Select All" msgstr "全选 " msgid "Save" msgstr "保存" msgid "Settings saved successfully, Please restart VPN." msgstr "设置保存成功,请重启VPN" msgid "Failed saving settings: " msgstr "保存配置失败:" msgid "Failed saving settings." msgstr "保存配置失败。" msgid "Language" msgstr "语言" msgid "Auto-Startup" msgstr "开机自动启动" msgid "Popup Status Page on Startup" msgstr "启动时弹出状态页" msgid "Allow Remote" msgstr "允许远程访问" msgid "Help" msgstr "帮助" msgid "Display System Tray(Restarting APP Required)" msgstr "显示托盘图标(需要重启代理)" msgid "Display Notification" msgstr "显示通知" msgid "Display Windows software compatibility suggestions" msgstr "显示 Windows 软件兼容性建议" msgid "Feedback" msgstr "反馈" msgid "Run as Green Software" msgstr "以绿色方式运行" msgid "Module management" msgstr "模块管理" msgid "Enable" msgstr "启用" msgid "Restarting all remote, wait to refresh." msgstr "正在重启所有远程程序,请等待刷新。" msgid "Auto-Upgrade to" msgstr "自动升级到" msgid "Do not upgrade" msgstr "不升级" msgid "Notice stable version" msgstr "通知稳定版" msgid "Stable version" msgstr "稳定版" msgid "Notice test version" msgstr "通知测试版" msgid "Test version" msgstr "测试版" msgid "Check the latest version" msgstr "检查最新版本" msgid "Current version" msgstr "当前版本" msgid "Version of the test one" msgstr "测试版" msgid "Update now" msgstr "立即更新" msgid "Version of the stable one" msgstr "稳定版" msgid "Keep old versions count" msgstr "保留的旧版本数" msgid "keep all" msgstr "保留全部" msgid "Manually Manage" msgstr "手动管理" msgid "Advanced" msgstr "高级" msgid "All versions download page" msgstr "全部已发布版本" msgid "Released version" msgstr "发布版本" msgid "Released" msgstr "发布的" msgid "Download & Change to" msgstr "下载并切至" msgid "no hash check" msgstr "不校验" msgid "Local version" msgstr "本地版本" msgid "Local" msgstr "本地的" msgid "Change to this version" msgstr "切至此版本" msgid "Delete" msgstr "删除此版本" msgid "Settings saved successfully." msgstr "保存设置成功。" msgid "Settings save fail:" msgstr "保存设置失败:" msgid "Deleted successfully." msgstr "删除成功。" msgid "Deleting local version fail." msgstr "删除本地版本失败。" msgid "Failed getting local versions." msgstr "获取本地版本失败。" msgid "Failed getting released versions." msgstr "获取发布版本失败。" msgid "(Remote Web Control Enabled)" msgstr "(已允许远程访问)" msgid "Adaptive width" msgstr "自适应宽度" msgid "Exit" msgstr "退出" msgid "Menu" msgstr "菜单" msgid "Remind me later" msgstr "以后再提醒我" msgid "Do not remind me this version" msgstr "忽略此版本" msgid "View changes" msgstr "显示变动" msgid "Exited successfully." msgstr "退出成功。" msgid "Exitting failed." msgstr "退出失败。" msgid "Exitting failed. A network error occurred." msgstr "退出失败,遇到网络错误。" msgid "new to this version?" msgstr "第一次使用此版本?" msgid "Unkown error occured. Please refresh the page and try again." msgstr "发生未知错误,请刷新页面重试。" msgid "Updating in progress ..." msgstr "更新进行中..." msgid "New " msgstr "新" msgid "Finished." msgstr "" msgid "Downloading ..." msgstr "下载中..." msgid "Download completed." msgstr "下载完成。" msgid "Info" msgstr "信息和" msgid "System" msgstr "系统" msgid "Log" msgstr "日志" msgid "Your browser is obsolete. Partial functionality will not be available." msgstr "您的浏览器版本过低, 部分功能将无法使用。" msgid "The latest Chrome browser is recommended." msgstr "建议您使用最新版本的 Chrome 浏览器。" msgid "Search" msgstr "搜索" msgid "Search all issues" msgstr "在 issue 中搜索(支持 GitHub issue 搜索参数)" msgid "Status" msgstr "状态" msgid "Property" msgstr "属性" msgid "Value" msgstr "值" msgid "Browser Proxy Setting" msgstr "浏览器代理设置" msgid "CA status" msgstr "CA 证书状态" msgid "System Proxy" msgstr "系统代理" msgid "Modules" msgstr "模块" msgid "Launcher Web UI" msgstr "Web 控制页" msgid "LAN proxy" msgstr "前置代理" msgid "System Info" msgstr "系统信息" msgid "Diagnostic Info" msgstr "诊断信息" msgid "Check" msgstr "查看" msgid "GitHub issues" msgstr "GitHub 问题讨论区" msgid "or" msgstr "或" msgid "Google Group Discussions" msgstr "Google Group 讨论组" msgid "Show Details" msgstr "显示详细信息" msgid "Post to Github issue needs to sign in your Github account" msgstr "贴到 GitHub 问题区需要登录 GitHub 账号" msgid "Status Info" msgstr " 状态信息" msgid "" "-----------%0AProblem Description:%0APlease describe your problem, " "running logs may be needed.%0A%0A-----------%0ADiagnostic information:%0A" msgstr "-----------%0A问题描述:%0A请在此描述你遇到的问题,必要时贴出相关的日志信息。%0A%0A-----------%0A诊断信息:%0A" msgid "disable" msgstr "禁用" msgid "idle" msgstr "空闲" msgid "working" msgstr "工作" msgid "The status page is empty. Highly likely that " msgstr "状态页显示空白, 很可能 " msgid " failed getting started. Please follow " msgstr " 启动失败, 请按 " msgid "guide" msgstr "指导" msgid " to troubleshoot." msgstr "去解决。" msgid "Your local network failed, please check your network and firewall." msgstr "网络无法连接,请检查网络和防火墙设置。" msgid "Force-IPv6" msgstr "仅 IPv6" msgid " not available, Please check." msgstr " 不可用,请检查。" msgid "Force-IPv4" msgstr "仅 IPv4" msgid "You may want to $1turn on IP scaner$2." msgstr "您应该考虑$1开启 IP 扫描器$2。" msgid "" "You can try turn on IPv6 or use X-Tunnel." msgstr "" "你可以尝试 开启 IPv6使用X-Tunnel。" msgid "XX-Net is scanning IP. Please wait about half an hour." msgstr "等待扫描IP,建议开启 IPv6。" msgid "" "Public AppID out of quota, Please deploy your own " "AppID." msgstr "" "公共 AppID 配额已用完,请部署私有 AppID。" msgid "" "Your AppID out of quota, Please deploy more " "AppID." msgstr "" "您的 AppID 流量已用完,请部署更多 AppID。" msgid "No working AppID. Please check." msgstr "没有可用 AppID,请检查。" msgid "System is Idle." msgstr "系统空闲。" msgid "Connection not established yet." msgstr "连接尚未建立。" msgid "Please check your browser proxy setting." msgstr "请检查浏览器代理设置。" msgid "Detecting ..." msgstr "正在自检..." msgid "Please import certificates to your browser." msgstr "请导入浏览器 CA 证书。" msgid "" "You are using public AppIDs. You are recommended to deploy your own AppID." msgstr "" "您正在使用公共 AppID,因为资源有限,使用上存在限制,建议部署私有 AppID。" msgid ", Everything is OK. Welcome to the FREE Internet." msgstr ",一切正常,你可以访问真正的互联网了。" msgid "No response from process: " msgstr "进程:" msgid ". It might have already exited." msgstr " 无响应, 可能已退出。" msgid "Global PAC Proxy set" msgstr "全局 PAC 代理" msgid "Global GAEProxy Proxy set" msgstr "全局 GAEProxy 代理" msgid "Global X-Tunnel Proxy set" msgstr "全局 X-Tunnel 代理" msgid "Global Smart-Router Proxy set" msgstr "全局 Smart-Router 代理" msgid "Global Proxy disabled" msgstr "全局代理禁用" ================================================ FILE: code/default/launcher/mac_helper.c ================================================ #include #include #include int main(int argc, const char * argv[]) { if (geteuid() != 0) { fprintf(stderr, "Must be run as root!\n"); return 1; } if (argc == 4 && strcmp(argv[1], "enableauto") == 0) { execl("/usr/sbin/networksetup", "networksetup", "-setautoproxyurl", argv[2], argv[3], NULL); } else if (argc == 5 && strcmp(argv[1], "enablehttp") == 0) { execl("/usr/sbin/networksetup", "networksetup", "-setwebproxy", argv[2], argv[3], argv[4], NULL); } else if (argc == 5 && strcmp(argv[1], "enablehttps") == 0) { execl("/usr/sbin/networksetup", "networksetup", "-setsecurewebproxy", argv[2], argv[3], argv[4], NULL); } else if (argc == 3 && strcmp(argv[1], "disableauto") == 0) { execl("/usr/sbin/networksetup", "networksetup", "-setautoproxystate", argv[2], "off", NULL); } else if (argc == 3 && strcmp(argv[1], "disablehttp") == 0) { execl("/usr/sbin/networksetup", "networksetup", "-setwebproxystate", argv[2], "off", NULL); } else if (argc == 3 && strcmp(argv[1], "disablehttps") == 0) { execl("/usr/sbin/networksetup", "networksetup", "-setsecurewebproxystate", argv[2], "off", NULL); } else { fprintf(stderr, "Usage:\n"); fprintf(stderr, "%s enableauto \n", argv[0]); fprintf(stderr, "%s enablehttp \n", argv[0]); fprintf(stderr, "%s enablehttps \n", argv[0]); fprintf(stderr, "%s disableauto \n", argv[0]); fprintf(stderr, "%s disablehttp \n", argv[0]); fprintf(stderr, "%s disablehttps \n", argv[0]); } return 0; } ================================================ FILE: code/default/launcher/mac_tray.py ================================================ #!/usr/bin/env python3 # coding:utf-8 import os import shutil import sys current_path = os.path.dirname(os.path.abspath(__file__)) helper_path = os.path.join('/tmp', 'helper') if __name__ == "__main__": default_path = os.path.abspath(os.path.join(current_path, os.pardir)) noarch_lib = os.path.abspath(os.path.join(default_path, 'lib', 'noarch')) sys.path.append(noarch_lib) osx_lib = os.path.join(default_path, 'lib', 'darwin') sys.path.append(osx_lib) extra_lib = "/System/Library/Frameworks/Python.framework/Versions/3.8/Extras/lib/python/PyObjC" sys.path.append(extra_lib) from config import config, app_name import module_init import subprocess import webbrowser from xlog import getLogger xlog = getLogger("launcher") import AppKit import SystemConfiguration from PyObjCTools import AppHelper class MacTrayObject(AppKit.NSObject): def __init__(self): pass def applicationDidFinishLaunching_(self, notification): setupHelper() loadConfig() self.setupUI() self.registerObserver() def setupUI(self): self.autoGaeProxyMenuItem = None self.globalGaeProxyMenuItem = None self.globalXTunnelMenuItem = None self.globalSmartRouterMenuItem = None self.statusbar = AppKit.NSStatusBar.systemStatusBar() self.statusitem = self.statusbar.statusItemWithLength_( AppKit.NSSquareStatusItemLength) # NSSquareStatusItemLength #NSVariableStatusItemLength # Set initial image icon icon_path = os.path.join(current_path, "web_ui", "img", app_name, "favicon-mac.ico") image = AppKit.NSImage.alloc().initByReferencingFile_(icon_path) image.setScalesWhenResized_(True) image.setSize_((20, 20)) self.statusitem.setImage_(image) # Let it highlight upon clicking self.statusitem.setHighlightMode_(1) self.statusitem.setToolTip_(app_name) # Get current selected mode proxyState = getProxyState(currentService) # Build a very simple menu self.menu = AppKit.NSMenu.alloc().initWithTitle_(app_name) menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Config', 'config:', '') self.menu.addItem_(menuitem) menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(getCurrentServiceMenuItemTitle(), None, '') self.menu.addItem_(menuitem) self.currentServiceMenuItem = menuitem if config.enable_gae_proxy == 1: menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Enable Auto GAEProxy', 'enableAutoProxy:', '') if proxyState == 'pac': menuitem.setState_(AppKit.NSOnState) self.menu.addItem_(menuitem) self.autoGaeProxyMenuItem = menuitem menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Enable Global GAEProxy', 'enableGlobalProxy:', '') if proxyState == 'gae': menuitem.setState_(AppKit.NSOnState) self.menu.addItem_(menuitem) self.globalGaeProxyMenuItem = menuitem if config.enable_x_tunnel == 1: menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Enable Global X-Tunnel', 'enableGlobalXTunnel:', '') if proxyState == 'x_tunnel': menuitem.setState_(AppKit.NSOnState) self.menu.addItem_(menuitem) self.globalXTunnelMenuItem = menuitem if config.enable_smart_router == 1: menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Enable Global Smart-Router', 'enableGlobalSmartRouter:', '') if proxyState == 'smart_router': menuitem.setState_(AppKit.NSOnState) self.menu.addItem_(menuitem) self.globalSmartRouterMenuItem = menuitem menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Disable Proxy', 'disableProxy:', '') if proxyState == 'disable': menuitem.setState_(AppKit.NSOnState) self.menu.addItem_(menuitem) self.disableGaeProxyMenuItem = menuitem # Reset Menu Item menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Reset Each Module', 'restartEachModule:', '') self.menu.addItem_(menuitem) # Default event menuitem = AppKit.NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Quit', 'windowWillClose:', '') self.menu.addItem_(menuitem) # Bind it to the status item self.statusitem.setMenu_(self.menu) # Hide dock icon AppKit.NSApp.setActivationPolicy_(AppKit.NSApplicationActivationPolicyProhibited) def updateStatusBarMenu(self): self.currentServiceMenuItem.setTitle_(getCurrentServiceMenuItemTitle()) # Remove Tick before All Menu Items if self.autoGaeProxyMenuItem: self.autoGaeProxyMenuItem.setState_(AppKit.NSOffState) if self.globalGaeProxyMenuItem: self.globalGaeProxyMenuItem.setState_(AppKit.NSOffState) if self.globalXTunnelMenuItem: self.globalXTunnelMenuItem.setState_(AppKit.NSOffState) if self.globalSmartRouterMenuItem: self.globalSmartRouterMenuItem.setState_(AppKit.NSOffState) self.disableGaeProxyMenuItem.setState_(AppKit.NSOffState) # Get current selected mode proxyState = getProxyState(currentService) # Update Tick before Menu Item if proxyState == 'pac' and self.autoGaeProxyMenuItem: self.autoGaeProxyMenuItem.setState_(AppKit.NSOnState) elif proxyState == 'gae' and self.globalGaeProxyMenuItem: self.globalGaeProxyMenuItem.setState_(AppKit.NSOnState) elif proxyState == 'x_tunnel' and self.globalXTunnelMenuItem: self.globalXTunnelMenuItem.setState_(AppKit.NSOnState) elif proxyState == 'smart_router' and self.globalSmartRouterMenuItem: self.globalSmartRouterMenuItem.setState_(AppKit.NSOnState) else: self.disableGaeProxyMenuItem.setState_(AppKit.NSOnState) # Trigger autovalidation self.menu.update() def validateMenuItem_(self, menuItem): return currentService or (menuItem != self.autoGaeProxyMenuItem and menuItem != self.globalGaeProxyMenuItem and menuItem != self.globalXTunnelMenuItem and menuItem != self.globalSmartRouterMenuItem and menuItem != self.disableGaeProxyMenuItem) def presentAlert_withTitle_(self, msg, title): self.performSelectorOnMainThread_withObject_waitUntilDone_('presentAlertWithInfo:', [title, msg], True) return self.alertReturn def presentAlertWithInfo_(self, info): alert = AppKit.NSAlert.alloc().init() alert.setMessageText_(info[0]) alert.setInformativeText_(info[1]) alert.addButtonWithTitle_("OK") alert.addButtonWithTitle_("Cancel") self.alertReturn = alert.runModal() == AppKit.NSAlertFirstButtonReturn def registerObserver(self): nc = AppKit.NSWorkspace.sharedWorkspace().notificationCenter() nc.addObserver_selector_name_object_(self, 'windowWillClose:', AppKit.NSWorkspaceWillPowerOffNotification, None) def windowWillClose_(self, notification): executeResult = subprocess.check_output(['networksetup', '-listallnetworkservices']) services = executeResult.split(b'\n') services = [service for service in services if service and service.find(b'*') == -1 and getProxyState( service) != 'disable'] # Remove disabled services and empty lines if len(services) > 0: self.disableProxy_(True) module_init.stop_all() os._exit(0) AppKit.NSApp.terminate_(self) def config_(self, notification): host_port = config.control_port webbrowser.open_new("http://127.0.0.1:%s/" % host_port) def restartEachModule_(self, _): module_init.stop_all() module_init.start_all_auto() def enableAutoProxy_(self, _): try: helperDisableGlobalProxy(currentService) helperEnableAutoProxy(currentService) except: disableGlobalProxyCommand = getDisableGlobalProxyCommand(currentService) enableAutoProxyCommand = getEnableAutoProxyCommand(currentService) executeCommand = 'do shell script "%s;%s" with administrator privileges' % ( disableGlobalProxyCommand, enableAutoProxyCommand) xlog.info("try enable auto proxy:%s", executeCommand) subprocess.call(['osascript', '-e', executeCommand]) config.os_proxy_mode = "pac" config.save() self.updateStatusBarMenu() def enableGlobalProxy_(self, _): try: helperDisableAutoProxy(currentService) helperEnableGlobalProxy(currentService) except: disableAutoProxyCommand = getDisableAutoProxyCommand(currentService) enableGlobalProxyCommand = getEnableGlobalProxyCommand(currentService) executeCommand = 'do shell script "%s;%s" with administrator privileges' % ( disableAutoProxyCommand, enableGlobalProxyCommand) xlog.info("try enable global proxy:%s", executeCommand) subprocess.call(['osascript', '-e', executeCommand]) config.os_proxy_mode = "gae" config.save() self.updateStatusBarMenu() def enableGlobalXTunnel_(self, _): try: helperDisableAutoProxy(currentService) helperEnableXTunnelProxy(currentService) except: disableAutoProxyCommand = getDisableAutoProxyCommand(currentService) enableXTunnelProxyCommand = getEnableXTunnelProxyCommand(currentService) executeCommand = 'do shell script "%s;%s" with administrator privileges' % ( disableAutoProxyCommand, enableXTunnelProxyCommand) xlog.info("try enable global x-tunnel proxy:%s", executeCommand) subprocess.call(['osascript', '-e', executeCommand]) config.os_proxy_mode = "x_tunnel" config.save() self.updateStatusBarMenu() def enableGlobalSmartRouter_(self, _): try: helperDisableAutoProxy(currentService) helperEnableSmartRouterProxy(currentService) except: disableAutoProxyCommand = getDisableAutoProxyCommand(currentService) enableSmartRouterCommand = getEnableSmartRouterProxyCommand(currentService) executeCommand = 'do shell script "%s;%s" with administrator privileges' % ( disableAutoProxyCommand, enableSmartRouterCommand) xlog.info("try enable global smart-router proxy:%s", executeCommand) subprocess.call(['osascript', '-e', executeCommand]) config.os_proxy_mode = "smart_router" config.save() self.updateStatusBarMenu() def disableProxy_(self, is_quit=False): try: helperDisableAutoProxy(currentService) helperDisableGlobalProxy(currentService) except: disableAutoProxyCommand = getDisableAutoProxyCommand(currentService) disableGlobalProxyCommand = getDisableGlobalProxyCommand(currentService) executeCommand = 'do shell script "%s;%s" with administrator privileges' % ( disableAutoProxyCommand, disableGlobalProxyCommand) xlog.info("try disable proxy:%s", executeCommand) subprocess.call(['osascript', '-e', executeCommand]) if is_quit != True: # in case "Disable proxy" trigger by menu, is_quit will be a {NSMenuItem} config.os_proxy_mode = "disable" config.save() self.updateStatusBarMenu() def setupHelper(): try: with open(os.devnull) as devnull: subprocess.check_call(helper_path, stderr=devnull) except: if os.path.exists(helper_path): os.remove(helper_path) shutil.copyfile(os.path.join(current_path, 'mac_helper'), helper_path) chownCommand = "chown root \\\"%s\\\"" % helper_path chmodCommand = "chmod 4755 \\\"%s\\\"" % helper_path executeCommand = 'do shell script "%s;%s" with administrator privileges' % ( chownCommand, chmodCommand ) xlog.info("try setup helper:%s", executeCommand) subprocess.call(['osascript', '-e', executeCommand]) def getCurrentServiceMenuItemTitle(): if currentService: return 'Connection: %s' % currentService else: return 'Connection: None' def getProxyState(service): if not service: return # Check if auto proxy is enabled executeResult = subprocess.check_output(['networksetup', '-getautoproxyurl', service]) if (executeResult.find(b'http://127.0.0.1:8086/proxy.pac\nEnabled: Yes') != -1): return "pac" # Check if global proxy is enabled executeResult = subprocess.check_output(['networksetup', '-getwebproxy', service]) if (executeResult.find(b'Enabled: Yes\nServer: 127.0.0.1\nPort: 8087') != -1): return "gae" # Check if global proxy is enabled if (executeResult.find(b'Enabled: Yes\nServer: 127.0.0.1\nPort: 1080') != -1): return "x_tunnel" if (executeResult.find(b'Enabled: Yes\nServer: 127.0.0.1\nPort: 8086') != -1): return "smart_router" return "disable" # Generate commands for Apple Script def getEnableAutoProxyCommand(service): return "networksetup -setautoproxyurl \\\"%s\\\" \\\"http://127.0.0.1:8086/proxy.pac\\\"" % service def getDisableAutoProxyCommand(service): return "networksetup -setautoproxystate \\\"%s\\\" off" % service def getEnableGlobalProxyCommand(service): enableHttpProxyCommand = "networksetup -setwebproxy \\\"%s\\\" 127.0.0.1 8087" % service enableHttpsProxyCommand = "networksetup -setsecurewebproxy \\\"%s\\\" 127.0.0.1 8087" % service return "%s;%s" % (enableHttpProxyCommand, enableHttpsProxyCommand) def getEnableXTunnelProxyCommand(service): enableHttpProxyCommand = "networksetup -setwebproxy \\\"%s\\\" 127.0.0.1 1080" % service enableHttpsProxyCommand = "networksetup -setsecurewebproxy \\\"%s\\\" 127.0.0.1 1080" % service return "%s;%s" % (enableHttpProxyCommand, enableHttpsProxyCommand) def getEnableSmartRouterProxyCommand(service): enableHttpProxyCommand = "networksetup -setwebproxy \\\"%s\\\" 127.0.0.1 8086" % service enableHttpsProxyCommand = "networksetup -setsecurewebproxy \\\"%s\\\" 127.0.0.1 8086" % service return "%s;%s" % (enableHttpProxyCommand, enableHttpsProxyCommand) def getDisableGlobalProxyCommand(service): disableHttpProxyCommand = "networksetup -setwebproxystate \\\"%s\\\" off" % service disableHttpsProxyCommand = "networksetup -setsecurewebproxystate \\\"%s\\\" off" % service return "%s;%s" % (disableHttpProxyCommand, disableHttpsProxyCommand) # Call helper def helperEnableAutoProxy(service): subprocess.check_call([helper_path, 'enableauto', service, 'http://127.0.0.1:8086/proxy.pac']) def helperDisableAutoProxy(service): subprocess.check_call([helper_path, 'disableauto', service]) def helperEnableGlobalProxy(service): subprocess.check_call([helper_path, 'enablehttp', service, '127.0.0.1', '8087']) subprocess.check_call([helper_path, 'enablehttps', service, '127.0.0.1', '8087']) def helperEnableXTunnelProxy(service): subprocess.check_call([helper_path, 'enablehttp', service, '127.0.0.1', '1080']) subprocess.check_call([helper_path, 'enablehttps', service, '127.0.0.1', '1080']) def helperEnableSmartRouterProxy(service): subprocess.check_call([helper_path, 'enablehttp', service, '127.0.0.1', '8086']) subprocess.check_call([helper_path, 'enablehttps', service, '127.0.0.1', '8086']) def helperDisableGlobalProxy(service): subprocess.check_call([helper_path, 'disablehttp', service]) subprocess.check_call([helper_path, 'disablehttps', service]) def loadConfig(): if not currentService: return proxy_setting = config.os_proxy_mode if getProxyState(currentService) == proxy_setting: return try: if proxy_setting == "pac" and config.enable_smart_router: helperDisableGlobalProxy(currentService) helperEnableAutoProxy(currentService) elif proxy_setting == "gae" and config.enable_gae_proxy: helperDisableAutoProxy(currentService) helperEnableGlobalProxy(currentService) elif proxy_setting == "x_tunnel" and config.enable_x_tunnel: helperDisableAutoProxy(currentService) helperEnableXTunnelProxy(currentService) elif proxy_setting == "smart_router" and config.enable_smart_router: helperDisableAutoProxy(currentService) helperEnableSmartRouterProxy(currentService) else: helperDisableAutoProxy(currentService) helperDisableGlobalProxy(currentService) # else: # xlog.warn("proxy_setting:%r", proxy_setting) except Exception as e: xlog.warn("helper failed:%r, please manually reset proxy settings after switching connection", e) sys_tray = MacTrayObject.alloc().init() currentService = None def fetchCurrentService(protocol): global currentService status = SystemConfiguration.SCDynamicStoreCopyValue(None, "State:/Network/Global/" + protocol) if not status: currentService = None return serviceID = status['PrimaryService'] service = SystemConfiguration.SCDynamicStoreCopyValue(None, "Setup:/Network/Service/" + serviceID) if not service: currentService = None return currentService = service['UserDefinedName'] @AppKit.objc.callbackFor(AppKit.CFNotificationCenterAddObserver) def networkChanged(center, observer, name, object, userInfo): fetchCurrentService('IPv4') loadConfig() sys_tray.updateStatusBarMenu() # Note: the following code can't run in class def serve_forever(): app = AppKit.NSApplication.sharedApplication() app.setDelegate_(sys_tray) # Listen for network change nc = AppKit.CFNotificationCenterGetDarwinNotifyCenter() AppKit.CFNotificationCenterAddObserver(nc, None, networkChanged, "com.apple.system.config.network_change", None, AppKit.CFNotificationSuspensionBehaviorDeliverImmediately) fetchCurrentService('IPv4') AppHelper.runEventLoop() def on_quit(widget=None, data=None): # helperDisableAutoProxy(currentService) # helperDisableGlobalProxy(currentService) sys_tray.windowWillClose_(None) def main(): serve_forever() if __name__ == '__main__': main() ================================================ FILE: code/default/launcher/module_init.py ================================================ import subprocess import threading import os import sys from config import config from xlog import getLogger xlog = getLogger("launcher") import web_control import time proc_handler = {} xargs = {} current_path = os.path.dirname(os.path.abspath(__file__)) root_path = os.path.abspath(os.path.join(current_path, os.pardir)) if root_path not in sys.path: sys.path.append(root_path) import env_info data_launcher_path = os.path.join(env_info.data_path, 'launcher') running_file = os.path.join(data_launcher_path, "Running.Lck") def start(module): if module == "all": modules = ["gae_proxy", "smart_router", "x_tunnel"] for m in modules: if not getattr(config,"enable_" + m): continue start(m) return elif not os.path.isdir(os.path.join(root_path, module)): return try: if module not in config.all_modules: xlog.error("module not exist %s", module) raise Exception() if module in proc_handler: xlog.error("module %s is running", module) return "module is running" if module not in proc_handler: proc_handler[module] = {} if os.path.isfile(os.path.join(root_path, module, "__init__.py")): if "imp" not in proc_handler[module]: proc_handler[module]["imp"] = __import__(module, globals(), locals(), ['local'], 0) _local = proc_handler[module]["imp"].local p = threading.Thread(target=_local.start, args=([xargs]), name="%s_start" % module) p.daemon = True p.start() proc_handler[module]["proc"] = p while not _local.is_ready(): time.sleep(0.1) else: script_path = os.path.join(root_path, module, 'start.py') if not os.path.isfile(script_path): xlog.warn("start module script not exist:%s", script_path) return "fail" proc_handler[module]["proc"] = subprocess.Popen([sys.executable, script_path], shell=False) xlog.info("module %s started", module) except Exception as e: xlog.exception("start module %s fail:%s", module, e) raise return "start success." def stop(module): try: if module == "all": modules = list(proc_handler) for m in modules: stop(m) return elif module not in proc_handler: xlog.error("module %s not running", module) return if os.path.isfile(os.path.join(root_path, module, "__init__.py")): _local = proc_handler[module]["imp"].local xlog.debug("start to terminate %s module", module) _local.stop() xlog.debug("module %s stopping", module) while _local.is_ready(): time.sleep(0.1) else: proc_handler[module]["proc"].terminate() # Sends SIGTERM proc_handler[module]["proc"].wait() del proc_handler[module] xlog.info("module %s stopped", module) except Exception as e: xlog.exception("stop module %s fail:%s", module, e) return "Except:%s" % e return "stop success." def call_each_module(api_name, args): for module in proc_handler: try: apis = proc_handler[module]["imp"].local.apis if not hasattr(apis, api_name): continue api = getattr(apis, api_name) api(args) except Exception as e: xlog.exception("call %s api:%s, except:%r", module, api_name, e) def start_all_auto(): global running_file if not os.path.isfile(running_file): open(running_file, 'a').close() for module in config.all_modules: if module in ["launcher"]: continue if not os.path.isdir(os.path.join(root_path, module)): continue if getattr(config, "enable_" + module): start_time = time.time() start(module) # web_control.confirm_module_ready(config.get(["modules", module, "control_port"], 0)) finished_time = time.time() xlog.info("start %s time cost:%d ms", module, (finished_time - start_time) * 1000) def stop_all(): global running_file running_modules = [k for k in proc_handler] for module in running_modules: stop(module) try: os.remove(running_file) except: pass ================================================ FILE: code/default/launcher/non_tray.py ================================================ #!/usr/bin/env python # coding:utf-8 import os import time import global_var class None_tray(): def notify_general(self, msg="msg", title="Title", buttons={}, timeout=3600): pass def on_quit(self, widget=None, data=None): import module_init global_var.running = False module_init.stop_all() os._exit(0) def serve_forever(self): while global_var.running: time.sleep(10) sys_tray = None_tray() def main(): sys_tray.serve_forever() if __name__ == '__main__': main() ================================================ FILE: code/default/launcher/post_update.py ================================================ import os import shutil current_path = os.path.dirname(os.path.abspath(__file__)) root_path = os.path.abspath(os.path.join(current_path, os.pardir)) top_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir)) from xlog import getLogger xlog = getLogger("launcher") from config import config def check(): import update_from_github current_version = update_from_github.current_version() last_run_version = config.last_run_version if last_run_version == "0.0.0": postUpdateStat = "isNew" elif last_run_version != current_version: postUpdateStat = "isPostUpdate" run(last_run_version) else: return config.postUpdateStat = postUpdateStat config.last_run_version = current_version config.save() def run(last_run_version): if config.auto_start == 1: import autorun autorun.enable() if os.path.isdir(os.path.join(top_path, 'launcher')): shutil.rmtree(os.path.join(top_path, 'launcher')) # launcher is for auto-update from 2.X ================================================ FILE: code/default/launcher/setup.py ================================================ #!/usr/bin/env python from config import config import os import re import shutil import subprocess import sys import time import zipfile try: from urllib.request import build_opener, ProxyHandler except ImportError: from urllib2 import build_opener, ProxyHandler import env_info from xlog import getLogger xlog = getLogger("launcher") current_path = os.path.dirname(os.path.abspath(__file__)) python_path = os.path.abspath(os.path.join(current_path, os.pardir)) noarch_lib = os.path.abspath(os.path.join(python_path, 'lib', 'noarch')) sys.path.append(noarch_lib) opener = build_opener() root_path = os.path.abspath(os.path.join(current_path, os.pardir)) download_path = os.path.join(env_info.data_path, 'downloads') xxnet_unzip_path = "" def get_XXNet(): global xxnet_unzip_path def download_file(url, file): try: xlog.info("download %s to %s", url, file) req = opener.open(url) CHUNK = 16 * 1024 with open(file, 'wb') as fp: while True: chunk = req.read(CHUNK) if not chunk: break fp.write(chunk) return True except: xlog.info("download %s to %s fail", url, file) return False def get_xxnet_url_version(readme_file): try: fd = open(readme_file, "r") lines = fd.readlines() p = re.compile(r'https://codeload.github.com/XX-net/XX-Net/zip/([0-9]+)\.([0-9]+)\.([0-9]+)') for line in lines: m = p.match(line) if m: version = m.group(1) + "." + m.group(2) + "." + m.group(3) return m.group(0), version except Exception as e: xlog.exception("get version fail:%s", e) raise "get_version_fail:" % readme_file readme_url = "https://raw.githubusercontent.com/XX-net/XX-Net/master/README.md" readme_targe = os.path.join(download_path, "README.md") if not os.path.isdir(download_path): os.mkdir(download_path) if not download_file(readme_url, readme_targe): raise "get README fail:" + readme_url xxnet_url, xxnet_version = get_xxnet_url_version(readme_targe) xxnet_unzip_path = os.path.join(download_path, "XX-Net-%s" % xxnet_version) xxnet_zip_file = os.path.join(download_path, "XX-Net-%s.zip" % xxnet_version) if not download_file(xxnet_url, xxnet_zip_file): raise "download xxnet zip fail:" + download_path with zipfile.ZipFile(xxnet_zip_file, "r") as dz: dz.extractall(download_path) dz.close() def install_xxnet_files(): def sha1_file(filename): import hashlib BLOCKSIZE = 65536 hasher = hashlib.sha1() try: with open(filename, 'rb') as afile: buf = afile.read(BLOCKSIZE) while len(buf) > 0: hasher.update(buf) buf = afile.read(BLOCKSIZE) return hasher.hexdigest() except: return False pass for root, subdirs, files in os.walk(xxnet_unzip_path): # print("root:", root) relate_path = root[len(xxnet_unzip_path) + 1:] for subdir in subdirs: target_path = os.path.join(root_path, relate_path, subdir) if not os.path.isdir(target_path): xlog.info("mkdir %s", target_path) os.mkdir(target_path) for filename in files: if relate_path == os.path.join("data", "gae_proxy") and filename == "config.ini": continue if relate_path == os.path.join("data", "launcher") and filename == "config.yaml": continue src_file = os.path.join(root, filename) dst_file = os.path.join(root_path, relate_path, filename) if not os.path.isfile(dst_file) or sha1_file(src_file) != sha1_file(dst_file): shutil.copy(src_file, dst_file) xlog.info("copy %s => %s", src_file, dst_file) def update_environment(): get_XXNet() install_xxnet_files() def wait_xxnet_exit(): def http_request(url, method="GET"): proxy_handler = ProxyHandler({}) opener = build_opener(proxy_handler) try: req = opener.open(url) return req except Exception as e: # logging.exception("web_control http_request:%s fail:%s", url, e) return False for i in range(20): host_port = config.control_port req_url = "http://127.0.0.1:{port}/quit".format(port=host_port) if http_request(req_url) is False: return True time.sleep(1) return False def run_new_start_script(): current_path = os.path.dirname(os.path.abspath(__file__)) start_sript = os.path.abspath(os.path.join(current_path, "start.py")) subprocess.Popen([sys.executable, start_sript], shell=False) def main(): wait_xxnet_exit() update_environment() time.sleep(2) xlog.info("setup start run new launcher") run_new_start_script() if __name__ == "__main__": main() ================================================ FILE: code/default/launcher/simple_i18n.py ================================================ import os import sys import utils from config import get_language from xlog import getLogger xlog = getLogger("launcher") class SimpleI18N(object): def __init__(self): self.lang = get_language() xlog.debug("lang: %s", self.lang) self.base_po_dict = {} def add_translate(self, key, value): self.base_po_dict[key] = value @staticmethod def po_loader(file): if sys.version_info[0] == 2: fp = open(file, "r") else: fp = open(file, "rb") po_dict = {} while True: line = fp.readline() line = utils.to_bytes(line) if not line: break if len(line) < 2: continue if line.startswith(b"#"): continue if line.startswith(b"msgid "): key = line[7:-2] value = b"" while True: line = fp.readline() line = utils.to_bytes(line) if not line: break if line.startswith(b"\""): key += line[1:-2] elif line.startswith(b"msgstr "): value += line[8:-2] break else: break while True: line = fp.readline() line = utils.to_bytes(line) if not line: break if line.startswith(b"\""): value += line[1:-2] else: break if key == b"": continue po_dict[key] = value return po_dict def _render(self, po_dict, content): po_dict = utils.merge_two_dict(po_dict, self.base_po_dict) out_arr = [] cp = 0 while True: bp = content.find(b"{{", cp) if bp == -1: break ep = content.find(b"}}", bp) if ep == -1: # print((content[bp:])) break b1p = content.find(b"_(", bp, ep) if b1p == -1: # print((content[bp:])) continue b2p = content.find(b"\"", b1p + 2, b1p + 4) if b2p == -1: # print((content[bp:])) continue e1p = content.find(b")", ep - 2, ep) if e1p == -1: # print((content[bp:])) continue e2p = content.find(b"\"", e1p - 2, e1p) if e2p == -1: # print((content[bp:])) continue out_arr.append(content[cp:bp]) key = content[b2p + 1:e2p] if po_dict.get(key, b"") == b"": out_arr.append(key) else: out_arr.append(po_dict[key]) cp = ep + 2 out_arr.append(content[cp:]) return b"".join(out_arr) def render(self, lang_path, template_file): po_file = os.path.join(lang_path, self.lang, "LC_MESSAGES", "messages.po") if sys.version_info[0] == 2: fp = open(template_file, "r") content = fp.read() else: fp = open(template_file, "rb") content = fp.read() if not os.path.isfile(po_file): return self._render(dict(), content) else: po_dict = self.po_loader(po_file) return self._render(po_dict, content) def render_content(self, lang_path, content): po_file = os.path.join(lang_path, self.lang, "LC_MESSAGES", "messages.po") if not os.path.isfile(po_file): return self._render(dict(), content) else: po_dict = self.po_loader(po_file) return self._render(po_dict, content) ================================================ FILE: code/default/launcher/start.py ================================================ #!/usr/bin/env python3 # coding:utf-8 import platform import os import sys import time import traceback import atexit # reduce resource request for threading # for OpenWrt import threading try: threading.stack_size(64 * 1024) except: pass current_path = os.path.dirname(os.path.abspath(__file__)) sys.path.append(current_path) default_path = os.path.abspath(os.path.join(current_path, os.path.pardir)) noarch_lib = os.path.abspath(os.path.join(default_path, 'lib', 'noarch')) sys.path.append(noarch_lib) import env_info data_path = env_info.data_path data_launcher_path = os.path.join(data_path, 'launcher') def create_data_path(): if not os.path.isdir(data_path): os.mkdir(data_path) if not os.path.isdir(data_launcher_path): os.mkdir(data_launcher_path) data_gae_proxy_path = os.path.join(data_path, 'gae_proxy') if not os.path.isdir(data_gae_proxy_path): os.mkdir(data_gae_proxy_path) create_data_path() from xlog import getLogger log_file = os.path.join(data_launcher_path, "launcher.log") xlog = getLogger("launcher", log_path=data_launcher_path, save_start_log=500, save_warning_log=True) xlog.set_buffer(100) import sys_platform from config import config import web_control import module_init import update import update_from_github import download_modules import global_var current_version = update_from_github.current_version() xlog.info("start Version %s", current_version) xlog.info("Python version: %s", sys.version) xlog.info("System: %s|%s|%s", platform.system(), platform.version(), platform.architecture()) xlog.info("data path: %s", data_path) from front_base import openssl_wrap xlog.info("TLS implementation: %s", openssl_wrap.implementation) try: import OpenSSL except Exception as e2: print("import pyOpenSSL fail:", e2) running_file = os.path.join(data_launcher_path, "Running.Lck") def uncaught_exception_handler(etype, value, tb): if etype == KeyboardInterrupt: # Ctrl + C on console xlog.warn("KeyboardInterrupt, exiting...") global_var.running = False module_init.stop_all() os._exit(0) exc_info = ''.join(traceback.format_exception(etype, value, tb)) print(("uncaught Exception:\n" + exc_info)) xlog.error("uncaught Exception, type=%s value=%s traceback:%s", etype, value, exc_info) # sys.exit(1) sys.excepthook = uncaught_exception_handler def exit_handler(): xlog.info('Stopping all modules before exit!') global_var.running = False module_init.stop_all() web_control.stop() atexit.register(exit_handler) has_desktop = sys_platform.has_desktop def main(): # change path to launcher global __file__ __file__ = os.path.abspath(__file__) if os.path.islink(__file__): __file__ = getattr(os, 'readlink', lambda x: x)(__file__) os.chdir(os.path.dirname(os.path.abspath(__file__))) if sys.platform == "win32": import win_compat_suggest if config.show_compat_suggest: win_compat_suggest.main() ports_resolve_solution = win_compat_suggest.Win10PortReserveSolution() if not ports_resolve_solution.check_and_resolve(): return elif sys.platform == "darwin": import resource new_soft_limit = 4096 new_hard_limit = 4096 resource.setrlimit(resource.RLIMIT_NOFILE, (new_soft_limit, new_hard_limit)) xlog.info(f"New open file limits set to: Soft={new_soft_limit}, Hard={new_hard_limit}") web_control.confirm_xxnet_not_running() import post_update post_update.check() allow_remote = 0 no_mess_system = 0 no_popup = 0 no_systray = 0 if len(sys.argv) > 1: for s in sys.argv[1:]: xlog.info("command args:%s", s) if s == "-allow_remote": allow_remote = 1 elif s == "-no_mess_system": no_mess_system = 1 elif s == "-no_popup": no_popup = 1 elif s == "-no_systray": no_systray = 1 if allow_remote or config.allow_remote_connect: xlog.info("start with allow remote connect.") module_init.xargs["allow_remote"] = 1 if os.getenv("NOT_MESS_SYSTEM", "0") != "0" or no_mess_system or config.no_mess_system: xlog.info("start with no_mess_system, no CA will be imported to system, not create desktop.") module_init.xargs["no_mess_system"] = 1 update.should_create_desktop_shortcut = False if os.path.isfile(running_file): restart_from_except = True else: restart_from_except = False update.start() # put update before start all modules, generate uuid for x-tunnel. module_init.start_all_auto() web_control.start(allow_remote) if has_desktop and config.popup_webui == 1 and not restart_from_except and not no_popup: host_port = config.control_port import webbrowser url = "http://localhost:%s/" % host_port xlog.debug("Popup %s on startup", url) webbrowser.open(url) if has_desktop: download_modules.start_download() update_from_github.cleanup() if config.show_systray and not no_systray: sys_platform.show_systray() else: while global_var.running: time.sleep(10) try: main() except KeyboardInterrupt: # Ctrl + C on console global_var.running = False module_init.stop_all() os._exit(0) sys.exit() except Exception as e: xlog.exception("launcher except:%r", e) input("Press Enter to continue...") ================================================ FILE: code/default/launcher/sys_platform.py ================================================ import sys import os from xlog import getLogger xlog = getLogger("launcher") current_path = os.path.dirname(os.path.abspath(__file__)) default_path = os.path.abspath(os.path.join(current_path, os.pardir)) import global_var if sys.platform.startswith("linux"): if os.path.isfile("/system/bin/dalvikvm") or os.path.isfile("/system/bin/dalvikvm64") or \ "android.googlesource.com" in sys.version: xlog.info("This is Android") has_desktop = False platform = "android" platform_lib = "" def show_systray(): from non_tray import sys_tray sys_tray.serve_forever() def on_quit(): sys_tray.on_quit() else: def X_is_running(): try: from subprocess import Popen, PIPE p = Popen(["xset", "-q"], stdout=PIPE, stderr=PIPE) p.communicate() return p.returncode == 0 except: return False def has_gi(): try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk as gtk return True except Exception as e: xlog.warn("load gi fail:%r, SysTray will not show.", e) return False def has_pygtk(): try: import pygtk pygtk.require('2.0') import gtk return True except: return False platform = "linux" platform_lib = os.path.join(default_path, 'lib', 'linux') sys.path.append(platform_lib) if X_is_running() and (has_pygtk() or has_gi()): has_desktop = True else: has_desktop = False def show_systray(): global sys_tray if has_desktop: try: from gtk_tray import sys_tray except: from non_tray import sys_tray else: from non_tray import sys_tray sys_tray.serve_forever() def on_quit(): global sys_tray if has_desktop: from gtk_tray import sys_tray sys_tray.on_quit() elif sys.platform == "win32": has_desktop = True platform = "windows" platform_lib = os.path.join(default_path, 'lib', 'win32') sys.path.append(platform_lib) def show_systray(): from win_tray import sys_tray sys_tray.serve_forever() def on_quit(): from win_tray import sys_tray sys_tray.on_quit() elif sys.platform == "darwin": has_desktop = True platform = "mac" platform_lib = os.path.abspath(os.path.join(default_path, 'lib', 'darwin')) sys.path.append(platform_lib) extra_lib = "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjc" sys.path.append(extra_lib) def show_systray(): global sys_tray try: import mac_tray as sys_tray except Exception as e: xlog.warn("import mac_tray except:%r, Please try run 'sudo pip3 install -U PyObjC Pillow' by yourself.", e) from non_tray import sys_tray sys_tray.serve_forever() def on_quit(): global sys_tray sys_tray.on_quit() elif sys.platform == "ios": xlog.info("This is iOS") has_desktop = False platform = "ios" platform_lib = "" import time import gc gc.set_threshold(200, 12, 12) def show_systray(): while global_var.running: time.sleep(30) count = gc.get_count() c = gc.collect() xlog.debug("GC: count: %d,%d,%d Collect:%d", count[0], count[1], count[2], c) def on_quit(): from non_tray import sys_tray sys_tray.on_quit() else: xlog.warn(("detect platform fail:%s" % sys.platform)) platform = "unknown" has_desktop = False platform_lib = "" from non_tray import sys_tray def show_systray(): sys_tray.serve_forever() def on_quit(): sys_tray.on_quit() ================================================ FILE: code/default/launcher/tests/integrate_testing.py ================================================ import json import os import time import sys from subprocess import Popen, PIPE, STDOUT import threading current_path = os.path.dirname(os.path.abspath(__file__)) default_path = os.path.abspath(os.path.join(current_path, os.path.pardir, os.path.pardir)) root_path = os.path.abspath(os.path.join(default_path, os.path.pardir, os.path.pardir)) noarch_lib = os.path.abspath(os.path.join(default_path, 'lib', 'noarch')) sys.path.append(noarch_lib) import utils import simple_http_server from dnslib.dns import DNSRecord, DNSHeader, DNSQuestion import socket import simple_http_client from xlog import getLogger xlog = getLogger("test") class ServiceTesting(object): def __init__(self): self.xtunnel_login_status = False self.running = True self.pth = None self.log_fp = None self.log_fn = None # Lock for one integrate testing at the same time. # github act running in local will run multi python version in same VM, so we need to lock to avoid conflict. while True: try: res = simple_http_client.request("GET", "http://127.0.0.1:8888/test") if res and res.status == 200: time.sleep(1) continue else: break except: break self.lock_server = simple_http_server.HTTPServer(('', 8888), simple_http_server.TestHttpServer, ".") self.lock_server.start() if self.check_web_console(): xlog.info("APP was running externally.") self.th = None return self.log_fn = os.path.join(root_path, "running.log") if sys.version_info[0] == 3: self.log_fp = open(self.log_fn, "wb") else: self.log_fp = open(self.log_fn, "w") self.th = threading.Thread(target=self.start_xxnet) self.th.start() def __del__(self): if self.log_fp: self.log_fp.close() self.log_fp = None def run(self): self.get_xxnet_web_console() self.xtunnel_logout() self.smart_route_dns_query() self.smart_route_proxy_http() self.smart_route_proxy_socks4() self.smart_route_proxy_socks5() self.xtunnel_token_login() self.xtunnel_proxy_http() self.xtunnel_proxy_socks4() self.xtunnel_proxy_socks5() if not self.th: return self.stop_xxnet() self.check_log() self.lock_server.shutdown() for _ in range(30): if not self.th: return time.sleep(1) # If APP not exit, kill all python to exit, this script will also be killed. self.kill_python() def check_web_console(self): try: res = simple_http_client.request("GET", "http://127.0.0.1:8085/", timeout=1) return res is not None and res.status in [200, 404] # 404 is because act running locally may lost some folder. just bypass this error. except Exception as e: # xlog.debug("get web_console fail:%r", e) return False def get_xxnet_web_console(self, timeout=50): xlog.info("Start get xxnet web console.") t0 = time.time() t_end = t0 + timeout while time.time() < t_end and self.running: if not self.check_web_console(): time.sleep(1) continue xlog.info("Got web console success.") return xlog.warn("Get Web Console timeout.") def xtunnel_logout(self): xlog.info("Start testing XTunnel logout") res = simple_http_client.request("POST", "http://127.0.0.1:8085/module/x_tunnel/control/logout", timeout=10) self.assertEqual(res.status, 200) self.xtunnel_login_status = False xlog.info("Finished testing XTunnel logout") def smart_route_proxy_http(self): xlog.info("Start testing SmartRouter HTTP proxy protocol") proxy = "http://localhost:8086" res = simple_http_client.request("GET", "https://github.com/", proxy=proxy, timeout=20) self.assertEqual(res.status, 200) xlog.info("Finished testing SmartRouter HTTP proxy protocol") def smart_route_proxy_socks4(self): xlog.info("Start testing SmartRouter SOCKS4 proxy protocol") proxy = "socks4://localhost:8086" res = simple_http_client.request("GET", "https://github.com/", proxy=proxy, timeout=15) self.assertEqual(res.status, 200) xlog.info("Finished testing SmartRouter SOCKS4 proxy protocol") def smart_route_proxy_socks5(self): xlog.info("Start testing SmartRouter SOCKS5 proxy protocol") proxy = "socks5://localhost:8086" res = simple_http_client.request("GET", "https://github.com/", proxy=proxy, timeout=15) self.assertEqual(res.status, 200) xlog.info("Finished testing SmartRouter SOCKS5 proxy protocol") def smart_route_dns_query(self): xlog.info("Start testing SmartRouter DNS Query") domain = "appsec.hicloud.com" d = DNSRecord(DNSHeader(123)) d.add_question(DNSQuestion(domain, 1)) req4_pack = d.pack() for port in [8053, 53]: sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.sendto(req4_pack, ("127.0.0.1", port)) sock.settimeout(5) try: response, server = sock.recvfrom(8192) except Exception as e: xlog.warn("recv fail for port:%s e:%r", port, e) continue p = DNSRecord.parse(response) for r in p.rr: ip = utils.to_bytes(str(r.rdata)) xlog.info("IP:%s" % ip) self.assertEqual(utils.check_ip_valid(ip), True) xlog.info("Finished testing SmartRouter DNS Query") return def xtunnel_token_login(self): xlog.info("Start testing XTunnel login") headers = { "Content-Type": "application/json" } data = { "login_token": os.getenv("XTUNNEL_TOKEN"), } data = json.dumps(data) res = simple_http_client.request("POST", "http://127.0.0.1:8085/module/x_tunnel/control/token_login", headers=headers, body=data, timeout=60) self.assertEqual(res.status, 200) self.xtunnel_login_status = True xlog.info("Finished testing XTunnel login") def xtunnel_proxy_http(self): xlog.info("Start testing XTunnel HTTP proxy protocol") if not self.xtunnel_login_status: self.xtunnel_token_login() proxy = "http://localhost:1080" for _ in range(3): res = simple_http_client.request("GET", "https://github.com/", proxy=proxy, timeout=30) if not res: time.sleep(5) continue self.assertEqual(res.status, 200) xlog.info("Finished testing XTunnel HTTP proxy protocol") self.assertEqual(res.status, 200) def xtunnel_proxy_socks4(self): xlog.info("Start testing XTunnel Socks4 proxy protocol") if not self.xtunnel_login_status: self.xtunnel_token_login() proxy = "socks4://localhost:1080" res = simple_http_client.request("GET", "https://github.com/", proxy=proxy, timeout=15) self.assertEqual(res.status, 200) xlog.info("Finished testing XTunnel Socks4 proxy protocol") def xtunnel_proxy_socks5(self): xlog.info("Start testing XTunnel Socks5 proxy protocol") if not self.xtunnel_login_status: self.xtunnel_token_login() proxy = "socks5://localhost:1080" res = simple_http_client.request("GET", "https://github.com/", proxy=proxy, timeout=15) self.assertEqual(res.status, 200) xlog.info("Finished testing XTunnel Socks5 proxy protocol") def start_xxnet(self): py_bin = sys.executable start_script = os.path.join(default_path, "launcher", "start.py") cmd = [py_bin, start_script] xlog.info("start APP cmd: %s" % cmd) try: self.pth = Popen(cmd, stdout=PIPE, stderr=STDOUT) # , preexec_fn=os.setsid, shell=True, , bufsize=1 for line in iter(self.pth.stdout.readline, b''): self.log_fp.write(line) self.log_fp.flush() line = line.strip() xlog.info("LOG|%s", line) if not self.running: break except Exception as e: xlog.exception("run %s error:%r", cmd, e) xlog.info("xxnet quit.") self.running = False self.th = None def stop_xxnet(self): xlog.info("call api to Quit xxnet") try: res = simple_http_client.request("GET", "http://127.0.0.1:8085/quit", timeout=0.5) if res: xlog.info("Quit API res:%s", res.text) else: xlog.info("Quit API request failed.") except Exception as e: xlog.info("Quit API except:%r", e) def kill_python(self): self.running = False xlog.info("start kill python") if sys.platform == "win32": # This will kill this script as well. os.system("taskkill /F /im python.exe") else: os.system("pkill -9 -f 'start.py'") xlog.info("Finished kill python") def check_log(self): if not self.log_fn: # Debugging mode, running xxnet manually, check by human. return with open(self.log_fn, "r") as fp: for line in fp.readlines(): line = line.strip() line = utils.to_str(line) self.assertNotIn("[ERROR]", line) xlog.info("Log Check passed!") def assertEqual(self, a, b): if not a == b: raise Exception("%s not equal %s" % (a, b)) def assertNotIn(self, a, b): if a in b: raise Exception("%s in %s" % (a, b)) def run_testing(): testing = ServiceTesting() try: testing.run() except Exception as e: xlog.exception("test failed:%r", e) testing.stop_xxnet() testing.kill_python() exit(1) if __name__ == "__main__": run_testing() ================================================ FILE: code/default/launcher/tests/test_update.py ================================================ import os.path import unittest import tempfile import os from launcher.update_from_github import download_file class UpdateTest(unittest.TestCase): def test_download(self): tp = tempfile.gettempdir() fn = os.path.join(tp, "v4.txt") res = download_file("https://raw.githubusercontent.com/XX-net/XX-Net/master/code/default/update_v4.txt", fn) self.assertTrue(res) ================================================ FILE: code/default/launcher/tests/test_web_api.py ================================================ from unittest import TestCase import json import simple_http_client class TestAPi(TestCase): def setUp(self): self.base_url = "http://localhost:8085" def test_set_proxy_applist(self): url = self.base_url + "/set_proxy_applist" headers = { "Content-Type": "application/json" } info = { 'proxy_by_app': "true", 'enabled_app_list[]': [ "com.google.android.youtube" ] } dat = json.dumps(info) res = simple_http_client.request("POST", url, headers=headers, body=dat) print(res.text) ================================================ FILE: code/default/launcher/tests/test_win_port_reserve.py ================================================ from unittest import TestCase import sys from launcher.win_compat_suggest import Win10PortReserveSolution empty_output = [ b'\r\n', b'Protocol tcp Port Exclusion Ranges\r\n', b'\r\n', b'Start Port End Port \r\n', b'---------- -------- \r\n', b'\r\n', b'* - Administered port exclusions.\r\n', b'\r\n' ] valid_output = [ b'\r\n', b'Protocol tcp Port Exclusion Ranges\r\n', b'\r\n', b'Start Port End Port \r\n', b'---------- -------- \r\n', b' 49795 49894 \r\n', b' 49895 49994 \r\n', b' 50000 50059 *\r\n', b'\r\n', b'* - Administered port exclusions.\r\n', b'\r\n' ] class TestW10PortReserve(TestCase): def setUp(self): if sys.platform == "win32": self.s = Win10PortReserveSolution() else: self.s = None def test_detect(self): if not self.s: return res = self.s.is_port_reserve_conflict() print(res) def test_reset(self): if not self.s: return self.s.change_reserved_port_range() def test_resolve(self): if not self.s: return self.s.check_and_resolve() ================================================ FILE: code/default/launcher/tests/try_run.py ================================================ import logging import sys import os from subprocess import Popen, PIPE, STDOUT from logging import getLogger xlog = getLogger("test") xlog.setLevel(logging.DEBUG) current_path = os.path.dirname(os.path.abspath(__file__)) default_path = os.path.abspath(os.path.join(current_path, os.path.pardir, os.path.pardir)) class T(object): def start_xxnet(self): py_bin = sys.executable start_script = os.path.join(default_path, "launcher", "start.py") cmd = [py_bin, start_script] xlog.info("cmd: %s" % cmd) try: self.pth = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, bufsize=1) # , preexec_fn=os.setsid # for line in stream.stdout: for line in iter(self.pth.stdout.readline, b''): line = line.strip() xlog.info(b"LOG|%s" % line) print(line) # self.assertNotIn(b"[ERROR]", line) except Exception as e: xlog.exception("run %s error:%r", cmd, e) xlog.info("xxnet exit.") self.running = False self.th = None if __name__ == "__main__": t = T() t.start_xxnet() ================================================ FILE: code/default/launcher/tests/try_smartroute_sock4.py ================================================ import simple_http_client def smart_route_proxy_socks4(): proxy = "socks4://localhost:8086" res = simple_http_client.request("GET", "https://github.com/", proxy=proxy, timeout=1000) return res if __name__ == "__main__": smart_route_proxy_socks4() ================================================ FILE: code/default/launcher/unzip.vbs ================================================ Sub Unzip(ZipFile, ExtractTo) Dim objShell: set objShell = CreateObject("Shell.Application") Dim FilesInZip dim ns ZipFile = GetAbslutePath(ZipFile) ExtractTo = GetAbslutePath(ExtractTo) x = CreateDir(ExtractTo) set ns = objShell.NameSpace(ZipFile) set FilesInZip = ns.items() objShell.NameSpace(ExtractTo).CopyHere(FilesInZip) End Sub ================================================ FILE: code/default/launcher/update.py ================================================ #!/usr/bin/env python # coding:utf-8 import os, stat import json import time import threading import zipfile import sys import platform import uuid try: from urllib.request import build_opener, HTTPSHandler, ProxyHandler except ImportError: from urllib2 import build_opener, HTTPSHandler, ProxyHandler try: reduce # Python 2 except NameError: # Python 3 from functools import reduce import utils from xlog import getLogger xlog = getLogger("launcher") from config import config, app_name import update_from_github import sys_platform import global_var import env_info update_url = "https://xxnet-update.appspot.com/update.json" update_content = "" update_dict = {} new_gae_proxy_version = "" gae_proxy_path = "" current_path = os.path.dirname(os.path.abspath(__file__)) root_path = os.path.abspath(os.path.join(current_path, os.pardir)) data_root = env_info.data_path should_create_desktop_shortcut = True def get_opener(): autoproxy = '127.0.0.1:8086' # import ssl # if getattr(ssl, "create_default_context", None): # cafile = os.path.join(data_root, "gae_proxy", "CA.crt") # if not os.path.isfile(cafile): # cafile = None # context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH, # cafile=cafile) # https_handler = HTTPSHandler(context=context) # # opener = build_opener(ProxyHandler({'http': autoproxy, 'https': autoproxy}), https_handler) # else: opener = build_opener(ProxyHandler({'http': autoproxy, 'https': autoproxy})) return opener def version_to_bin(s): return reduce(lambda a, b: a << 8 | b, list(map(int, s.split(".")))) def compare_versions(v1, v2): """Compare two version strings and return -1, 0, or 1.""" def parse_version(version): return [int(x) for x in version.split('.')] parts1 = parse_version(v1) parts2 = parse_version(v2) # Pad with zeros to make lengths equal max_len = max(len(parts1), len(parts2)) parts1 += [0] * (max_len - len(parts1)) parts2 += [0] * (max_len - len(parts2)) if parts1 < parts2: return -1 elif parts1 > parts2: return 1 else: return 0 def download_file(url, file): try: xlog.info("download %s to %s", url, file) opener = get_opener() req = opener.open(url, cafile="") CHUNK = 16 * 1024 with open(file, 'wb') as fp: while True: chunk = req.read(CHUNK) if not chunk: break fp.write(chunk) return True except: xlog.info("download %s to %s fail", url, file) return False def sha1_file(filename): import hashlib BLOCKSIZE = 65536 hasher = hashlib.sha1() try: with open(filename, 'rb') as afile: buf = afile.read(BLOCKSIZE) while len(buf) > 0: hasher.update(buf) buf = afile.read(BLOCKSIZE) return hasher.hexdigest() except: return False def install_module(module, new_version): import module_init import os, subprocess, sys current_path = os.path.dirname(os.path.abspath(__file__)) new_module_version_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, module, new_version)) # check path exist if not os.path.isdir(new_module_version_path): xlog.error("install module %s dir %s not exist", module, new_module_version_path) return # call setup.py setup_script = os.path.join(new_module_version_path, "setup.py") if not os.path.isfile(setup_script): xlog.warn("update %s fail. setup script %s not exist", module, setup_script) return config.current_version = str(new_version) config.save() if module == "launcher": module_init.stop_all() import web_control web_control.stop() subprocess.Popen([sys.executable, setup_script], shell=False) os._exit(0) else: xlog.info("Setup %s version %s ...", module, new_version) try: module_init.stop(module) subprocess.call([sys.executable, setup_script], shell=False) xlog.info("Finished new version setup.") xlog.info("Restarting new version ...") module_init.start(module) except Exception as e: xlog.error("install module %s %s fail:%s", module, new_version, e) def download_module(module, new_version): import os global update_content, update_dict current_path = os.path.dirname(os.path.abspath(__file__)) download_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, 'data', 'downloads')) if not os.path.isdir(download_path): os.mkdir(download_path) try: for source in update_dict["modules"][module]["versions"][new_version]["sources"]: url = source["url"] filename = module + "-" + new_version + ".zip" file_path = os.path.join(download_path, filename) if os.path.isfile(file_path) and sha1_file(file_path) == update_dict["modules"][module]["versions"][new_version]["sha1"]: pass elif not download_file(url, file_path): xlog.warn("download %s fail", url) continue sha1 = sha1_file(file_path) if update_dict["modules"][module]["versions"][new_version]["sha1"] != sha1: xlog.warn("download %s sha1 wrong", url) continue module_path = os.path.abspath(os.path.join(current_path, os.pardir, os.pardir, module)) if not os.path.isdir(module_path): os.mkdir(module_path) version_path = os.path.join(module_path, new_version) if os.path.isdir(version_path): xlog.error("module dir exist:%s, download exist.", version_path) return with zipfile.ZipFile(file_path, "r") as dz: dz.extractall(module_path) dz.close() import shutil unzip_path = os.path.abspath(os.path.join(module_path, module + "-" + new_version)) tag_path = os.path.abspath(os.path.join(module_path, new_version)) shutil.move(unzip_path, tag_path) msg = "Module %s new version %s downloaded, Install?" % (module, new_version) if sys.platform == "linux" or sys.platform == "linux2": from gtk_tray import sys_tray data_install = "%s|%s|install" % (module, new_version) data_ignore = "%s|%s|ignore" % (module, new_version) buttons = {1: {"data": data_install, "label": "Install", 'callback': general_gtk_callback}, 2: {"data": data_ignore, "label": "Ignore", 'callback': general_gtk_callback}} sys_tray.notify_general(msg=msg, title="Install", buttons=buttons) elif sys.platform == "win32": from win_tray import sys_tray if sys_tray.dialog_yes_no(msg, "Install", None, None) == 1: install_module(module, new_version) else: ignore_module(module, new_version) elif sys.platform == "darwin": from mac_tray import sys_tray if sys_tray.presentAlert_withTitle_(msg, "Install"): install_module(module, new_version) else: ignore_module(module, new_version) else: install_module(module, new_version) break except Exception as e: xlog.warn("get gae_proxy source fail, content:%s err:%s", update_content, e) def ignore_module(module, new_version): config.ignore_version = str(new_version) config.save() def general_gtk_callback(widget=None, data=None): args = data.split('|') if len(args) != 3: xlog.error("general_gtk_callback data:%s", data) return module = args[0] new_version = args[1] action = args[2] if action == "download": download_module(module, new_version) elif action == "install": install_module(module, new_version) elif action == "ignore": ignore_module(module, new_version) def check_update(): try: if update_from_github.update_info == "dont-check": return # check_push_update() # server broken update_rule = config.check_update if update_rule not in ("stable", "notice-stable", "test", "notice-test"): return try: versions = update_from_github.get_github_versions() except Exception as e: xlog.warn("check_update get version failed. e:%r", e) return current_version = update_from_github.current_version() test_version, stable_version = versions[0][1], versions[1][1] if test_version != config.skip_test_version: if update_rule == "notice-test": if compare_versions(current_version, test_version) < 0: xlog.info("checked new test version %s", test_version) update_from_github.update_info = '{"type":"test", "version":"%s"}' % test_version elif update_rule == "test": if compare_versions(current_version, test_version) < 0: xlog.info("update to test version %s", test_version) update_from_github.update_version(test_version) if stable_version != config.skip_stable_version: if update_rule == "notice-stable": if compare_versions(current_version, stable_version) < 0: xlog.info("checked new stable version %s", stable_version) update_from_github.update_info = '{"type":"stable", "version":"%s"}' % stable_version elif update_rule == "stable": if compare_versions(current_version, stable_version) < 0: xlog.info("update to stable version %s", stable_version) update_from_github.update_version(stable_version) except IOError as e: xlog.exception("check update fail:%r", e) except Exception as e: xlog.exception("check_update fail:%r", e) finally: if update_from_github.update_info == "init": update_from_github.update_info = "" def check_push_update(): global update_content, update_dict try: opener = get_opener() req_url = update_url + "?uuid=" + get_uuid() \ + "&version=" + update_from_github.current_version() \ + "&platform=" + platform.platform() try: res = opener.open(req_url) update_content = res.read() except Exception as e: xlog.exception("check_update get content fail:%r", e) return False update_dict = json.loads(utils.to_str(update_content)) return True except Exception as e: xlog.exception("check_update except:%s", e) return def create_desktop_shortcut(): import sys import subprocess work_path = os.path.dirname(os.path.abspath(__file__)) os.chdir(work_path) if sys.platform.startswith("linux"): def create_xwindows_shortcut(): if os.getenv("DESKTOP_SESSION", "unknown") == "unknown": # make sure this is desktop linux return desktop_path = os.path.join(os.path.join(os.path.expanduser('~')), 'Desktop') if not os.path.isdir(desktop_path): return xxnet_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir)) content = "[Desktop Entry]\n" + \ "Version=1.0\n" + \ "Type=Application\n" + \ "Name=" + app_name + "\n" +\ "Comment=\n" + \ "Exec=sh -c \"" + xxnet_path + "/start\"\n" + \ "Icon=" + xxnet_path + "/code/default/launcher/web_ui/img/" + app_name + "/favicon.ico\n" + \ "Path=\n" + \ "Terminal=false\n" + \ "StartupNotify=false\n" fp = os.path.join(desktop_path, app_name + ".desktop") with open(fp, "w") as fd: fd.write(content) os.chmod(fp, 0o0744) create_xwindows_shortcut() elif sys.platform == "win32": # import ctypes # msg = u"是否在桌面创建图标?" # title = app_name #res = ctypes.windll.user32.MessageBoxW(None, msg, title, 1) # Yes:1 No:2 #if res == 2: # return subprocess.call(["Wscript.exe", "//E:JScript", "create_shortcut.js", app_name], shell=False) def notify_install_tcpz_for_winXp(): import ctypes ctypes.windll.user32.MessageBoxW(None, "请使用tcp-z对 tcpip.sys 打补丁,解决链接并发限制!", "Patch XP needed", 0) def check_new_machine(): current_path = os.path.dirname(os.path.abspath(__file__)) if current_path != config.last_path: config.last_path = current_path config.save() if sys.platform == "win32" and platform.release() == "XP": notify_install_tcpz_for_winXp() if sys_platform.has_desktop and should_create_desktop_shortcut: xlog.info("generate desktop shortcut") create_desktop_shortcut() def update_check_loop(): check_new_machine() # wait gae_proxy to start # update need gae_proxy as proxy time.sleep(500) while global_var.running: check_update() time.sleep(3600 * 24) def start(): get_uuid() p = threading.Thread(target=update_check_loop, name="check_update") p.daemon = True p.start() def need_new_uuid(): if not config.update_uuid: xlog.info("need_new_uuid: uuid is empty") return True return False def generate_new_uuid(): xx_net_uuid = str(uuid.uuid4()) config.update_uuid = xx_net_uuid xlog.info("generate uuid:%s", xx_net_uuid) config.save() def get_uuid(): if need_new_uuid(): generate_new_uuid() xx_net_uuid = config.update_uuid xlog.info("get uuid:%s", xx_net_uuid) return xx_net_uuid if __name__ == "__main__": #get_uuid() #check_update() #sys_tray.serve_forever() # create_desktop_shortcut() print(compare_versions("2.1.1", "2.1.0")) ================================================ FILE: code/default/launcher/update_from_github.py ================================================ import os import sys import time import subprocess import threading import re import zipfile import shutil import stat import glob current_path = os.path.dirname(os.path.abspath(__file__)) root_path = os.path.abspath(os.path.join(current_path, os.pardir)) top_path = os.path.abspath(os.path.join(root_path, os.pardir, os.pardir)) code_path = os.path.abspath(os.path.join(root_path, os.pardir)) import env_info data_root = env_info.data_path python_path = root_path noarch_lib = os.path.join(python_path, 'lib', 'noarch') sys.path.append(noarch_lib) import utils import simple_http_client import global_var from xlog import getLogger xlog = getLogger("launcher") try: from config import config except: from .config import config if not os.path.isdir(data_root): os.mkdir(data_root) download_path = os.path.join(data_root, 'downloads') if not os.path.isdir(download_path): os.mkdir(download_path) progress = {} # link => {"size", 'downloaded', status:downloading|canceled|finished:failed} progress["update_status"] = "Idle" update_info = "init" def init_update_info(check_update): global update_info if check_update == "dont-check": update_info = "dont-check" elif config.check_update == update_info: update_info = "init" elif check_update != "init": update_info = "" init_update_info(config.check_update) def request(url, retry=0, timeout=30): if retry == 0: if config.global_proxy_enable == 1: client = simple_http_client.Client(proxy={ "type": config.global_proxy_type, "host": config.global_proxy_host, "port": config.global_proxy_port, "user": config.global_proxy_username, "pass": config.global_proxy_password, }, timeout=timeout) else: client = simple_http_client.Client(timeout=timeout) else: cert = os.path.join(data_root, "gae_proxy", "CA.crt") client = simple_http_client.Client(proxy={ "type": "http", "host": "127.0.0.1", "port": 8086, "user": None, "pass": None }, timeout=timeout, cert=cert) res = client.request("GET", url, read_payload=False) return res def download_file(url, filename): if url not in progress: progress[url] = {} progress[url]["status"] = "downloading" progress[url]["size"] = 1 progress[url]["downloaded"] = 0 else: if progress[url]["status"] == "downloading": xlog.warn("url in downloading, %s", url) return False for i in range(0, 2): try: xlog.info("download %s to %s, retry:%d", url, filename, i) req = request(url, i, timeout=120) if not req: continue start_time = time.time() timeout = 300 if req.chunked: # don't known the file size, set to large for show the progress progress[url]["size"] = 20 * 1024 * 1024 downloaded = 0 with open(filename, 'wb') as fp: while global_var.running: time_left = timeout - (time.time() - start_time) if time_left < 0: raise Exception("time out") dat = req.read(timeout=time_left) if not dat: break fp.write(dat) downloaded += len(dat) progress[url]["downloaded"] = downloaded progress[url]["status"] = "finished" return True else: file_size = progress[url]["size"] = int(req.getheader(b'Content-Length', 0)) left = file_size downloaded = 0 with open(filename, 'wb') as fp: while global_var.running: chunk_len = min(65536, left) if not chunk_len: break chunk = req.read(chunk_len) if not chunk: break fp.write(chunk) downloaded += len(chunk) progress[url]["downloaded"] = downloaded left -= len(chunk) if downloaded != progress[url]["size"]: xlog.warn("download size:%d, need size:%d, download fail.", downloaded, progress[url]["size"]) continue else: progress[url]["status"] = "finished" return True except Exception as e: xlog.exception("download %s to %s fail:%r", url, filename, e) continue progress[url]["status"] = "failed" return False def parse_update_versions(readme_file): versions = [] try: fd = open(readme_file, "rb") lines = fd.readlines() p = re.compile(br'https://codeload.github.com/XX-net/XX-Net/zip/([0-9]+)\.([0-9]+)\.([0-9]+) ([0-9a-fA-F]*)') for line in lines: m = p.match(line) if m: version = m.group(1) + b"." + m.group(2) + b"." + m.group(3) hashsum = m.group(4).lower() versions.append([m.group(0), version, hashsum]) versions = utils.to_str(versions) if len(versions) == 2: return versions except Exception as e: xlog.exception("xxnet_version fail:%r", e) raise Exception("get_version_fail:%s" % readme_file) def current_version(): readme_file = os.path.join(root_path, "version.txt") try: with open(readme_file) as fd: content = fd.read() p = re.compile(r'([0-9]+)\.([0-9]+)\.([0-9]+)') m = p.match(content) if m: version = m.group(1) + "." + m.group(2) + "." + m.group(3) return version except: xlog.warn("get_version_fail in update_from_github") return "get_version_fail" def get_github_versions(): readme_url = "https://raw.githubusercontent.com/XX-net/XX-Net/master/code/default/update_v5.txt" readme_target = os.path.join(download_path, "version.txt") if not download_file(readme_url, readme_target): raise IOError("get update file %s fail:" % readme_url) versions = parse_update_versions(readme_target) return versions def get_hash_sum(version): versions = get_github_versions() for v in versions: if v[1] == version: return v[2] def hash_file_sum(filename): import hashlib BLOCKSIZE = 65536 hasher = hashlib.sha256() try: with open(filename, 'rb') as afile: buf = afile.read(BLOCKSIZE) while len(buf) > 0: hasher.update(buf) buf = afile.read(BLOCKSIZE) return hasher.hexdigest() except: return False def overwrite(xxnet_version, xxnet_unzip_path): progress["update_status"] = "Overwriting" try: for root, subdirs, files in os.walk(xxnet_unzip_path): relate_path = root[len(xxnet_unzip_path) + 1:] target_relate_path = relate_path if sys.platform == 'win32': if target_relate_path.startswith("code\\default"): target_relate_path = "code\\" + xxnet_version + relate_path[12:] else: if target_relate_path.startswith("code/default"): target_relate_path = "code/" + xxnet_version + relate_path[12:] for subdir in subdirs: if relate_path == "code" and subdir == "default": subdir = xxnet_version target_path = os.path.join(top_path, target_relate_path, subdir) if not os.path.isdir(target_path): xlog.info("mkdir %s", target_path) os.mkdir(target_path) for filename in files: src_file = os.path.join(root, filename) dst_file = os.path.join(top_path, target_relate_path, filename) if relate_path == 'code' and filename == 'app_info.json': continue if not os.path.isfile(dst_file) or hash_file_sum(src_file) != hash_file_sum(dst_file): xlog.info("copy %s => %s", src_file, dst_file) # modify by outofmemo, files in '/sdcard' are not allowed to chmod for Android # and shutil.copy() will call shutil.copymode() if sys.platform != 'win32' and os.path.isfile("/system/bin/dalvikvm") == False and os.path.isfile( "/system/bin/dalvikvm64") == False and os.path.isfile(dst_file): st = os.stat(dst_file) shutil.copy(src_file, dst_file) if st.st_mode & stat.S_IEXEC: os.chmod(dst_file, st.st_mode) else: shutil.copyfile(src_file, dst_file) except Exception as e: xlog.warn("update overwrite fail:%r", e) progress["update_status"] = "Overwrite Fail:%r" % e raise e xlog.info("update file finished.") def download_overwrite_new_version(xxnet_version, checkhash=1): global update_progress xxnet_url = 'https://codeload.github.com/XX-net/XX-Net/zip/%s' % xxnet_version xxnet_zip_file = os.path.join(download_path, "XX-Net-%s.zip" % xxnet_version) xxnet_unzip_path = os.path.join(download_path, "XX-Net-%s" % xxnet_version) progress["update_status"] = "Downloading %s" % xxnet_url if not download_file(xxnet_url, xxnet_zip_file): progress["update_status"] = "Download Fail." raise Exception("download xxnet zip fail:%s" % xxnet_zip_file) if checkhash: hash_sum = get_hash_sum(xxnet_version) if len(hash_sum) and hash_file_sum(xxnet_zip_file) != hash_sum: progress["update_status"] = "Download Checksum Fail." xlog.warn("downloaded xxnet zip checksum fail:%s" % xxnet_zip_file) raise Exception("downloaded xxnet zip checksum fail:%s" % xxnet_zip_file) else: xlog.debug("skip checking downloaded file hash") xlog.info("update download %s finished.", download_path) xlog.info("update start unzip") progress["update_status"] = "Unziping" try: with zipfile.ZipFile(xxnet_zip_file, "r") as dz: dz.extractall(download_path) dz.close() except Exception as e: xlog.warn("unzip %s fail:%r", xxnet_zip_file, e) progress["update_status"] = "Unzip Fail:%s" % e raise e xlog.info("update finished unzip") overwrite(xxnet_version, xxnet_unzip_path) os.remove(xxnet_zip_file) shutil.rmtree(xxnet_unzip_path, ignore_errors=True) def get_local_versions(): def get_folder_version(folder): f = os.path.join(code_path, folder, "version.txt") try: with open(f) as fd: content = fd.read() p = re.compile(r'([0-9]+)\.([0-9]+)\.([0-9]+)') m = p.match(content) if m: version = m.group(1) + "." + m.group(2) + "." + m.group(3) return version except: return False files_in_code_path = os.listdir(code_path) local_versions = [] for name in files_in_code_path: if os.path.isdir(os.path.join(code_path, name)): v = get_folder_version(name) if v: local_versions.append([v, name]) local_versions.sort(key=lambda s: list(map(int, s[0].split('.'))), reverse=True) return local_versions def get_current_version_dir(): current_dir = os.path.split(root_path)[-1] return current_dir def del_version(version): if version == get_current_version_dir(): xlog.warn("try to delect current version.") return False try: shutil.rmtree(os.path.join(top_path, "code", version)) return True except Exception as e: xlog.warn("deleting fail: %s", e) return False def update_current_version(version): start_script = os.path.join(top_path, "code", version, "launcher", "start.py") if not os.path.isfile(start_script): xlog.warn("set version %s not exist", version) return False current_version_file = os.path.join(top_path, "code", "version.txt") with open(current_version_file, "w") as fd: fd.write(version) return True def restart_xxnet(version=None): import module_init module_init.stop_all() import web_control web_control.stop() # New process will hold the listen port # We should close all listen port before create new process xlog.info("Close web control port.") if version is None: current_version_file = os.path.join(top_path, "code", "version.txt") with open(current_version_file, "r") as fd: version = fd.read() xlog.info("restart to xx-net version:%s", version) start_script = os.path.join(top_path, "code", version, "launcher", "start.py") subprocess.Popen([sys.executable, start_script]) time.sleep(20) xlog.info("Exit old process...") os._exit(0) def update_version(version, checkhash=1): global update_progress, update_info _update_info = update_info update_info = "" try: download_overwrite_new_version(version, checkhash) update_current_version(version) progress["update_status"] = "Restarting" xlog.info("update try restart xxnet") restart_xxnet(version) except Exception as e: xlog.warn("update version %s fail:%r", version, e) update_info = _update_info def start_update_version(version, checkhash=1): if progress["update_status"] != "Idle" and "Fail" not in progress["update_status"]: return progress["update_status"] progress["update_status"] = "Start update" th = threading.Thread(target=update_version, args=(version, checkhash), name="update_version") th.start() return True def cleanup(): def rm_paths(path_list): del_fullpaths = [] for ps in path_list: pt = os.path.join(top_path, ps) pt = glob.glob(pt) del_fullpaths += pt if del_fullpaths: xlog.info("DELETE: %s", ' , '.join(del_fullpaths)) for pt in del_fullpaths: try: if os.path.isfile(pt): os.remove(pt) elif os.path.isdir(pt): shutil.rmtree(pt) except: pass keep_old_num = config.keep_old_ver_num # default keep several old versions if keep_old_num < 99 and keep_old_num >= 0: # 99 means don't delete any old version del_paths = [] local_vs = get_local_versions() for i in range(len(local_vs)): if local_vs[i][0] == current_version(): for u in range(i + keep_old_num + 1, len(local_vs)): del_paths.append("code/" + local_vs[u][1] + "/") break if del_paths: rm_paths(del_paths) del_paths = [] if config.clear_cache: del_paths += [ "data/*/*.*.log", "data/*/*.log.*", "data/downloads/XX-Net-*.zip" ] if config.del_win: del_paths += [ "code/*/lib/win32/" ] if config.del_mac: del_paths += [ "code/*/lib/darwin/" ] if config.del_linux: del_paths += [ "code/*/lib/linux/" ] if config.del_gae: del_paths += [ "code/*/gae_proxy/" ] if config.del_gae_server: del_paths += [ "code/*/gae_proxy/server/" ] if config.del_xtunnel: del_paths += [ "code/*/x_tunnel/" ] if config.del_smartroute: del_paths += [ "code/*/smart_router/" ] if del_paths: rm_paths(del_paths) ================================================ FILE: code/default/launcher/web_control.py ================================================ #!/usr/bin/env python # coding:utf-8 import os, sys import errno import re import socket, ssl import time import threading import json import cgi import traceback import base64 try: from urllib.parse import urlparse, urlencode, parse_qs from urllib.request import urlopen, Request from urllib.error import HTTPError except ImportError: from urlparse import urlparse, parse_qs from urllib import urlencode from urllib2 import urlopen, Request, HTTPError try: from urllib.request import ProxyHandler from urllib.request import build_opener except ImportError: from urllib2 import ProxyHandler from urllib2 import build_opener current_path = os.path.dirname(os.path.abspath(__file__)) default_path = os.path.abspath(os.path.join(current_path, os.pardir)) if __name__ == "__main__": noarch_lib = os.path.abspath(os.path.join(default_path, 'lib', 'noarch')) sys.path.append(noarch_lib) import sys_platform from xlog import getLogger, keep_log xlog = getLogger("launcher") import module_init from config import config, valid_language, app_name import autorun import update import update_from_github import simple_http_client import simple_http_server import utils from simple_i18n import SimpleI18N import env_info NetWorkIOError = (socket.error, ssl.SSLError, OSError) current_version = utils.to_bytes(update_from_github.current_version()) i18n_translator = SimpleI18N() i18n_translator.add_translate(b"APP_NAME", utils.to_bytes(app_name)) i18n_translator.add_translate(b"APP_VERSION", current_version) module_menus = {} class FakeHttpHandler(simple_http_server.HttpServerHandler): def handle_one_request(self): # This function will replace simple_http_server HttpHandler.handle_one_request to hold all http requests. # Doing this is to simulate bug. self.close_connection = 0 CORS_header = { "Allow": "GET,POST,OPTIONS", "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET,POST,OPTIONS", "Access-Control-Allow-Headers": "Authorization,Content-Type,Sec-Fetch-Site,Sec-Fetch-Mode,Sec-Fetch-Dest", "Connection": "close", } class Http_Handler(simple_http_server.HttpServerHandler): deploy_proc = None def load_module_menus(self): global module_menus new_module_menus = {} modules = config.all_modules for module in modules: if getattr(config, "enable_" + module) != 1: continue menu_path = os.path.join(default_path, module, "web_ui", "menu.json") # launcher & gae_proxy modules if not os.path.isfile(menu_path): continue # i18n code lines (Both the locale dir & the template dir are module-dependent) locale_dir = os.path.abspath(os.path.join(default_path, module, 'lang')) stream = i18n_translator.render(locale_dir, menu_path) module_menu = json.loads(utils.to_str(stream)) new_module_menus[module] = module_menu module_menus = sorted(iter(new_module_menus.items()), key=lambda k_and_v: (k_and_v[1]['menu_sort_id'])) # for k,v in self.module_menus: # xlog.debug("m:%s id:%d", k, v['menu_sort_id']) def do_OPTIONS(self): # xlog.debug('%s "%s headers:%s from:%s', self.command, self.path, self.headers, self.address_string()) try: origin = utils.to_str(self.headers.get(b'Origin')) # if origin not in self.config.allow_web_origins: # return header = { "Allow": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS", "Access-Control-Allow-Origin": origin, "Access-Control-Allow-Methods": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS", "Access-Control-Allow-Headers": "Authorization,Content-Type", } return self.send_response(headers=header) except Exception as e: xlog.exception("options fail:%r", e) return self.send_not_found() def do_POST(self): self.headers = utils.to_str(self.headers) self.path = utils.to_str(self.path) refer = self.headers.get('Referer') if refer: refer_loc = urlparse(refer).netloc host = self.headers.get('Host') if refer_loc != host and refer_loc not in config.allowed_refers: xlog.warn("web control ref:%s host:%s", refer_loc, host) return self.set_CORS(CORS_header) try: content_type = self.headers.get('Content-Type', "") ctype, pdict = cgi.parse_header(content_type) if ctype == 'multipart/form-data': self.postvars = cgi.parse_multipart(self.rfile, pdict) elif ctype == 'application/x-www-form-urlencoded': length = int(self.headers.get('Content-Length')) content = self.rfile.read(length) self.postvars = parse_qs(content, keep_blank_values=True) self.postvars = self.unpack_reqs(self.postvars) elif ctype == 'application/json': length = int(self.headers.get('Content-Length')) content = self.rfile.read(length) self.postvars = json.loads(content) else: self.postvars = {} content = b'' except Exception as e: xlog.exception("do_POST %s except:%r", self.path, e) self.postvars = {} url_path_list = self.path.split('/') url_path = urlparse(self.path).path if len(url_path_list) >= 3 and url_path_list[1] == "module": module = url_path_list[2] if len(url_path_list) >= 4 and url_path_list[3] == "control": if module not in module_init.proc_handler: xlog.warn("request %s no module in path", self.path) return self.send_not_found() path = '/' + '/'.join(url_path_list[4:]) controler = module_init.proc_handler[module]["imp"].local.web_control. \ ControlHandler(self.client_address, self.headers, self.command, path, self.rfile, self.wfile) controler.set_CORS(self.res_headers) controler.postvars = utils.to_str(self.postvars) try: controler.do_POST() return except Exception as e: xlog.exception("POST %s except:%r", path, e) elif url_path == "/set_proxy_applist": return self.set_proxy_applist() elif url_path.startswith("/openai/"): status, res_headers, res_body = module_init.proc_handler["x_tunnel"]["imp"].local.openai_handler.handle_openai( "POST", url_path, self.headers, content, self.connection) return self.send_response(content=res_body, headers=res_headers, status=status) else: self.send_not_found() xlog.info('%s "%s %s HTTP/1.1" 404 -', self.address_string(), self.command, self.path) def do_GET(self): self.headers = utils.to_str(self.headers) self.path = utils.to_str(self.path) refer = self.headers.get('Referer') if refer: refer_loc = urlparse(refer).netloc host = self.headers.get('Host') if refer_loc != host and refer_loc not in config.allowed_refers: xlog.warn("web control ref:%s host:%s", refer_loc, host) return self.set_CORS(CORS_header) # check for '..', which will leak file if re.search(r'(\.{2})', self.path) is not None: self.wfile.write(b'HTTP/1.1 404\r\n\r\n') xlog.warn('%s %s %s haking', self.address_string(), self.command, self.path) return if config.webui_auth: auth = self.headers.get("Authorization") if not auth or not auth.startswith("Basic "): return self.send_response(content="", headers={ "WWW-Authenticate": 'Basic realm="Access to admin"' }, status=401) try: user_pass = base64.b64decode(auth[6:]) user_pass = utils.to_str(user_pass) user, password = user_pass.split(":")[0:2] except Exception as e: xlog.warn("decode auth fail:%r", e) return self.send_response(content="", headers={ "WWW-Authenticate": 'Basic realm="Access to admin"' }, status=401) if config.webui_auth.get(user) != password: return self.send_response(content="", headers={ "WWW-Authenticate": 'Basic realm="Access to admin"' }, status=401) url_path = urlparse(self.path).path if url_path == '/': return self.req_index_handler() url_path_list = self.path.split('/') if len(url_path_list) >= 3 and url_path_list[1] == "module": module = url_path_list[2] if len(url_path_list) >= 4 and url_path_list[3] == "control": if module not in module_init.proc_handler: xlog.warn("request %s no module in path", url_path) self.send_not_found() return if "imp" not in module_init.proc_handler[module]: xlog.warn("request module:%s start fail", module) self.send_not_found() return path = '/' + '/'.join(url_path_list[4:]) controler = module_init.proc_handler[module]["imp"].local.web_control.ControlHandler( self.client_address, self.headers, self.command, path, self.rfile, self.wfile) controler.set_CORS(self.res_headers) controler.do_GET() return else: relate_path = '/'.join(url_path_list[3:]) file_path = os.path.join(default_path, module, "web_ui", relate_path) if not os.path.isfile(file_path): return self.send_not_found() # i18n code lines (Both the locale dir & the template dir are module-dependent) locale_dir = os.path.abspath(os.path.join(default_path, module, 'lang')) content = i18n_translator.render(locale_dir, file_path) return self.send_response('text/html', content) else: file_path = os.path.join(current_path, 'web_ui' + url_path) if os.path.isfile(file_path): if file_path.endswith('.js'): mimetype = 'application/javascript' elif file_path.endswith('.css'): mimetype = 'text/css' elif file_path.endswith('.html'): mimetype = 'text/html' elif file_path.endswith('.jpg'): mimetype = 'image/jpeg' elif file_path.endswith('.png'): mimetype = 'image/png' else: mimetype = 'text/plain' self.send_file(file_path, mimetype) else: xlog.debug('launcher web_control %s %s %s ', self.address_string(), self.command, self.path) if url_path == '/config': self.req_config_handler() elif url_path == "/log": return self.req_log_handler() elif url_path == "/keep_log": return self.req_keep_log_handler() elif url_path == "/suck_threads": return self.req_suck_threads() elif url_path == "/hold_8085": return self.req_hold_8085() elif url_path == '/update': self.req_update_handler() elif url_path == '/config_proxy': self.req_config_proxy_handler() elif url_path == '/installed_app': self.req_get_installed_app() elif url_path == '/init_module': self.req_init_module_handler() elif url_path == '/quit': content = b'System: %s Exited successfully.' % utils.to_bytes(sys_platform.platform) try: self.send_response('text/html', content) self.wfile.flush() except: pass xlog.info("start quit") if sys_platform.platform in ["android", "ios"]: try: xlog.info("request http://localhost:8084/quit/") simple_http_client.request("GET", "http://localhost:8084/quit/", timeout=1) except Exception as e: xlog.warn("request http://localhost:8084/quit/ e:%r", e) pass sys_platform.on_quit() elif url_path == "/debug": self.req_debug_handler() elif url_path == "/log_files": self.req_log_files() elif url_path == "/mem_info": self.req_mem_info_handler() elif url_path == "/gc": self.req_gc_handler() elif url_path == '/restart': self.send_response('text/html', '{"status":"success"}') update_from_github.restart_xxnet() else: self.send_not_found() xlog.info('%s "%s %s HTTP/1.1" 404 -', self.address_string(), self.command, self.path) def req_index_handler(self): req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) try: target_module = reqs['module'][0] target_menu = reqs['menu'][0] except: if config.enable_x_tunnel: target_module = 'x_tunnel' target_menu = 'config' # elif config.get(['modules', 'smart_router', 'auto_start'], 0) == 1: # target_module = 'smart_router' # target_menu = 'config' elif config.enable_gae_proxy: target_module = 'gae_proxy' target_menu = 'status' else: target_module = 'launcher' target_menu = 'about' if len(module_menus) == 0: self.load_module_menus() # i18n code lines (Both the locale dir & the template dir are module-dependent) locale_dir = os.path.abspath(os.path.join(current_path, 'lang')) fn = os.path.join(current_path, "web_ui", "index.html") try: index_content = i18n_translator.render(locale_dir, fn) except Exception as e: xlog.warn("render %s except:%r", fn, e) return self.send_not_found() menu_content = b'' for module, v in module_menus: # xlog.debug("m:%s id:%d", module, v['menu_sort_id']) title = v["module_title"] menu_content += b'\n' % utils.to_bytes(title) for sub_id in v['sub_menus']: list_meta = b'' web_id = v['sub_menus'][sub_id].get("id") if web_id: list_meta += b' id="%s"' % sub_id sub_title = v['sub_menus'][sub_id]['title'] if "url" in v['sub_menus'][sub_id]: sub_url = v['sub_menus'][sub_id]['url'] if target_module == module and target_menu == sub_url: list_meta += b'class="active"' menu_content += b'
  • %s
  • \n' % utils.to_bytes( (list_meta, module, sub_url, sub_title)) elif "api_url" in v['sub_menus'][sub_id]: api_url = v['sub_menus'][sub_id]["api_url"] menu_content += b'
  • %s
  • \n' % utils.to_bytes( (list_meta, api_url, sub_title)) right_content_file = os.path.join(default_path, target_module, "web_ui", target_menu + ".html") if os.path.isfile(right_content_file): # i18n code lines (Both the locale dir & the template dir are module-dependent) locale_dir = os.path.abspath(os.path.join(default_path, target_module, 'lang')) right_content = i18n_translator.render(locale_dir, os.path.join(default_path, target_module, "web_ui", target_menu + ".html")) else: right_content = b"" data = index_content % (config.enable_gae_proxy, menu_content, right_content) self.send_response('text/html', data) def req_config_handler(self): req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) reqs = self.unpack_reqs(reqs) data = '' if reqs['cmd'] == 'get_config': if module_init.xargs.get("allow_remote", 0): allow_remote_connect = 1 else: allow_remote_connect = config.allow_remote_connect dat = { "platform": sys_platform.platform, "check_update": config.check_update, "language": config.language or i18n_translator.lang, "popup_webui": config.popup_webui, "allow_remote_connect": allow_remote_connect, "allow_remote_switch": config.allow_remote_connect, "show_systray": config.show_systray, "show_android_notification": config.show_android_notification, "auto_start": config.auto_start, "show_detail": config.gae_show_detail, "gae_proxy_enable": config.enable_gae_proxy, "x_tunnel_enable": config.enable_x_tunnel, "smart_router_enable": config.enable_smart_router, "system-proxy": config.os_proxy_mode, "show-compat-suggest": config.show_compat_suggest, "no_mess_system": config.no_mess_system, "keep_old_ver_num": config.keep_old_ver_num, "postUpdateStat": config.postUpdateStat, } data = json.dumps(dat) elif reqs['cmd'] == 'set_config': if 'skip_version' in reqs: skip_version = reqs['skip_version'] skip_version_type = reqs['skip_version_type'] if skip_version_type not in ["stable", "test"]: data = '{"res":"fail"}' else: setattr(config, "skip_%s_version" % skip_version_type, skip_version) config.save() if skip_version in update_from_github.update_info: update_from_github.update_info = '' data = '{"res":"success"}' elif 'check_update' in reqs: check_update = reqs['check_update'] if check_update not in ["dont-check", "stable", "notice-stable", "test", "notice-test"]: data = '{"res":"fail, check_update:%s"}' % check_update else: if config.check_update != check_update: update_from_github.init_update_info(check_update) config.check_update = check_update config.save() data = '{"res":"success"}' elif 'language' in reqs: language = reqs['language'] if language not in valid_language: data = '{"res":"fail, language:%s"}' % language else: config.language = language config.save() i18n_translator.lang = language self.load_module_menus() data = '{"res":"success"}' elif 'popup_webui' in reqs: popup_webui = int(reqs['popup_webui']) if popup_webui != 0 and popup_webui != 1: data = '{"res":"fail, popup_webui:%s"}' % popup_webui else: config.popup_webui = popup_webui config.save() data = '{"res":"success"}' elif 'allow_remote_switch' in reqs: allow_remote_switch = int(reqs['allow_remote_switch']) if allow_remote_switch != 0 and allow_remote_switch != 1: data = '{"res":"fail, allow_remote_connect:%s"}' % allow_remote_switch else: try: del module_init.xargs["allow_remote"] except: pass if allow_remote_switch: module_init.call_each_module("set_bind_ip", { "ip": "0.0.0.0" }) else: module_init.call_each_module("set_bind_ip", { "ip": "127.0.0.1" }) config.allow_remote_connect = allow_remote_switch config.save() xlog.debug("restart web control.") stop() module_init.stop_all() time.sleep(1) start(allow_remote_switch) module_init.start_all_auto() xlog.debug("launcher web control restarted.") data = '{"res":"success"}' elif 'show_systray' in reqs: show_systray = int(reqs['show_systray']) if show_systray != 0 and show_systray != 1: data = '{"res":"fail, show_systray:%s"}' % show_systray else: config.show_systray = show_systray config.save() data = '{"res":"success"}' elif 'show_android_notification' in reqs: show_android_notification = int(reqs['show_android_notification']) if show_android_notification != 0 and show_android_notification != 1: data = '{"res":"fail, show_systray:%s"}' % show_android_notification else: config.show_android_notification = show_android_notification config.save() data = '{"res":"success"}' elif 'show_compat_suggest' in reqs: show_compat_suggest = int(reqs['show_compat_suggest']) if show_compat_suggest != 0 and show_compat_suggest != 1: data = '{"res":"fail, show_compat_suggest:%s"}' % show_compat_suggest else: config.show_compat_suggest = show_compat_suggest config.save() data = '{"res":"success"}' elif 'no_mess_system' in reqs: no_mess_system = int(reqs['no_mess_system']) if no_mess_system != 0 and no_mess_system != 1: data = '{"res":"fail, no_mess_system:%s"}' % no_mess_system else: config.no_mess_system = no_mess_system config.save() data = '{"res":"success"}' elif 'keep_old_ver_num' in reqs: keep_old_ver_num = int(reqs['keep_old_ver_num']) if keep_old_ver_num < 0 or keep_old_ver_num > 99: data = '{"res":"fail, keep_old_ver_num:%s not in range 0 to 99"}' % keep_old_ver_num else: config.keep_old_ver_num = keep_old_ver_num config.save() data = '{"res":"success"}' elif 'auto_start' in reqs: auto_start = int(reqs['auto_start']) if auto_start != 0 and auto_start != 1: data = '{"res":"fail, auto_start:%s"}' % auto_start else: if auto_start: autorun.enable() else: autorun.disable() config.auto_start = auto_start config.save() data = '{"res":"success"}' elif 'show_detail' in reqs: show_detail = int(reqs['show_detail']) if show_detail != 0 and show_detail != 1: data = '{"res":"fail, show_detail:%s"}' % show_detail else: config.gae_show_detail = show_detail config.save() data = '{"res":"success"}' elif 'gae_proxy_enable' in reqs: gae_proxy_enable = int(reqs['gae_proxy_enable']) if gae_proxy_enable != 0 and gae_proxy_enable != 1: data = '{"res":"fail, gae_proxy_enable:%s"}' % gae_proxy_enable else: config.enable_gae_proxy = gae_proxy_enable config.save() if gae_proxy_enable: module_init.start("gae_proxy") else: module_init.stop("gae_proxy") if config.enable_smart_router: module_init.stop("smart_router") module_init.start("smart_router") self.load_module_menus() data = '{"res":"success"}' elif 'x_tunnel_enable' in reqs: x_tunnel_enable = int(reqs['x_tunnel_enable']) if x_tunnel_enable != 0 and x_tunnel_enable != 1: data = '{"res":"fail, x_tunnel_enable:%s"}' % x_tunnel_enable else: config.enable_x_tunnel = x_tunnel_enable config.save() if x_tunnel_enable: module_init.start("x_tunnel") else: module_init.stop("x_tunnel") self.load_module_menus() data = '{"res":"success"}' elif 'smart_router_enable' in reqs: smart_router_enable = int(reqs['smart_router_enable']) if smart_router_enable != 0 and smart_router_enable != 1: data = '{"res":"fail, smart_router_enable:%s"}' % smart_router_enable else: config.enable_smart_router = smart_router_enable config.save() if smart_router_enable: module_init.start("smart_router") else: module_init.stop("smart_router") self.load_module_menus() data = '{"res":"success"}' elif 'postUpdateStat' in reqs: postUpdateStat = reqs['postUpdateStat'] if postUpdateStat not in ["noChange", "isNew", "isPostUpdate"]: data = '{"res":"fail, postUpdateStat:%s"}' % postUpdateStat else: config.postUpdateStat = postUpdateStat config.save() data = '{"res":"success"}' else: data = '{"res":"fail"}' elif reqs['cmd'] == 'get_version': current_version = update_from_github.current_version() data = '{"current_version":"%s"}' % current_version self.send_response('text/html', data) def req_update_handler(self): req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) data = '' if reqs['cmd'] == ['get_info']: data = update_from_github.update_info if data == '' or data[0] != '{': data = '{"type":"%s"}' % data elif reqs['cmd'] == ['set_info']: update_from_github.update_info = reqs['info'] data = '{"res":"success"}' elif reqs['cmd'] == ['start_check']: update_from_github.init_update_info(reqs['check_update']) update.check_update() data = '{"res":"success"}' elif reqs['cmd'] == ['get_progress']: data = json.dumps(update_from_github.progress) elif reqs['cmd'] == ['get_new_version']: current_version = update_from_github.current_version() github_versions = update_from_github.get_github_versions() data = '{"res":"success", "test_version":"%s", "stable_version":"%s", "current_version":"%s"}' % ( github_versions[0][1], github_versions[1][1], current_version) xlog.info("%s", data) elif reqs['cmd'] == ['update_version']: version = reqs['version'] checkhash = 1 if 'checkhash' in reqs and reqs['checkhash'] == '0': checkhash = 0 update_from_github.start_update_version(version, checkhash) data = '{"res":"success"}' elif reqs['cmd'] == ['set_localversion']: version = reqs['version'] if update_from_github.update_current_version(version): data = '{"res":"success"}' else: data = '{"res":"false", "reason": "version not exist"}' elif reqs['cmd'] == ['get_localversions']: local_versions = update_from_github.get_local_versions() s = "" for v in local_versions: if not s == "": s += "," s += ' { "v":"%s" , "folder":"%s" } ' % (v[0], v[1]) data = '[ %s ]' % (s) elif reqs['cmd'] == ['del_localversion']: if update_from_github.del_version(reqs['version']): data = '{"res":"success"}' else: data = '{"res":"fail"}' self.send_response('text/html', data) def req_config_proxy_handler(self): req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) data = '' if reqs['cmd'] == ['get_config']: data = { "enable": config.global_proxy_enable, "type": config.global_proxy_type, "host": config.global_proxy_host, "port": config.global_proxy_port, "user": config.global_proxy_username, "passwd": config.global_proxy_password, } data = json.dumps(data) elif reqs['cmd'] == ['set_config']: enable = int(reqs['enable']) type = reqs['type'] host = reqs['host'] port = int(reqs['port']) user = reqs['user'] passwd = reqs['passwd'] if int(enable) and not test_proxy(type, host, port, user, passwd): return self.send_response('text/html', '{"res":"fail", "reason": "test proxy fail"}') config.global_proxy_enable = enable config.global_proxy_type = type config.global_proxy_host = host config.global_proxy_port = port config.global_proxy_username = user config.global_proxy_password = passwd config.save() module_init.call_each_module("set_proxy", { "enable": enable, "type": type, "host": host, "port": port, "user": user, "passwd": passwd }) data = '{"res":"success"}' self.send_response('text/html', data) def req_get_installed_app(self): if sys_platform.platform != 'android': # simulate data for developing data = { "proxy_by_app": config.proxy_by_app, "installed_app_list": [ { "name": "Test", "package": "com.test" },{ "name": "APP", "package": "com.app" },{ "name": "com.google.foundation.Foundation.Application.", "package": "com.google.application" } ] } time.sleep(5) else: res = simple_http_client.request("GET", "http://localhost:8084/installed_app_list/") data = json.loads(res.text) data["proxy_by_app"] = config.proxy_by_app for app in data["installed_app_list"]: package = app["package"] if package in config.enabled_app_list: app["enable"] = True else: app["enable"] = False if config.proxy_by_app: # Pass the config in html. content = '' else: content = '' for app in data["installed_app_list"]: if app["enable"]: checked = " checked " else: checked = "" content += '
    '\ + app["name"] \ + '
    \n'\ # jquery can't work on dynamic insert elements. # load html content from backend is the best way to make it works. return self.send_response("text/html", content) def set_proxy_applist(self): self.postvars = utils.to_str(self.postvars) xlog.debug("set_proxy_applist %r", self.postvars) config.proxy_by_app = int(self.postvars.get('proxy_by_app') == "true") config.enabled_app_list = self.postvars.get("enabled_app_list[]", []) xlog.debug("set_proxy_applist proxy_by_app:%s", config.proxy_by_app) xlog.debug("set_proxy_applist enabled_app_list:%s", config.enabled_app_list) config.save() data = { "res": "success" } self.send_response("text/html", json.dumps(data)) def req_init_module_handler(self): req = urlparse(self.path).query reqs = self.unpack_reqs(parse_qs(req, keep_blank_values=True)) data = '' try: module = reqs['module'] config.load() if reqs['cmd'] == 'start': result = module_init.start(module) data = '{ "module": "%s", "cmd": "start", "result": "%s" }' % (module, result) elif reqs['cmd'] == 'stop': result = module_init.stop(module) data = '{ "module": "%s", "cmd": "stop", "result": "%s" }' % (module, result) elif reqs['cmd'] == 'restart': result_stop = module_init.stop(module) result_start = module_init.start(module) data = '{ "module": "%s", "cmd": "restart", "stop_result": "%s", "start_result": "%s" }' % ( module, result_stop, result_start) except Exception as e: xlog.exception("init_module except:%s", e) self.send_response("text/html", data, headers={"Access-Control-Allow-Origin": "*"}) def req_keep_log_handler(self): keep_log() data = "Keep log success." mimetype = 'text/plain' self.send_response(mimetype, data) def req_suck_threads(self): self.send_response('text/plain', "Start suck threads") while True: threading.Thread(target=time.sleep, args=(1000,)).start() def req_hold_8085(self): global server self.send_response('text/plain', "Hold 8085") server.handler = FakeHttpHandler def req_log_handler(self): req = urlparse(self.path).query reqs = self.unpack_reqs(parse_qs(req, keep_blank_values=True)) data = '' if reqs["cmd"]: cmd = reqs["cmd"] else: cmd = "get_last" if cmd == "get_last": max_line = int(reqs["max_line"]) data = xlog.get_last_lines(max_line) elif cmd == "get_new": last_no = int(reqs["last_no"]) data = xlog.get_new_lines(last_no) else: xlog.error('xtunnel log cmd:%s', cmd) mimetype = 'text/plain' self.send_response(mimetype, data) def req_gc_handler(self): req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) import gc count = gc.get_count() if "collect" in reqs: gc.collect() self.send_response("text/plain", "gc collected, count:%d,%d,%d" % count) @staticmethod def list_fds(): """List process currently open FDs and their target """ if not sys.platform.startswith('linux'): return "" dat = "" base = '/proc/self/fd' of = list(os.listdir(base)) dat += "Num: %d\r\n" % (len(of)) for num in of: path = None try: path = os.readlink(os.path.join(base, num)) except OSError as err: # Last FD is always the "listdir" one (which may be closed) if err.errno != errno.ENOENT: path = str(err) except Exception as e: path = str(e) dat += " [%s]: %s\r\n" % (num, path) return dat def req_debug_handler(self): dat = "" try: dat += "Opened files: \r\n%s \r\n" % self.list_fds() dat += "thread num:%d\r\n" % threading.active_count() for thread in threading.enumerate(): dat += "\nThread: %s \r\n" % (thread.name) stack = sys._current_frames()[thread.ident] st = traceback.extract_stack(stack) stl = traceback.format_list(st) dat += " \n".join(stl) except Exception as e: xlog.exception("debug:%r", e) self.send_response("text/plain", dat) def req_log_files(self): # pack data folder and response x_tunnel_local = os.path.abspath(os.path.join(default_path, 'x_tunnel', 'local')) sys.path.append(x_tunnel_local) from upload_logs import pack_logs data = pack_logs(200 * 1024 * 1024) self.send_response("application/zip", data) def req_mem_info_handler(self): global mem_stat req = urlparse(self.path).query reqs = parse_qs(req, keep_blank_values=True) try: import tracemalloc import gc import os import linecache python_lib = os.path.dirname(os.__file__) gc.collect() if not mem_stat: tracemalloc.start() if not mem_stat or "reset" in reqs: mem_stat = tracemalloc.take_snapshot() snapshot = tracemalloc.take_snapshot() if "compare" in reqs: top_stats = snapshot.compare_to(mem_stat, 'traceback') else: top_stats = snapshot.statistics('traceback') dat = "" for stat in top_stats[:100]: print(("%s memory blocks: %.1f KiB" % (stat.count, stat.size / 1024))) lines = stat.traceback.format() ll = "\n".join(lines) ln = len(lines) pl = "" for i in range(ln, 0, -1): line = lines[i - 1] print(line) if line[8:].startswith(python_lib): break if not line.startswith(" File"): pl = line continue if not line[8:].startswith(default_path): break ll = line[8:] + "\n" + pl if ll[0] == "[": pass dat += "%d KB, count:%d %s\n" % (stat.size / 1024, stat.count, ll) if hasattr(threading, "_start_trace"): dat += "\n\nThread stat:\n" for path in threading._start_trace: n = threading._start_trace[path] if n <= 1: continue dat += "%s => %d\n\n" % (path, n) dat += "thread num:%d
    " % threading.active_count() self.send_response("text/plain", dat) except Exception as e: xlog.exception("debug:%r", e) self.send_response("text/html", "no mem_top") mem_stat = None def test_proxy(type, host, port, user, passwd): if not host: return False if host == "127.0.0.1": if port in [8087, 1080, 8086]: xlog.warn("set LAN Proxy to %s:%d fail.", host, port) return False client = simple_http_client.Client(proxy={ "type": type, "host": host, "port": int(port), "user": user if len(user) else None, "pass": passwd if len(passwd) else None }, timeout=3) urls = [ "https://www.microsoft.com", "https://www.apple.com", "https://code.jquery.com", "https://cdn.bootcss.com", "https://cdnjs.cloudflare.com"] for url in urls: header = { "user-agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36", "accept": "application/json, text/javascript, */*; q=0.01", "accept-encoding": "gzip, deflate, sdch", "accept-language": 'en-US,en;q=0.8,ja;q=0.6,zh-CN;q=0.4,zh;q=0.2', "connection": "keep-alive" } try: response = client.request("HEAD", url, header, "") if response: return True except Exception as e: xlog.exception("test_proxy %s fail:%r", url, e) pass return False server = None def start(allow_remote=0): global server # should use config.yaml to bind ip if not allow_remote: allow_remote = config.allow_remote_connect host_ip = config.control_ip host_port = config.control_port if allow_remote: xlog.info("allow remote access WebUI") listen_ips = [] if allow_remote and ("0.0.0.0" not in listen_ips or "::" not in listen_ips): listen_ips.append("0.0.0.0") else: if isinstance(host_ip, str): listen_ips = [host_ip] else: listen_ips = list(host_ip) addresses = [(listen_ip, host_port) for listen_ip in listen_ips] xlog.info("begin to start web control:%s", addresses) server = simple_http_server.HTTPServer(addresses, Http_Handler, logger=xlog, max_thread=2048) server.start() xlog.info("launcher web control started.") def stop(): global server xlog.info("begin to exit web control") server.shutdown() xlog.info("launcher web control exited.") def http_request(url, method="GET", timeout=30): proxy_handler = ProxyHandler({}) opener = build_opener(proxy_handler) try: req = opener.open(url, timeout=timeout) return req except Exception as e: # xlog.exception("web_control http_request:%s fail:%s", url, e) return False def confirm_xxnet_not_running(): # if xxnet is already running, try exit it is_xxnet_exit = False host_port = config.control_port req_url = "http://127.0.0.1:{port}/quit".format(port=host_port) xlog.debug("start confirm_xxnet_exit url:%s", req_url) for i in range(30): if http_request(req_url, timeout=5) == False: xlog.debug("good, xxnet:%s clear!" % host_port) is_xxnet_exit = True break else: xlog.debug("<%d>: try to terminate xxnet:%s" % (i, host_port)) time.sleep(1) xlog.debug("finished confirm_xxnet_exit") return is_xxnet_exit def confirm_module_ready(port): if port == 0: xlog.error("confirm_module_ready with port: 0") time.sleep(1) return False for i in range(200): req = http_request("http://127.0.0.1:%d/is_ready" % port) if req == False: time.sleep(1) continue content = req.read(1024) req.close() # xlog.debug("cert_import_ready return:%s", content) if content == "True": return True else: time.sleep(1) return False if __name__ == "__main__": pass # confirm_xxnet_exit() ================================================ FILE: code/default/launcher/web_ui/about.html ================================================

    {{ _( "Hello!" ) }}

    {{ _( "You seem to be on your first visit." ) }}

    {{ _( "Learn more" ) }}

    {{ _( "Version" ) }}
    {{ _( "Project main page" ) }}
    {{ _( "Official Web Site" ) }}
    {{ _( "Telegram group" ) }}
    {{ _( "Telegram Channel" ) }}
    {{ _( "Bug feedback" ) }}
    GitHub@XX-Net/Issues ({{ _( "When submitting a bug, please attach " ) }}{{ _( "the status page " ) }}{{ _( "info and " ) }}{{ _( "the log page " ) }}{{ _( "contents" ) }})
    Twitter
    {{ _( "Collect debug info" ) }}

    {{ _( "Thanks to the following projects" ) }}

    1. GoAgent
    2. fqrouter
    3. Xndroid
    4. goagentfindip
    5. GoGoTester
    6. EasyGoAgent
    7. Cloudflare
    8. Google
    ================================================ FILE: code/default/launcher/web_ui/config.html ================================================
    ================================================ FILE: code/default/launcher/web_ui/config_applist.html ================================================

    * {{ _( "Select which APP should be proxied. You need to restart VPN after change this." ) }}

    ================================================ FILE: code/default/launcher/web_ui/config_general.html ================================================
    {{ _( "Auto-Startup" ) }}
    {{ _( "Allow Remote" ) }}({{ _( "Help" ) }})
    {{ _( "Display System Tray(Restarting APP Required)" ) }}
    {{ _( "Display Notification" ) }}
    {{ _( "Display Windows software compatibility suggestions" ) }}({{ _( "Feedback" ) }})
    {{ _( "Run as Green Software" ) }}({{ _( "Help" ) }})
    ================================================ FILE: code/default/launcher/web_ui/config_proxy.html ================================================

    * {{ _( "Generally not needed, only those who need internal proxy to access the external network (companies, Intranet, campus, etc.) need to configure this." ) }}

    ================================================ FILE: code/default/launcher/web_ui/config_update.html ================================================


    ================================================ FILE: code/default/launcher/web_ui/css/bootstrap-responsive.css ================================================ /*! * Bootstrap Responsive v2.3.2 * * Copyright 2012 Twitter, Inc * Licensed under the Apache License v2.0 * http://www.apache.org/licenses/LICENSE-2.0 * * Designed and built with all the love in the world @twitter by @mdo and @fat. */ .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} ================================================ FILE: code/default/launcher/web_ui/css/bootstrap.css ================================================ .clearfix { *zoom: 1 } .clearfix:before,.clearfix:after { display: table; line-height: 0; content: "" } .clearfix:after { clear: both } .hide-text { font: 0/0 a; color: transparent; text-shadow: none; background-color: transparent; border: 0 } .input-block-level { display: block; width: 100%; min-height: 30px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box } article,aside,details,figcaption,figure,footer,header,hgroup,nav,section { display: block } audio,canvas,video { display: inline-block; *display: inline; *zoom: 1 } audio:not([controls]) { display: none } html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100% } a:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px } a:hover,a:active { outline: 0 } sub,sup { position: relative; font-size: 75%; line-height: 0; vertical-align: baseline } sup { top: -0.5em } sub { bottom: -0.25em } img { width: auto\9; height: auto; max-width: 100%; vertical-align: middle; border: 0; -ms-interpolation-mode: bicubic } #map_canvas img,.google-maps img { max-width: none } button,input,select,textarea { margin: 0; font-size: 100%; vertical-align: middle } button,input { *overflow: visible; line-height: normal } button::-moz-focus-inner,input::-moz-focus-inner { padding: 0; border: 0 } button,html input[type="button"],input[type="reset"],input[type="submit"] { cursor: pointer; -webkit-appearance: button } label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"] { cursor: pointer } input[type="search"] { -webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box; -webkit-appearance: textfield } input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none } textarea { overflow: auto; vertical-align: top } @media print { * { color: #000!important; text-shadow: none!important; background: transparent!important; box-shadow: none!important } a,a:visited { text-decoration: underline } a[href]:after { content: " (" attr(href) ")" } abbr[title]:after { content: " (" attr(title) ")" } .ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after { content: "" } pre,blockquote { border: 1px solid #999; page-break-inside: avoid } thead { display: table-header-group } tr,img { page-break-inside: avoid } img { max-width: 100%!important }@ page { margin: .5cm } p,h2,h3 { orphans: 3; widows: 3 } h2,h3 { page-break-after: avoid } } body { margin: 0; font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; font-size: 14px; line-height: 20px; color: #333; background-color: #fff } a { color: #08c; text-decoration: none } a:hover,a:focus { color: #005580; text-decoration: underline } .img-rounded { -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px } .img-polaroid { padding: 4px; background-color: #fff; border: 1px solid #ccc; border: 1px solid rgba(0,0,0,0.2); -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1); -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.1); box-shadow: 0 1px 3px rgba(0,0,0,0.1) } .img-circle { -webkit-border-radius: 500px; -moz-border-radius: 500px; border-radius: 500px } .row { margin-left: -20px; *zoom: 1 } .row:before,.row:after { display: table; line-height: 0; content: "" } .row:after { clear: both }[class*="span"] { float: left; min-height: 1px; margin-left: 20px } .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container { width: 940px } .span12 { width: 940px } .span11 { width: 860px } .span10 { width: 780px } .span9 { width: 700px } .span8 { width: 620px } .span7 { width: 540px } .span6 { width: 460px } .span5 { width: 380px } .span4 { width: 300px } .span3 { width: 220px } .span2 { width: 140px } .span1 { width: 60px } .offset12 { margin-left: 980px } .offset11 { margin-left: 900px } .offset10 { margin-left: 820px } .offset9 { margin-left: 740px } .offset8 { margin-left: 660px } .offset7 { margin-left: 580px } .offset6 { margin-left: 500px } .offset5 { margin-left: 420px } .offset4 { margin-left: 340px } .offset3 { margin-left: 260px } .offset2 { margin-left: 180px } .offset1 { margin-left: 100px } .row-fluid { width: 100%; *zoom: 1 } .row-fluid:before,.row-fluid:after { display: table; line-height: 0; content: "" } .row-fluid:after { clear: both } .row-fluid [class*="span"] { display: block; float: left; width: 100%; min-height: 30px; margin-left: 2.127659574468085%; *margin-left: 2.074468085106383%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box } .row-fluid [class*="span"]:first-child { margin-left: 0 } .row-fluid .controls-row [class*="span"]+[class*="span"] { margin-left: 2.127659574468085% } .row-fluid .span12 { width: 100%; *width: 99.94680851063829% } .row-fluid .span11 { width: 91.48936170212765%; *width: 91.43617021276594% } .row-fluid .span10 { width: 82.97872340425532%; *width: 82.92553191489361% } .row-fluid .span9 { width: 74.46808510638297%; *width: 74.41489361702126% } .row-fluid .span8 { width: 65.95744680851064%; *width: 65.90425531914893% } .row-fluid .span7 { width: 57.44680851063829%; *width: 57.39361702127659% } .row-fluid .span6 { width: 48.93617021276595%; *width: 48.88297872340425% } .row-fluid .span5 { width: 40.42553191489362%; *width: 40.37234042553192% } .row-fluid .span4 { width: 31.914893617021278%; *width: 31.861702127659576% } .row-fluid .span3 { width: 23.404255319148934%; *width: 23.351063829787233% } .row-fluid .span2 { width: 14.893617021276595%; *width: 14.840425531914894% } .row-fluid .span1 { width: 6.382978723404255%; *width: 6.329787234042553% } .row-fluid .offset12 { margin-left: 104.25531914893617%; *margin-left: 104.14893617021275% } .row-fluid .offset12:first-child { margin-left: 102.12765957446808%; *margin-left: 102.02127659574467% } .row-fluid .offset11 { margin-left: 95.74468085106382%; *margin-left: 95.6382978723404% } .row-fluid .offset11:first-child { margin-left: 93.61702127659574%; *margin-left: 93.51063829787232% } .row-fluid .offset10 { margin-left: 87.23404255319149%; *margin-left: 87.12765957446807% } .row-fluid .offset10:first-child { margin-left: 85.1063829787234%; *margin-left: 84.99999999999999% } .row-fluid .offset9 { margin-left: 78.72340425531914%; *margin-left: 78.61702127659572% } .row-fluid .offset9:first-child { margin-left: 76.59574468085106%; *margin-left: 76.48936170212764% } .row-fluid .offset8 { margin-left: 70.2127659574468%; *margin-left: 70.10638297872339% } .row-fluid .offset8:first-child { margin-left: 68.08510638297872%; *margin-left: 67.9787234042553% } .row-fluid .offset7 { margin-left: 61.70212765957446%; *margin-left: 61.59574468085106% } .row-fluid .offset7:first-child { margin-left: 59.574468085106375%; *margin-left: 59.46808510638297% } .row-fluid .offset6 { margin-left: 53.191489361702125%; *margin-left: 53.085106382978715% } .row-fluid .offset6:first-child { margin-left: 51.063829787234035%; *margin-left: 50.95744680851063% } .row-fluid .offset5 { margin-left: 44.68085106382979%; *margin-left: 44.57446808510638% } .row-fluid .offset5:first-child { margin-left: 42.5531914893617%; *margin-left: 42.4468085106383% } .row-fluid .offset4 { margin-left: 36.170212765957444%; *margin-left: 36.06382978723405% } .row-fluid .offset4:first-child { margin-left: 34.04255319148936%; *margin-left: 33.93617021276596% } .row-fluid .offset3 { margin-left: 27.659574468085104%; *margin-left: 27.5531914893617% } .row-fluid .offset3:first-child { margin-left: 25.53191489361702%; *margin-left: 25.425531914893618% } .row-fluid .offset2 { margin-left: 19.148936170212764%; *margin-left: 19.04255319148936% } .row-fluid .offset2:first-child { margin-left: 17.02127659574468%; *margin-left: 16.914893617021278% } .row-fluid .offset1 { margin-left: 10.638297872340425%; *margin-left: 10.53191489361702% } .row-fluid .offset1:first-child { margin-left: 8.51063829787234%; *margin-left: 8.404255319148938% }[class*="span"].hide,.row-fluid [class*="span"].hide { display: none }[class*="span"].pull-right,.row-fluid [class*="span"].pull-right { float: right } .container { margin-right: auto; margin-left: auto; *zoom: 1 } .container:before,.container:after { display: table; line-height: 0; content: "" } .container:after { clear: both } .container-fluid { padding-right: 20px; padding-left: 20px; *zoom: 1 } .container-fluid:before,.container-fluid:after { display: table; line-height: 0; content: "" } .container-fluid:after { clear: both } p { margin: 0 0 10px } .lead { margin-bottom: 20px; font-size: 21px; font-weight: 200; line-height: 30px } small { font-size: 85% } strong { font-weight: bold } em { font-style: italic } cite { font-style: normal } .muted { color: #999 } a.muted:hover,a.muted:focus { color: #808080 } .text-warning { color: #c09853 } a.text-warning:hover,a.text-warning:focus { color: #a47e3c } .text-error { color: #b94a48 } a.text-error:hover,a.text-error:focus { color: #953b39 } .text-info { color: #3a87ad } a.text-info:hover,a.text-info:focus { color: #2d6987 } .text-success { color: #468847 } a.text-success:hover,a.text-success:focus { color: #356635 } .text-left { text-align: left } .text-right { text-align: right } .text-center { text-align: center } h1,h2,h3,h4,h5,h6 { margin: 10px 0; font-family: inherit; font-weight: bold; line-height: 20px; color: inherit; text-rendering: optimizelegibility } h1 small,h2 small,h3 small,h4 small,h5 small,h6 small { font-weight: normal; line-height: 1; color: #999 } h1,h2,h3 { line-height: 40px } h1 { font-size: 38.5px } h2 { font-size: 31.5px } h3 { font-size: 24.5px } h4 { font-size: 17.5px } h5 { font-size: 14px } h6 { font-size: 11.9px } h1 small { font-size: 24.5px } h2 small { font-size: 17.5px } h3 small { font-size: 14px } h4 small { font-size: 14px } .page-header { padding-bottom: 9px; margin: 20px 0 30px; border-bottom: 1px solid #eee } ul,ol { padding: 0; margin: 0 0 10px 25px } ul ul,ul ol,ol ol,ol ul { margin-bottom: 0 } li { line-height: 20px } ul.unstyled,ol.unstyled { margin-left: 0; list-style: none } ul.inline,ol.inline { margin-left: 0; list-style: none } ul.inline>li,ol.inline>li { display: inline-block; *display: inline; padding-right: 5px; padding-left: 5px; *zoom: 1 } dl { margin-bottom: 20px } dt,dd { line-height: 20px } dt { font-weight: bold } dd { margin-left: 10px } .dl-horizontal { *zoom: 1 } .dl-horizontal:before,.dl-horizontal:after { display: table; line-height: 0; content: "" } .dl-horizontal:after { clear: both } .dl-horizontal dt { float: left; width: 160px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap } .dl-horizontal dd { margin-left: 180px } hr { margin: 20px 0; border: 0; border-top: 1px solid #eee; border-bottom: 1px solid #fff } abbr[title],abbr[data-original-title] { cursor: help; border-bottom: 1px dotted #999 } abbr.initialism { font-size: 90%; text-transform: uppercase } blockquote { padding: 0 0 0 15px; margin: 0 0 20px; border-left: 5px solid #eee } blockquote p { margin-bottom: 0; font-size: 17.5px; font-weight: 300; line-height: 1.25 } blockquote small { display: block; line-height: 20px; color: #999 } blockquote small:before { content: '\2014 \00A0' } blockquote.pull-right { float: right; padding-right: 15px; padding-left: 0; border-right: 5px solid #eee; border-left: 0 } blockquote.pull-right p,blockquote.pull-right small { text-align: right } blockquote.pull-right small:before { content: '' } blockquote.pull-right small:after { content: '\00A0 \2014' } q:before,q:after,blockquote:before,blockquote:after { content: "" } address { display: block; margin-bottom: 20px; font-style: normal; line-height: 20px } code,pre { padding: 0 3px 2px; font-family: Monaco,Menlo,Consolas,"Courier New",monospace; font-size: 12px; color: #333; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px } code { padding: 2px 4px; color: #d14; white-space: nowrap; background-color: #f7f7f9; border: 1px solid #e1e1e8 } pre { display: block; padding: 9.5px; margin: 0 0 10px; font-size: 13px; line-height: 20px; word-break: break-all; word-wrap: break-word; white-space: pre; white-space: pre-wrap; background-color: #f5f5f5; border: 1px solid #ccc; border: 1px solid rgba(0,0,0,0.15); -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px } pre.prettyprint { margin-bottom: 20px } pre code { padding: 0; color: inherit; white-space: pre; white-space: pre-wrap; background-color: transparent; border: 0 } .pre-scrollable { max-height: 340px; overflow-y: scroll } fieldset { padding: 0; margin: 0; border: 0 } legend { display: block; width: 100%; padding: 0; margin-bottom: 20px; font-size: 21px; line-height: 40px; color: #333; border: 0; border-bottom: 1px solid #e5e5e5 } legend small { font-size: 15px; color: #999 } label,input,button,select,textarea { font-size: 14px; font-weight: normal; line-height: 20px } input,button,select,textarea { font-family: "Microsoft YaHei","Sogoe UI",Arial,sans-serif } label { display: block; margin-bottom: 5px } select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input { display: inline-block; height: 20px; padding: 4px 6px; font-size: 14px; line-height: 20px; color: #555; vertical-align: middle; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px } input,textarea,.uneditable-input { width: 206px } textarea { height: auto } textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input { background-color: #fff; border: 1px solid #ccc; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); -webkit-transition: border linear .2s,box-shadow linear .2s; -moz-transition: border linear .2s,box-shadow linear .2s; -o-transition: border linear .2s,box-shadow linear .2s; transition: border linear .2s,box-shadow linear .2s } textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus { border-color: rgba(82,168,236,0.8); outline: 0; outline: thin dotted \9; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6); -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6); box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6) } input[type="radio"],input[type="checkbox"] { margin: 4px 0 0; margin-top: 1px \9; *margin-top: 0; line-height: normal } input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"] { width: auto } select,input[type="file"] { height: 30px; *margin-top: 4px; line-height: 30px } select { width: 220px; background-color: #fff; border: 1px solid #ccc } select[multiple],select[size] { height: auto } select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px } .uneditable-input,.uneditable-textarea { color: #999; cursor: not-allowed; background-color: #fcfcfc; border-color: #ccc; -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.025); box-shadow: inset 0 1px 2px rgba(0,0,0,0.025) } .uneditable-input { overflow: hidden; white-space: nowrap } .uneditable-textarea { width: auto; height: auto } input:-moz-placeholder,textarea:-moz-placeholder { color: #999 } input:-ms-input-placeholder,textarea:-ms-input-placeholder { color: #999 } input::-webkit-input-placeholder,textarea::-webkit-input-placeholder { color: #999 } .radio,.checkbox { min-height: 20px; padding-left: 20px } .radio input[type="radio"],.checkbox input[type="checkbox"] { float: left; margin-left: -20px } .controls>.radio:first-child,.controls>.checkbox:first-child { padding-top: 5px } .radio.inline,.checkbox.inline { display: inline-block; padding-top: 5px; margin-bottom: 0; vertical-align: middle } .radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline { margin-left: 10px } .input-mini { width: 60px } .input-small { width: 90px } .input-medium { width: 150px } .input-large { width: 210px } .input-xlarge { width: 270px } .input-xxlarge { width: 530px } input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"] { float: none; margin-left: 0 } .input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"] { display: inline-block } input,textarea,.uneditable-input { margin-left: 0 } .controls-row [class*="span"]+[class*="span"] { margin-left: 20px } input.span12,textarea.span12,.uneditable-input.span12 { width: 926px } input.span11,textarea.span11,.uneditable-input.span11 { width: 846px } input.span10,textarea.span10,.uneditable-input.span10 { width: 766px } input.span9,textarea.span9,.uneditable-input.span9 { width: 686px } input.span8,textarea.span8,.uneditable-input.span8 { width: 606px } input.span7,textarea.span7,.uneditable-input.span7 { width: 526px } input.span6,textarea.span6,.uneditable-input.span6 { width: 446px } input.span5,textarea.span5,.uneditable-input.span5 { width: 366px } input.span4,textarea.span4,.uneditable-input.span4 { width: 286px } input.span3,textarea.span3,.uneditable-input.span3 { width: 206px } input.span2,textarea.span2,.uneditable-input.span2 { width: 126px } input.span1,textarea.span1,.uneditable-input.span1 { width: 46px } .controls-row { *zoom: 1 } .controls-row:before,.controls-row:after { display: table; line-height: 0; content: "" } .controls-row:after { clear: both } .controls-row [class*="span"],.row-fluid .controls-row [class*="span"] { float: left } .controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"] { padding-top: 5px } input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly] { cursor: not-allowed; background-color: #eee } input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly] { background-color: transparent } .control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline { color: #c09853 } .control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea { color: #c09853 } .control-group.warning input,.control-group.warning select,.control-group.warning textarea { border-color: #c09853; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); box-shadow: inset 0 1px 1px rgba(0,0,0,0.075) } .control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus { border-color: #a47e3c; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e; -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e; box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e } .control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on { color: #c09853; background-color: #fcf8e3; border-color: #c09853 } .control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline { color: #b94a48 } .control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea { color: #b94a48 } .control-group.error input,.control-group.error select,.control-group.error textarea { border-color: #b94a48; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); box-shadow: inset 0 1px 1px rgba(0,0,0,0.075) } .control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus { border-color: #953b39; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392; -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392; box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392 } .control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on { color: #b94a48; background-color: #f2dede; border-color: #b94a48 } .control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline { color: #468847 } .control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea { color: #468847 } .control-group.success input,.control-group.success select,.control-group.success textarea { border-color: #468847; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); box-shadow: inset 0 1px 1px rgba(0,0,0,0.075) } .control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus { border-color: #356635; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b; -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b; box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b } .control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on { color: #468847; background-color: #dff0d8; border-color: #468847 } .control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline { color: #3a87ad } .control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea { color: #3a87ad } .control-group.info input,.control-group.info select,.control-group.info textarea { border-color: #3a87ad; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075); box-shadow: inset 0 1px 1px rgba(0,0,0,0.075) } .control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus { border-color: #2d6987; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3; -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3; box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3 } .control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on { color: #3a87ad; background-color: #d9edf7; border-color: #3a87ad } input:focus:invalid,textarea:focus:invalid,select:focus:invalid { color: #b94a48; border-color: #ee5f5b } input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus { border-color: #e9322d; -webkit-box-shadow: 0 0 6px #f8b9b7; -moz-box-shadow: 0 0 6px #f8b9b7; box-shadow: 0 0 6px #f8b9b7 } .form-actions { padding: 19px 20px 20px; margin-top: 20px; margin-bottom: 20px; background-color: #f5f5f5; border-top: 1px solid #e5e5e5; *zoom: 1 } .form-actions:before,.form-actions:after { display: table; line-height: 0; content: "" } .form-actions:after { clear: both } .help-block,.help-inline { color: #595959 } .help-block { display: block; margin-bottom: 10px } .help-inline { display: inline-block; *display: inline; padding-left: 5px; vertical-align: middle; *zoom: 1 } .input-append,.input-prepend { display: inline-block; margin-bottom: 10px; font-size: 0; white-space: nowrap; vertical-align: middle } .input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover { font-size: 14px } .input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input { position: relative; margin-bottom: 0; *margin-left: 0; vertical-align: top; -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0 } .input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus { z-index: 2 } .input-append .add-on,.input-prepend .add-on { display: inline-block; width: auto; height: 20px; min-width: 16px; padding: 4px 5px; font-size: 14px; font-weight: normal; line-height: 20px; text-align: center; text-shadow: 0 1px 0 #fff; background-color: #eee; border: 1px solid #ccc } .input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle { vertical-align: top; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0 } .input-append .active,.input-prepend .active { background-color: #a9dba9; border-color: #46a546 } .input-prepend .add-on,.input-prepend .btn { margin-right: -1px } .input-prepend .add-on:first-child,.input-prepend .btn:first-child { -webkit-border-radius: 4px 0 0 4px; -moz-border-radius: 4px 0 0 4px; border-radius: 4px 0 0 4px } .input-append input,.input-append select,.input-append .uneditable-input { -webkit-border-radius: 4px 0 0 4px; -moz-border-radius: 4px 0 0 4px; border-radius: 4px 0 0 4px } .input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child { -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0 } .input-append .add-on,.input-append .btn,.input-append .btn-group { margin-left: -1px } .input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle { -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0 } .input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input { -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0 } .input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn { -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0 } .input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child { margin-right: -1px; -webkit-border-radius: 4px 0 0 4px; -moz-border-radius: 4px 0 0 4px; border-radius: 4px 0 0 4px } .input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child { margin-left: -1px; -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0 } .input-prepend.input-append .btn-group:first-child { margin-left: 0 } input.search-query { padding-right: 14px; padding-right: 4px \9; padding-left: 14px; padding-left: 4px \9; margin-bottom: 0; -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px } .form-search .input-append .search-query,.form-search .input-prepend .search-query { -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0 } .form-search .input-append .search-query { -webkit-border-radius: 14px 0 0 14px; -moz-border-radius: 14px 0 0 14px; border-radius: 14px 0 0 14px } .form-search .input-append .btn { -webkit-border-radius: 0 14px 14px 0; -moz-border-radius: 0 14px 14px 0; border-radius: 0 14px 14px 0 } .form-search .input-prepend .search-query { -webkit-border-radius: 0 14px 14px 0; -moz-border-radius: 0 14px 14px 0; border-radius: 0 14px 14px 0 } .form-search .input-prepend .btn { -webkit-border-radius: 14px 0 0 14px; -moz-border-radius: 14px 0 0 14px; border-radius: 14px 0 0 14px } .form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append { display: inline-block; *display: inline; margin-bottom: 0; vertical-align: middle; *zoom: 1 } .form-search .hide,.form-inline .hide,.form-horizontal .hide { display: none } .form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group { display: inline-block } .form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend { margin-bottom: 0 } .form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox { padding-left: 0; margin-bottom: 0; vertical-align: middle } .form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"] { float: left; margin-right: 3px; margin-left: 0 } legend+.control-group { margin-top: 20px; -webkit-margin-top-collapse: separate } .form-horizontal .control-group { margin-bottom: 20px; *zoom: 1 } .form-horizontal .control-group:before,.form-horizontal .control-group:after { display: table; line-height: 0; content: "" } .form-horizontal .control-group:after { clear: both } .form-horizontal .control-label { float: left; width: 160px; padding-top: 5px; text-align: right } .form-horizontal .controls { *display: inline-block; *padding-left: 20px; margin-left: 180px; *margin-left: 0 } .form-horizontal .controls:first-child { *padding-left: 180px } .form-horizontal .help-block { margin-bottom: 0 } .form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block { margin-top: 10px } .form-horizontal .form-actions { padding-left: 180px } table { max-width: 100%; background-color: transparent; border-collapse: collapse; border-spacing: 0 } .table { width: 100%; margin-bottom: 20px } .table th,.table td { padding: 8px; line-height: 20px; text-align: left; vertical-align: top; border-top: 1px solid #ddd } .table th { font-weight: bold } .table thead th { vertical-align: bottom } .table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td { border-top: 0 } .table tbody+tbody { border-top: 2px solid #ddd } .table .table { background-color: #fff } .table-condensed th,.table-condensed td { padding: 4px 5px } .table-bordered { border: 1px solid #ddd; border-collapse: separate; *border-collapse: collapse; border-left: 0; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px } .table-bordered th,.table-bordered td { border-left: 1px solid #ddd } .table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td { border-top: 0 } .table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child { -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topleft: 4px } .table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child { -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-topright: 4px } .table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child { -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomleft: 4px } .table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child { -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; -moz-border-radius-bottomright: 4px } .table-bordered tfoot+tbody:last-child tr:last-child td:first-child { -webkit-border-bottom-left-radius: 0; border-bottom-left-radius: 0; -moz-border-radius-bottomleft: 0 } .table-bordered tfoot+tbody:last-child tr:last-child td:last-child { -webkit-border-bottom-right-radius: 0; border-bottom-right-radius: 0; -moz-border-radius-bottomright: 0 } .table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child { -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topleft: 4px } .table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child { -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-topright: 4px } .table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th { background-color: #f9f9f9 } .table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th { background-color: #f5f5f5 } table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"] { display: table-cell; float: none; margin-left: 0 } .table td.span1,.table th.span1 { float: none; width: 44px; margin-left: 0 } .table td.span2,.table th.span2 { float: none; width: 124px; margin-left: 0 } .table td.span3,.table th.span3 { float: none; width: 204px; margin-left: 0 } .table td.span4,.table th.span4 { float: none; width: 284px; margin-left: 0 } .table td.span5,.table th.span5 { float: none; width: 364px; margin-left: 0 } .table td.span6,.table th.span6 { float: none; width: 444px; margin-left: 0 } .table td.span7,.table th.span7 { float: none; width: 524px; margin-left: 0 } .table td.span8,.table th.span8 { float: none; width: 604px; margin-left: 0 } .table td.span9,.table th.span9 { float: none; width: 684px; margin-left: 0 } .table td.span10,.table th.span10 { float: none; width: 764px; margin-left: 0 } .table td.span11,.table th.span11 { float: none; width: 844px; margin-left: 0 } .table td.span12,.table th.span12 { float: none; width: 924px; margin-left: 0 } .table tbody tr.success>td { background-color: #dff0d8 } .table tbody tr.error>td { background-color: #f2dede } .table tbody tr.warning>td { background-color: #fcf8e3 } .table tbody tr.info>td { background-color: #d9edf7 } .table-hover tbody tr.success:hover>td { background-color: #d0e9c6 } .table-hover tbody tr.error:hover>td { background-color: #ebcccc } .table-hover tbody tr.warning:hover>td { background-color: #faf2cc } .table-hover tbody tr.info:hover>td { background-color: #c4e3f3 }[class^="icon-"],[class*=" icon-"] { display: inline-block; width: 14px; height: 14px; margin-top: 1px; *margin-right: .3em; line-height: 14px; vertical-align: text-top; background-image: url("../img/glyphicons-halflings.png"); background-position: 14px 14px; background-repeat: no-repeat } .icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"] { background-image: url("../img/glyphicons-halflings-white.png") } .icon-glass { background-position: 0 0 } .icon-music { background-position: -24px 0 } .icon-search { background-position: -48px 0 } .icon-envelope { background-position: -72px 0 } .icon-heart { background-position: -96px 0 } .icon-star { background-position: -120px 0 } .icon-star-empty { background-position: -144px 0 } .icon-user { background-position: -168px 0 } .icon-film { background-position: -192px 0 } .icon-th-large { background-position: -216px 0 } .icon-th { background-position: -240px 0 } .icon-th-list { background-position: -264px 0 } .icon-ok { background-position: -288px 0 } .icon-remove { background-position: -312px 0 } .icon-zoom-in { background-position: -336px 0 } .icon-zoom-out { background-position: -360px 0 } .icon-off { background-position: -384px 0 } .icon-signal { background-position: -408px 0 } .icon-cog { background-position: -432px 0 } .icon-trash { background-position: -456px 0 } .icon-home { background-position: 0 -24px } .icon-file { background-position: -24px -24px } .icon-time { background-position: -48px -24px } .icon-road { background-position: -72px -24px } .icon-download-alt { background-position: -96px -24px } .icon-download { background-position: -120px -24px } .icon-upload { background-position: -144px -24px } .icon-inbox { background-position: -168px -24px } .icon-play-circle { background-position: -192px -24px } .icon-repeat { background-position: -216px -24px } .icon-refresh { background-position: -240px -24px } .icon-list-alt { background-position: -264px -24px } .icon-lock { background-position: -287px -24px } .icon-flag { background-position: -312px -24px } .icon-headphones { background-position: -336px -24px } .icon-volume-off { background-position: -360px -24px } .icon-volume-down { background-position: -384px -24px } .icon-volume-up { background-position: -408px -24px } .icon-qrcode { background-position: -432px -24px } .icon-barcode { background-position: -456px -24px } .icon-tag { background-position: 0 -48px } .icon-tags { background-position: -25px -48px } .icon-book { background-position: -48px -48px } .icon-bookmark { background-position: -72px -48px } .icon-print { background-position: -96px -48px } .icon-camera { background-position: -120px -48px } .icon-font { background-position: -144px -48px } .icon-bold { background-position: -167px -48px } .icon-italic { background-position: -192px -48px } .icon-text-height { background-position: -216px -48px } .icon-text-width { background-position: -240px -48px } .icon-align-left { background-position: -264px -48px } .icon-align-center { background-position: -288px -48px } .icon-align-right { background-position: -312px -48px } .icon-align-justify { background-position: -336px -48px } .icon-list { background-position: -360px -48px } .icon-indent-left { background-position: -384px -48px } .icon-indent-right { background-position: -408px -48px } .icon-facetime-video { background-position: -432px -48px } .icon-picture { background-position: -456px -48px } .icon-pencil { background-position: 0 -72px } .icon-map-marker { background-position: -24px -72px } .icon-adjust { background-position: -48px -72px } .icon-tint { background-position: -72px -72px } .icon-edit { background-position: -96px -72px } .icon-share { background-position: -120px -72px } .icon-check { background-position: -144px -72px } .icon-move { background-position: -168px -72px } .icon-step-backward { background-position: -192px -72px } .icon-fast-backward { background-position: -216px -72px } .icon-backward { background-position: -240px -72px } .icon-play { background-position: -264px -72px } .icon-pause { background-position: -288px -72px } .icon-stop { background-position: -312px -72px } .icon-forward { background-position: -336px -72px } .icon-fast-forward { background-position: -360px -72px } .icon-step-forward { background-position: -384px -72px } .icon-eject { background-position: -408px -72px } .icon-chevron-left { background-position: -432px -72px } .icon-chevron-right { background-position: -456px -72px } .icon-plus-sign { background-position: 0 -96px } .icon-minus-sign { background-position: -24px -96px } .icon-remove-sign { background-position: -48px -96px } .icon-ok-sign { background-position: -72px -96px } .icon-question-sign { background-position: -96px -96px } .icon-info-sign { background-position: -120px -96px } .icon-screenshot { background-position: -144px -96px } .icon-remove-circle { background-position: -168px -96px } .icon-ok-circle { background-position: -192px -96px } .icon-ban-circle { background-position: -216px -96px } .icon-arrow-left { background-position: -240px -96px } .icon-arrow-right { background-position: -264px -96px } .icon-arrow-up { background-position: -289px -96px } .icon-arrow-down { background-position: -312px -96px } .icon-share-alt { background-position: -336px -96px } .icon-resize-full { background-position: -360px -96px } .icon-resize-small { background-position: -384px -96px } .icon-plus { background-position: -408px -96px } .icon-minus { background-position: -433px -96px } .icon-asterisk { background-position: -456px -96px } .icon-exclamation-sign { background-position: 0 -120px } .icon-gift { background-position: -24px -120px } .icon-leaf { background-position: -48px -120px } .icon-fire { background-position: -72px -120px } .icon-eye-open { background-position: -96px -120px } .icon-eye-close { background-position: -120px -120px } .icon-warning-sign { background-position: -144px -120px } .icon-plane { background-position: -168px -120px } .icon-calendar { background-position: -192px -120px } .icon-random { width: 16px; background-position: -216px -120px } .icon-comment { background-position: -240px -120px } .icon-magnet { background-position: -264px -120px } .icon-chevron-up { background-position: -288px -120px } .icon-chevron-down { background-position: -313px -119px } .icon-retweet { background-position: -336px -120px } .icon-shopping-cart { background-position: -360px -120px } .icon-folder-close { width: 16px; background-position: -384px -120px } .icon-folder-open { width: 16px; background-position: -408px -120px } .icon-resize-vertical { background-position: -432px -119px } .icon-resize-horizontal { background-position: -456px -118px } .icon-hdd { background-position: 0 -144px } .icon-bullhorn { background-position: -24px -144px } .icon-bell { background-position: -48px -144px } .icon-certificate { background-position: -72px -144px } .icon-thumbs-up { background-position: -96px -144px } .icon-thumbs-down { background-position: -120px -144px } .icon-hand-right { background-position: -144px -144px } .icon-hand-left { background-position: -168px -144px } .icon-hand-up { background-position: -192px -144px } .icon-hand-down { background-position: -216px -144px } .icon-circle-arrow-right { background-position: -240px -144px } .icon-circle-arrow-left { background-position: -264px -144px } .icon-circle-arrow-up { background-position: -288px -144px } .icon-circle-arrow-down { background-position: -312px -144px } .icon-globe { background-position: -336px -144px } .icon-wrench { background-position: -360px -144px } .icon-tasks { background-position: -384px -144px } .icon-filter { background-position: -408px -144px } .icon-briefcase { background-position: -432px -144px } .icon-fullscreen { background-position: -456px -144px } .dropup,.dropdown { position: relative } .dropdown-toggle { *margin-bottom: -3px } .dropdown-toggle:active,.open .dropdown-toggle { outline: 0 } .caret { display: inline-block; width: 0; height: 0; vertical-align: top; border-top: 4px solid #000; border-right: 4px solid transparent; border-left: 4px solid transparent; content: "" } .dropdown .caret { margin-top: 8px; margin-left: 2px } .dropdown-menu { position: absolute; top: 100%; left: 0; z-index: 1000; display: none; float: left; min-width: 160px; padding: 5px 0; margin: 2px 0 0; list-style: none; background-color: #fff; border: 1px solid #ccc; border: 1px solid rgba(0,0,0,0.2); *border-right-width: 2px; *border-bottom-width: 2px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.2); -moz-box-shadow: 0 5px 10px rgba(0,0,0,0.2); box-shadow: 0 5px 10px rgba(0,0,0,0.2); -webkit-background-clip: padding-box; -moz-background-clip: padding; background-clip: padding-box } .dropdown-menu.pull-right { right: 0; left: auto } .dropdown-menu .divider { *width: 100%; height: 1px; margin: 9px 1px; *margin: -5px 0 5px; overflow: hidden; background-color: #e5e5e5; border-bottom: 1px solid #fff } .dropdown-menu>li>a { display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: 20px; color: #333; white-space: nowrap } .dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a { color: #fff; text-decoration: none; background-color: #0081c2; background-image: -moz-linear-gradient(top,#08c,#0077b3); background-image: -webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3)); background-image: -webkit-linear-gradient(top,#08c,#0077b3); background-image: -o-linear-gradient(top,#08c,#0077b3); background-image: linear-gradient(to bottom,#08c,#0077b3); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0) } .dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus { color: #fff; text-decoration: none; background-color: #0081c2; background-image: -moz-linear-gradient(top,#08c,#0077b3); background-image: -webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3)); background-image: -webkit-linear-gradient(top,#08c,#0077b3); background-image: -o-linear-gradient(top,#08c,#0077b3); background-image: linear-gradient(to bottom,#08c,#0077b3); background-repeat: repeat-x; outline: 0; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0) } .dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus { color: #999 } .dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus { text-decoration: none; cursor: default; background-color: transparent; background-image: none; filter: progid:DXImageTransform.Microsoft.gradient(enabled=false) } .open { *z-index: 1000 } .open>.dropdown-menu { display: block } .dropdown-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 990 } .pull-right>.dropdown-menu { right: 0; left: auto } .dropup .caret,.navbar-fixed-bottom .dropdown .caret { border-top: 0; border-bottom: 4px solid #000; content: "" } .dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu { top: auto; bottom: 100%; margin-bottom: 1px } .dropdown-submenu { position: relative } .dropdown-submenu>.dropdown-menu { top: 0; left: 100%; margin-top: -6px; margin-left: -1px; -webkit-border-radius: 0 6px 6px 6px; -moz-border-radius: 0 6px 6px 6px; border-radius: 0 6px 6px 6px } .dropdown-submenu:hover>.dropdown-menu { display: block } .dropup .dropdown-submenu>.dropdown-menu { top: auto; bottom: 0; margin-top: 0; margin-bottom: -2px; -webkit-border-radius: 5px 5px 5px 0; -moz-border-radius: 5px 5px 5px 0; border-radius: 5px 5px 5px 0 } .dropdown-submenu>a:after { display: block; float: right; width: 0; height: 0; margin-top: 5px; margin-right: -10px; border-color: transparent; border-left-color: #ccc; border-style: solid; border-width: 5px 0 5px 5px; content: " " } .dropdown-submenu:hover>a:after { border-left-color: #fff } .dropdown-submenu.pull-left { float: none } .dropdown-submenu.pull-left>.dropdown-menu { left: -100%; margin-left: 10px; -webkit-border-radius: 6px 0 6px 6px; -moz-border-radius: 6px 0 6px 6px; border-radius: 6px 0 6px 6px } .dropdown .dropdown-menu .nav-header { padding-right: 20px; padding-left: 20px } .typeahead { z-index: 1051; margin-top: 2px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px } .well { min-height: 20px; padding: 19px; margin-bottom: 20px; background-color: #f5f5f5; border: 1px solid #e3e3e3; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.05); -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,0.05); box-shadow: inset 0 1px 1px rgba(0,0,0,0.05) } .well blockquote { border-color: #ddd; border-color: rgba(0,0,0,0.15) } .well-large { padding: 24px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px } .well-small { padding: 9px; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px } .fade { opacity: 0; -webkit-transition: opacity .15s linear; -moz-transition: opacity .15s linear; -o-transition: opacity .15s linear; transition: opacity .15s linear } .fade.in { opacity: 1 } .collapse { position: relative; height: 0; overflow: hidden; -webkit-transition: height .35s ease; -moz-transition: height .35s ease; -o-transition: height .35s ease; transition: height .35s ease } .collapse.in { height: auto } .close { float: right; font-size: 20px; font-weight: bold; line-height: 20px; color: #000; text-shadow: 0 1px 0 #fff; opacity: .2; filter: alpha(opacity=20) } .close:hover,.close:focus { color: #000; text-decoration: none; cursor: pointer; opacity: .4; filter: alpha(opacity=40) } button.close { padding: 0; cursor: pointer; background: transparent; border: 0; -webkit-appearance: none } .btn { color: #333; background-color: #fff; display: inline-block; padding: 6px 12px; margin-bottom: 0; font-size: 14px; font-weight: normal; line-height: 1.428571429; text-align: center; white-space: nowrap; vertical-align: middle; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; background-image: none; border: 1px solid #ccc; border-radius: 4px } .btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled] { color: #333; background-color: #ebebeb; border-color: #adadad } .btn:active,.btn.active { background-color: #ccc \9 } .btn:first-child { *margin-left: 0 } .btn:hover,.btn:focus { color: #333; text-decoration: none; background-position: 0 -15px; -webkit-transition: background-position .1s linear; -moz-transition: background-position .1s linear; -o-transition: background-position .1s linear; transition: background-position .1s linear } .btn:focus { outline: thin dotted #333; outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px } .btn.active,.btn:active { background-image: none; outline: 0; -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05); -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05); box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05) } .btn.disabled,.btn[disabled] { cursor: default; background-image: none; opacity: .65; filter: alpha(opacity=65); -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .btn-large { padding: 11px 19px; font-size: 17.5px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px } .btn-large [class^="icon-"],.btn-large [class*=" icon-"] { margin-top: 4px } .btn-small { padding: 2px 10px; font-size: 11.9px; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px } .btn-small [class^="icon-"],.btn-small [class*=" icon-"] { margin-top: 0 } .btn-mini [class^="icon-"],.btn-mini [class*=" icon-"] { margin-top: -1px } .btn-mini { padding: 0 6px; font-size: 10.5px; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px } .btn-block { display: block; width: 100%; padding-right: 0; padding-left: 0; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box } .btn-block+.btn-block { margin-top: 5px } input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block { width: 100% } .btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active { color: rgba(255,255,255,0.75) } .btn-primary { color: #fff; background: #1b93d1; border: 1px solid #15709e } .btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled] { color: #fff; background-color: #3276b1; border-color: #285e8e } .btn-primary:active,.btn-primary.active { background-color: #039 \9 } .btn-warning { color: #fff; background-color: #f0ad4e; border-color: #eea236 } .btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled] { color: #fff; background-color: #ed9c28; border-color: #d58512 } .btn-warning:active,.btn-warning.active { background-color: #c67605 \9 } .btn-danger { color: #fff; background-color: #d9534f; border-color: #d43f3a } .btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled] { color: #fff; background-color: #d2322d; border-color: #ac2925 } .btn-danger:active,.btn-danger.active { background-color: #942a25 \9 } .btn-success { color: #fff; background-color: #5cb85c; border-color: #4cae4c } .btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled] { color: #fff; background-color: #47a447; border-color: #398439 } .btn-success:active,.btn-success.active { background-color: #408140 \9 } .btn-info { color: #fff; background-color: #5bc0de; border-color: #46b8da } .btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled] { color: #fff; background-color: #39b3d7; border-color: #269abc } .btn-info:active,.btn-info.active { background-color: #24748c \9 } .btn-inverse { color: #fff; text-shadow: 0 -1px 0 rgba(0,0,0,0.25); background-color: #363636; *background-color: #222; background-image: -moz-linear-gradient(top,#444,#222); background-image: -webkit-gradient(linear,0 0,0 100%,from(#444),to(#222)); background-image: -webkit-linear-gradient(top,#444,#222); background-image: -o-linear-gradient(top,#444,#222); background-image: linear-gradient(to bottom,#444,#222); background-repeat: repeat-x; border-color: #222 #222 #000; border-color: rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false) } .btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled] { color: #fff; background-color: #222; *background-color: #151515 } .btn-inverse:active,.btn-inverse.active { background-color: #080808 \9 } button.btn,input[type="submit"].btn { *padding-top: 3px; *padding-bottom: 3px } button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner { padding: 0; border: 0 } button.btn.btn-large,input[type="submit"].btn.btn-large { *padding-top: 7px; *padding-bottom: 7px } button.btn.btn-small,input[type="submit"].btn.btn-small { *padding-top: 3px; *padding-bottom: 3px } button.btn.btn-mini,input[type="submit"].btn.btn-mini { *padding-top: 1px; *padding-bottom: 1px } .btn-link,.btn-link:active,.btn-link[disabled] { background-color: transparent; background-image: none; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .btn-link { color: #08c; cursor: pointer; border-color: transparent; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0 } .btn-link:hover,.btn-link:focus { color: #005580; text-decoration: underline; background-color: transparent } .btn-link[disabled]:hover,.btn-link[disabled]:focus { color: #333; text-decoration: none } .btn-group { position: relative; display: inline-block; *display: inline; *margin-left: .3em; font-size: 0; white-space: nowrap; vertical-align: middle; *zoom: 1 } .btn-group:first-child { *margin-left: 0 } .btn-group+.btn-group { margin-left: 5px } .btn-toolbar { margin-top: 10px; margin-bottom: 10px; font-size: 0 } .btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group { margin-left: 5px } .btn-group>.btn { position: relative; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0 } .btn-group>.btn+.btn { margin-left: -1px } .btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover { font-size: 14px } .btn-group>.btn-mini { font-size: 10.5px } .btn-group>.btn-small { font-size: 11.9px } .btn-group>.btn-large { font-size: 17.5px } .btn-group>.btn:first-child { margin-left: 0; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -moz-border-radius-topleft: 4px } .btn-group>.btn:last-child,.btn-group>.dropdown-toggle { -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; -moz-border-radius-topright: 4px; -moz-border-radius-bottomright: 4px } .btn-group>.btn.large:first-child { margin-left: 0; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -moz-border-radius-topleft: 6px } .btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle { -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; -moz-border-radius-topright: 6px; -moz-border-radius-bottomright: 6px } .btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active { z-index: 2 } .btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle { outline: 0 } .btn-group>.btn+.dropdown-toggle { *padding-top: 5px; padding-right: 8px; *padding-bottom: 5px; padding-left: 8px; -webkit-box-shadow: inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05); -moz-box-shadow: inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05); box-shadow: inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05) } .btn-group>.btn-mini+.dropdown-toggle { *padding-top: 2px; padding-right: 5px; *padding-bottom: 2px; padding-left: 5px } .btn-group>.btn-small+.dropdown-toggle { *padding-top: 5px; *padding-bottom: 4px } .btn-group>.btn-large+.dropdown-toggle { *padding-top: 7px; padding-right: 12px; *padding-bottom: 7px; padding-left: 12px } .btn-group.open .dropdown-toggle { background-image: none; -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05); -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05); box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05) } .btn-group.open .btn.dropdown-toggle { background-color: #e6e6e6 } .btn-group.open .btn-primary.dropdown-toggle { background-color: #04c } .btn-group.open .btn-warning.dropdown-toggle { background-color: #f89406 } .btn-group.open .btn-danger.dropdown-toggle { background-color: #bd362f } .btn-group.open .btn-success.dropdown-toggle { background-color: #51a351 } .btn-group.open .btn-info.dropdown-toggle { background-color: #2f96b4 } .btn-group.open .btn-inverse.dropdown-toggle { background-color: #222 } .btn .caret { margin-top: 8px; margin-left: 0 } .btn-large .caret { margin-top: 6px } .btn-large .caret { border-top-width: 5px; border-right-width: 5px; border-left-width: 5px } .btn-mini .caret,.btn-small .caret { margin-top: 8px } .dropup .btn-large .caret { border-bottom-width: 5px } .btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret { border-top-color: #fff; border-bottom-color: #fff } .btn-group-vertical { display: inline-block; *display: inline; *zoom: 1 } .btn-group-vertical>.btn { display: block; float: none; max-width: 100%; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0 } .btn-group-vertical>.btn+.btn { margin-top: -1px; margin-left: 0 } .btn-group-vertical>.btn:first-child { -webkit-border-radius: 4px 4px 0 0; -moz-border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0 } .btn-group-vertical>.btn:last-child { -webkit-border-radius: 0 0 4px 4px; -moz-border-radius: 0 0 4px 4px; border-radius: 0 0 4px 4px } .btn-group-vertical>.btn-large:first-child { -webkit-border-radius: 6px 6px 0 0; -moz-border-radius: 6px 6px 0 0; border-radius: 6px 6px 0 0 } .btn-group-vertical>.btn-large:last-child { -webkit-border-radius: 0 0 6px 6px; -moz-border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px } .alert { font-size: 13px; padding: 8px 35px 8px 14px; margin-bottom: 20px; text-shadow: 0 1px 0 rgba(255,255,255,0.5); background-color: #fcf8e3; border: 1px solid #fbeed5; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px } .alert,.alert h4 { color: #c09853 } .alert h4 { margin: 0 } .alert .close { position: relative; top: -2px; right: -21px; line-height: 20px } .alert-success { color: #468847; background-color: #dff0d8; border-color: #d6e9c6 } .alert-success h4 { color: #468847 } .alert-danger,.alert-error { color: #b94a48; background-color: #f2dede; border-color: #eed3d7 } .alert-danger h4,.alert-error h4 { color: #b94a48 } .alert-info { color: #3a87ad; background-color: #d9edf7; border-color: #bce8f1 } .alert-info h4 { color: #3a87ad } .alert-block { padding-top: 14px; padding-bottom: 14px } .alert-block>p,.alert-block>ul { margin-bottom: 0 } .alert-block p+p { margin-top: 5px } .nav { margin-left: 0; list-style: none } .nav>li>a { display: block } .nav>li>a:hover,.nav>li>a:focus { text-decoration: none; background-color: #eee } .nav>li>a>img { max-width: none } .nav>.pull-right { float: right } .nav-header { display: block; padding: 3px 15px; font-size: 11px; font-weight: bold; line-height: 20px; color: #999; text-shadow: 0 1px 0 rgba(255,255,255,0.5); text-transform: uppercase } .nav li+.nav-header { margin-top: 9px } .nav-list { padding-right: 15px; padding-left: 15px; margin-bottom: 0 } .nav-list>li>a,.nav-list .nav-header { margin-right: -15px; margin-left: -15px; text-shadow: 0 1px 0 rgba(255,255,255,0.5) } .nav-list>li>a { padding: 3px 15px } .nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus { color: #fff; text-shadow: 0 -1px 0 rgba(0,0,0,0.2); background-color: #08c } .nav-list [class^="icon-"],.nav-list [class*=" icon-"] { margin-right: 2px } .nav-list .divider { *width: 100%; height: 1px; margin: 9px 1px; *margin: -5px 0 5px; overflow: hidden; background-color: #e5e5e5; border-bottom: 1px solid #fff } .nav-tabs,.nav-pills { *zoom: 1 } .nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after { display: table; line-height: 0; content: "" } .nav-tabs:after,.nav-pills:after { clear: both } .nav-tabs>li,.nav-pills>li { float: left } .nav-tabs>li>a,.nav-pills>li>a { padding-right: 12px; padding-left: 12px; margin-right: 2px; line-height: 14px } .nav-tabs { border-bottom: 1px solid #ddd } .nav-tabs>li { margin-bottom: -1px } .nav-tabs>li>a { padding-top: 8px; padding-bottom: 8px; line-height: 20px; border: 1px solid transparent; -webkit-border-radius: 4px 4px 0 0; -moz-border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0 } .nav-tabs>li>a:hover,.nav-tabs>li>a:focus { border-color: #eee #eee #ddd } .nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus { color: #555; cursor: default; background-color: #fff; border: 1px solid #ddd; border-bottom-color: transparent } .nav-pills>li>a { padding-top: 8px; padding-bottom: 8px; margin-top: 2px; margin-bottom: 2px; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px } .nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus { color: #fff; background-color: #08c } .nav-stacked>li { float: none } .nav-stacked>li>a { margin-right: 0 } .nav-tabs.nav-stacked { border-bottom: 0 } .nav-tabs.nav-stacked>li>a { border: 1px solid #ddd; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0 } .nav-tabs.nav-stacked>li:first-child>a { -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -moz-border-radius-topleft: 4px } .nav-tabs.nav-stacked>li:last-child>a { -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -moz-border-radius-bottomleft: 4px } .nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus { z-index: 2; border-color: #ddd } .nav-pills.nav-stacked>li>a { margin-bottom: 3px } .nav-pills.nav-stacked>li:last-child>a { margin-bottom: 1px } .nav-tabs .dropdown-menu { -webkit-border-radius: 0 0 6px 6px; -moz-border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px } .nav-pills .dropdown-menu { -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px } .nav .dropdown-toggle .caret { margin-top: 6px; border-top-color: #08c; border-bottom-color: #08c } .nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret { border-top-color: #005580; border-bottom-color: #005580 } .nav-tabs .dropdown-toggle .caret { margin-top: 8px } .nav .active .dropdown-toggle .caret { border-top-color: #fff; border-bottom-color: #fff } .nav-tabs .active .dropdown-toggle .caret { border-top-color: #555; border-bottom-color: #555 } .nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus { cursor: pointer } .nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus { color: #fff; background-color: #999; border-color: #999 } .nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret { border-top-color: #fff; border-bottom-color: #fff; opacity: 1; filter: alpha(opacity=100) } .tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus { border-color: #999 } .tabbable { *zoom: 1 } .tabbable:before,.tabbable:after { display: table; line-height: 0; content: "" } .tabbable:after { clear: both } .tab-content { overflow: auto } .tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs { border-bottom: 0 } .tab-content>.tab-pane,.pill-content>.pill-pane { display: none; padding-left: 10px } .tab-content>.active,.pill-content>.active { display: block } .tabs-below>.nav-tabs { border-top: 1px solid #ddd } .tabs-below>.nav-tabs>li { margin-top: -1px; margin-bottom: 0 } .tabs-below>.nav-tabs>li>a { -webkit-border-radius: 0 0 4px 4px; -moz-border-radius: 0 0 4px 4px; border-radius: 0 0 4px 4px } .tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus { border-top-color: #ddd; border-bottom-color: transparent } .tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus { border-color: transparent #ddd #ddd #ddd } .tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li { float: none } .tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a { min-width: 74px; margin-right: 0; margin-bottom: 3px } .tabs-left>.nav-tabs { float: left; margin-right: 19px; border-right: 1px solid #ddd } .tabs-left>.nav-tabs>li>a { margin-right: -1px; -webkit-border-radius: 4px 0 0 4px; -moz-border-radius: 4px 0 0 4px; border-radius: 4px 0 0 4px } .tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus { border-color: #eee #ddd #eee #eee } .tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus { border-color: #ddd transparent #ddd #ddd; *border-right-color: #fff } .tabs-right>.nav-tabs { float: right; margin-left: 19px; border-left: 1px solid #ddd } .tabs-right>.nav-tabs>li>a { margin-left: -1px; -webkit-border-radius: 0 4px 4px 0; -moz-border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0 } .tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus { border-color: #eee #eee #eee #ddd } .tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus { border-color: #ddd #ddd #ddd transparent; *border-left-color: #fff } .nav>.disabled>a { color: #999 } .nav>.disabled>a:hover,.nav>.disabled>a:focus { text-decoration: none; cursor: default; background-color: transparent } .navbar { *position: relative; *z-index: 2; margin-bottom: 20px; overflow: visible } .navbar-inner { min-height: 40px; padding-right: 20px; padding-left: 20px; background-color: #fafafa; background-image: -moz-linear-gradient(top,#fff,#f2f2f2); background-image: -webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2)); background-image: -webkit-linear-gradient(top,#fff,#f2f2f2); background-image: -o-linear-gradient(top,#fff,#f2f2f2); background-image: linear-gradient(to bottom,#fff,#f2f2f2); background-repeat: repeat-x; border: 1px solid #d4d4d4; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0); *zoom: 1; -webkit-box-shadow: 0 1px 4px rgba(0,0,0,0.065); -moz-box-shadow: 0 1px 4px rgba(0,0,0,0.065); box-shadow: 0 1px 4px rgba(0,0,0,0.065) } .navbar-inner:before,.navbar-inner:after { display: table; line-height: 0; content: "" } .navbar-inner:after { clear: both } .navbar .container { width: auto } .nav-collapse.collapse { height: auto; overflow: visible } .navbar .brand { display: block; float: left; padding: 10px 20px 10px; margin-left: -20px; font-size: 20px; font-weight: 200; color: #777; text-shadow: 0 1px 0 #fff } .navbar .brand:hover,.navbar .brand:focus { text-decoration: none } .navbar-text { margin-bottom: 0; line-height: 40px; color: #777 } .navbar-link { color: #777 } .navbar-link:hover,.navbar-link:focus { color: #333 } .navbar .divider-vertical { height: 40px; margin: 0 9px; border-right: 1px solid #fff; border-left: 1px solid #f2f2f2 } .navbar .btn,.navbar .btn-group { margin-top: 5px } .navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group { margin-top: 0 } .navbar-form { margin-bottom: 0; *zoom: 1 } .navbar-form:before,.navbar-form:after { display: table; line-height: 0; content: "" } .navbar-form:after { clear: both } .navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox { margin-top: 5px } .navbar-form input,.navbar-form select,.navbar-form .btn { display: inline-block; margin-bottom: 0 } .navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"] { margin-top: 3px } .navbar-form .input-append,.navbar-form .input-prepend { margin-top: 5px; white-space: nowrap } .navbar-form .input-append input,.navbar-form .input-prepend input { margin-top: 0 } .navbar-search { position: relative; float: left; margin-top: 5px; margin-bottom: 0 } .navbar-search .search-query { padding: 4px 14px; margin-bottom: 0; font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; font-size: 13px; font-weight: normal; line-height: 1; -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px } .navbar-static-top { position: static; margin-bottom: 0 } .navbar-static-top .navbar-inner { -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0 } .navbar-fixed-top,.navbar-fixed-bottom { position: fixed; right: 0; left: 0; z-index: 1030; margin-bottom: 0 } .navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner { border-width: 0 0 1px } .navbar-fixed-bottom .navbar-inner { border-width: 1px 0 0 } .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner { padding-right: 0; padding-left: 0; -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0 } .navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container { width: 940px } .navbar-fixed-top { top: 0 } .navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner { -webkit-box-shadow: 0 1px 10px rgba(0,0,0,0.1); -moz-box-shadow: 0 1px 10px rgba(0,0,0,0.1); box-shadow: 0 1px 10px rgba(0,0,0,0.1) } .navbar-fixed-bottom { bottom: 0 } .navbar-fixed-bottom .navbar-inner { -webkit-box-shadow: 0 -1px 10px rgba(0,0,0,0.1); -moz-box-shadow: 0 -1px 10px rgba(0,0,0,0.1); box-shadow: 0 -1px 10px rgba(0,0,0,0.1) } .navbar .nav { position: relative; left: 0; display: block; float: left; margin: 0 10px 0 0 } .navbar .nav.pull-right { float: right; margin-right: 0 } .navbar .nav>li { float: left } .navbar .nav>li>a { float: none; padding: 10px 15px 10px; color: #777; text-decoration: none; text-shadow: 0 1px 0 #fff } .navbar .nav .dropdown-toggle .caret { margin-top: 8px } .navbar .nav>li>a:focus,.navbar .nav>li>a:hover { color: #333; text-decoration: none; background-color: transparent } .navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus { color: #555; text-decoration: none; background-color: #e5e5e5; -webkit-box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); -moz-box-shadow: inset 0 3px 8px rgba(0,0,0,0.125); box-shadow: inset 0 3px 8px rgba(0,0,0,0.125) } .navbar .btn-navbar { display: none; float: right; padding: 7px 10px; margin-right: 5px; margin-left: 5px; color: #fff; text-shadow: 0 -1px 0 rgba(0,0,0,0.25); background-color: #ededed; *background-color: #e5e5e5; background-image: -moz-linear-gradient(top,#f2f2f2,#e5e5e5); background-image: -webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5)); background-image: -webkit-linear-gradient(top,#f2f2f2,#e5e5e5); background-image: -o-linear-gradient(top,#f2f2f2,#e5e5e5); background-image: linear-gradient(to bottom,#f2f2f2,#e5e5e5); background-repeat: repeat-x; border-color: #e5e5e5 #e5e5e5 #bfbfbf; border-color: rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075); -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075); box-shadow: inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075) } .navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled] { color: #fff; background-color: #e5e5e5; *background-color: #d9d9d9 } .navbar .btn-navbar:active,.navbar .btn-navbar.active { background-color: #ccc \9 } .navbar .btn-navbar .icon-bar { display: block; width: 18px; height: 2px; background-color: #f5f5f5; -webkit-border-radius: 1px; -moz-border-radius: 1px; border-radius: 1px; -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.25); -moz-box-shadow: 0 1px 0 rgba(0,0,0,0.25); box-shadow: 0 1px 0 rgba(0,0,0,0.25) } .btn-navbar .icon-bar+.icon-bar { margin-top: 3px } .navbar .nav>li>.dropdown-menu:before { position: absolute; top: -7px; left: 9px; display: inline-block; border-right: 7px solid transparent; border-bottom: 7px solid #ccc; border-left: 7px solid transparent; border-bottom-color: rgba(0,0,0,0.2); content: '' } .navbar .nav>li>.dropdown-menu:after { position: absolute; top: -6px; left: 10px; display: inline-block; border-right: 6px solid transparent; border-bottom: 6px solid #fff; border-left: 6px solid transparent; content: '' } .navbar-fixed-bottom .nav>li>.dropdown-menu:before { top: auto; bottom: -7px; border-top: 7px solid #ccc; border-bottom: 0; border-top-color: rgba(0,0,0,0.2) } .navbar-fixed-bottom .nav>li>.dropdown-menu:after { top: auto; bottom: -6px; border-top: 6px solid #fff; border-bottom: 0 } .navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret { border-top-color: #333; border-bottom-color: #333 } .navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle { color: #555; background-color: #e5e5e5 } .navbar .nav li.dropdown>.dropdown-toggle .caret { border-top-color: #777; border-bottom-color: #777 } .navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret { border-top-color: #555; border-bottom-color: #555 } .navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right { right: 0; left: auto } .navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before { right: 12px; left: auto } .navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after { right: 13px; left: auto } .navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu { right: 100%; left: auto; margin-right: -1px; margin-left: 0; -webkit-border-radius: 6px 0 6px 6px; -moz-border-radius: 6px 0 6px 6px; border-radius: 6px 0 6px 6px } .navbar-inverse .navbar-inner { background-color: #1b1b1b; background-image: -moz-linear-gradient(top,#222,#111); background-image: -webkit-gradient(linear,0 0,0 100%,from(#222),to(#111)); background-image: -webkit-linear-gradient(top,#222,#111); background-image: -o-linear-gradient(top,#222,#111); background-image: linear-gradient(to bottom,#222,#111); background-repeat: repeat-x; border-color: #252525; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0) } .navbar-inverse .brand,.navbar-inverse .nav>li>a { color: #999; text-shadow: 0 -1px 0 rgba(0,0,0,0.25) } .navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus { color: #fff } .navbar-inverse .brand { color: #999 } .navbar-inverse .navbar-text { color: #999 } .navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover { color: #fff; background-color: transparent } .navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus { color: #fff; background-color: #111 } .navbar-inverse .navbar-link { color: #999 } .navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus { color: #fff } .navbar-inverse .divider-vertical { border-right-color: #222; border-left-color: #111 } .navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle { color: #fff; background-color: #111 } .navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret { border-top-color: #fff; border-bottom-color: #fff } .navbar-inverse .nav li.dropdown>.dropdown-toggle .caret { border-top-color: #999; border-bottom-color: #999 } .navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret { border-top-color: #fff; border-bottom-color: #fff } .navbar-inverse .navbar-search .search-query { color: #fff; background-color: #515151; border-color: #111; -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15); -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15); box-shadow: inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15); -webkit-transition: none; -moz-transition: none; -o-transition: none; transition: none } .navbar-inverse .navbar-search .search-query:-moz-placeholder { color: #ccc } .navbar-inverse .navbar-search .search-query:-ms-input-placeholder { color: #ccc } .navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { color: #ccc } .navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused { padding: 5px 15px; color: #333; text-shadow: 0 1px 0 #fff; background-color: #fff; border: 0; outline: 0; -webkit-box-shadow: 0 0 3px rgba(0,0,0,0.15); -moz-box-shadow: 0 0 3px rgba(0,0,0,0.15); box-shadow: 0 0 3px rgba(0,0,0,0.15) } .navbar-inverse .btn-navbar { color: #fff; text-shadow: 0 -1px 0 rgba(0,0,0,0.25); background-color: #0e0e0e; *background-color: #040404; background-image: -moz-linear-gradient(top,#151515,#040404); background-image: -webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404)); background-image: -webkit-linear-gradient(top,#151515,#040404); background-image: -o-linear-gradient(top,#151515,#040404); background-image: linear-gradient(to bottom,#151515,#040404); background-repeat: repeat-x; border-color: #040404 #040404 #000; border-color: rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false) } .navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled] { color: #fff; background-color: #040404; *background-color: #000 } .navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active { background-color: #000 \9 } .breadcrumb { background-color: #f5f5f5; margin: 0 0 20px; list-style: none; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px } .breadcrumb>li { display: inline-block; *display: inline; text-shadow: 0 1px 0 #fff; *zoom: 1 } .breadcrumb>li>.divider { padding: 0 5px; color: #ccc } .breadcrumb>.active { color: #999 } .pagination { margin: 20px 0 } .pagination ul { display: inline-block; *display: inline; margin-bottom: 0; margin-left: 0; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; *zoom: 1; -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.05); -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.05); box-shadow: 0 1px 2px rgba(0,0,0,0.05) } .pagination ul>li { display: inline } .pagination ul>li>a,.pagination ul>li>span { float: left; padding: 4px 12px; line-height: 20px; text-decoration: none; background-color: #fff; border: 1px solid #ddd; border-left-width: 0 } .pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span { background-color: #f5f5f5 } .pagination ul>.active>a,.pagination ul>.active>span { color: #999; cursor: default } .pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus { color: #999; cursor: default; background-color: transparent } .pagination ul>li:first-child>a,.pagination ul>li:first-child>span { border-left-width: 1px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -moz-border-radius-topleft: 4px } .pagination ul>li:last-child>a,.pagination ul>li:last-child>span { -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; -moz-border-radius-topright: 4px; -moz-border-radius-bottomright: 4px } .pagination-centered { text-align: center } .pagination-right { text-align: right } .pagination-large ul>li>a,.pagination-large ul>li>span { padding: 11px 19px; font-size: 17.5px } .pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span { -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -moz-border-radius-topleft: 6px } .pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span { -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; -moz-border-radius-topright: 6px; -moz-border-radius-bottomright: 6px } .pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span { -webkit-border-bottom-left-radius: 3px; border-bottom-left-radius: 3px; -webkit-border-top-left-radius: 3px; border-top-left-radius: 3px; -moz-border-radius-bottomleft: 3px; -moz-border-radius-topleft: 3px } .pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span { -webkit-border-top-right-radius: 3px; border-top-right-radius: 3px; -webkit-border-bottom-right-radius: 3px; border-bottom-right-radius: 3px; -moz-border-radius-topright: 3px; -moz-border-radius-bottomright: 3px } .pagination-small ul>li>a,.pagination-small ul>li>span { padding: 2px 10px; font-size: 11.9px } .pagination-mini ul>li>a,.pagination-mini ul>li>span { padding: 0 6px; font-size: 10.5px } .pager { margin: 20px 0; text-align: center; list-style: none; *zoom: 1 } .pager:before,.pager:after { display: table; line-height: 0; content: "" } .pager:after { clear: both } .pager li { display: inline } .pager li>a,.pager li>span { display: inline-block; padding: 5px 14px; background-color: #fff; border: 1px solid #ddd; -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px } .pager li>a:hover,.pager li>a:focus { text-decoration: none; background-color: #f5f5f5 } .pager .next>a,.pager .next>span { float: right } .pager .previous>a,.pager .previous>span { float: left } .pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span { color: #999; cursor: default; background-color: #fff } .modal-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1040; background-color: #000 } .modal-backdrop.fade { opacity: 0 } .modal-backdrop,.modal-backdrop.fade.in { opacity: .8; filter: alpha(opacity=80) } .modal { position: absolute; top: 10%; left: 15%; right: 15%; margin: auto; z-index: 1050; width: 560px; background-color: #fff; border: 1px solid #999; border: 1px solid rgba(0,0,0,0.3); *border: 1px solid #999; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; outline: 0; -webkit-box-shadow: 0 3px 7px rgba(0,0,0,0.3); -moz-box-shadow: 0 3px 7px rgba(0,0,0,0.3); box-shadow: 0 3px 7px rgba(0,0,0,0.3); -webkit-background-clip: padding-box; -moz-background-clip: padding-box; background-clip: padding-box } .modal.fade { top: -25%; -webkit-transition: opacity .3s linear,top .3s ease-out; -moz-transition: opacity .3s linear,top .3s ease-out; -o-transition: opacity .3s linear,top .3s ease-out; transition: opacity .3s linear,top .3s ease-out } .modal.fade.in { top: 10% } .modal-header { padding: 9px 15px; border-bottom: 1px solid #eee } .modal-header .close { margin-top: 2px } .modal-header h3 { margin: 0; line-height: 30px } .modal-body { position: relative; padding: 15px; overflow: auto } .modal-form { margin-bottom: 0 } .modal-footer { padding: 14px 15px 15px; margin-bottom: 0; text-align: right; background-color: #f5f5f5; border-top: 1px solid #ddd; -webkit-border-radius: 0 0 6px 6px; -moz-border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px; *zoom: 1; -webkit-box-shadow: inset 0 1px 0 #fff; -moz-box-shadow: inset 0 1px 0 #fff; box-shadow: inset 0 1px 0 #fff } .modal-footer:before,.modal-footer:after { display: table; line-height: 0; content: "" } .modal-footer:after { clear: both } .modal-footer .btn+.btn { margin-bottom: 0; margin-left: 5px } .modal-footer .btn-group .btn+.btn { margin-left: -1px } .modal-footer .btn-block+.btn-block { margin-left: 0 } .tooltip { position: absolute; z-index: 1030; display: block; font-size: 11px; line-height: 1.4; opacity: 0; filter: alpha(opacity=0); visibility: visible } .tooltip.in { opacity: .8; filter: alpha(opacity=80) } .tooltip.top { padding: 5px 0; margin-top: -3px } .tooltip.right { padding: 0 5px; margin-left: 3px } .tooltip.bottom { padding: 5px 0; margin-top: 3px } .tooltip.left { padding: 0 5px; margin-left: -3px } .tooltip-inner { max-width: 200px; padding: 8px; color: #fff; text-align: center; text-decoration: none; background-color: #000; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px } .tooltip-arrow { position: absolute; width: 0; height: 0; border-color: transparent; border-style: solid } .tooltip.top .tooltip-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-color: #000; border-width: 5px 5px 0 } .tooltip.right .tooltip-arrow { top: 50%; left: 0; margin-top: -5px; border-right-color: #000; border-width: 5px 5px 5px 0 } .tooltip.left .tooltip-arrow { top: 50%; right: 0; margin-top: -5px; border-left-color: #000; border-width: 5px 0 5px 5px } .tooltip.bottom .tooltip-arrow { top: 0; left: 50%; margin-left: -5px; border-bottom-color: #000; border-width: 0 5px 5px } .popover { position: absolute; top: 0; left: 0; z-index: 1010; display: none; max-width: 276px; padding: 1px; text-align: left; white-space: normal; background-color: #fff; border: 1px solid #ccc; border: 1px solid rgba(0,0,0,0.2); -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; -webkit-box-shadow: 0 5px 10px rgba(0,0,0,0.2); -moz-box-shadow: 0 5px 10px rgba(0,0,0,0.2); box-shadow: 0 5px 10px rgba(0,0,0,0.2); -webkit-background-clip: padding-box; -moz-background-clip: padding; background-clip: padding-box } .popover.top { margin-top: -10px } .popover.right { margin-left: 10px } .popover.bottom { margin-top: 10px } .popover.left { margin-left: -10px } .popover-title { padding: 8px 14px; margin: 0; font-size: 14px; font-weight: normal; line-height: 18px; background-color: #f7f7f7; border-bottom: 1px solid #ebebeb; -webkit-border-radius: 5px 5px 0 0; -moz-border-radius: 5px 5px 0 0; border-radius: 5px 5px 0 0 } .popover-title:empty { display: none } .popover-content { padding: 9px 14px } .popover .arrow,.popover .arrow:after { position: absolute; display: block; width: 0; height: 0; border-color: transparent; border-style: solid } .popover .arrow { border-width: 11px } .popover .arrow:after { border-width: 10px; content: "" } .popover.top .arrow { bottom: -11px; left: 50%; margin-left: -11px; border-top-color: #999; border-top-color: rgba(0,0,0,0.25); border-bottom-width: 0 } .popover.top .arrow:after { bottom: 1px; margin-left: -10px; border-top-color: #fff; border-bottom-width: 0 } .popover.right .arrow { top: 50%; left: -11px; margin-top: -11px; border-right-color: #999; border-right-color: rgba(0,0,0,0.25); border-left-width: 0 } .popover.right .arrow:after { bottom: -10px; left: 1px; border-right-color: #fff; border-left-width: 0 } .popover.bottom .arrow { top: -11px; left: 50%; margin-left: -11px; border-bottom-color: #999; border-bottom-color: rgba(0,0,0,0.25); border-top-width: 0 } .popover.bottom .arrow:after { top: 1px; margin-left: -10px; border-bottom-color: #fff; border-top-width: 0 } .popover.left .arrow { top: 50%; right: -11px; margin-top: -11px; border-left-color: #999; border-left-color: rgba(0,0,0,0.25); border-right-width: 0 } .popover.left .arrow:after { right: 1px; bottom: -10px; border-left-color: #fff; border-right-width: 0 } .thumbnails { margin-left: -20px; list-style: none; *zoom: 1 } .thumbnails:before,.thumbnails:after { display: table; line-height: 0; content: "" } .thumbnails:after { clear: both } .row-fluid .thumbnails { margin-left: 0 } .thumbnails>li { float: left; margin-bottom: 20px; margin-left: 20px } .thumbnail { display: block; padding: 4px; line-height: 20px; border: 1px solid #ddd; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.055); -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.055); box-shadow: 0 1px 3px rgba(0,0,0,0.055); -webkit-transition: all .2s ease-in-out; -moz-transition: all .2s ease-in-out; -o-transition: all .2s ease-in-out; transition: all .2s ease-in-out } a.thumbnail:hover,a.thumbnail:focus { border-color: #08c; -webkit-box-shadow: 0 1px 4px rgba(0,105,214,0.25); -moz-box-shadow: 0 1px 4px rgba(0,105,214,0.25); box-shadow: 0 1px 4px rgba(0,105,214,0.25) } .thumbnail>img { display: block; max-width: 100%; margin-right: auto; margin-left: auto } .thumbnail .caption { padding: 9px; color: #555 } .media,.media-body { overflow: hidden; *overflow: visible; zoom: 1 } .media,.media .media { margin-top: 15px } .media:first-child { margin-top: 0 } .media-object { display: block } .media-heading { margin: 0 0 5px } .media>.pull-left { margin-right: 10px } .media>.pull-right { margin-left: 10px } .media-list { margin-left: 0; list-style: none } .label,.badge { display: inline-block; padding: 2px 4px; font-size: 11.844px; font-weight: bold; line-height: 14px; color: #fff; text-shadow: 0 -1px 0 rgba(0,0,0,0.25); white-space: nowrap; vertical-align: baseline; background-color: #999 } .label { -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px } .badge { padding-right: 9px; padding-left: 9px; -webkit-border-radius: 9px; -moz-border-radius: 9px; border-radius: 9px } .label:empty,.badge:empty { display: none } a.label:hover,a.label:focus,a.badge:hover,a.badge:focus { color: #fff; text-decoration: none; cursor: pointer } .label-important,.badge-important { background-color: #b94a48 } .label-important[href],.badge-important[href] { background-color: #953b39 } .label-warning,.badge-warning { background-color: #f89406 } .label-warning[href],.badge-warning[href] { background-color: #c67605 } .label-success,.badge-success { background-color: #468847 } .label-success[href],.badge-success[href] { background-color: #356635 } .label-info,.badge-info { background-color: #3a87ad } .label-info[href],.badge-info[href] { background-color: #2d6987 } .label-inverse,.badge-inverse { background-color: #333 } .label-inverse[href],.badge-inverse[href] { background-color: #1a1a1a } .btn .label,.btn .badge { position: relative; top: -1px } .btn-mini .label,.btn-mini .badge { top: 0 } @-webkit-keyframes progress-bar-stripes { from { background-position: 40px 0 } to { background-position: 0 0 } } @-moz-keyframes progress-bar-stripes { from { background-position: 40px 0 } to { background-position: 0 0 } } @-ms-keyframes progress-bar-stripes { from { background-position: 40px 0 } to { background-position: 0 0 } } @-o-keyframes progress-bar-stripes { from { background-position: 0 0 } to { background-position: 40px 0 } } @keyframes progress-bar-stripes { from { background-position: 40px 0 } to { background-position: 0 0 } } .progress { height: 20px; margin-bottom: 20px; overflow: hidden; background-color: #f7f7f7; background-image: -moz-linear-gradient(top,#f5f5f5,#f9f9f9); background-image: -webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9)); background-image: -webkit-linear-gradient(top,#f5f5f5,#f9f9f9); background-image: -o-linear-gradient(top,#f5f5f5,#f9f9f9); background-image: linear-gradient(to bottom,#f5f5f5,#f9f9f9); background-repeat: repeat-x; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0); -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); -moz-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); box-shadow: inset 0 1px 2px rgba(0,0,0,0.1) } .progress .bar { float: left; width: 0; height: 100%; font-size: 12px; color: #fff; text-align: center; text-shadow: 0 -1px 0 rgba(0,0,0,0.25); background-color: #0e90d2; background-image: -moz-linear-gradient(top,#149bdf,#0480be); background-image: -webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be)); background-image: -webkit-linear-gradient(top,#149bdf,#0480be); background-image: -o-linear-gradient(top,#149bdf,#0480be); background-image: linear-gradient(to bottom,#149bdf,#0480be); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0); -webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); -moz-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); box-shadow: inset 0 -1px 0 rgba(0,0,0,0.15); -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; -webkit-transition: width .6s ease; -moz-transition: width .6s ease; -o-transition: width .6s ease; transition: width .6s ease } .progress .bar+.bar { -webkit-box-shadow: inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15); -moz-box-shadow: inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15); box-shadow: inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15) } .progress-striped .bar { background-color: #149bdf; background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent)); background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); -webkit-background-size: 40px 40px; -moz-background-size: 40px 40px; -o-background-size: 40px 40px; background-size: 40px 40px } .progress.active .bar { -webkit-animation: progress-bar-stripes 2s linear infinite; -moz-animation: progress-bar-stripes 2s linear infinite; -ms-animation: progress-bar-stripes 2s linear infinite; -o-animation: progress-bar-stripes 2s linear infinite; animation: progress-bar-stripes 2s linear infinite } .progress-danger .bar,.progress .bar-danger { background-color: #dd514c; background-image: -moz-linear-gradient(top,#ee5f5b,#c43c35); background-image: -webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35)); background-image: -webkit-linear-gradient(top,#ee5f5b,#c43c35); background-image: -o-linear-gradient(top,#ee5f5b,#c43c35); background-image: linear-gradient(to bottom,#ee5f5b,#c43c35); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0) } .progress-danger.progress-striped .bar,.progress-striped .bar-danger { background-color: #ee5f5b; background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent)); background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent) } .progress-success .bar,.progress .bar-success { background-color: #5eb95e; background-image: -moz-linear-gradient(top,#62c462,#57a957); background-image: -webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957)); background-image: -webkit-linear-gradient(top,#62c462,#57a957); background-image: -o-linear-gradient(top,#62c462,#57a957); background-image: linear-gradient(to bottom,#62c462,#57a957); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0) } .progress-success.progress-striped .bar,.progress-striped .bar-success { background-color: #62c462; background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent)); background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent) } .progress-info .bar,.progress .bar-info { background-color: #4bb1cf; background-image: -moz-linear-gradient(top,#5bc0de,#339bb9); background-image: -webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9)); background-image: -webkit-linear-gradient(top,#5bc0de,#339bb9); background-image: -o-linear-gradient(top,#5bc0de,#339bb9); background-image: linear-gradient(to bottom,#5bc0de,#339bb9); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0) } .progress-info.progress-striped .bar,.progress-striped .bar-info { background-color: #5bc0de; background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent)); background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent) } .progress-warning .bar,.progress .bar-warning { background-color: #faa732; background-image: -moz-linear-gradient(top,#fbb450,#f89406); background-image: -webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406)); background-image: -webkit-linear-gradient(top,#fbb450,#f89406); background-image: -o-linear-gradient(top,#fbb450,#f89406); background-image: linear-gradient(to bottom,#fbb450,#f89406); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0) } .progress-warning.progress-striped .bar,.progress-striped .bar-warning { background-color: #fbb450; background-image: -webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent)); background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: -moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: -o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent); background-image: linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent) } .accordion { margin-bottom: 20px } .accordion-group { margin-bottom: 2px; border: 1px solid #e5e5e5; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px } .accordion-heading { border-bottom: 0 } .accordion-heading .accordion-toggle { display: block; padding: 8px 15px } .accordion-toggle { cursor: pointer } .accordion-inner { padding: 9px 15px; border-top: 1px solid #e5e5e5 } .carousel { position: relative; line-height: 1 } .carousel-inner { position: relative; width: 100%; overflow: hidden } .carousel-inner>.item { position: relative; display: none; -webkit-transition: .6s ease-in-out left; -moz-transition: .6s ease-in-out left; -o-transition: .6s ease-in-out left; transition: .6s ease-in-out left } .carousel-inner>.item>img,.carousel-inner>.item>a>img { display: block; margin: 0 auto; line-height: 1 } .carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev { display: block } .carousel-inner>.active { left: 0 } .carousel-inner>.next,.carousel-inner>.prev { position: absolute; top: 0; width: 100% } .carousel-inner>.next { left: 100% } .carousel-inner>.prev { left: -100% } .carousel-inner>.next.left,.carousel-inner>.prev.right { left: 0 } .carousel-inner>.active.left { left: -100% } .carousel-inner>.active.right { left: 100% } .carousel-control { position: absolute; top: 40%; left: 15px; width: 40px; height: 40px; margin-top: -20px; font-size: 60px; font-weight: 100; line-height: 30px; color: #fff; text-align: center; background: #222; border: 3px solid #fff; -webkit-border-radius: 23px; -moz-border-radius: 23px; border-radius: 23px; opacity: .5; filter: alpha(opacity=50) } .carousel-control.right { right: 15px; left: auto } .carousel-control:hover,.carousel-control:focus { color: #fff; text-decoration: none; opacity: .9; filter: alpha(opacity=90) } .carousel-indicators { cursor: pointer; position: absolute; bottom: 15px; right: 15px; z-index: 5; margin: 0; list-style: none } .carousel-indicators li { display: block; float: left; width: 10px; height: 10px; margin-left: 5px; text-indent: -999px; background-color: #ccc; background-color: rgba(255,255,255,0.25); border-radius: 5px } .carousel-indicators .active { background-color: #fff } .carousel-caption { position: absolute; right: 0; bottom: 0; left: 0; padding: 15px; background: #333; background: rgba(0,0,0,0.75) } .carousel-caption h4,.carousel-caption p { line-height: 20px; color: #fff } .carousel-caption h4 { margin: 0 0 5px } .carousel-caption p { margin-bottom: 0 } .hero-unit { padding: 35px; margin-bottom: 30px; font-size: 18px; font-weight: 200; line-height: 30px; color: inherit; background-color: #eee; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px } .hero-unit h1 { margin-top: 10px; margin-bottom: 10px; font-size: 45px; line-height: 1.1; letter-spacing: -1px; color: inherit } .hero-unit p { margin-top: 5px; margin-bottom: 5px; line-height: 1.1; } .hero-unit .btn { margin-top: 10px; margin-bottom: 0; } .hero-unit li { line-height: 30px } .pull-right { float: right } .pull-left { float: left } .hide { display: none } .show { display: block } .invisible { visibility: hidden } .affix { position: fixed } ================================================ FILE: code/default/launcher/web_ui/css/flat-ui.css ================================================ /*! * Flat UI Free v2.0.0 (http://designmodo.github.io/Flat-UI/) * Copyright 2013-2014 Designmodo, Inc. */ .fui-arrow-right,.fui-arrow-left,.fui-cmd,.fui-check-inverted,.fui-heart,.fui-location,.fui-plus,.fui-check,.fui-cross,.fui-list,.fui-new,.fui-video,.fui-photo,.fui-volume,.fui-time,.fui-eye,.fui-chat,.fui-search,.fui-user,.fui-mail,.fui-lock,.fui-gear,.fui-radio-unchecked,.fui-radio-checked,.fui-checkbox-unchecked,.fui-checkbox-checked,.fui-calendar-solid,.fui-pause,.fui-play,.fui-check-inverted-2 { display: inline-block; font-family: 'Flat-UI-Icons'; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased } .fui-arrow-right:before { content: "\e02c" } .fui-arrow-left:before { content: "\e02d" } .fui-cmd:before { content: "\e02f" } .fui-check-inverted:before { content: "\e006" } .fui-heart:before { content: "\e007" } .fui-location:before { content: "\e008" } .fui-plus:before { content: "\e009" } .fui-check:before { content: "\e00a" } .fui-cross:before { content: "\e00b" } .fui-list:before { content: "\e00c" } .fui-new:before { content: "\e00d" } .fui-video:before { content: "\e00e" } .fui-photo:before { content: "\e00f" } .fui-volume:before { content: "\e010" } .fui-time:before { content: "\e011" } .fui-eye:before { content: "\e012" } .fui-chat:before { content: "\e013" } .fui-search:before { content: "\e01c" } .fui-user:before { content: "\e01d" } .fui-mail:before { content: "\e01e" } .fui-lock:before { content: "\e01f" } .fui-gear:before { content: "\e024" } .fui-radio-unchecked:before { content: "\e02b" } .fui-radio-checked:before { content: "\e032" } .fui-checkbox-unchecked:before { content: "\e033" } .fui-checkbox-checked:before { content: "\e034" } .fui-calendar-solid:before { content: "\e022" } .fui-pause:before { content: "\e03b" } .fui-play:before { content: "\e03c" } .fui-check-inverted-2:before { content: "\e000" } .inline-block { display: inline-block; zoom: 1; *display: inline } .clearfix { *zoom: 1 } .clearfix:before,.clearfix:after { display: table; content: "" } .clearfix:after { clear: both } .drop-ie-gradient { filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)") } .dropdown-arrow-inverse { border-bottom-color: #34495e!important; border-top-color: #34495e!important } .demo-headline { padding: 73px 0 110px; text-align: center } .demo-logo { font-size: 90px; font-weight: 900; letter-spacing: -2px; line-height: 100px } .demo-logo .logo { background: url(../img/demo/logo-mask.png) center 0 no-repeat; background-size: 256px 186px; height: 186px; margin: 0 auto 26px; overflow: hidden; text-indent: -9999em; width: 256px } .demo-logo small { color: rgba(52,73,94,0.30000000000000004); display: block; font-size: 22px; font-weight: 700; letter-spacing: -1px; padding-top: 5px } .demo-row { margin-bottom: 20px } .demo-panel-title { margin-bottom: 20px; padding-top: 20px } .demo-panel-title small { color: #798795; font-size: inherit; font-weight: 400 } .demo-navigation { margin-bottom: -4px; margin-top: -10px } .demo-pager { margin-top: -10px } .demo-tooltips { height: 126px } .demo-tooltips .tooltip { left: -8px!important; position: relative!important; top: -8px!important } .demo-headings { margin-bottom: 12px } .demo-tiles { margin-bottom: 46px } .demo-icons { font-size: 32px; margin-left: -15px } .demo-icons .demo-content { margin: 0 0 0 -36px } .demo-icons .demo-content>span { display: inline-block; margin: 0 0 32px 36px; width: 24px; font-size: 24px } .demo-icons-tooltip { bottom: 0; color: #c2c8cf; font-size: 12px; left: 100%; margin-left: 0!important; position: absolute; width: 80px } .demo-illustrations { margin-top: 40px; *zoom: 1 } .demo-illustrations:before,.demo-illustrations:after { display: table; content: "" } .demo-illustrations:after { clear: both } .demo-illustrations .demo-content { margin: 0 0 0 -40px; padding-top: 20px } .demo-illustrations .demo-content>div { float: left; width: 100px; height: 100px; margin: 0 0 80px 40px; text-align: center } .demo-illustrations img { display: inline-block; max-height: 100px; max-width: 100px; vertical-align: baseline } .demo-samples { margin-bottom: 46px } .demo-video { padding-top: 95px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px } .demo-download-section { float: none; margin: 0 auto; padding: 60px 0 90px 20px; text-align: center } .demo-download-section [class*='fui-'] { margin: 3px 0 -3px } .demo-download { background-color: #ebedef; height: 120px; margin: 0 auto 32px; padding: 40px 28px 30px 32px; text-align: center; width: 130px; -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50% } .demo-download img { height: 104px; width: 82px } .demo-download-text { font-size: 15px; padding: 20px 0; text-align: center } .demo-text-box a:hover { color: #1abc9c } .demo-browser { background: #2c3e50 url(../img/demo/browser.png) 0 0 no-repeat; background-size: 659px 42px; color: #fff; margin: 0 41px 140px 0; padding-top: 42px; -webkit-border-radius: 0 0 6px 6px; -moz-border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px } .demo-browser-side { float: left; padding: 22px 20px; width: 111px } .demo-browser-side>h5 { margin-bottom: 3px; text-transform: none } .demo-browser-side>h6 { font-size: 11px; font-weight: 300; line-height: 18px; margin-top: 3px; text-transform: none } .demo-browser-author { background: url(../img/demo/browser-author.jpg) center center no-repeat; border: 3px solid #fff; display: block; height: 84px; margin: 0 auto; width: 84px; -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50% } .demo-browser-action { padding: 30px 0 12px } .demo-browser-action>.btn { padding: 9px 0 10px 11px!important; text-align: left; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px } .demo-browser-action>.btn:before { color: #fff; content: '\e009'; font-size: 16px; font-family: 'Flat-UI-Icons'; font-weight: 300; margin-right: 12px; position: relative; top: 1px; -webkit-font-smoothing: antialiased } .demo-browser-content { background-color: #34495e; overflow: hidden; padding: 21px 0 0 20px; -webkit-border-radius: 0 0 6px; -moz-border-radius: 0 0 6px; border-radius: 0 0 6px } .demo-browser-content>img { border: 6px solid #fff; float: left; margin: 0 15px 20px 0; width: 134px } @media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (-moz-min-device-pixel-ratio:2),only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-o-min-device-pixel-ratio:2/1),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:2) { .logo { background-image: url(../img/demo/logo-mask-2x.png) } .demo-browser { background-image: url(../img/demo/browser-2x.png) } } body { color: #34495e; font-family: "Lato",sans-serif; font-size: 14px; line-height: 1.231 } input,button,select,textarea { font-family: "Lato",sans-serif; font-size: 14px } a { color: #08c; text-decoration: underline; -webkit-transition: .25s; -moz-transition: .25s; -o-transition: .25s; transition: .25s; -webkit-backface-visibility: hidden } a:hover { color: #333; text-decoration: none } h1 { font-size: 32px; font-weight: 900 } h2 { font-size: 26px; font-weight: 700; margin-bottom: 2px } h3 { font-size: 24px; font-weight: 700; margin-bottom: 4px; margin-top: 2px } h4 { font-size: 18px; font-weight: 500; margin-top: 4px } h5 { font-size: 16px; font-weight: 500; text-transform: uppercase } h6 { font-size: 13px; font-weight: 500; text-transform: uppercase } .btn,.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover { font-size: 14.994px; font-weight: 500 } .btn { border: 0; background: #bdc3c7; color: #fff; padding: 9px 12px 10px; line-height: 22px; text-decoration: none; text-shadow: none; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; -webkit-transition: .25s; -moz-transition: .25s; -o-transition: .25s; transition: .25s; -webkit-backface-visibility: hidden } .btn:hover,.btn:focus,.btn-group:focus .btn.dropdown-toggle { background-color: #cacfd2; color: #fff; outline: 0; -webkit-transition: .25s; -moz-transition: .25s; -o-transition: .25s; transition: .25s; -webkit-backface-visibility: hidden } .btn:active,.btn-group.open .btn.dropdown-toggle,.btn.active { background-color: #a1a6a9; color: rgba(255,255,255,0.75); -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .btn.disabled,.btn[disabled] { background-color: #bdc3c7; color: rgba(255,255,255,0.75); -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; opacity: .7; filter: alpha(opacity=70) } .btn.btn-large { font-size: 16.996px; line-height: 20px; padding: 12px 18px 13px } .btn.btn-large>[class^="fui-"] { top: 0 } .btn.btn-large>[class^="fui-"].pull-right { margin-right: -2px } .btn.btn-primary { background-color: #1b93d1; } .btn.btn-primary:hover, .btn.btn-primary:focus, .btn-group:focus .btn.btn-primary.dropdown-toggle { background-color: #3276b1; } .btn.btn-primary:active, .btn-group.open .btn.btn-primary.dropdown-toggle, .btn.btn-primary.active { background-color: #039; } .btn.btn-info { background-color: #3498db } .btn.btn-info:hover,.btn.btn-info:focus,.btn-group:focus .btn.btn-info.dropdown-toggle { background-color: #5dade2 } .btn.btn-info:active,.btn-group.open .btn.btn-info.dropdown-toggle,.btn.btn-info.active { background-color: #2c81ba } .btn.btn-danger { background-color: #e74c3c } .btn.btn-danger:hover,.btn.btn-danger:focus,.btn-group:focus .btn.btn-danger.dropdown-toggle { background-color: #ec7063 } .btn.btn-danger:active,.btn-group.open .btn.btn-danger.dropdown-toggle,.btn.btn-danger.active { background-color: #c44133 } .btn.btn-success { background-color: #2ecc71 } .btn.btn-success:hover,.btn.btn-success:focus,.btn-group:focus .btn.btn-success.dropdown-toggle { background-color: #58d68d } .btn.btn-success:active,.btn-group.open .btn.btn-success.dropdown-toggle,.btn.btn-success.active { background-color: #27ad60 } .btn.btn-warning { background-color: #f1c40f } .btn.btn-warning:hover,.btn.btn-warning:focus,.btn-group:focus .btn.btn-warning.dropdown-toggle { background-color: #f5d313 } .btn.btn-warning:active,.btn-group.open .btn.btn-warning.dropdown-toggle,.btn.btn-warning.active { background-color: #cda70d } .btn.btn-inverse { background-color: #34495e } .btn.btn-inverse:hover,.btn.btn-inverse:focus,.btn-group:focus .btn.btn-inverse.dropdown-toggle { background-color: #415b76 } .btn.btn-inverse:active,.btn-group.open .btn.btn-inverse.dropdown-toggle,.btn.btn-inverse.active { background-color: #2c3e50 } .btn>[class^="fui-"] { margin: 0 4px; position: relative; top: 1px; vertical-align: top; display: inline-block; zoom: 1; *display: inline } .btn>[class^="fui-"].pull-right { margin-right: 0 } .btn-toolbar .btn.active { color: #fff } .btn-toolbar .btn:first-child { -webkit-border-radius: 6px 0 0 6px; -moz-border-radius: 6px 0 0 6px; border-radius: 6px 0 0 6px } .btn-toolbar .btn:last-child { -webkit-border-radius: 0 6px 6px 0; -moz-border-radius: 0 6px 6px 0; border-radius: 0 6px 6px 0 } .btn-toolbar .btn>[class^="fui-"] { font-size: 16px; top: 0 } .btn-tip { font-weight: 300; padding-left: 10px } .btn-group>.btn { border-radius: 0; text-align: center } .btn-group>.btn:active+.btn,.btn-group>.btn.active+.btn { border-left-color: transparent } .btn-group>.btn:first-of-type { border-top-left-radius: 6px; border-bottom-left-radius: 6px } .btn-group>.btn:last-of-type { border-top-right-radius: 6px; border-bottom-right-radius: 6px } .btn-group>.btn+.btn { margin-left: 0 } .btn-group>.btn+.dropdown-toggle { border-left: 2px solid rgba(52,73,94,0.15); padding-left: 13px; padding-right: 13px; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .btn-group>.btn+.dropdown-toggle .caret { margin-left: 3px; margin-right: 3px } .btn-group>.btn.btn-huge+.dropdown-toggle .caret { margin-left: 7px; margin-right: 7px } .btn-group>.btn.btn-small+.dropdown-toggle .caret { margin-left: 0; margin-right: 0 } .caret { border-left-width: 6px; border-right-width: 6px; border-top-width: 8px; border-bottom-color: #34495e; border-style: solid; border-bottom-style: none; border-top-color: #34495e; -webkit-transition: .25s; -moz-transition: .25s; -o-transition: .25s; transition: .25s; -webkit-backface-visibility: hidden } .dropup .caret,.dropup .btn-large .caret,.navbar-fixed-bottom .dropdown .caret { border-bottom-width: 8px } .btn-mini .caret,.btn-small .caret,.btn-large .caret { margin-top: 7px } .btn-large .caret { border-top-width: 8px; border-right-width: 6px; border-left-width: 6px } .navbar { font-size: 15.988px } .navbar .brand { border-radius: 6px 0 0 6px; color: #526476; font-size: 23.996px; font-weight: 700; margin-left: 0; padding: 23px 28px 24px 32px; text-shadow: none } .navbar .brand:hover,.navbar .brand:focus { color: #1abc9c } .navbar .brand[class*="fui-"] { font-weight: normal } .navbar .nav { margin-right: 0 } .navbar .nav>li { position: relative } .navbar .nav>li:hover>ul { opacity: 1; top: 100%; visibility: visible; z-index: 100; -webkit-transform: scale(1,1); display: block\9 } .navbar .nav>li.active>a,.navbar .nav>li.active>a:hover,.navbar .nav>li.active>a:focus { background: 0; color: #1abc9c; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .navbar .nav>li>ul { padding-top: 13px; top: 80% } .navbar .nav>li>ul:before { content: ""; border-style: solid; border-width: 0 9px 9px 9px; border-color: transparent transparent #34495e transparent; height: 0; position: absolute; left: 15px; top: 5px; width: 0; -webkit-transform: rotate(360deg) } .navbar .nav>li>ul li:hover ul { opacity: 1; -webkit-transform: scale(1,1); visibility: visible; display: block\9 } .navbar .nav>li>ul li ul { left: 100% } .navbar .nav>li>a { color: #526476; font-weight: 700; font-size: 14.994px; padding: 29px 20px 27px; text-shadow: none; -webkit-transition: background-color .25s,color .25s,border-bottom-color .25s; -moz-transition: background-color .25s,color .25s,border-bottom-color .25s; -o-transition: background-color .25s,color .25s,border-bottom-color .25s; transition: background-color .25s,color .25s,border-bottom-color .25s; -webkit-backface-visibility: hidden } .navbar .nav>li>a:hover,.navbar .nav>li>a:focus { color: #1abc9c } .navbar .nav>li>a[class*="fui-"] { font-size: 24px; font-weight: normal } .navbar .nav>li>a>[class*="fui-"] { font-size: 24px; margin: -4px 0 0; position: relative; top: 4px } .navbar .nav>li>a>[class*="fui-"]+* { margin-left: 12px } .navbar .nav>li:first-child>a { -webkit-border-radius: 0 0 0 6px; -moz-border-radius: 0 0 0 6px; border-radius: 0 0 0 6px } .navbar .nav ul { border-radius: 4px; left: 0; list-style-type: none; margin-left: 0; opacity: 0; position: absolute; top: 0; width: 234px; z-index: -100; -webkit-transform: scale(1,0.99); -webkit-transform-origin: 0 0; visibility: hidden; -webkit-transition: .3s ease-out; -moz-transition: .3s ease-out; -o-transition: .3s ease-out; transition: .3s ease-out; -webkit-backface-visibility: hidden } .navbar .nav ul ul { left: 95%; padding-left: 5px } .navbar .nav ul li { background-color: #34495e; padding: 0 3px 3px; position: relative } .navbar .nav ul li:first-child { border-radius: 6px 6px 0 0; padding-top: 3px } .navbar .nav ul li:last-child { border-radius: 0 0 6px 6px } .navbar .nav ul li.active>a,.navbar .nav ul li.active>a:hover,.navbar .nav ul li.active>a:focus { background-color: #1abc9c; color: #fff; padding-left: 9px; padding-right: 9px } .navbar .nav ul li.active+li>a { padding-left: 9px; padding-right: 9px } .navbar .nav ul a { border-radius: 2px; color: #fff; display: block; font-size: 14px; padding: 6px 9px; text-decoration: none } .navbar .nav ul a:hover { background-color: #1abc9c } .navbar .btn-navbar { background: 0; border: 0; color: #34495e; margin: 21px 15px 17px; text-shadow: none; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .navbar .btn-navbar:hover,.navbar .btn-navbar:focus { background: 0; color: #1abc9c } .navbar .btn-navbar:before { content: "\e00c"; font-family: "Flat-UI-Icons"; font-size: 21.994px; font-style: normal; font-weight: normal; -webkit-font-smoothing: antialiased } .navbar .btn-navbar .icon-bar { display: none } .navbar-inner { background: #eceef0; border: 0; padding-left: 0; padding-right: 0; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)"); -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .navbar-inverse { font-size: 16.996px } .navbar-inverse .navbar-inner { background: #34495e; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)"); padding: 5px; } .navbar-inverse .brand { border-bottom: 2px solid #2c3e50; border-right: 2px solid #2c3e50; color: #fff; padding: 10px 28px 11px 32px } .navbar-inverse .btn-navbar { color: #fff; margin: 7px 10px } .navbar-inverse .nav>li:first-child.active>a { padding-left: 20px } .navbar-inverse .nav>li:first-child>a { border-left: none } .navbar-inverse .nav>li.active>a,.navbar-inverse .nav>li.active>a:hover,.navbar-inverse .nav>li.active>a:focus { background-color: #1abc9c; border-bottom-color: #08c; border-left: none; color: #fff; padding-left: 22px; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .navbar-inverse .nav>li.active+li>a { border-left: none; padding-left: 22px } .navbar-inverse .nav>li>a { font-size: 16.002px; border-bottom: 2px solid #2c3e50; border-left: 2px solid #2c3e50; color: #fff; padding: 16px 20px 15px } .navbar-inverse .nav.pull-right>li>a { border-radius: 0 6px 6px 0 } .navbar-unread,.navbar-new { font-family: "Lato",sans-serif; background-color: #1abc9c; border-radius: 50%; color: #fff; font-size: 0; font-weight: 700; height: 6px; line-height: 14px; position: absolute; right: 12px; text-align: center; top: 28px; width: 6px; z-index: 10 } .active .navbar-unread,.active .navbar-new { background-color: #fff; display: none } .navbar-inverse .navbar-unread,.navbar-inverse .navbar-new { top: 15px } .navbar-new { background-color: #e74c3c; font-size: 12px; line-height: 17px; height: 18px; margin: -9px -1px; min-width: 16px; padding: 0 1px; width: auto; -webkit-font-smoothing: subpixel-antialiased } .navbar.navbar-inverse .nav li.dropdown.open>.dropdown-toggle { background-color: #1abc9c; border-bottom-color: #08c; color: #fff } .navbar.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret { border-bottom-color: #fff!important; border-top-color: #fff!important } .navbar .nav li.dropdown.open>.dropdown-toggle { background: 0; color: #1abc9c } .navbar .nav li.dropdown.open>.dropdown-toggle .caret { border-bottom-color: #1abc9c!important; border-top-color: #1abc9c!important } .navbar .nav li.dropdown.open .dropdown-menu { opacity: 1; top: 100%; visibility: visible; z-index: 1000; -webkit-transform: none } .navbar .nav li.dropdown>.dropdown-toggle { outline: 0 } .navbar .nav li.dropdown>.dropdown-toggle:hover .caret,.navbar .nav li.dropdown>.dropdown-toggle:focus .caret { border-bottom-color: #1abc9c; border-top-color: #1abc9c } .navbar .nav li.dropdown>.dropdown-toggle .caret { border-left-width: 6px; border-right-width: 6px; border-top-width: 8px; border-bottom-color: #4c6a89; border-top-color: #4c6a89; margin-left: 10px; margin-top: 7px } .navbar .nav li.dropdown .dropdown-menu { background-color: #34495e; opacity: 0; padding: 0; visibility: hidden } .navbar .nav li.dropdown .dropdown-menu:before { display: none } .navbar .nav li.dropdown .dropdown-menu:after { border-bottom-color: #34495e } .navbar .nav li.dropdown .dropdown-menu>li>a { border-radius: 3px; color: #fff; padding: 6px 8px 8px } .navbar .nav li.dropdown .dropdown-menu .divider { background-color: #2c3e50; border-bottom: 0; margin: 2px 0 5px; padding: 0; height: 2px } .select { display: inline-block; margin-bottom: 10px }[class*="span"]>.select[class*="span"] { margin-left: 0 } .select[class*="span"] .btn { width: 100%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box } .select.select-block { display: block; float: none; margin-left: 0; width: auto } .select.select-block .btn { width: 100%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box } .select .btn { width: 220px } .select .btn.btn-huge .filter-option { left: 20px; right: 40px; top: 16px } .select .btn.btn-huge .caret { right: 20px } .select .btn.btn-large .filter-option { left: 18px; right: 38px; top: 12px } .select .btn.btn-small .filter-option { left: 13px; right: 33px; top: 7px } .select .btn.btn-small .caret { right: 13px } .select .btn.btn-mini .filter-option { left: 13px; right: 33px; top: 5px } .select .btn.btn-mini .caret { right: 13px } .select .btn .filter-option { height: 26px; left: 13px; overflow: hidden; position: absolute; right: 33px; text-align: left; top: 10px } .select .btn .caret { position: absolute; right: 16px } .select .btn .dropdown-toggle { -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px } .select .btn .dropdown-menu { min-width: 100%; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box } .select .btn .dropdown-menu dt { cursor: default; display: block; padding: 3px 20px } .select .btn .dropdown-menu li:not(.disabled)>a:hover small { color: rgba(255,255,255,0.004) } .select .btn .dropdown-menu li>a { min-height: 20px } .select .btn .dropdown-menu li>a.opt { padding-left: 35px } .select .btn .dropdown-menu li small { padding-left: .5em } .select .btn .dropdown-menu li>dt small { font-weight: normal } .select .btn>.disabled,.select .btn .dropdown-menu li.disabled>a { cursor: default } .select .caret { border-left-width: 6px; border-right-width: 6px; border-top-width: 8px; border-bottom-color: #fff; border-style: solid; border-bottom-style: none; border-top-color: #fff; -webkit-transition: .25s; -moz-transition: .25s; -o-transition: .25s; transition: .25s; -webkit-backface-visibility: hidden } textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input { border: 2px solid #bdc3c7; color: #34495e; font-family: "Lato",sans-serif; font-size: 14px; padding: 8px 5px; height: 21px; text-indent: 6px; -webkit-appearance: none; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; -webkit-transition: border .25s linear,color .25s linear; -moz-transition: border .25s linear,color .25s linear; -o-transition: border .25s linear,color .25s linear; transition: border .25s linear,color .25s linear; -webkit-backface-visibility: hidden } textarea:-moz-placeholder,input[type="text"]:-moz-placeholder,input[type="password"]:-moz-placeholder,input[type="datetime"]:-moz-placeholder,input[type="datetime-local"]:-moz-placeholder,input[type="date"]:-moz-placeholder,input[type="month"]:-moz-placeholder,input[type="time"]:-moz-placeholder,input[type="week"]:-moz-placeholder,input[type="number"]:-moz-placeholder,input[type="email"]:-moz-placeholder,input[type="url"]:-moz-placeholder,input[type="search"]:-moz-placeholder,input[type="tel"]:-moz-placeholder,input[type="color"]:-moz-placeholder,.uneditable-input:-moz-placeholder { color: #b2bcc5 } textarea::-webkit-input-placeholder,input[type="text"]::-webkit-input-placeholder,input[type="password"]::-webkit-input-placeholder,input[type="datetime"]::-webkit-input-placeholder,input[type="datetime-local"]::-webkit-input-placeholder,input[type="date"]::-webkit-input-placeholder,input[type="month"]::-webkit-input-placeholder,input[type="time"]::-webkit-input-placeholder,input[type="week"]::-webkit-input-placeholder,input[type="number"]::-webkit-input-placeholder,input[type="email"]::-webkit-input-placeholder,input[type="url"]::-webkit-input-placeholder,input[type="search"]::-webkit-input-placeholder,input[type="tel"]::-webkit-input-placeholder,input[type="color"]::-webkit-input-placeholder,.uneditable-input::-webkit-input-placeholder { color: #b2bcc5 } textarea.placeholder,input[type="text"].placeholder,input[type="password"].placeholder,input[type="datetime"].placeholder,input[type="datetime-local"].placeholder,input[type="date"].placeholder,input[type="month"].placeholder,input[type="time"].placeholder,input[type="week"].placeholder,input[type="number"].placeholder,input[type="email"].placeholder,input[type="url"].placeholder,input[type="search"].placeholder,input[type="tel"].placeholder,input[type="color"].placeholder,.uneditable-input.placeholder { color: #b2bcc5 } .control-group.focus textarea,.control-group.focus input[type="text"],.control-group.focus input[type="password"],.control-group.focus input[type="datetime"],.control-group.focus input[type="datetime-local"],.control-group.focus input[type="date"],.control-group.focus input[type="month"],.control-group.focus input[type="time"],.control-group.focus input[type="week"],.control-group.focus input[type="number"],.control-group.focus input[type="email"],.control-group.focus input[type="url"],.control-group.focus input[type="search"],.control-group.focus input[type="tel"],.control-group.focus input[type="color"],.control-group.focus .uneditable-input,textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus { border-color: rgba(82,168,236,0.8); -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .row-fluid textarea,.row-fluid input[type="text"],.row-fluid input[type="password"],.row-fluid input[type="datetime"],.row-fluid input[type="datetime-local"],.row-fluid input[type="date"],.row-fluid input[type="month"],.row-fluid input[type="time"],.row-fluid input[type="week"],.row-fluid input[type="number"],.row-fluid input[type="email"],.row-fluid input[type="url"],.row-fluid input[type="search"],.row-fluid input[type="tel"],.row-fluid input[type="color"],.row-fluid .uneditable-input { height: 41px; width: 100% } textarea.flat,input[type="text"].flat,input[type="password"].flat,input[type="datetime"].flat,input[type="datetime-local"].flat,input[type="date"].flat,input[type="month"].flat,input[type="time"].flat,input[type="week"].flat,input[type="number"].flat,input[type="email"].flat,input[type="url"].flat,input[type="search"].flat,input[type="tel"].flat,input[type="color"].flat,.uneditable-input.flat { border-color: transparent } textarea.flat:hover,input[type="text"].flat:hover,input[type="password"].flat:hover,input[type="datetime"].flat:hover,input[type="datetime-local"].flat:hover,input[type="date"].flat:hover,input[type="month"].flat:hover,input[type="time"].flat:hover,input[type="week"].flat:hover,input[type="number"].flat:hover,input[type="email"].flat:hover,input[type="url"].flat:hover,input[type="search"].flat:hover,input[type="tel"].flat:hover,input[type="color"].flat:hover,.uneditable-input.flat:hover { border-color: #bdc3c7 } textarea.flat:focus,input[type="text"].flat:focus,input[type="password"].flat:focus,input[type="datetime"].flat:focus,input[type="datetime-local"].flat:focus,input[type="date"].flat:focus,input[type="month"].flat:focus,input[type="time"].flat:focus,input[type="week"].flat:focus,input[type="number"].flat:focus,input[type="email"].flat:focus,input[type="url"].flat:focus,input[type="search"].flat:focus,input[type="tel"].flat:focus,input[type="color"].flat:focus,.uneditable-input.flat:focus { border-color: rgba(82,168,236,0.8); } .control-group.error textarea,.control-group.error input[type="text"],.control-group.error input[type="password"],.control-group.error input[type="datetime"],.control-group.error input[type="datetime-local"],.control-group.error input[type="date"],.control-group.error input[type="month"],.control-group.error input[type="time"],.control-group.error input[type="week"],.control-group.error input[type="number"],.control-group.error input[type="email"],.control-group.error input[type="url"],.control-group.error input[type="search"],.control-group.error input[type="tel"],.control-group.error input[type="color"],.control-group.error .uneditable-input { border-color: #e74c3c; color: #e74c3c; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .control-group.error textarea:focus,.control-group.error input[type="text"]:focus,.control-group.error input[type="password"]:focus,.control-group.error input[type="datetime"]:focus,.control-group.error input[type="datetime-local"]:focus,.control-group.error input[type="date"]:focus,.control-group.error input[type="month"]:focus,.control-group.error input[type="time"]:focus,.control-group.error input[type="week"]:focus,.control-group.error input[type="number"]:focus,.control-group.error input[type="email"]:focus,.control-group.error input[type="url"]:focus,.control-group.error input[type="search"]:focus,.control-group.error input[type="tel"]:focus,.control-group.error input[type="color"]:focus,.control-group.error .uneditable-input:focus { -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .control-group.success textarea,.control-group.success input[type="text"],.control-group.success input[type="password"],.control-group.success input[type="datetime"],.control-group.success input[type="datetime-local"],.control-group.success input[type="date"],.control-group.success input[type="month"],.control-group.success input[type="time"],.control-group.success input[type="week"],.control-group.success input[type="number"],.control-group.success input[type="email"],.control-group.success input[type="url"],.control-group.success input[type="search"],.control-group.success input[type="tel"],.control-group.success input[type="color"],.control-group.success .uneditable-input { border-color: #2ecc71; color: #2ecc71; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .control-group.success textarea:focus,.control-group.success input[type="text"]:focus,.control-group.success input[type="password"]:focus,.control-group.success input[type="datetime"]:focus,.control-group.success input[type="datetime-local"]:focus,.control-group.success input[type="date"]:focus,.control-group.success input[type="month"]:focus,.control-group.success input[type="time"]:focus,.control-group.success input[type="week"]:focus,.control-group.success input[type="number"]:focus,.control-group.success input[type="email"]:focus,.control-group.success input[type="url"]:focus,.control-group.success input[type="search"]:focus,.control-group.success input[type="tel"]:focus,.control-group.success input[type="color"]:focus,.control-group.success .uneditable-input:focus { -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .control-group.warning textarea,.control-group.warning input[type="text"],.control-group.warning input[type="password"],.control-group.warning input[type="datetime"],.control-group.warning input[type="datetime-local"],.control-group.warning input[type="date"],.control-group.warning input[type="month"],.control-group.warning input[type="time"],.control-group.warning input[type="week"],.control-group.warning input[type="number"],.control-group.warning input[type="email"],.control-group.warning input[type="url"],.control-group.warning input[type="search"],.control-group.warning input[type="tel"],.control-group.warning input[type="color"],.control-group.warning .uneditable-input { border-color: #f1c40f; color: #f1c40f; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .control-group.warning textarea:focus,.control-group.warning input[type="text"]:focus,.control-group.warning input[type="password"]:focus,.control-group.warning input[type="datetime"]:focus,.control-group.warning input[type="datetime-local"]:focus,.control-group.warning input[type="date"]:focus,.control-group.warning input[type="month"]:focus,.control-group.warning input[type="time"]:focus,.control-group.warning input[type="week"]:focus,.control-group.warning input[type="number"]:focus,.control-group.warning input[type="email"]:focus,.control-group.warning input[type="url"]:focus,.control-group.warning input[type="search"]:focus,.control-group.warning input[type="tel"]:focus,.control-group.warning input[type="color"]:focus,.control-group.warning .uneditable-input:focus { -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .control-group.info textarea,.control-group.info input[type="text"],.control-group.info input[type="password"],.control-group.info input[type="datetime"],.control-group.info input[type="datetime-local"],.control-group.info input[type="date"],.control-group.info input[type="month"],.control-group.info input[type="time"],.control-group.info input[type="week"],.control-group.info input[type="number"],.control-group.info input[type="email"],.control-group.info input[type="url"],.control-group.info input[type="search"],.control-group.info input[type="tel"],.control-group.info input[type="color"],.control-group.info .uneditable-input { border-color: #3498db; color: #3498db; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .control-group.info textarea:focus,.control-group.info input[type="text"]:focus,.control-group.info input[type="password"]:focus,.control-group.info input[type="datetime"]:focus,.control-group.info input[type="datetime-local"]:focus,.control-group.info input[type="date"]:focus,.control-group.info input[type="month"]:focus,.control-group.info input[type="time"]:focus,.control-group.info input[type="week"]:focus,.control-group.info input[type="number"]:focus,.control-group.info input[type="email"]:focus,.control-group.info input[type="url"]:focus,.control-group.info input[type="search"]:focus,.control-group.info input[type="tel"]:focus,.control-group.info input[type="color"]:focus,.control-group.info .uneditable-input:focus { -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .control-group textarea,.control-group input[type="text"],.control-group input[type="password"],.control-group input[type="datetime"],.control-group input[type="datetime-local"],.control-group input[type="date"],.control-group input[type="month"],.control-group input[type="time"],.control-group input[type="week"],.control-group input[type="number"],.control-group input[type="email"],.control-group input[type="url"],.control-group input[type="search"],.control-group input[type="tel"],.control-group input[type="color"],.control-group .uneditable-input { margin-bottom: 0 } .control-group { position: relative } .control-group>.input-icon { position: absolute; top: 2px; right: 2px; line-height: 37px; vertical-align: middle; font-size: 19.991999999999997px; color: #b2bcc5; background-color: #fff; padding: 0 10px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px } .control-group input:focus+.input-icon { color: #34495e } .control-group.huge>.input-icon { line-height: 49px } .control-group.large>.input-icon { line-height: 41px } .control-group.small>.input-icon { font-size: 15.988px; line-height: 30px } .control-group.success>.input-icon,.control-group.success input+.input-icon { color: #2ecc71 } .control-group.warning>.input-icon,.control-group.warning input+.input-icon { color: #f1c40f } .control-group.error>.input-icon,.control-group.error input+.input-icon { color: #e74c3c } .control-group.disabled>.input-icon,.control-group.disabled input+.input-icon { color: #d5dbdb; background-color: #f4f6f6 } input[disabled],input[readonly],textarea[disabled],textarea[readonly] { background-color: #f4f6f6; border-color: #d5dbdb; color: #d5dbdb; cursor: default } input,textarea,.uneditable-input { width: 192px } textarea { height: auto; font-size: 14.994px; line-height: 24px; padding: 5px 11px; text-indent: 0 } .row-fluid textarea { height: auto; width: 100%!important } textarea[class*="span"] { width: 100%!important; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box } .checkbox,.radio { margin-bottom: 12px; padding-left: 32px; position: relative; -webkit-transition: color .25s linear; -moz-transition: color .25s linear; -o-transition: color .25s linear; transition: color .25s linear; -webkit-backface-visibility: hidden } .checkbox input,.radio input { outline: none!important; display: none } .checkbox .icons,.radio .icons { color: #bdc3c7; display: block; height: 20px; left: 0; position: absolute; top: 0; width: 20px; text-align: center; line-height: 20px; font-size: 20px; -webkit-transition: color .25s linear; -moz-transition: color .25s linear; -o-transition: color .25s linear; transition: color .25s linear; -webkit-backface-visibility: hidden } .checkbox .icons .first-icon-icon,.radio .icons .first-icon-icon,.checkbox .icons .second-icon,.radio .icons .second-icon { position: absolute; left: 0; top: 0; opacity: 1; filter: alpha(opacity=100) } .checkbox .icons .second-icon,.radio .icons .second-icon { opacity: 0; filter: alpha(opacity=0) } .checkbox:hover .first-icon,.radio:hover .first-icon { opacity: 0; filter: alpha(opacity=0) } .checkbox:hover .second-icon,.radio:hover .second-icon { opacity: 1; filter: alpha(opacity=100) } .checkbox.checked,.radio.checked { color: #08c } .checkbox.checked .icons,.radio.checked .icons { color: #1abc9c } .checkbox.checked .first-icon,.radio.checked .first-icon { opacity: 0; filter: alpha(opacity=0) } .checkbox.checked .second-icon,.radio.checked .second-icon { opacity: 1; filter: alpha(opacity=100) } .checkbox.disabled,.radio.disabled { cursor: default; color: #e6e8ea } .checkbox.disabled .icons,.radio.disabled .icons { color: #e6e8ea } .checkbox.disabled .first-icon,.radio.disabled .first-icon { opacity: 1; filter: alpha(opacity=100) } .checkbox.disabled .second-icon,.radio.disabled .second-icon { opacity: 0; filter: alpha(opacity=0) } .checkbox.disabled.checked .icons,.radio.disabled.checked .icons { color: #e6e8ea } .checkbox.disabled.checked .first-icon,.radio.disabled.checked .first-icon { opacity: 0; filter: alpha(opacity=0) } .checkbox.disabled.checked .second-icon,.radio.disabled.checked .second-icon { opacity: 1; filter: alpha(opacity=100) } .tagsinput { background: white; border: 2px solid #1abc9c; border-radius: 6px; height: 100px; margin-bottom: 18px; padding: 6px 1px 1px 6px; overflow-y: auto; text-align: left } .tagsinput .tag { border-radius: 4px; background-color: #1abc9c; color: #fff; cursor: pointer; margin-right: 5px; margin-bottom: 5px; overflow: hidden; line-height: 15px; padding: 6px 13px 8px 19px; position: relative; vertical-align: middle; display: inline-block; zoom: 1; *display: inline; -webkit-transition: .14s linear; -moz-transition: .14s linear; -o-transition: .14s linear; transition: .14s linear; -webkit-backface-visibility: hidden } .tagsinput .tag:hover { background-color: #08c; color: #fff; padding-left: 12px; padding-right: 20px } .tagsinput .tag:hover .tagsinput-remove-link { color: #fff; opacity: 1; display: block\9 } .tagsinput input { background: transparent; border: 0; color: #34495e; font-family: "Lato",sans-serif; font-size: 14px; margin: 0; padding: 0 0 0 5px; outline: 0; margin-right: 5px; margin-bottom: 5px; width: 12px } .tagsinput-remove-link { bottom: 0; color: #fff; cursor: pointer; font-size: 12px; opacity: 0; padding: 7px 7px 5px 0; position: absolute; right: 0; text-align: right; text-decoration: none; top: 0; width: 100%; z-index: 2; display: none\9 } .tagsinput-remove-link:before { color: #fff; content: "\e00b"; font-family: "Flat-UI-Icons" } .tagsinput-add-container { vertical-align: middle; display: inline-block; zoom: 1; *display: inline } .tagsinput-add { background-color: #d6dbdf; border-radius: 3px; color: #fff; cursor: pointer; margin-bottom: 5px; padding: 6px 9px; display: inline-block; zoom: 1; *display: inline; -webkit-transition: .25s; -moz-transition: .25s; -o-transition: .25s; transition: .25s; -webkit-backface-visibility: hidden } .tagsinput-add:hover { background-color: #1abc9c } .tagsinput-add:before { content: "\e009"; font-family: "Flat-UI-Icons" } .tags_clear { clear: both; width: 100%; height: 0 } .not_valid { background: #fbd8db!important; color: #90111a!important } .progress { background: #ebedef; border-radius: 32px; height: 12px; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)") } .progress .bar { background: #1abc9c; -webkit-box-shadow: none!important; -moz-box-shadow: none!important; box-shadow: none!important; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)") } .progress .bar-success { background-color: #2ecc71; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)") } .progress .bar-warning { background-color: #f1c40f; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)") } .progress .bar-danger { background-color: #e74c3c; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)") } .progress .bar-info { background-color: #3498db; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)") } .ui-slider { background: #ebedef; border-radius: 32px; height: 12px; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)"); margin-bottom: 20px; position: relative } .ui-slider .bar { background: #1abc9c; -webkit-box-shadow: none!important; -moz-box-shadow: none!important; box-shadow: none!important; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)") } .ui-slider .bar-success { background-color: #2ecc71; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)") } .ui-slider .bar-warning { background-color: #f1c40f; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)") } .ui-slider .bar-danger { background-color: #e74c3c; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)") } .ui-slider .bar-info { background-color: #3498db; filter: unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)") } .ui-slider-handle { background-color: #08c; border-radius: 50%; cursor: pointer; height: 18px; margin-left: -9px; position: absolute; top: -3px; width: 18px; z-index: 2; -webkit-transition: background .25s; -moz-transition: background .25s; -o-transition: background .25s; transition: background .25s; -webkit-backface-visibility: hidden } .ui-slider-handle[style*='100'] { margin-left: -15px } .ui-slider-handle:hover,.ui-slider-handle:focus { background-color: #48c9b0; outline: 0 } .ui-slider-handle:active { background-color: #08c } .ui-slider-range { background-color: #1abc9c; border-radius: 30px 0 0 30px; display: block; height: 100%; position: absolute; z-index: 1 } .ui-slider-segment { background-color: #d9dbdd; border-radius: 50%; float: left; height: 6px; margin: 3px -6px 0 0; width: 6px } .ui-slider-value { float: right; font-weight: 500; margin-top: 12px } .ui-slider-value.first { clear: left; float: left } .pager { background-color: #34495e; border-radius: 6px; color: #fff; font-size: 16px; font-weight: 700; display: inline-block; zoom: 1; *display: inline } .pager li:first-child>a,.pager li:first-child>span { border-left: none; -webkit-border-radius: 6px 0 0 6px; -moz-border-radius: 6px 0 0 6px; border-radius: 6px 0 0 6px } .pager li.pager-center { padding: 9px 15px 10px; padding-left: 0; padding-right: 0; display: inline-block; zoom: 1; *display: inline } .pager li>a,.pager li>span { background: 0; border: 0; border-left: 2px solid #2c3e50; color: #fff; padding: 9px 15px 10px; text-decoration: none; white-space: nowrap; -webkit-border-radius: 0 6px 6px 0; -moz-border-radius: 0 6px 6px 0; border-radius: 0 6px 6px 0 } .pager li>a:hover,.pager li>span:hover,.pager li>a:focus,.pager li>span:focus { background-color: #2c3e50 } .pager li>a:active,.pager li>span:active { background-color: #2c3e50 } .pager li>a [class*="fui-"]+span,.pager li>span [class*="fui-"]+span { margin-left: 8px } .pager li>a span+[class*="fui-"],.pager li>span span+[class*="fui-"] { margin-left: 8px } .pagination { position: relative } .pagination ul { background: #d6dbdf; color: #fff; vertical-align: top; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .pagination ul li { display: inline-block; margin-right: -3px; vertical-align: top } .pagination ul li.active>a,.pagination ul li.active>span { background-color: #1abc9c; color: #fff } .pagination ul li.active.previous>a,.pagination ul li.active.next>a,.pagination ul li.active.previous>span,.pagination ul li.active.next>span { margin: 0 } .pagination ul li.active.previous>a,.pagination ul li.active.next>a,.pagination ul li.active.previous>span,.pagination ul li.active.next>span,.pagination ul li.active.previous>a:hover,.pagination ul li.active.next>a:hover,.pagination ul li.active.previous>span:hover,.pagination ul li.active.next>span:hover,.pagination ul li.active.previous>a:focus,.pagination ul li.active.next>a:focus,.pagination ul li.active.previous>span:focus,.pagination ul li.active.next>span:focus { background-color: #1abc9c; color: #fff } .pagination ul li:first-child { -webkit-border-radius: 6px 0 0 6px; -moz-border-radius: 6px 0 0 6px; border-radius: 6px 0 0 6px } .pagination ul li:first-child>a,.pagination ul li:first-child>span { -webkit-border-radius: 6px 0 0 6px; -moz-border-radius: 6px 0 0 6px; border-radius: 6px 0 0 6px } .pagination ul li:first-child.previous+li>a,.pagination ul li:first-child.previous+li>span { border-left-width: 5px } .pagination ul li:first-child>a,.pagination ul li:first-child>span { border-left: none } .pagination ul li:last-child { margin-right: 0; -webkit-border-radius: 0 6px 6px 0; -moz-border-radius: 0 6px 6px 0; border-radius: 0 6px 6px 0 } .pagination ul li:last-child>a,.pagination ul li:last-child>span,.pagination ul li:last-child>a:hover,.pagination ul li:last-child>span:hover,.pagination ul li:last-child>a:focus,.pagination ul li:last-child>span:focus { -webkit-border-radius: 0 6px 6px 0; -moz-border-radius: 0 6px 6px 0; border-radius: 0 6px 6px 0 } .pagination ul li.previous>a,.pagination ul li.next>a,.pagination ul li.previous>span,.pagination ul li.next>span { background: transparent; border: 0; border-right: 2px solid #e4e7ea; font-size: 15.988px; margin: 0 9px 0 0; padding: 12px 17px; min-width: auto; -webkit-border-radius: 6px 0 0 6px; -moz-border-radius: 6px 0 0 6px; border-radius: 6px 0 0 6px; -webkit-box-shadow: none!important; -moz-box-shadow: none!important; box-shadow: none!important } .pagination ul li.previous>a,.pagination ul li.next>a,.pagination ul li.previous>span,.pagination ul li.next>span,.pagination ul li.previous>a:hover,.pagination ul li.next>a:hover,.pagination ul li.previous>span:hover,.pagination ul li.next>span:hover,.pagination ul li.previous>a:focus,.pagination ul li.next>a:focus,.pagination ul li.previous>span:focus,.pagination ul li.next>span:focus { border-color: #e4e7ea!important } .pagination ul li.next { margin-left: 9px } .pagination ul li.next>a,.pagination ul li.next>span { border-left: 2px solid #e4e7ea; border-right: 0; margin: 0; -webkit-border-radius: 0 6px 6px 0; -moz-border-radius: 0 6px 6px 0; border-radius: 0 6px 6px 0 } .pagination ul li.active>a,.pagination ul li.active>span { background-color: #fff; border-color: #fff; border-width: 2px!important; color: #d6dbdf; margin: 10px 5px 9px } .pagination ul li.active>a:hover,.pagination ul li.active>span:hover,.pagination ul li.active>a:focus,.pagination ul li.active>span:focus { background-color: #fff; border-color: #fff; color: #d6dbdf; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } .pagination ul li.active.previous,.pagination ul li.active.next { border-color: #e4e7ea } .pagination ul li.active.previous { margin-right: 6px } .pagination ul li>a,.pagination ul li>span { background: #fff; border: 5px solid #d6dbdf; color: #fff; line-height: 16px; min-height: 17px; min-width: auto; outline: 0; padding: 0 4px; margin: 7px 2px 6px; text-align: center; -webkit-border-radius: 50px; -moz-border-radius: 50px; border-radius: 50px; -webkit-transition: background .2s ease-out,border-color 0s ease-out,color .2s ease-out; -moz-transition: background .2s ease-out,border-color 0s ease-out,color .2s ease-out; -o-transition: background .2s ease-out,border-color 0s ease-out,color .2s ease-out; transition: background .2s ease-out,border-color 0s ease-out,color .2s ease-out; -webkit-backface-visibility: hidden } .pagination ul li>a:hover,.pagination ul li>span:hover,.pagination ul li>a:focus,.pagination ul li>span:focus { background-color: #1abc9c; border-color: #1abc9c; color: #fff; -webkit-transition: background .2s ease-out,border-color .2s ease-out,color .2s ease-out; -moz-transition: background .2s ease-out,border-color .2s ease-out,color .2s ease-out; -o-transition: background .2s ease-out,border-color .2s ease-out,color .2s ease-out; transition: background .2s ease-out,border-color .2s ease-out,color .2s ease-out; -webkit-backface-visibility: hidden } .pagination ul li>a:active,.pagination ul li>span:active { background-color: #08c; border-color: #08c; color: #fff } .pagination>.btn.previous,.pagination>.btn.next { margin-right: 8px; font-size: 14px; padding-left: 23px; padding-right: 23px } .pagination>.btn.previous [class*="fui-"],.pagination>.btn.next [class*="fui-"] { font-size: 16px; margin-left: -2px; margin-top: -2px } .pagination>.btn.next { margin-left: 8px; margin-right: 0 } .pagination>.btn.next [class*="fui-"] { margin-right: -2px; margin-left: 4px } .tooltip { font-size: 14px } .tooltip.in { opacity: 1 } .tooltip.top { padding-bottom: 9px } .tooltip.top .tooltip-arrow { border-top-color: #34495e; border-width: 9px 9px 0; bottom: 0; margin-left: -9px } .tooltip.right .tooltip-arrow { border-right-color: #34495e; border-width: 9px 9px 9px 0; margin-top: -9px; left: -3px } .tooltip.bottom { padding-top: 8px } .tooltip.bottom .tooltip-arrow { border-bottom-color: #34495e; border-width: 0 9px 9px; margin-left: -9px; top: -1px } .tooltip.left .tooltip-arrow { border-left-color: #34495e; border-width: 9px 0 9px 9px; margin-top: -9px; right: -3px } .tooltip-inner { background-color: #34495e; line-height: 17.99px; padding: 12px 12px; text-align: center; width: 183px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px } .dropdown-menu { background-color: #f3f4f5; border: 0; display: block; margin-top: 8px; opacity: 0; padding: 0; visibility: hidden; width: 100%; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; -webkit-transition: .25s; -moz-transition: .25s; -o-transition: .25s; transition: .25s; -webkit-backface-visibility: hidden } .dropdown-menu.typeahead { display: none; opacity: 1; visibility: visible; width: auto; margin-top: 2px } .open>.dropdown-menu { margin-top: 18px; opacity: 1; visibility: visible } .dropdown-menu li:first-child dt+a { border-radius: 0 } .dropdown-menu li:first-child>a { border-radius: 6px 6px 0 0; padding-top: 8px } .dropdown-menu li:last-child>a { border-radius: 0 0 6px 6px; padding-bottom: 10px } .dropdown-menu li.active>a,.dropdown-menu li.selected>a,.dropdown-menu li.active>a.highlighted,.dropdown-menu li.selected>a.highlighted { background: #1abc9c; color: #fff } .dropdown-menu li.active>a:hover,.dropdown-menu li.selected>a:hover,.dropdown-menu li.active>a.highlighted:hover,.dropdown-menu li.selected>a.highlighted:hover,.dropdown-menu li.active>a:focus,.dropdown-menu li.selected>a:focus,.dropdown-menu li.active>a.highlighted:focus,.dropdown-menu li.selected>a.highlighted:focus { background: #08c; color: #fff } .dropdown-menu li>a { color: rgba(52,73,94,0.75); padding: 6px 15px 8px; text-decoration: none; *zoom: 1; -webkit-transition: background-color .25s; -moz-transition: background-color .25s; -o-transition: background-color .25s; transition: background-color .25s; -webkit-backface-visibility: hidden } .dropdown-menu li>a:before,.dropdown-menu li>a:after { display: table; content: "" } .dropdown-menu li>a:after { clear: both } .dropdown-menu li>a:hover,.dropdown-menu li>a:active,.dropdown-menu li>a:focus { background: #e1e4e7; color: inherit; outline: 0 } .dropdown-menu li>a.highlighted { background: #c9cfd4; color: #fff } .dropdown-menu li>a.highlighted:hover,.dropdown-menu li>a.highlighted:focus { background: #bac1c8; color: #fff } .dropdown-menu li>a:before { float: right; margin-top: 3px } .dropdown-menu li dt { font-weight: 300; margin-bottom: 3px; margin-top: 12px; padding: 0 15px } .dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu { margin-bottom: 8px } .dropup .dropdown-arrow,.navbar-fixed-bottom .dropdown .dropdown-arrow { border-bottom: 0; border-top: 8px outset #f3f4f5; bottom: 100%; top: auto } .navbar-fixed-bottom .nav>li>ul:before { border-bottom: 0; border-top: 9px outset #34495e; bottom: 4px; top: auto } .open.dropup>.dropdown-menu { margin-bottom: 18px } .open.dropup>.dropdown-arrow { margin-bottom: 10px } .open.dropup>.dropdown-arrow.dropdown-arrow-inverse { border-top-color: #34495e } .open>.dropdown-arrow { margin-top: 9px; opacity: 1 } .dropdown-arrow { border-style: solid; border-width: 0 9px 9px 9px; border-color: transparent transparent #f3f4f5 transparent; height: 0; margin-top: 0; opacity: 0; position: absolute; right: 13px; top: 100%; width: 0; z-index: 10; -webkit-transform: rotate(360deg); -webkit-transition: .25s; -moz-transition: .25s; -o-transition: .25s; transition: .25s; -webkit-backface-visibility: hidden } .dropdown-inverse { background-color: #34495e; color: #ccc; padding: 4px 0 6px } .dropdown-inverse li { margin: 0 4px -2px } .dropdown-inverse li:first-child>a,.dropdown-inverse li:last-child>a { border-radius: 2px; padding-bottom: 7px; padding-top: 5px } .dropdown-inverse li:first-child dt+a,.dropdown-inverse li:last-child dt+a { border-radius: 2px } .dropdown-inverse li.active>a,.dropdown-inverse li.selected>a { background: #1abc9c; color: #fff; position: relative; z-index: 1 } .dropdown-inverse li dt { padding-left: 11px; padding-right: 11px } .dropdown-inverse li .divider { margin-left: 11px; margin-right: 11px } .dropdown-inverse li>a { border-radius: 2px; color: #fff; padding: 5px 11px 7px } .dropdown-inverse li>a:hover,.dropdown-inverse li>a:active,.dropdown-inverse li>a:focus { background: #2c3e50 } .dropdown-inverse li>a.highlighted { background: #526476 } .dropdown-inverse li>a.highlighted:hover,.dropdown-inverse li>a.highlighted:focus { background: #677786 } .dropdown-inverse li .divider { background-color: #526476; border-bottom-color: #526476 } .has-switch { border-radius: 30px; display: inline-block; cursor: pointer; line-height: 1.231; overflow: hidden; position: relative; text-align: left; width: 80px; -webkit-mask: url('../img/switch-mask.png') 0 0 no-repeat; mask: url('../img/switch-mask.png') 0 0 no-repeat; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none } .has-switch.deactivate { opacity: .5; filter: alpha(opacity=50); cursor: default!important } .has-switch.deactivate label,.has-switch.deactivate span { cursor: default!important } .has-switch>div { width: 162%; position: relative; top: 0 } .has-switch>div.switch-animate { -webkit-transition: left .25s ease-out; -moz-transition: left .25s ease-out; -o-transition: left .25s ease-out; transition: left .25s ease-out; -webkit-backface-visibility: hidden } .has-switch>div.switch-off { left: -63% } .has-switch>div.switch-off label { background-color: #7f8c9a; border-color: #bdc3c7; -webkit-box-shadow: -1px 0 0 rgba(255,255,255,0.5); -moz-box-shadow: -1px 0 0 rgba(255,255,255,0.5); box-shadow: -1px 0 0 rgba(255,255,255,0.5) } .has-switch>div.switch-on { left: 0 } .has-switch>div.switch-on label { background-color: #08c } .has-switch input[type=checkbox] { display: none } .has-switch span { cursor: pointer; font-size: 14.994px; font-weight: 700; float: left; height: 29px; line-height: 19px; margin: 0; padding-bottom: 6px; padding-top: 5px; position: relative; text-align: center; width: 50%; z-index: 1; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; -webkit-transition: .25s ease-out; -moz-transition: .25s ease-out; -o-transition: .25s ease-out; transition: .25s ease-out; -webkit-backface-visibility: hidden } .has-switch span.switch-left { border-radius: 30px 0 0 30px; background-color: #34495e; color: #ccc; border-left: 1px solid transparent } .has-switch span.switch-right { border-radius: 0 30px 30px 0; background-color: #bdc3c7; color: #fff; text-indent: 7px } .has-switch span.switch-right [class*="fui-"] { text-indent: 0 } .has-switch label { border: 4px solid #34495e; border-radius: 50%; float: left; height: 21px; margin: 0 -15px 0 -14px; padding: 0; position: relative; vertical-align: middle; width: 21px; z-index: 100; -webkit-transition: .25s ease-out; -moz-transition: .25s ease-out; -o-transition: .25s ease-out; transition: .25s ease-out; -webkit-backface-visibility: hidden } .switch-square { border-radius: 6px; -webkit-mask: url('../img/switch-mask.png') 0 0 no-repeat; mask: url('../img/switch-mask.png') 0 0 no-repeat } .switch-square>div.switch-off label { border-color: #7f8c9a; border-radius: 6px 0 0 6px } .switch-square span.switch-left { border-radius: 6px 0 0 6px } .switch-square span.switch-left [class*="fui-"] { text-indent: -10px } .switch-square span.switch-right { border-radius: 0 6px 6px 0 } .switch-square span.switch-right [class*="fui-"] { text-indent: 5px } .switch-square label { border-radius: 0 6px 6px 0; border-color: #1abc9c } .share { background-color: #eff0f2; position: relative; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px } .share:before { content: ""; border-style: solid; border-width: 0 9px 9px 9px; border-color: transparent transparent #eff0f2 transparent; height: 0; position: absolute; left: 23px; top: -9px; width: 0; -webkit-transform: rotate(360deg) } .share ul { list-style-type: none; margin: 0; padding: 15px } .share li { padding-top: 11px; *zoom: 1 } .share li:before,.share li:after { display: table; content: "" } .share li:after { clear: both } .share li:first-child { padding-top: 0 } .share .toggle { float: right; margin: 0 } .share .btn { -webkit-border-radius: 0 0 6px 6px; -moz-border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px } .share-label { float: left; font-size: 15px; padding-top: 5px; width: 50% } .palette { color: #fff; margin: 0; padding: 15px; text-transform: uppercase } .palette dt { display: block; font-weight: 500; opacity: .8; filter: alpha(opacity=80) } .palette dd { font-weight: 200; margin-left: 0; opacity: .8; filter: alpha(opacity=80) } .palette-turquoise { background-color: #1abc9c } .palette-green-sea { background-color: #08c } .palette-emerland { background-color: #2ecc71 } .palette-nephritis { background-color: #27ae60 } .palette-peter-river { background-color: #3498db } .palette-belize-hole { background-color: #2980b9 } .palette-amethyst { background-color: #9b59b6 } .palette-wisteria { background-color: #8e44ad } .palette-wet-asphalt { background-color: #34495e } .palette-midnight-blue { background-color: #2c3e50 } .palette-sun-flower { background-color: #f1c40f } .palette-orange { background-color: #f39c12 } .palette-carrot { background-color: #e67e22 } .palette-pumpkin { background-color: #d35400 } .palette-alizarin { background-color: #e74c3c } .palette-pomegranate { background-color: #c0392b } .palette-clouds { background-color: #ecf0f1 } .palette-silver { background-color: #bdc3c7 } .palette-concrete { background-color: #95a5a6 } .palette-asbestos { background-color: #7f8c8d } .palette-clouds { color: #bdc3c7 } .palette-paragraph { color: #7f8c8d; font-size: 12px; line-height: 17px } .palette-paragraph span { color: #bdc3c7 } .palette-headline { color: #7f8c8d; font-weight: 700; margin-top: -5px } .tile { background-color: #eff0f2; border-radius: 6px; padding: 14px; position: relative; text-align: center } .tile.tile-hot:before { background: url(../img/tile/ribbon.png) 0 0 no-repeat; background-size: 82px 82px; content: ''; height: 82px; position: absolute; right: -4px; top: -4px; width: 82px } .tile p { font-size: 15px; margin-bottom: 33px } .tile-image { height: 100px; margin: 31px 0 27px; vertical-align: bottom } .tile-image.big-illustration { height: 111px; margin-top: 20px; width: 112px } .tile-title { font-size: 20px; margin: 0 } @media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (-moz-min-device-pixel-ratio:2),only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-o-min-device-pixel-ratio:2/1),only screen and (-moz-min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:2) { .tile.tile-hot:before { background-image: url(../img/tile/ribbon-2x.png) } } .todo { background-color: #2c3e50; color: #798795; margin-bottom: 20px; -webkit-border-radius: 8px 8px 6px 6px; -moz-border-radius: 8px 8px 6px 6px; border-radius: 8px 8px 6px 6px } .todo ul { margin: 0; list-style-type: none } .todo li { background: #34495e url(../img/todo/todo.png) 92% center no-repeat; background-size: 20px 20px; cursor: pointer; margin-top: 2px; padding: 18px 42px 17px 25px; position: relative; -webkit-transition: .25s; -moz-transition: .25s; -o-transition: .25s; transition: .25s; -webkit-backface-visibility: hidden } .todo li:first-child { margin-top: 0 } .todo li:last-child { -webkit-border-radius: 0 0 6px 6px; -moz-border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px; padding-bottom: 18px } .todo li.todo-done { background: transparent url(../img/todo/done.png) 92% center no-repeat; background-size: 20px 20px; color: #1abc9c } .todo li.todo-done .todo-name { color: #1abc9c } .todo-search { position: relative; background: #1abc9c; background-size: 16px 16px; border-radius: 6px 6px 0 0; color: #34495e; padding: 19px 25px 20px } .todo-search:before { position: absolute; font-family: 'Flat-UI-Icons'; content: "\e01c"; font-size: 16px; display: inline-block; top: 50%; left: 92%; margin: -0.5em 0 0 -1em } input.todo-search-field { background: 0; border: 0; color: #34495e; font-size: 19px; font-weight: 700; margin: 0; line-height: 23px; padding: 5px 0; text-indent: 0; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none } input.todo-search-field:-moz-placeholder { color: #34495e } input.todo-search-field::-webkit-input-placeholder { color: #34495e } input.todo-search-field.placeholder { color: #34495e } .todo-icon { float: left; font-size: 24px; padding: 11px 22px 0 0 } .todo-content { padding-top: 1px; overflow: hidden } .todo-name { color: #fff; font-size: 17px; margin: 1px 0 3px } @media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (-moz-min-device-pixel-ratio:2),only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-o-min-device-pixel-ratio:2/1),only screen and (-moz-min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:2) { .todo li { background-image: url(../img/todo/todo-2x.png) } .todo li.todo-done { background-image: url(../img/todo/done-2x.png) } .todo-search { background-image: url(../img/todo/search-2x.png) } } footer { background-color: #edeff1; color: #bac1c8; font-size: 15px; padding: 0 } footer a { color: #9aa4af; font-weight: 700 } footer p { font-size: 15px; line-height: 20px } .footer-title { margin: 0 0 22px; padding-top: 21px } .footer-brand { display: block; margin-bottom: 26px; width: 220px } .footer-brand img { width: 216px } .footer-banner { background-color: #1abc9c; color: #d1f2eb; margin-left: 42px; min-height: 286px; padding: 0 30px 30px } .footer-banner .footer-title { color: #fff } .footer-banner a { color: #b7f5e9; text-decoration: underline } .footer-banner a:hover { text-decoration: none } .footer-banner ul { list-style-type: none; margin: 0 0 26px } .footer-banner ul li { border-top: 1px solid #1bc5a3; line-height: 19px; padding: 6px 0 } .footer-banner ul li:first-child { border-top: 0; padding-top: 1px } .video-js { background-color: transparent; margin-top: -95px; position: relative; padding: 0; font-size: 10px; vertical-align: middle; -webkit-border-radius: 6px 6px 0 0; -moz-border-radius: 6px 6px 0 0; border-radius: 6px 6px 0 0; -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; -ms-backface-visibility: hidden; backface-visibility: hidden } .video-js .vjs-tech { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-border-radius: 6px 6px 0 0; -moz-border-radius: 6px 6px 0 0; border-radius: 6px 6px 0 0 } .video-js:-moz-full-screen { position: absolute } body.vjs-full-window { padding: 0; margin: 0; height: 100%; overflow-y: auto } .video-js.vjs-fullscreen { position: fixed; overflow: hidden; z-index: 1000; left: 0; top: 0; bottom: 0; right: 0; width: 100%!important; height: 100%!important; _position: absolute } .video-js:-webkit-full-screen { width: 100%!important; height: 100%!important } .vjs-poster { margin: 0 auto; padding: 0; cursor: pointer; position: relative; width: 100%; max-height: 100%; -webkit-border-radius: 6px 6px 0 0; -moz-border-radius: 6px 6px 0 0; border-radius: 6px 6px 0 0 } .video-js .vjs-text-track-display { text-align: center; position: absolute; bottom: 4em; left: 1em; right: 1em; font-family: "Lato",sans-serif } .video-js .vjs-text-track { display: none; color: #fff; font-size: 1.4em; text-align: center; margin-bottom: .1em; background: #000; background: rgba(0,0,0,0.5) } .video-js .vjs-subtitles { color: #fff } .video-js .vjs-captions { color: #fc6 } .vjs-tt-cue { display: block } .vjs-fade-in { visibility: visible!important; opacity: 1!important; -webkit-transition: visibility 0s linear 0s,opacity .3s linear; -moz-transition: visibility 0s linear 0s,opacity .3s linear; -o-transition: visibility 0s linear 0s,opacity .3s linear; transition: visibility 0s linear 0s,opacity .3s linear; -webkit-backface-visibility: hidden } .vjs-fade-out { visibility: hidden!important; opacity: 0!important; -webkit-transition: visibility 0s linear 1.5s,opacity 1.5s linear; -moz-transition: visibility 0s linear 1.5s,opacity 1.5s linear; -o-transition: visibility 0s linear 1.5s,opacity 1.5s linear; transition: visibility 0s linear 1.5s,opacity 1.5s linear; -webkit-backface-visibility: hidden } .vjs-controls { position: absolute; bottom: -47px; left: 0; right: 0; margin: 0; padding: 0; height: 47px; color: #fff; background: #273747; -webkit-border-radius: 0 0 6px 6px; -moz-border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px } .vjs-controls.vjs-fade-out { visibility: visible!important; opacity: 1!important } .vjs-control { background-position: center center; background-repeat: no-repeat; position: relative; float: left; text-align: center; margin: 0; padding: 0; height: 18px; width: 18px } .vjs-control:focus { outline: 0 } .vjs-control div { background-position: center center; background-repeat: no-repeat } .vjs-control-text { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px } .vjs-play-control { cursor: pointer!important; height: 47px; left: 0; position: absolute; top: 0; width: 58px } .vjs-play-control div { position: relative; height: 47px } .vjs-play-control div:before,.vjs-play-control div:after { position: absolute; font-family: "Flat-UI-Icons"; color: #1abc9c; font-size: 16px; top: 50%; left: 50%; margin: -0.55em 0 0 -0.5em; -webkit-transition: color .25s,opacity .25s; -moz-transition: color .25s,opacity .25s; -o-transition: color .25s,opacity .25s; transition: color .25s,opacity .25s; -webkit-backface-visibility: hidden } .vjs-play-control div:after { content: "\e03b" } .vjs-play-control div:before { content: "\e03c" } .vjs-paused .vjs-play-control:hover div:before { color: #08c } .vjs-paused .vjs-play-control div:after { opacity: 0; filter: alpha(opacity=0) } .vjs-paused .vjs-play-control div:before { opacity: 1; filter: alpha(opacity=100) } .vjs-playing .vjs-play-control:hover div:after { color: #08c } .vjs-playing .vjs-play-control div:after { opacity: 1; filter: alpha(opacity=100) } .vjs-playing .vjs-play-control div:before { opacity: 0; filter: alpha(opacity=0) } .vjs-rewind-control { width: 5em; cursor: pointer!important } .vjs-rewind-control div { width: 19px; height: 16px; background: none transparent; margin: .5em auto 0 } .vjs-mute-control { background: url(../img/video/volume-full.png) center -48px no-repeat; background-size: 16px 64px; cursor: pointer!important; position: absolute; right: 51px; top: 14px } .vjs-mute-control:hover div,.vjs-mute-control:focus div { opacity: 0 } .vjs-mute-control.vjs-vol-0,.vjs-mute-control.vjs-vol-0 div { background-image: url(../img/video/volume-off.png) } .vjs-mute-control div { background: #273747 url(../img/video/volume-full.png) no-repeat center 2px; background-size: 16px 64px; height: 18px; -webkit-transition: opacity .25s; -moz-transition: opacity .25s; -o-transition: opacity .25s; transition: opacity .25s; -webkit-backface-visibility: hidden } .vjs-volume-control,.vjs-volume-level,.vjs-volume-handle,.vjs-volume-bar { display: none } .vjs-progress-control { position: absolute; left: 60px; right: 180px; height: 12px; width: auto; top: 18px; background: #425669; -webkit-border-radius: 32px; -moz-border-radius: 32px; border-radius: 32px } .vjs-progress-holder { position: relative; cursor: pointer!important; padding: 0; margin: 0; height: 12px } .vjs-play-progress,.vjs-load-progress { position: absolute; display: block; height: 12px; margin: 0; padding: 0; left: 0; top: 0; -webkit-border-radius: 32px; -moz-border-radius: 32px; border-radius: 32px } .vjs-play-progress { background: #1abc9c; left: -1px } .vjs-load-progress { background: #d6dbdf; -webkit-border-radius: 32px 0 0 32px; -moz-border-radius: 32px 0 0 32px; border-radius: 32px 0 0 32px } .vjs-load-progress[style*='100%'],.vjs-load-progress[style*='99%'] { -webkit-border-radius: 32px; -moz-border-radius: 32px; border-radius: 32px } .vjs-seek-handle { background-color: #08c; position: absolute; width: 18px; height: 18px; margin: -3px 0 0 1px; left: 0; top: 0; -webkit-transition: background-color .25s; -moz-transition: background-color .25s; -o-transition: background-color .25s; transition: background-color .25s; -webkit-backface-visibility: hidden; -webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50% } .vjs-seek-handle[style*='95.'] { margin-left: 3px } .vjs-seek-handle[style='left: 0%;'] { margin-left: -2px } .vjs-seek-handle:hover,.vjs-seek-handle:focus { background-color: #148d75 } .vjs-seek-handle:active { background-color: #117a65 } .vjs-time-controls { position: absolute; height: 20px; width: 50px; top: 16px; font: 300 13px "Lato",sans-serif } .vjs-current-time { right: 128px; text-align: right } .vjs-duration { color: #5d6d7e; right: 69px; text-align: left } .vjs-remaining-time { display: none } .vjs-time-divider { color: #5d6d7e; font-size: 14px; position: absolute; right: 121px; top: 15px } .vjs-secondary-controls { float: right } .vjs-fullscreen-control { background-image: url(../img/video/fullscreen.png); background-position: center -47px; background-size: 15px 64px; cursor: pointer!important; position: absolute; right: 17px; top: 13px } .vjs-fullscreen-control:hover div,.vjs-fullscreen-control:focus div { opacity: 0 } .vjs-fullscreen-control div { height: 18px; background: url(../img/video/fullscreen.png) no-repeat center 2px; background-size: 15px 64px; -webkit-transition: opacity .25s; -moz-transition: opacity .25s; -o-transition: opacity .25s; transition: opacity .25s; -webkit-backface-visibility: hidden } .vjs-menu-button { display: none!important } @-webkit-keyframes sharp .sharp-keyframes(); @-moz-keyframes sharp .sharp-keyframes(); @-o-keyframes sharp .sharp-keyframes(); @keyframes sharp .sharp-keyframes(); .vjs-loading-spinner { background: #ebedee; display: none; height: 16px; left: 50%; margin: -8px 0 0 -8px; position: absolute; top: 50%; width: 16px; -webkit-animation: sharp 2s ease infinite; -moz-animation: sharp 2s ease infinite; -o-animation: sharp 2s ease infinite; animation: sharp 2s ease infinite; -webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px } .login { background: url(../img/login/imac.png) 0 0 no-repeat; background-size: 940px 778px; color: #fff; margin-bottom: 77px; padding: 38px 38px 267px; position: relative } .login-screen { background-color: #1abc9c; min-height: 317px; padding: 123px 199px 33px 306px } .login-icon { left: 200px; position: absolute; top: 160px; width: 96px } .login-icon>img { display: block; margin-bottom: 6px; width: 100% } .login-icon>h4 { font-size: 17px; font-weight: 200; line-height: 34px; opacity: .95; filter: alpha(opacity=95) } .login-icon>h4 small { color: inherit; display: block; font-size: inherit; font-weight: 700 } .login-form { background-color: #edeff1; padding: 24px 23px 20px; position: relative; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px } .login-form:before { content: ''; border-style: solid; border-width: 12px 12px 12px 0; border-color: transparent #edeff1 transparent transparent; height: 0; position: absolute; left: -12px; top: 35px; width: 0; -webkit-transform: rotate(360deg) } .login-form .control-group { margin-bottom: 6px; position: relative } .login-form .login-field { border-color: transparent; font-size: 17px; padding-bottom: 11px; padding-top: 11px; text-indent: 3px; width: 299px; margin-bottom: 10px!important } .login-form .login-field:focus+.login-field-icon { color: #1abc9c } .login-form .login-field-icon { color: #bfc9ca; font-size: 16px; position: absolute; right: 13px; top: 14px; -webkit-transition: .25s; -moz-transition: .25s; -o-transition: .25s; transition: .25s; -webkit-backface-visibility: hidden } .login-link { color: #bfc9ca; display: block; font-size: 13px; margin-top: 15px; text-align: center } @media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (-moz-min-device-pixel-ratio:2),only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-o-min-device-pixel-ratio:2/1),only screen and (-moz-min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:2) { .login { background-image: url(../img/login/imac-2x.png) } } .last-col { overflow: hidden } .ptn,.pvn,.pan { padding-top: 0 } .ptx,.pvx,.pax { padding-top: 3px } .pts,.pvs,.pas { padding-top: 5px } .ptm,.pvm,.pam { padding-top: 10px } .ptl,.pvl,.pal { padding-top: 20px } .prn,.phn,.pan { padding-right: 0 } .prx,.phx,.pax { padding-right: 3px } .prs,.phs,.pas { padding-right: 5px } .prm,.phm,.pam { padding-right: 10px } .prl,.phl,.pal { padding-right: 20px } .pbn,.pvn,.pan { padding-bottom: 0 } .pbx,.pvx,.pax { padding-bottom: 3px } .pbs,.pvs,.pas { padding-bottom: 5px } .pbm,.pvm,.pam { padding-bottom: 10px } .pbl,.pvl,.pal { padding-bottom: 20px } .pln,.phn,.pan { padding-left: 0 } .plx,.phx,.pax { padding-left: 3px } .pls,.phs,.pas { padding-left: 5px } .plm,.phm,.pam { padding-left: 10px } .pll,.phl,.pal { padding-left: 20px } .mtn,.mvn,.man { margin-top: 0 } .mtx,.mvx,.max { margin-top: 3px } .mts,.mvs,.mas { margin-top: 5px } .mtm,.mvm,.mam { margin-top: 10px } .mtl,.mvl,.mal { margin-top: 20px } .mrn,.mhn,.man { margin-right: 0 } .mrx,.mhx,.max { margin-right: 3px } .mrs,.mhs,.mas { margin-right: 5px } .mrm,.mhm,.mam { margin-right: 10px } .mrl,.mhl,.mal { margin-right: 20px } .mbn,.mvn,.man { margin-bottom: 0 } .mbx,.mvx,.max { margin-bottom: 3px } .mbs,.mvs,.mas { margin-bottom: 5px } .mbm,.mvm,.mam { margin-bottom: 10px } .mbl,.mvl,.mal { margin-bottom: 20px } .mln,.mhn,.man { margin-left: 0 } .mlx,.mhx,.max { margin-left: 3px } .mls,.mhs,.mas { margin-left: 5px } .mlm,.mhm,.mam { margin-left: 10px } .mll,.mhl,.mal { margin-left: 20px } ================================================ FILE: code/default/launcher/web_ui/css/primer-markdown.css ================================================ .markdown-body { color: #24292e; min-width: 888px; padding: 15px; overflow: auto; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: 16px; line-height: 1.5; word-wrap: break-word } .markdown-body::before { display: table; content: "" } .markdown-body::after { display: table; clear: both; content: "" } .markdown-body > *:first-child { margin-top: 0 !important } .markdown-body > *:last-child { margin-bottom: 0 !important } .markdown-body a:not([href]) { color: inherit; text-decoration: none } .markdown-body .absent { color: #cb2431 } .markdown-body .anchor { float: left; padding-right: 4px; margin-left: -20px; line-height: 1 } .markdown-body .anchor:focus { outline: none } .markdown-body p, .markdown-body blockquote, .markdown-body ul, .markdown-body ol, .markdown-body dl, .markdown-body table, .markdown-body pre { margin-top: 0; margin-bottom: 16px } .markdown-body hr { height: .25em; padding: 0; margin: 24px 0; background-color: #e1e4e8; border: 0 } .markdown-body blockquote { padding: 0 1em; color: #6a737d; border-left: 0.25em solid #dfe2e5 } .markdown-body blockquote > :first-child { margin-top: 0 } .markdown-body blockquote > :last-child { margin-bottom: 0 } .markdown-body kbd { display: inline-block; padding: 3px 5px; font-size: 11px; line-height: 10px; color: #444d56; vertical-align: middle; background-color: #fafbfc; border: solid 1px #c6cbd1; border-bottom-color: #959da5; border-radius: 3px; box-shadow: inset 0 -1px 0 #959da5 } .markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { margin-top: 24px; margin-bottom: 16px; font-weight: 600; line-height: 1.25 } .markdown-body h1 .octicon-link, .markdown-body h2 .octicon-link, .markdown-body h3 .octicon-link, .markdown-body h4 .octicon-link, .markdown-body h5 .octicon-link, .markdown-body h6 .octicon-link { color: #1b1f23; vertical-align: middle; visibility: hidden } .markdown-body h1:hover .anchor, .markdown-body h2:hover .anchor, .markdown-body h3:hover .anchor, .markdown-body h4:hover .anchor, .markdown-body h5:hover .anchor, .markdown-body h6:hover .anchor { text-decoration: none } .markdown-body h1:hover .anchor .octicon-link, .markdown-body h2:hover .anchor .octicon-link, .markdown-body h3:hover .anchor .octicon-link, .markdown-body h4:hover .anchor .octicon-link, .markdown-body h5:hover .anchor .octicon-link, .markdown-body h6:hover .anchor .octicon-link { visibility: visible } .markdown-body h1 tt, .markdown-body h1 code, .markdown-body h2 tt, .markdown-body h2 code, .markdown-body h3 tt, .markdown-body h3 code, .markdown-body h4 tt, .markdown-body h4 code, .markdown-body h5 tt, .markdown-body h5 code, .markdown-body h6 tt, .markdown-body h6 code { font-size: inherit } .markdown-body h1 { padding-bottom: 0.3em; font-size: 2em; border-bottom: 1px solid #eaecef } .markdown-body h2 { padding-bottom: 0.3em; font-size: 1.5em; border-bottom: 1px solid #eaecef } .markdown-body h3 { font-size: 1.25em } .markdown-body h4 { font-size: 1em } .markdown-body h5 { font-size: 0.875em } .markdown-body h6 { font-size: 0.85em; color: #6a737d } .markdown-body ul, .markdown-body ol { padding-left: 2em } .markdown-body ul.no-list, .markdown-body ol.no-list { padding: 0; list-style-type: none } .markdown-body ul ul, .markdown-body ul ol, .markdown-body ol ol, .markdown-body ol ul { margin-top: 0; margin-bottom: 0 } .markdown-body li { word-wrap: break-all } .markdown-body li > p { margin-top: 16px } .markdown-body li + li { margin-top: .25em } .markdown-body dl { padding: 0 } .markdown-body dl dt { padding: 0; margin-top: 16px; font-size: 1em; font-style: italic; font-weight: 600 } .markdown-body dl dd { padding: 0 16px; margin-bottom: 16px } .markdown-body table { display: block; width: 100%; overflow: auto } .markdown-body table th { font-weight: 600 } .markdown-body table th, .markdown-body table td { padding: 6px 13px; border: 1px solid #dfe2e5 } .markdown-body table tr { background-color: #fff; border-top: 1px solid #c6cbd1 } .markdown-body table tr:nth-child(2n) { background-color: #f6f8fa } .markdown-body table img { background-color: transparent } .markdown-body img { max-width: 100%; box-sizing: content-box; background-color: #fff } .markdown-body img[align=right] { padding-left: 20px } .markdown-body img[align=left] { padding-right: 20px } .markdown-body .emoji { max-width: none; vertical-align: text-top; background-color: transparent } .markdown-body span.frame { display: block; overflow: hidden } .markdown-body span.frame > span { display: block; float: left; width: auto; padding: 7px; margin: 13px 0 0; overflow: hidden; border: 1px solid #dfe2e5 } .markdown-body span.frame span img { display: block; float: left } .markdown-body span.frame span span { display: block; padding: 5px 0 0; clear: both; color: #24292e } .markdown-body span.align-center { display: block; overflow: hidden; clear: both } .markdown-body span.align-center > span { display: block; margin: 13px auto 0; overflow: hidden; text-align: center } .markdown-body span.align-center span img { margin: 0 auto; text-align: center } .markdown-body span.align-right { display: block; overflow: hidden; clear: both } .markdown-body span.align-right > span { display: block; margin: 13px 0 0; overflow: hidden; text-align: right } .markdown-body span.align-right span img { margin: 0; text-align: right } .markdown-body span.float-left { display: block; float: left; margin-right: 13px; overflow: hidden } .markdown-body span.float-left span { margin: 13px 0 0 } .markdown-body span.float-right { display: block; float: right; margin-left: 13px; overflow: hidden } .markdown-body span.float-right > span { display: block; margin: 13px auto 0; overflow: hidden; text-align: right } .markdown-body code, .markdown-body tt { padding: 0.2em 0.4em; margin: 0; font-size: 85%; color: #24292e; background-color: rgba(27, 31, 35, 0.05); border-radius: 3px } .markdown-body code br, .markdown-body tt br { display: none } .markdown-body del code { text-decoration: inherit } .markdown-body pre { word-wrap: normal } .markdown-body pre > code { padding: 0; margin: 0; font-size: 100%; word-break: normal; white-space: pre; background: transparent; border: 0 } .markdown-body .highlight { margin-bottom: 16px } .markdown-body .highlight pre { margin-bottom: 0; word-break: normal } .markdown-body .highlight pre, .markdown-body pre { padding: 16px; overflow: auto; font-size: 85%; line-height: 1.45; background-color: #f6f8fa; border-radius: 3px } .markdown-body pre code, .markdown-body pre tt { display: inline; max-width: auto; padding: 0; margin: 0; overflow: visible; line-height: inherit; word-wrap: normal; background-color: transparent; border: 0 } .markdown-body .csv-data td, .markdown-body .csv-data th { padding: 5px; overflow: hidden; font-size: 12px; line-height: 1; text-align: left; white-space: nowrap } .markdown-body .csv-data .blob-num { padding: 10px 8px 9px; text-align: right; background: #fff; border: 0 } .markdown-body .csv-data tr { border-top: 0 } .markdown-body .csv-data th { font-weight: 600; background: #f6f8fa; border-top: 0 } ================================================ FILE: code/default/launcher/web_ui/css/style.css ================================================ html, body { font-family: "Microsoft YaHei", "Segoe UI Light", "Segoe UI", "Heiti SC"; margin: 0; padding: 0; } .container-fluid{ padding-left: 1rem; padding-right: 1rem; } button, input, select, textarea { font-family: "Microsoft YaHei", "Segoe UI Light", "Segoe UI", "Heiti SC" !important; } a { text-decoration: none !important; cursor: pointer; } select { border: 2px solid #bdc3c7; color: #34495e; display: inline-block; font-family: "Lato", sans-serif; font-size: 14px; padding: 8px 5px; height: 41px; text-indent: 6px; width: 100%; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; -webkit-transition: border .25s linear,color .25s linear; -moz-transition: border .25s linear,color .25s linear; -o-transition: border .25s linear,color .25s linear; transition: border .25s linear,color .25s linear; } button.btn-danger, button[type=submit] { margin-top: 10px; } select:focus { border-color: #3498db; outline: none; } .navbar-fixed-top { position:fixed; top:0; width:100%; } div#header a { color: #fff; text-decoration: none; } div#header div#logo { padding: 4px 0; } div#header div#logo img { height: 32px; max-height: 32px; } #version_on_logo { margin: 0 5px; font-size: 70%; } div#header a#resize-window-trigger, div#header a#menu-button, div#header a#quit-trigger { display: block; padding-top: 8px; } div#header img { max-height: 22px; } .align-right { position: absolute; top: 5px; right: 30px; } div#content { margin: 40px auto 0; padding-top: 3rem; } div#content div#sidebar a { text-decoration: none; } div#content h2 { margin: 0 0 20px; } div#content div.alert p.message { margin-bottom: 0; } div#content form div.row-fluid { margin-bottom: 10px; } div#content div.row-fluid > div.span4 > label { font-weight: bold; margin: 10px 0 0; } div#content div.row-fluid > div.span3 > label { font-weight: bold; margin: 10px 0 0; } div#content div.row-fluid > div.span2 > label { font-weight: bold; margin: 10px 0 0; } div#content div.row-fluid > div.span1 > label { font-weight: bold; margin: 10px 0 0; } div#content form div.row-fluid > div.span4 > label > a { font-weight: normal; text-decoration: none; } div#content input[type=text], div#content input[type=number], div#content input[type=password] { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } div#content div#advanced-options, div#content div#module-switch { padding-left: 20px; } div#content textarea { color: #34495e; height: 285px; max-width: 100%; resize: none; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } div#content ul.nav-tabs { margin-bottom: 0; } div#content div.tab-content { border: 1px solid #ddd; border-top: none; min-height: 360px; padding: 20px 10px; } /* Style for config.html in PHP-Proxy */ div#content form#gae_proxy-php-config div.row-fluid div.span4 label[for=enable-php-proxy] { margin-top: 5px; } div#content form#gae_proxy-php-config div.row-fluid div.span4 label[for=enable-php-proxy] > a { font-weight: normal; text-decoration: none; } /* Style for status.html */ table#status td { word-wrap: break-word; } table#plan th { text-align:center; } table#plan td { text-align:center; vertical-align:middle; } table#quota_list_table th { text-align:center; } table#quota_list_table td { text-align:center; vertical-align:middle; } div#report-issue-modal { position: fixed; } /* Style for logging.html */ div#log { background-color: #f4f6f6; border: 2px solid #d5dbdb; border-radius: 6px; color: #34495e; font-size: 14.994px; height: 285px; line-height: 24px; max-width: 100%; overflow-y: auto; padding: 5px 11px; text-indent: 0; } div#log > p { margin-bottom: 0; word-wrap: break-word; } td#working-appid { word-wrap: break-word; word-break: break-all; } /* Styles for deploy.html */ div#content div#deploy p.tip { font-size: 13px; margin-top: 5px; } /* Styles for about.html */ div#content div#about a { text-decoration: none; } div#content div#about div.row-fluid div.span4 { font-weight: bold; } div#content div#thanks ul { list-style: none; margin: 0; } div#content div#thanks li { line-height: 150%; } /* Styles for config.html in System */ div#content div#options div.row-fluid { margin-bottom: 10px; } div#content div#options div.row-fluid div.span4, .bold { font-weight: bold; padding-top: 5px; } #noob-info { padding: 10px; margin: 40px 0; color: #b94a48; background-color: #f2dede; border:1px solid; border-color: #eed3d7; border-radius: 4px; transition: color .3s,background .3s,border .3s; } #noob-info.hard { color: #468847; background-color: #dff0d8; border-color: #d6e9c6; } #noob-info.fluent { color: #146C98; background-color: #d9edf7; border-color: #bce8f1; } #update-notify, .popnotify { padding: 6px; margin: 10px 0; background-color: #dff0d8; border:1px solid; border-color: #cfe0c8; border-radius: 4px; transition: color .3s,background .3s,border .3s; } #update-message{ font-size: 120%; color: #507050; } .update-notify-action { float: right; color: #0072E3; cursor: pointer; margin: 0 6px; } #update-notify-close { float: right; cursor: pointer; margin-left: 7px; color: #b94a48; } #details, #update-options, #modules-manager{ overflow: hidden; } /* Style for config.html in X-Tunnel */ .modal h5 { margin: 0; } div#info.tab-pane div.section { margin-bottom: 20px; } div#info.tab-pane form#login-form, div#info.tab-pane form#register-form { max-width: 640px; } div#info.tab-pane div#account-information p, div#help.tab-pane p { margin-top: 10px; } div#plans.tab-pane h1.price { text-align: center; } div#plans.tab-pane ul.details { color: #8e8e8e; list-style: none; margin: 0; } div#plans.tab-pane ul.details div.span4.text-right { color: #747474; font-weight: bold; } div#history.tab-pane > div.row-fluid { margin-bottom: 10px; } div#history.tab-pane h4 { padding-top: 5px; } /* Smaller than standard 1200 (devices and browsers) */ @media only screen and (max-width: 1199px) { } /* Portrait size to standard 1200 (devices and browsers) */ @media only screen and (min-width: 960px) and (max-width: 1199px) { div.container { width: 960px; } } /* Smaller than standard 960 (devices and browsers) */ @media only screen and (max-width: 959px) { } /* Tablet Portrait size to standard 960 (devices and browsers) */ @media only screen and (min-width: 768px) and (max-width: 959px) { div.container { width: 768px; } } /* All Mobile Sizes (devices and browser) */ @media only screen and (max-width: 767px) { div#header { margin: 0; } div#header div.span8 { display: none; } div#header div#logo { text-align: center; } } /* Mobile Landscape Size to Tablet Portrait (devices and browsers) */ @media only screen and (min-width: 480px) and (max-width: 767px) { div.container { width: 480px; } } /* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */ @media only screen and (max-width: 479px) { div.container { width: 320px; } } .config_label { display: inline-block; font-weight: bold; margin: 10px 0 0; max-width: 100%; overflow: hidden; } .config_switch { float: right; padding-right: 1rem; margin: 10px 0 0; } #loading_animation { height: 250px; top: 50%; text-align: center; } .p80 { max-width: 600px; text-align: center; } .plan-block { margin-left: 10px; margin-top: 10px; margin-bottom: 10px; text-align: center; } ================================================ FILE: code/default/launcher/web_ui/index.html ================================================ {{ _( "APP_NAME" ) }}
    × {{ _( "Update now" ) }} {{ _( "Remind me later" ) }} {{ _( "Do not remind me this version" ) }}   {{ _( "View changes" ) }}

    %s
    ================================================ FILE: code/default/launcher/web_ui/js/flat-ui.js ================================================ /*! * Flat UI Free v2.0.0 (http://designmodo.github.io/Flat-UI/) * Copyright 2013-2014 Designmodo, Inc. */ /* ============================================================ * bootstrapSwitch v1.3 by Larentis Mattia @spiritualGuru * http://www.larentis.eu/switch/ * ============================================================ * Licensed under the Apache License, Version 2.0 * http://www.apache.org/licenses/LICENSE-2.0 * ============================================================ */ !function ($) { "use strict"; $.fn['bootstrapSwitch'] = function (method) { var methods = { init: function () { return this.each(function () { var $element = $(this) , $div , $switchLeft , $switchRight , $label , myClasses = "" , classes = $element.attr('class') , color , moving , onLabel = "ON" , offLabel = "OFF" , icon = false; $.each(['switch-mini', 'switch-small', 'switch-large'], function (i, el) { if (classes.indexOf(el) >= 0) myClasses = el; }); $element.addClass('has-switch'); if ($element.data('on') !== undefined) color = "switch-" + $element.data('on'); if ($element.data('on-label') !== undefined) onLabel = $element.data('on-label'); if ($element.data('off-label') !== undefined) offLabel = $element.data('off-label'); if ($element.data('icon') !== undefined) icon = $element.data('icon'); $switchLeft = $('') .addClass("switch-left") .addClass(myClasses) .addClass(color) .html(onLabel); color = ''; if ($element.data('off') !== undefined) color = "switch-" + $element.data('off'); $switchRight = $('') .addClass("switch-right") .addClass(myClasses) .addClass(color) .html(offLabel); $label = $('