Bug 1479503: Check infer in ./mach static-analysis autotest. r=nalexander
authorRobert Bartlensky <bartlensky.robert@gmail.com>
Wed, 24 Oct 2018 21:54:34 +0000
changeset 442875 8e850a230bfcfb52e5dc15d146a402c7d8521ab8
parent 442874 7e0e03b9169e2c5046e8bd8b947edccf04fbdc1b
child 442876 74050b668ada1a9f3ddabfed1a98cc2b969f067f
push id34926
push userncsoregi@mozilla.com
push dateThu, 25 Oct 2018 04:44:20 +0000
treeherdermozilla-central@58b7faab3b8d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnalexander
bugs1479503
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1479503: Check infer in ./mach static-analysis autotest. r=nalexander Now autotest does not require java to be installed, but it will let the user know that infer is not being tested if java is missing. Differential Revision: https://phabricator.services.mozilla.com/D7326
.flake8
.hgignore
python/mozbuild/mozbuild/mach_commands.py
taskcluster/ci/docker-image/kind.yml
taskcluster/ci/static-analysis-autotest/kind.yml
taskcluster/ci/toolchain/linux.yml
taskcluster/docker/static-analysis-build/Dockerfile
testing/mozharness/mozharness/mozilla/building/buildbase.py
tools/infer/config.yaml
tools/infer/test/autotest/build.gradle
tools/infer/test/autotest/src/main/java/Biabduction.java
tools/infer/test/autotest/src/main/java/Biabduction.json
tools/infer/test/autotest/src/main/java/Checkers.java
tools/infer/test/autotest/src/main/java/Checkers.json
tools/infer/test/autotest/src/main/java/Eradicate.java
tools/infer/test/autotest/src/main/java/Racerd.java
tools/infer/test/autotest/src/main/java/Racerd.json
tools/infer/test/autotest/src/main/java/Starvation.java
tools/infer/test/autotest/src/main/java/Starvation.json
tools/infer/test/build.gradle
tools/infer/test/gradle.properties
tools/infer/test/gradle/wrapper/gradle-wrapper.jar
tools/infer/test/gradle/wrapper/gradle-wrapper.properties
tools/infer/test/gradlew
tools/infer/test/gradlew.bat
tools/infer/test/settings.gradle
--- a/.flake8
+++ b/.flake8
@@ -17,8 +17,9 @@ exclude =
     js/*.configure,
     memory/moz.configure,
     mobile/android/*.configure,
     node_modules,
     security/nss/,
     testing/mochitest/pywebsocket,
     tools/lint/test/files,
     build/build-infer/build-infer.py,
+    tools/infer/test/*.configure,    tools/infer/test/*.configure,
\ No newline at end of file
--- a/.hgignore
+++ b/.hgignore
@@ -69,16 +69,17 @@ compile_commands\.json
 # Ignore the files and directory that JetBrains IDEs create.
 \.idea/
 \.iml$
 # Android Monitor in Android Studio creates a captures/ directory.
 ^captures/
 
 # Gradle cache.
 ^.gradle/
+^tools/infer/test/.gradle/
 
 # Local Gradle configuration properties.
 ^local.properties$
 
 # Python stuff installed at build time.
 ^third_party/python/psutil/.*\.so
 ^third_party/python/psutil/.*\.pyd
 ^third_party/python/psutil/build/
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -1699,24 +1699,18 @@ class StaticAnalysis(MachCommandBase):
             StaticAnalysisFooter,
             StaticAnalysisOutputManager,
         )
 
         self._set_log_level(verbose)
         self.log_manager.enable_all_structured_loggers()
 
         rc = self._build_compile_db(verbose=verbose)
-        if rc != 0:
-            return rc
-
-        rc = self._build_export(jobs=jobs, verbose=verbose)
-        if rc != 0:
-            return rc
-
-        rc = self._get_clang_tools(verbose=verbose)
+        rc = rc or self._build_export(jobs=jobs, verbose=verbose)
+        rc = rc or self._get_clang_tools(verbose=verbose)
         if rc != 0:
             return rc
 
         compile_db = json.loads(open(self._compile_db, 'r').read())
         total = 0
         import re
         name_re = re.compile('(' + ')|('.join(source) + ')')
         for f in compile_db:
@@ -1771,16 +1765,19 @@ class StaticAnalysis(MachCommandBase):
                    task='compileLocalWithGeckoBinariesNoMinApiDebugSources',
                    skip_export=False):
         self._set_log_level(verbose)
         self.log_manager.enable_all_structured_loggers()
         if self.substs['MOZ_BUILD_APP'] != 'mobile/android':
             self.log(logging.WARNING, 'static-analysis', {},
                      'Cannot check java source code unless you are building for android!')
             return 1
+        rc = self._check_for_java()
+        if rc != 0:
+            return 1
         # if source contains the whole mobile folder, then we just have to
         # analyze everything
         check_all = any(i.rstrip(os.sep).split(os.sep)[-1] == 'mobile' for i in source)
         # gather all java sources from the source variable
         java_sources = []
         if not check_all:
             java_sources = self._get_java_files(source)
             if not java_sources:
@@ -1795,31 +1792,25 @@ class StaticAnalysis(MachCommandBase):
                      'This command is only available for linux64!')
             return rc
         # which checkers to use, and which folders to exclude
         all_checkers, third_party_path = self._get_infer_config()
         checkers, excludes = self._get_infer_args(
             checks=checks or all_checkers,
             third_party_path=third_party_path
         )
-        gradlew = mozpath.join(self.topsrcdir, 'gradlew')
+        rc = rc or self._gradle(['clean'])  # clean so that we can recompile
         # infer capture command
-        capture_cmd = [self._infer_path, 'capture'] + excludes + \
-            ['--', gradlew, task]
+        capture_cmd = [self._infer_path, 'capture'] + excludes + ['--']
+        rc = rc or self._gradle([task], infer_args=capture_cmd, verbose=verbose)
         tmp_file, args = self._get_infer_source_args(java_sources)
         # infer analyze command
         analysis_cmd = [self._infer_path, 'analyze', '--keep-going'] +  \
             checkers + args
-        # capture, then analyze the sources
-        for args in [[gradlew, 'clean'], capture_cmd, analysis_cmd]:
-            rc = self.run_process(args=args, cwd=self.topsrcdir,
-                                  pass_thru=True)
-            # if a command fails, break and close the tmp file before returning
-            if rc != 0:
-                break
+        rc = rc or self.run_process(args=analysis_cmd, cwd=self.topsrcdir, pass_thru=True)
         if tmp_file:
             tmp_file.close()
         return rc
 
     def _get_java_files(self, sources):
         java_sources = []
         for i in sources:
             f = mozpath.join(self.topsrcdir, i)
@@ -1913,16 +1904,57 @@ class StaticAnalysis(MachCommandBase):
         if fix:
             common_args += '-fix'
 
         return [
             self.virtualenv_manager.python_path, self._run_clang_tidy_path, '-j',
             str(jobs), '-p', self._compilation_commands_path
         ] + common_args + sources
 
+    def _check_for_java(self):
+        '''Check if javac can be found.'''
+        import distutils
+        java = self.substs.get('JAVA')
+        java = java or os.getenv('JAVA_HOME')
+        java = java or distutils.spawn.find_executable('javac')
+        error = 'javac was not found! Please install javac and either add it to your PATH, '
+        error += 'set JAVA_HOME, or add the following to your mozconfig:\n'
+        error += '  --with-java-bin-path=/path/to/java/bin/'
+        if not java:
+            self.log(logging.ERROR, 'ERROR: static-analysis', {}, error)
+            return 1
+        return 0
+
+    def _gradle(self, args, infer_args=None, verbose=False, autotest=False,
+                suppress_output=True):
+        infer_args = infer_args or []
+        if autotest:
+            cwd = mozpath.join(self.topsrcdir, 'tools', 'infer', 'test')
+            gradle = mozpath.join(cwd, 'gradlew')
+        else:
+            gradle = self.substs['GRADLE']
+            cwd = self.topsrcdir
+        extra_env = {
+            'GRADLE_OPTS': '-Dfile.encoding=utf-8',  # see mobile/android/mach_commands.py
+            'JAVA_TOOL_OPTIONS': '-Dfile.encoding=utf-8',
+        }
+        if suppress_output:
+            devnull = open(os.devnull, 'w')
+            return subprocess.call(
+                infer_args + [gradle] + args,
+                env=dict(os.environ, **extra_env),
+                cwd=cwd, stdout=devnull, stderr=subprocess.STDOUT, close_fds=True)
+        else:
+            return self.run_process(
+                infer_args + [gradle] + args,
+                append_env=extra_env,
+                pass_thru=True,  # Allow user to run gradle interactively.
+                ensure_exit_code=False,  # Don't throw on non-zero exit code.
+                cwd=cwd)
+
     @StaticAnalysisSubCommand('static-analysis', 'autotest',
                               'Run the auto-test suite in order to determine that'
                               ' the analysis did not regress.')
     @CommandArgument('--dump-results', '-d', default=False, action='store_true',
                      help='Generate the baseline for the regression test. Based on'
                      ' this baseline we will test future results.')
     @CommandArgument('--intree-tool', '-i', default=False, action='store_true',
                      help='Use a pre-aquired in-tree clang-tidy package.')
@@ -1930,32 +1962,30 @@ class StaticAnalysis(MachCommandBase):
                      help='Checkers that are going to be auto-tested.')
     def autotest(self, verbose=False, dump_results=False, intree_tool=False, checker_names=[]):
         # If 'dump_results' is True than we just want to generate the issues files for each
         # checker in particulat and thus 'force_download' becomes 'False' since we want to
         # do this on a local trusted clang-tidy package.
         self._set_log_level(verbose)
         self._dump_results = dump_results
 
-        force_download = True
-
-        if self._dump_results:
-            force_download = False
+        force_download = not self._dump_results
 
         # Function return codes
         self.TOOLS_SUCCESS = 0
         self.TOOLS_FAILED_DOWNLOAD = 1
         self.TOOLS_UNSUPORTED_PLATFORM = 2
         self.TOOLS_CHECKER_NO_TEST_FILE = 3
         self.TOOLS_CHECKER_RETURNED_NO_ISSUES = 4
         self.TOOLS_CHECKER_RESULT_FILE_NOT_FOUND = 5
         self.TOOLS_CHECKER_DIFF_FAILED = 6
         self.TOOLS_CHECKER_NOT_FOUND = 7
         self.TOOLS_CHECKER_FAILED_FILE = 8
         self.TOOLS_CHECKER_LIST_EMPTY = 9
+        self.TOOLS_GRADLE_FAILED = 10
 
         # Configure the tree or download clang-tidy package, depending on the option that we choose
         if intree_tool:
             _, config, _ = self._get_config_environment()
             clang_tools_path = self.topsrcdir
             self._clang_tidy_path = mozpath.join(
                 clang_tools_path, "clang-tidy", "bin",
                 "clang-tidy" + config.substs.get('BIN_SUFFIX', ''))
@@ -2053,17 +2083,17 @@ class StaticAnalysis(MachCommandBase):
                 ret_val = self._run_analysis_batch(checkers_test_batch)
                 if ret_val != self.TOOLS_SUCCESS:
                     shutil.rmtree(self._compilation_commands_path)
                     return ret_val
 
         self.log(logging.INFO, 'static-analysis', {}, "SUCCESS: clang-tidy all tests passed.")
         # Also delete the tmp folder
         shutil.rmtree(self._compilation_commands_path)
-        return self.TOOLS_SUCCESS
+        return self._autotest_infer(intree_tool, force_download, verbose)
 
     def _run_analysis(self, checks, header_filter, sources, jobs=1, fix=False, print_out=False):
         cmd = self._get_clang_tidy_command(
             checks=checks, header_filter=header_filter,
             sources=sources,
             jobs=jobs, fix=fix)
 
         try:
@@ -2106,25 +2136,148 @@ class StaticAnalysis(MachCommandBase):
             compile_commands = []
             director = mozpath.join(self.topsrcdir, 'tools', 'clang-tidy', 'test')
             for item in config['clang_checkers']:
                 if item['name'] in ['-*', 'mozilla-*']:
                     continue
                 file = item['name'] + '.cpp'
                 element = {}
                 element["directory"] = director
-                element["command"] = 'cpp '+ file
+                element["command"] = 'cpp ' + file
                 element["file"] = mozpath.join(director, file)
                 compile_commands.append(element)
 
             json.dump(compile_commands, file_handler)
             file_handler.flush()
 
             return directory
 
+    def _autotest_infer(self, intree_tool, force_download, verbose):
+        # infer is not available on other platforms, but autotest should work even without
+        # it being installed
+        if self.platform[0] == 'linux64':
+            rc = self._check_for_java()
+            if rc != 0:
+                return 1
+            rc = self._get_infer(force=force_download, verbose=verbose, intree_tool=intree_tool)
+            if rc != 0:
+                self.log(logging.ERROR, 'ERROR: static-analysis', {},
+                         'infer unable to locate package.')
+                return self.TOOLS_FAILED_DOWNLOAD
+            self.__infer_tool = mozpath.join(self.topsrcdir, 'tools', 'infer')
+            self.__infer_test_folder = mozpath.join(self.__infer_tool, 'test')
+
+            import concurrent.futures
+            import multiprocessing
+            max_workers = multiprocessing.cpu_count()
+            self.log(logging.INFO, 'static-analysis', {},
+                     "RUNNING: infer autotest for platform {0} with {1} workers.".format(
+                         self.platform[0], max_workers))
+            # clean previous autotest if it exists
+            rc = self._gradle(['autotest:clean'], autotest=True)
+            if rc != 0:
+                return rc
+            import yaml
+            with open(mozpath.join(self.__infer_tool, 'config.yaml')) as f:
+                config = yaml.safe_load(f)
+            with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
+                futures = []
+                for item in config['infer_checkers']:
+                    if item['publish']:
+                        futures.append(executor.submit(self._verify_infer_checker, item))
+                # this is always included in check-java, but not in config.yaml
+                futures.append(executor.submit(self._verify_infer_checker,
+                                               {'name': 'checkers'}))
+                for future in concurrent.futures.as_completed(futures):
+                    ret_val = future.result()
+                    if ret_val != self.TOOLS_SUCCESS:
+                        return ret_val
+            self.log(logging.INFO, 'static-analysis', {}, "SUCCESS: infer all tests passed.")
+        else:
+            self.log(logging.WARNING, 'static-analysis', {},
+                     "Skipping infer autotest, because it is only available on linux64!")
+        return self.TOOLS_SUCCESS
+
+    def _verify_infer_checker(self, item):
+        '''Given a checker, this method verifies the following:
+          1. if there is a `checker`.json and `checker`.java file in
+             `tools/infer/test/autotest/src`
+          2. if running infer on `checker`.java yields the same result as `checker`.json
+        An `item` is simply a dictionary, which needs to have a `name` field set, which is the
+        name of the checker.
+        '''
+        def to_camelcase(str):
+            return ''.join([s.capitalize() for s in str.split('-')])
+        check = item['name']
+        test_file_path = mozpath.join(self.__infer_tool, 'test', 'autotest', 'src',
+                                      'main', 'java', to_camelcase(check))
+        test_file_path_java = test_file_path + '.java'
+        test_file_path_json = test_file_path + '.json'
+        self.log(logging.INFO, 'static-analysis', {}, "RUNNING: infer check {}.".format(check))
+        # Verify if the test file exists for this checker
+        if not os.path.exists(test_file_path_java):
+            self.log(logging.ERROR, 'static-analysis', {},
+                     "ERROR: infer check {} doesn't have a test file.".format(check))
+            return self.TOOLS_CHECKER_NO_TEST_FILE
+        # run infer on a particular test file
+        out_folder = mozpath.join(self.__infer_test_folder, 'test-infer-{}'.format(check))
+        if check == 'checkers':
+            check_arg = ['-a', 'checkers']
+        else:
+            check_arg = ['--{}-only'.format(check)]
+        infer_args = [self._infer_path, 'run'] + check_arg + ['-o', out_folder, '--']
+        gradle_args = ['autotest:compileInferTest{}'.format(to_camelcase(check))]
+        rc = self._gradle(gradle_args, infer_args=infer_args, autotest=True)
+        if rc != 0:
+            self.log(logging.ERROR, 'static-analysis', {},
+                     "ERROR: infer failed to execute gradle {}.".format(gradle_args))
+            return self.TOOLS_GRADLE_FAILED
+        issues = json.load(open(mozpath.join(out_folder, 'report.json')))
+        # remove folder that infer creates because the issues are loaded into memory
+        import shutil
+        shutil.rmtree(out_folder)
+        # Verify to see if we got any issues, if not raise exception
+        if not issues:
+            self.log(
+                logging.ERROR, 'static-analysis', {},
+                "ERROR: infer check {0} did not find any issues in its associated test suite."
+                .format(check)
+            )
+            return self.TOOLS_CHECKER_RETURNED_NO_ISSUES
+        if self._dump_results:
+            self._build_autotest_result(test_file_path_json, issues)
+        else:
+            if not os.path.exists(test_file_path_json):
+                # Result file for test not found maybe regenerate it?
+                self.log(
+                    logging.ERROR, 'static-analysis', {},
+                    "ERROR: infer result file not found for check {0}".format(check)
+                )
+                return self.TOOLS_CHECKER_RESULT_FILE_NOT_FOUND
+            # Read the pre-determined issues
+            baseline_issues = self._get_autotest_stored_issues(test_file_path_json)
+
+            def ordered(obj):
+                if isinstance(obj, dict):
+                    return sorted((k, ordered(v)) for k, v in obj.items())
+                if isinstance(obj, list):
+                    return sorted(ordered(x) for x in obj)
+                return obj
+            # Compare the two lists
+            if ordered(issues) != ordered(baseline_issues):
+                error_str = "ERROR: in check {} Expected: ".format(check)
+                error_str += '\n' + json.dumps(baseline_issues, indent=2)
+                error_str += '\n Got:\n' + json.dumps(issues, indent=2)
+                self.log(logging.ERROR, 'static-analysis', {},
+                         'ERROR: infer autotest for check {} failed, check stdout for more details'
+                         .format(check))
+                print(error_str)
+                return self.TOOLS_CHECKER_DIFF_FAILED
+        return self.TOOLS_SUCCESS
+
     @StaticAnalysisSubCommand('static-analysis', 'install',
                               'Install the static analysis helper tool')
     @CommandArgument('source', nargs='?', type=str,
                      help='Where to fetch a local archive containing the static-analysis and '
                      'format helper tool.'
                           'It will be installed in ~/.mozbuild/clang-tools and ~/.mozbuild/infer.'
                           'Can be omitted, in which case the latest clang-tools and infer '
                           'helper for the platform would be automatically detected and installed.')
@@ -2408,17 +2561,16 @@ class StaticAnalysis(MachCommandBase):
             "clang-format" + config.substs.get('BIN_SUFFIX', ''))
         self._clang_apply_replacements = mozpath.join(
             clang_tools_path, "clang-tidy", "bin",
             "clang-apply-replacements" + config.substs.get('BIN_SUFFIX', ''))
         self._run_clang_tidy_path = mozpath.join(clang_tools_path, "clang-tidy", "share", "clang",
                                                  "run-clang-tidy.py")
         self._clang_format_diff = mozpath.join(clang_tools_path, "clang-tidy", "share", "clang",
                                                "clang-format-diff.py")
-
         if os.path.exists(self._clang_tidy_path) and \
            os.path.exists(self._clang_format_path) and \
            os.path.exists(self._clang_apply_replacements) and \
            os.path.exists(self._run_clang_tidy_path) and \
            not force:
             return 0
         else:
             if os.path.isdir(clang_tools_path) and download_if_needed:
@@ -2509,25 +2661,27 @@ class StaticAnalysis(MachCommandBase):
                         continue  # empty or comment
                     magics = ['exclude']
                     if pattern.startswith('^'):
                         magics += ['top']
                         pattern = pattern[1:]
                     args += [':({0}){1}'.format(','.join(magics), pattern)]
         return args
 
-    def _get_infer(self, force=False, skip_cache=False,
-                   download_if_needed=True, verbose=False):
+    def _get_infer(self, force=False, skip_cache=False, download_if_needed=True,
+                   verbose=False, intree_tool=False):
         rc, config, _ = self._get_config_environment()
         if rc != 0:
             return rc
-        infer_path = mozpath.join(self._mach_context.state_dir, 'infer')
-        self._infer_path = mozpath.join(infer_path, 'infer', 'bin',
-                                        'infer' +
+        infer_path = self.topsrcdir if intree_tool else \
+            mozpath.join(self._mach_context.state_dir, 'infer')
+        self._infer_path = mozpath.join(infer_path, 'infer', 'bin', 'infer' +
                                         config.substs.get('BIN_SUFFIX', ''))
+        if intree_tool:
+            return not os.path.exists(self._infer_path)
         if os.path.exists(self._infer_path) and not force:
             return 0
         else:
             if os.path.isdir(infer_path) and download_if_needed:
                 # The directory exists, perhaps it's corrupted?  Delete it
                 # and start from scratch.
                 import shutil
                 shutil.rmtree(infer_path)
--- a/taskcluster/ci/docker-image/kind.yml
+++ b/taskcluster/ci/docker-image/kind.yml
@@ -81,19 +81,19 @@ jobs:
       - deb9-mercurial
       - deb9-python-zstandard
   android-build:
     symbol: I(agb)
     parent: debian9-base
   fetch:
     symbol: I(fetch)
     parent: debian9-base
-  infer-build:
-    symbol: I(infer)
-    parent: debian9-base
+  static-analysis-build:
+    symbol: I(static-analysis-build)
+    parent: android-build
   mingw32-build:
     symbol: I(mingw)
     parent: debian9-base
   index-task:
     symbol: I(idx)
   funsize-update-generator:
     symbol: I(pg)
   google-play-strings:
--- a/taskcluster/ci/static-analysis-autotest/kind.yml
+++ b/taskcluster/ci/static-analysis-autotest/kind.yml
@@ -35,20 +35,22 @@ jobs:
     linux64-st-autotest/debug:
         description: "Linux64 Debug Static Analysis Autotest"
         index:
             job-name: linux64-st-autotest-debug
         treeherder:
             platform: linux64/debug
         worker-type: aws-provisioner-v1/gecko-t-linux-large
         worker:
+            docker-image: {in-tree: static-analysis-build}
             env:
                 # clang-tidy needs a recent libstdc++, which can be found in the clang
                 # toolchain.
                 LD_LIBRARY_PATH: /builds/worker/workspace/build/src/clang/lib
+                PERFHERDER_EXTRA_OPTIONS: static-analysis-autotest
         run:
             config:
                 - builds/releng_base_firefox.py
                 - builds/releng_sub_linux_configs/64_stat_and_debug.py
             tooltool-downloads: public
             keep-artifacts: false
         toolchains:
             - linux64-clang
--- a/taskcluster/ci/toolchain/linux.yml
+++ b/taskcluster/ci/toolchain/linux.yml
@@ -180,17 +180,17 @@ linux64-infer:
         job-name: linux64-infer
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(infer)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
-        docker-image: {in-tree: infer-build}
+        docker-image: {in-tree: static-analysis-build}
         max-run-time: 3600
     run:
         using: toolchain-script
         script: build-infer-linux.sh
         resources:
             - 'build/build-infer/build-infer.py'
             - 'build/build-infer/infer-linux64.json'
         toolchain-artifact: public/build/infer.tar.xz
new file mode 100644
--- /dev/null
+++ b/taskcluster/docker/static-analysis-build/Dockerfile
@@ -0,0 +1,58 @@
+# %ARG DOCKER_IMAGE_PARENT
+FROM $DOCKER_IMAGE_PARENT
+MAINTAINER Robert Bartlensky <rbartlensky@mozilla.com>
+
+VOLUME /builds/worker/checkouts
+VOLUME /builds/worker/workspace
+VOLUME /builds/worker/tooltool-cache
+
+ENV XZ_OPT=-T0
+
+RUN apt-get update && \
+    apt-get install \
+      autoconf2.13 \
+      automake \
+      bison \
+      bzip2 \
+      cmake \
+      flex \
+      curl \
+      opam \
+      libsqlite3-dev \
+      file \
+      gawk \
+      gcc-multilib \
+      gnupg \
+      libc6-dev \
+      openjdk-8-jdk-headless \
+      pkg-config \
+      patch \
+      p7zip-full \
+      procps \
+      python-pip \
+      python-setuptools \
+      python-virtualenv \
+      rsync \
+      screen \
+      tar \
+      unzip \
+      uuid \
+      valgrind \
+      wget \
+      yasm \
+      zip \
+      zlib1g-dev \
+      x11-utils \
+      xvfb \
+      linux-libc-dev \
+      libdbus-glib-1-dev \
+      libfontconfig1-dev \
+      libfreetype6-dev \
+      libgconf2-dev \
+      libgtk-3-dev \
+      libgtk2.0-dev \
+      libpango1.0-dev \
+      libpulse-dev \
+      libx11-xcb-dev \
+      libxt-dev \
+      lib32z1
--- a/testing/mozharness/mozharness/mozilla/building/buildbase.py
+++ b/testing/mozharness/mozharness/mozilla/building/buildbase.py
@@ -1092,48 +1092,60 @@ or run without that action (ie: --no-{ac
         self._run_mach_command_in_build_env(['build', '-v'])
 
         self.generate_build_props(console_output=True, halt_on_failure=True)
         self._generate_build_stats()
 
     def static_analysis_autotest(self):
         """Run mach static-analysis autotest, in order to make sure we dont regress"""
         self.preflight_build()
-        self._run_mach_command_in_build_env(['static-analysis', 'autotest', '--intree-tool'])
+        self._run_mach_command_in_build_env(['configure'])
+        self._run_mach_command_in_build_env(['static-analysis', 'autotest',
+                                             '--intree-tool'],
+                                            use_subprocess=True)
 
     def _query_mach(self):
         dirs = self.query_abs_dirs()
 
         if 'MOZILLABUILD' in os.environ:
             # We found many issues with intermittent build failures when not
             # invoking mach via bash.
             # See bug 1364651 before considering changing.
             mach = [
                 os.path.join(os.environ['MOZILLABUILD'], 'msys', 'bin', 'bash.exe'),
                 os.path.join(dirs['abs_src_dir'], 'mach')
             ]
         else:
             mach = [sys.executable, 'mach']
         return mach
 
-    def _run_mach_command_in_build_env(self, args):
+    def _run_mach_command_in_build_env(self, args, use_subprocess=False):
         """Run a mach command in a build context."""
         env = self.query_build_env()
         env.update(self.query_mach_build_env())
 
         dirs = self.query_abs_dirs()
 
         mach = self._query_mach()
 
-        return_code = self.run_command(
-            command=mach + ['--log-no-times'] + args,
-            cwd=dirs['abs_src_dir'],
-            env=env,
-            output_timeout=self.config.get('max_build_output_timeout', 60 * 40)
-        )
+        # XXX See bug 1483883
+        # Work around an interaction between Gradle and mozharness
+        # Not using `subprocess` causes gradle to hang
+        if use_subprocess:
+            import subprocess
+            return_code = subprocess.call(mach + ['--log-no-times'] + args,
+                                          env=env, cwd=dirs['abs_src_dir'])
+        else:
+            return_code = self.run_command(
+                command=mach + ['--log-no-times'] + args,
+                cwd=dirs['abs_src_dir'],
+                env=env,
+                output_timeout=self.config.get('max_build_output_timeout',
+                                               60 * 40)
+            )
 
         if return_code:
             self.return_code = self.worst_level(
                 EXIT_STATUS_DICT[TBPL_FAILURE], self.return_code,
                 AUTOMATION_EXIT_CODES[::-1]
             )
             self.fatal("'mach %s' did not run successfully. Please check "
                        "log for errors." % ' '.join(args))
--- a/tools/infer/config.yaml
+++ b/tools/infer/config.yaml
@@ -1,23 +1,31 @@
 ---
 target: obj-x86_64-pc-linux-gnu
 # It is used by 'mach static-analysis' and 'mozreview static-analysis bot'
 # in order to have consistency across the used checkers.
 platforms:
   - linux64
 infer_checkers:
+  # no issues were ever trigger by this
   - name: check-nullable
+    publish: !!bool no
+  - name: biabduction
     publish: !!bool yes
+  # very very noisy
+  # it could be useful, but it won't be part of the default enabled checkers
   - name: eradicate
     publish: !!bool no
+  # hard to use, not useful
   - name: quandary
-    publish: !!bool yes
+    publish: !!bool no
   - name: starvation
     publish: !!bool yes
+  # experimental
   - name: litho
-    publish: !!bool yes
+    publish: !!bool no
   - name: racerd
     publish: !!bool yes
+  # I think this is only for c++, can't trigger these errors in Java
   - name: liveness
-    publish: !!bool yes
+    publish: !!bool no
 # Third party files from mozilla-central
 third_party: tools/rewriting/ThirdPartyPaths.txt
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/build.gradle
@@ -0,0 +1,25 @@
+buildDir "${topobjdir}/gradle/build/tools/infer/test/autotest"
+
+apply plugin: 'java'
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+    compile "com.google.code.findbugs:jsr305:3.0.2"
+}
+
+def createSingleTask = { name ->
+    task("compileInferTest${name}", type: JavaCompile) {
+        source = fileTree(dir: '.', include: "src/main/java/${name}.java")
+        classpath = project.configurations.compileClasspath
+        destinationDir = file("${topobjdir}/gradle/build/tools/infer/test/autotest")
+    }
+}
+
+createSingleTask('Biabduction')
+createSingleTask('Checkers')
+createSingleTask('Eradicate')
+createSingleTask('Racerd')
+createSingleTask('Starvation')
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Biabduction.java
@@ -0,0 +1,22 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import javax.annotation.Nullable;
+import java.util.List;
+
+public class Biabduction {
+    private String get() { return null; }
+
+    public void f1() {
+        get().length(); // error
+    }
+
+    public void f2() {
+        try {
+            get().length(); // error
+        } catch (NullPointerException e) {
+
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Biabduction.json
@@ -0,0 +1,114 @@
+[
+    {
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "start of procedure f1()",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 0,
+                "line_number": 11
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 0,
+                "line_number": 12
+            },
+            {
+                "column_number": -1,
+                "description": "start of procedure get()",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 1,
+                "line_number": 9
+            },
+            {
+                "column_number": -1,
+                "description": "return from a call to String Biabduction.get()",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 1,
+                "line_number": 9
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 0,
+                "line_number": 12
+            }
+        ],
+        "bug_type": "NULL_DEREFERENCE",
+        "bug_type_hum": "Null Dereference",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Biabduction.java",
+        "hash": "918d7eaedf45f651f04c55554c72478c",
+        "key": "Biabduction.java|f1|NULL_DEREFERENCE",
+        "kind": "ERROR",
+        "line": 12,
+        "node_key": "9afcdcc9d4253c36267a0d34b98c337d",
+        "procedure": "void Biabduction.f1()",
+        "procedure_id": "Biabduction.f1():void.4b49520e7621606a0d5661886ff0b098",
+        "procedure_start_line": 11,
+        "qualifier": "object returned by `get(this)` could be null and is dereferenced at line 12.",
+        "severity": "HIGH",
+        "visibility": "user"
+    },
+    {
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "start of procedure f2()",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 0,
+                "line_number": 15
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 0,
+                "line_number": 17
+            },
+            {
+                "column_number": -1,
+                "description": "start of procedure get()",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 1,
+                "line_number": 9
+            },
+            {
+                "column_number": -1,
+                "description": "return from a call to String Biabduction.get()",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 1,
+                "line_number": 9
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Biabduction.java",
+                "level": 0,
+                "line_number": 17
+            }
+        ],
+        "bug_type": "NULL_DEREFERENCE",
+        "bug_type_hum": "Null Dereference",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Biabduction.java",
+        "hash": "bc952ce8bad58dac5cb6672dc3150524",
+        "key": "Biabduction.java|f2|NULL_DEREFERENCE",
+        "kind": "ERROR",
+        "line": 17,
+        "node_key": "9afcdcc9d4253c36267a0d34b98c337d",
+        "procedure": "void Biabduction.f2()",
+        "procedure_id": "Biabduction.f2():void.41c05a632eb912a458482c1e2e4dcbb4",
+        "procedure_start_line": 15,
+        "qualifier": "object returned by `get(this)` could be null and is dereferenced at line 17.",
+        "severity": "HIGH",
+        "visibility": "user"
+    }
+]
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Checkers.java
@@ -0,0 +1,34 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+
+public class Checkers {
+    public static void leak() {
+        try {
+            BufferedReader br = new BufferedReader(
+                new FileReader(new File("some.txt"))
+            );
+        } catch (Exception e) {
+
+        }
+    }
+
+    public static void error1() {
+        String str = null;
+        try {
+            int x = str.length(); // Error: even if exception is caught
+        } catch (NullPointerException e) {
+
+        }
+    }
+
+    public static void error2() {
+        String str = null;
+        int x = str.length(); // Error: not checking for null
+    }
+
+}
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Checkers.json
@@ -0,0 +1,121 @@
+[
+    {
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "start of procedure leak()",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 10
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 12
+            }
+        ],
+        "bug_type": "RESOURCE_LEAK",
+        "bug_type_hum": "Resource Leak",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Checkers.java",
+        "hash": "56806153823413731f2e2166ed8d30a0",
+        "key": "Checkers.java|leak|RESOURCE_LEAK",
+        "kind": "ERROR",
+        "line": 12,
+        "node_key": "3a2af627d5d1f10e1994f6259cf18e4c",
+        "procedure": "void Checkers.leak()",
+        "procedure_id": "Checkers.leak():void.e21648e10d3037f4559cdb7c08642c84",
+        "procedure_start_line": 10,
+        "qualifier": "resource of type `java.io.FileReader` acquired by call to `new()` at line 12 is not released after line 12.",
+        "severity": "HIGH",
+        "visibility": "user"
+    },
+    {
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "start of procedure error1()",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 20
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 21
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 23
+            }
+        ],
+        "bug_type": "NULL_DEREFERENCE",
+        "bug_type_hum": "Null Dereference",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Checkers.java",
+        "hash": "6de26e7c66c71b1114ad233679d55640",
+        "key": "Checkers.java|error1|NULL_DEREFERENCE",
+        "kind": "ERROR",
+        "line": 23,
+        "node_key": "c281f77c6dae544ee5fb7d5e2bb35118",
+        "procedure": "void Checkers.error1()",
+        "procedure_id": "Checkers.error1():void.59417424d80960700a32012973e98db5",
+        "procedure_start_line": 20,
+        "qualifier": "object `str` last assigned on line 21 could be null and is dereferenced at line 23.",
+        "severity": "HIGH",
+        "visibility": "user"
+    },
+    {
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "start of procedure error2()",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 29
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 30
+            },
+            {
+                "column_number": -1,
+                "description": "",
+                "filename": "autotest/src/main/java/Checkers.java",
+                "level": 0,
+                "line_number": 31
+            }
+        ],
+        "bug_type": "NULL_DEREFERENCE",
+        "bug_type_hum": "Null Dereference",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Checkers.java",
+        "hash": "39e021b634ab428af7be2034688491a7",
+        "key": "Checkers.java|error2|NULL_DEREFERENCE",
+        "kind": "ERROR",
+        "line": 31,
+        "node_key": "c281f77c6dae544ee5fb7d5e2bb35118",
+        "procedure": "void Checkers.error2()",
+        "procedure_id": "Checkers.error2():void.e9146d80ba20c908c11d08947cd89d06",
+        "procedure_start_line": 29,
+        "qualifier": "object `str` last assigned on line 30 could be null and is dereferenced at line 31.",
+        "severity": "HIGH",
+        "visibility": "user"
+    }
+]
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Eradicate.java
@@ -0,0 +1,57 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import javax.annotation.Nullable;
+
+// Examples taken from the infer website.
+public class Eradicate {
+
+    public String f; // Because it is not annoted with nullable -> can never be null!
+
+    public void field(@Nullable Eradicate x) {
+        x.f = "3"; // Error: Eradicate null field access
+    }
+
+    public void method(@Nullable Object x) {
+        String s = x.toString(); // Error: Eradicate null method call
+    }
+
+    public void filedNotNull(@Nullable String s) {
+        f = s; // Error: Eradicate field not nullable
+    }
+
+    public Eradicate() {} // Error: Eradicate field not initialized
+
+    public void str(Eradicate x) {
+        String s = x.toString();
+    }
+
+    public void callStr(@Nullable Eradicate x) {
+        str(x); // Error:  Eradicate parameter not nullable
+    }
+
+    public String shouldNotReturnNullBecauseNotAnnotated() {
+        return null; // Error: Eradicate return not nullable
+    }
+
+    public void redundant() {
+        String s = new String("abc");
+        if (s != null) { // Error: Eradicate condition redundant
+            int n = s.length();
+        }
+    }
+
+    @Nullable
+    public static String someMethod() {
+        return ""; // Error: Eradicate return overannotated
+    }
+}
+
+class B extends Eradicate {
+    @Nullable public String shouldNotReturnNullBecauseNotAnnotated() {
+        return null; // Error: Eradicate inconsistent subclass return annotation
+    }
+
+    public void field(Eradicate x) {} // Error: Inconsistent subclass parameter annotation
+}
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Racerd.java
@@ -0,0 +1,40 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import javax.annotation.concurrent.ThreadSafe;
+
+// Examples taken from the infer website.
+@ThreadSafe
+public class Racerd {
+    private int mTemperature;
+
+    public void makeDinner() {
+        boilWater();
+    }
+
+    private void boilWater() {
+        mTemperature = 100; //Error: unprotected write.
+    }
+}
+
+@ThreadSafe
+class Account {
+
+    int mBalance = 0;
+
+    public void deposit(int amount) {
+        if (amount > 0) {
+            mBalance += amount; // Error: unsynchronized write
+        }
+    }
+
+    public int withdraw(int amount){
+        if (amount >= 0 && mBalance - amount >= 0) {
+            mBalance -= amount; // Error: unsynchronized write
+            return mBalance; // Error: unsynchronized read
+        } else {
+            return 0;
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Racerd.json
@@ -0,0 +1,146 @@
+[
+    {
+        "access": "hJWmvgAAAJMAAAApAAAAfgAAAHSwkNAnZGVwb3NpdKCgQCNpbnRAk6AnQWNjb3VudECQoEAkdm9pZECgoJKgIECwXAD/kgkiYXV0b3Rlc3Qvc3JjL21haW4vamF2YS9SYWNlcmQuamF2YZGgoJGwAjafTBegJHRoaXNAkAQcoKOglJOgBBpAsEBAQEAEAaCRkTBBY2NvdW50Lm1CYWxhbmNlQKAEF0A=",
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "access to `this.Account.mBalance`",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 28
+            }
+        ],
+        "bug_type": "THREAD_SAFETY_VIOLATION",
+        "bug_type_hum": "Thread Safety Violation",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Racerd.java",
+        "hash": "6b62cb17008a3135d218108fa3123402",
+        "key": "Racerd.java|deposit|THREAD_SAFETY_VIOLATION",
+        "kind": "ERROR",
+        "line": 28,
+        "node_key": "9c5d6d9028928346cc4fb44cced5dea1",
+        "procedure": "void Account.deposit(int)",
+        "procedure_id": "Account.deposit(int):void.a9cc1805c1e3652887a5ee12b55803af",
+        "procedure_start_line": 0,
+        "qualifier": "Unprotected write. Non-private method `void Account.deposit(int)` writes to field `this.Account.mBalance` outside of synchronization.\n Reporting because the current class is annotated `@ThreadSafe`, so we assume that this method can run in parallel with other non-private methods in the class (including itself).",
+        "severity": "HIGH",
+        "visibility": "user"
+    },
+    {
+        "access": "hJWmvgAAAKYAAAApAAAAhQAAAHqwkNAqbWFrZURpbm5lckCToCZSYWNlcmRAkKBAJHZvaWRAoKCQ0Clib2lsV2F0ZXJAk6AEC0AECkCwTQD/kgkiYXV0b3Rlc3Qvc3JjL21haW4vamF2YS9SYWNlcmQuamF2YZGgoJGwAjafTBegJHRoaXNAkAQboKOglJOgBBxAsEBAQEAEAaCRkTNSYWNlcmQubVRlbXBlcmF0dXJlQKCwUQD/BBdA",
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "call to void Racerd.boilWater()",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 13
+            },
+            {
+                "column_number": -1,
+                "description": "access to `this.Racerd.mTemperature`",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 1,
+                "line_number": 17
+            }
+        ],
+        "bug_type": "THREAD_SAFETY_VIOLATION",
+        "bug_type_hum": "Thread Safety Violation",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Racerd.java",
+        "hash": "2882383086ab102a88144ae3c2cc4701",
+        "key": "Racerd.java|makeDinner|THREAD_SAFETY_VIOLATION",
+        "kind": "ERROR",
+        "line": 13,
+        "node_key": "9c5d6d9028928346cc4fb44cced5dea1",
+        "procedure": "void Racerd.makeDinner()",
+        "procedure_id": "Racerd.makeDinner():void.2796f75396b30d2d49b24ddfab722306",
+        "procedure_start_line": 0,
+        "qualifier": "Unprotected write. Non-private method `void Racerd.makeDinner()` indirectly writes to field `this.Racerd.mTemperature` outside of synchronization.\n Reporting because the current class is annotated `@ThreadSafe`, so we assume that this method can run in parallel with other non-private methods in the class (including itself).",
+        "severity": "HIGH",
+        "visibility": "user"
+    },
+    {
+        "access": "hJWmvgAAAJgAAAAqAAAAgwAAAHqwkNAod2l0aGRyYXegoEAjaW50QJOgJ0FjY291bnRAkKBABAZAoKCSoCBAsGMA/5IJImF1dG90ZXN0L3NyYy9tYWluL2phdmEvUmFjZXJkLmphdmGQoKCRsAI2n0wXoCR0aGlzQJAEG6CjoJSToAQZQLBAQEBABAGgkZEwQWNjb3VudC5tQmFsYW5jZUCgBBegsGIA/wQYQA==",
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "<Read trace>",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 35
+            },
+            {
+                "column_number": -1,
+                "description": "access to `this.Account.mBalance`",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 35
+            },
+            {
+                "column_number": -1,
+                "description": "<Write trace>",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 34
+            },
+            {
+                "column_number": -1,
+                "description": "access to `this.Account.mBalance`",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 34
+            }
+        ],
+        "bug_type": "THREAD_SAFETY_VIOLATION",
+        "bug_type_hum": "Thread Safety Violation",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Racerd.java",
+        "hash": "5665f12d2392f93f11f556cd1b1e238a",
+        "key": "Racerd.java|withdraw|THREAD_SAFETY_VIOLATION",
+        "kind": "ERROR",
+        "line": 35,
+        "node_key": "9c5d6d9028928346cc4fb44cced5dea1",
+        "procedure": "int Account.withdraw(int)",
+        "procedure_id": "Account.withdraw(int):int.038de5054c5c25e60d169e42e0177a16",
+        "procedure_start_line": 0,
+        "qualifier": "Read/Write race. Non-private method `int Account.withdraw(int)` reads without synchronization from `this.Account.mBalance`. Potentially races with write in method `Account.withdraw(...)`.\n Reporting because the current class is annotated `@ThreadSafe`, so we assume that this method can run in parallel with other non-private methods in the class (including itself).",
+        "severity": "HIGH",
+        "visibility": "user"
+    },
+    {
+        "access": "hJWmvgAAAJEAAAAoAAAAfAAAAHOwkNAod2l0aGRyYXegoEAjaW50QJOgJ0FjY291bnRAkKBABAZAoKCSoCBAsGIA/5IJImF1dG90ZXN0L3NyYy9tYWluL2phdmEvUmFjZXJkLmphdmGRoKCRsAI2n0wXoCR0aGlzQJAEG6CjoJSToAQZQLBAQEBABAGgkZEwQWNjb3VudC5tQmFsYW5jZUCgBBdA",
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "access to `this.Account.mBalance`",
+                "filename": "autotest/src/main/java/Racerd.java",
+                "level": 0,
+                "line_number": 34
+            }
+        ],
+        "bug_type": "THREAD_SAFETY_VIOLATION",
+        "bug_type_hum": "Thread Safety Violation",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Racerd.java",
+        "hash": "a7c30fd1b251d9e16750fc7e5913b885",
+        "key": "Racerd.java|withdraw|THREAD_SAFETY_VIOLATION",
+        "kind": "ERROR",
+        "line": 34,
+        "node_key": "9c5d6d9028928346cc4fb44cced5dea1",
+        "procedure": "int Account.withdraw(int)",
+        "procedure_id": "Account.withdraw(int):int.038de5054c5c25e60d169e42e0177a16",
+        "procedure_start_line": 0,
+        "qualifier": "Unprotected write. Non-private method `int Account.withdraw(int)` writes to field `this.Account.mBalance` outside of synchronization.\n Reporting because the current class is annotated `@ThreadSafe`, so we assume that this method can run in parallel with other non-private methods in the class (including itself).",
+        "severity": "HIGH",
+        "visibility": "user"
+    }
+]
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Starvation.java
@@ -0,0 +1,25 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Examples taken from the infer website.
+public class Starvation {
+
+    String lockA, lockB;
+
+    public void lockAThenB() {
+        synchronized(lockA) {
+            synchronized(lockB) {
+                // do something with both resources
+            }
+        }
+    }
+
+    public void lockBThenA() {
+        synchronized(lockB) {
+            synchronized(lockA) {
+                // do something with both resources
+            }
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/autotest/src/main/java/Starvation.json
@@ -0,0 +1,65 @@
+[
+    {
+        "bug_class": "PROVER",
+        "bug_trace": [
+            {
+                "column_number": -1,
+                "description": "[Trace 1] `void Starvation.lockAThenB()`",
+                "filename": "autotest/src/main/java/Starvation.java",
+                "level": 0,
+                "line_number": 11
+            },
+            {
+                "column_number": -1,
+                "description": "locks `this.Starvation.lockA` in class `Starvation*`",
+                "filename": "autotest/src/main/java/Starvation.java",
+                "level": 0,
+                "line_number": 11
+            },
+            {
+                "column_number": -1,
+                "description": "locks `this.Starvation.lockB` in class `Starvation*`",
+                "filename": "autotest/src/main/java/Starvation.java",
+                "level": 1,
+                "line_number": 12
+            },
+            {
+                "column_number": -1,
+                "description": "[Trace 2] `void Starvation.lockBThenA()`",
+                "filename": "autotest/src/main/java/Starvation.java",
+                "level": 0,
+                "line_number": 19
+            },
+            {
+                "column_number": -1,
+                "description": "locks `this.Starvation.lockB` in class `Starvation*`",
+                "filename": "autotest/src/main/java/Starvation.java",
+                "level": 0,
+                "line_number": 19
+            },
+            {
+                "column_number": -1,
+                "description": "locks `this.Starvation.lockA` in class `Starvation*`",
+                "filename": "autotest/src/main/java/Starvation.java",
+                "level": 1,
+                "line_number": 20
+            }
+        ],
+        "bug_type": "DEADLOCK",
+        "bug_type_hum": "Deadlock",
+        "censored_reason": "",
+        "column": -1,
+        "file": "autotest/src/main/java/Starvation.java",
+        "hash": "043d28a94431b4c573b949b8570fb318",
+        "key": "Starvation.java|lockAThenB|DEADLOCK",
+        "kind": "ERROR",
+        "line": 11,
+        "node_key": "9c5d6d9028928346cc4fb44cced5dea1",
+        "procedure": "void Starvation.lockAThenB()",
+        "procedure_id": "Starvation.lockAThenB():void.b7eb3955306c498af42d6336f52a796f",
+        "procedure_start_line": 0,
+        "qualifier": "Potential deadlock.\nTrace 1 (starts at `void Starvation.lockAThenB()`) first locks `this.Starvation.lockA` in class `Starvation*` (line 11 in `void Starvation.lockAThenB()`) and then locks `this.Starvation.lockB` in class `Starvation*` (line 12 in `void Starvation.lockAThenB()`).\nTrace 2 (starts at `void Starvation.lockBThenA()`), first locks `this.Starvation.lockB` in class `Starvation*` (line 19 in `void Starvation.lockBThenA()`) and then locks `this.Starvation.lockA` in class `Starvation*` (line 20 in `void Starvation.lockBThenA()`).",
+        "severity": "HIGH",
+        "visibility": "user"
+    }
+]
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/build.gradle
@@ -0,0 +1,6 @@
+allprojects {
+    // Expose the per-object-directory configuration to all projects.
+    ext {
+        topobjdir = gradle.mozconfig.topobjdir
+    }
+}
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.parallel=true
+org.gradle.daemon=true
+org.gradle.jvmargs=-Xmx2560M
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e8c6bf7bb47dff6b81c2cf7a349eb7e912c9fbe2
GIT binary patch
literal 53638
zc$|cL1CVCHvS!=1jlXSc+O}=mwr$(C-P5*hOxy0B#_a6gw{PFQd*AMf$S9nwIF%J&
zW@T38QIG}&g8>49f&z+`rWXhL`+xxb<AMH5vZ5-2bdqvn44^;?|HN3N=vF51mqFz(
zq5W4zSwT5TF;Qg|dRehY+36`6X*&7^cxgK7+3C4vCB|iz{o{vex^c-F*%=y1T40!q
zFq5=jC0bM+nB--@N{q$_TXD`aAD!-<fdA!#|8-_yf63m-{QsKNf8~Mw4<2(TLlYa*
z|0gTzKeM_!89F$aI{jZmEP_nTivO~%{3X(VKSadd-Ok3|(1eVM-q^;_+1WQn7G{tU
zDRj?*O^e2jAqaLYEbk|w12H|XppCE%w4`KJZ#FFAe&H~h<0bD2AHlRw{p%4lk?`OE
zmXVN88%O$-ZzZ{5S8MHp8rr4QHn?FMOJ`dj>jfaYnhuL1B-AyEh7yL(^HM}tdd%Oy
zItEC{iBYU87GqahUV;Z_Z4ltsrNV3v^(c_wf{n!IQ%)E%PXZ?-h6O<w9y<i@N{8?J
zFEWnohOVOhT^EPHODyvLkx|*x*~QdW!O8w_uZyLr^WU0>r=Y8gg{hs3rLm!lz0*Gy
zp;Xz{9z_tz4+9WBws2T!P@B5B>ZNiVWxrs6105R)%_LhTD<fcQ2x?yEZepMKQ2!Kd
z%X$y_Rvgp(Bb5jk^>%3XiuZAvm#6#n=ydHCXwt)qBsK^d797-?YMZ?=E*6blS!4AE
zA62`<ngn5Npe@iFZUR$pzfw1>Lz&k^VtKI4K%>e#&|`^@3*&)K;DyR)Z3yBOvGeK4
z4^5_`4U?&c@QIXM?!|N+S;>=x<hDisx~dH-Wo@521#b0{2&w7h5r8u6sflPhWh=S+
z6uOn%Bdp@ia0Tu+o}K*&tA>@PEp)BisRzh5&cK9#!<B3N4)p(JN0h?DS824*4=T~e
zqAcB61c}PCV+fd*G+{&>th0$w&m)jO0im{}!eG`Y!ErWWqHRmPNa6lHeoI0O&)c97
zB<+3&*|BeBGWKI*P?&cSp8(fmu;Igh$aMTmjSIMDHU~)9?Z=bnyi>R@*5dEHu$|v<
z+H$_MqLK_2s!{&oSb4INpW;?-%wi-e8rII5sY%HZA<Dc}Oux!oIIGSt^)el0Y8Ld(
z1pOU{pK2FLwTg13)AZ0V+UAfxWaQv9wUUF0#!R(p4MA*lNV9(+yd!r?DaIc66Myf@
z<rx2z+Z^Rm(swwAJ1LKJGOE$>(}){@vx}MJqr}CvG+b)^6$VX8x2gSe2H4g$!5>zA
zV)Iw2;xKwfhaASnGQ&Tk?(|B-x#}<4w*C^yzek<q|AyT^FeMuM^RHsTh5ea6KS4w8
zfzf+5y6>rm0Tonu(ragCm*Tl_;m?L790*6@NyUbmNdJ6)^w}W<!Z`Cj^MZo%E21H1
zlZQ$^r#MxgO#y5eVutEZvTB<vg*1~AYwQ>)revy_Bl1mo`!Y3FyoLz2d}_{I3J+>z
zr<8_KDm6^r6(NPO;SAmxGjvLAyre{Tki~o#pD2g_a8Q8k48hQuvXyqdUVpN=9q<SJ
zXGy^-y>@i|>X+hQ{i6H#l8XPYrmC~4lZ3sksf@k7wX4HFgpO6#md6o9`xZ;oU42%n
z0kpPRX@hBRXkDu=4Np}?sz4Dz%bSEk*U@*IXxe<L_mWvzEspU&iL>zyDbb7vcTaTA
zxc51qOi$km2>5|$3|0jxPEU9g?NjARMo>W+=!xmPMIwnc5FK;|B>?pzc`1r1S;!7b
zLrcRYYyW=vEl91uIZ<a{`m`u0H<#wNl<yMeaIwzG#yZtdtu^Z`+ub$ExD!ib+H@Y1
zH-jnd?UiU~vDAp0XXp(+WaV_&AG-Dm%g@?jwpsR?SSXMOU<6~&g&~hAk;%U0unymz
z!41d2^yM@iqQ<JD`gCL5$IpZh6Pa|Z)>>hs##rO;7VDkWwJkp;VD0F>T=tlBl*@9p
z^6l6}Hphyk{G`i@YqQnLVSLcquyQZ`l~bmDViZWc8O=hKq$<KFsKf8sBpLAwS&*zp
zsWAo};@J!y*kAVUrm?~!7#;l;$t>e6??Y^<g?if*N_VN+BienrKJ5v%+9Mtj?$I3&
z()F%i;`d!fdT*S<P0hhQ&X7T>H})Da&TR}aM!zpPO0V672Ln;AW5QX7uT+@DOdTWb
zZe$Z5kmHZMqj0R7G4JJ3+MVBuUie=TQI<*QBUqM$$vfiyXh$5MM8uh#!b!<!3lc1g
zps<(*`q~MA2?H9=I7l*8!T>5>GW<bSg4SetEt4nKA>Z^fhMTV-uh1Wf6%c(P!RZOy
z!h>%Rni*@MBqDGmY7uU5@shJdVV#$QC>Q{W7xJZx{<?H3Z69TID0GH`5Xj1JuH`$V
zNM|_zaN3tayDM@br!rNymw!=6yhGis5pW=&-+#MU{yj`ZJ&bK!oh{u=#Vl=11&xhO
zot<S3?F`LL|HJC1s!2Pbn&SPj&7!dEvL*gOtY8Ba+M*Byz*q`OTQ{=MDu6EqM{l2C
z*X`Pg&6bt+CE~yMaJ@UrEoLUA(|{bs78f52<~|C%9~{AE$ireF7~X5oPV2)*cqjOC
zdi&=$yTJFy3Oo?vQ8H0mVKWGF$?)Q_xI2;_-s_PF62D8-l%(SYbb<Pnr63o1S|5>I
z@m_o&&@7lDX#^W5?l6l7yM*!_xFf>cM<Ey^0F4FMBs2?0gf5IaamWD)XI9+^tc$SN
z56dqDWwj)Zl6%gTO!@lMOWxIm?1MZ+=`@vzyo^SSe$`q#E73YpA(b&Us20mDzX($m
z8oiCZDoeDxnn+Mes$w>~E05J?1xMLM@Tt`*%#1Kifk2i5_cxgbs##hT8`X?LcXV-Z
zRjL|<tLhsIOVn<;Mpj39gr2uXajM2-i&JAxsfjBayB*bgkJZQ~gUOSTAg(eGtFG;o
z$+A$PG*e2B6>^2VBNWPJksV$ZHmVcdO|6Bs7p*Z)W|3)S7``;1i=MZQbvpX@+rB58
z@lr-Uv9??G3|2gHvYnY2*>YzR1iX0|`jEnN&{3daOoUA3;{g*3tYO4_3dqdzA4DQ(
z;Db4~rctGs8m<e7%Ov)>jcd(e)B)-7lWkhTYzKyvTHTC4k)Jm31UmSJ*4#Tz8NUTr
zg=e;Ka6^0-s*mAD=(Uz_tz^g2&7SXkS4LbH2UG_)6-|v4WY5e5`81bRwDXDHyjStU
zw58j!<2hvljfQxkoFy!4NmytY40o8tur%s5TbN6kSL?T3y+fN~01wOrgL2s24az~h
z0#euv14#{z_a^vMR$gkYCTIpz0Hc`eM)kRvaV*Rb0R4EzK(t>E*^y}viQ$rzX!?HR
zsHx6ywVzJXJ&s;_;()SW5Al(#Oq2f2`wbP2k<V!paUt_{obxbV6cnDl;}c0*l}Xr&
zjfu{JjZrLIrkY7zC+SU&s0|CV$g5*j@3oNMSiHMwPx$NC+mF%k@sIn&nD|8VymYG2
zkg|^~M}(onyd(t-bhi4*$`@$SCwWV&BKYX=Ir&68)0FAwg|K4+?)*D@lSt~WlwOr$
zl^;yCZRbg3R~l_2m{=(I+}uekH9?@?(?JzplrU}FlVJ?9!2r4Rvdb)*>2kn0BT6%A
zpDlZmYM9Su707h7t!zoo>2)A_Z7M;B=Z~eKE98@^o`P!X%ga~-)Wj9h<Z9EZu>CCv
z*fPDA71SucX>48kHQ(k6buZkrc*OL+juhwm*OSyCgMqZFYN<f6Rr*X{h+n)2pBmzC
zpp!_WZdX8iBD=g$BxDr1rwLeY;zCB391ga>Yy+50x2<u?iP`KrVdRZ>R8w>vQ`~v1
z^y;=c?8L$0)tBxFlt}7uvKlZQ<OXAZ<%EzT&M{pTqwRQHycMPcPq2XA4%|?s%nfib
z!VAO)QmKRl>69sO!FP5?Zd0k`rXA{0>G{F0%<xkYKtcA2Lo&4XjWQf$s_=io&9GEp
zTfo$2j&62vT;&P@^a#o>xW#|p%o$SGBYJl#l-fMtu<P{kkY2IQ6u1?D5w#@dg-%e}
zz=V2I6wNdnv~6!Y<GZ39q8k=%Utp0@j8PoyI3v})kr3$UQFyTEamhD4P_Vpnl{rRd
zc7^Wc`V#sL;-7xEH>Y!D_D6Wtb!WT+oYx0rIFy>8Av5lSc}w3oY6(By?Jtnw61juM
z62w{dhJ!mo)MO5k_*xg#LG+99_X<Gw4gr1xOHXT&`W6Qmp6wGK!94;KAJIKLzrKX?
zDx45OT6}`@UYdg-nS}M@lSZXx)$+<gpJ=(t%_cn}-q;B!Yh#%EiQ_Ovdl36kmWWf1
z7*l_7y;B1IkWuL=T|}xq?I5?&^+T0n@J;O;wVb(ESoQqfP;|mLTtiJ5z^f}x+N|he
zK`AA#$$R5-ShrgDpi9!2SGKpXE4E6+v8kDe&O3Nt2>*Fkn1<IAOZ@A+yhHrA&Wrj#
zN@06DGfQ(<CqoxYd%OQ|UXpF)Q3a94{%oDD2J;666cv$N6Xz7{vp^%NGO5C$OZW)a
zIi!&u$8GDf-78y?Fx`g|4j`K5^lBH>Yz=d;G_ySBe_iW*e9X=11D)If!lg4N4A`Ub
zV&HBZ1;%E0IbJ(G2WEtDqAht%=3i_D?yl508g#=A8yqeCnBm7@Vrple%i%(Ie@C5b
z!<AN)8*|$hOR|;Iz4o#MgN7CEsyq(l=xf-x#bYh%UmaPX#24)@vurg6lZSb<w#_7H
zxV~2A*{{bvw|Or&^}L!@qwZecWaio~HNR_;q5cfKW?9CmTVvnM>)dOMnalI^vGE+0
z`=zdXTD)`PMPW|7?Xv~5O5f9?P&;8i_u-`6=+zkBoK~v1utZ&cL|<2VRh<=H_2;EZ
zOuReETx0{evfccE)NfBIPK8iTKz#O=PbAf%qas3h>DtSC6*l|UPo;HV^BV^q9d1ES
z-;TbX?V?+I=J&}>bu5P~eDF96T#g^{H_bg8TEd#bVcB$S7%;r(F6VQ;erg@J{-N0A
z{3a|T@OL<nQp9~E+Q{2=Ap?{?S|6DY*Au8gPW}~Rt{Y%(JpNK(;7REU%&|9xQ;<1E
z*)ZoDW0D~mUo6Q696HJ=g~}kMh$%)vEgC}6EQWUoT?aiK>z5~8rN8*e<wipaQciTT
z`Jtl@>LK|>+`XOeZ?H_~6rGG*qL~?oL5F2>iaQC|y-5dr4m2W1Y!fADX2B!$zqJxE
zoL)qzKa8J;+ENK6aLmPEowX2>lSIxXnYW-yNJPm}2{mv{1z?@U5EGL`@sf`vh!Tnc
zGE{;}%;V1F5~}b?NrGvT&5MvFWIwE=5?bJt)Pv5f{+3O0S!=#OCP7TNm$$!Q{~6ng
zzWA2Mf1Psdzg>*~9^3yK?@Acj{eAr(?oO=Qr8BB3+8^6&lOeaMVg)IwP$&?~-w^@m
zHZaulQl*Gw3ba98vi8ZLCLA{GE$Ha^Z(?7AaB)NG{9M69SOc@;?tcK!?i__P(VJ#o
zH@&B>bMLv%b60zRKHo6|zTPy4=wm88goRPXSaXIeqBz*z$RAT6(2XA$>D^JODO7XR
z?$g55V!#~5>YycOrJUq~<0^?}tvzs;7O#Y0cYlsx=nQrz^-wbKP?p|WGcuA&Dh<(w
zsN`7-!dRl0MNPqg2$z|5iKDZMca@{P#ceeU{S0GTLO~6^igB35VZnCV9K9+@%w)z>
z&YP0S&t`vw@fx$CM3?3owGkUW!6!{em7{IUa2I`PF@D_7BJp2r0Jt5(u$PBu)2KGE
zFuQGZm<`MDup60)^mMz>c9>DH+x@b@WUURkgd(jbQYq!JI)<^66k!VuY-N}drwqqT
zB00@!6V-e~Zv;5smtYS`jaZmzQAI7+98fF`YP#L*Tt%d4?0@A+j2duO3aM$>wWd#G
zPLZ4|?V9uz7)XZ(E2?vbSxav{cOJW#E}N*B*A$f2G>(UuB3mKPJD~^I)*{sdQL#*5
z)7!V=m^yWlMM*za1<{}6VYn9j-YoQLxZn~$chDV_(G1geI5YNmHmchwPiugcQ%c#t
z@Dh`LmR82^7Chsq-F99aFZWE3qTyyXShBGUNe_xMZ%KNxIB!T?a#a1jyIoL@=28dd
zS7y*@rltbLW7W*9#>mp#G~tHG6L%eQx-<x5ZeyI*bSLFH<Q#JxfdJ_#se=!$lMFmV
zv!0<Jc3|XRBCuI&BsfOGKktZ7SoJ0`Hr7#ih>D*dr0Ekj=ZZIgN!_>XsO;1?xJKQ#
za8K8_bkFCf;3z#7|0XHua*dc7xct%&(u*REfZ4o#jz^EFk+WHs04h#VZ?F|r@xUex
z@6T*}TFQbQC%V%o;oI!8);K9KX8kn9;L7$@V4bdElPS?l!d3)NQn8;S%k$FXBcu0;
zKj#tbQz6Nd{dlKIUK$q9F~F6ER2R~s6iW-EU5({rmu8Mc=$q;_Vq;Z(%G}qIn2!YO
za?spUiW7HS=-$Bm`^a)gGNKyXkX$qvPfg4cpZ-W5vcY~f#r35euX})NodDZbBQ&;^
z_b>@rZBo`7o<k}t>HYRA|2M;_B5)2zK=wui3<3wEezGv{+#daSKLx;vKk?>(YE<>$
zBA!3wp__778s{!!t1(`Mfr==|uI>^^6tUH!hBp9F@ZnoSXz59qHC{CO?hC|!?u-0w
z0xE_<Ft_Y<U&LM?`SPuPCz$^%IXmHYf-i(Jtw5fkFm>~Ciyf^ok)9oWVf7U$JHN%&
zGvp<5m!yqfEIde1fBY3|3vK%+bSG@$@h$9o^ck(uhXD~9py(3eB?P38Bo9|b*b15F
zrl^;)<VC7BSH&mBfn|2@<5h9amlZY9_sksR%VR-Xm@`DMMS(;xLx|@bp{xTH7ipB@
zB0OT7Ug{M&jsRqF?itC;5?wSW=kb>gN!8l<J%vD<o#Xb-sNnX9bcg&5B<EEiH{`qF
zvfLE^E`~VfwbAyD7$x27<I*JsA3=d>Kp%t!-vCO9BMie*w0w}9e7ytwA;&I(d7{u8
zx-jS9q0Zs!s$!3ne|;*f#-dklx3OMgytDh@7W^N`e>Rz=o{U{;|MLv>Z=gu{?@gwR
zz4?CzgrUhF_KON=WBuu4)b&iG4l)_2xiF&YVfIWEVJ6VXgwSRbAGImjb<&oFXt95y
z{6ld@h6z7GKZ|2d+u%_&niKN!oNu}EAF2JnzkkE;BgrRA?3;n4JJ1AfRZu7f(~9Uu
z@Ca?EIuHpa&KpF;mqWN?uR{-QvJ5eApTad>NM2{?*?JFPH|Y)?)|U_QyYE)|Cd;vR
zx0Pj$RT)F^aK?0&kA@U3x8mzA;JX?)9TykJiES%(wbeP7k07zx<`ybk=T#D_jHuA*
zo_EF>p3@~N;5<x-tn|XsAgJUAXo7}~8u@&vxO(~U9;c0Jw}wVz=CuRl$W|$g!;CcW
zgjrHH&O?-rP}N<BpSV+g(%6=7B0QVn@Y#l$%;j<82rv(?D}CD_h{)hz<CP@}X$i5!
zdUr4!2;v|rN)$(k3-MwcLLWotG7pXZ`LzFSu2T%sK1&m6RTtIB@b=0ttHWOc>n)`S
z-j6z@wz~+UqXniOzAW*bW4yU5p;0zcpwp6%et0mlq#sE&E8go83gi0)JzsFXfp%2l
zFP8HJw<>8i!7UWx_e1F$nj+ng=pnTRid~|PRO*4*Xq`d|nQQK$Co&C^S60C?cU_3s
zpbsuX^PPtzKk+ln!Z&Q4xdRN^bg`a3pxN0WO|Fg40htH*O%-VNeLn>;u0Oq>wvZ;I
zPmcHl_G}w3cL-hTrg#citC-&SY4+nR=101_xrTPAI<y|C#7^*(-#T6%;=a&U=`KlL
zo4D4pv<F>J`Xbz-6?f<&8=wSxQ96_xy?6WW@Z}HiKSOfX=`so(5(vl+0SJiV-$PQt
z(8WT~+1b?A$mahXRlFPHsw01|uA+M;b4EF@w+0(g#?o$JNGby)QSVknYU_Vf%WZa8
zTa(&T-*$CZ4~IFS0$zQ=KvF&+Ftw<LTY&w3#e?*1=xVo7FTFtaa@<<(PIIvAWw-zN
zp8Mhe&Kd1L<cu05$Qe<>gRmQ>>Ln6Z3_AwMY_yp)qKrg44l5?$Ym-qzsGlg|DQ>4+
zYctn~HDZhj`jExNPx_nRE5Q*)A09dSfaJ#<C_DP#<R^}pi+16UoSJ<5;Emli!RbdF
zMl1SIg)xjRgw_w=sVaVF!RcdW?;)LMGx<oL*pJ=iV)fyUz25o$bfgR;9KI9g@}!LF
zhCztYh}Lo(chK3=0Ca|#QY$!@Rc-}~&N#Y=|4ful{t_k~dSp=^N`6cq6AwQvFQare
zPDdjXv$No6wNYe&-Jrr@ggr&S!f%loTaj^Bqe*iC|Dd24%f}<g+2wAnH?V#$;y*fj
zF}2oY^<fE1^&JFUup)bIGs3?X1&yk_)&$KLq?T`fBM&W)Nln3a@zv6yx!yDEo3m{t
zxHe!rrNb57;5A+et-7c7np)G)bmivGZ<qRswaUn5$03xsbz#_lz;<=B5I$CVwdLKL
zi+S$=Qfy>h=G^;h*HG;xJAT<XcB6y4&MdoD5VaL>{m!6>j5)Sk#mu&uGQw)>kD4UZ
z0bfKn7X9gQQM=-e>9|_y(_(_jU_FaMelnj<P<K>%bI?20bz}kVI}SLDt1cK)cX}F0
zvhA?mSh)6A7U*d>f#JceLjWjX9TnQDg{xyerxFPuk2(Jw-2C0-s!XWo>bi8lh{xP}
z1(*&?GM){Z{NTETOUUlZ&dr>@MrkT>9;LTS^ia+oRo8F>cf`Rr2<^FYzsZZG{t#AD
zAjoNwdMTpMHu;T!@H_#Hj_IH{;>k-e60ZVxG)A2_#D?zdp*5n6btJlLr#T{j7Zn9g
z`yjPegayDJ>9MPRt33OJ6EGKRqV^-MhJ7oI(vN(y?kU=z?l$jOf0IS)S7iz;*X&A`
zdm)ov(-CFra}d^dDSpe1+B-t*c`Fu<7rPfn_aDqxtvOOf_y4Jn-r^yic23V@faX+I
zjS2Q_UE}~<4|~`Y6zrN&P*B^&qsgpmthx7M{!ySxeUe;uOpz|JU1C_5vRxvd%ipML
zC<fRb+Edvc3ybQP7Q2b=KG}q*JcRF&bOOtb$7~)pTTAD-0uWTZg`=H;d`sHFu*{N6
z_LdxwNuR)$xkei#*{2(Um+v0Pl6R@N)3G70wsZi;JJ3~jq1CJA-C5uxtDETw-tu(q
z1NWEccCM;85O-U3+2ad0e}fwhJupGQ5(@k8^z}54tvxpMZdGq7HwPzW14!5CvO|>b
z0=X0Q@GFlUzWDFw|5%#&9Zh(~pO6^y_IiuCUxzWBGy4g{m3Ebqi%HRV&XjgKTwDZ*
z;7ma7l2qpOI|EXyVcB(WO)G9>7&cbvJgs}d*zZ{a_aA>>yty)ILh?LzjZx9ryc`Tw
z>iG6QSb<$F>eE_^mXGe51=U~GEM*;CO!=Wu+C-x{thoU*M<0Fea!=ZKi?tkndBD|B
ztHX~w_}XoCr3<*JO)}jyE;xM>smD90afUCU1M0o12oJGN;arG@Z=3z3s_H|4;hZo)
zg#!aAE2z30nG$Au;=-y@eM7*>ERQ)~3YMB(*4GedBgq=Th8b<&+5bq(E6%nrWisQ?
zK*g4MQ$xj<db6O5%!aZf<tFzVp<iwM@Tm);s9R=!p?Gn$fOiBK`-9J%4rX^jx}8zD
zop~wAKP#AkLY^+x9;`}$(_LyGv=9$6jVN?A5?bOJra>+QtD30`bzcSV!d$b{JI3q$
zlpb%yfai5Zl~=O*rI{?hX)H5C^emnc#CUx*0w{%Id*241==kX`loMYX+0YmxjE+Yj
zjR)NySnM2|S=p&@yUf>8x0Z6lD(yBZocbbfU&wtztiUUI$ELs%=!mEq++!ZN*Ud{w
z`GI2ldN&V9Ugck1(iR(oh?@zGIOanq%a%`Z^zn58)pd?Uty!3W%sW1!bvuo#d3MJ8
zfy%_1%$-Z?hB-y|Hp|=xwaFAom1kjOR>mYutD9neAA>2ohw+==XI*%YNFN+{(Rvx9
zsMQ1oG2QV(=tDPz<uY^hg;{B(hpfjU&nQ;R!ZW3l;PsR8t67^s%VFdZsdQA8_i`aS
zpE!^qd()^q_Wg|D8u=urYh5s$?~)I{@N`N-osYoG#6ZPRtc1DDY&4nZ+e&q_t*6b9
zU~WkqE4;u{N72)FxL+l7k2CO3x~Cj7bBZLA;2i$&Vtt_@U-H?r+KkYv$R3{wjmK?Q
z3i-azA?tZAa$Ww$uXj>Js|0@OGJf&;HH~1;9HO|3Q2b3H?hqdZ;2j=+{M$#3vGCMZ
zAGFCo|8g(Px!bmbiwXpEMFj*z^xxdj**Uuy+SvSKOU>1U^+7vs6`<_i*q|MvK^mO2
z79sHr=fFXNmrPhkO1NVrx-fB1in$`anN1R@)ryu{=~K{NP^*bIqEl6roCmC1`L?|j
zwzjses9D=zUibFCzU*#&P`~<{xp8EhARRLFf0><l=bZk@x%JW4`}$ZCkF+56M=Ic-
zO&_I<C5hF~3IbsTwj7-($0=YYsJ{b4yw9Ek2MnN^+9a_igX)Ycmt^AXljLC(@N{To
zox?zavZk7ke`dnWJv?3k%^AubEP=Y<%)#Gb^U8Zkm2fE^yaQ(q9f9ghngUlHIlb2;
zlqqFZIqJ-?!7$uC3WZ`$#EbxE%}JN|SLUZrICn;Pr^V#r7Z}w&Kf-v{(e68Ys0Pd(
zKZ1BvD|@&Gqy=M+UX)rUlqmvgkYP?gJZqm=seA$l^B<g>^VcNBr2}S<o)>MP?m~MM
z4_1L{kMI3<$>wGjRlq%9?N#4MLbps7+kk3MuYs)&qS1Ge3)Bv_2Gif(mEJpKvZzC!
zfm$8A2Md90Pu&E<zii$*g@0Ys?$fi2R!@EPDCZ#~Q&c(7{=jb_%X;IyIiV?$1mwWY
z%h{!jCPh+(x>IeV7T9Itp6Y4NQ%31w?^nNBz4vJC^3(BmY8_Z-1i{BzU$Ar7ceNB&
zx-N~Dtz>hs)!KKu2=A1&%7o6OUv@ubMG#!pShk{=)i{GMz5Vu}wLE9CjwX;4e6Y^+
zN%Sx;Pc+C{z>{}bb)k527_K;%Jlok3D=OO{7?$$q+(nHZer8;<X^)hJKX*J>tku?a
zohU)JjfXn!w1Z{;HT$z@DP~uJES1$A+j=@e5fcV`;ukkx*;dm^hoS}V0Z77QEvs=^
zYt(ttV*JA85gS+Mx~X<X&+~o5Pu9kb7;L&qi|)kr5@Q8kB*gPXI<LW$TbJ^+3+7}Q
z7G17rdlF;`LMU>$9cG;Ak`b4-Y6$IIO1w=&w=$G2(@|rZNxbsxdz{9|4w4j}Srxa*
zk^)7nD^xRYsXh)$5*bvy2d1H_jh;qm<tV4}7Ps^0G<s`U(M$?)k>{`+!O(hP_s4NN
zidHHN(Ax-v;z34fIjbkn;)oweqF|PcsG8W}G6kDWHZ0x8xMkorF?O11DsL=zC=kMx
zP&K)vf3_D7R3^8BCYDT}m>VPYQSr76ljovIgv_{>lEnb2jJ17Pt^pJd8wPGTlG18!
zP!Lf~yjey&RIo1ad{K&Fsy^41aR`EbyDuwHeJ}h0g6%G4AdIeL23h=4RVy#l^BEhK
z8m^6Z7^H@7Psf{9#=Hm;bXbLZ7SCeDm7HrU@M6p<jNSN%UPERe7cx$22E0m3Hk)2@
zxCFqyJDGrav1whdoGoh2?x{pR{FrB5F$;4gpXL^qmKMqt2*)ZBe1?HAuW_k!<gF#}
z2@h&yW*d)q7O(Eu1k;dfWdGqnG?k_8gM{iTb$PNAVzajRmTV5AVa5dWA}R|u9^<Z5
zDXd~$#-y@n$udg#>PF0hrr{{u7?EWe3h?oWn#AQcs3{W+(lhr4!w?P}uXV{pNg6zP
zO--WBnzdn6#hs=r=v^o!oHLhpQod6xS78$R2{+ft7|xW2!iAItRFh$>u*c_(eeFc>
zz}_M%h_px*j+lHN@_n+P)_cHNj646u(Lx1*a7v{HvV6^y*NTiCoAG*CL2G%74K7*?
zrM8QvCK5YISjkdIbSa~vWZBg<=)>U@;YE-UH0XR@(+=C+kPtusy?Zg_&{@ZrY7O~a
zY+CBc)YoteTiQAy8OKy42@NlC1{j4Co8;2@cWCR(A}+g$u|h~4m1Z+%xRWt0I$M*Z
zPA7BnTa>u7ys(QAV0R}yIXI(ATGu(bTLod&fG$3kLSBRxbKW+3R=dFfSh@KUA#LMk
zG$-o83sa(5Axl)a1_OrXb%uFp()D9%l@nViI%Iyb5p}XQkhujTKWA0aSvqVLrBIa(
zLu)GxgCTVUGjH&)@nofEcSKkx4LTj&*v;Lp#YBRRu(_?NV@2*1;c(@t$11aI@$o50
zs=v@(m0RYE`YXq;aFK|wc+vF<JGHLRTGcCrK=oX#k054D#bL5&uBs*5PT}0^cg<k8
zYG0te$~(nw@!jdKBePWd18voB-o2>n_hG3S&>G1zU%_LBhx7u`x+JKx)mB&43T3qK
zrb+L2b}+Y_kQ@haWG}&kE!Do@{-Ou<ce&Kpd);yR8`I!H_v%l!@2<($JHOQ1V|xkb
z{K?m76vT>8qAxhypYw;Yl^LdDu{MKdT~|KZlyvQC^C#(Kr`87@iOWWg(!zpP=VmfX
z#=aS81Ae&acxtt5WgPl5QP%hpzp@sheYqFQ>858dtHm;zhW&j%j?dKIvweQRy(CQT
z9e&C1$N@yM+)-!`wVskC3m%3(ZBuWEGtP+o#gD}e&~KV(=vYk3b?J5sJ16D~hXfCn
zq>acM*$0+g<y3B$x}J2yR_(BuW)_Qgn#`^F%2rf$QJSTnL{yr)Twr4hXWZ!qPOWz$
zIWe?+acFlad+-`mOMj~65`=GNE!SpchB%@Wk>a7Ik!R%vSe%DI#H?Q}PPN8~@K&8?
zrAm;G=*hvW(nVQzj+BKpRjJWPrVTS^DkeuMgyr1Sj0m4U)UCRqja#_7#j;!dI2H$w
zjj!~HAXI;YPR&OfBRuiDS{2T0rca#zAoH!_{UM<I4kb|fu=KzVmA{Z3^y^1Awlrkn
zz$v!PJY|(**iU+8ztixpBFAOoykqI~s!!TmWNL9${?R$APu<jhN&{K~d~3@nt!hJH
z!%Qc+OM<G?mN<_hwd6Bzy#q{@Z+?N4$W6siJmq=QYPV4pzeIhMO1-p`R6~qO3@_^b
zNpA(^2m!J*y(t-7y@tw9&`kD^BWw1uhu<F5C~d-go+#jr+V&AxUP=yS6P+4HD01S%
znfUAw-cK3i3mJoWKlQnd*g1%i0rw`ZaL2im0>9SKzY`|~PVy^0mHj}C`Q*qe9<t%`
z`$q)Cu`jf~E1rn|2pzPmewP*;sej6iE*4L+ruxGZKH7uvu!wUTe>MEJ^|F(i#YYk7
zp|SInFBMo2hxwy+ym$Xh-9P6}(w^s`{o_6RJTXChrrqKS@;Jua_VxG;?zkzXvQ$>~
zA;&*T9SnfyIEg3cuVlF~&J%P_N^y+WT%OiNP}7=hIqGt*aU;UN5G!;5)p$K5tkzp-
z#2VnaF%`O#-|>KL*Q%^G+e`L%etsmAd$}<z#{M#>0D~=Hwz4eD898sbhBtcx18(j!
ztqU<bt+2PsfD!Z!t2=vQO4$jQd6?9f5O)U!OVM6WZyh97dDCDg`5ue_S=Q&E1!ixV
zsgoo_ke7MoJ>;n7b3N}Xsc4x@v+Kjz=%S_Th6lya*o?<$p0XOBm)~nt$=g_GxAdjP
zOF9;EfX<)7oE*Dg2P-b3AD)|b?K};**b?s^Q_UygnD|x3Y^ev0>b2jbI6B_7Wv&y5
zmV+lqJ|ri%GHbXQ`Q7zm!kg3t7g>IgZ9+&5`nC{ENAe0|09u00JuByU9>&#mOhckB
zEmm*oy?)QxceSieq|O3j@o`dYvz$A{$+D3^wN4a75XLgc`JRfYArmC`>_tl;Ooi!~
zlBIUx1Z{9CUBGXs&AgT%>`s_0?m9VIl8w=(_hI5JbvLoy2qy30luGKZV_+I?BnO9n
zYEpfm9<#JF_gb`)QdsyToA~sb954I&vLMx1=%hlLd?I~=2X}%1cd?XuDYM)p2^~9!
z3z)1@o4%60-R#e4B1^;IEbz=d0ht^cjxev&X~%<tf*@A!C664Eob1c9#-d~YC7oge
z>l)aQy=jyVB$AS@my<59A*)ynfSCn|h2HE*>wGQ|*Noi^J!7Hs{6W;6yS?!zF-Kfi
zP31)E&xYs<)C1EhT)N5tQb#5$KSbtk!E$B7RAfbd@N=oIsEoQ%bpqckm}8IFS0OIz
zE%}_JYs$E354oS)xaSlt-gmC}0FV0|b^agV$H8b8G<Y1DdIUtzjIj*$oHA0L$A%B7
z>iA{Q;Wh~Q!rnOV^RpvTv1N<c35EnSWhgzlk{re*+l7+t^R*%`+2g}6*%GPd{gFBZ
zPkwoQ0R)LBP~Z|jomE8zWOc&Ll%(I2S%Ddnt$PLS1<+Sdri`U(5x<Ut`vkK#)d-%z
zA8BZ+ASx>I%lO1c;$st<;keU+oybjUi?CJTCotEY>RdZak99=#OBe);e7LjwWV{8*
ze@LIPudfBS9=q`DK+l-{nDcePG@B{Sbm7?bd19-1F*;srgg8|dC$tmN2O{M_lM@j7
z=^E^!r9A>PV{uRWD3>QP_h$VV-Q)RTX{O59pKnJ0h~at5^_@Ox&{qy6HOuYr89eEi
zr3*`U+5(@TR_&4Y9{nk}xA0-{(}bJg3H=>Y-#J9Co(>A*X-Vg{mzBOkMr&T)+y<U{
zk<I?nPJoc}+e_iRJc+ourf|ZdUFa&>f}|A~XKR1(nl+rh?7amvtSe-e1pfqT;T^3k
z)@0svS&+hY5#8cr-kna=2G#Ay&#8vrdRUbK^aZ6)@LlnrMJ}r~9P?j{C?pWo1O<@9
zBO;rkdnKTZ*2LuJ#5H$8Vj+E^h(k5i1J7F?j|ZJm2#fCfWjde&Lh)t5k8omOR&>V=
z)_&3}$}SW`97~Xve%gkWubR}>k1A~h#0A}lSYkAZQZMD<)nW+Vc|{kzQlR6>panGZ
z6hzJ_1+u{W-4%IW&H=kgD=i}s5L@=~KS?|_I@1sqjtXAECQMPwz4Jum>*T^K1!|X?
z8v-0`YrGOKrf485%2u_>EA$;O=^%(O?C5k#){E3z+B_E;J6h@bt6FC;pQ5N+-{Y51
zel989B5SduH9Omu>%fPt&2w@ZQIjx5Xz;=o<%eV006o~Z84rZ>r$P|<@tftvR`g7&
zH8WM4k@A_I;(4Neo^II7Z#gDaFB9SY0z9MglCNGsSaLP^q=CI|d{{6Mw9=`Hr+e~E
zJwzkHzb2}wru0{=Vm>`DMfsMfLHNoqO!97a@eoS*wL6V-G}{KX3)XHOWb;&{^aVA1
zQ-k#d&xUGb0x^JZ-nIw3P^%7fi8uOjJNQkD?ZCY~arGQWJ7|JmF8VzMXL&F%T=JEl
zN<R6lv0uO5dFSalEK>D@(u1G<L5kouC-g*wS8~)AJ*WcacE@jrTlBQ;Gq0?hQSQL0
zqp1l$+V2lr1-5c|*uwe6(Q)(HeFjIyX_~M)s39AQ`Lt9%yx{Sq>?}~r^TQgVveY(V
zwSD3f9@OOk$Tmf0AqqU(3Y}^1q)qEjv<jXIOgpCn;&1H_%S*Li=#o&Ft#}2N2wS!u
z_@_O3+aT+y$IN?7Nu6*QdO_*J^Sw~_pGZy-y!k&690%N>(TjHwFZW=hcfw^){k%tw
zM11KE{n%DpNC&-<PS=S0>;+|R#fNz#03J{;epoF8Lm#LOPlliHAaP?r!|p&mdq>hf
zTksAqL^%EO41*VIh991hdJtoLtkHVFXkYtj1?uN)9-V1!i->38cTFa#Yv<x;JU0Db
z>tQe9nsfe86;Y?<^SDpSxSOJ9o<m`7c{*mL9J97>DC_xZ9_PqiSB{GxmA#!sjLY%|
zJ&=Gs?|ElNT(3~}_~L;%rYwjSSx769U`vEhR{K<nd2Kh1<B3quthwL>rH0O)!MJcM
z-Wb<B)n@8O=o~$}p=zg9l6~udo~A$p?FYQ=>qL#8%b~(TocDi7;GR%4dSeVcz$v`Z
zsjk?_KGQ9cm(dE-0(7CxdS&}V)=`lNlIHm|oGHFw5Rekn&1YJ3{A{yn<n2C|x_3qQ
z$pjnR6Sz(KFI^H=$j>)Yo@@?}ox+ISxE<oJij5XZl=zG0OY@C>oZ|+gK@N9sg~h_p
zql2dW07iO}QfEHHC6eCH<Nk4kzh53S*$6sjk6G4TvSi;6{xyamSd8z&Wgz&b`N9&Q
z<AIvT@l%Q;cAaEz@NA0}+6%Jqo%c)wnr^P}HGydlvUD$al@K8J2T02Qhus&cg>MM=
zC86LssS1++EJdN`y47Cs-e4O~!^}5AHTlTx%%&rQZ^AC;OHkE-9m+*9qTmWB_DjGJ
zA+a|_dz;~>{Qmy0Rqc67B&y6SQP~A0#Zavx+ss$HECo$dbre3xxIfqiXQF83Vi=D8
zf*<w@FZBS^Z`9-MJ)#SL(?FmiO=RhURbcI56u?VgZ~IK6yA7g&lFT2I)1{h-<j<$M
zf}4o-2rdHN)CU+Fi|<0EVRO_RLzd+nswW1^FqkjvO$r#1lo{6U_JBA2^SvcvrQq`E
z$@Jl0a$2qwoF$EK0tJ_6BYn!+pBz}@nmXBXApG5*4*J(%oeb5fa|<vo-`U?|v2m~a
zSm&P%U;3NVxCZ!=Y<?No&kd&uH00$L_vTdZf)g7vUk%O8*&pY(L+;LZT(iF}W_jJ&
z32$e+owlKC7@hO7nbvb(pko9*X?Y*lqq%=P*b(gf6s>@DsA)P~`13Cb;X4B|k;7m>
zK&jCGZBCVty}gUG%io5qp{1R&i=mUt|4BO0)ZS7<;u~xNuR<BHVFGgiLCYSIQ<lOl
zV1*8Cz)CVm<1UGAU=R~YtDr?aOQW~^!2P|M-p9@mR_`Ob_rdUc*?+;U&Lo)QVFl4W
zGn2=8cDmR2>wV6i0k|iS(DcnwU5vqutcSr+O^oKmWP7M52AuZ6P%;dX342Q8VCc(>
zcRwloStAuGosp~<*&1cl)W$%05b{~Vfg}E{VI+L)`AuO|{7qw!@>${CNm~pv2}KFS
zM>(r-V+n+}@GcC<aa4v0IF@O~fTnYry?J%nHka%>BU9xWer55kj|lBrmyU)AkEPay
z)wYr<S2SPi;+wy@$X#}6cC$rOjg8c<I&G##5_p$ZALb0vcI0Ill&z{-j2ow&Zbm}B
z3uPu|){;Bh<*q_4i=<_l5re3k_;d!&uv5oR<416{t_qz{J}Z1S{w7OT*3763+lT~~
zgFM!BTwVRBl**?=m;w(8@C<n)J~HCW^VIY%8&!BNIRwVmg63je7k85lgZ%b_ACqTo
zs$F?lS?B4-5ZP8c+tRqye(Cx`jEc+*_Jpn(mx-4Ux@VOM{f&j3tIE^`C8V~hS1xu5
z5(e0^WlO@5*{oC(*QrW@+5yRSa1c=)l?P-yn2SyVH?UNt*iVE-6gPB>_2fH|z_=KY
zU_`+Tloxa#7->Na7fP=)9MSD6(I=3jaX$08M!@(%!2IJfYHidNl}D5?u<YsK$CkGW
zG_*Jj|In$ZNhs@l=vu37+#xKu{vi$c+#TD!(@;FdP`p?e0jj6;AO}p}h`Y+wBTzNh
z&?@s)jRA<6`E*Vm3{DyTa^)2}>}EIZnGzI+F9hao4Fp>;K+ZD7)|O|C4-68rDHs`i
z?w&9FB{<;cpZAut*c?zA!C$R2&#Kfe$^ad&9ZZTTnpTB|7*);D@upgmwGplMvP^t|
z$xT}2?}jJ>YI)B3qzy!sXl#{Rhek*=QeB5Aj-aHjx@#?&Qge5z%;t{b!@gG98k*z%
z=IOl3`%fO>dZ@L6rLMbgNTHRP@+gBqtw!?gI!CkW3z;|7*rQ2NZmZ2KM+5#s9-nH~
z81KEQK{SyAtHgl5D0Zdbl4Pi^Je@gQLx9eTG#N>6(F24|-gh&_jtW&V3-(G`_z!|D
ztI`)_<ZUK8<|-l$(s(wgJkh#yAJDb4KdXq}k3aV5Vn;7qq8DlBukg9U?t(B}&x#jL
zp?K!yiw|)Ofa;fI;!%m44#WRY@I;=>6eb!k*X9f+Bl(AC+{K(6%nV@)1g408G2u`Q
zqmBbJ#jk-B=}#OjhH&gZ>r-5ghLnTL-t%Tr`T*zuK=B`Bk@-lQ!9>tPC?A7HEpW(f
zxgBJzGlJWBnwb|S1nNbY_QaF|rqB;%`t@Uv>;pOIYDhR{G3o<PIHV(*_4NS4H`QZ8
z9o6nowh4zO!Ohh^(JqIKL~@sc;YnU$e1}Q&X`#m@YIV4w{~GJs(}gy^C+8(5+ScfG
z?hM}&)!wPfQ|BJ?;p`K-FW`0UwCHZC-#@pA=Ad7T%qQr^`03M8Ezk`H76!Fs2Y}oo
zc<DIFSI#YK7!2kfH16S;dBGG(#l0r;YmdA(oIjxMh)*jLZ&y<)El1=oXwU6%`yKJ0
z&7s6<JK56TCMgyW5a9orVk+ukYV7)-|Cpt!dm7-WV*inCny_PE3b9LSqoSfEw_ThO
zo!Utwl~l$VU$I%tDq5YmVbxr}3fb5ofPw)4sEhDO&_qOQ+Xc@dA_9sqMsROG`0ocn
z?eAV^WZ0XxY~lT{vR`{&dvD)-$Gks&IU@?d81$k%9MSo0BM)c?1AgZEZKI1|BR~}H
z+i7-=#kYey)Dzkx9^!kLBcXRNL`dO19q9_H92tOf?a>W+n{bj1c^^N0n0WLz_z(pk
zPQD5^Js4*Ck_BMD?=lRDgT7_>5GGs?F;77-((FN+dH@2#k9jDE#=bnr0>nq6#zMYO
z1#{x$qjKY?u9TTST!8YC3FF@GL+<brb3aU8GzIuEhc`H}29h7Xe1P<!_M?G)r~()u
z?^1#KsHf!L?^}twLar|#zQW+-RS&b@(j?y72=}0iF!#{O_h1h{-U2gThKT$^2qEuL
zKUo9vsVepsaq+Qlu5s|s@$uIAxVPKAEj%15%sotG1S@WtZR=MPmz7ZQ6{loMDA=hq
z7Hvxw)6$yUEGA;=3{3L^>SitC#f8346i&z4=T4$}X3pAXcW`HUt=(N(^nX6+_6m0w
zlLim*g`)8BfFA}el`++3s|m@|Xq;r^HKI(!6>f9S)NAc;W=Sl5Q-`w{x<Jt(+$>F_
z`QlG&EMe17PKp&eduhp!v^r)t@|u;rkWrx3T(V3@#z8AbQ$EM}mWfd`8<#&`w|O#`
znUTk!A+B68$>6wT5;V7w$;5?u{`fgE^R9-b?#au?_wlR|HdryZW;=YY;i^wkifB?c
z>gp^KC(Rq1k+xl!30=4&8aUG$MqKDxH&6(YGs!`z1byiPev01Oiga%5(I6ZsWayfA
zo%hA$yD2(mE=z&cJ37MEWwW_l&ZfMVB*DTn#zJDUECb*y^vo?LD%Hj>9_mG@X-Q-<
zhP~HYhdzOm__%i--CJ($pj*UZOP)U9^@^4&Wtv$$;$efR3ks06Oe@XiDz_nPn`KZI
z6!j6*P+goq6wVW|)k4b((k4nYLcZ8kkwcw(D$6LIeV`EV`&l7>mWGKK^fR@GR%L$i
zQ%GsGek%dBTRNM8uZtWld6|ZeB$Kvl%@hmcda3M#?OuWfoZNA~JQG!<q$~mfC(%KK
z+JZAr2)y-3^cP{VSajB4jKg{xw(?VF(p_hwLC+dHq3w2;(My$GJ{My_WQucCj&@B+
zN1yl<+3Cl1XLM3abwx!$rGBE}T4XbfI~8E-GNQ&98@p^JU!r`Xecy)BYAr_jPb>KI
z8vO%$&G(;FDa;<Kx`NJtJ>o5$Cf`Eg>WpEA$}SDr@!fh8iHbKizaeg22M^BVCKP3_
zx(4)?F7{B&knq>}42PvG7iCVn1Q~2KjlH==OY<4paU8t#o3k-{Ro>XW$icm4D@;v3
zYPTa(>d^-2ky4MwsPz3(YJ`0$bSf<B?*IWM&28m+T`ev3drIEoL)Q+;k$h2Ig0TcM
z*{Zi_hfh`Z%bx57$=GxYR+iF3`?#2FRbCpKi`2+-Kye`t&NqGcpYbgRus_P|-{iP#
zqF$_tSM1Ca9kFRoO?Q1H16iXf@HX88&-UnPZ@&qVKlORb4?Snm1`OJxPFrtEus(mk
z`#5U1M8!1FGfbb>$&g^DFTR*h|6-)kR7EQd$=p!{%1{oJ!sUCQzn!0Hxn5wtwQ^T7
zM!%AbFwo~IR7_RkWkD44vsb@+b6kqL1&xj+$B#Ruk8Q{+qIP2I6ys<O%Z7=i({ZM=
zg|V*m_?``FmAyVll;o=oe<e?vxa%Nbf2J~KKre$QT_GTlx`6ZMOm>q^wwtuB^@Ue{
zvK%>8p9Jf5LT`upp6Y$R=rqET8>y!TE*-1~Q!Q13xkG3CjH;rRPND8ss->m`NTa(T
zU>SCI&f{4#`*ivZC}!ua8XMW=K%mX!cwT7)Q+g#6c?Brkyp|Zs-az0z)#Q0yxi9-f
zAB!q)(i(T_URh>ur>Z|7&~W8U^?J-b?<&c~19tl^qjs=V^mFNZD$?0c1!P02%l5g`
z4^4$_=&PzIbYnUdLQ>urdS)-8Kz4O_4%B{UXba|Tre?S;gD>d~Za9W?^B^E|eY3GM
zTjG2;$&bQBMUGOqRvwW%5k4-YH|0!`y{>9|{9HR;FP7^Y@dz-aZH7CX?67)?RuSAP
zvU6@<82_@we(Y>~2QM8~v>)6wnllD3_bhdjw=zq?Y|D!}_cS~Hg4NVYczBVP;${(E
z)p^RbI8{xA2SJm@L1{}J^D|_MVPe*PDc-7!8Q~|3hf!{nZds3xaVw?c35XTl%Ll(X
zLi_%x1w#_yYctMJNl}4bO(wXXr;&*FI)hl`;eDDYarZh?mh2xFt{0WCbDI@*>fF-b
zy?sev<L_6k2nch`i%7)z!6gq&b6OBHQ)ohqLY*6Gk6>!t46x4(^&d^cJ=K_H`N856
zH<hEjZhV=LX<?{pKtjm_+&{B|F+t*hsWx3`M2q&s_cyp)lz0-XXx4bhIEzJ7RS#8)
zt3_KB!{X+(+R|AwIjIQk>BMWDbjt%AP1=}XsG{l0E>Pl)E=pV)hLF&OE23KR#B5^V
zxKi3#TlyloCPH@bMVo5UwwD*8KTH()VbC;lE@)aitg3BTQ*v2T@>m-hxk+JE=Z+}n
zj)-MD#x}RDYFam~Wg!+C7SDx|9u6#!I4pmdEj+A$xfsLW4DxB5f;6H_bJ+#NU#@WC
zw{iw63ZPOR(AMPyL(P)6BKNL~aIy~#dv*YyDvME;>I8T@5;vW-0rLjWZ$}?@z@;k_
z2nwMnv!^t(S48n8!%;VygV<A@`d~YyRE&Dcz2HD=SQ9GRc!NB<o$v-^(QbAw{)C%6
zY{^UuH3+k@)vo*^sc3OwqrV4hS!gYadFP9zu?Ur%9J9~*P?LLg^M*%S7cP9(wBZaY
zb>_^~?DoSjpFW(%)^b%dM1WU3b}KuJs8w<m>7ee7V&)Q^W8OIa1uwOSH){rxiwd19
z4X<efXM2bQZR=L~Xmjz&djXQ(l^~3fi?$$&yz^CCNM|bdf?9Q!!O+5=B|0ak)LN@)
z;|qnEYH&)d^0IYfvqhEH8ll`$AChL~MAeuU3W4DV4Z1Rf^xWKWL~EaH9CqBBuBRhw
zKe7k)b!lF7HNyXJYw9X-2mXSq11EK7b=96d4uT{2F1}xMFJ(l0pv@M(%LL-%=ns3{
z8`9q=423Y>9_y(sR9vMXKFU4XN{<<m3Z~p82)?4GXc)1fGG-5YfB`zhzFh4j+B-Qb
za8BOp!By9!>ptC;CD3=h{oNF(4{bV7S^GUGmwF$<v)@%UpJ~1Qh=23W%%$(~Mm=}X
zw0&Uhm>VsbBqp5>-O9ZQ$^Ls&>mu_d_!ZM+k8SutEA7s;6C}kcgP|KqPxJ}h+l`M@
z$!JdRe=zorQIY^#x^{Khw$WwVwrzCTwq04aZQHhO+je!S3%Admx!*nK%>8D~uUwfK
zKO!^tj(FakJKhLdeXx!*-IY-A<^=lr^}&9?Rkuz%EKnqBaLZ9V7kbG{iaurmy9ei5
zCAuJ6Q&gR#av@<!OLi_MpBIzzvyt6V&2X}7J=p`MoT*c>PGcR7&H8EiPfT9d4*Q}f
zs7W<*<&B7F@LRWynC4t-MuR|SV3LNcCQ(;9{?<U`Jsa87^;Yj-kde_$%19P%bPX+&
z7m7Sg3^k>}n%LzEuBY(L?<IZqgM6k|q}aEs3+LKWVBDK$!i~7a?Y#>%^TNB`FaCc8
z<6!Kf%7(vBh5mvu)qi(z{6F#dAGL!2Y{k)la7P_Q`+|_$ShQ5-fGQeH0)bhIoAHmX
z??co?CX7SOGYzom%0fTCJ6GGfRy;^CEL{s<l&DYS;FUW-&Eg<mkC44WC6{yayq!Mp
z=6*ACbK%;i75deKFn!(S@!9Qh3n$O_cvlFt5*ba^vQLMGbH~))r9)S%a3_TZhOFbS
zPRVgNTKVZ7z16KYd}-fG@bY@^31+9DNLD{_C+6W^8^OLm4ZTxPu<)Z-br`-&_QAVT
zXNM@&t)dO#R_V?b?Dqc97s|6X;@CYm@TF2C1ffg=&<KsMph(ib6^cOh8b^RoQ8pZ^
zTEs}yOLqJar-T1&G!YwHc6W%>?x)hviAFGNM1?;(s^X2Ct8g#LlfS17%~x&6oTGA&
z<-HO+E15C-=N=5~S5oe;gi!hML3(Mizp#upepc!0E!)3ZOzSp&jN`jS=hu5a+N$D>
zv#WTg%ilvD-dlSB@tUvWTXZn`8Xl2*U<U15Q-IKmShnGj*W6usXzyn?8Zg-D*})C}
za&>umwN8zA##NF#H^|7#hkVnFJpVd|9+1GsoYVBw#+o;(1Q4Kz?dmS9ZEmbA<Q*&>
z5MAHhU7t@4pvwfCCZXEGjux-B0fxD}fB^NjIbkSHb`d=s*;!gcBAG8G2**;AWG)y5
ze-cr-(aoF1jwS<JaZL}8zmpImh{4)Vg!1v;k_dL&*c3EdtrkCInP4CJ6+r3|`XJj<
zd>M}PP<h9JuAn>9`8!ykJP3((kh_2}sI>SHDlt@TNkS^jKY>BEl2>YLz=1cO<+Ywm
zdsc!5+m?BB<mt7J#WgotSWFa&**7riXTM21Xm@F13S$dB300)vCJUAa#Yr2Q$p??f
zh9jWyEKDzF%0L=}^SQXnoQ4M^)s?I3z5I&KDasXnWGWu1{7O_$@vH$sQvF1TOAaeO
z$ppD~1jf&vEydYuv^<Q_MlOVpC+iX<Alap{kkN}Aq>{@JH(LEDZ}oJ<F}_l^CF-Gr
zhec3t5>J1tZr~Gw%S(Qg_ESa7;NaCrM*A&W5(`7MV*!m>|7QZ5*l|--R;BxZp#2Sq
zswAc)b8;AFwd4Wjds^Q?lx_C?ebTYNWCfn2sL>!qR2ULoE0a0fA8T6nC0!2LhpAmY
z`hs>xq3h;p`<uyxE|^UkFv~XZRZGl%T5Q`9S?rj7GPOb&-Jfv1LyOL;HQZRNU&-7>
zvXq8w(M*&qAJDyOcQ|mp!?$5hI(d8URF-pQIN!0<W&1C$K>+>(dFZdIefn4GM9UMQ
z>xIO^?e{i7@BS_JSAd_T!~r~9>Af`^`i;sRJ>2(*A83kaTdnfSu|^ce%wgR&4_0jY
zJA;+KlcUn$qeJG?0dwOvn{2&&tC)78q)`+aE7ASeWC)!=HN=Bzm4##^4py$7bZa!4
z5RHC?Nh!p%3q_{cM1gUq0urArYM78LMO4|HGOJ?nriNIJK^qDy@bLOiA++HHIivP8
z`Dk^Ka55>;bm9rtdI?Ze#r$xodJQCL7DdvE^Cr$4>QCN8dI%*4YA#b__+o59QJUo;
zQKetIiW%kMCWh^OEo{8_?A3F1f^JcaNJ8;xIWjSejroP9#77l4hNqBtvS~*7keORZ
zycWTht3RzW&5A8%<Bi0I7KWhfm84)T43kkYU^m&@Dfe}bHTkq?=}gUEGKg?Uj|zfI
zDnV5xhC?Zf7b=Ua3dE}BhqM%_>%w`qv``{8hsly~*@@>16^%GhqjN+38i_Ah6l1M4
zb9g6UNLEctB-l5F7x^5HS*49|Q0L3ST?)ci72|9)P*V5UM5|I?4$-;xyM{%S?BcG8
z(3$0*NA1EMv7cnvqcb|*-&l5p7MEWfXYcjl(RmkLoMRf64w>ljmlLbQ<CoHqTIq_k
z0JT|AF=FCMP<mCY9wzL&nClPFSLH@MEABC1n#Qj4M%37hRaZ3{yxa8;5MaaEMxZqr
z;)P=e0~2k<d}j2aWl76am3nz}7^x#QJ$Dp>CLS0NPTZZ!)vjK0h%M*UL$L^x9*dos
z$MQ6d*VE^oZ}oThq8P{Ul)<{}<VLk>jN9-$@@A^O+Wv-XYI8)PT@543!Hdy6vt1n_
zw5JD;o!paPaQHM%owsyk3NrAbXj4-#@_;uF6SJnAJsW4He2T_Y+NHYZ3rFK6<Pmq7
z)IurZ@t|p!N9e*;26b+JrHo%}AU28DL-p}1n%0O_FxMrI8JfI45Q$N`#Fp9crw0mG
z5$%k){9~=D%nA4FDWfhYNgoxnZX?j*a=Pi|?9A-kw5?W?Pepq-nq@SJ)f@=Qa%0Qu
zGZ#3rY2?{n91NL~r6?^sV`T=t5>bbgykdT|Gh}YqmnrW-BKky_i&&%7Jb?~lK_k?0
zk-X;D+{WZ_tQWzT0y|}Tx1w%2_uHpYj>|4Nr%GD)GJ<^5p?7Z{vuZs9K?Ed7;pq(~
zEK}KqjUe%xj}MmIL4!H$+uuCfBWc#ZRX&BfnDHF1KN#K!3kSEp7w)j_-DW(uUDHqC
z${j}XZ}dNb)C@pce%uj-{eX28>B;B>qd4%Tu&Q<RW3c))@R?ubLrEFzy<*=T6UT7W
z28YTbBfz6yh<l=C4x+y2S(6b2geU&09SjKw7d3PM97I5Qc_YJgV3XI^Wk%ZFqCx}6
z6xI%4-WL?WgL(qR_XxBwDK79Hz?ODcA{OUN`$&;>sQQDHDM(B_qy_5)7U-bgu@@kl
zP~{2=M4_mH(dF_JC?Xd%62w&F$d_rq@_H?h1=}?@l$z)?Si&Q<mhv_jLQI7F3n*z$
zu{9XOlTjdL4VD$=_yd+v+T5X8kDAG%o0(H?#r!X^xjboYs*49N6hpvi#7XFexvqqm
zpBHV^jd;5ok-+my>!4Z<nQg^k^a86nf~fB?wQO#qx$%j26uG@)A2>OsV$t`BMBYe+
z9|#Fj3N<7+Uk<^C!kP(2837#KzP#PG3DQKII@0FA&?e0e6nG)I3vBoEDa5VJOP8Q>
zOvI(uoWR>3CzUgB&cR*icdaQsSwhze!g;p9zZ3I<Ds>c$(9K7PidA6E#lg7F67X6S
zrE%5T;-&h&xJ+@1ComeQ@0i#dBgSjy-`v>9d$}4PD%YN2#tu$kBh@f!C)7BiT|TU!
zSs(^1beIBuw_kNMuBn==-T%I6=uE9i^t`R<1F*1_I9On(7S~(M`cRx_44mYTK<PNd
zFlhm6FRXbYRFE>*7vCaT<7lnTafe@{xUX=kr>{WixU8h8%I)ghST+PQ`RfgULtYD$
zzNd2q$rMz2_#v2fsgK8PN1Vp>WJx~i@Wk5pdee4x@J%D4-?{mBfNw0A?=IefN?H4G
z;gY&CxVX8pDkbVh2h6azy47ZmtdTITTpuf{FRr6|gmwh>IC)()c6Xieo{ssDw#@Y}
zjN3fZ*JY3IPTy`n*BZ@&zoUFm6`YXL{7{uCN|qVME^#99!6`|t)n965uyJEHcwx{i
zj)qH`laRJ6y>5_dJ^*tk+NXx{K}ys>Y)r#<ug5F=d1HUQV^&J{xrRs~Wwg6p=A4k6
z`DuY0$CoQ|D|3{6)kHxQQY`bG4y$4C3uk<LAe-)Gn(k$R@+sZ|ic}_#pFP%g>Okqj
z5vj`(`Lg)m{~=qSL2}On2Lft>|Nl3K`j6K0|Kqxrt#0Lpvy8UAime&JBZ>Rthhiuw
z10nUA6fD$FIUy8oe?dkfxq}f|?U4n-Smqo>aT4-;guJc+k~!ewG&cf7b7>r{Dvlz!
zSl8;BW#21tUogKs6M|^t$%X^6-&%YxJItp!jklbC_?~9Jy&duU#6EnmIvg~H+(f+9
zhh9W@2nWLQA&iiWjlzgA0<eT(jhNgOJl`lrikn54i4MXbwTFyh3+)T+O%&q#UkdMr
zIxvG`6U<9C>`_OD_S#?xEC&(p2H8F!`O)v~QDej2=P`W)M-AO|4x$diDRQC?D9>{c
z@0+Il$i$jv#qM-K$w}Px@_i=ixNX?2)(X}3<tEwC)QriZC`oMEEwElFo5E#hsNO+R
zO6@gmjx>!(cOA1qa(LOt89$!_e1fu?q^25b9`lmvJpgNz&L%qaxiem3Gi;0EyoCx3
z-A@v8&#Re^z6Fd^cWv{X7LWE8N<{dejd0|-_$2{}r@?A|TU4&L3TNi%CUcbU0Gr5d
zw#oVrJm^^RR3@FYVAH}4EqYJINJTe1mAUtA+{PXzBhC{A3&*LaXB;D?P<OEj$GJNi
zEcN7!Dy1LL?|Fv|fi|d-WUQ++^=UKFI;~=6G%8*VmGwQ0ehm!jp9*pjTZS%FI{27O
ze_TE1*xR93Q641+xeYx7-W*3+oQ8kAlo@r3$q7ayr{AJ8og`T#(u=I<osta(LZi>R
z_=GIOsJnM5Xdia~C^ylCc8Dlk2_`eZ#;q6wF(6x7YNUK`aWWYikuBEilHFi?kLE9D
zhQVDN#+I$eA7w`6UznAFi!|2^T8~Vo_3u4ddwC5<kZ)WYTC|M~UednWCY|<5xqJZ_
zF4p~OcsO;6;<aJg_LVWRYgLDATQ!9U^z-UI6nOMTtpmx?!Rx9GS6S!hubg`G_b^=(
zp1<3~on<E55Ngle@$Amrm4~zoyl`$Qg1w*tr<bqAWqu*Qn6;`6ojc@sKFI>zT)IM)
zxpqb&kUrE#Z|}VD2o4aqzQPufyo(OyU!6b+F4K_sO|DK281y$v=;b7E$d-P`EN){>
ziP@`-l5=46|8o97J56r~nGsgYCv5rI$F*C$U-~LDdip9fx;u32Pt##UiJvGN&8ni&
zXp98q=sSUHfm+jJj~h7cS+buAa+EWWQUW2mNZVs>7n0C0ntCehS4&g}d?3Ps&qOvY
zwlPCsda$|gdm+ch$%<ZH(X}^Jb_-4wa+x?SS3PoAI!y(?B&8lO3Abg529iY`?sTd#
z-z?qJzIr#Bj!BZq8p&hEepfWD^8mGBjP=-VISrLQ^+t$8D)D%=8pzVE#AM6&YkVZ|
zO11SvX<b@p4olgnQ|1C~`oh5;-?3I;$Mrl8!V0J17MNTAD=hltq{Au^PJKQw3c7|u
zQoP{W&4YyfPLN7B$Y=5!u+89cpWkDc52&xcDDF?>TVMWQ3a4Lj^oqh6CVIrwHJ2+c
z@9$F8cl`w|Q*&Puxz+V!8{#4d*QNFNV^FM?U{-kZ=iE&%r1|fu_B1#xm^w}1r_Wux
z6i@Y5T}SL=SeTe0qQ|nbx)_9Ud_Lg?a~r$VPB{HdZ5xk4RV_Wo<dhek;$zXVQ|GX6
zpS6+o&GpSlbdj~4G%bFR<PHyT+VUH$U?nIUa4jmN96^p`^K3z@3s_=;`35j<3T;k;
zC~t^jz4P5Ly8?m-jssaCYEQd+q!Q94?NdbFq<2hO6B_Q&wR~oC7%@+*$wO+22@MZG
zESjaTNma&3#&46M()tW&(uuu6lg73WX9ngkY~l?{^ZaYP#WanDZ#1W`(2hwBUSd8o
z2a{z6Uo?K@;^g=|RV;Og-Cm-Oo5nN9d~W*|(;|Q=`YP=GqE<+?mJm0LUd7@XUAGk)
zpRlu48_|eMR6L~9j~_{vaU$;MtFc+{x23AREN3)_;Nc_RE1GI1`I(u(WwZf>?o5~f
z>`yg3L{oL$ueLs%wBBkh(k8Y@RHrWApZVD}bwU+f5z9&45(&cEV+FA7PHEi`V_7K1
z(~=J-!fMYv)!zZxuk5b-)K8Th;3^Qi2v!cM9e6>Oz%ONoV`YhJg?jyQp4mJoC0B>F
zc_>%gk|h8RC*B)F`Y8JG^iD=d**2wPMJ3sNd|y?LD%X8ILkoj0KLZ2+V!^3uTkJ1Z
zPk2mB@6KG`7sWzF=B=JY-xmm-BRxg59DuUPmbWJqacCvb$(90s*&4x+MDZs&ylPMM
z!KMt*t5ZBTc5-j+znxjOB(#ic`T+!_1_A`c@jp1T{8Prx$iP~}!pYgu!qDaa8tf!1
zX-ne>qJGVoZZA7mIyARzXg7I;SzT@%XiEzsgAz4`pc8mg$RrTSb*#fB%0_-m^()-v
z^Y;;`@-PDy$`HNR(w+X$Ijv3hV)y}d4Oenb=~qJ{$jd%W;m-PWJt>mC+OUqrs^l{4
zo<-ymt7&%CBER`=RZz>`Js7c;T_Lhzr{4_W(QbrC`B}{0O5^z<z1{EV6M9XHSdMrQ
zs8l?}26taP-Am4oTR+C_tu(a!q+wB^;)nB+E$@W_M;;JcK_1Van>acwu!=%Px2c_Z
zZnlJXN-hrGBa|(!Aq_0{Fm|hGo}fkc)n1E#`zGzoQF3`axryKz)n>&a|J9gpJAU~y
z3vr#T4M>y+5>cPG57!jrHSKr3pu3x2?A3^tq{v1%KYM3GG77Y6<HQ3CTh(Lk{yo34
zfH{vnDz>mdxiQTKyd5&aTh{3nH*T9Zy|^}s!V`|%lV`BdlPTy+)FnJRO=!B})RM^(
z0u7O1IJJqX5e@oVP;^v^5lNwK6TX2-722b$_pHb%Mb;O|i?yQmz@DeRjD)*4`C2y=
zUpvUvUO2D%I_>NAP&UQ~atH9gMnZy-6b=?75Rfzi5D?LSZ@&7UmI~_OeyC<xzNU?x
z%-pb?=*SuraV2opH^k5hO-n!HTsK+zX`pl!92&USX||`V%}k+GY`QCc+cx8?7U`jB
z$ELJcQ_LNxs_<x4t7(5=d|)h{W^P|0sZG(p#k~C4IrPds^*WtQ_RIAH>vR23HZcmR
z1L2(CqQ}-YIi#>xJ#vs4DS!qWRn6)Hq2dchh&&-NoDHJF9}qY3mKhmUWjREl%D9t6
zLpW46d|QOZSG>paR%6LkzW4AJ9LBgOo#(+WxE@9I)*M#9Ym2I-dd-NKe)R;}nHA{_
zv@3H5-c`A$%~GjTmg%95%0f<1hR#vB!vot@z2gPjRlfrPlOKQ0k63(-k193cAvqjH
zCKQZJFENNUbs1&Eg~Gc>iLs)&YOT&P=)@Y_KYI<|@8Y&gvn4C<Orgzp_+C1~Q~q;s
zPg3Y6C%;827$K>_YndKXnRyeHGmQgBECp35Rx&#BEQ=RD3V&T_uH6`{zamu%r?t*u
zyM7+fR9)II(pOM@dgh?NrHz{~H{_wlF{N=5+@mi68B4Gndk&(xErT$m%WYKBPOH;w
zGg61=>g-@OGS%kwGfJfP@KDQXRjR}E=c{-%>Nb0{nT!!}FN4(@#M62eMqKhzBXdVK
z(qqEh?TlI4sO)dt+h+9Xs^U`27dXkutjVIsmU^cC9VqOAfyM+XN{KaOT5vP$o4zNN
zDpbo6Y|KexIC>dP`C{wA{M(U@Y7rt64%-o$b=#`t<h&d192Q5z`S^PjsOd>tqY|sN
zk{lBr5AM!^I}TQy#~1^I(rDzfsSj&kTRHzrZk~a-sgHpqq5->!bu}#!cFW@sMWquu
zt>%ZC;1)-oL=W~<w{%b8UwJP4PDAditL~(eG9;9N$MC-Zm(?bpX`0peWE|t(YHrcz
z#}uSh(XPvd@lyU1Pm03;tU(#5np!G3DQVi|V(3kpQi-{^V-=Xt>m#1%;p(nz7Lf`M
z@f55%`YZFbNC&vqLtbnEV}XGRi<?nac(&WNj-Q-@Fev?DDYh@bjP$A<zS{Qd+fBXA
zTW$mkZuSrii{6qWG7vzTwa5?+g+*_{5esv4>L@49BM_~^$~IJ#A+#(#&@VdQMRSM-
zmwM*}M|pQv!6BX-8W{D<{FT(Vcz@Mhb;Ja&x8Kg>Lv9f5LvN5kgn^)sApK9&UPSh6
zyO`8SE=w0+m9&a-kXMteCV0#deFMX#v|FnFmxwTH`LB^&)(<edvDZpK@4hUY-{>Xw
z7ZLJJ|CV1BXop%xa-TJo90nEgy5qYnf^%{qcKuC%PyHg+ne#?r_DtN%rYh?ZT&04&
z<1@uM%^@wE-60iPEeL}_c_Vfuja>&mcME;#%%gU4M}>I=tRdF|K>J`G3QD`sh03Vg
zYDuwmM~(OnT2=dvtM;|3EN1_P_2kJr1;fQiwZC%xbbYSkZPbf&VA<w|awap?&ZBq?
z4C6-H#CnvvIy40?NvbH=->SYvg;LE@NBU_)3nzS~Rx^1{>b+}Rra+TY3z@CTUQu~&
z<D#}Mjgeh><kJKF0h(^}Vo&KCXJrgjRaG47vVuuPn{9OosS$ls4-Y{EA=Y`=lEO*9
zr>%)Ay%h|2@^M2-J89wLA_}EaXXfIfJ9mBss!&Sio0G9njaLj>|LgQL2NqE|k<PAM
z4L^JJx=o@goyAgu_v#v*z(uUF1%C_HY<{NgD08Z5$dK3{yvLS8-jsH<tXoqrF3NDG
z0mB*Jz%82u7yp+g=EXMi*4WFTYtQyhI1rmYJ2)r)LFZhkHfL|OWe<eGz0W=e4IiT(
z|HbbgH|vo;)}tIw?W?oCJ}<~cH#v=WE-yKv!fv~ouawYP_f^~dt{{Qd><%xc!F6EK
z=A+nRP4IYaiPYPo++q84x78gxkMtfSNCC4r;h5MQC!;l}{g|hQs~h%rxJQ%bT|lHn
zv_#JEmcw2oZa=cU9qo!&%T5)kFOqqr+8|K2XszX(TGw`$wEHT6n}W7^yQMX{7jzJ&
ze>-lSrd!chBq7WNOJ2R`u<UoI6_{oj@smPu<mkDQeMVC1PA69`1hZhCQRX=?xc`t1
zhcTC%vzkO6K#AA?VFfNKwhBLi<k!YZj4_9Pk5OmKFxOE1R=`vi>{=c#AVR6{V`w(^
z@{??qNU0A%KKIVU2C$>hUj(z33vQ*!|5VD{!1mPGEp92dayS$^yH_^9_C@NslLg!I
zo<qUzT<Qs1n8T*ZdwlZCc~)yhucJk7gC#|#Alz`n+V%l+&K{8s()x7KtP*dMHgjJB
zl6wdN`qF)RHzXz?#2NCF;bUU<cQZh9H6(G3N4X`F>TG8kn@4Q7$BEw^4Bm+W^~g^|
zd5MREZ+|6Re}z<jqcGr*H02Ss<q>AdB?Y2aIOH*@RdNk!Sf%g^YG{Q50MUxaR^DNn
z+Q)rFCCt7o#LCd$mgWkBx@UDFFh?LBhu-l`sQysHI;k{Ct4+~=-lydgj){ZEbB7`@
zuJX;fmYpIV@5uo5-b>P;k;toCO_%s~Z_8BaA>SHwCEl8Jog=tG(IwoX@6dM_aCUr6
zF+Dc1mS<6@B+9va8A1t=Ak2Xj3%n1;jX#7cX3sH)f37F8IXJzGIh`oKy~CZEyYH3}
z1g7QL@x*t5L1<4Ny*eZki71H(NQTGVyTDcMm*;g^+!?ku06yuCq^z+6knmSW?NNLK
zH?fM8iKXrEq32Yk>JgxKamWbKN=3%b-2!Exy>AHiEr0(TS713iTq^$M3HkptuKy3F
zp#4v#p#9${VgDB~>FobMZ#(6gX?e<NNmU6+*~zI%n(?XGL#5~GS!GB$S_K9cMTWX2
zriMBuCMA1UICw<{CI*&cDvF6&DOozo7Fl{JnQ_Tw*_rVpDynJf@hREnW8i<X6L9@I
zqo&m*!I{4^!T!s=n13G)T`a7PX&p_BOf2l3|7jYmvD3DLgowenT~cVEE&cm_q^(k_
zbm5-W=o;K2;52<|1ieL)&(G6WSF!6K2Q%6XX)ZEI;U19c1a&Hql{c6eGWP+|*+&mS
z&BSaWdzYn)uI43s4`%`u;|!E*Ec&z6LVsg&yyCvh(^0xu46+RGCTj+3E0E<l{natN
zE=9Y-Gq9MjeGq;(EmB_5iA(8ukSk&04e9H_;g8MTv)6>z1iTQgX;fM_sg;~tlPW)Z
zob|8V_-g$x{yZ)7>Ey&u&LdDT7x7W{USQcbkbnIS{`m$1gny+yBWsI)xqaXt!{f%D
zQh5H3R|W$DV*Ibe1r7hvB5vd?Y-eL*U~4R6VQV66XX|S6f1AaVRdnr;1yOlHU?Qno
z!fdK{=Matyoj3W?g(M*7&4ntE7KTPmuvTsKQ(=V*{RVam=vn562=-!`b~NJ@QktF&
zPIoxHZrhzscDDKb{Jy~L!$?4&uFlq25&L6);LRq#2zhYgdEkNJi2~e*f9q(Pgq=K;
z!fI{b+5?sWm-mSVwbP=LmTpjz?B1IfIa&j%f1t|7XK(!Tm+nH0xCSnq+b!I58&~ip
z4AvWNUOZD)6^&hXxle^06;0RLrhYen=iZ)?i6pC4>X5Q+<CDOSwvVK{*rw}FI!(2r
z7HCW|uXR3SwVH4e03;$waTgj|!UAg~7p&-(d1=O?UuYTk0u8M6`lkAKAsA7+&ytd{
zswhJ)IRjcKEQ}fSeCj=Zb@Z^$)sNa&o^$1ph6dJL>07WBOh7mjP*oq+MOb2X2+5Se
zh%FL8XZE_P5;Us+w)wRzInZYVm~vT77J>RBnZ_Y;fDexq!JdW)Sn47JT$74~Oiqa`
z2Qyze$jfC4!Q~@;9B~N>yE?7T`oAw2_D?Z%>2Nf?c_a`vG7F2keUYh9;WjTlS!upg
z{}d29+eIRhp3Y~L?8Md-V^eDb`XeZZ>Si7dp^r`7L^k?ELp0)QTUsK6rf{ZOF{j{<
zm>Nmv8%%sGMpzE26p49=l0)#?4&?pqA~dzJpa)ddqAy9A3g)RC6{TJFPF-K8ynJwh
zvb%q1QsqoM6bBpmDds4D#t47OEBTRCFwbzKfF~fQK6O}4zxAJ8w*C={OutNGOa6x7
z8PI=e()~v${!<7l7&topRjmJ6mko&${Kst=qTlAtS}?B19bs0&vkIu7qWvgCu4S|q
zz>>f1>3IA@k(G5i?D-z~2~2k`Kiz@H5JMq_MS{<)ZCmzis?+MmWH+UBZ>*-tE$}v7
zNNyAU>QNyq^~;OC?d2pQ)8OLz<gzLnv`C@lgHw-WB!MtDt;XqO=NLSq^LQai-SETW
z{Q{DrZwbi@P7rUiGq7FYC~t5~uiW?O54hj7>E8dAc1l7}cx8Xn?gbnOi06OuS!FGp
zoGfh3<n8~V%mp3Il${NnP5!ekovbUrsE<1OJ<HZneQBIW*u#X8)J<p<=I>7yNY5z8
z(yt$=j!>1(x~;r`zDwVAKZ5f~s3%cCazB8u7s`}VO6!CpJ(5Cp%_%?omc82azm4$n
zg3-_zk5q>g!xC9Ymn*4|(^AYtDW^pkafVsJhc{f{q(vA<8J^Y>bL}_hui;WVxq_Yr
zAh-3H+Yis+2X)pPDu*kksY~>>7^4p|R4W}6DRG2eKFMMPQYa@Ph+tpP2ZdS)1Z)$D
z8cbCwas@5gdek>pu1mc)ixT%6ng^$4ZE=(k;7M*^f)?;Rj5%V6D)=5+bm1zru5v`h
z<*7(j5A9lA7OYqO#1$KkQ$Nt?GjvoUacX33C);TO46T(+y(IKl2`T1+)-D3h{?DtQ
z!K5p+4wzK)OuNf+?QRH**n}qGWQm;xLd|AQnTk4QK!cAxfSv8qBU-Vu>8P$`OtP56
zfjnCcujd%w*|<n1&mmK-XW>CYr3bcJ!C@#k7|g}GFdXce{Vo7$l(=Bk+t+iLK}9M$
z^VIW>06^x&l|csIh{Lzg2;kHvT)}>)tDI_J+Q3U6b<u2CTLP0xv^|Yw@$NrNq;8=h
z7xWX1h?9s5i};$)g2<EX;R-0<d!KyZPZ3}Y*BGB{)(untHopOZL(;6Uhf^*dR6apN
zY}FzPY_1rn;t0k?q=(fV`bf#o`hWs1CXkuq(!pFBct$uv9*Z#jJHQ?fB&3`x>DH!A
z9-r<Shs}N*h@3RJ2yq;P0pH&a9BPC#%`vJ)n4kR^(@x+p8h5b`H4mMKS3ogl_N!Gs
z`Q{47@TxL&(OZ}x6<F4Q*nf*?vTnByr0%oDSdU$GZL4ll@37bzEKyHXbCy}06$DGf
zoP*RH=?#V20Q3PvZ9sH^`ALN88R1_upsPxj=^w7oL4P+M-v3Dk{72|3J3IbOgTL?E
z8#w;oyI`_aX5~=?QNK((Obl%D9}4xG1GVxMj425vq{52Aq3V%PV8eGxu1jDwUB_=y
zUTgctGa<b0fy2p08vT;)r(LUstSmX4cQRjkJZ?AbcAiFO>34xp@2C0@Pv9^u=j-!~
z=KTSr&1qaIsu|XbqY*KxfB@R_G5t)Ulw5xOxe42CL(FoCQO{+b8m%21#b!z-EeERs
zKExcAKNMwPp$ldbx7nZzF3%wHT+t0)-o!jeZTP~5s}3}^)-b!Rkgb{y-GKEwk?oeL
z3|iR%e3;UjjBfNCJCF9AWGPrr+AYP!cJE_}Ea*jaxj}0Z>FxM8U9LmGazum=MqZ*G
z5z>e7Dh%Z4&gV{*j#ZO7Z-b>^Id=i}{mZ1fmk4JvQSmA!V#?*8x8a12;H_^UEWoqL
zAd;YRc*Ae{ifMt369UrKj*ztyrIDV^C(9L>a$DBzWm`!+DZ&6_VEOtQqo93{Uoj^8
z+MO|WoIS8d<;%SIi#~`IhlQYIai$Wwr_*%~gBBf1RkY}X?)1%=_|Lsi8JL@n*!>2t
z0CQ~9_w0TqUZEhd19V<ZI2|bIPJ@kfV+$?BUu~e@GVr62)gV-3$`bLp<{<VshYC)j
z4<e!bL}Cv5rS<`7&p$ezk+iJ6?r*m{Qh0+H^Rr22wAY=EbBJo1dxX3u>5%9VJ@b|=
zymP;V`@|WiM&phT(~eQb9wkxVP}Mxhem1SxVk0T-{45bl;BFJfCwHtI+oPMGBo6gD
zvM9$R&WR4|Es}|{cFe!Sdnf*+V_3U*`^{{lU#givAs0HGkd&#$z{;w)FWbPAkoY@=
zc^ljrdZb)G=7Et1{=P8{#s=TWm>HEo=ttoZFJa^o;kNz{`M5W*e~tAs61WHPzf39(
z{Qrcke~R_LE4z!0iLJA!yOD|gKNVr)r=>s`QA6b4nG2g+v}~v^25y>EAy$(E!vY!F
z>Wcq3W0%CIi!d=?ShZ8N-Tm;UV3d?bqYc#DI?CDlvyJlbb^i{&2Rn@ny~bp)DY`8h
z)W>-mSjrptp6@45P>!L9<oT)MfaDqr01c7mGzC@7g>lUsCMf}TMzttDne-PEu4o%S
zH6+Tu3*H+_rFs$)9YuN!4D(85iYdp$84H1KObdUy;M7N;Of8V!8=;XjH!ttiL2OEO
z|5E}>CdHTjwqnnir&%ERyBH0$xMxbGucrNe^L=uy{6~^vu#r$m-easf(v|OY@1)3t
zQA?W$jK?R8>9N2RD4uTiZ|9uF&cz!ULA|Tbh#1mJHkV^~wcq88l?(3~#T*nyy3DYZ
zOlI3>SRUP-*E9F1?YVWl+f8-`5RDCBQ`v)4<q>dJ4vVg<eE-H9{21onqYywqp(y{u
z6-e6F&dv5emZAT6<)1d;Z4E1T)MGT?UgJbfG7vxrP=H!#Mx3z|!jH(gCZd8OfB=q6
zRMUomn+!NR^Je-w=+&^4_Vu>j9GjX~J>-UGfE2P&*OFdc!S9s<`R`|scOIYj-P~$k
zGgH^b%<Z~x{y(RgkJ-0dJx+gSZic^e{C)^<?<CiQxz*&65*4BtA<JM9X+%jrJb36?
z>*4C@l*mhBA{Yq`AYrZUmBE6!F+PPb^k@Xo?@!7&x5^y!4s3e;^j015^yZE7GO-@?
zVd@F6dl+vu_Qu&Y7`O%8^Nwu&3b;Ll==x9?h<$zKAmArF#Kcd!Gs1GI8+e8CBlqy2
zh{}C<F~Ex5Gn4uA2>k*4BK=BQ>7g=E`!fqsp{mGA<HX+z=OipRF?c;SB;Tgi;=)y4
z$O(5F$^5$UDt-k?JCgiqMPtDHx_)GYg?Yy;?cI0U)wz=_(=Sw@y;gAVVzTa?M?@DX
zQyg9YUS+5eGrV}pfmJ=#KBCPB1ss!TPHAg}#*@uON4n@WCD|vm*`b>C7(0B0Z_we~
zdf1=Q(9(8-te+Jo#_j!2uxU&a_{)u<!%f-#Qj_l2Ne`Gz_aXyatMs0bkHdqBSbp1S
zB)6x>j5Q`I<Zlg!hZQuLg<NdzqD_b<VW<I-_o}oM%q8ofmmf?+JIESti59YHJ*u4Z
zTY6jm164=b>r9>3@k?p89l)IzkAur~TPjdiSRV1-4#1UbFB#X*m*P4~v~y~`)_9d-
z&Tg?MQ`&l3yY`iCSO+p>&d*ZmsSUuSV$ppYRb5vuF4|7CGgZ)&c+1y5f>>0N^iAhB
zdJV^-d}D}Eu`mLAyWa@snpqv&()$S{HeF4R3;mPmdR!js6F&M-h7|fBY7;T%?3h_6
zmk;Jz9Olr^dFuUeZSnc!pes|M4Vx{^g<EE?XRFYz`QrU**6Q|nt`uwGv6N>*t$~8D
zP%Lz|%3O)A1mWj`udSe?(@<RMpK8@B%Umv&TMKy0O*+fVH%qG1DvMaVLZ1$Nhc9?s
zRik4KyL*ysx0GP=hgbpG+a(pTq}zp9Y%W4hOGP%(I1aouI|l2P)=0~=$a2&iLAz9K
zVC>ZH=)%x5h7toweJurayH*_VCds*+&c}IvDriHE(~Ccwci#yCRB8R3P>s+tMsod5
z?qUOv(0YB5(7vPnXB(MPZQ#q6VjYEYXDvO(Z}j^w$X|JTu~$L-`$93dpAU+6Or4*z
z?xOvoT~u|xM8h>n@nM&2zt=ztJ1X{AKSEMh!PttHv0|`S6I<{}a)*{pi9JDTCES(!
zwP`+VK2!&GL6;1ZEB26gklLO>o-G4nNLylXOP0axrzbB2fn_Hx2%kzY=zRh@4!W7l
zS(Y{|XiKdz7t0py=<mevuCz5=o~+T_Ju9HQ?Pz%NGf8gBN-I<KQn#=Gb6Pw-{@m37
zy=+KcvF-3+)_9NDv-%WRGj@zO6O_T;(!PFD4wCPCy$TTOCJh<4tc>RwHp_Kh>6K(G
zAZT~T{o)5bJZzY8i}TW_7T_5AucqT@ut?rMm7W*}jPtE77I3B*LpIE)rucWjN4~2O
zS=l*XGTK%hQWWBo`7wi8G<v)@jmdD?$=#MPc;=3ojgPRelEc`+{o8&?gmpWgxuEf9
zoN1<>?g^8bVPg1;TFlEcDJ*FK=Ah-aJku6Y=Iv-uYl_STS+TEEf4_aaX@}8|&jK_~
zc>>pJ=SEHCK2%4Y1UD%Bg)uDl4K*rGWBcKnnfq`5nH}x)AVPF)g2oZ%`r7U+@r81B
z$YkFH*9G|<M-lfTLW%+9keA~Afj<k@`#u&od2hF#fzoxI4GE!Wv5moI7+h~Zukl4F
z4g5>Y4^gEG48e=%IfDUa3Tz<{=8LFB=8vcY^A~fdY9f_T)VcRRcSJ6e<IIP6erWPU
zP~Bs)MI^RKWeHWg<3=AqJt4`GPiXKx8xrgZTDyfq)E^h)54D8ygjLg%Ts|KvW8sj-
z_V9B>M}*c{z)#p4o1A%6VbewDgs|Adt54-U43Ah;$q|S@#6r>8WesN_!^Y<|mom4m
zjo~B83nI%W{w}T8%o0p>NAEtUatm_ld7grMzqf#mvjK*%chWyZ)RaGDvy_x}$5u@&
zGxcfIAZG|qcGBRVn%TDJQvXfW)1zPUs4(o5!!?Y7T86?y3NFRPQ=Di1DwQ)eMrqdN
zP8rFcwckr>Q{?WCD=CL=ay2HoWTJWIRo#)ds&@B<%l59t{`<|EpkUqwo8Z}hHbkz-
z&ewzsSRE~<k7gUiE7SBINlja{Z#mGk*6JN6vsBUP;?wWV(2_ncC@;ZjjVF{#YV=)V
zkfnge20J>QjKEYVutczn_N&JQ-9{6dtq85@<xw`Q=5XoH_fLf!gaH>+@Guw+61|eD
zZi#w7wARQ~1|q#thkJ0c;Y@dpu8_n78y)1-yBv3jZ=_o#ny(wquE;IFEJxS0h62<V
zeH7ba!GuqIuzhAdz;_VU@M!#FP@nTW=BwrwxFS@AI4xwoY{O4@!>0Q3b}kiNHV_9>
z!8C&Vrkne7Ce89a#O2nzJPic{=mWtJ%DEtDW&2Qd1K4Q&rAr7v={^JB1*s-y%RXjJ
zNL1|N3kuN}&K0JK50q^wJ=LIw{BCW)w*@y~ROsRR-&8uT6?*;jUuN6<tJ2y3=NjeT
z)k(6djr^hls;}+pydoE-o$?)+2rQ1Bi9aDMQkEe)217d0y%E+l&AHZs>rn1K!hYnh
zJ_*Cut61WkO*W@GseNIuS>995+4h&NCchfrPjH34m?)ML<EIC8gcDMlF~oWbBdAGa
zJt>X&_=7*FdXgH4cP>z(P&mkX%+5BLDf>1|KONtE!0U|(E?|Ao1{d5iqd~Ucs_@c^
zu*%k0r?*ydgKmY3&wN;Q08=~lW@~EWwzyU?C+qM*N-Z?ol<66l7r`18YjV2P+#C7j
zm8^>jP@8jA!uThNCv6?f9*Koxgv%dzVDE9AA%u4{BP0(d2TeZheGEvqbAj{=x;Wr3
z*k!mD<QbNhYP!{)F$T+#0nvoY?QDlT{qcH_5!u+j(EFPME){blv|vyw@UPDGn$)Ns
z%Vf8}#%DFyF4B(~JcY^Mc+KZnCGWMcIQN<xKP}rW*|RfxjP6>-T!V8@m!O%>)bGHx
zkz26TZr6|nQ#LcHacuTJl#zF+DE9GOj;Dnft%m_L7BzY;I@^wLvmEo>MzO<$s8M^o
zgYG&j9JWdM_P6bAuJw72u)>PPh3K(%FjTs_FM)(CWuNWd+BhmMI|;2@r1}P!wy|~@
z&L#eIf<b~7v#JGG^Kj}@;?cv+^U$X?%8B$w0X=rzEId9>E~rFzDTUiW*D6{THE~&d
zp?5)`KZ2fa4y0T|h!T>4{0(?Oa|Ngr&pxup5}InJvWOgh+{18-Kah9O5na!?maPoK
z6utI%*^2N4d2d9lM1o>4Qp{z8_Q!VMGK4C&KS9QRCRXi1Np3xI<`_nKm!26O{tQpI
z;o5Gzb0!!U>XMM3)hRGb$zi4_jaSD-@UPalkU`{pES5|NhJD2h8M11EHki?Ho@w}z
zCz|$i0Cyc_?9Z#k)axY;{v4N}hm101L()1%6LBJOv=o1X;=5qE#_-v%f6b61!)5aQ
zzZqitm!tXrCmEt@YxUnybhqlH(qA3V%RBzlfJp!n@jfJsVjK~2Kc6^^xVTsqRV$=H
zfAy#G;h8ZYLni6h-7g&pv{)((U;ppDk=21{9QKa7F5Yx#Bq36V{ga)W&6lhmpPT8U
z&)e2ppd$xuLD)lRE{1u*$}EP&furI6q(F-)5eL=?D_F<%!yNo!T;UHSx5<u9GGN#X
zkj<5ClgQLb&vXOBVTb6f{fC0$Q|Od*ZC5E$TMTs>?b-vei@ir!q8n`3@no|PuvyJ5
zHb<)*s||3xVVF=2z<%KrpL~5xE@3>_B3rj8IImAuJ*S}8u-OXMz@%J!#3edqW%5GF
z4c|#-3Z32&YFqP+uJToo{+gF%f&_^C)oIJ)f^XY#ddz2P7HyI}a$3%=$=QyNo}Od0
zlw>Qf5_|S~UY(IL;IjH+b0;Criz(ZpRX)OqU}481&vrA4QSXq%abl;znbD9Pv+wSL
zpQX;jb;quuiI-AFFOAZm1WQco$KvElR)qH4ZF<3Hxe+JIK{S=;Jo!{tgzZn2C&F?e
z!PE!?Sh4!N12Xi&wqb^s*~NZ_Wz<cerA5LN8*$_JeKw2;1D0(|W<Unq4`Fh8^jljm
zx?iViA<v)DBh5dS>!}$<2nOKaH2`s_aQUiAO=B-hqz_0E1wJhGpH0;BbTU1^j3DBg
z>Uo2kuJ8voUh$9cxZ>i7GXrIqzmS;zfQI;pvHuC=dqyiglc_}32QmZlBc(I`lG34k
zqgIp&D=>4QYvYpEGnU+6ZT2E29_V@Nvi!}mXTlNN50nlQ*U%C>mPxXA>!RNd-Xk!f
z((iOsoY=?jZC{b0;1wSg`4yRldFyW)?>K}8Ws|zJA!<&b==eZXNUX6YKeS%kk$|kK
zb|FDe2cd&gM0g&V#+HJ|546dtv<yMOuRL9@iZ+-maEd7gl5HgMhbvNb<TfgpF_$({
z?qLu$+z8!L<HKm?fJN0KoCn#^+SGx!>f_%OD6!|bRst9hP&(XyxmV)fvPb@(iUHYb
z+D?mVh+j#Vll7v=utWR!g#Jb-Tj;<^MGBCu0uug3lEQhS^{V13@j99(3xB#lVY;5G
zkBbqSln08YoZp9p&ECo1g*SY~)r{90q)QURXL6Qvw(Z<{c^?S;zTa{DQ}1nXxfw`}
zxMJ93T=cnj&iY_YL!L_9r%3HV9-+2|Xz$&nM>e6h08~bTVtg?(7v+I*EJWQTMFs9O
zBYC6t;uO2l{fHH$4lAe#(qfV$UdYCkM`tOTDRZp8;@y=eR57+kB`jtdLZeA~EUKl3
zR>;pQy?EueaLY6&CAiw`k%QzOLW<XhCX&qA=Mbd$8;Et-tV@pRWSQ75Bv=kiigObl
z+HU<45`b-G%{i%-6!nntD$C3zsjy4ao(6&JH3@de4s-3~g{m7GDUL13jfTkff@*YF
z+En(Zt+M8(qKpuS?Ip79F<az$r0u2bL}aCNpeRQ1#$_;J9Q?F+M671$3<@lHIh7Q2
z7B8(Xl)maN%c-&!y5}4wOAm|Y^H1L&Itn$)qYYTB2Q(K~134H*RkiuC(n9h+_APxN
zb2PE&cvCg&YD+|VOIhQpz%~*H!4yrkimSxdhKjVg&ut_I6nMlleOeceJkD})R<h!M
z7Oj|+fjQD0$shS~e%_QUdta90G&egA>zir|+0Cjr7v@2MJ1@9pHx{1P)w1TxAg@>q
z*4=>Bx0FI~;A?-Xt3yiAV`=sM?BO!d5*#pPZ@n9$T>4cuy{6DMXqC}m+z~(%C@;SF
zJ(wyzL|JKg+Wgp&=OsUO5qDRyM`*p!guY*(rDu!^#$7KhrWp{_4gDM@E@n;zeRGf#
z^#>YXU#9=htALQ3k-V{Y*&d1a6#R-#?4?Ny_j17|^s_;4p!{8VAc)XAY;NQ=#uMW&
zE1_L|0{Uic=mkvu{ZlJ9JeOaFD*fuOTK(+AuDg*`s-fPF`!OkQI!aSj2d=-SG`PG7
z(sMdJV|bx|fgu}qxLMTCxpX7wn2y(_<YGT~33bkvAuZ}&gcd`Ghpw(F`eQB!<{5EW
zQ$ymZN|R0(_3JNMSn%2^3NuFr_E+_%1z(@fe>cQ%s;QC^qeJ5o!8^rO7p52>Cgv5v
zOs=F<bz-|dK6VD}zEdOwn&=m{SrzukB2MqVJmzNEAA{^n)HumP)4jWD`i_tyd&E5u
zS^A1|6YJ2M<Oogh2ybpFH}MPpd}LnX6>KVrZ=?>BY;&{+!$Zb5#0hB|dJGSrq7Q?u
z5wIA%D)jq$58v5{KXgJc^u8(jM(vo3#6M}s)BuDZ^As~`b%{j6(gNc5Zqq+`(oZtg
z?bBYvpv4(L+ZN<-Ngs@o&}vkt9r$b2DYNrZE!8-0f~UEDT-RI0IYm+={n^S>CBN(f
zQY9x@>INj{BwFc!L2@RdCA(jpqPZ=D@MJmY{#Kdxu4-6K$5zWff2q%L9PFAYg>;I-
zHdu^b4;!+~YZ1s3=E;H4zqtdJ<k(&se>atb?|jYR<P1`r9naMp*kE>UIM+R_(tB~D
z(5$C38l+i0aw=+^TzkbkSik8pvCfz#V~=zjpg4yf$Dd{Ujo2OC(p@vo)UpJWLrB`M
zHnKKEcjLJps!KEH>uMN>g>R5ki*%y-r8~l@L+){6AKxoP4>nQj0X1wN>3XUIoHYtY
z->lrP=NekU+^;9sa#oy1wSPtYrsd)~K<&!z6y+$_6N>8*Eb%86P9zh0sdKaTrTD~m
zt(8FQHQnao)ba5sA^+$keQO$h9Pchc`i~6ugTQ$D7)p`QjO}7Nb|1+f_Yog_uu}SU
z4j-+=bC4PqJl*#Dx*bPn@+~jp1*ZZJG)XA(uC|s3OJqY+uuY1UnlibXK4f}=#N~Qm
zRjIc%rJZ4I9JBoK_e1aG1y=QrFZzF7)w8U1W=nqn0hRpM&fEV^HT)MCN><YSN9QeX
zqh_P4tZY-pfm;-%7^N-hub;%`0;qw|@jS0=l7Q<mQ#Dg^((l6FBKZ)$SCIF@2sgGL
zNH7+z_%qp^r#X|nZeJgtpRjv~zr2m>&IgA}LK8x509WNI3t5cD6<#*rtw=AR!abD9
zZCFp-Lc5Q0BI(1XTgQr-Ru;F1MOHoI!3O)!<6|1z4%v{~Oj~ocTg^&B?8G@g11UzQ
zH9`f;Jm`@H*%JgwZeH3i*7*uMCb;9d2ED5&mQKWAr`zFqldw*9p2}5U$fSGGejABu
z1@$NZ_6s(=k9Iu}9nipO3yYyIm8oY!2XyX_RFkK?C2$mvm48Ov)eQmxwl9pY2RpWd
znX4F8zCvZAweAJnhKrk|DSHla*Pxuz1XqMZ_RZf_8Bq0fJFa;m=-}R5uv0N762%QD
zWQp5JJqPHnQbUZ)h}C&Jz=Dk#O`rYx-y{Qq){~5Vz5@_YPsKoAUm@F?*l3E{!sIFG
z3^<1irZH%oOlW+C&Z36bdxs-Q1|)c*)#_7Hs!KoMED<J5&a4e)e#ev3Ao`Mt7(D-5
zsbAaOHZAEd438rHKezP%{UaOyQwaPYpQ&{}9CfrWvCXjsk$Tn9m~ArEMUE5`PQcGO
z_wvX?GFjYBN(V`MEoc-gV);0;r1`OMZ7J#exsc*wu#6NR=E#5|7AP|Q6!zEq863N=
zJ9We!Zf0!hl{Q9t=F=U{7w%JUv-So4uRo*wAg>HN@_8r#Smpr4DD)%66bH(Hvd+4p
zLgGQWyy5L~vijgjNuB-%cOH^MO{`q$JTx)j&3hf>+))#(S@L_}9>mc|rk=FDdV12i
zm{enL&H!6X2XE1?UonSh_r9v;U1V~;tl_o$4H~|>K;FV5mkwR=0th|nLz(W<XWr60
zJ+%0C<F7Hn*QV<$vW1Su9xE-*g=5*}krxSE8qL2K_L{Wt<L8(vG2oVKv@(JdqkoBS
zn@F-o1kv@4C0U?BM5bs_SOh(i`rJ7zSD1%DIXNh@LMwOVXFJlwL?LmiwlqbUuHC2=
z&%aigDj)ZcWCI1k#}(6NNNe>&NLi>`OXIahEQ=mE6*j}0N!3E0b>p<K^~XeC0BmC=
z&!$!=v+7u-d4Da4z0XL5$)thFy3gL3Rz#k%UP9f=3VBXssY{!wNMl&pH4YzVkp&AS
z%0dzO)CNCu-QpUxSlnkSxxPAsB*$%2ZAT40&0MX!lSyzJ(w`**ZIgLlOqfPLKNA9e
zI<qX)>C`AXa0vK4-Q0vXMS+?aNt=m|9JFXszdl?4Qb10UR$W{fi5@5_hbah3ByeU@
zyN@$bFN3_PbZxhkKC|SqFRDm|&XB0CQja-T3(;EOj9<^Y1EzL%p6m$tYN07h*5bV$
zW3zgi&s+gpu54elEsZC{$6-&gBJXT)0pm7Ek=p1QY~|?gHbyUPBCS4pF%z$A2-evP
zl?5h%Y{9~PZ-*24ySIBnG^4TpIRmsO)TqjT8n3T5wMznRE(!Gu@)V|2Y>+)Q>J&=f
zyr5sKLi%wDyxbgr`vq6F2{)V8mRhWU<}I!cRcSV#G#ho8-^Gx<ehyfGh2FD4>5`wf
zX=(0-6zBu}$>g)Yqwcappx_7wLB7%a=CakiXdu++7r#@)Qb+3wax?K(?|-@T0pssO
zAT_=@VP|e(RYU!N<WIRrVH*;=G5JvGpS^Q}g6MYO$T}}SVvfd$?_71)4(|r<Q$D3{
zh(nv&OA18$2vnaXQx0+y<tyAveMJius|}=-p-uyO`(#x!`4H<TXDr=oeZ>>^*pAXK
zMO{{!t}IkPVT}#Vu8~jQ$&s=fVYrqN?Cd*(`6D_)H`Z3N$EAkW6<YegT6+tyI+As3
z7<YGfm%zr|T|;n9aCdiim*5^GxVr{-cXyW%90GiqJNN#a;mn*n_ng0Z_S3sz*IG??
zbye-R-dYRoCqc>R4jX`yI33+F)+$pWy}Q}Du1X0fwcu<>n*H2P&F*0&MiVll3?Gm#
zy3ObuN+#l$aXg+`4<URu9$^WO3vaGM9?3ENXj6~f>Pk7`zW_e1p%e;0o2ZxfVjOrF
z%}pFmRZt`Ji1fF(EFtH!#;Gq3KX3-?A%e0%OwEI9r8-!^bfBUdQQBVEc9o;sbje}V
zp;54rCPe(MYDVcTA|8W*j|lCr75JUFeDUD<foMLMt@O7y#ANq;5yV5?J}f?r24}5t
zE#TD7xH(OlQ0oE#dI@?b5Ic?lxvD_DEr_@$^Y>&j`}38uUCQZsF>&8jEwY*-RgP-m
z#UZRn+JfB4;KW;UGj+ryqVyhZ=x+H)w5!SoaGU~cop#4MRL)wRGsXe{UHiaP9!|_V
z_&>|m1&iYON1d5=+ySAFjN#gqRk#dWUabLeIuw#$cx=;w7bP}zBZz|vC&R_R1D^Yn
z$+tM7kgVhGP+bz72)g<+Du@MvqqeX%B%+Z;yP$_)*3ZWB<hLZH((ydvggpFI0_41#
zNpC0}#scjlq}u~CYV47TDewU_J&i~&KIP^J5l~aSOWPc0sYkafP@%SaM$j*t+<mu)
z%Lfz<w{qfrTF=3xe!Rhp!a_fiBhTC*Lp>ha(-s`rver&pn{ypYzAp@AbnIJiJ)85b
zK4uIZ2;*^*9f&5PCmEOF8%%VQd8Ru$rK8E&8K<&R@L+%$S3yQAhE-3A;W3eRDQ1mK
z=c&bD?+;GP2!$N<Ux1my&Lh*+j@^M}<@X4lAba?6lL%TiJ*N$%qn|K6Knkf{o62y&
zbY+O+^>eL&wxe2(++uB#r9T2KxG<iO>B_Hx-$?T8?jFgugM)g4Ei29wuht=$W(`&`
z6SRhz7&!jA3Ed@LFkBM3Ukj~1R0Wfr<X5y^sU?pg*QOyr`{x=md#&EwpIvP#mfk)z
zqjP87m_EUg>p1EBM9&Qfj4~1CYGD`I*C@R7?jBn{NRd7d=a^k#fVshNdx`s4u~dty
z>nmHJ&@MoUiATx&?o)>FJAUf=Qj<2M-OJ?LWE_WN(A-=}wtA7Ga`Ie)Y+O-a`AD%<
zDuV0kuTV&0v4+=L>oJ{7(vKgsLD1I)!A1K88G%-XSz5u)tTqhA613M+Ogvctm1ovN
z&>Ax7G=)=fS@a}#PEOp@5_Wme{rhMd_)<NK;diCRkMQF+@4YRZ9<JldN(h^oDuc8_
zmZ=pQw621Cz@GNq4y*vY-Ng5FtFBQEotNp440mUzTU4G4)CFMf9V#-y?Zd)RUr2<>
zA?+``|JbjG3$j{x{2J83{u<PA{Yk%WXKiMv@9^s4{MQMS8FA9`T>@x<<KSQ-9{lgS
zb5A<Ka8Mn$Nfjb!bIGu7g}D;}mcekK&@WP|6z_flKT~a^6$2JTw&~6e(>d3#oC>VZ
z87hEosx$>Ka9u6-sy>TT2cP0OK`o*p!+45GsG2(m$S5|aSFWHCcMw2mms_dNvyW*=
zbB%Q9ONm@Aj2vWQAw_9?aIG&)KDJ-J2wYY9;mf@wkwr^?mrd>O6KGXyt{6nBZ|5kZ
zc711T;xRoh6ci9?R(9PfHgcnWu!vtKa*%Q`7JWcIFLSp-o`5<B5ruLQ6&Qs_6Z|ps
z>uwwW^;`%S6-h9U?^1xCx72Lp4KyZxdD%jk!w;il9UAG|##wxr^|}IhHRZMMI4W)U
z5nonJ83_R11Lp8u-@FkbZ8-choFO%;);W|IjnDXTu-{+l7L28(SSCb_o$~r;jtIkm
zE7qXe<HHtU6as$<NA-Xn253cZUTGZJLeP5(Pk%g+0!hsj9S%J(14&I0rG@@_?@U>A
z{U!y8$wIYW3IqrU3>*kZ?C%WJg>~%>C9UiYt?W%5Oq~q>JQpcn@%MySW)Hdzz1aFY
z_1>^VhL-#XJ)%e{Js~nPq3K&-h;*YxOQ)p1jxFzv-lWvKPaZeo*ynV(GO!S+!pZLY
zV@>;Gyv{fK71ry(EZ=!RLFJhw4#|Ca+Y;cF92(8Ctu~5$J%bFSIcYfbLO#<{!d=vJ
zC&1xq?+!RmOMZ0g&$U)0TX%%);zQ1ydZfZa<fF;j6x6({-oBf<P|hARWcZ%IY}FFa
zycybgjWrUrEm2_!yPlNrz4_Qp-~1#rhrZ0WjIK*AfO$rlA8I^F#}wW${u@>RcXOXk
zlRM2=pdqZW#c1s4u0*~t=b3u8R$<PgItX19Vo^;FP9&DvKFs6ea}gfc=x&J7eip(z
zRB_{nJl#$`0f~nCdojiF+$#owAP4zKd}NtAl(G(OM;xl<2hxw`O^>9xLsu(B>@n5}
z1Xj95EA4VjvENuxAx)Awz^GGNqzv^?H6bzqtv}ZRAN8`>dn)USNrP6e%>Wi+(R&N0
z5%}}*&3xTAVUT%{sXE!%VaErODE@rxL%E2I2<48s8Is)Lbnt|sN2=c$c5DnxWsivD
zx47>2@O<ERa<ZT$vB;yL@F~+OW*LyUm+m8a#$+BZ7X7Fzka+^h<Vm}k8Jn=HRrXVm
zOK$2FplEk(<9Xzq8Es)3kcZoHQ=M~Dt&zVF#+1!@5h)bDfXCH*#$*`t4M$O5>20eN
z!QkGxz>^5o6Zz>!7oG5_<TKR>Fl-kXGGE>$mXq*L(gdMLEcPxwjzJyas57rDI=iCv
zKi1a3{8~(76d<5Jn*S|W_<L>r{~YsNlxFL6XfHY9<3Y({f&6($5C`?+fP{R$Gl?iA
zfH6V^1-nSd#rY1(B&Pr=e9fJqxmGC2{p6`yRHh;-8KO{HcCKex;<?IaaejKern&5H
z?Y``0u6fvTlaewbgFtb!y?w&#UePwUbbN7M=e+jwt_f9yC0u@Q3gN-~{--D(;oyD+
z&J%sovmD{^PL3ki>8GipQ1xxR3<pzfF6@)J#crLHIhGsK^t67i{X?bBAh~-Uq3u{M
z^oy@NWBYzQ?{=7Xm^HRZG7!FF5k}9N@<dNBR7{f*oNqJl-h$oBpoK|tX?MqaYSEDz
z4;qI>$Xs8rm<&#PderwZJHRl8@1R6VI~MER*rwF({(v3`gSl6N@u%73R^+P@k*~9I
zBFO5t-%-rI(8|EDuj{*X&=|U8)ycMvlpA)*k*jN!2*EIK6)C*zg^_k_es6?v*@QEH
z<WR+^)o1UaMXACmZ<P3GQYgXskq`60gSaAQO%&&2y7;k6e)KV`Rm>R;a??`3xyZS+
z#|l-)yqQOloGR3|qZU!y^;VeA6$sA9y={ucd58=R*DqIW_bxSR`*s-(-_g0!T4(!5
zbD@7u=GOF<@ma+WIz{@+^ca*v1(%s<4@C5qVofJ2XIy+DTfvHk=(co>jgn(F>myZ&
zYyilXGwaWV*^I#S`(13v(WZq^uj^#ATX9b}N_Q`J$7<`k+tp!5s!#ScVmGiL2yXQj
zrW}8wvB5%MMxTY$2ZYocn}4x1gK;mijMP+cXDP4^Fs;Sm<j0Ea#cin<sz6{~0f87U
zos*au!kKSmHuPE2HkuiV3FjFY#_IHnbT9{GRGD2bp_ky)v&_sftXDTXoi6Pru`u4N
zS}{APDr;YS`buL~r`}Scl4fgyt~0<wqet6P$~~yBgyYz@2%Wmp_epah!dbMcdpD&f
z{3MH*c}2yLS*?)?#j?aKJe8ifq?i+}RO-aikkMjs=$#fwCb$t5+M+Vyie(+yNN*2r
zB`9m=Cc_9?y;_Ds$)Zxb4;mFB?ozdXEDdWdA5IUWS{6W7h`Km26Eh-3Qy7EpOdAaj
za$7oCi#-20dBrgnLz)e?4yT!`USqOO2ugvLbkxWs0~>zmyeFG`jUWI=kx$pU-dMy#
zQmP_AiiCmRJ!Wv4S~_{}vjv_-@05i?n74GQfX#q8!5#EB1Ph>yVP|&DL7yIiy`(&a
zG9QZS?#)o<gf3`rz$o?<&NPG}Vxvo$4J;GHnU3#77}>Te-FbGqPk<5XXxEa2Q2j6(
z0_Qi=fy&wtrANUz1{ru`D^%P0lr{il1DB<aDlDq24(HVzGdnK@b8$0weC+NHd~jY|
zf;y+glCG=$4*>`eUzAw15_rU&?b<lOh;$Gg)d&^hHqBt%5jl$$BNiCvW?>a9SwVX?
z3lF;o@@#T+IuIOxwH~I)vdJ+0Z=5Nl;X%P4-3mXA<pXNq<*o|d3+ii7k*$o;QPx8Y
zh^`JKYJ0;d;s*%O>wv7whR_FNf3no6K<MWdnYYZsFD#e_H51L~2W~6ex2;%(GsU{5
z;v_1^mN$ZBe+e28NEgOG;utWn^|HfaA!SYovdcs&^_`p5Ju^y8wG{0Co{?CWGaW<k
zuoN^6*lu(?o9K_<=DMwyKtitnN@nS)O@>yT`nf+tXbHHKhl8SL@KB=O?3j%ac||e4
zDuK4zuoE3Xt32S+;8a&1Cf^5-QY$kW(x^gB$TWTn927oepf8=_Ocvk0GE+EqphR<I
zWM6|GE}O<}PceNJmm`>s1}-pmmI6w<KRjd~RAcvkGR~k%Ky8QIYve;Q9Ts1=U~ix`
z^1-Q)kadKEXqrMdbW}8UPwodSEC<Y0%L&2e>1>7xONdoLXQoK`A3C$>=O<y^1&NEg
z;S(HI6Nrt&+1;(Egl_NoZh?>>*<5n4&HE{Ax3~|eV4Y1{mp821r?P_&0R>w*QT~D_
zv3)on4Zjnt(ZcbQW|gEA2lL$E9c!q2M)p0zwI^0gyL5cZ+C7GU##;wUAC98;x84B_
z@ehOX=O1SWD8o^+v>jonvu|U4{kq_CzcsoGvEBs<*Z#TV(|60CqW;$V+(0Je()#((
zVZEOXA=U>W0}tN$pYI6+S+X)rGf4;cn7W2mg^hkTlo)2=kX1<={xT^sv(cS<weU?H
z7p_i1i2245(R*;i{hrVN98;L5(;4e05x>FrZjXTthG||1{;p^<kDiSRs0Is2gdsM6
z!tDwQP!iM*a<BG`&5b&RVL$&ABlsF0+(x-j#}10Det0jxj?5KfkeTk~vP31DF<gqv
z6Y2DC@;?-@HH#v}My)uRSiEq2k*U}YlCEg|qr-r+HjUx=`s7Vl^e5z-<~O$0hZPG$
zzIme9o*h;lZbo$00G2lP?;!ji?_Hr%%3H5MK&Vx;=wRXah)p^Aup?Q$6b?FkNyy8@
zK$q%Mh|yZK@i|Hr13AnX+>d*i3;K=FAoY8Vpr9tEv{(E{h%D-q!Y~*@Q#wq)H<00)
z9gWy<pfIp$YJ`!Rn#-2LQ;MfrrmC$(^o2WvZ=d!u(-<k?IKZwJUkpQZbXA!BOf~4a
zmcb1ktl~gHaKvO6@3Lja3d+qmHNsjBg-8oeTi&cP3Q&W)psrS`F%;XSgeX1ri2TTY
z2d`itG+2=D&gQ72j0>{fhO5{XMxQn;1@9G)+^QH9L9T@`h974#u<s8pT+Oj6-DR`2
zdY|EIdQ;dT4i6b7e<=oVcCq0)7}RULPk*xchIYr2l)t&*x%Wl<{_qh01H)76VN`Ef
zlprGXjcuz<cIi0RS7mj6w+VW0|K>g89E>5}3T)JqI2e=djpj-Rn-qQ$(B@77^q(6n
z<#|^Q`CndG0!t29=I;BVQ%<|70)pD55Iiw6^YhRV=0L8M7;Oz9YmF=zPH8@JxS%zz
zSoPtQuG(H_`!`SGtMH2@C2*my-{TwIsx-BUZx1dTD1-{Dw+OCLIyt1|s9^|BX%ndd
z2FzYsWm(cEM^Cp_R@CO_)JSr}rBpZ)w@Aqjrt2%e>B7E@oGxEv7#Rp9W2v{zkKpy$
z3(VC7W56}2wd`tlM$(rd5mwl&rIr&(k<(5yQO<j4EV_m=(>hhHq_!0_Ux8@jxn>n;
z#QX6RNUp9*<0%s^8ucn%!+ot-Mpqm_VYv({wb5+V4y1;Q!GvZP>5_!pqaE5|OAPla
zXDb>Ra|+`v?34qARi0|H$s|o)%8e}_yB3VqOh$nJu|sUju75BhFJgjGO*SsYx*u4%
z^!@;K1M)CeU$`jP-!B5Mf$)=<5lOb?#AT_PJxj93>2U&O#61EVcERV?<uWV7%vjL)
z>jJfYQefzgyBYJa+zY{<T#u2x;pO;zH?)JDu!3$-aKOih4AiLUOzuPrJY_lMShYB(
z2C{g0-4UxjkDY$<`Q}FNxpPUi%1e%zjDl4(F0wA11JTMwXHPwS6!2;K#5PLMt?HR9
z3>YdJFzFpOw6b>CX(H2pjzT3*>Gk?4l#n|jqJkZC1<Xa*C^uZnOSlDhgiWZ|`lp5r
zNN?x6h%ty;o%dXc&UWCx*v6_p`4`hCxbrDIb2QOz-BL|#Ek&IteK!X*O?I28^Sh=-
z#Wf_=>ipm>!&(Wih)Oh}j?A+^<hz1POFt`w3_&Y_L@i~D7oU`)JI>dtoKAD2KF4aB
zU`-ubZDZNOx&Yc1lAzECItQsN`2y{biNe@t6o*9A)^b1`vLKE)odhs8&-n7yZg?nq
zdVm1uS}Ckd^{{~^QrRj@`5muNwB9q+L-lFJ#!L4VR#QOHG11jHD6TXAF8j5jpyFc9
z&e0d40v)a|Nn-Q2iVBMAKJKP6!mfmoy|ewN&bN~s1;QR5+`I~`C+=|M1J|d8jS03W
ze`a<;^RiqZ?cPr3QK)k@Z9=VwZ*CEA9V10T=C6ZpQS-9Y^&Q{dOt2uG0Dp53eSdhn
z!*G^UQ_{v}h)iV!Rkk<(^KQ3YsEqzwE^OsjC3-ID$!1>Y50%&Mt<=qf;zcKn=)TQ(
zGr`mqSs>q)dc)N~a&amwmd{VW4B?54U~TToN+>N&wm`43rsmF|Bs|hQ6v0FoVT>K+
zEDG_o1dqi!nMIDDALnoef1Nm&w!$o)0LIQ--Y6QQA3~2;<`=oFqWu}?Ir?>yS^Wq)
z(JgFuCFrTiV`pYq+=SX;P*Rm0;2ltan4g4nIAnN<6Xn5ElN-DTNtUTalNt2^Xg!i8
zifvM<$Aw;74s#MiLs~T^)O*>K)=`mJTbAAdRb8S=MMNE!SNik{1^lq3Hqr~C_?Ak9
z@B?H<E@N~yRCK;vrUZ9ma;}z?ZKk;PiUhYS>FJi`%xH!K`FVcH9nk5fxG4jF)Ox=O
zA;0|mMM-VedI9boXmhN$Jo_c#p~^GuY9HbBDQDa>$|J8trIkUq>Y@4Fnq>T;ts6+2
zc#H*8fgp2tX5c%v3<y)jgX1f*Lp<Rz{y_Am3A2*aYe6fkTve%x>FMn0Z2z{o;EX5W
zIX9FJ^LtJ=2wud`m)w;-0Lg1SXC}l+cd&=exy}wzD}3=px!sQnguIYxx0C=e1>UUK
zGPa&JpJ!+{fG?LlfCRhZa}#la1rU_QMl-Gyo)qXidT=es4D}s2JzEB~mHkdV!nh~$
zH1L+3rl2ZWKisz3?Dp22Es?rq<x}b(XibDdQW&mA^Ddx+E5(D~oG|w$9-at#&KW>F
zYeR~1x*$+-G-EsCdi@xE2{i0>W*!Ye0i57-6htYA^(kO2BO;pc45hw=bKT>(8|;(L
zs6SbuZ9ln-ij#SxmS}bUKzYD0Sy2+0-prz`>}Jh&NzwVXpeIm%H<HgmR%MUcR$Mt9
zJm3w#HZJKpMBplneIff$Z;3ol^BpwxhvrjlZBc8|7`VqAh)NPGF!-_CVQWwrTKmnU
zU2<;LSn%PyuePdG<}*OuC^sC`Z2^L<Y-zB8qcD{U5+M;CRD(NujOw8ya~AKKo>#z<
z9H*oOYTprkIQ8-=xbu|5nijwQ<P<=GC?k)><9VdeQBk?cQRavCwNhiDUCK4=R(A?!
z{!{1a`1P@;L#XtDF$vL5wn+kSxRVYvME)w-A$jd|7>}R)Y`>{x9poml^gI04Jmxxs
z47Hr-xsqL}yA<E9;T4AWit!*OGtH5_waB;{ND^npsP!MfCYH5an%b!4Azb6RzfJ16
z98m;pCKf6ZyO4uO3s7J}pNPXG3AHRrY|KKzqMG80rJf0;N+qr$mdO!aJ%a<^*au8L
zLM5#e2k;3^c*szy7d8Neu5Ws{rR`5R-)lV(%un7nMXqgXU%gwG;@?p{=>N&}6d>;>
zjk1Q2tH(k8Npv14ncTph_z~a++sZ1@k<l(}P0F)gXbRLq33%iVxVfDPo1M6(>ROd%
zH4sjKtcC~o!jb=AY6~~90MYou*A`yIy79G->}$NK?;7GkFx0)4SBjSizZlBhz4`+*
zi_N4(JLJ-unAOP%_(PEtvt%l#i6yUh;?(6nkh10+1EbNU3u*5*Z(ja8hT+hM{Unnd
zNbMPU)y@>7Hh0N;^BsDvn(ET%`T|S}7G8zq85atIf)${#pL^H9oF^K2`ykanp)%_r
zI`cnFsa*L|kl2&uVN6s26TBc~yAldqW>JB^z<yq~HsSQlZmj}a0()=uMEit$vnS3E
z{J=ru9qE|ocHUhNf;oJ^-$@F&5;&f5m|bz;?LQavfCyAAe%JsVV;O8{Fi$yj3`&{U
zSiCBF7K%7oE)eVP6e&(zLa7jb_gGX{R7oETl-ajEvnDO5#1Xf%9Cx`~vmgCIf^K?J
zc(WTiRf28Qiyi2(&r4&4EZ>;HaSjsgE^qrbFHDK1<+IM201EILEF2!gEDOjw|D?$S
zGtrZ9s=T+aC139Ffi)G$vz$AlGkt^|EHm#I2Vg;TeEX}U(4$ELmiR0n%^wcQWL(g@
z!p{lw#3SF&i5(#TnWlV|1HLdn`$+_5NuDhG3FA)Hj)ZbOSmyq`=TI$Bg@+Wwi9b`>
zShX-CoZx{_H>CGPy2DxRWa!;g2Ik8*1-r5DWG{qIlez#zVWyMo!kMzK8ly;&{Qgc?
z@6puG_=K$HnUz$qxaBU4sjg~^i6O!Q%ytHNuAWQDJVQz`BJf1D8!JNfFmqQUxi#6B
zXeZwZyQ44hn%w&J8&Bwz{cQBVX>x4FICaFz3UK0I8qaMbxD++v559q@WpB1W09qRN
zf2OEq_qW2IxWczS<A0Mk{SlFG>I(=E5H%za5cA&&tO^=A7~1`w24Vku+^X#Jf8|W~
zzck<;A3)$zg^a`c3BV@g<c0tgJfH?eP#r>B0nX<5v*oPLq8Frh+8)HAQn{goors1!
z4JBWyWBmZKZsVM{E9;#5Yxc`o9qms*@B6|a(5G>#lMg8+RRJZ$k*@F*7)lAsbWA%(
zUNwWfC0j0R-7dYD@HNDZyGur^jw6&>wHD@%>&Ah^_QMzH8*JS>4%Lq`pNZR!G{G1o
zx*wcsjKT|B_u>p2x8|EPce`TU3}hfR<-&=*_YFUV_gjPX-{v*%xz?*Wx|SHmn-N6d
zg=13?Q*0emAM3?;R4n2GV+t-0FfwVo_O9Da@9K1~Km}~Gsu;0hf6!tvu+xr*18v6?
z{@U2ZIFq=nV9Jz@!{#32-XrxcH=O=<J^IJ^{aW++QxV0jDulE9Y$6^5fn={T1Y;@w
zW^(-CZY6p`2KYS<vkaagw154kb$IhrXKWc@X_uKHe1tT()kAyu3t?&)dC;!N1M_*^
ze#fO-`r3l7B2%9uI{Oc`KG~oq{cED`6WjVM-HW?bL3R#TRqTRhxvR=c8uEL9$HDCJ
zOOEbV*<Hn<Q*S=*2>tQ19FfcCmgO5_LSGuGtKJcz`j^TR>bQsO0Y1`UAX7w1MU#<3
z3&b!h4?(jeC2;>M0+BG4xrzRxiR3_#MX}{Gsx2@iDU{&@&d^w>W|1#fA3hLrm%{Ck
zuY>^-5QK?`i(&vlHOSk@W!VQ*9^wy8Io@JYMhmxxK$X}a(w6fGl}Nz(4pC%*JC}`E
zIp<=m=5b~oqGIcXW_Cf)2I{nl#dE~wmUapld;}L~vC$D(laaiYtDxBJA%@9^HcX9Z
zR%r<ojMzpFoLZcsl;8&rax`#ovGb-l<9WM?6P@5V(k!{j`QF*SoF*M_ayi8(jZWfz
z)%kSrzgg%1aXs^YXMrf5%Keu8JdIeNP^UeVM3w5NyhLwEy+s+)hl5HAj0y+w0)MKO
zXyKf;+I#Tj4($1}2+?E@<oBEi=K@-xWw1N@{WWg;Gv58Nk#l~2FW|3Ri$vww2^9JT
zv4ZMB_S8yK$-()$#PINjro~fq1vaXg+EX?kyFr6EZqwkJ>Uf`HH4&WC=8O)Ot?W~D
zJI#aZ_v32xTAUh(7&T9L=hLVy0c2)6!i)y<7OJJ^4Nd_siRT<bPCt%T7Ps2zx2aN~
zoKJlO*Wbf)8&Y}fHg{EU@<4%|YM5uP*QWAWb95DR*DGIY(4VmxgtM<827Kg*qy$bW
zfcm%~xV)J)?;8FPfg$}AP#{#XZSFDv6f}=H<;s^;oGN-U?Z={Qih&J-`3(Sf;ie5H
znA2P<@Ll5~?&uLl*4pjSOS`ppccR~&W<)w9N*9aE4l8yqHi`~TPp8PlrBolA77lea
zKkIy1PWX;1^OJHvybPc+Eb2IU>U%<t9rY1h-^&9ow|g!D(?~i$v)iyJr`4A<{6hqx
zv*2&s+$)Ay$M#M6w^u{1E%Yl8lc&zvl<1}fMSJ7hK|D{5a8GksvI%{XI&yL;b9qCN
z6KS~lCTY1GW$Kq$wly9h0i4cIPTAS|Fp1f>oB?3dfPt@6!=KWB+#|rDHbPLz*Xs_&
zN9yfNTZ&lneZ^7(bdbhM6X<Th7I+CQ^NC3X`6n3H;t@Zg$G@-zjahhbZ?X`XSLyZ&
zpU*_PFy5o(W@41tF_;nvo<l@uflzXP5)K;`-++%3@5)KpZPM>SXx>QmOUodoWS(He
z9~J11NcFw4%JFH8?Xp}s)D_!mPBAr3mMxhAjL>NI<Tb}(t)B5}iQ=%E2F5<X{;`U?
zP;4oE0s{iVfdvBM{%ft6zcUG1rlRSLqm1^904Kwgvgen>N>L^WhYkW?R&PqrA~ikp
zX;8E%)RflA2Ra4K$i^r{<i-EIeAoTsF|4JQv})E9{xgDOmM@V(WxjgXme$Rp@wv74
zW4h<vcEv|;NE>i|369`pl0@?KUi`IEiN<hw@=}t~!mNu)UTEx6NwxkyB({rtq;`Qs
z_FKsB`Cy3k5S6?EwjRBd+^w!eTg2-x5<T-Ic5u&m1?D#>{_J>*dPs?pxkHR`lMaq;
zDuX3^p5z}XB#HFV5`HA=nR%?Cz}#dS0kp=kjHq>(KI^GRVh(BWd~UE%q+UoXP*9fD
zR4g<6@<HK>guTV$0Fq2;6s%iKl2?Um<?B*v4s%2>X^Q8rKxh(r8`}6%K|zv)V^_YL
zcpZ9KDF$|dTd6v@qPaRA9o9p+N^uGpCmJ7gJ?K(_o<=}8>ShI(e$e9laeV!x-8IcA
z1=AD;tSk(cRm%hiML2#7iY${^y-HLC^{mKFPdbw-D-|@ItfX5mffe;`YV(JR)M7)<
z7?8GwD--)3hu|U>a*--{f`|pUz9ZyFTzr2eOXC#6^!S4@C&KjZql?X^xw2G;ZU^ba
z#*WW!f|ev`7x0GcC7&I7ovI(VaW5AOmj|f7mEXV*EH=fitHL^wY+)!29VNNi=W~BK
z-QDum?$S|Za4ojMyQvWyrTgm4n%QOIjp^yT9CyJ+fh8ut^!eglf#Jv}jUIjMb7ADz
zBn1J5KDv(zRkXQ1sy8AgOg9%IBI;t`%}~N(=<7p_-zqxkvDwVvVr+fR4Q6Zy($2BR
z9C~R<{am?x3u!dbZg3e-=guaiQt~xKXHRcJjgq~z>vHUHy$;6Y^0K-vVYd5cRo4_t
z_0>cUwHg_^yK75IcHRZOP==Hrcg39a*PDM_?(ThNDXN?(*-}#6B1SqZ1;QTPQnhN-
z>|)HWE2jF~Rt}Fp%es;HVUYZJZnpW9ryKD=cQ!-vR&k;ID7OG}_Mz{ca3v<X=`-1k
z$zx=tyK`2r(M0iuu<VTs)uF>UB`4MyIi}IUOE2g5XsAAG-n#P%Iyv4|*}J_g|0f|(
zM2ezo?k=K&&hxS_K9`L^P#_HOa{SXr#;)>Q=ep&FwNgtuM+{<~9p7rUGpsw)R*}D=
zR>R-T>A~O4>#?BYVl6z+n*)K=#e+G7weKU7MB{yPnASk`WrmrIj$MON&SpF{YITXh
zxP7K{y;aN#x9fn1V<W=X4bgp?LN*A>suc2PhGW=lqLzX3-GmUs@DyAh#|ocxxPsEx
zvEc6|8*LT*2<i(>e1J;8{$0iV@Eo(sc<0-3cDq1=-vSgeDr`?zaF1}<_fw>5@qlpg
zN|6u@q<rg$i9j3lB$Ica;BKkFlQQn?PVelltS>=>ukqAdq%O40_kE=?B<(W#KqRd;
zNP|1lzEJ=8oQ=Hy=`)>O+LQ;&4azn=Sl0E3WxRUPsk%`0u6h@}(CT6T^p7h5pY6j8
z{~sH!_>5Nc)?a-y(XYOl?r$Vz{^M$kNJY*6k`}3Npg$$a*FqDd!pxx`3d3xDUjhao
zHtorS@V6G`RuB5EQ>I7uh8d@5zsnAliV^X=5yu`sd6$nS>5-Db`IvF;vChfd@#66U
z{0W(s+Ti_r1sP&LA;bs9tlZt8urx`!ycnO%K6*L|TTQR?uZ^@Fw>#B&TkT<xFevUL
z7PhK_1=Yhh$!k9Xic|xR>1hv&V7m2mhBsl1n!S?zY6j_qE8L<gBX*hc$)vhabkqe|
zJ}xLBY1SPltf(Smcu$&H*zcn+vr)&DEwCC{F^Lb@V@0@f`z7qq*6SYxbstg8n-@%c
zWa{6&R&JU6q@w-7l7&}SQ|X<ljkO}qd&Xpj^du1iIV6#EUSEgQbY9HXPL0&rW7?=m
zGn-*W#svQ8xTyG2_`zpsdAs1I96hs1T=1geRXekvO)>abEuBYx22+dyy5OLNW~z9>
zr_zHs53#d0_%$#TawX+y6zs|B*UA0!Yjcg`q9HykstrwPH5LpF-8U{#>W`c+OmqW6
ziZldfE?{vyI9-yi<&#XjlPs=24$vB1`prD6a;ym#BHfDACO0pAu0e+S?n(1sgOkRh
zg3dx{*TCB}3qJ?ZidU_1J`jC&5I6m#?GN)Z*k015ZO+o>DKnKeIN_h`JNRzO*+&i;
zjzrGgjI%6>`h!@4lR$wBRK82Zz#MVzN94zoFBKCs>%>%~Vw|M4(;z(MdNcck-E}b~
z*mm^j9mHNfYx-pM)knl}{NW#wxP=h0Jqd#pDK`(0r;va8-4totCbRgN6)Anmy6Z0z
zB0$BTO<J1mrzW^4Id+J9*^0YPpxcBj<c{0cwVQ~+>!kpoYq*FZo2tf>U5Xz>Za6yA
z?!{1WlD5Am#Qib2%3|b!?O-h2_koHQ_i7`~5A<slqQOu7q`rHE$i@0^oP?iW-gMvf
zot5^<zn+3(i2sw~j-a!yo#8(vr<W=J8mlTG@iu5TpE^~c=Xh;E>LE9y!LSY#!k_@i
z;8SN<zIivCYG5|B?48X;i(f$h+(wiYi6rCmK{QO)Ow^c472V1j8yiWnFL2&Fd;WR-
z1nJ{iN*U7w56@No!&K-?RvHckAfFggxVIJpotegnm5i}aPe(MCSlvEN_H0HvQJ*Oy
zNo$gd1*~G(D91=MuwTo?$nz4>=ri#ie?#ku7NG-Xxi%G<+o&Dg%e(IGA{&=RkMgc;
zi)KeNHgZtzGNV~Ed6(IOf%k)Dwk=(O<WEFj2b{2(qIDh;k1bmFNZ!*vt`xSmpK=r|
z)Hdy>1ZX0hGA(C?KASfWuB*uY2=ETk#Y&+$y-;oaWM8O2_1I;HQ_@rjr|=G^dNY$O
zvd7U$Yd?g@wRG|E>7a|7Z>>PZNi)~TO8tim6Yqg~Q8sB{ZB&ig1R#W&%SvCVH#dr$
zu0(CJDvUKK@cnM2aXWQA-RAwS3abP&+%2qh9XA{^<u(rwAx`qzsT9IeU9aL;4Dkzt
zanTk5C>BMxDmVAK&T8W>KD-m1#XL5IYuociB!f%fGW{jPu+m}vkwRh0rN-!0>q!@$
z_DU$KmS|HR!}IWG-or(U+pig!<~(?X5tFzd3Z0F?y6t*>9W>tYisrsIi4HQU-XEYv
zCXr&ZlsWguKA|NM^CFy-7o`81_=65Ha+Ijo2q07ixBE5dL^S(}jFqIv75WSCCCohv
zI&(pX!2QH#xL~<*RXF9`X6PnU`TNXGnm&+BUbtEX(QW2j5mtdjPvH}MCdl{B`IO8v
zu0MG{KuVlIl;2c+DUyV!58==}nxc1d2=}!Dn_p(#ZWNd!+9mV+I7W-iHH=qI{ew1M
zI1>rF8hoow6yxyD`j1tf5=;UP8yE=4__tuhzpV0a#;1`AveMlGNS@PkeKQrsl;b2U
zFk%(5)DjA4ATZEt4TsGZlI+#13D0bZ&p_S@jj}ml@j{r18Ll<wZMu8=x5v1hykqzd
z_~|I=WQwrm@Hy+Sg%;m_CQxs7V3jX&><U7=<IB71fmFaCb43pac;loLHTg69;Y#Kt
z53*9O%t9kdsTtHNkzhgC;<?<QWV-7X1TwIs<*mqnIP3uM?#C;zr2$x>^Ou@xj`8!@
z+RHQgg3&~mRnhfAKbRbJx>H_3*mjullxBQL*yY-kXR3R^ByXB@gVtIvR|^<E9ZRbS
zIP-?>8g<(8$GDH6tyxq`6EOMYm`X2%N}qPRSZa8|hKI{q`B7;lRjOYF!A7med<Uw(
z*Zl|NAFr?QB*xwmC=ieb?BA5J6EZZiwlfqnwX=6nbkzIrzyE&8dsQqIQB~2rtg3Bn
zYfL2IKi4lv_zUPj36=;T!6L_?gjy!BEi}lgP0t$4FIp6P=kVvebdA;eCl=jk8b9Q}
zeBsZXws+QtqNx04Tk!F0xM`esziB+v{pR`l+?oL>&-P=V`bb8uk&YOaJsvhT3Wg!w
zh6a#y<Jd)LGM#-X)B-#<lM3e?MCF*RVjl$GXF!N-RC)wbJ;x8c2JDB^^J_PUAYD3R
zjn7KGADl}xinV4H)oWA~BUjU{Od6C+%GI%j7><Ih7yza6ZrvZnIrdiBw2aKs1cy>v
zaJsQ|7tCg)QXR$Vl?PFVQVi>w%QTvk*(2k!hmmw9&(ad>3p5>DCa73FnW%7sa?}@#
zH7d-((k{ucPme<6aHt3cT0*8>F@glAsTPV2_X!u9O>I2J7<Zyp)oM-RD>4RGK(8TL
zm6ao<ia%*KD-1el6tosO-%%iV%@#u)a{ZiaV8-VO-9cCZPu)Y5RcwQ>;v_JOr&*7%
z)naQ(h7<P%hC^JJqH(Q}<38MTXCh6lH8H}@Z9CDAfi>!;QA`cN!#nGgfo(!h?+)?P
zZ5_4^CUzyk?%ivFslNd4Pl5?s&<$~s{JKHVu9tip;V|!Fk{liRZqViID>*nOBZZph
zFcLpkXSK5F3`@6;=ZCq}tY@KV!@LxXL7Ghxt1(fEzGKvBxNrVHN0JCk4AZu`!D*yO
z^inp9_hZ?jIVNmw!8enRx<9j*K(-;-3BTi4p+9BJ`GR32@Ad6a$F=adDs<Zqi_M)z
zs7;4Poj$3~jhBmEIO+HU;;rjY<ZR`&*-_$y1lqVT1dRdus8QpB-1KOIs{67mB-|dj
z|Ah|LiA_wVukg|Hg6!vp_ijt(4i%{oAB~03(?8S{#L-=9yR32R6sgo9I4{y}JzYW=
zE^N<lJR#n7^vI_7(2`tb!%TBWfcxjRP7feveZ9H5b&ED)H$5xV3GMX`WWbO=`S!v*
z>gkfTG_4n@Elj8><fGjWX@Fb6+NGc1(T%N8M~>Sq-nek}zz#7X-d2xTge70edu7?{
z<$I3(fI9xo^9~dgb}HnGa;p4(Mjq-^_+6hVP6)D&YjgBBy@T2-?lH8d!7gU7TgEFp
z!kpZNSiD#r;&s=hTz7)>1EbI*_=sxdh$>dH1uiBF|Fv+=;Ag`mwea>JXc-hsKx%F*
zBJc@O5E#B^!j7aK&Icqi^=8*bo-&CUdvSWFY?Th1Zj1~@0Ok}-H$eJ`+1O!lQaa+@
zw*J1mmaT_YZ}3b-jFa&pr$;88!cjl@g_e#$x=t_k5i*{S%R6IYf^OJG(MHDWEJ;2O
z*(dh6pM-A)=Rn*kzhzec{MANt{&O3m=xXm^X!-XNtB0k!1<-=V7fLMa>gUX6MORpb
zP(^wIF=H?=KQO#M^hza|jwM5-m=;=-QuTu+><mVsG({>B>`_l=z8rrUO>b)TZfytd
z1hz;bLX0G_K+91N7zMFF&lV-}9^#=Ghc;Mxh!LnC?w813GA3A)Sw#+W=dw%qaBd&Y
zB}}8nBG*%zUg^`RkOjM33y#liqJh8+sY^83hPon7j18fE);xnN9`4k{u1FGw3c`wO
zs0U;1IoK$kJvsLn?I0!_>{ibi<L6pmUGJslPDO2RBlC&f@LeUCv<e;kosyc%U~brT
zM}m<ExKcKdC`g`oHeS#BepNKzZD1+OaucuWvOYo<PQg<%m$JIaO8ByA`)-q)5qRU7
zlw2z$j-UOkMa$aR@5Fr3X5u>RD<L_rHx!0JLdSBqs&P_iP(Ry0G6-ZU8$(Oc?CDn_
z7^2hK`w!6q+F@qF&d6*E+OKMT*gA4j7#!%qN9l68i%fp)-{oq+6!V#%XuN>^@s`q~
zoA^Qgx}7axKtN1?r(5{vwU3JH)>H4%p5>^~VC_3slvq&N@fg{TJeaX$$x@SJETN4M
z-CG2@n-etcm+2q)@3+D!`0gO@etqMzTr}_pGo8vLyiGs%*iT<x_x5@Qu>tBA!&zoy
zS{TbU+s1aHo1tfcN>R<c%AF5TYO@t$<o-56Uh2eqNT3t(SpGouz~?Tt`ibZ#Y7UR3
ze7cdtUSPmV)%%<hx7d({loz7>60UYA;Uq-ORe{L#SQO!PM~L=)2fquoft>P~9p%EQ
z<$x|VkHZ#=qJsm)9q_nHo%76a>CHQ#sC1n?9!@iMIcRl;Rv1ZW)+svUEht*wbfKC`
zX)1~b__ad&uo3E(#tdwWy%^XXU80JC_Kf-QDSMb5r2%fv+6gkB_azKLTqehsxLH}K
z#V@F`mG0jHaT?Eg+wLM$k`t|{5MkB*l)X{eZZu_K-Ca+<nB<5qXcq9Eovr&sJ?x(m
zk+iCL{Rk-Q9bKhLwD5Pw3OBJSV6ZVn_EX>Npap$WW4wZLfp%W7Q~Mznv-SkMjY|t*
z@oZEZKQvI4DG#Dn4nn~!2!Noek`Y)+H#9jgqQ1u8o7ZGa1B{5F#C7&8;hgzm+2AAU
zZ3I&Ze~c2JKS`|`J-0OCRve-7r85~AmE4j}?8_@l+4+H%b;X*+l9`QC$Q!xcV3TBs
zP0d%N+gr=|CFqfkuttRV5%Z7LN~|90miO0aV+i_B<Bxwat@IazjpGl~?~$J6G@<f<
zrNDc*^$fG=Yr&B#U8t4ceV|eko&1>7gF^)!4{?F+0kjTk?C?It_UC>?^p-HknIsIF
zbXphVc2<qM)2)ZGb4?3p$Fs*H0#T4C@@NRl6bkyJUx-AtAVZLibZ4c{vKBLqP-n6a
zH%OnTi>-V>$Rh{=lmz2Un)Qqj(a=Q3RHPP}@j!_ydE978Y+id6v3Uu#vLc4TmuxKC
zY64Z(+17r>*<*|6ia>H5`l|3-dVovZLvhzc7x<+nE^XL_lFnd!Pu5h8otGq=Qab|-
z?}~O%eUG^!fI|7pC!>0muo$?hhyrRcCI(Cx81+bw2P_VR;H@hoMEYn+SywVR+2%xm
zVYiHRYH>NV1XJx&t0y|OY?s?&nnwKkP;6`IE(!MZ`#P;wt*QMJS8TTXjl@Vic`a-L
zPtMh9%0ek2X-vb}_BKmY%<nP4aL2|!HZ!`z)q6MHFn6UR82sUUHO2rT*q*}!H1RYQ
z$x%#cz?lTlUg_~0!X-Z9C=>wlPa0it1k4VchW@%Eld;B2%>~xx{Rslb<evki8%OZd
zzAQPmeyRuY5GNP)j$}2QhjUasOl)BtPh#o*UbIx4n0$hZx?G)u7g-di_kG7xX!lG@
zR5`qpEtf04Mm_&MRD@WORIr&z1YZktgA6NSN<91h3<pUz!WcD$u>4_+L`5mJy8Vkq
zkwhm*WHD(@8^2X+x*&JrSc*oPbA5q=D(%v_B3$MXy3S}T$Mv)7Q5U74DCX0y<^gY~
z2Or-=h<$hOKJMr-+mh_`nyeB`5MMVsT%hyjvxGb5lBwk$SA7WA4VX@%AmkvIg!m0d
zbhuCNqyY(bH+u7^*pm;0O9+Ku*2V*f{2lF))}8Oe{d3m$b3rwP*aG4Kr^&_|NZXX<
z({C+!F!2&c>#A(0c#T{8J|~<Si?FpdhF}Y{!x`D0lfK;0TH@?Y-<oiHny3z_KpLSN
zqQ6{WXv-*?{LK5*JA$BJz8}0O1l?!@^e#JkBe@s6>?<dx(87>eM<BolR)mrYbo6TL
zh-^?fcb<pDEu?E+fKm?&*xRfZiLx!}K>NG61{^8@rcr1C&(<3Wpq1ip(7&n9i~f2M
zzS;o%dLsW_3jn4DCV;}9SODz)LHHjS1P%1njNl(-@1cSIXF~!y75r^4E2<<&FDWO+
z@U~d4f>Xh7x<yLAUT8qCTb?iVKNgb}l#>(_RaAN>EB3F5!Ty2xNig-lo2Y+P0`?Cj
z+W*+7{i}kge<*nP7Y1K%08IQ0jK2K(=<I(xHvG?4>x&2cFMXl@M{4~oVDDPs9NMo_
zvibF&i~Irbw-fzWfNzI&zuvjH3OYKN7+N`)>c6h0dds+fqGn(Gi(wh)ciYZaMkla8
zH}U+Vx7Axbup+lrtzYM=@T)ZaAMieb|0$mMe;q3S>Ru$QEe&O?t<4>6{u~-_OMAKZ
z7svz5?=!-$(2!7n3N7lQZ{cWf>h$aTv4x?azP_Qoy{xX4uCd`?T#FHS9kJgewC^F_
zo;yCmpAxA4zW+6DHZnDKw9|c!a=(RE@WeOW{dGyOfBlN_5775We+vEfeoFl6YAyci
z#PeMln^k_R$>6^?8L#Mc7=MZ`V{QDGS7FTVI1C*U2*?WI_jOUPU>#WhyY1bdV{)w3
zuj2lC#7=&-0z`kn#3K4vR<VDMw%REZ+VksTeujQ~pKO``6ivw5+TpjkR2x}cQ>$O2
z;@9suZ=ogT8px)99g<@G?wRlk?Zfe}s(`4Ap}yl^K4bwnc_r1q4uyW9()<B6MfhJl
z6#tF=+e!a9?px2@SKN5HzvICB7VoXc;VYiK^1ttR_?G3Zf8HyLr|REu(|Zf|);8xA
zZuaBfGST@*z&~@nc?C57^w%CZZ&7|L@sGYSzi+>FF6O%bJY)8z@LLy|*HcLS=feNH
zr_5XUx6UB1@Z<)6-zVfP>RS(vS5#!f|ICr&Ez?`CgI6Y0lmF29;4Rf#srgr`7qfpu
zc>XQ?Tg~)W_|F#qp@RBbs<+~+uT%{V|F#tCTavf>m9Hd=&i}ER<y*41a(}O6nC^d9
z{O>L1Td}EE%u}C#UwY~-%Ue~WSC%8czpHWd7W1v5!YgK1*ngt0@K24$n^pd=Jc$wi
zf35j{%lUS#_A94I^xs{%{TB0WQtd0|dCtF;V*8fhZ3g2j!FJximCyK=;BEfcD?wl3
zf0Rx3mgsH1$19O{>HjVJ<1O;rIrLZLz>5EHM*S_-+quhEDwpd2!%XH|*tb)5udoX>
z|JelIKi!2lf&Et|yvF|^%>S0=ZLs+to{Oe`C-nRl|83Oq6<@6NKZ-%VC3+i3c_muu
b_+P^+@1?;Ze)}-s*ALRKR{B%tZ%6+Rs1GVa
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
+distributionSha256Sum=7a2c66d1a78f811d5f37d14630ad21cec5e77a2a4dc61e787e2257a6341016ce
\ No newline at end of file
new file mode 100755
--- /dev/null
+++ b/tools/infer/test/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
new file mode 100644
--- /dev/null
+++ b/tools/infer/test/settings.gradle
@@ -0,0 +1,24 @@
+// Check out root/settings.gradle for more information
+
+rootProject.name = 'infer'
+
+def topsrcdir = rootProject.projectDir.absolutePath + '/../../..'
+
+def commandLine = ["${topsrcdir}/mach", "environment", "--format", "json", "--verbose"]
+def proc = commandLine.execute(null, new File(topsrcdir))
+def standardOutput = new ByteArrayOutputStream()
+proc.consumeProcessOutput(standardOutput, standardOutput)
+proc.waitFor()
+
+if (proc.exitValue() != 0) {
+    throw new GradleException("Process '${commandLine}' finished with non-zero exit value ${proc.exitValue()}:\n\n${standardOutput.toString()}")
+}
+
+import groovy.json.JsonSlurper
+def slurper = new JsonSlurper()
+def json = slurper.parseText(standardOutput.toString())
+
+include 'autotest'
+project(':autotest').projectDir = new File("${json.topsrcdir}/tools/infer/test/autotest")
+
+gradle.ext.mozconfig = json